chiark / gitweb /
Merge nss-myhostname
authorTom Gundersen <teg@jklm.no>
Mon, 7 Jan 2013 14:14:01 +0000 (15:14 +0100)
committerTom Gundersen <teg@jklm.no>
Mon, 7 Jan 2013 14:14:01 +0000 (15:14 +0100)
989 files changed:
.dir-locals.el [new file with mode: 0644]
.gitignore [new file with mode: 0644]
.mailmap [new file with mode: 0644]
.vimrc [new file with mode: 0644]
CODING_STYLE [new file with mode: 0644]
DISTRO_PORTING [new file with mode: 0644]
LICENSE.GPL2 [new file with mode: 0644]
LICENSE.LGPL2.1 [new file with mode: 0644]
LICENSE.MIT [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
catalog/Makefile [new symlink]
catalog/systemd.catalog [new file with mode: 0644]
configure.ac [new file with mode: 0644]
docs/.gitignore [new file with mode: 0644]
docs/Makefile [new symlink]
docs/gudev/.gitignore [new file with mode: 0644]
docs/gudev/Makefile.am [new file with mode: 0644]
docs/gudev/gudev-docs.xml [new file with mode: 0644]
docs/gudev/gudev-sections.txt [new file with mode: 0644]
docs/gudev/gudev.types [new file with mode: 0644]
docs/gudev/version.xml.in [new file with mode: 0644]
docs/libudev/.gitignore [new file with mode: 0644]
docs/libudev/Makefile.am [new file with mode: 0644]
docs/libudev/libudev-docs.xml [new file with mode: 0644]
docs/libudev/libudev-sections.txt [new file with mode: 0644]
docs/libudev/libudev.types [new file with mode: 0644]
docs/libudev/version.xml.in [new file with mode: 0644]
docs/sysvinit/.gitignore [new file with mode: 0644]
docs/sysvinit/Makefile [new symlink]
docs/sysvinit/README.in [new file with mode: 0644]
docs/var-log/.gitignore [new file with mode: 0644]
docs/var-log/Makefile [new symlink]
docs/var-log/README.in [new file with mode: 0644]
hwdb/.gitignore [new file with mode: 0644]
hwdb/20-OUI.hwdb [new file with mode: 0644]
hwdb/20-acpi-vendor.hwdb [new file with mode: 0644]
hwdb/20-bluetooth-vendor-product.hwdb [new file with mode: 0644]
hwdb/20-pci-classes.hwdb [new file with mode: 0644]
hwdb/20-pci-vendor-product.hwdb [new file with mode: 0644]
hwdb/20-usb-classes.hwdb [new file with mode: 0644]
hwdb/20-usb-vendor-product.hwdb [new file with mode: 0644]
hwdb/ids-update.pl [new file with mode: 0755]
introspect.awk [new file with mode: 0644]
keymaps-force-release/common-volume-keys [new file with mode: 0644]
keymaps-force-release/dell-touchpad [new file with mode: 0644]
keymaps-force-release/dell-xps [new file with mode: 0644]
keymaps-force-release/hp-other [new file with mode: 0644]
keymaps-force-release/samsung-other [new file with mode: 0644]
keymaps-force-release/samsung-series-9 [new file with mode: 0644]
keymaps/acer [new file with mode: 0644]
keymaps/acer-aspire_5720 [new file with mode: 0644]
keymaps/acer-aspire_5920g [new file with mode: 0644]
keymaps/acer-aspire_6920 [new file with mode: 0644]
keymaps/acer-aspire_8930 [new file with mode: 0644]
keymaps/acer-travelmate_c300 [new file with mode: 0644]
keymaps/asus [new file with mode: 0644]
keymaps/compaq-e_evo [new file with mode: 0644]
keymaps/dell [new file with mode: 0644]
keymaps/dell-latitude-xt2 [new file with mode: 0644]
keymaps/everex-xt5000 [new file with mode: 0644]
keymaps/fujitsu-amilo_li_2732 [new file with mode: 0644]
keymaps/fujitsu-amilo_pa_2548 [new file with mode: 0644]
keymaps/fujitsu-amilo_pro_edition_v3505 [new file with mode: 0644]
keymaps/fujitsu-amilo_pro_v3205 [new file with mode: 0644]
keymaps/fujitsu-amilo_si_1520 [new file with mode: 0644]
keymaps/fujitsu-esprimo_mobile_v5 [new file with mode: 0644]
keymaps/fujitsu-esprimo_mobile_v6 [new file with mode: 0644]
keymaps/genius-slimstar-320 [new file with mode: 0644]
keymaps/hewlett-packard [new file with mode: 0644]
keymaps/hewlett-packard-2510p_2530p [new file with mode: 0644]
keymaps/hewlett-packard-compaq_elitebook [new file with mode: 0644]
keymaps/hewlett-packard-pavilion [new file with mode: 0644]
keymaps/hewlett-packard-presario-2100 [new file with mode: 0644]
keymaps/hewlett-packard-tablet [new file with mode: 0644]
keymaps/hewlett-packard-tx2 [new file with mode: 0644]
keymaps/hewlett-packard_elitebook-8440p [new file with mode: 0644]
keymaps/ibm-thinkpad-usb-keyboard-trackpoint [new file with mode: 0644]
keymaps/inventec-symphony_6.0_7.0 [new file with mode: 0644]
keymaps/lenovo-3000 [new file with mode: 0644]
keymaps/lenovo-ideapad [new file with mode: 0644]
keymaps/lenovo-thinkpad-usb-keyboard-trackpoint [new file with mode: 0644]
keymaps/lenovo-thinkpad_x200_tablet [new file with mode: 0644]
keymaps/lenovo-thinkpad_x6_tablet [new file with mode: 0644]
keymaps/lg-x110 [new file with mode: 0644]
keymaps/logitech-wave [new file with mode: 0644]
keymaps/logitech-wave-cordless [new file with mode: 0644]
keymaps/logitech-wave-pro-cordless [new file with mode: 0644]
keymaps/maxdata-pro_7000 [new file with mode: 0644]
keymaps/medion-fid2060 [new file with mode: 0644]
keymaps/medionnb-a555 [new file with mode: 0644]
keymaps/micro-star [new file with mode: 0644]
keymaps/module-asus-w3j [new file with mode: 0644]
keymaps/module-ibm [new file with mode: 0644]
keymaps/module-lenovo [new file with mode: 0644]
keymaps/module-sony [new file with mode: 0644]
keymaps/module-sony-old [new file with mode: 0644]
keymaps/module-sony-vgn [new file with mode: 0644]
keymaps/module-sony-vpc [new file with mode: 0644]
keymaps/olpc-xo [new file with mode: 0644]
keymaps/onkyo [new file with mode: 0644]
keymaps/oqo-model2 [new file with mode: 0644]
keymaps/samsung-other [new file with mode: 0644]
keymaps/samsung-series-9 [new file with mode: 0644]
keymaps/samsung-sq1us [new file with mode: 0644]
keymaps/samsung-sx20s [new file with mode: 0644]
keymaps/toshiba-satellite_a100 [new file with mode: 0644]
keymaps/toshiba-satellite_a110 [new file with mode: 0644]
keymaps/toshiba-satellite_m30x [new file with mode: 0644]
keymaps/zepto-znote [new file with mode: 0644]
m4/.gitignore [new file with mode: 0644]
m4/acx_libwrap.m4 [new file with mode: 0644]
m4/attributes.m4 [new file with mode: 0644]
make-directive-index.py [new file with mode: 0755]
make-man-index.py [new file with mode: 0755]
man/.gitignore [new file with mode: 0644]
man/Makefile [new symlink]
man/binfmt.d.xml [new file with mode: 0644]
man/bootup.xml [new file with mode: 0644]
man/crypttab.xml [new file with mode: 0644]
man/custom-html.xsl [new file with mode: 0644]
man/daemon.xml [new file with mode: 0644]
man/halt.xml [new file with mode: 0644]
man/hostname.xml [new file with mode: 0644]
man/hostnamectl.xml [new file with mode: 0644]
man/journalctl.xml [new file with mode: 0644]
man/journald.conf.xml [new file with mode: 0644]
man/kernel-command-line.xml [new file with mode: 0644]
man/locale.conf.xml [new file with mode: 0644]
man/localectl.xml [new file with mode: 0644]
man/localtime.xml [new file with mode: 0644]
man/loginctl.xml [new file with mode: 0644]
man/logind.conf.xml [new file with mode: 0644]
man/machine-id.xml [new file with mode: 0644]
man/machine-info.xml [new file with mode: 0644]
man/modules-load.d.xml [new file with mode: 0644]
man/os-release.xml [new file with mode: 0644]
man/pam_systemd.xml [new file with mode: 0644]
man/runlevel.xml [new file with mode: 0644]
man/sd-daemon.xml [new file with mode: 0644]
man/sd-id128.xml [new file with mode: 0644]
man/sd-journal.xml [new file with mode: 0644]
man/sd-login.xml [new file with mode: 0644]
man/sd-readahead.xml [new file with mode: 0644]
man/sd_booted.xml [new file with mode: 0644]
man/sd_get_seats.xml [new file with mode: 0644]
man/sd_id128_get_machine.xml [new file with mode: 0644]
man/sd_id128_randomize.xml [new file with mode: 0644]
man/sd_id128_to_string.xml [new file with mode: 0644]
man/sd_is_fifo.xml [new file with mode: 0644]
man/sd_journal_add_match.xml [new file with mode: 0644]
man/sd_journal_get_catalog.xml [new file with mode: 0644]
man/sd_journal_get_cursor.xml [new file with mode: 0644]
man/sd_journal_get_cutoff_realtime_usec.xml [new file with mode: 0644]
man/sd_journal_get_data.xml [new file with mode: 0644]
man/sd_journal_get_fd.xml [new file with mode: 0644]
man/sd_journal_get_realtime_usec.xml [new file with mode: 0644]
man/sd_journal_get_usage.xml [new file with mode: 0644]
man/sd_journal_next.xml [new file with mode: 0644]
man/sd_journal_open.xml [new file with mode: 0644]
man/sd_journal_print.xml [new file with mode: 0644]
man/sd_journal_query_unique.xml [new file with mode: 0644]
man/sd_journal_seek_head.xml [new file with mode: 0644]
man/sd_journal_stream_fd.xml [new file with mode: 0644]
man/sd_listen_fds.xml [new file with mode: 0644]
man/sd_login_monitor_new.xml [new file with mode: 0644]
man/sd_notify.xml [new file with mode: 0644]
man/sd_pid_get_session.xml [new file with mode: 0644]
man/sd_readahead.xml [new file with mode: 0644]
man/sd_seat_get_active.xml [new file with mode: 0644]
man/sd_session_is_active.xml [new file with mode: 0644]
man/sd_uid_get_state.xml [new file with mode: 0644]
man/shutdown.xml [new file with mode: 0644]
man/sysctl.d.xml [new file with mode: 0644]
man/systemctl.xml [new file with mode: 0644]
man/systemd-analyze.xml [new file with mode: 0644]
man/systemd-ask-password-console.service.xml [new file with mode: 0644]
man/systemd-ask-password.xml [new file with mode: 0644]
man/systemd-binfmt.service.xml [new file with mode: 0644]
man/systemd-cat.xml [new file with mode: 0644]
man/systemd-cgls.xml [new file with mode: 0644]
man/systemd-cgtop.xml [new file with mode: 0644]
man/systemd-coredumpctl.xml [new file with mode: 0644]
man/systemd-cryptsetup-generator.xml [new file with mode: 0644]
man/systemd-cryptsetup@.service.xml [new file with mode: 0644]
man/systemd-delta.xml [new file with mode: 0644]
man/systemd-detect-virt.xml [new file with mode: 0644]
man/systemd-fsck@.service.xml [new file with mode: 0644]
man/systemd-fstab-generator.xml [new file with mode: 0644]
man/systemd-getty-generator.xml [new file with mode: 0644]
man/systemd-halt.service.xml [new file with mode: 0644]
man/systemd-hostnamed.service.xml [new file with mode: 0644]
man/systemd-inhibit.xml [new file with mode: 0644]
man/systemd-initctl.service.xml [new file with mode: 0644]
man/systemd-journal-gatewayd.service.xml [new file with mode: 0644]
man/systemd-journald.service.xml [new file with mode: 0644]
man/systemd-localed.service.xml [new file with mode: 0644]
man/systemd-logind.service.xml [new file with mode: 0644]
man/systemd-machine-id-setup.xml [new file with mode: 0644]
man/systemd-modules-load.service.xml [new file with mode: 0644]
man/systemd-notify.xml [new file with mode: 0644]
man/systemd-nspawn.xml [new file with mode: 0644]
man/systemd-quotacheck.service.xml [new file with mode: 0644]
man/systemd-random-seed-load.service.xml [new file with mode: 0644]
man/systemd-readahead-replay.service.xml [new file with mode: 0644]
man/systemd-remount-fs.service.xml [new file with mode: 0644]
man/systemd-shutdownd.service.xml [new file with mode: 0644]
man/systemd-suspend.service.xml [new file with mode: 0644]
man/systemd-sysctl.service.xml [new file with mode: 0644]
man/systemd-system-update-generator.xml [new file with mode: 0644]
man/systemd-timedated.service.xml [new file with mode: 0644]
man/systemd-tmpfiles.xml [new file with mode: 0644]
man/systemd-tty-ask-password-agent.xml [new file with mode: 0644]
man/systemd-udevd.service.xml [new file with mode: 0644]
man/systemd-update-utmp-runlevel.service.xml [new file with mode: 0644]
man/systemd-user-sessions.service.xml [new file with mode: 0644]
man/systemd-vconsole-setup.service.xml [new file with mode: 0644]
man/systemd.automount.xml [new file with mode: 0644]
man/systemd.conf.xml [new file with mode: 0644]
man/systemd.device.xml [new file with mode: 0644]
man/systemd.exec.xml [new file with mode: 0644]
man/systemd.journal-fields.xml [new file with mode: 0644]
man/systemd.kill.xml [new file with mode: 0644]
man/systemd.mount.xml [new file with mode: 0644]
man/systemd.path.xml [new file with mode: 0644]
man/systemd.preset.xml [new file with mode: 0644]
man/systemd.service.xml [new file with mode: 0644]
man/systemd.snapshot.xml [new file with mode: 0644]
man/systemd.socket.xml [new file with mode: 0644]
man/systemd.special.xml [new file with mode: 0644]
man/systemd.swap.xml [new file with mode: 0644]
man/systemd.target.xml [new file with mode: 0644]
man/systemd.time.xml [new file with mode: 0644]
man/systemd.timer.xml [new file with mode: 0644]
man/systemd.unit.xml [new file with mode: 0644]
man/systemd.xml [new file with mode: 0644]
man/telinit.xml [new file with mode: 0644]
man/timedatectl.xml [new file with mode: 0644]
man/tmpfiles.d.xml [new file with mode: 0644]
man/udev.xml [new file with mode: 0644]
man/udevadm.xml [new file with mode: 0644]
man/vconsole.conf.xml [new file with mode: 0644]
po/.gitignore [new file with mode: 0644]
po/POTFILES.in [new file with mode: 0644]
po/POTFILES.skip [new file with mode: 0644]
po/pl.po [new file with mode: 0644]
rules/.gitignore [new file with mode: 0644]
rules/42-usb-hid-pm.rules [new file with mode: 0644]
rules/50-udev-default.rules [new file with mode: 0644]
rules/60-cdrom_id.rules [new file with mode: 0644]
rules/60-persistent-alsa.rules [new file with mode: 0644]
rules/60-persistent-input.rules [new file with mode: 0644]
rules/60-persistent-serial.rules [new file with mode: 0644]
rules/60-persistent-storage-tape.rules [new file with mode: 0644]
rules/60-persistent-storage.rules [new file with mode: 0644]
rules/60-persistent-v4l.rules [new file with mode: 0644]
rules/61-accelerometer.rules [new file with mode: 0644]
rules/64-btrfs.rules [new file with mode: 0644]
rules/75-net-description.rules [new file with mode: 0644]
rules/75-probe_mtd.rules [new file with mode: 0644]
rules/75-tty-description.rules [new file with mode: 0644]
rules/78-sound-card.rules [new file with mode: 0644]
rules/80-drivers.rules [new file with mode: 0644]
rules/80-net-name-slot.rules [new file with mode: 0644]
rules/95-udev-late.rules [new file with mode: 0644]
rules/99-systemd.rules.in [new file with mode: 0644]
shell-completion/systemd-bash-completion.sh [new file with mode: 0644]
shell-completion/systemd-zsh-completion.zsh [new file with mode: 0644]
src/.gitignore [new file with mode: 0644]
src/Makefile [new file with mode: 0644]
src/ac-power/Makefile [new symlink]
src/ac-power/ac-power.c [new file with mode: 0644]
src/analyze/.gitignore [new file with mode: 0644]
src/analyze/Makefile [new symlink]
src/analyze/systemd-analyze.in [new file with mode: 0755]
src/ask-password/Makefile [new symlink]
src/ask-password/ask-password.c [new file with mode: 0644]
src/binfmt/Makefile [new symlink]
src/binfmt/binfmt.c [new file with mode: 0644]
src/cgls/Makefile [new symlink]
src/cgls/cgls.c [new file with mode: 0644]
src/cgroups-agent/Makefile [new symlink]
src/cgroups-agent/cgroups-agent.c [new file with mode: 0644]
src/cgtop/Makefile [new symlink]
src/cgtop/cgtop.c [new file with mode: 0644]
src/core/.gitignore [new file with mode: 0644]
src/core/Makefile [new symlink]
src/core/audit-fd.c [new file with mode: 0644]
src/core/audit-fd.h [new file with mode: 0644]
src/core/automount.c [new file with mode: 0644]
src/core/automount.h [new file with mode: 0644]
src/core/build.h [new file with mode: 0644]
src/core/bus-errors.h [new file with mode: 0644]
src/core/cgroup-attr.c [new file with mode: 0644]
src/core/cgroup-attr.h [new file with mode: 0644]
src/core/cgroup.c [new file with mode: 0644]
src/core/cgroup.h [new file with mode: 0644]
src/core/condition.c [new file with mode: 0644]
src/core/condition.h [new file with mode: 0644]
src/core/dbus-automount.c [new file with mode: 0644]
src/core/dbus-automount.h [new file with mode: 0644]
src/core/dbus-device.c [new file with mode: 0644]
src/core/dbus-device.h [new file with mode: 0644]
src/core/dbus-execute.c [new file with mode: 0644]
src/core/dbus-execute.h [new file with mode: 0644]
src/core/dbus-job.c [new file with mode: 0644]
src/core/dbus-job.h [new file with mode: 0644]
src/core/dbus-kill.c [new file with mode: 0644]
src/core/dbus-kill.h [new file with mode: 0644]
src/core/dbus-manager.c [new file with mode: 0644]
src/core/dbus-manager.h [new file with mode: 0644]
src/core/dbus-mount.c [new file with mode: 0644]
src/core/dbus-mount.h [new file with mode: 0644]
src/core/dbus-path.c [new file with mode: 0644]
src/core/dbus-path.h [new file with mode: 0644]
src/core/dbus-service.c [new file with mode: 0644]
src/core/dbus-service.h [new file with mode: 0644]
src/core/dbus-snapshot.c [new file with mode: 0644]
src/core/dbus-snapshot.h [new file with mode: 0644]
src/core/dbus-socket.c [new file with mode: 0644]
src/core/dbus-socket.h [new file with mode: 0644]
src/core/dbus-swap.c [new file with mode: 0644]
src/core/dbus-swap.h [new file with mode: 0644]
src/core/dbus-target.c [new file with mode: 0644]
src/core/dbus-target.h [new file with mode: 0644]
src/core/dbus-timer.c [new file with mode: 0644]
src/core/dbus-timer.h [new file with mode: 0644]
src/core/dbus-unit.c [new file with mode: 0644]
src/core/dbus-unit.h [new file with mode: 0644]
src/core/dbus.c [new file with mode: 0644]
src/core/dbus.h [new file with mode: 0644]
src/core/device.c [new file with mode: 0644]
src/core/device.h [new file with mode: 0644]
src/core/execute.c [new file with mode: 0644]
src/core/execute.h [new file with mode: 0644]
src/core/hostname-setup.c [new file with mode: 0644]
src/core/hostname-setup.h [new file with mode: 0644]
src/core/ima-setup.c [new file with mode: 0644]
src/core/ima-setup.h [new file with mode: 0644]
src/core/initreq.h [new file with mode: 0644]
src/core/job.c [new file with mode: 0644]
src/core/job.h [new file with mode: 0644]
src/core/kill.c [new file with mode: 0644]
src/core/kill.h [new file with mode: 0644]
src/core/killall.c [new file with mode: 0644]
src/core/killall.h [new file with mode: 0644]
src/core/kmod-setup.c [new file with mode: 0644]
src/core/kmod-setup.h [new file with mode: 0644]
src/core/load-dropin.c [new file with mode: 0644]
src/core/load-dropin.h [new file with mode: 0644]
src/core/load-fragment-gperf.gperf.m4 [new file with mode: 0644]
src/core/load-fragment.c [new file with mode: 0644]
src/core/load-fragment.h [new file with mode: 0644]
src/core/locale-setup.c [new file with mode: 0644]
src/core/locale-setup.h [new file with mode: 0644]
src/core/loopback-setup.c [new file with mode: 0644]
src/core/loopback-setup.h [new file with mode: 0644]
src/core/machine-id-setup.c [new file with mode: 0644]
src/core/machine-id-setup.h [new file with mode: 0644]
src/core/macros.systemd.in [new file with mode: 0644]
src/core/main.c [new file with mode: 0644]
src/core/manager.c [new file with mode: 0644]
src/core/manager.h [new file with mode: 0644]
src/core/mount-setup.c [new file with mode: 0644]
src/core/mount-setup.h [new file with mode: 0644]
src/core/mount.c [new file with mode: 0644]
src/core/mount.h [new file with mode: 0644]
src/core/namespace.c [new file with mode: 0644]
src/core/namespace.h [new file with mode: 0644]
src/core/org.freedesktop.systemd1.conf [new file with mode: 0644]
src/core/org.freedesktop.systemd1.policy.in.in [new file with mode: 0644]
src/core/org.freedesktop.systemd1.service [new file with mode: 0644]
src/core/path.c [new file with mode: 0644]
src/core/path.h [new file with mode: 0644]
src/core/securebits.h [new file with mode: 0644]
src/core/selinux-access.c [new file with mode: 0644]
src/core/selinux-access.h [new file with mode: 0644]
src/core/selinux-setup.c [new file with mode: 0644]
src/core/selinux-setup.h [new file with mode: 0644]
src/core/service.c [new file with mode: 0644]
src/core/service.h [new file with mode: 0644]
src/core/shutdown.c [new file with mode: 0644]
src/core/snapshot.c [new file with mode: 0644]
src/core/snapshot.h [new file with mode: 0644]
src/core/socket.c [new file with mode: 0644]
src/core/socket.h [new file with mode: 0644]
src/core/special.h [new file with mode: 0644]
src/core/swap.c [new file with mode: 0644]
src/core/swap.h [new file with mode: 0644]
src/core/switch-root.c [new file with mode: 0644]
src/core/switch-root.h [new file with mode: 0644]
src/core/syscall-list.c [new file with mode: 0644]
src/core/syscall-list.h [new file with mode: 0644]
src/core/sysfs-show.h [new file with mode: 0644]
src/core/system.conf [new file with mode: 0644]
src/core/systemd.pc.in [new file with mode: 0644]
src/core/target.c [new file with mode: 0644]
src/core/target.h [new file with mode: 0644]
src/core/tcpwrap.c [new file with mode: 0644]
src/core/tcpwrap.h [new file with mode: 0644]
src/core/timer.c [new file with mode: 0644]
src/core/timer.h [new file with mode: 0644]
src/core/transaction.c [new file with mode: 0644]
src/core/transaction.h [new file with mode: 0644]
src/core/umount.c [new file with mode: 0644]
src/core/umount.h [new file with mode: 0644]
src/core/unit-printf.c [new file with mode: 0644]
src/core/unit-printf.h [new file with mode: 0644]
src/core/unit.c [new file with mode: 0644]
src/core/unit.h [new file with mode: 0644]
src/core/user.conf [new file with mode: 0644]
src/cryptsetup/Makefile [new symlink]
src/cryptsetup/cryptsetup-generator.c [new file with mode: 0644]
src/cryptsetup/cryptsetup.c [new file with mode: 0644]
src/delta/Makefile [new symlink]
src/delta/delta.c [new file with mode: 0644]
src/detect-virt/Makefile [new symlink]
src/detect-virt/detect-virt.c [new file with mode: 0644]
src/fsck/Makefile [new symlink]
src/fsck/fsck.c [new file with mode: 0644]
src/fstab-generator/Makefile [new symlink]
src/fstab-generator/fstab-generator.c [new file with mode: 0644]
src/getty-generator/Makefile [new symlink]
src/getty-generator/getty-generator.c [new file with mode: 0644]
src/gudev/.gitignore [new file with mode: 0644]
src/gudev/Makefile [new symlink]
src/gudev/gjs-example.js [new file with mode: 0755]
src/gudev/gudev-1.0.pc.in [new file with mode: 0644]
src/gudev/gudev.h [new file with mode: 0644]
src/gudev/gudevclient.c [new file with mode: 0644]
src/gudev/gudevclient.h [new file with mode: 0644]
src/gudev/gudevdevice.c [new file with mode: 0644]
src/gudev/gudevdevice.h [new file with mode: 0644]
src/gudev/gudevenumerator.c [new file with mode: 0644]
src/gudev/gudevenumerator.h [new file with mode: 0644]
src/gudev/gudevenums.h [new file with mode: 0644]
src/gudev/gudevenumtypes.c.template [new file with mode: 0644]
src/gudev/gudevenumtypes.h.template [new file with mode: 0644]
src/gudev/gudevmarshal.list [new file with mode: 0644]
src/gudev/gudevprivate.h [new file with mode: 0644]
src/gudev/gudevtypes.h [new file with mode: 0644]
src/gudev/seed-example-enum.js [new file with mode: 0755]
src/gudev/seed-example.js [new file with mode: 0755]
src/hostname/.gitignore [new file with mode: 0644]
src/hostname/Makefile [new symlink]
src/hostname/hostnamectl.c [new file with mode: 0644]
src/hostname/hostnamed.c [new file with mode: 0644]
src/hostname/org.freedesktop.hostname1.conf [new file with mode: 0644]
src/hostname/org.freedesktop.hostname1.policy.in [new file with mode: 0644]
src/hostname/org.freedesktop.hostname1.service [new file with mode: 0644]
src/initctl/Makefile [new symlink]
src/initctl/initctl.c [new file with mode: 0644]
src/journal/.gitignore [new file with mode: 0644]
src/journal/Makefile [new symlink]
src/journal/browse.html [new file with mode: 0644]
src/journal/cat.c [new file with mode: 0644]
src/journal/catalog.c [new file with mode: 0644]
src/journal/catalog.h [new file with mode: 0644]
src/journal/compress.c [new file with mode: 0644]
src/journal/compress.h [new file with mode: 0644]
src/journal/coredump.c [new file with mode: 0644]
src/journal/coredumpctl.c [new file with mode: 0644]
src/journal/fsprg.c [new file with mode: 0644]
src/journal/fsprg.h [new file with mode: 0644]
src/journal/journal-authenticate.c [new file with mode: 0644]
src/journal/journal-authenticate.h [new file with mode: 0644]
src/journal/journal-def.h [new file with mode: 0644]
src/journal/journal-file.c [new file with mode: 0644]
src/journal/journal-file.h [new file with mode: 0644]
src/journal/journal-gatewayd.c [new file with mode: 0644]
src/journal/journal-internal.h [new file with mode: 0644]
src/journal/journal-qrcode.c [new file with mode: 0644]
src/journal/journal-qrcode.h [new file with mode: 0644]
src/journal/journal-send.c [new file with mode: 0644]
src/journal/journal-vacuum.c [new file with mode: 0644]
src/journal/journal-vacuum.h [new file with mode: 0644]
src/journal/journal-verify.c [new file with mode: 0644]
src/journal/journal-verify.h [new file with mode: 0644]
src/journal/journalctl.c [new file with mode: 0644]
src/journal/journald-console.c [new file with mode: 0644]
src/journal/journald-console.h [new file with mode: 0644]
src/journal/journald-gperf.gperf [new file with mode: 0644]
src/journal/journald-kmsg.c [new file with mode: 0644]
src/journal/journald-kmsg.h [new file with mode: 0644]
src/journal/journald-native.c [new file with mode: 0644]
src/journal/journald-native.h [new file with mode: 0644]
src/journal/journald-rate-limit.c [new file with mode: 0644]
src/journal/journald-rate-limit.h [new file with mode: 0644]
src/journal/journald-server.c [new file with mode: 0644]
src/journal/journald-server.h [new file with mode: 0644]
src/journal/journald-stream.c [new file with mode: 0644]
src/journal/journald-stream.h [new file with mode: 0644]
src/journal/journald-syslog.c [new file with mode: 0644]
src/journal/journald-syslog.h [new file with mode: 0644]
src/journal/journald.c [new file with mode: 0644]
src/journal/journald.conf [new file with mode: 0644]
src/journal/libsystemd-journal.pc.in [new file with mode: 0644]
src/journal/libsystemd-journal.sym [new file with mode: 0644]
src/journal/lookup3.c [new file with mode: 0644]
src/journal/lookup3.h [new file with mode: 0644]
src/journal/mmap-cache.c [new file with mode: 0644]
src/journal/mmap-cache.h [new file with mode: 0644]
src/journal/sd-journal.c [new file with mode: 0644]
src/journal/test-catalog.c [new file with mode: 0644]
src/journal/test-journal-enum.c [new file with mode: 0644]
src/journal/test-journal-match.c [new file with mode: 0644]
src/journal/test-journal-send.c [new file with mode: 0644]
src/journal/test-journal-stream.c [new file with mode: 0644]
src/journal/test-journal-syslog.c [new file with mode: 0644]
src/journal/test-journal-verify.c [new file with mode: 0644]
src/journal/test-journal.c [new file with mode: 0644]
src/journal/test-mmap-cache.c [new file with mode: 0644]
src/libsystemd-daemon/.gitignore [new file with mode: 0644]
src/libsystemd-daemon/Makefile [new symlink]
src/libsystemd-daemon/libsystemd-daemon.pc.in [new file with mode: 0644]
src/libsystemd-daemon/libsystemd-daemon.sym [new file with mode: 0644]
src/libsystemd-daemon/sd-daemon.c [new file with mode: 0644]
src/libsystemd-id128/.gitignore [new file with mode: 0644]
src/libsystemd-id128/Makefile [new symlink]
src/libsystemd-id128/libsystemd-id128.pc.in [new file with mode: 0644]
src/libsystemd-id128/libsystemd-id128.sym [new file with mode: 0644]
src/libsystemd-id128/sd-id128.c [new file with mode: 0644]
src/libudev/.gitignore [new file with mode: 0644]
src/libudev/Makefile [new symlink]
src/libudev/libudev-device-private.c [new file with mode: 0644]
src/libudev/libudev-device.c [new file with mode: 0644]
src/libudev/libudev-enumerate.c [new file with mode: 0644]
src/libudev/libudev-hwdb-def.h [new file with mode: 0644]
src/libudev/libudev-hwdb.c [new file with mode: 0644]
src/libudev/libudev-list.c [new file with mode: 0644]
src/libudev/libudev-monitor.c [new file with mode: 0644]
src/libudev/libudev-private.h [new file with mode: 0644]
src/libudev/libudev-queue-private.c [new file with mode: 0644]
src/libudev/libudev-queue.c [new file with mode: 0644]
src/libudev/libudev-util.c [new file with mode: 0644]
src/libudev/libudev.c [new file with mode: 0644]
src/libudev/libudev.h [new file with mode: 0644]
src/libudev/libudev.pc.in [new file with mode: 0644]
src/libudev/libudev.sym [new file with mode: 0644]
src/locale/.gitignore [new file with mode: 0644]
src/locale/Makefile [new symlink]
src/locale/generate-kbd-model-map [new file with mode: 0755]
src/locale/kbd-model-map [new file with mode: 0644]
src/locale/localectl.c [new file with mode: 0644]
src/locale/localed.c [new file with mode: 0644]
src/locale/org.freedesktop.locale1.conf [new file with mode: 0644]
src/locale/org.freedesktop.locale1.policy.in [new file with mode: 0644]
src/locale/org.freedesktop.locale1.service [new file with mode: 0644]
src/login/.gitignore [new file with mode: 0644]
src/login/70-power-switch.rules [new file with mode: 0644]
src/login/70-uaccess.rules [new file with mode: 0644]
src/login/71-seat.rules.in [new file with mode: 0644]
src/login/73-seat-late.rules.in [new file with mode: 0644]
src/login/Makefile [new symlink]
src/login/inhibit.c [new file with mode: 0644]
src/login/libsystemd-login.pc.in [new file with mode: 0644]
src/login/libsystemd-login.sym [new file with mode: 0644]
src/login/loginctl.c [new file with mode: 0644]
src/login/logind-acl.c [new file with mode: 0644]
src/login/logind-acl.h [new file with mode: 0644]
src/login/logind-action.c [new file with mode: 0644]
src/login/logind-action.h [new file with mode: 0644]
src/login/logind-button.c [new file with mode: 0644]
src/login/logind-button.h [new file with mode: 0644]
src/login/logind-dbus.c [new file with mode: 0644]
src/login/logind-device.c [new file with mode: 0644]
src/login/logind-device.h [new file with mode: 0644]
src/login/logind-gperf.gperf [new file with mode: 0644]
src/login/logind-inhibit.c [new file with mode: 0644]
src/login/logind-inhibit.h [new file with mode: 0644]
src/login/logind-seat-dbus.c [new file with mode: 0644]
src/login/logind-seat.c [new file with mode: 0644]
src/login/logind-seat.h [new file with mode: 0644]
src/login/logind-session-dbus.c [new file with mode: 0644]
src/login/logind-session.c [new file with mode: 0644]
src/login/logind-session.h [new file with mode: 0644]
src/login/logind-user-dbus.c [new file with mode: 0644]
src/login/logind-user.c [new file with mode: 0644]
src/login/logind-user.h [new file with mode: 0644]
src/login/logind.c [new file with mode: 0644]
src/login/logind.conf [new file with mode: 0644]
src/login/logind.h [new file with mode: 0644]
src/login/multi-seat-x.c [new file with mode: 0644]
src/login/org.freedesktop.login1.conf [new file with mode: 0644]
src/login/org.freedesktop.login1.policy.in [new file with mode: 0644]
src/login/org.freedesktop.login1.service [new file with mode: 0644]
src/login/pam-module.c [new file with mode: 0644]
src/login/sd-login.c [new file with mode: 0644]
src/login/sysfs-show.c [new file with mode: 0644]
src/login/test-inhibit.c [new file with mode: 0644]
src/login/test-login.c [new file with mode: 0644]
src/login/uaccess.c [new file with mode: 0644]
src/login/user-sessions.c [new file with mode: 0644]
src/machine-id-setup/Makefile [new symlink]
src/machine-id-setup/machine-id-setup-main.c [new file with mode: 0644]
src/modules-load/Makefile [new symlink]
src/modules-load/modules-load.c [new file with mode: 0644]
src/notify/Makefile [new symlink]
src/notify/notify.c [new file with mode: 0644]
src/nspawn/Makefile [new symlink]
src/nspawn/nspawn.c [new file with mode: 0644]
src/python-systemd/Makefile [new symlink]
src/python-systemd/__init__.py [new file with mode: 0644]
src/python-systemd/_journal.c [new file with mode: 0644]
src/python-systemd/journal.py [new file with mode: 0644]
src/quotacheck/Makefile [new symlink]
src/quotacheck/quotacheck.c [new file with mode: 0644]
src/random-seed/Makefile [new symlink]
src/random-seed/random-seed.c [new file with mode: 0644]
src/rc-local-generator/Makefile [new symlink]
src/rc-local-generator/rc-local-generator.c [new file with mode: 0644]
src/readahead/Makefile [new symlink]
src/readahead/readahead-analyze.c [new file with mode: 0644]
src/readahead/readahead-collect.c [new file with mode: 0644]
src/readahead/readahead-common.c [new file with mode: 0644]
src/readahead/readahead-common.h [new file with mode: 0644]
src/readahead/readahead-replay.c [new file with mode: 0644]
src/readahead/readahead.c [new file with mode: 0644]
src/readahead/sd-readahead.c [new file with mode: 0644]
src/remount-fs/Makefile [new symlink]
src/remount-fs/remount-fs.c [new file with mode: 0644]
src/reply-password/Makefile [new symlink]
src/reply-password/reply-password.c [new file with mode: 0644]
src/shared/Makefile [new symlink]
src/shared/acl-util.c [new file with mode: 0644]
src/shared/acl-util.h [new file with mode: 0644]
src/shared/ask-password-api.c [new file with mode: 0644]
src/shared/ask-password-api.h [new file with mode: 0644]
src/shared/audit.c [new file with mode: 0644]
src/shared/audit.h [new file with mode: 0644]
src/shared/calendarspec.c [new file with mode: 0644]
src/shared/calendarspec.h [new file with mode: 0644]
src/shared/capability.c [new file with mode: 0644]
src/shared/capability.h [new file with mode: 0644]
src/shared/cgroup-label.c [new file with mode: 0644]
src/shared/cgroup-show.c [new file with mode: 0644]
src/shared/cgroup-show.h [new file with mode: 0644]
src/shared/cgroup-util.c [new file with mode: 0644]
src/shared/cgroup-util.h [new file with mode: 0644]
src/shared/conf-files.c [new file with mode: 0644]
src/shared/conf-files.h [new file with mode: 0644]
src/shared/conf-parser.c [new file with mode: 0644]
src/shared/conf-parser.h [new file with mode: 0644]
src/shared/dbus-common.c [new file with mode: 0644]
src/shared/dbus-common.h [new file with mode: 0644]
src/shared/dbus-loop.c [new file with mode: 0644]
src/shared/dbus-loop.h [new file with mode: 0644]
src/shared/def.h [new file with mode: 0644]
src/shared/dev-setup.c [new file with mode: 0644]
src/shared/dev-setup.h [new file with mode: 0644]
src/shared/exit-status.c [new file with mode: 0644]
src/shared/exit-status.h [new file with mode: 0644]
src/shared/fdset.c [new file with mode: 0644]
src/shared/fdset.h [new file with mode: 0644]
src/shared/hashmap.c [new file with mode: 0644]
src/shared/hashmap.h [new file with mode: 0644]
src/shared/hwclock.c [new file with mode: 0644]
src/shared/hwclock.h [new file with mode: 0644]
src/shared/install.c [new file with mode: 0644]
src/shared/install.h [new file with mode: 0644]
src/shared/ioprio.h [new file with mode: 0644]
src/shared/label.c [new file with mode: 0644]
src/shared/label.h [new file with mode: 0644]
src/shared/linux/Makefile [new symlink]
src/shared/linux/auto_dev-ioctl.h [new file with mode: 0644]
src/shared/linux/fanotify.h [new file with mode: 0644]
src/shared/linux/seccomp-bpf.h [new file with mode: 0644]
src/shared/linux/seccomp.h [new file with mode: 0644]
src/shared/list.h [new file with mode: 0644]
src/shared/log.c [new file with mode: 0644]
src/shared/log.h [new file with mode: 0644]
src/shared/logs-show.c [new file with mode: 0644]
src/shared/logs-show.h [new file with mode: 0644]
src/shared/macro.h [new file with mode: 0644]
src/shared/missing.h [new file with mode: 0644]
src/shared/mkdir.c [new file with mode: 0644]
src/shared/mkdir.h [new file with mode: 0644]
src/shared/pager.c [new file with mode: 0644]
src/shared/pager.h [new file with mode: 0644]
src/shared/path-lookup.c [new file with mode: 0644]
src/shared/path-lookup.h [new file with mode: 0644]
src/shared/path-util.c [new file with mode: 0644]
src/shared/path-util.h [new file with mode: 0644]
src/shared/polkit.c [new file with mode: 0644]
src/shared/polkit.h [new file with mode: 0644]
src/shared/ratelimit.c [new file with mode: 0644]
src/shared/ratelimit.h [new file with mode: 0644]
src/shared/replace-var.c [new file with mode: 0644]
src/shared/replace-var.h [new file with mode: 0644]
src/shared/selinux-util.c [new file with mode: 0644]
src/shared/selinux-util.h [new file with mode: 0644]
src/shared/set.c [new file with mode: 0644]
src/shared/set.h [new file with mode: 0644]
src/shared/socket-label.c [new file with mode: 0644]
src/shared/socket-util.c [new file with mode: 0644]
src/shared/socket-util.h [new file with mode: 0644]
src/shared/sparse-endian.h [new file with mode: 0644]
src/shared/spawn-ask-password-agent.c [new file with mode: 0644]
src/shared/spawn-ask-password-agent.h [new file with mode: 0644]
src/shared/spawn-polkit-agent.c [new file with mode: 0644]
src/shared/spawn-polkit-agent.h [new file with mode: 0644]
src/shared/specifier.c [new file with mode: 0644]
src/shared/specifier.h [new file with mode: 0644]
src/shared/strbuf.c [new file with mode: 0644]
src/shared/strbuf.h [new file with mode: 0644]
src/shared/strv.c [new file with mode: 0644]
src/shared/strv.h [new file with mode: 0644]
src/shared/time-dst.c [new file with mode: 0644]
src/shared/time-dst.h [new file with mode: 0644]
src/shared/time-util.c [new file with mode: 0644]
src/shared/time-util.h [new file with mode: 0644]
src/shared/unit-name.c [new file with mode: 0644]
src/shared/unit-name.h [new file with mode: 0644]
src/shared/utf8.c [new file with mode: 0644]
src/shared/utf8.h [new file with mode: 0644]
src/shared/util.c [new file with mode: 0644]
src/shared/util.h [new file with mode: 0644]
src/shared/utmp-wtmp.c [new file with mode: 0644]
src/shared/utmp-wtmp.h [new file with mode: 0644]
src/shared/virt.c [new file with mode: 0644]
src/shared/virt.h [new file with mode: 0644]
src/shared/watchdog.c [new file with mode: 0644]
src/shared/watchdog.h [new file with mode: 0644]
src/shutdownd/Makefile [new symlink]
src/shutdownd/shutdownd.c [new file with mode: 0644]
src/sleep/Makefile [new symlink]
src/sleep/sleep.c [new file with mode: 0644]
src/stdio-bridge/Makefile [new symlink]
src/stdio-bridge/stdio-bridge.c [new file with mode: 0644]
src/sysctl/Makefile [new symlink]
src/sysctl/sysctl.c [new file with mode: 0644]
src/system-update-generator/Makefile [new symlink]
src/system-update-generator/system-update-generator.c [new file with mode: 0644]
src/systemctl/Makefile [new symlink]
src/systemctl/systemctl.c [new file with mode: 0644]
src/systemd/Makefile [new symlink]
src/systemd/sd-daemon.h [new file with mode: 0644]
src/systemd/sd-id128.h [new file with mode: 0644]
src/systemd/sd-journal.h [new file with mode: 0644]
src/systemd/sd-login.h [new file with mode: 0644]
src/systemd/sd-messages.h [new file with mode: 0644]
src/systemd/sd-readahead.h [new file with mode: 0644]
src/systemd/sd-shutdown.h [new file with mode: 0644]
src/test/Makefile [new symlink]
src/test/test-calendarspec.c [new file with mode: 0644]
src/test/test-cgroup.c [new file with mode: 0644]
src/test/test-daemon.c [new file with mode: 0644]
src/test/test-date.c [new file with mode: 0644]
src/test/test-engine.c [new file with mode: 0644]
src/test/test-env-replace.c [new file with mode: 0644]
src/test/test-hostname.c [new file with mode: 0644]
src/test/test-id128.c [new file with mode: 0644]
src/test/test-install.c [new file with mode: 0644]
src/test/test-job-type.c [new file with mode: 0644]
src/test/test-libudev.c [new file with mode: 0644]
src/test/test-log.c [new file with mode: 0644]
src/test/test-loopback.c [new file with mode: 0644]
src/test/test-ns.c [new file with mode: 0644]
src/test/test-replace-var.c [new file with mode: 0644]
src/test/test-sched-prio.c [new file with mode: 0644]
src/test/test-sleep.c [new file with mode: 0644]
src/test/test-strip-tab-ansi.c [new file with mode: 0644]
src/test/test-strv.c [new file with mode: 0644]
src/test/test-udev.c [new file with mode: 0644]
src/test/test-unit-file.c [new file with mode: 0644]
src/test/test-unit-name.c [new file with mode: 0644]
src/test/test-watchdog.c [new file with mode: 0644]
src/timedate/.gitignore [new file with mode: 0644]
src/timedate/Makefile [new symlink]
src/timedate/org.freedesktop.timedate1.conf [new file with mode: 0644]
src/timedate/org.freedesktop.timedate1.policy.in [new file with mode: 0644]
src/timedate/org.freedesktop.timedate1.service [new file with mode: 0644]
src/timedate/timedatectl.c [new file with mode: 0644]
src/timedate/timedated.c [new file with mode: 0644]
src/timestamp/Makefile [new symlink]
src/timestamp/timestamp.c [new file with mode: 0644]
src/tmpfiles/Makefile [new symlink]
src/tmpfiles/tmpfiles.c [new file with mode: 0644]
src/tty-ask-password-agent/Makefile [new symlink]
src/tty-ask-password-agent/tty-ask-password-agent.c [new file with mode: 0644]
src/udev/.gitignore [new file with mode: 0644]
src/udev/.vimrc [new file with mode: 0644]
src/udev/Makefile [new symlink]
src/udev/accelerometer/accelerometer.c [new file with mode: 0644]
src/udev/ata_id/ata_id.c [new file with mode: 0644]
src/udev/cdrom_id/cdrom_id.c [new file with mode: 0644]
src/udev/collect/collect.c [new file with mode: 0644]
src/udev/keymap/.gitignore [new file with mode: 0644]
src/udev/keymap/95-keyboard-force-release.rules [new file with mode: 0644]
src/udev/keymap/95-keymap.rules [new file with mode: 0644]
src/udev/keymap/README.keymap.txt [new file with mode: 0644]
src/udev/keymap/check-keymaps.sh [new file with mode: 0755]
src/udev/keymap/findkeyboards [new file with mode: 0755]
src/udev/keymap/keyboard-force-release.sh.in [new file with mode: 0755]
src/udev/keymap/keymap.c [new file with mode: 0644]
src/udev/mtd_probe/mtd_probe.c [new file with mode: 0644]
src/udev/mtd_probe/mtd_probe.h [new file with mode: 0644]
src/udev/mtd_probe/probe_smartmedia.c [new file with mode: 0644]
src/udev/scsi_id/.gitignore [new file with mode: 0644]
src/udev/scsi_id/README [new file with mode: 0644]
src/udev/scsi_id/scsi.h [new file with mode: 0644]
src/udev/scsi_id/scsi_id.c [new file with mode: 0644]
src/udev/scsi_id/scsi_id.h [new file with mode: 0644]
src/udev/scsi_id/scsi_serial.c [new file with mode: 0644]
src/udev/udev-builtin-blkid.c [new file with mode: 0644]
src/udev/udev-builtin-btrfs.c [new file with mode: 0644]
src/udev/udev-builtin-firmware.c [new file with mode: 0644]
src/udev/udev-builtin-hwdb.c [new file with mode: 0644]
src/udev/udev-builtin-input_id.c [new file with mode: 0644]
src/udev/udev-builtin-kmod.c [new file with mode: 0644]
src/udev/udev-builtin-net_id.c [new file with mode: 0644]
src/udev/udev-builtin-path_id.c [new file with mode: 0644]
src/udev/udev-builtin-uaccess.c [new file with mode: 0644]
src/udev/udev-builtin-usb_id.c [new file with mode: 0644]
src/udev/udev-builtin.c [new file with mode: 0644]
src/udev/udev-ctrl.c [new file with mode: 0644]
src/udev/udev-event.c [new file with mode: 0644]
src/udev/udev-node.c [new file with mode: 0644]
src/udev/udev-rules.c [new file with mode: 0644]
src/udev/udev-watch.c [new file with mode: 0644]
src/udev/udev.conf [new file with mode: 0644]
src/udev/udev.h [new file with mode: 0644]
src/udev/udev.pc.in [new file with mode: 0644]
src/udev/udevadm-control.c [new file with mode: 0644]
src/udev/udevadm-hwdb.c [new file with mode: 0644]
src/udev/udevadm-info.c [new file with mode: 0644]
src/udev/udevadm-monitor.c [new file with mode: 0644]
src/udev/udevadm-settle.c [new file with mode: 0644]
src/udev/udevadm-test-builtin.c [new file with mode: 0644]
src/udev/udevadm-test.c [new file with mode: 0644]
src/udev/udevadm-trigger.c [new file with mode: 0644]
src/udev/udevadm.c [new file with mode: 0644]
src/udev/udevd.c [new file with mode: 0644]
src/udev/v4l_id/v4l_id.c [new file with mode: 0644]
src/update-utmp/Makefile [new symlink]
src/update-utmp/update-utmp.c [new file with mode: 0644]
src/vconsole/Makefile [new symlink]
src/vconsole/vconsole-setup.c [new file with mode: 0644]
sysctl.d/.gitignore [new file with mode: 0644]
sysctl.d/Makefile [new symlink]
sysctl.d/coredump.conf.in [new file with mode: 0644]
test/.gitignore [new file with mode: 0644]
test/Makefile [new file with mode: 0644]
test/README.testsuite [new file with mode: 0644]
test/TEST-01-BASIC/Makefile [new file with mode: 0644]
test/TEST-01-BASIC/test.sh [new file with mode: 0755]
test/TEST-02-CRYPTSETUP/Makefile [new symlink]
test/TEST-02-CRYPTSETUP/test.sh [new file with mode: 0755]
test/a.service [new file with mode: 0644]
test/b.service [new file with mode: 0644]
test/c.service [new file with mode: 0644]
test/d.service [new file with mode: 0644]
test/e.service [new file with mode: 0644]
test/f.service [new file with mode: 0644]
test/g.service [new file with mode: 0644]
test/h.service [new file with mode: 0644]
test/rule-syntax-check.py [new file with mode: 0755]
test/rules-test.sh [new file with mode: 0755]
test/sched_idle_bad.service [new file with mode: 0644]
test/sched_idle_ok.service [new file with mode: 0644]
test/sched_rr_bad.service [new file with mode: 0644]
test/sched_rr_change.service [new file with mode: 0644]
test/sched_rr_ok.service [new file with mode: 0644]
test/sys.tar.xz [new file with mode: 0644]
test/test-functions [new file with mode: 0644]
test/udev-test.pl [new file with mode: 0755]
tmpfiles.d/Makefile [new symlink]
tmpfiles.d/legacy.conf [new file with mode: 0644]
tmpfiles.d/systemd.conf [new file with mode: 0644]
tmpfiles.d/tmp.conf [new file with mode: 0644]
tmpfiles.d/x11.conf [new file with mode: 0644]
units/.gitignore [new file with mode: 0644]
units/Makefile [new symlink]
units/basic.target [new file with mode: 0644]
units/bluetooth.target [new file with mode: 0644]
units/console-getty.service.m4.in [new file with mode: 0644]
units/console-shell.service.m4.in [new file with mode: 0644]
units/cryptsetup.target [new file with mode: 0644]
units/debug-shell.service.in [new file with mode: 0644]
units/dev-hugepages.mount [new file with mode: 0644]
units/dev-mqueue.mount [new file with mode: 0644]
units/emergency.service.in [new file with mode: 0644]
units/emergency.target [new file with mode: 0644]
units/final.target [new file with mode: 0644]
units/getty.target [new file with mode: 0644]
units/getty@.service.m4 [new file with mode: 0644]
units/graphical.target [new file with mode: 0644]
units/halt-local.service.in [new file with mode: 0644]
units/halt.target [new file with mode: 0644]
units/hibernate.target [new file with mode: 0644]
units/hybrid-sleep.target [new file with mode: 0644]
units/kexec.target [new file with mode: 0644]
units/local-fs-pre.target [new file with mode: 0644]
units/local-fs.target [new file with mode: 0644]
units/mail-transfer-agent.target [new file with mode: 0644]
units/multi-user.target [new file with mode: 0644]
units/network.target [new file with mode: 0644]
units/nss-lookup.target [new file with mode: 0644]
units/nss-user-lookup.target [new file with mode: 0644]
units/poweroff.target [new file with mode: 0644]
units/printer.target [new file with mode: 0644]
units/proc-sys-fs-binfmt_misc.automount [new file with mode: 0644]
units/proc-sys-fs-binfmt_misc.mount [new file with mode: 0644]
units/quotaon.service.in [new file with mode: 0644]
units/rc-local.service.in [new file with mode: 0644]
units/reboot.target [new file with mode: 0644]
units/remote-fs-pre.target [new file with mode: 0644]
units/remote-fs.target [new file with mode: 0644]
units/rescue.service.m4.in [new file with mode: 0644]
units/rescue.target [new file with mode: 0644]
units/rpcbind.target [new file with mode: 0644]
units/serial-getty@.service.m4 [new file with mode: 0644]
units/shutdown.target [new file with mode: 0644]
units/sigpwr.target [new file with mode: 0644]
units/sleep.target [new file with mode: 0644]
units/smartcard.target [new file with mode: 0644]
units/sockets.target [new file with mode: 0644]
units/sound.target [new file with mode: 0644]
units/suspend.target [new file with mode: 0644]
units/swap.target [new file with mode: 0644]
units/sys-fs-fuse-connections.mount [new file with mode: 0644]
units/sys-kernel-config.mount [new file with mode: 0644]
units/sys-kernel-debug.mount [new file with mode: 0644]
units/sysinit.target [new file with mode: 0644]
units/syslog.socket [new file with mode: 0644]
units/syslog.target [new file with mode: 0644]
units/system-update.target [new file with mode: 0644]
units/systemd-ask-password-console.path [new file with mode: 0644]
units/systemd-ask-password-console.service.in [new file with mode: 0644]
units/systemd-ask-password-wall.path [new file with mode: 0644]
units/systemd-ask-password-wall.service.in [new file with mode: 0644]
units/systemd-binfmt.service.in [new file with mode: 0644]
units/systemd-fsck-root.service.in [new file with mode: 0644]
units/systemd-fsck@.service.in [new file with mode: 0644]
units/systemd-halt.service.in [new file with mode: 0644]
units/systemd-hibernate.service.in [new file with mode: 0644]
units/systemd-hostnamed.service.in [new file with mode: 0644]
units/systemd-hybrid-sleep.service.in [new file with mode: 0644]
units/systemd-initctl.service.in [new file with mode: 0644]
units/systemd-initctl.socket [new file with mode: 0644]
units/systemd-journal-flush.service.in [new file with mode: 0644]
units/systemd-journal-gatewayd.service.in [new file with mode: 0644]
units/systemd-journal-gatewayd.socket [new file with mode: 0644]
units/systemd-journald.service.in [new file with mode: 0644]
units/systemd-journald.socket [new file with mode: 0644]
units/systemd-kexec.service.in [new file with mode: 0644]
units/systemd-localed.service.in [new file with mode: 0644]
units/systemd-logind.service.in [new file with mode: 0644]
units/systemd-modules-load.service.in [new file with mode: 0644]
units/systemd-poweroff.service.in [new file with mode: 0644]
units/systemd-quotacheck.service.in [new file with mode: 0644]
units/systemd-random-seed-load.service.in [new file with mode: 0644]
units/systemd-random-seed-save.service.in [new file with mode: 0644]
units/systemd-readahead-collect.service.in [new file with mode: 0644]
units/systemd-readahead-done.service.in [new file with mode: 0644]
units/systemd-readahead-done.timer [new file with mode: 0644]
units/systemd-readahead-drop.service [new file with mode: 0644]
units/systemd-readahead-replay.service.in [new file with mode: 0644]
units/systemd-reboot.service.in [new file with mode: 0644]
units/systemd-remount-fs.service.in [new file with mode: 0644]
units/systemd-shutdownd.service.in [new file with mode: 0644]
units/systemd-shutdownd.socket [new file with mode: 0644]
units/systemd-suspend.service.in [new file with mode: 0644]
units/systemd-sysctl.service.in [new file with mode: 0644]
units/systemd-timedated.service.in [new file with mode: 0644]
units/systemd-tmpfiles-clean.service.in [new file with mode: 0644]
units/systemd-tmpfiles-clean.timer [new file with mode: 0644]
units/systemd-tmpfiles-setup.service.in [new file with mode: 0644]
units/systemd-udev-settle.service.in [new file with mode: 0644]
units/systemd-udev-trigger.service.in [new file with mode: 0644]
units/systemd-udevd-control.socket [new file with mode: 0644]
units/systemd-udevd-kernel.socket [new file with mode: 0644]
units/systemd-udevd.service.in [new file with mode: 0644]
units/systemd-update-utmp-runlevel.service.in [new file with mode: 0644]
units/systemd-update-utmp-shutdown.service.in [new file with mode: 0644]
units/systemd-user-sessions.service.in [new file with mode: 0644]
units/systemd-vconsole-setup.service.in [new file with mode: 0644]
units/time-sync.target [new file with mode: 0644]
units/tmp.mount [new file with mode: 0644]
units/umount.target [new file with mode: 0644]
units/user/.gitignore [new file with mode: 0644]
units/user/Makefile [new symlink]
units/user/default.target [new file with mode: 0644]
units/user/exit.target [new file with mode: 0644]
units/user/systemd-exit.service.in [new file with mode: 0644]
units/user@.service.in [new file with mode: 0644]

diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644 (file)
index 0000000..9d9f8cd
--- /dev/null
@@ -0,0 +1,7 @@
+; Sets emacs variables based on mode.
+; A list of (major-mode . ((var1 . value1) (var2 . value2)))
+; Mode can be nil, which gives default values.
+
+((nil . ((indent-tabs-mode . nil)
+         (tab-width . 8)))
+)
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..a551904
--- /dev/null
@@ -0,0 +1,138 @@
+/Makefile
+/TAGS
+/accelerometer
+/ata_id
+/build-aux
+/cdrom_id
+/collect
+/gtk-doc.make
+/hostnamectl
+/install-tree
+/journalctl
+/keymap
+/libtool
+/localectl
+/loginctl
+/mtd_probe
+/org.freedesktop.hostname1.xml
+/org.freedesktop.locale1.xml
+/org.freedesktop.systemd1.*.xml
+/org.freedesktop.timedate1.xml
+/scsi_id
+/systemadm
+/systemctl
+/systemd
+/systemd-ac-power
+/systemd-ask-password
+/systemd-binfmt
+/systemd-cat
+/systemd-cgls
+/systemd-cgroups-agent
+/systemd-cgtop
+/systemd-coredump
+/systemd-coredumpctl
+/systemd-cryptsetup
+/systemd-cryptsetup-generator
+/systemd-delta
+/systemd-detect-virt
+/systemd-fsck
+/systemd-fstab-generator
+/systemd-getty-generator
+/systemd-gnome-ask-password-agent
+/systemd-hostnamed
+/systemd-inhibit
+/systemd-initctl
+/systemd-journal-gatewayd
+/systemd-journald
+/systemd-kmsg-syslogd
+/systemd-localed
+/systemd-logind
+/systemd-machine-id-setup
+/systemd-modules-load
+/systemd-multi-seat-x
+/systemd-notify
+/systemd-nspawn
+/systemd-quotacheck
+/systemd-random-seed
+/systemd-rc-local-generator
+/systemd-readahead
+/systemd-remount-api-vfs
+/systemd-remount-fs
+/systemd-reply-password
+/systemd-shutdown
+/systemd-shutdownd
+/systemd-sleep
+/systemd-stdio-bridge
+/systemd-sysctl
+/systemd-system-update-generator
+/systemd-timedated
+/systemd-timestamp
+/systemd-tmpfiles
+/systemd-tty-ask-password-agent
+/systemd-uaccess
+/systemd-udevd
+/systemd-update-utmp
+/systemd-user-sessions
+/systemd-vconsole-setup
+/tags
+/test-calendarspec
+/test-catalog
+/test-cgroup
+/test-daemon
+/test-date
+/test-engine
+/test-env-replace
+/test-hostname
+/test-id128
+/test-inhibit
+/test-install
+/test-job-type
+/test-journal
+/test-journal-enum
+/test-journal-match
+/test-journal-send
+/test-journal-stream
+/test-journal-syslog
+/test-journal-verify
+/test-libudev
+/test-log
+/test-login
+/test-loopback
+/test-mmap-cache
+/test-ns
+/test-replace-var
+/test-sched-prio
+/test-sleep
+/test-strip-tab-ansi
+/test-strv
+/test-udev
+/test-unit-file
+/test-unit-name
+/test-watchdog
+/timedatectl
+/udevadm
+/v4l_id
+/*.tar.bz2
+/*.tar.gz
+/*.tar.xz
+*.trs
+*.log
+*.a
+*.cache
+*.html
+*.la
+*.lo
+*.o
+*.stamp
+*~
+.deps/
+.dirstamp
+.libs/
+Makefile.in
+aclocal.m4
+config.h
+config.h.in
+config.log
+config.status
+configure
+stamp-*
diff --git a/.mailmap b/.mailmap
new file mode 100644 (file)
index 0000000..da8ca84
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,45 @@
+Kay Sievers <kay@vrfy.org>
+Kay Sievers <kay@vrfy.org> <kay.sievers@vrfy.org>
+Kay Sievers <kay@vrfy.org> <kay.sievers@suse.de>
+Kay Sievers <kay@vrfy.org> <kay@pim.off.vrfy.org>
+Kay Sievers <kay@vrfy.org> <kay@pim>
+Greg KH <greg@kroah.com>
+Greg KH <greg@kroah.com> <greg@kroah.com>
+Greg KH <greg@kroah.com> <greg@press.(none)>
+Greg KH <greg@kroah.com> <gregkh@suse.de>
+Harald Hoyer <harald@redhat.com>
+David Zeuthen <david@fubar.dk>
+David Zeuthen <david@fubar.dk> <davidz@redhat.com>
+David Zeuthen <david@fubar.dk> <zeuthen@gmail.com>
+Hannes Reinecke <hare@suse.de>
+Scott James Remnant <scott@netsplit.com>
+Scott James Remnant <scott@netsplit.com>  <scott@ubuntu.com>
+Alan Jenkins <alan.christopher.jenkins@googlemail.com>
+Alan Jenkins <alan.christopher.jenkins@googlemail.com> <alan-jenkins@tuffmail.co.uk>
+Marco d'Itri <md@linux.it> <md@Linux.IT>
+Robert Gerus <ar@bash.org.pl> Robert "arachnist" Gerus <ar@bash.org.pl>
+Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> Zbyszek Szmek <zbyszek@in.waw.pl>
+Fabiano Fidêncio <fabianofidencio@gmail.com> Fabiano Fidencio <fidencio@profusion.mobi>
+Martin Pitt <martinpitt@gnome.org>
+Martin Pitt <martinpitt@gnome.org> <martin.pitt@ubuntu.com>
+Daniel J Walsh <dwalsh@redhat.com>
+Dave Reisner <dreisner@archlinux.org> <d@falconindy.com>
+Diego Elio Pettenò <flameeyes@gmail.com>
+Daniel Elstner  <daniel.kitta@gmail.com> <danielk@openismus.com>
+Frederic Crozat <fcrozat@suse.com> <fcrozat@mandriva.com>
+Ian Campbell <ijc@hellion.org.uk> <Ian.Campbell@citrix.com>
+Jerone Young <jyoung@redhat.com> <jerone.young@canonical.com>
+Luis Felipe Strano Moraes <luis.strano@gmail.com> <lfelipe@profusion.mobi>
+Mario Limonciello <mario_limonciello@dell.com> <Mario_Limonciello@dell.com>
+Matthias Clasen <mclasen@redhat.com> <matthias.clasen@gmail.com>
+Michal Soltys <soltys@ziu.info> <nozo@ziu.info>
+Piter PUNK <piterpunk@slackware.com> <piterpk@terra.com.br>
+Richard Hughes <richard@hughsie.com> <hughsient@gmail.com>
+Robby Workman <rw@rlworkman.net> <rworkman@slackware.com>
+Shawn Landden <shawnlandden@gmail.com>
+Simon Peeters <peeters.simon@gmail.com>
+Tobias Klauser <tklauser@distanz.ch> <tklauser@nuerscht.ch>
+Miklos Vajna <vmiklos@frugalware.org> <vmiklos@gmail.com>
+William Jon McCann <jmccann@redhat.com> <william.jon.mccann@gmail.com>
+Yin Kangkai <kangkai.yin@intel.com> <kangkai.yin@linux.intel.com>
+Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
diff --git a/.vimrc b/.vimrc
new file mode 100644 (file)
index 0000000..366fbdc
--- /dev/null
+++ b/.vimrc
@@ -0,0 +1,4 @@
+" 'set exrc' in ~/.vimrc will read .vimrc from the current directory
+set tabstop=8
+set shiftwidth=8
+set expandtab
diff --git a/CODING_STYLE b/CODING_STYLE
new file mode 100644 (file)
index 0000000..04b4ed2
--- /dev/null
@@ -0,0 +1,27 @@
+
+- 8ch indent, no tabs
+
+- structs in MixedCase, variables, functions in lower_case
+
+- the destructors always unregister the object from the next bigger
+  object, not the other way around
+
+- to minimize strict aliasing violations we prefer unions over casting
+
+- for robustness reasons destructors should be able to destruct
+  half-initialized objects, too
+
+- error codes are returned as negative Exxx. i.e. return -EINVAL. There
+  are some exceptions: for constructors its is OK to return NULL on
+  OOM. For lookup functions NULL is fine too for "not found"
+
+- Do not issue NSS requests (that includes user name and host name
+  lookups) from the main daemon as this might trigger deadlocks when
+  we those lookups involve synchronously talking to services that we
+  would need to start up
+
+- Do not access any directories outside of /etc, /dev, /lib from the
+  init daemon to avoid deadlocks with the automounter
+
+- Don't synchronously talk to any other service, due to risk of
+  deadlocks
diff --git a/DISTRO_PORTING b/DISTRO_PORTING
new file mode 100644 (file)
index 0000000..99c652c
--- /dev/null
@@ -0,0 +1,34 @@
+Porting systemd To New Distributions
+
+HOWTO:
+        You need to make the follow changes to adapt systemd to your
+        distribution:
+
+        1) Find the right configure parameters for:
+
+            --with-rootprefix=
+            --with-sysvinit-path=
+            --with-sysvrcd-path=
+            --with-rc-local-script-path-start=
+            --with-rc-local-script-path-stop=
+            --with-kbd-loadkeys=
+            --with-kbd-setfont=
+            --with-tty-gid=
+
+        2) Try it out. Play around with 'systemd --test --system' for
+        a test run of systemd without booting. This will read the unit
+        files and print the initial transaction it would execute
+        during boot-up. This will also inform you about ordering loops
+        and suchlike.
+
+CONTRIBUTING UPSTREAM:
+
+        We are generally do no longer accept distribution specific
+        patches to systemd upstream. If you have to make changes to
+        systemd's source code to make it work on your distribution:
+        unless your code is generic enough to be generally useful we
+        are unlikely to merge it. Please always consider adopting the
+        upstream defaults. If that's not possible please maintain the
+        relevant patches downstream.
+
+        Thank you for understanding.
diff --git a/LICENSE.GPL2 b/LICENSE.GPL2
new file mode 100644 (file)
index 0000000..d511905
--- /dev/null
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/LICENSE.LGPL2.1 b/LICENSE.LGPL2.1
new file mode 100644 (file)
index 0000000..4362b49
--- /dev/null
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENSE.MIT b/LICENSE.MIT
new file mode 100644 (file)
index 0000000..fd44f73
--- /dev/null
@@ -0,0 +1,19 @@
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..9920bc1
--- /dev/null
@@ -0,0 +1,4101 @@
+#  -*- Mode: makefile; indent-tabs-mode: t -*- */
+#
+#  This file is part of systemd.
+#
+#  Copyright 2010-2012 Lennart Poettering
+#  Copyright 2010-2012 Kay Sievers
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
+AM_MAKEFLAGS = --no-print-directory
+AUTOMAKE_OPTIONS = color-tests parallel-tests
+
+SUBDIRS = . po
+
+# remove targets if the command fails
+.DELETE_ON_ERROR:
+
+LIBUDEV_CURRENT=3
+LIBUDEV_REVISION=0
+LIBUDEV_AGE=2
+
+LIBGUDEV_CURRENT=1
+LIBGUDEV_REVISION=2
+LIBGUDEV_AGE=1
+
+LIBSYSTEMD_LOGIN_CURRENT=3
+LIBSYSTEMD_LOGIN_REVISION=10
+LIBSYSTEMD_LOGIN_AGE=3
+
+LIBSYSTEMD_DAEMON_CURRENT=0
+LIBSYSTEMD_DAEMON_REVISION=6
+LIBSYSTEMD_DAEMON_AGE=0
+
+LIBSYSTEMD_ID128_CURRENT=0
+LIBSYSTEMD_ID128_REVISION=16
+LIBSYSTEMD_ID128_AGE=0
+
+LIBSYSTEMD_JOURNAL_CURRENT=7
+LIBSYSTEMD_JOURNAL_REVISION=0
+LIBSYSTEMD_JOURNAL_AGE=7
+
+# Dirs of external packages
+dbuspolicydir=@dbuspolicydir@
+dbussessionservicedir=@dbussessionservicedir@
+dbussystemservicedir=@dbussystemservicedir@
+dbusinterfacedir=@dbusinterfacedir@
+pamlibdir=@pamlibdir@
+pkgconfigdatadir=$(datadir)/pkgconfig
+pkgconfiglibdir=$(libdir)/pkgconfig
+polkitpolicydir=$(datadir)/polkit-1/actions
+bashcompletiondir=$(sysconfdir)/bash_completion.d
+rpmmacrosdir=$(sysconfdir)/rpm
+sysvinitdir=$(SYSTEM_SYSVINIT_PATH)
+sysvrcddir=$(SYSTEM_SYSVRCND_PATH)
+varlogdir=$(localstatedir)/log
+systemdstatedir=$(localstatedir)/lib/systemd
+catalogstatedir=$(systemdstatedir)/catalog
+hwdb_bin=/etc/udev/hwdb.bin
+
+# Our own, non-special dirs
+pkgsysconfdir=$(sysconfdir)/systemd
+userunitdir=$(prefix)/lib/systemd/user
+userpresetdir=$(prefix)/lib/systemd/user-preset
+tmpfilesdir=$(prefix)/lib/tmpfiles.d
+sysctldir=$(prefix)/lib/sysctl.d
+usergeneratordir=$(prefix)/lib/systemd/user-generators
+pkgincludedir=$(includedir)/systemd
+systemgeneratordir=$(rootlibexecdir)/system-generators
+systemshutdowndir=$(rootlibexecdir)/system-shutdown
+systemsleepdir=$(rootlibexecdir)/system-sleep
+systemunitdir=$(rootprefix)/lib/systemd/system
+systempresetdir=$(rootprefix)/lib/systemd/system-preset
+udevlibexecdir=$(rootprefix)/lib/udev
+udevhomedir=$(udevlibexecdir)
+udevrulesdir=$(udevlibexecdir)/rules.d
+udevhwdbdir=$(udevlibexecdir)/hwdb.d
+catalogdir=$(prefix)/lib/systemd/catalog
+
+# And these are the special ones for /
+rootprefix=@rootprefix@
+rootbindir=$(rootprefix)/bin
+rootlibexecdir=$(rootprefix)/lib/systemd
+
+CLEANFILES = $(BUILT_SOURCES)
+EXTRA_DIST =
+BUILT_SOURCES =
+INSTALL_EXEC_HOOKS =
+UNINSTALL_EXEC_HOOKS =
+INSTALL_DATA_HOOKS =
+UNINSTALL_DATA_HOOKS =
+DISTCLEAN_LOCAL_HOOKS =
+pkginclude_HEADERS =
+noinst_LTLIBRARIES =
+lib_LTLIBRARIES =
+include_HEADERS =
+pkgconfiglib_DATA =
+polkitpolicy_in_files =
+polkitpolicy_files =
+dist_udevrules_DATA =
+nodist_udevrules_DATA =
+dist_man_MANS =
+dist_pkgsysconf_DATA =
+dist_pkgdata_DATA =
+dist_dbuspolicy_DATA =
+dbusinterface_DATA =
+dist_dbussystemservice_DATA =
+check_PROGRAMS =
+check_DATA =
+noinst_PROGRAMS =
+TESTS =
+udevlibexec_PROGRAMS =
+
+AM_CPPFLAGS = \
+       -include $(top_builddir)/config.h \
+       -DSYSTEM_CONFIG_FILE=\"$(pkgsysconfdir)/system.conf\" \
+       -DSYSTEM_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/system\" \
+       -DSYSTEM_DATA_UNIT_PATH=\"$(systemunitdir)\" \
+       -DSYSTEM_SYSVINIT_PATH=\"$(SYSTEM_SYSVINIT_PATH)\" \
+       -DSYSTEM_SYSVRCND_PATH=\"$(SYSTEM_SYSVRCND_PATH)\" \
+       -DUSER_CONFIG_FILE=\"$(pkgsysconfdir)/user.conf\" \
+       -DUSER_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/user\" \
+       -DUSER_DATA_UNIT_PATH=\"$(userunitdir)\" \
+       -DCATALOG_PATH=\"$(catalogstatedir)\" \
+       -DHWDB_BIN=\"$(hwdb_bin)\" \
+       -DSYSTEMD_CGROUP_AGENT_PATH=\"$(rootlibexecdir)/systemd-cgroups-agent\" \
+       -DSYSTEMD_BINARY_PATH=\"$(rootlibexecdir)/systemd\" \
+       -DSYSTEMD_SHUTDOWN_BINARY_PATH=\"$(rootlibexecdir)/systemd-shutdown\" \
+       -DSYSTEMD_SLEEP_BINARY_PATH=\"$(rootlibexecdir)/systemd-sleep\" \
+       -DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \
+       -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \
+       -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \
+       -DROOTPREFIX=\"$(rootprefix)\" \
+       -DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \
+       -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \
+       -DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \
+       -DUSER_GENERATOR_PATH=\"$(usergeneratordir)\" \
+       -DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \
+       -DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \
+       -DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
+       -DX_SERVER=\"$(bindir)/X\" \
+       -DUDEVLIBEXECDIR=\"$(udevlibexecdir)\" \
+       -DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \
+       -I $(top_srcdir)/src \
+       -I $(top_srcdir)/src/shared \
+       -I $(top_srcdir)/src/login \
+       -I $(top_srcdir)/src/journal \
+       -I $(top_srcdir)/src/systemd \
+       -I $(top_builddir)/src/core \
+       -I $(top_srcdir)/src/core \
+       -I $(top_srcdir)/src/libudev \
+       -I $(top_srcdir)/src/udev \
+       $(OUR_CPPFLAGS)
+
+AM_CFLAGS = $(OUR_CFLAGS)
+AM_LDFLAGS = $(OUR_LDFLAGS)
+
+# ------------------------------------------------------------------------------
+
+define move-to-rootlibdir
+       if test "$(libdir)" != "$(rootlibdir)"; then \
+               $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
+               so_img_name=$$(readlink $(DESTDIR)$(libdir)/$$libname) && \
+               so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
+               ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/$$libname && \
+               mv $(DESTDIR)$(libdir)/$$libname.* $(DESTDIR)$(rootlibdir); \
+       fi
+endef
+
+# ------------------------------------------------------------------------------
+rootbin_PROGRAMS = \
+       systemctl \
+       systemd-notify \
+       systemd-ask-password \
+       systemd-tty-ask-password-agent \
+       systemd-tmpfiles \
+       systemd-machine-id-setup
+
+bin_PROGRAMS = \
+       systemd-cgls \
+       systemd-cgtop \
+       systemd-stdio-bridge \
+       systemd-nspawn \
+       systemd-detect-virt \
+       systemd-delta
+
+rootlibexec_PROGRAMS = \
+       systemd \
+       systemd-cgroups-agent \
+       systemd-initctl \
+       systemd-update-utmp \
+       systemd-shutdownd \
+       systemd-shutdown \
+       systemd-remount-fs \
+       systemd-reply-password \
+       systemd-fsck \
+       systemd-timestamp \
+       systemd-ac-power \
+       systemd-sysctl \
+       systemd-sleep
+
+if HAVE_KMOD
+rootlibexec_PROGRAMS += \
+       systemd-modules-load
+endif
+
+systemgenerator_PROGRAMS = \
+       systemd-getty-generator \
+       systemd-fstab-generator \
+       systemd-system-update-generator
+
+dist_bin_SCRIPTS = \
+       src/analyze/systemd-analyze
+
+EXTRA_DIST += \
+       src/analyze/systemd-analyze.in
+
+CLEANFILES += \
+       src/analyze/systemd-analyze
+
+dist_bashcompletion_DATA = \
+       shell-completion/systemd-bash-completion.sh
+
+dist_tmpfiles_DATA = \
+       tmpfiles.d/systemd.conf \
+       tmpfiles.d/tmp.conf \
+       tmpfiles.d/x11.conf
+
+if HAVE_SYSV_COMPAT
+dist_tmpfiles_DATA += \
+       tmpfiles.d/legacy.conf
+endif
+
+dist_systemunit_DATA = \
+       units/graphical.target \
+       units/multi-user.target \
+       units/emergency.service \
+       units/emergency.target \
+       units/sysinit.target \
+       units/basic.target \
+       units/getty.target \
+       units/halt.target \
+       units/kexec.target \
+       units/local-fs.target \
+       units/local-fs-pre.target \
+       units/remote-fs.target \
+       units/remote-fs-pre.target \
+       units/network.target \
+       units/nss-lookup.target \
+       units/nss-user-lookup.target \
+       units/mail-transfer-agent.target \
+       units/hibernate.target \
+       units/hybrid-sleep.target \
+       units/poweroff.target \
+       units/reboot.target \
+       units/rescue.target \
+       units/rpcbind.target \
+       units/time-sync.target \
+       units/shutdown.target \
+       units/final.target \
+       units/umount.target \
+       units/sigpwr.target \
+       units/sleep.target \
+       units/sockets.target \
+       units/suspend.target \
+       units/swap.target \
+       units/systemd-initctl.socket \
+       units/systemd-shutdownd.socket \
+       units/syslog.socket \
+       units/dev-hugepages.mount \
+       units/dev-mqueue.mount \
+       units/sys-kernel-config.mount \
+       units/sys-kernel-debug.mount \
+       units/sys-fs-fuse-connections.mount \
+       units/tmp.mount \
+       units/printer.target \
+       units/sound.target \
+       units/bluetooth.target \
+       units/smartcard.target \
+       units/systemd-tmpfiles-clean.timer \
+       units/quotaon.service \
+       units/systemd-ask-password-wall.path \
+       units/systemd-ask-password-console.path \
+       units/syslog.target \
+       units/systemd-udevd-control.socket \
+       units/systemd-udevd-kernel.socket \
+       units/system-update.target
+
+nodist_systemunit_DATA = \
+       units/getty@.service \
+       units/serial-getty@.service \
+       units/console-shell.service \
+       units/console-getty.service \
+       units/systemd-initctl.service \
+       units/systemd-shutdownd.service \
+       units/systemd-remount-fs.service \
+       units/systemd-update-utmp-runlevel.service \
+       units/systemd-update-utmp-shutdown.service \
+       units/systemd-tmpfiles-setup.service \
+       units/systemd-tmpfiles-clean.service \
+       units/systemd-ask-password-wall.service \
+       units/systemd-ask-password-console.service \
+       units/systemd-sysctl.service \
+       units/emergency.service \
+       units/rescue.service \
+       units/user@.service \
+       units/systemd-hibernate.service \
+       units/systemd-hybrid-sleep.service \
+       units/systemd-suspend.service \
+       units/systemd-halt.service \
+       units/systemd-poweroff.service \
+       units/systemd-reboot.service \
+       units/systemd-kexec.service \
+       units/systemd-fsck@.service \
+       units/systemd-fsck-root.service \
+       units/systemd-udevd.service \
+       units/systemd-udev-trigger.service \
+       units/systemd-udev-settle.service \
+       units/debug-shell.service
+
+if HAVE_KMOD
+nodist_systemunit_DATA += \
+       units/systemd-modules-load.service
+endif
+
+dist_userunit_DATA = \
+       units/user/default.target \
+       units/user/exit.target
+
+nodist_userunit_DATA = \
+       units/user/systemd-exit.service
+
+EXTRA_DIST += \
+       units/getty@.service.m4 \
+       units/serial-getty@.service.m4 \
+       units/console-shell.service.m4.in \
+       units/console-getty.service.m4.in \
+       units/rescue.service.m4.in \
+       units/systemd-initctl.service.in \
+       units/systemd-shutdownd.service.in \
+       units/systemd-remount-fs.service.in \
+       units/systemd-update-utmp-runlevel.service.in \
+       units/systemd-update-utmp-shutdown.service.in \
+       units/systemd-tmpfiles-setup.service.in \
+       units/systemd-tmpfiles-clean.service.in \
+       units/systemd-ask-password-wall.service.in \
+       units/systemd-ask-password-console.service.in \
+       units/systemd-sysctl.service.in \
+       units/emergency.service.in \
+       units/systemd-halt.service.in \
+       units/systemd-poweroff.service.in \
+       units/systemd-reboot.service.in \
+       units/systemd-kexec.service.in \
+       units/user/systemd-exit.service.in \
+       units/systemd-fsck@.service.in \
+       units/systemd-fsck-root.service.in \
+       units/user@.service.in \
+       units/systemd-udevd.service \
+       units/systemd-udev-trigger.service \
+       units/systemd-udev-settle.service \
+       units/debug-shell.service.in \
+       units/systemd-hibernate.service.in \
+       units/systemd-hybrid-sleep.service.in \
+       units/systemd-suspend.service.in \
+       units/quotaon.service.in \
+       introspect.awk \
+       man/custom-html.xsl
+
+if HAVE_KMOD
+EXTRA_DIST += \
+       units/systemd-modules-load.service.in
+endif
+
+if HAVE_SYSV_COMPAT
+nodist_systemunit_DATA += \
+       units/rc-local.service \
+       units/halt-local.service
+
+EXTRA_DIST += \
+       units/rc-local.service.in \
+       units/halt-local.service.in
+
+systemgenerator_PROGRAMS += \
+       systemd-rc-local-generator
+endif
+
+dist_doc_DATA = \
+       README \
+       NEWS \
+       LICENSE.LGPL2.1 \
+       LICENSE.GPL2 \
+       LICENSE.MIT \
+       DISTRO_PORTING
+
+@INTLTOOL_POLICY_RULE@
+
+# ------------------------------------------------------------------------------
+MANPAGES = \
+       man/systemd.1 \
+       man/systemctl.1 \
+       man/systemd-cgls.1 \
+       man/systemd-delta.1 \
+       man/systemd-cgtop.1 \
+       man/systemd-nspawn.1 \
+       man/systemd-tmpfiles.8 \
+       man/systemd-notify.1 \
+       man/systemd.unit.5 \
+       man/systemd.service.5 \
+       man/systemd.socket.5 \
+       man/systemd.mount.5 \
+       man/systemd.automount.5 \
+       man/systemd.swap.5 \
+       man/systemd.timer.5 \
+       man/systemd.path.5 \
+       man/systemd.target.5 \
+       man/systemd.device.5 \
+       man/systemd.snapshot.5 \
+       man/systemd.exec.5 \
+       man/systemd.kill.5 \
+       man/systemd.special.7 \
+       man/systemd.journal-fields.7 \
+       man/systemd.time.7 \
+       man/kernel-command-line.7 \
+       man/daemon.7 \
+       man/bootup.7 \
+       man/runlevel.8 \
+       man/telinit.8 \
+       man/halt.8 \
+       man/shutdown.8 \
+       man/pam_systemd.8 \
+       man/systemd.conf.5 \
+       man/tmpfiles.d.5 \
+       man/hostname.5 \
+       man/localtime.5 \
+       man/machine-id.5 \
+       man/locale.conf.5 \
+       man/os-release.5 \
+       man/machine-info.5 \
+       man/sysctl.d.5 \
+       man/systemd-sysctl.service.8 \
+       man/systemd-ask-password.1 \
+       man/systemd-cat.1 \
+       man/systemd-machine-id-setup.1 \
+       man/systemd-detect-virt.1 \
+       man/journald.conf.5 \
+       man/systemd-journald.service.8 \
+       man/journalctl.1 \
+       man/systemd-coredumpctl.1 \
+       man/systemd-inhibit.1 \
+       man/systemd-remount-fs.service.8 \
+       man/systemd-update-utmp-runlevel.service.8 \
+       man/systemd-initctl.service.8 \
+       man/systemd-shutdownd.service.8 \
+       man/systemd-suspend.service.8 \
+       man/systemd-halt.service.8 \
+       man/systemd-fsck@.service.8 \
+       man/systemd-ask-password-console.service.8 \
+       man/systemd-analyze.1 \
+       man/systemd-tty-ask-password-agent.1 \
+       man/systemd-getty-generator.8 \
+       man/systemd-system-update-generator.8 \
+       man/systemd-fstab-generator.8 \
+       man/systemd.preset.5 \
+       man/sd-id128.3 \
+       man/sd_id128_to_string.3 \
+       man/sd_id128_randomize.3 \
+       man/sd_id128_get_machine.3 \
+       man/sd-journal.3 \
+       man/sd_journal_print.3 \
+       man/sd_journal_stream_fd.3 \
+       man/sd_journal_open.3 \
+       man/sd_journal_next.3 \
+       man/sd_journal_get_data.3 \
+       man/sd_journal_get_realtime_usec.3 \
+       man/sd_journal_get_cutoff_realtime_usec.3 \
+       man/sd_journal_get_cursor.3 \
+       man/sd_journal_get_fd.3 \
+       man/sd_journal_get_usage.3 \
+       man/sd_journal_add_match.3 \
+       man/sd_journal_seek_head.3 \
+       man/sd_journal_query_unique.3 \
+       man/sd_journal_get_catalog.3
+
+MANPAGES_ALIAS = \
+       man/reboot.8 \
+       man/poweroff.8 \
+       man/init.1 \
+       man/systemd-sysctl.8 \
+       man/systemd-journald.socket.8 \
+       man/systemd-journald.8 \
+       man/systemd-remount-fs.8 \
+       man/systemd-update-utmp-shutdown.service.8 \
+       man/systemd-update-utmp.8 \
+       man/systemd-initctl.socket.8 \
+       man/systemd-initctl.8 \
+       man/systemd-shutdownd.socket.8 \
+       man/systemd-shutdownd.8 \
+       man/systemd-hibernate.service.8 \
+       man/systemd-hybrid-sleep.service.8 \
+       man/systemd-sleep.8 \
+       man/systemd-shutdown.8 \
+       man/systemd-poweroff.service.8 \
+       man/systemd-reboot.service.8 \
+       man/systemd-kexec.service.8 \
+       man/systemd-fsck.8 \
+       man/systemd-fsck-root.service.8 \
+       man/systemd-ask-password-console.path.8 \
+       man/systemd-ask-password-wall.service.8 \
+       man/systemd-ask-password-wall.path.8 \
+       man/systemd-tmpfiles-setup.service.8 \
+       man/systemd-tmpfiles-clean.service.8 \
+       man/systemd-tmpfiles-clean.timer.8 \
+       man/sd_id128_t.3 \
+       man/SD_ID128_MAKE.3 \
+       man/SD_ID128_CONST_STR.3 \
+       man/SD_ID128_FORMAT_STR.3 \
+       man/SD_ID128_FORMAT_VAL.3 \
+       man/sd_id128_equal.3 \
+       man/sd_id128_from_string.3 \
+       man/sd_id128_get_boot.3 \
+       man/sd_journal_printv.3 \
+       man/sd_journal_send.3 \
+       man/sd_journal_sendv.3 \
+       man/sd_journal_perror.3 \
+       man/SD_JOURNAL_SUPPRESS_LOCATION.3 \
+       man/sd_journal_open_directory.3 \
+       man/sd_journal_close.3 \
+       man/sd_journal.3 \
+       man/SD_JOURNAL_RUNTIME_ONLY.3 \
+       man/SD_JOURNAL_SYSTEM_ONLY.3 \
+       man/SD_JOURNAL_LOCAL_ONLY.3 \
+       man/sd_journal_previous.3 \
+       man/sd_journal_next_skip.3 \
+       man/sd_journal_previous_skip.3 \
+       man/SD_JOURNAL_FOREACH.3 \
+       man/SD_JOURNAL_FOREACH_BACKWARDS.3 \
+       man/sd_journal_enumerate_data.3 \
+       man/sd_journal_restart_data.3 \
+       man/SD_JOURNAL_FOREACH_DATA.3 \
+       man/sd_journal_get_monotonic_usec.3 \
+       man/sd_journal_get_cutoff_monotonic_usec.3 \
+       man/sd_journal_reliable_fd.3 \
+       man/sd_journal_process.3 \
+       man/sd_journal_wait.3 \
+       man/SD_JOURNAL_NOP.3 \
+       man/SD_JOURNAL_APPEND.3 \
+       man/SD_JOURNAL_INVALIDATE.3 \
+       man/sd_journal_add_disjunction.3 \
+       man/sd_journal_flush_matches.3 \
+       man/sd_journal_seek_tail.3 \
+       man/sd_journal_seek_monotonic_usec.3 \
+       man/sd_journal_seek_realtime_usec.3 \
+       man/sd_journal_seek_cursor.3 \
+       man/sd_journal_test_cursor.3 \
+       man/sd_journal_enumerate_unique.3 \
+       man/sd_journal_restart_unique.3 \
+       man/SD_JOURNAL_FOREACH_UNIQUE.3 \
+       man/sd_journal_get_catalog_for_message_id.3
+
+if HAVE_KMOD
+MANPAGES += \
+       man/modules-load.d.5 \
+       man/systemd-modules-load.service.8
+MANPAGES_ALIAS += \
+       man/systemd-modules-load.8
+man/systemd-modules-load.8: man/systemd-modules-load.service.8
+endif
+
+if HAVE_MICROHTTPD
+MANPAGES += \
+       man/systemd-journal-gatewayd.service.8
+MANPAGES_ALIAS += \
+       man/systemd-journal-gatewayd.socket.8 \
+       man/systemd-journal-gatewayd.8
+man/systemd-journal-gatewayd.socket.8: man/systemd-journal-gatewayd.service.8
+man/systemd-journal-gatewayd.8: man/systemd-journal-gatewayd.service.8
+endif
+
+man/reboot.8: man/halt.8
+man/poweroff.8: man/halt.8
+man/init.1: man/systemd.1
+man/systemd-sysctl.8: man/systemd-sysctl.service.8
+man/systemd-journald.socket.8: man/systemd-journald.service.8
+man/systemd-journald.8: man/systemd-journald.service.8
+man/systemd-remount-fs.8: man/systemd-remount-fs.service.8
+man/systemd-update-utmp-shutdown.service.8: man/systemd-update-utmp-runlevel.service.8
+man/systemd-update-utmp.8: man/systemd-update-utmp-runlevel.service.8
+man/systemd-initctl.socket.8: man/systemd-initctl.service.8
+man/systemd-initctl.8: man/systemd-initctl.service.8
+man/systemd-shutdownd.socket.8: man/systemd-shutdownd.service.8
+man/systemd-shutdownd.8: man/systemd-shutdownd.service.8
+man/systemd-hibernate.service.8: man/systemd-suspend.service.8
+man/systemd-hybrid-sleep.service.8: man/systemd-suspend.service.8
+man/systemd-sleep.8: man/systemd-suspend.service.8
+man/systemd-shutdown.8: man/systemd-halt.service.8
+man/systemd-poweroff.service.8: man/systemd-halt.service.8
+man/systemd-reboot.service.8: man/systemd-halt.service.8
+man/systemd-kexec.service.8: man/systemd-halt.service.8
+man/systemd-fsck.8: man/systemd-fsck@.service.8
+man/systemd-fsck-root.service.8: man/systemd-fsck@.service.8
+man/systemd-ask-password-console.path.8: man/systemd-ask-password-console.service.8
+man/systemd-ask-password-wall.service.8: man/systemd-ask-password-console.service.8
+man/systemd-ask-password-wall.path.8: man/systemd-ask-password-console.service.8
+man/systemd-tmpfiles-setup.service.8: man/systemd-tmpfiles.8
+man/systemd-tmpfiles-clean.service.8: man/systemd-tmpfiles.8
+man/systemd-tmpfiles-clean.timer.8: man/systemd-tmpfiles.8
+man/sd_id128_t.3: man/sd-id128.3
+man/SD_ID128_MAKE.3: man/sd-id128.3
+man/SD_ID128_CONST_STR.3: man/sd-id128.3
+man/SD_ID128_FORMAT_STR.3: man/sd-id128.3
+man/SD_ID128_FORMAT_VAL.3: man/sd-id128.3
+man/sd_id128_equal.3: man/sd-id128.3
+man/sd_id128_from_string.3: man/sd_id128_to_string.3
+man/sd_id128_get_boot.3: man/sd_id128_get_machine.3
+man/sd_journal_printv.3: man/sd_journal_print.3
+man/sd_journal_send.3: man/sd_journal_print.3
+man/sd_journal_sendv.3: man/sd_journal_print.3
+man/sd_journal_perror.3: man/sd_journal_print.3
+man/SD_JOURNAL_SUPPRESS_LOCATION.3: man/sd_journal_print.3
+man/sd_journal_open_directory.3: man/sd_journal_open.3
+man/sd_journal_close.3: man/sd_journal_open.3
+man/sd_journal.3: man/sd_journal_open.3
+man/SD_JOURNAL_RUNTIME_ONLY.3: man/sd_journal_open.3
+man/SD_JOURNAL_SYSTEM_ONLY.3: man/sd_journal_open.3
+man/SD_JOURNAL_LOCAL_ONLY.3: man/sd_journal_open.3
+man/sd_journal_previous.3: man/sd_journal_next.3
+man/sd_journal_next_skip.3: man/sd_journal_next.3
+man/sd_journal_previous_skip.3: man/sd_journal_next.3
+man/SD_JOURNAL_FOREACH.3: man/sd_journal_next.3
+man/SD_JOURNAL_FOREACH_BACKWARDS.3: man/sd_journal_next.3
+man/sd_journal_enumerate_data.3: man/sd_journal_get_data.3
+man/sd_journal_restart_data.3: man/sd_journal_get_data.3
+man/SD_JOURNAL_FOREACH_DATA.3: man/sd_journal_get_data.3
+man/sd_journal_get_monotonic_usec.3: man/sd_journal_get_realtime_usec.3
+man/sd_journal_get_cutoff_monotonic_usec.3: man/sd_journal_get_cutoff_realtime_usec.3
+man/sd_journal_reliable_fd.3: man/sd_journal_get_fd.3
+man/sd_journal_process.3: man/sd_journal_get_fd.3
+man/sd_journal_wait.3: man/sd_journal_get_fd.3
+man/SD_JOURNAL_NOP.3: man/sd_journal_get_fd.3
+man/SD_JOURNAL_APPEND.3: man/sd_journal_get_fd.3
+man/SD_JOURNAL_INVALIDATE.3: man/sd_journal_get_fd.3
+man/sd_journal_add_disjunction.3: man/sd_journal_add_match.3
+man/sd_journal_flush_matches.3: man/sd_journal_add_match.3
+man/sd_journal_seek_tail.3: man/sd_journal_seek_head.3
+man/sd_journal_seek_monotonic_usec.3: man/sd_journal_seek_head.3
+man/sd_journal_seek_realtime_usec.3: man/sd_journal_seek_head.3
+man/sd_journal_seek_cursor.3: man/sd_journal_seek_head.3
+man/sd_journal_test_cursor.3: man/sd_journal_get_cursor.3
+man/sd_journal_enumerate_unique.3: man/sd_journal_query_unique.3
+man/sd_journal_restart_unique.3: man/sd_journal_query_unique.3
+man/SD_JOURNAL_FOREACH_UNIQUE.3: man/sd_journal_query_unique.3
+man/sd_journal_get_catalog_for_message_id.3: man/sd_journal_get_catalog.3
+
+XML_FILES = \
+       ${patsubst %.1,%.xml,${patsubst %.3,%.xml,${patsubst %.5,%.xml,${patsubst %.7,%.xml,${patsubst %.8,%.xml,$(MANPAGES)}}}}}
+
+if ENABLE_MANPAGES
+man_MANS = \
+       $(MANPAGES) \
+       $(MANPAGES_ALIAS)
+
+noinst_DATA = \
+       ${XML_FILES:.xml=.html}
+
+CLEANFILES += \
+       $(MANPAGES) \
+       $(MANPAGES_ALIAS) \
+       ${XML_FILES:.xml=.html}
+
+if HAVE_PYTHON
+noinst_DATA += \
+       man/index.html
+
+CLEANFILES += \
+       man/index.html
+
+man/index.html: make-man-index.py $(XML_FILES)
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(PYTHON) $^ > $@
+
+MANPAGES += \
+       man/systemd.directives.5
+
+EXTRA_DIST += \
+       man/index.html
+
+XML_DIRECTIVE_FILES = \
+       man/systemd.unit.xml \
+       man/systemd.service.xml \
+       man/systemd.socket.xml \
+       man/systemd.mount.xml \
+       man/systemd.automount.xml \
+       man/systemd.swap.xml \
+       man/systemd.target.xml \
+       man/systemd.path.xml \
+       man/systemd.timer.xml \
+       man/systemd.snapshot.xml \
+       man/systemd.exec.xml \
+       man/systemd.kill.xml \
+       man/systemd.device.xml \
+       man/systemd.conf.xml \
+       man/systemd.journal-fields.xml \
+       man/systemd.time.xml
+
+man/systemd.directives.xml: make-directive-index.py $(XML_DIRECTIVE_FILES)
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(PYTHON) $^ > $@
+
+EXTRA_DIST += \
+       man/systemd.directives.xml
+
+endif
+
+endif
+
+EXTRA_DIST += \
+       $(XML_FILES) \
+       ${XML_FILES:.xml=.html} \
+       $(MANPAGES) \
+       $(MANPAGES_ALIAS) \
+       make-man-index.py \
+       make-directive-index.py
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libsystemd-shared.la
+
+libsystemd_shared_la_SOURCES = \
+       src/shared/linux/auto_dev-ioctl.h \
+       src/shared/linux/fanotify.h \
+       src/shared/linux/seccomp.h \
+       src/shared/linux/seccomp-bpf.h \
+       src/shared/missing.h \
+       src/shared/list.h \
+       src/shared/macro.h \
+       src/shared/def.h \
+       src/shared/sparse-endian.h \
+       src/shared/util.c \
+       src/shared/util.h \
+       src/shared/virt.c \
+       src/shared/virt.h \
+       src/shared/path-util.c \
+       src/shared/path-util.h \
+       src/shared/time-util.c \
+       src/shared/time-util.h \
+       src/shared/hashmap.c \
+       src/shared/hashmap.h \
+       src/shared/set.c \
+       src/shared/set.h \
+       src/shared/fdset.c \
+       src/shared/fdset.h \
+       src/shared/strv.c \
+       src/shared/strv.h \
+       src/shared/strbuf.c \
+       src/shared/strbuf.h \
+       src/shared/conf-parser.c \
+       src/shared/conf-parser.h \
+       src/shared/log.c \
+       src/shared/log.h \
+       src/shared/ratelimit.h \
+       src/shared/ratelimit.c \
+       src/shared/exit-status.c \
+       src/shared/exit-status.h \
+       src/shared/utf8.c \
+       src/shared/utf8.h \
+       src/shared/pager.c \
+       src/shared/pager.h \
+       src/shared/ioprio.h \
+       src/shared/socket-util.c \
+       src/shared/socket-util.h \
+       src/shared/conf-files.c \
+       src/shared/conf-files.h \
+       src/shared/cgroup-util.c \
+       src/shared/cgroup-util.h \
+       src/shared/cgroup-show.c \
+       src/shared/cgroup-show.h \
+       src/shared/unit-name.c \
+       src/shared/unit-name.h \
+       src/shared/utmp-wtmp.c \
+       src/shared/utmp-wtmp.h \
+       src/shared/watchdog.c \
+       src/shared/watchdog.h \
+       src/shared/spawn-ask-password-agent.c \
+       src/shared/spawn-ask-password-agent.h \
+       src/shared/specifier.c \
+       src/shared/specifier.h \
+       src/shared/replace-var.c \
+       src/shared/replace-var.h \
+       src/shared/spawn-polkit-agent.c \
+       src/shared/spawn-polkit-agent.h \
+       src/shared/hwclock.c \
+       src/shared/hwclock.h \
+       src/shared/time-dst.c \
+       src/shared/time-dst.h \
+       src/shared/calendarspec.c \
+       src/shared/calendarspec.h
+
+libsystemd_shared_la_LIBADD = libsystemd-daemon.la
+
+#-------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libsystemd-dbus.la
+
+libsystemd_dbus_la_SOURCES = \
+       src/shared/dbus-common.c \
+       src/shared/dbus-common.h \
+       src/shared/dbus-loop.c \
+       src/shared/dbus-loop.h \
+       src/shared/polkit.c \
+       src/shared/polkit.h
+
+libsystemd_dbus_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+libsystemd_dbus_la_LIBADD = \
+       $(DBUS_LIBS)
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libsystemd-units.la
+
+libsystemd_units_la_SOURCES = \
+       src/shared/install.c \
+       src/shared/install.h \
+       src/shared/path-lookup.c \
+       src/shared/path-lookup.h
+
+libsystemd_units_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libsystemd-label.la
+
+libsystemd_label_la_SOURCES = \
+       src/shared/cgroup-label.c \
+       src/shared/socket-label.c \
+       src/shared/label.c \
+       src/shared/label.h \
+       src/shared/selinux-util.c \
+       src/shared/selinux-util.h \
+       src/shared/mkdir.c \
+       src/shared/mkdir.h \
+       src/shared/ask-password-api.c \
+       src/shared/ask-password-api.h \
+       src/shared/dev-setup.c \
+       src/shared/dev-setup.h
+
+libsystemd_label_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(SELINUX_CFLAGS)
+
+libsystemd_label_la_LIBADD = \
+       $(SELINUX_LIBS)
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libsystemd-logs.la
+
+libsystemd_logs_la_SOURCES = \
+       src/shared/logs-show.c \
+       src/shared/logs-show.h
+
+libsystemd_logs_la_CFLAGS = \
+       $(AM_CFLAGS)
+
+libsystemd_logs_la_LIBADD = \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libsystemd-capability.la
+
+libsystemd_capability_la_SOURCES = \
+       src/shared/capability.c \
+       src/shared/capability.h
+
+libsystemd_capability_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(CAP_CFLAGS)
+
+libsystemd_capability_la_LIBADD = \
+       $(CAP_LIBS)
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libsystemd-audit.la
+
+libsystemd_audit_la_SOURCES = \
+       src/shared/audit.c \
+       src/shared/audit.h
+
+libsystemd_audit_la_LIBADD = \
+       libsystemd-capability.la
+
+# ------------------------------------------------------------------------------
+if HAVE_ACL
+noinst_LTLIBRARIES += \
+       libsystemd-acl.la
+
+libsystemd_acl_la_SOURCES = \
+       src/shared/acl-util.c \
+       src/shared/acl-util.h
+
+libsystemd_acl_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(ACL_CFLAGS)
+
+libsystemd_acl_la_LIBADD = \
+       $(ACL_LIBS)
+endif
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libsystemd-core.la
+
+libsystemd_core_la_SOURCES = \
+       src/core/unit.c \
+       src/core/unit.h \
+       src/core/unit-printf.c \
+       src/core/unit-printf.h \
+       src/core/job.c \
+       src/core/job.h \
+       src/core/manager.c \
+       src/core/manager.h \
+       src/core/transaction.c \
+       src/core/transaction.h \
+       src/core/load-fragment.c \
+       src/core/load-fragment.h \
+       src/core/service.c \
+       src/core/service.h \
+       src/core/automount.c \
+       src/core/automount.h \
+       src/core/mount.c \
+       src/core/mount.h \
+       src/core/swap.c \
+       src/core/swap.h \
+       src/core/device.c \
+       src/core/device.h \
+       src/core/target.c \
+       src/core/target.h \
+       src/core/snapshot.c \
+       src/core/snapshot.h \
+       src/core/socket.c \
+       src/core/socket.h \
+       src/core/timer.c \
+       src/core/timer.h \
+       src/core/path.c \
+       src/core/path.h \
+       src/core/load-dropin.c \
+       src/core/load-dropin.h \
+       src/core/execute.c \
+       src/core/execute.h \
+       src/core/kill.c \
+       src/core/kill.h \
+       src/core/dbus.c \
+       src/core/dbus.h \
+       src/core/dbus-manager.c \
+       src/core/dbus-manager.h \
+       src/core/dbus-unit.c \
+       src/core/dbus-unit.h \
+       src/core/dbus-job.c \
+       src/core/dbus-job.h \
+       src/core/dbus-service.c \
+       src/core/dbus-service.h \
+       src/core/dbus-socket.c \
+       src/core/dbus-socket.h \
+       src/core/dbus-timer.c \
+       src/core/dbus-timer.h \
+       src/core/dbus-target.c \
+       src/core/dbus-target.h \
+       src/core/dbus-mount.c \
+       src/core/dbus-mount.h \
+       src/core/dbus-automount.c \
+       src/core/dbus-automount.h \
+       src/core/dbus-swap.c \
+       src/core/dbus-swap.h \
+       src/core/dbus-snapshot.c \
+       src/core/dbus-snapshot.h \
+       src/core/dbus-device.c \
+       src/core/dbus-device.h \
+       src/core/dbus-execute.c \
+       src/core/dbus-execute.h \
+       src/core/dbus-kill.c \
+       src/core/dbus-kill.h \
+       src/core/dbus-path.c \
+       src/core/dbus-path.h \
+       src/core/cgroup.c \
+       src/core/cgroup.h \
+       src/core/selinux-access.c \
+       src/core/selinux-access.h \
+       src/core/selinux-setup.c \
+       src/core/selinux-setup.h \
+       src/core/ima-setup.c \
+       src/core/ima-setup.h \
+       src/core/locale-setup.h \
+       src/core/locale-setup.c \
+       src/core/hostname-setup.c \
+       src/core/hostname-setup.h \
+       src/core/machine-id-setup.c \
+       src/core/machine-id-setup.h \
+       src/core/mount-setup.c \
+       src/core/mount-setup.h \
+       src/core/loopback-setup.h \
+       src/core/loopback-setup.c \
+       src/core/condition.c \
+       src/core/condition.h \
+       src/core/namespace.c \
+       src/core/namespace.h \
+       src/core/tcpwrap.c \
+       src/core/tcpwrap.h \
+       src/core/cgroup-attr.c \
+       src/core/cgroup-attr.h \
+       src/core/securebits.h \
+       src/core/initreq.h \
+       src/core/special.h \
+       src/core/bus-errors.h \
+       src/core/build.h \
+       src/core/sysfs-show.h \
+       src/core/switch-root.h \
+       src/core/switch-root.c \
+       src/core/killall.h \
+       src/core/killall.c \
+       src/core/syscall-list.c \
+       src/core/syscall-list.h \
+       src/core/audit-fd.c \
+       src/core/audit-fd.h
+
+if HAVE_KMOD
+libsystemd_core_la_SOURCES += \
+       src/core/kmod-setup.c \
+       src/core/kmod-setup.h
+endif
+
+nodist_libsystemd_core_la_SOURCES = \
+       src/core/load-fragment-gperf.c \
+       src/core/load-fragment-gperf-nulstr.c \
+       src/core/syscall-from-name.h \
+       src/core/syscall-to-name.h
+
+libsystemd_core_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS) \
+       $(LIBWRAP_CFLAGS) \
+       $(PAM_CFLAGS) \
+       $(AUDIT_CFLAGS) \
+       $(KMOD_CFLAGS)
+
+libsystemd_core_la_LIBADD = \
+       libsystemd-capability.la \
+       libsystemd-units.la \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libsystemd-dbus.la \
+       libsystemd-audit.la \
+       libsystemd-id128-internal.la \
+       libsystemd-daemon.la \
+       libudev.la \
+       $(LIBWRAP_LIBS) \
+       $(PAM_LIBS) \
+       $(AUDIT_LIBS) \
+       $(CAP_LIBS) \
+       $(KMOD_LIBS)
+
+src/core/load-fragment-gperf-nulstr.c: src/core/load-fragment-gperf.gperf
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(AWK) 'BEGIN{ keywords=0 ; FS="," ; print "extern const char load_fragment_gperf_nulstr[];" ; print "const char load_fragment_gperf_nulstr[] ="} ; keyword==1 { print "\"" $$1 "\\0\"" } ; /%%/ { keyword=1} ; END { print ";" }' < $< > $@
+
+EXTRA_DIST += \
+       src/core/load-fragment-gperf.gperf.m4
+
+CLEANFILES += \
+       src/core/load-fragment-gperf.gperf \
+       src/core/load-fragment-gperf.c \
+       src/core/load-fragment-gperf-nulstr.c \
+       src/core/syscall-list.txt \
+       src/core/syscall-from-name.gperf
+
+BUILT_SOURCES += \
+       src/core/syscall-from-name.h \
+       src/core/syscall-to-name.h
+
+src/core/syscall-list.txt: Makefile
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/syscall.h - < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+\(?.*[0-9]+.*\)?/ { sub(/__NR_/, "", $$2); print $$2; }' > $@
+
+src/core/syscall-from-name.gperf: src/core/syscall-list.txt Makefile
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct syscall_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, __NR_%s\n", $$1, $$1 }' < $< > $@
+
+src/core/syscall-from-name.h: src/core/syscall-from-name.gperf Makefile
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_syscall -H hash_syscall_name -p -C < $< > $@
+
+src/core/syscall-to-name.h: src/core/syscall-list.txt Makefile
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const syscall_names[] = { "} { printf "[__NR_%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@
+
+# ------------------------------------------------------------------------------
+systemd_SOURCES = \
+       src/core/main.c
+
+systemd_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_LDADD = \
+       libsystemd-core.la \
+       libsystemd-daemon.la \
+       libsystemd-id128-internal.la \
+       libsystemd-dbus.la
+
+dist_pkgsysconf_DATA += \
+       src/core/system.conf \
+       src/core/user.conf
+
+dist_dbuspolicy_DATA += \
+       src/core/org.freedesktop.systemd1.conf
+
+dist_dbussystemservice_DATA += \
+       src/core/org.freedesktop.systemd1.service
+
+dbusinterface_DATA += \
+       org.freedesktop.systemd1.Manager.xml \
+       org.freedesktop.systemd1.Job.xml \
+       org.freedesktop.systemd1.Unit.xml \
+       org.freedesktop.systemd1.Service.xml \
+       org.freedesktop.systemd1.Socket.xml \
+       org.freedesktop.systemd1.Timer.xml \
+       org.freedesktop.systemd1.Target.xml \
+       org.freedesktop.systemd1.Device.xml \
+       org.freedesktop.systemd1.Mount.xml \
+       org.freedesktop.systemd1.Automount.xml \
+       org.freedesktop.systemd1.Snapshot.xml \
+       org.freedesktop.systemd1.Swap.xml \
+       org.freedesktop.systemd1.Path.xml
+
+polkitpolicy_in_in_files = \
+       src/core/org.freedesktop.systemd1.policy.in.in
+
+org.freedesktop.systemd1.%.xml: systemd
+       $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.$* $< $@.tmp && \
+               $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \
+               $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp
+
+pkgconfigdata_DATA = \
+       src/core/systemd.pc
+
+nodist_rpmmacros_DATA = \
+       src/core/macros.systemd
+
+EXTRA_DIST += \
+       src/core/systemd.pc.in \
+       src/core/macros.systemd.in
+
+CLEANFILES += \
+       src/core/macros.systemd
+
+# ------------------------------------------------------------------------------
+noinst_PROGRAMS += \
+       test-engine \
+       test-job-type \
+       test-ns \
+       test-loopback \
+       test-hostname \
+       test-daemon \
+       test-cgroup \
+       test-env-replace \
+       test-strv \
+       test-install \
+       test-watchdog \
+       test-unit-name \
+       test-log \
+       test-unit-file \
+       test-date \
+       test-sleep \
+       test-replace-var \
+       test-sched-prio \
+       test-calendarspec \
+       test-strip-tab-ansi
+
+TESTS += \
+       test-job-type \
+       test-env-replace \
+       test-strv \
+       test-unit-name \
+       test-unit-file \
+       test-date \
+       test-sleep \
+       test-replace-var \
+       test-sched-prio \
+       test-calendarspec \
+       test-strip-tab-ansi
+
+EXTRA_DIST += \
+       test/sched_idle_bad.service \
+       test/sched_idle_ok.service \
+       test/sched_rr_bad.service \
+       test/sched_rr_ok.service \
+       test/sched_rr_change.service
+
+test_engine_SOURCES = \
+       src/test/test-engine.c
+
+test_engine_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+test_engine_LDADD = \
+       libsystemd-core.la \
+       libsystemd-daemon.la \
+       libsystemd-dbus.la
+
+test_job_type_SOURCES = \
+       src/test/test-job-type.c
+
+test_job_type_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+test_job_type_LDADD = \
+       libsystemd-core.la \
+       libsystemd-daemon.la
+
+test_ns_SOURCES = \
+       src/test/test-ns.c
+
+test_ns_LDADD = \
+       libsystemd-core.la
+
+test_loopback_SOURCES = \
+       src/test/test-loopback.c
+
+test_loopback_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-core.la
+
+test_hostname_SOURCES = \
+       src/test/test-hostname.c
+
+test_hostname_LDADD = \
+       libsystemd-core.la
+
+test_unit_name_SOURCES = \
+       src/test/test-unit-name.c
+
+test_unit_name_LDADD = \
+       libsystemd-core.la
+
+test_unit_file_SOURCES = \
+       src/test/test-unit-file.c
+
+test_unit_file_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+test_unit_file_LDADD = \
+       libsystemd-core.la
+
+test_log_SOURCES = \
+       src/test/test-log.c
+
+test_log_LDADD = \
+       libsystemd-core.la
+
+test_date_SOURCES = \
+       src/test/test-date.c
+
+test_date_LDADD = \
+       libsystemd-core.la
+
+test_sleep_SOURCES = \
+       src/test/test-sleep.c
+
+test_sleep_LDADD = \
+       libsystemd-core.la
+
+test_replace_var_SOURCES = \
+       src/test/test-replace-var.c
+
+test_replace_var_LDADD = \
+       libsystemd-shared.la
+
+test_calendarspec_SOURCES = \
+       src/test/test-calendarspec.c
+
+test_calendarspec_LDADD = \
+       libsystemd-shared.la
+
+test_strip_tab_ansi_SOURCES = \
+       src/test/test-strip-tab-ansi.c
+
+test_strip_tab_ansi_LDADD = \
+       libsystemd-shared.la
+
+test_daemon_SOURCES = \
+       src/test/test-daemon.c
+
+test_daemon_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-daemon.la
+
+test_cgroup_SOURCES = \
+       src/test/test-cgroup.c
+
+test_cgroup_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+test_env_replace_SOURCES = \
+       src/test/test-env-replace.c
+
+test_env_replace_LDADD = \
+       libsystemd-shared.la
+
+test_strv_SOURCES = \
+       src/test/test-strv.c
+
+test_strv_LDADD = \
+       libsystemd-shared.la
+
+test_install_SOURCES = \
+       src/test/test-install.c
+
+test_install_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+test_install_LDADD = \
+       libsystemd-units.la \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+test_watchdog_SOURCES = \
+       src/test/test-watchdog.c
+
+test_watchdog_LDADD = \
+       libsystemd-shared.la
+
+test_sched_prio_SOURCES = \
+       src/test/test-sched-prio.c
+
+test_sched_prio_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS) \
+       -D"STR(s)=\#s" -D"TEST_DIR=STR($(abs_top_srcdir)/test/)"
+
+test_sched_prio_LDADD = \
+       libsystemd-core.la \
+       libsystemd-daemon.la
+
+# ------------------------------------------------------------------------------
+systemd_initctl_SOURCES = \
+       src/initctl/initctl.c
+
+systemd_initctl_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_initctl_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-daemon.la \
+       libsystemd-dbus.la
+
+# ------------------------------------------------------------------------------
+systemd_update_utmp_SOURCES = \
+       src/update-utmp/update-utmp.c
+
+systemd_update_utmp_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS) \
+       $(AUDIT_CFLAGS)
+
+systemd_update_utmp_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la \
+       $(AUDIT_LIBS)
+
+# ------------------------------------------------------------------------------
+systemd_shutdownd_SOURCES = \
+       src/shutdownd/shutdownd.c
+
+systemd_shutdownd_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libsystemd-daemon.la
+
+pkginclude_HEADERS += \
+       src/systemd/sd-shutdown.h
+
+# ------------------------------------------------------------------------------
+systemd_shutdown_SOURCES = \
+       src/core/umount.c \
+       src/core/umount.h \
+       src/core/shutdown.c \
+       src/core/mount-setup.c \
+       src/core/mount-setup.h \
+       src/core/killall.h \
+       src/core/killall.c
+
+systemd_shutdown_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libudev.la
+
+if HAVE_KMOD
+# ------------------------------------------------------------------------------
+systemd_modules_load_SOURCES = \
+       src/modules-load/modules-load.c
+
+systemd_modules_load_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(KMOD_CFLAGS)
+
+systemd_modules_load_LDADD = \
+       libsystemd-shared.la \
+       $(KMOD_LIBS)
+endif
+
+# ------------------------------------------------------------------------------
+systemd_tmpfiles_SOURCES = \
+       src/tmpfiles/tmpfiles.c
+
+systemd_tmpfiles_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libsystemd-capability.la
+
+# ------------------------------------------------------------------------------
+systemd_machine_id_setup_SOURCES = \
+       src/machine-id-setup/machine-id-setup-main.c \
+       src/core/machine-id-setup.c \
+       src/core/machine-id-setup.h
+
+systemd_machine_id_setup_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libsystemd-id128-internal.la
+
+# ------------------------------------------------------------------------------
+systemd_sysctl_SOURCES = \
+       src/sysctl/sysctl.c
+
+systemd_sysctl_LDADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_sleep_SOURCES = \
+       src/sleep/sleep.c
+
+systemd_sleep_LDADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_fsck_SOURCES = \
+       src/fsck/fsck.c
+
+systemd_fsck_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_fsck_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la \
+       libudev.la
+
+# ------------------------------------------------------------------------------
+systemd_timestamp_SOURCES = \
+       src/timestamp/timestamp.c
+
+systemd_timestamp_LDADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_ac_power_SOURCES = \
+       src/ac-power/ac-power.c
+
+systemd_ac_power_LDADD = \
+       libsystemd-shared.la \
+       libudev.la
+
+# ------------------------------------------------------------------------------
+systemd_detect_virt_SOURCES = \
+       src/detect-virt/detect-virt.c
+
+systemd_detect_virt_LDADD = \
+       libsystemd-shared.la
+
+systemd-detect-virt-install-hook:
+       -$(SETCAP) cap_dac_override,cap_sys_ptrace=ep $(DESTDIR)$(bindir)/systemd-detect-virt
+
+INSTALL_EXEC_HOOKS += \
+       systemd-detect-virt-install-hook
+
+# ------------------------------------------------------------------------------
+systemd_delta_SOURCES = \
+       src/delta/delta.c
+
+systemd_delta_LDADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_getty_generator_SOURCES = \
+       src/getty-generator/getty-generator.c
+
+systemd_getty_generator_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_fstab_generator_SOURCES = \
+       src/fstab-generator/fstab-generator.c \
+       src/core/mount-setup.c
+
+systemd_fstab_generator_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_system_update_generator_SOURCES = \
+       src/system-update-generator/system-update-generator.c
+
+systemd_system_update_generator_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_rc_local_generator_SOURCES = \
+       src/rc-local-generator/rc-local-generator.c
+
+systemd_rc_local_generator_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_remount_fs_SOURCES = \
+       src/remount-fs/remount-fs.c \
+       src/core/mount-setup.c \
+       src/core/mount-setup.h
+
+systemd_remount_fs_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_cgroups_agent_SOURCES = \
+       src/cgroups-agent/cgroups-agent.c
+
+systemd_cgroups_agent_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_cgroups_agent_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la
+
+# ------------------------------------------------------------------------------
+systemctl_SOURCES = \
+       src/systemctl/systemctl.c
+
+systemctl_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemctl_LDADD = \
+       libsystemd-units.la \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libsystemd-daemon.la \
+       libsystemd-dbus.la \
+       libsystemd-logs.la
+
+# ------------------------------------------------------------------------------
+systemd_notify_SOURCES = \
+       src/notify/notify.c \
+       src/readahead/sd-readahead.c
+
+systemd_notify_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-daemon.la
+
+# ------------------------------------------------------------------------------
+systemd_ask_password_SOURCES = \
+       src/ask-password/ask-password.c
+
+systemd_ask_password_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_reply_password_SOURCES = \
+       src/reply-password/reply-password.c
+
+systemd_reply_password_LDADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_cgls_SOURCES = \
+       src/cgls/cgls.c
+
+systemd_cgls_LDADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_cgtop_SOURCES = \
+       src/cgtop/cgtop.c
+
+systemd_cgtop_LDADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_nspawn_SOURCES = \
+       src/nspawn/nspawn.c \
+       src/core/mount-setup.c \
+       src/core/mount-setup.h \
+       src/core/loopback-setup.c \
+       src/core/loopback-setup.h
+
+systemd_nspawn_LDADD = \
+       libsystemd-label.la \
+       libsystemd-capability.la \
+       libsystemd-shared.la \
+       libsystemd-daemon.la \
+       libsystemd-id128-internal.la
+
+# ------------------------------------------------------------------------------
+systemd_stdio_bridge_SOURCES = \
+       src/stdio-bridge/stdio-bridge.c
+
+systemd_stdio_bridge_LDADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+systemd_tty_ask_password_agent_SOURCES = \
+       src/tty-ask-password-agent/tty-ask-password-agent.c
+
+systemd_tty_ask_password_agent_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+libsystemd_daemon_la_SOURCES = \
+       src/libsystemd-daemon/sd-daemon.c
+
+libsystemd_daemon_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       -fvisibility=hidden \
+       -DSD_EXPORT_SYMBOLS
+
+libsystemd_daemon_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -shared \
+       -version-info $(LIBSYSTEMD_DAEMON_CURRENT):$(LIBSYSTEMD_DAEMON_REVISION):$(LIBSYSTEMD_DAEMON_AGE) \
+       -Wl,--version-script=$(top_srcdir)/src/libsystemd-daemon/libsystemd-daemon.sym
+
+pkginclude_HEADERS += \
+       src/systemd/sd-daemon.h
+
+# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
+libsystemd-daemon-install-hook:
+       libname=libsystemd-daemon.so && $(move-to-rootlibdir)
+
+libsystemd-daemon-uninstall-hook:
+       rm -f $(DESTDIR)$(rootlibdir)/libsystemd-daemon.so*
+
+INSTALL_EXEC_HOOKS += libsystemd-daemon-install-hook
+UNINSTALL_EXEC_HOOKS += libsystemd-daemon-uninstall-hook
+
+lib_LTLIBRARIES += \
+       libsystemd-daemon.la
+
+pkgconfiglib_DATA += \
+       src/libsystemd-daemon/libsystemd-daemon.pc
+
+MANPAGES += \
+       man/sd-daemon.3 \
+       man/sd_notify.3 \
+       man/sd_listen_fds.3 \
+       man/sd_is_fifo.3 \
+       man/sd_booted.3
+
+MANPAGES_ALIAS += \
+       man/sd_is_socket.3 \
+       man/sd_is_socket_unix.3 \
+       man/sd_is_socket_inet.3 \
+       man/sd_is_mq.3 \
+       man/sd_notifyf.3 \
+       man/SD_LISTEN_FDS_START.3 \
+       man/SD_EMERG.3 \
+       man/SD_ALERT.3 \
+       man/SD_CRIT.3 \
+       man/SD_ERR.3 \
+       man/SD_WARNING.3 \
+       man/SD_NOTICE.3 \
+       man/SD_INFO.3 \
+       man/SD_DEBUG.3
+
+man/sd_is_socket.3: man/sd_is_fifo.3
+man/sd_is_socket_unix.3: man/sd_is_fifo.3
+man/sd_is_socket_inet.3: man/sd_is_fifo.3
+man/sd_is_mq.3: man/sd_is_fifo.3
+man/sd_notifyf.3: man/sd_notify.3
+man/SD_LISTEN_FDS_START.3: man/sd_listen_fds.3
+man/SD_EMERG.3: man/sd-daemon.3
+man/SD_ALERT.3: man/sd-daemon.3
+man/SD_CRIT.3: man/sd-daemon.3
+man/SD_ERR.3: man/sd-daemon.3
+man/SD_WARNING.3: man/sd-daemon.3
+man/SD_NOTICE.3: man/sd-daemon.3
+man/SD_INFO.3: man/sd-daemon.3
+man/SD_DEBUG.3: man/sd-daemon.3
+
+EXTRA_DIST += \
+       src/libsystemd-daemon/libsystemd-daemon.pc.in \
+       src/libsystemd-daemon/libsystemd-daemon.sym
+
+# ------------------------------------------------------------------------------
+if ENABLE_GTK_DOC
+SUBDIRS += \
+       docs/libudev
+endif
+
+include_HEADERS += \
+       src/libudev/libudev.h
+
+lib_LTLIBRARIES += \
+       libudev.la
+
+libudev_la_SOURCES =\
+       src/libudev/libudev-private.h \
+       src/libudev/libudev.c \
+       src/libudev/libudev-list.c \
+       src/libudev/libudev-util.c \
+       src/libudev/libudev-device.c \
+       src/libudev/libudev-enumerate.c \
+       src/libudev/libudev-monitor.c \
+       src/libudev/libudev-queue.c \
+       src/libudev/libudev-hwdb-def.h \
+       src/libudev/libudev-hwdb.c
+
+libudev_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       -fvisibility=hidden
+
+libudev_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -version-info $(LIBUDEV_CURRENT):$(LIBUDEV_REVISION):$(LIBUDEV_AGE) \
+       -Wl,--version-script=$(top_srcdir)/src/libudev/libudev.sym
+
+libudev_la_LIBADD = \
+       libsystemd-shared.la
+
+pkgconfiglib_DATA += \
+       src/libudev/libudev.pc
+
+EXTRA_DIST += \
+       src/libudev/libudev.pc.in \
+       src/libudev/libudev.sym
+
+CLEANFILES += \
+       src/libudev/libudev.pc
+
+# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
+libudev-install-hook:
+       libname=libudev.so && $(move-to-rootlibdir)
+
+libudev-uninstall-hook:
+       rm -f $(DESTDIR)$(rootlibdir)/libudev.so*
+
+INSTALL_EXEC_HOOKS += libudev-install-hook
+UNINSTALL_EXEC_HOOKS += libudev-uninstall-hook
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+       libudev-private.la
+
+libudev_private_la_SOURCES =\
+       $(libudev_la_SOURCES) \
+       src/libudev/libudev-device-private.c \
+       src/libudev/libudev-queue-private.c
+
+libudev_private_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       -fvisibility=default
+
+libudev_private_la_LIBADD = \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
+MANPAGES += \
+       man/udev.7 \
+       man/udevadm.8 \
+       man/systemd-udevd.service.8
+
+MANPAGES_ALIAS += \
+       man/systemd-udevd.8 \
+       man/systemd-udevd-control.socket.8 \
+       man/systemd-udevd-kernel.socket.8
+
+man/systemd-udevd.8: man/systemd-udevd.service.8
+man/systemd-udevd-control.socket.8: man/systemd-udevd.service.8
+man/systemd-udevd-kernel.socket.8: man/systemd-udevd.service.8
+
+udev-confdirs:
+       -$(MKDIR_P) $(DESTDIR)$(sysconfdir)/udev/rules.d
+       -$(MKDIR_P) $(DESTDIR)$(sysconfdir)/udev/hwdb.d
+
+INSTALL_DATA_HOOKS += udev-confdirs
+
+dist_udevrules_DATA += \
+       rules/99-systemd.rules \
+       rules/42-usb-hid-pm.rules \
+       rules/50-udev-default.rules \
+       rules/60-persistent-storage-tape.rules \
+       rules/60-persistent-serial.rules \
+       rules/60-persistent-input.rules \
+       rules/60-persistent-alsa.rules \
+       rules/60-persistent-storage.rules \
+       rules/64-btrfs.rules \
+       rules/75-net-description.rules \
+       rules/75-tty-description.rules \
+       rules/78-sound-card.rules \
+       rules/80-net-name-slot.rules \
+       rules/95-udev-late.rules
+
+if HAVE_KMOD
+dist_udevrules_DATA += \
+       rules/80-drivers.rules
+endif
+
+dist_udevhwdb_DATA = \
+       hwdb/20-pci-vendor-product.hwdb \
+       hwdb/20-pci-classes.hwdb \
+       hwdb/20-usb-vendor-product.hwdb \
+       hwdb/20-usb-classes.hwdb \
+       hwdb/20-bluetooth-vendor-product.hwdb \
+       hwdb/20-acpi-vendor.hwdb \
+       hwdb/20-OUI.hwdb
+
+udevconfdir = $(sysconfdir)/udev
+dist_udevconf_DATA = \
+       src/udev/udev.conf
+
+sharepkgconfigdir = $(datadir)/pkgconfig
+sharepkgconfig_DATA = \
+       src/udev/udev.pc
+
+EXTRA_DIST += \
+       rules/99-systemd.rules.in \
+       src/udev/udev.pc.in
+
+CLEANFILES += \
+       rules/99-systemd.rules \
+       src/udev/udev.pc
+
+EXTRA_DIST += \
+       units/systemd-udevd.service.in \
+       units/systemd-udev-trigger.service.in \
+       units/systemd-udev-settle.service.in
+
+CLEANFILES += \
+       units/systemd-udevd.service \
+       units/systemd-udev-trigger.service \
+       units/systemd-udev-settle.service
+
+systemd-install-hook:
+       $(MKDIR_P) $(DESTDIR)$(systemunitdir)/sockets.target.wants
+       ln -sf ../systemd-udevd-control.socket $(DESTDIR)$(systemunitdir)/sockets.target.wants/systemd-udevd-control.socket
+       ln -sf ../systemd-udevd-kernel.socket $(DESTDIR)$(systemunitdir)/sockets.target.wants/systemd-udevd-kernel.socket
+       $(MKDIR_P) $(DESTDIR)$(systemunitdir)/sysinit.target.wants
+       ln -sf ../systemd-udevd.service $(DESTDIR)$(systemunitdir)/sysinit.target.wants/systemd-udevd.service
+       ln -sf ../systemd-udev-trigger.service $(DESTDIR)$(systemunitdir)/sysinit.target.wants/systemd-udev-trigger.service
+
+INSTALL_DATA_HOOKS += systemd-install-hook
+
+bin_PROGRAMS += \
+       udevadm
+
+rootlibexec_PROGRAMS += \
+       systemd-udevd
+
+noinst_LTLIBRARIES += \
+       libudev-core.la
+
+libudev_core_la_SOURCES = \
+       src/udev/udev.h \
+       src/udev/udev-event.c \
+       src/udev/udev-watch.c \
+       src/udev/udev-node.c \
+       src/udev/udev-rules.c \
+       src/udev/udev-ctrl.c \
+       src/udev/udev-builtin.c \
+       src/udev/udev-builtin-btrfs.c \
+       src/udev/udev-builtin-firmware.c \
+       src/udev/udev-builtin-hwdb.c \
+       src/udev/udev-builtin-input_id.c \
+       src/udev/udev-builtin-net_id.c \
+       src/udev/udev-builtin-path_id.c \
+       src/udev/udev-builtin-usb_id.c \
+       src/libsystemd-daemon/sd-daemon.c
+
+libudev_core_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(BLKID_CFLAGS) \
+       $(KMOD_CFLAGS)
+
+libudev_core_la_LIBADD = \
+       libudev-private.la \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       $(BLKID_LIBS) \
+       $(KMOD_LIBS)
+
+libudev_core_la_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       -DFIRMWARE_PATH="$(FIRMWARE_PATH)"
+
+if HAVE_KMOD
+libudev_core_la_SOURCES += \
+       src/udev/udev-builtin-kmod.c
+endif
+
+if HAVE_BLKID
+libudev_core_la_SOURCES += \
+       src/udev/udev-builtin-blkid.c
+endif
+
+if HAVE_ACL
+libudev_core_la_SOURCES += \
+       src/udev/udev-builtin-uaccess.c \
+       src/login/logind-acl.c \
+       src/login/sd-login.c
+
+libudev_core_la_LIBADD += \
+       libsystemd-acl.la
+endif
+
+systemd_udevd_SOURCES = \
+       src/udev/udevd.c
+
+systemd_udevd_LDADD = \
+       libudev-core.la
+
+udevadm_SOURCES = \
+       src/udev/udevadm.c \
+       src/udev/udevadm-info.c \
+       src/udev/udevadm-control.c \
+       src/udev/udevadm-monitor.c \
+       src/udev/udevadm-hwdb.c \
+       src/udev/udevadm-settle.c \
+       src/udev/udevadm-trigger.c \
+       src/udev/udevadm-test.c \
+       src/udev/udevadm-test-builtin.c
+
+udevadm_LDADD = \
+       libudev-core.la \
+       libsystemd-shared.la
+
+# Update hwdb on installation. Do not bother if installing
+# in DESTDIR, since this is likely for packaging purposes.
+hwdb-update-hook:
+       -test -n "$(DESTDIR)" || $(bindir)/udevadm hwdb --update
+
+INSTALL_DATA_HOOKS += \
+       hwdb-update-hook
+
+hwdb-remove-hook:
+       -test -n "$(DESTDIR)" || rm -f $(HWDB_BIN)
+
+# ------------------------------------------------------------------------------
+TESTS += \
+       test/udev-test.pl \
+       test/rules-test.sh
+
+noinst_PROGRAMS += \
+       test-libudev \
+       test-udev
+
+test_libudev_SOURCES = \
+       src/test/test-libudev.c
+
+test_libudev_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libudev.la
+
+test_udev_SOURCES = \
+       src/test/test-udev.c
+
+test_udev_LDADD = \
+       libudev-core.la \
+       libsystemd-shared.la \
+       $(BLKID_LIBS) \
+       $(KMOD_LIBS) \
+       $(SELINUX_LIBS)
+
+if HAVE_ACL
+test_udev_LDADD += \
+       libsystemd-acl.la
+endif
+
+check_DATA += \
+       test/sys
+
+# packed sysfs test tree
+test/sys:
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)tar -C test/ -xJf $(top_srcdir)/test/sys.tar.xz
+
+test-sys-distclean:
+       -rm -rf test/sys
+DISTCLEAN_LOCAL_HOOKS += test-sys-distclean
+
+EXTRA_DIST += \
+       test/sys.tar.xz \
+       test/udev-test.pl \
+       test/rules-test.sh \
+       test/rule-syntax-check.py
+
+# ------------------------------------------------------------------------------
+ata_id_SOURCES = \
+       src/udev/ata_id/ata_id.c
+
+ata_id_LDADD = \
+       libudev-private.la \
+       libsystemd-shared.la
+
+udevlibexec_PROGRAMS += \
+       ata_id
+
+# ------------------------------------------------------------------------------
+cdrom_id_SOURCES = \
+       src/udev/cdrom_id/cdrom_id.c
+
+cdrom_id_LDADD = \
+       libudev.la \
+       libsystemd-shared.la
+
+udevlibexec_PROGRAMS += \
+       cdrom_id
+
+dist_udevrules_DATA += \
+       rules/60-cdrom_id.rules
+
+# ------------------------------------------------------------------------------
+collect_SOURCES = \
+       src/udev/collect/collect.c
+
+collect_LDADD = \
+       libudev-private.la
+
+udevlibexec_PROGRAMS += \
+       collect
+
+# ------------------------------------------------------------------------------
+scsi_id_SOURCES =\
+       src/udev/scsi_id/scsi_id.c \
+       src/udev/scsi_id/scsi_serial.c \
+       src/udev/scsi_id/scsi.h \
+       src/udev/scsi_id/scsi_id.h
+
+scsi_id_LDADD = \
+       libudev-private.la \
+       libsystemd-shared.la
+
+udevlibexec_PROGRAMS += \
+       scsi_id
+
+EXTRA_DIST += \
+       src/udev/scsi_id/README
+
+# ------------------------------------------------------------------------------
+v4l_id_SOURCES = \
+       src/udev/v4l_id/v4l_id.c
+
+v4l_id_LDADD = \
+       libudev.la
+
+udevlibexec_PROGRAMS += \
+       v4l_id
+
+dist_udevrules_DATA += \
+       rules/60-persistent-v4l.rules
+
+# ------------------------------------------------------------------------------
+accelerometer_SOURCES = \
+       src/udev/accelerometer/accelerometer.c
+
+accelerometer_LDADD = \
+       libudev.la -lm \
+       libsystemd-shared.la
+
+udevlibexec_PROGRAMS += \
+       accelerometer
+
+dist_udevrules_DATA += \
+       rules/61-accelerometer.rules
+
+# ------------------------------------------------------------------------------
+if ENABLE_GUDEV
+if ENABLE_GTK_DOC
+SUBDIRS += \
+       docs/gudev
+endif
+
+libgudev_includedir = \
+       $(includedir)/gudev-1.0/gudev
+
+libgudev_include_HEADERS = \
+       src/gudev/gudev.h \
+       src/gudev/gudevenums.h \
+       src/gudev/gudevenumtypes.h \
+       src/gudev/gudevtypes.h \
+       src/gudev/gudevclient.h \
+       src/gudev/gudevdevice.h \
+       src/gudev/gudevenumerator.h
+
+lib_LTLIBRARIES += libgudev-1.0.la
+
+pkgconfiglib_DATA += \
+       src/gudev/gudev-1.0.pc
+
+CLEANFILES += \
+       src/gudev/gudev-1.0.pc
+
+libgudev_1_0_la_SOURCES = \
+       src/gudev/gudevenums.h \
+       src/gudev/gudevenumtypes.h \
+       src/gudev/gudevenumtypes.h\
+       src/gudev/gudevtypes.h \
+       src/gudev/gudevclient.h \
+       src/gudev/gudevclient.c \
+       src/gudev/gudevdevice.h \
+       src/gudev/gudevdevice.c \
+       src/gudev/gudevenumerator.h \
+       src/gudev/gudevenumerator.c \
+       src/gudev/gudevprivate.h
+
+nodist_libgudev_1_0_la_SOURCES = \
+       src/gudev/gudevmarshal.h \
+       src/gudev/gudevmarshal.c \
+       src/gudev/gudevenumtypes.h \
+       src/gudev/gudevenumtypes.c
+
+BUILT_SOURCES += \
+       $(nodist_libgudev_1_0_la_SOURCES)
+
+libgudev_1_0_la_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       -I$(top_builddir)/src\
+       -I$(top_srcdir)/src\
+       -I$(top_builddir)/src/gudev \
+       -I$(top_srcdir)/src/gudev \
+       -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+       -D_GUDEV_COMPILATION \
+       -DG_LOG_DOMAIN=\"GUdev\"
+
+libgudev_1_0_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       -fvisibility=default \
+       $(GLIB_CFLAGS)
+
+libgudev_1_0_la_LIBADD = \
+       libudev.la \
+       $(GLIB_LIBS)
+
+libgudev_1_0_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -version-info $(LIBGUDEV_CURRENT):$(LIBGUDEV_REVISION):$(LIBGUDEV_AGE) \
+       -export-dynamic -no-undefined \
+       -export-symbols-regex '^g_udev_.*'
+
+src/gudev/gudevmarshal.h: src/gudev/gudevmarshal.list
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)glib-genmarshal $< --prefix=g_udev_marshal --header > $@
+
+src/gudev/gudevmarshal.c: src/gudev/gudevmarshal.list
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)echo '#include "gudevmarshal.h"' > $@ && \
+       glib-genmarshal $< --prefix=g_udev_marshal --body >> $@
+
+src/gudev/gudevenumtypes.%: src/gudev/gudevenumtypes.%.template src/gudev/gudevenums.h
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)glib-mkenums --template $^ > $@
+
+if HAVE_INTROSPECTION
+-include $(INTROSPECTION_MAKEFILE)
+
+src/gudev/GUdev-1.0.gir: libgudev-1.0.la
+
+src_gudev_GUdev_1_0_gir_INCLUDES = GObject-2.0
+
+src_gudev_GUdev_1_0_gir_CFLAGS = \
+       $(INCLUDES) \
+       -D_GUDEV_COMPILATION \
+       -D_GUDEV_WORK_AROUND_DEV_T_BUG \
+       -I$(top_srcdir)/src \
+       -I$(top_builddir)/src \
+       -I$(top_srcdir)/src/gdev \
+       -I$(top_builddir)/src/gdev
+
+src_gudev_GUdev_1_0_gir_LIBS = libgudev-1.0.la
+
+src_gudev_GUdev_1_0_gir_SCANNERFLAGS = \
+       --pkg-export=gudev-1.0 \
+       --warn-all
+
+src_gudev_GUdev_1_0_gir_FILES = \
+       src/gudev/gudev.h \
+       src/gudev/gudevtypes.h \
+       src/gudev/gudevenums.h \
+       src/gudev/gudevenumtypes.h \
+       src/gudev/gudevclient.h \
+       src/gudev/gudevdevice.h \
+       src/gudev/gudevenumerator.h \
+       src/gudev/gudevclient.c \
+       src/gudev/gudevdevice.c \
+       src/gudev/gudevenumerator.c
+
+INTROSPECTION_GIRS = src/gudev/GUdev-1.0.gir
+INTROSPECTION_SCANNER_ARGS = --c-include=gudev/gudev.h
+
+girdir = $(datadir)/gir-1.0
+gir_DATA = \
+       src/gudev/GUdev-1.0.gir
+
+typelibsdir = $(libdir)/girepository-1.0
+typelibs_DATA = \
+       src/gudev/GUdev-1.0.typelib
+
+CLEANFILES += $(gir_DATA) $(typelibs_DATA)
+endif # HAVE_INTROSPECTION
+
+# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
+libgudev-install-hook:
+       libname=libgudev-1.0.so && $(move-to-rootlibdir)
+
+libgudev-uninstall-hook:
+       rm -f $(DESTDIR)$(rootlibdir)/libgudev-1.0.so*
+
+INSTALL_EXEC_HOOKS += libgudev-install-hook
+UNINSTALL_EXEC_HOOKS += libgudev-uninstall-hook
+endif
+
+EXTRA_DIST += \
+       src/gudev/gudev-1.0.pc.in \
+       src/gudev/gudevmarshal.list \
+       src/gudev/gudevenumtypes.h.template \
+       src/gudev/gudevenumtypes.c.template \
+       src/gudev/gjs-example.js \
+       src/gudev/seed-example-enum.js \
+       src/gudev/seed-example.js
+
+
+# ------------------------------------------------------------------------------
+if ENABLE_KEYMAP
+keymap_SOURCES = \
+       src/udev/keymap/keymap.c
+
+keymap_CPPFLAGS = \
+       $(AM_CPPFLAGS) -I src/udev/keymap
+
+keymap_LDADD = \
+       libsystemd-shared.la
+
+nodist_keymap_SOURCES = \
+       src/udev/keymap/keys-from-name.h \
+       src/udev/keymap/keys-to-name.h
+
+BUILT_SOURCES += \
+       $(nodist_keymap_SOURCES)
+
+udevlibexec_PROGRAMS += \
+       keymap
+
+dist_doc_DATA += \
+       src/udev/keymap/README.keymap.txt
+
+dist_udevrules_DATA += \
+       src/udev/keymap/95-keymap.rules \
+       src/udev/keymap/95-keyboard-force-release.rules
+
+dist_udevhome_SCRIPTS = \
+       src/udev/keymap/findkeyboards \
+       src/udev/keymap/keyboard-force-release.sh
+
+TESTS += \
+       src/udev/keymap/check-keymaps.sh
+
+CLEANFILES += \
+       src/udev/keymap/keys.txt \
+       src/udev/keymap/keys-from-name.gperf \
+       src/udev/keymap/keyboard-force-release.sh
+
+udevkeymapdir = $(udevlibexecdir)/keymaps
+dist_udevkeymap_DATA = \
+       keymaps/acer \
+       keymaps/acer-aspire_5720 \
+       keymaps/acer-aspire_8930 \
+       keymaps/acer-aspire_5920g \
+       keymaps/acer-aspire_6920 \
+       keymaps/acer-travelmate_c300 \
+       keymaps/asus \
+       keymaps/compaq-e_evo \
+       keymaps/dell \
+       keymaps/dell-latitude-xt2 \
+       keymaps/everex-xt5000 \
+       keymaps/fujitsu-amilo_li_2732 \
+       keymaps/fujitsu-amilo_pa_2548 \
+       keymaps/fujitsu-amilo_pro_edition_v3505 \
+       keymaps/fujitsu-amilo_pro_v3205 \
+       keymaps/fujitsu-amilo_si_1520 \
+       keymaps/fujitsu-esprimo_mobile_v5 \
+       keymaps/fujitsu-esprimo_mobile_v6 \
+       keymaps/genius-slimstar-320 \
+       keymaps/hewlett-packard \
+       keymaps/hewlett-packard-2510p_2530p \
+       keymaps/hewlett-packard-compaq_elitebook \
+       keymaps/hewlett-packard-pavilion \
+       keymaps/hewlett-packard-presario-2100 \
+       keymaps/hewlett-packard-tablet \
+       keymaps/hewlett-packard-tx2 \
+       keymaps/hewlett-packard_elitebook-8440p \
+       keymaps/ibm-thinkpad-usb-keyboard-trackpoint \
+       keymaps/inventec-symphony_6.0_7.0 \
+       keymaps/lenovo-3000 \
+       keymaps/lenovo-ideapad \
+       keymaps/lenovo-thinkpad-usb-keyboard-trackpoint \
+       keymaps/lenovo-thinkpad_x6_tablet \
+       keymaps/lenovo-thinkpad_x200_tablet \
+       keymaps/lg-x110 \
+       keymaps/logitech-wave \
+       keymaps/logitech-wave-cordless \
+       keymaps/logitech-wave-pro-cordless \
+       keymaps/maxdata-pro_7000 \
+       keymaps/medion-fid2060 \
+       keymaps/medionnb-a555 \
+       keymaps/micro-star \
+       keymaps/module-asus-w3j \
+       keymaps/module-ibm \
+       keymaps/module-lenovo \
+       keymaps/module-sony \
+       keymaps/module-sony-old \
+       keymaps/module-sony-vgn \
+       keymaps/module-sony-vpc \
+       keymaps/olpc-xo \
+       keymaps/onkyo \
+       keymaps/oqo-model2 \
+       keymaps/samsung-other \
+       keymaps/samsung-series-9 \
+       keymaps/samsung-sq1us \
+       keymaps/samsung-sx20s \
+       keymaps/toshiba-satellite_a100 \
+       keymaps/toshiba-satellite_a110 \
+       keymaps/toshiba-satellite_m30x \
+       keymaps/zepto-znote
+
+udevkeymapforcereldir = $(udevlibexecdir)/keymaps/force-release
+dist_udevkeymapforcerel_DATA = \
+       keymaps-force-release/dell-touchpad \
+       keymaps-force-release/dell-xps \
+       keymaps-force-release/hp-other \
+       keymaps-force-release/samsung-other \
+       keymaps-force-release/samsung-series-9 \
+       keymaps-force-release/common-volume-keys
+
+src/udev/keymap/keys.txt: Makefile
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include linux/input.h - < /dev/null | $(AWK) '/^#define[ \t]+KEY_[^ ]+[ \t]+[0-9]/ { if ($$2 != "KEY_MAX") { print $$2 } }' | sed 's/^KEY_COFFEE$$/KEY_SCREENLOCK/' > $@
+
+src/udev/keymap/keys-from-name.gperf: src/udev/keymap/keys.txt Makefile
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print $$1 ", " $$1 }' < $< > $@
+
+src/udev/keymap/keys-from-name.h: src/udev/keymap/keys-from-name.gperf Makefile
+       $(AM_V_GEN)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_key -H hash_key_name -p -C < $< > $@
+
+src/udev/keymap/keys-to-name.h: src/udev/keymap/keys.txt Makefile
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const key_names[KEY_CNT] = { "} { print "[" $$1 "] = \"" $$1 "\"," } END{print "};"}' < $< > $@
+endif
+
+EXTRA_DIST += \
+       src/udev/keymap/check-keymaps.sh \
+       src/udev/keymap/keyboard-force-release.sh.in
+
+# ------------------------------------------------------------------------------
+mtd_probe_SOURCES =  \
+       src/udev/mtd_probe/mtd_probe.c \
+       src/udev/mtd_probe/mtd_probe.h \
+       src/udev/mtd_probe/probe_smartmedia.c
+
+mtd_probe_CPPFLAGS = \
+       $(AM_CPPFLAGS)
+
+dist_udevrules_DATA += \
+       rules/75-probe_mtd.rules
+
+udevlibexec_PROGRAMS += \
+       mtd_probe
+
+# ------------------------------------------------------------------------------
+libsystemd_id128_la_SOURCES = \
+       src/libsystemd-id128/sd-id128.c
+
+libsystemd_id128_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       -fvisibility=hidden
+
+libsystemd_id128_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -shared \
+       -version-info $(LIBSYSTEMD_ID128_CURRENT):$(LIBSYSTEMD_ID128_REVISION):$(LIBSYSTEMD_ID128_AGE) \
+       -Wl,--version-script=$(top_srcdir)/src/libsystemd-id128/libsystemd-id128.sym
+
+libsystemd_id128_la_LIBADD = \
+       libsystemd-shared.la
+
+libsystemd_id128_internal_la_SOURCES = \
+       $(libsystemd_id128_la_SOURCES)
+
+test_id128_SOURCES = \
+       src/test/test-id128.c
+
+test_id128_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-id128-internal.la
+
+noinst_PROGRAMS += \
+       test-id128
+
+TESTS += \
+       test-id128
+
+pkginclude_HEADERS += \
+       src/systemd/sd-id128.h
+
+lib_LTLIBRARIES += \
+       libsystemd-id128.la
+
+noinst_LTLIBRARIES += \
+       libsystemd-id128-internal.la
+
+pkgconfiglib_DATA += \
+       src/libsystemd-id128/libsystemd-id128.pc
+
+# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
+libsystemd-id128-install-hook:
+       libname=libsystemd-id128.so && $(move-to-rootlibdir)
+
+libsystemd-id128-uninstall-hook:
+       rm -f $(DESTDIR)$(rootlibdir)/libsystemd-id128.so*
+
+INSTALL_EXEC_HOOKS += libsystemd-id128-install-hook
+UNINSTALL_EXEC_HOOKS += libsystemd-id128-uninstall-hook
+
+EXTRA_DIST += \
+       src/libsystemd-id128/libsystemd-id128.pc.in \
+       src/libsystemd-id128/libsystemd-id128.sym
+
+# ------------------------------------------------------------------------------
+systemd_journald_SOURCES = \
+       src/journal/journald.c \
+       src/journal/journald-server.h
+
+systemd_journald_LDADD = \
+       libsystemd-journal-internal.la \
+       libsystemd-shared.la \
+       libsystemd-id128-internal.la
+
+systemd_cat_SOURCES = \
+       src/journal/cat.c
+
+systemd_cat_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la
+
+journalctl_SOURCES = \
+       src/journal/journalctl.c
+
+journalctl_CFLAGS = \
+       $(AM_CFLAGS)
+
+journalctl_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la \
+       libsystemd-logs.la
+
+if HAVE_QRENCODE
+journalctl_SOURCES += \
+       src/journal/journal-qrcode.c \
+       src/journal/journal-qrcode.h
+
+journalctl_CFLAGS += \
+       $(QRENCODE_CFLAGS)
+
+journalctl_LDADD += \
+       $(QRENCODE_LIBS)
+endif
+
+systemd_coredumpctl_SOURCES = \
+       src/journal/coredumpctl.c
+
+systemd_coredumpctl_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal.la
+
+test_journal_SOURCES = \
+       src/journal/test-journal.c
+
+test_journal_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la
+
+test_journal_send_SOURCES = \
+       src/journal/test-journal-send.c
+
+test_journal_send_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la
+
+test_journal_syslog_SOURCES = \
+       src/journal/test-journal-syslog.c
+
+test_journal_syslog_LDADD = \
+       libsystemd-journal-internal.la \
+       libsystemd-shared.la \
+       libsystemd-id128-internal.la
+
+test_journal_match_SOURCES = \
+       src/journal/test-journal-match.c
+
+test_journal_match_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la
+
+test_journal_enum_SOURCES = \
+       src/journal/test-journal-enum.c
+
+test_journal_enum_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la
+
+test_journal_stream_SOURCES = \
+       src/journal/test-journal-stream.c
+
+test_journal_stream_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la
+
+test_journal_verify_SOURCES = \
+       src/journal/test-journal-verify.c
+
+test_journal_verify_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la
+
+test_mmap_cache_SOURCES = \
+       src/journal/test-mmap-cache.c
+
+test_mmap_cache_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-journal-internal.la
+
+test_catalog_SOURCES = \
+       src/journal/test-catalog.c
+
+test_catalog_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-label.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la
+
+libsystemd_journal_la_SOURCES = \
+       src/journal/sd-journal.c \
+       src/systemd/sd-journal.h \
+       src/journal/journal-file.c \
+       src/journal/journal-file.h \
+       src/journal/journal-vacuum.c \
+       src/journal/journal-vacuum.h \
+       src/journal/journal-verify.c \
+       src/journal/journal-verify.h \
+       src/journal/lookup3.c \
+       src/journal/lookup3.h \
+       src/journal/journal-send.c \
+       src/journal/journal-def.h \
+       src/journal/compress.h \
+       src/journal/catalog.c \
+       src/journal/catalog.h \
+       src/journal/mmap-cache.c \
+       src/journal/mmap-cache.h
+
+libsystemd_journal_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       -fvisibility=hidden
+
+libsystemd_journal_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -shared \
+       -version-info $(LIBSYSTEMD_JOURNAL_CURRENT):$(LIBSYSTEMD_JOURNAL_REVISION):$(LIBSYSTEMD_JOURNAL_AGE) \
+       -Wl,--version-script=$(top_srcdir)/src/journal/libsystemd-journal.sym
+
+libsystemd_journal_la_LIBADD = \
+       libsystemd-shared.la \
+       libsystemd-label.la \
+       libsystemd-id128-internal.la
+
+libsystemd_journal_internal_la_SOURCES = \
+       $(libsystemd_journal_la_SOURCES) \
+       src/journal/journald-kmsg.c \
+       src/journal/journald-kmsg.h \
+       src/journal/journald-syslog.c \
+       src/journal/journald-syslog.h \
+       src/journal/journald-stream.c \
+       src/journal/journald-stream.h \
+       src/journal/journald-server.c \
+       src/journal/journald-server.h \
+       src/journal/journald-console.c \
+       src/journal/journald-console.h \
+       src/journal/journald-native.c \
+       src/journal/journald-native.h \
+       src/journal/journald-rate-limit.c \
+       src/journal/journald-rate-limit.h \
+       src/journal/journal-internal.h
+
+libsystemd_journal_internal_la_CFLAGS = \
+       $(AM_CFLAGS)
+
+libsystemd_journal_internal_la_LIBADD = \
+       libsystemd-label.la \
+       libsystemd-audit.la \
+       libsystemd-daemon.la \
+       libudev.la \
+       libsystemd-shared.la \
+       libsystemd-label.la
+
+nodist_libsystemd_journal_internal_la_SOURCES = \
+       src/journal/journald-gperf.c
+
+if ENABLE_LOGIND
+libsystemd_journal_internal_la_LIBADD += \
+       libsystemd-login-internal.la
+endif
+
+if HAVE_ACL
+libsystemd_journal_internal_la_LIBADD += \
+       libsystemd-acl.la
+endif
+
+if HAVE_XZ
+libsystemd_journal_la_SOURCES += \
+       src/journal/compress.c
+
+libsystemd_journal_la_CFLAGS += \
+       $(XZ_CFLAGS)
+
+libsystemd_journal_la_LIBADD += \
+       $(XZ_LIBS)
+
+libsystemd_journal_internal_la_CFLAGS += \
+       $(XZ_CFLAGS)
+
+libsystemd_journal_internal_la_LIBADD += \
+       $(XZ_LIBS)
+
+endif
+
+if HAVE_GCRYPT
+libsystemd_journal_la_SOURCES += \
+       src/journal/journal-authenticate.c \
+       src/journal/journal-authenticate.h \
+       src/journal/fsprg.c \
+       src/journal/fsprg.h
+
+libsystemd_journal_la_CFLAGS += \
+       $(GCRYPT_CFLAGS) \
+       -Wno-pointer-arith
+
+libsystemd_journal_la_LIBADD += \
+       $(GCRYPT_LIBS)
+
+libsystemd_journal_internal_la_CFLAGS += \
+       $(GCRYPT_CFLAGS) \
+       -Wno-pointer-arith
+
+libsystemd_journal_internal_la_LIBADD += \
+       $(GCRYPT_LIBS)
+endif
+
+# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
+libsystemd-journal-install-hook:
+       libname=libsystemd-journal.so && $(move-to-rootlibdir)
+
+libsystemd-journal-uninstall-hook:
+       rm -f $(DESTDIR)$(rootlibdir)/libsystemd-journal.so*
+
+INSTALL_EXEC_HOOKS += libsystemd-journal-install-hook
+UNINSTALL_EXEC_HOOKS += libsystemd-journal-uninstall-hook
+
+# Update catalog on installation. Do not bother if installing
+# in DESTDIR, since this is likely for packaging purposes.
+catalog-update-hook:
+       -test -n "$(DESTDIR)" || $(rootbindir)/journalctl --update-catalog
+
+INSTALL_DATA_HOOKS += \
+       catalog-update-hook
+
+catalog-remove-hook:
+       -test -n "$(DESTDIR)" || rm -f $(catalogstatedir)/database
+
+UNINSTALL_DATA_HOOKS += \
+       catalog-remove-hook
+
+noinst_PROGRAMS += \
+       test-journal \
+       test-journal-send \
+       test-journal-syslog \
+       test-journal-match \
+       test-journal-enum \
+       test-journal-stream \
+       test-journal-verify \
+       test-mmap-cache \
+       test-catalog
+
+TESTS += \
+       test-journal \
+       test-journal-send \
+       test-journal-syslog \
+       test-journal-match \
+       test-journal-stream \
+       test-journal-verify \
+       test-mmap-cache
+
+pkginclude_HEADERS += \
+       src/systemd/sd-journal.h \
+       src/systemd/sd-messages.h
+
+lib_LTLIBRARIES += \
+       libsystemd-journal.la
+
+noinst_LTLIBRARIES += \
+       libsystemd-journal-internal.la
+
+rootlibexec_PROGRAMS += \
+       systemd-journald
+
+rootbin_PROGRAMS += \
+       journalctl
+
+bin_PROGRAMS += \
+       systemd-coredumpctl \
+       systemd-cat
+
+dist_systemunit_DATA += \
+       units/systemd-journald.socket
+
+nodist_systemunit_DATA += \
+       units/systemd-journald.service \
+       units/systemd-journal-flush.service
+
+dist_pkgsysconf_DATA += \
+       src/journal/journald.conf
+
+pkgconfiglib_DATA += \
+       src/journal/libsystemd-journal.pc
+
+dist_catalog_DATA = \
+       catalog/systemd.catalog
+
+journal-install-data-hook:
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(systemunitdir)/sockets.target.wants \
+               $(DESTDIR)$(systemunitdir)/sysinit.target.wants
+       ( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \
+               rm -f systemd-journald.socket && \
+               $(LN_S) ../systemd-journald.socket )
+       ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+               rm -f systemd-journald.service systemd-journal-flush.service && \
+               $(LN_S) ../systemd-journald.service && \
+               $(LN_S) ../systemd-journal-flush.service )
+
+INSTALL_DATA_HOOKS += \
+       journal-install-data-hook
+
+EXTRA_DIST += \
+       src/journal/libsystemd-journal.pc.in \
+       src/journal/libsystemd-journal.sym \
+       units/systemd-journald.service.in \
+       units/systemd-journal-flush.service.in \
+       src/journal/journald-gperf.gperf
+
+CLEANFILES += \
+       src/journal/journald-gperf.c
+
+if HAVE_MICROHTTPD
+
+gatewayddocumentrootdir=$(pkgdatadir)/gatewayd
+
+rootlibexec_PROGRAMS += \
+       systemd-journal-gatewayd
+
+systemd_journal_gatewayd_SOURCES = \
+       src/journal/journal-gatewayd.c
+
+systemd_journal_gatewayd_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-logs.la \
+       libsystemd-journal-internal.la \
+       libsystemd-id128-internal.la \
+       libsystemd-daemon.la \
+       $(MICROHTTPD_LIBS)
+
+systemd_journal_gatewayd_CFLAGS = \
+       -DDOCUMENT_ROOT=\"$(gatewayddocumentrootdir)\" \
+       $(AM_CFLAGS) \
+       $(MICROHTTPD_CFLAGS)
+
+dist_systemunit_DATA += \
+       units/systemd-journal-gatewayd.socket
+
+nodist_systemunit_DATA += \
+       units/systemd-journal-gatewayd.service
+
+dist_gatewayddocumentroot_DATA = \
+       src/journal/browse.html
+
+endif
+
+EXTRA_DIST += \
+       units/systemd-journal-gatewayd.service.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_COREDUMP
+systemd_coredump_SOURCES = \
+       src/journal/coredump.c
+
+systemd_coredump_LDADD = \
+       libsystemd-journal-internal.la \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+if ENABLE_LOGIND
+systemd_coredump_LDADD += \
+       libsystemd-login-internal.la
+endif
+
+rootlibexec_PROGRAMS += \
+       systemd-coredump
+
+sysctl_DATA = \
+       sysctl.d/coredump.conf
+
+CLEANFILES += \
+       sysctl.d/coredump.conf
+endif
+
+EXTRA_DIST += \
+       sysctl.d/coredump.conf.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_BINFMT
+systemd_binfmt_SOURCES = \
+       src/binfmt/binfmt.c
+
+systemd_binfmt_LDADD = \
+       libsystemd-shared.la
+
+rootlibexec_PROGRAMS += \
+       systemd-binfmt
+
+dist_systemunit_DATA += \
+       units/proc-sys-fs-binfmt_misc.automount \
+       units/proc-sys-fs-binfmt_misc.mount
+
+nodist_systemunit_DATA += \
+       units/systemd-binfmt.service
+
+binfmt-install-data-hook:
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(prefix)/lib/binfmt.d \
+               $(DESTDIR)$(sysconfdir)/binfmt.d \
+               $(DESTDIR)$(systemunitdir)/sysinit.target.wants
+       ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+               rm -f systemd-binfmt.service \
+                       proc-sys-fs-binfmt_misc.automount && \
+               $(LN_S) ../systemd-binfmt.service systemd-binfmt.service && \
+               $(LN_S) ../proc-sys-fs-binfmt_misc.automount proc-sys-fs-binfmt_misc.automount )
+
+INSTALL_DATA_HOOKS += \
+       binfmt-install-data-hook
+
+MANPAGES += \
+       man/binfmt.d.5 \
+       man/systemd-binfmt.service.8
+
+MANPAGES_ALIAS +=  \
+       man/systemd-binfmt.8
+
+man/systemd-binfmt.8: man/systemd-binfmt.service.8
+endif
+
+EXTRA_DIST += \
+       units/systemd-binfmt.service.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_VCONSOLE
+systemd_vconsole_setup_SOURCES = \
+       src/vconsole/vconsole-setup.c
+
+systemd_vconsole_setup_LDADD = \
+       libsystemd-shared.la
+
+rootlibexec_PROGRAMS += \
+       systemd-vconsole-setup
+
+nodist_systemunit_DATA += \
+       units/systemd-vconsole-setup.service
+
+vconsole-install-data-hook:
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(systemunitdir)/sysinit.target.wants
+       ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+               rm -f systemd-vconsole-setup.service && \
+               $(LN_S) ../systemd-vconsole-setup.service systemd-vconsole-setup.service )
+
+INSTALL_DATA_HOOKS += \
+       vconsole-install-data-hook
+
+MANPAGES += \
+       man/vconsole.conf.5 \
+       man/systemd-vconsole-setup.service.8
+
+MANPAGES_ALIAS += \
+       man/systemd-vconsole-setup.8
+
+man/systemd-vconsole-setup.8: man/systemd-vconsole-setup.service.8
+endif
+
+EXTRA_DIST += \
+       units/systemd-vconsole-setup.service.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_READAHEAD
+systemd_readahead_SOURCES = \
+       src/readahead/readahead.c \
+       src/readahead/readahead-collect.c \
+       src/readahead/readahead-replay.c \
+       src/readahead/readahead-analyze.c \
+       src/readahead/readahead-common.c \
+       src/readahead/readahead-common.h
+
+systemd_readahead_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-daemon.la \
+       libudev.la
+
+dist_doc_DATA += \
+       src/readahead/sd-readahead.c \
+       src/systemd/sd-readahead.h
+
+rootlibexec_PROGRAMS += \
+       systemd-readahead
+
+dist_systemunit_DATA += \
+       units/systemd-readahead-drop.service \
+       units/systemd-readahead-done.timer
+
+nodist_systemunit_DATA += \
+       units/systemd-readahead-collect.service \
+       units/systemd-readahead-replay.service \
+       units/systemd-readahead-done.service
+
+MANPAGES += \
+       man/sd_readahead.3 \
+       man/sd-readahead.3 \
+       man/systemd-readahead-replay.service.8
+
+MANPAGES_ALIAS += \
+       man/systemd-readahead-collect.service.8 \
+       man/systemd-readahead-done.service.8 \
+       man/systemd-readahead-done.timer.8 \
+       man/systemd-readahead.8
+
+man/systemd-readahead-collect.service.8: man/systemd-readahead-replay.service.8
+man/systemd-readahead-done.service.8: man/systemd-readahead-replay.service.8
+man/systemd-readahead-done.timer.8: man/systemd-readahead-replay.service.8
+man/systemd-readahead.8: man/systemd-readahead-replay.service.8
+
+endif
+
+EXTRA_DIST += \
+       units/systemd-readahead-collect.service.in \
+       units/systemd-readahead-replay.service.in \
+       units/systemd-readahead-done.service.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_QUOTACHECK
+rootlibexec_PROGRAMS += \
+       systemd-quotacheck
+
+nodist_systemunit_DATA += \
+       units/systemd-quotacheck.service
+
+systemd_quotacheck_SOURCES = \
+       src/quotacheck/quotacheck.c
+
+systemd_quotacheck_LDADD = \
+       libsystemd-shared.la
+
+MANPAGES += \
+       man/systemd-quotacheck.service.8
+
+MANPAGES_ALIAS += \
+       man/systemd-quotacheck.8
+
+man/systemd-quotacheck.8: man/systemd-quotacheck.service.8
+
+endif
+
+EXTRA_DIST += \
+       units/systemd-quotacheck.service.in
+
+nodist_systemunit_DATA += \
+       units/quotaon.service
+
+# ------------------------------------------------------------------------------
+if ENABLE_RANDOMSEED
+rootlibexec_PROGRAMS += \
+       systemd-random-seed
+
+nodist_systemunit_DATA += \
+       units/systemd-random-seed-save.service \
+       units/systemd-random-seed-load.service
+
+systemd_random_seed_SOURCES = \
+       src/random-seed/random-seed.c
+
+systemd_random_seed_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+randomseed-install-data-hook:
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(systemunitdir)/shutdown.target.wants \
+               $(DESTDIR)$(systemunitdir)/sysinit.target.wants
+       ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \
+               rm -f systemd-random-seed-save.service && \
+               $(LN_S) ../systemd-random-seed-save.service systemd-random-seed-save.service )
+       ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+               rm -f systemd-random-seed-load.service && \
+               $(LN_S) ../systemd-random-seed-load.service systemd-random-seed-load.service )
+
+INSTALL_DATA_HOOKS += \
+       randomseed-install-data-hook
+
+MANPAGES += \
+       man/systemd-random-seed-load.service.8
+
+MANPAGES_ALIAS +=  \
+       man/systemd-random-seed-save.service.8 \
+       man/systemd-random-seed.8
+
+man/systemd-random-seed-save.service.8: man/systemd-random-seed-load.service.8
+man/systemd-random-seed.8: man/systemd-random-seed-load.service.8
+
+endif
+
+EXTRA_DIST += \
+       units/systemd-random-seed-save.service.in \
+       units/systemd-random-seed-load.service.in
+
+# ------------------------------------------------------------------------------
+if HAVE_LIBCRYPTSETUP
+rootlibexec_PROGRAMS += \
+       systemd-cryptsetup
+
+systemgenerator_PROGRAMS += \
+       systemd-cryptsetup-generator
+
+dist_systemunit_DATA += \
+       units/cryptsetup.target
+
+systemd_cryptsetup_SOURCES = \
+       src/cryptsetup/cryptsetup.c
+
+systemd_cryptsetup_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(LIBCRYPTSETUP_CFLAGS)
+
+systemd_cryptsetup_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libudev.la \
+       $(LIBCRYPTSETUP_LIBS)
+
+systemd_cryptsetup_generator_SOURCES = \
+       src/cryptsetup/cryptsetup-generator.c
+
+systemd_cryptsetup_generator_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+cryptsetup-install-data-hook:
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(systemunitdir)/sysinit.target.wants
+       ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+               rm -f cryptsetup.target && \
+               $(LN_S) ../cryptsetup.target cryptsetup.target )
+
+INSTALL_DATA_HOOKS += \
+       cryptsetup-install-data-hook
+
+MANPAGES += \
+       man/systemd-cryptsetup@.service.8 \
+       man/systemd-cryptsetup-generator.8 \
+       man/crypttab.5
+
+MANPAGES_ALIAS += \
+       man/systemd-cryptsetup.8
+
+man/systemd-cryptsetup.8: man/systemd-cryptsetup@.service.8
+
+endif
+
+# ------------------------------------------------------------------------------
+if ENABLE_HOSTNAMED
+systemd_hostnamed_SOURCES = \
+       src/hostname/hostnamed.c
+
+systemd_hostnamed_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_hostnamed_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-daemon.la \
+       libsystemd-dbus.la
+
+rootlibexec_PROGRAMS += \
+       systemd-hostnamed
+
+nodist_systemunit_DATA += \
+       units/systemd-hostnamed.service
+
+dist_dbuspolicy_DATA += \
+       src/hostname/org.freedesktop.hostname1.conf
+
+dist_dbussystemservice_DATA += \
+       src/hostname/org.freedesktop.hostname1.service
+
+polkitpolicy_files += \
+       src/hostname/org.freedesktop.hostname1.policy
+
+dbusinterface_DATA += \
+       org.freedesktop.hostname1.xml
+
+org.freedesktop.hostname1.xml: systemd-hostnamed
+       $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.hostname1 $< $@.tmp && \
+               $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \
+               $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp
+
+hostnamed-install-data-hook:
+       ( cd $(DESTDIR)$(systemunitdir) && \
+               rm -f dbus-org.freedesktop.hostname1.service && \
+               $(LN_S) systemd-hostnamed.service dbus-org.freedesktop.hostname1.service )
+
+INSTALL_DATA_HOOKS += \
+       hostnamed-install-data-hook
+
+MANPAGES += \
+       man/systemd-hostnamed.service.8
+
+MANPAGES_ALIAS += \
+       man/systemd-hostnamed.8
+
+man/systemd-hostnamed.8: man/systemd-hostnamed.service.8
+
+hostnamectl_SOURCES = \
+       src/hostname/hostnamectl.c
+
+hostnamectl_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+hostnamectl_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la \
+       libsystemd-id128-internal.la
+
+bin_PROGRAMS += \
+       hostnamectl
+
+MANPAGES += \
+       man/hostnamectl.1
+
+endif
+
+polkitpolicy_in_files += \
+       src/hostname/org.freedesktop.hostname1.policy.in
+
+EXTRA_DIST += \
+       units/systemd-hostnamed.service.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_LOCALED
+systemd_localed_SOURCES = \
+       src/locale/localed.c
+
+systemd_localed_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_localed_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libsystemd-daemon.la \
+       libsystemd-dbus.la
+
+nodist_systemunit_DATA += \
+       units/systemd-localed.service
+
+rootlibexec_PROGRAMS += \
+       systemd-localed
+
+dist_dbuspolicy_DATA += \
+       src/locale/org.freedesktop.locale1.conf
+
+dist_dbussystemservice_DATA += \
+       src/locale/org.freedesktop.locale1.service
+
+polkitpolicy_files += \
+       src/locale/org.freedesktop.locale1.policy
+
+dbusinterface_DATA += \
+       org.freedesktop.locale1.xml
+
+org.freedesktop.locale1.xml: systemd-localed
+       $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.locale1 $< $@.tmp && \
+               $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \
+               $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp
+
+localed-install-data-hook:
+       ( cd $(DESTDIR)$(systemunitdir) && \
+               rm -f dbus-org.freedesktop.locale1.service && \
+               $(LN_S) systemd-localed.service dbus-org.freedesktop.locale1.service )
+
+INSTALL_DATA_HOOKS += \
+       localed-install-data-hook
+
+MANPAGES += \
+       man/systemd-localed.service.8
+
+MANPAGES_ALIAS += \
+       man/systemd-localed.8
+
+man/systemd-localed.8: man/systemd-localed.service.8
+
+dist_pkgdata_DATA += \
+       src/locale/kbd-model-map
+
+dist_noinst_SCRIPT = \
+       src/locale/generate-kbd-model-map
+
+update-kbd-model-map: src/locale/generate-kbd-model-map
+       $PYTHON $< > src/locale/kbd-model-map
+
+localectl_SOURCES = \
+       src/locale/localectl.c
+
+localectl_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+localectl_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la \
+       libsystemd-id128-internal.la
+
+bin_PROGRAMS += \
+       localectl
+
+MANPAGES += \
+       man/localectl.1
+
+endif
+
+polkitpolicy_in_files += \
+       src/locale/org.freedesktop.locale1.policy.in
+
+EXTRA_DIST += \
+       units/systemd-localed.service.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_TIMEDATED
+systemd_timedated_SOURCES = \
+       src/timedate/timedated.c
+
+systemd_timedated_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_timedated_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-daemon.la \
+       libsystemd-dbus.la
+
+rootlibexec_PROGRAMS += \
+       systemd-timedated
+
+dist_dbussystemservice_DATA += \
+       src/timedate/org.freedesktop.timedate1.service
+
+dist_dbuspolicy_DATA += \
+       src/timedate/org.freedesktop.timedate1.conf
+
+nodist_systemunit_DATA += \
+       units/systemd-timedated.service
+
+polkitpolicy_files += \
+       src/timedate/org.freedesktop.timedate1.policy
+
+org.freedesktop.timedate1.xml: systemd-timedated
+       $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.timedate1 $< $@.tmp && \
+               $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \
+               $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp
+
+dbusinterface_DATA += \
+       org.freedesktop.timedate1.xml
+
+timedated-install-data-hook:
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(prefix)/lib/systemd/ntp-units.d \
+               $(DESTDIR)$(sysconfdir)/systemd/ntp-units.d
+       ( cd $(DESTDIR)$(systemunitdir) && \
+               rm -f dbus-org.freedesktop.timedate1.service  && \
+               $(LN_S) systemd-timedated.service dbus-org.freedesktop.timedate1.service )
+
+INSTALL_DATA_HOOKS += \
+       timedated-install-data-hook
+
+MANPAGES += \
+       man/systemd-timedated.service.8
+
+MANPAGES_ALIAS += \
+       man/systemd-timedated.8
+
+man/systemd-timedated.8: man/systemd-timedated.service.8
+
+timedatectl_SOURCES = \
+       src/timedate/timedatectl.c
+
+timedatectl_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+timedatectl_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la
+
+bin_PROGRAMS += \
+       timedatectl
+
+MANPAGES += \
+       man/timedatectl.1
+
+endif
+
+polkitpolicy_in_files += \
+       src/timedate/org.freedesktop.timedate1.policy.in
+
+EXTRA_DIST += \
+       units/systemd-timedated.service.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_LOGIND
+systemd_logind_SOURCES = \
+       src/login/logind.c \
+       src/login/logind.h \
+       src/login/logind-dbus.c \
+       src/login/logind-device.c \
+       src/login/logind-device.h \
+       src/login/logind-button.c \
+       src/login/logind-button.h \
+       src/login/logind-action.c \
+       src/login/logind-action.h \
+       src/login/logind-seat.c \
+       src/login/logind-seat.h \
+       src/login/logind-session.c \
+       src/login/logind-session.h \
+       src/login/logind-user.c \
+       src/login/logind-user.h \
+       src/login/logind-inhibit.c \
+       src/login/logind-inhibit.h \
+       src/login/logind-session-dbus.c \
+       src/login/logind-seat-dbus.c \
+       src/login/logind-user-dbus.c \
+       src/login/logind-acl.h
+
+nodist_systemd_logind_SOURCES = \
+       src/login/logind-gperf.c
+
+systemd_logind_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_logind_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la \
+       libsystemd-audit.la \
+       libsystemd-daemon.la \
+       libsystemd-dbus.la \
+       libudev.la
+
+if HAVE_ACL
+systemd_logind_SOURCES += \
+       src/login/logind-acl.c
+
+systemd_logind_LDADD += \
+       libsystemd-acl.la
+endif
+
+systemd_user_sessions_SOURCES = \
+       src/login/user-sessions.c
+
+systemd_user_sessions_LDADD = \
+       libsystemd-shared.la
+
+rootlibexec_PROGRAMS += \
+       systemd-logind \
+       systemd-user-sessions
+
+loginctl_SOURCES = \
+       src/login/loginctl.c \
+       src/login/sysfs-show.c
+
+loginctl_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+loginctl_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la \
+       libudev.la
+
+rootbin_PROGRAMS += \
+       loginctl
+
+systemd_inhibit_SOURCES = \
+       src/login/inhibit.c
+
+systemd_inhibit_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+systemd_inhibit_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la
+
+rootbin_PROGRAMS += \
+       systemd-inhibit
+
+test_login_SOURCES = \
+       src/login/test-login.c
+
+test_login_LDADD = \
+       libsystemd-login-internal.la \
+       libsystemd-shared.la
+
+test_inhibit_SOURCES = \
+       src/login/test-inhibit.c
+
+test_inhibit_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-dbus.la
+
+test_inhibit_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(DBUS_CFLAGS)
+
+noinst_PROGRAMS += \
+       test-login \
+       test-inhibit
+
+libsystemd_login_la_SOURCES = \
+       src/login/sd-login.c
+
+libsystemd_login_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       -fvisibility=hidden
+
+libsystemd_login_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -shared \
+       -version-info $(LIBSYSTEMD_LOGIN_CURRENT):$(LIBSYSTEMD_LOGIN_REVISION):$(LIBSYSTEMD_LOGIN_AGE) \
+       -Wl,--version-script=$(top_srcdir)/src/login/libsystemd-login.sym
+
+libsystemd_login_la_LIBADD = \
+       libsystemd-shared.la
+
+libsystemd_login_internal_la_SOURCES = \
+       $(libsystemd_login_la_SOURCES)
+
+if HAVE_PAM
+pam_systemd_la_SOURCES = \
+       src/login/pam-module.c
+
+pam_systemd_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(PAM_CFLAGS) \
+       $(DBUS_CFLAGS) \
+       -fvisibility=hidden
+
+pam_systemd_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -module \
+       -export-dynamic \
+       -avoid-version \
+       -shared \
+       -export-symbols-regex '^pam_sm_.*'
+
+pam_systemd_la_LIBADD = \
+       libsystemd-daemon.la \
+       libsystemd-audit.la \
+       libsystemd-dbus.la \
+       libsystemd-shared.la \
+       $(PAM_LIBS)
+
+pamlib_LTLIBRARIES = \
+       pam_systemd.la
+endif
+
+# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
+libsystemd-login-install-hook:
+       libname=libsystemd-login.so && $(move-to-rootlibdir)
+
+libsystemd-login-uninstall-hook:
+       rm -f $(DESTDIR)$(rootlibdir)/libsystemd-login.so*
+
+INSTALL_EXEC_HOOKS += libsystemd-login-install-hook
+UNINSTALL_EXEC_HOOKS += libsystemd-login-uninstall-hook
+
+nodist_systemunit_DATA += \
+       units/systemd-logind.service \
+       units/systemd-user-sessions.service
+
+dist_dbussystemservice_DATA += \
+       src/login/org.freedesktop.login1.service
+
+dist_dbuspolicy_DATA += \
+       src/login/org.freedesktop.login1.conf
+
+dist_pkgsysconf_DATA += \
+       src/login/logind.conf
+
+pkginclude_HEADERS += \
+       src/systemd/sd-login.h
+
+lib_LTLIBRARIES += \
+       libsystemd-login.la
+
+noinst_LTLIBRARIES += \
+       libsystemd-login-internal.la
+
+pkgconfiglib_DATA += \
+       src/login/libsystemd-login.pc
+
+polkitpolicy_files += \
+       src/login/org.freedesktop.login1.policy
+
+logind-install-data-hook:
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(systemunitdir)/multi-user.target.wants \
+               $(DESTDIR)$(systemdstatedir)
+       ( cd $(DESTDIR)$(systemunitdir) && \
+               rm -f dbus-org.freedesktop.login1.service && \
+               $(LN_S) systemd-logind.service dbus-org.freedesktop.login1.service)
+       ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \
+               rm -f systemd-logind.service systemd-user-sessions.service && \
+               $(LN_S) ../systemd-logind.service systemd-logind.service && \
+               $(LN_S) ../systemd-user-sessions.service systemd-user-sessions.service )
+
+INSTALL_DATA_HOOKS += \
+       logind-install-data-hook
+
+systemd_multi_seat_x_SOURCES = \
+       src/login/multi-seat-x.c
+
+systemd_multi_seat_x_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+rootlibexec_PROGRAMS += \
+       systemd-multi-seat-x
+
+dist_udevrules_DATA += \
+       src/login/70-uaccess.rules \
+       src/login/70-power-switch.rules
+
+nodist_udevrules_DATA += \
+       src/login/71-seat.rules \
+       src/login/73-seat-late.rules
+
+MANPAGES += \
+       man/systemd-logind.service.8 \
+       man/logind.conf.5 \
+       man/sd-login.3 \
+       man/loginctl.1 \
+       man/sd_login_monitor_new.3 \
+       man/sd_pid_get_session.3 \
+       man/sd_uid_get_state.3 \
+       man/sd_session_is_active.3 \
+       man/sd_seat_get_active.3 \
+       man/sd_get_seats.3 \
+       man/systemd-user-sessions.service.8
+
+MANPAGES_ALIAS += \
+       man/sd_login_monitor_unref.3 \
+       man/sd_login_monitor_flush.3 \
+       man/sd_login_monitor_get_fd.3 \
+       man/sd_login_monitor.3 \
+       man/sd_session_get_uid.3 \
+       man/sd_session_get_seat.3 \
+       man/sd_session_get_service.3 \
+       man/sd_session_get_state.3 \
+       man/sd_session_get_type.3 \
+       man/sd_session_get_class.3 \
+       man/sd_session_get_display.3 \
+       man/sd_pid_get_owner_uid.3 \
+       man/sd_pid_get_unit.3 \
+       man/sd_uid_is_on_seat.3 \
+       man/sd_uid_get_sessions.3 \
+       man/sd_uid_get_seats.3 \
+       man/sd_seat_get_sessions.3 \
+       man/sd_seat_can_multi_session.3 \
+       man/sd_get_sessions.3 \
+       man/sd_get_uids.3 \
+       man/systemd-logind.8 \
+       man/systemd-user-sessions.8
+
+man/systemd-logind.8: man/systemd-logind.service.8
+man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3
+man/sd_login_monitor_flush.3: man/sd_login_monitor_new.3
+man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3
+man/sd_login_monitor.3: man/sd_login_monitor_new.3
+man/sd_session_get_uid.3: man/sd_session_is_active.3
+man/sd_session_get_seat.3: man/sd_session_is_active.3
+man/sd_session_get_service.3: man/sd_session_is_active.3
+man/sd_session_get_state.3: man/sd_session_is_active.3
+man/sd_session_get_type.3: man/sd_session_is_active.3
+man/sd_session_get_class.3: man/sd_session_is_active.3
+man/sd_session_get_display.3: man/sd_session_is_active.3
+man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3
+man/sd_pid_get_unit.3: man/sd_pid_get_session.3
+man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3
+man/sd_uid_get_sessions.3: man/sd_uid_get_state.3
+man/sd_uid_get_seats.3: man/sd_uid_get_state.3
+man/sd_seat_get_sessions.3: man/sd_seat_get_active.3
+man/sd_seat_can_multi_session.3: man/sd_seat_get_active.3
+man/sd_get_sessions.3: man/sd_get_seats.3
+man/sd_get_uids.3: man/sd_get_seats.3
+man/systemd-user-sessions.8: man/systemd-user-sessions.service.8
+
+CLEANFILES += \
+       src/login/logind-gperf.c \
+       src/login/71-seat.rules \
+       src/login/73-seat-late.rules
+endif
+
+polkitpolicy_in_files += \
+       src/login/org.freedesktop.login1.policy.in
+
+EXTRA_DIST += \
+       src/login/logind-gperf.gperf \
+       src/login/libsystemd-login.pc.in \
+       src/login/libsystemd-login.sym \
+       src/login/71-seat.rules.in \
+       src/login/73-seat-late.rules.in \
+       units/systemd-logind.service.in \
+       units/systemd-user-sessions.service.in
+
+# ------------------------------------------------------------------------------
+
+if HAVE_PYTHON_DEVEL
+
+pkgpyexec_LTLIBRARIES = \
+       _journal.la
+
+_journal_la_SOURCES = \
+       src/python-systemd/_journal.c
+
+_journal_la_CFLAGS = \
+       $(AM_CFLAGS) \
+        -fvisibility=default \
+       $(PYTHON_CFLAGS)
+
+_journal_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -shared \
+       -module \
+       -avoid-version
+
+_journal_la_LIBADD = \
+       $(PYTHON_LIBS) \
+       libsystemd-journal.la
+
+dist_pkgpyexec_PYTHON = \
+       src/python-systemd/journal.py \
+       src/python-systemd/__init__.py
+
+endif
+
+# ------------------------------------------------------------------------------
+
+SED_PROCESS = \
+       $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+       $(SED)  -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \
+               -e 's,@rootbindir\@,$(rootbindir),g' \
+               -e 's,@bindir\@,$(bindir),g' \
+               -e 's,@SYSTEMCTL\@,$(rootbindir)/systemctl,g' \
+               -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \
+               -e 's,@pkgsysconfdir\@,$(pkgsysconfdir),g' \
+               -e 's,@pkgdatadir\@,$(pkgdatadir),g' \
+               -e 's,@systemunitdir\@,$(systemunitdir),g' \
+               -e 's,@userunitdir\@,$(userunitdir),g' \
+               -e 's,@systempresetdir\@,$(systempresetdir),g' \
+               -e 's,@userpresetdir\@,$(userpresetdir),g' \
+               -e 's,@udevhwdbdir\@,$(udevhwdbdir),g' \
+               -e 's,@udevrulesdir\@,$(udevrulesdir),g' \
+               -e 's,@catalogdir\@,$(catalogdir),g' \
+               -e 's,@tmpfilesdir\@,$(tmpfilesdir),g' \
+               -e 's,@sysctldir\@,$(sysctldir),g' \
+               -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
+               -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \
+               -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' \
+               -e 's,@RANDOM_SEED\@,$(localstatedir)/lib/random-seed,g' \
+               -e 's,@prefix\@,$(prefix),g' \
+               -e 's,@exec_prefix\@,$(exec_prefix),g' \
+               -e 's,@libdir\@,$(libdir),g' \
+               -e 's,@includedir\@,$(includedir),g' \
+               -e 's,@VERSION\@,$(VERSION),g' \
+               -e 's,@rootprefix\@,$(rootprefix),g' \
+               -e 's,@udevlibexecdir\@,$(udevlibexecdir),g' \
+               -e 's,@sushell\@,$(sushell),g' \
+               -e 's,@KILL\@,$(KILL),g' \
+               -e 's,@QUOTAON\@,$(QUOTAON),g' \
+               -e 's,@QUOTACHECK\@,$(QUOTACHECK),g' \
+               -e 's,@SYSTEM_SYSVINIT_PATH\@,$(sysvinitdir),g' \
+               -e 's,@VARLOGDIR\@,$(varlogdir),g' \
+               -e 's,@RC_LOCAL_SCRIPT_PATH_START\@,$(RC_LOCAL_SCRIPT_PATH_START),g' \
+               -e 's,@RC_LOCAL_SCRIPT_PATH_STOP\@,$(RC_LOCAL_SCRIPT_PATH_STOP),g' \
+               -e 's,@PYTHON\@,$(PYTHON),g' \
+               -e 's,@PYTHON_BINARY\@,$(PYTHON_BINARY),g' \
+               < $< > $@
+
+units/%: units/%.in Makefile
+       $(SED_PROCESS)
+
+man/%: man/%.in Makefile
+       $(SED_PROCESS)
+
+sysctl.d/%: sysctl.d/%.in Makefile
+       $(SED_PROCESS)
+
+%.pc: %.pc.in Makefile
+       $(SED_PROCESS)
+
+src/core/macros.%: src/core/macros.%.in Makefile
+       $(SED_PROCESS)
+
+src/%.policy.in: src/%.policy.in.in Makefile
+       $(SED_PROCESS)
+
+%.rules: %.rules.in Makefile
+       $(SED_PROCESS)
+
+%.sh: %.sh.in Makefile
+       $(SED_PROCESS)
+       $(AM_V_GEN)chmod +x $@
+
+src/analyze/systemd-analyze: %: %.in Makefile
+       $(SED_PROCESS)
+       $(AM_V_GEN)chmod +x $@
+
+src/%.c: src/%.gperf
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(GPERF) < $< > $@
+
+src/%: src/%.m4
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(M4) -P $(M4_DEFINES) < $< > $@
+
+M4_PROCESS_SYSTEM = \
+       $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+       $(M4) -P $(M4_DEFINES) -DFOR_SYSTEM=1 < $< > $@
+
+M4_PROCESS_USER = \
+       $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+       $(M4) -P $(M4_DEFINES) -DFOR_USER=1 < $< > $@
+
+units/%: units/%.m4 Makefile
+       $(M4_PROCESS_SYSTEM)
+
+units/user/%: units/%.m4 Makefile
+       $(M4_PROCESS_USER)
+
+nodist_polkitpolicy_DATA = \
+       $(polkitpolicy_files) \
+       $(polkitpolicy_in_in_files:.policy.in.in=.policy)
+
+EXTRA_DIST += \
+       $(polkitpolicy_in_files) \
+       $(polkitpolicy_in_in_files)
+
+CLEANFILES += \
+       $(nodist_systemunit_DATA) \
+       $(nodist_userunit_DATA) \
+       $(nodist_man_MANS) \
+       $(pkgconfigdata_DATA) \
+       $(pkgconfiglib_DATA) \
+       $(nodist_polkitpolicy_DATA)
+
+if ENABLE_MANPAGES
+XSLTPROC_FLAGS = \
+       --nonet \
+       --stringparam man.output.quietly 1 \
+       --stringparam funcsynopsis.style ansi \
+       --stringparam man.th.extra1.suppress 1 \
+       --stringparam man.authors.section.enabled 0 \
+       --stringparam man.copyright.section.enabled 0
+
+XSLTPROC_PROCESS_MAN = \
+       $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+       $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
+
+XSLTPROC_PROCESS_HTML = \
+       $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+       $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $<
+
+man/%.1: man/%.xml
+       $(XSLTPROC_PROCESS_MAN)
+
+man/%.3: man/%.xml
+       $(XSLTPROC_PROCESS_MAN)
+
+man/%.5: man/%.xml
+       $(XSLTPROC_PROCESS_MAN)
+
+man/%.7: man/%.xml
+       $(XSLTPROC_PROCESS_MAN)
+
+man/%.8: man/%.xml
+       $(XSLTPROC_PROCESS_MAN)
+
+man/%.html: man/%.xml man/custom-html.xsl
+       $(XSLTPROC_PROCESS_HTML)
+
+CLEANFILES += \
+       $(dist_man_MANS) \
+       ${XML_FILES:.xml=.html}
+endif
+
+DBUS_PREPROCESS = $(CPP) -P $(CFLAGS) $(DBUS_CFLAGS) -imacros dbus/dbus-protocol.h
+
+CLEANFILES += \
+       $(dbusinterface_DATA)
+
+if HAVE_SYSV_COMPAT
+sysvinit_DATA = \
+       docs/sysvinit/README
+
+varlog_DATA = \
+       docs/var-log/README
+
+docs/sysvinit/README: docs/sysvinit/README.in
+       $(SED_PROCESS)
+
+docs/var-log/README: docs/var-log/README.in
+       $(SED_PROCESS)
+
+EXTRA_DIST += \
+       docs/sysvinit/README.in \
+       docs/var-log/README.in
+
+CLEANFILES += \
+       docs/sysvinit/README \
+       docs/var-log/README
+
+endif
+
+EXTRA_DIST += \
+       shell-completion/systemd-zsh-completion.zsh
+
+systemd-install-data-hook:
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(tmpfilesdir) \
+               $(DESTDIR)$(sysconfdir)/tmpfiles.d \
+               $(DESTDIR)$(prefix)/lib/modules-load.d \
+               $(DESTDIR)$(sysconfdir)/modules-load.d \
+               $(DESTDIR)$(prefix)/lib/sysctl.d \
+               $(DESTDIR)$(sysconfdir)/sysctl.d \
+               $(DESTDIR)$(systemshutdowndir) \
+               $(DESTDIR)$(systemsleepdir) \
+               $(DESTDIR)$(systemgeneratordir) \
+               $(DESTDIR)$(usergeneratordir)
+       $(MKDIR_P) -m 0755 \
+               $(DESTDIR)$(systemunitdir) \
+               $(DESTDIR)$(userunitdir) \
+               $(DESTDIR)$(systemunitdir)/sysinit.target.wants \
+               $(DESTDIR)$(systemunitdir)/sockets.target.wants \
+               $(DESTDIR)$(systemunitdir)/basic.target.wants \
+               $(DESTDIR)$(systemunitdir)/shutdown.target.wants \
+               $(DESTDIR)$(systemunitdir)/local-fs.target.wants \
+               $(DESTDIR)$(systemunitdir)/runlevel1.target.wants \
+               $(DESTDIR)$(systemunitdir)/runlevel2.target.wants \
+               $(DESTDIR)$(systemunitdir)/runlevel3.target.wants \
+               $(DESTDIR)$(systemunitdir)/runlevel4.target.wants \
+               $(DESTDIR)$(systemunitdir)/runlevel5.target.wants \
+               $(DESTDIR)$(systemunitdir)/multi-user.target.wants \
+               $(DESTDIR)$(systemunitdir)/graphical.target.wants \
+               $(DESTDIR)$(pkgsysconfdir)/system \
+               $(DESTDIR)$(pkgsysconfdir)/system/sysinit.target.wants \
+               $(DESTDIR)$(pkgsysconfdir)/system/local-fs.target.wants \
+               $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants \
+               $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants \
+               $(DESTDIR)$(pkgsysconfdir)/user \
+               $(DESTDIR)$(dbussessionservicedir) \
+               $(DESTDIR)$(sysconfdir)/xdg/systemd
+       ( cd $(DESTDIR)$(sysconfdir)/xdg/systemd/ && \
+               rm -f user && \
+               $(LN_S) $(pkgsysconfdir)/user user )
+       ( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \
+               rm -f systemd-initctl.socket systemd-shutdownd.socket && \
+               $(LN_S) ../systemd-initctl.socket systemd-initctl.socket && \
+               $(LN_S) ../systemd-shutdownd.socket systemd-shutdownd.socket )
+       ( cd $(DESTDIR)$(systemunitdir)/runlevel1.target.wants && \
+               rm -f systemd-update-utmp-runlevel.service && \
+               $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service )
+       ( cd $(DESTDIR)$(systemunitdir)/runlevel2.target.wants && \
+               rm -f systemd-update-utmp-runlevel.service && \
+               $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service )
+       ( cd $(DESTDIR)$(systemunitdir)/runlevel3.target.wants && \
+               rm -f systemd-update-utmp-runlevel.service && \
+               $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service )
+       ( cd $(DESTDIR)$(systemunitdir)/runlevel4.target.wants && \
+               rm -f systemd-update-utmp-runlevel.service && \
+               $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service )
+       ( cd $(DESTDIR)$(systemunitdir)/runlevel5.target.wants && \
+               rm -f systemd-update-utmp-runlevel.service && \
+               $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service )
+       ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \
+               rm -f systemd-update-utmp-shutdown.service && \
+               $(LN_S) ../systemd-update-utmp-shutdown.service systemd-update-utmp-shutdown.service )
+       ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \
+               rm -f systemd-remount-fs.service \
+                       systemd-fsck-root.service \
+                       tmp.mount && \
+               $(LN_S) ../systemd-remount-fs.service systemd-remount-fs.service && \
+               $(LN_S) ../systemd-fsck-root.service systemd-fsck-root.service && \
+               $(LN_S) ../tmp.mount tmp.mount )
+       ( cd $(DESTDIR)$(userunitdir) && \
+               rm -f shutdown.target sockets.target bluetooth.target printer.target sound.target && \
+               $(LN_S) $(systemunitdir)/shutdown.target shutdown.target && \
+               $(LN_S) $(systemunitdir)/sockets.target sockets.target && \
+               $(LN_S) $(systemunitdir)/bluetooth.target bluetooth.target && \
+               $(LN_S) $(systemunitdir)/printer.target printer.target && \
+               $(LN_S) $(systemunitdir)/sound.target sound.target )
+       ( cd $(DESTDIR)$(systemunitdir) && \
+               rm -f runlevel0.target runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target runlevel6.target && \
+               $(LN_S) poweroff.target runlevel0.target && \
+               $(LN_S) rescue.target runlevel1.target && \
+               $(LN_S) multi-user.target runlevel2.target && \
+               $(LN_S) multi-user.target runlevel3.target && \
+               $(LN_S) multi-user.target runlevel4.target && \
+               $(LN_S) graphical.target runlevel5.target && \
+               $(LN_S) reboot.target runlevel6.target )
+       ( cd $(DESTDIR)$(systemunitdir) && \
+               rm -f default.target ctrl-alt-del.target autovt@.service && \
+               $(LN_S) graphical.target default.target && \
+               $(LN_S) reboot.target ctrl-alt-del.target && \
+               $(LN_S) getty@.service autovt@.service )
+       ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \
+               rm -f getty.target systemd-ask-password-wall.path && \
+               $(LN_S) ../getty.target getty.target && \
+               $(LN_S) ../systemd-ask-password-wall.path systemd-ask-password-wall.path)
+       ( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \
+               rm -f getty@tty1.service && \
+               $(LN_S) $(systemunitdir)/getty@.service getty@tty1.service )
+       ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \
+               rm -f remote-fs.target && \
+               $(LN_S) $(systemunitdir)/remote-fs.target remote-fs.target )
+       ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+               rm -f dev-hugepages.mount \
+                       dev-mqueue.mount \
+                       sys-kernel-config.mount \
+                       sys-kernel-debug.mount \
+                       sys-fs-fuse-connections.mount \
+                       systemd-tmpfiles-setup.service \
+                       systemd-sysctl.service \
+                       systemd-ask-password-console.path && \
+               $(LN_S) ../dev-hugepages.mount dev-hugepages.mount && \
+               $(LN_S) ../dev-mqueue.mount dev-mqueue.mount && \
+               $(LN_S) ../sys-kernel-config.mount sys-kernel-config.mount && \
+               $(LN_S) ../sys-kernel-debug.mount sys-kernel-debug.mount && \
+               $(LN_S) ../sys-fs-fuse-connections.mount sys-fs-fuse-connections.mount && \
+               $(LN_S) ../systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \
+               $(LN_S) ../systemd-sysctl.service systemd-sysctl.service && \
+               $(LN_S) ../systemd-ask-password-console.path systemd-ask-password-console.path )
+       ( cd $(DESTDIR)$(systemunitdir)/basic.target.wants && \
+               rm -f systemd-tmpfiles-clean.timer && \
+               $(LN_S) ../systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.timer )
+       ( cd $(DESTDIR)$(dbussessionservicedir) && \
+               rm -f org.freedesktop.systemd1.service && \
+               $(LN_S) ../system-services/org.freedesktop.systemd1.service org.freedesktop.systemd1.service )
+
+if HAVE_KMOD
+       ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+               rm -f systemd-modules-load.service && \
+               $(LN_S) ../systemd-modules-load.service systemd-modules-load.service )
+endif
+
+install-exec-hook: $(INSTALL_EXEC_HOOKS)
+
+uninstall-hook: $(UNINSTALL_DATA_HOOKS) $(UNINSTALL_EXEC_HOOKS)
+
+install-data-hook: systemd-install-data-hook $(INSTALL_DATA_HOOKS)
+
+distclean-local: $(DISTCLEAN_LOCAL_HOOKS)
+
+clean-local:
+       rm -rf $(abs_srcdir)/install-tree
+       rm -f $(abs_srcdir)/hwdb/usb.ids $(abs_srcdir)/hwdb/pci.ids $(abs_srcdir)/hwdb/oui.txt \
+              $(abs_srcdir)/hwdb/iab.txt
+
+DISTCHECK_CONFIGURE_FLAGS = \
+       --with-dbuspolicydir=$$dc_install_base/$(dbuspolicydir) \
+       --with-dbussessionservicedir=$$dc_install_base/$(dbussessionservicedir) \
+       --with-dbussystemservicedir=$$dc_install_base/$(dbussystemservicedir) \
+       --with-dbusinterfacedir=$$dc_install_base/$(dbusinterfacedir) \
+       --with-pamlibdir=$$dc_install_base/$(pamlibdir) \
+       --with-rootprefix=$$dc_install_base \
+       --disable-split-usr
+
+
+if HAVE_SYSV_COMPAT
+DISTCHECK_CONFIGURE_FLAGS += \
+       --with-sysvinit-path=$$dc_install_base/$(sysvinitdir) \
+       --with-sysvrcnd-path=$$dc_install_base/$(sysvrcddir)
+endif
+
+if ENABLE_GTK_DOC
+DISTCHECK_CONFIGURE_FLAGS += \
+       --enable-gtk-doc
+endif
+
+hwdb-update:
+       ( cd $(top_srcdir)/hwdb && \
+       wget -N http://www.linux-usb.org/usb.ids \
+               http://pci-ids.ucw.cz/v2.2/pci.ids \
+               http://standards.ieee.org/develop/regauth/oui/oui.txt \
+               http://standards.ieee.org/develop/regauth/iab/iab.txt && \
+       ./ids-update.pl )
+
+upload: all distcheck
+       cp -v systemd-$(VERSION).tar.xz /home/lennart/git.fedora/systemd/
+       scp systemd-$(VERSION).tar.xz fdo:/srv/www.freedesktop.org/www/software/systemd/
+       scp man/*.html tango:public/systemd-man/
+
+doc-sync: all
+       gtkdoc-rebase --html-dir=docs/libudev/html --online
+       rsync -av --delete docs/libudev/html/ --omit-dir-times www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd/libudev/
+       gtkdoc-rebase --html-dir=docs/gudev/html --online
+       rsync -av --delete docs/gudev/html/ --omit-dir-times www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd/gudev/
+       rsync -av --delete-excluded --include="*.html" --exclude="*" --omit-dir-times man/ www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd/man/
+
+git-tag:
+       git tag "v$(VERSION)" -m "systemd $(VERSION)"
+
+install-tree: all
+       rm -rf $(abs_srcdir)/install-tree
+       make install DESTDIR=$(abs_srcdir)/install-tree
+       tree $(abs_srcdir)/install-tree
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..ca6245b
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,1264 @@
+systemd System and Service Manager
+
+CHANGES WITH 196:
+
+        * udev gained support for loading additional device properties
+          from an indexed database that is keyed by vendor/product IDs
+          and similar device identifiers. For the beginning this
+          "hwdb" is populated with data from the well-known PCI and
+          USB database, but also includes PNP, ACPI and OID data. In
+          the longer run this indexed database shall grow into
+          becoming the one central database for non-essential
+          userspace device metadata. Previously, data from the PCI/USB
+          database was only attached to select devices, since the
+          lookup was a relatively expensive operation due to O(n) time
+          complexity (with n being the number of entries in the
+          database). Since this is now O(1), we decided to add in this
+          data for all devices where this is available, by
+          default. Note that the indexed database needs to be rebuilt
+          when new data files are installed. To achieve this you need
+          to update your packaging scripts to invoke "udevadm hwdb
+          --update" after installation of hwdb data files. For
+          RPM-based distributions we introduced the new
+          %udev_hwdb_update macro for this purpose.
+
+        * The Journal gained support for the "Message Catalog", an
+          indexed database to link up additional information with
+          journal entries. For further details please check:
+
+          http://www.freedesktop.org/wiki/Software/systemd/catalog
+
+          The indexed message catalog database also needs to be
+          rebuilt after installation of message catalog files. Use
+          "journalctl --update-catalog" for this. For RPM-based
+          distributions we introduced the %journal_catalog_update
+          macro for this purpose.
+
+        * The Python Journal bindings gained support for the standard
+          Python logging framework.
+
+        * The Journal API gained new functions for checking whether
+          the underlying file system of a journal file is capable of
+          properly reporting file change notifications, or whether
+          applications that want to reflect journal changes "live"
+          need to recheck journal files continously in appropriate
+          time intervals.
+
+        * It is now possible to set the "age" field for tmpfiles
+          entries to 0, indicating that files matching this entry
+          shall always be removed when the directories are cleaned up.
+
+        * coredumpctl gained a new "gdb" verb which invokes gdb
+          right-away on the selected coredump.
+
+        * There's now support for "hybrid sleep" on kernels that
+          support this, in addition to "suspend" and "hibernate". Use
+          "systemctl hybrid-sleep" to make use of this.
+
+        * logind's HandleSuspendKey= setting (and related settings)
+          now gained support for a new "lock" setting to simply
+          request the screen lock on all local sessions, instead of
+          actually executing a suspend or hibernation.
+
+        * systemd will now mount the EFI variables file system by
+          default.
+
+        * Socket units now gained support for configuration of the
+          SMACK security label.
+
+        * timedatectl will now output the time of the last and next
+          daylight saving change.
+
+        * We dropped support for various legacy and distro-specific
+          concepts, such as insserv, early-boot SysV services
+          (i.e. those for non-standard runlevels such as 'b' or 'S')
+          or ArchLinux /etc/rc.conf support. We recommend the
+          distributions who still need support this to either continue
+          to maintain the necessary patches downstream, or find a
+          different solution. (Talk to us if you have questions!)
+
+        * Various systemd components will now bypass PolicyKit checks
+          for root and otherwise handle properly if PolicyKit is not
+          found to be around. This should fix most issues for
+          PolicyKit-less systems. Quite frankly this should have been
+          this way since day one. It is absolutely our intention to
+          make systemd work fine on PolicyKit-less systems, and we
+          consider it a bug if something doesn't work as it should if
+          PolicyKit is not around.
+
+        * For embedded systems it is now possible to build udev and
+          systemd without blkid and/or kmod support.
+
+        * "systemctl switch-root" is now capable of switching root
+          more than once. I.e. in addition to transitions from the
+          initrd to the host OS it is now possible to transition to
+          further OS images from the host. This is useful to implement
+          offline updating tools.
+
+        * Various other additions have been made to the RPM macros
+          shipped with systemd. Use %udev_rules_update() after
+          installing new udev rules files. %_udevhwdbdir,
+          %_udevrulesdir, %_journalcatalogdir, %_tmpfilesdir,
+          %_sysctldir are now available which resolve to the right
+          directories for packages to place various data files in.
+
+        * journalctl gained the new --full switch (in addition to
+          --all, to disable ellipsation for long messages.
+
+        Contributions from: Anders Olofsson, Auke Kok, Ben Boeckel,
+        Colin Walters, Cosimo Cecchi, Daniel Wallace, Dave Reisner,
+        Eelco Dolstra, Holger Hans Peter Freyther, Kay Sievers,
+        Chun-Yi Lee, Lekensteyn, Lennart Poettering, Mantas Mikulėnas,
+        Marti Raudsepp, Martin Pitt, Mauro Dreissig, Michael Biebl,
+        Michal Schmidt, Michal Sekletar, Miklos Vajna, Nis Martensen,
+        Oleksii Shevchuk, Olivier Brunel, Ramkumar Ramachandra, Thomas
+        Bächler, Thomas Hindoe Paaboel Andersen, Tom Gundersen, Tony
+        Camuso, Umut Tezduyar, Zbigniew Jędrzejewski-Szmek
+
+CHANGES WITH 195:
+
+        * journalctl gained new --since= and --until= switches to
+          filter by time. It also now supports nice filtering for
+          units via --unit=/-u.
+
+        * Type=oneshot services may use ExecReload= and do the
+          right thing.
+
+        * The journal daemon now supports time-based rotation and
+          vacuuming, in addition to the usual disk-space based
+          rotation.
+
+        * The journal will now index the available field values for
+          each field name. This enables clients to show pretty drop
+          downs of available match values when filtering. The bash
+          completion of journalctl has been updated
+          accordingly. journalctl gained a new switch -F to list all
+          values a certain field takes in the journal database.
+
+        * More service events are now written as structured messages
+          to the journal, and made recognizable via message IDs.
+
+        * The timedated, localed and hostnamed mini-services which
+          previously only provided support for changing time, locale
+          and hostname settings from graphical DEs such as GNOME now
+          also have a minimal (but very useful) text-based client
+          utility each. This is probably the nicest way to changing
+          these settings from the command line now, especially since
+          it lists available options and is fully integrated with bash
+          completion.
+
+        * There's now a new tool "systemd-coredumpctl" to list and
+          extract coredumps from the journal.
+
+        * We now install a README each in /var/log/ and
+          /etc/rc.d/init.d explaining where the system logs and init
+          scripts went. This hopefully should help folks who go to
+          that dirs and look into the otherwise now empty void and
+          scratch their heads.
+
+        * When user-services are invoked (by systemd --user) the
+          $MANAGERPID env var is set to the PID of systemd.
+
+        * SIGRTMIN+24 when sent to a --user instance will now result
+          in immediate termination of systemd.
+
+        * gatewayd received numerous feature additions such as a
+          "follow" mode, for live syncing and filtering.
+
+        * browse.html now allows filtering and showing detailed
+          information on specific entries. Keyboard navigation and
+          mouse screen support has been added.
+
+        * gatewayd/journalctl now supports HTML5/JSON
+          Server-Sent-Events as output.
+
+        * The SysV init script compatibility logic will now
+          heuristically determine whether a script supports the
+          "reload" verb, and only then make this available as
+          "systemctl reload".
+
+        * "systemctl status --follow" has been removed, use "journalctl
+          -u" instead.
+
+        * journald.conf's RuntimeMinSize=, PersistentMinSize= settings
+          have been removed since they are hardly useful to be
+          configured.
+
+        * And I'd like to take the opportunity to specifically mention
+          Zbigniew for his great contributions. Zbigniew, you rock!
+
+        Contributions from: Andrew Eikum, Christian Hesse, Colin
+        Guthrie, Daniel J Walsh, Dave Reisner, Eelco Dolstra, Ferenc
+        Wágner, Kay Sievers, Lennart Poettering, Lukas Nykryn, Mantas
+        Mikulėnas, Martin Mikkelsen, Martin Pitt, Michael Olbrich,
+        Michael Stapelberg, Michal Schmidt, Sebastian Ott, Thomas
+        Bächler, Umut Tezduyar, Will Woods, Wulf C. Krueger, Zbigniew
+        Jędrzejewski-Szmek, Сковорода Никита Андреевич
+
+CHANGES WITH 194:
+
+        * If /etc/vconsole.conf is non-existent or empty we will no
+          longer load any console font or key map at boot by
+          default. Instead the kernel defaults will be left
+          intact. This is definitely the right thing to do, as no
+          configuration should mean no configuration, and hard-coding
+          font names that are different on all archs is probably a bad
+          idea. Also, the kernel default key map and font should be
+          good enough for most cases anyway, and mostly identical to
+          the userspace fonts/key maps we previously overloaded them
+          with. If distributions want to continue to default to a
+          non-kernel font or key map they should ship a default
+          /etc/vconsole.conf with the appropriate contents.
+
+        Contributions from: Colin Walters, Daniel J Walsh, Dave
+        Reisner, Kay Sievers, Lennart Poettering, Lukas Nykryn, Tollef
+        Fog Heen, Tom Gundersen, Zbigniew Jędrzejewski-Szmek
+
+CHANGES WITH 193:
+
+        * journalctl gained a new --cursor= switch to show entries
+          starting from the specified location in the journal.
+
+        * We now enforce a size limit on journal entry fields exported
+          with "-o json" in journalctl. Fields larger than 4K will be
+          assigned null. This can be turned off with --all.
+
+        * An (optional) journal gateway daemon is now available as
+          "systemd-journal-gatewayd.service". This service provides
+          access to the journal via HTTP and JSON. This functionality
+          will be used to implement live log synchronization in both
+          pull and push modes, but has various other users too, such
+          as easy log access for debugging of embedded devices. Right
+          now it is already useful to retrieve the journal via HTTP:
+
+          # systemctl start systemd-journal-gatewayd.service
+          # wget http://localhost:19531/entries
+
+          This will download the journal contents in a
+          /var/log/messages compatible format. The same as JSON:
+
+          # curl -H"Accept: application/json" http://localhost:19531/entries
+
+          This service is also accessible via a web browser where a
+          single static HTML5 app is served that uses the JSON logic
+          to enable the user to do some basic browsing of the
+          journal. This will be extended later on. Here's an example
+          screenshot of this app in its current state:
+
+          http://0pointer.de/public/journal-gatewayd
+
+        Contributions from: Kay Sievers, Lennart Poettering, Robert
+        Milasan, Tom Gundersen
+
+CHANGES WITH 192:
+
+        * The bash completion logic is now available for journalctl
+          too.
+
+        * We don't mount the "cpuset" controller anymore together with
+          "cpu" and "cpuacct", as "cpuset" groups generally cannot be
+          started if no parameters are assigned to it. "cpuset" hence
+          broke code that assumed it it could create "cpu" groups and
+          just start them.
+
+        * journalctl -f will now subscribe to terminal size changes,
+          and line break accordingly.
+
+        Contributions from: Dave Reisner, Kay Sievers, Lennart
+        Poettering, Lukas Nykrynm, Mirco Tischler, Václav Pavlín
+
+CHANGES WITH 191:
+
+        * nspawn will now create a symlink /etc/localtime in the
+          container environment, copying the host's timezone
+          setting. Previously this has been done via a bind mount, but
+          since symlinks cannot be bind mounted this has now been
+          changed to create/update the appropriate symlink.
+
+        * journalctl -n's line number argument is now optional, and
+          will default to 10 if omitted.
+
+        * journald will now log the maximum size the journal files may
+          take up on disk. This is particularly useful if the default
+          built-in logic of determining this parameter from the file
+          system size is used. Use "systemctl status
+          systemd-journald.service" to see this information.
+
+        * The multi-seat X wrapper tool has been stripped down. As X
+          is now capable of enumerating graphics devices via udev in a
+          seat-aware way the wrapper is not strictly necessary
+          anymore. A stripped down temporary stop-gap is still shipped
+          until the upstream display managers have been updated to
+          fully support the new X logic. Expect this wrapper to be
+          removed entirely in one of the next releases.
+
+        * HandleSleepKey= in logind.conf has been split up into
+          HandleSuspendKey= and HandleHibernateKey=. The old setting
+          is not available anymore. X11 and the kernel are
+          distuingishing between these keys and we should too. This
+          also means the inhibition lock for these keys has been split
+          into two.
+
+        Contributions from: Dave Airlie, Eelco Dolstra, Lennart
+        Poettering, Lukas Nykryn, Václav Pavlín
+
+CHANGES WITH 190:
+
+        * Whenever a unit changes state we'll now log this to the
+          journal and show along the unit's own log output in
+          "systemctl status".
+
+        * ConditionPathIsMountPoint= can now properly detect bind
+          mount points too. (Previously, a bind mount of one file
+          system to another place in the same file system could not be
+          detected as mount, since they shared struct stat's st_dev
+          field.)
+
+        * We will now mount the cgroup controllers cpu, cpuacct,
+          cpuset and the controllers net_cls, net_prio together by
+          default.
+
+        * nspawn containers will now have a virtualized boot
+          ID. (i.e. /proc/sys/kernel/random/boot_id is now mounted
+          over with a randomized ID at container initialization). This
+          has the effect of making "journalctl -b" do the right thing
+          in a container.
+
+        * The JSON output journal serialization has been updated not
+          to generate "endless" list objects anymore, but rather one
+          JSON object per line. This is more in line how most JSON
+          parsers expect JSON objects. The new output mode
+          "json-pretty" has been added to provide similar output, but
+          neatly aligned for readability by humans.
+
+        * We dropped all explicit sync() invocations in the shutdown
+          code. The kernel does this implicitly anyway in the kernel
+          reboot() syscall. halt(8)'s -n option is now a compatibility
+          no-op.
+
+        * We now support virtualized reboot() in containers, as
+          supported by newer kernels. We will fall back to exit() if
+          CAP_SYS_REBOOT is not available to the container. Also,
+          nspawn makes use of this now and will actually reboot the
+          container if the containerized OS asks for that.
+
+        * journalctl will only show local log output by default
+          now. Use --merge (-m) to show remote log output, too.
+
+        * libsystemd-journal gained the new sd_journal_get_usage()
+          call to determine the current disk usage of all journal
+          files. This is exposed in the new "journalctl --disk-usage"
+          command.
+
+        * journald gained a new configuration setting SplitMode= in
+          journald.conf which may be used to control how user journals
+          are split off. See journald.conf(5) for details.
+
+        * A new condition type ConditionFileNotEmpty= has been added.
+
+        * tmpfiles' "w" lines now support file globbing, to write
+          multiple files at once.
+
+        * We added Python bindings for the journal submission
+          APIs. More Python APIs for a number of selected APIs will
+          likely follow. Note that we intend to add native bindings
+          only for the Python language, as we consider it common
+          enough to deserve bindings shipped within systemd. There are
+          various projects outside of systemd that provide bindings
+          for languages such as PHP or Lua.
+
+        * Many conditions will now resolve specifiers such as %i. In
+          addition, PathChanged= and related directives of .path units
+          now support specifiers as well.
+
+        * There's now a new RPM macro definition for the system preset
+          dir: %_presetdir.
+
+        * journald will now warn if it can't foward a message to the
+          syslog daemon because it's socket is full.
+
+        * timedated will no longer write or process /etc/timezone,
+          except on Debian. As we do not support late mounted /usr
+          anymore /etc/localtime always being a symlink is now safe,
+          and hence the information in /etc/timezone is not necessary
+          anymore.
+
+        * logind will now always reserve one VT for a text getty (VT6
+          by default). Previously if more than 6 X sessions where
+          started they took up all the VTs with auto-spawned gettys,
+          so that no text gettys were available anymore.
+
+        * udev will now automatically inform the btrfs kernel logic
+          about btrfs RAID components showing up. This should make
+          simple hotplug based btrfs RAID assembly work.
+
+        * PID 1 will now increase its RLIMIT_NOFILE to 64K by default
+          (but not for its children which will stay at the kernel
+          default). This should allow setups with a lot more listening
+          sockets.
+
+        * systemd will now always pass the configured timezone to the
+          kernel at boot. timedated will do the same when the timezone
+          is changed.
+
+        * logind's inhibition logic has been updated. By default,
+          logind will now handle the lid switch, the power and sleep
+          keys all the time, even in graphical sessions. If DEs want
+          to handle these events on their own they should take the new
+          handle-power-key, handle-sleep-key and handle-lid-switch
+          inhibitors during their runtime. A simple way to achiveve
+          that is to invoke the DE wrapped in an invocation of:
+
+          systemd-inhibit --what=handle-power-key:handle-sleep-key:handle-lid-switch ...
+
+        * Access to unit operations is now checked via SELinux taking
+          the unit file label and client process label into account.
+
+        * systemd will now notify the administrator in the journal
+          when he over-mounts a non-empty directory.
+
+        * There are new specifiers that are resolved in unit files,
+          for the host name (%H), the machine ID (%m) and the boot ID
+          (%b).
+
+        Contributions from: Allin Cottrell, Auke Kok, Brandon Philips,
+        Colin Guthrie, Colin Walters, Daniel J Walsh, Dave Reisner,
+        Eelco Dolstra, Jan Engelhardt, Kay Sievers, Lennart
+        Poettering, Lucas De Marchi, Lukas Nykryn, Mantas Mikulėnas,
+        Martin Pitt, Matthias Clasen, Michael Olbrich, Pierre Schmitz,
+        Shawn Landden, Thomas Hindoe Paaboel Andersen, Tom Gundersen,
+        Václav Pavlín, Yin Kangkai, Zbigniew Jędrzejewski-Szmek
+
+CHANGES WITH 189:
+
+        * Support for reading structured kernel messages from
+          /dev/kmsg has now been added and is enabled by default.
+
+        * Support for reading kernel messages from /proc/kmsg has now
+          been removed. If you want kernel messages in the journal
+          make sure to run a recent kernel (>= 3.5) that supports
+          reading structured messages from /dev/kmsg (see
+          above). /proc/kmsg is now exclusive property of classic
+          syslog daemons again.
+
+        * The libudev API gained the new
+          udev_device_new_from_device_id() call.
+
+        * The logic for file system namespace (ReadOnlyDirectory=,
+          ReadWriteDirectoy=, PrivateTmp=) has been reworked not to
+          require pivot_root() anymore. This means fewer temporary
+          directories are created below /tmp for this feature.
+
+        * nspawn containers will now see and receive all submounts
+          made on the host OS below the root file system of the
+          container.
+
+        * Forward Secure Sealing is now supported for Journal files,
+          which provide cryptographical sealing of journal files so
+          that attackers cannot alter log history anymore without this
+          being detectable. Lennart will soon post a blog story about
+          this explaining it in more detail.
+
+        * There are two new service settings RestartPreventExitStatus=
+          and SuccessExitStatus= which allow configuration of exit
+          status (exit code or signal) which will be excepted from the
+          restart logic, resp. consider successful.
+
+        * journalctl gained the new --verify switch that can be used
+          to check the integrity of the structure of journal files and
+          (if Forward Secure Sealing is enabled) the contents of
+          journal files.
+
+        * nspawn containers will now be run with /dev/stdin, /dev/fd/
+          and similar symlinks pre-created. This makes running shells
+          as container init process a lot more fun.
+
+        * The fstab support can now handle PARTUUID= and PARTLABEL=
+          entries.
+
+        * A new ConditionHost= condition has been added to match
+          against the hostname (with globs) and machine ID. This is
+          useful for clusters where a single OS image is used to
+          provision a large number of hosts which shall run slightly
+          different sets of services.
+
+        * Services which hit the restart limit will now be placed in a
+          failure state.
+
+        Contributions from: Bertram Poettering, Dave Reisner, Huang
+        Hang, Kay Sievers, Lennart Poettering, Lukas Nykryn, Martin
+        Pitt, Simon Peeters, Zbigniew Jędrzejewski-Szmek
+
+CHANGES WITH 188:
+
+        * When running in --user mode systemd will now become a
+          subreaper (PR_SET_CHILD_SUBREAPER). This should make the ps
+          tree a lot more organized.
+
+        * A new PartOf= unit dependency type has been introduced that
+          may be used to group services in a natural way.
+
+        * "systemctl enable" may now be used to enable instances of
+          services.
+
+        * journalctl now prints error log levels in red, and
+          warning/notice log levels in bright white. It also supports
+          filtering by log level now.
+
+        * cgtop gained a new -n switch (similar to top), to configure
+          the maximum number of iterations to run for. It also gained
+          -b, to run in batch mode (accepting no input).
+
+        * The suffix ".service" may now be ommited on most systemctl
+          command lines involving service unit names.
+
+        * There's a new bus call in logind to lock all sessions, as
+          well as a loginctl verb for it "lock-sessions".
+
+        * libsystemd-logind.so gained a new call sd_journal_perror()
+          that works similar to libc perror() but logs to the journal
+          and encodes structured information about the error number.
+
+        * /etc/crypttab entries now understand the new keyfile-size=
+          option.
+
+        * shutdown(8) now can send a (configurable) wall message when
+          a shutdown is cancelled.
+
+        * The mount propagation mode for the root file system will now
+          default to "shared", which is useful to make containers work
+          nicely out-of-the-box so that they receive new mounts from
+          the host. This can be undone locally by running "mount
+          --make-rprivate /" if needed.
+
+        * The prefdm.service file has been removed. Distributions
+          should maintain this unit downstream if they intend to keep
+          it around. However, we recommend writing normal unit files
+          for display managers instead.
+
+        * Since systemd is a crucial part of the OS we will now
+          default to a number of compiler switches that improve
+          security (hardening) such as read-only relocations, stack
+          protection, and suchlike.
+
+        * The TimeoutSec= setting for services is now split into
+          TimeoutStartSec= and TimeoutStopSec= to allow configuration
+          of individual time outs for the start and the stop phase of
+          the service.
+
+        Contributions from: Artur Zaprzala, Arvydas Sidorenko, Auke
+        Kok, Bryan Kadzban, Dave Reisner, David Strauss, Harald Hoyer,
+        Jim Meyering, Kay Sievers, Lennart Poettering, Mantas
+        Mikulėnas, Martin Pitt, Michal Schmidt, Michal Sekletar, Peter
+        Alfredsen, Shawn Landden, Simon Peeters, Terence Honles, Tom
+        Gundersen, Zbigniew Jędrzejewski-Szmek
+
+CHANGES WITH 187:
+
+        * The journal and id128 C APIs are now fully documented as man
+          pages.
+
+        * Extra safety checks have been added when transitioning from
+          the initial RAM disk to the main system to avoid accidental
+          data loss.
+
+        * /etc/crypttab entries now understand the new keyfile-offset=
+          option.
+
+        * systemctl -t can now be used to filter by unit load state.
+
+        * The journal C API gained the new sd_journal_wait() call to
+          make writing synchronous journal clients easier.
+
+        * journalctl gained the new -D switch to show journals from a
+          specific directory.
+
+        * journalctl now displays a special marker between log
+          messages of two different boots.
+
+        * The journal is now explicitly flushed to /var via a service
+          systemd-journal-flush.service, rather than implicitly simply
+          by seeing /var/log/journal to be writable.
+
+        * journalctl (and the journal C APIs) can now match for much
+          more complex expressions, with alternatives and
+          disjunctions.
+
+        * When transitioning from the initial RAM disk to the main
+          system we will now kill all processes in a killing spree to
+          ensure no processes stay around by accident.
+
+        * Three new specifiers may be used in unit files: %u, %h, %s
+          resolve to the user name, user home directory resp. user
+          shell. This is useful for running systemd user instances.
+
+        * We now automatically rotate journal files if their data
+          object hash table gets a fill level > 75%. We also size the
+          hash table based on the configured maximum file size. This
+          together should lower hash collisions drastically and thus
+          speed things up a bit.
+
+        * journalctl gained the new "--header" switch to introspect
+          header data of journal files.
+
+        * A new setting SystemCallFilters= has been added to services
+          which may be used to apply blacklists or whitelists to
+          system calls. This is based on SECCOMP Mode 2 of Linux 3.5.
+
+        * nspawn gained a new --link-journal= switch (and quicker: -j)
+          to link the container journal with the host. This makes it
+          very easy to centralize log viewing on the host for all
+          guests while still keeping the journal files separated.
+
+        * Many bugfixes and optimizations
+
+        Contributions from: Auke Kok, Eelco Dolstra, Harald Hoyer, Kay
+        Sievers, Lennart Poettering, Malte Starostik, Paul Menzel, Rex
+        Tsai, Shawn Landden, Tom Gundersen, Ville Skyttä, Zbigniew
+        Jędrzejewski-Szmek
+
+CHANGES WITH 186:
+
+        * Several tools now understand kernel command line arguments,
+          which are only read when run in an initial RAM disk. They
+          usually follow closely their normal counterparts, but are
+          prefixed with rd.
+
+        * There's a new tool to analyze the readahead files that are
+          automatically generated at boot. Use:
+
+          /usr/lib/systemd/systemd-readahead analyze /.readahead
+
+        * We now provide an early debug shell on tty9 if this enabled. Use:
+
+          systemctl enable debug-shell.service
+
+        * All plymouth related units have been moved into the Plymouth
+          package. Please make sure to upgrade your Plymouth version
+          as well.
+
+        * systemd-tmpfiles now supports getting passed the basename of
+          a configuration file only, in which case it will look for it
+          in all appropriate directories automatically.
+
+        * udevadm info now takes a /dev or /sys path as argument, and
+          does the right thing. Example:
+
+          udevadm info /dev/sda
+          udevadm info /sys/class/block/sda
+
+        * systemctl now prints a warning if a unit is stopped but a
+          unit that might trigger it continues to run. Example: a
+          service is stopped but the socket that activates it is left
+          running.
+
+        * "systemctl status" will now mention if the log output was
+          shortened due to rotation since a service has been started.
+
+        * The journal API now exposes functions to determine the
+          "cutoff" times due to rotation.
+
+        * journald now understands SIGUSR1 and SIGUSR2 for triggering
+          immediately flushing of runtime logs to /var if possible,
+          resp. for triggering immediate rotation of the journal
+          files.
+
+        * It is now considered an error if a service is attempted to
+          be stopped that is not loaded.
+
+        * XDG_RUNTIME_DIR now uses numeric UIDs instead of usernames.
+
+        * systemd-analyze now supports Python 3
+
+        * tmpfiles now supports cleaning up directories via aging
+          where the first level dirs are always kept around but
+          directories beneath it automatically aged. This is enabled
+          by prefixing the age field with '~'.
+
+        * Seat objects now expose CanGraphical, CanTTY properties
+          which is required to deal with very fast bootups where the
+          display manager might be running before the graphics drivers
+          completed initialization.
+
+        * Seat objects now expose a State property.
+
+        * We now include RPM macros for service enabling/disabling
+          based on the preset logic. We recommend RPM based
+          distributions to make use of these macros if possible. This
+          makes it simpler to reuse RPM spec files across
+          distributions.
+
+        * We now make sure that the collected systemd unit name is
+          always valid when services log to the journal via
+          STDOUT/STDERR.
+
+        * There's a new man page kernel-command-line(7) detailing all
+          command line options we understand.
+
+        * The fstab generator may now be disabled at boot by passing
+          fstab=0 on the kernel command line.
+
+        * A new kernel command line option modules-load= is now understood
+          to load a specific kernel module statically, early at boot.
+
+        * Unit names specified on the systemctl command line are now
+          automatically escaped as needed. Also, if file system or
+          device paths are specified they are automatically turned
+          into the appropriate mount or device unit names. Example:
+
+          systemctl status /home
+          systemctl status /dev/sda
+
+        * The SysVConsole= configuration option has been removed from
+          system.conf parsing.
+
+        * The SysV search path is no longer exported on the D-Bus
+          Manager object.
+
+        * The Names= option is been removed from unit file parsing.
+
+        * There's a new man page bootup(7) detailing the boot process.
+
+        * Every unit and every generator we ship with systemd now
+          comes with full documentation. The self-explanatory boot is
+          complete.
+
+        * A couple of services gained "systemd-" prefixes in their
+          name if they wrap systemd code, rather than only external
+          code. Among them fsck@.service which is now
+          systemd-fsck@.service.
+
+        * The HaveWatchdog property has been removed from the D-Bus
+          Manager object.
+
+        * systemd.confirm_spawn= on the kernel command line should now
+          work sensibly.
+
+        * There's a new man page crypttab(5) which details all options
+          we actually understand.
+
+        * systemd-nspawn gained a new --capability= switch to pass
+          additional capabilities to the container.
+
+        * timedated will now read known NTP implementation unit names
+          from /usr/lib/systemd/ntp-units.d/*.list,
+          systemd-timedated-ntp.target has been removed.
+
+        * journalctl gained a new switch "-b" that lists log data of
+          the current boot only.
+
+        * The notify socket is in the abstract namespace again, in
+          order to support daemons which chroot() at start-up.
+
+        * There is a new Storage= configuration option for journald
+          which allows configuration of where log data should go. This
+          also provides a way to disable journal logging entirely, so
+          that data collected is only forwarded to the console, the
+          kernel log buffer or another syslog implementation.
+
+        * Many bugfixes and optimizations
+
+        Contributions from: Auke Kok, Colin Guthrie, Dave Reisner,
+        David Strauss, Eelco Dolstra, Kay Sievers, Lennart Poettering,
+        Lukas Nykryn, Michal Schmidt, Michal Sekletar, Paul Menzel,
+        Shawn Landden, Tom Gundersen
+
+CHANGES WITH 185:
+
+        * "systemctl help <unit>" now shows the man page if one is
+          available.
+
+        * Several new man pages have been added.
+
+        * MaxLevelStore=, MaxLevelSyslog=, MaxLevelKMsg=,
+          MaxLevelConsole= can now be specified in
+          journald.conf. These options allow reducing the amount of
+          data stored on disk or forwarded by the log level.
+
+        * TimerSlackNSec= can now be specified in system.conf for
+          PID1. This allows system-wide power savings.
+
+        Contributions from: Dave Reisner, Kay Sievers, Lauri Kasanen,
+        Lennart Poettering, Malte Starostik, Marc-Antoine Perennou,
+        Matthias Clasen
+
+CHANGES WITH 184:
+
+        * logind is now capable of (optionally) handling power and
+          sleep keys as well as the lid switch.
+
+        * journalctl now understands the syntax "journalctl
+          /usr/bin/avahi-daemon" to get all log output of a specific
+          daemon.
+
+        * CapabilityBoundingSet= in system.conf now also influences
+          the capability bound set of usermode helpers of the kernel.
+
+        Contributions from: Daniel Drake, Daniel J. Walsh, Gert
+        Michael Kulyk, Harald Hoyer, Jean Delvare, Kay Sievers,
+        Lennart Poettering, Matthew Garrett, Matthias Clasen, Paul
+        Menzel, Shawn Landden, Tero Roponen, Tom Gundersen
+
+CHANGES WITH 183:
+
+        * Note that we skipped 139 releases here in order to set the
+          new version to something that is greater than both udev's
+          and systemd's most recent version number.
+
+        * udev: all udev sources are merged into the systemd source tree now.
+          All future udev development will happen in the systemd tree. It
+          is still fully supported to use the udev daemon and tools without
+          systemd running, like in initramfs or other init systems. Building
+          udev though, will require the *build* of the systemd tree, but
+          udev can be properly *run* without systemd.
+
+        * udev: /lib/udev/devices/ are not read anymore; systemd-tmpfiles
+          should be used to create dead device nodes as workarounds for broken
+          subsystems.
+
+        * udev: RUN+="socket:..."  and udev_monitor_new_from_socket() is
+          no longer supported. udev_monitor_new_from_netlink() needs to be
+          used to subscribe to events.
+
+        * udev: when udevd is started by systemd, processes which are left
+          behind by forking them off of udev rules, are unconditionally cleaned
+          up and killed now after the event handling has finished. Services or
+          daemons must be started as systemd services. Services can be
+          pulled-in by udev to get started, but they can no longer be directly
+          forked by udev rules.
+
+        * udev: the daemon binary is called systemd-udevd now and installed
+          in /usr/lib/systemd/. Standalone builds or non-systemd systems need
+          to adapt to that, create symlink, or rename the binary after building
+          it.
+
+        * libudev no longer provides these symbols:
+            udev_monitor_from_socket()
+            udev_queue_get_failed_list_entry()
+            udev_get_{dev,sys,run}_path()
+          The versions number was bumped and symbol versioning introduced.
+
+        * systemd-loginctl and systemd-journalctl have been renamed
+          to loginctl and journalctl to match systemctl.
+
+        * The config files: /etc/systemd/systemd-logind.conf and
+          /etc/systemd/systemd-journald.conf have been renamed to
+          logind.conf and journald.conf. Package updates should rename
+          the files to the new names on upgrade.
+
+        * For almost all files the license is now LGPL2.1+, changed
+          from the previous GPL2.0+. Exceptions are some minor stuff
+          of udev (which will be changed to LGPL2.1 eventually, too),
+          and the MIT licensed sd-daemon.[ch] library that is suitable
+          to be used as drop-in files.
+
+        * systemd and logind now handle system sleep states, in
+          particular suspending and hibernating.
+
+        * logind now implements a sleep/shutdown/idle inhibiting logic
+          suitable for a variety of uses. Soonishly Lennart will blog
+          about this in more detail.
+
+        * var-run.mount and var-lock.mount are no longer provided
+          (which prevously bind mounted these directories to their new
+          places). Distributions which have not converted these
+          directories to symlinks should consider stealing these files
+          from git history and add them downstream.
+
+        * We introduced the Documentation= field for units and added
+          this to all our shipped units. This is useful to make it
+          easier to explore the boot and the purpose of the various
+          units.
+
+        * All smaller setup units (such as
+          systemd-vconsole-setup.service) now detect properly if they
+          are run in a container and are skipped when
+          appropriate. This guarantees an entirely noise-free boot in
+          Linux container environments such as systemd-nspawn.
+
+        * A framework for implementing offline system updates is now
+          integrated, for details see:
+          http://freedesktop.org/wiki/Software/systemd/SystemUpdates
+
+        * A new service type Type=idle is available now which helps us
+          avoiding ugly interleaving of getty output and boot status
+          messages.
+
+        * There's now a system-wide CapabilityBoundingSet= option to
+          globally reduce the set of capabilities for the
+          system. This is useful to drop CAP_SYS_MKNOD, CAP_SYS_RAWIO,
+          CAP_NET_RAW, CAP_SYS_MODULE, CAP_SYS_TIME, CAP_SYS_PTRACE or
+          even CAP_NET_ADMIN system-wide for secure systems.
+
+        * There are now system-wide DefaultLimitXXX= options to
+          globally change the defaults of the various resource limits
+          for all units started by PID 1.
+
+        * Harald Hoyer's systemd test suite has been integrated into
+          systemd which allows easy testing of systemd builds in qemu
+          and nspawn. (This is really awesome! Ask us for details!)
+
+        * The fstab parser is now implemented as generator, not inside
+          of PID 1 anymore.
+
+        * systemctl will now warn you if .mount units generated from
+          /etc/fstab are out of date due to changes in fstab that
+          haven't been read by systemd yet.
+
+        * systemd is now suitable for usage in initrds. Dracut has
+          already been updated to make use of this. With this in place
+          initrds get a slight bit faster but primarily are much
+          easier to introspect and debug since "systemctl status" in
+          the host system can be used to introspect initrd services,
+          and the journal from the initrd is kept around too.
+
+        * systemd-delta has been added, a tool to explore differences
+          between user/admin configuration and vendor defaults.
+
+        * PrivateTmp= now affects both /tmp and /var/tmp.
+
+        * Boot time status messages are now much prettier and feature
+          proper english language. Booting up systemd has never been
+          so sexy.
+
+        * Read-ahead pack files now include the inode number of all
+          files to pre-cache. When the inode changes the pre-caching
+          is not attempted. This should be nicer to deal with updated
+          packages which might result in changes of read-ahead
+          patterns.
+
+        * We now temporaritly lower the kernel's read_ahead_kb variable
+          when collecting read-ahead data to ensure the kernel's
+          built-in read-ahead does not add noise to our measurements
+          of necessary blocks to pre-cache.
+
+        * There's now RequiresMountsFor= to add automatic dependencies
+          for all mounts necessary for a specific file system path.
+
+        * MountAuto= and SwapAuto= have been removed from
+          system.conf. Mounting file systems at boot has to take place
+          in systemd now.
+
+        * nspawn now learned a new switch --uuid= to set the machine
+          ID on the command line.
+
+        * nspawn now learned the -b switch to automatically search
+          for an init system.
+
+        * vt102 is now the default TERM for serial TTYs, upgraded from
+          vt100.
+
+        * systemd-logind now works on VT-less systems.
+
+        * The build tree has been reorganized. The individual
+          components now have directories of their own.
+
+        * A new condition type ConditionPathIsReadWrite= is now available.
+
+        * nspawn learned the new -C switch to create cgroups for the
+          container in other hierarchies.
+
+        * We now have support for hardware watchdogs, configurable in
+          system.conf.
+
+        * The scheduled shutdown logic now has a public API.
+
+        * We now mount /tmp as tmpfs by default, but this can be
+          masked and /etc/fstab can override it.
+
+        * Since udisks doesn't make use of /media anymore we are not
+          mounting a tmpfs on it anymore.
+
+        * journalctl gained a new --local switch to only interleave
+          locally generated journal files.
+
+        * We can now load the IMA policy at boot automatically.
+
+        * The GTK tools have been split off into a systemd-ui.
+
+        Contributions from: Andreas Schwab, Auke Kok, Ayan George,
+        Colin Guthrie, Daniel Mack, Dave Reisner, David Ward, Elan
+        Ruusamäe, Frederic Crozat, Gergely Nagy, Guillermo Vidal,
+        Hannes Reinecke, Harald Hoyer, Javier Jardón, Kay Sievers,
+        Lennart Poettering, Lucas De Marchi, Léo Gillot-Lamure,
+        Marc-Antoine Perennou, Martin Pitt, Matthew Monaco, Maxim
+        A. Mikityanskiy, Michael Biebl, Michael Olbrich, Michal
+        Schmidt, Nis Martensen, Patrick McCarty, Roberto Sassu, Shawn
+        Landden, Sjoerd Simons, Sven Anders, Tollef Fog Heen, Tom
+        Gundersen
+
+CHANGES WITH 44:
+
+        * This is mostly a bugfix release
+
+        * Support optional initialization of the machine ID from the
+          KVM or container configured UUID.
+
+        * Support immediate reboots with "systemctl reboot -ff"
+
+        * Show /etc/os-release data in systemd-analyze output
+
+        * Many bugfixes for the journal, including endianess fixes and
+          ensuring that disk space enforcement works
+
+        * sd-login.h is C++ comptaible again
+
+        * Extend the /etc/os-release format on request of the Debian
+          folks
+
+        * We now refuse non-UTF8 strings used in various configuration
+          and unit files. This is done to ensure we don't pass invalid
+          data over D-Bus or expose it elsewhere.
+
+        * Register Mimo USB Screens as suitable for automatic seat
+          configuration
+
+        * Read SELinux client context from journal clients in a race
+          free fashion
+
+        * Reorder configuration file lookup order. /etc now always
+          overrides /run in order to allow the administrator to always
+          and unconditionally override vendor supplied or
+          automatically generated data.
+
+        * The various user visible bits of the journal now have man
+          pages. We still lack man pages for the journal API calls
+          however.
+
+        * We now ship all man pages in HTML format again in the
+          tarball.
+
+        Contributions from: Dave Reisner, Dirk Eibach, Frederic
+        Crozat, Harald Hoyer, Kay Sievers, Lennart Poettering, Marti
+        Raudsepp, Michal Schmidt, Shawn Landden, Tero Roponen, Thierry
+        Reding
+
+CHANGES WITH 43:
+
+        * This is mostly a bugfix release
+
+        * systems lacking /etc/os-release  are no longer supported.
+
+        * Various functionality updates to libsystemd-login.so
+
+        * Track class of PAM logins to distuingish greeters from
+          normal user logins.
+
+        Contributions from: Kay Sievers, Lennart Poettering, Michael
+        Biebl
+
+CHANGES WITH 42:
+
+        * This is an important bugfix release for v41.
+
+        * Building man pages is now optional which should be useful
+          for those building systemd from git but unwilling to install
+          xsltproc.
+
+        * Watchdog support for supervising services is now usable. In
+          a future release support for hardware watchdogs
+          (i.e. /dev/watchdog) will be added building on this.
+
+        * Service start rate limiting is now configurable and can be
+          turned off per service. When a start rate limit is hit a
+          reboot can automatically be triggered.
+
+        * New CanReboot(), CanPowerOff() bus calls in systemd-logind.
+
+        Contributions from: Benjamin Franzke, Bill Nottingham,
+        Frederic Crozat, Lennart Poettering, Michael Olbrich, Michal
+        Schmidt, Michał Górny, Piotr Drąg
+
+CHANGES WITH 41:
+
+        * The systemd binary is installed /usr/lib/systemd/systemd now;
+          An existing /sbin/init symlink needs to be adapted with the
+          package update.
+
+        * The code that loads kernel modules has been ported to invoke
+          libkmod directly, instead of modprobe. This means we do not
+          support systems with module-init-tools anymore.
+
+        * Watchdog support is now already useful, but still not
+          complete.
+
+        * A new kernel command line option systemd.setenv= is
+          understood to set system wide environment variables
+          dynamically at boot.
+
+       * We now limit the set of capabilities of systemd-journald.
+
+        * We now set SIGPIPE to ignore by default, since it only is
+          useful in shell pipelines, and has little use in general
+          code. This can be disabled with IgnoreSIPIPE=no in unit
+          files.
+
+        Contributions from: Benjamin Franzke, Kay Sievers, Lennart
+        Poettering, Michael Olbrich, Michal Schmidt, Tom Gundersen,
+        William Douglas
+
+CHANGES WITH 40:
+
+        * This is mostly a bugfix release
+
+        * We now expose the reason why a service failed in the
+          "Result" D-Bus property.
+
+        * Rudimentary service watchdog support (will be completed over
+          the next few releases.)
+
+        * When systemd forks off in order execute some service we will
+          now immediately changes its argv[0] to reflect which process
+          it will execute. This is useful to minimize the time window
+          with a generic argv[0], which makes bootcharts more useful
+
+        Contributions from: Alvaro Soliverez, Chris Paulson-Ellis, Kay
+        Sievers, Lennart Poettering, Michael Olbrich, Michal Schmidt,
+        Mike Kazantsev, Ray Strode
+
+CHANGES WITH 39:
+
+        * This is mostly a test release, but incorporates many
+          bugfixes.
+
+        * New systemd-cgtop tool to show control groups by their
+          resource usage.
+
+        * Linking against libacl for ACLs is optional again. If
+          disabled, support tracking device access for active logins
+          goes becomes unavailable, and so does access to the user
+          journals by the respective users.
+
+        * If a group "adm" exists, journal files are automatically
+          owned by them, thus allow members of this group full access
+          to the system journal as well as all user journals.
+
+        * The journal now stores the SELinux context of the logging
+          client for all entries.
+
+        * Add C++ inclusion guards to all public headers
+
+        * New output mode "cat" in the journal to print only text
+          messages, without any meta data like date or time.
+
+        * Include tiny X server wrapper as a temporary stop-gap to
+          teach XOrg udev display enumeration. This is used by display
+          managers such as gdm, and will go away as soon as XOrg
+          learned native udev hotplugging for display devices.
+
+        * Add new systemd-cat tool for executing arbitrary programs
+          with STDERR/STDOUT connected to the journal. Can also act as
+          BSD logger replacement, and does so by default.
+
+        * Optionally store all locally generated coredumps in the
+          journal along with meta data.
+
+        * systemd-tmpfiles learnt four new commands: n, L, c, b, for
+          writing short strings to files (for usage for /sys), and for
+          creating symlinks, character and block device nodes.
+
+        * New unit file option ControlGroupPersistent= to make cgroups
+          persistent, following the mechanisms outlined in
+          http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups
+
+        * Support multiple local RTCs in a sane way
+
+        * No longer monopolize IO when replaying readahead data on
+          rotating disks, since we might starve non-file-system IO to
+          death, since fanotify() will not see accesses done by blkid,
+          or fsck.
+
+        * Don't show kernel threads in systemd-cgls anymore, unless
+          requested with new -k switch.
+
+        Contributions from: Dan Horák, Kay Sievers, Lennart
+        Poettering, Michal Schmidt
+
+CHANGES WITH 38:
+
+        * This is mostly a test release, but incorporates many
+          bugfixes.
+
+        * The git repository moved to:
+          git://anongit.freedesktop.org/systemd/systemd
+          ssh://git.freedesktop.org/git/systemd/systemd
+
+        * First release with the journal
+          http://0pointer.de/blog/projects/the-journal.html
+
+        * The journal replaces both systemd-kmsg-syslogd and
+          systemd-stdout-bridge.
+
+        * New sd_pid_get_unit() API call in libsystemd-logind
+
+        * Many systemadm clean-ups
+
+        * Introduce remote-fs-pre.target which is ordered before all
+          remote mounts and may be used to start services before all
+          remote mounts.
+
+        * Added Mageia support
+
+        * Add bash completion for systemd-loginctl
+
+        * Actively monitor PID file creation for daemons which exit in
+          the parent process before having finished writing the PID
+          file in the daemon process. Daemons which do this need to be
+          fixed (i.e. PID file creation must have finished before the
+          parent exits), but we now react a bit more gracefully to them.
+
+        * Add colourful boot output, mimicking the well-known output
+          of existing distributions.
+
+        * New option PassCredentials= for socket units, for
+          compatibility with a recent kernel ABI breakage.
+
+        * /etc/rc.local is now hooked in via a generator binary, and
+          thus will no longer act as synchronization point during
+          boot.
+
+        * systemctl list-unit-files now supports --root=.
+
+        * systemd-tmpfiles now understands two new commands: z, Z for
+          relabelling files according to the SELinux database. This is
+          useful to apply SELinux labels to specific files in /sys,
+          among other things.
+
+        * Output of SysV services is now forwarded to both the console
+          and the journal by default, not only just the console.
+
+        * New man pages for all APIs from libsystemd-login.
+
+        * The build tree got reorganized and a the build system is a
+          lot more modular allowing embedded setups to specifically
+          select the components of systemd they are interested in.
+
+        * Support for Linux systems lacking the kernel VT subsystem is
+          restored.
+
+        * configure's --with-rootdir= got renamed to
+          --with-rootprefix= to follow the naming used by udev and
+          kmod
+
+        * Unless specified otherwise we'll now install to /usr instead
+          of /usr/local by default.
+
+        * Processes with '@' in argv[0][0] are now excluded from the
+          final shut-down killing spree, following the logic explained
+          in:
+          http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
+
+        * All processes remaining in a service cgroup when we enter
+          the START or START_PRE states are now killed with
+          SIGKILL. That means it is no longer possible to spawn
+          background processes from ExecStart= lines (which was never
+          supported anyway, and bad style).
+
+        * New PropagateReloadTo=/PropagateReloadFrom= options to bind
+          reloading of units together.
+
+        Contributions from: Bill Nottingham, Daniel J. Walsh, Dave
+        Reisner, Dexter Morgan, Gregs Gregs, Jonathan Nieder, Kay
+        Sievers, Lennart Poettering, Michael Biebl, Michal Schmidt,
+        Michał Górny, Ran Benita, Thomas Jarosch, Tim Waugh, Tollef
+        Fog Heen, Tom Gundersen, Zbigniew Jędrzejewski-Szmek
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..581e845
--- /dev/null
+++ b/README
@@ -0,0 +1,122 @@
+systemd System and Service Manager
+
+DETAILS:
+        http://0pointer.de/blog/projects/systemd.html
+
+WEB SITE:
+        http://www.freedesktop.org/wiki/Software/systemd
+
+GIT:
+        git://anongit.freedesktop.org/systemd/systemd
+        ssh://git.freedesktop.org/git/systemd/systemd
+
+GITWEB:
+        http://cgit.freedesktop.org/systemd/systemd
+
+MAILING LIST:
+        http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+        http://lists.freedesktop.org/mailman/listinfo/systemd-commits
+
+IRC:
+        #systemd on irc.freenode.org
+
+BUG REPORTS:
+        https://bugs.freedesktop.org/enter_bug.cgi?product=systemd
+
+AUTHOR:
+        Lennart Poettering
+        Kay Sievers
+        ...and many others
+
+LICENSE:
+        LGPLv2.1+ for all code
+        - except sd-daemon.[ch] and sd-readahead.[ch] which are MIT
+        - except src/udev/ which is GPLv2.0+
+
+REQUIREMENTS:
+        Linux kernel >= 2.6.39
+                with devtmpfs
+                with cgroups (but it's OK to disable all controllers)
+                optional but strongly recommended: autofs4, ipv6
+        dbus >= 1.4.0
+        libcap
+        libblkid >= 2.20 (from util-linux) (optional)
+        libkmod >= 5 (optional)
+        PAM >= 1.1.2 (optional)
+        libcryptsetup (optional)
+        libaudit (optional)
+        libacl (optional)
+        libattr (optional)
+        libselinux (optional)
+        liblzma (optional)
+        tcpwrappers (optional)
+        libgcrypt (optional)
+        libqrencode (optional)
+        libmicrohttpd (optional)
+        libpython (optional)
+        make, gcc, and similar tools
+
+        During runtime you need the following additional dependencies:
+
+        util-linux >= v2.19 (requires fsck -l, agetty -s)
+        sulogin (from util-linux >= 2.22 or sysvinit-tools, optional but recommended)
+        dracut (optional)
+
+        When building from git you need the following additional dependencies:
+
+        docbook-xsl
+        xsltproc
+        automake
+        autoconf
+        libtool
+        intltool
+        gperf
+        gtkdocize (optional)
+        python (optional)
+
+        When systemd-hostnamed is used it is strongly recommended to
+        install nss-myhostname to ensure that in a world of
+        dynamically changing hostnames the hostname stays resolvable
+        under all circumstances. In fact, systemd-hostnamed will warn
+        if nss-myhostname is not installed. Packagers are encouraged to
+        add a dependency on nss-myhostname to the package that
+        includes systemd-hostnamed.
+
+        Note that D-Bus can link against libsystemd-login.so, which
+        results in a cyclic build dependency. To accommodate for this
+        please build D-Bus without systemd first, then build systemd,
+        then rebuild D-Bus with systemd support.
+
+WARNINGS:
+        systemd will warn you during boot if /etc/mtab is not a
+        symlink to /proc/mounts. Please ensure that /etc/mtab is a
+        proper symlink.
+
+        systemd will warn you during boot if /usr is on a different
+        file system than /. While in systemd itself very little will
+        break if /usr is on a separate partition many of its
+        dependencies very likely will break sooner or later in one
+        form or another. For example udev rules tend to refer to
+        binaries in /usr, binaries that link to libraries in /usr or
+        binaries that refer to data files in /usr. Since these
+        breakages are not always directly visible systemd will warn
+        about this, since this kind of file system setup is not really
+        supported anymore by the basic set of Linux OS components.
+
+        For more information on this issue consult
+        http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
+
+        To run systemd under valgrind, compile with VALGRIND defined
+        (e.g. ./configure CPPFLAGS='... -DVALGRIND=1'). Otherwise,
+        false positives will be triggered by code which violates
+        some rules but is actually safe.
+
+ENGINEERING AND CONSULTING SERVICES:
+        ProFUSION <http://profusion.mobi> offers professional
+        engineering and consulting services for systemd for embedded
+        and other use. Please contact Gustavo Barbieri
+        <barbieri@profusion.mobi> for more information.
+
+        Disclaimer: This notice is not a recommendation or official
+        endorsement. However, ProFUSION's upstream work has been very
+        beneficial for the systemd project.
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..c2eb557
--- /dev/null
+++ b/TODO
@@ -0,0 +1,613 @@
+Bugfixes:
+* check systemd-tmpfiles for selinux context hookup for mknod(), symlink() and similar
+
+* swap units that are activated by one name but shown in the kernel under another are semi-broken
+
+* make anaconda write timeout=0 for encrypted devices
+
+* Dangling symlinks of .automount unit files in .wants/ directories, set up
+  automount points even when the original .automount file did not exist
+  anymore. Only the .mount unit was still around.
+
+* make polkit checks async
+
+* properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point.
+
+F18:
+
+* Retest multi-seat
+
+Features:
+* udev: remove all (misguided from day 1) userspace firmware_class handling
+
+* logind: optionally, ignore idle-hint logic for autosuspend, block suspend as long as a session is around
+
+* service: when killing a service with SIGKILL always kill all processes, even if for SIGTERM we only killed the main process
+
+* exec: when deinitializating a tty device fix the perms and group, too, not only when initializing. Set access mode/gid to 0620/tty.
+
+* DeviceAllow/DeviceDeny: disallow everything by default, but whitelist /dev/zero, /dev/null and friends
+
+* service: watchdog logic: for testing purposes allow ping, but do not require pong
+
+* journald: when dropping msgs due to ratelimit make sure to write
+  "dropped %u messages" not only when we are about to print the next
+  message that works, but alraedy after a short tiemout
+
+* journald: also get thread ID from client, plus thread name
+
+* check if we can make journalctl by default use --follow mode inside of less if called without args?
+
+* Add a verbose mode to "systemctl start" and friends that explains what is being done or not done
+
+* journal is not closed properly at shutdown when run in a container?
+
+* journal: when waiting for journal additions in the client always sleep at least 1s or so, in order to minimize wakeups
+
+* When shutdown.target is queued begin with an asynchronous sync()?
+
+* add API to close/reopen/get fd for journal client fd in libsystemd-journal.
+
+* maybe add API to send pairs of iovecs via sd_journal_send
+
+* fallback to /dev/log based logging in libsystemd-journal, if we can't log natively?
+
+* declare the local journal protocol stable in the wiki interface chart
+
+* journal: reuse XZ context
+
+* sd-journal: speed up sd_journal_get_data() with transparent hash table in bg
+
+* introduce ntp.service (or suchlike) as symlink that is used to arbitrate between various NTP implementations
+
+* timer units should get the ability to trigger when:
+    - CLOCK_REALTIME makes jumps (TFD_TIMER_CANCEL_ON_SET)
+    - DST changes
+
+* update the kernel's TZ (sys_tz) when DST changes
+
+* sync down the system time to the RTC when:
+    - CLOCK_REALTIME makes jumps (the user explicitely requested a time set)
+    - DST/timezone changes && ntp is active && RTC-in-localtime (never do it without ntp)
+  This takes care of syncing ntpdate updates to the RTC, and DST updates for localtime
+  mode, it will never touch the RTC if the no reliable time source is active or the
+  user did not request anything like it.
+
+* When we begin with system shutdown all kind of suspend/hibernation should be prohibited until shutdown/reboot
+
+* When we update the kernel all kind of hibernation should be prohibited until shutdown/reboot
+
+* hwdb:
+  - implement conditional properties (dmi matches)
+  - hwdb --filter=ID_DRIVE_*
+  - find out what to do for blockdevs and skipping scsi modaliases
+  - move writing code to src/libudev/libudev-hwdb-private.c
+
+* if booted in "quiet" mode, and an error happens, turn on status output again, so that the emergency mode isn't totally surprising
+
+* localectl: add listing support for X11 keymaps, by parsing /usr/share/X11/xkb/rules/xorg.lst
+
+* libunwind support for coredump pattern hook, and includes this in
+  the message for coredumps. After all, libunwind is now capable to
+  unwind coredumps since a few weeks ago. This probably requires that
+  we have nice support for multi-line messages on display in logs-show.c.
+
+* figure out relation of --all and --full in the various tools
+
+* journal: when writing journal auto-rotate if time jumps backwards
+
+* introduce new "journal" group in place of adm? introduce groups for the various mini daemons?
+
+* journal: add a setgid "adm" utility to invoke from libsystemd-journal, which passes fds via STDOUT and does PK access
+
+* journactl: support negative filtering, i.e. FOOBAR!="waldo",
+  and !FOOBAR for events without FOOBAR.
+
+* print nice message from systemctl --failed if there are no entries shown, and hook that into ExecStartPre of rescue.service/emergency.service
+
+* add libsystemd-password or so to query passwords during boot using the password agent logic
+
+* journal: when rotating, copy over old acls/access mode
+
+* journal: document why we do not give ownership to journal files to the user that created them but use FS ACLs for that
+
+* journal: send out marker messages every now and then, and immediately sync with fdatasync() afterwards, in order to have hourly guaranteed syncs.
+
+* journal: when we haven't written anything in a while, sync to disk and mark file as offline, in order to be more often than not in a clean state
+
+* journal-send.c, log.c: when the log socket is clogged, and we drop, count this and write a message about this when it gets unclogged again.
+
+* If we show an error about a unit (such as not showing up) and it has no Description string, then show a description string generated form the reverse of unit_name_mangle().
+
+* fedup: add --unit to systemctl switch-root somehow
+* fedup: don't delete initrd on switch-root
+* fedup: generator
+
+* journal: find a way to allow dropping history early, based on priority, other rules
+
+* journal: When used on NFS, check payload hashes
+
+* journal: When used on NFS make sure wake up sd_journal_wait() every 2s, to handle missing inotify
+
+* document that people can use file system ACLs to manage access to journal files, with example
+
+* timedated: export boolean that clarifies whether NTP is even available
+
+* timedated: refuse time changes when NTP is on
+
+* clean up date formatting and parsing so that all absolute/relative timestamps we format can also be parsed
+
+* document unit_name_mangle()
+
+* add new command to systemctl: "systemctl system-reexec" which reexecs as many daemons as virtually possible
+
+* introduce generic AUGMENT_PID=, AUGMENT_DEVICE= fields
+
+* deal with sendmail/postfix exclusivity
+
+* systemctl enable: improve the success messages (i.e. more human readable, less shell-like)
+
+* systemctl enable: fail if target to alias into doesn't exist? maybe show how many units are enabled afterwards?
+
+* on shutdown: move utmp, wall, audit logic all into PID 1 itself, get rid of systemd-update-utmp-runlevel
+
+* add "provisioning" instructions to setup an empty /etc + /var
+    - used to setup a new container from a shared /usr
+    - superset of tmpfiles model
+    - instructions shipped by packages and stored in /usr/lib/
+    - compose /etc/passwd and /etc/group, copy files
+    - able to create uid + gid used by packages, for file ownership
+
+* make repeated alt-ctrl-del presses printing a dump, or even force a reboot without
+  waiting for the timeout
+
+* high level net_prio setting in execution context
+
+* Introduce journalctl -b <nr> to show journal messages of a previous boot
+
+* hostnamed: before returning information from /etc/machine-info.conf check the modification data and reread. Similar for localed, ...
+
+* currently x-systemd.timeout is lost in the initrd, since crypttab is copied into dracut, but fstab isn't
+
+* WorkingDirectory: support env var replacements like in ExecStart= so that people can use $HOME
+
+* refuse boot if /etc/machine-id is not useful (or set taint?)
+
+* nspawn: consider changing users for -u with su, so that NSS resolving works correctly
+
+* nspawn: implement personality changes a la linux32(8)
+
+* cryptsetup-generator: warn if the password files are world-readable
+
+* cryptsetup-generator: add RequiresMountsFor= to cryptseup service files referencing a file, similar for devices
+
+* cryptsetup-generator: allow specification of passwords in crypttab itself
+
+* document that deps in [Unit] sections ignore Alias= fileds in
+  [Install] units of other units, unless those units are disabled
+
+* systemctl: when powering down/suspending check for inhibitors, and warn.
+
+* instantiated [Install] for target units
+  https://bugs.freedesktop.org/show_bug.cgi?id=54377
+
+* move debug shell to tty6 and make sure this doesn't break the gettys on tty6
+
+* move cryptsetup key caching into kernel keyctl?
+  https://bugs.freedesktop.org/show_bug.cgi?id=54982
+
+* hw watchdog: optionally try to use the preset watchdog timeout instead of always overriding it
+  https://bugs.freedesktop.org/show_bug.cgi?id=54712
+
+* after deserializing sockets in socket.c we should reapply sockopts and things
+
+* make timer units go away after they elapsed
+
+* http://lists.freedesktop.org/archives/systemd-devel/2012-September/006502.html
+  (network and remote-fs on shutdown)
+
+* come up with a nice way to write queue/read_ahead_kb for a block device without interfering with readahead
+
+* journald: add kernel cmdline option to disable ratelimiting for debug purposes
+
+* move PID 1 segfaults to /var/lib/systemd/coredump?
+
+* Document word splitting syntax for ExecStart= and friends
+
+* create /sbin/init symlinks from the build system
+
+* Query Paul Moore about relabelling socket fds while they are open
+
+* move keymaps to /usr/lib/... rather than /usr/lib/udev/...
+
+* journald: check whether it is OK if the client can still modify delivered journal entries
+
+* journal live copy, based on libneon (client) and libmicrohttpd
+
+* system-wide seccomp filter
+
+* system.conf should have controls for cgroups
+
+* bind mount read-only the cgroup tree higher than nspawn
+
+* allow writing multiple conditions in unit files on one line
+
+* explore multiple service instances per listening socket idea
+
+* testing tool for socket activation: some binary that listens on a socket and passes it on using the usual socket activation protocol to some server.
+
+* shutdown: don't read-only mount anything when running in container
+
+* nspawn: --read-only is not applied recursively to submounts
+
+* MountFlags=shared acts as MountFlags=slave right now.
+
+* ReadOnlyDirectories= is not applied recursively to submounts
+
+* drop PID 1 reloading, only do reexecing (difficult: Reload()
+  currently is properly synchronous, Reexec() is weird, because we
+  can't delay the response properly until we are back, so instead of
+  being properly synchronous we just keep open the fd and close it
+  when done. That means clients don't get a successful method reply,
+  but much rather a disconnect on success.
+
+* document that service reload may be implemented as service reexec
+
+* remember which condition failed for services, not just the fact that something failed
+
+* use opterr = 0 for all getopt tools
+
+* properly handle loop back mounts via fstab, especially regards to fsck/passno
+
+* allow services with no ExecStart= but with an ExecStop=
+
+* add proper journal support to "systemctl --user status ..."
+
+* add _SYSTEMD_USER_UNIT= field to journal entries
+
+* dracut-shutdown needs to be ordered before unmounting /boot
+
+* initialize the hostname from the fs label of /, if /etc/hostname does not exist?
+
+* rename "userspace" to "core-os"
+
+* systemctl: "Journal has been rotated since unit was started." message is misleading
+
+* syscall filter: add knowledge about compat syscalls
+
+* syscall filter: don't enforce no new privs?
+
+* syscall filter: option to return EPERM rather than SIGSYS?
+
+* syscall filter: port to libseccomp
+
+* logind: wakelock/opportunistic suspend support
+
+* systemd-analyze post-boot is broken for initrd
+
+* systemd-analyze: data collection tools should be lightweight (few dependencies); data analysis tools can be heavyweight
+
+* man: clarify that time-sync.target is not only sysv compat but also useful otherwise. Same for similar targets
+
+* .device aliases need to be implemented with the "following" logic, probably.
+
+* refuse taking lower-case variable names in sd_journal_send() and friends.
+
+* load-fragment: when loading a unit file via a chain of symlinks
+  verify that it isn't masked via any of the names traversed.
+
+* journald: we currently rotate only after MaxUse+MaxFilesize has been reached.
+
+* Document:
+        - PID 1 D-Bus API
+
+* introduce Type=pid-file
+
+* maybe allow services with ExecStop= set, but no ExecStart=?
+
+* efi: implement /forcefsck as uefi variables thus not requiring file system altering to trigger a file system check
+
+* efi: honor language efi variables for default language selection
+
+* efi: honor timezone efi variables for default timezone selection
+
+* efi: automatically mount EFI partition to /boot if no such entry exists in /etc/fstab and /boot is empty
+  gummiboot exports the EFI system partion (ESP) device:
+  /sys/firmware/efi/vars/LoaderDeviceIdentifier-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f/data
+  Acpi(PNP0A03,0)/Pci(1F|2)/?/HD(Part1,Sig1FCBC57F-4BFC-4C2B-91A3-9C84FBCD9AF1)
+  '/' is the separator for the device path list
+  HD(Part1,Sig1FCBC57F-4BFC-4C2B-91A3-9C84FBCD9AF1) contains the GPT UUID of the ESP
+
+* read the bootloader performance data (raw TSC) in systemd-analyze
+  /sys/firmware/efi/vars/LoaderTicksExec-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f/data
+  19066159288
+  /sys/firmware/efi/vars/LoaderTicksInit-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f/data
+  17442940316
+  /sys/firmware/efi/vars/LoaderTicksStartMenu-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f/data
+  (only set if the menu was active)
+
+* change Requires=basic.target to RequisiteOverride=basic.target
+
+* support rd.luks.allow-discards= kernel cmdline params in cryptsetup generator
+
+* nspawn: make use of device cgroup controller by default
+
+* drop accountsservice's StandardOutput=syslog and Type=dbus fields
+
+* when breaking cycles drop sysv services first, then services from /run, then from /etc, then from /usr
+
+* readahead: when bumping /sys readahead variable save mtime and compare later to detect changes
+
+* (attempt to) make Debianites happy:
+        - implement .d/ auto includes for unit files
+        - add syntax to reset ExecStart= lists (and similar)
+
+* move passno parsing to fstab generator
+
+* improve !/proc/*/loginuid situation: make /proc/*/loginuid less dependent on CONFIG_AUDIT,
+  or use the users cgroup information when /proc/*/loginuid is not available.
+
+* pam_systemd: try to get old session id from cgroup, if audit sessionid cannot be determined
+
+* pam: when leaving a session explicitly exclude the ReleaseSession() caller process from the killing spree
+
+* maybe introduce ~/.config/locale.conf and apply it within PAM
+
+* readahead: make use of EXT4_IOC_MOVE_EXT, as used by http://e4rat.sourceforge.net/
+
+* automount: implement expire
+
+* services which create their own subcgroups break cgroup-empty notification (needs to be fixed in the kernel)
+
+* don't delete /tmp/systemd-namespace-* before a process is gone down
+
+* vconsole: implement setterm -store -foreground xxx --background zzz
+
+* ExecOnFailure=/usr/bin/foo
+
+* fedora: make sshd and pam_loginuid work in nspawn containers
+
+* fix utmp for console logins in containers
+
+* Add pretty name for seats in logind
+
+* ConditionSecurity= should learn about IMA and SMACK
+
+* Auke: merge Auke's bootchart
+
+* udev: move to LGPL
+
+* udev systemd unify:
+  - strpcpy(), strpcpyl(), strscpy(), strscpyl()
+  - utf8 validator code
+
+* udev: scsi_id -> sg3_utils -> kill scsi_id
+
+* udev: add trigger --subsystem-match=usb/usb_device device
+
+* allow configuration of console width/height in vconsole.conf
+
+* cleanup syslog 'priority' vs. 'level' wording
+
+* dbus upstream still refers to dbus.target and shouldn't
+
+* when a service has the same env var set twice we actually store it twice and return that in systemctl show -p... We should only show the last setting
+
+* support container_ttys=
+
+* introduce mix of BindTo and Requisite
+
+* journalctl: show multiline log messages sanely, expand tabs, and show all valid utf8 messages
+
+* add DeleteSocketsOnStop=yes|no option to socket units
+
+* journal: store euid in journal if it differs from uid
+
+* There's currently no way to cancel fsck (used to be possible via C-c or c on the console)
+
+* journal: sanely deal with entries which are larger than the individual file size, but where the components would fit
+
+* add command to systemctl to plot dependency graph as tree (see rhbz 795365)
+
+* add option to sockets to avoid activation. Instead just drop packets/connections, see http://cyberelk.net/tim/2012/02/15/portreserve-systemd-solution/
+
+* default unix qlen is too small (10). bump sysctl? add sockopt?
+
+* figure out whether we should leave dbus around during shutdown
+
+* dbus: in fedora, make the machine a symlink to /etc/machine-id
+
+* dbus: move dbus to early boot
+
+* logind: add equivalent to sd_pid_get_owner_uid() to the D-Bus API
+
+* journal: deal nicely with byte-by-byte copied files, especially regards header
+
+* journal: local deserializer of export mode, http server
+
+* document the exit codes when services fail before they are exec()ed
+
+* save coredump in Windows/Mozilla minidump format
+
+* support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting)
+
+* clean up session cgroups that remain after logout (think sshd), but eventually run empty
+
+* support "systemctl stop foobar@.service" to stop all units matching a certain template
+
+* logind: allow showing logout dialog from system
+
+* document that %% can be used to write % in a string that is specifier extended
+
+* when an instanced service exits, remove its parent cgroup too if possible.
+
+* default to actual 32bit PIDs, via /proc/sys/kernel/pid_max
+
+* be able to specify a forced restart of service A where service B depends on, in case B
+  needs to be auto-respawned?
+
+* Something is wrong with symlink handling of "autovt@.service" in "systemctl list-unit-files"
+
+* when a bus name of a service disappears from the bus make sure to queue further activation requests
+
+* something like ConditionExec= or ExecStartPre= without failure state
+
+* tmpfiles: apply "x" on "D" too (see patch from William Douglas)
+
+* don't set $HOME in services unless requested
+
+* hide PAM/TCPWrap options in fragment parser when compile time disabled
+
+* when we automatically restart a service, ensure we restart its rdeps, too.
+
+* allow Type=simple with PIDFile=
+  https://bugzilla.redhat.com/show_bug.cgi?id=723942
+
+* move PAM code into its own binary
+
+* logind: spawn user@..service on login
+
+* logind: non-local X11 server handling
+
+* implement Register= switch in .socket units to enable registration
+  in Avahi, RPC and other socket registration services.
+
+* make sure systemd-ask-password-wall does not shutdown systemd-ask-password-console too early
+
+* readahead: use BTRFS_IOC_DEFRAG_RANGE instead of BTRFS_IOC_DEFRAG ioctl, with START_IO
+
+* support sd_notify() style notification when reload begins (RELOADING=1), reload is finished (READY=1), and add ReloadSignal= then to use in combination
+
+* support sd_notify() style notification when shutting down, to make auto-exit bus services work (STOPPING=1)
+
+* verify that the AF_UNIX sockets of a service in the fs still exist
+  when we start a service in order to avoid confusion when a user
+  assumes starting a service is enough to make it accessible
+
+* Make it possible to set the keymap independently from the font on
+  the kernel cmdline. Right now setting one resets also the other.
+
+* move nss-myhostname into systemd
+
+* and a dbus call to generate target from current state
+
+* drop /.readahead on bigger upgrades with yum
+
+* add support for /bin/mount -s
+
+* GC unreferenced jobs (such as .device jobs)
+
+* write blog stories about:
+  - hwdb: what belongs into it, lsusb
+  - enabling dbus services
+  - status update
+  - how to make changes to sysctl and sysfs attributes
+  - remote access
+  - how to pass throw-away units to systemd, or dynamically change properties of existing units
+  - how to integrate cgconfig and suchlike with systemd
+  - testing with Harald's awesome test kit
+  - auto-restart
+  - how to develop against journal browsing APIs
+  - the journal HTTP iface
+  - non-cgroup resource management
+  - refreshed, longer missions statement
+  - using detect-virt
+
+* allow port=0 in .socket units
+
+* move readahead files into /var (look for them with .path units?)
+
+* teach dbus to activate all services it finds in /etc/systemd/services/org-*.service
+
+* support systemd.mask= on the kernel command line.
+
+* when key file cannot be found, read it from kbd in cryptsetup
+
+* reuse mkdtemp namespace dirs in /tmp?
+
+* recreate systemd's D-Bus private socket file on SIGUSR2
+
+* Support --test based on current system state
+
+* investigate whether the gnome pty helper should be moved into systemd, to provide cgroup support.
+
+* maybe introduce ExecRestartPre=
+
+* configurable jitter for timer events
+
+* timer events with system resume
+
+* dot output for --test showing the 'initial transaction'
+
+* writable cgroups dbus properties for live changes
+
+* port over to LISTEN_FDS/LISTEN_PID:
+   - rpcbind (/var/run/rpcbind.sock!) HAVEPATCH
+   - cups     HAVEPATCH
+   - postfix, saslauthd
+   - apache/samba
+   - libvirtd (/var/run/libvirt/libvirt-sock-ro)
+   - bluetoothd (/var/run/sdp! @/org/bluez/audio!)
+   - distccd
+
+* fingerprint.target, wireless.target, gps.target, netdevice.target
+
+* io priority during initialization
+
+* systemctl list-jobs - show dependencies
+
+* add systemctl switch to dump transaction without executing it
+
+* drop cap bounding set in readahead and other services
+
+External:
+
+* dbus:
+   - dbus --user
+   - natively watch for dbus-*.service symlinks (PENDING)
+   - allow specification of socket mode/umask when allocating DBusServer
+   - allow disabling of fd passing when connecting a AF_UNIX connection
+   - allow disabling of UID passing for AUTH EXTERNAL
+   - always pass cred data along each message
+
+* fix alsa mixer restore to not print error when no config is stored
+
+* gnome-shell python script/glxinfo/is-accelerated must die
+
+* make cryptsetup lower --iter-time
+
+* patch kernel for xattr support in /dev, /proc/, /sys and /sys/fs/cgroup?
+
+* NTP: the kernel's 11-minutes-mode syncs the system time to the RTC, but only
+  in an ~30 minutes window. It does not adjust larger differences. Find a way
+  to tell the kernel, to always do a full time sync when the RTC is in UTC and
+  we are in 11-minutes-mode. When we trust the system time to NTP we also want
+  the RTC to sync up.
+
+* kernel: add device_type = "fb", "fbcon" to class "graphics"
+
+Regularly:
+
+* look for close() vs. close_nointr() vs. close_nointr_nofail()
+
+* check for strerror(r) instead of strerror(-r)
+
+* Use PR_SET_PROCTITLE_AREA if it becomes available in the kernel
+
+* %m in printf() instead of strerror(errno);
+
+* pahole
+
+* set_put(), hashmap_put() return values check. i.e. == 0 doesn't free()!
+
+* use secure_getenv() instead of getenv() where appropriate
+
+* link up selected blog stories from man pages and unit files Documentation= fields
+
+Scheduled for removal or fixing:
+
+* xxxOverridable dependencies (probably: fix)
+
+* support for early-boot SysV services (definitely: remove)
+
+* insserv support (definitely: remove)
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..33d8fcd
--- /dev/null
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then
+        # This part is allowed to fail
+        cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
+        chmod +x .git/hooks/pre-commit && \
+        echo "Activated pre-commit hook." || :
+fi
+
+if which gtkdocize >/dev/null 2>/dev/null; then
+        gtkdocize --docdir docs/
+        gtkdocargs=--enable-gtk-doc
+else
+        echo "You don't have gtk-doc installed, and thus won't be able to generate the documentation."
+        rm -f docs/gtk-doc.make
+        echo 'EXTRA_DIST =' > docs/gtk-doc.make
+fi
+
+intltoolize --force --automake
+autoreconf --force --install --symlink
+
+libdir() {
+        echo $(cd "$1/$(gcc -print-multi-os-directory)"; pwd)
+}
+
+args="\
+--sysconfdir=/etc \
+--localstatedir=/var \
+--libdir=$(libdir /usr/lib) \
+$gtkdocargs"
+
+if [ ! -L /bin ]; then
+args="$args \
+--with-rootprefix= \
+--with-rootlibdir=$(libdir /lib) \
+"
+fi
+
+if [ "x$1" = "xc" ]; then
+        ./configure CFLAGS='-g -O0 -Wp,-U_FORTIFY_SOURCE' $args
+        make clean
+else
+        echo
+        echo "----------------------------------------------------------------"
+        echo "Initialized build system. For a common configuration please run:"
+        echo "----------------------------------------------------------------"
+        echo
+        echo "./configure CFLAGS='-g -O0 -Wp,-U_FORTIFY_SOURCE' $args"
+        echo
+fi
diff --git a/catalog/Makefile b/catalog/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/catalog/systemd.catalog b/catalog/systemd.catalog
new file mode 100644 (file)
index 0000000..5dcbd46
--- /dev/null
@@ -0,0 +1,291 @@
+#  This file is part of systemd.
+#
+#  Copyright 2012 Lennart Poettering
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+# Message catalog for systemd's own messages
+
+# The catalog format is documented on
+# http://www.freedesktop.org/wiki/Software/systemd/catalog
+
+# For an explanation why we do all this, see https://xkcd.com/1024/
+
+-- f77379a8490b408bbe5f6940505a777b
+Subject: The Journal has been started
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+The system journal process has been starting up, opened the journal
+files for writing and is now ready to process requests.
+
+-- d93fb3c9c24d451a97cea615ce59c00b
+Subject: The Journal has been stopped
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+The system journal process has shut down and closed all currently
+active journal files.
+
+-- a596d6fe7bfa4994828e72309e95d61e
+Subject: Messages from a service have been suppressed
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:journald.conf(5)
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+A service has logged too many messages within a time period. Messages
+from the service have been dropped.
+
+Note that only messages from the service in question have been
+dropped, other services' messages are unaffected.
+
+The limits when messages are dropped may be configured with
+RateLimitInterval= and RateLimitBurst= in
+/etc/systemd/journald.conf. See journald.conf(5) for details.
+
+-- e9bf28e6e834481bb6f48f548ad13606
+Subject: Journal messages have been missed
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Kernel messages have been lost as the journal system has been unable
+to process them quickly enough.
+
+-- fc2e22bc6ee647b6b90729ab34a250b1
+Subject: Process @COREDUMP_PID@ (@COREDUMP_COMM@) dumped core
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:core(5)
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Process @COREDUMP_PID@ (@COREDUMP_COMM@) crashed and dumped core.
+
+This usually indicates a programming error in the crashing program and
+should be reported to its vendor as a bug.
+
+-- fc2e22bc6ee647b6b90729ab34a250b1 de
+Subject: Speicherabbild für Prozess @COREDUMP_PID@ (@COREDUMP_COMM) generiert
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: man:core(5)
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Prozess @COREDUMP_PID@ (@COREDUMP_COMM@) ist abgebrochen worden und
+ein Speicherabbild wurde generiert.
+
+Üblicherweise ist dies ein Hinweis auf einen Programmfehler und sollte
+als Fehler dem jeweiligen Hersteller gemeldet werden.
+
+-- 8d45620c1a4348dbb17410da57c60c66
+Subject: A new session @SESSION_ID@ has been created for user @USER_ID@
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+A new session with the ID @SESSION_ID@ has been created for the user @USER_ID@.
+
+The leading process of the session is @LEADER@.
+
+-- 3354939424b4456d9802ca8333ed424a
+Subject: A session @SESSION_ID@ has been terminated
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+A session with the ID @SESSION_ID@ has been terminated.
+
+-- fcbefc5da23d428093f97c82a9290f7b
+Subject: A new seat @SEAT_ID@ is now available
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+A new seat @SEAT_ID@ has been configured and is now available.
+
+-- e7852bfe46784ed0accde04bc864c2d5
+Subject: A seat @SEAT_ID@ has now been removed
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+A seat @SEAT_ID@ has been removed and is no longer available.
+
+-- c7a787079b354eaaa9e77b371893cd27
+Subject: Time change
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+The system clock has been changed to @REALTIME@ microseconds after January 1st, 1970.
+
+-- c7a787079b354eaaa9e77b371893cd27 de
+Subject: Zeitänderung
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Die System-Zeit wurde geändert auf @REALTIME@ Mikrosekunden nach dem 1. Januar 1970.
+
+-- 45f82f4aef7a4bbf942ce861d1f20990
+Subject: Time zone change to @TIMEZONE@
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+The system time zone has been changed to @TIMEZONE@.
+
+-- b07a249cd024414a82dd00cd181378ff
+Subject: System start-up is now complete
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+All system services necessary queued for starting at boot have been
+successfully started. Note that this does not mean that the machine is
+now idle as services might still be busy with completing start-up.
+
+Kernel start-up required @KERNEL_USEC@ microseconds.
+
+Initial RAM disk start-up required @INITRD_USEC@ microseconds.
+
+Userspace start-up required @USERSPACE_USEC@ microseconds.
+
+-- 6bbd95ee977941e497c48be27c254128
+Subject: System sleep state @SLEEP@ entered
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+The system has now entered the @SLEEP@ sleep state.
+
+-- 8811e6df2a8e40f58a94cea26f8ebf14
+Subject: System sleep state @SLEEP@ left
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+The system has now left the @SLEEP@ sleep state.
+
+-- 98268866d1d54a499c4e98921d93bc40
+Subject: System shutdown initiated
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Systemd shutdown has been initiated. The shutdown has now begun and
+all system services are terminated and all file systems unmounted.
+
+-- 7d4958e842da4a758f6c1cdc7b36dcc5
+Subject: Unit @UNIT@ has begun with start-up
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Unit @UNIT@ has begun starting up.
+
+-- 39f53479d3a045ac8e11786248231fbf
+Subject: Unit @UNIT@ has finished start-up
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Unit @UNIT@ has finished starting up.
+
+The start-up result is @RESULT@.
+
+-- de5b426a63be47a7b6ac3eaac82e2f6f
+Subject: Unit @UNIT@ has begun shutting down
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Unit @UNIT@ has begun shutting down.
+
+-- 9d1aaa27d60140bd96365438aad20286
+Subject: Unit @UNIT@ has finished shutting down
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Unit @UNIT@ has finished shutting down.
+
+-- be02cf6855d2428ba40df7e9d022f03d
+Subject: Unit @UNIT@ has failed
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Unit @UNIT@ has failed.
+
+The result is @RESULT@.
+
+-- d34d037fff1847e6ae669a370e694725
+Subject: Unit @UNIT@ has begun with reloading its configuration
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Unit @UNIT@ has begun with reloading its configuration
+
+-- 7b05ebc668384222baa8881179cfda54
+Subject: Unit @UNIT@ has finished reloading its configuration
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+Unit @UNIT@ has finished reloading its configuration
+
+The result is @RESULT@.
+
+-- 641257651c1b4ec9a8624d7a40a9e1e7
+Subject: Process @EXECUTABLE@ could not be executed
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+The process @EXECUTABLE@ could not be executed and failed.
+
+The error number returned while executing this process is @ERRNO@.
+
+-- 0027229ca0644181a76c4e92458afa2e
+Subject: One or more messages could not be forwarded to syslog
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+One or more messages could not be forwarded to the syslog service
+running side-by-side with journald. This usually indicates that the
+syslog implementation has not been able to keep up with the speed of
+messages queued.
+
+-- 1dee0369c7fc4736b7099b38ecb46ee7
+Subject: Mount point is not empty
+Defined-By: systemd
+Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
+
+The directory @WHERE@ is specified as the mount point (second field in
+/etc/fstab or Where= field in systemd unit file) and is not empty.
+This does not interfere with mounting, but the pre-exisiting files in
+this directory become inaccessible. To see those over-mounted files,
+please manually mount the underlying file system to a secondary
+location.
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..a8d4887
--- /dev/null
@@ -0,0 +1,874 @@
+#
+#  This file is part of systemd.
+#
+#  Copyright 2010-2012 Lennart Poettering
+#  Copyright 2010-2012 Kay Sievers
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+AC_PREREQ([2.64])
+
+AC_INIT([systemd],
+        [196],
+        [http://bugs.freedesktop.org/enter_bug.cgi?product=systemd],
+        [systemd],
+        [http://www.freedesktop.org/wiki/Software/systemd])
+
+AC_CONFIG_SRCDIR([src/core/main.c])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_AUX_DIR([build-aux])
+
+AC_USE_SYSTEM_EXTENSIONS
+AC_SYS_LARGEFILE
+AC_PREFIX_DEFAULT([/usr])
+AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax no-dist-gzip dist-xz subdir-objects check-news])
+AM_SILENT_RULES([yes])
+AC_CANONICAL_HOST
+AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.])
+AS_IF([test "x$host_cpu" = "xmips" || test "x$host_cpu" = "xmipsel" ||
+       test "x$host_cpu" = "xmips64" || test "x$host_cpu" = "xmips64el"],
+      [AC_DEFINE(ARCH_MIPS, [], [Whether on mips arch])])
+
+LT_PREREQ(2.2)
+LT_INIT
+
+# i18n stuff for the PolicyKit policy files
+IT_PROG_INTLTOOL([0.40.0])
+
+GETTEXT_PACKAGE=systemd
+AC_SUBST(GETTEXT_PACKAGE)
+
+AC_PROG_MKDIR_P
+AC_PROG_LN_S
+AC_PROG_SED
+AC_PROG_GREP
+AC_PROG_AWK
+
+AC_PROG_CC
+AC_PROG_CC_C99
+AM_PROG_CC_C_O
+AC_PROG_GCC_TRADITIONAL
+
+AC_PATH_PROG([M4], [m4])
+AC_PATH_PROG([XSLTPROC], [xsltproc])
+
+AC_PATH_PROG([QUOTAON], [quotaon], [/usr/sbin/quotaon])
+AC_PATH_PROG([QUOTACHECK], [quotacheck], [/usr/sbin/quotacheck])
+
+AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap])
+
+AC_PATH_PROG([KILL], [kill], [/usr/bin/kill])
+
+# gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line
+m4_ifdef([GTK_DOC_CHECK], [
+GTK_DOC_CHECK([1.18],[--flavour no-tmpl])
+], [AM_CONDITIONAL([ENABLE_GTK_DOC], [false])])
+
+AS_IF([test "x$enable_gtk_doc" = "xyes" -a "x$XSLTPROC" = x], [
+        AC_MSG_ERROR([*** GTK doc requested but xsltproc not found])
+])
+
+m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [
+GOBJECT_INTROSPECTION_CHECK([1.31.1])
+], [
+   AM_CONDITIONAL([HAVE_INTROSPECTION], [false])
+   enable_introspection=no])
+
+AC_PATH_TOOL(OBJCOPY, objcopy)
+AC_PATH_TOOL(STRINGS, strings)
+AC_PATH_TOOL(GPERF, gperf)
+if test -z "$GPERF" ; then
+        AC_MSG_ERROR([*** gperf not found])
+fi
+
+# we use python to build the man page index, and for systemd-python
+have_python=no
+have_python_devel=no
+
+AC_ARG_WITH([python],
+        [AS_HELP_STRING([--without-python], [Disable building the man page index and systemd-python (default: test)])])
+
+AS_IF([test "x$with_python" != "xno"], [
+        AM_PATH_PYTHON(,, [:])
+        AS_IF([test "$PYTHON" != :], [have_python=yes])
+])
+AM_CONDITIONAL([HAVE_PYTHON], [test "x$have_python" = "xyes"])
+AS_IF([test "x$PYTHON_BINARY" = "x"],
+      [AS_IF([test "x$have_python" = "xyes"],
+             [PYTHON_BINARY="`which "$PYTHON"`"],
+             [PYTHON_BINARY=/usr/bin/python])])
+AC_ARG_VAR(PYTHON_BINARY, [Python binary used to launch installed scripts])
+
+AS_IF([test "x$with_python" != "xno"], [
+        AC_PATH_PROG(PYTHON_CONFIG, python${PYTHON_VERSION}-config)
+        AS_IF([test -n "$PYTHON_CONFIG"], [
+              have_python_devel=yes
+              PYTHON_CFLAGS="`$PYTHON_CONFIG --cflags`"
+              PYTHON_LIBS="`$PYTHON_CONFIG --ldflags`"
+              AC_SUBST(PYTHON_CFLAGS)
+              AC_SUBST(PYTHON_LIBS)
+        ])
+])
+AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test "$have_python_devel" = "yes"])
+
+CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
+        -pipe \
+        -Wall \
+        -Wextra \
+        -Wno-inline \
+        -Wundef \
+        -Wformat=2 \
+        -Wlogical-op \
+        -Wsign-compare \
+        -Wformat-security \
+        -Wmissing-include-dirs \
+        -Wformat-nonliteral \
+        -Wold-style-definition \
+        -Wpointer-arith \
+        -Winit-self \
+        -Wdeclaration-after-statement \
+        -Wfloat-equal \
+        -Wmissing-prototypes \
+        -Wstrict-prototypes \
+        -Wredundant-decls \
+        -Wmissing-declarations \
+        -Wmissing-noreturn \
+        -Wshadow \
+        -Wendif-labels \
+        -Wcast-align \
+        -Wstrict-aliasing=2 \
+        -Wwrite-strings \
+        -Wno-long-long \
+        -Wno-overlength-strings \
+        -Wno-unused-parameter \
+        -Wno-missing-field-initializers \
+        -Wno-unused-result \
+        -Werror=overflow \
+        -ffast-math \
+        -fno-common \
+        -fdiagnostics-show-option \
+        -fno-strict-aliasing \
+        -fvisibility=hidden \
+        -ffunction-sections \
+        -fdata-sections \
+        -fstack-protector \
+        --param=ssp-buffer-size=4])
+AC_SUBST([OUR_CFLAGS], $with_cflags)
+
+CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\
+        -Wp,-D_FORTIFY_SOURCE=2])
+AC_SUBST([OUR_CPPFLAGS], $with_cppflags)
+
+CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\
+        -Wl,--as-needed \
+        -Wl,--gc-sections \
+        -Wl,-z,relro \
+        -Wl,-z,now])
+AC_SUBST([OUR_LDFLAGS], $with_ldflags)
+
+AC_SEARCH_LIBS([mq_open], [rt], [], [AC_MSG_ERROR([*** POSIX RT library not found])])
+AC_SEARCH_LIBS([dlsym], [dl], [], [AC_MSG_ERROR([*** Dynamic linking loader library not found])])
+
+save_LIBS="$LIBS"
+LIBS=
+AC_SEARCH_LIBS([cap_init], [cap], [], [AC_MSG_ERROR([*** POSIX caps library not found])])
+AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])])
+CAP_LIBS="$LIBS"
+LIBS="$save_LIBS"
+AC_SUBST(CAP_LIBS)
+
+AC_CHECK_FUNCS([fanotify_init fanotify_mark])
+AC_CHECK_FUNCS([__secure_getenv secure_getenv])
+AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at], [], [], [[#include <sys/types.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <fcntl.h>]])
+
+# This makes sure pkg.m4 is available.
+m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config])
+
+PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2])
+
+# ------------------------------------------------------------------------------
+have_kmod=no
+AC_ARG_ENABLE(kmod, AS_HELP_STRING([--disable-kmod], [disable loadable modules support]))
+if test "x$enable_kmod" != "xno"; then
+        PKG_CHECK_MODULES(KMOD, [ libkmod >= 5 ],
+                [AC_DEFINE(HAVE_KMOD, 1, [Define if kmod is available]) have_kmod=yes], have_kmod=no)
+        if test "x$have_kmod" = xno -a "x$enable_kmod" = xyes; then
+                AC_MSG_ERROR([*** kmod support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_KMOD, [test "$have_kmod" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_blkid=no
+AC_ARG_ENABLE(blkid, AS_HELP_STRING([--disable-blkid], [disable blkid support]))
+if test "x$enable_blkid" != "xno"; then
+        PKG_CHECK_MODULES(BLKID, [ blkid >= 2.20 ],
+                [AC_DEFINE(HAVE_BLKID, 1, [Define if blkid is available]) have_blkid=yes], have_blkid=no)
+        if test "x$have_blkid" = xno -a "x$enable_blkid" = xyes; then
+                AC_MSG_ERROR([*** blkid support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_BLKID, [test "$have_blkid" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_ima=yes
+AC_ARG_ENABLE([ima], AS_HELP_STRING([--disable-ima],[Disable optional IMA support]),
+                [case "${enableval}" in
+                        yes) have_ima=yes ;;
+                        no) have_ima=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-ima) ;;
+                esac],
+                [have_ima=yes])
+
+if test "x${have_ima}" != xno ; then
+        AC_DEFINE(HAVE_IMA, 1, [Define if IMA is available])
+fi
+
+# ------------------------------------------------------------------------------
+have_chkconfig=yes
+AC_ARG_ENABLE([chkconfig], AS_HELP_STRING([--disable-chkconfig],[Disable optional chkconfig support]),
+                [case "${enableval}" in
+                        yes) have_chkconfig=yes ;;
+                        no) have_chkconfig=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-chkconfig) ;;
+                esac],
+                [AC_PATH_PROG(CHKCONFIG, chkconfig)
+                if test -z "$CHKCONFIG"; then
+                        have_chkconfig=no
+                else
+                        have_chkconfig=yes
+                fi])
+
+if test "x${have_chkconfig}" != xno ; then
+        AC_DEFINE(HAVE_CHKCONFIG, 1, [Define if CHKCONFIG is available])
+fi
+
+# ------------------------------------------------------------------------------
+have_selinux=no
+AC_ARG_ENABLE(selinux, AS_HELP_STRING([--disable-selinux], [Disable optional SELINUX support]))
+if test "x$enable_selinux" != "xno"; then
+        PKG_CHECK_MODULES([SELINUX], [libselinux >= 2.1.9],
+                [AC_DEFINE(HAVE_SELINUX, 1, [Define if SELinux is available]) have_selinux=yes], have_selinux=no)
+        if test "x$have_selinux" = xno -a "x$enable_selinux" = xyes; then
+                AC_MSG_ERROR([*** SELinux support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_SELINUX, [test "$have_selinux" = "yes"])
+if test "x${have_selinux}" != xno ; then
+        sushell=/sbin/sushell
+else
+        sushell=/bin/bash
+fi
+AC_SUBST(sushell)
+
+# ------------------------------------------------------------------------------
+have_xz=no
+AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [Disable optional XZ support]))
+if test "x$enable_xz" != "xno"; then
+        PKG_CHECK_MODULES(XZ, [ liblzma ],
+                [AC_DEFINE(HAVE_XZ, 1, [Define if XZ is available]) have_xz=yes], have_xz=no)
+        if test "x$have_xz" = xno -a "x$enable_xz" = xyes; then
+                AC_MSG_ERROR([*** Xz support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_XZ, [test "$have_xz" = "yes"])
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([tcpwrap],
+        AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]),
+                [case "${enableval}" in
+                        yes) have_tcpwrap=yes ;;
+                        no) have_tcpwrap=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-tcpwrap) ;;
+                esac],
+                [have_tcpwrap=auto])
+
+if test "x${have_tcpwrap}" != xno ; then
+        ACX_LIBWRAP
+        if test "x${LIBWRAP_LIBS}" = x ; then
+                if test "x$have_tcpwrap" = xyes ; then
+                        AC_MSG_ERROR([*** TCP wrappers support not found.])
+                fi
+                have_tcpwrap=no
+        else
+                have_tcpwrap=yes
+        fi
+else
+        LIBWRAP_LIBS=
+fi
+AC_SUBST(LIBWRAP_LIBS)
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([pam],
+        AS_HELP_STRING([--disable-pam],[Disable optional PAM support]),
+                [case "${enableval}" in
+                        yes) have_pam=yes ;;
+                        no) have_pam=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-pam) ;;
+                esac],
+                [have_pam=auto])
+
+if test "x${have_pam}" != xno ; then
+        AC_CHECK_HEADERS(
+                [security/pam_modules.h security/pam_modutil.h security/pam_ext.h],
+                [have_pam=yes],
+                [if test "x$have_pam" = xyes ; then
+                        AC_MSG_ERROR([*** PAM headers not found.])
+                fi])
+
+        AC_CHECK_LIB(
+                [pam],
+                [pam_syslog],
+                [have_pam=yes],
+                [if test "x$have_pam" = xyes ; then
+                        AC_MSG_ERROR([*** libpam not found.])
+                fi])
+
+        if test "x$have_pam" = xyes ; then
+                PAM_LIBS="-lpam -lpam_misc"
+                AC_DEFINE(HAVE_PAM, 1, [PAM available])
+        else
+                have_pam=no
+        fi
+else
+        PAM_LIBS=
+fi
+AC_SUBST(PAM_LIBS)
+AM_CONDITIONAL([HAVE_PAM], [test "x$have_pam" != xno])
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([acl],
+        AS_HELP_STRING([--disable-acl],[Disable optional ACL support]),
+                [case "${enableval}" in
+                        yes) have_acl=yes ;;
+                        no) have_acl=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-acl) ;;
+                esac],
+                [have_acl=auto])
+
+if test "x${have_acl}" != xno ; then
+        AC_CHECK_HEADERS(
+                [sys/acl.h acl/libacl.h],
+                [have_acl=yes],
+                [if test "x$have_acl" = xyes ; then
+                        AC_MSG_ERROR([*** ACL headers not found.])
+                fi])
+
+        AC_CHECK_LIB(
+                [acl],
+                [acl_get_file],
+                [have_acl=yes],
+                [if test "x$have_acl" = xyes ; then
+                        AC_MSG_ERROR([*** libacl not found.])
+                fi])
+
+        if test "x$have_acl" = xyes ; then
+                ACL_LIBS="-lacl"
+                AC_DEFINE(HAVE_ACL, 1, [ACL available])
+        else
+                have_acl=no
+        fi
+else
+        ACL_LIBS=
+fi
+AC_SUBST(ACL_LIBS)
+AM_CONDITIONAL([HAVE_ACL], [test "x$have_acl" != xno])
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([xattr],
+        AS_HELP_STRING([--disable-xattr],[Disable optional XATTR support]),
+                [case "${enableval}" in
+                        yes) have_xattr=yes ;;
+                        no) have_xattr=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-xattr) ;;
+                esac],
+                [have_xattr=auto])
+
+if test "x${have_xattr}" != xno ; then
+        AC_CHECK_HEADERS(
+                [attr/xattr.h],
+                [have_xattr=yes],
+                [if test "x$have_xattr" = xyes ; then
+                        AC_MSG_ERROR([*** XATTR headers not found.])
+                fi])
+
+        AC_CHECK_LIB(
+                [attr],
+                [fsetxattr],
+                [have_xattr=yes],
+                [if test "x$have_xattr" = xyes ; then
+                        AC_MSG_ERROR([*** libattr not found.])
+                fi])
+
+        if test "x$have_xattr" = xyes ; then
+                XATTR_LIBS="-lattr"
+                AC_DEFINE(HAVE_XATTR, 1, [XATTR available])
+        else
+                have_xattr=no
+        fi
+else
+        XATTR_LIBS=
+fi
+AC_SUBST(XATTR_LIBS)
+AM_CONDITIONAL([HAVE_XATTR], [test "x$have_xattr" != xno])
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([gcrypt],
+        AS_HELP_STRING([--disable-gcrypt],[Disable optional GCRYPT support]),
+                [case "${enableval}" in
+                        yes) have_gcrypt=yes ;;
+                        no) have_gcrypt=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-gcrypt) ;;
+                esac],
+                [have_gcrypt=auto])
+
+if test "x${have_gcrypt}" != xno ; then
+        AM_PATH_LIBGCRYPT(
+                [1.4.5],
+                [have_gcrypt=yes],
+                [if test "x$have_gcrypt" = xyes ; then
+                        AC_MSG_ERROR([*** GCRYPT headers not found.])
+                fi])
+
+        if test "x$have_gcrypt" = xyes ; then
+                GCRYPT_LIBS="$LIBGCRYPT_LIBS"
+                GCRYPT_CFLAGS="$LIBGCRYPT_CFLAGS"
+                AC_DEFINE(HAVE_GCRYPT, 1, [GCRYPT available])
+        else
+                have_gcrypt=no
+        fi
+else
+        GCRYPT_LIBS=
+        GCRYPT_CFLAGS=
+fi
+AC_SUBST(GCRYPT_LIBS)
+AC_SUBST(GCRYPT_CFLAGS)
+AM_CONDITIONAL([HAVE_GCRYPT], [test "x$have_gcrypt" != xno])
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([audit],
+        AS_HELP_STRING([--disable-audit],[Disable optional AUDIT support]),
+                [case "${enableval}" in
+                        yes) have_audit=yes ;;
+                        no) have_audit=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-audit) ;;
+                esac],
+                [have_audit=auto])
+
+if test "x${have_audit}" != xno ; then
+        AC_CHECK_HEADERS(
+                [libaudit.h],
+                [have_audit=yes],
+                [if test "x$have_audit" = xyes ; then
+                        AC_MSG_ERROR([*** AUDIT headers not found.])
+                fi])
+
+        AC_CHECK_LIB(
+                [audit],
+                [audit_open],
+                [have_audit=yes],
+                [if test "x$have_audit" = xyes ; then
+                        AC_MSG_ERROR([*** libaudit not found.])
+                fi])
+
+        if test "x$have_audit" = xyes ; then
+                AUDIT_LIBS="-laudit"
+                AC_DEFINE(HAVE_AUDIT, 1, [AUDIT available])
+        else
+                have_audit=no
+        fi
+else
+        AUDIT_LIBS=
+fi
+AC_SUBST(AUDIT_LIBS)
+
+# ------------------------------------------------------------------------------
+have_libcryptsetup=no
+AC_ARG_ENABLE(libcryptsetup, AS_HELP_STRING([--disable-libcryptsetup], [disable libcryptsetup tools]))
+if test "x$enable_libcryptsetup" != "xno"; then
+        PKG_CHECK_MODULES(LIBCRYPTSETUP, [ libcryptsetup >= 1.4.2 ],
+                [AC_DEFINE(HAVE_LIBCRYPTSETUP, 1, [Define if libcryptsetup is available]) have_libcryptsetup=yes], have_libcryptsetup=no)
+        if test "x$have_libcryptsetup" = xno -a "x$enable_libcryptsetup" = xyes; then
+                AC_MSG_ERROR([*** libcryptsetup support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_LIBCRYPTSETUP, [test "$have_libcryptsetup" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_qrencode=no
+AC_ARG_ENABLE(qrencode, AS_HELP_STRING([--disable-qrencode], [disable qrencode support]))
+if test "x$enable_qrencode" != "xno"; then
+        PKG_CHECK_MODULES(QRENCODE, [ libqrencode ],
+                [AC_DEFINE(HAVE_QRENCODE, 1, [Define if qrencode is available]) have_qrencode=yes], have_qrencode=no)
+        if test "x$have_qrencode" = xno -a "x$enable_qrencode" = xyes; then
+                AC_MSG_ERROR([*** qrencode support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_QRENCODE, [test "$have_qrencode" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_microhttpd=no
+AC_ARG_ENABLE(microhttpd, AS_HELP_STRING([--disable-microhttpd], [disable microhttpd support]))
+if test "x$enable_microhttpd" != "xno"; then
+        PKG_CHECK_MODULES(MICROHTTPD, [libmicrohttpd >= 0.9.5],
+                [AC_DEFINE(HAVE_MICROHTTPD, 1, [Define if microhttpd is available]) have_microhttpd=yes], have_microhttpd=no)
+        if test "x$have_microhttpd" = xno -a "x$enable_microhttpd" = xyes; then
+                AC_MSG_ERROR([*** microhttpd support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_MICROHTTPD, [test "$have_microhttpd" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_binfmt=no
+AC_ARG_ENABLE(binfmt, AS_HELP_STRING([--disable-binfmt], [disable binfmt tool]))
+if test "x$enable_binfmt" != "xno"; then
+        have_binfmt=yes
+fi
+AM_CONDITIONAL(ENABLE_BINFMT, [test "$have_binfmt" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_vconsole=no
+AC_ARG_ENABLE(vconsole, AS_HELP_STRING([--disable-vconsole], [disable vconsole tool]))
+if test "x$enable_vconsole" != "xno"; then
+        have_vconsole=yes
+fi
+AM_CONDITIONAL(ENABLE_VCONSOLE, [test "$have_vconsole" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_readahead=no
+AC_ARG_ENABLE(readahead, AS_HELP_STRING([--disable-readahead], [disable readahead tools]))
+if test "x$enable_readahead" != "xno"; then
+        have_readahead=yes
+fi
+AM_CONDITIONAL(ENABLE_READAHEAD, [test "$have_readahead" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_quotacheck=no
+AC_ARG_ENABLE(quotacheck, AS_HELP_STRING([--disable-quotacheck], [disable quotacheck tools]))
+if test "x$enable_quotacheck" != "xno"; then
+        have_quotacheck=yes
+fi
+AM_CONDITIONAL(ENABLE_QUOTACHECK, [test "$have_quotacheck" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_randomseed=no
+AC_ARG_ENABLE(randomseed, AS_HELP_STRING([--disable-randomseed], [disable randomseed tools]))
+if test "x$enable_randomseed" != "xno"; then
+        have_randomseed=yes
+fi
+AM_CONDITIONAL(ENABLE_RANDOMSEED, [test "$have_randomseed" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_logind=no
+AC_ARG_ENABLE(logind, AS_HELP_STRING([--disable-logind], [disable login daemon]))
+if test "x$enable_logind" != "xno"; then
+        have_logind=yes
+fi
+AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"])
+AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(HAVE_LOGIND, [1], [Logind support available]) ])
+
+# ------------------------------------------------------------------------------
+have_hostnamed=no
+AC_ARG_ENABLE(hostnamed, AS_HELP_STRING([--disable-hostnamed], [disable hostname daemon]))
+if test "x$enable_hostnamed" != "xno"; then
+        have_hostnamed=yes
+fi
+AM_CONDITIONAL(ENABLE_HOSTNAMED, [test "$have_hostnamed" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_timedated=no
+AC_ARG_ENABLE(timedated, AS_HELP_STRING([--disable-timedated], [disable timedate daemon]))
+if test "x$enable_timedated" != "xno"; then
+        have_timedated=yes
+fi
+AM_CONDITIONAL(ENABLE_TIMEDATED, [test "$have_timedated" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_localed=no
+AC_ARG_ENABLE(localed, AS_HELP_STRING([--disable-localed], [disable locale daemon]))
+if test "x$enable_localed" != "xno"; then
+        have_localed=yes
+fi
+AM_CONDITIONAL(ENABLE_LOCALED, [test "$have_localed" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_coredump=no
+AC_ARG_ENABLE(coredump, AS_HELP_STRING([--disable-coredump], [disable coredump hook]))
+if test "x$enable_coredump" != "xno"; then
+        have_coredump=yes
+fi
+AM_CONDITIONAL(ENABLE_COREDUMP, [test "$have_coredump" = "yes"])
+
+# ------------------------------------------------------------------------------
+AC_ARG_WITH(rc-local-script-path-start,
+        AS_HELP_STRING([--with-rc-local-script-path-start=PATH],
+                [Path to /etc/rc.local]),
+        [RC_LOCAL_SCRIPT_PATH_START="$withval"],
+        [RC_LOCAL_SCRIPT_PATH_START="/etc/rc.local"])
+
+AC_ARG_WITH(rc-local-script-path-stop,
+        AS_HELP_STRING([--with-rc-local-script-path-stop=PATH],
+                [Path to /usr/sbin/halt.local]),
+        [RC_LOCAL_SCRIPT_PATH_STOP="$withval"],
+        [RC_LOCAL_SCRIPT_PATH_STOP="/usr/sbin/halt.local"])
+
+AC_DEFINE_UNQUOTED(RC_LOCAL_SCRIPT_PATH_START, ["$RC_LOCAL_SCRIPT_PATH_START"], [Path of /etc/rc.local script])
+AC_DEFINE_UNQUOTED(RC_LOCAL_SCRIPT_PATH_STOP, ["$RC_LOCAL_SCRIPT_PATH_STOP"], [Path of /usr/sbin/halt.local script])
+
+AC_SUBST(RC_LOCAL_SCRIPT_PATH_START)
+AC_SUBST(RC_LOCAL_SCRIPT_PATH_STOP)
+
+# ------------------------------------------------------------------------------
+AC_ARG_WITH(kbd-loadkeys,
+        AS_HELP_STRING([--with-kbd-loadkeys=PATH],
+                [Path to loadkeys]),
+        [KBD_LOADKEYS="$withval"],
+        [KBD_LOADKEYS="/usr/bin/loadkeys"])
+
+AC_ARG_WITH(kbd-setfont,
+        AS_HELP_STRING([--with-kbd-setfont=PATH],
+                [Path to setfont]),
+        [KBD_SETFONT="$withval"],
+        [KBD_SETFONT="/usr/bin/setfont"])
+
+AC_DEFINE_UNQUOTED(KBD_LOADKEYS, ["$KBD_LOADKEYS"], [Path of loadkeys])
+AC_DEFINE_UNQUOTED(KBD_SETFONT, ["$KBD_SETFONT"], [Path of setfont])
+
+AC_SUBST(KBD_LOADKEYS)
+AC_SUBST(KBD_SETFONT)
+
+# ------------------------------------------------------------------------------
+AC_ARG_WITH(firmware-path,
+       AS_HELP_STRING([--with-firmware-path=DIR[[[:DIR[...]]]]],
+          [Firmware search path (default=ROOTPREFIX/lib/firmware/updates:ROOTPREFIX/lib/firmware)]),
+       [], [with_firmware_path="$rootprefix/lib/firmware/updates:$rootprefix/lib/firmware"])
+OLD_IFS=$IFS
+IFS=:
+for i in $with_firmware_path; do
+       if test "x${FIRMWARE_PATH}" = "x"; then
+              FIRMWARE_PATH="\\\"${i}/\\\""
+       else
+              FIRMWARE_PATH="${FIRMWARE_PATH}, \\\"${i}/\\\""
+       fi
+done
+IFS=$OLD_IFS
+AC_SUBST([FIRMWARE_PATH], [$FIRMWARE_PATH])
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([gudev],
+       AS_HELP_STRING([--disable-gudev], [disable Gobject libudev support @<:@default=enabled@:>@]),
+       [], [enable_gudev=yes])
+AS_IF([test "x$enable_gudev" = "xyes"], [ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.22.0 gobject-2.0 >= 2.22.0]) ])
+AM_CONDITIONAL([ENABLE_GUDEV], [test "x$enable_gudev" = "xyes"])
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([keymap],
+       AS_HELP_STRING([--disable-keymap], [disable keymap fixup support @<:@default=enabled@:>@]),
+       [], [enable_keymap=yes])
+AS_IF([test "x$enable_keymap" = "xyes"], [
+       AC_PATH_PROG([GPERF], [gperf])
+       if test -z "$GPERF"; then
+              AC_MSG_ERROR([gperf is needed])
+       fi
+
+       AC_CHECK_HEADER([linux/input.h], [:], AC_MSG_ERROR([kernel headers not found]))
+       AC_SUBST([INCLUDE_PREFIX], [$(echo '#include <linux/input.h>' | eval $ac_cpp -E - | sed -n '/linux\/input.h/ {s:.*"\(.*\)/linux/input.h".*:\1:; p; q}')])
+])
+AM_CONDITIONAL([ENABLE_KEYMAP], [test "x$enable_keymap" = "xyes"])
+
+# ------------------------------------------------------------------------------
+have_manpages=no
+AC_ARG_ENABLE(manpages, AS_HELP_STRING([--disable-manpages], [disable manpages]))
+AS_IF([test "x$enable_manpages" != xno], [
+        AS_IF([test "x$enable_manpages" = xyes -a "x$XSLTPROC" = x], [
+                AC_MSG_ERROR([*** Manpages requested but xsltproc not found])
+        ])
+        AS_IF([test "x$XSLTPROC" != x], [have_manpages=yes])
+])
+AM_CONDITIONAL(ENABLE_MANPAGES, [test "x$have_manpages" = "xyes"])
+
+# ------------------------------------------------------------------------------
+
+# Location of the init scripts as mandated by LSB
+SYSTEM_SYSVINIT_PATH=/etc/init.d
+SYSTEM_SYSVRCND_PATH=/etc/rc.d
+M4_DEFINES=
+
+AC_ARG_WITH([sysvinit-path],
+        [AS_HELP_STRING([--with-sysvinit-path=PATH],
+                [Specify the path to where the SysV init scripts are located])],
+        [SYSTEM_SYSVINIT_PATH="$withval"],
+        [])
+
+AC_ARG_WITH([sysvrcd-path],
+        [AS_HELP_STRING([--with-sysvrcd-path=PATH],
+                [Specify the path to the base directory for the SysV rcN.d directories])],
+        [SYSTEM_SYSVRCND_PATH="$withval"],
+        [])
+
+if test "x${SYSTEM_SYSVINIT_PATH}" != "x" -a "x${SYSTEM_SYSVRCND_PATH}" != "x"; then
+        AC_DEFINE(HAVE_SYSV_COMPAT, [], [SysV init scripts and rcN.d links are supported.])
+        SYSTEM_SYSV_COMPAT="yes"
+        M4_DEFINES="$M4_DEFINES -DHAVE_SYSV_COMPAT"
+elif test "x${SYSTEM_SYSVINIT_PATH}" != "x" -o "x${SYSTEM_SYSVRCND_PATH}" != "x"; then
+        AC_MSG_ERROR([*** You need both --with-sysvinit-path=PATH and --with-sysvrcd-path=PATH to enable SysV compatibility support, or both empty to disable it.])
+else
+        SYSTEM_SYSV_COMPAT="no"
+fi
+
+AC_SUBST(SYSTEM_SYSVINIT_PATH)
+AC_SUBST(SYSTEM_SYSVRCND_PATH)
+AC_SUBST(M4_DEFINES)
+
+AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes")
+
+AC_ARG_WITH([tty-gid],
+        [AS_HELP_STRING([--with-tty-gid=GID],
+                [Specify the numeric GID of the 'tty' group])],
+        [AC_DEFINE_UNQUOTED(TTY_GID, [$withval], [GID of the 'tty' group])],
+        [])
+
+AC_ARG_WITH([dbuspolicydir],
+        AS_HELP_STRING([--with-dbuspolicydir=DIR], [D-Bus policy directory]),
+        [],
+        [with_dbuspolicydir=`pkg-config --variable=sysconfdir dbus-1`/dbus-1/system.d])
+
+AC_ARG_WITH([dbussessionservicedir],
+        AS_HELP_STRING([--with-dbussessionservicedir=DIR], [D-Bus session service directory]),
+        [],
+        [with_dbussessionservicedir=`pkg-config --variable=session_bus_services_dir dbus-1`])
+
+AC_ARG_WITH([dbussystemservicedir],
+        AS_HELP_STRING([--with-dbussystemservicedir=DIR], [D-Bus system service directory]),
+        [],
+        [with_dbussystemservicedir=`pkg-config --variable=session_bus_services_dir dbus-1`/../system-services])
+
+AC_ARG_WITH([dbusinterfacedir],
+        AS_HELP_STRING([--with-dbusinterfacedir=DIR], [D-Bus interface directory]),
+        [],
+        [with_dbusinterfacedir=`pkg-config --variable=session_bus_services_dir dbus-1`/../interfaces])
+
+AC_ARG_WITH([rootprefix],
+        AS_HELP_STRING([--with-rootprefix=DIR], [rootfs directory prefix for config files and kernel modules]),
+        [], [with_rootprefix=${ac_default_prefix}])
+
+AC_ARG_WITH([rootlibdir],
+        AS_HELP_STRING([--with-rootlibdir=DIR], [Root directory for libraries necessary for boot]),
+        [],
+        [with_rootlibdir=${libdir}])
+
+AC_ARG_WITH([pamlibdir],
+        AS_HELP_STRING([--with-pamlibdir=DIR], [Directory for PAM modules]),
+        [],
+        [with_pamlibdir=${with_rootlibdir}/security])
+
+AC_ARG_ENABLE([split-usr],
+        AS_HELP_STRING([--enable-split-usr], [Assume that /bin, /sbin aren\'t symlinks into /usr]),
+        [],
+        [AS_IF([test "x${ac_default_prefix}" != "x${with_rootprefix}"], [
+                enable_split_usr=yes
+        ], [
+                enable_split_usr=no
+        ])])
+
+AS_IF([test "x${enable_split_usr}" = "xyes"], [
+        AC_DEFINE(HAVE_SPLIT_USR, 1, [Define if /bin, /sbin aren't symlinks into /usr])
+])
+
+AC_SUBST([dbuspolicydir], [$with_dbuspolicydir])
+AC_SUBST([dbussessionservicedir], [$with_dbussessionservicedir])
+AC_SUBST([dbussystemservicedir], [$with_dbussystemservicedir])
+AC_SUBST([dbusinterfacedir], [$with_dbusinterfacedir])
+AC_SUBST([pamlibdir], [$with_pamlibdir])
+AC_SUBST([rootprefix], [$with_rootprefix])
+AC_SUBST([rootlibdir], [$with_rootlibdir])
+
+AC_CONFIG_FILES([
+        Makefile po/Makefile.in
+        docs/libudev/Makefile
+        docs/libudev/version.xml
+        docs/gudev/Makefile
+        docs/gudev/version.xml
+])
+
+AC_OUTPUT
+AC_MSG_RESULT([
+        $PACKAGE_NAME $VERSION
+
+        libcryptsetup:           ${have_libcryptsetup}
+        tcpwrap:                 ${have_tcpwrap}
+        PAM:                     ${have_pam}
+        AUDIT:                   ${have_audit}
+        IMA:                     ${have_ima}
+        SELinux:                 ${have_selinux}
+        XZ:                      ${have_xz}
+        ACL:                     ${have_acl}
+        XATTR:                   ${have_xattr}
+        GCRYPT:                  ${have_gcrypt}
+        QRENCODE:                ${have_qrencode}
+        MICROHTTPD:              ${have_microhttpd}
+        CHKCONFIG:               ${have_chkconfig}
+        binfmt:                  ${have_binfmt}
+        vconsole:                ${have_vconsole}
+        readahead:               ${have_readahead}
+        quotacheck:              ${have_quotacheck}
+        randomseed:              ${have_randomseed}
+        logind:                  ${have_logind}
+        hostnamed:               ${have_hostnamed}
+        timedated:               ${have_timedated}
+        localed:                 ${have_localed}
+        coredump:                ${have_coredump}
+        kmod:                    ${have_kmod}
+        blkid:                   ${have_blkid}
+        gudev:                   ${enable_gudev}
+        gintrospection:          ${enable_introspection}
+        keymap:                  ${enable_keymap}
+        Python:                  ${have_python}
+        Python Headers:          ${have_python_devel}
+        man pages:               ${have_manpages}
+        gtk-doc:                 ${enable_gtk_doc}
+        Split /usr:              ${enable_split_usr}
+        SysV compatibility:      ${SYSTEM_SYSV_COMPAT}
+
+        prefix:                  ${prefix}
+        rootprefix:              ${with_rootprefix}
+        sysconf dir:             ${sysconfdir}
+        datarootdir:             ${datarootdir}
+        includedir:              ${includedir}
+        include_prefix:          ${INCLUDE_PREFIX}
+        lib dir:                 ${libdir}
+        rootlib dir:             ${with_rootlibdir}
+        SysV init scripts:       ${SYSTEM_SYSVINIT_PATH}
+        SysV rc?.d directories:  ${SYSTEM_SYSVRCND_PATH}
+        Build Python:            ${PYTHON}
+        Installation Python:     ${PYTHON_BINARY}
+        firmware path:           ${FIRMWARE_PATH}
+        PAM modules dir:         ${with_pamlibdir}
+        D-Bus policy dir:        ${with_dbuspolicydir}
+        D-Bus session dir:       ${with_dbussessionservicedir}
+        D-Bus system dir:        ${with_dbussystemservicedir}
+        D-Bus interfaces dir:    ${with_dbusinterfacedir}
+        Extra start script:      ${RC_LOCAL_SCRIPT_PATH_START}
+        Extra stop script:       ${RC_LOCAL_SCRIPT_PATH_STOP}
+
+        CFLAGS:                  ${OUR_CFLAGS} ${CFLAGS}
+        CPPLAGS:                 ${OUR_CPPFLAGS} ${CPPFLAGS}
+        LDFLAGS:                 ${OUR_LDFLAGS} ${LDFLAGS}
+        PYTHON_CFLAGS:           ${PYTHON_CFLAGS}
+        PYTHON_LIBS:             ${PYTHON_LIBS}
+])
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644 (file)
index 0000000..e9fed44
--- /dev/null
@@ -0,0 +1 @@
+/gtk-doc.make
diff --git a/docs/Makefile b/docs/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/docs/gudev/.gitignore b/docs/gudev/.gitignore
new file mode 100644 (file)
index 0000000..e6f2371
--- /dev/null
@@ -0,0 +1,19 @@
+/*.bak
+/gtk-doc.make
+/version.xml
+/Makefile
+/gudev-overrides.txt
+/gudev-decl-list.txt
+/gudev-decl.txt
+/gudev-undeclared.txt
+/gudev-undocumented.txt
+/gudev-unused.txt
+/gudev.args
+/gudev.hierarchy
+/gudev.interfaces
+/gudev.prerequisites
+/gudev.signals
+/html/
+/xml/
+/*.stamp
+/tmpl/
diff --git a/docs/gudev/Makefile.am b/docs/gudev/Makefile.am
new file mode 100644 (file)
index 0000000..26c8652
--- /dev/null
@@ -0,0 +1,113 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.10 at least.
+AUTOMAKE_OPTIONS = 1.10 color-tests
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=gudev
+
+# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
+#DOC_MODULE_VERSION=2
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=$(top_srcdir)/src/gudev $(top_builddir)/src/gudev
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--xml-mode --output-format=xml --name-space=g_udev
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkhtml
+MKHTML_OPTIONS=--path=$(abs_srcdir) --path=$(abs_builddir)
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=>/dev/null 2>&1
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/src/gudev/*.h
+CFILE_GLOB=$(top_srcdir)/src/gudev/*.c
+
+# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
+# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
+EXTRA_HFILES=
+
+# Header files to ignore when scanning. Use base file name, no paths
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=gudevenumtypes.h gudevmarshal.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files = version.xml
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# Hack, hack. You silly gtk-doc, you must not add  CFLAGS multiple
+# times when calling gcc; it surely can not work with options that must
+# be listed only once.
+# Kill CFLAGS here because gtk-doc thinks adding CFLAGS to CC _and_ also
+# adding CFLAGS itself again would work.
+override CFLAGS=
+override LDFLAGS=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+GTKDOC_CFLAGS = \
+       $(GLIB_CFLAGS) \
+       -I$(top_srcdir)/src/gudev \
+       -I$(top_builddir)/src/gudev
+
+GTKDOC_LIBS = \
+       $(GLIB_LIBS) \
+       $(top_builddir)/libgudev-1.0.la
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/docs/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST += version.xml.in
+
+# Files not to distribute
+# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
+# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
+#DISTCLEANFILES +=
+
+# Comment this out if you want your docs-status tested during 'make check'
+if ENABLE_GTK_DOC
+TESTS_ENVIRONMENT = cd $(top_srcdir)
+TESTS = $(GTKDOC_CHECK)
+endif
diff --git a/docs/gudev/gudev-docs.xml b/docs/gudev/gudev-docs.xml
new file mode 100644 (file)
index 0000000..3e7e50a
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+  <bookinfo>
+    <title>GUdev Reference Manual</title>
+    <releaseinfo>
+       For version &version; — the latest version of this
+       documentation can be found at
+       <ulink role="online-location" url="http://www.freedesktop.org/software/systemd/gudev/">
+         http://www.freedesktop.org/software/systemd/gudev/
+       </ulink>.
+    </releaseinfo>
+    <copyright>
+      <year>2009-2012</year>
+      <holder>David Zeuthen &lt;davidz@redhat.com&gt;</holder>
+      <holder>Bastien Nocera &lt;hadess@hadess.net&gt;</holder>
+    </copyright>
+  </bookinfo>
+
+  <chapter id="ref-API">
+    <title>API Reference</title>
+    <xi:include href="xml/gudevclient.xml"/>
+    <xi:include href="xml/gudevdevice.xml"/>
+    <xi:include href="xml/gudevenumerator.xml"/>
+  </chapter>
+
+  <chapter id="gudev-hierarchy">
+    <title>Object Hierarchy</title>
+      <xi:include href="xml/tree_index.sgml"/>
+  </chapter>
+
+  <index id="api-index-full">
+    <title>API Index</title>
+      <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+  </index>
+
+  <index role="165">
+    <title>Index of new symbols in 165</title>
+    <xi:include href="xml/api-index-165.xml"><xi:fallback /></xi:include>
+  </index>
+
+  <index id="api-index-deprecated" role="deprecated">
+    <title>Index of deprecated API</title>
+       <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+  </index>
+
+  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+</book>
diff --git a/docs/gudev/gudev-sections.txt b/docs/gudev/gudev-sections.txt
new file mode 100644 (file)
index 0000000..b25c13b
--- /dev/null
@@ -0,0 +1,100 @@
+<SECTION>
+<FILE>gudevclient</FILE>
+<TITLE>GUdevClient</TITLE>
+GUdevClient
+GUdevClientClass
+GUdevDeviceType
+GUdevDeviceNumber
+g_udev_client_new
+g_udev_client_query_by_subsystem
+g_udev_client_query_by_device_number
+g_udev_client_query_by_device_file
+g_udev_client_query_by_sysfs_path
+g_udev_client_query_by_subsystem_and_name
+<SUBSECTION Standard>
+G_UDEV_CLIENT
+G_UDEV_IS_CLIENT
+G_UDEV_TYPE_CLIENT
+g_udev_client_get_type
+G_UDEV_CLIENT_CLASS
+G_UDEV_IS_CLIENT_CLASS
+G_UDEV_CLIENT_GET_CLASS
+<SUBSECTION Private>
+GUdevClientPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gudevdevice</FILE>
+<TITLE>GUdevDevice</TITLE>
+GUdevDevice
+GUdevDeviceClass
+g_udev_device_get_subsystem
+g_udev_device_get_devtype
+g_udev_device_get_name
+g_udev_device_get_number
+g_udev_device_get_sysfs_path
+g_udev_device_get_driver
+g_udev_device_get_action
+g_udev_device_get_seqnum
+g_udev_device_get_device_type
+g_udev_device_get_device_number
+g_udev_device_get_device_file
+g_udev_device_get_device_file_symlinks
+g_udev_device_get_parent
+g_udev_device_get_parent_with_subsystem
+g_udev_device_get_tags
+g_udev_device_get_is_initialized
+g_udev_device_get_usec_since_initialized
+g_udev_device_get_property_keys
+g_udev_device_has_property
+g_udev_device_get_property
+g_udev_device_get_property_as_int
+g_udev_device_get_property_as_uint64
+g_udev_device_get_property_as_double
+g_udev_device_get_property_as_boolean
+g_udev_device_get_property_as_strv
+g_udev_device_get_sysfs_attr
+g_udev_device_get_sysfs_attr_as_int
+g_udev_device_get_sysfs_attr_as_uint64
+g_udev_device_get_sysfs_attr_as_double
+g_udev_device_get_sysfs_attr_as_boolean
+g_udev_device_get_sysfs_attr_as_strv
+<SUBSECTION Standard>
+G_UDEV_DEVICE
+G_UDEV_IS_DEVICE
+G_UDEV_TYPE_DEVICE
+g_udev_device_get_type
+G_UDEV_DEVICE_CLASS
+G_UDEV_IS_DEVICE_CLASS
+G_UDEV_DEVICE_GET_CLASS
+<SUBSECTION Private>
+GUdevDevicePrivate
+</SECTION>
+
+<SECTION>
+<FILE>gudevenumerator</FILE>
+<TITLE>GUdevEnumerator</TITLE>
+GUdevEnumerator
+GUdevEnumeratorClass
+g_udev_enumerator_new
+g_udev_enumerator_add_match_subsystem
+g_udev_enumerator_add_nomatch_subsystem
+g_udev_enumerator_add_match_sysfs_attr
+g_udev_enumerator_add_nomatch_sysfs_attr
+g_udev_enumerator_add_match_property
+g_udev_enumerator_add_match_name
+g_udev_enumerator_add_match_tag
+g_udev_enumerator_add_match_is_initialized
+g_udev_enumerator_add_sysfs_path
+g_udev_enumerator_execute
+<SUBSECTION Standard>
+G_UDEV_ENUMERATOR
+G_UDEV_IS_ENUMERATOR
+G_UDEV_TYPE_ENUMERATOR
+g_udev_enumerator_get_type
+G_UDEV_ENUMERATOR_CLASS
+G_UDEV_IS_ENUMERATOR_CLASS
+G_UDEV_ENUMERATOR_GET_CLASS
+<SUBSECTION Private>
+GUdevEnumeratorPrivate
+</SECTION>
diff --git a/docs/gudev/gudev.types b/docs/gudev/gudev.types
new file mode 100644 (file)
index 0000000..a89857a
--- /dev/null
@@ -0,0 +1,4 @@
+g_udev_device_type_get_type
+g_udev_device_get_type
+g_udev_client_get_type
+g_udev_enumerator_get_type
diff --git a/docs/gudev/version.xml.in b/docs/gudev/version.xml.in
new file mode 100644 (file)
index 0000000..d78bda9
--- /dev/null
@@ -0,0 +1 @@
+@VERSION@
diff --git a/docs/libudev/.gitignore b/docs/libudev/.gitignore
new file mode 100644 (file)
index 0000000..f8dd67c
--- /dev/null
@@ -0,0 +1,19 @@
+/gtk-doc.make
+/version.xml
+/Makefile
+/libudev-overrides.txt
+/libudev-decl-list.txt
+/libudev-decl.txt
+/libudev-undeclared.txt
+/libudev-undocumented.txt
+/libudev-unused.txt
+/libudev.args
+/libudev.hierarchy
+/libudev.interfaces
+/libudev.prerequisites
+/libudev.signals
+/html/
+/xml/
+/*.stamp
+/*.bak
+/tmpl/
diff --git a/docs/libudev/Makefile.am b/docs/libudev/Makefile.am
new file mode 100644 (file)
index 0000000..87196e8
--- /dev/null
@@ -0,0 +1,107 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.10 at least.
+AUTOMAKE_OPTIONS = 1.10 color-tests
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=libudev
+
+# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
+#DOC_MODULE_VERSION=2
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=$(top_srcdir)/src/libudev
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--xml-mode --output-format=xml --name-space=udev
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkhtml
+MKHTML_OPTIONS=--path=$(abs_srcdir) --path=$(abs_builddir)
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=>/dev/null 2>&1
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/src/libudev/libudev*.h
+CFILE_GLOB=$(top_srcdir)/src/libudev/libudev*.c
+
+# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
+# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
+EXTRA_HFILES=
+
+# Header files to ignore when scanning. Use base file name, no paths
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES = libudev-private.h libudev-hwdb-def.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files = version.xml
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# Hack, hack. You silly gtk-doc, you must not add  CFLAGS multiple
+# times when calling gcc; it surely can not work with options that must
+# be listed only once.
+# Kill CFLAGS here because gtk-doc thinks adding CFLAGS to CC _and_ also
+# adding CFLAGS itself again would work.
+override CFLAGS=
+override LDFLAGS=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+GTKDOC_CFLAGS=
+GTKDOC_LIBS=
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/docs/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST += version.xml.in
+
+# Files not to distribute
+# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
+# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
+#DISTCLEANFILES +=
+
+# Comment this out if you want your docs-status tested during 'make check'
+if ENABLE_GTK_DOC
+TESTS_ENVIRONMENT = cd $(top_srcdir)
+TESTS = $(GTKDOC_CHECK)
+endif
diff --git a/docs/libudev/libudev-docs.xml b/docs/libudev/libudev-docs.xml
new file mode 100644 (file)
index 0000000..454cd31
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+  <bookinfo>
+    <title>libudev Reference Manual</title>
+    <releaseinfo>
+       For version &version; — the latest version of this
+       documentation can be found at
+       <ulink role="online-location" url="http://www.freedesktop.org/software/systemd/libudev/">
+         http://www.freedesktop.org/software/systemd/libudev/
+       </ulink>.
+    </releaseinfo>
+    <copyright>
+      <year>2009-2012</year>
+      <holder>Kay Sievers &lt;kay@vrfy.org&gt;</holder>
+    </copyright>
+  </bookinfo>
+
+  <chapter>
+    <title>API Reference</title>
+    <xi:include href="xml/libudev.xml"/>
+    <xi:include href="xml/libudev-list.xml"/>
+    <xi:include href="xml/libudev-device.xml"/>
+    <xi:include href="xml/libudev-monitor.xml"/>
+    <xi:include href="xml/libudev-enumerate.xml"/>
+    <xi:include href="xml/libudev-queue.xml"/>
+    <xi:include href="xml/libudev-hwdb.xml"/>
+    <xi:include href="xml/libudev-util.xml"/>
+    <xi:include href="xml/api-index-deprecated.xml"/>
+  </chapter>
+
+  <index id="api-index-full">
+    <title>Index</title>
+    <xi:include href="xml/api-index-full.xml"/>
+  </index>
+</book>
diff --git a/docs/libudev/libudev-sections.txt b/docs/libudev/libudev-sections.txt
new file mode 100644 (file)
index 0000000..067a3f5
--- /dev/null
@@ -0,0 +1,134 @@
+<SECTION>
+<FILE>libudev</FILE>
+<TITLE>udev</TITLE>
+udev
+udev_ref
+udev_unref
+udev_new
+udev_set_log_fn
+udev_get_log_priority
+udev_set_log_priority
+udev_get_userdata
+udev_set_userdata
+</SECTION>
+
+<SECTION>
+<FILE>libudev-list</FILE>
+<TITLE>udev_list</TITLE>
+udev_list_entry
+udev_list_entry_get_next
+udev_list_entry_get_by_name
+udev_list_entry_get_name
+udev_list_entry_get_value
+udev_list_entry_foreach
+</SECTION>
+
+<SECTION>
+<FILE>libudev-device</FILE>
+<TITLE>udev_device</TITLE>
+udev_device
+udev_device_ref
+udev_device_unref
+udev_device_get_udev
+udev_device_new_from_syspath
+udev_device_new_from_devnum
+udev_device_new_from_subsystem_sysname
+udev_device_new_from_device_id
+udev_device_new_from_environment
+udev_device_get_parent
+udev_device_get_parent_with_subsystem_devtype
+udev_device_get_devpath
+udev_device_get_subsystem
+udev_device_get_devtype
+udev_device_get_syspath
+udev_device_get_sysname
+udev_device_get_sysnum
+udev_device_get_devnode
+udev_device_get_is_initialized
+udev_device_get_devlinks_list_entry
+udev_device_get_properties_list_entry
+udev_device_get_tags_list_entry
+udev_device_get_property_value
+udev_device_get_driver
+udev_device_get_devnum
+udev_device_get_action
+udev_device_get_sysattr_value
+udev_device_get_sysattr_list_entry
+udev_device_get_seqnum
+udev_device_get_usec_since_initialized
+udev_device_has_tag
+</SECTION>
+
+<SECTION>
+<FILE>libudev-monitor</FILE>
+<TITLE>udev_monitor</TITLE>
+udev_monitor
+udev_monitor_ref
+udev_monitor_unref
+udev_monitor_get_udev
+udev_monitor_new_from_netlink
+udev_monitor_enable_receiving
+udev_monitor_set_receive_buffer_size
+udev_monitor_get_fd
+udev_monitor_receive_device
+udev_monitor_filter_add_match_subsystem_devtype
+udev_monitor_filter_add_match_tag
+udev_monitor_filter_update
+udev_monitor_filter_remove
+</SECTION>
+
+<SECTION>
+<FILE>libudev-enumerate</FILE>
+<TITLE>udev_enumerate</TITLE>
+udev_enumerate
+udev_enumerate_ref
+udev_enumerate_unref
+udev_enumerate_get_udev
+udev_enumerate_new
+udev_enumerate_add_match_subsystem
+udev_enumerate_add_nomatch_subsystem
+udev_enumerate_add_match_sysattr
+udev_enumerate_add_nomatch_sysattr
+udev_enumerate_add_match_property
+udev_enumerate_add_match_tag
+udev_enumerate_add_match_parent
+udev_enumerate_add_match_is_initialized
+udev_enumerate_add_match_sysname
+udev_enumerate_add_syspath
+udev_enumerate_scan_devices
+udev_enumerate_scan_subsystems
+udev_enumerate_get_list_entry
+</SECTION>
+
+<SECTION>
+<FILE>libudev-queue</FILE>
+<TITLE>udev_queue</TITLE>
+udev_queue
+udev_queue_ref
+udev_queue_unref
+udev_queue_get_udev
+udev_queue_new
+udev_queue_get_udev_is_active
+udev_queue_get_queue_is_empty
+udev_queue_get_seqnum_is_finished
+udev_queue_get_seqnum_sequence_is_finished
+udev_queue_get_queued_list_entry
+udev_queue_get_kernel_seqnum
+udev_queue_get_udev_seqnum
+</SECTION>
+
+<SECTION>
+<FILE>libudev-hwdb</FILE>
+<TITLE>udev_hwdb</TITLE>
+udev_hwdb
+udev_hwdb_ref
+udev_hwdb_unref
+udev_hwdb_new
+udev_hwdb_get_properties_list_entry
+</SECTION>
+
+<SECTION>
+<FILE>libudev-util</FILE>
+<TITLE>udev_util</TITLE>
+udev_util_encode_string
+</SECTION>
diff --git a/docs/libudev/libudev.types b/docs/libudev/libudev.types
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs/libudev/version.xml.in b/docs/libudev/version.xml.in
new file mode 100644 (file)
index 0000000..d78bda9
--- /dev/null
@@ -0,0 +1 @@
+@VERSION@
diff --git a/docs/sysvinit/.gitignore b/docs/sysvinit/.gitignore
new file mode 100644 (file)
index 0000000..c3fea74
--- /dev/null
@@ -0,0 +1 @@
+/README
diff --git a/docs/sysvinit/Makefile b/docs/sysvinit/Makefile
new file mode 120000 (symlink)
index 0000000..50be211
--- /dev/null
@@ -0,0 +1 @@
+../../src/Makefile
\ No newline at end of file
diff --git a/docs/sysvinit/README.in b/docs/sysvinit/README.in
new file mode 100644 (file)
index 0000000..996402d
--- /dev/null
@@ -0,0 +1,27 @@
+You are looking for the traditional init scripts in @SYSTEM_SYSVINIT_PATH@,
+and they are gone?
+
+Here's an explanation on what's going on:
+
+You are running a systemd-based OS where traditional init scripts have
+been replaced by native systemd services files. Service files provide
+very similar functionality to init scripts. To make use of service
+files simply invoke "systemctl", which will output a list of all
+currently running services (and other units). Use "systemctl
+list-unit-files" to get a listing of all known unit files, including
+stopped, disabled and masked ones. Use "systemctl start
+foobar.service" and "systemctl stop foobar.service" to start or stop a
+service, respectively. For further details, please refer to
+systemctl(1).
+
+Note that traditional init scripts continue to function on a systemd
+system. An init script @SYSTEM_SYSVINIT_PATH@/foobar is implicitly mapped
+into a service unit foobar.service during system initialization.
+
+Thank you!
+
+Further reading:
+        man:systemctl(1)
+        man:systemd(1)
+        http://0pointer.de/blog/projects/systemd-for-admins-3.html
+        http://www.freedesktop.org/wiki/Software/systemd/Incompatibilities
diff --git a/docs/var-log/.gitignore b/docs/var-log/.gitignore
new file mode 100644 (file)
index 0000000..c3fea74
--- /dev/null
@@ -0,0 +1 @@
+/README
diff --git a/docs/var-log/Makefile b/docs/var-log/Makefile
new file mode 120000 (symlink)
index 0000000..50be211
--- /dev/null
@@ -0,0 +1 @@
+../../src/Makefile
\ No newline at end of file
diff --git a/docs/var-log/README.in b/docs/var-log/README.in
new file mode 100644 (file)
index 0000000..2e64fb1
--- /dev/null
@@ -0,0 +1,26 @@
+You are looking for the traditional text log files in @VARLOGDIR@, and
+they are gone?
+
+Here's an explanation on what's going on:
+
+You are running a systemd-based OS where traditional syslog has been
+replaced with the Journal. The journal stores the same (and more)
+information as classic syslog. To make use of the journal and access
+the collected log data simply invoke "journalctl", which will output
+the logs in the identical text-based format the syslog files in
+@VARLOGDIR@ used to be. For further details, please refer to
+journalctl(1).
+
+Alternatively, consider installing one of the traditional syslog
+implementations available for your distribution, which will generate
+the classic log files for you. Syslog implementations such as
+syslog-ng or rsyslog may be installed side-by-side with the journal
+and will continue to function the way they always did.
+
+Thank you!
+
+Further reading:
+        man:journalctl(1)
+        man:systemd-journald.service(8)
+        man:journald.conf(5)
+        http://0pointer.de/blog/projects/the-journal.html
diff --git a/hwdb/.gitignore b/hwdb/.gitignore
new file mode 100644 (file)
index 0000000..a29233b
--- /dev/null
@@ -0,0 +1,4 @@
+/pci.ids
+/usb.ids
+/oui.txt
+/iab.txt
diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb
new file mode 100644 (file)
index 0000000..be98198
--- /dev/null
@@ -0,0 +1,64139 @@
+# This file is part of systemd.
+#
+# Data imported from:
+#   http://standards.ieee.org/develop/regauth/oui/oui.txt
+#   http://standards.ieee.org/develop/regauth/iab/iab.txt
+
+OUI:0050C2000*
+ ID_OUI_FROM_DATABASE=T.L.S. Corp.
+
+OUI:0050C2001*
+ ID_OUI_FROM_DATABASE=JMBS Developpements
+
+OUI:0050C2002*
+ ID_OUI_FROM_DATABASE=Integrated Automation Solutions
+
+OUI:0050C2003*
+ ID_OUI_FROM_DATABASE=Microsoft
+
+OUI:0050C2004*
+ ID_OUI_FROM_DATABASE=SCI Technology Inc.
+
+OUI:0050C2005*
+ ID_OUI_FROM_DATABASE=GD California, Inc.
+
+OUI:0050C2006*
+ ID_OUI_FROM_DATABASE=Project Management Enterprises, Inc.
+
+OUI:0050C2007*
+ ID_OUI_FROM_DATABASE=Clive Green & Co. Ltd.
+
+OUI:0050C2008*
+ ID_OUI_FROM_DATABASE=Portable Add-Ons
+
+OUI:0050C2009*
+ ID_OUI_FROM_DATABASE=Datakinetics Ltd.
+
+OUI:0050C200A*
+ ID_OUI_FROM_DATABASE=Tharsys
+
+OUI:0050C200B*
+ ID_OUI_FROM_DATABASE=IO Limited
+
+OUI:0050C200C*
+ ID_OUI_FROM_DATABASE=Vbrick Systems Inc.
+
+OUI:0050C200D*
+ ID_OUI_FROM_DATABASE=Opus Telecom Inc.
+
+OUI:0050C200E*
+ ID_OUI_FROM_DATABASE=TTTech
+
+OUI:0050C200F*
+ ID_OUI_FROM_DATABASE=XLN-t
+
+OUI:0050C2010*
+ ID_OUI_FROM_DATABASE=Moisture Systems
+
+OUI:0050C2011*
+ ID_OUI_FROM_DATABASE=BIHL & Wiedemann GmbH
+
+OUI:0050C2012*
+ ID_OUI_FROM_DATABASE=Floware System Solutions Ltd.
+
+OUI:0050C2013*
+ ID_OUI_FROM_DATABASE=Sensys Technologies Inc.
+
+OUI:0050C2014*
+ ID_OUI_FROM_DATABASE=Canal +
+
+OUI:0050C2015*
+ ID_OUI_FROM_DATABASE=Leroy Automatique Industrielle
+
+OUI:0050C2016*
+ ID_OUI_FROM_DATABASE=DSP Design Ltd.
+
+OUI:0050C2017*
+ ID_OUI_FROM_DATABASE=Hunter Technology Inc.
+
+OUI:0050C2018*
+ ID_OUI_FROM_DATABASE=CAD-UL GmbH
+
+OUI:0050C2019*
+ ID_OUI_FROM_DATABASE=Emtac Technology Corp.
+
+OUI:0050C201A*
+ ID_OUI_FROM_DATABASE=Skylake Talix
+
+OUI:0050C201B*
+ ID_OUI_FROM_DATABASE=Cross Products Ltd.
+
+OUI:0050C201C*
+ ID_OUI_FROM_DATABASE=Tadiran Scopus
+
+OUI:0050C201D*
+ ID_OUI_FROM_DATABASE=Princeton Gamma Tech
+
+OUI:0050C201E*
+ ID_OUI_FROM_DATABASE=CallTech International Limited
+
+OUI:0050C201F*
+ ID_OUI_FROM_DATABASE=KBS Industrieelektronik GmbH
+
+OUI:0050C2020*
+ ID_OUI_FROM_DATABASE=Icon Research Ltd.
+
+OUI:0050C2021*
+ ID_OUI_FROM_DATABASE=DRS Technologies Canada Co.
+
+OUI:0050C2022*
+ ID_OUI_FROM_DATABASE=Ashling Microsystems Ltd.
+
+OUI:0050C2023*
+ ID_OUI_FROM_DATABASE=Zabacom, Inc.
+
+OUI:0050C2024*
+ ID_OUI_FROM_DATABASE=IPITEK
+
+OUI:0050C2025*
+ ID_OUI_FROM_DATABASE=Teracom Telematica Ltda.
+
+OUI:0050C2026*
+ ID_OUI_FROM_DATABASE=Abatis Systems Corp.
+
+OUI:0050C2027*
+ ID_OUI_FROM_DATABASE=Industrial Control Links
+
+OUI:0050C2028*
+ ID_OUI_FROM_DATABASE=The Frensch Corporation (Pty) Ltd.
+
+OUI:0050C2029*
+ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
+
+OUI:0050C202A*
+ ID_OUI_FROM_DATABASE=VersaLogic Corp.
+
+OUI:0050C202B*
+ ID_OUI_FROM_DATABASE=Nova Engineering Inc.
+
+OUI:0050C202C*
+ ID_OUI_FROM_DATABASE=Narrowband Telecommunications
+
+OUI:0050C202D*
+ ID_OUI_FROM_DATABASE=Innocor LTD
+
+OUI:0050C202E*
+ ID_OUI_FROM_DATABASE=Turtle Mountain Corp
+
+OUI:0050C202F*
+ ID_OUI_FROM_DATABASE=Sinetica Corp
+
+OUI:0050C2030*
+ ID_OUI_FROM_DATABASE=Lockheed Martin Tactical Defense Systems Eagan
+
+OUI:0050C2031*
+ ID_OUI_FROM_DATABASE=Eloquence Ltd
+
+OUI:0050C2032*
+ ID_OUI_FROM_DATABASE=MotionIO
+
+OUI:0050C2033*
+ ID_OUI_FROM_DATABASE=Doble Engineering Company
+
+OUI:0050C2034*
+ ID_OUI_FROM_DATABASE=Ing. Buero W. Kanis GmbH
+
+OUI:0050C2035*
+ ID_OUI_FROM_DATABASE=Alliant Techsystems, Inc.
+
+OUI:0050C2036*
+ ID_OUI_FROM_DATABASE=Arcturus Networks Inc.
+
+OUI:0050C2037*
+ ID_OUI_FROM_DATABASE=E.I.S.M.
+
+OUI:0050C2038*
+ ID_OUI_FROM_DATABASE=Ardmona Foods Limites
+
+OUI:0050C2039*
+ ID_OUI_FROM_DATABASE=Apex Signal Corp
+
+OUI:0050C203A*
+ ID_OUI_FROM_DATABASE=PLLB Elettronica SPA
+
+OUI:0050C203B*
+ ID_OUI_FROM_DATABASE=VNR Electronique SA
+
+OUI:0050C203C*
+ ID_OUI_FROM_DATABASE=BrainBoxes Ltd
+
+OUI:0050C203D*
+ ID_OUI_FROM_DATABASE=ISDN Gateway Technology AG
+
+OUI:0050C203E*
+ ID_OUI_FROM_DATABASE=MSU UK Ltd
+
+OUI:0050C203F*
+ ID_OUI_FROM_DATABASE=Celotek Corp
+
+OUI:0050C2040*
+ ID_OUI_FROM_DATABASE=MiSPO Co., Ltd.
+
+OUI:0050C2041*
+ ID_OUI_FROM_DATABASE=Damler Chrysler Rail System (Signal) AB
+
+OUI:0050C2042*
+ ID_OUI_FROM_DATABASE=B.E.A.R. Solutions (Australasia) Pty, Ltd
+
+OUI:0050C2043*
+ ID_OUI_FROM_DATABASE=Curtis, Inc.
+
+OUI:0050C2045*
+ ID_OUI_FROM_DATABASE=Chase Manhattan Bank
+
+OUI:0050C2047*
+ ID_OUI_FROM_DATABASE=B. R. Electronics
+
+OUI:0050C2048*
+ ID_OUI_FROM_DATABASE=Cybectec Inc.
+
+OUI:0050C2049*
+ ID_OUI_FROM_DATABASE=Computer Concepts Corp
+
+OUI:0050C204A*
+ ID_OUI_FROM_DATABASE=Telecom Analysis Systems, LP
+
+OUI:0050C204B*
+ ID_OUI_FROM_DATABASE=Tecstar Demo Systems Division
+
+OUI:0050C204C*
+ ID_OUI_FROM_DATABASE=New Standard Engineering NV
+
+OUI:0050C204E*
+ ID_OUI_FROM_DATABASE=Industrial Electronic Engineers, Inc.
+
+OUI:0050C204F*
+ ID_OUI_FROM_DATABASE=Luma Corporation
+
+OUI:0050C2050*
+ ID_OUI_FROM_DATABASE=Dataprobe, Inc.
+
+OUI:0050C2051*
+ ID_OUI_FROM_DATABASE=JSR Ultrasonics
+
+OUI:0050C2052*
+ ID_OUI_FROM_DATABASE=Mayo Foundation
+
+OUI:0050C2054*
+ ID_OUI_FROM_DATABASE=Optionexist Limited
+
+OUI:0050C2055*
+ ID_OUI_FROM_DATABASE=San Castle Technologies, Inc.
+
+OUI:0050C2056*
+ ID_OUI_FROM_DATABASE=Base 2
+
+OUI:0050C2057*
+ ID_OUI_FROM_DATABASE=Lite F GmBH
+
+OUI:0050C2058*
+ ID_OUI_FROM_DATABASE=Vision Research, Inc.
+
+OUI:0050C2059*
+ ID_OUI_FROM_DATABASE=Austco Communication Systems Pty, Ltd
+
+OUI:0050C205A*
+ ID_OUI_FROM_DATABASE=Sonifex Ltd
+
+OUI:0050C205B*
+ ID_OUI_FROM_DATABASE=Radiometer Medical A/S
+
+OUI:0050C205C*
+ ID_OUI_FROM_DATABASE=Nortel Networks PLC (UK)
+
+OUI:0050C205D*
+ ID_OUI_FROM_DATABASE=Ignitus Communications, LLC
+
+OUI:0050C205E*
+ ID_OUI_FROM_DATABASE=DIVA Systems
+
+OUI:0050C205F*
+ ID_OUI_FROM_DATABASE=Malden Electronics Ltd
+
+OUI:0050C2061*
+ ID_OUI_FROM_DATABASE=Simple Network Magic Corporation
+
+OUI:0050C2063*
+ ID_OUI_FROM_DATABASE=Ticketmaster Corp
+
+OUI:0050C2065*
+ ID_OUI_FROM_DATABASE=Clever Devices, Ltd.
+
+OUI:0050C2067*
+ ID_OUI_FROM_DATABASE=Riverlink Computers, Ltd.
+
+OUI:0050C2068*
+ ID_OUI_FROM_DATABASE=Seabridge
+
+OUI:0050C2069*
+ ID_OUI_FROM_DATABASE=EC Elettronica S.R.L.
+
+OUI:0050C206A*
+ ID_OUI_FROM_DATABASE=Unimark
+
+OUI:0050C206B*
+ ID_OUI_FROM_DATABASE=NCast Corporation
+
+OUI:0050C206C*
+ ID_OUI_FROM_DATABASE=WaveCom Electronics, Inc.
+
+OUI:0050C206D*
+ ID_OUI_FROM_DATABASE=Advanced Signal Corp.
+
+OUI:0050C206E*
+ ID_OUI_FROM_DATABASE=Avtron Manufacturing Inc.
+
+OUI:0050C206F*
+ ID_OUI_FROM_DATABASE=Digital Services Group
+
+OUI:0050C2070*
+ ID_OUI_FROM_DATABASE=Katchall Technologies Group
+
+OUI:0050C2071*
+ ID_OUI_FROM_DATABASE=NetVision Telecom
+
+OUI:0050C2072*
+ ID_OUI_FROM_DATABASE=Neuberger Gebaeudeautomation GmbH & Co.
+
+OUI:0050C2073*
+ ID_OUI_FROM_DATABASE=Alstom Signalling Ltd.
+
+OUI:0050C2074*
+ ID_OUI_FROM_DATABASE=Edge Tech Co., Ltd.
+
+OUI:0050C2075*
+ ID_OUI_FROM_DATABASE=ENTTEC Pty Ltd.
+
+OUI:0050C2076*
+ ID_OUI_FROM_DATABASE=Litton Guidance & Control Systems
+
+OUI:0050C2077*
+ ID_OUI_FROM_DATABASE=Saco Smartvision Inc.
+
+OUI:0050C2078*
+ ID_OUI_FROM_DATABASE=Reselec AG
+
+OUI:0050C2079*
+ ID_OUI_FROM_DATABASE=Flextel S.p.A
+
+OUI:0050C207A*
+ ID_OUI_FROM_DATABASE=RadioTel
+
+OUI:0050C207B*
+ ID_OUI_FROM_DATABASE=Trikon Technologies Ltd.
+
+OUI:0050C207C*
+ ID_OUI_FROM_DATABASE=PLLB elettronica spa
+
+OUI:0050C207D*
+ ID_OUI_FROM_DATABASE=Caspian Networks
+
+OUI:0050C207E*
+ ID_OUI_FROM_DATABASE=JL-teknik
+
+OUI:0050C207F*
+ ID_OUI_FROM_DATABASE=Dunti Corporation
+
+OUI:0050C2080*
+ ID_OUI_FROM_DATABASE=AIM
+
+OUI:0050C2081*
+ ID_OUI_FROM_DATABASE=Matuschek Messtechnik GmbH
+
+OUI:0050C2082*
+ ID_OUI_FROM_DATABASE=GFI Chrono Time
+
+OUI:0050C2083*
+ ID_OUI_FROM_DATABASE=ARD SA
+
+OUI:0050C2084*
+ ID_OUI_FROM_DATABASE=DIALOG4 System Engineering GmbH
+
+OUI:0050C2085*
+ ID_OUI_FROM_DATABASE=Crossport Systems
+
+OUI:0050C2086*
+ ID_OUI_FROM_DATABASE=Validyne Engineering Corp.
+
+OUI:0050C2087*
+ ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd.
+
+OUI:0050C2088*
+ ID_OUI_FROM_DATABASE=TELINC Corporation
+
+OUI:0050C2089*
+ ID_OUI_FROM_DATABASE=Fenwal Italia S.P.A.
+
+OUI:0050C208A*
+ ID_OUI_FROM_DATABASE=Rising Edge Technologies
+
+OUI:0050C208B*
+ ID_OUI_FROM_DATABASE=HYPERCHIP Inc.
+
+OUI:0050C208C*
+ ID_OUI_FROM_DATABASE=IP Unity
+
+OUI:0050C208D*
+ ID_OUI_FROM_DATABASE=Kylink Communications Corp.
+
+OUI:0050C208E*
+ ID_OUI_FROM_DATABASE=BSQUARE
+
+OUI:0050C208F*
+ ID_OUI_FROM_DATABASE=General Industries Argentina
+
+OUI:0050C2090*
+ ID_OUI_FROM_DATABASE=Invensys Controls Network Systems
+
+OUI:0050C2091*
+ ID_OUI_FROM_DATABASE=StorLogic, Inc.
+
+OUI:0050C2092*
+ ID_OUI_FROM_DATABASE=DigitAll World Co., Ltd
+
+OUI:0050C2093*
+ ID_OUI_FROM_DATABASE=KOREALINK
+
+OUI:0050C2094*
+ ID_OUI_FROM_DATABASE=Analytical Spectral Devices, Inc.
+
+OUI:0050C2095*
+ ID_OUI_FROM_DATABASE=SEATECH
+
+OUI:0050C2096*
+ ID_OUI_FROM_DATABASE=Utronix Elektronikutreckling AB
+
+OUI:0050C2097*
+ ID_OUI_FROM_DATABASE=IMV Invertomatic
+
+OUI:0050C2098*
+ ID_OUI_FROM_DATABASE=EPEL Industrial, S.A.
+
+OUI:0050C2099*
+ ID_OUI_FROM_DATABASE=Case Information & Communications
+
+OUI:0050C209A*
+ ID_OUI_FROM_DATABASE=NBO Development Center Sekusui Chemical Co. Ltd.
+
+OUI:0050C209B*
+ ID_OUI_FROM_DATABASE=Seffle Instrument AB
+
+OUI:0050C209C*
+ ID_OUI_FROM_DATABASE=RF Applications, Inc.
+
+OUI:0050C209D*
+ ID_OUI_FROM_DATABASE=ZELPOS
+
+OUI:0050C209E*
+ ID_OUI_FROM_DATABASE=Infinitec Networks, Inc.
+
+OUI:0050C209F*
+ ID_OUI_FROM_DATABASE=MetaWave Vedeo Systems
+
+OUI:0050C20A0*
+ ID_OUI_FROM_DATABASE=CYNAPS
+
+OUI:0050C20A1*
+ ID_OUI_FROM_DATABASE=Visable Genetics, Inc.
+
+OUI:0050C20A2*
+ ID_OUI_FROM_DATABASE=Jäger Computergesteuerte Messtechnik GmbH
+
+OUI:0050C20A3*
+ ID_OUI_FROM_DATABASE=BaSyTec GmbH
+
+OUI:0050C20A4*
+ ID_OUI_FROM_DATABASE=Bounty Systems Pty Ltd.
+
+OUI:0050C20A5*
+ ID_OUI_FROM_DATABASE=Mobiltex Data Ltd.
+
+OUI:0050C20A6*
+ ID_OUI_FROM_DATABASE=Arula Systems, Inc.
+
+OUI:0050C20A7*
+ ID_OUI_FROM_DATABASE=WaterCove Networks
+
+OUI:0050C20A8*
+ ID_OUI_FROM_DATABASE=Kaveri Networks
+
+OUI:0050C20A9*
+ ID_OUI_FROM_DATABASE=Radiant Networks Plc
+
+OUI:0050C20AA*
+ ID_OUI_FROM_DATABASE=Log-In, Inc.
+
+OUI:0050C20AB*
+ ID_OUI_FROM_DATABASE=Fastware.Net, LLC
+
+OUI:0050C20AC*
+ ID_OUI_FROM_DATABASE=Honeywell GNO
+
+OUI:0050C20AD*
+ ID_OUI_FROM_DATABASE=BMC Messsysteme GmbH
+
+OUI:0050C20AE*
+ ID_OUI_FROM_DATABASE=Zarak Systems Corp.
+
+OUI:0050C20AF*
+ ID_OUI_FROM_DATABASE=Latus Lightworks, Inc.
+
+OUI:0050C20B0*
+ ID_OUI_FROM_DATABASE=LMI Technologies, Inc.
+
+OUI:0050C20B1*
+ ID_OUI_FROM_DATABASE=Beeline Networks, Inc.
+
+OUI:0050C20B2*
+ ID_OUI_FROM_DATABASE=R F Micro Devices
+
+OUI:0050C20B3*
+ ID_OUI_FROM_DATABASE=SMX Corporation
+
+OUI:0050C20B4*
+ ID_OUI_FROM_DATABASE=Wavefly Corporation
+
+OUI:0050C20B5*
+ ID_OUI_FROM_DATABASE=Extreme Copper, Inc.
+
+OUI:0050C20B6*
+ ID_OUI_FROM_DATABASE=ApSecure Technologies (Canada), Inc.
+
+OUI:0050C20B7*
+ ID_OUI_FROM_DATABASE=RYMIC
+
+OUI:0050C20B8*
+ ID_OUI_FROM_DATABASE=LAN Controls, Inc.
+
+OUI:0050C20B9*
+ ID_OUI_FROM_DATABASE=Helmut Mauell GmbH
+
+OUI:0050C20BA*
+ ID_OUI_FROM_DATABASE=Pro-Active
+
+OUI:0050C20BB*
+ ID_OUI_FROM_DATABASE=MAZet GmbH
+
+OUI:0050C20BC*
+ ID_OUI_FROM_DATABASE=Infolink Software AG
+
+OUI:0050C20BD*
+ ID_OUI_FROM_DATABASE=Tattile
+
+OUI:0050C20BE*
+ ID_OUI_FROM_DATABASE=Stella Electronics & Tagging
+
+OUI:0050C20C0*
+ ID_OUI_FROM_DATABASE=Imigix Ltd.
+
+OUI:0050C20C1*
+ ID_OUI_FROM_DATABASE=Casabyte
+
+OUI:0050C20C2*
+ ID_OUI_FROM_DATABASE=Alchemy Semiconductor, Inc.
+
+OUI:0050C20C3*
+ ID_OUI_FROM_DATABASE=Tonbu, Inc.
+
+OUI:0050C20C4*
+ ID_OUI_FROM_DATABASE=InterEpoch Technology, Inc.
+
+OUI:0050C20C5*
+ ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG
+
+OUI:0050C20C6*
+ ID_OUI_FROM_DATABASE=Advanced Medical Information Technologies, Inc.
+
+OUI:0050C20C7*
+ ID_OUI_FROM_DATABASE=TransComm Technology System, Inc.
+
+OUI:0050C20C8*
+ ID_OUI_FROM_DATABASE=The Trane Company
+
+OUI:0050C20C9*
+ ID_OUI_FROM_DATABASE=DSS Networks, Inc.
+
+OUI:0050C20CA*
+ ID_OUI_FROM_DATABASE=J D Richards
+
+OUI:0050C20CB*
+ ID_OUI_FROM_DATABASE=STUDIEL
+
+OUI:0050C20CC*
+ ID_OUI_FROM_DATABASE=AlphaMedia Co., Ltd
+
+OUI:0050C20CD*
+ ID_OUI_FROM_DATABASE=LINET OY
+
+OUI:0050C20CE*
+ ID_OUI_FROM_DATABASE=RFL Electronics, Inc.
+
+OUI:0050C20CF*
+ ID_OUI_FROM_DATABASE=PCSC
+
+OUI:0050C20D0*
+ ID_OUI_FROM_DATABASE=Telegrang AB
+
+OUI:0050C20D1*
+ ID_OUI_FROM_DATABASE=Renaissance Networking, Inc.
+
+OUI:0050C20D2*
+ ID_OUI_FROM_DATABASE=Real World Computing Partnership
+
+OUI:0050C20D3*
+ ID_OUI_FROM_DATABASE=Lake Technology, Ltd.
+
+OUI:0050C20D4*
+ ID_OUI_FROM_DATABASE=Palm, Inc.
+
+OUI:0050C20D5*
+ ID_OUI_FROM_DATABASE=Zelax
+
+OUI:0050C20D6*
+ ID_OUI_FROM_DATABASE=Inco Startec GmbH
+
+OUI:0050C20D7*
+ ID_OUI_FROM_DATABASE=Summit Avionics, Inc.
+
+OUI:0050C20D8*
+ ID_OUI_FROM_DATABASE=Charlotte's Web Networks
+
+OUI:0050C20D9*
+ ID_OUI_FROM_DATABASE=Loewe Opta GmbH
+
+OUI:0050C20DA*
+ ID_OUI_FROM_DATABASE=Motion Analysis Corp.
+
+OUI:0050C20DB*
+ ID_OUI_FROM_DATABASE=Cyberex
+
+OUI:0050C20DC*
+ ID_OUI_FROM_DATABASE=Elbit Systems Ltd.
+
+OUI:0050C20DD*
+ ID_OUI_FROM_DATABASE=Interisa Electronica, S.A.
+
+OUI:0050C20DE*
+ ID_OUI_FROM_DATABASE=Frederick Engineering
+
+OUI:0050C20DF*
+ ID_OUI_FROM_DATABASE=Innovation Institute, Inc.
+
+OUI:0050C20E0*
+ ID_OUI_FROM_DATABASE=EMAC, Inc.
+
+OUI:0050C20E1*
+ ID_OUI_FROM_DATABASE=Inspiration Technology P/L
+
+OUI:0050C20E2*
+ ID_OUI_FROM_DATABASE=Visual Circuits Corp.
+
+OUI:0050C20E3*
+ ID_OUI_FROM_DATABASE=Lanex S.A.
+
+OUI:0050C20E4*
+ ID_OUI_FROM_DATABASE=Collabo Tec. Co., Ltd.
+
+OUI:0050C20E5*
+ ID_OUI_FROM_DATABASE=Clearwater Networks
+
+OUI:0050C20E6*
+ ID_OUI_FROM_DATABASE=RouteFree, Inc.
+
+OUI:0050C20E7*
+ ID_OUI_FROM_DATABASE=Century Geophysical Corp.
+
+OUI:0050C20E8*
+ ID_OUI_FROM_DATABASE=Audio Design Associates, Inc.
+
+OUI:0050C20E9*
+ ID_OUI_FROM_DATABASE=Smartmedia LLC
+
+OUI:0050C20EA*
+ ID_OUI_FROM_DATABASE=iReady Corporation
+
+OUI:0050C20EB*
+ ID_OUI_FROM_DATABASE=iREZ Technologies LLC
+
+OUI:0050C20EC*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C20ED*
+ ID_OUI_FROM_DATABASE=Valley Products Corporation
+
+OUI:0050C20EE*
+ ID_OUI_FROM_DATABASE=Industrial Indexing Systems, Inc.
+
+OUI:0050C20EF*
+ ID_OUI_FROM_DATABASE=Movaz Networks, Inc.
+
+OUI:0050C20F0*
+ ID_OUI_FROM_DATABASE=VHB Technologies, Inc.
+
+OUI:0050C20F1*
+ ID_OUI_FROM_DATABASE=Polyvision Corporation
+
+OUI:0050C20F2*
+ ID_OUI_FROM_DATABASE=KMS Systems, Inc.
+
+OUI:0050C20F3*
+ ID_OUI_FROM_DATABASE=Young Computer Co., Ltd.
+
+OUI:0050C20F4*
+ ID_OUI_FROM_DATABASE=Sysnet Co., Ltd.
+
+OUI:0050C20F5*
+ ID_OUI_FROM_DATABASE=Spectra Technologies Holding Co., Ltd.
+
+OUI:0050C20F6*
+ ID_OUI_FROM_DATABASE=Carl Baasel Lasertechnik GmbH
+
+OUI:0050C20F7*
+ ID_OUI_FROM_DATABASE=Foss NIRSystems, Inc.
+
+OUI:0050C20F8*
+ ID_OUI_FROM_DATABASE=Tecnint HTE S.r.L.
+
+OUI:0050C20F9*
+ ID_OUI_FROM_DATABASE=Raven Industries
+
+OUI:0050C20FA*
+ ID_OUI_FROM_DATABASE=GE Lubrizol, LLC
+
+OUI:0050C20FB*
+ ID_OUI_FROM_DATABASE=PIUSYS Co., Ltd.
+
+OUI:0050C20FC*
+ ID_OUI_FROM_DATABASE=Kimmon Manufacturing Co., Ltd.
+
+OUI:0050C20FD*
+ ID_OUI_FROM_DATABASE=Inducomp Corporation
+
+OUI:0050C20FE*
+ ID_OUI_FROM_DATABASE=Energy ICT
+
+OUI:0050C20FF*
+ ID_OUI_FROM_DATABASE=IPAXS Corporation
+
+OUI:0050C2100*
+ ID_OUI_FROM_DATABASE=Corelatus A.B.
+
+OUI:0050C2101*
+ ID_OUI_FROM_DATABASE=LAUD Electronic Design AS
+
+OUI:0050C2102*
+ ID_OUI_FROM_DATABASE=Million Tech Development Ltd.
+
+OUI:0050C2103*
+ ID_OUI_FROM_DATABASE=Green Hills Software, Inc.
+
+OUI:0050C2104*
+ ID_OUI_FROM_DATABASE=Adescom Inc.
+
+OUI:0050C2105*
+ ID_OUI_FROM_DATABASE=Lumentis AB
+
+OUI:0050C2106*
+ ID_OUI_FROM_DATABASE=MATSUOKA
+
+OUI:0050C2107*
+ ID_OUI_FROM_DATABASE=NewHer Systems
+
+OUI:0050C2108*
+ ID_OUI_FROM_DATABASE=Balogh S.A.
+
+OUI:0050C2109*
+ ID_OUI_FROM_DATABASE=ITK Dr. Kassen GmbH
+
+OUI:0050C210A*
+ ID_OUI_FROM_DATABASE=Quinx AG
+
+OUI:0050C210B*
+ ID_OUI_FROM_DATABASE=MarekMicro GmbH
+
+OUI:0050C210C*
+ ID_OUI_FROM_DATABASE=Photonic Bridges, Inc.
+
+OUI:0050C210D*
+ ID_OUI_FROM_DATABASE=Implementa GmbH
+
+OUI:0050C210E*
+ ID_OUI_FROM_DATABASE=Unipower AB
+
+OUI:0050C210F*
+ ID_OUI_FROM_DATABASE=Perceptics Corp.
+
+OUI:0050C2110*
+ ID_OUI_FROM_DATABASE=QuesCom
+
+OUI:0050C2111*
+ ID_OUI_FROM_DATABASE=Endusis Limited
+
+OUI:0050C2112*
+ ID_OUI_FROM_DATABASE=Compuworx
+
+OUI:0050C2113*
+ ID_OUI_FROM_DATABASE=Ace Electronics, Inc.
+
+OUI:0050C2114*
+ ID_OUI_FROM_DATABASE=Quest Innovations
+
+OUI:0050C2115*
+ ID_OUI_FROM_DATABASE=Vidco, Inc.
+
+OUI:0050C2116*
+ ID_OUI_FROM_DATABASE=DSP Design, Ltd.
+
+OUI:0050C2117*
+ ID_OUI_FROM_DATABASE=Wintegra Ltd.
+
+OUI:0050C2118*
+ ID_OUI_FROM_DATABASE=Microbit 2.0 AB
+
+OUI:0050C2119*
+ ID_OUI_FROM_DATABASE=Global Opto Communication Tech. Corp
+
+OUI:0050C211A*
+ ID_OUI_FROM_DATABASE=Teamaxess Ticketing GmbH
+
+OUI:0050C211B*
+ ID_OUI_FROM_DATABASE=Digital Vision AB
+
+OUI:0050C211C*
+ ID_OUI_FROM_DATABASE=Stonefly Networks
+
+OUI:0050C211D*
+ ID_OUI_FROM_DATABASE=Destiny Networks, Inc.
+
+OUI:0050C211E*
+ ID_OUI_FROM_DATABASE=Volvo Car Corporation
+
+OUI:0050C211F*
+ ID_OUI_FROM_DATABASE=CSS Industrie Computer GmbH
+
+OUI:0050C2120*
+ ID_OUI_FROM_DATABASE=XStore, Inc.
+
+OUI:0050C2121*
+ ID_OUI_FROM_DATABASE=COE Limited
+
+OUI:0050C2122*
+ ID_OUI_FROM_DATABASE=Diva Systems
+
+OUI:0050C2123*
+ ID_OUI_FROM_DATABASE=Seranoa Networks, Inc.
+
+OUI:0050C2124*
+ ID_OUI_FROM_DATABASE=Tokai Soft Corporation
+
+OUI:0050C2125*
+ ID_OUI_FROM_DATABASE=Tecwings GmBh
+
+OUI:0050C2126*
+ ID_OUI_FROM_DATABASE=Marvell Hispana S.L.
+
+OUI:0050C2127*
+ ID_OUI_FROM_DATABASE=TPA Traffic & Parking Automation BV
+
+OUI:0050C2128*
+ ID_OUI_FROM_DATABASE=Pycon, Inc.
+
+OUI:0050C2129*
+ ID_OUI_FROM_DATABASE=TTPCom Ltd.
+
+OUI:0050C212A*
+ ID_OUI_FROM_DATABASE=Symbolic Sound Corp.
+
+OUI:0050C212B*
+ ID_OUI_FROM_DATABASE=Dong A Eltek Co., Ltd.
+
+OUI:0050C212C*
+ ID_OUI_FROM_DATABASE=Delta Tau Data Systems, Inc.
+
+OUI:0050C212D*
+ ID_OUI_FROM_DATABASE=Megisto Systems, Inc.
+
+OUI:0050C212E*
+ ID_OUI_FROM_DATABASE=RUNCOM
+
+OUI:0050C212F*
+ ID_OUI_FROM_DATABASE=HAAG-STREIT AG
+
+OUI:0050C2130*
+ ID_OUI_FROM_DATABASE=U.S. Traffic Corporation
+
+OUI:0050C2131*
+ ID_OUI_FROM_DATABASE=InBus Engineering, Inc.
+
+OUI:0050C2132*
+ ID_OUI_FROM_DATABASE=Procon Electronics
+
+OUI:0050C2133*
+ ID_OUI_FROM_DATABASE=ChipWrights, Inc.
+
+OUI:0050C2134*
+ ID_OUI_FROM_DATABASE=DRS Photronics
+
+OUI:0050C2135*
+ ID_OUI_FROM_DATABASE=ELAD SRL
+
+OUI:0050C2136*
+ ID_OUI_FROM_DATABASE=Tensilica, Inc.
+
+OUI:0050C2137*
+ ID_OUI_FROM_DATABASE=Uniwell Systems (UK) Ltd.
+
+OUI:0050C2138*
+ ID_OUI_FROM_DATABASE=Delphin Technology AG
+
+OUI:0050C2139*
+ ID_OUI_FROM_DATABASE=SR Research Ltd.
+
+OUI:0050C213A*
+ ID_OUI_FROM_DATABASE=Tex Computer SRL
+
+OUI:0050C213B*
+ ID_OUI_FROM_DATABASE=Vaisala Oyj
+
+OUI:0050C213C*
+ ID_OUI_FROM_DATABASE=NBG Industrial Automation B.V.
+
+OUI:0050C213D*
+ ID_OUI_FROM_DATABASE=Formula One Management Ltd.
+
+OUI:0050C213E*
+ ID_OUI_FROM_DATABASE=AVerMedia Systems, Inc.
+
+OUI:0050C213F*
+ ID_OUI_FROM_DATABASE=Sentito Networks
+
+OUI:0050C2140*
+ ID_OUI_FROM_DATABASE=ITS, Inc.
+
+OUI:0050C2141*
+ ID_OUI_FROM_DATABASE=Time Terminal Adductor Group AB
+
+OUI:0050C2142*
+ ID_OUI_FROM_DATABASE=Instrumeter A/S
+
+OUI:0050C2143*
+ ID_OUI_FROM_DATABASE=AARTESYS AG
+
+OUI:0050C2144*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2145*
+ ID_OUI_FROM_DATABASE=ELC Lighting
+
+OUI:0050C2146*
+ ID_OUI_FROM_DATABASE=APCON, Inc.
+
+OUI:0050C2147*
+ ID_OUI_FROM_DATABASE=UniSUR
+
+OUI:0050C2148*
+ ID_OUI_FROM_DATABASE=Alltec GmbH
+
+OUI:0050C2149*
+ ID_OUI_FROM_DATABASE=Haag-Streit AG
+
+OUI:0050C214A*
+ ID_OUI_FROM_DATABASE=DYCEC, S.A.
+
+OUI:0050C214B*
+ ID_OUI_FROM_DATABASE=HECUBA Elektronik
+
+OUI:0050C214C*
+ ID_OUI_FROM_DATABASE=Optibase Ltd.
+
+OUI:0050C214D*
+ ID_OUI_FROM_DATABASE=wellink, Ltd.
+
+OUI:0050C214E*
+ ID_OUI_FROM_DATABASE=Corinex Global
+
+OUI:0050C214F*
+ ID_OUI_FROM_DATABASE=Telephonics Corp.
+
+OUI:0050C2150*
+ ID_OUI_FROM_DATABASE=Torse
+
+OUI:0050C2151*
+ ID_OUI_FROM_DATABASE=Redux Communications Ltd.
+
+OUI:0050C2152*
+ ID_OUI_FROM_DATABASE=AirVast Technology Inc.
+
+OUI:0050C2153*
+ ID_OUI_FROM_DATABASE=Advanced Devices SpA
+
+OUI:0050C2154*
+ ID_OUI_FROM_DATABASE=Jostra AB
+
+OUI:0050C2155*
+ ID_OUI_FROM_DATABASE=Enea Real Time AB
+
+OUI:0050C2156*
+ ID_OUI_FROM_DATABASE=CommServ Solutions Inc.
+
+OUI:0050C2157*
+ ID_OUI_FROM_DATABASE=nCore, Inc.
+
+OUI:0050C2158*
+ ID_OUI_FROM_DATABASE=Communication Solutions, Inc.
+
+OUI:0050C2159*
+ ID_OUI_FROM_DATABASE=Standard Comm. Corp.
+
+OUI:0050C215A*
+ ID_OUI_FROM_DATABASE=Plextek Limited
+
+OUI:0050C215B*
+ ID_OUI_FROM_DATABASE=Dune Networks
+
+OUI:0050C215C*
+ ID_OUI_FROM_DATABASE=Aoptix Technologies
+
+OUI:0050C215D*
+ ID_OUI_FROM_DATABASE=Cepheid
+
+OUI:0050C215E*
+ ID_OUI_FROM_DATABASE=Celite Systems, Inc.
+
+OUI:0050C215F*
+ ID_OUI_FROM_DATABASE=Pulsar GmbH
+
+OUI:0050C2160*
+ ID_OUI_FROM_DATABASE=TTI - Telecom International Ltd.
+
+OUI:0050C2161*
+ ID_OUI_FROM_DATABASE=J&B Engineering Group S.L.
+
+OUI:0050C2162*
+ ID_OUI_FROM_DATABASE=Teseda Corporation
+
+OUI:0050C2163*
+ ID_OUI_FROM_DATABASE=Computerwise, Inc.
+
+OUI:0050C2164*
+ ID_OUI_FROM_DATABASE=Acunia N.V.
+
+OUI:0050C2165*
+ ID_OUI_FROM_DATABASE=IPCAST
+
+OUI:0050C2166*
+ ID_OUI_FROM_DATABASE=Infineer Ltd.
+
+OUI:0050C2167*
+ ID_OUI_FROM_DATABASE=Precision Filters, Inc.
+
+OUI:0050C2168*
+ ID_OUI_FROM_DATABASE=ExtremeSpeed Inc.
+
+OUI:0050C2169*
+ ID_OUI_FROM_DATABASE=Nordson Corp.
+
+OUI:0050C216A*
+ ID_OUI_FROM_DATABASE=Time Domain
+
+OUI:0050C216B*
+ ID_OUI_FROM_DATABASE=Masterclock, Inc.
+
+OUI:0050C216C*
+ ID_OUI_FROM_DATABASE=Brijing Embedor Embedded Internet Tech. Co. Ltd.
+
+OUI:0050C216D*
+ ID_OUI_FROM_DATABASE=Postec Data Systems Ltd.
+
+OUI:0050C216E*
+ ID_OUI_FROM_DATABASE=PMC
+
+OUI:0050C216F*
+ ID_OUI_FROM_DATABASE=Dickson Technologies
+
+OUI:0050C2170*
+ ID_OUI_FROM_DATABASE=Taishodo Seiko Co., Ltd.
+
+OUI:0050C2171*
+ ID_OUI_FROM_DATABASE=Quantronix, Inc.
+
+OUI:0050C2172*
+ ID_OUI_FROM_DATABASE=SAET I.S. S.r.l.
+
+OUI:0050C2173*
+ ID_OUI_FROM_DATABASE=DeMeTec GmbH
+
+OUI:0050C2174*
+ ID_OUI_FROM_DATABASE=N&P Technologies
+
+OUI:0050C2175*
+ ID_OUI_FROM_DATABASE=Sei S.p.A.
+
+OUI:0050C2176*
+ ID_OUI_FROM_DATABASE=Wavium AB
+
+OUI:0050C2177*
+ ID_OUI_FROM_DATABASE=Unicoi Systems
+
+OUI:0050C2178*
+ ID_OUI_FROM_DATABASE=Partner Voxstream A/S
+
+OUI:0050C2179*
+ ID_OUI_FROM_DATABASE=Verifiber LLC
+
+OUI:0050C217A*
+ ID_OUI_FROM_DATABASE=WOLF Industrial Systems Inc.
+
+OUI:0050C217B*
+ ID_OUI_FROM_DATABASE=Broadstorm Telecom
+
+OUI:0050C217C*
+ ID_OUI_FROM_DATABASE=Jeffress Engineering Pty Ltd
+
+OUI:0050C217D*
+ ID_OUI_FROM_DATABASE=Cognex Corporation
+
+OUI:0050C217E*
+ ID_OUI_FROM_DATABASE=Binary Wave Technologies Inc.
+
+OUI:0050C217F*
+ ID_OUI_FROM_DATABASE=PDQ Manufacturing
+
+OUI:0050C2180*
+ ID_OUI_FROM_DATABASE=Zultys Technologies
+
+OUI:0050C2181*
+ ID_OUI_FROM_DATABASE=Task 84 Spa
+
+OUI:0050C2182*
+ ID_OUI_FROM_DATABASE=wolf-inf-tec
+
+OUI:0050C2183*
+ ID_OUI_FROM_DATABASE=Mixbaal S.A. de C.V.
+
+OUI:0050C2184*
+ ID_OUI_FROM_DATABASE=H M Computing Limited
+
+OUI:0050C2185*
+ ID_OUI_FROM_DATABASE=Optical Wireless Link Inc.
+
+OUI:0050C2186*
+ ID_OUI_FROM_DATABASE=Pantec Engineering AG
+
+OUI:0050C2187*
+ ID_OUI_FROM_DATABASE=Cyan Technology Ltd
+
+OUI:0050C2188*
+ ID_OUI_FROM_DATABASE=dresden-elektronik
+
+OUI:0050C2189*
+ ID_OUI_FROM_DATABASE=CC Systems AB
+
+OUI:0050C218A*
+ ID_OUI_FROM_DATABASE=Basler Electric Company
+
+OUI:0050C218B*
+ ID_OUI_FROM_DATABASE=Teradyne Inc.
+
+OUI:0050C218C*
+ ID_OUI_FROM_DATABASE=Technodrive srl
+
+OUI:0050C218D*
+ ID_OUI_FROM_DATABASE=CCII Systems (Pty) Ltd
+
+OUI:0050C218E*
+ ID_OUI_FROM_DATABASE=SPARR ELECTRONICS LTD
+
+OUI:0050C218F*
+ ID_OUI_FROM_DATABASE=MATSUI MFG CO.,LTD
+
+OUI:0050C2190*
+ ID_OUI_FROM_DATABASE=Goerlitz AG
+
+OUI:0050C2191*
+ ID_OUI_FROM_DATABASE=Partner Voxstream A/S
+
+OUI:0050C2192*
+ ID_OUI_FROM_DATABASE=Advanced Concepts, Inc.
+
+OUI:0050C2193*
+ ID_OUI_FROM_DATABASE=LaserBit Communications Corp.
+
+OUI:0050C2194*
+ ID_OUI_FROM_DATABASE=COMINFO
+
+OUI:0050C2195*
+ ID_OUI_FROM_DATABASE=Momentum Data Systems
+
+OUI:0050C2196*
+ ID_OUI_FROM_DATABASE=Netsynt Spa
+
+OUI:0050C2197*
+ ID_OUI_FROM_DATABASE=EPM Tecnologia e Equipamentos
+
+OUI:0050C2198*
+ ID_OUI_FROM_DATABASE=PotsTek, Inc
+
+OUI:0050C2199*
+ ID_OUI_FROM_DATABASE=Survalent Technology Corporation
+
+OUI:0050C219A*
+ ID_OUI_FROM_DATABASE=AZIO TECHNOLOGY CO.
+
+OUI:0050C219B*
+ ID_OUI_FROM_DATABASE=Wilcoxon Research, Inc.
+
+OUI:0050C219C*
+ ID_OUI_FROM_DATABASE=Artec Design
+
+OUI:0050C219D*
+ ID_OUI_FROM_DATABASE=ELECTREX S.R.L
+
+OUI:0050C219E*
+ ID_OUI_FROM_DATABASE=Paltronics, Inc.
+
+OUI:0050C219F*
+ ID_OUI_FROM_DATABASE=Fleetwood Electronics Ltd
+
+OUI:0050C21A0*
+ ID_OUI_FROM_DATABASE=SCA Data Systems
+
+OUI:0050C21A1*
+ ID_OUI_FROM_DATABASE=Portalplayer, Inc
+
+OUI:0050C21A2*
+ ID_OUI_FROM_DATABASE=ABB Switzerland Inc
+
+OUI:0050C21A3*
+ ID_OUI_FROM_DATABASE=Tidel Engineering, L.P.
+
+OUI:0050C21A4*
+ ID_OUI_FROM_DATABASE=Protech Optronics Co. Ltd.
+
+OUI:0050C21A5*
+ ID_OUI_FROM_DATABASE=NORCO
+
+OUI:0050C21A6*
+ ID_OUI_FROM_DATABASE=RF Code
+
+OUI:0050C21A7*
+ ID_OUI_FROM_DATABASE=Alpha Beta Technologies, Inc.
+
+OUI:0050C21A8*
+ ID_OUI_FROM_DATABASE=ANOVA BROADBAND
+
+OUI:0050C21A9*
+ ID_OUI_FROM_DATABASE=Axotec Technologies GmbH
+
+OUI:0050C21AA*
+ ID_OUI_FROM_DATABASE=BitBox Ltd
+
+OUI:0050C21AB*
+ ID_OUI_FROM_DATABASE=Streaming Networks
+
+OUI:0050C21AC*
+ ID_OUI_FROM_DATABASE=Beckmann+Egle GmbH
+
+OUI:0050C21AD*
+ ID_OUI_FROM_DATABASE=Remia s.r.o.
+
+OUI:0050C21AE*
+ ID_OUI_FROM_DATABASE=Home Director, Inc
+
+OUI:0050C21AF*
+ ID_OUI_FROM_DATABASE=PESA Switching Systems, Inc.
+
+OUI:0050C21B0*
+ ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH
+
+OUI:0050C21B1*
+ ID_OUI_FROM_DATABASE=Axes Technologies
+
+OUI:0050C21B2*
+ ID_OUI_FROM_DATABASE=SIGOS Systemintegration GmbH
+
+OUI:0050C21B3*
+ ID_OUI_FROM_DATABASE=DSP DESIGN
+
+OUI:0050C21B4*
+ ID_OUI_FROM_DATABASE=DSP Group Inc.
+
+OUI:0050C21B5*
+ ID_OUI_FROM_DATABASE=Thrane & Thrane A/S
+
+OUI:0050C21B6*
+ ID_OUI_FROM_DATABASE=DTS, Inc.
+
+OUI:0050C21B7*
+ ID_OUI_FROM_DATABASE=MosChip USA
+
+OUI:0050C21B8*
+ ID_OUI_FROM_DATABASE=Electronic Systems Development
+
+OUI:0050C21B9*
+ ID_OUI_FROM_DATABASE=EmCom Technology Inc.
+
+OUI:0050C21BA*
+ ID_OUI_FROM_DATABASE=INTERZEAG AG
+
+OUI:0050C21BB*
+ ID_OUI_FROM_DATABASE=Email Metering
+
+OUI:0050C21BC*
+ ID_OUI_FROM_DATABASE=DINEC International
+
+OUI:0050C21BD*
+ ID_OUI_FROM_DATABASE=AIOI Systems Co., Ltd.
+
+OUI:0050C21BE*
+ ID_OUI_FROM_DATABASE=Sedia Electronics
+
+OUI:0050C21BF*
+ ID_OUI_FROM_DATABASE=International Test & Engineering Services Co.,Ltd.
+
+OUI:0050C21C0*
+ ID_OUI_FROM_DATABASE=WillMonius Inc.
+
+OUI:0050C21C1*
+ ID_OUI_FROM_DATABASE=InfinitiNetworks Inc.
+
+OUI:0050C21C2*
+ ID_OUI_FROM_DATABASE=Weltronics Corp.
+
+OUI:0050C21C3*
+ ID_OUI_FROM_DATABASE=TT electronic manufacturing services ltd
+
+OUI:0050C21C4*
+ ID_OUI_FROM_DATABASE=Palm Solutions Group
+
+OUI:0050C21C5*
+ ID_OUI_FROM_DATABASE=Flander Oy
+
+OUI:0050C21C6*
+ ID_OUI_FROM_DATABASE=Remco Italia Spa
+
+OUI:0050C21C7*
+ ID_OUI_FROM_DATABASE=TWIN DEVELOPMENT S.A.
+
+OUI:0050C21C8*
+ ID_OUI_FROM_DATABASE=Euphony technology CO., LTD.
+
+OUI:0050C21C9*
+ ID_OUI_FROM_DATABASE=modas GmbH
+
+OUI:0050C21CA*
+ ID_OUI_FROM_DATABASE=EVER Sp. z o.o.
+
+OUI:0050C21CB*
+ ID_OUI_FROM_DATABASE=quantumBEAM Limited
+
+OUI:0050C21CC*
+ ID_OUI_FROM_DATABASE=WaveIP ltd.
+
+OUI:0050C21CD*
+ ID_OUI_FROM_DATABASE=INCAA Informatica Italia  srl
+
+OUI:0050C21CE*
+ ID_OUI_FROM_DATABASE=Datatek Applications, Inc.
+
+OUI:0050C21CF*
+ ID_OUI_FROM_DATABASE=LIFETIME MEMORY PRODUCTS, INC.
+
+OUI:0050C21D0*
+ ID_OUI_FROM_DATABASE=Yazaki North America, Inc.
+
+OUI:0050C21D1*
+ ID_OUI_FROM_DATABASE=Benchmark Electronics
+
+OUI:0050C21D2*
+ ID_OUI_FROM_DATABASE=Shenyang Internet Technology Inc
+
+OUI:0050C21D3*
+ ID_OUI_FROM_DATABASE=Synopsys
+
+OUI:0050C21D4*
+ ID_OUI_FROM_DATABASE=Phase IV Engineering Inc.
+
+OUI:0050C21D5*
+ ID_OUI_FROM_DATABASE=Redpoint Controls
+
+OUI:0050C21D6*
+ ID_OUI_FROM_DATABASE=shanghai trend intelligent systems CO.,LTD
+
+OUI:0050C21D7*
+ ID_OUI_FROM_DATABASE=Pleora Technologies Inc.
+
+OUI:0050C21D8*
+ ID_OUI_FROM_DATABASE=Guardian Controls International
+
+OUI:0050C21D9*
+ ID_OUI_FROM_DATABASE=EDC
+
+OUI:0050C21DA*
+ ID_OUI_FROM_DATABASE=GFI Chrono Time
+
+OUI:0050C21DB*
+ ID_OUI_FROM_DATABASE=Applied Systems Engineering, Inc.
+
+OUI:0050C21DC*
+ ID_OUI_FROM_DATABASE=Imarda New Zealand Limited
+
+OUI:0050C21DD*
+ ID_OUI_FROM_DATABASE=Peiker acustic GmbH & Co. KG
+
+OUI:0050C21DE*
+ ID_OUI_FROM_DATABASE=ReliOn Inc.
+
+OUI:0050C21DF*
+ ID_OUI_FROM_DATABASE=Lulea University of Technology
+
+OUI:0050C21E0*
+ ID_OUI_FROM_DATABASE=Cognex Corporation
+
+OUI:0050C21E1*
+ ID_OUI_FROM_DATABASE=Automaatiotekniikka Seppo Saari Oy
+
+OUI:0050C21E2*
+ ID_OUI_FROM_DATABASE=DIGITRONIC Automationsanlagen GmbH
+
+OUI:0050C21E3*
+ ID_OUI_FROM_DATABASE=Bluesocket, Inc.
+
+OUI:0050C21E4*
+ ID_OUI_FROM_DATABASE=Soronti, Inc.
+
+OUI:0050C21E5*
+ ID_OUI_FROM_DATABASE=DORLET S.A.
+
+OUI:0050C21E6*
+ ID_OUI_FROM_DATABASE=United Tri-Tech Corporation
+
+OUI:0050C21E7*
+ ID_OUI_FROM_DATABASE=Smith Meter, Inc.
+
+OUI:0050C21E8*
+ ID_OUI_FROM_DATABASE=Metrotech
+
+OUI:0050C21E9*
+ ID_OUI_FROM_DATABASE=Ranch Networks
+
+OUI:0050C21EA*
+ ID_OUI_FROM_DATABASE=DAVE S.r.L.
+
+OUI:0050C21EB*
+ ID_OUI_FROM_DATABASE=Data Respons A/S
+
+OUI:0050C21EC*
+ ID_OUI_FROM_DATABASE=COSMO co.,ltd.
+
+OUI:0050C21ED*
+ ID_OUI_FROM_DATABASE=EMKA-electronic AG
+
+OUI:0050C21EE*
+ ID_OUI_FROM_DATABASE=Perto Periféricos de Automação S.A.
+
+OUI:0050C21EF*
+ ID_OUI_FROM_DATABASE=M2 Technology Pty Ltd
+
+OUI:0050C21F0*
+ ID_OUI_FROM_DATABASE=EXI Wireless Systems Inc.
+
+OUI:0050C21F1*
+ ID_OUI_FROM_DATABASE=SKY Computers, Inc.
+
+OUI:0050C21F2*
+ ID_OUI_FROM_DATABASE=Tattile srl
+
+OUI:0050C21F3*
+ ID_OUI_FROM_DATABASE=Radionor Communications AS
+
+OUI:0050C21F4*
+ ID_OUI_FROM_DATABASE=Covia, Inc
+
+OUI:0050C21F5*
+ ID_OUI_FROM_DATABASE=Abest Communication Corp.
+
+OUI:0050C21F6*
+ ID_OUI_FROM_DATABASE=BAE SYSTEMS Controls
+
+OUI:0050C21F7*
+ ID_OUI_FROM_DATABASE=ARC'Créations
+
+OUI:0050C21F8*
+ ID_OUI_FROM_DATABASE=ULTRACKER TECHNOLOGY
+
+OUI:0050C21F9*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C21FA*
+ ID_OUI_FROM_DATABASE=SP Controls, Inc
+
+OUI:0050C21FB*
+ ID_OUI_FROM_DATABASE=Willowglen Systems Inc.
+
+OUI:0050C21FC*
+ ID_OUI_FROM_DATABASE=EDD Srl
+
+OUI:0050C21FD*
+ ID_OUI_FROM_DATABASE=SouthWing S.L.
+
+OUI:0050C21FE*
+ ID_OUI_FROM_DATABASE=Safetran Traffic Systems Inc.
+
+OUI:0050C21FF*
+ ID_OUI_FROM_DATABASE=Product Design Dept., Sohwa Corporation
+
+OUI:0050C2200*
+ ID_OUI_FROM_DATABASE=Whittier Mailing Products, Inc.
+
+OUI:0050C2201*
+ ID_OUI_FROM_DATABASE=OlympusNDT
+
+OUI:0050C2202*
+ ID_OUI_FROM_DATABASE=Audio Riders Oy
+
+OUI:0050C2204*
+ ID_OUI_FROM_DATABASE=Algodue Elettronica srl
+
+OUI:0050C2205*
+ ID_OUI_FROM_DATABASE=SystIng
+
+OUI:0050C2206*
+ ID_OUI_FROM_DATABASE=Windmill Innovations
+
+OUI:0050C2207*
+ ID_OUI_FROM_DATABASE=Solectron Ind.Com.Servs.Exportadora do Brasil Ltda.
+
+OUI:0050C2208*
+ ID_OUI_FROM_DATABASE=nNovia, Inc.
+
+OUI:0050C2209*
+ ID_OUI_FROM_DATABASE=LK Ltd
+
+OUI:0050C220A*
+ ID_OUI_FROM_DATABASE=Ferrari electronic AG
+
+OUI:0050C220B*
+ ID_OUI_FROM_DATABASE=Rafael
+
+OUI:0050C220C*
+ ID_OUI_FROM_DATABASE=Communication and Telemechanical Systems Company Limited
+
+OUI:0050C220D*
+ ID_OUI_FROM_DATABASE=Varisys Ltd
+
+OUI:0050C220E*
+ ID_OUI_FROM_DATABASE=PYRAMID Computer Systeme GmbH
+
+OUI:0050C220F*
+ ID_OUI_FROM_DATABASE=OMICRON electronics GmbH
+
+OUI:0050C2210*
+ ID_OUI_FROM_DATABASE=Innovics Wireless Inc
+
+OUI:0050C2211*
+ ID_OUI_FROM_DATABASE=Hochschule für Technik, Wirtschaft und Kultur Leipzig (FH)
+
+OUI:0050C2212*
+ ID_OUI_FROM_DATABASE=4Links Limited
+
+OUI:0050C2213*
+ ID_OUI_FROM_DATABASE=SysAware S.A.R.L.
+
+OUI:0050C2214*
+ ID_OUI_FROM_DATABASE=Oshimi System Design Inc.
+
+OUI:0050C2215*
+ ID_OUI_FROM_DATABASE=VoiceCom AG
+
+OUI:0050C2216*
+ ID_OUI_FROM_DATABASE=Level Control Systems
+
+OUI:0050C2217*
+ ID_OUI_FROM_DATABASE=Linn Products Ltd
+
+OUI:0050C2218*
+ ID_OUI_FROM_DATABASE=Nansen S. A. - Instrumentos de Precisão
+
+OUI:0050C2219*
+ ID_OUI_FROM_DATABASE=Aeroflex GmbH
+
+OUI:0050C221A*
+ ID_OUI_FROM_DATABASE=MST SYSTEMS LIMITED
+
+OUI:0050C221B*
+ ID_OUI_FROM_DATABASE=General Dynamics Decision Systems
+
+OUI:0050C221C*
+ ID_OUI_FROM_DATABASE=Fracarro Radioindustrie SPA
+
+OUI:0050C221D*
+ ID_OUI_FROM_DATABASE=ESG Elektroniksystem u. Logistik GmbH
+
+OUI:0050C221E*
+ ID_OUI_FROM_DATABASE=Applied Technologies Associates
+
+OUI:0050C221F*
+ ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd
+
+OUI:0050C2220*
+ ID_OUI_FROM_DATABASE=Serveron Corporation
+
+OUI:0050C2221*
+ ID_OUI_FROM_DATABASE=Getinge IT Solutions ApS
+
+OUI:0050C2222*
+ ID_OUI_FROM_DATABASE=imo-elektronik GmbH
+
+OUI:0050C2223*
+ ID_OUI_FROM_DATABASE=visicontrol GmbH
+
+OUI:0050C2224*
+ ID_OUI_FROM_DATABASE=PANNOCOM Ltd.
+
+OUI:0050C2225*
+ ID_OUI_FROM_DATABASE=Pigeon Point Systems
+
+OUI:0050C2226*
+ ID_OUI_FROM_DATABASE=Ross Video Limited
+
+OUI:0050C2227*
+ ID_OUI_FROM_DATABASE=Intelligent Photonics Control
+
+OUI:0050C2228*
+ ID_OUI_FROM_DATABASE=Intelligent Media Technologies, Inc.
+
+OUI:0050C2229*
+ ID_OUI_FROM_DATABASE=eko systems inc.
+
+OUI:0050C222A*
+ ID_OUI_FROM_DATABASE=Crescendo Networks
+
+OUI:0050C222B*
+ ID_OUI_FROM_DATABASE=Riegl Laser Measurement Systems GmbH
+
+OUI:0050C222C*
+ ID_OUI_FROM_DATABASE=Intrinsity
+
+OUI:0050C222D*
+ ID_OUI_FROM_DATABASE=asetek Inc.
+
+OUI:0050C222E*
+ ID_OUI_FROM_DATABASE=LORD INGEN IERIE
+
+OUI:0050C222F*
+ ID_OUI_FROM_DATABASE=HTEC Limited
+
+OUI:0050C2230*
+ ID_OUI_FROM_DATABASE=AutoTOOLS group Co. Ltd.
+
+OUI:0050C2231*
+ ID_OUI_FROM_DATABASE=Legra Systems, Inc.
+
+OUI:0050C2232*
+ ID_OUI_FROM_DATABASE=SIMET
+
+OUI:0050C2233*
+ ID_OUI_FROM_DATABASE=EdenTree Technologies, Inc.
+
+OUI:0050C2234*
+ ID_OUI_FROM_DATABASE=Silverback Systems
+
+OUI:0050C2235*
+ ID_OUI_FROM_DATABASE=POLIMAR ELEKTRONIK LTD.
+
+OUI:0050C2236*
+ ID_OUI_FROM_DATABASE=JLCooper Electronics
+
+OUI:0050C2237*
+ ID_OUI_FROM_DATABASE=Tandata Systems Ltd
+
+OUI:0050C2238*
+ ID_OUI_FROM_DATABASE=Schwer+Kopka GmbH
+
+OUI:0050C2239*
+ ID_OUI_FROM_DATABASE=Stins Coman
+
+OUI:0050C223A*
+ ID_OUI_FROM_DATABASE=Chantry Networks
+
+OUI:0050C223B*
+ ID_OUI_FROM_DATABASE=Envara
+
+OUI:0050C223C*
+ ID_OUI_FROM_DATABASE=Wheatstone Corporation
+
+OUI:0050C223D*
+ ID_OUI_FROM_DATABASE=Gauging Systems Inc
+
+OUI:0050C223E*
+ ID_OUI_FROM_DATABASE=Kallastra Inc.
+
+OUI:0050C223F*
+ ID_OUI_FROM_DATABASE=Halliburton - NUMAR
+
+OUI:0050C2240*
+ ID_OUI_FROM_DATABASE=Geoquip Ltd
+
+OUI:0050C2241*
+ ID_OUI_FROM_DATABASE=Contronics Automacao Ltda
+
+OUI:0050C2242*
+ ID_OUI_FROM_DATABASE=MDS SCIEX
+
+OUI:0050C2243*
+ ID_OUI_FROM_DATABASE=RGB Spectrum
+
+OUI:0050C2244*
+ ID_OUI_FROM_DATABASE=intec GmbH
+
+OUI:0050C2245*
+ ID_OUI_FROM_DATABASE=Hauppauge Computer Works, Inc.
+
+OUI:0050C2246*
+ ID_OUI_FROM_DATABASE=Hardmeier
+
+OUI:0050C2247*
+ ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda.
+
+OUI:0050C2248*
+ ID_OUI_FROM_DATABASE=Dixtal Biomedica Ind. Com. Ltda.
+
+OUI:0050C2249*
+ ID_OUI_FROM_DATABASE=Dipl.-Ing. W. Bender GmbH & Co. KG
+
+OUI:0050C224A*
+ ID_OUI_FROM_DATABASE=CDS Rail
+
+OUI:0050C224B*
+ ID_OUI_FROM_DATABASE=Azimuth Systems, Inc.
+
+OUI:0050C224C*
+ ID_OUI_FROM_DATABASE=Supertel
+
+OUI:0050C224D*
+ ID_OUI_FROM_DATABASE=METTLER-TOLEDO HI-SPEED
+
+OUI:0050C224E*
+ ID_OUI_FROM_DATABASE=Scharff Weisberg Systems Integration Inc
+
+OUI:0050C224F*
+ ID_OUI_FROM_DATABASE=Macronet s.r.l.
+
+OUI:0050C2250*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C2251*
+ ID_OUI_FROM_DATABASE=DGT Sp. z o.o.
+
+OUI:0050C2252*
+ ID_OUI_FROM_DATABASE=ads-tec GmbH
+
+OUI:0050C2253*
+ ID_OUI_FROM_DATABASE=DSM-Messtechnik GmbH
+
+OUI:0050C2254*
+ ID_OUI_FROM_DATABASE=Thales Communications Ltd
+
+OUI:0050C2255*
+ ID_OUI_FROM_DATABASE=STMicroelectronics (R&D) Ltd
+
+OUI:0050C2256*
+ ID_OUI_FROM_DATABASE=Information Technology Corp.
+
+OUI:0050C2257*
+ ID_OUI_FROM_DATABASE=Digicast Networks
+
+OUI:0050C2258*
+ ID_OUI_FROM_DATABASE=Spacesaver Corporation
+
+OUI:0050C2259*
+ ID_OUI_FROM_DATABASE=Omicron Ceti AB
+
+OUI:0050C225A*
+ ID_OUI_FROM_DATABASE=Zendex Corporation
+
+OUI:0050C225B*
+ ID_OUI_FROM_DATABASE=Winford Engineering
+
+OUI:0050C225C*
+ ID_OUI_FROM_DATABASE=Softhill Technologies Ltd.
+
+OUI:0050C225D*
+ ID_OUI_FROM_DATABASE=RDTECH
+
+OUI:0050C225E*
+ ID_OUI_FROM_DATABASE=MITE Hradec Kralove, s.r.o.
+
+OUI:0050C225F*
+ ID_OUI_FROM_DATABASE=Handtmann Maschinenfabrik GmbH&Co.KG
+
+OUI:0050C2260*
+ ID_OUI_FROM_DATABASE=BIOTAGE
+
+OUI:0050C2261*
+ ID_OUI_FROM_DATABASE=Tattile Srl
+
+OUI:0050C2262*
+ ID_OUI_FROM_DATABASE=Shanghai Gaozhi Science&Technology Development Ltd.
+
+OUI:0050C2263*
+ ID_OUI_FROM_DATABASE=Vansco Electronics Oy
+
+OUI:0050C2264*
+ ID_OUI_FROM_DATABASE=Confidence Direct Ltd
+
+OUI:0050C2265*
+ ID_OUI_FROM_DATABASE=BELIK S.P.R.L.
+
+OUI:0050C2266*
+ ID_OUI_FROM_DATABASE=ATOM GIKEN Co.,Ltd.
+
+OUI:0050C2267*
+ ID_OUI_FROM_DATABASE=Allen Martin Conservation Ltd
+
+OUI:0050C2268*
+ ID_OUI_FROM_DATABASE=Parabit Systems
+
+OUI:0050C2269*
+ ID_OUI_FROM_DATABASE=Technisyst Pty Ltd
+
+OUI:0050C226A*
+ ID_OUI_FROM_DATABASE=FG SYNERYS
+
+OUI:0050C226B*
+ ID_OUI_FROM_DATABASE=Continental Gateway Limited
+
+OUI:0050C226C*
+ ID_OUI_FROM_DATABASE=Crystal Vision Ltd
+
+OUI:0050C226D*
+ ID_OUI_FROM_DATABASE=DSP DESIGN
+
+OUI:0050C226E*
+ ID_OUI_FROM_DATABASE=ZP Engineering srl
+
+OUI:0050C226F*
+ ID_OUI_FROM_DATABASE=Digital Recorders Inc
+
+OUI:0050C2270*
+ ID_OUI_FROM_DATABASE=S4 Technology Pty Ltd
+
+OUI:0050C2271*
+ ID_OUI_FROM_DATABASE=VLSIP TECHNOLOGIES INC.
+
+OUI:0050C2272*
+ ID_OUI_FROM_DATABASE=Verex Technology
+
+OUI:0050C2273*
+ ID_OUI_FROM_DATABASE=Servicios Condumex, S. A. de C. V.
+
+OUI:0050C2274*
+ ID_OUI_FROM_DATABASE=Fundación ROBOTIKER
+
+OUI:0050C2275*
+ ID_OUI_FROM_DATABASE=Extreme Engineering Solutions
+
+OUI:0050C2276*
+ ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd
+
+OUI:0050C2277*
+ ID_OUI_FROM_DATABASE=T/R Systems, Inc.
+
+OUI:0050C2278*
+ ID_OUI_FROM_DATABASE=Replicom Ltd.
+
+OUI:0050C2279*
+ ID_OUI_FROM_DATABASE=PATLITE Corporation
+
+OUI:0050C227A*
+ ID_OUI_FROM_DATABASE=Maestro Pty Ltd
+
+OUI:0050C227B*
+ ID_OUI_FROM_DATABASE=LinkSecurity A/S
+
+OUI:0050C227C*
+ ID_OUI_FROM_DATABASE=Danlaw Inc
+
+OUI:0050C227D*
+ ID_OUI_FROM_DATABASE=ALLIED TELESIS K.K.
+
+OUI:0050C227E*
+ ID_OUI_FROM_DATABASE=AnaLogic Computers Ltd.
+
+OUI:0050C227F*
+ ID_OUI_FROM_DATABASE=Air Broadband Communications, Inc.
+
+OUI:0050C2280*
+ ID_OUI_FROM_DATABASE=AGECODAGIS SARL
+
+OUI:0050C2281*
+ ID_OUI_FROM_DATABASE=CabTronix GmbH
+
+OUI:0050C2282*
+ ID_OUI_FROM_DATABASE=Telvent
+
+OUI:0050C2283*
+ ID_OUI_FROM_DATABASE=ANSITEX CORP.
+
+OUI:0050C2284*
+ ID_OUI_FROM_DATABASE=Micronet Ltd.
+
+OUI:0050C2285*
+ ID_OUI_FROM_DATABASE=Littwin GmbH & Co KG
+
+OUI:0050C2286*
+ ID_OUI_FROM_DATABASE=ATEME
+
+OUI:0050C2287*
+ ID_OUI_FROM_DATABASE=TECNEW Electronics Engineering Cr., Ltd.
+
+OUI:0050C2288*
+ ID_OUI_FROM_DATABASE=RPM Systems Corporation
+
+OUI:0050C2289*
+ ID_OUI_FROM_DATABASE=Rototype S.p.A.
+
+OUI:0050C228A*
+ ID_OUI_FROM_DATABASE=Real Time Systems
+
+OUI:0050C228B*
+ ID_OUI_FROM_DATABASE=Orion Technologies, Incorporated
+
+OUI:0050C228C*
+ ID_OUI_FROM_DATABASE=Futaba Corporation
+
+OUI:0050C228D*
+ ID_OUI_FROM_DATABASE=AXODE SA
+
+OUI:0050C228E*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:0050C228F*
+ ID_OUI_FROM_DATABASE=Spellman High Voltage Electronics Corp
+
+OUI:0050C2290*
+ ID_OUI_FROM_DATABASE=EBNEURO SPA
+
+OUI:0050C2291*
+ ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX
+
+OUI:0050C2292*
+ ID_OUI_FROM_DATABASE=AMIRIX Systems
+
+OUI:0050C2293*
+ ID_OUI_FROM_DATABASE=IP Unity
+
+OUI:0050C2294*
+ ID_OUI_FROM_DATABASE=EPSa GmbH
+
+OUI:0050C2295*
+ ID_OUI_FROM_DATABASE=LOGOSOL, INC.
+
+OUI:0050C2296*
+ ID_OUI_FROM_DATABASE=OpVista
+
+OUI:0050C2297*
+ ID_OUI_FROM_DATABASE=KINETICS
+
+OUI:0050C2298*
+ ID_OUI_FROM_DATABASE=Harvad University
+
+OUI:0050C2299*
+ ID_OUI_FROM_DATABASE=CAD-UL GmbH
+
+OUI:0050C229A*
+ ID_OUI_FROM_DATABASE=Packet Techniques Inc.
+
+OUI:0050C229B*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C229C*
+ ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s.
+
+OUI:0050C229D*
+ ID_OUI_FROM_DATABASE=Globe Wireless
+
+OUI:0050C229E*
+ ID_OUI_FROM_DATABASE=SELEX Communications Ltd
+
+OUI:0050C229F*
+ ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH
+
+OUI:0050C22A0*
+ ID_OUI_FROM_DATABASE=Sterling Industry Consult GmbH
+
+OUI:0050C22A1*
+ ID_OUI_FROM_DATABASE=Infinetix Corp
+
+OUI:0050C22A2*
+ ID_OUI_FROM_DATABASE=Epelsa, SL
+
+OUI:0050C22A3*
+ ID_OUI_FROM_DATABASE=West-Com Nurse Call Systems, Inc.
+
+OUI:0050C22A4*
+ ID_OUI_FROM_DATABASE=Xipher Embedded Networking
+
+OUI:0050C22A5*
+ ID_OUI_FROM_DATABASE=Septier Communication Ltd
+
+OUI:0050C22A6*
+ ID_OUI_FROM_DATABASE=Brannstroms Elektronik AB
+
+OUI:0050C22A7*
+ ID_OUI_FROM_DATABASE=Micro System Architecturing srl
+
+OUI:0050C22A8*
+ ID_OUI_FROM_DATABASE=DVTel Israel Ltd.
+
+OUI:0050C22A9*
+ ID_OUI_FROM_DATABASE=Dr. Staiger, Mohilo + Co GmbH
+
+OUI:0050C22AA*
+ ID_OUI_FROM_DATABASE=DEUTA Werke GmbH
+
+OUI:0050C22AB*
+ ID_OUI_FROM_DATABASE=AUM Infotech Private Limited
+
+OUI:0050C22AC*
+ ID_OUI_FROM_DATABASE=BBI Engineering, Inc.
+
+OUI:0050C22AD*
+ ID_OUI_FROM_DATABASE=ABB T&D Spa
+
+OUI:0050C22AE*
+ ID_OUI_FROM_DATABASE=Quest Retail Technology Pty Ltd
+
+OUI:0050C22AF*
+ ID_OUI_FROM_DATABASE=CSA  Computer & Antriebstechnik GmbH
+
+OUI:0050C22B0*
+ ID_OUI_FROM_DATABASE=Telda Electronics
+
+OUI:0050C22B2*
+ ID_OUI_FROM_DATABASE=Smiths Detection
+
+OUI:0050C22B3*
+ ID_OUI_FROM_DATABASE=Embedded Systems Design
+
+OUI:0050C22B4*
+ ID_OUI_FROM_DATABASE=Polatis Ltd
+
+OUI:0050C22B5*
+ ID_OUI_FROM_DATABASE=Hobbes Computer Network Accessories
+
+OUI:0050C22B6*
+ ID_OUI_FROM_DATABASE=Softier Inc.
+
+OUI:0050C22B7*
+ ID_OUI_FROM_DATABASE=Rafi GmbH & Co. KG
+
+OUI:0050C22B8*
+ ID_OUI_FROM_DATABASE=Admiral Secure Products, Ltd.
+
+OUI:0050C22B9*
+ ID_OUI_FROM_DATABASE=Richmond Sound Design Ltd.
+
+OUI:0050C22BA*
+ ID_OUI_FROM_DATABASE=NORCO INDUSTRIAL TECHNOLOGY INC
+
+OUI:0050C22BB*
+ ID_OUI_FROM_DATABASE=TA Instruments Ltd
+
+OUI:0050C22BC*
+ ID_OUI_FROM_DATABASE=Uster Technologies AG
+
+OUI:0050C22BD*
+ ID_OUI_FROM_DATABASE=StorLink Semi
+
+OUI:0050C22BE*
+ ID_OUI_FROM_DATABASE=Lipowsky Industrie-Elektronik GmbH
+
+OUI:0050C22BF*
+ ID_OUI_FROM_DATABASE=PERAX
+
+OUI:0050C22C0*
+ ID_OUI_FROM_DATABASE=Magellan Technology Pty Ltd
+
+OUI:0050C22C1*
+ ID_OUI_FROM_DATABASE=Stage Tec Entwicklungsgesellschaft für professionelle Audio
+
+OUI:0050C22C2*
+ ID_OUI_FROM_DATABASE=smarteye corporation
+
+OUI:0050C22C3*
+ ID_OUI_FROM_DATABASE=Digital SP Ltd
+
+OUI:0050C22C4*
+ ID_OUI_FROM_DATABASE=Invensys Energy Systens (NZ) Limited
+
+OUI:0050C22C5*
+ ID_OUI_FROM_DATABASE=Elman srl
+
+OUI:0050C22C6*
+ ID_OUI_FROM_DATABASE=Initial Electronic Security Systems
+
+OUI:0050C22C7*
+ ID_OUI_FROM_DATABASE=Siliquent Technologies Ltd
+
+OUI:0050C22C8*
+ ID_OUI_FROM_DATABASE=SELCO
+
+OUI:0050C22C9*
+ ID_OUI_FROM_DATABASE=Roseman Engineering Ltd.
+
+OUI:0050C22CA*
+ ID_OUI_FROM_DATABASE=PUTERCOM CO., LTD
+
+OUI:0050C22CB*
+ ID_OUI_FROM_DATABASE=FACTS Engineering LLC
+
+OUI:0050C22CC*
+ ID_OUI_FROM_DATABASE=EMBEDDED TOOLSMITHS
+
+OUI:0050C22CD*
+ ID_OUI_FROM_DATABASE=DataWind Research
+
+OUI:0050C22CE*
+ ID_OUI_FROM_DATABASE=Ross Video Limited
+
+OUI:0050C22CF*
+ ID_OUI_FROM_DATABASE=Diseño de Sistemas en Silicio S.A.
+
+OUI:0050C22D0*
+ ID_OUI_FROM_DATABASE=Worth Data, Inc.
+
+OUI:0050C22D1*
+ ID_OUI_FROM_DATABASE=Miritek, Inc.
+
+OUI:0050C22D2*
+ ID_OUI_FROM_DATABASE=AIRNET COMMUNICATIONS CORP
+
+OUI:0050C22D3*
+ ID_OUI_FROM_DATABASE=Gerber Scientific Products, Inc.
+
+OUI:0050C22D4*
+ ID_OUI_FROM_DATABASE=Integrated System Solution Corp.
+
+OUI:0050C22D5*
+ ID_OUI_FROM_DATABASE=PIXY AG
+
+OUI:0050C22D6*
+ ID_OUI_FROM_DATABASE=WIS Technologies
+
+OUI:0050C22D7*
+ ID_OUI_FROM_DATABASE=Neo Electronics Ltd
+
+OUI:0050C22D8*
+ ID_OUI_FROM_DATABASE=SYN-TECH SYSTEMS INC
+
+OUI:0050C22DA*
+ ID_OUI_FROM_DATABASE=PYRAMID Computer GmbH
+
+OUI:0050C22DB*
+ ID_OUI_FROM_DATABASE=AutoTOOLS group Co. Ltd.
+
+OUI:0050C22DC*
+ ID_OUI_FROM_DATABASE=Wiener, Plein & Baus GmbH
+
+OUI:0050C22DD*
+ ID_OUI_FROM_DATABASE=Westek Technology Ltd
+
+OUI:0050C22DE*
+ ID_OUI_FROM_DATABASE=Research Applications
+
+OUI:0050C22DF*
+ ID_OUI_FROM_DATABASE=MICREL-NKE
+
+OUI:0050C22E0*
+ ID_OUI_FROM_DATABASE=Baxter Healthcare
+
+OUI:0050C22E1*
+ ID_OUI_FROM_DATABASE=Access IS
+
+OUI:0050C22E2*
+ ID_OUI_FROM_DATABASE=Ballard Technology, Inc.
+
+OUI:0050C22E3*
+ ID_OUI_FROM_DATABASE=MG Industrieelektronik GmbH
+
+OUI:0050C22E4*
+ ID_OUI_FROM_DATABASE=iamba LTD.
+
+OUI:0050C22E5*
+ ID_OUI_FROM_DATABASE=Transtech DSP
+
+OUI:0050C22E6*
+ ID_OUI_FROM_DATABASE=DALSA
+
+OUI:0050C22E7*
+ ID_OUI_FROM_DATABASE=SafeView, Inc.
+
+OUI:0050C22E8*
+ ID_OUI_FROM_DATABASE=S.M.V. Systemelektronik GmbH
+
+OUI:0050C22E9*
+ ID_OUI_FROM_DATABASE=SRI International
+
+OUI:0050C22EA*
+ ID_OUI_FROM_DATABASE=QUBIsoft S.r.l.
+
+OUI:0050C22EB*
+ ID_OUI_FROM_DATABASE=Lingg & Janke OHG
+
+OUI:0050C22EC*
+ ID_OUI_FROM_DATABASE=CHENGDU  BOOK DIGITAL CO., LTD
+
+OUI:0050C22ED*
+ ID_OUI_FROM_DATABASE=4RF Communications Ltd
+
+OUI:0050C22EE*
+ ID_OUI_FROM_DATABASE=SHF Communication Technologies AG
+
+OUI:0050C22EF*
+ ID_OUI_FROM_DATABASE=Profline B.V.
+
+OUI:0050C22F0*
+ ID_OUI_FROM_DATABASE=LECO Corporation
+
+OUI:0050C22F1*
+ ID_OUI_FROM_DATABASE=Geometrics, Inc.
+
+OUI:0050C22F2*
+ ID_OUI_FROM_DATABASE=Eurotek Srl
+
+OUI:0050C22F3*
+ ID_OUI_FROM_DATABASE=Crossbow Technology, Inc.
+
+OUI:0050C22F4*
+ ID_OUI_FROM_DATABASE=Efficient Channel Coding
+
+OUI:0050C22F5*
+ ID_OUI_FROM_DATABASE=ADChips
+
+OUI:0050C22F6*
+ ID_OUI_FROM_DATABASE=Clifford Chance LLP
+
+OUI:0050C22F7*
+ ID_OUI_FROM_DATABASE=GILLAM-FEI S.A.
+
+OUI:0050C22F8*
+ ID_OUI_FROM_DATABASE=SavvyCorp.com Ltd
+
+OUI:0050C22F9*
+ ID_OUI_FROM_DATABASE=Digilent Inc.
+
+OUI:0050C22FA*
+ ID_OUI_FROM_DATABASE=Tornado Modular Systems, Ltd
+
+OUI:0050C22FB*
+ ID_OUI_FROM_DATABASE=Arthur Industries Inc., dba On Hold Media Group
+
+OUI:0050C22FC*
+ ID_OUI_FROM_DATABASE=Blackline Systems Corporation
+
+OUI:0050C22FD*
+ ID_OUI_FROM_DATABASE=American Microsystems LTD
+
+OUI:0050C22FE*
+ ID_OUI_FROM_DATABASE=Saab AB
+
+OUI:0050C22FF*
+ ID_OUI_FROM_DATABASE=Patria Advanced Solutions
+
+OUI:0050C2300*
+ ID_OUI_FROM_DATABASE=Soredex Instrumentarium Oyj
+
+OUI:0050C2301*
+ ID_OUI_FROM_DATABASE=Delphi Display Systems, Inc.
+
+OUI:0050C2302*
+ ID_OUI_FROM_DATABASE=EuroDesign embedded technologies GmbH
+
+OUI:0050C2303*
+ ID_OUI_FROM_DATABASE=CI Systems Ltd.
+
+OUI:0050C2304*
+ ID_OUI_FROM_DATABASE=COMERSON S.r.l.
+
+OUI:0050C2305*
+ ID_OUI_FROM_DATABASE=Symbium Corporation
+
+OUI:0050C2306*
+ ID_OUI_FROM_DATABASE=Noran Tel Communications Ltd.
+
+OUI:0050C2307*
+ ID_OUI_FROM_DATABASE=UNIONDIGITAL.,CO.LTD
+
+OUI:0050C2308*
+ ID_OUI_FROM_DATABASE=FiveCo
+
+OUI:0050C2309*
+ ID_OUI_FROM_DATABASE=Rackmaster Systems, Inc.
+
+OUI:0050C230A*
+ ID_OUI_FROM_DATABASE=Innings Telecom Inc.
+
+OUI:0050C230B*
+ ID_OUI_FROM_DATABASE=VX Technologies Inc.
+
+OUI:0050C230C*
+ ID_OUI_FROM_DATABASE=TEAMLOG
+
+OUI:0050C230D*
+ ID_OUI_FROM_DATABASE=SETARAM
+
+OUI:0050C230E*
+ ID_OUI_FROM_DATABASE=Obvius
+
+OUI:0050C230F*
+ ID_OUI_FROM_DATABASE=Digicontrole Lda
+
+OUI:0050C2310*
+ ID_OUI_FROM_DATABASE=CYBERTRON CO., LTD.
+
+OUI:0050C2311*
+ ID_OUI_FROM_DATABASE=Comodo
+
+OUI:0050C2312*
+ ID_OUI_FROM_DATABASE=Dese Technologies SL
+
+OUI:0050C2313*
+ ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG
+
+OUI:0050C2314*
+ ID_OUI_FROM_DATABASE=MicroBee Systems, Inc
+
+OUI:0050C2315*
+ ID_OUI_FROM_DATABASE=ifak system GmbH
+
+OUI:0050C2316*
+ ID_OUI_FROM_DATABASE=Dataline AB
+
+OUI:0050C2317*
+ ID_OUI_FROM_DATABASE=Cosine Systems, Inc.
+
+OUI:0050C2318*
+ ID_OUI_FROM_DATABASE=Milmega Ltd
+
+OUI:0050C2319*
+ ID_OUI_FROM_DATABASE=Invatron Systems Corp.
+
+OUI:0050C231A*
+ ID_OUI_FROM_DATABASE=IN-SNEC ZODIAC
+
+OUI:0050C231B*
+ ID_OUI_FROM_DATABASE=Datacon
+
+OUI:0050C231C*
+ ID_OUI_FROM_DATABASE=Casa Systems Inc.
+
+OUI:0050C231D*
+ ID_OUI_FROM_DATABASE=Imarda New Zealand Limited
+
+OUI:0050C231E*
+ ID_OUI_FROM_DATABASE=C3-ilex, LLC
+
+OUI:0050C231F*
+ ID_OUI_FROM_DATABASE=Geotech Instruments, LLC
+
+OUI:0050C2320*
+ ID_OUI_FROM_DATABASE=DTASENSOR S.p.A.
+
+OUI:0050C2321*
+ ID_OUI_FROM_DATABASE=UXP
+
+OUI:0050C2322*
+ ID_OUI_FROM_DATABASE=BQT Solutions (Australia) Limited
+
+OUI:0050C2323*
+ ID_OUI_FROM_DATABASE=Red Rock Networks
+
+OUI:0050C2324*
+ ID_OUI_FROM_DATABASE=ODIXION
+
+OUI:0050C2325*
+ ID_OUI_FROM_DATABASE=Federal Aviation Administration
+
+OUI:0050C2326*
+ ID_OUI_FROM_DATABASE=Navionics S.p.A.
+
+OUI:0050C2327*
+ ID_OUI_FROM_DATABASE=Dornier GmbH
+
+OUI:0050C2328*
+ ID_OUI_FROM_DATABASE=I.C.S. Electronics Limited
+
+OUI:0050C2329*
+ ID_OUI_FROM_DATABASE=Imax
+
+OUI:0050C232A*
+ ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH
+
+OUI:0050C232B*
+ ID_OUI_FROM_DATABASE=Digital Multimedia Technologies Spa
+
+OUI:0050C232C*
+ ID_OUI_FROM_DATABASE=Integrated Silicon Solution (Taiwan), Inc.
+
+OUI:0050C232D*
+ ID_OUI_FROM_DATABASE=Consens Zeiterfassung GMBH
+
+OUI:0050C232E*
+ ID_OUI_FROM_DATABASE=MANUSA-GEST, S.L.
+
+OUI:0050C232F*
+ ID_OUI_FROM_DATABASE=PULTRONICS
+
+OUI:0050C2330*
+ ID_OUI_FROM_DATABASE=Sicon S.r.l.
+
+OUI:0050C2331*
+ ID_OUI_FROM_DATABASE=Broadcast Sports Inc
+
+OUI:0050C2332*
+ ID_OUI_FROM_DATABASE=PUNJAB COMMUNICATIONS LTD
+
+OUI:0050C2333*
+ ID_OUI_FROM_DATABASE=Radix Corporation
+
+OUI:0050C2334*
+ ID_OUI_FROM_DATABASE=Picture Elements, Inc.
+
+OUI:0050C2335*
+ ID_OUI_FROM_DATABASE=Nimcat Networks
+
+OUI:0050C2336*
+ ID_OUI_FROM_DATABASE=Golden River Traffic
+
+OUI:0050C2337*
+ ID_OUI_FROM_DATABASE=ETI
+
+OUI:0050C2338*
+ ID_OUI_FROM_DATABASE=Ernitec A/S
+
+OUI:0050C2339*
+ ID_OUI_FROM_DATABASE=CEGELEC SUD EST
+
+OUI:0050C233A*
+ ID_OUI_FROM_DATABASE=United Telecoms Ltd
+
+OUI:0050C233B*
+ ID_OUI_FROM_DATABASE=MultimediaLED
+
+OUI:0050C233C*
+ ID_OUI_FROM_DATABASE=SkipJam
+
+OUI:0050C233D*
+ ID_OUI_FROM_DATABASE=General Dynamics Decision Systems
+
+OUI:0050C233E*
+ ID_OUI_FROM_DATABASE=CA Technology, Inc
+
+OUI:0050C233F*
+ ID_OUI_FROM_DATABASE=EXYS bvba
+
+OUI:0050C2340*
+ ID_OUI_FROM_DATABASE=Virtu
+
+OUI:0050C2341*
+ ID_OUI_FROM_DATABASE=Novx Systems Canada Inc.
+
+OUI:0050C2342*
+ ID_OUI_FROM_DATABASE=St. Michael Strategies
+
+OUI:0050C2343*
+ ID_OUI_FROM_DATABASE=ABB Xiamen Switchgear Co. Ltd.
+
+OUI:0050C2344*
+ ID_OUI_FROM_DATABASE=ads-tec GmbH
+
+OUI:0050C2345*
+ ID_OUI_FROM_DATABASE=ACT
+
+OUI:0050C2346*
+ ID_OUI_FROM_DATABASE=biokeysystem
+
+OUI:0050C2347*
+ ID_OUI_FROM_DATABASE=Row Seven Ltd
+
+OUI:0050C2348*
+ ID_OUI_FROM_DATABASE=KoolSpan, Inc.
+
+OUI:0050C2349*
+ ID_OUI_FROM_DATABASE=SSI Schaefer Peem
+
+OUI:0050C234A*
+ ID_OUI_FROM_DATABASE=NIE Corporation
+
+OUI:0050C234B*
+ ID_OUI_FROM_DATABASE=Ecutel Systems, Inc.
+
+OUI:0050C234C*
+ ID_OUI_FROM_DATABASE=Chuo Electric Works Co., LTD.
+
+OUI:0050C234D*
+ ID_OUI_FROM_DATABASE=BMK professional electronics GmbH
+
+OUI:0050C234E*
+ ID_OUI_FROM_DATABASE=ABB Power Technologies S.p.A.  Unità  Operativa SACE (PTMV)
+
+OUI:0050C234F*
+ ID_OUI_FROM_DATABASE=North Pole Engineering, Inc.
+
+OUI:0050C2350*
+ ID_OUI_FROM_DATABASE=Kinesys Projects Limited
+
+OUI:0050C2351*
+ ID_OUI_FROM_DATABASE=Finesystem Co., Ltd
+
+OUI:0050C2352*
+ ID_OUI_FROM_DATABASE=edixia
+
+OUI:0050C2353*
+ ID_OUI_FROM_DATABASE=Crossing Informationssysteme GmbH
+
+OUI:0050C2354*
+ ID_OUI_FROM_DATABASE=Advanced IP Communications
+
+OUI:0050C2355*
+ ID_OUI_FROM_DATABASE=IHM
+
+OUI:0050C2356*
+ ID_OUI_FROM_DATABASE=Baytech Cinema
+
+OUI:0050C2357*
+ ID_OUI_FROM_DATABASE=Athena Semiconductor
+
+OUI:0050C2358*
+ ID_OUI_FROM_DATABASE=ALCEA
+
+OUI:0050C2359*
+ ID_OUI_FROM_DATABASE=Kramer Electronics Ltd.
+
+OUI:0050C235A*
+ ID_OUI_FROM_DATABASE=Advanced Si-Net Co., LTD.
+
+OUI:0050C235B*
+ ID_OUI_FROM_DATABASE=VLSIP TECHNOLOGIES, INC
+
+OUI:0050C235C*
+ ID_OUI_FROM_DATABASE=Ratotec GmbH
+
+OUI:0050C235D*
+ ID_OUI_FROM_DATABASE=NetTest A/S
+
+OUI:0050C235E*
+ ID_OUI_FROM_DATABASE=Jobin Yvon,Inc
+
+OUI:0050C235F*
+ ID_OUI_FROM_DATABASE=F.Imm. S.r.L.
+
+OUI:0050C2360*
+ ID_OUI_FROM_DATABASE=Digital Receiver Technology, Inc.
+
+OUI:0050C2361*
+ ID_OUI_FROM_DATABASE=Contec
+
+OUI:0050C2362*
+ ID_OUI_FROM_DATABASE=AZD Praha s.r.o.
+
+OUI:0050C2363*
+ ID_OUI_FROM_DATABASE=Septentrio nv/sa
+
+OUI:0050C2364*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:0050C2365*
+ ID_OUI_FROM_DATABASE=Vishay Nobel AB
+
+OUI:0050C2366*
+ ID_OUI_FROM_DATABASE=Vanguard Technology Corp.
+
+OUI:0050C2367*
+ ID_OUI_FROM_DATABASE=CANMAX Technology Ltd.
+
+OUI:0050C2368*
+ ID_OUI_FROM_DATABASE=ASPEL S.A.
+
+OUI:0050C2369*
+ ID_OUI_FROM_DATABASE=Always On Wireless
+
+OUI:0050C236A*
+ ID_OUI_FROM_DATABASE=Optronic Partner pr AB
+
+OUI:0050C236B*
+ ID_OUI_FROM_DATABASE=Minerva Technology Inc
+
+OUI:0050C236C*
+ ID_OUI_FROM_DATABASE=RISCO Group
+
+OUI:0050C236D*
+ ID_OUI_FROM_DATABASE=Oplink Communications
+
+OUI:0050C236E*
+ ID_OUI_FROM_DATABASE=Minicom Advanced Systems Ltd
+
+OUI:0050C236F*
+ ID_OUI_FROM_DATABASE=SOFTHARD Technology Ltd
+
+OUI:0050C2370*
+ ID_OUI_FROM_DATABASE=Europe Technologies
+
+OUI:0050C2371*
+ ID_OUI_FROM_DATABASE=DIGITAL ART SYSTEM
+
+OUI:0050C2372*
+ ID_OUI_FROM_DATABASE=ELV Elektronik AG
+
+OUI:0050C2373*
+ ID_OUI_FROM_DATABASE=Companion Worlds, inc.
+
+OUI:0050C2374*
+ ID_OUI_FROM_DATABASE=Owasys Advanced Wireless Devices
+
+OUI:0050C2375*
+ ID_OUI_FROM_DATABASE=TIR Systems Ltd.
+
+OUI:0050C2376*
+ ID_OUI_FROM_DATABASE=CLEODE
+
+OUI:0050C2377*
+ ID_OUI_FROM_DATABASE=Xycom VME
+
+OUI:0050C2378*
+ ID_OUI_FROM_DATABASE=Daintree Networks Inc
+
+OUI:0050C2379*
+ ID_OUI_FROM_DATABASE=Control LAN S.A.
+
+OUI:0050C237A*
+ ID_OUI_FROM_DATABASE=IDA Corporation
+
+OUI:0050C237B*
+ ID_OUI_FROM_DATABASE=freescale semiconductor
+
+OUI:0050C237C*
+ ID_OUI_FROM_DATABASE=MODIA SYSTEMS Co., Ltd
+
+OUI:0050C237D*
+ ID_OUI_FROM_DATABASE=VeroTrak Inc.
+
+OUI:0050C237E*
+ ID_OUI_FROM_DATABASE=Ni.Co. S.r.l.
+
+OUI:0050C237F*
+ ID_OUI_FROM_DATABASE=Foresearch
+
+OUI:0050C2380*
+ ID_OUI_FROM_DATABASE=EKE-Electronics Ltd.
+
+OUI:0050C2381*
+ ID_OUI_FROM_DATABASE=Realtime Engineering AG
+
+OUI:0050C2382*
+ ID_OUI_FROM_DATABASE=Colorado vNet
+
+OUI:0050C2383*
+ ID_OUI_FROM_DATABASE=ICS Electronics
+
+OUI:0050C2384*
+ ID_OUI_FROM_DATABASE=Wireless Reading Systems Holding ASA
+
+OUI:0050C2385*
+ ID_OUI_FROM_DATABASE=SUNGJIN NEOTECH Co.Ltd.
+
+OUI:0050C2386*
+ ID_OUI_FROM_DATABASE=Precision System Science Co.,Ltd
+
+OUI:0050C2387*
+ ID_OUI_FROM_DATABASE=Inoteska s.r.o.
+
+OUI:0050C2388*
+ ID_OUI_FROM_DATABASE=IEE Inc
+
+OUI:0050C2389*
+ ID_OUI_FROM_DATABASE=Exavio Inc.
+
+OUI:0050C238A*
+ ID_OUI_FROM_DATABASE=Embedtronics Enterprise
+
+OUI:0050C238B*
+ ID_OUI_FROM_DATABASE=InterBridge,Inc.
+
+OUI:0050C238C*
+ ID_OUI_FROM_DATABASE=EPSILON SRL
+
+OUI:0050C238D*
+ ID_OUI_FROM_DATABASE=A&G Soluzioni Digitali
+
+OUI:0050C238E*
+ ID_OUI_FROM_DATABASE=Nordic Alarm AB
+
+OUI:0050C238F*
+ ID_OUI_FROM_DATABASE=TTC Telecom
+
+OUI:0050C2390*
+ ID_OUI_FROM_DATABASE=TC Communications
+
+OUI:0050C2391*
+ ID_OUI_FROM_DATABASE=Esensors, Inc.
+
+OUI:0050C2392*
+ ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH
+
+OUI:0050C2393*
+ ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH
+
+OUI:0050C2394*
+ ID_OUI_FROM_DATABASE=Embedit A/S
+
+OUI:0050C2395*
+ ID_OUI_FROM_DATABASE=vidisys gmbh
+
+OUI:0050C2396*
+ ID_OUI_FROM_DATABASE=RapidWave Inc.
+
+OUI:0050C2397*
+ ID_OUI_FROM_DATABASE=MANGO DSP Ltd.
+
+OUI:0050C2398*
+ ID_OUI_FROM_DATABASE=InHand Electronics, Inc.
+
+OUI:0050C2399*
+ ID_OUI_FROM_DATABASE=Advanced Micro Controls Inc.
+
+OUI:0050C239A*
+ ID_OUI_FROM_DATABASE=Optical Air Data Systems
+
+OUI:0050C239B*
+ ID_OUI_FROM_DATABASE=YUYAMA MFG. CO., LTD.
+
+OUI:0050C239C*
+ ID_OUI_FROM_DATABASE=TIYODA MFG CO.,LTD.
+
+OUI:0050C239D*
+ ID_OUI_FROM_DATABASE=DigitalDeck, Inc.
+
+OUI:0050C239E*
+ ID_OUI_FROM_DATABASE=A.R.G ElectroDesign Ltd
+
+OUI:0050C239F*
+ ID_OUI_FROM_DATABASE=Isensix
+
+OUI:0050C23A0*
+ ID_OUI_FROM_DATABASE=StreetFire Sound Labs, LLC
+
+OUI:0050C23A1*
+ ID_OUI_FROM_DATABASE=Samsoft
+
+OUI:0050C23A2*
+ ID_OUI_FROM_DATABASE=Vegas Amusement
+
+OUI:0050C23A3*
+ ID_OUI_FROM_DATABASE=Star Link Communication Pvt. Ltd.
+
+OUI:0050C23A4*
+ ID_OUI_FROM_DATABASE=Silvertree Engineering Ltd
+
+OUI:0050C23A5*
+ ID_OUI_FROM_DATABASE=LabJack Corporation
+
+OUI:0050C23A6*
+ ID_OUI_FROM_DATABASE=IntelliDesign Pty Ltd
+
+OUI:0050C23A7*
+ ID_OUI_FROM_DATABASE=Elektrotechnik & Elektronik Oltmann GmbH
+
+OUI:0050C23A8*
+ ID_OUI_FROM_DATABASE=Engim, Inc.
+
+OUI:0050C23A9*
+ ID_OUI_FROM_DATABASE=Westronic Systems Inc.
+
+OUI:0050C23AA*
+ ID_OUI_FROM_DATABASE=Networked Robotics Corporation
+
+OUI:0050C23AB*
+ ID_OUI_FROM_DATABASE=taskit Rechnertechnik GmbH
+
+OUI:0050C23AC*
+ ID_OUI_FROM_DATABASE=InAccess Networks
+
+OUI:0050C23AD*
+ ID_OUI_FROM_DATABASE=Spirent Communications (Scotland) Limited
+
+OUI:0050C23AE*
+ ID_OUI_FROM_DATABASE=Hankuk Tapi Computer Co., Ltd
+
+OUI:0050C23AF*
+ ID_OUI_FROM_DATABASE=Norbit AS
+
+OUI:0050C23B0*
+ ID_OUI_FROM_DATABASE=Microtarget Tecnologia Digital Ltda.
+
+OUI:0050C23B1*
+ ID_OUI_FROM_DATABASE=RDC Specstroy-Svyaz Ltd
+
+OUI:0050C23B2*
+ ID_OUI_FROM_DATABASE=Tennessee Valley Authority
+
+OUI:0050C23B3*
+ ID_OUI_FROM_DATABASE=Media Lab., Inc.
+
+OUI:0050C23B4*
+ ID_OUI_FROM_DATABASE=Contrôle Analytique inc.
+
+OUI:0050C23B5*
+ ID_OUI_FROM_DATABASE=NEC TOKIN Corporation
+
+OUI:0050C23B6*
+ ID_OUI_FROM_DATABASE=Arecont Vision, LLC
+
+OUI:0050C23B7*
+ ID_OUI_FROM_DATABASE=Mindspeed Technologies
+
+OUI:0050C23B8*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C23B9*
+ ID_OUI_FROM_DATABASE=Gilbarco Autotank AB
+
+OUI:0050C23BA*
+ ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH
+
+OUI:0050C23BB*
+ ID_OUI_FROM_DATABASE=IMAGO Technologies GmbH
+
+OUI:0050C23BC*
+ ID_OUI_FROM_DATABASE=Tyzx, Inc.
+
+OUI:0050C23BD*
+ ID_OUI_FROM_DATABASE=Bigbang L.T.D.
+
+OUI:0050C23BE*
+ ID_OUI_FROM_DATABASE=Pauly Steuer- und Regelanlagen GmbH & Co. KG
+
+OUI:0050C23BF*
+ ID_OUI_FROM_DATABASE=Audio Processing Technology Ltd
+
+OUI:0050C23C0*
+ ID_OUI_FROM_DATABASE=EDA Industries Srl
+
+OUI:0050C23C1*
+ ID_OUI_FROM_DATABASE=MicroTek Electronics, Inc.
+
+OUI:0050C23C2*
+ ID_OUI_FROM_DATABASE=Casabyte Inc.
+
+OUI:0050C23C3*
+ ID_OUI_FROM_DATABASE=4g Technologies, L.P.
+
+OUI:0050C23C4*
+ ID_OUI_FROM_DATABASE=Sypris Electronics
+
+OUI:0050C23C5*
+ ID_OUI_FROM_DATABASE=Silicon Optix Canada Inc.
+
+OUI:0050C23C6*
+ ID_OUI_FROM_DATABASE=Net Optics
+
+OUI:0050C23C7*
+ ID_OUI_FROM_DATABASE=Salent Technologies Ltd
+
+OUI:0050C23C8*
+ ID_OUI_FROM_DATABASE=Wheels of Zeus Inc.
+
+OUI:0050C23C9*
+ ID_OUI_FROM_DATABASE=Dilax Intelcom AG
+
+OUI:0050C23CA*
+ ID_OUI_FROM_DATABASE=ABB Inc.
+
+OUI:0050C23CB*
+ ID_OUI_FROM_DATABASE=Analytica GmbH
+
+OUI:0050C23CC*
+ ID_OUI_FROM_DATABASE=LINKWELL TELESYSTEMS PRIVATE LIMITED
+
+OUI:0050C23CD*
+ ID_OUI_FROM_DATABASE=Micro-Measurements
+
+OUI:0050C23CE*
+ ID_OUI_FROM_DATABASE=Ward Leonard Electric Company
+
+OUI:0050C23CF*
+ ID_OUI_FROM_DATABASE=Technovare Systems, Inc.
+
+OUI:0050C23D0*
+ ID_OUI_FROM_DATABASE=Micro-Robotics Limited
+
+OUI:0050C23D1*
+ ID_OUI_FROM_DATABASE=Braintronics BV
+
+OUI:0050C23D2*
+ ID_OUI_FROM_DATABASE=Adilec Enginyeria SL
+
+OUI:0050C23D3*
+ ID_OUI_FROM_DATABASE=American LED-gible Inc.
+
+OUI:0050C23D4*
+ ID_OUI_FROM_DATABASE=Wisnu and Supak Co.Ltd.
+
+OUI:0050C23D5*
+ ID_OUI_FROM_DATABASE=Fluke Biomedical, Radiation Management Services
+
+OUI:0050C23D6*
+ ID_OUI_FROM_DATABASE=Comlab Inc.
+
+OUI:0050C23D7*
+ ID_OUI_FROM_DATABASE=TTC TELEKOMUNIKACE Ltd
+
+OUI:0050C23D8*
+ ID_OUI_FROM_DATABASE=Key Systems , Inc.
+
+OUI:0050C23D9*
+ ID_OUI_FROM_DATABASE=Bavaria Digital Technik GmbH
+
+OUI:0050C23DA*
+ ID_OUI_FROM_DATABASE=M5 Data Limited
+
+OUI:0050C23DB*
+ ID_OUI_FROM_DATABASE=Osmetech Inc.
+
+OUI:0050C23DC*
+ ID_OUI_FROM_DATABASE=3D perception
+
+OUI:0050C23DD*
+ ID_OUI_FROM_DATABASE=ELMIC GmbH
+
+OUI:0050C23DE*
+ ID_OUI_FROM_DATABASE=ABB Power Technologies
+
+OUI:0050C23DF*
+ ID_OUI_FROM_DATABASE=BiODE Inc.
+
+OUI:0050C23E0*
+ ID_OUI_FROM_DATABASE=Oy Stinghorn Ltd
+
+OUI:0050C23E1*
+ ID_OUI_FROM_DATABASE=NeuLion Incorporated
+
+OUI:0050C23E2*
+ ID_OUI_FROM_DATABASE=SysNova
+
+OUI:0050C23E3*
+ ID_OUI_FROM_DATABASE=CSIRO - Division of Exploration and Mining
+
+OUI:0050C23E4*
+ ID_OUI_FROM_DATABASE=CUE, a.s.
+
+OUI:0050C23E5*
+ ID_OUI_FROM_DATABASE=Vacon Plc
+
+OUI:0050C23E6*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:0050C23E7*
+ ID_OUI_FROM_DATABASE=Revolution Education Ltd
+
+OUI:0050C23E8*
+ ID_OUI_FROM_DATABASE=Conformative Systems, Inc.
+
+OUI:0050C23E9*
+ ID_OUI_FROM_DATABASE=MedAvant Healthcare
+
+OUI:0050C23EA*
+ ID_OUI_FROM_DATABASE=Alro Information Systems SA
+
+OUI:0050C23EB*
+ ID_OUI_FROM_DATABASE=ISS International
+
+OUI:0050C23EC*
+ ID_OUI_FROM_DATABASE=Teneros
+
+OUI:0050C23ED*
+ ID_OUI_FROM_DATABASE=The Board Room Inc.
+
+OUI:0050C23EE*
+ ID_OUI_FROM_DATABASE=Commoca, Inc
+
+OUI:0050C23EF*
+ ID_OUI_FROM_DATABASE=PAT Industries, DBA Pacific Advanced Technology
+
+OUI:0050C23F0*
+ ID_OUI_FROM_DATABASE=megatec electronic GmbH
+
+OUI:0050C23F1*
+ ID_OUI_FROM_DATABASE=Salland Electronics Holding BV
+
+OUI:0050C23F2*
+ ID_OUI_FROM_DATABASE=STL GmbH
+
+OUI:0050C23F3*
+ ID_OUI_FROM_DATABASE=Hytec Gerätebau GmbH
+
+OUI:0050C23F4*
+ ID_OUI_FROM_DATABASE=MC TECHNOLOGY GmbH
+
+OUI:0050C23F5*
+ ID_OUI_FROM_DATABASE=Phaedrus Limited
+
+OUI:0050C23F6*
+ ID_OUI_FROM_DATABASE=dAFTdATA Limited
+
+OUI:0050C23F7*
+ ID_OUI_FROM_DATABASE=Advantage R&D
+
+OUI:0050C23F8*
+ ID_OUI_FROM_DATABASE=Superna Ltd
+
+OUI:0050C23F9*
+ ID_OUI_FROM_DATABASE=Sintium Ltd
+
+OUI:0050C23FA*
+ ID_OUI_FROM_DATABASE=Tumsan
+
+OUI:0050C23FB*
+ ID_OUI_FROM_DATABASE=Pigeon Point Systems
+
+OUI:0050C23FC*
+ ID_OUI_FROM_DATABASE=Weinberger Deutschland GmbH
+
+OUI:0050C23FD*
+ ID_OUI_FROM_DATABASE=HARTMANN software GbR
+
+OUI:0050C23FE*
+ ID_OUI_FROM_DATABASE=HaiVision Systems Incorporated
+
+OUI:0050C23FF*
+ ID_OUI_FROM_DATABASE=Cast Iron Systems
+
+OUI:0050C2400*
+ ID_OUI_FROM_DATABASE=SmartMotor AS
+
+OUI:0050C2401*
+ ID_OUI_FROM_DATABASE=Promess Incorporated
+
+OUI:0050C2402*
+ ID_OUI_FROM_DATABASE=Numeron Sp. z o.o.
+
+OUI:0050C2403*
+ ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA
+
+OUI:0050C2404*
+ ID_OUI_FROM_DATABASE=NanShanBridge Co.Ltd
+
+OUI:0050C2405*
+ ID_OUI_FROM_DATABASE=Guralp Systems Limited
+
+OUI:0050C2406*
+ ID_OUI_FROM_DATABASE=CoreStreet, Ltd
+
+OUI:0050C2407*
+ ID_OUI_FROM_DATABASE=AIE Etudes
+
+OUI:0050C2408*
+ ID_OUI_FROM_DATABASE=TERN, Inc.
+
+OUI:0050C2409*
+ ID_OUI_FROM_DATABASE=KTEC LTD
+
+OUI:0050C240A*
+ ID_OUI_FROM_DATABASE=Contec Steuerungstechnik & Automation GmbH
+
+OUI:0050C240B*
+ ID_OUI_FROM_DATABASE=Center VOSPI JSC
+
+OUI:0050C240C*
+ ID_OUI_FROM_DATABASE=Applied Materials UK Ltd
+
+OUI:0050C240D*
+ ID_OUI_FROM_DATABASE=Afonics Fibreoptics Ltd
+
+OUI:0050C240E*
+ ID_OUI_FROM_DATABASE=ads-tec GmbH
+
+OUI:0050C240F*
+ ID_OUI_FROM_DATABASE=BIR,INC.
+
+OUI:0050C2410*
+ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
+
+OUI:0050C2411*
+ ID_OUI_FROM_DATABASE=Multimessage Systems Ltd.
+
+OUI:0050C2412*
+ ID_OUI_FROM_DATABASE=TSB Solutions Inc.
+
+OUI:0050C2413*
+ ID_OUI_FROM_DATABASE=Goodrich
+
+OUI:0050C2414*
+ ID_OUI_FROM_DATABASE=Talleres de Escoriaza SA
+
+OUI:0050C2415*
+ ID_OUI_FROM_DATABASE=SensoTech GmbH
+
+OUI:0050C2416*
+ ID_OUI_FROM_DATABASE=SELCO s.r.l.
+
+OUI:0050C2417*
+ ID_OUI_FROM_DATABASE=QT systems ab
+
+OUI:0050C2418*
+ ID_OUI_FROM_DATABASE=Planea Oy
+
+OUI:0050C2419*
+ ID_OUI_FROM_DATABASE=Mecsel Oy
+
+OUI:0050C241A*
+ ID_OUI_FROM_DATABASE=Bluewater Systems Ltd
+
+OUI:0050C241B*
+ ID_OUI_FROM_DATABASE=LogiM GmbH Software und Entwicklung
+
+OUI:0050C241C*
+ ID_OUI_FROM_DATABASE=Infrasafe, Inc.
+
+OUI:0050C241D*
+ ID_OUI_FROM_DATABASE=Altronic, Inc.
+
+OUI:0050C241E*
+ ID_OUI_FROM_DATABASE=Videotek Sistemas Eletronicos Ltda.
+
+OUI:0050C241F*
+ ID_OUI_FROM_DATABASE=Avionica, Inc
+
+OUI:0050C2420*
+ ID_OUI_FROM_DATABASE=Boundless Technologies
+
+OUI:0050C2421*
+ ID_OUI_FROM_DATABASE=EFSYS
+
+OUI:0050C2422*
+ ID_OUI_FROM_DATABASE=Gekeler Martina
+
+OUI:0050C2423*
+ ID_OUI_FROM_DATABASE=Power-One Inc.
+
+OUI:0050C2424*
+ ID_OUI_FROM_DATABASE=Metrolab Instruments SA
+
+OUI:0050C2425*
+ ID_OUI_FROM_DATABASE=Pinnacle Technology
+
+OUI:0050C2426*
+ ID_OUI_FROM_DATABASE=STOM System
+
+OUI:0050C2427*
+ ID_OUI_FROM_DATABASE=Scheidt & Bachmann GmbH
+
+OUI:0050C2428*
+ ID_OUI_FROM_DATABASE=Roxar A/S
+
+OUI:0050C2429*
+ ID_OUI_FROM_DATABASE=Matthews Australasia
+
+OUI:0050C242A*
+ ID_OUI_FROM_DATABASE=DSP DESIGN
+
+OUI:0050C242B*
+ ID_OUI_FROM_DATABASE=VLSIP TECHNOLOGIES, INC.
+
+OUI:0050C242C*
+ ID_OUI_FROM_DATABASE=Trapeze ITS U.S.A., LLC
+
+OUI:0050C242D*
+ ID_OUI_FROM_DATABASE=Argo-Tech
+
+OUI:0050C242E*
+ ID_OUI_FROM_DATABASE=Oelmann Elektronik GmbH
+
+OUI:0050C242F*
+ ID_OUI_FROM_DATABASE=Win4NET
+
+OUI:0050C2430*
+ ID_OUI_FROM_DATABASE=Arcom Digital
+
+OUI:0050C2431*
+ ID_OUI_FROM_DATABASE=Octatron, Inc.
+
+OUI:0050C2432*
+ ID_OUI_FROM_DATABASE=Topway Industries Ltd.
+
+OUI:0050C2433*
+ ID_OUI_FROM_DATABASE=Idetech Europe S.A.
+
+OUI:0050C2434*
+ ID_OUI_FROM_DATABASE=ImperativeNetworks
+
+OUI:0050C2435*
+ ID_OUI_FROM_DATABASE=ADATEL TELECOMUNICACIONES S.A.
+
+OUI:0050C2436*
+ ID_OUI_FROM_DATABASE=Satellite Services BV
+
+OUI:0050C2437*
+ ID_OUI_FROM_DATABASE=PowerWAN, Inc
+
+OUI:0050C2438*
+ ID_OUI_FROM_DATABASE=Telecom Protection Technologies Limited
+
+OUI:0050C2439*
+ ID_OUI_FROM_DATABASE=Peleton Photonic Systems
+
+OUI:0050C243A*
+ ID_OUI_FROM_DATABASE=ProDesign GmbH
+
+OUI:0050C243B*
+ ID_OUI_FROM_DATABASE=A3IP
+
+OUI:0050C243C*
+ ID_OUI_FROM_DATABASE=LaBarge
+
+OUI:0050C243D*
+ ID_OUI_FROM_DATABASE=Ann Arbor Sensor Systems LLC
+
+OUI:0050C243E*
+ ID_OUI_FROM_DATABASE=Coppercom
+
+OUI:0050C243F*
+ ID_OUI_FROM_DATABASE=ARVOO Imaging Products BV
+
+OUI:0050C2440*
+ ID_OUI_FROM_DATABASE=Advanced Modular Computers Ltd.
+
+OUI:0050C2441*
+ ID_OUI_FROM_DATABASE=Sammi Information Systems Co.,Ltd
+
+OUI:0050C2442*
+ ID_OUI_FROM_DATABASE=Pico Computing, Inc.
+
+OUI:0050C2443*
+ ID_OUI_FROM_DATABASE=Pickering Laboratories
+
+OUI:0050C2444*
+ ID_OUI_FROM_DATABASE=Offshore Systems Ltd
+
+OUI:0050C2445*
+ ID_OUI_FROM_DATABASE=MICRONIC s.r.o.
+
+OUI:0050C2446*
+ ID_OUI_FROM_DATABASE=Micro Technic A-S
+
+OUI:0050C2447*
+ ID_OUI_FROM_DATABASE=Grupo Epelsa S.L.
+
+OUI:0050C2448*
+ ID_OUI_FROM_DATABASE=Comtech Systems Inc.
+
+OUI:0050C2449*
+ ID_OUI_FROM_DATABASE=BLEILE DATENTECHNIK GmbH
+
+OUI:0050C244A*
+ ID_OUI_FROM_DATABASE=ELETTRONICA SANTERNO SPA
+
+OUI:0050C244B*
+ ID_OUI_FROM_DATABASE=Solace Systems, Inc.
+
+OUI:0050C244C*
+ ID_OUI_FROM_DATABASE=Computime Systems UK Ltd.
+
+OUI:0050C244D*
+ ID_OUI_FROM_DATABASE=Electro-Matic Products, Inc.
+
+OUI:0050C244E*
+ ID_OUI_FROM_DATABASE=QQ Technology,Inc
+
+OUI:0050C244F*
+ ID_OUI_FROM_DATABASE=kippdata GmbH
+
+OUI:0050C2450*
+ ID_OUI_FROM_DATABASE=Enconair Ecological Chambers Inc.
+
+OUI:0050C2451*
+ ID_OUI_FROM_DATABASE=HAMEG GmbH
+
+OUI:0050C2452*
+ ID_OUI_FROM_DATABASE=SCAME SISTEMI s.r.l.
+
+OUI:0050C2453*
+ ID_OUI_FROM_DATABASE=Erhardt + Leimer GmbH
+
+OUI:0050C2454*
+ ID_OUI_FROM_DATABASE=Brivo Systems, LLC
+
+OUI:0050C2455*
+ ID_OUI_FROM_DATABASE=AirCell, Inc.
+
+OUI:0050C2456*
+ ID_OUI_FROM_DATABASE=DRDC Valcartier
+
+OUI:0050C2457*
+ ID_OUI_FROM_DATABASE=Danbridge
+
+OUI:0050C2458*
+ ID_OUI_FROM_DATABASE=HRZ data GmbH
+
+OUI:0050C2459*
+ ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH
+
+OUI:0050C245A*
+ ID_OUI_FROM_DATABASE=Funkwerk plettac electronic GmbH
+
+OUI:0050C245B*
+ ID_OUI_FROM_DATABASE=Matra Electronique
+
+OUI:0050C245C*
+ ID_OUI_FROM_DATABASE=Deister Electronic GmbH
+
+OUI:0050C245D*
+ ID_OUI_FROM_DATABASE=Digital Engineering, Inc.
+
+OUI:0050C245E*
+ ID_OUI_FROM_DATABASE=Halliburton - Sperry Drilling Service
+
+OUI:0050C245F*
+ ID_OUI_FROM_DATABASE=T2C Marketing AB
+
+OUI:0050C2460*
+ ID_OUI_FROM_DATABASE=Vitelnet
+
+OUI:0050C2461*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:0050C2462*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2463*
+ ID_OUI_FROM_DATABASE=Codem Systems, Inc.
+
+OUI:0050C2464*
+ ID_OUI_FROM_DATABASE=XYTAC system technologies
+
+OUI:0050C2465*
+ ID_OUI_FROM_DATABASE=PDTS GmbH
+
+OUI:0050C2466*
+ ID_OUI_FROM_DATABASE=LoNAP Limited
+
+OUI:0050C2467*
+ ID_OUI_FROM_DATABASE=United Western Technologies
+
+OUI:0050C2468*
+ ID_OUI_FROM_DATABASE=Network I/O
+
+OUI:0050C2469*
+ ID_OUI_FROM_DATABASE=BiPOM Electronics, Inc.
+
+OUI:0050C246A*
+ ID_OUI_FROM_DATABASE=ISE GmbH
+
+OUI:0050C246B*
+ ID_OUI_FROM_DATABASE=EASYTECH GmbH
+
+OUI:0050C246C*
+ ID_OUI_FROM_DATABASE=CAMCO GmbH
+
+OUI:0050C246D*
+ ID_OUI_FROM_DATABASE=Paul Scherrer Institut (PSI)
+
+OUI:0050C246E*
+ ID_OUI_FROM_DATABASE=Avenir Technologies Inc.
+
+OUI:0050C246F*
+ ID_OUI_FROM_DATABASE=Neuroware
+
+OUI:0050C2470*
+ ID_OUI_FROM_DATABASE=Cybectec inc.
+
+OUI:0050C2471*
+ ID_OUI_FROM_DATABASE=Pixtree Technologies, inc.
+
+OUI:0050C2472*
+ ID_OUI_FROM_DATABASE=KOP Ltd
+
+OUI:0050C2473*
+ ID_OUI_FROM_DATABASE=Sensus Metering Systems Israel
+
+OUI:0050C2474*
+ ID_OUI_FROM_DATABASE=Venue 1, Inc.
+
+OUI:0050C2475*
+ ID_OUI_FROM_DATABASE=ISEPOS GmbH
+
+OUI:0050C2476*
+ ID_OUI_FROM_DATABASE=Ascon S.p.a.
+
+OUI:0050C2477*
+ ID_OUI_FROM_DATABASE=SEV Tidsystem AB
+
+OUI:0050C2478*
+ ID_OUI_FROM_DATABASE=Metafix Inc.
+
+OUI:0050C2479*
+ ID_OUI_FROM_DATABASE=Unlimited Bandwidth LLC
+
+OUI:0050C247A*
+ ID_OUI_FROM_DATABASE=Efficient Channel Coding
+
+OUI:0050C247B*
+ ID_OUI_FROM_DATABASE=Pitney Bowes, Inc
+
+OUI:0050C247C*
+ ID_OUI_FROM_DATABASE=AUCONET GmbH
+
+OUI:0050C247D*
+ ID_OUI_FROM_DATABASE=WIT Inc
+
+OUI:0050C247E*
+ ID_OUI_FROM_DATABASE=Energie Umwelt Systemtechnik GmbH
+
+OUI:0050C247F*
+ ID_OUI_FROM_DATABASE=BRIT Inc.
+
+OUI:0050C2480*
+ ID_OUI_FROM_DATABASE=SELKOM GmbH
+
+OUI:0050C2481*
+ ID_OUI_FROM_DATABASE=Computer Sciences Corp
+
+OUI:0050C2482*
+ ID_OUI_FROM_DATABASE=PRIAMUS SYSTEM TECHNOLOGIES AG
+
+OUI:0050C2483*
+ ID_OUI_FROM_DATABASE=SES
+
+OUI:0050C2484*
+ ID_OUI_FROM_DATABASE=Kooltech LLC
+
+OUI:0050C2485*
+ ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH
+
+OUI:0050C2486*
+ ID_OUI_FROM_DATABASE=Safegate International AB
+
+OUI:0050C2487*
+ ID_OUI_FROM_DATABASE=Eridon Corporation
+
+OUI:0050C2488*
+ ID_OUI_FROM_DATABASE=DA SISTEMI SPA
+
+OUI:0050C2489*
+ ID_OUI_FROM_DATABASE=EREE Electronique
+
+OUI:0050C248A*
+ ID_OUI_FROM_DATABASE=Mobile Matrix, Inc.
+
+OUI:0050C248B*
+ ID_OUI_FROM_DATABASE=ADS-TEC GmbH
+
+OUI:0050C248C*
+ ID_OUI_FROM_DATABASE=UNITON AG
+
+OUI:0050C248D*
+ ID_OUI_FROM_DATABASE=Metron Sp. z o.o.
+
+OUI:0050C248E*
+ ID_OUI_FROM_DATABASE=Teledyne Tekmar
+
+OUI:0050C248F*
+ ID_OUI_FROM_DATABASE=DENGYOSHA co.,LTD.
+
+OUI:0050C2490*
+ ID_OUI_FROM_DATABASE=Cloanto Corporation
+
+OUI:0050C2491*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C2492*
+ ID_OUI_FROM_DATABASE=TRAFSYS AS
+
+OUI:0050C2493*
+ ID_OUI_FROM_DATABASE=Artis GmbH
+
+OUI:0050C2494*
+ ID_OUI_FROM_DATABASE=Ultimate Technology, Inc.
+
+OUI:0050C2495*
+ ID_OUI_FROM_DATABASE=VAZA Elektronik AB
+
+OUI:0050C2496*
+ ID_OUI_FROM_DATABASE=Acutelogic Corporation
+
+OUI:0050C2497*
+ ID_OUI_FROM_DATABASE=Advanced Driver Information Technology GmbH
+
+OUI:0050C2498*
+ ID_OUI_FROM_DATABASE=Quartet Technology, Inc.
+
+OUI:0050C2499*
+ ID_OUI_FROM_DATABASE=Trellia Networks
+
+OUI:0050C249A*
+ ID_OUI_FROM_DATABASE=TelASIC Communications, Inc.
+
+OUI:0050C249B*
+ ID_OUI_FROM_DATABASE=vg controls, inc
+
+OUI:0050C249C*
+ ID_OUI_FROM_DATABASE=Envisacor Technologies Inc.
+
+OUI:0050C249D*
+ ID_OUI_FROM_DATABASE=Critical Link
+
+OUI:0050C249E*
+ ID_OUI_FROM_DATABASE=Armorlink CO .Ltd
+
+OUI:0050C249F*
+ ID_OUI_FROM_DATABASE=GCS, Inc
+
+OUI:0050C24A0*
+ ID_OUI_FROM_DATABASE=Advanced technologies & Engineering (pty) Ltd
+
+OUI:0050C24A1*
+ ID_OUI_FROM_DATABASE=Pigeon Point Systems
+
+OUI:0050C24A2*
+ ID_OUI_FROM_DATABASE=SPECS GmbH
+
+OUI:0050C24A3*
+ ID_OUI_FROM_DATABASE=Protium Technologies, Inc.
+
+OUI:0050C24A4*
+ ID_OUI_FROM_DATABASE=IEEE P1609 WG
+
+OUI:0050C24A5*
+ ID_OUI_FROM_DATABASE=Teledyne Monitor Labs
+
+OUI:0050C24A6*
+ ID_OUI_FROM_DATABASE=BUYANG ELECTRONICS INDUSTRIAL CO., LTD.
+
+OUI:0050C24A7*
+ ID_OUI_FROM_DATABASE=iseg Spezialelektronik GmbH
+
+OUI:0050C24A8*
+ ID_OUI_FROM_DATABASE=CYJAYA Korea
+
+OUI:0050C24A9*
+ ID_OUI_FROM_DATABASE=Faber Electronics BV
+
+OUI:0050C24AA*
+ ID_OUI_FROM_DATABASE=HEINEN ELEKTRONIK GmbH
+
+OUI:0050C24AB*
+ ID_OUI_FROM_DATABASE=JVF Communications Ltd
+
+OUI:0050C24AC*
+ ID_OUI_FROM_DATABASE=Doramu Co.,Ltd.
+
+OUI:0050C24AD*
+ ID_OUI_FROM_DATABASE=OpenPeak, Inc.
+
+OUI:0050C24AE*
+ ID_OUI_FROM_DATABASE=ads-tec GmbH
+
+OUI:0050C24AF*
+ ID_OUI_FROM_DATABASE=Orbis Oy
+
+OUI:0050C24B0*
+ ID_OUI_FROM_DATABASE=Esmart Distribution Pte Ltd
+
+OUI:0050C24B1*
+ ID_OUI_FROM_DATABASE=Nsfocus Information Technology Co.,Ltd
+
+OUI:0050C24B2*
+ ID_OUI_FROM_DATABASE=TESLA, a.s.
+
+OUI:0050C24B3*
+ ID_OUI_FROM_DATABASE=ANSA Corporation
+
+OUI:0050C24B4*
+ ID_OUI_FROM_DATABASE=Matrix Audio Designs
+
+OUI:0050C24B5*
+ ID_OUI_FROM_DATABASE=Valley Tecnologia
+
+OUI:0050C24B6*
+ ID_OUI_FROM_DATABASE=General Resources Co., LTD.
+
+OUI:0050C24B7*
+ ID_OUI_FROM_DATABASE=GFI Chrono Time
+
+OUI:0050C24B8*
+ ID_OUI_FROM_DATABASE=Shenzhen Hongdian Technologies.,Ltd
+
+OUI:0050C24B9*
+ ID_OUI_FROM_DATABASE=Rose Technologies
+
+OUI:0050C24BA*
+ ID_OUI_FROM_DATABASE=Mistletoe Technologies
+
+OUI:0050C24BB*
+ ID_OUI_FROM_DATABASE=Protonic Holland
+
+OUI:0050C24BC*
+ ID_OUI_FROM_DATABASE=Saia Burgess Controls AG
+
+OUI:0050C24BD*
+ ID_OUI_FROM_DATABASE=Argon ST
+
+OUI:0050C24BE*
+ ID_OUI_FROM_DATABASE=Digital Dynamics, Inc.
+
+OUI:0050C24BF*
+ ID_OUI_FROM_DATABASE=Westinghouse Rail Systems Ltd
+
+OUI:0050C24C0*
+ ID_OUI_FROM_DATABASE=Bio-logic Systems Corp
+
+OUI:0050C24C1*
+ ID_OUI_FROM_DATABASE=Movaz Networks, Inc.
+
+OUI:0050C24C2*
+ ID_OUI_FROM_DATABASE=Elbit Systems
+
+OUI:0050C24C3*
+ ID_OUI_FROM_DATABASE=Quantum3D, Inc.
+
+OUI:0050C24C4*
+ ID_OUI_FROM_DATABASE=Black Diamond Video, Inc.
+
+OUI:0050C24C5*
+ ID_OUI_FROM_DATABASE=eXray Broadband Inc.
+
+OUI:0050C24C6*
+ ID_OUI_FROM_DATABASE=Rubin Ltd.
+
+OUI:0050C24C7*
+ ID_OUI_FROM_DATABASE=Transbit Sp.z o.o.
+
+OUI:0050C24C8*
+ ID_OUI_FROM_DATABASE=Neets
+
+OUI:0050C24C9*
+ ID_OUI_FROM_DATABASE=Scirocco AB
+
+OUI:0050C24CA*
+ ID_OUI_FROM_DATABASE=Yarg Biometrics Limited
+
+OUI:0050C24CB*
+ ID_OUI_FROM_DATABASE=Verint Systems Ltd
+
+OUI:0050C24CC*
+ ID_OUI_FROM_DATABASE=ImpediMed Limited
+
+OUI:0050C24CD*
+ ID_OUI_FROM_DATABASE=Adasoft AG
+
+OUI:0050C24CE*
+ ID_OUI_FROM_DATABASE=Open Date Equipment Limited
+
+OUI:0050C24CF*
+ ID_OUI_FROM_DATABASE=Ziehl-Abegg AG
+
+OUI:0050C24D0*
+ ID_OUI_FROM_DATABASE=Radford Control Systems
+
+OUI:0050C24D1*
+ ID_OUI_FROM_DATABASE=SLICAN sp. z o.o.
+
+OUI:0050C24D2*
+ ID_OUI_FROM_DATABASE=Twoway CATV SERVICE INC.
+
+OUI:0050C24D3*
+ ID_OUI_FROM_DATABASE=SOFTIN sp. z o.o.
+
+OUI:0050C24D4*
+ ID_OUI_FROM_DATABASE=Herholdt Controls srl
+
+OUI:0050C24D5*
+ ID_OUI_FROM_DATABASE=SEBA Design Pty Ltd
+
+OUI:0050C24D6*
+ ID_OUI_FROM_DATABASE=Ingenieurbüro Schober
+
+OUI:0050C24D7*
+ ID_OUI_FROM_DATABASE=Delta Tau Data Systems, Inc.
+
+OUI:0050C24D8*
+ ID_OUI_FROM_DATABASE=Avantry Ltd.
+
+OUI:0050C24D9*
+ ID_OUI_FROM_DATABASE=GE Security Kampro
+
+OUI:0050C24DA*
+ ID_OUI_FROM_DATABASE=MEDIORNET GmbH
+
+OUI:0050C24DB*
+ ID_OUI_FROM_DATABASE=Alfing Montagetechnik GmbH
+
+OUI:0050C24DC*
+ ID_OUI_FROM_DATABASE=Ace Electronics Inc.
+
+OUI:0050C24DD*
+ ID_OUI_FROM_DATABASE=Truteq Wireless (PTY) Ltd.
+
+OUI:0050C24DE*
+ ID_OUI_FROM_DATABASE=General Dynamics C4 Systems
+
+OUI:0050C24DF*
+ ID_OUI_FROM_DATABASE=Thermo Electron
+
+OUI:0050C24E0*
+ ID_OUI_FROM_DATABASE=Telematrix
+
+OUI:0050C24E1*
+ ID_OUI_FROM_DATABASE=SS Telecoms CC
+
+OUI:0050C24E2*
+ ID_OUI_FROM_DATABASE=Applied Research Laboratories: UT
+
+OUI:0050C24E3*
+ ID_OUI_FROM_DATABASE=Romteck Pty Ltd
+
+OUI:0050C24E4*
+ ID_OUI_FROM_DATABASE=Embigence GmbH
+
+OUI:0050C24E5*
+ ID_OUI_FROM_DATABASE=Sedo Systems Ltd
+
+OUI:0050C24E6*
+ ID_OUI_FROM_DATABASE=Photonic Bridges  Inc.
+
+OUI:0050C24E7*
+ ID_OUI_FROM_DATABASE=Computerized Elevator Contol
+
+OUI:0050C24E8*
+ ID_OUI_FROM_DATABASE=SATEL sp. z o.o.
+
+OUI:0050C24E9*
+ ID_OUI_FROM_DATABASE=Seachange international
+
+OUI:0050C24EA*
+ ID_OUI_FROM_DATABASE=PMC
+
+OUI:0050C24EB*
+ ID_OUI_FROM_DATABASE=Mandozzi Elettronica SA
+
+OUI:0050C24EC*
+ ID_OUI_FROM_DATABASE=Thales Defence and Security Systems GmbH
+
+OUI:0050C24ED*
+ ID_OUI_FROM_DATABASE=Lab X Technologies, LLC
+
+OUI:0050C24EE*
+ ID_OUI_FROM_DATABASE=Beijing Corelogic Communication Co., Ltd.
+
+OUI:0050C24EF*
+ ID_OUI_FROM_DATABASE=Creative Retail Entertainment
+
+OUI:0050C24F0*
+ ID_OUI_FROM_DATABASE=MedAvant Healthcare
+
+OUI:0050C24F1*
+ ID_OUI_FROM_DATABASE=Packet Island Inc.
+
+OUI:0050C24F2*
+ ID_OUI_FROM_DATABASE=Tantronic AG
+
+OUI:0050C24F3*
+ ID_OUI_FROM_DATABASE=Autronica Fire & Security
+
+OUI:0050C24F4*
+ ID_OUI_FROM_DATABASE=O2RUN
+
+OUI:0050C24F5*
+ ID_OUI_FROM_DATABASE=Monroe Electronics, Inc.
+
+OUI:0050C24F6*
+ ID_OUI_FROM_DATABASE=REAL D
+
+OUI:0050C24F7*
+ ID_OUI_FROM_DATABASE=WaveIP Ltd.
+
+OUI:0050C24F8*
+ ID_OUI_FROM_DATABASE=Prodco International Inc.
+
+OUI:0050C24F9*
+ ID_OUI_FROM_DATABASE=RTDS Technologies Inc.
+
+OUI:0050C24FA*
+ ID_OUI_FROM_DATABASE=Cambridge Technology, Inc.
+
+OUI:0050C24FB*
+ ID_OUI_FROM_DATABASE=BES Technology Group
+
+OUI:0050C24FC*
+ ID_OUI_FROM_DATABASE=Hwayoung RF Solution Inc
+
+OUI:0050C24FD*
+ ID_OUI_FROM_DATABASE=Network Automation mxc AB
+
+OUI:0050C24FE*
+ ID_OUI_FROM_DATABASE=GEM ELETTRONICA Srl
+
+OUI:0050C24FF*
+ ID_OUI_FROM_DATABASE=Dakty GmbH
+
+OUI:0050C2500*
+ ID_OUI_FROM_DATABASE=Orenco Systems, Inc.
+
+OUI:0050C2501*
+ ID_OUI_FROM_DATABASE=IBEX
+
+OUI:0050C2502*
+ ID_OUI_FROM_DATABASE=Criterion Systems Limited
+
+OUI:0050C2503*
+ ID_OUI_FROM_DATABASE=RESPIRONICS INC.
+
+OUI:0050C2504*
+ ID_OUI_FROM_DATABASE=Aphex Systems Ltd.
+
+OUI:0050C2505*
+ ID_OUI_FROM_DATABASE=Computerwise, Inc.
+
+OUI:0050C2506*
+ ID_OUI_FROM_DATABASE=7+ Kft
+
+OUI:0050C2507*
+ ID_OUI_FROM_DATABASE=Micro Connect Pty Ltd
+
+OUI:0050C2508*
+ ID_OUI_FROM_DATABASE=PUTERCOM ENTERPRISE CO., LTD.
+
+OUI:0050C2509*
+ ID_OUI_FROM_DATABASE=Hillcrest Laboratories, Inc.
+
+OUI:0050C250A*
+ ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd
+
+OUI:0050C250B*
+ ID_OUI_FROM_DATABASE=Logic Beach Inc
+
+OUI:0050C250C*
+ ID_OUI_FROM_DATABASE=AIRWISE TECHNOLOGY CO., LTD.
+
+OUI:0050C250D*
+ ID_OUI_FROM_DATABASE=Clearsonics Pty. Ltd.
+
+OUI:0050C250E*
+ ID_OUI_FROM_DATABASE=Fibresavers Corporation
+
+OUI:0050C250F*
+ ID_OUI_FROM_DATABASE=Polystar Instruments AB
+
+OUI:0050C2510*
+ ID_OUI_FROM_DATABASE=Summit Developmen
+
+OUI:0050C2511*
+ ID_OUI_FROM_DATABASE=Tecna Srl
+
+OUI:0050C2512*
+ ID_OUI_FROM_DATABASE=Linear Acoustic, Inc
+
+OUI:0050C2513*
+ ID_OUI_FROM_DATABASE=Genie Network Resource Management Inc.
+
+OUI:0050C2514*
+ ID_OUI_FROM_DATABASE=Tadian Electronics Systems LTD
+
+OUI:0050C2515*
+ ID_OUI_FROM_DATABASE=Monaghan Engineering, Inc.
+
+OUI:0050C2516*
+ ID_OUI_FROM_DATABASE=SOWA ELECTRIC CO., LTD.
+
+OUI:0050C2517*
+ ID_OUI_FROM_DATABASE=Solid State Logic
+
+OUI:0050C2518*
+ ID_OUI_FROM_DATABASE=Christ Elektronik GmbH
+
+OUI:0050C2519*
+ ID_OUI_FROM_DATABASE=DBM, LLC
+
+OUI:0050C251A*
+ ID_OUI_FROM_DATABASE=SpeasTech, Inc.
+
+OUI:0050C251B*
+ ID_OUI_FROM_DATABASE=Beta Lasermike Ltd
+
+OUI:0050C251C*
+ ID_OUI_FROM_DATABASE=TOA Systems
+
+OUI:0050C251D*
+ ID_OUI_FROM_DATABASE=VELUX
+
+OUI:0050C251E*
+ ID_OUI_FROM_DATABASE=Alcon Technologies
+
+OUI:0050C251F*
+ ID_OUI_FROM_DATABASE=Traquair Data Systems, Inc.
+
+OUI:0050C2520*
+ ID_OUI_FROM_DATABASE=McCain Traffic Supply
+
+OUI:0050C2521*
+ ID_OUI_FROM_DATABASE=ARIS TECHNOLOGIES
+
+OUI:0050C2522*
+ ID_OUI_FROM_DATABASE=Mark IV IDS Corp.
+
+OUI:0050C2523*
+ ID_OUI_FROM_DATABASE=AMRDEC Prototype Integration Facility
+
+OUI:0050C2524*
+ ID_OUI_FROM_DATABASE=Motec Pty Ltd
+
+OUI:0050C2525*
+ ID_OUI_FROM_DATABASE=VASTech
+
+OUI:0050C2526*
+ ID_OUI_FROM_DATABASE=AC SYSTEMS, s.r.o.
+
+OUI:0050C2527*
+ ID_OUI_FROM_DATABASE=IRTrans
+
+OUI:0050C2528*
+ ID_OUI_FROM_DATABASE=tattile srl
+
+OUI:0050C2529*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C252A*
+ ID_OUI_FROM_DATABASE=OMNITRONICS PTY LTD
+
+OUI:0050C252B*
+ ID_OUI_FROM_DATABASE=Sicon s.r.l.
+
+OUI:0050C252C*
+ ID_OUI_FROM_DATABASE=VITEC MULTIMEDIA
+
+OUI:0050C252D*
+ ID_OUI_FROM_DATABASE=Smartcom-Bulgaria AD
+
+OUI:0050C252E*
+ ID_OUI_FROM_DATABASE=DSP DESIGN
+
+OUI:0050C252F*
+ ID_OUI_FROM_DATABASE=Gesellschaft für  Rationalisierung und Rechentechnik mbH
+
+OUI:0050C2530*
+ ID_OUI_FROM_DATABASE=Innovation, Institute, Inc
+
+OUI:0050C2531*
+ ID_OUI_FROM_DATABASE=Orion Technologies, Inc.
+
+OUI:0050C2532*
+ ID_OUI_FROM_DATABASE=NVE Corporation
+
+OUI:0050C2533*
+ ID_OUI_FROM_DATABASE=NanShanBridge Co.Ltd
+
+OUI:0050C2534*
+ ID_OUI_FROM_DATABASE=Hyundai J. Comm
+
+OUI:0050C2535*
+ ID_OUI_FROM_DATABASE=MMS Servis s.r.o.
+
+OUI:0050C2536*
+ ID_OUI_FROM_DATABASE=C2 DIAGNOSTICS
+
+OUI:0050C2537*
+ ID_OUI_FROM_DATABASE=DST CONTROL AB
+
+OUI:0050C2538*
+ ID_OUI_FROM_DATABASE=EtherTek Circuits
+
+OUI:0050C2539*
+ ID_OUI_FROM_DATABASE=Detection Technology Inc.
+
+OUI:0050C253A*
+ ID_OUI_FROM_DATABASE=Image Control Design Limited
+
+OUI:0050C253B*
+ ID_OUI_FROM_DATABASE=Teleks Co. Ltd.
+
+OUI:0050C253C*
+ ID_OUI_FROM_DATABASE=Marposs SPA
+
+OUI:0050C253D*
+ ID_OUI_FROM_DATABASE=Digital communications Technologies
+
+OUI:0050C253E*
+ ID_OUI_FROM_DATABASE=Honeywell GNO
+
+OUI:0050C253F*
+ ID_OUI_FROM_DATABASE=Ellips B.V.
+
+OUI:0050C2540*
+ ID_OUI_FROM_DATABASE=Mesure Controle Commande
+
+OUI:0050C2541*
+ ID_OUI_FROM_DATABASE=WAVES SYSTEM
+
+OUI:0050C2542*
+ ID_OUI_FROM_DATABASE=AVerMedia Technologies, Inc.
+
+OUI:0050C2543*
+ ID_OUI_FROM_DATABASE=DIGI SESN AG
+
+OUI:0050C2544*
+ ID_OUI_FROM_DATABASE=Zetera
+
+OUI:0050C2545*
+ ID_OUI_FROM_DATABASE=SecuInfo Co., Ltd.
+
+OUI:0050C2546*
+ ID_OUI_FROM_DATABASE=Universidad de Chile Facultad de Medicina
+
+OUI:0050C2547*
+ ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH
+
+OUI:0050C2548*
+ ID_OUI_FROM_DATABASE=I.T.W. Betaprint
+
+OUI:0050C2549*
+ ID_OUI_FROM_DATABASE=Netsynt S.p.A.
+
+OUI:0050C254A*
+ ID_OUI_FROM_DATABASE=IPTC Tech. Comm. AB
+
+OUI:0050C254B*
+ ID_OUI_FROM_DATABASE=Innopsys
+
+OUI:0050C254C*
+ ID_OUI_FROM_DATABASE=Sintecnos srl
+
+OUI:0050C254D*
+ ID_OUI_FROM_DATABASE=Silent System
+
+OUI:0050C254E*
+ ID_OUI_FROM_DATABASE=Convergent Design
+
+OUI:0050C254F*
+ ID_OUI_FROM_DATABASE=Valtronic SA
+
+OUI:0050C2550*
+ ID_OUI_FROM_DATABASE=LJU Automatisierungstechnik GmbH
+
+OUI:0050C2551*
+ ID_OUI_FROM_DATABASE=Innovative Neurotroncs
+
+OUI:0050C2552*
+ ID_OUI_FROM_DATABASE=Elfiq Inc.
+
+OUI:0050C2553*
+ ID_OUI_FROM_DATABASE=ATH system
+
+OUI:0050C2554*
+ ID_OUI_FROM_DATABASE=Weinzierl Engineering GmbH
+
+OUI:0050C2555*
+ ID_OUI_FROM_DATABASE=Control Alternative Solutions, Inc.
+
+OUI:0050C2556*
+ ID_OUI_FROM_DATABASE=Freiburger BlickZentrum
+
+OUI:0050C2557*
+ ID_OUI_FROM_DATABASE=TOYO RADIO SYSTEMS CO., LTD.
+
+OUI:0050C2558*
+ ID_OUI_FROM_DATABASE=Bedo Elektronik GmbH
+
+OUI:0050C2559*
+ ID_OUI_FROM_DATABASE=Fail Safe Solutions LLC
+
+OUI:0050C255A*
+ ID_OUI_FROM_DATABASE=Valde Systems, Inc.
+
+OUI:0050C255B*
+ ID_OUI_FROM_DATABASE=MATRIX TELECOM PVT. LTD.
+
+OUI:0050C255C*
+ ID_OUI_FROM_DATABASE=ads-tec GmbH
+
+OUI:0050C255D*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C255E*
+ ID_OUI_FROM_DATABASE=HANZAS ELEKTRONIKA, SIA
+
+OUI:0050C255F*
+ ID_OUI_FROM_DATABASE=Broad Reach Engineering
+
+OUI:0050C2560*
+ ID_OUI_FROM_DATABASE=Procon Electronics
+
+OUI:0050C2561*
+ ID_OUI_FROM_DATABASE=Seitec Elektronik GmbH
+
+OUI:0050C2562*
+ ID_OUI_FROM_DATABASE=C21 Technology Limited
+
+OUI:0050C2563*
+ ID_OUI_FROM_DATABASE=ORTRAT, S.L.
+
+OUI:0050C2564*
+ ID_OUI_FROM_DATABASE=Last Mile Gear
+
+OUI:0050C2565*
+ ID_OUI_FROM_DATABASE=WORKPOWER TECNOLOGIA ELETRONICA LTDA-EPP
+
+OUI:0050C2566*
+ ID_OUI_FROM_DATABASE=ubinetsys.co..ltd
+
+OUI:0050C2567*
+ ID_OUI_FROM_DATABASE=Tess GmbH
+
+OUI:0050C2568*
+ ID_OUI_FROM_DATABASE=GeoFocus, LLC
+
+OUI:0050C2569*
+ ID_OUI_FROM_DATABASE=Twinwin Technplogy Co.,Ltd.
+
+OUI:0050C256A*
+ ID_OUI_FROM_DATABASE=GRUPO EPELSA S. L.
+
+OUI:0050C256B*
+ ID_OUI_FROM_DATABASE=Dataton Utvecklings AB
+
+OUI:0050C256C*
+ ID_OUI_FROM_DATABASE=Targeted Technologies, LLC
+
+OUI:0050C256D*
+ ID_OUI_FROM_DATABASE=Computrol Fuel Systems Inc.
+
+OUI:0050C256E*
+ ID_OUI_FROM_DATABASE=LAB-EL ELEKTRONIKA LABORATORYJNA S.J.
+
+OUI:0050C256F*
+ ID_OUI_FROM_DATABASE=GMA, LLC
+
+OUI:0050C2570*
+ ID_OUI_FROM_DATABASE=Ellex Medical Pty Ltd
+
+OUI:0050C2571*
+ ID_OUI_FROM_DATABASE=Oberon Service srl
+
+OUI:0050C2572*
+ ID_OUI_FROM_DATABASE=Chell Instruments Ltd
+
+OUI:0050C2573*
+ ID_OUI_FROM_DATABASE=DATAMICRO Co., Ltd.
+
+OUI:0050C2574*
+ ID_OUI_FROM_DATABASE=Ingeniería Almudí S.L.
+
+OUI:0050C2575*
+ ID_OUI_FROM_DATABASE=SOLYSTIC
+
+OUI:0050C2576*
+ ID_OUI_FROM_DATABASE=Visi-tech Systems Ltd
+
+OUI:0050C2577*
+ ID_OUI_FROM_DATABASE=Advanced Software Technologies
+
+OUI:0050C2578*
+ ID_OUI_FROM_DATABASE=Delphi Display Systems, Inc.
+
+OUI:0050C2579*
+ ID_OUI_FROM_DATABASE=Gastager Systemtechnik GmbH
+
+OUI:0050C257A*
+ ID_OUI_FROM_DATABASE=Pigeon Point Systems
+
+OUI:0050C257B*
+ ID_OUI_FROM_DATABASE=ptswitch
+
+OUI:0050C257C*
+ ID_OUI_FROM_DATABASE=CYBERSYS
+
+OUI:0050C257D*
+ ID_OUI_FROM_DATABASE=Sierra Video Systems
+
+OUI:0050C257E*
+ ID_OUI_FROM_DATABASE=Digital Way
+
+OUI:0050C257F*
+ ID_OUI_FROM_DATABASE=Orderite, Inc.
+
+OUI:0050C2580*
+ ID_OUI_FROM_DATABASE=Buyang Electronics Industrial co.,Ltd.
+
+OUI:0050C2581*
+ ID_OUI_FROM_DATABASE=Devitech ApS
+
+OUI:0050C2582*
+ ID_OUI_FROM_DATABASE=AllSun A/S
+
+OUI:0050C2583*
+ ID_OUI_FROM_DATABASE=Jünger Audio-Studiotechnik GmbH
+
+OUI:0050C2584*
+ ID_OUI_FROM_DATABASE=Toyota Motorsport GmbH
+
+OUI:0050C2585*
+ ID_OUI_FROM_DATABASE=Wireless Cables Inc
+
+OUI:0050C2586*
+ ID_OUI_FROM_DATABASE=Genetix Ltd
+
+OUI:0050C2587*
+ ID_OUI_FROM_DATABASE=Dynalco
+
+OUI:0050C2588*
+ ID_OUI_FROM_DATABASE=Federal Electronics
+
+OUI:0050C2589*
+ ID_OUI_FROM_DATABASE=HORIBA MEDICAL
+
+OUI:0050C258A*
+ ID_OUI_FROM_DATABASE=Dixell S.p.a.
+
+OUI:0050C258B*
+ ID_OUI_FROM_DATABASE=Innovative Dynamics GmbH
+
+OUI:0050C258C*
+ ID_OUI_FROM_DATABASE=Lattice Semiconductor Corp. (LPA)
+
+OUI:0050C258D*
+ ID_OUI_FROM_DATABASE=ZAO
+
+OUI:0050C258E*
+ ID_OUI_FROM_DATABASE=Penny & Giles Aerospace Ltd
+
+OUI:0050C258F*
+ ID_OUI_FROM_DATABASE=XoIP Systems Pty Ltd
+
+OUI:0050C2590*
+ ID_OUI_FROM_DATABASE=EM Motorsport Ltd
+
+OUI:0050C2591*
+ ID_OUI_FROM_DATABASE=Grosvenor Technology Ltd
+
+OUI:0050C2592*
+ ID_OUI_FROM_DATABASE=PaloDEx Group Oy
+
+OUI:0050C2593*
+ ID_OUI_FROM_DATABASE=Broadlight
+
+OUI:0050C2594*
+ ID_OUI_FROM_DATABASE=Pixel Velocity, Inc.
+
+OUI:0050C2595*
+ ID_OUI_FROM_DATABASE=Callpod, Inc.
+
+OUI:0050C2596*
+ ID_OUI_FROM_DATABASE=SPANSION
+
+OUI:0050C2597*
+ ID_OUI_FROM_DATABASE=Nautel Limited
+
+OUI:0050C2598*
+ ID_OUI_FROM_DATABASE=Bundesamt für Strahlenschutz
+
+OUI:0050C2599*
+ ID_OUI_FROM_DATABASE=Fen Technology Limited
+
+OUI:0050C259A*
+ ID_OUI_FROM_DATABASE=MultiTrode Pty Ltd
+
+OUI:0050C259B*
+ ID_OUI_FROM_DATABASE=SAPEC
+
+OUI:0050C259C*
+ ID_OUI_FROM_DATABASE=DELSAT GROUP S.A.
+
+OUI:0050C259D*
+ ID_OUI_FROM_DATABASE=DSS Networks, Inc.
+
+OUI:0050C259E*
+ ID_OUI_FROM_DATABASE=Legerity
+
+OUI:0050C259F*
+ ID_OUI_FROM_DATABASE=ads-tec GmbH
+
+OUI:0050C25A0*
+ ID_OUI_FROM_DATABASE=Rudolph Technologies, Inc.
+
+OUI:0050C25A1*
+ ID_OUI_FROM_DATABASE=Vestfold Butikkdata AS
+
+OUI:0050C25A2*
+ ID_OUI_FROM_DATABASE=iNET Systems Inc.
+
+OUI:0050C25A3*
+ ID_OUI_FROM_DATABASE=LUMEL S.A.
+
+OUI:0050C25A4*
+ ID_OUI_FROM_DATABASE=Federal State Unitary Enterprise Experimental Factory for Sc
+
+OUI:0050C25A5*
+ ID_OUI_FROM_DATABASE=Equipos de Telecomunicación  Optoelectronicos, S.A.
+
+OUI:0050C25A6*
+ ID_OUI_FROM_DATABASE=Plastic Logic
+
+OUI:0050C25A7*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C25A8*
+ ID_OUI_FROM_DATABASE=ETAP NV
+
+OUI:0050C25A9*
+ ID_OUI_FROM_DATABASE=AYC Telecom Ltd
+
+OUI:0050C25AA*
+ ID_OUI_FROM_DATABASE=Transenna AB
+
+OUI:0050C25AB*
+ ID_OUI_FROM_DATABASE=Eaton Corporation  Electrical Group  Data Center Solutions - Pulizzi
+
+OUI:0050C25AC*
+ ID_OUI_FROM_DATABASE=Kinemetrics, Inc.
+
+OUI:0050C25AD*
+ ID_OUI_FROM_DATABASE=Emcom Systems
+
+OUI:0050C25AE*
+ ID_OUI_FROM_DATABASE=CPS EUROPE B.V.
+
+OUI:0050C25AF*
+ ID_OUI_FROM_DATABASE=DORLET S.A.
+
+OUI:0050C25B0*
+ ID_OUI_FROM_DATABASE=INCOTEC GmbH
+
+OUI:0050C25B1*
+ ID_OUI_FROM_DATABASE=Rosta Ltd
+
+OUI:0050C25B2*
+ ID_OUI_FROM_DATABASE=Syntronic AB
+
+OUI:0050C25B3*
+ ID_OUI_FROM_DATABASE=HITECOM System
+
+OUI:0050C25B4*
+ ID_OUI_FROM_DATABASE=Terrascience Systems Ltd.
+
+OUI:0050C25B5*
+ ID_OUI_FROM_DATABASE=RAFAEL
+
+OUI:0050C25B6*
+ ID_OUI_FROM_DATABASE=Kontron (Beijing) Technology Co.,Ltd.
+
+OUI:0050C25B7*
+ ID_OUI_FROM_DATABASE=AVerMedia Technologies, Inc.
+
+OUI:0050C25B8*
+ ID_OUI_FROM_DATABASE=WestfaliaSurge GmbH
+
+OUI:0050C25B9*
+ ID_OUI_FROM_DATABASE=Taiwan Video & Monitor
+
+OUI:0050C25BA*
+ ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG
+
+OUI:0050C25BB*
+ ID_OUI_FROM_DATABASE=UNIC TECHNOLOGIES INC
+
+OUI:0050C25BC*
+ ID_OUI_FROM_DATABASE=Guangzhou Hui Si Information Technologies Inc.
+
+OUI:0050C25BD*
+ ID_OUI_FROM_DATABASE=Nomus Comm-Systems
+
+OUI:0050C25BE*
+ ID_OUI_FROM_DATABASE=Card Access Services Pty Ltd
+
+OUI:0050C25BF*
+ ID_OUI_FROM_DATABASE=Techimp Systems S.r.l.
+
+OUI:0050C25C0*
+ ID_OUI_FROM_DATABASE=Pyott-Boone Electronics
+
+OUI:0050C25C1*
+ ID_OUI_FROM_DATABASE=R. L. Drake Company
+
+OUI:0050C25C2*
+ ID_OUI_FROM_DATABASE=Intuitive Surgical
+
+OUI:0050C25C3*
+ ID_OUI_FROM_DATABASE=KS System GmbH
+
+OUI:0050C25C4*
+ ID_OUI_FROM_DATABASE=ProMik GmbH
+
+OUI:0050C25C5*
+ ID_OUI_FROM_DATABASE=Radiant Imaging, Inc.
+
+OUI:0050C25C6*
+ ID_OUI_FROM_DATABASE=Technische Alternative GmbH
+
+OUI:0050C25C7*
+ ID_OUI_FROM_DATABASE=InSync Technology Ltd
+
+OUI:0050C25C8*
+ ID_OUI_FROM_DATABASE=Georgia Tech Research Institute
+
+OUI:0050C25C9*
+ ID_OUI_FROM_DATABASE=Shenzhen Quanlong Technique Co.Ltd
+
+OUI:0050C25CA*
+ ID_OUI_FROM_DATABASE=Buyang Electronics Industrial Co., Ltd.
+
+OUI:0050C25CB*
+ ID_OUI_FROM_DATABASE=Kobold Sistemi s.r.l.
+
+OUI:0050C25CC*
+ ID_OUI_FROM_DATABASE=ENSEO
+
+OUI:0050C25CD*
+ ID_OUI_FROM_DATABASE=RADA Electronics Industries Ltd.
+
+OUI:0050C25CE*
+ ID_OUI_FROM_DATABASE=Roke Manor Research Ltd
+
+OUI:0050C25CF*
+ ID_OUI_FROM_DATABASE=Innomed Medical Inc
+
+OUI:0050C25D0*
+ ID_OUI_FROM_DATABASE=Automata Spa
+
+OUI:0050C25D1*
+ ID_OUI_FROM_DATABASE=Meucci Solutions
+
+OUI:0050C25D2*
+ ID_OUI_FROM_DATABASE=DA-Design Oy
+
+OUI:0050C25D3*
+ ID_OUI_FROM_DATABASE=Wexiodisk AB
+
+OUI:0050C25D4*
+ ID_OUI_FROM_DATABASE=Buyang Electronics Industrial Co., Ltd.
+
+OUI:0050C25D5*
+ ID_OUI_FROM_DATABASE=Cannon Technologies
+
+OUI:0050C25D6*
+ ID_OUI_FROM_DATABASE=BioAccess Tecnologia em Biometria Ltda.
+
+OUI:0050C25D7*
+ ID_OUI_FROM_DATABASE=Synrad, Inc.
+
+OUI:0050C25D8*
+ ID_OUI_FROM_DATABASE=TECHNIFOR SAS
+
+OUI:0050C25D9*
+ ID_OUI_FROM_DATABASE=Crimson Microsystems, Inc.
+
+OUI:0050C25DA*
+ ID_OUI_FROM_DATABASE=TONNA ELECTRONIQUE
+
+OUI:0050C25DB*
+ ID_OUI_FROM_DATABASE=CEGELEC SUD EST
+
+OUI:0050C25DC*
+ ID_OUI_FROM_DATABASE=RM Michaelides Software & Elektronik GmbH
+
+OUI:0050C25DD*
+ ID_OUI_FROM_DATABASE=SomerData ltd
+
+OUI:0050C25DE*
+ ID_OUI_FROM_DATABASE=Magal Senstar Inc.
+
+OUI:0050C25DF*
+ ID_OUI_FROM_DATABASE=Gnutek Ltd.
+
+OUI:0050C25E0*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C25E1*
+ ID_OUI_FROM_DATABASE=Ittiam Systems (P) Ltd
+
+OUI:0050C25E2*
+ ID_OUI_FROM_DATABASE=PYRAMID Computer GmbH
+
+OUI:0050C25E3*
+ ID_OUI_FROM_DATABASE=Computechnic AG
+
+OUI:0050C25E4*
+ ID_OUI_FROM_DATABASE=Buyang Electronics Industrial Co., Ltd.
+
+OUI:0050C25E5*
+ ID_OUI_FROM_DATABASE=Stresstech OY
+
+OUI:0050C25E6*
+ ID_OUI_FROM_DATABASE=Musatel
+
+OUI:0050C25E7*
+ ID_OUI_FROM_DATABASE=EADS TEST & SERVICES
+
+OUI:0050C25E8*
+ ID_OUI_FROM_DATABASE=Info-Chip Communications Ltd.
+
+OUI:0050C25E9*
+ ID_OUI_FROM_DATABASE=Micro Technology Services Inc.
+
+OUI:0050C25EA*
+ ID_OUI_FROM_DATABASE=Micro Elektronische Producten
+
+OUI:0050C25EB*
+ ID_OUI_FROM_DATABASE=Garper Telecomunicaciones, S.L.
+
+OUI:0050C25EC*
+ ID_OUI_FROM_DATABASE=ASiS Technologies Pte Ltd
+
+OUI:0050C25ED*
+ ID_OUI_FROM_DATABASE=AQUAROTTER A FRANKE COMPANY
+
+OUI:0050C25EE*
+ ID_OUI_FROM_DATABASE=Condre Corporation
+
+OUI:0050C25EF*
+ ID_OUI_FROM_DATABASE=pikkerton GmbH
+
+OUI:0050C25F0*
+ ID_OUI_FROM_DATABASE=DIAS Infrared GmbH
+
+OUI:0050C25F1*
+ ID_OUI_FROM_DATABASE=Technomarine JSC
+
+OUI:0050C25F2*
+ ID_OUI_FROM_DATABASE=ESEM Grünau GmbH & Co. KG
+
+OUI:0050C25F3*
+ ID_OUI_FROM_DATABASE=POSNET Polska S.A.
+
+OUI:0050C25F4*
+ ID_OUI_FROM_DATABASE=TeamProjects BV
+
+OUI:0050C25F5*
+ ID_OUI_FROM_DATABASE=Genesis inc
+
+OUI:0050C25F6*
+ ID_OUI_FROM_DATABASE=CAMBRIDGE CONSULTANTS LTD
+
+OUI:0050C25F7*
+ ID_OUI_FROM_DATABASE=Metrologic Group
+
+OUI:0050C25F8*
+ ID_OUI_FROM_DATABASE=Grupo Epelsa s. l.
+
+OUI:0050C25F9*
+ ID_OUI_FROM_DATABASE=ROTHARY Solutions AG
+
+OUI:0050C25FA*
+ ID_OUI_FROM_DATABASE=LEA d.o.o.
+
+OUI:0050C25FB*
+ ID_OUI_FROM_DATABASE=All-Systems Electronics Pty Ltd
+
+OUI:0050C25FC*
+ ID_OUI_FROM_DATABASE=FilmLight Limited
+
+OUI:0050C25FD*
+ ID_OUI_FROM_DATABASE=MEG Electronic Inc.
+
+OUI:0050C25FE*
+ ID_OUI_FROM_DATABASE=Novacomm
+
+OUI:0050C25FF*
+ ID_OUI_FROM_DATABASE=Gazelle Monitoring Systems
+
+OUI:0050C2600*
+ ID_OUI_FROM_DATABASE=Protec Fire Detection plc
+
+OUI:0050C2601*
+ ID_OUI_FROM_DATABASE=MedAvant Healthcare
+
+OUI:0050C2602*
+ ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX
+
+OUI:0050C2603*
+ ID_OUI_FROM_DATABASE=Cerus Corp
+
+OUI:0050C2604*
+ ID_OUI_FROM_DATABASE=HCJB Global
+
+OUI:0050C2605*
+ ID_OUI_FROM_DATABASE=Swistec GmbH
+
+OUI:0050C2606*
+ ID_OUI_FROM_DATABASE=Shenzhen Huazhong Technology Inc
+
+OUI:0050C2607*
+ ID_OUI_FROM_DATABASE=Telecom FM
+
+OUI:0050C2608*
+ ID_OUI_FROM_DATABASE=Silex Industrial Automation Ltd.
+
+OUI:0050C2609*
+ ID_OUI_FROM_DATABASE=Toptech Systems, Inc.
+
+OUI:0050C260A*
+ ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda
+
+OUI:0050C260B*
+ ID_OUI_FROM_DATABASE=Shanghai QianJin Electronic Equipment Co. Ltd.
+
+OUI:0050C260C*
+ ID_OUI_FROM_DATABASE=IDENTIC AB
+
+OUI:0050C260D*
+ ID_OUI_FROM_DATABASE=Sicon s.r.l.
+
+OUI:0050C260E*
+ ID_OUI_FROM_DATABASE=Automation and Control Technology, Inc.
+
+OUI:0050C260F*
+ ID_OUI_FROM_DATABASE=Kommunikations- & Sicherheitssysteme Gesellschaft m.b.H
+
+OUI:0050C2610*
+ ID_OUI_FROM_DATABASE=FDT Manufacturing, LLC
+
+OUI:0050C2611*
+ ID_OUI_FROM_DATABASE=Brookhaven National Laboratory
+
+OUI:0050C2612*
+ ID_OUI_FROM_DATABASE=IHP-GmbH
+
+OUI:0050C2613*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:0050C2614*
+ ID_OUI_FROM_DATABASE=SICOM AS
+
+OUI:0050C2615*
+ ID_OUI_FROM_DATABASE=Axis Electronics
+
+OUI:0050C2616*
+ ID_OUI_FROM_DATABASE=Honeywell
+
+OUI:0050C2617*
+ ID_OUI_FROM_DATABASE=NARINET, INC.
+
+OUI:0050C2618*
+ ID_OUI_FROM_DATABASE=Intergrated Security Mfg. Ltd
+
+OUI:0050C2619*
+ ID_OUI_FROM_DATABASE=Linkbit, Inc.
+
+OUI:0050C261A*
+ ID_OUI_FROM_DATABASE=Communication Components Inc.
+
+OUI:0050C261B*
+ ID_OUI_FROM_DATABASE=NCI Technologies Inc.
+
+OUI:0050C261C*
+ ID_OUI_FROM_DATABASE=TestPro Systems, Inc.
+
+OUI:0050C261D*
+ ID_OUI_FROM_DATABASE=Sutus Inc
+
+OUI:0050C261E*
+ ID_OUI_FROM_DATABASE=LESTER ELECTRONICS LTD
+
+OUI:0050C261F*
+ ID_OUI_FROM_DATABASE=Imagine Communications
+
+OUI:0050C2620*
+ ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH
+
+OUI:0050C2621*
+ ID_OUI_FROM_DATABASE=Version-T
+
+OUI:0050C2622*
+ ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s.
+
+OUI:0050C2623*
+ ID_OUI_FROM_DATABASE=SAFELINE SL
+
+OUI:0050C2624*
+ ID_OUI_FROM_DATABASE=Comtest Networks
+
+OUI:0050C2625*
+ ID_OUI_FROM_DATABASE=EBNeuro SpA
+
+OUI:0050C2626*
+ ID_OUI_FROM_DATABASE=Winsys Informatica ltda
+
+OUI:0050C2627*
+ ID_OUI_FROM_DATABASE=JungleSystem Co., Ltd.
+
+OUI:0050C2628*
+ ID_OUI_FROM_DATABASE=DARE Development
+
+OUI:0050C2629*
+ ID_OUI_FROM_DATABASE=MacDonald Humfrey (Products) Ltd
+
+OUI:0050C262A*
+ ID_OUI_FROM_DATABASE=Prisma Engineering srl
+
+OUI:0050C262B*
+ ID_OUI_FROM_DATABASE=First Control Systems AB
+
+OUI:0050C262C*
+ ID_OUI_FROM_DATABASE=AirMatrix, Inc.
+
+OUI:0050C262D*
+ ID_OUI_FROM_DATABASE=Procon Electronics
+
+OUI:0050C262E*
+ ID_OUI_FROM_DATABASE=TDM Ingénierie
+
+OUI:0050C262F*
+ ID_OUI_FROM_DATABASE=QES
+
+OUI:0050C2630*
+ ID_OUI_FROM_DATABASE=Aurora Flight Sciences
+
+OUI:0050C2631*
+ ID_OUI_FROM_DATABASE=Fraunhofer IIS
+
+OUI:0050C2632*
+ ID_OUI_FROM_DATABASE=RoseTechnology A/S
+
+OUI:0050C2633*
+ ID_OUI_FROM_DATABASE=Rice University
+
+OUI:0050C2634*
+ ID_OUI_FROM_DATABASE=Sohon Inc
+
+OUI:0050C2635*
+ ID_OUI_FROM_DATABASE=Shockfish SA
+
+OUI:0050C2636*
+ ID_OUI_FROM_DATABASE=dSPACE GmbH
+
+OUI:0050C2637*
+ ID_OUI_FROM_DATABASE=Omnitrol Networks, Inc.
+
+OUI:0050C2638*
+ ID_OUI_FROM_DATABASE=HUNGAROCOM Telecommunication Ltd.
+
+OUI:0050C2639*
+ ID_OUI_FROM_DATABASE=Qstreams Networks Inc.
+
+OUI:0050C263A*
+ ID_OUI_FROM_DATABASE=3DSP Corporation
+
+OUI:0050C263B*
+ ID_OUI_FROM_DATABASE=Powis Corporation
+
+OUI:0050C263C*
+ ID_OUI_FROM_DATABASE=dPict Imaging, Inc.
+
+OUI:0050C263D*
+ ID_OUI_FROM_DATABASE=IDERs Inc
+
+OUI:0050C263E*
+ ID_OUI_FROM_DATABASE=T2 Communication Ltd
+
+OUI:0050C263F*
+ ID_OUI_FROM_DATABASE=Speech Technology Center, Ltd.
+
+OUI:0050C2640*
+ ID_OUI_FROM_DATABASE=IAC
+
+OUI:0050C2641*
+ ID_OUI_FROM_DATABASE=NEO Information Systems Co., Ltd.
+
+OUI:0050C2642*
+ ID_OUI_FROM_DATABASE=Stanton Technologies Sdn Bhd
+
+OUI:0050C2643*
+ ID_OUI_FROM_DATABASE=Enatel Limited
+
+OUI:0050C2644*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2645*
+ ID_OUI_FROM_DATABASE=The Software Group Limited
+
+OUI:0050C2646*
+ ID_OUI_FROM_DATABASE=TRUTOUCH TECHNOLOGIES INC
+
+OUI:0050C2647*
+ ID_OUI_FROM_DATABASE=R&D Technology Solutionz Limited
+
+OUI:0050C2648*
+ ID_OUI_FROM_DATABASE=Fidelity Comtech, Inc.
+
+OUI:0050C2649*
+ ID_OUI_FROM_DATABASE=Pan-STARRS
+
+OUI:0050C264A*
+ ID_OUI_FROM_DATABASE=CPqD
+
+OUI:0050C264B*
+ ID_OUI_FROM_DATABASE=MangoDSP
+
+OUI:0050C264C*
+ ID_OUI_FROM_DATABASE=CIS Corporation
+
+OUI:0050C264D*
+ ID_OUI_FROM_DATABASE=Tera Information System Labs
+
+OUI:0050C264E*
+ ID_OUI_FROM_DATABASE=Northern Power
+
+OUI:0050C264F*
+ ID_OUI_FROM_DATABASE=MA Lighting Technology GmbH
+
+OUI:0050C2650*
+ ID_OUI_FROM_DATABASE=Liquid Breaker, LLC
+
+OUI:0050C2651*
+ ID_OUI_FROM_DATABASE=STAER SPA
+
+OUI:0050C2652*
+ ID_OUI_FROM_DATABASE=Wideco Sweden AB
+
+OUI:0050C2653*
+ ID_OUI_FROM_DATABASE=Doble Engineering
+
+OUI:0050C2654*
+ ID_OUI_FROM_DATABASE=PaloDEx Group Oy
+
+OUI:0050C2655*
+ ID_OUI_FROM_DATABASE=Physik Instrumente (PI) GmbH&Co.KG
+
+OUI:0050C2656*
+ ID_OUI_FROM_DATABASE=LDA Audio Video Profesional
+
+OUI:0050C2657*
+ ID_OUI_FROM_DATABASE=MONYTEL S.A.
+
+OUI:0050C2658*
+ ID_OUI_FROM_DATABASE=OpenPKG GmbH
+
+OUI:0050C2659*
+ ID_OUI_FROM_DATABASE=Dorsett's, Incorporated
+
+OUI:0050C265A*
+ ID_OUI_FROM_DATABASE=Hisstema AB
+
+OUI:0050C265B*
+ ID_OUI_FROM_DATABASE=Silverbrook Research
+
+OUI:0050C265C*
+ ID_OUI_FROM_DATABASE=VTZ d.o.o.
+
+OUI:0050C265D*
+ ID_OUI_FROM_DATABASE=Redfone Communications LLC
+
+OUI:0050C265E*
+ ID_OUI_FROM_DATABASE=Cantion A/S
+
+OUI:0050C265F*
+ ID_OUI_FROM_DATABASE=Invocon, Inc.
+
+OUI:0050C2660*
+ ID_OUI_FROM_DATABASE=IZISOFT
+
+OUI:0050C2661*
+ ID_OUI_FROM_DATABASE=P.C.E.
+
+OUI:0050C2662*
+ ID_OUI_FROM_DATABASE=Asia Pacific Card & System Sdn Bhd
+
+OUI:0050C2663*
+ ID_OUI_FROM_DATABASE=COE Limited
+
+OUI:0050C2664*
+ ID_OUI_FROM_DATABASE=Westel Wireless Systems
+
+OUI:0050C2665*
+ ID_OUI_FROM_DATABASE=NetworkSound, Inc
+
+OUI:0050C2666*
+ ID_OUI_FROM_DATABASE=Xworks NZ Limited
+
+OUI:0050C2668*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2669*
+ ID_OUI_FROM_DATABASE=DSP DESIGN
+
+OUI:0050C266A*
+ ID_OUI_FROM_DATABASE=ABB Xiamen Transmission and Distribution Automation Equipmen
+
+OUI:0050C266B*
+ ID_OUI_FROM_DATABASE=flsystem
+
+OUI:0050C266C*
+ ID_OUI_FROM_DATABASE=DESY
+
+OUI:0050C266D*
+ ID_OUI_FROM_DATABASE=DIGITEK S.p.A.
+
+OUI:0050C266E*
+ ID_OUI_FROM_DATABASE=Linear Systems Ltd.
+
+OUI:0050C266F*
+ ID_OUI_FROM_DATABASE=Nilan A/S
+
+OUI:0050C2670*
+ ID_OUI_FROM_DATABASE=Naim Audio
+
+OUI:0050C2671*
+ ID_OUI_FROM_DATABASE=Skyline Products, Inc
+
+OUI:0050C2672*
+ ID_OUI_FROM_DATABASE=DDS Elettronica srl
+
+OUI:0050C2673*
+ ID_OUI_FROM_DATABASE=Ferrari electronic AG
+
+OUI:0050C2674*
+ ID_OUI_FROM_DATABASE=Protech Optronics Co., Ltd.
+
+OUI:0050C2675*
+ ID_OUI_FROM_DATABASE=Kenton Research Ltd
+
+OUI:0050C2676*
+ ID_OUI_FROM_DATABASE=EDS
+
+OUI:0050C2677*
+ ID_OUI_FROM_DATABASE=ProconX Pty Ltd
+
+OUI:0050C2678*
+ ID_OUI_FROM_DATABASE=IHM
+
+OUI:0050C2679*
+ ID_OUI_FROM_DATABASE=Industrial Vacuum Systems
+
+OUI:0050C267A*
+ ID_OUI_FROM_DATABASE=CC Systems AB
+
+OUI:0050C267B*
+ ID_OUI_FROM_DATABASE=Sparton Electronics
+
+OUI:0050C267C*
+ ID_OUI_FROM_DATABASE=AirCell, Inc.
+
+OUI:0050C267D*
+ ID_OUI_FROM_DATABASE=ESA  Messtechnik GmbH
+
+OUI:0050C267E*
+ ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG
+
+OUI:0050C267F*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2680*
+ ID_OUI_FROM_DATABASE=Honey Network Research Limited
+
+OUI:0050C2681*
+ ID_OUI_FROM_DATABASE=Owasys Advanced Wireless Devices
+
+OUI:0050C2682*
+ ID_OUI_FROM_DATABASE=Commet AB
+
+OUI:0050C2683*
+ ID_OUI_FROM_DATABASE=MEGGITT Safety System
+
+OUI:0050C2684*
+ ID_OUI_FROM_DATABASE=REASON Tecnologia S.A.
+
+OUI:0050C2685*
+ ID_OUI_FROM_DATABASE=Datamars SA
+
+OUI:0050C2686*
+ ID_OUI_FROM_DATABASE=ANNAX Anzeigesysteme GmbH
+
+OUI:0050C2687*
+ ID_OUI_FROM_DATABASE=Access Specialties, Inc
+
+OUI:0050C2688*
+ ID_OUI_FROM_DATABASE=Elk Products
+
+OUI:0050C2689*
+ ID_OUI_FROM_DATABASE=RF Code, Inc.
+
+OUI:0050C268A*
+ ID_OUI_FROM_DATABASE=Zhuhai Jiahe Electronics Co.,LTD
+
+OUI:0050C268B*
+ ID_OUI_FROM_DATABASE=SIMTEK INC.
+
+OUI:0050C268C*
+ ID_OUI_FROM_DATABASE=Isochron Inc
+
+OUI:0050C268D*
+ ID_OUI_FROM_DATABASE=CXR Larus Corporation
+
+OUI:0050C268E*
+ ID_OUI_FROM_DATABASE=SELCO
+
+OUI:0050C268F*
+ ID_OUI_FROM_DATABASE=BERTRONIC SRL
+
+OUI:0050C2690*
+ ID_OUI_FROM_DATABASE=GHL Systems Berhad
+
+OUI:0050C2691*
+ ID_OUI_FROM_DATABASE=Interopix, Inc.
+
+OUI:0050C2692*
+ ID_OUI_FROM_DATABASE=Mate Media Access Technologies
+
+OUI:0050C2693*
+ ID_OUI_FROM_DATABASE=Tech Comm, Inc.
+
+OUI:0050C2694*
+ ID_OUI_FROM_DATABASE=Initel srl
+
+OUI:0050C2695*
+ ID_OUI_FROM_DATABASE=Purelink Technology, inc.
+
+OUI:0050C2696*
+ ID_OUI_FROM_DATABASE=Casabyte Inc.
+
+OUI:0050C2697*
+ ID_OUI_FROM_DATABASE=Monarch Instrument
+
+OUI:0050C2698*
+ ID_OUI_FROM_DATABASE=Navtech Radar Ltd
+
+OUI:0050C2699*
+ ID_OUI_FROM_DATABASE=Bulletendpoints Enterprises Inc
+
+OUI:0050C269A*
+ ID_OUI_FROM_DATABASE=StoreTech Limited
+
+OUI:0050C269B*
+ ID_OUI_FROM_DATABASE=Tsien (UK) Ltd
+
+OUI:0050C269C*
+ ID_OUI_FROM_DATABASE=Bug Labs, Inc.
+
+OUI:0050C269D*
+ ID_OUI_FROM_DATABASE=Dvation.co.,Ltd
+
+OUI:0050C269E*
+ ID_OUI_FROM_DATABASE=Ideus AB
+
+OUI:0050C269F*
+ ID_OUI_FROM_DATABASE=Total RF, LLC
+
+OUI:0050C26A0*
+ ID_OUI_FROM_DATABASE=GFP Lab S.r.l.
+
+OUI:0050C26A1*
+ ID_OUI_FROM_DATABASE=PRICOL LIMITED
+
+OUI:0050C26A2*
+ ID_OUI_FROM_DATABASE=Cadi Scientific Pte Ltd
+
+OUI:0050C26A3*
+ ID_OUI_FROM_DATABASE=CreaTech Electronics Co.
+
+OUI:0050C26A4*
+ ID_OUI_FROM_DATABASE=TELETASK
+
+OUI:0050C26A5*
+ ID_OUI_FROM_DATABASE=FHF Funke+Huster Fernsig GmbH
+
+OUI:0050C26A6*
+ ID_OUI_FROM_DATABASE=Victory Concept Industries Ltd.
+
+OUI:0050C26A7*
+ ID_OUI_FROM_DATABASE=Hoer GmbH & Co. Industrie-Electronic KG
+
+OUI:0050C26A8*
+ ID_OUI_FROM_DATABASE=Intelligent Devices, Inc.
+
+OUI:0050C26A9*
+ ID_OUI_FROM_DATABASE=Armida Technologies Corporation
+
+OUI:0050C26AA*
+ ID_OUI_FROM_DATABASE=Ifox - Industria e Comercio Ltda
+
+OUI:0050C26AB*
+ ID_OUI_FROM_DATABASE=Softwareentwicklung
+
+OUI:0050C26AC*
+ ID_OUI_FROM_DATABASE=Thales UK
+
+OUI:0050C26AD*
+ ID_OUI_FROM_DATABASE=Heim- & Bürokommunikation
+
+OUI:0050C26AE*
+ ID_OUI_FROM_DATABASE=Qualisys AB
+
+OUI:0050C26AF*
+ ID_OUI_FROM_DATABASE=Nanoradio AB
+
+OUI:0050C26B0*
+ ID_OUI_FROM_DATABASE=Smart Key International Limited
+
+OUI:0050C26B1*
+ ID_OUI_FROM_DATABASE=Burk Technology
+
+OUI:0050C26B2*
+ ID_OUI_FROM_DATABASE=Edgeware AB
+
+OUI:0050C26B3*
+ ID_OUI_FROM_DATABASE=4RF Communications Ltd
+
+OUI:0050C26B4*
+ ID_OUI_FROM_DATABASE=SOMESCA
+
+OUI:0050C26B5*
+ ID_OUI_FROM_DATABASE=TRIUMF
+
+OUI:0050C26B6*
+ ID_OUI_FROM_DATABASE=CommoDaS GmbH
+
+OUI:0050C26B7*
+ ID_OUI_FROM_DATABASE=System LSI CO.Ltd.
+
+OUI:0050C26B8*
+ ID_OUI_FROM_DATABASE=Epec Oy
+
+OUI:0050C26B9*
+ ID_OUI_FROM_DATABASE=unipo GmbH
+
+OUI:0050C26BA*
+ ID_OUI_FROM_DATABASE=Fertron Controle e Automacao Industrial Ltda.
+
+OUI:0050C26BB*
+ ID_OUI_FROM_DATABASE=Ele.Mag S.r.l.
+
+OUI:0050C26BC*
+ ID_OUI_FROM_DATABASE=Paraytec Ltd
+
+OUI:0050C26BD*
+ ID_OUI_FROM_DATABASE=Mitron Oy
+
+OUI:0050C26BE*
+ ID_OUI_FROM_DATABASE=ESTEC Co.,Ltd.
+
+OUI:0050C26BF*
+ ID_OUI_FROM_DATABASE=Optoplan as
+
+OUI:0050C26C0*
+ ID_OUI_FROM_DATABASE=GLOSTER SANTE EUROPE
+
+OUI:0050C26C1*
+ ID_OUI_FROM_DATABASE=RADIUS Sweden AB
+
+OUI:0050C26C2*
+ ID_OUI_FROM_DATABASE=HoseoTelnet Inc...
+
+OUI:0050C26C3*
+ ID_OUI_FROM_DATABASE=iTRACS Corporation
+
+OUI:0050C26C4*
+ ID_OUI_FROM_DATABASE=REXXON GmbH
+
+OUI:0050C26C5*
+ ID_OUI_FROM_DATABASE=Oerlikon Contraves AG
+
+OUI:0050C26C6*
+ ID_OUI_FROM_DATABASE=MedAvant Healthcare Solutions
+
+OUI:0050C26C7*
+ ID_OUI_FROM_DATABASE=QuickCircuit Ltd.
+
+OUI:0050C26C8*
+ ID_OUI_FROM_DATABASE=B&S MEDIA Co., LTD.
+
+OUI:0050C26C9*
+ ID_OUI_FROM_DATABASE=NETAMI
+
+OUI:0050C26CA*
+ ID_OUI_FROM_DATABASE=Dynamic Hearing Pty Ltd
+
+OUI:0050C26CB*
+ ID_OUI_FROM_DATABASE=Stream Processors
+
+OUI:0050C26CC*
+ ID_OUI_FROM_DATABASE=Widmer Time Recorder Co., Inc.
+
+OUI:0050C26CD*
+ ID_OUI_FROM_DATABASE=RGM SPA
+
+OUI:0050C26CE*
+ ID_OUI_FROM_DATABASE=EMITALL Surveillance S.A,
+
+OUI:0050C26CF*
+ ID_OUI_FROM_DATABASE=Microway
+
+OUI:0050C26D0*
+ ID_OUI_FROM_DATABASE=EDS Systemtechnik
+
+OUI:0050C26D1*
+ ID_OUI_FROM_DATABASE=Schnick-Schnack-Systems GmbH
+
+OUI:0050C26D2*
+ ID_OUI_FROM_DATABASE=Lumistar Incorporated
+
+OUI:0050C26D3*
+ ID_OUI_FROM_DATABASE=DigiSensory technologies Pty Ltd
+
+OUI:0050C26D4*
+ ID_OUI_FROM_DATABASE=Etani Electronics Co.,Ltd.
+
+OUI:0050C26D5*
+ ID_OUI_FROM_DATABASE=Becker Electronics GmbH
+
+OUI:0050C26D6*
+ ID_OUI_FROM_DATABASE=ADL Electronics Ltd.
+
+OUI:0050C26D7*
+ ID_OUI_FROM_DATABASE=Mavenir System, Inc.
+
+OUI:0050C26D8*
+ ID_OUI_FROM_DATABASE=BL Healthcare, Inc.
+
+OUI:0050C26D9*
+ ID_OUI_FROM_DATABASE=Ajeco Oy
+
+OUI:0050C26DA*
+ ID_OUI_FROM_DATABASE=Techno Fittings S.r.l.
+
+OUI:0050C26DB*
+ ID_OUI_FROM_DATABASE=Gebhardt Ventilatoren GmbH
+
+OUI:0050C26DC*
+ ID_OUI_FROM_DATABASE=L-3 Communications Mobile-Vision, Inc.
+
+OUI:0050C26DD*
+ ID_OUI_FROM_DATABASE=Zmicro Systems Inc
+
+OUI:0050C26DE*
+ ID_OUI_FROM_DATABASE=Laser Tools & Technics Corp.
+
+OUI:0050C26DF*
+ ID_OUI_FROM_DATABASE=QR Sciences Ltd
+
+OUI:0050C26E0*
+ ID_OUI_FROM_DATABASE=FIRSTTRUST Co.,Ltd.
+
+OUI:0050C26E1*
+ ID_OUI_FROM_DATABASE=NewOnSys Ltd.
+
+OUI:0050C26E2*
+ ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH
+
+OUI:0050C26E3*
+ ID_OUI_FROM_DATABASE=Miros AS
+
+OUI:0050C26E4*
+ ID_OUI_FROM_DATABASE=MangoDSP
+
+OUI:0050C26E5*
+ ID_OUI_FROM_DATABASE=Boeckeler Instruments, Inc.
+
+OUI:0050C26E6*
+ ID_OUI_FROM_DATABASE=Lanetco
+
+OUI:0050C26E7*
+ ID_OUI_FROM_DATABASE=Axis Network Technology
+
+OUI:0050C26E8*
+ ID_OUI_FROM_DATABASE=Anymax
+
+OUI:0050C26E9*
+ ID_OUI_FROM_DATABASE=Bando electronic communication Co.Lltd
+
+OUI:0050C26EA*
+ ID_OUI_FROM_DATABASE=FIRSTEC SA
+
+OUI:0050C26EB*
+ ID_OUI_FROM_DATABASE=Harrison Audio, LLC
+
+OUI:0050C26EC*
+ ID_OUI_FROM_DATABASE=Netistix Technologies Corporation
+
+OUI:0050C26ED*
+ ID_OUI_FROM_DATABASE=Sechan Electronics, Inc.
+
+OUI:0050C26EE*
+ ID_OUI_FROM_DATABASE=Interactive Electronic Systems
+
+OUI:0050C26EF*
+ ID_OUI_FROM_DATABASE=Pneumopartners LaenneXT SA
+
+OUI:0050C26F0*
+ ID_OUI_FROM_DATABASE=Stanley Security Solutions, Inc.
+
+OUI:0050C26F1*
+ ID_OUI_FROM_DATABASE=ITS Telecom
+
+OUI:0050C26F2*
+ ID_OUI_FROM_DATABASE=Laser Electronics Ltd
+
+OUI:0050C26F3*
+ ID_OUI_FROM_DATABASE=E3Switch LLC
+
+OUI:0050C26F4*
+ ID_OUI_FROM_DATABASE=Cryogenic Control Systems, Inc.
+
+OUI:0050C26F5*
+ ID_OUI_FROM_DATABASE=Kitron Microelectronics AB
+
+OUI:0050C26F6*
+ ID_OUI_FROM_DATABASE=AV SatCom AS
+
+OUI:0050C26F7*
+ ID_OUI_FROM_DATABASE=infoplan Gesellschaftfür  Informationssysteme mbH
+
+OUI:0050C26F8*
+ ID_OUI_FROM_DATABASE=RV Technology Limited
+
+OUI:0050C26F9*
+ ID_OUI_FROM_DATABASE=Revox GmbH
+
+OUI:0050C26FA*
+ ID_OUI_FROM_DATABASE=DCN
+
+OUI:0050C26FB*
+ ID_OUI_FROM_DATABASE=WaveIP
+
+OUI:0050C26FC*
+ ID_OUI_FROM_DATABASE=Acte Sp. z o.o.
+
+OUI:0050C26FD*
+ ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG
+
+OUI:0050C26FE*
+ ID_OUI_FROM_DATABASE=Blue Origin
+
+OUI:0050C26FF*
+ ID_OUI_FROM_DATABASE=St. Michael Strategies Inc.
+
+OUI:0050C2700*
+ ID_OUI_FROM_DATABASE=GEM-MED SL
+
+OUI:0050C2701*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2702*
+ ID_OUI_FROM_DATABASE=SPM Instrument AB
+
+OUI:0050C2703*
+ ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG
+
+OUI:0050C2704*
+ ID_OUI_FROM_DATABASE=The Dini Group, La Jolla inc.
+
+OUI:0050C2705*
+ ID_OUI_FROM_DATABASE=Hauch & Bach ApS
+
+OUI:0050C2706*
+ ID_OUI_FROM_DATABASE=DioDigiWorks. CO., LTD.
+
+OUI:0050C2707*
+ ID_OUI_FROM_DATABASE=DTech Labs Inc
+
+OUI:0050C2708*
+ ID_OUI_FROM_DATABASE=Smartek d.o.o.
+
+OUI:0050C2709*
+ ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A
+
+OUI:0050C270A*
+ ID_OUI_FROM_DATABASE=Efficient Channel Coding
+
+OUI:0050C270B*
+ ID_OUI_FROM_DATABASE=B.E.A.R. Solutions (Australasia) Pty Ltd
+
+OUI:0050C270C*
+ ID_OUI_FROM_DATABASE=Exertus
+
+OUI:0050C270D*
+ ID_OUI_FROM_DATABASE=ela-soft GmbH & Co. KG
+
+OUI:0050C270E*
+ ID_OUI_FROM_DATABASE=AUDICO SYSTEMS OY
+
+OUI:0050C270F*
+ ID_OUI_FROM_DATABASE=Zumbach Electronic AG
+
+OUI:0050C2710*
+ ID_OUI_FROM_DATABASE=Wharton Electronics Ltd
+
+OUI:0050C2711*
+ ID_OUI_FROM_DATABASE=LINKIT S.R.L.
+
+OUI:0050C2712*
+ ID_OUI_FROM_DATABASE=Pasan SA
+
+OUI:0050C2713*
+ ID_OUI_FROM_DATABASE=3DX-Ray Limited
+
+OUI:0050C2714*
+ ID_OUI_FROM_DATABASE=T.E.AM., S. A.
+
+OUI:0050C2715*
+ ID_OUI_FROM_DATABASE=RIEXINGER Elektronik
+
+OUI:0050C2716*
+ ID_OUI_FROM_DATABASE=MITROL S.R.L.
+
+OUI:0050C2717*
+ ID_OUI_FROM_DATABASE=MB Connect Line GmbH
+
+OUI:0050C2718*
+ ID_OUI_FROM_DATABASE=illunis LLC
+
+OUI:0050C2719*
+ ID_OUI_FROM_DATABASE=ennovatis GmbH
+
+OUI:0050C271A*
+ ID_OUI_FROM_DATABASE=Logus Broadband Wireless Solutions Inc.
+
+OUI:0050C271B*
+ ID_OUI_FROM_DATABASE=ADVA Optical Networking
+
+OUI:0050C271C*
+ ID_OUI_FROM_DATABASE=Elmec Inc.
+
+OUI:0050C271D*
+ ID_OUI_FROM_DATABASE=MG s.r.l.
+
+OUI:0050C271E*
+ ID_OUI_FROM_DATABASE=ASKI Industrie Elektronik Ges.m.b.H.
+
+OUI:0050C271F*
+ ID_OUI_FROM_DATABASE=ASC telecom AG
+
+OUI:0050C2720*
+ ID_OUI_FROM_DATABASE=Colorado Engineering Inc.
+
+OUI:0050C2721*
+ ID_OUI_FROM_DATABASE=Spectrum Communications FZE
+
+OUI:0050C2722*
+ ID_OUI_FROM_DATABASE=Centric TSolve BV
+
+OUI:0050C2723*
+ ID_OUI_FROM_DATABASE=Power Electronics
+
+OUI:0050C2724*
+ ID_OUI_FROM_DATABASE=HSC-Regelungstechnik GmbH
+
+OUI:0050C2725*
+ ID_OUI_FROM_DATABASE=DSP DESIGN
+
+OUI:0050C2726*
+ ID_OUI_FROM_DATABASE=eta systemi CKB
+
+OUI:0050C2727*
+ ID_OUI_FROM_DATABASE=Pelweckyj Videotechnik GmbH
+
+OUI:0050C2728*
+ ID_OUI_FROM_DATABASE=InterDigital Canada Ltd
+
+OUI:0050C2729*
+ ID_OUI_FROM_DATABASE=SP Controls, Inc
+
+OUI:0050C272A*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C272B*
+ ID_OUI_FROM_DATABASE=Sequestered Solutions
+
+OUI:0050C272C*
+ ID_OUI_FROM_DATABASE=Richard Griessbach Feinmechanik GmbH
+
+OUI:0050C272D*
+ ID_OUI_FROM_DATABASE=Physical Acoustics Corporation
+
+OUI:0050C272E*
+ ID_OUI_FROM_DATABASE=SNCF EIM PAYS DE LOIRE
+
+OUI:0050C272F*
+ ID_OUI_FROM_DATABASE=Priority Electronics Ltd
+
+OUI:0050C2730*
+ ID_OUI_FROM_DATABASE=haber & koenig electronics gmbh
+
+OUI:0050C2731*
+ ID_OUI_FROM_DATABASE=Spirent Communications
+
+OUI:0050C2732*
+ ID_OUI_FROM_DATABASE=Schlumberger K.K.
+
+OUI:0050C2733*
+ ID_OUI_FROM_DATABASE=Cimetrics Research Pty Ltd
+
+OUI:0050C2734*
+ ID_OUI_FROM_DATABASE=CardioMEMS Inc.
+
+OUI:0050C2735*
+ ID_OUI_FROM_DATABASE=Duma Video, Inc.
+
+OUI:0050C2736*
+ ID_OUI_FROM_DATABASE=Nika Ltd
+
+OUI:0050C2737*
+ ID_OUI_FROM_DATABASE=Teradici Corporation
+
+OUI:0050C2738*
+ ID_OUI_FROM_DATABASE=Miracom Technology Co., Ltd.
+
+OUI:0050C2739*
+ ID_OUI_FROM_DATABASE=Tattile srl
+
+OUI:0050C273A*
+ ID_OUI_FROM_DATABASE=Naturela Ltd.
+
+OUI:0050C273B*
+ ID_OUI_FROM_DATABASE=On Air Networks
+
+OUI:0050C273C*
+ ID_OUI_FROM_DATABASE=Simicon
+
+OUI:0050C273D*
+ ID_OUI_FROM_DATABASE=cryptiris
+
+OUI:0050C273E*
+ ID_OUI_FROM_DATABASE=Quantec Networks GmbH
+
+OUI:0050C273F*
+ ID_OUI_FROM_DATABASE=MEDAV GmbH
+
+OUI:0050C2740*
+ ID_OUI_FROM_DATABASE=McQuay China
+
+OUI:0050C2741*
+ ID_OUI_FROM_DATABASE=Dain
+
+OUI:0050C2742*
+ ID_OUI_FROM_DATABASE=Fantuzzi Reggiane
+
+OUI:0050C2743*
+ ID_OUI_FROM_DATABASE=Elektro-Top 3000 Ltd.
+
+OUI:0050C2744*
+ ID_OUI_FROM_DATABASE=Avonaco Systems, Inc.
+
+OUI:0050C2745*
+ ID_OUI_FROM_DATABASE=ACISA
+
+OUI:0050C2746*
+ ID_OUI_FROM_DATABASE=Realtronix Company
+
+OUI:0050C2747*
+ ID_OUI_FROM_DATABASE=CDSA Dam Neck
+
+OUI:0050C2748*
+ ID_OUI_FROM_DATABASE=Letechnic Ltd
+
+OUI:0050C2749*
+ ID_OUI_FROM_DATABASE=Affolter Technologies SA
+
+OUI:0050C274A*
+ ID_OUI_FROM_DATABASE=MONITOR ELECTRONICS LTD
+
+OUI:0050C274B*
+ ID_OUI_FROM_DATABASE=STAR-Dundee Ltd
+
+OUI:0050C274C*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C274D*
+ ID_OUI_FROM_DATABASE=Beceem Communications, Inc.
+
+OUI:0050C274E*
+ ID_OUI_FROM_DATABASE=TRONICO
+
+OUI:0050C274F*
+ ID_OUI_FROM_DATABASE=German Technologies
+
+OUI:0050C2750*
+ ID_OUI_FROM_DATABASE=Brightlights Intellectual Property Ltd
+
+OUI:0050C2751*
+ ID_OUI_FROM_DATABASE=e&s Engineering & Software GmbH
+
+OUI:0050C2752*
+ ID_OUI_FROM_DATABASE=LOBER, S.A.
+
+OUI:0050C2753*
+ ID_OUI_FROM_DATABASE=ABB
+
+OUI:0050C2754*
+ ID_OUI_FROM_DATABASE=Abeo Corporation
+
+OUI:0050C2755*
+ ID_OUI_FROM_DATABASE=Teletek Electronics
+
+OUI:0050C2756*
+ ID_OUI_FROM_DATABASE=Chesapeake Sciences Corp
+
+OUI:0050C2757*
+ ID_OUI_FROM_DATABASE=E S P Technologies Ltd
+
+OUI:0050C2758*
+ ID_OUI_FROM_DATABASE=AixSolve GmbH
+
+OUI:0050C2759*
+ ID_OUI_FROM_DATABASE=Sequentric Energy Systems, LLC
+
+OUI:0050C275A*
+ ID_OUI_FROM_DATABASE=Gaisler Research AB
+
+OUI:0050C275B*
+ ID_OUI_FROM_DATABASE=DMT System S.p.A.
+
+OUI:0050C275C*
+ ID_OUI_FROM_DATABASE=STÖRK-TRONIC Störk GmbH&Co. KG
+
+OUI:0050C275D*
+ ID_OUI_FROM_DATABASE=Fluid Analytics, Inc.
+
+OUI:0050C275E*
+ ID_OUI_FROM_DATABASE=Sky-Skan, Incorporated
+
+OUI:0050C275F*
+ ID_OUI_FROM_DATABASE=B. Rexroth the identity company GmbH
+
+OUI:0050C2760*
+ ID_OUI_FROM_DATABASE=AR'S CO., LTD.
+
+OUI:0050C2761*
+ ID_OUI_FROM_DATABASE=Elbit Systems of America - Fort Worth Operations
+
+OUI:0050C2762*
+ ID_OUI_FROM_DATABASE=Assembly Contracts Limited
+
+OUI:0050C2763*
+ ID_OUI_FROM_DATABASE=XtendWave
+
+OUI:0050C2764*
+ ID_OUI_FROM_DATABASE=Argus-Spectrum
+
+OUI:0050C2765*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2766*
+ ID_OUI_FROM_DATABASE=EMTEC Elektronische Messtechnik GmbH
+
+OUI:0050C2767*
+ ID_OUI_FROM_DATABASE=EID
+
+OUI:0050C2768*
+ ID_OUI_FROM_DATABASE=Control Service do Brasil Ltda
+
+OUI:0050C2769*
+ ID_OUI_FROM_DATABASE=BES GmbH
+
+OUI:0050C276A*
+ ID_OUI_FROM_DATABASE=Digidrive Audio Limited
+
+OUI:0050C276B*
+ ID_OUI_FROM_DATABASE=Putercom Enterprise Co., LTD.
+
+OUI:0050C276C*
+ ID_OUI_FROM_DATABASE=EFG CZ spol. s r.o.
+
+OUI:0050C276D*
+ ID_OUI_FROM_DATABASE=Mobilisme
+
+OUI:0050C276E*
+ ID_OUI_FROM_DATABASE=Crinia Corporation
+
+OUI:0050C276F*
+ ID_OUI_FROM_DATABASE=Control and Robotics Solutions
+
+OUI:0050C2770*
+ ID_OUI_FROM_DATABASE=Cadex Electronics Inc.
+
+OUI:0050C2771*
+ ID_OUI_FROM_DATABASE=ZigBee Alliance
+
+OUI:0050C2772*
+ ID_OUI_FROM_DATABASE=IES Elektronikentwicklung
+
+OUI:0050C2773*
+ ID_OUI_FROM_DATABASE=Pointe Conception Medical Inc.
+
+OUI:0050C2774*
+ ID_OUI_FROM_DATABASE=GeoSIG Ltd.
+
+OUI:0050C2775*
+ ID_OUI_FROM_DATABASE=Laserdyne Technologies
+
+OUI:0050C2776*
+ ID_OUI_FROM_DATABASE=Integrated Security Corporation
+
+OUI:0050C2777*
+ ID_OUI_FROM_DATABASE=Euro Display Srl
+
+OUI:0050C2778*
+ ID_OUI_FROM_DATABASE=SunGard Vivista
+
+OUI:0050C2779*
+ ID_OUI_FROM_DATABASE=Coral Telecom Ltd
+
+OUI:0050C277A*
+ ID_OUI_FROM_DATABASE=Smith Meter, Inc
+
+OUI:0050C277B*
+ ID_OUI_FROM_DATABASE=Itibia Technologies, Inc.
+
+OUI:0050C277C*
+ ID_OUI_FROM_DATABASE=ATEC SRL
+
+OUI:0050C277D*
+ ID_OUI_FROM_DATABASE=Lincoln Industrial
+
+OUI:0050C277E*
+ ID_OUI_FROM_DATABASE=Cominfo, a.s.
+
+OUI:0050C277F*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C2780*
+ ID_OUI_FROM_DATABASE=IQ Solutions GmbH & Co. KG
+
+OUI:0050C2781*
+ ID_OUI_FROM_DATABASE=Starling Advanced Communications
+
+OUI:0050C2782*
+ ID_OUI_FROM_DATABASE=Phytec Mestechnik GmbH
+
+OUI:0050C2783*
+ ID_OUI_FROM_DATABASE=NORMA systems GmbH
+
+OUI:0050C2784*
+ ID_OUI_FROM_DATABASE=Lewis Controls Inc.
+
+OUI:0050C2785*
+ ID_OUI_FROM_DATABASE=Icon Time Systems
+
+OUI:0050C2786*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2787*
+ ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd
+
+OUI:0050C2788*
+ ID_OUI_FROM_DATABASE=HOSA TECHNOLOGY, INC.
+
+OUI:0050C2789*
+ ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited
+
+OUI:0050C278A*
+ ID_OUI_FROM_DATABASE=LEVEL TELECOM
+
+OUI:0050C278B*
+ ID_OUI_FROM_DATABASE=OMICRON electronics GmbH
+
+OUI:0050C278C*
+ ID_OUI_FROM_DATABASE=Giga-tronics, Inc.
+
+OUI:0050C278D*
+ ID_OUI_FROM_DATABASE=Telairity
+
+OUI:0050C278E*
+ ID_OUI_FROM_DATABASE=GLOBALCOM ENGINEERING SRL
+
+OUI:0050C278F*
+ ID_OUI_FROM_DATABASE=ELMAR electronic
+
+OUI:0050C2790*
+ ID_OUI_FROM_DATABASE=GE Security-Kampro
+
+OUI:0050C2791*
+ ID_OUI_FROM_DATABASE=M Squared Lasers Limited
+
+OUI:0050C2792*
+ ID_OUI_FROM_DATABASE=SMARTRO Co.,Ltd.
+
+OUI:0050C2793*
+ ID_OUI_FROM_DATABASE=Enertex Bayern GmbH
+
+OUI:0050C2794*
+ ID_OUI_FROM_DATABASE=COMSONICS, INC.
+
+OUI:0050C2795*
+ ID_OUI_FROM_DATABASE=Ameli Spa
+
+OUI:0050C2796*
+ ID_OUI_FROM_DATABASE=DORLET S.A.
+
+OUI:0050C2797*
+ ID_OUI_FROM_DATABASE=Tiefenbach Control Systems GmbH
+
+OUI:0050C2798*
+ ID_OUI_FROM_DATABASE=Indefia
+
+OUI:0050C2799*
+ ID_OUI_FROM_DATABASE=AAVD
+
+OUI:0050C279A*
+ ID_OUI_FROM_DATABASE=JMC America, LLC
+
+OUI:0050C279B*
+ ID_OUI_FROM_DATABASE=Schniewindt GmbH & Co. KG
+
+OUI:0050C279C*
+ ID_OUI_FROM_DATABASE=Vital Systems Inc
+
+OUI:0050C279D*
+ ID_OUI_FROM_DATABASE=MiraTrek
+
+OUI:0050C279E*
+ ID_OUI_FROM_DATABASE=Benshaw Canada Controls, Inc.
+
+OUI:0050C279F*
+ ID_OUI_FROM_DATABASE=ZAO NPC
+
+OUI:0050C27A0*
+ ID_OUI_FROM_DATABASE=MedAvant Healthcare
+
+OUI:0050C27A1*
+ ID_OUI_FROM_DATABASE=Field Design Service
+
+OUI:0050C27A2*
+ ID_OUI_FROM_DATABASE=RaySat Israel LTD
+
+OUI:0050C27A3*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiam
+
+OUI:0050C27A4*
+ ID_OUI_FROM_DATABASE=Calibre UK LTD
+
+OUI:0050C27A5*
+ ID_OUI_FROM_DATABASE=Quantum Medical Imaging
+
+OUI:0050C27A6*
+ ID_OUI_FROM_DATABASE=ASIANA IDT
+
+OUI:0050C27A7*
+ ID_OUI_FROM_DATABASE=Guidance Navigation Limited
+
+OUI:0050C27A8*
+ ID_OUI_FROM_DATABASE=Integrated Design Tools, Inc.
+
+OUI:0050C27A9*
+ ID_OUI_FROM_DATABASE=Delta Tau Data Systems, Inc
+
+OUI:0050C27AA*
+ ID_OUI_FROM_DATABASE=EPEL INDUSTRIAL
+
+OUI:0050C27AB*
+ ID_OUI_FROM_DATABASE=General Microsystems Sdn Bhd
+
+OUI:0050C27AC*
+ ID_OUI_FROM_DATABASE=IUSA SA DE CV
+
+OUI:0050C27AD*
+ ID_OUI_FROM_DATABASE=Turun Turvatekniikka Oy
+
+OUI:0050C27AE*
+ ID_OUI_FROM_DATABASE=Global Tel-Link
+
+OUI:0050C27AF*
+ ID_OUI_FROM_DATABASE=C2 Microsystems
+
+OUI:0050C27B0*
+ ID_OUI_FROM_DATABASE=IMP Telekom
+
+OUI:0050C27B1*
+ ID_OUI_FROM_DATABASE=ATEME
+
+OUI:0050C27B2*
+ ID_OUI_FROM_DATABASE=A.D.I Video technologies
+
+OUI:0050C27B3*
+ ID_OUI_FROM_DATABASE=Elmec,  Inc.
+
+OUI:0050C27B4*
+ ID_OUI_FROM_DATABASE=T 1 Engineering
+
+OUI:0050C27B5*
+ ID_OUI_FROM_DATABASE=DIT-MCO International
+
+OUI:0050C27B6*
+ ID_OUI_FROM_DATABASE=Alstom (Schweiz) AG
+
+OUI:0050C27B7*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:0050C27B8*
+ ID_OUI_FROM_DATABASE=Design 2000 Pty Ltd
+
+OUI:0050C27B9*
+ ID_OUI_FROM_DATABASE=Technovare Systems, Inc.
+
+OUI:0050C27BA*
+ ID_OUI_FROM_DATABASE=Infodev Electronic Designers Intl.
+
+OUI:0050C27BB*
+ ID_OUI_FROM_DATABASE=InRay Solutions Ltd.
+
+OUI:0050C27BC*
+ ID_OUI_FROM_DATABASE=EIDOS SPA
+
+OUI:0050C27BD*
+ ID_OUI_FROM_DATABASE=PROMATE ELECTRONIC CO.LTD
+
+OUI:0050C27BE*
+ ID_OUI_FROM_DATABASE=Powerlinx, Inc.
+
+OUI:0050C27BF*
+ ID_OUI_FROM_DATABASE=Zoe Medical
+
+OUI:0050C27C0*
+ ID_OUI_FROM_DATABASE=European Industrial Electronics B.V.
+
+OUI:0050C27C1*
+ ID_OUI_FROM_DATABASE=Primary Integration Encorp LLC
+
+OUI:0050C27C2*
+ ID_OUI_FROM_DATABASE=DSR Information Technologies Ltd.
+
+OUI:0050C27C3*
+ ID_OUI_FROM_DATABASE=AST INCORPORATED
+
+OUI:0050C27C4*
+ ID_OUI_FROM_DATABASE=MoBaCon
+
+OUI:0050C27C5*
+ ID_OUI_FROM_DATABASE=Venture Research Inc.
+
+OUI:0050C27C6*
+ ID_OUI_FROM_DATABASE=Lyngdorf Audio Aps
+
+OUI:0050C27C7*
+ ID_OUI_FROM_DATABASE=Pyrosequencing AB
+
+OUI:0050C27C8*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C27C9*
+ ID_OUI_FROM_DATABASE=Bluebell Opticom Limited
+
+OUI:0050C27CA*
+ ID_OUI_FROM_DATABASE=CEDAR Audio Limited
+
+OUI:0050C27CB*
+ ID_OUI_FROM_DATABASE=ViewPlus Technologies, Inc.
+
+OUI:0050C27CC*
+ ID_OUI_FROM_DATABASE=SWECO JAPS AB
+
+OUI:0050C27CD*
+ ID_OUI_FROM_DATABASE=Precision MicroControl Corporation
+
+OUI:0050C27CE*
+ ID_OUI_FROM_DATABASE=AirCell Inc.
+
+OUI:0050C27CF*
+ ID_OUI_FROM_DATABASE=Emitech Corporation
+
+OUI:0050C27D0*
+ ID_OUI_FROM_DATABASE=Radar Tronic ltd.
+
+OUI:0050C27D1*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C27D2*
+ ID_OUI_FROM_DATABASE=Bittitalo Oy
+
+OUI:0050C27D3*
+ ID_OUI_FROM_DATABASE=Highrail Systems Limited
+
+OUI:0050C27D4*
+ ID_OUI_FROM_DATABASE=WR Systems, Ltd.
+
+OUI:0050C27D5*
+ ID_OUI_FROM_DATABASE=Deuta-Werke GmbH
+
+OUI:0050C27D6*
+ ID_OUI_FROM_DATABASE=International Mining Technologies
+
+OUI:0050C27D7*
+ ID_OUI_FROM_DATABASE=Newtec A/S
+
+OUI:0050C27D8*
+ ID_OUI_FROM_DATABASE=InnoScan K/S
+
+OUI:0050C27D9*
+ ID_OUI_FROM_DATABASE=Volumatic Limited
+
+OUI:0050C27DA*
+ ID_OUI_FROM_DATABASE=HTEC Limited
+
+OUI:0050C27DB*
+ ID_OUI_FROM_DATABASE=Mueller Elektronik
+
+OUI:0050C27DC*
+ ID_OUI_FROM_DATABASE=aiXtrusion GmbH
+
+OUI:0050C27DD*
+ ID_OUI_FROM_DATABASE=LS Elektronik AB
+
+OUI:0050C27DE*
+ ID_OUI_FROM_DATABASE=Cascade Technologies Ltd
+
+OUI:0050C27E0*
+ ID_OUI_FROM_DATABASE=C&D Technologies, Inc
+
+OUI:0050C27E1*
+ ID_OUI_FROM_DATABASE=Zeltiq Aesthetics, Inc.
+
+OUI:0050C27E2*
+ ID_OUI_FROM_DATABASE=DIGITROL LTD
+
+OUI:0050C27E3*
+ ID_OUI_FROM_DATABASE=Progentech Limited
+
+OUI:0050C27E4*
+ ID_OUI_FROM_DATABASE=Meta Vision Systems Ltd.
+
+OUI:0050C27E5*
+ ID_OUI_FROM_DATABASE=Nystrom Engineering
+
+OUI:0050C27E6*
+ ID_OUI_FROM_DATABASE=Empirix Italy S.p.A.
+
+OUI:0050C27E7*
+ ID_OUI_FROM_DATABASE=V2Green, Inc.
+
+OUI:0050C27E8*
+ ID_OUI_FROM_DATABASE=Mistral Solutions Pvt. Ltd
+
+OUI:0050C27E9*
+ ID_OUI_FROM_DATABASE=Sicon s.r.l.
+
+OUI:0050C27EA*
+ ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd.
+
+OUI:0050C27EB*
+ ID_OUI_FROM_DATABASE=Sesol Industrial Computer
+
+OUI:0050C27EC*
+ ID_OUI_FROM_DATABASE=Lyngsoe Systems
+
+OUI:0050C27ED*
+ ID_OUI_FROM_DATABASE=Genesis Automation Inc.
+
+OUI:0050C27EE*
+ ID_OUI_FROM_DATABASE=NH Research
+
+OUI:0050C27EF*
+ ID_OUI_FROM_DATABASE=GFI Chrono Time
+
+OUI:0050C27F0*
+ ID_OUI_FROM_DATABASE=Network Harbor, Inc.
+
+OUI:0050C27F1*
+ ID_OUI_FROM_DATABASE=STUHL Regelsysteme GmbH
+
+OUI:0050C27F2*
+ ID_OUI_FROM_DATABASE=Logotherm Regelsysteme GmbH
+
+OUI:0050C27F3*
+ ID_OUI_FROM_DATABASE=SOREC
+
+OUI:0050C27F4*
+ ID_OUI_FROM_DATABASE=Wireless Cables Inc
+
+OUI:0050C27F5*
+ ID_OUI_FROM_DATABASE=ACE Carwash Systems
+
+OUI:0050C27F6*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C27F7*
+ ID_OUI_FROM_DATABASE=MangoDSP
+
+OUI:0050C27F8*
+ ID_OUI_FROM_DATABASE=Wise Industria de Telecomunicações Ldta.
+
+OUI:0050C27F9*
+ ID_OUI_FROM_DATABASE=Karl DUNGS GmbH & Co. KG
+
+OUI:0050C27FA*
+ ID_OUI_FROM_DATABASE=AutomationX GmbH
+
+OUI:0050C27FB*
+ ID_OUI_FROM_DATABASE=Qtron Pty Ltd
+
+OUI:0050C27FC*
+ ID_OUI_FROM_DATABASE=TIS Dialog LLC
+
+OUI:0050C27FD*
+ ID_OUI_FROM_DATABASE=Adeneo
+
+OUI:0050C27FE*
+ ID_OUI_FROM_DATABASE=Wireless Cables Inc.
+
+OUI:0050C27FF*
+ ID_OUI_FROM_DATABASE=Shenzhen MaiWei Cable TV Equipment CO.,LTD.
+
+OUI:0050C2800*
+ ID_OUI_FROM_DATABASE=Delphi Display Systems, Inc.
+
+OUI:0050C2801*
+ ID_OUI_FROM_DATABASE=JANUS srl
+
+OUI:0050C2803*
+ ID_OUI_FROM_DATABASE=dB Broadcast Limited
+
+OUI:0050C2804*
+ ID_OUI_FROM_DATABASE=SoftSwitching Technologies
+
+OUI:0050C2805*
+ ID_OUI_FROM_DATABASE=MultimediaLED
+
+OUI:0050C2806*
+ ID_OUI_FROM_DATABASE=CET
+
+OUI:0050C2807*
+ ID_OUI_FROM_DATABASE=TECHNOMARK
+
+OUI:0050C2808*
+ ID_OUI_FROM_DATABASE=ITB CompuPhase
+
+OUI:0050C2809*
+ ID_OUI_FROM_DATABASE=Varma Electronics Oy
+
+OUI:0050C280A*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C280B*
+ ID_OUI_FROM_DATABASE=Open Video, Inc.
+
+OUI:0050C280C*
+ ID_OUI_FROM_DATABASE=Luxpert Technologies Co., Ltd.
+
+OUI:0050C280D*
+ ID_OUI_FROM_DATABASE=Acube Systems s.r.l.
+
+OUI:0050C280E*
+ ID_OUI_FROM_DATABASE=Bruno International Ltd.
+
+OUI:0050C280F*
+ ID_OUI_FROM_DATABASE=Selekron Microcontrol s.l.
+
+OUI:0050C2810*
+ ID_OUI_FROM_DATABASE=Alphion Corporation
+
+OUI:0050C2811*
+ ID_OUI_FROM_DATABASE=Open System Solutions Limited
+
+OUI:0050C2812*
+ ID_OUI_FROM_DATABASE=Femto SA
+
+OUI:0050C2813*
+ ID_OUI_FROM_DATABASE=Intelleflex Corporation
+
+OUI:0050C2814*
+ ID_OUI_FROM_DATABASE=Telvent
+
+OUI:0050C2815*
+ ID_OUI_FROM_DATABASE=microC Design SRL
+
+OUI:0050C2816*
+ ID_OUI_FROM_DATABASE=Intelight Inc.
+
+OUI:0050C2817*
+ ID_OUI_FROM_DATABASE=Odin TeleSystems Inc
+
+OUI:0050C2818*
+ ID_OUI_FROM_DATABASE=Wireless Value BV
+
+OUI:0050C2819*
+ ID_OUI_FROM_DATABASE=Cabinplant A/S
+
+OUI:0050C281A*
+ ID_OUI_FROM_DATABASE=InfoGLOBAL
+
+OUI:0050C281B*
+ ID_OUI_FROM_DATABASE=Brain Tech Co., Ltd
+
+OUI:0050C281C*
+ ID_OUI_FROM_DATABASE=Telcom
+
+OUI:0050C281D*
+ ID_OUI_FROM_DATABASE=IT SALUX CO., LTD.
+
+OUI:0050C281E*
+ ID_OUI_FROM_DATABASE=Channelot Ltd.
+
+OUI:0050C281F*
+ ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s.
+
+OUI:0050C2820*
+ ID_OUI_FROM_DATABASE=TESCAN, s.r.o.
+
+OUI:0050C2821*
+ ID_OUI_FROM_DATABASE=MISCO Refractometer
+
+OUI:0050C2822*
+ ID_OUI_FROM_DATABASE=Winner Technology Co, Ltd.
+
+OUI:0050C2823*
+ ID_OUI_FROM_DATABASE=Robot Visual Systems GmbH
+
+OUI:0050C2824*
+ ID_OUI_FROM_DATABASE=SMT d.o.o.
+
+OUI:0050C2825*
+ ID_OUI_FROM_DATABASE=Funkwerk Information Technologies Karlsfeld GmbH
+
+OUI:0050C2826*
+ ID_OUI_FROM_DATABASE=HEWI Heinrich Wilke GmbH
+
+OUI:0050C2827*
+ ID_OUI_FROM_DATABASE=Enero Solutions inc.
+
+OUI:0050C2828*
+ ID_OUI_FROM_DATABASE=SLICAN sp. z o.o.
+
+OUI:0050C2829*
+ ID_OUI_FROM_DATABASE=Intellectronika
+
+OUI:0050C282A*
+ ID_OUI_FROM_DATABASE=VDC Display Systems
+
+OUI:0050C282B*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C282C*
+ ID_OUI_FROM_DATABASE=Vitel Net
+
+OUI:0050C282D*
+ ID_OUI_FROM_DATABASE=Elmec, Inc.
+
+OUI:0050C282E*
+ ID_OUI_FROM_DATABASE=LogiCom GmbH
+
+OUI:0050C282F*
+ ID_OUI_FROM_DATABASE=Momentum Data Systems
+
+OUI:0050C2830*
+ ID_OUI_FROM_DATABASE=CompuShop Services LLC
+
+OUI:0050C2831*
+ ID_OUI_FROM_DATABASE=St Jude Medical, Inc.
+
+OUI:0050C2832*
+ ID_OUI_FROM_DATABASE=S1nn GmbH & Co. KG
+
+OUI:0050C2833*
+ ID_OUI_FROM_DATABASE=LaserLinc, Inc.
+
+OUI:0050C2834*
+ ID_OUI_FROM_DATABASE=ANTEK GmbH
+
+OUI:0050C2835*
+ ID_OUI_FROM_DATABASE=Communications Laboratories Inc
+
+OUI:0050C2836*
+ ID_OUI_FROM_DATABASE=DSP DESIGN
+
+OUI:0050C2837*
+ ID_OUI_FROM_DATABASE=ID-KARTA s.r.o.
+
+OUI:0050C2838*
+ ID_OUI_FROM_DATABASE=T PROJE MUHENDISLIK DIS. TIC. LTD. STI.
+
+OUI:0050C2839*
+ ID_OUI_FROM_DATABASE=IMS Röntgensysteme GmbH
+
+OUI:0050C283A*
+ ID_OUI_FROM_DATABASE=Syr-Tec Engineering & Marketing
+
+OUI:0050C283B*
+ ID_OUI_FROM_DATABASE=O. Bay AG
+
+OUI:0050C283C*
+ ID_OUI_FROM_DATABASE=hema electronic GmbH
+
+OUI:0050C283D*
+ ID_OUI_FROM_DATABASE=beroNet GmbH
+
+OUI:0050C283E*
+ ID_OUI_FROM_DATABASE=KPE spol. s r.o.
+
+OUI:0050C283F*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2840*
+ ID_OUI_FROM_DATABASE=Residential Control Systems
+
+OUI:0050C2841*
+ ID_OUI_FROM_DATABASE=Connection Electronics Ltd.
+
+OUI:0050C2842*
+ ID_OUI_FROM_DATABASE=Quantum Controls BV
+
+OUI:0050C2843*
+ ID_OUI_FROM_DATABASE=Xtensor Systems Inc.
+
+OUI:0050C2844*
+ ID_OUI_FROM_DATABASE=Prodigy Electronics Limited
+
+OUI:0050C2845*
+ ID_OUI_FROM_DATABASE=VisualSonics Inc.
+
+OUI:0050C2846*
+ ID_OUI_FROM_DATABASE=ESP-Planning Co.
+
+OUI:0050C2847*
+ ID_OUI_FROM_DATABASE=Lars Morich Kommunikationstechnik GmbH
+
+OUI:0050C2848*
+ ID_OUI_FROM_DATABASE=DASA ROBOT Co., Ltd.
+
+OUI:0050C2849*
+ ID_OUI_FROM_DATABASE=Design Analysis Associates, Inc.
+
+OUI:0050C284A*
+ ID_OUI_FROM_DATABASE=Keystone Electronic Solutions
+
+OUI:0050C284B*
+ ID_OUI_FROM_DATABASE=TASK SISTEMAS DE COMPUTACAO LTDA
+
+OUI:0050C284C*
+ ID_OUI_FROM_DATABASE=Performance Motion Devices
+
+OUI:0050C284D*
+ ID_OUI_FROM_DATABASE=BMTI
+
+OUI:0050C284E*
+ ID_OUI_FROM_DATABASE=DRACO SYSTEMS
+
+OUI:0050C284F*
+ ID_OUI_FROM_DATABASE=Gamber-Johnson LLC
+
+OUI:0050C2850*
+ ID_OUI_FROM_DATABASE=K.K. Rocky
+
+OUI:0050C2851*
+ ID_OUI_FROM_DATABASE=SPJ Embedded Technologies Pvt. Ltd.
+
+OUI:0050C2852*
+ ID_OUI_FROM_DATABASE=eInfochips Ltd.
+
+OUI:0050C2853*
+ ID_OUI_FROM_DATABASE=Ettus Research LLC
+
+OUI:0050C2854*
+ ID_OUI_FROM_DATABASE=Ratioplast-Optoelectronics GmbH
+
+OUI:0050C2855*
+ ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA
+
+OUI:0050C2856*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2857*
+ ID_OUI_FROM_DATABASE=EPEL INDUSTRIAL
+
+OUI:0050C2858*
+ ID_OUI_FROM_DATABASE=Wireless Acquisition LLC
+
+OUI:0050C2859*
+ ID_OUI_FROM_DATABASE=Nuvation
+
+OUI:0050C285A*
+ ID_OUI_FROM_DATABASE=ART s.r.l.
+
+OUI:0050C285B*
+ ID_OUI_FROM_DATABASE=Boreste
+
+OUI:0050C285C*
+ ID_OUI_FROM_DATABASE=B S E
+
+OUI:0050C285D*
+ ID_OUI_FROM_DATABASE=Ing. Knauseder Mechatronik GmbH
+
+OUI:0050C285E*
+ ID_OUI_FROM_DATABASE=Radiometer Medical ApS
+
+OUI:0050C285F*
+ ID_OUI_FROM_DATABASE=General Dynamics C4 Systems
+
+OUI:0050C2860*
+ ID_OUI_FROM_DATABASE=Eutron S.p.A.
+
+OUI:0050C2861*
+ ID_OUI_FROM_DATABASE=Grantronics Pty Ltd
+
+OUI:0050C2862*
+ ID_OUI_FROM_DATABASE=Elsys AG
+
+OUI:0050C2863*
+ ID_OUI_FROM_DATABASE=Advanced Technology Solutions
+
+OUI:0050C2864*
+ ID_OUI_FROM_DATABASE=ATG Automatisierungstechnik GERA GmbH
+
+OUI:0050C2865*
+ ID_OUI_FROM_DATABASE=Persy Control Services B.v.
+
+OUI:0050C2866*
+ ID_OUI_FROM_DATABASE=Saia Burgess Controls AG
+
+OUI:0050C2867*
+ ID_OUI_FROM_DATABASE=Syntronics
+
+OUI:0050C2868*
+ ID_OUI_FROM_DATABASE=Aethon, Inc.
+
+OUI:0050C2869*
+ ID_OUI_FROM_DATABASE=Funkwerk plettac electronic GmbH
+
+OUI:0050C286A*
+ ID_OUI_FROM_DATABASE=USM Systems, Ltd
+
+OUI:0050C286B*
+ ID_OUI_FROM_DATABASE=OMB Sistemas Electronicos S.A.
+
+OUI:0050C286C*
+ ID_OUI_FROM_DATABASE=Condigi Televagt A/S
+
+OUI:0050C286D*
+ ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd
+
+OUI:0050C286E*
+ ID_OUI_FROM_DATABASE=HANYANG ELECTRIC CP., LTD
+
+OUI:0050C286F*
+ ID_OUI_FROM_DATABASE=b-plus GmbH
+
+OUI:0050C2870*
+ ID_OUI_FROM_DATABASE=LOGEL S.R.L.
+
+OUI:0050C2871*
+ ID_OUI_FROM_DATABASE=R-S-I Elektrotechnik GmbH & Co. KG
+
+OUI:0050C2872*
+ ID_OUI_FROM_DATABASE=Oliotalo - Objecthouse Oy
+
+OUI:0050C2873*
+ ID_OUI_FROM_DATABASE=XRONET Corporation
+
+OUI:0050C2874*
+ ID_OUI_FROM_DATABASE=Arcos Technologies Ltd.
+
+OUI:0050C2875*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2876*
+ ID_OUI_FROM_DATABASE=Privatquelle Gruber GmbH & CO KG
+
+OUI:0050C2877*
+ ID_OUI_FROM_DATABASE=Motion Analysis Corp
+
+OUI:0050C2878*
+ ID_OUI_FROM_DATABASE=Acoustic Research Laboratories Pty Ltd
+
+OUI:0050C2879*
+ ID_OUI_FROM_DATABASE=MILESYS
+
+OUI:0050C287A*
+ ID_OUI_FROM_DATABASE=Spectrum Management, LC
+
+OUI:0050C287B*
+ ID_OUI_FROM_DATABASE=UAVNavigation S.L.
+
+OUI:0050C287C*
+ ID_OUI_FROM_DATABASE=Arcontia AB
+
+OUI:0050C287D*
+ ID_OUI_FROM_DATABASE=AT&T Government Solutions
+
+OUI:0050C287E*
+ ID_OUI_FROM_DATABASE=SCM PRODUCTS, INC.
+
+OUI:0050C287F*
+ ID_OUI_FROM_DATABASE=Optoelettronica Italia S.r.l.
+
+OUI:0050C2880*
+ ID_OUI_FROM_DATABASE=Creation Technologies
+
+OUI:0050C2881*
+ ID_OUI_FROM_DATABASE=InnoTrans Communications, Inc.
+
+OUI:0050C2882*
+ ID_OUI_FROM_DATABASE=WARECUBE,INC.
+
+OUI:0050C2883*
+ ID_OUI_FROM_DATABASE=Neocontrol Soluções em Automação
+
+OUI:0050C2884*
+ ID_OUI_FROM_DATABASE=IP Thinking A/S
+
+OUI:0050C2885*
+ ID_OUI_FROM_DATABASE=OOO "NTK "IMOS"
+
+OUI:0050C2886*
+ ID_OUI_FROM_DATABASE=Transas Scandinavia AB
+
+OUI:0050C2887*
+ ID_OUI_FROM_DATABASE=Inventis Technology Pty Limited
+
+OUI:0050C2888*
+ ID_OUI_FROM_DATABASE=IADEA CORPORATION
+
+OUI:0050C2889*
+ ID_OUI_FROM_DATABASE=ACS MOTION CONTROL
+
+OUI:0050C288A*
+ ID_OUI_FROM_DATABASE=Continental Electronics Corp.
+
+OUI:0050C288B*
+ ID_OUI_FROM_DATABASE=Hollis Electronics Company LLC
+
+OUI:0050C288C*
+ ID_OUI_FROM_DATABASE=Z-App Systems
+
+OUI:0050C288D*
+ ID_OUI_FROM_DATABASE=L3 Communications Nova Engineering
+
+OUI:0050C288E*
+ ID_OUI_FROM_DATABASE=Cardinal Scale Mfg Co
+
+OUI:0050C288F*
+ ID_OUI_FROM_DATABASE=Keynote SIGOS GmbH
+
+OUI:0050C2890*
+ ID_OUI_FROM_DATABASE=BAE Systems Hägglunds AB
+
+OUI:0050C2891*
+ ID_OUI_FROM_DATABASE=Admiral Secure Products, Ltd.
+
+OUI:0050C2892*
+ ID_OUI_FROM_DATABASE=Trakce a.s.
+
+OUI:0050C2893*
+ ID_OUI_FROM_DATABASE=EIZO Technologies GmbH
+
+OUI:0050C2894*
+ ID_OUI_FROM_DATABASE=Shockfish SA
+
+OUI:0050C2895*
+ ID_OUI_FROM_DATABASE=Marine Communications Limited
+
+OUI:0050C2896*
+ ID_OUI_FROM_DATABASE=Blankom
+
+OUI:0050C2897*
+ ID_OUI_FROM_DATABASE=ODF Optronics, Inc.
+
+OUI:0050C2898*
+ ID_OUI_FROM_DATABASE=Veeco Process Equipment, Inc.
+
+OUI:0050C2899*
+ ID_OUI_FROM_DATABASE=Inico Technologies Ltd.
+
+OUI:0050C289A*
+ ID_OUI_FROM_DATABASE=Neptune Technology Group, Inc.
+
+OUI:0050C289B*
+ ID_OUI_FROM_DATABASE=Sensata Technologies, Inc.
+
+OUI:0050C289C*
+ ID_OUI_FROM_DATABASE=Mediana
+
+OUI:0050C289D*
+ ID_OUI_FROM_DATABASE=Systemtechnik GmbH
+
+OUI:0050C289E*
+ ID_OUI_FROM_DATABASE=Broadcast Electronics
+
+OUI:0050C289F*
+ ID_OUI_FROM_DATABASE=Datalink Technologies Gateways Inc.
+
+OUI:0050C28A0*
+ ID_OUI_FROM_DATABASE=Specialized Communications Corp.
+
+OUI:0050C28A1*
+ ID_OUI_FROM_DATABASE=Intune Networks Limited
+
+OUI:0050C28A2*
+ ID_OUI_FROM_DATABASE=UAVISION Engenharia de Sistemas
+
+OUI:0050C28A3*
+ ID_OUI_FROM_DATABASE=RTW GmbH & Co.KG
+
+OUI:0050C28A4*
+ ID_OUI_FROM_DATABASE=BALOGH T.A.G Corporation
+
+OUI:0050C28A5*
+ ID_OUI_FROM_DATABASE=Mocon, Inc.
+
+OUI:0050C28A6*
+ ID_OUI_FROM_DATABASE=SELCO
+
+OUI:0050C28A7*
+ ID_OUI_FROM_DATABASE=EBPW LTD
+
+OUI:0050C28A8*
+ ID_OUI_FROM_DATABASE=ALTEK ELECTRONICS
+
+OUI:0050C28A9*
+ ID_OUI_FROM_DATABASE=Intelligent Security Systems
+
+OUI:0050C28AA*
+ ID_OUI_FROM_DATABASE=ATS Elektronik GmbH
+
+OUI:0050C28AB*
+ ID_OUI_FROM_DATABASE=Nanomotion Ltd.
+
+OUI:0050C28AC*
+ ID_OUI_FROM_DATABASE=Telsa s.r.l
+
+OUI:0050C28AD*
+ ID_OUI_FROM_DATABASE=Thales Communications, Inc
+
+OUI:0050C28AE*
+ ID_OUI_FROM_DATABASE=DESARROLLO DE SISTEMAS INTEGRADOS DE CONTROL S.A.
+
+OUI:0050C28AF*
+ ID_OUI_FROM_DATABASE=Xelerated
+
+OUI:0050C28B0*
+ ID_OUI_FROM_DATABASE=BK Innovation, Inc.
+
+OUI:0050C28B1*
+ ID_OUI_FROM_DATABASE=RingCube Technologies, Inc.
+
+OUI:0050C28B2*
+ ID_OUI_FROM_DATABASE=SERVAIND SA.
+
+OUI:0050C28B3*
+ ID_OUI_FROM_DATABASE=VTQ Videtronik GmbH
+
+OUI:0050C28B4*
+ ID_OUI_FROM_DATABASE=Sandar Telecast AS
+
+OUI:0050C28B5*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C28B6*
+ ID_OUI_FROM_DATABASE=Shadrinskiy Telefonny Zavod
+
+OUI:0050C28B7*
+ ID_OUI_FROM_DATABASE=Calnex Solutions Limited
+
+OUI:0050C28B8*
+ ID_OUI_FROM_DATABASE=DSS Networks, Inc.
+
+OUI:0050C28B9*
+ ID_OUI_FROM_DATABASE=ACD Elektronik Gmbh
+
+OUI:0050C28BA*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C28BB*
+ ID_OUI_FROM_DATABASE=smtag international ag
+
+OUI:0050C28BC*
+ ID_OUI_FROM_DATABASE=Honeywell Sensotec
+
+OUI:0050C28BD*
+ ID_OUI_FROM_DATABASE=Matrix Switch Corporation
+
+OUI:0050C28BE*
+ ID_OUI_FROM_DATABASE=The Pennsylvania State University
+
+OUI:0050C28BF*
+ ID_OUI_FROM_DATABASE=ARISTO Graphic Systeme GmbH & Co. KG
+
+OUI:0050C28C0*
+ ID_OUI_FROM_DATABASE=S.C.E. s.r.l.
+
+OUI:0050C28C1*
+ ID_OUI_FROM_DATABASE=Heraeus Noblelight GmbH
+
+OUI:0050C28C2*
+ ID_OUI_FROM_DATABASE=Access Control Systems JSC
+
+OUI:0050C28C3*
+ ID_OUI_FROM_DATABASE=Byte Paradigm
+
+OUI:0050C28C4*
+ ID_OUI_FROM_DATABASE=Soldig Industria e Comercio de Equipamentos Eletronicos LTDA
+
+OUI:0050C28C5*
+ ID_OUI_FROM_DATABASE=Vortex Engineering pvt ltd
+
+OUI:0050C28C6*
+ ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda.
+
+OUI:0050C28C7*
+ ID_OUI_FROM_DATABASE=Tattile srl
+
+OUI:0050C28C8*
+ ID_OUI_FROM_DATABASE=Pumatronix Equipamentos Eletrônicos Ltda
+
+OUI:0050C28C9*
+ ID_OUI_FROM_DATABASE=A+S Aktuatorik und Sensorik GmbH
+
+OUI:0050C28CA*
+ ID_OUI_FROM_DATABASE=Altair semiconductor Ltd
+
+OUI:0050C28CB*
+ ID_OUI_FROM_DATABASE=Beonic Corporation
+
+OUI:0050C28CC*
+ ID_OUI_FROM_DATABASE=LyconSys GmbH & Co.KG
+
+OUI:0050C28CD*
+ ID_OUI_FROM_DATABASE=Cambridge Sound Management, LLC
+
+OUI:0050C28CE*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C28CF*
+ ID_OUI_FROM_DATABASE=GigaLinx Ltd.
+
+OUI:0050C28D0*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C28D1*
+ ID_OUI_FROM_DATABASE=my-sen GmbH
+
+OUI:0050C28D2*
+ ID_OUI_FROM_DATABASE=TTi Ltd
+
+OUI:0050C28D3*
+ ID_OUI_FROM_DATABASE=IFAM GmbH
+
+OUI:0050C28D4*
+ ID_OUI_FROM_DATABASE=Internet Protocolo Lógica SL
+
+OUI:0050C28D5*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corp
+
+OUI:0050C28D6*
+ ID_OUI_FROM_DATABASE=UltraVision Security Systems, Inc.
+
+OUI:0050C28D7*
+ ID_OUI_FROM_DATABASE=Polygon Informatics Ltd.
+
+OUI:0050C28D8*
+ ID_OUI_FROM_DATABASE=Array Technologies Inc
+
+OUI:0050C28D9*
+ ID_OUI_FROM_DATABASE=Industrial Control and Communication Limited
+
+OUI:0050C28DA*
+ ID_OUI_FROM_DATABASE=DOCUTEMP, INC
+
+OUI:0050C28DB*
+ ID_OUI_FROM_DATABASE=DCOM Network Technology (Pty) Ltd
+
+OUI:0050C28DC*
+ ID_OUI_FROM_DATABASE=Frame Systems Limited
+
+OUI:0050C28DD*
+ ID_OUI_FROM_DATABASE=GIMCON
+
+OUI:0050C28DE*
+ ID_OUI_FROM_DATABASE=Coherix, Inc
+
+OUI:0050C28DF*
+ ID_OUI_FROM_DATABASE=Dipl.-Ing. W. Nophut GmbH
+
+OUI:0050C28E0*
+ ID_OUI_FROM_DATABASE=Shenzhen Pennda Technologies Co., Ltd.
+
+OUI:0050C28E1*
+ ID_OUI_FROM_DATABASE=Deutscher Weterdienst
+
+OUI:0050C28E2*
+ ID_OUI_FROM_DATABASE=Wireless Cables Inc
+
+OUI:0050C28E3*
+ ID_OUI_FROM_DATABASE=bioMérieux Italia S.p.A.
+
+OUI:0050C28E4*
+ ID_OUI_FROM_DATABASE=MaCaPS International Limited
+
+OUI:0050C28E5*
+ ID_OUI_FROM_DATABASE=Berthel GmbH
+
+OUI:0050C28E6*
+ ID_OUI_FROM_DATABASE=Sandel Avionics, Inc.
+
+OUI:0050C28E7*
+ ID_OUI_FROM_DATABASE=MKT Systemtechnik
+
+OUI:0050C28E8*
+ ID_OUI_FROM_DATABASE=Friedrich Kuhnt GmbH
+
+OUI:0050C28E9*
+ ID_OUI_FROM_DATABASE=UNIDATA
+
+OUI:0050C28EA*
+ ID_OUI_FROM_DATABASE=ATEME
+
+OUI:0050C28EB*
+ ID_OUI_FROM_DATABASE=C-COM Satellite Systems Inc.
+
+OUI:0050C28EC*
+ ID_OUI_FROM_DATABASE=Balfour Beatty Rail GmbH
+
+OUI:0050C28ED*
+ ID_OUI_FROM_DATABASE=AT-Automation Technology GmbH
+
+OUI:0050C28EE*
+ ID_OUI_FROM_DATABASE=PCSC
+
+OUI:0050C28EF*
+ ID_OUI_FROM_DATABASE=Technologies Sensio Inc
+
+OUI:0050C28F0*
+ ID_OUI_FROM_DATABASE=Xentras Communications
+
+OUI:0050C28F1*
+ ID_OUI_FROM_DATABASE=Detection Technologies Ltd.
+
+OUI:0050C28F2*
+ ID_OUI_FROM_DATABASE=Schneider Electric GmbH
+
+OUI:0050C28F3*
+ ID_OUI_FROM_DATABASE=Curtis Door Systems Inc
+
+OUI:0050C28F4*
+ ID_OUI_FROM_DATABASE=Critical Link
+
+OUI:0050C28F5*
+ ID_OUI_FROM_DATABASE=tec5 AG
+
+OUI:0050C28F6*
+ ID_OUI_FROM_DATABASE=K-MAC Corp.
+
+OUI:0050C28F7*
+ ID_OUI_FROM_DATABASE=TGE Co., Ltd.
+
+OUI:0050C28F8*
+ ID_OUI_FROM_DATABASE=RMSD LTD
+
+OUI:0050C28F9*
+ ID_OUI_FROM_DATABASE=Honeywell International
+
+OUI:0050C28FA*
+ ID_OUI_FROM_DATABASE=TELIUM s.c.
+
+OUI:0050C28FB*
+ ID_OUI_FROM_DATABASE=Alfred Kuhse GmbH
+
+OUI:0050C28FC*
+ ID_OUI_FROM_DATABASE=Symetrics Industries
+
+OUI:0050C28FD*
+ ID_OUI_FROM_DATABASE=Sindoma Müh Mim Ýnþ Elk San Tic Ltd.
+
+OUI:0050C28FE*
+ ID_OUI_FROM_DATABASE=Cross Country Systems AB
+
+OUI:0050C28FF*
+ ID_OUI_FROM_DATABASE=Luceat Spa
+
+OUI:0050C2900*
+ ID_OUI_FROM_DATABASE=Magor Communications Corp
+
+OUI:0050C2901*
+ ID_OUI_FROM_DATABASE=Research Applications Incorp
+
+OUI:0050C2902*
+ ID_OUI_FROM_DATABASE=China Railway Signal & Communication Corp.
+
+OUI:0050C2903*
+ ID_OUI_FROM_DATABASE=EcoAxis Systems Pvt. Ltd.
+
+OUI:0050C2904*
+ ID_OUI_FROM_DATABASE=R2Sonic, LLC
+
+OUI:0050C2905*
+ ID_OUI_FROM_DATABASE=Link Communications, Inc
+
+OUI:0050C2906*
+ ID_OUI_FROM_DATABASE=Gidel
+
+OUI:0050C2907*
+ ID_OUI_FROM_DATABASE=Cristal Controles Ltee
+
+OUI:0050C2908*
+ ID_OUI_FROM_DATABASE=Codex Digital Ltd
+
+OUI:0050C2909*
+ ID_OUI_FROM_DATABASE=Elisra Electronic Systems
+
+OUI:0050C290A*
+ ID_OUI_FROM_DATABASE=Board Level Limited
+
+OUI:0050C290B*
+ ID_OUI_FROM_DATABASE=E.ON ES Sverige AB
+
+OUI:0050C290C*
+ ID_OUI_FROM_DATABASE=LSS GmbH
+
+OUI:0050C290D*
+ ID_OUI_FROM_DATABASE=EVK DI Kerschhaggl GmbH
+
+OUI:0050C290E*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C290F*
+ ID_OUI_FROM_DATABASE=INTEGRA Biosciences AG
+
+OUI:0050C2910*
+ ID_OUI_FROM_DATABASE=Autotank AB
+
+OUI:0050C2911*
+ ID_OUI_FROM_DATABASE=Vapor Rail
+
+OUI:0050C2912*
+ ID_OUI_FROM_DATABASE=ASSET InterTech, Inc.
+
+OUI:0050C2913*
+ ID_OUI_FROM_DATABASE=Selex Sensors & Airborne Systems
+
+OUI:0050C2914*
+ ID_OUI_FROM_DATABASE=IO-Connect
+
+OUI:0050C2915*
+ ID_OUI_FROM_DATABASE=Verint Systems Ltd.
+
+OUI:0050C2916*
+ ID_OUI_FROM_DATABASE=CHK GridSense P/L
+
+OUI:0050C2917*
+ ID_OUI_FROM_DATABASE=CIRTEM
+
+OUI:0050C2918*
+ ID_OUI_FROM_DATABASE=Design Lightning Corp
+
+OUI:0050C2919*
+ ID_OUI_FROM_DATABASE=AHV Systems, Inc.
+
+OUI:0050C291A*
+ ID_OUI_FROM_DATABASE=Xtone Networks
+
+OUI:0050C291B*
+ ID_OUI_FROM_DATABASE=Embedded Data Systems, LLC
+
+OUI:0050C291C*
+ ID_OUI_FROM_DATABASE=MangoDSP
+
+OUI:0050C291D*
+ ID_OUI_FROM_DATABASE=Rosendahl Studiotechnik GmbH
+
+OUI:0050C291E*
+ ID_OUI_FROM_DATABASE=Automation Tec
+
+OUI:0050C291F*
+ ID_OUI_FROM_DATABASE=2NCOMM DESIGN SRL
+
+OUI:0050C2920*
+ ID_OUI_FROM_DATABASE=Rogue Engineering Inc.
+
+OUI:0050C2921*
+ ID_OUI_FROM_DATABASE=iQue RFID Technologies BV
+
+OUI:0050C2922*
+ ID_OUI_FROM_DATABASE=Metrum Sweden AB
+
+OUI:0050C2923*
+ ID_OUI_FROM_DATABASE=Amicus Wireless
+
+OUI:0050C2924*
+ ID_OUI_FROM_DATABASE=Link Electric & Safety Control Co.
+
+OUI:0050C2925*
+ ID_OUI_FROM_DATABASE=PHB Eletronica Ltda.
+
+OUI:0050C2926*
+ ID_OUI_FROM_DATABASE=DITEST FAHRZEUGDIAGNOSE GMBH
+
+OUI:0050C2927*
+ ID_OUI_FROM_DATABASE=ATIS group s.r.o.
+
+OUI:0050C2928*
+ ID_OUI_FROM_DATABASE=Cinetix GmbH
+
+OUI:0050C2929*
+ ID_OUI_FROM_DATABASE=Flight Deck Resources
+
+OUI:0050C292A*
+ ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA
+
+OUI:0050C292B*
+ ID_OUI_FROM_DATABASE=DSP DESIGN
+
+OUI:0050C292C*
+ ID_OUI_FROM_DATABASE=Exatrol Corporation
+
+OUI:0050C292D*
+ ID_OUI_FROM_DATABASE=APProSoftware.com
+
+OUI:0050C292E*
+ ID_OUI_FROM_DATABASE=Goanna Technologies Pty Ltd
+
+OUI:0050C292F*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2930*
+ ID_OUI_FROM_DATABASE=NETA Elektronik AS
+
+OUI:0050C2931*
+ ID_OUI_FROM_DATABASE=Korea Telecom Internet Solutions (KTIS)
+
+OUI:0050C2932*
+ ID_OUI_FROM_DATABASE=SMAVIS Inc.
+
+OUI:0050C2933*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2934*
+ ID_OUI_FROM_DATABASE=Xilar Corp.
+
+OUI:0050C2935*
+ ID_OUI_FROM_DATABASE=Image Video
+
+OUI:0050C2936*
+ ID_OUI_FROM_DATABASE=Margaritis Engineering
+
+OUI:0050C2937*
+ ID_OUI_FROM_DATABASE=BigBear
+
+OUI:0050C2938*
+ ID_OUI_FROM_DATABASE=Postec Data Systems Ltd
+
+OUI:0050C2939*
+ ID_OUI_FROM_DATABASE=Mosaic Dynamic Solutions
+
+OUI:0050C293A*
+ ID_OUI_FROM_DATABASE=ALPHATRONICS nv
+
+OUI:0050C293B*
+ ID_OUI_FROM_DATABASE=Reliatronics Inc.
+
+OUI:0050C293C*
+ ID_OUI_FROM_DATABASE=FractureCode Corporation
+
+OUI:0050C293D*
+ ID_OUI_FROM_DATABASE=Lighting Science Group Corporation
+
+OUI:0050C293E*
+ ID_OUI_FROM_DATABASE=RCS Communication Test Systems Ltd.
+
+OUI:0050C293F*
+ ID_OUI_FROM_DATABASE=TSB Solutions Inc.
+
+OUI:0050C2940*
+ ID_OUI_FROM_DATABASE=Phitek Systems Ltd.
+
+OUI:0050C2941*
+ ID_OUI_FROM_DATABASE=Rolbit
+
+OUI:0050C2942*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2943*
+ ID_OUI_FROM_DATABASE=QuanZhou TDX Electronics Co., Ltd.
+
+OUI:0050C2944*
+ ID_OUI_FROM_DATABASE=Wireonair A/S
+
+OUI:0050C2945*
+ ID_OUI_FROM_DATABASE=Ex-i Flow Measurement Ltd.
+
+OUI:0050C2946*
+ ID_OUI_FROM_DATABASE=MEGWARE Computer GmbH
+
+OUI:0050C2947*
+ ID_OUI_FROM_DATABASE=IMEXHIGHWAY cvba
+
+OUI:0050C2948*
+ ID_OUI_FROM_DATABASE=ELECTRONIA
+
+OUI:0050C2949*
+ ID_OUI_FROM_DATABASE=taskit GmbH
+
+OUI:0050C294A*
+ ID_OUI_FROM_DATABASE=TRUMEDIA TECHNOLOGIES
+
+OUI:0050C294B*
+ ID_OUI_FROM_DATABASE=Piller engineering Ltd.
+
+OUI:0050C294C*
+ ID_OUI_FROM_DATABASE=TEMIX
+
+OUI:0050C294D*
+ ID_OUI_FROM_DATABASE=C&H technology  ltd.
+
+OUI:0050C294E*
+ ID_OUI_FROM_DATABASE=Zynix Original Sdn. Bhd.
+
+OUI:0050C294F*
+ ID_OUI_FROM_DATABASE=IT-Designers GmbH
+
+OUI:0050C2950*
+ ID_OUI_FROM_DATABASE=Tele and Radio Research Institute
+
+OUI:0050C2951*
+ ID_OUI_FROM_DATABASE=EL.C.A. soc. coop.
+
+OUI:0050C2952*
+ ID_OUI_FROM_DATABASE=Tech Fass s.r.o.
+
+OUI:0050C2953*
+ ID_OUI_FROM_DATABASE=EPEL Industrial
+
+OUI:0050C2954*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2955*
+ ID_OUI_FROM_DATABASE=Roessmann Engineering
+
+OUI:0050C2956*
+ ID_OUI_FROM_DATABASE=Sicon s.r.l.
+
+OUI:0050C2957*
+ ID_OUI_FROM_DATABASE=STRATEC Control Systems
+
+OUI:0050C2958*
+ ID_OUI_FROM_DATABASE=Sensoptics Ltd
+
+OUI:0050C2959*
+ ID_OUI_FROM_DATABASE=DECTRIS Ltd.
+
+OUI:0050C295A*
+ ID_OUI_FROM_DATABASE=TechnoAP
+
+OUI:0050C295B*
+ ID_OUI_FROM_DATABASE=AS Solar GmbH
+
+OUI:0050C295C*
+ ID_OUI_FROM_DATABASE=Resurgent Health & Medical
+
+OUI:0050C295D*
+ ID_OUI_FROM_DATABASE=full electronic system
+
+OUI:0050C295E*
+ ID_OUI_FROM_DATABASE=BEEcube Inc.
+
+OUI:0050C295F*
+ ID_OUI_FROM_DATABASE=METRONIC APARATURA KONTROLNO - POMIAROWA
+
+OUI:0050C2960*
+ ID_OUI_FROM_DATABASE=kuroneko dennnou kenkyuushitsu
+
+OUI:0050C2961*
+ ID_OUI_FROM_DATABASE=Picsolve International Limited
+
+OUI:0050C2962*
+ ID_OUI_FROM_DATABASE=Shockfish SA
+
+OUI:0050C2963*
+ ID_OUI_FROM_DATABASE=Lécureux SA
+
+OUI:0050C2964*
+ ID_OUI_FROM_DATABASE=IQ Automation GmbH
+
+OUI:0050C2965*
+ ID_OUI_FROM_DATABASE=Emitech Corporation
+
+OUI:0050C2966*
+ ID_OUI_FROM_DATABASE=PCM Industries
+
+OUI:0050C2967*
+ ID_OUI_FROM_DATABASE=Watthour Engineering Co., Inc.
+
+OUI:0050C2968*
+ ID_OUI_FROM_DATABASE=BuLogics, Inc.
+
+OUI:0050C2969*
+ ID_OUI_FROM_DATABASE=Gehrke Kommunikationssysteme GmbH
+
+OUI:0050C296A*
+ ID_OUI_FROM_DATABASE=Elektrobit Wireless Communications Ltd
+
+OUI:0050C296B*
+ ID_OUI_FROM_DATABASE=Electronic Media Services Ltd
+
+OUI:0050C296C*
+ ID_OUI_FROM_DATABASE=Aqua Cooler Pty Ltd
+
+OUI:0050C296D*
+ ID_OUI_FROM_DATABASE=Keene Electronics Ltd.
+
+OUI:0050C296E*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corporation
+
+OUI:0050C296F*
+ ID_OUI_FROM_DATABASE=Varec Inc.
+
+OUI:0050C2970*
+ ID_OUI_FROM_DATABASE=Tsuji Electronics Co.,Ltd
+
+OUI:0050C2971*
+ ID_OUI_FROM_DATABASE=Ipitek
+
+OUI:0050C2972*
+ ID_OUI_FROM_DATABASE=Switch Science (Panini Keikaku)
+
+OUI:0050C2973*
+ ID_OUI_FROM_DATABASE=Systèmes Pran
+
+OUI:0050C2974*
+ ID_OUI_FROM_DATABASE=EMAC, INC.
+
+OUI:0050C2975*
+ ID_OUI_FROM_DATABASE=Pyramid Technical Consultants
+
+OUI:0050C2976*
+ ID_OUI_FROM_DATABASE=SANDS INSTRUMENTATION INDIA PVT LTD
+
+OUI:0050C2977*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2978*
+ ID_OUI_FROM_DATABASE=LOGITAL DIGITAL MEDIA srl
+
+OUI:0050C2979*
+ ID_OUI_FROM_DATABASE=Far South Networks (Pty) Ltd
+
+OUI:0050C297A*
+ ID_OUI_FROM_DATABASE=KST Technology Co., Ltd
+
+OUI:0050C297B*
+ ID_OUI_FROM_DATABASE=SMARTQUANTUM SA
+
+OUI:0050C297C*
+ ID_OUI_FROM_DATABASE=Creacon Technologies B.V.
+
+OUI:0050C297D*
+ ID_OUI_FROM_DATABASE=Soehnle Professional GmbH & Co.KG
+
+OUI:0050C297E*
+ ID_OUI_FROM_DATABASE=Long Distance Technologies
+
+OUI:0050C297F*
+ ID_OUI_FROM_DATABASE=C&I  Co.Ltd
+
+OUI:0050C2980*
+ ID_OUI_FROM_DATABASE=Digital Payment Technologies
+
+OUI:0050C2981*
+ ID_OUI_FROM_DATABASE=Novotronik GmbH
+
+OUI:0050C2982*
+ ID_OUI_FROM_DATABASE=Triple Ring Technologies, Inc.
+
+OUI:0050C2983*
+ ID_OUI_FROM_DATABASE=Bogart Engineering
+
+OUI:0050C2984*
+ ID_OUI_FROM_DATABASE=Atel Corporation
+
+OUI:0050C2985*
+ ID_OUI_FROM_DATABASE=Earnestcom Sdn Bhd
+
+OUI:0050C2986*
+ ID_OUI_FROM_DATABASE=DSCI
+
+OUI:0050C2987*
+ ID_OUI_FROM_DATABASE=Joinsoon Electronics MFG. Co., Ltd
+
+OUI:0050C2988*
+ ID_OUI_FROM_DATABASE=Pantel International
+
+OUI:0050C2989*
+ ID_OUI_FROM_DATABASE=Psigenics Corporation
+
+OUI:0050C298A*
+ ID_OUI_FROM_DATABASE=MEV Limited
+
+OUI:0050C298B*
+ ID_OUI_FROM_DATABASE=TI2000 TECNOLOGIA INFORMATICA 2000
+
+OUI:0050C298C*
+ ID_OUI_FROM_DATABASE=MGM-Devices Oy
+
+OUI:0050C298D*
+ ID_OUI_FROM_DATABASE=Mecos Traxler AG
+
+OUI:0050C298E*
+ ID_OUI_FROM_DATABASE=Link Technologies, Inc
+
+OUI:0050C298F*
+ ID_OUI_FROM_DATABASE=BELIK S.P.R.L.
+
+OUI:0050C2990*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2991*
+ ID_OUI_FROM_DATABASE=UGL Limited
+
+OUI:0050C2992*
+ ID_OUI_FROM_DATABASE=IDT Sound Processing Corporation
+
+OUI:0050C2993*
+ ID_OUI_FROM_DATABASE=UNETCONVERGENCE CO., LTD
+
+OUI:0050C2994*
+ ID_OUI_FROM_DATABASE=Xafax Nederland bv
+
+OUI:0050C2995*
+ ID_OUI_FROM_DATABASE=Inter Control Hermann Köhler  Elektrik GmbH&Co.KG
+
+OUI:0050C2996*
+ ID_OUI_FROM_DATABASE=Commercial Timesharing Inc.
+
+OUI:0050C2997*
+ ID_OUI_FROM_DATABASE=Depro Électronique
+
+OUI:0050C2998*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2999*
+ ID_OUI_FROM_DATABASE=Cambustion Ltd
+
+OUI:0050C299A*
+ ID_OUI_FROM_DATABASE=Miromico AG
+
+OUI:0050C299B*
+ ID_OUI_FROM_DATABASE=Bettini srl
+
+OUI:0050C299C*
+ ID_OUI_FROM_DATABASE=CaTs3 Limited
+
+OUI:0050C299D*
+ ID_OUI_FROM_DATABASE=Powersense A/S
+
+OUI:0050C299E*
+ ID_OUI_FROM_DATABASE=Engage Technologies
+
+OUI:0050C299F*
+ ID_OUI_FROM_DATABASE=Sietron Elektronik
+
+OUI:0050C29A0*
+ ID_OUI_FROM_DATABASE=Trs Systems, Inc.
+
+OUI:0050C29A1*
+ ID_OUI_FROM_DATABASE=ComAp s.r.o
+
+OUI:0050C29A2*
+ ID_OUI_FROM_DATABASE=SAMsystems GmbH
+
+OUI:0050C29A3*
+ ID_OUI_FROM_DATABASE=Computerwise, Inc.
+
+OUI:0050C29A4*
+ ID_OUI_FROM_DATABASE=Entwicklung Hard- & Software
+
+OUI:0050C29A5*
+ ID_OUI_FROM_DATABASE=Conolog Corporation
+
+OUI:0050C29A6*
+ ID_OUI_FROM_DATABASE=Metodo2
+
+OUI:0050C29A7*
+ ID_OUI_FROM_DATABASE=Thales Communications France
+
+OUI:0050C29A8*
+ ID_OUI_FROM_DATABASE=DOMIS SA
+
+OUI:0050C29A9*
+ ID_OUI_FROM_DATABASE=General Dynamics C4 Systems
+
+OUI:0050C29AA*
+ ID_OUI_FROM_DATABASE=TEKO TELECOM SpA
+
+OUI:0050C29AB*
+ ID_OUI_FROM_DATABASE=Electrodata Inc.
+
+OUI:0050C29AC*
+ ID_OUI_FROM_DATABASE=Questek Australia Pty Ltd
+
+OUI:0050C29AD*
+ ID_OUI_FROM_DATABASE=Chronos Technology Ltd.
+
+OUI:0050C29AE*
+ ID_OUI_FROM_DATABASE=Esensors, Inc.
+
+OUI:0050C29AF*
+ ID_OUI_FROM_DATABASE=KRESS-NET Krzysztof Rutecki
+
+OUI:0050C29B0*
+ ID_OUI_FROM_DATABASE=Ebru GmbH
+
+OUI:0050C29B1*
+ ID_OUI_FROM_DATABASE=Bon Hora GmbH
+
+OUI:0050C29B2*
+ ID_OUI_FROM_DATABASE=TempSys
+
+OUI:0050C29B3*
+ ID_OUI_FROM_DATABASE=Kahler Automation
+
+OUI:0050C29B4*
+ ID_OUI_FROM_DATABASE=EUKREA ELECTROMATIQUE SARL
+
+OUI:0050C29B5*
+ ID_OUI_FROM_DATABASE=Telegamma srl
+
+OUI:0050C29B6*
+ ID_OUI_FROM_DATABASE=ACTECH
+
+OUI:0050C29B7*
+ ID_OUI_FROM_DATABASE=St. Michael Strategies
+
+OUI:0050C29B8*
+ ID_OUI_FROM_DATABASE=Sound Player Systems e.K.
+
+OUI:0050C29B9*
+ ID_OUI_FROM_DATABASE=ISA - Intelligent Sensing Anywhere, S.A.
+
+OUI:0050C29BA*
+ ID_OUI_FROM_DATABASE=Connor-Winfield
+
+OUI:0050C29BB*
+ ID_OUI_FROM_DATABASE=OMICRON electronics GmbH
+
+OUI:0050C29BC*
+ ID_OUI_FROM_DATABASE=Vester Elektronik GmbH
+
+OUI:0050C29BD*
+ ID_OUI_FROM_DATABASE=Sensitron Semiconductor
+
+OUI:0050C29BE*
+ ID_OUI_FROM_DATABASE=Xad Communications Ltd
+
+OUI:0050C29BF*
+ ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s.
+
+OUI:0050C29C0*
+ ID_OUI_FROM_DATABASE=Stuyts Engineering Haarlem BV
+
+OUI:0050C29C1*
+ ID_OUI_FROM_DATABASE=Tattile srl
+
+OUI:0050C29C2*
+ ID_OUI_FROM_DATABASE=Team Enginers
+
+OUI:0050C29C3*
+ ID_OUI_FROM_DATABASE=GE Security-Kampro
+
+OUI:0050C29C4*
+ ID_OUI_FROM_DATABASE=Vitel Net
+
+OUI:0050C29C5*
+ ID_OUI_FROM_DATABASE=Scansonic MI GmbH
+
+OUI:0050C29C6*
+ ID_OUI_FROM_DATABASE=Protronic GmbH
+
+OUI:0050C29C7*
+ ID_OUI_FROM_DATABASE=Kumera Drives Oy
+
+OUI:0050C29C8*
+ ID_OUI_FROM_DATABASE=ethermetrics
+
+OUI:0050C29C9*
+ ID_OUI_FROM_DATABASE=LUMINEX Lighting Control Equipment
+
+OUI:0050C29CA*
+ ID_OUI_FROM_DATABASE=ESAB-ATAS GmbH
+
+OUI:0050C29CB*
+ ID_OUI_FROM_DATABASE=NIS-time GmbH
+
+OUI:0050C29CC*
+ ID_OUI_FROM_DATABASE=Hirotech, Inc
+
+OUI:0050C29CD*
+ ID_OUI_FROM_DATABASE=Uwe Schneider GmbH
+
+OUI:0050C29CE*
+ ID_OUI_FROM_DATABASE=Ronan Engineering
+
+OUI:0050C29CF*
+ ID_OUI_FROM_DATABASE=Intuitive Surgical, Inc
+
+OUI:0050C29D0*
+ ID_OUI_FROM_DATABASE=J. DITTRICH ELEKTRONIC GmbH & Co. KG
+
+OUI:0050C29D1*
+ ID_OUI_FROM_DATABASE=Bladelius Design Group AB
+
+OUI:0050C29D2*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C29D3*
+ ID_OUI_FROM_DATABASE=Telemetrie Elektronik GmbH
+
+OUI:0050C29D4*
+ ID_OUI_FROM_DATABASE=FIRST
+
+OUI:0050C29D5*
+ ID_OUI_FROM_DATABASE=Netpower Labs AB
+
+OUI:0050C29D6*
+ ID_OUI_FROM_DATABASE=Innovation, Institute, Inc
+
+OUI:0050C29D7*
+ ID_OUI_FROM_DATABASE=Melex Inc.
+
+OUI:0050C29D8*
+ ID_OUI_FROM_DATABASE=SAMSUNG HEAVY INDUSTRIES CO.,LTD.
+
+OUI:0050C29D9*
+ ID_OUI_FROM_DATABASE=CNS Systems, Inc.
+
+OUI:0050C29DA*
+ ID_OUI_FROM_DATABASE=NEUTRONIK e.K.
+
+OUI:0050C29DB*
+ ID_OUI_FROM_DATABASE=Walter Grotkasten
+
+OUI:0050C29DC*
+ ID_OUI_FROM_DATABASE=FTM Marketing Limited
+
+OUI:0050C29DD*
+ ID_OUI_FROM_DATABASE=Institut Dr. Foerster
+
+OUI:0050C29DE*
+ ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX
+
+OUI:0050C29DF*
+ ID_OUI_FROM_DATABASE=CODEC Co., Ltd.
+
+OUI:0050C29E0*
+ ID_OUI_FROM_DATABASE=DST Swiss AG
+
+OUI:0050C29E1*
+ ID_OUI_FROM_DATABASE=Enreduce Energy Control AB
+
+OUI:0050C29E2*
+ ID_OUI_FROM_DATABASE=E-ViEWS SAFETY SYSTEMS, INC
+
+OUI:0050C29E3*
+ ID_OUI_FROM_DATABASE=beON Automatenmanagement GmbH
+
+OUI:0050C29E4*
+ ID_OUI_FROM_DATABASE=Pyxis Controls WLL
+
+OUI:0050C29E5*
+ ID_OUI_FROM_DATABASE=Halliburton Far East Pte Ltd
+
+OUI:0050C29E6*
+ ID_OUI_FROM_DATABASE=Kumho Electric, Inc.
+
+OUI:0050C29E7*
+ ID_OUI_FROM_DATABASE=DORLET S.A.
+
+OUI:0050C29E8*
+ ID_OUI_FROM_DATABASE=Hammock Corporation
+
+OUI:0050C29E9*
+ ID_OUI_FROM_DATABASE=Ciemme Sistemi Spa
+
+OUI:0050C29EA*
+ ID_OUI_FROM_DATABASE=SISMODULAR - Engenharia, Lda
+
+OUI:0050C29EB*
+ ID_OUI_FROM_DATABASE=AFORE Solutions Inc.
+
+OUI:0050C29EC*
+ ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA
+
+OUI:0050C29ED*
+ ID_OUI_FROM_DATABASE=Picell B.V.
+
+OUI:0050C29EE*
+ ID_OUI_FROM_DATABASE=Michael Stevens & Partners Ltd
+
+OUI:0050C29EF*
+ ID_OUI_FROM_DATABASE=WoKa-Elektronik GmbH
+
+OUI:0050C29F0*
+ ID_OUI_FROM_DATABASE=Veracity UK Ltd
+
+OUI:0050C29F1*
+ ID_OUI_FROM_DATABASE=IDEAS s.r.l.
+
+OUI:0050C29F2*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C29F3*
+ ID_OUI_FROM_DATABASE=Vision Technologies, Inc.
+
+OUI:0050C29F4*
+ ID_OUI_FROM_DATABASE=FSR Inc.
+
+OUI:0050C29F5*
+ ID_OUI_FROM_DATABASE=Commex Technologies
+
+OUI:0050C29F6*
+ ID_OUI_FROM_DATABASE=Ion Sense Inc.
+
+OUI:0050C29F7*
+ ID_OUI_FROM_DATABASE=Dave Jones Design
+
+OUI:0050C29F8*
+ ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd
+
+OUI:0050C29F9*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China)
+
+OUI:0050C29FA*
+ ID_OUI_FROM_DATABASE=Teranex A Division of Silicon Optix
+
+OUI:0050C29FB*
+ ID_OUI_FROM_DATABASE=Villbau Kft.
+
+OUI:0050C29FC*
+ ID_OUI_FROM_DATABASE=ECTEC INC.
+
+OUI:0050C29FD*
+ ID_OUI_FROM_DATABASE=Bitt technology-A Ltd.
+
+OUI:0050C29FE*
+ ID_OUI_FROM_DATABASE=SPECTRA EMBEDDED SYSTEMS
+
+OUI:0050C29FF*
+ ID_OUI_FROM_DATABASE=Humphrey Products
+
+OUI:0050C2A00*
+ ID_OUI_FROM_DATABASE=Technovare Systems
+
+OUI:0050C2A01*
+ ID_OUI_FROM_DATABASE=Patronics International LTD
+
+OUI:0050C2A02*
+ ID_OUI_FROM_DATABASE=Reference, LLC.
+
+OUI:0050C2A03*
+ ID_OUI_FROM_DATABASE=EEG Enterprises Inc
+
+OUI:0050C2A04*
+ ID_OUI_FROM_DATABASE=TP Radio
+
+OUI:0050C2A05*
+ ID_OUI_FROM_DATABASE=Adgil Design Inc.
+
+OUI:0050C2A06*
+ ID_OUI_FROM_DATABASE=Cloos Schweisstechnik GmbH
+
+OUI:0050C2A07*
+ ID_OUI_FROM_DATABASE=Dynon Instruments
+
+OUI:0050C2A08*
+ ID_OUI_FROM_DATABASE=LabJack Corporation
+
+OUI:0050C2A09*
+ ID_OUI_FROM_DATABASE=Innovative American Technology
+
+OUI:0050C2A0A*
+ ID_OUI_FROM_DATABASE=ACD Elektronik Gmbh
+
+OUI:0050C2A0B*
+ ID_OUI_FROM_DATABASE=I.D.S. Ingegneria Dei Sistemi  S.p.A.
+
+OUI:0050C2A0C*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2A0D*
+ ID_OUI_FROM_DATABASE=CHARLYROBOT
+
+OUI:0050C2A0E*
+ ID_OUI_FROM_DATABASE=Engicam srl
+
+OUI:0050C2A0F*
+ ID_OUI_FROM_DATABASE=Visualware Inc
+
+OUI:0050C2A10*
+ ID_OUI_FROM_DATABASE=Essential Design & Integration P/L
+
+OUI:0050C2A11*
+ ID_OUI_FROM_DATABASE=OJSC Rawenstvo
+
+OUI:0050C2A12*
+ ID_OUI_FROM_DATABASE=HCE Engineering S.r.l.
+
+OUI:0050C2A13*
+ ID_OUI_FROM_DATABASE=Talyst, Inc.
+
+OUI:0050C2A14*
+ ID_OUI_FROM_DATABASE=Elbit Systems of America - Tallahassee Operations
+
+OUI:0050C2A15*
+ ID_OUI_FROM_DATABASE=Industrial Computing Ltd
+
+OUI:0050C2A16*
+ ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH
+
+OUI:0050C2A17*
+ ID_OUI_FROM_DATABASE=Winners Satellite Electronics Corp.
+
+OUI:0050C2A18*
+ ID_OUI_FROM_DATABASE=Eoslink
+
+OUI:0050C2A19*
+ ID_OUI_FROM_DATABASE=Icon Time Systems
+
+OUI:0050C2A1A*
+ ID_OUI_FROM_DATABASE=DDL
+
+OUI:0050C2A1B*
+ ID_OUI_FROM_DATABASE=Realtime Systems Ltd.
+
+OUI:0050C2A1C*
+ ID_OUI_FROM_DATABASE=Microtechnica
+
+OUI:0050C2A1D*
+ ID_OUI_FROM_DATABASE=SAMH Engineering Services
+
+OUI:0050C2A1E*
+ ID_OUI_FROM_DATABASE=MAMAC Systems, Inc.
+
+OUI:0050C2A1F*
+ ID_OUI_FROM_DATABASE=Flight Data Systems Pty Ltd
+
+OUI:0050C2A20*
+ ID_OUI_FROM_DATABASE=Quorum Technologies Ltd
+
+OUI:0050C2A21*
+ ID_OUI_FROM_DATABASE=ISAC SRL
+
+OUI:0050C2A22*
+ ID_OUI_FROM_DATABASE=Nippon Manufacturing Service Corporation (abbreviated as 'nms')
+
+OUI:0050C2A23*
+ ID_OUI_FROM_DATABASE=Agility Mfg, Inc.
+
+OUI:0050C2A24*
+ ID_OUI_FROM_DATABASE=GRUPO EPELSA s.l.
+
+OUI:0050C2A25*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2A26*
+ ID_OUI_FROM_DATABASE=Preferred Oil, LLC
+
+OUI:0050C2A27*
+ ID_OUI_FROM_DATABASE=meconet e. K.
+
+OUI:0050C2A28*
+ ID_OUI_FROM_DATABASE=KENDA ELECTRONIC SYSTEMS LIMITED
+
+OUI:0050C2A29*
+ ID_OUI_FROM_DATABASE=Luminex Corporation
+
+OUI:0050C2A2A*
+ ID_OUI_FROM_DATABASE=Custom Control Concepts
+
+OUI:0050C2A2B*
+ ID_OUI_FROM_DATABASE=APRILIA RACING S.R.L.
+
+OUI:0050C2A2C*
+ ID_OUI_FROM_DATABASE=KWS-Electronic GmbH
+
+OUI:0050C2A2D*
+ ID_OUI_FROM_DATABASE=Inventure Inc.
+
+OUI:0050C2A2E*
+ ID_OUI_FROM_DATABASE=Yuyama Mfg. Co., Ltd.
+
+OUI:0050C2A2F*
+ ID_OUI_FROM_DATABASE=DragonFly Scientific LLC
+
+OUI:0050C2A30*
+ ID_OUI_FROM_DATABASE=D-TA Systems
+
+OUI:0050C2A31*
+ ID_OUI_FROM_DATABASE=Coolit Systems, Inc.
+
+OUI:0050C2A32*
+ ID_OUI_FROM_DATABASE=Harris Designs of NRV, Inc.
+
+OUI:0050C2A33*
+ ID_OUI_FROM_DATABASE=Fuji Firmware
+
+OUI:0050C2A34*
+ ID_OUI_FROM_DATABASE=Casabyte Inc.
+
+OUI:0050C2A35*
+ ID_OUI_FROM_DATABASE=Appareo Systems, LLC
+
+OUI:0050C2A36*
+ ID_OUI_FROM_DATABASE=Shenzhen Shangji electronic Co.Ltd
+
+OUI:0050C2A37*
+ ID_OUI_FROM_DATABASE=Software Systems Plus
+
+OUI:0050C2A38*
+ ID_OUI_FROM_DATABASE=Tred Displays
+
+OUI:0050C2A39*
+ ID_OUI_FROM_DATABASE=Industrial Data Products Ltd
+
+OUI:0050C2A3A*
+ ID_OUI_FROM_DATABASE=Telecor Inc.
+
+OUI:0050C2A3B*
+ ID_OUI_FROM_DATABASE=IPcontrols GmbH
+
+OUI:0050C2A3C*
+ ID_OUI_FROM_DATABASE=Brähler ICS Konferenztechnik AG
+
+OUI:0050C2A3D*
+ ID_OUI_FROM_DATABASE=OWANDY
+
+OUI:0050C2A3E*
+ ID_OUI_FROM_DATABASE=DUEVI SNC DI MORA E SANTESE
+
+OUI:0050C2A3F*
+ ID_OUI_FROM_DATABASE=LHA Systems CC
+
+OUI:0050C2A40*
+ ID_OUI_FROM_DATABASE=Mosberger Consulting LLC
+
+OUI:0050C2A41*
+ ID_OUI_FROM_DATABASE=Meiryo Denshi Corp.
+
+OUI:0050C2A42*
+ ID_OUI_FROM_DATABASE=RealVision Inc.
+
+OUI:0050C2A43*
+ ID_OUI_FROM_DATABASE=NKS Co.Ltd.
+
+OUI:0050C2A44*
+ ID_OUI_FROM_DATABASE=TORC Technologies
+
+OUI:0050C2A45*
+ ID_OUI_FROM_DATABASE=Sofradir-EC
+
+OUI:0050C2A46*
+ ID_OUI_FROM_DATABASE=Softronics Ltd.
+
+OUI:0050C2A47*
+ ID_OUI_FROM_DATABASE=PRIMETECH ENGINEERING CORP.
+
+OUI:0050C2A48*
+ ID_OUI_FROM_DATABASE=Thales Optronics Limited
+
+OUI:0050C2A49*
+ ID_OUI_FROM_DATABASE=Wayne Dalton Corp.
+
+OUI:0050C2A4A*
+ ID_OUI_FROM_DATABASE=DITRON S.r.l.
+
+OUI:0050C2A4B*
+ ID_OUI_FROM_DATABASE=L-3 Communications Mobile-Vision, Inc.
+
+OUI:0050C2A4C*
+ ID_OUI_FROM_DATABASE=VasoNova, Inc.
+
+OUI:0050C2A4D*
+ ID_OUI_FROM_DATABASE=LevelStar LLC.
+
+OUI:0050C2A4E*
+ ID_OUI_FROM_DATABASE=Conduant Corporation
+
+OUI:0050C2A4F*
+ ID_OUI_FROM_DATABASE=Deuta GmbH
+
+OUI:0050C2A50*
+ ID_OUI_FROM_DATABASE=i-RED Infrarot Systeme GmbH
+
+OUI:0050C2A51*
+ ID_OUI_FROM_DATABASE=Y-products co.ltd.
+
+OUI:0050C2A52*
+ ID_OUI_FROM_DATABASE=The VON Corporation
+
+OUI:0050C2A53*
+ ID_OUI_FROM_DATABASE=Quality & Design
+
+OUI:0050C2A54*
+ ID_OUI_FROM_DATABASE=Diamond Point International (Europe) Ltd
+
+OUI:0050C2A55*
+ ID_OUI_FROM_DATABASE=Arrowvale Electronics
+
+OUI:0050C2A56*
+ ID_OUI_FROM_DATABASE=ReaMetrix, Inc.
+
+OUI:0050C2A57*
+ ID_OUI_FROM_DATABASE=Juice Technologies, LLC
+
+OUI:0050C2A58*
+ ID_OUI_FROM_DATABASE=EPL
+
+OUI:0050C2A59*
+ ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH
+
+OUI:0050C2A5A*
+ ID_OUI_FROM_DATABASE=ITAS A/S
+
+OUI:0050C2A5B*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2A5C*
+ ID_OUI_FROM_DATABASE=JSC "Component-ASU"
+
+OUI:0050C2A5D*
+ ID_OUI_FROM_DATABASE=MECC CO., LTD.
+
+OUI:0050C2A5E*
+ ID_OUI_FROM_DATABASE=Ansen Investment Holdings Ltd.
+
+OUI:0050C2A5F*
+ ID_OUI_FROM_DATABASE=Alga Microwave Inc
+
+OUI:0050C2A60*
+ ID_OUI_FROM_DATABASE=Arrow Central Europe GmbH - Division Spoerle
+
+OUI:0050C2A61*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C2A62*
+ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
+
+OUI:0050C2A63*
+ ID_OUI_FROM_DATABASE=EMS Industries
+
+OUI:0050C2A64*
+ ID_OUI_FROM_DATABASE=tetronik GmbH AEN
+
+OUI:0050C2A65*
+ ID_OUI_FROM_DATABASE=Mark-O-Print GmbH
+
+OUI:0050C2A66*
+ ID_OUI_FROM_DATABASE=DVTech
+
+OUI:0050C2A67*
+ ID_OUI_FROM_DATABASE=GSS Avionics Limited
+
+OUI:0050C2A68*
+ ID_OUI_FROM_DATABASE=X-Pert Paint Mixing Systems
+
+OUI:0050C2A69*
+ ID_OUI_FROM_DATABASE=Advanced Integrated Systems
+
+OUI:0050C2A6A*
+ ID_OUI_FROM_DATABASE=Infocrossing
+
+OUI:0050C2A6B*
+ ID_OUI_FROM_DATABASE=Explorer Inc.
+
+OUI:0050C2A6C*
+ ID_OUI_FROM_DATABASE=Figment Design Laboratories
+
+OUI:0050C2A6D*
+ ID_OUI_FROM_DATABASE=DTV Innovations
+
+OUI:0050C2A6E*
+ ID_OUI_FROM_DATABASE=Screen Technics Pty Limited
+
+OUI:0050C2A6F*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2A70*
+ ID_OUI_FROM_DATABASE=Reliable System Services Corp
+
+OUI:0050C2A71*
+ ID_OUI_FROM_DATABASE=Purite Ltd
+
+OUI:0050C2A72*
+ ID_OUI_FROM_DATABASE=Gamber-Johnson LLC.
+
+OUI:0050C2A73*
+ ID_OUI_FROM_DATABASE=KYOEI ENGINEERING Co.,Ltd.
+
+OUI:0050C2A74*
+ ID_OUI_FROM_DATABASE=DSP DESIGN LTD
+
+OUI:0050C2A75*
+ ID_OUI_FROM_DATABASE=JTL Systems Ltd.
+
+OUI:0050C2A76*
+ ID_OUI_FROM_DATABASE=Roesch & Walter Industrie-Elektronik GmbH
+
+OUI:0050C2A77*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2A78*
+ ID_OUI_FROM_DATABASE=Apantac LLC
+
+OUI:0050C2A79*
+ ID_OUI_FROM_DATABASE=Saintronic
+
+OUI:0050C2A7A*
+ ID_OUI_FROM_DATABASE=DetNet South Africa PTY (LTD)
+
+OUI:0050C2A7B*
+ ID_OUI_FROM_DATABASE=Orange Tree Technologies
+
+OUI:0050C2A7C*
+ ID_OUI_FROM_DATABASE=Pneu-Logic Corporation
+
+OUI:0050C2A7D*
+ ID_OUI_FROM_DATABASE=Vitel Net
+
+OUI:0050C2A7E*
+ ID_OUI_FROM_DATABASE=Independent Project Engineering Ltd
+
+OUI:0050C2A7F*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2A80*
+ ID_OUI_FROM_DATABASE=ARD SA
+
+OUI:0050C2A81*
+ ID_OUI_FROM_DATABASE=BPC circuits Ltd
+
+OUI:0050C2A82*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2A83*
+ ID_OUI_FROM_DATABASE=Techno Sobi Co. Ltd.
+
+OUI:0050C2A84*
+ ID_OUI_FROM_DATABASE=Lino Manfrotto +Co spa
+
+OUI:0050C2A85*
+ ID_OUI_FROM_DATABASE=JOYSYSTEM
+
+OUI:0050C2A86*
+ ID_OUI_FROM_DATABASE=LIMAB AB
+
+OUI:0050C2A87*
+ ID_OUI_FROM_DATABASE=Littlemore Scientific
+
+OUI:0050C2A88*
+ ID_OUI_FROM_DATABASE=S-SYS
+
+OUI:0050C2A89*
+ ID_OUI_FROM_DATABASE=CA Traffic Ltd
+
+OUI:0050C2A8A*
+ ID_OUI_FROM_DATABASE=Audio Engineering Ltd.
+
+OUI:0050C2A8B*
+ ID_OUI_FROM_DATABASE=Navicron Oy
+
+OUI:0050C2A8C*
+ ID_OUI_FROM_DATABASE=Redwire, LLC
+
+OUI:0050C2A8D*
+ ID_OUI_FROM_DATABASE=Frontier Electronic Systems Corp.
+
+OUI:0050C2A8E*
+ ID_OUI_FROM_DATABASE=BFI Industrie-Elektronik GmbH & Co.KG
+
+OUI:0050C2A8F*
+ ID_OUI_FROM_DATABASE=Quantum3D, Inc.
+
+OUI:0050C2A90*
+ ID_OUI_FROM_DATABASE=S.two Corporation
+
+OUI:0050C2A91*
+ ID_OUI_FROM_DATABASE=Ceron Tech Co.,LTD
+
+OUI:0050C2A92*
+ ID_OUI_FROM_DATABASE=Sicon s.r.l.
+
+OUI:0050C2A93*
+ ID_OUI_FROM_DATABASE=SPX Dehydration & Filtration
+
+OUI:0050C2A94*
+ ID_OUI_FROM_DATABASE=Par-Tech, Inc.
+
+OUI:0050C2A95*
+ ID_OUI_FROM_DATABASE=INNOVACIONES Microelectrónicas SL (AnaFocus)
+
+OUI:0050C2A96*
+ ID_OUI_FROM_DATABASE=FEP SRL
+
+OUI:0050C2A97*
+ ID_OUI_FROM_DATABASE=MICROSYSTEMES
+
+OUI:0050C2A98*
+ ID_OUI_FROM_DATABASE=Sentry 360 Security
+
+OUI:0050C2A99*
+ ID_OUI_FROM_DATABASE=Haivision Systems Inc
+
+OUI:0050C2A9A*
+ ID_OUI_FROM_DATABASE=Absolutron. LLC
+
+OUI:0050C2A9B*
+ ID_OUI_FROM_DATABASE=PDQ Manufacturing  Inc.
+
+OUI:0050C2A9C*
+ ID_OUI_FROM_DATABASE=Eberspächer Electronics GmbH & Co. KG
+
+OUI:0050C2A9D*
+ ID_OUI_FROM_DATABASE=Joehl & Koeferli AG
+
+OUI:0050C2A9E*
+ ID_OUI_FROM_DATABASE=Procon Engineering Limited
+
+OUI:0050C2A9F*
+ ID_OUI_FROM_DATABASE=YellowSoft Co., Ltd.
+
+OUI:0050C2AA0*
+ ID_OUI_FROM_DATABASE=Smith Meter, Inc.
+
+OUI:0050C2AA1*
+ ID_OUI_FROM_DATABASE=ELREM ELECTRONIC AG
+
+OUI:0050C2AA2*
+ ID_OUI_FROM_DATABASE=ELPA sas
+
+OUI:0050C2AA3*
+ ID_OUI_FROM_DATABASE=Peek Traffic/US Traffic
+
+OUI:0050C2AA4*
+ ID_OUI_FROM_DATABASE=PSi Printer Systems international GmbH
+
+OUI:0050C2AA5*
+ ID_OUI_FROM_DATABASE=Tampere University of Technology
+
+OUI:0050C2AA6*
+ ID_OUI_FROM_DATABASE=Bassett Electronic Systems ltd
+
+OUI:0050C2AA7*
+ ID_OUI_FROM_DATABASE=Endeas Oy
+
+OUI:0050C2AA8*
+ ID_OUI_FROM_DATABASE=Nexans Cabling Solutions
+
+OUI:0050C2AA9*
+ ID_OUI_FROM_DATABASE=SAN GIORGIO S.E.I.N. srl
+
+OUI:0050C2AAA*
+ ID_OUI_FROM_DATABASE=Flexible Picture Systems
+
+OUI:0050C2AAB*
+ ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos
+
+OUI:0050C2AAC*
+ ID_OUI_FROM_DATABASE=VisiCon GmbH
+
+OUI:0050C2AAD*
+ ID_OUI_FROM_DATABASE=Update Systems Inc.
+
+OUI:0050C2AAE*
+ ID_OUI_FROM_DATABASE=OUTLINE srl
+
+OUI:0050C2AAF*
+ ID_OUI_FROM_DATABASE=Santa Barbara Instrument Group
+
+OUI:0050C2AB0*
+ ID_OUI_FROM_DATABASE=FRAKO Kondensatoren- und Anlagenbau GmbH
+
+OUI:0050C2AB1*
+ ID_OUI_FROM_DATABASE=Bitmanufaktur GmbH
+
+OUI:0050C2AB2*
+ ID_OUI_FROM_DATABASE=ProCom Systems, Inc.
+
+OUI:0050C2AB3*
+ ID_OUI_FROM_DATABASE=Compañía de Instrumentacion y control, S.L.
+
+OUI:0050C2AB4*
+ ID_OUI_FROM_DATABASE=n3k Informatik GmbH
+
+OUI:0050C2AB5*
+ ID_OUI_FROM_DATABASE=METTLER-TOLEDO HI-SPEED
+
+OUI:0050C2AB6*
+ ID_OUI_FROM_DATABASE=Gygax Embedded Engineering GEE.ch
+
+OUI:0050C2AB7*
+ ID_OUI_FROM_DATABASE=Twinfalls Technologies
+
+OUI:0050C2AB8*
+ ID_OUI_FROM_DATABASE=AHM Limited (CLiKAPAD)
+
+OUI:0050C2AB9*
+ ID_OUI_FROM_DATABASE=Showtacle
+
+OUI:0050C2ABA*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2ABB*
+ ID_OUI_FROM_DATABASE=Volantic AB
+
+OUI:0050C2ABC*
+ ID_OUI_FROM_DATABASE=Barrick
+
+OUI:0050C2ABD*
+ ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd.
+
+OUI:0050C2ABE*
+ ID_OUI_FROM_DATABASE=AP Labs
+
+OUI:0050C2ABF*
+ ID_OUI_FROM_DATABASE=MCC Computer Company
+
+OUI:0050C2AC0*
+ ID_OUI_FROM_DATABASE=DS PRO Audio Ltda
+
+OUI:0050C2AC1*
+ ID_OUI_FROM_DATABASE=DAISHIN-DENSHI Co., Ltd
+
+OUI:0050C2AC2*
+ ID_OUI_FROM_DATABASE=OpenXS B.V.
+
+OUI:0050C2AC3*
+ ID_OUI_FROM_DATABASE=Diversified Control, Inc.
+
+OUI:0050C2AC4*
+ ID_OUI_FROM_DATABASE=Orion Technologies, Inc.
+
+OUI:0050C2AC5*
+ ID_OUI_FROM_DATABASE=E-Motion System, Inc.
+
+OUI:0050C2AC6*
+ ID_OUI_FROM_DATABASE=Marathon Products, Inc.
+
+OUI:0050C2AC7*
+ ID_OUI_FROM_DATABASE=WaveIP
+
+OUI:0050C2AC8*
+ ID_OUI_FROM_DATABASE=Palladio Systeme GmbH
+
+OUI:0050C2AC9*
+ ID_OUI_FROM_DATABASE=Steinbeis-Transferzentrum Embedded Design und Networking
+
+OUI:0050C2ACA*
+ ID_OUI_FROM_DATABASE=Soft & Control Technology s.r.o.
+
+OUI:0050C2ACB*
+ ID_OUI_FROM_DATABASE=U-CARE INC.
+
+OUI:0050C2ACC*
+ ID_OUI_FROM_DATABASE=StockerYale
+
+OUI:0050C2ACD*
+ ID_OUI_FROM_DATABASE=MeshWorks Wireless Oy
+
+OUI:0050C2ACE*
+ ID_OUI_FROM_DATABASE=ChronoLogic Pty. Ltd.
+
+OUI:0050C2ACF*
+ ID_OUI_FROM_DATABASE=SP Controls, Inc
+
+OUI:0050C2AD0*
+ ID_OUI_FROM_DATABASE=Geonautics Australia Pty Ltd
+
+OUI:0050C2AD1*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2AD2*
+ ID_OUI_FROM_DATABASE=Rafael
+
+OUI:0050C2AD3*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corporation
+
+OUI:0050C2AD4*
+ ID_OUI_FROM_DATABASE=Global Rainmakers Inc.
+
+OUI:0050C2AD5*
+ ID_OUI_FROM_DATABASE=Mighty Lube Systematic Lubrication, Inc.
+
+OUI:0050C2AD6*
+ ID_OUI_FROM_DATABASE=Unisensor A/S
+
+OUI:0050C2AD7*
+ ID_OUI_FROM_DATABASE=Air Monitors Ltd
+
+OUI:0050C2AD8*
+ ID_OUI_FROM_DATABASE=Incyma
+
+OUI:0050C2AD9*
+ ID_OUI_FROM_DATABASE=elettrondata srl
+
+OUI:0050C2ADA*
+ ID_OUI_FROM_DATABASE=Essepie Srl
+
+OUI:0050C2ADB*
+ ID_OUI_FROM_DATABASE=GO engineering GmbH
+
+OUI:0050C2ADC*
+ ID_OUI_FROM_DATABASE=Synthesechemie Dr. Penth GmbH
+
+OUI:0050C2ADD*
+ ID_OUI_FROM_DATABASE=General Dynamics C4 Sysems
+
+OUI:0050C2ADE*
+ ID_OUI_FROM_DATABASE=Neoptix Inc.
+
+OUI:0050C2ADF*
+ ID_OUI_FROM_DATABASE=Altinex, Inc
+
+OUI:0050C2AE0*
+ ID_OUI_FROM_DATABASE=AT4 wireless.S.A
+
+OUI:0050C2AE1*
+ ID_OUI_FROM_DATABASE=EVERCARE
+
+OUI:0050C2AE2*
+ ID_OUI_FROM_DATABASE=Power Medical Interventions
+
+OUI:0050C2AE3*
+ ID_OUI_FROM_DATABASE=PSD
+
+OUI:0050C2AE4*
+ ID_OUI_FROM_DATABASE=Advanced Electronic Designs, Inc.
+
+OUI:0050C2AE5*
+ ID_OUI_FROM_DATABASE=ABS Gesellschaft f. Automatisierung, Bildverarbeitung und Software mbH
+
+OUI:0050C2AE6*
+ ID_OUI_FROM_DATABASE=VECOM USA
+
+OUI:0050C2AE7*
+ ID_OUI_FROM_DATABASE=Redwood Systems
+
+OUI:0050C2AE8*
+ ID_OUI_FROM_DATABASE=Bit-Lab PTY LTD
+
+OUI:0050C2AE9*
+ ID_OUI_FROM_DATABASE=ClearCorp Enterprises, Inc
+
+OUI:0050C2AEA*
+ ID_OUI_FROM_DATABASE=EMBEDIA
+
+OUI:0050C2AEB*
+ ID_OUI_FROM_DATABASE=UMLogics Corporation
+
+OUI:0050C2AEC*
+ ID_OUI_FROM_DATABASE=Fritz Pauker Ingenieure GmbH
+
+OUI:0050C2AED*
+ ID_OUI_FROM_DATABASE=3Roam
+
+OUI:0050C2AEE*
+ ID_OUI_FROM_DATABASE=IPtec, Inc.
+
+OUI:0050C2AEF*
+ ID_OUI_FROM_DATABASE=National CineMedia
+
+OUI:0050C2AF0*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C2AF1*
+ ID_OUI_FROM_DATABASE=Green Goose
+
+OUI:0050C2AF2*
+ ID_OUI_FROM_DATABASE=ACD Elektronik Gmbh
+
+OUI:0050C2AF3*
+ ID_OUI_FROM_DATABASE=Palomar Products, Inc.
+
+OUI:0050C2AF4*
+ ID_OUI_FROM_DATABASE=Dixell S.p.A.
+
+OUI:0050C2AF5*
+ ID_OUI_FROM_DATABASE=Kramara s.r.o.
+
+OUI:0050C2AF6*
+ ID_OUI_FROM_DATABASE=Energid
+
+OUI:0050C2AF7*
+ ID_OUI_FROM_DATABASE=Midwest Microwave Solutions Inc.
+
+OUI:0050C2AF8*
+ ID_OUI_FROM_DATABASE=Global Satellite Engineering
+
+OUI:0050C2AF9*
+ ID_OUI_FROM_DATABASE=Ingenieurbuero Bickele und Buehler GmbH
+
+OUI:0050C2AFA*
+ ID_OUI_FROM_DATABASE=Absolute Fire Solutions Inc.
+
+OUI:0050C2AFC*
+ ID_OUI_FROM_DATABASE=Odus Technologies SA
+
+OUI:0050C2AFD*
+ ID_OUI_FROM_DATABASE=HomeScenario, Inc.
+
+OUI:0050C2AFE*
+ ID_OUI_FROM_DATABASE=Trolex Limited
+
+OUI:0050C2AFF*
+ ID_OUI_FROM_DATABASE=XoByte LLC
+
+OUI:0050C2B00*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2B01*
+ ID_OUI_FROM_DATABASE=HSR Harald L. Reuter
+
+OUI:0050C2B02*
+ ID_OUI_FROM_DATABASE=MASTER CO LTD
+
+OUI:0050C2B03*
+ ID_OUI_FROM_DATABASE=Spider Tecnologia Ind. e Com. Ltda.
+
+OUI:0050C2B04*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:0050C2B05*
+ ID_OUI_FROM_DATABASE=POLA s.r.l.
+
+OUI:0050C2B06*
+ ID_OUI_FROM_DATABASE=CompuDesigns, Inc.
+
+OUI:0050C2B07*
+ ID_OUI_FROM_DATABASE=FARECO
+
+OUI:0050C2B08*
+ ID_OUI_FROM_DATABASE=Goerlitz AG
+
+OUI:0050C2B09*
+ ID_OUI_FROM_DATABASE=Harper Chalice Group Limited
+
+OUI:0050C2B0A*
+ ID_OUI_FROM_DATABASE=Indutherm Giesstechnologie GmbH
+
+OUI:0050C2B0B*
+ ID_OUI_FROM_DATABASE=Honeywell
+
+OUI:0050C2B0C*
+ ID_OUI_FROM_DATABASE=SMARTB TECHNOLOGIES
+
+OUI:0050C2B0D*
+ ID_OUI_FROM_DATABASE=Japan Electronics System, Inc
+
+OUI:0050C2B0E*
+ ID_OUI_FROM_DATABASE=KYAB Lulea AB
+
+OUI:0050C2B0F*
+ ID_OUI_FROM_DATABASE=NARA Controls Inc.
+
+OUI:0050C2B10*
+ ID_OUI_FROM_DATABASE=Marine Entertainment Systems Ltd
+
+OUI:0050C2B11*
+ ID_OUI_FROM_DATABASE=EXEL s.r.l
+
+OUI:0050C2B12*
+ ID_OUI_FROM_DATABASE=CM Elektronik GmbH
+
+OUI:0050C2B13*
+ ID_OUI_FROM_DATABASE=Measy Electronics Co., Ltd.
+
+OUI:0050C2B14*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2B15*
+ ID_OUI_FROM_DATABASE=PhotoTelesis LP
+
+OUI:0050C2B16*
+ ID_OUI_FROM_DATABASE=Neothings, Inc.
+
+OUI:0050C2B17*
+ ID_OUI_FROM_DATABASE=Elcoteq Design Center Oy
+
+OUI:0050C2B18*
+ ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited
+
+OUI:0050C2B19*
+ ID_OUI_FROM_DATABASE=Polytron Corporation
+
+OUI:0050C2B1A*
+ ID_OUI_FROM_DATABASE=ELCUS
+
+OUI:0050C2B1B*
+ ID_OUI_FROM_DATABASE=Integrated  Control Corp.
+
+OUI:0050C2B1C*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2B1D*
+ ID_OUI_FROM_DATABASE=Telegenix
+
+OUI:0050C2B1E*
+ ID_OUI_FROM_DATABASE=Abbott Medical Optics
+
+OUI:0050C2B1F*
+ ID_OUI_FROM_DATABASE=SCA Schucker GmbH & Co.
+
+OUI:0050C2B20*
+ ID_OUI_FROM_DATABASE=FIVE9 NETWORK SYSTEMS LLC
+
+OUI:0050C2B21*
+ ID_OUI_FROM_DATABASE=Phytron-Elektronik GmbH
+
+OUI:0050C2B22*
+ ID_OUI_FROM_DATABASE=FarSite Communications Limited
+
+OUI:0050C2B23*
+ ID_OUI_FROM_DATABASE=7 Marsyas Development a.s.
+
+OUI:0050C2B24*
+ ID_OUI_FROM_DATABASE=Teledyne Defence Limited
+
+OUI:0050C2B25*
+ ID_OUI_FROM_DATABASE=Triax A/S
+
+OUI:0050C2B26*
+ ID_OUI_FROM_DATABASE=Elko Systems
+
+OUI:0050C2B27*
+ ID_OUI_FROM_DATABASE=ATEME
+
+OUI:0050C2B28*
+ ID_OUI_FROM_DATABASE=Micromax Pty. Ltd.
+
+OUI:0050C2B29*
+ ID_OUI_FROM_DATABASE=Integra LifeSciences (Ireland) Ltd
+
+OUI:0050C2B2A*
+ ID_OUI_FROM_DATABASE=Trench Austria GmbH
+
+OUI:0050C2B2B*
+ ID_OUI_FROM_DATABASE=CosmoData Informatica Ltda.
+
+OUI:0050C2B2C*
+ ID_OUI_FROM_DATABASE=Concepteers, LLC
+
+OUI:0050C2B2D*
+ ID_OUI_FROM_DATABASE=Datasat Digital Entertainment
+
+OUI:0050C2B2E*
+ ID_OUI_FROM_DATABASE=ACT
+
+OUI:0050C2B2F*
+ ID_OUI_FROM_DATABASE=IntelliVision Technologies, Corp
+
+OUI:0050C2B30*
+ ID_OUI_FROM_DATABASE=Applied Micro Electronics "AME" BV
+
+OUI:0050C2B31*
+ ID_OUI_FROM_DATABASE=Shop Safe AG
+
+OUI:0050C2B32*
+ ID_OUI_FROM_DATABASE=Byres Security Inc
+
+OUI:0050C2B33*
+ ID_OUI_FROM_DATABASE=Numcore Ltd
+
+OUI:0050C2B34*
+ ID_OUI_FROM_DATABASE=Meisol co.,ltd
+
+OUI:0050C2B35*
+ ID_OUI_FROM_DATABASE=haneron
+
+OUI:0050C2B36*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:0050C2B37*
+ ID_OUI_FROM_DATABASE=IAdea Corporation
+
+OUI:0050C2B38*
+ ID_OUI_FROM_DATABASE=Grenmore Ltd
+
+OUI:0050C2B39*
+ ID_OUI_FROM_DATABASE=siXis, Inc.
+
+OUI:0050C2B3A*
+ ID_OUI_FROM_DATABASE=Nikon Systems Inc.
+
+OUI:0050C2B3B*
+ ID_OUI_FROM_DATABASE=Sportvision Inc.
+
+OUI:0050C2B3C*
+ ID_OUI_FROM_DATABASE=JanasCard
+
+OUI:0050C2B3D*
+ ID_OUI_FROM_DATABASE=AMS
+
+OUI:0050C2B3E*
+ ID_OUI_FROM_DATABASE=Sage Consultants
+
+OUI:0050C2B3F*
+ ID_OUI_FROM_DATABASE=M-Tronic Design and Technology GmbH
+
+OUI:0050C2B40*
+ ID_OUI_FROM_DATABASE=Tecnint HTE SRL
+
+OUI:0050C2B41*
+ ID_OUI_FROM_DATABASE=Tata Power Company, Strategic Electronics Division
+
+OUI:0050C2B42*
+ ID_OUI_FROM_DATABASE=ETM Electromatic Incorporated
+
+OUI:0050C2B43*
+ ID_OUI_FROM_DATABASE=J-Systems Inc.
+
+OUI:0050C2B44*
+ ID_OUI_FROM_DATABASE=Ampcontrol Pty Ltd
+
+OUI:0050C2B45*
+ ID_OUI_FROM_DATABASE=Efftronics Systems (P) Ltd
+
+OUI:0050C2B46*
+ ID_OUI_FROM_DATABASE=Mobileye
+
+OUI:0050C2B47*
+ ID_OUI_FROM_DATABASE=MCS MICRONIC Computer Systeme GmbH
+
+OUI:0050C2B48*
+ ID_OUI_FROM_DATABASE=MTD GmbH
+
+OUI:0050C2B49*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2B4A*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2B4B*
+ ID_OUI_FROM_DATABASE=Chitose Co.,Ltd
+
+OUI:0050C2B4C*
+ ID_OUI_FROM_DATABASE=ElectroCom
+
+OUI:0050C2B4D*
+ ID_OUI_FROM_DATABASE=Troll Systems Corporation
+
+OUI:0050C2B4E*
+ ID_OUI_FROM_DATABASE=AixControl GmbH
+
+OUI:0050C2B4F*
+ ID_OUI_FROM_DATABASE=Sencon UK Ltd.
+
+OUI:0050C2B50*
+ ID_OUI_FROM_DATABASE=SELCO
+
+OUI:0050C2B51*
+ ID_OUI_FROM_DATABASE=Aeroflex GmbH
+
+OUI:0050C2B52*
+ ID_OUI_FROM_DATABASE=SMH Technologies
+
+OUI:0050C2B53*
+ ID_OUI_FROM_DATABASE=Prodco
+
+OUI:0050C2B54*
+ ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC
+
+OUI:0050C2B55*
+ ID_OUI_FROM_DATABASE=SANYO ELECTRONIC INDUSTRIES CO.,LTD
+
+OUI:0050C2B56*
+ ID_OUI_FROM_DATABASE=SINOVIA SA
+
+OUI:0050C2B57*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2B58*
+ ID_OUI_FROM_DATABASE=Real D
+
+OUI:0050C2B59*
+ ID_OUI_FROM_DATABASE=SLICAN sp. z o.o.
+
+OUI:0050C2B5A*
+ ID_OUI_FROM_DATABASE=GREEN Center s.r.o.
+
+OUI:0050C2B5B*
+ ID_OUI_FROM_DATABASE=Timberline Mfg Company
+
+OUI:0050C2B5C*
+ ID_OUI_FROM_DATABASE=ADI Video Technologies
+
+OUI:0050C2B5D*
+ ID_OUI_FROM_DATABASE=Plitron Manufacturing Inc.
+
+OUI:0050C2B5E*
+ ID_OUI_FROM_DATABASE=Palgiken Co.,Ltd.
+
+OUI:0050C2B5F*
+ ID_OUI_FROM_DATABASE=North Bridge Technologies
+
+OUI:0050C2B60*
+ ID_OUI_FROM_DATABASE=OOO NPF ATIS
+
+OUI:0050C2B61*
+ ID_OUI_FROM_DATABASE=Nayos LTD
+
+OUI:0050C2B62*
+ ID_OUI_FROM_DATABASE=Measurement Technology NW
+
+OUI:0050C2B63*
+ ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A
+
+OUI:0050C2B64*
+ ID_OUI_FROM_DATABASE=FEW Bauer GmbH
+
+OUI:0050C2B65*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corporation
+
+OUI:0050C2B66*
+ ID_OUI_FROM_DATABASE=Deuta-Werke GmbH
+
+OUI:0050C2B67*
+ ID_OUI_FROM_DATABASE=RC Systems Co. Inc.
+
+OUI:0050C2B68*
+ ID_OUI_FROM_DATABASE=Electronic Systems Protection, Inc.
+
+OUI:0050C2B69*
+ ID_OUI_FROM_DATABASE=Thetis S.p.A.
+
+OUI:0050C2B6A*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2B6B*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2B6C*
+ ID_OUI_FROM_DATABASE=Drinelec
+
+OUI:0050C2B6D*
+ ID_OUI_FROM_DATABASE=Sound Metrics Corp
+
+OUI:0050C2B6F*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2B70*
+ ID_OUI_FROM_DATABASE=Nisshin Electronics co.,ltd.
+
+OUI:0050C2B71*
+ ID_OUI_FROM_DATABASE=Digitale Analoge COMponenten West Electronic Vertriebs GmbH
+
+OUI:0050C2B72*
+ ID_OUI_FROM_DATABASE=Advanced Desktop Systems Ltd
+
+OUI:0050C2B73*
+ ID_OUI_FROM_DATABASE=ARKRAY, Inc.
+
+OUI:0050C2B74*
+ ID_OUI_FROM_DATABASE=AXED Jakubowski Wojciechowski sp.j.
+
+OUI:0050C2B75*
+ ID_OUI_FROM_DATABASE=Blankom
+
+OUI:0050C2B76*
+ ID_OUI_FROM_DATABASE=ITF Fröschl GmbH
+
+OUI:0050C2B77*
+ ID_OUI_FROM_DATABASE=KRISTECH
+
+OUI:0050C2B78*
+ ID_OUI_FROM_DATABASE=Folink
+
+OUI:0050C2B79*
+ ID_OUI_FROM_DATABASE=MITSUYA LABORATORIES INC.
+
+OUI:0050C2B7A*
+ ID_OUI_FROM_DATABASE=Schnoor Industrieelektronik GmbH & Co. KG
+
+OUI:0050C2B7B*
+ ID_OUI_FROM_DATABASE=QUARTECH CORPORATION
+
+OUI:0050C2B7C*
+ ID_OUI_FROM_DATABASE=Bettini srl
+
+OUI:0050C2B7D*
+ ID_OUI_FROM_DATABASE=ELETECH Srl
+
+OUI:0050C2B7E*
+ ID_OUI_FROM_DATABASE=NARETRENDS
+
+OUI:0050C2B7F*
+ ID_OUI_FROM_DATABASE=Enatel
+
+OUI:0050C2B80*
+ ID_OUI_FROM_DATABASE=iScreen LLC
+
+OUI:0050C2B81*
+ ID_OUI_FROM_DATABASE=GHL GmbH & Co.KG
+
+OUI:0050C2B82*
+ ID_OUI_FROM_DATABASE=TANABIKI Inc.
+
+OUI:0050C2B83*
+ ID_OUI_FROM_DATABASE=Advanced Storage Concepts, Inc.
+
+OUI:0050C2B84*
+ ID_OUI_FROM_DATABASE=Innovate Software Solutions Pvt Ltd
+
+OUI:0050C2B85*
+ ID_OUI_FROM_DATABASE=SilverNet
+
+OUI:0050C2B86*
+ ID_OUI_FROM_DATABASE=ASTO
+
+OUI:0050C2B87*
+ ID_OUI_FROM_DATABASE=EMAC, Inc.
+
+OUI:0050C2B88*
+ ID_OUI_FROM_DATABASE=GIgatronik  Köln GmbH
+
+OUI:0050C2B89*
+ ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD.
+
+OUI:0050C2B8A*
+ ID_OUI_FROM_DATABASE=MicroPoise
+
+OUI:0050C2B8B*
+ ID_OUI_FROM_DATABASE=CSTI BV
+
+OUI:0050C2B8C*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2B8D*
+ ID_OUI_FROM_DATABASE=CEMSI
+
+OUI:0050C2B8E*
+ ID_OUI_FROM_DATABASE=WAC (Israel) Ltd.
+
+OUI:0050C2B8F*
+ ID_OUI_FROM_DATABASE=Gentec
+
+OUI:0050C2B90*
+ ID_OUI_FROM_DATABASE=NAONWORKS Co., Ltd
+
+OUI:0050C2B91*
+ ID_OUI_FROM_DATABASE=Finnet-Service Ltd.
+
+OUI:0050C2B92*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China)
+
+OUI:0050C2B93*
+ ID_OUI_FROM_DATABASE=EMC PARTNER AG
+
+OUI:0050C2B94*
+ ID_OUI_FROM_DATABASE=Tritech International Ltd
+
+OUI:0050C2B95*
+ ID_OUI_FROM_DATABASE=Rx Monitoring Services
+
+OUI:0050C2B96*
+ ID_OUI_FROM_DATABASE=Onix Electronic Systems Inc
+
+OUI:0050C2B97*
+ ID_OUI_FROM_DATABASE=ikerlan
+
+OUI:0050C2B98*
+ ID_OUI_FROM_DATABASE=Southwest Research Institute
+
+OUI:0050C2B99*
+ ID_OUI_FROM_DATABASE=Greenlight Innovation Corp.
+
+OUI:0050C2B9A*
+ ID_OUI_FROM_DATABASE=Talo, NV Inc
+
+OUI:0050C2B9B*
+ ID_OUI_FROM_DATABASE=Telventy Energia S.A.
+
+OUI:0050C2B9C*
+ ID_OUI_FROM_DATABASE=Dave srl
+
+OUI:0050C2B9D*
+ ID_OUI_FROM_DATABASE=W. Vershoven GmbH
+
+OUI:0050C2B9E*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2B9F*
+ ID_OUI_FROM_DATABASE=AUDIOSCOPE 2K SRL
+
+OUI:0050C2BA0*
+ ID_OUI_FROM_DATABASE=txtr GmbH
+
+OUI:0050C2BA1*
+ ID_OUI_FROM_DATABASE=Transtechnik GmbH & Co.KG
+
+OUI:0050C2BA2*
+ ID_OUI_FROM_DATABASE=Logical Tools s.r.l.
+
+OUI:0050C2BA3*
+ ID_OUI_FROM_DATABASE=DSP DESIGN LTD
+
+OUI:0050C2BA4*
+ ID_OUI_FROM_DATABASE=CUSTOS MOBILE S.L.
+
+OUI:0050C2BA5*
+ ID_OUI_FROM_DATABASE=InterCel Pty Ltd
+
+OUI:0050C2BA6*
+ ID_OUI_FROM_DATABASE=Jomitek
+
+OUI:0050C2BA7*
+ ID_OUI_FROM_DATABASE=RaumComputer Entwicklungs- und Vertriebs GmbH
+
+OUI:0050C2BA8*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corporation
+
+OUI:0050C2BA9*
+ ID_OUI_FROM_DATABASE=SISS Technology Inc.
+
+OUI:0050C2BAA*
+ ID_OUI_FROM_DATABASE=NetworkFX Communications, LLC
+
+OUI:0050C2BAB*
+ ID_OUI_FROM_DATABASE=iDeal Teknoloji Bilisim Cozumleri A.S.
+
+OUI:0050C2BAC*
+ ID_OUI_FROM_DATABASE=VITECO VNPT JSC
+
+OUI:0050C2BAD*
+ ID_OUI_FROM_DATABASE=Prediktor AS
+
+OUI:0050C2BAE*
+ ID_OUI_FROM_DATABASE=Fiber Connections Inc.
+
+OUI:0050C2BAF*
+ ID_OUI_FROM_DATABASE=MangoDSP
+
+OUI:0050C2BB0*
+ ID_OUI_FROM_DATABASE=Gainbrain
+
+OUI:0050C2BB1*
+ ID_OUI_FROM_DATABASE=Pro4tech
+
+OUI:0050C2BB2*
+ ID_OUI_FROM_DATABASE=St Michael Strategies Inc
+
+OUI:0050C2BB3*
+ ID_OUI_FROM_DATABASE=ClimateWell AB (publ)
+
+OUI:0050C2BB4*
+ ID_OUI_FROM_DATABASE=JSC Electrical Equipment Factory
+
+OUI:0050C2BB5*
+ ID_OUI_FROM_DATABASE=MROAD INFORMATION SYSTEM
+
+OUI:0050C2BB6*
+ ID_OUI_FROM_DATABASE=Quarch Technology Ltd
+
+OUI:0050C2BB7*
+ ID_OUI_FROM_DATABASE=General Dynamics C4 Systems
+
+OUI:0050C2BB8*
+ ID_OUI_FROM_DATABASE=MoeTronix
+
+OUI:0050C2BB9*
+ ID_OUI_FROM_DATABASE=Toptech Systems, Inc.
+
+OUI:0050C2BBA*
+ ID_OUI_FROM_DATABASE=Systemteq Limited
+
+OUI:0050C2BBB*
+ ID_OUI_FROM_DATABASE=GHL Systems Berhad
+
+OUI:0050C2BBC*
+ ID_OUI_FROM_DATABASE=ImpactSystems
+
+OUI:0050C2BBD*
+ ID_OUI_FROM_DATABASE=ITS Telecom
+
+OUI:0050C2BBE*
+ ID_OUI_FROM_DATABASE=Onlinepizza Norden AB
+
+OUI:0050C2BBF*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2BC0*
+ ID_OUI_FROM_DATABASE=Galaxia Electronics
+
+OUI:0050C2BC1*
+ ID_OUI_FROM_DATABASE=Sentec Ltd
+
+OUI:0050C2BC2*
+ ID_OUI_FROM_DATABASE=XSLENT Energy Technologies LLC
+
+OUI:0050C2BC3*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2BC4*
+ ID_OUI_FROM_DATABASE=Wheatstone Corporation
+
+OUI:0050C2BC5*
+ ID_OUI_FROM_DATABASE=Toptechnology SRL
+
+OUI:0050C2BC6*
+ ID_OUI_FROM_DATABASE=MireroTack
+
+OUI:0050C2BC7*
+ ID_OUI_FROM_DATABASE=PTS GmbH
+
+OUI:0050C2BC8*
+ ID_OUI_FROM_DATABASE=AGWTech Ltd
+
+OUI:0050C2BC9*
+ ID_OUI_FROM_DATABASE=Nextmove Technologies
+
+OUI:0050C2BCA*
+ ID_OUI_FROM_DATABASE=Aitecsystem Co.,Ltd.
+
+OUI:0050C2BCB*
+ ID_OUI_FROM_DATABASE=ARTEIXO TELECOM
+
+OUI:0050C2BCC*
+ ID_OUI_FROM_DATABASE=VVDN TECHNOLOGIES PVT. LTD.
+
+OUI:0050C2BCD*
+ ID_OUI_FROM_DATABASE=Highlight Parking Systems Ltd
+
+OUI:0050C2BCE*
+ ID_OUI_FROM_DATABASE=TV Portal Co., Ltd.
+
+OUI:0050C2BCF*
+ ID_OUI_FROM_DATABASE=Epiko, elektronski sistemi d.o.o.
+
+OUI:0050C2BD0*
+ ID_OUI_FROM_DATABASE=EDC wifi
+
+OUI:0050C2BD1*
+ ID_OUI_FROM_DATABASE=Ariem Technologies Pvt Ltd
+
+OUI:0050C2BD2*
+ ID_OUI_FROM_DATABASE=Percello Ltd.
+
+OUI:0050C2BD3*
+ ID_OUI_FROM_DATABASE=Postjet Systems Ltd
+
+OUI:0050C2BD4*
+ ID_OUI_FROM_DATABASE=Global Security Devices
+
+OUI:0050C2BD5*
+ ID_OUI_FROM_DATABASE=RF-Embedded GmbH
+
+OUI:0050C2BD6*
+ ID_OUI_FROM_DATABASE=BG Systems, Inc.
+
+OUI:0050C2BD7*
+ ID_OUI_FROM_DATABASE=SLAT
+
+OUI:0050C2BD8*
+ ID_OUI_FROM_DATABASE=b.a.b-technologie gmbh
+
+OUI:0050C2BD9*
+ ID_OUI_FROM_DATABASE=AMS Controls, Inc.
+
+OUI:0050C2BDA*
+ ID_OUI_FROM_DATABASE=Digital Lumens
+
+OUI:0050C2BDB*
+ ID_OUI_FROM_DATABASE=GasTOPS Ltd.
+
+OUI:0050C2BDC*
+ ID_OUI_FROM_DATABASE=SS Systems LLC
+
+OUI:0050C2BDE*
+ ID_OUI_FROM_DATABASE=Evo-Teh d.o.o.
+
+OUI:0050C2BDF*
+ ID_OUI_FROM_DATABASE=Euro-Konsult Sp. z o.o.
+
+OUI:0050C2BE0*
+ ID_OUI_FROM_DATABASE=Phaedrus Limited
+
+OUI:0050C2BE1*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:0050C2BE2*
+ ID_OUI_FROM_DATABASE=Convergent Bioscience Ltd.
+
+OUI:0050C2BE3*
+ ID_OUI_FROM_DATABASE=Jiskoot Ltd
+
+OUI:0050C2BE4*
+ ID_OUI_FROM_DATABASE=GRUPO EPELSA S.L.
+
+OUI:0050C2BE5*
+ ID_OUI_FROM_DATABASE=RF Code, Inc
+
+OUI:0050C2BE6*
+ ID_OUI_FROM_DATABASE=Docobo Ltd
+
+OUI:0050C2BE7*
+ ID_OUI_FROM_DATABASE=Genetec Inc.
+
+OUI:0050C2BE8*
+ ID_OUI_FROM_DATABASE=VEHICLE TESTING EQUIPMENT, S.L.
+
+OUI:0050C2BE9*
+ ID_OUI_FROM_DATABASE=ZUCCHETTI SPA
+
+OUI:0050C2BEA*
+ ID_OUI_FROM_DATABASE=Daeyoung inc.
+
+OUI:0050C2BEB*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corporation
+
+OUI:0050C2BEC*
+ ID_OUI_FROM_DATABASE=DRS Laruel Technologies
+
+OUI:0050C2BED*
+ ID_OUI_FROM_DATABASE=Touch Revolution Inc.
+
+OUI:0050C2BEF*
+ ID_OUI_FROM_DATABASE=SOCIEDAD IBERICA DE CONSTRUCCIONES ELECTRICAS, S.A. (SICE)
+
+OUI:0050C2BF0*
+ ID_OUI_FROM_DATABASE=AIM
+
+OUI:0050C2BF1*
+ ID_OUI_FROM_DATABASE=Amatic Industries GmbH
+
+OUI:0050C2BF2*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2BF3*
+ ID_OUI_FROM_DATABASE=Wanco Inc.
+
+OUI:0050C2BF4*
+ ID_OUI_FROM_DATABASE=Monarch Innovative Technologies Pvt Ltd
+
+OUI:0050C2BF5*
+ ID_OUI_FROM_DATABASE=AILES ELECTRONICS CO., LTD.
+
+OUI:0050C2BF6*
+ ID_OUI_FROM_DATABASE=NOLAM EMBEDDED SYSTEMS
+
+OUI:0050C2BF7*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:0050C2BF8*
+ ID_OUI_FROM_DATABASE=Crtiical Link
+
+OUI:0050C2BF9*
+ ID_OUI_FROM_DATABASE=Vitel Net
+
+OUI:0050C2BFA*
+ ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA
+
+OUI:0050C2BFB*
+ ID_OUI_FROM_DATABASE=ecs srl
+
+OUI:0050C2BFC*
+ ID_OUI_FROM_DATABASE=Altronix Corporation
+
+OUI:0050C2BFD*
+ ID_OUI_FROM_DATABASE=Ernemann Cine Tec GmbH
+
+OUI:0050C2BFE*
+ ID_OUI_FROM_DATABASE=Ingeteam Paneles S.A.U.
+
+OUI:0050C2BFF*
+ ID_OUI_FROM_DATABASE=I.S.A. S.r.l.
+
+OUI:0050C2C00*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C2C01*
+ ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L.
+
+OUI:0050C2C02*
+ ID_OUI_FROM_DATABASE=Hanning Elektro-Werke GmbH & Co. KG
+
+OUI:0050C2C03*
+ ID_OUI_FROM_DATABASE=Volumatic Limited.
+
+OUI:0050C2C04*
+ ID_OUI_FROM_DATABASE=SoGEME
+
+OUI:0050C2C05*
+ ID_OUI_FROM_DATABASE=Doppler Systems LLC
+
+OUI:0050C2C06*
+ ID_OUI_FROM_DATABASE=ANALOG WAY
+
+OUI:0050C2C07*
+ ID_OUI_FROM_DATABASE=CIO Informatique Industrielle
+
+OUI:0050C2C08*
+ ID_OUI_FROM_DATABASE=juiceboss
+
+OUI:0050C2C09*
+ ID_OUI_FROM_DATABASE=Globe Wireless
+
+OUI:0050C2C0A*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China)
+
+OUI:0050C2C0B*
+ ID_OUI_FROM_DATABASE=ProSourcing GmbH
+
+OUI:0050C2C0C*
+ ID_OUI_FROM_DATABASE=Altierre
+
+OUI:0050C2C0D*
+ ID_OUI_FROM_DATABASE=Fr. SauterAG
+
+OUI:0050C2C0E*
+ ID_OUI_FROM_DATABASE=AVItronic GmbH
+
+OUI:0050C2C0F*
+ ID_OUI_FROM_DATABASE=DYCEC, S.A.
+
+OUI:0050C2C10*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2C11*
+ ID_OUI_FROM_DATABASE=ART Antriebs- und Regeltechnik GmbH
+
+OUI:0050C2C12*
+ ID_OUI_FROM_DATABASE=OKI DENKI BOHSAI CO.,LTD.
+
+OUI:0050C2C13*
+ ID_OUI_FROM_DATABASE=Dantec Dynamics A/S
+
+OUI:0050C2C14*
+ ID_OUI_FROM_DATABASE=Spectronix Corporation
+
+OUI:0050C2C15*
+ ID_OUI_FROM_DATABASE=INO - Institut National d'Optique
+
+OUI:0050C2C16*
+ ID_OUI_FROM_DATABASE=OMICRON electronics GmbH
+
+OUI:0050C2C17*
+ ID_OUI_FROM_DATABASE=Axis-Shield PoC AS
+
+OUI:0050C2C18*
+ ID_OUI_FROM_DATABASE=Linuxstamp Designs, LLC
+
+OUI:0050C2C19*
+ ID_OUI_FROM_DATABASE=Ibercomp SA
+
+OUI:0050C2C1A*
+ ID_OUI_FROM_DATABASE=SAM Co., Ltd.
+
+OUI:0050C2C1B*
+ ID_OUI_FROM_DATABASE=Graesslin GmbH
+
+OUI:0050C2C1C*
+ ID_OUI_FROM_DATABASE=Becton Dickinson
+
+OUI:0050C2C1D*
+ ID_OUI_FROM_DATABASE=Powerbase Energy Systems Inc.
+
+OUI:0050C2C1E*
+ ID_OUI_FROM_DATABASE=Peperoni-Light
+
+OUI:0050C2C1F*
+ ID_OUI_FROM_DATABASE=Specialist Electronics Services Ltd
+
+OUI:0050C2C20*
+ ID_OUI_FROM_DATABASE=SRC Computers, LLC
+
+OUI:0050C2C22*
+ ID_OUI_FROM_DATABASE=Audient Ltd
+
+OUI:0050C2C23*
+ ID_OUI_FROM_DATABASE=Vidicon LLC
+
+OUI:0050C2C24*
+ ID_OUI_FROM_DATABASE=Qualnetics Corporation
+
+OUI:0050C2C26*
+ ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd
+
+OUI:0050C2C27*
+ ID_OUI_FROM_DATABASE=Qtechnology A/S
+
+OUI:0050C2C28*
+ ID_OUI_FROM_DATABASE=ELREHA GmbH
+
+OUI:0050C2C29*
+ ID_OUI_FROM_DATABASE=Newtel Engineering S.r.l.
+
+OUI:0050C2C2A*
+ ID_OUI_FROM_DATABASE=RealTime Systems Ltd
+
+OUI:0050C2C2B*
+ ID_OUI_FROM_DATABASE=Z-App Systems, Inc.
+
+OUI:0050C2C2C*
+ ID_OUI_FROM_DATABASE=bach-messtechnik gmbh
+
+OUI:0050C2C2D*
+ ID_OUI_FROM_DATABASE=Digitale Analoge COMponenten West Electronic Vertriebs GmbH
+
+OUI:0050C2C2E*
+ ID_OUI_FROM_DATABASE=DISMUNTEL SAL
+
+OUI:0050C2C2F*
+ ID_OUI_FROM_DATABASE=REFLEX CES
+
+OUI:0050C2C30*
+ ID_OUI_FROM_DATABASE=Wagner Group GmbH
+
+OUI:0050C2C31*
+ ID_OUI_FROM_DATABASE=4D Technology Corporation
+
+OUI:0050C2C32*
+ ID_OUI_FROM_DATABASE=Procon Electronics Pty Ltd
+
+OUI:0050C2C34*
+ ID_OUI_FROM_DATABASE=Kyuhen
+
+OUI:0050C2C35*
+ ID_OUI_FROM_DATABASE=Insitu, Inc.
+
+OUI:0050C2C36*
+ ID_OUI_FROM_DATABASE=SET GmbH
+
+OUI:0050C2C37*
+ ID_OUI_FROM_DATABASE=BEAR Solutions (Australasia) Pty Ltd
+
+OUI:0050C2C38*
+ ID_OUI_FROM_DATABASE=Computer Automation Technology Inc
+
+OUI:0050C2C39*
+ ID_OUI_FROM_DATABASE=SECAD SA
+
+OUI:0050C2C3A*
+ ID_OUI_FROM_DATABASE=Sicon s.r.l.
+
+OUI:0050C2C3B*
+ ID_OUI_FROM_DATABASE=ELEKTRO-AUTOMATIK GmbH & Co. KG
+
+OUI:0050C2C3C*
+ ID_OUI_FROM_DATABASE=ELSIST S.r.l.
+
+OUI:0050C2C3D*
+ ID_OUI_FROM_DATABASE=PLA ELECTRO APPLIANCES PVT. LTD.
+
+OUI:0050C2C3E*
+ ID_OUI_FROM_DATABASE=Sysacom
+
+OUI:0050C2C3F*
+ ID_OUI_FROM_DATABASE=ANXeBusiness Corporation
+
+OUI:0050C2C40*
+ ID_OUI_FROM_DATABASE=BAE Systems Bofors AB
+
+OUI:0050C2C41*
+ ID_OUI_FROM_DATABASE=COMPRION GmbH
+
+OUI:0050C2C42*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2C43*
+ ID_OUI_FROM_DATABASE=Cammegh Limited
+
+OUI:0050C2C44*
+ ID_OUI_FROM_DATABASE=Beijing Zhongherongzhi Elec.&Tech.Co.,Ltd.
+
+OUI:0050C2C45*
+ ID_OUI_FROM_DATABASE=Galvamat & Unican Technologies SA
+
+OUI:0050C2C46*
+ ID_OUI_FROM_DATABASE=QNE GmbH & Co. KG
+
+OUI:0050C2C47*
+ ID_OUI_FROM_DATABASE=Weltek Technologies Co. Ltd.
+
+OUI:0050C2C48*
+ ID_OUI_FROM_DATABASE=Cytek Media Systems, INC.
+
+OUI:0050C2C49*
+ ID_OUI_FROM_DATABASE=Elektronic Thoma GmbH
+
+OUI:0050C2C4A*
+ ID_OUI_FROM_DATABASE=Herrick Technology Laboratories, Inc.
+
+OUI:0050C2C4B*
+ ID_OUI_FROM_DATABASE=R.V.R. elettronica s.p.a.
+
+OUI:0050C2C4C*
+ ID_OUI_FROM_DATABASE=Lancier Monitoring GmbH
+
+OUI:0050C2C4D*
+ ID_OUI_FROM_DATABASE=Industrial Automation Systems
+
+OUI:0050C2C4E*
+ ID_OUI_FROM_DATABASE=Elaso AG
+
+OUI:0050C2C4F*
+ ID_OUI_FROM_DATABASE=Powersense A/S
+
+OUI:0050C2C50*
+ ID_OUI_FROM_DATABASE=Beceem Communications, Inc.
+
+OUI:0050C2C51*
+ ID_OUI_FROM_DATABASE=InForce Computing, Inc.
+
+OUI:0050C2C52*
+ ID_OUI_FROM_DATABASE=Smartfield, Inc.
+
+OUI:0050C2C53*
+ ID_OUI_FROM_DATABASE=Eilersen Electric A/S
+
+OUI:0050C2C54*
+ ID_OUI_FROM_DATABASE=HPC Platform
+
+OUI:0050C2C55*
+ ID_OUI_FROM_DATABASE=Watterott electronic
+
+OUI:0050C2C56*
+ ID_OUI_FROM_DATABASE=Spirent Communications
+
+OUI:0050C2C57*
+ ID_OUI_FROM_DATABASE=High Speed Design, Inc.
+
+OUI:0050C2C58*
+ ID_OUI_FROM_DATABASE=Foerster-Technik GmbH
+
+OUI:0050C2C59*
+ ID_OUI_FROM_DATABASE=SKD System AB
+
+OUI:0050C2C5A*
+ ID_OUI_FROM_DATABASE=Commotive A/S
+
+OUI:0050C2C5B*
+ ID_OUI_FROM_DATABASE=MICRO TECHNICA
+
+OUI:0050C2C5C*
+ ID_OUI_FROM_DATABASE=WAVECOM ELEKTRONIK AG
+
+OUI:0050C2C5D*
+ ID_OUI_FROM_DATABASE=SweMet AB
+
+OUI:0050C2C5E*
+ ID_OUI_FROM_DATABASE=CellPlus technologies, Inc.
+
+OUI:0050C2C5F*
+ ID_OUI_FROM_DATABASE=Icon Time Systems
+
+OUI:0050C2C60*
+ ID_OUI_FROM_DATABASE=Integration Technologies Limited
+
+OUI:0050C2C61*
+ ID_OUI_FROM_DATABASE=HaiVision Systems Incorporated
+
+OUI:0050C2C62*
+ ID_OUI_FROM_DATABASE=Zeus Systems Private Limited
+
+OUI:0050C2C63*
+ ID_OUI_FROM_DATABASE=Potter Electric Signal Company
+
+OUI:0050C2C64*
+ ID_OUI_FROM_DATABASE=Pal Software Service Co.,Ltd.
+
+OUI:0050C2C65*
+ ID_OUI_FROM_DATABASE=Micro I/O Servicos de Electronica, Lda
+
+OUI:0050C2C66*
+ ID_OUI_FROM_DATABASE=KS Beschallungstechnik GmbH
+
+OUI:0050C2C67*
+ ID_OUI_FROM_DATABASE=Practical Control Ltd
+
+OUI:0050C2C68*
+ ID_OUI_FROM_DATABASE=Broadsoft PacketSmart, Inc.
+
+OUI:0050C2C69*
+ ID_OUI_FROM_DATABASE=REBO CO.,LTD.
+
+OUI:0050C2C6A*
+ ID_OUI_FROM_DATABASE=ELECTRONICA KELD
+
+OUI:0050C2C6B*
+ ID_OUI_FROM_DATABASE=SiGarden Sp z o.o.
+
+OUI:0050C2C6C*
+ ID_OUI_FROM_DATABASE=DORLET S.A.
+
+OUI:0050C2C6D*
+ ID_OUI_FROM_DATABASE=Deansoft CO., Ltd.
+
+OUI:0050C2C6E*
+ ID_OUI_FROM_DATABASE=TBS Holding AG
+
+OUI:0050C2C6F*
+ ID_OUI_FROM_DATABASE=MSB Elektronik und Geraetebau GmbH
+
+OUI:0050C2C70*
+ ID_OUI_FROM_DATABASE=Wilke Technology GmbH
+
+OUI:0050C2C71*
+ ID_OUI_FROM_DATABASE=Sequoia Technology Group Ltd
+
+OUI:0050C2C72*
+ ID_OUI_FROM_DATABASE=Quail
+
+OUI:0050C2C73*
+ ID_OUI_FROM_DATABASE=Industry Controls, Inc.
+
+OUI:0050C2C74*
+ ID_OUI_FROM_DATABASE=Wapice Ltd.
+
+OUI:0050C2C75*
+ ID_OUI_FROM_DATABASE=Rovsing A/S
+
+OUI:0050C2C76*
+ ID_OUI_FROM_DATABASE=GridManager A/S
+
+OUI:0050C2C77*
+ ID_OUI_FROM_DATABASE=AIM Co.,Ltd
+
+OUI:0050C2C78*
+ ID_OUI_FROM_DATABASE=9Solutions Oy
+
+OUI:0050C2C79*
+ ID_OUI_FROM_DATABASE=CODESYSTEM Co.,Ltd
+
+OUI:0050C2C7A*
+ ID_OUI_FROM_DATABASE=Protonic Holland
+
+OUI:0050C2C7B*
+ ID_OUI_FROM_DATABASE=Honeywell
+
+OUI:0050C2C7C*
+ ID_OUI_FROM_DATABASE=Scienlab Electronic Systems GmbH
+
+OUI:0050C2C7D*
+ ID_OUI_FROM_DATABASE=TAE Antriebstechnik GmbH
+
+OUI:0050C2C7E*
+ ID_OUI_FROM_DATABASE=Buerkert Werke GmbH
+
+OUI:0050C2C7F*
+ ID_OUI_FROM_DATABASE=Kinects Solutions Inc
+
+OUI:0050C2C80*
+ ID_OUI_FROM_DATABASE=Reko-vek
+
+OUI:0050C2C81*
+ ID_OUI_FROM_DATABASE=Odyssee Systemes SAS
+
+OUI:0050C2C82*
+ ID_OUI_FROM_DATABASE=Kyosha Industries
+
+OUI:0050C2C83*
+ ID_OUI_FROM_DATABASE=Gronic Systems GmbH
+
+OUI:0050C2C84*
+ ID_OUI_FROM_DATABASE=DOMIS
+
+OUI:0050C2C85*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corporation
+
+OUI:0050C2C86*
+ ID_OUI_FROM_DATABASE=Bruckner & Jarosch Ingenieurgesellschaft mbH
+
+OUI:0050C2C87*
+ ID_OUI_FROM_DATABASE=LECO Corporation
+
+OUI:0050C2C88*
+ ID_OUI_FROM_DATABASE=CSI Controles e Sistemas Industriais Ltda.
+
+OUI:0050C2C89*
+ ID_OUI_FROM_DATABASE=Creative Micro Design
+
+OUI:0050C2C8A*
+ ID_OUI_FROM_DATABASE=Automated Media Services, Inc.
+
+OUI:0050C2C8B*
+ ID_OUI_FROM_DATABASE=OCAS AS
+
+OUI:0050C2C8C*
+ ID_OUI_FROM_DATABASE=Lanmark Controls Inc.
+
+OUI:0050C2C8D*
+ ID_OUI_FROM_DATABASE=Emergency Message Controls LLC
+
+OUI:0050C2C8E*
+ ID_OUI_FROM_DATABASE=SDD ITG
+
+OUI:0050C2C8F*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2C90*
+ ID_OUI_FROM_DATABASE=REALD
+
+OUI:0050C2C91*
+ ID_OUI_FROM_DATABASE=Media Technologies Ltd.
+
+OUI:0050C2C92*
+ ID_OUI_FROM_DATABASE=EMAC, Inc.
+
+OUI:0050C2C93*
+ ID_OUI_FROM_DATABASE=SENSAIR Pty Ltd
+
+OUI:0050C2C94*
+ ID_OUI_FROM_DATABASE=ISIS ENGINEERING, S.A.
+
+OUI:0050C2C95*
+ ID_OUI_FROM_DATABASE=IPSES S.r.l.
+
+OUI:0050C2C96*
+ ID_OUI_FROM_DATABASE=CyberCraft
+
+OUI:0050C2C97*
+ ID_OUI_FROM_DATABASE=MSTRONIC CO., LTD.
+
+OUI:0050C2C98*
+ ID_OUI_FROM_DATABASE=Criticare Systems, Inc
+
+OUI:0050C2C99*
+ ID_OUI_FROM_DATABASE=HJPC Corporation dba Pactron
+
+OUI:0050C2C9A*
+ ID_OUI_FROM_DATABASE=PACOMP Sp. z o.o.
+
+OUI:0050C2C9B*
+ ID_OUI_FROM_DATABASE=Sm electronic co.
+
+OUI:0050C2C9C*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2C9D*
+ ID_OUI_FROM_DATABASE=Radius Sweden AB
+
+OUI:0050C2C9E*
+ ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA
+
+OUI:0050C2C9F*
+ ID_OUI_FROM_DATABASE=Etherhome
+
+OUI:0050C2CA0*
+ ID_OUI_FROM_DATABASE=Kiefer technic GmbH
+
+OUI:0050C2CA1*
+ ID_OUI_FROM_DATABASE=Wayne Kerr Electronics
+
+OUI:0050C2CA2*
+ ID_OUI_FROM_DATABASE=The Logical Company
+
+OUI:0050C2CA3*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2CA4*
+ ID_OUI_FROM_DATABASE=Vox Technologies
+
+OUI:0050C2CA5*
+ ID_OUI_FROM_DATABASE=YOKOWO CO.,LTD
+
+OUI:0050C2CA6*
+ ID_OUI_FROM_DATABASE=Vidisys GmbH
+
+OUI:0050C2CA7*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific
+
+OUI:0050C2CA8*
+ ID_OUI_FROM_DATABASE=Systems With Intelligence Inc.
+
+OUI:0050C2CA9*
+ ID_OUI_FROM_DATABASE=Intelligent Devices
+
+OUI:0050C2CAA*
+ ID_OUI_FROM_DATABASE=DSP DESIGN LTD
+
+OUI:0050C2CAB*
+ ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG
+
+OUI:0050C2CAC*
+ ID_OUI_FROM_DATABASE=PURVIS Systems Incorporated
+
+OUI:0050C2CAD*
+ ID_OUI_FROM_DATABASE=Pacific Coast Engineering
+
+OUI:0050C2CAE*
+ ID_OUI_FROM_DATABASE=Campbell Scientific Canada Corp.
+
+OUI:0050C2CAF*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C2CB0*
+ ID_OUI_FROM_DATABASE=Konsmetal S.A.
+
+OUI:0050C2CB1*
+ ID_OUI_FROM_DATABASE=ZK Celltest Inc
+
+OUI:0050C2CB2*
+ ID_OUI_FROM_DATABASE=Moravian Instruments
+
+OUI:0050C2CB3*
+ ID_OUI_FROM_DATABASE=Deuta-Werke GmbH
+
+OUI:0050C2CB4*
+ ID_OUI_FROM_DATABASE=GEA Farm Technologies GmbH
+
+OUI:0050C2CB6*
+ ID_OUI_FROM_DATABASE=Krontek Pty Ltd
+
+OUI:0050C2CB7*
+ ID_OUI_FROM_DATABASE=inotech GmbH
+
+OUI:0050C2CB8*
+ ID_OUI_FROM_DATABASE=Raith GmbH
+
+OUI:0050C2CB9*
+ ID_OUI_FROM_DATABASE=Micro Technic A/S
+
+OUI:0050C2CBA*
+ ID_OUI_FROM_DATABASE=DELTA TAU DATA SYSTEMS
+
+OUI:0050C2CBB*
+ ID_OUI_FROM_DATABASE=Coptonix GmbH
+
+OUI:0050C2CBC*
+ ID_OUI_FROM_DATABASE=CP ELETRONICA SA
+
+OUI:0050C2CBD*
+ ID_OUI_FROM_DATABASE=Hi Tech Electronics Ltd
+
+OUI:0050C2CBE*
+ ID_OUI_FROM_DATABASE=CODE BLUE CORPORATION
+
+OUI:0050C2CBF*
+ ID_OUI_FROM_DATABASE=Megacon AB
+
+OUI:0050C2CC0*
+ ID_OUI_FROM_DATABASE=World Time Solutions Limited
+
+OUI:0050C2CC1*
+ ID_OUI_FROM_DATABASE=Level 3 Communications
+
+OUI:0050C2CC2*
+ ID_OUI_FROM_DATABASE=ConectaIP Tecnologia S.L.
+
+OUI:0050C2CC3*
+ ID_OUI_FROM_DATABASE=viscount systems inc.
+
+OUI:0050C2CC4*
+ ID_OUI_FROM_DATABASE=General Dynamics C4S
+
+OUI:0050C2CC5*
+ ID_OUI_FROM_DATABASE=Tecnovum AG
+
+OUI:0050C2CC6*
+ ID_OUI_FROM_DATABASE=KDT
+
+OUI:0050C2CC7*
+ ID_OUI_FROM_DATABASE=TOPROOT Technology Corp. Ltd.,
+
+OUI:0050C2CC9*
+ ID_OUI_FROM_DATABASE=Promess GmbH
+
+OUI:0050C2CCA*
+ ID_OUI_FROM_DATABASE=SANMINA-SCI SHENZHEN
+
+OUI:0050C2CCB*
+ ID_OUI_FROM_DATABASE=CaptiveAire Systems Inc.
+
+OUI:0050C2CCC*
+ ID_OUI_FROM_DATABASE=Smartech-technology
+
+OUI:0050C2CCD*
+ ID_OUI_FROM_DATABASE=FUJI DATA SYSTEM Co.,Ltd.
+
+OUI:0050C2CCE*
+ ID_OUI_FROM_DATABASE=Mac-Gray Corporation
+
+OUI:0050C2CCF*
+ ID_OUI_FROM_DATABASE=TASK SISTEMAS DE COMPUTACAO LTDA
+
+OUI:0050C2CD0*
+ ID_OUI_FROM_DATABASE=MME Mueller Mikroelektronik
+
+OUI:0050C2CD1*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C2CD2*
+ ID_OUI_FROM_DATABASE=SIM2 Multimedia S.p.A.
+
+OUI:0050C2CD3*
+ ID_OUI_FROM_DATABASE=Covidence A/S
+
+OUI:0050C2CD4*
+ ID_OUI_FROM_DATABASE=SCHRAML GmbH
+
+OUI:0050C2CD5*
+ ID_OUI_FROM_DATABASE=Arcos Technologies Ltd.
+
+OUI:0050C2CD6*
+ ID_OUI_FROM_DATABASE=Arktan Systems
+
+OUI:0050C2CD7*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2CD8*
+ ID_OUI_FROM_DATABASE=IT-IS International Ltd.
+
+OUI:0050C2CD9*
+ ID_OUI_FROM_DATABASE=NDC Infrared Engineering, Inc.
+
+OUI:0050C2CDA*
+ ID_OUI_FROM_DATABASE=taskit GmbH
+
+OUI:0050C2CDB*
+ ID_OUI_FROM_DATABASE=RUTTER INC
+
+OUI:0050C2CDC*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China)
+
+OUI:0050C2CDD*
+ ID_OUI_FROM_DATABASE=K.C.C. SHOKAI LIMITED
+
+OUI:0050C2CDE*
+ ID_OUI_FROM_DATABASE=Axotec Technologies GmbH
+
+OUI:0050C2CDF*
+ ID_OUI_FROM_DATABASE=CoreEL TEchnologies (I) Pvt Ltd
+
+OUI:0050C2CE0*
+ ID_OUI_FROM_DATABASE=Industrial Control Links, Inc.
+
+OUI:0050C2CE1*
+ ID_OUI_FROM_DATABASE=Satellink Inc.
+
+OUI:0050C2CE2*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:0050C2CE3*
+ ID_OUI_FROM_DATABASE=Industrial Automatics Design Bureau
+
+OUI:0050C2CE4*
+ ID_OUI_FROM_DATABASE=TEKTRONIK
+
+OUI:0050C2CE5*
+ ID_OUI_FROM_DATABASE=Maretron, LLP
+
+OUI:0050C2CE6*
+ ID_OUI_FROM_DATABASE=APLICA TECHNOLOGIES
+
+OUI:0050C2CE7*
+ ID_OUI_FROM_DATABASE=Echola Systems
+
+OUI:0050C2CE8*
+ ID_OUI_FROM_DATABASE=Thomas & Betts
+
+OUI:0050C2CEA*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2CEB*
+ ID_OUI_FROM_DATABASE=Toyon Research Corporation
+
+OUI:0050C2CEC*
+ ID_OUI_FROM_DATABASE=Erhardt+Leimer GmbH
+
+OUI:0050C2CED*
+ ID_OUI_FROM_DATABASE=AeroMechanical Services Ltd, FLYHT
+
+OUI:0050C2CEE*
+ ID_OUI_FROM_DATABASE=EMBED-IT OG
+
+OUI:0050C2CEF*
+ ID_OUI_FROM_DATABASE=Lupatecnologia e Sistemas Ltda
+
+OUI:0050C2CF0*
+ ID_OUI_FROM_DATABASE=Inviso B.V.
+
+OUI:0050C2CF1*
+ ID_OUI_FROM_DATABASE=TelGaAs, Inc.
+
+OUI:0050C2CF2*
+ ID_OUI_FROM_DATABASE=Weiss Robotics GmbH & Co. KG
+
+OUI:0050C2CF3*
+ ID_OUI_FROM_DATABASE=Daiken Automacao Ltda
+
+OUI:0050C2CF4*
+ ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH
+
+OUI:0050C2CF5*
+ ID_OUI_FROM_DATABASE=Aircell
+
+OUI:0050C2CF6*
+ ID_OUI_FROM_DATABASE=Epec Oy
+
+OUI:0050C2CF7*
+ ID_OUI_FROM_DATABASE=Armour Home Electronics LTD
+
+OUI:0050C2CF8*
+ ID_OUI_FROM_DATABASE=beks Kommunikacios Technika kft
+
+OUI:0050C2CF9*
+ ID_OUI_FROM_DATABASE=Elbit Systems of America
+
+OUI:0050C2CFA*
+ ID_OUI_FROM_DATABASE=GRUPO EPELSA S. L.
+
+OUI:0050C2CFB*
+ ID_OUI_FROM_DATABASE=New Embedded Technology
+
+OUI:0050C2CFC*
+ ID_OUI_FROM_DATABASE=Tritium Pty Ltd
+
+OUI:0050C2CFD*
+ ID_OUI_FROM_DATABASE=AIRFOLC,INC.
+
+OUI:0050C2CFE*
+ ID_OUI_FROM_DATABASE=Techleader
+
+OUI:0050C2CFF*
+ ID_OUI_FROM_DATABASE=INFRASAFE INCORPORATED
+
+OUI:0050C2D00*
+ ID_OUI_FROM_DATABASE=Bodensee Gravitymeter Geosystem GmbH
+
+OUI:0050C2D01*
+ ID_OUI_FROM_DATABASE=Aanderaa Data Instruments
+
+OUI:0050C2D02*
+ ID_OUI_FROM_DATABASE=SURVALENT TECHNOLOGY CORP
+
+OUI:0050C2D03*
+ ID_OUI_FROM_DATABASE=Peekel Instruments B.V.
+
+OUI:0050C2D04*
+ ID_OUI_FROM_DATABASE=Tehama Wireless
+
+OUI:0050C2D06*
+ ID_OUI_FROM_DATABASE=nCk Research LLC
+
+OUI:0050C2D07*
+ ID_OUI_FROM_DATABASE=IAF GmbH
+
+OUI:0050C2D08*
+ ID_OUI_FROM_DATABASE=Reimesch Kommunikationssysteme GmbH
+
+OUI:0050C2D09*
+ ID_OUI_FROM_DATABASE=Guardtec, Inc.
+
+OUI:0050C2D0A*
+ ID_OUI_FROM_DATABASE=Airpoint Co., Ltd.
+
+OUI:0050C2D0B*
+ ID_OUI_FROM_DATABASE=CODACO ELECTRONIC s.r.o.
+
+OUI:0050C2D0C*
+ ID_OUI_FROM_DATABASE=JVL Industri Elektronik
+
+OUI:0050C2D0D*
+ ID_OUI_FROM_DATABASE=DECA Card Engineering GmbH
+
+OUI:0050C2D0E*
+ ID_OUI_FROM_DATABASE=Weinert Engineering GmbH
+
+OUI:0050C2D0F*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2D10*
+ ID_OUI_FROM_DATABASE=Rosslare Enterprises Ltd.
+
+OUI:0050C2D11*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2D12*
+ ID_OUI_FROM_DATABASE=Tokyo Weld Co.,Ltd.
+
+OUI:0050C2D13*
+ ID_OUI_FROM_DATABASE=GUNMA ELECTRONICS CO LTD
+
+OUI:0050C2D14*
+ ID_OUI_FROM_DATABASE=SAET I.S.
+
+OUI:0050C2D15*
+ ID_OUI_FROM_DATABASE=MSR-Office GmbH
+
+OUI:0050C2D16*
+ ID_OUI_FROM_DATABASE=Imricor Medical Systems, Inc.
+
+OUI:0050C2D17*
+ ID_OUI_FROM_DATABASE=CUE, a.s.
+
+OUI:0050C2D18*
+ ID_OUI_FROM_DATABASE=Glyn GmbH & Co.KG
+
+OUI:0050C2D19*
+ ID_OUI_FROM_DATABASE=Applied Medical Technologies, Inc DBA AirClean Systems
+
+OUI:0050C2D1A*
+ ID_OUI_FROM_DATABASE=GILLAM-FEI S.A.
+
+OUI:0050C2D1B*
+ ID_OUI_FROM_DATABASE=TECHKON GmbH
+
+OUI:0050C2D1C*
+ ID_OUI_FROM_DATABASE=Recon Dynamics, LLC
+
+OUI:0050C2D1D*
+ ID_OUI_FROM_DATABASE=Moco Media Pty Ltd
+
+OUI:0050C2D1E*
+ ID_OUI_FROM_DATABASE=Tobila Systems, Inc.
+
+OUI:0050C2D1F*
+ ID_OUI_FROM_DATABASE=Olympus NDT Canada Inc.
+
+OUI:0050C2D20*
+ ID_OUI_FROM_DATABASE=7+ Kft
+
+OUI:0050C2D21*
+ ID_OUI_FROM_DATABASE=Innovative Circuit Technology
+
+OUI:0050C2D22*
+ ID_OUI_FROM_DATABASE=eMDee Technology, Inc.
+
+OUI:0050C2D23*
+ ID_OUI_FROM_DATABASE=Bluestone Technology GmbH
+
+OUI:0050C2D24*
+ ID_OUI_FROM_DATABASE=Expro North Sea
+
+OUI:0050C2D25*
+ ID_OUI_FROM_DATABASE=VAF Instruments BV
+
+OUI:0050C2D26*
+ ID_OUI_FROM_DATABASE=RCH
+
+OUI:0050C2D27*
+ ID_OUI_FROM_DATABASE=Fr.Sauter AG
+
+OUI:0050C2D28*
+ ID_OUI_FROM_DATABASE=Digitale Analoge COMponenten West Electronic Vertriebs GmbH
+
+OUI:0050C2D29*
+ ID_OUI_FROM_DATABASE=Axible Technologies
+
+OUI:0050C2D2A*
+ ID_OUI_FROM_DATABASE=Millennium Electronics Pty.Ltd.
+
+OUI:0050C2D2B*
+ ID_OUI_FROM_DATABASE=Video Tech Laboratories, Inc.
+
+OUI:0050C2D2C*
+ ID_OUI_FROM_DATABASE=Schneider Electric Motion USA
+
+OUI:0050C2D2D*
+ ID_OUI_FROM_DATABASE=CADI SCIENTIFIC PTE LTD
+
+OUI:0050C2D2E*
+ ID_OUI_FROM_DATABASE=RS Gesellschaft fur Informationstechnik mbH & Co KG
+
+OUI:0050C2D2F*
+ ID_OUI_FROM_DATABASE=Key Systems, Inc.
+
+OUI:0050C2D30*
+ ID_OUI_FROM_DATABASE=ACTIV Financial Systems, Inc.
+
+OUI:0050C2D31*
+ ID_OUI_FROM_DATABASE=UNGAVA Technologies Inc.
+
+OUI:0050C2D32*
+ ID_OUI_FROM_DATABASE=RealTime Systems Ltd
+
+OUI:0050C2D33*
+ ID_OUI_FROM_DATABASE=Maddalena S.p.A
+
+OUI:0050C2D34*
+ ID_OUI_FROM_DATABASE=GAON TECH corp.
+
+OUI:0050C2D35*
+ ID_OUI_FROM_DATABASE=UG Systems GmbH & Co. KG
+
+OUI:0050C2D36*
+ ID_OUI_FROM_DATABASE=Enatel Limited
+
+OUI:0050C2D37*
+ ID_OUI_FROM_DATABASE=LJT & Associates, Inc.
+
+OUI:0050C2D38*
+ ID_OUI_FROM_DATABASE=Kyowa Electronics Co.,Ltd.
+
+OUI:0050C2D39*
+ ID_OUI_FROM_DATABASE=Apex NV
+
+OUI:0050C2D3A*
+ ID_OUI_FROM_DATABASE=WellSense Technologies
+
+OUI:0050C2D3B*
+ ID_OUI_FROM_DATABASE=Gitsn Inc.
+
+OUI:0050C2D3C*
+ ID_OUI_FROM_DATABASE=ASSYSTEM France
+
+OUI:0050C2D3D*
+ ID_OUI_FROM_DATABASE=Tellabs Operations Inc.
+
+OUI:0050C2D3E*
+ ID_OUI_FROM_DATABASE=Synatec Electronic GmbH
+
+OUI:0050C2D3F*
+ ID_OUI_FROM_DATABASE=CSS, LLC
+
+OUI:0050C2D40*
+ ID_OUI_FROM_DATABASE=demmel products
+
+OUI:0050C2D41*
+ ID_OUI_FROM_DATABASE=AREA ENERGY, INC.
+
+OUI:0050C2D42*
+ ID_OUI_FROM_DATABASE=Hagenuk KMT GmbH
+
+OUI:0050C2D43*
+ ID_OUI_FROM_DATABASE=DSP4YOU Ltd
+
+OUI:0050C2D44*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2D45*
+ ID_OUI_FROM_DATABASE=Technagon GmbH
+
+OUI:0050C2D46*
+ ID_OUI_FROM_DATABASE=Thales Nederland BV
+
+OUI:0050C2D47*
+ ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA
+
+OUI:0050C2D48*
+ ID_OUI_FROM_DATABASE=Watermark Estate Management Services, LLC
+
+OUI:0050C2D49*
+ ID_OUI_FROM_DATABASE=Smith Meter, Inc
+
+OUI:0050C2D4A*
+ ID_OUI_FROM_DATABASE=ATH system
+
+OUI:0050C2D4B*
+ ID_OUI_FROM_DATABASE=Indra Australia
+
+OUI:0050C2D4C*
+ ID_OUI_FROM_DATABASE=DALOG Diagnosesysteme GmbH
+
+OUI:0050C2D4D*
+ ID_OUI_FROM_DATABASE=Yardney Technical Products Inc.
+
+OUI:0050C2D4E*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2D4F*
+ ID_OUI_FROM_DATABASE=SECOM GmbH
+
+OUI:0050C2D50*
+ ID_OUI_FROM_DATABASE=Solbrig Electronics, Inc.
+
+OUI:0050C2D51*
+ ID_OUI_FROM_DATABASE=BETTINI SRL
+
+OUI:0050C2D52*
+ ID_OUI_FROM_DATABASE=F+D Feinwerk- und Drucktechnik GmbH
+
+OUI:0050C2D53*
+ ID_OUI_FROM_DATABASE=Telemerkki Oy
+
+OUI:0050C2D54*
+ ID_OUI_FROM_DATABASE=ABtrack s.r.l.
+
+OUI:0050C2D55*
+ ID_OUI_FROM_DATABASE=Sterna Security
+
+OUI:0050C2D56*
+ ID_OUI_FROM_DATABASE=SELEX Communications Limited
+
+OUI:0050C2D57*
+ ID_OUI_FROM_DATABASE=Hijikata Denki Corp.
+
+OUI:0050C2D58*
+ ID_OUI_FROM_DATABASE=NIK-ELEKTRONIKA Ltd
+
+OUI:0050C2D59*
+ ID_OUI_FROM_DATABASE=Buanco System A/S
+
+OUI:0050C2D5A*
+ ID_OUI_FROM_DATABASE=Embedded Monitoring Systems Ltd.
+
+OUI:0050C2D5B*
+ ID_OUI_FROM_DATABASE=Infinition Inc.
+
+OUI:0050C2D5C*
+ ID_OUI_FROM_DATABASE=Ibetor S.L.
+
+OUI:0050C2D5D*
+ ID_OUI_FROM_DATABASE=GLOBALCOM ENGINEERING SRL
+
+OUI:0050C2D5E*
+ ID_OUI_FROM_DATABASE=infinitec co., ltd.
+
+OUI:0050C2D5F*
+ ID_OUI_FROM_DATABASE=Embedded Solution Co., Ltd.
+
+OUI:0050C2D60*
+ ID_OUI_FROM_DATABASE=Nihon Kessho Koogaku Co., Ltd.
+
+OUI:0050C2D61*
+ ID_OUI_FROM_DATABASE=system2 GmbH
+
+OUI:0050C2D62*
+ ID_OUI_FROM_DATABASE=EMAC, Inc.
+
+OUI:0050C2D63*
+ ID_OUI_FROM_DATABASE=DATAREGIS S.A.
+
+OUI:0050C2D64*
+ ID_OUI_FROM_DATABASE=TV1 GmbH
+
+OUI:0050C2D65*
+ ID_OUI_FROM_DATABASE=TX Technology Corp
+
+OUI:0050C2D66*
+ ID_OUI_FROM_DATABASE=Uvax Concepts
+
+OUI:0050C2D67*
+ ID_OUI_FROM_DATABASE=KLING & FREITAG GmbH
+
+OUI:0050C2D68*
+ ID_OUI_FROM_DATABASE=HiSpeed Data, Inc.
+
+OUI:0050C2D69*
+ ID_OUI_FROM_DATABASE=GHL Systems Bhd
+
+OUI:0050C2D6A*
+ ID_OUI_FROM_DATABASE=A&T Corporation, Electrics Group , LAS R&D Unit,
+
+OUI:0050C2D6B*
+ ID_OUI_FROM_DATABASE=Nemec Automation
+
+OUI:0050C2D6C*
+ ID_OUI_FROM_DATABASE=ALPHA Corporation
+
+OUI:0050C2D6D*
+ ID_OUI_FROM_DATABASE=Pro-Digital
+
+OUI:0050C2D6E*
+ ID_OUI_FROM_DATABASE=BC Illumination, Inc.
+
+OUI:0050C2D6F*
+ ID_OUI_FROM_DATABASE=Imtron Messtechnik GmbH
+
+OUI:0050C2D70*
+ ID_OUI_FROM_DATABASE=C. Rob. Hammerstein GmbH & Co. KG
+
+OUI:0050C2D71*
+ ID_OUI_FROM_DATABASE=EMAC, Inc.
+
+OUI:0050C2D72*
+ ID_OUI_FROM_DATABASE=Scale-Tron, Inc.
+
+OUI:0050C2D73*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2D74*
+ ID_OUI_FROM_DATABASE=Computech International
+
+OUI:0050C2D75*
+ ID_OUI_FROM_DATABASE=Collectric AB
+
+OUI:0050C2D76*
+ ID_OUI_FROM_DATABASE=Telvent
+
+OUI:0050C2D77*
+ ID_OUI_FROM_DATABASE=Fr.SauterAG
+
+OUI:0050C2D78*
+ ID_OUI_FROM_DATABASE=P4Q Electronics
+
+OUI:0050C2D79*
+ ID_OUI_FROM_DATABASE=DSI RF Systems, Inc.
+
+OUI:0050C2D7A*
+ ID_OUI_FROM_DATABASE=Transbit Sp. z o.o.
+
+OUI:0050C2D7B*
+ ID_OUI_FROM_DATABASE=OWITA GmbH
+
+OUI:0050C2D7C*
+ ID_OUI_FROM_DATABASE=Microcubs Systems Pvt Ltd
+
+OUI:0050C2D7D*
+ ID_OUI_FROM_DATABASE=Voltech Instruments
+
+OUI:0050C2D7E*
+ ID_OUI_FROM_DATABASE=LYNX Technik AG
+
+OUI:0050C2D7F*
+ ID_OUI_FROM_DATABASE=HMI Technologies
+
+OUI:0050C2D80*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2D81*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:0050C2D82*
+ ID_OUI_FROM_DATABASE=Audio Authority Corp
+
+OUI:0050C2D83*
+ ID_OUI_FROM_DATABASE=Blankom
+
+OUI:0050C2D84*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China)
+
+OUI:0050C2D85*
+ ID_OUI_FROM_DATABASE=VITEC
+
+OUI:0050C2D86*
+ ID_OUI_FROM_DATABASE=ECOMM ERA
+
+OUI:0050C2D87*
+ ID_OUI_FROM_DATABASE=Electrolight Shivuk (1994) Ltd.
+
+OUI:0050C2D88*
+ ID_OUI_FROM_DATABASE=T+A elektroakustik GmbH & Co KG
+
+OUI:0050C2D89*
+ ID_OUI_FROM_DATABASE=Visual Telecommunication Network, Inc
+
+OUI:0050C2D8A*
+ ID_OUI_FROM_DATABASE=OptoLink  Industria e Comercio Ltda
+
+OUI:0050C2D8B*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:0050C2D8C*
+ ID_OUI_FROM_DATABASE=iRphotonics
+
+OUI:0050C2D8D*
+ ID_OUI_FROM_DATABASE=CS-Instruments
+
+OUI:0050C2D8E*
+ ID_OUI_FROM_DATABASE=LSD Science&Technology Co.,Ltd.
+
+OUI:0050C2D8F*
+ ID_OUI_FROM_DATABASE=Syes srl
+
+OUI:0050C2D90*
+ ID_OUI_FROM_DATABASE=Dumps Electronic
+
+OUI:0050C2D91*
+ ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX
+
+OUI:0050C2D92*
+ ID_OUI_FROM_DATABASE=Manz
+
+OUI:0050C2D93*
+ ID_OUI_FROM_DATABASE=Axlon AB
+
+OUI:0050C2D94*
+ ID_OUI_FROM_DATABASE=Software Effect Enterprises, Inc
+
+OUI:0050C2D95*
+ ID_OUI_FROM_DATABASE=Honeywell
+
+OUI:0050C2D96*
+ ID_OUI_FROM_DATABASE=CONTEC GmbH
+
+OUI:0050C2D97*
+ ID_OUI_FROM_DATABASE=ERS electronic GmbH
+
+OUI:0050C2D98*
+ ID_OUI_FROM_DATABASE=Rong Shun Xuan Corp.
+
+OUI:0050C2D99*
+ ID_OUI_FROM_DATABASE=T-Industry, s.r.o.
+
+OUI:0050C2D9A*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2D9B*
+ ID_OUI_FROM_DATABASE=Intuitive Surgical, Inc
+
+OUI:0050C2D9C*
+ ID_OUI_FROM_DATABASE=Gamber Johnson LLC
+
+OUI:0050C2D9D*
+ ID_OUI_FROM_DATABASE=Mistral Solutions Pvt. Ltd
+
+OUI:0050C2D9F*
+ ID_OUI_FROM_DATABASE=BitWise Controls
+
+OUI:0050C2DA0*
+ ID_OUI_FROM_DATABASE=Precision Remotes
+
+OUI:0050C2DA1*
+ ID_OUI_FROM_DATABASE=MangoDSP
+
+OUI:0050C2DA2*
+ ID_OUI_FROM_DATABASE=metraTec GmbH
+
+OUI:0050C2DA3*
+ ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS
+
+OUI:0050C2DA4*
+ ID_OUI_FROM_DATABASE=Deuta-Werke GmbH
+
+OUI:0050C2DA5*
+ ID_OUI_FROM_DATABASE=megatec electronic GmbH
+
+OUI:0050C2DA6*
+ ID_OUI_FROM_DATABASE=Manitowoc Ice
+
+OUI:0050C2DA7*
+ ID_OUI_FROM_DATABASE=Capton
+
+OUI:0050C2DA8*
+ ID_OUI_FROM_DATABASE=Sine Systems, Inc.
+
+OUI:0050C2DA9*
+ ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd
+
+OUI:0050C2DAA*
+ ID_OUI_FROM_DATABASE=M & PAUL, INC
+
+OUI:0050C2DAB*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2DAC*
+ ID_OUI_FROM_DATABASE=RFL Electronics
+
+OUI:0050C2DAD*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2DAE*
+ ID_OUI_FROM_DATABASE=Spang Power Electronics
+
+OUI:0050C2DAF*
+ ID_OUI_FROM_DATABASE=eumig industrie-tv GmbH
+
+OUI:0050C2DB0*
+ ID_OUI_FROM_DATABASE=IMAGO Technologies GmbH
+
+OUI:0050C2DB1*
+ ID_OUI_FROM_DATABASE=RF Code, Inc
+
+OUI:0050C2DB2*
+ ID_OUI_FROM_DATABASE=SoftwareCannery
+
+OUI:0050C2DB3*
+ ID_OUI_FROM_DATABASE=LAUDA DR. R. WOBSER GMBH & CO. KG
+
+OUI:0050C2DB4*
+ ID_OUI_FROM_DATABASE=ZAO NPC "Kompjuternie Technologii"
+
+OUI:0050C2DB5*
+ ID_OUI_FROM_DATABASE=DSP DESIGN LTD
+
+OUI:0050C2DB6*
+ ID_OUI_FROM_DATABASE=PROSOFT-SYSTEMS LTD
+
+OUI:0050C2DB7*
+ ID_OUI_FROM_DATABASE=SOREL GmbH Mikroelektronik
+
+OUI:0050C2DB8*
+ ID_OUI_FROM_DATABASE=Comsat VertriebsgmbH
+
+OUI:0050C2DB9*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corporation
+
+OUI:0050C2DBA*
+ ID_OUI_FROM_DATABASE=M.P. Electronics
+
+OUI:0050C2DBB*
+ ID_OUI_FROM_DATABASE=Esensors, Inc.
+
+OUI:0050C2DBC*
+ ID_OUI_FROM_DATABASE=Nantes Systems Private Limited
+
+OUI:0050C2DBD*
+ ID_OUI_FROM_DATABASE=Margento R&D
+
+OUI:0050C2DBE*
+ ID_OUI_FROM_DATABASE=WITHSYSTEM Co.,Ltd
+
+OUI:0050C2DBF*
+ ID_OUI_FROM_DATABASE=One-Nemoto Engineering Corporation
+
+OUI:0050C2DC0*
+ ID_OUI_FROM_DATABASE=Security Services Group (SSG)
+
+OUI:0050C2DC1*
+ ID_OUI_FROM_DATABASE=Acrux Technology Limited
+
+OUI:0050C2DC2*
+ ID_OUI_FROM_DATABASE=TESSERA TECHNOLOGY INC.
+
+OUI:0050C2DC3*
+ ID_OUI_FROM_DATABASE=ZED Ziegler Electronic Devices GmbH
+
+OUI:0050C2DC4*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:0050C2DC5*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2DC6*
+ ID_OUI_FROM_DATABASE=Fluid Components International
+
+OUI:0050C2DC7*
+ ID_OUI_FROM_DATABASE=AGT Holdings Limited
+
+OUI:0050C2DC8*
+ ID_OUI_FROM_DATABASE=T2M2 GmbH
+
+OUI:0050C2DC9*
+ ID_OUI_FROM_DATABASE=KinotonGmbH
+
+OUI:0050C2DCA*
+ ID_OUI_FROM_DATABASE=Tele Data Control
+
+OUI:0050C2DCB*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2DCC*
+ ID_OUI_FROM_DATABASE=Instrumentel Limited
+
+OUI:0050C2DCD*
+ ID_OUI_FROM_DATABASE=dilitronics GmbH
+
+OUI:0050C2DCE*
+ ID_OUI_FROM_DATABASE=Mecsel Oy
+
+OUI:0050C2DCF*
+ ID_OUI_FROM_DATABASE=MCS Engenharia ltda
+
+OUI:0050C2DD0*
+ ID_OUI_FROM_DATABASE=IDC Solutions Pty Ltd
+
+OUI:0050C2DD1*
+ ID_OUI_FROM_DATABASE=Dr. Ing. K. Brankamp System Prozessautomation GmbH
+
+OUI:0050C2DD2*
+ ID_OUI_FROM_DATABASE=Electronic Applications, Inc.
+
+OUI:0050C2DD3*
+ ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA
+
+OUI:0050C2DD4*
+ ID_OUI_FROM_DATABASE=SYSTECH
+
+OUI:0050C2DD5*
+ ID_OUI_FROM_DATABASE=Friend Spring Industrial Co., Ltd.
+
+OUI:0050C2DD6*
+ ID_OUI_FROM_DATABASE=Transas Marine International AB
+
+OUI:0050C2DD7*
+ ID_OUI_FROM_DATABASE=Tornado Modular Systems
+
+OUI:0050C2DD8*
+ ID_OUI_FROM_DATABASE=Selex Systems Integration Inc
+
+OUI:0050C2DD9*
+ ID_OUI_FROM_DATABASE=Metraware
+
+OUI:0050C2DDA*
+ ID_OUI_FROM_DATABASE=rbz robot design s.l.
+
+OUI:0050C2DDB*
+ ID_OUI_FROM_DATABASE=EDIXIA
+
+OUI:0050C2DDC*
+ ID_OUI_FROM_DATABASE=Vision  & Control GmbH
+
+OUI:0050C2DDD*
+ ID_OUI_FROM_DATABASE=A&A GENERAL SRL
+
+OUI:0050C2DDE*
+ ID_OUI_FROM_DATABASE=DRS RSTA
+
+OUI:0050C2DDF*
+ ID_OUI_FROM_DATABASE=Device GmbH
+
+OUI:0050C2DE0*
+ ID_OUI_FROM_DATABASE=INTERNET PROTOCOLO LOGICA SL
+
+OUI:0050C2DE1*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China)
+
+OUI:0050C2DE2*
+ ID_OUI_FROM_DATABASE=SEQUTEC INC
+
+OUI:0050C2DE3*
+ ID_OUI_FROM_DATABASE=Breakaway Systems LLC
+
+OUI:0050C2DE4*
+ ID_OUI_FROM_DATABASE=EGS Technologies Ltd
+
+OUI:0050C2DE5*
+ ID_OUI_FROM_DATABASE=Neets
+
+OUI:0050C2DE6*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C2DE7*
+ ID_OUI_FROM_DATABASE=Elan Systems
+
+OUI:0050C2DE8*
+ ID_OUI_FROM_DATABASE=Visual Productions
+
+OUI:0050C2DE9*
+ ID_OUI_FROM_DATABASE=Digatale Analoge COMponenten West Electronic Vertrieb GmbH
+
+OUI:0050C2DEA*
+ ID_OUI_FROM_DATABASE=Cerner Corporation
+
+OUI:0050C2DEB*
+ ID_OUI_FROM_DATABASE=Ruwisch & Kollegen GmbH
+
+OUI:0050C2DEC*
+ ID_OUI_FROM_DATABASE=VendNovation LLC
+
+OUI:0050C2DED*
+ ID_OUI_FROM_DATABASE=Lee Laser
+
+OUI:0050C2DEF*
+ ID_OUI_FROM_DATABASE=Powersense A/S
+
+OUI:0050C2DF0*
+ ID_OUI_FROM_DATABASE=Koncar Electrical Engineering Institute
+
+OUI:0050C2DF1*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2DF2*
+ ID_OUI_FROM_DATABASE=Instrument Concepts
+
+OUI:0050C2DF3*
+ ID_OUI_FROM_DATABASE=INSEVIS GmbH
+
+OUI:0050C2DF4*
+ ID_OUI_FROM_DATABASE=Potter Electric Signal
+
+OUI:0050C2DF5*
+ ID_OUI_FROM_DATABASE=EtherLight
+
+OUI:0050C2DF6*
+ ID_OUI_FROM_DATABASE=HINO ENGINEERING, INC
+
+OUI:0050C2DF7*
+ ID_OUI_FROM_DATABASE=Combilent
+
+OUI:0050C2DF8*
+ ID_OUI_FROM_DATABASE=Tommotek (WA) Pty Ltd.
+
+OUI:0050C2DF9*
+ ID_OUI_FROM_DATABASE=Jenny Science AG
+
+OUI:0050C2DFA*
+ ID_OUI_FROM_DATABASE=MAC Valves, Inc.
+
+OUI:0050C2DFB*
+ ID_OUI_FROM_DATABASE=BETTINI SRL
+
+OUI:0050C2DFC*
+ ID_OUI_FROM_DATABASE=I-Evo Ltd
+
+OUI:0050C2DFD*
+ ID_OUI_FROM_DATABASE=Wotbox ltd
+
+OUI:0050C2DFE*
+ ID_OUI_FROM_DATABASE=Xitek Design Limited
+
+OUI:0050C2DFF*
+ ID_OUI_FROM_DATABASE=TANTAL ELECTRONICA, SL
+
+OUI:0050C2E00*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2E01*
+ ID_OUI_FROM_DATABASE=Tyco Traffic & Transportation
+
+OUI:0050C2E02*
+ ID_OUI_FROM_DATABASE=Cleverscope
+
+OUI:0050C2E03*
+ ID_OUI_FROM_DATABASE=ICU Scandinavia Schweiz GmbH
+
+OUI:0050C2E04*
+ ID_OUI_FROM_DATABASE=Sec.Eng Systems Pty Ltd
+
+OUI:0050C2E05*
+ ID_OUI_FROM_DATABASE=NOCOSIUM
+
+OUI:0050C2E06*
+ ID_OUI_FROM_DATABASE=Ebner Electronic GmbH
+
+OUI:0050C2E07*
+ ID_OUI_FROM_DATABASE=Protagon Process Technologies GmbH
+
+OUI:0050C2E08*
+ ID_OUI_FROM_DATABASE=KST Technology
+
+OUI:0050C2E09*
+ ID_OUI_FROM_DATABASE=ATEME
+
+OUI:0050C2E0A*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:0050C2E0B*
+ ID_OUI_FROM_DATABASE=Seartech
+
+OUI:0050C2E0C*
+ ID_OUI_FROM_DATABASE=YOUHO ELECTRIC IND.,LTD.
+
+OUI:0050C2E0D*
+ ID_OUI_FROM_DATABASE=Unixmedia Srl
+
+OUI:0050C2E0E*
+ ID_OUI_FROM_DATABASE=PMAC JAPAN
+
+OUI:0050C2E0F*
+ ID_OUI_FROM_DATABASE=Trentino Systems
+
+OUI:0050C2E10*
+ ID_OUI_FROM_DATABASE=Radinetworks Co., Ltd
+
+OUI:0050C2E11*
+ ID_OUI_FROM_DATABASE=RF Neulink
+
+OUI:0050C2E12*
+ ID_OUI_FROM_DATABASE=Innolex
+
+OUI:0050C2E13*
+ ID_OUI_FROM_DATABASE=Automation Assist Japan Company
+
+OUI:0050C2E14*
+ ID_OUI_FROM_DATABASE=Calixto Systems Pvt Ltd
+
+OUI:0050C2E15*
+ ID_OUI_FROM_DATABASE=IHI Scube Co.,Ltd
+
+OUI:0050C2E16*
+ ID_OUI_FROM_DATABASE=Jetstream Ltd.
+
+OUI:0050C2E17*
+ ID_OUI_FROM_DATABASE=Gall Tankdatensysteme GmbH
+
+OUI:0050C2E18*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiamen) Co., Ltd.
+
+OUI:0050C2E19*
+ ID_OUI_FROM_DATABASE=Zoe Medical
+
+OUI:0050C2E1A*
+ ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited
+
+OUI:0050C2E1B*
+ ID_OUI_FROM_DATABASE=Embedded Labs
+
+OUI:0050C2E1C*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2E1D*
+ ID_OUI_FROM_DATABASE=Holdline Tecnologia e Sistemas Ltda
+
+OUI:0050C2E1E*
+ ID_OUI_FROM_DATABASE=Lo-Q plc
+
+OUI:0050C2E1F*
+ ID_OUI_FROM_DATABASE=ELVEES
+
+OUI:0050C2E20*
+ ID_OUI_FROM_DATABASE=Divelbiss Corporation
+
+OUI:0050C2E21*
+ ID_OUI_FROM_DATABASE=Norwia AS
+
+OUI:0050C2E22*
+ ID_OUI_FROM_DATABASE=Michael Riedel Transformatorenbau GmbH
+
+OUI:0050C2E23*
+ ID_OUI_FROM_DATABASE=VITEC
+
+OUI:0050C2E24*
+ ID_OUI_FROM_DATABASE=DiTEST Fahrzeugdiagnose GmbH
+
+OUI:0050C2E25*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C2E26*
+ ID_OUI_FROM_DATABASE=Cinetix s.r.l.
+
+OUI:0050C2E27*
+ ID_OUI_FROM_DATABASE=CONTROL SYSTEMS Srl
+
+OUI:0050C2E28*
+ ID_OUI_FROM_DATABASE=Teplovodokhran
+
+OUI:0050C2E29*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C2E2A*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:0050C2E2B*
+ ID_OUI_FROM_DATABASE=Plant Integrity Limited
+
+OUI:0050C2E2C*
+ ID_OUI_FROM_DATABASE=EN ElectronicNetwork Hamburg GmbH
+
+OUI:0050C2E2D*
+ ID_OUI_FROM_DATABASE=Funkwerk IT Karlsfeld GmbH
+
+OUI:0050C2E2E*
+ ID_OUI_FROM_DATABASE=DS! Ingenieurbuero
+
+OUI:0050C2E2F*
+ ID_OUI_FROM_DATABASE=Beam Ltd
+
+OUI:0050C2E30*
+ ID_OUI_FROM_DATABASE=Goennheimer Elektronic GmbH
+
+OUI:0050C2E31*
+ ID_OUI_FROM_DATABASE=ENSIS Co., Ltd.
+
+OUI:0050C2E32*
+ ID_OUI_FROM_DATABASE=Oshoksh Corporation
+
+OUI:0050C2E33*
+ ID_OUI_FROM_DATABASE=Morita Technical Center Company
+
+OUI:0050C2E34*
+ ID_OUI_FROM_DATABASE=HGL Dynamics
+
+OUI:0050C2E35*
+ ID_OUI_FROM_DATABASE=Omnica Corporation
+
+OUI:0050C2E36*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2E37*
+ ID_OUI_FROM_DATABASE=FUJI DATA SYSTEM Co., Ltd
+
+OUI:0050C2E38*
+ ID_OUI_FROM_DATABASE=Aesir Copenhagen
+
+OUI:0050C2E39*
+ ID_OUI_FROM_DATABASE=Telemetrics Inc.
+
+OUI:0050C2E3B*
+ ID_OUI_FROM_DATABASE=Nanosolution Inc.
+
+OUI:0050C2E3C*
+ ID_OUI_FROM_DATABASE=GRUPO EPELSA S.L.
+
+OUI:0050C2E3D*
+ ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH
+
+OUI:0050C2E3E*
+ ID_OUI_FROM_DATABASE=Monnit Corp.
+
+OUI:0050C2E3F*
+ ID_OUI_FROM_DATABASE=VISITO S.R.L. IT10346660011
+
+OUI:0050C2E40*
+ ID_OUI_FROM_DATABASE=Ecrin Systems
+
+OUI:0050C2E41*
+ ID_OUI_FROM_DATABASE=Higeco S.r.l.
+
+OUI:0050C2E42*
+ ID_OUI_FROM_DATABASE=Wings for Media SL
+
+OUI:0050C2E43*
+ ID_OUI_FROM_DATABASE=Technica Engineering GmbH
+
+OUI:0050C2E44*
+ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH
+
+OUI:0050C2E45*
+ ID_OUI_FROM_DATABASE=Stichting Sunrise
+
+OUI:0050C2E46*
+ ID_OUI_FROM_DATABASE=Industrea Mining Technology
+
+OUI:0050C2E47*
+ ID_OUI_FROM_DATABASE=ENIKA.CZ
+
+OUI:0050C2E48*
+ ID_OUI_FROM_DATABASE=ITW Reyflex North America
+
+OUI:0050C2E49*
+ ID_OUI_FROM_DATABASE=CTF TECHNOLOGIES DO BRASIL LTDA
+
+OUI:0050C2E4A*
+ ID_OUI_FROM_DATABASE=GHL Systems Bhd
+
+OUI:0050C2E4B*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:0050C2E4C*
+ ID_OUI_FROM_DATABASE=Applied Micro Electronics "AME" BV
+
+OUI:0050C2E4D*
+ ID_OUI_FROM_DATABASE=PCSC
+
+OUI:0050C2E4E*
+ ID_OUI_FROM_DATABASE=Institute For Information Industry
+
+OUI:0050C2E4F*
+ ID_OUI_FROM_DATABASE=Wine Technology Marlborough
+
+OUI:0050C2E50*
+ ID_OUI_FROM_DATABASE=Tattile srl
+
+OUI:0050C2E51*
+ ID_OUI_FROM_DATABASE=Motec Pty Ltd
+
+OUI:0050C2E52*
+ ID_OUI_FROM_DATABASE=Famas System S.p.A.
+
+OUI:0050C2E53*
+ ID_OUI_FROM_DATABASE=NEXT video systems Hard- and Software Development GmbH
+
+OUI:0050C2E54*
+ ID_OUI_FROM_DATABASE=Arcos Technologies LTD
+
+OUI:0050C2E55*
+ ID_OUI_FROM_DATABASE=TTi Ltd
+
+OUI:0050C2E56*
+ ID_OUI_FROM_DATABASE=RFENGINE CO., LTD.
+
+OUI:0050C2E57*
+ ID_OUI_FROM_DATABASE=EOLANE MONTCEAU
+
+OUI:0050C2E58*
+ ID_OUI_FROM_DATABASE=Agri-hitech LLC
+
+OUI:0050C2E59*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2E5A*
+ ID_OUI_FROM_DATABASE=FUTEC INC.
+
+OUI:0050C2E5B*
+ ID_OUI_FROM_DATABASE=CAIPO Automazione Industriale s.r.l.
+
+OUI:0050C2E5C*
+ ID_OUI_FROM_DATABASE=MCOPIA Co., Ltd
+
+OUI:0050C2E5D*
+ ID_OUI_FROM_DATABASE=T8 Ltd
+
+OUI:0050C2E5E*
+ ID_OUI_FROM_DATABASE=OREP
+
+OUI:0050C2E5F*
+ ID_OUI_FROM_DATABASE=Pantec Engineering AG
+
+OUI:0050C2E60*
+ ID_OUI_FROM_DATABASE=TAIYO SEIKI CO.,LTD.
+
+OUI:0050C2E61*
+ ID_OUI_FROM_DATABASE=Detech Electronics ApS
+
+OUI:0050C2E62*
+ ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG
+
+OUI:0050C2E63*
+ ID_OUI_FROM_DATABASE=Prima sistemi
+
+OUI:0050C2E64*
+ ID_OUI_FROM_DATABASE=Edgeware AB
+
+OUI:0050C2E65*
+ ID_OUI_FROM_DATABASE=IB Elektronik GmbH
+
+OUI:0050C2E66*
+ ID_OUI_FROM_DATABASE=EMAC, Inc.
+
+OUI:0050C2E67*
+ ID_OUI_FROM_DATABASE=Critical Link, LLC
+
+OUI:0050C2E68*
+ ID_OUI_FROM_DATABASE=Kyoritsu Electric Corporation
+
+OUI:0050C2E69*
+ ID_OUI_FROM_DATABASE=Netmaker
+
+OUI:0050C2E6A*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2E6B*
+ ID_OUI_FROM_DATABASE=Sika Technology AG
+
+OUI:0050C2E6C*
+ ID_OUI_FROM_DATABASE=SAMSUNG LED Co.,Ltd.
+
+OUI:0050C2E6D*
+ ID_OUI_FROM_DATABASE=Allerta Inc
+
+OUI:0050C2E6E*
+ ID_OUI_FROM_DATABASE=Power-One Italia S.p.A
+
+OUI:0050C2E6F*
+ ID_OUI_FROM_DATABASE=Leyden Engineering
+
+OUI:0050C2E70*
+ ID_OUI_FROM_DATABASE=DORLET S.A.
+
+OUI:0050C2E71*
+ ID_OUI_FROM_DATABASE=traffic network solutions s.l
+
+OUI:0050C2E73*
+ ID_OUI_FROM_DATABASE=ACS Motion Control Ltd.
+
+OUI:0050C2E74*
+ ID_OUI_FROM_DATABASE=Will corp.
+
+OUI:0050C2E75*
+ ID_OUI_FROM_DATABASE=FSM Elektronik GmbH
+
+OUI:0050C2E76*
+ ID_OUI_FROM_DATABASE=Embedded Solution Bank Co., Ltd.
+
+OUI:0050C2E77*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:0050C2E78*
+ ID_OUI_FROM_DATABASE=TASK SISTEMAS DE COMPUTACAO LTDA
+
+OUI:0050C2E79*
+ ID_OUI_FROM_DATABASE=MCS MICRONIC Computer Systeme GmbH
+
+OUI:0050C2E7A*
+ ID_OUI_FROM_DATABASE=Lightel
+
+OUI:0050C2E7B*
+ ID_OUI_FROM_DATABASE=ATOM GIKEN Co.,Ltd.
+
+OUI:0050C2E7C*
+ ID_OUI_FROM_DATABASE=sp controls, inc
+
+OUI:0050C2E7D*
+ ID_OUI_FROM_DATABASE=AEL Microsystems Limited
+
+OUI:0050C2E7E*
+ ID_OUI_FROM_DATABASE=Swareflex GmbH
+
+OUI:0050C2E7F*
+ ID_OUI_FROM_DATABASE=LS Control A/S
+
+OUI:0050C2E80*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2E81*
+ ID_OUI_FROM_DATABASE=Adaptive Technologies, Inc.
+
+OUI:0050C2E82*
+ ID_OUI_FROM_DATABASE=Xplore Technologies Corp
+
+OUI:0050C2E83*
+ ID_OUI_FROM_DATABASE=Witree Co.,Ltd
+
+OUI:0050C2E84*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiamen) Co., Ltd.
+
+OUI:0050C2E85*
+ ID_OUI_FROM_DATABASE=Cosmo Life Co.,Ltd
+
+OUI:0050C2E86*
+ ID_OUI_FROM_DATABASE=Multisuns Corporation
+
+OUI:0050C2E87*
+ ID_OUI_FROM_DATABASE=Lamson Safes & Security
+
+OUI:0050C2E88*
+ ID_OUI_FROM_DATABASE=Pivitec, LLC
+
+OUI:0050C2E89*
+ ID_OUI_FROM_DATABASE=PROTEQSEN
+
+OUI:0050C2E8A*
+ ID_OUI_FROM_DATABASE=Macronet s.r.l.
+
+OUI:0050C2E8B*
+ ID_OUI_FROM_DATABASE=RPA Electronic Solutions, Inc.
+
+OUI:0050C2E8C*
+ ID_OUI_FROM_DATABASE=Epec Oy
+
+OUI:0050C2E8D*
+ ID_OUI_FROM_DATABASE=SystemAdvanced Co,Ltd
+
+OUI:0050C2E8E*
+ ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS
+
+OUI:0050C2E8F*
+ ID_OUI_FROM_DATABASE=STT Condigi A/S
+
+OUI:0050C2E90*
+ ID_OUI_FROM_DATABASE=GS Elektromedizinische Geraete G. Stemple GmbH
+
+OUI:0050C2E91*
+ ID_OUI_FROM_DATABASE=DSP DESIGN LTD
+
+OUI:0050C2E92*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2E93*
+ ID_OUI_FROM_DATABASE=Perceptive Pixel Inc.
+
+OUI:0050C2E94*
+ ID_OUI_FROM_DATABASE=ANA-U GmbH
+
+OUI:0050C2E95*
+ ID_OUI_FROM_DATABASE=Dlite Comercio, Importadora e Serviços de Automação Ltda
+
+OUI:0050C2E96*
+ ID_OUI_FROM_DATABASE=PROYECSON S.A.
+
+OUI:0050C2E97*
+ ID_OUI_FROM_DATABASE=Arista Systems Corporation
+
+OUI:0050C2E98*
+ ID_OUI_FROM_DATABASE=i3 International Inc.
+
+OUI:0050C2E99*
+ ID_OUI_FROM_DATABASE=UV Networks, Inc.
+
+OUI:0050C2E9A*
+ ID_OUI_FROM_DATABASE=Solace Systems
+
+OUI:0050C2E9B*
+ ID_OUI_FROM_DATABASE=Hentschel System GmbH
+
+OUI:0050C2E9C*
+ ID_OUI_FROM_DATABASE=SPARQ systems
+
+OUI:0050C2E9D*
+ ID_OUI_FROM_DATABASE=nicai-systems
+
+OUI:0050C2E9E*
+ ID_OUI_FROM_DATABASE=American Microsystems, Ltd.
+
+OUI:0050C2E9F*
+ ID_OUI_FROM_DATABASE=DataSoft Corporation
+
+OUI:0050C2EA0*
+ ID_OUI_FROM_DATABASE=Robert Bosch Healthcare, Inc.
+
+OUI:0050C2EA1*
+ ID_OUI_FROM_DATABASE=TEX COMPUTER SRL
+
+OUI:0050C2EA2*
+ ID_OUI_FROM_DATABASE=ThinkRF Corp
+
+OUI:0050C2EA3*
+ ID_OUI_FROM_DATABASE=Subsea Systems, Inc.
+
+OUI:0050C2EA4*
+ ID_OUI_FROM_DATABASE=head
+
+OUI:0050C2EA5*
+ ID_OUI_FROM_DATABASE=Aerodata AG
+
+OUI:0050C2EA6*
+ ID_OUI_FROM_DATABASE=Powersense A/S
+
+OUI:0050C2EA7*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2EA8*
+ ID_OUI_FROM_DATABASE=MB Connect Line GmbH
+
+OUI:0050C2EA9*
+ ID_OUI_FROM_DATABASE=METTLER-TOLEDO HI-SPEED
+
+OUI:0050C2EAA*
+ ID_OUI_FROM_DATABASE=BAE Systems
+
+OUI:0050C2EAB*
+ ID_OUI_FROM_DATABASE=Warp9 Tech Design, Inc.
+
+OUI:0050C2EAC*
+ ID_OUI_FROM_DATABASE=Alias ip
+
+OUI:0050C2EAD*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:0050C2EAE*
+ ID_OUI_FROM_DATABASE=Alyrica Networks
+
+OUI:0050C2EAF*
+ ID_OUI_FROM_DATABASE=Aircell
+
+OUI:0050C2EB0*
+ ID_OUI_FROM_DATABASE=Pulse Communication Systems Pvt. Ltd.
+
+OUI:0050C2EB1*
+ ID_OUI_FROM_DATABASE=PDU EXPERT UK LTD
+
+OUI:0050C2EB2*
+ ID_OUI_FROM_DATABASE=Otaki Electric Corporation
+
+OUI:0050C2EB3*
+ ID_OUI_FROM_DATABASE=AR RF/Microwave Instrumentation
+
+OUI:0050C2EB4*
+ ID_OUI_FROM_DATABASE=Wishtek Technology, Inc.
+
+OUI:0050C2EB5*
+ ID_OUI_FROM_DATABASE=Covidence A/S
+
+OUI:0050C2EB6*
+ ID_OUI_FROM_DATABASE=Monsoon Solutions, Inc.
+
+OUI:0050C2EB7*
+ ID_OUI_FROM_DATABASE=Saab AB
+
+OUI:0050C2EB8*
+ ID_OUI_FROM_DATABASE=dspnor
+
+OUI:0050C2EB9*
+ ID_OUI_FROM_DATABASE=ALPHA-MOS
+
+OUI:0050C2EBA*
+ ID_OUI_FROM_DATABASE=West-Com Nurse Call Systems, Inc.
+
+OUI:0050C2EBB*
+ ID_OUI_FROM_DATABASE=TimeTerminal Adductor Group AB
+
+OUI:0050C2EBC*
+ ID_OUI_FROM_DATABASE=Diehl AKO Stiftung & Co. KG
+
+OUI:0050C2EBD*
+ ID_OUI_FROM_DATABASE=Droplet Measurement Technologies
+
+OUI:0050C2EBE*
+ ID_OUI_FROM_DATABASE=Global Tecnologia LTDA.
+
+OUI:0050C2EBF*
+ ID_OUI_FROM_DATABASE=CIVOLUTION
+
+OUI:0050C2EC0*
+ ID_OUI_FROM_DATABASE=UgMO Technologies
+
+OUI:0050C2EC1*
+ ID_OUI_FROM_DATABASE=ANT Group s.r.l
+
+OUI:0050C2EC2*
+ ID_OUI_FROM_DATABASE=Ixonos Finland Ltd
+
+OUI:0050C2EC3*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2EC4*
+ ID_OUI_FROM_DATABASE=Logical Electromechanical Sys Inc.
+
+OUI:0050C2EC5*
+ ID_OUI_FROM_DATABASE=RSUPPORT Co., Ltd.
+
+OUI:0050C2EC6*
+ ID_OUI_FROM_DATABASE=INFRONICS SYSTEMS LIMITED
+
+OUI:0050C2EC7*
+ ID_OUI_FROM_DATABASE=LIQUID ROBOTICS, INC
+
+OUI:0050C2EC8*
+ ID_OUI_FROM_DATABASE=IBERNEX INGENIERIA, S.L.
+
+OUI:0050C2EC9*
+ ID_OUI_FROM_DATABASE=Amsterdam Scientific Instruments BV
+
+OUI:0050C2ECA*
+ ID_OUI_FROM_DATABASE=BitWise Controls
+
+OUI:0050C2ECB*
+ ID_OUI_FROM_DATABASE=FAL Corp
+
+OUI:0050C2ECC*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2ECD*
+ ID_OUI_FROM_DATABASE=Peek Traffic Corporation
+
+OUI:0050C2ECE*
+ ID_OUI_FROM_DATABASE=easii ic adiis
+
+OUI:0050C2ECF*
+ ID_OUI_FROM_DATABASE=TAIWAN HIPLUS CORPORATION
+
+OUI:0050C2ED0*
+ ID_OUI_FROM_DATABASE=Nippon Systemware Co.,Ltd.
+
+OUI:0050C2ED1*
+ ID_OUI_FROM_DATABASE=Arcontia Technology AB
+
+OUI:0050C2ED2*
+ ID_OUI_FROM_DATABASE=Klangspektrum GmbH
+
+OUI:0050C2ED3*
+ ID_OUI_FROM_DATABASE=ECO MONITORING UTILITY SYSTEMS LTD
+
+OUI:0050C2ED4*
+ ID_OUI_FROM_DATABASE=TAMAGAWA ELECTRONICS CO.,LTD.
+
+OUI:0050C2ED5*
+ ID_OUI_FROM_DATABASE=RFL Electronics Inc.
+
+OUI:0050C2ED6*
+ ID_OUI_FROM_DATABASE=Cat AB
+
+OUI:0050C2ED7*
+ ID_OUI_FROM_DATABASE=FBT Elettronica spa
+
+OUI:0050C2ED8*
+ ID_OUI_FROM_DATABASE=AVocation Systems, Inc.
+
+OUI:0050C2ED9*
+ ID_OUI_FROM_DATABASE=Plasmatronics pty ltd
+
+OUI:0050C2EDA*
+ ID_OUI_FROM_DATABASE=Joint Stock Company "Svyaz Inginiring M"
+
+OUI:0050C2EDB*
+ ID_OUI_FROM_DATABASE=BELIK S.P.R.L.
+
+OUI:0050C2EDC*
+ ID_OUI_FROM_DATABASE=Eyelock Corporation
+
+OUI:0050C2EDD*
+ ID_OUI_FROM_DATABASE=EBNEURO SPA
+
+OUI:0050C2EDE*
+ ID_OUI_FROM_DATABASE=Smart Grid Networks
+
+OUI:0050C2EDF*
+ ID_OUI_FROM_DATABASE=Monitor Business Machines
+
+OUI:0050C2EE0*
+ ID_OUI_FROM_DATABASE=osf Hansjuergen Meier GmbH & Co. KG
+
+OUI:0050C2EE1*
+ ID_OUI_FROM_DATABASE=Procon Electronics Pty Ltd
+
+OUI:0050C2EE2*
+ ID_OUI_FROM_DATABASE=System Industrie Electronic GmbH
+
+OUI:0050C2EE3*
+ ID_OUI_FROM_DATABASE=Tecnint HTE Srl
+
+OUI:0050C2EE4*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:0050C2EE5*
+ ID_OUI_FROM_DATABASE=Cytec Zylindertechnik GmbH
+
+OUI:0050C2EE6*
+ ID_OUI_FROM_DATABASE=B:TECH, a. s.
+
+OUI:0050C2EE7*
+ ID_OUI_FROM_DATABASE=Syes srl
+
+OUI:0050C2EE8*
+ ID_OUI_FROM_DATABASE=Kamacho Scale Co., Ltd.
+
+OUI:0050C2EE9*
+ ID_OUI_FROM_DATABASE=QUANTA S.r.l.
+
+OUI:0050C2EEA*
+ ID_OUI_FROM_DATABASE=Positioneering Limited
+
+OUI:0050C2EEB*
+ ID_OUI_FROM_DATABASE=fibrisTerre GmbH
+
+OUI:0050C2EEC*
+ ID_OUI_FROM_DATABASE=Yuyama Mfg. Co., Ltd.
+
+OUI:0050C2EED*
+ ID_OUI_FROM_DATABASE=Future Design Controls, Inc
+
+OUI:0050C2EEE*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiamen) Co., Ltd
+
+OUI:0050C2EEF*
+ ID_OUI_FROM_DATABASE=IDTRONIC GmbH
+
+OUI:0050C2EF0*
+ ID_OUI_FROM_DATABASE=Homaetrix Ltd
+
+OUI:0050C2EF1*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2EF2*
+ ID_OUI_FROM_DATABASE=Specialty Microwave Corp
+
+OUI:0050C2EF3*
+ ID_OUI_FROM_DATABASE=Smart Power Electronics GmbH & Co. KG
+
+OUI:0050C2EF4*
+ ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A
+
+OUI:0050C2EF5*
+ ID_OUI_FROM_DATABASE=Human Network Labs, Inc.
+
+OUI:0050C2EF6*
+ ID_OUI_FROM_DATABASE=Netline Communication Technologies
+
+OUI:0050C2EF7*
+ ID_OUI_FROM_DATABASE=Amstelland Electronic BV
+
+OUI:0050C2EF8*
+ ID_OUI_FROM_DATABASE=HCL Technologies
+
+OUI:0050C2EF9*
+ ID_OUI_FROM_DATABASE=HORIBA ABX
+
+OUI:0050C2EFA*
+ ID_OUI_FROM_DATABASE=Predictive Sensor Technology
+
+OUI:0050C2EFB*
+ ID_OUI_FROM_DATABASE=Norbit ODM AS
+
+OUI:0050C2EFD*
+ ID_OUI_FROM_DATABASE=Sanmina-SCI
+
+OUI:0050C2EFE*
+ ID_OUI_FROM_DATABASE=PLR Information Systems Ltd.
+
+OUI:0050C2EFF*
+ ID_OUI_FROM_DATABASE=Zephyrus Electronics LTD.
+
+OUI:0050C2F00*
+ ID_OUI_FROM_DATABASE=Syscom Instruments
+
+OUI:0050C2F01*
+ ID_OUI_FROM_DATABASE=Mango DSP, Inc
+
+OUI:0050C2F02*
+ ID_OUI_FROM_DATABASE=BMR
+
+OUI:0050C2F03*
+ ID_OUI_FROM_DATABASE=Wren Sound Systems
+
+OUI:0050C2F04*
+ ID_OUI_FROM_DATABASE=KINKI ROENTGEN INDUSTRIAL CO.,LTD
+
+OUI:0050C2F05*
+ ID_OUI_FROM_DATABASE=ESI Ventures
+
+OUI:0050C2F06*
+ ID_OUI_FROM_DATABASE=Micro-Key BV
+
+OUI:0050C2F07*
+ ID_OUI_FROM_DATABASE=Icon Research Ltd
+
+OUI:0050C2F08*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2F09*
+ ID_OUI_FROM_DATABASE=Wheatstone Corporation
+
+OUI:0050C2F0A*
+ ID_OUI_FROM_DATABASE=HASCOM International Pty Ltd
+
+OUI:0050C2F0B*
+ ID_OUI_FROM_DATABASE=Treehaven Technologies, Inc.
+
+OUI:0050C2F0C*
+ ID_OUI_FROM_DATABASE=SKYCHANNEL LTD
+
+OUI:0050C2F0D*
+ ID_OUI_FROM_DATABASE=Bluetest AB
+
+OUI:0050C2F0E*
+ ID_OUI_FROM_DATABASE=Micro Technic A/S
+
+OUI:0050C2F0F*
+ ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc.
+
+OUI:0050C2F10*
+ ID_OUI_FROM_DATABASE=Wincor Nixdorf Sp. z o.o.
+
+OUI:0050C2F11*
+ ID_OUI_FROM_DATABASE=Organis GmbH
+
+OUI:0050C2F12*
+ ID_OUI_FROM_DATABASE=General Industrial Controls Pvt Ltd
+
+OUI:0050C2F13*
+ ID_OUI_FROM_DATABASE=Packet Plus, Inc.
+
+OUI:0050C2F14*
+ ID_OUI_FROM_DATABASE=VISION SYSTEMS AERONAUTIC
+
+OUI:0050C2F15*
+ ID_OUI_FROM_DATABASE=Sascal Displays Ltd
+
+OUI:0050C2F16*
+ ID_OUI_FROM_DATABASE=Peter Huber Kältemaschinenbau GmbH
+
+OUI:0050C2F17*
+ ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiamen) Co., Ltd
+
+OUI:0050C2F18*
+ ID_OUI_FROM_DATABASE=Vitec Multimedia
+
+OUI:0050C2F19*
+ ID_OUI_FROM_DATABASE=Netlink Bilisim Sistemleri San. ve Tic. Ltd. Sti.
+
+OUI:0050C2F1A*
+ ID_OUI_FROM_DATABASE=Aqua Management
+
+OUI:0050C2F1B*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2F1C*
+ ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS
+
+OUI:0050C2F1D*
+ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
+
+OUI:0050C2F1E*
+ ID_OUI_FROM_DATABASE=Dell'Orto S.P.A.
+
+OUI:0050C2F1F*
+ ID_OUI_FROM_DATABASE=Verified Energy, LLC.
+
+OUI:0050C2F20*
+ ID_OUI_FROM_DATABASE=Unfors Instruments AB
+
+OUI:0050C2F21*
+ ID_OUI_FROM_DATABASE=SEITEC Co. Ltd
+
+OUI:0050C2F22*
+ ID_OUI_FROM_DATABASE=Harland Simon plc
+
+OUI:0050C2F23*
+ ID_OUI_FROM_DATABASE=Electro Motive Diesel
+
+OUI:0050C2F24*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2F25*
+ ID_OUI_FROM_DATABASE=Samway Electronic SRL
+
+OUI:0050C2F26*
+ ID_OUI_FROM_DATABASE=WaveIP
+
+OUI:0050C2F27*
+ ID_OUI_FROM_DATABASE=ELAN SYSTEMS
+
+OUI:0050C2F28*
+ ID_OUI_FROM_DATABASE=Vertex Antennentechnik GmbH
+
+OUI:0050C2F29*
+ ID_OUI_FROM_DATABASE=RADYNE CORPORATION
+
+OUI:0050C2F2A*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C2F2B*
+ ID_OUI_FROM_DATABASE=Bio Guard component & technologies
+
+OUI:0050C2F2C*
+ ID_OUI_FROM_DATABASE=Terratel Technology s.r.o.
+
+OUI:0050C2F2D*
+ ID_OUI_FROM_DATABASE=Robert Bosch Healthcare Systems, Inc.
+
+OUI:0050C2F2E*
+ ID_OUI_FROM_DATABASE=H&L Instruments, LLC
+
+OUI:0050C2F2F*
+ ID_OUI_FROM_DATABASE=Arcos Technologies LTD
+
+OUI:0050C2F30*
+ ID_OUI_FROM_DATABASE=Miris AB
+
+OUI:0050C2F31*
+ ID_OUI_FROM_DATABASE=Ruetz Technologies GmbH
+
+OUI:0050C2F32*
+ ID_OUI_FROM_DATABASE=Net4Things
+
+OUI:0050C2F33*
+ ID_OUI_FROM_DATABASE=Applied Micro Electronics "AME" BV
+
+OUI:0050C2F34*
+ ID_OUI_FROM_DATABASE=Sequip S+E GmbH
+
+OUI:0050C2F35*
+ ID_OUI_FROM_DATABASE=GRUPO EPELSA S.L.
+
+OUI:0050C2F36*
+ ID_OUI_FROM_DATABASE=Visitech AS
+
+OUI:0050C2F37*
+ ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited
+
+OUI:0050C2F38*
+ ID_OUI_FROM_DATABASE=AeroControl, Inc.
+
+OUI:0050C2F39*
+ ID_OUI_FROM_DATABASE=Inforce Computing, Inc.
+
+OUI:0050C2F3A*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2F3B*
+ ID_OUI_FROM_DATABASE=TAMS firmware co.
+
+OUI:0050C2F3C*
+ ID_OUI_FROM_DATABASE=Vemco Sp. z o. o.
+
+OUI:0050C2F3D*
+ ID_OUI_FROM_DATABASE=Project service S.a.s
+
+OUI:0050C2F3E*
+ ID_OUI_FROM_DATABASE=Vtron Pty Ltd
+
+OUI:0050C2F3F*
+ ID_OUI_FROM_DATABASE=DENSEI COMMUNICATION Inc.
+
+OUI:0050C2F40*
+ ID_OUI_FROM_DATABASE=iBWorld co.,ltd.
+
+OUI:0050C2F41*
+ ID_OUI_FROM_DATABASE=FairyDevices Inc.
+
+OUI:0050C2F42*
+ ID_OUI_FROM_DATABASE=DSPCon
+
+OUI:0050C2F43*
+ ID_OUI_FROM_DATABASE=Special Systems Engineering Center LLC
+
+OUI:0050C2F44*
+ ID_OUI_FROM_DATABASE=Steinbichler Optotechnik GmbH
+
+OUI:0050C2F45*
+ ID_OUI_FROM_DATABASE=HUSTY M.Styczen J.Hupert Sp.J.
+
+OUI:0050C2F46*
+ ID_OUI_FROM_DATABASE=Reason Tecnologia S.A.
+
+OUI:0050C2F47*
+ ID_OUI_FROM_DATABASE=cadac,inc.
+
+OUI:0050C2F48*
+ ID_OUI_FROM_DATABASE=Midas Technology DBA Phoenix Audio Technologies
+
+OUI:0050C2F49*
+ ID_OUI_FROM_DATABASE=Green Instruments A/S
+
+OUI:0050C2F4A*
+ ID_OUI_FROM_DATABASE=Z-App Systems, Inc.
+
+OUI:0050C2F4B*
+ ID_OUI_FROM_DATABASE=Supranet
+
+OUI:0050C2F4C*
+ ID_OUI_FROM_DATABASE=Enistic Limited
+
+OUI:0050C2F4D*
+ ID_OUI_FROM_DATABASE=KNOWHOW INFOCOM INC.
+
+OUI:0050C2F4E*
+ ID_OUI_FROM_DATABASE=Heinzinger electronic GmbH
+
+OUI:0050C2F4F*
+ ID_OUI_FROM_DATABASE=BAP Precision Ltd.
+
+OUI:0050C2F50*
+ ID_OUI_FROM_DATABASE=Moritex Corporation
+
+OUI:0050C2F51*
+ ID_OUI_FROM_DATABASE=NDC Infrared Engineering, Inc.
+
+OUI:0050C2F52*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:0050C2F53*
+ ID_OUI_FROM_DATABASE=BAYCOM OPTO-ELECTRONICS TECHNOLOGY CO.,LTD.
+
+OUI:0050C2F54*
+ ID_OUI_FROM_DATABASE=Hella Gutmann Solutions GmbH
+
+OUI:0050C2F55*
+ ID_OUI_FROM_DATABASE=Honeywell International Inc.
+
+OUI:0050C2F56*
+ ID_OUI_FROM_DATABASE=Monsoon Solutions, Inc.
+
+OUI:0050C2F57*
+ ID_OUI_FROM_DATABASE=Reach Technologies Inc.
+
+OUI:0050C2F58*
+ ID_OUI_FROM_DATABASE=IEEE-SA
+
+OUI:0050C2F59*
+ ID_OUI_FROM_DATABASE=G3 Technologies
+
+OUI:0050C2F5A*
+ ID_OUI_FROM_DATABASE=Sentry 360 Security
+
+OUI:0050C2F5B*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:0050C2F5C*
+ ID_OUI_FROM_DATABASE=DSP DESIGN LTD
+
+OUI:0050C2F5D*
+ ID_OUI_FROM_DATABASE=SMARTB TECHNOLOGIES
+
+OUI:0050C2F5E*
+ ID_OUI_FROM_DATABASE=Y-cam Solutions Ltd
+
+OUI:0050C2F5F*
+ ID_OUI_FROM_DATABASE=BORYEU TECHNOLOGY CO.,LTD
+
+OUI:0050C2F60*
+ ID_OUI_FROM_DATABASE=Deckma GmbH
+
+OUI:0050C2F61*
+ ID_OUI_FROM_DATABASE=Brauch Elektronik GmbH&Co.KG
+
+OUI:0050C2F62*
+ ID_OUI_FROM_DATABASE=EMAC, Inc.
+
+OUI:0050C2F63*
+ ID_OUI_FROM_DATABASE=Triax A/S
+
+OUI:0050C2F64*
+ ID_OUI_FROM_DATABASE=Chrisso Technologies LLC
+
+OUI:0050C2F65*
+ ID_OUI_FROM_DATABASE=Telebyte Inc.
+
+OUI:0050C2F66*
+ ID_OUI_FROM_DATABASE=GWT LLC
+
+OUI:0050C2F67*
+ ID_OUI_FROM_DATABASE=Celestial Audio
+
+OUI:0050C2F68*
+ ID_OUI_FROM_DATABASE=NEWTEC A/S
+
+OUI:0050C2F69*
+ ID_OUI_FROM_DATABASE=Safe Place Solutions Ltd
+
+OUI:0050C2F6A*
+ ID_OUI_FROM_DATABASE=OFI Inc. (dba 2D2C)
+
+OUI:0050C2F6B*
+ ID_OUI_FROM_DATABASE=Algodue Elettronica Srl
+
+OUI:0050C2F6C*
+ ID_OUI_FROM_DATABASE=Pro Design Electronic GmbH
+
+OUI:0050C2F6D*
+ ID_OUI_FROM_DATABASE=Pro Design Electronic GmbH
+
+OUI:0050C2F6E*
+ ID_OUI_FROM_DATABASE=Smith Meter, Inc.
+
+OUI:0050C2F6F*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2F70*
+ ID_OUI_FROM_DATABASE=Noralta Technologies Inc
+
+OUI:0050C2F71*
+ ID_OUI_FROM_DATABASE=RF CODE, INC
+
+OUI:0050C2F72*
+ ID_OUI_FROM_DATABASE=MaxDeTec AG
+
+OUI:0050C2F73*
+ ID_OUI_FROM_DATABASE=DELTACAST.TV
+
+OUI:0050C2F74*
+ ID_OUI_FROM_DATABASE=Thor Technologies Pty Ltd
+
+OUI:0050C2F75*
+ ID_OUI_FROM_DATABASE=PumpWell Solutions Ltd.
+
+OUI:0050C2F76*
+ ID_OUI_FROM_DATABASE=Rong Jie(FuZhou)Electronics Co.,Ltd
+
+OUI:0050C2F77*
+ ID_OUI_FROM_DATABASE=SYSTEMTECHNIK GmbH
+
+OUI:0050C2F78*
+ ID_OUI_FROM_DATABASE=Gets MSS S.A.
+
+OUI:0050C2F79*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:0050C2F7A*
+ ID_OUI_FROM_DATABASE=C3 LLC
+
+OUI:0050C2F7B*
+ ID_OUI_FROM_DATABASE=MCM Electronics
+
+OUI:0050C2F7C*
+ ID_OUI_FROM_DATABASE=Atonometrics, Inc.
+
+OUI:0050C2F7D*
+ ID_OUI_FROM_DATABASE=D-Hike Electroncs Technology Co.,Ltd
+
+OUI:0050C2F7E*
+ ID_OUI_FROM_DATABASE=TruTeq Wireless (Pty) Ltd
+
+OUI:0050C2F7F*
+ ID_OUI_FROM_DATABASE=Dynamic Design
+
+OUI:0050C2F80*
+ ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH
+
+OUI:0050C2F81*
+ ID_OUI_FROM_DATABASE=PLDA
+
+OUI:0050C2F82*
+ ID_OUI_FROM_DATABASE=Sincair Systems International
+
+OUI:0050C2F83*
+ ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH
+
+OUI:0050C2F84*
+ ID_OUI_FROM_DATABASE=Dynon Instruments
+
+OUI:0050C2F85*
+ ID_OUI_FROM_DATABASE=Enetics, Inc.
+
+OUI:0050C2F86*
+ ID_OUI_FROM_DATABASE=Audio Power Labs
+
+OUI:0050C2F87*
+ ID_OUI_FROM_DATABASE=Vaisala Oyj
+
+OUI:0050C2F88*
+ ID_OUI_FROM_DATABASE=RTC Manufacturing Inc.
+
+OUI:0050C2F89*
+ ID_OUI_FROM_DATABASE=CSA Engineering AG
+
+OUI:0050C2F8A*
+ ID_OUI_FROM_DATABASE=EMAC, Inc.
+
+OUI:0050C2F8B*
+ ID_OUI_FROM_DATABASE=Comlet Verteilte Systeme GmbH
+
+OUI:0050C2F8C*
+ ID_OUI_FROM_DATABASE=UBSTechnology Co., Ltd
+
+OUI:0050C2F8D*
+ ID_OUI_FROM_DATABASE=GUANGDONG EAST POWER CO.,LTD.
+
+OUI:0050C2F8E*
+ ID_OUI_FROM_DATABASE=GPO
+
+OUI:0050C2F8F*
+ ID_OUI_FROM_DATABASE=Computerwise, Inc.
+
+OUI:0050C2F90*
+ ID_OUI_FROM_DATABASE=SecureTech Systems, Inc.
+
+OUI:0050C2F91*
+ ID_OUI_FROM_DATABASE=RE2 Inc
+
+OUI:0050C2F92*
+ ID_OUI_FROM_DATABASE=CONET Solutions GmbH
+
+OUI:0050C2F93*
+ ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH
+
+OUI:0050C2F94*
+ ID_OUI_FROM_DATABASE=Digital Barriers
+
+OUI:0050C2F95*
+ ID_OUI_FROM_DATABASE=TTi LTD (Thurlby Thandar Instruments LTD)
+
+OUI:0050C2F96*
+ ID_OUI_FROM_DATABASE=JLCooper Electronics
+
+OUI:0050C2F97*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:0050C2F98*
+ ID_OUI_FROM_DATABASE=Infotech North America
+
+OUI:0050C2F99*
+ ID_OUI_FROM_DATABASE=Dr. Neumann elektronik GmbH
+
+OUI:0050C2F9A*
+ ID_OUI_FROM_DATABASE=Telvent
+
+OUI:0050C2F9B*
+ ID_OUI_FROM_DATABASE=NEWELL TECHNOLOGIES LIMITED
+
+OUI:0050C2F9C*
+ ID_OUI_FROM_DATABASE=R&D KOMETEH
+
+OUI:0050C2F9D*
+ ID_OUI_FROM_DATABASE=JSC "Kaluga Teletypes Manufacturing Plant"
+
+OUI:0050C2F9E*
+ ID_OUI_FROM_DATABASE=Matsusada Precision Inc.
+
+OUI:0050C2F9F*
+ ID_OUI_FROM_DATABASE=Nanjing SAC Power Grid Automation Co., Ltd.
+
+OUI:0050C2FA0*
+ ID_OUI_FROM_DATABASE=Amplus Communication Pte Ltd
+
+OUI:0050C2FA1*
+ ID_OUI_FROM_DATABASE=N-Hands GmbH und Co KG
+
+OUI:0050C2FA2*
+ ID_OUI_FROM_DATABASE=Power-One
+
+OUI:0050C2FA3*
+ ID_OUI_FROM_DATABASE=Xemex NV
+
+OUI:0050C2FA5*
+ ID_OUI_FROM_DATABASE=Intuitive Surgical, Inc.
+
+OUI:0050C2FA6*
+ ID_OUI_FROM_DATABASE=Hilkom digital GmbH
+
+OUI:0050C2FA7*
+ ID_OUI_FROM_DATABASE=Exelis Inc.
+
+OUI:0050C2FA8*
+ ID_OUI_FROM_DATABASE=Yash SiQure Technologies India Pvt. Ltd.
+
+OUI:0050C2FA9*
+ ID_OUI_FROM_DATABASE=Hijet Print d.o.o.
+
+OUI:0050C2FAA*
+ ID_OUI_FROM_DATABASE=YJSYSTEM
+
+OUI:0050C2FAB*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:0050C2FAC*
+ ID_OUI_FROM_DATABASE=ADETEL GROUP
+
+OUI:0050C2FAD*
+ ID_OUI_FROM_DATABASE=Finishing Brands
+
+OUI:0050C2FAE*
+ ID_OUI_FROM_DATABASE=ATI Automacao Telecomunicacoes e Informatica Ltda
+
+OUI:0050C2FAF*
+ ID_OUI_FROM_DATABASE=Vremya-CH JSC
+
+OUI:0050C2FB0*
+ ID_OUI_FROM_DATABASE=Tateishi Kobisha Co.LTD
+
+OUI:0050C2FB1*
+ ID_OUI_FROM_DATABASE=MATELEX
+
+OUI:0050C2FB2*
+ ID_OUI_FROM_DATABASE=Preston Industries dba PolyScience
+
+OUI:0050C2FB3*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:0050C2FB4*
+ ID_OUI_FROM_DATABASE=MC-monitoring SA
+
+OUI:0050C2FB5*
+ ID_OUI_FROM_DATABASE=Assembly Contracts Limited
+
+OUI:0050C2FB6*
+ ID_OUI_FROM_DATABASE=ARGUS-SPECTRUM
+
+OUI:0050C2FB7*
+ ID_OUI_FROM_DATABASE=Pounce Consulting
+
+OUI:0050C2FB8*
+ ID_OUI_FROM_DATABASE=TECHNO CO.,LTD.
+
+OUI:0050C2FB9*
+ ID_OUI_FROM_DATABASE=Coral Telecom Ltd
+
+OUI:0050C2FBA*
+ ID_OUI_FROM_DATABASE=Elbit Systems of America
+
+OUI:0050C2FBB*
+ ID_OUI_FROM_DATABASE=ACIDA GmbH
+
+OUI:0050C2FBC*
+ ID_OUI_FROM_DATABASE=Leroy Somer
+
+OUI:0050C2FBD*
+ ID_OUI_FROM_DATABASE=FHF Funke + Huster Fernsig GmbH
+
+OUI:0050C2FBE*
+ ID_OUI_FROM_DATABASE=senTec Elektronik GmbH
+
+OUI:0050C2FBF*
+ ID_OUI_FROM_DATABASE=MYLOGIC
+
+OUI:0050C2FC0*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:0050C2FC1*
+ ID_OUI_FROM_DATABASE=Motec Pty Ltd
+
+OUI:0050C2FC2*
+ ID_OUI_FROM_DATABASE=ELTA
+
+OUI:0050C2FC3*
+ ID_OUI_FROM_DATABASE=HSDC Sp. z o.o.
+
+OUI:0050C2FC4*
+ ID_OUI_FROM_DATABASE=Kyowadensi
+
+OUI:0050C2FC5*
+ ID_OUI_FROM_DATABASE=Sakura Seiki Co.,Ltd.
+
+OUI:0050C2FC6*
+ ID_OUI_FROM_DATABASE=Critical Link
+
+OUI:0050C2FC7*
+ ID_OUI_FROM_DATABASE=SERCOM Regeltechniek
+
+OUI:0050C2FC8*
+ ID_OUI_FROM_DATABASE=Far South Networks
+
+OUI:0050C2FC9*
+ ID_OUI_FROM_DATABASE=Mehta Tech, Inc.
+
+OUI:0050C2FCA*
+ ID_OUI_FROM_DATABASE=Telemisis Ltd
+
+OUI:0050C2FCB*
+ ID_OUI_FROM_DATABASE=Propagation Systems Limited
+
+OUI:0050C2FCC*
+ ID_OUI_FROM_DATABASE=Soudronic AG
+
+OUI:0050C2FCD*
+ ID_OUI_FROM_DATABASE=Jinyoung Contech
+
+OUI:0050C2FCE*
+ ID_OUI_FROM_DATABASE=KOYO ELECTRIC
+
+OUI:0050C2FCF*
+ ID_OUI_FROM_DATABASE=DINTEK Shanghai Electronic Ltd
+
+OUI:0050C2FD0*
+ ID_OUI_FROM_DATABASE=Simple Solutions
+
+OUI:0050C2FD1*
+ ID_OUI_FROM_DATABASE=Enyx SA
+
+OUI:0050C2FD2*
+ ID_OUI_FROM_DATABASE=Autonomic Controls. Inc
+
+OUI:0050C2FD3*
+ ID_OUI_FROM_DATABASE=Aster Electric Co.,Ltd.
+
+OUI:0050C2FD4*
+ ID_OUI_FROM_DATABASE=Insitu, Inc.
+
+OUI:0050C2FD5*
+ ID_OUI_FROM_DATABASE=American Microsystems, Ltd.
+
+OUI:0050C2FD6*
+ ID_OUI_FROM_DATABASE=City Computing Ltd
+
+OUI:0050C2FD7*
+ ID_OUI_FROM_DATABASE=Deuta-Werke GmbH
+
+OUI:0050C2FD8*
+ ID_OUI_FROM_DATABASE=Ease Inc.
+
+OUI:0050C2FD9*
+ ID_OUI_FROM_DATABASE=Figment Design Laboratories
+
+OUI:0050C2FDA*
+ ID_OUI_FROM_DATABASE=ELAN SYSTEMS
+
+OUI:0050C2FDB*
+ ID_OUI_FROM_DATABASE=The Security Center Inc
+
+OUI:0050C2FDC*
+ ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L.
+
+OUI:0050C2FDD*
+ ID_OUI_FROM_DATABASE=Toptech Systems, Inc.
+
+OUI:0050C2FDE*
+ ID_OUI_FROM_DATABASE=Peek Traffic
+
+OUI:0050C2FDF*
+ ID_OUI_FROM_DATABASE=ACD Elektronik GmbH
+
+OUI:0050C2FE0*
+ ID_OUI_FROM_DATABASE=Azurtest
+
+OUI:0050C2FE1*
+ ID_OUI_FROM_DATABASE=dotOcean
+
+OUI:0050C2FE2*
+ ID_OUI_FROM_DATABASE=Pulsotronic Anlagentechnik GmbH
+
+OUI:0050C2FE4*
+ ID_OUI_FROM_DATABASE=RTT Mobile Interpretation
+
+OUI:0050C2FE5*
+ ID_OUI_FROM_DATABASE=Scandinova Systems AB
+
+OUI:0050C2FE6*
+ ID_OUI_FROM_DATABASE=Exibea AB
+
+OUI:0050C2FE7*
+ ID_OUI_FROM_DATABASE=Erhardt+Leimer GmbH
+
+OUI:0050C2FE8*
+ ID_OUI_FROM_DATABASE=Mango DSP, Inc.
+
+OUI:0050C2FE9*
+ ID_OUI_FROM_DATABASE=MB Connect Line GmbH
+
+OUI:0050C2FEA*
+ ID_OUI_FROM_DATABASE=Brunel GmbH Section Communications
+
+OUI:0050C2FEB*
+ ID_OUI_FROM_DATABASE=Axible Technologies
+
+OUI:0050C2FEC*
+ ID_OUI_FROM_DATABASE=First System Technology Co., Ltd.
+
+OUI:0050C2FED*
+ ID_OUI_FROM_DATABASE=LOGISOL Kft.
+
+OUI:0050C2FEE*
+ ID_OUI_FROM_DATABASE=Sparks Instruments SA
+
+OUI:0050C2FEF*
+ ID_OUI_FROM_DATABASE=Task Sistemas de Computacao
+
+OUI:0050C2FF0*
+ ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS
+
+OUI:0050C2FF1*
+ ID_OUI_FROM_DATABASE=DiTEST FAHRZEUGDIAGNOSE GMBH
+
+OUI:0050C2FF2*
+ ID_OUI_FROM_DATABASE=GLOBALCOM ENGINEERING SRL
+
+OUI:0050C2FF3*
+ ID_OUI_FROM_DATABASE=CONTROL SYSTEMS Srl
+
+OUI:0050C2FF4*
+ ID_OUI_FROM_DATABASE=Burk Technology
+
+OUI:0050C2FF5*
+ ID_OUI_FROM_DATABASE=Flexkom Internet Pazarlama Bilipim ve Eoitim Hiz.Inp.Mim.Muh.Oto.Enerji San. Tic. A.p.
+
+OUI:0050C2FF6*
+ ID_OUI_FROM_DATABASE=Booyco Electronics
+
+OUI:0050C2FF7*
+ ID_OUI_FROM_DATABASE=Human Intech
+
+OUI:0050C2FF8*
+ ID_OUI_FROM_DATABASE=KST technology
+
+OUI:0050C2FF9*
+ ID_OUI_FROM_DATABASE=Penttech AB
+
+OUI:0050C2FFA*
+ ID_OUI_FROM_DATABASE=Nupoint Systems Inc.
+
+OUI:0050C2FFB*
+ ID_OUI_FROM_DATABASE=SEFRAM
+
+OUI:0050C2FFC*
+ ID_OUI_FROM_DATABASE=Spirent Communications
+
+OUI:0050C2FFD*
+ ID_OUI_FROM_DATABASE=Touchless Biometric Systems AG
+
+OUI:0050C2FFE*
+ ID_OUI_FROM_DATABASE=Sensata Technologies
+
+OUI:0050C2FFF*
+ ID_OUI_FROM_DATABASE=MSR-Solutions GmbH
+
+OUI:40D855000*
+ ID_OUI_FROM_DATABASE=XRONOS.INC
+
+OUI:40D855001*
+ ID_OUI_FROM_DATABASE=Vemotion
+
+OUI:40D855002*
+ ID_OUI_FROM_DATABASE=Hangzhou Chenxiao Technologies Co. Ltd.
+
+OUI:40D855003*
+ ID_OUI_FROM_DATABASE=AlphaNavigation coltd
+
+OUI:40D855004*
+ ID_OUI_FROM_DATABASE=CR Magnetics, Inc.
+
+OUI:40D855005*
+ ID_OUI_FROM_DATABASE=Monarch Instrument
+
+OUI:40D855006*
+ ID_OUI_FROM_DATABASE=Bactest Limited
+
+OUI:40D855007*
+ ID_OUI_FROM_DATABASE=Digital Audio SA
+
+OUI:40D855008*
+ ID_OUI_FROM_DATABASE=Kaori Industria Eletronica Ltda
+
+OUI:40D855009*
+ ID_OUI_FROM_DATABASE=ClearSite Communications Inc.
+
+OUI:40D85500A*
+ ID_OUI_FROM_DATABASE=Sarana Sistem Mikro
+
+OUI:40D85500B*
+ ID_OUI_FROM_DATABASE=Aircell
+
+OUI:40D85500C*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:40D85500D*
+ ID_OUI_FROM_DATABASE=HuNS
+
+OUI:40D85500E*
+ ID_OUI_FROM_DATABASE=Brightwell Dispensers
+
+OUI:40D85500F*
+ ID_OUI_FROM_DATABASE=DIGITAL DYNAMICS, INC.
+
+OUI:40D855010*
+ ID_OUI_FROM_DATABASE=APG CASH DRAWER
+
+OUI:40D855011*
+ ID_OUI_FROM_DATABASE=Flexim Security Oy
+
+OUI:40D855012*
+ ID_OUI_FROM_DATABASE=Sencon Inc.
+
+OUI:40D855013*
+ ID_OUI_FROM_DATABASE=Grande Vitesse Systems
+
+OUI:40D855014*
+ ID_OUI_FROM_DATABASE=Toni Studio
+
+OUI:40D855015*
+ ID_OUI_FROM_DATABASE=BITMILL srl
+
+OUI:40D855016*
+ ID_OUI_FROM_DATABASE=Par-Tech, Inc.
+
+OUI:40D855017*
+ ID_OUI_FROM_DATABASE=Franke Aquarotter GmbH
+
+OUI:40D855018*
+ ID_OUI_FROM_DATABASE=STANEO SAS
+
+OUI:40D855019*
+ ID_OUI_FROM_DATABASE=Nautel Limited
+
+OUI:40D85501A*
+ ID_OUI_FROM_DATABASE=MEGGITT DEFENSE SYSTEMS INC.
+
+OUI:40D85501B*
+ ID_OUI_FROM_DATABASE=Audio Enhancement
+
+OUI:40D85501C*
+ ID_OUI_FROM_DATABASE=BERG
+
+OUI:40D85501D*
+ ID_OUI_FROM_DATABASE=Scharco Elektronik GmbH
+
+OUI:40D85501E*
+ ID_OUI_FROM_DATABASE=A2S
+
+OUI:40D85501F*
+ ID_OUI_FROM_DATABASE=Sitep Italia Spa
+
+OUI:40D855020*
+ ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic CO., LTD.
+
+OUI:40D855021*
+ ID_OUI_FROM_DATABASE=SMT D.O.O.
+
+OUI:40D855022*
+ ID_OUI_FROM_DATABASE=Digimerge Technology Inc
+
+OUI:40D855023*
+ ID_OUI_FROM_DATABASE=Shanghai o-solution electronics & Technology Co., Ltd.
+
+OUI:40D855024*
+ ID_OUI_FROM_DATABASE=Electrical Geodesics Incorporated
+
+OUI:40D855025*
+ ID_OUI_FROM_DATABASE=Rosemount Analytical
+
+OUI:40D855026*
+ ID_OUI_FROM_DATABASE=Symetrics Industries
+
+OUI:40D855027*
+ ID_OUI_FROM_DATABASE=GRUPO EPELSA S.L.
+
+OUI:40D855028*
+ ID_OUI_FROM_DATABASE=Integrated Control Corp.
+
+OUI:40D855029*
+ ID_OUI_FROM_DATABASE=Depro Electronique
+
+OUI:40D85502A*
+ ID_OUI_FROM_DATABASE=Tinkerforge GmbH
+
+OUI:40D85502B*
+ ID_OUI_FROM_DATABASE=Nomatronics
+
+OUI:40D85502C*
+ ID_OUI_FROM_DATABASE=InventLab s.c.
+
+OUI:40D85502D*
+ ID_OUI_FROM_DATABASE=Elgama Sistemos
+
+OUI:40D85502E*
+ ID_OUI_FROM_DATABASE=Circuitec Ind. Equip. Eletr. Ltda
+
+OUI:40D85502F*
+ ID_OUI_FROM_DATABASE=Adva Technologies
+
+OUI:40D855030*
+ ID_OUI_FROM_DATABASE=Tecnologias Plexus
+
+OUI:40D855031*
+ ID_OUI_FROM_DATABASE=Dommel GmbH
+
+OUI:40D855032*
+ ID_OUI_FROM_DATABASE=BETTINI SRL
+
+OUI:40D855033*
+ ID_OUI_FROM_DATABASE=Ermes Elettronica s.r.l.
+
+OUI:40D855034*
+ ID_OUI_FROM_DATABASE=Dacom West GmbH
+
+OUI:40D855035*
+ ID_OUI_FROM_DATABASE=Mesotech International, Inc.
+
+OUI:40D855036*
+ ID_OUI_FROM_DATABASE=Schweers informationstechnologie GmbH
+
+OUI:40D855037*
+ ID_OUI_FROM_DATABASE=Software Workshop
+
+OUI:40D855038*
+ ID_OUI_FROM_DATABASE=Special Measurements Labs LLC
+
+OUI:40D855039*
+ ID_OUI_FROM_DATABASE=CI Systems Ltd
+
+OUI:40D85503A*
+ ID_OUI_FROM_DATABASE=Socus networks
+
+OUI:40D85503B*
+ ID_OUI_FROM_DATABASE=Telcomkorea
+
+OUI:40D85503C*
+ ID_OUI_FROM_DATABASE=Computer System Co.,Ltd
+
+OUI:40D85503D*
+ ID_OUI_FROM_DATABASE=Tekelek Europe Ltd
+
+OUI:40D85503E*
+ ID_OUI_FROM_DATABASE=Vishay Celtron Technologies, Inc.
+
+OUI:40D85503F*
+ ID_OUI_FROM_DATABASE=UniSVR Global Information Technology Corp.
+
+OUI:40D855040*
+ ID_OUI_FROM_DATABASE=GHL Systems Berhad
+
+OUI:40D855041*
+ ID_OUI_FROM_DATABASE=T.Q.M. Itaca Technology s.r.l.
+
+OUI:40D855042*
+ ID_OUI_FROM_DATABASE=Mango Communicaitons Inc.
+
+OUI:40D855043*
+ ID_OUI_FROM_DATABASE=SchulerControl GmbH
+
+OUI:40D855044*
+ ID_OUI_FROM_DATABASE=An Chen Computer Co. Ltd.
+
+OUI:40D855045*
+ ID_OUI_FROM_DATABASE=Genadsystem
+
+OUI:40D855046*
+ ID_OUI_FROM_DATABASE=Circuitlink Pty Ltd
+
+OUI:40D855047*
+ ID_OUI_FROM_DATABASE=Dos&Donts SRL
+
+OUI:40D855048*
+ ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS
+
+OUI:40D855049*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific
+
+OUI:40D85504A*
+ ID_OUI_FROM_DATABASE=Gateway Technologies SA de CV
+
+OUI:40D85504B*
+ ID_OUI_FROM_DATABASE=Vital Tech Industria e Comercio Ltda
+
+OUI:40D85504C*
+ ID_OUI_FROM_DATABASE=Serveron Corporation
+
+OUI:40D85504D*
+ ID_OUI_FROM_DATABASE=MACHINEPERFORMANCE ApS
+
+OUI:40D85504E*
+ ID_OUI_FROM_DATABASE=Honeywell Aerospace/Intelligent Automation Corp.
+
+OUI:40D85504F*
+ ID_OUI_FROM_DATABASE=Haein S&S Co., Ltd
+
+OUI:40D855050*
+ ID_OUI_FROM_DATABASE=ATG UV Technology
+
+OUI:40D855051*
+ ID_OUI_FROM_DATABASE=CS Instruments Asia
+
+OUI:40D855052*
+ ID_OUI_FROM_DATABASE=DAN ELECTRONICS SYSTEM (P) LIMITED
+
+OUI:40D855053*
+ ID_OUI_FROM_DATABASE=Amantys Ltd
+
+OUI:40D855054*
+ ID_OUI_FROM_DATABASE=VITEC
+
+OUI:40D855055*
+ ID_OUI_FROM_DATABASE=Helmholtz Zentrum Dresden Rossendorf e.V.
+
+OUI:40D855056*
+ ID_OUI_FROM_DATABASE=GROUP 57
+
+OUI:40D855057*
+ ID_OUI_FROM_DATABASE=Tammermatic Group Oy
+
+OUI:40D855058*
+ ID_OUI_FROM_DATABASE=Energy Team S.p.A.
+
+OUI:40D855059*
+ ID_OUI_FROM_DATABASE=COLONIAL ASSEMBLY and  DESIGN
+
+OUI:40D85505A*
+ ID_OUI_FROM_DATABASE=Ultra Electronics Flightline Systems
+
+OUI:40D85505B*
+ ID_OUI_FROM_DATABASE=Data Flow Systems, Inc.
+
+OUI:40D85505C*
+ ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited
+
+OUI:40D85505D*
+ ID_OUI_FROM_DATABASE=Leica Biosystems
+
+OUI:40D85505E*
+ ID_OUI_FROM_DATABASE=inoage GmbH
+
+OUI:40D85505F*
+ ID_OUI_FROM_DATABASE=EPSa GmbH
+
+OUI:40D855060*
+ ID_OUI_FROM_DATABASE=Aplex Technology Inc.
+
+OUI:40D855061*
+ ID_OUI_FROM_DATABASE=Cominfo, Inc.
+
+OUI:40D855062*
+ ID_OUI_FROM_DATABASE=Tech Source Inc
+
+OUI:40D855063*
+ ID_OUI_FROM_DATABASE=Protonic Holland
+
+OUI:40D855064*
+ ID_OUI_FROM_DATABASE=HIPODROMO DE AGUA CALIENTE, S.A. DE C.V.
+
+OUI:40D855065*
+ ID_OUI_FROM_DATABASE=Parallel Wireless
+
+OUI:40D855066*
+ ID_OUI_FROM_DATABASE=TeraTron GmbH
+
+OUI:40D855067*
+ ID_OUI_FROM_DATABASE=Tronic Control ltd.
+
+OUI:40D855068*
+ ID_OUI_FROM_DATABASE=Oki Seatec Co., Ltd.
+
+OUI:40D855069*
+ ID_OUI_FROM_DATABASE=Smartcom-Bulgaria AD
+
+OUI:40D85506A*
+ ID_OUI_FROM_DATABASE=elgris
+
+OUI:40D85506B*
+ ID_OUI_FROM_DATABASE=BRS Sistemas Eletronicos
+
+OUI:40D85506C*
+ ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA
+
+OUI:40D85506D*
+ ID_OUI_FROM_DATABASE=BroadSoft, INC
+
+OUI:40D85506E*
+ ID_OUI_FROM_DATABASE=C-COM Satellite Systems Inc.
+
+OUI:40D85506F*
+ ID_OUI_FROM_DATABASE=DORLET SA
+
+OUI:40D855070*
+ ID_OUI_FROM_DATABASE=JSC Electrical Equipment Factory
+
+OUI:40D855071*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:40D855072*
+ ID_OUI_FROM_DATABASE=CT Company
+
+OUI:40D855073*
+ ID_OUI_FROM_DATABASE=Diamond Technologies, Inc
+
+OUI:40D855074*
+ ID_OUI_FROM_DATABASE=Sphere Medical Ltd
+
+OUI:40D855075*
+ ID_OUI_FROM_DATABASE=Teraflops
+
+OUI:000000*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000001*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000002*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000003*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000004*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000005*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000006*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000007*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000008*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:000009*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:00000A*
+ ID_OUI_FROM_DATABASE=OMRON TATEISI ELECTRONICS CO.
+
+OUI:00000B*
+ ID_OUI_FROM_DATABASE=MATRIX CORPORATION
+
+OUI:00000C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00000D*
+ ID_OUI_FROM_DATABASE=FIBRONICS LTD.
+
+OUI:00000E*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+
+OUI:00000F*
+ ID_OUI_FROM_DATABASE=NEXT, INC.
+
+OUI:000010*
+ ID_OUI_FROM_DATABASE=SYTEK INC.
+
+OUI:000011*
+ ID_OUI_FROM_DATABASE=NORMEREL SYSTEMES
+
+OUI:000012*
+ ID_OUI_FROM_DATABASE=INFORMATION TECHNOLOGY LIMITED
+
+OUI:000013*
+ ID_OUI_FROM_DATABASE=CAMEX
+
+OUI:000014*
+ ID_OUI_FROM_DATABASE=NETRONIX
+
+OUI:000015*
+ ID_OUI_FROM_DATABASE=DATAPOINT CORPORATION
+
+OUI:000016*
+ ID_OUI_FROM_DATABASE=DU PONT PIXEL SYSTEMS     .
+
+OUI:000017*
+ ID_OUI_FROM_DATABASE=TEKELEC
+
+OUI:000018*
+ ID_OUI_FROM_DATABASE=WEBSTER COMPUTER CORPORATION
+
+OUI:000019*
+ ID_OUI_FROM_DATABASE=APPLIED DYNAMICS INTERNATIONAL
+
+OUI:00001A*
+ ID_OUI_FROM_DATABASE=ADVANCED MICRO DEVICES
+
+OUI:00001B*
+ ID_OUI_FROM_DATABASE=NOVELL INC.
+
+OUI:00001C*
+ ID_OUI_FROM_DATABASE=BELL TECHNOLOGIES
+
+OUI:00001D*
+ ID_OUI_FROM_DATABASE=CABLETRON SYSTEMS, INC.
+
+OUI:00001E*
+ ID_OUI_FROM_DATABASE=TELSIST INDUSTRIA ELECTRONICA
+
+OUI:00001F*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:000020*
+ ID_OUI_FROM_DATABASE=DATAINDUSTRIER DIAB AB
+
+OUI:000021*
+ ID_OUI_FROM_DATABASE=SUREMAN COMP. & COMMUN. CORP.
+
+OUI:000022*
+ ID_OUI_FROM_DATABASE=VISUAL TECHNOLOGY INC.
+
+OUI:000023*
+ ID_OUI_FROM_DATABASE=ABB INDUSTRIAL SYSTEMS AB
+
+OUI:000024*
+ ID_OUI_FROM_DATABASE=CONNECT AS
+
+OUI:000025*
+ ID_OUI_FROM_DATABASE=RAMTEK CORP.
+
+OUI:000026*
+ ID_OUI_FROM_DATABASE=SHA-KEN CO., LTD.
+
+OUI:000027*
+ ID_OUI_FROM_DATABASE=JAPAN RADIO COMPANY
+
+OUI:000028*
+ ID_OUI_FROM_DATABASE=PRODIGY SYSTEMS CORPORATION
+
+OUI:000029*
+ ID_OUI_FROM_DATABASE=IMC NETWORKS CORP.
+
+OUI:00002A*
+ ID_OUI_FROM_DATABASE=TRW - SEDD/INP
+
+OUI:00002B*
+ ID_OUI_FROM_DATABASE=CRISP AUTOMATION, INC
+
+OUI:00002C*
+ ID_OUI_FROM_DATABASE=AUTOTOTE LIMITED
+
+OUI:00002D*
+ ID_OUI_FROM_DATABASE=CHROMATICS INC
+
+OUI:00002E*
+ ID_OUI_FROM_DATABASE=SOCIETE EVIRA
+
+OUI:00002F*
+ ID_OUI_FROM_DATABASE=TIMEPLEX INC.
+
+OUI:000030*
+ ID_OUI_FROM_DATABASE=VG LABORATORY SYSTEMS LTD
+
+OUI:000031*
+ ID_OUI_FROM_DATABASE=QPSX COMMUNICATIONS PTY LTD
+
+OUI:000032*
+ ID_OUI_FROM_DATABASE=Marconi plc
+
+OUI:000033*
+ ID_OUI_FROM_DATABASE=EGAN MACHINERY COMPANY
+
+OUI:000034*
+ ID_OUI_FROM_DATABASE=NETWORK RESOURCES CORPORATION
+
+OUI:000035*
+ ID_OUI_FROM_DATABASE=SPECTRAGRAPHICS CORPORATION
+
+OUI:000036*
+ ID_OUI_FROM_DATABASE=ATARI CORPORATION
+
+OUI:000037*
+ ID_OUI_FROM_DATABASE=OXFORD METRICS LIMITED
+
+OUI:000038*
+ ID_OUI_FROM_DATABASE=CSS LABS
+
+OUI:000039*
+ ID_OUI_FROM_DATABASE=TOSHIBA CORPORATION
+
+OUI:00003A*
+ ID_OUI_FROM_DATABASE=CHYRON CORPORATION
+
+OUI:00003B*
+ ID_OUI_FROM_DATABASE=i Controls, Inc.
+
+OUI:00003C*
+ ID_OUI_FROM_DATABASE=AUSPEX SYSTEMS INC.
+
+OUI:00003D*
+ ID_OUI_FROM_DATABASE=UNISYS
+
+OUI:00003E*
+ ID_OUI_FROM_DATABASE=SIMPACT
+
+OUI:00003F*
+ ID_OUI_FROM_DATABASE=SYNTREX, INC.
+
+OUI:000040*
+ ID_OUI_FROM_DATABASE=APPLICON, INC.
+
+OUI:000041*
+ ID_OUI_FROM_DATABASE=ICE CORPORATION
+
+OUI:000042*
+ ID_OUI_FROM_DATABASE=METIER MANAGEMENT SYSTEMS LTD.
+
+OUI:000043*
+ ID_OUI_FROM_DATABASE=MICRO TECHNOLOGY
+
+OUI:000044*
+ ID_OUI_FROM_DATABASE=CASTELLE CORPORATION
+
+OUI:000045*
+ ID_OUI_FROM_DATABASE=FORD AEROSPACE & COMM. CORP.
+
+OUI:000046*
+ ID_OUI_FROM_DATABASE=OLIVETTI NORTH AMERICA
+
+OUI:000047*
+ ID_OUI_FROM_DATABASE=NICOLET INSTRUMENTS CORP.
+
+OUI:000048*
+ ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION
+
+OUI:000049*
+ ID_OUI_FROM_DATABASE=APRICOT COMPUTERS, LTD
+
+OUI:00004A*
+ ID_OUI_FROM_DATABASE=ADC CODENOLL TECHNOLOGY CORP.
+
+OUI:00004B*
+ ID_OUI_FROM_DATABASE=ICL DATA OY
+
+OUI:00004C*
+ ID_OUI_FROM_DATABASE=NEC CORPORATION
+
+OUI:00004D*
+ ID_OUI_FROM_DATABASE=DCI CORPORATION
+
+OUI:00004E*
+ ID_OUI_FROM_DATABASE=AMPEX CORPORATION
+
+OUI:00004F*
+ ID_OUI_FROM_DATABASE=LOGICRAFT, INC.
+
+OUI:000050*
+ ID_OUI_FROM_DATABASE=RADISYS CORPORATION
+
+OUI:000051*
+ ID_OUI_FROM_DATABASE=HOB ELECTRONIC GMBH & CO. KG
+
+OUI:000052*
+ ID_OUI_FROM_DATABASE=Intrusion.com, Inc.
+
+OUI:000053*
+ ID_OUI_FROM_DATABASE=COMPUCORP
+
+OUI:000054*
+ ID_OUI_FROM_DATABASE=MODICON, INC.
+
+OUI:000055*
+ ID_OUI_FROM_DATABASE=COMMISSARIAT A L`ENERGIE ATOM.
+
+OUI:000056*
+ ID_OUI_FROM_DATABASE=DR. B. STRUCK
+
+OUI:000057*
+ ID_OUI_FROM_DATABASE=SCITEX CORPORATION LTD.
+
+OUI:000058*
+ ID_OUI_FROM_DATABASE=RACORE COMPUTER PRODUCTS INC.
+
+OUI:000059*
+ ID_OUI_FROM_DATABASE=HELLIGE GMBH
+
+OUI:00005A*
+ ID_OUI_FROM_DATABASE=SysKonnect GmbH
+
+OUI:00005B*
+ ID_OUI_FROM_DATABASE=ELTEC ELEKTRONIK AG
+
+OUI:00005C*
+ ID_OUI_FROM_DATABASE=TELEMATICS INTERNATIONAL INC.
+
+OUI:00005D*
+ ID_OUI_FROM_DATABASE=CS TELECOM
+
+OUI:00005E*
+ ID_OUI_FROM_DATABASE=USC INFORMATION SCIENCES INST
+
+OUI:00005F*
+ ID_OUI_FROM_DATABASE=SUMITOMO ELECTRIC IND., LTD.
+
+OUI:000060*
+ ID_OUI_FROM_DATABASE=KONTRON ELEKTRONIK GMBH
+
+OUI:000061*
+ ID_OUI_FROM_DATABASE=GATEWAY COMMUNICATIONS
+
+OUI:000062*
+ ID_OUI_FROM_DATABASE=BULL HN INFORMATION SYSTEMS
+
+OUI:000063*
+ ID_OUI_FROM_DATABASE=BARCO CONTROL ROOMS GMBH
+
+OUI:000064*
+ ID_OUI_FROM_DATABASE=YOKOGAWA DIGITAL COMPUTER CORP
+
+OUI:000065*
+ ID_OUI_FROM_DATABASE=Network General Corporation
+
+OUI:000066*
+ ID_OUI_FROM_DATABASE=TALARIS SYSTEMS, INC.
+
+OUI:000067*
+ ID_OUI_FROM_DATABASE=SOFT * RITE, INC.
+
+OUI:000068*
+ ID_OUI_FROM_DATABASE=ROSEMOUNT CONTROLS
+
+OUI:000069*
+ ID_OUI_FROM_DATABASE=CONCORD COMMUNICATIONS INC
+
+OUI:00006A*
+ ID_OUI_FROM_DATABASE=COMPUTER CONSOLES INC.
+
+OUI:00006B*
+ ID_OUI_FROM_DATABASE=SILICON GRAPHICS INC./MIPS
+
+OUI:00006D*
+ ID_OUI_FROM_DATABASE=CRAY COMMUNICATIONS, LTD.
+
+OUI:00006E*
+ ID_OUI_FROM_DATABASE=ARTISOFT, INC.
+
+OUI:00006F*
+ ID_OUI_FROM_DATABASE=Madge Ltd.
+
+OUI:000070*
+ ID_OUI_FROM_DATABASE=HCL LIMITED
+
+OUI:000071*
+ ID_OUI_FROM_DATABASE=ADRA SYSTEMS INC.
+
+OUI:000072*
+ ID_OUI_FROM_DATABASE=MINIWARE TECHNOLOGY
+
+OUI:000073*
+ ID_OUI_FROM_DATABASE=SIECOR CORPORATION
+
+OUI:000074*
+ ID_OUI_FROM_DATABASE=RICOH COMPANY LTD.
+
+OUI:000075*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000076*
+ ID_OUI_FROM_DATABASE=ABEKAS VIDEO SYSTEM
+
+OUI:000077*
+ ID_OUI_FROM_DATABASE=INTERPHASE CORPORATION
+
+OUI:000078*
+ ID_OUI_FROM_DATABASE=LABTAM LIMITED
+
+OUI:000079*
+ ID_OUI_FROM_DATABASE=NETWORTH INCORPORATED
+
+OUI:00007A*
+ ID_OUI_FROM_DATABASE=DANA COMPUTER INC.
+
+OUI:00007B*
+ ID_OUI_FROM_DATABASE=RESEARCH MACHINES
+
+OUI:00007C*
+ ID_OUI_FROM_DATABASE=AMPERE INCORPORATED
+
+OUI:00007D*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:00007E*
+ ID_OUI_FROM_DATABASE=CLUSTRIX CORPORATION
+
+OUI:00007F*
+ ID_OUI_FROM_DATABASE=LINOTYPE-HELL AG
+
+OUI:000080*
+ ID_OUI_FROM_DATABASE=CRAY COMMUNICATIONS A/S
+
+OUI:000081*
+ ID_OUI_FROM_DATABASE=BAY NETWORKS
+
+OUI:000082*
+ ID_OUI_FROM_DATABASE=LECTRA SYSTEMES SA
+
+OUI:000083*
+ ID_OUI_FROM_DATABASE=TADPOLE TECHNOLOGY PLC
+
+OUI:000084*
+ ID_OUI_FROM_DATABASE=SUPERNET
+
+OUI:000085*
+ ID_OUI_FROM_DATABASE=CANON INC.
+
+OUI:000086*
+ ID_OUI_FROM_DATABASE=MEGAHERTZ CORPORATION
+
+OUI:000087*
+ ID_OUI_FROM_DATABASE=HITACHI, LTD.
+
+OUI:000088*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000089*
+ ID_OUI_FROM_DATABASE=CAYMAN SYSTEMS INC.
+
+OUI:00008A*
+ ID_OUI_FROM_DATABASE=DATAHOUSE INFORMATION SYSTEMS
+
+OUI:00008B*
+ ID_OUI_FROM_DATABASE=INFOTRON
+
+OUI:00008C*
+ ID_OUI_FROM_DATABASE=Alloy Computer Products (Australia) Pty Ltd
+
+OUI:00008D*
+ ID_OUI_FROM_DATABASE=Cryptek Inc.
+
+OUI:00008E*
+ ID_OUI_FROM_DATABASE=SOLBOURNE COMPUTER, INC.
+
+OUI:00008F*
+ ID_OUI_FROM_DATABASE=Raytheon
+
+OUI:000090*
+ ID_OUI_FROM_DATABASE=MICROCOM
+
+OUI:000091*
+ ID_OUI_FROM_DATABASE=ANRITSU CORPORATION
+
+OUI:000092*
+ ID_OUI_FROM_DATABASE=COGENT DATA TECHNOLOGIES
+
+OUI:000093*
+ ID_OUI_FROM_DATABASE=PROTEON INC.
+
+OUI:000094*
+ ID_OUI_FROM_DATABASE=ASANTE TECHNOLOGIES
+
+OUI:000095*
+ ID_OUI_FROM_DATABASE=SONY TEKTRONIX CORP.
+
+OUI:000096*
+ ID_OUI_FROM_DATABASE=MARCONI ELECTRONICS LTD.
+
+OUI:000097*
+ ID_OUI_FROM_DATABASE=EMC Corporation
+
+OUI:000098*
+ ID_OUI_FROM_DATABASE=CROSSCOMM CORPORATION
+
+OUI:000099*
+ ID_OUI_FROM_DATABASE=MTX, INC.
+
+OUI:00009A*
+ ID_OUI_FROM_DATABASE=RC COMPUTER A/S
+
+OUI:00009B*
+ ID_OUI_FROM_DATABASE=INFORMATION INTERNATIONAL, INC
+
+OUI:00009C*
+ ID_OUI_FROM_DATABASE=ROLM MIL-SPEC COMPUTERS
+
+OUI:00009D*
+ ID_OUI_FROM_DATABASE=LOCUS COMPUTING CORPORATION
+
+OUI:00009E*
+ ID_OUI_FROM_DATABASE=MARLI S.A.
+
+OUI:00009F*
+ ID_OUI_FROM_DATABASE=AMERISTAR TECHNOLOGIES INC.
+
+OUI:0000A0*
+ ID_OUI_FROM_DATABASE=SANYO Electric Co., Ltd.
+
+OUI:0000A1*
+ ID_OUI_FROM_DATABASE=MARQUETTE ELECTRIC CO.
+
+OUI:0000A2*
+ ID_OUI_FROM_DATABASE=BAY NETWORKS
+
+OUI:0000A3*
+ ID_OUI_FROM_DATABASE=NETWORK APPLICATION TECHNOLOGY
+
+OUI:0000A4*
+ ID_OUI_FROM_DATABASE=ACORN COMPUTERS LIMITED
+
+OUI:0000A5*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:0000A6*
+ ID_OUI_FROM_DATABASE=NETWORK GENERAL CORPORATION
+
+OUI:0000A7*
+ ID_OUI_FROM_DATABASE=NETWORK COMPUTING DEVICES INC.
+
+OUI:0000A8*
+ ID_OUI_FROM_DATABASE=STRATUS COMPUTER INC.
+
+OUI:0000A9*
+ ID_OUI_FROM_DATABASE=NETWORK SYSTEMS CORP.
+
+OUI:0000AA*
+ ID_OUI_FROM_DATABASE=XEROX CORPORATION
+
+OUI:0000AB*
+ ID_OUI_FROM_DATABASE=LOGIC MODELING CORPORATION
+
+OUI:0000AC*
+ ID_OUI_FROM_DATABASE=CONWARE COMPUTER CONSULTING
+
+OUI:0000AD*
+ ID_OUI_FROM_DATABASE=BRUKER INSTRUMENTS INC.
+
+OUI:0000AE*
+ ID_OUI_FROM_DATABASE=DASSAULT ELECTRONIQUE
+
+OUI:0000AF*
+ ID_OUI_FROM_DATABASE=NUCLEAR DATA INSTRUMENTATION
+
+OUI:0000B0*
+ ID_OUI_FROM_DATABASE=RND-RAD NETWORK DEVICES
+
+OUI:0000B1*
+ ID_OUI_FROM_DATABASE=ALPHA MICROSYSTEMS INC.
+
+OUI:0000B2*
+ ID_OUI_FROM_DATABASE=TELEVIDEO SYSTEMS, INC.
+
+OUI:0000B3*
+ ID_OUI_FROM_DATABASE=CIMLINC INCORPORATED
+
+OUI:0000B4*
+ ID_OUI_FROM_DATABASE=EDIMAX COMPUTER COMPANY
+
+OUI:0000B5*
+ ID_OUI_FROM_DATABASE=DATABILITY SOFTWARE SYS. INC.
+
+OUI:0000B6*
+ ID_OUI_FROM_DATABASE=MICRO-MATIC RESEARCH
+
+OUI:0000B7*
+ ID_OUI_FROM_DATABASE=DOVE COMPUTER CORPORATION
+
+OUI:0000B8*
+ ID_OUI_FROM_DATABASE=SEIKOSHA CO., LTD.
+
+OUI:0000B9*
+ ID_OUI_FROM_DATABASE=MCDONNELL DOUGLAS COMPUTER SYS
+
+OUI:0000BA*
+ ID_OUI_FROM_DATABASE=SIIG, INC.
+
+OUI:0000BB*
+ ID_OUI_FROM_DATABASE=TRI-DATA
+
+OUI:0000BC*
+ ID_OUI_FROM_DATABASE=Rockwell Automation
+
+OUI:0000BD*
+ ID_OUI_FROM_DATABASE=MITSUBISHI CABLE COMPANY
+
+OUI:0000BE*
+ ID_OUI_FROM_DATABASE=THE NTI GROUP
+
+OUI:0000BF*
+ ID_OUI_FROM_DATABASE=SYMMETRIC COMPUTER SYSTEMS
+
+OUI:0000C0*
+ ID_OUI_FROM_DATABASE=WESTERN DIGITAL CORPORATION
+
+OUI:0000C1*
+ ID_OUI_FROM_DATABASE=Madge Ltd.
+
+OUI:0000C2*
+ ID_OUI_FROM_DATABASE=INFORMATION PRESENTATION TECH.
+
+OUI:0000C3*
+ ID_OUI_FROM_DATABASE=HARRIS CORP COMPUTER SYS DIV
+
+OUI:0000C4*
+ ID_OUI_FROM_DATABASE=WATERS DIV. OF MILLIPORE
+
+OUI:0000C5*
+ ID_OUI_FROM_DATABASE=FARALLON COMPUTING/NETOPIA
+
+OUI:0000C6*
+ ID_OUI_FROM_DATABASE=EON SYSTEMS
+
+OUI:0000C7*
+ ID_OUI_FROM_DATABASE=ARIX CORPORATION
+
+OUI:0000C8*
+ ID_OUI_FROM_DATABASE=ALTOS COMPUTER SYSTEMS
+
+OUI:0000C9*
+ ID_OUI_FROM_DATABASE=Emulex Corporation
+
+OUI:0000CA*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:0000CB*
+ ID_OUI_FROM_DATABASE=COMPU-SHACK ELECTRONIC GMBH
+
+OUI:0000CC*
+ ID_OUI_FROM_DATABASE=DENSAN CO., LTD.
+
+OUI:0000CD*
+ ID_OUI_FROM_DATABASE=Allied Telesis Labs Ltd
+
+OUI:0000CE*
+ ID_OUI_FROM_DATABASE=MEGADATA CORP.
+
+OUI:0000CF*
+ ID_OUI_FROM_DATABASE=HAYES MICROCOMPUTER PRODUCTS
+
+OUI:0000D0*
+ ID_OUI_FROM_DATABASE=DEVELCON ELECTRONICS LTD.
+
+OUI:0000D1*
+ ID_OUI_FROM_DATABASE=ADAPTEC INCORPORATED
+
+OUI:0000D2*
+ ID_OUI_FROM_DATABASE=SBE, INC.
+
+OUI:0000D3*
+ ID_OUI_FROM_DATABASE=WANG LABORATORIES INC.
+
+OUI:0000D4*
+ ID_OUI_FROM_DATABASE=PURE DATA LTD.
+
+OUI:0000D5*
+ ID_OUI_FROM_DATABASE=MICROGNOSIS INTERNATIONAL
+
+OUI:0000D6*
+ ID_OUI_FROM_DATABASE=PUNCH LINE HOLDING
+
+OUI:0000D7*
+ ID_OUI_FROM_DATABASE=DARTMOUTH COLLEGE
+
+OUI:0000D8*
+ ID_OUI_FROM_DATABASE=NOVELL, INC.
+
+OUI:0000D9*
+ ID_OUI_FROM_DATABASE=NIPPON TELEGRAPH & TELEPHONE
+
+OUI:0000DA*
+ ID_OUI_FROM_DATABASE=ATEX
+
+OUI:0000DB*
+ ID_OUI_FROM_DATABASE=British Telecommunications plc
+
+OUI:0000DC*
+ ID_OUI_FROM_DATABASE=HAYES MICROCOMPUTER PRODUCTS
+
+OUI:0000DD*
+ ID_OUI_FROM_DATABASE=TCL INCORPORATED
+
+OUI:0000DE*
+ ID_OUI_FROM_DATABASE=CETIA
+
+OUI:0000DF*
+ ID_OUI_FROM_DATABASE=BELL & HOWELL PUB SYS DIV
+
+OUI:0000E0*
+ ID_OUI_FROM_DATABASE=QUADRAM CORP.
+
+OUI:0000E1*
+ ID_OUI_FROM_DATABASE=GRID SYSTEMS
+
+OUI:0000E2*
+ ID_OUI_FROM_DATABASE=ACER TECHNOLOGIES CORP.
+
+OUI:0000E3*
+ ID_OUI_FROM_DATABASE=INTEGRATED MICRO PRODUCTS LTD
+
+OUI:0000E4*
+ ID_OUI_FROM_DATABASE=IN2 GROUPE INTERTECHNIQUE
+
+OUI:0000E5*
+ ID_OUI_FROM_DATABASE=SIGMEX LTD.
+
+OUI:0000E6*
+ ID_OUI_FROM_DATABASE=APTOR PRODUITS DE COMM INDUST
+
+OUI:0000E7*
+ ID_OUI_FROM_DATABASE=STAR GATE TECHNOLOGIES
+
+OUI:0000E8*
+ ID_OUI_FROM_DATABASE=ACCTON TECHNOLOGY CORP.
+
+OUI:0000E9*
+ ID_OUI_FROM_DATABASE=ISICAD, INC.
+
+OUI:0000EA*
+ ID_OUI_FROM_DATABASE=UPNOD AB
+
+OUI:0000EB*
+ ID_OUI_FROM_DATABASE=MATSUSHITA COMM. IND. CO. LTD.
+
+OUI:0000EC*
+ ID_OUI_FROM_DATABASE=MICROPROCESS
+
+OUI:0000ED*
+ ID_OUI_FROM_DATABASE=APRIL
+
+OUI:0000EE*
+ ID_OUI_FROM_DATABASE=NETWORK DESIGNERS, LTD.
+
+OUI:0000EF*
+ ID_OUI_FROM_DATABASE=KTI
+
+OUI:0000F0*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD.
+
+OUI:0000F1*
+ ID_OUI_FROM_DATABASE=MAGNA COMPUTER CORPORATION
+
+OUI:0000F2*
+ ID_OUI_FROM_DATABASE=SPIDER COMMUNICATIONS
+
+OUI:0000F3*
+ ID_OUI_FROM_DATABASE=GANDALF DATA LIMITED
+
+OUI:0000F4*
+ ID_OUI_FROM_DATABASE=Allied Telesis
+
+OUI:0000F5*
+ ID_OUI_FROM_DATABASE=DIAMOND SALES LIMITED
+
+OUI:0000F6*
+ ID_OUI_FROM_DATABASE=APPLIED MICROSYSTEMS CORP.
+
+OUI:0000F7*
+ ID_OUI_FROM_DATABASE=YOUTH KEEP ENTERPRISE CO LTD
+
+OUI:0000F8*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:0000F9*
+ ID_OUI_FROM_DATABASE=QUOTRON SYSTEMS INC.
+
+OUI:0000FA*
+ ID_OUI_FROM_DATABASE=MICROSAGE COMPUTER SYSTEMS INC
+
+OUI:0000FB*
+ ID_OUI_FROM_DATABASE=RECHNER ZUR KOMMUNIKATION
+
+OUI:0000FC*
+ ID_OUI_FROM_DATABASE=MEIKO
+
+OUI:0000FD*
+ ID_OUI_FROM_DATABASE=HIGH LEVEL HARDWARE
+
+OUI:0000FE*
+ ID_OUI_FROM_DATABASE=ANNAPOLIS MICRO SYSTEMS
+
+OUI:0000FF*
+ ID_OUI_FROM_DATABASE=CAMTEC ELECTRONICS LTD.
+
+OUI:000100*
+ ID_OUI_FROM_DATABASE=EQUIP'TRANS
+
+OUI:000102*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:000103*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:000104*
+ ID_OUI_FROM_DATABASE=DVICO Co., Ltd.
+
+OUI:000105*
+ ID_OUI_FROM_DATABASE=Beckhoff Automation GmbH
+
+OUI:000106*
+ ID_OUI_FROM_DATABASE=Tews Datentechnik GmbH
+
+OUI:000107*
+ ID_OUI_FROM_DATABASE=Leiser GmbH
+
+OUI:000108*
+ ID_OUI_FROM_DATABASE=AVLAB Technology, Inc.
+
+OUI:000109*
+ ID_OUI_FROM_DATABASE=Nagano Japan Radio Co., Ltd.
+
+OUI:00010A*
+ ID_OUI_FROM_DATABASE=CIS TECHNOLOGY INC.
+
+OUI:00010B*
+ ID_OUI_FROM_DATABASE=Space CyberLink, Inc.
+
+OUI:00010C*
+ ID_OUI_FROM_DATABASE=System Talks Inc.
+
+OUI:00010D*
+ ID_OUI_FROM_DATABASE=CORECO, INC.
+
+OUI:00010E*
+ ID_OUI_FROM_DATABASE=Bri-Link Technologies Co., Ltd
+
+OUI:00010F*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000110*
+ ID_OUI_FROM_DATABASE=Gotham Networks
+
+OUI:000111*
+ ID_OUI_FROM_DATABASE=iDigm Inc.
+
+OUI:000112*
+ ID_OUI_FROM_DATABASE=Shark Multimedia Inc.
+
+OUI:000113*
+ ID_OUI_FROM_DATABASE=OLYMPUS CORPORATION
+
+OUI:000114*
+ ID_OUI_FROM_DATABASE=KANDA TSUSHIN KOGYO CO., LTD.
+
+OUI:000115*
+ ID_OUI_FROM_DATABASE=EXTRATECH CORPORATION
+
+OUI:000116*
+ ID_OUI_FROM_DATABASE=Netspect Technologies, Inc.
+
+OUI:000117*
+ ID_OUI_FROM_DATABASE=CANAL +
+
+OUI:000118*
+ ID_OUI_FROM_DATABASE=EZ Digital Co., Ltd.
+
+OUI:000119*
+ ID_OUI_FROM_DATABASE=RTUnet (Australia)
+
+OUI:00011A*
+ ID_OUI_FROM_DATABASE=EEH DataLink GmbH
+
+OUI:00011B*
+ ID_OUI_FROM_DATABASE=Unizone Technologies, Inc.
+
+OUI:00011C*
+ ID_OUI_FROM_DATABASE=Universal Talkware Corporation
+
+OUI:00011D*
+ ID_OUI_FROM_DATABASE=Centillium Communications
+
+OUI:00011E*
+ ID_OUI_FROM_DATABASE=Precidia Technologies, Inc.
+
+OUI:00011F*
+ ID_OUI_FROM_DATABASE=RC Networks, Inc.
+
+OUI:000120*
+ ID_OUI_FROM_DATABASE=OSCILLOQUARTZ S.A.
+
+OUI:000121*
+ ID_OUI_FROM_DATABASE=Watchguard Technologies, Inc.
+
+OUI:000122*
+ ID_OUI_FROM_DATABASE=Trend Communications, Ltd.
+
+OUI:000123*
+ ID_OUI_FROM_DATABASE=DIGITAL ELECTRONICS CORP.
+
+OUI:000124*
+ ID_OUI_FROM_DATABASE=Acer Incorporated
+
+OUI:000125*
+ ID_OUI_FROM_DATABASE=YAESU MUSEN CO., LTD.
+
+OUI:000126*
+ ID_OUI_FROM_DATABASE=PAC Labs
+
+OUI:000127*
+ ID_OUI_FROM_DATABASE=OPEN Networks Pty Ltd
+
+OUI:000128*
+ ID_OUI_FROM_DATABASE=EnjoyWeb, Inc.
+
+OUI:000129*
+ ID_OUI_FROM_DATABASE=DFI Inc.
+
+OUI:00012A*
+ ID_OUI_FROM_DATABASE=Telematica Sistems Inteligente
+
+OUI:00012B*
+ ID_OUI_FROM_DATABASE=TELENET Co., Ltd.
+
+OUI:00012C*
+ ID_OUI_FROM_DATABASE=Aravox Technologies, Inc.
+
+OUI:00012D*
+ ID_OUI_FROM_DATABASE=Komodo Technology
+
+OUI:00012E*
+ ID_OUI_FROM_DATABASE=PC Partner Ltd.
+
+OUI:00012F*
+ ID_OUI_FROM_DATABASE=Twinhead International Corp
+
+OUI:000130*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:000131*
+ ID_OUI_FROM_DATABASE=Bosch Security Systems, Inc.
+
+OUI:000132*
+ ID_OUI_FROM_DATABASE=Dranetz - BMI
+
+OUI:000133*
+ ID_OUI_FROM_DATABASE=KYOWA Electronic Instruments C
+
+OUI:000134*
+ ID_OUI_FROM_DATABASE=Selectron Systems AG
+
+OUI:000135*
+ ID_OUI_FROM_DATABASE=KDC Corp.
+
+OUI:000136*
+ ID_OUI_FROM_DATABASE=CyberTAN Technology, Inc.
+
+OUI:000137*
+ ID_OUI_FROM_DATABASE=IT Farm Corporation
+
+OUI:000138*
+ ID_OUI_FROM_DATABASE=XAVi Technologies Corp.
+
+OUI:000139*
+ ID_OUI_FROM_DATABASE=Point Multimedia Systems
+
+OUI:00013A*
+ ID_OUI_FROM_DATABASE=SHELCAD COMMUNICATIONS, LTD.
+
+OUI:00013B*
+ ID_OUI_FROM_DATABASE=BNA SYSTEMS
+
+OUI:00013C*
+ ID_OUI_FROM_DATABASE=TIW SYSTEMS
+
+OUI:00013D*
+ ID_OUI_FROM_DATABASE=RiscStation Ltd.
+
+OUI:00013E*
+ ID_OUI_FROM_DATABASE=Ascom Tateco AB
+
+OUI:00013F*
+ ID_OUI_FROM_DATABASE=Neighbor World Co., Ltd.
+
+OUI:000140*
+ ID_OUI_FROM_DATABASE=Sendtek Corporation
+
+OUI:000141*
+ ID_OUI_FROM_DATABASE=CABLE PRINT
+
+OUI:000142*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000143*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000144*
+ ID_OUI_FROM_DATABASE=EMC Corporation
+
+OUI:000145*
+ ID_OUI_FROM_DATABASE=WINSYSTEMS, INC.
+
+OUI:000146*
+ ID_OUI_FROM_DATABASE=Tesco Controls, Inc.
+
+OUI:000147*
+ ID_OUI_FROM_DATABASE=Zhone Technologies
+
+OUI:000148*
+ ID_OUI_FROM_DATABASE=X-traWeb Inc.
+
+OUI:000149*
+ ID_OUI_FROM_DATABASE=T.D.T. Transfer Data Test GmbH
+
+OUI:00014A*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:00014B*
+ ID_OUI_FROM_DATABASE=Ennovate Networks, Inc.
+
+OUI:00014C*
+ ID_OUI_FROM_DATABASE=Berkeley Process Control
+
+OUI:00014D*
+ ID_OUI_FROM_DATABASE=Shin Kin Enterprises Co., Ltd
+
+OUI:00014E*
+ ID_OUI_FROM_DATABASE=WIN Enterprises, Inc.
+
+OUI:00014F*
+ ID_OUI_FROM_DATABASE=ADTRAN INC
+
+OUI:000150*
+ ID_OUI_FROM_DATABASE=GILAT COMMUNICATIONS, LTD.
+
+OUI:000151*
+ ID_OUI_FROM_DATABASE=Ensemble Communications
+
+OUI:000152*
+ ID_OUI_FROM_DATABASE=CHROMATEK INC.
+
+OUI:000153*
+ ID_OUI_FROM_DATABASE=ARCHTEK TELECOM CORPORATION
+
+OUI:000154*
+ ID_OUI_FROM_DATABASE=G3M Corporation
+
+OUI:000155*
+ ID_OUI_FROM_DATABASE=Promise Technology, Inc.
+
+OUI:000156*
+ ID_OUI_FROM_DATABASE=FIREWIREDIRECT.COM, INC.
+
+OUI:000157*
+ ID_OUI_FROM_DATABASE=SYSWAVE CO., LTD
+
+OUI:000158*
+ ID_OUI_FROM_DATABASE=Electro Industries/Gauge Tech
+
+OUI:000159*
+ ID_OUI_FROM_DATABASE=S1 Corporation
+
+OUI:00015A*
+ ID_OUI_FROM_DATABASE=Digital Video Broadcasting
+
+OUI:00015B*
+ ID_OUI_FROM_DATABASE=ITALTEL S.p.A/RF-UP-I
+
+OUI:00015C*
+ ID_OUI_FROM_DATABASE=CADANT INC.
+
+OUI:00015D*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:00015E*
+ ID_OUI_FROM_DATABASE=BEST TECHNOLOGY CO., LTD.
+
+OUI:00015F*
+ ID_OUI_FROM_DATABASE=DIGITAL DESIGN GmbH
+
+OUI:000160*
+ ID_OUI_FROM_DATABASE=ELMEX Co., LTD.
+
+OUI:000161*
+ ID_OUI_FROM_DATABASE=Meta Machine Technology
+
+OUI:000162*
+ ID_OUI_FROM_DATABASE=Cygnet Technologies, Inc.
+
+OUI:000163*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000164*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000165*
+ ID_OUI_FROM_DATABASE=AirSwitch Corporation
+
+OUI:000166*
+ ID_OUI_FROM_DATABASE=TC GROUP A/S
+
+OUI:000167*
+ ID_OUI_FROM_DATABASE=HIOKI E.E. CORPORATION
+
+OUI:000168*
+ ID_OUI_FROM_DATABASE=VITANA CORPORATION
+
+OUI:000169*
+ ID_OUI_FROM_DATABASE=Celestix Networks Pte Ltd.
+
+OUI:00016A*
+ ID_OUI_FROM_DATABASE=ALITEC
+
+OUI:00016B*
+ ID_OUI_FROM_DATABASE=LightChip, Inc.
+
+OUI:00016C*
+ ID_OUI_FROM_DATABASE=FOXCONN
+
+OUI:00016D*
+ ID_OUI_FROM_DATABASE=CarrierComm Inc.
+
+OUI:00016E*
+ ID_OUI_FROM_DATABASE=Conklin Corporation
+
+OUI:00016F*
+ ID_OUI_FROM_DATABASE=Inkel Corp.
+
+OUI:000170*
+ ID_OUI_FROM_DATABASE=ESE Embedded System Engineer'g
+
+OUI:000171*
+ ID_OUI_FROM_DATABASE=Allied Data Technologies
+
+OUI:000172*
+ ID_OUI_FROM_DATABASE=TechnoLand Co., LTD.
+
+OUI:000173*
+ ID_OUI_FROM_DATABASE=AMCC
+
+OUI:000174*
+ ID_OUI_FROM_DATABASE=CyberOptics Corporation
+
+OUI:000175*
+ ID_OUI_FROM_DATABASE=Radiant Communications Corp.
+
+OUI:000176*
+ ID_OUI_FROM_DATABASE=Orient Silver Enterprises
+
+OUI:000177*
+ ID_OUI_FROM_DATABASE=EDSL
+
+OUI:000178*
+ ID_OUI_FROM_DATABASE=MARGI Systems, Inc.
+
+OUI:000179*
+ ID_OUI_FROM_DATABASE=WIRELESS TECHNOLOGY, INC.
+
+OUI:00017A*
+ ID_OUI_FROM_DATABASE=Chengdu Maipu Electric Industrial Co., Ltd.
+
+OUI:00017B*
+ ID_OUI_FROM_DATABASE=Heidelberger Druckmaschinen AG
+
+OUI:00017C*
+ ID_OUI_FROM_DATABASE=AG-E GmbH
+
+OUI:00017D*
+ ID_OUI_FROM_DATABASE=ThermoQuest
+
+OUI:00017E*
+ ID_OUI_FROM_DATABASE=ADTEK System Science Co., Ltd.
+
+OUI:00017F*
+ ID_OUI_FROM_DATABASE=Experience Music Project
+
+OUI:000180*
+ ID_OUI_FROM_DATABASE=AOpen, Inc.
+
+OUI:000181*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000182*
+ ID_OUI_FROM_DATABASE=DICA TECHNOLOGIES AG
+
+OUI:000183*
+ ID_OUI_FROM_DATABASE=ANITE TELECOMS
+
+OUI:000184*
+ ID_OUI_FROM_DATABASE=SIEB & MEYER AG
+
+OUI:000185*
+ ID_OUI_FROM_DATABASE=Hitachi Aloka Medical, Ltd.
+
+OUI:000186*
+ ID_OUI_FROM_DATABASE=Uwe Disch
+
+OUI:000187*
+ ID_OUI_FROM_DATABASE=i2SE GmbH
+
+OUI:000188*
+ ID_OUI_FROM_DATABASE=LXCO Technologies ag
+
+OUI:000189*
+ ID_OUI_FROM_DATABASE=Refraction Technology, Inc.
+
+OUI:00018A*
+ ID_OUI_FROM_DATABASE=ROI COMPUTER AG
+
+OUI:00018B*
+ ID_OUI_FROM_DATABASE=NetLinks Co., Ltd.
+
+OUI:00018C*
+ ID_OUI_FROM_DATABASE=Mega Vision
+
+OUI:00018D*
+ ID_OUI_FROM_DATABASE=AudeSi Technologies
+
+OUI:00018E*
+ ID_OUI_FROM_DATABASE=Logitec Corporation
+
+OUI:00018F*
+ ID_OUI_FROM_DATABASE=Kenetec, Inc.
+
+OUI:000190*
+ ID_OUI_FROM_DATABASE=SMK-M
+
+OUI:000191*
+ ID_OUI_FROM_DATABASE=SYRED Data Systems
+
+OUI:000192*
+ ID_OUI_FROM_DATABASE=Texas Digital Systems
+
+OUI:000193*
+ ID_OUI_FROM_DATABASE=Hanbyul Telecom Co., Ltd.
+
+OUI:000194*
+ ID_OUI_FROM_DATABASE=Capital Equipment Corporation
+
+OUI:000195*
+ ID_OUI_FROM_DATABASE=Sena Technologies, Inc.
+
+OUI:000196*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000197*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000198*
+ ID_OUI_FROM_DATABASE=Darim Vision
+
+OUI:000199*
+ ID_OUI_FROM_DATABASE=HeiSei Electronics
+
+OUI:00019A*
+ ID_OUI_FROM_DATABASE=LEUNIG GmbH
+
+OUI:00019B*
+ ID_OUI_FROM_DATABASE=Kyoto Microcomputer Co., Ltd.
+
+OUI:00019C*
+ ID_OUI_FROM_DATABASE=JDS Uniphase Inc.
+
+OUI:00019D*
+ ID_OUI_FROM_DATABASE=E-Control Systems, Inc.
+
+OUI:00019E*
+ ID_OUI_FROM_DATABASE=ESS Technology, Inc.
+
+OUI:00019F*
+ ID_OUI_FROM_DATABASE=ReadyNet
+
+OUI:0001A0*
+ ID_OUI_FROM_DATABASE=Infinilink Corporation
+
+OUI:0001A1*
+ ID_OUI_FROM_DATABASE=Mag-Tek, Inc.
+
+OUI:0001A2*
+ ID_OUI_FROM_DATABASE=Logical Co., Ltd.
+
+OUI:0001A3*
+ ID_OUI_FROM_DATABASE=GENESYS LOGIC, INC.
+
+OUI:0001A4*
+ ID_OUI_FROM_DATABASE=Microlink Corporation
+
+OUI:0001A5*
+ ID_OUI_FROM_DATABASE=Nextcomm, Inc.
+
+OUI:0001A6*
+ ID_OUI_FROM_DATABASE=Scientific-Atlanta Arcodan A/S
+
+OUI:0001A7*
+ ID_OUI_FROM_DATABASE=UNEX TECHNOLOGY CORPORATION
+
+OUI:0001A8*
+ ID_OUI_FROM_DATABASE=Welltech Computer Co., Ltd.
+
+OUI:0001A9*
+ ID_OUI_FROM_DATABASE=BMW AG
+
+OUI:0001AA*
+ ID_OUI_FROM_DATABASE=Airspan Communications, Ltd.
+
+OUI:0001AB*
+ ID_OUI_FROM_DATABASE=Main Street Networks
+
+OUI:0001AC*
+ ID_OUI_FROM_DATABASE=Sitara Networks, Inc.
+
+OUI:0001AD*
+ ID_OUI_FROM_DATABASE=Coach Master International  d.b.a. CMI Worldwide, Inc.
+
+OUI:0001AE*
+ ID_OUI_FROM_DATABASE=Trex Enterprises
+
+OUI:0001AF*
+ ID_OUI_FROM_DATABASE=Emerson Network Power
+
+OUI:0001B0*
+ ID_OUI_FROM_DATABASE=Fulltek Technology Co., Ltd.
+
+OUI:0001B1*
+ ID_OUI_FROM_DATABASE=General Bandwidth
+
+OUI:0001B2*
+ ID_OUI_FROM_DATABASE=Digital Processing Systems, Inc.
+
+OUI:0001B3*
+ ID_OUI_FROM_DATABASE=Precision Electronic Manufacturing
+
+OUI:0001B4*
+ ID_OUI_FROM_DATABASE=Wayport, Inc.
+
+OUI:0001B5*
+ ID_OUI_FROM_DATABASE=Turin Networks, Inc.
+
+OUI:0001B6*
+ ID_OUI_FROM_DATABASE=SAEJIN T&M Co., Ltd.
+
+OUI:0001B7*
+ ID_OUI_FROM_DATABASE=Centos, Inc.
+
+OUI:0001B8*
+ ID_OUI_FROM_DATABASE=Netsensity, Inc.
+
+OUI:0001B9*
+ ID_OUI_FROM_DATABASE=SKF Condition Monitoring
+
+OUI:0001BA*
+ ID_OUI_FROM_DATABASE=IC-Net, Inc.
+
+OUI:0001BB*
+ ID_OUI_FROM_DATABASE=Frequentis
+
+OUI:0001BC*
+ ID_OUI_FROM_DATABASE=Brains Corporation
+
+OUI:0001BD*
+ ID_OUI_FROM_DATABASE=Peterson Electro-Musical Products, Inc.
+
+OUI:0001BE*
+ ID_OUI_FROM_DATABASE=Gigalink Co., Ltd.
+
+OUI:0001BF*
+ ID_OUI_FROM_DATABASE=Teleforce Co., Ltd.
+
+OUI:0001C0*
+ ID_OUI_FROM_DATABASE=CompuLab, Ltd.
+
+OUI:0001C1*
+ ID_OUI_FROM_DATABASE=Vitesse Semiconductor Corporation
+
+OUI:0001C2*
+ ID_OUI_FROM_DATABASE=ARK Research Corp.
+
+OUI:0001C3*
+ ID_OUI_FROM_DATABASE=Acromag, Inc.
+
+OUI:0001C4*
+ ID_OUI_FROM_DATABASE=NeoWave, Inc.
+
+OUI:0001C5*
+ ID_OUI_FROM_DATABASE=Simpler Networks
+
+OUI:0001C6*
+ ID_OUI_FROM_DATABASE=Quarry Technologies
+
+OUI:0001C7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0001C8*
+ ID_OUI_FROM_DATABASE=THOMAS CONRAD CORP.
+
+OUI:0001C8*
+ ID_OUI_FROM_DATABASE=CONRAD CORP.
+
+OUI:0001C9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0001CA*
+ ID_OUI_FROM_DATABASE=Geocast Network Systems, Inc.
+
+OUI:0001CB*
+ ID_OUI_FROM_DATABASE=EVR
+
+OUI:0001CC*
+ ID_OUI_FROM_DATABASE=Japan Total Design Communication Co., Ltd.
+
+OUI:0001CD*
+ ID_OUI_FROM_DATABASE=ARtem
+
+OUI:0001CE*
+ ID_OUI_FROM_DATABASE=Custom Micro Products, Ltd.
+
+OUI:0001CF*
+ ID_OUI_FROM_DATABASE=Alpha Data Parallel Systems, Ltd.
+
+OUI:0001D0*
+ ID_OUI_FROM_DATABASE=VitalPoint, Inc.
+
+OUI:0001D1*
+ ID_OUI_FROM_DATABASE=CoNet Communications, Inc.
+
+OUI:0001D2*
+ ID_OUI_FROM_DATABASE=inXtron, Inc.
+
+OUI:0001D3*
+ ID_OUI_FROM_DATABASE=PAXCOMM, Inc.
+
+OUI:0001D4*
+ ID_OUI_FROM_DATABASE=Leisure Time, Inc.
+
+OUI:0001D5*
+ ID_OUI_FROM_DATABASE=HAEDONG INFO & COMM CO., LTD
+
+OUI:0001D6*
+ ID_OUI_FROM_DATABASE=manroland AG
+
+OUI:0001D7*
+ ID_OUI_FROM_DATABASE=F5 Networks, Inc.
+
+OUI:0001D8*
+ ID_OUI_FROM_DATABASE=Teltronics, Inc.
+
+OUI:0001D9*
+ ID_OUI_FROM_DATABASE=Sigma, Inc.
+
+OUI:0001DA*
+ ID_OUI_FROM_DATABASE=WINCOMM Corporation
+
+OUI:0001DB*
+ ID_OUI_FROM_DATABASE=Freecom Technologies GmbH
+
+OUI:0001DC*
+ ID_OUI_FROM_DATABASE=Activetelco
+
+OUI:0001DD*
+ ID_OUI_FROM_DATABASE=Avail Networks
+
+OUI:0001DE*
+ ID_OUI_FROM_DATABASE=Trango Systems, Inc.
+
+OUI:0001DF*
+ ID_OUI_FROM_DATABASE=ISDN Communications, Ltd.
+
+OUI:0001E0*
+ ID_OUI_FROM_DATABASE=Fast Systems, Inc.
+
+OUI:0001E1*
+ ID_OUI_FROM_DATABASE=Kinpo Electronics, Inc.
+
+OUI:0001E2*
+ ID_OUI_FROM_DATABASE=Ando Electric Corporation
+
+OUI:0001E3*
+ ID_OUI_FROM_DATABASE=Siemens AG
+
+OUI:0001E4*
+ ID_OUI_FROM_DATABASE=Sitera, Inc.
+
+OUI:0001E5*
+ ID_OUI_FROM_DATABASE=Supernet, Inc.
+
+OUI:0001E6*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0001E7*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0001E8*
+ ID_OUI_FROM_DATABASE=Force10 Networks, Inc.
+
+OUI:0001E9*
+ ID_OUI_FROM_DATABASE=Litton Marine Systems B.V.
+
+OUI:0001EA*
+ ID_OUI_FROM_DATABASE=Cirilium Corp.
+
+OUI:0001EB*
+ ID_OUI_FROM_DATABASE=C-COM Corporation
+
+OUI:0001EC*
+ ID_OUI_FROM_DATABASE=Ericsson Group
+
+OUI:0001ED*
+ ID_OUI_FROM_DATABASE=SETA Corp.
+
+OUI:0001EE*
+ ID_OUI_FROM_DATABASE=Comtrol Europe, Ltd.
+
+OUI:0001EF*
+ ID_OUI_FROM_DATABASE=Camtel Technology Corp.
+
+OUI:0001F0*
+ ID_OUI_FROM_DATABASE=Tridium, Inc.
+
+OUI:0001F1*
+ ID_OUI_FROM_DATABASE=Innovative Concepts, Inc.
+
+OUI:0001F2*
+ ID_OUI_FROM_DATABASE=Mark of the Unicorn, Inc.
+
+OUI:0001F3*
+ ID_OUI_FROM_DATABASE=QPS, Inc.
+
+OUI:0001F4*
+ ID_OUI_FROM_DATABASE=Enterasys Networks
+
+OUI:0001F5*
+ ID_OUI_FROM_DATABASE=ERIM S.A.
+
+OUI:0001F6*
+ ID_OUI_FROM_DATABASE=Association of Musical Electronics Industry
+
+OUI:0001F7*
+ ID_OUI_FROM_DATABASE=Image Display Systems, Inc.
+
+OUI:0001F8*
+ ID_OUI_FROM_DATABASE=Adherent Systems, Ltd.
+
+OUI:0001F9*
+ ID_OUI_FROM_DATABASE=TeraGlobal Communications Corp.
+
+OUI:0001FA*
+ ID_OUI_FROM_DATABASE=HOROSCAS
+
+OUI:0001FB*
+ ID_OUI_FROM_DATABASE=DoTop Technology, Inc.
+
+OUI:0001FC*
+ ID_OUI_FROM_DATABASE=Keyence Corporation
+
+OUI:0001FD*
+ ID_OUI_FROM_DATABASE=Digital Voice Systems, Inc.
+
+OUI:0001FE*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:0001FF*
+ ID_OUI_FROM_DATABASE=Data Direct Networks, Inc.
+
+OUI:000200*
+ ID_OUI_FROM_DATABASE=Net & Sys Co., Ltd.
+
+OUI:000201*
+ ID_OUI_FROM_DATABASE=IFM Electronic gmbh
+
+OUI:000202*
+ ID_OUI_FROM_DATABASE=Amino Communications, Ltd.
+
+OUI:000203*
+ ID_OUI_FROM_DATABASE=Woonsang Telecom, Inc.
+
+OUI:000204*
+ ID_OUI_FROM_DATABASE=Bodmann Industries Elektronik GmbH
+
+OUI:000205*
+ ID_OUI_FROM_DATABASE=Hitachi Denshi, Ltd.
+
+OUI:000206*
+ ID_OUI_FROM_DATABASE=Telital R&D Denmark A/S
+
+OUI:000207*
+ ID_OUI_FROM_DATABASE=VisionGlobal Network Corp.
+
+OUI:000208*
+ ID_OUI_FROM_DATABASE=Unify Networks, Inc.
+
+OUI:000209*
+ ID_OUI_FROM_DATABASE=Shenzhen SED Information Technology Co., Ltd.
+
+OUI:00020A*
+ ID_OUI_FROM_DATABASE=Gefran Spa
+
+OUI:00020B*
+ ID_OUI_FROM_DATABASE=Native Networks, Inc.
+
+OUI:00020C*
+ ID_OUI_FROM_DATABASE=Metro-Optix
+
+OUI:00020D*
+ ID_OUI_FROM_DATABASE=Micronpc.com
+
+OUI:00020E*
+ ID_OUI_FROM_DATABASE=ECI Telecom, Ltd., NSD-US
+
+OUI:00020F*
+ ID_OUI_FROM_DATABASE=AATR
+
+OUI:000210*
+ ID_OUI_FROM_DATABASE=Fenecom
+
+OUI:000211*
+ ID_OUI_FROM_DATABASE=Nature Worldwide Technology Corp.
+
+OUI:000212*
+ ID_OUI_FROM_DATABASE=SierraCom
+
+OUI:000213*
+ ID_OUI_FROM_DATABASE=S.D.E.L.
+
+OUI:000214*
+ ID_OUI_FROM_DATABASE=DTVRO
+
+OUI:000215*
+ ID_OUI_FROM_DATABASE=Cotas Computer Technology A/B
+
+OUI:000216*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000217*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000218*
+ ID_OUI_FROM_DATABASE=Advanced Scientific Corp
+
+OUI:000219*
+ ID_OUI_FROM_DATABASE=Paralon Technologies
+
+OUI:00021A*
+ ID_OUI_FROM_DATABASE=Zuma Networks
+
+OUI:00021B*
+ ID_OUI_FROM_DATABASE=Kollmorgen-Servotronix
+
+OUI:00021C*
+ ID_OUI_FROM_DATABASE=Network Elements, Inc.
+
+OUI:00021D*
+ ID_OUI_FROM_DATABASE=Data General Communication Ltd.
+
+OUI:00021E*
+ ID_OUI_FROM_DATABASE=SIMTEL S.R.L.
+
+OUI:00021F*
+ ID_OUI_FROM_DATABASE=Aculab PLC
+
+OUI:000220*
+ ID_OUI_FROM_DATABASE=CANON FINETECH INC.
+
+OUI:000221*
+ ID_OUI_FROM_DATABASE=DSP Application, Ltd.
+
+OUI:000222*
+ ID_OUI_FROM_DATABASE=Chromisys, Inc.
+
+OUI:000223*
+ ID_OUI_FROM_DATABASE=ClickTV
+
+OUI:000224*
+ ID_OUI_FROM_DATABASE=C-COR
+
+OUI:000225*
+ ID_OUI_FROM_DATABASE=One Stop Systems
+
+OUI:000226*
+ ID_OUI_FROM_DATABASE=XESystems, Inc.
+
+OUI:000227*
+ ID_OUI_FROM_DATABASE=ESD Electronic System Design GmbH
+
+OUI:000228*
+ ID_OUI_FROM_DATABASE=Necsom, Ltd.
+
+OUI:000229*
+ ID_OUI_FROM_DATABASE=Adtec Corporation
+
+OUI:00022A*
+ ID_OUI_FROM_DATABASE=Asound Electronic
+
+OUI:00022B*
+ ID_OUI_FROM_DATABASE=SAXA, Inc.
+
+OUI:00022C*
+ ID_OUI_FROM_DATABASE=ABB Bomem, Inc.
+
+OUI:00022D*
+ ID_OUI_FROM_DATABASE=Agere Systems
+
+OUI:00022E*
+ ID_OUI_FROM_DATABASE=TEAC Corp. R& D
+
+OUI:00022F*
+ ID_OUI_FROM_DATABASE=P-Cube, Ltd.
+
+OUI:000230*
+ ID_OUI_FROM_DATABASE=Intersoft Electronics
+
+OUI:000231*
+ ID_OUI_FROM_DATABASE=Ingersoll-Rand
+
+OUI:000232*
+ ID_OUI_FROM_DATABASE=Avision, Inc.
+
+OUI:000233*
+ ID_OUI_FROM_DATABASE=Mantra Communications, Inc.
+
+OUI:000234*
+ ID_OUI_FROM_DATABASE=Imperial Technology, Inc.
+
+OUI:000235*
+ ID_OUI_FROM_DATABASE=Paragon Networks International
+
+OUI:000236*
+ ID_OUI_FROM_DATABASE=INIT GmbH
+
+OUI:000237*
+ ID_OUI_FROM_DATABASE=Cosmo Research Corp.
+
+OUI:000238*
+ ID_OUI_FROM_DATABASE=Serome Technology, Inc.
+
+OUI:000239*
+ ID_OUI_FROM_DATABASE=Visicom
+
+OUI:00023A*
+ ID_OUI_FROM_DATABASE=ZSK Stickmaschinen GmbH
+
+OUI:00023B*
+ ID_OUI_FROM_DATABASE=Ericsson
+
+OUI:00023C*
+ ID_OUI_FROM_DATABASE=Creative Technology, Ltd.
+
+OUI:00023D*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc.
+
+OUI:00023E*
+ ID_OUI_FROM_DATABASE=Selta Telematica S.p.a
+
+OUI:00023F*
+ ID_OUI_FROM_DATABASE=Compal Electronics, Inc.
+
+OUI:000240*
+ ID_OUI_FROM_DATABASE=Seedek Co., Ltd.
+
+OUI:000241*
+ ID_OUI_FROM_DATABASE=Amer.com
+
+OUI:000242*
+ ID_OUI_FROM_DATABASE=Videoframe Systems
+
+OUI:000243*
+ ID_OUI_FROM_DATABASE=Raysis Co., Ltd.
+
+OUI:000244*
+ ID_OUI_FROM_DATABASE=SURECOM Technology Co.
+
+OUI:000245*
+ ID_OUI_FROM_DATABASE=Lampus Co, Ltd.
+
+OUI:000246*
+ ID_OUI_FROM_DATABASE=All-Win Tech Co., Ltd.
+
+OUI:000247*
+ ID_OUI_FROM_DATABASE=Great Dragon Information Technology (Group) Co., Ltd.
+
+OUI:000248*
+ ID_OUI_FROM_DATABASE=Pilz GmbH & Co.
+
+OUI:000249*
+ ID_OUI_FROM_DATABASE=Aviv Infocom Co, Ltd.
+
+OUI:00024A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00024B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00024C*
+ ID_OUI_FROM_DATABASE=SiByte, Inc.
+
+OUI:00024D*
+ ID_OUI_FROM_DATABASE=Mannesman Dematic Colby Pty. Ltd.
+
+OUI:00024E*
+ ID_OUI_FROM_DATABASE=Datacard Group
+
+OUI:00024F*
+ ID_OUI_FROM_DATABASE=IPM Datacom S.R.L.
+
+OUI:000250*
+ ID_OUI_FROM_DATABASE=Geyser Networks, Inc.
+
+OUI:000251*
+ ID_OUI_FROM_DATABASE=Soma Networks, Inc.
+
+OUI:000252*
+ ID_OUI_FROM_DATABASE=Carrier Corporation
+
+OUI:000253*
+ ID_OUI_FROM_DATABASE=Televideo, Inc.
+
+OUI:000254*
+ ID_OUI_FROM_DATABASE=WorldGate
+
+OUI:000255*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:000256*
+ ID_OUI_FROM_DATABASE=Alpha Processor, Inc.
+
+OUI:000257*
+ ID_OUI_FROM_DATABASE=Microcom Corp.
+
+OUI:000258*
+ ID_OUI_FROM_DATABASE=Flying Packets Communications
+
+OUI:000259*
+ ID_OUI_FROM_DATABASE=Tsann Kuen China (Shanghai)Enterprise Co., Ltd. IT Group
+
+OUI:00025A*
+ ID_OUI_FROM_DATABASE=Catena Networks
+
+OUI:00025B*
+ ID_OUI_FROM_DATABASE=Cambridge Silicon Radio
+
+OUI:00025C*
+ ID_OUI_FROM_DATABASE=SCI Systems (Kunshan) Co., Ltd.
+
+OUI:00025D*
+ ID_OUI_FROM_DATABASE=Calix Networks
+
+OUI:00025E*
+ ID_OUI_FROM_DATABASE=High Technology Ltd
+
+OUI:00025F*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000260*
+ ID_OUI_FROM_DATABASE=Accordion Networks, Inc.
+
+OUI:000261*
+ ID_OUI_FROM_DATABASE=Tilgin AB
+
+OUI:000262*
+ ID_OUI_FROM_DATABASE=Soyo Group Soyo Com Tech Co., Ltd
+
+OUI:000263*
+ ID_OUI_FROM_DATABASE=UPS Manufacturing SRL
+
+OUI:000264*
+ ID_OUI_FROM_DATABASE=AudioRamp.com
+
+OUI:000265*
+ ID_OUI_FROM_DATABASE=Virditech Co. Ltd.
+
+OUI:000266*
+ ID_OUI_FROM_DATABASE=Thermalogic Corporation
+
+OUI:000267*
+ ID_OUI_FROM_DATABASE=NODE RUNNER, INC.
+
+OUI:000268*
+ ID_OUI_FROM_DATABASE=Harris Government Communications
+
+OUI:000269*
+ ID_OUI_FROM_DATABASE=Nadatel Co., Ltd
+
+OUI:00026A*
+ ID_OUI_FROM_DATABASE=Cocess Telecom Co., Ltd.
+
+OUI:00026B*
+ ID_OUI_FROM_DATABASE=BCM Computers Co., Ltd.
+
+OUI:00026C*
+ ID_OUI_FROM_DATABASE=Philips CFT
+
+OUI:00026D*
+ ID_OUI_FROM_DATABASE=Adept Telecom
+
+OUI:00026E*
+ ID_OUI_FROM_DATABASE=NeGeN Access, Inc.
+
+OUI:00026F*
+ ID_OUI_FROM_DATABASE=Senao International Co., Ltd.
+
+OUI:000270*
+ ID_OUI_FROM_DATABASE=Crewave Co., Ltd.
+
+OUI:000271*
+ ID_OUI_FROM_DATABASE=Zhone Technologies
+
+OUI:000272*
+ ID_OUI_FROM_DATABASE=CC&C Technologies, Inc.
+
+OUI:000273*
+ ID_OUI_FROM_DATABASE=Coriolis Networks
+
+OUI:000274*
+ ID_OUI_FROM_DATABASE=Tommy Technologies Corp.
+
+OUI:000275*
+ ID_OUI_FROM_DATABASE=SMART Technologies, Inc.
+
+OUI:000276*
+ ID_OUI_FROM_DATABASE=Primax Electronics Ltd.
+
+OUI:000277*
+ ID_OUI_FROM_DATABASE=Cash Systemes Industrie
+
+OUI:000278*
+ ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics Co., Ltd.
+
+OUI:000279*
+ ID_OUI_FROM_DATABASE=Control Applications, Ltd.
+
+OUI:00027A*
+ ID_OUI_FROM_DATABASE=IOI Technology Corporation
+
+OUI:00027B*
+ ID_OUI_FROM_DATABASE=Amplify Net, Inc.
+
+OUI:00027C*
+ ID_OUI_FROM_DATABASE=Trilithic, Inc.
+
+OUI:00027D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00027E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00027F*
+ ID_OUI_FROM_DATABASE=ask-technologies.com
+
+OUI:000280*
+ ID_OUI_FROM_DATABASE=Mu Net, Inc.
+
+OUI:000281*
+ ID_OUI_FROM_DATABASE=Madge Ltd.
+
+OUI:000282*
+ ID_OUI_FROM_DATABASE=ViaClix, Inc.
+
+OUI:000283*
+ ID_OUI_FROM_DATABASE=Spectrum Controls, Inc.
+
+OUI:000284*
+ ID_OUI_FROM_DATABASE=AREVA T&D
+
+OUI:000285*
+ ID_OUI_FROM_DATABASE=Riverstone Networks
+
+OUI:000286*
+ ID_OUI_FROM_DATABASE=Occam Networks
+
+OUI:000287*
+ ID_OUI_FROM_DATABASE=Adapcom
+
+OUI:000288*
+ ID_OUI_FROM_DATABASE=GLOBAL VILLAGE COMMUNICATION
+
+OUI:000289*
+ ID_OUI_FROM_DATABASE=DNE Technologies
+
+OUI:00028A*
+ ID_OUI_FROM_DATABASE=Ambit Microsystems Corporation
+
+OUI:00028B*
+ ID_OUI_FROM_DATABASE=VDSL Systems OY
+
+OUI:00028C*
+ ID_OUI_FROM_DATABASE=Micrel-Synergy Semiconductor
+
+OUI:00028D*
+ ID_OUI_FROM_DATABASE=Movita Technologies, Inc.
+
+OUI:00028E*
+ ID_OUI_FROM_DATABASE=Rapid 5 Networks, Inc.
+
+OUI:00028F*
+ ID_OUI_FROM_DATABASE=Globetek, Inc.
+
+OUI:000290*
+ ID_OUI_FROM_DATABASE=Woorigisool, Inc.
+
+OUI:000291*
+ ID_OUI_FROM_DATABASE=Open Network Co., Ltd.
+
+OUI:000292*
+ ID_OUI_FROM_DATABASE=Logic Innovations, Inc.
+
+OUI:000293*
+ ID_OUI_FROM_DATABASE=Solid Data Systems
+
+OUI:000294*
+ ID_OUI_FROM_DATABASE=Tokyo Sokushin Co., Ltd.
+
+OUI:000295*
+ ID_OUI_FROM_DATABASE=IP.Access Limited
+
+OUI:000296*
+ ID_OUI_FROM_DATABASE=Lectron Co,. Ltd.
+
+OUI:000297*
+ ID_OUI_FROM_DATABASE=C-COR.net
+
+OUI:000298*
+ ID_OUI_FROM_DATABASE=Broadframe Corporation
+
+OUI:000299*
+ ID_OUI_FROM_DATABASE=Apex, Inc.
+
+OUI:00029A*
+ ID_OUI_FROM_DATABASE=Storage Apps
+
+OUI:00029B*
+ ID_OUI_FROM_DATABASE=Kreatel Communications AB
+
+OUI:00029C*
+ ID_OUI_FROM_DATABASE=3COM
+
+OUI:00029D*
+ ID_OUI_FROM_DATABASE=Merix Corp.
+
+OUI:00029E*
+ ID_OUI_FROM_DATABASE=Information Equipment Co., Ltd.
+
+OUI:00029F*
+ ID_OUI_FROM_DATABASE=L-3 Communication Aviation Recorders
+
+OUI:0002A0*
+ ID_OUI_FROM_DATABASE=Flatstack Ltd.
+
+OUI:0002A1*
+ ID_OUI_FROM_DATABASE=World Wide Packets
+
+OUI:0002A2*
+ ID_OUI_FROM_DATABASE=Hilscher GmbH
+
+OUI:0002A3*
+ ID_OUI_FROM_DATABASE=ABB Switzerland Ltd, Power Systems
+
+OUI:0002A4*
+ ID_OUI_FROM_DATABASE=AddPac Technology Co., Ltd.
+
+OUI:0002A5*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0002A6*
+ ID_OUI_FROM_DATABASE=Effinet Systems Co., Ltd.
+
+OUI:0002A7*
+ ID_OUI_FROM_DATABASE=Vivace Networks
+
+OUI:0002A8*
+ ID_OUI_FROM_DATABASE=Air Link Technology
+
+OUI:0002A9*
+ ID_OUI_FROM_DATABASE=RACOM, s.r.o.
+
+OUI:0002AA*
+ ID_OUI_FROM_DATABASE=PLcom Co., Ltd.
+
+OUI:0002AB*
+ ID_OUI_FROM_DATABASE=CTC Union Technologies Co., Ltd.
+
+OUI:0002AC*
+ ID_OUI_FROM_DATABASE=3PAR data
+
+OUI:0002AD*
+ ID_OUI_FROM_DATABASE=HOYA Corporation
+
+OUI:0002AE*
+ ID_OUI_FROM_DATABASE=Scannex Electronics Ltd.
+
+OUI:0002AF*
+ ID_OUI_FROM_DATABASE=TeleCruz Technology, Inc.
+
+OUI:0002B0*
+ ID_OUI_FROM_DATABASE=Hokubu Communication & Industrial Co., Ltd.
+
+OUI:0002B1*
+ ID_OUI_FROM_DATABASE=Anritsu, Ltd.
+
+OUI:0002B2*
+ ID_OUI_FROM_DATABASE=Cablevision
+
+OUI:0002B3*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0002B4*
+ ID_OUI_FROM_DATABASE=DAPHNE
+
+OUI:0002B5*
+ ID_OUI_FROM_DATABASE=Avnet, Inc.
+
+OUI:0002B6*
+ ID_OUI_FROM_DATABASE=Acrosser Technology Co., Ltd.
+
+OUI:0002B7*
+ ID_OUI_FROM_DATABASE=Watanabe Electric Industry Co., Ltd.
+
+OUI:0002B8*
+ ID_OUI_FROM_DATABASE=WHI KONSULT AB
+
+OUI:0002B9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0002BA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0002BB*
+ ID_OUI_FROM_DATABASE=Continuous Computing Corp
+
+OUI:0002BC*
+ ID_OUI_FROM_DATABASE=LVL 7 Systems, Inc.
+
+OUI:0002BD*
+ ID_OUI_FROM_DATABASE=Bionet Co., Ltd.
+
+OUI:0002BE*
+ ID_OUI_FROM_DATABASE=Totsu Engineering, Inc.
+
+OUI:0002BF*
+ ID_OUI_FROM_DATABASE=dotRocket, Inc.
+
+OUI:0002C0*
+ ID_OUI_FROM_DATABASE=Bencent Tzeng Industry Co., Ltd.
+
+OUI:0002C1*
+ ID_OUI_FROM_DATABASE=Innovative Electronic Designs, Inc.
+
+OUI:0002C2*
+ ID_OUI_FROM_DATABASE=Net Vision Telecom
+
+OUI:0002C3*
+ ID_OUI_FROM_DATABASE=Arelnet Ltd.
+
+OUI:0002C4*
+ ID_OUI_FROM_DATABASE=Vector International BVBA
+
+OUI:0002C5*
+ ID_OUI_FROM_DATABASE=Evertz Microsystems Ltd.
+
+OUI:0002C6*
+ ID_OUI_FROM_DATABASE=Data Track Technology PLC
+
+OUI:0002C7*
+ ID_OUI_FROM_DATABASE=ALPS ELECTRIC Co., Ltd.
+
+OUI:0002C8*
+ ID_OUI_FROM_DATABASE=Technocom Communications Technology (pte) Ltd
+
+OUI:0002C9*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies
+
+OUI:0002CA*
+ ID_OUI_FROM_DATABASE=EndPoints, Inc.
+
+OUI:0002CB*
+ ID_OUI_FROM_DATABASE=TriState Ltd.
+
+OUI:0002CC*
+ ID_OUI_FROM_DATABASE=M.C.C.I
+
+OUI:0002CD*
+ ID_OUI_FROM_DATABASE=TeleDream, Inc.
+
+OUI:0002CE*
+ ID_OUI_FROM_DATABASE=FoxJet, Inc.
+
+OUI:0002CF*
+ ID_OUI_FROM_DATABASE=ZyGate Communications, Inc.
+
+OUI:0002D0*
+ ID_OUI_FROM_DATABASE=Comdial Corporation
+
+OUI:0002D1*
+ ID_OUI_FROM_DATABASE=Vivotek, Inc.
+
+OUI:0002D2*
+ ID_OUI_FROM_DATABASE=Workstation AG
+
+OUI:0002D3*
+ ID_OUI_FROM_DATABASE=NetBotz, Inc.
+
+OUI:0002D4*
+ ID_OUI_FROM_DATABASE=PDA Peripherals, Inc.
+
+OUI:0002D5*
+ ID_OUI_FROM_DATABASE=ACR
+
+OUI:0002D6*
+ ID_OUI_FROM_DATABASE=NICE Systems
+
+OUI:0002D7*
+ ID_OUI_FROM_DATABASE=EMPEG Ltd
+
+OUI:0002D8*
+ ID_OUI_FROM_DATABASE=BRECIS Communications Corporation
+
+OUI:0002D9*
+ ID_OUI_FROM_DATABASE=Reliable Controls
+
+OUI:0002DA*
+ ID_OUI_FROM_DATABASE=ExiO Communications, Inc.
+
+OUI:0002DB*
+ ID_OUI_FROM_DATABASE=NETSEC
+
+OUI:0002DC*
+ ID_OUI_FROM_DATABASE=Fujitsu General Limited
+
+OUI:0002DD*
+ ID_OUI_FROM_DATABASE=Bromax Communications, Ltd.
+
+OUI:0002DE*
+ ID_OUI_FROM_DATABASE=Astrodesign, Inc.
+
+OUI:0002DF*
+ ID_OUI_FROM_DATABASE=Net Com Systems, Inc.
+
+OUI:0002E0*
+ ID_OUI_FROM_DATABASE=ETAS GmbH
+
+OUI:0002E1*
+ ID_OUI_FROM_DATABASE=Integrated Network Corporation
+
+OUI:0002E2*
+ ID_OUI_FROM_DATABASE=NDC Infared Engineering
+
+OUI:0002E3*
+ ID_OUI_FROM_DATABASE=LITE-ON Communications, Inc.
+
+OUI:0002E4*
+ ID_OUI_FROM_DATABASE=JC HYUN Systems, Inc.
+
+OUI:0002E5*
+ ID_OUI_FROM_DATABASE=Timeware Ltd.
+
+OUI:0002E6*
+ ID_OUI_FROM_DATABASE=Gould Instrument Systems, Inc.
+
+OUI:0002E7*
+ ID_OUI_FROM_DATABASE=CAB GmbH & Co KG
+
+OUI:0002E8*
+ ID_OUI_FROM_DATABASE=E.D.&A.
+
+OUI:0002E9*
+ ID_OUI_FROM_DATABASE=CS Systemes De Securite - C3S
+
+OUI:0002EA*
+ ID_OUI_FROM_DATABASE=Focus Enhancements
+
+OUI:0002EB*
+ ID_OUI_FROM_DATABASE=Pico Communications
+
+OUI:0002EC*
+ ID_OUI_FROM_DATABASE=Maschoff Design Engineering
+
+OUI:0002ED*
+ ID_OUI_FROM_DATABASE=DXO Telecom Co., Ltd.
+
+OUI:0002EE*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0002EF*
+ ID_OUI_FROM_DATABASE=CCC Network Systems Group Ltd.
+
+OUI:0002F0*
+ ID_OUI_FROM_DATABASE=AME Optimedia Technology Co., Ltd.
+
+OUI:0002F1*
+ ID_OUI_FROM_DATABASE=Pinetron Co., Ltd.
+
+OUI:0002F2*
+ ID_OUI_FROM_DATABASE=eDevice, Inc.
+
+OUI:0002F3*
+ ID_OUI_FROM_DATABASE=Media Serve Co., Ltd.
+
+OUI:0002F4*
+ ID_OUI_FROM_DATABASE=PCTEL, Inc.
+
+OUI:0002F5*
+ ID_OUI_FROM_DATABASE=VIVE Synergies, Inc.
+
+OUI:0002F6*
+ ID_OUI_FROM_DATABASE=Equipe Communications
+
+OUI:0002F7*
+ ID_OUI_FROM_DATABASE=ARM
+
+OUI:0002F8*
+ ID_OUI_FROM_DATABASE=SEAKR Engineering, Inc.
+
+OUI:0002F9*
+ ID_OUI_FROM_DATABASE=Mimos Semiconductor SDN BHD
+
+OUI:0002FA*
+ ID_OUI_FROM_DATABASE=DX Antenna Co., Ltd.
+
+OUI:0002FB*
+ ID_OUI_FROM_DATABASE=Baumuller Aulugen-Systemtechnik GmbH
+
+OUI:0002FC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0002FD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0002FE*
+ ID_OUI_FROM_DATABASE=Viditec, Inc.
+
+OUI:0002FF*
+ ID_OUI_FROM_DATABASE=Handan BroadInfoCom
+
+OUI:000300*
+ ID_OUI_FROM_DATABASE=Barracuda Networks, Inc.
+
+OUI:000301*
+ ID_OUI_FROM_DATABASE=Avantas Networks Corporation
+
+OUI:000302*
+ ID_OUI_FROM_DATABASE=Charles Industries, Ltd.
+
+OUI:000303*
+ ID_OUI_FROM_DATABASE=JAMA Electronics Co., Ltd.
+
+OUI:000304*
+ ID_OUI_FROM_DATABASE=Pacific Broadband Communications
+
+OUI:000305*
+ ID_OUI_FROM_DATABASE=MSC Vertriebs GmbH
+
+OUI:000306*
+ ID_OUI_FROM_DATABASE=Fusion In Tech Co., Ltd.
+
+OUI:000307*
+ ID_OUI_FROM_DATABASE=Secure Works, Inc.
+
+OUI:000308*
+ ID_OUI_FROM_DATABASE=AM Communications, Inc.
+
+OUI:000309*
+ ID_OUI_FROM_DATABASE=Texcel Technology PLC
+
+OUI:00030A*
+ ID_OUI_FROM_DATABASE=Argus Technologies
+
+OUI:00030B*
+ ID_OUI_FROM_DATABASE=Hunter Technology, Inc.
+
+OUI:00030C*
+ ID_OUI_FROM_DATABASE=Telesoft Technologies Ltd.
+
+OUI:00030D*
+ ID_OUI_FROM_DATABASE=Uniwill Computer Corp.
+
+OUI:00030E*
+ ID_OUI_FROM_DATABASE=Core Communications Co., Ltd.
+
+OUI:00030F*
+ ID_OUI_FROM_DATABASE=Digital China (Shanghai) Networks Ltd.
+
+OUI:000310*
+ ID_OUI_FROM_DATABASE=ITX E-Globaledge Corporation
+
+OUI:000311*
+ ID_OUI_FROM_DATABASE=Micro Technology Co., Ltd.
+
+OUI:000312*
+ ID_OUI_FROM_DATABASE=TR-Systemtechnik GmbH
+
+OUI:000313*
+ ID_OUI_FROM_DATABASE=Access Media SPA
+
+OUI:000314*
+ ID_OUI_FROM_DATABASE=Teleware Network Systems
+
+OUI:000315*
+ ID_OUI_FROM_DATABASE=Cidco Incorporated
+
+OUI:000316*
+ ID_OUI_FROM_DATABASE=Nobell Communications, Inc.
+
+OUI:000317*
+ ID_OUI_FROM_DATABASE=Merlin Systems, Inc.
+
+OUI:000318*
+ ID_OUI_FROM_DATABASE=Cyras Systems, Inc.
+
+OUI:000319*
+ ID_OUI_FROM_DATABASE=Infineon AG
+
+OUI:00031A*
+ ID_OUI_FROM_DATABASE=Beijing Broad Telecom Ltd., China
+
+OUI:00031B*
+ ID_OUI_FROM_DATABASE=Cellvision Systems, Inc.
+
+OUI:00031C*
+ ID_OUI_FROM_DATABASE=Svenska Hardvarufabriken AB
+
+OUI:00031D*
+ ID_OUI_FROM_DATABASE=Taiwan Commate Computer, Inc.
+
+OUI:00031E*
+ ID_OUI_FROM_DATABASE=Optranet, Inc.
+
+OUI:00031F*
+ ID_OUI_FROM_DATABASE=Condev Ltd.
+
+OUI:000320*
+ ID_OUI_FROM_DATABASE=Xpeed, Inc.
+
+OUI:000321*
+ ID_OUI_FROM_DATABASE=Reco Research Co., Ltd.
+
+OUI:000322*
+ ID_OUI_FROM_DATABASE=IDIS Co., Ltd.
+
+OUI:000323*
+ ID_OUI_FROM_DATABASE=Cornet Technology, Inc.
+
+OUI:000324*
+ ID_OUI_FROM_DATABASE=SANYO Consumer Electronics Co., Ltd.
+
+OUI:000325*
+ ID_OUI_FROM_DATABASE=Arima Computer Corp.
+
+OUI:000326*
+ ID_OUI_FROM_DATABASE=Iwasaki Information Systems Co., Ltd.
+
+OUI:000327*
+ ID_OUI_FROM_DATABASE=ACT'L
+
+OUI:000328*
+ ID_OUI_FROM_DATABASE=Mace Group, Inc.
+
+OUI:000329*
+ ID_OUI_FROM_DATABASE=F3, Inc.
+
+OUI:00032A*
+ ID_OUI_FROM_DATABASE=UniData Communication Systems, Inc.
+
+OUI:00032B*
+ ID_OUI_FROM_DATABASE=GAI Datenfunksysteme GmbH
+
+OUI:00032C*
+ ID_OUI_FROM_DATABASE=ABB Switzerland Ltd
+
+OUI:00032D*
+ ID_OUI_FROM_DATABASE=IBASE Technology, Inc.
+
+OUI:00032E*
+ ID_OUI_FROM_DATABASE=Scope Information Management, Ltd.
+
+OUI:00032F*
+ ID_OUI_FROM_DATABASE=Global Sun Technology, Inc.
+
+OUI:000330*
+ ID_OUI_FROM_DATABASE=Imagenics, Co., Ltd.
+
+OUI:000331*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000332*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000333*
+ ID_OUI_FROM_DATABASE=Digitel Co., Ltd.
+
+OUI:000334*
+ ID_OUI_FROM_DATABASE=Newport Electronics
+
+OUI:000335*
+ ID_OUI_FROM_DATABASE=Mirae Technology
+
+OUI:000336*
+ ID_OUI_FROM_DATABASE=Zetes Technologies
+
+OUI:000337*
+ ID_OUI_FROM_DATABASE=Vaone, Inc.
+
+OUI:000338*
+ ID_OUI_FROM_DATABASE=Oak Technology
+
+OUI:000339*
+ ID_OUI_FROM_DATABASE=Eurologic Systems, Ltd.
+
+OUI:00033A*
+ ID_OUI_FROM_DATABASE=Silicon Wave, Inc.
+
+OUI:00033B*
+ ID_OUI_FROM_DATABASE=TAMI Tech Co., Ltd.
+
+OUI:00033C*
+ ID_OUI_FROM_DATABASE=Daiden Co., Ltd.
+
+OUI:00033D*
+ ID_OUI_FROM_DATABASE=ILSHin Lab
+
+OUI:00033E*
+ ID_OUI_FROM_DATABASE=Tateyama System Laboratory Co., Ltd.
+
+OUI:00033F*
+ ID_OUI_FROM_DATABASE=BigBand Networks, Ltd.
+
+OUI:000340*
+ ID_OUI_FROM_DATABASE=Floware Wireless Systems, Ltd.
+
+OUI:000341*
+ ID_OUI_FROM_DATABASE=Axon Digital Design
+
+OUI:000342*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000343*
+ ID_OUI_FROM_DATABASE=Martin Professional A/S
+
+OUI:000344*
+ ID_OUI_FROM_DATABASE=Tietech.Co., Ltd.
+
+OUI:000345*
+ ID_OUI_FROM_DATABASE=Routrek Networks Corporation
+
+OUI:000346*
+ ID_OUI_FROM_DATABASE=Hitachi Kokusai Electric, Inc.
+
+OUI:000347*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:000348*
+ ID_OUI_FROM_DATABASE=Norscan Instruments, Ltd.
+
+OUI:000349*
+ ID_OUI_FROM_DATABASE=Vidicode Datacommunicatie B.V.
+
+OUI:00034A*
+ ID_OUI_FROM_DATABASE=RIAS Corporation
+
+OUI:00034B*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:00034C*
+ ID_OUI_FROM_DATABASE=Shanghai DigiVision Technology Co., Ltd.
+
+OUI:00034D*
+ ID_OUI_FROM_DATABASE=Chiaro Networks, Ltd.
+
+OUI:00034E*
+ ID_OUI_FROM_DATABASE=Pos Data Company, Ltd.
+
+OUI:00034F*
+ ID_OUI_FROM_DATABASE=Sur-Gard Security
+
+OUI:000350*
+ ID_OUI_FROM_DATABASE=BTICINO SPA
+
+OUI:000351*
+ ID_OUI_FROM_DATABASE=Diebold, Inc.
+
+OUI:000352*
+ ID_OUI_FROM_DATABASE=Colubris Networks
+
+OUI:000353*
+ ID_OUI_FROM_DATABASE=Mitac, Inc.
+
+OUI:000354*
+ ID_OUI_FROM_DATABASE=Fiber Logic Communications
+
+OUI:000355*
+ ID_OUI_FROM_DATABASE=TeraBeam Internet Systems
+
+OUI:000356*
+ ID_OUI_FROM_DATABASE=Wincor Nixdorf International GmbH
+
+OUI:000357*
+ ID_OUI_FROM_DATABASE=Intervoice-Brite, Inc.
+
+OUI:000358*
+ ID_OUI_FROM_DATABASE=Hanyang Digitech Co., Ltd.
+
+OUI:000359*
+ ID_OUI_FROM_DATABASE=DigitalSis
+
+OUI:00035A*
+ ID_OUI_FROM_DATABASE=Photron Limited
+
+OUI:00035B*
+ ID_OUI_FROM_DATABASE=BridgeWave Communications
+
+OUI:00035C*
+ ID_OUI_FROM_DATABASE=Saint Song Corp.
+
+OUI:00035D*
+ ID_OUI_FROM_DATABASE=Bosung Hi-Net Co., Ltd.
+
+OUI:00035E*
+ ID_OUI_FROM_DATABASE=Metropolitan Area Networks, Inc.
+
+OUI:00035F*
+ ID_OUI_FROM_DATABASE=Prüftechnik Condition Monitoring GmbH & Co. KG
+
+OUI:000360*
+ ID_OUI_FROM_DATABASE=PAC Interactive Technology, Inc.
+
+OUI:000361*
+ ID_OUI_FROM_DATABASE=Widcomm, Inc.
+
+OUI:000362*
+ ID_OUI_FROM_DATABASE=Vodtel Communications, Inc.
+
+OUI:000363*
+ ID_OUI_FROM_DATABASE=Miraesys Co., Ltd.
+
+OUI:000364*
+ ID_OUI_FROM_DATABASE=Scenix Semiconductor, Inc.
+
+OUI:000365*
+ ID_OUI_FROM_DATABASE=Kira Information & Communications, Ltd.
+
+OUI:000366*
+ ID_OUI_FROM_DATABASE=ASM Pacific Technology
+
+OUI:000367*
+ ID_OUI_FROM_DATABASE=Jasmine Networks, Inc.
+
+OUI:000368*
+ ID_OUI_FROM_DATABASE=Embedone Co., Ltd.
+
+OUI:000369*
+ ID_OUI_FROM_DATABASE=Nippon Antenna Co., Ltd.
+
+OUI:00036A*
+ ID_OUI_FROM_DATABASE=Mainnet, Ltd.
+
+OUI:00036B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00036C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00036D*
+ ID_OUI_FROM_DATABASE=Runtop, Inc.
+
+OUI:00036E*
+ ID_OUI_FROM_DATABASE=Nicon Systems (Pty) Limited
+
+OUI:00036F*
+ ID_OUI_FROM_DATABASE=Telsey SPA
+
+OUI:000370*
+ ID_OUI_FROM_DATABASE=NXTV, Inc.
+
+OUI:000371*
+ ID_OUI_FROM_DATABASE=Acomz Networks Corp.
+
+OUI:000372*
+ ID_OUI_FROM_DATABASE=ULAN
+
+OUI:000373*
+ ID_OUI_FROM_DATABASE=Aselsan A.S
+
+OUI:000374*
+ ID_OUI_FROM_DATABASE=Control Microsystems
+
+OUI:000375*
+ ID_OUI_FROM_DATABASE=NetMedia, Inc.
+
+OUI:000376*
+ ID_OUI_FROM_DATABASE=Graphtec Technology, Inc.
+
+OUI:000377*
+ ID_OUI_FROM_DATABASE=Gigabit Wireless
+
+OUI:000378*
+ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
+
+OUI:000379*
+ ID_OUI_FROM_DATABASE=Proscend Communications, Inc.
+
+OUI:00037A*
+ ID_OUI_FROM_DATABASE=Taiyo Yuden Co., Ltd.
+
+OUI:00037B*
+ ID_OUI_FROM_DATABASE=IDEC IZUMI Corporation
+
+OUI:00037C*
+ ID_OUI_FROM_DATABASE=Coax Media
+
+OUI:00037D*
+ ID_OUI_FROM_DATABASE=Stellcom
+
+OUI:00037E*
+ ID_OUI_FROM_DATABASE=PORTech Communications, Inc.
+
+OUI:00037F*
+ ID_OUI_FROM_DATABASE=Atheros Communications, Inc.
+
+OUI:000380*
+ ID_OUI_FROM_DATABASE=SSH Communications Security Corp.
+
+OUI:000381*
+ ID_OUI_FROM_DATABASE=Ingenico International
+
+OUI:000382*
+ ID_OUI_FROM_DATABASE=A-One Co., Ltd.
+
+OUI:000383*
+ ID_OUI_FROM_DATABASE=Metera Networks, Inc.
+
+OUI:000384*
+ ID_OUI_FROM_DATABASE=AETA
+
+OUI:000385*
+ ID_OUI_FROM_DATABASE=Actelis Networks, Inc.
+
+OUI:000386*
+ ID_OUI_FROM_DATABASE=Ho Net, Inc.
+
+OUI:000387*
+ ID_OUI_FROM_DATABASE=Blaze Network Products
+
+OUI:000388*
+ ID_OUI_FROM_DATABASE=Fastfame Technology Co., Ltd.
+
+OUI:000389*
+ ID_OUI_FROM_DATABASE=Plantronics
+
+OUI:00038A*
+ ID_OUI_FROM_DATABASE=America Online, Inc.
+
+OUI:00038B*
+ ID_OUI_FROM_DATABASE=PLUS-ONE I&T, Inc.
+
+OUI:00038C*
+ ID_OUI_FROM_DATABASE=Total Impact
+
+OUI:00038D*
+ ID_OUI_FROM_DATABASE=PCS Revenue Control Systems, Inc.
+
+OUI:00038E*
+ ID_OUI_FROM_DATABASE=Atoga Systems, Inc.
+
+OUI:00038F*
+ ID_OUI_FROM_DATABASE=Weinschel Corporation
+
+OUI:000390*
+ ID_OUI_FROM_DATABASE=Digital Video Communications, Inc.
+
+OUI:000391*
+ ID_OUI_FROM_DATABASE=Advanced Digital Broadcast, Ltd.
+
+OUI:000392*
+ ID_OUI_FROM_DATABASE=Hyundai Teletek Co., Ltd.
+
+OUI:000393*
+ ID_OUI_FROM_DATABASE=Apple Computer, Inc.
+
+OUI:000394*
+ ID_OUI_FROM_DATABASE=Connect One
+
+OUI:000395*
+ ID_OUI_FROM_DATABASE=California Amplifier
+
+OUI:000396*
+ ID_OUI_FROM_DATABASE=EZ Cast Co., Ltd.
+
+OUI:000397*
+ ID_OUI_FROM_DATABASE=Watchfront Limited
+
+OUI:000398*
+ ID_OUI_FROM_DATABASE=WISI
+
+OUI:000399*
+ ID_OUI_FROM_DATABASE=Dongju Informations & Communications Co., Ltd.
+
+OUI:00039A*
+ ID_OUI_FROM_DATABASE=SiConnect
+
+OUI:00039B*
+ ID_OUI_FROM_DATABASE=NetChip Technology, Inc.
+
+OUI:00039C*
+ ID_OUI_FROM_DATABASE=OptiMight Communications, Inc.
+
+OUI:00039D*
+ ID_OUI_FROM_DATABASE=Qisda Corporation
+
+OUI:00039E*
+ ID_OUI_FROM_DATABASE=Tera System Co., Ltd.
+
+OUI:00039F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0003A0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0003A1*
+ ID_OUI_FROM_DATABASE=HIPER Information & Communication, Inc.
+
+OUI:0003A2*
+ ID_OUI_FROM_DATABASE=Catapult Communications
+
+OUI:0003A3*
+ ID_OUI_FROM_DATABASE=MAVIX, Ltd.
+
+OUI:0003A4*
+ ID_OUI_FROM_DATABASE=Imation Corp.
+
+OUI:0003A5*
+ ID_OUI_FROM_DATABASE=Medea Corporation
+
+OUI:0003A6*
+ ID_OUI_FROM_DATABASE=Traxit Technology, Inc.
+
+OUI:0003A7*
+ ID_OUI_FROM_DATABASE=Unixtar Technology, Inc.
+
+OUI:0003A8*
+ ID_OUI_FROM_DATABASE=IDOT Computers, Inc.
+
+OUI:0003A9*
+ ID_OUI_FROM_DATABASE=AXCENT Media AG
+
+OUI:0003AA*
+ ID_OUI_FROM_DATABASE=Watlow
+
+OUI:0003AB*
+ ID_OUI_FROM_DATABASE=Bridge Information Systems
+
+OUI:0003AC*
+ ID_OUI_FROM_DATABASE=Fronius Schweissmaschinen
+
+OUI:0003AD*
+ ID_OUI_FROM_DATABASE=Emerson Energy Systems AB
+
+OUI:0003AE*
+ ID_OUI_FROM_DATABASE=Allied Advanced Manufacturing Pte, Ltd.
+
+OUI:0003AF*
+ ID_OUI_FROM_DATABASE=Paragea Communications
+
+OUI:0003B0*
+ ID_OUI_FROM_DATABASE=Xsense Technology Corp.
+
+OUI:0003B1*
+ ID_OUI_FROM_DATABASE=Hospira Inc.
+
+OUI:0003B2*
+ ID_OUI_FROM_DATABASE=Radware
+
+OUI:0003B3*
+ ID_OUI_FROM_DATABASE=IA Link Systems Co., Ltd.
+
+OUI:0003B4*
+ ID_OUI_FROM_DATABASE=Macrotek International Corp.
+
+OUI:0003B5*
+ ID_OUI_FROM_DATABASE=Entra Technology Co.
+
+OUI:0003B6*
+ ID_OUI_FROM_DATABASE=QSI Corporation
+
+OUI:0003B7*
+ ID_OUI_FROM_DATABASE=ZACCESS Systems
+
+OUI:0003B8*
+ ID_OUI_FROM_DATABASE=NetKit Solutions, LLC
+
+OUI:0003B9*
+ ID_OUI_FROM_DATABASE=Hualong Telecom Co., Ltd.
+
+OUI:0003BA*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:0003BB*
+ ID_OUI_FROM_DATABASE=Signal Communications Limited
+
+OUI:0003BC*
+ ID_OUI_FROM_DATABASE=COT GmbH
+
+OUI:0003BD*
+ ID_OUI_FROM_DATABASE=OmniCluster Technologies, Inc.
+
+OUI:0003BE*
+ ID_OUI_FROM_DATABASE=Netility
+
+OUI:0003BF*
+ ID_OUI_FROM_DATABASE=Centerpoint Broadband Technologies, Inc.
+
+OUI:0003C0*
+ ID_OUI_FROM_DATABASE=RFTNC Co., Ltd.
+
+OUI:0003C1*
+ ID_OUI_FROM_DATABASE=Packet Dynamics Ltd
+
+OUI:0003C2*
+ ID_OUI_FROM_DATABASE=Solphone K.K.
+
+OUI:0003C3*
+ ID_OUI_FROM_DATABASE=Micronik Multimedia
+
+OUI:0003C4*
+ ID_OUI_FROM_DATABASE=Tomra Systems ASA
+
+OUI:0003C5*
+ ID_OUI_FROM_DATABASE=Mobotix AG
+
+OUI:0003C6*
+ ID_OUI_FROM_DATABASE=ICUE Systems, Inc.
+
+OUI:0003C7*
+ ID_OUI_FROM_DATABASE=hopf Elektronik GmbH
+
+OUI:0003C8*
+ ID_OUI_FROM_DATABASE=CML Emergency Services
+
+OUI:0003C9*
+ ID_OUI_FROM_DATABASE=TECOM Co., Ltd.
+
+OUI:0003CA*
+ ID_OUI_FROM_DATABASE=MTS Systems Corp.
+
+OUI:0003CB*
+ ID_OUI_FROM_DATABASE=Nippon Systems Development Co., Ltd.
+
+OUI:0003CC*
+ ID_OUI_FROM_DATABASE=Momentum Computer, Inc.
+
+OUI:0003CD*
+ ID_OUI_FROM_DATABASE=Clovertech, Inc.
+
+OUI:0003CE*
+ ID_OUI_FROM_DATABASE=ETEN Technologies, Inc.
+
+OUI:0003CF*
+ ID_OUI_FROM_DATABASE=Muxcom, Inc.
+
+OUI:0003D0*
+ ID_OUI_FROM_DATABASE=KOANKEISO Co., Ltd.
+
+OUI:0003D1*
+ ID_OUI_FROM_DATABASE=Takaya Corporation
+
+OUI:0003D2*
+ ID_OUI_FROM_DATABASE=Crossbeam Systems, Inc.
+
+OUI:0003D3*
+ ID_OUI_FROM_DATABASE=Internet Energy Systems, Inc.
+
+OUI:0003D4*
+ ID_OUI_FROM_DATABASE=Alloptic, Inc.
+
+OUI:0003D5*
+ ID_OUI_FROM_DATABASE=Advanced Communications Co., Ltd.
+
+OUI:0003D6*
+ ID_OUI_FROM_DATABASE=RADVision, Ltd.
+
+OUI:0003D7*
+ ID_OUI_FROM_DATABASE=NextNet Wireless, Inc.
+
+OUI:0003D8*
+ ID_OUI_FROM_DATABASE=iMPath Networks, Inc.
+
+OUI:0003D9*
+ ID_OUI_FROM_DATABASE=Secheron SA
+
+OUI:0003DA*
+ ID_OUI_FROM_DATABASE=Takamisawa Cybernetics Co., Ltd.
+
+OUI:0003DB*
+ ID_OUI_FROM_DATABASE=Apogee Electronics Corp.
+
+OUI:0003DC*
+ ID_OUI_FROM_DATABASE=Lexar Media, Inc.
+
+OUI:0003DD*
+ ID_OUI_FROM_DATABASE=Comark Corp.
+
+OUI:0003DE*
+ ID_OUI_FROM_DATABASE=OTC Wireless
+
+OUI:0003DF*
+ ID_OUI_FROM_DATABASE=Desana Systems
+
+OUI:0003E0*
+ ID_OUI_FROM_DATABASE=Motorola, Inc.
+
+OUI:0003E1*
+ ID_OUI_FROM_DATABASE=Winmate Communication, Inc.
+
+OUI:0003E2*
+ ID_OUI_FROM_DATABASE=Comspace Corporation
+
+OUI:0003E3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0003E4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0003E5*
+ ID_OUI_FROM_DATABASE=Hermstedt SG
+
+OUI:0003E6*
+ ID_OUI_FROM_DATABASE=Entone, Inc.
+
+OUI:0003E7*
+ ID_OUI_FROM_DATABASE=Logostek Co. Ltd.
+
+OUI:0003E8*
+ ID_OUI_FROM_DATABASE=Wavelength Digital Limited
+
+OUI:0003E9*
+ ID_OUI_FROM_DATABASE=Akara Canada, Inc.
+
+OUI:0003EA*
+ ID_OUI_FROM_DATABASE=Mega System Technologies, Inc.
+
+OUI:0003EB*
+ ID_OUI_FROM_DATABASE=Atrica
+
+OUI:0003EC*
+ ID_OUI_FROM_DATABASE=ICG Research, Inc.
+
+OUI:0003ED*
+ ID_OUI_FROM_DATABASE=Shinkawa Electric Co., Ltd.
+
+OUI:0003EE*
+ ID_OUI_FROM_DATABASE=MKNet Corporation
+
+OUI:0003EF*
+ ID_OUI_FROM_DATABASE=Oneline AG
+
+OUI:0003F0*
+ ID_OUI_FROM_DATABASE=Redfern Broadband Networks
+
+OUI:0003F1*
+ ID_OUI_FROM_DATABASE=Cicada Semiconductor, Inc.
+
+OUI:0003F2*
+ ID_OUI_FROM_DATABASE=Seneca Networks
+
+OUI:0003F3*
+ ID_OUI_FROM_DATABASE=Dazzle Multimedia, Inc.
+
+OUI:0003F4*
+ ID_OUI_FROM_DATABASE=NetBurner
+
+OUI:0003F5*
+ ID_OUI_FROM_DATABASE=Chip2Chip
+
+OUI:0003F6*
+ ID_OUI_FROM_DATABASE=Allegro Networks, Inc.
+
+OUI:0003F7*
+ ID_OUI_FROM_DATABASE=Plast-Control GmbH
+
+OUI:0003F8*
+ ID_OUI_FROM_DATABASE=SanCastle Technologies, Inc.
+
+OUI:0003F9*
+ ID_OUI_FROM_DATABASE=Pleiades Communications, Inc.
+
+OUI:0003FA*
+ ID_OUI_FROM_DATABASE=TiMetra Networks
+
+OUI:0003FB*
+ ID_OUI_FROM_DATABASE=ENEGATE Co.,Ltd.
+
+OUI:0003FC*
+ ID_OUI_FROM_DATABASE=Intertex Data AB
+
+OUI:0003FD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0003FE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0003FF*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:000400*
+ ID_OUI_FROM_DATABASE=LEXMARK INTERNATIONAL, INC.
+
+OUI:000401*
+ ID_OUI_FROM_DATABASE=Osaki Electric Co., Ltd.
+
+OUI:000402*
+ ID_OUI_FROM_DATABASE=Nexsan Technologies, Ltd.
+
+OUI:000403*
+ ID_OUI_FROM_DATABASE=Nexsi Corporation
+
+OUI:000404*
+ ID_OUI_FROM_DATABASE=Makino Milling Machine Co., Ltd.
+
+OUI:000405*
+ ID_OUI_FROM_DATABASE=ACN Technologies
+
+OUI:000406*
+ ID_OUI_FROM_DATABASE=Fa. Metabox AG
+
+OUI:000407*
+ ID_OUI_FROM_DATABASE=Topcon Positioning Systems, Inc.
+
+OUI:000408*
+ ID_OUI_FROM_DATABASE=Sanko Electronics Co., Ltd.
+
+OUI:000409*
+ ID_OUI_FROM_DATABASE=Cratos Networks
+
+OUI:00040A*
+ ID_OUI_FROM_DATABASE=Sage Systems
+
+OUI:00040B*
+ ID_OUI_FROM_DATABASE=3com Europe Ltd.
+
+OUI:00040C*
+ ID_OUI_FROM_DATABASE=KANNO Work's Ltd.
+
+OUI:00040D*
+ ID_OUI_FROM_DATABASE=Avaya, Inc.
+
+OUI:00040E*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:00040F*
+ ID_OUI_FROM_DATABASE=Asus Network Technologies, Inc.
+
+OUI:000410*
+ ID_OUI_FROM_DATABASE=Spinnaker Networks, Inc.
+
+OUI:000411*
+ ID_OUI_FROM_DATABASE=Inkra Networks, Inc.
+
+OUI:000412*
+ ID_OUI_FROM_DATABASE=WaveSmith Networks, Inc.
+
+OUI:000413*
+ ID_OUI_FROM_DATABASE=SNOM Technology AG
+
+OUI:000414*
+ ID_OUI_FROM_DATABASE=Umezawa Musen Denki Co., Ltd.
+
+OUI:000415*
+ ID_OUI_FROM_DATABASE=Rasteme Systems Co., Ltd.
+
+OUI:000416*
+ ID_OUI_FROM_DATABASE=Parks S/A Comunicacoes Digitais
+
+OUI:000417*
+ ID_OUI_FROM_DATABASE=ELAU AG
+
+OUI:000418*
+ ID_OUI_FROM_DATABASE=Teltronic S.A.U.
+
+OUI:000419*
+ ID_OUI_FROM_DATABASE=Fibercycle Networks, Inc.
+
+OUI:00041A*
+ ID_OUI_FROM_DATABASE=Ines Test and Measurement GmbH & CoKG
+
+OUI:00041B*
+ ID_OUI_FROM_DATABASE=Bridgeworks Ltd.
+
+OUI:00041C*
+ ID_OUI_FROM_DATABASE=ipDialog, Inc.
+
+OUI:00041D*
+ ID_OUI_FROM_DATABASE=Corega of America
+
+OUI:00041E*
+ ID_OUI_FROM_DATABASE=Shikoku Instrumentation Co., Ltd.
+
+OUI:00041F*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment, Inc.
+
+OUI:000420*
+ ID_OUI_FROM_DATABASE=Slim Devices, Inc.
+
+OUI:000421*
+ ID_OUI_FROM_DATABASE=Ocular Networks
+
+OUI:000422*
+ ID_OUI_FROM_DATABASE=Gordon Kapes, Inc.
+
+OUI:000423*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:000424*
+ ID_OUI_FROM_DATABASE=TMC s.r.l.
+
+OUI:000425*
+ ID_OUI_FROM_DATABASE=Atmel Corporation
+
+OUI:000426*
+ ID_OUI_FROM_DATABASE=Autosys
+
+OUI:000427*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000428*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000429*
+ ID_OUI_FROM_DATABASE=Pixord Corporation
+
+OUI:00042A*
+ ID_OUI_FROM_DATABASE=Wireless Networks, Inc.
+
+OUI:00042B*
+ ID_OUI_FROM_DATABASE=IT Access Co., Ltd.
+
+OUI:00042C*
+ ID_OUI_FROM_DATABASE=Minet, Inc.
+
+OUI:00042D*
+ ID_OUI_FROM_DATABASE=Sarian Systems, Ltd.
+
+OUI:00042E*
+ ID_OUI_FROM_DATABASE=Netous Technologies, Ltd.
+
+OUI:00042F*
+ ID_OUI_FROM_DATABASE=International Communications Products, Inc.
+
+OUI:000430*
+ ID_OUI_FROM_DATABASE=Netgem
+
+OUI:000431*
+ ID_OUI_FROM_DATABASE=GlobalStreams, Inc.
+
+OUI:000432*
+ ID_OUI_FROM_DATABASE=Voyetra Turtle Beach, Inc.
+
+OUI:000433*
+ ID_OUI_FROM_DATABASE=Cyberboard A/S
+
+OUI:000434*
+ ID_OUI_FROM_DATABASE=Accelent Systems, Inc.
+
+OUI:000435*
+ ID_OUI_FROM_DATABASE=Comptek International, Inc.
+
+OUI:000436*
+ ID_OUI_FROM_DATABASE=ELANsat Technologies, Inc.
+
+OUI:000437*
+ ID_OUI_FROM_DATABASE=Powin Information Technology, Inc.
+
+OUI:000438*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000439*
+ ID_OUI_FROM_DATABASE=Rosco Entertainment Technology, Inc.
+
+OUI:00043A*
+ ID_OUI_FROM_DATABASE=Intelligent Telecommunications, Inc.
+
+OUI:00043B*
+ ID_OUI_FROM_DATABASE=Lava Computer Mfg., Inc.
+
+OUI:00043C*
+ ID_OUI_FROM_DATABASE=SONOS Co., Ltd.
+
+OUI:00043D*
+ ID_OUI_FROM_DATABASE=INDEL AG
+
+OUI:00043E*
+ ID_OUI_FROM_DATABASE=Telencomm
+
+OUI:00043F*
+ ID_OUI_FROM_DATABASE=ESTeem Wireless Modems, Inc
+
+OUI:000440*
+ ID_OUI_FROM_DATABASE=cyberPIXIE, Inc.
+
+OUI:000441*
+ ID_OUI_FROM_DATABASE=Half Dome Systems, Inc.
+
+OUI:000442*
+ ID_OUI_FROM_DATABASE=NACT
+
+OUI:000443*
+ ID_OUI_FROM_DATABASE=Agilent Technologies, Inc.
+
+OUI:000444*
+ ID_OUI_FROM_DATABASE=Western Multiplex Corporation
+
+OUI:000445*
+ ID_OUI_FROM_DATABASE=LMS Skalar Instruments GmbH
+
+OUI:000446*
+ ID_OUI_FROM_DATABASE=CYZENTECH Co., Ltd.
+
+OUI:000447*
+ ID_OUI_FROM_DATABASE=Acrowave Systems Co., Ltd.
+
+OUI:000448*
+ ID_OUI_FROM_DATABASE=Polaroid Corporation
+
+OUI:000449*
+ ID_OUI_FROM_DATABASE=Mapletree Networks
+
+OUI:00044A*
+ ID_OUI_FROM_DATABASE=iPolicy Networks, Inc.
+
+OUI:00044B*
+ ID_OUI_FROM_DATABASE=NVIDIA
+
+OUI:00044C*
+ ID_OUI_FROM_DATABASE=JENOPTIK
+
+OUI:00044D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00044E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00044F*
+ ID_OUI_FROM_DATABASE=Leukhardt Systemelektronik GmbH
+
+OUI:000450*
+ ID_OUI_FROM_DATABASE=DMD Computers SRL
+
+OUI:000451*
+ ID_OUI_FROM_DATABASE=Medrad, Inc.
+
+OUI:000452*
+ ID_OUI_FROM_DATABASE=RocketLogix, Inc.
+
+OUI:000453*
+ ID_OUI_FROM_DATABASE=YottaYotta, Inc.
+
+OUI:000454*
+ ID_OUI_FROM_DATABASE=Quadriga UK
+
+OUI:000455*
+ ID_OUI_FROM_DATABASE=ANTARA.net
+
+OUI:000456*
+ ID_OUI_FROM_DATABASE=Cambium Networks Limited
+
+OUI:000457*
+ ID_OUI_FROM_DATABASE=Universal Access Technology, Inc.
+
+OUI:000458*
+ ID_OUI_FROM_DATABASE=Fusion X Co., Ltd.
+
+OUI:000459*
+ ID_OUI_FROM_DATABASE=Veristar Corporation
+
+OUI:00045A*
+ ID_OUI_FROM_DATABASE=The Linksys Group, Inc.
+
+OUI:00045B*
+ ID_OUI_FROM_DATABASE=Techsan Electronics Co., Ltd.
+
+OUI:00045C*
+ ID_OUI_FROM_DATABASE=Mobiwave Pte Ltd
+
+OUI:00045D*
+ ID_OUI_FROM_DATABASE=BEKA Elektronik
+
+OUI:00045E*
+ ID_OUI_FROM_DATABASE=PolyTrax Information Technology AG
+
+OUI:00045F*
+ ID_OUI_FROM_DATABASE=Evalue Technology, Inc.
+
+OUI:000460*
+ ID_OUI_FROM_DATABASE=Knilink Technology, Inc.
+
+OUI:000461*
+ ID_OUI_FROM_DATABASE=EPOX Computer Co., Ltd.
+
+OUI:000462*
+ ID_OUI_FROM_DATABASE=DAKOS Data & Communication Co., Ltd.
+
+OUI:000463*
+ ID_OUI_FROM_DATABASE=Bosch Security Systems
+
+OUI:000464*
+ ID_OUI_FROM_DATABASE=Fantasma Networks, Inc.
+
+OUI:000465*
+ ID_OUI_FROM_DATABASE=i.s.t isdn-support technik GmbH
+
+OUI:000466*
+ ID_OUI_FROM_DATABASE=ARMITEL Co.
+
+OUI:000467*
+ ID_OUI_FROM_DATABASE=Wuhan Research Institute of MII
+
+OUI:000468*
+ ID_OUI_FROM_DATABASE=Vivity, Inc.
+
+OUI:000469*
+ ID_OUI_FROM_DATABASE=Innocom, Inc.
+
+OUI:00046A*
+ ID_OUI_FROM_DATABASE=Navini Networks
+
+OUI:00046B*
+ ID_OUI_FROM_DATABASE=Palm Wireless, Inc.
+
+OUI:00046C*
+ ID_OUI_FROM_DATABASE=Cyber Technology Co., Ltd.
+
+OUI:00046D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00046E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00046F*
+ ID_OUI_FROM_DATABASE=Digitel S/A Industria Eletronica
+
+OUI:000470*
+ ID_OUI_FROM_DATABASE=ipUnplugged AB
+
+OUI:000471*
+ ID_OUI_FROM_DATABASE=IPrad
+
+OUI:000472*
+ ID_OUI_FROM_DATABASE=Telelynx, Inc.
+
+OUI:000473*
+ ID_OUI_FROM_DATABASE=Photonex Corporation
+
+OUI:000474*
+ ID_OUI_FROM_DATABASE=LEGRAND
+
+OUI:000475*
+ ID_OUI_FROM_DATABASE=3 Com Corporation
+
+OUI:000476*
+ ID_OUI_FROM_DATABASE=3 Com Corporation
+
+OUI:000477*
+ ID_OUI_FROM_DATABASE=Scalant Systems, Inc.
+
+OUI:000478*
+ ID_OUI_FROM_DATABASE=G. Star Technology Corporation
+
+OUI:000479*
+ ID_OUI_FROM_DATABASE=Radius Co., Ltd.
+
+OUI:00047A*
+ ID_OUI_FROM_DATABASE=AXXESSIT ASA
+
+OUI:00047B*
+ ID_OUI_FROM_DATABASE=Schlumberger
+
+OUI:00047C*
+ ID_OUI_FROM_DATABASE=Skidata AG
+
+OUI:00047D*
+ ID_OUI_FROM_DATABASE=Pelco
+
+OUI:00047E*
+ ID_OUI_FROM_DATABASE=Siqura B.V.
+
+OUI:00047F*
+ ID_OUI_FROM_DATABASE=Chr. Mayr GmbH & Co. KG
+
+OUI:000480*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc
+
+OUI:000481*
+ ID_OUI_FROM_DATABASE=Econolite Control Products, Inc.
+
+OUI:000482*
+ ID_OUI_FROM_DATABASE=Medialogic Corp.
+
+OUI:000483*
+ ID_OUI_FROM_DATABASE=Deltron Technology, Inc.
+
+OUI:000484*
+ ID_OUI_FROM_DATABASE=Amann GmbH
+
+OUI:000485*
+ ID_OUI_FROM_DATABASE=PicoLight
+
+OUI:000486*
+ ID_OUI_FROM_DATABASE=ITTC, University of Kansas
+
+OUI:000487*
+ ID_OUI_FROM_DATABASE=Cogency Semiconductor, Inc.
+
+OUI:000488*
+ ID_OUI_FROM_DATABASE=Eurotherm Controls
+
+OUI:000489*
+ ID_OUI_FROM_DATABASE=YAFO Networks, Inc.
+
+OUI:00048A*
+ ID_OUI_FROM_DATABASE=Temia Vertriebs GmbH
+
+OUI:00048B*
+ ID_OUI_FROM_DATABASE=Poscon Corporation
+
+OUI:00048C*
+ ID_OUI_FROM_DATABASE=Nayna Networks, Inc.
+
+OUI:00048D*
+ ID_OUI_FROM_DATABASE=Tone Commander Systems, Inc.
+
+OUI:00048E*
+ ID_OUI_FROM_DATABASE=Ohm Tech Labs, Inc.
+
+OUI:00048F*
+ ID_OUI_FROM_DATABASE=TD Systems Corporation
+
+OUI:000490*
+ ID_OUI_FROM_DATABASE=Optical Access
+
+OUI:000491*
+ ID_OUI_FROM_DATABASE=Technovision, Inc.
+
+OUI:000492*
+ ID_OUI_FROM_DATABASE=Hive Internet, Ltd.
+
+OUI:000493*
+ ID_OUI_FROM_DATABASE=Tsinghua Unisplendour Co., Ltd.
+
+OUI:000494*
+ ID_OUI_FROM_DATABASE=Breezecom, Ltd.
+
+OUI:000495*
+ ID_OUI_FROM_DATABASE=Tejas Networks India Limited
+
+OUI:000496*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:000497*
+ ID_OUI_FROM_DATABASE=MacroSystem Digital Video AG
+
+OUI:000498*
+ ID_OUI_FROM_DATABASE=Mahi Networks
+
+OUI:000499*
+ ID_OUI_FROM_DATABASE=Chino Corporation
+
+OUI:00049A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00049B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00049C*
+ ID_OUI_FROM_DATABASE=Surgient Networks, Inc.
+
+OUI:00049D*
+ ID_OUI_FROM_DATABASE=Ipanema Technologies
+
+OUI:00049E*
+ ID_OUI_FROM_DATABASE=Wirelink Co., Ltd.
+
+OUI:00049F*
+ ID_OUI_FROM_DATABASE=Freescale Semiconductor
+
+OUI:0004A0*
+ ID_OUI_FROM_DATABASE=Verity Instruments, Inc.
+
+OUI:0004A1*
+ ID_OUI_FROM_DATABASE=Pathway Connectivity
+
+OUI:0004A2*
+ ID_OUI_FROM_DATABASE=L.S.I. Japan Co., Ltd.
+
+OUI:0004A3*
+ ID_OUI_FROM_DATABASE=Microchip Technology, Inc.
+
+OUI:0004A4*
+ ID_OUI_FROM_DATABASE=NetEnabled, Inc.
+
+OUI:0004A5*
+ ID_OUI_FROM_DATABASE=Barco Projection Systems NV
+
+OUI:0004A6*
+ ID_OUI_FROM_DATABASE=SAF Tehnika Ltd.
+
+OUI:0004A7*
+ ID_OUI_FROM_DATABASE=FabiaTech Corporation
+
+OUI:0004A8*
+ ID_OUI_FROM_DATABASE=Broadmax Technologies, Inc.
+
+OUI:0004A9*
+ ID_OUI_FROM_DATABASE=SandStream Technologies, Inc.
+
+OUI:0004AA*
+ ID_OUI_FROM_DATABASE=Jetstream Communications
+
+OUI:0004AB*
+ ID_OUI_FROM_DATABASE=Comverse Network Systems, Inc.
+
+OUI:0004AC*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:0004AD*
+ ID_OUI_FROM_DATABASE=Malibu Networks
+
+OUI:0004AE*
+ ID_OUI_FROM_DATABASE=Sullair Corporation
+
+OUI:0004AF*
+ ID_OUI_FROM_DATABASE=Digital Fountain, Inc.
+
+OUI:0004B0*
+ ID_OUI_FROM_DATABASE=ELESIGN Co., Ltd.
+
+OUI:0004B1*
+ ID_OUI_FROM_DATABASE=Signal Technology, Inc.
+
+OUI:0004B2*
+ ID_OUI_FROM_DATABASE=ESSEGI SRL
+
+OUI:0004B3*
+ ID_OUI_FROM_DATABASE=Videotek, Inc.
+
+OUI:0004B4*
+ ID_OUI_FROM_DATABASE=CIAC
+
+OUI:0004B5*
+ ID_OUI_FROM_DATABASE=Equitrac Corporation
+
+OUI:0004B6*
+ ID_OUI_FROM_DATABASE=Stratex Networks, Inc.
+
+OUI:0004B7*
+ ID_OUI_FROM_DATABASE=AMB i.t. Holding
+
+OUI:0004B8*
+ ID_OUI_FROM_DATABASE=Kumahira Co., Ltd.
+
+OUI:0004B9*
+ ID_OUI_FROM_DATABASE=S.I. Soubou, Inc.
+
+OUI:0004BA*
+ ID_OUI_FROM_DATABASE=KDD Media Will Corporation
+
+OUI:0004BB*
+ ID_OUI_FROM_DATABASE=Bardac Corporation
+
+OUI:0004BC*
+ ID_OUI_FROM_DATABASE=Giantec, Inc.
+
+OUI:0004BD*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0004BE*
+ ID_OUI_FROM_DATABASE=OptXCon, Inc.
+
+OUI:0004BF*
+ ID_OUI_FROM_DATABASE=VersaLogic Corp.
+
+OUI:0004C0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0004C1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0004C2*
+ ID_OUI_FROM_DATABASE=Magnipix, Inc.
+
+OUI:0004C3*
+ ID_OUI_FROM_DATABASE=CASTOR Informatique
+
+OUI:0004C4*
+ ID_OUI_FROM_DATABASE=Allen & Heath Limited
+
+OUI:0004C5*
+ ID_OUI_FROM_DATABASE=ASE Technologies, USA
+
+OUI:0004C6*
+ ID_OUI_FROM_DATABASE=Yamaha Motor Co., Ltd.
+
+OUI:0004C7*
+ ID_OUI_FROM_DATABASE=NetMount
+
+OUI:0004C8*
+ ID_OUI_FROM_DATABASE=LIBA Maschinenfabrik GmbH
+
+OUI:0004C9*
+ ID_OUI_FROM_DATABASE=Micro Electron Co., Ltd.
+
+OUI:0004CA*
+ ID_OUI_FROM_DATABASE=FreeMs Corp.
+
+OUI:0004CB*
+ ID_OUI_FROM_DATABASE=Tdsoft Communication, Ltd.
+
+OUI:0004CC*
+ ID_OUI_FROM_DATABASE=Peek Traffic B.V.
+
+OUI:0004CD*
+ ID_OUI_FROM_DATABASE=Informedia Research Group
+
+OUI:0004CE*
+ ID_OUI_FROM_DATABASE=Patria Ailon
+
+OUI:0004CF*
+ ID_OUI_FROM_DATABASE=Seagate Technology
+
+OUI:0004D0*
+ ID_OUI_FROM_DATABASE=Softlink s.r.o.
+
+OUI:0004D1*
+ ID_OUI_FROM_DATABASE=Drew Technologies, Inc.
+
+OUI:0004D2*
+ ID_OUI_FROM_DATABASE=Adcon Telemetry GmbH
+
+OUI:0004D3*
+ ID_OUI_FROM_DATABASE=Toyokeiki Co., Ltd.
+
+OUI:0004D4*
+ ID_OUI_FROM_DATABASE=Proview Electronics Co., Ltd.
+
+OUI:0004D5*
+ ID_OUI_FROM_DATABASE=Hitachi Information & Communication Engineering, Ltd.
+
+OUI:0004D6*
+ ID_OUI_FROM_DATABASE=Takagi Industrial Co., Ltd.
+
+OUI:0004D7*
+ ID_OUI_FROM_DATABASE=Omitec Instrumentation Ltd.
+
+OUI:0004D8*
+ ID_OUI_FROM_DATABASE=IPWireless, Inc.
+
+OUI:0004D9*
+ ID_OUI_FROM_DATABASE=Titan Electronics, Inc.
+
+OUI:0004DA*
+ ID_OUI_FROM_DATABASE=Relax Technology, Inc.
+
+OUI:0004DB*
+ ID_OUI_FROM_DATABASE=Tellus Group Corp.
+
+OUI:0004DC*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0004DD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0004DE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0004DF*
+ ID_OUI_FROM_DATABASE=Teracom Telematica Ltda.
+
+OUI:0004E0*
+ ID_OUI_FROM_DATABASE=Procket Networks
+
+OUI:0004E1*
+ ID_OUI_FROM_DATABASE=Infinior Microsystems
+
+OUI:0004E2*
+ ID_OUI_FROM_DATABASE=SMC Networks, Inc.
+
+OUI:0004E3*
+ ID_OUI_FROM_DATABASE=Accton Technology Corp.
+
+OUI:0004E4*
+ ID_OUI_FROM_DATABASE=Daeryung Ind., Inc.
+
+OUI:0004E5*
+ ID_OUI_FROM_DATABASE=Glonet Systems, Inc.
+
+OUI:0004E6*
+ ID_OUI_FROM_DATABASE=Banyan Network Private Limited
+
+OUI:0004E7*
+ ID_OUI_FROM_DATABASE=Lightpointe Communications, Inc
+
+OUI:0004E8*
+ ID_OUI_FROM_DATABASE=IER, Inc.
+
+OUI:0004E9*
+ ID_OUI_FROM_DATABASE=Infiniswitch Corporation
+
+OUI:0004EA*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0004EB*
+ ID_OUI_FROM_DATABASE=Paxonet Communications, Inc.
+
+OUI:0004EC*
+ ID_OUI_FROM_DATABASE=Memobox SA
+
+OUI:0004ED*
+ ID_OUI_FROM_DATABASE=Billion Electric Co., Ltd.
+
+OUI:0004EE*
+ ID_OUI_FROM_DATABASE=Lincoln Electric Company
+
+OUI:0004EF*
+ ID_OUI_FROM_DATABASE=Polestar Corp.
+
+OUI:0004F0*
+ ID_OUI_FROM_DATABASE=International Computers, Ltd
+
+OUI:0004F1*
+ ID_OUI_FROM_DATABASE=WhereNet
+
+OUI:0004F2*
+ ID_OUI_FROM_DATABASE=Polycom
+
+OUI:0004F3*
+ ID_OUI_FROM_DATABASE=FS FORTH-SYSTEME GmbH
+
+OUI:0004F4*
+ ID_OUI_FROM_DATABASE=Infinite Electronics Inc.
+
+OUI:0004F5*
+ ID_OUI_FROM_DATABASE=SnowShore Networks, Inc.
+
+OUI:0004F6*
+ ID_OUI_FROM_DATABASE=Amphus
+
+OUI:0004F7*
+ ID_OUI_FROM_DATABASE=Omega Band, Inc.
+
+OUI:0004F8*
+ ID_OUI_FROM_DATABASE=QUALICABLE TV Industria E Com., Ltda
+
+OUI:0004F9*
+ ID_OUI_FROM_DATABASE=Xtera Communications, Inc.
+
+OUI:0004FA*
+ ID_OUI_FROM_DATABASE=NBS Technologies Inc.
+
+OUI:0004FB*
+ ID_OUI_FROM_DATABASE=Commtech, Inc.
+
+OUI:0004FC*
+ ID_OUI_FROM_DATABASE=Stratus Computer (DE), Inc.
+
+OUI:0004FD*
+ ID_OUI_FROM_DATABASE=Japan Control Engineering Co., Ltd.
+
+OUI:0004FE*
+ ID_OUI_FROM_DATABASE=Pelago Networks
+
+OUI:0004FF*
+ ID_OUI_FROM_DATABASE=Acronet Co., Ltd.
+
+OUI:000500*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000501*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000502*
+ ID_OUI_FROM_DATABASE=APPLE COMPUTER
+
+OUI:000503*
+ ID_OUI_FROM_DATABASE=ICONAG
+
+OUI:000504*
+ ID_OUI_FROM_DATABASE=Naray Information & Communication Enterprise
+
+OUI:000505*
+ ID_OUI_FROM_DATABASE=Systems Integration Solutions, Inc.
+
+OUI:000506*
+ ID_OUI_FROM_DATABASE=Reddo Networks AB
+
+OUI:000507*
+ ID_OUI_FROM_DATABASE=Fine Appliance Corp.
+
+OUI:000508*
+ ID_OUI_FROM_DATABASE=Inetcam, Inc.
+
+OUI:000509*
+ ID_OUI_FROM_DATABASE=AVOC Nishimura Ltd.
+
+OUI:00050A*
+ ID_OUI_FROM_DATABASE=ICS Spa
+
+OUI:00050B*
+ ID_OUI_FROM_DATABASE=SICOM Systems, Inc.
+
+OUI:00050C*
+ ID_OUI_FROM_DATABASE=Network Photonics, Inc.
+
+OUI:00050D*
+ ID_OUI_FROM_DATABASE=Midstream Technologies, Inc.
+
+OUI:00050E*
+ ID_OUI_FROM_DATABASE=3ware, Inc.
+
+OUI:00050F*
+ ID_OUI_FROM_DATABASE=Tanaka S/S Ltd.
+
+OUI:000510*
+ ID_OUI_FROM_DATABASE=Infinite Shanghai Communication Terminals Ltd.
+
+OUI:000511*
+ ID_OUI_FROM_DATABASE=Complementary Technologies Ltd
+
+OUI:000512*
+ ID_OUI_FROM_DATABASE=MeshNetworks, Inc.
+
+OUI:000513*
+ ID_OUI_FROM_DATABASE=VTLinx Multimedia Systems, Inc.
+
+OUI:000514*
+ ID_OUI_FROM_DATABASE=KDT Systems Co., Ltd.
+
+OUI:000515*
+ ID_OUI_FROM_DATABASE=Nuark Co., Ltd.
+
+OUI:000516*
+ ID_OUI_FROM_DATABASE=SMART Modular Technologies
+
+OUI:000517*
+ ID_OUI_FROM_DATABASE=Shellcomm, Inc.
+
+OUI:000518*
+ ID_OUI_FROM_DATABASE=Jupiters Technology
+
+OUI:000519*
+ ID_OUI_FROM_DATABASE=Siemens Building Technologies AG,
+
+OUI:00051A*
+ ID_OUI_FROM_DATABASE=3Com Europe Ltd.
+
+OUI:00051B*
+ ID_OUI_FROM_DATABASE=Magic Control Technology Corporation
+
+OUI:00051C*
+ ID_OUI_FROM_DATABASE=Xnet Technology Corp.
+
+OUI:00051D*
+ ID_OUI_FROM_DATABASE=Airocon, Inc.
+
+OUI:00051E*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00051F*
+ ID_OUI_FROM_DATABASE=Taijin Media Co., Ltd.
+
+OUI:000520*
+ ID_OUI_FROM_DATABASE=Smartronix, Inc.
+
+OUI:000521*
+ ID_OUI_FROM_DATABASE=Control Microsystems
+
+OUI:000522*
+ ID_OUI_FROM_DATABASE=LEA*D Corporation, Inc.
+
+OUI:000523*
+ ID_OUI_FROM_DATABASE=AVL List GmbH
+
+OUI:000524*
+ ID_OUI_FROM_DATABASE=BTL System (HK) Limited
+
+OUI:000525*
+ ID_OUI_FROM_DATABASE=Puretek Industrial Co., Ltd.
+
+OUI:000526*
+ ID_OUI_FROM_DATABASE=IPAS GmbH
+
+OUI:000527*
+ ID_OUI_FROM_DATABASE=SJ Tek Co. Ltd
+
+OUI:000528*
+ ID_OUI_FROM_DATABASE=New Focus, Inc.
+
+OUI:000529*
+ ID_OUI_FROM_DATABASE=Shanghai Broadan Communication Technology Co., Ltd
+
+OUI:00052A*
+ ID_OUI_FROM_DATABASE=Ikegami Tsushinki Co., Ltd.
+
+OUI:00052B*
+ ID_OUI_FROM_DATABASE=HORIBA, Ltd.
+
+OUI:00052C*
+ ID_OUI_FROM_DATABASE=Supreme Magic Corporation
+
+OUI:00052D*
+ ID_OUI_FROM_DATABASE=Zoltrix International Limited
+
+OUI:00052E*
+ ID_OUI_FROM_DATABASE=Cinta Networks
+
+OUI:00052F*
+ ID_OUI_FROM_DATABASE=Leviton Network Solutions
+
+OUI:000530*
+ ID_OUI_FROM_DATABASE=Andiamo Systems, Inc.
+
+OUI:000531*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000532*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000533*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000534*
+ ID_OUI_FROM_DATABASE=Northstar Engineering Ltd.
+
+OUI:000535*
+ ID_OUI_FROM_DATABASE=Chip PC Ltd.
+
+OUI:000536*
+ ID_OUI_FROM_DATABASE=Danam Communications, Inc.
+
+OUI:000537*
+ ID_OUI_FROM_DATABASE=Nets Technology Co., Ltd.
+
+OUI:000538*
+ ID_OUI_FROM_DATABASE=Merilus, Inc.
+
+OUI:000539*
+ ID_OUI_FROM_DATABASE=A Brand New World in Sweden AB
+
+OUI:00053A*
+ ID_OUI_FROM_DATABASE=Willowglen Services Pte Ltd
+
+OUI:00053B*
+ ID_OUI_FROM_DATABASE=Harbour Networks Ltd., Co. Beijing
+
+OUI:00053C*
+ ID_OUI_FROM_DATABASE=Xircom
+
+OUI:00053D*
+ ID_OUI_FROM_DATABASE=Agere Systems
+
+OUI:00053E*
+ ID_OUI_FROM_DATABASE=KID Systeme GmbH
+
+OUI:00053F*
+ ID_OUI_FROM_DATABASE=VisionTek, Inc.
+
+OUI:000540*
+ ID_OUI_FROM_DATABASE=FAST Corporation
+
+OUI:000541*
+ ID_OUI_FROM_DATABASE=Advanced Systems Co., Ltd.
+
+OUI:000542*
+ ID_OUI_FROM_DATABASE=Otari, Inc.
+
+OUI:000543*
+ ID_OUI_FROM_DATABASE=IQ Wireless GmbH
+
+OUI:000544*
+ ID_OUI_FROM_DATABASE=Valley Technologies, Inc.
+
+OUI:000545*
+ ID_OUI_FROM_DATABASE=Internet Photonics
+
+OUI:000546*
+ ID_OUI_FROM_DATABASE=KDDI Network & Solultions Inc.
+
+OUI:000547*
+ ID_OUI_FROM_DATABASE=Starent Networks
+
+OUI:000548*
+ ID_OUI_FROM_DATABASE=Disco Corporation
+
+OUI:000549*
+ ID_OUI_FROM_DATABASE=Salira Optical Network Systems
+
+OUI:00054A*
+ ID_OUI_FROM_DATABASE=Ario Data Networks, Inc.
+
+OUI:00054B*
+ ID_OUI_FROM_DATABASE=Eaton Automation AG
+
+OUI:00054C*
+ ID_OUI_FROM_DATABASE=RF Innovations Pty Ltd
+
+OUI:00054D*
+ ID_OUI_FROM_DATABASE=Brans Technologies, Inc.
+
+OUI:00054E*
+ ID_OUI_FROM_DATABASE=Philips
+
+OUI:000550*
+ ID_OUI_FROM_DATABASE=Vcomms Connect Limited
+
+OUI:000551*
+ ID_OUI_FROM_DATABASE=F & S Elektronik Systeme GmbH
+
+OUI:000552*
+ ID_OUI_FROM_DATABASE=Xycotec Computer GmbH
+
+OUI:000553*
+ ID_OUI_FROM_DATABASE=DVC Company, Inc.
+
+OUI:000554*
+ ID_OUI_FROM_DATABASE=Rangestar Wireless
+
+OUI:000555*
+ ID_OUI_FROM_DATABASE=Japan Cash Machine Co., Ltd.
+
+OUI:000556*
+ ID_OUI_FROM_DATABASE=360 Systems
+
+OUI:000557*
+ ID_OUI_FROM_DATABASE=Agile TV Corporation
+
+OUI:000558*
+ ID_OUI_FROM_DATABASE=Synchronous, Inc.
+
+OUI:000559*
+ ID_OUI_FROM_DATABASE=Intracom S.A.
+
+OUI:00055A*
+ ID_OUI_FROM_DATABASE=Power Dsine Ltd.
+
+OUI:00055B*
+ ID_OUI_FROM_DATABASE=Charles Industries, Ltd.
+
+OUI:00055C*
+ ID_OUI_FROM_DATABASE=Kowa Company, Ltd.
+
+OUI:00055D*
+ ID_OUI_FROM_DATABASE=D-Link Systems, Inc.
+
+OUI:00055E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00055F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000560*
+ ID_OUI_FROM_DATABASE=LEADER COMM.CO., LTD
+
+OUI:000561*
+ ID_OUI_FROM_DATABASE=nac Image Technology, Inc.
+
+OUI:000562*
+ ID_OUI_FROM_DATABASE=Digital View Limited
+
+OUI:000563*
+ ID_OUI_FROM_DATABASE=J-Works, Inc.
+
+OUI:000564*
+ ID_OUI_FROM_DATABASE=Tsinghua Bitway Co., Ltd.
+
+OUI:000565*
+ ID_OUI_FROM_DATABASE=Tailyn Communication Company Ltd.
+
+OUI:000566*
+ ID_OUI_FROM_DATABASE=Secui.com Corporation
+
+OUI:000567*
+ ID_OUI_FROM_DATABASE=Etymonic Design, Inc.
+
+OUI:000568*
+ ID_OUI_FROM_DATABASE=Piltofish Networks AB
+
+OUI:000569*
+ ID_OUI_FROM_DATABASE=VMware, Inc.
+
+OUI:00056A*
+ ID_OUI_FROM_DATABASE=Heuft Systemtechnik GmbH
+
+OUI:00056B*
+ ID_OUI_FROM_DATABASE=C.P. Technology Co., Ltd.
+
+OUI:00056C*
+ ID_OUI_FROM_DATABASE=Hung Chang Co., Ltd.
+
+OUI:00056D*
+ ID_OUI_FROM_DATABASE=Pacific Corporation
+
+OUI:00056E*
+ ID_OUI_FROM_DATABASE=National Enhance Technology, Inc.
+
+OUI:00056F*
+ ID_OUI_FROM_DATABASE=Innomedia Technologies Pvt. Ltd.
+
+OUI:000570*
+ ID_OUI_FROM_DATABASE=Baydel Ltd.
+
+OUI:000571*
+ ID_OUI_FROM_DATABASE=Seiwa Electronics Co.
+
+OUI:000572*
+ ID_OUI_FROM_DATABASE=Deonet Co., Ltd.
+
+OUI:000573*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000574*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000575*
+ ID_OUI_FROM_DATABASE=CDS-Electronics BV
+
+OUI:000576*
+ ID_OUI_FROM_DATABASE=NSM Technology Ltd.
+
+OUI:000577*
+ ID_OUI_FROM_DATABASE=SM Information & Communication
+
+OUI:000579*
+ ID_OUI_FROM_DATABASE=Universal Control Solution Corp.
+
+OUI:00057A*
+ ID_OUI_FROM_DATABASE=Overture Networks
+
+OUI:00057B*
+ ID_OUI_FROM_DATABASE=Chung Nam Electronic Co., Ltd.
+
+OUI:00057C*
+ ID_OUI_FROM_DATABASE=RCO Security AB
+
+OUI:00057D*
+ ID_OUI_FROM_DATABASE=Sun Communications, Inc.
+
+OUI:00057E*
+ ID_OUI_FROM_DATABASE=Eckelmann Steuerungstechnik GmbH
+
+OUI:00057F*
+ ID_OUI_FROM_DATABASE=Acqis Technology
+
+OUI:000580*
+ ID_OUI_FROM_DATABASE=Fibrolan Ltd.
+
+OUI:000581*
+ ID_OUI_FROM_DATABASE=Snell
+
+OUI:000582*
+ ID_OUI_FROM_DATABASE=ClearCube Technology
+
+OUI:000583*
+ ID_OUI_FROM_DATABASE=ImageCom Limited
+
+OUI:000584*
+ ID_OUI_FROM_DATABASE=AbsoluteValue Systems, Inc.
+
+OUI:000585*
+ ID_OUI_FROM_DATABASE=Juniper Networks, Inc.
+
+OUI:000586*
+ ID_OUI_FROM_DATABASE=Lucent Technologies
+
+OUI:000587*
+ ID_OUI_FROM_DATABASE=Locus, Incorporated
+
+OUI:000588*
+ ID_OUI_FROM_DATABASE=Sensoria Corp.
+
+OUI:000589*
+ ID_OUI_FROM_DATABASE=National Datacomputer
+
+OUI:00058A*
+ ID_OUI_FROM_DATABASE=Netcom Co., Ltd.
+
+OUI:00058B*
+ ID_OUI_FROM_DATABASE=IPmental, Inc.
+
+OUI:00058C*
+ ID_OUI_FROM_DATABASE=Opentech Inc.
+
+OUI:00058D*
+ ID_OUI_FROM_DATABASE=Lynx Photonic Networks, Inc.
+
+OUI:00058E*
+ ID_OUI_FROM_DATABASE=Flextronics International GmbH & Co. Nfg. KG
+
+OUI:00058F*
+ ID_OUI_FROM_DATABASE=CLCsoft co.
+
+OUI:000590*
+ ID_OUI_FROM_DATABASE=Swissvoice Ltd.
+
+OUI:000591*
+ ID_OUI_FROM_DATABASE=Active Silicon Ltd.
+
+OUI:000592*
+ ID_OUI_FROM_DATABASE=Pultek Corp.
+
+OUI:000593*
+ ID_OUI_FROM_DATABASE=Grammar Engine Inc.
+
+OUI:000594*
+ ID_OUI_FROM_DATABASE=IXXAT Automation GmbH
+
+OUI:000595*
+ ID_OUI_FROM_DATABASE=Alesis Corporation
+
+OUI:000596*
+ ID_OUI_FROM_DATABASE=Genotech Co., Ltd.
+
+OUI:000597*
+ ID_OUI_FROM_DATABASE=Eagle Traffic Control Systems
+
+OUI:000598*
+ ID_OUI_FROM_DATABASE=CRONOS S.r.l.
+
+OUI:000599*
+ ID_OUI_FROM_DATABASE=DRS Test and Energy Management or DRS-TEM
+
+OUI:00059A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00059B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00059C*
+ ID_OUI_FROM_DATABASE=Kleinknecht GmbH, Ing. Büro
+
+OUI:00059D*
+ ID_OUI_FROM_DATABASE=Daniel Computing Systems, Inc.
+
+OUI:00059E*
+ ID_OUI_FROM_DATABASE=Zinwell Corporation
+
+OUI:00059F*
+ ID_OUI_FROM_DATABASE=Yotta Networks, Inc.
+
+OUI:0005A0*
+ ID_OUI_FROM_DATABASE=MOBILINE Kft.
+
+OUI:0005A1*
+ ID_OUI_FROM_DATABASE=Zenocom
+
+OUI:0005A2*
+ ID_OUI_FROM_DATABASE=CELOX Networks
+
+OUI:0005A3*
+ ID_OUI_FROM_DATABASE=QEI, Inc.
+
+OUI:0005A4*
+ ID_OUI_FROM_DATABASE=Lucid Voice Ltd.
+
+OUI:0005A5*
+ ID_OUI_FROM_DATABASE=KOTT
+
+OUI:0005A6*
+ ID_OUI_FROM_DATABASE=Extron Electronics
+
+OUI:0005A7*
+ ID_OUI_FROM_DATABASE=Hyperchip, Inc.
+
+OUI:0005A8*
+ ID_OUI_FROM_DATABASE=WYLE ELECTRONICS
+
+OUI:0005A9*
+ ID_OUI_FROM_DATABASE=Princeton Networks, Inc.
+
+OUI:0005AA*
+ ID_OUI_FROM_DATABASE=Moore Industries International Inc.
+
+OUI:0005AB*
+ ID_OUI_FROM_DATABASE=Cyber Fone, Inc.
+
+OUI:0005AC*
+ ID_OUI_FROM_DATABASE=Northern Digital, Inc.
+
+OUI:0005AD*
+ ID_OUI_FROM_DATABASE=Topspin Communications, Inc.
+
+OUI:0005AE*
+ ID_OUI_FROM_DATABASE=Mediaport USA
+
+OUI:0005AF*
+ ID_OUI_FROM_DATABASE=InnoScan Computing A/S
+
+OUI:0005B0*
+ ID_OUI_FROM_DATABASE=Korea Computer Technology Co., Ltd.
+
+OUI:0005B1*
+ ID_OUI_FROM_DATABASE=ASB Technology BV
+
+OUI:0005B2*
+ ID_OUI_FROM_DATABASE=Medison Co., Ltd.
+
+OUI:0005B3*
+ ID_OUI_FROM_DATABASE=Asahi-Engineering Co., Ltd.
+
+OUI:0005B4*
+ ID_OUI_FROM_DATABASE=Aceex Corporation
+
+OUI:0005B5*
+ ID_OUI_FROM_DATABASE=Broadcom Technologies
+
+OUI:0005B6*
+ ID_OUI_FROM_DATABASE=INSYS Microelectronics GmbH
+
+OUI:0005B7*
+ ID_OUI_FROM_DATABASE=Arbor Technology Corp.
+
+OUI:0005B8*
+ ID_OUI_FROM_DATABASE=Electronic Design Associates, Inc.
+
+OUI:0005B9*
+ ID_OUI_FROM_DATABASE=Airvana, Inc.
+
+OUI:0005BA*
+ ID_OUI_FROM_DATABASE=Area Netwoeks, Inc.
+
+OUI:0005BB*
+ ID_OUI_FROM_DATABASE=Myspace AB
+
+OUI:0005BC*
+ ID_OUI_FROM_DATABASE=Resorsys Ltd.
+
+OUI:0005BD*
+ ID_OUI_FROM_DATABASE=ROAX BV
+
+OUI:0005BE*
+ ID_OUI_FROM_DATABASE=Kongsberg Seatex AS
+
+OUI:0005BF*
+ ID_OUI_FROM_DATABASE=JustEzy Technology, Inc.
+
+OUI:0005C0*
+ ID_OUI_FROM_DATABASE=Digital Network Alacarte Co., Ltd.
+
+OUI:0005C1*
+ ID_OUI_FROM_DATABASE=A-Kyung Motion, Inc.
+
+OUI:0005C2*
+ ID_OUI_FROM_DATABASE=Soronti, Inc.
+
+OUI:0005C3*
+ ID_OUI_FROM_DATABASE=Pacific Instruments, Inc.
+
+OUI:0005C4*
+ ID_OUI_FROM_DATABASE=Telect, Inc.
+
+OUI:0005C5*
+ ID_OUI_FROM_DATABASE=Flaga HF
+
+OUI:0005C6*
+ ID_OUI_FROM_DATABASE=Triz Communications
+
+OUI:0005C7*
+ ID_OUI_FROM_DATABASE=I/F-COM A/S
+
+OUI:0005C8*
+ ID_OUI_FROM_DATABASE=VERYTECH
+
+OUI:0005C9*
+ ID_OUI_FROM_DATABASE=LG Innotek Co., Ltd.
+
+OUI:0005CA*
+ ID_OUI_FROM_DATABASE=Hitron Technology, Inc.
+
+OUI:0005CB*
+ ID_OUI_FROM_DATABASE=ROIS Technologies, Inc.
+
+OUI:0005CC*
+ ID_OUI_FROM_DATABASE=Sumtel Communications, Inc.
+
+OUI:0005CD*
+ ID_OUI_FROM_DATABASE=Denon, Ltd.
+
+OUI:0005CE*
+ ID_OUI_FROM_DATABASE=Prolink Microsystems Corporation
+
+OUI:0005CF*
+ ID_OUI_FROM_DATABASE=Thunder River Technologies, Inc.
+
+OUI:0005D0*
+ ID_OUI_FROM_DATABASE=Solinet Systems
+
+OUI:0005D1*
+ ID_OUI_FROM_DATABASE=Metavector Technologies
+
+OUI:0005D2*
+ ID_OUI_FROM_DATABASE=DAP Technologies
+
+OUI:0005D3*
+ ID_OUI_FROM_DATABASE=eProduction Solutions, Inc.
+
+OUI:0005D4*
+ ID_OUI_FROM_DATABASE=FutureSmart Networks, Inc.
+
+OUI:0005D5*
+ ID_OUI_FROM_DATABASE=Speedcom Wireless
+
+OUI:0005D6*
+ ID_OUI_FROM_DATABASE=Titan Wireless
+
+OUI:0005D7*
+ ID_OUI_FROM_DATABASE=Vista Imaging, Inc.
+
+OUI:0005D8*
+ ID_OUI_FROM_DATABASE=Arescom, Inc.
+
+OUI:0005D9*
+ ID_OUI_FROM_DATABASE=Techno Valley, Inc.
+
+OUI:0005DA*
+ ID_OUI_FROM_DATABASE=Apex Automationstechnik
+
+OUI:0005DB*
+ ID_OUI_FROM_DATABASE=PSI Nentec GmbH
+
+OUI:0005DC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0005DD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0005DE*
+ ID_OUI_FROM_DATABASE=Gi Fone Korea, Inc.
+
+OUI:0005DF*
+ ID_OUI_FROM_DATABASE=Electronic Innovation, Inc.
+
+OUI:0005E0*
+ ID_OUI_FROM_DATABASE=Empirix Corp.
+
+OUI:0005E1*
+ ID_OUI_FROM_DATABASE=Trellis Photonics, Ltd.
+
+OUI:0005E2*
+ ID_OUI_FROM_DATABASE=Creativ Network Technologies
+
+OUI:0005E3*
+ ID_OUI_FROM_DATABASE=LightSand Communications, Inc.
+
+OUI:0005E4*
+ ID_OUI_FROM_DATABASE=Red Lion Controls Inc.
+
+OUI:0005E5*
+ ID_OUI_FROM_DATABASE=Renishaw PLC
+
+OUI:0005E6*
+ ID_OUI_FROM_DATABASE=Egenera, Inc.
+
+OUI:0005E7*
+ ID_OUI_FROM_DATABASE=Netrake an AudioCodes Company
+
+OUI:0005E8*
+ ID_OUI_FROM_DATABASE=TurboWave, Inc.
+
+OUI:0005E9*
+ ID_OUI_FROM_DATABASE=Unicess Network, Inc.
+
+OUI:0005EA*
+ ID_OUI_FROM_DATABASE=Rednix
+
+OUI:0005EB*
+ ID_OUI_FROM_DATABASE=Blue Ridge Networks, Inc.
+
+OUI:0005EC*
+ ID_OUI_FROM_DATABASE=Mosaic Systems Inc.
+
+OUI:0005ED*
+ ID_OUI_FROM_DATABASE=Technikum Joanneum GmbH
+
+OUI:0005EE*
+ ID_OUI_FROM_DATABASE=BEWATOR Group
+
+OUI:0005EF*
+ ID_OUI_FROM_DATABASE=ADOIR Digital Technology
+
+OUI:0005F0*
+ ID_OUI_FROM_DATABASE=SATEC
+
+OUI:0005F1*
+ ID_OUI_FROM_DATABASE=Vrcom, Inc.
+
+OUI:0005F2*
+ ID_OUI_FROM_DATABASE=Power R, Inc.
+
+OUI:0005F3*
+ ID_OUI_FROM_DATABASE=Weboyn
+
+OUI:0005F4*
+ ID_OUI_FROM_DATABASE=System Base Co., Ltd.
+
+OUI:0005F5*
+ ID_OUI_FROM_DATABASE=OYO Geospace
+
+OUI:0005F6*
+ ID_OUI_FROM_DATABASE=Young Chang Co. Ltd.
+
+OUI:0005F7*
+ ID_OUI_FROM_DATABASE=Analog Devices, Inc.
+
+OUI:0005F8*
+ ID_OUI_FROM_DATABASE=Real Time Access, Inc.
+
+OUI:0005F9*
+ ID_OUI_FROM_DATABASE=TOA Corporation
+
+OUI:0005FA*
+ ID_OUI_FROM_DATABASE=IPOptical, Inc.
+
+OUI:0005FB*
+ ID_OUI_FROM_DATABASE=ShareGate, Inc.
+
+OUI:0005FC*
+ ID_OUI_FROM_DATABASE=Schenck Pegasus Corp.
+
+OUI:0005FD*
+ ID_OUI_FROM_DATABASE=PacketLight Networks Ltd.
+
+OUI:0005FE*
+ ID_OUI_FROM_DATABASE=Traficon N.V.
+
+OUI:0005FF*
+ ID_OUI_FROM_DATABASE=SNS Solutions, Inc.
+
+OUI:000600*
+ ID_OUI_FROM_DATABASE=Toshiba Teli Corporation
+
+OUI:000601*
+ ID_OUI_FROM_DATABASE=Otanikeiki Co., Ltd.
+
+OUI:000602*
+ ID_OUI_FROM_DATABASE=Cirkitech Electronics Co.
+
+OUI:000603*
+ ID_OUI_FROM_DATABASE=Baker Hughes Inc.
+
+OUI:000604*
+ ID_OUI_FROM_DATABASE=@Track Communications, Inc.
+
+OUI:000605*
+ ID_OUI_FROM_DATABASE=Inncom International, Inc.
+
+OUI:000606*
+ ID_OUI_FROM_DATABASE=RapidWAN, Inc.
+
+OUI:000607*
+ ID_OUI_FROM_DATABASE=Omni Directional Control Technology Inc.
+
+OUI:000608*
+ ID_OUI_FROM_DATABASE=At-Sky SAS
+
+OUI:000609*
+ ID_OUI_FROM_DATABASE=Crossport Systems
+
+OUI:00060A*
+ ID_OUI_FROM_DATABASE=Blue2space
+
+OUI:00060B*
+ ID_OUI_FROM_DATABASE=Emerson Network Power
+
+OUI:00060C*
+ ID_OUI_FROM_DATABASE=Melco Industries, Inc.
+
+OUI:00060D*
+ ID_OUI_FROM_DATABASE=Wave7 Optics
+
+OUI:00060E*
+ ID_OUI_FROM_DATABASE=IGYS Systems, Inc.
+
+OUI:00060F*
+ ID_OUI_FROM_DATABASE=Narad Networks Inc
+
+OUI:000610*
+ ID_OUI_FROM_DATABASE=Abeona Networks Inc
+
+OUI:000611*
+ ID_OUI_FROM_DATABASE=Zeus Wireless, Inc.
+
+OUI:000612*
+ ID_OUI_FROM_DATABASE=Accusys, Inc.
+
+OUI:000613*
+ ID_OUI_FROM_DATABASE=Kawasaki Microelectronics Incorporated
+
+OUI:000614*
+ ID_OUI_FROM_DATABASE=Prism Holdings
+
+OUI:000615*
+ ID_OUI_FROM_DATABASE=Kimoto Electric Co., Ltd.
+
+OUI:000616*
+ ID_OUI_FROM_DATABASE=Tel Net Co., Ltd.
+
+OUI:000617*
+ ID_OUI_FROM_DATABASE=Redswitch Inc.
+
+OUI:000618*
+ ID_OUI_FROM_DATABASE=DigiPower Manufacturing Inc.
+
+OUI:000619*
+ ID_OUI_FROM_DATABASE=Connection Technology Systems
+
+OUI:00061A*
+ ID_OUI_FROM_DATABASE=Zetari Inc.
+
+OUI:00061B*
+ ID_OUI_FROM_DATABASE=Notebook Development Lab.  Lenovo Japan Ltd.
+
+OUI:00061C*
+ ID_OUI_FROM_DATABASE=Hoshino Metal Industries, Ltd.
+
+OUI:00061D*
+ ID_OUI_FROM_DATABASE=MIP Telecom, Inc.
+
+OUI:00061E*
+ ID_OUI_FROM_DATABASE=Maxan Systems
+
+OUI:00061F*
+ ID_OUI_FROM_DATABASE=Vision Components GmbH
+
+OUI:000620*
+ ID_OUI_FROM_DATABASE=Serial System Ltd.
+
+OUI:000621*
+ ID_OUI_FROM_DATABASE=Hinox, Co., Ltd.
+
+OUI:000622*
+ ID_OUI_FROM_DATABASE=Chung Fu Chen Yeh Enterprise Corp.
+
+OUI:000623*
+ ID_OUI_FROM_DATABASE=MGE UPS Systems France
+
+OUI:000624*
+ ID_OUI_FROM_DATABASE=Gentner Communications Corp.
+
+OUI:000625*
+ ID_OUI_FROM_DATABASE=The Linksys Group, Inc.
+
+OUI:000626*
+ ID_OUI_FROM_DATABASE=MWE GmbH
+
+OUI:000627*
+ ID_OUI_FROM_DATABASE=Uniwide Technologies, Inc.
+
+OUI:000628*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000629*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:00062A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00062B*
+ ID_OUI_FROM_DATABASE=INTRASERVER TECHNOLOGY
+
+OUI:00062C*
+ ID_OUI_FROM_DATABASE=Bivio Networks
+
+OUI:00062D*
+ ID_OUI_FROM_DATABASE=TouchStar Technologies, L.L.C.
+
+OUI:00062E*
+ ID_OUI_FROM_DATABASE=Aristos Logic Corp.
+
+OUI:00062F*
+ ID_OUI_FROM_DATABASE=Pivotech Systems Inc.
+
+OUI:000630*
+ ID_OUI_FROM_DATABASE=Adtranz Sweden
+
+OUI:000631*
+ ID_OUI_FROM_DATABASE=Optical Solutions, Inc.
+
+OUI:000632*
+ ID_OUI_FROM_DATABASE=Mesco Engineering GmbH
+
+OUI:000633*
+ ID_OUI_FROM_DATABASE=Cross Match Technologies GmbH
+
+OUI:000634*
+ ID_OUI_FROM_DATABASE=GTE Airfone Inc.
+
+OUI:000635*
+ ID_OUI_FROM_DATABASE=PacketAir Networks, Inc.
+
+OUI:000636*
+ ID_OUI_FROM_DATABASE=Jedai Broadband Networks
+
+OUI:000637*
+ ID_OUI_FROM_DATABASE=Toptrend-Meta Information (ShenZhen) Inc.
+
+OUI:000638*
+ ID_OUI_FROM_DATABASE=Sungjin C&C Co., Ltd.
+
+OUI:000639*
+ ID_OUI_FROM_DATABASE=Newtec
+
+OUI:00063A*
+ ID_OUI_FROM_DATABASE=Dura Micro, Inc.
+
+OUI:00063B*
+ ID_OUI_FROM_DATABASE=Arcturus Networks, Inc.
+
+OUI:00063C*
+ ID_OUI_FROM_DATABASE=Intrinsyc Europe Ltd
+
+OUI:00063D*
+ ID_OUI_FROM_DATABASE=Microwave Data Systems Inc.
+
+OUI:00063E*
+ ID_OUI_FROM_DATABASE=Opthos Inc.
+
+OUI:00063F*
+ ID_OUI_FROM_DATABASE=Everex Communications Inc.
+
+OUI:000640*
+ ID_OUI_FROM_DATABASE=White Rock Networks
+
+OUI:000641*
+ ID_OUI_FROM_DATABASE=ITCN
+
+OUI:000642*
+ ID_OUI_FROM_DATABASE=Genetel Systems Inc.
+
+OUI:000643*
+ ID_OUI_FROM_DATABASE=SONO Computer Co., Ltd.
+
+OUI:000644*
+ ID_OUI_FROM_DATABASE=Neix,Inc
+
+OUI:000645*
+ ID_OUI_FROM_DATABASE=Meisei Electric Co. Ltd.
+
+OUI:000646*
+ ID_OUI_FROM_DATABASE=ShenZhen XunBao Network Technology Co Ltd
+
+OUI:000647*
+ ID_OUI_FROM_DATABASE=Etrali S.A.
+
+OUI:000648*
+ ID_OUI_FROM_DATABASE=Seedsware, Inc.
+
+OUI:000649*
+ ID_OUI_FROM_DATABASE=3M Deutschland GmbH
+
+OUI:00064A*
+ ID_OUI_FROM_DATABASE=Honeywell Co., Ltd. (KOREA)
+
+OUI:00064B*
+ ID_OUI_FROM_DATABASE=Alexon Co., Ltd.
+
+OUI:00064C*
+ ID_OUI_FROM_DATABASE=Invicta Networks, Inc.
+
+OUI:00064D*
+ ID_OUI_FROM_DATABASE=Sencore
+
+OUI:00064E*
+ ID_OUI_FROM_DATABASE=Broad Net Technology Inc.
+
+OUI:00064F*
+ ID_OUI_FROM_DATABASE=PRO-NETS Technology Corporation
+
+OUI:000650*
+ ID_OUI_FROM_DATABASE=Tiburon Networks, Inc.
+
+OUI:000651*
+ ID_OUI_FROM_DATABASE=Aspen Networks Inc.
+
+OUI:000652*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000653*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000654*
+ ID_OUI_FROM_DATABASE=Winpresa Building Automation Technologies GmbH
+
+OUI:000655*
+ ID_OUI_FROM_DATABASE=Yipee, Inc.
+
+OUI:000656*
+ ID_OUI_FROM_DATABASE=Tactel AB
+
+OUI:000657*
+ ID_OUI_FROM_DATABASE=Market Central, Inc.
+
+OUI:000658*
+ ID_OUI_FROM_DATABASE=Helmut Fischer GmbH Institut für Elektronik und Messtechnik
+
+OUI:000659*
+ ID_OUI_FROM_DATABASE=EAL (Apeldoorn) B.V.
+
+OUI:00065A*
+ ID_OUI_FROM_DATABASE=Strix Systems
+
+OUI:00065B*
+ ID_OUI_FROM_DATABASE=Dell Computer Corp.
+
+OUI:00065C*
+ ID_OUI_FROM_DATABASE=Malachite Technologies, Inc.
+
+OUI:00065D*
+ ID_OUI_FROM_DATABASE=Heidelberg Web Systems
+
+OUI:00065E*
+ ID_OUI_FROM_DATABASE=Photuris, Inc.
+
+OUI:00065F*
+ ID_OUI_FROM_DATABASE=ECI Telecom - NGTS Ltd.
+
+OUI:000660*
+ ID_OUI_FROM_DATABASE=NADEX Co., Ltd.
+
+OUI:000661*
+ ID_OUI_FROM_DATABASE=NIA Home Technologies Corp.
+
+OUI:000662*
+ ID_OUI_FROM_DATABASE=MBM Technology Ltd.
+
+OUI:000663*
+ ID_OUI_FROM_DATABASE=Human Technology Co., Ltd.
+
+OUI:000664*
+ ID_OUI_FROM_DATABASE=Fostex Corporation
+
+OUI:000665*
+ ID_OUI_FROM_DATABASE=Sunny Giken, Inc.
+
+OUI:000666*
+ ID_OUI_FROM_DATABASE=Roving Networks
+
+OUI:000667*
+ ID_OUI_FROM_DATABASE=Tripp Lite
+
+OUI:000668*
+ ID_OUI_FROM_DATABASE=Vicon Industries Inc.
+
+OUI:000669*
+ ID_OUI_FROM_DATABASE=Datasound Laboratories Ltd
+
+OUI:00066A*
+ ID_OUI_FROM_DATABASE=InfiniCon Systems, Inc.
+
+OUI:00066B*
+ ID_OUI_FROM_DATABASE=Sysmex Corporation
+
+OUI:00066C*
+ ID_OUI_FROM_DATABASE=Robinson Corporation
+
+OUI:00066D*
+ ID_OUI_FROM_DATABASE=Compuprint S.P.A.
+
+OUI:00066E*
+ ID_OUI_FROM_DATABASE=Delta Electronics, Inc.
+
+OUI:00066F*
+ ID_OUI_FROM_DATABASE=Korea Data Systems
+
+OUI:000670*
+ ID_OUI_FROM_DATABASE=Upponetti Oy
+
+OUI:000671*
+ ID_OUI_FROM_DATABASE=Softing AG
+
+OUI:000672*
+ ID_OUI_FROM_DATABASE=Netezza
+
+OUI:000673*
+ ID_OUI_FROM_DATABASE=TKH Security Solutions USA
+
+OUI:000674*
+ ID_OUI_FROM_DATABASE=Spectrum Control, Inc.
+
+OUI:000675*
+ ID_OUI_FROM_DATABASE=Banderacom, Inc.
+
+OUI:000676*
+ ID_OUI_FROM_DATABASE=Novra Technologies Inc.
+
+OUI:000677*
+ ID_OUI_FROM_DATABASE=SICK AG
+
+OUI:000678*
+ ID_OUI_FROM_DATABASE=Marantz Brand Company
+
+OUI:000679*
+ ID_OUI_FROM_DATABASE=Konami Corporation
+
+OUI:00067A*
+ ID_OUI_FROM_DATABASE=JMP Systems
+
+OUI:00067B*
+ ID_OUI_FROM_DATABASE=Toplink C&C Corporation
+
+OUI:00067C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00067D*
+ ID_OUI_FROM_DATABASE=Takasago Ltd.
+
+OUI:00067E*
+ ID_OUI_FROM_DATABASE=WinCom Systems, Inc.
+
+OUI:00067F*
+ ID_OUI_FROM_DATABASE=Digeo, Inc.
+
+OUI:000680*
+ ID_OUI_FROM_DATABASE=Card Access, Inc.
+
+OUI:000681*
+ ID_OUI_FROM_DATABASE=Goepel Electronic GmbH
+
+OUI:000682*
+ ID_OUI_FROM_DATABASE=Convedia
+
+OUI:000683*
+ ID_OUI_FROM_DATABASE=Bravara Communications, Inc.
+
+OUI:000684*
+ ID_OUI_FROM_DATABASE=Biacore AB
+
+OUI:000685*
+ ID_OUI_FROM_DATABASE=NetNearU Corporation
+
+OUI:000686*
+ ID_OUI_FROM_DATABASE=ZARDCOM Co., Ltd.
+
+OUI:000687*
+ ID_OUI_FROM_DATABASE=Omnitron Systems Technology, Inc.
+
+OUI:000688*
+ ID_OUI_FROM_DATABASE=Telways Communication Co., Ltd.
+
+OUI:000689*
+ ID_OUI_FROM_DATABASE=yLez Technologies Pte Ltd
+
+OUI:00068A*
+ ID_OUI_FROM_DATABASE=NeuronNet Co. Ltd. R&D Center
+
+OUI:00068B*
+ ID_OUI_FROM_DATABASE=AirRunner Technologies, Inc.
+
+OUI:00068C*
+ ID_OUI_FROM_DATABASE=3Com Corporation
+
+OUI:00068D*
+ ID_OUI_FROM_DATABASE=SEPATON, Inc.
+
+OUI:00068E*
+ ID_OUI_FROM_DATABASE=HID Corporation
+
+OUI:00068F*
+ ID_OUI_FROM_DATABASE=Telemonitor, Inc.
+
+OUI:000690*
+ ID_OUI_FROM_DATABASE=Euracom Communication GmbH
+
+OUI:000691*
+ ID_OUI_FROM_DATABASE=PT Inovacao
+
+OUI:000692*
+ ID_OUI_FROM_DATABASE=Intruvert Networks, Inc.
+
+OUI:000693*
+ ID_OUI_FROM_DATABASE=Flexus Computer Technology, Inc.
+
+OUI:000694*
+ ID_OUI_FROM_DATABASE=Mobillian Corporation
+
+OUI:000695*
+ ID_OUI_FROM_DATABASE=Ensure Technologies, Inc.
+
+OUI:000696*
+ ID_OUI_FROM_DATABASE=Advent Networks
+
+OUI:000697*
+ ID_OUI_FROM_DATABASE=R & D Center
+
+OUI:000698*
+ ID_OUI_FROM_DATABASE=egnite Software GmbH
+
+OUI:000699*
+ ID_OUI_FROM_DATABASE=Vida Design Co.
+
+OUI:00069A*
+ ID_OUI_FROM_DATABASE=e & Tel
+
+OUI:00069B*
+ ID_OUI_FROM_DATABASE=AVT Audio Video Technologies GmbH
+
+OUI:00069C*
+ ID_OUI_FROM_DATABASE=Transmode Systems AB
+
+OUI:00069D*
+ ID_OUI_FROM_DATABASE=Petards Ltd
+
+OUI:00069E*
+ ID_OUI_FROM_DATABASE=UNIQA, Inc.
+
+OUI:00069F*
+ ID_OUI_FROM_DATABASE=Kuokoa Networks
+
+OUI:0006A0*
+ ID_OUI_FROM_DATABASE=Mx Imaging
+
+OUI:0006A1*
+ ID_OUI_FROM_DATABASE=Celsian Technologies, Inc.
+
+OUI:0006A2*
+ ID_OUI_FROM_DATABASE=Microtune, Inc.
+
+OUI:0006A3*
+ ID_OUI_FROM_DATABASE=Bitran Corporation
+
+OUI:0006A4*
+ ID_OUI_FROM_DATABASE=INNOWELL Corp.
+
+OUI:0006A5*
+ ID_OUI_FROM_DATABASE=PINON Corp.
+
+OUI:0006A6*
+ ID_OUI_FROM_DATABASE=Artistic Licence (UK) Ltd
+
+OUI:0006A7*
+ ID_OUI_FROM_DATABASE=Primarion
+
+OUI:0006A8*
+ ID_OUI_FROM_DATABASE=KC Technology, Inc.
+
+OUI:0006A9*
+ ID_OUI_FROM_DATABASE=Universal Instruments Corp.
+
+OUI:0006AA*
+ ID_OUI_FROM_DATABASE=VT Miltope
+
+OUI:0006AB*
+ ID_OUI_FROM_DATABASE=W-Link Systems, Inc.
+
+OUI:0006AC*
+ ID_OUI_FROM_DATABASE=Intersoft Co.
+
+OUI:0006AD*
+ ID_OUI_FROM_DATABASE=KB Electronics Ltd.
+
+OUI:0006AE*
+ ID_OUI_FROM_DATABASE=Himachal Futuristic Communications Ltd
+
+OUI:0006AF*
+ ID_OUI_FROM_DATABASE=Xalted Networks
+
+OUI:0006B0*
+ ID_OUI_FROM_DATABASE=Comtech EF Data Corp.
+
+OUI:0006B1*
+ ID_OUI_FROM_DATABASE=Sonicwall
+
+OUI:0006B2*
+ ID_OUI_FROM_DATABASE=Linxtek Co.
+
+OUI:0006B3*
+ ID_OUI_FROM_DATABASE=Diagraph Corporation
+
+OUI:0006B4*
+ ID_OUI_FROM_DATABASE=Vorne Industries, Inc.
+
+OUI:0006B5*
+ ID_OUI_FROM_DATABASE=Source Photonics, Inc.
+
+OUI:0006B6*
+ ID_OUI_FROM_DATABASE=Nir-Or Israel Ltd.
+
+OUI:0006B7*
+ ID_OUI_FROM_DATABASE=TELEM GmbH
+
+OUI:0006B8*
+ ID_OUI_FROM_DATABASE=Bandspeed Pty Ltd
+
+OUI:0006B9*
+ ID_OUI_FROM_DATABASE=A5TEK Corp.
+
+OUI:0006BA*
+ ID_OUI_FROM_DATABASE=Westwave Communications
+
+OUI:0006BB*
+ ID_OUI_FROM_DATABASE=ATI Technologies Inc.
+
+OUI:0006BC*
+ ID_OUI_FROM_DATABASE=Macrolink, Inc.
+
+OUI:0006BD*
+ ID_OUI_FROM_DATABASE=BNTECHNOLOGY Co., Ltd.
+
+OUI:0006BE*
+ ID_OUI_FROM_DATABASE=Baumer Optronic GmbH
+
+OUI:0006BF*
+ ID_OUI_FROM_DATABASE=Accella Technologies Co., Ltd.
+
+OUI:0006C0*
+ ID_OUI_FROM_DATABASE=United Internetworks, Inc.
+
+OUI:0006C1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0006C2*
+ ID_OUI_FROM_DATABASE=Smartmatic Corporation
+
+OUI:0006C3*
+ ID_OUI_FROM_DATABASE=Schindler Elevator Ltd.
+
+OUI:0006C4*
+ ID_OUI_FROM_DATABASE=Piolink Inc.
+
+OUI:0006C5*
+ ID_OUI_FROM_DATABASE=INNOVI Technologies Limited
+
+OUI:0006C6*
+ ID_OUI_FROM_DATABASE=lesswire AG
+
+OUI:0006C7*
+ ID_OUI_FROM_DATABASE=RFNET Technologies Pte Ltd (S)
+
+OUI:0006C8*
+ ID_OUI_FROM_DATABASE=Sumitomo Metal Micro Devices, Inc.
+
+OUI:0006C9*
+ ID_OUI_FROM_DATABASE=Technical Marketing Research, Inc.
+
+OUI:0006CA*
+ ID_OUI_FROM_DATABASE=American Computer & Digital Components, Inc. (ACDC)
+
+OUI:0006CB*
+ ID_OUI_FROM_DATABASE=Jotron Electronics A/S
+
+OUI:0006CC*
+ ID_OUI_FROM_DATABASE=JMI Electronics Co., Ltd.
+
+OUI:0006CD*
+ ID_OUI_FROM_DATABASE=Leaf Imaging Ltd.
+
+OUI:0006CE*
+ ID_OUI_FROM_DATABASE=DATENO
+
+OUI:0006CF*
+ ID_OUI_FROM_DATABASE=Thales Avionics In-Flight Systems, LLC
+
+OUI:0006D0*
+ ID_OUI_FROM_DATABASE=Elgar Electronics Corp.
+
+OUI:0006D1*
+ ID_OUI_FROM_DATABASE=Tahoe Networks, Inc.
+
+OUI:0006D2*
+ ID_OUI_FROM_DATABASE=Tundra Semiconductor Corp.
+
+OUI:0006D3*
+ ID_OUI_FROM_DATABASE=Alpha Telecom, Inc. U.S.A.
+
+OUI:0006D4*
+ ID_OUI_FROM_DATABASE=Interactive Objects, Inc.
+
+OUI:0006D5*
+ ID_OUI_FROM_DATABASE=Diamond Systems Corp.
+
+OUI:0006D6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0006D7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0006D8*
+ ID_OUI_FROM_DATABASE=Maple Optical Systems
+
+OUI:0006D9*
+ ID_OUI_FROM_DATABASE=IPM-Net S.p.A.
+
+OUI:0006DA*
+ ID_OUI_FROM_DATABASE=ITRAN Communications Ltd.
+
+OUI:0006DB*
+ ID_OUI_FROM_DATABASE=ICHIPS Co., Ltd.
+
+OUI:0006DC*
+ ID_OUI_FROM_DATABASE=Syabas Technology (Amquest)
+
+OUI:0006DD*
+ ID_OUI_FROM_DATABASE=AT & T Laboratories - Cambridge Ltd
+
+OUI:0006DE*
+ ID_OUI_FROM_DATABASE=Flash Technology
+
+OUI:0006DF*
+ ID_OUI_FROM_DATABASE=AIDONIC Corporation
+
+OUI:0006E0*
+ ID_OUI_FROM_DATABASE=MAT Co., Ltd.
+
+OUI:0006E1*
+ ID_OUI_FROM_DATABASE=Techno Trade s.a
+
+OUI:0006E2*
+ ID_OUI_FROM_DATABASE=Ceemax Technology Co., Ltd.
+
+OUI:0006E3*
+ ID_OUI_FROM_DATABASE=Quantitative Imaging Corporation
+
+OUI:0006E4*
+ ID_OUI_FROM_DATABASE=Citel Technologies Ltd.
+
+OUI:0006E5*
+ ID_OUI_FROM_DATABASE=Fujian Newland Computer Ltd. Co.
+
+OUI:0006E6*
+ ID_OUI_FROM_DATABASE=DongYang Telecom Co., Ltd.
+
+OUI:0006E7*
+ ID_OUI_FROM_DATABASE=Bit Blitz Communications Inc.
+
+OUI:0006E8*
+ ID_OUI_FROM_DATABASE=Optical Network Testing, Inc.
+
+OUI:0006E9*
+ ID_OUI_FROM_DATABASE=Intime Corp.
+
+OUI:0006EA*
+ ID_OUI_FROM_DATABASE=ELZET80 Mikrocomputer GmbH&Co. KG
+
+OUI:0006EB*
+ ID_OUI_FROM_DATABASE=Global Data
+
+OUI:0006EC*
+ ID_OUI_FROM_DATABASE=Harris Corporation
+
+OUI:0006ED*
+ ID_OUI_FROM_DATABASE=Inara Networks
+
+OUI:0006EE*
+ ID_OUI_FROM_DATABASE=Shenyang Neu-era Information & Technology Stock Co., Ltd
+
+OUI:0006EF*
+ ID_OUI_FROM_DATABASE=Maxxan Systems, Inc.
+
+OUI:0006F0*
+ ID_OUI_FROM_DATABASE=Digeo, Inc.
+
+OUI:0006F1*
+ ID_OUI_FROM_DATABASE=Optillion
+
+OUI:0006F2*
+ ID_OUI_FROM_DATABASE=Platys Communications
+
+OUI:0006F3*
+ ID_OUI_FROM_DATABASE=AcceLight Networks
+
+OUI:0006F4*
+ ID_OUI_FROM_DATABASE=Prime Electronics & Satellitics Inc.
+
+OUI:0006F5*
+ ID_OUI_FROM_DATABASE=ALPS Co,. Ltd.
+
+OUI:0006F6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0006F7*
+ ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd.
+
+OUI:0006F8*
+ ID_OUI_FROM_DATABASE=CPU Technology, Inc.
+
+OUI:0006F9*
+ ID_OUI_FROM_DATABASE=Mitsui Zosen Systems Research Inc.
+
+OUI:0006FA*
+ ID_OUI_FROM_DATABASE=IP SQUARE Co, Ltd.
+
+OUI:0006FB*
+ ID_OUI_FROM_DATABASE=Hitachi Printing Solutions, Ltd.
+
+OUI:0006FC*
+ ID_OUI_FROM_DATABASE=Fnet Co., Ltd.
+
+OUI:0006FD*
+ ID_OUI_FROM_DATABASE=Comjet Information Systems Corp.
+
+OUI:0006FE*
+ ID_OUI_FROM_DATABASE=Ambrado, Inc
+
+OUI:0006FF*
+ ID_OUI_FROM_DATABASE=Sheba Systems Co., Ltd.
+
+OUI:000700*
+ ID_OUI_FROM_DATABASE=Zettamedia Korea
+
+OUI:000701*
+ ID_OUI_FROM_DATABASE=RACAL-DATACOM
+
+OUI:000702*
+ ID_OUI_FROM_DATABASE=Varian Medical Systems
+
+OUI:000703*
+ ID_OUI_FROM_DATABASE=CSEE Transport
+
+OUI:000704*
+ ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd.
+
+OUI:000705*
+ ID_OUI_FROM_DATABASE=Endress & Hauser GmbH & Co
+
+OUI:000706*
+ ID_OUI_FROM_DATABASE=Sanritz Corporation
+
+OUI:000707*
+ ID_OUI_FROM_DATABASE=Interalia Inc.
+
+OUI:000708*
+ ID_OUI_FROM_DATABASE=Bitrage Inc.
+
+OUI:000709*
+ ID_OUI_FROM_DATABASE=Westerstrand Urfabrik AB
+
+OUI:00070A*
+ ID_OUI_FROM_DATABASE=Unicom Automation Co., Ltd.
+
+OUI:00070B*
+ ID_OUI_FROM_DATABASE=Novabase SGPS, SA
+
+OUI:00070C*
+ ID_OUI_FROM_DATABASE=SVA-Intrusion.com Co. Ltd.
+
+OUI:00070D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00070E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00070F*
+ ID_OUI_FROM_DATABASE=Fujant, Inc.
+
+OUI:000710*
+ ID_OUI_FROM_DATABASE=Adax, Inc.
+
+OUI:000711*
+ ID_OUI_FROM_DATABASE=Acterna
+
+OUI:000712*
+ ID_OUI_FROM_DATABASE=JAL Information Technology
+
+OUI:000713*
+ ID_OUI_FROM_DATABASE=IP One, Inc.
+
+OUI:000714*
+ ID_OUI_FROM_DATABASE=Brightcom
+
+OUI:000715*
+ ID_OUI_FROM_DATABASE=General Research of Electronics, Inc.
+
+OUI:000716*
+ ID_OUI_FROM_DATABASE=J & S Marine Ltd.
+
+OUI:000717*
+ ID_OUI_FROM_DATABASE=Wieland Electric GmbH
+
+OUI:000718*
+ ID_OUI_FROM_DATABASE=iCanTek Co., Ltd.
+
+OUI:000719*
+ ID_OUI_FROM_DATABASE=Mobiis Co., Ltd.
+
+OUI:00071A*
+ ID_OUI_FROM_DATABASE=Finedigital Inc.
+
+OUI:00071B*
+ ID_OUI_FROM_DATABASE=CDV Americas Ltd
+
+OUI:00071C*
+ ID_OUI_FROM_DATABASE=AT&T Fixed Wireless Services
+
+OUI:00071D*
+ ID_OUI_FROM_DATABASE=Satelsa Sistemas Y Aplicaciones De Telecomunicaciones, S.A.
+
+OUI:00071E*
+ ID_OUI_FROM_DATABASE=Tri-M Engineering / Nupak Dev. Corp.
+
+OUI:00071F*
+ ID_OUI_FROM_DATABASE=European Systems Integration
+
+OUI:000720*
+ ID_OUI_FROM_DATABASE=Trutzschler GmbH & Co. KG
+
+OUI:000721*
+ ID_OUI_FROM_DATABASE=Formac Elektronik GmbH
+
+OUI:000722*
+ ID_OUI_FROM_DATABASE=The Nielsen Company
+
+OUI:000723*
+ ID_OUI_FROM_DATABASE=ELCON Systemtechnik GmbH
+
+OUI:000724*
+ ID_OUI_FROM_DATABASE=Telemax Co., Ltd.
+
+OUI:000725*
+ ID_OUI_FROM_DATABASE=Bematech International Corp.
+
+OUI:000726*
+ ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co., Ltd.
+
+OUI:000727*
+ ID_OUI_FROM_DATABASE=Zi Corporation (HK) Ltd.
+
+OUI:000728*
+ ID_OUI_FROM_DATABASE=Neo Telecom
+
+OUI:000729*
+ ID_OUI_FROM_DATABASE=Kistler Instrumente AG
+
+OUI:00072A*
+ ID_OUI_FROM_DATABASE=Innovance Networks
+
+OUI:00072B*
+ ID_OUI_FROM_DATABASE=Jung Myung Telecom Co., Ltd.
+
+OUI:00072C*
+ ID_OUI_FROM_DATABASE=Fabricom
+
+OUI:00072D*
+ ID_OUI_FROM_DATABASE=CNSystems
+
+OUI:00072E*
+ ID_OUI_FROM_DATABASE=North Node AB
+
+OUI:00072F*
+ ID_OUI_FROM_DATABASE=Intransa, Inc.
+
+OUI:000730*
+ ID_OUI_FROM_DATABASE=Hutchison OPTEL Telecom Technology Co., Ltd.
+
+OUI:000731*
+ ID_OUI_FROM_DATABASE=Ophir-Spiricon Inc
+
+OUI:000732*
+ ID_OUI_FROM_DATABASE=AAEON Technology Inc.
+
+OUI:000733*
+ ID_OUI_FROM_DATABASE=DANCONTROL Engineering
+
+OUI:000734*
+ ID_OUI_FROM_DATABASE=ONStor, Inc.
+
+OUI:000735*
+ ID_OUI_FROM_DATABASE=Flarion Technologies, Inc.
+
+OUI:000736*
+ ID_OUI_FROM_DATABASE=Data Video Technologies Co., Ltd.
+
+OUI:000737*
+ ID_OUI_FROM_DATABASE=Soriya Co. Ltd.
+
+OUI:000738*
+ ID_OUI_FROM_DATABASE=Young Technology Co., Ltd.
+
+OUI:000739*
+ ID_OUI_FROM_DATABASE=Scotty Group Austria Gmbh
+
+OUI:00073A*
+ ID_OUI_FROM_DATABASE=Inventel Systemes
+
+OUI:00073B*
+ ID_OUI_FROM_DATABASE=Tenovis GmbH & Co KG
+
+OUI:00073C*
+ ID_OUI_FROM_DATABASE=Telecom Design
+
+OUI:00073D*
+ ID_OUI_FROM_DATABASE=Nanjing Postel Telecommunications Co., Ltd.
+
+OUI:00073E*
+ ID_OUI_FROM_DATABASE=China Great-Wall Computer Shenzhen Co., Ltd.
+
+OUI:00073F*
+ ID_OUI_FROM_DATABASE=Woojyun Systec Co., Ltd.
+
+OUI:000740*
+ ID_OUI_FROM_DATABASE=Buffalo, Inc
+
+OUI:000741*
+ ID_OUI_FROM_DATABASE=Sierra Automated Systems
+
+OUI:000742*
+ ID_OUI_FROM_DATABASE=Current Technologies, LLC
+
+OUI:000743*
+ ID_OUI_FROM_DATABASE=Chelsio Communications
+
+OUI:000744*
+ ID_OUI_FROM_DATABASE=Unico, Inc.
+
+OUI:000745*
+ ID_OUI_FROM_DATABASE=Radlan Computer Communications Ltd.
+
+OUI:000746*
+ ID_OUI_FROM_DATABASE=TURCK, Inc.
+
+OUI:000747*
+ ID_OUI_FROM_DATABASE=Mecalc
+
+OUI:000748*
+ ID_OUI_FROM_DATABASE=The Imaging Source Europe
+
+OUI:000749*
+ ID_OUI_FROM_DATABASE=CENiX Inc.
+
+OUI:00074A*
+ ID_OUI_FROM_DATABASE=Carl Valentin GmbH
+
+OUI:00074B*
+ ID_OUI_FROM_DATABASE=Daihen Corporation
+
+OUI:00074C*
+ ID_OUI_FROM_DATABASE=Beicom Inc.
+
+OUI:00074D*
+ ID_OUI_FROM_DATABASE=Zebra Technologies Corp.
+
+OUI:00074E*
+ ID_OUI_FROM_DATABASE=IPFRONT Inc
+
+OUI:00074F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000750*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000751*
+ ID_OUI_FROM_DATABASE=m-u-t AG
+
+OUI:000752*
+ ID_OUI_FROM_DATABASE=Rhythm Watch Co., Ltd.
+
+OUI:000753*
+ ID_OUI_FROM_DATABASE=Beijing Qxcomm Technology Co., Ltd.
+
+OUI:000754*
+ ID_OUI_FROM_DATABASE=Xyterra Computing, Inc.
+
+OUI:000755*
+ ID_OUI_FROM_DATABASE=Lafon SA
+
+OUI:000756*
+ ID_OUI_FROM_DATABASE=Juyoung Telecom
+
+OUI:000757*
+ ID_OUI_FROM_DATABASE=Topcall International AG
+
+OUI:000758*
+ ID_OUI_FROM_DATABASE=Dragonwave
+
+OUI:000759*
+ ID_OUI_FROM_DATABASE=Boris Manufacturing Corp.
+
+OUI:00075A*
+ ID_OUI_FROM_DATABASE=Air Products and Chemicals, Inc.
+
+OUI:00075B*
+ ID_OUI_FROM_DATABASE=Gibson Guitars
+
+OUI:00075C*
+ ID_OUI_FROM_DATABASE=Eastman Kodak Company
+
+OUI:00075D*
+ ID_OUI_FROM_DATABASE=Celleritas Inc.
+
+OUI:00075E*
+ ID_OUI_FROM_DATABASE=Ametek Power Instruments
+
+OUI:00075F*
+ ID_OUI_FROM_DATABASE=VCS Video Communication Systems AG
+
+OUI:000760*
+ ID_OUI_FROM_DATABASE=TOMIS Information & Telecom Corp.
+
+OUI:000761*
+ ID_OUI_FROM_DATABASE=Logitech SA
+
+OUI:000762*
+ ID_OUI_FROM_DATABASE=Group Sense Limited
+
+OUI:000763*
+ ID_OUI_FROM_DATABASE=Sunniwell Cyber Tech. Co., Ltd.
+
+OUI:000764*
+ ID_OUI_FROM_DATABASE=YoungWoo Telecom Co. Ltd.
+
+OUI:000765*
+ ID_OUI_FROM_DATABASE=Jade Quantum Technologies, Inc.
+
+OUI:000766*
+ ID_OUI_FROM_DATABASE=Chou Chin Industrial Co., Ltd.
+
+OUI:000767*
+ ID_OUI_FROM_DATABASE=Yuxing Electronics Company Limited
+
+OUI:000768*
+ ID_OUI_FROM_DATABASE=Danfoss A/S
+
+OUI:000769*
+ ID_OUI_FROM_DATABASE=Italiana Macchi SpA
+
+OUI:00076A*
+ ID_OUI_FROM_DATABASE=NEXTEYE Co., Ltd.
+
+OUI:00076B*
+ ID_OUI_FROM_DATABASE=Stralfors AB
+
+OUI:00076C*
+ ID_OUI_FROM_DATABASE=Daehanet, Inc.
+
+OUI:00076D*
+ ID_OUI_FROM_DATABASE=Flexlight Networks
+
+OUI:00076E*
+ ID_OUI_FROM_DATABASE=Sinetica Corporation Limited
+
+OUI:00076F*
+ ID_OUI_FROM_DATABASE=Synoptics Limited
+
+OUI:000770*
+ ID_OUI_FROM_DATABASE=Locusnetworks Corporation
+
+OUI:000771*
+ ID_OUI_FROM_DATABASE=Embedded System Corporation
+
+OUI:000772*
+ ID_OUI_FROM_DATABASE=Alcatel Shanghai Bell Co., Ltd.
+
+OUI:000773*
+ ID_OUI_FROM_DATABASE=Ascom Powerline Communications Ltd.
+
+OUI:000774*
+ ID_OUI_FROM_DATABASE=GuangZhou Thinker Technology Co. Ltd.
+
+OUI:000775*
+ ID_OUI_FROM_DATABASE=Valence Semiconductor, Inc.
+
+OUI:000776*
+ ID_OUI_FROM_DATABASE=Federal APD
+
+OUI:000777*
+ ID_OUI_FROM_DATABASE=Motah Ltd.
+
+OUI:000778*
+ ID_OUI_FROM_DATABASE=GERSTEL GmbH & Co. KG
+
+OUI:000779*
+ ID_OUI_FROM_DATABASE=Sungil Telecom Co., Ltd.
+
+OUI:00077A*
+ ID_OUI_FROM_DATABASE=Infoware System Co., Ltd.
+
+OUI:00077B*
+ ID_OUI_FROM_DATABASE=Millimetrix Broadband Networks
+
+OUI:00077C*
+ ID_OUI_FROM_DATABASE=Westermo Teleindustri AB
+
+OUI:00077D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00077E*
+ ID_OUI_FROM_DATABASE=Elrest GmbH
+
+OUI:00077F*
+ ID_OUI_FROM_DATABASE=J Communications Co., Ltd.
+
+OUI:000780*
+ ID_OUI_FROM_DATABASE=Bluegiga Technologies OY
+
+OUI:000781*
+ ID_OUI_FROM_DATABASE=Itron Inc.
+
+OUI:000782*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:000783*
+ ID_OUI_FROM_DATABASE=SynCom Network, Inc.
+
+OUI:000784*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000785*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000786*
+ ID_OUI_FROM_DATABASE=Wireless Networks Inc.
+
+OUI:000787*
+ ID_OUI_FROM_DATABASE=Idea System Co., Ltd.
+
+OUI:000788*
+ ID_OUI_FROM_DATABASE=Clipcomm, Inc.
+
+OUI:000789*
+ ID_OUI_FROM_DATABASE=DONGWON SYSTEMS
+
+OUI:00078A*
+ ID_OUI_FROM_DATABASE=Mentor Data System Inc.
+
+OUI:00078B*
+ ID_OUI_FROM_DATABASE=Wegener Communications, Inc.
+
+OUI:00078C*
+ ID_OUI_FROM_DATABASE=Elektronikspecialisten i Borlange AB
+
+OUI:00078D*
+ ID_OUI_FROM_DATABASE=NetEngines Ltd.
+
+OUI:00078E*
+ ID_OUI_FROM_DATABASE=Garz & Friche GmbH
+
+OUI:00078F*
+ ID_OUI_FROM_DATABASE=Emkay Innovative Products
+
+OUI:000790*
+ ID_OUI_FROM_DATABASE=Tri-M Technologies (s) Limited
+
+OUI:000791*
+ ID_OUI_FROM_DATABASE=International Data Communications, Inc.
+
+OUI:000792*
+ ID_OUI_FROM_DATABASE=Sütron Electronic GmbH
+
+OUI:000793*
+ ID_OUI_FROM_DATABASE=Shin Satellite Public Company Limited
+
+OUI:000794*
+ ID_OUI_FROM_DATABASE=Simple Devices, Inc.
+
+OUI:000795*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. (ECS)
+
+OUI:000796*
+ ID_OUI_FROM_DATABASE=LSI Systems, Inc.
+
+OUI:000797*
+ ID_OUI_FROM_DATABASE=Netpower Co., Ltd.
+
+OUI:000798*
+ ID_OUI_FROM_DATABASE=Selea SRL
+
+OUI:000799*
+ ID_OUI_FROM_DATABASE=Tipping Point Technologies, Inc.
+
+OUI:00079A*
+ ID_OUI_FROM_DATABASE=Verint Systems Inc
+
+OUI:00079B*
+ ID_OUI_FROM_DATABASE=Aurora Networks
+
+OUI:00079C*
+ ID_OUI_FROM_DATABASE=Golden Electronics Technology Co., Ltd.
+
+OUI:00079D*
+ ID_OUI_FROM_DATABASE=Musashi Co., Ltd.
+
+OUI:00079E*
+ ID_OUI_FROM_DATABASE=Ilinx Co., Ltd.
+
+OUI:00079F*
+ ID_OUI_FROM_DATABASE=Action Digital Inc.
+
+OUI:0007A0*
+ ID_OUI_FROM_DATABASE=e-Watch Inc.
+
+OUI:0007A1*
+ ID_OUI_FROM_DATABASE=VIASYS Healthcare GmbH
+
+OUI:0007A2*
+ ID_OUI_FROM_DATABASE=Opteon Corporation
+
+OUI:0007A3*
+ ID_OUI_FROM_DATABASE=Ositis Software, Inc.
+
+OUI:0007A4*
+ ID_OUI_FROM_DATABASE=GN Netcom Ltd.
+
+OUI:0007A5*
+ ID_OUI_FROM_DATABASE=Y.D.K Co. Ltd.
+
+OUI:0007A6*
+ ID_OUI_FROM_DATABASE=Home Automation, Inc.
+
+OUI:0007A7*
+ ID_OUI_FROM_DATABASE=A-Z Inc.
+
+OUI:0007A8*
+ ID_OUI_FROM_DATABASE=Haier Group Technologies Ltd.
+
+OUI:0007A9*
+ ID_OUI_FROM_DATABASE=Novasonics
+
+OUI:0007AA*
+ ID_OUI_FROM_DATABASE=Quantum Data Inc.
+
+OUI:0007AB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0007AC*
+ ID_OUI_FROM_DATABASE=Eolring
+
+OUI:0007AD*
+ ID_OUI_FROM_DATABASE=Pentacon GmbH Foto-und Feinwerktechnik
+
+OUI:0007AE*
+ ID_OUI_FROM_DATABASE=Britestream Networks, Inc.
+
+OUI:0007AF*
+ ID_OUI_FROM_DATABASE=N-TRON Corporation
+
+OUI:0007B0*
+ ID_OUI_FROM_DATABASE=Office Details, Inc.
+
+OUI:0007B1*
+ ID_OUI_FROM_DATABASE=Equator Technologies
+
+OUI:0007B2*
+ ID_OUI_FROM_DATABASE=Transaccess S.A.
+
+OUI:0007B3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0007B4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0007B5*
+ ID_OUI_FROM_DATABASE=Any One Wireless Ltd.
+
+OUI:0007B6*
+ ID_OUI_FROM_DATABASE=Telecom Technology Ltd.
+
+OUI:0007B7*
+ ID_OUI_FROM_DATABASE=Samurai Ind. Prods Eletronicos Ltda
+
+OUI:0007B8*
+ ID_OUI_FROM_DATABASE=Corvalent Corporation
+
+OUI:0007B9*
+ ID_OUI_FROM_DATABASE=Ginganet Corporation
+
+OUI:0007BA*
+ ID_OUI_FROM_DATABASE=UTStarcom, Inc.
+
+OUI:0007BB*
+ ID_OUI_FROM_DATABASE=Candera Inc.
+
+OUI:0007BC*
+ ID_OUI_FROM_DATABASE=Identix Inc.
+
+OUI:0007BD*
+ ID_OUI_FROM_DATABASE=Radionet Ltd.
+
+OUI:0007BE*
+ ID_OUI_FROM_DATABASE=DataLogic SpA
+
+OUI:0007BF*
+ ID_OUI_FROM_DATABASE=Armillaire Technologies, Inc.
+
+OUI:0007C0*
+ ID_OUI_FROM_DATABASE=NetZerver Inc.
+
+OUI:0007C1*
+ ID_OUI_FROM_DATABASE=Overture Networks, Inc.
+
+OUI:0007C2*
+ ID_OUI_FROM_DATABASE=Netsys Telecom
+
+OUI:0007C3*
+ ID_OUI_FROM_DATABASE=Thomson
+
+OUI:0007C4*
+ ID_OUI_FROM_DATABASE=JEAN Co. Ltd.
+
+OUI:0007C5*
+ ID_OUI_FROM_DATABASE=Gcom, Inc.
+
+OUI:0007C6*
+ ID_OUI_FROM_DATABASE=VDS Vosskuhler GmbH
+
+OUI:0007C7*
+ ID_OUI_FROM_DATABASE=Synectics Systems Limited
+
+OUI:0007C8*
+ ID_OUI_FROM_DATABASE=Brain21, Inc.
+
+OUI:0007C9*
+ ID_OUI_FROM_DATABASE=Technol Seven Co., Ltd.
+
+OUI:0007CA*
+ ID_OUI_FROM_DATABASE=Creatix Polymedia Ges Fur Kommunikaitonssysteme
+
+OUI:0007CB*
+ ID_OUI_FROM_DATABASE=Freebox SA
+
+OUI:0007CC*
+ ID_OUI_FROM_DATABASE=Kaba Benzing GmbH
+
+OUI:0007CD*
+ ID_OUI_FROM_DATABASE=NMTEL Co., Ltd.
+
+OUI:0007CE*
+ ID_OUI_FROM_DATABASE=Cabletime Limited
+
+OUI:0007CF*
+ ID_OUI_FROM_DATABASE=Anoto AB
+
+OUI:0007D0*
+ ID_OUI_FROM_DATABASE=Automat Engenharia de Automação Ltda.
+
+OUI:0007D1*
+ ID_OUI_FROM_DATABASE=Spectrum Signal Processing Inc.
+
+OUI:0007D2*
+ ID_OUI_FROM_DATABASE=Logopak Systeme
+
+OUI:0007D3*
+ ID_OUI_FROM_DATABASE=Stork Prints B.V.
+
+OUI:0007D4*
+ ID_OUI_FROM_DATABASE=Zhejiang Yutong Network Communication Co Ltd.
+
+OUI:0007D5*
+ ID_OUI_FROM_DATABASE=3e Technologies Int;., Inc.
+
+OUI:0007D6*
+ ID_OUI_FROM_DATABASE=Commil Ltd.
+
+OUI:0007D7*
+ ID_OUI_FROM_DATABASE=Caporis Networks AG
+
+OUI:0007D8*
+ ID_OUI_FROM_DATABASE=Hitron Systems Inc.
+
+OUI:0007D9*
+ ID_OUI_FROM_DATABASE=Splicecom
+
+OUI:0007DA*
+ ID_OUI_FROM_DATABASE=Neuro Telecom Co., Ltd.
+
+OUI:0007DB*
+ ID_OUI_FROM_DATABASE=Kirana Networks, Inc.
+
+OUI:0007DC*
+ ID_OUI_FROM_DATABASE=Atek Co, Ltd.
+
+OUI:0007DD*
+ ID_OUI_FROM_DATABASE=Cradle Technologies
+
+OUI:0007DE*
+ ID_OUI_FROM_DATABASE=eCopilt AB
+
+OUI:0007DF*
+ ID_OUI_FROM_DATABASE=Vbrick Systems Inc.
+
+OUI:0007E0*
+ ID_OUI_FROM_DATABASE=Palm Inc.
+
+OUI:0007E1*
+ ID_OUI_FROM_DATABASE=WIS Communications Co. Ltd.
+
+OUI:0007E2*
+ ID_OUI_FROM_DATABASE=Bitworks, Inc.
+
+OUI:0007E3*
+ ID_OUI_FROM_DATABASE=Navcom Technology, Inc.
+
+OUI:0007E4*
+ ID_OUI_FROM_DATABASE=SoftRadio Co., Ltd.
+
+OUI:0007E5*
+ ID_OUI_FROM_DATABASE=Coup Corporation
+
+OUI:0007E6*
+ ID_OUI_FROM_DATABASE=edgeflow Canada Inc.
+
+OUI:0007E7*
+ ID_OUI_FROM_DATABASE=FreeWave Technologies
+
+OUI:0007E8*
+ ID_OUI_FROM_DATABASE=EdgeWave
+
+OUI:0007E9*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0007EA*
+ ID_OUI_FROM_DATABASE=Massana, Inc.
+
+OUI:0007EB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0007EC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0007ED*
+ ID_OUI_FROM_DATABASE=Altera Corporation
+
+OUI:0007EE*
+ ID_OUI_FROM_DATABASE=telco Informationssysteme GmbH
+
+OUI:0007EF*
+ ID_OUI_FROM_DATABASE=Lockheed Martin Tactical Systems
+
+OUI:0007F0*
+ ID_OUI_FROM_DATABASE=LogiSync LLC
+
+OUI:0007F1*
+ ID_OUI_FROM_DATABASE=TeraBurst Networks Inc.
+
+OUI:0007F2*
+ ID_OUI_FROM_DATABASE=IOA Corporation
+
+OUI:0007F3*
+ ID_OUI_FROM_DATABASE=Thinkengine Networks
+
+OUI:0007F4*
+ ID_OUI_FROM_DATABASE=Eletex Co., Ltd.
+
+OUI:0007F5*
+ ID_OUI_FROM_DATABASE=Bridgeco Co AG
+
+OUI:0007F6*
+ ID_OUI_FROM_DATABASE=Qqest Software Systems
+
+OUI:0007F7*
+ ID_OUI_FROM_DATABASE=Galtronics
+
+OUI:0007F8*
+ ID_OUI_FROM_DATABASE=ITDevices, Inc.
+
+OUI:0007F9*
+ ID_OUI_FROM_DATABASE=Phonetics, Inc.
+
+OUI:0007FA*
+ ID_OUI_FROM_DATABASE=ITT Co., Ltd.
+
+OUI:0007FB*
+ ID_OUI_FROM_DATABASE=Giga Stream UMTS Technologies GmbH
+
+OUI:0007FC*
+ ID_OUI_FROM_DATABASE=Adept Systems Inc.
+
+OUI:0007FD*
+ ID_OUI_FROM_DATABASE=LANergy Ltd.
+
+OUI:0007FE*
+ ID_OUI_FROM_DATABASE=Rigaku Corporation
+
+OUI:0007FF*
+ ID_OUI_FROM_DATABASE=Gluon Networks
+
+OUI:000800*
+ ID_OUI_FROM_DATABASE=MULTITECH SYSTEMS, INC.
+
+OUI:000801*
+ ID_OUI_FROM_DATABASE=HighSpeed Surfing Inc.
+
+OUI:000802*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:000803*
+ ID_OUI_FROM_DATABASE=Cos Tron
+
+OUI:000804*
+ ID_OUI_FROM_DATABASE=ICA Inc.
+
+OUI:000805*
+ ID_OUI_FROM_DATABASE=Techno-Holon Corporation
+
+OUI:000806*
+ ID_OUI_FROM_DATABASE=Raonet Systems, Inc.
+
+OUI:000807*
+ ID_OUI_FROM_DATABASE=Access Devices Limited
+
+OUI:000808*
+ ID_OUI_FROM_DATABASE=PPT Vision, Inc.
+
+OUI:000809*
+ ID_OUI_FROM_DATABASE=Systemonic AG
+
+OUI:00080A*
+ ID_OUI_FROM_DATABASE=Espera-Werke GmbH
+
+OUI:00080B*
+ ID_OUI_FROM_DATABASE=Birka BPA Informationssystem AB
+
+OUI:00080C*
+ ID_OUI_FROM_DATABASE=VDA Elettronica spa
+
+OUI:00080D*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:00080E*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00080F*
+ ID_OUI_FROM_DATABASE=Proximion Fiber Optics AB
+
+OUI:000810*
+ ID_OUI_FROM_DATABASE=Key Technology, Inc.
+
+OUI:000811*
+ ID_OUI_FROM_DATABASE=VOIX Corporation
+
+OUI:000812*
+ ID_OUI_FROM_DATABASE=GM-2 Corporation
+
+OUI:000813*
+ ID_OUI_FROM_DATABASE=Diskbank, Inc.
+
+OUI:000814*
+ ID_OUI_FROM_DATABASE=TIL Technologies
+
+OUI:000815*
+ ID_OUI_FROM_DATABASE=CATS Co., Ltd.
+
+OUI:000816*
+ ID_OUI_FROM_DATABASE=Bluetags A/S
+
+OUI:000817*
+ ID_OUI_FROM_DATABASE=EmergeCore Networks LLC
+
+OUI:000818*
+ ID_OUI_FROM_DATABASE=Pixelworks, Inc.
+
+OUI:000819*
+ ID_OUI_FROM_DATABASE=Banksys
+
+OUI:00081A*
+ ID_OUI_FROM_DATABASE=Sanrad Intelligence Storage Communications (2000) Ltd.
+
+OUI:00081B*
+ ID_OUI_FROM_DATABASE=Windigo Systems
+
+OUI:00081C*
+ ID_OUI_FROM_DATABASE=@pos.com
+
+OUI:00081D*
+ ID_OUI_FROM_DATABASE=Ipsil, Incorporated
+
+OUI:00081E*
+ ID_OUI_FROM_DATABASE=Repeatit AB
+
+OUI:00081F*
+ ID_OUI_FROM_DATABASE=Pou Yuen Tech Corp. Ltd.
+
+OUI:000820*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000821*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000822*
+ ID_OUI_FROM_DATABASE=InPro Comm
+
+OUI:000823*
+ ID_OUI_FROM_DATABASE=Texa Corp.
+
+OUI:000824*
+ ID_OUI_FROM_DATABASE=Copitrak Inc
+
+OUI:000825*
+ ID_OUI_FROM_DATABASE=Acme Packet
+
+OUI:000826*
+ ID_OUI_FROM_DATABASE=Colorado Med Tech
+
+OUI:000827*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:000828*
+ ID_OUI_FROM_DATABASE=Koei Engineering Ltd.
+
+OUI:000829*
+ ID_OUI_FROM_DATABASE=Aval Nagasaki Corporation
+
+OUI:00082A*
+ ID_OUI_FROM_DATABASE=Powerwallz Network Security
+
+OUI:00082B*
+ ID_OUI_FROM_DATABASE=Wooksung Electronics, Inc.
+
+OUI:00082C*
+ ID_OUI_FROM_DATABASE=Homag AG
+
+OUI:00082D*
+ ID_OUI_FROM_DATABASE=Indus Teqsite Private Limited
+
+OUI:00082E*
+ ID_OUI_FROM_DATABASE=Multitone Electronics PLC
+
+OUI:00082F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000830*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000831*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000832*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:00084E*
+ ID_OUI_FROM_DATABASE=DivergeNet, Inc.
+
+OUI:00084F*
+ ID_OUI_FROM_DATABASE=Qualstar Corporation
+
+OUI:000850*
+ ID_OUI_FROM_DATABASE=Arizona Instrument Corp.
+
+OUI:000851*
+ ID_OUI_FROM_DATABASE=Canadian Bank Note Company, Ltd.
+
+OUI:000852*
+ ID_OUI_FROM_DATABASE=Davolink Co. Inc.
+
+OUI:000853*
+ ID_OUI_FROM_DATABASE=Schleicher GmbH & Co. Relaiswerke KG
+
+OUI:000854*
+ ID_OUI_FROM_DATABASE=Netronix, Inc.
+
+OUI:000855*
+ ID_OUI_FROM_DATABASE=NASA-Goddard Space Flight Center
+
+OUI:000856*
+ ID_OUI_FROM_DATABASE=Gamatronic Electronic Industries Ltd.
+
+OUI:000857*
+ ID_OUI_FROM_DATABASE=Polaris Networks, Inc.
+
+OUI:000858*
+ ID_OUI_FROM_DATABASE=Novatechnology Inc.
+
+OUI:000859*
+ ID_OUI_FROM_DATABASE=ShenZhen Unitone Electronics Co., Ltd.
+
+OUI:00085A*
+ ID_OUI_FROM_DATABASE=IntiGate Inc.
+
+OUI:00085B*
+ ID_OUI_FROM_DATABASE=Hanbit Electronics Co., Ltd.
+
+OUI:00085C*
+ ID_OUI_FROM_DATABASE=Shanghai Dare Technologies Co. Ltd.
+
+OUI:00085D*
+ ID_OUI_FROM_DATABASE=Aastra
+
+OUI:00085E*
+ ID_OUI_FROM_DATABASE=PCO AG
+
+OUI:00085F*
+ ID_OUI_FROM_DATABASE=Picanol N.V.
+
+OUI:000860*
+ ID_OUI_FROM_DATABASE=LodgeNet Entertainment Corp.
+
+OUI:000861*
+ ID_OUI_FROM_DATABASE=SoftEnergy Co., Ltd.
+
+OUI:000862*
+ ID_OUI_FROM_DATABASE=NEC Eluminant Technologies, Inc.
+
+OUI:000863*
+ ID_OUI_FROM_DATABASE=Entrisphere Inc.
+
+OUI:000864*
+ ID_OUI_FROM_DATABASE=Fasy S.p.A.
+
+OUI:000865*
+ ID_OUI_FROM_DATABASE=JASCOM CO., LTD
+
+OUI:000866*
+ ID_OUI_FROM_DATABASE=DSX Access Systems, Inc.
+
+OUI:000867*
+ ID_OUI_FROM_DATABASE=Uptime Devices
+
+OUI:000868*
+ ID_OUI_FROM_DATABASE=PurOptix
+
+OUI:000869*
+ ID_OUI_FROM_DATABASE=Command-e Technology Co.,Ltd.
+
+OUI:00086A*
+ ID_OUI_FROM_DATABASE=Securiton Gmbh
+
+OUI:00086B*
+ ID_OUI_FROM_DATABASE=MIPSYS
+
+OUI:00086C*
+ ID_OUI_FROM_DATABASE=Plasmon LMS
+
+OUI:00086D*
+ ID_OUI_FROM_DATABASE=Missouri FreeNet
+
+OUI:00086E*
+ ID_OUI_FROM_DATABASE=Hyglo AB
+
+OUI:00086F*
+ ID_OUI_FROM_DATABASE=Resources Computer Network Ltd.
+
+OUI:000870*
+ ID_OUI_FROM_DATABASE=Rasvia Systems, Inc.
+
+OUI:000871*
+ ID_OUI_FROM_DATABASE=NORTHDATA Co., Ltd.
+
+OUI:000872*
+ ID_OUI_FROM_DATABASE=Sorenson Communications
+
+OUI:000873*
+ ID_OUI_FROM_DATABASE=DapTechnology B.V.
+
+OUI:000874*
+ ID_OUI_FROM_DATABASE=Dell Computer Corp.
+
+OUI:000875*
+ ID_OUI_FROM_DATABASE=Acorp Electronics Corp.
+
+OUI:000876*
+ ID_OUI_FROM_DATABASE=SDSystem
+
+OUI:000877*
+ ID_OUI_FROM_DATABASE=Liebert-Hiross Spa
+
+OUI:000878*
+ ID_OUI_FROM_DATABASE=Benchmark Storage Innovations
+
+OUI:000879*
+ ID_OUI_FROM_DATABASE=CEM Corporation
+
+OUI:00087A*
+ ID_OUI_FROM_DATABASE=Wipotec GmbH
+
+OUI:00087B*
+ ID_OUI_FROM_DATABASE=RTX Telecom A/S
+
+OUI:00087C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00087D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00087E*
+ ID_OUI_FROM_DATABASE=Bon Electro-Telecom Inc.
+
+OUI:00087F*
+ ID_OUI_FROM_DATABASE=SPAUN electronic GmbH & Co. KG
+
+OUI:000880*
+ ID_OUI_FROM_DATABASE=BroadTel Canada Communications inc.
+
+OUI:000881*
+ ID_OUI_FROM_DATABASE=DIGITAL HANDS CO.,LTD.
+
+OUI:000882*
+ ID_OUI_FROM_DATABASE=SIGMA CORPORATION
+
+OUI:000883*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:000884*
+ ID_OUI_FROM_DATABASE=Index Braille AB
+
+OUI:000885*
+ ID_OUI_FROM_DATABASE=EMS Dr. Thomas Wünsche
+
+OUI:000886*
+ ID_OUI_FROM_DATABASE=Hansung Teliann, Inc.
+
+OUI:000887*
+ ID_OUI_FROM_DATABASE=Maschinenfabrik Reinhausen GmbH
+
+OUI:000888*
+ ID_OUI_FROM_DATABASE=OULLIM Information Technology Inc,.
+
+OUI:000889*
+ ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+
+OUI:00088A*
+ ID_OUI_FROM_DATABASE=Minds@Work
+
+OUI:00088B*
+ ID_OUI_FROM_DATABASE=Tropic Networks Inc.
+
+OUI:00088C*
+ ID_OUI_FROM_DATABASE=Quanta Network Systems Inc.
+
+OUI:00088D*
+ ID_OUI_FROM_DATABASE=Sigma-Links Inc.
+
+OUI:00088E*
+ ID_OUI_FROM_DATABASE=Nihon Computer Co., Ltd.
+
+OUI:00088F*
+ ID_OUI_FROM_DATABASE=ADVANCED DIGITAL TECHNOLOGY
+
+OUI:000890*
+ ID_OUI_FROM_DATABASE=AVILINKS SA
+
+OUI:000891*
+ ID_OUI_FROM_DATABASE=Lyan Inc.
+
+OUI:000892*
+ ID_OUI_FROM_DATABASE=EM Solutions
+
+OUI:000893*
+ ID_OUI_FROM_DATABASE=LE INFORMATION COMMUNICATION INC.
+
+OUI:000894*
+ ID_OUI_FROM_DATABASE=InnoVISION Multimedia Ltd.
+
+OUI:000895*
+ ID_OUI_FROM_DATABASE=DIRC Technologie GmbH & Co.KG
+
+OUI:000896*
+ ID_OUI_FROM_DATABASE=Printronix, Inc.
+
+OUI:000897*
+ ID_OUI_FROM_DATABASE=Quake Technologies
+
+OUI:000898*
+ ID_OUI_FROM_DATABASE=Gigabit Optics Corporation
+
+OUI:000899*
+ ID_OUI_FROM_DATABASE=Netbind, Inc.
+
+OUI:00089A*
+ ID_OUI_FROM_DATABASE=Alcatel Microelectronics
+
+OUI:00089B*
+ ID_OUI_FROM_DATABASE=ICP Electronics Inc.
+
+OUI:00089C*
+ ID_OUI_FROM_DATABASE=Elecs Industry Co., Ltd.
+
+OUI:00089D*
+ ID_OUI_FROM_DATABASE=UHD-Elektronik
+
+OUI:00089E*
+ ID_OUI_FROM_DATABASE=Beijing Enter-Net co.LTD
+
+OUI:00089F*
+ ID_OUI_FROM_DATABASE=EFM Networks
+
+OUI:0008A0*
+ ID_OUI_FROM_DATABASE=Stotz Feinmesstechnik GmbH
+
+OUI:0008A1*
+ ID_OUI_FROM_DATABASE=CNet Technology Inc.
+
+OUI:0008A2*
+ ID_OUI_FROM_DATABASE=ADI Engineering, Inc.
+
+OUI:0008A3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0008A4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0008A5*
+ ID_OUI_FROM_DATABASE=Peninsula Systems Inc.
+
+OUI:0008A6*
+ ID_OUI_FROM_DATABASE=Multiware & Image Co., Ltd.
+
+OUI:0008A7*
+ ID_OUI_FROM_DATABASE=iLogic Inc.
+
+OUI:0008A8*
+ ID_OUI_FROM_DATABASE=Systec Co., Ltd.
+
+OUI:0008A9*
+ ID_OUI_FROM_DATABASE=SangSang Technology, Inc.
+
+OUI:0008AA*
+ ID_OUI_FROM_DATABASE=KARAM
+
+OUI:0008AB*
+ ID_OUI_FROM_DATABASE=EnerLinx.com, Inc.
+
+OUI:0008AC*
+ ID_OUI_FROM_DATABASE=Eltromat GmbH
+
+OUI:0008AD*
+ ID_OUI_FROM_DATABASE=Toyo-Linx Co., Ltd.
+
+OUI:0008AE*
+ ID_OUI_FROM_DATABASE=PacketFront International AB
+
+OUI:0008AF*
+ ID_OUI_FROM_DATABASE=Novatec Corporation
+
+OUI:0008B0*
+ ID_OUI_FROM_DATABASE=BKtel communications GmbH
+
+OUI:0008B1*
+ ID_OUI_FROM_DATABASE=ProQuent Systems
+
+OUI:0008B2*
+ ID_OUI_FROM_DATABASE=SHENZHEN COMPASS TECHNOLOGY DEVELOPMENT CO.,LTD
+
+OUI:0008B3*
+ ID_OUI_FROM_DATABASE=Fastwel
+
+OUI:0008B4*
+ ID_OUI_FROM_DATABASE=SYSPOL
+
+OUI:0008B5*
+ ID_OUI_FROM_DATABASE=TAI GUEN ENTERPRISE CO., LTD
+
+OUI:0008B6*
+ ID_OUI_FROM_DATABASE=RouteFree, Inc.
+
+OUI:0008B7*
+ ID_OUI_FROM_DATABASE=HIT Incorporated
+
+OUI:0008B8*
+ ID_OUI_FROM_DATABASE=E.F. Johnson
+
+OUI:0008B9*
+ ID_OUI_FROM_DATABASE=KAON MEDIA Co., Ltd.
+
+OUI:0008BA*
+ ID_OUI_FROM_DATABASE=Erskine Systems Ltd
+
+OUI:0008BB*
+ ID_OUI_FROM_DATABASE=NetExcell
+
+OUI:0008BC*
+ ID_OUI_FROM_DATABASE=Ilevo AB
+
+OUI:0008BD*
+ ID_OUI_FROM_DATABASE=TEPG-US
+
+OUI:0008BE*
+ ID_OUI_FROM_DATABASE=XENPAK MSA Group
+
+OUI:0008BF*
+ ID_OUI_FROM_DATABASE=Aptus Elektronik AB
+
+OUI:0008C0*
+ ID_OUI_FROM_DATABASE=ASA SYSTEMS
+
+OUI:0008C1*
+ ID_OUI_FROM_DATABASE=Avistar Communications Corporation
+
+OUI:0008C2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0008C3*
+ ID_OUI_FROM_DATABASE=Contex A/S
+
+OUI:0008C4*
+ ID_OUI_FROM_DATABASE=Hikari Co.,Ltd.
+
+OUI:0008C5*
+ ID_OUI_FROM_DATABASE=Liontech Co., Ltd.
+
+OUI:0008C6*
+ ID_OUI_FROM_DATABASE=Philips Consumer Communications
+
+OUI:0008C7*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0008C8*
+ ID_OUI_FROM_DATABASE=Soneticom, Inc.
+
+OUI:0008C9*
+ ID_OUI_FROM_DATABASE=TechniSat Digital GmbH
+
+OUI:0008CA*
+ ID_OUI_FROM_DATABASE=TwinHan Technology Co.,Ltd
+
+OUI:0008CB*
+ ID_OUI_FROM_DATABASE=Zeta Broadband Inc.
+
+OUI:0008CC*
+ ID_OUI_FROM_DATABASE=Remotec, Inc.
+
+OUI:0008CD*
+ ID_OUI_FROM_DATABASE=With-Net Inc
+
+OUI:0008CE*
+ ID_OUI_FROM_DATABASE=IPMobileNet Inc.
+
+OUI:0008CF*
+ ID_OUI_FROM_DATABASE=Nippon Koei Power Systems Co., Ltd.
+
+OUI:0008D0*
+ ID_OUI_FROM_DATABASE=Musashi Engineering Co., LTD.
+
+OUI:0008D1*
+ ID_OUI_FROM_DATABASE=KAREL INC.
+
+OUI:0008D2*
+ ID_OUI_FROM_DATABASE=ZOOM Networks Inc.
+
+OUI:0008D3*
+ ID_OUI_FROM_DATABASE=Hercules Technologies S.A.
+
+OUI:0008D4*
+ ID_OUI_FROM_DATABASE=IneoQuest Technologies, Inc
+
+OUI:0008D5*
+ ID_OUI_FROM_DATABASE=Vanguard Networks Solutions, LLC
+
+OUI:0008D6*
+ ID_OUI_FROM_DATABASE=HASSNET Inc.
+
+OUI:0008D7*
+ ID_OUI_FROM_DATABASE=HOW CORPORATION
+
+OUI:0008D8*
+ ID_OUI_FROM_DATABASE=Dowkey Microwave
+
+OUI:0008D9*
+ ID_OUI_FROM_DATABASE=Mitadenshi Co.,LTD
+
+OUI:0008DA*
+ ID_OUI_FROM_DATABASE=SofaWare Technologies Ltd.
+
+OUI:0008DB*
+ ID_OUI_FROM_DATABASE=Corrigent Systems
+
+OUI:0008DC*
+ ID_OUI_FROM_DATABASE=Wiznet
+
+OUI:0008DD*
+ ID_OUI_FROM_DATABASE=Telena Communications, Inc.
+
+OUI:0008DE*
+ ID_OUI_FROM_DATABASE=3UP Systems
+
+OUI:0008DF*
+ ID_OUI_FROM_DATABASE=Alistel Inc.
+
+OUI:0008E0*
+ ID_OUI_FROM_DATABASE=ATO Technology Ltd.
+
+OUI:0008E1*
+ ID_OUI_FROM_DATABASE=Barix AG
+
+OUI:0008E2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0008E3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0008E4*
+ ID_OUI_FROM_DATABASE=Envenergy Inc
+
+OUI:0008E5*
+ ID_OUI_FROM_DATABASE=IDK Corporation
+
+OUI:0008E6*
+ ID_OUI_FROM_DATABASE=Littlefeet
+
+OUI:0008E7*
+ ID_OUI_FROM_DATABASE=SHI ControlSystems,Ltd.
+
+OUI:0008E8*
+ ID_OUI_FROM_DATABASE=Excel Master Ltd.
+
+OUI:0008E9*
+ ID_OUI_FROM_DATABASE=NextGig
+
+OUI:0008EA*
+ ID_OUI_FROM_DATABASE=Motion Control Engineering, Inc
+
+OUI:0008EB*
+ ID_OUI_FROM_DATABASE=ROMWin Co.,Ltd.
+
+OUI:0008EC*
+ ID_OUI_FROM_DATABASE=Optical Zonu Corporation
+
+OUI:0008ED*
+ ID_OUI_FROM_DATABASE=ST&T Instrument Corp.
+
+OUI:0008EE*
+ ID_OUI_FROM_DATABASE=Logic Product Development
+
+OUI:0008EF*
+ ID_OUI_FROM_DATABASE=DIBAL,S.A.
+
+OUI:0008F0*
+ ID_OUI_FROM_DATABASE=Next Generation Systems, Inc.
+
+OUI:0008F1*
+ ID_OUI_FROM_DATABASE=Voltaire
+
+OUI:0008F2*
+ ID_OUI_FROM_DATABASE=C&S Technology
+
+OUI:0008F3*
+ ID_OUI_FROM_DATABASE=WANY
+
+OUI:0008F4*
+ ID_OUI_FROM_DATABASE=Bluetake Technology Co., Ltd.
+
+OUI:0008F5*
+ ID_OUI_FROM_DATABASE=YESTECHNOLOGY Co.,Ltd.
+
+OUI:0008F6*
+ ID_OUI_FROM_DATABASE=Sumitomo Electric System Solutions Co.,Ltd.
+
+OUI:0008F7*
+ ID_OUI_FROM_DATABASE=Hitachi Ltd, Semiconductor & Integrated Circuits Gr
+
+OUI:0008F8*
+ ID_OUI_FROM_DATABASE=UTC CCS
+
+OUI:0008F9*
+ ID_OUI_FROM_DATABASE=Emerson Network Power
+
+OUI:0008FA*
+ ID_OUI_FROM_DATABASE=Karl E.Brinkmann GmbH
+
+OUI:0008FB*
+ ID_OUI_FROM_DATABASE=SonoSite, Inc.
+
+OUI:0008FC*
+ ID_OUI_FROM_DATABASE=Gigaphoton Inc.
+
+OUI:0008FD*
+ ID_OUI_FROM_DATABASE=BlueKorea Co., Ltd.
+
+OUI:0008FE*
+ ID_OUI_FROM_DATABASE=UNIK C&C Co.,Ltd.
+
+OUI:0008FF*
+ ID_OUI_FROM_DATABASE=Trilogy Communications Ltd
+
+OUI:000900*
+ ID_OUI_FROM_DATABASE=TMT
+
+OUI:000901*
+ ID_OUI_FROM_DATABASE=Shenzhen Shixuntong Information & Technoligy Co
+
+OUI:000902*
+ ID_OUI_FROM_DATABASE=Redline Communications Inc.
+
+OUI:000903*
+ ID_OUI_FROM_DATABASE=Panasas, Inc
+
+OUI:000904*
+ ID_OUI_FROM_DATABASE=MONDIAL electronic
+
+OUI:000905*
+ ID_OUI_FROM_DATABASE=iTEC Technologies Ltd.
+
+OUI:000906*
+ ID_OUI_FROM_DATABASE=Esteem Networks
+
+OUI:000907*
+ ID_OUI_FROM_DATABASE=Chrysalis Development
+
+OUI:000908*
+ ID_OUI_FROM_DATABASE=VTech Technology Corp.
+
+OUI:000909*
+ ID_OUI_FROM_DATABASE=Telenor Connect A/S
+
+OUI:00090A*
+ ID_OUI_FROM_DATABASE=SnedFar Technology Co., Ltd.
+
+OUI:00090B*
+ ID_OUI_FROM_DATABASE=MTL  Instruments PLC
+
+OUI:00090C*
+ ID_OUI_FROM_DATABASE=Mayekawa Mfg. Co. Ltd.
+
+OUI:00090D*
+ ID_OUI_FROM_DATABASE=LEADER ELECTRONICS CORP.
+
+OUI:00090E*
+ ID_OUI_FROM_DATABASE=Helix Technology Inc.
+
+OUI:00090F*
+ ID_OUI_FROM_DATABASE=Fortinet Inc.
+
+OUI:000910*
+ ID_OUI_FROM_DATABASE=Simple Access Inc.
+
+OUI:000911*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000912*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000913*
+ ID_OUI_FROM_DATABASE=SystemK Corporation
+
+OUI:000914*
+ ID_OUI_FROM_DATABASE=COMPUTROLS INC.
+
+OUI:000915*
+ ID_OUI_FROM_DATABASE=CAS Corp.
+
+OUI:000916*
+ ID_OUI_FROM_DATABASE=Listman Home Technologies, Inc.
+
+OUI:000917*
+ ID_OUI_FROM_DATABASE=WEM Technology Inc
+
+OUI:000918*
+ ID_OUI_FROM_DATABASE=SAMSUNG TECHWIN CO.,LTD
+
+OUI:000919*
+ ID_OUI_FROM_DATABASE=MDS Gateways
+
+OUI:00091A*
+ ID_OUI_FROM_DATABASE=Macat Optics & Electronics Co., Ltd.
+
+OUI:00091B*
+ ID_OUI_FROM_DATABASE=Digital Generation Inc.
+
+OUI:00091C*
+ ID_OUI_FROM_DATABASE=CacheVision, Inc
+
+OUI:00091D*
+ ID_OUI_FROM_DATABASE=Proteam Computer Corporation
+
+OUI:00091E*
+ ID_OUI_FROM_DATABASE=Firstech Technology Corp.
+
+OUI:00091F*
+ ID_OUI_FROM_DATABASE=A&D Co., Ltd.
+
+OUI:000920*
+ ID_OUI_FROM_DATABASE=EpoX COMPUTER CO.,LTD.
+
+OUI:000921*
+ ID_OUI_FROM_DATABASE=Planmeca Oy
+
+OUI:000922*
+ ID_OUI_FROM_DATABASE=TST Biometrics GmbH
+
+OUI:000923*
+ ID_OUI_FROM_DATABASE=Heaman System Co., Ltd
+
+OUI:000924*
+ ID_OUI_FROM_DATABASE=Telebau GmbH
+
+OUI:000925*
+ ID_OUI_FROM_DATABASE=VSN Systemen BV
+
+OUI:000926*
+ ID_OUI_FROM_DATABASE=YODA COMMUNICATIONS, INC.
+
+OUI:000927*
+ ID_OUI_FROM_DATABASE=TOYOKEIKI CO.,LTD.
+
+OUI:000928*
+ ID_OUI_FROM_DATABASE=Telecore
+
+OUI:000929*
+ ID_OUI_FROM_DATABASE=Sanyo Industries (UK) Limited
+
+OUI:00092A*
+ ID_OUI_FROM_DATABASE=MYTECS Co.,Ltd.
+
+OUI:00092B*
+ ID_OUI_FROM_DATABASE=iQstor Networks, Inc.
+
+OUI:00092C*
+ ID_OUI_FROM_DATABASE=Hitpoint Inc.
+
+OUI:00092D*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:00092E*
+ ID_OUI_FROM_DATABASE=B&Tech System Inc.
+
+OUI:00092F*
+ ID_OUI_FROM_DATABASE=Akom Technology Corporation
+
+OUI:000930*
+ ID_OUI_FROM_DATABASE=AeroConcierge Inc.
+
+OUI:000931*
+ ID_OUI_FROM_DATABASE=Future Internet, Inc.
+
+OUI:000932*
+ ID_OUI_FROM_DATABASE=Omnilux
+
+OUI:000933*
+ ID_OUI_FROM_DATABASE=Ophit Co.Ltd.
+
+OUI:000934*
+ ID_OUI_FROM_DATABASE=Dream-Multimedia-Tv GmbH
+
+OUI:000935*
+ ID_OUI_FROM_DATABASE=Sandvine Incorporated
+
+OUI:000936*
+ ID_OUI_FROM_DATABASE=Ipetronik GmbH & Co.KG
+
+OUI:000937*
+ ID_OUI_FROM_DATABASE=Inventec Appliance Corp
+
+OUI:000938*
+ ID_OUI_FROM_DATABASE=Allot Communications
+
+OUI:000939*
+ ID_OUI_FROM_DATABASE=ShibaSoku Co.,Ltd.
+
+OUI:00093A*
+ ID_OUI_FROM_DATABASE=Molex Fiber Optics
+
+OUI:00093B*
+ ID_OUI_FROM_DATABASE=HYUNDAI NETWORKS INC.
+
+OUI:00093C*
+ ID_OUI_FROM_DATABASE=Jacques Technologies P/L
+
+OUI:00093D*
+ ID_OUI_FROM_DATABASE=Newisys,Inc.
+
+OUI:00093E*
+ ID_OUI_FROM_DATABASE=C&I Technologies
+
+OUI:00093F*
+ ID_OUI_FROM_DATABASE=Double-Win Enterpirse CO., LTD
+
+OUI:000940*
+ ID_OUI_FROM_DATABASE=AGFEO GmbH & Co. KG
+
+OUI:000941*
+ ID_OUI_FROM_DATABASE=Allied Telesis K.K.
+
+OUI:000942*
+ ID_OUI_FROM_DATABASE=Wireless Technologies, Inc
+
+OUI:000943*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000944*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000945*
+ ID_OUI_FROM_DATABASE=Palmmicro Communications Inc
+
+OUI:000946*
+ ID_OUI_FROM_DATABASE=Cluster Labs GmbH
+
+OUI:000947*
+ ID_OUI_FROM_DATABASE=Aztek, Inc.
+
+OUI:000948*
+ ID_OUI_FROM_DATABASE=Vista Control Systems, Corp.
+
+OUI:000949*
+ ID_OUI_FROM_DATABASE=Glyph Technologies Inc.
+
+OUI:00094A*
+ ID_OUI_FROM_DATABASE=Homenet Communications
+
+OUI:00094B*
+ ID_OUI_FROM_DATABASE=FillFactory NV
+
+OUI:00094C*
+ ID_OUI_FROM_DATABASE=Communication Weaver Co.,Ltd.
+
+OUI:00094D*
+ ID_OUI_FROM_DATABASE=Braintree Communications Pty Ltd
+
+OUI:00094E*
+ ID_OUI_FROM_DATABASE=BARTECH SYSTEMS INTERNATIONAL, INC
+
+OUI:00094F*
+ ID_OUI_FROM_DATABASE=elmegt GmbH & Co. KG
+
+OUI:000950*
+ ID_OUI_FROM_DATABASE=Independent Storage Corporation
+
+OUI:000951*
+ ID_OUI_FROM_DATABASE=Apogee Imaging Systems
+
+OUI:000952*
+ ID_OUI_FROM_DATABASE=Auerswald GmbH & Co. KG
+
+OUI:000953*
+ ID_OUI_FROM_DATABASE=Linkage System Integration Co.Ltd.
+
+OUI:000954*
+ ID_OUI_FROM_DATABASE=AMiT spol. s. r. o.
+
+OUI:000955*
+ ID_OUI_FROM_DATABASE=Young Generation International Corp.
+
+OUI:000956*
+ ID_OUI_FROM_DATABASE=Network Systems Group, Ltd. (NSG)
+
+OUI:000957*
+ ID_OUI_FROM_DATABASE=Supercaller, Inc.
+
+OUI:000958*
+ ID_OUI_FROM_DATABASE=INTELNET S.A.
+
+OUI:000959*
+ ID_OUI_FROM_DATABASE=Sitecsoft
+
+OUI:00095A*
+ ID_OUI_FROM_DATABASE=RACEWOOD TECHNOLOGY
+
+OUI:00095B*
+ ID_OUI_FROM_DATABASE=Netgear, Inc.
+
+OUI:00095C*
+ ID_OUI_FROM_DATABASE=Philips Medical Systems - Cardiac and Monitoring Systems (CM
+
+OUI:00095D*
+ ID_OUI_FROM_DATABASE=Dialogue Technology Corp.
+
+OUI:00095E*
+ ID_OUI_FROM_DATABASE=Masstech Group Inc.
+
+OUI:00095F*
+ ID_OUI_FROM_DATABASE=Telebyte, Inc.
+
+OUI:000960*
+ ID_OUI_FROM_DATABASE=YOZAN Inc.
+
+OUI:000961*
+ ID_OUI_FROM_DATABASE=Switchgear and Instrumentation Ltd
+
+OUI:000962*
+ ID_OUI_FROM_DATABASE=Sonitor Technologies AS
+
+OUI:000963*
+ ID_OUI_FROM_DATABASE=Dominion Lasercom Inc.
+
+OUI:000964*
+ ID_OUI_FROM_DATABASE=Hi-Techniques, Inc.
+
+OUI:000965*
+ ID_OUI_FROM_DATABASE=HyunJu Computer Co., Ltd.
+
+OUI:000966*
+ ID_OUI_FROM_DATABASE=Thales Navigation
+
+OUI:000967*
+ ID_OUI_FROM_DATABASE=Tachyon, Inc
+
+OUI:000968*
+ ID_OUI_FROM_DATABASE=TECHNOVENTURE, INC.
+
+OUI:000969*
+ ID_OUI_FROM_DATABASE=Meret Optical Communications
+
+OUI:00096A*
+ ID_OUI_FROM_DATABASE=Cloverleaf Communications Inc.
+
+OUI:00096B*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:00096C*
+ ID_OUI_FROM_DATABASE=Imedia Semiconductor Corp.
+
+OUI:00096D*
+ ID_OUI_FROM_DATABASE=Powernet Technologies Corp.
+
+OUI:00096E*
+ ID_OUI_FROM_DATABASE=GIANT ELECTRONICS LTD.
+
+OUI:00096F*
+ ID_OUI_FROM_DATABASE=Beijing Zhongqing Elegant Tech. Corp.,Limited
+
+OUI:000970*
+ ID_OUI_FROM_DATABASE=Vibration Research Corporation
+
+OUI:000971*
+ ID_OUI_FROM_DATABASE=Time Management, Inc.
+
+OUI:000972*
+ ID_OUI_FROM_DATABASE=Securebase,Inc
+
+OUI:000973*
+ ID_OUI_FROM_DATABASE=Lenten Technology Co., Ltd.
+
+OUI:000974*
+ ID_OUI_FROM_DATABASE=Innopia Technologies, Inc.
+
+OUI:000975*
+ ID_OUI_FROM_DATABASE=fSONA Communications Corporation
+
+OUI:000976*
+ ID_OUI_FROM_DATABASE=Datasoft ISDN Systems GmbH
+
+OUI:000977*
+ ID_OUI_FROM_DATABASE=Brunner Elektronik AG
+
+OUI:000978*
+ ID_OUI_FROM_DATABASE=AIJI System Co., Ltd.
+
+OUI:000979*
+ ID_OUI_FROM_DATABASE=Advanced Television Systems Committee, Inc.
+
+OUI:00097A*
+ ID_OUI_FROM_DATABASE=Louis Design Labs.
+
+OUI:00097B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00097C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00097D*
+ ID_OUI_FROM_DATABASE=SecWell Networks Oy
+
+OUI:00097E*
+ ID_OUI_FROM_DATABASE=IMI TECHNOLOGY CO., LTD
+
+OUI:00097F*
+ ID_OUI_FROM_DATABASE=Vsecure 2000 LTD.
+
+OUI:000980*
+ ID_OUI_FROM_DATABASE=Power Zenith Inc.
+
+OUI:000981*
+ ID_OUI_FROM_DATABASE=Newport Networks
+
+OUI:000982*
+ ID_OUI_FROM_DATABASE=Loewe Opta GmbH
+
+OUI:000983*
+ ID_OUI_FROM_DATABASE=GlobalTop Technology, Inc.
+
+OUI:000984*
+ ID_OUI_FROM_DATABASE=MyCasa Network Inc.
+
+OUI:000985*
+ ID_OUI_FROM_DATABASE=Auto Telecom Company
+
+OUI:000986*
+ ID_OUI_FROM_DATABASE=Metalink LTD.
+
+OUI:000987*
+ ID_OUI_FROM_DATABASE=NISHI NIPPON ELECTRIC WIRE & CABLE CO.,LTD.
+
+OUI:000988*
+ ID_OUI_FROM_DATABASE=Nudian Electron Co., Ltd.
+
+OUI:000989*
+ ID_OUI_FROM_DATABASE=VividLogic Inc.
+
+OUI:00098A*
+ ID_OUI_FROM_DATABASE=EqualLogic Inc
+
+OUI:00098B*
+ ID_OUI_FROM_DATABASE=Entropic Communications, Inc.
+
+OUI:00098C*
+ ID_OUI_FROM_DATABASE=Option Wireless Sweden
+
+OUI:00098D*
+ ID_OUI_FROM_DATABASE=Velocity Semiconductor
+
+OUI:00098E*
+ ID_OUI_FROM_DATABASE=ipcas GmbH
+
+OUI:00098F*
+ ID_OUI_FROM_DATABASE=Cetacean Networks
+
+OUI:000990*
+ ID_OUI_FROM_DATABASE=ACKSYS Communications & systems
+
+OUI:000991*
+ ID_OUI_FROM_DATABASE=GE Fanuc Automation Manufacturing, Inc.
+
+OUI:000992*
+ ID_OUI_FROM_DATABASE=InterEpoch Technology,INC.
+
+OUI:000993*
+ ID_OUI_FROM_DATABASE=Visteon Corporation
+
+OUI:000994*
+ ID_OUI_FROM_DATABASE=Cronyx Engineering
+
+OUI:000995*
+ ID_OUI_FROM_DATABASE=Castle Technology Ltd
+
+OUI:000996*
+ ID_OUI_FROM_DATABASE=RDI
+
+OUI:000997*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000998*
+ ID_OUI_FROM_DATABASE=Capinfo Company Limited
+
+OUI:000999*
+ ID_OUI_FROM_DATABASE=CP GEORGES RENAULT
+
+OUI:00099A*
+ ID_OUI_FROM_DATABASE=ELMO COMPANY, LIMITED
+
+OUI:00099B*
+ ID_OUI_FROM_DATABASE=Western Telematic Inc.
+
+OUI:00099C*
+ ID_OUI_FROM_DATABASE=Naval Research Laboratory
+
+OUI:00099D*
+ ID_OUI_FROM_DATABASE=Haliplex Communications
+
+OUI:00099E*
+ ID_OUI_FROM_DATABASE=Testech, Inc.
+
+OUI:00099F*
+ ID_OUI_FROM_DATABASE=VIDEX INC.
+
+OUI:0009A0*
+ ID_OUI_FROM_DATABASE=Microtechno Corporation
+
+OUI:0009A1*
+ ID_OUI_FROM_DATABASE=Telewise Communications, Inc.
+
+OUI:0009A2*
+ ID_OUI_FROM_DATABASE=Interface Co., Ltd.
+
+OUI:0009A3*
+ ID_OUI_FROM_DATABASE=Leadfly Techologies Corp. Ltd.
+
+OUI:0009A4*
+ ID_OUI_FROM_DATABASE=HARTEC Corporation
+
+OUI:0009A5*
+ ID_OUI_FROM_DATABASE=HANSUNG ELETRONIC INDUSTRIES DEVELOPMENT CO., LTD
+
+OUI:0009A6*
+ ID_OUI_FROM_DATABASE=Ignis Optics, Inc.
+
+OUI:0009A7*
+ ID_OUI_FROM_DATABASE=Bang & Olufsen A/S
+
+OUI:0009A8*
+ ID_OUI_FROM_DATABASE=Eastmode Pte Ltd
+
+OUI:0009A9*
+ ID_OUI_FROM_DATABASE=Ikanos Communications
+
+OUI:0009AA*
+ ID_OUI_FROM_DATABASE=Data Comm for Business, Inc.
+
+OUI:0009AB*
+ ID_OUI_FROM_DATABASE=Netcontrol Oy
+
+OUI:0009AC*
+ ID_OUI_FROM_DATABASE=LANVOICE
+
+OUI:0009AD*
+ ID_OUI_FROM_DATABASE=HYUNDAI SYSCOMM, INC.
+
+OUI:0009AE*
+ ID_OUI_FROM_DATABASE=OKANO ELECTRIC CO.,LTD
+
+OUI:0009AF*
+ ID_OUI_FROM_DATABASE=e-generis
+
+OUI:0009B0*
+ ID_OUI_FROM_DATABASE=Onkyo Corporation
+
+OUI:0009B1*
+ ID_OUI_FROM_DATABASE=Kanematsu Electronics, Ltd.
+
+OUI:0009B2*
+ ID_OUI_FROM_DATABASE=L&F Inc.
+
+OUI:0009B3*
+ ID_OUI_FROM_DATABASE=MCM Systems Ltd
+
+OUI:0009B4*
+ ID_OUI_FROM_DATABASE=KISAN TELECOM CO., LTD.
+
+OUI:0009B5*
+ ID_OUI_FROM_DATABASE=3J Tech. Co., Ltd.
+
+OUI:0009B6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0009B7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0009B8*
+ ID_OUI_FROM_DATABASE=Entise Systems
+
+OUI:0009B9*
+ ID_OUI_FROM_DATABASE=Action Imaging Solutions
+
+OUI:0009BA*
+ ID_OUI_FROM_DATABASE=MAKU Informationstechik GmbH
+
+OUI:0009BB*
+ ID_OUI_FROM_DATABASE=MathStar, Inc.
+
+OUI:0009BC*
+ ID_OUI_FROM_DATABASE=Digital Safety Technologies, Inc
+
+OUI:0009BD*
+ ID_OUI_FROM_DATABASE=Epygi Technologies, Ltd.
+
+OUI:0009BE*
+ ID_OUI_FROM_DATABASE=Mamiya-OP Co.,Ltd.
+
+OUI:0009BF*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd.
+
+OUI:0009C0*
+ ID_OUI_FROM_DATABASE=6WIND
+
+OUI:0009C1*
+ ID_OUI_FROM_DATABASE=PROCES-DATA A/S
+
+OUI:0009C2*
+ ID_OUI_FROM_DATABASE=Onity, Inc.
+
+OUI:0009C3*
+ ID_OUI_FROM_DATABASE=NETAS
+
+OUI:0009C4*
+ ID_OUI_FROM_DATABASE=Medicore Co., Ltd
+
+OUI:0009C5*
+ ID_OUI_FROM_DATABASE=KINGENE Technology Corporation
+
+OUI:0009C6*
+ ID_OUI_FROM_DATABASE=Visionics Corporation
+
+OUI:0009C7*
+ ID_OUI_FROM_DATABASE=Movistec
+
+OUI:0009C8*
+ ID_OUI_FROM_DATABASE=SINAGAWA TSUSHIN KEISOU SERVICE
+
+OUI:0009C9*
+ ID_OUI_FROM_DATABASE=BlueWINC Co., Ltd.
+
+OUI:0009CA*
+ ID_OUI_FROM_DATABASE=iMaxNetworks(Shenzhen)Limited.
+
+OUI:0009CB*
+ ID_OUI_FROM_DATABASE=HBrain
+
+OUI:0009CC*
+ ID_OUI_FROM_DATABASE=Moog GmbH
+
+OUI:0009CD*
+ ID_OUI_FROM_DATABASE=HUDSON SOFT CO.,LTD.
+
+OUI:0009CE*
+ ID_OUI_FROM_DATABASE=SpaceBridge Semiconductor Corp.
+
+OUI:0009CF*
+ ID_OUI_FROM_DATABASE=iAd GmbH
+
+OUI:0009D0*
+ ID_OUI_FROM_DATABASE=Solacom Technologies Inc.
+
+OUI:0009D1*
+ ID_OUI_FROM_DATABASE=SERANOA NETWORKS INC
+
+OUI:0009D2*
+ ID_OUI_FROM_DATABASE=Mai Logic Inc.
+
+OUI:0009D3*
+ ID_OUI_FROM_DATABASE=Western DataCom Co., Inc.
+
+OUI:0009D4*
+ ID_OUI_FROM_DATABASE=Transtech Networks
+
+OUI:0009D5*
+ ID_OUI_FROM_DATABASE=Signal Communication, Inc.
+
+OUI:0009D6*
+ ID_OUI_FROM_DATABASE=KNC One GmbH
+
+OUI:0009D7*
+ ID_OUI_FROM_DATABASE=DC Security Products
+
+OUI:0009D8*
+ ID_OUI_FROM_DATABASE=Fält Communications AB
+
+OUI:0009D9*
+ ID_OUI_FROM_DATABASE=Neoscale Systems, Inc
+
+OUI:0009DA*
+ ID_OUI_FROM_DATABASE=Control Module Inc.
+
+OUI:0009DB*
+ ID_OUI_FROM_DATABASE=eSpace
+
+OUI:0009DC*
+ ID_OUI_FROM_DATABASE=Galaxis Technology AG
+
+OUI:0009DD*
+ ID_OUI_FROM_DATABASE=Mavin Technology Inc.
+
+OUI:0009DE*
+ ID_OUI_FROM_DATABASE=Samjin Information & Communications Co., Ltd.
+
+OUI:0009DF*
+ ID_OUI_FROM_DATABASE=Vestel Komunikasyon Sanayi ve Ticaret A.S.
+
+OUI:0009E0*
+ ID_OUI_FROM_DATABASE=XEMICS S.A.
+
+OUI:0009E1*
+ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+
+OUI:0009E2*
+ ID_OUI_FROM_DATABASE=Sinbon Electronics Co., Ltd.
+
+OUI:0009E3*
+ ID_OUI_FROM_DATABASE=Angel Iglesias S.A.
+
+OUI:0009E4*
+ ID_OUI_FROM_DATABASE=K Tech Infosystem Inc.
+
+OUI:0009E5*
+ ID_OUI_FROM_DATABASE=Hottinger Baldwin Messtechnik GmbH
+
+OUI:0009E6*
+ ID_OUI_FROM_DATABASE=Cyber Switching Inc.
+
+OUI:0009E7*
+ ID_OUI_FROM_DATABASE=ADC Techonology
+
+OUI:0009E8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0009E9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0009EA*
+ ID_OUI_FROM_DATABASE=YEM Inc.
+
+OUI:0009EB*
+ ID_OUI_FROM_DATABASE=HuMANDATA LTD.
+
+OUI:0009EC*
+ ID_OUI_FROM_DATABASE=Daktronics, Inc.
+
+OUI:0009ED*
+ ID_OUI_FROM_DATABASE=CipherOptics
+
+OUI:0009EE*
+ ID_OUI_FROM_DATABASE=MEIKYO ELECTRIC CO.,LTD
+
+OUI:0009EF*
+ ID_OUI_FROM_DATABASE=Vocera Communications
+
+OUI:0009F0*
+ ID_OUI_FROM_DATABASE=Shimizu Technology Inc.
+
+OUI:0009F1*
+ ID_OUI_FROM_DATABASE=Yamaki Electric Corporation
+
+OUI:0009F2*
+ ID_OUI_FROM_DATABASE=Cohu, Inc., Electronics Division
+
+OUI:0009F3*
+ ID_OUI_FROM_DATABASE=WELL Communication Corp.
+
+OUI:0009F4*
+ ID_OUI_FROM_DATABASE=Alcon Laboratories, Inc.
+
+OUI:0009F5*
+ ID_OUI_FROM_DATABASE=Emerson Network Power Co.,Ltd
+
+OUI:0009F6*
+ ID_OUI_FROM_DATABASE=Shenzhen Eastern Digital Tech Ltd.
+
+OUI:0009F7*
+ ID_OUI_FROM_DATABASE=SED, a division of Calian
+
+OUI:0009F8*
+ ID_OUI_FROM_DATABASE=UNIMO TECHNOLOGY CO., LTD.
+
+OUI:0009F9*
+ ID_OUI_FROM_DATABASE=ART JAPAN CO., LTD.
+
+OUI:0009FB*
+ ID_OUI_FROM_DATABASE=Philips Patient Monitoring
+
+OUI:0009FC*
+ ID_OUI_FROM_DATABASE=IPFLEX Inc.
+
+OUI:0009FD*
+ ID_OUI_FROM_DATABASE=Ubinetics Limited
+
+OUI:0009FE*
+ ID_OUI_FROM_DATABASE=Daisy Technologies, Inc.
+
+OUI:0009FF*
+ ID_OUI_FROM_DATABASE=X.net 2000 GmbH
+
+OUI:000A00*
+ ID_OUI_FROM_DATABASE=Mediatek Corp.
+
+OUI:000A01*
+ ID_OUI_FROM_DATABASE=SOHOware, Inc.
+
+OUI:000A02*
+ ID_OUI_FROM_DATABASE=ANNSO CO., LTD.
+
+OUI:000A03*
+ ID_OUI_FROM_DATABASE=ENDESA SERVICIOS, S.L.
+
+OUI:000A04*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:000A05*
+ ID_OUI_FROM_DATABASE=Widax Corp.
+
+OUI:000A06*
+ ID_OUI_FROM_DATABASE=Teledex LLC
+
+OUI:000A07*
+ ID_OUI_FROM_DATABASE=WebWayOne Ltd
+
+OUI:000A08*
+ ID_OUI_FROM_DATABASE=ALPINE ELECTRONICS, INC.
+
+OUI:000A09*
+ ID_OUI_FROM_DATABASE=TaraCom Integrated Products, Inc.
+
+OUI:000A0A*
+ ID_OUI_FROM_DATABASE=SUNIX Co., Ltd.
+
+OUI:000A0B*
+ ID_OUI_FROM_DATABASE=Sealevel Systems, Inc.
+
+OUI:000A0C*
+ ID_OUI_FROM_DATABASE=Scientific Research Corporation
+
+OUI:000A0D*
+ ID_OUI_FROM_DATABASE=FCI Deutschland GmbH
+
+OUI:000A0E*
+ ID_OUI_FROM_DATABASE=Invivo Research Inc.
+
+OUI:000A0F*
+ ID_OUI_FROM_DATABASE=Ilryung Telesys, Inc
+
+OUI:000A10*
+ ID_OUI_FROM_DATABASE=FAST media integrations AG
+
+OUI:000A11*
+ ID_OUI_FROM_DATABASE=ExPet Technologies, Inc
+
+OUI:000A12*
+ ID_OUI_FROM_DATABASE=Azylex Technology, Inc
+
+OUI:000A13*
+ ID_OUI_FROM_DATABASE=Honeywell Video Systems
+
+OUI:000A14*
+ ID_OUI_FROM_DATABASE=TECO a.s.
+
+OUI:000A15*
+ ID_OUI_FROM_DATABASE=Silicon Data, Inc
+
+OUI:000A16*
+ ID_OUI_FROM_DATABASE=Lassen Research
+
+OUI:000A17*
+ ID_OUI_FROM_DATABASE=NESTAR COMMUNICATIONS, INC
+
+OUI:000A18*
+ ID_OUI_FROM_DATABASE=Vichel Inc.
+
+OUI:000A19*
+ ID_OUI_FROM_DATABASE=Valere Power, Inc.
+
+OUI:000A1A*
+ ID_OUI_FROM_DATABASE=Imerge Ltd
+
+OUI:000A1B*
+ ID_OUI_FROM_DATABASE=Stream Labs
+
+OUI:000A1C*
+ ID_OUI_FROM_DATABASE=Bridge Information Co., Ltd.
+
+OUI:000A1D*
+ ID_OUI_FROM_DATABASE=Optical Communications Products Inc.
+
+OUI:000A1E*
+ ID_OUI_FROM_DATABASE=Red-M Products Limited
+
+OUI:000A1F*
+ ID_OUI_FROM_DATABASE=ART WARE Telecommunication Co., Ltd.
+
+OUI:000A20*
+ ID_OUI_FROM_DATABASE=SVA Networks, Inc.
+
+OUI:000A21*
+ ID_OUI_FROM_DATABASE=Integra Telecom Co. Ltd
+
+OUI:000A22*
+ ID_OUI_FROM_DATABASE=Amperion Inc
+
+OUI:000A23*
+ ID_OUI_FROM_DATABASE=Parama Networks Inc
+
+OUI:000A24*
+ ID_OUI_FROM_DATABASE=Octave Communications
+
+OUI:000A25*
+ ID_OUI_FROM_DATABASE=CERAGON NETWORKS
+
+OUI:000A26*
+ ID_OUI_FROM_DATABASE=CEIA S.p.A.
+
+OUI:000A27*
+ ID_OUI_FROM_DATABASE=Apple Computer, Inc.
+
+OUI:000A28*
+ ID_OUI_FROM_DATABASE=Motorola
+
+OUI:000A29*
+ ID_OUI_FROM_DATABASE=Pan Dacom Networking AG
+
+OUI:000A2A*
+ ID_OUI_FROM_DATABASE=QSI Systems Inc.
+
+OUI:000A2B*
+ ID_OUI_FROM_DATABASE=Etherstuff
+
+OUI:000A2C*
+ ID_OUI_FROM_DATABASE=Active Tchnology Corporation
+
+OUI:000A2D*
+ ID_OUI_FROM_DATABASE=Cabot Communications Limited
+
+OUI:000A2E*
+ ID_OUI_FROM_DATABASE=MAPLE NETWORKS CO., LTD
+
+OUI:000A2F*
+ ID_OUI_FROM_DATABASE=Artnix Inc.
+
+OUI:000A30*
+ ID_OUI_FROM_DATABASE=Johnson Controls-ASG
+
+OUI:000A31*
+ ID_OUI_FROM_DATABASE=HCV Consulting
+
+OUI:000A32*
+ ID_OUI_FROM_DATABASE=Xsido Corporation
+
+OUI:000A33*
+ ID_OUI_FROM_DATABASE=Emulex Corporation
+
+OUI:000A34*
+ ID_OUI_FROM_DATABASE=Identicard Systems Incorporated
+
+OUI:000A35*
+ ID_OUI_FROM_DATABASE=Xilinx
+
+OUI:000A36*
+ ID_OUI_FROM_DATABASE=Synelec Telecom Multimedia
+
+OUI:000A37*
+ ID_OUI_FROM_DATABASE=Procera Networks, Inc.
+
+OUI:000A38*
+ ID_OUI_FROM_DATABASE=Apani Networks
+
+OUI:000A39*
+ ID_OUI_FROM_DATABASE=LoPA Information Technology
+
+OUI:000A3A*
+ ID_OUI_FROM_DATABASE=J-THREE INTERNATIONAL Holding Co., Ltd.
+
+OUI:000A3B*
+ ID_OUI_FROM_DATABASE=GCT Semiconductor, Inc
+
+OUI:000A3C*
+ ID_OUI_FROM_DATABASE=Enerpoint Ltd.
+
+OUI:000A3D*
+ ID_OUI_FROM_DATABASE=Elo Sistemas Eletronicos S.A.
+
+OUI:000A3E*
+ ID_OUI_FROM_DATABASE=EADS Telecom
+
+OUI:000A3F*
+ ID_OUI_FROM_DATABASE=Data East Corporation
+
+OUI:000A40*
+ ID_OUI_FROM_DATABASE=Crown Audio -- Harmanm International
+
+OUI:000A41*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000A42*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000A43*
+ ID_OUI_FROM_DATABASE=Chunghwa Telecom Co., Ltd.
+
+OUI:000A44*
+ ID_OUI_FROM_DATABASE=Avery Dennison Deutschland GmbH
+
+OUI:000A45*
+ ID_OUI_FROM_DATABASE=Audio-Technica Corp.
+
+OUI:000A46*
+ ID_OUI_FROM_DATABASE=ARO WELDING TECHNOLOGIES SAS
+
+OUI:000A47*
+ ID_OUI_FROM_DATABASE=Allied Vision Technologies
+
+OUI:000A48*
+ ID_OUI_FROM_DATABASE=Albatron Technology
+
+OUI:000A49*
+ ID_OUI_FROM_DATABASE=F5 Networks, Inc.
+
+OUI:000A4A*
+ ID_OUI_FROM_DATABASE=Targa Systems Ltd.
+
+OUI:000A4B*
+ ID_OUI_FROM_DATABASE=DataPower Technology, Inc.
+
+OUI:000A4C*
+ ID_OUI_FROM_DATABASE=Molecular Devices Corporation
+
+OUI:000A4D*
+ ID_OUI_FROM_DATABASE=Noritz Corporation
+
+OUI:000A4E*
+ ID_OUI_FROM_DATABASE=UNITEK Electronics INC.
+
+OUI:000A4F*
+ ID_OUI_FROM_DATABASE=Brain Boxes Limited
+
+OUI:000A50*
+ ID_OUI_FROM_DATABASE=REMOTEK CORPORATION
+
+OUI:000A51*
+ ID_OUI_FROM_DATABASE=GyroSignal Technology Co., Ltd.
+
+OUI:000A52*
+ ID_OUI_FROM_DATABASE=AsiaRF Ltd.
+
+OUI:000A53*
+ ID_OUI_FROM_DATABASE=Intronics, Incorporated
+
+OUI:000A54*
+ ID_OUI_FROM_DATABASE=Laguna Hills, Inc.
+
+OUI:000A55*
+ ID_OUI_FROM_DATABASE=MARKEM Corporation
+
+OUI:000A56*
+ ID_OUI_FROM_DATABASE=HITACHI Maxell Ltd.
+
+OUI:000A57*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company - Standards
+
+OUI:000A58*
+ ID_OUI_FROM_DATABASE=Ingenieur-Büro Freyer & Siegel
+
+OUI:000A59*
+ ID_OUI_FROM_DATABASE=HW server
+
+OUI:000A5A*
+ ID_OUI_FROM_DATABASE=GreenNET Technologies Co.,Ltd.
+
+OUI:000A5B*
+ ID_OUI_FROM_DATABASE=Power-One as
+
+OUI:000A5C*
+ ID_OUI_FROM_DATABASE=Carel s.p.a.
+
+OUI:000A5D*
+ ID_OUI_FROM_DATABASE=PUC Founder (MSC) Berhad
+
+OUI:000A5E*
+ ID_OUI_FROM_DATABASE=3COM Corporation
+
+OUI:000A5F*
+ ID_OUI_FROM_DATABASE=almedio inc.
+
+OUI:000A60*
+ ID_OUI_FROM_DATABASE=Autostar Technology Pte Ltd
+
+OUI:000A61*
+ ID_OUI_FROM_DATABASE=Cellinx Systems Inc.
+
+OUI:000A62*
+ ID_OUI_FROM_DATABASE=Crinis Networks, Inc.
+
+OUI:000A63*
+ ID_OUI_FROM_DATABASE=DHD GmbH
+
+OUI:000A64*
+ ID_OUI_FROM_DATABASE=Eracom Technologies
+
+OUI:000A65*
+ ID_OUI_FROM_DATABASE=GentechMedia.co.,ltd.
+
+OUI:000A66*
+ ID_OUI_FROM_DATABASE=MITSUBISHI ELECTRIC SYSTEM & SERVICE CO.,LTD.
+
+OUI:000A67*
+ ID_OUI_FROM_DATABASE=OngCorp
+
+OUI:000A68*
+ ID_OUI_FROM_DATABASE=SolarFlare Communications, Inc.
+
+OUI:000A69*
+ ID_OUI_FROM_DATABASE=SUNNY bell Technology Co., Ltd.
+
+OUI:000A6A*
+ ID_OUI_FROM_DATABASE=SVM Microwaves s.r.o.
+
+OUI:000A6B*
+ ID_OUI_FROM_DATABASE=Tadiran Telecom Business Systems LTD
+
+OUI:000A6C*
+ ID_OUI_FROM_DATABASE=Walchem Corporation
+
+OUI:000A6D*
+ ID_OUI_FROM_DATABASE=EKS Elektronikservice GmbH
+
+OUI:000A6E*
+ ID_OUI_FROM_DATABASE=Harmonic, Inc
+
+OUI:000A6F*
+ ID_OUI_FROM_DATABASE=ZyFLEX Technologies Inc
+
+OUI:000A70*
+ ID_OUI_FROM_DATABASE=MPLS Forum
+
+OUI:000A71*
+ ID_OUI_FROM_DATABASE=Avrio Technologies, Inc
+
+OUI:000A72*
+ ID_OUI_FROM_DATABASE=STEC, INC.
+
+OUI:000A73*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta
+
+OUI:000A74*
+ ID_OUI_FROM_DATABASE=Manticom Networks Inc.
+
+OUI:000A75*
+ ID_OUI_FROM_DATABASE=Caterpillar, Inc
+
+OUI:000A76*
+ ID_OUI_FROM_DATABASE=Beida Jade Bird Huaguang Technology Co.,Ltd
+
+OUI:000A77*
+ ID_OUI_FROM_DATABASE=Bluewire Technologies LLC
+
+OUI:000A78*
+ ID_OUI_FROM_DATABASE=OLITEC
+
+OUI:000A79*
+ ID_OUI_FROM_DATABASE=Allied Telesis K.K. corega division
+
+OUI:000A7A*
+ ID_OUI_FROM_DATABASE=Kyoritsu Electric Co., Ltd.
+
+OUI:000A7B*
+ ID_OUI_FROM_DATABASE=Cornelius Consult
+
+OUI:000A7C*
+ ID_OUI_FROM_DATABASE=Tecton Ltd
+
+OUI:000A7D*
+ ID_OUI_FROM_DATABASE=Valo, Inc.
+
+OUI:000A7E*
+ ID_OUI_FROM_DATABASE=The Advantage Group
+
+OUI:000A7F*
+ ID_OUI_FROM_DATABASE=Teradon Industries, Inc
+
+OUI:000A80*
+ ID_OUI_FROM_DATABASE=Telkonet Inc.
+
+OUI:000A81*
+ ID_OUI_FROM_DATABASE=TEIMA Audiotex S.L.
+
+OUI:000A82*
+ ID_OUI_FROM_DATABASE=TATSUTA SYSTEM ELECTRONICS CO.,LTD.
+
+OUI:000A83*
+ ID_OUI_FROM_DATABASE=SALTO SYSTEMS S.L.
+
+OUI:000A84*
+ ID_OUI_FROM_DATABASE=Rainsun Enterprise Co., Ltd.
+
+OUI:000A85*
+ ID_OUI_FROM_DATABASE=PLAT'C2,Inc
+
+OUI:000A86*
+ ID_OUI_FROM_DATABASE=Lenze
+
+OUI:000A87*
+ ID_OUI_FROM_DATABASE=Integrated Micromachines Inc.
+
+OUI:000A88*
+ ID_OUI_FROM_DATABASE=InCypher S.A.
+
+OUI:000A89*
+ ID_OUI_FROM_DATABASE=Creval Systems, Inc.
+
+OUI:000A8A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000A8B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000A8C*
+ ID_OUI_FROM_DATABASE=Guardware Systems Ltd.
+
+OUI:000A8D*
+ ID_OUI_FROM_DATABASE=EUROTHERM LIMITED
+
+OUI:000A8E*
+ ID_OUI_FROM_DATABASE=Invacom Ltd
+
+OUI:000A8F*
+ ID_OUI_FROM_DATABASE=Aska International Inc.
+
+OUI:000A90*
+ ID_OUI_FROM_DATABASE=Bayside Interactive, Inc.
+
+OUI:000A91*
+ ID_OUI_FROM_DATABASE=HemoCue AB
+
+OUI:000A92*
+ ID_OUI_FROM_DATABASE=Presonus Corporation
+
+OUI:000A93*
+ ID_OUI_FROM_DATABASE=W2 Networks, Inc.
+
+OUI:000A94*
+ ID_OUI_FROM_DATABASE=ShangHai cellink CO., LTD
+
+OUI:000A95*
+ ID_OUI_FROM_DATABASE=Apple Computer, Inc.
+
+OUI:000A96*
+ ID_OUI_FROM_DATABASE=MEWTEL TECHNOLOGY INC.
+
+OUI:000A97*
+ ID_OUI_FROM_DATABASE=SONICblue, Inc.
+
+OUI:000A98*
+ ID_OUI_FROM_DATABASE=M+F Gwinner GmbH & Co
+
+OUI:000A99*
+ ID_OUI_FROM_DATABASE=Calamp Wireless Networks Inc
+
+OUI:000A9A*
+ ID_OUI_FROM_DATABASE=Aiptek International Inc
+
+OUI:000A9B*
+ ID_OUI_FROM_DATABASE=TB Group Inc
+
+OUI:000A9C*
+ ID_OUI_FROM_DATABASE=Server Technology, Inc.
+
+OUI:000A9D*
+ ID_OUI_FROM_DATABASE=King Young Technology Co. Ltd.
+
+OUI:000A9E*
+ ID_OUI_FROM_DATABASE=BroadWeb Corportation
+
+OUI:000A9F*
+ ID_OUI_FROM_DATABASE=Pannaway Technologies, Inc.
+
+OUI:000AA0*
+ ID_OUI_FROM_DATABASE=Cedar Point Communications
+
+OUI:000AA1*
+ ID_OUI_FROM_DATABASE=V V S Limited
+
+OUI:000AA2*
+ ID_OUI_FROM_DATABASE=SYSTEK INC.
+
+OUI:000AA3*
+ ID_OUI_FROM_DATABASE=SHIMAFUJI ELECTRIC CO.,LTD.
+
+OUI:000AA4*
+ ID_OUI_FROM_DATABASE=SHANGHAI SURVEILLANCE TECHNOLOGY CO,LTD
+
+OUI:000AA5*
+ ID_OUI_FROM_DATABASE=MAXLINK INDUSTRIES LIMITED
+
+OUI:000AA6*
+ ID_OUI_FROM_DATABASE=Hochiki Corporation
+
+OUI:000AA7*
+ ID_OUI_FROM_DATABASE=FEI Electron Optics
+
+OUI:000AA8*
+ ID_OUI_FROM_DATABASE=ePipe Pty. Ltd.
+
+OUI:000AA9*
+ ID_OUI_FROM_DATABASE=Brooks Automation GmbH
+
+OUI:000AAA*
+ ID_OUI_FROM_DATABASE=AltiGen Communications Inc.
+
+OUI:000AAB*
+ ID_OUI_FROM_DATABASE=Toyota Technical Development Corporation
+
+OUI:000AAC*
+ ID_OUI_FROM_DATABASE=TerraTec Electronic GmbH
+
+OUI:000AAD*
+ ID_OUI_FROM_DATABASE=Stargames Corporation
+
+OUI:000AAE*
+ ID_OUI_FROM_DATABASE=Rosemount Process Analytical
+
+OUI:000AAF*
+ ID_OUI_FROM_DATABASE=Pipal Systems
+
+OUI:000AB0*
+ ID_OUI_FROM_DATABASE=LOYTEC electronics GmbH
+
+OUI:000AB1*
+ ID_OUI_FROM_DATABASE=GENETEC Corporation
+
+OUI:000AB2*
+ ID_OUI_FROM_DATABASE=Fresnel Wireless Systems
+
+OUI:000AB3*
+ ID_OUI_FROM_DATABASE=Fa. GIRA
+
+OUI:000AB4*
+ ID_OUI_FROM_DATABASE=ETIC Telecommunications
+
+OUI:000AB5*
+ ID_OUI_FROM_DATABASE=Digital Electronic Network
+
+OUI:000AB6*
+ ID_OUI_FROM_DATABASE=COMPUNETIX, INC
+
+OUI:000AB7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000AB8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000AB9*
+ ID_OUI_FROM_DATABASE=Astera Technologies Corp.
+
+OUI:000ABA*
+ ID_OUI_FROM_DATABASE=Arcon Technology Limited
+
+OUI:000ABB*
+ ID_OUI_FROM_DATABASE=Taiwan Secom Co,. Ltd
+
+OUI:000ABC*
+ ID_OUI_FROM_DATABASE=Seabridge Ltd.
+
+OUI:000ABD*
+ ID_OUI_FROM_DATABASE=Rupprecht & Patashnick Co.
+
+OUI:000ABE*
+ ID_OUI_FROM_DATABASE=OPNET Technologies CO., LTD.
+
+OUI:000ABF*
+ ID_OUI_FROM_DATABASE=HIROTA SS
+
+OUI:000AC0*
+ ID_OUI_FROM_DATABASE=Fuyoh Video Industry CO., LTD.
+
+OUI:000AC1*
+ ID_OUI_FROM_DATABASE=Futuretel
+
+OUI:000AC2*
+ ID_OUI_FROM_DATABASE=FiberHome Telecommunication Technologies CO.,LTD
+
+OUI:000AC3*
+ ID_OUI_FROM_DATABASE=eM Technics Co., Ltd.
+
+OUI:000AC4*
+ ID_OUI_FROM_DATABASE=Daewoo Teletech Co., Ltd
+
+OUI:000AC5*
+ ID_OUI_FROM_DATABASE=Color Kinetics
+
+OUI:000AC6*
+ ID_OUI_FROM_DATABASE=Overture Networks.
+
+OUI:000AC7*
+ ID_OUI_FROM_DATABASE=Unication Group
+
+OUI:000AC8*
+ ID_OUI_FROM_DATABASE=ZPSYS CO.,LTD. (Planning&Management)
+
+OUI:000AC9*
+ ID_OUI_FROM_DATABASE=Zambeel Inc
+
+OUI:000ACA*
+ ID_OUI_FROM_DATABASE=YOKOYAMA SHOKAI CO.,Ltd.
+
+OUI:000ACB*
+ ID_OUI_FROM_DATABASE=XPAK MSA Group
+
+OUI:000ACC*
+ ID_OUI_FROM_DATABASE=Winnow Networks, Inc.
+
+OUI:000ACD*
+ ID_OUI_FROM_DATABASE=Sunrich Technology Limited
+
+OUI:000ACE*
+ ID_OUI_FROM_DATABASE=RADIANTECH, INC.
+
+OUI:000ACF*
+ ID_OUI_FROM_DATABASE=PROVIDEO Multimedia Co. Ltd.
+
+OUI:000AD0*
+ ID_OUI_FROM_DATABASE=Niigata Develoment Center,  F.I.T. Co., Ltd.
+
+OUI:000AD1*
+ ID_OUI_FROM_DATABASE=MWS
+
+OUI:000AD2*
+ ID_OUI_FROM_DATABASE=JEPICO Corporation
+
+OUI:000AD3*
+ ID_OUI_FROM_DATABASE=INITECH Co., Ltd
+
+OUI:000AD4*
+ ID_OUI_FROM_DATABASE=CoreBell Systems Inc.
+
+OUI:000AD5*
+ ID_OUI_FROM_DATABASE=Brainchild Electronic Co., Ltd.
+
+OUI:000AD6*
+ ID_OUI_FROM_DATABASE=BeamReach Networks
+
+OUI:000AD7*
+ ID_OUI_FROM_DATABASE=Origin ELECTRIC CO.,LTD.
+
+OUI:000AD8*
+ ID_OUI_FROM_DATABASE=IPCserv Technology Corp.
+
+OUI:000AD9*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:000ADA*
+ ID_OUI_FROM_DATABASE=Vindicator Technologies
+
+OUI:000ADB*
+ ID_OUI_FROM_DATABASE=SkyPilot Network, Inc
+
+OUI:000ADC*
+ ID_OUI_FROM_DATABASE=RuggedCom Inc.
+
+OUI:000ADD*
+ ID_OUI_FROM_DATABASE=Allworx Corp.
+
+OUI:000ADE*
+ ID_OUI_FROM_DATABASE=Happy Communication Co., Ltd.
+
+OUI:000ADF*
+ ID_OUI_FROM_DATABASE=Gennum Corporation
+
+OUI:000AE0*
+ ID_OUI_FROM_DATABASE=Fujitsu Softek
+
+OUI:000AE1*
+ ID_OUI_FROM_DATABASE=EG Technology
+
+OUI:000AE2*
+ ID_OUI_FROM_DATABASE=Binatone Electronics International, Ltd
+
+OUI:000AE3*
+ ID_OUI_FROM_DATABASE=YANG MEI TECHNOLOGY CO., LTD
+
+OUI:000AE4*
+ ID_OUI_FROM_DATABASE=Wistron Corp.
+
+OUI:000AE5*
+ ID_OUI_FROM_DATABASE=ScottCare Corporation
+
+OUI:000AE6*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. (ECS)
+
+OUI:000AE7*
+ ID_OUI_FROM_DATABASE=ELIOP S.A.
+
+OUI:000AE8*
+ ID_OUI_FROM_DATABASE=Cathay Roxus Information Technology Co. LTD
+
+OUI:000AE9*
+ ID_OUI_FROM_DATABASE=AirVast Technology Inc.
+
+OUI:000AEA*
+ ID_OUI_FROM_DATABASE=ADAM ELEKTRONIK LTD. ŞTI
+
+OUI:000AEB*
+ ID_OUI_FROM_DATABASE=Shenzhen Tp-Link Technology Co; Ltd.
+
+OUI:000AEC*
+ ID_OUI_FROM_DATABASE=Koatsu Gas Kogyo Co., Ltd.
+
+OUI:000AED*
+ ID_OUI_FROM_DATABASE=HARTING Systems GmbH & Co KG
+
+OUI:000AEE*
+ ID_OUI_FROM_DATABASE=GCD Hard- & Software GmbH
+
+OUI:000AEF*
+ ID_OUI_FROM_DATABASE=OTRUM ASA
+
+OUI:000AF0*
+ ID_OUI_FROM_DATABASE=SHIN-OH ELECTRONICS CO., LTD. R&D
+
+OUI:000AF1*
+ ID_OUI_FROM_DATABASE=Clarity Design, Inc.
+
+OUI:000AF2*
+ ID_OUI_FROM_DATABASE=NeoAxiom Corp.
+
+OUI:000AF3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000AF4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000AF5*
+ ID_OUI_FROM_DATABASE=Airgo Networks, Inc.
+
+OUI:000AF6*
+ ID_OUI_FROM_DATABASE=Emerson Climate Technologies Retail Solutions, Inc.
+
+OUI:000AF7*
+ ID_OUI_FROM_DATABASE=Broadcom Corp.
+
+OUI:000AF8*
+ ID_OUI_FROM_DATABASE=American Telecare Inc.
+
+OUI:000AF9*
+ ID_OUI_FROM_DATABASE=HiConnect, Inc.
+
+OUI:000AFA*
+ ID_OUI_FROM_DATABASE=Traverse Technologies Australia
+
+OUI:000AFB*
+ ID_OUI_FROM_DATABASE=Ambri Limited
+
+OUI:000AFC*
+ ID_OUI_FROM_DATABASE=Core Tec Communications, LLC
+
+OUI:000AFD*
+ ID_OUI_FROM_DATABASE=Viking Electronic Services
+
+OUI:000AFE*
+ ID_OUI_FROM_DATABASE=NovaPal Ltd
+
+OUI:000AFF*
+ ID_OUI_FROM_DATABASE=Kilchherr Elektronik AG
+
+OUI:000B00*
+ ID_OUI_FROM_DATABASE=FUJIAN START COMPUTER EQUIPMENT CO.,LTD
+
+OUI:000B01*
+ ID_OUI_FROM_DATABASE=DAIICHI ELECTRONICS CO., LTD.
+
+OUI:000B02*
+ ID_OUI_FROM_DATABASE=Dallmeier electronic
+
+OUI:000B03*
+ ID_OUI_FROM_DATABASE=Taekwang Industrial Co., Ltd
+
+OUI:000B04*
+ ID_OUI_FROM_DATABASE=Volktek Corporation
+
+OUI:000B05*
+ ID_OUI_FROM_DATABASE=Pacific Broadband Networks
+
+OUI:000B06*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:000B07*
+ ID_OUI_FROM_DATABASE=Voxpath Networks
+
+OUI:000B08*
+ ID_OUI_FROM_DATABASE=Pillar Data Systems
+
+OUI:000B09*
+ ID_OUI_FROM_DATABASE=Ifoundry Systems Singapore
+
+OUI:000B0A*
+ ID_OUI_FROM_DATABASE=dBm Optics
+
+OUI:000B0B*
+ ID_OUI_FROM_DATABASE=Corrent Corporation
+
+OUI:000B0C*
+ ID_OUI_FROM_DATABASE=Agile Systems Inc.
+
+OUI:000B0D*
+ ID_OUI_FROM_DATABASE=Air2U, Inc.
+
+OUI:000B0E*
+ ID_OUI_FROM_DATABASE=Trapeze Networks
+
+OUI:000B0F*
+ ID_OUI_FROM_DATABASE=Bosch Rexroth
+
+OUI:000B10*
+ ID_OUI_FROM_DATABASE=11wave Technonlogy Co.,Ltd
+
+OUI:000B11*
+ ID_OUI_FROM_DATABASE=HIMEJI ABC TRADING CO.,LTD.
+
+OUI:000B12*
+ ID_OUI_FROM_DATABASE=NURI Telecom Co., Ltd.
+
+OUI:000B13*
+ ID_OUI_FROM_DATABASE=ZETRON INC
+
+OUI:000B14*
+ ID_OUI_FROM_DATABASE=ViewSonic Corporation
+
+OUI:000B15*
+ ID_OUI_FROM_DATABASE=Platypus Technology
+
+OUI:000B16*
+ ID_OUI_FROM_DATABASE=Communication Machinery Corporation
+
+OUI:000B17*
+ ID_OUI_FROM_DATABASE=MKS Instruments
+
+OUI:000B19*
+ ID_OUI_FROM_DATABASE=Vernier Networks, Inc.
+
+OUI:000B1A*
+ ID_OUI_FROM_DATABASE=Industrial Defender, Inc.
+
+OUI:000B1B*
+ ID_OUI_FROM_DATABASE=Systronix, Inc.
+
+OUI:000B1C*
+ ID_OUI_FROM_DATABASE=SIBCO bv
+
+OUI:000B1D*
+ ID_OUI_FROM_DATABASE=LayerZero Power Systems, Inc.
+
+OUI:000B1E*
+ ID_OUI_FROM_DATABASE=KAPPA opto-electronics GmbH
+
+OUI:000B1F*
+ ID_OUI_FROM_DATABASE=I CON Computer Co.
+
+OUI:000B20*
+ ID_OUI_FROM_DATABASE=Hirata corporation
+
+OUI:000B21*
+ ID_OUI_FROM_DATABASE=G-Star Communications Inc.
+
+OUI:000B22*
+ ID_OUI_FROM_DATABASE=Environmental Systems and Services
+
+OUI:000B23*
+ ID_OUI_FROM_DATABASE=Siemens Subscriber Networks
+
+OUI:000B24*
+ ID_OUI_FROM_DATABASE=AirLogic
+
+OUI:000B25*
+ ID_OUI_FROM_DATABASE=Aeluros
+
+OUI:000B26*
+ ID_OUI_FROM_DATABASE=Wetek Corporation
+
+OUI:000B27*
+ ID_OUI_FROM_DATABASE=Scion Corporation
+
+OUI:000B28*
+ ID_OUI_FROM_DATABASE=Quatech Inc.
+
+OUI:000B29*
+ ID_OUI_FROM_DATABASE=LS(LG) Industrial Systems co.,Ltd
+
+OUI:000B2A*
+ ID_OUI_FROM_DATABASE=HOWTEL Co., Ltd.
+
+OUI:000B2B*
+ ID_OUI_FROM_DATABASE=HOSTNET CORPORATION
+
+OUI:000B2C*
+ ID_OUI_FROM_DATABASE=Eiki Industrial Co. Ltd.
+
+OUI:000B2D*
+ ID_OUI_FROM_DATABASE=Danfoss Inc.
+
+OUI:000B2E*
+ ID_OUI_FROM_DATABASE=Cal-Comp Electronics (Thailand) Public Company Limited Taipe
+
+OUI:000B2F*
+ ID_OUI_FROM_DATABASE=bplan GmbH
+
+OUI:000B30*
+ ID_OUI_FROM_DATABASE=Beijing Gongye Science & Technology Co.,Ltd
+
+OUI:000B31*
+ ID_OUI_FROM_DATABASE=Yantai ZhiYang Scientific and technology industry CO., LTD
+
+OUI:000B32*
+ ID_OUI_FROM_DATABASE=VORMETRIC, INC.
+
+OUI:000B33*
+ ID_OUI_FROM_DATABASE=Vivato Technologies
+
+OUI:000B34*
+ ID_OUI_FROM_DATABASE=ShangHai Broadband Technologies CO.LTD
+
+OUI:000B35*
+ ID_OUI_FROM_DATABASE=Quad Bit System co., Ltd.
+
+OUI:000B36*
+ ID_OUI_FROM_DATABASE=Productivity Systems, Inc.
+
+OUI:000B37*
+ ID_OUI_FROM_DATABASE=MANUFACTURE DES MONTRES ROLEX SA
+
+OUI:000B38*
+ ID_OUI_FROM_DATABASE=Knürr GmbH
+
+OUI:000B39*
+ ID_OUI_FROM_DATABASE=Keisoku Giken Co.,Ltd.
+
+OUI:000B3A*
+ ID_OUI_FROM_DATABASE=QuStream Corporation
+
+OUI:000B3B*
+ ID_OUI_FROM_DATABASE=devolo AG
+
+OUI:000B3C*
+ ID_OUI_FROM_DATABASE=Cygnal Integrated Products, Inc.
+
+OUI:000B3D*
+ ID_OUI_FROM_DATABASE=CONTAL OK Ltd.
+
+OUI:000B3E*
+ ID_OUI_FROM_DATABASE=BittWare, Inc
+
+OUI:000B3F*
+ ID_OUI_FROM_DATABASE=Anthology Solutions Inc.
+
+OUI:000B40*
+ ID_OUI_FROM_DATABASE=Oclaro
+
+OUI:000B41*
+ ID_OUI_FROM_DATABASE=Ing. Büro Dr. Beutlhauser
+
+OUI:000B42*
+ ID_OUI_FROM_DATABASE=commax Co., Ltd.
+
+OUI:000B43*
+ ID_OUI_FROM_DATABASE=Microscan Systems, Inc.
+
+OUI:000B44*
+ ID_OUI_FROM_DATABASE=Concord IDea Corp.
+
+OUI:000B45*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000B46*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000B47*
+ ID_OUI_FROM_DATABASE=Advanced Energy
+
+OUI:000B48*
+ ID_OUI_FROM_DATABASE=sofrel
+
+OUI:000B49*
+ ID_OUI_FROM_DATABASE=RF-Link System Inc.
+
+OUI:000B4A*
+ ID_OUI_FROM_DATABASE=Visimetrics (UK) Ltd
+
+OUI:000B4B*
+ ID_OUI_FROM_DATABASE=VISIOWAVE SA
+
+OUI:000B4C*
+ ID_OUI_FROM_DATABASE=Clarion (M) Sdn Bhd
+
+OUI:000B4D*
+ ID_OUI_FROM_DATABASE=Emuzed
+
+OUI:000B4E*
+ ID_OUI_FROM_DATABASE=VertexRSI, General Dynamics SatCOM Technologies, Inc.
+
+OUI:000B4F*
+ ID_OUI_FROM_DATABASE=Verifone, INC.
+
+OUI:000B50*
+ ID_OUI_FROM_DATABASE=Oxygnet
+
+OUI:000B51*
+ ID_OUI_FROM_DATABASE=Micetek International Inc.
+
+OUI:000B52*
+ ID_OUI_FROM_DATABASE=JOYMAX ELECTRONICS CO. LTD.
+
+OUI:000B53*
+ ID_OUI_FROM_DATABASE=INITIUM Co., Ltd.
+
+OUI:000B54*
+ ID_OUI_FROM_DATABASE=BiTMICRO Networks, Inc.
+
+OUI:000B55*
+ ID_OUI_FROM_DATABASE=ADInstruments
+
+OUI:000B56*
+ ID_OUI_FROM_DATABASE=Cybernetics
+
+OUI:000B57*
+ ID_OUI_FROM_DATABASE=Silicon Laboratories
+
+OUI:000B58*
+ ID_OUI_FROM_DATABASE=Astronautics C.A  LTD
+
+OUI:000B59*
+ ID_OUI_FROM_DATABASE=ScriptPro, LLC
+
+OUI:000B5A*
+ ID_OUI_FROM_DATABASE=HyperEdge
+
+OUI:000B5B*
+ ID_OUI_FROM_DATABASE=Rincon Research Corporation
+
+OUI:000B5C*
+ ID_OUI_FROM_DATABASE=Newtech Co.,Ltd
+
+OUI:000B5D*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+
+OUI:000B5E*
+ ID_OUI_FROM_DATABASE=Audio Engineering Society Inc.
+
+OUI:000B5F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000B60*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000B61*
+ ID_OUI_FROM_DATABASE=Friedrich Lütze GmbH & Co. KG
+
+OUI:000B62*
+ ID_OUI_FROM_DATABASE=Ingenieurbüro für Elektronikdesign Ingo Mohnen
+
+OUI:000B63*
+ ID_OUI_FROM_DATABASE=Kaleidescape
+
+OUI:000B64*
+ ID_OUI_FROM_DATABASE=Kieback & Peter GmbH & Co KG
+
+OUI:000B65*
+ ID_OUI_FROM_DATABASE=Sy.A.C. srl
+
+OUI:000B66*
+ ID_OUI_FROM_DATABASE=Teralink Communications
+
+OUI:000B67*
+ ID_OUI_FROM_DATABASE=Topview Technology Corporation
+
+OUI:000B68*
+ ID_OUI_FROM_DATABASE=Addvalue Communications Pte Ltd
+
+OUI:000B69*
+ ID_OUI_FROM_DATABASE=Franke Finland Oy
+
+OUI:000B6A*
+ ID_OUI_FROM_DATABASE=Asiarock Incorporation
+
+OUI:000B6B*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
+
+OUI:000B6C*
+ ID_OUI_FROM_DATABASE=Sychip Inc.
+
+OUI:000B6D*
+ ID_OUI_FROM_DATABASE=SOLECTRON JAPAN NAKANIIDA
+
+OUI:000B6E*
+ ID_OUI_FROM_DATABASE=Neff Instrument Corp.
+
+OUI:000B6F*
+ ID_OUI_FROM_DATABASE=Media Streaming Networks Inc
+
+OUI:000B70*
+ ID_OUI_FROM_DATABASE=Load Technology, Inc.
+
+OUI:000B71*
+ ID_OUI_FROM_DATABASE=Litchfield Communications Inc.
+
+OUI:000B72*
+ ID_OUI_FROM_DATABASE=Lawo AG
+
+OUI:000B73*
+ ID_OUI_FROM_DATABASE=Kodeos Communications
+
+OUI:000B74*
+ ID_OUI_FROM_DATABASE=Kingwave Technology Co., Ltd.
+
+OUI:000B75*
+ ID_OUI_FROM_DATABASE=Iosoft Ltd.
+
+OUI:000B76*
+ ID_OUI_FROM_DATABASE=ET&T Technology Co. Ltd.
+
+OUI:000B77*
+ ID_OUI_FROM_DATABASE=Cogent Systems, Inc.
+
+OUI:000B78*
+ ID_OUI_FROM_DATABASE=TAIFATECH INC.
+
+OUI:000B79*
+ ID_OUI_FROM_DATABASE=X-COM, Inc.
+
+OUI:000B7A*
+ ID_OUI_FROM_DATABASE=Wave Science Inc.
+
+OUI:000B7B*
+ ID_OUI_FROM_DATABASE=Test-Um Inc.
+
+OUI:000B7C*
+ ID_OUI_FROM_DATABASE=Telex Communications
+
+OUI:000B7D*
+ ID_OUI_FROM_DATABASE=SOLOMON EXTREME INTERNATIONAL LTD.
+
+OUI:000B7E*
+ ID_OUI_FROM_DATABASE=SAGINOMIYA Seisakusho Inc.
+
+OUI:000B7F*
+ ID_OUI_FROM_DATABASE=Align Engineering LLC
+
+OUI:000B80*
+ ID_OUI_FROM_DATABASE=Lycium Networks
+
+OUI:000B81*
+ ID_OUI_FROM_DATABASE=Kaparel Corporation
+
+OUI:000B82*
+ ID_OUI_FROM_DATABASE=Grandstream Networks, Inc.
+
+OUI:000B83*
+ ID_OUI_FROM_DATABASE=DATAWATT B.V.
+
+OUI:000B84*
+ ID_OUI_FROM_DATABASE=BODET
+
+OUI:000B85*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000B86*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
+OUI:000B87*
+ ID_OUI_FROM_DATABASE=American Reliance Inc.
+
+OUI:000B88*
+ ID_OUI_FROM_DATABASE=Vidisco ltd.
+
+OUI:000B89*
+ ID_OUI_FROM_DATABASE=Top Global Technology, Ltd.
+
+OUI:000B8A*
+ ID_OUI_FROM_DATABASE=MITEQ Inc.
+
+OUI:000B8B*
+ ID_OUI_FROM_DATABASE=KERAJET, S.A.
+
+OUI:000B8C*
+ ID_OUI_FROM_DATABASE=Flextronics
+
+OUI:000B8D*
+ ID_OUI_FROM_DATABASE=Avvio Networks
+
+OUI:000B8E*
+ ID_OUI_FROM_DATABASE=Ascent Corporation
+
+OUI:000B8F*
+ ID_OUI_FROM_DATABASE=AKITA ELECTRONICS SYSTEMS CO.,LTD.
+
+OUI:000B90*
+ ID_OUI_FROM_DATABASE=Adva Optical Networking Inc.
+
+OUI:000B91*
+ ID_OUI_FROM_DATABASE=Aglaia Gesellschaft für Bildverarbeitung und Kommunikation mbH
+
+OUI:000B92*
+ ID_OUI_FROM_DATABASE=Ascom Danmark A/S
+
+OUI:000B93*
+ ID_OUI_FROM_DATABASE=Ritter Elektronik
+
+OUI:000B94*
+ ID_OUI_FROM_DATABASE=Digital Monitoring Products, Inc.
+
+OUI:000B95*
+ ID_OUI_FROM_DATABASE=eBet Gaming Systems Pty Ltd
+
+OUI:000B96*
+ ID_OUI_FROM_DATABASE=Innotrac Diagnostics Oy
+
+OUI:000B97*
+ ID_OUI_FROM_DATABASE=Matsushita Electric Industrial Co.,Ltd.
+
+OUI:000B98*
+ ID_OUI_FROM_DATABASE=NiceTechVision
+
+OUI:000B99*
+ ID_OUI_FROM_DATABASE=SensAble Technologies, Inc.
+
+OUI:000B9A*
+ ID_OUI_FROM_DATABASE=Shanghai Ulink Telecom Equipment Co. Ltd.
+
+OUI:000B9B*
+ ID_OUI_FROM_DATABASE=Sirius System Co, Ltd.
+
+OUI:000B9C*
+ ID_OUI_FROM_DATABASE=TriBeam Technologies, Inc.
+
+OUI:000B9D*
+ ID_OUI_FROM_DATABASE=TwinMOS Technologies Inc.
+
+OUI:000B9E*
+ ID_OUI_FROM_DATABASE=Yasing Technology Corp.
+
+OUI:000B9F*
+ ID_OUI_FROM_DATABASE=Neue ELSA GmbH
+
+OUI:000BA0*
+ ID_OUI_FROM_DATABASE=T&L Information Inc.
+
+OUI:000BA1*
+ ID_OUI_FROM_DATABASE=SYSCOM Ltd.
+
+OUI:000BA2*
+ ID_OUI_FROM_DATABASE=Sumitomo Electric Networks, Inc
+
+OUI:000BA3*
+ ID_OUI_FROM_DATABASE=Siemens AG, I&S
+
+OUI:000BA4*
+ ID_OUI_FROM_DATABASE=Shiron Satellite Communications Ltd. (1996)
+
+OUI:000BA5*
+ ID_OUI_FROM_DATABASE=Quasar Cipta Mandiri, PT
+
+OUI:000BA6*
+ ID_OUI_FROM_DATABASE=Miyakawa Electric Works Ltd.
+
+OUI:000BA7*
+ ID_OUI_FROM_DATABASE=Maranti Networks
+
+OUI:000BA8*
+ ID_OUI_FROM_DATABASE=HANBACK ELECTRONICS CO., LTD.
+
+OUI:000BA9*
+ ID_OUI_FROM_DATABASE=CloudShield Technologies, Inc.
+
+OUI:000BAA*
+ ID_OUI_FROM_DATABASE=Aiphone co.,Ltd
+
+OUI:000BAB*
+ ID_OUI_FROM_DATABASE=Advantech Technology (CHINA) Co., Ltd.
+
+OUI:000BAC*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:000BAD*
+ ID_OUI_FROM_DATABASE=PC-PoS Inc.
+
+OUI:000BAE*
+ ID_OUI_FROM_DATABASE=Vitals System Inc.
+
+OUI:000BAF*
+ ID_OUI_FROM_DATABASE=WOOJU COMMUNICATIONS Co,.Ltd
+
+OUI:000BB0*
+ ID_OUI_FROM_DATABASE=Sysnet Telematica srl
+
+OUI:000BB1*
+ ID_OUI_FROM_DATABASE=Super Star Technology Co., Ltd.
+
+OUI:000BB2*
+ ID_OUI_FROM_DATABASE=SMALLBIG TECHNOLOGY
+
+OUI:000BB3*
+ ID_OUI_FROM_DATABASE=RiT technologies Ltd.
+
+OUI:000BB4*
+ ID_OUI_FROM_DATABASE=RDC Semiconductor Inc.,
+
+OUI:000BB5*
+ ID_OUI_FROM_DATABASE=nStor Technologies, Inc.
+
+OUI:000BB6*
+ ID_OUI_FROM_DATABASE=Metalligence Technology Corp.
+
+OUI:000BB7*
+ ID_OUI_FROM_DATABASE=Micro Systems Co.,Ltd.
+
+OUI:000BB8*
+ ID_OUI_FROM_DATABASE=Kihoku Electronic Co.
+
+OUI:000BB9*
+ ID_OUI_FROM_DATABASE=Imsys AB
+
+OUI:000BBA*
+ ID_OUI_FROM_DATABASE=Harmonic, Inc
+
+OUI:000BBB*
+ ID_OUI_FROM_DATABASE=Etin Systems Co., Ltd
+
+OUI:000BBC*
+ ID_OUI_FROM_DATABASE=En Garde Systems, Inc.
+
+OUI:000BBD*
+ ID_OUI_FROM_DATABASE=Connexionz Limited
+
+OUI:000BBE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000BBF*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000BC0*
+ ID_OUI_FROM_DATABASE=China IWNComm Co., Ltd.
+
+OUI:000BC1*
+ ID_OUI_FROM_DATABASE=Bay Microsystems, Inc.
+
+OUI:000BC2*
+ ID_OUI_FROM_DATABASE=Corinex Communication Corp.
+
+OUI:000BC3*
+ ID_OUI_FROM_DATABASE=Multiplex, Inc.
+
+OUI:000BC4*
+ ID_OUI_FROM_DATABASE=BIOTRONIK GmbH & Co
+
+OUI:000BC5*
+ ID_OUI_FROM_DATABASE=SMC Networks, Inc.
+
+OUI:000BC6*
+ ID_OUI_FROM_DATABASE=ISAC, Inc.
+
+OUI:000BC7*
+ ID_OUI_FROM_DATABASE=ICET S.p.A.
+
+OUI:000BC8*
+ ID_OUI_FROM_DATABASE=AirFlow Networks
+
+OUI:000BC9*
+ ID_OUI_FROM_DATABASE=Electroline Equipment
+
+OUI:000BCA*
+ ID_OUI_FROM_DATABASE=DATAVAN International Corporation
+
+OUI:000BCB*
+ ID_OUI_FROM_DATABASE=Fagor Automation , S. Coop
+
+OUI:000BCC*
+ ID_OUI_FROM_DATABASE=JUSAN, S.A.
+
+OUI:000BCD*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:000BCE*
+ ID_OUI_FROM_DATABASE=Free2move AB
+
+OUI:000BCF*
+ ID_OUI_FROM_DATABASE=AGFA NDT INC.
+
+OUI:000BD0*
+ ID_OUI_FROM_DATABASE=XiMeta Technology Americas Inc.
+
+OUI:000BD1*
+ ID_OUI_FROM_DATABASE=Aeronix, Inc.
+
+OUI:000BD2*
+ ID_OUI_FROM_DATABASE=Remopro Technology Inc.
+
+OUI:000BD3*
+ ID_OUI_FROM_DATABASE=cd3o
+
+OUI:000BD4*
+ ID_OUI_FROM_DATABASE=Beijing Wise Technology & Science Development Co.Ltd
+
+OUI:000BD5*
+ ID_OUI_FROM_DATABASE=Nvergence, Inc.
+
+OUI:000BD6*
+ ID_OUI_FROM_DATABASE=Paxton Access Ltd
+
+OUI:000BD7*
+ ID_OUI_FROM_DATABASE=DORMA Time + Access GmbH
+
+OUI:000BD8*
+ ID_OUI_FROM_DATABASE=Industrial Scientific Corp.
+
+OUI:000BD9*
+ ID_OUI_FROM_DATABASE=General Hydrogen
+
+OUI:000BDA*
+ ID_OUI_FROM_DATABASE=EyeCross Co.,Inc.
+
+OUI:000BDB*
+ ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+
+OUI:000BDC*
+ ID_OUI_FROM_DATABASE=AKCP
+
+OUI:000BDD*
+ ID_OUI_FROM_DATABASE=TOHOKU RICOH Co., LTD.
+
+OUI:000BDE*
+ ID_OUI_FROM_DATABASE=TELDIX GmbH
+
+OUI:000BDF*
+ ID_OUI_FROM_DATABASE=Shenzhen RouterD Networks Limited
+
+OUI:000BE0*
+ ID_OUI_FROM_DATABASE=SercoNet Ltd.
+
+OUI:000BE1*
+ ID_OUI_FROM_DATABASE=Nokia NET Product Operations
+
+OUI:000BE2*
+ ID_OUI_FROM_DATABASE=Lumenera Corporation
+
+OUI:000BE3*
+ ID_OUI_FROM_DATABASE=Key Stream Co., Ltd.
+
+OUI:000BE4*
+ ID_OUI_FROM_DATABASE=Hosiden Corporation
+
+OUI:000BE5*
+ ID_OUI_FROM_DATABASE=HIMS Korea Co., Ltd.
+
+OUI:000BE6*
+ ID_OUI_FROM_DATABASE=Datel Electronics
+
+OUI:000BE7*
+ ID_OUI_FROM_DATABASE=COMFLUX TECHNOLOGY INC.
+
+OUI:000BE8*
+ ID_OUI_FROM_DATABASE=AOIP
+
+OUI:000BE9*
+ ID_OUI_FROM_DATABASE=Actel Corporation
+
+OUI:000BEA*
+ ID_OUI_FROM_DATABASE=Zultys Technologies
+
+OUI:000BEB*
+ ID_OUI_FROM_DATABASE=Systegra AG
+
+OUI:000BEC*
+ ID_OUI_FROM_DATABASE=NIPPON ELECTRIC INSTRUMENT, INC.
+
+OUI:000BED*
+ ID_OUI_FROM_DATABASE=ELM Inc.
+
+OUI:000BEE*
+ ID_OUI_FROM_DATABASE=inc.jet, Incorporated
+
+OUI:000BEF*
+ ID_OUI_FROM_DATABASE=Code Corporation
+
+OUI:000BF0*
+ ID_OUI_FROM_DATABASE=MoTEX Products Co., Ltd.
+
+OUI:000BF1*
+ ID_OUI_FROM_DATABASE=LAP Laser Applikations
+
+OUI:000BF2*
+ ID_OUI_FROM_DATABASE=Chih-Kan Technology Co., Ltd.
+
+OUI:000BF3*
+ ID_OUI_FROM_DATABASE=BAE SYSTEMS
+
+OUI:000BF5*
+ ID_OUI_FROM_DATABASE=Shanghai Sibo Telecom Technology Co.,Ltd
+
+OUI:000BF6*
+ ID_OUI_FROM_DATABASE=Nitgen Co., Ltd
+
+OUI:000BF7*
+ ID_OUI_FROM_DATABASE=NIDEK CO.,LTD
+
+OUI:000BF8*
+ ID_OUI_FROM_DATABASE=Infinera
+
+OUI:000BF9*
+ ID_OUI_FROM_DATABASE=Gemstone communications, Inc.
+
+OUI:000BFA*
+ ID_OUI_FROM_DATABASE=EXEMYS SRL
+
+OUI:000BFB*
+ ID_OUI_FROM_DATABASE=D-NET International Corporation
+
+OUI:000BFC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000BFD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000BFE*
+ ID_OUI_FROM_DATABASE=CASTEL Broadband Limited
+
+OUI:000BFF*
+ ID_OUI_FROM_DATABASE=Berkeley Camera Engineering
+
+OUI:000C00*
+ ID_OUI_FROM_DATABASE=BEB Industrie-Elektronik AG
+
+OUI:000C01*
+ ID_OUI_FROM_DATABASE=Abatron AG
+
+OUI:000C02*
+ ID_OUI_FROM_DATABASE=ABB Oy
+
+OUI:000C03*
+ ID_OUI_FROM_DATABASE=HDMI Licensing, LLC
+
+OUI:000C04*
+ ID_OUI_FROM_DATABASE=Tecnova
+
+OUI:000C05*
+ ID_OUI_FROM_DATABASE=RPA Reserch Co., Ltd.
+
+OUI:000C06*
+ ID_OUI_FROM_DATABASE=Nixvue Systems  Pte Ltd
+
+OUI:000C07*
+ ID_OUI_FROM_DATABASE=Iftest AG
+
+OUI:000C08*
+ ID_OUI_FROM_DATABASE=HUMEX Technologies Corp.
+
+OUI:000C09*
+ ID_OUI_FROM_DATABASE=Hitachi IE Systems Co., Ltd
+
+OUI:000C0A*
+ ID_OUI_FROM_DATABASE=Guangdong Province Electronic Technology Research Institute
+
+OUI:000C0B*
+ ID_OUI_FROM_DATABASE=Broadbus Technologies
+
+OUI:000C0C*
+ ID_OUI_FROM_DATABASE=APPRO TECHNOLOGY INC.
+
+OUI:000C0D*
+ ID_OUI_FROM_DATABASE=Communications & Power Industries / Satcom Division
+
+OUI:000C0E*
+ ID_OUI_FROM_DATABASE=XtremeSpectrum, Inc.
+
+OUI:000C0F*
+ ID_OUI_FROM_DATABASE=Techno-One Co., Ltd
+
+OUI:000C10*
+ ID_OUI_FROM_DATABASE=PNI Corporation
+
+OUI:000C11*
+ ID_OUI_FROM_DATABASE=NIPPON DEMPA CO.,LTD.
+
+OUI:000C12*
+ ID_OUI_FROM_DATABASE=Micro-Optronic-Messtechnik GmbH
+
+OUI:000C13*
+ ID_OUI_FROM_DATABASE=MediaQ
+
+OUI:000C14*
+ ID_OUI_FROM_DATABASE=Diagnostic Instruments, Inc.
+
+OUI:000C15*
+ ID_OUI_FROM_DATABASE=CyberPower Systems, Inc.
+
+OUI:000C16*
+ ID_OUI_FROM_DATABASE=Concorde Microsystems Inc.
+
+OUI:000C17*
+ ID_OUI_FROM_DATABASE=AJA Video Systems Inc
+
+OUI:000C18*
+ ID_OUI_FROM_DATABASE=Zenisu Keisoku Inc.
+
+OUI:000C19*
+ ID_OUI_FROM_DATABASE=Telio Communications GmbH
+
+OUI:000C1A*
+ ID_OUI_FROM_DATABASE=Quest Technical Solutions Inc.
+
+OUI:000C1B*
+ ID_OUI_FROM_DATABASE=ORACOM Co, Ltd.
+
+OUI:000C1C*
+ ID_OUI_FROM_DATABASE=MicroWeb Co., Ltd.
+
+OUI:000C1D*
+ ID_OUI_FROM_DATABASE=Mettler & Fuchs AG
+
+OUI:000C1E*
+ ID_OUI_FROM_DATABASE=Global Cache
+
+OUI:000C1F*
+ ID_OUI_FROM_DATABASE=Glimmerglass Networks
+
+OUI:000C20*
+ ID_OUI_FROM_DATABASE=Fi WIn, Inc.
+
+OUI:000C21*
+ ID_OUI_FROM_DATABASE=Faculty of Science and Technology, Keio University
+
+OUI:000C22*
+ ID_OUI_FROM_DATABASE=Double D Electronics Ltd
+
+OUI:000C23*
+ ID_OUI_FROM_DATABASE=Beijing Lanchuan Tech. Co., Ltd.
+
+OUI:000C24*
+ ID_OUI_FROM_DATABASE=ANATOR
+
+OUI:000C25*
+ ID_OUI_FROM_DATABASE=Allied Telesis Labs, Inc.
+
+OUI:000C26*
+ ID_OUI_FROM_DATABASE=Weintek Labs. Inc.
+
+OUI:000C27*
+ ID_OUI_FROM_DATABASE=Sammy Corporation
+
+OUI:000C28*
+ ID_OUI_FROM_DATABASE=RIFATRON
+
+OUI:000C29*
+ ID_OUI_FROM_DATABASE=VMware, Inc.
+
+OUI:000C2A*
+ ID_OUI_FROM_DATABASE=OCTTEL Communication Co., Ltd.
+
+OUI:000C2B*
+ ID_OUI_FROM_DATABASE=ELIAS Technology, Inc.
+
+OUI:000C2C*
+ ID_OUI_FROM_DATABASE=Enwiser Inc.
+
+OUI:000C2D*
+ ID_OUI_FROM_DATABASE=FullWave Technology Co., Ltd.
+
+OUI:000C2E*
+ ID_OUI_FROM_DATABASE=Openet information technology(shenzhen) Co., Ltd.
+
+OUI:000C2F*
+ ID_OUI_FROM_DATABASE=SeorimTechnology Co.,Ltd.
+
+OUI:000C30*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000C31*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000C32*
+ ID_OUI_FROM_DATABASE=Avionic Design Development GmbH
+
+OUI:000C33*
+ ID_OUI_FROM_DATABASE=Compucase Enterprise Co. Ltd.
+
+OUI:000C34*
+ ID_OUI_FROM_DATABASE=Vixen Co., Ltd.
+
+OUI:000C35*
+ ID_OUI_FROM_DATABASE=KaVo Dental GmbH & Co. KG
+
+OUI:000C36*
+ ID_OUI_FROM_DATABASE=SHARP TAKAYA ELECTRONICS INDUSTRY CO.,LTD.
+
+OUI:000C37*
+ ID_OUI_FROM_DATABASE=Geomation, Inc.
+
+OUI:000C38*
+ ID_OUI_FROM_DATABASE=TelcoBridges Inc.
+
+OUI:000C39*
+ ID_OUI_FROM_DATABASE=Sentinel Wireless Inc.
+
+OUI:000C3A*
+ ID_OUI_FROM_DATABASE=Oxance
+
+OUI:000C3B*
+ ID_OUI_FROM_DATABASE=Orion Electric Co., Ltd.
+
+OUI:000C3C*
+ ID_OUI_FROM_DATABASE=MediaChorus, Inc.
+
+OUI:000C3D*
+ ID_OUI_FROM_DATABASE=Glsystech Co., Ltd.
+
+OUI:000C3E*
+ ID_OUI_FROM_DATABASE=Crest Audio
+
+OUI:000C3F*
+ ID_OUI_FROM_DATABASE=Cogent Defence & Security Networks,
+
+OUI:000C40*
+ ID_OUI_FROM_DATABASE=Altech Controls
+
+OUI:000C41*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys
+
+OUI:000C42*
+ ID_OUI_FROM_DATABASE=Routerboard.com
+
+OUI:000C43*
+ ID_OUI_FROM_DATABASE=Ralink Technology, Corp.
+
+OUI:000C44*
+ ID_OUI_FROM_DATABASE=Automated Interfaces, Inc.
+
+OUI:000C45*
+ ID_OUI_FROM_DATABASE=Animation Technologies Inc.
+
+OUI:000C46*
+ ID_OUI_FROM_DATABASE=Allied Telesyn Inc.
+
+OUI:000C47*
+ ID_OUI_FROM_DATABASE=SK Teletech(R&D Planning Team)
+
+OUI:000C48*
+ ID_OUI_FROM_DATABASE=QoStek Corporation
+
+OUI:000C49*
+ ID_OUI_FROM_DATABASE=Dangaard Telecom RTC Division A/S
+
+OUI:000C4A*
+ ID_OUI_FROM_DATABASE=Cygnus Microsystems (P) Limited
+
+OUI:000C4B*
+ ID_OUI_FROM_DATABASE=Cheops Elektronik
+
+OUI:000C4C*
+ ID_OUI_FROM_DATABASE=Arcor AG&Co.
+
+OUI:000C4D*
+ ID_OUI_FROM_DATABASE=ACRA CONTROL
+
+OUI:000C4E*
+ ID_OUI_FROM_DATABASE=Winbest Technology CO,LT
+
+OUI:000C4F*
+ ID_OUI_FROM_DATABASE=UDTech Japan Corporation
+
+OUI:000C50*
+ ID_OUI_FROM_DATABASE=Seagate Technology
+
+OUI:000C51*
+ ID_OUI_FROM_DATABASE=Scientific Technologies Inc.
+
+OUI:000C52*
+ ID_OUI_FROM_DATABASE=Roll Systems Inc.
+
+OUI:000C54*
+ ID_OUI_FROM_DATABASE=Pedestal Networks, Inc
+
+OUI:000C55*
+ ID_OUI_FROM_DATABASE=Microlink Communications Inc.
+
+OUI:000C56*
+ ID_OUI_FROM_DATABASE=Megatel Computer (1986) Corp.
+
+OUI:000C57*
+ ID_OUI_FROM_DATABASE=MACKIE Engineering Services Belgium BVBA
+
+OUI:000C58*
+ ID_OUI_FROM_DATABASE=M&S Systems
+
+OUI:000C59*
+ ID_OUI_FROM_DATABASE=Indyme Electronics, Inc.
+
+OUI:000C5A*
+ ID_OUI_FROM_DATABASE=IBSmm Industrieelektronik Multimedia
+
+OUI:000C5B*
+ ID_OUI_FROM_DATABASE=HANWANG TECHNOLOGY CO.,LTD
+
+OUI:000C5C*
+ ID_OUI_FROM_DATABASE=GTN Systems B.V.
+
+OUI:000C5D*
+ ID_OUI_FROM_DATABASE=CHIC TECHNOLOGY (CHINA) CORP.
+
+OUI:000C5E*
+ ID_OUI_FROM_DATABASE=Calypso Medical
+
+OUI:000C5F*
+ ID_OUI_FROM_DATABASE=Avtec, Inc.
+
+OUI:000C60*
+ ID_OUI_FROM_DATABASE=ACM Systems
+
+OUI:000C61*
+ ID_OUI_FROM_DATABASE=AC Tech corporation DBA Advanced Digital
+
+OUI:000C62*
+ ID_OUI_FROM_DATABASE=ABB AB, Cewe-Control
+
+OUI:000C63*
+ ID_OUI_FROM_DATABASE=Zenith Electronics Corporation
+
+OUI:000C64*
+ ID_OUI_FROM_DATABASE=X2 MSA Group
+
+OUI:000C65*
+ ID_OUI_FROM_DATABASE=Sunin Telecom
+
+OUI:000C66*
+ ID_OUI_FROM_DATABASE=Pronto Networks Inc
+
+OUI:000C67*
+ ID_OUI_FROM_DATABASE=OYO ELECTRIC CO.,LTD
+
+OUI:000C68*
+ ID_OUI_FROM_DATABASE=SigmaTel, Inc.
+
+OUI:000C69*
+ ID_OUI_FROM_DATABASE=National Radio Astronomy Observatory
+
+OUI:000C6A*
+ ID_OUI_FROM_DATABASE=MBARI
+
+OUI:000C6B*
+ ID_OUI_FROM_DATABASE=Kurz Industrie-Elektronik GmbH
+
+OUI:000C6C*
+ ID_OUI_FROM_DATABASE=Elgato Systems LLC
+
+OUI:000C6D*
+ ID_OUI_FROM_DATABASE=Edwards Ltd.
+
+OUI:000C6E*
+ ID_OUI_FROM_DATABASE=ASUSTEK COMPUTER INC.
+
+OUI:000C6F*
+ ID_OUI_FROM_DATABASE=Amtek system co.,LTD.
+
+OUI:000C70*
+ ID_OUI_FROM_DATABASE=ACC GmbH
+
+OUI:000C71*
+ ID_OUI_FROM_DATABASE=Wybron, Inc
+
+OUI:000C72*
+ ID_OUI_FROM_DATABASE=Tempearl Industrial Co., Ltd.
+
+OUI:000C73*
+ ID_OUI_FROM_DATABASE=TELSON ELECTRONICS CO., LTD
+
+OUI:000C74*
+ ID_OUI_FROM_DATABASE=RIVERTEC CORPORATION
+
+OUI:000C75*
+ ID_OUI_FROM_DATABASE=Oriental integrated electronics. LTD
+
+OUI:000C76*
+ ID_OUI_FROM_DATABASE=MICRO-STAR INTERNATIONAL CO., LTD.
+
+OUI:000C77*
+ ID_OUI_FROM_DATABASE=Life Racing Ltd
+
+OUI:000C78*
+ ID_OUI_FROM_DATABASE=In-Tech Electronics Limited
+
+OUI:000C79*
+ ID_OUI_FROM_DATABASE=Extel Communications P/L
+
+OUI:000C7A*
+ ID_OUI_FROM_DATABASE=DaTARIUS Technologies GmbH
+
+OUI:000C7B*
+ ID_OUI_FROM_DATABASE=ALPHA PROJECT Co.,Ltd.
+
+OUI:000C7C*
+ ID_OUI_FROM_DATABASE=Internet Information Image Inc.
+
+OUI:000C7D*
+ ID_OUI_FROM_DATABASE=TEIKOKU ELECTRIC MFG. CO., LTD
+
+OUI:000C7E*
+ ID_OUI_FROM_DATABASE=Tellium Incorporated
+
+OUI:000C7F*
+ ID_OUI_FROM_DATABASE=synertronixx GmbH
+
+OUI:000C80*
+ ID_OUI_FROM_DATABASE=Opelcomm Inc.
+
+OUI:000C81*
+ ID_OUI_FROM_DATABASE=Schneider Electric (Australia)
+
+OUI:000C82*
+ ID_OUI_FROM_DATABASE=NETWORK TECHNOLOGIES INC
+
+OUI:000C83*
+ ID_OUI_FROM_DATABASE=Logical Solutions
+
+OUI:000C84*
+ ID_OUI_FROM_DATABASE=Eazix, Inc.
+
+OUI:000C85*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000C86*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000C87*
+ ID_OUI_FROM_DATABASE=AMD
+
+OUI:000C88*
+ ID_OUI_FROM_DATABASE=Apache Micro Peripherals, Inc.
+
+OUI:000C89*
+ ID_OUI_FROM_DATABASE=AC Electric Vehicles, Ltd.
+
+OUI:000C8A*
+ ID_OUI_FROM_DATABASE=Bose Corporation
+
+OUI:000C8B*
+ ID_OUI_FROM_DATABASE=Connect Tech Inc
+
+OUI:000C8C*
+ ID_OUI_FROM_DATABASE=KODICOM CO.,LTD.
+
+OUI:000C8D*
+ ID_OUI_FROM_DATABASE=MATRIX VISION GmbH
+
+OUI:000C8E*
+ ID_OUI_FROM_DATABASE=Mentor Engineering Inc
+
+OUI:000C8F*
+ ID_OUI_FROM_DATABASE=Nergal s.r.l.
+
+OUI:000C90*
+ ID_OUI_FROM_DATABASE=Octasic Inc.
+
+OUI:000C91*
+ ID_OUI_FROM_DATABASE=Riverhead Networks Inc.
+
+OUI:000C92*
+ ID_OUI_FROM_DATABASE=WolfVision Gmbh
+
+OUI:000C93*
+ ID_OUI_FROM_DATABASE=Xeline Co., Ltd.
+
+OUI:000C94*
+ ID_OUI_FROM_DATABASE=United Electronic Industries, Inc. (EUI)
+
+OUI:000C95*
+ ID_OUI_FROM_DATABASE=PrimeNet
+
+OUI:000C96*
+ ID_OUI_FROM_DATABASE=OQO, Inc.
+
+OUI:000C97*
+ ID_OUI_FROM_DATABASE=NV ADB TTV Technologies SA
+
+OUI:000C98*
+ ID_OUI_FROM_DATABASE=LETEK Communications Inc.
+
+OUI:000C99*
+ ID_OUI_FROM_DATABASE=HITEL LINK Co.,Ltd
+
+OUI:000C9A*
+ ID_OUI_FROM_DATABASE=Hitech Electronics Corp.
+
+OUI:000C9B*
+ ID_OUI_FROM_DATABASE=EE Solutions, Inc
+
+OUI:000C9C*
+ ID_OUI_FROM_DATABASE=Chongho information & communications
+
+OUI:000C9D*
+ ID_OUI_FROM_DATABASE=AirWalk Communications, Inc.
+
+OUI:000C9E*
+ ID_OUI_FROM_DATABASE=MemoryLink Corp.
+
+OUI:000C9F*
+ ID_OUI_FROM_DATABASE=NKE Corporation
+
+OUI:000CA0*
+ ID_OUI_FROM_DATABASE=StorCase Technology, Inc.
+
+OUI:000CA1*
+ ID_OUI_FROM_DATABASE=SIGMACOM Co., LTD.
+
+OUI:000CA2*
+ ID_OUI_FROM_DATABASE=Harmonic Video Network
+
+OUI:000CA3*
+ ID_OUI_FROM_DATABASE=Rancho Technology, Inc.
+
+OUI:000CA4*
+ ID_OUI_FROM_DATABASE=Prompttec Product Management GmbH
+
+OUI:000CA5*
+ ID_OUI_FROM_DATABASE=Naman NZ LTd
+
+OUI:000CA6*
+ ID_OUI_FROM_DATABASE=Mintera Corporation
+
+OUI:000CA7*
+ ID_OUI_FROM_DATABASE=Metro (Suzhou) Technologies Co., Ltd.
+
+OUI:000CA8*
+ ID_OUI_FROM_DATABASE=Garuda Networks Corporation
+
+OUI:000CA9*
+ ID_OUI_FROM_DATABASE=Ebtron Inc.
+
+OUI:000CAA*
+ ID_OUI_FROM_DATABASE=Cubic Transportation Systems Inc
+
+OUI:000CAB*
+ ID_OUI_FROM_DATABASE=COMMEND International
+
+OUI:000CAC*
+ ID_OUI_FROM_DATABASE=Citizen Watch Co., Ltd.
+
+OUI:000CAD*
+ ID_OUI_FROM_DATABASE=BTU International
+
+OUI:000CAE*
+ ID_OUI_FROM_DATABASE=Ailocom Oy
+
+OUI:000CAF*
+ ID_OUI_FROM_DATABASE=TRI TERM CO.,LTD.
+
+OUI:000CB0*
+ ID_OUI_FROM_DATABASE=Star Semiconductor Corporation
+
+OUI:000CB1*
+ ID_OUI_FROM_DATABASE=Salland Engineering (Europe) BV
+
+OUI:000CB2*
+ ID_OUI_FROM_DATABASE=Comstar Co., Ltd.
+
+OUI:000CB3*
+ ID_OUI_FROM_DATABASE=ROUND Co.,Ltd.
+
+OUI:000CB4*
+ ID_OUI_FROM_DATABASE=AutoCell Laboratories, Inc.
+
+OUI:000CB5*
+ ID_OUI_FROM_DATABASE=Premier Technolgies, Inc
+
+OUI:000CB6*
+ ID_OUI_FROM_DATABASE=NANJING SEU MOBILE & INTERNET TECHNOLOGY CO.,LTD
+
+OUI:000CB7*
+ ID_OUI_FROM_DATABASE=Nanjing Huazhuo Electronics Co., Ltd.
+
+OUI:000CB8*
+ ID_OUI_FROM_DATABASE=MEDION AG
+
+OUI:000CB9*
+ ID_OUI_FROM_DATABASE=LEA
+
+OUI:000CBA*
+ ID_OUI_FROM_DATABASE=Jamex, Inc.
+
+OUI:000CBB*
+ ID_OUI_FROM_DATABASE=ISKRAEMECO
+
+OUI:000CBC*
+ ID_OUI_FROM_DATABASE=Iscutum
+
+OUI:000CBD*
+ ID_OUI_FROM_DATABASE=Interface Masters, Inc
+
+OUI:000CBE*
+ ID_OUI_FROM_DATABASE=Innominate Security Technologies AG
+
+OUI:000CBF*
+ ID_OUI_FROM_DATABASE=Holy Stone Ent. Co., Ltd.
+
+OUI:000CC0*
+ ID_OUI_FROM_DATABASE=Genera Oy
+
+OUI:000CC1*
+ ID_OUI_FROM_DATABASE=Cooper Industries Inc.
+
+OUI:000CC2*
+ ID_OUI_FROM_DATABASE=ControlNet (India) Private Limited
+
+OUI:000CC3*
+ ID_OUI_FROM_DATABASE=BeWAN systems
+
+OUI:000CC4*
+ ID_OUI_FROM_DATABASE=Tiptel AG
+
+OUI:000CC5*
+ ID_OUI_FROM_DATABASE=Nextlink Co., Ltd.
+
+OUI:000CC6*
+ ID_OUI_FROM_DATABASE=Ka-Ro electronics GmbH
+
+OUI:000CC7*
+ ID_OUI_FROM_DATABASE=Intelligent Computer Solutions Inc.
+
+OUI:000CC8*
+ ID_OUI_FROM_DATABASE=Xytronix Research & Design, Inc.
+
+OUI:000CC9*
+ ID_OUI_FROM_DATABASE=ILWOO DATA & TECHNOLOGY CO.,LTD
+
+OUI:000CCA*
+ ID_OUI_FROM_DATABASE=HGST a Western Digital Company
+
+OUI:000CCB*
+ ID_OUI_FROM_DATABASE=Design Combus Ltd
+
+OUI:000CCC*
+ ID_OUI_FROM_DATABASE=Aeroscout Ltd.
+
+OUI:000CCD*
+ ID_OUI_FROM_DATABASE=IEC - TC57
+
+OUI:000CCE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000CCF*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000CD0*
+ ID_OUI_FROM_DATABASE=Symetrix
+
+OUI:000CD1*
+ ID_OUI_FROM_DATABASE=SFOM Technology Corp.
+
+OUI:000CD2*
+ ID_OUI_FROM_DATABASE=Schaffner EMV AG
+
+OUI:000CD3*
+ ID_OUI_FROM_DATABASE=Prettl Elektronik Radeberg GmbH
+
+OUI:000CD4*
+ ID_OUI_FROM_DATABASE=Positron Public Safety Systems inc.
+
+OUI:000CD5*
+ ID_OUI_FROM_DATABASE=Passave Inc.
+
+OUI:000CD6*
+ ID_OUI_FROM_DATABASE=PARTNER TECH
+
+OUI:000CD7*
+ ID_OUI_FROM_DATABASE=Nallatech Ltd
+
+OUI:000CD8*
+ ID_OUI_FROM_DATABASE=M. K. Juchheim GmbH & Co
+
+OUI:000CD9*
+ ID_OUI_FROM_DATABASE=Itcare Co., Ltd
+
+OUI:000CDA*
+ ID_OUI_FROM_DATABASE=FreeHand Systems, Inc.
+
+OUI:000CDB*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc
+
+OUI:000CDC*
+ ID_OUI_FROM_DATABASE=BECS Technology, Inc
+
+OUI:000CDD*
+ ID_OUI_FROM_DATABASE=AOS Technologies AG
+
+OUI:000CDE*
+ ID_OUI_FROM_DATABASE=ABB STOTZ-KONTAKT GmbH
+
+OUI:000CDF*
+ ID_OUI_FROM_DATABASE=PULNiX America, Inc
+
+OUI:000CE0*
+ ID_OUI_FROM_DATABASE=Trek Diagnostics Inc.
+
+OUI:000CE1*
+ ID_OUI_FROM_DATABASE=The Open Group
+
+OUI:000CE2*
+ ID_OUI_FROM_DATABASE=Rolls-Royce
+
+OUI:000CE3*
+ ID_OUI_FROM_DATABASE=Option International N.V.
+
+OUI:000CE4*
+ ID_OUI_FROM_DATABASE=NeuroCom International, Inc.
+
+OUI:000CE5*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:000CE6*
+ ID_OUI_FROM_DATABASE=Meru Networks Inc
+
+OUI:000CE7*
+ ID_OUI_FROM_DATABASE=MediaTek Inc.
+
+OUI:000CE8*
+ ID_OUI_FROM_DATABASE=GuangZhou AnJuBao Co., Ltd
+
+OUI:000CE9*
+ ID_OUI_FROM_DATABASE=BLOOMBERG L.P.
+
+OUI:000CEA*
+ ID_OUI_FROM_DATABASE=aphona Kommunikationssysteme
+
+OUI:000CEB*
+ ID_OUI_FROM_DATABASE=CNMP Networks, Inc.
+
+OUI:000CEC*
+ ID_OUI_FROM_DATABASE=Spectracom Corp.
+
+OUI:000CED*
+ ID_OUI_FROM_DATABASE=Real Digital Media
+
+OUI:000CEE*
+ ID_OUI_FROM_DATABASE=jp-embedded
+
+OUI:000CEF*
+ ID_OUI_FROM_DATABASE=Open Networks Engineering Ltd
+
+OUI:000CF0*
+ ID_OUI_FROM_DATABASE=M & N GmbH
+
+OUI:000CF1*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:000CF2*
+ ID_OUI_FROM_DATABASE=GAMESA Eólica
+
+OUI:000CF3*
+ ID_OUI_FROM_DATABASE=CALL IMAGE SA
+
+OUI:000CF4*
+ ID_OUI_FROM_DATABASE=AKATSUKI ELECTRIC MFG.CO.,LTD.
+
+OUI:000CF5*
+ ID_OUI_FROM_DATABASE=InfoExpress
+
+OUI:000CF6*
+ ID_OUI_FROM_DATABASE=Sitecom Europe BV
+
+OUI:000CF7*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000CF8*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000CF9*
+ ID_OUI_FROM_DATABASE=ITT Flygt AB
+
+OUI:000CFA*
+ ID_OUI_FROM_DATABASE=Digital Systems Corp
+
+OUI:000CFB*
+ ID_OUI_FROM_DATABASE=Korea Network Systems
+
+OUI:000CFC*
+ ID_OUI_FROM_DATABASE=S2io Technologies Corp
+
+OUI:000CFD*
+ ID_OUI_FROM_DATABASE=Hyundai ImageQuest Co.,Ltd.
+
+OUI:000CFE*
+ ID_OUI_FROM_DATABASE=Grand Electronic Co., Ltd
+
+OUI:000CFF*
+ ID_OUI_FROM_DATABASE=MRO-TEK LIMITED
+
+OUI:000D00*
+ ID_OUI_FROM_DATABASE=Seaway Networks Inc.
+
+OUI:000D01*
+ ID_OUI_FROM_DATABASE=P&E Microcomputer Systems, Inc.
+
+OUI:000D02*
+ ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+
+OUI:000D03*
+ ID_OUI_FROM_DATABASE=Matrics, Inc.
+
+OUI:000D04*
+ ID_OUI_FROM_DATABASE=Foxboro Eckardt Development GmbH
+
+OUI:000D05*
+ ID_OUI_FROM_DATABASE=cybernet manufacturing inc.
+
+OUI:000D06*
+ ID_OUI_FROM_DATABASE=Compulogic Limited
+
+OUI:000D07*
+ ID_OUI_FROM_DATABASE=Calrec Audio Ltd
+
+OUI:000D08*
+ ID_OUI_FROM_DATABASE=AboveCable, Inc.
+
+OUI:000D09*
+ ID_OUI_FROM_DATABASE=Yuehua(Zhuhai) Electronic CO. LTD
+
+OUI:000D0A*
+ ID_OUI_FROM_DATABASE=Projectiondesign as
+
+OUI:000D0B*
+ ID_OUI_FROM_DATABASE=Buffalo Inc.
+
+OUI:000D0C*
+ ID_OUI_FROM_DATABASE=MDI Security Systems
+
+OUI:000D0D*
+ ID_OUI_FROM_DATABASE=ITSupported, LLC
+
+OUI:000D0E*
+ ID_OUI_FROM_DATABASE=Inqnet Systems, Inc.
+
+OUI:000D0F*
+ ID_OUI_FROM_DATABASE=Finlux Ltd
+
+OUI:000D10*
+ ID_OUI_FROM_DATABASE=Embedtronics Oy
+
+OUI:000D11*
+ ID_OUI_FROM_DATABASE=DENTSPLY - Gendex
+
+OUI:000D12*
+ ID_OUI_FROM_DATABASE=AXELL Corporation
+
+OUI:000D13*
+ ID_OUI_FROM_DATABASE=Wilhelm Rutenbeck GmbH&Co.
+
+OUI:000D14*
+ ID_OUI_FROM_DATABASE=Vtech Innovation LP dba Advanced American Telephones
+
+OUI:000D15*
+ ID_OUI_FROM_DATABASE=Voipac s.r.o.
+
+OUI:000D16*
+ ID_OUI_FROM_DATABASE=UHS Systems Pty Ltd
+
+OUI:000D17*
+ ID_OUI_FROM_DATABASE=Turbo Networks Co.Ltd
+
+OUI:000D18*
+ ID_OUI_FROM_DATABASE=Mega-Trend Electronics CO., LTD.
+
+OUI:000D19*
+ ID_OUI_FROM_DATABASE=ROBE Show lighting
+
+OUI:000D1A*
+ ID_OUI_FROM_DATABASE=Mustek System Inc.
+
+OUI:000D1B*
+ ID_OUI_FROM_DATABASE=Kyoto Electronics Manufacturing Co., Ltd.
+
+OUI:000D1C*
+ ID_OUI_FROM_DATABASE=Amesys Defense
+
+OUI:000D1D*
+ ID_OUI_FROM_DATABASE=HIGH-TEK HARNESS ENT. CO., LTD.
+
+OUI:000D1E*
+ ID_OUI_FROM_DATABASE=Control Techniques
+
+OUI:000D1F*
+ ID_OUI_FROM_DATABASE=AV Digital
+
+OUI:000D20*
+ ID_OUI_FROM_DATABASE=ASAHIKASEI TECHNOSYSTEM CO.,LTD.
+
+OUI:000D21*
+ ID_OUI_FROM_DATABASE=WISCORE Inc.
+
+OUI:000D22*
+ ID_OUI_FROM_DATABASE=Unitronics LTD
+
+OUI:000D23*
+ ID_OUI_FROM_DATABASE=Smart Solution, Inc
+
+OUI:000D24*
+ ID_OUI_FROM_DATABASE=SENTEC E&E CO., LTD.
+
+OUI:000D25*
+ ID_OUI_FROM_DATABASE=SANDEN CORPORATION
+
+OUI:000D26*
+ ID_OUI_FROM_DATABASE=Primagraphics Limited
+
+OUI:000D27*
+ ID_OUI_FROM_DATABASE=MICROPLEX Printware AG
+
+OUI:000D28*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000D29*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000D2A*
+ ID_OUI_FROM_DATABASE=Scanmatic AS
+
+OUI:000D2B*
+ ID_OUI_FROM_DATABASE=Racal Instruments
+
+OUI:000D2C*
+ ID_OUI_FROM_DATABASE=Patapsco Designs Ltd
+
+OUI:000D2D*
+ ID_OUI_FROM_DATABASE=NCT Deutschland GmbH
+
+OUI:000D2E*
+ ID_OUI_FROM_DATABASE=Matsushita Avionics Systems Corporation
+
+OUI:000D2F*
+ ID_OUI_FROM_DATABASE=AIN Comm.Tech.Co., LTD
+
+OUI:000D30*
+ ID_OUI_FROM_DATABASE=IceFyre Semiconductor
+
+OUI:000D31*
+ ID_OUI_FROM_DATABASE=Compellent Technologies, Inc.
+
+OUI:000D32*
+ ID_OUI_FROM_DATABASE=DispenseSource, Inc.
+
+OUI:000D33*
+ ID_OUI_FROM_DATABASE=Prediwave Corp.
+
+OUI:000D34*
+ ID_OUI_FROM_DATABASE=Shell International Exploration and Production, Inc.
+
+OUI:000D35*
+ ID_OUI_FROM_DATABASE=PAC International Ltd
+
+OUI:000D36*
+ ID_OUI_FROM_DATABASE=Wu Han Routon Electronic Co., Ltd
+
+OUI:000D37*
+ ID_OUI_FROM_DATABASE=WIPLUG
+
+OUI:000D38*
+ ID_OUI_FROM_DATABASE=NISSIN INC.
+
+OUI:000D39*
+ ID_OUI_FROM_DATABASE=Network Electronics
+
+OUI:000D3A*
+ ID_OUI_FROM_DATABASE=Microsoft Corp.
+
+OUI:000D3B*
+ ID_OUI_FROM_DATABASE=Microelectronics Technology Inc.
+
+OUI:000D3C*
+ ID_OUI_FROM_DATABASE=i.Tech Dynamic Ltd
+
+OUI:000D3D*
+ ID_OUI_FROM_DATABASE=Hammerhead Systems, Inc.
+
+OUI:000D3E*
+ ID_OUI_FROM_DATABASE=APLUX Communications Ltd.
+
+OUI:000D3F*
+ ID_OUI_FROM_DATABASE=VTI Instruments Corporation
+
+OUI:000D40*
+ ID_OUI_FROM_DATABASE=Verint Loronix Video Solutions
+
+OUI:000D41*
+ ID_OUI_FROM_DATABASE=Siemens AG ICM MP UC RD IT KLF1
+
+OUI:000D42*
+ ID_OUI_FROM_DATABASE=Newbest Development Limited
+
+OUI:000D43*
+ ID_OUI_FROM_DATABASE=DRS Tactical Systems Inc.
+
+OUI:000D44*
+ ID_OUI_FROM_DATABASE=Audio BU - Logitech
+
+OUI:000D45*
+ ID_OUI_FROM_DATABASE=Tottori SANYO Electric Co., Ltd.
+
+OUI:000D46*
+ ID_OUI_FROM_DATABASE=Parker SSD Drives
+
+OUI:000D47*
+ ID_OUI_FROM_DATABASE=Collex
+
+OUI:000D48*
+ ID_OUI_FROM_DATABASE=AEWIN Technologies Co., Ltd.
+
+OUI:000D49*
+ ID_OUI_FROM_DATABASE=Triton Systems of Delaware, Inc.
+
+OUI:000D4A*
+ ID_OUI_FROM_DATABASE=Steag ETA-Optik
+
+OUI:000D4B*
+ ID_OUI_FROM_DATABASE=Roku, LLC
+
+OUI:000D4C*
+ ID_OUI_FROM_DATABASE=Outline Electronics Ltd.
+
+OUI:000D4D*
+ ID_OUI_FROM_DATABASE=Ninelanes
+
+OUI:000D4E*
+ ID_OUI_FROM_DATABASE=NDR Co.,LTD.
+
+OUI:000D4F*
+ ID_OUI_FROM_DATABASE=Kenwood Corporation
+
+OUI:000D50*
+ ID_OUI_FROM_DATABASE=Galazar Networks
+
+OUI:000D51*
+ ID_OUI_FROM_DATABASE=DIVR Systems, Inc.
+
+OUI:000D52*
+ ID_OUI_FROM_DATABASE=Comart system
+
+OUI:000D53*
+ ID_OUI_FROM_DATABASE=Beijing 5w Communication Corp.
+
+OUI:000D54*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:000D55*
+ ID_OUI_FROM_DATABASE=SANYCOM Technology Co.,Ltd
+
+OUI:000D56*
+ ID_OUI_FROM_DATABASE=Dell PCBA Test
+
+OUI:000D57*
+ ID_OUI_FROM_DATABASE=Fujitsu I-Network Systems Limited.
+
+OUI:000D59*
+ ID_OUI_FROM_DATABASE=Amity Systems, Inc.
+
+OUI:000D5A*
+ ID_OUI_FROM_DATABASE=Tiesse SpA
+
+OUI:000D5B*
+ ID_OUI_FROM_DATABASE=Smart Empire Investments Limited
+
+OUI:000D5C*
+ ID_OUI_FROM_DATABASE=Robert Bosch GmbH, VT-ATMO
+
+OUI:000D5D*
+ ID_OUI_FROM_DATABASE=Raritan Computer, Inc
+
+OUI:000D5E*
+ ID_OUI_FROM_DATABASE=NEC Personal Products
+
+OUI:000D5F*
+ ID_OUI_FROM_DATABASE=Minds Inc
+
+OUI:000D60*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:000D61*
+ ID_OUI_FROM_DATABASE=Giga-Byte Technology Co., Ltd.
+
+OUI:000D62*
+ ID_OUI_FROM_DATABASE=Funkwerk Dabendorf GmbH
+
+OUI:000D63*
+ ID_OUI_FROM_DATABASE=DENT Instruments, Inc.
+
+OUI:000D64*
+ ID_OUI_FROM_DATABASE=COMAG Handels AG
+
+OUI:000D65*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000D66*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000D67*
+ ID_OUI_FROM_DATABASE=BelAir Networks Inc.
+
+OUI:000D68*
+ ID_OUI_FROM_DATABASE=Vinci Systems, Inc.
+
+OUI:000D69*
+ ID_OUI_FROM_DATABASE=TMT&D Corporation
+
+OUI:000D6A*
+ ID_OUI_FROM_DATABASE=Redwood Technologies LTD
+
+OUI:000D6B*
+ ID_OUI_FROM_DATABASE=Mita-Teknik A/S
+
+OUI:000D6C*
+ ID_OUI_FROM_DATABASE=M-Audio
+
+OUI:000D6D*
+ ID_OUI_FROM_DATABASE=K-Tech Devices Corp.
+
+OUI:000D6E*
+ ID_OUI_FROM_DATABASE=K-Patents Oy
+
+OUI:000D6F*
+ ID_OUI_FROM_DATABASE=Ember Corporation
+
+OUI:000D70*
+ ID_OUI_FROM_DATABASE=Datamax Corporation
+
+OUI:000D71*
+ ID_OUI_FROM_DATABASE=boca systems
+
+OUI:000D72*
+ ID_OUI_FROM_DATABASE=2Wire, Inc
+
+OUI:000D73*
+ ID_OUI_FROM_DATABASE=Technical Support, Inc.
+
+OUI:000D74*
+ ID_OUI_FROM_DATABASE=Sand Network Systems, Inc.
+
+OUI:000D75*
+ ID_OUI_FROM_DATABASE=Kobian Pte Ltd - Taiwan Branch
+
+OUI:000D76*
+ ID_OUI_FROM_DATABASE=Hokuto Denshi Co,. Ltd.
+
+OUI:000D77*
+ ID_OUI_FROM_DATABASE=FalconStor Software
+
+OUI:000D78*
+ ID_OUI_FROM_DATABASE=Engineering & Security
+
+OUI:000D79*
+ ID_OUI_FROM_DATABASE=Dynamic Solutions Co,.Ltd.
+
+OUI:000D7A*
+ ID_OUI_FROM_DATABASE=DiGATTO Asia Pacific Pte Ltd
+
+OUI:000D7B*
+ ID_OUI_FROM_DATABASE=Consensys Computers Inc.
+
+OUI:000D7C*
+ ID_OUI_FROM_DATABASE=Codian Ltd
+
+OUI:000D7D*
+ ID_OUI_FROM_DATABASE=Afco Systems
+
+OUI:000D7E*
+ ID_OUI_FROM_DATABASE=Axiowave Networks, Inc.
+
+OUI:000D7F*
+ ID_OUI_FROM_DATABASE=MIDAS  COMMUNICATION TECHNOLOGIES PTE LTD ( Foreign Branch)
+
+OUI:000D80*
+ ID_OUI_FROM_DATABASE=Online Development Inc
+
+OUI:000D81*
+ ID_OUI_FROM_DATABASE=Pepperl+Fuchs GmbH
+
+OUI:000D82*
+ ID_OUI_FROM_DATABASE=PHS srl
+
+OUI:000D83*
+ ID_OUI_FROM_DATABASE=Sanmina-SCI Hungary  Ltd.
+
+OUI:000D84*
+ ID_OUI_FROM_DATABASE=Makus Inc.
+
+OUI:000D85*
+ ID_OUI_FROM_DATABASE=Tapwave, Inc.
+
+OUI:000D86*
+ ID_OUI_FROM_DATABASE=Huber + Suhner AG
+
+OUI:000D87*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. (ECS)
+
+OUI:000D88*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:000D89*
+ ID_OUI_FROM_DATABASE=Bils Technology Inc
+
+OUI:000D8A*
+ ID_OUI_FROM_DATABASE=Winners Electronics Co., Ltd.
+
+OUI:000D8B*
+ ID_OUI_FROM_DATABASE=T&D Corporation
+
+OUI:000D8C*
+ ID_OUI_FROM_DATABASE=Shanghai Wedone Digital Ltd. CO.
+
+OUI:000D8D*
+ ID_OUI_FROM_DATABASE=ProLinx Communication Gateways, Inc.
+
+OUI:000D8E*
+ ID_OUI_FROM_DATABASE=Koden Electronics Co., Ltd.
+
+OUI:000D8F*
+ ID_OUI_FROM_DATABASE=King Tsushin Kogyo Co., LTD.
+
+OUI:000D90*
+ ID_OUI_FROM_DATABASE=Factum Electronics AB
+
+OUI:000D91*
+ ID_OUI_FROM_DATABASE=Eclipse (HQ Espana) S.L.
+
+OUI:000D92*
+ ID_OUI_FROM_DATABASE=Arima Communication Corporation
+
+OUI:000D93*
+ ID_OUI_FROM_DATABASE=Apple Computer
+
+OUI:000D94*
+ ID_OUI_FROM_DATABASE=AFAR Communications,Inc
+
+OUI:000D95*
+ ID_OUI_FROM_DATABASE=Opti-cell, Inc.
+
+OUI:000D96*
+ ID_OUI_FROM_DATABASE=Vtera Technology Inc.
+
+OUI:000D97*
+ ID_OUI_FROM_DATABASE=Tropos Networks, Inc.
+
+OUI:000D98*
+ ID_OUI_FROM_DATABASE=S.W.A.C. Schmitt-Walter Automation Consult GmbH
+
+OUI:000D99*
+ ID_OUI_FROM_DATABASE=Orbital Sciences Corp.; Launch Systems Group
+
+OUI:000D9A*
+ ID_OUI_FROM_DATABASE=INFOTEC LTD
+
+OUI:000D9B*
+ ID_OUI_FROM_DATABASE=Heraeus Electro-Nite International N.V.
+
+OUI:000D9C*
+ ID_OUI_FROM_DATABASE=Elan GmbH & Co KG
+
+OUI:000D9D*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:000D9E*
+ ID_OUI_FROM_DATABASE=TOKUDEN OHIZUMI SEISAKUSYO Co.,Ltd.
+
+OUI:000D9F*
+ ID_OUI_FROM_DATABASE=RF Micro Devices
+
+OUI:000DA0*
+ ID_OUI_FROM_DATABASE=NEDAP N.V.
+
+OUI:000DA1*
+ ID_OUI_FROM_DATABASE=MIRAE ITS Co.,LTD.
+
+OUI:000DA2*
+ ID_OUI_FROM_DATABASE=Infrant Technologies, Inc.
+
+OUI:000DA3*
+ ID_OUI_FROM_DATABASE=Emerging Technologies Limited
+
+OUI:000DA4*
+ ID_OUI_FROM_DATABASE=DOSCH & AMAND SYSTEMS AG
+
+OUI:000DA5*
+ ID_OUI_FROM_DATABASE=Fabric7 Systems, Inc
+
+OUI:000DA6*
+ ID_OUI_FROM_DATABASE=Universal Switching Corporation
+
+OUI:000DA8*
+ ID_OUI_FROM_DATABASE=Teletronics Technology Corporation
+
+OUI:000DA9*
+ ID_OUI_FROM_DATABASE=T.E.A.M. S.L.
+
+OUI:000DAA*
+ ID_OUI_FROM_DATABASE=S.A.Tehnology co.,Ltd.
+
+OUI:000DAB*
+ ID_OUI_FROM_DATABASE=Parker Hannifin GmbH Electromechanical Division Europe
+
+OUI:000DAC*
+ ID_OUI_FROM_DATABASE=Japan CBM Corporation
+
+OUI:000DAD*
+ ID_OUI_FROM_DATABASE=Dataprobe Inc
+
+OUI:000DAE*
+ ID_OUI_FROM_DATABASE=SAMSUNG HEAVY INDUSTRIES CO., LTD.
+
+OUI:000DAF*
+ ID_OUI_FROM_DATABASE=Plexus Corp (UK) Ltd
+
+OUI:000DB0*
+ ID_OUI_FROM_DATABASE=Olym-tech Co.,Ltd.
+
+OUI:000DB1*
+ ID_OUI_FROM_DATABASE=Japan Network Service Co., Ltd.
+
+OUI:000DB2*
+ ID_OUI_FROM_DATABASE=Ammasso, Inc.
+
+OUI:000DB3*
+ ID_OUI_FROM_DATABASE=SDO Communication Corperation
+
+OUI:000DB4*
+ ID_OUI_FROM_DATABASE=NETASQ
+
+OUI:000DB5*
+ ID_OUI_FROM_DATABASE=GLOBALSAT TECHNOLOGY CORPORATION
+
+OUI:000DB6*
+ ID_OUI_FROM_DATABASE=Broadcom Corporation
+
+OUI:000DB7*
+ ID_OUI_FROM_DATABASE=SANKO ELECTRIC CO,.LTD
+
+OUI:000DB8*
+ ID_OUI_FROM_DATABASE=SCHILLER AG
+
+OUI:000DB9*
+ ID_OUI_FROM_DATABASE=PC Engines GmbH
+
+OUI:000DBA*
+ ID_OUI_FROM_DATABASE=Océ Document Technologies GmbH
+
+OUI:000DBB*
+ ID_OUI_FROM_DATABASE=Nippon Dentsu Co.,Ltd.
+
+OUI:000DBC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000DBD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000DBE*
+ ID_OUI_FROM_DATABASE=Bel Fuse Europe Ltd.,UK
+
+OUI:000DBF*
+ ID_OUI_FROM_DATABASE=TekTone Sound & Signal Mfg., Inc.
+
+OUI:000DC0*
+ ID_OUI_FROM_DATABASE=Spagat AS
+
+OUI:000DC1*
+ ID_OUI_FROM_DATABASE=SafeWeb Inc
+
+OUI:000DC3*
+ ID_OUI_FROM_DATABASE=First Communication, Inc.
+
+OUI:000DC4*
+ ID_OUI_FROM_DATABASE=Emcore Corporation
+
+OUI:000DC5*
+ ID_OUI_FROM_DATABASE=EchoStar Global B.V.
+
+OUI:000DC6*
+ ID_OUI_FROM_DATABASE=DigiRose Technology Co., Ltd.
+
+OUI:000DC7*
+ ID_OUI_FROM_DATABASE=COSMIC ENGINEERING INC.
+
+OUI:000DC8*
+ ID_OUI_FROM_DATABASE=AirMagnet, Inc
+
+OUI:000DC9*
+ ID_OUI_FROM_DATABASE=THALES Elektronik Systeme GmbH
+
+OUI:000DCA*
+ ID_OUI_FROM_DATABASE=Tait Electronics
+
+OUI:000DCB*
+ ID_OUI_FROM_DATABASE=Petcomkorea Co., Ltd.
+
+OUI:000DCC*
+ ID_OUI_FROM_DATABASE=NEOSMART Corp.
+
+OUI:000DCD*
+ ID_OUI_FROM_DATABASE=GROUPE TXCOM
+
+OUI:000DCE*
+ ID_OUI_FROM_DATABASE=Dynavac Technology Pte Ltd
+
+OUI:000DCF*
+ ID_OUI_FROM_DATABASE=Cidra Corp.
+
+OUI:000DD0*
+ ID_OUI_FROM_DATABASE=TetraTec Instruments GmbH
+
+OUI:000DD1*
+ ID_OUI_FROM_DATABASE=Stryker Corporation
+
+OUI:000DD2*
+ ID_OUI_FROM_DATABASE=Simrad Optronics ASA
+
+OUI:000DD3*
+ ID_OUI_FROM_DATABASE=SAMWOO Telecommunication Co.,Ltd.
+
+OUI:000DD4*
+ ID_OUI_FROM_DATABASE=Symantec Corporation
+
+OUI:000DD5*
+ ID_OUI_FROM_DATABASE=O'RITE TECHNOLOGY CO.,LTD
+
+OUI:000DD6*
+ ID_OUI_FROM_DATABASE=ITI    LTD
+
+OUI:000DD7*
+ ID_OUI_FROM_DATABASE=Bright
+
+OUI:000DD8*
+ ID_OUI_FROM_DATABASE=BBN
+
+OUI:000DD9*
+ ID_OUI_FROM_DATABASE=Anton Paar GmbH
+
+OUI:000DDA*
+ ID_OUI_FROM_DATABASE=ALLIED TELESIS K.K.
+
+OUI:000DDB*
+ ID_OUI_FROM_DATABASE=AIRWAVE TECHNOLOGIES INC.
+
+OUI:000DDC*
+ ID_OUI_FROM_DATABASE=VAC
+
+OUI:000DDD*
+ ID_OUI_FROM_DATABASE=Profilo Telra Elektronik Sanayi ve Ticaret. A.Ş
+
+OUI:000DDE*
+ ID_OUI_FROM_DATABASE=Joyteck Co., Ltd.
+
+OUI:000DDF*
+ ID_OUI_FROM_DATABASE=Japan Image & Network Inc.
+
+OUI:000DE0*
+ ID_OUI_FROM_DATABASE=ICPDAS Co.,LTD
+
+OUI:000DE1*
+ ID_OUI_FROM_DATABASE=Control Products, Inc.
+
+OUI:000DE2*
+ ID_OUI_FROM_DATABASE=CMZ Sistemi Elettronici
+
+OUI:000DE3*
+ ID_OUI_FROM_DATABASE=AT Sweden AB
+
+OUI:000DE4*
+ ID_OUI_FROM_DATABASE=DIGINICS, Inc.
+
+OUI:000DE5*
+ ID_OUI_FROM_DATABASE=Samsung Thales
+
+OUI:000DE6*
+ ID_OUI_FROM_DATABASE=YOUNGBO ENGINEERING CO.,LTD
+
+OUI:000DE7*
+ ID_OUI_FROM_DATABASE=Snap-on OEM Group
+
+OUI:000DE8*
+ ID_OUI_FROM_DATABASE=Nasaco Electronics Pte. Ltd
+
+OUI:000DE9*
+ ID_OUI_FROM_DATABASE=Napatech Aps
+
+OUI:000DEA*
+ ID_OUI_FROM_DATABASE=Kingtel Telecommunication Corp.
+
+OUI:000DEB*
+ ID_OUI_FROM_DATABASE=CompXs Limited
+
+OUI:000DEC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000DED*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000DEE*
+ ID_OUI_FROM_DATABASE=Andrew RF Power Amplifier Group
+
+OUI:000DEF*
+ ID_OUI_FROM_DATABASE=Soc. Coop. Bilanciai
+
+OUI:000DF0*
+ ID_OUI_FROM_DATABASE=QCOM TECHNOLOGY INC.
+
+OUI:000DF1*
+ ID_OUI_FROM_DATABASE=IONIX INC.
+
+OUI:000DF3*
+ ID_OUI_FROM_DATABASE=Asmax Solutions
+
+OUI:000DF4*
+ ID_OUI_FROM_DATABASE=Watertek Co.
+
+OUI:000DF5*
+ ID_OUI_FROM_DATABASE=Teletronics International Inc.
+
+OUI:000DF6*
+ ID_OUI_FROM_DATABASE=Technology Thesaurus Corp.
+
+OUI:000DF7*
+ ID_OUI_FROM_DATABASE=Space Dynamics Lab
+
+OUI:000DF8*
+ ID_OUI_FROM_DATABASE=ORGA Kartensysteme GmbH
+
+OUI:000DF9*
+ ID_OUI_FROM_DATABASE=NDS Limited
+
+OUI:000DFA*
+ ID_OUI_FROM_DATABASE=Micro Control Systems Ltd.
+
+OUI:000DFB*
+ ID_OUI_FROM_DATABASE=Komax AG
+
+OUI:000DFC*
+ ID_OUI_FROM_DATABASE=ITFOR Inc.
+
+OUI:000DFD*
+ ID_OUI_FROM_DATABASE=Huges Hi-Tech Inc.,
+
+OUI:000DFE*
+ ID_OUI_FROM_DATABASE=Hauppauge Computer Works, Inc.
+
+OUI:000DFF*
+ ID_OUI_FROM_DATABASE=CHENMING MOLD INDUSTRY CORP.
+
+OUI:000E00*
+ ID_OUI_FROM_DATABASE=Atrie
+
+OUI:000E01*
+ ID_OUI_FROM_DATABASE=ASIP Technologies Inc.
+
+OUI:000E02*
+ ID_OUI_FROM_DATABASE=Advantech AMT Inc.
+
+OUI:000E03*
+ ID_OUI_FROM_DATABASE=Emulex
+
+OUI:000E04*
+ ID_OUI_FROM_DATABASE=CMA/Microdialysis AB
+
+OUI:000E05*
+ ID_OUI_FROM_DATABASE=WIRELESS MATRIX CORP.
+
+OUI:000E06*
+ ID_OUI_FROM_DATABASE=Team Simoco Ltd
+
+OUI:000E07*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:000E08*
+ ID_OUI_FROM_DATABASE=Cisco Linksys LLC
+
+OUI:000E09*
+ ID_OUI_FROM_DATABASE=Shenzhen Coship Software Co.,LTD.
+
+OUI:000E0A*
+ ID_OUI_FROM_DATABASE=SAKUMA DESIGN OFFICE
+
+OUI:000E0B*
+ ID_OUI_FROM_DATABASE=Netac Technology Co., Ltd.
+
+OUI:000E0C*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:000E0D*
+ ID_OUI_FROM_DATABASE=Hesch Schröder GmbH
+
+OUI:000E0E*
+ ID_OUI_FROM_DATABASE=ESA elettronica S.P.A.
+
+OUI:000E0F*
+ ID_OUI_FROM_DATABASE=ERMME
+
+OUI:000E10*
+ ID_OUI_FROM_DATABASE=C-guys, Inc.
+
+OUI:000E11*
+ ID_OUI_FROM_DATABASE=BDT Büro und Datentechnik GmbH & Co.KG
+
+OUI:000E12*
+ ID_OUI_FROM_DATABASE=Adaptive Micro Systems Inc.
+
+OUI:000E13*
+ ID_OUI_FROM_DATABASE=Accu-Sort Systems inc.
+
+OUI:000E14*
+ ID_OUI_FROM_DATABASE=Visionary Solutions, Inc.
+
+OUI:000E15*
+ ID_OUI_FROM_DATABASE=Tadlys LTD
+
+OUI:000E16*
+ ID_OUI_FROM_DATABASE=SouthWing S.L.
+
+OUI:000E18*
+ ID_OUI_FROM_DATABASE=MyA Technology
+
+OUI:000E19*
+ ID_OUI_FROM_DATABASE=LogicaCMG Pty Ltd
+
+OUI:000E1A*
+ ID_OUI_FROM_DATABASE=JPS Communications
+
+OUI:000E1B*
+ ID_OUI_FROM_DATABASE=IAV GmbH
+
+OUI:000E1C*
+ ID_OUI_FROM_DATABASE=Hach Company
+
+OUI:000E1D*
+ ID_OUI_FROM_DATABASE=ARION Technology Inc.
+
+OUI:000E1E*
+ ID_OUI_FROM_DATABASE=QLogic Corporation
+
+OUI:000E1F*
+ ID_OUI_FROM_DATABASE=TCL Networks Equipment Co., Ltd.
+
+OUI:000E20*
+ ID_OUI_FROM_DATABASE=ACCESS Systems Americas, Inc.
+
+OUI:000E21*
+ ID_OUI_FROM_DATABASE=MTU Friedrichshafen GmbH
+
+OUI:000E23*
+ ID_OUI_FROM_DATABASE=Incipient, Inc.
+
+OUI:000E24*
+ ID_OUI_FROM_DATABASE=Huwell Technology Inc.
+
+OUI:000E25*
+ ID_OUI_FROM_DATABASE=Hannae Technology Co., Ltd
+
+OUI:000E26*
+ ID_OUI_FROM_DATABASE=Gincom Technology Corp.
+
+OUI:000E27*
+ ID_OUI_FROM_DATABASE=Crere Networks, Inc.
+
+OUI:000E28*
+ ID_OUI_FROM_DATABASE=Dynamic Ratings P/L
+
+OUI:000E29*
+ ID_OUI_FROM_DATABASE=Shester Communications Inc
+
+OUI:000E2B*
+ ID_OUI_FROM_DATABASE=Safari Technologies
+
+OUI:000E2C*
+ ID_OUI_FROM_DATABASE=Netcodec co.
+
+OUI:000E2D*
+ ID_OUI_FROM_DATABASE=Hyundai Digital Technology Co.,Ltd.
+
+OUI:000E2E*
+ ID_OUI_FROM_DATABASE=Edimax Technology Co., Ltd.
+
+OUI:000E2F*
+ ID_OUI_FROM_DATABASE=Disetronic Medical Systems AG
+
+OUI:000E30*
+ ID_OUI_FROM_DATABASE=AERAS Networks, Inc.
+
+OUI:000E31*
+ ID_OUI_FROM_DATABASE=Olympus Soft Imaging Solutions GmbH
+
+OUI:000E32*
+ ID_OUI_FROM_DATABASE=Kontron Medical
+
+OUI:000E33*
+ ID_OUI_FROM_DATABASE=Shuko Electronics Co.,Ltd
+
+OUI:000E34*
+ ID_OUI_FROM_DATABASE=NexGen City, LP
+
+OUI:000E35*
+ ID_OUI_FROM_DATABASE=Intel Corp
+
+OUI:000E36*
+ ID_OUI_FROM_DATABASE=HEINESYS, Inc.
+
+OUI:000E37*
+ ID_OUI_FROM_DATABASE=Harms & Wende GmbH & Co.KG
+
+OUI:000E38*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000E39*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000E3A*
+ ID_OUI_FROM_DATABASE=Cirrus Logic
+
+OUI:000E3B*
+ ID_OUI_FROM_DATABASE=Hawking Technologies, Inc.
+
+OUI:000E3C*
+ ID_OUI_FROM_DATABASE=Transact Technologies Inc
+
+OUI:000E3D*
+ ID_OUI_FROM_DATABASE=Televic N.V.
+
+OUI:000E3E*
+ ID_OUI_FROM_DATABASE=Sun Optronics Inc
+
+OUI:000E3F*
+ ID_OUI_FROM_DATABASE=Soronti, Inc.
+
+OUI:000E40*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000E41*
+ ID_OUI_FROM_DATABASE=NIHON MECHATRONICS CO.,LTD.
+
+OUI:000E42*
+ ID_OUI_FROM_DATABASE=Motic Incoporation Ltd.
+
+OUI:000E43*
+ ID_OUI_FROM_DATABASE=G-Tek Electronics Sdn. Bhd.
+
+OUI:000E44*
+ ID_OUI_FROM_DATABASE=Digital 5, Inc.
+
+OUI:000E45*
+ ID_OUI_FROM_DATABASE=Beijing Newtry Electronic Technology Ltd
+
+OUI:000E46*
+ ID_OUI_FROM_DATABASE=Niigata Seimitsu Co.,Ltd.
+
+OUI:000E47*
+ ID_OUI_FROM_DATABASE=NCI System Co.,Ltd.
+
+OUI:000E48*
+ ID_OUI_FROM_DATABASE=Lipman TransAction Solutions
+
+OUI:000E49*
+ ID_OUI_FROM_DATABASE=Forsway Scandinavia AB
+
+OUI:000E4A*
+ ID_OUI_FROM_DATABASE=Changchun Huayu WEBPAD Co.,LTD
+
+OUI:000E4B*
+ ID_OUI_FROM_DATABASE=atrium c and i
+
+OUI:000E4C*
+ ID_OUI_FROM_DATABASE=Bermai Inc.
+
+OUI:000E4D*
+ ID_OUI_FROM_DATABASE=Numesa Inc.
+
+OUI:000E4E*
+ ID_OUI_FROM_DATABASE=Waveplus Technology Co., Ltd.
+
+OUI:000E4F*
+ ID_OUI_FROM_DATABASE=Trajet GmbH
+
+OUI:000E50*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:000E51*
+ ID_OUI_FROM_DATABASE=tecna elettronica srl
+
+OUI:000E52*
+ ID_OUI_FROM_DATABASE=Optium Corporation
+
+OUI:000E53*
+ ID_OUI_FROM_DATABASE=AV TECH CORPORATION
+
+OUI:000E54*
+ ID_OUI_FROM_DATABASE=AlphaCell Wireless Ltd.
+
+OUI:000E55*
+ ID_OUI_FROM_DATABASE=AUVITRAN
+
+OUI:000E56*
+ ID_OUI_FROM_DATABASE=4G Systems GmbH & Co. KG
+
+OUI:000E57*
+ ID_OUI_FROM_DATABASE=Iworld Networking, Inc.
+
+OUI:000E58*
+ ID_OUI_FROM_DATABASE=Sonos, Inc.
+
+OUI:000E59*
+ ID_OUI_FROM_DATABASE=SAGEM SA
+
+OUI:000E5A*
+ ID_OUI_FROM_DATABASE=TELEFIELD inc.
+
+OUI:000E5B*
+ ID_OUI_FROM_DATABASE=ParkerVision - Direct2Data
+
+OUI:000E5C*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:000E5D*
+ ID_OUI_FROM_DATABASE=Triple Play Technologies A/S
+
+OUI:000E5E*
+ ID_OUI_FROM_DATABASE=Raisecom Technology
+
+OUI:000E5F*
+ ID_OUI_FROM_DATABASE=activ-net GmbH & Co. KG
+
+OUI:000E60*
+ ID_OUI_FROM_DATABASE=360SUN Digital Broadband Corporation
+
+OUI:000E61*
+ ID_OUI_FROM_DATABASE=MICROTROL LIMITED
+
+OUI:000E62*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000E63*
+ ID_OUI_FROM_DATABASE=Lemke Diagnostics GmbH
+
+OUI:000E64*
+ ID_OUI_FROM_DATABASE=Elphel, Inc
+
+OUI:000E65*
+ ID_OUI_FROM_DATABASE=TransCore
+
+OUI:000E66*
+ ID_OUI_FROM_DATABASE=Hitachi Advanced Digital, Inc.
+
+OUI:000E67*
+ ID_OUI_FROM_DATABASE=Eltis Microelectronics Ltd.
+
+OUI:000E68*
+ ID_OUI_FROM_DATABASE=E-TOP Network Technology Inc.
+
+OUI:000E69*
+ ID_OUI_FROM_DATABASE=China Electric Power Research Institute
+
+OUI:000E6A*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:000E6B*
+ ID_OUI_FROM_DATABASE=Janitza electronics GmbH
+
+OUI:000E6C*
+ ID_OUI_FROM_DATABASE=Device Drivers Limited
+
+OUI:000E6D*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:000E6E*
+ ID_OUI_FROM_DATABASE=MICRELEC  ELECTRONICS S.A
+
+OUI:000E6F*
+ ID_OUI_FROM_DATABASE=IRIS Corporation Berhad
+
+OUI:000E70*
+ ID_OUI_FROM_DATABASE=in2 Networks
+
+OUI:000E71*
+ ID_OUI_FROM_DATABASE=Gemstar Technology Development Ltd.
+
+OUI:000E72*
+ ID_OUI_FROM_DATABASE=CTS electronics
+
+OUI:000E73*
+ ID_OUI_FROM_DATABASE=Tpack A/S
+
+OUI:000E74*
+ ID_OUI_FROM_DATABASE=Solar Telecom. Tech
+
+OUI:000E75*
+ ID_OUI_FROM_DATABASE=New York Air Brake Corp.
+
+OUI:000E76*
+ ID_OUI_FROM_DATABASE=GEMSOC INNOVISION INC.
+
+OUI:000E77*
+ ID_OUI_FROM_DATABASE=Decru, Inc.
+
+OUI:000E78*
+ ID_OUI_FROM_DATABASE=Amtelco
+
+OUI:000E79*
+ ID_OUI_FROM_DATABASE=Ample Communications Inc.
+
+OUI:000E7A*
+ ID_OUI_FROM_DATABASE=GemWon Communications Co., Ltd.
+
+OUI:000E7B*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:000E7C*
+ ID_OUI_FROM_DATABASE=Televes S.A.
+
+OUI:000E7D*
+ ID_OUI_FROM_DATABASE=Electronics Line 3000 Ltd.
+
+OUI:000E7E*
+ ID_OUI_FROM_DATABASE=ionSign Oy
+
+OUI:000E7F*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:000E80*
+ ID_OUI_FROM_DATABASE=Thomson Technology Inc
+
+OUI:000E81*
+ ID_OUI_FROM_DATABASE=Devicescape Software, Inc.
+
+OUI:000E82*
+ ID_OUI_FROM_DATABASE=Commtech Wireless
+
+OUI:000E83*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000E84*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000E85*
+ ID_OUI_FROM_DATABASE=Catalyst Enterprises, Inc.
+
+OUI:000E86*
+ ID_OUI_FROM_DATABASE=Alcatel North America
+
+OUI:000E87*
+ ID_OUI_FROM_DATABASE=adp Gauselmann GmbH
+
+OUI:000E88*
+ ID_OUI_FROM_DATABASE=VIDEOTRON CORP.
+
+OUI:000E89*
+ ID_OUI_FROM_DATABASE=CLEMATIC
+
+OUI:000E8A*
+ ID_OUI_FROM_DATABASE=Avara Technologies Pty. Ltd.
+
+OUI:000E8B*
+ ID_OUI_FROM_DATABASE=Astarte Technology Co, Ltd.
+
+OUI:000E8C*
+ ID_OUI_FROM_DATABASE=Siemens AG A&D ET
+
+OUI:000E8D*
+ ID_OUI_FROM_DATABASE=Systems in Progress Holding GmbH
+
+OUI:000E8E*
+ ID_OUI_FROM_DATABASE=SparkLAN Communications, Inc.
+
+OUI:000E8F*
+ ID_OUI_FROM_DATABASE=Sercomm Corp.
+
+OUI:000E90*
+ ID_OUI_FROM_DATABASE=PONICO CORP.
+
+OUI:000E91*
+ ID_OUI_FROM_DATABASE=Navico Auckland Ltd
+
+OUI:000E92*
+ ID_OUI_FROM_DATABASE=Millinet Co., Ltd.
+
+OUI:000E93*
+ ID_OUI_FROM_DATABASE=Milénio 3 Sistemas Electrónicos, Lda.
+
+OUI:000E94*
+ ID_OUI_FROM_DATABASE=Maas International BV
+
+OUI:000E95*
+ ID_OUI_FROM_DATABASE=Fujiya Denki Seisakusho Co.,Ltd.
+
+OUI:000E96*
+ ID_OUI_FROM_DATABASE=Cubic Defense Applications, Inc.
+
+OUI:000E97*
+ ID_OUI_FROM_DATABASE=Ultracker Technology CO., Inc
+
+OUI:000E98*
+ ID_OUI_FROM_DATABASE=HME Clear-Com LTD.
+
+OUI:000E99*
+ ID_OUI_FROM_DATABASE=Spectrum Digital, Inc
+
+OUI:000E9A*
+ ID_OUI_FROM_DATABASE=BOE TECHNOLOGY GROUP CO.,LTD
+
+OUI:000E9B*
+ ID_OUI_FROM_DATABASE=Ambit Microsystems Corporation
+
+OUI:000E9C*
+ ID_OUI_FROM_DATABASE=Pemstar
+
+OUI:000E9D*
+ ID_OUI_FROM_DATABASE=Tiscali UK Ltd
+
+OUI:000E9E*
+ ID_OUI_FROM_DATABASE=Topfield Co., Ltd
+
+OUI:000E9F*
+ ID_OUI_FROM_DATABASE=TEMIC SDS GmbH
+
+OUI:000EA0*
+ ID_OUI_FROM_DATABASE=NetKlass Technology Inc.
+
+OUI:000EA1*
+ ID_OUI_FROM_DATABASE=Formosa Teletek Corporation
+
+OUI:000EA2*
+ ID_OUI_FROM_DATABASE=McAfee, Inc
+
+OUI:000EA3*
+ ID_OUI_FROM_DATABASE=CNCR-IT CO.,LTD,HangZhou P.R.CHINA
+
+OUI:000EA4*
+ ID_OUI_FROM_DATABASE=Certance Inc.
+
+OUI:000EA5*
+ ID_OUI_FROM_DATABASE=BLIP Systems
+
+OUI:000EA6*
+ ID_OUI_FROM_DATABASE=ASUSTEK COMPUTER INC.
+
+OUI:000EA7*
+ ID_OUI_FROM_DATABASE=Endace Technology
+
+OUI:000EA8*
+ ID_OUI_FROM_DATABASE=United Technologists Europe Limited
+
+OUI:000EA9*
+ ID_OUI_FROM_DATABASE=Shanghai Xun Shi Communications Equipment Ltd. Co.
+
+OUI:000EAA*
+ ID_OUI_FROM_DATABASE=Scalent Systems, Inc.
+
+OUI:000EAB*
+ ID_OUI_FROM_DATABASE=Cray Inc
+
+OUI:000EAC*
+ ID_OUI_FROM_DATABASE=MINTRON ENTERPRISE CO., LTD.
+
+OUI:000EAD*
+ ID_OUI_FROM_DATABASE=Metanoia Technologies, Inc.
+
+OUI:000EAE*
+ ID_OUI_FROM_DATABASE=GAWELL TECHNOLOGIES CORP.
+
+OUI:000EAF*
+ ID_OUI_FROM_DATABASE=CASTEL
+
+OUI:000EB0*
+ ID_OUI_FROM_DATABASE=Solutions Radio BV
+
+OUI:000EB1*
+ ID_OUI_FROM_DATABASE=Newcotech,Ltd
+
+OUI:000EB2*
+ ID_OUI_FROM_DATABASE=Micro-Research Finland Oy
+
+OUI:000EB3*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard
+
+OUI:000EB4*
+ ID_OUI_FROM_DATABASE=GUANGZHOU GAOKE COMMUNICATIONS TECHNOLOGY CO.LTD.
+
+OUI:000EB5*
+ ID_OUI_FROM_DATABASE=Ecastle Electronics Co., Ltd.
+
+OUI:000EB6*
+ ID_OUI_FROM_DATABASE=Riverbed Technology, Inc.
+
+OUI:000EB7*
+ ID_OUI_FROM_DATABASE=Knovative, Inc.
+
+OUI:000EB8*
+ ID_OUI_FROM_DATABASE=Iiga co.,Ltd
+
+OUI:000EB9*
+ ID_OUI_FROM_DATABASE=HASHIMOTO Electronics Industry Co.,Ltd.
+
+OUI:000EBA*
+ ID_OUI_FROM_DATABASE=HANMI SEMICONDUCTOR CO., LTD.
+
+OUI:000EBB*
+ ID_OUI_FROM_DATABASE=Everbee Networks
+
+OUI:000EBC*
+ ID_OUI_FROM_DATABASE=Paragon Fidelity GmbH
+
+OUI:000EBD*
+ ID_OUI_FROM_DATABASE=Burdick, a Quinton Compny
+
+OUI:000EBE*
+ ID_OUI_FROM_DATABASE=B&B Electronics Manufacturing Co.
+
+OUI:000EBF*
+ ID_OUI_FROM_DATABASE=Remsdaq Limited
+
+OUI:000EC0*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000EC1*
+ ID_OUI_FROM_DATABASE=MYNAH Technologies
+
+OUI:000EC2*
+ ID_OUI_FROM_DATABASE=Lowrance Electronics, Inc.
+
+OUI:000EC3*
+ ID_OUI_FROM_DATABASE=Logic Controls, Inc.
+
+OUI:000EC4*
+ ID_OUI_FROM_DATABASE=Iskra Transmission d.d.
+
+OUI:000EC5*
+ ID_OUI_FROM_DATABASE=Digital Multitools Inc
+
+OUI:000EC6*
+ ID_OUI_FROM_DATABASE=ASIX ELECTRONICS CORP.
+
+OUI:000EC7*
+ ID_OUI_FROM_DATABASE=Motorola Korea
+
+OUI:000EC8*
+ ID_OUI_FROM_DATABASE=Zoran Corporation
+
+OUI:000EC9*
+ ID_OUI_FROM_DATABASE=YOKO Technology Corp.
+
+OUI:000ECA*
+ ID_OUI_FROM_DATABASE=WTSS Inc
+
+OUI:000ECB*
+ ID_OUI_FROM_DATABASE=VineSys Technology
+
+OUI:000ECC*
+ ID_OUI_FROM_DATABASE=Tableau, LLC
+
+OUI:000ECD*
+ ID_OUI_FROM_DATABASE=SKOV A/S
+
+OUI:000ECE*
+ ID_OUI_FROM_DATABASE=S.I.T.T.I. S.p.A.
+
+OUI:000ECF*
+ ID_OUI_FROM_DATABASE=PROFIBUS Nutzerorganisation e.V.
+
+OUI:000ED0*
+ ID_OUI_FROM_DATABASE=Privaris, Inc.
+
+OUI:000ED1*
+ ID_OUI_FROM_DATABASE=Osaka Micro Computer.
+
+OUI:000ED2*
+ ID_OUI_FROM_DATABASE=Filtronic plc
+
+OUI:000ED3*
+ ID_OUI_FROM_DATABASE=Epicenter, Inc.
+
+OUI:000ED4*
+ ID_OUI_FROM_DATABASE=CRESITT INDUSTRIE
+
+OUI:000ED5*
+ ID_OUI_FROM_DATABASE=COPAN Systems Inc.
+
+OUI:000ED6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000ED7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000ED8*
+ ID_OUI_FROM_DATABASE=Aktino, Inc.
+
+OUI:000ED9*
+ ID_OUI_FROM_DATABASE=Aksys, Ltd.
+
+OUI:000EDA*
+ ID_OUI_FROM_DATABASE=C-TECH UNITED CORP.
+
+OUI:000EDB*
+ ID_OUI_FROM_DATABASE=XiNCOM Corp.
+
+OUI:000EDC*
+ ID_OUI_FROM_DATABASE=Tellion INC.
+
+OUI:000EDD*
+ ID_OUI_FROM_DATABASE=SHURE INCORPORATED
+
+OUI:000EDE*
+ ID_OUI_FROM_DATABASE=REMEC, Inc.
+
+OUI:000EDF*
+ ID_OUI_FROM_DATABASE=PLX Technology
+
+OUI:000EE0*
+ ID_OUI_FROM_DATABASE=Mcharge
+
+OUI:000EE1*
+ ID_OUI_FROM_DATABASE=ExtremeSpeed Inc.
+
+OUI:000EE2*
+ ID_OUI_FROM_DATABASE=Custom Engineering S.p.A.
+
+OUI:000EE3*
+ ID_OUI_FROM_DATABASE=Chiyu Technology Co.,Ltd
+
+OUI:000EE4*
+ ID_OUI_FROM_DATABASE=BOE TECHNOLOGY GROUP CO.,LTD
+
+OUI:000EE5*
+ ID_OUI_FROM_DATABASE=bitWallet, Inc.
+
+OUI:000EE6*
+ ID_OUI_FROM_DATABASE=Adimos Systems LTD
+
+OUI:000EE7*
+ ID_OUI_FROM_DATABASE=AAC ELECTRONICS CORP.
+
+OUI:000EE8*
+ ID_OUI_FROM_DATABASE=zioncom
+
+OUI:000EE9*
+ ID_OUI_FROM_DATABASE=WayTech Development, Inc.
+
+OUI:000EEA*
+ ID_OUI_FROM_DATABASE=Shadong Luneng Jicheng Electronics,Co.,Ltd
+
+OUI:000EEB*
+ ID_OUI_FROM_DATABASE=Sandmartin(zhong shan)Electronics Co.,Ltd
+
+OUI:000EEC*
+ ID_OUI_FROM_DATABASE=Orban
+
+OUI:000EED*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:000EEE*
+ ID_OUI_FROM_DATABASE=Muco Industrie BV
+
+OUI:000EF0*
+ ID_OUI_FROM_DATABASE=Festo AG & Co. KG
+
+OUI:000EF1*
+ ID_OUI_FROM_DATABASE=EZQUEST INC.
+
+OUI:000EF2*
+ ID_OUI_FROM_DATABASE=Infinico Corporation
+
+OUI:000EF3*
+ ID_OUI_FROM_DATABASE=Smarthome
+
+OUI:000EF4*
+ ID_OUI_FROM_DATABASE=Kasda Digital Technology Co.,Ltd
+
+OUI:000EF5*
+ ID_OUI_FROM_DATABASE=iPAC Technology Co., Ltd.
+
+OUI:000EF6*
+ ID_OUI_FROM_DATABASE=E-TEN Information Systems Co., Ltd.
+
+OUI:000EF7*
+ ID_OUI_FROM_DATABASE=Vulcan Portals Inc
+
+OUI:000EF8*
+ ID_OUI_FROM_DATABASE=SBC ASI
+
+OUI:000EF9*
+ ID_OUI_FROM_DATABASE=REA Elektronik GmbH
+
+OUI:000EFA*
+ ID_OUI_FROM_DATABASE=Optoway Technology Incorporation
+
+OUI:000EFB*
+ ID_OUI_FROM_DATABASE=Macey Enterprises
+
+OUI:000EFC*
+ ID_OUI_FROM_DATABASE=JTAG Technologies B.V.
+
+OUI:000EFD*
+ ID_OUI_FROM_DATABASE=FUJINON CORPORATION
+
+OUI:000EFE*
+ ID_OUI_FROM_DATABASE=EndRun Technologies LLC
+
+OUI:000EFF*
+ ID_OUI_FROM_DATABASE=Megasolution,Inc.
+
+OUI:000F00*
+ ID_OUI_FROM_DATABASE=Legra Systems, Inc.
+
+OUI:000F01*
+ ID_OUI_FROM_DATABASE=DIGITALKS INC
+
+OUI:000F02*
+ ID_OUI_FROM_DATABASE=Digicube Technology Co., Ltd
+
+OUI:000F03*
+ ID_OUI_FROM_DATABASE=COM&C CO., LTD
+
+OUI:000F04*
+ ID_OUI_FROM_DATABASE=cim-usa inc
+
+OUI:000F05*
+ ID_OUI_FROM_DATABASE=3B SYSTEM INC.
+
+OUI:000F06*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000F07*
+ ID_OUI_FROM_DATABASE=Mangrove Systems, Inc.
+
+OUI:000F08*
+ ID_OUI_FROM_DATABASE=Indagon Oy
+
+OUI:000F0A*
+ ID_OUI_FROM_DATABASE=Clear Edge Networks
+
+OUI:000F0B*
+ ID_OUI_FROM_DATABASE=Kentima Technologies AB
+
+OUI:000F0C*
+ ID_OUI_FROM_DATABASE=SYNCHRONIC ENGINEERING
+
+OUI:000F0D*
+ ID_OUI_FROM_DATABASE=Hunt Electronic Co., Ltd.
+
+OUI:000F0E*
+ ID_OUI_FROM_DATABASE=WaveSplitter Technologies, Inc.
+
+OUI:000F0F*
+ ID_OUI_FROM_DATABASE=Real ID Technology Co., Ltd.
+
+OUI:000F10*
+ ID_OUI_FROM_DATABASE=RDM Corporation
+
+OUI:000F11*
+ ID_OUI_FROM_DATABASE=Prodrive B.V.
+
+OUI:000F12*
+ ID_OUI_FROM_DATABASE=Panasonic Europe Ltd.
+
+OUI:000F13*
+ ID_OUI_FROM_DATABASE=Nisca corporation
+
+OUI:000F14*
+ ID_OUI_FROM_DATABASE=Mindray Co., Ltd.
+
+OUI:000F15*
+ ID_OUI_FROM_DATABASE=Kjaerulff1 A/S
+
+OUI:000F16*
+ ID_OUI_FROM_DATABASE=JAY HOW TECHNOLOGY CO.,
+
+OUI:000F17*
+ ID_OUI_FROM_DATABASE=Insta Elektro GmbH
+
+OUI:000F18*
+ ID_OUI_FROM_DATABASE=Industrial Control Systems
+
+OUI:000F19*
+ ID_OUI_FROM_DATABASE=Boston Scientific
+
+OUI:000F1A*
+ ID_OUI_FROM_DATABASE=Gaming Support B.V.
+
+OUI:000F1B*
+ ID_OUI_FROM_DATABASE=Ego Systems Inc.
+
+OUI:000F1C*
+ ID_OUI_FROM_DATABASE=DigitAll World Co., Ltd
+
+OUI:000F1D*
+ ID_OUI_FROM_DATABASE=Cosmo Techs Co., Ltd.
+
+OUI:000F1E*
+ ID_OUI_FROM_DATABASE=Chengdu KT Electric Co.of High & New Technology
+
+OUI:000F1F*
+ ID_OUI_FROM_DATABASE=WW PCBA Test
+
+OUI:000F20*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:000F21*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta, Inc
+
+OUI:000F22*
+ ID_OUI_FROM_DATABASE=Helius, Inc.
+
+OUI:000F23*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000F24*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000F25*
+ ID_OUI_FROM_DATABASE=AimValley B.V.
+
+OUI:000F26*
+ ID_OUI_FROM_DATABASE=WorldAccxx  LLC
+
+OUI:000F27*
+ ID_OUI_FROM_DATABASE=TEAL Electronics, Inc.
+
+OUI:000F28*
+ ID_OUI_FROM_DATABASE=Itronix Corporation
+
+OUI:000F29*
+ ID_OUI_FROM_DATABASE=Augmentix Corporation
+
+OUI:000F2A*
+ ID_OUI_FROM_DATABASE=Cableware Electronics
+
+OUI:000F2B*
+ ID_OUI_FROM_DATABASE=GREENBELL SYSTEMS
+
+OUI:000F2C*
+ ID_OUI_FROM_DATABASE=Uplogix, Inc.
+
+OUI:000F2D*
+ ID_OUI_FROM_DATABASE=CHUNG-HSIN ELECTRIC & MACHINERY MFG.CORP.
+
+OUI:000F2E*
+ ID_OUI_FROM_DATABASE=Megapower International Corp.
+
+OUI:000F2F*
+ ID_OUI_FROM_DATABASE=W-LINX TECHNOLOGY CO., LTD.
+
+OUI:000F30*
+ ID_OUI_FROM_DATABASE=Raza Microelectronics Inc
+
+OUI:000F31*
+ ID_OUI_FROM_DATABASE=Allied Vision Technologies Canada Inc
+
+OUI:000F32*
+ ID_OUI_FROM_DATABASE=Lootom Optoelectronic Technology (Wuxi) Co Ltd
+
+OUI:000F33*
+ ID_OUI_FROM_DATABASE=DUALi Inc.
+
+OUI:000F34*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000F35*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000F36*
+ ID_OUI_FROM_DATABASE=Accurate Techhnologies, Inc.
+
+OUI:000F37*
+ ID_OUI_FROM_DATABASE=Xambala Incorporated
+
+OUI:000F38*
+ ID_OUI_FROM_DATABASE=Netstar
+
+OUI:000F39*
+ ID_OUI_FROM_DATABASE=IRIS SENSORS
+
+OUI:000F3A*
+ ID_OUI_FROM_DATABASE=HISHARP
+
+OUI:000F3B*
+ ID_OUI_FROM_DATABASE=Fuji System Machines Co., Ltd.
+
+OUI:000F3C*
+ ID_OUI_FROM_DATABASE=Endeleo Limited
+
+OUI:000F3D*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:000F3E*
+ ID_OUI_FROM_DATABASE=CardioNet, Inc
+
+OUI:000F3F*
+ ID_OUI_FROM_DATABASE=Big Bear Networks
+
+OUI:000F40*
+ ID_OUI_FROM_DATABASE=Optical Internetworking Forum
+
+OUI:000F41*
+ ID_OUI_FROM_DATABASE=Zipher Ltd
+
+OUI:000F42*
+ ID_OUI_FROM_DATABASE=Xalyo Systems
+
+OUI:000F43*
+ ID_OUI_FROM_DATABASE=Wasabi Systems Inc.
+
+OUI:000F44*
+ ID_OUI_FROM_DATABASE=Tivella Inc.
+
+OUI:000F45*
+ ID_OUI_FROM_DATABASE=Stretch, Inc.
+
+OUI:000F46*
+ ID_OUI_FROM_DATABASE=SINAR AG
+
+OUI:000F47*
+ ID_OUI_FROM_DATABASE=ROBOX SPA
+
+OUI:000F48*
+ ID_OUI_FROM_DATABASE=Polypix Inc.
+
+OUI:000F49*
+ ID_OUI_FROM_DATABASE=Northover Solutions Limited
+
+OUI:000F4A*
+ ID_OUI_FROM_DATABASE=Kyushu-kyohan co.,ltd
+
+OUI:000F4B*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:000F4C*
+ ID_OUI_FROM_DATABASE=Elextech INC
+
+OUI:000F4D*
+ ID_OUI_FROM_DATABASE=TalkSwitch
+
+OUI:000F4E*
+ ID_OUI_FROM_DATABASE=Cellink
+
+OUI:000F4F*
+ ID_OUI_FROM_DATABASE=Cadmus Technology Ltd
+
+OUI:000F50*
+ ID_OUI_FROM_DATABASE=StreamScale Limited
+
+OUI:000F51*
+ ID_OUI_FROM_DATABASE=Azul Systems, Inc.
+
+OUI:000F52*
+ ID_OUI_FROM_DATABASE=YORK Refrigeration, Marine & Controls
+
+OUI:000F53*
+ ID_OUI_FROM_DATABASE=Solarflare Communications Inc
+
+OUI:000F54*
+ ID_OUI_FROM_DATABASE=Entrelogic Corporation
+
+OUI:000F55*
+ ID_OUI_FROM_DATABASE=Datawire Communication Networks Inc.
+
+OUI:000F56*
+ ID_OUI_FROM_DATABASE=Continuum Photonics Inc
+
+OUI:000F57*
+ ID_OUI_FROM_DATABASE=CABLELOGIC Co., Ltd.
+
+OUI:000F58*
+ ID_OUI_FROM_DATABASE=Adder Technology Limited
+
+OUI:000F59*
+ ID_OUI_FROM_DATABASE=Phonak Communications AG
+
+OUI:000F5A*
+ ID_OUI_FROM_DATABASE=Peribit Networks
+
+OUI:000F5B*
+ ID_OUI_FROM_DATABASE=Delta Information Systems, Inc.
+
+OUI:000F5C*
+ ID_OUI_FROM_DATABASE=Day One Digital Media Limited
+
+OUI:000F5D*
+ ID_OUI_FROM_DATABASE=PacketFront International AB
+
+OUI:000F5E*
+ ID_OUI_FROM_DATABASE=Veo
+
+OUI:000F5F*
+ ID_OUI_FROM_DATABASE=Nicety Technologies Inc. (NTS)
+
+OUI:000F60*
+ ID_OUI_FROM_DATABASE=Lifetron Co.,Ltd
+
+OUI:000F61*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:000F62*
+ ID_OUI_FROM_DATABASE=Alcatel Bell Space N.V.
+
+OUI:000F63*
+ ID_OUI_FROM_DATABASE=Obzerv Technologies
+
+OUI:000F64*
+ ID_OUI_FROM_DATABASE=D&R Electronica Weesp BV
+
+OUI:000F65*
+ ID_OUI_FROM_DATABASE=icube Corp.
+
+OUI:000F66*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys
+
+OUI:000F67*
+ ID_OUI_FROM_DATABASE=West Instruments
+
+OUI:000F68*
+ ID_OUI_FROM_DATABASE=Vavic Network Technology, Inc.
+
+OUI:000F69*
+ ID_OUI_FROM_DATABASE=SEW Eurodrive GmbH & Co. KG
+
+OUI:000F6A*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000F6B*
+ ID_OUI_FROM_DATABASE=GateWare Communications GmbH
+
+OUI:000F6C*
+ ID_OUI_FROM_DATABASE=ADDI-DATA GmbH
+
+OUI:000F6D*
+ ID_OUI_FROM_DATABASE=Midas Engineering
+
+OUI:000F6E*
+ ID_OUI_FROM_DATABASE=BBox
+
+OUI:000F6F*
+ ID_OUI_FROM_DATABASE=FTA Communication Technologies
+
+OUI:000F70*
+ ID_OUI_FROM_DATABASE=Wintec Industries, inc.
+
+OUI:000F71*
+ ID_OUI_FROM_DATABASE=Sanmei Electronics Co.,Ltd
+
+OUI:000F72*
+ ID_OUI_FROM_DATABASE=Sandburst
+
+OUI:000F73*
+ ID_OUI_FROM_DATABASE=RS Automation Co., Ltd
+
+OUI:000F74*
+ ID_OUI_FROM_DATABASE=Qamcom Technology AB
+
+OUI:000F75*
+ ID_OUI_FROM_DATABASE=First Silicon Solutions
+
+OUI:000F76*
+ ID_OUI_FROM_DATABASE=Digital Keystone, Inc.
+
+OUI:000F77*
+ ID_OUI_FROM_DATABASE=DENTUM CO.,LTD
+
+OUI:000F78*
+ ID_OUI_FROM_DATABASE=Datacap Systems Inc
+
+OUI:000F79*
+ ID_OUI_FROM_DATABASE=Bluetooth Interest Group Inc.
+
+OUI:000F7A*
+ ID_OUI_FROM_DATABASE=BeiJing NuQX Technology CO.,LTD
+
+OUI:000F7B*
+ ID_OUI_FROM_DATABASE=Arce Sistemas, S.A.
+
+OUI:000F7C*
+ ID_OUI_FROM_DATABASE=ACTi Corporation
+
+OUI:000F7D*
+ ID_OUI_FROM_DATABASE=Xirrus
+
+OUI:000F7E*
+ ID_OUI_FROM_DATABASE=Ablerex Electronics Co., LTD
+
+OUI:000F7F*
+ ID_OUI_FROM_DATABASE=UBSTORAGE Co.,Ltd.
+
+OUI:000F80*
+ ID_OUI_FROM_DATABASE=Trinity Security Systems,Inc.
+
+OUI:000F81*
+ ID_OUI_FROM_DATABASE=Secure Info Imaging
+
+OUI:000F82*
+ ID_OUI_FROM_DATABASE=Mortara Instrument, Inc.
+
+OUI:000F83*
+ ID_OUI_FROM_DATABASE=Brainium Technologies Inc.
+
+OUI:000F84*
+ ID_OUI_FROM_DATABASE=Astute Networks, Inc.
+
+OUI:000F85*
+ ID_OUI_FROM_DATABASE=ADDO-Japan Corporation
+
+OUI:000F86*
+ ID_OUI_FROM_DATABASE=Research In Motion Limited
+
+OUI:000F87*
+ ID_OUI_FROM_DATABASE=Maxcess International
+
+OUI:000F88*
+ ID_OUI_FROM_DATABASE=AMETEK, Inc.
+
+OUI:000F89*
+ ID_OUI_FROM_DATABASE=Winnertec System Co., Ltd.
+
+OUI:000F8A*
+ ID_OUI_FROM_DATABASE=WideView
+
+OUI:000F8B*
+ ID_OUI_FROM_DATABASE=Orion MultiSystems Inc
+
+OUI:000F8C*
+ ID_OUI_FROM_DATABASE=Gigawavetech Pte Ltd
+
+OUI:000F8D*
+ ID_OUI_FROM_DATABASE=FAST TV-Server AG
+
+OUI:000F8E*
+ ID_OUI_FROM_DATABASE=DONGYANG TELECOM CO.,LTD.
+
+OUI:000F8F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000F90*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000F91*
+ ID_OUI_FROM_DATABASE=Aerotelecom Co.,Ltd.
+
+OUI:000F92*
+ ID_OUI_FROM_DATABASE=Microhard Systems Inc.
+
+OUI:000F93*
+ ID_OUI_FROM_DATABASE=Landis+Gyr Ltd.
+
+OUI:000F94*
+ ID_OUI_FROM_DATABASE=Genexis
+
+OUI:000F95*
+ ID_OUI_FROM_DATABASE=ELECOM Co.,LTD Laneed Division
+
+OUI:000F96*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:000F97*
+ ID_OUI_FROM_DATABASE=Avanex Corporation
+
+OUI:000F98*
+ ID_OUI_FROM_DATABASE=Avamax Co. Ltd.
+
+OUI:000F99*
+ ID_OUI_FROM_DATABASE=APAC opto Electronics Inc.
+
+OUI:000F9A*
+ ID_OUI_FROM_DATABASE=Synchrony, Inc.
+
+OUI:000F9B*
+ ID_OUI_FROM_DATABASE=Ross Video Limited
+
+OUI:000F9C*
+ ID_OUI_FROM_DATABASE=Panduit Corp
+
+OUI:000F9D*
+ ID_OUI_FROM_DATABASE=DisplayLink (UK) Ltd
+
+OUI:000F9E*
+ ID_OUI_FROM_DATABASE=Murrelektronik GmbH
+
+OUI:000F9F*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:000FA0*
+ ID_OUI_FROM_DATABASE=CANON KOREA BUSINESS SOLUTIONS INC.
+
+OUI:000FA1*
+ ID_OUI_FROM_DATABASE=Gigabit Systems Inc.
+
+OUI:000FA2*
+ ID_OUI_FROM_DATABASE=Digital Path Networks
+
+OUI:000FA3*
+ ID_OUI_FROM_DATABASE=Alpha Networks Inc.
+
+OUI:000FA4*
+ ID_OUI_FROM_DATABASE=Sprecher Automation GmbH
+
+OUI:000FA5*
+ ID_OUI_FROM_DATABASE=BWA Technology GmbH
+
+OUI:000FA6*
+ ID_OUI_FROM_DATABASE=S2 Security Corporation
+
+OUI:000FA7*
+ ID_OUI_FROM_DATABASE=Raptor Networks Technology
+
+OUI:000FA8*
+ ID_OUI_FROM_DATABASE=Photometrics, Inc.
+
+OUI:000FA9*
+ ID_OUI_FROM_DATABASE=PC Fabrik
+
+OUI:000FAA*
+ ID_OUI_FROM_DATABASE=Nexus Technologies
+
+OUI:000FAB*
+ ID_OUI_FROM_DATABASE=Kyushu Electronics Systems Inc.
+
+OUI:000FAC*
+ ID_OUI_FROM_DATABASE=IEEE 802.11
+
+OUI:000FAD*
+ ID_OUI_FROM_DATABASE=FMN communications GmbH
+
+OUI:000FAE*
+ ID_OUI_FROM_DATABASE=E2O Communications
+
+OUI:000FAF*
+ ID_OUI_FROM_DATABASE=Dialog Inc.
+
+OUI:000FB0*
+ ID_OUI_FROM_DATABASE=Compal Electronics,INC.
+
+OUI:000FB1*
+ ID_OUI_FROM_DATABASE=Cognio Inc.
+
+OUI:000FB2*
+ ID_OUI_FROM_DATABASE=Broadband Pacenet (India) Pvt. Ltd.
+
+OUI:000FB3*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:000FB4*
+ ID_OUI_FROM_DATABASE=Timespace Technology
+
+OUI:000FB5*
+ ID_OUI_FROM_DATABASE=NETGEAR Inc
+
+OUI:000FB6*
+ ID_OUI_FROM_DATABASE=Europlex Technologies
+
+OUI:000FB7*
+ ID_OUI_FROM_DATABASE=Cavium Networks
+
+OUI:000FB8*
+ ID_OUI_FROM_DATABASE=CallURL Inc.
+
+OUI:000FB9*
+ ID_OUI_FROM_DATABASE=Adaptive Instruments
+
+OUI:000FBA*
+ ID_OUI_FROM_DATABASE=Tevebox AB
+
+OUI:000FBB*
+ ID_OUI_FROM_DATABASE=Nokia Siemens Networks GmbH & Co. KG
+
+OUI:000FBC*
+ ID_OUI_FROM_DATABASE=Onkey Technologies, Inc.
+
+OUI:000FBD*
+ ID_OUI_FROM_DATABASE=MRV Communications (Networks) LTD
+
+OUI:000FBE*
+ ID_OUI_FROM_DATABASE=e-w/you Inc.
+
+OUI:000FBF*
+ ID_OUI_FROM_DATABASE=DGT Sp. z o.o.
+
+OUI:000FC0*
+ ID_OUI_FROM_DATABASE=DELCOMp
+
+OUI:000FC1*
+ ID_OUI_FROM_DATABASE=WAVE Corporation
+
+OUI:000FC2*
+ ID_OUI_FROM_DATABASE=Uniwell Corporation
+
+OUI:000FC3*
+ ID_OUI_FROM_DATABASE=PalmPalm Technology, Inc.
+
+OUI:000FC4*
+ ID_OUI_FROM_DATABASE=NST co.,LTD.
+
+OUI:000FC5*
+ ID_OUI_FROM_DATABASE=KeyMed Ltd
+
+OUI:000FC6*
+ ID_OUI_FROM_DATABASE=Eurocom Industries A/S
+
+OUI:000FC7*
+ ID_OUI_FROM_DATABASE=Dionica R&D Ltd.
+
+OUI:000FC8*
+ ID_OUI_FROM_DATABASE=Chantry Networks
+
+OUI:000FC9*
+ ID_OUI_FROM_DATABASE=Allnet GmbH
+
+OUI:000FCA*
+ ID_OUI_FROM_DATABASE=A-JIN TECHLINE CO, LTD
+
+OUI:000FCB*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:000FCC*
+ ID_OUI_FROM_DATABASE=Netopia, Inc.
+
+OUI:000FCD*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:000FCE*
+ ID_OUI_FROM_DATABASE=Kikusui Electronics Corp.
+
+OUI:000FCF*
+ ID_OUI_FROM_DATABASE=Datawind Research
+
+OUI:000FD0*
+ ID_OUI_FROM_DATABASE=ASTRI
+
+OUI:000FD1*
+ ID_OUI_FROM_DATABASE=Applied Wireless Identifications Group, Inc.
+
+OUI:000FD2*
+ ID_OUI_FROM_DATABASE=EWA Technologies, Inc.
+
+OUI:000FD3*
+ ID_OUI_FROM_DATABASE=Digium
+
+OUI:000FD4*
+ ID_OUI_FROM_DATABASE=Soundcraft
+
+OUI:000FD5*
+ ID_OUI_FROM_DATABASE=Schwechat - RISE
+
+OUI:000FD6*
+ ID_OUI_FROM_DATABASE=Sarotech Co., Ltd
+
+OUI:000FD7*
+ ID_OUI_FROM_DATABASE=Harman Music Group
+
+OUI:000FD8*
+ ID_OUI_FROM_DATABASE=Force, Inc.
+
+OUI:000FD9*
+ ID_OUI_FROM_DATABASE=FlexDSL Telecommunications AG
+
+OUI:000FDA*
+ ID_OUI_FROM_DATABASE=YAZAKI CORPORATION
+
+OUI:000FDB*
+ ID_OUI_FROM_DATABASE=Westell Technologies
+
+OUI:000FDC*
+ ID_OUI_FROM_DATABASE=Ueda Japan  Radio Co., Ltd.
+
+OUI:000FDD*
+ ID_OUI_FROM_DATABASE=SORDIN AB
+
+OUI:000FDE*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:000FDF*
+ ID_OUI_FROM_DATABASE=SOLOMON Technology Corp.
+
+OUI:000FE0*
+ ID_OUI_FROM_DATABASE=NComputing Co.,Ltd.
+
+OUI:000FE1*
+ ID_OUI_FROM_DATABASE=ID DIGITAL CORPORATION
+
+OUI:000FE2*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Ltd.
+
+OUI:000FE3*
+ ID_OUI_FROM_DATABASE=Damm Cellular Systems A/S
+
+OUI:000FE4*
+ ID_OUI_FROM_DATABASE=Pantech Co.,Ltd
+
+OUI:000FE5*
+ ID_OUI_FROM_DATABASE=MERCURY SECURITY CORPORATION
+
+OUI:000FE6*
+ ID_OUI_FROM_DATABASE=MBTech Systems, Inc.
+
+OUI:000FE7*
+ ID_OUI_FROM_DATABASE=Lutron Electronics Co., Inc.
+
+OUI:000FE8*
+ ID_OUI_FROM_DATABASE=Lobos, Inc.
+
+OUI:000FE9*
+ ID_OUI_FROM_DATABASE=GW TECHNOLOGIES CO.,LTD.
+
+OUI:000FEA*
+ ID_OUI_FROM_DATABASE=Giga-Byte Technology Co.,LTD.
+
+OUI:000FEB*
+ ID_OUI_FROM_DATABASE=Cylon Controls
+
+OUI:000FEC*
+ ID_OUI_FROM_DATABASE=Arkus Inc.
+
+OUI:000FED*
+ ID_OUI_FROM_DATABASE=Anam Electronics Co., Ltd
+
+OUI:000FEE*
+ ID_OUI_FROM_DATABASE=XTec, Incorporated
+
+OUI:000FEF*
+ ID_OUI_FROM_DATABASE=Thales e-Transactions GmbH
+
+OUI:000FF0*
+ ID_OUI_FROM_DATABASE=Sunray Co. Ltd.
+
+OUI:000FF1*
+ ID_OUI_FROM_DATABASE=nex-G Systems Pte.Ltd
+
+OUI:000FF2*
+ ID_OUI_FROM_DATABASE=Loud Technologies Inc.
+
+OUI:000FF3*
+ ID_OUI_FROM_DATABASE=Jung Myoung Communications&Technology
+
+OUI:000FF4*
+ ID_OUI_FROM_DATABASE=Guntermann & Drunck GmbH
+
+OUI:000FF5*
+ ID_OUI_FROM_DATABASE=GN&S company
+
+OUI:000FF6*
+ ID_OUI_FROM_DATABASE=Darfon Electronics Corp.
+
+OUI:000FF7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000FF8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:000FF9*
+ ID_OUI_FROM_DATABASE=Valcretec, Inc.
+
+OUI:000FFA*
+ ID_OUI_FROM_DATABASE=Optinel Systems, Inc.
+
+OUI:000FFB*
+ ID_OUI_FROM_DATABASE=Nippon Denso Industry Co., Ltd.
+
+OUI:000FFC*
+ ID_OUI_FROM_DATABASE=Merit Li-Lin Ent.
+
+OUI:000FFD*
+ ID_OUI_FROM_DATABASE=Glorytek Network Inc.
+
+OUI:000FFE*
+ ID_OUI_FROM_DATABASE=G-PRO COMPUTER
+
+OUI:000FFF*
+ ID_OUI_FROM_DATABASE=Control4
+
+OUI:001000*
+ ID_OUI_FROM_DATABASE=CABLE TELEVISION LABORATORIES, INC.
+
+OUI:001001*
+ ID_OUI_FROM_DATABASE=Citel
+
+OUI:001002*
+ ID_OUI_FROM_DATABASE=ACTIA
+
+OUI:001003*
+ ID_OUI_FROM_DATABASE=IMATRON, INC.
+
+OUI:001004*
+ ID_OUI_FROM_DATABASE=THE BRANTLEY COILE COMPANY,INC
+
+OUI:001005*
+ ID_OUI_FROM_DATABASE=UEC COMMERCIAL
+
+OUI:001006*
+ ID_OUI_FROM_DATABASE=Thales Contact Solutions Ltd.
+
+OUI:001007*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001008*
+ ID_OUI_FROM_DATABASE=VIENNA SYSTEMS CORPORATION
+
+OUI:001009*
+ ID_OUI_FROM_DATABASE=HORO QUARTZ
+
+OUI:00100A*
+ ID_OUI_FROM_DATABASE=WILLIAMS COMMUNICATIONS GROUP
+
+OUI:00100B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00100C*
+ ID_OUI_FROM_DATABASE=ITO CO., LTD.
+
+OUI:00100D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00100E*
+ ID_OUI_FROM_DATABASE=MICRO LINEAR COPORATION
+
+OUI:00100F*
+ ID_OUI_FROM_DATABASE=INDUSTRIAL CPU SYSTEMS
+
+OUI:001010*
+ ID_OUI_FROM_DATABASE=INITIO CORPORATION
+
+OUI:001011*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001012*
+ ID_OUI_FROM_DATABASE=PROCESSOR SYSTEMS (I) PVT LTD
+
+OUI:001013*
+ ID_OUI_FROM_DATABASE=Kontron America, Inc.
+
+OUI:001014*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001015*
+ ID_OUI_FROM_DATABASE=OOmon Inc.
+
+OUI:001016*
+ ID_OUI_FROM_DATABASE=T.SQWARE
+
+OUI:001017*
+ ID_OUI_FROM_DATABASE=Bosch Access Systems GmbH
+
+OUI:001018*
+ ID_OUI_FROM_DATABASE=BROADCOM CORPORATION
+
+OUI:001019*
+ ID_OUI_FROM_DATABASE=SIRONA DENTAL SYSTEMS GmbH & Co. KG
+
+OUI:00101A*
+ ID_OUI_FROM_DATABASE=PictureTel Corp.
+
+OUI:00101B*
+ ID_OUI_FROM_DATABASE=CORNET TECHNOLOGY, INC.
+
+OUI:00101C*
+ ID_OUI_FROM_DATABASE=OHM TECHNOLOGIES INTL, LLC
+
+OUI:00101D*
+ ID_OUI_FROM_DATABASE=WINBOND ELECTRONICS CORP.
+
+OUI:00101E*
+ ID_OUI_FROM_DATABASE=MATSUSHITA ELECTRONIC INSTRUMENTS CORP.
+
+OUI:00101F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001020*
+ ID_OUI_FROM_DATABASE=Hand Held Products Inc
+
+OUI:001021*
+ ID_OUI_FROM_DATABASE=ENCANTO NETWORKS, INC.
+
+OUI:001022*
+ ID_OUI_FROM_DATABASE=SatCom Media Corporation
+
+OUI:001023*
+ ID_OUI_FROM_DATABASE=Network Equipment Technologies
+
+OUI:001024*
+ ID_OUI_FROM_DATABASE=NAGOYA ELECTRIC WORKS CO., LTD
+
+OUI:001025*
+ ID_OUI_FROM_DATABASE=Grayhill, Inc
+
+OUI:001026*
+ ID_OUI_FROM_DATABASE=ACCELERATED NETWORKS, INC.
+
+OUI:001027*
+ ID_OUI_FROM_DATABASE=L-3 COMMUNICATIONS EAST
+
+OUI:001028*
+ ID_OUI_FROM_DATABASE=COMPUTER TECHNICA, INC.
+
+OUI:001029*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00102A*
+ ID_OUI_FROM_DATABASE=ZF MICROSYSTEMS, INC.
+
+OUI:00102B*
+ ID_OUI_FROM_DATABASE=UMAX DATA SYSTEMS, INC.
+
+OUI:00102C*
+ ID_OUI_FROM_DATABASE=Lasat Networks A/S
+
+OUI:00102D*
+ ID_OUI_FROM_DATABASE=HITACHI SOFTWARE ENGINEERING
+
+OUI:00102E*
+ ID_OUI_FROM_DATABASE=NETWORK SYSTEMS & TECHNOLOGIES PVT. LTD.
+
+OUI:00102F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001030*
+ ID_OUI_FROM_DATABASE=EION Inc.
+
+OUI:001031*
+ ID_OUI_FROM_DATABASE=OBJECTIVE COMMUNICATIONS, INC.
+
+OUI:001032*
+ ID_OUI_FROM_DATABASE=ALTA TECHNOLOGY
+
+OUI:001033*
+ ID_OUI_FROM_DATABASE=ACCESSLAN COMMUNICATIONS, INC.
+
+OUI:001034*
+ ID_OUI_FROM_DATABASE=GNP Computers
+
+OUI:001035*
+ ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEMS CO., LTD
+
+OUI:001036*
+ ID_OUI_FROM_DATABASE=INTER-TEL INTEGRATED SYSTEMS
+
+OUI:001037*
+ ID_OUI_FROM_DATABASE=CYQ've Technology Co., Ltd.
+
+OUI:001038*
+ ID_OUI_FROM_DATABASE=MICRO RESEARCH INSTITUTE, INC.
+
+OUI:001039*
+ ID_OUI_FROM_DATABASE=Vectron Systems AG
+
+OUI:00103A*
+ ID_OUI_FROM_DATABASE=DIAMOND NETWORK TECH
+
+OUI:00103B*
+ ID_OUI_FROM_DATABASE=HIPPI NETWORKING FORUM
+
+OUI:00103C*
+ ID_OUI_FROM_DATABASE=IC ENSEMBLE, INC.
+
+OUI:00103D*
+ ID_OUI_FROM_DATABASE=PHASECOM, LTD.
+
+OUI:00103E*
+ ID_OUI_FROM_DATABASE=NETSCHOOLS CORPORATION
+
+OUI:00103F*
+ ID_OUI_FROM_DATABASE=TOLLGRADE COMMUNICATIONS, INC.
+
+OUI:001040*
+ ID_OUI_FROM_DATABASE=INTERMEC CORPORATION
+
+OUI:001041*
+ ID_OUI_FROM_DATABASE=BRISTOL BABCOCK, INC.
+
+OUI:001042*
+ ID_OUI_FROM_DATABASE=Alacritech, Inc.
+
+OUI:001043*
+ ID_OUI_FROM_DATABASE=A2 CORPORATION
+
+OUI:001044*
+ ID_OUI_FROM_DATABASE=InnoLabs Corporation
+
+OUI:001045*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001046*
+ ID_OUI_FROM_DATABASE=ALCORN MCBRIDE INC.
+
+OUI:001047*
+ ID_OUI_FROM_DATABASE=ECHO ELETRIC CO. LTD.
+
+OUI:001048*
+ ID_OUI_FROM_DATABASE=HTRC AUTOMATION, INC.
+
+OUI:001049*
+ ID_OUI_FROM_DATABASE=ShoreTel, Inc
+
+OUI:00104A*
+ ID_OUI_FROM_DATABASE=The Parvus Corporation
+
+OUI:00104B*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:00104C*
+ ID_OUI_FROM_DATABASE=LeCroy Corporation
+
+OUI:00104D*
+ ID_OUI_FROM_DATABASE=SURTEC INDUSTRIES, INC.
+
+OUI:00104E*
+ ID_OUI_FROM_DATABASE=CEOLOGIC
+
+OUI:00104F*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:001050*
+ ID_OUI_FROM_DATABASE=RION CO., LTD.
+
+OUI:001051*
+ ID_OUI_FROM_DATABASE=CMICRO CORPORATION
+
+OUI:001052*
+ ID_OUI_FROM_DATABASE=METTLER-TOLEDO (ALBSTADT) GMBH
+
+OUI:001053*
+ ID_OUI_FROM_DATABASE=COMPUTER TECHNOLOGY CORP.
+
+OUI:001054*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001055*
+ ID_OUI_FROM_DATABASE=FUJITSU MICROELECTRONICS, INC.
+
+OUI:001056*
+ ID_OUI_FROM_DATABASE=SODICK CO., LTD.
+
+OUI:001057*
+ ID_OUI_FROM_DATABASE=Rebel.com, Inc.
+
+OUI:001058*
+ ID_OUI_FROM_DATABASE=ArrowPoint Communications
+
+OUI:001059*
+ ID_OUI_FROM_DATABASE=DIABLO RESEARCH CO. LLC
+
+OUI:00105A*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:00105B*
+ ID_OUI_FROM_DATABASE=NET INSIGHT AB
+
+OUI:00105C*
+ ID_OUI_FROM_DATABASE=QUANTUM DESIGNS (H.K.) LTD.
+
+OUI:00105D*
+ ID_OUI_FROM_DATABASE=Draeger Medical
+
+OUI:00105E*
+ ID_OUI_FROM_DATABASE=HEKIMIAN LABORATORIES, INC.
+
+OUI:00105F*
+ ID_OUI_FROM_DATABASE=ZODIAC DATA SYSTEMS
+
+OUI:001060*
+ ID_OUI_FROM_DATABASE=BILLIONTON SYSTEMS, INC.
+
+OUI:001061*
+ ID_OUI_FROM_DATABASE=HOSTLINK CORP.
+
+OUI:001062*
+ ID_OUI_FROM_DATABASE=NX SERVER, ILNC.
+
+OUI:001063*
+ ID_OUI_FROM_DATABASE=STARGUIDE DIGITAL NETWORKS
+
+OUI:001064*
+ ID_OUI_FROM_DATABASE=DNPG, LLC
+
+OUI:001065*
+ ID_OUI_FROM_DATABASE=RADYNE CORPORATION
+
+OUI:001066*
+ ID_OUI_FROM_DATABASE=ADVANCED CONTROL SYSTEMS, INC.
+
+OUI:001067*
+ ID_OUI_FROM_DATABASE=Ericsson
+
+OUI:001068*
+ ID_OUI_FROM_DATABASE=COMOS TELECOM
+
+OUI:001069*
+ ID_OUI_FROM_DATABASE=HELIOSS COMMUNICATIONS, INC.
+
+OUI:00106A*
+ ID_OUI_FROM_DATABASE=DIGITAL MICROWAVE CORPORATION
+
+OUI:00106B*
+ ID_OUI_FROM_DATABASE=SONUS NETWORKS, INC.
+
+OUI:00106C*
+ ID_OUI_FROM_DATABASE=Infratec AG
+
+OUI:00106D*
+ ID_OUI_FROM_DATABASE=Axxcelera Broadband Wireless
+
+OUI:00106E*
+ ID_OUI_FROM_DATABASE=TADIRAN COM. LTD.
+
+OUI:00106F*
+ ID_OUI_FROM_DATABASE=TRENTON TECHNOLOGY INC.
+
+OUI:001070*
+ ID_OUI_FROM_DATABASE=CARADON TREND LTD.
+
+OUI:001071*
+ ID_OUI_FROM_DATABASE=ADVANET INC.
+
+OUI:001072*
+ ID_OUI_FROM_DATABASE=GVN TECHNOLOGIES, INC.
+
+OUI:001073*
+ ID_OUI_FROM_DATABASE=Technobox, Inc.
+
+OUI:001074*
+ ID_OUI_FROM_DATABASE=ATEN INTERNATIONAL CO., LTD.
+
+OUI:001075*
+ ID_OUI_FROM_DATABASE=Maxtor Corporation
+
+OUI:001076*
+ ID_OUI_FROM_DATABASE=EUREM GmbH
+
+OUI:001077*
+ ID_OUI_FROM_DATABASE=SAF DRIVE SYSTEMS, LTD.
+
+OUI:001078*
+ ID_OUI_FROM_DATABASE=NUERA COMMUNICATIONS, INC.
+
+OUI:001079*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00107A*
+ ID_OUI_FROM_DATABASE=AmbiCom, Inc.
+
+OUI:00107B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00107C*
+ ID_OUI_FROM_DATABASE=P-COM, INC.
+
+OUI:00107D*
+ ID_OUI_FROM_DATABASE=AURORA COMMUNICATIONS, LTD.
+
+OUI:00107E*
+ ID_OUI_FROM_DATABASE=BACHMANN ELECTRONIC GmbH
+
+OUI:00107F*
+ ID_OUI_FROM_DATABASE=CRESTRON ELECTRONICS, INC.
+
+OUI:001080*
+ ID_OUI_FROM_DATABASE=METAWAVE COMMUNICATIONS
+
+OUI:001081*
+ ID_OUI_FROM_DATABASE=DPS, INC.
+
+OUI:001082*
+ ID_OUI_FROM_DATABASE=JNA TELECOMMUNICATIONS LIMITED
+
+OUI:001083*
+ ID_OUI_FROM_DATABASE=HEWLETT-PACKARD COMPANY
+
+OUI:001084*
+ ID_OUI_FROM_DATABASE=K-BOT COMMUNICATIONS
+
+OUI:001085*
+ ID_OUI_FROM_DATABASE=POLARIS COMMUNICATIONS, INC.
+
+OUI:001086*
+ ID_OUI_FROM_DATABASE=ATTO Technology, Inc.
+
+OUI:001087*
+ ID_OUI_FROM_DATABASE=Xstreamis PLC
+
+OUI:001088*
+ ID_OUI_FROM_DATABASE=AMERICAN NETWORKS INC.
+
+OUI:001089*
+ ID_OUI_FROM_DATABASE=WebSonic
+
+OUI:00108A*
+ ID_OUI_FROM_DATABASE=TeraLogic, Inc.
+
+OUI:00108B*
+ ID_OUI_FROM_DATABASE=LASERANIMATION SOLLINGER GmbH
+
+OUI:00108C*
+ ID_OUI_FROM_DATABASE=FUJITSU TELECOMMUNICATIONS EUROPE, LTD.
+
+OUI:00108D*
+ ID_OUI_FROM_DATABASE=Johnson Controls, Inc.
+
+OUI:00108E*
+ ID_OUI_FROM_DATABASE=HUGH SYMONS CONCEPT Technologies Ltd.
+
+OUI:00108F*
+ ID_OUI_FROM_DATABASE=RAPTOR SYSTEMS
+
+OUI:001090*
+ ID_OUI_FROM_DATABASE=CIMETRICS, INC.
+
+OUI:001091*
+ ID_OUI_FROM_DATABASE=NO WIRES NEEDED BV
+
+OUI:001092*
+ ID_OUI_FROM_DATABASE=NETCORE INC.
+
+OUI:001093*
+ ID_OUI_FROM_DATABASE=CMS COMPUTERS, LTD.
+
+OUI:001094*
+ ID_OUI_FROM_DATABASE=Performance Analysis Broadband, Spirent plc
+
+OUI:001095*
+ ID_OUI_FROM_DATABASE=Thomson Inc.
+
+OUI:001096*
+ ID_OUI_FROM_DATABASE=TRACEWELL SYSTEMS, INC.
+
+OUI:001097*
+ ID_OUI_FROM_DATABASE=WinNet Metropolitan Communications Systems, Inc.
+
+OUI:001098*
+ ID_OUI_FROM_DATABASE=STARNET TECHNOLOGIES, INC.
+
+OUI:001099*
+ ID_OUI_FROM_DATABASE=InnoMedia, Inc.
+
+OUI:00109A*
+ ID_OUI_FROM_DATABASE=NETLINE
+
+OUI:00109B*
+ ID_OUI_FROM_DATABASE=Emulex Corporation
+
+OUI:00109C*
+ ID_OUI_FROM_DATABASE=M-SYSTEM CO., LTD.
+
+OUI:00109D*
+ ID_OUI_FROM_DATABASE=CLARINET SYSTEMS, INC.
+
+OUI:00109E*
+ ID_OUI_FROM_DATABASE=AWARE, INC.
+
+OUI:00109F*
+ ID_OUI_FROM_DATABASE=PAVO, INC.
+
+OUI:0010A0*
+ ID_OUI_FROM_DATABASE=INNOVEX TECHNOLOGIES, INC.
+
+OUI:0010A1*
+ ID_OUI_FROM_DATABASE=KENDIN SEMICONDUCTOR, INC.
+
+OUI:0010A2*
+ ID_OUI_FROM_DATABASE=TNS
+
+OUI:0010A3*
+ ID_OUI_FROM_DATABASE=OMNITRONIX, INC.
+
+OUI:0010A4*
+ ID_OUI_FROM_DATABASE=XIRCOM
+
+OUI:0010A5*
+ ID_OUI_FROM_DATABASE=OXFORD INSTRUMENTS
+
+OUI:0010A6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0010A7*
+ ID_OUI_FROM_DATABASE=UNEX TECHNOLOGY CORPORATION
+
+OUI:0010A8*
+ ID_OUI_FROM_DATABASE=RELIANCE COMPUTER CORP.
+
+OUI:0010A9*
+ ID_OUI_FROM_DATABASE=ADHOC TECHNOLOGIES
+
+OUI:0010AA*
+ ID_OUI_FROM_DATABASE=MEDIA4, INC.
+
+OUI:0010AB*
+ ID_OUI_FROM_DATABASE=KOITO ELECTRIC INDUSTRIES, LTD.
+
+OUI:0010AC*
+ ID_OUI_FROM_DATABASE=IMCI TECHNOLOGIES
+
+OUI:0010AD*
+ ID_OUI_FROM_DATABASE=SOFTRONICS USB, INC.
+
+OUI:0010AE*
+ ID_OUI_FROM_DATABASE=SHINKO ELECTRIC INDUSTRIES CO.
+
+OUI:0010AF*
+ ID_OUI_FROM_DATABASE=TAC SYSTEMS, INC.
+
+OUI:0010B0*
+ ID_OUI_FROM_DATABASE=MERIDIAN TECHNOLOGY CORP.
+
+OUI:0010B1*
+ ID_OUI_FROM_DATABASE=FOR-A CO., LTD.
+
+OUI:0010B2*
+ ID_OUI_FROM_DATABASE=COACTIVE AESTHETICS
+
+OUI:0010B3*
+ ID_OUI_FROM_DATABASE=NOKIA MULTIMEDIA TERMINALS
+
+OUI:0010B4*
+ ID_OUI_FROM_DATABASE=ATMOSPHERE NETWORKS
+
+OUI:0010B5*
+ ID_OUI_FROM_DATABASE=ACCTON TECHNOLOGY CORPORATION
+
+OUI:0010B6*
+ ID_OUI_FROM_DATABASE=ENTRATA COMMUNICATIONS CORP.
+
+OUI:0010B7*
+ ID_OUI_FROM_DATABASE=COYOTE TECHNOLOGIES, LLC
+
+OUI:0010B8*
+ ID_OUI_FROM_DATABASE=ISHIGAKI COMPUTER SYSTEM CO.
+
+OUI:0010B9*
+ ID_OUI_FROM_DATABASE=MAXTOR CORP.
+
+OUI:0010BA*
+ ID_OUI_FROM_DATABASE=MARTINHO-DAVIS SYSTEMS, INC.
+
+OUI:0010BB*
+ ID_OUI_FROM_DATABASE=DATA & INFORMATION TECHNOLOGY
+
+OUI:0010BC*
+ ID_OUI_FROM_DATABASE=Aastra Telecom
+
+OUI:0010BD*
+ ID_OUI_FROM_DATABASE=THE TELECOMMUNICATION TECHNOLOGY COMMITTEE (TTC)
+
+OUI:0010BE*
+ ID_OUI_FROM_DATABASE=MARCH NETWORKS CORPORATION
+
+OUI:0010BF*
+ ID_OUI_FROM_DATABASE=InterAir Wireless
+
+OUI:0010C0*
+ ID_OUI_FROM_DATABASE=ARMA, Inc.
+
+OUI:0010C1*
+ ID_OUI_FROM_DATABASE=OI ELECTRIC CO., LTD.
+
+OUI:0010C2*
+ ID_OUI_FROM_DATABASE=WILLNET, INC.
+
+OUI:0010C3*
+ ID_OUI_FROM_DATABASE=CSI-CONTROL SYSTEMS
+
+OUI:0010C4*
+ ID_OUI_FROM_DATABASE=MEDIA LINKS CO., LTD.
+
+OUI:0010C5*
+ ID_OUI_FROM_DATABASE=PROTOCOL TECHNOLOGIES, INC.
+
+OUI:0010C6*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:0010C7*
+ ID_OUI_FROM_DATABASE=DATA TRANSMISSION NETWORK
+
+OUI:0010C8*
+ ID_OUI_FROM_DATABASE=COMMUNICATIONS ELECTRONICS SECURITY GROUP
+
+OUI:0010C9*
+ ID_OUI_FROM_DATABASE=MITSUBISHI ELECTRONICS LOGISTIC SUPPORT CO.
+
+OUI:0010CA*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:0010CB*
+ ID_OUI_FROM_DATABASE=FACIT K.K.
+
+OUI:0010CC*
+ ID_OUI_FROM_DATABASE=CLP COMPUTER LOGISTIK PLANUNG GmbH
+
+OUI:0010CD*
+ ID_OUI_FROM_DATABASE=INTERFACE CONCEPT
+
+OUI:0010CE*
+ ID_OUI_FROM_DATABASE=VOLAMP, LTD.
+
+OUI:0010CF*
+ ID_OUI_FROM_DATABASE=FIBERLANE COMMUNICATIONS
+
+OUI:0010D0*
+ ID_OUI_FROM_DATABASE=WITCOM, LTD.
+
+OUI:0010D1*
+ ID_OUI_FROM_DATABASE=Top Layer Networks, Inc.
+
+OUI:0010D2*
+ ID_OUI_FROM_DATABASE=NITTO TSUSHINKI CO., LTD
+
+OUI:0010D3*
+ ID_OUI_FROM_DATABASE=GRIPS ELECTRONIC GMBH
+
+OUI:0010D4*
+ ID_OUI_FROM_DATABASE=STORAGE COMPUTER CORPORATION
+
+OUI:0010D5*
+ ID_OUI_FROM_DATABASE=IMASDE CANARIAS, S.A.
+
+OUI:0010D6*
+ ID_OUI_FROM_DATABASE=ITT - A/CD
+
+OUI:0010D7*
+ ID_OUI_FROM_DATABASE=ARGOSY RESEARCH INC.
+
+OUI:0010D8*
+ ID_OUI_FROM_DATABASE=CALISTA
+
+OUI:0010D9*
+ ID_OUI_FROM_DATABASE=IBM JAPAN, FUJISAWA MT+D
+
+OUI:0010DA*
+ ID_OUI_FROM_DATABASE=MOTION ENGINEERING, INC.
+
+OUI:0010DB*
+ ID_OUI_FROM_DATABASE=Juniper Networks, Inc.
+
+OUI:0010DC*
+ ID_OUI_FROM_DATABASE=MICRO-STAR INTERNATIONAL CO., LTD.
+
+OUI:0010DD*
+ ID_OUI_FROM_DATABASE=ENABLE SEMICONDUCTOR, INC.
+
+OUI:0010DE*
+ ID_OUI_FROM_DATABASE=INTERNATIONAL DATACASTING CORPORATION
+
+OUI:0010DF*
+ ID_OUI_FROM_DATABASE=RISE COMPUTER INC.
+
+OUI:0010E0*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:0010E1*
+ ID_OUI_FROM_DATABASE=S.I. TECH, INC.
+
+OUI:0010E2*
+ ID_OUI_FROM_DATABASE=ArrayComm, Inc.
+
+OUI:0010E3*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0010E4*
+ ID_OUI_FROM_DATABASE=NSI CORPORATION
+
+OUI:0010E5*
+ ID_OUI_FROM_DATABASE=SOLECTRON TEXAS
+
+OUI:0010E6*
+ ID_OUI_FROM_DATABASE=APPLIED INTELLIGENT SYSTEMS, INC.
+
+OUI:0010E7*
+ ID_OUI_FROM_DATABASE=BreezeCom
+
+OUI:0010E8*
+ ID_OUI_FROM_DATABASE=TELOCITY, INCORPORATED
+
+OUI:0010E9*
+ ID_OUI_FROM_DATABASE=RAIDTEC LTD.
+
+OUI:0010EA*
+ ID_OUI_FROM_DATABASE=ADEPT TECHNOLOGY
+
+OUI:0010EB*
+ ID_OUI_FROM_DATABASE=SELSIUS SYSTEMS, INC.
+
+OUI:0010EC*
+ ID_OUI_FROM_DATABASE=RPCG, LLC
+
+OUI:0010ED*
+ ID_OUI_FROM_DATABASE=SUNDANCE TECHNOLOGY, INC.
+
+OUI:0010EE*
+ ID_OUI_FROM_DATABASE=CTI PRODUCTS, INC.
+
+OUI:0010EF*
+ ID_OUI_FROM_DATABASE=DBTEL INCORPORATED
+
+OUI:0010F1*
+ ID_OUI_FROM_DATABASE=I-O CORPORATION
+
+OUI:0010F2*
+ ID_OUI_FROM_DATABASE=ANTEC
+
+OUI:0010F3*
+ ID_OUI_FROM_DATABASE=Nexcom International Co., Ltd.
+
+OUI:0010F4*
+ ID_OUI_FROM_DATABASE=Vertical Communications
+
+OUI:0010F5*
+ ID_OUI_FROM_DATABASE=AMHERST SYSTEMS, INC.
+
+OUI:0010F6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0010F7*
+ ID_OUI_FROM_DATABASE=IRIICHI TECHNOLOGIES Inc.
+
+OUI:0010F8*
+ ID_OUI_FROM_DATABASE=Niikke Techno System Co. Ltd
+
+OUI:0010F9*
+ ID_OUI_FROM_DATABASE=UNIQUE SYSTEMS, INC.
+
+OUI:0010FA*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:0010FB*
+ ID_OUI_FROM_DATABASE=ZIDA TECHNOLOGIES LIMITED
+
+OUI:0010FC*
+ ID_OUI_FROM_DATABASE=BROADBAND NETWORKS, INC.
+
+OUI:0010FD*
+ ID_OUI_FROM_DATABASE=COCOM A/S
+
+OUI:0010FE*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:0010FF*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001100*
+ ID_OUI_FROM_DATABASE=Schneider Electric
+
+OUI:001101*
+ ID_OUI_FROM_DATABASE=CET Technologies Pte Ltd
+
+OUI:001102*
+ ID_OUI_FROM_DATABASE=Aurora Multimedia Corp.
+
+OUI:001103*
+ ID_OUI_FROM_DATABASE=kawamura electric inc.
+
+OUI:001104*
+ ID_OUI_FROM_DATABASE=TELEXY
+
+OUI:001105*
+ ID_OUI_FROM_DATABASE=Sunplus Technology Co., Ltd.
+
+OUI:001106*
+ ID_OUI_FROM_DATABASE=Siemens NV (Belgium)
+
+OUI:001107*
+ ID_OUI_FROM_DATABASE=RGB Networks Inc.
+
+OUI:001108*
+ ID_OUI_FROM_DATABASE=Orbital Data Corporation
+
+OUI:001109*
+ ID_OUI_FROM_DATABASE=Micro-Star International
+
+OUI:00110A*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:00110B*
+ ID_OUI_FROM_DATABASE=Franklin Technology Systems
+
+OUI:00110C*
+ ID_OUI_FROM_DATABASE=Atmark Techno, Inc.
+
+OUI:00110D*
+ ID_OUI_FROM_DATABASE=SANBlaze Technology, Inc.
+
+OUI:00110E*
+ ID_OUI_FROM_DATABASE=Tsurusaki Sealand Transportation Co. Ltd.
+
+OUI:00110F*
+ ID_OUI_FROM_DATABASE=netplat,Inc.
+
+OUI:001110*
+ ID_OUI_FROM_DATABASE=Maxanna Technology Co., Ltd.
+
+OUI:001111*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:001112*
+ ID_OUI_FROM_DATABASE=Honeywell CMSS
+
+OUI:001113*
+ ID_OUI_FROM_DATABASE=Fraunhofer FOKUS
+
+OUI:001114*
+ ID_OUI_FROM_DATABASE=EverFocus Electronics Corp.
+
+OUI:001115*
+ ID_OUI_FROM_DATABASE=EPIN Technologies, Inc.
+
+OUI:001116*
+ ID_OUI_FROM_DATABASE=COTEAU VERT CO., LTD.
+
+OUI:001117*
+ ID_OUI_FROM_DATABASE=CESNET
+
+OUI:001118*
+ ID_OUI_FROM_DATABASE=BLX IC Design Corp., Ltd.
+
+OUI:001119*
+ ID_OUI_FROM_DATABASE=Solteras, Inc.
+
+OUI:00111A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00111B*
+ ID_OUI_FROM_DATABASE=Targa Systems Div L-3 Communications Canada
+
+OUI:00111C*
+ ID_OUI_FROM_DATABASE=Pleora Technologies Inc.
+
+OUI:00111D*
+ ID_OUI_FROM_DATABASE=Hectrix Limited
+
+OUI:00111E*
+ ID_OUI_FROM_DATABASE=EPSG (Ethernet Powerlink Standardization Group)
+
+OUI:00111F*
+ ID_OUI_FROM_DATABASE=Doremi Labs, Inc.
+
+OUI:001120*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001121*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001122*
+ ID_OUI_FROM_DATABASE=CIMSYS Inc
+
+OUI:001123*
+ ID_OUI_FROM_DATABASE=Appointech, Inc.
+
+OUI:001124*
+ ID_OUI_FROM_DATABASE=Apple Computer
+
+OUI:001125*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:001126*
+ ID_OUI_FROM_DATABASE=Venstar Inc.
+
+OUI:001127*
+ ID_OUI_FROM_DATABASE=TASI, Inc
+
+OUI:001128*
+ ID_OUI_FROM_DATABASE=Streamit
+
+OUI:001129*
+ ID_OUI_FROM_DATABASE=Paradise Datacom Ltd.
+
+OUI:00112A*
+ ID_OUI_FROM_DATABASE=Niko NV
+
+OUI:00112B*
+ ID_OUI_FROM_DATABASE=NetModule AG
+
+OUI:00112C*
+ ID_OUI_FROM_DATABASE=IZT GmbH
+
+OUI:00112D*
+ ID_OUI_FROM_DATABASE=iPulse Systems
+
+OUI:00112E*
+ ID_OUI_FROM_DATABASE=CEICOM
+
+OUI:00112F*
+ ID_OUI_FROM_DATABASE=ASUSTek Computer Inc.
+
+OUI:001130*
+ ID_OUI_FROM_DATABASE=Allied Telesis (Hong Kong) Ltd.
+
+OUI:001131*
+ ID_OUI_FROM_DATABASE=UNATECH. CO.,LTD
+
+OUI:001132*
+ ID_OUI_FROM_DATABASE=Synology Incorporated
+
+OUI:001133*
+ ID_OUI_FROM_DATABASE=Siemens Austria SIMEA
+
+OUI:001134*
+ ID_OUI_FROM_DATABASE=MediaCell, Inc.
+
+OUI:001135*
+ ID_OUI_FROM_DATABASE=Grandeye Ltd
+
+OUI:001136*
+ ID_OUI_FROM_DATABASE=Goodrich Sensor Systems
+
+OUI:001137*
+ ID_OUI_FROM_DATABASE=AICHI ELECTRIC CO., LTD.
+
+OUI:001138*
+ ID_OUI_FROM_DATABASE=TAISHIN CO., LTD.
+
+OUI:001139*
+ ID_OUI_FROM_DATABASE=STOEBER ANTRIEBSTECHNIK GmbH + Co. KG.
+
+OUI:00113A*
+ ID_OUI_FROM_DATABASE=SHINBORAM
+
+OUI:00113B*
+ ID_OUI_FROM_DATABASE=Micronet Communications Inc.
+
+OUI:00113C*
+ ID_OUI_FROM_DATABASE=Micronas GmbH
+
+OUI:00113D*
+ ID_OUI_FROM_DATABASE=KN SOLTEC CO.,LTD.
+
+OUI:00113E*
+ ID_OUI_FROM_DATABASE=JL Corporation
+
+OUI:00113F*
+ ID_OUI_FROM_DATABASE=Alcatel DI
+
+OUI:001140*
+ ID_OUI_FROM_DATABASE=Nanometrics Inc.
+
+OUI:001141*
+ ID_OUI_FROM_DATABASE=GoodMan Corporation
+
+OUI:001142*
+ ID_OUI_FROM_DATABASE=e-SMARTCOM  INC.
+
+OUI:001143*
+ ID_OUI_FROM_DATABASE=DELL INC.
+
+OUI:001144*
+ ID_OUI_FROM_DATABASE=Assurance Technology Corp
+
+OUI:001145*
+ ID_OUI_FROM_DATABASE=ValuePoint Networks
+
+OUI:001146*
+ ID_OUI_FROM_DATABASE=Telecard-Pribor Ltd
+
+OUI:001147*
+ ID_OUI_FROM_DATABASE=Secom-Industry co.LTD.
+
+OUI:001148*
+ ID_OUI_FROM_DATABASE=Prolon Control Systems
+
+OUI:001149*
+ ID_OUI_FROM_DATABASE=Proliphix Inc.
+
+OUI:00114A*
+ ID_OUI_FROM_DATABASE=KAYABA INDUSTRY Co,.Ltd.
+
+OUI:00114B*
+ ID_OUI_FROM_DATABASE=Francotyp-Postalia GmbH
+
+OUI:00114C*
+ ID_OUI_FROM_DATABASE=caffeina applied research ltd.
+
+OUI:00114D*
+ ID_OUI_FROM_DATABASE=Atsumi Electric Co.,LTD.
+
+OUI:00114E*
+ ID_OUI_FROM_DATABASE=690885 Ontario Inc.
+
+OUI:00114F*
+ ID_OUI_FROM_DATABASE=US Digital Television, Inc
+
+OUI:001150*
+ ID_OUI_FROM_DATABASE=Belkin Corporation
+
+OUI:001151*
+ ID_OUI_FROM_DATABASE=Mykotronx
+
+OUI:001152*
+ ID_OUI_FROM_DATABASE=Eidsvoll Electronics AS
+
+OUI:001153*
+ ID_OUI_FROM_DATABASE=Trident Tek, Inc.
+
+OUI:001154*
+ ID_OUI_FROM_DATABASE=Webpro Technologies Inc.
+
+OUI:001155*
+ ID_OUI_FROM_DATABASE=Sevis Systems
+
+OUI:001156*
+ ID_OUI_FROM_DATABASE=Pharos Systems NZ
+
+OUI:001157*
+ ID_OUI_FROM_DATABASE=OF Networks Co., Ltd.
+
+OUI:001158*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001159*
+ ID_OUI_FROM_DATABASE=MATISSE NETWORKS INC
+
+OUI:00115A*
+ ID_OUI_FROM_DATABASE=Ivoclar Vivadent AG
+
+OUI:00115B*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. (ECS)
+
+OUI:00115C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00115D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00115E*
+ ID_OUI_FROM_DATABASE=ProMinent Dosiertechnik GmbH
+
+OUI:00115F*
+ ID_OUI_FROM_DATABASE=ITX Security Co., Ltd.
+
+OUI:001160*
+ ID_OUI_FROM_DATABASE=ARTDIO Company Co., LTD
+
+OUI:001161*
+ ID_OUI_FROM_DATABASE=NetStreams, LLC
+
+OUI:001162*
+ ID_OUI_FROM_DATABASE=STAR MICRONICS CO.,LTD.
+
+OUI:001163*
+ ID_OUI_FROM_DATABASE=SYSTEM SPA DEPT. ELECTRONICS
+
+OUI:001164*
+ ID_OUI_FROM_DATABASE=ACARD Technology Corp.
+
+OUI:001165*
+ ID_OUI_FROM_DATABASE=Znyx Networks
+
+OUI:001166*
+ ID_OUI_FROM_DATABASE=Taelim Electronics Co., Ltd.
+
+OUI:001167*
+ ID_OUI_FROM_DATABASE=Integrated System Solution Corp.
+
+OUI:001168*
+ ID_OUI_FROM_DATABASE=HomeLogic LLC
+
+OUI:001169*
+ ID_OUI_FROM_DATABASE=EMS Satcom
+
+OUI:00116A*
+ ID_OUI_FROM_DATABASE=Domo Ltd
+
+OUI:00116B*
+ ID_OUI_FROM_DATABASE=Digital Data Communications Asia Co.,Ltd
+
+OUI:00116C*
+ ID_OUI_FROM_DATABASE=Nanwang Multimedia Inc.,Ltd
+
+OUI:00116D*
+ ID_OUI_FROM_DATABASE=American Time and Signal
+
+OUI:00116E*
+ ID_OUI_FROM_DATABASE=PePLink Ltd.
+
+OUI:00116F*
+ ID_OUI_FROM_DATABASE=Netforyou Co., LTD.
+
+OUI:001170*
+ ID_OUI_FROM_DATABASE=GSC SRL
+
+OUI:001171*
+ ID_OUI_FROM_DATABASE=DEXTER Communications, Inc.
+
+OUI:001172*
+ ID_OUI_FROM_DATABASE=COTRON CORPORATION
+
+OUI:001173*
+ ID_OUI_FROM_DATABASE=SMART Storage Systems
+
+OUI:001174*
+ ID_OUI_FROM_DATABASE=Wibhu Technologies, Inc.
+
+OUI:001175*
+ ID_OUI_FROM_DATABASE=PathScale, Inc.
+
+OUI:001176*
+ ID_OUI_FROM_DATABASE=Intellambda Systems, Inc.
+
+OUI:001177*
+ ID_OUI_FROM_DATABASE=Coaxial Networks, Inc.
+
+OUI:001178*
+ ID_OUI_FROM_DATABASE=Chiron Technology Ltd
+
+OUI:001179*
+ ID_OUI_FROM_DATABASE=Singular Technology Co. Ltd.
+
+OUI:00117A*
+ ID_OUI_FROM_DATABASE=Singim International Corp.
+
+OUI:00117B*
+ ID_OUI_FROM_DATABASE=Büchi  Labortechnik AG
+
+OUI:00117C*
+ ID_OUI_FROM_DATABASE=e-zy.net
+
+OUI:00117D*
+ ID_OUI_FROM_DATABASE=ZMD America, Inc.
+
+OUI:00117E*
+ ID_OUI_FROM_DATABASE=Progeny, A division of Midmark Corp
+
+OUI:00117F*
+ ID_OUI_FROM_DATABASE=Neotune Information Technology Corporation,.LTD
+
+OUI:001180*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001181*
+ ID_OUI_FROM_DATABASE=InterEnergy Co.Ltd,
+
+OUI:001182*
+ ID_OUI_FROM_DATABASE=IMI Norgren Ltd
+
+OUI:001183*
+ ID_OUI_FROM_DATABASE=Datalogic Mobile, Inc.
+
+OUI:001184*
+ ID_OUI_FROM_DATABASE=Humo Laboratory,Ltd.
+
+OUI:001185*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001186*
+ ID_OUI_FROM_DATABASE=Prime Systems, Inc.
+
+OUI:001187*
+ ID_OUI_FROM_DATABASE=Category Solutions, Inc
+
+OUI:001188*
+ ID_OUI_FROM_DATABASE=Enterasys
+
+OUI:001189*
+ ID_OUI_FROM_DATABASE=Aerotech Inc
+
+OUI:00118A*
+ ID_OUI_FROM_DATABASE=Viewtran Technology Limited
+
+OUI:00118B*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group
+
+OUI:00118C*
+ ID_OUI_FROM_DATABASE=Missouri Department of Transportation
+
+OUI:00118D*
+ ID_OUI_FROM_DATABASE=Hanchang System Corp.
+
+OUI:00118E*
+ ID_OUI_FROM_DATABASE=Halytech Mace
+
+OUI:00118F*
+ ID_OUI_FROM_DATABASE=EUTECH INSTRUMENTS PTE. LTD.
+
+OUI:001190*
+ ID_OUI_FROM_DATABASE=Digital Design Corporation
+
+OUI:001191*
+ ID_OUI_FROM_DATABASE=CTS-Clima Temperatur Systeme GmbH
+
+OUI:001192*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001193*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001194*
+ ID_OUI_FROM_DATABASE=Chi Mei Communication Systems, Inc.
+
+OUI:001195*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:001196*
+ ID_OUI_FROM_DATABASE=Actuality Systems, Inc.
+
+OUI:001197*
+ ID_OUI_FROM_DATABASE=Monitoring Technologies Limited
+
+OUI:001198*
+ ID_OUI_FROM_DATABASE=Prism Media Products Limited
+
+OUI:001199*
+ ID_OUI_FROM_DATABASE=2wcom GmbH
+
+OUI:00119A*
+ ID_OUI_FROM_DATABASE=Alkeria srl
+
+OUI:00119B*
+ ID_OUI_FROM_DATABASE=Telesynergy Research Inc.
+
+OUI:00119C*
+ ID_OUI_FROM_DATABASE=EP&T Energy
+
+OUI:00119D*
+ ID_OUI_FROM_DATABASE=Diginfo Technology Corporation
+
+OUI:00119E*
+ ID_OUI_FROM_DATABASE=Solectron Brazil
+
+OUI:00119F*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0011A0*
+ ID_OUI_FROM_DATABASE=Vtech Engineering Canada Ltd
+
+OUI:0011A1*
+ ID_OUI_FROM_DATABASE=VISION NETWARE CO.,LTD
+
+OUI:0011A2*
+ ID_OUI_FROM_DATABASE=Manufacturing Technology Inc
+
+OUI:0011A3*
+ ID_OUI_FROM_DATABASE=LanReady Technologies Inc.
+
+OUI:0011A4*
+ ID_OUI_FROM_DATABASE=JStream Technologies Inc.
+
+OUI:0011A5*
+ ID_OUI_FROM_DATABASE=Fortuna Electronic Corp.
+
+OUI:0011A6*
+ ID_OUI_FROM_DATABASE=Sypixx Networks
+
+OUI:0011A7*
+ ID_OUI_FROM_DATABASE=Infilco Degremont Inc.
+
+OUI:0011A8*
+ ID_OUI_FROM_DATABASE=Quest Technologies
+
+OUI:0011A9*
+ ID_OUI_FROM_DATABASE=MOIMSTONE Co., LTD
+
+OUI:0011AA*
+ ID_OUI_FROM_DATABASE=Uniclass Technology, Co., LTD
+
+OUI:0011AB*
+ ID_OUI_FROM_DATABASE=TRUSTABLE TECHNOLOGY CO.,LTD.
+
+OUI:0011AC*
+ ID_OUI_FROM_DATABASE=Simtec Electronics
+
+OUI:0011AD*
+ ID_OUI_FROM_DATABASE=Shanghai Ruijie Technology
+
+OUI:0011AE*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0011AF*
+ ID_OUI_FROM_DATABASE=Medialink-i,Inc
+
+OUI:0011B0*
+ ID_OUI_FROM_DATABASE=Fortelink Inc.
+
+OUI:0011B1*
+ ID_OUI_FROM_DATABASE=BlueExpert Technology Corp.
+
+OUI:0011B2*
+ ID_OUI_FROM_DATABASE=2001 Technology Inc.
+
+OUI:0011B3*
+ ID_OUI_FROM_DATABASE=YOSHIMIYA CO.,LTD.
+
+OUI:0011B4*
+ ID_OUI_FROM_DATABASE=Westermo Teleindustri AB
+
+OUI:0011B5*
+ ID_OUI_FROM_DATABASE=Shenzhen Powercom Co.,Ltd
+
+OUI:0011B6*
+ ID_OUI_FROM_DATABASE=Open Systems International
+
+OUI:0011B7*
+ ID_OUI_FROM_DATABASE=Octalix B.V.
+
+OUI:0011B8*
+ ID_OUI_FROM_DATABASE=Liebherr - Elektronik GmbH
+
+OUI:0011B9*
+ ID_OUI_FROM_DATABASE=Inner Range Pty. Ltd.
+
+OUI:0011BA*
+ ID_OUI_FROM_DATABASE=Elexol Pty Ltd
+
+OUI:0011BB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0011BC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0011BD*
+ ID_OUI_FROM_DATABASE=Bombardier Transportation
+
+OUI:0011BE*
+ ID_OUI_FROM_DATABASE=AGP Telecom Co. Ltd
+
+OUI:0011BF*
+ ID_OUI_FROM_DATABASE=AESYS S.p.A.
+
+OUI:0011C0*
+ ID_OUI_FROM_DATABASE=Aday Technology Inc
+
+OUI:0011C1*
+ ID_OUI_FROM_DATABASE=4P MOBILE DATA PROCESSING
+
+OUI:0011C2*
+ ID_OUI_FROM_DATABASE=United Fiber Optic Communication
+
+OUI:0011C3*
+ ID_OUI_FROM_DATABASE=Transceiving System Technology Corporation
+
+OUI:0011C4*
+ ID_OUI_FROM_DATABASE=Terminales de Telecomunicacion Terrestre, S.L.
+
+OUI:0011C5*
+ ID_OUI_FROM_DATABASE=TEN Technology
+
+OUI:0011C6*
+ ID_OUI_FROM_DATABASE=Seagate Technology LLC
+
+OUI:0011C7*
+ ID_OUI_FROM_DATABASE=Raymarine UK Ltd
+
+OUI:0011C8*
+ ID_OUI_FROM_DATABASE=Powercom Co., Ltd.
+
+OUI:0011C9*
+ ID_OUI_FROM_DATABASE=MTT Corporation
+
+OUI:0011CA*
+ ID_OUI_FROM_DATABASE=Long Range Systems, Inc.
+
+OUI:0011CB*
+ ID_OUI_FROM_DATABASE=Jacobsons AB
+
+OUI:0011CC*
+ ID_OUI_FROM_DATABASE=Guangzhou Jinpeng Group Co.,Ltd.
+
+OUI:0011CD*
+ ID_OUI_FROM_DATABASE=Axsun Technologies
+
+OUI:0011CE*
+ ID_OUI_FROM_DATABASE=Ubisense Limited
+
+OUI:0011CF*
+ ID_OUI_FROM_DATABASE=Thrane & Thrane A/S
+
+OUI:0011D0*
+ ID_OUI_FROM_DATABASE=Tandberg Data ASA
+
+OUI:0011D1*
+ ID_OUI_FROM_DATABASE=Soft Imaging System GmbH
+
+OUI:0011D2*
+ ID_OUI_FROM_DATABASE=Perception Digital Ltd
+
+OUI:0011D3*
+ ID_OUI_FROM_DATABASE=NextGenTel Holding ASA
+
+OUI:0011D4*
+ ID_OUI_FROM_DATABASE=NetEnrich, Inc
+
+OUI:0011D5*
+ ID_OUI_FROM_DATABASE=Hangzhou Sunyard System Engineering Co.,Ltd.
+
+OUI:0011D6*
+ ID_OUI_FROM_DATABASE=HandEra, Inc.
+
+OUI:0011D7*
+ ID_OUI_FROM_DATABASE=eWerks Inc
+
+OUI:0011D8*
+ ID_OUI_FROM_DATABASE=ASUSTek Computer Inc.
+
+OUI:0011D9*
+ ID_OUI_FROM_DATABASE=TiVo
+
+OUI:0011DA*
+ ID_OUI_FROM_DATABASE=Vivaas Technology Inc.
+
+OUI:0011DB*
+ ID_OUI_FROM_DATABASE=Land-Cellular Corporation
+
+OUI:0011DC*
+ ID_OUI_FROM_DATABASE=Glunz & Jensen
+
+OUI:0011DD*
+ ID_OUI_FROM_DATABASE=FROMUS TEC. Co., Ltd.
+
+OUI:0011DE*
+ ID_OUI_FROM_DATABASE=EURILOGIC
+
+OUI:0011DF*
+ ID_OUI_FROM_DATABASE=Current Energy
+
+OUI:0011E0*
+ ID_OUI_FROM_DATABASE=U-MEDIA Communications, Inc.
+
+OUI:0011E1*
+ ID_OUI_FROM_DATABASE=Arcelik A.S
+
+OUI:0011E2*
+ ID_OUI_FROM_DATABASE=Hua Jung Components Co., Ltd.
+
+OUI:0011E3*
+ ID_OUI_FROM_DATABASE=Thomson, Inc.
+
+OUI:0011E4*
+ ID_OUI_FROM_DATABASE=Danelec Electronics A/S
+
+OUI:0011E5*
+ ID_OUI_FROM_DATABASE=KCodes Corporation
+
+OUI:0011E6*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta
+
+OUI:0011E7*
+ ID_OUI_FROM_DATABASE=WORLDSAT - Texas de France
+
+OUI:0011E8*
+ ID_OUI_FROM_DATABASE=Tixi.Com
+
+OUI:0011E9*
+ ID_OUI_FROM_DATABASE=STARNEX CO., LTD.
+
+OUI:0011EA*
+ ID_OUI_FROM_DATABASE=IWICS Inc.
+
+OUI:0011EB*
+ ID_OUI_FROM_DATABASE=Innovative Integration
+
+OUI:0011EC*
+ ID_OUI_FROM_DATABASE=AVIX INC.
+
+OUI:0011ED*
+ ID_OUI_FROM_DATABASE=802 Global
+
+OUI:0011EE*
+ ID_OUI_FROM_DATABASE=Estari, Inc.
+
+OUI:0011EF*
+ ID_OUI_FROM_DATABASE=Conitec Datensysteme GmbH
+
+OUI:0011F0*
+ ID_OUI_FROM_DATABASE=Wideful Limited
+
+OUI:0011F1*
+ ID_OUI_FROM_DATABASE=QinetiQ Ltd
+
+OUI:0011F2*
+ ID_OUI_FROM_DATABASE=Institute of Network Technologies
+
+OUI:0011F3*
+ ID_OUI_FROM_DATABASE=NeoMedia Europe AG
+
+OUI:0011F4*
+ ID_OUI_FROM_DATABASE=woori-net
+
+OUI:0011F5*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP.
+
+OUI:0011F6*
+ ID_OUI_FROM_DATABASE=Asia Pacific Microsystems , Inc.
+
+OUI:0011F7*
+ ID_OUI_FROM_DATABASE=Shenzhen Forward Industry Co., Ltd
+
+OUI:0011F8*
+ ID_OUI_FROM_DATABASE=AIRAYA Corp
+
+OUI:0011F9*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0011FA*
+ ID_OUI_FROM_DATABASE=Rane Corporation
+
+OUI:0011FB*
+ ID_OUI_FROM_DATABASE=Heidelberg Engineering GmbH
+
+OUI:0011FC*
+ ID_OUI_FROM_DATABASE=HARTING Electric Gmbh & Co.KG
+
+OUI:0011FD*
+ ID_OUI_FROM_DATABASE=KORG INC.
+
+OUI:0011FE*
+ ID_OUI_FROM_DATABASE=Keiyo System Research, Inc.
+
+OUI:0011FF*
+ ID_OUI_FROM_DATABASE=Digitro Tecnologia Ltda
+
+OUI:001200*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001201*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001202*
+ ID_OUI_FROM_DATABASE=Decrane Aerospace - Audio International Inc.
+
+OUI:001203*
+ ID_OUI_FROM_DATABASE=Activ Networks
+
+OUI:001204*
+ ID_OUI_FROM_DATABASE=u10 Networks, Inc.
+
+OUI:001205*
+ ID_OUI_FROM_DATABASE=Terrasat Communications, Inc.
+
+OUI:001206*
+ ID_OUI_FROM_DATABASE=iQuest (NZ) Ltd
+
+OUI:001207*
+ ID_OUI_FROM_DATABASE=Head Strong International Limited
+
+OUI:001208*
+ ID_OUI_FROM_DATABASE=Gantner Instruments GmbH
+
+OUI:001209*
+ ID_OUI_FROM_DATABASE=Fastrax Ltd
+
+OUI:00120A*
+ ID_OUI_FROM_DATABASE=Emerson Electric GmbH & Co. OHG
+
+OUI:00120B*
+ ID_OUI_FROM_DATABASE=Chinasys Technologies Limited
+
+OUI:00120C*
+ ID_OUI_FROM_DATABASE=CE-Infosys Pte Ltd
+
+OUI:00120D*
+ ID_OUI_FROM_DATABASE=Advanced Telecommunication Technologies, Inc.
+
+OUI:00120E*
+ ID_OUI_FROM_DATABASE=AboCom
+
+OUI:00120F*
+ ID_OUI_FROM_DATABASE=IEEE 802.3
+
+OUI:001210*
+ ID_OUI_FROM_DATABASE=WideRay Corp
+
+OUI:001211*
+ ID_OUI_FROM_DATABASE=Protechna Herbst GmbH & Co. KG
+
+OUI:001212*
+ ID_OUI_FROM_DATABASE=PLUS  Corporation
+
+OUI:001213*
+ ID_OUI_FROM_DATABASE=Metrohm AG
+
+OUI:001214*
+ ID_OUI_FROM_DATABASE=Koenig & Bauer AG
+
+OUI:001215*
+ ID_OUI_FROM_DATABASE=iStor Networks, Inc.
+
+OUI:001216*
+ ID_OUI_FROM_DATABASE=ICP Internet Communication Payment AG
+
+OUI:001217*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:001218*
+ ID_OUI_FROM_DATABASE=ARUZE Corporation
+
+OUI:001219*
+ ID_OUI_FROM_DATABASE=Ahead Communication Systems Inc
+
+OUI:00121A*
+ ID_OUI_FROM_DATABASE=Techno Soft Systemnics Inc.
+
+OUI:00121B*
+ ID_OUI_FROM_DATABASE=Sound Devices, LLC
+
+OUI:00121C*
+ ID_OUI_FROM_DATABASE=PARROT S.A.
+
+OUI:00121D*
+ ID_OUI_FROM_DATABASE=Netfabric Corporation
+
+OUI:00121E*
+ ID_OUI_FROM_DATABASE=Juniper Networks, Inc.
+
+OUI:00121F*
+ ID_OUI_FROM_DATABASE=Harding Intruments
+
+OUI:001220*
+ ID_OUI_FROM_DATABASE=Cadco Systems
+
+OUI:001221*
+ ID_OUI_FROM_DATABASE=B.Braun Melsungen AG
+
+OUI:001222*
+ ID_OUI_FROM_DATABASE=Skardin (UK) Ltd
+
+OUI:001223*
+ ID_OUI_FROM_DATABASE=Pixim
+
+OUI:001224*
+ ID_OUI_FROM_DATABASE=NexQL Corporation
+
+OUI:001225*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001226*
+ ID_OUI_FROM_DATABASE=Japan Direx Corporation
+
+OUI:001227*
+ ID_OUI_FROM_DATABASE=Franklin Electric Co., Inc.
+
+OUI:001228*
+ ID_OUI_FROM_DATABASE=Data Ltd.
+
+OUI:001229*
+ ID_OUI_FROM_DATABASE=BroadEasy Technologies Co.,Ltd
+
+OUI:00122A*
+ ID_OUI_FROM_DATABASE=VTech Telecommunications Ltd.
+
+OUI:00122B*
+ ID_OUI_FROM_DATABASE=Virbiage Pty Ltd
+
+OUI:00122C*
+ ID_OUI_FROM_DATABASE=Soenen Controls N.V.
+
+OUI:00122D*
+ ID_OUI_FROM_DATABASE=SiNett Corporation
+
+OUI:00122E*
+ ID_OUI_FROM_DATABASE=Signal Technology - AISD
+
+OUI:00122F*
+ ID_OUI_FROM_DATABASE=Sanei Electric Inc.
+
+OUI:001230*
+ ID_OUI_FROM_DATABASE=Picaso Infocommunication CO., LTD.
+
+OUI:001231*
+ ID_OUI_FROM_DATABASE=Motion Control Systems, Inc.
+
+OUI:001232*
+ ID_OUI_FROM_DATABASE=LeWiz Communications Inc.
+
+OUI:001233*
+ ID_OUI_FROM_DATABASE=JRC TOKKI Co.,Ltd.
+
+OUI:001234*
+ ID_OUI_FROM_DATABASE=Camille Bauer
+
+OUI:001235*
+ ID_OUI_FROM_DATABASE=Andrew Corporation
+
+OUI:001236*
+ ID_OUI_FROM_DATABASE=ConSentry Networks
+
+OUI:001237*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001238*
+ ID_OUI_FROM_DATABASE=SetaBox Technology Co., Ltd.
+
+OUI:001239*
+ ID_OUI_FROM_DATABASE=S Net Systems Inc.
+
+OUI:00123A*
+ ID_OUI_FROM_DATABASE=Posystech Inc., Co.
+
+OUI:00123B*
+ ID_OUI_FROM_DATABASE=KeRo Systems ApS
+
+OUI:00123C*
+ ID_OUI_FROM_DATABASE=Second Rule LLC
+
+OUI:00123D*
+ ID_OUI_FROM_DATABASE=GES
+
+OUI:00123E*
+ ID_OUI_FROM_DATABASE=ERUNE technology Co., Ltd.
+
+OUI:00123F*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:001240*
+ ID_OUI_FROM_DATABASE=AMOI ELECTRONICS CO.,LTD
+
+OUI:001241*
+ ID_OUI_FROM_DATABASE=a2i marketing center
+
+OUI:001242*
+ ID_OUI_FROM_DATABASE=Millennial Net
+
+OUI:001243*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001244*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001245*
+ ID_OUI_FROM_DATABASE=Zellweger Analytics, Inc.
+
+OUI:001246*
+ ID_OUI_FROM_DATABASE=T.O.M TECHNOLOGY INC..
+
+OUI:001247*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+OUI:001248*
+ ID_OUI_FROM_DATABASE=EMC Corporation (Kashya)
+
+OUI:001249*
+ ID_OUI_FROM_DATABASE=Delta Elettronica S.p.A.
+
+OUI:00124A*
+ ID_OUI_FROM_DATABASE=Dedicated Devices, Inc.
+
+OUI:00124B*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:00124C*
+ ID_OUI_FROM_DATABASE=BBWM Corporation
+
+OUI:00124D*
+ ID_OUI_FROM_DATABASE=Inducon BV
+
+OUI:00124E*
+ ID_OUI_FROM_DATABASE=XAC AUTOMATION CORP.
+
+OUI:00124F*
+ ID_OUI_FROM_DATABASE=Tyco Thermal Controls LLC.
+
+OUI:001250*
+ ID_OUI_FROM_DATABASE=Tokyo Aircaft Instrument Co., Ltd.
+
+OUI:001251*
+ ID_OUI_FROM_DATABASE=SILINK
+
+OUI:001252*
+ ID_OUI_FROM_DATABASE=Citronix, LLC
+
+OUI:001253*
+ ID_OUI_FROM_DATABASE=AudioDev AB
+
+OUI:001254*
+ ID_OUI_FROM_DATABASE=Spectra Technologies Holdings Company Ltd
+
+OUI:001255*
+ ID_OUI_FROM_DATABASE=NetEffect Incorporated
+
+OUI:001256*
+ ID_OUI_FROM_DATABASE=LG INFORMATION & COMM.
+
+OUI:001257*
+ ID_OUI_FROM_DATABASE=LeapComm Communication Technologies Inc.
+
+OUI:001258*
+ ID_OUI_FROM_DATABASE=Activis Polska
+
+OUI:001259*
+ ID_OUI_FROM_DATABASE=THERMO ELECTRON KARLSRUHE
+
+OUI:00125A*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:00125B*
+ ID_OUI_FROM_DATABASE=KAIMEI ELECTRONI
+
+OUI:00125C*
+ ID_OUI_FROM_DATABASE=Green Hills Software, Inc.
+
+OUI:00125D*
+ ID_OUI_FROM_DATABASE=CyberNet Inc.
+
+OUI:00125E*
+ ID_OUI_FROM_DATABASE=CAEN
+
+OUI:00125F*
+ ID_OUI_FROM_DATABASE=AWIND Inc.
+
+OUI:001260*
+ ID_OUI_FROM_DATABASE=Stanton Magnetics,inc.
+
+OUI:001261*
+ ID_OUI_FROM_DATABASE=Adaptix, Inc
+
+OUI:001262*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001263*
+ ID_OUI_FROM_DATABASE=Data Voice Technologies GmbH
+
+OUI:001264*
+ ID_OUI_FROM_DATABASE=daum electronic gmbh
+
+OUI:001265*
+ ID_OUI_FROM_DATABASE=Enerdyne Technologies, Inc.
+
+OUI:001266*
+ ID_OUI_FROM_DATABASE=Swisscom Hospitality Services SA
+
+OUI:001267*
+ ID_OUI_FROM_DATABASE=Matsushita Electronic Components Co., Ltd.
+
+OUI:001268*
+ ID_OUI_FROM_DATABASE=IPS d.o.o.
+
+OUI:001269*
+ ID_OUI_FROM_DATABASE=Value Electronics
+
+OUI:00126A*
+ ID_OUI_FROM_DATABASE=OPTOELECTRONICS Co., Ltd.
+
+OUI:00126B*
+ ID_OUI_FROM_DATABASE=Ascalade Communications Limited
+
+OUI:00126C*
+ ID_OUI_FROM_DATABASE=Visonic Ltd.
+
+OUI:00126D*
+ ID_OUI_FROM_DATABASE=University of California, Berkeley
+
+OUI:00126E*
+ ID_OUI_FROM_DATABASE=Seidel Elektronik GmbH Nfg.KG
+
+OUI:00126F*
+ ID_OUI_FROM_DATABASE=Rayson Technology Co., Ltd.
+
+OUI:001270*
+ ID_OUI_FROM_DATABASE=NGES Denro Systems
+
+OUI:001271*
+ ID_OUI_FROM_DATABASE=Measurement Computing Corp
+
+OUI:001272*
+ ID_OUI_FROM_DATABASE=Redux Communications Ltd.
+
+OUI:001273*
+ ID_OUI_FROM_DATABASE=Stoke Inc
+
+OUI:001274*
+ ID_OUI_FROM_DATABASE=NIT lab
+
+OUI:001275*
+ ID_OUI_FROM_DATABASE=Sentilla Corporation
+
+OUI:001276*
+ ID_OUI_FROM_DATABASE=CG Power Systems Ireland Limited
+
+OUI:001277*
+ ID_OUI_FROM_DATABASE=Korenix Technologies Co., Ltd.
+
+OUI:001278*
+ ID_OUI_FROM_DATABASE=International Bar Code
+
+OUI:001279*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:00127A*
+ ID_OUI_FROM_DATABASE=Sanyu Industry Co.,Ltd.
+
+OUI:00127B*
+ ID_OUI_FROM_DATABASE=VIA Networking Technologies, Inc.
+
+OUI:00127C*
+ ID_OUI_FROM_DATABASE=SWEGON AB
+
+OUI:00127D*
+ ID_OUI_FROM_DATABASE=MobileAria
+
+OUI:00127E*
+ ID_OUI_FROM_DATABASE=Digital Lifestyles Group, Inc.
+
+OUI:00127F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001280*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001281*
+ ID_OUI_FROM_DATABASE=March Networks S.p.A.
+
+OUI:001282*
+ ID_OUI_FROM_DATABASE=Qovia
+
+OUI:001283*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001284*
+ ID_OUI_FROM_DATABASE=Lab33 Srl
+
+OUI:001285*
+ ID_OUI_FROM_DATABASE=Gizmondo Europe Ltd
+
+OUI:001286*
+ ID_OUI_FROM_DATABASE=ENDEVCO CORP
+
+OUI:001287*
+ ID_OUI_FROM_DATABASE=Digital Everywhere Unterhaltungselektronik GmbH
+
+OUI:001288*
+ ID_OUI_FROM_DATABASE=2Wire, Inc
+
+OUI:001289*
+ ID_OUI_FROM_DATABASE=Advance Sterilization Products
+
+OUI:00128A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00128B*
+ ID_OUI_FROM_DATABASE=Sensory Networks Inc
+
+OUI:00128C*
+ ID_OUI_FROM_DATABASE=Woodward Governor
+
+OUI:00128D*
+ ID_OUI_FROM_DATABASE=STB Datenservice GmbH
+
+OUI:00128E*
+ ID_OUI_FROM_DATABASE=Q-Free ASA
+
+OUI:00128F*
+ ID_OUI_FROM_DATABASE=Montilio
+
+OUI:001290*
+ ID_OUI_FROM_DATABASE=KYOWA Electric & Machinery Corp.
+
+OUI:001291*
+ ID_OUI_FROM_DATABASE=KWS Computersysteme GmbH
+
+OUI:001292*
+ ID_OUI_FROM_DATABASE=Griffin Technology
+
+OUI:001293*
+ ID_OUI_FROM_DATABASE=GE Energy
+
+OUI:001294*
+ ID_OUI_FROM_DATABASE=SUMITOMO ELECTRIC DEVICE INNOVATIONS, INC
+
+OUI:001295*
+ ID_OUI_FROM_DATABASE=Aiware Inc.
+
+OUI:001296*
+ ID_OUI_FROM_DATABASE=Addlogix
+
+OUI:001297*
+ ID_OUI_FROM_DATABASE=O2Micro, Inc.
+
+OUI:001298*
+ ID_OUI_FROM_DATABASE=MICO ELECTRIC(SHENZHEN) LIMITED
+
+OUI:001299*
+ ID_OUI_FROM_DATABASE=Ktech Telecommunications Inc
+
+OUI:00129A*
+ ID_OUI_FROM_DATABASE=IRT Electronics Pty Ltd
+
+OUI:00129B*
+ ID_OUI_FROM_DATABASE=E2S Electronic Engineering Solutions, S.L.
+
+OUI:00129C*
+ ID_OUI_FROM_DATABASE=Yulinet
+
+OUI:00129D*
+ ID_OUI_FROM_DATABASE=First International Computer do Brasil
+
+OUI:00129E*
+ ID_OUI_FROM_DATABASE=Surf Communications Inc.
+
+OUI:00129F*
+ ID_OUI_FROM_DATABASE=RAE Systems
+
+OUI:0012A0*
+ ID_OUI_FROM_DATABASE=NeoMeridian Sdn Bhd
+
+OUI:0012A1*
+ ID_OUI_FROM_DATABASE=BluePacket Communications Co., Ltd.
+
+OUI:0012A2*
+ ID_OUI_FROM_DATABASE=VITA
+
+OUI:0012A3*
+ ID_OUI_FROM_DATABASE=Trust International B.V.
+
+OUI:0012A4*
+ ID_OUI_FROM_DATABASE=ThingMagic, LLC
+
+OUI:0012A5*
+ ID_OUI_FROM_DATABASE=Stargen, Inc.
+
+OUI:0012A6*
+ ID_OUI_FROM_DATABASE=Dolby Australia
+
+OUI:0012A7*
+ ID_OUI_FROM_DATABASE=ISR TECHNOLOGIES Inc
+
+OUI:0012A8*
+ ID_OUI_FROM_DATABASE=intec GmbH
+
+OUI:0012A9*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:0012AA*
+ ID_OUI_FROM_DATABASE=IEE, Inc.
+
+OUI:0012AB*
+ ID_OUI_FROM_DATABASE=WiLife, Inc.
+
+OUI:0012AC*
+ ID_OUI_FROM_DATABASE=ONTIMETEK INC.
+
+OUI:0012AD*
+ ID_OUI_FROM_DATABASE=IDS GmbH
+
+OUI:0012AE*
+ ID_OUI_FROM_DATABASE=HLS HARD-LINE Solutions Inc.
+
+OUI:0012AF*
+ ID_OUI_FROM_DATABASE=ELPRO Technologies
+
+OUI:0012B0*
+ ID_OUI_FROM_DATABASE=Efore Oyj   (Plc)
+
+OUI:0012B1*
+ ID_OUI_FROM_DATABASE=Dai Nippon Printing Co., Ltd
+
+OUI:0012B2*
+ ID_OUI_FROM_DATABASE=AVOLITES LTD.
+
+OUI:0012B3*
+ ID_OUI_FROM_DATABASE=Advance Wireless Technology Corp.
+
+OUI:0012B4*
+ ID_OUI_FROM_DATABASE=Work Microwave GmbH
+
+OUI:0012B5*
+ ID_OUI_FROM_DATABASE=Vialta, Inc.
+
+OUI:0012B6*
+ ID_OUI_FROM_DATABASE=Santa Barbara Infrared, Inc.
+
+OUI:0012B7*
+ ID_OUI_FROM_DATABASE=PTW Freiburg
+
+OUI:0012B8*
+ ID_OUI_FROM_DATABASE=G2 Microsystems
+
+OUI:0012B9*
+ ID_OUI_FROM_DATABASE=Fusion Digital Technology
+
+OUI:0012BA*
+ ID_OUI_FROM_DATABASE=FSI Systems, Inc.
+
+OUI:0012BB*
+ ID_OUI_FROM_DATABASE=Telecommunications Industry Association TR-41 Committee
+
+OUI:0012BC*
+ ID_OUI_FROM_DATABASE=Echolab LLC
+
+OUI:0012BD*
+ ID_OUI_FROM_DATABASE=Avantec Manufacturing Limited
+
+OUI:0012BE*
+ ID_OUI_FROM_DATABASE=Astek Corporation
+
+OUI:0012BF*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:0012C0*
+ ID_OUI_FROM_DATABASE=HotLava Systems, Inc.
+
+OUI:0012C1*
+ ID_OUI_FROM_DATABASE=Check Point Software Technologies
+
+OUI:0012C2*
+ ID_OUI_FROM_DATABASE=Apex Electronics Factory
+
+OUI:0012C3*
+ ID_OUI_FROM_DATABASE=WIT S.A.
+
+OUI:0012C4*
+ ID_OUI_FROM_DATABASE=Viseon, Inc.
+
+OUI:0012C5*
+ ID_OUI_FROM_DATABASE=V-Show  Technology (China) Co.,Ltd
+
+OUI:0012C6*
+ ID_OUI_FROM_DATABASE=TGC America, Inc
+
+OUI:0012C7*
+ ID_OUI_FROM_DATABASE=SECURAY Technologies Ltd.Co.
+
+OUI:0012C8*
+ ID_OUI_FROM_DATABASE=Perfect tech
+
+OUI:0012C9*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0012CA*
+ ID_OUI_FROM_DATABASE=Mechatronic Brick Aps
+
+OUI:0012CB*
+ ID_OUI_FROM_DATABASE=CSS Inc.
+
+OUI:0012CC*
+ ID_OUI_FROM_DATABASE=Bitatek CO., LTD
+
+OUI:0012CD*
+ ID_OUI_FROM_DATABASE=ASEM SpA
+
+OUI:0012CE*
+ ID_OUI_FROM_DATABASE=Advanced Cybernetics Group
+
+OUI:0012CF*
+ ID_OUI_FROM_DATABASE=Accton Technology Corporation
+
+OUI:0012D0*
+ ID_OUI_FROM_DATABASE=Gossen-Metrawatt-GmbH
+
+OUI:0012D1*
+ ID_OUI_FROM_DATABASE=Texas Instruments Inc
+
+OUI:0012D2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0012D3*
+ ID_OUI_FROM_DATABASE=Zetta Systems, Inc.
+
+OUI:0012D4*
+ ID_OUI_FROM_DATABASE=Princeton Technology, Ltd
+
+OUI:0012D5*
+ ID_OUI_FROM_DATABASE=Motion Reality Inc.
+
+OUI:0012D6*
+ ID_OUI_FROM_DATABASE=Jiangsu Yitong High-Tech Co.,Ltd
+
+OUI:0012D7*
+ ID_OUI_FROM_DATABASE=Invento Networks, Inc.
+
+OUI:0012D8*
+ ID_OUI_FROM_DATABASE=International Games System Co., Ltd.
+
+OUI:0012D9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0012DA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0012DB*
+ ID_OUI_FROM_DATABASE=ZIEHL industrie-elektronik GmbH + Co KG
+
+OUI:0012DC*
+ ID_OUI_FROM_DATABASE=SunCorp Industrial Limited
+
+OUI:0012DD*
+ ID_OUI_FROM_DATABASE=Shengqu Information Technology (Shanghai) Co., Ltd.
+
+OUI:0012DE*
+ ID_OUI_FROM_DATABASE=Radio Components Sweden AB
+
+OUI:0012DF*
+ ID_OUI_FROM_DATABASE=Novomatic AG
+
+OUI:0012E0*
+ ID_OUI_FROM_DATABASE=Codan Limited
+
+OUI:0012E1*
+ ID_OUI_FROM_DATABASE=Alliant Networks, Inc
+
+OUI:0012E2*
+ ID_OUI_FROM_DATABASE=ALAXALA Networks Corporation
+
+OUI:0012E3*
+ ID_OUI_FROM_DATABASE=Agat-RT, Ltd.
+
+OUI:0012E4*
+ ID_OUI_FROM_DATABASE=ZIEHL industrie-electronik GmbH + Co KG
+
+OUI:0012E5*
+ ID_OUI_FROM_DATABASE=Time America, Inc.
+
+OUI:0012E6*
+ ID_OUI_FROM_DATABASE=SPECTEC COMPUTER CO., LTD.
+
+OUI:0012E7*
+ ID_OUI_FROM_DATABASE=Projectek Networking Electronics Corp.
+
+OUI:0012E8*
+ ID_OUI_FROM_DATABASE=Fraunhofer IMS
+
+OUI:0012E9*
+ ID_OUI_FROM_DATABASE=Abbey Systems Ltd
+
+OUI:0012EA*
+ ID_OUI_FROM_DATABASE=Trane
+
+OUI:0012EB*
+ ID_OUI_FROM_DATABASE=R2DI, LLC
+
+OUI:0012EC*
+ ID_OUI_FROM_DATABASE=Movacolor b.v.
+
+OUI:0012ED*
+ ID_OUI_FROM_DATABASE=AVG Advanced Technologies
+
+OUI:0012EE*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:0012EF*
+ ID_OUI_FROM_DATABASE=OneAccess SA
+
+OUI:0012F0*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0012F1*
+ ID_OUI_FROM_DATABASE=IFOTEC
+
+OUI:0012F2*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc
+
+OUI:0012F3*
+ ID_OUI_FROM_DATABASE=connectBlue AB
+
+OUI:0012F4*
+ ID_OUI_FROM_DATABASE=Belco International Co.,Ltd.
+
+OUI:0012F5*
+ ID_OUI_FROM_DATABASE=Imarda New Zealand Limited
+
+OUI:0012F6*
+ ID_OUI_FROM_DATABASE=MDK CO.,LTD.
+
+OUI:0012F7*
+ ID_OUI_FROM_DATABASE=Xiamen Xinglian Electronics Co., Ltd.
+
+OUI:0012F8*
+ ID_OUI_FROM_DATABASE=WNI Resources, LLC
+
+OUI:0012F9*
+ ID_OUI_FROM_DATABASE=URYU SEISAKU, LTD.
+
+OUI:0012FA*
+ ID_OUI_FROM_DATABASE=THX LTD
+
+OUI:0012FB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:0012FC*
+ ID_OUI_FROM_DATABASE=PLANET System Co.,LTD
+
+OUI:0012FD*
+ ID_OUI_FROM_DATABASE=OPTIMUS IC S.A.
+
+OUI:0012FE*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
+OUI:0012FF*
+ ID_OUI_FROM_DATABASE=Lely Industries N.V.
+
+OUI:001300*
+ ID_OUI_FROM_DATABASE=IT-FACTORY, INC.
+
+OUI:001301*
+ ID_OUI_FROM_DATABASE=IronGate S.L.
+
+OUI:001302*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001303*
+ ID_OUI_FROM_DATABASE=GateConnect Technologies GmbH
+
+OUI:001304*
+ ID_OUI_FROM_DATABASE=Flaircomm Technologies Co. LTD
+
+OUI:001305*
+ ID_OUI_FROM_DATABASE=Epicom, Inc.
+
+OUI:001306*
+ ID_OUI_FROM_DATABASE=Always On Wireless
+
+OUI:001307*
+ ID_OUI_FROM_DATABASE=Paravirtual Corporation
+
+OUI:001308*
+ ID_OUI_FROM_DATABASE=Nuvera Fuel Cells
+
+OUI:001309*
+ ID_OUI_FROM_DATABASE=Ocean Broadband Networks
+
+OUI:00130A*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:00130B*
+ ID_OUI_FROM_DATABASE=Mextal B.V.
+
+OUI:00130C*
+ ID_OUI_FROM_DATABASE=HF System Corporation
+
+OUI:00130D*
+ ID_OUI_FROM_DATABASE=GALILEO AVIONICA
+
+OUI:00130E*
+ ID_OUI_FROM_DATABASE=Focusrite Audio Engineering Limited
+
+OUI:00130F*
+ ID_OUI_FROM_DATABASE=EGEMEN Bilgisayar Muh San ve Tic LTD STI
+
+OUI:001310*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:001311*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:001312*
+ ID_OUI_FROM_DATABASE=Amedia Networks Inc.
+
+OUI:001313*
+ ID_OUI_FROM_DATABASE=GuangZhou Post & Telecom Equipment ltd
+
+OUI:001314*
+ ID_OUI_FROM_DATABASE=Asiamajor Inc.
+
+OUI:001315*
+ ID_OUI_FROM_DATABASE=SONY Computer Entertainment inc,
+
+OUI:001316*
+ ID_OUI_FROM_DATABASE=L-S-B Broadcast Technologies GmbH
+
+OUI:001317*
+ ID_OUI_FROM_DATABASE=GN Netcom as
+
+OUI:001318*
+ ID_OUI_FROM_DATABASE=DGSTATION Co., Ltd.
+
+OUI:001319*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00131A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00131B*
+ ID_OUI_FROM_DATABASE=BeCell Innovations Corp.
+
+OUI:00131C*
+ ID_OUI_FROM_DATABASE=LiteTouch, Inc.
+
+OUI:00131D*
+ ID_OUI_FROM_DATABASE=Scanvaegt International A/S
+
+OUI:00131E*
+ ID_OUI_FROM_DATABASE=Peiker acustic GmbH & Co. KG
+
+OUI:00131F*
+ ID_OUI_FROM_DATABASE=NxtPhase T&D, Corp.
+
+OUI:001320*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001321*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001322*
+ ID_OUI_FROM_DATABASE=DAQ Electronics, Inc.
+
+OUI:001323*
+ ID_OUI_FROM_DATABASE=Cap Co., Ltd.
+
+OUI:001324*
+ ID_OUI_FROM_DATABASE=Schneider Electric Ultra Terminal
+
+OUI:001325*
+ ID_OUI_FROM_DATABASE=Cortina Systems Inc
+
+OUI:001326*
+ ID_OUI_FROM_DATABASE=ECM Systems Ltd
+
+OUI:001327*
+ ID_OUI_FROM_DATABASE=Data Acquisitions limited
+
+OUI:001328*
+ ID_OUI_FROM_DATABASE=Westech Korea Inc.,
+
+OUI:001329*
+ ID_OUI_FROM_DATABASE=VSST Co., LTD
+
+OUI:00132A*
+ ID_OUI_FROM_DATABASE=Sitronics Telecom Solutions
+
+OUI:00132B*
+ ID_OUI_FROM_DATABASE=Phoenix Digital
+
+OUI:00132C*
+ ID_OUI_FROM_DATABASE=MAZ Brandenburg GmbH
+
+OUI:00132D*
+ ID_OUI_FROM_DATABASE=iWise Communications
+
+OUI:00132E*
+ ID_OUI_FROM_DATABASE=ITian Coporation
+
+OUI:00132F*
+ ID_OUI_FROM_DATABASE=Interactek
+
+OUI:001330*
+ ID_OUI_FROM_DATABASE=EURO PROTECTION SURVEILLANCE
+
+OUI:001331*
+ ID_OUI_FROM_DATABASE=CellPoint Connect
+
+OUI:001332*
+ ID_OUI_FROM_DATABASE=Beijing Topsec Network Security Technology Co., Ltd.
+
+OUI:001333*
+ ID_OUI_FROM_DATABASE=BaudTec Corporation
+
+OUI:001334*
+ ID_OUI_FROM_DATABASE=Arkados, Inc.
+
+OUI:001335*
+ ID_OUI_FROM_DATABASE=VS Industry Berhad
+
+OUI:001336*
+ ID_OUI_FROM_DATABASE=Tianjin 712 Communication Broadcasting co., ltd.
+
+OUI:001337*
+ ID_OUI_FROM_DATABASE=Orient Power Home Network Ltd.
+
+OUI:001338*
+ ID_OUI_FROM_DATABASE=FRESENIUS-VIAL
+
+OUI:001339*
+ ID_OUI_FROM_DATABASE=EL-ME AG
+
+OUI:00133A*
+ ID_OUI_FROM_DATABASE=VadaTech Inc.
+
+OUI:00133B*
+ ID_OUI_FROM_DATABASE=Speed Dragon Multimedia Limited
+
+OUI:00133C*
+ ID_OUI_FROM_DATABASE=QUINTRON SYSTEMS INC.
+
+OUI:00133D*
+ ID_OUI_FROM_DATABASE=Micro Memory Curtiss Wright Co
+
+OUI:00133E*
+ ID_OUI_FROM_DATABASE=MetaSwitch
+
+OUI:00133F*
+ ID_OUI_FROM_DATABASE=Eppendorf Instrumente GmbH
+
+OUI:001340*
+ ID_OUI_FROM_DATABASE=AD.EL s.r.l.
+
+OUI:001341*
+ ID_OUI_FROM_DATABASE=Shandong New Beiyang Information Technology Co.,Ltd
+
+OUI:001342*
+ ID_OUI_FROM_DATABASE=Vision Research, Inc.
+
+OUI:001343*
+ ID_OUI_FROM_DATABASE=Matsushita Electronic Components (Europe) GmbH
+
+OUI:001344*
+ ID_OUI_FROM_DATABASE=Fargo Electronics Inc.
+
+OUI:001345*
+ ID_OUI_FROM_DATABASE=Eaton Corporation
+
+OUI:001346*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:001347*
+ ID_OUI_FROM_DATABASE=BlueTree Wireless Data Inc.
+
+OUI:001348*
+ ID_OUI_FROM_DATABASE=Artila Electronics Co., Ltd.
+
+OUI:001349*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:00134A*
+ ID_OUI_FROM_DATABASE=Engim, Inc.
+
+OUI:00134B*
+ ID_OUI_FROM_DATABASE=ToGoldenNet Technology Inc.
+
+OUI:00134C*
+ ID_OUI_FROM_DATABASE=YDT Technology International
+
+OUI:00134D*
+ ID_OUI_FROM_DATABASE=Inepro BV
+
+OUI:00134E*
+ ID_OUI_FROM_DATABASE=Valox Systems, Inc.
+
+OUI:00134F*
+ ID_OUI_FROM_DATABASE=Tranzeo Wireless Technologies Inc.
+
+OUI:001350*
+ ID_OUI_FROM_DATABASE=Silver Spring Networks, Inc
+
+OUI:001351*
+ ID_OUI_FROM_DATABASE=Niles Audio Corporation
+
+OUI:001352*
+ ID_OUI_FROM_DATABASE=Naztec, Inc.
+
+OUI:001353*
+ ID_OUI_FROM_DATABASE=HYDAC Filtertechnik GMBH
+
+OUI:001354*
+ ID_OUI_FROM_DATABASE=Zcomax Technologies, Inc.
+
+OUI:001355*
+ ID_OUI_FROM_DATABASE=TOMEN Cyber-business Solutions, Inc.
+
+OUI:001356*
+ ID_OUI_FROM_DATABASE=FLIR Radiation Inc
+
+OUI:001357*
+ ID_OUI_FROM_DATABASE=Soyal Technology Co., Ltd.
+
+OUI:001358*
+ ID_OUI_FROM_DATABASE=Realm Systems, Inc.
+
+OUI:001359*
+ ID_OUI_FROM_DATABASE=ProTelevision Technologies A/S
+
+OUI:00135A*
+ ID_OUI_FROM_DATABASE=Project T&E Limited
+
+OUI:00135B*
+ ID_OUI_FROM_DATABASE=PanelLink Cinema, LLC
+
+OUI:00135C*
+ ID_OUI_FROM_DATABASE=OnSite Systems, Inc.
+
+OUI:00135D*
+ ID_OUI_FROM_DATABASE=NTTPC Communications, Inc.
+
+OUI:00135E*
+ ID_OUI_FROM_DATABASE=EAB/RWI/K
+
+OUI:00135F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001360*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001361*
+ ID_OUI_FROM_DATABASE=Biospace Co., Ltd.
+
+OUI:001362*
+ ID_OUI_FROM_DATABASE=ShinHeung Precision Co., Ltd.
+
+OUI:001363*
+ ID_OUI_FROM_DATABASE=Verascape, Inc.
+
+OUI:001364*
+ ID_OUI_FROM_DATABASE=Paradigm Technology Inc..
+
+OUI:001365*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001366*
+ ID_OUI_FROM_DATABASE=Neturity Technologies Inc.
+
+OUI:001367*
+ ID_OUI_FROM_DATABASE=Narayon. Co., Ltd.
+
+OUI:001368*
+ ID_OUI_FROM_DATABASE=Maersk Data Defence
+
+OUI:001369*
+ ID_OUI_FROM_DATABASE=Honda Electron Co., LED.
+
+OUI:00136A*
+ ID_OUI_FROM_DATABASE=Hach Lange SA
+
+OUI:00136B*
+ ID_OUI_FROM_DATABASE=E-TEC
+
+OUI:00136C*
+ ID_OUI_FROM_DATABASE=TomTom
+
+OUI:00136D*
+ ID_OUI_FROM_DATABASE=Tentaculus AB
+
+OUI:00136E*
+ ID_OUI_FROM_DATABASE=Techmetro Corp.
+
+OUI:00136F*
+ ID_OUI_FROM_DATABASE=PacketMotion, Inc.
+
+OUI:001370*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001371*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001372*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:001373*
+ ID_OUI_FROM_DATABASE=BLwave Electronics Co., Ltd
+
+OUI:001374*
+ ID_OUI_FROM_DATABASE=Atheros Communications, Inc.
+
+OUI:001375*
+ ID_OUI_FROM_DATABASE=American Security Products Co.
+
+OUI:001376*
+ ID_OUI_FROM_DATABASE=Tabor Electronics Ltd.
+
+OUI:001377*
+ ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD
+
+OUI:001378*
+ ID_OUI_FROM_DATABASE=QSAN Technology, Inc.
+
+OUI:001379*
+ ID_OUI_FROM_DATABASE=PONDER INFORMATION INDUSTRIES LTD.
+
+OUI:00137A*
+ ID_OUI_FROM_DATABASE=Netvox Technology Co., Ltd.
+
+OUI:00137B*
+ ID_OUI_FROM_DATABASE=Movon Corporation
+
+OUI:00137C*
+ ID_OUI_FROM_DATABASE=Kaicom co., Ltd.
+
+OUI:00137D*
+ ID_OUI_FROM_DATABASE=Dynalab, Inc.
+
+OUI:00137E*
+ ID_OUI_FROM_DATABASE=CorEdge Networks, Inc.
+
+OUI:00137F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001380*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001381*
+ ID_OUI_FROM_DATABASE=CHIPS & Systems, Inc.
+
+OUI:001382*
+ ID_OUI_FROM_DATABASE=Cetacea Networks Corporation
+
+OUI:001383*
+ ID_OUI_FROM_DATABASE=Application Technologies and Engineering Research Laboratory
+
+OUI:001384*
+ ID_OUI_FROM_DATABASE=Advanced Motion Controls
+
+OUI:001385*
+ ID_OUI_FROM_DATABASE=Add-On Technology Co., LTD.
+
+OUI:001386*
+ ID_OUI_FROM_DATABASE=ABB Inc./Totalflow
+
+OUI:001387*
+ ID_OUI_FROM_DATABASE=27M Technologies AB
+
+OUI:001388*
+ ID_OUI_FROM_DATABASE=WiMedia Alliance
+
+OUI:001389*
+ ID_OUI_FROM_DATABASE=Redes de Telefonía Móvil S.A.
+
+OUI:00138A*
+ ID_OUI_FROM_DATABASE=QINGDAO GOERTEK ELECTRONICS CO.,LTD.
+
+OUI:00138B*
+ ID_OUI_FROM_DATABASE=Phantom Technologies LLC
+
+OUI:00138C*
+ ID_OUI_FROM_DATABASE=Kumyoung.Co.Ltd
+
+OUI:00138D*
+ ID_OUI_FROM_DATABASE=Kinghold
+
+OUI:00138E*
+ ID_OUI_FROM_DATABASE=FOAB Elektronik AB
+
+OUI:00138F*
+ ID_OUI_FROM_DATABASE=Asiarock Incorporation
+
+OUI:001390*
+ ID_OUI_FROM_DATABASE=Termtek Computer Co., Ltd
+
+OUI:001391*
+ ID_OUI_FROM_DATABASE=OUEN CO.,LTD.
+
+OUI:001392*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:001393*
+ ID_OUI_FROM_DATABASE=Panta Systems, Inc.
+
+OUI:001394*
+ ID_OUI_FROM_DATABASE=Infohand Co.,Ltd
+
+OUI:001395*
+ ID_OUI_FROM_DATABASE=congatec AG
+
+OUI:001396*
+ ID_OUI_FROM_DATABASE=Acbel Polytech Inc.
+
+OUI:001397*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:001398*
+ ID_OUI_FROM_DATABASE=TrafficSim Co.,Ltd
+
+OUI:001399*
+ ID_OUI_FROM_DATABASE=STAC Corporation.
+
+OUI:00139A*
+ ID_OUI_FROM_DATABASE=K-ubique ID Corp.
+
+OUI:00139B*
+ ID_OUI_FROM_DATABASE=ioIMAGE Ltd.
+
+OUI:00139C*
+ ID_OUI_FROM_DATABASE=Exavera Technologies, Inc.
+
+OUI:00139D*
+ ID_OUI_FROM_DATABASE=Marvell Hispana S.L.
+
+OUI:00139E*
+ ID_OUI_FROM_DATABASE=Ciara Technologies Inc.
+
+OUI:00139F*
+ ID_OUI_FROM_DATABASE=Electronics Design Services, Co., Ltd.
+
+OUI:0013A0*
+ ID_OUI_FROM_DATABASE=ALGOSYSTEM Co., Ltd.
+
+OUI:0013A1*
+ ID_OUI_FROM_DATABASE=Crow Electronic Engeneering
+
+OUI:0013A2*
+ ID_OUI_FROM_DATABASE=MaxStream, Inc
+
+OUI:0013A3*
+ ID_OUI_FROM_DATABASE=Siemens Com CPE Devices
+
+OUI:0013A4*
+ ID_OUI_FROM_DATABASE=KeyEye Communications
+
+OUI:0013A5*
+ ID_OUI_FROM_DATABASE=General Solutions, LTD.
+
+OUI:0013A6*
+ ID_OUI_FROM_DATABASE=Extricom Ltd
+
+OUI:0013A7*
+ ID_OUI_FROM_DATABASE=BATTELLE MEMORIAL INSTITUTE
+
+OUI:0013A8*
+ ID_OUI_FROM_DATABASE=Tanisys Technology
+
+OUI:0013A9*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:0013AA*
+ ID_OUI_FROM_DATABASE=ALS  & TEC Ltd.
+
+OUI:0013AB*
+ ID_OUI_FROM_DATABASE=Telemotive AG
+
+OUI:0013AC*
+ ID_OUI_FROM_DATABASE=Sunmyung Electronics Co., LTD
+
+OUI:0013AD*
+ ID_OUI_FROM_DATABASE=Sendo Ltd
+
+OUI:0013AE*
+ ID_OUI_FROM_DATABASE=Radiance Technologies, Inc.
+
+OUI:0013AF*
+ ID_OUI_FROM_DATABASE=NUMA Technology,Inc.
+
+OUI:0013B0*
+ ID_OUI_FROM_DATABASE=Jablotron
+
+OUI:0013B1*
+ ID_OUI_FROM_DATABASE=Intelligent Control Systems (Asia) Pte Ltd
+
+OUI:0013B2*
+ ID_OUI_FROM_DATABASE=Carallon Limited
+
+OUI:0013B3*
+ ID_OUI_FROM_DATABASE=Ecom Communications Technology Co., Ltd.
+
+OUI:0013B4*
+ ID_OUI_FROM_DATABASE=Appear TV
+
+OUI:0013B5*
+ ID_OUI_FROM_DATABASE=Wavesat
+
+OUI:0013B6*
+ ID_OUI_FROM_DATABASE=Sling Media, Inc.
+
+OUI:0013B7*
+ ID_OUI_FROM_DATABASE=Scantech ID
+
+OUI:0013B8*
+ ID_OUI_FROM_DATABASE=RyCo Electronic Systems Limited
+
+OUI:0013B9*
+ ID_OUI_FROM_DATABASE=BM SPA
+
+OUI:0013BA*
+ ID_OUI_FROM_DATABASE=ReadyLinks Inc
+
+OUI:0013BB*
+ ID_OUI_FROM_DATABASE=Smartvue Corporation
+
+OUI:0013BC*
+ ID_OUI_FROM_DATABASE=Artimi Ltd
+
+OUI:0013BD*
+ ID_OUI_FROM_DATABASE=HYMATOM SA
+
+OUI:0013BE*
+ ID_OUI_FROM_DATABASE=Virtual Conexions
+
+OUI:0013BF*
+ ID_OUI_FROM_DATABASE=Media System Planning Corp.
+
+OUI:0013C0*
+ ID_OUI_FROM_DATABASE=Trix Tecnologia Ltda.
+
+OUI:0013C1*
+ ID_OUI_FROM_DATABASE=Asoka USA Corporation
+
+OUI:0013C2*
+ ID_OUI_FROM_DATABASE=WACOM Co.,Ltd
+
+OUI:0013C3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0013C4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0013C5*
+ ID_OUI_FROM_DATABASE=LIGHTRON FIBER-OPTIC DEVICES INC.
+
+OUI:0013C6*
+ ID_OUI_FROM_DATABASE=OpenGear, Inc
+
+OUI:0013C7*
+ ID_OUI_FROM_DATABASE=IONOS Co.,Ltd.
+
+OUI:0013C8*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:0013C9*
+ ID_OUI_FROM_DATABASE=Beyond Achieve Enterprises Ltd.
+
+OUI:0013CA*
+ ID_OUI_FROM_DATABASE=Pico Digital
+
+OUI:0013CB*
+ ID_OUI_FROM_DATABASE=Zenitel Norway AS
+
+OUI:0013CC*
+ ID_OUI_FROM_DATABASE=Tall Maple Systems
+
+OUI:0013CD*
+ ID_OUI_FROM_DATABASE=MTI co. LTD
+
+OUI:0013CE*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0013CF*
+ ID_OUI_FROM_DATABASE=4Access Communications
+
+OUI:0013D0*
+ ID_OUI_FROM_DATABASE=t+ Medical Ltd
+
+OUI:0013D1*
+ ID_OUI_FROM_DATABASE=KIRK telecom A/S
+
+OUI:0013D2*
+ ID_OUI_FROM_DATABASE=PAGE IBERICA, S.A.
+
+OUI:0013D3*
+ ID_OUI_FROM_DATABASE=MICRO-STAR INTERNATIONAL CO., LTD.
+
+OUI:0013D4*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:0013D5*
+ ID_OUI_FROM_DATABASE=RuggedCom
+
+OUI:0013D6*
+ ID_OUI_FROM_DATABASE=TII NETWORK TECHNOLOGIES, INC.
+
+OUI:0013D7*
+ ID_OUI_FROM_DATABASE=SPIDCOM Technologies SA
+
+OUI:0013D8*
+ ID_OUI_FROM_DATABASE=Princeton Instruments
+
+OUI:0013D9*
+ ID_OUI_FROM_DATABASE=Matrix Product Development, Inc.
+
+OUI:0013DA*
+ ID_OUI_FROM_DATABASE=Diskware Co., Ltd
+
+OUI:0013DB*
+ ID_OUI_FROM_DATABASE=SHOEI Electric Co.,Ltd
+
+OUI:0013DC*
+ ID_OUI_FROM_DATABASE=IBTEK INC.
+
+OUI:0013DD*
+ ID_OUI_FROM_DATABASE=Abbott Diagnostics
+
+OUI:0013DE*
+ ID_OUI_FROM_DATABASE=Adapt4, LLC
+
+OUI:0013DF*
+ ID_OUI_FROM_DATABASE=Ryvor Corp.
+
+OUI:0013E0*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:0013E1*
+ ID_OUI_FROM_DATABASE=Iprobe AB
+
+OUI:0013E2*
+ ID_OUI_FROM_DATABASE=GeoVision Inc.
+
+OUI:0013E3*
+ ID_OUI_FROM_DATABASE=CoVi Technologies, Inc.
+
+OUI:0013E4*
+ ID_OUI_FROM_DATABASE=YANGJAE SYSTEMS CORP.
+
+OUI:0013E5*
+ ID_OUI_FROM_DATABASE=TENOSYS, INC.
+
+OUI:0013E6*
+ ID_OUI_FROM_DATABASE=Technolution
+
+OUI:0013E7*
+ ID_OUI_FROM_DATABASE=Halcro
+
+OUI:0013E8*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0013E9*
+ ID_OUI_FROM_DATABASE=VeriWave, Inc.
+
+OUI:0013EA*
+ ID_OUI_FROM_DATABASE=Kamstrup A/S
+
+OUI:0013EB*
+ ID_OUI_FROM_DATABASE=Sysmaster Corporation
+
+OUI:0013EC*
+ ID_OUI_FROM_DATABASE=Sunbay Software AG
+
+OUI:0013ED*
+ ID_OUI_FROM_DATABASE=PSIA
+
+OUI:0013EE*
+ ID_OUI_FROM_DATABASE=JBX Designs Inc.
+
+OUI:0013EF*
+ ID_OUI_FROM_DATABASE=Kingjon Digital Technology Co.,Ltd
+
+OUI:0013F0*
+ ID_OUI_FROM_DATABASE=Wavefront Semiconductor
+
+OUI:0013F1*
+ ID_OUI_FROM_DATABASE=AMOD Technology Co., Ltd.
+
+OUI:0013F2*
+ ID_OUI_FROM_DATABASE=Klas Ltd
+
+OUI:0013F3*
+ ID_OUI_FROM_DATABASE=Giga-byte Communications Inc.
+
+OUI:0013F4*
+ ID_OUI_FROM_DATABASE=Psitek (Pty) Ltd
+
+OUI:0013F5*
+ ID_OUI_FROM_DATABASE=Akimbi Systems
+
+OUI:0013F6*
+ ID_OUI_FROM_DATABASE=Cintech
+
+OUI:0013F7*
+ ID_OUI_FROM_DATABASE=SMC Networks, Inc.
+
+OUI:0013F8*
+ ID_OUI_FROM_DATABASE=Dex Security Solutions
+
+OUI:0013F9*
+ ID_OUI_FROM_DATABASE=Cavera Systems
+
+OUI:0013FA*
+ ID_OUI_FROM_DATABASE=LifeSize Communications, Inc
+
+OUI:0013FB*
+ ID_OUI_FROM_DATABASE=RKC INSTRUMENT INC.
+
+OUI:0013FC*
+ ID_OUI_FROM_DATABASE=SiCortex, Inc
+
+OUI:0013FD*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0013FE*
+ ID_OUI_FROM_DATABASE=GRANDTEC ELECTRONIC CORP.
+
+OUI:0013FF*
+ ID_OUI_FROM_DATABASE=Dage-MTI of MC, Inc.
+
+OUI:001400*
+ ID_OUI_FROM_DATABASE=MINERVA KOREA CO., LTD
+
+OUI:001401*
+ ID_OUI_FROM_DATABASE=Rivertree Networks Corp.
+
+OUI:001402*
+ ID_OUI_FROM_DATABASE=kk-electronic a/s
+
+OUI:001403*
+ ID_OUI_FROM_DATABASE=Renasis, LLC
+
+OUI:001404*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001405*
+ ID_OUI_FROM_DATABASE=OpenIB, Inc.
+
+OUI:001406*
+ ID_OUI_FROM_DATABASE=Go Networks
+
+OUI:001407*
+ ID_OUI_FROM_DATABASE=Sperian Protection Instrumentation
+
+OUI:001408*
+ ID_OUI_FROM_DATABASE=Eka Systems Inc.
+
+OUI:001409*
+ ID_OUI_FROM_DATABASE=MAGNETI MARELLI   S.E. S.p.A.
+
+OUI:00140A*
+ ID_OUI_FROM_DATABASE=WEPIO Co., Ltd.
+
+OUI:00140B*
+ ID_OUI_FROM_DATABASE=FIRST INTERNATIONAL COMPUTER, INC.
+
+OUI:00140C*
+ ID_OUI_FROM_DATABASE=GKB CCTV CO., LTD.
+
+OUI:00140D*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:00140E*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:00140F*
+ ID_OUI_FROM_DATABASE=Federal State Unitary Enterprise Leningrad R&D Institute of
+
+OUI:001410*
+ ID_OUI_FROM_DATABASE=Suzhou Keda Technology CO.,Ltd
+
+OUI:001411*
+ ID_OUI_FROM_DATABASE=Deutschmann Automation GmbH & Co. KG
+
+OUI:001412*
+ ID_OUI_FROM_DATABASE=S-TEC electronics AG
+
+OUI:001413*
+ ID_OUI_FROM_DATABASE=Trebing & Himstedt Prozeßautomation GmbH & Co. KG
+
+OUI:001414*
+ ID_OUI_FROM_DATABASE=Jumpnode Systems LLC.
+
+OUI:001415*
+ ID_OUI_FROM_DATABASE=Intec Automation Inc.
+
+OUI:001416*
+ ID_OUI_FROM_DATABASE=Scosche Industries, Inc.
+
+OUI:001417*
+ ID_OUI_FROM_DATABASE=RSE Informations Technologie GmbH
+
+OUI:001418*
+ ID_OUI_FROM_DATABASE=C4Line
+
+OUI:001419*
+ ID_OUI_FROM_DATABASE=SIDSA
+
+OUI:00141A*
+ ID_OUI_FROM_DATABASE=DEICY CORPORATION
+
+OUI:00141B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00141C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00141D*
+ ID_OUI_FROM_DATABASE=Lust Antriebstechnik GmbH
+
+OUI:00141E*
+ ID_OUI_FROM_DATABASE=P.A. Semi, Inc.
+
+OUI:00141F*
+ ID_OUI_FROM_DATABASE=SunKwang Electronics Co., Ltd
+
+OUI:001420*
+ ID_OUI_FROM_DATABASE=G-Links networking company
+
+OUI:001421*
+ ID_OUI_FROM_DATABASE=Total Wireless Technologies Pte. Ltd.
+
+OUI:001422*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:001423*
+ ID_OUI_FROM_DATABASE=J-S Co. NEUROCOM
+
+OUI:001424*
+ ID_OUI_FROM_DATABASE=Merry Electrics CO., LTD.
+
+OUI:001425*
+ ID_OUI_FROM_DATABASE=Galactic Computing Corp.
+
+OUI:001426*
+ ID_OUI_FROM_DATABASE=NL Technology
+
+OUI:001427*
+ ID_OUI_FROM_DATABASE=JazzMutant
+
+OUI:001428*
+ ID_OUI_FROM_DATABASE=Vocollect, Inc
+
+OUI:001429*
+ ID_OUI_FROM_DATABASE=V Center Technologies Co., Ltd.
+
+OUI:00142A*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer System Co., Ltd
+
+OUI:00142B*
+ ID_OUI_FROM_DATABASE=Edata Communication Inc.
+
+OUI:00142C*
+ ID_OUI_FROM_DATABASE=Koncept International, Inc.
+
+OUI:00142D*
+ ID_OUI_FROM_DATABASE=Toradex AG
+
+OUI:00142E*
+ ID_OUI_FROM_DATABASE=77 Elektronika Kft.
+
+OUI:00142F*
+ ID_OUI_FROM_DATABASE=WildPackets
+
+OUI:001430*
+ ID_OUI_FROM_DATABASE=ViPowER, Inc
+
+OUI:001431*
+ ID_OUI_FROM_DATABASE=PDL Electronics Ltd
+
+OUI:001432*
+ ID_OUI_FROM_DATABASE=Tarallax Wireless, Inc.
+
+OUI:001433*
+ ID_OUI_FROM_DATABASE=Empower Technologies(Canada) Inc.
+
+OUI:001434*
+ ID_OUI_FROM_DATABASE=Keri Systems, Inc
+
+OUI:001435*
+ ID_OUI_FROM_DATABASE=CityCom Corp.
+
+OUI:001436*
+ ID_OUI_FROM_DATABASE=Qwerty Elektronik AB
+
+OUI:001437*
+ ID_OUI_FROM_DATABASE=GSTeletech Co.,Ltd.
+
+OUI:001438*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001439*
+ ID_OUI_FROM_DATABASE=Blonder Tongue Laboratories, Inc.
+
+OUI:00143A*
+ ID_OUI_FROM_DATABASE=RAYTALK INTERNATIONAL SRL
+
+OUI:00143B*
+ ID_OUI_FROM_DATABASE=Sensovation AG
+
+OUI:00143C*
+ ID_OUI_FROM_DATABASE=Rheinmetall Canada Inc.
+
+OUI:00143D*
+ ID_OUI_FROM_DATABASE=Aevoe Inc.
+
+OUI:00143E*
+ ID_OUI_FROM_DATABASE=AirLink Communications, Inc.
+
+OUI:00143F*
+ ID_OUI_FROM_DATABASE=Hotway Technology Corporation
+
+OUI:001440*
+ ID_OUI_FROM_DATABASE=ATOMIC Corporation
+
+OUI:001441*
+ ID_OUI_FROM_DATABASE=Innovation Sound Technology Co., LTD.
+
+OUI:001442*
+ ID_OUI_FROM_DATABASE=ATTO CORPORATION
+
+OUI:001443*
+ ID_OUI_FROM_DATABASE=Consultronics Europe Ltd
+
+OUI:001444*
+ ID_OUI_FROM_DATABASE=Grundfos Electronics
+
+OUI:001445*
+ ID_OUI_FROM_DATABASE=Telefon-Gradnja d.o.o.
+
+OUI:001446*
+ ID_OUI_FROM_DATABASE=SuperVision Solutions LLC
+
+OUI:001447*
+ ID_OUI_FROM_DATABASE=BOAZ Inc.
+
+OUI:001448*
+ ID_OUI_FROM_DATABASE=Inventec Multimedia & Telecom Corporation
+
+OUI:001449*
+ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
+
+OUI:00144A*
+ ID_OUI_FROM_DATABASE=Taiwan Thick-Film Ind. Corp.
+
+OUI:00144B*
+ ID_OUI_FROM_DATABASE=Hifn, Inc.
+
+OUI:00144C*
+ ID_OUI_FROM_DATABASE=General Meters Corp.
+
+OUI:00144D*
+ ID_OUI_FROM_DATABASE=Intelligent Systems
+
+OUI:00144E*
+ ID_OUI_FROM_DATABASE=SRISA
+
+OUI:00144F*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:001450*
+ ID_OUI_FROM_DATABASE=Heim Systems GmbH
+
+OUI:001451*
+ ID_OUI_FROM_DATABASE=Apple Computer Inc.
+
+OUI:001452*
+ ID_OUI_FROM_DATABASE=CALCULEX,INC.
+
+OUI:001453*
+ ID_OUI_FROM_DATABASE=ADVANTECH TECHNOLOGIES CO.,LTD
+
+OUI:001454*
+ ID_OUI_FROM_DATABASE=Symwave
+
+OUI:001455*
+ ID_OUI_FROM_DATABASE=Coder Electronics Corporation
+
+OUI:001456*
+ ID_OUI_FROM_DATABASE=Edge Products
+
+OUI:001457*
+ ID_OUI_FROM_DATABASE=T-VIPS AS
+
+OUI:001458*
+ ID_OUI_FROM_DATABASE=HS Automatic ApS
+
+OUI:001459*
+ ID_OUI_FROM_DATABASE=Moram Co., Ltd.
+
+OUI:00145A*
+ ID_OUI_FROM_DATABASE=Neratec AG
+
+OUI:00145B*
+ ID_OUI_FROM_DATABASE=SeekerNet Inc.
+
+OUI:00145C*
+ ID_OUI_FROM_DATABASE=Intronics B.V.
+
+OUI:00145D*
+ ID_OUI_FROM_DATABASE=WJ Communications, Inc.
+
+OUI:00145E*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:00145F*
+ ID_OUI_FROM_DATABASE=ADITEC CO. LTD
+
+OUI:001460*
+ ID_OUI_FROM_DATABASE=Kyocera Wireless Corp.
+
+OUI:001461*
+ ID_OUI_FROM_DATABASE=CORONA CORPORATION
+
+OUI:001462*
+ ID_OUI_FROM_DATABASE=Digiwell Technology, inc
+
+OUI:001463*
+ ID_OUI_FROM_DATABASE=IDCS N.V.
+
+OUI:001464*
+ ID_OUI_FROM_DATABASE=Cryptosoft
+
+OUI:001465*
+ ID_OUI_FROM_DATABASE=Novo Nordisk A/S
+
+OUI:001466*
+ ID_OUI_FROM_DATABASE=Kleinhenz Elektronik GmbH
+
+OUI:001467*
+ ID_OUI_FROM_DATABASE=ArrowSpan Inc.
+
+OUI:001468*
+ ID_OUI_FROM_DATABASE=CelPlan International, Inc.
+
+OUI:001469*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00146A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00146B*
+ ID_OUI_FROM_DATABASE=Anagran, Inc.
+
+OUI:00146C*
+ ID_OUI_FROM_DATABASE=Netgear Inc.
+
+OUI:00146D*
+ ID_OUI_FROM_DATABASE=RF Technologies
+
+OUI:00146E*
+ ID_OUI_FROM_DATABASE=H. Stoll GmbH & Co. KG
+
+OUI:00146F*
+ ID_OUI_FROM_DATABASE=Kohler Co
+
+OUI:001470*
+ ID_OUI_FROM_DATABASE=Prokom Software SA
+
+OUI:001471*
+ ID_OUI_FROM_DATABASE=Eastern Asia Technology Limited
+
+OUI:001472*
+ ID_OUI_FROM_DATABASE=China Broadband Wireless IP Standard Group
+
+OUI:001473*
+ ID_OUI_FROM_DATABASE=Bookham Inc
+
+OUI:001474*
+ ID_OUI_FROM_DATABASE=K40 Electronics
+
+OUI:001475*
+ ID_OUI_FROM_DATABASE=Wiline Networks, Inc.
+
+OUI:001476*
+ ID_OUI_FROM_DATABASE=MultiCom Industries Limited
+
+OUI:001477*
+ ID_OUI_FROM_DATABASE=Nertec  Inc.
+
+OUI:001478*
+ ID_OUI_FROM_DATABASE=ShenZhen TP-LINK Technologies Co., Ltd.
+
+OUI:001479*
+ ID_OUI_FROM_DATABASE=NEC Magnus Communications,Ltd.
+
+OUI:00147A*
+ ID_OUI_FROM_DATABASE=Eubus GmbH
+
+OUI:00147B*
+ ID_OUI_FROM_DATABASE=Iteris, Inc.
+
+OUI:00147C*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:00147D*
+ ID_OUI_FROM_DATABASE=Aeon Digital International
+
+OUI:00147E*
+ ID_OUI_FROM_DATABASE=InnerWireless
+
+OUI:00147F*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:001480*
+ ID_OUI_FROM_DATABASE=Hitachi-LG Data Storage Korea, Inc
+
+OUI:001481*
+ ID_OUI_FROM_DATABASE=Multilink Inc
+
+OUI:001482*
+ ID_OUI_FROM_DATABASE=GoBackTV, Inc
+
+OUI:001483*
+ ID_OUI_FROM_DATABASE=eXS Inc.
+
+OUI:001484*
+ ID_OUI_FROM_DATABASE=Cermate Technologies Inc.
+
+OUI:001485*
+ ID_OUI_FROM_DATABASE=Giga-Byte
+
+OUI:001486*
+ ID_OUI_FROM_DATABASE=Echo Digital Audio Corporation
+
+OUI:001487*
+ ID_OUI_FROM_DATABASE=American Technology Integrators
+
+OUI:001488*
+ ID_OUI_FROM_DATABASE=Akorri
+
+OUI:001489*
+ ID_OUI_FROM_DATABASE=B15402100 - JANDEI, S.L.
+
+OUI:00148A*
+ ID_OUI_FROM_DATABASE=Elin Ebg Traction Gmbh
+
+OUI:00148B*
+ ID_OUI_FROM_DATABASE=Globo Electronic GmbH & Co. KG
+
+OUI:00148C*
+ ID_OUI_FROM_DATABASE=Fortress Technologies
+
+OUI:00148D*
+ ID_OUI_FROM_DATABASE=Cubic Defense Simulation Systems
+
+OUI:00148E*
+ ID_OUI_FROM_DATABASE=Tele Power Inc.
+
+OUI:00148F*
+ ID_OUI_FROM_DATABASE=Protronic (Far East) Ltd.
+
+OUI:001490*
+ ID_OUI_FROM_DATABASE=ASP Corporation
+
+OUI:001491*
+ ID_OUI_FROM_DATABASE=Daniels Electronics Ltd.
+
+OUI:001492*
+ ID_OUI_FROM_DATABASE=Liteon, Mobile Media Solution SBU
+
+OUI:001493*
+ ID_OUI_FROM_DATABASE=Systimax Solutions
+
+OUI:001494*
+ ID_OUI_FROM_DATABASE=ESU AG
+
+OUI:001495*
+ ID_OUI_FROM_DATABASE=2Wire, Inc.
+
+OUI:001496*
+ ID_OUI_FROM_DATABASE=Phonic Corp.
+
+OUI:001497*
+ ID_OUI_FROM_DATABASE=ZHIYUAN Eletronics co.,ltd.
+
+OUI:001498*
+ ID_OUI_FROM_DATABASE=Viking Design Technology
+
+OUI:001499*
+ ID_OUI_FROM_DATABASE=Helicomm Inc
+
+OUI:00149A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00149B*
+ ID_OUI_FROM_DATABASE=Nokota Communications, LLC
+
+OUI:00149C*
+ ID_OUI_FROM_DATABASE=HF Company
+
+OUI:00149D*
+ ID_OUI_FROM_DATABASE=Sound ID Inc.
+
+OUI:00149E*
+ ID_OUI_FROM_DATABASE=UbONE Co., Ltd
+
+OUI:00149F*
+ ID_OUI_FROM_DATABASE=System and Chips, Inc.
+
+OUI:0014A0*
+ ID_OUI_FROM_DATABASE=Accsense, Inc.
+
+OUI:0014A1*
+ ID_OUI_FROM_DATABASE=Synchronous Communication Corp
+
+OUI:0014A2*
+ ID_OUI_FROM_DATABASE=Core Micro Systems Inc.
+
+OUI:0014A3*
+ ID_OUI_FROM_DATABASE=Vitelec BV
+
+OUI:0014A4*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:0014A5*
+ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+
+OUI:0014A6*
+ ID_OUI_FROM_DATABASE=Teranetics, Inc.
+
+OUI:0014A7*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0014A8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0014A9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0014AA*
+ ID_OUI_FROM_DATABASE=Ashly Audio, Inc.
+
+OUI:0014AB*
+ ID_OUI_FROM_DATABASE=Senhai Electronic Technology Co., Ltd.
+
+OUI:0014AC*
+ ID_OUI_FROM_DATABASE=Bountiful WiFi
+
+OUI:0014AD*
+ ID_OUI_FROM_DATABASE=Gassner Wiege- und Meßtechnik GmbH
+
+OUI:0014AE*
+ ID_OUI_FROM_DATABASE=Wizlogics Co., Ltd.
+
+OUI:0014AF*
+ ID_OUI_FROM_DATABASE=Datasym Inc.
+
+OUI:0014B0*
+ ID_OUI_FROM_DATABASE=Naeil Community
+
+OUI:0014B1*
+ ID_OUI_FROM_DATABASE=Avitec AB
+
+OUI:0014B2*
+ ID_OUI_FROM_DATABASE=mCubelogics Corporation
+
+OUI:0014B3*
+ ID_OUI_FROM_DATABASE=CoreStar International Corp
+
+OUI:0014B4*
+ ID_OUI_FROM_DATABASE=General Dynamics United Kingdom Ltd
+
+OUI:0014B5*
+ ID_OUI_FROM_DATABASE=PHYSIOMETRIX,INC
+
+OUI:0014B6*
+ ID_OUI_FROM_DATABASE=Enswer Technology Inc.
+
+OUI:0014B7*
+ ID_OUI_FROM_DATABASE=AR Infotek Inc.
+
+OUI:0014B8*
+ ID_OUI_FROM_DATABASE=Hill-Rom
+
+OUI:0014B9*
+ ID_OUI_FROM_DATABASE=MSTAR SEMICONDUCTOR
+
+OUI:0014BA*
+ ID_OUI_FROM_DATABASE=Carvers SA de CV
+
+OUI:0014BB*
+ ID_OUI_FROM_DATABASE=Open Interface North America
+
+OUI:0014BC*
+ ID_OUI_FROM_DATABASE=SYNECTIC TELECOM EXPORTS PVT. LTD.
+
+OUI:0014BD*
+ ID_OUI_FROM_DATABASE=incNETWORKS, Inc
+
+OUI:0014BE*
+ ID_OUI_FROM_DATABASE=Wink communication technology CO.LTD
+
+OUI:0014BF*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys LLC
+
+OUI:0014C0*
+ ID_OUI_FROM_DATABASE=Symstream Technology Group Ltd
+
+OUI:0014C1*
+ ID_OUI_FROM_DATABASE=U.S. Robotics Corporation
+
+OUI:0014C2*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0014C3*
+ ID_OUI_FROM_DATABASE=Seagate Technology LLC
+
+OUI:0014C4*
+ ID_OUI_FROM_DATABASE=Vitelcom Mobile Technology
+
+OUI:0014C5*
+ ID_OUI_FROM_DATABASE=Alive Technologies Pty Ltd
+
+OUI:0014C6*
+ ID_OUI_FROM_DATABASE=Quixant Ltd
+
+OUI:0014C7*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:0014C8*
+ ID_OUI_FROM_DATABASE=Contemporary Research Corp
+
+OUI:0014C9*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:0014CA*
+ ID_OUI_FROM_DATABASE=Key Radio Systems Limited
+
+OUI:0014CB*
+ ID_OUI_FROM_DATABASE=LifeSync Corporation
+
+OUI:0014CC*
+ ID_OUI_FROM_DATABASE=Zetec, Inc.
+
+OUI:0014CD*
+ ID_OUI_FROM_DATABASE=DigitalZone Co., Ltd.
+
+OUI:0014CE*
+ ID_OUI_FROM_DATABASE=NF CORPORATION
+
+OUI:0014CF*
+ ID_OUI_FROM_DATABASE=INVISIO Communications
+
+OUI:0014D0*
+ ID_OUI_FROM_DATABASE=BTI Systems Inc.
+
+OUI:0014D1*
+ ID_OUI_FROM_DATABASE=TRENDnet
+
+OUI:0014D2*
+ ID_OUI_FROM_DATABASE=Kyuden Technosystems Corporation
+
+OUI:0014D3*
+ ID_OUI_FROM_DATABASE=SEPSA
+
+OUI:0014D4*
+ ID_OUI_FROM_DATABASE=K Technology Corporation
+
+OUI:0014D5*
+ ID_OUI_FROM_DATABASE=Datang Telecom Technology CO. , LCD,Optical Communication Br
+
+OUI:0014D6*
+ ID_OUI_FROM_DATABASE=Jeongmin Electronics Co.,Ltd.
+
+OUI:0014D7*
+ ID_OUI_FROM_DATABASE=Datastore Technology Corp
+
+OUI:0014D8*
+ ID_OUI_FROM_DATABASE=bio-logic SA
+
+OUI:0014D9*
+ ID_OUI_FROM_DATABASE=IP Fabrics, Inc.
+
+OUI:0014DA*
+ ID_OUI_FROM_DATABASE=Huntleigh Healthcare
+
+OUI:0014DB*
+ ID_OUI_FROM_DATABASE=Elma Trenew Electronic GmbH
+
+OUI:0014DC*
+ ID_OUI_FROM_DATABASE=Communication System Design & Manufacturing (CSDM)
+
+OUI:0014DD*
+ ID_OUI_FROM_DATABASE=Covergence Inc.
+
+OUI:0014DE*
+ ID_OUI_FROM_DATABASE=Sage Instruments Inc.
+
+OUI:0014DF*
+ ID_OUI_FROM_DATABASE=HI-P Tech Corporation
+
+OUI:0014E0*
+ ID_OUI_FROM_DATABASE=LET'S Corporation
+
+OUI:0014E1*
+ ID_OUI_FROM_DATABASE=Data Display AG
+
+OUI:0014E2*
+ ID_OUI_FROM_DATABASE=datacom systems inc.
+
+OUI:0014E3*
+ ID_OUI_FROM_DATABASE=mm-lab GmbH
+
+OUI:0014E4*
+ ID_OUI_FROM_DATABASE=infinias, LLC
+
+OUI:0014E5*
+ ID_OUI_FROM_DATABASE=Alticast
+
+OUI:0014E6*
+ ID_OUI_FROM_DATABASE=AIM Infrarotmodule GmbH
+
+OUI:0014E7*
+ ID_OUI_FROM_DATABASE=Stolinx,. Inc
+
+OUI:0014E8*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0014E9*
+ ID_OUI_FROM_DATABASE=Nortech International
+
+OUI:0014EA*
+ ID_OUI_FROM_DATABASE=S Digm Inc. (Safe Paradigm Inc.)
+
+OUI:0014EB*
+ ID_OUI_FROM_DATABASE=AwarePoint Corporation
+
+OUI:0014EC*
+ ID_OUI_FROM_DATABASE=Acro Telecom
+
+OUI:0014ED*
+ ID_OUI_FROM_DATABASE=Airak, Inc.
+
+OUI:0014EE*
+ ID_OUI_FROM_DATABASE=Western Digital Technologies, Inc.
+
+OUI:0014EF*
+ ID_OUI_FROM_DATABASE=TZero Technologies, Inc.
+
+OUI:0014F0*
+ ID_OUI_FROM_DATABASE=Business Security OL AB
+
+OUI:0014F1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0014F2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0014F3*
+ ID_OUI_FROM_DATABASE=ViXS Systems Inc
+
+OUI:0014F4*
+ ID_OUI_FROM_DATABASE=DekTec Digital Video B.V.
+
+OUI:0014F5*
+ ID_OUI_FROM_DATABASE=OSI Security Devices
+
+OUI:0014F6*
+ ID_OUI_FROM_DATABASE=Juniper Networks, Inc.
+
+OUI:0014F7*
+ ID_OUI_FROM_DATABASE=Crevis
+
+OUI:0014F8*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta
+
+OUI:0014F9*
+ ID_OUI_FROM_DATABASE=Vantage Controls
+
+OUI:0014FA*
+ ID_OUI_FROM_DATABASE=AsGa S.A.
+
+OUI:0014FB*
+ ID_OUI_FROM_DATABASE=Technical Solutions Inc.
+
+OUI:0014FC*
+ ID_OUI_FROM_DATABASE=Extandon, Inc.
+
+OUI:0014FD*
+ ID_OUI_FROM_DATABASE=Thecus Technology Corp.
+
+OUI:0014FE*
+ ID_OUI_FROM_DATABASE=Artech Electronics
+
+OUI:0014FF*
+ ID_OUI_FROM_DATABASE=Precise Automation, Inc.
+
+OUI:001500*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001501*
+ ID_OUI_FROM_DATABASE=LexBox
+
+OUI:001502*
+ ID_OUI_FROM_DATABASE=BETA tech
+
+OUI:001503*
+ ID_OUI_FROM_DATABASE=PROFIcomms s.r.o.
+
+OUI:001504*
+ ID_OUI_FROM_DATABASE=GAME PLUS CO., LTD.
+
+OUI:001505*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:001506*
+ ID_OUI_FROM_DATABASE=Neo Photonics
+
+OUI:001507*
+ ID_OUI_FROM_DATABASE=Renaissance Learning Inc
+
+OUI:001508*
+ ID_OUI_FROM_DATABASE=Global Target Enterprise Inc
+
+OUI:001509*
+ ID_OUI_FROM_DATABASE=Plus Technology Co., Ltd
+
+OUI:00150A*
+ ID_OUI_FROM_DATABASE=Sonoa Systems, Inc
+
+OUI:00150B*
+ ID_OUI_FROM_DATABASE=SAGE INFOTECH LTD.
+
+OUI:00150C*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:00150D*
+ ID_OUI_FROM_DATABASE=Hoana Medical, Inc.
+
+OUI:00150E*
+ ID_OUI_FROM_DATABASE=OPENBRAIN TECHNOLOGIES CO., LTD.
+
+OUI:00150F*
+ ID_OUI_FROM_DATABASE=mingjong
+
+OUI:001510*
+ ID_OUI_FROM_DATABASE=Techsphere Co., Ltd
+
+OUI:001511*
+ ID_OUI_FROM_DATABASE=Data Center Systems
+
+OUI:001512*
+ ID_OUI_FROM_DATABASE=Zurich University of Applied Sciences
+
+OUI:001513*
+ ID_OUI_FROM_DATABASE=EFS sas
+
+OUI:001514*
+ ID_OUI_FROM_DATABASE=Hu Zhou NAVA Networks&Electronics Ltd.
+
+OUI:001515*
+ ID_OUI_FROM_DATABASE=Leipold+Co.GmbH
+
+OUI:001516*
+ ID_OUI_FROM_DATABASE=URIEL SYSTEMS INC.
+
+OUI:001517*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001518*
+ ID_OUI_FROM_DATABASE=Shenzhen 10MOONS Technology Development CO.,Ltd
+
+OUI:001519*
+ ID_OUI_FROM_DATABASE=StoreAge Networking Technologies
+
+OUI:00151A*
+ ID_OUI_FROM_DATABASE=Hunter Engineering Company
+
+OUI:00151B*
+ ID_OUI_FROM_DATABASE=Isilon Systems Inc.
+
+OUI:00151C*
+ ID_OUI_FROM_DATABASE=LENECO
+
+OUI:00151D*
+ ID_OUI_FROM_DATABASE=M2I CORPORATION
+
+OUI:00151E*
+ ID_OUI_FROM_DATABASE=Ethernet Powerlink Standardization Group (EPSG)
+
+OUI:00151F*
+ ID_OUI_FROM_DATABASE=Multivision Intelligent Surveillance (Hong Kong) Ltd
+
+OUI:001520*
+ ID_OUI_FROM_DATABASE=Radiocrafts AS
+
+OUI:001521*
+ ID_OUI_FROM_DATABASE=Horoquartz
+
+OUI:001522*
+ ID_OUI_FROM_DATABASE=Dea Security
+
+OUI:001523*
+ ID_OUI_FROM_DATABASE=Meteor Communications Corporation
+
+OUI:001524*
+ ID_OUI_FROM_DATABASE=Numatics, Inc.
+
+OUI:001525*
+ ID_OUI_FROM_DATABASE=Chamberlain Access Solutions
+
+OUI:001526*
+ ID_OUI_FROM_DATABASE=Remote Technologies Inc
+
+OUI:001527*
+ ID_OUI_FROM_DATABASE=Balboa Instruments
+
+OUI:001528*
+ ID_OUI_FROM_DATABASE=Beacon Medical Products LLC d.b.a. BeaconMedaes
+
+OUI:001529*
+ ID_OUI_FROM_DATABASE=N3 Corporation
+
+OUI:00152A*
+ ID_OUI_FROM_DATABASE=Nokia GmbH
+
+OUI:00152B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00152C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00152D*
+ ID_OUI_FROM_DATABASE=TenX Networks, LLC
+
+OUI:00152E*
+ ID_OUI_FROM_DATABASE=PacketHop, Inc.
+
+OUI:00152F*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001530*
+ ID_OUI_FROM_DATABASE=EMC Corporation
+
+OUI:001531*
+ ID_OUI_FROM_DATABASE=KOCOM
+
+OUI:001532*
+ ID_OUI_FROM_DATABASE=Consumer Technologies Group, LLC
+
+OUI:001533*
+ ID_OUI_FROM_DATABASE=NADAM.CO.,LTD
+
+OUI:001534*
+ ID_OUI_FROM_DATABASE=A Beltrónica-Companhia de Comunicações, Lda
+
+OUI:001535*
+ ID_OUI_FROM_DATABASE=OTE Spa
+
+OUI:001536*
+ ID_OUI_FROM_DATABASE=Powertech co.,Ltd
+
+OUI:001537*
+ ID_OUI_FROM_DATABASE=Ventus Networks
+
+OUI:001538*
+ ID_OUI_FROM_DATABASE=RFID, Inc.
+
+OUI:001539*
+ ID_OUI_FROM_DATABASE=Technodrive SRL
+
+OUI:00153A*
+ ID_OUI_FROM_DATABASE=Shenzhen Syscan Technology Co.,Ltd.
+
+OUI:00153B*
+ ID_OUI_FROM_DATABASE=EMH metering GmbH & Co. KG
+
+OUI:00153C*
+ ID_OUI_FROM_DATABASE=Kprotech Co., Ltd.
+
+OUI:00153D*
+ ID_OUI_FROM_DATABASE=ELIM PRODUCT CO.
+
+OUI:00153E*
+ ID_OUI_FROM_DATABASE=Q-Matic Sweden AB
+
+OUI:00153F*
+ ID_OUI_FROM_DATABASE=Alcatel Alenia Space Italia
+
+OUI:001540*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001541*
+ ID_OUI_FROM_DATABASE=StrataLight Communications, Inc.
+
+OUI:001542*
+ ID_OUI_FROM_DATABASE=MICROHARD S.R.L.
+
+OUI:001543*
+ ID_OUI_FROM_DATABASE=Aberdeen Test Center
+
+OUI:001544*
+ ID_OUI_FROM_DATABASE=coM.s.a.t. AG
+
+OUI:001545*
+ ID_OUI_FROM_DATABASE=SEECODE Co., Ltd.
+
+OUI:001546*
+ ID_OUI_FROM_DATABASE=ITG Worldwide Sdn Bhd
+
+OUI:001547*
+ ID_OUI_FROM_DATABASE=AiZen Solutions Inc.
+
+OUI:001548*
+ ID_OUI_FROM_DATABASE=CUBE TECHNOLOGIES
+
+OUI:001549*
+ ID_OUI_FROM_DATABASE=Dixtal Biomedica Ind. Com. Ltda
+
+OUI:00154A*
+ ID_OUI_FROM_DATABASE=WANSHIH ELECTRONIC CO., LTD
+
+OUI:00154B*
+ ID_OUI_FROM_DATABASE=Wonde Proud Technology Co., Ltd
+
+OUI:00154C*
+ ID_OUI_FROM_DATABASE=Saunders Electronics
+
+OUI:00154D*
+ ID_OUI_FROM_DATABASE=Netronome Systems, Inc.
+
+OUI:00154E*
+ ID_OUI_FROM_DATABASE=IEC
+
+OUI:00154F*
+ ID_OUI_FROM_DATABASE=one RF Technology
+
+OUI:001550*
+ ID_OUI_FROM_DATABASE=Nits Technology Inc
+
+OUI:001551*
+ ID_OUI_FROM_DATABASE=RadioPulse Inc.
+
+OUI:001552*
+ ID_OUI_FROM_DATABASE=Wi-Gear Inc.
+
+OUI:001553*
+ ID_OUI_FROM_DATABASE=Cytyc Corporation
+
+OUI:001554*
+ ID_OUI_FROM_DATABASE=Atalum Wireless S.A.
+
+OUI:001555*
+ ID_OUI_FROM_DATABASE=DFM GmbH
+
+OUI:001556*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:001557*
+ ID_OUI_FROM_DATABASE=Olivetti
+
+OUI:001558*
+ ID_OUI_FROM_DATABASE=FOXCONN
+
+OUI:001559*
+ ID_OUI_FROM_DATABASE=Securaplane Technologies, Inc.
+
+OUI:00155A*
+ ID_OUI_FROM_DATABASE=DAINIPPON PHARMACEUTICAL CO., LTD.
+
+OUI:00155B*
+ ID_OUI_FROM_DATABASE=Sampo Corporation
+
+OUI:00155C*
+ ID_OUI_FROM_DATABASE=Dresser Wayne
+
+OUI:00155D*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:00155E*
+ ID_OUI_FROM_DATABASE=Morgan Stanley
+
+OUI:00155F*
+ ID_OUI_FROM_DATABASE=GreenPeak Technologies
+
+OUI:001560*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001561*
+ ID_OUI_FROM_DATABASE=JJPlus Corporation
+
+OUI:001562*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001563*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001564*
+ ID_OUI_FROM_DATABASE=BEHRINGER Spezielle Studiotechnik GmbH
+
+OUI:001565*
+ ID_OUI_FROM_DATABASE=XIAMEN YEALINK NETWORK TECHNOLOGY CO.,LTD
+
+OUI:001566*
+ ID_OUI_FROM_DATABASE=A-First Technology Co., Ltd.
+
+OUI:001567*
+ ID_OUI_FROM_DATABASE=RADWIN Inc.
+
+OUI:001568*
+ ID_OUI_FROM_DATABASE=Dilithium Networks
+
+OUI:001569*
+ ID_OUI_FROM_DATABASE=PECO II, Inc.
+
+OUI:00156A*
+ ID_OUI_FROM_DATABASE=DG2L Technologies Pvt. Ltd.
+
+OUI:00156B*
+ ID_OUI_FROM_DATABASE=Perfisans Networks Corp.
+
+OUI:00156C*
+ ID_OUI_FROM_DATABASE=SANE SYSTEM CO., LTD
+
+OUI:00156D*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc.
+
+OUI:00156E*
+ ID_OUI_FROM_DATABASE=A. W. Communication Systems Ltd
+
+OUI:00156F*
+ ID_OUI_FROM_DATABASE=Xiranet Communications GmbH
+
+OUI:001570*
+ ID_OUI_FROM_DATABASE=Symbol TechnologiesWholly owned Subsidiary of Motorola
+
+OUI:001571*
+ ID_OUI_FROM_DATABASE=Nolan Systems
+
+OUI:001572*
+ ID_OUI_FROM_DATABASE=Red-Lemon
+
+OUI:001573*
+ ID_OUI_FROM_DATABASE=NewSoft  Technology Corporation
+
+OUI:001574*
+ ID_OUI_FROM_DATABASE=Horizon Semiconductors Ltd.
+
+OUI:001575*
+ ID_OUI_FROM_DATABASE=Nevis Networks Inc.
+
+OUI:001576*
+ ID_OUI_FROM_DATABASE=LABiTec - Labor Biomedical Technologies GmbH
+
+OUI:001577*
+ ID_OUI_FROM_DATABASE=Allied Telesis
+
+OUI:001578*
+ ID_OUI_FROM_DATABASE=Audio / Video Innovations
+
+OUI:001579*
+ ID_OUI_FROM_DATABASE=Lunatone Industrielle Elektronik GmbH
+
+OUI:00157A*
+ ID_OUI_FROM_DATABASE=Telefin S.p.A.
+
+OUI:00157B*
+ ID_OUI_FROM_DATABASE=Leuze electronic GmbH + Co. KG
+
+OUI:00157C*
+ ID_OUI_FROM_DATABASE=Dave Networks, Inc.
+
+OUI:00157D*
+ ID_OUI_FROM_DATABASE=POSDATA CO., LTD.
+
+OUI:00157E*
+ ID_OUI_FROM_DATABASE=Weidmüller Interface GmbH & Co. KG
+
+OUI:00157F*
+ ID_OUI_FROM_DATABASE=ChuanG International Holding CO.,LTD.
+
+OUI:001580*
+ ID_OUI_FROM_DATABASE=U-WAY CORPORATION
+
+OUI:001581*
+ ID_OUI_FROM_DATABASE=MAKUS Inc.
+
+OUI:001582*
+ ID_OUI_FROM_DATABASE=Pulse Eight Limited
+
+OUI:001583*
+ ID_OUI_FROM_DATABASE=IVT corporation
+
+OUI:001584*
+ ID_OUI_FROM_DATABASE=Schenck Process GmbH
+
+OUI:001585*
+ ID_OUI_FROM_DATABASE=Aonvision Technolopy Corp.
+
+OUI:001586*
+ ID_OUI_FROM_DATABASE=Xiamen Overseas Chinese Electronic Co., Ltd.
+
+OUI:001587*
+ ID_OUI_FROM_DATABASE=Takenaka Seisakusho Co.,Ltd
+
+OUI:001588*
+ ID_OUI_FROM_DATABASE=Balda Solution Malaysia Sdn Bhd
+
+OUI:001589*
+ ID_OUI_FROM_DATABASE=D-MAX Technology Co.,Ltd
+
+OUI:00158A*
+ ID_OUI_FROM_DATABASE=SURECOM Technology Corp.
+
+OUI:00158B*
+ ID_OUI_FROM_DATABASE=Park Air Systems Ltd
+
+OUI:00158C*
+ ID_OUI_FROM_DATABASE=Liab ApS
+
+OUI:00158D*
+ ID_OUI_FROM_DATABASE=Jennic Ltd
+
+OUI:00158E*
+ ID_OUI_FROM_DATABASE=Plustek.INC
+
+OUI:00158F*
+ ID_OUI_FROM_DATABASE=NTT Advanced Technology Corporation
+
+OUI:001590*
+ ID_OUI_FROM_DATABASE=Hectronic GmbH
+
+OUI:001591*
+ ID_OUI_FROM_DATABASE=RLW Inc.
+
+OUI:001592*
+ ID_OUI_FROM_DATABASE=Facom UK Ltd (Melksham)
+
+OUI:001593*
+ ID_OUI_FROM_DATABASE=U4EA Technologies Inc.
+
+OUI:001594*
+ ID_OUI_FROM_DATABASE=BIXOLON CO.,LTD
+
+OUI:001595*
+ ID_OUI_FROM_DATABASE=Quester Tangent Corporation
+
+OUI:001596*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:001597*
+ ID_OUI_FROM_DATABASE=AETA AUDIO SYSTEMS
+
+OUI:001598*
+ ID_OUI_FROM_DATABASE=Kolektor group
+
+OUI:001599*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
+
+OUI:00159A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00159B*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:00159C*
+ ID_OUI_FROM_DATABASE=B-KYUNG SYSTEM Co.,Ltd.
+
+OUI:00159D*
+ ID_OUI_FROM_DATABASE=Minicom Advanced Systems ltd
+
+OUI:00159E*
+ ID_OUI_FROM_DATABASE=Mad Catz Interactive Inc
+
+OUI:00159F*
+ ID_OUI_FROM_DATABASE=Terascala, Inc.
+
+OUI:0015A0*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0015A1*
+ ID_OUI_FROM_DATABASE=ECA-SINTERS
+
+OUI:0015A2*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:0015A3*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:0015A4*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:0015A5*
+ ID_OUI_FROM_DATABASE=DCI Co., Ltd.
+
+OUI:0015A6*
+ ID_OUI_FROM_DATABASE=Digital Electronics Products Ltd.
+
+OUI:0015A7*
+ ID_OUI_FROM_DATABASE=Robatech AG
+
+OUI:0015A8*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0015A9*
+ ID_OUI_FROM_DATABASE=KWANG WOO I&C CO.,LTD
+
+OUI:0015AA*
+ ID_OUI_FROM_DATABASE=Rextechnik International Co.,
+
+OUI:0015AB*
+ ID_OUI_FROM_DATABASE=PRO CO SOUND INC
+
+OUI:0015AC*
+ ID_OUI_FROM_DATABASE=Capelon AB
+
+OUI:0015AD*
+ ID_OUI_FROM_DATABASE=Accedian Networks
+
+OUI:0015AE*
+ ID_OUI_FROM_DATABASE=kyung il
+
+OUI:0015AF*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc.
+
+OUI:0015B0*
+ ID_OUI_FROM_DATABASE=AUTOTELENET CO.,LTD
+
+OUI:0015B1*
+ ID_OUI_FROM_DATABASE=Ambient Corporation
+
+OUI:0015B2*
+ ID_OUI_FROM_DATABASE=Advanced Industrial Computer, Inc.
+
+OUI:0015B3*
+ ID_OUI_FROM_DATABASE=Caretech AB
+
+OUI:0015B4*
+ ID_OUI_FROM_DATABASE=Polymap  Wireless LLC
+
+OUI:0015B5*
+ ID_OUI_FROM_DATABASE=CI Network Corp.
+
+OUI:0015B6*
+ ID_OUI_FROM_DATABASE=ShinMaywa Industries, Ltd.
+
+OUI:0015B7*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:0015B8*
+ ID_OUI_FROM_DATABASE=Tahoe
+
+OUI:0015B9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+OUI:0015BA*
+ ID_OUI_FROM_DATABASE=iba AG
+
+OUI:0015BB*
+ ID_OUI_FROM_DATABASE=SMA Solar Technology AG
+
+OUI:0015BC*
+ ID_OUI_FROM_DATABASE=Develco
+
+OUI:0015BD*
+ ID_OUI_FROM_DATABASE=Group 4 Technology Ltd
+
+OUI:0015BE*
+ ID_OUI_FROM_DATABASE=Iqua Ltd.
+
+OUI:0015BF*
+ ID_OUI_FROM_DATABASE=technicob
+
+OUI:0015C0*
+ ID_OUI_FROM_DATABASE=DIGITAL TELEMEDIA CO.,LTD.
+
+OUI:0015C1*
+ ID_OUI_FROM_DATABASE=SONY Computer Entertainment inc,
+
+OUI:0015C2*
+ ID_OUI_FROM_DATABASE=3M Germany
+
+OUI:0015C3*
+ ID_OUI_FROM_DATABASE=Ruf Telematik AG
+
+OUI:0015C4*
+ ID_OUI_FROM_DATABASE=FLOVEL CO., LTD.
+
+OUI:0015C5*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:0015C6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0015C7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0015C8*
+ ID_OUI_FROM_DATABASE=FlexiPanel Ltd
+
+OUI:0015C9*
+ ID_OUI_FROM_DATABASE=Gumstix, Inc
+
+OUI:0015CA*
+ ID_OUI_FROM_DATABASE=TeraRecon, Inc.
+
+OUI:0015CB*
+ ID_OUI_FROM_DATABASE=Surf Communication Solutions Ltd.
+
+OUI:0015CC*
+ ID_OUI_FROM_DATABASE=UQUEST, LTD.
+
+OUI:0015CD*
+ ID_OUI_FROM_DATABASE=Exartech International Corp.
+
+OUI:0015CE*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:0015CF*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:0015D0*
+ ID_OUI_FROM_DATABASE=ARRIS International
+
+OUI:0015D1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015D2*
+ ID_OUI_FROM_DATABASE=Xantech Corporation
+
+OUI:0015D3*
+ ID_OUI_FROM_DATABASE=Pantech&Curitel Communications, Inc.
+
+OUI:0015D4*
+ ID_OUI_FROM_DATABASE=Emitor AB
+
+OUI:0015D5*
+ ID_OUI_FROM_DATABASE=NICEVT
+
+OUI:0015D6*
+ ID_OUI_FROM_DATABASE=OSLiNK Sp. z o.o.
+
+OUI:0015D7*
+ ID_OUI_FROM_DATABASE=Reti Corporation
+
+OUI:0015D8*
+ ID_OUI_FROM_DATABASE=Interlink Electronics
+
+OUI:0015D9*
+ ID_OUI_FROM_DATABASE=PKC Electronics Oy
+
+OUI:0015DA*
+ ID_OUI_FROM_DATABASE=IRITEL A.D.
+
+OUI:0015DB*
+ ID_OUI_FROM_DATABASE=Canesta Inc.
+
+OUI:0015DC*
+ ID_OUI_FROM_DATABASE=KT&C Co., Ltd.
+
+OUI:0015DD*
+ ID_OUI_FROM_DATABASE=IP Control Systems Ltd.
+
+OUI:0015DE*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0015DF*
+ ID_OUI_FROM_DATABASE=Clivet S.p.A.
+
+OUI:0015E0*
+ ID_OUI_FROM_DATABASE=ST-Ericsson
+
+OUI:0015E1*
+ ID_OUI_FROM_DATABASE=Picochip Ltd
+
+OUI:0015E2*
+ ID_OUI_FROM_DATABASE=Dr.Ing. Herbert Knauer GmbH
+
+OUI:0015E3*
+ ID_OUI_FROM_DATABASE=Dream Technologies Corporation
+
+OUI:0015E4*
+ ID_OUI_FROM_DATABASE=Zimmer Elektromedizin
+
+OUI:0015E5*
+ ID_OUI_FROM_DATABASE=Cheertek Inc.
+
+OUI:0015E6*
+ ID_OUI_FROM_DATABASE=MOBILE TECHNIKA Inc.
+
+OUI:0015E7*
+ ID_OUI_FROM_DATABASE=Quantec ProAudio
+
+OUI:0015E8*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:0015E9*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:0015EA*
+ ID_OUI_FROM_DATABASE=Tellumat (Pty) Ltd
+
+OUI:0015EB*
+ ID_OUI_FROM_DATABASE=ZTE CORPORATION
+
+OUI:0015EC*
+ ID_OUI_FROM_DATABASE=Boca Devices LLC
+
+OUI:0015ED*
+ ID_OUI_FROM_DATABASE=Fulcrum Microsystems, Inc.
+
+OUI:0015EE*
+ ID_OUI_FROM_DATABASE=Omnex Control Systems
+
+OUI:0015EF*
+ ID_OUI_FROM_DATABASE=NEC TOKIN Corporation
+
+OUI:0015F0*
+ ID_OUI_FROM_DATABASE=EGO BV
+
+OUI:0015F1*
+ ID_OUI_FROM_DATABASE=KYLINK Communications Corp.
+
+OUI:0015F2*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:0015F3*
+ ID_OUI_FROM_DATABASE=PELTOR AB
+
+OUI:0015F4*
+ ID_OUI_FROM_DATABASE=Eventide
+
+OUI:0015F5*
+ ID_OUI_FROM_DATABASE=Sustainable Energy Systems
+
+OUI:0015F6*
+ ID_OUI_FROM_DATABASE=SCIENCE AND ENGINEERING SERVICES, INC.
+
+OUI:0015F7*
+ ID_OUI_FROM_DATABASE=Wintecronics Ltd.
+
+OUI:0015F8*
+ ID_OUI_FROM_DATABASE=Kingtronics Industrial Co. Ltd.
+
+OUI:0015F9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0015FA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0015FB*
+ ID_OUI_FROM_DATABASE=setex schermuly textile computer gmbh
+
+OUI:0015FC*
+ ID_OUI_FROM_DATABASE=Littelfuse Startco
+
+OUI:0015FD*
+ ID_OUI_FROM_DATABASE=Complete Media Systems
+
+OUI:0015FE*
+ ID_OUI_FROM_DATABASE=SCHILLING ROBOTICS LLC
+
+OUI:0015FF*
+ ID_OUI_FROM_DATABASE=Novatel Wireless, Inc.
+
+OUI:001600*
+ ID_OUI_FROM_DATABASE=CelleBrite Mobile Synchronization
+
+OUI:001601*
+ ID_OUI_FROM_DATABASE=Buffalo Inc.
+
+OUI:001602*
+ ID_OUI_FROM_DATABASE=CEYON TECHNOLOGY CO.,LTD.
+
+OUI:001603*
+ ID_OUI_FROM_DATABASE=COOLKSKY Co., LTD
+
+OUI:001604*
+ ID_OUI_FROM_DATABASE=Sigpro
+
+OUI:001605*
+ ID_OUI_FROM_DATABASE=YORKVILLE SOUND INC.
+
+OUI:001606*
+ ID_OUI_FROM_DATABASE=Ideal Industries
+
+OUI:001607*
+ ID_OUI_FROM_DATABASE=Curves International Inc.
+
+OUI:001608*
+ ID_OUI_FROM_DATABASE=Sequans Communications
+
+OUI:001609*
+ ID_OUI_FROM_DATABASE=Unitech electronics co., ltd.
+
+OUI:00160A*
+ ID_OUI_FROM_DATABASE=SWEEX Europe BV
+
+OUI:00160B*
+ ID_OUI_FROM_DATABASE=TVWorks LLC
+
+OUI:00160C*
+ ID_OUI_FROM_DATABASE=LPL  DEVELOPMENT S.A. DE C.V
+
+OUI:00160D*
+ ID_OUI_FROM_DATABASE=Be Here Corporation
+
+OUI:00160E*
+ ID_OUI_FROM_DATABASE=Optica Technologies Inc.
+
+OUI:00160F*
+ ID_OUI_FROM_DATABASE=BADGER METER INC
+
+OUI:001610*
+ ID_OUI_FROM_DATABASE=Carina Technology
+
+OUI:001611*
+ ID_OUI_FROM_DATABASE=Altecon Srl
+
+OUI:001612*
+ ID_OUI_FROM_DATABASE=Otsuka Electronics Co., Ltd.
+
+OUI:001613*
+ ID_OUI_FROM_DATABASE=LibreStream Technologies Inc.
+
+OUI:001614*
+ ID_OUI_FROM_DATABASE=Picosecond Pulse Labs
+
+OUI:001615*
+ ID_OUI_FROM_DATABASE=Nittan Company, Limited
+
+OUI:001616*
+ ID_OUI_FROM_DATABASE=BROWAN COMMUNICATION INC.
+
+OUI:001617*
+ ID_OUI_FROM_DATABASE=MSI
+
+OUI:001618*
+ ID_OUI_FROM_DATABASE=HIVION Co., Ltd.
+
+OUI:001619*
+ ID_OUI_FROM_DATABASE=La Factoría de Comunicaciones Aplicadas,S.L.
+
+OUI:00161A*
+ ID_OUI_FROM_DATABASE=Dametric AB
+
+OUI:00161B*
+ ID_OUI_FROM_DATABASE=Micronet Corporation
+
+OUI:00161C*
+ ID_OUI_FROM_DATABASE=e:cue
+
+OUI:00161D*
+ ID_OUI_FROM_DATABASE=Innovative Wireless Technologies, Inc.
+
+OUI:00161E*
+ ID_OUI_FROM_DATABASE=Woojinnet
+
+OUI:00161F*
+ ID_OUI_FROM_DATABASE=SUNWAVETEC Co., Ltd.
+
+OUI:001620*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:001621*
+ ID_OUI_FROM_DATABASE=Colorado Vnet
+
+OUI:001622*
+ ID_OUI_FROM_DATABASE=BBH SYSTEMS GMBH
+
+OUI:001623*
+ ID_OUI_FROM_DATABASE=Interval Media
+
+OUI:001624*
+ ID_OUI_FROM_DATABASE=Teneros, Inc.
+
+OUI:001625*
+ ID_OUI_FROM_DATABASE=Impinj, Inc.
+
+OUI:001626*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001627*
+ ID_OUI_FROM_DATABASE=embedded-logic DESIGN AND MORE GmbH
+
+OUI:001628*
+ ID_OUI_FROM_DATABASE=Ultra Electronics Manufacturing and Card Systems
+
+OUI:001629*
+ ID_OUI_FROM_DATABASE=Nivus GmbH
+
+OUI:00162A*
+ ID_OUI_FROM_DATABASE=Antik computers & communications s.r.o.
+
+OUI:00162B*
+ ID_OUI_FROM_DATABASE=Togami Electric Mfg.co.,Ltd.
+
+OUI:00162C*
+ ID_OUI_FROM_DATABASE=Xanboo
+
+OUI:00162D*
+ ID_OUI_FROM_DATABASE=STNet Co., Ltd.
+
+OUI:00162E*
+ ID_OUI_FROM_DATABASE=Space Shuttle Hi-Tech Co., Ltd.
+
+OUI:00162F*
+ ID_OUI_FROM_DATABASE=Geutebrück GmbH
+
+OUI:001630*
+ ID_OUI_FROM_DATABASE=Vativ Technologies
+
+OUI:001631*
+ ID_OUI_FROM_DATABASE=Xteam
+
+OUI:001632*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD.
+
+OUI:001633*
+ ID_OUI_FROM_DATABASE=Oxford Diagnostics Ltd.
+
+OUI:001634*
+ ID_OUI_FROM_DATABASE=Mathtech, Inc.
+
+OUI:001635*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001636*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc.
+
+OUI:001637*
+ ID_OUI_FROM_DATABASE=Citel Srl
+
+OUI:001638*
+ ID_OUI_FROM_DATABASE=TECOM Co., Ltd.
+
+OUI:001639*
+ ID_OUI_FROM_DATABASE=UBIQUAM Co.,Ltd
+
+OUI:00163A*
+ ID_OUI_FROM_DATABASE=YVES TECHNOLOGY CO., LTD.
+
+OUI:00163B*
+ ID_OUI_FROM_DATABASE=VertexRSI/General Dynamics
+
+OUI:00163C*
+ ID_OUI_FROM_DATABASE=Rebox B.V.
+
+OUI:00163D*
+ ID_OUI_FROM_DATABASE=Tsinghua Tongfang Legend Silicon Tech. Co., Ltd.
+
+OUI:00163E*
+ ID_OUI_FROM_DATABASE=Xensource, Inc.
+
+OUI:00163F*
+ ID_OUI_FROM_DATABASE=CReTE SYSTEMS Inc.
+
+OUI:001640*
+ ID_OUI_FROM_DATABASE=Asmobile Communication Inc.
+
+OUI:001641*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:001642*
+ ID_OUI_FROM_DATABASE=Pangolin
+
+OUI:001643*
+ ID_OUI_FROM_DATABASE=Sunhillo Corporation
+
+OUI:001644*
+ ID_OUI_FROM_DATABASE=LITE-ON Technology Corp.
+
+OUI:001645*
+ ID_OUI_FROM_DATABASE=Power Distribution, Inc.
+
+OUI:001646*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001647*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001648*
+ ID_OUI_FROM_DATABASE=SSD Company Limited
+
+OUI:001649*
+ ID_OUI_FROM_DATABASE=SetOne GmbH
+
+OUI:00164A*
+ ID_OUI_FROM_DATABASE=Vibration Technology Limited
+
+OUI:00164B*
+ ID_OUI_FROM_DATABASE=Quorion Data Systems GmbH
+
+OUI:00164C*
+ ID_OUI_FROM_DATABASE=PLANET INT Co., Ltd
+
+OUI:00164D*
+ ID_OUI_FROM_DATABASE=Alcatel North America IP Division
+
+OUI:00164E*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00164F*
+ ID_OUI_FROM_DATABASE=World Ethnic Broadcastin Inc.
+
+OUI:001650*
+ ID_OUI_FROM_DATABASE=Herley General Microwave Israel.
+
+OUI:001651*
+ ID_OUI_FROM_DATABASE=Exeo Systems
+
+OUI:001652*
+ ID_OUI_FROM_DATABASE=Hoatech Technologies, Inc.
+
+OUI:001653*
+ ID_OUI_FROM_DATABASE=LEGO System A/S IE Electronics Division
+
+OUI:001654*
+ ID_OUI_FROM_DATABASE=Flex-P Industries Sdn. Bhd.
+
+OUI:001655*
+ ID_OUI_FROM_DATABASE=FUHO TECHNOLOGY Co., LTD
+
+OUI:001656*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001657*
+ ID_OUI_FROM_DATABASE=Aegate Ltd
+
+OUI:001658*
+ ID_OUI_FROM_DATABASE=Fusiontech Technologies Inc.
+
+OUI:001659*
+ ID_OUI_FROM_DATABASE=Z.M.P. RADWAG
+
+OUI:00165A*
+ ID_OUI_FROM_DATABASE=Harman Specialty Group
+
+OUI:00165B*
+ ID_OUI_FROM_DATABASE=Grip Audio
+
+OUI:00165C*
+ ID_OUI_FROM_DATABASE=Trackflow Ltd
+
+OUI:00165D*
+ ID_OUI_FROM_DATABASE=AirDefense, Inc.
+
+OUI:00165E*
+ ID_OUI_FROM_DATABASE=Precision I/O
+
+OUI:00165F*
+ ID_OUI_FROM_DATABASE=Fairmount Automation
+
+OUI:001660*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001661*
+ ID_OUI_FROM_DATABASE=Novatium Solutions (P) Ltd
+
+OUI:001662*
+ ID_OUI_FROM_DATABASE=Liyuh Technology Ltd.
+
+OUI:001663*
+ ID_OUI_FROM_DATABASE=KBT Mobile
+
+OUI:001664*
+ ID_OUI_FROM_DATABASE=Prod-El SpA
+
+OUI:001665*
+ ID_OUI_FROM_DATABASE=Cellon France
+
+OUI:001666*
+ ID_OUI_FROM_DATABASE=Quantier Communication Inc.
+
+OUI:001667*
+ ID_OUI_FROM_DATABASE=A-TEC Subsystem INC.
+
+OUI:001668*
+ ID_OUI_FROM_DATABASE=Eishin Electronics
+
+OUI:001669*
+ ID_OUI_FROM_DATABASE=MRV Communication (Networks) LTD
+
+OUI:00166A*
+ ID_OUI_FROM_DATABASE=TPS
+
+OUI:00166B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:00166C*
+ ID_OUI_FROM_DATABASE=Samsung Electonics Digital Video System Division
+
+OUI:00166D*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt
+
+OUI:00166E*
+ ID_OUI_FROM_DATABASE=Arbitron Inc.
+
+OUI:00166F*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:001670*
+ ID_OUI_FROM_DATABASE=SKNET Corporation
+
+OUI:001671*
+ ID_OUI_FROM_DATABASE=Symphox Information Co.
+
+OUI:001672*
+ ID_OUI_FROM_DATABASE=Zenway enterprise ltd
+
+OUI:001673*
+ ID_OUI_FROM_DATABASE=Bury GmbH & Co. KG
+
+OUI:001674*
+ ID_OUI_FROM_DATABASE=EuroCB (Phils.), Inc.
+
+OUI:001675*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001676*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:001677*
+ ID_OUI_FROM_DATABASE=Bihl+Wiedemann GmbH
+
+OUI:001678*
+ ID_OUI_FROM_DATABASE=SHENZHEN BAOAN GAOKE ELECTRONICS CO., LTD
+
+OUI:001679*
+ ID_OUI_FROM_DATABASE=eOn Communications
+
+OUI:00167A*
+ ID_OUI_FROM_DATABASE=Skyworth Overseas Dvelopment Ltd.
+
+OUI:00167B*
+ ID_OUI_FROM_DATABASE=Haver&Boecker
+
+OUI:00167C*
+ ID_OUI_FROM_DATABASE=iRex Technologies BV
+
+OUI:00167D*
+ ID_OUI_FROM_DATABASE=Sky-Line Information Co., Ltd.
+
+OUI:00167E*
+ ID_OUI_FROM_DATABASE=DIBOSS.CO.,LTD
+
+OUI:00167F*
+ ID_OUI_FROM_DATABASE=Bluebird Soft Inc.
+
+OUI:001680*
+ ID_OUI_FROM_DATABASE=Bally Gaming + Systems
+
+OUI:001681*
+ ID_OUI_FROM_DATABASE=Vector Informatik GmbH
+
+OUI:001682*
+ ID_OUI_FROM_DATABASE=Pro Dex, Inc
+
+OUI:001683*
+ ID_OUI_FROM_DATABASE=WEBIO International Co.,.Ltd.
+
+OUI:001684*
+ ID_OUI_FROM_DATABASE=Donjin Co.,Ltd.
+
+OUI:001685*
+ ID_OUI_FROM_DATABASE=Elisa Oyj
+
+OUI:001686*
+ ID_OUI_FROM_DATABASE=Karl Storz Imaging
+
+OUI:001687*
+ ID_OUI_FROM_DATABASE=Chubb CSC-Vendor AP
+
+OUI:001688*
+ ID_OUI_FROM_DATABASE=ServerEngines LLC
+
+OUI:001689*
+ ID_OUI_FROM_DATABASE=Pilkor Electronics Co., Ltd
+
+OUI:00168A*
+ ID_OUI_FROM_DATABASE=id-Confirm Inc
+
+OUI:00168B*
+ ID_OUI_FROM_DATABASE=Paralan Corporation
+
+OUI:00168C*
+ ID_OUI_FROM_DATABASE=DSL Partner AS
+
+OUI:00168D*
+ ID_OUI_FROM_DATABASE=KORWIN CO., Ltd.
+
+OUI:00168E*
+ ID_OUI_FROM_DATABASE=Vimicro corporation
+
+OUI:00168F*
+ ID_OUI_FROM_DATABASE=GN Netcom as
+
+OUI:001690*
+ ID_OUI_FROM_DATABASE=J-TEK INCORPORATION
+
+OUI:001691*
+ ID_OUI_FROM_DATABASE=Moser-Baer AG
+
+OUI:001692*
+ ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc.
+
+OUI:001693*
+ ID_OUI_FROM_DATABASE=PowerLink Technology Inc.
+
+OUI:001694*
+ ID_OUI_FROM_DATABASE=Sennheiser Communications A/S
+
+OUI:001695*
+ ID_OUI_FROM_DATABASE=AVC Technology (International) Limited
+
+OUI:001696*
+ ID_OUI_FROM_DATABASE=QDI Technology (H.K.) Limited
+
+OUI:001697*
+ ID_OUI_FROM_DATABASE=NEC Corporation
+
+OUI:001698*
+ ID_OUI_FROM_DATABASE=T&A Mobile Phones
+
+OUI:001699*
+ ID_OUI_FROM_DATABASE=Tonic DVB Marketing Ltd
+
+OUI:00169A*
+ ID_OUI_FROM_DATABASE=Quadrics Ltd
+
+OUI:00169B*
+ ID_OUI_FROM_DATABASE=Alstom Transport
+
+OUI:00169C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00169D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00169E*
+ ID_OUI_FROM_DATABASE=TV One Ltd
+
+OUI:00169F*
+ ID_OUI_FROM_DATABASE=Vimtron Electronics Co., Ltd.
+
+OUI:0016A0*
+ ID_OUI_FROM_DATABASE=Auto-Maskin
+
+OUI:0016A1*
+ ID_OUI_FROM_DATABASE=3Leaf Networks
+
+OUI:0016A2*
+ ID_OUI_FROM_DATABASE=CentraLite Systems, Inc.
+
+OUI:0016A3*
+ ID_OUI_FROM_DATABASE=Ingeteam Transmission&Distribution, S.A.
+
+OUI:0016A4*
+ ID_OUI_FROM_DATABASE=Ezurio Ltd
+
+OUI:0016A5*
+ ID_OUI_FROM_DATABASE=Tandberg Storage ASA
+
+OUI:0016A6*
+ ID_OUI_FROM_DATABASE=Dovado FZ-LLC
+
+OUI:0016A7*
+ ID_OUI_FROM_DATABASE=AWETA G&P
+
+OUI:0016A8*
+ ID_OUI_FROM_DATABASE=CWT CO., LTD.
+
+OUI:0016A9*
+ ID_OUI_FROM_DATABASE=2EI
+
+OUI:0016AA*
+ ID_OUI_FROM_DATABASE=Kei Communication Technology Inc.
+
+OUI:0016AB*
+ ID_OUI_FROM_DATABASE=PBI-Dansensor A/S
+
+OUI:0016AC*
+ ID_OUI_FROM_DATABASE=Toho Technology Corp.
+
+OUI:0016AD*
+ ID_OUI_FROM_DATABASE=BT-Links Company Limited
+
+OUI:0016AE*
+ ID_OUI_FROM_DATABASE=INVENTEL
+
+OUI:0016AF*
+ ID_OUI_FROM_DATABASE=Shenzhen Union Networks Equipment Co.,Ltd.
+
+OUI:0016B0*
+ ID_OUI_FROM_DATABASE=VK Corporation
+
+OUI:0016B1*
+ ID_OUI_FROM_DATABASE=KBS
+
+OUI:0016B2*
+ ID_OUI_FROM_DATABASE=DriveCam Inc
+
+OUI:0016B3*
+ ID_OUI_FROM_DATABASE=Photonicbridges (China) Co., Ltd.
+
+OUI:0016B5*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0016B6*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys
+
+OUI:0016B7*
+ ID_OUI_FROM_DATABASE=Seoul Commtech
+
+OUI:0016B8*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:0016B9*
+ ID_OUI_FROM_DATABASE=ProCurve Networking
+
+OUI:0016BA*
+ ID_OUI_FROM_DATABASE=WEATHERNEWS INC.
+
+OUI:0016BB*
+ ID_OUI_FROM_DATABASE=Law-Chain Computer Technology Co Ltd
+
+OUI:0016BC*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0016BD*
+ ID_OUI_FROM_DATABASE=ATI Industrial Automation
+
+OUI:0016BE*
+ ID_OUI_FROM_DATABASE=INFRANET, Inc.
+
+OUI:0016BF*
+ ID_OUI_FROM_DATABASE=PaloDEx Group Oy
+
+OUI:0016C0*
+ ID_OUI_FROM_DATABASE=Semtech Corporation
+
+OUI:0016C1*
+ ID_OUI_FROM_DATABASE=Eleksen Ltd
+
+OUI:0016C2*
+ ID_OUI_FROM_DATABASE=Avtec Systems Inc
+
+OUI:0016C3*
+ ID_OUI_FROM_DATABASE=BA Systems Inc
+
+OUI:0016C4*
+ ID_OUI_FROM_DATABASE=SiRF Technology, Inc.
+
+OUI:0016C5*
+ ID_OUI_FROM_DATABASE=Shenzhen Xing Feng Industry Co.,Ltd
+
+OUI:0016C6*
+ ID_OUI_FROM_DATABASE=North Atlantic Industries
+
+OUI:0016C7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0016C8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0016C9*
+ ID_OUI_FROM_DATABASE=NAT Seattle, Inc.
+
+OUI:0016CA*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:0016CB*
+ ID_OUI_FROM_DATABASE=Apple Computer
+
+OUI:0016CC*
+ ID_OUI_FROM_DATABASE=Xcute Mobile Corp.
+
+OUI:0016CD*
+ ID_OUI_FROM_DATABASE=HIJI HIGH-TECH CO., LTD.
+
+OUI:0016CE*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:0016CF*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:0016D0*
+ ID_OUI_FROM_DATABASE=ATech elektronika d.o.o.
+
+OUI:0016D1*
+ ID_OUI_FROM_DATABASE=ZAT a.s.
+
+OUI:0016D2*
+ ID_OUI_FROM_DATABASE=Caspian
+
+OUI:0016D3*
+ ID_OUI_FROM_DATABASE=Wistron Corporation
+
+OUI:0016D4*
+ ID_OUI_FROM_DATABASE=Compal Communications, Inc.
+
+OUI:0016D5*
+ ID_OUI_FROM_DATABASE=Synccom Co., Ltd
+
+OUI:0016D6*
+ ID_OUI_FROM_DATABASE=TDA Tech Pty Ltd
+
+OUI:0016D7*
+ ID_OUI_FROM_DATABASE=Sunways AG
+
+OUI:0016D8*
+ ID_OUI_FROM_DATABASE=Senea AB
+
+OUI:0016D9*
+ ID_OUI_FROM_DATABASE=NINGBO BIRD CO.,LTD.
+
+OUI:0016DA*
+ ID_OUI_FROM_DATABASE=Futronic Technology Co. Ltd.
+
+OUI:0016DB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+OUI:0016DC*
+ ID_OUI_FROM_DATABASE=ARCHOS
+
+OUI:0016DD*
+ ID_OUI_FROM_DATABASE=Gigabeam Corporation
+
+OUI:0016DE*
+ ID_OUI_FROM_DATABASE=FAST Inc
+
+OUI:0016DF*
+ ID_OUI_FROM_DATABASE=Lundinova AB
+
+OUI:0016E0*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:0016E1*
+ ID_OUI_FROM_DATABASE=SiliconStor, Inc.
+
+OUI:0016E2*
+ ID_OUI_FROM_DATABASE=American Fibertek, Inc.
+
+OUI:0016E3*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP.
+
+OUI:0016E4*
+ ID_OUI_FROM_DATABASE=VANGUARD SECURITY ENGINEERING CORP.
+
+OUI:0016E5*
+ ID_OUI_FROM_DATABASE=FORDLEY DEVELOPMENT LIMITED
+
+OUI:0016E6*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:0016E7*
+ ID_OUI_FROM_DATABASE=Dynamix Promotions Limited
+
+OUI:0016E8*
+ ID_OUI_FROM_DATABASE=Sigma Designs, Inc.
+
+OUI:0016E9*
+ ID_OUI_FROM_DATABASE=Tiba Medical Inc
+
+OUI:0016EA*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0016EB*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0016EC*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co., Ltd.
+
+OUI:0016ED*
+ ID_OUI_FROM_DATABASE=Digital Safety Technologies, Inc
+
+OUI:0016EE*
+ ID_OUI_FROM_DATABASE=RoyalDigital Inc.
+
+OUI:0016EF*
+ ID_OUI_FROM_DATABASE=Koko Fitness, Inc.
+
+OUI:0016F0*
+ ID_OUI_FROM_DATABASE=Dell
+
+OUI:0016F1*
+ ID_OUI_FROM_DATABASE=OmniSense, LLC
+
+OUI:0016F2*
+ ID_OUI_FROM_DATABASE=Dmobile System Co., Ltd.
+
+OUI:0016F3*
+ ID_OUI_FROM_DATABASE=CAST Information Co., Ltd
+
+OUI:0016F4*
+ ID_OUI_FROM_DATABASE=Eidicom Co., Ltd.
+
+OUI:0016F5*
+ ID_OUI_FROM_DATABASE=Dalian Golden Hualu Digital Technology Co.,Ltd
+
+OUI:0016F6*
+ ID_OUI_FROM_DATABASE=Video Products Group
+
+OUI:0016F7*
+ ID_OUI_FROM_DATABASE=L-3 Communications, Electrodynamics, Inc.
+
+OUI:0016F8*
+ ID_OUI_FROM_DATABASE=AVIQTECH TECHNOLOGY CO., LTD.
+
+OUI:0016F9*
+ ID_OUI_FROM_DATABASE=CETRTA POT, d.o.o., Kranj
+
+OUI:0016FA*
+ ID_OUI_FROM_DATABASE=ECI Telecom Ltd.
+
+OUI:0016FB*
+ ID_OUI_FROM_DATABASE=SHENZHEN MTC CO.,LTD.
+
+OUI:0016FC*
+ ID_OUI_FROM_DATABASE=TOHKEN CO.,LTD.
+
+OUI:0016FD*
+ ID_OUI_FROM_DATABASE=Jaty Electronics
+
+OUI:0016FE*
+ ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd
+
+OUI:0016FF*
+ ID_OUI_FROM_DATABASE=Wamin Optocomm Mfg Corp
+
+OUI:001700*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001701*
+ ID_OUI_FROM_DATABASE=KDE, Inc.
+
+OUI:001702*
+ ID_OUI_FROM_DATABASE=Osung Midicom Co., Ltd
+
+OUI:001703*
+ ID_OUI_FROM_DATABASE=MOSDAN Internation Co.,Ltd
+
+OUI:001704*
+ ID_OUI_FROM_DATABASE=Shinco Electronics Group Co.,Ltd
+
+OUI:001705*
+ ID_OUI_FROM_DATABASE=Methode Electronics
+
+OUI:001706*
+ ID_OUI_FROM_DATABASE=Techfaith Wireless Communication Technology Limited.
+
+OUI:001707*
+ ID_OUI_FROM_DATABASE=InGrid, Inc
+
+OUI:001708*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001709*
+ ID_OUI_FROM_DATABASE=Exalt Communications
+
+OUI:00170A*
+ ID_OUI_FROM_DATABASE=INEW DIGITAL COMPANY
+
+OUI:00170B*
+ ID_OUI_FROM_DATABASE=Contela, Inc.
+
+OUI:00170C*
+ ID_OUI_FROM_DATABASE=Twig Com Ltd.
+
+OUI:00170D*
+ ID_OUI_FROM_DATABASE=Dust Networks Inc.
+
+OUI:00170E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00170F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001710*
+ ID_OUI_FROM_DATABASE=Casa Systems Inc.
+
+OUI:001711*
+ ID_OUI_FROM_DATABASE=GE Healthcare Bio-Sciences AB
+
+OUI:001712*
+ ID_OUI_FROM_DATABASE=ISCO International
+
+OUI:001713*
+ ID_OUI_FROM_DATABASE=Tiger NetCom
+
+OUI:001714*
+ ID_OUI_FROM_DATABASE=BR Controls Nederland bv
+
+OUI:001715*
+ ID_OUI_FROM_DATABASE=Qstik
+
+OUI:001716*
+ ID_OUI_FROM_DATABASE=Qno Technology Inc.
+
+OUI:001717*
+ ID_OUI_FROM_DATABASE=Leica Geosystems AG
+
+OUI:001718*
+ ID_OUI_FROM_DATABASE=Vansco Electronics Oy
+
+OUI:001719*
+ ID_OUI_FROM_DATABASE=AudioCodes USA, Inc
+
+OUI:00171A*
+ ID_OUI_FROM_DATABASE=Winegard Company
+
+OUI:00171B*
+ ID_OUI_FROM_DATABASE=Innovation Lab Corp.
+
+OUI:00171C*
+ ID_OUI_FROM_DATABASE=NT MicroSystems, Inc.
+
+OUI:00171D*
+ ID_OUI_FROM_DATABASE=DIGIT
+
+OUI:00171E*
+ ID_OUI_FROM_DATABASE=Theo Benning GmbH & Co. KG
+
+OUI:00171F*
+ ID_OUI_FROM_DATABASE=IMV Corporation
+
+OUI:001720*
+ ID_OUI_FROM_DATABASE=Image Sensing Systems, Inc.
+
+OUI:001721*
+ ID_OUI_FROM_DATABASE=FITRE S.p.A.
+
+OUI:001722*
+ ID_OUI_FROM_DATABASE=Hanazeder Electronic GmbH
+
+OUI:001723*
+ ID_OUI_FROM_DATABASE=Summit Data Communications
+
+OUI:001724*
+ ID_OUI_FROM_DATABASE=Studer Professional Audio GmbH
+
+OUI:001725*
+ ID_OUI_FROM_DATABASE=Liquid Computing
+
+OUI:001726*
+ ID_OUI_FROM_DATABASE=m2c Electronic Technology Ltd.
+
+OUI:001727*
+ ID_OUI_FROM_DATABASE=Thermo Ramsey Italia s.r.l.
+
+OUI:001728*
+ ID_OUI_FROM_DATABASE=Selex Communications
+
+OUI:001729*
+ ID_OUI_FROM_DATABASE=Ubicod Co.LTD
+
+OUI:00172A*
+ ID_OUI_FROM_DATABASE=Proware Technology Corp.
+
+OUI:00172B*
+ ID_OUI_FROM_DATABASE=Global Technologies Inc.
+
+OUI:00172C*
+ ID_OUI_FROM_DATABASE=TAEJIN INFOTECH
+
+OUI:00172D*
+ ID_OUI_FROM_DATABASE=Axcen Photonics Corporation
+
+OUI:00172E*
+ ID_OUI_FROM_DATABASE=FXC Inc.
+
+OUI:00172F*
+ ID_OUI_FROM_DATABASE=NeuLion Incorporated
+
+OUI:001730*
+ ID_OUI_FROM_DATABASE=Automation Electronics
+
+OUI:001731*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:001732*
+ ID_OUI_FROM_DATABASE=Science-Technical Center "RISSA"
+
+OUI:001733*
+ ID_OUI_FROM_DATABASE=SFR
+
+OUI:001734*
+ ID_OUI_FROM_DATABASE=ADC Telecommunications
+
+OUI:001736*
+ ID_OUI_FROM_DATABASE=iiTron Inc.
+
+OUI:001737*
+ ID_OUI_FROM_DATABASE=Industrie Dial Face S.p.A.
+
+OUI:001738*
+ ID_OUI_FROM_DATABASE=International Business Machines
+
+OUI:001739*
+ ID_OUI_FROM_DATABASE=Bright Headphone Electronics Company
+
+OUI:00173A*
+ ID_OUI_FROM_DATABASE=Reach Systems Inc.
+
+OUI:00173B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc.
+
+OUI:00173C*
+ ID_OUI_FROM_DATABASE=Extreme Engineering Solutions
+
+OUI:00173D*
+ ID_OUI_FROM_DATABASE=Neology
+
+OUI:00173E*
+ ID_OUI_FROM_DATABASE=LeucotronEquipamentos Ltda.
+
+OUI:00173F*
+ ID_OUI_FROM_DATABASE=Belkin Corporation
+
+OUI:001740*
+ ID_OUI_FROM_DATABASE=Bluberi Gaming Technologies Inc
+
+OUI:001741*
+ ID_OUI_FROM_DATABASE=DEFIDEV
+
+OUI:001742*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+
+OUI:001743*
+ ID_OUI_FROM_DATABASE=Deck Srl
+
+OUI:001744*
+ ID_OUI_FROM_DATABASE=Araneo Ltd.
+
+OUI:001745*
+ ID_OUI_FROM_DATABASE=INNOTZ CO., Ltd
+
+OUI:001746*
+ ID_OUI_FROM_DATABASE=Freedom9 Inc.
+
+OUI:001747*
+ ID_OUI_FROM_DATABASE=Trimble
+
+OUI:001748*
+ ID_OUI_FROM_DATABASE=Neokoros Brasil Ltda
+
+OUI:001749*
+ ID_OUI_FROM_DATABASE=HYUNDAE YONG-O-SA CO.,LTD
+
+OUI:00174A*
+ ID_OUI_FROM_DATABASE=SOCOMEC
+
+OUI:00174B*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00174C*
+ ID_OUI_FROM_DATABASE=Millipore
+
+OUI:00174D*
+ ID_OUI_FROM_DATABASE=DYNAMIC NETWORK FACTORY, INC.
+
+OUI:00174E*
+ ID_OUI_FROM_DATABASE=Parama-tech Co.,Ltd.
+
+OUI:00174F*
+ ID_OUI_FROM_DATABASE=iCatch Inc.
+
+OUI:001750*
+ ID_OUI_FROM_DATABASE=GSI Group, MicroE Systems
+
+OUI:001751*
+ ID_OUI_FROM_DATABASE=Online Corporation
+
+OUI:001752*
+ ID_OUI_FROM_DATABASE=DAGS, Inc
+
+OUI:001753*
+ ID_OUI_FROM_DATABASE=nFore Technology Inc.
+
+OUI:001754*
+ ID_OUI_FROM_DATABASE=Arkino HiTOP Corporation Limited
+
+OUI:001755*
+ ID_OUI_FROM_DATABASE=GE Security
+
+OUI:001756*
+ ID_OUI_FROM_DATABASE=Vinci Labs Oy
+
+OUI:001757*
+ ID_OUI_FROM_DATABASE=RIX TECHNOLOGY LIMITED
+
+OUI:001758*
+ ID_OUI_FROM_DATABASE=ThruVision Ltd
+
+OUI:001759*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00175A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00175B*
+ ID_OUI_FROM_DATABASE=ACS Solutions Switzerland Ltd.
+
+OUI:00175C*
+ ID_OUI_FROM_DATABASE=SHARP CORPORATION
+
+OUI:00175D*
+ ID_OUI_FROM_DATABASE=Dongseo system.
+
+OUI:00175E*
+ ID_OUI_FROM_DATABASE=Zed-3
+
+OUI:00175F*
+ ID_OUI_FROM_DATABASE=XENOLINK Communications Co., Ltd.
+
+OUI:001760*
+ ID_OUI_FROM_DATABASE=Naito Densei Machida MFG.CO.,LTD
+
+OUI:001761*
+ ID_OUI_FROM_DATABASE=ZKSoftware Inc.
+
+OUI:001762*
+ ID_OUI_FROM_DATABASE=Solar Technology, Inc.
+
+OUI:001763*
+ ID_OUI_FROM_DATABASE=Essentia S.p.A.
+
+OUI:001764*
+ ID_OUI_FROM_DATABASE=ATMedia GmbH
+
+OUI:001765*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001766*
+ ID_OUI_FROM_DATABASE=Accense Technology, Inc.
+
+OUI:001767*
+ ID_OUI_FROM_DATABASE=Earforce AS
+
+OUI:001768*
+ ID_OUI_FROM_DATABASE=Zinwave Ltd
+
+OUI:001769*
+ ID_OUI_FROM_DATABASE=Cymphonix Corp
+
+OUI:00176A*
+ ID_OUI_FROM_DATABASE=Avago Technologies
+
+OUI:00176B*
+ ID_OUI_FROM_DATABASE=Kiyon, Inc.
+
+OUI:00176C*
+ ID_OUI_FROM_DATABASE=Pivot3, Inc.
+
+OUI:00176D*
+ ID_OUI_FROM_DATABASE=CORE CORPORATION
+
+OUI:00176E*
+ ID_OUI_FROM_DATABASE=DUCATI SISTEMI
+
+OUI:00176F*
+ ID_OUI_FROM_DATABASE=PAX Computer Technology(Shenzhen) Ltd.
+
+OUI:001770*
+ ID_OUI_FROM_DATABASE=Arti Industrial Electronics Ltd.
+
+OUI:001771*
+ ID_OUI_FROM_DATABASE=APD Communications Ltd
+
+OUI:001772*
+ ID_OUI_FROM_DATABASE=ASTRO Strobel Kommunikationssysteme GmbH
+
+OUI:001773*
+ ID_OUI_FROM_DATABASE=Laketune Technologies Co. Ltd
+
+OUI:001774*
+ ID_OUI_FROM_DATABASE=Elesta GmbH
+
+OUI:001775*
+ ID_OUI_FROM_DATABASE=TTE Germany GmbH
+
+OUI:001776*
+ ID_OUI_FROM_DATABASE=Meso Scale Diagnostics, LLC
+
+OUI:001777*
+ ID_OUI_FROM_DATABASE=Obsidian Research Corporation
+
+OUI:001778*
+ ID_OUI_FROM_DATABASE=Central Music Co.
+
+OUI:001779*
+ ID_OUI_FROM_DATABASE=QuickTel
+
+OUI:00177A*
+ ID_OUI_FROM_DATABASE=ASSA ABLOY AB
+
+OUI:00177B*
+ ID_OUI_FROM_DATABASE=Azalea Networks inc
+
+OUI:00177C*
+ ID_OUI_FROM_DATABASE=Smartlink Network Systems Limited
+
+OUI:00177D*
+ ID_OUI_FROM_DATABASE=IDT International Limited
+
+OUI:00177E*
+ ID_OUI_FROM_DATABASE=Meshcom Technologies Inc.
+
+OUI:00177F*
+ ID_OUI_FROM_DATABASE=Worldsmart Retech
+
+OUI:001780*
+ ID_OUI_FROM_DATABASE=Applied Biosystems B.V.
+
+OUI:001781*
+ ID_OUI_FROM_DATABASE=Greystone Data System, Inc.
+
+OUI:001782*
+ ID_OUI_FROM_DATABASE=LoBenn Inc.
+
+OUI:001783*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001784*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001785*
+ ID_OUI_FROM_DATABASE=Sparr Electronics Ltd
+
+OUI:001786*
+ ID_OUI_FROM_DATABASE=wisembed
+
+OUI:001787*
+ ID_OUI_FROM_DATABASE=Brother, Brother & Sons ApS
+
+OUI:001788*
+ ID_OUI_FROM_DATABASE=Philips Lighting BV
+
+OUI:001789*
+ ID_OUI_FROM_DATABASE=Zenitron Corporation
+
+OUI:00178A*
+ ID_OUI_FROM_DATABASE=DARTS TECHNOLOGIES CORP.
+
+OUI:00178B*
+ ID_OUI_FROM_DATABASE=Teledyne Technologies Incorporated
+
+OUI:00178C*
+ ID_OUI_FROM_DATABASE=Independent Witness, Inc
+
+OUI:00178D*
+ ID_OUI_FROM_DATABASE=Checkpoint Systems, Inc.
+
+OUI:00178E*
+ ID_OUI_FROM_DATABASE=Gunnebo Cash Automation AB
+
+OUI:00178F*
+ ID_OUI_FROM_DATABASE=NINGBO YIDONG ELECTRONIC CO.,LTD.
+
+OUI:001790*
+ ID_OUI_FROM_DATABASE=HYUNDAI DIGITECH Co, Ltd.
+
+OUI:001791*
+ ID_OUI_FROM_DATABASE=LinTech GmbH
+
+OUI:001792*
+ ID_OUI_FROM_DATABASE=Falcom Wireless Comunications Gmbh
+
+OUI:001793*
+ ID_OUI_FROM_DATABASE=Tigi Corporation
+
+OUI:001794*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001795*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001796*
+ ID_OUI_FROM_DATABASE=Rittmeyer AG
+
+OUI:001797*
+ ID_OUI_FROM_DATABASE=Telsy Elettronica S.p.A.
+
+OUI:001798*
+ ID_OUI_FROM_DATABASE=Azonic Technology Co., LTD
+
+OUI:001799*
+ ID_OUI_FROM_DATABASE=SmarTire Systems Inc.
+
+OUI:00179A*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:00179B*
+ ID_OUI_FROM_DATABASE=Chant Sincere CO., LTD.
+
+OUI:00179C*
+ ID_OUI_FROM_DATABASE=DEPRAG SCHULZ GMBH u. CO.
+
+OUI:00179D*
+ ID_OUI_FROM_DATABASE=Kelman Limited
+
+OUI:00179E*
+ ID_OUI_FROM_DATABASE=Sirit Inc
+
+OUI:00179F*
+ ID_OUI_FROM_DATABASE=Apricorn
+
+OUI:0017A0*
+ ID_OUI_FROM_DATABASE=RoboTech srl
+
+OUI:0017A1*
+ ID_OUI_FROM_DATABASE=3soft inc.
+
+OUI:0017A2*
+ ID_OUI_FROM_DATABASE=Camrivox Ltd.
+
+OUI:0017A3*
+ ID_OUI_FROM_DATABASE=MIX s.r.l.
+
+OUI:0017A4*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0017A5*
+ ID_OUI_FROM_DATABASE=Ralink Technology Corp
+
+OUI:0017A6*
+ ID_OUI_FROM_DATABASE=YOSIN ELECTRONICS CO., LTD.
+
+OUI:0017A7*
+ ID_OUI_FROM_DATABASE=Mobile Computing Promotion Consortium
+
+OUI:0017A8*
+ ID_OUI_FROM_DATABASE=EDM Corporation
+
+OUI:0017A9*
+ ID_OUI_FROM_DATABASE=Sentivision
+
+OUI:0017AA*
+ ID_OUI_FROM_DATABASE=elab-experience inc.
+
+OUI:0017AB*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:0017AC*
+ ID_OUI_FROM_DATABASE=O'Neil Product Development Inc.
+
+OUI:0017AD*
+ ID_OUI_FROM_DATABASE=AceNet Corporation
+
+OUI:0017AE*
+ ID_OUI_FROM_DATABASE=GAI-Tronics
+
+OUI:0017AF*
+ ID_OUI_FROM_DATABASE=Enermet
+
+OUI:0017B0*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0017B1*
+ ID_OUI_FROM_DATABASE=ACIST Medical Systems, Inc.
+
+OUI:0017B2*
+ ID_OUI_FROM_DATABASE=SK Telesys
+
+OUI:0017B3*
+ ID_OUI_FROM_DATABASE=Aftek Infosys Limited
+
+OUI:0017B4*
+ ID_OUI_FROM_DATABASE=Remote Security Systems, LLC
+
+OUI:0017B5*
+ ID_OUI_FROM_DATABASE=Peerless Systems Corporation
+
+OUI:0017B6*
+ ID_OUI_FROM_DATABASE=Aquantia
+
+OUI:0017B7*
+ ID_OUI_FROM_DATABASE=Tonze Technology Co.
+
+OUI:0017B8*
+ ID_OUI_FROM_DATABASE=NOVATRON CO., LTD.
+
+OUI:0017B9*
+ ID_OUI_FROM_DATABASE=Gambro Lundia AB
+
+OUI:0017BA*
+ ID_OUI_FROM_DATABASE=SEDO CO., LTD.
+
+OUI:0017BB*
+ ID_OUI_FROM_DATABASE=Syrinx Industrial Electronics
+
+OUI:0017BC*
+ ID_OUI_FROM_DATABASE=Touchtunes Music Corporation
+
+OUI:0017BD*
+ ID_OUI_FROM_DATABASE=Tibetsystem
+
+OUI:0017BE*
+ ID_OUI_FROM_DATABASE=Tratec Telecom B.V.
+
+OUI:0017BF*
+ ID_OUI_FROM_DATABASE=Coherent Research Limited
+
+OUI:0017C0*
+ ID_OUI_FROM_DATABASE=PureTech Systems, Inc.
+
+OUI:0017C1*
+ ID_OUI_FROM_DATABASE=CM Precision Technology LTD.
+
+OUI:0017C2*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:0017C3*
+ ID_OUI_FROM_DATABASE=KTF Technologies Inc.
+
+OUI:0017C4*
+ ID_OUI_FROM_DATABASE=Quanta Microsystems, INC.
+
+OUI:0017C5*
+ ID_OUI_FROM_DATABASE=SonicWALL
+
+OUI:0017C6*
+ ID_OUI_FROM_DATABASE=Cross Match Technologies Inc
+
+OUI:0017C7*
+ ID_OUI_FROM_DATABASE=MARA Systems Consulting AB
+
+OUI:0017C8*
+ ID_OUI_FROM_DATABASE=Kyocera Mita Corporation
+
+OUI:0017C9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+OUI:0017CA*
+ ID_OUI_FROM_DATABASE=Qisda Corporation
+
+OUI:0017CB*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:0017CC*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:0017CD*
+ ID_OUI_FROM_DATABASE=CEC Wireless R&D Ltd.
+
+OUI:0017CE*
+ ID_OUI_FROM_DATABASE=Screen Service Spa
+
+OUI:0017CF*
+ ID_OUI_FROM_DATABASE=iMCA-GmbH
+
+OUI:0017D0*
+ ID_OUI_FROM_DATABASE=Opticom Communications, LLC
+
+OUI:0017D1*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:0017D2*
+ ID_OUI_FROM_DATABASE=THINLINX PTY LTD
+
+OUI:0017D3*
+ ID_OUI_FROM_DATABASE=Etymotic Research, Inc.
+
+OUI:0017D4*
+ ID_OUI_FROM_DATABASE=Monsoon Multimedia, Inc
+
+OUI:0017D5*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+OUI:0017D6*
+ ID_OUI_FROM_DATABASE=Bluechips Microhouse Co.,Ltd.
+
+OUI:0017D7*
+ ID_OUI_FROM_DATABASE=ION Geophysical Corporation Inc.
+
+OUI:0017D8*
+ ID_OUI_FROM_DATABASE=Magnum Semiconductor, Inc.
+
+OUI:0017D9*
+ ID_OUI_FROM_DATABASE=AAI Corporation
+
+OUI:0017DA*
+ ID_OUI_FROM_DATABASE=Spans Logic
+
+OUI:0017DB*
+ ID_OUI_FROM_DATABASE=CANKO TECHNOLOGIES INC.
+
+OUI:0017DC*
+ ID_OUI_FROM_DATABASE=DAEMYUNG ZERO1
+
+OUI:0017DD*
+ ID_OUI_FROM_DATABASE=Clipsal Australia
+
+OUI:0017DE*
+ ID_OUI_FROM_DATABASE=Advantage Six Ltd
+
+OUI:0017DF*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0017E0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0017E1*
+ ID_OUI_FROM_DATABASE=DACOS Technologies Co., Ltd.
+
+OUI:0017E2*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0017E3*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E6*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E7*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017E9*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017EA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017EB*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017EC*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0017ED*
+ ID_OUI_FROM_DATABASE=WooJooIT Ltd.
+
+OUI:0017EE*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0017EF*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:0017F0*
+ ID_OUI_FROM_DATABASE=SZCOM Broadband Network Technology Co.,Ltd
+
+OUI:0017F1*
+ ID_OUI_FROM_DATABASE=Renu Electronics Pvt Ltd
+
+OUI:0017F2*
+ ID_OUI_FROM_DATABASE=Apple Computer
+
+OUI:0017F3*
+ ID_OUI_FROM_DATABASE=Harris Corparation
+
+OUI:0017F4*
+ ID_OUI_FROM_DATABASE=ZERON ALLIANCE
+
+OUI:0017F5*
+ ID_OUI_FROM_DATABASE=LIG NEOPTEK
+
+OUI:0017F6*
+ ID_OUI_FROM_DATABASE=Pyramid Meriden Inc.
+
+OUI:0017F7*
+ ID_OUI_FROM_DATABASE=CEM Solutions Pvt Ltd
+
+OUI:0017F8*
+ ID_OUI_FROM_DATABASE=Motech Industries Inc.
+
+OUI:0017F9*
+ ID_OUI_FROM_DATABASE=Forcom Sp. z o.o.
+
+OUI:0017FA*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:0017FB*
+ ID_OUI_FROM_DATABASE=FA
+
+OUI:0017FC*
+ ID_OUI_FROM_DATABASE=Suprema Inc.
+
+OUI:0017FD*
+ ID_OUI_FROM_DATABASE=Amulet Hotkey
+
+OUI:0017FE*
+ ID_OUI_FROM_DATABASE=TALOS SYSTEM INC.
+
+OUI:0017FF*
+ ID_OUI_FROM_DATABASE=PLAYLINE Co.,Ltd.
+
+OUI:001800*
+ ID_OUI_FROM_DATABASE=UNIGRAND LTD
+
+OUI:001801*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:001802*
+ ID_OUI_FROM_DATABASE=Alpha Networks Inc.
+
+OUI:001803*
+ ID_OUI_FROM_DATABASE=ArcSoft Shanghai Co. LTD
+
+OUI:001804*
+ ID_OUI_FROM_DATABASE=E-TEK DIGITAL TECHNOLOGY LIMITED
+
+OUI:001805*
+ ID_OUI_FROM_DATABASE=Beijing InHand Networking Technology Co.,Ltd.
+
+OUI:001806*
+ ID_OUI_FROM_DATABASE=Hokkei Industries Co., Ltd.
+
+OUI:001807*
+ ID_OUI_FROM_DATABASE=Fanstel Corp.
+
+OUI:001808*
+ ID_OUI_FROM_DATABASE=SightLogix, Inc.
+
+OUI:001809*
+ ID_OUI_FROM_DATABASE=CRESYN
+
+OUI:00180A*
+ ID_OUI_FROM_DATABASE=Meraki, Inc.
+
+OUI:00180B*
+ ID_OUI_FROM_DATABASE=Brilliant Telecommunications
+
+OUI:00180C*
+ ID_OUI_FROM_DATABASE=Optelian Access Networks
+
+OUI:00180D*
+ ID_OUI_FROM_DATABASE=Terabytes Server Storage Tech Corp
+
+OUI:00180E*
+ ID_OUI_FROM_DATABASE=Avega Systems
+
+OUI:00180F*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001810*
+ ID_OUI_FROM_DATABASE=IPTrade S.A.
+
+OUI:001811*
+ ID_OUI_FROM_DATABASE=Neuros Technology International, LLC.
+
+OUI:001812*
+ ID_OUI_FROM_DATABASE=Beijing Xinwei Telecom Technology Co., Ltd.
+
+OUI:001813*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:001814*
+ ID_OUI_FROM_DATABASE=Mitutoyo Corporation
+
+OUI:001815*
+ ID_OUI_FROM_DATABASE=GZ Technologies, Inc.
+
+OUI:001816*
+ ID_OUI_FROM_DATABASE=Ubixon Co., Ltd.
+
+OUI:001817*
+ ID_OUI_FROM_DATABASE=D. E. Shaw Research, LLC
+
+OUI:001818*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001819*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00181A*
+ ID_OUI_FROM_DATABASE=AVerMedia Information Inc.
+
+OUI:00181B*
+ ID_OUI_FROM_DATABASE=TaiJin Metal Co., Ltd.
+
+OUI:00181C*
+ ID_OUI_FROM_DATABASE=Exterity Limited
+
+OUI:00181D*
+ ID_OUI_FROM_DATABASE=ASIA ELECTRONICS CO.,LTD
+
+OUI:00181E*
+ ID_OUI_FROM_DATABASE=GDX Technologies Ltd.
+
+OUI:00181F*
+ ID_OUI_FROM_DATABASE=Palmmicro Communications
+
+OUI:001820*
+ ID_OUI_FROM_DATABASE=w5networks
+
+OUI:001821*
+ ID_OUI_FROM_DATABASE=SINDORICOH
+
+OUI:001822*
+ ID_OUI_FROM_DATABASE=CEC TELECOM CO.,LTD.
+
+OUI:001823*
+ ID_OUI_FROM_DATABASE=Delta Electronics, Inc.
+
+OUI:001824*
+ ID_OUI_FROM_DATABASE=Kimaldi Electronics, S.L.
+
+OUI:001826*
+ ID_OUI_FROM_DATABASE=Cale Access AB
+
+OUI:001827*
+ ID_OUI_FROM_DATABASE=NEC UNIFIED SOLUTIONS NEDERLAND B.V.
+
+OUI:001828*
+ ID_OUI_FROM_DATABASE=e2v technologies (UK) ltd.
+
+OUI:001829*
+ ID_OUI_FROM_DATABASE=Gatsometer
+
+OUI:00182A*
+ ID_OUI_FROM_DATABASE=Taiwan Video & Monitor
+
+OUI:00182B*
+ ID_OUI_FROM_DATABASE=Softier
+
+OUI:00182C*
+ ID_OUI_FROM_DATABASE=Ascend Networks, Inc.
+
+OUI:00182D*
+ ID_OUI_FROM_DATABASE=Artec Group OÜ
+
+OUI:00182E*
+ ID_OUI_FROM_DATABASE=XStreamHD, LLC
+
+OUI:00182F*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001830*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001831*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001832*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001833*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001834*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001835*
+ ID_OUI_FROM_DATABASE=Thoratec / ITC
+
+OUI:001836*
+ ID_OUI_FROM_DATABASE=Reliance Electric Limited
+
+OUI:001837*
+ ID_OUI_FROM_DATABASE=Universal ABIT Co., Ltd.
+
+OUI:001838*
+ ID_OUI_FROM_DATABASE=PanAccess Communications,Inc.
+
+OUI:001839*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys LLC
+
+OUI:00183A*
+ ID_OUI_FROM_DATABASE=Westell Technologies
+
+OUI:00183B*
+ ID_OUI_FROM_DATABASE=CENITS Co., Ltd.
+
+OUI:00183C*
+ ID_OUI_FROM_DATABASE=Encore Software Limited
+
+OUI:00183D*
+ ID_OUI_FROM_DATABASE=Vertex Link Corporation
+
+OUI:00183E*
+ ID_OUI_FROM_DATABASE=Digilent, Inc
+
+OUI:00183F*
+ ID_OUI_FROM_DATABASE=2Wire, Inc
+
+OUI:001840*
+ ID_OUI_FROM_DATABASE=3 Phoenix, Inc.
+
+OUI:001841*
+ ID_OUI_FROM_DATABASE=High Tech Computer Corp
+
+OUI:001842*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001843*
+ ID_OUI_FROM_DATABASE=Dawevision Ltd
+
+OUI:001844*
+ ID_OUI_FROM_DATABASE=Heads Up Technologies, Inc.
+
+OUI:001845*
+ ID_OUI_FROM_DATABASE=NPL Pulsar Ltd.
+
+OUI:001846*
+ ID_OUI_FROM_DATABASE=Crypto S.A.
+
+OUI:001847*
+ ID_OUI_FROM_DATABASE=AceNet Technology Inc.
+
+OUI:001848*
+ ID_OUI_FROM_DATABASE=Vecima Networks Inc.
+
+OUI:001849*
+ ID_OUI_FROM_DATABASE=Pigeon Point Systems
+
+OUI:00184A*
+ ID_OUI_FROM_DATABASE=Catcher, Inc.
+
+OUI:00184B*
+ ID_OUI_FROM_DATABASE=Las Vegas Gaming, Inc.
+
+OUI:00184C*
+ ID_OUI_FROM_DATABASE=Bogen Communications
+
+OUI:00184D*
+ ID_OUI_FROM_DATABASE=Netgear Inc.
+
+OUI:00184E*
+ ID_OUI_FROM_DATABASE=Lianhe Technologies, Inc.
+
+OUI:00184F*
+ ID_OUI_FROM_DATABASE=8 Ways Technology Corp.
+
+OUI:001850*
+ ID_OUI_FROM_DATABASE=Secfone Kft
+
+OUI:001851*
+ ID_OUI_FROM_DATABASE=SWsoft
+
+OUI:001852*
+ ID_OUI_FROM_DATABASE=StorLink Semiconductors, Inc.
+
+OUI:001853*
+ ID_OUI_FROM_DATABASE=Atera Networks LTD.
+
+OUI:001854*
+ ID_OUI_FROM_DATABASE=Argard Co., Ltd
+
+OUI:001855*
+ ID_OUI_FROM_DATABASE=Aeromaritime Systembau GmbH
+
+OUI:001856*
+ ID_OUI_FROM_DATABASE=EyeFi, Inc
+
+OUI:001857*
+ ID_OUI_FROM_DATABASE=Unilever R&D
+
+OUI:001858*
+ ID_OUI_FROM_DATABASE=TagMaster AB
+
+OUI:001859*
+ ID_OUI_FROM_DATABASE=Strawberry Linux Co.,Ltd.
+
+OUI:00185A*
+ ID_OUI_FROM_DATABASE=uControl, Inc.
+
+OUI:00185B*
+ ID_OUI_FROM_DATABASE=Network Chemistry, Inc
+
+OUI:00185C*
+ ID_OUI_FROM_DATABASE=EDS Lab Pte Ltd
+
+OUI:00185D*
+ ID_OUI_FROM_DATABASE=TAIGUEN TECHNOLOGY (SHEN-ZHEN) CO., LTD.
+
+OUI:00185E*
+ ID_OUI_FROM_DATABASE=Nexterm Inc.
+
+OUI:00185F*
+ ID_OUI_FROM_DATABASE=TAC Inc.
+
+OUI:001860*
+ ID_OUI_FROM_DATABASE=SIM Technology Group Shanghai Simcom Ltd.,
+
+OUI:001861*
+ ID_OUI_FROM_DATABASE=Ooma, Inc.
+
+OUI:001862*
+ ID_OUI_FROM_DATABASE=Seagate Technology
+
+OUI:001863*
+ ID_OUI_FROM_DATABASE=Veritech Electronics Limited
+
+OUI:001864*
+ ID_OUI_FROM_DATABASE=Cybectec Inc.
+
+OUI:001865*
+ ID_OUI_FROM_DATABASE=Siemens Healthcare Diagnostics Manufacturing Ltd
+
+OUI:001866*
+ ID_OUI_FROM_DATABASE=Leutron Vision
+
+OUI:001867*
+ ID_OUI_FROM_DATABASE=Evolution Robotics Retail
+
+OUI:001868*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta, A Cisco Company
+
+OUI:001869*
+ ID_OUI_FROM_DATABASE=KINGJIM
+
+OUI:00186A*
+ ID_OUI_FROM_DATABASE=Global Link Digital Technology Co,.LTD
+
+OUI:00186B*
+ ID_OUI_FROM_DATABASE=Sambu Communics CO., LTD.
+
+OUI:00186C*
+ ID_OUI_FROM_DATABASE=Neonode AB
+
+OUI:00186D*
+ ID_OUI_FROM_DATABASE=Zhenjiang Sapphire Electronic Industry CO.
+
+OUI:00186E*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:00186F*
+ ID_OUI_FROM_DATABASE=Setha Industria Eletronica LTDA
+
+OUI:001870*
+ ID_OUI_FROM_DATABASE=E28 Shanghai Limited
+
+OUI:001871*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001872*
+ ID_OUI_FROM_DATABASE=Expertise Engineering
+
+OUI:001873*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001874*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001875*
+ ID_OUI_FROM_DATABASE=AnaCise Testnology Pte Ltd
+
+OUI:001876*
+ ID_OUI_FROM_DATABASE=WowWee Ltd.
+
+OUI:001877*
+ ID_OUI_FROM_DATABASE=Amplex A/S
+
+OUI:001878*
+ ID_OUI_FROM_DATABASE=Mackware GmbH
+
+OUI:001879*
+ ID_OUI_FROM_DATABASE=dSys
+
+OUI:00187A*
+ ID_OUI_FROM_DATABASE=Wiremold
+
+OUI:00187B*
+ ID_OUI_FROM_DATABASE=4NSYS Co. Ltd.
+
+OUI:00187C*
+ ID_OUI_FROM_DATABASE=INTERCROSS, LLC
+
+OUI:00187D*
+ ID_OUI_FROM_DATABASE=Armorlink shanghai Co. Ltd
+
+OUI:00187E*
+ ID_OUI_FROM_DATABASE=RGB Spectrum
+
+OUI:00187F*
+ ID_OUI_FROM_DATABASE=ZODIANET
+
+OUI:001880*
+ ID_OUI_FROM_DATABASE=Maxim Integrated Products
+
+OUI:001881*
+ ID_OUI_FROM_DATABASE=Buyang Electronics Industrial Co., Ltd
+
+OUI:001882*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd.
+
+OUI:001883*
+ ID_OUI_FROM_DATABASE=FORMOSA21 INC.
+
+OUI:001884*
+ ID_OUI_FROM_DATABASE=Fon Technology S.L.
+
+OUI:001885*
+ ID_OUI_FROM_DATABASE=Avigilon Corporation
+
+OUI:001886*
+ ID_OUI_FROM_DATABASE=EL-TECH, INC.
+
+OUI:001887*
+ ID_OUI_FROM_DATABASE=Metasystem SpA
+
+OUI:001888*
+ ID_OUI_FROM_DATABASE=GOTIVE a.s.
+
+OUI:001889*
+ ID_OUI_FROM_DATABASE=WinNet Solutions Limited
+
+OUI:00188A*
+ ID_OUI_FROM_DATABASE=Infinova LLC
+
+OUI:00188B*
+ ID_OUI_FROM_DATABASE=Dell
+
+OUI:00188C*
+ ID_OUI_FROM_DATABASE=Mobile Action Technology Inc.
+
+OUI:00188D*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00188E*
+ ID_OUI_FROM_DATABASE=Ekahau, Inc.
+
+OUI:00188F*
+ ID_OUI_FROM_DATABASE=Montgomery Technology, Inc.
+
+OUI:001890*
+ ID_OUI_FROM_DATABASE=RadioCOM, s.r.o.
+
+OUI:001891*
+ ID_OUI_FROM_DATABASE=Zhongshan General K-mate Electronics Co., Ltd
+
+OUI:001892*
+ ID_OUI_FROM_DATABASE=ads-tec GmbH
+
+OUI:001893*
+ ID_OUI_FROM_DATABASE=SHENZHEN PHOTON BROADBAND TECHNOLOGY CO.,LTD
+
+OUI:001894*
+ ID_OUI_FROM_DATABASE=zimocom
+
+OUI:001895*
+ ID_OUI_FROM_DATABASE=Hansun Technologies Inc.
+
+OUI:001896*
+ ID_OUI_FROM_DATABASE=Great Well Electronic LTD
+
+OUI:001897*
+ ID_OUI_FROM_DATABASE=JESS-LINK PRODUCTS Co., LTD
+
+OUI:001898*
+ ID_OUI_FROM_DATABASE=KINGSTATE ELECTRONICS CORPORATION
+
+OUI:001899*
+ ID_OUI_FROM_DATABASE=ShenZhen jieshun Science&Technology Industry CO,LTD.
+
+OUI:00189A*
+ ID_OUI_FROM_DATABASE=HANA Micron Inc.
+
+OUI:00189B*
+ ID_OUI_FROM_DATABASE=Thomson Inc.
+
+OUI:00189C*
+ ID_OUI_FROM_DATABASE=Weldex Corporation
+
+OUI:00189D*
+ ID_OUI_FROM_DATABASE=Navcast Inc.
+
+OUI:00189E*
+ ID_OUI_FROM_DATABASE=OMNIKEY GmbH.
+
+OUI:00189F*
+ ID_OUI_FROM_DATABASE=Lenntek Corporation
+
+OUI:0018A0*
+ ID_OUI_FROM_DATABASE=Cierma Ascenseurs
+
+OUI:0018A1*
+ ID_OUI_FROM_DATABASE=Tiqit Computers, Inc.
+
+OUI:0018A2*
+ ID_OUI_FROM_DATABASE=XIP Technology AB
+
+OUI:0018A3*
+ ID_OUI_FROM_DATABASE=ZIPPY TECHNOLOGY CORP.
+
+OUI:0018A4*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0018A5*
+ ID_OUI_FROM_DATABASE=ADigit Technologies Corp.
+
+OUI:0018A6*
+ ID_OUI_FROM_DATABASE=Persistent Systems, LLC
+
+OUI:0018A7*
+ ID_OUI_FROM_DATABASE=Yoggie Security Systems LTD.
+
+OUI:0018A8*
+ ID_OUI_FROM_DATABASE=AnNeal Technology Inc.
+
+OUI:0018A9*
+ ID_OUI_FROM_DATABASE=Ethernet Direct Corporation
+
+OUI:0018AA*
+ ID_OUI_FROM_DATABASE=Protec Fire Detection plc
+
+OUI:0018AB*
+ ID_OUI_FROM_DATABASE=BEIJING LHWT MICROELECTRONICS INC.
+
+OUI:0018AC*
+ ID_OUI_FROM_DATABASE=Shanghai Jiao Da HISYS Technology Co. Ltd.
+
+OUI:0018AD*
+ ID_OUI_FROM_DATABASE=NIDEC SANKYO CORPORATION
+
+OUI:0018AE*
+ ID_OUI_FROM_DATABASE=TVT CO.,LTD
+
+OUI:0018AF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+OUI:0018B0*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:0018B1*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:0018B2*
+ ID_OUI_FROM_DATABASE=ADEUNIS RF
+
+OUI:0018B3*
+ ID_OUI_FROM_DATABASE=TEC WizHome Co., Ltd.
+
+OUI:0018B4*
+ ID_OUI_FROM_DATABASE=Dawon Media Inc.
+
+OUI:0018B5*
+ ID_OUI_FROM_DATABASE=Magna Carta
+
+OUI:0018B6*
+ ID_OUI_FROM_DATABASE=S3C, Inc.
+
+OUI:0018B7*
+ ID_OUI_FROM_DATABASE=D3 LED, LLC
+
+OUI:0018B8*
+ ID_OUI_FROM_DATABASE=New Voice International AG
+
+OUI:0018B9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0018BA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0018BB*
+ ID_OUI_FROM_DATABASE=Eliwell Controls srl
+
+OUI:0018BC*
+ ID_OUI_FROM_DATABASE=ZAO NVP Bolid
+
+OUI:0018BD*
+ ID_OUI_FROM_DATABASE=SHENZHEN DVBWORLD TECHNOLOGY CO., LTD.
+
+OUI:0018BE*
+ ID_OUI_FROM_DATABASE=ANSA Corporation
+
+OUI:0018BF*
+ ID_OUI_FROM_DATABASE=Essence Technology Solution, Inc.
+
+OUI:0018C0*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0018C1*
+ ID_OUI_FROM_DATABASE=Almitec Informática e Comércio
+
+OUI:0018C2*
+ ID_OUI_FROM_DATABASE=Firetide, Inc
+
+OUI:0018C3*
+ ID_OUI_FROM_DATABASE=CS Corporation
+
+OUI:0018C4*
+ ID_OUI_FROM_DATABASE=Raba Technologies LLC
+
+OUI:0018C5*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0018C6*
+ ID_OUI_FROM_DATABASE=OPW Fuel Management Systems
+
+OUI:0018C7*
+ ID_OUI_FROM_DATABASE=Real Time Automation
+
+OUI:0018C8*
+ ID_OUI_FROM_DATABASE=ISONAS Inc.
+
+OUI:0018C9*
+ ID_OUI_FROM_DATABASE=EOps Technology Limited
+
+OUI:0018CA*
+ ID_OUI_FROM_DATABASE=Viprinet GmbH
+
+OUI:0018CB*
+ ID_OUI_FROM_DATABASE=Tecobest Technology Limited
+
+OUI:0018CC*
+ ID_OUI_FROM_DATABASE=AXIOHM SAS
+
+OUI:0018CD*
+ ID_OUI_FROM_DATABASE=Erae Electronics Industry Co., Ltd
+
+OUI:0018CE*
+ ID_OUI_FROM_DATABASE=Dreamtech Co., Ltd
+
+OUI:0018CF*
+ ID_OUI_FROM_DATABASE=Baldor Electric Company
+
+OUI:0018D0*
+ ID_OUI_FROM_DATABASE=AtRoad,  A Trimble Company
+
+OUI:0018D1*
+ ID_OUI_FROM_DATABASE=Siemens Home & Office Comm. Devices
+
+OUI:0018D2*
+ ID_OUI_FROM_DATABASE=High-Gain Antennas LLC
+
+OUI:0018D3*
+ ID_OUI_FROM_DATABASE=TEAMCAST
+
+OUI:0018D4*
+ ID_OUI_FROM_DATABASE=Unified Display Interface SIG
+
+OUI:0018D5*
+ ID_OUI_FROM_DATABASE=REIGNCOM
+
+OUI:0018D6*
+ ID_OUI_FROM_DATABASE=Swirlnet A/S
+
+OUI:0018D7*
+ ID_OUI_FROM_DATABASE=Javad Navigation Systems Inc.
+
+OUI:0018D8*
+ ID_OUI_FROM_DATABASE=ARCH METER Corporation
+
+OUI:0018D9*
+ ID_OUI_FROM_DATABASE=Santosha Internatonal, Inc
+
+OUI:0018DA*
+ ID_OUI_FROM_DATABASE=AMBER wireless GmbH
+
+OUI:0018DB*
+ ID_OUI_FROM_DATABASE=EPL Technology Ltd
+
+OUI:0018DC*
+ ID_OUI_FROM_DATABASE=Prostar Co., Ltd.
+
+OUI:0018DD*
+ ID_OUI_FROM_DATABASE=Silicondust Engineering Ltd
+
+OUI:0018DE*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0018DF*
+ ID_OUI_FROM_DATABASE=The Morey Corporation
+
+OUI:0018E0*
+ ID_OUI_FROM_DATABASE=ANAVEO
+
+OUI:0018E1*
+ ID_OUI_FROM_DATABASE=Verkerk Service Systemen
+
+OUI:0018E2*
+ ID_OUI_FROM_DATABASE=Topdata Sistemas de Automacao Ltda
+
+OUI:0018E3*
+ ID_OUI_FROM_DATABASE=Visualgate Systems, Inc.
+
+OUI:0018E4*
+ ID_OUI_FROM_DATABASE=YIGUANG
+
+OUI:0018E5*
+ ID_OUI_FROM_DATABASE=Adhoco AG
+
+OUI:0018E6*
+ ID_OUI_FROM_DATABASE=Computer Hardware Design SIA
+
+OUI:0018E7*
+ ID_OUI_FROM_DATABASE=Cameo Communications, INC.
+
+OUI:0018E8*
+ ID_OUI_FROM_DATABASE=Hacetron Corporation
+
+OUI:0018E9*
+ ID_OUI_FROM_DATABASE=Numata Corporation
+
+OUI:0018EA*
+ ID_OUI_FROM_DATABASE=Alltec GmbH
+
+OUI:0018EB*
+ ID_OUI_FROM_DATABASE=BroVis Wireless Networks
+
+OUI:0018EC*
+ ID_OUI_FROM_DATABASE=Welding Technology Corporation
+
+OUI:0018ED*
+ ID_OUI_FROM_DATABASE=Accutech Ultrasystems Co., Ltd.
+
+OUI:0018EE*
+ ID_OUI_FROM_DATABASE=Videology Imaging Solutions, Inc.
+
+OUI:0018EF*
+ ID_OUI_FROM_DATABASE=Escape Communications, Inc.
+
+OUI:0018F0*
+ ID_OUI_FROM_DATABASE=JOYTOTO Co., Ltd.
+
+OUI:0018F1*
+ ID_OUI_FROM_DATABASE=Chunichi Denshi Co.,LTD.
+
+OUI:0018F2*
+ ID_OUI_FROM_DATABASE=Beijing Tianyu Communication Equipment Co., Ltd
+
+OUI:0018F3*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:0018F4*
+ ID_OUI_FROM_DATABASE=EO TECHNICS Co., Ltd.
+
+OUI:0018F5*
+ ID_OUI_FROM_DATABASE=Shenzhen Streaming Video Technology Company Limited
+
+OUI:0018F6*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:0018F7*
+ ID_OUI_FROM_DATABASE=Kameleon Technologies
+
+OUI:0018F8*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys LLC
+
+OUI:0018F9*
+ ID_OUI_FROM_DATABASE=VVOND, Inc.
+
+OUI:0018FA*
+ ID_OUI_FROM_DATABASE=Yushin Precision Equipment Co.,Ltd.
+
+OUI:0018FB*
+ ID_OUI_FROM_DATABASE=Compro Technology
+
+OUI:0018FC*
+ ID_OUI_FROM_DATABASE=Altec Electronic AG
+
+OUI:0018FD*
+ ID_OUI_FROM_DATABASE=Optimal Technologies International Inc.
+
+OUI:0018FE*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0018FF*
+ ID_OUI_FROM_DATABASE=PowerQuattro Co.
+
+OUI:001900*
+ ID_OUI_FROM_DATABASE=Intelliverese - DBA Voicecom
+
+OUI:001901*
+ ID_OUI_FROM_DATABASE=F1MEDIA
+
+OUI:001902*
+ ID_OUI_FROM_DATABASE=Cambridge Consultants Ltd
+
+OUI:001903*
+ ID_OUI_FROM_DATABASE=Bigfoot Networks Inc
+
+OUI:001904*
+ ID_OUI_FROM_DATABASE=WB Electronics Sp. z o.o.
+
+OUI:001905*
+ ID_OUI_FROM_DATABASE=SCHRACK Seconet AG
+
+OUI:001906*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001907*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001908*
+ ID_OUI_FROM_DATABASE=Duaxes Corporation
+
+OUI:001909*
+ ID_OUI_FROM_DATABASE=Devi A/S
+
+OUI:00190A*
+ ID_OUI_FROM_DATABASE=HASWARE INC.
+
+OUI:00190B*
+ ID_OUI_FROM_DATABASE=Southern Vision Systems, Inc.
+
+OUI:00190C*
+ ID_OUI_FROM_DATABASE=Encore Electronics, Inc.
+
+OUI:00190D*
+ ID_OUI_FROM_DATABASE=IEEE 1394c
+
+OUI:00190E*
+ ID_OUI_FROM_DATABASE=Atech Technology Co., Ltd.
+
+OUI:00190F*
+ ID_OUI_FROM_DATABASE=Advansus Corp.
+
+OUI:001910*
+ ID_OUI_FROM_DATABASE=Knick Elektronische Messgeraete GmbH & Co. KG
+
+OUI:001911*
+ ID_OUI_FROM_DATABASE=Just In Mobile Information Technologies (Shanghai) Co., Ltd.
+
+OUI:001912*
+ ID_OUI_FROM_DATABASE=Welcat Inc
+
+OUI:001913*
+ ID_OUI_FROM_DATABASE=Chuang-Yi Network Equipment Co.Ltd.
+
+OUI:001914*
+ ID_OUI_FROM_DATABASE=Winix Co., Ltd
+
+OUI:001915*
+ ID_OUI_FROM_DATABASE=TECOM Co., Ltd.
+
+OUI:001916*
+ ID_OUI_FROM_DATABASE=PayTec AG
+
+OUI:001917*
+ ID_OUI_FROM_DATABASE=Posiflex Inc.
+
+OUI:001918*
+ ID_OUI_FROM_DATABASE=Interactive Wear AG
+
+OUI:001919*
+ ID_OUI_FROM_DATABASE=ASTEL Inc.
+
+OUI:00191A*
+ ID_OUI_FROM_DATABASE=IRLINK
+
+OUI:00191B*
+ ID_OUI_FROM_DATABASE=Sputnik Engineering AG
+
+OUI:00191C*
+ ID_OUI_FROM_DATABASE=Sensicast Systems
+
+OUI:00191D*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd.
+
+OUI:00191E*
+ ID_OUI_FROM_DATABASE=Beyondwiz Co., Ltd.
+
+OUI:00191F*
+ ID_OUI_FROM_DATABASE=Microlink communications Inc.
+
+OUI:001920*
+ ID_OUI_FROM_DATABASE=KUME electric Co.,Ltd.
+
+OUI:001921*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer System Co.
+
+OUI:001922*
+ ID_OUI_FROM_DATABASE=CM Comandos Lineares
+
+OUI:001923*
+ ID_OUI_FROM_DATABASE=Phonex Korea Co., LTD.
+
+OUI:001924*
+ ID_OUI_FROM_DATABASE=LBNL  Engineering
+
+OUI:001925*
+ ID_OUI_FROM_DATABASE=Intelicis Corporation
+
+OUI:001926*
+ ID_OUI_FROM_DATABASE=BitsGen Co., Ltd.
+
+OUI:001927*
+ ID_OUI_FROM_DATABASE=ImCoSys Ltd
+
+OUI:001928*
+ ID_OUI_FROM_DATABASE=Siemens AG, Transportation Systems
+
+OUI:001929*
+ ID_OUI_FROM_DATABASE=2M2B Montadora de Maquinas Bahia Brasil LTDA
+
+OUI:00192A*
+ ID_OUI_FROM_DATABASE=Antiope Associates
+
+OUI:00192B*
+ ID_OUI_FROM_DATABASE=Aclara RF Systems Inc.
+
+OUI:00192C*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00192D*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:00192E*
+ ID_OUI_FROM_DATABASE=Spectral Instruments, Inc.
+
+OUI:00192F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001930*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001931*
+ ID_OUI_FROM_DATABASE=Balluff GmbH
+
+OUI:001932*
+ ID_OUI_FROM_DATABASE=Gude Analog- und Digialsysteme GmbH
+
+OUI:001933*
+ ID_OUI_FROM_DATABASE=Strix Systems, Inc.
+
+OUI:001934*
+ ID_OUI_FROM_DATABASE=TRENDON TOUCH TECHNOLOGY CORP.
+
+OUI:001935*
+ ID_OUI_FROM_DATABASE=Duerr Dental GmbH & Co. KG
+
+OUI:001936*
+ ID_OUI_FROM_DATABASE=STERLITE OPTICAL TECHNOLOGIES LIMITED
+
+OUI:001937*
+ ID_OUI_FROM_DATABASE=CommerceGuard AB
+
+OUI:001938*
+ ID_OUI_FROM_DATABASE=UMB Communications Co., Ltd.
+
+OUI:001939*
+ ID_OUI_FROM_DATABASE=Gigamips
+
+OUI:00193A*
+ ID_OUI_FROM_DATABASE=OESOLUTIONS
+
+OUI:00193B*
+ ID_OUI_FROM_DATABASE=Wilibox Deliberant Group LLC
+
+OUI:00193C*
+ ID_OUI_FROM_DATABASE=HighPoint Technologies Incorporated
+
+OUI:00193D*
+ ID_OUI_FROM_DATABASE=GMC Guardian Mobility Corp.
+
+OUI:00193E*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:00193F*
+ ID_OUI_FROM_DATABASE=RDI technology(Shenzhen) Co.,LTD
+
+OUI:001940*
+ ID_OUI_FROM_DATABASE=Rackable Systems
+
+OUI:001941*
+ ID_OUI_FROM_DATABASE=Pitney Bowes, Inc
+
+OUI:001942*
+ ID_OUI_FROM_DATABASE=ON SOFTWARE INTERNATIONAL LIMITED
+
+OUI:001943*
+ ID_OUI_FROM_DATABASE=Belden
+
+OUI:001944*
+ ID_OUI_FROM_DATABASE=Fossil Partners, L.P.
+
+OUI:001945*
+ ID_OUI_FROM_DATABASE=Ten-Tec Inc.
+
+OUI:001946*
+ ID_OUI_FROM_DATABASE=Cianet Industria e Comercio S/A
+
+OUI:001947*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta, A Cisco Company
+
+OUI:001948*
+ ID_OUI_FROM_DATABASE=AireSpider Networks
+
+OUI:001949*
+ ID_OUI_FROM_DATABASE=TENTEL  COMTECH CO., LTD.
+
+OUI:00194A*
+ ID_OUI_FROM_DATABASE=TESTO AG
+
+OUI:00194B*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:00194C*
+ ID_OUI_FROM_DATABASE=Fujian Stelcom information & Technology CO.,Ltd
+
+OUI:00194D*
+ ID_OUI_FROM_DATABASE=Avago Technologies Sdn Bhd
+
+OUI:00194E*
+ ID_OUI_FROM_DATABASE=Ultra Electronics - TCS (Tactical Communication Systems)
+
+OUI:00194F*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001950*
+ ID_OUI_FROM_DATABASE=Harman Multimedia
+
+OUI:001951*
+ ID_OUI_FROM_DATABASE=NETCONS, s.r.o.
+
+OUI:001952*
+ ID_OUI_FROM_DATABASE=ACOGITO Co., Ltd
+
+OUI:001953*
+ ID_OUI_FROM_DATABASE=Chainleader Communications Corp.
+
+OUI:001954*
+ ID_OUI_FROM_DATABASE=Leaf Corporation.
+
+OUI:001955*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001956*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001957*
+ ID_OUI_FROM_DATABASE=Saafnet Canada Inc.
+
+OUI:001958*
+ ID_OUI_FROM_DATABASE=Bluetooth SIG, Inc.
+
+OUI:001959*
+ ID_OUI_FROM_DATABASE=Staccato Communications Inc.
+
+OUI:00195A*
+ ID_OUI_FROM_DATABASE=Jenaer Antriebstechnik GmbH
+
+OUI:00195B*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:00195C*
+ ID_OUI_FROM_DATABASE=Innotech Corporation
+
+OUI:00195D*
+ ID_OUI_FROM_DATABASE=ShenZhen XinHuaTong Opto Electronics Co.,Ltd
+
+OUI:00195E*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00195F*
+ ID_OUI_FROM_DATABASE=Valemount Networks Corporation
+
+OUI:001960*
+ ID_OUI_FROM_DATABASE=DoCoMo Systems, Inc.
+
+OUI:001961*
+ ID_OUI_FROM_DATABASE=Blaupunkt  Embedded Systems GmbH
+
+OUI:001962*
+ ID_OUI_FROM_DATABASE=Commerciant, LP
+
+OUI:001963*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:001964*
+ ID_OUI_FROM_DATABASE=Doorking Inc.
+
+OUI:001965*
+ ID_OUI_FROM_DATABASE=YuHua TelTech (ShangHai) Co., Ltd.
+
+OUI:001966*
+ ID_OUI_FROM_DATABASE=Asiarock Technology Limited
+
+OUI:001967*
+ ID_OUI_FROM_DATABASE=TELDAT Sp.J.
+
+OUI:001968*
+ ID_OUI_FROM_DATABASE=Digital Video Networks(Shanghai) CO. LTD.
+
+OUI:001969*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:00196A*
+ ID_OUI_FROM_DATABASE=MikroM GmbH
+
+OUI:00196B*
+ ID_OUI_FROM_DATABASE=Danpex Corporation
+
+OUI:00196C*
+ ID_OUI_FROM_DATABASE=ETROVISION TECHNOLOGY
+
+OUI:00196D*
+ ID_OUI_FROM_DATABASE=Raybit Systems Korea, Inc
+
+OUI:00196E*
+ ID_OUI_FROM_DATABASE=Metacom (Pty) Ltd.
+
+OUI:00196F*
+ ID_OUI_FROM_DATABASE=SensoPart GmbH
+
+OUI:001970*
+ ID_OUI_FROM_DATABASE=Z-Com, Inc.
+
+OUI:001971*
+ ID_OUI_FROM_DATABASE=Guangzhou Unicomp Technology Co.,Ltd
+
+OUI:001972*
+ ID_OUI_FROM_DATABASE=Plexus (Xiamen) Co.,ltd
+
+OUI:001973*
+ ID_OUI_FROM_DATABASE=Zeugma Systems
+
+OUI:001974*
+ ID_OUI_FROM_DATABASE=AboCom Systems, Inc.
+
+OUI:001975*
+ ID_OUI_FROM_DATABASE=Beijing Huisen networks technology Inc
+
+OUI:001976*
+ ID_OUI_FROM_DATABASE=Xipher Technologies, LLC
+
+OUI:001977*
+ ID_OUI_FROM_DATABASE=Aerohive Networks, Inc.
+
+OUI:001978*
+ ID_OUI_FROM_DATABASE=Datum Systems, Inc.
+
+OUI:001979*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00197A*
+ ID_OUI_FROM_DATABASE=MAZeT GmbH
+
+OUI:00197B*
+ ID_OUI_FROM_DATABASE=Picotest Corp.
+
+OUI:00197C*
+ ID_OUI_FROM_DATABASE=Riedel Communications GmbH
+
+OUI:00197D*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd
+
+OUI:00197E*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd
+
+OUI:00197F*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:001980*
+ ID_OUI_FROM_DATABASE=Gridpoint Systems
+
+OUI:001981*
+ ID_OUI_FROM_DATABASE=Vivox Inc
+
+OUI:001982*
+ ID_OUI_FROM_DATABASE=SmarDTV
+
+OUI:001983*
+ ID_OUI_FROM_DATABASE=CCT R&D Limited
+
+OUI:001984*
+ ID_OUI_FROM_DATABASE=ESTIC Corporation
+
+OUI:001985*
+ ID_OUI_FROM_DATABASE=IT Watchdogs, Inc
+
+OUI:001986*
+ ID_OUI_FROM_DATABASE=Cheng Hongjian
+
+OUI:001987*
+ ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co., Ltd.
+
+OUI:001988*
+ ID_OUI_FROM_DATABASE=Wi2Wi, Inc
+
+OUI:001989*
+ ID_OUI_FROM_DATABASE=Sonitrol Corporation
+
+OUI:00198A*
+ ID_OUI_FROM_DATABASE=Northrop Grumman Systems Corp.
+
+OUI:00198B*
+ ID_OUI_FROM_DATABASE=Novera Optics Korea, Inc.
+
+OUI:00198C*
+ ID_OUI_FROM_DATABASE=iXSea
+
+OUI:00198D*
+ ID_OUI_FROM_DATABASE=Ocean Optics, Inc.
+
+OUI:00198E*
+ ID_OUI_FROM_DATABASE=Oticon A/S
+
+OUI:00198F*
+ ID_OUI_FROM_DATABASE=Alcatel Bell N.V.
+
+OUI:001990*
+ ID_OUI_FROM_DATABASE=ELM DATA Co., Ltd.
+
+OUI:001991*
+ ID_OUI_FROM_DATABASE=avinfo
+
+OUI:001992*
+ ID_OUI_FROM_DATABASE=ADTRAN INC.
+
+OUI:001993*
+ ID_OUI_FROM_DATABASE=Changshu Switchgear MFG. Co.,Ltd. (Former Changshu Switchgea
+
+OUI:001994*
+ ID_OUI_FROM_DATABASE=Jorjin Technologies Inc.
+
+OUI:001995*
+ ID_OUI_FROM_DATABASE=Jurong Hi-Tech (Suzhou)Co.ltd
+
+OUI:001996*
+ ID_OUI_FROM_DATABASE=TurboChef Technologies Inc.
+
+OUI:001997*
+ ID_OUI_FROM_DATABASE=Soft Device Sdn Bhd
+
+OUI:001998*
+ ID_OUI_FROM_DATABASE=SATO CORPORATION
+
+OUI:001999*
+ ID_OUI_FROM_DATABASE=Fujitsu Technology Solutions
+
+OUI:00199A*
+ ID_OUI_FROM_DATABASE=EDO-EVI
+
+OUI:00199B*
+ ID_OUI_FROM_DATABASE=Diversified Technical Systems, Inc.
+
+OUI:00199C*
+ ID_OUI_FROM_DATABASE=CTRING
+
+OUI:00199D*
+ ID_OUI_FROM_DATABASE=VIZIO, Inc.
+
+OUI:00199E*
+ ID_OUI_FROM_DATABASE=SHOWADENSHI ELECTRONICS,INC.
+
+OUI:00199F*
+ ID_OUI_FROM_DATABASE=DKT A/S
+
+OUI:0019A0*
+ ID_OUI_FROM_DATABASE=NIHON DATA SYSTENS, INC.
+
+OUI:0019A1*
+ ID_OUI_FROM_DATABASE=LG INFORMATION & COMM.
+
+OUI:0019A2*
+ ID_OUI_FROM_DATABASE=ORDYN TECHNOLOGIES
+
+OUI:0019A3*
+ ID_OUI_FROM_DATABASE=asteel electronique atlantique
+
+OUI:0019A4*
+ ID_OUI_FROM_DATABASE=Austar Technology (hang zhou) Co.,Ltd
+
+OUI:0019A5*
+ ID_OUI_FROM_DATABASE=RadarFind Corporation
+
+OUI:0019A6*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0019A7*
+ ID_OUI_FROM_DATABASE=ITU-T
+
+OUI:0019A8*
+ ID_OUI_FROM_DATABASE=WiQuest Communications
+
+OUI:0019A9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0019AA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0019AB*
+ ID_OUI_FROM_DATABASE=Raycom CO ., LTD
+
+OUI:0019AC*
+ ID_OUI_FROM_DATABASE=GSP SYSTEMS Inc.
+
+OUI:0019AD*
+ ID_OUI_FROM_DATABASE=BOBST SA
+
+OUI:0019AE*
+ ID_OUI_FROM_DATABASE=Hopling Technologies b.v.
+
+OUI:0019AF*
+ ID_OUI_FROM_DATABASE=Rigol Technologies, Inc.
+
+OUI:0019B0*
+ ID_OUI_FROM_DATABASE=HanYang System
+
+OUI:0019B1*
+ ID_OUI_FROM_DATABASE=Arrow7 Corporation
+
+OUI:0019B2*
+ ID_OUI_FROM_DATABASE=XYnetsoft Co.,Ltd
+
+OUI:0019B3*
+ ID_OUI_FROM_DATABASE=Stanford Research Systems
+
+OUI:0019B4*
+ ID_OUI_FROM_DATABASE=VideoCast Ltd.
+
+OUI:0019B5*
+ ID_OUI_FROM_DATABASE=Famar Fueguina S.A.
+
+OUI:0019B6*
+ ID_OUI_FROM_DATABASE=Euro Emme s.r.l.
+
+OUI:0019B7*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0019B8*
+ ID_OUI_FROM_DATABASE=Boundary Devices
+
+OUI:0019B9*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:0019BA*
+ ID_OUI_FROM_DATABASE=Paradox Security Systems Ltd
+
+OUI:0019BB*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0019BC*
+ ID_OUI_FROM_DATABASE=ELECTRO CHANCE SRL
+
+OUI:0019BD*
+ ID_OUI_FROM_DATABASE=New Media Life
+
+OUI:0019BE*
+ ID_OUI_FROM_DATABASE=Altai Technologies Limited
+
+OUI:0019BF*
+ ID_OUI_FROM_DATABASE=Citiway technology Co.,ltd
+
+OUI:0019C0*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0019C1*
+ ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd
+
+OUI:0019C2*
+ ID_OUI_FROM_DATABASE=Equustek Solutions, Inc.
+
+OUI:0019C3*
+ ID_OUI_FROM_DATABASE=Qualitrol
+
+OUI:0019C4*
+ ID_OUI_FROM_DATABASE=Infocrypt Inc.
+
+OUI:0019C5*
+ ID_OUI_FROM_DATABASE=SONY Computer Entertainment inc,
+
+OUI:0019C6*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:0019C7*
+ ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
+
+OUI:0019C8*
+ ID_OUI_FROM_DATABASE=AnyDATA Corporation
+
+OUI:0019C9*
+ ID_OUI_FROM_DATABASE=S&C ELECTRIC COMPANY
+
+OUI:0019CA*
+ ID_OUI_FROM_DATABASE=Broadata Communications, Inc
+
+OUI:0019CB*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:0019CC*
+ ID_OUI_FROM_DATABASE=RCG (HK) Ltd
+
+OUI:0019CD*
+ ID_OUI_FROM_DATABASE=Chengdu ethercom information technology Ltd.
+
+OUI:0019CE*
+ ID_OUI_FROM_DATABASE=Progressive Gaming International
+
+OUI:0019CF*
+ ID_OUI_FROM_DATABASE=SALICRU, S.A.
+
+OUI:0019D0*
+ ID_OUI_FROM_DATABASE=Cathexis
+
+OUI:0019D1*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0019D2*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0019D3*
+ ID_OUI_FROM_DATABASE=TRAK Microwave
+
+OUI:0019D4*
+ ID_OUI_FROM_DATABASE=ICX Technologies
+
+OUI:0019D5*
+ ID_OUI_FROM_DATABASE=IP Innovations, Inc.
+
+OUI:0019D6*
+ ID_OUI_FROM_DATABASE=LS Cable Ltd.
+
+OUI:0019D7*
+ ID_OUI_FROM_DATABASE=FORTUNETEK CO., LTD
+
+OUI:0019D8*
+ ID_OUI_FROM_DATABASE=MAXFOR
+
+OUI:0019D9*
+ ID_OUI_FROM_DATABASE=Zeutschel GmbH
+
+OUI:0019DA*
+ ID_OUI_FROM_DATABASE=Welltrans O&E Technology Co. , Ltd.
+
+OUI:0019DB*
+ ID_OUI_FROM_DATABASE=MICRO-STAR INTERNATIONAL CO., LTD.
+
+OUI:0019DC*
+ ID_OUI_FROM_DATABASE=ENENSYS Technologies
+
+OUI:0019DD*
+ ID_OUI_FROM_DATABASE=FEI-Zyfer, Inc.
+
+OUI:0019DE*
+ ID_OUI_FROM_DATABASE=MOBITEK
+
+OUI:0019DF*
+ ID_OUI_FROM_DATABASE=Thomson Inc.
+
+OUI:0019E0*
+ ID_OUI_FROM_DATABASE=TP-LINK Technologies Co., Ltd.
+
+OUI:0019E1*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:0019E2*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:0019E3*
+ ID_OUI_FROM_DATABASE=Apple Computer Inc.
+
+OUI:0019E4*
+ ID_OUI_FROM_DATABASE=2Wire, Inc
+
+OUI:0019E5*
+ ID_OUI_FROM_DATABASE=Lynx Studio Technology, Inc.
+
+OUI:0019E6*
+ ID_OUI_FROM_DATABASE=TOYO MEDIC CO.,LTD.
+
+OUI:0019E7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0019E8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0019E9*
+ ID_OUI_FROM_DATABASE=S-Information Technolgy, Co., Ltd.
+
+OUI:0019EA*
+ ID_OUI_FROM_DATABASE=TeraMage Technologies Co., Ltd.
+
+OUI:0019EB*
+ ID_OUI_FROM_DATABASE=Pyronix Ltd
+
+OUI:0019EC*
+ ID_OUI_FROM_DATABASE=Sagamore Systems, Inc.
+
+OUI:0019ED*
+ ID_OUI_FROM_DATABASE=Axesstel Inc.
+
+OUI:0019EE*
+ ID_OUI_FROM_DATABASE=CARLO GAVAZZI CONTROLS SPA-Controls Division
+
+OUI:0019EF*
+ ID_OUI_FROM_DATABASE=SHENZHEN LINNKING ELECTRONICS CO.,LTD
+
+OUI:0019F0*
+ ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD
+
+OUI:0019F1*
+ ID_OUI_FROM_DATABASE=Star Communication Network Technology Co.,Ltd
+
+OUI:0019F2*
+ ID_OUI_FROM_DATABASE=Teradyne K.K.
+
+OUI:0019F3*
+ ID_OUI_FROM_DATABASE=Cetis, Inc
+
+OUI:0019F4*
+ ID_OUI_FROM_DATABASE=Convergens Oy Ltd
+
+OUI:0019F5*
+ ID_OUI_FROM_DATABASE=Imagination Technologies Ltd
+
+OUI:0019F6*
+ ID_OUI_FROM_DATABASE=Acconet (PTE) Ltd
+
+OUI:0019F7*
+ ID_OUI_FROM_DATABASE=Onset Computer Corporation
+
+OUI:0019F8*
+ ID_OUI_FROM_DATABASE=Embedded Systems Design, Inc.
+
+OUI:0019F9*
+ ID_OUI_FROM_DATABASE=TDK-Lambda
+
+OUI:0019FA*
+ ID_OUI_FROM_DATABASE=Cable Vision Electronics CO., LTD.
+
+OUI:0019FB*
+ ID_OUI_FROM_DATABASE=BSkyB Ltd
+
+OUI:0019FC*
+ ID_OUI_FROM_DATABASE=PT. Ufoakses Sukses Luarbiasa
+
+OUI:0019FD*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:0019FE*
+ ID_OUI_FROM_DATABASE=SHENZHEN SEECOMM TECHNOLOGY CO.,LTD.
+
+OUI:0019FF*
+ ID_OUI_FROM_DATABASE=Finnzymes
+
+OUI:001A00*
+ ID_OUI_FROM_DATABASE=MATRIX INC.
+
+OUI:001A01*
+ ID_OUI_FROM_DATABASE=Smiths Medical
+
+OUI:001A02*
+ ID_OUI_FROM_DATABASE=SECURE CARE PRODUCTS, INC
+
+OUI:001A03*
+ ID_OUI_FROM_DATABASE=Angel Electronics Co., Ltd.
+
+OUI:001A04*
+ ID_OUI_FROM_DATABASE=Interay Solutions BV
+
+OUI:001A05*
+ ID_OUI_FROM_DATABASE=OPTIBASE LTD
+
+OUI:001A06*
+ ID_OUI_FROM_DATABASE=OpVista, Inc.
+
+OUI:001A07*
+ ID_OUI_FROM_DATABASE=Arecont Vision
+
+OUI:001A08*
+ ID_OUI_FROM_DATABASE=Dalman Technical Services
+
+OUI:001A09*
+ ID_OUI_FROM_DATABASE=Wayfarer Transit Systems Ltd
+
+OUI:001A0A*
+ ID_OUI_FROM_DATABASE=Adaptive Micro-Ware Inc.
+
+OUI:001A0B*
+ ID_OUI_FROM_DATABASE=BONA TECHNOLOGY INC.
+
+OUI:001A0C*
+ ID_OUI_FROM_DATABASE=Swe-Dish Satellite Systems AB
+
+OUI:001A0D*
+ ID_OUI_FROM_DATABASE=HandHeld entertainment, Inc.
+
+OUI:001A0E*
+ ID_OUI_FROM_DATABASE=Cheng Uei Precision Industry Co.,Ltd
+
+OUI:001A0F*
+ ID_OUI_FROM_DATABASE=Sistemas Avanzados de Control, S.A.
+
+OUI:001A10*
+ ID_OUI_FROM_DATABASE=LUCENT TRANS ELECTRONICS CO.,LTD
+
+OUI:001A11*
+ ID_OUI_FROM_DATABASE=Google Inc.
+
+OUI:001A12*
+ ID_OUI_FROM_DATABASE=Essilor
+
+OUI:001A13*
+ ID_OUI_FROM_DATABASE=Wanlida Group Co., LTD
+
+OUI:001A14*
+ ID_OUI_FROM_DATABASE=Xin Hua Control Engineering Co.,Ltd.
+
+OUI:001A15*
+ ID_OUI_FROM_DATABASE=gemalto e-Payment
+
+OUI:001A16*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001A17*
+ ID_OUI_FROM_DATABASE=Teak Technologies, Inc.
+
+OUI:001A18*
+ ID_OUI_FROM_DATABASE=Advanced Simulation Technology inc.
+
+OUI:001A19*
+ ID_OUI_FROM_DATABASE=Computer Engineering Limited
+
+OUI:001A1A*
+ ID_OUI_FROM_DATABASE=Gentex Corporation/Electro-Acoustic Products
+
+OUI:001A1B*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001A1C*
+ ID_OUI_FROM_DATABASE=GT&T Engineering Pte Ltd
+
+OUI:001A1D*
+ ID_OUI_FROM_DATABASE=PChome Online Inc.
+
+OUI:001A1E*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
+OUI:001A1F*
+ ID_OUI_FROM_DATABASE=Coastal Environmental Systems
+
+OUI:001A20*
+ ID_OUI_FROM_DATABASE=CMOTECH Co. Ltd.
+
+OUI:001A21*
+ ID_OUI_FROM_DATABASE=Indac B.V.
+
+OUI:001A22*
+ ID_OUI_FROM_DATABASE=eQ-3 Entwicklung GmbH
+
+OUI:001A23*
+ ID_OUI_FROM_DATABASE=Ice Qube, Inc
+
+OUI:001A24*
+ ID_OUI_FROM_DATABASE=Galaxy Telecom Technologies Ltd
+
+OUI:001A25*
+ ID_OUI_FROM_DATABASE=DELTA DORE
+
+OUI:001A26*
+ ID_OUI_FROM_DATABASE=Deltanode Solutions AB
+
+OUI:001A27*
+ ID_OUI_FROM_DATABASE=Ubistar
+
+OUI:001A28*
+ ID_OUI_FROM_DATABASE=ASWT Co., LTD. Taiwan Branch H.K.
+
+OUI:001A29*
+ ID_OUI_FROM_DATABASE=Techsonic Industries d/b/a Humminbird
+
+OUI:001A2A*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:001A2B*
+ ID_OUI_FROM_DATABASE=Ayecom Technology Co., Ltd.
+
+OUI:001A2C*
+ ID_OUI_FROM_DATABASE=SATEC Co.,LTD
+
+OUI:001A2D*
+ ID_OUI_FROM_DATABASE=The Navvo Group
+
+OUI:001A2E*
+ ID_OUI_FROM_DATABASE=Ziova Coporation
+
+OUI:001A2F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001A30*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001A31*
+ ID_OUI_FROM_DATABASE=SCAN COIN Industries AB
+
+OUI:001A32*
+ ID_OUI_FROM_DATABASE=ACTIVA MULTIMEDIA
+
+OUI:001A33*
+ ID_OUI_FROM_DATABASE=ASI Communications, Inc.
+
+OUI:001A34*
+ ID_OUI_FROM_DATABASE=Konka Group Co., Ltd.
+
+OUI:001A35*
+ ID_OUI_FROM_DATABASE=BARTEC GmbH
+
+OUI:001A36*
+ ID_OUI_FROM_DATABASE=Aipermon GmbH & Co. KG
+
+OUI:001A37*
+ ID_OUI_FROM_DATABASE=Lear Corporation
+
+OUI:001A38*
+ ID_OUI_FROM_DATABASE=Sanmina-SCI
+
+OUI:001A39*
+ ID_OUI_FROM_DATABASE=Merten GmbH&CoKG
+
+OUI:001A3A*
+ ID_OUI_FROM_DATABASE=Dongahelecomm
+
+OUI:001A3B*
+ ID_OUI_FROM_DATABASE=Doah Elecom Inc.
+
+OUI:001A3C*
+ ID_OUI_FROM_DATABASE=Technowave Ltd.
+
+OUI:001A3D*
+ ID_OUI_FROM_DATABASE=Ajin Vision Co.,Ltd
+
+OUI:001A3E*
+ ID_OUI_FROM_DATABASE=Faster Technology LLC
+
+OUI:001A3F*
+ ID_OUI_FROM_DATABASE=intelbras
+
+OUI:001A40*
+ ID_OUI_FROM_DATABASE=A-FOUR TECH CO., LTD.
+
+OUI:001A41*
+ ID_OUI_FROM_DATABASE=INOCOVA Co.,Ltd
+
+OUI:001A42*
+ ID_OUI_FROM_DATABASE=Techcity Technology co., Ltd.
+
+OUI:001A43*
+ ID_OUI_FROM_DATABASE=Logical Link Communications
+
+OUI:001A44*
+ ID_OUI_FROM_DATABASE=JWTrading Co., Ltd
+
+OUI:001A45*
+ ID_OUI_FROM_DATABASE=GN Netcom as
+
+OUI:001A46*
+ ID_OUI_FROM_DATABASE=Digital Multimedia Technology Co., Ltd
+
+OUI:001A47*
+ ID_OUI_FROM_DATABASE=Agami Systems, Inc.
+
+OUI:001A48*
+ ID_OUI_FROM_DATABASE=Takacom Corporation
+
+OUI:001A49*
+ ID_OUI_FROM_DATABASE=Micro Vision Co.,LTD
+
+OUI:001A4A*
+ ID_OUI_FROM_DATABASE=Qumranet Inc.
+
+OUI:001A4B*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001A4C*
+ ID_OUI_FROM_DATABASE=Crossbow Technology, Inc
+
+OUI:001A4D*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:001A4E*
+ ID_OUI_FROM_DATABASE=NTI AG / LinMot
+
+OUI:001A4F*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:001A50*
+ ID_OUI_FROM_DATABASE=PheeNet Technology Corp.
+
+OUI:001A51*
+ ID_OUI_FROM_DATABASE=Alfred Mann Foundation
+
+OUI:001A52*
+ ID_OUI_FROM_DATABASE=Meshlinx Wireless Inc.
+
+OUI:001A53*
+ ID_OUI_FROM_DATABASE=Zylaya
+
+OUI:001A54*
+ ID_OUI_FROM_DATABASE=Hip Shing Electronics Ltd.
+
+OUI:001A55*
+ ID_OUI_FROM_DATABASE=ACA-Digital Corporation
+
+OUI:001A56*
+ ID_OUI_FROM_DATABASE=ViewTel Co,. Ltd.
+
+OUI:001A57*
+ ID_OUI_FROM_DATABASE=Matrix Design Group, LLC
+
+OUI:001A58*
+ ID_OUI_FROM_DATABASE=CCV Deutschland GmbH - Celectronic eHealth Div.
+
+OUI:001A59*
+ ID_OUI_FROM_DATABASE=Ircona
+
+OUI:001A5A*
+ ID_OUI_FROM_DATABASE=Korea Electric Power Data Network  (KDN) Co., Ltd
+
+OUI:001A5B*
+ ID_OUI_FROM_DATABASE=NetCare Service Co., Ltd.
+
+OUI:001A5C*
+ ID_OUI_FROM_DATABASE=Euchner GmbH+Co. KG
+
+OUI:001A5D*
+ ID_OUI_FROM_DATABASE=Mobinnova Corp.
+
+OUI:001A5E*
+ ID_OUI_FROM_DATABASE=Thincom Technology Co.,Ltd
+
+OUI:001A5F*
+ ID_OUI_FROM_DATABASE=KitWorks.fi Ltd.
+
+OUI:001A60*
+ ID_OUI_FROM_DATABASE=Wave Electronics Co.,Ltd.
+
+OUI:001A61*
+ ID_OUI_FROM_DATABASE=PacStar Corp.
+
+OUI:001A62*
+ ID_OUI_FROM_DATABASE=Data Robotics, Incorporated
+
+OUI:001A63*
+ ID_OUI_FROM_DATABASE=Elster Solutions, LLC,
+
+OUI:001A64*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:001A65*
+ ID_OUI_FROM_DATABASE=Seluxit
+
+OUI:001A66*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001A67*
+ ID_OUI_FROM_DATABASE=Infinite QL Sdn Bhd
+
+OUI:001A68*
+ ID_OUI_FROM_DATABASE=Weltec Enterprise Co., Ltd.
+
+OUI:001A69*
+ ID_OUI_FROM_DATABASE=Wuhan Yangtze Optical Technology CO.,Ltd.
+
+OUI:001A6A*
+ ID_OUI_FROM_DATABASE=Tranzas, Inc.
+
+OUI:001A6B*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:001A6C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001A6D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001A6E*
+ ID_OUI_FROM_DATABASE=Impro Technologies
+
+OUI:001A6F*
+ ID_OUI_FROM_DATABASE=MI.TEL s.r.l.
+
+OUI:001A70*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:001A71*
+ ID_OUI_FROM_DATABASE=Diostech Co., Ltd.
+
+OUI:001A72*
+ ID_OUI_FROM_DATABASE=Mosart Semiconductor Corp.
+
+OUI:001A73*
+ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+
+OUI:001A74*
+ ID_OUI_FROM_DATABASE=Procare International Co
+
+OUI:001A75*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:001A76*
+ ID_OUI_FROM_DATABASE=SDT information Technology Co.,LTD.
+
+OUI:001A77*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001A78*
+ ID_OUI_FROM_DATABASE=ubtos
+
+OUI:001A79*
+ ID_OUI_FROM_DATABASE=TELECOMUNICATION TECHNOLOGIES LTD.
+
+OUI:001A7A*
+ ID_OUI_FROM_DATABASE=Lismore Instruments Limited
+
+OUI:001A7B*
+ ID_OUI_FROM_DATABASE=Teleco, Inc.
+
+OUI:001A7C*
+ ID_OUI_FROM_DATABASE=Hirschmann Multimedia B.V.
+
+OUI:001A7D*
+ ID_OUI_FROM_DATABASE=cyber-blue(HK)Ltd
+
+OUI:001A7E*
+ ID_OUI_FROM_DATABASE=LN Srithai Comm Ltd.
+
+OUI:001A7F*
+ ID_OUI_FROM_DATABASE=GCI Science&Technology Co.,Ltd.
+
+OUI:001A80*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:001A81*
+ ID_OUI_FROM_DATABASE=Zelax
+
+OUI:001A82*
+ ID_OUI_FROM_DATABASE=PROBA Building Automation Co.,LTD
+
+OUI:001A83*
+ ID_OUI_FROM_DATABASE=Pegasus Technologies Inc.
+
+OUI:001A84*
+ ID_OUI_FROM_DATABASE=V One Multimedia Pte Ltd
+
+OUI:001A85*
+ ID_OUI_FROM_DATABASE=NV Michel Van de Wiele
+
+OUI:001A86*
+ ID_OUI_FROM_DATABASE=AdvancedIO Systems Inc
+
+OUI:001A87*
+ ID_OUI_FROM_DATABASE=Canhold International Limited
+
+OUI:001A88*
+ ID_OUI_FROM_DATABASE=Venergy,Co,Ltd
+
+OUI:001A89*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001A8A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+OUI:001A8B*
+ ID_OUI_FROM_DATABASE=CHUNIL ELECTRIC IND., CO.
+
+OUI:001A8C*
+ ID_OUI_FROM_DATABASE=Astaro AG
+
+OUI:001A8D*
+ ID_OUI_FROM_DATABASE=AVECS Bergen GmbH
+
+OUI:001A8E*
+ ID_OUI_FROM_DATABASE=3Way Networks Ltd
+
+OUI:001A8F*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001A90*
+ ID_OUI_FROM_DATABASE=Trópico Sistemas e Telecomunicações da Amazônia LTDA.
+
+OUI:001A91*
+ ID_OUI_FROM_DATABASE=FusionDynamic Ltd.
+
+OUI:001A92*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:001A93*
+ ID_OUI_FROM_DATABASE=ERCO Leuchten GmbH
+
+OUI:001A94*
+ ID_OUI_FROM_DATABASE=Votronic GmbH
+
+OUI:001A95*
+ ID_OUI_FROM_DATABASE=Hisense Mobile Communications Technoligy Co.,Ltd.
+
+OUI:001A96*
+ ID_OUI_FROM_DATABASE=ECLER S.A.
+
+OUI:001A97*
+ ID_OUI_FROM_DATABASE=fitivision technology Inc.
+
+OUI:001A98*
+ ID_OUI_FROM_DATABASE=Asotel Communication Limited Taiwan Branch
+
+OUI:001A99*
+ ID_OUI_FROM_DATABASE=Smarty (HZ) Information Electronics Co., Ltd
+
+OUI:001A9A*
+ ID_OUI_FROM_DATABASE=Skyworth Digital technology(shenzhen)co.ltd.
+
+OUI:001A9B*
+ ID_OUI_FROM_DATABASE=ADEC & Parter AG
+
+OUI:001A9C*
+ ID_OUI_FROM_DATABASE=RightHand Technologies, Inc.
+
+OUI:001A9D*
+ ID_OUI_FROM_DATABASE=Skipper Wireless, Inc.
+
+OUI:001A9E*
+ ID_OUI_FROM_DATABASE=ICON Digital International Limited
+
+OUI:001A9F*
+ ID_OUI_FROM_DATABASE=A-Link Europe Ltd
+
+OUI:001AA0*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:001AA1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001AA2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001AA3*
+ ID_OUI_FROM_DATABASE=DELORME
+
+OUI:001AA4*
+ ID_OUI_FROM_DATABASE=Future University-Hakodate
+
+OUI:001AA5*
+ ID_OUI_FROM_DATABASE=BRN Phoenix
+
+OUI:001AA6*
+ ID_OUI_FROM_DATABASE=Telefunken Radio Communication Systems GmbH &CO.KG
+
+OUI:001AA7*
+ ID_OUI_FROM_DATABASE=Torian Wireless
+
+OUI:001AA8*
+ ID_OUI_FROM_DATABASE=Mamiya Digital Imaging Co., Ltd.
+
+OUI:001AA9*
+ ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD
+
+OUI:001AAA*
+ ID_OUI_FROM_DATABASE=Analogic Corp.
+
+OUI:001AAB*
+ ID_OUI_FROM_DATABASE=eWings s.r.l.
+
+OUI:001AAC*
+ ID_OUI_FROM_DATABASE=Corelatus AB
+
+OUI:001AAD*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001AAE*
+ ID_OUI_FROM_DATABASE=Savant Systems LLC
+
+OUI:001AAF*
+ ID_OUI_FROM_DATABASE=BLUSENS TECHNOLOGY
+
+OUI:001AB0*
+ ID_OUI_FROM_DATABASE=Signal Networks Pvt. Ltd.,
+
+OUI:001AB1*
+ ID_OUI_FROM_DATABASE=Asia Pacific Satellite Industries Co., Ltd.
+
+OUI:001AB2*
+ ID_OUI_FROM_DATABASE=Cyber Solutions Inc.
+
+OUI:001AB3*
+ ID_OUI_FROM_DATABASE=VISIONITE INC.
+
+OUI:001AB4*
+ ID_OUI_FROM_DATABASE=FFEI Ltd.
+
+OUI:001AB5*
+ ID_OUI_FROM_DATABASE=Home Network System
+
+OUI:001AB6*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:001AB7*
+ ID_OUI_FROM_DATABASE=Ethos Networks LTD.
+
+OUI:001AB8*
+ ID_OUI_FROM_DATABASE=Anseri Corporation
+
+OUI:001AB9*
+ ID_OUI_FROM_DATABASE=PMC
+
+OUI:001ABA*
+ ID_OUI_FROM_DATABASE=Caton Overseas Limited
+
+OUI:001ABB*
+ ID_OUI_FROM_DATABASE=Fontal Technology Incorporation
+
+OUI:001ABC*
+ ID_OUI_FROM_DATABASE=U4EA Technologies Ltd
+
+OUI:001ABD*
+ ID_OUI_FROM_DATABASE=Impatica Inc.
+
+OUI:001ABE*
+ ID_OUI_FROM_DATABASE=COMPUTER HI-TECH INC.
+
+OUI:001ABF*
+ ID_OUI_FROM_DATABASE=TRUMPF Laser Marking Systems AG
+
+OUI:001AC0*
+ ID_OUI_FROM_DATABASE=JOYBIEN TECHNOLOGIES CO., LTD.
+
+OUI:001AC1*
+ ID_OUI_FROM_DATABASE=3Com Ltd
+
+OUI:001AC2*
+ ID_OUI_FROM_DATABASE=YEC Co.,Ltd.
+
+OUI:001AC3*
+ ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc
+
+OUI:001AC4*
+ ID_OUI_FROM_DATABASE=2Wire, Inc
+
+OUI:001AC5*
+ ID_OUI_FROM_DATABASE=BreakingPoint Systems, Inc.
+
+OUI:001AC6*
+ ID_OUI_FROM_DATABASE=Micro Control Designs
+
+OUI:001AC7*
+ ID_OUI_FROM_DATABASE=UNIPOINT
+
+OUI:001AC8*
+ ID_OUI_FROM_DATABASE=ISL (Instrumentation Scientifique de Laboratoire)
+
+OUI:001AC9*
+ ID_OUI_FROM_DATABASE=SUZUKEN CO.,LTD
+
+OUI:001ACA*
+ ID_OUI_FROM_DATABASE=Tilera Corporation
+
+OUI:001ACB*
+ ID_OUI_FROM_DATABASE=Autocom Products Ltd
+
+OUI:001ACC*
+ ID_OUI_FROM_DATABASE=Celestial Semiconductor, Ltd
+
+OUI:001ACD*
+ ID_OUI_FROM_DATABASE=Tidel Engineering LP
+
+OUI:001ACE*
+ ID_OUI_FROM_DATABASE=YUPITERU CORPORATION
+
+OUI:001ACF*
+ ID_OUI_FROM_DATABASE=C.T. ELETTRONICA
+
+OUI:001AD0*
+ ID_OUI_FROM_DATABASE=Albis Technologies AG
+
+OUI:001AD1*
+ ID_OUI_FROM_DATABASE=FARGO CO., LTD.
+
+OUI:001AD2*
+ ID_OUI_FROM_DATABASE=Eletronica Nitron Ltda
+
+OUI:001AD3*
+ ID_OUI_FROM_DATABASE=Vamp Ltd.
+
+OUI:001AD4*
+ ID_OUI_FROM_DATABASE=iPOX Technology Co., Ltd.
+
+OUI:001AD5*
+ ID_OUI_FROM_DATABASE=KMC CHAIN INDUSTRIAL CO., LTD.
+
+OUI:001AD6*
+ ID_OUI_FROM_DATABASE=JIAGNSU AETNA ELECTRIC CO.,LTD
+
+OUI:001AD7*
+ ID_OUI_FROM_DATABASE=Christie Digital Systems, Inc.
+
+OUI:001AD8*
+ ID_OUI_FROM_DATABASE=AlsterAero GmbH
+
+OUI:001AD9*
+ ID_OUI_FROM_DATABASE=International Broadband Electric Communications, Inc.
+
+OUI:001ADA*
+ ID_OUI_FROM_DATABASE=Biz-2-Me Inc.
+
+OUI:001ADB*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001ADC*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001ADD*
+ ID_OUI_FROM_DATABASE=PePWave Ltd
+
+OUI:001ADE*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001ADF*
+ ID_OUI_FROM_DATABASE=Interactivetv Pty Limited
+
+OUI:001AE0*
+ ID_OUI_FROM_DATABASE=Mythology Tech Express Inc.
+
+OUI:001AE1*
+ ID_OUI_FROM_DATABASE=EDGE ACCESS INC
+
+OUI:001AE2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001AE3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001AE4*
+ ID_OUI_FROM_DATABASE=Medicis Technologies Corporation
+
+OUI:001AE5*
+ ID_OUI_FROM_DATABASE=Mvox Technologies Inc.
+
+OUI:001AE6*
+ ID_OUI_FROM_DATABASE=Atlanta Advanced Communications Holdings Limited
+
+OUI:001AE7*
+ ID_OUI_FROM_DATABASE=Aztek Networks, Inc.
+
+OUI:001AE8*
+ ID_OUI_FROM_DATABASE=Siemens Enterprise Communications GmbH & Co. KG
+
+OUI:001AE9*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001AEA*
+ ID_OUI_FROM_DATABASE=Radio Terminal Systems Pty Ltd
+
+OUI:001AEB*
+ ID_OUI_FROM_DATABASE=Allied Telesis K.K.
+
+OUI:001AEC*
+ ID_OUI_FROM_DATABASE=Keumbee Electronics Co.,Ltd.
+
+OUI:001AED*
+ ID_OUI_FROM_DATABASE=INCOTEC GmbH
+
+OUI:001AEE*
+ ID_OUI_FROM_DATABASE=Shenztech Ltd
+
+OUI:001AEF*
+ ID_OUI_FROM_DATABASE=Loopcomm Technology, Inc.
+
+OUI:001AF0*
+ ID_OUI_FROM_DATABASE=Alcatel - IPD
+
+OUI:001AF1*
+ ID_OUI_FROM_DATABASE=Embedded Artists AB
+
+OUI:001AF2*
+ ID_OUI_FROM_DATABASE=Dynavisions Schweiz AG
+
+OUI:001AF3*
+ ID_OUI_FROM_DATABASE=Samyoung Electronics
+
+OUI:001AF4*
+ ID_OUI_FROM_DATABASE=Handreamnet
+
+OUI:001AF5*
+ ID_OUI_FROM_DATABASE=PENTAONE. CO., LTD.
+
+OUI:001AF6*
+ ID_OUI_FROM_DATABASE=Woven Systems, Inc.
+
+OUI:001AF7*
+ ID_OUI_FROM_DATABASE=dataschalt e+a GmbH
+
+OUI:001AF8*
+ ID_OUI_FROM_DATABASE=Copley Controls Corporation
+
+OUI:001AF9*
+ ID_OUI_FROM_DATABASE=AeroVIronment (AV Inc)
+
+OUI:001AFA*
+ ID_OUI_FROM_DATABASE=Welch Allyn, Inc.
+
+OUI:001AFB*
+ ID_OUI_FROM_DATABASE=Joby Inc.
+
+OUI:001AFC*
+ ID_OUI_FROM_DATABASE=ModusLink Corporation
+
+OUI:001AFD*
+ ID_OUI_FROM_DATABASE=EVOLIS
+
+OUI:001AFE*
+ ID_OUI_FROM_DATABASE=SOFACREAL
+
+OUI:001AFF*
+ ID_OUI_FROM_DATABASE=Wizyoung Tech.
+
+OUI:001B00*
+ ID_OUI_FROM_DATABASE=Neopost Technologies
+
+OUI:001B01*
+ ID_OUI_FROM_DATABASE=Applied Radio Technologies
+
+OUI:001B02*
+ ID_OUI_FROM_DATABASE=ED Co.Ltd
+
+OUI:001B03*
+ ID_OUI_FROM_DATABASE=Action Technology (SZ) Co., Ltd
+
+OUI:001B04*
+ ID_OUI_FROM_DATABASE=Affinity International S.p.a
+
+OUI:001B05*
+ ID_OUI_FROM_DATABASE=YMC AG
+
+OUI:001B06*
+ ID_OUI_FROM_DATABASE=Ateliers R. LAUMONIER
+
+OUI:001B07*
+ ID_OUI_FROM_DATABASE=Mendocino Software
+
+OUI:001B08*
+ ID_OUI_FROM_DATABASE=Danfoss Drives A/S
+
+OUI:001B09*
+ ID_OUI_FROM_DATABASE=Matrix Telecom Pvt. Ltd.
+
+OUI:001B0A*
+ ID_OUI_FROM_DATABASE=Intelligent Distributed Controls Ltd
+
+OUI:001B0B*
+ ID_OUI_FROM_DATABASE=Phidgets Inc.
+
+OUI:001B0C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001B0D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001B0E*
+ ID_OUI_FROM_DATABASE=InoTec GmbH Organisationssysteme
+
+OUI:001B0F*
+ ID_OUI_FROM_DATABASE=Petratec
+
+OUI:001B10*
+ ID_OUI_FROM_DATABASE=ShenZhen Kang Hui Technology Co.,ltd
+
+OUI:001B11*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:001B12*
+ ID_OUI_FROM_DATABASE=Apprion
+
+OUI:001B13*
+ ID_OUI_FROM_DATABASE=Icron Technologies Corporation
+
+OUI:001B14*
+ ID_OUI_FROM_DATABASE=Carex Lighting Equipment Factory
+
+OUI:001B15*
+ ID_OUI_FROM_DATABASE=Voxtel, Inc.
+
+OUI:001B16*
+ ID_OUI_FROM_DATABASE=Celtro Ltd.
+
+OUI:001B17*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:001B18*
+ ID_OUI_FROM_DATABASE=Tsuken Electric Ind. Co.,Ltd
+
+OUI:001B19*
+ ID_OUI_FROM_DATABASE=IEEE I&M Society TC9
+
+OUI:001B1A*
+ ID_OUI_FROM_DATABASE=e-trees Japan, Inc.
+
+OUI:001B1B*
+ ID_OUI_FROM_DATABASE=Siemens AG,
+
+OUI:001B1C*
+ ID_OUI_FROM_DATABASE=Coherent
+
+OUI:001B1D*
+ ID_OUI_FROM_DATABASE=Phoenix International Co., Ltd
+
+OUI:001B1E*
+ ID_OUI_FROM_DATABASE=HART Communication Foundation
+
+OUI:001B1F*
+ ID_OUI_FROM_DATABASE=DELTA - Danish Electronics, Light & Acoustics
+
+OUI:001B20*
+ ID_OUI_FROM_DATABASE=TPine Technology
+
+OUI:001B21*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001B22*
+ ID_OUI_FROM_DATABASE=Palit Microsystems ( H.K.) Ltd.
+
+OUI:001B23*
+ ID_OUI_FROM_DATABASE=SimpleComTools
+
+OUI:001B24*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc.
+
+OUI:001B25*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001B26*
+ ID_OUI_FROM_DATABASE=RON-Telecom ZAO
+
+OUI:001B27*
+ ID_OUI_FROM_DATABASE=Merlin CSI
+
+OUI:001B28*
+ ID_OUI_FROM_DATABASE=POLYGON, JSC
+
+OUI:001B29*
+ ID_OUI_FROM_DATABASE=Avantis.Co.,Ltd
+
+OUI:001B2A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001B2B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001B2C*
+ ID_OUI_FROM_DATABASE=ATRON electronic GmbH
+
+OUI:001B2D*
+ ID_OUI_FROM_DATABASE=Med-Eng Systems Inc.
+
+OUI:001B2E*
+ ID_OUI_FROM_DATABASE=Sinkyo Electron Inc
+
+OUI:001B2F*
+ ID_OUI_FROM_DATABASE=NETGEAR Inc.
+
+OUI:001B30*
+ ID_OUI_FROM_DATABASE=Solitech Inc.
+
+OUI:001B31*
+ ID_OUI_FROM_DATABASE=Neural Image. Co. Ltd.
+
+OUI:001B32*
+ ID_OUI_FROM_DATABASE=QLogic Corporation
+
+OUI:001B33*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001B34*
+ ID_OUI_FROM_DATABASE=Focus System Inc.
+
+OUI:001B35*
+ ID_OUI_FROM_DATABASE=ChongQing JINOU Science & Technology Development CO.,Ltd
+
+OUI:001B36*
+ ID_OUI_FROM_DATABASE=Tsubata Engineering Co.,Ltd. (Head Office)
+
+OUI:001B37*
+ ID_OUI_FROM_DATABASE=Computec Oy
+
+OUI:001B38*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:001B39*
+ ID_OUI_FROM_DATABASE=Proxicast
+
+OUI:001B3A*
+ ID_OUI_FROM_DATABASE=SIMS Corp.
+
+OUI:001B3B*
+ ID_OUI_FROM_DATABASE=Yi-Qing CO., LTD
+
+OUI:001B3C*
+ ID_OUI_FROM_DATABASE=Software Technologies Group,Inc.
+
+OUI:001B3D*
+ ID_OUI_FROM_DATABASE=EuroTel Spa
+
+OUI:001B3E*
+ ID_OUI_FROM_DATABASE=Curtis, Inc.
+
+OUI:001B3F*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:001B40*
+ ID_OUI_FROM_DATABASE=Network Automation mxc AB
+
+OUI:001B41*
+ ID_OUI_FROM_DATABASE=General Infinity Co.,Ltd.
+
+OUI:001B42*
+ ID_OUI_FROM_DATABASE=Wise & Blue
+
+OUI:001B43*
+ ID_OUI_FROM_DATABASE=Beijing DG Telecommunications equipment Co.,Ltd
+
+OUI:001B44*
+ ID_OUI_FROM_DATABASE=SanDisk Corporation
+
+OUI:001B45*
+ ID_OUI_FROM_DATABASE=ABB AS, Division Automation Products
+
+OUI:001B46*
+ ID_OUI_FROM_DATABASE=Blueone Technology Co.,Ltd
+
+OUI:001B47*
+ ID_OUI_FROM_DATABASE=Futarque A/S
+
+OUI:001B48*
+ ID_OUI_FROM_DATABASE=Shenzhen Lantech Electronics Co., Ltd.
+
+OUI:001B49*
+ ID_OUI_FROM_DATABASE=Roberts Radio limited
+
+OUI:001B4A*
+ ID_OUI_FROM_DATABASE=W&W Communications, Inc.
+
+OUI:001B4B*
+ ID_OUI_FROM_DATABASE=SANION Co., Ltd.
+
+OUI:001B4C*
+ ID_OUI_FROM_DATABASE=Signtech
+
+OUI:001B4D*
+ ID_OUI_FROM_DATABASE=Areca Technology Corporation
+
+OUI:001B4E*
+ ID_OUI_FROM_DATABASE=Navman New Zealand
+
+OUI:001B4F*
+ ID_OUI_FROM_DATABASE=Avaya Inc.
+
+OUI:001B50*
+ ID_OUI_FROM_DATABASE=Nizhny Novgorod Factory named after M.Frunze, FSUE (NZiF)
+
+OUI:001B51*
+ ID_OUI_FROM_DATABASE=Vector Technology Corp.
+
+OUI:001B52*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001B53*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001B54*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001B55*
+ ID_OUI_FROM_DATABASE=Hurco Automation Ltd.
+
+OUI:001B56*
+ ID_OUI_FROM_DATABASE=Tehuti Networks Ltd.
+
+OUI:001B57*
+ ID_OUI_FROM_DATABASE=SEMINDIA SYSTEMS PRIVATE LIMITED
+
+OUI:001B58*
+ ID_OUI_FROM_DATABASE=ACE CAD Enterprise Co., Ltd.
+
+OUI:001B59*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:001B5A*
+ ID_OUI_FROM_DATABASE=Apollo Imaging Technologies, Inc.
+
+OUI:001B5B*
+ ID_OUI_FROM_DATABASE=2Wire, Inc.
+
+OUI:001B5C*
+ ID_OUI_FROM_DATABASE=Azuretec Co., Ltd.
+
+OUI:001B5D*
+ ID_OUI_FROM_DATABASE=Vololink Pty Ltd
+
+OUI:001B5E*
+ ID_OUI_FROM_DATABASE=BPL Limited
+
+OUI:001B5F*
+ ID_OUI_FROM_DATABASE=Alien Technology
+
+OUI:001B60*
+ ID_OUI_FROM_DATABASE=NAVIGON AG
+
+OUI:001B61*
+ ID_OUI_FROM_DATABASE=Digital Acoustics, LLC
+
+OUI:001B62*
+ ID_OUI_FROM_DATABASE=JHT Optoelectronics Co.,Ltd.
+
+OUI:001B63*
+ ID_OUI_FROM_DATABASE=Apple Computer Inc.
+
+OUI:001B64*
+ ID_OUI_FROM_DATABASE=IsaacLandKorea Co., Ltd,
+
+OUI:001B65*
+ ID_OUI_FROM_DATABASE=China Gridcom Co., Ltd
+
+OUI:001B66*
+ ID_OUI_FROM_DATABASE=Sennheiser electronic GmbH & Co. KG
+
+OUI:001B67*
+ ID_OUI_FROM_DATABASE=Ubiquisys Ltd
+
+OUI:001B68*
+ ID_OUI_FROM_DATABASE=Modnnet Co., Ltd
+
+OUI:001B69*
+ ID_OUI_FROM_DATABASE=Equaline Corporation
+
+OUI:001B6A*
+ ID_OUI_FROM_DATABASE=Powerwave Technologies Sweden AB
+
+OUI:001B6B*
+ ID_OUI_FROM_DATABASE=Swyx Solutions AG
+
+OUI:001B6C*
+ ID_OUI_FROM_DATABASE=LookX Digital Media BV
+
+OUI:001B6D*
+ ID_OUI_FROM_DATABASE=Midtronics, Inc.
+
+OUI:001B6E*
+ ID_OUI_FROM_DATABASE=Anue Systems, Inc.
+
+OUI:001B6F*
+ ID_OUI_FROM_DATABASE=Teletrak Ltd
+
+OUI:001B70*
+ ID_OUI_FROM_DATABASE=IRI Ubiteq, INC.
+
+OUI:001B71*
+ ID_OUI_FROM_DATABASE=Telular Corp.
+
+OUI:001B72*
+ ID_OUI_FROM_DATABASE=Sicep s.p.a.
+
+OUI:001B73*
+ ID_OUI_FROM_DATABASE=DTL Broadcast Ltd
+
+OUI:001B74*
+ ID_OUI_FROM_DATABASE=MiraLink Corporation
+
+OUI:001B75*
+ ID_OUI_FROM_DATABASE=Hypermedia Systems
+
+OUI:001B76*
+ ID_OUI_FROM_DATABASE=Ripcode, Inc.
+
+OUI:001B77*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001B78*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001B79*
+ ID_OUI_FROM_DATABASE=FAIVELEY TRANSPORT
+
+OUI:001B7A*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001B7B*
+ ID_OUI_FROM_DATABASE=The Tintometer Ltd
+
+OUI:001B7C*
+ ID_OUI_FROM_DATABASE=A & R Cambridge
+
+OUI:001B7D*
+ ID_OUI_FROM_DATABASE=CXR Anderson Jacobson
+
+OUI:001B7E*
+ ID_OUI_FROM_DATABASE=Beckmann GmbH
+
+OUI:001B7F*
+ ID_OUI_FROM_DATABASE=TMN Technologies Telecomunicacoes Ltda
+
+OUI:001B80*
+ ID_OUI_FROM_DATABASE=LORD Corporation
+
+OUI:001B81*
+ ID_OUI_FROM_DATABASE=DATAQ Instruments, Inc.
+
+OUI:001B82*
+ ID_OUI_FROM_DATABASE=Taiwan Semiconductor Co., Ltd.
+
+OUI:001B83*
+ ID_OUI_FROM_DATABASE=Finsoft Ltd
+
+OUI:001B84*
+ ID_OUI_FROM_DATABASE=Scan Engineering Telecom
+
+OUI:001B85*
+ ID_OUI_FROM_DATABASE=MAN Diesel SE
+
+OUI:001B86*
+ ID_OUI_FROM_DATABASE=Bosch Access Systems GmbH
+
+OUI:001B87*
+ ID_OUI_FROM_DATABASE=Deepsound Tech. Co., Ltd
+
+OUI:001B88*
+ ID_OUI_FROM_DATABASE=Divinet Access Technologies Ltd
+
+OUI:001B89*
+ ID_OUI_FROM_DATABASE=EMZA Visual Sense Ltd.
+
+OUI:001B8A*
+ ID_OUI_FROM_DATABASE=2M Electronic A/S
+
+OUI:001B8B*
+ ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+
+OUI:001B8C*
+ ID_OUI_FROM_DATABASE=JMicron Technology Corp.
+
+OUI:001B8D*
+ ID_OUI_FROM_DATABASE=Electronic Computer Systems, Inc.
+
+OUI:001B8E*
+ ID_OUI_FROM_DATABASE=Hulu Sweden AB
+
+OUI:001B8F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001B90*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001B91*
+ ID_OUI_FROM_DATABASE=EFKON AG
+
+OUI:001B92*
+ ID_OUI_FROM_DATABASE=l-acoustics
+
+OUI:001B93*
+ ID_OUI_FROM_DATABASE=JC Decaux SA DNT
+
+OUI:001B94*
+ ID_OUI_FROM_DATABASE=T.E.M.A. S.p.A.
+
+OUI:001B95*
+ ID_OUI_FROM_DATABASE=VIDEO SYSTEMS SRL
+
+OUI:001B96*
+ ID_OUI_FROM_DATABASE=General Sensing
+
+OUI:001B97*
+ ID_OUI_FROM_DATABASE=Violin Technologies
+
+OUI:001B98*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+OUI:001B99*
+ ID_OUI_FROM_DATABASE=KS System GmbH
+
+OUI:001B9A*
+ ID_OUI_FROM_DATABASE=Apollo Fire Detectors Ltd
+
+OUI:001B9B*
+ ID_OUI_FROM_DATABASE=Hose-McCann Communications
+
+OUI:001B9C*
+ ID_OUI_FROM_DATABASE=SATEL sp. z o.o.
+
+OUI:001B9D*
+ ID_OUI_FROM_DATABASE=Novus Security Sp. z o.o.
+
+OUI:001B9E*
+ ID_OUI_FROM_DATABASE=ASKEY  COMPUTER  CORP
+
+OUI:001B9F*
+ ID_OUI_FROM_DATABASE=Calyptech Pty Ltd
+
+OUI:001BA0*
+ ID_OUI_FROM_DATABASE=Awox
+
+OUI:001BA1*
+ ID_OUI_FROM_DATABASE=Åmic AB
+
+OUI:001BA2*
+ ID_OUI_FROM_DATABASE=IDS Imaging Development Systems GmbH
+
+OUI:001BA3*
+ ID_OUI_FROM_DATABASE=Flexit Group GmbH
+
+OUI:001BA4*
+ ID_OUI_FROM_DATABASE=S.A.E Afikim
+
+OUI:001BA5*
+ ID_OUI_FROM_DATABASE=MyungMin Systems, Inc.
+
+OUI:001BA6*
+ ID_OUI_FROM_DATABASE=intotech inc.
+
+OUI:001BA7*
+ ID_OUI_FROM_DATABASE=Lorica Solutions
+
+OUI:001BA8*
+ ID_OUI_FROM_DATABASE=UBI&MOBI,.Inc
+
+OUI:001BA9*
+ ID_OUI_FROM_DATABASE=BROTHER INDUSTRIES, LTD.
+
+OUI:001BAA*
+ ID_OUI_FROM_DATABASE=XenICs nv
+
+OUI:001BAB*
+ ID_OUI_FROM_DATABASE=Telchemy, Incorporated
+
+OUI:001BAC*
+ ID_OUI_FROM_DATABASE=Curtiss Wright Controls Embedded Computing
+
+OUI:001BAD*
+ ID_OUI_FROM_DATABASE=iControl Incorporated
+
+OUI:001BAE*
+ ID_OUI_FROM_DATABASE=Micro Control Systems, Inc
+
+OUI:001BAF*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001BB0*
+ ID_OUI_FROM_DATABASE=BHARAT ELECTRONICS
+
+OUI:001BB1*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
+
+OUI:001BB2*
+ ID_OUI_FROM_DATABASE=Intellect International NV
+
+OUI:001BB3*
+ ID_OUI_FROM_DATABASE=Condalo GmbH
+
+OUI:001BB4*
+ ID_OUI_FROM_DATABASE=Airvod Limited
+
+OUI:001BB5*
+ ID_OUI_FROM_DATABASE=ZF Electronics GmbH
+
+OUI:001BB6*
+ ID_OUI_FROM_DATABASE=Bird Electronic Corp.
+
+OUI:001BB7*
+ ID_OUI_FROM_DATABASE=Alta Heights Technology Corp.
+
+OUI:001BB8*
+ ID_OUI_FROM_DATABASE=BLUEWAY ELECTRONIC CO;LTD
+
+OUI:001BB9*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer System Co.
+
+OUI:001BBA*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001BBB*
+ ID_OUI_FROM_DATABASE=RFTech Co.,Ltd
+
+OUI:001BBC*
+ ID_OUI_FROM_DATABASE=Silver Peak Systems, Inc.
+
+OUI:001BBD*
+ ID_OUI_FROM_DATABASE=FMC Kongsberg Subsea AS
+
+OUI:001BBE*
+ ID_OUI_FROM_DATABASE=ICOP Digital
+
+OUI:001BBF*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:001BC0*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:001BC1*
+ ID_OUI_FROM_DATABASE=HOLUX Technology, Inc.
+
+OUI:001BC2*
+ ID_OUI_FROM_DATABASE=Integrated Control Technology Limitied
+
+OUI:001BC3*
+ ID_OUI_FROM_DATABASE=Mobisolution Co.,Ltd
+
+OUI:001BC4*
+ ID_OUI_FROM_DATABASE=Ultratec, Inc.
+
+OUI:001BC5*
+ ID_OUI_FROM_DATABASE=IEEE Registration Authority
+
+OUI:001BC6*
+ ID_OUI_FROM_DATABASE=Strato Rechenzentrum AG
+
+OUI:001BC7*
+ ID_OUI_FROM_DATABASE=StarVedia Technology Inc.
+
+OUI:001BC8*
+ ID_OUI_FROM_DATABASE=MIURA CO.,LTD
+
+OUI:001BC9*
+ ID_OUI_FROM_DATABASE=FSN DISPLAY INC
+
+OUI:001BCA*
+ ID_OUI_FROM_DATABASE=Beijing Run Technology LTD. Company
+
+OUI:001BCB*
+ ID_OUI_FROM_DATABASE=PEMPEK SYSTEMS PTY LTD
+
+OUI:001BCC*
+ ID_OUI_FROM_DATABASE=KINGTEK CCTV ALLIANCE CO., LTD.
+
+OUI:001BCD*
+ ID_OUI_FROM_DATABASE=DAVISCOMMS (S) PTE LTD
+
+OUI:001BCE*
+ ID_OUI_FROM_DATABASE=Measurement Devices Ltd
+
+OUI:001BCF*
+ ID_OUI_FROM_DATABASE=Dataupia Corporation
+
+OUI:001BD0*
+ ID_OUI_FROM_DATABASE=IDENTEC SOLUTIONS
+
+OUI:001BD1*
+ ID_OUI_FROM_DATABASE=SOGESTMATIC
+
+OUI:001BD2*
+ ID_OUI_FROM_DATABASE=ULTRA-X ASIA PACIFIC Inc.
+
+OUI:001BD3*
+ ID_OUI_FROM_DATABASE=Matsushita Electric Panasonic AVC
+
+OUI:001BD4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001BD5*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001BD6*
+ ID_OUI_FROM_DATABASE=Kelvin Hughes Ltd
+
+OUI:001BD7*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta, A Cisco Company
+
+OUI:001BD8*
+ ID_OUI_FROM_DATABASE=DVTel LTD
+
+OUI:001BD9*
+ ID_OUI_FROM_DATABASE=Edgewater Computer Systems
+
+OUI:001BDA*
+ ID_OUI_FROM_DATABASE=UTStarcom Inc
+
+OUI:001BDB*
+ ID_OUI_FROM_DATABASE=Valeo VECS
+
+OUI:001BDC*
+ ID_OUI_FROM_DATABASE=Vencer Co., Ltd.
+
+OUI:001BDD*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001BDE*
+ ID_OUI_FROM_DATABASE=Renkus-Heinz, Inc.
+
+OUI:001BDF*
+ ID_OUI_FROM_DATABASE=Iskra MIS
+
+OUI:001BE0*
+ ID_OUI_FROM_DATABASE=TELENOT ELECTRONIC GmbH
+
+OUI:001BE1*
+ ID_OUI_FROM_DATABASE=ViaLogy
+
+OUI:001BE2*
+ ID_OUI_FROM_DATABASE=AhnLab,Inc.
+
+OUI:001BE3*
+ ID_OUI_FROM_DATABASE=Health Hero Network, Inc.
+
+OUI:001BE4*
+ ID_OUI_FROM_DATABASE=TOWNET SRL
+
+OUI:001BE5*
+ ID_OUI_FROM_DATABASE=802automation Limited
+
+OUI:001BE6*
+ ID_OUI_FROM_DATABASE=VR AG
+
+OUI:001BE7*
+ ID_OUI_FROM_DATABASE=Postek Electronics Co., Ltd.
+
+OUI:001BE8*
+ ID_OUI_FROM_DATABASE=Ultratronik GmbH
+
+OUI:001BE9*
+ ID_OUI_FROM_DATABASE=Broadcom Corporation
+
+OUI:001BEA*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001BEB*
+ ID_OUI_FROM_DATABASE=DMP Electronics INC.
+
+OUI:001BEC*
+ ID_OUI_FROM_DATABASE=Netio Technologies Co., Ltd
+
+OUI:001BED*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc
+
+OUI:001BEE*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001BEF*
+ ID_OUI_FROM_DATABASE=Blossoms Digital Technology Co.,Ltd.
+
+OUI:001BF0*
+ ID_OUI_FROM_DATABASE=Value Platforms Limited
+
+OUI:001BF1*
+ ID_OUI_FROM_DATABASE=Nanjing SilverNet Software Co., Ltd.
+
+OUI:001BF2*
+ ID_OUI_FROM_DATABASE=KWORLD COMPUTER CO., LTD
+
+OUI:001BF3*
+ ID_OUI_FROM_DATABASE=TRANSRADIO SenderSysteme Berlin AG
+
+OUI:001BF4*
+ ID_OUI_FROM_DATABASE=KENWIN INDUSTRIAL(HK) LTD.
+
+OUI:001BF5*
+ ID_OUI_FROM_DATABASE=Tellink Sistemas de Telecomunicación S.L.
+
+OUI:001BF6*
+ ID_OUI_FROM_DATABASE=CONWISE Technology Corporation Ltd.
+
+OUI:001BF7*
+ ID_OUI_FROM_DATABASE=Lund IP Products AB
+
+OUI:001BF8*
+ ID_OUI_FROM_DATABASE=Digitrax Inc.
+
+OUI:001BF9*
+ ID_OUI_FROM_DATABASE=Intellitect Water Ltd
+
+OUI:001BFA*
+ ID_OUI_FROM_DATABASE=G.i.N. mbH
+
+OUI:001BFB*
+ ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd
+
+OUI:001BFC*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:001BFD*
+ ID_OUI_FROM_DATABASE=Dignsys Inc.
+
+OUI:001BFE*
+ ID_OUI_FROM_DATABASE=Zavio Inc.
+
+OUI:001BFF*
+ ID_OUI_FROM_DATABASE=Millennia Media inc.
+
+OUI:001C00*
+ ID_OUI_FROM_DATABASE=Entry Point, LLC
+
+OUI:001C01*
+ ID_OUI_FROM_DATABASE=ABB Oy Drives
+
+OUI:001C02*
+ ID_OUI_FROM_DATABASE=Pano Logic
+
+OUI:001C03*
+ ID_OUI_FROM_DATABASE=Betty TV Technology AG
+
+OUI:001C04*
+ ID_OUI_FROM_DATABASE=Airgain, Inc.
+
+OUI:001C05*
+ ID_OUI_FROM_DATABASE=Nonin Medical Inc.
+
+OUI:001C06*
+ ID_OUI_FROM_DATABASE=Siemens Numerical Control Ltd., Nanjing
+
+OUI:001C07*
+ ID_OUI_FROM_DATABASE=Cwlinux Limited
+
+OUI:001C08*
+ ID_OUI_FROM_DATABASE=Echo360, Inc.
+
+OUI:001C09*
+ ID_OUI_FROM_DATABASE=SAE Electronic Co.,Ltd.
+
+OUI:001C0A*
+ ID_OUI_FROM_DATABASE=Shenzhen AEE Technology Co.,Ltd.
+
+OUI:001C0B*
+ ID_OUI_FROM_DATABASE=SmartAnt Telecom
+
+OUI:001C0C*
+ ID_OUI_FROM_DATABASE=TANITA Corporation
+
+OUI:001C0D*
+ ID_OUI_FROM_DATABASE=G-Technology, Inc.
+
+OUI:001C0E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001C0F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001C10*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:001C11*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001C12*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001C13*
+ ID_OUI_FROM_DATABASE=OPTSYS TECHNOLOGY CO., LTD.
+
+OUI:001C14*
+ ID_OUI_FROM_DATABASE=VMware, Inc
+
+OUI:001C15*
+ ID_OUI_FROM_DATABASE=TXP Corporation
+
+OUI:001C16*
+ ID_OUI_FROM_DATABASE=ThyssenKrupp Elevator
+
+OUI:001C17*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001C18*
+ ID_OUI_FROM_DATABASE=Sicert S.r.L.
+
+OUI:001C19*
+ ID_OUI_FROM_DATABASE=secunet Security Networks AG
+
+OUI:001C1A*
+ ID_OUI_FROM_DATABASE=Thomas Instrumentation, Inc
+
+OUI:001C1B*
+ ID_OUI_FROM_DATABASE=Hyperstone GmbH
+
+OUI:001C1C*
+ ID_OUI_FROM_DATABASE=Center Communication Systems GmbH
+
+OUI:001C1D*
+ ID_OUI_FROM_DATABASE=CHENZHOU GOSPELL DIGITAL TECHNOLOGY CO.,LTD
+
+OUI:001C1E*
+ ID_OUI_FROM_DATABASE=emtrion GmbH
+
+OUI:001C1F*
+ ID_OUI_FROM_DATABASE=Quest Retail Technology Pty Ltd
+
+OUI:001C20*
+ ID_OUI_FROM_DATABASE=CLB Benelux
+
+OUI:001C21*
+ ID_OUI_FROM_DATABASE=Nucsafe Inc.
+
+OUI:001C22*
+ ID_OUI_FROM_DATABASE=Aeris Elettronica s.r.l.
+
+OUI:001C23*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:001C24*
+ ID_OUI_FROM_DATABASE=Formosa Wireless Systems Corp.
+
+OUI:001C25*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:001C26*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:001C27*
+ ID_OUI_FROM_DATABASE=Sunell Electronics Co.
+
+OUI:001C28*
+ ID_OUI_FROM_DATABASE=Sphairon Technologies GmbH
+
+OUI:001C29*
+ ID_OUI_FROM_DATABASE=CORE DIGITAL ELECTRONICS CO., LTD
+
+OUI:001C2A*
+ ID_OUI_FROM_DATABASE=Envisacor Technologies Inc.
+
+OUI:001C2B*
+ ID_OUI_FROM_DATABASE=Alertme.com Limited
+
+OUI:001C2C*
+ ID_OUI_FROM_DATABASE=Synapse
+
+OUI:001C2D*
+ ID_OUI_FROM_DATABASE=FlexRadio Systems
+
+OUI:001C2E*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:001C2F*
+ ID_OUI_FROM_DATABASE=Pfister GmbH
+
+OUI:001C30*
+ ID_OUI_FROM_DATABASE=Mode Lighting (UK ) Ltd.
+
+OUI:001C31*
+ ID_OUI_FROM_DATABASE=Mobile XP Technology Co., LTD
+
+OUI:001C32*
+ ID_OUI_FROM_DATABASE=Telian Corporation
+
+OUI:001C33*
+ ID_OUI_FROM_DATABASE=Sutron
+
+OUI:001C34*
+ ID_OUI_FROM_DATABASE=HUEY CHIAO INTERNATIONAL CO., LTD.
+
+OUI:001C35*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001C36*
+ ID_OUI_FROM_DATABASE=iNEWiT NV
+
+OUI:001C37*
+ ID_OUI_FROM_DATABASE=Callpod, Inc.
+
+OUI:001C38*
+ ID_OUI_FROM_DATABASE=Bio-Rad Laboratories, Inc.
+
+OUI:001C39*
+ ID_OUI_FROM_DATABASE=S Netsystems Inc.
+
+OUI:001C3A*
+ ID_OUI_FROM_DATABASE=Element Labs, Inc.
+
+OUI:001C3B*
+ ID_OUI_FROM_DATABASE=AmRoad Technology Inc.
+
+OUI:001C3C*
+ ID_OUI_FROM_DATABASE=Seon Design Inc.
+
+OUI:001C3D*
+ ID_OUI_FROM_DATABASE=WaveStorm
+
+OUI:001C3E*
+ ID_OUI_FROM_DATABASE=ECKey Limited
+
+OUI:001C3F*
+ ID_OUI_FROM_DATABASE=International Police Technologies, Inc.
+
+OUI:001C40*
+ ID_OUI_FROM_DATABASE=VDG-Security bv
+
+OUI:001C41*
+ ID_OUI_FROM_DATABASE=scemtec Transponder Technology GmbH
+
+OUI:001C42*
+ ID_OUI_FROM_DATABASE=Parallels, Inc.
+
+OUI:001C43*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001C44*
+ ID_OUI_FROM_DATABASE=Bosch Security Systems BV
+
+OUI:001C45*
+ ID_OUI_FROM_DATABASE=Chenbro Micom Co., Ltd.
+
+OUI:001C46*
+ ID_OUI_FROM_DATABASE=QTUM
+
+OUI:001C47*
+ ID_OUI_FROM_DATABASE=Hangzhou Hollysys Automation Co., Ltd
+
+OUI:001C48*
+ ID_OUI_FROM_DATABASE=WiDeFi, Inc.
+
+OUI:001C49*
+ ID_OUI_FROM_DATABASE=Zoltan Technology Inc.
+
+OUI:001C4A*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:001C4B*
+ ID_OUI_FROM_DATABASE=Gener8, Inc.
+
+OUI:001C4C*
+ ID_OUI_FROM_DATABASE=Petrotest Instruments
+
+OUI:001C4D*
+ ID_OUI_FROM_DATABASE=Zeemote Technology Inc. (part of Aplix).
+
+OUI:001C4E*
+ ID_OUI_FROM_DATABASE=TASA International Limited
+
+OUI:001C4F*
+ ID_OUI_FROM_DATABASE=MACAB AB
+
+OUI:001C50*
+ ID_OUI_FROM_DATABASE=TCL Technoly Electronics(Huizhou)Co.,Ltd
+
+OUI:001C51*
+ ID_OUI_FROM_DATABASE=Celeno Communications
+
+OUI:001C52*
+ ID_OUI_FROM_DATABASE=VISIONEE SRL
+
+OUI:001C53*
+ ID_OUI_FROM_DATABASE=Synergy Lighting Controls
+
+OUI:001C54*
+ ID_OUI_FROM_DATABASE=Hillstone Networks Inc
+
+OUI:001C55*
+ ID_OUI_FROM_DATABASE=Shenzhen Kaifa Technology Co.
+
+OUI:001C56*
+ ID_OUI_FROM_DATABASE=Pado Systems, Inc.
+
+OUI:001C57*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001C58*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001C59*
+ ID_OUI_FROM_DATABASE=DEVON IT
+
+OUI:001C5A*
+ ID_OUI_FROM_DATABASE=Advanced Relay Corporation
+
+OUI:001C5B*
+ ID_OUI_FROM_DATABASE=Chubb Electronic Security Systems Ltd
+
+OUI:001C5C*
+ ID_OUI_FROM_DATABASE=Integrated Medical Systems, Inc.
+
+OUI:001C5D*
+ ID_OUI_FROM_DATABASE=Leica Microsystems
+
+OUI:001C5E*
+ ID_OUI_FROM_DATABASE=ASTON France
+
+OUI:001C5F*
+ ID_OUI_FROM_DATABASE=Winland Electronics, Inc.
+
+OUI:001C60*
+ ID_OUI_FROM_DATABASE=CSP Frontier Technologies,Inc.
+
+OUI:001C61*
+ ID_OUI_FROM_DATABASE=Galaxy  Microsystems LImited
+
+OUI:001C62*
+ ID_OUI_FROM_DATABASE=LG Electronics Inc
+
+OUI:001C63*
+ ID_OUI_FROM_DATABASE=TRUEN
+
+OUI:001C64*
+ ID_OUI_FROM_DATABASE=Cellnet+Hunt
+
+OUI:001C65*
+ ID_OUI_FROM_DATABASE=JoeScan, Inc.
+
+OUI:001C66*
+ ID_OUI_FROM_DATABASE=UCAMP CO.,LTD
+
+OUI:001C67*
+ ID_OUI_FROM_DATABASE=Pumpkin Networks, Inc.
+
+OUI:001C68*
+ ID_OUI_FROM_DATABASE=Anhui Sun Create Electronics Co., Ltd
+
+OUI:001C69*
+ ID_OUI_FROM_DATABASE=Packet Vision Ltd
+
+OUI:001C6A*
+ ID_OUI_FROM_DATABASE=Weiss Engineering Ltd.
+
+OUI:001C6B*
+ ID_OUI_FROM_DATABASE=COVAX  Co. Ltd
+
+OUI:001C6C*
+ ID_OUI_FROM_DATABASE=Jabil Circuit (Guangzhou) Limited
+
+OUI:001C6D*
+ ID_OUI_FROM_DATABASE=KYOHRITSU ELECTRONIC INDUSTRY CO., LTD.
+
+OUI:001C6E*
+ ID_OUI_FROM_DATABASE=Newbury Networks, Inc.
+
+OUI:001C6F*
+ ID_OUI_FROM_DATABASE=Emfit Ltd
+
+OUI:001C70*
+ ID_OUI_FROM_DATABASE=NOVACOMM LTDA
+
+OUI:001C71*
+ ID_OUI_FROM_DATABASE=Emergent Electronics
+
+OUI:001C72*
+ ID_OUI_FROM_DATABASE=Mayer & Cie GmbH & Co KG
+
+OUI:001C73*
+ ID_OUI_FROM_DATABASE=Arista Networks, Inc.
+
+OUI:001C74*
+ ID_OUI_FROM_DATABASE=Syswan Technologies Inc.
+
+OUI:001C75*
+ ID_OUI_FROM_DATABASE=RF Systems GmbH
+
+OUI:001C76*
+ ID_OUI_FROM_DATABASE=The Wandsworth Group Ltd
+
+OUI:001C77*
+ ID_OUI_FROM_DATABASE=Prodys
+
+OUI:001C78*
+ ID_OUI_FROM_DATABASE=WYPLAY SAS
+
+OUI:001C79*
+ ID_OUI_FROM_DATABASE=Cohesive Financial Technologies LLC
+
+OUI:001C7A*
+ ID_OUI_FROM_DATABASE=Perfectone Netware Company Ltd
+
+OUI:001C7B*
+ ID_OUI_FROM_DATABASE=Castlenet Technology Inc.
+
+OUI:001C7C*
+ ID_OUI_FROM_DATABASE=PERQ SYSTEMS CORPORATION
+
+OUI:001C7D*
+ ID_OUI_FROM_DATABASE=Excelpoint Manufacturing Pte Ltd
+
+OUI:001C7E*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:001C7F*
+ ID_OUI_FROM_DATABASE=Check Point Software Technologies
+
+OUI:001C80*
+ ID_OUI_FROM_DATABASE=New Business Division/Rhea-Information CO., LTD.
+
+OUI:001C81*
+ ID_OUI_FROM_DATABASE=NextGen Venturi LTD
+
+OUI:001C82*
+ ID_OUI_FROM_DATABASE=Genew Technologies
+
+OUI:001C83*
+ ID_OUI_FROM_DATABASE=New Level Telecom Co., Ltd.
+
+OUI:001C84*
+ ID_OUI_FROM_DATABASE=STL Solution Co.,Ltd.
+
+OUI:001C85*
+ ID_OUI_FROM_DATABASE=Eunicorn
+
+OUI:001C86*
+ ID_OUI_FROM_DATABASE=Cranite Systems, Inc.
+
+OUI:001C87*
+ ID_OUI_FROM_DATABASE=Uriver Inc.
+
+OUI:001C88*
+ ID_OUI_FROM_DATABASE=TRANSYSTEM INC.
+
+OUI:001C89*
+ ID_OUI_FROM_DATABASE=Force Communications, Inc.
+
+OUI:001C8A*
+ ID_OUI_FROM_DATABASE=Cirrascale Corporation
+
+OUI:001C8B*
+ ID_OUI_FROM_DATABASE=MJ Innovations Ltd.
+
+OUI:001C8C*
+ ID_OUI_FROM_DATABASE=DIAL TECHNOLOGY LTD.
+
+OUI:001C8D*
+ ID_OUI_FROM_DATABASE=Mesa Imaging
+
+OUI:001C8E*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:001C8F*
+ ID_OUI_FROM_DATABASE=Advanced Electronic Design, Inc.
+
+OUI:001C90*
+ ID_OUI_FROM_DATABASE=Empacket Corporation
+
+OUI:001C91*
+ ID_OUI_FROM_DATABASE=Gefen Inc.
+
+OUI:001C92*
+ ID_OUI_FROM_DATABASE=Tervela
+
+OUI:001C93*
+ ID_OUI_FROM_DATABASE=ExaDigm Inc
+
+OUI:001C94*
+ ID_OUI_FROM_DATABASE=LI-COR Biosciences
+
+OUI:001C95*
+ ID_OUI_FROM_DATABASE=Opticomm Corporation
+
+OUI:001C96*
+ ID_OUI_FROM_DATABASE=Linkwise Technology Pte Ltd
+
+OUI:001C97*
+ ID_OUI_FROM_DATABASE=Enzytek Technology Inc.,
+
+OUI:001C98*
+ ID_OUI_FROM_DATABASE=LUCKY TECHNOLOGY (HK) COMPANY LIMITED
+
+OUI:001C99*
+ ID_OUI_FROM_DATABASE=Shunra Software Ltd.
+
+OUI:001C9A*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001C9B*
+ ID_OUI_FROM_DATABASE=FEIG ELECTRONIC GmbH
+
+OUI:001C9C*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001C9D*
+ ID_OUI_FROM_DATABASE=Liecthi AG
+
+OUI:001C9E*
+ ID_OUI_FROM_DATABASE=Dualtech IT AB
+
+OUI:001C9F*
+ ID_OUI_FROM_DATABASE=Razorstream, LLC
+
+OUI:001CA0*
+ ID_OUI_FROM_DATABASE=Production Resource Group, LLC
+
+OUI:001CA1*
+ ID_OUI_FROM_DATABASE=AKAMAI TECHNOLOGIES, INC.
+
+OUI:001CA2*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:001CA3*
+ ID_OUI_FROM_DATABASE=Terra
+
+OUI:001CA4*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:001CA5*
+ ID_OUI_FROM_DATABASE=Zygo Corporation
+
+OUI:001CA6*
+ ID_OUI_FROM_DATABASE=Win4NET
+
+OUI:001CA7*
+ ID_OUI_FROM_DATABASE=International Quartz Limited
+
+OUI:001CA8*
+ ID_OUI_FROM_DATABASE=AirTies Wireless Networks
+
+OUI:001CA9*
+ ID_OUI_FROM_DATABASE=Audiomatica Srl
+
+OUI:001CAA*
+ ID_OUI_FROM_DATABASE=Bellon Pty Ltd
+
+OUI:001CAB*
+ ID_OUI_FROM_DATABASE=Meyer Sound Laboratories, Inc.
+
+OUI:001CAC*
+ ID_OUI_FROM_DATABASE=Qniq Technology Corp.
+
+OUI:001CAD*
+ ID_OUI_FROM_DATABASE=Wuhan Telecommunication Devices Co.,Ltd
+
+OUI:001CAE*
+ ID_OUI_FROM_DATABASE=WiChorus, Inc.
+
+OUI:001CAF*
+ ID_OUI_FROM_DATABASE=Plato Networks Inc.
+
+OUI:001CB0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001CB1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001CB2*
+ ID_OUI_FROM_DATABASE=BPT SPA
+
+OUI:001CB3*
+ ID_OUI_FROM_DATABASE=APPLE, INC
+
+OUI:001CB4*
+ ID_OUI_FROM_DATABASE=Iridium Satellite LLC
+
+OUI:001CB5*
+ ID_OUI_FROM_DATABASE=Neihua Network Technology Co.,LTD.(NHN)
+
+OUI:001CB6*
+ ID_OUI_FROM_DATABASE=Duzon CNT Co., Ltd.
+
+OUI:001CB7*
+ ID_OUI_FROM_DATABASE=USC DigiArk Corporation
+
+OUI:001CB8*
+ ID_OUI_FROM_DATABASE=CBC Co., Ltd
+
+OUI:001CB9*
+ ID_OUI_FROM_DATABASE=KWANG SUNG ELECTRONICS CO., LTD.
+
+OUI:001CBA*
+ ID_OUI_FROM_DATABASE=VerScient, Inc.
+
+OUI:001CBB*
+ ID_OUI_FROM_DATABASE=MusicianLink
+
+OUI:001CBC*
+ ID_OUI_FROM_DATABASE=CastGrabber, LLC
+
+OUI:001CBD*
+ ID_OUI_FROM_DATABASE=Ezze Mobile Tech., Inc.
+
+OUI:001CBE*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001CBF*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001CC0*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001CC1*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001CC2*
+ ID_OUI_FROM_DATABASE=Part II Research, Inc.
+
+OUI:001CC3*
+ ID_OUI_FROM_DATABASE=Pace plc
+
+OUI:001CC4*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001CC5*
+ ID_OUI_FROM_DATABASE=3COM LTD
+
+OUI:001CC6*
+ ID_OUI_FROM_DATABASE=ProStor Systems
+
+OUI:001CC7*
+ ID_OUI_FROM_DATABASE=Rembrandt Technologies, LLC d/b/a REMSTREAM
+
+OUI:001CC8*
+ ID_OUI_FROM_DATABASE=INDUSTRONIC Industrie-Electronic GmbH & Co. KG
+
+OUI:001CC9*
+ ID_OUI_FROM_DATABASE=Kaise Electronic Technology Co., Ltd.
+
+OUI:001CCA*
+ ID_OUI_FROM_DATABASE=Shanghai Gaozhi Science & Technology Development Co.
+
+OUI:001CCB*
+ ID_OUI_FROM_DATABASE=Forth Corporation Public Company Limited
+
+OUI:001CCC*
+ ID_OUI_FROM_DATABASE=Research In Motion Limited
+
+OUI:001CCD*
+ ID_OUI_FROM_DATABASE=Alektrona Corporation
+
+OUI:001CCE*
+ ID_OUI_FROM_DATABASE=By Techdesign
+
+OUI:001CCF*
+ ID_OUI_FROM_DATABASE=LIMETEK
+
+OUI:001CD0*
+ ID_OUI_FROM_DATABASE=Circleone Co.,Ltd.
+
+OUI:001CD1*
+ ID_OUI_FROM_DATABASE=Waves Audio LTD
+
+OUI:001CD2*
+ ID_OUI_FROM_DATABASE=King Champion (Hong Kong) Limited
+
+OUI:001CD3*
+ ID_OUI_FROM_DATABASE=ZP Engineering SEL
+
+OUI:001CD4*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001CD5*
+ ID_OUI_FROM_DATABASE=ZeeVee, Inc.
+
+OUI:001CD6*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001CD7*
+ ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH
+
+OUI:001CD8*
+ ID_OUI_FROM_DATABASE=BlueAnt Wireless
+
+OUI:001CD9*
+ ID_OUI_FROM_DATABASE=GlobalTop Technology Inc.
+
+OUI:001CDA*
+ ID_OUI_FROM_DATABASE=Exegin Technologies Limited
+
+OUI:001CDB*
+ ID_OUI_FROM_DATABASE=CARPOINT CO.,LTD
+
+OUI:001CDC*
+ ID_OUI_FROM_DATABASE=Custom Computer Services, Inc.
+
+OUI:001CDD*
+ ID_OUI_FROM_DATABASE=COWBELL ENGINEERING CO., LTD.
+
+OUI:001CDE*
+ ID_OUI_FROM_DATABASE=Interactive Multimedia eXchange Inc.
+
+OUI:001CDF*
+ ID_OUI_FROM_DATABASE=Belkin International Inc.
+
+OUI:001CE0*
+ ID_OUI_FROM_DATABASE=DASAN TPS
+
+OUI:001CE1*
+ ID_OUI_FROM_DATABASE=INDRA SISTEMAS, S.A.
+
+OUI:001CE2*
+ ID_OUI_FROM_DATABASE=Attero Tech, LLC.
+
+OUI:001CE3*
+ ID_OUI_FROM_DATABASE=Optimedical Systems
+
+OUI:001CE4*
+ ID_OUI_FROM_DATABASE=EleSy JSC
+
+OUI:001CE5*
+ ID_OUI_FROM_DATABASE=MBS Electronic Systems GmbH
+
+OUI:001CE6*
+ ID_OUI_FROM_DATABASE=INNES
+
+OUI:001CE7*
+ ID_OUI_FROM_DATABASE=Rocon PLC Research Centre
+
+OUI:001CE8*
+ ID_OUI_FROM_DATABASE=Cummins Inc
+
+OUI:001CE9*
+ ID_OUI_FROM_DATABASE=Galaxy Technology Limited
+
+OUI:001CEA*
+ ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc
+
+OUI:001CEB*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001CEC*
+ ID_OUI_FROM_DATABASE=Mobilesoft (Aust.) Pty Ltd
+
+OUI:001CED*
+ ID_OUI_FROM_DATABASE=ENVIRONNEMENT SA
+
+OUI:001CEE*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
+
+OUI:001CEF*
+ ID_OUI_FROM_DATABASE=Primax Electronics LTD
+
+OUI:001CF0*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:001CF1*
+ ID_OUI_FROM_DATABASE=SUPoX Technology Co. , LTD.
+
+OUI:001CF2*
+ ID_OUI_FROM_DATABASE=Tenlon Technology Co.,Ltd.
+
+OUI:001CF3*
+ ID_OUI_FROM_DATABASE=EVS BROADCAST EQUIPMENT
+
+OUI:001CF4*
+ ID_OUI_FROM_DATABASE=Media Technology Systems Inc
+
+OUI:001CF5*
+ ID_OUI_FROM_DATABASE=Wiseblue Technology Limited
+
+OUI:001CF6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001CF7*
+ ID_OUI_FROM_DATABASE=AudioScience
+
+OUI:001CF8*
+ ID_OUI_FROM_DATABASE=Parade Technologies, Ltd.
+
+OUI:001CF9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001CFA*
+ ID_OUI_FROM_DATABASE=Alarm.com
+
+OUI:001CFB*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001CFC*
+ ID_OUI_FROM_DATABASE=Suminet Communication Technologies (Shanghai) Co., Ltd.
+
+OUI:001CFD*
+ ID_OUI_FROM_DATABASE=Universal Electronics
+
+OUI:001CFE*
+ ID_OUI_FROM_DATABASE=Quartics Inc
+
+OUI:001CFF*
+ ID_OUI_FROM_DATABASE=Napera Networks Inc
+
+OUI:001D00*
+ ID_OUI_FROM_DATABASE=Brivo Systems, LLC
+
+OUI:001D01*
+ ID_OUI_FROM_DATABASE=Neptune Digital
+
+OUI:001D02*
+ ID_OUI_FROM_DATABASE=Cybertech Telecom Development
+
+OUI:001D03*
+ ID_OUI_FROM_DATABASE=Design Solutions Inc.
+
+OUI:001D04*
+ ID_OUI_FROM_DATABASE=Zipit Wireless, Inc.
+
+OUI:001D05*
+ ID_OUI_FROM_DATABASE=iLight
+
+OUI:001D06*
+ ID_OUI_FROM_DATABASE=HM Electronics, Inc.
+
+OUI:001D07*
+ ID_OUI_FROM_DATABASE=Shenzhen Sang Fei Consumer Communications Co.,Ltd
+
+OUI:001D08*
+ ID_OUI_FROM_DATABASE=JIANGSU YINHE ELECTRONICS CO., LTD
+
+OUI:001D09*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:001D0A*
+ ID_OUI_FROM_DATABASE=Davis Instruments, Inc.
+
+OUI:001D0B*
+ ID_OUI_FROM_DATABASE=Power Standards Lab
+
+OUI:001D0C*
+ ID_OUI_FROM_DATABASE=MobileCompia
+
+OUI:001D0D*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment inc.
+
+OUI:001D0E*
+ ID_OUI_FROM_DATABASE=Agapha Technology co., Ltd.
+
+OUI:001D0F*
+ ID_OUI_FROM_DATABASE=TP-LINK Technologies Co., Ltd.
+
+OUI:001D10*
+ ID_OUI_FROM_DATABASE=LightHaus Logic, Inc.
+
+OUI:001D11*
+ ID_OUI_FROM_DATABASE=Analogue & Micro Ltd
+
+OUI:001D12*
+ ID_OUI_FROM_DATABASE=ROHM CO., LTD.
+
+OUI:001D13*
+ ID_OUI_FROM_DATABASE=NextGTV
+
+OUI:001D14*
+ ID_OUI_FROM_DATABASE=SPERADTONE INFORMATION TECHNOLOGY LIMITED
+
+OUI:001D15*
+ ID_OUI_FROM_DATABASE=Shenzhen Dolphin Electronic Co., Ltd
+
+OUI:001D16*
+ ID_OUI_FROM_DATABASE=Efixo
+
+OUI:001D17*
+ ID_OUI_FROM_DATABASE=Digital Sky Corporation
+
+OUI:001D18*
+ ID_OUI_FROM_DATABASE=Power Innovation GmbH
+
+OUI:001D19*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:001D1A*
+ ID_OUI_FROM_DATABASE=OvisLink S.A.
+
+OUI:001D1B*
+ ID_OUI_FROM_DATABASE=Sangean Electronics Inc.
+
+OUI:001D1C*
+ ID_OUI_FROM_DATABASE=Gennet s.a.
+
+OUI:001D1D*
+ ID_OUI_FROM_DATABASE=Inter-M Corporation
+
+OUI:001D1E*
+ ID_OUI_FROM_DATABASE=KYUSHU TEN CO.,LTD
+
+OUI:001D1F*
+ ID_OUI_FROM_DATABASE=Siauliu Tauro Televizoriai, JSC
+
+OUI:001D20*
+ ID_OUI_FROM_DATABASE=COMTREND CO.
+
+OUI:001D21*
+ ID_OUI_FROM_DATABASE=Alcad SL
+
+OUI:001D22*
+ ID_OUI_FROM_DATABASE=Foss Analytical A/S
+
+OUI:001D23*
+ ID_OUI_FROM_DATABASE=SENSUS
+
+OUI:001D24*
+ ID_OUI_FROM_DATABASE=Aclara Power-Line Systems Inc.
+
+OUI:001D25*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001D26*
+ ID_OUI_FROM_DATABASE=Rockridgesound Technology Co.
+
+OUI:001D27*
+ ID_OUI_FROM_DATABASE=NAC-INTERCOM
+
+OUI:001D28*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:001D29*
+ ID_OUI_FROM_DATABASE=Doro AB
+
+OUI:001D2A*
+ ID_OUI_FROM_DATABASE=Tideway Electronic LTD
+
+OUI:001D2B*
+ ID_OUI_FROM_DATABASE=Wuhan Pont Technology CO. , LTD
+
+OUI:001D2C*
+ ID_OUI_FROM_DATABASE=Wavetrend Technologies (Pty) Limited
+
+OUI:001D2D*
+ ID_OUI_FROM_DATABASE=Pylone, Inc.
+
+OUI:001D2E*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:001D2F*
+ ID_OUI_FROM_DATABASE=QuantumVision Corporation
+
+OUI:001D30*
+ ID_OUI_FROM_DATABASE=YX Wireless S.A.
+
+OUI:001D31*
+ ID_OUI_FROM_DATABASE=HIGHPRO INTERNATIONAL R&D CO,.LTD.
+
+OUI:001D32*
+ ID_OUI_FROM_DATABASE=Longkay Communication & Technology (Shanghai) Co. Ltd
+
+OUI:001D33*
+ ID_OUI_FROM_DATABASE=Maverick Systems Inc.
+
+OUI:001D34*
+ ID_OUI_FROM_DATABASE=SYRIS Technology Corp
+
+OUI:001D35*
+ ID_OUI_FROM_DATABASE=Viconics Electronics Inc.
+
+OUI:001D36*
+ ID_OUI_FROM_DATABASE=ELECTRONICS CORPORATION OF INDIA LIMITED
+
+OUI:001D37*
+ ID_OUI_FROM_DATABASE=Thales-Panda Transportation System
+
+OUI:001D38*
+ ID_OUI_FROM_DATABASE=Seagate Technology
+
+OUI:001D39*
+ ID_OUI_FROM_DATABASE=MOOHADIGITAL CO., LTD
+
+OUI:001D3A*
+ ID_OUI_FROM_DATABASE=mh acoustics LLC
+
+OUI:001D3B*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001D3C*
+ ID_OUI_FROM_DATABASE=Muscle Corporation
+
+OUI:001D3D*
+ ID_OUI_FROM_DATABASE=Avidyne Corporation
+
+OUI:001D3E*
+ ID_OUI_FROM_DATABASE=SAKA TECHNO SCIENCE CO.,LTD
+
+OUI:001D3F*
+ ID_OUI_FROM_DATABASE=Mitron Pty Ltd
+
+OUI:001D40*
+ ID_OUI_FROM_DATABASE=Living Independently Group, Inc.
+
+OUI:001D41*
+ ID_OUI_FROM_DATABASE=Hardy Instruments
+
+OUI:001D42*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001D43*
+ ID_OUI_FROM_DATABASE=Shenzhen G-link Digital Technology Co., Ltd.
+
+OUI:001D44*
+ ID_OUI_FROM_DATABASE=Krohne
+
+OUI:001D45*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001D46*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001D47*
+ ID_OUI_FROM_DATABASE=Covote GmbH & Co KG
+
+OUI:001D48*
+ ID_OUI_FROM_DATABASE=Sensor-Technik Wiedemann GmbH
+
+OUI:001D49*
+ ID_OUI_FROM_DATABASE=Innovation Wireless Inc.
+
+OUI:001D4A*
+ ID_OUI_FROM_DATABASE=Carestream Health, Inc.
+
+OUI:001D4B*
+ ID_OUI_FROM_DATABASE=Grid Connect Inc.
+
+OUI:001D4C*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:001D4D*
+ ID_OUI_FROM_DATABASE=Adaptive Recognition Hungary, Inc
+
+OUI:001D4E*
+ ID_OUI_FROM_DATABASE=TCM Mobile LLC
+
+OUI:001D4F*
+ ID_OUI_FROM_DATABASE=Apple Computer Inc.
+
+OUI:001D50*
+ ID_OUI_FROM_DATABASE=SPINETIX SA
+
+OUI:001D51*
+ ID_OUI_FROM_DATABASE=Babcock & Wilcox Power Generation Group, Inc
+
+OUI:001D52*
+ ID_OUI_FROM_DATABASE=Defzone B.V.
+
+OUI:001D53*
+ ID_OUI_FROM_DATABASE=S&O Electronics (Malaysia) Sdn. Bhd.
+
+OUI:001D54*
+ ID_OUI_FROM_DATABASE=Sunnic Technology & Merchandise INC.
+
+OUI:001D55*
+ ID_OUI_FROM_DATABASE=ZANTAZ, Inc
+
+OUI:001D56*
+ ID_OUI_FROM_DATABASE=Kramer Electronics Ltd.
+
+OUI:001D57*
+ ID_OUI_FROM_DATABASE=CAETEC Messtechnik
+
+OUI:001D58*
+ ID_OUI_FROM_DATABASE=CQ Inc
+
+OUI:001D59*
+ ID_OUI_FROM_DATABASE=Mitra Energy & Infrastructure
+
+OUI:001D5A*
+ ID_OUI_FROM_DATABASE=2Wire Inc.
+
+OUI:001D5B*
+ ID_OUI_FROM_DATABASE=Tecvan Informática Ltda
+
+OUI:001D5C*
+ ID_OUI_FROM_DATABASE=Tom Communication Industrial Co.,Ltd.
+
+OUI:001D5D*
+ ID_OUI_FROM_DATABASE=Control Dynamics Pty. Ltd.
+
+OUI:001D5E*
+ ID_OUI_FROM_DATABASE=COMING MEDIA CORP.
+
+OUI:001D5F*
+ ID_OUI_FROM_DATABASE=OverSpeed SARL
+
+OUI:001D60*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:001D61*
+ ID_OUI_FROM_DATABASE=BIJ Corporation
+
+OUI:001D62*
+ ID_OUI_FROM_DATABASE=InPhase Technologies
+
+OUI:001D63*
+ ID_OUI_FROM_DATABASE=Miele & Cie. KG
+
+OUI:001D64*
+ ID_OUI_FROM_DATABASE=Adam Communications Systems Int Ltd
+
+OUI:001D65*
+ ID_OUI_FROM_DATABASE=Microwave Radio Communications
+
+OUI:001D66*
+ ID_OUI_FROM_DATABASE=Hyundai Telecom
+
+OUI:001D67*
+ ID_OUI_FROM_DATABASE=AMEC
+
+OUI:001D68*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:001D69*
+ ID_OUI_FROM_DATABASE=Knorr-Bremse AG
+
+OUI:001D6A*
+ ID_OUI_FROM_DATABASE=Alpha Networks Inc.
+
+OUI:001D6B*
+ ID_OUI_FROM_DATABASE=Motorola (formerly Netopia, Inc
+
+OUI:001D6C*
+ ID_OUI_FROM_DATABASE=ClariPhy Communications, Inc.
+
+OUI:001D6D*
+ ID_OUI_FROM_DATABASE=Confidant International LLC
+
+OUI:001D6E*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001D6F*
+ ID_OUI_FROM_DATABASE=Chainzone Technology Co., Ltd
+
+OUI:001D70*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001D71*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001D72*
+ ID_OUI_FROM_DATABASE=Wistron Corporation
+
+OUI:001D73*
+ ID_OUI_FROM_DATABASE=Buffalo Inc.
+
+OUI:001D74*
+ ID_OUI_FROM_DATABASE=Tianjin China-Silicon Microelectronics Co., Ltd.
+
+OUI:001D75*
+ ID_OUI_FROM_DATABASE=Radioscape PLC
+
+OUI:001D76*
+ ID_OUI_FROM_DATABASE=Eyeheight Ltd.
+
+OUI:001D77*
+ ID_OUI_FROM_DATABASE=NSGate
+
+OUI:001D78*
+ ID_OUI_FROM_DATABASE=Invengo Information Technology Co.,Ltd
+
+OUI:001D79*
+ ID_OUI_FROM_DATABASE=SIGNAMAX LLC
+
+OUI:001D7A*
+ ID_OUI_FROM_DATABASE=Wideband Semiconductor, Inc.
+
+OUI:001D7B*
+ ID_OUI_FROM_DATABASE=Ice Energy, Inc.
+
+OUI:001D7C*
+ ID_OUI_FROM_DATABASE=ABE Elettronica S.p.A.
+
+OUI:001D7D*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:001D7E*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:001D7F*
+ ID_OUI_FROM_DATABASE=Tekron International Ltd
+
+OUI:001D80*
+ ID_OUI_FROM_DATABASE=Beijing Huahuan Eletronics Co.,Ltd
+
+OUI:001D81*
+ ID_OUI_FROM_DATABASE=GUANGZHOU GATEWAY ELECTRONICS CO., LTD
+
+OUI:001D82*
+ ID_OUI_FROM_DATABASE=GN A/S (GN Netcom A/S)
+
+OUI:001D83*
+ ID_OUI_FROM_DATABASE=Emitech Corporation
+
+OUI:001D84*
+ ID_OUI_FROM_DATABASE=Gateway, Inc.
+
+OUI:001D85*
+ ID_OUI_FROM_DATABASE=Call Direct Cellular Solutions
+
+OUI:001D86*
+ ID_OUI_FROM_DATABASE=Shinwa Industries(China) Ltd.
+
+OUI:001D87*
+ ID_OUI_FROM_DATABASE=VigTech Labs Sdn Bhd
+
+OUI:001D88*
+ ID_OUI_FROM_DATABASE=Clearwire
+
+OUI:001D89*
+ ID_OUI_FROM_DATABASE=VaultStor Corporation
+
+OUI:001D8A*
+ ID_OUI_FROM_DATABASE=TechTrex Inc
+
+OUI:001D8B*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:001D8C*
+ ID_OUI_FROM_DATABASE=La Crosse Technology LTD
+
+OUI:001D8D*
+ ID_OUI_FROM_DATABASE=Raytek GmbH
+
+OUI:001D8E*
+ ID_OUI_FROM_DATABASE=Alereon, Inc.
+
+OUI:001D8F*
+ ID_OUI_FROM_DATABASE=PureWave Networks
+
+OUI:001D90*
+ ID_OUI_FROM_DATABASE=EMCO Flow Systems
+
+OUI:001D91*
+ ID_OUI_FROM_DATABASE=Digitize, Inc
+
+OUI:001D92*
+ ID_OUI_FROM_DATABASE=MICRO-STAR INT'L CO.,LTD.
+
+OUI:001D93*
+ ID_OUI_FROM_DATABASE=Modacom
+
+OUI:001D94*
+ ID_OUI_FROM_DATABASE=Climax Technology Co., Ltd
+
+OUI:001D95*
+ ID_OUI_FROM_DATABASE=Flash, Inc.
+
+OUI:001D96*
+ ID_OUI_FROM_DATABASE=WatchGuard Video
+
+OUI:001D97*
+ ID_OUI_FROM_DATABASE=Alertus Technologies LLC
+
+OUI:001D98*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001D99*
+ ID_OUI_FROM_DATABASE=Cyan Optic, Inc.
+
+OUI:001D9A*
+ ID_OUI_FROM_DATABASE=GODEX INTERNATIONAL CO., LTD
+
+OUI:001D9B*
+ ID_OUI_FROM_DATABASE=Hokuyo Automatic Co., Ltd.
+
+OUI:001D9C*
+ ID_OUI_FROM_DATABASE=Rockwell Automation
+
+OUI:001D9D*
+ ID_OUI_FROM_DATABASE=ARTJOY INTERNATIONAL LIMITED
+
+OUI:001D9E*
+ ID_OUI_FROM_DATABASE=AXION TECHNOLOGIES
+
+OUI:001D9F*
+ ID_OUI_FROM_DATABASE=MATT   R.P.Traczynscy Sp.J.
+
+OUI:001DA0*
+ ID_OUI_FROM_DATABASE=Heng Yu Electronic Manufacturing Company Limited
+
+OUI:001DA1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001DA2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001DA3*
+ ID_OUI_FROM_DATABASE=SabiOso
+
+OUI:001DA4*
+ ID_OUI_FROM_DATABASE=Hangzhou System Technology CO., LTD
+
+OUI:001DA5*
+ ID_OUI_FROM_DATABASE=WB Electronics
+
+OUI:001DA6*
+ ID_OUI_FROM_DATABASE=Media Numerics Limited
+
+OUI:001DA7*
+ ID_OUI_FROM_DATABASE=Seamless Internet
+
+OUI:001DA8*
+ ID_OUI_FROM_DATABASE=Takahata Electronics Co.,Ltd
+
+OUI:001DA9*
+ ID_OUI_FROM_DATABASE=Castles Technology, Co., LTD
+
+OUI:001DAA*
+ ID_OUI_FROM_DATABASE=DrayTek Corp.
+
+OUI:001DAB*
+ ID_OUI_FROM_DATABASE=SwissQual License AG
+
+OUI:001DAC*
+ ID_OUI_FROM_DATABASE=Gigamon Systems LLC
+
+OUI:001DAD*
+ ID_OUI_FROM_DATABASE=Sinotech Engineering Consultants, Inc.  Geotechnical Enginee
+
+OUI:001DAE*
+ ID_OUI_FROM_DATABASE=CHANG TSENG TECHNOLOGY CO., LTD
+
+OUI:001DAF*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001DB0*
+ ID_OUI_FROM_DATABASE=FuJian HengTong Information Technology Co.,Ltd
+
+OUI:001DB1*
+ ID_OUI_FROM_DATABASE=Crescendo Networks
+
+OUI:001DB2*
+ ID_OUI_FROM_DATABASE=HOKKAIDO ELECTRIC ENGINEERING CO.,LTD.
+
+OUI:001DB3*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:001DB4*
+ ID_OUI_FROM_DATABASE=KUMHO ENG CO.,LTD
+
+OUI:001DB5*
+ ID_OUI_FROM_DATABASE=Juniper networks
+
+OUI:001DB6*
+ ID_OUI_FROM_DATABASE=BestComm Networks, Inc.
+
+OUI:001DB7*
+ ID_OUI_FROM_DATABASE=Tendril Networks, Inc.
+
+OUI:001DB8*
+ ID_OUI_FROM_DATABASE=Intoto Inc.
+
+OUI:001DB9*
+ ID_OUI_FROM_DATABASE=Wellspring Wireless
+
+OUI:001DBA*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:001DBB*
+ ID_OUI_FROM_DATABASE=Dynamic System Electronics Corp.
+
+OUI:001DBC*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001DBD*
+ ID_OUI_FROM_DATABASE=Versamed Inc.
+
+OUI:001DBE*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001DBF*
+ ID_OUI_FROM_DATABASE=Radiient Technologies, Inc.
+
+OUI:001DC0*
+ ID_OUI_FROM_DATABASE=Enphase Energy
+
+OUI:001DC1*
+ ID_OUI_FROM_DATABASE=Audinate Pty L
+
+OUI:001DC2*
+ ID_OUI_FROM_DATABASE=XORTEC OY
+
+OUI:001DC3*
+ ID_OUI_FROM_DATABASE=RIKOR TV, Ltd
+
+OUI:001DC4*
+ ID_OUI_FROM_DATABASE=AIOI Systems Co., Ltd.
+
+OUI:001DC5*
+ ID_OUI_FROM_DATABASE=Beijing Jiaxun Feihong Electricial Co., Ltd.
+
+OUI:001DC6*
+ ID_OUI_FROM_DATABASE=SNR Inc.
+
+OUI:001DC7*
+ ID_OUI_FROM_DATABASE=L-3 Communications Geneva Aerospace
+
+OUI:001DC8*
+ ID_OUI_FROM_DATABASE=ScadaMetrcs, LLC.
+
+OUI:001DC9*
+ ID_OUI_FROM_DATABASE=GainSpan Corp.
+
+OUI:001DCA*
+ ID_OUI_FROM_DATABASE=PAV Electronics Limited
+
+OUI:001DCB*
+ ID_OUI_FROM_DATABASE=Exéns Development Oy
+
+OUI:001DCC*
+ ID_OUI_FROM_DATABASE=Hetra Secure Solutions
+
+OUI:001DCD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DCE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DCF*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD6*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD7*
+ ID_OUI_FROM_DATABASE=Algolith
+
+OUI:001DD8*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:001DD9*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.,Ltd.
+
+OUI:001DDA*
+ ID_OUI_FROM_DATABASE=Mikroelektronika spol. s r. o.
+
+OUI:001DDB*
+ ID_OUI_FROM_DATABASE=C-BEL Corporation
+
+OUI:001DDC*
+ ID_OUI_FROM_DATABASE=HangZhou DeChangLong Tech&Info Co.,Ltd
+
+OUI:001DDD*
+ ID_OUI_FROM_DATABASE=DAT H.K. LIMITED
+
+OUI:001DDE*
+ ID_OUI_FROM_DATABASE=Zhejiang Broadcast&Television Technology Co.,Ltd.
+
+OUI:001DDF*
+ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd.
+
+OUI:001DE0*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001DE1*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001DE2*
+ ID_OUI_FROM_DATABASE=Radionor Communications
+
+OUI:001DE3*
+ ID_OUI_FROM_DATABASE=Intuicom
+
+OUI:001DE4*
+ ID_OUI_FROM_DATABASE=Visioneered Image Systems
+
+OUI:001DE5*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001DE6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001DE7*
+ ID_OUI_FROM_DATABASE=Marine Sonic Technology, Ltd.
+
+OUI:001DE8*
+ ID_OUI_FROM_DATABASE=Nikko Denki Tsushin Company(NDTC)
+
+OUI:001DE9*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001DEA*
+ ID_OUI_FROM_DATABASE=Commtest Instruments Ltd
+
+OUI:001DEB*
+ ID_OUI_FROM_DATABASE=DINEC International
+
+OUI:001DEC*
+ ID_OUI_FROM_DATABASE=Marusys
+
+OUI:001DED*
+ ID_OUI_FROM_DATABASE=Grid Net, Inc.
+
+OUI:001DEE*
+ ID_OUI_FROM_DATABASE=NEXTVISION SISTEMAS DIGITAIS DE TELEVISÃO LTDA.
+
+OUI:001DEF*
+ ID_OUI_FROM_DATABASE=TRIMM, INC.
+
+OUI:001DF0*
+ ID_OUI_FROM_DATABASE=Vidient Systems, Inc.
+
+OUI:001DF1*
+ ID_OUI_FROM_DATABASE=Intego Systems, Inc.
+
+OUI:001DF2*
+ ID_OUI_FROM_DATABASE=Netflix, Inc.
+
+OUI:001DF3*
+ ID_OUI_FROM_DATABASE=SBS Science & Technology Co., Ltd
+
+OUI:001DF4*
+ ID_OUI_FROM_DATABASE=Magellan Technology Pty Limited
+
+OUI:001DF5*
+ ID_OUI_FROM_DATABASE=Sunshine Co,LTD
+
+OUI:001DF6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001DF7*
+ ID_OUI_FROM_DATABASE=R. STAHL Schaltgeräte GmbH
+
+OUI:001DF8*
+ ID_OUI_FROM_DATABASE=Webpro Vision Technology Corporation
+
+OUI:001DF9*
+ ID_OUI_FROM_DATABASE=Cybiotronics (Far East) Limited
+
+OUI:001DFA*
+ ID_OUI_FROM_DATABASE=Fujian LANDI Commercial Equipment Co.,Ltd
+
+OUI:001DFB*
+ ID_OUI_FROM_DATABASE=NETCLEUS Systems Corporation
+
+OUI:001DFC*
+ ID_OUI_FROM_DATABASE=KSIC
+
+OUI:001DFD*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001DFE*
+ ID_OUI_FROM_DATABASE=Palm, Inc
+
+OUI:001DFF*
+ ID_OUI_FROM_DATABASE=Network Critical Solutions Ltd
+
+OUI:001E00*
+ ID_OUI_FROM_DATABASE=Shantou Institute of Ultrasonic Instruments
+
+OUI:001E01*
+ ID_OUI_FROM_DATABASE=Renesas Technology Sales Co., Ltd.
+
+OUI:001E02*
+ ID_OUI_FROM_DATABASE=Sougou Keikaku Kougyou Co.,Ltd.
+
+OUI:001E03*
+ ID_OUI_FROM_DATABASE=LiComm Co., Ltd.
+
+OUI:001E04*
+ ID_OUI_FROM_DATABASE=Hanson Research Corporation
+
+OUI:001E05*
+ ID_OUI_FROM_DATABASE=Xseed Technologies & Computing
+
+OUI:001E06*
+ ID_OUI_FROM_DATABASE=WIBRAIN
+
+OUI:001E07*
+ ID_OUI_FROM_DATABASE=Winy Technology Co., Ltd.
+
+OUI:001E08*
+ ID_OUI_FROM_DATABASE=Centec Networks Inc
+
+OUI:001E09*
+ ID_OUI_FROM_DATABASE=ZEFATEK Co.,LTD
+
+OUI:001E0A*
+ ID_OUI_FROM_DATABASE=Syba Tech Limited
+
+OUI:001E0B*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001E0C*
+ ID_OUI_FROM_DATABASE=Sherwood Information Partners, Inc.
+
+OUI:001E0D*
+ ID_OUI_FROM_DATABASE=Micran Ltd.
+
+OUI:001E0E*
+ ID_OUI_FROM_DATABASE=MAXI VIEW HOLDINGS LIMITED
+
+OUI:001E0F*
+ ID_OUI_FROM_DATABASE=Briot International
+
+OUI:001E10*
+ ID_OUI_FROM_DATABASE=ShenZhen Huawei Communication Technologies Co.,Ltd.
+
+OUI:001E11*
+ ID_OUI_FROM_DATABASE=ELELUX INTERNATIONAL LTD
+
+OUI:001E12*
+ ID_OUI_FROM_DATABASE=Ecolab
+
+OUI:001E13*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001E14*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001E15*
+ ID_OUI_FROM_DATABASE=Beech Hill Electronics
+
+OUI:001E16*
+ ID_OUI_FROM_DATABASE=Keytronix
+
+OUI:001E17*
+ ID_OUI_FROM_DATABASE=STN BV
+
+OUI:001E18*
+ ID_OUI_FROM_DATABASE=Radio Activity srl
+
+OUI:001E19*
+ ID_OUI_FROM_DATABASE=GTRI
+
+OUI:001E1A*
+ ID_OUI_FROM_DATABASE=Best Source Taiwan Inc.
+
+OUI:001E1B*
+ ID_OUI_FROM_DATABASE=Digital Stream Technology, Inc.
+
+OUI:001E1C*
+ ID_OUI_FROM_DATABASE=SWS Australia Pty Limited
+
+OUI:001E1D*
+ ID_OUI_FROM_DATABASE=East Coast Datacom, Inc.
+
+OUI:001E1E*
+ ID_OUI_FROM_DATABASE=Honeywell Life Safety
+
+OUI:001E1F*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001E20*
+ ID_OUI_FROM_DATABASE=Intertain Inc.
+
+OUI:001E21*
+ ID_OUI_FROM_DATABASE=Qisda Co.
+
+OUI:001E22*
+ ID_OUI_FROM_DATABASE=ARVOO Imaging Products BV
+
+OUI:001E23*
+ ID_OUI_FROM_DATABASE=Electronic Educational Devices, Inc
+
+OUI:001E24*
+ ID_OUI_FROM_DATABASE=Zhejiang Bell Technology Co.,ltd
+
+OUI:001E25*
+ ID_OUI_FROM_DATABASE=Intek Digital Inc
+
+OUI:001E26*
+ ID_OUI_FROM_DATABASE=Digifriends Co. Ltd
+
+OUI:001E27*
+ ID_OUI_FROM_DATABASE=SBN TECH Co.,Ltd.
+
+OUI:001E28*
+ ID_OUI_FROM_DATABASE=Lumexis Corporation
+
+OUI:001E29*
+ ID_OUI_FROM_DATABASE=Hypertherm Inc
+
+OUI:001E2A*
+ ID_OUI_FROM_DATABASE=Netgear Inc.
+
+OUI:001E2B*
+ ID_OUI_FROM_DATABASE=Radio Systems Design, Inc.
+
+OUI:001E2C*
+ ID_OUI_FROM_DATABASE=CyVerse Corporation
+
+OUI:001E2D*
+ ID_OUI_FROM_DATABASE=STIM
+
+OUI:001E2E*
+ ID_OUI_FROM_DATABASE=SIRTI S.p.A.
+
+OUI:001E2F*
+ ID_OUI_FROM_DATABASE=DiMoto Pty Ltd
+
+OUI:001E30*
+ ID_OUI_FROM_DATABASE=Shireen Inc
+
+OUI:001E31*
+ ID_OUI_FROM_DATABASE=INFOMARK CO.,LTD.
+
+OUI:001E32*
+ ID_OUI_FROM_DATABASE=Zensys
+
+OUI:001E33*
+ ID_OUI_FROM_DATABASE=Inventec Corporation
+
+OUI:001E34*
+ ID_OUI_FROM_DATABASE=CryptoMetrics
+
+OUI:001E35*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001E36*
+ ID_OUI_FROM_DATABASE=IPTE
+
+OUI:001E37*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:001E38*
+ ID_OUI_FROM_DATABASE=Bluecard Software Technology Co., Ltd.
+
+OUI:001E39*
+ ID_OUI_FROM_DATABASE=Comsys Communication Ltd.
+
+OUI:001E3A*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001E3B*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001E3C*
+ ID_OUI_FROM_DATABASE=Lyngbox Media AB
+
+OUI:001E3D*
+ ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd
+
+OUI:001E3E*
+ ID_OUI_FROM_DATABASE=KMW Inc.
+
+OUI:001E3F*
+ ID_OUI_FROM_DATABASE=TrellisWare Technologies, Inc.
+
+OUI:001E40*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies  Co.,Ltd.
+
+OUI:001E41*
+ ID_OUI_FROM_DATABASE=Microwave Communication & Component, Inc.
+
+OUI:001E42*
+ ID_OUI_FROM_DATABASE=Teltonika
+
+OUI:001E43*
+ ID_OUI_FROM_DATABASE=AISIN AW CO.,LTD.
+
+OUI:001E44*
+ ID_OUI_FROM_DATABASE=SANTEC
+
+OUI:001E45*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:001E46*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001E47*
+ ID_OUI_FROM_DATABASE=PT. Hariff Daya Tunggal Engineering
+
+OUI:001E48*
+ ID_OUI_FROM_DATABASE=Wi-Links
+
+OUI:001E49*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001E4A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001E4B*
+ ID_OUI_FROM_DATABASE=City Theatrical
+
+OUI:001E4C*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co., Ltd.
+
+OUI:001E4D*
+ ID_OUI_FROM_DATABASE=Welkin Sciences, LLC
+
+OUI:001E4E*
+ ID_OUI_FROM_DATABASE=DAKO EDV-Ingenieur- und Systemhaus GmbH
+
+OUI:001E4F*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:001E50*
+ ID_OUI_FROM_DATABASE=BATTISTONI RESEARCH
+
+OUI:001E51*
+ ID_OUI_FROM_DATABASE=Converter Industry Srl
+
+OUI:001E52*
+ ID_OUI_FROM_DATABASE=Apple Computer Inc
+
+OUI:001E53*
+ ID_OUI_FROM_DATABASE=Further Tech Co., LTD
+
+OUI:001E54*
+ ID_OUI_FROM_DATABASE=TOYO ELECTRIC Corporation
+
+OUI:001E55*
+ ID_OUI_FROM_DATABASE=COWON SYSTEMS,Inc.
+
+OUI:001E56*
+ ID_OUI_FROM_DATABASE=Bally Wulff Entertainment GmbH
+
+OUI:001E57*
+ ID_OUI_FROM_DATABASE=ALCOMA, spol. s r.o.
+
+OUI:001E58*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:001E59*
+ ID_OUI_FROM_DATABASE=Silicon Turnkey Express, LLC
+
+OUI:001E5A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001E5B*
+ ID_OUI_FROM_DATABASE=Unitron Company, Inc.
+
+OUI:001E5C*
+ ID_OUI_FROM_DATABASE=RB GeneralEkonomik
+
+OUI:001E5D*
+ ID_OUI_FROM_DATABASE=Holosys d.o.o.
+
+OUI:001E5E*
+ ID_OUI_FROM_DATABASE=COmputime Ltd.
+
+OUI:001E5F*
+ ID_OUI_FROM_DATABASE=KwikByte, LLC
+
+OUI:001E60*
+ ID_OUI_FROM_DATABASE=Digital Lighting Systems, Inc
+
+OUI:001E61*
+ ID_OUI_FROM_DATABASE=ITEC GmbH
+
+OUI:001E62*
+ ID_OUI_FROM_DATABASE=Siemon
+
+OUI:001E63*
+ ID_OUI_FROM_DATABASE=Vibro-Meter SA
+
+OUI:001E64*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001E65*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001E66*
+ ID_OUI_FROM_DATABASE=RESOL Elektronische Regelungen GmbH
+
+OUI:001E67*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001E68*
+ ID_OUI_FROM_DATABASE=Quanta Computer
+
+OUI:001E69*
+ ID_OUI_FROM_DATABASE=Thomson Inc.
+
+OUI:001E6A*
+ ID_OUI_FROM_DATABASE=Beijing Bluexon Technology Co.,Ltd
+
+OUI:001E6B*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta, A Cisco Company
+
+OUI:001E6C*
+ ID_OUI_FROM_DATABASE=Carbon Mountain LLC
+
+OUI:001E6D*
+ ID_OUI_FROM_DATABASE=IT R&D Center
+
+OUI:001E6E*
+ ID_OUI_FROM_DATABASE=Shenzhen First Mile Communications Ltd
+
+OUI:001E6F*
+ ID_OUI_FROM_DATABASE=Magna-Power Electronics, Inc.
+
+OUI:001E70*
+ ID_OUI_FROM_DATABASE=Cobham Defence Communications Ltd
+
+OUI:001E71*
+ ID_OUI_FROM_DATABASE=Igeacare Solutions Inc.
+
+OUI:001E72*
+ ID_OUI_FROM_DATABASE=PCS
+
+OUI:001E73*
+ ID_OUI_FROM_DATABASE=ZTE CORPORATION
+
+OUI:001E74*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:001E75*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:001E76*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific
+
+OUI:001E77*
+ ID_OUI_FROM_DATABASE=Air2App
+
+OUI:001E78*
+ ID_OUI_FROM_DATABASE=Owitek Technology Ltd.,
+
+OUI:001E79*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001E7A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001E7B*
+ ID_OUI_FROM_DATABASE=R.I.CO. S.r.l.
+
+OUI:001E7C*
+ ID_OUI_FROM_DATABASE=Taiwick Limited
+
+OUI:001E7D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001E7E*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001E7F*
+ ID_OUI_FROM_DATABASE=CBM of America
+
+OUI:001E80*
+ ID_OUI_FROM_DATABASE=Last Mile Ltd.
+
+OUI:001E81*
+ ID_OUI_FROM_DATABASE=CNB Technology Inc.
+
+OUI:001E82*
+ ID_OUI_FROM_DATABASE=SanDisk Corporation
+
+OUI:001E83*
+ ID_OUI_FROM_DATABASE=LAN/MAN Standards Association (LMSC)
+
+OUI:001E84*
+ ID_OUI_FROM_DATABASE=Pika Technologies Inc.
+
+OUI:001E85*
+ ID_OUI_FROM_DATABASE=Lagotek Corporation
+
+OUI:001E86*
+ ID_OUI_FROM_DATABASE=MEL Co.,Ltd.
+
+OUI:001E87*
+ ID_OUI_FROM_DATABASE=Realease Limited
+
+OUI:001E88*
+ ID_OUI_FROM_DATABASE=ANDOR SYSTEM SUPPORT CO., LTD.
+
+OUI:001E89*
+ ID_OUI_FROM_DATABASE=CRFS Limited
+
+OUI:001E8A*
+ ID_OUI_FROM_DATABASE=eCopy, Inc
+
+OUI:001E8B*
+ ID_OUI_FROM_DATABASE=Infra Access Korea Co., Ltd.
+
+OUI:001E8C*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:001E8D*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001E8E*
+ ID_OUI_FROM_DATABASE=Hunkeler AG
+
+OUI:001E8F*
+ ID_OUI_FROM_DATABASE=CANON INC.
+
+OUI:001E90*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co
+
+OUI:001E91*
+ ID_OUI_FROM_DATABASE=KIMIN Electronic Co., Ltd.
+
+OUI:001E92*
+ ID_OUI_FROM_DATABASE=JEULIN S.A.
+
+OUI:001E93*
+ ID_OUI_FROM_DATABASE=CiriTech Systems Inc
+
+OUI:001E94*
+ ID_OUI_FROM_DATABASE=SUPERCOM TECHNOLOGY CORPORATION
+
+OUI:001E95*
+ ID_OUI_FROM_DATABASE=SIGMALINK
+
+OUI:001E96*
+ ID_OUI_FROM_DATABASE=Sepura Plc
+
+OUI:001E97*
+ ID_OUI_FROM_DATABASE=Medium Link System Technology CO., LTD,
+
+OUI:001E98*
+ ID_OUI_FROM_DATABASE=GreenLine Communications
+
+OUI:001E99*
+ ID_OUI_FROM_DATABASE=Vantanol Industrial Corporation
+
+OUI:001E9A*
+ ID_OUI_FROM_DATABASE=HAMILTON Bonaduz AG
+
+OUI:001E9B*
+ ID_OUI_FROM_DATABASE=San-Eisha, Ltd.
+
+OUI:001E9C*
+ ID_OUI_FROM_DATABASE=Fidustron INC
+
+OUI:001E9D*
+ ID_OUI_FROM_DATABASE=Recall Technologies, Inc.
+
+OUI:001E9E*
+ ID_OUI_FROM_DATABASE=ddm hopt + schuler Gmbh + Co. KG
+
+OUI:001E9F*
+ ID_OUI_FROM_DATABASE=Visioneering Systems, Inc.
+
+OUI:001EA0*
+ ID_OUI_FROM_DATABASE=XLN-t
+
+OUI:001EA1*
+ ID_OUI_FROM_DATABASE=Brunata a/s
+
+OUI:001EA2*
+ ID_OUI_FROM_DATABASE=Symx Systems, Inc.
+
+OUI:001EA3*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001EA4*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001EA5*
+ ID_OUI_FROM_DATABASE=ROBOTOUS, Inc.
+
+OUI:001EA6*
+ ID_OUI_FROM_DATABASE=Best IT World (India) Pvt. Ltd.
+
+OUI:001EA7*
+ ID_OUI_FROM_DATABASE=ActionTec Electronics, Inc
+
+OUI:001EA8*
+ ID_OUI_FROM_DATABASE=Datang Mobile Communications Equipment CO.,LTD
+
+OUI:001EA9*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001EAA*
+ ID_OUI_FROM_DATABASE=E-Senza Technologies GmbH
+
+OUI:001EAB*
+ ID_OUI_FROM_DATABASE=TeleWell Oy
+
+OUI:001EAC*
+ ID_OUI_FROM_DATABASE=Armadeus Systems
+
+OUI:001EAD*
+ ID_OUI_FROM_DATABASE=Wingtech Group Limited
+
+OUI:001EAE*
+ ID_OUI_FROM_DATABASE=Continental Automotive Systems
+
+OUI:001EAF*
+ ID_OUI_FROM_DATABASE=Ophir Optronics Ltd
+
+OUI:001EB0*
+ ID_OUI_FROM_DATABASE=ImesD Electronica S.L.
+
+OUI:001EB1*
+ ID_OUI_FROM_DATABASE=Cryptsoft Pty Ltd
+
+OUI:001EB2*
+ ID_OUI_FROM_DATABASE=LG innotek
+
+OUI:001EB3*
+ ID_OUI_FROM_DATABASE=Primex Wireless
+
+OUI:001EB4*
+ ID_OUI_FROM_DATABASE=UNIFAT TECHNOLOGY LTD.
+
+OUI:001EB5*
+ ID_OUI_FROM_DATABASE=Ever Sparkle Technologies Ltd
+
+OUI:001EB6*
+ ID_OUI_FROM_DATABASE=TAG Heuer SA
+
+OUI:001EB7*
+ ID_OUI_FROM_DATABASE=TBTech, Co., Ltd.
+
+OUI:001EB8*
+ ID_OUI_FROM_DATABASE=Fortis, Inc.
+
+OUI:001EB9*
+ ID_OUI_FROM_DATABASE=Sing Fai Technology Limited
+
+OUI:001EBA*
+ ID_OUI_FROM_DATABASE=High Density Devices AS
+
+OUI:001EBB*
+ ID_OUI_FROM_DATABASE=BLUELIGHT TECHNOLOGY INC.
+
+OUI:001EBC*
+ ID_OUI_FROM_DATABASE=WINTECH AUTOMATION CO.,LTD.
+
+OUI:001EBD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001EBE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001EBF*
+ ID_OUI_FROM_DATABASE=Haas Automation Inc.
+
+OUI:001EC0*
+ ID_OUI_FROM_DATABASE=Microchip Technology Inc.
+
+OUI:001EC1*
+ ID_OUI_FROM_DATABASE=3COM EUROPE LTD
+
+OUI:001EC2*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:001EC3*
+ ID_OUI_FROM_DATABASE=Kozio, Inc.
+
+OUI:001EC4*
+ ID_OUI_FROM_DATABASE=Celio Corp
+
+OUI:001EC5*
+ ID_OUI_FROM_DATABASE=Middle Atlantic Products Inc
+
+OUI:001EC6*
+ ID_OUI_FROM_DATABASE=Obvius Holdings LLC
+
+OUI:001EC7*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:001EC8*
+ ID_OUI_FROM_DATABASE=Rapid Mobile (Pty) Ltd
+
+OUI:001EC9*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:001ECA*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001ECB*
+ ID_OUI_FROM_DATABASE="RPC "Energoautomatika" Ltd
+
+OUI:001ECC*
+ ID_OUI_FROM_DATABASE=CDVI
+
+OUI:001ECD*
+ ID_OUI_FROM_DATABASE=KYLAND
+
+OUI:001ECE*
+ ID_OUI_FROM_DATABASE=BISA Technologies (Hong Kong) Limited
+
+OUI:001ECF*
+ ID_OUI_FROM_DATABASE=PHILIPS ELECTRONICS UK LTD
+
+OUI:001ED0*
+ ID_OUI_FROM_DATABASE=Ingespace
+
+OUI:001ED1*
+ ID_OUI_FROM_DATABASE=Keyprocessor B.V.
+
+OUI:001ED2*
+ ID_OUI_FROM_DATABASE=Ray Shine Video Technology Inc
+
+OUI:001ED3*
+ ID_OUI_FROM_DATABASE=Dot Technology Int'l Co., Ltd.
+
+OUI:001ED4*
+ ID_OUI_FROM_DATABASE=Doble Engineering
+
+OUI:001ED5*
+ ID_OUI_FROM_DATABASE=Tekon-Automatics
+
+OUI:001ED6*
+ ID_OUI_FROM_DATABASE=Alentec & Orion AB
+
+OUI:001ED7*
+ ID_OUI_FROM_DATABASE=H-Stream Wireless, Inc.
+
+OUI:001ED8*
+ ID_OUI_FROM_DATABASE=Digital United Inc.
+
+OUI:001ED9*
+ ID_OUI_FROM_DATABASE=Mitsubishi Precision Co.,LTd.
+
+OUI:001EDA*
+ ID_OUI_FROM_DATABASE=Wesemann Elektrotechniek B.V.
+
+OUI:001EDB*
+ ID_OUI_FROM_DATABASE=Giken Trastem Co., Ltd.
+
+OUI:001EDC*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:001EDD*
+ ID_OUI_FROM_DATABASE=WASKO S.A.
+
+OUI:001EDE*
+ ID_OUI_FROM_DATABASE=BYD COMPANY LIMITED
+
+OUI:001EDF*
+ ID_OUI_FROM_DATABASE=Master Industrialization Center Kista
+
+OUI:001EE0*
+ ID_OUI_FROM_DATABASE=Urmet Domus SpA
+
+OUI:001EE1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001EE2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001EE3*
+ ID_OUI_FROM_DATABASE=T&W Electronics (ShenZhen) Co.,Ltd
+
+OUI:001EE4*
+ ID_OUI_FROM_DATABASE=ACS Solutions France
+
+OUI:001EE5*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:001EE6*
+ ID_OUI_FROM_DATABASE=Shenzhen Advanced Video Info-Tech Co., Ltd.
+
+OUI:001EE7*
+ ID_OUI_FROM_DATABASE=Epic Systems Inc
+
+OUI:001EE8*
+ ID_OUI_FROM_DATABASE=Mytek
+
+OUI:001EE9*
+ ID_OUI_FROM_DATABASE=Stoneridge Electronics AB
+
+OUI:001EEA*
+ ID_OUI_FROM_DATABASE=Sensor Switch, Inc.
+
+OUI:001EEB*
+ ID_OUI_FROM_DATABASE=Talk-A-Phone Co.
+
+OUI:001EEC*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:001EED*
+ ID_OUI_FROM_DATABASE=Adventiq Ltd.
+
+OUI:001EEE*
+ ID_OUI_FROM_DATABASE=ETL Systems Ltd
+
+OUI:001EEF*
+ ID_OUI_FROM_DATABASE=Cantronic International Limited
+
+OUI:001EF0*
+ ID_OUI_FROM_DATABASE=Gigafin Networks
+
+OUI:001EF1*
+ ID_OUI_FROM_DATABASE=Servimat
+
+OUI:001EF2*
+ ID_OUI_FROM_DATABASE=Micro Motion Inc
+
+OUI:001EF3*
+ ID_OUI_FROM_DATABASE=From2
+
+OUI:001EF4*
+ ID_OUI_FROM_DATABASE=L-3 Communications Display Systems
+
+OUI:001EF5*
+ ID_OUI_FROM_DATABASE=Hitek Automated Inc.
+
+OUI:001EF6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001EF7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001EF8*
+ ID_OUI_FROM_DATABASE=Emfinity Inc.
+
+OUI:001EF9*
+ ID_OUI_FROM_DATABASE=Pascom Kommunikations systeme GmbH.
+
+OUI:001EFA*
+ ID_OUI_FROM_DATABASE=PROTEI Ltd.
+
+OUI:001EFB*
+ ID_OUI_FROM_DATABASE=Trio Motion Technology Ltd
+
+OUI:001EFC*
+ ID_OUI_FROM_DATABASE=JSC "MASSA-K"
+
+OUI:001EFD*
+ ID_OUI_FROM_DATABASE=Microbit 2.0 AB
+
+OUI:001EFE*
+ ID_OUI_FROM_DATABASE=LEVEL s.r.o.
+
+OUI:001EFF*
+ ID_OUI_FROM_DATABASE=Mueller-Elektronik GmbH & Co. KG
+
+OUI:001F00*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001F01*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001F02*
+ ID_OUI_FROM_DATABASE=Pixelmetrix Corporation Pte Ltd
+
+OUI:001F03*
+ ID_OUI_FROM_DATABASE=NUM AG
+
+OUI:001F04*
+ ID_OUI_FROM_DATABASE=Granch Ltd.
+
+OUI:001F05*
+ ID_OUI_FROM_DATABASE=iTAS Technology Corp.
+
+OUI:001F06*
+ ID_OUI_FROM_DATABASE=Integrated Dispatch Solutions
+
+OUI:001F07*
+ ID_OUI_FROM_DATABASE=AZTEQ Mobile
+
+OUI:001F08*
+ ID_OUI_FROM_DATABASE=RISCO LTD
+
+OUI:001F09*
+ ID_OUI_FROM_DATABASE=JASTEC CO., LTD.
+
+OUI:001F0A*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001F0B*
+ ID_OUI_FROM_DATABASE=Federal State Unitary Enterprise Industrial Union"Electropribor"
+
+OUI:001F0C*
+ ID_OUI_FROM_DATABASE=Intelligent Digital Services GmbH
+
+OUI:001F0D*
+ ID_OUI_FROM_DATABASE=L3 Communications - Telemetry West
+
+OUI:001F0E*
+ ID_OUI_FROM_DATABASE=Japan Kyastem Co., Ltd
+
+OUI:001F0F*
+ ID_OUI_FROM_DATABASE=Select Engineered Systems
+
+OUI:001F10*
+ ID_OUI_FROM_DATABASE=TOLEDO DO BRASIL INDUSTRIA DE BALANCAS  LTDA
+
+OUI:001F11*
+ ID_OUI_FROM_DATABASE=OPENMOKO, INC.
+
+OUI:001F12*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:001F13*
+ ID_OUI_FROM_DATABASE=S.& A.S. Ltd.
+
+OUI:001F14*
+ ID_OUI_FROM_DATABASE=NexG
+
+OUI:001F15*
+ ID_OUI_FROM_DATABASE=Bioscrypt Inc
+
+OUI:001F16*
+ ID_OUI_FROM_DATABASE=Wistron Corporation
+
+OUI:001F17*
+ ID_OUI_FROM_DATABASE=IDX Company, Ltd.
+
+OUI:001F18*
+ ID_OUI_FROM_DATABASE=Hakusan.Mfg.Co,.Ltd
+
+OUI:001F19*
+ ID_OUI_FROM_DATABASE=BEN-RI ELECTRONICA S.A.
+
+OUI:001F1A*
+ ID_OUI_FROM_DATABASE=Prominvest
+
+OUI:001F1B*
+ ID_OUI_FROM_DATABASE=RoyalTek Company Ltd.
+
+OUI:001F1C*
+ ID_OUI_FROM_DATABASE=KOBISHI ELECTRIC Co.,Ltd.
+
+OUI:001F1D*
+ ID_OUI_FROM_DATABASE=Atlas Material Testing Technology LLC
+
+OUI:001F1E*
+ ID_OUI_FROM_DATABASE=Astec Technology Co., Ltd
+
+OUI:001F1F*
+ ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd.
+
+OUI:001F20*
+ ID_OUI_FROM_DATABASE=Logitech Europe SA
+
+OUI:001F21*
+ ID_OUI_FROM_DATABASE=Inner Mongolia Yin An Science & Technology Development Co.,L
+
+OUI:001F22*
+ ID_OUI_FROM_DATABASE=Source Photonics, Inc.
+
+OUI:001F23*
+ ID_OUI_FROM_DATABASE=Interacoustics
+
+OUI:001F24*
+ ID_OUI_FROM_DATABASE=DIGITVIEW TECHNOLOGY CO., LTD.
+
+OUI:001F25*
+ ID_OUI_FROM_DATABASE=MBS GmbH
+
+OUI:001F26*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001F27*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001F28*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:001F29*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:001F2A*
+ ID_OUI_FROM_DATABASE=ACCM
+
+OUI:001F2B*
+ ID_OUI_FROM_DATABASE=Orange Logic
+
+OUI:001F2C*
+ ID_OUI_FROM_DATABASE=Starbridge Networks
+
+OUI:001F2D*
+ ID_OUI_FROM_DATABASE=Electro-Optical Imaging, Inc.
+
+OUI:001F2E*
+ ID_OUI_FROM_DATABASE=Triangle Research Int'l Pte Ltd
+
+OUI:001F2F*
+ ID_OUI_FROM_DATABASE=Berker GmbH & Co. KG
+
+OUI:001F30*
+ ID_OUI_FROM_DATABASE=Travelping
+
+OUI:001F31*
+ ID_OUI_FROM_DATABASE=Radiocomp
+
+OUI:001F32*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001F33*
+ ID_OUI_FROM_DATABASE=Netgear Inc.
+
+OUI:001F34*
+ ID_OUI_FROM_DATABASE=Lung Hwa Electronics Co., Ltd.
+
+OUI:001F35*
+ ID_OUI_FROM_DATABASE=AIR802 LLC
+
+OUI:001F36*
+ ID_OUI_FROM_DATABASE=Bellwin Information Co. Ltd.,
+
+OUI:001F37*
+ ID_OUI_FROM_DATABASE=Genesis I&C
+
+OUI:001F38*
+ ID_OUI_FROM_DATABASE=POSITRON
+
+OUI:001F39*
+ ID_OUI_FROM_DATABASE=Construcciones y Auxiliar de Ferrocarriles, S.A.
+
+OUI:001F3A*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co., Ltd.
+
+OUI:001F3B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001F3C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:001F3D*
+ ID_OUI_FROM_DATABASE=Qbit GmbH
+
+OUI:001F3E*
+ ID_OUI_FROM_DATABASE=RP-Technik e.K.
+
+OUI:001F3F*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:001F40*
+ ID_OUI_FROM_DATABASE=Speakercraft Inc.
+
+OUI:001F41*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:001F42*
+ ID_OUI_FROM_DATABASE=Etherstack Pty Ltd
+
+OUI:001F43*
+ ID_OUI_FROM_DATABASE=ENTES ELEKTRONIK
+
+OUI:001F44*
+ ID_OUI_FROM_DATABASE=GE Transportation Systems
+
+OUI:001F45*
+ ID_OUI_FROM_DATABASE=Enterasys
+
+OUI:001F46*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:001F47*
+ ID_OUI_FROM_DATABASE=MCS Logic Inc.
+
+OUI:001F48*
+ ID_OUI_FROM_DATABASE=Mojix Inc.
+
+OUI:001F49*
+ ID_OUI_FROM_DATABASE=Eurosat Distribution Ltd
+
+OUI:001F4A*
+ ID_OUI_FROM_DATABASE=Albentia Systems S.A.
+
+OUI:001F4B*
+ ID_OUI_FROM_DATABASE=Lineage Power
+
+OUI:001F4C*
+ ID_OUI_FROM_DATABASE=Roseman Engineering Ltd
+
+OUI:001F4D*
+ ID_OUI_FROM_DATABASE=Segnetics LLC
+
+OUI:001F4E*
+ ID_OUI_FROM_DATABASE=ConMed Linvatec
+
+OUI:001F4F*
+ ID_OUI_FROM_DATABASE=Thinkware Co. Ltd.
+
+OUI:001F50*
+ ID_OUI_FROM_DATABASE=Swissdis AG
+
+OUI:001F51*
+ ID_OUI_FROM_DATABASE=HD Communications Corp
+
+OUI:001F52*
+ ID_OUI_FROM_DATABASE=UVT Unternehmensberatung fur Verkehr und Technik GmbH
+
+OUI:001F53*
+ ID_OUI_FROM_DATABASE=GEMAC Gesellschaft für Mikroelektronikanwendung Chemnitz mbH
+
+OUI:001F54*
+ ID_OUI_FROM_DATABASE=Lorex Technology Inc.
+
+OUI:001F55*
+ ID_OUI_FROM_DATABASE=Honeywell Security (China) Co., Ltd.
+
+OUI:001F56*
+ ID_OUI_FROM_DATABASE=DIGITAL FORECAST
+
+OUI:001F57*
+ ID_OUI_FROM_DATABASE=Phonik Innovation Co.,LTD
+
+OUI:001F58*
+ ID_OUI_FROM_DATABASE=EMH Energiemesstechnik GmbH & co.KG
+
+OUI:001F59*
+ ID_OUI_FROM_DATABASE=Kronback Tracers
+
+OUI:001F5A*
+ ID_OUI_FROM_DATABASE=Beckwith Electric Co.
+
+OUI:001F5B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:001F5C*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001F5D*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001F5E*
+ ID_OUI_FROM_DATABASE=Dyna Technology Co.,Ltd.
+
+OUI:001F5F*
+ ID_OUI_FROM_DATABASE=Blatand GmbH
+
+OUI:001F60*
+ ID_OUI_FROM_DATABASE=COMPASS SYSTEMS CORP.
+
+OUI:001F61*
+ ID_OUI_FROM_DATABASE=Talent Communication Networks Inc.
+
+OUI:001F62*
+ ID_OUI_FROM_DATABASE=JSC "Stilsoft"
+
+OUI:001F63*
+ ID_OUI_FROM_DATABASE=JSC Goodwin-Europa
+
+OUI:001F64*
+ ID_OUI_FROM_DATABASE=Beijing Autelan Technology Inc.
+
+OUI:001F65*
+ ID_OUI_FROM_DATABASE=KOREA ELECTRIC TERMINAL CO., LTD.
+
+OUI:001F66*
+ ID_OUI_FROM_DATABASE=PLANAR LLC
+
+OUI:001F67*
+ ID_OUI_FROM_DATABASE=Hitachi,Ltd.
+
+OUI:001F68*
+ ID_OUI_FROM_DATABASE=Martinsson Elektronik AB
+
+OUI:001F69*
+ ID_OUI_FROM_DATABASE=Pingood Technology Co., Ltd.
+
+OUI:001F6A*
+ ID_OUI_FROM_DATABASE=PacketFlux Technologies, Inc.
+
+OUI:001F6B*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:001F6C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001F6D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001F6E*
+ ID_OUI_FROM_DATABASE=Vtech Engineering Corporation
+
+OUI:001F6F*
+ ID_OUI_FROM_DATABASE=Fujian Sunnada Communication Co.,Ltd.
+
+OUI:001F70*
+ ID_OUI_FROM_DATABASE=Botik Technologies LTD
+
+OUI:001F71*
+ ID_OUI_FROM_DATABASE=xG Technology, Inc.
+
+OUI:001F72*
+ ID_OUI_FROM_DATABASE=QingDao Hiphone Technology Co,.Ltd
+
+OUI:001F73*
+ ID_OUI_FROM_DATABASE=Teraview Technology Co., Ltd.
+
+OUI:001F74*
+ ID_OUI_FROM_DATABASE=Eigen Development
+
+OUI:001F75*
+ ID_OUI_FROM_DATABASE=GiBahn Media
+
+OUI:001F76*
+ ID_OUI_FROM_DATABASE=AirLogic Systems Inc.
+
+OUI:001F77*
+ ID_OUI_FROM_DATABASE=HEOL DESIGN
+
+OUI:001F78*
+ ID_OUI_FROM_DATABASE=Blue Fox Porini Textile
+
+OUI:001F79*
+ ID_OUI_FROM_DATABASE=Lodam Electronics A/S
+
+OUI:001F7A*
+ ID_OUI_FROM_DATABASE=WiWide Inc.
+
+OUI:001F7B*
+ ID_OUI_FROM_DATABASE=TechNexion Ltd.
+
+OUI:001F7C*
+ ID_OUI_FROM_DATABASE=Witelcom AS
+
+OUI:001F7D*
+ ID_OUI_FROM_DATABASE=embedded wireless GmbH
+
+OUI:001F7E*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001F7F*
+ ID_OUI_FROM_DATABASE=Phabrix Limited
+
+OUI:001F80*
+ ID_OUI_FROM_DATABASE=Lucas Holding bv
+
+OUI:001F81*
+ ID_OUI_FROM_DATABASE=Accel Semiconductor Corp
+
+OUI:001F82*
+ ID_OUI_FROM_DATABASE=Cal-Comp Electronics & Communications Co., Ltd
+
+OUI:001F83*
+ ID_OUI_FROM_DATABASE=Teleplan Technology Services Sdn Bhd
+
+OUI:001F84*
+ ID_OUI_FROM_DATABASE=Gigle Semiconductor
+
+OUI:001F85*
+ ID_OUI_FROM_DATABASE=Apriva ISS, LLC
+
+OUI:001F86*
+ ID_OUI_FROM_DATABASE=digEcor
+
+OUI:001F87*
+ ID_OUI_FROM_DATABASE=Skydigital Inc.
+
+OUI:001F88*
+ ID_OUI_FROM_DATABASE=FMS Force Measuring Systems AG
+
+OUI:001F89*
+ ID_OUI_FROM_DATABASE=Signalion GmbH
+
+OUI:001F8A*
+ ID_OUI_FROM_DATABASE=Ellion Digital Inc.
+
+OUI:001F8B*
+ ID_OUI_FROM_DATABASE=Cache IQ
+
+OUI:001F8C*
+ ID_OUI_FROM_DATABASE=CCS Inc.
+
+OUI:001F8D*
+ ID_OUI_FROM_DATABASE=Ingenieurbuero Stark GmbH und Ko. KG
+
+OUI:001F8E*
+ ID_OUI_FROM_DATABASE=Metris USA Inc.
+
+OUI:001F8F*
+ ID_OUI_FROM_DATABASE=Shanghai Bellmann Digital Source Co.,Ltd.
+
+OUI:001F90*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:001F91*
+ ID_OUI_FROM_DATABASE=DBS Lodging Technologies, LLC
+
+OUI:001F92*
+ ID_OUI_FROM_DATABASE=VideoIQ, Inc.
+
+OUI:001F93*
+ ID_OUI_FROM_DATABASE=Xiotech Corporation
+
+OUI:001F94*
+ ID_OUI_FROM_DATABASE=Lascar Electronics Ltd
+
+OUI:001F95*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:001F96*
+ ID_OUI_FROM_DATABASE=APROTECH CO.LTD
+
+OUI:001F97*
+ ID_OUI_FROM_DATABASE=BERTANA SRL
+
+OUI:001F98*
+ ID_OUI_FROM_DATABASE=DAIICHI-DENTSU LTD.
+
+OUI:001F99*
+ ID_OUI_FROM_DATABASE=SERONICS co.ltd
+
+OUI:001F9A*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001F9B*
+ ID_OUI_FROM_DATABASE=POSBRO
+
+OUI:001F9C*
+ ID_OUI_FROM_DATABASE=LEDCO
+
+OUI:001F9D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001F9E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001F9F*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:001FA0*
+ ID_OUI_FROM_DATABASE=A10 Networks
+
+OUI:001FA1*
+ ID_OUI_FROM_DATABASE=Gtran Inc
+
+OUI:001FA2*
+ ID_OUI_FROM_DATABASE=Datron World Communications, Inc.
+
+OUI:001FA3*
+ ID_OUI_FROM_DATABASE=T&W Electronics(Shenzhen)Co.,Ltd.
+
+OUI:001FA4*
+ ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd
+
+OUI:001FA5*
+ ID_OUI_FROM_DATABASE=Blue-White Industries
+
+OUI:001FA6*
+ ID_OUI_FROM_DATABASE=Stilo srl
+
+OUI:001FA7*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+
+OUI:001FA8*
+ ID_OUI_FROM_DATABASE=Smart Energy Instruments Inc.
+
+OUI:001FA9*
+ ID_OUI_FROM_DATABASE=Atlanta DTH, Inc.
+
+OUI:001FAA*
+ ID_OUI_FROM_DATABASE=Taseon, Inc.
+
+OUI:001FAB*
+ ID_OUI_FROM_DATABASE=I.S HIGH TECH.INC
+
+OUI:001FAC*
+ ID_OUI_FROM_DATABASE=Goodmill Systems Ltd
+
+OUI:001FAD*
+ ID_OUI_FROM_DATABASE=Brown Innovations, Inc
+
+OUI:001FAE*
+ ID_OUI_FROM_DATABASE=Blick South Africa (Pty) Ltd
+
+OUI:001FAF*
+ ID_OUI_FROM_DATABASE=NextIO, Inc.
+
+OUI:001FB0*
+ ID_OUI_FROM_DATABASE=TimeIPS, Inc.
+
+OUI:001FB1*
+ ID_OUI_FROM_DATABASE=Cybertech Inc.
+
+OUI:001FB2*
+ ID_OUI_FROM_DATABASE=Sontheim Industrie Elektronik GmbH
+
+OUI:001FB3*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:001FB4*
+ ID_OUI_FROM_DATABASE=SmartShare Systems
+
+OUI:001FB5*
+ ID_OUI_FROM_DATABASE=I/O Interconnect Inc.
+
+OUI:001FB6*
+ ID_OUI_FROM_DATABASE=Chi Lin Technology Co., Ltd.
+
+OUI:001FB7*
+ ID_OUI_FROM_DATABASE=WiMate Technologies Corp.
+
+OUI:001FB8*
+ ID_OUI_FROM_DATABASE=Universal Remote Control, Inc.
+
+OUI:001FB9*
+ ID_OUI_FROM_DATABASE=Paltronics
+
+OUI:001FBA*
+ ID_OUI_FROM_DATABASE=BoYoung Tech. & Marketing, Inc.
+
+OUI:001FBB*
+ ID_OUI_FROM_DATABASE=Xenatech Co.,LTD
+
+OUI:001FBC*
+ ID_OUI_FROM_DATABASE=EVGA Corporation
+
+OUI:001FBD*
+ ID_OUI_FROM_DATABASE=Kyocera Wireless Corp.
+
+OUI:001FBE*
+ ID_OUI_FROM_DATABASE=Shenzhen Mopnet Industrial Co.,Ltd
+
+OUI:001FBF*
+ ID_OUI_FROM_DATABASE=Fulhua Microelectronics Corp. Taiwan Branch
+
+OUI:001FC0*
+ ID_OUI_FROM_DATABASE=Control Express Finland Oy
+
+OUI:001FC1*
+ ID_OUI_FROM_DATABASE=Hanlong Technology Co.,LTD
+
+OUI:001FC2*
+ ID_OUI_FROM_DATABASE=Jow Tong Technology Co Ltd
+
+OUI:001FC3*
+ ID_OUI_FROM_DATABASE=SmartSynch, Inc
+
+OUI:001FC4*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:001FC5*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:001FC6*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:001FC7*
+ ID_OUI_FROM_DATABASE=Casio Hitachi Mobile Comunications Co., Ltd.
+
+OUI:001FC8*
+ ID_OUI_FROM_DATABASE=Up-Today Industrial Co., Ltd.
+
+OUI:001FC9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001FCA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:001FCB*
+ ID_OUI_FROM_DATABASE=NIW Solutions
+
+OUI:001FCC*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:001FCD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:001FCE*
+ ID_OUI_FROM_DATABASE=QTECH LLC
+
+OUI:001FCF*
+ ID_OUI_FROM_DATABASE=MSI Technology GmbH
+
+OUI:001FD0*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:001FD1*
+ ID_OUI_FROM_DATABASE=OPTEX CO.,LTD.
+
+OUI:001FD2*
+ ID_OUI_FROM_DATABASE=COMMTECH TECHNOLOGY MACAO COMMERCIAL OFFSHORE LTD.
+
+OUI:001FD3*
+ ID_OUI_FROM_DATABASE=RIVA Networks Inc.
+
+OUI:001FD4*
+ ID_OUI_FROM_DATABASE=4IPNET, INC.
+
+OUI:001FD5*
+ ID_OUI_FROM_DATABASE=MICRORISC s.r.o.
+
+OUI:001FD6*
+ ID_OUI_FROM_DATABASE=Shenzhen Allywll
+
+OUI:001FD7*
+ ID_OUI_FROM_DATABASE=TELERAD SA
+
+OUI:001FD8*
+ ID_OUI_FROM_DATABASE=A-TRUST COMPUTER CORPORATION
+
+OUI:001FD9*
+ ID_OUI_FROM_DATABASE=RSD Communications Ltd
+
+OUI:001FDA*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:001FDB*
+ ID_OUI_FROM_DATABASE=Network Supply Corp.,
+
+OUI:001FDC*
+ ID_OUI_FROM_DATABASE=Mobile Safe Track Ltd
+
+OUI:001FDD*
+ ID_OUI_FROM_DATABASE=GDI LLC
+
+OUI:001FDE*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001FDF*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:001FE0*
+ ID_OUI_FROM_DATABASE=EdgeVelocity Corp
+
+OUI:001FE1*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:001FE2*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:001FE3*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:001FE4*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:001FE5*
+ ID_OUI_FROM_DATABASE=In-Circuit GmbH
+
+OUI:001FE6*
+ ID_OUI_FROM_DATABASE=Alphion Corporation
+
+OUI:001FE7*
+ ID_OUI_FROM_DATABASE=Simet
+
+OUI:001FE8*
+ ID_OUI_FROM_DATABASE=KURUSUGAWA Electronics Industry Inc,.
+
+OUI:001FE9*
+ ID_OUI_FROM_DATABASE=Printrex, Inc.
+
+OUI:001FEA*
+ ID_OUI_FROM_DATABASE=Applied Media Technologies Corporation
+
+OUI:001FEB*
+ ID_OUI_FROM_DATABASE=Trio Datacom Pty Ltd
+
+OUI:001FEC*
+ ID_OUI_FROM_DATABASE=Synapse Électronique
+
+OUI:001FED*
+ ID_OUI_FROM_DATABASE=Tecan Systems Inc.
+
+OUI:001FEE*
+ ID_OUI_FROM_DATABASE=ubisys technologies GmbH
+
+OUI:001FEF*
+ ID_OUI_FROM_DATABASE=SHINSEI INDUSTRIES CO.,LTD
+
+OUI:001FF0*
+ ID_OUI_FROM_DATABASE=Audio Partnership
+
+OUI:001FF1*
+ ID_OUI_FROM_DATABASE=Paradox Hellas S.A.
+
+OUI:001FF2*
+ ID_OUI_FROM_DATABASE=VIA Technologies, Inc.
+
+OUI:001FF3*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:001FF4*
+ ID_OUI_FROM_DATABASE=Power Monitors, Inc.
+
+OUI:001FF5*
+ ID_OUI_FROM_DATABASE=Kongsberg Defence & Aerospace
+
+OUI:001FF6*
+ ID_OUI_FROM_DATABASE=PS Audio International
+
+OUI:001FF7*
+ ID_OUI_FROM_DATABASE=Nakajima All Precision Co., Ltd.
+
+OUI:001FF8*
+ ID_OUI_FROM_DATABASE=Siemens AG, Sector Industry, Drive Technologies, Motion Control Systems
+
+OUI:001FF9*
+ ID_OUI_FROM_DATABASE=Advanced Knowledge Associates
+
+OUI:001FFA*
+ ID_OUI_FROM_DATABASE=Coretree, Co, Ltd
+
+OUI:001FFB*
+ ID_OUI_FROM_DATABASE=Green Packet Bhd
+
+OUI:001FFC*
+ ID_OUI_FROM_DATABASE=Riccius+Sohn GmbH
+
+OUI:001FFD*
+ ID_OUI_FROM_DATABASE=Indigo Mobile Technologies Corp.
+
+OUI:001FFE*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:001FFF*
+ ID_OUI_FROM_DATABASE=Respironics, Inc.
+
+OUI:002000*
+ ID_OUI_FROM_DATABASE=LEXMARK INTERNATIONAL, INC.
+
+OUI:002001*
+ ID_OUI_FROM_DATABASE=DSP SOLUTIONS, INC.
+
+OUI:002002*
+ ID_OUI_FROM_DATABASE=SERITECH ENTERPRISE CO., LTD.
+
+OUI:002003*
+ ID_OUI_FROM_DATABASE=PIXEL POWER LTD.
+
+OUI:002004*
+ ID_OUI_FROM_DATABASE=YAMATAKE-HONEYWELL CO., LTD.
+
+OUI:002005*
+ ID_OUI_FROM_DATABASE=SIMPLE TECHNOLOGY
+
+OUI:002006*
+ ID_OUI_FROM_DATABASE=GARRETT COMMUNICATIONS, INC.
+
+OUI:002007*
+ ID_OUI_FROM_DATABASE=SFA, INC.
+
+OUI:002008*
+ ID_OUI_FROM_DATABASE=CABLE & COMPUTER TECHNOLOGY
+
+OUI:002009*
+ ID_OUI_FROM_DATABASE=PACKARD BELL ELEC., INC.
+
+OUI:00200A*
+ ID_OUI_FROM_DATABASE=SOURCE-COMM CORP.
+
+OUI:00200B*
+ ID_OUI_FROM_DATABASE=OCTAGON SYSTEMS CORP.
+
+OUI:00200C*
+ ID_OUI_FROM_DATABASE=ADASTRA SYSTEMS CORP.
+
+OUI:00200D*
+ ID_OUI_FROM_DATABASE=CARL ZEISS
+
+OUI:00200E*
+ ID_OUI_FROM_DATABASE=SATELLITE TECHNOLOGY MGMT, INC
+
+OUI:00200F*
+ ID_OUI_FROM_DATABASE=TANBAC CO., LTD.
+
+OUI:002010*
+ ID_OUI_FROM_DATABASE=JEOL SYSTEM TECHNOLOGY CO. LTD
+
+OUI:002011*
+ ID_OUI_FROM_DATABASE=CANOPUS CO., LTD.
+
+OUI:002012*
+ ID_OUI_FROM_DATABASE=CAMTRONICS MEDICAL SYSTEMS
+
+OUI:002013*
+ ID_OUI_FROM_DATABASE=DIVERSIFIED TECHNOLOGY, INC.
+
+OUI:002014*
+ ID_OUI_FROM_DATABASE=GLOBAL VIEW CO., LTD.
+
+OUI:002015*
+ ID_OUI_FROM_DATABASE=ACTIS COMPUTER SA
+
+OUI:002016*
+ ID_OUI_FROM_DATABASE=SHOWA ELECTRIC WIRE & CABLE CO
+
+OUI:002017*
+ ID_OUI_FROM_DATABASE=ORBOTECH
+
+OUI:002018*
+ ID_OUI_FROM_DATABASE=CIS TECHNOLOGY INC.
+
+OUI:002019*
+ ID_OUI_FROM_DATABASE=OHLER GmbH
+
+OUI:00201A*
+ ID_OUI_FROM_DATABASE=MRV Communications, Inc.
+
+OUI:00201B*
+ ID_OUI_FROM_DATABASE=NORTHERN TELECOM/NETWORK
+
+OUI:00201C*
+ ID_OUI_FROM_DATABASE=EXCEL, INC.
+
+OUI:00201D*
+ ID_OUI_FROM_DATABASE=KATANA PRODUCTS
+
+OUI:00201E*
+ ID_OUI_FROM_DATABASE=NETQUEST CORPORATION
+
+OUI:00201F*
+ ID_OUI_FROM_DATABASE=BEST POWER TECHNOLOGY, INC.
+
+OUI:002020*
+ ID_OUI_FROM_DATABASE=MEGATRON COMPUTER INDUSTRIES PTY, LTD.
+
+OUI:002021*
+ ID_OUI_FROM_DATABASE=ALGORITHMS SOFTWARE PVT. LTD.
+
+OUI:002022*
+ ID_OUI_FROM_DATABASE=NMS Communications
+
+OUI:002023*
+ ID_OUI_FROM_DATABASE=T.C. TECHNOLOGIES PTY. LTD
+
+OUI:002024*
+ ID_OUI_FROM_DATABASE=PACIFIC COMMUNICATION SCIENCES
+
+OUI:002025*
+ ID_OUI_FROM_DATABASE=CONTROL TECHNOLOGY, INC.
+
+OUI:002026*
+ ID_OUI_FROM_DATABASE=AMKLY SYSTEMS, INC.
+
+OUI:002027*
+ ID_OUI_FROM_DATABASE=MING FORTUNE INDUSTRY CO., LTD
+
+OUI:002028*
+ ID_OUI_FROM_DATABASE=WEST EGG SYSTEMS, INC.
+
+OUI:002029*
+ ID_OUI_FROM_DATABASE=TELEPROCESSING PRODUCTS, INC.
+
+OUI:00202A*
+ ID_OUI_FROM_DATABASE=N.V. DZINE
+
+OUI:00202B*
+ ID_OUI_FROM_DATABASE=ADVANCED TELECOMMUNICATIONS MODULES, LTD.
+
+OUI:00202C*
+ ID_OUI_FROM_DATABASE=WELLTRONIX CO., LTD.
+
+OUI:00202D*
+ ID_OUI_FROM_DATABASE=TAIYO CORPORATION
+
+OUI:00202E*
+ ID_OUI_FROM_DATABASE=DAYSTAR DIGITAL
+
+OUI:00202F*
+ ID_OUI_FROM_DATABASE=ZETA COMMUNICATIONS, LTD.
+
+OUI:002030*
+ ID_OUI_FROM_DATABASE=ANALOG & DIGITAL SYSTEMS
+
+OUI:002031*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:002032*
+ ID_OUI_FROM_DATABASE=ALCATEL TAISEL
+
+OUI:002033*
+ ID_OUI_FROM_DATABASE=SYNAPSE TECHNOLOGIES, INC.
+
+OUI:002034*
+ ID_OUI_FROM_DATABASE=ROTEC INDUSTRIEAUTOMATION GMBH
+
+OUI:002035*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:002036*
+ ID_OUI_FROM_DATABASE=BMC SOFTWARE
+
+OUI:002037*
+ ID_OUI_FROM_DATABASE=SEAGATE TECHNOLOGY
+
+OUI:002038*
+ ID_OUI_FROM_DATABASE=VME MICROSYSTEMS INTERNATIONAL CORPORATION
+
+OUI:002039*
+ ID_OUI_FROM_DATABASE=SCINETS
+
+OUI:00203A*
+ ID_OUI_FROM_DATABASE=DIGITAL BI0METRICS INC.
+
+OUI:00203B*
+ ID_OUI_FROM_DATABASE=WISDM LTD.
+
+OUI:00203C*
+ ID_OUI_FROM_DATABASE=EUROTIME AB
+
+OUI:00203D*
+ ID_OUI_FROM_DATABASE=Honeywell ECC
+
+OUI:00203E*
+ ID_OUI_FROM_DATABASE=LogiCan Technologies, Inc.
+
+OUI:00203F*
+ ID_OUI_FROM_DATABASE=JUKI CORPORATION
+
+OUI:002040*
+ ID_OUI_FROM_DATABASE=Motorola Broadband Communications Sector
+
+OUI:002041*
+ ID_OUI_FROM_DATABASE=DATA NET
+
+OUI:002042*
+ ID_OUI_FROM_DATABASE=DATAMETRICS CORP.
+
+OUI:002043*
+ ID_OUI_FROM_DATABASE=NEURON COMPANY LIMITED
+
+OUI:002044*
+ ID_OUI_FROM_DATABASE=GENITECH PTY LTD
+
+OUI:002045*
+ ID_OUI_FROM_DATABASE=ION Networks, Inc.
+
+OUI:002046*
+ ID_OUI_FROM_DATABASE=CIPRICO, INC.
+
+OUI:002047*
+ ID_OUI_FROM_DATABASE=STEINBRECHER CORP.
+
+OUI:002048*
+ ID_OUI_FROM_DATABASE=Marconi Communications
+
+OUI:002049*
+ ID_OUI_FROM_DATABASE=COMTRON, INC.
+
+OUI:00204A*
+ ID_OUI_FROM_DATABASE=PRONET GMBH
+
+OUI:00204B*
+ ID_OUI_FROM_DATABASE=AUTOCOMPUTER CO., LTD.
+
+OUI:00204C*
+ ID_OUI_FROM_DATABASE=MITRON COMPUTER PTE LTD.
+
+OUI:00204D*
+ ID_OUI_FROM_DATABASE=INOVIS GMBH
+
+OUI:00204E*
+ ID_OUI_FROM_DATABASE=NETWORK SECURITY SYSTEMS, INC.
+
+OUI:00204F*
+ ID_OUI_FROM_DATABASE=DEUTSCHE AEROSPACE AG
+
+OUI:002050*
+ ID_OUI_FROM_DATABASE=KOREA COMPUTER INC.
+
+OUI:002051*
+ ID_OUI_FROM_DATABASE=Verilink Corporation
+
+OUI:002052*
+ ID_OUI_FROM_DATABASE=RAGULA SYSTEMS
+
+OUI:002053*
+ ID_OUI_FROM_DATABASE=HUNTSVILLE MICROSYSTEMS, INC.
+
+OUI:002054*
+ ID_OUI_FROM_DATABASE=Sycamore Networks
+
+OUI:002055*
+ ID_OUI_FROM_DATABASE=ALTECH CO., LTD.
+
+OUI:002056*
+ ID_OUI_FROM_DATABASE=NEOPRODUCTS
+
+OUI:002057*
+ ID_OUI_FROM_DATABASE=TITZE DATENTECHNIK GmbH
+
+OUI:002058*
+ ID_OUI_FROM_DATABASE=ALLIED SIGNAL INC.
+
+OUI:002059*
+ ID_OUI_FROM_DATABASE=MIRO COMPUTER PRODUCTS AG
+
+OUI:00205A*
+ ID_OUI_FROM_DATABASE=COMPUTER IDENTICS
+
+OUI:00205B*
+ ID_OUI_FROM_DATABASE=Kentrox, LLC
+
+OUI:00205C*
+ ID_OUI_FROM_DATABASE=InterNet Systems of Florida, Inc.
+
+OUI:00205D*
+ ID_OUI_FROM_DATABASE=NANOMATIC OY
+
+OUI:00205E*
+ ID_OUI_FROM_DATABASE=CASTLE ROCK, INC.
+
+OUI:00205F*
+ ID_OUI_FROM_DATABASE=GAMMADATA COMPUTER GMBH
+
+OUI:002060*
+ ID_OUI_FROM_DATABASE=ALCATEL ITALIA S.p.A.
+
+OUI:002061*
+ ID_OUI_FROM_DATABASE=GarrettCom, Inc.
+
+OUI:002062*
+ ID_OUI_FROM_DATABASE=SCORPION LOGIC, LTD.
+
+OUI:002063*
+ ID_OUI_FROM_DATABASE=WIPRO INFOTECH LTD.
+
+OUI:002064*
+ ID_OUI_FROM_DATABASE=PROTEC MICROSYSTEMS, INC.
+
+OUI:002065*
+ ID_OUI_FROM_DATABASE=SUPERNET NETWORKING INC.
+
+OUI:002066*
+ ID_OUI_FROM_DATABASE=GENERAL MAGIC, INC.
+
+OUI:002068*
+ ID_OUI_FROM_DATABASE=ISDYNE
+
+OUI:002069*
+ ID_OUI_FROM_DATABASE=ISDN SYSTEMS CORPORATION
+
+OUI:00206A*
+ ID_OUI_FROM_DATABASE=OSAKA COMPUTER CORP.
+
+OUI:00206B*
+ ID_OUI_FROM_DATABASE=KONICA MINOLTA HOLDINGS, INC.
+
+OUI:00206C*
+ ID_OUI_FROM_DATABASE=EVERGREEN TECHNOLOGY CORP.
+
+OUI:00206D*
+ ID_OUI_FROM_DATABASE=DATA RACE, INC.
+
+OUI:00206E*
+ ID_OUI_FROM_DATABASE=XACT, INC.
+
+OUI:00206F*
+ ID_OUI_FROM_DATABASE=FLOWPOINT CORPORATION
+
+OUI:002070*
+ ID_OUI_FROM_DATABASE=HYNET, LTD.
+
+OUI:002071*
+ ID_OUI_FROM_DATABASE=IBR GMBH
+
+OUI:002072*
+ ID_OUI_FROM_DATABASE=WORKLINK INNOVATIONS
+
+OUI:002073*
+ ID_OUI_FROM_DATABASE=FUSION SYSTEMS CORPORATION
+
+OUI:002074*
+ ID_OUI_FROM_DATABASE=SUNGWOON SYSTEMS
+
+OUI:002075*
+ ID_OUI_FROM_DATABASE=MOTOROLA COMMUNICATION ISRAEL
+
+OUI:002076*
+ ID_OUI_FROM_DATABASE=REUDO CORPORATION
+
+OUI:002077*
+ ID_OUI_FROM_DATABASE=KARDIOS SYSTEMS CORP.
+
+OUI:002078*
+ ID_OUI_FROM_DATABASE=RUNTOP, INC.
+
+OUI:002079*
+ ID_OUI_FROM_DATABASE=MIKRON GMBH
+
+OUI:00207A*
+ ID_OUI_FROM_DATABASE=WiSE Communications, Inc.
+
+OUI:00207B*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:00207C*
+ ID_OUI_FROM_DATABASE=AUTEC GmbH
+
+OUI:00207D*
+ ID_OUI_FROM_DATABASE=ADVANCED COMPUTER APPLICATIONS
+
+OUI:00207E*
+ ID_OUI_FROM_DATABASE=FINECOM Co., Ltd.
+
+OUI:00207F*
+ ID_OUI_FROM_DATABASE=KYOEI SANGYO CO., LTD.
+
+OUI:002080*
+ ID_OUI_FROM_DATABASE=SYNERGY (UK) LTD.
+
+OUI:002081*
+ ID_OUI_FROM_DATABASE=TITAN ELECTRONICS
+
+OUI:002082*
+ ID_OUI_FROM_DATABASE=ONEAC CORPORATION
+
+OUI:002083*
+ ID_OUI_FROM_DATABASE=PRESTICOM INCORPORATED
+
+OUI:002084*
+ ID_OUI_FROM_DATABASE=OCE PRINTING SYSTEMS, GMBH
+
+OUI:002085*
+ ID_OUI_FROM_DATABASE=EXIDE ELECTRONICS
+
+OUI:002086*
+ ID_OUI_FROM_DATABASE=MICROTECH ELECTRONICS LIMITED
+
+OUI:002087*
+ ID_OUI_FROM_DATABASE=MEMOTEC, INC.
+
+OUI:002088*
+ ID_OUI_FROM_DATABASE=GLOBAL VILLAGE COMMUNICATION
+
+OUI:002089*
+ ID_OUI_FROM_DATABASE=T3PLUS NETWORKING, INC.
+
+OUI:00208A*
+ ID_OUI_FROM_DATABASE=SONIX COMMUNICATIONS, LTD.
+
+OUI:00208B*
+ ID_OUI_FROM_DATABASE=LAPIS TECHNOLOGIES, INC.
+
+OUI:00208C*
+ ID_OUI_FROM_DATABASE=GALAXY NETWORKS, INC.
+
+OUI:00208D*
+ ID_OUI_FROM_DATABASE=CMD TECHNOLOGY
+
+OUI:00208E*
+ ID_OUI_FROM_DATABASE=CHEVIN SOFTWARE ENG. LTD.
+
+OUI:00208F*
+ ID_OUI_FROM_DATABASE=ECI TELECOM LTD.
+
+OUI:002090*
+ ID_OUI_FROM_DATABASE=ADVANCED COMPRESSION TECHNOLOGY, INC.
+
+OUI:002091*
+ ID_OUI_FROM_DATABASE=J125, NATIONAL SECURITY AGENCY
+
+OUI:002092*
+ ID_OUI_FROM_DATABASE=CHESS ENGINEERING B.V.
+
+OUI:002093*
+ ID_OUI_FROM_DATABASE=LANDINGS TECHNOLOGY CORP.
+
+OUI:002094*
+ ID_OUI_FROM_DATABASE=CUBIX CORPORATION
+
+OUI:002095*
+ ID_OUI_FROM_DATABASE=RIVA ELECTRONICS
+
+OUI:002096*
+ ID_OUI_FROM_DATABASE=Invensys
+
+OUI:002097*
+ ID_OUI_FROM_DATABASE=APPLIED SIGNAL TECHNOLOGY
+
+OUI:002098*
+ ID_OUI_FROM_DATABASE=HECTRONIC AB
+
+OUI:002099*
+ ID_OUI_FROM_DATABASE=BON ELECTRIC CO., LTD.
+
+OUI:00209A*
+ ID_OUI_FROM_DATABASE=THE 3DO COMPANY
+
+OUI:00209B*
+ ID_OUI_FROM_DATABASE=ERSAT ELECTRONIC GMBH
+
+OUI:00209C*
+ ID_OUI_FROM_DATABASE=PRIMARY ACCESS CORP.
+
+OUI:00209D*
+ ID_OUI_FROM_DATABASE=LIPPERT AUTOMATIONSTECHNIK
+
+OUI:00209E*
+ ID_OUI_FROM_DATABASE=BROWN'S OPERATING SYSTEM SERVICES, LTD.
+
+OUI:00209F*
+ ID_OUI_FROM_DATABASE=MERCURY COMPUTER SYSTEMS, INC.
+
+OUI:0020A0*
+ ID_OUI_FROM_DATABASE=OA LABORATORY CO., LTD.
+
+OUI:0020A1*
+ ID_OUI_FROM_DATABASE=DOVATRON
+
+OUI:0020A2*
+ ID_OUI_FROM_DATABASE=GALCOM NETWORKING LTD.
+
+OUI:0020A3*
+ ID_OUI_FROM_DATABASE=Harmonic, Inc
+
+OUI:0020A4*
+ ID_OUI_FROM_DATABASE=MULTIPOINT NETWORKS
+
+OUI:0020A5*
+ ID_OUI_FROM_DATABASE=API ENGINEERING
+
+OUI:0020A6*
+ ID_OUI_FROM_DATABASE=Proxim Wireless
+
+OUI:0020A7*
+ ID_OUI_FROM_DATABASE=PAIRGAIN TECHNOLOGIES, INC.
+
+OUI:0020A8*
+ ID_OUI_FROM_DATABASE=SAST TECHNOLOGY CORP.
+
+OUI:0020A9*
+ ID_OUI_FROM_DATABASE=WHITE HORSE INDUSTRIAL
+
+OUI:0020AA*
+ ID_OUI_FROM_DATABASE=Ericsson Television Limited
+
+OUI:0020AB*
+ ID_OUI_FROM_DATABASE=MICRO INDUSTRIES CORP.
+
+OUI:0020AC*
+ ID_OUI_FROM_DATABASE=INTERFLEX DATENSYSTEME GMBH
+
+OUI:0020AD*
+ ID_OUI_FROM_DATABASE=LINQ SYSTEMS
+
+OUI:0020AE*
+ ID_OUI_FROM_DATABASE=ORNET DATA COMMUNICATION TECH.
+
+OUI:0020AF*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:0020B0*
+ ID_OUI_FROM_DATABASE=GATEWAY DEVICES, INC.
+
+OUI:0020B1*
+ ID_OUI_FROM_DATABASE=COMTECH RESEARCH INC.
+
+OUI:0020B2*
+ ID_OUI_FROM_DATABASE=GKD Gesellschaft Fur Kommunikation Und Datentechnik
+
+OUI:0020B3*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:0020B4*
+ ID_OUI_FROM_DATABASE=TERMA ELEKTRONIK AS
+
+OUI:0020B5*
+ ID_OUI_FROM_DATABASE=YASKAWA ELECTRIC CORPORATION
+
+OUI:0020B6*
+ ID_OUI_FROM_DATABASE=AGILE NETWORKS, INC.
+
+OUI:0020B7*
+ ID_OUI_FROM_DATABASE=NAMAQUA COMPUTERWARE
+
+OUI:0020B8*
+ ID_OUI_FROM_DATABASE=PRIME OPTION, INC.
+
+OUI:0020B9*
+ ID_OUI_FROM_DATABASE=METRICOM, INC.
+
+OUI:0020BA*
+ ID_OUI_FROM_DATABASE=CENTER FOR HIGH PERFORMANCE
+
+OUI:0020BB*
+ ID_OUI_FROM_DATABASE=ZAX CORPORATION
+
+OUI:0020BC*
+ ID_OUI_FROM_DATABASE=Long Reach Networks Pty Ltd
+
+OUI:0020BD*
+ ID_OUI_FROM_DATABASE=NIOBRARA R & D CORPORATION
+
+OUI:0020BE*
+ ID_OUI_FROM_DATABASE=LAN ACCESS CORP.
+
+OUI:0020BF*
+ ID_OUI_FROM_DATABASE=AEHR TEST SYSTEMS
+
+OUI:0020C0*
+ ID_OUI_FROM_DATABASE=PULSE ELECTRONICS, INC.
+
+OUI:0020C1*
+ ID_OUI_FROM_DATABASE=SAXA, Inc.
+
+OUI:0020C2*
+ ID_OUI_FROM_DATABASE=TEXAS MEMORY SYSTEMS, INC.
+
+OUI:0020C3*
+ ID_OUI_FROM_DATABASE=COUNTER SOLUTIONS LTD.
+
+OUI:0020C4*
+ ID_OUI_FROM_DATABASE=INET,INC.
+
+OUI:0020C5*
+ ID_OUI_FROM_DATABASE=EAGLE TECHNOLOGY
+
+OUI:0020C6*
+ ID_OUI_FROM_DATABASE=NECTEC
+
+OUI:0020C7*
+ ID_OUI_FROM_DATABASE=AKAI Professional M.I. Corp.
+
+OUI:0020C8*
+ ID_OUI_FROM_DATABASE=LARSCOM INCORPORATED
+
+OUI:0020C9*
+ ID_OUI_FROM_DATABASE=VICTRON BV
+
+OUI:0020CA*
+ ID_OUI_FROM_DATABASE=DIGITAL OCEAN
+
+OUI:0020CB*
+ ID_OUI_FROM_DATABASE=PRETEC ELECTRONICS CORP.
+
+OUI:0020CC*
+ ID_OUI_FROM_DATABASE=DIGITAL SERVICES, LTD.
+
+OUI:0020CD*
+ ID_OUI_FROM_DATABASE=HYBRID NETWORKS, INC.
+
+OUI:0020CE*
+ ID_OUI_FROM_DATABASE=LOGICAL DESIGN GROUP, INC.
+
+OUI:0020CF*
+ ID_OUI_FROM_DATABASE=TEST & MEASUREMENT SYSTEMS INC
+
+OUI:0020D0*
+ ID_OUI_FROM_DATABASE=VERSALYNX CORPORATION
+
+OUI:0020D1*
+ ID_OUI_FROM_DATABASE=MICROCOMPUTER SYSTEMS (M) SDN.
+
+OUI:0020D2*
+ ID_OUI_FROM_DATABASE=RAD DATA COMMUNICATIONS, LTD.
+
+OUI:0020D3*
+ ID_OUI_FROM_DATABASE=OST (OUEST STANDARD TELEMATIQU
+
+OUI:0020D4*
+ ID_OUI_FROM_DATABASE=CABLETRON - ZEITTNET INC.
+
+OUI:0020D5*
+ ID_OUI_FROM_DATABASE=VIPA GMBH
+
+OUI:0020D6*
+ ID_OUI_FROM_DATABASE=BREEZECOM
+
+OUI:0020D7*
+ ID_OUI_FROM_DATABASE=JAPAN MINICOMPUTER SYSTEMS CO., Ltd.
+
+OUI:0020D8*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0020D9*
+ ID_OUI_FROM_DATABASE=PANASONIC TECHNOLOGIES, INC./MIECO-US
+
+OUI:0020DA*
+ ID_OUI_FROM_DATABASE=Alcatel North America ESD
+
+OUI:0020DB*
+ ID_OUI_FROM_DATABASE=XNET TECHNOLOGY, INC.
+
+OUI:0020DC*
+ ID_OUI_FROM_DATABASE=DENSITRON TAIWAN LTD.
+
+OUI:0020DD*
+ ID_OUI_FROM_DATABASE=Cybertec Pty Ltd
+
+OUI:0020DE*
+ ID_OUI_FROM_DATABASE=JAPAN DIGITAL LABORAT'Y CO.LTD
+
+OUI:0020DF*
+ ID_OUI_FROM_DATABASE=KYOSAN ELECTRIC MFG. CO., LTD.
+
+OUI:0020E0*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc.
+
+OUI:0020E1*
+ ID_OUI_FROM_DATABASE=ALAMAR ELECTRONICS
+
+OUI:0020E2*
+ ID_OUI_FROM_DATABASE=INFORMATION RESOURCE ENGINEERING
+
+OUI:0020E3*
+ ID_OUI_FROM_DATABASE=MCD KENCOM CORPORATION
+
+OUI:0020E4*
+ ID_OUI_FROM_DATABASE=HSING TECH ENTERPRISE CO., LTD
+
+OUI:0020E5*
+ ID_OUI_FROM_DATABASE=APEX DATA, INC.
+
+OUI:0020E6*
+ ID_OUI_FROM_DATABASE=LIDKOPING MACHINE TOOLS AB
+
+OUI:0020E7*
+ ID_OUI_FROM_DATABASE=B&W NUCLEAR SERVICE COMPANY
+
+OUI:0020E8*
+ ID_OUI_FROM_DATABASE=DATATREK CORPORATION
+
+OUI:0020E9*
+ ID_OUI_FROM_DATABASE=DANTEL
+
+OUI:0020EA*
+ ID_OUI_FROM_DATABASE=EFFICIENT NETWORKS, INC.
+
+OUI:0020EB*
+ ID_OUI_FROM_DATABASE=CINCINNATI MICROWAVE, INC.
+
+OUI:0020EC*
+ ID_OUI_FROM_DATABASE=TECHWARE SYSTEMS CORP.
+
+OUI:0020ED*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO., LTD.
+
+OUI:0020EE*
+ ID_OUI_FROM_DATABASE=GTECH CORPORATION
+
+OUI:0020EF*
+ ID_OUI_FROM_DATABASE=USC CORPORATION
+
+OUI:0020F0*
+ ID_OUI_FROM_DATABASE=UNIVERSAL MICROELECTRONICS CO.
+
+OUI:0020F1*
+ ID_OUI_FROM_DATABASE=ALTOS INDIA LIMITED
+
+OUI:0020F2*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:0020F3*
+ ID_OUI_FROM_DATABASE=RAYNET CORPORATION
+
+OUI:0020F4*
+ ID_OUI_FROM_DATABASE=SPECTRIX CORPORATION
+
+OUI:0020F5*
+ ID_OUI_FROM_DATABASE=PANDATEL AG
+
+OUI:0020F6*
+ ID_OUI_FROM_DATABASE=NET TEK  AND KARLNET, INC.
+
+OUI:0020F7*
+ ID_OUI_FROM_DATABASE=CYBERDATA CORPORATION
+
+OUI:0020F8*
+ ID_OUI_FROM_DATABASE=CARRERA COMPUTERS, INC.
+
+OUI:0020F9*
+ ID_OUI_FROM_DATABASE=PARALINK NETWORKS, INC.
+
+OUI:0020FA*
+ ID_OUI_FROM_DATABASE=GDE SYSTEMS, INC.
+
+OUI:0020FB*
+ ID_OUI_FROM_DATABASE=OCTEL COMMUNICATIONS CORP.
+
+OUI:0020FC*
+ ID_OUI_FROM_DATABASE=MATROX
+
+OUI:0020FD*
+ ID_OUI_FROM_DATABASE=ITV TECHNOLOGIES, INC.
+
+OUI:0020FE*
+ ID_OUI_FROM_DATABASE=TOPWARE INC. / GRAND COMPUTER
+
+OUI:0020FF*
+ ID_OUI_FROM_DATABASE=SYMMETRICAL TECHNOLOGIES
+
+OUI:002100*
+ ID_OUI_FROM_DATABASE=GemTek Technology Co., Ltd.
+
+OUI:002101*
+ ID_OUI_FROM_DATABASE=Aplicaciones Electronicas Quasar (AEQ)
+
+OUI:002102*
+ ID_OUI_FROM_DATABASE=UpdateLogic Inc.
+
+OUI:002103*
+ ID_OUI_FROM_DATABASE=GHI Electronics, LLC
+
+OUI:002104*
+ ID_OUI_FROM_DATABASE=Gigaset Communications GmbH
+
+OUI:002105*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:002106*
+ ID_OUI_FROM_DATABASE=RIM Testing Services
+
+OUI:002107*
+ ID_OUI_FROM_DATABASE=Seowonintech Co Ltd.
+
+OUI:002108*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:002109*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00210A*
+ ID_OUI_FROM_DATABASE=byd:sign Corporation
+
+OUI:00210B*
+ ID_OUI_FROM_DATABASE=GEMINI TRAZE RFID PVT. LTD.
+
+OUI:00210C*
+ ID_OUI_FROM_DATABASE=Cymtec Systems, Inc.
+
+OUI:00210D*
+ ID_OUI_FROM_DATABASE=SAMSIN INNOTEC
+
+OUI:00210E*
+ ID_OUI_FROM_DATABASE=Orpak Systems L.T.D.
+
+OUI:00210F*
+ ID_OUI_FROM_DATABASE=Cernium Corp
+
+OUI:002110*
+ ID_OUI_FROM_DATABASE=Clearbox Systems
+
+OUI:002111*
+ ID_OUI_FROM_DATABASE=Uniphone Inc.
+
+OUI:002112*
+ ID_OUI_FROM_DATABASE=WISCOM SYSTEM CO.,LTD
+
+OUI:002113*
+ ID_OUI_FROM_DATABASE=Padtec S/A
+
+OUI:002114*
+ ID_OUI_FROM_DATABASE=Hylab Technology Inc.
+
+OUI:002115*
+ ID_OUI_FROM_DATABASE=PHYWE Systeme GmbH & Co. KG
+
+OUI:002116*
+ ID_OUI_FROM_DATABASE=Transcon Electronic Systems, spol. s r. o.
+
+OUI:002117*
+ ID_OUI_FROM_DATABASE=Tellord
+
+OUI:002118*
+ ID_OUI_FROM_DATABASE=Athena Tech, Inc.
+
+OUI:002119*
+ ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics
+
+OUI:00211A*
+ ID_OUI_FROM_DATABASE=LInTech Corporation
+
+OUI:00211B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00211C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00211D*
+ ID_OUI_FROM_DATABASE=Dataline AB
+
+OUI:00211E*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00211F*
+ ID_OUI_FROM_DATABASE=SHINSUNG DELTATECH CO.,LTD.
+
+OUI:002120*
+ ID_OUI_FROM_DATABASE=Sequel Technologies
+
+OUI:002121*
+ ID_OUI_FROM_DATABASE=VRmagic GmbH
+
+OUI:002122*
+ ID_OUI_FROM_DATABASE=Chip-pro Ltd.
+
+OUI:002123*
+ ID_OUI_FROM_DATABASE=Aerosat Avionics
+
+OUI:002124*
+ ID_OUI_FROM_DATABASE=Optos Plc
+
+OUI:002125*
+ ID_OUI_FROM_DATABASE=KUK JE TONG SHIN Co.,LTD
+
+OUI:002126*
+ ID_OUI_FROM_DATABASE=Shenzhen Torch Equipment Co., Ltd.
+
+OUI:002127*
+ ID_OUI_FROM_DATABASE=TP-LINK Technology Co., Ltd.
+
+OUI:002128*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:002129*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:00212A*
+ ID_OUI_FROM_DATABASE=Audiovox Corporation
+
+OUI:00212B*
+ ID_OUI_FROM_DATABASE=MSA Auer
+
+OUI:00212C*
+ ID_OUI_FROM_DATABASE=SemIndia System Private Limited
+
+OUI:00212D*
+ ID_OUI_FROM_DATABASE=SCIMOLEX CORPORATION
+
+OUI:00212E*
+ ID_OUI_FROM_DATABASE=dresden-elektronik
+
+OUI:00212F*
+ ID_OUI_FROM_DATABASE=Phoebe Micro Inc.
+
+OUI:002130*
+ ID_OUI_FROM_DATABASE=Keico Hightech Inc.
+
+OUI:002131*
+ ID_OUI_FROM_DATABASE=Blynke Inc.
+
+OUI:002132*
+ ID_OUI_FROM_DATABASE=Masterclock, Inc.
+
+OUI:002133*
+ ID_OUI_FROM_DATABASE=Building B, Inc
+
+OUI:002134*
+ ID_OUI_FROM_DATABASE=Brandywine Communications
+
+OUI:002135*
+ ID_OUI_FROM_DATABASE=ALCATEL-LUCENT
+
+OUI:002136*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002137*
+ ID_OUI_FROM_DATABASE=Bay Controls, LLC
+
+OUI:002138*
+ ID_OUI_FROM_DATABASE=Cepheid
+
+OUI:002139*
+ ID_OUI_FROM_DATABASE=Escherlogic Inc.
+
+OUI:00213A*
+ ID_OUI_FROM_DATABASE=Winchester Systems Inc.
+
+OUI:00213B*
+ ID_OUI_FROM_DATABASE=Berkshire Products, Inc
+
+OUI:00213C*
+ ID_OUI_FROM_DATABASE=AliphCom
+
+OUI:00213D*
+ ID_OUI_FROM_DATABASE=Cermetek Microelectronics, Inc.
+
+OUI:00213E*
+ ID_OUI_FROM_DATABASE=TomTom
+
+OUI:00213F*
+ ID_OUI_FROM_DATABASE=A-Team Technology Ltd.
+
+OUI:002140*
+ ID_OUI_FROM_DATABASE=EN Technologies Inc.
+
+OUI:002141*
+ ID_OUI_FROM_DATABASE=RADLIVE
+
+OUI:002142*
+ ID_OUI_FROM_DATABASE=Advanced Control Systems doo
+
+OUI:002143*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002144*
+ ID_OUI_FROM_DATABASE=SS Telecoms
+
+OUI:002145*
+ ID_OUI_FROM_DATABASE=Semptian Technologies Ltd.
+
+OUI:002146*
+ ID_OUI_FROM_DATABASE=SCI Technology
+
+OUI:002147*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:002148*
+ ID_OUI_FROM_DATABASE=Kaco Solar Korea
+
+OUI:002149*
+ ID_OUI_FROM_DATABASE=China Daheng Group ,Inc.
+
+OUI:00214A*
+ ID_OUI_FROM_DATABASE=Pixel Velocity, Inc
+
+OUI:00214B*
+ ID_OUI_FROM_DATABASE=Shenzhen HAMP Science & Technology Co.,Ltd
+
+OUI:00214C*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD.
+
+OUI:00214D*
+ ID_OUI_FROM_DATABASE=Guangzhou Skytone Transmission Technology Com. Ltd.
+
+OUI:00214E*
+ ID_OUI_FROM_DATABASE=GS Yuasa Power Supply Ltd.
+
+OUI:00214F*
+ ID_OUI_FROM_DATABASE=ALPS Electric Co., Ltd
+
+OUI:002150*
+ ID_OUI_FROM_DATABASE=EYEVIEW ELECTRONICS
+
+OUI:002151*
+ ID_OUI_FROM_DATABASE=Millinet Co., Ltd.
+
+OUI:002152*
+ ID_OUI_FROM_DATABASE=General Satellite Research & Development Limited
+
+OUI:002153*
+ ID_OUI_FROM_DATABASE=SeaMicro Inc.
+
+OUI:002154*
+ ID_OUI_FROM_DATABASE=D-TACQ Solutions Ltd
+
+OUI:002155*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002156*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002157*
+ ID_OUI_FROM_DATABASE=National Datacast, Inc.
+
+OUI:002158*
+ ID_OUI_FROM_DATABASE=Style Flying Technology Co.
+
+OUI:002159*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:00215A*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:00215B*
+ ID_OUI_FROM_DATABASE=Inotive
+
+OUI:00215C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:00215D*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:00215E*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:00215F*
+ ID_OUI_FROM_DATABASE=IHSE GmbH
+
+OUI:002160*
+ ID_OUI_FROM_DATABASE=Hidea Solutions Co. Ltd.
+
+OUI:002161*
+ ID_OUI_FROM_DATABASE=Yournet Inc.
+
+OUI:002162*
+ ID_OUI_FROM_DATABASE=Nortel
+
+OUI:002163*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
+OUI:002164*
+ ID_OUI_FROM_DATABASE=Special Design Bureau for Seismic Instrumentation
+
+OUI:002165*
+ ID_OUI_FROM_DATABASE=Presstek Inc.
+
+OUI:002166*
+ ID_OUI_FROM_DATABASE=NovAtel Inc.
+
+OUI:002167*
+ ID_OUI_FROM_DATABASE=HWA JIN T&I Corp.
+
+OUI:002168*
+ ID_OUI_FROM_DATABASE=iVeia, LLC
+
+OUI:002169*
+ ID_OUI_FROM_DATABASE=Prologix, LLC.
+
+OUI:00216A*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:00216B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:00216C*
+ ID_OUI_FROM_DATABASE=ODVA
+
+OUI:00216D*
+ ID_OUI_FROM_DATABASE=Soltech Co., Ltd.
+
+OUI:00216E*
+ ID_OUI_FROM_DATABASE=Function ATI (Huizhou) Telecommunications Co., Ltd.
+
+OUI:00216F*
+ ID_OUI_FROM_DATABASE=SymCom, Inc.
+
+OUI:002170*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:002171*
+ ID_OUI_FROM_DATABASE=Wesung TNC Co., Ltd.
+
+OUI:002172*
+ ID_OUI_FROM_DATABASE=Seoultek Valley
+
+OUI:002173*
+ ID_OUI_FROM_DATABASE=Ion Torrent Systems, Inc.
+
+OUI:002174*
+ ID_OUI_FROM_DATABASE=AvaLAN Wireless
+
+OUI:002175*
+ ID_OUI_FROM_DATABASE=Pacific Satellite International Ltd.
+
+OUI:002176*
+ ID_OUI_FROM_DATABASE=YMax Telecom Ltd.
+
+OUI:002177*
+ ID_OUI_FROM_DATABASE=W. L. Gore & Associates
+
+OUI:002178*
+ ID_OUI_FROM_DATABASE=Matuschek Messtechnik GmbH
+
+OUI:002179*
+ ID_OUI_FROM_DATABASE=IOGEAR, Inc.
+
+OUI:00217A*
+ ID_OUI_FROM_DATABASE=Sejin Electron, Inc.
+
+OUI:00217B*
+ ID_OUI_FROM_DATABASE=Bastec AB
+
+OUI:00217C*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:00217D*
+ ID_OUI_FROM_DATABASE=PYXIS S.R.L.
+
+OUI:00217E*
+ ID_OUI_FROM_DATABASE=Telit Communication s.p.a
+
+OUI:00217F*
+ ID_OUI_FROM_DATABASE=Intraco Technology Pte Ltd
+
+OUI:002180*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002181*
+ ID_OUI_FROM_DATABASE=Si2 Microsystems Limited
+
+OUI:002182*
+ ID_OUI_FROM_DATABASE=SandLinks Systems, Ltd.
+
+OUI:002183*
+ ID_OUI_FROM_DATABASE=VATECH HYDRO
+
+OUI:002184*
+ ID_OUI_FROM_DATABASE=POWERSOFT SRL
+
+OUI:002185*
+ ID_OUI_FROM_DATABASE=MICRO-STAR INT'L CO.,LTD.
+
+OUI:002186*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd
+
+OUI:002187*
+ ID_OUI_FROM_DATABASE=Imacs GmbH
+
+OUI:002188*
+ ID_OUI_FROM_DATABASE=EMC Corporation
+
+OUI:002189*
+ ID_OUI_FROM_DATABASE=AppTech, Inc.
+
+OUI:00218A*
+ ID_OUI_FROM_DATABASE=Electronic Design and Manufacturing Company
+
+OUI:00218B*
+ ID_OUI_FROM_DATABASE=Wescon Technology, Inc.
+
+OUI:00218C*
+ ID_OUI_FROM_DATABASE=TopControl GMBH
+
+OUI:00218D*
+ ID_OUI_FROM_DATABASE=AP Router Ind. Eletronica LTDA
+
+OUI:00218E*
+ ID_OUI_FROM_DATABASE=MEKICS CO., LTD.
+
+OUI:00218F*
+ ID_OUI_FROM_DATABASE=Avantgarde Acoustic Lautsprechersysteme GmbH
+
+OUI:002190*
+ ID_OUI_FROM_DATABASE=Goliath Solutions
+
+OUI:002191*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:002192*
+ ID_OUI_FROM_DATABASE=Baoding Galaxy Electronic Technology  Co.,Ltd
+
+OUI:002193*
+ ID_OUI_FROM_DATABASE=Videofon MV
+
+OUI:002194*
+ ID_OUI_FROM_DATABASE=Ping Communication
+
+OUI:002195*
+ ID_OUI_FROM_DATABASE=GWD Media Limited
+
+OUI:002196*
+ ID_OUI_FROM_DATABASE=Telsey  S.p.A.
+
+OUI:002197*
+ ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM
+
+OUI:002198*
+ ID_OUI_FROM_DATABASE=Thai Radio Co, LTD
+
+OUI:002199*
+ ID_OUI_FROM_DATABASE=Vacon Plc
+
+OUI:00219A*
+ ID_OUI_FROM_DATABASE=Cambridge Visual Networks Ltd
+
+OUI:00219B*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:00219C*
+ ID_OUI_FROM_DATABASE=Honeywld Technology Corp.
+
+OUI:00219D*
+ ID_OUI_FROM_DATABASE=Adesys BV
+
+OUI:00219E*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:00219F*
+ ID_OUI_FROM_DATABASE=SATEL OY
+
+OUI:0021A0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0021A1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0021A2*
+ ID_OUI_FROM_DATABASE=EKE-Electronics Ltd.
+
+OUI:0021A3*
+ ID_OUI_FROM_DATABASE=Micromint
+
+OUI:0021A4*
+ ID_OUI_FROM_DATABASE=Dbii Networks
+
+OUI:0021A5*
+ ID_OUI_FROM_DATABASE=ERLPhase Power Technologies Ltd.
+
+OUI:0021A6*
+ ID_OUI_FROM_DATABASE=Videotec Spa
+
+OUI:0021A7*
+ ID_OUI_FROM_DATABASE=Hantle System Co., Ltd.
+
+OUI:0021A8*
+ ID_OUI_FROM_DATABASE=Telephonics Corporation
+
+OUI:0021A9*
+ ID_OUI_FROM_DATABASE=Mobilink Telecom Co.,Ltd
+
+OUI:0021AA*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0021AB*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0021AC*
+ ID_OUI_FROM_DATABASE=Infrared Integrated Systems Ltd
+
+OUI:0021AD*
+ ID_OUI_FROM_DATABASE=Nordic ID Oy
+
+OUI:0021AE*
+ ID_OUI_FROM_DATABASE=ALCATEL-LUCENT FRANCE - WTD
+
+OUI:0021AF*
+ ID_OUI_FROM_DATABASE=Radio Frequency Systems
+
+OUI:0021B0*
+ ID_OUI_FROM_DATABASE=Tyco Telecommunications
+
+OUI:0021B1*
+ ID_OUI_FROM_DATABASE=DIGITAL SOLUTIONS LTD
+
+OUI:0021B2*
+ ID_OUI_FROM_DATABASE=Fiberblaze A/S
+
+OUI:0021B3*
+ ID_OUI_FROM_DATABASE=Ross Controls
+
+OUI:0021B4*
+ ID_OUI_FROM_DATABASE=APRO MEDIA CO., LTD
+
+OUI:0021B5*
+ ID_OUI_FROM_DATABASE=Vyro Games Limited
+
+OUI:0021B6*
+ ID_OUI_FROM_DATABASE=Triacta Power Technologies Inc.
+
+OUI:0021B7*
+ ID_OUI_FROM_DATABASE=Lexmark International Inc.
+
+OUI:0021B8*
+ ID_OUI_FROM_DATABASE=Inphi Corporation
+
+OUI:0021B9*
+ ID_OUI_FROM_DATABASE=Universal Devices Inc.
+
+OUI:0021BA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0021BB*
+ ID_OUI_FROM_DATABASE=Riken Keiki Co., Ltd.
+
+OUI:0021BC*
+ ID_OUI_FROM_DATABASE=ZALA COMPUTER
+
+OUI:0021BD*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:0021BE*
+ ID_OUI_FROM_DATABASE=Cisco, Service Provider Video Technology Group
+
+OUI:0021BF*
+ ID_OUI_FROM_DATABASE=Hitachi High-Tech Control Systems Corporation
+
+OUI:0021C0*
+ ID_OUI_FROM_DATABASE=Mobile Appliance, Inc.
+
+OUI:0021C1*
+ ID_OUI_FROM_DATABASE=ABB Oy / Distribution Automation
+
+OUI:0021C2*
+ ID_OUI_FROM_DATABASE=GL Communications Inc
+
+OUI:0021C3*
+ ID_OUI_FROM_DATABASE=CORNELL Communications, Inc.
+
+OUI:0021C4*
+ ID_OUI_FROM_DATABASE=Consilium AB
+
+OUI:0021C5*
+ ID_OUI_FROM_DATABASE=3DSP Corp
+
+OUI:0021C6*
+ ID_OUI_FROM_DATABASE=CSJ Global, Inc.
+
+OUI:0021C7*
+ ID_OUI_FROM_DATABASE=Russound
+
+OUI:0021C8*
+ ID_OUI_FROM_DATABASE=LOHUIS Networks
+
+OUI:0021C9*
+ ID_OUI_FROM_DATABASE=Wavecom Asia Pacific Limited
+
+OUI:0021CA*
+ ID_OUI_FROM_DATABASE=ART System Co., Ltd.
+
+OUI:0021CB*
+ ID_OUI_FROM_DATABASE=SMS TECNOLOGIA ELETRONICA LTDA
+
+OUI:0021CC*
+ ID_OUI_FROM_DATABASE=Flextronics International
+
+OUI:0021CD*
+ ID_OUI_FROM_DATABASE=LiveTV
+
+OUI:0021CE*
+ ID_OUI_FROM_DATABASE=NTC-Metrotek
+
+OUI:0021CF*
+ ID_OUI_FROM_DATABASE=The Crypto Group
+
+OUI:0021D0*
+ ID_OUI_FROM_DATABASE=Global Display Solutions Spa
+
+OUI:0021D1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0021D2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0021D3*
+ ID_OUI_FROM_DATABASE=BOCOM SECURITY(ASIA PACIFIC) LIMITED
+
+OUI:0021D4*
+ ID_OUI_FROM_DATABASE=Vollmer Werke GmbH
+
+OUI:0021D5*
+ ID_OUI_FROM_DATABASE=X2E GmbH
+
+OUI:0021D6*
+ ID_OUI_FROM_DATABASE=LXI Consortium
+
+OUI:0021D7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0021D8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0021D9*
+ ID_OUI_FROM_DATABASE=SEKONIC CORPORATION
+
+OUI:0021DA*
+ ID_OUI_FROM_DATABASE=Automation Products Group Inc.
+
+OUI:0021DB*
+ ID_OUI_FROM_DATABASE=Santachi Video Technology (Shenzhen) Co., Ltd.
+
+OUI:0021DC*
+ ID_OUI_FROM_DATABASE=TECNOALARM S.r.l.
+
+OUI:0021DD*
+ ID_OUI_FROM_DATABASE=Northstar Systems Corp
+
+OUI:0021DE*
+ ID_OUI_FROM_DATABASE=Firepro Wireless
+
+OUI:0021DF*
+ ID_OUI_FROM_DATABASE=Martin Christ GmbH
+
+OUI:0021E0*
+ ID_OUI_FROM_DATABASE=CommAgility Ltd
+
+OUI:0021E1*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0021E2*
+ ID_OUI_FROM_DATABASE=Creative Electronic GmbH
+
+OUI:0021E3*
+ ID_OUI_FROM_DATABASE=SerialTek LLC
+
+OUI:0021E4*
+ ID_OUI_FROM_DATABASE=I-WIN
+
+OUI:0021E5*
+ ID_OUI_FROM_DATABASE=Display Solution AG
+
+OUI:0021E6*
+ ID_OUI_FROM_DATABASE=Starlight Video Limited
+
+OUI:0021E7*
+ ID_OUI_FROM_DATABASE=Informatics Services Corporation
+
+OUI:0021E8*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:0021E9*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:0021EA*
+ ID_OUI_FROM_DATABASE=Bystronic Laser AG
+
+OUI:0021EB*
+ ID_OUI_FROM_DATABASE=ESP SYSTEMS, LLC
+
+OUI:0021EC*
+ ID_OUI_FROM_DATABASE=Solutronic GmbH
+
+OUI:0021ED*
+ ID_OUI_FROM_DATABASE=Telegesis
+
+OUI:0021EE*
+ ID_OUI_FROM_DATABASE=Full Spectrum Inc.
+
+OUI:0021EF*
+ ID_OUI_FROM_DATABASE=Kapsys
+
+OUI:0021F0*
+ ID_OUI_FROM_DATABASE=EW3 Technologies LLC
+
+OUI:0021F1*
+ ID_OUI_FROM_DATABASE=Tutus Data AB
+
+OUI:0021F2*
+ ID_OUI_FROM_DATABASE=EASY3CALL Technology Limited
+
+OUI:0021F3*
+ ID_OUI_FROM_DATABASE=Si14 SpA
+
+OUI:0021F4*
+ ID_OUI_FROM_DATABASE=INRange Systems, Inc
+
+OUI:0021F5*
+ ID_OUI_FROM_DATABASE=Western Engravers Supply, Inc.
+
+OUI:0021F6*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:0021F7*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:0021F8*
+ ID_OUI_FROM_DATABASE=Enseo, Inc.
+
+OUI:0021F9*
+ ID_OUI_FROM_DATABASE=WIRECOM Technologies
+
+OUI:0021FA*
+ ID_OUI_FROM_DATABASE=A4SP Technologies Ltd.
+
+OUI:0021FB*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:0021FC*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0021FD*
+ ID_OUI_FROM_DATABASE=DSTA S.L.
+
+OUI:0021FE*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0021FF*
+ ID_OUI_FROM_DATABASE=Cyfrowy Polsat SA
+
+OUI:002200*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:002201*
+ ID_OUI_FROM_DATABASE=Aksys Networks Inc
+
+OUI:002202*
+ ID_OUI_FROM_DATABASE=Excito Elektronik i Skåne AB
+
+OUI:002203*
+ ID_OUI_FROM_DATABASE=Glensound Electronics Ltd
+
+OUI:002204*
+ ID_OUI_FROM_DATABASE=KORATEK
+
+OUI:002205*
+ ID_OUI_FROM_DATABASE=WeLink Solutions, Inc.
+
+OUI:002206*
+ ID_OUI_FROM_DATABASE=Cyberdyne Inc.
+
+OUI:002207*
+ ID_OUI_FROM_DATABASE=Inteno Broadband Technology AB
+
+OUI:002208*
+ ID_OUI_FROM_DATABASE=Certicom Corp
+
+OUI:002209*
+ ID_OUI_FROM_DATABASE=Omron Healthcare Co., Ltd
+
+OUI:00220A*
+ ID_OUI_FROM_DATABASE=OnLive, Inc
+
+OUI:00220B*
+ ID_OUI_FROM_DATABASE=National Source Coding Center
+
+OUI:00220C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00220D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00220E*
+ ID_OUI_FROM_DATABASE=Indigo Security Co., Ltd.
+
+OUI:00220F*
+ ID_OUI_FROM_DATABASE=MoCA (Multimedia over Coax Alliance)
+
+OUI:002210*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002211*
+ ID_OUI_FROM_DATABASE=Rohati Systems
+
+OUI:002212*
+ ID_OUI_FROM_DATABASE=CAI Networks, Inc.
+
+OUI:002213*
+ ID_OUI_FROM_DATABASE=PCI CORPORATION
+
+OUI:002214*
+ ID_OUI_FROM_DATABASE=RINNAI KOREA
+
+OUI:002215*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:002216*
+ ID_OUI_FROM_DATABASE=SHIBAURA VENDING MACHINE CORPORATION
+
+OUI:002217*
+ ID_OUI_FROM_DATABASE=Neat Electronics
+
+OUI:002218*
+ ID_OUI_FROM_DATABASE=Verivue Inc.
+
+OUI:002219*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:00221A*
+ ID_OUI_FROM_DATABASE=Audio Precision
+
+OUI:00221B*
+ ID_OUI_FROM_DATABASE=Morega Systems
+
+OUI:00221D*
+ ID_OUI_FROM_DATABASE=Freegene Technology LTD
+
+OUI:00221E*
+ ID_OUI_FROM_DATABASE=Media Devices Co., Ltd.
+
+OUI:00221F*
+ ID_OUI_FROM_DATABASE=eSang Technologies Co., Ltd.
+
+OUI:002220*
+ ID_OUI_FROM_DATABASE=Mitac Technology Corp
+
+OUI:002221*
+ ID_OUI_FROM_DATABASE=ITOH DENKI CO,LTD.
+
+OUI:002222*
+ ID_OUI_FROM_DATABASE=Schaffner Deutschland GmbH
+
+OUI:002223*
+ ID_OUI_FROM_DATABASE=TimeKeeping Systems, Inc.
+
+OUI:002224*
+ ID_OUI_FROM_DATABASE=Good Will Instrument Co., Ltd.
+
+OUI:002225*
+ ID_OUI_FROM_DATABASE=Thales Avionics Ltd
+
+OUI:002226*
+ ID_OUI_FROM_DATABASE=Avaak, Inc.
+
+OUI:002227*
+ ID_OUI_FROM_DATABASE=uv-electronic GmbH
+
+OUI:002228*
+ ID_OUI_FROM_DATABASE=Breeze Innovations Ltd.
+
+OUI:002229*
+ ID_OUI_FROM_DATABASE=Compumedics Ltd
+
+OUI:00222A*
+ ID_OUI_FROM_DATABASE=SoundEar A/S
+
+OUI:00222B*
+ ID_OUI_FROM_DATABASE=Nucomm, Inc.
+
+OUI:00222C*
+ ID_OUI_FROM_DATABASE=Ceton Corp
+
+OUI:00222D*
+ ID_OUI_FROM_DATABASE=SMC Networks Inc.
+
+OUI:00222E*
+ ID_OUI_FROM_DATABASE=maintech GmbH
+
+OUI:00222F*
+ ID_OUI_FROM_DATABASE=Open Grid Computing, Inc.
+
+OUI:002230*
+ ID_OUI_FROM_DATABASE=FutureLogic Inc.
+
+OUI:002231*
+ ID_OUI_FROM_DATABASE=SMT&C Co., Ltd.
+
+OUI:002232*
+ ID_OUI_FROM_DATABASE=Design Design Technology Ltd
+
+OUI:002233*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:002234*
+ ID_OUI_FROM_DATABASE=Corventis Inc.
+
+OUI:002235*
+ ID_OUI_FROM_DATABASE=Strukton Systems bv
+
+OUI:002236*
+ ID_OUI_FROM_DATABASE=VECTOR SP. Z O.O.
+
+OUI:002237*
+ ID_OUI_FROM_DATABASE=Shinhint Group
+
+OUI:002238*
+ ID_OUI_FROM_DATABASE=LOGIPLUS
+
+OUI:002239*
+ ID_OUI_FROM_DATABASE=Indiana Life Sciences Incorporated
+
+OUI:00223A*
+ ID_OUI_FROM_DATABASE=Scientific Atlanta, Cisco SPVT Group
+
+OUI:00223B*
+ ID_OUI_FROM_DATABASE=Communication Networks, LLC
+
+OUI:00223C*
+ ID_OUI_FROM_DATABASE=RATIO Entwicklungen GmbH
+
+OUI:00223D*
+ ID_OUI_FROM_DATABASE=JumpGen Systems, LLC
+
+OUI:00223E*
+ ID_OUI_FROM_DATABASE=IRTrans GmbH
+
+OUI:00223F*
+ ID_OUI_FROM_DATABASE=Netgear Inc.
+
+OUI:002240*
+ ID_OUI_FROM_DATABASE=Universal Telecom S/A
+
+OUI:002241*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:002242*
+ ID_OUI_FROM_DATABASE=Alacron Inc.
+
+OUI:002243*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc.
+
+OUI:002244*
+ ID_OUI_FROM_DATABASE=Chengdu Linkon Communications Device Co., Ltd
+
+OUI:002245*
+ ID_OUI_FROM_DATABASE=Leine & Linde AB
+
+OUI:002246*
+ ID_OUI_FROM_DATABASE=Evoc Intelligent Technology Co.,Ltd.
+
+OUI:002247*
+ ID_OUI_FROM_DATABASE=DAC ENGINEERING CO., LTD.
+
+OUI:002248*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:002249*
+ ID_OUI_FROM_DATABASE=HOME MULTIENERGY SL
+
+OUI:00224A*
+ ID_OUI_FROM_DATABASE=RAYLASE AG
+
+OUI:00224B*
+ ID_OUI_FROM_DATABASE=AIRTECH TECHNOLOGIES, INC.
+
+OUI:00224C*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:00224D*
+ ID_OUI_FROM_DATABASE=MITAC INTERNATIONAL CORP.
+
+OUI:00224E*
+ ID_OUI_FROM_DATABASE=SEEnergy Corp.
+
+OUI:00224F*
+ ID_OUI_FROM_DATABASE=Byzoro Networks Ltd.
+
+OUI:002250*
+ ID_OUI_FROM_DATABASE=Point Six Wireless, LLC
+
+OUI:002251*
+ ID_OUI_FROM_DATABASE=Lumasense Technologies
+
+OUI:002252*
+ ID_OUI_FROM_DATABASE=ZOLL Lifecor Corporation
+
+OUI:002253*
+ ID_OUI_FROM_DATABASE=Entorian Technologies
+
+OUI:002254*
+ ID_OUI_FROM_DATABASE=Bigelow Aerospace
+
+OUI:002255*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002256*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002257*
+ ID_OUI_FROM_DATABASE=3Com Europe Ltd
+
+OUI:002258*
+ ID_OUI_FROM_DATABASE=Taiyo Yuden Co., Ltd.
+
+OUI:002259*
+ ID_OUI_FROM_DATABASE=Guangzhou New Postcom Equipment Co.,Ltd.
+
+OUI:00225A*
+ ID_OUI_FROM_DATABASE=Garde Security AB
+
+OUI:00225B*
+ ID_OUI_FROM_DATABASE=Teradici Corporation
+
+OUI:00225C*
+ ID_OUI_FROM_DATABASE=Multimedia & Communication Technology
+
+OUI:00225D*
+ ID_OUI_FROM_DATABASE=Digicable Network India Pvt. Ltd.
+
+OUI:00225E*
+ ID_OUI_FROM_DATABASE=Uwin Technologies Co.,LTD
+
+OUI:00225F*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:002260*
+ ID_OUI_FROM_DATABASE=AFREEY Inc.
+
+OUI:002261*
+ ID_OUI_FROM_DATABASE=Frontier Silicon Ltd
+
+OUI:002262*
+ ID_OUI_FROM_DATABASE=BEP Marine
+
+OUI:002263*
+ ID_OUI_FROM_DATABASE=Koos Technical Services, Inc.
+
+OUI:002264*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:002265*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:002266*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:002267*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:002268*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:002269*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:00226A*
+ ID_OUI_FROM_DATABASE=Honeywell
+
+OUI:00226B*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:00226C*
+ ID_OUI_FROM_DATABASE=LinkSprite Technologies, Inc.
+
+OUI:00226D*
+ ID_OUI_FROM_DATABASE=Shenzhen GIEC Electronics Co., Ltd.
+
+OUI:00226E*
+ ID_OUI_FROM_DATABASE=Gowell Electronic Limited
+
+OUI:00226F*
+ ID_OUI_FROM_DATABASE=3onedata Technology Co. Ltd.
+
+OUI:002270*
+ ID_OUI_FROM_DATABASE=ABK North America, LLC
+
+OUI:002271*
+ ID_OUI_FROM_DATABASE=Jäger Computergesteuerte Meßtechnik GmbH.
+
+OUI:002272*
+ ID_OUI_FROM_DATABASE=American Micro-Fuel Device Corp.
+
+OUI:002273*
+ ID_OUI_FROM_DATABASE=Techway
+
+OUI:002274*
+ ID_OUI_FROM_DATABASE=FamilyPhone AB
+
+OUI:002275*
+ ID_OUI_FROM_DATABASE=Belkin International, Inc.
+
+OUI:002276*
+ ID_OUI_FROM_DATABASE=Triple EYE B.V.
+
+OUI:002277*
+ ID_OUI_FROM_DATABASE=NEC Australia Pty Ltd
+
+OUI:002278*
+ ID_OUI_FROM_DATABASE=Shenzhen  Tongfang Multimedia  Technology Co.,Ltd.
+
+OUI:002279*
+ ID_OUI_FROM_DATABASE=Nippon Conlux Co., Ltd.
+
+OUI:00227A*
+ ID_OUI_FROM_DATABASE=Telecom Design
+
+OUI:00227B*
+ ID_OUI_FROM_DATABASE=Apogee Labs, Inc.
+
+OUI:00227C*
+ ID_OUI_FROM_DATABASE=Woori SMT Co.,ltd
+
+OUI:00227D*
+ ID_OUI_FROM_DATABASE=YE DATA INC.
+
+OUI:00227E*
+ ID_OUI_FROM_DATABASE=Chengdu 30Kaitian Communication Industry Co.Ltd
+
+OUI:00227F*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:002280*
+ ID_OUI_FROM_DATABASE=A2B Electronics AB
+
+OUI:002281*
+ ID_OUI_FROM_DATABASE=Daintree Networks Inc
+
+OUI:002282*
+ ID_OUI_FROM_DATABASE=8086 Limited
+
+OUI:002283*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:002284*
+ ID_OUI_FROM_DATABASE=DESAY A&V SCIENCE AND TECHNOLOGY CO.,LTD
+
+OUI:002285*
+ ID_OUI_FROM_DATABASE=NOMUS COMM SYSTEMS
+
+OUI:002286*
+ ID_OUI_FROM_DATABASE=ASTRON
+
+OUI:002287*
+ ID_OUI_FROM_DATABASE=Titan Wireless LLC
+
+OUI:002288*
+ ID_OUI_FROM_DATABASE=Sagrad, Inc.
+
+OUI:002289*
+ ID_OUI_FROM_DATABASE=Optosecurity Inc.
+
+OUI:00228A*
+ ID_OUI_FROM_DATABASE=Teratronik elektronische systeme gmbh
+
+OUI:00228B*
+ ID_OUI_FROM_DATABASE=Kensington Computer Products Group
+
+OUI:00228C*
+ ID_OUI_FROM_DATABASE=Photon Europe GmbH
+
+OUI:00228D*
+ ID_OUI_FROM_DATABASE=GBS Laboratories LLC
+
+OUI:00228E*
+ ID_OUI_FROM_DATABASE=TV-NUMERIC
+
+OUI:00228F*
+ ID_OUI_FROM_DATABASE=CNRS
+
+OUI:002290*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002291*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002292*
+ ID_OUI_FROM_DATABASE=Cinetal
+
+OUI:002293*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:002294*
+ ID_OUI_FROM_DATABASE=Kyocera Corporation
+
+OUI:002295*
+ ID_OUI_FROM_DATABASE=SGM Technology for lighting spa
+
+OUI:002296*
+ ID_OUI_FROM_DATABASE=LinoWave Corporation
+
+OUI:002297*
+ ID_OUI_FROM_DATABASE=XMOS Semiconductor
+
+OUI:002298*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:002299*
+ ID_OUI_FROM_DATABASE=SeaMicro Inc.
+
+OUI:00229A*
+ ID_OUI_FROM_DATABASE=Lastar, Inc.
+
+OUI:00229B*
+ ID_OUI_FROM_DATABASE=AverLogic Technologies, Inc.
+
+OUI:00229C*
+ ID_OUI_FROM_DATABASE=Verismo Networks Inc
+
+OUI:00229D*
+ ID_OUI_FROM_DATABASE=PYUNG-HWA IND.CO.,LTD
+
+OUI:00229E*
+ ID_OUI_FROM_DATABASE=Social Aid Research Co., Ltd.
+
+OUI:00229F*
+ ID_OUI_FROM_DATABASE=Sensys Traffic AB
+
+OUI:0022A0*
+ ID_OUI_FROM_DATABASE=Delphi Corporation
+
+OUI:0022A1*
+ ID_OUI_FROM_DATABASE=Huawei Symantec Technologies Co.,Ltd.
+
+OUI:0022A2*
+ ID_OUI_FROM_DATABASE=Xtramus Technologies
+
+OUI:0022A3*
+ ID_OUI_FROM_DATABASE=California Eastern Laboratories
+
+OUI:0022A4*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:0022A5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0022A6*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment America
+
+OUI:0022A7*
+ ID_OUI_FROM_DATABASE=Tyco Electronics AMP GmbH
+
+OUI:0022A8*
+ ID_OUI_FROM_DATABASE=Ouman Finland Oy
+
+OUI:0022A9*
+ ID_OUI_FROM_DATABASE=LG Electronics Inc
+
+OUI:0022AA*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:0022AB*
+ ID_OUI_FROM_DATABASE=Shenzhen Turbosight Technology Ltd
+
+OUI:0022AC*
+ ID_OUI_FROM_DATABASE=Hangzhou Siyuan Tech. Co., Ltd
+
+OUI:0022AD*
+ ID_OUI_FROM_DATABASE=TELESIS TECHNOLOGIES, INC.
+
+OUI:0022AE*
+ ID_OUI_FROM_DATABASE=Mattel Inc.
+
+OUI:0022AF*
+ ID_OUI_FROM_DATABASE=Safety Vision
+
+OUI:0022B0*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:0022B1*
+ ID_OUI_FROM_DATABASE=Elbit Systems
+
+OUI:0022B2*
+ ID_OUI_FROM_DATABASE=4RF Communications Ltd
+
+OUI:0022B3*
+ ID_OUI_FROM_DATABASE=Sei S.p.A.
+
+OUI:0022B4*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0022B5*
+ ID_OUI_FROM_DATABASE=NOVITA
+
+OUI:0022B6*
+ ID_OUI_FROM_DATABASE=Superflow Technologies Group
+
+OUI:0022B7*
+ ID_OUI_FROM_DATABASE=GSS Grundig SAT-Systems GmbH
+
+OUI:0022B8*
+ ID_OUI_FROM_DATABASE=Norcott
+
+OUI:0022B9*
+ ID_OUI_FROM_DATABASE=Analogix Seminconductor, Inc
+
+OUI:0022BA*
+ ID_OUI_FROM_DATABASE=HUTH Elektronik Systeme GmbH
+
+OUI:0022BB*
+ ID_OUI_FROM_DATABASE=beyerdynamic GmbH & Co. KG
+
+OUI:0022BC*
+ ID_OUI_FROM_DATABASE=JDSU France SAS
+
+OUI:0022BD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0022BE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0022BF*
+ ID_OUI_FROM_DATABASE=SieAmp Group of Companies
+
+OUI:0022C0*
+ ID_OUI_FROM_DATABASE=Shenzhen Forcelink Electronic Co, Ltd
+
+OUI:0022C1*
+ ID_OUI_FROM_DATABASE=Active Storage Inc.
+
+OUI:0022C2*
+ ID_OUI_FROM_DATABASE=Proview Eletrônica do Brasil LTDA
+
+OUI:0022C3*
+ ID_OUI_FROM_DATABASE=Zeeport Technology Inc.
+
+OUI:0022C4*
+ ID_OUI_FROM_DATABASE=epro GmbH
+
+OUI:0022C5*
+ ID_OUI_FROM_DATABASE=INFORSON Co,Ltd.
+
+OUI:0022C6*
+ ID_OUI_FROM_DATABASE=Sutus Inc
+
+OUI:0022C7*
+ ID_OUI_FROM_DATABASE=SEGGER Microcontroller GmbH & Co. KG
+
+OUI:0022C8*
+ ID_OUI_FROM_DATABASE=Applied Instruments
+
+OUI:0022C9*
+ ID_OUI_FROM_DATABASE=Lenord, Bauer & Co GmbH
+
+OUI:0022CA*
+ ID_OUI_FROM_DATABASE=Anviz Biometric Tech. Co., Ltd.
+
+OUI:0022CB*
+ ID_OUI_FROM_DATABASE=IONODES Inc.
+
+OUI:0022CC*
+ ID_OUI_FROM_DATABASE=SciLog, Inc.
+
+OUI:0022CD*
+ ID_OUI_FROM_DATABASE=Ared Technology Co., Ltd.
+
+OUI:0022CE*
+ ID_OUI_FROM_DATABASE=Cisco, Service Provider Video Technology Group
+
+OUI:0022CF*
+ ID_OUI_FROM_DATABASE=PLANEX Communications INC
+
+OUI:0022D0*
+ ID_OUI_FROM_DATABASE=Polar Electro Oy
+
+OUI:0022D1*
+ ID_OUI_FROM_DATABASE=Albrecht Jung GmbH & Co. KG
+
+OUI:0022D2*
+ ID_OUI_FROM_DATABASE=All Earth Comércio de Eletrônicos LTDA.
+
+OUI:0022D3*
+ ID_OUI_FROM_DATABASE=Hub-Tech
+
+OUI:0022D4*
+ ID_OUI_FROM_DATABASE=ComWorth Co., Ltd.
+
+OUI:0022D5*
+ ID_OUI_FROM_DATABASE=Eaton Corp. Electrical Group Data Center Solutions - Pulizzi
+
+OUI:0022D6*
+ ID_OUI_FROM_DATABASE=Cypak AB
+
+OUI:0022D7*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:0022D8*
+ ID_OUI_FROM_DATABASE=Shenzhen GST Security and Safety Technology Limited
+
+OUI:0022D9*
+ ID_OUI_FROM_DATABASE=Fortex Industrial Ltd.
+
+OUI:0022DA*
+ ID_OUI_FROM_DATABASE=ANATEK, LLC
+
+OUI:0022DB*
+ ID_OUI_FROM_DATABASE=Translogic Corporation
+
+OUI:0022DC*
+ ID_OUI_FROM_DATABASE=Vigil Health Solutions Inc.
+
+OUI:0022DD*
+ ID_OUI_FROM_DATABASE=Protecta Electronics Ltd
+
+OUI:0022DE*
+ ID_OUI_FROM_DATABASE=OPPO Digital, Inc.
+
+OUI:0022DF*
+ ID_OUI_FROM_DATABASE=TAMUZ Monitors
+
+OUI:0022E0*
+ ID_OUI_FROM_DATABASE=Atlantic Software Technologies S.r.L.
+
+OUI:0022E1*
+ ID_OUI_FROM_DATABASE=ZORT Labs, LLC.
+
+OUI:0022E2*
+ ID_OUI_FROM_DATABASE=WABTEC Transit Division
+
+OUI:0022E3*
+ ID_OUI_FROM_DATABASE=Amerigon
+
+OUI:0022E4*
+ ID_OUI_FROM_DATABASE=APASS TECHNOLOGY CO., LTD.
+
+OUI:0022E5*
+ ID_OUI_FROM_DATABASE=Fisher-Rosemount Systems Inc.
+
+OUI:0022E6*
+ ID_OUI_FROM_DATABASE=Intelligent Data
+
+OUI:0022E7*
+ ID_OUI_FROM_DATABASE=WPS Parking Systems
+
+OUI:0022E8*
+ ID_OUI_FROM_DATABASE=Applition Co., Ltd.
+
+OUI:0022E9*
+ ID_OUI_FROM_DATABASE=ProVision Communications
+
+OUI:0022EA*
+ ID_OUI_FROM_DATABASE=Rustelcom Inc.
+
+OUI:0022EB*
+ ID_OUI_FROM_DATABASE=Data Respons A/S
+
+OUI:0022EC*
+ ID_OUI_FROM_DATABASE=IDEALBT TECHNOLOGY CORPORATION
+
+OUI:0022ED*
+ ID_OUI_FROM_DATABASE=TSI Power Corporation
+
+OUI:0022EE*
+ ID_OUI_FROM_DATABASE=Algo Communication Products Ltd
+
+OUI:0022EF*
+ ID_OUI_FROM_DATABASE=Ibis Tek, LLC
+
+OUI:0022F0*
+ ID_OUI_FROM_DATABASE=3 Greens Aviation Limited
+
+OUI:0022F2*
+ ID_OUI_FROM_DATABASE=SunPower Corp
+
+OUI:0022F3*
+ ID_OUI_FROM_DATABASE=SHARP CORPORATION
+
+OUI:0022F4*
+ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
+
+OUI:0022F5*
+ ID_OUI_FROM_DATABASE=Advanced Realtime Tracking GmbH
+
+OUI:0022F6*
+ ID_OUI_FROM_DATABASE=Syracuse Research Corporation
+
+OUI:0022F7*
+ ID_OUI_FROM_DATABASE=Conceptronic
+
+OUI:0022F8*
+ ID_OUI_FROM_DATABASE=PIMA Electronic Systems Ltd.
+
+OUI:0022F9*
+ ID_OUI_FROM_DATABASE=Pollin Electronic GmbH
+
+OUI:0022FA*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0022FB*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0022FC*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0022FD*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0022FE*
+ ID_OUI_FROM_DATABASE=Microprocessor Designs Inc
+
+OUI:0022FF*
+ ID_OUI_FROM_DATABASE=NIVIS LLC
+
+OUI:002300*
+ ID_OUI_FROM_DATABASE=Cayee Computer Ltd.
+
+OUI:002301*
+ ID_OUI_FROM_DATABASE=Witron Technology Limited
+
+OUI:002302*
+ ID_OUI_FROM_DATABASE=Cobalt Digital, Inc.
+
+OUI:002303*
+ ID_OUI_FROM_DATABASE=LITE-ON IT Corporation
+
+OUI:002304*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002305*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002306*
+ ID_OUI_FROM_DATABASE=ALPS Electric Co., Ltd
+
+OUI:002307*
+ ID_OUI_FROM_DATABASE=FUTURE INNOVATION TECH CO.,LTD
+
+OUI:002308*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:002309*
+ ID_OUI_FROM_DATABASE=Janam Technologies LLC
+
+OUI:00230A*
+ ID_OUI_FROM_DATABASE=ARBURG GmbH & Co KG
+
+OUI:00230B*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:00230C*
+ ID_OUI_FROM_DATABASE=CLOVER ELECTRONICS CO.,LTD.
+
+OUI:00230D*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:00230E*
+ ID_OUI_FROM_DATABASE=Gorba AG
+
+OUI:00230F*
+ ID_OUI_FROM_DATABASE=Hirsch Electronics Corporation
+
+OUI:002310*
+ ID_OUI_FROM_DATABASE=LNC Technology Co., Ltd.
+
+OUI:002311*
+ ID_OUI_FROM_DATABASE=Gloscom Co., Ltd.
+
+OUI:002312*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:002313*
+ ID_OUI_FROM_DATABASE=Qool Technologies Ltd.
+
+OUI:002314*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:002315*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:002316*
+ ID_OUI_FROM_DATABASE=KISAN ELECTRONICS CO
+
+OUI:002317*
+ ID_OUI_FROM_DATABASE=Lasercraft Inc
+
+OUI:002318*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:002319*
+ ID_OUI_FROM_DATABASE=Sielox LLC
+
+OUI:00231A*
+ ID_OUI_FROM_DATABASE=ITF Co., Ltd.
+
+OUI:00231B*
+ ID_OUI_FROM_DATABASE=Danaher Motion - Kollmorgen
+
+OUI:00231C*
+ ID_OUI_FROM_DATABASE=Fourier Systems Ltd.
+
+OUI:00231D*
+ ID_OUI_FROM_DATABASE=Deltacom Electronics Ltd
+
+OUI:00231E*
+ ID_OUI_FROM_DATABASE=Cezzer Multimedia Technologies
+
+OUI:00231F*
+ ID_OUI_FROM_DATABASE=Guangda Electronic & Telecommunication Technology Development Co., Ltd.
+
+OUI:002320*
+ ID_OUI_FROM_DATABASE=Nicira Networks
+
+OUI:002321*
+ ID_OUI_FROM_DATABASE=Avitech International Corp
+
+OUI:002322*
+ ID_OUI_FROM_DATABASE=KISS Teknical Solutions, Inc.
+
+OUI:002323*
+ ID_OUI_FROM_DATABASE=Zylin AS
+
+OUI:002324*
+ ID_OUI_FROM_DATABASE=G-PRO COMPUTER
+
+OUI:002325*
+ ID_OUI_FROM_DATABASE=IOLAN Holding
+
+OUI:002326*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
+OUI:002327*
+ ID_OUI_FROM_DATABASE=Shouyo Electronics CO., LTD
+
+OUI:002328*
+ ID_OUI_FROM_DATABASE=ALCON TELECOMMUNICATIONS CO., LTD.
+
+OUI:002329*
+ ID_OUI_FROM_DATABASE=DDRdrive LLC
+
+OUI:00232A*
+ ID_OUI_FROM_DATABASE=eonas IT-Beratung und -Entwicklung GmbH
+
+OUI:00232B*
+ ID_OUI_FROM_DATABASE=IRD A/S
+
+OUI:00232C*
+ ID_OUI_FROM_DATABASE=Senticare
+
+OUI:00232D*
+ ID_OUI_FROM_DATABASE=SandForce
+
+OUI:00232E*
+ ID_OUI_FROM_DATABASE=Kedah Electronics Engineering, LLC
+
+OUI:00232F*
+ ID_OUI_FROM_DATABASE=Advanced Card Systems Ltd.
+
+OUI:002330*
+ ID_OUI_FROM_DATABASE=DIZIPIA, INC.
+
+OUI:002331*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:002332*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:002333*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002334*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002335*
+ ID_OUI_FROM_DATABASE=Linkflex Co.,Ltd
+
+OUI:002336*
+ ID_OUI_FROM_DATABASE=METEL s.r.o.
+
+OUI:002337*
+ ID_OUI_FROM_DATABASE=Global Star Solutions ULC
+
+OUI:002338*
+ ID_OUI_FROM_DATABASE=OJ-Electronics A/S
+
+OUI:002339*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:00233A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:00233B*
+ ID_OUI_FROM_DATABASE=C-Matic Systems Ltd
+
+OUI:00233C*
+ ID_OUI_FROM_DATABASE=Alflex
+
+OUI:00233D*
+ ID_OUI_FROM_DATABASE=Novero holding B.V.
+
+OUI:00233E*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD
+
+OUI:00233F*
+ ID_OUI_FROM_DATABASE=Purechoice Inc
+
+OUI:002340*
+ ID_OUI_FROM_DATABASE=MiX Telematics
+
+OUI:002341*
+ ID_OUI_FROM_DATABASE=Siemens AG, Infrastructure & Cities Sector, Building Technologies Division
+
+OUI:002342*
+ ID_OUI_FROM_DATABASE=Coffee Equipment Company
+
+OUI:002343*
+ ID_OUI_FROM_DATABASE=TEM AG
+
+OUI:002344*
+ ID_OUI_FROM_DATABASE=Objective Interface Systems
+
+OUI:002345*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:002346*
+ ID_OUI_FROM_DATABASE=Vestac
+
+OUI:002347*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:002348*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:002349*
+ ID_OUI_FROM_DATABASE=Helmholtz Centre Berlin for Material and Energy
+
+OUI:00234B*
+ ID_OUI_FROM_DATABASE=Inyuan Technology Inc.
+
+OUI:00234C*
+ ID_OUI_FROM_DATABASE=KTC AB
+
+OUI:00234D*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:00234E*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:00234F*
+ ID_OUI_FROM_DATABASE=Luminous Power Technologies Pvt. Ltd.
+
+OUI:002350*
+ ID_OUI_FROM_DATABASE=LynTec
+
+OUI:002351*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:002352*
+ ID_OUI_FROM_DATABASE=DATASENSOR S.p.A.
+
+OUI:002353*
+ ID_OUI_FROM_DATABASE=F E T Elettronica snc
+
+OUI:002354*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:002355*
+ ID_OUI_FROM_DATABASE=Kinco Automation(Shanghai) Ltd.
+
+OUI:002356*
+ ID_OUI_FROM_DATABASE=Packet Forensics LLC
+
+OUI:002357*
+ ID_OUI_FROM_DATABASE=Pitronot Technologies and Engineering P.T.E. Ltd.
+
+OUI:002358*
+ ID_OUI_FROM_DATABASE=SYSTEL SA
+
+OUI:002359*
+ ID_OUI_FROM_DATABASE=Benchmark Electronics ( Thailand ) Public Company Limited
+
+OUI:00235A*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., Ltd.
+
+OUI:00235B*
+ ID_OUI_FROM_DATABASE=Gulfstream
+
+OUI:00235C*
+ ID_OUI_FROM_DATABASE=Aprius, Inc.
+
+OUI:00235D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00235E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00235F*
+ ID_OUI_FROM_DATABASE=Silicon Micro Sensors GmbH
+
+OUI:002360*
+ ID_OUI_FROM_DATABASE=Lookit Technology Co., Ltd
+
+OUI:002361*
+ ID_OUI_FROM_DATABASE=Unigen Corporation
+
+OUI:002362*
+ ID_OUI_FROM_DATABASE=Goldline Controls
+
+OUI:002363*
+ ID_OUI_FROM_DATABASE=Zhuhai RaySharp Technology Co., Ltd.
+
+OUI:002364*
+ ID_OUI_FROM_DATABASE=Power Instruments Pte Ltd
+
+OUI:002365*
+ ID_OUI_FROM_DATABASE=ELKA-Elektronik GmbH
+
+OUI:002366*
+ ID_OUI_FROM_DATABASE=Beijing Siasun Electronic System Co.,Ltd.
+
+OUI:002367*
+ ID_OUI_FROM_DATABASE=UniControls a.s.
+
+OUI:002368*
+ ID_OUI_FROM_DATABASE=Motorola
+
+OUI:002369*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:00236A*
+ ID_OUI_FROM_DATABASE=SmartRG Inc
+
+OUI:00236B*
+ ID_OUI_FROM_DATABASE=Xembedded, Inc.
+
+OUI:00236C*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:00236D*
+ ID_OUI_FROM_DATABASE=ResMed Ltd
+
+OUI:00236E*
+ ID_OUI_FROM_DATABASE=Burster GmbH & Co KG
+
+OUI:00236F*
+ ID_OUI_FROM_DATABASE=DAQ System
+
+OUI:002370*
+ ID_OUI_FROM_DATABASE=Snell
+
+OUI:002371*
+ ID_OUI_FROM_DATABASE=SOAM Systel
+
+OUI:002372*
+ ID_OUI_FROM_DATABASE=MORE STAR INDUSTRIAL GROUP LIMITED
+
+OUI:002373*
+ ID_OUI_FROM_DATABASE=GridIron Systems, Inc.
+
+OUI:002374*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002375*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002376*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:002377*
+ ID_OUI_FROM_DATABASE=Isotek Electronics Ltd
+
+OUI:002378*
+ ID_OUI_FROM_DATABASE=GN Netcom A/S
+
+OUI:002379*
+ ID_OUI_FROM_DATABASE=Union Business Machines Co. Ltd.
+
+OUI:00237A*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:00237B*
+ ID_OUI_FROM_DATABASE=WHDI LLC
+
+OUI:00237C*
+ ID_OUI_FROM_DATABASE=NEOTION
+
+OUI:00237D*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:00237E*
+ ID_OUI_FROM_DATABASE=ELSTER GMBH
+
+OUI:00237F*
+ ID_OUI_FROM_DATABASE=PLANTRONICS
+
+OUI:002380*
+ ID_OUI_FROM_DATABASE=Nanoteq
+
+OUI:002381*
+ ID_OUI_FROM_DATABASE=Lengda Technology(Xiamen) Co.,Ltd.
+
+OUI:002382*
+ ID_OUI_FROM_DATABASE=Lih Rong Electronic Enterprise Co., Ltd.
+
+OUI:002383*
+ ID_OUI_FROM_DATABASE=InMage Systems Inc
+
+OUI:002384*
+ ID_OUI_FROM_DATABASE=GGH Engineering s.r.l.
+
+OUI:002385*
+ ID_OUI_FROM_DATABASE=ANTIPODE
+
+OUI:002386*
+ ID_OUI_FROM_DATABASE=Tour & Andersson AB
+
+OUI:002387*
+ ID_OUI_FROM_DATABASE=ThinkFlood, Inc.
+
+OUI:002388*
+ ID_OUI_FROM_DATABASE=V.T. Telematica S.p.a.
+
+OUI:002389*
+ ID_OUI_FROM_DATABASE=HANGZHOU H3C Technologies Co., Ltd.
+
+OUI:00238A*
+ ID_OUI_FROM_DATABASE=Ciena Corporation
+
+OUI:00238B*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc.
+
+OUI:00238D*
+ ID_OUI_FROM_DATABASE=Techno Design Co., Ltd.
+
+OUI:00238E*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:00238F*
+ ID_OUI_FROM_DATABASE=NIDEC COPAL CORPORATION
+
+OUI:002390*
+ ID_OUI_FROM_DATABASE=Algolware Corporation
+
+OUI:002391*
+ ID_OUI_FROM_DATABASE=Maxian
+
+OUI:002392*
+ ID_OUI_FROM_DATABASE=Proteus Industries Inc.
+
+OUI:002393*
+ ID_OUI_FROM_DATABASE=AJINEXTEK
+
+OUI:002394*
+ ID_OUI_FROM_DATABASE=Samjeon
+
+OUI:002395*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002396*
+ ID_OUI_FROM_DATABASE=ANDES TECHNOLOGY CORPORATION
+
+OUI:002397*
+ ID_OUI_FROM_DATABASE=Westell Technologies Inc.
+
+OUI:002398*
+ ID_OUI_FROM_DATABASE=Sky Control
+
+OUI:002399*
+ ID_OUI_FROM_DATABASE=VD Division, Samsung Electronics Co.
+
+OUI:00239A*
+ ID_OUI_FROM_DATABASE=EasyData Software GmbH
+
+OUI:00239B*
+ ID_OUI_FROM_DATABASE=Elster Solutions, LLC
+
+OUI:00239C*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:00239D*
+ ID_OUI_FROM_DATABASE=Mapower Electronics Co., Ltd
+
+OUI:00239E*
+ ID_OUI_FROM_DATABASE=Jiangsu Lemote Technology Corporation Limited
+
+OUI:00239F*
+ ID_OUI_FROM_DATABASE=Institut für Prüftechnik
+
+OUI:0023A0*
+ ID_OUI_FROM_DATABASE=Hana CNS Co., LTD.
+
+OUI:0023A1*
+ ID_OUI_FROM_DATABASE=Trend Electronics Ltd
+
+OUI:0023A2*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0023A3*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0023A4*
+ ID_OUI_FROM_DATABASE=New Concepts Development Corp.
+
+OUI:0023A5*
+ ID_OUI_FROM_DATABASE=SageTV, LLC
+
+OUI:0023A6*
+ ID_OUI_FROM_DATABASE=E-Mon
+
+OUI:0023A7*
+ ID_OUI_FROM_DATABASE=Redpine Signals, Inc.
+
+OUI:0023A8*
+ ID_OUI_FROM_DATABASE=Marshall Electronics
+
+OUI:0023A9*
+ ID_OUI_FROM_DATABASE=Beijing Detianquan Electromechanical Equipment Co., Ltd
+
+OUI:0023AA*
+ ID_OUI_FROM_DATABASE=HFR, Inc.
+
+OUI:0023AB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0023AC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0023AD*
+ ID_OUI_FROM_DATABASE=Xmark Corporation
+
+OUI:0023AE*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:0023AF*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0023B0*
+ ID_OUI_FROM_DATABASE=COMXION Technology Inc.
+
+OUI:0023B1*
+ ID_OUI_FROM_DATABASE=Longcheer Technology (Singapore) Pte Ltd
+
+OUI:0023B2*
+ ID_OUI_FROM_DATABASE=Intelligent Mechatronic Systems Inc
+
+OUI:0023B3*
+ ID_OUI_FROM_DATABASE=Lyyn AB
+
+OUI:0023B4*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0023B5*
+ ID_OUI_FROM_DATABASE=ORTANA LTD
+
+OUI:0023B6*
+ ID_OUI_FROM_DATABASE=SECURITE COMMUNICATIONS / HONEYWELL
+
+OUI:0023B7*
+ ID_OUI_FROM_DATABASE=Q-Light Co., Ltd.
+
+OUI:0023B8*
+ ID_OUI_FROM_DATABASE=Sichuan Jiuzhou Electronic Technology Co.,Ltd
+
+OUI:0023B9*
+ ID_OUI_FROM_DATABASE=EADS Deutschland GmbH
+
+OUI:0023BA*
+ ID_OUI_FROM_DATABASE=Chroma
+
+OUI:0023BB*
+ ID_OUI_FROM_DATABASE=Schmitt Industries
+
+OUI:0023BC*
+ ID_OUI_FROM_DATABASE=EQ-SYS GmbH
+
+OUI:0023BD*
+ ID_OUI_FROM_DATABASE=Digital Ally, Inc.
+
+OUI:0023BE*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:0023BF*
+ ID_OUI_FROM_DATABASE=Mainpine, Inc.
+
+OUI:0023C0*
+ ID_OUI_FROM_DATABASE=Broadway Networks
+
+OUI:0023C1*
+ ID_OUI_FROM_DATABASE=Securitas Direct AB
+
+OUI:0023C2*
+ ID_OUI_FROM_DATABASE=SAMSUNG Electronics. Co. LTD
+
+OUI:0023C3*
+ ID_OUI_FROM_DATABASE=LogMeIn, Inc.
+
+OUI:0023C4*
+ ID_OUI_FROM_DATABASE=Lux Lumen
+
+OUI:0023C5*
+ ID_OUI_FROM_DATABASE=Radiation Safety and Control Services Inc
+
+OUI:0023C6*
+ ID_OUI_FROM_DATABASE=SMC Corporation
+
+OUI:0023C7*
+ ID_OUI_FROM_DATABASE=AVSystem
+
+OUI:0023C8*
+ ID_OUI_FROM_DATABASE=TEAM-R
+
+OUI:0023C9*
+ ID_OUI_FROM_DATABASE=Sichuan Tianyi Information Science & Technology Stock CO.,LTD
+
+OUI:0023CA*
+ ID_OUI_FROM_DATABASE=Behind The Set, LLC
+
+OUI:0023CB*
+ ID_OUI_FROM_DATABASE=Shenzhen Full-join Technology Co.,Ltd
+
+OUI:0023CC*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:0023CD*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:0023CE*
+ ID_OUI_FROM_DATABASE=KITA DENSHI CORPORATION
+
+OUI:0023CF*
+ ID_OUI_FROM_DATABASE=CUMMINS-ALLISON CORP.
+
+OUI:0023D0*
+ ID_OUI_FROM_DATABASE=Uniloc USA Inc.
+
+OUI:0023D1*
+ ID_OUI_FROM_DATABASE=TRG
+
+OUI:0023D2*
+ ID_OUI_FROM_DATABASE=Inhand Electronics, Inc.
+
+OUI:0023D3*
+ ID_OUI_FROM_DATABASE=AirLink WiFi Networking Corp.
+
+OUI:0023D4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0023D5*
+ ID_OUI_FROM_DATABASE=WAREMA electronic GmbH
+
+OUI:0023D6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
+OUI:0023D7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:0023D8*
+ ID_OUI_FROM_DATABASE=Ball-It Oy
+
+OUI:0023D9*
+ ID_OUI_FROM_DATABASE=Banner Engineering
+
+OUI:0023DA*
+ ID_OUI_FROM_DATABASE=Industrial Computer Source (Deutschland)GmbH
+
+OUI:0023DB*
+ ID_OUI_FROM_DATABASE=saxnet gmbh
+
+OUI:0023DC*
+ ID_OUI_FROM_DATABASE=Benein, Inc
+
+OUI:0023DD*
+ ID_OUI_FROM_DATABASE=ELGIN S.A.
+
+OUI:0023DE*
+ ID_OUI_FROM_DATABASE=Ansync Inc.
+
+OUI:0023DF*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:0023E0*
+ ID_OUI_FROM_DATABASE=INO Therapeutics LLC
+
+OUI:0023E1*
+ ID_OUI_FROM_DATABASE=Cavena Image Products AB
+
+OUI:0023E2*
+ ID_OUI_FROM_DATABASE=SEA Signalisation
+
+OUI:0023E3*
+ ID_OUI_FROM_DATABASE=Microtronic AG
+
+OUI:0023E4*
+ ID_OUI_FROM_DATABASE=IPnect co. ltd.
+
+OUI:0023E5*
+ ID_OUI_FROM_DATABASE=IPaXiom Networks
+
+OUI:0023E6*
+ ID_OUI_FROM_DATABASE=Pirkus, Inc.
+
+OUI:0023E7*
+ ID_OUI_FROM_DATABASE=Hinke A/S
+
+OUI:0023E8*
+ ID_OUI_FROM_DATABASE=Demco Corp.
+
+OUI:0023E9*
+ ID_OUI_FROM_DATABASE=F5 Networks, Inc.
+
+OUI:0023EA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0023EB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0023EC*
+ ID_OUI_FROM_DATABASE=Algorithmix GmbH
+
+OUI:0023ED*
+ ID_OUI_FROM_DATABASE=Motorola CHS
+
+OUI:0023EE*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0023EF*
+ ID_OUI_FROM_DATABASE=Zuend Systemtechnik AG
+
+OUI:0023F0*
+ ID_OUI_FROM_DATABASE=Shanghai Jinghan Weighing Apparatus Co. Ltd.
+
+OUI:0023F1*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:0023F2*
+ ID_OUI_FROM_DATABASE=TVLogic
+
+OUI:0023F3*
+ ID_OUI_FROM_DATABASE=Glocom, Inc.
+
+OUI:0023F4*
+ ID_OUI_FROM_DATABASE=Masternaut
+
+OUI:0023F5*
+ ID_OUI_FROM_DATABASE=WILO SE
+
+OUI:0023F6*
+ ID_OUI_FROM_DATABASE=Softwell Technology Co., Ltd.
+
+OUI:0023F8*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:0023F9*
+ ID_OUI_FROM_DATABASE=Double-Take Software, INC.
+
+OUI:0023FA*
+ ID_OUI_FROM_DATABASE=RG Nets, Inc.
+
+OUI:0023FB*
+ ID_OUI_FROM_DATABASE=IP Datatel, Inc.
+
+OUI:0023FC*
+ ID_OUI_FROM_DATABASE=Ultra Stereo Labs, Inc
+
+OUI:0023FD*
+ ID_OUI_FROM_DATABASE=AFT Atlas Fahrzeugtechnik GmbH
+
+OUI:0023FE*
+ ID_OUI_FROM_DATABASE=Biodevices, SA
+
+OUI:0023FF*
+ ID_OUI_FROM_DATABASE=Beijing HTTC Technology Ltd.
+
+OUI:002400*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:002401*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:002402*
+ ID_OUI_FROM_DATABASE=Op-Tection GmbH
+
+OUI:002403*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:002404*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:002405*
+ ID_OUI_FROM_DATABASE=Dilog Nordic AB
+
+OUI:002406*
+ ID_OUI_FROM_DATABASE=Pointmobile
+
+OUI:002407*
+ ID_OUI_FROM_DATABASE=TELEM SAS
+
+OUI:002408*
+ ID_OUI_FROM_DATABASE=Pacific Biosciences
+
+OUI:002409*
+ ID_OUI_FROM_DATABASE=The Toro Company
+
+OUI:00240A*
+ ID_OUI_FROM_DATABASE=US Beverage Net
+
+OUI:00240B*
+ ID_OUI_FROM_DATABASE=Virtual Computer Inc.
+
+OUI:00240C*
+ ID_OUI_FROM_DATABASE=DELEC GmbH
+
+OUI:00240D*
+ ID_OUI_FROM_DATABASE=OnePath Networks LTD.
+
+OUI:00240E*
+ ID_OUI_FROM_DATABASE=Inventec Besta Co., Ltd.
+
+OUI:00240F*
+ ID_OUI_FROM_DATABASE=Ishii Tool & Engineering Corporation
+
+OUI:002410*
+ ID_OUI_FROM_DATABASE=NUETEQ Technology,Inc.
+
+OUI:002411*
+ ID_OUI_FROM_DATABASE=PharmaSmart LLC
+
+OUI:002412*
+ ID_OUI_FROM_DATABASE=Benign Technologies Co, Ltd.
+
+OUI:002413*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002414*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002415*
+ ID_OUI_FROM_DATABASE=Magnetic Autocontrol GmbH
+
+OUI:002416*
+ ID_OUI_FROM_DATABASE=Any Use
+
+OUI:002417*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:002418*
+ ID_OUI_FROM_DATABASE=Nextwave Semiconductor
+
+OUI:00241A*
+ ID_OUI_FROM_DATABASE=Red Beetle Inc.
+
+OUI:00241B*
+ ID_OUI_FROM_DATABASE=iWOW Communications Pte Ltd
+
+OUI:00241C*
+ ID_OUI_FROM_DATABASE=FuGang Electronic (DG) Co.,Ltd
+
+OUI:00241D*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:00241E*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:00241F*
+ ID_OUI_FROM_DATABASE=DCT-Delta GmbH
+
+OUI:002420*
+ ID_OUI_FROM_DATABASE=NetUP Inc.
+
+OUI:002421*
+ ID_OUI_FROM_DATABASE=MICRO-STAR INT'L CO., LTD.
+
+OUI:002422*
+ ID_OUI_FROM_DATABASE=Knapp Logistik Automation GmbH
+
+OUI:002423*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies (Shanghai) Inc.
+
+OUI:002424*
+ ID_OUI_FROM_DATABASE=Axis Network Technology
+
+OUI:002425*
+ ID_OUI_FROM_DATABASE=Shenzhenshi chuangzhicheng Technology Co.,Ltd
+
+OUI:002426*
+ ID_OUI_FROM_DATABASE=NOHMI BOSAI LTD.
+
+OUI:002427*
+ ID_OUI_FROM_DATABASE=SSI COMPUTER CORP
+
+OUI:002428*
+ ID_OUI_FROM_DATABASE=EnergyICT
+
+OUI:002429*
+ ID_OUI_FROM_DATABASE=MK MASTER INC.
+
+OUI:00242A*
+ ID_OUI_FROM_DATABASE=Hittite Microwave Corporation
+
+OUI:00242B*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.,Ltd.
+
+OUI:00242C*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:00242E*
+ ID_OUI_FROM_DATABASE=Datastrip Inc.
+
+OUI:00242F*
+ ID_OUI_FROM_DATABASE=VirtenSys Inc
+
+OUI:002430*
+ ID_OUI_FROM_DATABASE=Ruby Tech Corp.
+
+OUI:002431*
+ ID_OUI_FROM_DATABASE=Uni-v co.,ltd
+
+OUI:002432*
+ ID_OUI_FROM_DATABASE=Neostar Technology Co.,LTD
+
+OUI:002433*
+ ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd
+
+OUI:002434*
+ ID_OUI_FROM_DATABASE=Lectrosonics, Inc.
+
+OUI:002435*
+ ID_OUI_FROM_DATABASE=WIDE CORPORATION
+
+OUI:002436*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:002437*
+ ID_OUI_FROM_DATABASE=Motorola - BSG
+
+OUI:002438*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc
+
+OUI:002439*
+ ID_OUI_FROM_DATABASE=Essential Viewing Systems Limited
+
+OUI:00243A*
+ ID_OUI_FROM_DATABASE=Ludl Electronic Products
+
+OUI:00243B*
+ ID_OUI_FROM_DATABASE=CSSI (S) Pte Ltd
+
+OUI:00243C*
+ ID_OUI_FROM_DATABASE=S.A.A.A.
+
+OUI:00243D*
+ ID_OUI_FROM_DATABASE=Emerson Appliance Motors and Controls
+
+OUI:00243F*
+ ID_OUI_FROM_DATABASE=Storwize, Inc.
+
+OUI:002440*
+ ID_OUI_FROM_DATABASE=Halo Monitoring, Inc.
+
+OUI:002441*
+ ID_OUI_FROM_DATABASE=Wanzl Metallwarenfabrik GmbH
+
+OUI:002442*
+ ID_OUI_FROM_DATABASE=Axona Limited
+
+OUI:002443*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:002444*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:002445*
+ ID_OUI_FROM_DATABASE=LiquidxStream Systems Inc.
+
+OUI:002446*
+ ID_OUI_FROM_DATABASE=MMB Research Inc.
+
+OUI:002447*
+ ID_OUI_FROM_DATABASE=Kaztek Systems
+
+OUI:002448*
+ ID_OUI_FROM_DATABASE=SpiderCloud Wireless, Inc
+
+OUI:002449*
+ ID_OUI_FROM_DATABASE=Shen Zhen Lite Star Electronics Technology Co., Ltd
+
+OUI:00244A*
+ ID_OUI_FROM_DATABASE=Voyant International
+
+OUI:00244B*
+ ID_OUI_FROM_DATABASE=PERCEPTRON INC
+
+OUI:00244C*
+ ID_OUI_FROM_DATABASE=Solartron Metrology Ltd
+
+OUI:00244D*
+ ID_OUI_FROM_DATABASE=Hokkaido Electronics Corporation
+
+OUI:00244E*
+ ID_OUI_FROM_DATABASE=RadChips, Inc.
+
+OUI:00244F*
+ ID_OUI_FROM_DATABASE=Asantron Technologies Ltd.
+
+OUI:002450*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002451*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002452*
+ ID_OUI_FROM_DATABASE=Silicon Software GmbH
+
+OUI:002453*
+ ID_OUI_FROM_DATABASE=Initra d.o.o.
+
+OUI:002454*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
+
+OUI:002455*
+ ID_OUI_FROM_DATABASE=MuLogic BV
+
+OUI:002456*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:002458*
+ ID_OUI_FROM_DATABASE=PA Bastion CC
+
+OUI:002459*
+ ID_OUI_FROM_DATABASE=ABB STOTZ-KONTAKT GmbH
+
+OUI:00245A*
+ ID_OUI_FROM_DATABASE=Nanjing Panda Electronics Company Limited
+
+OUI:00245B*
+ ID_OUI_FROM_DATABASE=RAIDON TECHNOLOGY, INC.
+
+OUI:00245C*
+ ID_OUI_FROM_DATABASE=Design-Com Technologies Pty. Ltd.
+
+OUI:00245D*
+ ID_OUI_FROM_DATABASE=Terberg besturingstechniek B.V.
+
+OUI:00245E*
+ ID_OUI_FROM_DATABASE=Hivision Co.,ltd
+
+OUI:00245F*
+ ID_OUI_FROM_DATABASE=Vine Telecom CO.,Ltd.
+
+OUI:002460*
+ ID_OUI_FROM_DATABASE=Giaval Science Development Co. Ltd.
+
+OUI:002461*
+ ID_OUI_FROM_DATABASE=Shin Wang Tech.
+
+OUI:002462*
+ ID_OUI_FROM_DATABASE=Rayzone Corporation
+
+OUI:002463*
+ ID_OUI_FROM_DATABASE=Phybridge Inc
+
+OUI:002464*
+ ID_OUI_FROM_DATABASE=Bridge Technologies Co AS
+
+OUI:002465*
+ ID_OUI_FROM_DATABASE=Elentec
+
+OUI:002466*
+ ID_OUI_FROM_DATABASE=Unitron nv
+
+OUI:002467*
+ ID_OUI_FROM_DATABASE=AOC International (Europe) GmbH
+
+OUI:002468*
+ ID_OUI_FROM_DATABASE=Sumavision Technologies Co.,Ltd
+
+OUI:002469*
+ ID_OUI_FROM_DATABASE=Smart Doorphones
+
+OUI:00246A*
+ ID_OUI_FROM_DATABASE=Solid Year Co., Ltd.
+
+OUI:00246B*
+ ID_OUI_FROM_DATABASE=Covia, Inc.
+
+OUI:00246C*
+ ID_OUI_FROM_DATABASE=ARUBA NETWORKS, INC.
+
+OUI:00246D*
+ ID_OUI_FROM_DATABASE=Weinzierl Engineering GmbH
+
+OUI:00246E*
+ ID_OUI_FROM_DATABASE=Phihong USA Corp.
+
+OUI:00246F*
+ ID_OUI_FROM_DATABASE=Onda Communication spa
+
+OUI:002470*
+ ID_OUI_FROM_DATABASE=AUROTECH ultrasound AS.
+
+OUI:002471*
+ ID_OUI_FROM_DATABASE=Fusion MultiSystems dba Fusion-io
+
+OUI:002472*
+ ID_OUI_FROM_DATABASE=ReDriven Power Inc.
+
+OUI:002473*
+ ID_OUI_FROM_DATABASE=3Com Europe Ltd
+
+OUI:002474*
+ ID_OUI_FROM_DATABASE=Autronica Fire And Securirty
+
+OUI:002475*
+ ID_OUI_FROM_DATABASE=Compass System(Embedded Dept.)
+
+OUI:002476*
+ ID_OUI_FROM_DATABASE=TAP.tv
+
+OUI:002477*
+ ID_OUI_FROM_DATABASE=Tibbo Technology
+
+OUI:002478*
+ ID_OUI_FROM_DATABASE=Mag Tech Electronics Co Limited
+
+OUI:002479*
+ ID_OUI_FROM_DATABASE=Optec Displays, Inc.
+
+OUI:00247A*
+ ID_OUI_FROM_DATABASE=FU YI CHENG Technology Co., Ltd.
+
+OUI:00247B*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:00247C*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00247D*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00247E*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd
+
+OUI:00247F*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:002480*
+ ID_OUI_FROM_DATABASE=Meteocontrol GmbH
+
+OUI:002481*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:002482*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:002483*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:002484*
+ ID_OUI_FROM_DATABASE=Bang and Olufsen Medicom a/s
+
+OUI:002485*
+ ID_OUI_FROM_DATABASE=ConteXtream Ltd
+
+OUI:002486*
+ ID_OUI_FROM_DATABASE=DesignArt Networks
+
+OUI:002487*
+ ID_OUI_FROM_DATABASE=Blackboard Inc.
+
+OUI:002488*
+ ID_OUI_FROM_DATABASE=Centre For Development Of Telematics
+
+OUI:002489*
+ ID_OUI_FROM_DATABASE=Vodafone Omnitel N.V.
+
+OUI:00248A*
+ ID_OUI_FROM_DATABASE=Kaga Electronics Co., Ltd.
+
+OUI:00248B*
+ ID_OUI_FROM_DATABASE=HYBUS CO., LTD.
+
+OUI:00248C*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:00248D*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+
+OUI:00248E*
+ ID_OUI_FROM_DATABASE=Infoware ZRt.
+
+OUI:00248F*
+ ID_OUI_FROM_DATABASE=DO-MONIX
+
+OUI:002490*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
+OUI:002491*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:002492*
+ ID_OUI_FROM_DATABASE=Motorola, Broadband Solutions Group
+
+OUI:002493*
+ ID_OUI_FROM_DATABASE=Motorola, Inc
+
+OUI:002494*
+ ID_OUI_FROM_DATABASE=Shenzhen Baoxin Tech CO., Ltd.
+
+OUI:002495*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002496*
+ ID_OUI_FROM_DATABASE=Ginzinger electronic systems
+
+OUI:002497*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002498*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002499*
+ ID_OUI_FROM_DATABASE=Aquila Technologies
+
+OUI:00249A*
+ ID_OUI_FROM_DATABASE=Beijing Zhongchuang Telecommunication Test Co., Ltd.
+
+OUI:00249B*
+ ID_OUI_FROM_DATABASE=Action Star Enterprise Co., Ltd.
+
+OUI:00249C*
+ ID_OUI_FROM_DATABASE=Bimeng Comunication System Co. Ltd
+
+OUI:00249D*
+ ID_OUI_FROM_DATABASE=NES Technology Inc.
+
+OUI:00249E*
+ ID_OUI_FROM_DATABASE=ADC-Elektronik GmbH
+
+OUI:00249F*
+ ID_OUI_FROM_DATABASE=RIM Testing Services
+
+OUI:0024A0*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0024A1*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0024A2*
+ ID_OUI_FROM_DATABASE=Hong Kong Middleware Technology Limited
+
+OUI:0024A3*
+ ID_OUI_FROM_DATABASE=Sonim Technologies Inc
+
+OUI:0024A4*
+ ID_OUI_FROM_DATABASE=Siklu Communication
+
+OUI:0024A5*
+ ID_OUI_FROM_DATABASE=Buffalo Inc.
+
+OUI:0024A6*
+ ID_OUI_FROM_DATABASE=TELESTAR DIGITAL GmbH
+
+OUI:0024A7*
+ ID_OUI_FROM_DATABASE=Advanced Video Communications Inc.
+
+OUI:0024A8*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:0024A9*
+ ID_OUI_FROM_DATABASE=Ag Leader Technology
+
+OUI:0024AA*
+ ID_OUI_FROM_DATABASE=Dycor Technologies Ltd.
+
+OUI:0024AB*
+ ID_OUI_FROM_DATABASE=A7 Engineering, Inc.
+
+OUI:0024AC*
+ ID_OUI_FROM_DATABASE=Hangzhou DPtech Technologies Co., Ltd.
+
+OUI:0024AD*
+ ID_OUI_FROM_DATABASE=Adolf Thies Gmbh & Co. KG
+
+OUI:0024AE*
+ ID_OUI_FROM_DATABASE=Morpho
+
+OUI:0024AF*
+ ID_OUI_FROM_DATABASE=EchoStar Technologies
+
+OUI:0024B0*
+ ID_OUI_FROM_DATABASE=ESAB AB
+
+OUI:0024B1*
+ ID_OUI_FROM_DATABASE=Coulomb Technologies
+
+OUI:0024B2*
+ ID_OUI_FROM_DATABASE=Netgear
+
+OUI:0024B3*
+ ID_OUI_FROM_DATABASE=Graf-Syteco GmbH & Co. KG
+
+OUI:0024B4*
+ ID_OUI_FROM_DATABASE=ESCATRONIC GmbH
+
+OUI:0024B5*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0024B6*
+ ID_OUI_FROM_DATABASE=Seagate Technology
+
+OUI:0024B7*
+ ID_OUI_FROM_DATABASE=GridPoint, Inc.
+
+OUI:0024B8*
+ ID_OUI_FROM_DATABASE=free alliance sdn bhd
+
+OUI:0024B9*
+ ID_OUI_FROM_DATABASE=Wuhan Higheasy Electronic Technology Development Co.Ltd
+
+OUI:0024BA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:0024BB*
+ ID_OUI_FROM_DATABASE=CENTRAL Corporation
+
+OUI:0024BC*
+ ID_OUI_FROM_DATABASE=HuRob Co.,Ltd
+
+OUI:0024BD*
+ ID_OUI_FROM_DATABASE=Hainzl Industriesysteme GmbH
+
+OUI:0024BE*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:0024BF*
+ ID_OUI_FROM_DATABASE=CIAT
+
+OUI:0024C0*
+ ID_OUI_FROM_DATABASE=NTI COMODO INC
+
+OUI:0024C1*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0024C2*
+ ID_OUI_FROM_DATABASE=Asumo Co.,Ltd.
+
+OUI:0024C3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0024C4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0024C5*
+ ID_OUI_FROM_DATABASE=Meridian Audio Limited
+
+OUI:0024C6*
+ ID_OUI_FROM_DATABASE=Hager Electro SAS
+
+OUI:0024C7*
+ ID_OUI_FROM_DATABASE=Mobilarm Ltd
+
+OUI:0024C8*
+ ID_OUI_FROM_DATABASE=Broadband Solutions Group
+
+OUI:0024C9*
+ ID_OUI_FROM_DATABASE=Broadband Solutions Group
+
+OUI:0024CA*
+ ID_OUI_FROM_DATABASE=Tobii Technology AB
+
+OUI:0024CB*
+ ID_OUI_FROM_DATABASE=Autonet Mobile
+
+OUI:0024CC*
+ ID_OUI_FROM_DATABASE=Fascinations Toys and Gifts, Inc.
+
+OUI:0024CD*
+ ID_OUI_FROM_DATABASE=Willow Garage, Inc.
+
+OUI:0024CE*
+ ID_OUI_FROM_DATABASE=Exeltech Inc
+
+OUI:0024CF*
+ ID_OUI_FROM_DATABASE=Inscape Data Corporation
+
+OUI:0024D0*
+ ID_OUI_FROM_DATABASE=Shenzhen SOGOOD Industry CO.,LTD.
+
+OUI:0024D1*
+ ID_OUI_FROM_DATABASE=Thomson Inc.
+
+OUI:0024D2*
+ ID_OUI_FROM_DATABASE=Askey Computer
+
+OUI:0024D3*
+ ID_OUI_FROM_DATABASE=QUALICA Inc.
+
+OUI:0024D4*
+ ID_OUI_FROM_DATABASE=FREEBOX SA
+
+OUI:0024D5*
+ ID_OUI_FROM_DATABASE=Winward Industrial Limited
+
+OUI:0024D6*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0024D7*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0024D8*
+ ID_OUI_FROM_DATABASE=IlSung Precision
+
+OUI:0024D9*
+ ID_OUI_FROM_DATABASE=BICOM, Inc.
+
+OUI:0024DA*
+ ID_OUI_FROM_DATABASE=Innovar Systems Limited
+
+OUI:0024DB*
+ ID_OUI_FROM_DATABASE=Alcohol Monitoring Systems
+
+OUI:0024DC*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:0024DD*
+ ID_OUI_FROM_DATABASE=Centrak, Inc.
+
+OUI:0024DE*
+ ID_OUI_FROM_DATABASE=GLOBAL Technology Inc.
+
+OUI:0024DF*
+ ID_OUI_FROM_DATABASE=Digitalbox Europe GmbH
+
+OUI:0024E0*
+ ID_OUI_FROM_DATABASE=DS Tech, LLC
+
+OUI:0024E1*
+ ID_OUI_FROM_DATABASE=Convey Computer Corp.
+
+OUI:0024E2*
+ ID_OUI_FROM_DATABASE=HASEGAWA ELECTRIC CO.,LTD.
+
+OUI:0024E3*
+ ID_OUI_FROM_DATABASE=CAO Group
+
+OUI:0024E4*
+ ID_OUI_FROM_DATABASE=Withings
+
+OUI:0024E5*
+ ID_OUI_FROM_DATABASE=Seer Technology, Inc
+
+OUI:0024E6*
+ ID_OUI_FROM_DATABASE=In Motion Technology Inc.
+
+OUI:0024E7*
+ ID_OUI_FROM_DATABASE=Plaster Networks
+
+OUI:0024E8*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:0024E9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd., Storage System Division
+
+OUI:0024EA*
+ ID_OUI_FROM_DATABASE=iris-GmbH infrared & intelligent sensors
+
+OUI:0024EB*
+ ID_OUI_FROM_DATABASE=ClearPath Networks, Inc.
+
+OUI:0024EC*
+ ID_OUI_FROM_DATABASE=United Information Technology Co.,Ltd.
+
+OUI:0024ED*
+ ID_OUI_FROM_DATABASE=YT Elec. Co,.Ltd.
+
+OUI:0024EE*
+ ID_OUI_FROM_DATABASE=Wynmax Inc.
+
+OUI:0024EF*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:0024F0*
+ ID_OUI_FROM_DATABASE=Seanodes
+
+OUI:0024F1*
+ ID_OUI_FROM_DATABASE=Shenzhen Fanhai Sanjiang Electronics Co., Ltd.
+
+OUI:0024F2*
+ ID_OUI_FROM_DATABASE=Uniphone Telecommunication Co., Ltd.
+
+OUI:0024F3*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:0024F4*
+ ID_OUI_FROM_DATABASE=Kaminario Technologies Ltd.
+
+OUI:0024F5*
+ ID_OUI_FROM_DATABASE=NDS Surgical Imaging
+
+OUI:0024F6*
+ ID_OUI_FROM_DATABASE=MIYOSHI ELECTRONICS CORPORATION
+
+OUI:0024F7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0024F8*
+ ID_OUI_FROM_DATABASE=Technical Solutions Company Ltd.
+
+OUI:0024F9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0024FA*
+ ID_OUI_FROM_DATABASE=Hilger u. Kern GMBH
+
+OUI:0024FC*
+ ID_OUI_FROM_DATABASE=QuoPin Co., Ltd.
+
+OUI:0024FD*
+ ID_OUI_FROM_DATABASE=Accedian Networks Inc
+
+OUI:0024FE*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:0024FF*
+ ID_OUI_FROM_DATABASE=QLogic Corporation
+
+OUI:002500*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:002501*
+ ID_OUI_FROM_DATABASE=JSC "Supertel"
+
+OUI:002502*
+ ID_OUI_FROM_DATABASE=NaturalPoint
+
+OUI:002503*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:002504*
+ ID_OUI_FROM_DATABASE=Valiant Communications Limited
+
+OUI:002505*
+ ID_OUI_FROM_DATABASE=eks Engel GmbH & Co. KG
+
+OUI:002506*
+ ID_OUI_FROM_DATABASE=A.I. ANTITACCHEGGIO ITALIA SRL
+
+OUI:002507*
+ ID_OUI_FROM_DATABASE=ASTAK Inc.
+
+OUI:002508*
+ ID_OUI_FROM_DATABASE=Maquet Cardiopulmonary AG
+
+OUI:002509*
+ ID_OUI_FROM_DATABASE=SHARETRONIC Group LTD
+
+OUI:00250A*
+ ID_OUI_FROM_DATABASE=Security Expert Co. Ltd
+
+OUI:00250B*
+ ID_OUI_FROM_DATABASE=CENTROFACTOR  INC
+
+OUI:00250C*
+ ID_OUI_FROM_DATABASE=Enertrac
+
+OUI:00250D*
+ ID_OUI_FROM_DATABASE=GZT Telkom-Telmor sp. z o.o.
+
+OUI:00250E*
+ ID_OUI_FROM_DATABASE=gt german telematics gmbh
+
+OUI:00250F*
+ ID_OUI_FROM_DATABASE=On-Ramp Wireless, Inc.
+
+OUI:002510*
+ ID_OUI_FROM_DATABASE=Pico-Tesla Magnetic Therapies
+
+OUI:002511*
+ ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD.
+
+OUI:002512*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:002513*
+ ID_OUI_FROM_DATABASE=CXP DIGITAL BV
+
+OUI:002514*
+ ID_OUI_FROM_DATABASE=PC Worth Int'l Co., Ltd.
+
+OUI:002515*
+ ID_OUI_FROM_DATABASE=SFR
+
+OUI:002516*
+ ID_OUI_FROM_DATABASE=Integrated Design Tools, Inc.
+
+OUI:002517*
+ ID_OUI_FROM_DATABASE=Venntis, LLC
+
+OUI:002518*
+ ID_OUI_FROM_DATABASE=Power PLUS Communications AG
+
+OUI:002519*
+ ID_OUI_FROM_DATABASE=Viaas Inc
+
+OUI:00251A*
+ ID_OUI_FROM_DATABASE=Psiber Data Systems Inc.
+
+OUI:00251B*
+ ID_OUI_FROM_DATABASE=Philips CareServant
+
+OUI:00251C*
+ ID_OUI_FROM_DATABASE=EDT
+
+OUI:00251D*
+ ID_OUI_FROM_DATABASE=DSA Encore, LLC
+
+OUI:00251E*
+ ID_OUI_FROM_DATABASE=ROTEL TECHNOLOGIES
+
+OUI:00251F*
+ ID_OUI_FROM_DATABASE=ZYNUS VISION INC.
+
+OUI:002520*
+ ID_OUI_FROM_DATABASE=SMA Railway Technology GmbH
+
+OUI:002521*
+ ID_OUI_FROM_DATABASE=Logitek Electronic Systems, Inc.
+
+OUI:002522*
+ ID_OUI_FROM_DATABASE=ASRock Incorporation
+
+OUI:002523*
+ ID_OUI_FROM_DATABASE=OCP Inc.
+
+OUI:002524*
+ ID_OUI_FROM_DATABASE=Lightcomm Technology Co., Ltd
+
+OUI:002525*
+ ID_OUI_FROM_DATABASE=CTERA Networks Ltd.
+
+OUI:002526*
+ ID_OUI_FROM_DATABASE=Genuine Technologies Co., Ltd.
+
+OUI:002527*
+ ID_OUI_FROM_DATABASE=Bitrode Corp.
+
+OUI:002528*
+ ID_OUI_FROM_DATABASE=Daido Signal Co., Ltd.
+
+OUI:002529*
+ ID_OUI_FROM_DATABASE=COMELIT GROUP S.P.A
+
+OUI:00252A*
+ ID_OUI_FROM_DATABASE=Chengdu GeeYa Technology Co.,LTD
+
+OUI:00252B*
+ ID_OUI_FROM_DATABASE=Stirling Energy Systems
+
+OUI:00252C*
+ ID_OUI_FROM_DATABASE=Entourage Systems, Inc.
+
+OUI:00252D*
+ ID_OUI_FROM_DATABASE=Kiryung Electronics
+
+OUI:00252E*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:00252F*
+ ID_OUI_FROM_DATABASE=Energy, Inc.
+
+OUI:002530*
+ ID_OUI_FROM_DATABASE=Aetas Systems Inc.
+
+OUI:002531*
+ ID_OUI_FROM_DATABASE=Cloud Engines, Inc.
+
+OUI:002532*
+ ID_OUI_FROM_DATABASE=Digital Recorders
+
+OUI:002533*
+ ID_OUI_FROM_DATABASE=WITTENSTEIN AG
+
+OUI:002535*
+ ID_OUI_FROM_DATABASE=Minimax GmbH & Co KG
+
+OUI:002536*
+ ID_OUI_FROM_DATABASE=Oki Electric Industry Co., Ltd.
+
+OUI:002537*
+ ID_OUI_FROM_DATABASE=Runcom Technologies Ltd.
+
+OUI:002538*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd., Memory Division
+
+OUI:002539*
+ ID_OUI_FROM_DATABASE=IfTA GmbH
+
+OUI:00253A*
+ ID_OUI_FROM_DATABASE=CEVA, Ltd.
+
+OUI:00253B*
+ ID_OUI_FROM_DATABASE=din Dietmar Nocker Facilitymanagement GmbH
+
+OUI:00253C*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:00253D*
+ ID_OUI_FROM_DATABASE=DRS Consolidated Controls
+
+OUI:00253E*
+ ID_OUI_FROM_DATABASE=Sensus Metering Systems
+
+OUI:002540*
+ ID_OUI_FROM_DATABASE=Quasar Technologies, Inc.
+
+OUI:002541*
+ ID_OUI_FROM_DATABASE=Maquet Critical Care AB
+
+OUI:002542*
+ ID_OUI_FROM_DATABASE=Pittasoft
+
+OUI:002543*
+ ID_OUI_FROM_DATABASE=MONEYTECH
+
+OUI:002544*
+ ID_OUI_FROM_DATABASE=LoJack Corporation
+
+OUI:002545*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002546*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002547*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:002548*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:002549*
+ ID_OUI_FROM_DATABASE=Jeorich Tech. Co.,Ltd.
+
+OUI:00254A*
+ ID_OUI_FROM_DATABASE=RingCube Technologies, Inc.
+
+OUI:00254B*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:00254C*
+ ID_OUI_FROM_DATABASE=Videon Central, Inc.
+
+OUI:00254D*
+ ID_OUI_FROM_DATABASE=Singapore Technologies Electronics Limited
+
+OUI:00254E*
+ ID_OUI_FROM_DATABASE=Vertex Wireless Co., Ltd.
+
+OUI:00254F*
+ ID_OUI_FROM_DATABASE=ELETTROLAB Srl
+
+OUI:002550*
+ ID_OUI_FROM_DATABASE=Riverbed Technology
+
+OUI:002551*
+ ID_OUI_FROM_DATABASE=SE-Elektronic GmbH
+
+OUI:002552*
+ ID_OUI_FROM_DATABASE=VXI CORPORATION
+
+OUI:002553*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:002554*
+ ID_OUI_FROM_DATABASE=Pixel8 Networks
+
+OUI:002555*
+ ID_OUI_FROM_DATABASE=Visonic Technologies 1993 Ltd
+
+OUI:002556*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:002557*
+ ID_OUI_FROM_DATABASE=Research In Motion
+
+OUI:002558*
+ ID_OUI_FROM_DATABASE=MPEDIA
+
+OUI:002559*
+ ID_OUI_FROM_DATABASE=Syphan Technologies Ltd
+
+OUI:00255A*
+ ID_OUI_FROM_DATABASE=Tantalus Systems Corp.
+
+OUI:00255B*
+ ID_OUI_FROM_DATABASE=CoachComm, LLC
+
+OUI:00255C*
+ ID_OUI_FROM_DATABASE=NEC Corporation
+
+OUI:00255D*
+ ID_OUI_FROM_DATABASE=Morningstar Corporation
+
+OUI:00255E*
+ ID_OUI_FROM_DATABASE=Shanghai Dare Technologies Co.,Ltd.
+
+OUI:00255F*
+ ID_OUI_FROM_DATABASE=SenTec AG
+
+OUI:002560*
+ ID_OUI_FROM_DATABASE=Ibridge Networks & Communications Ltd.
+
+OUI:002561*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:002562*
+ ID_OUI_FROM_DATABASE=interbro Co. Ltd.
+
+OUI:002563*
+ ID_OUI_FROM_DATABASE=Luxtera Inc
+
+OUI:002564*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:002565*
+ ID_OUI_FROM_DATABASE=Vizimax Inc.
+
+OUI:002566*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:002567*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:002568*
+ ID_OUI_FROM_DATABASE=Shenzhen Huawei Communication Technologies Co., Ltd
+
+OUI:002569*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:00256A*
+ ID_OUI_FROM_DATABASE=inIT - Institut Industrial IT
+
+OUI:00256B*
+ ID_OUI_FROM_DATABASE=ATENIX E.E. s.r.l.
+
+OUI:00256C*
+ ID_OUI_FROM_DATABASE="Azimut" Production Association JSC
+
+OUI:00256D*
+ ID_OUI_FROM_DATABASE=Broadband Forum
+
+OUI:00256E*
+ ID_OUI_FROM_DATABASE=Van Breda B.V.
+
+OUI:00256F*
+ ID_OUI_FROM_DATABASE=Dantherm Power
+
+OUI:002570*
+ ID_OUI_FROM_DATABASE=Eastern Communications Company Limited
+
+OUI:002571*
+ ID_OUI_FROM_DATABASE=Zhejiang Tianle Digital Electric Co.,Ltd
+
+OUI:002572*
+ ID_OUI_FROM_DATABASE=Nemo-Q International AB
+
+OUI:002573*
+ ID_OUI_FROM_DATABASE=ST Electronics (Info-Security) Pte Ltd
+
+OUI:002574*
+ ID_OUI_FROM_DATABASE=KUNIMI MEDIA DEVICE Co., Ltd.
+
+OUI:002575*
+ ID_OUI_FROM_DATABASE=FiberPlex Inc
+
+OUI:002576*
+ ID_OUI_FROM_DATABASE=NELI TECHNOLOGIES
+
+OUI:002577*
+ ID_OUI_FROM_DATABASE=D-BOX Technologies
+
+OUI:002578*
+ ID_OUI_FROM_DATABASE=JSC "Concern "Sozvezdie"
+
+OUI:002579*
+ ID_OUI_FROM_DATABASE=J & F Labs
+
+OUI:00257A*
+ ID_OUI_FROM_DATABASE=CAMCO Produktions- und Vertriebs-GmbH für  Beschallungs- und Beleuchtungsanlagen
+
+OUI:00257B*
+ ID_OUI_FROM_DATABASE=STJ  ELECTRONICS  PVT  LTD
+
+OUI:00257C*
+ ID_OUI_FROM_DATABASE=Huachentel Technology Development Co., Ltd
+
+OUI:00257D*
+ ID_OUI_FROM_DATABASE=PointRed Telecom Private Ltd.
+
+OUI:00257E*
+ ID_OUI_FROM_DATABASE=NEW POS Technology Limited
+
+OUI:00257F*
+ ID_OUI_FROM_DATABASE=CallTechSolution Co.,Ltd
+
+OUI:002580*
+ ID_OUI_FROM_DATABASE=Equipson S.A.
+
+OUI:002581*
+ ID_OUI_FROM_DATABASE=x-star networks Inc.
+
+OUI:002582*
+ ID_OUI_FROM_DATABASE=Maksat Technologies (P) Ltd
+
+OUI:002583*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002584*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002585*
+ ID_OUI_FROM_DATABASE=KOKUYO S&T Co., Ltd.
+
+OUI:002586*
+ ID_OUI_FROM_DATABASE=TP-LINK Technologies Co., Ltd.
+
+OUI:002587*
+ ID_OUI_FROM_DATABASE=Vitality, Inc.
+
+OUI:002588*
+ ID_OUI_FROM_DATABASE=Genie Industries, Inc.
+
+OUI:002589*
+ ID_OUI_FROM_DATABASE=Hills Industries Limited
+
+OUI:00258A*
+ ID_OUI_FROM_DATABASE=Pole/Zero Corporation
+
+OUI:00258B*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies Ltd
+
+OUI:00258C*
+ ID_OUI_FROM_DATABASE=ESUS ELEKTRONIK SAN. VE DIS. TIC. LTD. STI.
+
+OUI:00258D*
+ ID_OUI_FROM_DATABASE=Haier
+
+OUI:00258E*
+ ID_OUI_FROM_DATABASE=The Weather Channel
+
+OUI:00258F*
+ ID_OUI_FROM_DATABASE=Trident Microsystems, Inc.
+
+OUI:002590*
+ ID_OUI_FROM_DATABASE=Super Micro Computer, Inc.
+
+OUI:002591*
+ ID_OUI_FROM_DATABASE=NEXTEK, Inc.
+
+OUI:002592*
+ ID_OUI_FROM_DATABASE=Guangzhou Shirui Electronic Co., Ltd
+
+OUI:002593*
+ ID_OUI_FROM_DATABASE=DatNet Informatikai Kft.
+
+OUI:002594*
+ ID_OUI_FROM_DATABASE=Eurodesign BG LTD
+
+OUI:002595*
+ ID_OUI_FROM_DATABASE=Northwest Signal Supply, Inc
+
+OUI:002596*
+ ID_OUI_FROM_DATABASE=GIGAVISION srl
+
+OUI:002597*
+ ID_OUI_FROM_DATABASE=Kalki Communication Technologies
+
+OUI:002598*
+ ID_OUI_FROM_DATABASE=Zhong Shan City Litai Electronic Industrial Co. Ltd
+
+OUI:002599*
+ ID_OUI_FROM_DATABASE=Hedon e.d. B.V.
+
+OUI:00259A*
+ ID_OUI_FROM_DATABASE=CEStronics GmbH
+
+OUI:00259B*
+ ID_OUI_FROM_DATABASE=Beijing PKUNITY Microsystems Technology Co., Ltd
+
+OUI:00259C*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:00259E*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd.
+
+OUI:00259F*
+ ID_OUI_FROM_DATABASE=TechnoDigital Technologies GmbH
+
+OUI:0025A0*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:0025A1*
+ ID_OUI_FROM_DATABASE=Enalasys
+
+OUI:0025A2*
+ ID_OUI_FROM_DATABASE=Alta Definicion LINCEO S.L.
+
+OUI:0025A3*
+ ID_OUI_FROM_DATABASE=Trimax Wireless, Inc.
+
+OUI:0025A4*
+ ID_OUI_FROM_DATABASE=EuroDesign embedded technologies GmbH
+
+OUI:0025A5*
+ ID_OUI_FROM_DATABASE=Walnut Media Network
+
+OUI:0025A6*
+ ID_OUI_FROM_DATABASE=Central Network Solution Co., Ltd.
+
+OUI:0025A7*
+ ID_OUI_FROM_DATABASE=Comverge, Inc.
+
+OUI:0025A8*
+ ID_OUI_FROM_DATABASE=Kontron (BeiJing) Technology Co.,Ltd
+
+OUI:0025A9*
+ ID_OUI_FROM_DATABASE=Shanghai Embedway Information Technologies Co.,Ltd
+
+OUI:0025AA*
+ ID_OUI_FROM_DATABASE=Beijing Soul Technology Co.,Ltd.
+
+OUI:0025AB*
+ ID_OUI_FROM_DATABASE=AIO LCD PC BU / TPV
+
+OUI:0025AC*
+ ID_OUI_FROM_DATABASE=I-Tech corporation
+
+OUI:0025AD*
+ ID_OUI_FROM_DATABASE=Manufacturing Resources International
+
+OUI:0025AE*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:0025AF*
+ ID_OUI_FROM_DATABASE=COMFILE Technology
+
+OUI:0025B0*
+ ID_OUI_FROM_DATABASE=Schmartz Inc
+
+OUI:0025B1*
+ ID_OUI_FROM_DATABASE=Maya-Creation Corporation
+
+OUI:0025B2*
+ ID_OUI_FROM_DATABASE=LFK-Lenkflugkörpersysteme GmbH
+
+OUI:0025B3*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:0025B4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0025B5*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0025B6*
+ ID_OUI_FROM_DATABASE=Telecom FM
+
+OUI:0025B7*
+ ID_OUI_FROM_DATABASE=Costar  electronics, inc.,
+
+OUI:0025B8*
+ ID_OUI_FROM_DATABASE=Agile Communications, Inc.
+
+OUI:0025B9*
+ ID_OUI_FROM_DATABASE=Agilink Systems Corp.
+
+OUI:0025BA*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD
+
+OUI:0025BB*
+ ID_OUI_FROM_DATABASE=INNERINT Co., Ltd.
+
+OUI:0025BC*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:0025BD*
+ ID_OUI_FROM_DATABASE=Italdata Ingegneria dell'Idea S.p.A.
+
+OUI:0025BE*
+ ID_OUI_FROM_DATABASE=Tektrap Systems Inc.
+
+OUI:0025BF*
+ ID_OUI_FROM_DATABASE=Wireless Cables Inc.
+
+OUI:0025C0*
+ ID_OUI_FROM_DATABASE=ZillionTV Corporation
+
+OUI:0025C1*
+ ID_OUI_FROM_DATABASE=Nawoo Korea Corp.
+
+OUI:0025C2*
+ ID_OUI_FROM_DATABASE=RingBell Co.,Ltd.
+
+OUI:0025C3*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:0025C4*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:0025C5*
+ ID_OUI_FROM_DATABASE=Star Link Communication Pvt. Ltd.
+
+OUI:0025C6*
+ ID_OUI_FROM_DATABASE=kasercorp, ltd
+
+OUI:0025C7*
+ ID_OUI_FROM_DATABASE=altek Corporation
+
+OUI:0025C8*
+ ID_OUI_FROM_DATABASE=S-Access GmbH
+
+OUI:0025C9*
+ ID_OUI_FROM_DATABASE=SHENZHEN HUAPU DIGITAL CO., LTD
+
+OUI:0025CA*
+ ID_OUI_FROM_DATABASE=LS Research, LLC
+
+OUI:0025CB*
+ ID_OUI_FROM_DATABASE=Reiner SCT
+
+OUI:0025CC*
+ ID_OUI_FROM_DATABASE=Mobile Communications Korea Incorporated
+
+OUI:0025CD*
+ ID_OUI_FROM_DATABASE=Skylane Optics
+
+OUI:0025CE*
+ ID_OUI_FROM_DATABASE=InnerSpace
+
+OUI:0025CF*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0025D0*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0025D1*
+ ID_OUI_FROM_DATABASE=Eastech Electronics (Taiwan) Inc.
+
+OUI:0025D2*
+ ID_OUI_FROM_DATABASE=InpegVision Co., Ltd
+
+OUI:0025D3*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc
+
+OUI:0025D4*
+ ID_OUI_FROM_DATABASE=Fortress Technologies
+
+OUI:0025D5*
+ ID_OUI_FROM_DATABASE=Robonica (Pty) Ltd
+
+OUI:0025D6*
+ ID_OUI_FROM_DATABASE=The Kroger Co.
+
+OUI:0025D7*
+ ID_OUI_FROM_DATABASE=CEDO
+
+OUI:0025D8*
+ ID_OUI_FROM_DATABASE=KOREA MAINTENANCE
+
+OUI:0025D9*
+ ID_OUI_FROM_DATABASE=DataFab Systems Inc.
+
+OUI:0025DA*
+ ID_OUI_FROM_DATABASE=Secura Key
+
+OUI:0025DB*
+ ID_OUI_FROM_DATABASE=ATI Electronics(Shenzhen) Co., LTD
+
+OUI:0025DC*
+ ID_OUI_FROM_DATABASE=Sumitomo Electric Networks, Inc
+
+OUI:0025DD*
+ ID_OUI_FROM_DATABASE=SUNNYTEK INFORMATION CO., LTD.
+
+OUI:0025DE*
+ ID_OUI_FROM_DATABASE=Probits Co., LTD.
+
+OUI:0025E0*
+ ID_OUI_FROM_DATABASE=CeedTec Sdn Bhd
+
+OUI:0025E1*
+ ID_OUI_FROM_DATABASE=SHANGHAI SEEYOO ELECTRONIC & TECHNOLOGY CO., LTD
+
+OUI:0025E2*
+ ID_OUI_FROM_DATABASE=Everspring Industry Co., Ltd.
+
+OUI:0025E3*
+ ID_OUI_FROM_DATABASE=Hanshinit Inc.
+
+OUI:0025E4*
+ ID_OUI_FROM_DATABASE=OMNI-WiFi, LLC
+
+OUI:0025E5*
+ ID_OUI_FROM_DATABASE=LG Electronics Inc
+
+OUI:0025E6*
+ ID_OUI_FROM_DATABASE=Belgian Monitoring Systems bvba
+
+OUI:0025E7*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:0025E8*
+ ID_OUI_FROM_DATABASE=Idaho Technology
+
+OUI:0025E9*
+ ID_OUI_FROM_DATABASE=i-mate Development, Inc.
+
+OUI:0025EA*
+ ID_OUI_FROM_DATABASE=Iphion BV
+
+OUI:0025EB*
+ ID_OUI_FROM_DATABASE=Reutech Radar Systems (PTY) Ltd
+
+OUI:0025EC*
+ ID_OUI_FROM_DATABASE=Humanware
+
+OUI:0025ED*
+ ID_OUI_FROM_DATABASE=NuVo Technologies LLC
+
+OUI:0025EE*
+ ID_OUI_FROM_DATABASE=Avtex Ltd
+
+OUI:0025EF*
+ ID_OUI_FROM_DATABASE=I-TEC Co., Ltd.
+
+OUI:0025F0*
+ ID_OUI_FROM_DATABASE=Suga Electronics Limited
+
+OUI:0025F1*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0025F2*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0025F3*
+ ID_OUI_FROM_DATABASE=Nordwestdeutsche Zählerrevision
+
+OUI:0025F4*
+ ID_OUI_FROM_DATABASE=KoCo Connector AG
+
+OUI:0025F5*
+ ID_OUI_FROM_DATABASE=DVS Korea, Co., Ltd
+
+OUI:0025F6*
+ ID_OUI_FROM_DATABASE=netTALK.com, Inc.
+
+OUI:0025F7*
+ ID_OUI_FROM_DATABASE=Ansaldo STS USA
+
+OUI:0025F9*
+ ID_OUI_FROM_DATABASE=GMK electronic design GmbH
+
+OUI:0025FA*
+ ID_OUI_FROM_DATABASE=J&M Analytik AG
+
+OUI:0025FB*
+ ID_OUI_FROM_DATABASE=Tunstall Healthcare A/S
+
+OUI:0025FC*
+ ID_OUI_FROM_DATABASE=ENDA ENDUSTRIYEL ELEKTRONIK LTD. STI.
+
+OUI:0025FD*
+ ID_OUI_FROM_DATABASE=OBR Centrum Techniki Morskiej S.A.
+
+OUI:0025FE*
+ ID_OUI_FROM_DATABASE=Pilot Electronics Corporation
+
+OUI:0025FF*
+ ID_OUI_FROM_DATABASE=CreNova Technology GmbH
+
+OUI:002600*
+ ID_OUI_FROM_DATABASE=TEAC Australia Pty Ltd.
+
+OUI:002601*
+ ID_OUI_FROM_DATABASE=Cutera Inc
+
+OUI:002602*
+ ID_OUI_FROM_DATABASE=SMART Temps LLC
+
+OUI:002603*
+ ID_OUI_FROM_DATABASE=Shenzhen Wistar Technology Co., Ltd
+
+OUI:002604*
+ ID_OUI_FROM_DATABASE=Audio Processing Technology Ltd
+
+OUI:002605*
+ ID_OUI_FROM_DATABASE=CC Systems AB
+
+OUI:002606*
+ ID_OUI_FROM_DATABASE=RAUMFELD GmbH
+
+OUI:002607*
+ ID_OUI_FROM_DATABASE=Enabling Technology Pty Ltd
+
+OUI:002608*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:002609*
+ ID_OUI_FROM_DATABASE=Phyllis Co., Ltd.
+
+OUI:00260A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00260B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00260C*
+ ID_OUI_FROM_DATABASE=Dataram
+
+OUI:00260D*
+ ID_OUI_FROM_DATABASE=Micronetics, Inc.
+
+OUI:00260E*
+ ID_OUI_FROM_DATABASE=Ablaze Systems, LLC
+
+OUI:00260F*
+ ID_OUI_FROM_DATABASE=Linn Products Ltd
+
+OUI:002610*
+ ID_OUI_FROM_DATABASE=Apacewave Technologies
+
+OUI:002611*
+ ID_OUI_FROM_DATABASE=Licera AB
+
+OUI:002612*
+ ID_OUI_FROM_DATABASE=Space Exploration Technologies
+
+OUI:002613*
+ ID_OUI_FROM_DATABASE=Engel Axil S.L.
+
+OUI:002614*
+ ID_OUI_FROM_DATABASE=KTNF
+
+OUI:002615*
+ ID_OUI_FROM_DATABASE=Teracom Limited
+
+OUI:002616*
+ ID_OUI_FROM_DATABASE=Rosemount Inc.
+
+OUI:002617*
+ ID_OUI_FROM_DATABASE=OEM Worldwide
+
+OUI:002618*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:002619*
+ ID_OUI_FROM_DATABASE=FRC
+
+OUI:00261A*
+ ID_OUI_FROM_DATABASE=Femtocomm System Technology Corp.
+
+OUI:00261B*
+ ID_OUI_FROM_DATABASE=LAUREL BANK MACHINES CO., LTD.
+
+OUI:00261C*
+ ID_OUI_FROM_DATABASE=NEOVIA INC.
+
+OUI:00261D*
+ ID_OUI_FROM_DATABASE=COP SECURITY SYSTEM CORP.
+
+OUI:00261E*
+ ID_OUI_FROM_DATABASE=QINGBANG ELEC(SZ) CO., LTD
+
+OUI:00261F*
+ ID_OUI_FROM_DATABASE=SAE Magnetics (H.K.) Ltd.
+
+OUI:002620*
+ ID_OUI_FROM_DATABASE=ISGUS GmbH
+
+OUI:002621*
+ ID_OUI_FROM_DATABASE=InteliCloud Technology Inc.
+
+OUI:002622*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:002623*
+ ID_OUI_FROM_DATABASE=JRD Communication Inc
+
+OUI:002624*
+ ID_OUI_FROM_DATABASE=Thomson Inc.
+
+OUI:002625*
+ ID_OUI_FROM_DATABASE=MediaSputnik
+
+OUI:002626*
+ ID_OUI_FROM_DATABASE=Geophysical Survey Systems, Inc.
+
+OUI:002627*
+ ID_OUI_FROM_DATABASE=Truesell
+
+OUI:002628*
+ ID_OUI_FROM_DATABASE=companytec automação e controle ltda.
+
+OUI:002629*
+ ID_OUI_FROM_DATABASE=Juphoon System Software Inc.
+
+OUI:00262A*
+ ID_OUI_FROM_DATABASE=Proxense, LLC
+
+OUI:00262B*
+ ID_OUI_FROM_DATABASE=Wongs Electronics Co. Ltd.
+
+OUI:00262C*
+ ID_OUI_FROM_DATABASE=IKT Advanced Technologies s.r.o.
+
+OUI:00262D*
+ ID_OUI_FROM_DATABASE=Wistron Corporation
+
+OUI:00262E*
+ ID_OUI_FROM_DATABASE=Chengdu Jiuzhou Electronic Technology Inc
+
+OUI:00262F*
+ ID_OUI_FROM_DATABASE=HAMAMATSU TOA ELECTRONICS
+
+OUI:002630*
+ ID_OUI_FROM_DATABASE=ACOREL S.A.S
+
+OUI:002631*
+ ID_OUI_FROM_DATABASE=COMMTACT LTD
+
+OUI:002632*
+ ID_OUI_FROM_DATABASE=Instrumentation Technologies d.d.
+
+OUI:002633*
+ ID_OUI_FROM_DATABASE=MIR - Medical International Research
+
+OUI:002634*
+ ID_OUI_FROM_DATABASE=Infineta Systems, Inc
+
+OUI:002635*
+ ID_OUI_FROM_DATABASE=Bluetechnix GmbH
+
+OUI:002636*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:002637*
+ ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics
+
+OUI:002638*
+ ID_OUI_FROM_DATABASE=Xia Men Joyatech Co., Ltd.
+
+OUI:002639*
+ ID_OUI_FROM_DATABASE=T.M. Electronics, Inc.
+
+OUI:00263A*
+ ID_OUI_FROM_DATABASE=Digitec Systems
+
+OUI:00263B*
+ ID_OUI_FROM_DATABASE=Onbnetech
+
+OUI:00263C*
+ ID_OUI_FROM_DATABASE=Bachmann GmbH & Co. KG
+
+OUI:00263D*
+ ID_OUI_FROM_DATABASE=MIA Corporation
+
+OUI:00263E*
+ ID_OUI_FROM_DATABASE=Trapeze Networks
+
+OUI:00263F*
+ ID_OUI_FROM_DATABASE=LIOS Technology GmbH
+
+OUI:002640*
+ ID_OUI_FROM_DATABASE=Baustem Broadband Technologies, Ltd.
+
+OUI:002641*
+ ID_OUI_FROM_DATABASE=Motorola, Inc
+
+OUI:002642*
+ ID_OUI_FROM_DATABASE=Motorola, Inc
+
+OUI:002643*
+ ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd
+
+OUI:002644*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:002645*
+ ID_OUI_FROM_DATABASE=Circontrol S.A.
+
+OUI:002646*
+ ID_OUI_FROM_DATABASE=SHENYANG TONGFANG MULTIMEDIA TECHNOLOGY COMPANY LIMITED
+
+OUI:002647*
+ ID_OUI_FROM_DATABASE=WFE TECHNOLOGY CORP.
+
+OUI:002648*
+ ID_OUI_FROM_DATABASE=Emitech Corp.
+
+OUI:00264A*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:00264C*
+ ID_OUI_FROM_DATABASE=Shanghai DigiVision Technology Co., Ltd.
+
+OUI:00264D*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:00264E*
+ ID_OUI_FROM_DATABASE=Rail & Road Protec GmbH
+
+OUI:00264F*
+ ID_OUI_FROM_DATABASE=Krüger &Gothe GmbH
+
+OUI:002650*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:002651*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002652*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002653*
+ ID_OUI_FROM_DATABASE=DaySequerra Corporation
+
+OUI:002654*
+ ID_OUI_FROM_DATABASE=3Com Corporation
+
+OUI:002655*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:002656*
+ ID_OUI_FROM_DATABASE=Sansonic Electronics USA
+
+OUI:002657*
+ ID_OUI_FROM_DATABASE=OOO NPP EKRA
+
+OUI:002658*
+ ID_OUI_FROM_DATABASE=T-Platforms (Cyprus) Limited
+
+OUI:002659*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:00265A*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:00265B*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:00265C*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:00265D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:00265E*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:00265F*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:002660*
+ ID_OUI_FROM_DATABASE=Logiways
+
+OUI:002661*
+ ID_OUI_FROM_DATABASE=Irumtek Co., Ltd.
+
+OUI:002662*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:002663*
+ ID_OUI_FROM_DATABASE=Shenzhen Huitaiwei Tech. Ltd, co.
+
+OUI:002664*
+ ID_OUI_FROM_DATABASE=Core System Japan
+
+OUI:002665*
+ ID_OUI_FROM_DATABASE=ProtectedLogic Corporation
+
+OUI:002666*
+ ID_OUI_FROM_DATABASE=EFM Networks
+
+OUI:002667*
+ ID_OUI_FROM_DATABASE=CARECOM CO.,LTD.
+
+OUI:002668*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:002669*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:00266A*
+ ID_OUI_FROM_DATABASE=ESSENSIUM NV
+
+OUI:00266B*
+ ID_OUI_FROM_DATABASE=SHINE UNION ENTERPRISE LIMITED
+
+OUI:00266C*
+ ID_OUI_FROM_DATABASE=Inventec
+
+OUI:00266D*
+ ID_OUI_FROM_DATABASE=MobileAccess Networks
+
+OUI:00266E*
+ ID_OUI_FROM_DATABASE=Nissho-denki Co.,LTD.
+
+OUI:00266F*
+ ID_OUI_FROM_DATABASE=Coordiwise Technology Corp.
+
+OUI:002670*
+ ID_OUI_FROM_DATABASE=Cinch Connectors
+
+OUI:002671*
+ ID_OUI_FROM_DATABASE=AUTOVISION Co., Ltd
+
+OUI:002672*
+ ID_OUI_FROM_DATABASE=AAMP of America
+
+OUI:002673*
+ ID_OUI_FROM_DATABASE=RICOH COMPANY LTD.
+
+OUI:002674*
+ ID_OUI_FROM_DATABASE=Electronic Solutions, Inc.
+
+OUI:002675*
+ ID_OUI_FROM_DATABASE=Aztech Electronics Pte Ltd
+
+OUI:002676*
+ ID_OUI_FROM_DATABASE=COMMidt AS
+
+OUI:002677*
+ ID_OUI_FROM_DATABASE=DEIF A/S
+
+OUI:002678*
+ ID_OUI_FROM_DATABASE=Logic Instrument SA
+
+OUI:002679*
+ ID_OUI_FROM_DATABASE=Euphonic Technologies, Inc.
+
+OUI:00267A*
+ ID_OUI_FROM_DATABASE=wuhan hongxin telecommunication technologies co.,ltd
+
+OUI:00267B*
+ ID_OUI_FROM_DATABASE=GSI Helmholtzzentrum für Schwerionenforschung GmbH
+
+OUI:00267C*
+ ID_OUI_FROM_DATABASE=Metz-Werke GmbH & Co KG
+
+OUI:00267D*
+ ID_OUI_FROM_DATABASE=A-Max Technology Macao Commercial Offshore Company Limited
+
+OUI:00267E*
+ ID_OUI_FROM_DATABASE=Parrot SA
+
+OUI:00267F*
+ ID_OUI_FROM_DATABASE=Zenterio AB
+
+OUI:002680*
+ ID_OUI_FROM_DATABASE=Lockie Innovation Pty Ltd
+
+OUI:002681*
+ ID_OUI_FROM_DATABASE=Interspiro AB
+
+OUI:002682*
+ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+
+OUI:002683*
+ ID_OUI_FROM_DATABASE=Ajoho Enterprise Co., Ltd.
+
+OUI:002684*
+ ID_OUI_FROM_DATABASE=KISAN SYSTEM
+
+OUI:002685*
+ ID_OUI_FROM_DATABASE=Digital Innovation
+
+OUI:002686*
+ ID_OUI_FROM_DATABASE=Quantenna Communcations, Inc.
+
+OUI:002687*
+ ID_OUI_FROM_DATABASE=ALLIED TELESIS, K.K corega division.
+
+OUI:002688*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:002689*
+ ID_OUI_FROM_DATABASE=General Dynamics Robotic Systems
+
+OUI:00268A*
+ ID_OUI_FROM_DATABASE=Terrier SC Ltd
+
+OUI:00268B*
+ ID_OUI_FROM_DATABASE=Guangzhou Escene Computer Technology Limited
+
+OUI:00268C*
+ ID_OUI_FROM_DATABASE=StarLeaf Ltd.
+
+OUI:00268D*
+ ID_OUI_FROM_DATABASE=CellTel S.p.A.
+
+OUI:00268E*
+ ID_OUI_FROM_DATABASE=Alta Solutions, Inc.
+
+OUI:00268F*
+ ID_OUI_FROM_DATABASE=MTA SpA
+
+OUI:002690*
+ ID_OUI_FROM_DATABASE=I DO IT
+
+OUI:002691*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:002692*
+ ID_OUI_FROM_DATABASE=Mitsubishi Electric Co.
+
+OUI:002693*
+ ID_OUI_FROM_DATABASE=QVidium Technologies, Inc.
+
+OUI:002694*
+ ID_OUI_FROM_DATABASE=Senscient Ltd
+
+OUI:002695*
+ ID_OUI_FROM_DATABASE=ZT Group Int'l Inc
+
+OUI:002696*
+ ID_OUI_FROM_DATABASE=NOOLIX Co., Ltd
+
+OUI:002697*
+ ID_OUI_FROM_DATABASE=Cheetah Technologies, L.P.
+
+OUI:002698*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002699*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00269A*
+ ID_OUI_FROM_DATABASE=carina system co., ltd.
+
+OUI:00269B*
+ ID_OUI_FROM_DATABASE=SOKRAT Ltd.
+
+OUI:00269C*
+ ID_OUI_FROM_DATABASE=ITUS JAPAN CO. LTD
+
+OUI:00269D*
+ ID_OUI_FROM_DATABASE=M2Mnet Co., Ltd.
+
+OUI:00269E*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc
+
+OUI:0026A0*
+ ID_OUI_FROM_DATABASE=moblic
+
+OUI:0026A1*
+ ID_OUI_FROM_DATABASE=Megger
+
+OUI:0026A2*
+ ID_OUI_FROM_DATABASE=Instrumentation Technology Systems
+
+OUI:0026A3*
+ ID_OUI_FROM_DATABASE=FQ Ingenieria Electronica S.A.
+
+OUI:0026A4*
+ ID_OUI_FROM_DATABASE=Novus Produtos Eletronicos Ltda
+
+OUI:0026A5*
+ ID_OUI_FROM_DATABASE=MICROROBOT.CO.,LTD
+
+OUI:0026A6*
+ ID_OUI_FROM_DATABASE=TRIXELL
+
+OUI:0026A7*
+ ID_OUI_FROM_DATABASE=CONNECT SRL
+
+OUI:0026A8*
+ ID_OUI_FROM_DATABASE=DAEHAP HYPER-TECH
+
+OUI:0026A9*
+ ID_OUI_FROM_DATABASE=Strong Technologies Pty Ltd
+
+OUI:0026AA*
+ ID_OUI_FROM_DATABASE=Kenmec Mechanical Engineering Co., Ltd.
+
+OUI:0026AB*
+ ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION
+
+OUI:0026AC*
+ ID_OUI_FROM_DATABASE=Shanghai LUSTER Teraband photonic Co., Ltd.
+
+OUI:0026AD*
+ ID_OUI_FROM_DATABASE=Arada Systems, Inc.
+
+OUI:0026AE*
+ ID_OUI_FROM_DATABASE=Wireless Measurement Ltd
+
+OUI:0026AF*
+ ID_OUI_FROM_DATABASE=Duelco A/S
+
+OUI:0026B0*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:0026B1*
+ ID_OUI_FROM_DATABASE=Navis Auto Motive Systems, Inc.
+
+OUI:0026B2*
+ ID_OUI_FROM_DATABASE=Setrix AG
+
+OUI:0026B3*
+ ID_OUI_FROM_DATABASE=Thales Communications Inc
+
+OUI:0026B4*
+ ID_OUI_FROM_DATABASE=Ford Motor Company
+
+OUI:0026B5*
+ ID_OUI_FROM_DATABASE=ICOMM Tele Ltd
+
+OUI:0026B6*
+ ID_OUI_FROM_DATABASE=Askey Computer
+
+OUI:0026B7*
+ ID_OUI_FROM_DATABASE=Kingston Technology Company, Inc.
+
+OUI:0026B8*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:0026B9*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:0026BA*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:0026BB*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:0026BC*
+ ID_OUI_FROM_DATABASE=General Jack Technology Ltd.
+
+OUI:0026BD*
+ ID_OUI_FROM_DATABASE=JTEC Card & Communication Co., Ltd.
+
+OUI:0026BE*
+ ID_OUI_FROM_DATABASE=Schoonderbeek Elektronica Systemen B.V.
+
+OUI:0026BF*
+ ID_OUI_FROM_DATABASE=ShenZhen Temobi Science&Tech Development Co.,Ltd
+
+OUI:0026C0*
+ ID_OUI_FROM_DATABASE=EnergyHub
+
+OUI:0026C1*
+ ID_OUI_FROM_DATABASE=ARTRAY CO., LTD.
+
+OUI:0026C2*
+ ID_OUI_FROM_DATABASE=SCDI Co. LTD
+
+OUI:0026C3*
+ ID_OUI_FROM_DATABASE=Insightek Corp.
+
+OUI:0026C4*
+ ID_OUI_FROM_DATABASE=Cadmos microsystems S.r.l.
+
+OUI:0026C5*
+ ID_OUI_FROM_DATABASE=Guangdong Gosun Telecommunications Co.,Ltd
+
+OUI:0026C6*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0026C7*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0026C8*
+ ID_OUI_FROM_DATABASE=System Sensor
+
+OUI:0026C9*
+ ID_OUI_FROM_DATABASE=Proventix Systems, Inc.
+
+OUI:0026CA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0026CB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0026CC*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:0026CD*
+ ID_OUI_FROM_DATABASE=PurpleComm, Inc.
+
+OUI:0026CE*
+ ID_OUI_FROM_DATABASE=Kozumi USA Corp.
+
+OUI:0026CF*
+ ID_OUI_FROM_DATABASE=DEKA R&D
+
+OUI:0026D0*
+ ID_OUI_FROM_DATABASE=Semihalf
+
+OUI:0026D1*
+ ID_OUI_FROM_DATABASE=S Squared Innovations Inc.
+
+OUI:0026D2*
+ ID_OUI_FROM_DATABASE=Pcube Systems, Inc.
+
+OUI:0026D3*
+ ID_OUI_FROM_DATABASE=Zeno Information System
+
+OUI:0026D4*
+ ID_OUI_FROM_DATABASE=IRCA SpA
+
+OUI:0026D5*
+ ID_OUI_FROM_DATABASE=Ory Solucoes em Comercio de Informatica Ltda.
+
+OUI:0026D6*
+ ID_OUI_FROM_DATABASE=Ningbo Andy Optoelectronic Co., Ltd.
+
+OUI:0026D7*
+ ID_OUI_FROM_DATABASE=Xiamen BB Electron & Technology Co., Ltd.
+
+OUI:0026D8*
+ ID_OUI_FROM_DATABASE=Magic Point Inc.
+
+OUI:0026D9*
+ ID_OUI_FROM_DATABASE=Pace plc
+
+OUI:0026DA*
+ ID_OUI_FROM_DATABASE=Universal Media Corporation /Slovakia/ s.r.o.
+
+OUI:0026DB*
+ ID_OUI_FROM_DATABASE=Ionics EMS Inc.
+
+OUI:0026DC*
+ ID_OUI_FROM_DATABASE=Optical Systems Design
+
+OUI:0026DD*
+ ID_OUI_FROM_DATABASE=Fival Corporation
+
+OUI:0026DE*
+ ID_OUI_FROM_DATABASE=FDI MATELEC
+
+OUI:0026DF*
+ ID_OUI_FROM_DATABASE=TaiDoc Technology Corp.
+
+OUI:0026E0*
+ ID_OUI_FROM_DATABASE=ASITEQ
+
+OUI:0026E1*
+ ID_OUI_FROM_DATABASE=Stanford University, OpenFlow Group
+
+OUI:0026E2*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:0026E3*
+ ID_OUI_FROM_DATABASE=DTI
+
+OUI:0026E4*
+ ID_OUI_FROM_DATABASE=CANAL OVERSEAS
+
+OUI:0026E5*
+ ID_OUI_FROM_DATABASE=AEG Power Solutions
+
+OUI:0026E6*
+ ID_OUI_FROM_DATABASE=Visionhitech Co., Ltd.
+
+OUI:0026E7*
+ ID_OUI_FROM_DATABASE=Shanghai ONLAN Communication Tech. Co., Ltd.
+
+OUI:0026E8*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:0026E9*
+ ID_OUI_FROM_DATABASE=SP Corp
+
+OUI:0026EA*
+ ID_OUI_FROM_DATABASE=Cheerchip Electronic Technology (ShangHai) Co., Ltd.
+
+OUI:0026EB*
+ ID_OUI_FROM_DATABASE=Advanced Spectrum Technology Co., Ltd.
+
+OUI:0026EC*
+ ID_OUI_FROM_DATABASE=Legrand Home Systems, Inc
+
+OUI:0026ED*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:0026EE*
+ ID_OUI_FROM_DATABASE=TKM GmbH
+
+OUI:0026EF*
+ ID_OUI_FROM_DATABASE=Technology Advancement Group, Inc.
+
+OUI:0026F0*
+ ID_OUI_FROM_DATABASE=cTrixs International GmbH.
+
+OUI:0026F1*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:0026F2*
+ ID_OUI_FROM_DATABASE=Netgear
+
+OUI:0026F3*
+ ID_OUI_FROM_DATABASE=SMC Networks
+
+OUI:0026F4*
+ ID_OUI_FROM_DATABASE=Nesslab
+
+OUI:0026F5*
+ ID_OUI_FROM_DATABASE=XRPLUS Inc.
+
+OUI:0026F6*
+ ID_OUI_FROM_DATABASE=Military Communication Institute
+
+OUI:0026F7*
+ ID_OUI_FROM_DATABASE=Infosys Technologies Ltd.
+
+OUI:0026F8*
+ ID_OUI_FROM_DATABASE=Golden Highway Industry Development Co., Ltd.
+
+OUI:0026F9*
+ ID_OUI_FROM_DATABASE=S.E.M. srl
+
+OUI:0026FA*
+ ID_OUI_FROM_DATABASE=BandRich Inc.
+
+OUI:0026FB*
+ ID_OUI_FROM_DATABASE=AirDio Wireless, Inc.
+
+OUI:0026FC*
+ ID_OUI_FROM_DATABASE=AcSiP Technology Corp.
+
+OUI:0026FD*
+ ID_OUI_FROM_DATABASE=Interactive Intelligence
+
+OUI:0026FE*
+ ID_OUI_FROM_DATABASE=MKD Technology Inc.
+
+OUI:0026FF*
+ ID_OUI_FROM_DATABASE=Research In Motion
+
+OUI:002700*
+ ID_OUI_FROM_DATABASE=Shenzhen Siglent Technology Co., Ltd.
+
+OUI:002701*
+ ID_OUI_FROM_DATABASE=INCOstartec GmbH
+
+OUI:002702*
+ ID_OUI_FROM_DATABASE=SolarEdge Technologies
+
+OUI:002703*
+ ID_OUI_FROM_DATABASE=Testech Electronics Pte Ltd
+
+OUI:002704*
+ ID_OUI_FROM_DATABASE=Accelerated Concepts, Inc
+
+OUI:002705*
+ ID_OUI_FROM_DATABASE=Sectronic
+
+OUI:002706*
+ ID_OUI_FROM_DATABASE=YOISYS
+
+OUI:002707*
+ ID_OUI_FROM_DATABASE=Lift Complex DS, JSC
+
+OUI:002708*
+ ID_OUI_FROM_DATABASE=Nordiag ASA
+
+OUI:002709*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:00270A*
+ ID_OUI_FROM_DATABASE=IEE S.A.
+
+OUI:00270B*
+ ID_OUI_FROM_DATABASE=Adura Technologies
+
+OUI:00270C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00270D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00270E*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:00270F*
+ ID_OUI_FROM_DATABASE=Envisionnovation Inc
+
+OUI:002710*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:002711*
+ ID_OUI_FROM_DATABASE=LanPro Inc
+
+OUI:002712*
+ ID_OUI_FROM_DATABASE=MaxVision LLC
+
+OUI:002713*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:002714*
+ ID_OUI_FROM_DATABASE=Grainmustards, Co,ltd.
+
+OUI:002715*
+ ID_OUI_FROM_DATABASE=Rebound Telecom. Co., Ltd
+
+OUI:002716*
+ ID_OUI_FROM_DATABASE=Adachi-Syokai Co., Ltd.
+
+OUI:002717*
+ ID_OUI_FROM_DATABASE=CE Digital(Zhenjiang)Co.,Ltd
+
+OUI:002718*
+ ID_OUI_FROM_DATABASE=Suzhou NEW SEAUNION Video Technology Co.,Ltd
+
+OUI:002719*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:00271A*
+ ID_OUI_FROM_DATABASE=Geenovo Technology Ltd.
+
+OUI:00271B*
+ ID_OUI_FROM_DATABASE=Alec Sicherheitssysteme GmbH
+
+OUI:00271C*
+ ID_OUI_FROM_DATABASE=MERCURY CORPORATION
+
+OUI:00271D*
+ ID_OUI_FROM_DATABASE=Comba Telecom Systems (China) Ltd.
+
+OUI:00271E*
+ ID_OUI_FROM_DATABASE=Xagyl Communications
+
+OUI:00271F*
+ ID_OUI_FROM_DATABASE=MIPRO Electronics Co., Ltd
+
+OUI:002720*
+ ID_OUI_FROM_DATABASE=NEW-SOL COM
+
+OUI:002721*
+ ID_OUI_FROM_DATABASE=Shenzhen Baoan Fenda Industrial Co., Ltd
+
+OUI:002722*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:0027F8*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc
+
+OUI:002A6A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:002AAF*
+ ID_OUI_FROM_DATABASE=LARsys-Automation GmbH
+
+OUI:002D76*
+ ID_OUI_FROM_DATABASE=TITECH GmbH
+
+OUI:003000*
+ ID_OUI_FROM_DATABASE=ALLWELL TECHNOLOGY CORP.
+
+OUI:003001*
+ ID_OUI_FROM_DATABASE=SMP
+
+OUI:003002*
+ ID_OUI_FROM_DATABASE=Expand Networks
+
+OUI:003003*
+ ID_OUI_FROM_DATABASE=Phasys Ltd.
+
+OUI:003004*
+ ID_OUI_FROM_DATABASE=LEADTEK RESEARCH INC.
+
+OUI:003005*
+ ID_OUI_FROM_DATABASE=Fujitsu Siemens Computers
+
+OUI:003006*
+ ID_OUI_FROM_DATABASE=SUPERPOWER COMPUTER
+
+OUI:003007*
+ ID_OUI_FROM_DATABASE=OPTI, INC.
+
+OUI:003008*
+ ID_OUI_FROM_DATABASE=AVIO DIGITAL, INC.
+
+OUI:003009*
+ ID_OUI_FROM_DATABASE=Tachion Networks, Inc.
+
+OUI:00300A*
+ ID_OUI_FROM_DATABASE=AZTECH Electronics Pte Ltd
+
+OUI:00300B*
+ ID_OUI_FROM_DATABASE=mPHASE Technologies, Inc.
+
+OUI:00300C*
+ ID_OUI_FROM_DATABASE=CONGRUENCY, LTD.
+
+OUI:00300D*
+ ID_OUI_FROM_DATABASE=MMC Technology, Inc.
+
+OUI:00300E*
+ ID_OUI_FROM_DATABASE=Klotz Digital AG
+
+OUI:00300F*
+ ID_OUI_FROM_DATABASE=IMT - Information Management T
+
+OUI:003010*
+ ID_OUI_FROM_DATABASE=VISIONETICS INTERNATIONAL
+
+OUI:003011*
+ ID_OUI_FROM_DATABASE=HMS Industrial Networks
+
+OUI:003012*
+ ID_OUI_FROM_DATABASE=DIGITAL ENGINEERING LTD.
+
+OUI:003013*
+ ID_OUI_FROM_DATABASE=NEC Corporation
+
+OUI:003014*
+ ID_OUI_FROM_DATABASE=DIVIO, INC.
+
+OUI:003015*
+ ID_OUI_FROM_DATABASE=CP CLARE CORP.
+
+OUI:003016*
+ ID_OUI_FROM_DATABASE=ISHIDA CO., LTD.
+
+OUI:003017*
+ ID_OUI_FROM_DATABASE=BlueArc UK Ltd
+
+OUI:003018*
+ ID_OUI_FROM_DATABASE=Jetway Information Co., Ltd.
+
+OUI:003019*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00301A*
+ ID_OUI_FROM_DATABASE=SMARTBRIDGES PTE. LTD.
+
+OUI:00301B*
+ ID_OUI_FROM_DATABASE=SHUTTLE, INC.
+
+OUI:00301C*
+ ID_OUI_FROM_DATABASE=ALTVATER AIRDATA SYSTEMS
+
+OUI:00301D*
+ ID_OUI_FROM_DATABASE=SKYSTREAM, INC.
+
+OUI:00301E*
+ ID_OUI_FROM_DATABASE=3COM Europe Ltd.
+
+OUI:00301F*
+ ID_OUI_FROM_DATABASE=OPTICAL NETWORKS, INC.
+
+OUI:003020*
+ ID_OUI_FROM_DATABASE=TSI, Inc..
+
+OUI:003021*
+ ID_OUI_FROM_DATABASE=HSING TECH. ENTERPRISE CO.,LTD
+
+OUI:003022*
+ ID_OUI_FROM_DATABASE=Fong Kai Industrial Co., Ltd.
+
+OUI:003023*
+ ID_OUI_FROM_DATABASE=COGENT COMPUTER SYSTEMS, INC.
+
+OUI:003024*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003025*
+ ID_OUI_FROM_DATABASE=CHECKOUT COMPUTER SYSTEMS, LTD
+
+OUI:003026*
+ ID_OUI_FROM_DATABASE=HeiTel Digital Video GmbH
+
+OUI:003027*
+ ID_OUI_FROM_DATABASE=KERBANGO, INC.
+
+OUI:003028*
+ ID_OUI_FROM_DATABASE=FASE Saldatura srl
+
+OUI:003029*
+ ID_OUI_FROM_DATABASE=OPICOM
+
+OUI:00302A*
+ ID_OUI_FROM_DATABASE=SOUTHERN INFORMATION
+
+OUI:00302B*
+ ID_OUI_FROM_DATABASE=INALP NETWORKS, INC.
+
+OUI:00302C*
+ ID_OUI_FROM_DATABASE=SYLANTRO SYSTEMS CORPORATION
+
+OUI:00302D*
+ ID_OUI_FROM_DATABASE=QUANTUM BRIDGE COMMUNICATIONS
+
+OUI:00302E*
+ ID_OUI_FROM_DATABASE=Hoft & Wessel AG
+
+OUI:00302F*
+ ID_OUI_FROM_DATABASE=GE Aviation System
+
+OUI:003030*
+ ID_OUI_FROM_DATABASE=HARMONIX CORPORATION
+
+OUI:003031*
+ ID_OUI_FROM_DATABASE=LIGHTWAVE COMMUNICATIONS, INC.
+
+OUI:003032*
+ ID_OUI_FROM_DATABASE=MagicRam, Inc.
+
+OUI:003033*
+ ID_OUI_FROM_DATABASE=ORIENT TELECOM CO., LTD.
+
+OUI:003034*
+ ID_OUI_FROM_DATABASE=SET ENGINEERING
+
+OUI:003035*
+ ID_OUI_FROM_DATABASE=Corning Incorporated
+
+OUI:003036*
+ ID_OUI_FROM_DATABASE=RMP ELEKTRONIKSYSTEME GMBH
+
+OUI:003037*
+ ID_OUI_FROM_DATABASE=Packard Bell Nec Services
+
+OUI:003038*
+ ID_OUI_FROM_DATABASE=XCP, INC.
+
+OUI:003039*
+ ID_OUI_FROM_DATABASE=SOFTBOOK PRESS
+
+OUI:00303A*
+ ID_OUI_FROM_DATABASE=MAATEL
+
+OUI:00303B*
+ ID_OUI_FROM_DATABASE=PowerCom Technology
+
+OUI:00303C*
+ ID_OUI_FROM_DATABASE=ONNTO CORP.
+
+OUI:00303D*
+ ID_OUI_FROM_DATABASE=IVA CORPORATION
+
+OUI:00303E*
+ ID_OUI_FROM_DATABASE=Radcom Ltd.
+
+OUI:00303F*
+ ID_OUI_FROM_DATABASE=TurboComm Tech Inc.
+
+OUI:003040*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003041*
+ ID_OUI_FROM_DATABASE=SAEJIN T & M CO., LTD.
+
+OUI:003042*
+ ID_OUI_FROM_DATABASE=DeTeWe-Deutsche Telephonwerke
+
+OUI:003043*
+ ID_OUI_FROM_DATABASE=IDREAM TECHNOLOGIES, PTE. LTD.
+
+OUI:003044*
+ ID_OUI_FROM_DATABASE=CradlePoint, Inc
+
+OUI:003045*
+ ID_OUI_FROM_DATABASE=Village Networks, Inc. (VNI)
+
+OUI:003046*
+ ID_OUI_FROM_DATABASE=Controlled Electronic Manageme
+
+OUI:003047*
+ ID_OUI_FROM_DATABASE=NISSEI ELECTRIC CO., LTD.
+
+OUI:003048*
+ ID_OUI_FROM_DATABASE=Supermicro Computer, Inc.
+
+OUI:003049*
+ ID_OUI_FROM_DATABASE=BRYANT TECHNOLOGY, LTD.
+
+OUI:00304A*
+ ID_OUI_FROM_DATABASE=Fraunhofer IPMS
+
+OUI:00304B*
+ ID_OUI_FROM_DATABASE=ORBACOM SYSTEMS, INC.
+
+OUI:00304C*
+ ID_OUI_FROM_DATABASE=APPIAN COMMUNICATIONS, INC.
+
+OUI:00304D*
+ ID_OUI_FROM_DATABASE=ESI
+
+OUI:00304E*
+ ID_OUI_FROM_DATABASE=BUSTEC PRODUCTION LTD.
+
+OUI:00304F*
+ ID_OUI_FROM_DATABASE=PLANET Technology Corporation
+
+OUI:003050*
+ ID_OUI_FROM_DATABASE=Versa Technology
+
+OUI:003051*
+ ID_OUI_FROM_DATABASE=ORBIT AVIONIC & COMMUNICATION
+
+OUI:003052*
+ ID_OUI_FROM_DATABASE=ELASTIC NETWORKS
+
+OUI:003053*
+ ID_OUI_FROM_DATABASE=Basler AG
+
+OUI:003054*
+ ID_OUI_FROM_DATABASE=CASTLENET TECHNOLOGY, INC.
+
+OUI:003055*
+ ID_OUI_FROM_DATABASE=Renesas Technology America, Inc.
+
+OUI:003056*
+ ID_OUI_FROM_DATABASE=Beck IPC GmbH
+
+OUI:003057*
+ ID_OUI_FROM_DATABASE=QTelNet, Inc.
+
+OUI:003058*
+ ID_OUI_FROM_DATABASE=API MOTION
+
+OUI:003059*
+ ID_OUI_FROM_DATABASE=KONTRON COMPACT COMPUTERS AG
+
+OUI:00305A*
+ ID_OUI_FROM_DATABASE=TELGEN CORPORATION
+
+OUI:00305B*
+ ID_OUI_FROM_DATABASE=Toko Inc.
+
+OUI:00305C*
+ ID_OUI_FROM_DATABASE=SMAR Laboratories Corp.
+
+OUI:00305D*
+ ID_OUI_FROM_DATABASE=DIGITRA SYSTEMS, INC.
+
+OUI:00305E*
+ ID_OUI_FROM_DATABASE=Abelko Innovation
+
+OUI:00305F*
+ ID_OUI_FROM_DATABASE=Hasselblad
+
+OUI:003060*
+ ID_OUI_FROM_DATABASE=Powerfile, Inc.
+
+OUI:003061*
+ ID_OUI_FROM_DATABASE=MobyTEL
+
+OUI:003062*
+ ID_OUI_FROM_DATABASE=PATH 1 NETWORK TECHNOL'S INC.
+
+OUI:003063*
+ ID_OUI_FROM_DATABASE=SANTERA SYSTEMS, INC.
+
+OUI:003064*
+ ID_OUI_FROM_DATABASE=ADLINK TECHNOLOGY, INC.
+
+OUI:003065*
+ ID_OUI_FROM_DATABASE=APPLE COMPUTER, INC.
+
+OUI:003066*
+ ID_OUI_FROM_DATABASE=RFM
+
+OUI:003067*
+ ID_OUI_FROM_DATABASE=BIOSTAR MICROTECH INT'L CORP.
+
+OUI:003068*
+ ID_OUI_FROM_DATABASE=CYBERNETICS TECH. CO., LTD.
+
+OUI:003069*
+ ID_OUI_FROM_DATABASE=IMPACCT TECHNOLOGY CORP.
+
+OUI:00306A*
+ ID_OUI_FROM_DATABASE=PENTA MEDIA CO., LTD.
+
+OUI:00306B*
+ ID_OUI_FROM_DATABASE=CMOS SYSTEMS, INC.
+
+OUI:00306C*
+ ID_OUI_FROM_DATABASE=Hitex Holding GmbH
+
+OUI:00306D*
+ ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES
+
+OUI:00306E*
+ ID_OUI_FROM_DATABASE=HEWLETT PACKARD
+
+OUI:00306F*
+ ID_OUI_FROM_DATABASE=SEYEON TECH. CO., LTD.
+
+OUI:003070*
+ ID_OUI_FROM_DATABASE=1Net Corporation
+
+OUI:003071*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003072*
+ ID_OUI_FROM_DATABASE=Intellibyte Inc.
+
+OUI:003073*
+ ID_OUI_FROM_DATABASE=International Microsystems, In
+
+OUI:003074*
+ ID_OUI_FROM_DATABASE=EQUIINET LTD.
+
+OUI:003075*
+ ID_OUI_FROM_DATABASE=ADTECH
+
+OUI:003076*
+ ID_OUI_FROM_DATABASE=Akamba Corporation
+
+OUI:003077*
+ ID_OUI_FROM_DATABASE=ONPREM NETWORKS
+
+OUI:003078*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003079*
+ ID_OUI_FROM_DATABASE=CQOS, INC.
+
+OUI:00307A*
+ ID_OUI_FROM_DATABASE=Advanced Technology & Systems
+
+OUI:00307B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00307C*
+ ID_OUI_FROM_DATABASE=ADID SA
+
+OUI:00307D*
+ ID_OUI_FROM_DATABASE=GRE AMERICA, INC.
+
+OUI:00307E*
+ ID_OUI_FROM_DATABASE=Redflex Communication Systems
+
+OUI:00307F*
+ ID_OUI_FROM_DATABASE=IRLAN LTD.
+
+OUI:003080*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003081*
+ ID_OUI_FROM_DATABASE=ALTOS C&C
+
+OUI:003082*
+ ID_OUI_FROM_DATABASE=TAIHAN ELECTRIC WIRE CO., LTD.
+
+OUI:003083*
+ ID_OUI_FROM_DATABASE=Ivron Systems
+
+OUI:003084*
+ ID_OUI_FROM_DATABASE=ALLIED TELESYN INTERNAIONAL
+
+OUI:003085*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003086*
+ ID_OUI_FROM_DATABASE=Transistor Devices, Inc.
+
+OUI:003087*
+ ID_OUI_FROM_DATABASE=VEGA GRIESHABER KG
+
+OUI:003088*
+ ID_OUI_FROM_DATABASE=Ericsson
+
+OUI:003089*
+ ID_OUI_FROM_DATABASE=Spectrapoint Wireless, LLC
+
+OUI:00308A*
+ ID_OUI_FROM_DATABASE=NICOTRA SISTEMI S.P.A
+
+OUI:00308B*
+ ID_OUI_FROM_DATABASE=Brix Networks
+
+OUI:00308C*
+ ID_OUI_FROM_DATABASE=Quantum Corporation
+
+OUI:00308D*
+ ID_OUI_FROM_DATABASE=Pinnacle Systems, Inc.
+
+OUI:00308E*
+ ID_OUI_FROM_DATABASE=CROSS MATCH TECHNOLOGIES, INC.
+
+OUI:00308F*
+ ID_OUI_FROM_DATABASE=MICRILOR, Inc.
+
+OUI:003090*
+ ID_OUI_FROM_DATABASE=CYRA TECHNOLOGIES, INC.
+
+OUI:003091*
+ ID_OUI_FROM_DATABASE=TAIWAN FIRST LINE ELEC. CORP.
+
+OUI:003092*
+ ID_OUI_FROM_DATABASE=ModuNORM GmbH
+
+OUI:003093*
+ ID_OUI_FROM_DATABASE=Sonnet Technologies, Inc
+
+OUI:003094*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003095*
+ ID_OUI_FROM_DATABASE=Procomp Informatics, Ltd.
+
+OUI:003096*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003097*
+ ID_OUI_FROM_DATABASE=AB Regin
+
+OUI:003098*
+ ID_OUI_FROM_DATABASE=Global Converging Technologies
+
+OUI:003099*
+ ID_OUI_FROM_DATABASE=BOENIG UND KALLENBACH OHG
+
+OUI:00309A*
+ ID_OUI_FROM_DATABASE=ASTRO TERRA CORP.
+
+OUI:00309B*
+ ID_OUI_FROM_DATABASE=Smartware
+
+OUI:00309C*
+ ID_OUI_FROM_DATABASE=Timing Applications, Inc.
+
+OUI:00309D*
+ ID_OUI_FROM_DATABASE=Nimble Microsystems, Inc.
+
+OUI:00309E*
+ ID_OUI_FROM_DATABASE=WORKBIT CORPORATION.
+
+OUI:00309F*
+ ID_OUI_FROM_DATABASE=AMBER NETWORKS
+
+OUI:0030A0*
+ ID_OUI_FROM_DATABASE=TYCO SUBMARINE SYSTEMS, LTD.
+
+OUI:0030A1*
+ ID_OUI_FROM_DATABASE=WEBGATE Inc.
+
+OUI:0030A2*
+ ID_OUI_FROM_DATABASE=Lightner Engineering
+
+OUI:0030A3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0030A4*
+ ID_OUI_FROM_DATABASE=Woodwind Communications System
+
+OUI:0030A5*
+ ID_OUI_FROM_DATABASE=ACTIVE POWER
+
+OUI:0030A6*
+ ID_OUI_FROM_DATABASE=VIANET TECHNOLOGIES, LTD.
+
+OUI:0030A7*
+ ID_OUI_FROM_DATABASE=SCHWEITZER ENGINEERING
+
+OUI:0030A8*
+ ID_OUI_FROM_DATABASE=OL'E COMMUNICATIONS, INC.
+
+OUI:0030A9*
+ ID_OUI_FROM_DATABASE=Netiverse, Inc.
+
+OUI:0030AA*
+ ID_OUI_FROM_DATABASE=AXUS MICROSYSTEMS, INC.
+
+OUI:0030AB*
+ ID_OUI_FROM_DATABASE=DELTA NETWORKS, INC.
+
+OUI:0030AC*
+ ID_OUI_FROM_DATABASE=Systeme Lauer GmbH & Co., Ltd.
+
+OUI:0030AD*
+ ID_OUI_FROM_DATABASE=SHANGHAI COMMUNICATION
+
+OUI:0030AE*
+ ID_OUI_FROM_DATABASE=Times N System, Inc.
+
+OUI:0030AF*
+ ID_OUI_FROM_DATABASE=Honeywell GmbH
+
+OUI:0030B0*
+ ID_OUI_FROM_DATABASE=Convergenet Technologies
+
+OUI:0030B1*
+ ID_OUI_FROM_DATABASE=TrunkNet
+
+OUI:0030B2*
+ ID_OUI_FROM_DATABASE=L-3 Sonoma EO
+
+OUI:0030B3*
+ ID_OUI_FROM_DATABASE=San Valley Systems, Inc.
+
+OUI:0030B4*
+ ID_OUI_FROM_DATABASE=INTERSIL CORP.
+
+OUI:0030B5*
+ ID_OUI_FROM_DATABASE=Tadiran Microwave Networks
+
+OUI:0030B6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0030B7*
+ ID_OUI_FROM_DATABASE=Teletrol Systems, Inc.
+
+OUI:0030B8*
+ ID_OUI_FROM_DATABASE=RiverDelta Networks
+
+OUI:0030B9*
+ ID_OUI_FROM_DATABASE=ECTEL
+
+OUI:0030BA*
+ ID_OUI_FROM_DATABASE=AC&T SYSTEM CO., LTD.
+
+OUI:0030BB*
+ ID_OUI_FROM_DATABASE=CacheFlow, Inc.
+
+OUI:0030BC*
+ ID_OUI_FROM_DATABASE=Optronic AG
+
+OUI:0030BD*
+ ID_OUI_FROM_DATABASE=BELKIN COMPONENTS
+
+OUI:0030BE*
+ ID_OUI_FROM_DATABASE=City-Net Technology, Inc.
+
+OUI:0030BF*
+ ID_OUI_FROM_DATABASE=MULTIDATA GMBH
+
+OUI:0030C0*
+ ID_OUI_FROM_DATABASE=Lara Technology, Inc.
+
+OUI:0030C1*
+ ID_OUI_FROM_DATABASE=HEWLETT-PACKARD
+
+OUI:0030C2*
+ ID_OUI_FROM_DATABASE=COMONE
+
+OUI:0030C3*
+ ID_OUI_FROM_DATABASE=FLUECKIGER ELEKTRONIK AG
+
+OUI:0030C4*
+ ID_OUI_FROM_DATABASE=Canon Imaging Systems Inc.
+
+OUI:0030C5*
+ ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS
+
+OUI:0030C6*
+ ID_OUI_FROM_DATABASE=CONTROL SOLUTIONS, INC.
+
+OUI:0030C7*
+ ID_OUI_FROM_DATABASE=Macromate Corp.
+
+OUI:0030C8*
+ ID_OUI_FROM_DATABASE=GAD LINE, LTD.
+
+OUI:0030C9*
+ ID_OUI_FROM_DATABASE=LuxN, N
+
+OUI:0030CA*
+ ID_OUI_FROM_DATABASE=Discovery Com
+
+OUI:0030CB*
+ ID_OUI_FROM_DATABASE=OMNI FLOW COMPUTERS, INC.
+
+OUI:0030CC*
+ ID_OUI_FROM_DATABASE=Tenor Networks, Inc.
+
+OUI:0030CD*
+ ID_OUI_FROM_DATABASE=CONEXANT SYSTEMS, INC.
+
+OUI:0030CE*
+ ID_OUI_FROM_DATABASE=Zaffire
+
+OUI:0030CF*
+ ID_OUI_FROM_DATABASE=TWO TECHNOLOGIES, INC.
+
+OUI:0030D0*
+ ID_OUI_FROM_DATABASE=Tellabs
+
+OUI:0030D1*
+ ID_OUI_FROM_DATABASE=INOVA CORPORATION
+
+OUI:0030D2*
+ ID_OUI_FROM_DATABASE=WIN TECHNOLOGIES, CO., LTD.
+
+OUI:0030D3*
+ ID_OUI_FROM_DATABASE=Agilent Technologies
+
+OUI:0030D4*
+ ID_OUI_FROM_DATABASE=AAE Systems, Inc
+
+OUI:0030D5*
+ ID_OUI_FROM_DATABASE=DResearch GmbH
+
+OUI:0030D6*
+ ID_OUI_FROM_DATABASE=MSC VERTRIEBS GMBH
+
+OUI:0030D7*
+ ID_OUI_FROM_DATABASE=Innovative Systems, L.L.C.
+
+OUI:0030D8*
+ ID_OUI_FROM_DATABASE=SITEK
+
+OUI:0030D9*
+ ID_OUI_FROM_DATABASE=DATACORE SOFTWARE CORP.
+
+OUI:0030DA*
+ ID_OUI_FROM_DATABASE=COMTREND CO.
+
+OUI:0030DB*
+ ID_OUI_FROM_DATABASE=Mindready Solutions, Inc.
+
+OUI:0030DC*
+ ID_OUI_FROM_DATABASE=RIGHTECH CORPORATION
+
+OUI:0030DD*
+ ID_OUI_FROM_DATABASE=INDIGITA CORPORATION
+
+OUI:0030DE*
+ ID_OUI_FROM_DATABASE=WAGO Kontakttechnik GmbH
+
+OUI:0030DF*
+ ID_OUI_FROM_DATABASE=KB/TEL TELECOMUNICACIONES
+
+OUI:0030E0*
+ ID_OUI_FROM_DATABASE=OXFORD SEMICONDUCTOR LTD.
+
+OUI:0030E1*
+ ID_OUI_FROM_DATABASE=Network Equipment Technologies, Inc.
+
+OUI:0030E2*
+ ID_OUI_FROM_DATABASE=GARNET SYSTEMS CO., LTD.
+
+OUI:0030E3*
+ ID_OUI_FROM_DATABASE=SEDONA NETWORKS CORP.
+
+OUI:0030E4*
+ ID_OUI_FROM_DATABASE=CHIYODA SYSTEM RIKEN
+
+OUI:0030E5*
+ ID_OUI_FROM_DATABASE=Amper Datos S.A.
+
+OUI:0030E6*
+ ID_OUI_FROM_DATABASE=Draeger Medical Systems, Inc.
+
+OUI:0030E7*
+ ID_OUI_FROM_DATABASE=CNF MOBILE SOLUTIONS, INC.
+
+OUI:0030E8*
+ ID_OUI_FROM_DATABASE=ENSIM CORP.
+
+OUI:0030E9*
+ ID_OUI_FROM_DATABASE=GMA COMMUNICATION MANUFACT'G
+
+OUI:0030EA*
+ ID_OUI_FROM_DATABASE=TeraForce Technology Corporation
+
+OUI:0030EB*
+ ID_OUI_FROM_DATABASE=TURBONET COMMUNICATIONS, INC.
+
+OUI:0030EC*
+ ID_OUI_FROM_DATABASE=BORGARDT
+
+OUI:0030ED*
+ ID_OUI_FROM_DATABASE=Expert Magnetics Corp.
+
+OUI:0030EE*
+ ID_OUI_FROM_DATABASE=DSG Technology, Inc.
+
+OUI:0030EF*
+ ID_OUI_FROM_DATABASE=NEON TECHNOLOGY, INC.
+
+OUI:0030F0*
+ ID_OUI_FROM_DATABASE=Uniform Industrial Corp.
+
+OUI:0030F1*
+ ID_OUI_FROM_DATABASE=Accton Technology Corp.
+
+OUI:0030F2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0030F3*
+ ID_OUI_FROM_DATABASE=At Work Computers
+
+OUI:0030F4*
+ ID_OUI_FROM_DATABASE=STARDOT TECHNOLOGIES
+
+OUI:0030F5*
+ ID_OUI_FROM_DATABASE=Wild Lab. Ltd.
+
+OUI:0030F6*
+ ID_OUI_FROM_DATABASE=SECURELOGIX CORPORATION
+
+OUI:0030F7*
+ ID_OUI_FROM_DATABASE=RAMIX INC.
+
+OUI:0030F8*
+ ID_OUI_FROM_DATABASE=Dynapro Systems, Inc.
+
+OUI:0030F9*
+ ID_OUI_FROM_DATABASE=Sollae Systems Co., Ltd.
+
+OUI:0030FA*
+ ID_OUI_FROM_DATABASE=TELICA, INC.
+
+OUI:0030FB*
+ ID_OUI_FROM_DATABASE=AZS Technology AG
+
+OUI:0030FC*
+ ID_OUI_FROM_DATABASE=Terawave Communications, Inc.
+
+OUI:0030FD*
+ ID_OUI_FROM_DATABASE=INTEGRATED SYSTEMS DESIGN
+
+OUI:0030FE*
+ ID_OUI_FROM_DATABASE=DSA GmbH
+
+OUI:0030FF*
+ ID_OUI_FROM_DATABASE=DATAFAB SYSTEMS, INC.
+
+OUI:00336C*
+ ID_OUI_FROM_DATABASE=SynapSense Corporation
+
+OUI:0034F1*
+ ID_OUI_FROM_DATABASE=Radicom Research, Inc.
+
+OUI:003532*
+ ID_OUI_FROM_DATABASE=Electro-Metrics Corporation
+
+OUI:0036F8*
+ ID_OUI_FROM_DATABASE=Conti Temic microelectronic GmbH
+
+OUI:0036FE*
+ ID_OUI_FROM_DATABASE=SuperVision
+
+OUI:00376D*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:003A98*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003A99*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003A9A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003A9B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003A9C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:003A9D*
+ ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+
+OUI:003AAF*
+ ID_OUI_FROM_DATABASE=BlueBit Ltd.
+
+OUI:003CC5*
+ ID_OUI_FROM_DATABASE=WONWOO Engineering Co., Ltd
+
+OUI:003D41*
+ ID_OUI_FROM_DATABASE=Hatteland Computer AS
+
+OUI:003EE1*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:004000*
+ ID_OUI_FROM_DATABASE=PCI COMPONENTES DA AMZONIA LTD
+
+OUI:004001*
+ ID_OUI_FROM_DATABASE=Zero One Technology Co. Ltd.
+
+OUI:004002*
+ ID_OUI_FROM_DATABASE=PERLE SYSTEMS LIMITED
+
+OUI:004003*
+ ID_OUI_FROM_DATABASE=Emerson Process Management Power & Water Solutions, Inc.
+
+OUI:004004*
+ ID_OUI_FROM_DATABASE=ICM CO. LTD.
+
+OUI:004005*
+ ID_OUI_FROM_DATABASE=ANI COMMUNICATIONS INC.
+
+OUI:004006*
+ ID_OUI_FROM_DATABASE=SAMPO TECHNOLOGY CORPORATION
+
+OUI:004007*
+ ID_OUI_FROM_DATABASE=TELMAT INFORMATIQUE
+
+OUI:004008*
+ ID_OUI_FROM_DATABASE=A PLUS INFO CORPORATION
+
+OUI:004009*
+ ID_OUI_FROM_DATABASE=TACHIBANA TECTRON CO., LTD.
+
+OUI:00400A*
+ ID_OUI_FROM_DATABASE=PIVOTAL TECHNOLOGIES, INC.
+
+OUI:00400B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00400C*
+ ID_OUI_FROM_DATABASE=GENERAL MICRO SYSTEMS, INC.
+
+OUI:00400D*
+ ID_OUI_FROM_DATABASE=LANNET DATA COMMUNICATIONS,LTD
+
+OUI:00400E*
+ ID_OUI_FROM_DATABASE=MEMOTEC, INC.
+
+OUI:00400F*
+ ID_OUI_FROM_DATABASE=DATACOM TECHNOLOGIES
+
+OUI:004010*
+ ID_OUI_FROM_DATABASE=SONIC SYSTEMS, INC.
+
+OUI:004011*
+ ID_OUI_FROM_DATABASE=ANDOVER CONTROLS CORPORATION
+
+OUI:004012*
+ ID_OUI_FROM_DATABASE=WINDATA, INC.
+
+OUI:004013*
+ ID_OUI_FROM_DATABASE=NTT DATA COMM. SYSTEMS CORP.
+
+OUI:004014*
+ ID_OUI_FROM_DATABASE=COMSOFT GMBH
+
+OUI:004015*
+ ID_OUI_FROM_DATABASE=ASCOM INFRASYS AG
+
+OUI:004016*
+ ID_OUI_FROM_DATABASE=ADC - Global Connectivity Solutions Division
+
+OUI:004017*
+ ID_OUI_FROM_DATABASE=Silex Technology America
+
+OUI:004018*
+ ID_OUI_FROM_DATABASE=ADOBE SYSTEMS, INC.
+
+OUI:004019*
+ ID_OUI_FROM_DATABASE=AEON SYSTEMS, INC.
+
+OUI:00401A*
+ ID_OUI_FROM_DATABASE=FUJI ELECTRIC CO., LTD.
+
+OUI:00401B*
+ ID_OUI_FROM_DATABASE=PRINTER SYSTEMS CORP.
+
+OUI:00401C*
+ ID_OUI_FROM_DATABASE=AST RESEARCH, INC.
+
+OUI:00401D*
+ ID_OUI_FROM_DATABASE=INVISIBLE SOFTWARE, INC.
+
+OUI:00401E*
+ ID_OUI_FROM_DATABASE=ICC
+
+OUI:00401F*
+ ID_OUI_FROM_DATABASE=COLORGRAPH LTD
+
+OUI:004020*
+ ID_OUI_FROM_DATABASE=TE Connectivity Ltd.
+
+OUI:004021*
+ ID_OUI_FROM_DATABASE=RASTER GRAPHICS
+
+OUI:004022*
+ ID_OUI_FROM_DATABASE=KLEVER COMPUTERS, INC.
+
+OUI:004023*
+ ID_OUI_FROM_DATABASE=LOGIC CORPORATION
+
+OUI:004024*
+ ID_OUI_FROM_DATABASE=COMPAC INC.
+
+OUI:004025*
+ ID_OUI_FROM_DATABASE=MOLECULAR DYNAMICS
+
+OUI:004026*
+ ID_OUI_FROM_DATABASE=Buffalo, Inc
+
+OUI:004027*
+ ID_OUI_FROM_DATABASE=SMC MASSACHUSETTS, INC.
+
+OUI:004028*
+ ID_OUI_FROM_DATABASE=NETCOMM LIMITED
+
+OUI:004029*
+ ID_OUI_FROM_DATABASE=COMPEX
+
+OUI:00402A*
+ ID_OUI_FROM_DATABASE=CANOGA-PERKINS
+
+OUI:00402B*
+ ID_OUI_FROM_DATABASE=TRIGEM COMPUTER, INC.
+
+OUI:00402C*
+ ID_OUI_FROM_DATABASE=ISIS DISTRIBUTED SYSTEMS, INC.
+
+OUI:00402D*
+ ID_OUI_FROM_DATABASE=HARRIS ADACOM CORPORATION
+
+OUI:00402E*
+ ID_OUI_FROM_DATABASE=PRECISION SOFTWARE, INC.
+
+OUI:00402F*
+ ID_OUI_FROM_DATABASE=XLNT DESIGNS INC.
+
+OUI:004030*
+ ID_OUI_FROM_DATABASE=GK COMPUTER
+
+OUI:004031*
+ ID_OUI_FROM_DATABASE=KOKUSAI ELECTRIC CO., LTD
+
+OUI:004032*
+ ID_OUI_FROM_DATABASE=DIGITAL COMMUNICATIONS
+
+OUI:004033*
+ ID_OUI_FROM_DATABASE=ADDTRON TECHNOLOGY CO., LTD.
+
+OUI:004034*
+ ID_OUI_FROM_DATABASE=BUSTEK CORPORATION
+
+OUI:004035*
+ ID_OUI_FROM_DATABASE=OPCOM
+
+OUI:004036*
+ ID_OUI_FROM_DATABASE=TRIBE COMPUTER WORKS, INC.
+
+OUI:004037*
+ ID_OUI_FROM_DATABASE=SEA-ILAN, INC.
+
+OUI:004038*
+ ID_OUI_FROM_DATABASE=TALENT ELECTRIC INCORPORATED
+
+OUI:004039*
+ ID_OUI_FROM_DATABASE=OPTEC DAIICHI DENKO CO., LTD.
+
+OUI:00403A*
+ ID_OUI_FROM_DATABASE=IMPACT TECHNOLOGIES
+
+OUI:00403B*
+ ID_OUI_FROM_DATABASE=SYNERJET INTERNATIONAL CORP.
+
+OUI:00403C*
+ ID_OUI_FROM_DATABASE=FORKS, INC.
+
+OUI:00403D*
+ ID_OUI_FROM_DATABASE=Teradata Corporation
+
+OUI:00403E*
+ ID_OUI_FROM_DATABASE=RASTER OPS CORPORATION
+
+OUI:00403F*
+ ID_OUI_FROM_DATABASE=SSANGYONG COMPUTER SYSTEMS
+
+OUI:004040*
+ ID_OUI_FROM_DATABASE=RING ACCESS, INC.
+
+OUI:004041*
+ ID_OUI_FROM_DATABASE=FUJIKURA LTD.
+
+OUI:004042*
+ ID_OUI_FROM_DATABASE=N.A.T. GMBH
+
+OUI:004043*
+ ID_OUI_FROM_DATABASE=Nokia Siemens Networks GmbH & Co. KG.
+
+OUI:004044*
+ ID_OUI_FROM_DATABASE=QNIX COMPUTER CO., LTD.
+
+OUI:004045*
+ ID_OUI_FROM_DATABASE=TWINHEAD CORPORATION
+
+OUI:004046*
+ ID_OUI_FROM_DATABASE=UDC RESEARCH LIMITED
+
+OUI:004047*
+ ID_OUI_FROM_DATABASE=WIND RIVER SYSTEMS
+
+OUI:004048*
+ ID_OUI_FROM_DATABASE=SMD INFORMATICA S.A.
+
+OUI:004049*
+ ID_OUI_FROM_DATABASE=Roche Diagnostics Ltd.
+
+OUI:00404A*
+ ID_OUI_FROM_DATABASE=WEST AUSTRALIAN DEPARTMENT
+
+OUI:00404B*
+ ID_OUI_FROM_DATABASE=MAPLE COMPUTER SYSTEMS
+
+OUI:00404C*
+ ID_OUI_FROM_DATABASE=HYPERTEC PTY LTD.
+
+OUI:00404D*
+ ID_OUI_FROM_DATABASE=TELECOMMUNICATIONS TECHNIQUES
+
+OUI:00404E*
+ ID_OUI_FROM_DATABASE=FLUENT, INC.
+
+OUI:00404F*
+ ID_OUI_FROM_DATABASE=SPACE & NAVAL WARFARE SYSTEMS
+
+OUI:004050*
+ ID_OUI_FROM_DATABASE=IRONICS, INCORPORATED
+
+OUI:004051*
+ ID_OUI_FROM_DATABASE=GRACILIS, INC.
+
+OUI:004052*
+ ID_OUI_FROM_DATABASE=STAR TECHNOLOGIES, INC.
+
+OUI:004053*
+ ID_OUI_FROM_DATABASE=AMPRO COMPUTERS
+
+OUI:004054*
+ ID_OUI_FROM_DATABASE=CONNECTION MACHINES SERVICES
+
+OUI:004055*
+ ID_OUI_FROM_DATABASE=METRONIX GMBH
+
+OUI:004056*
+ ID_OUI_FROM_DATABASE=MCM JAPAN LTD.
+
+OUI:004057*
+ ID_OUI_FROM_DATABASE=LOCKHEED - SANDERS
+
+OUI:004058*
+ ID_OUI_FROM_DATABASE=KRONOS, INC.
+
+OUI:004059*
+ ID_OUI_FROM_DATABASE=YOSHIDA KOGYO K. K.
+
+OUI:00405A*
+ ID_OUI_FROM_DATABASE=GOLDSTAR INFORMATION & COMM.
+
+OUI:00405B*
+ ID_OUI_FROM_DATABASE=FUNASSET LIMITED
+
+OUI:00405C*
+ ID_OUI_FROM_DATABASE=FUTURE SYSTEMS, INC.
+
+OUI:00405D*
+ ID_OUI_FROM_DATABASE=STAR-TEK, INC.
+
+OUI:00405E*
+ ID_OUI_FROM_DATABASE=NORTH HILLS ISRAEL
+
+OUI:00405F*
+ ID_OUI_FROM_DATABASE=AFE COMPUTERS LTD.
+
+OUI:004060*
+ ID_OUI_FROM_DATABASE=COMENDEC LTD
+
+OUI:004061*
+ ID_OUI_FROM_DATABASE=DATATECH ENTERPRISES CO., LTD.
+
+OUI:004062*
+ ID_OUI_FROM_DATABASE=E-SYSTEMS, INC./GARLAND DIV.
+
+OUI:004063*
+ ID_OUI_FROM_DATABASE=VIA TECHNOLOGIES, INC.
+
+OUI:004064*
+ ID_OUI_FROM_DATABASE=KLA INSTRUMENTS CORPORATION
+
+OUI:004065*
+ ID_OUI_FROM_DATABASE=GTE SPACENET
+
+OUI:004066*
+ ID_OUI_FROM_DATABASE=HITACHI CABLE, LTD.
+
+OUI:004067*
+ ID_OUI_FROM_DATABASE=OMNIBYTE CORPORATION
+
+OUI:004068*
+ ID_OUI_FROM_DATABASE=EXTENDED SYSTEMS
+
+OUI:004069*
+ ID_OUI_FROM_DATABASE=LEMCOM SYSTEMS, INC.
+
+OUI:00406A*
+ ID_OUI_FROM_DATABASE=KENTEK INFORMATION SYSTEMS,INC
+
+OUI:00406B*
+ ID_OUI_FROM_DATABASE=SYSGEN
+
+OUI:00406C*
+ ID_OUI_FROM_DATABASE=COPERNIQUE
+
+OUI:00406D*
+ ID_OUI_FROM_DATABASE=LANCO, INC.
+
+OUI:00406E*
+ ID_OUI_FROM_DATABASE=COROLLARY, INC.
+
+OUI:00406F*
+ ID_OUI_FROM_DATABASE=SYNC RESEARCH INC.
+
+OUI:004070*
+ ID_OUI_FROM_DATABASE=INTERWARE CO., LTD.
+
+OUI:004071*
+ ID_OUI_FROM_DATABASE=ATM COMPUTER GMBH
+
+OUI:004072*
+ ID_OUI_FROM_DATABASE=Applied Innovation Inc.
+
+OUI:004073*
+ ID_OUI_FROM_DATABASE=BASS ASSOCIATES
+
+OUI:004074*
+ ID_OUI_FROM_DATABASE=CABLE AND WIRELESS
+
+OUI:004075*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:004076*
+ ID_OUI_FROM_DATABASE=Sun Conversion Technologies
+
+OUI:004077*
+ ID_OUI_FROM_DATABASE=MAXTON TECHNOLOGY CORPORATION
+
+OUI:004078*
+ ID_OUI_FROM_DATABASE=WEARNES AUTOMATION PTE LTD
+
+OUI:004079*
+ ID_OUI_FROM_DATABASE=JUKO MANUFACTURE COMPANY, LTD.
+
+OUI:00407A*
+ ID_OUI_FROM_DATABASE=SOCIETE D'EXPLOITATION DU CNIT
+
+OUI:00407B*
+ ID_OUI_FROM_DATABASE=SCIENTIFIC ATLANTA
+
+OUI:00407C*
+ ID_OUI_FROM_DATABASE=QUME CORPORATION
+
+OUI:00407D*
+ ID_OUI_FROM_DATABASE=EXTENSION TECHNOLOGY CORP.
+
+OUI:00407E*
+ ID_OUI_FROM_DATABASE=EVERGREEN SYSTEMS, INC.
+
+OUI:00407F*
+ ID_OUI_FROM_DATABASE=FLIR Systems
+
+OUI:004080*
+ ID_OUI_FROM_DATABASE=ATHENIX CORPORATION
+
+OUI:004081*
+ ID_OUI_FROM_DATABASE=MANNESMANN SCANGRAPHIC GMBH
+
+OUI:004082*
+ ID_OUI_FROM_DATABASE=LABORATORY EQUIPMENT CORP.
+
+OUI:004083*
+ ID_OUI_FROM_DATABASE=TDA INDUSTRIA DE PRODUTOS
+
+OUI:004084*
+ ID_OUI_FROM_DATABASE=HONEYWELL ACS
+
+OUI:004085*
+ ID_OUI_FROM_DATABASE=SAAB INSTRUMENTS AB
+
+OUI:004086*
+ ID_OUI_FROM_DATABASE=MICHELS & KLEBERHOFF COMPUTER
+
+OUI:004087*
+ ID_OUI_FROM_DATABASE=UBITREX CORPORATION
+
+OUI:004088*
+ ID_OUI_FROM_DATABASE=MOBIUS TECHNOLOGIES, INC.
+
+OUI:004089*
+ ID_OUI_FROM_DATABASE=MEIDENSHA CORPORATION
+
+OUI:00408A*
+ ID_OUI_FROM_DATABASE=TPS TELEPROCESSING SYS. GMBH
+
+OUI:00408B*
+ ID_OUI_FROM_DATABASE=RAYLAN CORPORATION
+
+OUI:00408C*
+ ID_OUI_FROM_DATABASE=AXIS COMMUNICATIONS AB
+
+OUI:00408D*
+ ID_OUI_FROM_DATABASE=THE GOODYEAR TIRE & RUBBER CO.
+
+OUI:00408E*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:00408F*
+ ID_OUI_FROM_DATABASE=WM-DATA MINFO AB
+
+OUI:004090*
+ ID_OUI_FROM_DATABASE=ANSEL COMMUNICATIONS
+
+OUI:004091*
+ ID_OUI_FROM_DATABASE=PROCOMP INDUSTRIA ELETRONICA
+
+OUI:004092*
+ ID_OUI_FROM_DATABASE=ASP COMPUTER PRODUCTS, INC.
+
+OUI:004093*
+ ID_OUI_FROM_DATABASE=PAXDATA NETWORKS LTD.
+
+OUI:004094*
+ ID_OUI_FROM_DATABASE=SHOGRAPHICS, INC.
+
+OUI:004095*
+ ID_OUI_FROM_DATABASE=R.P.T. INTERGROUPS INT'L LTD.
+
+OUI:004096*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc.
+
+OUI:004097*
+ ID_OUI_FROM_DATABASE=DATEX DIVISION OF
+
+OUI:004098*
+ ID_OUI_FROM_DATABASE=DRESSLER GMBH & CO.
+
+OUI:004099*
+ ID_OUI_FROM_DATABASE=NEWGEN SYSTEMS CORP.
+
+OUI:00409A*
+ ID_OUI_FROM_DATABASE=NETWORK EXPRESS, INC.
+
+OUI:00409B*
+ ID_OUI_FROM_DATABASE=HAL COMPUTER SYSTEMS INC.
+
+OUI:00409C*
+ ID_OUI_FROM_DATABASE=TRANSWARE
+
+OUI:00409D*
+ ID_OUI_FROM_DATABASE=DIGIBOARD, INC.
+
+OUI:00409E*
+ ID_OUI_FROM_DATABASE=CONCURRENT TECHNOLOGIES  LTD.
+
+OUI:00409F*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:0040A0*
+ ID_OUI_FROM_DATABASE=GOLDSTAR CO., LTD.
+
+OUI:0040A1*
+ ID_OUI_FROM_DATABASE=ERGO COMPUTING
+
+OUI:0040A2*
+ ID_OUI_FROM_DATABASE=KINGSTAR TECHNOLOGY INC.
+
+OUI:0040A3*
+ ID_OUI_FROM_DATABASE=MICROUNITY SYSTEMS ENGINEERING
+
+OUI:0040A4*
+ ID_OUI_FROM_DATABASE=ROSE ELECTRONICS
+
+OUI:0040A5*
+ ID_OUI_FROM_DATABASE=CLINICOMP INTL.
+
+OUI:0040A6*
+ ID_OUI_FROM_DATABASE=Cray, Inc.
+
+OUI:0040A7*
+ ID_OUI_FROM_DATABASE=ITAUTEC PHILCO S.A.
+
+OUI:0040A8*
+ ID_OUI_FROM_DATABASE=IMF INTERNATIONAL LTD.
+
+OUI:0040A9*
+ ID_OUI_FROM_DATABASE=DATACOM INC.
+
+OUI:0040AA*
+ ID_OUI_FROM_DATABASE=VALMET AUTOMATION INC.
+
+OUI:0040AB*
+ ID_OUI_FROM_DATABASE=ROLAND DG CORPORATION
+
+OUI:0040AC*
+ ID_OUI_FROM_DATABASE=SUPER WORKSTATION, INC.
+
+OUI:0040AD*
+ ID_OUI_FROM_DATABASE=SMA REGELSYSTEME GMBH
+
+OUI:0040AE*
+ ID_OUI_FROM_DATABASE=DELTA CONTROLS, INC.
+
+OUI:0040AF*
+ ID_OUI_FROM_DATABASE=DIGITAL PRODUCTS, INC.
+
+OUI:0040B0*
+ ID_OUI_FROM_DATABASE=BYTEX CORPORATION, ENGINEERING
+
+OUI:0040B1*
+ ID_OUI_FROM_DATABASE=CODONICS INC.
+
+OUI:0040B2*
+ ID_OUI_FROM_DATABASE=SYSTEMFORSCHUNG
+
+OUI:0040B3*
+ ID_OUI_FROM_DATABASE=ParTech Inc.
+
+OUI:0040B4*
+ ID_OUI_FROM_DATABASE=NEXTCOM K.K.
+
+OUI:0040B5*
+ ID_OUI_FROM_DATABASE=VIDEO TECHNOLOGY COMPUTERS LTD
+
+OUI:0040B6*
+ ID_OUI_FROM_DATABASE=COMPUTERM  CORPORATION
+
+OUI:0040B7*
+ ID_OUI_FROM_DATABASE=STEALTH COMPUTER SYSTEMS
+
+OUI:0040B8*
+ ID_OUI_FROM_DATABASE=IDEA ASSOCIATES
+
+OUI:0040B9*
+ ID_OUI_FROM_DATABASE=MACQ ELECTRONIQUE SA
+
+OUI:0040BA*
+ ID_OUI_FROM_DATABASE=ALLIANT COMPUTER SYSTEMS CORP.
+
+OUI:0040BB*
+ ID_OUI_FROM_DATABASE=GOLDSTAR CABLE CO., LTD.
+
+OUI:0040BC*
+ ID_OUI_FROM_DATABASE=ALGORITHMICS LTD.
+
+OUI:0040BD*
+ ID_OUI_FROM_DATABASE=STARLIGHT NETWORKS, INC.
+
+OUI:0040BE*
+ ID_OUI_FROM_DATABASE=BOEING DEFENSE & SPACE
+
+OUI:0040BF*
+ ID_OUI_FROM_DATABASE=CHANNEL SYSTEMS INTERN'L INC.
+
+OUI:0040C0*
+ ID_OUI_FROM_DATABASE=VISTA CONTROLS CORPORATION
+
+OUI:0040C1*
+ ID_OUI_FROM_DATABASE=BIZERBA-WERKE WILHEIM KRAUT
+
+OUI:0040C2*
+ ID_OUI_FROM_DATABASE=APPLIED COMPUTING DEVICES
+
+OUI:0040C3*
+ ID_OUI_FROM_DATABASE=FISCHER AND PORTER CO.
+
+OUI:0040C4*
+ ID_OUI_FROM_DATABASE=KINKEI SYSTEM CORPORATION
+
+OUI:0040C5*
+ ID_OUI_FROM_DATABASE=MICOM COMMUNICATIONS INC.
+
+OUI:0040C6*
+ ID_OUI_FROM_DATABASE=FIBERNET RESEARCH, INC.
+
+OUI:0040C7*
+ ID_OUI_FROM_DATABASE=RUBY TECH CORPORATION
+
+OUI:0040C8*
+ ID_OUI_FROM_DATABASE=MILAN TECHNOLOGY CORPORATION
+
+OUI:0040C9*
+ ID_OUI_FROM_DATABASE=NCUBE
+
+OUI:0040CA*
+ ID_OUI_FROM_DATABASE=FIRST INTERNAT'L COMPUTER, INC
+
+OUI:0040CB*
+ ID_OUI_FROM_DATABASE=LANWAN TECHNOLOGIES
+
+OUI:0040CC*
+ ID_OUI_FROM_DATABASE=SILCOM MANUF'G TECHNOLOGY INC.
+
+OUI:0040CD*
+ ID_OUI_FROM_DATABASE=TERA MICROSYSTEMS, INC.
+
+OUI:0040CE*
+ ID_OUI_FROM_DATABASE=NET-SOURCE, INC.
+
+OUI:0040CF*
+ ID_OUI_FROM_DATABASE=STRAWBERRY TREE, INC.
+
+OUI:0040D0*
+ ID_OUI_FROM_DATABASE=MITAC INTERNATIONAL CORP.
+
+OUI:0040D1*
+ ID_OUI_FROM_DATABASE=FUKUDA DENSHI CO., LTD.
+
+OUI:0040D2*
+ ID_OUI_FROM_DATABASE=PAGINE CORPORATION
+
+OUI:0040D3*
+ ID_OUI_FROM_DATABASE=KIMPSION INTERNATIONAL CORP.
+
+OUI:0040D4*
+ ID_OUI_FROM_DATABASE=GAGE TALKER CORP.
+
+OUI:0040D5*
+ ID_OUI_FROM_DATABASE=Sartorius Mechatronics T&H GmbH
+
+OUI:0040D6*
+ ID_OUI_FROM_DATABASE=LOCAMATION B.V.
+
+OUI:0040D7*
+ ID_OUI_FROM_DATABASE=STUDIO GEN INC.
+
+OUI:0040D8*
+ ID_OUI_FROM_DATABASE=OCEAN OFFICE AUTOMATION LTD.
+
+OUI:0040D9*
+ ID_OUI_FROM_DATABASE=AMERICAN MEGATRENDS INC.
+
+OUI:0040DA*
+ ID_OUI_FROM_DATABASE=TELSPEC LTD
+
+OUI:0040DB*
+ ID_OUI_FROM_DATABASE=ADVANCED TECHNICAL SOLUTIONS
+
+OUI:0040DC*
+ ID_OUI_FROM_DATABASE=TRITEC ELECTRONIC GMBH
+
+OUI:0040DD*
+ ID_OUI_FROM_DATABASE=HONG TECHNOLOGIES
+
+OUI:0040DE*
+ ID_OUI_FROM_DATABASE=Elsag Datamat spa
+
+OUI:0040DF*
+ ID_OUI_FROM_DATABASE=DIGALOG SYSTEMS, INC.
+
+OUI:0040E0*
+ ID_OUI_FROM_DATABASE=ATOMWIDE LTD.
+
+OUI:0040E1*
+ ID_OUI_FROM_DATABASE=MARNER INTERNATIONAL, INC.
+
+OUI:0040E2*
+ ID_OUI_FROM_DATABASE=MESA RIDGE TECHNOLOGIES, INC.
+
+OUI:0040E3*
+ ID_OUI_FROM_DATABASE=QUIN SYSTEMS LTD
+
+OUI:0040E4*
+ ID_OUI_FROM_DATABASE=E-M TECHNOLOGY, INC.
+
+OUI:0040E5*
+ ID_OUI_FROM_DATABASE=SYBUS CORPORATION
+
+OUI:0040E6*
+ ID_OUI_FROM_DATABASE=C.A.E.N.
+
+OUI:0040E7*
+ ID_OUI_FROM_DATABASE=ARNOS INSTRUMENTS & COMPUTER
+
+OUI:0040E8*
+ ID_OUI_FROM_DATABASE=CHARLES RIVER DATA SYSTEMS,INC
+
+OUI:0040E9*
+ ID_OUI_FROM_DATABASE=ACCORD SYSTEMS, INC.
+
+OUI:0040EA*
+ ID_OUI_FROM_DATABASE=PLAIN TREE SYSTEMS INC
+
+OUI:0040EB*
+ ID_OUI_FROM_DATABASE=MARTIN MARIETTA CORPORATION
+
+OUI:0040EC*
+ ID_OUI_FROM_DATABASE=MIKASA SYSTEM ENGINEERING
+
+OUI:0040ED*
+ ID_OUI_FROM_DATABASE=NETWORK CONTROLS INT'NATL INC.
+
+OUI:0040EE*
+ ID_OUI_FROM_DATABASE=OPTIMEM
+
+OUI:0040EF*
+ ID_OUI_FROM_DATABASE=HYPERCOM, INC.
+
+OUI:0040F0*
+ ID_OUI_FROM_DATABASE=MicroBrain,Inc.
+
+OUI:0040F1*
+ ID_OUI_FROM_DATABASE=CHUO ELECTRONICS CO., LTD.
+
+OUI:0040F2*
+ ID_OUI_FROM_DATABASE=JANICH & KLASS COMPUTERTECHNIK
+
+OUI:0040F3*
+ ID_OUI_FROM_DATABASE=NETCOR
+
+OUI:0040F4*
+ ID_OUI_FROM_DATABASE=CAMEO COMMUNICATIONS, INC.
+
+OUI:0040F5*
+ ID_OUI_FROM_DATABASE=OEM ENGINES
+
+OUI:0040F6*
+ ID_OUI_FROM_DATABASE=KATRON COMPUTERS INC.
+
+OUI:0040F7*
+ ID_OUI_FROM_DATABASE=Polaroid Corporation
+
+OUI:0040F8*
+ ID_OUI_FROM_DATABASE=SYSTEMHAUS DISCOM
+
+OUI:0040F9*
+ ID_OUI_FROM_DATABASE=COMBINET
+
+OUI:0040FA*
+ ID_OUI_FROM_DATABASE=MICROBOARDS, INC.
+
+OUI:0040FB*
+ ID_OUI_FROM_DATABASE=CASCADE COMMUNICATIONS CORP.
+
+OUI:0040FC*
+ ID_OUI_FROM_DATABASE=IBR COMPUTER TECHNIK GMBH
+
+OUI:0040FD*
+ ID_OUI_FROM_DATABASE=LXE
+
+OUI:0040FE*
+ ID_OUI_FROM_DATABASE=SYMPLEX COMMUNICATIONS
+
+OUI:0040FF*
+ ID_OUI_FROM_DATABASE=TELEBIT CORPORATION
+
+OUI:0041B4*
+ ID_OUI_FROM_DATABASE=Wuxi Zhongxing Optoelectronics Technology Co.,Ltd.
+
+OUI:004252*
+ ID_OUI_FROM_DATABASE=RLX Technologies
+
+OUI:0043FF*
+ ID_OUI_FROM_DATABASE=KETRON S.R.L.
+
+OUI:004501*
+ ID_OUI_FROM_DATABASE=Versus Technology, Inc.
+
+OUI:00464B*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:004D32*
+ ID_OUI_FROM_DATABASE=Andon Health Co.,Ltd.
+
+OUI:005000*
+ ID_OUI_FROM_DATABASE=NEXO COMMUNICATIONS, INC.
+
+OUI:005001*
+ ID_OUI_FROM_DATABASE=YAMASHITA SYSTEMS CORP.
+
+OUI:005002*
+ ID_OUI_FROM_DATABASE=OMNISEC AG
+
+OUI:005003*
+ ID_OUI_FROM_DATABASE=Xrite Inc
+
+OUI:005004*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:005006*
+ ID_OUI_FROM_DATABASE=TAC AB
+
+OUI:005007*
+ ID_OUI_FROM_DATABASE=SIEMENS TELECOMMUNICATION SYSTEMS LIMITED
+
+OUI:005008*
+ ID_OUI_FROM_DATABASE=TIVA MICROCOMPUTER CORP. (TMC)
+
+OUI:005009*
+ ID_OUI_FROM_DATABASE=PHILIPS BROADBAND NETWORKS
+
+OUI:00500A*
+ ID_OUI_FROM_DATABASE=IRIS TECHNOLOGIES, INC.
+
+OUI:00500B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00500C*
+ ID_OUI_FROM_DATABASE=e-Tek Labs, Inc.
+
+OUI:00500D*
+ ID_OUI_FROM_DATABASE=SATORI ELECTORIC CO., LTD.
+
+OUI:00500E*
+ ID_OUI_FROM_DATABASE=CHROMATIS NETWORKS, INC.
+
+OUI:00500F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:005010*
+ ID_OUI_FROM_DATABASE=NovaNET Learning, Inc.
+
+OUI:005012*
+ ID_OUI_FROM_DATABASE=CBL - GMBH
+
+OUI:005013*
+ ID_OUI_FROM_DATABASE=Chaparral Network Storage
+
+OUI:005014*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:005015*
+ ID_OUI_FROM_DATABASE=BRIGHT STAR ENGINEERING
+
+OUI:005016*
+ ID_OUI_FROM_DATABASE=SST/WOODHEAD INDUSTRIES
+
+OUI:005017*
+ ID_OUI_FROM_DATABASE=RSR S.R.L.
+
+OUI:005018*
+ ID_OUI_FROM_DATABASE=AMIT, Inc.
+
+OUI:005019*
+ ID_OUI_FROM_DATABASE=SPRING TIDE NETWORKS, INC.
+
+OUI:00501A*
+ ID_OUI_FROM_DATABASE=IQinVision
+
+OUI:00501B*
+ ID_OUI_FROM_DATABASE=ABL CANADA, INC.
+
+OUI:00501C*
+ ID_OUI_FROM_DATABASE=JATOM SYSTEMS, INC.
+
+OUI:00501E*
+ ID_OUI_FROM_DATABASE=Miranda Technologies, Inc.
+
+OUI:00501F*
+ ID_OUI_FROM_DATABASE=MRG SYSTEMS, LTD.
+
+OUI:005020*
+ ID_OUI_FROM_DATABASE=MEDIASTAR CO., LTD.
+
+OUI:005021*
+ ID_OUI_FROM_DATABASE=EIS INTERNATIONAL, INC.
+
+OUI:005022*
+ ID_OUI_FROM_DATABASE=ZONET TECHNOLOGY, INC.
+
+OUI:005023*
+ ID_OUI_FROM_DATABASE=PG DESIGN ELECTRONICS, INC.
+
+OUI:005024*
+ ID_OUI_FROM_DATABASE=NAVIC SYSTEMS, INC.
+
+OUI:005026*
+ ID_OUI_FROM_DATABASE=COSYSTEMS, INC.
+
+OUI:005027*
+ ID_OUI_FROM_DATABASE=GENICOM CORPORATION
+
+OUI:005028*
+ ID_OUI_FROM_DATABASE=AVAL COMMUNICATIONS
+
+OUI:005029*
+ ID_OUI_FROM_DATABASE=1394 PRINTER WORKING GROUP
+
+OUI:00502A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00502B*
+ ID_OUI_FROM_DATABASE=GENRAD LTD.
+
+OUI:00502C*
+ ID_OUI_FROM_DATABASE=SOYO COMPUTER, INC.
+
+OUI:00502D*
+ ID_OUI_FROM_DATABASE=ACCEL, INC.
+
+OUI:00502E*
+ ID_OUI_FROM_DATABASE=CAMBEX CORPORATION
+
+OUI:00502F*
+ ID_OUI_FROM_DATABASE=TollBridge Technologies, Inc.
+
+OUI:005030*
+ ID_OUI_FROM_DATABASE=FUTURE PLUS SYSTEMS
+
+OUI:005031*
+ ID_OUI_FROM_DATABASE=AEROFLEX LABORATORIES, INC.
+
+OUI:005032*
+ ID_OUI_FROM_DATABASE=PICAZO COMMUNICATIONS, INC.
+
+OUI:005033*
+ ID_OUI_FROM_DATABASE=MAYAN NETWORKS
+
+OUI:005036*
+ ID_OUI_FROM_DATABASE=NETCAM, LTD.
+
+OUI:005037*
+ ID_OUI_FROM_DATABASE=KOGA ELECTRONICS CO.
+
+OUI:005038*
+ ID_OUI_FROM_DATABASE=DAIN TELECOM CO., LTD.
+
+OUI:005039*
+ ID_OUI_FROM_DATABASE=MARINER NETWORKS
+
+OUI:00503A*
+ ID_OUI_FROM_DATABASE=DATONG ELECTRONICS LTD.
+
+OUI:00503B*
+ ID_OUI_FROM_DATABASE=MEDIAFIRE CORPORATION
+
+OUI:00503C*
+ ID_OUI_FROM_DATABASE=TSINGHUA NOVEL ELECTRONICS
+
+OUI:00503E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00503F*
+ ID_OUI_FROM_DATABASE=ANCHOR GAMES
+
+OUI:005040*
+ ID_OUI_FROM_DATABASE=Panasonic Electric Works Co., Ltd.
+
+OUI:005041*
+ ID_OUI_FROM_DATABASE=Coretronic Corporation
+
+OUI:005042*
+ ID_OUI_FROM_DATABASE=SCI MANUFACTURING SINGAPORE PTE, LTD.
+
+OUI:005043*
+ ID_OUI_FROM_DATABASE=MARVELL SEMICONDUCTOR, INC.
+
+OUI:005044*
+ ID_OUI_FROM_DATABASE=ASACA CORPORATION
+
+OUI:005045*
+ ID_OUI_FROM_DATABASE=RIOWORKS SOLUTIONS, INC.
+
+OUI:005046*
+ ID_OUI_FROM_DATABASE=MENICX INTERNATIONAL CO., LTD.
+
+OUI:005048*
+ ID_OUI_FROM_DATABASE=INFOLIBRIA
+
+OUI:005049*
+ ID_OUI_FROM_DATABASE=Arbor Networks Inc
+
+OUI:00504A*
+ ID_OUI_FROM_DATABASE=ELTECO A.S.
+
+OUI:00504B*
+ ID_OUI_FROM_DATABASE=BARCONET N.V.
+
+OUI:00504C*
+ ID_OUI_FROM_DATABASE=Galil Motion Control
+
+OUI:00504D*
+ ID_OUI_FROM_DATABASE=Tokyo Electron Device Limited
+
+OUI:00504E*
+ ID_OUI_FROM_DATABASE=SIERRA MONITOR CORP.
+
+OUI:00504F*
+ ID_OUI_FROM_DATABASE=OLENCOM ELECTRONICS
+
+OUI:005050*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:005051*
+ ID_OUI_FROM_DATABASE=IWATSU ELECTRIC CO., LTD.
+
+OUI:005052*
+ ID_OUI_FROM_DATABASE=TIARA NETWORKS, INC.
+
+OUI:005053*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:005054*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:005055*
+ ID_OUI_FROM_DATABASE=DOMS A/S
+
+OUI:005056*
+ ID_OUI_FROM_DATABASE=VMware, Inc.
+
+OUI:005057*
+ ID_OUI_FROM_DATABASE=BROADBAND ACCESS SYSTEMS
+
+OUI:005058*
+ ID_OUI_FROM_DATABASE=VegaStream Group Limted
+
+OUI:005059*
+ ID_OUI_FROM_DATABASE=iBAHN
+
+OUI:00505A*
+ ID_OUI_FROM_DATABASE=NETWORK ALCHEMY, INC.
+
+OUI:00505B*
+ ID_OUI_FROM_DATABASE=KAWASAKI LSI U.S.A., INC.
+
+OUI:00505C*
+ ID_OUI_FROM_DATABASE=TUNDO CORPORATION
+
+OUI:00505E*
+ ID_OUI_FROM_DATABASE=DIGITEK MICROLOGIC S.A.
+
+OUI:00505F*
+ ID_OUI_FROM_DATABASE=BRAND INNOVATORS
+
+OUI:005060*
+ ID_OUI_FROM_DATABASE=TANDBERG TELECOM AS
+
+OUI:005062*
+ ID_OUI_FROM_DATABASE=KOUWELL ELECTRONICS CORP.  **
+
+OUI:005063*
+ ID_OUI_FROM_DATABASE=OY COMSEL SYSTEM AB
+
+OUI:005064*
+ ID_OUI_FROM_DATABASE=CAE ELECTRONICS
+
+OUI:005065*
+ ID_OUI_FROM_DATABASE=TDK-Lambda Corporation
+
+OUI:005066*
+ ID_OUI_FROM_DATABASE=AtecoM GmbH advanced telecomunication modules
+
+OUI:005067*
+ ID_OUI_FROM_DATABASE=AEROCOMM, INC.
+
+OUI:005068*
+ ID_OUI_FROM_DATABASE=ELECTRONIC INDUSTRIES ASSOCIATION
+
+OUI:005069*
+ ID_OUI_FROM_DATABASE=PixStream Incorporated
+
+OUI:00506A*
+ ID_OUI_FROM_DATABASE=EDEVA, INC.
+
+OUI:00506B*
+ ID_OUI_FROM_DATABASE=SPX-ATEG
+
+OUI:00506C*
+ ID_OUI_FROM_DATABASE=Beijer Electronics Products AB
+
+OUI:00506D*
+ ID_OUI_FROM_DATABASE=VIDEOJET SYSTEMS
+
+OUI:00506E*
+ ID_OUI_FROM_DATABASE=CORDER ENGINEERING CORPORATION
+
+OUI:00506F*
+ ID_OUI_FROM_DATABASE=G-CONNECT
+
+OUI:005070*
+ ID_OUI_FROM_DATABASE=CHAINTECH COMPUTER CO., LTD.
+
+OUI:005071*
+ ID_OUI_FROM_DATABASE=AIWA CO., LTD.
+
+OUI:005072*
+ ID_OUI_FROM_DATABASE=CORVIS CORPORATION
+
+OUI:005073*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:005074*
+ ID_OUI_FROM_DATABASE=ADVANCED HI-TECH CORP.
+
+OUI:005075*
+ ID_OUI_FROM_DATABASE=KESTREL SOLUTIONS
+
+OUI:005076*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:005077*
+ ID_OUI_FROM_DATABASE=PROLIFIC TECHNOLOGY, INC.
+
+OUI:005078*
+ ID_OUI_FROM_DATABASE=MEGATON HOUSE, LTD.
+
+OUI:00507A*
+ ID_OUI_FROM_DATABASE=XPEED, INC.
+
+OUI:00507B*
+ ID_OUI_FROM_DATABASE=MERLOT COMMUNICATIONS
+
+OUI:00507C*
+ ID_OUI_FROM_DATABASE=VIDEOCON AG
+
+OUI:00507D*
+ ID_OUI_FROM_DATABASE=IFP
+
+OUI:00507E*
+ ID_OUI_FROM_DATABASE=NEWER TECHNOLOGY
+
+OUI:00507F*
+ ID_OUI_FROM_DATABASE=DrayTek Corp.
+
+OUI:005080*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:005081*
+ ID_OUI_FROM_DATABASE=MURATA MACHINERY, LTD.
+
+OUI:005082*
+ ID_OUI_FROM_DATABASE=FORESSON CORPORATION
+
+OUI:005083*
+ ID_OUI_FROM_DATABASE=GILBARCO, INC.
+
+OUI:005084*
+ ID_OUI_FROM_DATABASE=ATL PRODUCTS
+
+OUI:005086*
+ ID_OUI_FROM_DATABASE=TELKOM SA, LTD.
+
+OUI:005087*
+ ID_OUI_FROM_DATABASE=TERASAKI ELECTRIC CO., LTD.
+
+OUI:005088*
+ ID_OUI_FROM_DATABASE=AMANO CORPORATION
+
+OUI:005089*
+ ID_OUI_FROM_DATABASE=SAFETY MANAGEMENT SYSTEMS
+
+OUI:00508B*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:00508C*
+ ID_OUI_FROM_DATABASE=RSI SYSTEMS
+
+OUI:00508D*
+ ID_OUI_FROM_DATABASE=ABIT COMPUTER CORPORATION
+
+OUI:00508E*
+ ID_OUI_FROM_DATABASE=OPTIMATION, INC.
+
+OUI:00508F*
+ ID_OUI_FROM_DATABASE=ASITA TECHNOLOGIES INT'L LTD.
+
+OUI:005090*
+ ID_OUI_FROM_DATABASE=DCTRI
+
+OUI:005091*
+ ID_OUI_FROM_DATABASE=NETACCESS, INC.
+
+OUI:005092*
+ ID_OUI_FROM_DATABASE=RIGAKU INDUSTRIAL CORPORATION
+
+OUI:005093*
+ ID_OUI_FROM_DATABASE=BOEING
+
+OUI:005094*
+ ID_OUI_FROM_DATABASE=PACE plc
+
+OUI:005095*
+ ID_OUI_FROM_DATABASE=PERACOM NETWORKS
+
+OUI:005096*
+ ID_OUI_FROM_DATABASE=SALIX TECHNOLOGIES, INC.
+
+OUI:005097*
+ ID_OUI_FROM_DATABASE=MMC-EMBEDDED COMPUTERTECHNIK GmbH
+
+OUI:005098*
+ ID_OUI_FROM_DATABASE=GLOBALOOP, LTD.
+
+OUI:005099*
+ ID_OUI_FROM_DATABASE=3COM EUROPE, LTD.
+
+OUI:00509A*
+ ID_OUI_FROM_DATABASE=TAG ELECTRONIC SYSTEMS
+
+OUI:00509B*
+ ID_OUI_FROM_DATABASE=SWITCHCORE AB
+
+OUI:00509C*
+ ID_OUI_FROM_DATABASE=BETA RESEARCH
+
+OUI:00509D*
+ ID_OUI_FROM_DATABASE=THE INDUSTREE B.V.
+
+OUI:00509E*
+ ID_OUI_FROM_DATABASE=Les Technologies SoftAcoustik Inc.
+
+OUI:00509F*
+ ID_OUI_FROM_DATABASE=HORIZON COMPUTER
+
+OUI:0050A0*
+ ID_OUI_FROM_DATABASE=DELTA COMPUTER SYSTEMS, INC.
+
+OUI:0050A1*
+ ID_OUI_FROM_DATABASE=CARLO GAVAZZI, INC.
+
+OUI:0050A2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0050A3*
+ ID_OUI_FROM_DATABASE=TransMedia Communications, Inc.
+
+OUI:0050A4*
+ ID_OUI_FROM_DATABASE=IO TECH, INC.
+
+OUI:0050A5*
+ ID_OUI_FROM_DATABASE=CAPITOL BUSINESS SYSTEMS, LTD.
+
+OUI:0050A6*
+ ID_OUI_FROM_DATABASE=OPTRONICS
+
+OUI:0050A7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0050A8*
+ ID_OUI_FROM_DATABASE=OpenCon Systems, Inc.
+
+OUI:0050A9*
+ ID_OUI_FROM_DATABASE=MOLDAT WIRELESS TECHNOLGIES
+
+OUI:0050AA*
+ ID_OUI_FROM_DATABASE=KONICA MINOLTA HOLDINGS, INC.
+
+OUI:0050AB*
+ ID_OUI_FROM_DATABASE=NALTEC, Inc.
+
+OUI:0050AC*
+ ID_OUI_FROM_DATABASE=MAPLE COMPUTER CORPORATION
+
+OUI:0050AD*
+ ID_OUI_FROM_DATABASE=CommUnique Wireless Corp.
+
+OUI:0050AE*
+ ID_OUI_FROM_DATABASE=FDK Co., Ltd
+
+OUI:0050AF*
+ ID_OUI_FROM_DATABASE=INTERGON, INC.
+
+OUI:0050B0*
+ ID_OUI_FROM_DATABASE=TECHNOLOGY ATLANTA CORPORATION
+
+OUI:0050B1*
+ ID_OUI_FROM_DATABASE=GIDDINGS & LEWIS
+
+OUI:0050B2*
+ ID_OUI_FROM_DATABASE=BRODEL AUTOMATION
+
+OUI:0050B3*
+ ID_OUI_FROM_DATABASE=VOICEBOARD CORPORATION
+
+OUI:0050B4*
+ ID_OUI_FROM_DATABASE=SATCHWELL CONTROL SYSTEMS, LTD
+
+OUI:0050B5*
+ ID_OUI_FROM_DATABASE=FICHET-BAUCHE
+
+OUI:0050B6*
+ ID_OUI_FROM_DATABASE=GOOD WAY IND. CO., LTD.
+
+OUI:0050B7*
+ ID_OUI_FROM_DATABASE=BOSER TECHNOLOGY CO., LTD.
+
+OUI:0050B8*
+ ID_OUI_FROM_DATABASE=INOVA COMPUTERS GMBH & CO. KG
+
+OUI:0050B9*
+ ID_OUI_FROM_DATABASE=XITRON TECHNOLOGIES, INC.
+
+OUI:0050BA*
+ ID_OUI_FROM_DATABASE=D-LINK
+
+OUI:0050BB*
+ ID_OUI_FROM_DATABASE=CMS TECHNOLOGIES
+
+OUI:0050BC*
+ ID_OUI_FROM_DATABASE=HAMMER STORAGE SOLUTIONS
+
+OUI:0050BD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0050BE*
+ ID_OUI_FROM_DATABASE=FAST MULTIMEDIA AG
+
+OUI:0050BF*
+ ID_OUI_FROM_DATABASE=Metalligence Technology Corp.
+
+OUI:0050C0*
+ ID_OUI_FROM_DATABASE=GATAN, INC.
+
+OUI:0050C1*
+ ID_OUI_FROM_DATABASE=GEMFLEX NETWORKS, LTD.
+
+OUI:0050C4*
+ ID_OUI_FROM_DATABASE=IMD
+
+OUI:0050C5*
+ ID_OUI_FROM_DATABASE=ADS Technologies, Inc
+
+OUI:0050C6*
+ ID_OUI_FROM_DATABASE=LOOP TELECOMMUNICATION INTERNATIONAL, INC.
+
+OUI:0050C8*
+ ID_OUI_FROM_DATABASE=Addonics Technologies, Inc.
+
+OUI:0050C9*
+ ID_OUI_FROM_DATABASE=MASPRO DENKOH CORP.
+
+OUI:0050CA*
+ ID_OUI_FROM_DATABASE=NET TO NET TECHNOLOGIES
+
+OUI:0050CB*
+ ID_OUI_FROM_DATABASE=JETTER
+
+OUI:0050CC*
+ ID_OUI_FROM_DATABASE=XYRATEX
+
+OUI:0050CD*
+ ID_OUI_FROM_DATABASE=DIGIANSWER A/S
+
+OUI:0050CE*
+ ID_OUI_FROM_DATABASE=LG INTERNATIONAL CORP.
+
+OUI:0050CF*
+ ID_OUI_FROM_DATABASE=VANLINK COMMUNICATION TECHNOLOGY RESEARCH INSTITUTE
+
+OUI:0050D0*
+ ID_OUI_FROM_DATABASE=MINERVA SYSTEMS
+
+OUI:0050D1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0050D2*
+ ID_OUI_FROM_DATABASE=CMC Electronics Inc
+
+OUI:0050D3*
+ ID_OUI_FROM_DATABASE=DIGITAL AUDIO PROCESSING PTY. LTD.
+
+OUI:0050D4*
+ ID_OUI_FROM_DATABASE=JOOHONG INFORMATION &
+
+OUI:0050D5*
+ ID_OUI_FROM_DATABASE=AD SYSTEMS CORP.
+
+OUI:0050D6*
+ ID_OUI_FROM_DATABASE=ATLAS COPCO TOOLS AB
+
+OUI:0050D7*
+ ID_OUI_FROM_DATABASE=TELSTRAT
+
+OUI:0050D8*
+ ID_OUI_FROM_DATABASE=UNICORN COMPUTER CORP.
+
+OUI:0050D9*
+ ID_OUI_FROM_DATABASE=ENGETRON-ENGENHARIA ELETRONICA IND. e COM. LTDA
+
+OUI:0050DA*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:0050DB*
+ ID_OUI_FROM_DATABASE=CONTEMPORARY CONTROL
+
+OUI:0050DC*
+ ID_OUI_FROM_DATABASE=TAS TELEFONBAU A. SCHWABE GMBH & CO. KG
+
+OUI:0050DD*
+ ID_OUI_FROM_DATABASE=SERRA SOLDADURA, S.A.
+
+OUI:0050DE*
+ ID_OUI_FROM_DATABASE=SIGNUM SYSTEMS CORP.
+
+OUI:0050DF*
+ ID_OUI_FROM_DATABASE=AirFiber, Inc.
+
+OUI:0050E1*
+ ID_OUI_FROM_DATABASE=NS TECH ELECTRONICS SDN BHD
+
+OUI:0050E2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0050E3*
+ ID_OUI_FROM_DATABASE=Motorola, Inc.
+
+OUI:0050E4*
+ ID_OUI_FROM_DATABASE=APPLE COMPUTER, INC.
+
+OUI:0050E6*
+ ID_OUI_FROM_DATABASE=HAKUSAN CORPORATION
+
+OUI:0050E7*
+ ID_OUI_FROM_DATABASE=PARADISE INNOVATIONS (ASIA)
+
+OUI:0050E8*
+ ID_OUI_FROM_DATABASE=NOMADIX INC.
+
+OUI:0050EA*
+ ID_OUI_FROM_DATABASE=XEL COMMUNICATIONS, INC.
+
+OUI:0050EB*
+ ID_OUI_FROM_DATABASE=ALPHA-TOP CORPORATION
+
+OUI:0050EC*
+ ID_OUI_FROM_DATABASE=OLICOM A/S
+
+OUI:0050ED*
+ ID_OUI_FROM_DATABASE=ANDA NETWORKS
+
+OUI:0050EE*
+ ID_OUI_FROM_DATABASE=TEK DIGITEL CORPORATION
+
+OUI:0050EF*
+ ID_OUI_FROM_DATABASE=SPE Systemhaus GmbH
+
+OUI:0050F0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0050F1*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:0050F2*
+ ID_OUI_FROM_DATABASE=MICROSOFT CORP.
+
+OUI:0050F3*
+ ID_OUI_FROM_DATABASE=GLOBAL NET INFORMATION CO., Ltd.
+
+OUI:0050F4*
+ ID_OUI_FROM_DATABASE=SIGMATEK GMBH & CO. KG
+
+OUI:0050F6*
+ ID_OUI_FROM_DATABASE=PAN-INTERNATIONAL INDUSTRIAL CORP.
+
+OUI:0050F7*
+ ID_OUI_FROM_DATABASE=VENTURE MANUFACTURING (SINGAPORE) LTD.
+
+OUI:0050F8*
+ ID_OUI_FROM_DATABASE=ENTREGA TECHNOLOGIES, INC.
+
+OUI:0050F9*
+ ID_OUI_FROM_DATABASE=SENSORMATIC ACD
+
+OUI:0050FA*
+ ID_OUI_FROM_DATABASE=OXTEL, LTD.
+
+OUI:0050FB*
+ ID_OUI_FROM_DATABASE=VSK ELECTRONICS
+
+OUI:0050FC*
+ ID_OUI_FROM_DATABASE=EDIMAX TECHNOLOGY CO., LTD.
+
+OUI:0050FD*
+ ID_OUI_FROM_DATABASE=VISIONCOMM CO., LTD.
+
+OUI:0050FE*
+ ID_OUI_FROM_DATABASE=PCTVnet ASA
+
+OUI:0050FF*
+ ID_OUI_FROM_DATABASE=HAKKO ELECTRONICS CO., LTD.
+
+OUI:005218*
+ ID_OUI_FROM_DATABASE=Wuxi Keboda Electron Co.Ltd
+
+OUI:0054AF*
+ ID_OUI_FROM_DATABASE=Continental Automotive Systems Inc.
+
+OUI:005CB1*
+ ID_OUI_FROM_DATABASE=Gospell DIGITAL TECHNOLOGY CO., LTD
+
+OUI:005D03*
+ ID_OUI_FROM_DATABASE=Xilinx, Inc
+
+OUI:006000*
+ ID_OUI_FROM_DATABASE=XYCOM INC.
+
+OUI:006001*
+ ID_OUI_FROM_DATABASE=InnoSys, Inc.
+
+OUI:006002*
+ ID_OUI_FROM_DATABASE=SCREEN SUBTITLING SYSTEMS, LTD
+
+OUI:006003*
+ ID_OUI_FROM_DATABASE=TERAOKA WEIGH SYSTEM PTE, LTD.
+
+OUI:006004*
+ ID_OUI_FROM_DATABASE=COMPUTADORES MODULARES SA
+
+OUI:006005*
+ ID_OUI_FROM_DATABASE=FEEDBACK DATA LTD.
+
+OUI:006006*
+ ID_OUI_FROM_DATABASE=SOTEC CO., LTD
+
+OUI:006007*
+ ID_OUI_FROM_DATABASE=ACRES GAMING, INC.
+
+OUI:006008*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:006009*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00600A*
+ ID_OUI_FROM_DATABASE=SORD COMPUTER CORPORATION
+
+OUI:00600B*
+ ID_OUI_FROM_DATABASE=LOGWARE GmbH
+
+OUI:00600C*
+ ID_OUI_FROM_DATABASE=Eurotech Inc.
+
+OUI:00600D*
+ ID_OUI_FROM_DATABASE=Digital Logic GmbH
+
+OUI:00600E*
+ ID_OUI_FROM_DATABASE=WAVENET INTERNATIONAL, INC.
+
+OUI:00600F*
+ ID_OUI_FROM_DATABASE=WESTELL, INC.
+
+OUI:006010*
+ ID_OUI_FROM_DATABASE=NETWORK MACHINES, INC.
+
+OUI:006011*
+ ID_OUI_FROM_DATABASE=CRYSTAL SEMICONDUCTOR CORP.
+
+OUI:006012*
+ ID_OUI_FROM_DATABASE=POWER COMPUTING CORPORATION
+
+OUI:006013*
+ ID_OUI_FROM_DATABASE=NETSTAL MASCHINEN AG
+
+OUI:006014*
+ ID_OUI_FROM_DATABASE=EDEC CO., LTD.
+
+OUI:006015*
+ ID_OUI_FROM_DATABASE=NET2NET CORPORATION
+
+OUI:006016*
+ ID_OUI_FROM_DATABASE=CLARIION
+
+OUI:006017*
+ ID_OUI_FROM_DATABASE=TOKIMEC INC.
+
+OUI:006018*
+ ID_OUI_FROM_DATABASE=STELLAR ONE CORPORATION
+
+OUI:006019*
+ ID_OUI_FROM_DATABASE=Roche Diagnostics
+
+OUI:00601A*
+ ID_OUI_FROM_DATABASE=KEITHLEY INSTRUMENTS
+
+OUI:00601B*
+ ID_OUI_FROM_DATABASE=MESA ELECTRONICS
+
+OUI:00601C*
+ ID_OUI_FROM_DATABASE=TELXON CORPORATION
+
+OUI:00601D*
+ ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES
+
+OUI:00601E*
+ ID_OUI_FROM_DATABASE=SOFTLAB, INC.
+
+OUI:00601F*
+ ID_OUI_FROM_DATABASE=STALLION TECHNOLOGIES
+
+OUI:006020*
+ ID_OUI_FROM_DATABASE=PIVOTAL NETWORKING, INC.
+
+OUI:006021*
+ ID_OUI_FROM_DATABASE=DSC CORPORATION
+
+OUI:006022*
+ ID_OUI_FROM_DATABASE=VICOM SYSTEMS, INC.
+
+OUI:006023*
+ ID_OUI_FROM_DATABASE=PERICOM SEMICONDUCTOR CORP.
+
+OUI:006024*
+ ID_OUI_FROM_DATABASE=GRADIENT TECHNOLOGIES, INC.
+
+OUI:006025*
+ ID_OUI_FROM_DATABASE=ACTIVE IMAGING PLC
+
+OUI:006026*
+ ID_OUI_FROM_DATABASE=VIKING Modular Solutions
+
+OUI:006027*
+ ID_OUI_FROM_DATABASE=Superior Modular Products
+
+OUI:006028*
+ ID_OUI_FROM_DATABASE=MACROVISION CORPORATION
+
+OUI:006029*
+ ID_OUI_FROM_DATABASE=CARY PERIPHERALS INC.
+
+OUI:00602A*
+ ID_OUI_FROM_DATABASE=SYMICRON COMPUTER COMMUNICATIONS, LTD.
+
+OUI:00602B*
+ ID_OUI_FROM_DATABASE=PEAK AUDIO
+
+OUI:00602C*
+ ID_OUI_FROM_DATABASE=LINX Data Terminals, Inc.
+
+OUI:00602D*
+ ID_OUI_FROM_DATABASE=ALERTON TECHNOLOGIES, INC.
+
+OUI:00602E*
+ ID_OUI_FROM_DATABASE=CYCLADES CORPORATION
+
+OUI:00602F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:006030*
+ ID_OUI_FROM_DATABASE=VILLAGE TRONIC ENTWICKLUNG
+
+OUI:006031*
+ ID_OUI_FROM_DATABASE=HRK SYSTEMS
+
+OUI:006032*
+ ID_OUI_FROM_DATABASE=I-CUBE, INC.
+
+OUI:006033*
+ ID_OUI_FROM_DATABASE=ACUITY IMAGING, INC.
+
+OUI:006034*
+ ID_OUI_FROM_DATABASE=ROBERT BOSCH GmbH
+
+OUI:006035*
+ ID_OUI_FROM_DATABASE=DALLAS SEMICONDUCTOR, INC.
+
+OUI:006036*
+ ID_OUI_FROM_DATABASE=AIT Austrian Institute of Technology GmbH
+
+OUI:006037*
+ ID_OUI_FROM_DATABASE=NXP Semiconductors
+
+OUI:006038*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:006039*
+ ID_OUI_FROM_DATABASE=SanCom Technology, Inc.
+
+OUI:00603A*
+ ID_OUI_FROM_DATABASE=QUICK CONTROLS LTD.
+
+OUI:00603B*
+ ID_OUI_FROM_DATABASE=AMTEC spa
+
+OUI:00603C*
+ ID_OUI_FROM_DATABASE=HAGIWARA SYS-COM CO., LTD.
+
+OUI:00603D*
+ ID_OUI_FROM_DATABASE=3CX
+
+OUI:00603E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00603F*
+ ID_OUI_FROM_DATABASE=PATAPSCO DESIGNS
+
+OUI:006040*
+ ID_OUI_FROM_DATABASE=NETRO CORP.
+
+OUI:006041*
+ ID_OUI_FROM_DATABASE=Yokogawa Electric Corporation
+
+OUI:006042*
+ ID_OUI_FROM_DATABASE=TKS (USA), INC.
+
+OUI:006043*
+ ID_OUI_FROM_DATABASE=iDirect, INC.
+
+OUI:006044*
+ ID_OUI_FROM_DATABASE=LITTON/POLY-SCIENTIFIC
+
+OUI:006045*
+ ID_OUI_FROM_DATABASE=PATHLIGHT TECHNOLOGIES
+
+OUI:006046*
+ ID_OUI_FROM_DATABASE=VMETRO, INC.
+
+OUI:006047*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:006048*
+ ID_OUI_FROM_DATABASE=EMC CORPORATION
+
+OUI:006049*
+ ID_OUI_FROM_DATABASE=VINA TECHNOLOGIES
+
+OUI:00604A*
+ ID_OUI_FROM_DATABASE=SAIC IDEAS GROUP
+
+OUI:00604B*
+ ID_OUI_FROM_DATABASE=Safe-com GmbH & Co. KG
+
+OUI:00604C*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:00604D*
+ ID_OUI_FROM_DATABASE=MMC NETWORKS, INC.
+
+OUI:00604E*
+ ID_OUI_FROM_DATABASE=CYCLE COMPUTER CORPORATION, INC.
+
+OUI:00604F*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:006050*
+ ID_OUI_FROM_DATABASE=INTERNIX INC.
+
+OUI:006051*
+ ID_OUI_FROM_DATABASE=QUALITY SEMICONDUCTOR
+
+OUI:006052*
+ ID_OUI_FROM_DATABASE=PERIPHERALS ENTERPRISE CO., Ltd.
+
+OUI:006053*
+ ID_OUI_FROM_DATABASE=TOYODA MACHINE WORKS, LTD.
+
+OUI:006054*
+ ID_OUI_FROM_DATABASE=CONTROLWARE GMBH
+
+OUI:006055*
+ ID_OUI_FROM_DATABASE=CORNELL UNIVERSITY
+
+OUI:006056*
+ ID_OUI_FROM_DATABASE=NETWORK TOOLS, INC.
+
+OUI:006057*
+ ID_OUI_FROM_DATABASE=MURATA MANUFACTURING CO., LTD.
+
+OUI:006058*
+ ID_OUI_FROM_DATABASE=COPPER MOUNTAIN COMMUNICATIONS, INC.
+
+OUI:006059*
+ ID_OUI_FROM_DATABASE=TECHNICAL COMMUNICATIONS CORP.
+
+OUI:00605A*
+ ID_OUI_FROM_DATABASE=CELCORE, INC.
+
+OUI:00605B*
+ ID_OUI_FROM_DATABASE=IntraServer Technology, Inc.
+
+OUI:00605C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00605D*
+ ID_OUI_FROM_DATABASE=SCANIVALVE CORP.
+
+OUI:00605E*
+ ID_OUI_FROM_DATABASE=LIBERTY TECHNOLOGY NETWORKING
+
+OUI:00605F*
+ ID_OUI_FROM_DATABASE=NIPPON UNISOFT CORPORATION
+
+OUI:006060*
+ ID_OUI_FROM_DATABASE=DAWNING TECHNOLOGIES, INC.
+
+OUI:006061*
+ ID_OUI_FROM_DATABASE=WHISTLE COMMUNICATIONS CORP.
+
+OUI:006062*
+ ID_OUI_FROM_DATABASE=TELESYNC, INC.
+
+OUI:006063*
+ ID_OUI_FROM_DATABASE=PSION DACOM PLC.
+
+OUI:006064*
+ ID_OUI_FROM_DATABASE=NETCOMM LIMITED
+
+OUI:006065*
+ ID_OUI_FROM_DATABASE=BERNECKER & RAINER INDUSTRIE-ELEKTRONIC GmbH
+
+OUI:006066*
+ ID_OUI_FROM_DATABASE=LACROIX Trafic
+
+OUI:006067*
+ ID_OUI_FROM_DATABASE=ACER NETXUS INC.
+
+OUI:006068*
+ ID_OUI_FROM_DATABASE=Dialogic Corporation
+
+OUI:006069*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00606A*
+ ID_OUI_FROM_DATABASE=MITSUBISHI WIRELESS COMMUNICATIONS. INC.
+
+OUI:00606B*
+ ID_OUI_FROM_DATABASE=Synclayer Inc.
+
+OUI:00606C*
+ ID_OUI_FROM_DATABASE=ARESCOM
+
+OUI:00606D*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORP.
+
+OUI:00606E*
+ ID_OUI_FROM_DATABASE=DAVICOM SEMICONDUCTOR, INC.
+
+OUI:00606F*
+ ID_OUI_FROM_DATABASE=CLARION CORPORATION OF AMERICA
+
+OUI:006070*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:006071*
+ ID_OUI_FROM_DATABASE=MIDAS LAB, INC.
+
+OUI:006072*
+ ID_OUI_FROM_DATABASE=VXL INSTRUMENTS, LIMITED
+
+OUI:006073*
+ ID_OUI_FROM_DATABASE=REDCREEK COMMUNICATIONS, INC.
+
+OUI:006074*
+ ID_OUI_FROM_DATABASE=QSC AUDIO PRODUCTS
+
+OUI:006075*
+ ID_OUI_FROM_DATABASE=PENTEK, INC.
+
+OUI:006076*
+ ID_OUI_FROM_DATABASE=SCHLUMBERGER TECHNOLOGIES RETAIL PETROLEUM SYSTEMS
+
+OUI:006077*
+ ID_OUI_FROM_DATABASE=PRISA NETWORKS
+
+OUI:006078*
+ ID_OUI_FROM_DATABASE=POWER MEASUREMENT LTD.
+
+OUI:006079*
+ ID_OUI_FROM_DATABASE=Mainstream Data, Inc.
+
+OUI:00607A*
+ ID_OUI_FROM_DATABASE=DVS GmbH
+
+OUI:00607B*
+ ID_OUI_FROM_DATABASE=FORE SYSTEMS, INC.
+
+OUI:00607C*
+ ID_OUI_FROM_DATABASE=WaveAccess, Ltd.
+
+OUI:00607D*
+ ID_OUI_FROM_DATABASE=SENTIENT NETWORKS INC.
+
+OUI:00607E*
+ ID_OUI_FROM_DATABASE=GIGALABS, INC.
+
+OUI:00607F*
+ ID_OUI_FROM_DATABASE=AURORA TECHNOLOGIES, INC.
+
+OUI:006080*
+ ID_OUI_FROM_DATABASE=MICROTRONIX DATACOM LTD.
+
+OUI:006081*
+ ID_OUI_FROM_DATABASE=TV/COM INTERNATIONAL
+
+OUI:006082*
+ ID_OUI_FROM_DATABASE=NOVALINK TECHNOLOGIES, INC.
+
+OUI:006083*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:006084*
+ ID_OUI_FROM_DATABASE=DIGITAL VIDEO
+
+OUI:006085*
+ ID_OUI_FROM_DATABASE=Storage Concepts
+
+OUI:006086*
+ ID_OUI_FROM_DATABASE=LOGIC REPLACEMENT TECH. LTD.
+
+OUI:006087*
+ ID_OUI_FROM_DATABASE=KANSAI ELECTRIC CO., LTD.
+
+OUI:006088*
+ ID_OUI_FROM_DATABASE=WHITE MOUNTAIN DSP, INC.
+
+OUI:006089*
+ ID_OUI_FROM_DATABASE=XATA
+
+OUI:00608A*
+ ID_OUI_FROM_DATABASE=CITADEL COMPUTER
+
+OUI:00608B*
+ ID_OUI_FROM_DATABASE=ConferTech International
+
+OUI:00608C*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:00608D*
+ ID_OUI_FROM_DATABASE=UNIPULSE CORP.
+
+OUI:00608E*
+ ID_OUI_FROM_DATABASE=HE ELECTRONICS, TECHNOLOGIE & SYSTEMTECHNIK GmbH
+
+OUI:00608F*
+ ID_OUI_FROM_DATABASE=TEKRAM TECHNOLOGY CO., LTD.
+
+OUI:006090*
+ ID_OUI_FROM_DATABASE=Artiza Networks Inc
+
+OUI:006091*
+ ID_OUI_FROM_DATABASE=FIRST PACIFIC NETWORKS, INC.
+
+OUI:006092*
+ ID_OUI_FROM_DATABASE=MICRO/SYS, INC.
+
+OUI:006093*
+ ID_OUI_FROM_DATABASE=VARIAN
+
+OUI:006094*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:006095*
+ ID_OUI_FROM_DATABASE=ACCU-TIME SYSTEMS, INC.
+
+OUI:006096*
+ ID_OUI_FROM_DATABASE=T.S. MICROTECH INC.
+
+OUI:006097*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:006098*
+ ID_OUI_FROM_DATABASE=HT COMMUNICATIONS
+
+OUI:006099*
+ ID_OUI_FROM_DATABASE=SBE, Inc.
+
+OUI:00609A*
+ ID_OUI_FROM_DATABASE=NJK TECHNO CO.
+
+OUI:00609B*
+ ID_OUI_FROM_DATABASE=ASTRO-MED, INC.
+
+OUI:00609C*
+ ID_OUI_FROM_DATABASE=Perkin-Elmer Incorporated
+
+OUI:00609D*
+ ID_OUI_FROM_DATABASE=PMI FOOD EQUIPMENT GROUP
+
+OUI:00609E*
+ ID_OUI_FROM_DATABASE=ASC X3 - INFORMATION TECHNOLOGY STANDARDS SECRETARIATS
+
+OUI:00609F*
+ ID_OUI_FROM_DATABASE=PHAST CORPORATION
+
+OUI:0060A0*
+ ID_OUI_FROM_DATABASE=SWITCHED NETWORK TECHNOLOGIES, INC.
+
+OUI:0060A1*
+ ID_OUI_FROM_DATABASE=VPNet, Inc.
+
+OUI:0060A2*
+ ID_OUI_FROM_DATABASE=NIHON UNISYS LIMITED CO.
+
+OUI:0060A3*
+ ID_OUI_FROM_DATABASE=CONTINUUM TECHNOLOGY CORP.
+
+OUI:0060A4*
+ ID_OUI_FROM_DATABASE=GRINAKER SYSTEM TECHNOLOGIES
+
+OUI:0060A5*
+ ID_OUI_FROM_DATABASE=PERFORMANCE TELECOM CORP.
+
+OUI:0060A6*
+ ID_OUI_FROM_DATABASE=PARTICLE MEASURING SYSTEMS
+
+OUI:0060A7*
+ ID_OUI_FROM_DATABASE=MICROSENS GmbH & CO. KG
+
+OUI:0060A8*
+ ID_OUI_FROM_DATABASE=TIDOMAT AB
+
+OUI:0060A9*
+ ID_OUI_FROM_DATABASE=GESYTEC MbH
+
+OUI:0060AA*
+ ID_OUI_FROM_DATABASE=INTELLIGENT DEVICES INC. (IDI)
+
+OUI:0060AB*
+ ID_OUI_FROM_DATABASE=LARSCOM INCORPORATED
+
+OUI:0060AC*
+ ID_OUI_FROM_DATABASE=RESILIENCE CORPORATION
+
+OUI:0060AD*
+ ID_OUI_FROM_DATABASE=MegaChips Corporation
+
+OUI:0060AE*
+ ID_OUI_FROM_DATABASE=TRIO INFORMATION SYSTEMS AB
+
+OUI:0060AF*
+ ID_OUI_FROM_DATABASE=PACIFIC MICRO DATA, INC.
+
+OUI:0060B0*
+ ID_OUI_FROM_DATABASE=HEWLETT-PACKARD CO.
+
+OUI:0060B1*
+ ID_OUI_FROM_DATABASE=INPUT/OUTPUT, INC.
+
+OUI:0060B2*
+ ID_OUI_FROM_DATABASE=PROCESS CONTROL CORP.
+
+OUI:0060B3*
+ ID_OUI_FROM_DATABASE=Z-COM, INC.
+
+OUI:0060B4*
+ ID_OUI_FROM_DATABASE=GLENAYRE R&D INC.
+
+OUI:0060B5*
+ ID_OUI_FROM_DATABASE=KEBA GmbH
+
+OUI:0060B6*
+ ID_OUI_FROM_DATABASE=LAND COMPUTER CO., LTD.
+
+OUI:0060B7*
+ ID_OUI_FROM_DATABASE=CHANNELMATIC, INC.
+
+OUI:0060B8*
+ ID_OUI_FROM_DATABASE=CORELIS Inc.
+
+OUI:0060B9*
+ ID_OUI_FROM_DATABASE=NEC Infrontia Corporation
+
+OUI:0060BA*
+ ID_OUI_FROM_DATABASE=SAHARA NETWORKS, INC.
+
+OUI:0060BB*
+ ID_OUI_FROM_DATABASE=CABLETRON - NETLINK, INC.
+
+OUI:0060BC*
+ ID_OUI_FROM_DATABASE=KeunYoung Electronics & Communication Co., Ltd.
+
+OUI:0060BD*
+ ID_OUI_FROM_DATABASE=HUBBELL-PULSECOM
+
+OUI:0060BE*
+ ID_OUI_FROM_DATABASE=WEBTRONICS
+
+OUI:0060BF*
+ ID_OUI_FROM_DATABASE=MACRAIGOR SYSTEMS, INC.
+
+OUI:0060C0*
+ ID_OUI_FROM_DATABASE=Nera Networks AS
+
+OUI:0060C1*
+ ID_OUI_FROM_DATABASE=WaveSpan Corporation
+
+OUI:0060C2*
+ ID_OUI_FROM_DATABASE=MPL AG
+
+OUI:0060C3*
+ ID_OUI_FROM_DATABASE=NETVISION CORPORATION
+
+OUI:0060C4*
+ ID_OUI_FROM_DATABASE=SOLITON SYSTEMS K.K.
+
+OUI:0060C5*
+ ID_OUI_FROM_DATABASE=ANCOT CORP.
+
+OUI:0060C6*
+ ID_OUI_FROM_DATABASE=DCS AG
+
+OUI:0060C7*
+ ID_OUI_FROM_DATABASE=AMATI COMMUNICATIONS CORP.
+
+OUI:0060C8*
+ ID_OUI_FROM_DATABASE=KUKA WELDING SYSTEMS & ROBOTS
+
+OUI:0060C9*
+ ID_OUI_FROM_DATABASE=ControlNet, Inc.
+
+OUI:0060CA*
+ ID_OUI_FROM_DATABASE=HARMONIC SYSTEMS INCORPORATED
+
+OUI:0060CB*
+ ID_OUI_FROM_DATABASE=HITACHI ZOSEN CORPORATION
+
+OUI:0060CC*
+ ID_OUI_FROM_DATABASE=EMTRAK, INCORPORATED
+
+OUI:0060CD*
+ ID_OUI_FROM_DATABASE=VideoServer, Inc.
+
+OUI:0060CE*
+ ID_OUI_FROM_DATABASE=ACCLAIM COMMUNICATIONS
+
+OUI:0060CF*
+ ID_OUI_FROM_DATABASE=ALTEON NETWORKS, INC.
+
+OUI:0060D0*
+ ID_OUI_FROM_DATABASE=SNMP RESEARCH INCORPORATED
+
+OUI:0060D1*
+ ID_OUI_FROM_DATABASE=CASCADE COMMUNICATIONS
+
+OUI:0060D2*
+ ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES TAIWAN TELECOMMUNICATIONS CO., LTD.
+
+OUI:0060D3*
+ ID_OUI_FROM_DATABASE=AT&T
+
+OUI:0060D4*
+ ID_OUI_FROM_DATABASE=ELDAT COMMUNICATION LTD.
+
+OUI:0060D5*
+ ID_OUI_FROM_DATABASE=MIYACHI TECHNOS CORP.
+
+OUI:0060D6*
+ ID_OUI_FROM_DATABASE=NovAtel Wireless Technologies Ltd.
+
+OUI:0060D7*
+ ID_OUI_FROM_DATABASE=ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (EPFL)
+
+OUI:0060D8*
+ ID_OUI_FROM_DATABASE=ELMIC SYSTEMS, INC.
+
+OUI:0060D9*
+ ID_OUI_FROM_DATABASE=TRANSYS NETWORKS INC.
+
+OUI:0060DA*
+ ID_OUI_FROM_DATABASE=JBM ELECTRONICS CO.
+
+OUI:0060DB*
+ ID_OUI_FROM_DATABASE=NTP ELEKTRONIK A/S
+
+OUI:0060DC*
+ ID_OUI_FROM_DATABASE=Toyo Network Systems  & System Integration Co. LTD
+
+OUI:0060DD*
+ ID_OUI_FROM_DATABASE=MYRICOM, INC.
+
+OUI:0060DE*
+ ID_OUI_FROM_DATABASE=Kayser-Threde GmbH
+
+OUI:0060DF*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:0060E0*
+ ID_OUI_FROM_DATABASE=AXIOM TECHNOLOGY CO., LTD.
+
+OUI:0060E1*
+ ID_OUI_FROM_DATABASE=ORCKIT COMMUNICATIONS LTD.
+
+OUI:0060E2*
+ ID_OUI_FROM_DATABASE=QUEST ENGINEERING & DEVELOPMENT
+
+OUI:0060E3*
+ ID_OUI_FROM_DATABASE=ARBIN INSTRUMENTS
+
+OUI:0060E4*
+ ID_OUI_FROM_DATABASE=COMPUSERVE, INC.
+
+OUI:0060E5*
+ ID_OUI_FROM_DATABASE=FUJI AUTOMATION CO., LTD.
+
+OUI:0060E6*
+ ID_OUI_FROM_DATABASE=SHOMITI SYSTEMS INCORPORATED
+
+OUI:0060E7*
+ ID_OUI_FROM_DATABASE=RANDATA
+
+OUI:0060E8*
+ ID_OUI_FROM_DATABASE=HITACHI COMPUTER PRODUCTS (AMERICA), INC.
+
+OUI:0060E9*
+ ID_OUI_FROM_DATABASE=ATOP TECHNOLOGIES, INC.
+
+OUI:0060EA*
+ ID_OUI_FROM_DATABASE=StreamLogic
+
+OUI:0060EB*
+ ID_OUI_FROM_DATABASE=FOURTHTRACK SYSTEMS
+
+OUI:0060EC*
+ ID_OUI_FROM_DATABASE=HERMARY OPTO ELECTRONICS INC.
+
+OUI:0060ED*
+ ID_OUI_FROM_DATABASE=RICARDO TEST AUTOMATION LTD.
+
+OUI:0060EE*
+ ID_OUI_FROM_DATABASE=APOLLO
+
+OUI:0060EF*
+ ID_OUI_FROM_DATABASE=FLYTECH TECHNOLOGY CO., LTD.
+
+OUI:0060F0*
+ ID_OUI_FROM_DATABASE=JOHNSON & JOHNSON MEDICAL, INC
+
+OUI:0060F1*
+ ID_OUI_FROM_DATABASE=EXP COMPUTER, INC.
+
+OUI:0060F2*
+ ID_OUI_FROM_DATABASE=LASERGRAPHICS, INC.
+
+OUI:0060F3*
+ ID_OUI_FROM_DATABASE=Performance Analysis Broadband, Spirent plc
+
+OUI:0060F4*
+ ID_OUI_FROM_DATABASE=ADVANCED COMPUTER SOLUTIONS, Inc.
+
+OUI:0060F5*
+ ID_OUI_FROM_DATABASE=ICON WEST, INC.
+
+OUI:0060F6*
+ ID_OUI_FROM_DATABASE=NEXTEST COMMUNICATIONS PRODUCTS, INC.
+
+OUI:0060F7*
+ ID_OUI_FROM_DATABASE=DATAFUSION SYSTEMS
+
+OUI:0060F8*
+ ID_OUI_FROM_DATABASE=Loran International Technologies Inc.
+
+OUI:0060F9*
+ ID_OUI_FROM_DATABASE=DIAMOND LANE COMMUNICATIONS
+
+OUI:0060FA*
+ ID_OUI_FROM_DATABASE=EDUCATIONAL TECHNOLOGY RESOURCES, INC.
+
+OUI:0060FB*
+ ID_OUI_FROM_DATABASE=PACKETEER, INC.
+
+OUI:0060FC*
+ ID_OUI_FROM_DATABASE=CONSERVATION THROUGH INNOVATION LTD.
+
+OUI:0060FD*
+ ID_OUI_FROM_DATABASE=NetICs, Inc.
+
+OUI:0060FE*
+ ID_OUI_FROM_DATABASE=LYNX SYSTEM DEVELOPERS, INC.
+
+OUI:0060FF*
+ ID_OUI_FROM_DATABASE=QuVis, Inc.
+
+OUI:006440*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0064A6*
+ ID_OUI_FROM_DATABASE=Maquet CardioVascular
+
+OUI:006B9E*
+ ID_OUI_FROM_DATABASE=VIZIO Inc
+
+OUI:006BA0*
+ ID_OUI_FROM_DATABASE=SHENZHEN UNIVERSAL INTELLISYS PTE LTD
+
+OUI:006DFB*
+ ID_OUI_FROM_DATABASE=Vutrix (UK) Ltd
+
+OUI:0070B0*
+ ID_OUI_FROM_DATABASE=M/A-COM INC. COMPANIES
+
+OUI:0070B3*
+ ID_OUI_FROM_DATABASE=DATA RECALL LTD.
+
+OUI:00789E*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:007F28*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:008000*
+ ID_OUI_FROM_DATABASE=MULTITECH SYSTEMS, INC.
+
+OUI:008001*
+ ID_OUI_FROM_DATABASE=PERIPHONICS CORPORATION
+
+OUI:008002*
+ ID_OUI_FROM_DATABASE=SATELCOM (UK) LTD
+
+OUI:008003*
+ ID_OUI_FROM_DATABASE=HYTEC ELECTRONICS LTD.
+
+OUI:008004*
+ ID_OUI_FROM_DATABASE=ANTLOW COMMUNICATIONS, LTD.
+
+OUI:008005*
+ ID_OUI_FROM_DATABASE=CACTUS COMPUTER INC.
+
+OUI:008006*
+ ID_OUI_FROM_DATABASE=COMPUADD CORPORATION
+
+OUI:008007*
+ ID_OUI_FROM_DATABASE=DLOG NC-SYSTEME
+
+OUI:008008*
+ ID_OUI_FROM_DATABASE=DYNATECH COMPUTER SYSTEMS
+
+OUI:008009*
+ ID_OUI_FROM_DATABASE=JUPITER SYSTEMS, INC.
+
+OUI:00800A*
+ ID_OUI_FROM_DATABASE=JAPAN COMPUTER CORP.
+
+OUI:00800B*
+ ID_OUI_FROM_DATABASE=CSK CORPORATION
+
+OUI:00800C*
+ ID_OUI_FROM_DATABASE=VIDECOM LIMITED
+
+OUI:00800D*
+ ID_OUI_FROM_DATABASE=VOSSWINKEL F.U.
+
+OUI:00800E*
+ ID_OUI_FROM_DATABASE=ATLANTIX CORPORATION
+
+OUI:00800F*
+ ID_OUI_FROM_DATABASE=STANDARD MICROSYSTEMS
+
+OUI:008010*
+ ID_OUI_FROM_DATABASE=COMMODORE INTERNATIONAL
+
+OUI:008011*
+ ID_OUI_FROM_DATABASE=DIGITAL SYSTEMS INT'L. INC.
+
+OUI:008012*
+ ID_OUI_FROM_DATABASE=INTEGRATED MEASUREMENT SYSTEMS
+
+OUI:008013*
+ ID_OUI_FROM_DATABASE=THOMAS-CONRAD CORPORATION
+
+OUI:008014*
+ ID_OUI_FROM_DATABASE=ESPRIT SYSTEMS
+
+OUI:008015*
+ ID_OUI_FROM_DATABASE=SEIKO SYSTEMS, INC.
+
+OUI:008016*
+ ID_OUI_FROM_DATABASE=WANDEL AND GOLTERMANN
+
+OUI:008017*
+ ID_OUI_FROM_DATABASE=PFU LIMITED
+
+OUI:008018*
+ ID_OUI_FROM_DATABASE=KOBE STEEL, LTD.
+
+OUI:008019*
+ ID_OUI_FROM_DATABASE=DAYNA COMMUNICATIONS, INC.
+
+OUI:00801A*
+ ID_OUI_FROM_DATABASE=BELL ATLANTIC
+
+OUI:00801B*
+ ID_OUI_FROM_DATABASE=KODIAK TECHNOLOGY
+
+OUI:00801C*
+ ID_OUI_FROM_DATABASE=NEWPORT SYSTEMS SOLUTIONS
+
+OUI:00801D*
+ ID_OUI_FROM_DATABASE=INTEGRATED INFERENCE MACHINES
+
+OUI:00801E*
+ ID_OUI_FROM_DATABASE=XINETRON, INC.
+
+OUI:00801F*
+ ID_OUI_FROM_DATABASE=KRUPP ATLAS ELECTRONIK GMBH
+
+OUI:008020*
+ ID_OUI_FROM_DATABASE=NETWORK PRODUCTS
+
+OUI:008021*
+ ID_OUI_FROM_DATABASE=Alcatel Canada Inc.
+
+OUI:008022*
+ ID_OUI_FROM_DATABASE=SCAN-OPTICS
+
+OUI:008023*
+ ID_OUI_FROM_DATABASE=INTEGRATED BUSINESS NETWORKS
+
+OUI:008024*
+ ID_OUI_FROM_DATABASE=KALPANA, INC.
+
+OUI:008025*
+ ID_OUI_FROM_DATABASE=STOLLMANN GMBH
+
+OUI:008026*
+ ID_OUI_FROM_DATABASE=NETWORK PRODUCTS CORPORATION
+
+OUI:008027*
+ ID_OUI_FROM_DATABASE=ADAPTIVE SYSTEMS, INC.
+
+OUI:008028*
+ ID_OUI_FROM_DATABASE=TRADPOST (HK) LTD
+
+OUI:008029*
+ ID_OUI_FROM_DATABASE=EAGLE TECHNOLOGY, INC.
+
+OUI:00802A*
+ ID_OUI_FROM_DATABASE=TEST SYSTEMS & SIMULATIONS INC
+
+OUI:00802B*
+ ID_OUI_FROM_DATABASE=INTEGRATED MARKETING CO
+
+OUI:00802C*
+ ID_OUI_FROM_DATABASE=THE SAGE GROUP PLC
+
+OUI:00802D*
+ ID_OUI_FROM_DATABASE=XYLOGICS INC
+
+OUI:00802E*
+ ID_OUI_FROM_DATABASE=CASTLE ROCK COMPUTING
+
+OUI:00802F*
+ ID_OUI_FROM_DATABASE=NATIONAL INSTRUMENTS CORP.
+
+OUI:008030*
+ ID_OUI_FROM_DATABASE=NEXUS ELECTRONICS
+
+OUI:008031*
+ ID_OUI_FROM_DATABASE=BASYS, CORP.
+
+OUI:008032*
+ ID_OUI_FROM_DATABASE=ACCESS CO., LTD.
+
+OUI:008033*
+ ID_OUI_FROM_DATABASE=EMS Aviation, Inc.
+
+OUI:008034*
+ ID_OUI_FROM_DATABASE=SMT GOUPIL
+
+OUI:008035*
+ ID_OUI_FROM_DATABASE=TECHNOLOGY WORKS, INC.
+
+OUI:008036*
+ ID_OUI_FROM_DATABASE=REFLEX MANUFACTURING SYSTEMS
+
+OUI:008037*
+ ID_OUI_FROM_DATABASE=Ericsson Group
+
+OUI:008038*
+ ID_OUI_FROM_DATABASE=DATA RESEARCH & APPLICATIONS
+
+OUI:008039*
+ ID_OUI_FROM_DATABASE=ALCATEL STC AUSTRALIA
+
+OUI:00803A*
+ ID_OUI_FROM_DATABASE=VARITYPER, INC.
+
+OUI:00803B*
+ ID_OUI_FROM_DATABASE=APT COMMUNICATIONS, INC.
+
+OUI:00803C*
+ ID_OUI_FROM_DATABASE=TVS ELECTRONICS LTD
+
+OUI:00803D*
+ ID_OUI_FROM_DATABASE=SURIGIKEN CO.,  LTD.
+
+OUI:00803E*
+ ID_OUI_FROM_DATABASE=SYNERNETICS
+
+OUI:00803F*
+ ID_OUI_FROM_DATABASE=TATUNG COMPANY
+
+OUI:008040*
+ ID_OUI_FROM_DATABASE=JOHN FLUKE MANUFACTURING CO.
+
+OUI:008041*
+ ID_OUI_FROM_DATABASE=VEB KOMBINAT ROBOTRON
+
+OUI:008042*
+ ID_OUI_FROM_DATABASE=Emerson Network Power
+
+OUI:008043*
+ ID_OUI_FROM_DATABASE=NETWORLD, INC.
+
+OUI:008044*
+ ID_OUI_FROM_DATABASE=SYSTECH COMPUTER CORP.
+
+OUI:008045*
+ ID_OUI_FROM_DATABASE=MATSUSHITA ELECTRIC IND. CO
+
+OUI:008046*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:008047*
+ ID_OUI_FROM_DATABASE=IN-NET CORP.
+
+OUI:008048*
+ ID_OUI_FROM_DATABASE=COMPEX INCORPORATED
+
+OUI:008049*
+ ID_OUI_FROM_DATABASE=NISSIN ELECTRIC CO., LTD.
+
+OUI:00804A*
+ ID_OUI_FROM_DATABASE=PRO-LOG
+
+OUI:00804B*
+ ID_OUI_FROM_DATABASE=EAGLE TECHNOLOGIES PTY.LTD.
+
+OUI:00804C*
+ ID_OUI_FROM_DATABASE=CONTEC CO., LTD.
+
+OUI:00804D*
+ ID_OUI_FROM_DATABASE=CYCLONE MICROSYSTEMS, INC.
+
+OUI:00804E*
+ ID_OUI_FROM_DATABASE=APEX COMPUTER COMPANY
+
+OUI:00804F*
+ ID_OUI_FROM_DATABASE=DAIKIN INDUSTRIES, LTD.
+
+OUI:008050*
+ ID_OUI_FROM_DATABASE=ZIATECH CORPORATION
+
+OUI:008051*
+ ID_OUI_FROM_DATABASE=FIBERMUX
+
+OUI:008052*
+ ID_OUI_FROM_DATABASE=TECHNICALLY ELITE CONCEPTS
+
+OUI:008053*
+ ID_OUI_FROM_DATABASE=INTELLICOM, INC.
+
+OUI:008054*
+ ID_OUI_FROM_DATABASE=FRONTIER TECHNOLOGIES CORP.
+
+OUI:008055*
+ ID_OUI_FROM_DATABASE=FERMILAB
+
+OUI:008056*
+ ID_OUI_FROM_DATABASE=SPHINX ELEKTRONIK GMBH
+
+OUI:008057*
+ ID_OUI_FROM_DATABASE=ADSOFT, LTD.
+
+OUI:008058*
+ ID_OUI_FROM_DATABASE=PRINTER SYSTEMS CORPORATION
+
+OUI:008059*
+ ID_OUI_FROM_DATABASE=STANLEY ELECTRIC CO., LTD
+
+OUI:00805A*
+ ID_OUI_FROM_DATABASE=TULIP COMPUTERS INTERNAT'L B.V
+
+OUI:00805B*
+ ID_OUI_FROM_DATABASE=CONDOR SYSTEMS, INC.
+
+OUI:00805C*
+ ID_OUI_FROM_DATABASE=AGILIS CORPORATION
+
+OUI:00805D*
+ ID_OUI_FROM_DATABASE=CANSTAR
+
+OUI:00805E*
+ ID_OUI_FROM_DATABASE=LSI LOGIC CORPORATION
+
+OUI:00805F*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:008060*
+ ID_OUI_FROM_DATABASE=NETWORK INTERFACE CORPORATION
+
+OUI:008061*
+ ID_OUI_FROM_DATABASE=LITTON SYSTEMS, INC.
+
+OUI:008062*
+ ID_OUI_FROM_DATABASE=INTERFACE  CO.
+
+OUI:008063*
+ ID_OUI_FROM_DATABASE=Hirschmann Automation and Control GmbH
+
+OUI:008064*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:008065*
+ ID_OUI_FROM_DATABASE=CYBERGRAPHIC SYSTEMS PTY LTD.
+
+OUI:008066*
+ ID_OUI_FROM_DATABASE=ARCOM CONTROL SYSTEMS, LTD.
+
+OUI:008067*
+ ID_OUI_FROM_DATABASE=SQUARE D COMPANY
+
+OUI:008068*
+ ID_OUI_FROM_DATABASE=YAMATECH SCIENTIFIC LTD.
+
+OUI:008069*
+ ID_OUI_FROM_DATABASE=COMPUTONE SYSTEMS
+
+OUI:00806A*
+ ID_OUI_FROM_DATABASE=ERI (EMPAC RESEARCH INC.)
+
+OUI:00806B*
+ ID_OUI_FROM_DATABASE=SCHMID TELECOMMUNICATION
+
+OUI:00806C*
+ ID_OUI_FROM_DATABASE=CEGELEC PROJECTS LTD
+
+OUI:00806D*
+ ID_OUI_FROM_DATABASE=CENTURY SYSTEMS CORP.
+
+OUI:00806E*
+ ID_OUI_FROM_DATABASE=NIPPON STEEL CORPORATION
+
+OUI:00806F*
+ ID_OUI_FROM_DATABASE=ONELAN LTD.
+
+OUI:008070*
+ ID_OUI_FROM_DATABASE=COMPUTADORAS MICRON
+
+OUI:008071*
+ ID_OUI_FROM_DATABASE=SAI TECHNOLOGY
+
+OUI:008072*
+ ID_OUI_FROM_DATABASE=MICROPLEX SYSTEMS LTD.
+
+OUI:008073*
+ ID_OUI_FROM_DATABASE=DWB ASSOCIATES
+
+OUI:008074*
+ ID_OUI_FROM_DATABASE=FISHER CONTROLS
+
+OUI:008075*
+ ID_OUI_FROM_DATABASE=PARSYTEC GMBH
+
+OUI:008076*
+ ID_OUI_FROM_DATABASE=MCNC
+
+OUI:008077*
+ ID_OUI_FROM_DATABASE=BROTHER INDUSTRIES, LTD.
+
+OUI:008078*
+ ID_OUI_FROM_DATABASE=PRACTICAL PERIPHERALS, INC.
+
+OUI:008079*
+ ID_OUI_FROM_DATABASE=MICROBUS DESIGNS LTD.
+
+OUI:00807A*
+ ID_OUI_FROM_DATABASE=AITECH SYSTEMS LTD.
+
+OUI:00807B*
+ ID_OUI_FROM_DATABASE=ARTEL COMMUNICATIONS CORP.
+
+OUI:00807C*
+ ID_OUI_FROM_DATABASE=FIBERCOM, INC.
+
+OUI:00807D*
+ ID_OUI_FROM_DATABASE=EQUINOX SYSTEMS INC.
+
+OUI:00807E*
+ ID_OUI_FROM_DATABASE=SOUTHERN PACIFIC LTD.
+
+OUI:00807F*
+ ID_OUI_FROM_DATABASE=DY-4 INCORPORATED
+
+OUI:008080*
+ ID_OUI_FROM_DATABASE=DATAMEDIA CORPORATION
+
+OUI:008081*
+ ID_OUI_FROM_DATABASE=KENDALL SQUARE RESEARCH CORP.
+
+OUI:008082*
+ ID_OUI_FROM_DATABASE=PEP MODULAR COMPUTERS GMBH
+
+OUI:008083*
+ ID_OUI_FROM_DATABASE=AMDAHL
+
+OUI:008084*
+ ID_OUI_FROM_DATABASE=THE CLOUD INC.
+
+OUI:008085*
+ ID_OUI_FROM_DATABASE=H-THREE SYSTEMS CORPORATION
+
+OUI:008086*
+ ID_OUI_FROM_DATABASE=COMPUTER GENERATION INC.
+
+OUI:008087*
+ ID_OUI_FROM_DATABASE=OKI ELECTRIC INDUSTRY CO., LTD
+
+OUI:008088*
+ ID_OUI_FROM_DATABASE=VICTOR COMPANY OF JAPAN, LTD.
+
+OUI:008089*
+ ID_OUI_FROM_DATABASE=TECNETICS (PTY) LTD.
+
+OUI:00808A*
+ ID_OUI_FROM_DATABASE=SUMMIT MICROSYSTEMS CORP.
+
+OUI:00808B*
+ ID_OUI_FROM_DATABASE=DACOLL LIMITED
+
+OUI:00808C*
+ ID_OUI_FROM_DATABASE=NetScout Systems, Inc.
+
+OUI:00808D*
+ ID_OUI_FROM_DATABASE=WESTCOAST TECHNOLOGY B.V.
+
+OUI:00808E*
+ ID_OUI_FROM_DATABASE=RADSTONE TECHNOLOGY
+
+OUI:00808F*
+ ID_OUI_FROM_DATABASE=C. ITOH ELECTRONICS, INC.
+
+OUI:008090*
+ ID_OUI_FROM_DATABASE=MICROTEK INTERNATIONAL, INC.
+
+OUI:008091*
+ ID_OUI_FROM_DATABASE=TOKYO ELECTRIC CO.,LTD
+
+OUI:008092*
+ ID_OUI_FROM_DATABASE=Silex Technology, Inc.
+
+OUI:008093*
+ ID_OUI_FROM_DATABASE=XYRON CORPORATION
+
+OUI:008094*
+ ID_OUI_FROM_DATABASE=ALFA LAVAL AUTOMATION AB
+
+OUI:008095*
+ ID_OUI_FROM_DATABASE=BASIC MERTON HANDELSGES.M.B.H.
+
+OUI:008096*
+ ID_OUI_FROM_DATABASE=HUMAN DESIGNED SYSTEMS, INC.
+
+OUI:008097*
+ ID_OUI_FROM_DATABASE=CENTRALP AUTOMATISMES
+
+OUI:008098*
+ ID_OUI_FROM_DATABASE=TDK CORPORATION
+
+OUI:008099*
+ ID_OUI_FROM_DATABASE=Eaton Industries GmbH
+
+OUI:00809A*
+ ID_OUI_FROM_DATABASE=NOVUS NETWORKS LTD
+
+OUI:00809B*
+ ID_OUI_FROM_DATABASE=JUSTSYSTEM CORPORATION
+
+OUI:00809C*
+ ID_OUI_FROM_DATABASE=LUXCOM, INC.
+
+OUI:00809D*
+ ID_OUI_FROM_DATABASE=Commscraft Ltd.
+
+OUI:00809E*
+ ID_OUI_FROM_DATABASE=DATUS GMBH
+
+OUI:00809F*
+ ID_OUI_FROM_DATABASE=ALCATEL BUSINESS SYSTEMS
+
+OUI:0080A0*
+ ID_OUI_FROM_DATABASE=EDISA HEWLETT PACKARD S/A
+
+OUI:0080A1*
+ ID_OUI_FROM_DATABASE=MICROTEST, INC.
+
+OUI:0080A2*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:0080A3*
+ ID_OUI_FROM_DATABASE=Lantronix
+
+OUI:0080A4*
+ ID_OUI_FROM_DATABASE=LIBERTY ELECTRONICS
+
+OUI:0080A5*
+ ID_OUI_FROM_DATABASE=SPEED INTERNATIONAL
+
+OUI:0080A6*
+ ID_OUI_FROM_DATABASE=REPUBLIC TECHNOLOGY, INC.
+
+OUI:0080A7*
+ ID_OUI_FROM_DATABASE=Honeywell International Inc
+
+OUI:0080A8*
+ ID_OUI_FROM_DATABASE=VITACOM CORPORATION
+
+OUI:0080A9*
+ ID_OUI_FROM_DATABASE=CLEARPOINT RESEARCH
+
+OUI:0080AA*
+ ID_OUI_FROM_DATABASE=MAXPEED
+
+OUI:0080AB*
+ ID_OUI_FROM_DATABASE=DUKANE NETWORK INTEGRATION
+
+OUI:0080AC*
+ ID_OUI_FROM_DATABASE=IMLOGIX, DIVISION OF GENESYS
+
+OUI:0080AD*
+ ID_OUI_FROM_DATABASE=CNET TECHNOLOGY, INC.
+
+OUI:0080AE*
+ ID_OUI_FROM_DATABASE=HUGHES NETWORK SYSTEMS
+
+OUI:0080AF*
+ ID_OUI_FROM_DATABASE=ALLUMER CO., LTD.
+
+OUI:0080B0*
+ ID_OUI_FROM_DATABASE=ADVANCED INFORMATION
+
+OUI:0080B1*
+ ID_OUI_FROM_DATABASE=SOFTCOM A/S
+
+OUI:0080B2*
+ ID_OUI_FROM_DATABASE=NETWORK EQUIPMENT TECHNOLOGIES
+
+OUI:0080B3*
+ ID_OUI_FROM_DATABASE=AVAL DATA CORPORATION
+
+OUI:0080B4*
+ ID_OUI_FROM_DATABASE=SOPHIA SYSTEMS
+
+OUI:0080B5*
+ ID_OUI_FROM_DATABASE=UNITED NETWORKS INC.
+
+OUI:0080B6*
+ ID_OUI_FROM_DATABASE=THEMIS COMPUTER
+
+OUI:0080B7*
+ ID_OUI_FROM_DATABASE=STELLAR COMPUTER
+
+OUI:0080B8*
+ ID_OUI_FROM_DATABASE=BUG, INCORPORATED
+
+OUI:0080B9*
+ ID_OUI_FROM_DATABASE=ARCHE TECHNOLIGIES INC.
+
+OUI:0080BA*
+ ID_OUI_FROM_DATABASE=SPECIALIX (ASIA) PTE, LTD
+
+OUI:0080BB*
+ ID_OUI_FROM_DATABASE=HUGHES LAN SYSTEMS
+
+OUI:0080BC*
+ ID_OUI_FROM_DATABASE=HITACHI ENGINEERING CO., LTD
+
+OUI:0080BD*
+ ID_OUI_FROM_DATABASE=THE FURUKAWA ELECTRIC CO., LTD
+
+OUI:0080BE*
+ ID_OUI_FROM_DATABASE=ARIES RESEARCH
+
+OUI:0080BF*
+ ID_OUI_FROM_DATABASE=TAKAOKA ELECTRIC MFG. CO. LTD.
+
+OUI:0080C0*
+ ID_OUI_FROM_DATABASE=PENRIL DATACOMM
+
+OUI:0080C1*
+ ID_OUI_FROM_DATABASE=LANEX CORPORATION
+
+OUI:0080C2*
+ ID_OUI_FROM_DATABASE=IEEE 802.1 COMMITTEE
+
+OUI:0080C3*
+ ID_OUI_FROM_DATABASE=BICC INFORMATION SYSTEMS & SVC
+
+OUI:0080C4*
+ ID_OUI_FROM_DATABASE=DOCUMENT TECHNOLOGIES, INC.
+
+OUI:0080C5*
+ ID_OUI_FROM_DATABASE=NOVELLCO DE MEXICO
+
+OUI:0080C6*
+ ID_OUI_FROM_DATABASE=NATIONAL DATACOMM CORPORATION
+
+OUI:0080C7*
+ ID_OUI_FROM_DATABASE=XIRCOM
+
+OUI:0080C8*
+ ID_OUI_FROM_DATABASE=D-LINK SYSTEMS, INC.
+
+OUI:0080C9*
+ ID_OUI_FROM_DATABASE=ALBERTA MICROELECTRONIC CENTRE
+
+OUI:0080CA*
+ ID_OUI_FROM_DATABASE=NETCOM RESEARCH INCORPORATED
+
+OUI:0080CB*
+ ID_OUI_FROM_DATABASE=FALCO DATA PRODUCTS
+
+OUI:0080CC*
+ ID_OUI_FROM_DATABASE=MICROWAVE BYPASS SYSTEMS
+
+OUI:0080CD*
+ ID_OUI_FROM_DATABASE=MICRONICS COMPUTER, INC.
+
+OUI:0080CE*
+ ID_OUI_FROM_DATABASE=BROADCAST TELEVISION SYSTEMS
+
+OUI:0080CF*
+ ID_OUI_FROM_DATABASE=EMBEDDED PERFORMANCE INC.
+
+OUI:0080D0*
+ ID_OUI_FROM_DATABASE=COMPUTER PERIPHERALS, INC.
+
+OUI:0080D1*
+ ID_OUI_FROM_DATABASE=KIMTRON CORPORATION
+
+OUI:0080D2*
+ ID_OUI_FROM_DATABASE=SHINNIHONDENKO CO., LTD.
+
+OUI:0080D3*
+ ID_OUI_FROM_DATABASE=SHIVA CORP.
+
+OUI:0080D4*
+ ID_OUI_FROM_DATABASE=CHASE RESEARCH LTD.
+
+OUI:0080D5*
+ ID_OUI_FROM_DATABASE=CADRE TECHNOLOGIES
+
+OUI:0080D6*
+ ID_OUI_FROM_DATABASE=NUVOTECH, INC.
+
+OUI:0080D7*
+ ID_OUI_FROM_DATABASE=Fantum Engineering
+
+OUI:0080D8*
+ ID_OUI_FROM_DATABASE=NETWORK PERIPHERALS INC.
+
+OUI:0080D9*
+ ID_OUI_FROM_DATABASE=EMK Elektronik GmbH & Co. KG
+
+OUI:0080DA*
+ ID_OUI_FROM_DATABASE=Bruel & Kjaer Sound & Vibration Measurement A/S
+
+OUI:0080DB*
+ ID_OUI_FROM_DATABASE=GRAPHON CORPORATION
+
+OUI:0080DC*
+ ID_OUI_FROM_DATABASE=PICKER INTERNATIONAL
+
+OUI:0080DD*
+ ID_OUI_FROM_DATABASE=GMX INC/GIMIX
+
+OUI:0080DE*
+ ID_OUI_FROM_DATABASE=GIPSI S.A.
+
+OUI:0080DF*
+ ID_OUI_FROM_DATABASE=ADC CODENOLL TECHNOLOGY CORP.
+
+OUI:0080E0*
+ ID_OUI_FROM_DATABASE=XTP SYSTEMS, INC.
+
+OUI:0080E1*
+ ID_OUI_FROM_DATABASE=STMICROELECTRONICS
+
+OUI:0080E2*
+ ID_OUI_FROM_DATABASE=T.D.I. CO., LTD.
+
+OUI:0080E3*
+ ID_OUI_FROM_DATABASE=CORAL NETWORK CORPORATION
+
+OUI:0080E4*
+ ID_OUI_FROM_DATABASE=NORTHWEST DIGITAL SYSTEMS, INC
+
+OUI:0080E5*
+ ID_OUI_FROM_DATABASE=LSI Logic Corporation
+
+OUI:0080E6*
+ ID_OUI_FROM_DATABASE=PEER NETWORKS, INC.
+
+OUI:0080E7*
+ ID_OUI_FROM_DATABASE=LYNWOOD SCIENTIFIC DEV. LTD.
+
+OUI:0080E8*
+ ID_OUI_FROM_DATABASE=CUMULUS CORPORATIION
+
+OUI:0080E9*
+ ID_OUI_FROM_DATABASE=Madge Ltd.
+
+OUI:0080EA*
+ ID_OUI_FROM_DATABASE=ADVA Optical Networking Ltd.
+
+OUI:0080EB*
+ ID_OUI_FROM_DATABASE=COMPCONTROL B.V.
+
+OUI:0080EC*
+ ID_OUI_FROM_DATABASE=SUPERCOMPUTING SOLUTIONS, INC.
+
+OUI:0080ED*
+ ID_OUI_FROM_DATABASE=IQ TECHNOLOGIES, INC.
+
+OUI:0080EE*
+ ID_OUI_FROM_DATABASE=THOMSON CSF
+
+OUI:0080EF*
+ ID_OUI_FROM_DATABASE=RATIONAL
+
+OUI:0080F0*
+ ID_OUI_FROM_DATABASE=Panasonic Communications Co., Ltd.
+
+OUI:0080F1*
+ ID_OUI_FROM_DATABASE=OPUS SYSTEMS
+
+OUI:0080F2*
+ ID_OUI_FROM_DATABASE=RAYCOM SYSTEMS INC
+
+OUI:0080F3*
+ ID_OUI_FROM_DATABASE=SUN ELECTRONICS CORP.
+
+OUI:0080F4*
+ ID_OUI_FROM_DATABASE=TELEMECANIQUE ELECTRIQUE
+
+OUI:0080F5*
+ ID_OUI_FROM_DATABASE=Quantel Ltd
+
+OUI:0080F6*
+ ID_OUI_FROM_DATABASE=SYNERGY MICROSYSTEMS
+
+OUI:0080F7*
+ ID_OUI_FROM_DATABASE=ZENITH ELECTRONICS
+
+OUI:0080F8*
+ ID_OUI_FROM_DATABASE=MIZAR, INC.
+
+OUI:0080F9*
+ ID_OUI_FROM_DATABASE=HEURIKON CORPORATION
+
+OUI:0080FA*
+ ID_OUI_FROM_DATABASE=RWT GMBH
+
+OUI:0080FB*
+ ID_OUI_FROM_DATABASE=BVM LIMITED
+
+OUI:0080FC*
+ ID_OUI_FROM_DATABASE=AVATAR CORPORATION
+
+OUI:0080FD*
+ ID_OUI_FROM_DATABASE=EXSCEED CORPRATION
+
+OUI:0080FE*
+ ID_OUI_FROM_DATABASE=AZURE TECHNOLOGIES, INC.
+
+OUI:0080FF*
+ ID_OUI_FROM_DATABASE=SOC. DE TELEINFORMATIQUE RTC
+
+OUI:008865*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:008C10*
+ ID_OUI_FROM_DATABASE=Black Box Corp.
+
+OUI:008C54*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:008CFA*
+ ID_OUI_FROM_DATABASE=Inventec Corporation
+
+OUI:008D4E*
+ ID_OUI_FROM_DATABASE=CJSC NII STT
+
+OUI:008DDA*
+ ID_OUI_FROM_DATABASE=Link One Co., Ltd.
+
+OUI:008EF2*
+ ID_OUI_FROM_DATABASE=NETGEAR INC.,
+
+OUI:009000*
+ ID_OUI_FROM_DATABASE=DIAMOND MULTIMEDIA
+
+OUI:009001*
+ ID_OUI_FROM_DATABASE=NISHIMU ELECTRONICS INDUSTRIES CO., LTD.
+
+OUI:009002*
+ ID_OUI_FROM_DATABASE=ALLGON AB
+
+OUI:009003*
+ ID_OUI_FROM_DATABASE=APLIO
+
+OUI:009004*
+ ID_OUI_FROM_DATABASE=3COM EUROPE LTD.
+
+OUI:009005*
+ ID_OUI_FROM_DATABASE=PROTECH SYSTEMS CO., LTD.
+
+OUI:009006*
+ ID_OUI_FROM_DATABASE=HAMAMATSU PHOTONICS K.K.
+
+OUI:009007*
+ ID_OUI_FROM_DATABASE=DOMEX TECHNOLOGY CORP.
+
+OUI:009008*
+ ID_OUI_FROM_DATABASE=HanA Systems Inc.
+
+OUI:009009*
+ ID_OUI_FROM_DATABASE=i Controls, Inc.
+
+OUI:00900A*
+ ID_OUI_FROM_DATABASE=PROTON ELECTRONIC INDUSTRIAL CO., LTD.
+
+OUI:00900B*
+ ID_OUI_FROM_DATABASE=LANNER ELECTRONICS, INC.
+
+OUI:00900C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00900D*
+ ID_OUI_FROM_DATABASE=Overland Storage Inc.
+
+OUI:00900E*
+ ID_OUI_FROM_DATABASE=HANDLINK TECHNOLOGIES, INC.
+
+OUI:00900F*
+ ID_OUI_FROM_DATABASE=KAWASAKI HEAVY INDUSTRIES, LTD
+
+OUI:009010*
+ ID_OUI_FROM_DATABASE=SIMULATION LABORATORIES, INC.
+
+OUI:009011*
+ ID_OUI_FROM_DATABASE=WAVTrace, Inc.
+
+OUI:009012*
+ ID_OUI_FROM_DATABASE=GLOBESPAN SEMICONDUCTOR, INC.
+
+OUI:009013*
+ ID_OUI_FROM_DATABASE=SAMSAN CORP.
+
+OUI:009014*
+ ID_OUI_FROM_DATABASE=ROTORK INSTRUMENTS, LTD.
+
+OUI:009015*
+ ID_OUI_FROM_DATABASE=CENTIGRAM COMMUNICATIONS CORP.
+
+OUI:009016*
+ ID_OUI_FROM_DATABASE=ZAC
+
+OUI:009017*
+ ID_OUI_FROM_DATABASE=Zypcom, Inc
+
+OUI:009018*
+ ID_OUI_FROM_DATABASE=ITO ELECTRIC INDUSTRY CO, LTD.
+
+OUI:009019*
+ ID_OUI_FROM_DATABASE=HERMES ELECTRONICS CO., LTD.
+
+OUI:00901A*
+ ID_OUI_FROM_DATABASE=UNISPHERE SOLUTIONS
+
+OUI:00901B*
+ ID_OUI_FROM_DATABASE=DIGITAL CONTROLS
+
+OUI:00901C*
+ ID_OUI_FROM_DATABASE=mps Software Gmbh
+
+OUI:00901D*
+ ID_OUI_FROM_DATABASE=PEC (NZ) LTD.
+
+OUI:00901E*
+ ID_OUI_FROM_DATABASE=Selesta Ingegneria S.p.A.
+
+OUI:00901F*
+ ID_OUI_FROM_DATABASE=ADTEC PRODUCTIONS, INC.
+
+OUI:009020*
+ ID_OUI_FROM_DATABASE=PHILIPS ANALYTICAL X-RAY B.V.
+
+OUI:009021*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:009022*
+ ID_OUI_FROM_DATABASE=IVEX
+
+OUI:009023*
+ ID_OUI_FROM_DATABASE=ZILOG INC.
+
+OUI:009024*
+ ID_OUI_FROM_DATABASE=PIPELINKS, INC.
+
+OUI:009025*
+ ID_OUI_FROM_DATABASE=BAE Systems Australia (Electronic Systems) Pty Ltd
+
+OUI:009026*
+ ID_OUI_FROM_DATABASE=ADVANCED SWITCHING COMMUNICATIONS, INC.
+
+OUI:009027*
+ ID_OUI_FROM_DATABASE=INTEL CORPORATION
+
+OUI:009028*
+ ID_OUI_FROM_DATABASE=NIPPON SIGNAL CO., LTD.
+
+OUI:009029*
+ ID_OUI_FROM_DATABASE=CRYPTO AG
+
+OUI:00902A*
+ ID_OUI_FROM_DATABASE=COMMUNICATION DEVICES, INC.
+
+OUI:00902B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00902C*
+ ID_OUI_FROM_DATABASE=DATA & CONTROL EQUIPMENT LTD.
+
+OUI:00902D*
+ ID_OUI_FROM_DATABASE=DATA ELECTRONICS (AUST.) PTY, LTD.
+
+OUI:00902E*
+ ID_OUI_FROM_DATABASE=NAMCO LIMITED
+
+OUI:00902F*
+ ID_OUI_FROM_DATABASE=NETCORE SYSTEMS, INC.
+
+OUI:009030*
+ ID_OUI_FROM_DATABASE=HONEYWELL-DATING
+
+OUI:009031*
+ ID_OUI_FROM_DATABASE=MYSTICOM, LTD.
+
+OUI:009032*
+ ID_OUI_FROM_DATABASE=PELCOMBE GROUP LTD.
+
+OUI:009033*
+ ID_OUI_FROM_DATABASE=INNOVAPHONE AG
+
+OUI:009034*
+ ID_OUI_FROM_DATABASE=IMAGIC, INC.
+
+OUI:009035*
+ ID_OUI_FROM_DATABASE=ALPHA TELECOM, INC.
+
+OUI:009036*
+ ID_OUI_FROM_DATABASE=ens, inc.
+
+OUI:009037*
+ ID_OUI_FROM_DATABASE=ACUCOMM, INC.
+
+OUI:009038*
+ ID_OUI_FROM_DATABASE=FOUNTAIN TECHNOLOGIES, INC.
+
+OUI:009039*
+ ID_OUI_FROM_DATABASE=SHASTA NETWORKS
+
+OUI:00903A*
+ ID_OUI_FROM_DATABASE=NIHON MEDIA TOOL INC.
+
+OUI:00903B*
+ ID_OUI_FROM_DATABASE=TriEMS Research Lab, Inc.
+
+OUI:00903C*
+ ID_OUI_FROM_DATABASE=ATLANTIC NETWORK SYSTEMS
+
+OUI:00903D*
+ ID_OUI_FROM_DATABASE=BIOPAC SYSTEMS, INC.
+
+OUI:00903E*
+ ID_OUI_FROM_DATABASE=N.V. PHILIPS INDUSTRIAL ACTIVITIES
+
+OUI:00903F*
+ ID_OUI_FROM_DATABASE=AZTEC RADIOMEDIA
+
+OUI:009040*
+ ID_OUI_FROM_DATABASE=Siemens Network Convergence LLC
+
+OUI:009041*
+ ID_OUI_FROM_DATABASE=APPLIED DIGITAL ACCESS
+
+OUI:009042*
+ ID_OUI_FROM_DATABASE=ECCS, Inc.
+
+OUI:009043*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:009044*
+ ID_OUI_FROM_DATABASE=ASSURED DIGITAL, INC.
+
+OUI:009045*
+ ID_OUI_FROM_DATABASE=Marconi Communications
+
+OUI:009046*
+ ID_OUI_FROM_DATABASE=DEXDYNE, LTD.
+
+OUI:009047*
+ ID_OUI_FROM_DATABASE=GIGA FAST E. LTD.
+
+OUI:009048*
+ ID_OUI_FROM_DATABASE=ZEAL CORPORATION
+
+OUI:009049*
+ ID_OUI_FROM_DATABASE=ENTRIDIA CORPORATION
+
+OUI:00904A*
+ ID_OUI_FROM_DATABASE=CONCUR SYSTEM TECHNOLOGIES
+
+OUI:00904B*
+ ID_OUI_FROM_DATABASE=GemTek Technology Co., Ltd.
+
+OUI:00904C*
+ ID_OUI_FROM_DATABASE=EPIGRAM, INC.
+
+OUI:00904D*
+ ID_OUI_FROM_DATABASE=SPEC S.A.
+
+OUI:00904E*
+ ID_OUI_FROM_DATABASE=DELEM BV
+
+OUI:00904F*
+ ID_OUI_FROM_DATABASE=ABB POWER T&D COMPANY, INC.
+
+OUI:009050*
+ ID_OUI_FROM_DATABASE=TELESTE OY
+
+OUI:009051*
+ ID_OUI_FROM_DATABASE=ULTIMATE TECHNOLOGY CORP.
+
+OUI:009052*
+ ID_OUI_FROM_DATABASE=SELCOM ELETTRONICA S.R.L.
+
+OUI:009053*
+ ID_OUI_FROM_DATABASE=DAEWOO ELECTRONICS CO., LTD.
+
+OUI:009054*
+ ID_OUI_FROM_DATABASE=INNOVATIVE SEMICONDUCTORS, INC
+
+OUI:009055*
+ ID_OUI_FROM_DATABASE=PARKER HANNIFIN CORPORATION COMPUMOTOR DIVISION
+
+OUI:009056*
+ ID_OUI_FROM_DATABASE=TELESTREAM, INC.
+
+OUI:009057*
+ ID_OUI_FROM_DATABASE=AANetcom, Inc.
+
+OUI:009058*
+ ID_OUI_FROM_DATABASE=Ultra Electronics Ltd., Command and Control Systems
+
+OUI:009059*
+ ID_OUI_FROM_DATABASE=TELECOM DEVICE K.K.
+
+OUI:00905A*
+ ID_OUI_FROM_DATABASE=DEARBORN GROUP, INC.
+
+OUI:00905B*
+ ID_OUI_FROM_DATABASE=RAYMOND AND LAE ENGINEERING
+
+OUI:00905C*
+ ID_OUI_FROM_DATABASE=EDMI
+
+OUI:00905D*
+ ID_OUI_FROM_DATABASE=NETCOM SICHERHEITSTECHNIK GmbH
+
+OUI:00905E*
+ ID_OUI_FROM_DATABASE=RAULAND-BORG CORPORATION
+
+OUI:00905F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:009060*
+ ID_OUI_FROM_DATABASE=SYSTEM CREATE CORP.
+
+OUI:009061*
+ ID_OUI_FROM_DATABASE=PACIFIC RESEARCH & ENGINEERING CORPORATION
+
+OUI:009062*
+ ID_OUI_FROM_DATABASE=ICP VORTEX COMPUTERSYSTEME GmbH
+
+OUI:009063*
+ ID_OUI_FROM_DATABASE=COHERENT COMMUNICATIONS SYSTEMS CORPORATION
+
+OUI:009064*
+ ID_OUI_FROM_DATABASE=Thomson Inc.
+
+OUI:009065*
+ ID_OUI_FROM_DATABASE=FINISAR CORPORATION
+
+OUI:009066*
+ ID_OUI_FROM_DATABASE=Troika Networks, Inc.
+
+OUI:009067*
+ ID_OUI_FROM_DATABASE=WalkAbout Computers, Inc.
+
+OUI:009068*
+ ID_OUI_FROM_DATABASE=DVT CORP.
+
+OUI:009069*
+ ID_OUI_FROM_DATABASE=JUNIPER NETWORKS, INC.
+
+OUI:00906A*
+ ID_OUI_FROM_DATABASE=TURNSTONE SYSTEMS, INC.
+
+OUI:00906B*
+ ID_OUI_FROM_DATABASE=APPLIED RESOURCES, INC.
+
+OUI:00906C*
+ ID_OUI_FROM_DATABASE=Sartorius Hamburg GmbH
+
+OUI:00906D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00906E*
+ ID_OUI_FROM_DATABASE=PRAXON, INC.
+
+OUI:00906F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:009070*
+ ID_OUI_FROM_DATABASE=NEO NETWORKS, INC.
+
+OUI:009071*
+ ID_OUI_FROM_DATABASE=Applied Innovation Inc.
+
+OUI:009072*
+ ID_OUI_FROM_DATABASE=SIMRAD AS
+
+OUI:009073*
+ ID_OUI_FROM_DATABASE=GAIO TECHNOLOGY
+
+OUI:009074*
+ ID_OUI_FROM_DATABASE=ARGON NETWORKS, INC.
+
+OUI:009075*
+ ID_OUI_FROM_DATABASE=NEC DO BRASIL S.A.
+
+OUI:009076*
+ ID_OUI_FROM_DATABASE=FMT AIRCRAFT GATE SUPPORT SYSTEMS AB
+
+OUI:009077*
+ ID_OUI_FROM_DATABASE=ADVANCED FIBRE COMMUNICATIONS
+
+OUI:009078*
+ ID_OUI_FROM_DATABASE=MER TELEMANAGEMENT SOLUTIONS, LTD.
+
+OUI:009079*
+ ID_OUI_FROM_DATABASE=ClearOne, Inc.
+
+OUI:00907A*
+ ID_OUI_FROM_DATABASE=Polycom, Inc.
+
+OUI:00907B*
+ ID_OUI_FROM_DATABASE=E-TECH, INC.
+
+OUI:00907C*
+ ID_OUI_FROM_DATABASE=DIGITALCAST, INC.
+
+OUI:00907D*
+ ID_OUI_FROM_DATABASE=Lake Communications
+
+OUI:00907E*
+ ID_OUI_FROM_DATABASE=VETRONIX CORP.
+
+OUI:00907F*
+ ID_OUI_FROM_DATABASE=WatchGuard Technologies, Inc.
+
+OUI:009080*
+ ID_OUI_FROM_DATABASE=NOT LIMITED, INC.
+
+OUI:009081*
+ ID_OUI_FROM_DATABASE=ALOHA NETWORKS, INC.
+
+OUI:009082*
+ ID_OUI_FROM_DATABASE=FORCE INSTITUTE
+
+OUI:009083*
+ ID_OUI_FROM_DATABASE=TURBO COMMUNICATION, INC.
+
+OUI:009084*
+ ID_OUI_FROM_DATABASE=ATECH SYSTEM
+
+OUI:009085*
+ ID_OUI_FROM_DATABASE=GOLDEN ENTERPRISES, INC.
+
+OUI:009086*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:009087*
+ ID_OUI_FROM_DATABASE=ITIS
+
+OUI:009088*
+ ID_OUI_FROM_DATABASE=BAXALL SECURITY LTD.
+
+OUI:009089*
+ ID_OUI_FROM_DATABASE=SOFTCOM MICROSYSTEMS, INC.
+
+OUI:00908A*
+ ID_OUI_FROM_DATABASE=BAYLY COMMUNICATIONS, INC.
+
+OUI:00908B*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:00908C*
+ ID_OUI_FROM_DATABASE=ETREND ELECTRONICS, INC.
+
+OUI:00908D*
+ ID_OUI_FROM_DATABASE=VICKERS ELECTRONICS SYSTEMS
+
+OUI:00908E*
+ ID_OUI_FROM_DATABASE=Nortel Networks Broadband Access
+
+OUI:00908F*
+ ID_OUI_FROM_DATABASE=AUDIO CODES LTD.
+
+OUI:009090*
+ ID_OUI_FROM_DATABASE=I-BUS
+
+OUI:009091*
+ ID_OUI_FROM_DATABASE=DigitalScape, Inc.
+
+OUI:009092*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:009093*
+ ID_OUI_FROM_DATABASE=NANAO CORPORATION
+
+OUI:009094*
+ ID_OUI_FROM_DATABASE=OSPREY TECHNOLOGIES, INC.
+
+OUI:009095*
+ ID_OUI_FROM_DATABASE=UNIVERSAL AVIONICS
+
+OUI:009096*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP.
+
+OUI:009097*
+ ID_OUI_FROM_DATABASE=Sycamore Networks
+
+OUI:009098*
+ ID_OUI_FROM_DATABASE=SBC DESIGNS, INC.
+
+OUI:009099*
+ ID_OUI_FROM_DATABASE=ALLIED TELESIS, K.K.
+
+OUI:00909A*
+ ID_OUI_FROM_DATABASE=ONE WORLD SYSTEMS, INC.
+
+OUI:00909B*
+ ID_OUI_FROM_DATABASE=IMAJE
+
+OUI:00909C*
+ ID_OUI_FROM_DATABASE=Motorola, Inc.
+
+OUI:00909D*
+ ID_OUI_FROM_DATABASE=NovaTech Process Solutions, LLC
+
+OUI:00909E*
+ ID_OUI_FROM_DATABASE=Critical IO, LLC
+
+OUI:00909F*
+ ID_OUI_FROM_DATABASE=DIGI-DATA CORPORATION
+
+OUI:0090A0*
+ ID_OUI_FROM_DATABASE=8X8 INC.
+
+OUI:0090A1*
+ ID_OUI_FROM_DATABASE=Flying Pig Systems/High End Systems Inc.
+
+OUI:0090A2*
+ ID_OUI_FROM_DATABASE=CYBERTAN TECHNOLOGY, INC.
+
+OUI:0090A3*
+ ID_OUI_FROM_DATABASE=Corecess Inc.
+
+OUI:0090A4*
+ ID_OUI_FROM_DATABASE=ALTIGA NETWORKS
+
+OUI:0090A5*
+ ID_OUI_FROM_DATABASE=SPECTRA LOGIC
+
+OUI:0090A6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0090A7*
+ ID_OUI_FROM_DATABASE=CLIENTEC CORPORATION
+
+OUI:0090A8*
+ ID_OUI_FROM_DATABASE=NineTiles Networks, Ltd.
+
+OUI:0090A9*
+ ID_OUI_FROM_DATABASE=WESTERN DIGITAL
+
+OUI:0090AA*
+ ID_OUI_FROM_DATABASE=INDIGO ACTIVE VISION SYSTEMS LIMITED
+
+OUI:0090AB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0090AC*
+ ID_OUI_FROM_DATABASE=OPTIVISION, INC.
+
+OUI:0090AD*
+ ID_OUI_FROM_DATABASE=ASPECT ELECTRONICS, INC.
+
+OUI:0090AE*
+ ID_OUI_FROM_DATABASE=ITALTEL S.p.A.
+
+OUI:0090AF*
+ ID_OUI_FROM_DATABASE=J. MORITA MFG. CORP.
+
+OUI:0090B0*
+ ID_OUI_FROM_DATABASE=VADEM
+
+OUI:0090B1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0090B2*
+ ID_OUI_FROM_DATABASE=AVICI SYSTEMS INC.
+
+OUI:0090B3*
+ ID_OUI_FROM_DATABASE=AGRANAT SYSTEMS
+
+OUI:0090B4*
+ ID_OUI_FROM_DATABASE=WILLOWBROOK TECHNOLOGIES
+
+OUI:0090B5*
+ ID_OUI_FROM_DATABASE=NIKON CORPORATION
+
+OUI:0090B6*
+ ID_OUI_FROM_DATABASE=FIBEX SYSTEMS
+
+OUI:0090B7*
+ ID_OUI_FROM_DATABASE=DIGITAL LIGHTWAVE, INC.
+
+OUI:0090B8*
+ ID_OUI_FROM_DATABASE=ROHDE & SCHWARZ GMBH & CO. KG
+
+OUI:0090B9*
+ ID_OUI_FROM_DATABASE=BERAN INSTRUMENTS LTD.
+
+OUI:0090BA*
+ ID_OUI_FROM_DATABASE=VALID NETWORKS, INC.
+
+OUI:0090BB*
+ ID_OUI_FROM_DATABASE=TAINET COMMUNICATION SYSTEM Corp.
+
+OUI:0090BC*
+ ID_OUI_FROM_DATABASE=TELEMANN CO., LTD.
+
+OUI:0090BD*
+ ID_OUI_FROM_DATABASE=OMNIA COMMUNICATIONS, INC.
+
+OUI:0090BE*
+ ID_OUI_FROM_DATABASE=IBC/INTEGRATED BUSINESS COMPUTERS
+
+OUI:0090BF*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0090C0*
+ ID_OUI_FROM_DATABASE=K.J. LAW ENGINEERS, INC.
+
+OUI:0090C1*
+ ID_OUI_FROM_DATABASE=Peco II, Inc.
+
+OUI:0090C2*
+ ID_OUI_FROM_DATABASE=JK microsystems, Inc.
+
+OUI:0090C3*
+ ID_OUI_FROM_DATABASE=TOPIC SEMICONDUCTOR CORP.
+
+OUI:0090C4*
+ ID_OUI_FROM_DATABASE=JAVELIN SYSTEMS, INC.
+
+OUI:0090C5*
+ ID_OUI_FROM_DATABASE=INTERNET MAGIC, INC.
+
+OUI:0090C6*
+ ID_OUI_FROM_DATABASE=OPTIM SYSTEMS, INC.
+
+OUI:0090C7*
+ ID_OUI_FROM_DATABASE=ICOM INC.
+
+OUI:0090C8*
+ ID_OUI_FROM_DATABASE=WAVERIDER COMMUNICATIONS (CANADA) INC.
+
+OUI:0090C9*
+ ID_OUI_FROM_DATABASE=DPAC Technologies
+
+OUI:0090CA*
+ ID_OUI_FROM_DATABASE=ACCORD VIDEO TELECOMMUNICATIONS, LTD.
+
+OUI:0090CB*
+ ID_OUI_FROM_DATABASE=Wireless OnLine, Inc.
+
+OUI:0090CC*
+ ID_OUI_FROM_DATABASE=Planex Communications
+
+OUI:0090CD*
+ ID_OUI_FROM_DATABASE=ENT-EMPRESA NACIONAL DE TELECOMMUNICACOES, S.A.
+
+OUI:0090CE*
+ ID_OUI_FROM_DATABASE=TETRA GmbH
+
+OUI:0090CF*
+ ID_OUI_FROM_DATABASE=NORTEL
+
+OUI:0090D0*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:0090D1*
+ ID_OUI_FROM_DATABASE=LEICHU ENTERPRISE CO., LTD.
+
+OUI:0090D2*
+ ID_OUI_FROM_DATABASE=ARTEL VIDEO SYSTEMS
+
+OUI:0090D3*
+ ID_OUI_FROM_DATABASE=GIESECKE & DEVRIENT GmbH
+
+OUI:0090D4*
+ ID_OUI_FROM_DATABASE=BindView Development Corp.
+
+OUI:0090D5*
+ ID_OUI_FROM_DATABASE=EUPHONIX, INC.
+
+OUI:0090D6*
+ ID_OUI_FROM_DATABASE=CRYSTAL GROUP
+
+OUI:0090D7*
+ ID_OUI_FROM_DATABASE=NetBoost Corp.
+
+OUI:0090D8*
+ ID_OUI_FROM_DATABASE=WHITECROSS SYSTEMS
+
+OUI:0090D9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0090DA*
+ ID_OUI_FROM_DATABASE=DYNARC, INC.
+
+OUI:0090DB*
+ ID_OUI_FROM_DATABASE=NEXT LEVEL COMMUNICATIONS
+
+OUI:0090DC*
+ ID_OUI_FROM_DATABASE=TECO INFORMATION SYSTEMS
+
+OUI:0090DD*
+ ID_OUI_FROM_DATABASE=THE MIHARU COMMUNICATIONS CO., LTD.
+
+OUI:0090DE*
+ ID_OUI_FROM_DATABASE=CARDKEY SYSTEMS, INC.
+
+OUI:0090DF*
+ ID_OUI_FROM_DATABASE=MITSUBISHI CHEMICAL AMERICA, INC.
+
+OUI:0090E0*
+ ID_OUI_FROM_DATABASE=SYSTRAN CORP.
+
+OUI:0090E1*
+ ID_OUI_FROM_DATABASE=TELENA S.P.A.
+
+OUI:0090E2*
+ ID_OUI_FROM_DATABASE=DISTRIBUTED PROCESSING TECHNOLOGY
+
+OUI:0090E3*
+ ID_OUI_FROM_DATABASE=AVEX ELECTRONICS INC.
+
+OUI:0090E4*
+ ID_OUI_FROM_DATABASE=NEC AMERICA, INC.
+
+OUI:0090E5*
+ ID_OUI_FROM_DATABASE=TEKNEMA, INC.
+
+OUI:0090E6*
+ ID_OUI_FROM_DATABASE=ALi Corporation
+
+OUI:0090E7*
+ ID_OUI_FROM_DATABASE=HORSCH ELEKTRONIK AG
+
+OUI:0090E8*
+ ID_OUI_FROM_DATABASE=MOXA TECHNOLOGIES CORP., LTD.
+
+OUI:0090E9*
+ ID_OUI_FROM_DATABASE=JANZ COMPUTER AG
+
+OUI:0090EA*
+ ID_OUI_FROM_DATABASE=ALPHA TECHNOLOGIES, INC.
+
+OUI:0090EB*
+ ID_OUI_FROM_DATABASE=SENTRY TELECOM SYSTEMS
+
+OUI:0090EC*
+ ID_OUI_FROM_DATABASE=PYRESCOM
+
+OUI:0090ED*
+ ID_OUI_FROM_DATABASE=CENTRAL SYSTEM RESEARCH CO., LTD.
+
+OUI:0090EE*
+ ID_OUI_FROM_DATABASE=PERSONAL COMMUNICATIONS TECHNOLOGIES
+
+OUI:0090EF*
+ ID_OUI_FROM_DATABASE=INTEGRIX, INC.
+
+OUI:0090F0*
+ ID_OUI_FROM_DATABASE=Harmonic Video Systems Ltd.
+
+OUI:0090F1*
+ ID_OUI_FROM_DATABASE=DOT HILL SYSTEMS CORPORATION
+
+OUI:0090F2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0090F3*
+ ID_OUI_FROM_DATABASE=ASPECT COMMUNICATIONS
+
+OUI:0090F4*
+ ID_OUI_FROM_DATABASE=LIGHTNING INSTRUMENTATION
+
+OUI:0090F5*
+ ID_OUI_FROM_DATABASE=CLEVO CO.
+
+OUI:0090F6*
+ ID_OUI_FROM_DATABASE=ESCALATE NETWORKS, INC.
+
+OUI:0090F7*
+ ID_OUI_FROM_DATABASE=NBASE COMMUNICATIONS LTD.
+
+OUI:0090F8*
+ ID_OUI_FROM_DATABASE=MEDIATRIX TELECOM
+
+OUI:0090F9*
+ ID_OUI_FROM_DATABASE=LEITCH
+
+OUI:0090FA*
+ ID_OUI_FROM_DATABASE=EMULEX Corp
+
+OUI:0090FB*
+ ID_OUI_FROM_DATABASE=PORTWELL, INC.
+
+OUI:0090FC*
+ ID_OUI_FROM_DATABASE=NETWORK COMPUTING DEVICES
+
+OUI:0090FD*
+ ID_OUI_FROM_DATABASE=CopperCom, Inc.
+
+OUI:0090FE*
+ ID_OUI_FROM_DATABASE=ELECOM CO., LTD.  (LANEED DIV.)
+
+OUI:0090FF*
+ ID_OUI_FROM_DATABASE=TELLUS TECHNOLOGY INC.
+
+OUI:0091D6*
+ ID_OUI_FROM_DATABASE=Crystal Group, Inc.
+
+OUI:0091FA*
+ ID_OUI_FROM_DATABASE=Synapse Product Development
+
+OUI:009363*
+ ID_OUI_FROM_DATABASE=Uni-Link Technology Co., Ltd.
+
+OUI:009569*
+ ID_OUI_FROM_DATABASE=LSD Science and Technology Co.,Ltd.
+
+OUI:0097FF*
+ ID_OUI_FROM_DATABASE=Heimann Sensor GmbH
+
+OUI:009C02*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:009D8E*
+ ID_OUI_FROM_DATABASE=CARDIAC RECORDERS, INC.
+
+OUI:00A000*
+ ID_OUI_FROM_DATABASE=CENTILLION NETWORKS, INC.
+
+OUI:00A001*
+ ID_OUI_FROM_DATABASE=DRS Signal Solutions
+
+OUI:00A002*
+ ID_OUI_FROM_DATABASE=LEEDS & NORTHRUP AUSTRALIA PTY LTD
+
+OUI:00A003*
+ ID_OUI_FROM_DATABASE=Siemens Switzerland Ltd., I B T HVP
+
+OUI:00A004*
+ ID_OUI_FROM_DATABASE=NETPOWER, INC.
+
+OUI:00A005*
+ ID_OUI_FROM_DATABASE=DANIEL INSTRUMENTS, LTD.
+
+OUI:00A006*
+ ID_OUI_FROM_DATABASE=IMAGE DATA PROCESSING SYSTEM GROUP
+
+OUI:00A007*
+ ID_OUI_FROM_DATABASE=APEXX TECHNOLOGY, INC.
+
+OUI:00A008*
+ ID_OUI_FROM_DATABASE=NETCORP
+
+OUI:00A009*
+ ID_OUI_FROM_DATABASE=WHITETREE NETWORK
+
+OUI:00A00A*
+ ID_OUI_FROM_DATABASE=Airspan
+
+OUI:00A00B*
+ ID_OUI_FROM_DATABASE=COMPUTEX CO., LTD.
+
+OUI:00A00C*
+ ID_OUI_FROM_DATABASE=KINGMAX TECHNOLOGY, INC.
+
+OUI:00A00D*
+ ID_OUI_FROM_DATABASE=THE PANDA PROJECT
+
+OUI:00A00E*
+ ID_OUI_FROM_DATABASE=VISUAL NETWORKS, INC.
+
+OUI:00A00F*
+ ID_OUI_FROM_DATABASE=Broadband Technologies
+
+OUI:00A010*
+ ID_OUI_FROM_DATABASE=SYSLOGIC DATENTECHNIK AG
+
+OUI:00A011*
+ ID_OUI_FROM_DATABASE=MUTOH INDUSTRIES LTD.
+
+OUI:00A012*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:00A013*
+ ID_OUI_FROM_DATABASE=TELTREND LTD.
+
+OUI:00A014*
+ ID_OUI_FROM_DATABASE=CSIR
+
+OUI:00A015*
+ ID_OUI_FROM_DATABASE=WYLE
+
+OUI:00A016*
+ ID_OUI_FROM_DATABASE=MICROPOLIS CORP.
+
+OUI:00A017*
+ ID_OUI_FROM_DATABASE=J B M CORPORATION
+
+OUI:00A018*
+ ID_OUI_FROM_DATABASE=CREATIVE CONTROLLERS, INC.
+
+OUI:00A019*
+ ID_OUI_FROM_DATABASE=NEBULA CONSULTANTS, INC.
+
+OUI:00A01A*
+ ID_OUI_FROM_DATABASE=BINAR ELEKTRONIK AB
+
+OUI:00A01B*
+ ID_OUI_FROM_DATABASE=PREMISYS COMMUNICATIONS, INC.
+
+OUI:00A01C*
+ ID_OUI_FROM_DATABASE=NASCENT NETWORKS CORPORATION
+
+OUI:00A01D*
+ ID_OUI_FROM_DATABASE=SIXNET
+
+OUI:00A01E*
+ ID_OUI_FROM_DATABASE=EST CORPORATION
+
+OUI:00A01F*
+ ID_OUI_FROM_DATABASE=TRICORD SYSTEMS, INC.
+
+OUI:00A020*
+ ID_OUI_FROM_DATABASE=CITICORP/TTI
+
+OUI:00A021*
+ ID_OUI_FROM_DATABASE=General Dynamics
+
+OUI:00A022*
+ ID_OUI_FROM_DATABASE=CENTRE FOR DEVELOPMENT OF ADVANCED COMPUTING
+
+OUI:00A023*
+ ID_OUI_FROM_DATABASE=APPLIED CREATIVE TECHNOLOGY, INC.
+
+OUI:00A024*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:00A025*
+ ID_OUI_FROM_DATABASE=REDCOM LABS INC.
+
+OUI:00A026*
+ ID_OUI_FROM_DATABASE=TELDAT, S.A.
+
+OUI:00A027*
+ ID_OUI_FROM_DATABASE=FIREPOWER SYSTEMS, INC.
+
+OUI:00A028*
+ ID_OUI_FROM_DATABASE=CONNER PERIPHERALS
+
+OUI:00A029*
+ ID_OUI_FROM_DATABASE=COULTER CORPORATION
+
+OUI:00A02A*
+ ID_OUI_FROM_DATABASE=TRANCELL SYSTEMS
+
+OUI:00A02B*
+ ID_OUI_FROM_DATABASE=TRANSITIONS RESEARCH CORP.
+
+OUI:00A02C*
+ ID_OUI_FROM_DATABASE=interWAVE Communications
+
+OUI:00A02D*
+ ID_OUI_FROM_DATABASE=1394 Trade Association
+
+OUI:00A02E*
+ ID_OUI_FROM_DATABASE=BRAND COMMUNICATIONS, LTD.
+
+OUI:00A02F*
+ ID_OUI_FROM_DATABASE=PIRELLI CAVI
+
+OUI:00A030*
+ ID_OUI_FROM_DATABASE=CAPTOR NV/SA
+
+OUI:00A031*
+ ID_OUI_FROM_DATABASE=HAZELTINE CORPORATION, MS 1-17
+
+OUI:00A032*
+ ID_OUI_FROM_DATABASE=GES SINGAPORE PTE. LTD.
+
+OUI:00A033*
+ ID_OUI_FROM_DATABASE=imc MeBsysteme GmbH
+
+OUI:00A034*
+ ID_OUI_FROM_DATABASE=AXEL
+
+OUI:00A035*
+ ID_OUI_FROM_DATABASE=CYLINK CORPORATION
+
+OUI:00A036*
+ ID_OUI_FROM_DATABASE=APPLIED NETWORK TECHNOLOGY
+
+OUI:00A037*
+ ID_OUI_FROM_DATABASE=Mindray DS USA, Inc.
+
+OUI:00A038*
+ ID_OUI_FROM_DATABASE=EMAIL ELECTRONICS
+
+OUI:00A039*
+ ID_OUI_FROM_DATABASE=ROSS TECHNOLOGY, INC.
+
+OUI:00A03A*
+ ID_OUI_FROM_DATABASE=KUBOTEK CORPORATION
+
+OUI:00A03B*
+ ID_OUI_FROM_DATABASE=TOSHIN ELECTRIC CO., LTD.
+
+OUI:00A03C*
+ ID_OUI_FROM_DATABASE=EG&G NUCLEAR INSTRUMENTS
+
+OUI:00A03D*
+ ID_OUI_FROM_DATABASE=OPTO-22
+
+OUI:00A03E*
+ ID_OUI_FROM_DATABASE=ATM FORUM
+
+OUI:00A03F*
+ ID_OUI_FROM_DATABASE=COMPUTER SOCIETY MICROPROCESSOR & MICROPROCESSOR STANDARDS C
+
+OUI:00A040*
+ ID_OUI_FROM_DATABASE=APPLE COMPUTER
+
+OUI:00A041*
+ ID_OUI_FROM_DATABASE=INFICON
+
+OUI:00A042*
+ ID_OUI_FROM_DATABASE=SPUR PRODUCTS CORP.
+
+OUI:00A043*
+ ID_OUI_FROM_DATABASE=AMERICAN TECHNOLOGY LABS, INC.
+
+OUI:00A044*
+ ID_OUI_FROM_DATABASE=NTT IT CO., LTD.
+
+OUI:00A045*
+ ID_OUI_FROM_DATABASE=PHOENIX CONTACT GMBH & CO.
+
+OUI:00A046*
+ ID_OUI_FROM_DATABASE=SCITEX CORP. LTD.
+
+OUI:00A047*
+ ID_OUI_FROM_DATABASE=INTEGRATED FITNESS CORP.
+
+OUI:00A048*
+ ID_OUI_FROM_DATABASE=QUESTECH, LTD.
+
+OUI:00A049*
+ ID_OUI_FROM_DATABASE=DIGITECH INDUSTRIES, INC.
+
+OUI:00A04A*
+ ID_OUI_FROM_DATABASE=NISSHIN ELECTRIC CO., LTD.
+
+OUI:00A04B*
+ ID_OUI_FROM_DATABASE=TFL LAN INC.
+
+OUI:00A04C*
+ ID_OUI_FROM_DATABASE=INNOVATIVE SYSTEMS & TECHNOLOGIES, INC.
+
+OUI:00A04D*
+ ID_OUI_FROM_DATABASE=EDA INSTRUMENTS, INC.
+
+OUI:00A04E*
+ ID_OUI_FROM_DATABASE=VOELKER TECHNOLOGIES, INC.
+
+OUI:00A04F*
+ ID_OUI_FROM_DATABASE=AMERITEC CORP.
+
+OUI:00A050*
+ ID_OUI_FROM_DATABASE=CYPRESS SEMICONDUCTOR
+
+OUI:00A051*
+ ID_OUI_FROM_DATABASE=ANGIA COMMUNICATIONS. INC.
+
+OUI:00A052*
+ ID_OUI_FROM_DATABASE=STANILITE ELECTRONICS PTY. LTD
+
+OUI:00A053*
+ ID_OUI_FROM_DATABASE=COMPACT DEVICES, INC.
+
+OUI:00A055*
+ ID_OUI_FROM_DATABASE=Data Device Corporation
+
+OUI:00A056*
+ ID_OUI_FROM_DATABASE=MICROPROSS
+
+OUI:00A057*
+ ID_OUI_FROM_DATABASE=LANCOM Systems GmbH
+
+OUI:00A058*
+ ID_OUI_FROM_DATABASE=GLORY, LTD.
+
+OUI:00A059*
+ ID_OUI_FROM_DATABASE=HAMILTON HALLMARK
+
+OUI:00A05A*
+ ID_OUI_FROM_DATABASE=KOFAX IMAGE PRODUCTS
+
+OUI:00A05B*
+ ID_OUI_FROM_DATABASE=MARQUIP, INC.
+
+OUI:00A05C*
+ ID_OUI_FROM_DATABASE=INVENTORY CONVERSION, INC./
+
+OUI:00A05D*
+ ID_OUI_FROM_DATABASE=CS COMPUTER SYSTEME GmbH
+
+OUI:00A05E*
+ ID_OUI_FROM_DATABASE=MYRIAD LOGIC INC.
+
+OUI:00A05F*
+ ID_OUI_FROM_DATABASE=BTG Electronics Design BV
+
+OUI:00A060*
+ ID_OUI_FROM_DATABASE=ACER PERIPHERALS, INC.
+
+OUI:00A061*
+ ID_OUI_FROM_DATABASE=PURITAN BENNETT
+
+OUI:00A062*
+ ID_OUI_FROM_DATABASE=AES PRODATA
+
+OUI:00A063*
+ ID_OUI_FROM_DATABASE=JRL SYSTEMS, INC.
+
+OUI:00A064*
+ ID_OUI_FROM_DATABASE=KVB/ANALECT
+
+OUI:00A065*
+ ID_OUI_FROM_DATABASE=Symantec Corporation
+
+OUI:00A066*
+ ID_OUI_FROM_DATABASE=ISA CO., LTD.
+
+OUI:00A067*
+ ID_OUI_FROM_DATABASE=NETWORK SERVICES GROUP
+
+OUI:00A068*
+ ID_OUI_FROM_DATABASE=BHP LIMITED
+
+OUI:00A069*
+ ID_OUI_FROM_DATABASE=Symmetricom, Inc.
+
+OUI:00A06A*
+ ID_OUI_FROM_DATABASE=Verilink Corporation
+
+OUI:00A06B*
+ ID_OUI_FROM_DATABASE=DMS DORSCH MIKROSYSTEM GMBH
+
+OUI:00A06C*
+ ID_OUI_FROM_DATABASE=SHINDENGEN ELECTRIC MFG. CO., LTD.
+
+OUI:00A06D*
+ ID_OUI_FROM_DATABASE=MANNESMANN TALLY CORPORATION
+
+OUI:00A06E*
+ ID_OUI_FROM_DATABASE=AUSTRON, INC.
+
+OUI:00A06F*
+ ID_OUI_FROM_DATABASE=THE APPCON GROUP, INC.
+
+OUI:00A070*
+ ID_OUI_FROM_DATABASE=COASTCOM
+
+OUI:00A071*
+ ID_OUI_FROM_DATABASE=VIDEO LOTTERY TECHNOLOGIES,INC
+
+OUI:00A072*
+ ID_OUI_FROM_DATABASE=OVATION SYSTEMS LTD.
+
+OUI:00A073*
+ ID_OUI_FROM_DATABASE=COM21, INC.
+
+OUI:00A074*
+ ID_OUI_FROM_DATABASE=PERCEPTION TECHNOLOGY
+
+OUI:00A075*
+ ID_OUI_FROM_DATABASE=MICRON TECHNOLOGY, INC.
+
+OUI:00A076*
+ ID_OUI_FROM_DATABASE=CARDWARE LAB, INC.
+
+OUI:00A077*
+ ID_OUI_FROM_DATABASE=FUJITSU NEXION, INC.
+
+OUI:00A078*
+ ID_OUI_FROM_DATABASE=Marconi Communications
+
+OUI:00A079*
+ ID_OUI_FROM_DATABASE=ALPS ELECTRIC (USA), INC.
+
+OUI:00A07A*
+ ID_OUI_FROM_DATABASE=ADVANCED PERIPHERALS TECHNOLOGIES, INC.
+
+OUI:00A07B*
+ ID_OUI_FROM_DATABASE=DAWN COMPUTER INCORPORATION
+
+OUI:00A07C*
+ ID_OUI_FROM_DATABASE=TONYANG NYLON CO., LTD.
+
+OUI:00A07D*
+ ID_OUI_FROM_DATABASE=SEEQ TECHNOLOGY, INC.
+
+OUI:00A07E*
+ ID_OUI_FROM_DATABASE=AVID TECHNOLOGY, INC.
+
+OUI:00A07F*
+ ID_OUI_FROM_DATABASE=GSM-SYNTEL, LTD.
+
+OUI:00A080*
+ ID_OUI_FROM_DATABASE=Tattile SRL
+
+OUI:00A081*
+ ID_OUI_FROM_DATABASE=ALCATEL DATA NETWORKS
+
+OUI:00A082*
+ ID_OUI_FROM_DATABASE=NKT ELEKTRONIK A/S
+
+OUI:00A083*
+ ID_OUI_FROM_DATABASE=ASIMMPHONY TURKEY
+
+OUI:00A084*
+ ID_OUI_FROM_DATABASE=Dataplex Pty Ltd
+
+OUI:00A086*
+ ID_OUI_FROM_DATABASE=AMBER WAVE SYSTEMS, INC.
+
+OUI:00A087*
+ ID_OUI_FROM_DATABASE=Zarlink Semiconductor Ltd.
+
+OUI:00A088*
+ ID_OUI_FROM_DATABASE=ESSENTIAL COMMUNICATIONS
+
+OUI:00A089*
+ ID_OUI_FROM_DATABASE=XPOINT TECHNOLOGIES, INC.
+
+OUI:00A08A*
+ ID_OUI_FROM_DATABASE=BROOKTROUT TECHNOLOGY, INC.
+
+OUI:00A08B*
+ ID_OUI_FROM_DATABASE=ASTON ELECTRONIC DESIGNS LTD.
+
+OUI:00A08C*
+ ID_OUI_FROM_DATABASE=MultiMedia LANs, Inc.
+
+OUI:00A08D*
+ ID_OUI_FROM_DATABASE=JACOMO CORPORATION
+
+OUI:00A08E*
+ ID_OUI_FROM_DATABASE=Check Point Software Technologies
+
+OUI:00A08F*
+ ID_OUI_FROM_DATABASE=DESKNET SYSTEMS, INC.
+
+OUI:00A090*
+ ID_OUI_FROM_DATABASE=TimeStep Corporation
+
+OUI:00A091*
+ ID_OUI_FROM_DATABASE=APPLICOM INTERNATIONAL
+
+OUI:00A092*
+ ID_OUI_FROM_DATABASE=H. BOLLMANN MANUFACTURERS, LTD
+
+OUI:00A093*
+ ID_OUI_FROM_DATABASE=B/E AEROSPACE, Inc.
+
+OUI:00A094*
+ ID_OUI_FROM_DATABASE=COMSAT CORPORATION
+
+OUI:00A095*
+ ID_OUI_FROM_DATABASE=ACACIA NETWORKS, INC.
+
+OUI:00A096*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO., LTD.
+
+OUI:00A097*
+ ID_OUI_FROM_DATABASE=JC INFORMATION SYSTEMS
+
+OUI:00A098*
+ ID_OUI_FROM_DATABASE=NetApp
+
+OUI:00A099*
+ ID_OUI_FROM_DATABASE=K-NET LTD.
+
+OUI:00A09A*
+ ID_OUI_FROM_DATABASE=NIHON KOHDEN AMERICA
+
+OUI:00A09B*
+ ID_OUI_FROM_DATABASE=QPSX COMMUNICATIONS, LTD.
+
+OUI:00A09C*
+ ID_OUI_FROM_DATABASE=Xyplex, Inc.
+
+OUI:00A09D*
+ ID_OUI_FROM_DATABASE=JOHNATHON FREEMAN TECHNOLOGIES
+
+OUI:00A09E*
+ ID_OUI_FROM_DATABASE=ICTV
+
+OUI:00A09F*
+ ID_OUI_FROM_DATABASE=COMMVISION CORP.
+
+OUI:00A0A0*
+ ID_OUI_FROM_DATABASE=COMPACT DATA, LTD.
+
+OUI:00A0A1*
+ ID_OUI_FROM_DATABASE=EPIC DATA INC.
+
+OUI:00A0A2*
+ ID_OUI_FROM_DATABASE=DIGICOM S.P.A.
+
+OUI:00A0A3*
+ ID_OUI_FROM_DATABASE=RELIABLE POWER METERS
+
+OUI:00A0A4*
+ ID_OUI_FROM_DATABASE=MICROS SYSTEMS, INC.
+
+OUI:00A0A5*
+ ID_OUI_FROM_DATABASE=TEKNOR MICROSYSTEME, INC.
+
+OUI:00A0A6*
+ ID_OUI_FROM_DATABASE=M.I. SYSTEMS, K.K.
+
+OUI:00A0A7*
+ ID_OUI_FROM_DATABASE=VORAX CORPORATION
+
+OUI:00A0A8*
+ ID_OUI_FROM_DATABASE=RENEX CORPORATION
+
+OUI:00A0A9*
+ ID_OUI_FROM_DATABASE=NAVTEL COMMUNICATIONS INC.
+
+OUI:00A0AA*
+ ID_OUI_FROM_DATABASE=SPACELABS MEDICAL
+
+OUI:00A0AB*
+ ID_OUI_FROM_DATABASE=NETCS INFORMATIONSTECHNIK GMBH
+
+OUI:00A0AC*
+ ID_OUI_FROM_DATABASE=GILAT SATELLITE NETWORKS, LTD.
+
+OUI:00A0AD*
+ ID_OUI_FROM_DATABASE=MARCONI SPA
+
+OUI:00A0AE*
+ ID_OUI_FROM_DATABASE=NUCOM SYSTEMS, INC.
+
+OUI:00A0AF*
+ ID_OUI_FROM_DATABASE=WMS INDUSTRIES
+
+OUI:00A0B0*
+ ID_OUI_FROM_DATABASE=I-O DATA DEVICE, INC.
+
+OUI:00A0B1*
+ ID_OUI_FROM_DATABASE=FIRST VIRTUAL CORPORATION
+
+OUI:00A0B2*
+ ID_OUI_FROM_DATABASE=SHIMA SEIKI
+
+OUI:00A0B3*
+ ID_OUI_FROM_DATABASE=ZYKRONIX
+
+OUI:00A0B4*
+ ID_OUI_FROM_DATABASE=TEXAS MICROSYSTEMS, INC.
+
+OUI:00A0B5*
+ ID_OUI_FROM_DATABASE=3H TECHNOLOGY
+
+OUI:00A0B6*
+ ID_OUI_FROM_DATABASE=SANRITZ AUTOMATION CO., LTD.
+
+OUI:00A0B7*
+ ID_OUI_FROM_DATABASE=CORDANT, INC.
+
+OUI:00A0B8*
+ ID_OUI_FROM_DATABASE=SYMBIOS LOGIC INC.
+
+OUI:00A0B9*
+ ID_OUI_FROM_DATABASE=EAGLE TECHNOLOGY, INC.
+
+OUI:00A0BA*
+ ID_OUI_FROM_DATABASE=PATTON ELECTRONICS CO.
+
+OUI:00A0BB*
+ ID_OUI_FROM_DATABASE=HILAN GMBH
+
+OUI:00A0BC*
+ ID_OUI_FROM_DATABASE=VIASAT, INCORPORATED
+
+OUI:00A0BD*
+ ID_OUI_FROM_DATABASE=I-TECH CORP.
+
+OUI:00A0BE*
+ ID_OUI_FROM_DATABASE=INTEGRATED CIRCUIT SYSTEMS, INC. COMMUNICATIONS GROUP
+
+OUI:00A0BF*
+ ID_OUI_FROM_DATABASE=WIRELESS DATA GROUP MOTOROLA
+
+OUI:00A0C0*
+ ID_OUI_FROM_DATABASE=DIGITAL LINK CORP.
+
+OUI:00A0C1*
+ ID_OUI_FROM_DATABASE=ORTIVUS MEDICAL AB
+
+OUI:00A0C2*
+ ID_OUI_FROM_DATABASE=R.A. SYSTEMS CO., LTD.
+
+OUI:00A0C3*
+ ID_OUI_FROM_DATABASE=UNICOMPUTER GMBH
+
+OUI:00A0C4*
+ ID_OUI_FROM_DATABASE=CRISTIE ELECTRONICS LTD.
+
+OUI:00A0C5*
+ ID_OUI_FROM_DATABASE=ZYXEL COMMUNICATION
+
+OUI:00A0C6*
+ ID_OUI_FROM_DATABASE=QUALCOMM INCORPORATED
+
+OUI:00A0C7*
+ ID_OUI_FROM_DATABASE=TADIRAN TELECOMMUNICATIONS
+
+OUI:00A0C8*
+ ID_OUI_FROM_DATABASE=ADTRAN INC.
+
+OUI:00A0C9*
+ ID_OUI_FROM_DATABASE=INTEL CORPORATION - HF1-06
+
+OUI:00A0CA*
+ ID_OUI_FROM_DATABASE=FUJITSU DENSO LTD.
+
+OUI:00A0CB*
+ ID_OUI_FROM_DATABASE=ARK TELECOMMUNICATIONS, INC.
+
+OUI:00A0CC*
+ ID_OUI_FROM_DATABASE=LITE-ON COMMUNICATIONS, INC.
+
+OUI:00A0CD*
+ ID_OUI_FROM_DATABASE=DR. JOHANNES HEIDENHAIN GmbH
+
+OUI:00A0CE*
+ ID_OUI_FROM_DATABASE=Ecessa
+
+OUI:00A0CF*
+ ID_OUI_FROM_DATABASE=SOTAS, INC.
+
+OUI:00A0D0*
+ ID_OUI_FROM_DATABASE=TEN X TECHNOLOGY, INC.
+
+OUI:00A0D1*
+ ID_OUI_FROM_DATABASE=INVENTEC CORPORATION
+
+OUI:00A0D2*
+ ID_OUI_FROM_DATABASE=ALLIED TELESIS INTERNATIONAL CORPORATION
+
+OUI:00A0D3*
+ ID_OUI_FROM_DATABASE=INSTEM COMPUTER SYSTEMS, LTD.
+
+OUI:00A0D4*
+ ID_OUI_FROM_DATABASE=RADIOLAN,  INC.
+
+OUI:00A0D5*
+ ID_OUI_FROM_DATABASE=SIERRA WIRELESS INC.
+
+OUI:00A0D6*
+ ID_OUI_FROM_DATABASE=SBE, INC.
+
+OUI:00A0D7*
+ ID_OUI_FROM_DATABASE=KASTEN CHASE APPLIED RESEARCH
+
+OUI:00A0D8*
+ ID_OUI_FROM_DATABASE=SPECTRA - TEK
+
+OUI:00A0D9*
+ ID_OUI_FROM_DATABASE=CONVEX COMPUTER CORPORATION
+
+OUI:00A0DA*
+ ID_OUI_FROM_DATABASE=INTEGRATED SYSTEMS Technology, Inc.
+
+OUI:00A0DB*
+ ID_OUI_FROM_DATABASE=FISHER & PAYKEL PRODUCTION
+
+OUI:00A0DC*
+ ID_OUI_FROM_DATABASE=O.N. ELECTRONIC CO., LTD.
+
+OUI:00A0DD*
+ ID_OUI_FROM_DATABASE=AZONIX CORPORATION
+
+OUI:00A0DE*
+ ID_OUI_FROM_DATABASE=YAMAHA CORPORATION
+
+OUI:00A0DF*
+ ID_OUI_FROM_DATABASE=STS TECHNOLOGIES, INC.
+
+OUI:00A0E0*
+ ID_OUI_FROM_DATABASE=TENNYSON TECHNOLOGIES PTY LTD
+
+OUI:00A0E1*
+ ID_OUI_FROM_DATABASE=WESTPORT RESEARCH ASSOCIATES, INC.
+
+OUI:00A0E2*
+ ID_OUI_FROM_DATABASE=Keisokugiken Corporation
+
+OUI:00A0E3*
+ ID_OUI_FROM_DATABASE=XKL SYSTEMS CORP.
+
+OUI:00A0E4*
+ ID_OUI_FROM_DATABASE=OPTIQUEST
+
+OUI:00A0E5*
+ ID_OUI_FROM_DATABASE=NHC COMMUNICATIONS
+
+OUI:00A0E6*
+ ID_OUI_FROM_DATABASE=DIALOGIC CORPORATION
+
+OUI:00A0E7*
+ ID_OUI_FROM_DATABASE=CENTRAL DATA CORPORATION
+
+OUI:00A0E8*
+ ID_OUI_FROM_DATABASE=REUTERS HOLDINGS PLC
+
+OUI:00A0E9*
+ ID_OUI_FROM_DATABASE=ELECTRONIC RETAILING SYSTEMS INTERNATIONAL
+
+OUI:00A0EA*
+ ID_OUI_FROM_DATABASE=ETHERCOM CORP.
+
+OUI:00A0EB*
+ ID_OUI_FROM_DATABASE=Encore Networks, Inc.
+
+OUI:00A0EC*
+ ID_OUI_FROM_DATABASE=TRANSMITTON LTD.
+
+OUI:00A0ED*
+ ID_OUI_FROM_DATABASE=Brooks Automation, Inc.
+
+OUI:00A0EE*
+ ID_OUI_FROM_DATABASE=NASHOBA NETWORKS
+
+OUI:00A0EF*
+ ID_OUI_FROM_DATABASE=LUCIDATA LTD.
+
+OUI:00A0F0*
+ ID_OUI_FROM_DATABASE=TORONTO MICROELECTRONICS INC.
+
+OUI:00A0F1*
+ ID_OUI_FROM_DATABASE=MTI
+
+OUI:00A0F2*
+ ID_OUI_FROM_DATABASE=INFOTEK COMMUNICATIONS, INC.
+
+OUI:00A0F3*
+ ID_OUI_FROM_DATABASE=STAUBLI
+
+OUI:00A0F4*
+ ID_OUI_FROM_DATABASE=GE
+
+OUI:00A0F5*
+ ID_OUI_FROM_DATABASE=RADGUARD LTD.
+
+OUI:00A0F6*
+ ID_OUI_FROM_DATABASE=AutoGas Systems Inc.
+
+OUI:00A0F7*
+ ID_OUI_FROM_DATABASE=V.I COMPUTER CORP.
+
+OUI:00A0F8*
+ ID_OUI_FROM_DATABASE=SYMBOL TECHNOLOGIES, INC.
+
+OUI:00A0F9*
+ ID_OUI_FROM_DATABASE=BINTEC COMMUNICATIONS GMBH
+
+OUI:00A0FA*
+ ID_OUI_FROM_DATABASE=Marconi Communication GmbH
+
+OUI:00A0FB*
+ ID_OUI_FROM_DATABASE=TORAY ENGINEERING CO., LTD.
+
+OUI:00A0FC*
+ ID_OUI_FROM_DATABASE=IMAGE SCIENCES, INC.
+
+OUI:00A0FD*
+ ID_OUI_FROM_DATABASE=SCITEX DIGITAL PRINTING, INC.
+
+OUI:00A0FE*
+ ID_OUI_FROM_DATABASE=BOSTON TECHNOLOGY, INC.
+
+OUI:00A0FF*
+ ID_OUI_FROM_DATABASE=TELLABS OPERATIONS, INC.
+
+OUI:00A1DE*
+ ID_OUI_FROM_DATABASE=ShenZhen ShiHua Technology CO.,LTD
+
+OUI:00A2DA*
+ ID_OUI_FROM_DATABASE=INAT GmbH
+
+OUI:00AA00*
+ ID_OUI_FROM_DATABASE=INTEL CORPORATION
+
+OUI:00AA01*
+ ID_OUI_FROM_DATABASE=INTEL CORPORATION
+
+OUI:00AA02*
+ ID_OUI_FROM_DATABASE=INTEL CORPORATION
+
+OUI:00AA3C*
+ ID_OUI_FROM_DATABASE=OLIVETTI TELECOM SPA (OLTECO)
+
+OUI:00AA70*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:00B009*
+ ID_OUI_FROM_DATABASE=Grass Valley Group
+
+OUI:00B017*
+ ID_OUI_FROM_DATABASE=InfoGear Technology Corp.
+
+OUI:00B019*
+ ID_OUI_FROM_DATABASE=UTC CCS
+
+OUI:00B01C*
+ ID_OUI_FROM_DATABASE=Westport Technologies
+
+OUI:00B01E*
+ ID_OUI_FROM_DATABASE=Rantic Labs, Inc.
+
+OUI:00B02A*
+ ID_OUI_FROM_DATABASE=ORSYS GmbH
+
+OUI:00B02D*
+ ID_OUI_FROM_DATABASE=ViaGate Technologies, Inc.
+
+OUI:00B033*
+ ID_OUI_FROM_DATABASE=OAO "Izhevskiy radiozavod"
+
+OUI:00B03B*
+ ID_OUI_FROM_DATABASE=HiQ Networks
+
+OUI:00B048*
+ ID_OUI_FROM_DATABASE=Marconi Communications Inc.
+
+OUI:00B04A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00B052*
+ ID_OUI_FROM_DATABASE=Atheros Communications
+
+OUI:00B064*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00B069*
+ ID_OUI_FROM_DATABASE=Honewell Oy
+
+OUI:00B06D*
+ ID_OUI_FROM_DATABASE=Jones Futurex Inc.
+
+OUI:00B080*
+ ID_OUI_FROM_DATABASE=Mannesmann Ipulsys B.V.
+
+OUI:00B086*
+ ID_OUI_FROM_DATABASE=LocSoft Limited
+
+OUI:00B08E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00B091*
+ ID_OUI_FROM_DATABASE=Transmeta Corp.
+
+OUI:00B094*
+ ID_OUI_FROM_DATABASE=Alaris, Inc.
+
+OUI:00B09A*
+ ID_OUI_FROM_DATABASE=Morrow Technologies Corp.
+
+OUI:00B09D*
+ ID_OUI_FROM_DATABASE=Point Grey Research Inc.
+
+OUI:00B0AC*
+ ID_OUI_FROM_DATABASE=SIAE-Microelettronica S.p.A.
+
+OUI:00B0AE*
+ ID_OUI_FROM_DATABASE=Symmetricom
+
+OUI:00B0B3*
+ ID_OUI_FROM_DATABASE=Xstreamis PLC
+
+OUI:00B0C2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00B0C7*
+ ID_OUI_FROM_DATABASE=Tellabs Operations, Inc.
+
+OUI:00B0CE*
+ ID_OUI_FROM_DATABASE=TECHNOLOGY RESCUE
+
+OUI:00B0D0*
+ ID_OUI_FROM_DATABASE=Dell Computer Corp.
+
+OUI:00B0DB*
+ ID_OUI_FROM_DATABASE=Nextcell, Inc.
+
+OUI:00B0DF*
+ ID_OUI_FROM_DATABASE=Starboard Storage Systems
+
+OUI:00B0E7*
+ ID_OUI_FROM_DATABASE=British Federal Ltd.
+
+OUI:00B0EC*
+ ID_OUI_FROM_DATABASE=EACEM
+
+OUI:00B0EE*
+ ID_OUI_FROM_DATABASE=Ajile Systems, Inc.
+
+OUI:00B0F0*
+ ID_OUI_FROM_DATABASE=CALY NETWORKS
+
+OUI:00B0F5*
+ ID_OUI_FROM_DATABASE=NetWorth Technologies, Inc.
+
+OUI:00B338*
+ ID_OUI_FROM_DATABASE=Kontron Design Manufacturing Services (M) Sdn. Bhd
+
+OUI:00B342*
+ ID_OUI_FROM_DATABASE=MacroSAN Technologies Co., Ltd.
+
+OUI:00B56D*
+ ID_OUI_FROM_DATABASE=David Electronics Co., LTD.
+
+OUI:00B5D6*
+ ID_OUI_FROM_DATABASE=Omnibit Inc.
+
+OUI:00B9F6*
+ ID_OUI_FROM_DATABASE=Shenzhen Super Rich Electronics Co.,Ltd
+
+OUI:00BAC0*
+ ID_OUI_FROM_DATABASE=Biometric Access Company
+
+OUI:00BB01*
+ ID_OUI_FROM_DATABASE=OCTOTHORPE CORP.
+
+OUI:00BB8E*
+ ID_OUI_FROM_DATABASE=HME Co., Ltd.
+
+OUI:00BBF0*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00BD27*
+ ID_OUI_FROM_DATABASE=Exar Corp.
+
+OUI:00BD3A*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:00BF15*
+ ID_OUI_FROM_DATABASE=Genetec Inc.
+
+OUI:00C000*
+ ID_OUI_FROM_DATABASE=LANOPTICS, LTD.
+
+OUI:00C001*
+ ID_OUI_FROM_DATABASE=DIATEK PATIENT MANAGMENT
+
+OUI:00C002*
+ ID_OUI_FROM_DATABASE=SERCOMM CORPORATION
+
+OUI:00C003*
+ ID_OUI_FROM_DATABASE=GLOBALNET COMMUNICATIONS
+
+OUI:00C004*
+ ID_OUI_FROM_DATABASE=JAPAN BUSINESS COMPUTER CO.LTD
+
+OUI:00C005*
+ ID_OUI_FROM_DATABASE=LIVINGSTON ENTERPRISES, INC.
+
+OUI:00C006*
+ ID_OUI_FROM_DATABASE=NIPPON AVIONICS CO., LTD.
+
+OUI:00C007*
+ ID_OUI_FROM_DATABASE=PINNACLE DATA SYSTEMS, INC.
+
+OUI:00C008*
+ ID_OUI_FROM_DATABASE=SECO SRL
+
+OUI:00C009*
+ ID_OUI_FROM_DATABASE=KT TECHNOLOGY (S) PTE LTD
+
+OUI:00C00A*
+ ID_OUI_FROM_DATABASE=MICRO CRAFT
+
+OUI:00C00B*
+ ID_OUI_FROM_DATABASE=NORCONTROL A.S.
+
+OUI:00C00C*
+ ID_OUI_FROM_DATABASE=RELIA TECHNOLGIES
+
+OUI:00C00D*
+ ID_OUI_FROM_DATABASE=ADVANCED LOGIC RESEARCH, INC.
+
+OUI:00C00E*
+ ID_OUI_FROM_DATABASE=PSITECH, INC.
+
+OUI:00C00F*
+ ID_OUI_FROM_DATABASE=QUANTUM SOFTWARE SYSTEMS LTD.
+
+OUI:00C010*
+ ID_OUI_FROM_DATABASE=HIRAKAWA HEWTECH CORP.
+
+OUI:00C011*
+ ID_OUI_FROM_DATABASE=INTERACTIVE COMPUTING DEVICES
+
+OUI:00C012*
+ ID_OUI_FROM_DATABASE=NETSPAN CORPORATION
+
+OUI:00C013*
+ ID_OUI_FROM_DATABASE=NETRIX
+
+OUI:00C014*
+ ID_OUI_FROM_DATABASE=TELEMATICS CALABASAS INT'L,INC
+
+OUI:00C015*
+ ID_OUI_FROM_DATABASE=NEW MEDIA CORPORATION
+
+OUI:00C016*
+ ID_OUI_FROM_DATABASE=ELECTRONIC THEATRE CONTROLS
+
+OUI:00C017*
+ ID_OUI_FROM_DATABASE=Fluke Corporation
+
+OUI:00C018*
+ ID_OUI_FROM_DATABASE=LANART CORPORATION
+
+OUI:00C019*
+ ID_OUI_FROM_DATABASE=LEAP TECHNOLOGY, INC.
+
+OUI:00C01A*
+ ID_OUI_FROM_DATABASE=COROMETRICS MEDICAL SYSTEMS
+
+OUI:00C01B*
+ ID_OUI_FROM_DATABASE=SOCKET COMMUNICATIONS, INC.
+
+OUI:00C01C*
+ ID_OUI_FROM_DATABASE=INTERLINK COMMUNICATIONS LTD.
+
+OUI:00C01D*
+ ID_OUI_FROM_DATABASE=GRAND JUNCTION NETWORKS, INC.
+
+OUI:00C01E*
+ ID_OUI_FROM_DATABASE=LA FRANCAISE DES JEUX
+
+OUI:00C01F*
+ ID_OUI_FROM_DATABASE=S.E.R.C.E.L.
+
+OUI:00C020*
+ ID_OUI_FROM_DATABASE=ARCO ELECTRONIC, CONTROL LTD.
+
+OUI:00C021*
+ ID_OUI_FROM_DATABASE=NETEXPRESS
+
+OUI:00C022*
+ ID_OUI_FROM_DATABASE=LASERMASTER TECHNOLOGIES, INC.
+
+OUI:00C023*
+ ID_OUI_FROM_DATABASE=TUTANKHAMON ELECTRONICS
+
+OUI:00C024*
+ ID_OUI_FROM_DATABASE=EDEN SISTEMAS DE COMPUTACAO SA
+
+OUI:00C025*
+ ID_OUI_FROM_DATABASE=DATAPRODUCTS CORPORATION
+
+OUI:00C026*
+ ID_OUI_FROM_DATABASE=LANS TECHNOLOGY CO., LTD.
+
+OUI:00C027*
+ ID_OUI_FROM_DATABASE=CIPHER SYSTEMS, INC.
+
+OUI:00C028*
+ ID_OUI_FROM_DATABASE=JASCO CORPORATION
+
+OUI:00C029*
+ ID_OUI_FROM_DATABASE=Nexans Deutschland GmbH - ANS
+
+OUI:00C02A*
+ ID_OUI_FROM_DATABASE=OHKURA ELECTRIC CO., LTD.
+
+OUI:00C02B*
+ ID_OUI_FROM_DATABASE=GERLOFF GESELLSCHAFT FUR
+
+OUI:00C02C*
+ ID_OUI_FROM_DATABASE=CENTRUM COMMUNICATIONS, INC.
+
+OUI:00C02D*
+ ID_OUI_FROM_DATABASE=FUJI PHOTO FILM CO., LTD.
+
+OUI:00C02E*
+ ID_OUI_FROM_DATABASE=NETWIZ
+
+OUI:00C02F*
+ ID_OUI_FROM_DATABASE=OKUMA CORPORATION
+
+OUI:00C030*
+ ID_OUI_FROM_DATABASE=INTEGRATED ENGINEERING B. V.
+
+OUI:00C031*
+ ID_OUI_FROM_DATABASE=DESIGN RESEARCH SYSTEMS, INC.
+
+OUI:00C032*
+ ID_OUI_FROM_DATABASE=I-CUBED LIMITED
+
+OUI:00C033*
+ ID_OUI_FROM_DATABASE=TELEBIT COMMUNICATIONS APS
+
+OUI:00C034*
+ ID_OUI_FROM_DATABASE=TRANSACTION NETWORK
+
+OUI:00C035*
+ ID_OUI_FROM_DATABASE=QUINTAR COMPANY
+
+OUI:00C036*
+ ID_OUI_FROM_DATABASE=RAYTECH ELECTRONIC CORP.
+
+OUI:00C037*
+ ID_OUI_FROM_DATABASE=DYNATEM
+
+OUI:00C038*
+ ID_OUI_FROM_DATABASE=RASTER IMAGE PROCESSING SYSTEM
+
+OUI:00C039*
+ ID_OUI_FROM_DATABASE=Teridian Semiconductor Corporation
+
+OUI:00C03A*
+ ID_OUI_FROM_DATABASE=MEN-MIKRO ELEKTRONIK GMBH
+
+OUI:00C03B*
+ ID_OUI_FROM_DATABASE=MULTIACCESS COMPUTING CORP.
+
+OUI:00C03C*
+ ID_OUI_FROM_DATABASE=TOWER TECH S.R.L.
+
+OUI:00C03D*
+ ID_OUI_FROM_DATABASE=WIESEMANN & THEIS GMBH
+
+OUI:00C03E*
+ ID_OUI_FROM_DATABASE=FA. GEBR. HELLER GMBH
+
+OUI:00C03F*
+ ID_OUI_FROM_DATABASE=STORES AUTOMATED SYSTEMS, INC.
+
+OUI:00C040*
+ ID_OUI_FROM_DATABASE=ECCI
+
+OUI:00C041*
+ ID_OUI_FROM_DATABASE=DIGITAL TRANSMISSION SYSTEMS
+
+OUI:00C042*
+ ID_OUI_FROM_DATABASE=DATALUX CORP.
+
+OUI:00C043*
+ ID_OUI_FROM_DATABASE=STRATACOM
+
+OUI:00C044*
+ ID_OUI_FROM_DATABASE=EMCOM CORPORATION
+
+OUI:00C045*
+ ID_OUI_FROM_DATABASE=ISOLATION SYSTEMS, LTD.
+
+OUI:00C046*
+ ID_OUI_FROM_DATABASE=Blue Chip Technology Ltd
+
+OUI:00C047*
+ ID_OUI_FROM_DATABASE=UNIMICRO SYSTEMS, INC.
+
+OUI:00C048*
+ ID_OUI_FROM_DATABASE=BAY TECHNICAL ASSOCIATES
+
+OUI:00C049*
+ ID_OUI_FROM_DATABASE=U.S. ROBOTICS, INC.
+
+OUI:00C04A*
+ ID_OUI_FROM_DATABASE=GROUP 2000 AG
+
+OUI:00C04B*
+ ID_OUI_FROM_DATABASE=CREATIVE MICROSYSTEMS
+
+OUI:00C04C*
+ ID_OUI_FROM_DATABASE=DEPARTMENT OF FOREIGN AFFAIRS
+
+OUI:00C04D*
+ ID_OUI_FROM_DATABASE=MITEC, INC.
+
+OUI:00C04E*
+ ID_OUI_FROM_DATABASE=COMTROL CORPORATION
+
+OUI:00C04F*
+ ID_OUI_FROM_DATABASE=DELL COMPUTER CORPORATION
+
+OUI:00C050*
+ ID_OUI_FROM_DATABASE=TOYO DENKI SEIZO K.K.
+
+OUI:00C051*
+ ID_OUI_FROM_DATABASE=ADVANCED INTEGRATION RESEARCH
+
+OUI:00C052*
+ ID_OUI_FROM_DATABASE=BURR-BROWN
+
+OUI:00C053*
+ ID_OUI_FROM_DATABASE=Aspect Software Inc.
+
+OUI:00C054*
+ ID_OUI_FROM_DATABASE=NETWORK PERIPHERALS, LTD.
+
+OUI:00C055*
+ ID_OUI_FROM_DATABASE=MODULAR COMPUTING TECHNOLOGIES
+
+OUI:00C056*
+ ID_OUI_FROM_DATABASE=SOMELEC
+
+OUI:00C057*
+ ID_OUI_FROM_DATABASE=MYCO ELECTRONICS
+
+OUI:00C058*
+ ID_OUI_FROM_DATABASE=DATAEXPERT CORP.
+
+OUI:00C059*
+ ID_OUI_FROM_DATABASE=DENSO CORPORATION
+
+OUI:00C05A*
+ ID_OUI_FROM_DATABASE=SEMAPHORE COMMUNICATIONS CORP.
+
+OUI:00C05B*
+ ID_OUI_FROM_DATABASE=NETWORKS NORTHWEST, INC.
+
+OUI:00C05C*
+ ID_OUI_FROM_DATABASE=ELONEX PLC
+
+OUI:00C05D*
+ ID_OUI_FROM_DATABASE=L&N TECHNOLOGIES
+
+OUI:00C05E*
+ ID_OUI_FROM_DATABASE=VARI-LITE, INC.
+
+OUI:00C05F*
+ ID_OUI_FROM_DATABASE=FINE-PAL COMPANY LIMITED
+
+OUI:00C060*
+ ID_OUI_FROM_DATABASE=ID SCANDINAVIA AS
+
+OUI:00C061*
+ ID_OUI_FROM_DATABASE=SOLECTEK CORPORATION
+
+OUI:00C062*
+ ID_OUI_FROM_DATABASE=IMPULSE TECHNOLOGY
+
+OUI:00C063*
+ ID_OUI_FROM_DATABASE=MORNING STAR TECHNOLOGIES, INC
+
+OUI:00C064*
+ ID_OUI_FROM_DATABASE=GENERAL DATACOMM IND. INC.
+
+OUI:00C065*
+ ID_OUI_FROM_DATABASE=SCOPE COMMUNICATIONS, INC.
+
+OUI:00C066*
+ ID_OUI_FROM_DATABASE=DOCUPOINT, INC.
+
+OUI:00C067*
+ ID_OUI_FROM_DATABASE=UNITED BARCODE INDUSTRIES
+
+OUI:00C068*
+ ID_OUI_FROM_DATABASE=HME Clear-Com LTD.
+
+OUI:00C069*
+ ID_OUI_FROM_DATABASE=Axxcelera Broadband Wireless
+
+OUI:00C06A*
+ ID_OUI_FROM_DATABASE=ZAHNER-ELEKTRIK GMBH & CO. KG
+
+OUI:00C06B*
+ ID_OUI_FROM_DATABASE=OSI PLUS CORPORATION
+
+OUI:00C06C*
+ ID_OUI_FROM_DATABASE=SVEC COMPUTER CORP.
+
+OUI:00C06D*
+ ID_OUI_FROM_DATABASE=BOCA RESEARCH, INC.
+
+OUI:00C06E*
+ ID_OUI_FROM_DATABASE=HAFT TECHNOLOGY, INC.
+
+OUI:00C06F*
+ ID_OUI_FROM_DATABASE=KOMATSU LTD.
+
+OUI:00C070*
+ ID_OUI_FROM_DATABASE=SECTRA SECURE-TRANSMISSION AB
+
+OUI:00C071*
+ ID_OUI_FROM_DATABASE=AREANEX COMMUNICATIONS, INC.
+
+OUI:00C072*
+ ID_OUI_FROM_DATABASE=KNX LTD.
+
+OUI:00C073*
+ ID_OUI_FROM_DATABASE=XEDIA CORPORATION
+
+OUI:00C074*
+ ID_OUI_FROM_DATABASE=TOYODA AUTOMATIC LOOM
+
+OUI:00C075*
+ ID_OUI_FROM_DATABASE=XANTE CORPORATION
+
+OUI:00C076*
+ ID_OUI_FROM_DATABASE=I-DATA INTERNATIONAL A-S
+
+OUI:00C077*
+ ID_OUI_FROM_DATABASE=DAEWOO TELECOM LTD.
+
+OUI:00C078*
+ ID_OUI_FROM_DATABASE=COMPUTER SYSTEMS ENGINEERING
+
+OUI:00C079*
+ ID_OUI_FROM_DATABASE=FONSYS CO.,LTD.
+
+OUI:00C07A*
+ ID_OUI_FROM_DATABASE=PRIVA B.V.
+
+OUI:00C07B*
+ ID_OUI_FROM_DATABASE=ASCEND COMMUNICATIONS, INC.
+
+OUI:00C07C*
+ ID_OUI_FROM_DATABASE=HIGHTECH INFORMATION
+
+OUI:00C07D*
+ ID_OUI_FROM_DATABASE=RISC DEVELOPMENTS LTD.
+
+OUI:00C07E*
+ ID_OUI_FROM_DATABASE=KUBOTA CORPORATION ELECTRONIC
+
+OUI:00C07F*
+ ID_OUI_FROM_DATABASE=NUPON COMPUTING CORP.
+
+OUI:00C080*
+ ID_OUI_FROM_DATABASE=NETSTAR, INC.
+
+OUI:00C081*
+ ID_OUI_FROM_DATABASE=METRODATA LTD.
+
+OUI:00C082*
+ ID_OUI_FROM_DATABASE=MOORE PRODUCTS CO.
+
+OUI:00C083*
+ ID_OUI_FROM_DATABASE=TRACE MOUNTAIN PRODUCTS, INC.
+
+OUI:00C084*
+ ID_OUI_FROM_DATABASE=DATA LINK CORP. LTD.
+
+OUI:00C085*
+ ID_OUI_FROM_DATABASE=ELECTRONICS FOR IMAGING, INC.
+
+OUI:00C086*
+ ID_OUI_FROM_DATABASE=THE LYNK CORPORATION
+
+OUI:00C087*
+ ID_OUI_FROM_DATABASE=UUNET TECHNOLOGIES, INC.
+
+OUI:00C088*
+ ID_OUI_FROM_DATABASE=EKF ELEKTRONIK GMBH
+
+OUI:00C089*
+ ID_OUI_FROM_DATABASE=TELINDUS DISTRIBUTION
+
+OUI:00C08A*
+ ID_OUI_FROM_DATABASE=Lauterbach GmbH
+
+OUI:00C08B*
+ ID_OUI_FROM_DATABASE=RISQ MODULAR SYSTEMS, INC.
+
+OUI:00C08C*
+ ID_OUI_FROM_DATABASE=PERFORMANCE TECHNOLOGIES, INC.
+
+OUI:00C08D*
+ ID_OUI_FROM_DATABASE=TRONIX PRODUCT DEVELOPMENT
+
+OUI:00C08E*
+ ID_OUI_FROM_DATABASE=NETWORK INFORMATION TECHNOLOGY
+
+OUI:00C08F*
+ ID_OUI_FROM_DATABASE=Panasonic Electric Works Co., Ltd.
+
+OUI:00C090*
+ ID_OUI_FROM_DATABASE=PRAIM S.R.L.
+
+OUI:00C091*
+ ID_OUI_FROM_DATABASE=JABIL CIRCUIT, INC.
+
+OUI:00C092*
+ ID_OUI_FROM_DATABASE=MENNEN MEDICAL INC.
+
+OUI:00C093*
+ ID_OUI_FROM_DATABASE=ALTA RESEARCH CORP.
+
+OUI:00C094*
+ ID_OUI_FROM_DATABASE=VMX INC.
+
+OUI:00C095*
+ ID_OUI_FROM_DATABASE=ZNYX
+
+OUI:00C096*
+ ID_OUI_FROM_DATABASE=TAMURA CORPORATION
+
+OUI:00C097*
+ ID_OUI_FROM_DATABASE=ARCHIPEL SA
+
+OUI:00C098*
+ ID_OUI_FROM_DATABASE=CHUNTEX ELECTRONIC CO., LTD.
+
+OUI:00C099*
+ ID_OUI_FROM_DATABASE=YOSHIKI INDUSTRIAL CO.,LTD.
+
+OUI:00C09A*
+ ID_OUI_FROM_DATABASE=PHOTONICS CORPORATION
+
+OUI:00C09B*
+ ID_OUI_FROM_DATABASE=RELIANCE COMM/TEC, R-TEC
+
+OUI:00C09C*
+ ID_OUI_FROM_DATABASE=HIOKI E.E. CORPORATION
+
+OUI:00C09D*
+ ID_OUI_FROM_DATABASE=DISTRIBUTED SYSTEMS INT'L, INC
+
+OUI:00C09E*
+ ID_OUI_FROM_DATABASE=CACHE COMPUTERS, INC.
+
+OUI:00C09F*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER, INC.
+
+OUI:00C0A0*
+ ID_OUI_FROM_DATABASE=ADVANCE MICRO RESEARCH, INC.
+
+OUI:00C0A1*
+ ID_OUI_FROM_DATABASE=TOKYO DENSHI SEKEI CO.
+
+OUI:00C0A2*
+ ID_OUI_FROM_DATABASE=INTERMEDIUM A/S
+
+OUI:00C0A3*
+ ID_OUI_FROM_DATABASE=DUAL ENTERPRISES CORPORATION
+
+OUI:00C0A4*
+ ID_OUI_FROM_DATABASE=UNIGRAF OY
+
+OUI:00C0A5*
+ ID_OUI_FROM_DATABASE=DICKENS DATA SYSTEMS
+
+OUI:00C0A6*
+ ID_OUI_FROM_DATABASE=EXICOM AUSTRALIA PTY. LTD
+
+OUI:00C0A7*
+ ID_OUI_FROM_DATABASE=SEEL LTD.
+
+OUI:00C0A8*
+ ID_OUI_FROM_DATABASE=GVC CORPORATION
+
+OUI:00C0A9*
+ ID_OUI_FROM_DATABASE=BARRON MCCANN LTD.
+
+OUI:00C0AA*
+ ID_OUI_FROM_DATABASE=SILICON VALLEY COMPUTER
+
+OUI:00C0AB*
+ ID_OUI_FROM_DATABASE=Telco Systems, Inc.
+
+OUI:00C0AC*
+ ID_OUI_FROM_DATABASE=GAMBIT COMPUTER COMMUNICATIONS
+
+OUI:00C0AD*
+ ID_OUI_FROM_DATABASE=MARBEN COMMUNICATION SYSTEMS
+
+OUI:00C0AE*
+ ID_OUI_FROM_DATABASE=TOWERCOM CO. INC. DBA PC HOUSE
+
+OUI:00C0AF*
+ ID_OUI_FROM_DATABASE=TEKLOGIX INC.
+
+OUI:00C0B0*
+ ID_OUI_FROM_DATABASE=GCC TECHNOLOGIES,INC.
+
+OUI:00C0B1*
+ ID_OUI_FROM_DATABASE=GENIUS NET CO.
+
+OUI:00C0B2*
+ ID_OUI_FROM_DATABASE=NORAND CORPORATION
+
+OUI:00C0B3*
+ ID_OUI_FROM_DATABASE=COMSTAT DATACOMM CORPORATION
+
+OUI:00C0B4*
+ ID_OUI_FROM_DATABASE=MYSON TECHNOLOGY, INC.
+
+OUI:00C0B5*
+ ID_OUI_FROM_DATABASE=CORPORATE NETWORK SYSTEMS,INC.
+
+OUI:00C0B6*
+ ID_OUI_FROM_DATABASE=Overland Storage, Inc.
+
+OUI:00C0B7*
+ ID_OUI_FROM_DATABASE=AMERICAN POWER CONVERSION CORP
+
+OUI:00C0B8*
+ ID_OUI_FROM_DATABASE=FRASER'S HILL LTD.
+
+OUI:00C0B9*
+ ID_OUI_FROM_DATABASE=FUNK SOFTWARE, INC.
+
+OUI:00C0BA*
+ ID_OUI_FROM_DATABASE=NETVANTAGE
+
+OUI:00C0BB*
+ ID_OUI_FROM_DATABASE=FORVAL CREATIVE, INC.
+
+OUI:00C0BC*
+ ID_OUI_FROM_DATABASE=TELECOM AUSTRALIA/CSSC
+
+OUI:00C0BD*
+ ID_OUI_FROM_DATABASE=INEX TECHNOLOGIES, INC.
+
+OUI:00C0BE*
+ ID_OUI_FROM_DATABASE=ALCATEL - SEL
+
+OUI:00C0BF*
+ ID_OUI_FROM_DATABASE=TECHNOLOGY CONCEPTS, LTD.
+
+OUI:00C0C0*
+ ID_OUI_FROM_DATABASE=SHORE MICROSYSTEMS, INC.
+
+OUI:00C0C1*
+ ID_OUI_FROM_DATABASE=QUAD/GRAPHICS, INC.
+
+OUI:00C0C2*
+ ID_OUI_FROM_DATABASE=INFINITE NETWORKS LTD.
+
+OUI:00C0C3*
+ ID_OUI_FROM_DATABASE=ACUSON COMPUTED SONOGRAPHY
+
+OUI:00C0C4*
+ ID_OUI_FROM_DATABASE=COMPUTER OPERATIONAL
+
+OUI:00C0C5*
+ ID_OUI_FROM_DATABASE=SID INFORMATICA
+
+OUI:00C0C6*
+ ID_OUI_FROM_DATABASE=PERSONAL MEDIA CORP.
+
+OUI:00C0C7*
+ ID_OUI_FROM_DATABASE=SPARKTRUM MICROSYSTEMS, INC.
+
+OUI:00C0C8*
+ ID_OUI_FROM_DATABASE=MICRO BYTE PTY. LTD.
+
+OUI:00C0C9*
+ ID_OUI_FROM_DATABASE=ELSAG BAILEY PROCESS
+
+OUI:00C0CA*
+ ID_OUI_FROM_DATABASE=ALFA, INC.
+
+OUI:00C0CB*
+ ID_OUI_FROM_DATABASE=CONTROL TECHNOLOGY CORPORATION
+
+OUI:00C0CC*
+ ID_OUI_FROM_DATABASE=TELESCIENCES CO SYSTEMS, INC.
+
+OUI:00C0CD*
+ ID_OUI_FROM_DATABASE=COMELTA, S.A.
+
+OUI:00C0CE*
+ ID_OUI_FROM_DATABASE=CEI SYSTEMS & ENGINEERING PTE
+
+OUI:00C0CF*
+ ID_OUI_FROM_DATABASE=IMATRAN VOIMA OY
+
+OUI:00C0D0*
+ ID_OUI_FROM_DATABASE=RATOC SYSTEM INC.
+
+OUI:00C0D1*
+ ID_OUI_FROM_DATABASE=COMTREE TECHNOLOGY CORPORATION
+
+OUI:00C0D2*
+ ID_OUI_FROM_DATABASE=SYNTELLECT, INC.
+
+OUI:00C0D3*
+ ID_OUI_FROM_DATABASE=OLYMPUS IMAGE SYSTEMS, INC.
+
+OUI:00C0D4*
+ ID_OUI_FROM_DATABASE=AXON NETWORKS, INC.
+
+OUI:00C0D5*
+ ID_OUI_FROM_DATABASE=Werbeagentur Jürgen Siebert
+
+OUI:00C0D6*
+ ID_OUI_FROM_DATABASE=J1 SYSTEMS, INC.
+
+OUI:00C0D7*
+ ID_OUI_FROM_DATABASE=TAIWAN TRADING CENTER DBA
+
+OUI:00C0D8*
+ ID_OUI_FROM_DATABASE=UNIVERSAL DATA SYSTEMS
+
+OUI:00C0D9*
+ ID_OUI_FROM_DATABASE=QUINTE NETWORK CONFIDENTIALITY
+
+OUI:00C0DA*
+ ID_OUI_FROM_DATABASE=NICE SYSTEMS LTD.
+
+OUI:00C0DB*
+ ID_OUI_FROM_DATABASE=IPC CORPORATION (PTE) LTD.
+
+OUI:00C0DC*
+ ID_OUI_FROM_DATABASE=EOS TECHNOLOGIES, INC.
+
+OUI:00C0DD*
+ ID_OUI_FROM_DATABASE=QLogic Corporation
+
+OUI:00C0DE*
+ ID_OUI_FROM_DATABASE=ZCOMM, INC.
+
+OUI:00C0DF*
+ ID_OUI_FROM_DATABASE=KYE Systems Corp.
+
+OUI:00C0E0*
+ ID_OUI_FROM_DATABASE=DSC COMMUNICATION CORP.
+
+OUI:00C0E1*
+ ID_OUI_FROM_DATABASE=SONIC SOLUTIONS
+
+OUI:00C0E2*
+ ID_OUI_FROM_DATABASE=CALCOMP, INC.
+
+OUI:00C0E3*
+ ID_OUI_FROM_DATABASE=OSITECH COMMUNICATIONS, INC.
+
+OUI:00C0E4*
+ ID_OUI_FROM_DATABASE=SIEMENS BUILDING
+
+OUI:00C0E5*
+ ID_OUI_FROM_DATABASE=GESPAC, S.A.
+
+OUI:00C0E6*
+ ID_OUI_FROM_DATABASE=Verilink Corporation
+
+OUI:00C0E7*
+ ID_OUI_FROM_DATABASE=FIBERDATA AB
+
+OUI:00C0E8*
+ ID_OUI_FROM_DATABASE=PLEXCOM, INC.
+
+OUI:00C0E9*
+ ID_OUI_FROM_DATABASE=OAK SOLUTIONS, LTD.
+
+OUI:00C0EA*
+ ID_OUI_FROM_DATABASE=ARRAY TECHNOLOGY LTD.
+
+OUI:00C0EB*
+ ID_OUI_FROM_DATABASE=SEH COMPUTERTECHNIK GMBH
+
+OUI:00C0EC*
+ ID_OUI_FROM_DATABASE=DAUPHIN TECHNOLOGY
+
+OUI:00C0ED*
+ ID_OUI_FROM_DATABASE=US ARMY ELECTRONIC
+
+OUI:00C0EE*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:00C0EF*
+ ID_OUI_FROM_DATABASE=ABIT CORPORATION
+
+OUI:00C0F0*
+ ID_OUI_FROM_DATABASE=KINGSTON TECHNOLOGY CORP.
+
+OUI:00C0F1*
+ ID_OUI_FROM_DATABASE=SHINKO ELECTRIC CO., LTD.
+
+OUI:00C0F2*
+ ID_OUI_FROM_DATABASE=TRANSITION NETWORKS
+
+OUI:00C0F3*
+ ID_OUI_FROM_DATABASE=NETWORK COMMUNICATIONS CORP.
+
+OUI:00C0F4*
+ ID_OUI_FROM_DATABASE=INTERLINK SYSTEM CO., LTD.
+
+OUI:00C0F5*
+ ID_OUI_FROM_DATABASE=METACOMP, INC.
+
+OUI:00C0F6*
+ ID_OUI_FROM_DATABASE=CELAN TECHNOLOGY INC.
+
+OUI:00C0F7*
+ ID_OUI_FROM_DATABASE=ENGAGE COMMUNICATION, INC.
+
+OUI:00C0F8*
+ ID_OUI_FROM_DATABASE=ABOUT COMPUTING INC.
+
+OUI:00C0F9*
+ ID_OUI_FROM_DATABASE=Emerson Network Power
+
+OUI:00C0FA*
+ ID_OUI_FROM_DATABASE=CANARY COMMUNICATIONS, INC.
+
+OUI:00C0FB*
+ ID_OUI_FROM_DATABASE=ADVANCED TECHNOLOGY LABS
+
+OUI:00C0FC*
+ ID_OUI_FROM_DATABASE=ELASTIC REALITY, INC.
+
+OUI:00C0FD*
+ ID_OUI_FROM_DATABASE=PROSUM
+
+OUI:00C0FE*
+ ID_OUI_FROM_DATABASE=APTEC COMPUTER SYSTEMS, INC.
+
+OUI:00C0FF*
+ ID_OUI_FROM_DATABASE=DOT HILL SYSTEMS CORPORATION
+
+OUI:00C14F*
+ ID_OUI_FROM_DATABASE=DDL Co,.ltd.
+
+OUI:00C2C6*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:00C610*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:00CBBD*
+ ID_OUI_FROM_DATABASE=Cambridge Broadband Networks Ltd.
+
+OUI:00CD90*
+ ID_OUI_FROM_DATABASE=MAS Elektronik AG
+
+OUI:00CF1C*
+ ID_OUI_FROM_DATABASE=COMMUNICATION MACHINERY CORP.
+
+OUI:00D000*
+ ID_OUI_FROM_DATABASE=FERRAN SCIENTIFIC, INC.
+
+OUI:00D001*
+ ID_OUI_FROM_DATABASE=VST TECHNOLOGIES, INC.
+
+OUI:00D002*
+ ID_OUI_FROM_DATABASE=DITECH CORPORATION
+
+OUI:00D003*
+ ID_OUI_FROM_DATABASE=COMDA ENTERPRISES CORP.
+
+OUI:00D004*
+ ID_OUI_FROM_DATABASE=PENTACOM LTD.
+
+OUI:00D005*
+ ID_OUI_FROM_DATABASE=ZHS ZEITMANAGEMENTSYSTEME
+
+OUI:00D006*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D007*
+ ID_OUI_FROM_DATABASE=MIC ASSOCIATES, INC.
+
+OUI:00D008*
+ ID_OUI_FROM_DATABASE=MACTELL CORPORATION
+
+OUI:00D009*
+ ID_OUI_FROM_DATABASE=HSING TECH. ENTERPRISE CO. LTD
+
+OUI:00D00A*
+ ID_OUI_FROM_DATABASE=LANACCESS TELECOM S.A.
+
+OUI:00D00B*
+ ID_OUI_FROM_DATABASE=RHK TECHNOLOGY, INC.
+
+OUI:00D00C*
+ ID_OUI_FROM_DATABASE=SNIJDER MICRO SYSTEMS
+
+OUI:00D00D*
+ ID_OUI_FROM_DATABASE=MICROMERITICS INSTRUMENT
+
+OUI:00D00E*
+ ID_OUI_FROM_DATABASE=PLURIS, INC.
+
+OUI:00D00F*
+ ID_OUI_FROM_DATABASE=SPEECH DESIGN GMBH
+
+OUI:00D010*
+ ID_OUI_FROM_DATABASE=CONVERGENT NETWORKS, INC.
+
+OUI:00D011*
+ ID_OUI_FROM_DATABASE=PRISM VIDEO, INC.
+
+OUI:00D012*
+ ID_OUI_FROM_DATABASE=GATEWORKS CORP.
+
+OUI:00D013*
+ ID_OUI_FROM_DATABASE=PRIMEX AEROSPACE COMPANY
+
+OUI:00D014*
+ ID_OUI_FROM_DATABASE=ROOT, INC.
+
+OUI:00D015*
+ ID_OUI_FROM_DATABASE=UNIVEX MICROTECHNOLOGY CORP.
+
+OUI:00D016*
+ ID_OUI_FROM_DATABASE=SCM MICROSYSTEMS, INC.
+
+OUI:00D017*
+ ID_OUI_FROM_DATABASE=SYNTECH INFORMATION CO., LTD.
+
+OUI:00D018*
+ ID_OUI_FROM_DATABASE=QWES. COM, INC.
+
+OUI:00D019*
+ ID_OUI_FROM_DATABASE=DAINIPPON SCREEN CORPORATE
+
+OUI:00D01A*
+ ID_OUI_FROM_DATABASE=URMET  TLC S.P.A.
+
+OUI:00D01B*
+ ID_OUI_FROM_DATABASE=MIMAKI ENGINEERING CO., LTD.
+
+OUI:00D01C*
+ ID_OUI_FROM_DATABASE=SBS TECHNOLOGIES,
+
+OUI:00D01D*
+ ID_OUI_FROM_DATABASE=FURUNO ELECTRIC CO., LTD.
+
+OUI:00D01E*
+ ID_OUI_FROM_DATABASE=PINGTEL CORP.
+
+OUI:00D01F*
+ ID_OUI_FROM_DATABASE=CTAM PTY. LTD.
+
+OUI:00D020*
+ ID_OUI_FROM_DATABASE=AIM SYSTEM, INC.
+
+OUI:00D021*
+ ID_OUI_FROM_DATABASE=REGENT ELECTRONICS CORP.
+
+OUI:00D022*
+ ID_OUI_FROM_DATABASE=INCREDIBLE TECHNOLOGIES, INC.
+
+OUI:00D023*
+ ID_OUI_FROM_DATABASE=INFORTREND TECHNOLOGY, INC.
+
+OUI:00D024*
+ ID_OUI_FROM_DATABASE=Cognex Corporation
+
+OUI:00D025*
+ ID_OUI_FROM_DATABASE=XROSSTECH, INC.
+
+OUI:00D026*
+ ID_OUI_FROM_DATABASE=HIRSCHMANN AUSTRIA GMBH
+
+OUI:00D027*
+ ID_OUI_FROM_DATABASE=APPLIED AUTOMATION, INC.
+
+OUI:00D028*
+ ID_OUI_FROM_DATABASE=Harmonic, Inc
+
+OUI:00D029*
+ ID_OUI_FROM_DATABASE=WAKEFERN FOOD CORPORATION
+
+OUI:00D02A*
+ ID_OUI_FROM_DATABASE=Voxent Systems Ltd.
+
+OUI:00D02B*
+ ID_OUI_FROM_DATABASE=JETCELL, INC.
+
+OUI:00D02C*
+ ID_OUI_FROM_DATABASE=CAMPBELL SCIENTIFIC, INC.
+
+OUI:00D02D*
+ ID_OUI_FROM_DATABASE=ADEMCO
+
+OUI:00D02E*
+ ID_OUI_FROM_DATABASE=COMMUNICATION AUTOMATION CORP.
+
+OUI:00D02F*
+ ID_OUI_FROM_DATABASE=VLSI TECHNOLOGY INC.
+
+OUI:00D030*
+ ID_OUI_FROM_DATABASE=Safetran Systems Corp
+
+OUI:00D031*
+ ID_OUI_FROM_DATABASE=INDUSTRIAL LOGIC CORPORATION
+
+OUI:00D032*
+ ID_OUI_FROM_DATABASE=YANO ELECTRIC CO., LTD.
+
+OUI:00D033*
+ ID_OUI_FROM_DATABASE=DALIAN DAXIAN NETWORK
+
+OUI:00D034*
+ ID_OUI_FROM_DATABASE=ORMEC SYSTEMS CORP.
+
+OUI:00D035*
+ ID_OUI_FROM_DATABASE=BEHAVIOR TECH. COMPUTER CORP.
+
+OUI:00D036*
+ ID_OUI_FROM_DATABASE=TECHNOLOGY ATLANTA CORP.
+
+OUI:00D037*
+ ID_OUI_FROM_DATABASE=Pace France
+
+OUI:00D038*
+ ID_OUI_FROM_DATABASE=FIVEMERE, LTD.
+
+OUI:00D039*
+ ID_OUI_FROM_DATABASE=UTILICOM, INC.
+
+OUI:00D03A*
+ ID_OUI_FROM_DATABASE=ZONEWORX, INC.
+
+OUI:00D03B*
+ ID_OUI_FROM_DATABASE=VISION PRODUCTS PTY. LTD.
+
+OUI:00D03C*
+ ID_OUI_FROM_DATABASE=Vieo, Inc.
+
+OUI:00D03D*
+ ID_OUI_FROM_DATABASE=GALILEO TECHNOLOGY, LTD.
+
+OUI:00D03E*
+ ID_OUI_FROM_DATABASE=ROCKETCHIPS, INC.
+
+OUI:00D03F*
+ ID_OUI_FROM_DATABASE=AMERICAN COMMUNICATION
+
+OUI:00D040*
+ ID_OUI_FROM_DATABASE=SYSMATE CO., LTD.
+
+OUI:00D041*
+ ID_OUI_FROM_DATABASE=AMIGO TECHNOLOGY CO., LTD.
+
+OUI:00D042*
+ ID_OUI_FROM_DATABASE=MAHLO GMBH & CO. UG
+
+OUI:00D043*
+ ID_OUI_FROM_DATABASE=ZONAL RETAIL DATA SYSTEMS
+
+OUI:00D044*
+ ID_OUI_FROM_DATABASE=ALIDIAN NETWORKS, INC.
+
+OUI:00D045*
+ ID_OUI_FROM_DATABASE=KVASER AB
+
+OUI:00D046*
+ ID_OUI_FROM_DATABASE=DOLBY LABORATORIES, INC.
+
+OUI:00D047*
+ ID_OUI_FROM_DATABASE=XN TECHNOLOGIES
+
+OUI:00D048*
+ ID_OUI_FROM_DATABASE=ECTON, INC.
+
+OUI:00D049*
+ ID_OUI_FROM_DATABASE=IMPRESSTEK CO., LTD.
+
+OUI:00D04A*
+ ID_OUI_FROM_DATABASE=PRESENCE TECHNOLOGY GMBH
+
+OUI:00D04B*
+ ID_OUI_FROM_DATABASE=LA CIE GROUP S.A.
+
+OUI:00D04C*
+ ID_OUI_FROM_DATABASE=EUROTEL TELECOM LTD.
+
+OUI:00D04D*
+ ID_OUI_FROM_DATABASE=DIV OF RESEARCH & STATISTICS
+
+OUI:00D04E*
+ ID_OUI_FROM_DATABASE=LOGIBAG
+
+OUI:00D04F*
+ ID_OUI_FROM_DATABASE=BITRONICS, INC.
+
+OUI:00D050*
+ ID_OUI_FROM_DATABASE=ISKRATEL
+
+OUI:00D051*
+ ID_OUI_FROM_DATABASE=O2 MICRO, INC.
+
+OUI:00D052*
+ ID_OUI_FROM_DATABASE=ASCEND COMMUNICATIONS, INC.
+
+OUI:00D053*
+ ID_OUI_FROM_DATABASE=CONNECTED SYSTEMS
+
+OUI:00D054*
+ ID_OUI_FROM_DATABASE=SAS INSTITUTE INC.
+
+OUI:00D055*
+ ID_OUI_FROM_DATABASE=KATHREIN-WERKE KG
+
+OUI:00D056*
+ ID_OUI_FROM_DATABASE=SOMAT CORPORATION
+
+OUI:00D057*
+ ID_OUI_FROM_DATABASE=ULTRAK, INC.
+
+OUI:00D058*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D059*
+ ID_OUI_FROM_DATABASE=AMBIT MICROSYSTEMS CORP.
+
+OUI:00D05A*
+ ID_OUI_FROM_DATABASE=SYMBIONICS, LTD.
+
+OUI:00D05B*
+ ID_OUI_FROM_DATABASE=ACROLOOP MOTION CONTROL
+
+OUI:00D05C*
+ ID_OUI_FROM_DATABASE=TECHNOTREND SYSTEMTECHNIK GMBH
+
+OUI:00D05D*
+ ID_OUI_FROM_DATABASE=INTELLIWORXX, INC.
+
+OUI:00D05E*
+ ID_OUI_FROM_DATABASE=STRATABEAM TECHNOLOGY, INC.
+
+OUI:00D05F*
+ ID_OUI_FROM_DATABASE=VALCOM, INC.
+
+OUI:00D060*
+ ID_OUI_FROM_DATABASE=Panasonic Europe Ltd.
+
+OUI:00D061*
+ ID_OUI_FROM_DATABASE=TREMON ENTERPRISES CO., LTD.
+
+OUI:00D062*
+ ID_OUI_FROM_DATABASE=DIGIGRAM
+
+OUI:00D063*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D064*
+ ID_OUI_FROM_DATABASE=MULTITEL
+
+OUI:00D065*
+ ID_OUI_FROM_DATABASE=TOKO ELECTRIC
+
+OUI:00D066*
+ ID_OUI_FROM_DATABASE=WINTRISS ENGINEERING CORP.
+
+OUI:00D067*
+ ID_OUI_FROM_DATABASE=CAMPIO COMMUNICATIONS
+
+OUI:00D068*
+ ID_OUI_FROM_DATABASE=IWILL CORPORATION
+
+OUI:00D069*
+ ID_OUI_FROM_DATABASE=TECHNOLOGIC SYSTEMS
+
+OUI:00D06A*
+ ID_OUI_FROM_DATABASE=LINKUP SYSTEMS CORPORATION
+
+OUI:00D06B*
+ ID_OUI_FROM_DATABASE=SR TELECOM INC.
+
+OUI:00D06C*
+ ID_OUI_FROM_DATABASE=SHAREWAVE, INC.
+
+OUI:00D06D*
+ ID_OUI_FROM_DATABASE=ACRISON, INC.
+
+OUI:00D06E*
+ ID_OUI_FROM_DATABASE=TRENDVIEW RECORDERS LTD.
+
+OUI:00D06F*
+ ID_OUI_FROM_DATABASE=KMC CONTROLS
+
+OUI:00D070*
+ ID_OUI_FROM_DATABASE=LONG WELL ELECTRONICS CORP.
+
+OUI:00D071*
+ ID_OUI_FROM_DATABASE=ECHELON CORP.
+
+OUI:00D072*
+ ID_OUI_FROM_DATABASE=BROADLOGIC
+
+OUI:00D073*
+ ID_OUI_FROM_DATABASE=ACN ADVANCED COMMUNICATIONS
+
+OUI:00D074*
+ ID_OUI_FROM_DATABASE=TAQUA SYSTEMS, INC.
+
+OUI:00D075*
+ ID_OUI_FROM_DATABASE=ALARIS MEDICAL SYSTEMS, INC.
+
+OUI:00D076*
+ ID_OUI_FROM_DATABASE=Bank of America
+
+OUI:00D077*
+ ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES
+
+OUI:00D078*
+ ID_OUI_FROM_DATABASE=Eltex of Sweden AB
+
+OUI:00D079*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D07A*
+ ID_OUI_FROM_DATABASE=AMAQUEST COMPUTER CORP.
+
+OUI:00D07B*
+ ID_OUI_FROM_DATABASE=COMCAM INTERNATIONAL INC
+
+OUI:00D07C*
+ ID_OUI_FROM_DATABASE=KOYO ELECTRONICS INC. CO.,LTD.
+
+OUI:00D07D*
+ ID_OUI_FROM_DATABASE=COSINE COMMUNICATIONS
+
+OUI:00D07E*
+ ID_OUI_FROM_DATABASE=KEYCORP LTD.
+
+OUI:00D07F*
+ ID_OUI_FROM_DATABASE=STRATEGY & TECHNOLOGY, LIMITED
+
+OUI:00D080*
+ ID_OUI_FROM_DATABASE=EXABYTE CORPORATION
+
+OUI:00D081*
+ ID_OUI_FROM_DATABASE=RTD Embedded Technologies, Inc.
+
+OUI:00D082*
+ ID_OUI_FROM_DATABASE=IOWAVE INC.
+
+OUI:00D083*
+ ID_OUI_FROM_DATABASE=INVERTEX, INC.
+
+OUI:00D084*
+ ID_OUI_FROM_DATABASE=NEXCOMM SYSTEMS, INC.
+
+OUI:00D085*
+ ID_OUI_FROM_DATABASE=OTIS ELEVATOR COMPANY
+
+OUI:00D086*
+ ID_OUI_FROM_DATABASE=FOVEON, INC.
+
+OUI:00D087*
+ ID_OUI_FROM_DATABASE=MICROFIRST INC.
+
+OUI:00D088*
+ ID_OUI_FROM_DATABASE=Motorola, Inc.
+
+OUI:00D089*
+ ID_OUI_FROM_DATABASE=DYNACOLOR, INC.
+
+OUI:00D08A*
+ ID_OUI_FROM_DATABASE=PHOTRON USA
+
+OUI:00D08B*
+ ID_OUI_FROM_DATABASE=ADVA Optical Networking Ltd
+
+OUI:00D08C*
+ ID_OUI_FROM_DATABASE=GENOA TECHNOLOGY, INC.
+
+OUI:00D08D*
+ ID_OUI_FROM_DATABASE=PHOENIX GROUP, INC.
+
+OUI:00D08E*
+ ID_OUI_FROM_DATABASE=NVISION INC.
+
+OUI:00D08F*
+ ID_OUI_FROM_DATABASE=ARDENT TECHNOLOGIES, INC.
+
+OUI:00D090*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D091*
+ ID_OUI_FROM_DATABASE=SMARTSAN SYSTEMS, INC.
+
+OUI:00D092*
+ ID_OUI_FROM_DATABASE=GLENAYRE WESTERN MULTIPLEX
+
+OUI:00D093*
+ ID_OUI_FROM_DATABASE=TQ - COMPONENTS GMBH
+
+OUI:00D094*
+ ID_OUI_FROM_DATABASE=TIMELINE VISTA, INC.
+
+OUI:00D095*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group
+
+OUI:00D096*
+ ID_OUI_FROM_DATABASE=3COM EUROPE LTD.
+
+OUI:00D097*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D098*
+ ID_OUI_FROM_DATABASE=Photon Dynamics Canada Inc.
+
+OUI:00D099*
+ ID_OUI_FROM_DATABASE=Elcard Wireless Systems Oy
+
+OUI:00D09A*
+ ID_OUI_FROM_DATABASE=FILANET CORPORATION
+
+OUI:00D09B*
+ ID_OUI_FROM_DATABASE=SPECTEL LTD.
+
+OUI:00D09C*
+ ID_OUI_FROM_DATABASE=KAPADIA COMMUNICATIONS
+
+OUI:00D09D*
+ ID_OUI_FROM_DATABASE=VERIS INDUSTRIES
+
+OUI:00D09E*
+ ID_OUI_FROM_DATABASE=2WIRE, INC.
+
+OUI:00D09F*
+ ID_OUI_FROM_DATABASE=NOVTEK TEST SYSTEMS
+
+OUI:00D0A0*
+ ID_OUI_FROM_DATABASE=MIPS DENMARK
+
+OUI:00D0A1*
+ ID_OUI_FROM_DATABASE=OSKAR VIERLING GMBH + CO. KG
+
+OUI:00D0A2*
+ ID_OUI_FROM_DATABASE=INTEGRATED DEVICE
+
+OUI:00D0A3*
+ ID_OUI_FROM_DATABASE=VOCAL DATA, INC.
+
+OUI:00D0A4*
+ ID_OUI_FROM_DATABASE=ALANTRO COMMUNICATIONS
+
+OUI:00D0A5*
+ ID_OUI_FROM_DATABASE=AMERICAN ARIUM
+
+OUI:00D0A6*
+ ID_OUI_FROM_DATABASE=LANBIRD TECHNOLOGY CO., LTD.
+
+OUI:00D0A7*
+ ID_OUI_FROM_DATABASE=TOKYO SOKKI KENKYUJO CO., LTD.
+
+OUI:00D0A8*
+ ID_OUI_FROM_DATABASE=NETWORK ENGINES, INC.
+
+OUI:00D0A9*
+ ID_OUI_FROM_DATABASE=SHINANO KENSHI CO., LTD.
+
+OUI:00D0AA*
+ ID_OUI_FROM_DATABASE=CHASE COMMUNICATIONS
+
+OUI:00D0AB*
+ ID_OUI_FROM_DATABASE=DELTAKABEL TELECOM CV
+
+OUI:00D0AC*
+ ID_OUI_FROM_DATABASE=GRAYSON WIRELESS
+
+OUI:00D0AD*
+ ID_OUI_FROM_DATABASE=TL INDUSTRIES
+
+OUI:00D0AE*
+ ID_OUI_FROM_DATABASE=ORESIS COMMUNICATIONS, INC.
+
+OUI:00D0AF*
+ ID_OUI_FROM_DATABASE=CUTLER-HAMMER, INC.
+
+OUI:00D0B0*
+ ID_OUI_FROM_DATABASE=BITSWITCH LTD.
+
+OUI:00D0B1*
+ ID_OUI_FROM_DATABASE=OMEGA ELECTRONICS SA
+
+OUI:00D0B2*
+ ID_OUI_FROM_DATABASE=XIOTECH CORPORATION
+
+OUI:00D0B3*
+ ID_OUI_FROM_DATABASE=DRS Technologies Canada Ltd
+
+OUI:00D0B4*
+ ID_OUI_FROM_DATABASE=KATSUJIMA CO., LTD.
+
+OUI:00D0B5*
+ ID_OUI_FROM_DATABASE=IPricot formerly DotCom
+
+OUI:00D0B6*
+ ID_OUI_FROM_DATABASE=CRESCENT NETWORKS, INC.
+
+OUI:00D0B7*
+ ID_OUI_FROM_DATABASE=INTEL CORPORATION
+
+OUI:00D0B8*
+ ID_OUI_FROM_DATABASE=Iomega Corporation
+
+OUI:00D0B9*
+ ID_OUI_FROM_DATABASE=MICROTEK INTERNATIONAL, INC.
+
+OUI:00D0BA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D0BB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D0BC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D0BD*
+ ID_OUI_FROM_DATABASE=Silicon Image GmbH
+
+OUI:00D0BE*
+ ID_OUI_FROM_DATABASE=EMUTEC INC.
+
+OUI:00D0BF*
+ ID_OUI_FROM_DATABASE=PIVOTAL TECHNOLOGIES
+
+OUI:00D0C0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D0C1*
+ ID_OUI_FROM_DATABASE=HARMONIC DATA SYSTEMS, LTD.
+
+OUI:00D0C2*
+ ID_OUI_FROM_DATABASE=BALTHAZAR TECHNOLOGY AB
+
+OUI:00D0C3*
+ ID_OUI_FROM_DATABASE=VIVID TECHNOLOGY PTE, LTD.
+
+OUI:00D0C4*
+ ID_OUI_FROM_DATABASE=TERATECH CORPORATION
+
+OUI:00D0C5*
+ ID_OUI_FROM_DATABASE=COMPUTATIONAL SYSTEMS, INC.
+
+OUI:00D0C6*
+ ID_OUI_FROM_DATABASE=THOMAS & BETTS CORP.
+
+OUI:00D0C7*
+ ID_OUI_FROM_DATABASE=PATHWAY, INC.
+
+OUI:00D0C8*
+ ID_OUI_FROM_DATABASE=Prevas A/S
+
+OUI:00D0C9*
+ ID_OUI_FROM_DATABASE=ADVANTECH CO., LTD.
+
+OUI:00D0CA*
+ ID_OUI_FROM_DATABASE=Intrinsyc Software International Inc.
+
+OUI:00D0CB*
+ ID_OUI_FROM_DATABASE=DASAN CO., LTD.
+
+OUI:00D0CC*
+ ID_OUI_FROM_DATABASE=TECHNOLOGIES LYRE INC.
+
+OUI:00D0CD*
+ ID_OUI_FROM_DATABASE=ATAN TECHNOLOGY INC.
+
+OUI:00D0CE*
+ ID_OUI_FROM_DATABASE=ASYST ELECTRONIC
+
+OUI:00D0CF*
+ ID_OUI_FROM_DATABASE=MORETON BAY
+
+OUI:00D0D0*
+ ID_OUI_FROM_DATABASE=ZHONGXING TELECOM LTD.
+
+OUI:00D0D1*
+ ID_OUI_FROM_DATABASE=Sycamore Networks
+
+OUI:00D0D2*
+ ID_OUI_FROM_DATABASE=EPILOG CORPORATION
+
+OUI:00D0D3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D0D4*
+ ID_OUI_FROM_DATABASE=V-BITS, INC.
+
+OUI:00D0D5*
+ ID_OUI_FROM_DATABASE=GRUNDIG AG
+
+OUI:00D0D6*
+ ID_OUI_FROM_DATABASE=AETHRA TELECOMUNICAZIONI
+
+OUI:00D0D7*
+ ID_OUI_FROM_DATABASE=B2C2, INC.
+
+OUI:00D0D8*
+ ID_OUI_FROM_DATABASE=3Com Corporation
+
+OUI:00D0D9*
+ ID_OUI_FROM_DATABASE=DEDICATED MICROCOMPUTERS
+
+OUI:00D0DA*
+ ID_OUI_FROM_DATABASE=TAICOM DATA SYSTEMS CO., LTD.
+
+OUI:00D0DB*
+ ID_OUI_FROM_DATABASE=MCQUAY INTERNATIONAL
+
+OUI:00D0DC*
+ ID_OUI_FROM_DATABASE=MODULAR MINING SYSTEMS, INC.
+
+OUI:00D0DD*
+ ID_OUI_FROM_DATABASE=SUNRISE TELECOM, INC.
+
+OUI:00D0DE*
+ ID_OUI_FROM_DATABASE=PHILIPS MULTIMEDIA NETWORK
+
+OUI:00D0DF*
+ ID_OUI_FROM_DATABASE=KUZUMI ELECTRONICS, INC.
+
+OUI:00D0E0*
+ ID_OUI_FROM_DATABASE=DOOIN ELECTRONICS CO.
+
+OUI:00D0E1*
+ ID_OUI_FROM_DATABASE=AVIONITEK ISRAEL INC.
+
+OUI:00D0E2*
+ ID_OUI_FROM_DATABASE=MRT MICRO, INC.
+
+OUI:00D0E3*
+ ID_OUI_FROM_DATABASE=ELE-CHEM ENGINEERING CO., LTD.
+
+OUI:00D0E4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D0E5*
+ ID_OUI_FROM_DATABASE=SOLIDUM SYSTEMS CORP.
+
+OUI:00D0E6*
+ ID_OUI_FROM_DATABASE=IBOND INC.
+
+OUI:00D0E7*
+ ID_OUI_FROM_DATABASE=VCON TELECOMMUNICATION LTD.
+
+OUI:00D0E8*
+ ID_OUI_FROM_DATABASE=MAC SYSTEM CO., LTD.
+
+OUI:00D0E9*
+ ID_OUI_FROM_DATABASE=Advantage Century Telecommunication Corp.
+
+OUI:00D0EA*
+ ID_OUI_FROM_DATABASE=NEXTONE COMMUNICATIONS, INC.
+
+OUI:00D0EB*
+ ID_OUI_FROM_DATABASE=LIGHTERA NETWORKS, INC.
+
+OUI:00D0EC*
+ ID_OUI_FROM_DATABASE=NAKAYO TELECOMMUNICATIONS, INC
+
+OUI:00D0ED*
+ ID_OUI_FROM_DATABASE=XIOX
+
+OUI:00D0EE*
+ ID_OUI_FROM_DATABASE=DICTAPHONE CORPORATION
+
+OUI:00D0EF*
+ ID_OUI_FROM_DATABASE=IGT
+
+OUI:00D0F0*
+ ID_OUI_FROM_DATABASE=CONVISION TECHNOLOGY GMBH
+
+OUI:00D0F1*
+ ID_OUI_FROM_DATABASE=SEGA ENTERPRISES, LTD.
+
+OUI:00D0F2*
+ ID_OUI_FROM_DATABASE=MONTEREY NETWORKS
+
+OUI:00D0F3*
+ ID_OUI_FROM_DATABASE=SOLARI DI UDINE SPA
+
+OUI:00D0F4*
+ ID_OUI_FROM_DATABASE=CARINTHIAN TECH INSTITUTE
+
+OUI:00D0F5*
+ ID_OUI_FROM_DATABASE=ORANGE MICRO, INC.
+
+OUI:00D0F6*
+ ID_OUI_FROM_DATABASE=Alcatel Canada
+
+OUI:00D0F7*
+ ID_OUI_FROM_DATABASE=NEXT NETS CORPORATION
+
+OUI:00D0F8*
+ ID_OUI_FROM_DATABASE=FUJIAN STAR TERMINAL
+
+OUI:00D0F9*
+ ID_OUI_FROM_DATABASE=ACUTE COMMUNICATIONS CORP.
+
+OUI:00D0FA*
+ ID_OUI_FROM_DATABASE=Thales e-Security Ltd.
+
+OUI:00D0FB*
+ ID_OUI_FROM_DATABASE=TEK MICROSYSTEMS, INCORPORATED
+
+OUI:00D0FC*
+ ID_OUI_FROM_DATABASE=GRANITE MICROSYSTEMS
+
+OUI:00D0FD*
+ ID_OUI_FROM_DATABASE=OPTIMA TELE.COM, INC.
+
+OUI:00D0FE*
+ ID_OUI_FROM_DATABASE=ASTRAL POINT
+
+OUI:00D0FF*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00D11C*
+ ID_OUI_FROM_DATABASE=ACETEL
+
+OUI:00D38D*
+ ID_OUI_FROM_DATABASE=Hotel Technology Next Generation
+
+OUI:00D632*
+ ID_OUI_FROM_DATABASE=GE Energy
+
+OUI:00DB1E*
+ ID_OUI_FROM_DATABASE=Albedo Telecom SL
+
+OUI:00DB45*
+ ID_OUI_FROM_DATABASE=THAMWAY CO.,LTD.
+
+OUI:00DBDF*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:00DD00*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD01*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD02*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD03*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD04*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD05*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD06*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD07*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD08*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD09*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD0A*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD0B*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD0C*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD0D*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD0E*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DD0F*
+ ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC.
+
+OUI:00DEFB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E000*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
+OUI:00E001*
+ ID_OUI_FROM_DATABASE=STRAND LIGHTING LIMITED
+
+OUI:00E002*
+ ID_OUI_FROM_DATABASE=CROSSROADS SYSTEMS, INC.
+
+OUI:00E003*
+ ID_OUI_FROM_DATABASE=NOKIA WIRELESS BUSINESS COMMUN
+
+OUI:00E004*
+ ID_OUI_FROM_DATABASE=PMC-SIERRA, INC.
+
+OUI:00E005*
+ ID_OUI_FROM_DATABASE=TECHNICAL CORP.
+
+OUI:00E006*
+ ID_OUI_FROM_DATABASE=SILICON INTEGRATED SYS. CORP.
+
+OUI:00E007*
+ ID_OUI_FROM_DATABASE=Avaya ECS Ltd
+
+OUI:00E008*
+ ID_OUI_FROM_DATABASE=AMAZING CONTROLS! INC.
+
+OUI:00E009*
+ ID_OUI_FROM_DATABASE=MARATHON TECHNOLOGIES CORP.
+
+OUI:00E00A*
+ ID_OUI_FROM_DATABASE=DIBA, INC.
+
+OUI:00E00B*
+ ID_OUI_FROM_DATABASE=ROOFTOP COMMUNICATIONS CORP.
+
+OUI:00E00C*
+ ID_OUI_FROM_DATABASE=MOTOROLA
+
+OUI:00E00D*
+ ID_OUI_FROM_DATABASE=RADIANT SYSTEMS
+
+OUI:00E00E*
+ ID_OUI_FROM_DATABASE=AVALON IMAGING SYSTEMS, INC.
+
+OUI:00E00F*
+ ID_OUI_FROM_DATABASE=SHANGHAI BAUD DATA
+
+OUI:00E010*
+ ID_OUI_FROM_DATABASE=HESS SB-AUTOMATENBAU GmbH
+
+OUI:00E011*
+ ID_OUI_FROM_DATABASE=Uniden Corporation
+
+OUI:00E012*
+ ID_OUI_FROM_DATABASE=PLUTO TECHNOLOGIES INTERNATIONAL INC.
+
+OUI:00E013*
+ ID_OUI_FROM_DATABASE=EASTERN ELECTRONIC CO., LTD.
+
+OUI:00E014*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E015*
+ ID_OUI_FROM_DATABASE=HEIWA CORPORATION
+
+OUI:00E016*
+ ID_OUI_FROM_DATABASE=RAPID CITY COMMUNICATIONS
+
+OUI:00E017*
+ ID_OUI_FROM_DATABASE=EXXACT GmbH
+
+OUI:00E018*
+ ID_OUI_FROM_DATABASE=ASUSTEK COMPUTER INC.
+
+OUI:00E019*
+ ID_OUI_FROM_DATABASE=ING. GIORDANO ELETTRONICA
+
+OUI:00E01A*
+ ID_OUI_FROM_DATABASE=COMTEC SYSTEMS. CO., LTD.
+
+OUI:00E01B*
+ ID_OUI_FROM_DATABASE=SPHERE COMMUNICATIONS, INC.
+
+OUI:00E01C*
+ ID_OUI_FROM_DATABASE=Cradlepoint, Inc
+
+OUI:00E01D*
+ ID_OUI_FROM_DATABASE=WebTV NETWORKS, INC.
+
+OUI:00E01E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E01F*
+ ID_OUI_FROM_DATABASE=AVIDIA Systems, Inc.
+
+OUI:00E020*
+ ID_OUI_FROM_DATABASE=TECNOMEN OY
+
+OUI:00E021*
+ ID_OUI_FROM_DATABASE=FREEGATE CORP.
+
+OUI:00E022*
+ ID_OUI_FROM_DATABASE=Analog Devices Inc.
+
+OUI:00E023*
+ ID_OUI_FROM_DATABASE=TELRAD
+
+OUI:00E024*
+ ID_OUI_FROM_DATABASE=GADZOOX NETWORKS
+
+OUI:00E025*
+ ID_OUI_FROM_DATABASE=dit Co., Ltd.
+
+OUI:00E026*
+ ID_OUI_FROM_DATABASE=Redlake MASD LLC
+
+OUI:00E027*
+ ID_OUI_FROM_DATABASE=DUX, INC.
+
+OUI:00E028*
+ ID_OUI_FROM_DATABASE=APTIX CORPORATION
+
+OUI:00E029*
+ ID_OUI_FROM_DATABASE=STANDARD MICROSYSTEMS CORP.
+
+OUI:00E02A*
+ ID_OUI_FROM_DATABASE=TANDBERG TELEVISION AS
+
+OUI:00E02B*
+ ID_OUI_FROM_DATABASE=EXTREME NETWORKS
+
+OUI:00E02C*
+ ID_OUI_FROM_DATABASE=AST COMPUTER
+
+OUI:00E02D*
+ ID_OUI_FROM_DATABASE=InnoMediaLogic, Inc.
+
+OUI:00E02E*
+ ID_OUI_FROM_DATABASE=SPC ELECTRONICS CORPORATION
+
+OUI:00E02F*
+ ID_OUI_FROM_DATABASE=MCNS HOLDINGS, L.P.
+
+OUI:00E030*
+ ID_OUI_FROM_DATABASE=MELITA INTERNATIONAL CORP.
+
+OUI:00E031*
+ ID_OUI_FROM_DATABASE=HAGIWARA ELECTRIC CO., LTD.
+
+OUI:00E032*
+ ID_OUI_FROM_DATABASE=MISYS FINANCIAL SYSTEMS, LTD.
+
+OUI:00E033*
+ ID_OUI_FROM_DATABASE=E.E.P.D. GmbH
+
+OUI:00E034*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E035*
+ ID_OUI_FROM_DATABASE=Emerson Network Power
+
+OUI:00E036*
+ ID_OUI_FROM_DATABASE=PIONEER CORPORATION
+
+OUI:00E037*
+ ID_OUI_FROM_DATABASE=CENTURY CORPORATION
+
+OUI:00E038*
+ ID_OUI_FROM_DATABASE=PROXIMA CORPORATION
+
+OUI:00E039*
+ ID_OUI_FROM_DATABASE=PARADYNE CORP.
+
+OUI:00E03A*
+ ID_OUI_FROM_DATABASE=CABLETRON SYSTEMS, INC.
+
+OUI:00E03B*
+ ID_OUI_FROM_DATABASE=PROMINET CORPORATION
+
+OUI:00E03C*
+ ID_OUI_FROM_DATABASE=AdvanSys
+
+OUI:00E03D*
+ ID_OUI_FROM_DATABASE=FOCON ELECTRONIC SYSTEMS A/S
+
+OUI:00E03E*
+ ID_OUI_FROM_DATABASE=ALFATECH, INC.
+
+OUI:00E03F*
+ ID_OUI_FROM_DATABASE=JATON CORPORATION
+
+OUI:00E040*
+ ID_OUI_FROM_DATABASE=DeskStation Technology, Inc.
+
+OUI:00E041*
+ ID_OUI_FROM_DATABASE=CSPI
+
+OUI:00E042*
+ ID_OUI_FROM_DATABASE=Pacom Systems Ltd.
+
+OUI:00E043*
+ ID_OUI_FROM_DATABASE=VitalCom
+
+OUI:00E044*
+ ID_OUI_FROM_DATABASE=LSICS CORPORATION
+
+OUI:00E045*
+ ID_OUI_FROM_DATABASE=TOUCHWAVE, INC.
+
+OUI:00E046*
+ ID_OUI_FROM_DATABASE=BENTLY NEVADA CORP.
+
+OUI:00E047*
+ ID_OUI_FROM_DATABASE=InFocus Corporation
+
+OUI:00E048*
+ ID_OUI_FROM_DATABASE=SDL COMMUNICATIONS, INC.
+
+OUI:00E049*
+ ID_OUI_FROM_DATABASE=MICROWI ELECTRONIC GmbH
+
+OUI:00E04A*
+ ID_OUI_FROM_DATABASE=ENHANCED MESSAGING SYSTEMS, INC
+
+OUI:00E04B*
+ ID_OUI_FROM_DATABASE=JUMP INDUSTRIELLE COMPUTERTECHNIK GmbH
+
+OUI:00E04C*
+ ID_OUI_FROM_DATABASE=REALTEK SEMICONDUCTOR CORP.
+
+OUI:00E04D*
+ ID_OUI_FROM_DATABASE=INTERNET INITIATIVE JAPAN, INC
+
+OUI:00E04E*
+ ID_OUI_FROM_DATABASE=SANYO DENKI CO., LTD.
+
+OUI:00E04F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E050*
+ ID_OUI_FROM_DATABASE=EXECUTONE INFORMATION SYSTEMS, INC.
+
+OUI:00E051*
+ ID_OUI_FROM_DATABASE=TALX CORPORATION
+
+OUI:00E052*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc
+
+OUI:00E053*
+ ID_OUI_FROM_DATABASE=CELLPORT LABS, INC.
+
+OUI:00E054*
+ ID_OUI_FROM_DATABASE=KODAI HITEC CO., LTD.
+
+OUI:00E055*
+ ID_OUI_FROM_DATABASE=INGENIERIA ELECTRONICA COMERCIAL INELCOM S.A.
+
+OUI:00E056*
+ ID_OUI_FROM_DATABASE=HOLONTECH CORPORATION
+
+OUI:00E057*
+ ID_OUI_FROM_DATABASE=HAN MICROTELECOM. CO., LTD.
+
+OUI:00E058*
+ ID_OUI_FROM_DATABASE=PHASE ONE DENMARK A/S
+
+OUI:00E059*
+ ID_OUI_FROM_DATABASE=CONTROLLED ENVIRONMENTS, LTD.
+
+OUI:00E05A*
+ ID_OUI_FROM_DATABASE=GALEA NETWORK SECURITY
+
+OUI:00E05B*
+ ID_OUI_FROM_DATABASE=WEST END SYSTEMS CORP.
+
+OUI:00E05C*
+ ID_OUI_FROM_DATABASE=MATSUSHITA KOTOBUKI ELECTRONICS INDUSTRIES, LTD.
+
+OUI:00E05D*
+ ID_OUI_FROM_DATABASE=UNITEC CO., LTD.
+
+OUI:00E05E*
+ ID_OUI_FROM_DATABASE=JAPAN AVIATION ELECTRONICS INDUSTRY, LTD.
+
+OUI:00E05F*
+ ID_OUI_FROM_DATABASE=e-Net, Inc.
+
+OUI:00E060*
+ ID_OUI_FROM_DATABASE=SHERWOOD
+
+OUI:00E061*
+ ID_OUI_FROM_DATABASE=EdgePoint Networks, Inc.
+
+OUI:00E062*
+ ID_OUI_FROM_DATABASE=HOST ENGINEERING
+
+OUI:00E063*
+ ID_OUI_FROM_DATABASE=CABLETRON - YAGO SYSTEMS, INC.
+
+OUI:00E064*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS
+
+OUI:00E065*
+ ID_OUI_FROM_DATABASE=OPTICAL ACCESS INTERNATIONAL
+
+OUI:00E066*
+ ID_OUI_FROM_DATABASE=ProMax Systems, Inc.
+
+OUI:00E067*
+ ID_OUI_FROM_DATABASE=eac AUTOMATION-CONSULTING GmbH
+
+OUI:00E068*
+ ID_OUI_FROM_DATABASE=MERRIMAC SYSTEMS INC.
+
+OUI:00E069*
+ ID_OUI_FROM_DATABASE=JAYCOR
+
+OUI:00E06A*
+ ID_OUI_FROM_DATABASE=KAPSCH AG
+
+OUI:00E06B*
+ ID_OUI_FROM_DATABASE=W&G SPECIAL PRODUCTS
+
+OUI:00E06C*
+ ID_OUI_FROM_DATABASE=AEP Systems International Ltd
+
+OUI:00E06D*
+ ID_OUI_FROM_DATABASE=COMPUWARE CORPORATION
+
+OUI:00E06E*
+ ID_OUI_FROM_DATABASE=FAR SYSTEMS S.p.A.
+
+OUI:00E06F*
+ ID_OUI_FROM_DATABASE=Motorola, Inc.
+
+OUI:00E070*
+ ID_OUI_FROM_DATABASE=DH TECHNOLOGY
+
+OUI:00E071*
+ ID_OUI_FROM_DATABASE=EPIS MICROCOMPUTER
+
+OUI:00E072*
+ ID_OUI_FROM_DATABASE=LYNK
+
+OUI:00E073*
+ ID_OUI_FROM_DATABASE=NATIONAL AMUSEMENT NETWORK, INC.
+
+OUI:00E074*
+ ID_OUI_FROM_DATABASE=TIERNAN COMMUNICATIONS, INC.
+
+OUI:00E075*
+ ID_OUI_FROM_DATABASE=Verilink Corporation
+
+OUI:00E076*
+ ID_OUI_FROM_DATABASE=DEVELOPMENT CONCEPTS, INC.
+
+OUI:00E077*
+ ID_OUI_FROM_DATABASE=WEBGEAR, INC.
+
+OUI:00E078*
+ ID_OUI_FROM_DATABASE=BERKELEY NETWORKS
+
+OUI:00E079*
+ ID_OUI_FROM_DATABASE=A.T.N.R.
+
+OUI:00E07A*
+ ID_OUI_FROM_DATABASE=MIKRODIDAKT AB
+
+OUI:00E07B*
+ ID_OUI_FROM_DATABASE=BAY NETWORKS
+
+OUI:00E07C*
+ ID_OUI_FROM_DATABASE=METTLER-TOLEDO, INC.
+
+OUI:00E07D*
+ ID_OUI_FROM_DATABASE=NETRONIX, INC.
+
+OUI:00E07E*
+ ID_OUI_FROM_DATABASE=WALT DISNEY IMAGINEERING
+
+OUI:00E07F*
+ ID_OUI_FROM_DATABASE=LOGISTISTEM s.r.l.
+
+OUI:00E080*
+ ID_OUI_FROM_DATABASE=CONTROL RESOURCES CORPORATION
+
+OUI:00E081*
+ ID_OUI_FROM_DATABASE=TYAN COMPUTER CORP.
+
+OUI:00E082*
+ ID_OUI_FROM_DATABASE=ANERMA
+
+OUI:00E083*
+ ID_OUI_FROM_DATABASE=JATO TECHNOLOGIES, INC.
+
+OUI:00E084*
+ ID_OUI_FROM_DATABASE=COMPULITE R&D
+
+OUI:00E085*
+ ID_OUI_FROM_DATABASE=GLOBAL MAINTECH, INC.
+
+OUI:00E086*
+ ID_OUI_FROM_DATABASE=CYBEX COMPUTER PRODUCTS
+
+OUI:00E087*
+ ID_OUI_FROM_DATABASE=LeCroy - Networking Productions Division
+
+OUI:00E088*
+ ID_OUI_FROM_DATABASE=LTX CORPORATION
+
+OUI:00E089*
+ ID_OUI_FROM_DATABASE=ION Networks, Inc.
+
+OUI:00E08A*
+ ID_OUI_FROM_DATABASE=GEC AVERY, LTD.
+
+OUI:00E08B*
+ ID_OUI_FROM_DATABASE=QLogic Corp.
+
+OUI:00E08C*
+ ID_OUI_FROM_DATABASE=NEOPARADIGM LABS, INC.
+
+OUI:00E08D*
+ ID_OUI_FROM_DATABASE=PRESSURE SYSTEMS, INC.
+
+OUI:00E08E*
+ ID_OUI_FROM_DATABASE=UTSTARCOM
+
+OUI:00E08F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E090*
+ ID_OUI_FROM_DATABASE=BECKMAN LAB. AUTOMATION DIV.
+
+OUI:00E091*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS, INC.
+
+OUI:00E092*
+ ID_OUI_FROM_DATABASE=ADMTEK INCORPORATED
+
+OUI:00E093*
+ ID_OUI_FROM_DATABASE=ACKFIN NETWORKS
+
+OUI:00E094*
+ ID_OUI_FROM_DATABASE=OSAI SRL
+
+OUI:00E095*
+ ID_OUI_FROM_DATABASE=ADVANCED-VISION TECHNOLGIES CORP.
+
+OUI:00E096*
+ ID_OUI_FROM_DATABASE=SHIMADZU CORPORATION
+
+OUI:00E097*
+ ID_OUI_FROM_DATABASE=CARRIER ACCESS CORPORATION
+
+OUI:00E098*
+ ID_OUI_FROM_DATABASE=AboCom Systems, Inc.
+
+OUI:00E099*
+ ID_OUI_FROM_DATABASE=SAMSON AG
+
+OUI:00E09A*
+ ID_OUI_FROM_DATABASE=Positron Inc.
+
+OUI:00E09B*
+ ID_OUI_FROM_DATABASE=ENGAGE NETWORKS, INC.
+
+OUI:00E09C*
+ ID_OUI_FROM_DATABASE=MII
+
+OUI:00E09D*
+ ID_OUI_FROM_DATABASE=SARNOFF CORPORATION
+
+OUI:00E09E*
+ ID_OUI_FROM_DATABASE=QUANTUM CORPORATION
+
+OUI:00E09F*
+ ID_OUI_FROM_DATABASE=PIXEL VISION
+
+OUI:00E0A0*
+ ID_OUI_FROM_DATABASE=WILTRON CO.
+
+OUI:00E0A1*
+ ID_OUI_FROM_DATABASE=HIMA PAUL HILDEBRANDT GmbH Co. KG
+
+OUI:00E0A2*
+ ID_OUI_FROM_DATABASE=MICROSLATE INC.
+
+OUI:00E0A3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E0A4*
+ ID_OUI_FROM_DATABASE=ESAOTE S.p.A.
+
+OUI:00E0A5*
+ ID_OUI_FROM_DATABASE=ComCore Semiconductor, Inc.
+
+OUI:00E0A6*
+ ID_OUI_FROM_DATABASE=TELOGY NETWORKS, INC.
+
+OUI:00E0A7*
+ ID_OUI_FROM_DATABASE=IPC INFORMATION SYSTEMS, INC.
+
+OUI:00E0A8*
+ ID_OUI_FROM_DATABASE=SAT GmbH & Co.
+
+OUI:00E0A9*
+ ID_OUI_FROM_DATABASE=FUNAI ELECTRIC CO., LTD.
+
+OUI:00E0AA*
+ ID_OUI_FROM_DATABASE=ELECTROSONIC LTD.
+
+OUI:00E0AB*
+ ID_OUI_FROM_DATABASE=DIMAT S.A.
+
+OUI:00E0AC*
+ ID_OUI_FROM_DATABASE=MIDSCO, INC.
+
+OUI:00E0AD*
+ ID_OUI_FROM_DATABASE=EES TECHNOLOGY, LTD.
+
+OUI:00E0AE*
+ ID_OUI_FROM_DATABASE=XAQTI CORPORATION
+
+OUI:00E0AF*
+ ID_OUI_FROM_DATABASE=GENERAL DYNAMICS INFORMATION SYSTEMS
+
+OUI:00E0B0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E0B1*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group
+
+OUI:00E0B2*
+ ID_OUI_FROM_DATABASE=TELMAX COMMUNICATIONS CORP.
+
+OUI:00E0B3*
+ ID_OUI_FROM_DATABASE=EtherWAN Systems, Inc.
+
+OUI:00E0B4*
+ ID_OUI_FROM_DATABASE=TECHNO SCOPE CO., LTD.
+
+OUI:00E0B5*
+ ID_OUI_FROM_DATABASE=ARDENT COMMUNICATIONS CORP.
+
+OUI:00E0B6*
+ ID_OUI_FROM_DATABASE=Entrada Networks
+
+OUI:00E0B7*
+ ID_OUI_FROM_DATABASE=PI GROUP, LTD.
+
+OUI:00E0B8*
+ ID_OUI_FROM_DATABASE=GATEWAY 2000
+
+OUI:00E0B9*
+ ID_OUI_FROM_DATABASE=BYAS SYSTEMS
+
+OUI:00E0BA*
+ ID_OUI_FROM_DATABASE=BERGHOF AUTOMATIONSTECHNIK GmbH
+
+OUI:00E0BB*
+ ID_OUI_FROM_DATABASE=NBX CORPORATION
+
+OUI:00E0BC*
+ ID_OUI_FROM_DATABASE=SYMON COMMUNICATIONS, INC.
+
+OUI:00E0BD*
+ ID_OUI_FROM_DATABASE=INTERFACE SYSTEMS, INC.
+
+OUI:00E0BE*
+ ID_OUI_FROM_DATABASE=GENROCO INTERNATIONAL, INC.
+
+OUI:00E0BF*
+ ID_OUI_FROM_DATABASE=TORRENT NETWORKING TECHNOLOGIES CORP.
+
+OUI:00E0C0*
+ ID_OUI_FROM_DATABASE=SEIWA ELECTRIC MFG. CO., LTD.
+
+OUI:00E0C1*
+ ID_OUI_FROM_DATABASE=MEMOREX TELEX JAPAN, LTD.
+
+OUI:00E0C2*
+ ID_OUI_FROM_DATABASE=NECSY S.p.A.
+
+OUI:00E0C3*
+ ID_OUI_FROM_DATABASE=SAKAI SYSTEM DEVELOPMENT CORP.
+
+OUI:00E0C4*
+ ID_OUI_FROM_DATABASE=HORNER ELECTRIC, INC.
+
+OUI:00E0C5*
+ ID_OUI_FROM_DATABASE=BCOM ELECTRONICS INC.
+
+OUI:00E0C6*
+ ID_OUI_FROM_DATABASE=LINK2IT, L.L.C.
+
+OUI:00E0C7*
+ ID_OUI_FROM_DATABASE=EUROTECH SRL
+
+OUI:00E0C8*
+ ID_OUI_FROM_DATABASE=VIRTUAL ACCESS, LTD.
+
+OUI:00E0C9*
+ ID_OUI_FROM_DATABASE=AutomatedLogic Corporation
+
+OUI:00E0CA*
+ ID_OUI_FROM_DATABASE=BEST DATA PRODUCTS
+
+OUI:00E0CB*
+ ID_OUI_FROM_DATABASE=RESON, INC.
+
+OUI:00E0CC*
+ ID_OUI_FROM_DATABASE=HERO SYSTEMS, LTD.
+
+OUI:00E0CD*
+ ID_OUI_FROM_DATABASE=SENSIS CORPORATION
+
+OUI:00E0CE*
+ ID_OUI_FROM_DATABASE=ARN
+
+OUI:00E0CF*
+ ID_OUI_FROM_DATABASE=INTEGRATED DEVICE TECHNOLOGY, INC.
+
+OUI:00E0D0*
+ ID_OUI_FROM_DATABASE=NETSPEED, INC.
+
+OUI:00E0D1*
+ ID_OUI_FROM_DATABASE=TELSIS LIMITED
+
+OUI:00E0D2*
+ ID_OUI_FROM_DATABASE=VERSANET COMMUNICATIONS, INC.
+
+OUI:00E0D3*
+ ID_OUI_FROM_DATABASE=DATENTECHNIK GmbH
+
+OUI:00E0D4*
+ ID_OUI_FROM_DATABASE=EXCELLENT COMPUTER
+
+OUI:00E0D5*
+ ID_OUI_FROM_DATABASE=Emulex Corporation
+
+OUI:00E0D6*
+ ID_OUI_FROM_DATABASE=COMPUTER & COMMUNICATION RESEARCH LAB.
+
+OUI:00E0D7*
+ ID_OUI_FROM_DATABASE=SUNSHINE ELECTRONICS, INC.
+
+OUI:00E0D8*
+ ID_OUI_FROM_DATABASE=LANBit Computer, Inc.
+
+OUI:00E0D9*
+ ID_OUI_FROM_DATABASE=TAZMO CO., LTD.
+
+OUI:00E0DA*
+ ID_OUI_FROM_DATABASE=Alcatel North America ESD
+
+OUI:00E0DB*
+ ID_OUI_FROM_DATABASE=ViaVideo Communications, Inc.
+
+OUI:00E0DC*
+ ID_OUI_FROM_DATABASE=NEXWARE CORP.
+
+OUI:00E0DD*
+ ID_OUI_FROM_DATABASE=ZENITH ELECTRONICS CORPORATION
+
+OUI:00E0DE*
+ ID_OUI_FROM_DATABASE=DATAX NV
+
+OUI:00E0DF*
+ ID_OUI_FROM_DATABASE=KEYMILE GmbH
+
+OUI:00E0E0*
+ ID_OUI_FROM_DATABASE=SI ELECTRONICS, LTD.
+
+OUI:00E0E1*
+ ID_OUI_FROM_DATABASE=G2 NETWORKS, INC.
+
+OUI:00E0E2*
+ ID_OUI_FROM_DATABASE=INNOVA CORP.
+
+OUI:00E0E3*
+ ID_OUI_FROM_DATABASE=SK-ELEKTRONIK GmbH
+
+OUI:00E0E4*
+ ID_OUI_FROM_DATABASE=FANUC ROBOTICS NORTH AMERICA, Inc.
+
+OUI:00E0E5*
+ ID_OUI_FROM_DATABASE=CINCO NETWORKS, INC.
+
+OUI:00E0E6*
+ ID_OUI_FROM_DATABASE=INCAA DATACOM B.V.
+
+OUI:00E0E7*
+ ID_OUI_FROM_DATABASE=RAYTHEON E-SYSTEMS, INC.
+
+OUI:00E0E8*
+ ID_OUI_FROM_DATABASE=GRETACODER Data Systems AG
+
+OUI:00E0E9*
+ ID_OUI_FROM_DATABASE=DATA LABS, INC.
+
+OUI:00E0EA*
+ ID_OUI_FROM_DATABASE=INNOVAT COMMUNICATIONS, INC.
+
+OUI:00E0EB*
+ ID_OUI_FROM_DATABASE=DIGICOM SYSTEMS, INCORPORATED
+
+OUI:00E0EC*
+ ID_OUI_FROM_DATABASE=CELESTICA INC.
+
+OUI:00E0ED*
+ ID_OUI_FROM_DATABASE=SILICOM, LTD.
+
+OUI:00E0EE*
+ ID_OUI_FROM_DATABASE=MAREL HF
+
+OUI:00E0EF*
+ ID_OUI_FROM_DATABASE=DIONEX
+
+OUI:00E0F0*
+ ID_OUI_FROM_DATABASE=ABLER TECHNOLOGY, INC.
+
+OUI:00E0F1*
+ ID_OUI_FROM_DATABASE=THAT CORPORATION
+
+OUI:00E0F2*
+ ID_OUI_FROM_DATABASE=ARLOTTO COMNET, INC.
+
+OUI:00E0F3*
+ ID_OUI_FROM_DATABASE=WebSprint Communications, Inc.
+
+OUI:00E0F4*
+ ID_OUI_FROM_DATABASE=INSIDE Technology A/S
+
+OUI:00E0F5*
+ ID_OUI_FROM_DATABASE=TELES AG
+
+OUI:00E0F6*
+ ID_OUI_FROM_DATABASE=DECISION EUROPE
+
+OUI:00E0F7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E0F8*
+ ID_OUI_FROM_DATABASE=DICNA CONTROL AB
+
+OUI:00E0F9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E0FA*
+ ID_OUI_FROM_DATABASE=TRL TECHNOLOGY, LTD.
+
+OUI:00E0FB*
+ ID_OUI_FROM_DATABASE=LEIGHTRONIX, INC.
+
+OUI:00E0FC*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO., LTD.
+
+OUI:00E0FD*
+ ID_OUI_FROM_DATABASE=A-TREND TECHNOLOGY CO., LTD.
+
+OUI:00E0FE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:00E0FF*
+ ID_OUI_FROM_DATABASE=SECURITY DYNAMICS TECHNOLOGIES, Inc.
+
+OUI:00E175*
+ ID_OUI_FROM_DATABASE=AK-Systems Ltd
+
+OUI:00E666*
+ ID_OUI_FROM_DATABASE=ARIMA Communications Corp.
+
+OUI:00E6D3*
+ ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORP.
+
+OUI:00E8AB*
+ ID_OUI_FROM_DATABASE=Meggitt Training Systems, Inc.
+
+OUI:00EB2D*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
+OUI:00F051*
+ ID_OUI_FROM_DATABASE=KWB Gmbh
+
+OUI:00F403*
+ ID_OUI_FROM_DATABASE=Orbis Systems Oy
+
+OUI:00F4B9*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:00F860*
+ ID_OUI_FROM_DATABASE=PT. Panggung Electric Citrabuana
+
+OUI:00FA3B*
+ ID_OUI_FROM_DATABASE=CLOOS ELECTRONIC GMBH
+
+OUI:00FC58*
+ ID_OUI_FROM_DATABASE=WebSilicon Ltd.
+
+OUI:00FC70*
+ ID_OUI_FROM_DATABASE=Intrepid Control Systems, Inc.
+
+OUI:00FD4C*
+ ID_OUI_FROM_DATABASE=NEVATEC
+
+OUI:020701*
+ ID_OUI_FROM_DATABASE=RACAL-DATACOM
+
+OUI:021C7C*
+ ID_OUI_FROM_DATABASE=PERQ SYSTEMS CORPORATION
+
+OUI:026086*
+ ID_OUI_FROM_DATABASE=LOGIC REPLACEMENT TECH. LTD.
+
+OUI:02608C*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:027001*
+ ID_OUI_FROM_DATABASE=RACAL-DATACOM
+
+OUI:0270B0*
+ ID_OUI_FROM_DATABASE=M/A-COM INC. COMPANIES
+
+OUI:0270B3*
+ ID_OUI_FROM_DATABASE=DATA RECALL LTD
+
+OUI:029D8E*
+ ID_OUI_FROM_DATABASE=CARDIAC RECORDERS INC.
+
+OUI:02AA3C*
+ ID_OUI_FROM_DATABASE=OLIVETTI TELECOMM SPA (OLTECO)
+
+OUI:02BB01*
+ ID_OUI_FROM_DATABASE=OCTOTHORPE CORP.
+
+OUI:02C08C*
+ ID_OUI_FROM_DATABASE=3COM CORPORATION
+
+OUI:02CF1C*
+ ID_OUI_FROM_DATABASE=COMMUNICATION MACHINERY CORP.
+
+OUI:02E6D3*
+ ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORPORATION
+
+OUI:040A83*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:040AE0*
+ ID_OUI_FROM_DATABASE=XMIT AG COMPUTER NETWORKS
+
+OUI:040CCE*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:040EC2*
+ ID_OUI_FROM_DATABASE=ViewSonic Mobile China Limited
+
+OUI:041552*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:04180F*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0418D6*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:041D10*
+ ID_OUI_FROM_DATABASE=Dream Ware Inc.
+
+OUI:041E64*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:04209A*
+ ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
+
+OUI:042234*
+ ID_OUI_FROM_DATABASE=Wireless Standard Extensions
+
+OUI:042605*
+ ID_OUI_FROM_DATABASE=GFR Gesellschaft für Regelungstechnik und Energieeinsparung mbH
+
+OUI:042665*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:042BBB*
+ ID_OUI_FROM_DATABASE=PicoCELA, Inc.
+
+OUI:042F56*
+ ID_OUI_FROM_DATABASE=ATOCS (Shenzhen) LTD
+
+OUI:0432F4*
+ ID_OUI_FROM_DATABASE=Partron
+
+OUI:043604*
+ ID_OUI_FROM_DATABASE=Gyeyoung I&T
+
+OUI:044665*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:044A50*
+ ID_OUI_FROM_DATABASE=Ramaxel Technology (Shenzhen) limited company
+
+OUI:044BFF*
+ ID_OUI_FROM_DATABASE=GuangZhou Hedy Digital Technology Co., Ltd
+
+OUI:044FAA*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:045453*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:0455CA*
+ ID_OUI_FROM_DATABASE=BriView (Xiamen) Corp.
+
+OUI:04586F*
+ ID_OUI_FROM_DATABASE=Sichuan Whayer information industry Co.,LTD
+
+OUI:045A95*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:045C06*
+ ID_OUI_FROM_DATABASE=Zmodo Technology Corporation
+
+OUI:045D56*
+ ID_OUI_FROM_DATABASE=camtron industrial inc.
+
+OUI:045FA7*
+ ID_OUI_FROM_DATABASE=Shenzhen Yichen Technology Development Co.,LTD
+
+OUI:0462D7*
+ ID_OUI_FROM_DATABASE=ALSTOM HYDRO FRANCE
+
+OUI:0463E0*
+ ID_OUI_FROM_DATABASE=Nome Oy
+
+OUI:046D42*
+ ID_OUI_FROM_DATABASE=Bryston Ltd.
+
+OUI:046E49*
+ ID_OUI_FROM_DATABASE=TaiYear Electronic Technology (Suzhou) Co., Ltd
+
+OUI:0470BC*
+ ID_OUI_FROM_DATABASE=Globalstar Inc.
+
+OUI:0474A1*
+ ID_OUI_FROM_DATABASE=Aligera Equipamentos Digitais Ltda
+
+OUI:0475F5*
+ ID_OUI_FROM_DATABASE=CSST
+
+OUI:04766E*
+ ID_OUI_FROM_DATABASE=ALPS Co,. Ltd.
+
+OUI:047D7B*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc.
+
+OUI:0481AE*
+ ID_OUI_FROM_DATABASE=Clack Corporation
+
+OUI:04888C*
+ ID_OUI_FROM_DATABASE=Eifelwerk Butler Systeme GmbH
+
+OUI:048A15*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:048B42*
+ ID_OUI_FROM_DATABASE=Skspruce Technology Limited
+
+OUI:0494A1*
+ ID_OUI_FROM_DATABASE=CATCH THE WIND INC
+
+OUI:0498F3*
+ ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd.
+
+OUI:049C62*
+ ID_OUI_FROM_DATABASE=BMT Medical Technology s.r.o.
+
+OUI:049F06*
+ ID_OUI_FROM_DATABASE=Smobile Co., Ltd.
+
+OUI:049F81*
+ ID_OUI_FROM_DATABASE=Simena, LLC
+
+OUI:04A3F3*
+ ID_OUI_FROM_DATABASE=Emicon
+
+OUI:04A82A*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:04B3B6*
+ ID_OUI_FROM_DATABASE=Seamap (UK) Ltd
+
+OUI:04B466*
+ ID_OUI_FROM_DATABASE=BSP Co., Ltd.
+
+OUI:04C05B*
+ ID_OUI_FROM_DATABASE=Tigo Energy
+
+OUI:04C06F*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:04C1B9*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
+
+OUI:04C5A4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:04C880*
+ ID_OUI_FROM_DATABASE=Samtec Inc
+
+OUI:04CE14*
+ ID_OUI_FROM_DATABASE=Wilocity LTD.
+
+OUI:04D783*
+ ID_OUI_FROM_DATABASE=Y&H E&C Co.,LTD.
+
+OUI:04DAD2*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:04DD4C*
+ ID_OUI_FROM_DATABASE=IPBlaze
+
+OUI:04E0C4*
+ ID_OUI_FROM_DATABASE=TRIUMPH-ADLER AG
+
+OUI:04E1C8*
+ ID_OUI_FROM_DATABASE=IMS Soluções em Energia Ltda.
+
+OUI:04E2F8*
+ ID_OUI_FROM_DATABASE=AEP srl
+
+OUI:04E451*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:04E548*
+ ID_OUI_FROM_DATABASE=Cohda Wireless Pty Ltd
+
+OUI:04E662*
+ ID_OUI_FROM_DATABASE=Acroname Inc.
+
+OUI:04E9E5*
+ ID_OUI_FROM_DATABASE=PJRC.COM, LLC
+
+OUI:04EE91*
+ ID_OUI_FROM_DATABASE=x-fabric GmbH
+
+OUI:04F021*
+ ID_OUI_FROM_DATABASE=Compex Systems Pte Ltd
+
+OUI:04F17D*
+ ID_OUI_FROM_DATABASE=Tarana Wireless
+
+OUI:04F4BC*
+ ID_OUI_FROM_DATABASE=Xena Networks
+
+OUI:04F7E4*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:04F8C2*
+ ID_OUI_FROM_DATABASE=Flaircomm Microelectronics, Inc.
+
+OUI:04FE31*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:04FE7F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:04FF51*
+ ID_OUI_FROM_DATABASE=NOVAMEDIA INNOVISION SP. Z O.O.
+
+OUI:080001*
+ ID_OUI_FROM_DATABASE=COMPUTERVISION CORPORATION
+
+OUI:080002*
+ ID_OUI_FROM_DATABASE=BRIDGE COMMUNICATIONS INC.
+
+OUI:080003*
+ ID_OUI_FROM_DATABASE=ADVANCED COMPUTER COMM.
+
+OUI:080004*
+ ID_OUI_FROM_DATABASE=CROMEMCO INCORPORATED
+
+OUI:080005*
+ ID_OUI_FROM_DATABASE=SYMBOLICS INC.
+
+OUI:080006*
+ ID_OUI_FROM_DATABASE=SIEMENS AG
+
+OUI:080007*
+ ID_OUI_FROM_DATABASE=APPLE COMPUTER INC.
+
+OUI:080008*
+ ID_OUI_FROM_DATABASE=BOLT BERANEK AND NEWMAN INC.
+
+OUI:080009*
+ ID_OUI_FROM_DATABASE=HEWLETT PACKARD
+
+OUI:08000A*
+ ID_OUI_FROM_DATABASE=NESTAR SYSTEMS INCORPORATED
+
+OUI:08000B*
+ ID_OUI_FROM_DATABASE=UNISYS CORPORATION
+
+OUI:08000C*
+ ID_OUI_FROM_DATABASE=MIKLYN DEVELOPMENT CO.
+
+OUI:08000D*
+ ID_OUI_FROM_DATABASE=INTERNATIONAL COMPUTERS LTD.
+
+OUI:08000E*
+ ID_OUI_FROM_DATABASE=NCR CORPORATION
+
+OUI:08000F*
+ ID_OUI_FROM_DATABASE=MITEL CORPORATION
+
+OUI:080011*
+ ID_OUI_FROM_DATABASE=TEKTRONIX INC.
+
+OUI:080012*
+ ID_OUI_FROM_DATABASE=BELL ATLANTIC INTEGRATED SYST.
+
+OUI:080013*
+ ID_OUI_FROM_DATABASE=EXXON
+
+OUI:080014*
+ ID_OUI_FROM_DATABASE=EXCELAN
+
+OUI:080015*
+ ID_OUI_FROM_DATABASE=STC BUSINESS SYSTEMS
+
+OUI:080016*
+ ID_OUI_FROM_DATABASE=BARRISTER INFO SYS CORP
+
+OUI:080017*
+ ID_OUI_FROM_DATABASE=NATIONAL SEMICONDUCTOR
+
+OUI:080018*
+ ID_OUI_FROM_DATABASE=PIRELLI FOCOM NETWORKS
+
+OUI:080019*
+ ID_OUI_FROM_DATABASE=GENERAL ELECTRIC CORPORATION
+
+OUI:08001A*
+ ID_OUI_FROM_DATABASE=TIARA/ 10NET
+
+OUI:08001B*
+ ID_OUI_FROM_DATABASE=EMC Corporation
+
+OUI:08001C*
+ ID_OUI_FROM_DATABASE=KDD-KOKUSAI DEBNSIN DENWA CO.
+
+OUI:08001D*
+ ID_OUI_FROM_DATABASE=ABLE COMMUNICATIONS INC.
+
+OUI:08001E*
+ ID_OUI_FROM_DATABASE=APOLLO COMPUTER INC.
+
+OUI:08001F*
+ ID_OUI_FROM_DATABASE=SHARP CORPORATION
+
+OUI:080020*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
+OUI:080021*
+ ID_OUI_FROM_DATABASE=3M COMPANY
+
+OUI:080022*
+ ID_OUI_FROM_DATABASE=NBI INC.
+
+OUI:080023*
+ ID_OUI_FROM_DATABASE=Panasonic Communications Co., Ltd.
+
+OUI:080024*
+ ID_OUI_FROM_DATABASE=10NET COMMUNICATIONS/DCA
+
+OUI:080025*
+ ID_OUI_FROM_DATABASE=CONTROL DATA
+
+OUI:080026*
+ ID_OUI_FROM_DATABASE=NORSK DATA A.S.
+
+OUI:080027*
+ ID_OUI_FROM_DATABASE=CADMUS COMPUTER SYSTEMS
+
+OUI:080028*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:080029*
+ ID_OUI_FROM_DATABASE=MEGATEK CORPORATION
+
+OUI:08002A*
+ ID_OUI_FROM_DATABASE=MOSAIC TECHNOLOGIES INC.
+
+OUI:08002B*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:08002C*
+ ID_OUI_FROM_DATABASE=BRITTON LEE INC.
+
+OUI:08002D*
+ ID_OUI_FROM_DATABASE=LAN-TEC INC.
+
+OUI:08002E*
+ ID_OUI_FROM_DATABASE=METAPHOR COMPUTER SYSTEMS
+
+OUI:08002F*
+ ID_OUI_FROM_DATABASE=PRIME COMPUTER INC.
+
+OUI:080030*
+ ID_OUI_FROM_DATABASE=NETWORK RESEARCH CORPORATION
+
+OUI:080030*
+ ID_OUI_FROM_DATABASE=CERN
+
+OUI:080030*
+ ID_OUI_FROM_DATABASE=ROYAL MELBOURNE INST OF TECH
+
+OUI:080031*
+ ID_OUI_FROM_DATABASE=LITTLE MACHINES INC.
+
+OUI:080032*
+ ID_OUI_FROM_DATABASE=TIGAN INCORPORATED
+
+OUI:080033*
+ ID_OUI_FROM_DATABASE=BAUSCH & LOMB
+
+OUI:080034*
+ ID_OUI_FROM_DATABASE=FILENET CORPORATION
+
+OUI:080035*
+ ID_OUI_FROM_DATABASE=MICROFIVE CORPORATION
+
+OUI:080036*
+ ID_OUI_FROM_DATABASE=INTERGRAPH CORPORATION
+
+OUI:080037*
+ ID_OUI_FROM_DATABASE=FUJI-XEROX CO. LTD.
+
+OUI:080038*
+ ID_OUI_FROM_DATABASE=BULL S.A.S.
+
+OUI:080039*
+ ID_OUI_FROM_DATABASE=SPIDER SYSTEMS LIMITED
+
+OUI:08003A*
+ ID_OUI_FROM_DATABASE=ORCATECH INC.
+
+OUI:08003B*
+ ID_OUI_FROM_DATABASE=TORUS SYSTEMS LIMITED
+
+OUI:08003C*
+ ID_OUI_FROM_DATABASE=SCHLUMBERGER WELL SERVICES
+
+OUI:08003D*
+ ID_OUI_FROM_DATABASE=CADNETIX CORPORATIONS
+
+OUI:08003E*
+ ID_OUI_FROM_DATABASE=CODEX CORPORATION
+
+OUI:08003F*
+ ID_OUI_FROM_DATABASE=FRED KOSCHARA ENTERPRISES
+
+OUI:080040*
+ ID_OUI_FROM_DATABASE=FERRANTI COMPUTER SYS. LIMITED
+
+OUI:080041*
+ ID_OUI_FROM_DATABASE=RACAL-MILGO INFORMATION SYS..
+
+OUI:080042*
+ ID_OUI_FROM_DATABASE=JAPAN MACNICS CORP.
+
+OUI:080043*
+ ID_OUI_FROM_DATABASE=PIXEL COMPUTER INC.
+
+OUI:080044*
+ ID_OUI_FROM_DATABASE=DAVID SYSTEMS INC.
+
+OUI:080045*
+ ID_OUI_FROM_DATABASE=CONCURRENT COMPUTER CORP.
+
+OUI:080046*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:080047*
+ ID_OUI_FROM_DATABASE=SEQUENT COMPUTER SYSTEMS INC.
+
+OUI:080048*
+ ID_OUI_FROM_DATABASE=EUROTHERM GAUGING SYSTEMS
+
+OUI:080049*
+ ID_OUI_FROM_DATABASE=UNIVATION
+
+OUI:08004A*
+ ID_OUI_FROM_DATABASE=BANYAN SYSTEMS INC.
+
+OUI:08004B*
+ ID_OUI_FROM_DATABASE=PLANNING RESEARCH CORP.
+
+OUI:08004C*
+ ID_OUI_FROM_DATABASE=HYDRA COMPUTER SYSTEMS INC.
+
+OUI:08004D*
+ ID_OUI_FROM_DATABASE=CORVUS SYSTEMS INC.
+
+OUI:08004E*
+ ID_OUI_FROM_DATABASE=3COM EUROPE LTD.
+
+OUI:08004F*
+ ID_OUI_FROM_DATABASE=CYGNET SYSTEMS
+
+OUI:080050*
+ ID_OUI_FROM_DATABASE=DAISY SYSTEMS CORP.
+
+OUI:080051*
+ ID_OUI_FROM_DATABASE=EXPERDATA
+
+OUI:080052*
+ ID_OUI_FROM_DATABASE=INSYSTEC
+
+OUI:080053*
+ ID_OUI_FROM_DATABASE=MIDDLE EAST TECH. UNIVERSITY
+
+OUI:080055*
+ ID_OUI_FROM_DATABASE=STANFORD TELECOMM. INC.
+
+OUI:080056*
+ ID_OUI_FROM_DATABASE=STANFORD LINEAR ACCEL. CENTER
+
+OUI:080057*
+ ID_OUI_FROM_DATABASE=EVANS & SUTHERLAND
+
+OUI:080058*
+ ID_OUI_FROM_DATABASE=SYSTEMS CONCEPTS
+
+OUI:080059*
+ ID_OUI_FROM_DATABASE=A/S MYCRON
+
+OUI:08005A*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:08005B*
+ ID_OUI_FROM_DATABASE=VTA TECHNOLOGIES INC.
+
+OUI:08005C*
+ ID_OUI_FROM_DATABASE=FOUR PHASE SYSTEMS
+
+OUI:08005D*
+ ID_OUI_FROM_DATABASE=GOULD INC.
+
+OUI:08005E*
+ ID_OUI_FROM_DATABASE=COUNTERPOINT COMPUTER INC.
+
+OUI:08005F*
+ ID_OUI_FROM_DATABASE=SABER TECHNOLOGY CORP.
+
+OUI:080060*
+ ID_OUI_FROM_DATABASE=INDUSTRIAL NETWORKING INC.
+
+OUI:080061*
+ ID_OUI_FROM_DATABASE=JAROGATE LTD.
+
+OUI:080062*
+ ID_OUI_FROM_DATABASE=GENERAL DYNAMICS
+
+OUI:080063*
+ ID_OUI_FROM_DATABASE=PLESSEY
+
+OUI:080064*
+ ID_OUI_FROM_DATABASE=Sitasys AG
+
+OUI:080065*
+ ID_OUI_FROM_DATABASE=GENRAD INC.
+
+OUI:080066*
+ ID_OUI_FROM_DATABASE=AGFA CORPORATION
+
+OUI:080067*
+ ID_OUI_FROM_DATABASE=COMDESIGN
+
+OUI:080068*
+ ID_OUI_FROM_DATABASE=RIDGE COMPUTERS
+
+OUI:080069*
+ ID_OUI_FROM_DATABASE=SILICON GRAPHICS INC.
+
+OUI:08006A*
+ ID_OUI_FROM_DATABASE=ATT BELL LABORATORIES
+
+OUI:08006B*
+ ID_OUI_FROM_DATABASE=ACCEL TECHNOLOGIES INC.
+
+OUI:08006C*
+ ID_OUI_FROM_DATABASE=SUNTEK TECHNOLOGY INT'L
+
+OUI:08006D*
+ ID_OUI_FROM_DATABASE=WHITECHAPEL COMPUTER WORKS
+
+OUI:08006E*
+ ID_OUI_FROM_DATABASE=MASSCOMP
+
+OUI:08006F*
+ ID_OUI_FROM_DATABASE=PHILIPS APELDOORN B.V.
+
+OUI:080070*
+ ID_OUI_FROM_DATABASE=MITSUBISHI ELECTRIC CORP.
+
+OUI:080071*
+ ID_OUI_FROM_DATABASE=MATRA (DSIE)
+
+OUI:080072*
+ ID_OUI_FROM_DATABASE=XEROX CORP UNIV GRANT PROGRAM
+
+OUI:080073*
+ ID_OUI_FROM_DATABASE=TECMAR INC.
+
+OUI:080074*
+ ID_OUI_FROM_DATABASE=CASIO COMPUTER CO. LTD.
+
+OUI:080075*
+ ID_OUI_FROM_DATABASE=DANSK DATA ELECTRONIK
+
+OUI:080076*
+ ID_OUI_FROM_DATABASE=PC LAN TECHNOLOGIES
+
+OUI:080077*
+ ID_OUI_FROM_DATABASE=TSL COMMUNICATIONS LTD.
+
+OUI:080078*
+ ID_OUI_FROM_DATABASE=ACCELL CORPORATION
+
+OUI:080079*
+ ID_OUI_FROM_DATABASE=THE DROID WORKS
+
+OUI:08007A*
+ ID_OUI_FROM_DATABASE=INDATA
+
+OUI:08007B*
+ ID_OUI_FROM_DATABASE=SANYO ELECTRIC CO. LTD.
+
+OUI:08007C*
+ ID_OUI_FROM_DATABASE=VITALINK COMMUNICATIONS CORP.
+
+OUI:08007E*
+ ID_OUI_FROM_DATABASE=AMALGAMATED WIRELESS(AUS) LTD
+
+OUI:08007F*
+ ID_OUI_FROM_DATABASE=CARNEGIE-MELLON UNIVERSITY
+
+OUI:080080*
+ ID_OUI_FROM_DATABASE=AES DATA INC.
+
+OUI:080081*
+ ID_OUI_FROM_DATABASE=,ASTECH INC.
+
+OUI:080082*
+ ID_OUI_FROM_DATABASE=VERITAS SOFTWARE
+
+OUI:080083*
+ ID_OUI_FROM_DATABASE=Seiko Instruments Inc.
+
+OUI:080084*
+ ID_OUI_FROM_DATABASE=TOMEN ELECTRONICS CORP.
+
+OUI:080085*
+ ID_OUI_FROM_DATABASE=ELXSI
+
+OUI:080086*
+ ID_OUI_FROM_DATABASE=KONICA MINOLTA HOLDINGS, INC.
+
+OUI:080087*
+ ID_OUI_FROM_DATABASE=XYPLEX
+
+OUI:080088*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:080089*
+ ID_OUI_FROM_DATABASE=KINETICS
+
+OUI:08008A*
+ ID_OUI_FROM_DATABASE=PerfTech, Inc.
+
+OUI:08008B*
+ ID_OUI_FROM_DATABASE=PYRAMID TECHNOLOGY CORP.
+
+OUI:08008C*
+ ID_OUI_FROM_DATABASE=NETWORK RESEARCH CORPORATION
+
+OUI:08008D*
+ ID_OUI_FROM_DATABASE=XYVISION INC.
+
+OUI:08008E*
+ ID_OUI_FROM_DATABASE=TANDEM COMPUTERS
+
+OUI:08008F*
+ ID_OUI_FROM_DATABASE=CHIPCOM CORPORATION
+
+OUI:080090*
+ ID_OUI_FROM_DATABASE=SONOMA SYSTEMS
+
+OUI:0808C2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:0808EA*
+ ID_OUI_FROM_DATABASE=AMSC
+
+OUI:080C0B*
+ ID_OUI_FROM_DATABASE=SysMik GmbH Dresden
+
+OUI:080CC9*
+ ID_OUI_FROM_DATABASE=Mission Technology Group, dba Magma
+
+OUI:080D84*
+ ID_OUI_FROM_DATABASE=GECO, Inc.
+
+OUI:080FFA*
+ ID_OUI_FROM_DATABASE=KSP INC.
+
+OUI:081196*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:081443*
+ ID_OUI_FROM_DATABASE=UNIBRAIN S.A.
+
+OUI:081651*
+ ID_OUI_FROM_DATABASE=Shenzhen Sea Star Technology Co.,Ltd
+
+OUI:081735*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0817F4*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:08181A*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:08184C*
+ ID_OUI_FROM_DATABASE=A. S. Thomas, Inc.
+
+OUI:0819A6*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:081DFB*
+ ID_OUI_FROM_DATABASE=Shanghai Mexon Communication Technology Co.,Ltd
+
+OUI:081F3F*
+ ID_OUI_FROM_DATABASE=WondaLink Inc.
+
+OUI:081FF3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:082522*
+ ID_OUI_FROM_DATABASE=ADVANSEE
+
+OUI:082AD0*
+ ID_OUI_FROM_DATABASE=SRD Innovations Inc.
+
+OUI:082E5F*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:08373D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:08379C*
+ ID_OUI_FROM_DATABASE=Topaz Co. LTD.
+
+OUI:0838A5*
+ ID_OUI_FROM_DATABASE=Funkwerk plettac electronic GmbH
+
+OUI:083AB8*
+ ID_OUI_FROM_DATABASE=Shinoda Plasma Co., Ltd.
+
+OUI:083E8E*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd
+
+OUI:084E1C*
+ ID_OUI_FROM_DATABASE=H2A Systems, LLC
+
+OUI:084EBF*
+ ID_OUI_FROM_DATABASE=Broad Net Mux Corporation
+
+OUI:08512E*
+ ID_OUI_FROM_DATABASE=Orion Diagnostica Oy
+
+OUI:085B0E*
+ ID_OUI_FROM_DATABASE=Fortinet, Inc.
+
+OUI:08606E*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:0868D0*
+ ID_OUI_FROM_DATABASE=Japan System Design
+
+OUI:0868EA*
+ ID_OUI_FROM_DATABASE=EITO ELECTRONICS CO., LTD.
+
+OUI:087572*
+ ID_OUI_FROM_DATABASE=Obelux Oy
+
+OUI:087618*
+ ID_OUI_FROM_DATABASE=ViE Technologies Sdn. Bhd.
+
+OUI:087695*
+ ID_OUI_FROM_DATABASE=Auto Industrial Co., Ltd.
+
+OUI:0876FF*
+ ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
+
+OUI:087999*
+ ID_OUI_FROM_DATABASE=AIM GmbH
+
+OUI:087BAA*
+ ID_OUI_FROM_DATABASE=SVYAZKOMPLEKTSERVICE, LLC
+
+OUI:087CBE*
+ ID_OUI_FROM_DATABASE=Quintic Corp.
+
+OUI:087D21*
+ ID_OUI_FROM_DATABASE=Altasec technology corporation
+
+OUI:0881F4*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:08863B*
+ ID_OUI_FROM_DATABASE=Belkin International, Inc.
+
+OUI:088DC8*
+ ID_OUI_FROM_DATABASE=Ryowa Electronics Co.,Ltd
+
+OUI:088F2C*
+ ID_OUI_FROM_DATABASE=Hills Sound Vision & Lighting
+
+OUI:089E01*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
+OUI:089F97*
+ ID_OUI_FROM_DATABASE=LEROY AUTOMATION
+
+OUI:08A12B*
+ ID_OUI_FROM_DATABASE=ShenZhen EZL Technology Co., Ltd
+
+OUI:08A95A*
+ ID_OUI_FROM_DATABASE=Azurewave
+
+OUI:08ACA5*
+ ID_OUI_FROM_DATABASE=Benu Video, Inc.
+
+OUI:08AF78*
+ ID_OUI_FROM_DATABASE=Totus Solutions, Inc.
+
+OUI:08B4CF*
+ ID_OUI_FROM_DATABASE=Abicom International
+
+OUI:08B738*
+ ID_OUI_FROM_DATABASE=Lite-On Technogy Corp.
+
+OUI:08B7EC*
+ ID_OUI_FROM_DATABASE=Wireless Seismic
+
+OUI:08BBCC*
+ ID_OUI_FROM_DATABASE=AK-NORD EDV VERTRIEBSGES. mbH
+
+OUI:08BE09*
+ ID_OUI_FROM_DATABASE=Astrol Electronic AG
+
+OUI:08D09F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:08D29A*
+ ID_OUI_FROM_DATABASE=Proformatique
+
+OUI:08D40C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:08D42B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:08D5C0*
+ ID_OUI_FROM_DATABASE=Seers Technology Co., Ltd
+
+OUI:08E5DA*
+ ID_OUI_FROM_DATABASE=NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD.
+
+OUI:08E672*
+ ID_OUI_FROM_DATABASE=JEBSEE ELECTRONICS CO.,LTD.
+
+OUI:08EA44*
+ ID_OUI_FROM_DATABASE=Aerohive Networks, Inc.
+
+OUI:08EB74*
+ ID_OUI_FROM_DATABASE=Humax
+
+OUI:08EBED*
+ ID_OUI_FROM_DATABASE=World Elite Technology Co.,LTD
+
+OUI:08EDB9*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:08F1B7*
+ ID_OUI_FROM_DATABASE=Towerstream Corpration
+
+OUI:08F2F4*
+ ID_OUI_FROM_DATABASE=Net One Partners Co.,Ltd.
+
+OUI:08F6F8*
+ ID_OUI_FROM_DATABASE=GET Engineering
+
+OUI:08FAE0*
+ ID_OUI_FROM_DATABASE=Fohhn Audio AG
+
+OUI:08FC52*
+ ID_OUI_FROM_DATABASE=OpenXS BV
+
+OUI:0C130B*
+ ID_OUI_FROM_DATABASE=Uniqoteq Ltd.
+
+OUI:0C1420*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0C15C5*
+ ID_OUI_FROM_DATABASE=SDTEC Co., Ltd.
+
+OUI:0C17F1*
+ ID_OUI_FROM_DATABASE=TELECSYS
+
+OUI:0C191F*
+ ID_OUI_FROM_DATABASE=Inform Electronik
+
+OUI:0C1DC2*
+ ID_OUI_FROM_DATABASE=SeAH Networks
+
+OUI:0C2755*
+ ID_OUI_FROM_DATABASE=Valuable Techologies Limited
+
+OUI:0C2A69*
+ ID_OUI_FROM_DATABASE=electric imp, incorporated
+
+OUI:0C37DC*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:0C3956*
+ ID_OUI_FROM_DATABASE=Observator instruments
+
+OUI:0C3C65*
+ ID_OUI_FROM_DATABASE=Dome Imaging Inc
+
+OUI:0C469D*
+ ID_OUI_FROM_DATABASE=MS Sedco
+
+OUI:0C4C39*
+ ID_OUI_FROM_DATABASE=Mitrastar Technology
+
+OUI:0C51F7*
+ ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX
+
+OUI:0C5521*
+ ID_OUI_FROM_DATABASE=Axiros GmbH
+
+OUI:0C565C*
+ ID_OUI_FROM_DATABASE=HyBroad Vision (Hong Kong) Technology Co Ltd
+
+OUI:0C57EB*
+ ID_OUI_FROM_DATABASE=Mueller Systems
+
+OUI:0C5A19*
+ ID_OUI_FROM_DATABASE=Axtion Sdn Bhd
+
+OUI:0C6076*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:0C6E4F*
+ ID_OUI_FROM_DATABASE=PrimeVOLT Co., Ltd.
+
+OUI:0C715D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0C722C*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:0C74C2*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:0C7523*
+ ID_OUI_FROM_DATABASE=BEIJING GEHUA CATV NETWORK CO.,LTD
+
+OUI:0C771A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:0C7D7C*
+ ID_OUI_FROM_DATABASE=Kexiang Information Technology Co, Ltd.
+
+OUI:0C8230*
+ ID_OUI_FROM_DATABASE=SHENZHEN MAGNUS TECHNOLOGIES CO.,LTD
+
+OUI:0C826A*
+ ID_OUI_FROM_DATABASE=Wuhan Huagong Genuine Optics Technology Co., Ltd
+
+OUI:0C8411*
+ ID_OUI_FROM_DATABASE=A.O. Smith Water Products
+
+OUI:0C8525*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0C8BFD*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0C8CDC*
+ ID_OUI_FROM_DATABASE=Suunto Oy
+
+OUI:0C8D98*
+ ID_OUI_FROM_DATABASE=TOP EIGHT IND CORP
+
+OUI:0C924E*
+ ID_OUI_FROM_DATABASE=Rice Lake Weighing Systems
+
+OUI:0C93FB*
+ ID_OUI_FROM_DATABASE=BNS Solutions
+
+OUI:0C9D56*
+ ID_OUI_FROM_DATABASE=Consort Controls Ltd
+
+OUI:0C9E91*
+ ID_OUI_FROM_DATABASE=Sankosha Corporation
+
+OUI:0CA138*
+ ID_OUI_FROM_DATABASE=Blinq Wireless Inc.
+
+OUI:0CA2F4*
+ ID_OUI_FROM_DATABASE=Chameleon Technology (UK) Limited
+
+OUI:0CA402*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent IPD
+
+OUI:0CA42A*
+ ID_OUI_FROM_DATABASE=OB Telecom Electronic Technology Co., Ltd
+
+OUI:0CAF5A*
+ ID_OUI_FROM_DATABASE=GENUS POWER INFRASTRUCTURES LIMITED
+
+OUI:0CB4EF*
+ ID_OUI_FROM_DATABASE=Digience Co.,Ltd.
+
+OUI:0CBF15*
+ ID_OUI_FROM_DATABASE=Genetec
+
+OUI:0CC0C0*
+ ID_OUI_FROM_DATABASE=MAGNETI MARELLI SISTEMAS ELECTRONICOS MEXICO
+
+OUI:0CC3A7*
+ ID_OUI_FROM_DATABASE=Meritec
+
+OUI:0CC47E*
+ ID_OUI_FROM_DATABASE=EUCAST Co., Ltd.
+
+OUI:0CC655*
+ ID_OUI_FROM_DATABASE=Wuxi YSTen Technology Co.,Ltd.
+
+OUI:0CC66A*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:0CC6AC*
+ ID_OUI_FROM_DATABASE=DAGS
+
+OUI:0CC9C6*
+ ID_OUI_FROM_DATABASE=Samwin Hong Kong Limited
+
+OUI:0CCDD3*
+ ID_OUI_FROM_DATABASE=EASTRIVER TECHNOLOGY CO., LTD.
+
+OUI:0CCDFB*
+ ID_OUI_FROM_DATABASE=EDIC Systems Inc.
+
+OUI:0CD292*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0CD2B5*
+ ID_OUI_FROM_DATABASE=Binatone Telecommunication Pvt. Ltd
+
+OUI:0CD502*
+ ID_OUI_FROM_DATABASE=Westell
+
+OUI:0CD696*
+ ID_OUI_FROM_DATABASE=Amimon Ltd
+
+OUI:0CD7C2*
+ ID_OUI_FROM_DATABASE=Axium Technologies, Inc.
+
+OUI:0CD996*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:0CD9C1*
+ ID_OUI_FROM_DATABASE=Johnson Controls-ASG
+
+OUI:0CDA41*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:0CDCCC*
+ ID_OUI_FROM_DATABASE=Inala Technologies
+
+OUI:0CDDEF*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:0CDFA4*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0CE5D3*
+ ID_OUI_FROM_DATABASE=DH electronics GmbH
+
+OUI:0CE709*
+ ID_OUI_FROM_DATABASE=Fox Crypto B.V.
+
+OUI:0CE82F*
+ ID_OUI_FROM_DATABASE=Bonfiglioli Vectron GmbH
+
+OUI:0CE936*
+ ID_OUI_FROM_DATABASE=ELIMOS srl
+
+OUI:0CEEE6*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:0CEF7C*
+ ID_OUI_FROM_DATABASE=AnaCom Inc
+
+OUI:0CF0B4*
+ ID_OUI_FROM_DATABASE=Globalsat International Technology Ltd
+
+OUI:0CF361*
+ ID_OUI_FROM_DATABASE=Java Information
+
+OUI:0CF3EE*
+ ID_OUI_FROM_DATABASE=EM Microelectronic
+
+OUI:0CF893*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0CFC83*
+ ID_OUI_FROM_DATABASE=Airoha Technology Corp.,
+
+OUI:10005A*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:1000E8*
+ ID_OUI_FROM_DATABASE=NATIONAL SEMICONDUCTOR
+
+OUI:1000FD*
+ ID_OUI_FROM_DATABASE=LaonPeople
+
+OUI:10090C*
+ ID_OUI_FROM_DATABASE=Janome Sewing Machine Co., Ltd.
+
+OUI:100BA9*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:100C24*
+ ID_OUI_FROM_DATABASE=pomdevices, LLC
+
+OUI:100D2F*
+ ID_OUI_FROM_DATABASE=Online Security Pty. Ltd.
+
+OUI:100D32*
+ ID_OUI_FROM_DATABASE=Embedian, Inc.
+
+OUI:100D7F*
+ ID_OUI_FROM_DATABASE=NETGEAR INC.,
+
+OUI:100E2B*
+ ID_OUI_FROM_DATABASE=NEC CASIO Mobile Communications
+
+OUI:1010B6*
+ ID_OUI_FROM_DATABASE=McCain Inc
+
+OUI:101212*
+ ID_OUI_FROM_DATABASE=Vivo International Corporation Pty Ltd
+
+OUI:101248*
+ ID_OUI_FROM_DATABASE=ITG, Inc.
+
+OUI:1013EE*
+ ID_OUI_FROM_DATABASE=Justec International Technology INC.
+
+OUI:10189E*
+ ID_OUI_FROM_DATABASE=Elmo Motion Control
+
+OUI:101B54*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:101D51*
+ ID_OUI_FROM_DATABASE=ON-Q LLC dba ON-Q Mesh Networks
+
+OUI:101DC0*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:101F74*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:102D96*
+ ID_OUI_FROM_DATABASE=Looxcie Inc.
+
+OUI:102EAF*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:103711*
+ ID_OUI_FROM_DATABASE=Simlink AS
+
+OUI:103DEA*
+ ID_OUI_FROM_DATABASE=HFC Technology (Beijing) Ltd. Co.
+
+OUI:1040F3*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:104369*
+ ID_OUI_FROM_DATABASE=Soundmax Electronic Limited
+
+OUI:10445A*
+ ID_OUI_FROM_DATABASE=Shaanxi Hitech Electronic Co., LTD
+
+OUI:1045BE*
+ ID_OUI_FROM_DATABASE=Norphonic AS
+
+OUI:1045F8*
+ ID_OUI_FROM_DATABASE=LNT-Automation GmbH
+
+OUI:104780*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:1048B1*
+ ID_OUI_FROM_DATABASE=Beijing Duokan Technology Limited
+
+OUI:104D77*
+ ID_OUI_FROM_DATABASE=Innovative Computer Engineering
+
+OUI:1056CA*
+ ID_OUI_FROM_DATABASE=Peplink International Ltd.
+
+OUI:105CBF*
+ ID_OUI_FROM_DATABASE=DuroByte Inc
+
+OUI:105F06*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:105F49*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:10604B*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:1062C9*
+ ID_OUI_FROM_DATABASE=Adatis GmbH & Co. KG
+
+OUI:1064E2*
+ ID_OUI_FROM_DATABASE=ADFweb.com s.r.l.
+
+OUI:1065A3*
+ ID_OUI_FROM_DATABASE=Panamax Inc.
+
+OUI:1065CF*
+ ID_OUI_FROM_DATABASE=IQSIM
+
+OUI:10683F*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:106F3F*
+ ID_OUI_FROM_DATABASE=Buffalo Inc.
+
+OUI:106FEF*
+ ID_OUI_FROM_DATABASE=Ad-Sol Nissin Corp
+
+OUI:1071F9*
+ ID_OUI_FROM_DATABASE=Cloud Telecomputers, LLC
+
+OUI:10768A*
+ ID_OUI_FROM_DATABASE=EoCell
+
+OUI:1078D2*
+ ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD.
+
+OUI:1083D2*
+ ID_OUI_FROM_DATABASE=Microseven Systems, LLC
+
+OUI:10880F*
+ ID_OUI_FROM_DATABASE=Daruma Telecomunicações e Informática S.A.
+
+OUI:108CCF*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:1093E9*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:109ADD*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:109FA9*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:10A13B*
+ ID_OUI_FROM_DATABASE=FUJIKURA RUBBER LTD.
+
+OUI:10A743*
+ ID_OUI_FROM_DATABASE=SK Mtek Limited
+
+OUI:10A932*
+ ID_OUI_FROM_DATABASE=Beijing Cyber Cloud Technology Co. ,Ltd.
+
+OUI:10B7F6*
+ ID_OUI_FROM_DATABASE=Plastoform Industries Ltd.
+
+OUI:10B9FE*
+ ID_OUI_FROM_DATABASE=Lika srl
+
+OUI:10BAA5*
+ ID_OUI_FROM_DATABASE=GANA I&C CO., LTD
+
+OUI:10BD18*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:10BF48*
+ ID_OUI_FROM_DATABASE=ASUSTEK COMPUTER INC.
+
+OUI:10C2BA*
+ ID_OUI_FROM_DATABASE=UTT Co., Ltd.
+
+OUI:10C586*
+ ID_OUI_FROM_DATABASE=BIO SOUND LAB CO., LTD.
+
+OUI:10C61F*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:10C6FC*
+ ID_OUI_FROM_DATABASE=Garmin International
+
+OUI:10C73F*
+ ID_OUI_FROM_DATABASE=Midas Klark Teknik Ltd
+
+OUI:10CA81*
+ ID_OUI_FROM_DATABASE=PRECIA
+
+OUI:10CCDB*
+ ID_OUI_FROM_DATABASE=AXIMUM PRODUITS ELECTRONIQUES
+
+OUI:10D1DC*
+ ID_OUI_FROM_DATABASE=INSTAR Deutschland GmbH
+
+OUI:10DDB1*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:10E2D5*
+ ID_OUI_FROM_DATABASE=Qi Hardware Inc.
+
+OUI:10E3C7*
+ ID_OUI_FROM_DATABASE=Seohwa Telecom
+
+OUI:10E4AF*
+ ID_OUI_FROM_DATABASE=APR, LLC
+
+OUI:10E6AE*
+ ID_OUI_FROM_DATABASE=Source Technologies, LLC
+
+OUI:10E8EE*
+ ID_OUI_FROM_DATABASE=PhaseSpace
+
+OUI:10EA59*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:10EED9*
+ ID_OUI_FROM_DATABASE=Canoga Perkins Corporation
+
+OUI:10F3DB*
+ ID_OUI_FROM_DATABASE=Gridco Systems, Inc.
+
+OUI:10F49A*
+ ID_OUI_FROM_DATABASE=T3 Innovation
+
+OUI:10F96F*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:10F9EE*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:10FBF0*
+ ID_OUI_FROM_DATABASE=KangSheng LTD.
+
+OUI:10FC54*
+ ID_OUI_FROM_DATABASE=Shany Electronic Co., Ltd.
+
+OUI:10FEED*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:1407E0*
+ ID_OUI_FROM_DATABASE=Abrantix AG
+
+OUI:140C76*
+ ID_OUI_FROM_DATABASE=FREEBOX SAS
+
+OUI:14109F*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:14144B*
+ ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD
+
+OUI:141A51*
+ ID_OUI_FROM_DATABASE=Treetech Sistemas Digitais
+
+OUI:141BBD*
+ ID_OUI_FROM_DATABASE=Volex Inc.
+
+OUI:141BF0*
+ ID_OUI_FROM_DATABASE=Intellimedia Systems Ltd
+
+OUI:142DF5*
+ ID_OUI_FROM_DATABASE=Amphitech
+
+OUI:14307A*
+ ID_OUI_FROM_DATABASE=Avermetrics
+
+OUI:14358B*
+ ID_OUI_FROM_DATABASE=Mediabridge Products, LLC.
+
+OUI:1435B3*
+ ID_OUI_FROM_DATABASE=Future Designs, Inc.
+
+OUI:143605*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:14373B*
+ ID_OUI_FROM_DATABASE=PROCOM Systems
+
+OUI:143AEA*
+ ID_OUI_FROM_DATABASE=Dynapower Company LLC
+
+OUI:143E60*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:144319*
+ ID_OUI_FROM_DATABASE=Creative&Link Technology Limited
+
+OUI:144978*
+ ID_OUI_FROM_DATABASE=Digital Control Incorporated
+
+OUI:144C1A*
+ ID_OUI_FROM_DATABASE=Max Communication GmbH
+
+OUI:145412*
+ ID_OUI_FROM_DATABASE=Entis Co., Ltd.
+
+OUI:145A05*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:145BD1*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:146308*
+ ID_OUI_FROM_DATABASE=JABIL CIRCUIT (SHANGHAI) LTD.
+
+OUI:146A0B*
+ ID_OUI_FROM_DATABASE=Cypress Electronics Limited
+
+OUI:147373*
+ ID_OUI_FROM_DATABASE=TUBITAK UEKAE
+
+OUI:147411*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:147DB3*
+ ID_OUI_FROM_DATABASE=JOA TELECOM.CO.,LTD
+
+OUI:147DC5*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:14825B*
+ ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd
+
+OUI:1489FD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:148A70*
+ ID_OUI_FROM_DATABASE=ADS GmbH
+
+OUI:148FC6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:149090*
+ ID_OUI_FROM_DATABASE=KongTop industrial(shen zhen)CO.,LTD
+
+OUI:149FE8*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
+OUI:14A62C*
+ ID_OUI_FROM_DATABASE=S.M. Dezac S.A.
+
+OUI:14A86B*
+ ID_OUI_FROM_DATABASE=ShenZhen Telacom Science&Technology Co., Ltd
+
+OUI:14A9E3*
+ ID_OUI_FROM_DATABASE=MST CORPORATION
+
+OUI:14B1C8*
+ ID_OUI_FROM_DATABASE=InfiniWing, Inc.
+
+OUI:14B73D*
+ ID_OUI_FROM_DATABASE=ARCHEAN Technologies
+
+OUI:14C21D*
+ ID_OUI_FROM_DATABASE=Sabtech Industries
+
+OUI:14CF8D*
+ ID_OUI_FROM_DATABASE=OHSUNG ELECTRONICS CO., LTD.
+
+OUI:14CF92*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:14D4FE*
+ ID_OUI_FROM_DATABASE=Pace plc
+
+OUI:14D64D*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:14D76E*
+ ID_OUI_FROM_DATABASE=CONCH ELECTRONIC Co.,Ltd
+
+OUI:14DAE9*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:14DB85*
+ ID_OUI_FROM_DATABASE=S NET MEDIA
+
+OUI:14E4EC*
+ ID_OUI_FROM_DATABASE=mLogic LLC
+
+OUI:14E6E4*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:14EB33*
+ ID_OUI_FROM_DATABASE=BSMediasoft Co., Ltd.
+
+OUI:14EE9D*
+ ID_OUI_FROM_DATABASE=AirNav Systems LLC
+
+OUI:14F0C5*
+ ID_OUI_FROM_DATABASE=Xtremio Ltd.
+
+OUI:14F42A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:14FEAF*
+ ID_OUI_FROM_DATABASE=SAGITTAR LIMITED
+
+OUI:14FEB5*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:18002D*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
+OUI:1801E3*
+ ID_OUI_FROM_DATABASE=Elektrobit Wireless Communications Ltd
+
+OUI:180373*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:1803FA*
+ ID_OUI_FROM_DATABASE=IBT Interfaces
+
+OUI:180675*
+ ID_OUI_FROM_DATABASE=DILAX Intelcom GmbH
+
+OUI:180B52*
+ ID_OUI_FROM_DATABASE=Nanotron Technologies GmbH
+
+OUI:180C77*
+ ID_OUI_FROM_DATABASE=Westinghouse Electric Company, LLC
+
+OUI:180CAC*
+ ID_OUI_FROM_DATABASE=CANON INC.
+
+OUI:181420*
+ ID_OUI_FROM_DATABASE=TEB SAS
+
+OUI:181456*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:181714*
+ ID_OUI_FROM_DATABASE=DAEWOOIS
+
+OUI:181725*
+ ID_OUI_FROM_DATABASE=Cameo Communications, Inc.
+
+OUI:18193F*
+ ID_OUI_FROM_DATABASE=Tamtron Oy
+
+OUI:182032*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:182861*
+ ID_OUI_FROM_DATABASE=AirTies Wireless Networks
+
+OUI:182A7B*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:182B05*
+ ID_OUI_FROM_DATABASE=8D Technologies
+
+OUI:182C91*
+ ID_OUI_FROM_DATABASE=Concept Development, Inc.
+
+OUI:18339D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:183451*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:183825*
+ ID_OUI_FROM_DATABASE=Wuhan Lingjiu High-tech Co.,Ltd.
+
+OUI:183919*
+ ID_OUI_FROM_DATABASE=Unicoi Systems
+
+OUI:183BD2*
+ ID_OUI_FROM_DATABASE=BYD Precision Manufacture Company Ltd.
+
+OUI:183DA2*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:183F47*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:18422F*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent
+
+OUI:184617*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:1848D8*
+ ID_OUI_FROM_DATABASE=Fastback Networks
+
+OUI:184E94*
+ ID_OUI_FROM_DATABASE=MESSOA TECHNOLOGIES INC.
+
+OUI:185253*
+ ID_OUI_FROM_DATABASE=Pixord Corporation
+
+OUI:1853E0*
+ ID_OUI_FROM_DATABASE=Hanyang Digitech Co.Ltd
+
+OUI:18550F*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:185933*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:185AE8*
+ ID_OUI_FROM_DATABASE=Zenotech.Co.,Ltd
+
+OUI:1866E3*
+ ID_OUI_FROM_DATABASE=Veros Systems, Inc.
+
+OUI:18673F*
+ ID_OUI_FROM_DATABASE=Hanover Displays Limited
+
+OUI:186751*
+ ID_OUI_FROM_DATABASE=KOMEG Industrielle Messtechnik GmbH
+
+OUI:1867B0*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
+OUI:186D99*
+ ID_OUI_FROM_DATABASE=Adanis Inc.
+
+OUI:187A93*
+ ID_OUI_FROM_DATABASE=AMICCOM Electronics Corporation
+
+OUI:187C81*
+ ID_OUI_FROM_DATABASE=Valeo Vision Systems
+
+OUI:1880CE*
+ ID_OUI_FROM_DATABASE=Barberry Solutions Ltd
+
+OUI:1880F5*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:18863A*
+ ID_OUI_FROM_DATABASE=DIGITAL ART SYSTEM
+
+OUI:1886AC*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:188796*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:188ED5*
+ ID_OUI_FROM_DATABASE=Philips Innovative Application NV
+
+OUI:18922C*
+ ID_OUI_FROM_DATABASE=Virtual Instruments
+
+OUI:1897FF*
+ ID_OUI_FROM_DATABASE=TechFaith Wireless Technology Limited
+
+OUI:189A67*
+ ID_OUI_FROM_DATABASE=CSE-Servelec Limited
+
+OUI:189EFC*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:18A905*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:18ABF5*
+ ID_OUI_FROM_DATABASE=Ultra Electronics - Electrics
+
+OUI:18AD4D*
+ ID_OUI_FROM_DATABASE=Polostar Technology Corporation
+
+OUI:18AEBB*
+ ID_OUI_FROM_DATABASE=Siemens Programm- und Systementwicklung GmbH&Co.KG
+
+OUI:18AF9F*
+ ID_OUI_FROM_DATABASE=DIGITRONIC Automationsanlagen GmbH
+
+OUI:18B209*
+ ID_OUI_FROM_DATABASE=Torrey Pines Logic, Inc
+
+OUI:18B3BA*
+ ID_OUI_FROM_DATABASE=Netlogic AB
+
+OUI:18B430*
+ ID_OUI_FROM_DATABASE=Nest Labs Inc.
+
+OUI:18B591*
+ ID_OUI_FROM_DATABASE=I-Storm
+
+OUI:18B79E*
+ ID_OUI_FROM_DATABASE=Invoxia
+
+OUI:18C086*
+ ID_OUI_FROM_DATABASE=Broadcom Corporation
+
+OUI:18C451*
+ ID_OUI_FROM_DATABASE=Tucson Embedded Systems
+
+OUI:18D071*
+ ID_OUI_FROM_DATABASE=DASAN SMC, Inc.
+
+OUI:18D66A*
+ ID_OUI_FROM_DATABASE=Inmarsat
+
+OUI:18D949*
+ ID_OUI_FROM_DATABASE=Qvis Labs, LLC
+
+OUI:18DC56*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt
+
+OUI:18E288*
+ ID_OUI_FROM_DATABASE=STT Condigi
+
+OUI:18E2C2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:18E7F4*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:18E80F*
+ ID_OUI_FROM_DATABASE=Viking Electronics Inc.
+
+OUI:18EF63*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:18F46A*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:18F650*
+ ID_OUI_FROM_DATABASE=Multimedia Pacific Limited
+
+OUI:18F87A*
+ ID_OUI_FROM_DATABASE=i3 International Inc.
+
+OUI:18FC9F*
+ ID_OUI_FROM_DATABASE=Changhe Electronics Co., Ltd.
+
+OUI:1C0656*
+ ID_OUI_FROM_DATABASE=IDY Corporation
+
+OUI:1C0B52*
+ ID_OUI_FROM_DATABASE=EPICOM S.A
+
+OUI:1C0FCF*
+ ID_OUI_FROM_DATABASE=Sypro Optics GmbH
+
+OUI:1C11E1*
+ ID_OUI_FROM_DATABASE=Wartsila Finland Oy
+
+OUI:1C129D*
+ ID_OUI_FROM_DATABASE=IEEE PES PSRC/SUB
+
+OUI:1C1448*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:1C17D3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:1C184A*
+ ID_OUI_FROM_DATABASE=ShenZhen RicherLink Technologies Co.,LTD
+
+OUI:1C19DE*
+ ID_OUI_FROM_DATABASE=eyevis GmbH
+
+OUI:1C1D67*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:1C334D*
+ ID_OUI_FROM_DATABASE=ITS Telecom
+
+OUI:1C3477*
+ ID_OUI_FROM_DATABASE=Innovation Wireless
+
+OUI:1C35F1*
+ ID_OUI_FROM_DATABASE=NEW Lift Neue Elektronische Wege Steuerungsbau GmbH
+
+OUI:1C3A4F*
+ ID_OUI_FROM_DATABASE=AccuSpec Electronics, LLC
+
+OUI:1C3DE7*
+ ID_OUI_FROM_DATABASE=Sigma Koki Co.,Ltd.
+
+OUI:1C43EC*
+ ID_OUI_FROM_DATABASE=JAPAN CIRCUIT CO.,LTD
+
+OUI:1C4593*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:1C4BD6*
+ ID_OUI_FROM_DATABASE=AzureWave
+
+OUI:1C51B5*
+ ID_OUI_FROM_DATABASE=Techaya LTD
+
+OUI:1C52D6*
+ ID_OUI_FROM_DATABASE=FLAT DISPLAY TECHNOLOGY CORPORATION
+
+OUI:1C5A3E*
+ ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd (Visual Display Divison)
+
+OUI:1C5A6B*
+ ID_OUI_FROM_DATABASE=Philips Electronics Nederland BV
+
+OUI:1C5C55*
+ ID_OUI_FROM_DATABASE=PRIMA Cinema, Inc
+
+OUI:1C5C60*
+ ID_OUI_FROM_DATABASE=Shenzhen Belzon Technology Co.,LTD.
+
+OUI:1C5FFF*
+ ID_OUI_FROM_DATABASE=Beijing Ereneben Information Technology Co.,Ltd Shenzhen Branch
+
+OUI:1C62B8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:1C659D*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:1C666D*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd
+
+OUI:1C66AA*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:1C69A5*
+ ID_OUI_FROM_DATABASE=Research In Motion
+
+OUI:1C6BCA*
+ ID_OUI_FROM_DATABASE=Mitsunami Co., Ltd.
+
+OUI:1C6F65*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:1C7508*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:1C7C11*
+ ID_OUI_FROM_DATABASE=EID
+
+OUI:1C7C45*
+ ID_OUI_FROM_DATABASE=Vitek Industrial Video Products, Inc.
+
+OUI:1C7EE5*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:1C83B0*
+ ID_OUI_FROM_DATABASE=Linked IP GmbH
+
+OUI:1C8464*
+ ID_OUI_FROM_DATABASE=FORMOSA WIRELESS COMMUNICATION CORP.
+
+OUI:1C8E8E*
+ ID_OUI_FROM_DATABASE=DB Communication & Systems Co., ltd.
+
+OUI:1C8F8A*
+ ID_OUI_FROM_DATABASE=Phase Motion Control SpA
+
+OUI:1C9179*
+ ID_OUI_FROM_DATABASE=Integrated System Technologies Ltd
+
+OUI:1C9492*
+ ID_OUI_FROM_DATABASE=RUAG Schweiz AG
+
+OUI:1C955D*
+ ID_OUI_FROM_DATABASE=I-LAX ELECTRONICS INC.
+
+OUI:1C959F*
+ ID_OUI_FROM_DATABASE=Veethree Electronics And Marine LLC
+
+OUI:1C973D*
+ ID_OUI_FROM_DATABASE=PRICOM Design
+
+OUI:1CAA07*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:1CABA7*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:1CAFF7*
+ ID_OUI_FROM_DATABASE=D-LINK INTERNATIONAL PTE LIMITED
+
+OUI:1CB094*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:1CB17F*
+ ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+
+OUI:1CB243*
+ ID_OUI_FROM_DATABASE=TDC A/S
+
+OUI:1CBBA8*
+ ID_OUI_FROM_DATABASE=OJSC "Ufimskiy Zavod "Promsvyaz"
+
+OUI:1CBD0E*
+ ID_OUI_FROM_DATABASE=Amplified Engineering Pty Ltd
+
+OUI:1CBDB9*
+ ID_OUI_FROM_DATABASE=D-LINK INTERNATIONAL PTE LIMITED
+
+OUI:1CC1DE*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:1CC316*
+ ID_OUI_FROM_DATABASE=MileSight Technology Co., Ltd.
+
+OUI:1CC63C*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:1CD40C*
+ ID_OUI_FROM_DATABASE=Kriwan Industrie-Elektronik GmbH
+
+OUI:1CDF0F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:1CE165*
+ ID_OUI_FROM_DATABASE=Marshal Corporation
+
+OUI:1CE192*
+ ID_OUI_FROM_DATABASE=Qisda Corporation
+
+OUI:1CE2CC*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:1CE6C7*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:1CF061*
+ ID_OUI_FROM_DATABASE=SCAPS GmbH
+
+OUI:1CF5E7*
+ ID_OUI_FROM_DATABASE=Turtle Industry Co., Ltd.
+
+OUI:1CFEA7*
+ ID_OUI_FROM_DATABASE=IDentytech Solutins Ltd.
+
+OUI:20014F*
+ ID_OUI_FROM_DATABASE=Linea Research Ltd
+
+OUI:2002AF*
+ ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd.
+
+OUI:200505*
+ ID_OUI_FROM_DATABASE=RADMAX COMMUNICATION PRIVATE LIMITED
+
+OUI:2005E8*
+ ID_OUI_FROM_DATABASE=OOO "InProMedia"
+
+OUI:200A5E*
+ ID_OUI_FROM_DATABASE=Xiangshan Giant Eagle Technology Developing co.,LTD
+
+OUI:20107A*
+ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+
+OUI:201257*
+ ID_OUI_FROM_DATABASE=Most Lucky Trading Ltd
+
+OUI:2013E0*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:2016D8*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:201A06*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:2021A5*
+ ID_OUI_FROM_DATABASE=LG Electronics Inc
+
+OUI:202598*
+ ID_OUI_FROM_DATABASE=Teleview
+
+OUI:202BC1*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:202CB7*
+ ID_OUI_FROM_DATABASE=Kong Yue Electronics & Information Industry (Xinhui) Ltd.
+
+OUI:203706*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:2037BC*
+ ID_OUI_FROM_DATABASE=Kuipers Electronic Engineering BV
+
+OUI:203A07*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:204005*
+ ID_OUI_FROM_DATABASE=feno GmbH
+
+OUI:20415A*
+ ID_OUI_FROM_DATABASE=Smarteh d.o.o.
+
+OUI:20443A*
+ ID_OUI_FROM_DATABASE=Schneider Electric Asia Pacific Ltd
+
+OUI:2046A1*
+ ID_OUI_FROM_DATABASE=VECOW Co., Ltd
+
+OUI:2046F9*
+ ID_OUI_FROM_DATABASE=Advanced Network Devices (dba:AND)
+
+OUI:204AAA*
+ ID_OUI_FROM_DATABASE=Hanscan Spain S.A.
+
+OUI:204E6B*
+ ID_OUI_FROM_DATABASE=Axxana(israel) ltd
+
+OUI:204E7F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:205476*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
+OUI:2059A0*
+ ID_OUI_FROM_DATABASE=Paragon Technologies Inc.
+
+OUI:205B5E*
+ ID_OUI_FROM_DATABASE=Shenzhen Wonhe Technology Co., Ltd
+
+OUI:206432*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO.,LTD.
+
+OUI:2067B1*
+ ID_OUI_FROM_DATABASE=Pluto inc.
+
+OUI:20689D*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:206A8A*
+ ID_OUI_FROM_DATABASE=Wistron InfoComm Manufacturing(Kunshan)Co.,Ltd.
+
+OUI:206AFF*
+ ID_OUI_FROM_DATABASE=Atlas Elektronik UK Limited
+
+OUI:206FEC*
+ ID_OUI_FROM_DATABASE=Braemac CA LLC
+
+OUI:207355*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2074CF*
+ ID_OUI_FROM_DATABASE=Shenzhen Voxtech Co.,Ltd
+
+OUI:207600*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:207C8F*
+ ID_OUI_FROM_DATABASE=Quanta Microsystems,Inc.
+
+OUI:207D74*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:20858C*
+ ID_OUI_FROM_DATABASE=Assa
+
+OUI:208984*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD
+
+OUI:20918A*
+ ID_OUI_FROM_DATABASE=PROFALUX
+
+OUI:2091D9*
+ ID_OUI_FROM_DATABASE=I'M SPA
+
+OUI:209BA5*
+ ID_OUI_FROM_DATABASE=JIAXING GLEAD Electronics Co.,Ltd
+
+OUI:20A2E7*
+ ID_OUI_FROM_DATABASE=Lee-Dickens Ltd
+
+OUI:20AA25*
+ ID_OUI_FROM_DATABASE=IP-NET LLC
+
+OUI:20AA4B*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:20B0F7*
+ ID_OUI_FROM_DATABASE=Enclustra GmbH
+
+OUI:20B399*
+ ID_OUI_FROM_DATABASE=Enterasys
+
+OUI:20B5C6*
+ ID_OUI_FROM_DATABASE=Mimosa Networks
+
+OUI:20B7C0*
+ ID_OUI_FROM_DATABASE=Omicron electronics GmbH
+
+OUI:20BBC0*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:20BBC6*
+ ID_OUI_FROM_DATABASE=Jabil Circuit Hungary Ltd.
+
+OUI:20BFDB*
+ ID_OUI_FROM_DATABASE=DVL
+
+OUI:20C1AF*
+ ID_OUI_FROM_DATABASE=i Wit Digital Co., Limited
+
+OUI:20C8B3*
+ ID_OUI_FROM_DATABASE=SHENZHEN BUL-TECH CO.,LTD.
+
+OUI:20C9D0*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:20CF30*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:20D5AB*
+ ID_OUI_FROM_DATABASE=Korea Infocom Co.,Ltd.
+
+OUI:20D5BF*
+ ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd
+
+OUI:20D607*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:20D906*
+ ID_OUI_FROM_DATABASE=Iota, Inc.
+
+OUI:20DC93*
+ ID_OUI_FROM_DATABASE=Cheetah Hi-Tech, Inc.
+
+OUI:20DCE6*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:20E52A*
+ ID_OUI_FROM_DATABASE=NETGEAR INC.,
+
+OUI:20E564*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:20EEC6*
+ ID_OUI_FROM_DATABASE=Elefirst Science & Tech Co ., ltd
+
+OUI:20F002*
+ ID_OUI_FROM_DATABASE=MTData Developments Pty. Ltd.
+
+OUI:20F3A3*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:20F85E*
+ ID_OUI_FROM_DATABASE=Delta Electronics
+
+OUI:20FABB*
+ ID_OUI_FROM_DATABASE=Cambridge Executive Limited
+
+OUI:20FDF1*
+ ID_OUI_FROM_DATABASE=3COM EUROPE LTD
+
+OUI:20FECD*
+ ID_OUI_FROM_DATABASE=System In Frontier Inc.
+
+OUI:20FEDB*
+ ID_OUI_FROM_DATABASE=M2M Solution S.A.S.
+
+OUI:2401C7*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:240917*
+ ID_OUI_FROM_DATABASE=Devlin Electronics Limited
+
+OUI:240B2A*
+ ID_OUI_FROM_DATABASE=Viettel Group
+
+OUI:240BB1*
+ ID_OUI_FROM_DATABASE=KOSTAL Industrie Elektrik GmbH
+
+OUI:241064*
+ ID_OUI_FROM_DATABASE=Shenzhen Ecsino Tecnical Co. Ltd
+
+OUI:241125*
+ ID_OUI_FROM_DATABASE=Hutek Co., Ltd.
+
+OUI:2411D0*
+ ID_OUI_FROM_DATABASE=Chongqing Ehs Science and Technology Development Co.,Ltd.
+
+OUI:241A8C*
+ ID_OUI_FROM_DATABASE=Squarehead Technology AS
+
+OUI:241B13*
+ ID_OUI_FROM_DATABASE=Shanghai Nutshell Electronic Co., Ltd.
+
+OUI:241F2C*
+ ID_OUI_FROM_DATABASE=Calsys, Inc.
+
+OUI:2421AB*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+OUI:242FFA*
+ ID_OUI_FROM_DATABASE=Toshiba Global Commerce Solutions
+
+OUI:24374C*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:2437EF*
+ ID_OUI_FROM_DATABASE=EMC Electronic Media Communication SA
+
+OUI:243C20*
+ ID_OUI_FROM_DATABASE=Dynamode Group
+
+OUI:244597*
+ ID_OUI_FROM_DATABASE=GEMUE Gebr. Mueller Apparatebau
+
+OUI:24470E*
+ ID_OUI_FROM_DATABASE=PentronicAB
+
+OUI:24497B*
+ ID_OUI_FROM_DATABASE=Innovative Converged Devices Inc
+
+OUI:245FDF*
+ ID_OUI_FROM_DATABASE=KYOCERA Corporation
+
+OUI:246511*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:24694A*
+ ID_OUI_FROM_DATABASE=Jasmine Systems Inc.
+
+OUI:2469A5*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:24767D*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:247703*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:24828A*
+ ID_OUI_FROM_DATABASE=Prowave Technologies Ltd.
+
+OUI:2486F4*
+ ID_OUI_FROM_DATABASE=Ctek, Inc.
+
+OUI:248707*
+ ID_OUI_FROM_DATABASE=SEnergy Corporation
+
+OUI:249442*
+ ID_OUI_FROM_DATABASE=OPEN ROAD SOLUTIONS , INC.
+
+OUI:24A42C*
+ ID_OUI_FROM_DATABASE=KOUKAAM a.s.
+
+OUI:24A43C*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks, INC
+
+OUI:24A937*
+ ID_OUI_FROM_DATABASE=PURE Storage
+
+OUI:24AB81*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:24AF4A*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD
+
+OUI:24AF54*
+ ID_OUI_FROM_DATABASE=NEXGEN Mediatech Inc.
+
+OUI:24B657*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:24B6B8*
+ ID_OUI_FROM_DATABASE=FRIEM SPA
+
+OUI:24B6FD*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:24B88C*
+ ID_OUI_FROM_DATABASE=Crenus Co.,Ltd.
+
+OUI:24B8D2*
+ ID_OUI_FROM_DATABASE=Opzoon Technology Co.,Ltd.
+
+OUI:24BA30*
+ ID_OUI_FROM_DATABASE=Technical Consumer Products, Inc.
+
+OUI:24BBC1*
+ ID_OUI_FROM_DATABASE=Absolute Analysis
+
+OUI:24BC82*
+ ID_OUI_FROM_DATABASE=Dali Wireless, Inc.
+
+OUI:24BE05*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:24C0B3*
+ ID_OUI_FROM_DATABASE=RSF
+
+OUI:24C86E*
+ ID_OUI_FROM_DATABASE=Chaney Instrument Co.
+
+OUI:24C9DE*
+ ID_OUI_FROM_DATABASE=Genoray
+
+OUI:24CBE7*
+ ID_OUI_FROM_DATABASE=MYK, Inc.
+
+OUI:24CF21*
+ ID_OUI_FROM_DATABASE=Shenzhen State Micro Technology Co., Ltd
+
+OUI:24D2CC*
+ ID_OUI_FROM_DATABASE=SmartDrive Systems Inc.
+
+OUI:24D921*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:24DAB6*
+ ID_OUI_FROM_DATABASE=Sistemas de Gestión Energética S.A. de C.V
+
+OUI:24DBAC*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:24DBAD*
+ ID_OUI_FROM_DATABASE=ShopperTrak RCT Corporation
+
+OUI:24DEC6*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
+OUI:24E6BA*
+ ID_OUI_FROM_DATABASE=JSC Zavod im. Kozitsky
+
+OUI:24EC99*
+ ID_OUI_FROM_DATABASE=Askey Computer Corp
+
+OUI:24EE3A*
+ ID_OUI_FROM_DATABASE=Chengdu Yingji Electronic Hi-tech Co Ltd
+
+OUI:24F0FF*
+ ID_OUI_FROM_DATABASE=GHT Co., Ltd.
+
+OUI:24F2DD*
+ ID_OUI_FROM_DATABASE=Radiant Zemax LLC
+
+OUI:2804E0*
+ ID_OUI_FROM_DATABASE=FERMAX ELECTRONICA S.A.U.
+
+OUI:28061E*
+ ID_OUI_FROM_DATABASE=NINGBO GLOBAL USEFUL ELECTRIC CO.,LTD
+
+OUI:28068D*
+ ID_OUI_FROM_DATABASE=ITL, LLC
+
+OUI:280CB8*
+ ID_OUI_FROM_DATABASE=Mikrosay Yazilim ve Elektronik A.S.
+
+OUI:280DFC*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+
+OUI:28107B*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:281471*
+ ID_OUI_FROM_DATABASE=Lantis co., LTD.
+
+OUI:28162E*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:2817CE*
+ ID_OUI_FROM_DATABASE=Omnisense Ltd
+
+OUI:2818FD*
+ ID_OUI_FROM_DATABASE=Aditya Infotech Ltd.
+
+OUI:2826A6*
+ ID_OUI_FROM_DATABASE=PBR electronics GmbH
+
+OUI:2829D9*
+ ID_OUI_FROM_DATABASE=GlobalBeiMing technology (Beijing)Co. Ltd
+
+OUI:283410*
+ ID_OUI_FROM_DATABASE=Enigma Diagnostics Limited
+
+OUI:283737*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:2838CF*
+ ID_OUI_FROM_DATABASE=Gen2wave
+
+OUI:2839E7*
+ ID_OUI_FROM_DATABASE=Preceno Technology Pte.Ltd.
+
+OUI:283CE4*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:28401A*
+ ID_OUI_FROM_DATABASE=C8 MediSensors, Inc.
+
+OUI:284121*
+ ID_OUI_FROM_DATABASE=OptiSense Network, LLC
+
+OUI:284846*
+ ID_OUI_FROM_DATABASE=GridCentric Inc.
+
+OUI:284C53*
+ ID_OUI_FROM_DATABASE=Intune Networks
+
+OUI:285132*
+ ID_OUI_FROM_DATABASE=Shenzhen Prayfly Technology Co.,Ltd
+
+OUI:285FDB*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:286046*
+ ID_OUI_FROM_DATABASE=Lantech Communications Global, Inc.
+
+OUI:286094*
+ ID_OUI_FROM_DATABASE=CAPELEC
+
+OUI:286AB8*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:286ABA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:286ED4*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:287184*
+ ID_OUI_FROM_DATABASE=Spire Payments
+
+OUI:2872C5*
+ ID_OUI_FROM_DATABASE=Smartmatic Corp
+
+OUI:2872F0*
+ ID_OUI_FROM_DATABASE=ATHENA
+
+OUI:28852D*
+ ID_OUI_FROM_DATABASE=Touch Networks
+
+OUI:288915*
+ ID_OUI_FROM_DATABASE=CashGuard Sverige AB
+
+OUI:2891D0*
+ ID_OUI_FROM_DATABASE=Stage Tec Entwicklungsgesellschaft für professionelle Audiotechnik mbH
+
+OUI:28924A*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:2893FE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:28940F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:28987B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:289A4B*
+ ID_OUI_FROM_DATABASE=SteelSeries ApS
+
+OUI:289EDF*
+ ID_OUI_FROM_DATABASE=Danfoss Turbocor Compressors, Inc
+
+OUI:28A186*
+ ID_OUI_FROM_DATABASE=enblink
+
+OUI:28A192*
+ ID_OUI_FROM_DATABASE=GERP Solution
+
+OUI:28A574*
+ ID_OUI_FROM_DATABASE=Miller Electric Mfg. Co.
+
+OUI:28AF0A*
+ ID_OUI_FROM_DATABASE=Sirius XM Radio Inc
+
+OUI:28B0CC*
+ ID_OUI_FROM_DATABASE=Xenya d.o.o.
+
+OUI:28B3AB*
+ ID_OUI_FROM_DATABASE=Genmark Automation
+
+OUI:28BA18*
+ ID_OUI_FROM_DATABASE=NextNav, LLC
+
+OUI:28BE9B*
+ ID_OUI_FROM_DATABASE=Technicolor USA Inc.
+
+OUI:28C0DA*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:28C68E*
+ ID_OUI_FROM_DATABASE=NETGEAR INC.,
+
+OUI:28C718*
+ ID_OUI_FROM_DATABASE=Altierre
+
+OUI:28C914*
+ ID_OUI_FROM_DATABASE=Taimag Corporation
+
+OUI:28CC01*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:28CCFF*
+ ID_OUI_FROM_DATABASE=Corporacion Empresarial Altra SL
+
+OUI:28CD1C*
+ ID_OUI_FROM_DATABASE=Espotel Oy
+
+OUI:28CD4C*
+ ID_OUI_FROM_DATABASE=Individual Computers GmbH
+
+OUI:28CFDA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:28D1AF*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:28D244*
+ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology Co., Ltd.
+
+OUI:28D576*
+ ID_OUI_FROM_DATABASE=Premier Wireless, Inc.
+
+OUI:28D997*
+ ID_OUI_FROM_DATABASE=Yuduan Mobile Co., Ltd.
+
+OUI:28E02C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:28E297*
+ ID_OUI_FROM_DATABASE=Shanghai InfoTM Microelectronics Co.,Ltd.
+
+OUI:28E608*
+ ID_OUI_FROM_DATABASE=Tokheim
+
+OUI:28E794*
+ ID_OUI_FROM_DATABASE=Microtime Computer Inc.
+
+OUI:28E7CF*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:28ED58*
+ ID_OUI_FROM_DATABASE=JAG Jakob AG
+
+OUI:28EE2C*
+ ID_OUI_FROM_DATABASE=Frontline Test Equipment
+
+OUI:28F358*
+ ID_OUI_FROM_DATABASE=2C - Trifonov & Co
+
+OUI:28F606*
+ ID_OUI_FROM_DATABASE=Syes srl
+
+OUI:28FBD3*
+ ID_OUI_FROM_DATABASE=Shanghai RagenTek Communication Technology Co.,Ltd.
+
+OUI:2C002C*
+ ID_OUI_FROM_DATABASE=UNOWHY
+
+OUI:2C0033*
+ ID_OUI_FROM_DATABASE=EControls, LLC
+
+OUI:2C00F7*
+ ID_OUI_FROM_DATABASE=XOS
+
+OUI:2C0623*
+ ID_OUI_FROM_DATABASE=Win Leader Inc.
+
+OUI:2C10C1*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:2C1984*
+ ID_OUI_FROM_DATABASE=IDN Telecom, Inc.
+
+OUI:2C1EEA*
+ ID_OUI_FROM_DATABASE=AERODEV
+
+OUI:2C2172*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:2C26C5*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:2C27D7*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:2C2D48*
+ ID_OUI_FROM_DATABASE=bct electronic GesmbH
+
+OUI:2C3068*
+ ID_OUI_FROM_DATABASE=Pantech Co.,Ltd
+
+OUI:2C3427*
+ ID_OUI_FROM_DATABASE=ERCO & GENER
+
+OUI:2C3557*
+ ID_OUI_FROM_DATABASE=ELLIY Power CO..Ltd
+
+OUI:2C36A0*
+ ID_OUI_FROM_DATABASE=Capisco Limited
+
+OUI:2C36F8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:2C3A28*
+ ID_OUI_FROM_DATABASE=Fagor Electrónica
+
+OUI:2C3BFD*
+ ID_OUI_FROM_DATABASE=Netstor Technology Co., Ltd.
+
+OUI:2C3F38*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:2C3F3E*
+ ID_OUI_FROM_DATABASE=Alge-Timing GmbH
+
+OUI:2C4138*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:2C4401*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:2C441B*
+ ID_OUI_FROM_DATABASE=Spectrum Medical Limited
+
+OUI:2C542D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:2C5AA3*
+ ID_OUI_FROM_DATABASE=PROMATE ELECTRONIC CO.LTD
+
+OUI:2C625A*
+ ID_OUI_FROM_DATABASE=Finest Security Systems Co., Ltd
+
+OUI:2C6289*
+ ID_OUI_FROM_DATABASE=Regenersis (Glenrothes) Ltd
+
+OUI:2C67FB*
+ ID_OUI_FROM_DATABASE=ShenZhen Zhengjili Electronics Co., LTD
+
+OUI:2C6BF5*
+ ID_OUI_FROM_DATABASE=Juniper networks
+
+OUI:2C750F*
+ ID_OUI_FROM_DATABASE=Shanghai Dongzhou-Lawton Communication Technology Co. Ltd.
+
+OUI:2C768A*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:2C7AFE*
+ ID_OUI_FROM_DATABASE=IEE&E "Black" ops
+
+OUI:2C7B5A*
+ ID_OUI_FROM_DATABASE=Milper Ltd
+
+OUI:2C7ECF*
+ ID_OUI_FROM_DATABASE=Onzo Ltd
+
+OUI:2C8065*
+ ID_OUI_FROM_DATABASE=HARTING Inc. of North America
+
+OUI:2C8158*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd
+
+OUI:2C8BF2*
+ ID_OUI_FROM_DATABASE=Hitachi Metals America Ltd
+
+OUI:2C9127*
+ ID_OUI_FROM_DATABASE=Eintechno Corporation
+
+OUI:2C9717*
+ ID_OUI_FROM_DATABASE=I.C.Y. B.V.
+
+OUI:2C9E5F*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:2C9EFC*
+ ID_OUI_FROM_DATABASE=CANON INC.
+
+OUI:2CA157*
+ ID_OUI_FROM_DATABASE=ACROMATE, INC.
+
+OUI:2CA780*
+ ID_OUI_FROM_DATABASE=True Technologies Inc.
+
+OUI:2CA835*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:2CAB25*
+ ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
+
+OUI:2CB05D*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:2CB0DF*
+ ID_OUI_FROM_DATABASE=Soliton Technologies Pvt Ltd
+
+OUI:2CB69D*
+ ID_OUI_FROM_DATABASE=RED Digital Cinema
+
+OUI:2CBE97*
+ ID_OUI_FROM_DATABASE=Ingenieurbuero Bickele und Buehler GmbH
+
+OUI:2CC260*
+ ID_OUI_FROM_DATABASE=Ravello Systems
+
+OUI:2CCD27*
+ ID_OUI_FROM_DATABASE=Precor Inc
+
+OUI:2CCD43*
+ ID_OUI_FROM_DATABASE=Summit Technology Group
+
+OUI:2CD1DA*
+ ID_OUI_FROM_DATABASE=Sanjole, Inc.
+
+OUI:2CD2E7*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:2CD444*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
+OUI:2CDD0C*
+ ID_OUI_FROM_DATABASE=Discovergy GmbH
+
+OUI:2CE2A8*
+ ID_OUI_FROM_DATABASE=DeviceDesign
+
+OUI:2CE412*
+ ID_OUI_FROM_DATABASE=SAGEMCOM SAS
+
+OUI:2CE871*
+ ID_OUI_FROM_DATABASE=Alert Metalguard ApS
+
+OUI:2CEDEB*
+ ID_OUI_FROM_DATABASE=Alpheus Digital Company Limited
+
+OUI:2CEE26*
+ ID_OUI_FROM_DATABASE=Petroleum Geo-Services
+
+OUI:2CF4C5*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:300B9C*
+ ID_OUI_FROM_DATABASE=Delta Mobile Systems, Inc.
+
+OUI:300ED5*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd
+
+OUI:30142D*
+ ID_OUI_FROM_DATABASE=Piciorgros GmbH
+
+OUI:30144A*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
+
+OUI:301518*
+ ID_OUI_FROM_DATABASE=Ubiquitous Communication Co. ltd.
+
+OUI:30168D*
+ ID_OUI_FROM_DATABASE=ProLon
+
+OUI:3017C8*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:3018CF*
+ ID_OUI_FROM_DATABASE=DEOS control systems GmbH
+
+OUI:301A28*
+ ID_OUI_FROM_DATABASE=Mako Networks Ltd
+
+OUI:30215B*
+ ID_OUI_FROM_DATABASE=Shenzhen Ostar Display Electronic Co.,Ltd
+
+OUI:302DE8*
+ ID_OUI_FROM_DATABASE=JDA, LLC (JDA Systems)
+
+OUI:303294*
+ ID_OUI_FROM_DATABASE=W-IE-NE-R Plein & Baus GmbH
+
+OUI:3032D4*
+ ID_OUI_FROM_DATABASE=Hanilstm Co., Ltd.
+
+OUI:3037A6*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:303855*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:303926*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:303955*
+ ID_OUI_FROM_DATABASE=Shenzhen Jinhengjia Electronic Co., Ltd.
+
+OUI:3039F2*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:303D08*
+ ID_OUI_FROM_DATABASE=GLINTT TES S.A.
+
+OUI:304174*
+ ID_OUI_FROM_DATABASE=ALTEC LANSING LLC
+
+OUI:304449*
+ ID_OUI_FROM_DATABASE=PLATH GmbH
+
+OUI:30469A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:30493B*
+ ID_OUI_FROM_DATABASE=Nanjing Z-Com Wireless Co.,Ltd
+
+OUI:304C7E*
+ ID_OUI_FROM_DATABASE=Panasonic Electric Works Automation Controls Techno Co.,Ltd.
+
+OUI:304EC3*
+ ID_OUI_FROM_DATABASE=Tianjin Techua Technology Co., Ltd.
+
+OUI:30525A*
+ ID_OUI_FROM_DATABASE=NST Co., LTD
+
+OUI:3055ED*
+ ID_OUI_FROM_DATABASE=Trex Network LLC
+
+OUI:3057AC*
+ ID_OUI_FROM_DATABASE=IRLAB LTD.
+
+OUI:305D38*
+ ID_OUI_FROM_DATABASE=Beissbarth
+
+OUI:306118*
+ ID_OUI_FROM_DATABASE=Paradom Inc.
+
+OUI:30688C*
+ ID_OUI_FROM_DATABASE=Reach Technology Inc.
+
+OUI:30694B*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:306CBE*
+ ID_OUI_FROM_DATABASE=Skymotion Technology (HK) Limited
+
+OUI:306E5C*
+ ID_OUI_FROM_DATABASE=Validus Technologies
+
+OUI:3071B2*
+ ID_OUI_FROM_DATABASE=Hangzhou Prevail Optoelectronic Equipment Co.,LTD.
+
+OUI:3078C2*
+ ID_OUI_FROM_DATABASE=Innowireless, Co. Ltd.
+
+OUI:307C30*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:307ECB*
+ ID_OUI_FROM_DATABASE=SFR
+
+OUI:3085A9*
+ ID_OUI_FROM_DATABASE=Asustek Computer Inc
+
+OUI:308730*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:308CFB*
+ ID_OUI_FROM_DATABASE=Dropcam
+
+OUI:3090AB*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:3092F6*
+ ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD
+
+OUI:30AEF6*
+ ID_OUI_FROM_DATABASE=Radio Mobile Access
+
+OUI:30B216*
+ ID_OUI_FROM_DATABASE=Hytec Geraetebau GmbH
+
+OUI:30B3A2*
+ ID_OUI_FROM_DATABASE=Shenzhen Heguang Measurement & Control Technology Co.,Ltd
+
+OUI:30C82A*
+ ID_OUI_FROM_DATABASE=Wi-Next s.r.l.
+
+OUI:30CDA7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics ITS, Printer division
+
+OUI:30D357*
+ ID_OUI_FROM_DATABASE=Logosol, Inc.
+
+OUI:30DE86*
+ ID_OUI_FROM_DATABASE=Cedac Software S.r.l.
+
+OUI:30E48E*
+ ID_OUI_FROM_DATABASE=Vodafone UK
+
+OUI:30E4DB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:30EB25*
+ ID_OUI_FROM_DATABASE=INTEK DIGITAL
+
+OUI:30EFD1*
+ ID_OUI_FROM_DATABASE=Alstom Strongwish (Shenzhen) Co., Ltd.
+
+OUI:30F33A*
+ ID_OUI_FROM_DATABASE=+plugg srl
+
+OUI:30F70D*
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:30F7C5*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:30F9ED*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:30FD11*
+ ID_OUI_FROM_DATABASE=MACROTECH (USA) INC.
+
+OUI:3407FB*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:340804*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:34159E*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:342109*
+ ID_OUI_FROM_DATABASE=Jensen Scandinavia AS
+
+OUI:34255D*
+ ID_OUI_FROM_DATABASE=Shenzhen Loadcom Technology Co.,Ltd
+
+OUI:3429EA*
+ ID_OUI_FROM_DATABASE=MCD ELECTRONICS SP. Z O.O.
+
+OUI:342F6E*
+ ID_OUI_FROM_DATABASE=Anywire corporation
+
+OUI:3440B5*
+ ID_OUI_FROM_DATABASE=IBM
+
+OUI:344B3D*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
+
+OUI:344B50*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:344F69*
+ ID_OUI_FROM_DATABASE=EKINOPS SAS
+
+OUI:3451C9*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:345B11*
+ ID_OUI_FROM_DATABASE=EVI HEAT AB
+
+OUI:34684A*
+ ID_OUI_FROM_DATABASE=Teraworks Co., Ltd.
+
+OUI:346BD3*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:346E8A*
+ ID_OUI_FROM_DATABASE=Ecosense
+
+OUI:346F92*
+ ID_OUI_FROM_DATABASE=White Rodgers Division
+
+OUI:3475C7*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:3476C5*
+ ID_OUI_FROM_DATABASE=I-O DATA DEVICE, INC.
+
+OUI:347877*
+ ID_OUI_FROM_DATABASE=O-NET Communications(Shenzhen) Limited
+
+OUI:347E39*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:348137*
+ ID_OUI_FROM_DATABASE=UNICARD SA
+
+OUI:3482DE*
+ ID_OUI_FROM_DATABASE=Kayo Technology, Inc.
+
+OUI:348302*
+ ID_OUI_FROM_DATABASE=iForcom Co., Ltd
+
+OUI:348446*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:34862A*
+ ID_OUI_FROM_DATABASE=Heinz Lackmann GmbH & Co KG
+
+OUI:3497FB*
+ ID_OUI_FROM_DATABASE=ADVANCED RF TECHNOLOGIES INC
+
+OUI:34996F*
+ ID_OUI_FROM_DATABASE=VPI Engineering
+
+OUI:3499D7*
+ ID_OUI_FROM_DATABASE=Universal Flow Monitors, Inc.
+
+OUI:349A0D*
+ ID_OUI_FROM_DATABASE=ZBD Displays Ltd
+
+OUI:34A183*
+ ID_OUI_FROM_DATABASE=AWare, Inc
+
+OUI:34A55D*
+ ID_OUI_FROM_DATABASE=TECHNOSOFT INTERNATIONAL SRL
+
+OUI:34A709*
+ ID_OUI_FROM_DATABASE=Trevil srl
+
+OUI:34A7BA*
+ ID_OUI_FROM_DATABASE=Fischer International Systems Corporation
+
+OUI:34A84E*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:34AA99*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:34AAEE*
+ ID_OUI_FROM_DATABASE=Mikrovisatos Servisas UAB
+
+OUI:34ADE4*
+ ID_OUI_FROM_DATABASE=Shanghai Chint Power Systems Co., Ltd.
+
+OUI:34AF2C*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:34B1F7*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:34B571*
+ ID_OUI_FROM_DATABASE=PLDS
+
+OUI:34BA51*
+ ID_OUI_FROM_DATABASE=Se-Kure Controls, Inc.
+
+OUI:34BA9A*
+ ID_OUI_FROM_DATABASE=Asiatelco Technologies Co.
+
+OUI:34BB1F*
+ ID_OUI_FROM_DATABASE=Research In Motion
+
+OUI:34BCA6*
+ ID_OUI_FROM_DATABASE=Beijing Ding Qing Technology, Ltd.
+
+OUI:34BDC8*
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:34BDF9*
+ ID_OUI_FROM_DATABASE=Shanghai WDK Industrial Co.,Ltd.
+
+OUI:34BDFA*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:34C059*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:34C3AC*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:34C69A*
+ ID_OUI_FROM_DATABASE=Enecsys Ltd
+
+OUI:34C731*
+ ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd.
+
+OUI:34C803*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:34C99D*
+ ID_OUI_FROM_DATABASE=EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD.
+
+OUI:34CE94*
+ ID_OUI_FROM_DATABASE=Parsec (Pty) Ltd
+
+OUI:34D09B*
+ ID_OUI_FROM_DATABASE=MobilMAX Technology Inc.
+
+OUI:34D2C4*
+ ID_OUI_FROM_DATABASE=RENA GmbH Print Systeme
+
+OUI:34D7B4*
+ ID_OUI_FROM_DATABASE=Tributary Systems, Inc.
+
+OUI:34DF2A*
+ ID_OUI_FROM_DATABASE=Fujikon Industrial Co.,Limited
+
+OUI:34E0CF*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:34E0D7*
+ ID_OUI_FROM_DATABASE=DONGGUAN QISHENG ELECTRONICS INDUSTRIAL CO., LTD
+
+OUI:34EF44*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:34EF8B*
+ ID_OUI_FROM_DATABASE=NTT Communications Corporation
+
+OUI:34F39B*
+ ID_OUI_FROM_DATABASE=WizLAN Ltd.
+
+OUI:34F62D*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
+
+OUI:34F968*
+ ID_OUI_FROM_DATABASE=ATEK Products, LLC
+
+OUI:34FA40*
+ ID_OUI_FROM_DATABASE=Guangzhou Robustel Technologies Co., Limited
+
+OUI:34FC6F*
+ ID_OUI_FROM_DATABASE=ALCEA
+
+OUI:380197*
+ ID_OUI_FROM_DATABASE=Toshiba Samsung Storage Technolgoy Korea Corporation
+
+OUI:380A0A*
+ ID_OUI_FROM_DATABASE=Sky-City Communication and Electronics Limited Company
+
+OUI:380A94*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:380DD4*
+ ID_OUI_FROM_DATABASE=Primax Electronics LTD.
+
+OUI:380FE4*
+ ID_OUI_FROM_DATABASE=Dedicated Network Partners Oy
+
+OUI:3816D1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:38192F*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:381C4A*
+ ID_OUI_FROM_DATABASE=SIMCom Wireless Solutions Co.,Ltd.
+
+OUI:38229D*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:3822D6*
+ ID_OUI_FROM_DATABASE=H3C Technologies Co., Limited
+
+OUI:3826CD*
+ ID_OUI_FROM_DATABASE=ANDTEK
+
+OUI:3828EA*
+ ID_OUI_FROM_DATABASE=Fujian Netcom Technology Co., LTD
+
+OUI:3831AC*
+ ID_OUI_FROM_DATABASE=WEG
+
+OUI:383F10*
+ ID_OUI_FROM_DATABASE=DBL Technology Ltd.
+
+OUI:384369*
+ ID_OUI_FROM_DATABASE=Patrol Products Consortium LLC
+
+OUI:38458C*
+ ID_OUI_FROM_DATABASE=MyCloud Technology corporation
+
+OUI:384608*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:38484C*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:38521A*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent 7705
+
+OUI:38580C*
+ ID_OUI_FROM_DATABASE=Panaccess Systems GmbH
+
+OUI:3859F9*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:385FC3*
+ ID_OUI_FROM_DATABASE=Yu Jeong System, Co.Ltd
+
+OUI:386077*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:3863F6*
+ ID_OUI_FROM_DATABASE=3NOD MULTIMEDIA(SHENZHEN)CO.,LTD
+
+OUI:386645*
+ ID_OUI_FROM_DATABASE=OOSIC Technology CO.,Ltd
+
+OUI:386BBB*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:386E21*
+ ID_OUI_FROM_DATABASE=Wasion Group Ltd.
+
+OUI:3872C0*
+ ID_OUI_FROM_DATABASE=COMTREND
+
+OUI:388345*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:388AB7*
+ ID_OUI_FROM_DATABASE=ITC Networks
+
+OUI:388EE7*
+ ID_OUI_FROM_DATABASE=Fanhattan LLC
+
+OUI:3891FB*
+ ID_OUI_FROM_DATABASE=Xenox Holding BV
+
+OUI:389592*
+ ID_OUI_FROM_DATABASE=Beijing Tendyron Corporation
+
+OUI:389F83*
+ ID_OUI_FROM_DATABASE=OTN Systems N.V.
+
+OUI:38A5B6*
+ ID_OUI_FROM_DATABASE=SHENZHEN MEGMEET ELECTRICAL CO.,LTD
+
+OUI:38A851*
+ ID_OUI_FROM_DATABASE=Quickset International Inc
+
+OUI:38A95F*
+ ID_OUI_FROM_DATABASE=Actifio Inc
+
+OUI:38AA3C*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS
+
+OUI:38B12D*
+ ID_OUI_FROM_DATABASE=Sonotronic Nagel GmbH
+
+OUI:38B5BD*
+ ID_OUI_FROM_DATABASE=E.G.O. Elektro-Ger
+
+OUI:38BB23*
+ ID_OUI_FROM_DATABASE=OzVision America LLC
+
+OUI:38BC1A*
+ ID_OUI_FROM_DATABASE=Meizu technology co.,ltd
+
+OUI:38BF33*
+ ID_OUI_FROM_DATABASE=NEC CASIO Mobile Communications
+
+OUI:38C096*
+ ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
+
+OUI:38C7BA*
+ ID_OUI_FROM_DATABASE=CS Services Co.,Ltd.
+
+OUI:38C85C*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:38D135*
+ ID_OUI_FROM_DATABASE=EasyIO Corporation Sdn. Bhd.
+
+OUI:38DE60*
+ ID_OUI_FROM_DATABASE=Mohlenhoff GmbH
+
+OUI:38E08E*
+ ID_OUI_FROM_DATABASE=Mitsubishi Electric Co.
+
+OUI:38E595*
+ ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
+
+OUI:38E7D8*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:38E8DF*
+ ID_OUI_FROM_DATABASE=b gmbh medien + datenbanken
+
+OUI:38E98C*
+ ID_OUI_FROM_DATABASE=Reco S.p.A.
+
+OUI:38EAA7*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:38ECE4*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:38EE9D*
+ ID_OUI_FROM_DATABASE=Anedo Ltd.
+
+OUI:38F597*
+ ID_OUI_FROM_DATABASE=home2net GmbH
+
+OUI:38F8B7*
+ ID_OUI_FROM_DATABASE=V2COM PARTICIPACOES S.A.
+
+OUI:38FEC5*
+ ID_OUI_FROM_DATABASE=Ellips B.V.
+
+OUI:3C02B1*
+ ID_OUI_FROM_DATABASE=Creation Technologies LP
+
+OUI:3C04BF*
+ ID_OUI_FROM_DATABASE=PRAVIS SYSTEMS Co.Ltd.,
+
+OUI:3C05AB*
+ ID_OUI_FROM_DATABASE=Product Creation Studio
+
+OUI:3C0754*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:3C0771*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:3C096D*
+ ID_OUI_FROM_DATABASE=Powerhouse Dynamics
+
+OUI:3C0FC1*
+ ID_OUI_FROM_DATABASE=KBC Networks
+
+OUI:3C106F*
+ ID_OUI_FROM_DATABASE=ALBAHITH TECHNOLOGIES
+
+OUI:3C1915*
+ ID_OUI_FROM_DATABASE=GFI Chrono Time
+
+OUI:3C197D*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:3C1A79*
+ ID_OUI_FROM_DATABASE=Huayuan Technology CO.,LTD
+
+OUI:3C1CBE*
+ ID_OUI_FROM_DATABASE=JADAK LLC
+
+OUI:3C26D5*
+ ID_OUI_FROM_DATABASE=Sotera Wireless
+
+OUI:3C2763*
+ ID_OUI_FROM_DATABASE=SLE quality engineering GmbH & Co. KG
+
+OUI:3C2DB7*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:3C2F3A*
+ ID_OUI_FROM_DATABASE=SFORZATO Corp.
+
+OUI:3C363D*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:3C3888*
+ ID_OUI_FROM_DATABASE=ConnectQuest, llc
+
+OUI:3C39C3*
+ ID_OUI_FROM_DATABASE=JW Electronics Co., Ltd.
+
+OUI:3C3A73*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:3C438E*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:3C4A92*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:3C4C69*
+ ID_OUI_FROM_DATABASE=Infinity System S.L.
+
+OUI:3C4E47*
+ ID_OUI_FROM_DATABASE=Etronic A/S
+
+OUI:3C57BD*
+ ID_OUI_FROM_DATABASE=Kessler Crane Inc.
+
+OUI:3C57D5*
+ ID_OUI_FROM_DATABASE=FiveCo
+
+OUI:3C5A37*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:3C5F01*
+ ID_OUI_FROM_DATABASE=Synerchip Co., Ltd.
+
+OUI:3C6200*
+ ID_OUI_FROM_DATABASE=Samsung electronics CO., LTD
+
+OUI:3C6278*
+ ID_OUI_FROM_DATABASE=SHENZHEN JETNET TECHNOLOGY CO.,LTD.
+
+OUI:3C672C*
+ ID_OUI_FROM_DATABASE=Sciovid Inc.
+
+OUI:3C6A7D*
+ ID_OUI_FROM_DATABASE=Niigata Power Systems Co., Ltd.
+
+OUI:3C6F45*
+ ID_OUI_FROM_DATABASE=Fiberpro Inc.
+
+OUI:3C6FF7*
+ ID_OUI_FROM_DATABASE=EnTek Systems, Inc.
+
+OUI:3C7059*
+ ID_OUI_FROM_DATABASE=MakerBot Industries
+
+OUI:3C7437*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:3C754A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:3C7DB1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:3C81D8*
+ ID_OUI_FROM_DATABASE=SAGEMCOM SAS
+
+OUI:3C83B5*
+ ID_OUI_FROM_DATABASE=Advance Vision Electronics Co. Ltd.
+
+OUI:3C8AE5*
+ ID_OUI_FROM_DATABASE=Tensun Information Technology(Hangzhou) Co.,LTD
+
+OUI:3C8BFE*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:3C9157*
+ ID_OUI_FROM_DATABASE=Hangzhou Yulong Conmunication Co.,Ltd
+
+OUI:3C9174*
+ ID_OUI_FROM_DATABASE=ALONG COMMUNICATION TECHNOLOGY
+
+OUI:3C94D5*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:3C970E*
+ ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd.
+
+OUI:3C98BF*
+ ID_OUI_FROM_DATABASE=Quest Controls, Inc.
+
+OUI:3C99F7*
+ ID_OUI_FROM_DATABASE=Lansentechnology AB
+
+OUI:3C9F81*
+ ID_OUI_FROM_DATABASE=Shenzhen CATIC Bit Communications Technology Co.,Ltd
+
+OUI:3CA315*
+ ID_OUI_FROM_DATABASE=Bless Information & Communications Co., Ltd
+
+OUI:3CA72B*
+ ID_OUI_FROM_DATABASE=MRV Communications (Networks) LTD
+
+OUI:3CA9F4*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:3CB15B*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:3CB17F*
+ ID_OUI_FROM_DATABASE=Wattwatchers Pty Ld
+
+OUI:3CB9A6*
+ ID_OUI_FROM_DATABASE=Belden Deutschland GmbH
+
+OUI:3CBDD8*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
+
+OUI:3CC0C6*
+ ID_OUI_FROM_DATABASE=d&b audiotechnik GmbH
+
+OUI:3CC12C*
+ ID_OUI_FROM_DATABASE=AES Corporation
+
+OUI:3CC1F6*
+ ID_OUI_FROM_DATABASE=Melange Systems Pvt. Ltd.
+
+OUI:3CC99E*
+ ID_OUI_FROM_DATABASE=Huiyang Technology Co., Ltd
+
+OUI:3CCE73*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:3CD0F8*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:3CD16E*
+ ID_OUI_FROM_DATABASE=Telepower Communication Co., Ltd
+
+OUI:3CD7DA*
+ ID_OUI_FROM_DATABASE=SK Mtek microelectronics(shenzhen)limited
+
+OUI:3CD92B*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:3CDF1E*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:3CE072*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:3CE5A6*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Ltd.
+
+OUI:3CE5B4*
+ ID_OUI_FROM_DATABASE=KIDASEN INDUSTRIA E COMERCIO DE ANTENAS LTDA
+
+OUI:3CE624*
+ ID_OUI_FROM_DATABASE=LG Display
+
+OUI:3CEA4F*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:3CEAFB*
+ ID_OUI_FROM_DATABASE=NSE AG
+
+OUI:3CF392*
+ ID_OUI_FROM_DATABASE=Virtualtek. Co. Ltd
+
+OUI:3CF52C*
+ ID_OUI_FROM_DATABASE=DSPECIALISTS GmbH
+
+OUI:3CF72A*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:4001C6*
+ ID_OUI_FROM_DATABASE=3COM EUROPE LTD
+
+OUI:40040C*
+ ID_OUI_FROM_DATABASE=A&T
+
+OUI:400E67*
+ ID_OUI_FROM_DATABASE=Tremol Ltd.
+
+OUI:4012E4*
+ ID_OUI_FROM_DATABASE=Compass-EOS
+
+OUI:4013D9*
+ ID_OUI_FROM_DATABASE=Global ES
+
+OUI:401597*
+ ID_OUI_FROM_DATABASE=Protect America, Inc.
+
+OUI:40169F*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:4016FA*
+ ID_OUI_FROM_DATABASE=EKM Metering
+
+OUI:4018B1*
+ ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
+
+OUI:4018D7*
+ ID_OUI_FROM_DATABASE=Wyle Telemetry and Data Systems
+
+OUI:401D59*
+ ID_OUI_FROM_DATABASE=Biometric Associates, LP
+
+OUI:4022ED*
+ ID_OUI_FROM_DATABASE=Digital Projection Ltd
+
+OUI:4025C2*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:40270B*
+ ID_OUI_FROM_DATABASE=Mobileeco Co., Ltd
+
+OUI:402BA1*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:402CF4*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:403004*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:40336C*
+ ID_OUI_FROM_DATABASE=Godrej & Boyce Mfg. co. ltd
+
+OUI:4037AD*
+ ID_OUI_FROM_DATABASE=Macro Image Technology, Inc.
+
+OUI:403CFC*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:404022*
+ ID_OUI_FROM_DATABASE=ZIV
+
+OUI:40406B*
+ ID_OUI_FROM_DATABASE=Icomera
+
+OUI:404A03*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:404D8E*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:4050E0*
+ ID_OUI_FROM_DATABASE=Milton Security Group LLC
+
+OUI:40520D*
+ ID_OUI_FROM_DATABASE=Pico Technology
+
+OUI:405539*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:405A9B*
+ ID_OUI_FROM_DATABASE=ANOVO
+
+OUI:405FBE*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:405FC2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:40605A*
+ ID_OUI_FROM_DATABASE=Hawkeye Tech Co. Ltd
+
+OUI:406186*
+ ID_OUI_FROM_DATABASE=MICRO-STAR INT'L CO.,LTD
+
+OUI:40618E*
+ ID_OUI_FROM_DATABASE=Stella-Green Co
+
+OUI:40667A*
+ ID_OUI_FROM_DATABASE=mediola - connected living AG
+
+OUI:406AAB*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:406C8F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:406F2A*
+ ID_OUI_FROM_DATABASE=Research In Motion
+
+OUI:40704A*
+ ID_OUI_FROM_DATABASE=Power Idea Technology Limited
+
+OUI:407074*
+ ID_OUI_FROM_DATABASE=Life Technology (China) Co., Ltd
+
+OUI:407B1B*
+ ID_OUI_FROM_DATABASE=Mettle Networks Inc.
+
+OUI:4083DE*
+ ID_OUI_FROM_DATABASE=Motorola
+
+OUI:408493*
+ ID_OUI_FROM_DATABASE=Clavister AB
+
+OUI:4088E0*
+ ID_OUI_FROM_DATABASE=Beijing Ereneben Information Technology Limited Shenzhen Branch
+
+OUI:408A9A*
+ ID_OUI_FROM_DATABASE=TITENG CO., Ltd.
+
+OUI:408B07*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:408BF6*
+ ID_OUI_FROM_DATABASE=Shenzhen TCL New Technology Co; Ltd.
+
+OUI:409558*
+ ID_OUI_FROM_DATABASE=Aisino Corporation
+
+OUI:4097D1*
+ ID_OUI_FROM_DATABASE=BK Electronics cc
+
+OUI:40984C*
+ ID_OUI_FROM_DATABASE=Casacom Solutions AG
+
+OUI:40984E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:40987B*
+ ID_OUI_FROM_DATABASE=Aisino Corporation
+
+OUI:409FC7*
+ ID_OUI_FROM_DATABASE=BAEKCHUN ENC Co., Ltd.
+
+OUI:40A6A4*
+ ID_OUI_FROM_DATABASE=PassivSystems Ltd
+
+OUI:40A6D9*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:40AC8D*
+ ID_OUI_FROM_DATABASE=Data Management, Inc.
+
+OUI:40B2C8*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:40B395*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:40B3FC*
+ ID_OUI_FROM_DATABASE=Logital Co. Limited
+
+OUI:40B4F0*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:40B7F3*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:40BA61*
+ ID_OUI_FROM_DATABASE=Arima Communications Corp.
+
+OUI:40BC8B*
+ ID_OUI_FROM_DATABASE=itelio GmbH
+
+OUI:40BF17*
+ ID_OUI_FROM_DATABASE=Digistar Telecom. SA
+
+OUI:40C245*
+ ID_OUI_FROM_DATABASE=Shenzhen Hexicom Technology Co., Ltd.
+
+OUI:40C7C9*
+ ID_OUI_FROM_DATABASE=Naviit Inc.
+
+OUI:40CD3A*
+ ID_OUI_FROM_DATABASE=Z3 Technology
+
+OUI:40D32D*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:40D40E*
+ ID_OUI_FROM_DATABASE=Biodata Ltd
+
+OUI:40D559*
+ ID_OUI_FROM_DATABASE=MICRO S.E.R.I.
+
+OUI:40E793*
+ ID_OUI_FROM_DATABASE=Shenzhen Siviton Technology Co.,Ltd
+
+OUI:40ECF8*
+ ID_OUI_FROM_DATABASE=Siemens AG
+
+OUI:40EF4C*
+ ID_OUI_FROM_DATABASE=Fihonest communication co.,Ltd
+
+OUI:40F14C*
+ ID_OUI_FROM_DATABASE=ISE Europe SPRL
+
+OUI:40F2E9*
+ ID_OUI_FROM_DATABASE=IBM
+
+OUI:40F407*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:40F4EC*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:40F52E*
+ ID_OUI_FROM_DATABASE=Leica Microsystems (Schweiz) AG
+
+OUI:40FC89*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:4403A7*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:440CFD*
+ ID_OUI_FROM_DATABASE=NetMan Co., Ltd.
+
+OUI:441319*
+ ID_OUI_FROM_DATABASE=WKK TECHNOLOGY LTD.
+
+OUI:44184F*
+ ID_OUI_FROM_DATABASE=Fitview
+
+OUI:4419B6*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+
+OUI:441EA1*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:4423AA*
+ ID_OUI_FROM_DATABASE=Farmage Co., Ltd.
+
+OUI:4425BB*
+ ID_OUI_FROM_DATABASE=Bamboo Entertainment Corporation
+
+OUI:442A60*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:442B03*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:44322A*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:44334C*
+ ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
+
+OUI:44348F*
+ ID_OUI_FROM_DATABASE=MXT INDUSTRIAL LTDA
+
+OUI:443719*
+ ID_OUI_FROM_DATABASE=2 Save Energy Ltd
+
+OUI:44376F*
+ ID_OUI_FROM_DATABASE=Young Electric Sign Co
+
+OUI:4437E6*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd
+
+OUI:443839*
+ ID_OUI_FROM_DATABASE=Cumulus Networks, inc
+
+OUI:443D21*
+ ID_OUI_FROM_DATABASE=Nuvolt
+
+OUI:443EB2*
+ ID_OUI_FROM_DATABASE=DEOTRON Co., LTD.
+
+OUI:444C0C*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:444E1A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:444F5E*
+ ID_OUI_FROM_DATABASE=Pan Studios Co.,Ltd.
+
+OUI:4451DB*
+ ID_OUI_FROM_DATABASE=Raytheon BBN Technologies
+
+OUI:4454C0*
+ ID_OUI_FROM_DATABASE=Thompson Aerospace
+
+OUI:44568D*
+ ID_OUI_FROM_DATABASE=PNC Technologies  Co., Ltd.
+
+OUI:4456B7*
+ ID_OUI_FROM_DATABASE=Spawn Labs, Inc
+
+OUI:445829*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:44599F*
+ ID_OUI_FROM_DATABASE=Criticare Systems, Inc
+
+OUI:445EF3*
+ ID_OUI_FROM_DATABASE=Tonalite Holding B.V.
+
+OUI:445F7A*
+ ID_OUI_FROM_DATABASE=Shihlin Electric & Engineering Corp.
+
+OUI:446132*
+ ID_OUI_FROM_DATABASE=ecobee inc
+
+OUI:4468AB*
+ ID_OUI_FROM_DATABASE=JUIN COMPANY, LIMITED
+
+OUI:446C24*
+ ID_OUI_FROM_DATABASE=Reallin Electronic Co.,Ltd
+
+OUI:446D57*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:447C7F*
+ ID_OUI_FROM_DATABASE=Innolight Technology Corporation
+
+OUI:447DA5*
+ ID_OUI_FROM_DATABASE=VTION INFORMATION TECHNOLOGY (FUJIAN) CO.,LTD
+
+OUI:447E95*
+ ID_OUI_FROM_DATABASE=Alpha and Omega, Inc
+
+OUI:448312*
+ ID_OUI_FROM_DATABASE=Star-Net
+
+OUI:448500*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:4487FC*
+ ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD.
+
+OUI:448C52*
+ ID_OUI_FROM_DATABASE=KTIS CO., Ltd
+
+OUI:448E12*
+ ID_OUI_FROM_DATABASE=DT Research, Inc.
+
+OUI:448E81*
+ ID_OUI_FROM_DATABASE=VIG
+
+OUI:4491DB*
+ ID_OUI_FROM_DATABASE=Shanghai Huaqin Telecom Technology Co.,Ltd
+
+OUI:4495FA*
+ ID_OUI_FROM_DATABASE=Qingdao Santong Digital Technology Co.Ltd
+
+OUI:449B78*
+ ID_OUI_FROM_DATABASE=The Now Factory
+
+OUI:449CB5*
+ ID_OUI_FROM_DATABASE=Alcomp, Inc
+
+OUI:44A42D*
+ ID_OUI_FROM_DATABASE=TCT Mobile Limited
+
+OUI:44A689*
+ ID_OUI_FROM_DATABASE=PROMAX ELECTRONICA SA
+
+OUI:44A7CF*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:44A8C2*
+ ID_OUI_FROM_DATABASE=SEWOO TECH CO., LTD
+
+OUI:44AA27*
+ ID_OUI_FROM_DATABASE=udworks Co., Ltd.
+
+OUI:44AAE8*
+ ID_OUI_FROM_DATABASE=Nanotec Electronic GmbH & Co. KG
+
+OUI:44B382*
+ ID_OUI_FROM_DATABASE=Kuang-chi Institute of Advanced Technology
+
+OUI:44C15C*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:44C233*
+ ID_OUI_FROM_DATABASE=Guangzhou Comet Technology Development Co.Ltd
+
+OUI:44C39B*
+ ID_OUI_FROM_DATABASE=OOO RUBEZH NPO
+
+OUI:44C9A2*
+ ID_OUI_FROM_DATABASE=Greenwald Industries
+
+OUI:44D15E*
+ ID_OUI_FROM_DATABASE=Shanghai Kingto Information Technology Ltd
+
+OUI:44D2CA*
+ ID_OUI_FROM_DATABASE=Anvia TV Oy
+
+OUI:44D3CA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:44D63D*
+ ID_OUI_FROM_DATABASE=Talari Networks
+
+OUI:44D832*
+ ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc.
+
+OUI:44D884*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:44DC91*
+ ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
+
+OUI:44DCCB*
+ ID_OUI_FROM_DATABASE=SEMINDIA SYSTEMS PVT LTD
+
+OUI:44E08E*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:44E49A*
+ ID_OUI_FROM_DATABASE=OMNITRONICS PTY LTD
+
+OUI:44E4D9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:44E8A5*
+ ID_OUI_FROM_DATABASE=Myreka Technologies Sdn. Bhd.
+
+OUI:44ED57*
+ ID_OUI_FROM_DATABASE=Longicorn, inc.
+
+OUI:44F459*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:44FB42*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:48022A*
+ ID_OUI_FROM_DATABASE=B-Link Electronic Limited
+
+OUI:480362*
+ ID_OUI_FROM_DATABASE=DESAY ELECTRONICS(HUIZHOU)CO.,LTD
+
+OUI:481249*
+ ID_OUI_FROM_DATABASE=Luxcom Technologies Inc.
+
+OUI:4813F3*
+ ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd.
+
+OUI:48174C*
+ ID_OUI_FROM_DATABASE=MicroPower technologies
+
+OUI:481BD2*
+ ID_OUI_FROM_DATABASE=Intron Scientific co., ltd.
+
+OUI:48282F*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:482CEA*
+ ID_OUI_FROM_DATABASE=Motorola Inc Business Light Radios
+
+OUI:4833DD*
+ ID_OUI_FROM_DATABASE=ZENNIO AVANCE Y TECNOLOGIA, S.L.
+
+OUI:48343D*
+ ID_OUI_FROM_DATABASE=IEP GmbH
+
+OUI:484487*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:4844F7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
+
+OUI:4846F1*
+ ID_OUI_FROM_DATABASE=Uros Oy
+
+OUI:485261*
+ ID_OUI_FROM_DATABASE=SOREEL
+
+OUI:485A3F*
+ ID_OUI_FROM_DATABASE=WISOL
+
+OUI:485B39*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:485D60*
+ ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc.
+
+OUI:4860BC*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:4861A3*
+ ID_OUI_FROM_DATABASE=Concern "Axion" JSC
+
+OUI:486B91*
+ ID_OUI_FROM_DATABASE=Fleetwood Group Inc.
+
+OUI:486FD2*
+ ID_OUI_FROM_DATABASE=StorSimple Inc
+
+OUI:487119*
+ ID_OUI_FROM_DATABASE=SGB GROUP LTD.
+
+OUI:488E42*
+ ID_OUI_FROM_DATABASE=DIGALOG GmbH
+
+OUI:489153*
+ ID_OUI_FROM_DATABASE=Weinmann Geräte für Medizin GmbH + Co. KG
+
+OUI:4891F6*
+ ID_OUI_FROM_DATABASE=Shenzhen Reach software technology CO.,LTD
+
+OUI:489BE2*
+ ID_OUI_FROM_DATABASE=SCI Innovations Ltd
+
+OUI:48A22D*
+ ID_OUI_FROM_DATABASE=Shenzhen Huaxuchang Telecom Technology Co.,Ltd
+
+OUI:48A6D2*
+ ID_OUI_FROM_DATABASE=GJsun Optical Science and Tech Co.,Ltd.
+
+OUI:48AA5D*
+ ID_OUI_FROM_DATABASE=Store Electronic Systems
+
+OUI:48B253*
+ ID_OUI_FROM_DATABASE=Marketaxess Corporation
+
+OUI:48B8DE*
+ ID_OUI_FROM_DATABASE=HOMEWINS TECHNOLOGY CO.,LTD.
+
+OUI:48B9C2*
+ ID_OUI_FROM_DATABASE=Teletics Inc.
+
+OUI:48BE2D*
+ ID_OUI_FROM_DATABASE=Symanitron
+
+OUI:48C1AC*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:48C862*
+ ID_OUI_FROM_DATABASE=Simo Wireless,Inc.
+
+OUI:48C8B6*
+ ID_OUI_FROM_DATABASE=SysTec GmbH
+
+OUI:48CB6E*
+ ID_OUI_FROM_DATABASE=Cello Electronics (UK) Ltd
+
+OUI:48D54C*
+ ID_OUI_FROM_DATABASE=Jeda Networks
+
+OUI:48D7FF*
+ ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH
+
+OUI:48D8FE*
+ ID_OUI_FROM_DATABASE=ClarIDy Solutions, Inc.
+
+OUI:48DCFB*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:48DF1C*
+ ID_OUI_FROM_DATABASE=Wuhan NEC Fibre Optic Communications industry Co. Ltd
+
+OUI:48E1AF*
+ ID_OUI_FROM_DATABASE=Vity
+
+OUI:48EA63*
+ ID_OUI_FROM_DATABASE=Zhejiang Uniview Technologies Co., Ltd.
+
+OUI:48EB30*
+ ID_OUI_FROM_DATABASE=ETERNA TECHNOLOGY, INC.
+
+OUI:48ED80*
+ ID_OUI_FROM_DATABASE=daesung eltec
+
+OUI:48F230*
+ ID_OUI_FROM_DATABASE=Ubizcore Co.,LTD
+
+OUI:48F47D*
+ ID_OUI_FROM_DATABASE=TechVision Holding  Internation Limited
+
+OUI:48F7F1*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:48F8B3*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:48F8E1*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent WT
+
+OUI:48FCB8*
+ ID_OUI_FROM_DATABASE=Woodstream Corporation
+
+OUI:4C022E*
+ ID_OUI_FROM_DATABASE=CMR KOREA CO., LTD
+
+OUI:4C0289*
+ ID_OUI_FROM_DATABASE=LEX COMPUTECH CO., LTD
+
+OUI:4C068A*
+ ID_OUI_FROM_DATABASE=Basler Electric Company
+
+OUI:4C07C9*
+ ID_OUI_FROM_DATABASE=COMPUTER OFFICE Co.,Ltd.
+
+OUI:4C09B4*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:4C0B3A*
+ ID_OUI_FROM_DATABASE=TCT Mobile Limited
+
+OUI:4C0F6E*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:4C0FC7*
+ ID_OUI_FROM_DATABASE=Earda Electronics Co.,Ltd
+
+OUI:4C1480*
+ ID_OUI_FROM_DATABASE=NOREGON SYSTEMS, INC
+
+OUI:4C17EB*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:4C1A3A*
+ ID_OUI_FROM_DATABASE=PRIMA Research And Production Enterprise Ltd.
+
+OUI:4C1A95*
+ ID_OUI_FROM_DATABASE=Novakon Co., Ltd.
+
+OUI:4C1FCC*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:4C2258*
+ ID_OUI_FROM_DATABASE=cozybit, Inc.
+
+OUI:4C2578*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:4C2C80*
+ ID_OUI_FROM_DATABASE=Beijing Skyway Technologies Co.,Ltd
+
+OUI:4C2F9D*
+ ID_OUI_FROM_DATABASE=ICM Controls
+
+OUI:4C3089*
+ ID_OUI_FROM_DATABASE=Thales Transportation Systems GmbH
+
+OUI:4C322D*
+ ID_OUI_FROM_DATABASE=TELEDATA NETWORKS
+
+OUI:4C32D9*
+ ID_OUI_FROM_DATABASE=M Rutty Holdings Pty. Ltd.
+
+OUI:4C3910*
+ ID_OUI_FROM_DATABASE=Newtek Electronics co., Ltd.
+
+OUI:4C3B74*
+ ID_OUI_FROM_DATABASE=VOGTEC(H.K.) Co., Ltd
+
+OUI:4C4B68*
+ ID_OUI_FROM_DATABASE=Mobile Device, Inc.
+
+OUI:4C4E35*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:4C5427*
+ ID_OUI_FROM_DATABASE=Linepro Sp. z o.o.
+
+OUI:4C5499*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:4C5585*
+ ID_OUI_FROM_DATABASE=Hamilton Systems
+
+OUI:4C5DCD*
+ ID_OUI_FROM_DATABASE=Oy Finnish Electric Vehicle Technologies Ltd
+
+OUI:4C5FD2*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:4C60D5*
+ ID_OUI_FROM_DATABASE=airPointe of New Hampshire
+
+OUI:4C60DE*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:4C63EB*
+ ID_OUI_FROM_DATABASE=Application Solutions (Electronics and Vision) Ltd
+
+OUI:4C64D9*
+ ID_OUI_FROM_DATABASE=Guangdong Leawin Group Co., Ltd
+
+OUI:4C72B9*
+ ID_OUI_FROM_DATABASE=Pegatron Corporation
+
+OUI:4C7367*
+ ID_OUI_FROM_DATABASE=Genius Bytes Software Solutions GmbH
+
+OUI:4C73A5*
+ ID_OUI_FROM_DATABASE=KOVE
+
+OUI:4C774F*
+ ID_OUI_FROM_DATABASE=Embedded Wireless Labs
+
+OUI:4C7897*
+ ID_OUI_FROM_DATABASE=Arrowhead Alarm Products Ltd
+
+OUI:4C8093*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:4C8B55*
+ ID_OUI_FROM_DATABASE=Grupo Digicon
+
+OUI:4C8BEF*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:4C8D79*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:4C8FA5*
+ ID_OUI_FROM_DATABASE=Jastec
+
+OUI:4C98EF*
+ ID_OUI_FROM_DATABASE=Zeo
+
+OUI:4C9E80*
+ ID_OUI_FROM_DATABASE=KYOKKO ELECTRIC Co., Ltd.
+
+OUI:4C9EE4*
+ ID_OUI_FROM_DATABASE=Hanyang Navicom Co.,Ltd.
+
+OUI:4CA74B*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent
+
+OUI:4CAA16*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies (Shanghai) Inc.
+
+OUI:4CAB33*
+ ID_OUI_FROM_DATABASE=KST technology
+
+OUI:4CAC0A*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:4CB16C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:4CB199*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:4CB4EA*
+ ID_OUI_FROM_DATABASE=HRD (S) PTE., LTD.
+
+OUI:4CB9C8*
+ ID_OUI_FROM_DATABASE=CONET CO., LTD.
+
+OUI:4CBAA3*
+ ID_OUI_FROM_DATABASE=Bison Electronics Inc.
+
+OUI:4CBCA5*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:4CC452*
+ ID_OUI_FROM_DATABASE=Shang Hai Tyd. Electon Technology Ltd.
+
+OUI:4CC602*
+ ID_OUI_FROM_DATABASE=Radios, Inc.
+
+OUI:4CC94F*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:4CCA53*
+ ID_OUI_FROM_DATABASE=Skyera, Inc.
+
+OUI:4CE676*
+ ID_OUI_FROM_DATABASE=Buffalo Inc.
+
+OUI:4CEB42*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:4CEDDE*
+ ID_OUI_FROM_DATABASE=Askey Computer Corp
+
+OUI:4CF737*
+ ID_OUI_FROM_DATABASE=SamJi Electronics Co., Ltd
+
+OUI:50008C*
+ ID_OUI_FROM_DATABASE=Hong Kong Telecommunications (HKT) Limited
+
+OUI:5001BB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:50053D*
+ ID_OUI_FROM_DATABASE=CyWee Group Ltd
+
+OUI:500B32*
+ ID_OUI_FROM_DATABASE=Foxda Technology Industrial(ShenZhen)Co.,LTD
+
+OUI:500E6D*
+ ID_OUI_FROM_DATABASE=TrafficCast International
+
+OUI:5011EB*
+ ID_OUI_FROM_DATABASE=SilverNet Ltd
+
+OUI:502267*
+ ID_OUI_FROM_DATABASE=PixeLINK
+
+OUI:50252B*
+ ID_OUI_FROM_DATABASE=Nethra Imaging Incorporated
+
+OUI:502690*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
+OUI:502A7E*
+ ID_OUI_FROM_DATABASE=Smart electronic GmbH
+
+OUI:502A8B*
+ ID_OUI_FROM_DATABASE=Telekom Research and Development Sdn Bhd
+
+OUI:502D1D*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:502DA2*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:502DF4*
+ ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH
+
+OUI:502ECE*
+ ID_OUI_FROM_DATABASE=Asahi Electronics Co.,Ltd
+
+OUI:503955*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:503DE5*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:503F56*
+ ID_OUI_FROM_DATABASE=Syncmold Enterprise Corp
+
+OUI:50465D*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:5048EB*
+ ID_OUI_FROM_DATABASE=BEIJING HAIHEJINSHENG NETWORK TECHNOLOGY CO. LTD.
+
+OUI:504A5E*
+ ID_OUI_FROM_DATABASE=Masimo Corporation
+
+OUI:504F94*
+ ID_OUI_FROM_DATABASE=Loxone Electronics GmbH
+
+OUI:505663*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:5057A8*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:506028*
+ ID_OUI_FROM_DATABASE=Xirrus Inc.
+
+OUI:506313*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:506441*
+ ID_OUI_FROM_DATABASE=Greenlee
+
+OUI:5067F0*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:506F9A*
+ ID_OUI_FROM_DATABASE=Wi-Fi Alliance
+
+OUI:5070E5*
+ ID_OUI_FROM_DATABASE=He Shan World Fair Electronics Technology Limited
+
+OUI:50724D*
+ ID_OUI_FROM_DATABASE=BEG Brueck Electronic GmbH
+
+OUI:5076A6*
+ ID_OUI_FROM_DATABASE=Ecil Informatica Ind. Com. Ltda
+
+OUI:50795B*
+ ID_OUI_FROM_DATABASE=Interexport Telecomunicaciones S.A.
+
+OUI:507D02*
+ ID_OUI_FROM_DATABASE=BIODIT
+
+OUI:507E5D*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:5087B8*
+ ID_OUI_FROM_DATABASE=Nuvyyo Inc
+
+OUI:508A42*
+ ID_OUI_FROM_DATABASE=Uptmate Technology Co., LTD
+
+OUI:508ACB*
+ ID_OUI_FROM_DATABASE=SHENZHEN MAXMADE TECHNOLOGY CO., LTD.
+
+OUI:508C77*
+ ID_OUI_FROM_DATABASE=DIRMEIER Schanktechnik GmbH &Co KG
+
+OUI:50934F*
+ ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda.
+
+OUI:509772*
+ ID_OUI_FROM_DATABASE=Westinghouse Digital
+
+OUI:50A4C8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:50A6E3*
+ ID_OUI_FROM_DATABASE=David Clark Company
+
+OUI:50A733*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:50ABBF*
+ ID_OUI_FROM_DATABASE=Hoseo Telecom
+
+OUI:50AF73*
+ ID_OUI_FROM_DATABASE=Shenzhen Bitland Information Technology Co., Ltd.
+
+OUI:50B7C3*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
+OUI:50C58D*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:50C971*
+ ID_OUI_FROM_DATABASE=GN Netcom A/S
+
+OUI:50CCF8*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
+
+OUI:50CE75*
+ ID_OUI_FROM_DATABASE=Measy Electronics Ltd
+
+OUI:50D274*
+ ID_OUI_FROM_DATABASE=Steffes Corporation
+
+OUI:50D6D7*
+ ID_OUI_FROM_DATABASE=Takahata Precision
+
+OUI:50E549*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:50EAD6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:50EB1A*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc
+
+OUI:50ED94*
+ ID_OUI_FROM_DATABASE=Egatel SL
+
+OUI:50F003*
+ ID_OUI_FROM_DATABASE=Open Stack, Inc.
+
+OUI:50F61A*
+ ID_OUI_FROM_DATABASE=Kunshan JADE Technologies co., Ltd.
+
+OUI:50FAAB*
+ ID_OUI_FROM_DATABASE=L-tek d.o.o.
+
+OUI:50FC30*
+ ID_OUI_FROM_DATABASE=Treehouse Labs
+
+OUI:5403F5*
+ ID_OUI_FROM_DATABASE=EBN Technology Corp.
+
+OUI:540496*
+ ID_OUI_FROM_DATABASE=Gigawave LTD
+
+OUI:5404A6*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:54055F*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent
+
+OUI:54115F*
+ ID_OUI_FROM_DATABASE=Atamo Pty Ltd
+
+OUI:541DFB*
+ ID_OUI_FROM_DATABASE=Freestyle Energy Ltd
+
+OUI:541FD5*
+ ID_OUI_FROM_DATABASE=Advantage Electronics
+
+OUI:542018*
+ ID_OUI_FROM_DATABASE=Tely Labs
+
+OUI:542696*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:542A9C*
+ ID_OUI_FROM_DATABASE=LSY Defense, LLC.
+
+OUI:543131*
+ ID_OUI_FROM_DATABASE=Raster Vision Ltd
+
+OUI:5435DF*
+ ID_OUI_FROM_DATABASE=Symeo GmbH
+
+OUI:543968*
+ ID_OUI_FROM_DATABASE=Edgewater Networks Inc
+
+OUI:543D37*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:544249*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:54466B*
+ ID_OUI_FROM_DATABASE=Shenzhen CZTIC Electronic Technology Co., Ltd
+
+OUI:544A05*
+ ID_OUI_FROM_DATABASE=wenglor sensoric gmbh
+
+OUI:5453ED*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:545EBD*
+ ID_OUI_FROM_DATABASE=NL Technologies
+
+OUI:545FA9*
+ ID_OUI_FROM_DATABASE=Teracom Limited
+
+OUI:5461EA*
+ ID_OUI_FROM_DATABASE=Zaplox AB
+
+OUI:547398*
+ ID_OUI_FROM_DATABASE=Toyo Electronics Corporation
+
+OUI:5474E6*
+ ID_OUI_FROM_DATABASE=Webtech Wireless
+
+OUI:5475D0*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:54781A*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:547975*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:547F54*
+ ID_OUI_FROM_DATABASE=INGENICO
+
+OUI:547FA8*
+ ID_OUI_FROM_DATABASE=TELCO systems, s.r.o.
+
+OUI:547FEE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:5481AD*
+ ID_OUI_FROM_DATABASE=Eagle Research Corporation
+
+OUI:54847B*
+ ID_OUI_FROM_DATABASE=Digital Devices GmbH
+
+OUI:548922*
+ ID_OUI_FROM_DATABASE=Zelfy Inc
+
+OUI:548998*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:5492BE*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:549478*
+ ID_OUI_FROM_DATABASE=Silvershore Technology Partners
+
+OUI:549A16*
+ ID_OUI_FROM_DATABASE=Uzushio Electric Co.,Ltd.
+
+OUI:549B12*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:549D85*
+ ID_OUI_FROM_DATABASE=EnerAccess inc
+
+OUI:54A04F*
+ ID_OUI_FROM_DATABASE=t-mac Technologies Ltd
+
+OUI:54A51B*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:54A9D4*
+ ID_OUI_FROM_DATABASE=Minibar Systems
+
+OUI:54B620*
+ ID_OUI_FROM_DATABASE=SUHDOL E&C Co.Ltd.
+
+OUI:54CDA7*
+ ID_OUI_FROM_DATABASE=Fujian Shenzhou Electronic Co.,Ltd
+
+OUI:54D0ED*
+ ID_OUI_FROM_DATABASE=AXIM Communications
+
+OUI:54D1B0*
+ ID_OUI_FROM_DATABASE=Universal Laser Systems, Inc
+
+OUI:54D46F*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:54DF63*
+ ID_OUI_FROM_DATABASE=Intrakey technologies GmbH
+
+OUI:54E032*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:54E63F*
+ ID_OUI_FROM_DATABASE=ShenZhen LingKeWeiEr Technology Co., Ltd.
+
+OUI:54E6FC*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:54F5B6*
+ ID_OUI_FROM_DATABASE=ORIENTAL PACIFIC INTERNATIONAL LIMITED
+
+OUI:54F666*
+ ID_OUI_FROM_DATABASE=Berthold Technologies GmbH and Co.KG
+
+OUI:54FDBF*
+ ID_OUI_FROM_DATABASE=Scheidt & Bachmann GmbH
+
+OUI:580556*
+ ID_OUI_FROM_DATABASE=Elettronica GF S.r.L.
+
+OUI:5808FA*
+ ID_OUI_FROM_DATABASE=Fiber Optic & telecommunication INC.
+
+OUI:5809E5*
+ ID_OUI_FROM_DATABASE=Kivic Inc.
+
+OUI:581243*
+ ID_OUI_FROM_DATABASE=AcSiP Technology Corp.
+
+OUI:581626*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:58170C*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:581D91*
+ ID_OUI_FROM_DATABASE=Advanced Mobile Telecom co.,ltd.
+
+OUI:581FAA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:581FEF*
+ ID_OUI_FROM_DATABASE=Tuttnaer LTD
+
+OUI:582EFE*
+ ID_OUI_FROM_DATABASE=Lighting Science Group
+
+OUI:582F42*
+ ID_OUI_FROM_DATABASE=Universal Electric Corporation
+
+OUI:58343B*
+ ID_OUI_FROM_DATABASE=Glovast Technology Ltd.
+
+OUI:5835D9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:583CC6*
+ ID_OUI_FROM_DATABASE=Omneality Ltd.
+
+OUI:5842E4*
+ ID_OUI_FROM_DATABASE=Sigma International General Medical Apparatus, LLC.
+
+OUI:5846E1*
+ ID_OUI_FROM_DATABASE=Baxter Healthcare
+
+OUI:5848C0*
+ ID_OUI_FROM_DATABASE=COFLEC
+
+OUI:5849BA*
+ ID_OUI_FROM_DATABASE=Chitai Electronic Corp.
+
+OUI:584C19*
+ ID_OUI_FROM_DATABASE=Chongqing Guohong Technology Development Company Limited
+
+OUI:584CEE*
+ ID_OUI_FROM_DATABASE=Digital One Technologies, Limited
+
+OUI:585076*
+ ID_OUI_FROM_DATABASE=Linear Equipamentos Eletronicos SA
+
+OUI:5850E6*
+ ID_OUI_FROM_DATABASE=Best Buy Corporation
+
+OUI:5855CA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:58570D*
+ ID_OUI_FROM_DATABASE=Danfoss Solar Inverters
+
+OUI:5865E6*
+ ID_OUI_FROM_DATABASE=INFOMARK CO., LTD.
+
+OUI:5866BA*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:58671A*
+ ID_OUI_FROM_DATABASE=BARNES&NOBLE.COM
+
+OUI:58677F*
+ ID_OUI_FROM_DATABASE=Clare Controls Inc.
+
+OUI:58696C*
+ ID_OUI_FROM_DATABASE=Fujian Ruijie Networks co, ltd
+
+OUI:5869F9*
+ ID_OUI_FROM_DATABASE=Fusion Transactive Ltd.
+
+OUI:586D8F*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:587521*
+ ID_OUI_FROM_DATABASE=CJSC RTSoft
+
+OUI:587675*
+ ID_OUI_FROM_DATABASE=Beijing ECHO Technologies Co.,Ltd
+
+OUI:587FC8*
+ ID_OUI_FROM_DATABASE=S2M
+
+OUI:5884E4*
+ ID_OUI_FROM_DATABASE=IP500 Alliance e.V.
+
+OUI:58874C*
+ ID_OUI_FROM_DATABASE=LITE-ON CLEAN ENERGY TECHNOLOGY CORP.
+
+OUI:5887E2*
+ ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd.
+
+OUI:588D09*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:5891CF*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:58920D*
+ ID_OUI_FROM_DATABASE=Kinetic Avionics Limited
+
+OUI:589396*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:58946B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:5894CF*
+ ID_OUI_FROM_DATABASE=Vertex Standard LMR, Inc.
+
+OUI:58971E*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:589835*
+ ID_OUI_FROM_DATABASE=Technicolor
+
+OUI:58986F*
+ ID_OUI_FROM_DATABASE=Revolution Display
+
+OUI:58A76F*
+ ID_OUI_FROM_DATABASE=iD corporation
+
+OUI:58B035*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:58B0D4*
+ ID_OUI_FROM_DATABASE=ZuniData Systems Inc.
+
+OUI:58B9E1*
+ ID_OUI_FROM_DATABASE=Crystalfontz America, Inc.
+
+OUI:58BC27*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:58BDA3*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:58BFEA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:58C232*
+ ID_OUI_FROM_DATABASE=NEC Corporation
+
+OUI:58C38B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:58CF4B*
+ ID_OUI_FROM_DATABASE=Lufkin Industries
+
+OUI:58D071*
+ ID_OUI_FROM_DATABASE=BW Broadcast
+
+OUI:58D08F*
+ ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group
+
+OUI:58D6D3*
+ ID_OUI_FROM_DATABASE=Dairy Cheq Inc
+
+OUI:58DB8D*
+ ID_OUI_FROM_DATABASE=Fast Co., Ltd.
+
+OUI:58E476*
+ ID_OUI_FROM_DATABASE=CENTRON COMMUNICATIONS TECHNOLOGIES FUJIAN CO.,LTD
+
+OUI:58E636*
+ ID_OUI_FROM_DATABASE=EVRsafe Technologies
+
+OUI:58E747*
+ ID_OUI_FROM_DATABASE=Deltanet AG
+
+OUI:58E808*
+ ID_OUI_FROM_DATABASE=AUTONICS CORPORATION
+
+OUI:58EB14*
+ ID_OUI_FROM_DATABASE=Proteus Digital Health
+
+OUI:58ECE1*
+ ID_OUI_FROM_DATABASE=Newport Corporation
+
+OUI:58EECE*
+ ID_OUI_FROM_DATABASE=Icon Time Systems
+
+OUI:58F67B*
+ ID_OUI_FROM_DATABASE=Xia Men UnionCore Technology LTD.
+
+OUI:58F6BF*
+ ID_OUI_FROM_DATABASE=Kyoto University
+
+OUI:58F98E*
+ ID_OUI_FROM_DATABASE=SECUDOS GmbH
+
+OUI:58FD20*
+ ID_OUI_FROM_DATABASE=Bravida Sakerhet AB
+
+OUI:5C076F*
+ ID_OUI_FROM_DATABASE=Thought Creator
+
+OUI:5C0A5B*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD.
+
+OUI:5C0CBB*
+ ID_OUI_FROM_DATABASE=CELIZION Inc.
+
+OUI:5C0E8B*
+ ID_OUI_FROM_DATABASE=Motorola
+
+OUI:5C1437*
+ ID_OUI_FROM_DATABASE=Thyssenkrupp Aufzugswerke GmbH
+
+OUI:5C16C7*
+ ID_OUI_FROM_DATABASE=Big Switch Networks
+
+OUI:5C1737*
+ ID_OUI_FROM_DATABASE=I-View Now, LLC.
+
+OUI:5C17D3*
+ ID_OUI_FROM_DATABASE=LGE
+
+OUI:5C18B5*
+ ID_OUI_FROM_DATABASE=Talon Communications
+
+OUI:5C20D0*
+ ID_OUI_FROM_DATABASE=Asoni Communication Co., Ltd.
+
+OUI:5C2479*
+ ID_OUI_FROM_DATABASE=Baltech AG
+
+OUI:5C260A*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:5C338E*
+ ID_OUI_FROM_DATABASE=Alpha Networkc Inc.
+
+OUI:5C353B*
+ ID_OUI_FROM_DATABASE=Compal Broadband Networks Inc.
+
+OUI:5C35DA*
+ ID_OUI_FROM_DATABASE=There Corporation Oy
+
+OUI:5C38E0*
+ ID_OUI_FROM_DATABASE=Shanghai Super Electronics Technology Co.,LTD
+
+OUI:5C4058*
+ ID_OUI_FROM_DATABASE=Jefferson Audio Video Systems, Inc.
+
+OUI:5C43D2*
+ ID_OUI_FROM_DATABASE=HAZEMEYER
+
+OUI:5C4A26*
+ ID_OUI_FROM_DATABASE=Enguity Technology Corp
+
+OUI:5C4CA9*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:5C5015*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:5C514F*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:5C56ED*
+ ID_OUI_FROM_DATABASE=3pleplay Electronics Private Limited
+
+OUI:5C571A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5C57C8*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:5C5948*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:5C5EAB*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:5C63BF*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:5C6984*
+ ID_OUI_FROM_DATABASE=NUVICO
+
+OUI:5C6A7D*
+ ID_OUI_FROM_DATABASE=KENTKART EGE ELEKTRONIK SAN. VE TIC. LTD. STI.
+
+OUI:5C6B32*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:5C6D20*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:5C6F4F*
+ ID_OUI_FROM_DATABASE=S.A. SISTEL
+
+OUI:5C7757*
+ ID_OUI_FROM_DATABASE=Haivision Network Video
+
+OUI:5C7D5E*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:5C864A*
+ ID_OUI_FROM_DATABASE=Secret Labs LLC
+
+OUI:5C8778*
+ ID_OUI_FROM_DATABASE=Cybertelbridge co.,ltd
+
+OUI:5C89D4*
+ ID_OUI_FROM_DATABASE=Beijing Banner Electric Co.,Ltd
+
+OUI:5C95AE*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:5C969D*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:5C9AD8*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
+OUI:5CA39D*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD.
+
+OUI:5CAC4C*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:5CB524*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:5CBD9E*
+ ID_OUI_FROM_DATABASE=HONGKONG MIRACLE EAGLE TECHNOLOGY(GROUP) LIMITED
+
+OUI:5CC213*
+ ID_OUI_FROM_DATABASE=Fr. Sauter AG
+
+OUI:5CC6D0*
+ ID_OUI_FROM_DATABASE=Skyworth Digital technology(shenzhen)co.ltd.
+
+OUI:5CC9D3*
+ ID_OUI_FROM_DATABASE=PALLADIUM ENERGY ELETRONICA DA AMAZONIA LTDA
+
+OUI:5CCA32*
+ ID_OUI_FROM_DATABASE=Theben AG
+
+OUI:5CCEAD*
+ ID_OUI_FROM_DATABASE=CDYNE Corporation
+
+OUI:5CD135*
+ ID_OUI_FROM_DATABASE=Xtreme Power Systems
+
+OUI:5CD2E4*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:5CD41B*
+ ID_OUI_FROM_DATABASE=UCZOON Technology Co., LTD
+
+OUI:5CD4AB*
+ ID_OUI_FROM_DATABASE=Zektor
+
+OUI:5CD998*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:5CDAD4*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:5CE0CA*
+ ID_OUI_FROM_DATABASE=FeiTian United (Beijing) System Technology Co., Ltd.
+
+OUI:5CE0F6*
+ ID_OUI_FROM_DATABASE=NIC.br- Nucleo de Informacao e Coordenacao do Ponto BR
+
+OUI:5CE223*
+ ID_OUI_FROM_DATABASE=Delphin Technology AG
+
+OUI:5CE286*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:5CE2F4*
+ ID_OUI_FROM_DATABASE=AcSiP Technology Corp.
+
+OUI:5CE8EB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:5CEB4E*
+ ID_OUI_FROM_DATABASE=R. STAHL HMI Systems GmbH
+
+OUI:5CEE79*
+ ID_OUI_FROM_DATABASE=Global Digitech Co LTD
+
+OUI:5CF207*
+ ID_OUI_FROM_DATABASE=Speco Technologies
+
+OUI:5CF3FC*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:5CF9DD*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:5CFF35*
+ ID_OUI_FROM_DATABASE=Wistron Corporation
+
+OUI:6002B4*
+ ID_OUI_FROM_DATABASE=Wistron NeWeb Corp.
+
+OUI:600F77*
+ ID_OUI_FROM_DATABASE=SilverPlus, Inc
+
+OUI:601199*
+ ID_OUI_FROM_DATABASE=Data-Tester Inc.
+
+OUI:601283*
+ ID_OUI_FROM_DATABASE=Soluciones Tecnologicas para la Salud y el Bienestar SA
+
+OUI:6015C7*
+ ID_OUI_FROM_DATABASE=IdaTech
+
+OUI:60190C*
+ ID_OUI_FROM_DATABASE=RRAMAC
+
+OUI:601929*
+ ID_OUI_FROM_DATABASE=VOLTRONIC POWER TECHNOLOGY(SHENZHEN) CORP.
+
+OUI:601D0F*
+ ID_OUI_FROM_DATABASE=Midnite Solar
+
+OUI:6021C0*
+ ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd.
+
+OUI:602A54*
+ ID_OUI_FROM_DATABASE=CardioTek B.V.
+
+OUI:602AD0*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:6032F0*
+ ID_OUI_FROM_DATABASE=Mplus technology
+
+OUI:60334B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:603553*
+ ID_OUI_FROM_DATABASE=Buwon Technology
+
+OUI:6036DD*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:60380E*
+ ID_OUI_FROM_DATABASE=Alps Electric Co.,
+
+OUI:60391F*
+ ID_OUI_FROM_DATABASE=ABB Ltd
+
+OUI:603FC5*
+ ID_OUI_FROM_DATABASE=COX CO., LTD
+
+OUI:6044F5*
+ ID_OUI_FROM_DATABASE=Easy Digital Ltd.
+
+OUI:60455E*
+ ID_OUI_FROM_DATABASE=Liptel s.r.o.
+
+OUI:6045BD*
+ ID_OUI_FROM_DATABASE=Microsoft
+
+OUI:604616*
+ ID_OUI_FROM_DATABASE=XIAMEN VANN INTELLIGENT CO., LTD
+
+OUI:6052D0*
+ ID_OUI_FROM_DATABASE=FACTS Engineering
+
+OUI:605464*
+ ID_OUI_FROM_DATABASE=Eyedro Green Solutions Inc.
+
+OUI:6063FD*
+ ID_OUI_FROM_DATABASE=Transcend Communication Beijing Co.,Ltd.
+
+OUI:606720*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:606BBD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
+
+OUI:606C66*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:60735C*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:60748D*
+ ID_OUI_FROM_DATABASE=Atmaca Elektronik
+
+OUI:607688*
+ ID_OUI_FROM_DATABASE=Velodyne
+
+OUI:6083B2*
+ ID_OUI_FROM_DATABASE=GkWare e.K.
+
+OUI:60843B*
+ ID_OUI_FROM_DATABASE=Soladigm, Inc.
+
+OUI:608645*
+ ID_OUI_FROM_DATABASE=Avery Weigh-Tronix, LLC
+
+OUI:60893C*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific P.O.A.
+
+OUI:6089B1*
+ ID_OUI_FROM_DATABASE=Key Digital Systems
+
+OUI:6089B7*
+ ID_OUI_FROM_DATABASE=KAEL MÜHENDİSLİK ELEKTRONİK TİCARET SANAYİ LİMİTED ŞİRKETİ
+
+OUI:608C2B*
+ ID_OUI_FROM_DATABASE=Hanson Technology
+
+OUI:608D17*
+ ID_OUI_FROM_DATABASE=Sentrus Government Systems Division, Inc
+
+OUI:609084*
+ ID_OUI_FROM_DATABASE=DSSD Inc
+
+OUI:609AA4*
+ ID_OUI_FROM_DATABASE=GVI SECURITY INC.
+
+OUI:609E64*
+ ID_OUI_FROM_DATABASE=Vivonic GmbH
+
+OUI:609F9D*
+ ID_OUI_FROM_DATABASE=CloudSwitch
+
+OUI:60A10A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:60A44C*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:60B185*
+ ID_OUI_FROM_DATABASE=ATH system
+
+OUI:60B3C4*
+ ID_OUI_FROM_DATABASE=Elber Srl
+
+OUI:60B606*
+ ID_OUI_FROM_DATABASE=Phorus
+
+OUI:60B933*
+ ID_OUI_FROM_DATABASE=Deutron Electronics Corp.
+
+OUI:60B982*
+ ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A.
+
+OUI:60BB0C*
+ ID_OUI_FROM_DATABASE=Beijing HuaqinWorld Technology Co,Ltd
+
+OUI:60BC4C*
+ ID_OUI_FROM_DATABASE=EWM Hightec Welding GmbH
+
+OUI:60BD91*
+ ID_OUI_FROM_DATABASE=Move Innovation
+
+OUI:60C547*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:60C5A8*
+ ID_OUI_FROM_DATABASE=Beijing LT Honway Technology Co.,Ltd
+
+OUI:60C980*
+ ID_OUI_FROM_DATABASE=Trymus
+
+OUI:60CBFB*
+ ID_OUI_FROM_DATABASE=AirScape Inc.
+
+OUI:60CDC5*
+ ID_OUI_FROM_DATABASE=Taiwan Carol Electronics., Ltd
+
+OUI:60D0A9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:60D1AA*
+ ID_OUI_FROM_DATABASE=Vishal Telecommunications Pvt Ltd
+
+OUI:60D2B9*
+ ID_OUI_FROM_DATABASE=REALAND BIO CO., LTD.
+
+OUI:60D30A*
+ ID_OUI_FROM_DATABASE=Quatius Limited
+
+OUI:60D819*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:60DA23*
+ ID_OUI_FROM_DATABASE=Estech Co.,Ltd
+
+OUI:60DE44*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:60E956*
+ ID_OUI_FROM_DATABASE=Ayla Networks, Inc
+
+OUI:60EB69*
+ ID_OUI_FROM_DATABASE=Quanta computer Inc.
+
+OUI:60F13D*
+ ID_OUI_FROM_DATABASE=JABLOCOM s.r.o.
+
+OUI:60F281*
+ ID_OUI_FROM_DATABASE=TRANWO TECHNOLOGY CO., LTD.
+
+OUI:60F2EF*
+ ID_OUI_FROM_DATABASE=VisionVera International Co., Ltd.
+
+OUI:60F3DA*
+ ID_OUI_FROM_DATABASE=Logic Way GmbH
+
+OUI:60F494*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:60F59C*
+ ID_OUI_FROM_DATABASE=CRU-Dataport
+
+OUI:60F673*
+ ID_OUI_FROM_DATABASE=TERUMO CORPORATION
+
+OUI:60FACD*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:60FB42*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:6400F1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:64094C*
+ ID_OUI_FROM_DATABASE=Beijing Superbee Wireless Technology Co.,Ltd
+
+OUI:640E36*
+ ID_OUI_FROM_DATABASE=TAZTAG
+
+OUI:640E94*
+ ID_OUI_FROM_DATABASE=Pluribus Networks, Inc.
+
+OUI:640F28*
+ ID_OUI_FROM_DATABASE=2wire
+
+OUI:641084*
+ ID_OUI_FROM_DATABASE=HEXIUM Technical Development Co., Ltd.
+
+OUI:64168D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:6416F0*
+ ID_OUI_FROM_DATABASE=Shehzhen Huawei Communication Technologies Co., Ltd.
+
+OUI:641A22*
+ ID_OUI_FROM_DATABASE=Heliospectra/Woodhill Investments
+
+OUI:641C67*
+ ID_OUI_FROM_DATABASE=DIGIBRAS INDUSTRIA DO BRASILS/A
+
+OUI:641E81*
+ ID_OUI_FROM_DATABASE=Dowslake Microsystems
+
+OUI:64200C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:642216*
+ ID_OUI_FROM_DATABASE=Shandong Taixin Electronic co.,Ltd
+
+OUI:642400*
+ ID_OUI_FROM_DATABASE=Xorcom Ltd.
+
+OUI:642737*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:642DB7*
+ ID_OUI_FROM_DATABASE=SEUNGIL ELECTRONICS
+
+OUI:643150*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:64317E*
+ ID_OUI_FROM_DATABASE=Dexin Corporation
+
+OUI:643409*
+ ID_OUI_FROM_DATABASE=BITwave Pte Ltd
+
+OUI:644346*
+ ID_OUI_FROM_DATABASE=GuangDong Quick Network Computer CO.,LTD
+
+OUI:644BC3*
+ ID_OUI_FROM_DATABASE=Shanghai WOASiS Telecommunications Ltd., Co.
+
+OUI:644BF0*
+ ID_OUI_FROM_DATABASE=CalDigit, Inc
+
+OUI:644D70*
+ ID_OUI_FROM_DATABASE=dSPACE GmbH
+
+OUI:644F74*
+ ID_OUI_FROM_DATABASE=LENUS Co., Ltd.
+
+OUI:64517E*
+ ID_OUI_FROM_DATABASE=LONG BEN (DONGGUAN) ELECTRONIC TECHNOLOGY CO.,LTD.
+
+OUI:645299*
+ ID_OUI_FROM_DATABASE=Chamberlain
+
+OUI:64535D*
+ ID_OUI_FROM_DATABASE=Frauscher Sensortechnik
+
+OUI:645422*
+ ID_OUI_FROM_DATABASE=Equinox Payments
+
+OUI:645563*
+ ID_OUI_FROM_DATABASE=Intelight Inc.
+
+OUI:64557F*
+ ID_OUI_FROM_DATABASE=NSFOCUS Information Technology Co., Ltd.
+
+OUI:645A04*
+ ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd.
+
+OUI:645DD7*
+ ID_OUI_FROM_DATABASE=Shenzhen Lifesense Medical Electronics Co., Ltd.
+
+OUI:645EBE*
+ ID_OUI_FROM_DATABASE=Yahoo! JAPAN
+
+OUI:645FFF*
+ ID_OUI_FROM_DATABASE=Nicolet Neuro
+
+OUI:646223*
+ ID_OUI_FROM_DATABASE=Cellient Co., Ltd.
+
+OUI:6465C0*
+ ID_OUI_FROM_DATABASE=Nuvon, Inc
+
+OUI:6466B3*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:646707*
+ ID_OUI_FROM_DATABASE=Beijing Omnific Technology, Ltd.
+
+OUI:64680C*
+ ID_OUI_FROM_DATABASE=COMTREND
+
+OUI:6469BC*
+ ID_OUI_FROM_DATABASE=Hytera Communications Co .,ltd
+
+OUI:646E6C*
+ ID_OUI_FROM_DATABASE=Radio Datacom LLC
+
+OUI:647002*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:6473E2*
+ ID_OUI_FROM_DATABASE=Arbiter Systems, Inc.
+
+OUI:647657*
+ ID_OUI_FROM_DATABASE=Innovative Security Designs
+
+OUI:647791*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:647BD4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:647C34*
+ ID_OUI_FROM_DATABASE=Ubee Interactive Corp.
+
+OUI:647D81*
+ ID_OUI_FROM_DATABASE=YOKOTA INDUSTRIAL CO,.LTD
+
+OUI:647FDA*
+ ID_OUI_FROM_DATABASE=TEKTELIC Communications Inc.
+
+OUI:64808B*
+ ID_OUI_FROM_DATABASE=VG Controls, Inc.
+
+OUI:648099*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:648125*
+ ID_OUI_FROM_DATABASE=Alphatron Marine BV
+
+OUI:648788*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:6487D7*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:64995D*
+ ID_OUI_FROM_DATABASE=LGE
+
+OUI:649968*
+ ID_OUI_FROM_DATABASE=Elentec
+
+OUI:6499A0*
+ ID_OUI_FROM_DATABASE=AG Elektronik AB
+
+OUI:649B24*
+ ID_OUI_FROM_DATABASE=V Technology Co., Ltd.
+
+OUI:649C8E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:649EF3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:649FF7*
+ ID_OUI_FROM_DATABASE=Kone OYj
+
+OUI:64A0E7*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:64A232*
+ ID_OUI_FROM_DATABASE=OOO Samlight
+
+OUI:64A341*
+ ID_OUI_FROM_DATABASE=Wonderlan (Beijing) Technology Co., Ltd.
+
+OUI:64A3CB*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:64A769*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:64A837*
+ ID_OUI_FROM_DATABASE=Juni Korea Co., Ltd
+
+OUI:64AE0C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:64AE88*
+ ID_OUI_FROM_DATABASE=Polytec GmbH
+
+OUI:64B64A*
+ ID_OUI_FROM_DATABASE=ViVOtech, Inc.
+
+OUI:64B9E8*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:64BC11*
+ ID_OUI_FROM_DATABASE=CombiQ AB
+
+OUI:64C5AA*
+ ID_OUI_FROM_DATABASE=South African Broadcasting Corporation
+
+OUI:64C6AF*
+ ID_OUI_FROM_DATABASE=AXERRA Networks Ltd
+
+OUI:64C944*
+ ID_OUI_FROM_DATABASE=LARK Technologies, Inc
+
+OUI:64D02D*
+ ID_OUI_FROM_DATABASE=Next Generation Integration (NGI)
+
+OUI:64D1A3*
+ ID_OUI_FROM_DATABASE=Sitecom Europe BV
+
+OUI:64D241*
+ ID_OUI_FROM_DATABASE=Keith & Koep GmbH
+
+OUI:64D4DA*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:64D814*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:64D912*
+ ID_OUI_FROM_DATABASE=Solidica, Inc.
+
+OUI:64D989*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:64DB18*
+ ID_OUI_FROM_DATABASE=OpenPattern
+
+OUI:64DC01*
+ ID_OUI_FROM_DATABASE=Static Systems Group PLC
+
+OUI:64DE1C*
+ ID_OUI_FROM_DATABASE=Kingnetic Pte Ltd
+
+OUI:64E161*
+ ID_OUI_FROM_DATABASE=DEP Corp.
+
+OUI:64E682*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:64E84F*
+ ID_OUI_FROM_DATABASE=Serialway Communication Technology Co. Ltd
+
+OUI:64E8E6*
+ ID_OUI_FROM_DATABASE=global moisture management system
+
+OUI:64ED57*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:64ED62*
+ ID_OUI_FROM_DATABASE=WOORI SYSTEMS Co., Ltd
+
+OUI:64F242*
+ ID_OUI_FROM_DATABASE=Gerdes Aktiengesellschaft
+
+OUI:64F50E*
+ ID_OUI_FROM_DATABASE=Kinion Technology Company Limited
+
+OUI:64F970*
+ ID_OUI_FROM_DATABASE=Kenade Electronics Technology Co.,LTD.
+
+OUI:64F987*
+ ID_OUI_FROM_DATABASE=Avvasi Inc.
+
+OUI:64FC8C*
+ ID_OUI_FROM_DATABASE=Zonar Systems
+
+OUI:6805CA*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:680927*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:68122D*
+ ID_OUI_FROM_DATABASE=Special Instrument Development Co., Ltd.
+
+OUI:6815D3*
+ ID_OUI_FROM_DATABASE=Zaklady Elektroniki i Mechaniki Precyzyjnej R&G S.A.
+
+OUI:681605*
+ ID_OUI_FROM_DATABASE=Systems And Electronic Development FZCO
+
+OUI:681729*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:681AB2*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:681CA2*
+ ID_OUI_FROM_DATABASE=Rosewill Inc.
+
+OUI:681E8B*
+ ID_OUI_FROM_DATABASE=InfoSight Corporation
+
+OUI:681FD8*
+ ID_OUI_FROM_DATABASE=Advanced Telemetry
+
+OUI:68234B*
+ ID_OUI_FROM_DATABASE=Nihon Dengyo Kousaku
+
+OUI:683B1E*
+ ID_OUI_FROM_DATABASE=Countwise LTD
+
+OUI:684352*
+ ID_OUI_FROM_DATABASE=Bhuu Limited
+
+OUI:684B88*
+ ID_OUI_FROM_DATABASE=Galtronics Telemetry Inc.
+
+OUI:684CA8*
+ ID_OUI_FROM_DATABASE=Shenzhen Herotel Tech. Co., Ltd.
+
+OUI:6851B7*
+ ID_OUI_FROM_DATABASE=PowerCloud Systems, Inc.
+
+OUI:6854F5*
+ ID_OUI_FROM_DATABASE=enLighted Inc
+
+OUI:68597F*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent
+
+OUI:685B36*
+ ID_OUI_FROM_DATABASE=POWERTECH INDUSTRIAL CO., LTD.
+
+OUI:685D43*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:685E6B*
+ ID_OUI_FROM_DATABASE=PowerRay Co., Ltd.
+
+OUI:686359*
+ ID_OUI_FROM_DATABASE=Advanced Digital Broadcast SA
+
+OUI:6869F2*
+ ID_OUI_FROM_DATABASE=ComAp s.r.o.
+
+OUI:686E23*
+ ID_OUI_FROM_DATABASE=Wi3 Inc.
+
+OUI:687251*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks
+
+OUI:68784C*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:687924*
+ ID_OUI_FROM_DATABASE=ELS-GmbH & Co. KG
+
+OUI:6879ED*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
+
+OUI:687F74*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:688470*
+ ID_OUI_FROM_DATABASE=eSSys Co.,Ltd
+
+OUI:688540*
+ ID_OUI_FROM_DATABASE=IGI Mobile, Inc.
+
+OUI:6886A7*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:6886E7*
+ ID_OUI_FROM_DATABASE=Orbotix, Inc.
+
+OUI:68876B*
+ ID_OUI_FROM_DATABASE=INQ Mobile Limited
+
+OUI:689234*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:689423*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:68967B*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:68974B*
+ ID_OUI_FROM_DATABASE=Shenzhen Costar Electronics Co. Ltd.
+
+OUI:689C5E*
+ ID_OUI_FROM_DATABASE=AcSiP Technology Corp.
+
+OUI:68A1B7*
+ ID_OUI_FROM_DATABASE=Honghao Mingchuan Technology (Beijing) CO.,Ltd.
+
+OUI:68A3C4*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:68A40E*
+ ID_OUI_FROM_DATABASE=BSH Bosch and Siemens Home Appliances GmbH
+
+OUI:68A86D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:68AAD2*
+ ID_OUI_FROM_DATABASE=DATECS LTD.,
+
+OUI:68AB8A*
+ ID_OUI_FROM_DATABASE=RF IDeas
+
+OUI:68AF13*
+ ID_OUI_FROM_DATABASE=Futura Mobility
+
+OUI:68B43A*
+ ID_OUI_FROM_DATABASE=WaterFurnace International, Inc.
+
+OUI:68B599*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:68B6FC*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:68B8D9*
+ ID_OUI_FROM_DATABASE=Act KDE, Inc.
+
+OUI:68BC0C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:68BDAB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:68CA00*
+ ID_OUI_FROM_DATABASE=Octopus Systems Limited
+
+OUI:68CC9C*
+ ID_OUI_FROM_DATABASE=Mine Site Technologies
+
+OUI:68CD0F*
+ ID_OUI_FROM_DATABASE=U Tek Company Limited
+
+OUI:68CE4E*
+ ID_OUI_FROM_DATABASE=L-3 Communications Infrared Products
+
+OUI:68D1FD*
+ ID_OUI_FROM_DATABASE=Shenzhen Trimax Technology Co.,Ltd
+
+OUI:68D925*
+ ID_OUI_FROM_DATABASE=ProSys Development Services
+
+OUI:68DB96*
+ ID_OUI_FROM_DATABASE=OPWILL Technologies CO .,LTD
+
+OUI:68DCE8*
+ ID_OUI_FROM_DATABASE=PacketStorm Communications
+
+OUI:68E41F*
+ ID_OUI_FROM_DATABASE=Unglaube Identech GmbH
+
+OUI:68EBAE*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:68EBC5*
+ ID_OUI_FROM_DATABASE=Angstrem Telecom
+
+OUI:68ED43*
+ ID_OUI_FROM_DATABASE=Research In Motion
+
+OUI:68EFBD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:68F125*
+ ID_OUI_FROM_DATABASE=Data Controls Inc.
+
+OUI:68F895*
+ ID_OUI_FROM_DATABASE=Redflow Limited
+
+OUI:68FB95*
+ ID_OUI_FROM_DATABASE=Generalplus Technology Inc.
+
+OUI:6C0460*
+ ID_OUI_FROM_DATABASE=RBH Access Technologies Inc.
+
+OUI:6C0E0D*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:6C0F6A*
+ ID_OUI_FROM_DATABASE=JDC Tech Co., Ltd.
+
+OUI:6C1811*
+ ID_OUI_FROM_DATABASE=Decatur Electronics
+
+OUI:6C2056*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:6C22AB*
+ ID_OUI_FROM_DATABASE=Ainsworth Game Technology
+
+OUI:6C23B9*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:6C2995*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:6C2E33*
+ ID_OUI_FROM_DATABASE=Accelink Technologies Co.,Ltd.
+
+OUI:6C2E85*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:6C32DE*
+ ID_OUI_FROM_DATABASE=Indieon Technologies Pvt. Ltd.
+
+OUI:6C33A9*
+ ID_OUI_FROM_DATABASE=Magicjack LP
+
+OUI:6C391D*
+ ID_OUI_FROM_DATABASE=Beijing ZhongHuaHun Network Information center
+
+OUI:6C3A84*
+ ID_OUI_FROM_DATABASE=Shenzhen Aero-Startech. Co.Ltd
+
+OUI:6C3BE5*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:6C3E6D*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:6C3E9C*
+ ID_OUI_FROM_DATABASE=KE Knestel Elektronik GmbH
+
+OUI:6C40C6*
+ ID_OUI_FROM_DATABASE=Nimbus Data Systems, Inc.
+
+OUI:6C504D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:6C5A34*
+ ID_OUI_FROM_DATABASE=Shenzhen Haitianxiong Electronic Co., Ltd.
+
+OUI:6C5CDE*
+ ID_OUI_FROM_DATABASE=SunReports, Inc.
+
+OUI:6C5D63*
+ ID_OUI_FROM_DATABASE=ShenZhen Rapoo Technology Co., Ltd.
+
+OUI:6C5E7A*
+ ID_OUI_FROM_DATABASE=Ubiquitous Internet Telecom Co., Ltd
+
+OUI:6C626D*
+ ID_OUI_FROM_DATABASE=Micro-Star INT'L CO., LTD
+
+OUI:6C6F18*
+ ID_OUI_FROM_DATABASE=Stereotaxis, Inc.
+
+OUI:6C7039*
+ ID_OUI_FROM_DATABASE=Novar GmbH
+
+OUI:6C71D9*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc
+
+OUI:6C81FE*
+ ID_OUI_FROM_DATABASE=Mitsuba Corporation
+
+OUI:6C8336*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:6C8814*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:6C8CDB*
+ ID_OUI_FROM_DATABASE=Otus Technologies Ltd
+
+OUI:6C8D65*
+ ID_OUI_FROM_DATABASE=Wireless Glue Networks, Inc.
+
+OUI:6C92BF*
+ ID_OUI_FROM_DATABASE=Inspur Electronic Information Industry Co.,Ltd.
+
+OUI:6C9AC9*
+ ID_OUI_FROM_DATABASE=Valentine Research, Inc.
+
+OUI:6C9B02*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:6C9CE9*
+ ID_OUI_FROM_DATABASE=Nimble Storage
+
+OUI:6C9CED*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:6CA682*
+ ID_OUI_FROM_DATABASE=EDAM information & communications
+
+OUI:6CA780*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:6CA906*
+ ID_OUI_FROM_DATABASE=Telefield Ltd
+
+OUI:6CA96F*
+ ID_OUI_FROM_DATABASE=TransPacket AS
+
+OUI:6CAB4D*
+ ID_OUI_FROM_DATABASE=Digital Payment Technologies
+
+OUI:6CAC60*
+ ID_OUI_FROM_DATABASE=Venetex Corp
+
+OUI:6CAD3F*
+ ID_OUI_FROM_DATABASE=Hubbell Building Automation, Inc.
+
+OUI:6CADEF*
+ ID_OUI_FROM_DATABASE=KZ Broadband Technologies, Ltd.
+
+OUI:6CAE8B*
+ ID_OUI_FROM_DATABASE=IBM Corporation
+
+OUI:6CB311*
+ ID_OUI_FROM_DATABASE=Shenzhen Lianrui Electronics Co.,Ltd
+
+OUI:6CBEE9*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD
+
+OUI:6CC1D2*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:6CC26B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:6CD032*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:6CD146*
+ ID_OUI_FROM_DATABASE=Smartek d.o.o.
+
+OUI:6CD68A*
+ ID_OUI_FROM_DATABASE=LG Electronics Inc
+
+OUI:6CDC6A*
+ ID_OUI_FROM_DATABASE=Promethean Limited
+
+OUI:6CE0B0*
+ ID_OUI_FROM_DATABASE=SOUND4
+
+OUI:6CE4CE*
+ ID_OUI_FROM_DATABASE=Villiger Security Solutions AG
+
+OUI:6CE873*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:6CE907*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:6CE983*
+ ID_OUI_FROM_DATABASE=Gastron Co., LTD.
+
+OUI:6CF049*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:6CF373*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:6CF37F*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
+OUI:6CFDB9*
+ ID_OUI_FROM_DATABASE=Proware Technologies Co Ltd.
+
+OUI:6CFFBE*
+ ID_OUI_FROM_DATABASE=MPB Communications Inc.
+
+OUI:700258*
+ ID_OUI_FROM_DATABASE=01DB-METRAVIB
+
+OUI:700514*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:700BC0*
+ ID_OUI_FROM_DATABASE=Dewav Technology Company
+
+OUI:701124*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:701404*
+ ID_OUI_FROM_DATABASE=Limited Liability Company "Research Center "Bresler"
+
+OUI:701A04*
+ ID_OUI_FROM_DATABASE=Liteon Tech Corp.
+
+OUI:701AED*
+ ID_OUI_FROM_DATABASE=ADVAS CO., LTD.
+
+OUI:702393*
+ ID_OUI_FROM_DATABASE=fos4X GmbH
+
+OUI:702526*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:702559*
+ ID_OUI_FROM_DATABASE=CyberTAN Technology, Inc.
+
+OUI:702B1D*
+ ID_OUI_FROM_DATABASE=E-Domus International Limited
+
+OUI:702F4B*
+ ID_OUI_FROM_DATABASE=PolyVision Inc.
+
+OUI:702F97*
+ ID_OUI_FROM_DATABASE=Aava Mobile Oy
+
+OUI:703018*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:703187*
+ ID_OUI_FROM_DATABASE=ACX GmbH
+
+OUI:7032D5*
+ ID_OUI_FROM_DATABASE=Athena Wireless Communications Inc
+
+OUI:703811*
+ ID_OUI_FROM_DATABASE=Invensys Rail
+
+OUI:7038EE*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:703AD8*
+ ID_OUI_FROM_DATABASE=Shenzhen Afoundry Electronic Co., Ltd
+
+OUI:703C39*
+ ID_OUI_FROM_DATABASE=SEAWING Kft
+
+OUI:7041B7*
+ ID_OUI_FROM_DATABASE=Edwards Lifesciences LLC
+
+OUI:704642*
+ ID_OUI_FROM_DATABASE=CHYNG HONG ELECTRONIC CO., LTD.
+
+OUI:704AAE*
+ ID_OUI_FROM_DATABASE=Xstream Flow (Pty) Ltd
+
+OUI:704AE4*
+ ID_OUI_FROM_DATABASE=Rinstrum Pty Ltd
+
+OUI:7054D2*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:7054F5*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:705681*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:705812*
+ ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
+
+OUI:705AB6*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:705CAD*
+ ID_OUI_FROM_DATABASE=Konami Gaming Inc
+
+OUI:705EAA*
+ ID_OUI_FROM_DATABASE=Action Target, Inc.
+
+OUI:706417*
+ ID_OUI_FROM_DATABASE=ORBIS TECNOLOGIA ELECTRICA S.A.
+
+OUI:706582*
+ ID_OUI_FROM_DATABASE=Suzhou Hanming Technologies Co., Ltd.
+
+OUI:70704C*
+ ID_OUI_FROM_DATABASE=Purple Communications, Inc
+
+OUI:7071BC*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:70723C*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:7072CF*
+ ID_OUI_FROM_DATABASE=EdgeCore Networks
+
+OUI:7073CB*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:7076DD*
+ ID_OUI_FROM_DATABASE=Oxyguard International A/S
+
+OUI:7076F0*
+ ID_OUI_FROM_DATABASE=LevelOne Communications (India) Private Limited
+
+OUI:707BE8*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:707E43*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:707EDE*
+ ID_OUI_FROM_DATABASE=NASTEC LTD.
+
+OUI:708105*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:70828E*
+ ID_OUI_FROM_DATABASE=OleumTech Corporation
+
+OUI:708B78*
+ ID_OUI_FROM_DATABASE=citygrow technology co., ltd
+
+OUI:7093F8*
+ ID_OUI_FROM_DATABASE=Space Monkey, Inc.
+
+OUI:709756*
+ ID_OUI_FROM_DATABASE=Happyelectronics Co.,Ltd
+
+OUI:709A0B*
+ ID_OUI_FROM_DATABASE=Italian Institute of Technology
+
+OUI:709BA5*
+ ID_OUI_FROM_DATABASE=Shenzhen Y&D Electronics Co.,LTD.
+
+OUI:709E86*
+ ID_OUI_FROM_DATABASE=X6D Limited
+
+OUI:70A191*
+ ID_OUI_FROM_DATABASE=Trendsetter Medical, LLC
+
+OUI:70A41C*
+ ID_OUI_FROM_DATABASE=Advanced Wireless Dynamics S.L.
+
+OUI:70A66A*
+ ID_OUI_FROM_DATABASE=Prox Dynamics AS
+
+OUI:70AAB2*
+ ID_OUI_FROM_DATABASE=Research In Motion
+
+OUI:70B035*
+ ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd
+
+OUI:70B08C*
+ ID_OUI_FROM_DATABASE=Shenou Communication Equipment Co.,Ltd
+
+OUI:70B265*
+ ID_OUI_FROM_DATABASE=Hiltron s.r.l.
+
+OUI:70B599*
+ ID_OUI_FROM_DATABASE=Embedded Technologies s.r.o.
+
+OUI:70B921*
+ ID_OUI_FROM_DATABASE=FiberHome Telecommunication Technologies CO.,LTD
+
+OUI:70CA9B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:70CD60*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:70D4F2*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:70D57E*
+ ID_OUI_FROM_DATABASE=Scalar Corporation
+
+OUI:70D5E7*
+ ID_OUI_FROM_DATABASE=Wellcore Corporation
+
+OUI:70D6B6*
+ ID_OUI_FROM_DATABASE=Metrum Technologies
+
+OUI:70D880*
+ ID_OUI_FROM_DATABASE=Upos System sp. z o.o.
+
+OUI:70DDA1*
+ ID_OUI_FROM_DATABASE=Tellabs
+
+OUI:70DEE2*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:70E139*
+ ID_OUI_FROM_DATABASE=3view Ltd
+
+OUI:70E24C*
+ ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG
+
+OUI:70E843*
+ ID_OUI_FROM_DATABASE=Beijing C&W Optical Communication Technology Co.,Ltd.
+
+OUI:70EE50*
+ ID_OUI_FROM_DATABASE=Netatmo
+
+OUI:70F1A1*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:70F1E5*
+ ID_OUI_FROM_DATABASE=Xetawave LLC
+
+OUI:70F395*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:70F927*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:740ABC*
+ ID_OUI_FROM_DATABASE=JSJS Designs (Europe) Limited
+
+OUI:741489*
+ ID_OUI_FROM_DATABASE=SRT Wireless
+
+OUI:7415E2*
+ ID_OUI_FROM_DATABASE=Tri-Sen Systems Corporation
+
+OUI:741E93*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
+
+OUI:74273C*
+ ID_OUI_FROM_DATABASE=ChangYang Technology (Nanjing) Co., LTD
+
+OUI:7427EA*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co., Ltd.
+
+OUI:742B0F*
+ ID_OUI_FROM_DATABASE=Infinidat Ltd.
+
+OUI:742D0A*
+ ID_OUI_FROM_DATABASE=Norfolk Elektronik AG
+
+OUI:742F68*
+ ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc.
+
+OUI:743170*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:743256*
+ ID_OUI_FROM_DATABASE=NT-ware Systemprg GmbH
+
+OUI:74372F*
+ ID_OUI_FROM_DATABASE=Tongfang Shenzhen Cloudcomputing Technology Co.,Ltd
+
+OUI:743889*
+ ID_OUI_FROM_DATABASE=ANNAX Anzeigesysteme GmbH
+
+OUI:744401*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:74458A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:7446A0*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:744D79*
+ ID_OUI_FROM_DATABASE=Arrive Systems Inc.
+
+OUI:745327*
+ ID_OUI_FROM_DATABASE=COMMSEN CO., LIMITED
+
+OUI:745612*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:745798*
+ ID_OUI_FROM_DATABASE=TRUMPF Laser GmbH + Co. KG
+
+OUI:745E1C*
+ ID_OUI_FROM_DATABASE=PIONEER CORPORATION
+
+OUI:745F00*
+ ID_OUI_FROM_DATABASE=Samsung Semiconductor Inc.
+
+OUI:745FAE*
+ ID_OUI_FROM_DATABASE=TSL PPL
+
+OUI:7463DF*
+ ID_OUI_FROM_DATABASE=VTS GmbH
+
+OUI:7465D1*
+ ID_OUI_FROM_DATABASE=Atlinks
+
+OUI:746A89*
+ ID_OUI_FROM_DATABASE=Rezolt Corporation
+
+OUI:746B82*
+ ID_OUI_FROM_DATABASE=MOVEK
+
+OUI:7472F2*
+ ID_OUI_FROM_DATABASE=Chipsip Technology Co., Ltd.
+
+OUI:747818*
+ ID_OUI_FROM_DATABASE=ServiceAssure
+
+OUI:747B7A*
+ ID_OUI_FROM_DATABASE=ETH Inc.
+
+OUI:747DB6*
+ ID_OUI_FROM_DATABASE=Aliwei Communications, Inc
+
+OUI:747E1A*
+ ID_OUI_FROM_DATABASE=Red Embedded Design Limited
+
+OUI:747E2D*
+ ID_OUI_FROM_DATABASE=Beijing Thomson CITIC Digital Technology Co. LTD.
+
+OUI:74888B*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:748EF8*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:749050*
+ ID_OUI_FROM_DATABASE=Renesas Electronics Corporation
+
+OUI:74911A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:7493A4*
+ ID_OUI_FROM_DATABASE=Zebra Technologies Corp.
+
+OUI:74943D*
+ ID_OUI_FROM_DATABASE=Hemisphere GPS
+
+OUI:749975*
+ ID_OUI_FROM_DATABASE=IBM Corporation
+
+OUI:749DDC*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:74A4A7*
+ ID_OUI_FROM_DATABASE=QRS Music Technologies, Inc.
+
+OUI:74A722*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:74AE76*
+ ID_OUI_FROM_DATABASE=iNovo Broadband, Inc.
+
+OUI:74B00C*
+ ID_OUI_FROM_DATABASE=Network Video Technologies, Inc
+
+OUI:74B9EB*
+ ID_OUI_FROM_DATABASE=Fujian JinQianMao Electronic Technology Co.,Ltd
+
+OUI:74BE08*
+ ID_OUI_FROM_DATABASE=ATEK Products, LLC
+
+OUI:74BFA1*
+ ID_OUI_FROM_DATABASE=HYUNTECK
+
+OUI:74CD0C*
+ ID_OUI_FROM_DATABASE=Smith Myers Communications Ltd.
+
+OUI:74CE56*
+ ID_OUI_FROM_DATABASE=Packet Force Technology Limited Company
+
+OUI:74D0DC*
+ ID_OUI_FROM_DATABASE=ERICSSON AB
+
+OUI:74D675*
+ ID_OUI_FROM_DATABASE=WYMA Tecnologia
+
+OUI:74D850*
+ ID_OUI_FROM_DATABASE=Evrisko Systems
+
+OUI:74DE2B*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:74E06E*
+ ID_OUI_FROM_DATABASE=Ergophone GmbH
+
+OUI:74E1B6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:74E2F5*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:74E424*
+ ID_OUI_FROM_DATABASE=APISTE CORPORATION
+
+OUI:74E50B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:74E537*
+ ID_OUI_FROM_DATABASE=RADSPIN
+
+OUI:74E543*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:74E7C6*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:74EA3A*
+ ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd.
+
+OUI:74ECF1*
+ ID_OUI_FROM_DATABASE=Acumen
+
+OUI:74F06D*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc.
+
+OUI:74F07D*
+ ID_OUI_FROM_DATABASE=BnCOM Co.,Ltd
+
+OUI:74F612*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:74F726*
+ ID_OUI_FROM_DATABASE=Neuron Robotics
+
+OUI:74FDA0*
+ ID_OUI_FROM_DATABASE=Compupal (Group) Corporation
+
+OUI:74FE48*
+ ID_OUI_FROM_DATABASE=ADVANTECH CO., LTD.
+
+OUI:74FF7D*
+ ID_OUI_FROM_DATABASE=Wren Sound Systems, LLC
+
+OUI:78028F*
+ ID_OUI_FROM_DATABASE=Adaptive Spectrum and Signal Alignment (ASSIA), Inc.
+
+OUI:780738*
+ ID_OUI_FROM_DATABASE=Z.U.K. Elzab S.A.
+
+OUI:781185*
+ ID_OUI_FROM_DATABASE=NBS Payment Solutions Inc.
+
+OUI:7812B8*
+ ID_OUI_FROM_DATABASE=ORANTEK LIMITED
+
+OUI:781881*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc.
+
+OUI:78192E*
+ ID_OUI_FROM_DATABASE=NASCENT Technology
+
+OUI:7819F7*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:781C5A*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
+
+OUI:781DBA*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:781DFD*
+ ID_OUI_FROM_DATABASE=Jabil Inc
+
+OUI:78223D*
+ ID_OUI_FROM_DATABASE=Affirmed Networks
+
+OUI:782544*
+ ID_OUI_FROM_DATABASE=Omnima Limited
+
+OUI:7825AD*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD.
+
+OUI:782BCB*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:782EEF*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:7830E1*
+ ID_OUI_FROM_DATABASE=UltraClenz, LLC
+
+OUI:78324F*
+ ID_OUI_FROM_DATABASE=Millennium Group, Inc.
+
+OUI:783CE3*
+ ID_OUI_FROM_DATABASE=Kai-EE
+
+OUI:783F15*
+ ID_OUI_FROM_DATABASE=EasySYNC Ltd.
+
+OUI:784405*
+ ID_OUI_FROM_DATABASE=FUJITU(HONG KONG) ELECTRONIC Co.,LTD.
+
+OUI:784476*
+ ID_OUI_FROM_DATABASE=Zioncom technology co.,ltd
+
+OUI:7845C4*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:7846C4*
+ ID_OUI_FROM_DATABASE=DAEHAP HYPER-TECH
+
+OUI:78471D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:78510C*
+ ID_OUI_FROM_DATABASE=LiveU Ltd.
+
+OUI:785262*
+ ID_OUI_FROM_DATABASE=Shenzhen Hojy Software Co., Ltd.
+
+OUI:785517*
+ ID_OUI_FROM_DATABASE=SankyuElectronics
+
+OUI:785712*
+ ID_OUI_FROM_DATABASE=Mobile Integration Workgroup
+
+OUI:78593E*
+ ID_OUI_FROM_DATABASE=RAFI GmbH & Co.KG
+
+OUI:78595E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:785C72*
+ ID_OUI_FROM_DATABASE=Hioso Technology Co., Ltd.
+
+OUI:78617C*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD
+
+OUI:7866AE*
+ ID_OUI_FROM_DATABASE=ZTEC Instruments, Inc.
+
+OUI:786C1C*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:787F62*
+ ID_OUI_FROM_DATABASE=GiK mbH
+
+OUI:78818F*
+ ID_OUI_FROM_DATABASE=Server Racks Australia Pty Ltd
+
+OUI:78843C*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:7884EE*
+ ID_OUI_FROM_DATABASE=INDRA ESPACIO S.A.
+
+OUI:788973*
+ ID_OUI_FROM_DATABASE=CMC
+
+OUI:788C54*
+ ID_OUI_FROM_DATABASE=Enkom Technologies Ltd.
+
+OUI:78929C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:7898FD*
+ ID_OUI_FROM_DATABASE=Q9 Networks Inc.
+
+OUI:78995C*
+ ID_OUI_FROM_DATABASE=Nationz Technologies Inc
+
+OUI:78998F*
+ ID_OUI_FROM_DATABASE=MEDILINE ITALIA SRL
+
+OUI:789ED0*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:789F87*
+ ID_OUI_FROM_DATABASE=Siemens AG I IA PP PRM
+
+OUI:78A051*
+ ID_OUI_FROM_DATABASE=iiNet Labs Pty Ltd
+
+OUI:78A183*
+ ID_OUI_FROM_DATABASE=Advidia
+
+OUI:78A2A0*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:78A3E4*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:78A5DD*
+ ID_OUI_FROM_DATABASE=Shenzhen Smarteye Digital Electronics Co., Ltd
+
+OUI:78A683*
+ ID_OUI_FROM_DATABASE=Precidata
+
+OUI:78A6BD*
+ ID_OUI_FROM_DATABASE=DAEYEON Control&Instrument Co,.Ltd
+
+OUI:78A714*
+ ID_OUI_FROM_DATABASE=Amphenol
+
+OUI:78AB60*
+ ID_OUI_FROM_DATABASE=ABB Australia
+
+OUI:78ACC0*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:78B6C1*
+ ID_OUI_FROM_DATABASE=AOBO Telecom Co.,Ltd
+
+OUI:78B81A*
+ ID_OUI_FROM_DATABASE=INTER SALES A/S
+
+OUI:78BAD0*
+ ID_OUI_FROM_DATABASE=Shinybow Technology Co. Ltd.
+
+OUI:78BEB6*
+ ID_OUI_FROM_DATABASE=Enhanced Vision
+
+OUI:78BEBD*
+ ID_OUI_FROM_DATABASE=STULZ GmbH
+
+OUI:78C40E*
+ ID_OUI_FROM_DATABASE=H&D Wireless
+
+OUI:78C4AB*
+ ID_OUI_FROM_DATABASE=Shenzhen Runsil Technology Co.,Ltd
+
+OUI:78C5E5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:78C6BB*
+ ID_OUI_FROM_DATABASE=Innovasic, Inc.
+
+OUI:78CA04*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:78CA39*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:78CD8E*
+ ID_OUI_FROM_DATABASE=SMC Networks Inc
+
+OUI:78D004*
+ ID_OUI_FROM_DATABASE=Neousys Technology Inc.
+
+OUI:78D129*
+ ID_OUI_FROM_DATABASE=Vicos
+
+OUI:78D34F*
+ ID_OUI_FROM_DATABASE=Pace-O-Matic, Inc.
+
+OUI:78D6F0*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
+
+OUI:78DD08*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:78DDD6*
+ ID_OUI_FROM_DATABASE=c-scape
+
+OUI:78DEE4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:78E3B5*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:78E400*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:78E7D1*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:78EC22*
+ ID_OUI_FROM_DATABASE=Shanghai Qihui Telecom Technology Co., LTD
+
+OUI:78EF4C*
+ ID_OUI_FROM_DATABASE=Unetconvergence Co., Ltd.
+
+OUI:78F5FD*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:78F7D0*
+ ID_OUI_FROM_DATABASE=Silverbrook Research
+
+OUI:78FE3D*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:7C0187*
+ ID_OUI_FROM_DATABASE=Curtis Instruments, Inc.
+
+OUI:7C02BC*
+ ID_OUI_FROM_DATABASE=Hansung Electronics Co. LTD
+
+OUI:7C034C*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:7C03D8*
+ ID_OUI_FROM_DATABASE=SAGEMCOM SAS
+
+OUI:7C051E*
+ ID_OUI_FROM_DATABASE=RAFAEL LTD.
+
+OUI:7C08D9*
+ ID_OUI_FROM_DATABASE=Shanghai Engineering Research Center for Broadband Technologies and Applications
+
+OUI:7C092B*
+ ID_OUI_FROM_DATABASE=Bekey A/S
+
+OUI:7C0A50*
+ ID_OUI_FROM_DATABASE=J-MEX Inc.
+
+OUI:7C11BE*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:7C1476*
+ ID_OUI_FROM_DATABASE=Damall Technologies S.A.S. Di Ludovic Anselme Glaglanon & C.
+
+OUI:7C160D*
+ ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG
+
+OUI:7C1E52*
+ ID_OUI_FROM_DATABASE=Microsoft
+
+OUI:7C1EB3*
+ ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s.
+
+OUI:7C2064*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent IPD
+
+OUI:7C2CF3*
+ ID_OUI_FROM_DATABASE=Secure Electrans Ltd
+
+OUI:7C2E0D*
+ ID_OUI_FROM_DATABASE=Blackmagic Design
+
+OUI:7C2F80*
+ ID_OUI_FROM_DATABASE=Gigaset Communications GmbH
+
+OUI:7C336E*
+ ID_OUI_FROM_DATABASE=MEG Electronics Inc.
+
+OUI:7C386C*
+ ID_OUI_FROM_DATABASE=Real Time Logic
+
+OUI:7C3920*
+ ID_OUI_FROM_DATABASE=SSOMA SECURITY
+
+OUI:7C3BD5*
+ ID_OUI_FROM_DATABASE=Imago Group
+
+OUI:7C3E9D*
+ ID_OUI_FROM_DATABASE=PATECH
+
+OUI:7C438F*
+ ID_OUI_FROM_DATABASE=E-Band Communications Corp.
+
+OUI:7C4A82*
+ ID_OUI_FROM_DATABASE=Portsmith LLC
+
+OUI:7C4AA8*
+ ID_OUI_FROM_DATABASE=MindTree Wireless PVT Ltd
+
+OUI:7C4B78*
+ ID_OUI_FROM_DATABASE=Red Sun Synthesis Pte Ltd
+
+OUI:7C4C58*
+ ID_OUI_FROM_DATABASE=Scale Computing, Inc.
+
+OUI:7C4CA5*
+ ID_OUI_FROM_DATABASE=BSkyB Ltd
+
+OUI:7C4FB5*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:7C55E7*
+ ID_OUI_FROM_DATABASE=YSI, Inc.
+
+OUI:7C6193*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:7C6ADB*
+ ID_OUI_FROM_DATABASE=SafeTone Technology Co.,Ltd
+
+OUI:7C6B33*
+ ID_OUI_FROM_DATABASE=Tenyu Tech Co. Ltd.
+
+OUI:7C6B52*
+ ID_OUI_FROM_DATABASE=Tigaro Wireless
+
+OUI:7C6C39*
+ ID_OUI_FROM_DATABASE=PIXSYS SRL
+
+OUI:7C6C8F*
+ ID_OUI_FROM_DATABASE=AMS NEVE LTD
+
+OUI:7C6D62*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:7C6F06*
+ ID_OUI_FROM_DATABASE=Caterpillar Trimble Control Technologies
+
+OUI:7C7673*
+ ID_OUI_FROM_DATABASE=ENMAS GmbH
+
+OUI:7C7A91*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:7C7BE4*
+ ID_OUI_FROM_DATABASE=Z'SEDAI KENKYUSHO CORPORATION
+
+OUI:7C7D41*
+ ID_OUI_FROM_DATABASE=Jinmuyu Electronics Co., Ltd.
+
+OUI:7C822D*
+ ID_OUI_FROM_DATABASE=Nortec
+
+OUI:7C8EE4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:7C94B2*
+ ID_OUI_FROM_DATABASE=Philips Healthcare PCCI
+
+OUI:7C9A9B*
+ ID_OUI_FROM_DATABASE=VSE valencia smart energy
+
+OUI:7CA29B*
+ ID_OUI_FROM_DATABASE=D.SignT GmbH & Co. KG
+
+OUI:7CA61D*
+ ID_OUI_FROM_DATABASE=MHL, LLC
+
+OUI:7CACB2*
+ ID_OUI_FROM_DATABASE=Bosch Software Innovations GmbH
+
+OUI:7CB03E*
+ ID_OUI_FROM_DATABASE=OSRAM AG
+
+OUI:7CB21B*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:7CB232*
+ ID_OUI_FROM_DATABASE=TCL King High Frequency EI,Co.,LTD
+
+OUI:7CB542*
+ ID_OUI_FROM_DATABASE=ACES Technology
+
+OUI:7CBB6F*
+ ID_OUI_FROM_DATABASE=Cosco Electronics Co., Ltd.
+
+OUI:7CBFB1*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:7CC3A1*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:7CC537*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:7CC8AB*
+ ID_OUI_FROM_DATABASE=Acro Associates, Inc.
+
+OUI:7CC8D0*
+ ID_OUI_FROM_DATABASE=TIANJIN YAAN TECHNOLOGY CO., LTD.
+
+OUI:7CC8D7*
+ ID_OUI_FROM_DATABASE=Damalisk
+
+OUI:7CCB0D*
+ ID_OUI_FROM_DATABASE=Aaxeon Technologies Inc.
+
+OUI:7CCFCF*
+ ID_OUI_FROM_DATABASE=Shanghai SEARI Intelligent System Co., Ltd
+
+OUI:7CD1C3*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:7CD9FE*
+ ID_OUI_FROM_DATABASE=New Cosmos Electric Co., Ltd.
+
+OUI:7CDA84*
+ ID_OUI_FROM_DATABASE=Dongnian Networks Inc.
+
+OUI:7CDD11*
+ ID_OUI_FROM_DATABASE=Chongqing MAS SCI&TECH.Co.,Ltd
+
+OUI:7CDD20*
+ ID_OUI_FROM_DATABASE=IOXOS Technologies S.A.
+
+OUI:7CDD90*
+ ID_OUI_FROM_DATABASE=Shenzhen Ogemray Technology Co., Ltd.
+
+OUI:7CE044*
+ ID_OUI_FROM_DATABASE=NEON Inc
+
+OUI:7CE9D3*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:7CEBEA*
+ ID_OUI_FROM_DATABASE=ASCT
+
+OUI:7CED8D*
+ ID_OUI_FROM_DATABASE=MICROSOFT
+
+OUI:7CEF18*
+ ID_OUI_FROM_DATABASE=Creative Product Design Pty. Ltd.
+
+OUI:7CEF8A*
+ ID_OUI_FROM_DATABASE=Inhon International Ltd.
+
+OUI:7CF05F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:7CF098*
+ ID_OUI_FROM_DATABASE=Bee Beans Technologies, Inc.
+
+OUI:7CF0BA*
+ ID_OUI_FROM_DATABASE=Linkwell Telesystems Pvt Ltd
+
+OUI:7CF429*
+ ID_OUI_FROM_DATABASE=NUUO Inc.
+
+OUI:7CFE28*
+ ID_OUI_FROM_DATABASE=Salutron Inc.
+
+OUI:80000B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:800010*
+ ID_OUI_FROM_DATABASE=ATT BELL LABORATORIES
+
+OUI:8007A2*
+ ID_OUI_FROM_DATABASE=Esson Technology Inc.
+
+OUI:800A06*
+ ID_OUI_FROM_DATABASE=COMTEC co.,ltd
+
+OUI:801440*
+ ID_OUI_FROM_DATABASE=Sunlit System Technology Corp
+
+OUI:8016B7*
+ ID_OUI_FROM_DATABASE=Brunel University
+
+OUI:80177D*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:8018A7*
+ ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd
+
+OUI:801DAA*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:801F02*
+ ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd.
+
+OUI:8020AF*
+ ID_OUI_FROM_DATABASE=Trade FIDES, a.s.
+
+OUI:802275*
+ ID_OUI_FROM_DATABASE=Beijing Beny Wave Technology Co Ltd
+
+OUI:802AFA*
+ ID_OUI_FROM_DATABASE=Germaneers GmbH
+
+OUI:802DE1*
+ ID_OUI_FROM_DATABASE=Solarbridge Technologies
+
+OUI:802E14*
+ ID_OUI_FROM_DATABASE=azeti Networks AG
+
+OUI:802FDE*
+ ID_OUI_FROM_DATABASE=Zurich Instruments AG
+
+OUI:803457*
+ ID_OUI_FROM_DATABASE=OT Systems Limited
+
+OUI:8038FD*
+ ID_OUI_FROM_DATABASE=LeapFrog Enterprises, Inc.
+
+OUI:8039E5*
+ ID_OUI_FROM_DATABASE=PATLITE CORPORATION
+
+OUI:803B9A*
+ ID_OUI_FROM_DATABASE=ghe-ces electronic ag
+
+OUI:803F5D*
+ ID_OUI_FROM_DATABASE=Winstars Technology Ltd
+
+OUI:803FD6*
+ ID_OUI_FROM_DATABASE=bytes at work AG
+
+OUI:80427C*
+ ID_OUI_FROM_DATABASE=Adolf Tedsen GmbH & Co. KG
+
+OUI:804731*
+ ID_OUI_FROM_DATABASE=Packet Design, Inc.
+
+OUI:804971*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:804F58*
+ ID_OUI_FROM_DATABASE=ThinkEco, Inc.
+
+OUI:80501B*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:8058C5*
+ ID_OUI_FROM_DATABASE=NovaTec Kommunikationstechnik GmbH
+
+OUI:806007*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:806459*
+ ID_OUI_FROM_DATABASE=Nimbus Inc.
+
+OUI:8065E9*
+ ID_OUI_FROM_DATABASE=BenQ Corporation
+
+OUI:806629*
+ ID_OUI_FROM_DATABASE=Prescope Technologies CO.,LTD.
+
+OUI:806CBC*
+ ID_OUI_FROM_DATABASE=NET New Electronic Technology GmbH
+
+OUI:80711F*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:807693*
+ ID_OUI_FROM_DATABASE=Newag SA
+
+OUI:807A7F*
+ ID_OUI_FROM_DATABASE=ABB Genway Xiamen Electrical Equipment CO., LTD
+
+OUI:807B1E*
+ ID_OUI_FROM_DATABASE=Corsair Components
+
+OUI:807D1B*
+ ID_OUI_FROM_DATABASE=Neosystem Co. Ltd.
+
+OUI:807DE3*
+ ID_OUI_FROM_DATABASE=Chongqing Sichuan Instrument Microcircuit Co.LTD.
+
+OUI:8081A5*
+ ID_OUI_FROM_DATABASE=TONGQING COMMUNICATION EQUIPMENT (SHENZHEN) Co.,Ltd
+
+OUI:808287*
+ ID_OUI_FROM_DATABASE=ATCOM Technology Co.Ltd.
+
+OUI:808698*
+ ID_OUI_FROM_DATABASE=Netronics Technologies Inc.
+
+OUI:808B5C*
+ ID_OUI_FROM_DATABASE=Shenzhen Runhuicheng Technology Co., Ltd
+
+OUI:80912A*
+ ID_OUI_FROM_DATABASE=Lih Rong electronic Enterprise Co., Ltd.
+
+OUI:8091C0*
+ ID_OUI_FROM_DATABASE=AgileMesh, Inc.
+
+OUI:80929F*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:809393*
+ ID_OUI_FROM_DATABASE=Xapt GmbH
+
+OUI:80946C*
+ ID_OUI_FROM_DATABASE=TOKYO RADAR CORPORATION
+
+OUI:8096B1*
+ ID_OUI_FROM_DATABASE=Motorola Mobility
+
+OUI:80971B*
+ ID_OUI_FROM_DATABASE=Altenergy Power System,Inc.
+
+OUI:809B20*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:80A1D7*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd
+
+OUI:80AAA4*
+ ID_OUI_FROM_DATABASE=USAG
+
+OUI:80B289*
+ ID_OUI_FROM_DATABASE=Forworld Electronics Ltd.
+
+OUI:80B32A*
+ ID_OUI_FROM_DATABASE=Alstom Grid
+
+OUI:80B686*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:80B95C*
+ ID_OUI_FROM_DATABASE=ELFTECH Co., Ltd.
+
+OUI:80BAAC*
+ ID_OUI_FROM_DATABASE=TeleAdapt Ltd
+
+OUI:80C16E*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:80C63F*
+ ID_OUI_FROM_DATABASE=Remec Broadband Wireless , LLC
+
+OUI:80C6AB*
+ ID_OUI_FROM_DATABASE=Technicolor USA Inc.
+
+OUI:80C6CA*
+ ID_OUI_FROM_DATABASE=Endian s.r.l.
+
+OUI:80C862*
+ ID_OUI_FROM_DATABASE=Openpeak, Inc
+
+OUI:80CEB1*
+ ID_OUI_FROM_DATABASE=Theissen Training Systems GmbH
+
+OUI:80CF41*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
+OUI:80D019*
+ ID_OUI_FROM_DATABASE=Embed, Inc
+
+OUI:80D18B*
+ ID_OUI_FROM_DATABASE=Hangzhou I'converge Technology Co.,Ltd
+
+OUI:80D733*
+ ID_OUI_FROM_DATABASE=QSR Automations, Inc.
+
+OUI:80DB31*
+ ID_OUI_FROM_DATABASE=Power Quotient International Co., Ltd.
+
+OUI:80EE73*
+ ID_OUI_FROM_DATABASE=Shuttle Inc.
+
+OUI:80F593*
+ ID_OUI_FROM_DATABASE=IRCO Sistemas de Telecomunicación S.A.
+
+OUI:80F62E*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:80FA5B*
+ ID_OUI_FROM_DATABASE=CLEVO CO.
+
+OUI:80FB06*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:80FFA8*
+ ID_OUI_FROM_DATABASE=UNIDIS
+
+OUI:8400D2*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:840B2D*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD
+
+OUI:841715*
+ ID_OUI_FROM_DATABASE=GP Electronics (HK) Ltd.
+
+OUI:841888*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:841B5E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:842141*
+ ID_OUI_FROM_DATABASE=Shenzhen Ginwave Technologies Ltd.
+
+OUI:84248D*
+ ID_OUI_FROM_DATABASE=Motorola Solutions Inc
+
+OUI:8425DB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:8427CE*
+ ID_OUI_FROM_DATABASE=Corporation of the Presiding Bishop of The Church of Jesus Christ of Latter-day Saints
+
+OUI:842914*
+ ID_OUI_FROM_DATABASE=EMPORIA TELECOM Produktions- und VertriebsgesmbH & Co KG
+
+OUI:842999*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:842B2B*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:842B50*
+ ID_OUI_FROM_DATABASE=Huria Co.,Ltd.
+
+OUI:842BBC*
+ ID_OUI_FROM_DATABASE=Modelleisenbahn GmbH
+
+OUI:8430E5*
+ ID_OUI_FROM_DATABASE=SkyHawke Technologies, LLC
+
+OUI:843497*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:843611*
+ ID_OUI_FROM_DATABASE=hyungseul publishing networks
+
+OUI:843A4B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:843F4E*
+ ID_OUI_FROM_DATABASE=Tri-Tech Manufacturing, Inc.
+
+OUI:844823*
+ ID_OUI_FROM_DATABASE=WOXTER TECHNOLOGY Co. Ltd
+
+OUI:844915*
+ ID_OUI_FROM_DATABASE=vArmour Networks, Inc.
+
+OUI:844BF5*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:845181*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:845787*
+ ID_OUI_FROM_DATABASE=DVR C&C Co., Ltd.
+
+OUI:845DD7*
+ ID_OUI_FROM_DATABASE=Shenzhen Netcom Electronics Co.,Ltd
+
+OUI:8462A6*
+ ID_OUI_FROM_DATABASE=EuroCB (Phils), Inc.
+
+OUI:846AED*
+ ID_OUI_FROM_DATABASE=Wireless Tsukamoto.,co.LTD
+
+OUI:846EB1*
+ ID_OUI_FROM_DATABASE=Park Assist LLC
+
+OUI:84742A*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:8478AC*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:847A88*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:847E40*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:8482F4*
+ ID_OUI_FROM_DATABASE=Beijing Huasun Unicreate Technology Co., Ltd
+
+OUI:848506*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:848D84*
+ ID_OUI_FROM_DATABASE=Rajant Corporation
+
+OUI:848E96*
+ ID_OUI_FROM_DATABASE=Embertec Pty Ltd
+
+OUI:848F69*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:849000*
+ ID_OUI_FROM_DATABASE=Arnold & Richter Cine Technik
+
+OUI:8497B8*
+ ID_OUI_FROM_DATABASE=Memjet Inc.
+
+OUI:849CA6*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:849DC5*
+ ID_OUI_FROM_DATABASE=Centera Photonics Inc.
+
+OUI:84A6C8*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:84A8E4*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:84A991*
+ ID_OUI_FROM_DATABASE=Cyber Trans Japan Co.,Ltd.
+
+OUI:84ACA4*
+ ID_OUI_FROM_DATABASE=Beijing Novel Super Digital TV Technology Co., Ltd
+
+OUI:84AF1F*
+ ID_OUI_FROM_DATABASE=Beat System Service Co,. Ltd.
+
+OUI:84C2E4*
+ ID_OUI_FROM_DATABASE=Jiangsu Qinheng Co., Ltd.
+
+OUI:84C727*
+ ID_OUI_FROM_DATABASE=Gnodal Ltd
+
+OUI:84C7A9*
+ ID_OUI_FROM_DATABASE=C3PO S.A.
+
+OUI:84C8B1*
+ ID_OUI_FROM_DATABASE=Incognito Software Inc.
+
+OUI:84C9B2*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:84D32A*
+ ID_OUI_FROM_DATABASE=IEEE P1905.1
+
+OUI:84D9C8*
+ ID_OUI_FROM_DATABASE=Unipattern Co.,
+
+OUI:84DB2F*
+ ID_OUI_FROM_DATABASE=Sierra Wireless Inc
+
+OUI:84DE3D*
+ ID_OUI_FROM_DATABASE=Crystal Vision Ltd
+
+OUI:84DF0C*
+ ID_OUI_FROM_DATABASE=NET2GRID BV
+
+OUI:84E714*
+ ID_OUI_FROM_DATABASE=Liang Herng Enterprise,Co.Ltd.
+
+OUI:84EA99*
+ ID_OUI_FROM_DATABASE=Vieworks
+
+OUI:84ED33*
+ ID_OUI_FROM_DATABASE=BBMC Co.,Ltd
+
+OUI:84F64C*
+ ID_OUI_FROM_DATABASE=Cross Point BV
+
+OUI:84FCFE*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:881036*
+ ID_OUI_FROM_DATABASE=Panodic(ShenZhen) Electronics Limted
+
+OUI:881544*
+ ID_OUI_FROM_DATABASE=Meraki, Inc.
+
+OUI:8818AE*
+ ID_OUI_FROM_DATABASE=Tamron Co., Ltd
+
+OUI:882012*
+ ID_OUI_FROM_DATABASE=LMI Technologies
+
+OUI:8821E3*
+ ID_OUI_FROM_DATABASE=Nebusens, S.L.
+
+OUI:8823FE*
+ ID_OUI_FROM_DATABASE=TTTech Computertechnik AG
+
+OUI:88252C*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
+OUI:88308A*
+ ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd.
+
+OUI:88329B*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co.,LTD.
+
+OUI:8841C1*
+ ID_OUI_FROM_DATABASE=ORBISAT DA AMAZONIA IND E AEROL SA
+
+OUI:8843E1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:884B39*
+ ID_OUI_FROM_DATABASE=Siemens AG, Healthcare Sector
+
+OUI:8851FB*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:88532E*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:885395*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:8853D4*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:885C4F*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent
+
+OUI:88615A*
+ ID_OUI_FROM_DATABASE=Siano Mobile Silicon Ltd.
+
+OUI:886B76*
+ ID_OUI_FROM_DATABASE=CHINA HOPEFUL GROUP HOPEFUL ELECTRIC CO.,LTD
+
+OUI:887556*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:8886A0*
+ ID_OUI_FROM_DATABASE=Simton Technologies, Ltd.
+
+OUI:888717*
+ ID_OUI_FROM_DATABASE=CANON INC.
+
+OUI:8887DD*
+ ID_OUI_FROM_DATABASE=DarbeeVision Inc.
+
+OUI:888B5D*
+ ID_OUI_FROM_DATABASE=Storage Appliance Corporation
+
+OUI:888C19*
+ ID_OUI_FROM_DATABASE=Brady Corp Asia Pacific Ltd
+
+OUI:8891DD*
+ ID_OUI_FROM_DATABASE=Racktivity
+
+OUI:8894F9*
+ ID_OUI_FROM_DATABASE=Gemicom Technology, Inc.
+
+OUI:8895B9*
+ ID_OUI_FROM_DATABASE=Unified Packet Systems Crop
+
+OUI:889676*
+ ID_OUI_FROM_DATABASE=TTC MARCONI s.r.o.
+
+OUI:8897DF*
+ ID_OUI_FROM_DATABASE=Entrypass Corporation Sdn. Bhd.
+
+OUI:889821*
+ ID_OUI_FROM_DATABASE=TERAON
+
+OUI:889FFA*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:88A3CC*
+ ID_OUI_FROM_DATABASE=Amatis Controls
+
+OUI:88A5BD*
+ ID_OUI_FROM_DATABASE=QPCOM INC.
+
+OUI:88ACC1*
+ ID_OUI_FROM_DATABASE=Generiton Co., Ltd.
+
+OUI:88AE1D*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION(KUNSHAN)CO.,LTD
+
+OUI:88B168*
+ ID_OUI_FROM_DATABASE=Delta Control GmbH
+
+OUI:88B627*
+ ID_OUI_FROM_DATABASE=Gembird Europe BV
+
+OUI:88BA7F*
+ ID_OUI_FROM_DATABASE=Qfiednet Co., Ltd.
+
+OUI:88BFD5*
+ ID_OUI_FROM_DATABASE=Simple Audio Ltd
+
+OUI:88C36E*
+ ID_OUI_FROM_DATABASE=Beijing Ereneben lnformation Technology Limited
+
+OUI:88C663*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:88CB87*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:88D7BC*
+ ID_OUI_FROM_DATABASE=DEP Company
+
+OUI:88DC96*
+ ID_OUI_FROM_DATABASE=SENAO Networks, Inc.
+
+OUI:88DD79*
+ ID_OUI_FROM_DATABASE=Voltaire
+
+OUI:88E0A0*
+ ID_OUI_FROM_DATABASE=Shenzhen VisionSTOR Technologies Co., Ltd
+
+OUI:88E0F3*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:88E712*
+ ID_OUI_FROM_DATABASE=Whirlpool Corporation
+
+OUI:88E7A6*
+ ID_OUI_FROM_DATABASE=iKnowledge Integration Corp.
+
+OUI:88E917*
+ ID_OUI_FROM_DATABASE=Tamaggo
+
+OUI:88ED1C*
+ ID_OUI_FROM_DATABASE=Cudo Communication Co., Ltd.
+
+OUI:88F077*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:88F488*
+ ID_OUI_FROM_DATABASE=cellon communications technology(shenzhen)Co.,Ltd.
+
+OUI:88F490*
+ ID_OUI_FROM_DATABASE=Jetmobile Pte Ltd
+
+OUI:88FD15*
+ ID_OUI_FROM_DATABASE=LINEEYE CO., LTD
+
+OUI:8C04FF*
+ ID_OUI_FROM_DATABASE=Technicolor USA Inc.
+
+OUI:8C078C*
+ ID_OUI_FROM_DATABASE=FLOW DATA INC
+
+OUI:8C0C90*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:8C0CA3*
+ ID_OUI_FROM_DATABASE=Amper
+
+OUI:8C0EE3*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD.
+
+OUI:8C11CB*
+ ID_OUI_FROM_DATABASE=ABUS Security-Center GmbH & Co. KG
+
+OUI:8C1F94*
+ ID_OUI_FROM_DATABASE=RF Surgical System Inc.
+
+OUI:8C210A*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:8C271D*
+ ID_OUI_FROM_DATABASE=QuantHouse
+
+OUI:8C278A*
+ ID_OUI_FROM_DATABASE=Vocollect Inc
+
+OUI:8C2DAA*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:8C3330*
+ ID_OUI_FROM_DATABASE=EmFirst Co., Ltd.
+
+OUI:8C3C4A*
+ ID_OUI_FROM_DATABASE=NAKAYO TELECOMMUNICATIONS,INC.
+
+OUI:8C4435*
+ ID_OUI_FROM_DATABASE=Shanghai BroadMobi Communication Technology Co., Ltd.
+
+OUI:8C4AEE*
+ ID_OUI_FROM_DATABASE=GIGA TMS INC
+
+OUI:8C4CDC*
+ ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
+
+OUI:8C4DEA*
+ ID_OUI_FROM_DATABASE=Cerio Corporation
+
+OUI:8C5105*
+ ID_OUI_FROM_DATABASE=Shenzhen ireadygo Information Technology CO.,LTD.
+
+OUI:8C53F7*
+ ID_OUI_FROM_DATABASE=A&D ENGINEERING CO., LTD.
+
+OUI:8C541D*
+ ID_OUI_FROM_DATABASE=LGE
+
+OUI:8C56C5*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:8C57FD*
+ ID_OUI_FROM_DATABASE=LVX Western
+
+OUI:8C5877*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:8C598B*
+ ID_OUI_FROM_DATABASE=C Technologies AB
+
+OUI:8C5CA1*
+ ID_OUI_FROM_DATABASE=d-broad,INC
+
+OUI:8C5FDF*
+ ID_OUI_FROM_DATABASE=Beijing Railway Signal Factory
+
+OUI:8C604F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:8C640B*
+ ID_OUI_FROM_DATABASE=Beyond Devices d.o.o.
+
+OUI:8C6422*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:8C6878*
+ ID_OUI_FROM_DATABASE=Nortek-AS
+
+OUI:8C6AE4*
+ ID_OUI_FROM_DATABASE=Viogem Limited
+
+OUI:8C705A*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:8C71F8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:8C736E*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
+OUI:8C76C1*
+ ID_OUI_FROM_DATABASE=Goden Tech Limited
+
+OUI:8C7712*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:8C7B9D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:8C7CB5*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:8C7CFF*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:8C7EB3*
+ ID_OUI_FROM_DATABASE=Lytro, Inc.
+
+OUI:8C82A8*
+ ID_OUI_FROM_DATABASE=Insigma Technology Co.,Ltd
+
+OUI:8C89A5*
+ ID_OUI_FROM_DATABASE=Micro-Star INT'L CO., LTD
+
+OUI:8C8A6E*
+ ID_OUI_FROM_DATABASE=ESTUN AUTOMATION TECHNOLOY CO., LTD
+
+OUI:8C8E76*
+ ID_OUI_FROM_DATABASE=taskit GmbH
+
+OUI:8C90D3*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent
+
+OUI:8C9236*
+ ID_OUI_FROM_DATABASE=Aus.Linx Technology Co., Ltd.
+
+OUI:8C94CF*
+ ID_OUI_FROM_DATABASE=Encell Technology, Inc.
+
+OUI:8CA048*
+ ID_OUI_FROM_DATABASE=Beijing NeTopChip Technology Co.,LTD
+
+OUI:8CA982*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:8CAE4C*
+ ID_OUI_FROM_DATABASE=Plugable Technologies
+
+OUI:8CB64F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:8CB82C*
+ ID_OUI_FROM_DATABASE=IPitomy Communications
+
+OUI:8CB864*
+ ID_OUI_FROM_DATABASE=AcSiP Technology Corp.
+
+OUI:8CC121*
+ ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
+
+OUI:8CC5E1*
+ ID_OUI_FROM_DATABASE=ShenZhen Konka Telecommunication Technology Co.,Ltd
+
+OUI:8CC7AA*
+ ID_OUI_FROM_DATABASE=Radinet Communications Inc.
+
+OUI:8CC8CD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
+
+OUI:8CCDE8*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:8CCF5C*
+ ID_OUI_FROM_DATABASE=BEFEGA GmbH
+
+OUI:8CD17B*
+ ID_OUI_FROM_DATABASE=CG Mobile
+
+OUI:8CD3A2*
+ ID_OUI_FROM_DATABASE=VisSim AS
+
+OUI:8CD628*
+ ID_OUI_FROM_DATABASE=Ikor Metering
+
+OUI:8CDB25*
+ ID_OUI_FROM_DATABASE=ESG Solutions
+
+OUI:8CDD8D*
+ ID_OUI_FROM_DATABASE=Wifly-City System Inc.
+
+OUI:8CDE52*
+ ID_OUI_FROM_DATABASE=ISSC Technologies Corp.
+
+OUI:8CE081*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:8CE7B3*
+ ID_OUI_FROM_DATABASE=Sonardyne International Ltd
+
+OUI:8CEEC6*
+ ID_OUI_FROM_DATABASE=Precepscion Pty. Ltd.
+
+OUI:8CF9C9*
+ ID_OUI_FROM_DATABASE=MESADA Technology Co.,Ltd.
+
+OUI:8CFABA*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:8CFDF0*
+ ID_OUI_FROM_DATABASE=QUALCOMM Incorporated
+
+OUI:90004E*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:90013B*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:9002A9*
+ ID_OUI_FROM_DATABASE=ZHEJIANG DAHUA TECHNOLOGY CO.,LTD
+
+OUI:9003B7*
+ ID_OUI_FROM_DATABASE=PARROT
+
+OUI:900917*
+ ID_OUI_FROM_DATABASE=Far-sighted mobile
+
+OUI:900A3A*
+ ID_OUI_FROM_DATABASE=PSG Plastic Service GmbH
+
+OUI:900D66*
+ ID_OUI_FROM_DATABASE=Digimore Electronics Co., Ltd
+
+OUI:900DCB*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:90185E*
+ ID_OUI_FROM_DATABASE=Apex Tool Group GmbH & Co OHG
+
+OUI:90187C*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
+
+OUI:9018AE*
+ ID_OUI_FROM_DATABASE=Shanghai Meridian Technologies, Co. Ltd.
+
+OUI:901900*
+ ID_OUI_FROM_DATABASE=SCS SA
+
+OUI:901B0E*
+ ID_OUI_FROM_DATABASE=Fujitsu Technology Solutions GmbH
+
+OUI:901EDD*
+ ID_OUI_FROM_DATABASE=GREAT COMPUTER CORPORATION
+
+OUI:902155*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:9027E4*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:902B34*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:902E87*
+ ID_OUI_FROM_DATABASE=LabJack
+
+OUI:90342B*
+ ID_OUI_FROM_DATABASE=Gatekeeper Systems, Inc.
+
+OUI:9034FC*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:9038DF*
+ ID_OUI_FROM_DATABASE=Changzhou Tiannengbo System Co. Ltd.
+
+OUI:903AA0*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:903CAE*
+ ID_OUI_FROM_DATABASE=Yunnan KSEC Digital Technology Co.,Ltd.
+
+OUI:903D5A*
+ ID_OUI_FROM_DATABASE=Shenzhen Wision Technology Holding Limited
+
+OUI:903D6B*
+ ID_OUI_FROM_DATABASE=Zicon Technology Corp.
+
+OUI:904716*
+ ID_OUI_FROM_DATABASE=RORZE CORPORATION
+
+OUI:904CE5*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:90507B*
+ ID_OUI_FROM_DATABASE=Advanced PANMOBIL Systems GmbH & Co. KG
+
+OUI:90513F*
+ ID_OUI_FROM_DATABASE=Elettronica Santerno
+
+OUI:905446*
+ ID_OUI_FROM_DATABASE=TES ELECTRONIC SOLUTIONS
+
+OUI:9055AE*
+ ID_OUI_FROM_DATABASE=Ericsson, EAB/RWI/K
+
+OUI:905682*
+ ID_OUI_FROM_DATABASE=Lenbrook Industries Limited
+
+OUI:9059AF*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:905F2E*
+ ID_OUI_FROM_DATABASE=TCT Mobile Limited
+
+OUI:905F8D*
+ ID_OUI_FROM_DATABASE=modas GmbH
+
+OUI:90610C*
+ ID_OUI_FROM_DATABASE=Fida International (S) Pte Ltd
+
+OUI:9067B5*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:9067F3*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent
+
+OUI:906DC8*
+ ID_OUI_FROM_DATABASE=DLG Automação Industrial Ltda
+
+OUI:906EBB*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:907025*
+ ID_OUI_FROM_DATABASE=Garea Microsys Co.,Ltd.
+
+OUI:907F61*
+ ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd.
+
+OUI:908260*
+ ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group
+
+OUI:90840D*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:9088A2*
+ ID_OUI_FROM_DATABASE=IONICS TECHNOLOGY ME LTDA
+
+OUI:908D1D*
+ ID_OUI_FROM_DATABASE=GH Technologies
+
+OUI:908FCF*
+ ID_OUI_FROM_DATABASE=UNO System Co., Ltd
+
+OUI:90903C*
+ ID_OUI_FROM_DATABASE=TRISON TECHNOLOGY CORPORATION
+
+OUI:909060*
+ ID_OUI_FROM_DATABASE=RSI VIDEO TECHNOLOGIES
+
+OUI:9092B4*
+ ID_OUI_FROM_DATABASE=Diehl BGT Defence GmbH & Co. KG
+
+OUI:9094E4*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:909DE0*
+ ID_OUI_FROM_DATABASE=Newland Design + Assoc. Inc.
+
+OUI:90A2DA*
+ ID_OUI_FROM_DATABASE=GHEO SA
+
+OUI:90A4DE*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
+
+OUI:90A783*
+ ID_OUI_FROM_DATABASE=JSW PACIFIC CORPORATION
+
+OUI:90A7C1*
+ ID_OUI_FROM_DATABASE=Pakedge Device and Software Inc.
+
+OUI:90AC3F*
+ ID_OUI_FROM_DATABASE=BrightSign LLC
+
+OUI:90B11C*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:90B134*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:90B8D0*
+ ID_OUI_FROM_DATABASE=Joyent, Inc.
+
+OUI:90B97D*
+ ID_OUI_FROM_DATABASE=Johnson Outdoors Marine Electronics d/b/a Minnkota
+
+OUI:90C115*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:90CC24*
+ ID_OUI_FROM_DATABASE=Synaptics, Inc
+
+OUI:90CF15*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:90CF6F*
+ ID_OUI_FROM_DATABASE=Dlogixs Co Ltd
+
+OUI:90CF7D*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Electric Co.,Ltd.
+
+OUI:90D11B*
+ ID_OUI_FROM_DATABASE=Palomar Medical Technologies
+
+OUI:90D74F*
+ ID_OUI_FROM_DATABASE=Bookeen
+
+OUI:90D7EB*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:90D852*
+ ID_OUI_FROM_DATABASE=Comtec Co., Ltd.
+
+OUI:90D92C*
+ ID_OUI_FROM_DATABASE=HUG-WITSCHI AG
+
+OUI:90E0F0*
+ ID_OUI_FROM_DATABASE=IEEE P1722
+
+OUI:90E2BA*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:90E6BA*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:90EA60*
+ ID_OUI_FROM_DATABASE=SPI Lasers Ltd
+
+OUI:90F278*
+ ID_OUI_FROM_DATABASE=Radius Gateway
+
+OUI:90F4C1*
+ ID_OUI_FROM_DATABASE=Rand McNally
+
+OUI:90F652*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:90F72F*
+ ID_OUI_FROM_DATABASE=Phillips Machine & Welding Co., Inc.
+
+OUI:90FB5B*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:90FBA6*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd
+
+OUI:90FF79*
+ ID_OUI_FROM_DATABASE=Metro Ethernet Forum
+
+OUI:940070*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:940149*
+ ID_OUI_FROM_DATABASE=AutoHotBox
+
+OUI:940B2D*
+ ID_OUI_FROM_DATABASE=NetView Technologies(Shenzhen) Co., Ltd
+
+OUI:940C6D*
+ ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd.
+
+OUI:9411DA*
+ ID_OUI_FROM_DATABASE=ITF Fröschl GmbH
+
+OUI:941673*
+ ID_OUI_FROM_DATABASE=Point Core SARL
+
+OUI:941D1C*
+ ID_OUI_FROM_DATABASE=TLab West Systems AB
+
+OUI:942053*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:942197*
+ ID_OUI_FROM_DATABASE=Stalmart Technology Limited
+
+OUI:94236E*
+ ID_OUI_FROM_DATABASE=Shenzhen Junlan Electronic Ltd
+
+OUI:942E17*
+ ID_OUI_FROM_DATABASE=Schneider Electric Canada Inc
+
+OUI:942E63*
+ ID_OUI_FROM_DATABASE=Finsécur
+
+OUI:94319B*
+ ID_OUI_FROM_DATABASE=Alphatronics BV
+
+OUI:9433DD*
+ ID_OUI_FROM_DATABASE=Taco Electronic Solutions, Inc.
+
+OUI:9439E5*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:943AF0*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:944444*
+ ID_OUI_FROM_DATABASE=LG Innotek
+
+OUI:944452*
+ ID_OUI_FROM_DATABASE=Belkin International, Inc.
+
+OUI:944696*
+ ID_OUI_FROM_DATABASE=BaudTec Corporation
+
+OUI:944A09*
+ ID_OUI_FROM_DATABASE=BitWise Controls
+
+OUI:945103*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:94592D*
+ ID_OUI_FROM_DATABASE=EKE Building Technology Systems Ltd
+
+OUI:945B7E*
+ ID_OUI_FROM_DATABASE=TRILOBIT LTDA.
+
+OUI:946124*
+ ID_OUI_FROM_DATABASE=Pason Systems
+
+OUI:9463D1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:9471AC*
+ ID_OUI_FROM_DATABASE=TCT Mobile Limited
+
+OUI:94756E*
+ ID_OUI_FROM_DATABASE=QinetiQ North America
+
+OUI:9481A4*
+ ID_OUI_FROM_DATABASE=Azuray Technologies
+
+OUI:94857A*
+ ID_OUI_FROM_DATABASE=Evantage Industries Corp
+
+OUI:948854*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:948B03*
+ ID_OUI_FROM_DATABASE=EAGET Innovation and Technology Co., Ltd.
+
+OUI:948D50*
+ ID_OUI_FROM_DATABASE=Beamex Oy Ab
+
+OUI:948FEE*
+ ID_OUI_FROM_DATABASE=Hughes Telematics, Inc.
+
+OUI:949426*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:949BFD*
+ ID_OUI_FROM_DATABASE=Trans New Technology, Inc.
+
+OUI:949C55*
+ ID_OUI_FROM_DATABASE=Alta Data Technologies
+
+OUI:94A7BC*
+ ID_OUI_FROM_DATABASE=BodyMedia, Inc.
+
+OUI:94AAB8*
+ ID_OUI_FROM_DATABASE=Joview(Beijing) Technology Co. Ltd.
+
+OUI:94AE61*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent
+
+OUI:94BA31*
+ ID_OUI_FROM_DATABASE=Visiontec da Amazônia Ltda.
+
+OUI:94C4E9*
+ ID_OUI_FROM_DATABASE=PowerLayer Microsystems HongKong Limited
+
+OUI:94C6EB*
+ ID_OUI_FROM_DATABASE=NOVA electronics, Inc.
+
+OUI:94C7AF*
+ ID_OUI_FROM_DATABASE=Raylios Technology
+
+OUI:94C962*
+ ID_OUI_FROM_DATABASE=Teseq AG
+
+OUI:94CA0F*
+ ID_OUI_FROM_DATABASE=Honeywell Analytics
+
+OUI:94CCB9*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:94CDAC*
+ ID_OUI_FROM_DATABASE=Creowave Oy
+
+OUI:94D019*
+ ID_OUI_FROM_DATABASE=Cydle Corp.
+
+OUI:94D723*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co., Ltd
+
+OUI:94D93C*
+ ID_OUI_FROM_DATABASE=ENELPS
+
+OUI:94DB49*
+ ID_OUI_FROM_DATABASE=SITCORP
+
+OUI:94DBC9*
+ ID_OUI_FROM_DATABASE=Azurewave
+
+OUI:94DD3F*
+ ID_OUI_FROM_DATABASE=A+V Link Technologies, Corp.
+
+OUI:94DE0E*
+ ID_OUI_FROM_DATABASE=SmartOptics AS
+
+OUI:94DE80*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:94DF58*
+ ID_OUI_FROM_DATABASE=IJ Electron CO.,Ltd.
+
+OUI:94E0D0*
+ ID_OUI_FROM_DATABASE=HealthStream Taiwan Inc.
+
+OUI:94E226*
+ ID_OUI_FROM_DATABASE=D. ORtiz Consulting, LLC
+
+OUI:94E711*
+ ID_OUI_FROM_DATABASE=Xirka Dama Persada PT
+
+OUI:94E848*
+ ID_OUI_FROM_DATABASE=FYLDE MICRO LTD
+
+OUI:94F692*
+ ID_OUI_FROM_DATABASE=Geminico co.,Ltd.
+
+OUI:94F720*
+ ID_OUI_FROM_DATABASE=Tianjin Deviser Electronics Instrument Co., Ltd
+
+OUI:94FAE8*
+ ID_OUI_FROM_DATABASE=Shenzhen Eycom Technology Co., Ltd
+
+OUI:94FD1D*
+ ID_OUI_FROM_DATABASE=WhereWhen Corp
+
+OUI:94FD2E*
+ ID_OUI_FROM_DATABASE=Shanghai Uniscope Technologies Co.,Ltd
+
+OUI:94FEF4*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:980284*
+ ID_OUI_FROM_DATABASE=Theobroma Systems GmbH
+
+OUI:9803A0*
+ ID_OUI_FROM_DATABASE=ABB n.v. Power Quality Products
+
+OUI:9803D8*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:980C82*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
+
+OUI:98208E*
+ ID_OUI_FROM_DATABASE=Definium Technologies
+
+OUI:98262A*
+ ID_OUI_FROM_DATABASE=Applied Research Associates, Inc
+
+OUI:98291D*
+ ID_OUI_FROM_DATABASE=Jaguar de Mexico, SA de CV
+
+OUI:98293F*
+ ID_OUI_FROM_DATABASE=Fujian Start Computer Equipment Co.,Ltd
+
+OUI:982CBE*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:982D56*
+ ID_OUI_FROM_DATABASE=Resolution Audio
+
+OUI:983000*
+ ID_OUI_FROM_DATABASE=Beijing KEMACOM Technologies Co., Ltd.
+
+OUI:983571*
+ ID_OUI_FROM_DATABASE=Sub10 Systems Ltd
+
+OUI:9835B8*
+ ID_OUI_FROM_DATABASE=Assembled Products Corporation
+
+OUI:983F9F*
+ ID_OUI_FROM_DATABASE=China SSJ (Suzhou) Network Technology Inc.
+
+OUI:984246*
+ ID_OUI_FROM_DATABASE=SOL INDUSTRY PTE., LTD
+
+OUI:98473C*
+ ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD
+
+OUI:984A47*
+ ID_OUI_FROM_DATABASE=CHG Hospital Beds
+
+OUI:984B4A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility Inc.
+
+OUI:984BE1*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:984C04*
+ ID_OUI_FROM_DATABASE=Zhangzhou Keneng Electrical Equipment Co Ltd
+
+OUI:984CD3*
+ ID_OUI_FROM_DATABASE=Mantis Deposition
+
+OUI:984E97*
+ ID_OUI_FROM_DATABASE=Starlight Marketing (H. K.) Ltd.
+
+OUI:9852B1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:9857D3*
+ ID_OUI_FROM_DATABASE=HON HAI-CCPBG  PRECISION IND.CO.,LTD.
+
+OUI:98588A*
+ ID_OUI_FROM_DATABASE=SYSGRATION Ltd.
+
+OUI:985945*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:985E1B*
+ ID_OUI_FROM_DATABASE=ConversDigital Co., Ltd.
+
+OUI:986022*
+ ID_OUI_FROM_DATABASE=EMW Co., Ltd.
+
+OUI:9866EA*
+ ID_OUI_FROM_DATABASE=Industrial Control Communications, Inc.
+
+OUI:986DC8*
+ ID_OUI_FROM_DATABASE=TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION
+
+OUI:9873C4*
+ ID_OUI_FROM_DATABASE=Sage Electronic Engineering LLC
+
+OUI:988217*
+ ID_OUI_FROM_DATABASE=Disruptive Ltd
+
+OUI:9886B1*
+ ID_OUI_FROM_DATABASE=Flyaudio corporation (China)
+
+OUI:9889ED*
+ ID_OUI_FROM_DATABASE=Anadem Information Inc.
+
+OUI:988B5D*
+ ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION
+
+OUI:988BAD*
+ ID_OUI_FROM_DATABASE=Corintech Ltd.
+
+OUI:988E34*
+ ID_OUI_FROM_DATABASE=ZHEJIANG BOXSAM ELECTRONIC CO.,LTD
+
+OUI:988EDD*
+ ID_OUI_FROM_DATABASE=TE Connectivity Limerick
+
+OUI:989080*
+ ID_OUI_FROM_DATABASE=Linkpower Network System Inc Ltd.
+
+OUI:989449*
+ ID_OUI_FROM_DATABASE=Skyworth Wireless Technology Ltd.
+
+OUI:98A7B0*
+ ID_OUI_FROM_DATABASE=MCST ZAO
+
+OUI:98AAD7*
+ ID_OUI_FROM_DATABASE=BLUE WAVE NETWORKING CO LTD
+
+OUI:98B8E3*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:98BC57*
+ ID_OUI_FROM_DATABASE=SVA TECHNOLOGIES CO.LTD
+
+OUI:98BC99*
+ ID_OUI_FROM_DATABASE=Edeltech Co.,Ltd.
+
+OUI:98C845*
+ ID_OUI_FROM_DATABASE=PacketAccess
+
+OUI:98D686*
+ ID_OUI_FROM_DATABASE=Chyi Lee industry Co., ltd.
+
+OUI:98D6BB*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:98D6F7*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:98D88C*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:98DCD9*
+ ID_OUI_FROM_DATABASE=UNITEC Co., Ltd.
+
+OUI:98E165*
+ ID_OUI_FROM_DATABASE=Accutome
+
+OUI:98E79A*
+ ID_OUI_FROM_DATABASE=Foxconn(NanJing) Communication Co.,Ltd.
+
+OUI:98EC65*
+ ID_OUI_FROM_DATABASE=Cosesy ApS
+
+OUI:98F537*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:98F8DB*
+ ID_OUI_FROM_DATABASE=Marini Impianti Industriali s.r.l.
+
+OUI:98FC11*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:98FE03*
+ ID_OUI_FROM_DATABASE=Ericsson - North America
+
+OUI:98FE94*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:9C0111*
+ ID_OUI_FROM_DATABASE=Shenzhen Newabel Electronic Co., Ltd.
+
+OUI:9C0298*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:9C0473*
+ ID_OUI_FROM_DATABASE=Tecmobile (International) Ltd.
+
+OUI:9C04EB*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:9C066E*
+ ID_OUI_FROM_DATABASE=Hytera Communications Corporation Limited
+
+OUI:9C0DAC*
+ ID_OUI_FROM_DATABASE=Tymphany HK Limited
+
+OUI:9C1874*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:9C1C12*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
+OUI:9C1FDD*
+ ID_OUI_FROM_DATABASE=Accupix Inc.
+
+OUI:9C207B*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:9C220E*
+ ID_OUI_FROM_DATABASE=TASCAN Service GmbH
+
+OUI:9C28BF*
+ ID_OUI_FROM_DATABASE=Continental Automotive Czech Republic s.r.o.
+
+OUI:9C2A70*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:9C3178*
+ ID_OUI_FROM_DATABASE=Foshan Huadian Intelligent Communications Teachnologies Co.,Ltd
+
+OUI:9C31B6*
+ ID_OUI_FROM_DATABASE=Kulite Semiconductor Products Inc
+
+OUI:9C417C*
+ ID_OUI_FROM_DATABASE=Hame  Technology Co.,  Limited
+
+OUI:9C4563*
+ ID_OUI_FROM_DATABASE=DIMEP Sistemas
+
+OUI:9C4A7B*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:9C4CAE*
+ ID_OUI_FROM_DATABASE=Mesa Labs
+
+OUI:9C4E20*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:9C4E36*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:9C4E8E*
+ ID_OUI_FROM_DATABASE=ALT Systems Ltd
+
+OUI:9C53CD*
+ ID_OUI_FROM_DATABASE=ENGICAM s.r.l.
+
+OUI:9C541C*
+ ID_OUI_FROM_DATABASE=Shenzhen My-power Technology Co.,Ltd
+
+OUI:9C54CA*
+ ID_OUI_FROM_DATABASE=Zhengzhou VCOM Science and Technology Co.,Ltd
+
+OUI:9C55B4*
+ ID_OUI_FROM_DATABASE=I.S.E. S.r.l.
+
+OUI:9C5711*
+ ID_OUI_FROM_DATABASE=Feitian Xunda(Beijing) Aeronautical Information Technology Co., Ltd.
+
+OUI:9C5B96*
+ ID_OUI_FROM_DATABASE=NMR Corporation
+
+OUI:9C5C8D*
+ ID_OUI_FROM_DATABASE=FIREMAX INDÚSTRIA E COMÉRCIO DE PRODUTOS ELETRÔNICOS  LTDA
+
+OUI:9C5D12*
+ ID_OUI_FROM_DATABASE=Aerohive Networks Inc
+
+OUI:9C5D95*
+ ID_OUI_FROM_DATABASE=VTC Electronics Corp.
+
+OUI:9C5E73*
+ ID_OUI_FROM_DATABASE=Calibre UK Ltd
+
+OUI:9C611D*
+ ID_OUI_FROM_DATABASE=Omni-ID USA, Inc.
+
+OUI:9C645E*
+ ID_OUI_FROM_DATABASE=Harman Consumer Group
+
+OUI:9C6650*
+ ID_OUI_FROM_DATABASE=Glodio Technolies Co.,Ltd Tianjin Branch
+
+OUI:9C6ABE*
+ ID_OUI_FROM_DATABASE=QEES ApS.
+
+OUI:9C7514*
+ ID_OUI_FROM_DATABASE=Wildix srl
+
+OUI:9C77AA*
+ ID_OUI_FROM_DATABASE=NADASNV
+
+OUI:9C7BD2*
+ ID_OUI_FROM_DATABASE=NEOLAB Convergence
+
+OUI:9C807D*
+ ID_OUI_FROM_DATABASE=SYSCABLE Korea Inc.
+
+OUI:9C8BF1*
+ ID_OUI_FROM_DATABASE=The Warehouse Limited
+
+OUI:9C8D1A*
+ ID_OUI_FROM_DATABASE=INTEG process group inc
+
+OUI:9C8E99*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:9C8EDC*
+ ID_OUI_FROM_DATABASE=Teracom Limited
+
+OUI:9C934E*
+ ID_OUI_FROM_DATABASE=Xerox Corporation
+
+OUI:9C95F8*
+ ID_OUI_FROM_DATABASE=SmartDoor Systems, LLC
+
+OUI:9C9811*
+ ID_OUI_FROM_DATABASE=Guangzhou Sunrise Electronics Development Co., Ltd
+
+OUI:9C9C1D*
+ ID_OUI_FROM_DATABASE=Starkey Labs Inc.
+
+OUI:9CA134*
+ ID_OUI_FROM_DATABASE=Nike, Inc.
+
+OUI:9CA3BA*
+ ID_OUI_FROM_DATABASE=SAKURA Internet Inc.
+
+OUI:9CADEF*
+ ID_OUI_FROM_DATABASE=Obihai Technology, Inc.
+
+OUI:9CAFCA*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:9CB008*
+ ID_OUI_FROM_DATABASE=Ubiquitous Computing Technology Corporation
+
+OUI:9CB206*
+ ID_OUI_FROM_DATABASE=PROCENTEC
+
+OUI:9CB70D*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:9CC077*
+ ID_OUI_FROM_DATABASE=PrintCounts, LLC
+
+OUI:9CC0D2*
+ ID_OUI_FROM_DATABASE=Conductix-Wampfler AG
+
+OUI:9CC7A6*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:9CC7D1*
+ ID_OUI_FROM_DATABASE=SHARP Corporation
+
+OUI:9CCAD9*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:9CCD82*
+ ID_OUI_FROM_DATABASE=CHENG UEI PRECISION INDUSTRY CO.,LTD
+
+OUI:9CD24B*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:9CD36D*
+ ID_OUI_FROM_DATABASE=NETGEAR INC.,
+
+OUI:9CDF03*
+ ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH
+
+OUI:9CE10E*
+ ID_OUI_FROM_DATABASE=NCTech Ltd
+
+OUI:9CE1D6*
+ ID_OUI_FROM_DATABASE=Junger Audio-Studiotechnik GmbH
+
+OUI:9CE635*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:9CEBE8*
+ ID_OUI_FROM_DATABASE=BizLink (Kunshan) Co.,Ltd
+
+OUI:9CF61A*
+ ID_OUI_FROM_DATABASE=UTC Fire and Security
+
+OUI:9CF67D*
+ ID_OUI_FROM_DATABASE=Ricardo Prague, s.r.o.
+
+OUI:9CF938*
+ ID_OUI_FROM_DATABASE=AREVA NP GmbH
+
+OUI:9CFFBE*
+ ID_OUI_FROM_DATABASE=OTSL Inc.
+
+OUI:A00363*
+ ID_OUI_FROM_DATABASE=Robert Bosch Healthcare GmbH
+
+OUI:A00798*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:A007B6*
+ ID_OUI_FROM_DATABASE=Advanced Technical Support, Inc.
+
+OUI:A00ABF*
+ ID_OUI_FROM_DATABASE=Wieson Technologies Co., Ltd.
+
+OUI:A00BBA*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS
+
+OUI:A00CA1*
+ ID_OUI_FROM_DATABASE=SKTB "SKiT"
+
+OUI:A0133B*
+ ID_OUI_FROM_DATABASE=Copyright © HiTi Digital, Inc.
+
+OUI:A0165C*
+ ID_OUI_FROM_DATABASE=TangoTec Ltd.
+
+OUI:A01859*
+ ID_OUI_FROM_DATABASE=Shenzhen Yidashi Electronics Co Ltd
+
+OUI:A01917*
+ ID_OUI_FROM_DATABASE=Bertel S.p.a.
+
+OUI:A02195*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Digital Imaging
+
+OUI:A021B7*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A0231B*
+ ID_OUI_FROM_DATABASE=TeleComp R&D Corp.
+
+OUI:A02EF3*
+ ID_OUI_FROM_DATABASE=United Integrated Services Co., Led.
+
+OUI:A0369F*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:A036F0*
+ ID_OUI_FROM_DATABASE=Comprehensive Power
+
+OUI:A036FA*
+ ID_OUI_FROM_DATABASE=Ettus Research LLC
+
+OUI:A03A75*
+ ID_OUI_FROM_DATABASE=PSS Belgium N.V.
+
+OUI:A04025*
+ ID_OUI_FROM_DATABASE=Actioncable, Inc.
+
+OUI:A04041*
+ ID_OUI_FROM_DATABASE=SAMWONFA Co.,Ltd.
+
+OUI:A041A7*
+ ID_OUI_FROM_DATABASE=NL Ministry of Defense
+
+OUI:A0423F*
+ ID_OUI_FROM_DATABASE=Tyan Computer Corp
+
+OUI:A04CC1*
+ ID_OUI_FROM_DATABASE=Helixtech Corp.
+
+OUI:A04E04*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:A051C6*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:A055DE*
+ ID_OUI_FROM_DATABASE=Pace plc
+
+OUI:A0593A*
+ ID_OUI_FROM_DATABASE=V.D.S. Video Display Systems srl
+
+OUI:A05AA4*
+ ID_OUI_FROM_DATABASE=Grand Products Nevada, Inc.
+
+OUI:A05DC1*
+ ID_OUI_FROM_DATABASE=TMCT Co., LTD.
+
+OUI:A05DE7*
+ ID_OUI_FROM_DATABASE=DIRECTV, Inc.
+
+OUI:A05E6B*
+ ID_OUI_FROM_DATABASE=MELPER Co., Ltd.
+
+OUI:A06986*
+ ID_OUI_FROM_DATABASE=Wellav Technologies Ltd
+
+OUI:A06A00*
+ ID_OUI_FROM_DATABASE=Verilink Corporation
+
+OUI:A06CEC*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:A06D09*
+ ID_OUI_FROM_DATABASE=Intelcan Technosystems Inc.
+
+OUI:A06E50*
+ ID_OUI_FROM_DATABASE=Nanotek Elektronik Sistemler Ltd. Sti.
+
+OUI:A071A9*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:A07332*
+ ID_OUI_FROM_DATABASE=Cashmaster International Limited
+
+OUI:A07591*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:A078BA*
+ ID_OUI_FROM_DATABASE=Pantech Co., Ltd.
+
+OUI:A082C7*
+ ID_OUI_FROM_DATABASE=P.T.I Co.,LTD
+
+OUI:A086EC*
+ ID_OUI_FROM_DATABASE=SAEHAN HITEC Co., Ltd
+
+OUI:A08869*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:A088B4*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:A08C15*
+ ID_OUI_FROM_DATABASE=Gerhard D. Wempe KG
+
+OUI:A08C9B*
+ ID_OUI_FROM_DATABASE=Xtreme Technologies Corp
+
+OUI:A090DE*
+ ID_OUI_FROM_DATABASE=VEEDIMS,LLC
+
+OUI:A09805*
+ ID_OUI_FROM_DATABASE=OpenVox Communication Co Ltd
+
+OUI:A098ED*
+ ID_OUI_FROM_DATABASE=Shandong Intelligent Optical Communication Development Co., Ltd.
+
+OUI:A09A5A*
+ ID_OUI_FROM_DATABASE=Time Domain
+
+OUI:A0A130*
+ ID_OUI_FROM_DATABASE=DLI Taiwan Branch office
+
+OUI:A0A763*
+ ID_OUI_FROM_DATABASE=Polytron Vertrieb GmbH
+
+OUI:A0AAFD*
+ ID_OUI_FROM_DATABASE=EraThink Technologies Corp.
+
+OUI:A0B3CC*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:A0B5DA*
+ ID_OUI_FROM_DATABASE=HongKong THTF Co., Ltd
+
+OUI:A0B662*
+ ID_OUI_FROM_DATABASE=Acutvista Innovation Co., Ltd.
+
+OUI:A0B9ED*
+ ID_OUI_FROM_DATABASE=Skytap
+
+OUI:A0BAB8*
+ ID_OUI_FROM_DATABASE=Pixon Imaging
+
+OUI:A0BFA5*
+ ID_OUI_FROM_DATABASE=CORESYS
+
+OUI:A0C3DE*
+ ID_OUI_FROM_DATABASE=Triton Electronic Systems Ltd.
+
+OUI:A0CF5B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:A0DC04*
+ ID_OUI_FROM_DATABASE=Becker-Antriebe GmbH
+
+OUI:A0DD97*
+ ID_OUI_FROM_DATABASE=PolarLink Technologies, Ltd
+
+OUI:A0DDE5*
+ ID_OUI_FROM_DATABASE=SHARP CORPORATION
+
+OUI:A0DE05*
+ ID_OUI_FROM_DATABASE=JSC "Irbis-T"
+
+OUI:A0E201*
+ ID_OUI_FROM_DATABASE=AVTrace Ltd.(China)
+
+OUI:A0E25A*
+ ID_OUI_FROM_DATABASE=Amicus SK, s.r.o.
+
+OUI:A0E295*
+ ID_OUI_FROM_DATABASE=DAT System Co.,Ltd
+
+OUI:A0E534*
+ ID_OUI_FROM_DATABASE=Stratec Biomedical AG
+
+OUI:A0E9DB*
+ ID_OUI_FROM_DATABASE=Ningbo FreeWings Technologies Co.,Ltd
+
+OUI:A0EF84*
+ ID_OUI_FROM_DATABASE=Seine Image Int'l Co., Ltd
+
+OUI:A0F217*
+ ID_OUI_FROM_DATABASE=GE Medical System(China) Co., Ltd.
+
+OUI:A0F3C1*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:A0F3E4*
+ ID_OUI_FROM_DATABASE=Alcatel Lucent IPD
+
+OUI:A0F419*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:A0F450*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:A0FE91*
+ ID_OUI_FROM_DATABASE=AVAT Automation GmbH
+
+OUI:A40130*
+ ID_OUI_FROM_DATABASE=ABIsystems Co., LTD
+
+OUI:A40BED*
+ ID_OUI_FROM_DATABASE=Carry Technology Co.,Ltd
+
+OUI:A40CC3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:A4134E*
+ ID_OUI_FROM_DATABASE=Luxul
+
+OUI:A41731*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:A41875*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:A41BC0*
+ ID_OUI_FROM_DATABASE=Fastec Imaging Corporation
+
+OUI:A41F72*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:A4218A*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:A424B3*
+ ID_OUI_FROM_DATABASE=FlatFrog Laboratories AB
+
+OUI:A429B7*
+ ID_OUI_FROM_DATABASE=bluesky
+
+OUI:A42C08*
+ ID_OUI_FROM_DATABASE=Masterwork Automodules
+
+OUI:A433D1*
+ ID_OUI_FROM_DATABASE=Fibrlink Communications Co.,Ltd.
+
+OUI:A438FC*
+ ID_OUI_FROM_DATABASE=Plastic Logic
+
+OUI:A4466B*
+ ID_OUI_FROM_DATABASE=EOC Technology
+
+OUI:A446FA*
+ ID_OUI_FROM_DATABASE=AmTRAN Video Corporation
+
+OUI:A44B15*
+ ID_OUI_FROM_DATABASE=Sun Cupid Technology (HK) LTD
+
+OUI:A44C11*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:A44E2D*
+ ID_OUI_FROM_DATABASE=Adaptive Wireless Solutions, LLC
+
+OUI:A44E31*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:A45055*
+ ID_OUI_FROM_DATABASE=busware.de
+
+OUI:A4526F*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:A4561B*
+ ID_OUI_FROM_DATABASE=MCOT Corporation
+
+OUI:A45630*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:A45A1C*
+ ID_OUI_FROM_DATABASE=smart-electronic GmbH
+
+OUI:A45C27*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:A46706*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:A46E79*
+ ID_OUI_FROM_DATABASE=DFT System Co.Ltd
+
+OUI:A479E4*
+ ID_OUI_FROM_DATABASE=KLINFO Corp
+
+OUI:A47AA4*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:A47C14*
+ ID_OUI_FROM_DATABASE=ChargeStorm AB
+
+OUI:A47C1F*
+ ID_OUI_FROM_DATABASE=Global Microwave Systems Inc.
+
+OUI:A4856B*
+ ID_OUI_FROM_DATABASE=Q Electronics Ltd
+
+OUI:A49005*
+ ID_OUI_FROM_DATABASE=CHINA GREATWALL COMPUTER SHENZHEN CO.,LTD
+
+OUI:A4934C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:A497BB*
+ ID_OUI_FROM_DATABASE=Hitachi Industrial Equipment Systems Co.,Ltd
+
+OUI:A49947*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:A49981*
+ ID_OUI_FROM_DATABASE=FuJian Elite Power Tech CO.,LTD.
+
+OUI:A49B13*
+ ID_OUI_FROM_DATABASE=Burroughs Payment Systems, Inc.
+
+OUI:A4A24A*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:A4A80F*
+ ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd.
+
+OUI:A4AD00*
+ ID_OUI_FROM_DATABASE=Ragsdale Technology
+
+OUI:A4ADB8*
+ ID_OUI_FROM_DATABASE=Vitec Group, Camera Dynamics Ltd
+
+OUI:A4AE9A*
+ ID_OUI_FROM_DATABASE=Maestro Wireless Solutions ltd.
+
+OUI:A4B121*
+ ID_OUI_FROM_DATABASE=Arantia 2010 S.L.
+
+OUI:A4B197*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:A4B1E9*
+ ID_OUI_FROM_DATABASE=Technicolor
+
+OUI:A4B1EE*
+ ID_OUI_FROM_DATABASE=H. ZANDER GmbH & Co. KG
+
+OUI:A4B2A7*
+ ID_OUI_FROM_DATABASE=Adaxys Solutions AG
+
+OUI:A4B36A*
+ ID_OUI_FROM_DATABASE=JSC SDO Chromatec
+
+OUI:A4B980*
+ ID_OUI_FROM_DATABASE=Parking BOXX Inc.
+
+OUI:A4BADB*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:A4BE61*
+ ID_OUI_FROM_DATABASE=EutroVision System, Inc.
+
+OUI:A4C0E1*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:A4C2AB*
+ ID_OUI_FROM_DATABASE=Hangzhou LEAD-IT Information & Technology Co.,Ltd
+
+OUI:A4D18F*
+ ID_OUI_FROM_DATABASE=Shenzhen Skyee Optical Fiber Communication Technology Ltd.
+
+OUI:A4D1D1*
+ ID_OUI_FROM_DATABASE=ECOtality North America
+
+OUI:A4D1D2*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:A4D856*
+ ID_OUI_FROM_DATABASE=Qualcomm Labs Inc.
+
+OUI:A4DA3F*
+ ID_OUI_FROM_DATABASE=Bionics Corp.
+
+OUI:A4DB2E*
+ ID_OUI_FROM_DATABASE=Kingspan Environmental Ltd
+
+OUI:A4DE50*
+ ID_OUI_FROM_DATABASE=Total Walther GmbH
+
+OUI:A4E32E*
+ ID_OUI_FROM_DATABASE=Silicon & Software Systems Ltd.
+
+OUI:A4E391*
+ ID_OUI_FROM_DATABASE=DENY FONTAINE
+
+OUI:A4E731*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:A4E7E4*
+ ID_OUI_FROM_DATABASE=Connex GmbH
+
+OUI:A4ED4E*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:A4EE57*
+ ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION
+
+OUI:A4EF52*
+ ID_OUI_FROM_DATABASE=Telewave Co., Ltd.
+
+OUI:A4F7D0*
+ ID_OUI_FROM_DATABASE=LAN Accessories Co., Ltd.
+
+OUI:A80180*
+ ID_OUI_FROM_DATABASE=IMAGO Technologies GmbH
+
+OUI:A80600*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:A816B2*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:A81758*
+ ID_OUI_FROM_DATABASE=Elektronik System i Umeå AB
+
+OUI:A81B18*
+ ID_OUI_FROM_DATABASE=XTS CORP
+
+OUI:A81FAF*
+ ID_OUI_FROM_DATABASE=KRYPTON POLSKA
+
+OUI:A82066*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:A826D9*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:A82BD6*
+ ID_OUI_FROM_DATABASE=Shina System Co., Ltd
+
+OUI:A830AD*
+ ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd
+
+OUI:A83944*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:A84041*
+ ID_OUI_FROM_DATABASE=Dragino Technology Co., Limited
+
+OUI:A84481*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:A845E9*
+ ID_OUI_FROM_DATABASE=Firich Enterprises CO., LTD.
+
+OUI:A849A5*
+ ID_OUI_FROM_DATABASE=Lisantech Co., Ltd.
+
+OUI:A854B2*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
+
+OUI:A8556A*
+ ID_OUI_FROM_DATABASE=Pocketnet Technology Inc.
+
+OUI:A85BB0*
+ ID_OUI_FROM_DATABASE=Shenzhen Dehoo Technology Co.,Ltd
+
+OUI:A85BF3*
+ ID_OUI_FROM_DATABASE=Audivo GmbH
+
+OUI:A862A2*
+ ID_OUI_FROM_DATABASE=JIWUMEDIA CO., LTD.
+
+OUI:A863DF*
+ ID_OUI_FROM_DATABASE=DISPLAIRE CORPORATION
+
+OUI:A863F2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:A865B2*
+ ID_OUI_FROM_DATABASE=DONGGUAN YISHANG ELECTRONIC TECHNOLOGY CO., LIMITED
+
+OUI:A86A6F*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:A870A5*
+ ID_OUI_FROM_DATABASE=UniComm Inc.
+
+OUI:A875D6*
+ ID_OUI_FROM_DATABASE=FreeTek International Co., Ltd.
+
+OUI:A8776F*
+ ID_OUI_FROM_DATABASE=Zonoff
+
+OUI:A87B39*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:A87E33*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:A88792*
+ ID_OUI_FROM_DATABASE=Broadband Antenna Tracking Systems
+
+OUI:A887ED*
+ ID_OUI_FROM_DATABASE=ARC Wireless LLC
+
+OUI:A88CEE*
+ ID_OUI_FROM_DATABASE=MicroMade Galka i Drozdz sp.j.
+
+OUI:A8922C*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:A893E6*
+ ID_OUI_FROM_DATABASE=JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LTD
+
+OUI:A895B0*
+ ID_OUI_FROM_DATABASE=Aker Subsea Ltd
+
+OUI:A8968A*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:A898C6*
+ ID_OUI_FROM_DATABASE=Shinbo Co., Ltd.
+
+OUI:A8995C*
+ ID_OUI_FROM_DATABASE=aizo ag
+
+OUI:A89B10*
+ ID_OUI_FROM_DATABASE=inMotion Ltd.
+
+OUI:A8AD3D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:A8B0AE*
+ ID_OUI_FROM_DATABASE=LEONI
+
+OUI:A8B1D4*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:A8BD1A*
+ ID_OUI_FROM_DATABASE=Honey Bee (Hong Kong) Limited
+
+OUI:A8C222*
+ ID_OUI_FROM_DATABASE=TM-Research Inc.
+
+OUI:A8CB95*
+ ID_OUI_FROM_DATABASE=EAST BEST CO., LTD.
+
+OUI:A8CE90*
+ ID_OUI_FROM_DATABASE=CVC
+
+OUI:A8D0E5*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:A8D3C8*
+ ID_OUI_FROM_DATABASE=Wachendorff Elektronik  GmbH & Co. KG
+
+OUI:A8E018*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:A8E3EE*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+
+OUI:A8EF26*
+ ID_OUI_FROM_DATABASE=Tritonwave
+
+OUI:A8F274*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:A8F470*
+ ID_OUI_FROM_DATABASE=Fujian Newland Communication Science Technologies Co.,Ltd.
+
+OUI:A8F94B*
+ ID_OUI_FROM_DATABASE=Eltex Enterprise Ltd.
+
+OUI:A8FAD8*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:A8FCB7*
+ ID_OUI_FROM_DATABASE=Consolidated Resource Imaging
+
+OUI:AA0000*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:AA0001*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:AA0002*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:AA0003*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:AA0004*
+ ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION
+
+OUI:AC0142*
+ ID_OUI_FROM_DATABASE=Uriel Technologies SIA
+
+OUI:AC02CF*
+ ID_OUI_FROM_DATABASE=RW Tecnologia Industria e Comercio Ltda
+
+OUI:AC02EF*
+ ID_OUI_FROM_DATABASE=Comsis
+
+OUI:AC0613*
+ ID_OUI_FROM_DATABASE=Senselogix Ltd
+
+OUI:AC0A61*
+ ID_OUI_FROM_DATABASE=Labor S.r.L.
+
+OUI:AC0DFE*
+ ID_OUI_FROM_DATABASE=Ekon GmbH - myGEKKO
+
+OUI:AC1461*
+ ID_OUI_FROM_DATABASE=ATAW  Co., Ltd.
+
+OUI:AC14D2*
+ ID_OUI_FROM_DATABASE=wi-daq, inc.
+
+OUI:AC162D*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:AC1702*
+ ID_OUI_FROM_DATABASE=Fibar Group sp. z o.o.
+
+OUI:AC199F*
+ ID_OUI_FROM_DATABASE=SUNGROW POWER SUPPLY CO.,LTD.
+
+OUI:AC20AA*
+ ID_OUI_FROM_DATABASE=DMATEK Co., Ltd.
+
+OUI:AC2FA8*
+ ID_OUI_FROM_DATABASE=Humannix Co.,Ltd.
+
+OUI:AC319D*
+ ID_OUI_FROM_DATABASE=Shenzhen TG-NET Botone Technology Co.,Ltd.
+
+OUI:AC34CB*
+ ID_OUI_FROM_DATABASE=Shanhai GBCOM Communication Technology Co. Ltd
+
+OUI:AC3C0B*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:AC3CB4*
+ ID_OUI_FROM_DATABASE=Nilan A/S
+
+OUI:AC3D05*
+ ID_OUI_FROM_DATABASE=Instorescreen Aisa
+
+OUI:AC3D75*
+ ID_OUI_FROM_DATABASE=HANGZHOU ZHIWAY TECHNOLOGIES CO.,LTD.
+
+OUI:AC3FA4*
+ ID_OUI_FROM_DATABASE=TAIYO YUDEN CO.,LTD
+
+OUI:AC40EA*
+ ID_OUI_FROM_DATABASE=C&T Solution Inc.
+
+OUI:AC44F2*
+ ID_OUI_FROM_DATABASE=Revolabs Inc
+
+OUI:AC4723*
+ ID_OUI_FROM_DATABASE=Genelec
+
+OUI:AC4AFE*
+ ID_OUI_FROM_DATABASE=Hisense Broadband Multimedia Technology Co.,Ltd.
+
+OUI:AC4BC8*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:AC4FFC*
+ ID_OUI_FROM_DATABASE=SVS-VISTEK GmbH
+
+OUI:AC5135*
+ ID_OUI_FROM_DATABASE=MPI TECH
+
+OUI:AC51EE*
+ ID_OUI_FROM_DATABASE=Cambridge Communication Systems Ltd
+
+OUI:AC54EC*
+ ID_OUI_FROM_DATABASE=IEEE P1823 Standards Working Group
+
+OUI:AC583B*
+ ID_OUI_FROM_DATABASE=Human Assembler, Inc.
+
+OUI:AC5D10*
+ ID_OUI_FROM_DATABASE=Pace Americas
+
+OUI:AC5E8C*
+ ID_OUI_FROM_DATABASE=Utillink
+
+OUI:AC6123*
+ ID_OUI_FROM_DATABASE=Drivven, Inc.
+
+OUI:AC6706*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:AC6E1A*
+ ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
+
+OUI:AC6F4F*
+ ID_OUI_FROM_DATABASE=Enspert Inc
+
+OUI:AC6FBB*
+ ID_OUI_FROM_DATABASE=TATUNG Technology Inc.
+
+OUI:AC6FD9*
+ ID_OUI_FROM_DATABASE=Valueplus Inc.
+
+OUI:AC7236*
+ ID_OUI_FROM_DATABASE=Lexking Technology Co., Ltd.
+
+OUI:AC7289*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:AC7A42*
+ ID_OUI_FROM_DATABASE=iConnectivity
+
+OUI:AC7BA1*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:AC80D6*
+ ID_OUI_FROM_DATABASE=Hexatronic AB
+
+OUI:AC8112*
+ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+
+OUI:AC81F3*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:AC8317*
+ ID_OUI_FROM_DATABASE=Shenzhen Furtunetel Communication Co., Ltd
+
+OUI:AC83F0*
+ ID_OUI_FROM_DATABASE=Magenta Video Networks
+
+OUI:AC8674*
+ ID_OUI_FROM_DATABASE=Open Mesh, Inc.
+
+OUI:AC867E*
+ ID_OUI_FROM_DATABASE=Create New Technology (HK) Limited Company
+
+OUI:AC8ACD*
+ ID_OUI_FROM_DATABASE=ROGER D.Wensker, G.Wensker sp.j.
+
+OUI:AC8D14*
+ ID_OUI_FROM_DATABASE=Smartrove Inc
+
+OUI:AC932F*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:AC9403*
+ ID_OUI_FROM_DATABASE=Envision Peripherals Inc
+
+OUI:AC9A96*
+ ID_OUI_FROM_DATABASE=Lantiq Deutschland GmbH
+
+OUI:AC9B84*
+ ID_OUI_FROM_DATABASE=Smak Tecnologia e Automacao
+
+OUI:AC9CE4*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:ACA016*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:ACA22C*
+ ID_OUI_FROM_DATABASE=Baycity Technologies Ltd
+
+OUI:ACA430*
+ ID_OUI_FROM_DATABASE=Peerless AV
+
+OUI:ACAB8D*
+ ID_OUI_FROM_DATABASE=Lyngso Marine A/S
+
+OUI:ACBD0B*
+ ID_OUI_FROM_DATABASE=IMAC CO.,LTD
+
+OUI:ACBE75*
+ ID_OUI_FROM_DATABASE=Ufine Technologies Co.,Ltd.
+
+OUI:ACBEB6*
+ ID_OUI_FROM_DATABASE=Visualedge Technology Co., Ltd.
+
+OUI:ACC2EC*
+ ID_OUI_FROM_DATABASE=CLT INT'L IND. CORP.
+
+OUI:ACC698*
+ ID_OUI_FROM_DATABASE=Kohzu Precision Co., Ltd.
+
+OUI:ACC935*
+ ID_OUI_FROM_DATABASE=Ness Corporation
+
+OUI:ACCA54*
+ ID_OUI_FROM_DATABASE=Telldus Technologies AB
+
+OUI:ACCABA*
+ ID_OUI_FROM_DATABASE=Midokura Co., Ltd.
+
+OUI:ACCB09*
+ ID_OUI_FROM_DATABASE=Hefcom Metering (Pty) Ltd
+
+OUI:ACCC8E*
+ ID_OUI_FROM_DATABASE=Axis Communications AB
+
+OUI:ACCE8F*
+ ID_OUI_FROM_DATABASE=HWA YAO TECHNOLOGIES CO., LTD
+
+OUI:ACCF23*
+ ID_OUI_FROM_DATABASE=Hi-flying electronics technology Co.,Ltd
+
+OUI:ACD180*
+ ID_OUI_FROM_DATABASE=Crexendo Business Solutions, Inc.
+
+OUI:ACD364*
+ ID_OUI_FROM_DATABASE=ABB SPA, ABB SACE DIV.
+
+OUI:ACD9D6*
+ ID_OUI_FROM_DATABASE=tci GmbH
+
+OUI:ACDBDA*
+ ID_OUI_FROM_DATABASE=Shenzhen Geniatech Inc, Ltd
+
+OUI:ACE215*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:ACE348*
+ ID_OUI_FROM_DATABASE=MadgeTech, Inc
+
+OUI:ACE64B*
+ ID_OUI_FROM_DATABASE=Shenzhen Baojia Battery Technology Co., Ltd.
+
+OUI:ACE87B*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:ACE87E*
+ ID_OUI_FROM_DATABASE=Bytemark Computer Consulting Ltd
+
+OUI:ACE97F*
+ ID_OUI_FROM_DATABASE=IoT Tech Limited
+
+OUI:ACE9AA*
+ ID_OUI_FROM_DATABASE=Hay Systems Ltd
+
+OUI:ACEA6A*
+ ID_OUI_FROM_DATABASE=GENIX INFOCOMM CO., LTD.
+
+OUI:ACEE3B*
+ ID_OUI_FROM_DATABASE=6harmonics Inc
+
+OUI:ACF0B2*
+ ID_OUI_FROM_DATABASE=Becker Electronics Taiwan Ltd.
+
+OUI:ACF1DF*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:ACF2C5*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:ACF7F3*
+ ID_OUI_FROM_DATABASE=XIAOMI CORPORATION
+
+OUI:ACF97E*
+ ID_OUI_FROM_DATABASE=ELESYS INC.
+
+OUI:B01203*
+ ID_OUI_FROM_DATABASE=Dynamics Hong Kong Limited
+
+OUI:B01266*
+ ID_OUI_FROM_DATABASE=Futaba-Kikaku
+
+OUI:B01408*
+ ID_OUI_FROM_DATABASE=LIGHTSPEED INTERNATIONAL CO.
+
+OUI:B01B7C*
+ ID_OUI_FROM_DATABASE=Ontrol A.S.
+
+OUI:B01C91*
+ ID_OUI_FROM_DATABASE=Elim Co
+
+OUI:B0358D*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:B03829*
+ ID_OUI_FROM_DATABASE=Siliconware Precision Industries Co., Ltd.
+
+OUI:B0435D*
+ ID_OUI_FROM_DATABASE=NuLEDs, Inc.
+
+OUI:B046FC*
+ ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
+
+OUI:B0487A*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:B0518E*
+ ID_OUI_FROM_DATABASE=Holl technology CO.Ltd.
+
+OUI:B058C4*
+ ID_OUI_FROM_DATABASE=Broadcast Microwave Services, Inc
+
+OUI:B05B1F*
+ ID_OUI_FROM_DATABASE=THERMO FISHER SCIENTIFIC S.P.A.
+
+OUI:B05CE5*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:B06563*
+ ID_OUI_FROM_DATABASE=Shanghai Railway Communication Factory
+
+OUI:B065BD*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:B06CBF*
+ ID_OUI_FROM_DATABASE=3ality Digital Systems GmbH
+
+OUI:B0750C*
+ ID_OUI_FROM_DATABASE=QA Cafe
+
+OUI:B075D5*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:B077AC*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:B07994*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
+OUI:B07D62*
+ ID_OUI_FROM_DATABASE=Dipl.-Ing. H. Horstmann GmbH
+
+OUI:B081D8*
+ ID_OUI_FROM_DATABASE=I-sys Corp
+
+OUI:B08991*
+ ID_OUI_FROM_DATABASE=LGE
+
+OUI:B08E1A*
+ ID_OUI_FROM_DATABASE=URadio Systems Co., Ltd
+
+OUI:B09074*
+ ID_OUI_FROM_DATABASE=Fulan Electronics Limited
+
+OUI:B09134*
+ ID_OUI_FROM_DATABASE=Taleo
+
+OUI:B0973A*
+ ID_OUI_FROM_DATABASE=E-Fuel Corporation
+
+OUI:B09928*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
+OUI:B09AE2*
+ ID_OUI_FROM_DATABASE=STEMMER IMAGING GmbH
+
+OUI:B09BD4*
+ ID_OUI_FROM_DATABASE=GNH Software India Private Limited
+
+OUI:B0A10A*
+ ID_OUI_FROM_DATABASE=Pivotal Systems Corporation
+
+OUI:B0A72A*
+ ID_OUI_FROM_DATABASE=Ensemble Designs, Inc.
+
+OUI:B0A86E*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:B0AA36*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD.
+
+OUI:B0ACFA*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
+OUI:B0B2DC*
+ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation
+
+OUI:B0B32B*
+ ID_OUI_FROM_DATABASE=Slican Sp. z o.o.
+
+OUI:B0B8D5*
+ ID_OUI_FROM_DATABASE=Nanjing Nengrui Auto Equipment CO.,Ltd
+
+OUI:B0BD6D*
+ ID_OUI_FROM_DATABASE=Echostreams Innovative Solutions
+
+OUI:B0BDA1*
+ ID_OUI_FROM_DATABASE=ZAKLAD ELEKTRONICZNY SIMS
+
+OUI:B0BF99*
+ ID_OUI_FROM_DATABASE=WIZITDONGDO
+
+OUI:B0C4E7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:B0C69A*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:B0C745*
+ ID_OUI_FROM_DATABASE=Buffalo Inc.
+
+OUI:B0C83F*
+ ID_OUI_FROM_DATABASE=Jiangsu Cynray IOT Co., Ltd.
+
+OUI:B0C8AD*
+ ID_OUI_FROM_DATABASE=People Power Company
+
+OUI:B0C95B*
+ ID_OUI_FROM_DATABASE=Beijing Symtech CO.,LTD
+
+OUI:B0CF4D*
+ ID_OUI_FROM_DATABASE=MI-Zone Technology Ireland
+
+OUI:B0D09C*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:B0D2F5*
+ ID_OUI_FROM_DATABASE=Vello Systems, Inc.
+
+OUI:B0E39D*
+ ID_OUI_FROM_DATABASE=CAT SYSTEM CO.,LTD.
+
+OUI:B0E50E*
+ ID_OUI_FROM_DATABASE=NRG SYSTEMS INC
+
+OUI:B0E754*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:B0E892*
+ ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION
+
+OUI:B0E97E*
+ ID_OUI_FROM_DATABASE=Advanced Micro Peripherals
+
+OUI:B0EC71*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:B0EE45*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc.
+
+OUI:B0F1BC*
+ ID_OUI_FROM_DATABASE=Dhemax Ingenieros Ltda
+
+OUI:B0FAEB*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:B4009C*
+ ID_OUI_FROM_DATABASE=CableWorld Ltd.
+
+OUI:B40142*
+ ID_OUI_FROM_DATABASE=GCI Science & Technology Co.,LTD
+
+OUI:B40418*
+ ID_OUI_FROM_DATABASE=Smartchip Integrated Inc.
+
+OUI:B407F9*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS
+
+OUI:B40832*
+ ID_OUI_FROM_DATABASE=TC Communications
+
+OUI:B40B7A*
+ ID_OUI_FROM_DATABASE=Brusa Elektronik AG
+
+OUI:B40C25*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:B40E96*
+ ID_OUI_FROM_DATABASE=HERAN
+
+OUI:B40EDC*
+ ID_OUI_FROM_DATABASE=LG-Ericsson Co.,Ltd.
+
+OUI:B41489*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:B41DEF*
+ ID_OUI_FROM_DATABASE=Internet Laboratories, Inc.
+
+OUI:B4211D*
+ ID_OUI_FROM_DATABASE=Beijing GuangXin Technology Co., Ltd
+
+OUI:B4218A*
+ ID_OUI_FROM_DATABASE=Dog Hunter LLC
+
+OUI:B428F1*
+ ID_OUI_FROM_DATABASE=E-Prime Co., Ltd.
+
+OUI:B42A39*
+ ID_OUI_FROM_DATABASE=ORBIT MERRET, spol. s r. o.
+
+OUI:B42CBE*
+ ID_OUI_FROM_DATABASE=Direct Payment Solutions Limited
+
+OUI:B431B8*
+ ID_OUI_FROM_DATABASE=Aviwest
+
+OUI:B43564*
+ ID_OUI_FROM_DATABASE=Fujian Tian Cheng Electron Science & Technical Development Co.,Ltd.
+
+OUI:B435F7*
+ ID_OUI_FROM_DATABASE=Zhejiang Pearmain Electronics Co.ltd.
+
+OUI:B43741*
+ ID_OUI_FROM_DATABASE=Consert, Inc.
+
+OUI:B439D6*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:B43DB2*
+ ID_OUI_FROM_DATABASE=Degreane Horizon
+
+OUI:B4417A*
+ ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd
+
+OUI:B44CC2*
+ ID_OUI_FROM_DATABASE=NR ELECTRIC CO., LTD
+
+OUI:B451F9*
+ ID_OUI_FROM_DATABASE=NB Software
+
+OUI:B45253*
+ ID_OUI_FROM_DATABASE=Seagate Technology
+
+OUI:B45570*
+ ID_OUI_FROM_DATABASE=Borea
+
+OUI:B45861*
+ ID_OUI_FROM_DATABASE=CRemote, LLC
+
+OUI:B45CA4*
+ ID_OUI_FROM_DATABASE=Thing-talk Wireless Communication Technologies Corporation Limited
+
+OUI:B461FF*
+ ID_OUI_FROM_DATABASE=Lumigon A/S
+
+OUI:B46238*
+ ID_OUI_FROM_DATABASE=Exablox
+
+OUI:B46293*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:B467E9*
+ ID_OUI_FROM_DATABASE=Qingdao GoerTek Technology Co., Ltd.
+
+OUI:B4749F*
+ ID_OUI_FROM_DATABASE=askey computer corp
+
+OUI:B47F5E*
+ ID_OUI_FROM_DATABASE=Foresight Manufacture (S) Pte Ltd
+
+OUI:B48255*
+ ID_OUI_FROM_DATABASE=Research Products Corporation
+
+OUI:B482C5*
+ ID_OUI_FROM_DATABASE=Relay2, Inc.
+
+OUI:B482FE*
+ ID_OUI_FROM_DATABASE=Askey Computer Corp
+
+OUI:B48910*
+ ID_OUI_FROM_DATABASE=Coster T.E. S.P.A.
+
+OUI:B4944E*
+ ID_OUI_FROM_DATABASE=WeTelecom Co., Ltd.
+
+OUI:B49842*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:B499BA*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:B49DB4*
+ ID_OUI_FROM_DATABASE=Axion Technologies Inc.
+
+OUI:B49EE6*
+ ID_OUI_FROM_DATABASE=SHENZHEN TECHNOLOGY CO LTD
+
+OUI:B4A4B5*
+ ID_OUI_FROM_DATABASE=Zen Eye Co.,Ltd
+
+OUI:B4A4E3*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:B4A5A9*
+ ID_OUI_FROM_DATABASE=MODI GmbH
+
+OUI:B4AA4D*
+ ID_OUI_FROM_DATABASE=Ensequence, Inc.
+
+OUI:B4AB2C*
+ ID_OUI_FROM_DATABASE=MtM Technology Corporation
+
+OUI:B4B017*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:B4B362*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:B4B52F*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:B4B5AF*
+ ID_OUI_FROM_DATABASE=Minsung Electronics
+
+OUI:B4B676*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:B4B88D*
+ ID_OUI_FROM_DATABASE=Thuh Company
+
+OUI:B4C44E*
+ ID_OUI_FROM_DATABASE=VXL eTech Pvt Ltd
+
+OUI:B4C799*
+ ID_OUI_FROM_DATABASE=Motorola Solutions Inc.
+
+OUI:B4C810*
+ ID_OUI_FROM_DATABASE=UMPI Elettronica
+
+OUI:B4CFDB*
+ ID_OUI_FROM_DATABASE=Shenzhen Jiuzhou Electric Co.,LTD
+
+OUI:B4D8A9*
+ ID_OUI_FROM_DATABASE=BetterBots
+
+OUI:B4D8DE*
+ ID_OUI_FROM_DATABASE=iota Computing, Inc.
+
+OUI:B4DF3B*
+ ID_OUI_FROM_DATABASE=Chromlech
+
+OUI:B4DFFA*
+ ID_OUI_FROM_DATABASE=Litemax Electronics Inc.
+
+OUI:B4E0CD*
+ ID_OUI_FROM_DATABASE=IO Turbine, Inc.
+
+OUI:B4E9B0*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:B4ED19*
+ ID_OUI_FROM_DATABASE=Pie Digital, Inc.
+
+OUI:B4ED54*
+ ID_OUI_FROM_DATABASE=Wohler Technologies
+
+OUI:B4EED4*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:B4F0AB*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:B4F2E8*
+ ID_OUI_FROM_DATABASE=Pace plc
+
+OUI:B4F323*
+ ID_OUI_FROM_DATABASE=PETATEL INC.
+
+OUI:B4FC75*
+ ID_OUI_FROM_DATABASE=SEMA Electronics(HK) CO.,LTD
+
+OUI:B80305*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:B80415*
+ ID_OUI_FROM_DATABASE=Bayan Audio
+
+OUI:B80B9D*
+ ID_OUI_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH
+
+OUI:B81413*
+ ID_OUI_FROM_DATABASE=Keen High Holding(HK) Ltd.
+
+OUI:B817C2*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B81999*
+ ID_OUI_FROM_DATABASE=Nesys
+
+OUI:B820E7*
+ ID_OUI_FROM_DATABASE=Guangzhou Horizontal Information & Network Integration Co. Ltd
+
+OUI:B82410*
+ ID_OUI_FROM_DATABASE=Magneti Marelli Slovakia s.r.o.
+
+OUI:B826D4*
+ ID_OUI_FROM_DATABASE=Furukawa Industrial S.A. Produtos Elétricos
+
+OUI:B827EB*
+ ID_OUI_FROM_DATABASE=Raspberry Pi Foundation
+
+OUI:B8288B*
+ ID_OUI_FROM_DATABASE=Parker Hannifin
+
+OUI:B829F7*
+ ID_OUI_FROM_DATABASE=Blaster Tech
+
+OUI:B82ADC*
+ ID_OUI_FROM_DATABASE=EFR Europäische Funk-Rundsteuerung GmbH
+
+OUI:B82CA0*
+ ID_OUI_FROM_DATABASE=Honeywell HomMed
+
+OUI:B838CA*
+ ID_OUI_FROM_DATABASE=Kyokko Tsushin System CO.,LTD
+
+OUI:B83A7B*
+ ID_OUI_FROM_DATABASE=Worldplay (Canada) Inc.
+
+OUI:B83D4E*
+ ID_OUI_FROM_DATABASE=Shenzhen Cultraview Digital Technology Co.,Ltd Shanghai Branch
+
+OUI:B83E59*
+ ID_OUI_FROM_DATABASE=Roku, Inc
+
+OUI:B8415F*
+ ID_OUI_FROM_DATABASE=ASP AG
+
+OUI:B85510*
+ ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd.
+
+OUI:B85810*
+ ID_OUI_FROM_DATABASE=NUMERA, INC.
+
+OUI:B85AF7*
+ ID_OUI_FROM_DATABASE=Ouya, Inc
+
+OUI:B85AFE*
+ ID_OUI_FROM_DATABASE=Handaer Communication Technology (Beijing) Co., Ltd
+
+OUI:B86091*
+ ID_OUI_FROM_DATABASE=Onnet Technologies and Innovations LLC
+
+OUI:B8616F*
+ ID_OUI_FROM_DATABASE=Accton Wireless Broadband(AWB), Corp.
+
+OUI:B8621F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:B86491*
+ ID_OUI_FROM_DATABASE=CK Telecom Ltd
+
+OUI:B8653B*
+ ID_OUI_FROM_DATABASE=Bolymin, Inc.
+
+OUI:B86B23*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:B870F4*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:B87424*
+ ID_OUI_FROM_DATABASE=Viessmann Elektronik GmbH
+
+OUI:B87447*
+ ID_OUI_FROM_DATABASE=Convergence Technologies
+
+OUI:B8763F*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:B877C3*
+ ID_OUI_FROM_DATABASE=Decagon Devices, Inc.
+
+OUI:B8797E*
+ ID_OUI_FROM_DATABASE=Secure Meters (UK) Limited
+
+OUI:B8871E*
+ ID_OUI_FROM_DATABASE=Good Mind Industries Co., Ltd.
+
+OUI:B888E3*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD
+
+OUI:B889CA*
+ ID_OUI_FROM_DATABASE=ILJIN ELECTRIC Co., Ltd.
+
+OUI:B88A60*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:B88D12*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B88E3A*
+ ID_OUI_FROM_DATABASE=Infinite Technologies JLT
+
+OUI:B88F14*
+ ID_OUI_FROM_DATABASE=Analytica GmbH
+
+OUI:B8921D*
+ ID_OUI_FROM_DATABASE=BG T&A
+
+OUI:B894D2*
+ ID_OUI_FROM_DATABASE=Retail Innovation HTT AB
+
+OUI:B89674*
+ ID_OUI_FROM_DATABASE=AllDSP GmbH & Co. KG
+
+OUI:B8975A*
+ ID_OUI_FROM_DATABASE=BIOSTAR Microtech Int'l Corp.
+
+OUI:B898B0*
+ ID_OUI_FROM_DATABASE=Atlona Inc.
+
+OUI:B89AED*
+ ID_OUI_FROM_DATABASE=OceanServer Technology, Inc
+
+OUI:B89BC9*
+ ID_OUI_FROM_DATABASE=SMC Networks Inc
+
+OUI:B8A386*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:B8A3E0*
+ ID_OUI_FROM_DATABASE=BenRui Technology Co.,Ltd
+
+OUI:B8A8AF*
+ ID_OUI_FROM_DATABASE=Logic S.p.A.
+
+OUI:B8AC6F*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:B8AF67*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:B8B1C7*
+ ID_OUI_FROM_DATABASE=BT&COM CO.,LTD
+
+OUI:B8B42E*
+ ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co,Ltd.ShenZhen
+
+OUI:B8B7D7*
+ ID_OUI_FROM_DATABASE=2GIG Technologies
+
+OUI:B8B94E*
+ ID_OUI_FROM_DATABASE=Shenzhen iBaby Labs, Inc.
+
+OUI:B8BA68*
+ ID_OUI_FROM_DATABASE=Xi'an Jizhong Digital Communication Co.,Ltd
+
+OUI:B8BA72*
+ ID_OUI_FROM_DATABASE=Cynove
+
+OUI:B8BB6D*
+ ID_OUI_FROM_DATABASE=ENERES Co.,Ltd.
+
+OUI:B8BEBF*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:B8C68E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:B8C716*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:B8C75D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B8CA3A*
+ ID_OUI_FROM_DATABASE=Dell PCBA Test
+
+OUI:B8CDA7*
+ ID_OUI_FROM_DATABASE=Maxeler Technologies Ltd.
+
+OUI:B8D06F*
+ ID_OUI_FROM_DATABASE=GUANGZHOU HKUST FOK YING TUNG RESEARCH INSTITUTE
+
+OUI:B8D49D*
+ ID_OUI_FROM_DATABASE=M Seven System Ltd.
+
+OUI:B8D9CE*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:B8DAF1*
+ ID_OUI_FROM_DATABASE=Strahlenschutz- Entwicklungs- und Ausruestungsgesellschaft mbH
+
+OUI:B8DAF7*
+ ID_OUI_FROM_DATABASE=Advanced Photonics, Inc.
+
+OUI:B8E589*
+ ID_OUI_FROM_DATABASE=Payter BV
+
+OUI:B8E625*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:B8E779*
+ ID_OUI_FROM_DATABASE=9Solutions Oy
+
+OUI:B8E937*
+ ID_OUI_FROM_DATABASE=Sonos, Inc.
+
+OUI:B8EE79*
+ ID_OUI_FROM_DATABASE=YWire Technologies, Inc.
+
+OUI:B8F4D0*
+ ID_OUI_FROM_DATABASE=Herrmann Ultraschalltechnik GmbH & Co. Kg
+
+OUI:B8F5E7*
+ ID_OUI_FROM_DATABASE=WayTools, LLC
+
+OUI:B8F6B1*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B8F732*
+ ID_OUI_FROM_DATABASE=Aryaka Networks Inc
+
+OUI:B8F934*
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+OUI:B8FD32*
+ ID_OUI_FROM_DATABASE=Zhejiang ROICX Microelectronics
+
+OUI:B8FF61*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B8FF6F*
+ ID_OUI_FROM_DATABASE=Shanghai Typrotech Technology Co.Ltd
+
+OUI:B8FFFE*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:BC0200*
+ ID_OUI_FROM_DATABASE=Stewart Audio
+
+OUI:BC0543*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:BC0DA5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:BC0F2B*
+ ID_OUI_FROM_DATABASE=FORTUNE TECHGROUP CO.,LTD
+
+OUI:BC125E*
+ ID_OUI_FROM_DATABASE=Beijing  WisVideo  INC.
+
+OUI:BC1401*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:BC15A6*
+ ID_OUI_FROM_DATABASE=Taiwan Jantek Electronics,Ltd.
+
+OUI:BC20A4*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:BC20BA*
+ ID_OUI_FROM_DATABASE=Inspur (Shandong) Electronic Information Co., Ltd
+
+OUI:BC2846*
+ ID_OUI_FROM_DATABASE=NextBIT Computing Pvt. Ltd.
+
+OUI:BC28D6*
+ ID_OUI_FROM_DATABASE=Rowley Associates Limited
+
+OUI:BC2C55*
+ ID_OUI_FROM_DATABASE=Bear Flag Design, Inc.
+
+OUI:BC305B*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:BC35E5*
+ ID_OUI_FROM_DATABASE=Hydro Systems Company
+
+OUI:BC38D2*
+ ID_OUI_FROM_DATABASE=Pandachip Limited
+
+OUI:BC39A6*
+ ID_OUI_FROM_DATABASE=CSUN System Technology Co.,LTD
+
+OUI:BC3BAF*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:BC3E13*
+ ID_OUI_FROM_DATABASE=Accordance Systems Inc.
+
+OUI:BC4377*
+ ID_OUI_FROM_DATABASE=Hang Zhou Huite Technology Co.,ltd.
+
+OUI:BC4760*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:BC4B79*
+ ID_OUI_FROM_DATABASE=SensingTek
+
+OUI:BC4E3C*
+ ID_OUI_FROM_DATABASE=CORE STAFF CO., LTD.
+
+OUI:BC51FE*
+ ID_OUI_FROM_DATABASE=Swann Communications Pty Ltd
+
+OUI:BC52B7*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:BC5FF4*
+ ID_OUI_FROM_DATABASE=ASRock Incorporation
+
+OUI:BC629F*
+ ID_OUI_FROM_DATABASE=Telenet Systems P. Ltd.
+
+OUI:BC6778*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:BC6784*
+ ID_OUI_FROM_DATABASE=Environics Oy
+
+OUI:BC6A16*
+ ID_OUI_FROM_DATABASE=tdvine
+
+OUI:BC6A29*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:BC6E76*
+ ID_OUI_FROM_DATABASE=Green Energy Options Ltd
+
+OUI:BC71C1*
+ ID_OUI_FROM_DATABASE=XTrillion, Inc.
+
+OUI:BC764E*
+ ID_OUI_FROM_DATABASE=Rackspace US, Inc.
+
+OUI:BC7670*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:BC7737*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:BC779F*
+ ID_OUI_FROM_DATABASE=SBM Co., Ltd.
+
+OUI:BC7DD1*
+ ID_OUI_FROM_DATABASE=Radio Data Comms
+
+OUI:BC811F*
+ ID_OUI_FROM_DATABASE=Ingate Systems
+
+OUI:BC8199*
+ ID_OUI_FROM_DATABASE=BASIC Co.,Ltd.
+
+OUI:BC83A7*
+ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LT
+
+OUI:BC851F*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:BC8B55*
+ ID_OUI_FROM_DATABASE=NPP ELIKS America Inc. DBA T&M Atlantic
+
+OUI:BC99BC*
+ ID_OUI_FROM_DATABASE=FonSee Technology Inc.
+
+OUI:BC9DA5*
+ ID_OUI_FROM_DATABASE=DASCOM Europe GmbH
+
+OUI:BCA4E1*
+ ID_OUI_FROM_DATABASE=Nabto
+
+OUI:BCA9D6*
+ ID_OUI_FROM_DATABASE=Cyber-Rain, Inc.
+
+OUI:BCAEC5*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:BCB181*
+ ID_OUI_FROM_DATABASE=SHARP CORPORATION
+
+OUI:BCB1F3*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:BCB852*
+ ID_OUI_FROM_DATABASE=Cybera, Inc.
+
+OUI:BCBBC9*
+ ID_OUI_FROM_DATABASE=Kellendonk Elektronik GmbH
+
+OUI:BCC168*
+ ID_OUI_FROM_DATABASE=DInBox Sverige AB
+
+OUI:BCC23A*
+ ID_OUI_FROM_DATABASE=Thomson Video Networks
+
+OUI:BCC61A*
+ ID_OUI_FROM_DATABASE=SPECTRA EMBEDDED SYSTEMS
+
+OUI:BCC810*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:BCCD45*
+ ID_OUI_FROM_DATABASE=VOISMART
+
+OUI:BCCFCC*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:BCD5B6*
+ ID_OUI_FROM_DATABASE=d2d technologies
+
+OUI:BCD940*
+ ID_OUI_FROM_DATABASE=ASR Co,.Ltd.
+
+OUI:BCE09D*
+ ID_OUI_FROM_DATABASE=Eoslink
+
+OUI:BCE59F*
+ ID_OUI_FROM_DATABASE=WATERWORLD Technology Co.,LTD
+
+OUI:BCEA2B*
+ ID_OUI_FROM_DATABASE=CityCom GmbH
+
+OUI:BCF2AF*
+ ID_OUI_FROM_DATABASE=devolo AG
+
+OUI:BCF685*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:BCFE8C*
+ ID_OUI_FROM_DATABASE=Altronic, LLC
+
+OUI:BCFFAC*
+ ID_OUI_FROM_DATABASE=TOPCON CORPORATION
+
+OUI:C00D7E*
+ ID_OUI_FROM_DATABASE=Additech, Inc.
+
+OUI:C011A6*
+ ID_OUI_FROM_DATABASE=Fort-Telecom ltd.
+
+OUI:C01242*
+ ID_OUI_FROM_DATABASE=Alpha Security Products
+
+OUI:C0143D*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:C01885*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:C01E9B*
+ ID_OUI_FROM_DATABASE=Pixavi AS
+
+OUI:C02506*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:C027B9*
+ ID_OUI_FROM_DATABASE=Beijing National Railway Research & Design Institute  of Signal & Communication
+
+OUI:C02973*
+ ID_OUI_FROM_DATABASE=Audyssey Laboratories Inc.
+
+OUI:C029F3*
+ ID_OUI_FROM_DATABASE=XySystem
+
+OUI:C02BFC*
+ ID_OUI_FROM_DATABASE=iNES. applied informatics GmbH
+
+OUI:C02C7A*
+ ID_OUI_FROM_DATABASE=Shen Zhen Horn audio Co., Ltd.
+
+OUI:C035BD*
+ ID_OUI_FROM_DATABASE=Velocytech Aps
+
+OUI:C038F9*
+ ID_OUI_FROM_DATABASE=Nokia Danmark A/S
+
+OUI:C03B8F*
+ ID_OUI_FROM_DATABASE=Minicom Digital Signage
+
+OUI:C03F0E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C03F2A*
+ ID_OUI_FROM_DATABASE=Biscotti, Inc.
+
+OUI:C041F6*
+ ID_OUI_FROM_DATABASE=LG Electronics Inc
+
+OUI:C044E3*
+ ID_OUI_FROM_DATABASE=Shenzhen Sinkna Electronics Co., LTD
+
+OUI:C0493D*
+ ID_OUI_FROM_DATABASE=MAITRISE TECHNOLOGIQUE
+
+OUI:C04A00*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:C058A7*
+ ID_OUI_FROM_DATABASE=Pico Systems Co., Ltd.
+
+OUI:C05E6F*
+ ID_OUI_FROM_DATABASE=V. Stonkaus firma "Kodinis Raktas"
+
+OUI:C05E79*
+ ID_OUI_FROM_DATABASE=SHENZHEN HUAXUN ARK TECHNOLOGIES CO.,LTD
+
+OUI:C0626B*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:C06C0F*
+ ID_OUI_FROM_DATABASE=Dobbs Stanford
+
+OUI:C07E40*
+ ID_OUI_FROM_DATABASE=SHENZHEN XDK COMMUNICATION EQUIPMENT CO.,LTD
+
+OUI:C08170*
+ ID_OUI_FROM_DATABASE=Effigis GeoSolutions
+
+OUI:C0830A*
+ ID_OUI_FROM_DATABASE=2Wire
+
+OUI:C0847A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C08ADE*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C08B6F*
+ ID_OUI_FROM_DATABASE=S I Sistemas Inteligentes Eletrônicos Ltda
+
+OUI:C09132*
+ ID_OUI_FROM_DATABASE=Patriot Memory
+
+OUI:C09134*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:C09C92*
+ ID_OUI_FROM_DATABASE=COBY
+
+OUI:C09F42*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:C0A0C7*
+ ID_OUI_FROM_DATABASE=FAIRFIELD INDUSTRIES
+
+OUI:C0A0DE*
+ ID_OUI_FROM_DATABASE=Multi Touch Oy
+
+OUI:C0A0E2*
+ ID_OUI_FROM_DATABASE=Eden Innovations
+
+OUI:C0A26D*
+ ID_OUI_FROM_DATABASE=Abbott Point of Care
+
+OUI:C0A364*
+ ID_OUI_FROM_DATABASE=3D Systems Burlington
+
+OUI:C0AA68*
+ ID_OUI_FROM_DATABASE=OSASI Technos Inc.
+
+OUI:C0AC54*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:C0B339*
+ ID_OUI_FROM_DATABASE=Comigo Ltd.
+
+OUI:C0B357*
+ ID_OUI_FROM_DATABASE=Yoshiki Electronics Industry Ltd.
+
+OUI:C0B8B1*
+ ID_OUI_FROM_DATABASE=BitBox Ltd
+
+OUI:C0BAE6*
+ ID_OUI_FROM_DATABASE=Application Solutions (Safety and Security) Ltd
+
+OUI:C0BD42*
+ ID_OUI_FROM_DATABASE=ZPA Smart Energy a.s.
+
+OUI:C0C1C0*
+ ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC
+
+OUI:C0C520*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C0C946*
+ ID_OUI_FROM_DATABASE=MITSUYA LABORATORIES INC.
+
+OUI:C0CB38*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:C0CFA3*
+ ID_OUI_FROM_DATABASE=Creative Electronics & Software, Inc.
+
+OUI:C0D044*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:C0D962*
+ ID_OUI_FROM_DATABASE=Askey Computer Corp.
+
+OUI:C0DF77*
+ ID_OUI_FROM_DATABASE=Conrad Electronic SE
+
+OUI:C0E422*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C0E54E*
+ ID_OUI_FROM_DATABASE=DENX Computer Systems GmbH
+
+OUI:C0EAE4*
+ ID_OUI_FROM_DATABASE=Sonicwall
+
+OUI:C0F8DA*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:C40142*
+ ID_OUI_FROM_DATABASE=MaxMedia Technology Limited
+
+OUI:C4017C*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C401B1*
+ ID_OUI_FROM_DATABASE=SeekTech INC
+
+OUI:C40ACB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:C40F09*
+ ID_OUI_FROM_DATABASE=Hermes electronic GmbH
+
+OUI:C4108A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C416FA*
+ ID_OUI_FROM_DATABASE=Prysm Inc
+
+OUI:C417FE*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:C4198B*
+ ID_OUI_FROM_DATABASE=Dominion Voting Systems Corporation
+
+OUI:C41ECE*
+ ID_OUI_FROM_DATABASE=HMI Sources Ltd.
+
+OUI:C4237A*
+ ID_OUI_FROM_DATABASE=WhizNets Inc.
+
+OUI:C4242E*
+ ID_OUI_FROM_DATABASE=Galvanic Applied Sciences Inc
+
+OUI:C42C03*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C436DA*
+ ID_OUI_FROM_DATABASE=Rusteletech Ltd.
+
+OUI:C438D3*
+ ID_OUI_FROM_DATABASE=TAGATEC CO.,LTD
+
+OUI:C4393A*
+ ID_OUI_FROM_DATABASE=SMC Networks Inc
+
+OUI:C43A9F*
+ ID_OUI_FROM_DATABASE=Siconix Inc.
+
+OUI:C43C3C*
+ ID_OUI_FROM_DATABASE=CYBELEC SA
+
+OUI:C43DC7*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C44567*
+ ID_OUI_FROM_DATABASE=SAMBON PRECISON and ELECTRONICS
+
+OUI:C44619*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:C44AD0*
+ ID_OUI_FROM_DATABASE=FIREFLIES RTLS
+
+OUI:C44B44*
+ ID_OUI_FROM_DATABASE=Omniprint Inc.
+
+OUI:C44EAC*
+ ID_OUI_FROM_DATABASE=Shenzhen Shiningworth Technology Co., Ltd.
+
+OUI:C455A6*
+ ID_OUI_FROM_DATABASE=Cadac Holdings Ltd
+
+OUI:C455C2*
+ ID_OUI_FROM_DATABASE=Bach-Simpson
+
+OUI:C45600*
+ ID_OUI_FROM_DATABASE=Galleon Embedded Computing
+
+OUI:C458C2*
+ ID_OUI_FROM_DATABASE=Shenzhen TATFOOK Technology Co., Ltd.
+
+OUI:C45976*
+ ID_OUI_FROM_DATABASE=Fugoo
+
+OUI:C45DD8*
+ ID_OUI_FROM_DATABASE=HDMI Forum
+
+OUI:C46044*
+ ID_OUI_FROM_DATABASE=Everex Electronics Limited
+
+OUI:C46354*
+ ID_OUI_FROM_DATABASE=U-Raku, Inc.
+
+OUI:C46413*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:C467B5*
+ ID_OUI_FROM_DATABASE=Libratone A/S
+
+OUI:C46AB7*
+ ID_OUI_FROM_DATABASE=Xiaomi Technology,Inc.
+
+OUI:C46DF1*
+ ID_OUI_FROM_DATABASE=DataGravity
+
+OUI:C47130*
+ ID_OUI_FROM_DATABASE=Fon Technology S.L.
+
+OUI:C471FE*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:C4731E*
+ ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd
+
+OUI:C47B2F*
+ ID_OUI_FROM_DATABASE=Beijing JoinHope Image Technology Ltd.
+
+OUI:C47BA3*
+ ID_OUI_FROM_DATABASE=NAVIS Inc.
+
+OUI:C47D4F*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:C47DCC*
+ ID_OUI_FROM_DATABASE=Motorola Solutions Inc.
+
+OUI:C4823F*
+ ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co,.Ltd.
+
+OUI:C48508*
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+OUI:C488E5*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C49300*
+ ID_OUI_FROM_DATABASE=8Devices
+
+OUI:C49313*
+ ID_OUI_FROM_DATABASE=100fio networks technology llc
+
+OUI:C495A2*
+ ID_OUI_FROM_DATABASE=SHENZHEN WEIJIU INDUSTRY AND TRADE DEVELOPMENT CO., LTD
+
+OUI:C49805*
+ ID_OUI_FROM_DATABASE=Minieum Networks, Inc
+
+OUI:C4AAA1*
+ ID_OUI_FROM_DATABASE=SUMMIT DEVELOPMENT, spol.s r.o.
+
+OUI:C4AD21*
+ ID_OUI_FROM_DATABASE=MEDIAEDGE Corporation
+
+OUI:C4B512*
+ ID_OUI_FROM_DATABASE=General Electric Digital Energy
+
+OUI:C4BA99*
+ ID_OUI_FROM_DATABASE=I+ME Actia Informatik und Mikro-Elektronik GmbH
+
+OUI:C4C19F*
+ ID_OUI_FROM_DATABASE=National Oilwell Varco Instrumentation, Monitoring, and Optimization (NOV IMO)
+
+OUI:C4CAD9*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:C4CD45*
+ ID_OUI_FROM_DATABASE=Beijing Boomsense Technology CO.,LTD.
+
+OUI:C4D489*
+ ID_OUI_FROM_DATABASE=JiangSu Joyque Information Industry Co.,Ltd
+
+OUI:C4D987*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:C4DA26*
+ ID_OUI_FROM_DATABASE=NOBLEX SA
+
+OUI:C4E032*
+ ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group
+
+OUI:C4E17C*
+ ID_OUI_FROM_DATABASE=U2S co.
+
+OUI:C4E7BE*
+ ID_OUI_FROM_DATABASE=SCSpro Co.,Ltd
+
+OUI:C4EBE3*
+ ID_OUI_FROM_DATABASE=RRCN SAS
+
+OUI:C4EDBA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C4EEAE*
+ ID_OUI_FROM_DATABASE=VSS Monitoring
+
+OUI:C4EEF5*
+ ID_OUI_FROM_DATABASE=Oclaro, Inc.
+
+OUI:C4F464*
+ ID_OUI_FROM_DATABASE=Spica international
+
+OUI:C4F57C*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:C4FCE4*
+ ID_OUI_FROM_DATABASE=DishTV NZ Ltd
+
+OUI:C802A6*
+ ID_OUI_FROM_DATABASE=Beijing Newmine Technology
+
+OUI:C80718*
+ ID_OUI_FROM_DATABASE=TDSi
+
+OUI:C80AA9*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc.
+
+OUI:C80E77*
+ ID_OUI_FROM_DATABASE=Le Shi Zhi Xin Electronic Technology (Tianjin)  Co.,Ltd
+
+OUI:C80E95*
+ ID_OUI_FROM_DATABASE=OmniLync Inc.
+
+OUI:C819F7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C81AFE*
+ ID_OUI_FROM_DATABASE=DLOGIC GmbH
+
+OUI:C81E8E*
+ ID_OUI_FROM_DATABASE=ADV Security (S) Pte Ltd
+
+OUI:C8208E*
+ ID_OUI_FROM_DATABASE=Storagedata
+
+OUI:C8292A*
+ ID_OUI_FROM_DATABASE=Barun Electronics
+
+OUI:C82A14*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:C82E94*
+ ID_OUI_FROM_DATABASE=Halfa Enterprise Co., Ltd.
+
+OUI:C83232*
+ ID_OUI_FROM_DATABASE=Hunting Innova
+
+OUI:C8334B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C835B8*
+ ID_OUI_FROM_DATABASE=Ericsson, EAB/RWI/K
+
+OUI:C83A35*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co., Ltd.
+
+OUI:C83B45*
+ ID_OUI_FROM_DATABASE=JRI-Maxant
+
+OUI:C83D97*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:C83E99*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C83EA7*
+ ID_OUI_FROM_DATABASE=KUNBUS GmbH
+
+OUI:C84529*
+ ID_OUI_FROM_DATABASE=IMK Networks Co.,Ltd
+
+OUI:C84544*
+ ID_OUI_FROM_DATABASE=Shanghai Enlogic Electric Technology Co., Ltd.
+
+OUI:C848F5*
+ ID_OUI_FROM_DATABASE=MEDISON Xray Co., Ltd
+
+OUI:C84C75*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:C85645*
+ ID_OUI_FROM_DATABASE=Intermas France
+
+OUI:C86000*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:C864C7*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:C86C1E*
+ ID_OUI_FROM_DATABASE=Display Systems Ltd
+
+OUI:C86C87*
+ ID_OUI_FROM_DATABASE=Zyxel Communications Corp
+
+OUI:C86CB6*
+ ID_OUI_FROM_DATABASE=Optcom Co., Ltd.
+
+OUI:C86F1D*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:C87248*
+ ID_OUI_FROM_DATABASE=Aplicom Oy
+
+OUI:C87B5B*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:C87CBC*
+ ID_OUI_FROM_DATABASE=Valink Co., Ltd.
+
+OUI:C87D77*
+ ID_OUI_FROM_DATABASE=Shenzhen Kingtech Communication Equipment Co.,Ltd
+
+OUI:C87E75*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C88439*
+ ID_OUI_FROM_DATABASE=Sunrise Technologies
+
+OUI:C88447*
+ ID_OUI_FROM_DATABASE=Beautiful Enterprise Co., Ltd
+
+OUI:C8873B*
+ ID_OUI_FROM_DATABASE=Net Optics
+
+OUI:C88A83*
+ ID_OUI_FROM_DATABASE=Dongguan HuaHong Electronics Co.,Ltd
+
+OUI:C88B47*
+ ID_OUI_FROM_DATABASE=Nolangroup S.P.A con Socio Unico
+
+OUI:C8903E*
+ ID_OUI_FROM_DATABASE=Pakton Technologies
+
+OUI:C89383*
+ ID_OUI_FROM_DATABASE=Embedded Automation, Inc.
+
+OUI:C894D2*
+ ID_OUI_FROM_DATABASE=Jiangsu Datang  Electronic Products Co., Ltd
+
+OUI:C8979F*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:C89C1D*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:C89CDC*
+ ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD.
+
+OUI:C89F42*
+ ID_OUI_FROM_DATABASE=VDII Innovation AB
+
+OUI:C8A030*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C8A1B6*
+ ID_OUI_FROM_DATABASE=Shenzhen Longway Technologies Co., Ltd
+
+OUI:C8A1BA*
+ ID_OUI_FROM_DATABASE=Neul Ltd
+
+OUI:C8A620*
+ ID_OUI_FROM_DATABASE=Nebula, Inc
+
+OUI:C8A70A*
+ ID_OUI_FROM_DATABASE=Verizon Business
+
+OUI:C8A729*
+ ID_OUI_FROM_DATABASE=SYStronics Co., Ltd.
+
+OUI:C8AA21*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:C8AE9C*
+ ID_OUI_FROM_DATABASE=Shanghai TYD Elecronic Technology Co. Ltd
+
+OUI:C8AF40*
+ ID_OUI_FROM_DATABASE=marco Systemanalyse und Entwicklung GmbH
+
+OUI:C8BBD3*
+ ID_OUI_FROM_DATABASE=Embrane
+
+OUI:C8BCC8*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C8BE19*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:C8C126*
+ ID_OUI_FROM_DATABASE=ZPM Industria e Comercio Ltda
+
+OUI:C8C13C*
+ ID_OUI_FROM_DATABASE=RuggedTek Hangzhou Co., Ltd
+
+OUI:C8C791*
+ ID_OUI_FROM_DATABASE=Zero1.tv GmbH
+
+OUI:C8CBB8*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:C8CD72*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:C8D15E*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:C8D1D1*
+ ID_OUI_FROM_DATABASE=AGAiT Technology Corporation
+
+OUI:C8D2C1*
+ ID_OUI_FROM_DATABASE=Jetlun (Shenzhen) Corporation
+
+OUI:C8D3A3*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:C8D5FE*
+ ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd
+
+OUI:C8D719*
+ ID_OUI_FROM_DATABASE=Cisco Consumer Products, LLC
+
+OUI:C8DE51*
+ ID_OUI_FROM_DATABASE=Integra Networks, Inc.
+
+OUI:C8DF7C*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:C8E1A7*
+ ID_OUI_FROM_DATABASE=Vertu Corporation Limited
+
+OUI:C8EE08*
+ ID_OUI_FROM_DATABASE=TANGTOP TECHNOLOGY CO.,LTD
+
+OUI:C8EF2E*
+ ID_OUI_FROM_DATABASE=Beijing Gefei Tech. Co., Ltd
+
+OUI:C8F406*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:C8F704*
+ ID_OUI_FROM_DATABASE=Building Block Video
+
+OUI:C8F733*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:C8F981*
+ ID_OUI_FROM_DATABASE=Seneca s.r.l.
+
+OUI:C8F9F9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:C8FB26*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:C8FE30*
+ ID_OUI_FROM_DATABASE=Bejing DAYO Mobile Communication Technology Ltd.
+
+OUI:CC0080*
+ ID_OUI_FROM_DATABASE=TRUST SYSTEM Co.,
+
+OUI:CC047C*
+ ID_OUI_FROM_DATABASE=G-WAY Microwave
+
+OUI:CC051B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:CC08E0*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:CC09C8*
+ ID_OUI_FROM_DATABASE=IMAQLIQ LTD
+
+OUI:CC0CDA*
+ ID_OUI_FROM_DATABASE=Miljovakt AS
+
+OUI:CC14A6*
+ ID_OUI_FROM_DATABASE=Yichun MyEnergy Domain, Inc
+
+OUI:CC187B*
+ ID_OUI_FROM_DATABASE=Manzanita Systems, Inc.
+
+OUI:CC1EFF*
+ ID_OUI_FROM_DATABASE=Metrological Group BV
+
+OUI:CC2218*
+ ID_OUI_FROM_DATABASE=InnoDigital Co., Ltd.
+
+OUI:CC262D*
+ ID_OUI_FROM_DATABASE=Verifi, LLC
+
+OUI:CC2D8C*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
+
+OUI:CC34D7*
+ ID_OUI_FROM_DATABASE=GEWISS S.P.A.
+
+OUI:CC3A61*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD.
+
+OUI:CC3E5F*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:CC43E3*
+ ID_OUI_FROM_DATABASE=Trump s.a.
+
+OUI:CC4BFB*
+ ID_OUI_FROM_DATABASE=Hellberg Safety AB
+
+OUI:CC4E24*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:CC501C*
+ ID_OUI_FROM_DATABASE=KVH Industries, Inc.
+
+OUI:CC5076*
+ ID_OUI_FROM_DATABASE=Ocom Communications, Inc.
+
+OUI:CC52AF*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:CC53B5*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:CC5459*
+ ID_OUI_FROM_DATABASE=OnTime Networks AS
+
+OUI:CC55AD*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:CC593E*
+ ID_OUI_FROM_DATABASE=TOUMAZ LTD
+
+OUI:CC5C75*
+ ID_OUI_FROM_DATABASE=Weightech Com. Imp. Exp. Equip. Pesagem Ltda
+
+OUI:CC5D4E*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:CC60BB*
+ ID_OUI_FROM_DATABASE=Empower RF Systems
+
+OUI:CC69B0*
+ ID_OUI_FROM_DATABASE=Global Traffic Technologies, LLC
+
+OUI:CC6B98*
+ ID_OUI_FROM_DATABASE=Minetec Wireless Technologies
+
+OUI:CC6BF1*
+ ID_OUI_FROM_DATABASE=Sound Masking Inc.
+
+OUI:CC6DA0*
+ ID_OUI_FROM_DATABASE=Roku, Inc.
+
+OUI:CC6DEF*
+ ID_OUI_FROM_DATABASE=TJK Tietolaite Oy
+
+OUI:CC7669*
+ ID_OUI_FROM_DATABASE=SEETECH
+
+OUI:CC785F*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:CC7A30*
+ ID_OUI_FROM_DATABASE=CMAX Wireless Co., Ltd.
+
+OUI:CC7D37*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:CC7EE7*
+ ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
+
+OUI:CC8CE3*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:CC9093*
+ ID_OUI_FROM_DATABASE=Hansong Tehnologies
+
+OUI:CC912B*
+ ID_OUI_FROM_DATABASE=TE Connectivity Touch Solutions
+
+OUI:CC944A*
+ ID_OUI_FROM_DATABASE=Pfeiffer Vacuum GmbH
+
+OUI:CC96A0*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:CC9E00*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:CCA374*
+ ID_OUI_FROM_DATABASE=Guangdong Guanglian Electronic Technology Co.Ltd
+
+OUI:CCA462*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc
+
+OUI:CCAF78*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:CCB255*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:CCB3F8*
+ ID_OUI_FROM_DATABASE=FUJITSU ISOTEC LIMITED
+
+OUI:CCB55A*
+ ID_OUI_FROM_DATABASE=Fraunhofer ITWM
+
+OUI:CCB888*
+ ID_OUI_FROM_DATABASE=AnB Securite s.a.
+
+OUI:CCB8F1*
+ ID_OUI_FROM_DATABASE=EAGLE KINGDOM TECHNOLOGIES LIMITED
+
+OUI:CCBE71*
+ ID_OUI_FROM_DATABASE=OptiLogix BV
+
+OUI:CCC104*
+ ID_OUI_FROM_DATABASE=Applied Technical Systems
+
+OUI:CCC50A*
+ ID_OUI_FROM_DATABASE=SHENZHEN DAJIAHAO TECHNOLOGY CO.,LTD
+
+OUI:CCC62B*
+ ID_OUI_FROM_DATABASE=Tri-Systems Corporation
+
+OUI:CCC8D7*
+ ID_OUI_FROM_DATABASE=CIAS Elettronica srl
+
+OUI:CCCC4E*
+ ID_OUI_FROM_DATABASE=Sun Fountainhead USA. Corp
+
+OUI:CCCC81*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:CCCD64*
+ ID_OUI_FROM_DATABASE=SM-Electronic GmbH
+
+OUI:CCCE40*
+ ID_OUI_FROM_DATABASE=Janteq Corp
+
+OUI:CCD539*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:CCD811*
+ ID_OUI_FROM_DATABASE=Aiconn Technology Corporation
+
+OUI:CCD9E9*
+ ID_OUI_FROM_DATABASE=SCR Engineers Ltd.
+
+OUI:CCE798*
+ ID_OUI_FROM_DATABASE=My Social Stuff
+
+OUI:CCE7DF*
+ ID_OUI_FROM_DATABASE=American Magnetics, Inc.
+
+OUI:CCEA1C*
+ ID_OUI_FROM_DATABASE=DCONWORKS  Co., Ltd
+
+OUI:CCEED9*
+ ID_OUI_FROM_DATABASE=Deto Mechatronic GmbH
+
+OUI:CCEF48*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:CCF3A5*
+ ID_OUI_FROM_DATABASE=Chi Mei Communication Systems, Inc
+
+OUI:CCF67A*
+ ID_OUI_FROM_DATABASE=Ayecka Communication Systems LTD
+
+OUI:CCF841*
+ ID_OUI_FROM_DATABASE=Lumewave
+
+OUI:CCF8F0*
+ ID_OUI_FROM_DATABASE=Xi'an HISU Multimedia Technology Co.,Ltd.
+
+OUI:CCF954*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:CCF9E8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:CCFC6D*
+ ID_OUI_FROM_DATABASE=RIZ TRANSMITTERS
+
+OUI:CCFCB1*
+ ID_OUI_FROM_DATABASE=Wireless Technology, Inc.
+
+OUI:CCFE3C*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:D00790*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D0131E*
+ ID_OUI_FROM_DATABASE=Sunrex Technology Corp
+
+OUI:D0154A*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:D0176A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D01AA7*
+ ID_OUI_FROM_DATABASE=UniPrint
+
+OUI:D01CBB*
+ ID_OUI_FROM_DATABASE=Beijing Ctimes Digital Technology Co., Ltd.
+
+OUI:D023DB*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:D02788*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd
+
+OUI:D03110*
+ ID_OUI_FROM_DATABASE=Ingenic Semiconductor Co.,Ltd
+
+OUI:D03761*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D046DC*
+ ID_OUI_FROM_DATABASE=Southwest Research Institute
+
+OUI:D04CC1*
+ ID_OUI_FROM_DATABASE=SINTRONES Technology Corp.
+
+OUI:D05162*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
+OUI:D052A8*
+ ID_OUI_FROM_DATABASE=Physical Graph Corporation
+
+OUI:D0542D*
+ ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
+
+OUI:D0574C*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:D05785*
+ ID_OUI_FROM_DATABASE=Pantech Co., Ltd.
+
+OUI:D05875*
+ ID_OUI_FROM_DATABASE=Active Control Technology Inc.
+
+OUI:D059C3*
+ ID_OUI_FROM_DATABASE=CeraMicro Technology Corporation
+
+OUI:D05A0F*
+ ID_OUI_FROM_DATABASE=I-BT DIGITAL CO.,LTD
+
+OUI:D05FCE*
+ ID_OUI_FROM_DATABASE=Hitachi Data Systems
+
+OUI:D063B4*
+ ID_OUI_FROM_DATABASE=SolidRun Ltd.
+
+OUI:D0667B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
+
+OUI:D067E5*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:D0699E*
+ ID_OUI_FROM_DATABASE=LUMINEX Lighting Control Equipment
+
+OUI:D0738E*
+ ID_OUI_FROM_DATABASE=DONG OH PRECISION CO., LTD.
+
+OUI:D075BE*
+ ID_OUI_FROM_DATABASE=Reno A&E
+
+OUI:D07DE5*
+ ID_OUI_FROM_DATABASE=Forward Pay Systems, Inc.
+
+OUI:D07E28*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:D08999*
+ ID_OUI_FROM_DATABASE=APCON, Inc.
+
+OUI:D08B7E*
+ ID_OUI_FROM_DATABASE=Passif Semiconductor
+
+OUI:D08CB5*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D08CFF*
+ ID_OUI_FROM_DATABASE=UPWIS AB
+
+OUI:D093F8*
+ ID_OUI_FROM_DATABASE=Stonestreet One LLC
+
+OUI:D09B05*
+ ID_OUI_FROM_DATABASE=Emtronix
+
+OUI:D0A311*
+ ID_OUI_FROM_DATABASE=Neuberger Gebäudeautomation GmbH
+
+OUI:D0AEEC*
+ ID_OUI_FROM_DATABASE=Alpha Networks Inc.
+
+OUI:D0AFB6*
+ ID_OUI_FROM_DATABASE=Linktop Technology Co., LTD
+
+OUI:D0B33F*
+ ID_OUI_FROM_DATABASE=SHENZHEN TINNO MOBILE TECHNOLOGY CO.,LTD.
+
+OUI:D0B498*
+ ID_OUI_FROM_DATABASE=Robert Bosch LLC Automotive Electronics
+
+OUI:D0B53D*
+ ID_OUI_FROM_DATABASE=SEPRO ROBOTIQUE
+
+OUI:D0BB80*
+ ID_OUI_FROM_DATABASE=SHL Telemedicine International Ltd.
+
+OUI:D0C1B1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D0C282*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:D0CDE1*
+ ID_OUI_FROM_DATABASE=Scientech Electronics
+
+OUI:D0CF5E*
+ ID_OUI_FROM_DATABASE=Energy Micro AS
+
+OUI:D0D0FD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:D0D212*
+ ID_OUI_FROM_DATABASE=K2NET Co.,Ltd.
+
+OUI:D0D286*
+ ID_OUI_FROM_DATABASE=Beckman Coulter Biomedical K.K.
+
+OUI:D0D3FC*
+ ID_OUI_FROM_DATABASE=Mios, Ltd.
+
+OUI:D0D6CC*
+ ID_OUI_FROM_DATABASE=Wintop
+
+OUI:D0DB32*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:D0DF9A*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:D0DFB2*
+ ID_OUI_FROM_DATABASE=Genie Networks Limited
+
+OUI:D0DFC7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D0E347*
+ ID_OUI_FROM_DATABASE=Yoga
+
+OUI:D0E40B*
+ ID_OUI_FROM_DATABASE=Wearable Inc.
+
+OUI:D0E54D*
+ ID_OUI_FROM_DATABASE=Pace plc
+
+OUI:D0E782*
+ ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc.
+
+OUI:D0EB9E*
+ ID_OUI_FROM_DATABASE=Seowoo Inc.
+
+OUI:D0F0DB*
+ ID_OUI_FROM_DATABASE=Ericsson
+
+OUI:D0F73B*
+ ID_OUI_FROM_DATABASE=Helmut Mauell GmbH
+
+OUI:D4000D*
+ ID_OUI_FROM_DATABASE=Phoenix Broadband Technologies, LLC.
+
+OUI:D40057*
+ ID_OUI_FROM_DATABASE=MC Technologies GmbH
+
+OUI:D4024A*
+ ID_OUI_FROM_DATABASE=Delphian Systems LLC
+
+OUI:D40FB2*
+ ID_OUI_FROM_DATABASE=Applied Micro Electronics AME bv
+
+OUI:D410CF*
+ ID_OUI_FROM_DATABASE=Huanshun Network Science and Technology Co., Ltd.
+
+OUI:D411D6*
+ ID_OUI_FROM_DATABASE=ShotSpotter, Inc.
+
+OUI:D41296*
+ ID_OUI_FROM_DATABASE=Anobit Technologies Ltd.
+
+OUI:D412BB*
+ ID_OUI_FROM_DATABASE=Quadrant Components Inc. Ltd
+
+OUI:D4136F*
+ ID_OUI_FROM_DATABASE=Asia Pacific Brands
+
+OUI:D41C1C*
+ ID_OUI_FROM_DATABASE=RCF S.P.A.
+
+OUI:D41E35*
+ ID_OUI_FROM_DATABASE=TOHO Electronics INC.
+
+OUI:D41F0C*
+ ID_OUI_FROM_DATABASE=TVI Vision Oy
+
+OUI:D4206D*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:D4223F*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
+OUI:D42751*
+ ID_OUI_FROM_DATABASE=Infopia Co., Ltd
+
+OUI:D428B2*
+ ID_OUI_FROM_DATABASE=ioBridge, Inc.
+
+OUI:D429EA*
+ ID_OUI_FROM_DATABASE=Zimory GmbH
+
+OUI:D42C3D*
+ ID_OUI_FROM_DATABASE=Sky Light Digital Limited
+
+OUI:D43AE9*
+ ID_OUI_FROM_DATABASE=DONGGUAN ipt INDUSTRIAL CO., LTD
+
+OUI:D43D67*
+ ID_OUI_FROM_DATABASE=Carma Industries Inc.
+
+OUI:D43D7E*
+ ID_OUI_FROM_DATABASE=Micro-Star Int'l Co, Ltd
+
+OUI:D443A8*
+ ID_OUI_FROM_DATABASE=Changzhou Haojie Electric Co., Ltd.
+
+OUI:D44B5E*
+ ID_OUI_FROM_DATABASE=TAIYO YUDEN CO., LTD.
+
+OUI:D44C24*
+ ID_OUI_FROM_DATABASE=Vuppalamritha Magnetic Components LTD
+
+OUI:D44CA7*
+ ID_OUI_FROM_DATABASE=Informtekhnika & Communication, LLC
+
+OUI:D44F80*
+ ID_OUI_FROM_DATABASE=Kemper Digital GmbH
+
+OUI:D4507A*
+ ID_OUI_FROM_DATABASE=CEIVA Logic, Inc
+
+OUI:D45251*
+ ID_OUI_FROM_DATABASE=IBT Ingenieurbureau Broennimann Thun
+
+OUI:D45297*
+ ID_OUI_FROM_DATABASE=nSTREAMS Technologies, Inc.
+
+OUI:D453AF*
+ ID_OUI_FROM_DATABASE=VIGO System S.A.
+
+OUI:D45AB2*
+ ID_OUI_FROM_DATABASE=Galleon Systems
+
+OUI:D45C70*
+ ID_OUI_FROM_DATABASE=Wireless Gigabit Alliance
+
+OUI:D45D42*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:D466A8*
+ ID_OUI_FROM_DATABASE=Riedo Networks GmbH
+
+OUI:D46CBF*
+ ID_OUI_FROM_DATABASE=Goodrich ISR
+
+OUI:D46CDA*
+ ID_OUI_FROM_DATABASE=CSM GmbH
+
+OUI:D46F42*
+ ID_OUI_FROM_DATABASE=WAXESS USA Inc
+
+OUI:D479C3*
+ ID_OUI_FROM_DATABASE=Cameronet GmbH & Co. KG
+
+OUI:D47B75*
+ ID_OUI_FROM_DATABASE=HARTING Electronics GmbH & Co. KG
+
+OUI:D4823E*
+ ID_OUI_FROM_DATABASE=Argosy Technologies, Ltd.
+
+OUI:D48564*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:D487D8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:D48890*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D48CB5*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:D48FAA*
+ ID_OUI_FROM_DATABASE=Sogecam Industrial, S.A.
+
+OUI:D491AF*
+ ID_OUI_FROM_DATABASE=Electroacustica General Iberica, S.A.
+
+OUI:D493A0*
+ ID_OUI_FROM_DATABASE=Fidelix Oy
+
+OUI:D4945A*
+ ID_OUI_FROM_DATABASE=COSMO CO., LTD
+
+OUI:D494A1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D496DF*
+ ID_OUI_FROM_DATABASE=SUNGJIN C&T CO.,LTD
+
+OUI:D49A20*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:D49C28*
+ ID_OUI_FROM_DATABASE=JayBird Gear LLC
+
+OUI:D49C8E*
+ ID_OUI_FROM_DATABASE=University of FUKUI
+
+OUI:D49E6D*
+ ID_OUI_FROM_DATABASE=Wuhan Zhongyuan Huadian Science & Technology Co.,
+
+OUI:D4A02A*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:D4A425*
+ ID_OUI_FROM_DATABASE=SMAX Technology Co., Ltd.
+
+OUI:D4A928*
+ ID_OUI_FROM_DATABASE=GreenWave Reality Inc
+
+OUI:D4AAFF*
+ ID_OUI_FROM_DATABASE=MICRO WORLD
+
+OUI:D4AE52*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:D4BED9*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:D4BF2D*
+ ID_OUI_FROM_DATABASE=SE Controls Asia Pacific Ltd
+
+OUI:D4C1FC*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:D4C766*
+ ID_OUI_FROM_DATABASE=Acentic GmbH
+
+OUI:D4CA6D*
+ ID_OUI_FROM_DATABASE=Routerboard.com
+
+OUI:D4CA6E*
+ ID_OUI_FROM_DATABASE=u-blox AG
+
+OUI:D4CBAF*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:D4CEB8*
+ ID_OUI_FROM_DATABASE=Enatel LTD
+
+OUI:D4D184*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:D4D249*
+ ID_OUI_FROM_DATABASE=Power Ethernet
+
+OUI:D4D748*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:D4D898*
+ ID_OUI_FROM_DATABASE=Korea CNO Tech Co., Ltd
+
+OUI:D4DF57*
+ ID_OUI_FROM_DATABASE=Alpinion Medical Systems
+
+OUI:D4E32C*
+ ID_OUI_FROM_DATABASE=S. Siedle & Sohne
+
+OUI:D4E33F*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:D4E8B2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:D4EA0E*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:D4EC0C*
+ ID_OUI_FROM_DATABASE=Harley-Davidson Motor Company
+
+OUI:D4EE07*
+ ID_OUI_FROM_DATABASE=HIWIFI Co., Ltd.
+
+OUI:D4F027*
+ ID_OUI_FROM_DATABASE=Navetas Energy Management
+
+OUI:D4F0B4*
+ ID_OUI_FROM_DATABASE=Napco Security Technologies
+
+OUI:D4F143*
+ ID_OUI_FROM_DATABASE=IPROAD.,Inc
+
+OUI:D4F63F*
+ ID_OUI_FROM_DATABASE=IEA S.R.L.
+
+OUI:D8004D*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:D8052E*
+ ID_OUI_FROM_DATABASE=Skyviia Corporation
+
+OUI:D806D1*
+ ID_OUI_FROM_DATABASE=Honeywell Fire System (Shanghai) Co,. Ltd.
+
+OUI:D808F5*
+ ID_OUI_FROM_DATABASE=Arcadia Networks Co. Ltd.
+
+OUI:D809C3*
+ ID_OUI_FROM_DATABASE=Cercacor Labs
+
+OUI:D80DE3*
+ ID_OUI_FROM_DATABASE=FXI TECHNOLOGIES AS
+
+OUI:D8160A*
+ ID_OUI_FROM_DATABASE=Nippon Electro-Sensory Devices
+
+OUI:D8182B*
+ ID_OUI_FROM_DATABASE=Conti Temic Microelectronic GmbH
+
+OUI:D819CE*
+ ID_OUI_FROM_DATABASE=Telesquare
+
+OUI:D81BFE*
+ ID_OUI_FROM_DATABASE=TWINLINX CORPORATION
+
+OUI:D81C14*
+ ID_OUI_FROM_DATABASE=Compacta International, Ltd.
+
+OUI:D824BD*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:D826B9*
+ ID_OUI_FROM_DATABASE=Guangdong Coagent Electronics S &T Co., Ltd.
+
+OUI:D828C9*
+ ID_OUI_FROM_DATABASE=General Electric Consumer and Industrial
+
+OUI:D82986*
+ ID_OUI_FROM_DATABASE=Best Wish Technology LTD
+
+OUI:D82A7E*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:D82DE1*
+ ID_OUI_FROM_DATABASE=Tricascade Inc.
+
+OUI:D83062*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:D831CF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D8337F*
+ ID_OUI_FROM_DATABASE=Office FA.com Co.,Ltd.
+
+OUI:D842AC*
+ ID_OUI_FROM_DATABASE=FreeComm Data Communication Co.,Ltd.
+
+OUI:D84606*
+ ID_OUI_FROM_DATABASE=Silicon Valley Global Marketing
+
+OUI:D84B2A*
+ ID_OUI_FROM_DATABASE=Cognitas Technologies, Inc.
+
+OUI:D8543A*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D857EF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:D85D4C*
+ ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd.
+
+OUI:D85D84*
+ ID_OUI_FROM_DATABASE=CAx soft GmbH
+
+OUI:D867D9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:D86BF7*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:D86CE9*
+ ID_OUI_FROM_DATABASE=SAGEMCOM SAS
+
+OUI:D87157*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
+OUI:D87533*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:D8760A*
+ ID_OUI_FROM_DATABASE=Escort, Inc.
+
+OUI:D878E5*
+ ID_OUI_FROM_DATABASE=KUHN SA
+
+OUI:D87988*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:D88A3B*
+ ID_OUI_FROM_DATABASE=UNIT-EM
+
+OUI:D8952F*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:D89685*
+ ID_OUI_FROM_DATABASE=GoPro
+
+OUI:D8973B*
+ ID_OUI_FROM_DATABASE=Emerson Network Power Embedded Power
+
+OUI:D89760*
+ ID_OUI_FROM_DATABASE=C2 Development, Inc.
+
+OUI:D89D67*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:D89DB9*
+ ID_OUI_FROM_DATABASE=eMegatech International Corp.
+
+OUI:D89E3F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:D8A25E*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:D8AE90*
+ ID_OUI_FROM_DATABASE=Itibia Technologies
+
+OUI:D8AF3B*
+ ID_OUI_FROM_DATABASE=Hangzhou Bigbright Integrated communications system Co.,Ltd
+
+OUI:D8AFF1*
+ ID_OUI_FROM_DATABASE=Panasonic Appliances Company
+
+OUI:D8B12A*
+ ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co., Ltd.
+
+OUI:D8B377*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:D8B6C1*
+ ID_OUI_FROM_DATABASE=NetworkAccountant, Inc.
+
+OUI:D8B8F6*
+ ID_OUI_FROM_DATABASE=Nantworks
+
+OUI:D8B90E*
+ ID_OUI_FROM_DATABASE=Triple Domain Vision Co.,Ltd.
+
+OUI:D8BF4C*
+ ID_OUI_FROM_DATABASE=Victory Concept Electronics Limited
+
+OUI:D8C068*
+ ID_OUI_FROM_DATABASE=Netgenetech.co.,ltd.
+
+OUI:D8C3FB*
+ ID_OUI_FROM_DATABASE=DETRACOM
+
+OUI:D8C691*
+ ID_OUI_FROM_DATABASE=Hichan Technology Corp.
+
+OUI:D8C7C8*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
+OUI:D8C99D*
+ ID_OUI_FROM_DATABASE=EA DISPLAY LIMITED
+
+OUI:D8D1CB*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:D8D27C*
+ ID_OUI_FROM_DATABASE=JEMA ENERGY, SA
+
+OUI:D8D385*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:D8D5B9*
+ ID_OUI_FROM_DATABASE=Rainforest Automation, Inc.
+
+OUI:D8D67E*
+ ID_OUI_FROM_DATABASE=GSK CNC EQUIPMENT CO.,LTD
+
+OUI:D8DF0D*
+ ID_OUI_FROM_DATABASE=beroNet GmbH
+
+OUI:D8E3AE*
+ ID_OUI_FROM_DATABASE=CIRTEC MEDICAL SYSTEMS
+
+OUI:D8E72B*
+ ID_OUI_FROM_DATABASE=OnPATH Technologies
+
+OUI:D8E743*
+ ID_OUI_FROM_DATABASE=Wush, Inc
+
+OUI:D8E952*
+ ID_OUI_FROM_DATABASE=KEOPSYS
+
+OUI:D8EB97*
+ ID_OUI_FROM_DATABASE=TRENDnet, Inc.
+
+OUI:D8F0F2*
+ ID_OUI_FROM_DATABASE=Zeebo Inc
+
+OUI:D8FE8F*
+ ID_OUI_FROM_DATABASE=IDFone Co., Ltd.
+
+OUI:DC0265*
+ ID_OUI_FROM_DATABASE=Meditech Kft
+
+OUI:DC028E*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:DC05ED*
+ ID_OUI_FROM_DATABASE=Nabtesco  Corporation
+
+OUI:DC07C1*
+ ID_OUI_FROM_DATABASE=HangZhou QiYang Technology Co.,Ltd.
+
+OUI:DC0B1A*
+ ID_OUI_FROM_DATABASE=ADB Broadband SpA
+
+OUI:DC0EA1*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD
+
+OUI:DC16A2*
+ ID_OUI_FROM_DATABASE=Medtronic Diabetes
+
+OUI:DC175A*
+ ID_OUI_FROM_DATABASE=Hitachi High-Technologies Corporation
+
+OUI:DC1D9F*
+ ID_OUI_FROM_DATABASE=U & B tech
+
+OUI:DC1EA3*
+ ID_OUI_FROM_DATABASE=Accensus LLC
+
+OUI:DC2008*
+ ID_OUI_FROM_DATABASE=ASD Electronics Ltd
+
+OUI:DC2A14*
+ ID_OUI_FROM_DATABASE=Shanghai Longjing Technology Co.
+
+OUI:DC2B61*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:DC2B66*
+ ID_OUI_FROM_DATABASE=Infoblock
+
+OUI:DC2C26*
+ ID_OUI_FROM_DATABASE=Iton Technology Limited
+
+OUI:DC2E6A*
+ ID_OUI_FROM_DATABASE=HCT. Co., Ltd.
+
+OUI:DC309C*
+ ID_OUI_FROM_DATABASE=SAY Systems Limited
+
+OUI:DC3350*
+ ID_OUI_FROM_DATABASE=TechSAT GmbH
+
+OUI:DC37D2*
+ ID_OUI_FROM_DATABASE=Hunan HKT Electronic Technology Co., Ltd
+
+OUI:DC3A5E*
+ ID_OUI_FROM_DATABASE=Roku, Inc
+
+OUI:DC3C2E*
+ ID_OUI_FROM_DATABASE=Manufacturing System Insights, Inc.
+
+OUI:DC3C84*
+ ID_OUI_FROM_DATABASE=Ticom Geomatics, Inc.
+
+OUI:DC3E51*
+ ID_OUI_FROM_DATABASE=Solberg & Andersen AS
+
+OUI:DC4517*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:DC49C9*
+ ID_OUI_FROM_DATABASE=CASCO SIGNAL LTD
+
+OUI:DC4EDE*
+ ID_OUI_FROM_DATABASE=SHINYEI TECHNOLOGY CO., LTD.
+
+OUI:DC6F08*
+ ID_OUI_FROM_DATABASE=Bay Storage Technology
+
+OUI:DC7144*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
+
+OUI:DC7B94*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:DC85DE*
+ ID_OUI_FROM_DATABASE=Azurewave Technologies., inc.
+
+OUI:DC9B1E*
+ ID_OUI_FROM_DATABASE=Intercom, Inc.
+
+OUI:DC9C52*
+ ID_OUI_FROM_DATABASE=Sapphire Technology Limited.
+
+OUI:DC9FA4*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:DC9FDB*
+ ID_OUI_FROM_DATABASE=Ubiquiti Networks, Inc.
+
+OUI:DCA6BD*
+ ID_OUI_FROM_DATABASE=Beijing Lanbo Technology Co., Ltd.
+
+OUI:DCA7D9*
+ ID_OUI_FROM_DATABASE=Compressor Controls Corp
+
+OUI:DCA8CF*
+ ID_OUI_FROM_DATABASE=New Spin Golf, LLC.
+
+OUI:DCA971*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:DCA989*
+ ID_OUI_FROM_DATABASE=MACANDC
+
+OUI:DCB058*
+ ID_OUI_FROM_DATABASE=Burkert Werke GmbH
+
+OUI:DCB4C4*
+ ID_OUI_FROM_DATABASE=Microsoft XCG
+
+OUI:DCBF90*
+ ID_OUI_FROM_DATABASE=HUIZHOU QIAOXING TELECOMMUNICATION INDUSTRY CO.,LTD.
+
+OUI:DCC0DB*
+ ID_OUI_FROM_DATABASE=Shenzhen Kaiboer Technology Co., Ltd.
+
+OUI:DCC101*
+ ID_OUI_FROM_DATABASE=SOLiD Technologies, Inc.
+
+OUI:DCCBA8*
+ ID_OUI_FROM_DATABASE=Explora Technologies Inc
+
+OUI:DCCE41*
+ ID_OUI_FROM_DATABASE=FE GLOBAL HONG KONG LIMITED
+
+OUI:DCCF94*
+ ID_OUI_FROM_DATABASE=Beijing Rongcheng Hutong Technology Co., Ltd.
+
+OUI:DCD0F7*
+ ID_OUI_FROM_DATABASE=Bentek Systems Ltd.
+
+OUI:DCD2FC*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:DCD321*
+ ID_OUI_FROM_DATABASE=HUMAX co.,tld
+
+OUI:DCD87F*
+ ID_OUI_FROM_DATABASE=Shenzhen JoinCyber Telecom Equipment Ltd
+
+OUI:DCDECA*
+ ID_OUI_FROM_DATABASE=Akyllor
+
+OUI:DCE2AC*
+ ID_OUI_FROM_DATABASE=Lumens Digital Optics Inc.
+
+OUI:DCE71C*
+ ID_OUI_FROM_DATABASE=AUG Elektronik GmbH
+
+OUI:DCF05D*
+ ID_OUI_FROM_DATABASE=Letta Teknoloji
+
+OUI:DCF858*
+ ID_OUI_FROM_DATABASE=Lorent Networks, Inc.
+
+OUI:DCFAD5*
+ ID_OUI_FROM_DATABASE=STRONG Ges.m.b.H.
+
+OUI:E005C5*
+ ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd.
+
+OUI:E006E6*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:E00B28*
+ ID_OUI_FROM_DATABASE=Inovonics
+
+OUI:E00C7F*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:E0143E*
+ ID_OUI_FROM_DATABASE=Modoosis Inc.
+
+OUI:E01C41*
+ ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
+
+OUI:E01CEE*
+ ID_OUI_FROM_DATABASE=Bravo Tech, Inc.
+
+OUI:E01D3B*
+ ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd
+
+OUI:E01E07*
+ ID_OUI_FROM_DATABASE=Anite Telecoms  US. Inc
+
+OUI:E01F0A*
+ ID_OUI_FROM_DATABASE=Xslent Energy Technologies. LLC
+
+OUI:E0247F*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E02538*
+ ID_OUI_FROM_DATABASE=Titan Pet Products
+
+OUI:E02630*
+ ID_OUI_FROM_DATABASE=Intrigue Technologies, Inc.
+
+OUI:E02636*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:E0271A*
+ ID_OUI_FROM_DATABASE=TTC Next-generation Home Network System WG
+
+OUI:E02A82*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:E02F6D*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:E03005*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:E039D7*
+ ID_OUI_FROM_DATABASE=Plexxi, Inc.
+
+OUI:E03C5B*
+ ID_OUI_FROM_DATABASE=SHENZHEN JIAXINJIE ELECTRON CO.,LTD
+
+OUI:E03E7D*
+ ID_OUI_FROM_DATABASE=data-complex GmbH
+
+OUI:E0469A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:E05597*
+ ID_OUI_FROM_DATABASE=Emergent Vision Technologies Inc.
+
+OUI:E0589E*
+ ID_OUI_FROM_DATABASE=Laerdal Medical
+
+OUI:E05B70*
+ ID_OUI_FROM_DATABASE=Innovid, Co., Ltd.
+
+OUI:E05DA6*
+ ID_OUI_FROM_DATABASE=Detlef Fink Elektronik & Softwareentwicklung
+
+OUI:E05FB9*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:E061B2*
+ ID_OUI_FROM_DATABASE=HANGZHOU ZENOINTEL TECHNOLOGY CO., LTD
+
+OUI:E06290*
+ ID_OUI_FROM_DATABASE=Jinan Jovision Science & Technology Co., Ltd.
+
+OUI:E064BB*
+ ID_OUI_FROM_DATABASE=DigiView S.r.l.
+
+OUI:E06995*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:E0757D*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
+OUI:E08177*
+ ID_OUI_FROM_DATABASE=GreenBytes, Inc.
+
+OUI:E087B1*
+ ID_OUI_FROM_DATABASE=Nata-Info Ltd.
+
+OUI:E08A7E*
+ ID_OUI_FROM_DATABASE=Exponent
+
+OUI:E08FEC*
+ ID_OUI_FROM_DATABASE=REPOTEC CO., LTD.
+
+OUI:E09153*
+ ID_OUI_FROM_DATABASE=XAVi Technologies Corp.
+
+OUI:E091F5*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:E09467*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:E09579*
+ ID_OUI_FROM_DATABASE=ORTHOsoft inc, d/b/a Zimmer CAS
+
+OUI:E09D31*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:E09DB8*
+ ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC.
+
+OUI:E0A1D7*
+ ID_OUI_FROM_DATABASE=SFR
+
+OUI:E0A30F*
+ ID_OUI_FROM_DATABASE=Pevco
+
+OUI:E0A670*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:E0AAB0*
+ ID_OUI_FROM_DATABASE=GENERAL VISION ELECTRONICS CO. LTD.
+
+OUI:E0ABFE*
+ ID_OUI_FROM_DATABASE=Orb Networks, Inc.
+
+OUI:E0AE5E*
+ ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd.
+
+OUI:E0AEED*
+ ID_OUI_FROM_DATABASE=LOENK
+
+OUI:E0B7B1*
+ ID_OUI_FROM_DATABASE=Pace plc
+
+OUI:E0B9A5*
+ ID_OUI_FROM_DATABASE=Azurewave
+
+OUI:E0B9BA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:E0BC43*
+ ID_OUI_FROM_DATABASE=C2 Microsystems, Inc.
+
+OUI:E0C286*
+ ID_OUI_FROM_DATABASE=Aisai Communication Technology Co., Ltd.
+
+OUI:E0C2B7*
+ ID_OUI_FROM_DATABASE=Masimo Corporation
+
+OUI:E0C3F3*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:E0C79D*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:E0C922*
+ ID_OUI_FROM_DATABASE=Jireh Energy Tech., Ltd.
+
+OUI:E0C97A*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:E0CA4D*
+ ID_OUI_FROM_DATABASE=Shenzhen Unistar Communication Co.,LTD
+
+OUI:E0CA94*
+ ID_OUI_FROM_DATABASE=Askey Computer
+
+OUI:E0CB4E*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:E0CEC3*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
+OUI:E0CF2D*
+ ID_OUI_FROM_DATABASE=Gemintek Corporation
+
+OUI:E0D10A*
+ ID_OUI_FROM_DATABASE=Katoudenkikougyousyo co ltd
+
+OUI:E0D7BA*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:E0D9A2*
+ ID_OUI_FROM_DATABASE=Hippih aps
+
+OUI:E0DADC*
+ ID_OUI_FROM_DATABASE=JVC KENWOOD Corporation
+
+OUI:E0DB55*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
+OUI:E0E751*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:E0E8E8*
+ ID_OUI_FROM_DATABASE=Olive Telecommunication Pvt. Ltd
+
+OUI:E0ED1A*
+ ID_OUI_FROM_DATABASE=vastriver Technology Co., Ltd
+
+OUI:E0EE1B*
+ ID_OUI_FROM_DATABASE=Panasonic Automotive Systems Company of America
+
+OUI:E0EF25*
+ ID_OUI_FROM_DATABASE=Lintes Technology Co., Ltd.
+
+OUI:E0F211*
+ ID_OUI_FROM_DATABASE=Digitalwatt
+
+OUI:E0F379*
+ ID_OUI_FROM_DATABASE=Vaddio
+
+OUI:E0F5CA*
+ ID_OUI_FROM_DATABASE=CHENG UEI PRECISION INDUSTRY CO.,LTD.
+
+OUI:E0F847*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:E0F9BE*
+ ID_OUI_FROM_DATABASE=Cloudena Corp.
+
+OUI:E4115B*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:E41289*
+ ID_OUI_FROM_DATABASE=topsystem Systemhaus GmbH
+
+OUI:E41C4B*
+ ID_OUI_FROM_DATABASE=V2 TECHNOLOGY, INC.
+
+OUI:E41F13*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:E425E9*
+ ID_OUI_FROM_DATABASE=Color-Chip
+
+OUI:E42771*
+ ID_OUI_FROM_DATABASE=Smartlabs
+
+OUI:E42AD3*
+ ID_OUI_FROM_DATABASE=Magneti Marelli S.p.A. Powertrain
+
+OUI:E42C56*
+ ID_OUI_FROM_DATABASE=Lilee Systems, Ltd.
+
+OUI:E42F26*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
+
+OUI:E42FF6*
+ ID_OUI_FROM_DATABASE=Unicore communication Inc.
+
+OUI:E43593*
+ ID_OUI_FROM_DATABASE=Hangzhou GoTo technology Co.Ltd
+
+OUI:E435FB*
+ ID_OUI_FROM_DATABASE=Sabre Technology (Hull) Ltd
+
+OUI:E437D7*
+ ID_OUI_FROM_DATABASE=HENRI DEPAEPE S.A.S.
+
+OUI:E43FA2*
+ ID_OUI_FROM_DATABASE=Wuxi DSP Technologies Inc.
+
+OUI:E441E6*
+ ID_OUI_FROM_DATABASE=Ottec Technology GmbH
+
+OUI:E446BD*
+ ID_OUI_FROM_DATABASE=C&C TECHNIC TAIWAN CO., LTD.
+
+OUI:E448C7*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:E44E18*
+ ID_OUI_FROM_DATABASE=Gardasoft VisionLimited
+
+OUI:E44F29*
+ ID_OUI_FROM_DATABASE=MA Lighting Technology GmbH
+
+OUI:E44F5F*
+ ID_OUI_FROM_DATABASE=EDS Elektronik Destek San.Tic.Ltd.Sti
+
+OUI:E455EA*
+ ID_OUI_FROM_DATABASE=Dedicated Computing
+
+OUI:E45614*
+ ID_OUI_FROM_DATABASE=Suttle Apparatus
+
+OUI:E46449*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:E467BA*
+ ID_OUI_FROM_DATABASE=Danish Interpretation Systems A/S
+
+OUI:E46C21*
+ ID_OUI_FROM_DATABASE=messMa GmbH
+
+OUI:E47185*
+ ID_OUI_FROM_DATABASE=Securifi Ltd
+
+OUI:E4751E*
+ ID_OUI_FROM_DATABASE=Getinge Sterilization AB
+
+OUI:E477D4*
+ ID_OUI_FROM_DATABASE=Minrray Industry Co.,Ltd
+
+OUI:E47CF9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
+
+OUI:E48399*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:E48AD5*
+ ID_OUI_FROM_DATABASE=RF WINDOW CO., LTD.
+
+OUI:E48B7F*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:E49069*
+ ID_OUI_FROM_DATABASE=Rockwell Automation
+
+OUI:E492E7*
+ ID_OUI_FROM_DATABASE=Gridlink Tech. Co.,Ltd.
+
+OUI:E496AE*
+ ID_OUI_FROM_DATABASE=ALTOGRAPHICS Inc.
+
+OUI:E497F0*
+ ID_OUI_FROM_DATABASE=Shanghai VLC Technologies Ltd. Co.
+
+OUI:E4A5EF*
+ ID_OUI_FROM_DATABASE=TRON LINK ELECTRONICS CO., LTD.
+
+OUI:E4A7FD*
+ ID_OUI_FROM_DATABASE=Cellco Partnership
+
+OUI:E4AB46*
+ ID_OUI_FROM_DATABASE=UAB Selteka
+
+OUI:E4AD7D*
+ ID_OUI_FROM_DATABASE=SCL Elements
+
+OUI:E4AFA1*
+ ID_OUI_FROM_DATABASE=HES-SO
+
+OUI:E4B021*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:E4C146*
+ ID_OUI_FROM_DATABASE=Objetivos y Servicios de Valor A
+
+OUI:E4C6E6*
+ ID_OUI_FROM_DATABASE=Mophie, LLC
+
+OUI:E4C806*
+ ID_OUI_FROM_DATABASE=Ceiec Electric Technology Inc.
+
+OUI:E4CE8F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:E4D3F1*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:E4D53D*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:E4D71D*
+ ID_OUI_FROM_DATABASE=Oraya Therapeutics
+
+OUI:E4DD79*
+ ID_OUI_FROM_DATABASE=En-Vision America, Inc.
+
+OUI:E4E0C5*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD
+
+OUI:E4E409*
+ ID_OUI_FROM_DATABASE=LEIFHEIT AG
+
+OUI:E4EC10*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:E4EEFD*
+ ID_OUI_FROM_DATABASE=MR&D Manufacturing
+
+OUI:E4F365*
+ ID_OUI_FROM_DATABASE=Time-O-Matic, Inc.
+
+OUI:E4FA1D*
+ ID_OUI_FROM_DATABASE=PAD Peripheral Advanced Design Inc.
+
+OUI:E4FFDD*
+ ID_OUI_FROM_DATABASE=ELECTRON INDIA
+
+OUI:E8039A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
+OUI:E8040B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:E80462*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:E804F3*
+ ID_OUI_FROM_DATABASE=Throughtek Co., Ltd.
+
+OUI:E8056D*
+ ID_OUI_FROM_DATABASE=Nortel Networks
+
+OUI:E80688*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:E80B13*
+ ID_OUI_FROM_DATABASE=Akib Systems Taiwan, INC
+
+OUI:E80C38*
+ ID_OUI_FROM_DATABASE=DAEYOUNG INFORMATION SYSTEM CO., LTD
+
+OUI:E80C75*
+ ID_OUI_FROM_DATABASE=Syncbak, Inc.
+
+OUI:E8102E*
+ ID_OUI_FROM_DATABASE=Really Simple Software, Inc
+
+OUI:E81132*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
+OUI:E81324*
+ ID_OUI_FROM_DATABASE=GuangZhou Bonsoninfo System CO.,LTD
+
+OUI:E82877*
+ ID_OUI_FROM_DATABASE=TMY Co., Ltd.
+
+OUI:E828D5*
+ ID_OUI_FROM_DATABASE=Cots Technology
+
+OUI:E82E24*
+ ID_OUI_FROM_DATABASE=Out of the Fog Research LLC
+
+OUI:E83935*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:E839DF*
+ ID_OUI_FROM_DATABASE=Askey Computer
+
+OUI:E83A97*
+ ID_OUI_FROM_DATABASE=OCZ Technology Group
+
+OUI:E83EB6*
+ ID_OUI_FROM_DATABASE=RIM
+
+OUI:E83EFB*
+ ID_OUI_FROM_DATABASE=GEODESIC LTD.
+
+OUI:E83EFC*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc
+
+OUI:E84040*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:E840F2*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:E843B6*
+ ID_OUI_FROM_DATABASE=QNAP Systems, Inc.
+
+OUI:E84E06*
+ ID_OUI_FROM_DATABASE=EDUP INTERNATIONAL (HK) CO., LTD
+
+OUI:E84ECE*
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:E85484*
+ ID_OUI_FROM_DATABASE=NEO INFORMATION SYSTEMS CO., LTD.
+
+OUI:E856D6*
+ ID_OUI_FROM_DATABASE=NCTech Ltd
+
+OUI:E85AA7*
+ ID_OUI_FROM_DATABASE=LLC Emzior
+
+OUI:E85B5B*
+ ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
+
+OUI:E85BF0*
+ ID_OUI_FROM_DATABASE=Imaging Diagnostics
+
+OUI:E85E53*
+ ID_OUI_FROM_DATABASE=Infratec Datentechnik GmbH
+
+OUI:E86CDA*
+ ID_OUI_FROM_DATABASE=Supercomputers and Neurocomputers Research Center
+
+OUI:E86D52*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:E86D54*
+ ID_OUI_FROM_DATABASE=Digit Mobile Inc
+
+OUI:E86D6E*
+ ID_OUI_FROM_DATABASE=Control & Display Systems Ltd t/a CDSRail
+
+OUI:E8718D*
+ ID_OUI_FROM_DATABASE=Elsys Equipamentos Eletronicos Ltda
+
+OUI:E8757F*
+ ID_OUI_FROM_DATABASE=FIRS Technologies(Shenzhen) Co., Ltd
+
+OUI:E878A1*
+ ID_OUI_FROM_DATABASE=BEOVIEW INTERCOM DOO
+
+OUI:E87AF3*
+ ID_OUI_FROM_DATABASE=S5 Tech S.r.l.
+
+OUI:E8892C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc
+
+OUI:E88D28*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:E88DF5*
+ ID_OUI_FROM_DATABASE=ZNYX Networks, Inc.
+
+OUI:E892A4*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:E8944C*
+ ID_OUI_FROM_DATABASE=Cogent Healthcare Systems Ltd
+
+OUI:E8995A*
+ ID_OUI_FROM_DATABASE=PiiGAB, Processinformation i Goteborg AB
+
+OUI:E899C4*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:E89A8F*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc.
+
+OUI:E89AFF*
+ ID_OUI_FROM_DATABASE=Fujian Landi Commercial Equipment Co.,Ltd
+
+OUI:E89D87*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:E8A364*
+ ID_OUI_FROM_DATABASE=Signal Path International / Peachtree Audio
+
+OUI:E8A4C1*
+ ID_OUI_FROM_DATABASE=Deep Sea Electronics PLC
+
+OUI:E8ABFA*
+ ID_OUI_FROM_DATABASE=Shenzhen Reecam Tech.Ltd.
+
+OUI:E8B4AE*
+ ID_OUI_FROM_DATABASE=Shenzhen C&D Electronics Co.,Ltd
+
+OUI:E8B748*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:E8BA70*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:E8BE81*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
+OUI:E8C229*
+ ID_OUI_FROM_DATABASE=H-Displays (MSC) Bhd
+
+OUI:E8C320*
+ ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd
+
+OUI:E8CBA1*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:E8CC32*
+ ID_OUI_FROM_DATABASE=Micronet  LTD
+
+OUI:E8D0FA*
+ ID_OUI_FROM_DATABASE=MKS Instruments Deutschland GmbH
+
+OUI:E8D483*
+ ID_OUI_FROM_DATABASE=ULTIMATE Europe Transportation Equipment GmbH
+
+OUI:E8DA96*
+ ID_OUI_FROM_DATABASE=Zhuhai Tianrui Electrical Power Tech. Co., Ltd.
+
+OUI:E8DAAA*
+ ID_OUI_FROM_DATABASE=VideoHome Technology Corp.
+
+OUI:E8DFF2*
+ ID_OUI_FROM_DATABASE=PRF Co., Ltd.
+
+OUI:E8E08F*
+ ID_OUI_FROM_DATABASE=GRAVOTECH MARKING SAS
+
+OUI:E8E0B7*
+ ID_OUI_FROM_DATABASE=Toshiba
+
+OUI:E8E1E2*
+ ID_OUI_FROM_DATABASE=Energotest
+
+OUI:E8E5D6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:E8E732*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:E8E776*
+ ID_OUI_FROM_DATABASE=Shenzhen Kootion Technology Co., Ltd
+
+OUI:E8E875*
+ ID_OUI_FROM_DATABASE=iS5 Communications Inc.
+
+OUI:E8F1B0*
+ ID_OUI_FROM_DATABASE=SAGEMCOM SAS
+
+OUI:E8F928*
+ ID_OUI_FROM_DATABASE=RFTECH SRL
+
+OUI:EC0ED6*
+ ID_OUI_FROM_DATABASE=ITECH INSTRUMENTS SAS
+
+OUI:EC1120*
+ ID_OUI_FROM_DATABASE=FloDesign Wind Turbine Corporation
+
+OUI:EC14F6*
+ ID_OUI_FROM_DATABASE=BioControl AS
+
+OUI:EC172F*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:EC1A59*
+ ID_OUI_FROM_DATABASE=Belkin International Inc.
+
+OUI:EC233D*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:EC2368*
+ ID_OUI_FROM_DATABASE=IntelliVoice Co.,Ltd.
+
+OUI:EC3091*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:EC3BF0*
+ ID_OUI_FROM_DATABASE=NovelSat
+
+OUI:EC3F05*
+ ID_OUI_FROM_DATABASE=Institute 706, The Second Academy China Aerospace Science & Industry Corp
+
+OUI:EC42F0*
+ ID_OUI_FROM_DATABASE=ADL Embedded Solutions, Inc.
+
+OUI:EC43E6*
+ ID_OUI_FROM_DATABASE=AWCER Ltd.
+
+OUI:EC43F6*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:EC4476*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:EC4644*
+ ID_OUI_FROM_DATABASE=TTK SAS
+
+OUI:EC4670*
+ ID_OUI_FROM_DATABASE=Meinberg Funkuhren GmbH & Co. KG
+
+OUI:EC473C*
+ ID_OUI_FROM_DATABASE=Redwire, LLC
+
+OUI:EC4993*
+ ID_OUI_FROM_DATABASE=Qihan Technology Co., Ltd
+
+OUI:EC4C4D*
+ ID_OUI_FROM_DATABASE=ZAO NPK RoTeK
+
+OUI:EC542E*
+ ID_OUI_FROM_DATABASE=Shanghai XiMei Electronic Technology Co. Ltd
+
+OUI:EC55F9*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:EC5C69*
+ ID_OUI_FROM_DATABASE=MITSUBISHI HEAVY INDUSTRIES MECHATRONICS SYSTEMS,LTD.
+
+OUI:EC6264*
+ ID_OUI_FROM_DATABASE=Global411 Internet Services, LLC
+
+OUI:EC63E5*
+ ID_OUI_FROM_DATABASE=ePBoard Design LLC
+
+OUI:EC66D1*
+ ID_OUI_FROM_DATABASE=B&W Group LTD
+
+OUI:EC6C9F*
+ ID_OUI_FROM_DATABASE=Chengdu Volans Technology CO.,LTD
+
+OUI:EC7C74*
+ ID_OUI_FROM_DATABASE=Justone Technologies Co., Ltd.
+
+OUI:EC7D9D*
+ ID_OUI_FROM_DATABASE=MEI
+
+OUI:EC836C*
+ ID_OUI_FROM_DATABASE=RM Tech Co., Ltd.
+
+OUI:EC852F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:EC888F*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:EC89F5*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
+OUI:EC8EAD*
+ ID_OUI_FROM_DATABASE=DLX
+
+OUI:EC9233*
+ ID_OUI_FROM_DATABASE=Eddyfi NDT Inc
+
+OUI:EC9327*
+ ID_OUI_FROM_DATABASE=MEMMERT GmbH + Co. KG
+
+OUI:EC9681*
+ ID_OUI_FROM_DATABASE=2276427 Ontario Inc
+
+OUI:EC986C*
+ ID_OUI_FROM_DATABASE=Lufft Mess- und Regeltechnik GmbH
+
+OUI:EC98C1*
+ ID_OUI_FROM_DATABASE=Beijing Risbo Network Technology Co.,Ltd
+
+OUI:EC9A74*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:EC9B5B*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:EC9ECD*
+ ID_OUI_FROM_DATABASE=Emerson Network Power and Embedded Computing
+
+OUI:ECA29B*
+ ID_OUI_FROM_DATABASE=Kemppi Oy
+
+OUI:ECA86B*
+ ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEMS CO., LTD.
+
+OUI:ECB106*
+ ID_OUI_FROM_DATABASE=Acuro Networks, Inc
+
+OUI:ECB541*
+ ID_OUI_FROM_DATABASE=SHINANO E and E Co.Ltd.
+
+OUI:ECBBAE*
+ ID_OUI_FROM_DATABASE=Digivoice Tecnologia em Eletronica Ltda
+
+OUI:ECBD09*
+ ID_OUI_FROM_DATABASE=FUSION Electronics Ltd
+
+OUI:ECC38A*
+ ID_OUI_FROM_DATABASE=Accuenergy (CANADA) Inc
+
+OUI:ECC882*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:ECCD6D*
+ ID_OUI_FROM_DATABASE=Allied Telesis, Inc.
+
+OUI:ECD00E*
+ ID_OUI_FROM_DATABASE=MiraeRecognition Co., Ltd.
+
+OUI:ECD19A*
+ ID_OUI_FROM_DATABASE=Zhuhai Liming Industries Co., Ltd
+
+OUI:ECD925*
+ ID_OUI_FROM_DATABASE=RAMI
+
+OUI:ECD950*
+ ID_OUI_FROM_DATABASE=IRT SA
+
+OUI:ECDE3D*
+ ID_OUI_FROM_DATABASE=Lamprey Networks, Inc.
+
+OUI:ECE09B*
+ ID_OUI_FROM_DATABASE=Samsung electronics CO., LTD
+
+OUI:ECE555*
+ ID_OUI_FROM_DATABASE=Hirschmann Automation
+
+OUI:ECE744*
+ ID_OUI_FROM_DATABASE=Omntec mfg. inc
+
+OUI:ECE90B*
+ ID_OUI_FROM_DATABASE=SISTEMA SOLUCOES ELETRONICAS LTDA - EASYTECH
+
+OUI:ECE915*
+ ID_OUI_FROM_DATABASE=STI Ltd
+
+OUI:ECE9F8*
+ ID_OUI_FROM_DATABASE=Guang Zhou TRI-SUN Electronics Technology  Co., Ltd
+
+OUI:ECEA03*
+ ID_OUI_FROM_DATABASE=DARFON LIGHTING CORP
+
+OUI:ECF00E*
+ ID_OUI_FROM_DATABASE=Abocom
+
+OUI:ECF236*
+ ID_OUI_FROM_DATABASE=NEOMONTANA ELECTRONICS
+
+OUI:ECFAAA*
+ ID_OUI_FROM_DATABASE=The IMS Company
+
+OUI:ECFC55*
+ ID_OUI_FROM_DATABASE=A. Eberle GmbH & Co. KG
+
+OUI:ECFE7E*
+ ID_OUI_FROM_DATABASE=BlueRadios, Inc.
+
+OUI:F0007F*
+ ID_OUI_FROM_DATABASE=Janz - Contadores de Energia, SA
+
+OUI:F0022B*
+ ID_OUI_FROM_DATABASE=Chrontel
+
+OUI:F00248*
+ ID_OUI_FROM_DATABASE=SmarteBuilding
+
+OUI:F00786*
+ ID_OUI_FROM_DATABASE=Shandong Bittel Electronics Co., Ltd
+
+OUI:F008F1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F013C3*
+ ID_OUI_FROM_DATABASE=SHENZHEN FENDA TECHNOLOGY CO., LTD
+
+OUI:F01C13*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:F0219D*
+ ID_OUI_FROM_DATABASE=Cal-Comp Electronics & Communications Company Ltd.
+
+OUI:F02329*
+ ID_OUI_FROM_DATABASE=SHOWA DENKI CO.,LTD.
+
+OUI:F02408*
+ ID_OUI_FROM_DATABASE=Talaris (Sweden) AB
+
+OUI:F02572*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:F0264C*
+ ID_OUI_FROM_DATABASE=Dr. Sigrist AG
+
+OUI:F02929*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:F02A61*
+ ID_OUI_FROM_DATABASE=Waldo Networks, Inc.
+
+OUI:F02FD8*
+ ID_OUI_FROM_DATABASE=Bi2-Vision
+
+OUI:F03A55*
+ ID_OUI_FROM_DATABASE=Omega Elektronik AS
+
+OUI:F04335*
+ ID_OUI_FROM_DATABASE=DVN(Shanghai)Ltd.
+
+OUI:F04A2B*
+ ID_OUI_FROM_DATABASE=PYRAMID Computer GmbH
+
+OUI:F04B6A*
+ ID_OUI_FROM_DATABASE=Scientific Production Association Siberian Arsenal, Ltd.
+
+OUI:F04BF2*
+ ID_OUI_FROM_DATABASE=JTECH Communications, Inc.
+
+OUI:F04DA2*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:F05849*
+ ID_OUI_FROM_DATABASE=CareView Communications
+
+OUI:F05D89*
+ ID_OUI_FROM_DATABASE=Dycon Limited
+
+OUI:F05F5A*
+ ID_OUI_FROM_DATABASE=Getriebebau NORD GmbH and Co. KG
+
+OUI:F0620D*
+ ID_OUI_FROM_DATABASE=Shenzhen Egreat Tech Corp.,Ltd
+
+OUI:F06281*
+ ID_OUI_FROM_DATABASE=ProCurve Networking by HP
+
+OUI:F065DD*
+ ID_OUI_FROM_DATABASE=Primax Electronics Ltd.
+
+OUI:F06853*
+ ID_OUI_FROM_DATABASE=Integrated Corporation
+
+OUI:F073AE*
+ ID_OUI_FROM_DATABASE=PEAK-System Technik
+
+OUI:F077D0*
+ ID_OUI_FROM_DATABASE=Xcellen
+
+OUI:F07BCB*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:F07D68*
+ ID_OUI_FROM_DATABASE=D-Link Corporation
+
+OUI:F081AF*
+ ID_OUI_FROM_DATABASE=IRZ AUTOMATION TECHNOLOGIES LTD
+
+OUI:F08BFE*
+ ID_OUI_FROM_DATABASE=COSTEL.,CO.LTD
+
+OUI:F0933A*
+ ID_OUI_FROM_DATABASE=NxtConect
+
+OUI:F093C5*
+ ID_OUI_FROM_DATABASE=Garland Technology
+
+OUI:F09CBB*
+ ID_OUI_FROM_DATABASE=RaonThink Inc.
+
+OUI:F09CE9*
+ ID_OUI_FROM_DATABASE=Aerohive Networks Inc
+
+OUI:F0A764*
+ ID_OUI_FROM_DATABASE=GST Co., Ltd.
+
+OUI:F0ACA4*
+ ID_OUI_FROM_DATABASE=HBC-radiomatic
+
+OUI:F0AD4E*
+ ID_OUI_FROM_DATABASE=Globalscale Technologies, Inc.
+
+OUI:F0AE51*
+ ID_OUI_FROM_DATABASE=Xi3 Corp
+
+OUI:F0B479*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:F0B6EB*
+ ID_OUI_FROM_DATABASE=Poslab Technology Co., Ltd.
+
+OUI:F0BCC8*
+ ID_OUI_FROM_DATABASE=MaxID (Pty) Ltd
+
+OUI:F0BDF1*
+ ID_OUI_FROM_DATABASE=Sipod Inc.
+
+OUI:F0BF97*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
+OUI:F0C24C*
+ ID_OUI_FROM_DATABASE=Zhejiang FeiYue Digital Technology Co., Ltd
+
+OUI:F0C27C*
+ ID_OUI_FROM_DATABASE=Mianyang Netop Telecom Equipment Co.,Ltd.
+
+OUI:F0C88C*
+ ID_OUI_FROM_DATABASE=LeddarTech Inc.
+
+OUI:F0CBA1*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:F0D14F*
+ ID_OUI_FROM_DATABASE=LINEAR LLC
+
+OUI:F0D1A9*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:F0D3E7*
+ ID_OUI_FROM_DATABASE=Sensometrix SA
+
+OUI:F0D767*
+ ID_OUI_FROM_DATABASE=Axema Passagekontroll AB
+
+OUI:F0DA7C*
+ ID_OUI_FROM_DATABASE=RLH INDUSTRIES,INC.
+
+OUI:F0DB30*
+ ID_OUI_FROM_DATABASE=Yottabyte
+
+OUI:F0DCE2*
+ ID_OUI_FROM_DATABASE=Apple Inc
+
+OUI:F0DE71*
+ ID_OUI_FROM_DATABASE=Shanghai EDO Technologies Co.,Ltd.
+
+OUI:F0DEB9*
+ ID_OUI_FROM_DATABASE=ShangHai Y&Y Electronics Co., Ltd
+
+OUI:F0DEF1*
+ ID_OUI_FROM_DATABASE=Wistron InfoComm (Kunshan)Co
+
+OUI:F0E5C3*
+ ID_OUI_FROM_DATABASE=Drägerwerk AG & Co. KG aA
+
+OUI:F0E77E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F0EC39*
+ ID_OUI_FROM_DATABASE=Essec
+
+OUI:F0ED1E*
+ ID_OUI_FROM_DATABASE=Bilkon Bilgisayar Kontrollu Cih. Im.Ltd.
+
+OUI:F0EEBB*
+ ID_OUI_FROM_DATABASE=VIPAR GmbH
+
+OUI:F0F002*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:F0F644*
+ ID_OUI_FROM_DATABASE=Whitesky Science & Technology Co.,Ltd.
+
+OUI:F0F669*
+ ID_OUI_FROM_DATABASE=Motion Analysis Corporation
+
+OUI:F0F755*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:F0F7B3*
+ ID_OUI_FROM_DATABASE=Phorm
+
+OUI:F0F842*
+ ID_OUI_FROM_DATABASE=KEEBOX, Inc.
+
+OUI:F0F9F7*
+ ID_OUI_FROM_DATABASE=IES GmbH & Co. KG
+
+OUI:F0FDA0*
+ ID_OUI_FROM_DATABASE=Acurix Networks LP
+
+OUI:F40321*
+ ID_OUI_FROM_DATABASE=BeNeXt B.V.
+
+OUI:F4044C*
+ ID_OUI_FROM_DATABASE=ValenceTech Limited
+
+OUI:F40B93*
+ ID_OUI_FROM_DATABASE=Research In Motion
+
+OUI:F40F9B*
+ ID_OUI_FROM_DATABASE=WAVELINK
+
+OUI:F41BA1*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:F41E26*
+ ID_OUI_FROM_DATABASE=Simon-Kaloi Engineering
+
+OUI:F41F0B*
+ ID_OUI_FROM_DATABASE=YAMABISHI Corporation
+
+OUI:F436E1*
+ ID_OUI_FROM_DATABASE=Abilis Systems SARL
+
+OUI:F43814*
+ ID_OUI_FROM_DATABASE=Shanghai Howell Electronic Co.,Ltd
+
+OUI:F43D80*
+ ID_OUI_FROM_DATABASE=FAG Industrial Services GmbH
+
+OUI:F43E61*
+ ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co., Ltd
+
+OUI:F43E9D*
+ ID_OUI_FROM_DATABASE=Benu Networks, Inc.
+
+OUI:F44227*
+ ID_OUI_FROM_DATABASE=S & S Research Inc.
+
+OUI:F44450*
+ ID_OUI_FROM_DATABASE=BND Co., Ltd.
+
+OUI:F445ED*
+ ID_OUI_FROM_DATABASE=Portable Innovation Technology Ltd.
+
+OUI:F4472A*
+ ID_OUI_FROM_DATABASE=Nanjing Rousing Sci. and Tech. Industrial Co., Ltd
+
+OUI:F44848*
+ ID_OUI_FROM_DATABASE=Amscreen Group Ltd
+
+OUI:F44EFD*
+ ID_OUI_FROM_DATABASE=Actions Semiconductor Co.,Ltd.(Cayman Islands)
+
+OUI:F450EB*
+ ID_OUI_FROM_DATABASE=Telechips Inc
+
+OUI:F45214*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
+OUI:F45433*
+ ID_OUI_FROM_DATABASE=Rockwell Automation
+
+OUI:F45595*
+ ID_OUI_FROM_DATABASE=HENGBAO Corporation LTD.
+
+OUI:F4559C*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:F455E0*
+ ID_OUI_FROM_DATABASE=Niceway CNC Technology Co.,Ltd.Hunan Province
+
+OUI:F45FD4*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:F45FF7*
+ ID_OUI_FROM_DATABASE=DQ Technology Inc.
+
+OUI:F4600D*
+ ID_OUI_FROM_DATABASE=Panoptic Technology, Inc
+
+OUI:F46349*
+ ID_OUI_FROM_DATABASE=Diffon Corporation
+
+OUI:F46D04*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:F46DE2*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:F473CA*
+ ID_OUI_FROM_DATABASE=Conversion Sound Inc.
+
+OUI:F47626*
+ ID_OUI_FROM_DATABASE=Viltechmeda UAB
+
+OUI:F47ACC*
+ ID_OUI_FROM_DATABASE=SolidFire, Inc.
+
+OUI:F47B5E*
+ ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd
+
+OUI:F47F35*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:F48771*
+ ID_OUI_FROM_DATABASE=Infoblox
+
+OUI:F48E09*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:F490EA*
+ ID_OUI_FROM_DATABASE=Deciso B.V.
+
+OUI:F49461*
+ ID_OUI_FROM_DATABASE=NexGen Storage
+
+OUI:F49466*
+ ID_OUI_FROM_DATABASE=CountMax,  ltd
+
+OUI:F49F54*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:F4A52A*
+ ID_OUI_FROM_DATABASE=Hawa Technologies Inc
+
+OUI:F4ACC1*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:F4B164*
+ ID_OUI_FROM_DATABASE=Lightning Telecommunications Technology Co. Ltd
+
+OUI:F4B549*
+ ID_OUI_FROM_DATABASE=Yeastar Technology Co., Ltd.
+
+OUI:F4B72A*
+ ID_OUI_FROM_DATABASE=TIME INTERCONNECT LTD
+
+OUI:F4B7E2*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:F4C6D7*
+ ID_OUI_FROM_DATABASE=blackned GmbH
+
+OUI:F4C714*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd
+
+OUI:F4C795*
+ ID_OUI_FROM_DATABASE=WEY Elektronik AG
+
+OUI:F4CAE5*
+ ID_OUI_FROM_DATABASE=FREEBOX SA
+
+OUI:F4CE46*
+ ID_OUI_FROM_DATABASE=Hewlett-Packard Company
+
+OUI:F4D9FB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD
+
+OUI:F4DC4D*
+ ID_OUI_FROM_DATABASE=Beijing CCD Digital Technology Co., Ltd
+
+OUI:F4DCDA*
+ ID_OUI_FROM_DATABASE=Zhuhai Jiahe Communication Technology Co., limited
+
+OUI:F4E142*
+ ID_OUI_FROM_DATABASE=Delta Elektronika BV
+
+OUI:F4E6D7*
+ ID_OUI_FROM_DATABASE=Solar Power Technologies, Inc.
+
+OUI:F4EA67*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:F4EC38*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:F4F15A*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:F4FC32*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:F80113*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:F80332*
+ ID_OUI_FROM_DATABASE=Khomp
+
+OUI:F8051C*
+ ID_OUI_FROM_DATABASE=DRS Imaging and Targeting Solutions
+
+OUI:F80BBE*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:F80BD0*
+ ID_OUI_FROM_DATABASE=Datang Telecom communication terminal (Tianjin) Co., Ltd.
+
+OUI:F80CF3*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:F80F41*
+ ID_OUI_FROM_DATABASE=Wistron InfoComm(ZhongShan) Corporation
+
+OUI:F80F84*
+ ID_OUI_FROM_DATABASE=Natural Security SAS
+
+OUI:F81037*
+ ID_OUI_FROM_DATABASE=Atopia Systems, LP
+
+OUI:F81A67*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:F81D93*
+ ID_OUI_FROM_DATABASE=Longdhua(Beijing) Controls Technology Co.,Ltd
+
+OUI:F81EDF*
+ ID_OUI_FROM_DATABASE=Apple, Inc
+
+OUI:F82285*
+ ID_OUI_FROM_DATABASE=Cypress Technology CO., LTD.
+
+OUI:F82EDB*
+ ID_OUI_FROM_DATABASE=RTW GmbH & Co. KG
+
+OUI:F82F5B*
+ ID_OUI_FROM_DATABASE=eGauge Systems LLC
+
+OUI:F83094*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Telecom Limited
+
+OUI:F8313E*
+ ID_OUI_FROM_DATABASE=endeavour GmbH
+
+OUI:F83376*
+ ID_OUI_FROM_DATABASE=Good Mind Innovation Co., Ltd.
+
+OUI:F83553*
+ ID_OUI_FROM_DATABASE=Magenta Research Ltd.
+
+OUI:F83DFF*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
+OUI:F8462D*
+ ID_OUI_FROM_DATABASE=SYNTEC Incorporation
+
+OUI:F8472D*
+ ID_OUI_FROM_DATABASE=X2gen Digital Corp. Ltd
+
+OUI:F84897*
+ ID_OUI_FROM_DATABASE=Hitachi, Ltd.
+
+OUI:F85063*
+ ID_OUI_FROM_DATABASE=Verathon
+
+OUI:F852DF*
+ ID_OUI_FROM_DATABASE=VNL Europe AB
+
+OUI:F85F2A*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:F866F2*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
+
+OUI:F86971*
+ ID_OUI_FROM_DATABASE=Seibu Electric Co.,
+
+OUI:F86ECF*
+ ID_OUI_FROM_DATABASE=Arcx Inc
+
+OUI:F871FE*
+ ID_OUI_FROM_DATABASE=The Goldman Sachs Group, Inc.
+
+OUI:F8769B*
+ ID_OUI_FROM_DATABASE=Neopis Co., Ltd.
+
+OUI:F87B62*
+ ID_OUI_FROM_DATABASE=FASTWEL INTERNATIONAL CO., LTD. Taiwan Branch
+
+OUI:F87B7A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility, Inc.
+
+OUI:F87B8C*
+ ID_OUI_FROM_DATABASE=Amped Wireless
+
+OUI:F8811A*
+ ID_OUI_FROM_DATABASE=OVERKIZ
+
+OUI:F88C1C*
+ ID_OUI_FROM_DATABASE=KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING
+
+OUI:F88DEF*
+ ID_OUI_FROM_DATABASE=Tenebraex
+
+OUI:F88E85*
+ ID_OUI_FROM_DATABASE=COMTREND CORPORATION
+
+OUI:F88FCA*
+ ID_OUI_FROM_DATABASE=Google Fiber, Inc
+
+OUI:F8912A*
+ ID_OUI_FROM_DATABASE=GLP German Light Products GmbH
+
+OUI:F893F3*
+ ID_OUI_FROM_DATABASE=VOLANS
+
+OUI:F897CF*
+ ID_OUI_FROM_DATABASE=DAESHIN-INFORMATION TECHNOLOGY CO., LTD.
+
+OUI:F89955*
+ ID_OUI_FROM_DATABASE=Fortress Technology Inc
+
+OUI:F89D0D*
+ ID_OUI_FROM_DATABASE=Control Technology Inc.
+
+OUI:F8A03D*
+ ID_OUI_FROM_DATABASE=Dinstar Technologies Co., Ltd.
+
+OUI:F8A9DE*
+ ID_OUI_FROM_DATABASE=PUISSANCE PLUS
+
+OUI:F8AA8A*
+ ID_OUI_FROM_DATABASE=Axview Technology (Shenzhen) Co.,Ltd
+
+OUI:F8AC6D*
+ ID_OUI_FROM_DATABASE=Deltenna Ltd
+
+OUI:F8B599*
+ ID_OUI_FROM_DATABASE=Guangzhou CHNAVS Digital Technology Co.,Ltd
+
+OUI:F8C001*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:F8C091*
+ ID_OUI_FROM_DATABASE=Highgates Technology
+
+OUI:F8C678*
+ ID_OUI_FROM_DATABASE=Carefusion
+
+OUI:F8D0AC*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+
+OUI:F8D0BD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F8D111*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:F8D3A9*
+ ID_OUI_FROM_DATABASE=AXAN Networks
+
+OUI:F8D462*
+ ID_OUI_FROM_DATABASE=Pumatronix Equipamentos Eletronicos Ltda.
+
+OUI:F8D756*
+ ID_OUI_FROM_DATABASE=Simm Tronic Limited
+
+OUI:F8D7BF*
+ ID_OUI_FROM_DATABASE=REV Ritter GmbH
+
+OUI:F8DAE2*
+ ID_OUI_FROM_DATABASE=Beta LaserMike
+
+OUI:F8DAF4*
+ ID_OUI_FROM_DATABASE=Taishan Online Technology Co., Ltd.
+
+OUI:F8DB4C*
+ ID_OUI_FROM_DATABASE=PNY Technologies, INC.
+
+OUI:F8DB7F*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:F8DC7A*
+ ID_OUI_FROM_DATABASE=Variscite LTD
+
+OUI:F8DFA8*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:F8E4FB*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:F8E7B5*
+ ID_OUI_FROM_DATABASE=µTech Engenharia e Automação LTDA
+
+OUI:F8E968*
+ ID_OUI_FROM_DATABASE=Egker Kft.
+
+OUI:F8EA0A*
+ ID_OUI_FROM_DATABASE=Dipl.-Math. Michael Rauch
+
+OUI:F8EDA5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F8F014*
+ ID_OUI_FROM_DATABASE=RackWare Inc.
+
+OUI:F8F082*
+ ID_OUI_FROM_DATABASE=NAG LLC
+
+OUI:F8F25A*
+ ID_OUI_FROM_DATABASE=G-Lab GmbH
+
+OUI:F8F7D3*
+ ID_OUI_FROM_DATABASE=International Communications Corporation
+
+OUI:F8F7FF*
+ ID_OUI_FROM_DATABASE=SYN-TECH SYSTEMS INC
+
+OUI:F8FB2F*
+ ID_OUI_FROM_DATABASE=Santur Corporation
+
+OUI:F8FE5C*
+ ID_OUI_FROM_DATABASE=Reciprocal Labs Corp
+
+OUI:FC0012*
+ ID_OUI_FROM_DATABASE=Toshiba Samsung Storage Technolgoy Korea Corporation
+
+OUI:FC01CD*
+ ID_OUI_FROM_DATABASE=FUNDACION TEKNIKER
+
+OUI:FC0647*
+ ID_OUI_FROM_DATABASE=Cortland Research, LLC
+
+OUI:FC0877*
+ ID_OUI_FROM_DATABASE=Prentke Romich Company
+
+OUI:FC0A81*
+ ID_OUI_FROM_DATABASE=Motorola Solutions Inc.
+
+OUI:FC0FE6*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+
+OUI:FC10BD*
+ ID_OUI_FROM_DATABASE=Control Sistematizado S.A.
+
+OUI:FC1794*
+ ID_OUI_FROM_DATABASE=InterCreative Co., Ltd
+
+OUI:FC1D59*
+ ID_OUI_FROM_DATABASE=I Smart Cities HK Ltd
+
+OUI:FC1F19*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD.
+
+OUI:FC1FC0*
+ ID_OUI_FROM_DATABASE=EURECAM
+
+OUI:FC253F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:FC2A54*
+ ID_OUI_FROM_DATABASE=connected data
+
+OUI:FC2E2D*
+ ID_OUI_FROM_DATABASE=Lorom Industrial Co.LTD.
+
+OUI:FC2F40*
+ ID_OUI_FROM_DATABASE=Calxeda, Inc.
+
+OUI:FC3598*
+ ID_OUI_FROM_DATABASE=Favite Inc.
+
+OUI:FC4463*
+ ID_OUI_FROM_DATABASE=Universal Audio
+
+OUI:FC455F*
+ ID_OUI_FROM_DATABASE=JIANGXI SHANSHUI OPTOELECTRONIC TECHNOLOGY CO.,LTD
+
+OUI:FC48EF*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:FC4DD4*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd.
+
+OUI:FC5090*
+ ID_OUI_FROM_DATABASE=SIMEX Sp. z o.o.
+
+OUI:FC52CE*
+ ID_OUI_FROM_DATABASE=Control iD
+
+OUI:FC5B24*
+ ID_OUI_FROM_DATABASE=Weibel Scientific A/S
+
+OUI:FC5B26*
+ ID_OUI_FROM_DATABASE=MikroBits
+
+OUI:FC6198*
+ ID_OUI_FROM_DATABASE=NEC Personal Products, Ltd
+
+OUI:FC626E*
+ ID_OUI_FROM_DATABASE=Beijing MDC Telecom
+
+OUI:FC683E*
+ ID_OUI_FROM_DATABASE=Directed Perception, Inc
+
+OUI:FC6C31*
+ ID_OUI_FROM_DATABASE=LXinstruments GmbH
+
+OUI:FC7516*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:FC75E6*
+ ID_OUI_FROM_DATABASE=Handreamnet
+
+OUI:FC7CE7*
+ ID_OUI_FROM_DATABASE=FCI USA LLC
+
+OUI:FC8329*
+ ID_OUI_FROM_DATABASE=Trei technics
+
+OUI:FC8399*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:FC8E7E*
+ ID_OUI_FROM_DATABASE=Pace plc
+
+OUI:FC8FC4*
+ ID_OUI_FROM_DATABASE=Intelligent Technology Inc.
+
+OUI:FC946C*
+ ID_OUI_FROM_DATABASE=UBIVELOX
+
+OUI:FC94E3*
+ ID_OUI_FROM_DATABASE=Technicolor USA Inc.
+
+OUI:FC9947*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:FC9FAE*
+ ID_OUI_FROM_DATABASE=Fidus Systems Inc
+
+OUI:FCA13E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics
+
+OUI:FCA841*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
+OUI:FCA9B0*
+ ID_OUI_FROM_DATABASE=MIARTECH (SHANGHAI),INC.
+
+OUI:FCAD0F*
+ ID_OUI_FROM_DATABASE=QTS NETWORKS
+
+OUI:FCAF6A*
+ ID_OUI_FROM_DATABASE=Conemtech AB
+
+OUI:FCC23D*
+ ID_OUI_FROM_DATABASE=Atmel Corporation
+
+OUI:FCC734*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:FCC897*
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+OUI:FCCCE4*
+ ID_OUI_FROM_DATABASE=Ascon Ltd.
+
+OUI:FCCF62*
+ ID_OUI_FROM_DATABASE=IBM Corp
+
+OUI:FCD4F2*
+ ID_OUI_FROM_DATABASE=The Coca Cola Company
+
+OUI:FCD4F6*
+ ID_OUI_FROM_DATABASE=Messana Air.Ray Conditioning s.r.l.
+
+OUI:FCD6BD*
+ ID_OUI_FROM_DATABASE=Robert Bosch GmbH
+
+OUI:FCE192*
+ ID_OUI_FROM_DATABASE=Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd
+
+OUI:FCE23F*
+ ID_OUI_FROM_DATABASE=CLAY PAKY SPA
+
+OUI:FCE557*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:FCE892*
+ ID_OUI_FROM_DATABASE=Hangzhou Lancable Technology Co.,Ltd
+
+OUI:FCEDB9*
+ ID_OUI_FROM_DATABASE=Arrayent
+
+OUI:FCF1CD*
+ ID_OUI_FROM_DATABASE=OPTEX-FA CO.,LTD.
+
+OUI:FCF528*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:FCF8AE*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:FCFAF7*
+ ID_OUI_FROM_DATABASE=Shanghai Baud Data Communication Co.,Ltd.
+
+OUI:FCFBFB*
+ ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb
new file mode 100644 (file)
index 0000000..09fc3bd
--- /dev/null
@@ -0,0 +1,6596 @@
+# This file is part of systemd.
+#
+# Data imported from:
+#  http://download.microsoft.com/download/7/E/7/7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2/ISA_PNPID_List.xlsx
+# Non-unique, duplicate assignements manually removed.
+
+acpi:AAA*:
+ ID_VENDOR_FROM_DATABASE=Avolites Ltd
+
+acpi:AAE*:
+ ID_VENDOR_FROM_DATABASE=Anatek Electronics Inc.
+
+acpi:AAT*:
+ ID_VENDOR_FROM_DATABASE=Ann Arbor Technologies
+
+acpi:ABA*:
+ ID_VENDOR_FROM_DATABASE=ABBAHOME INC.
+
+acpi:ABC*:
+ ID_VENDOR_FROM_DATABASE=AboCom System Inc
+
+acpi:ABD*:
+ ID_VENDOR_FROM_DATABASE=Allen Bradley Company
+
+acpi:ABE*:
+ ID_VENDOR_FROM_DATABASE=Alcatel Bell
+
+acpi:ABO*:
+ ID_VENDOR_FROM_DATABASE=D-Link Systems Inc
+
+acpi:ABT*:
+ ID_VENDOR_FROM_DATABASE=Anchor Bay Technologies, Inc.
+
+acpi:ABV*:
+ ID_VENDOR_FROM_DATABASE=Advanced Research Technology
+
+acpi:ACA*:
+ ID_VENDOR_FROM_DATABASE=Ariel Corporation
+
+acpi:ACB*:
+ ID_VENDOR_FROM_DATABASE=Aculab Ltd
+
+acpi:ACC*:
+ ID_VENDOR_FROM_DATABASE=Accton Technology Corporation
+
+acpi:ACD*:
+ ID_VENDOR_FROM_DATABASE=AWETA BV
+
+acpi:ACE*:
+ ID_VENDOR_FROM_DATABASE=Actek Engineering Pty Ltd
+
+acpi:ACG*:
+ ID_VENDOR_FROM_DATABASE=A&R Cambridge Ltd
+
+acpi:ACH*:
+ ID_VENDOR_FROM_DATABASE=Archtek Telecom Corporation
+
+acpi:ACI*:
+ ID_VENDOR_FROM_DATABASE=Ancor Communications Inc
+
+acpi:ACK*:
+ ID_VENDOR_FROM_DATABASE=Acksys
+
+acpi:ACL*:
+ ID_VENDOR_FROM_DATABASE=Apricot Computers
+
+acpi:ACM*:
+ ID_VENDOR_FROM_DATABASE=Acroloop Motion Control Systems Inc
+
+acpi:ACO*:
+ ID_VENDOR_FROM_DATABASE=Allion Computer Inc.
+
+acpi:ACP[0-9A-F]*:
+ ID_VENDOR_FROM_DATABASE=Aspen Tech Inc
+
+acpi:ACR*:
+ ID_VENDOR_FROM_DATABASE=Acer Technologies
+
+acpi:ACS*:
+ ID_VENDOR_FROM_DATABASE=Altos Computer Systems
+
+acpi:ACT*:
+ ID_VENDOR_FROM_DATABASE=Applied Creative Technology
+
+acpi:ACU*:
+ ID_VENDOR_FROM_DATABASE=Acculogic
+
+acpi:ACV*:
+ ID_VENDOR_FROM_DATABASE=ActivCard S.A
+
+acpi:ADA*:
+ ID_VENDOR_FROM_DATABASE=Addi-Data GmbH
+
+acpi:ADB*:
+ ID_VENDOR_FROM_DATABASE=Aldebbaron
+
+acpi:ADC*:
+ ID_VENDOR_FROM_DATABASE=Acnhor Datacomm
+
+acpi:ADD*:
+ ID_VENDOR_FROM_DATABASE=Advanced Peripheral Devices Inc
+
+acpi:ADE*:
+ ID_VENDOR_FROM_DATABASE=Arithmos, Inc.
+
+acpi:ADH*:
+ ID_VENDOR_FROM_DATABASE=Aerodata Holdings Ltd
+
+acpi:ADI*:
+ ID_VENDOR_FROM_DATABASE=ADI Systems Inc
+
+acpi:ADK*:
+ ID_VENDOR_FROM_DATABASE=Adtek System Science Company Ltd
+
+acpi:ADL*:
+ ID_VENDOR_FROM_DATABASE=ASTRA Security Products Ltd
+
+acpi:ADM*:
+ ID_VENDOR_FROM_DATABASE=Ad Lib MultiMedia Inc
+
+acpi:ADN*:
+ ID_VENDOR_FROM_DATABASE=Analog & Digital Devices Tel. Inc
+
+acpi:ADP*:
+ ID_VENDOR_FROM_DATABASE=Adaptec Inc
+
+acpi:ADR*:
+ ID_VENDOR_FROM_DATABASE=Nasa Ames Research Center
+
+acpi:ADS*:
+ ID_VENDOR_FROM_DATABASE=Analog Devices Inc
+
+acpi:ADT*:
+ ID_VENDOR_FROM_DATABASE=Aved Display Technologies
+
+acpi:ADV*:
+ ID_VENDOR_FROM_DATABASE=Advanced Micro Devices Inc
+
+acpi:ADX*:
+ ID_VENDOR_FROM_DATABASE=Adax Inc
+
+acpi:AEC*:
+ ID_VENDOR_FROM_DATABASE=Antex Electronics Corporation
+
+acpi:AED*:
+ ID_VENDOR_FROM_DATABASE=Advanced Electronic Designs, Inc.
+
+acpi:AEI*:
+ ID_VENDOR_FROM_DATABASE=Actiontec Electric Inc
+
+acpi:AEJ*:
+ ID_VENDOR_FROM_DATABASE=Alpha Electronics Company
+
+acpi:AEM*:
+ ID_VENDOR_FROM_DATABASE=ASEM S.p.A.
+
+acpi:AEN*:
+ ID_VENDOR_FROM_DATABASE=Avencall
+
+acpi:AEP*:
+ ID_VENDOR_FROM_DATABASE=Aetas Peripheral International
+
+acpi:AET*:
+ ID_VENDOR_FROM_DATABASE=Aethra Telecomunicazioni S.r.l.
+
+acpi:AFA*:
+ ID_VENDOR_FROM_DATABASE=Alfa Inc
+
+acpi:AGC*:
+ ID_VENDOR_FROM_DATABASE=Beijing Aerospace Golden Card Electronic Engineering Co.,Ltd.
+
+acpi:AGI*:
+ ID_VENDOR_FROM_DATABASE=Artish Graphics Inc
+
+acpi:AGL*:
+ ID_VENDOR_FROM_DATABASE=Argolis
+
+acpi:AGM*:
+ ID_VENDOR_FROM_DATABASE=Advan Int'l Corporation
+
+acpi:AGT*:
+ ID_VENDOR_FROM_DATABASE=Agilent Technologies
+
+acpi:AHC*:
+ ID_VENDOR_FROM_DATABASE=Advantech Co., Ltd.
+
+acpi:AIC*:
+ ID_VENDOR_FROM_DATABASE=Arnos Insturments & Computer Systems
+
+acpi:AIE*:
+ ID_VENDOR_FROM_DATABASE=Altmann Industrieelektronik
+
+acpi:AII*:
+ ID_VENDOR_FROM_DATABASE=Amptron International Inc.
+
+acpi:AIL*:
+ ID_VENDOR_FROM_DATABASE=Altos India Ltd
+
+acpi:AIM*:
+ ID_VENDOR_FROM_DATABASE=AIMS Lab Inc
+
+acpi:AIR*:
+ ID_VENDOR_FROM_DATABASE=Advanced Integ. Research Inc
+
+acpi:AIS*:
+ ID_VENDOR_FROM_DATABASE=Alien Internet Services
+
+acpi:AIW*:
+ ID_VENDOR_FROM_DATABASE=Aiwa Company Ltd
+
+acpi:AIX*:
+ ID_VENDOR_FROM_DATABASE=ALTINEX, INC.
+
+acpi:AJA*:
+ ID_VENDOR_FROM_DATABASE=AJA Video Systems, Inc.
+
+acpi:AKB*:
+ ID_VENDOR_FROM_DATABASE=Akebia Ltd
+
+acpi:AKE*:
+ ID_VENDOR_FROM_DATABASE=AKAMI Electric Co.,Ltd
+
+acpi:AKI*:
+ ID_VENDOR_FROM_DATABASE=AKIA Corporation
+
+acpi:AKL*:
+ ID_VENDOR_FROM_DATABASE=AMiT Ltd
+
+acpi:AKM*:
+ ID_VENDOR_FROM_DATABASE=Asahi Kasei Microsystems Company Ltd
+
+acpi:AKP*:
+ ID_VENDOR_FROM_DATABASE=Atom Komplex Prylad
+
+acpi:AKY*:
+ ID_VENDOR_FROM_DATABASE=Askey Computer Corporation
+
+acpi:ALA*:
+ ID_VENDOR_FROM_DATABASE=Alacron Inc
+
+acpi:ALC*:
+ ID_VENDOR_FROM_DATABASE=Altec Corporation
+
+acpi:ALD*:
+ ID_VENDOR_FROM_DATABASE=In4S Inc
+
+acpi:ALG*:
+ ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp.
+
+acpi:ALH*:
+ ID_VENDOR_FROM_DATABASE=AL Systems
+
+acpi:ALI*:
+ ID_VENDOR_FROM_DATABASE=Acer Labs
+
+acpi:ALJ*:
+ ID_VENDOR_FROM_DATABASE=Altec Lansing
+
+acpi:ALK*:
+ ID_VENDOR_FROM_DATABASE=Acrolink Inc
+
+acpi:ALL*:
+ ID_VENDOR_FROM_DATABASE=Alliance Semiconductor Corporation
+
+acpi:ALM*:
+ ID_VENDOR_FROM_DATABASE=Acutec Ltd.
+
+acpi:ALN*:
+ ID_VENDOR_FROM_DATABASE=Alana Technologies
+
+acpi:ALO*:
+ ID_VENDOR_FROM_DATABASE=Algolith Inc.
+
+acpi:ALP*:
+ ID_VENDOR_FROM_DATABASE=Alps Electric Company Ltd
+
+acpi:ALR*:
+ ID_VENDOR_FROM_DATABASE=Advanced Logic
+
+acpi:ALS*:
+ ID_VENDOR_FROM_DATABASE=Avance Logic Inc
+
+acpi:ALT*:
+ ID_VENDOR_FROM_DATABASE=Altra
+
+acpi:ALV*:
+ ID_VENDOR_FROM_DATABASE=AlphaView LCD
+
+acpi:ALX*:
+ ID_VENDOR_FROM_DATABASE=ALEXON Co.,Ltd.
+
+acpi:AMA*:
+ ID_VENDOR_FROM_DATABASE=Asia Microelectronic Development Inc
+
+acpi:AMB*:
+ ID_VENDOR_FROM_DATABASE=Ambient Technologies, Inc.
+
+acpi:AMC*:
+ ID_VENDOR_FROM_DATABASE=Attachmate Corporation
+
+acpi:AMD*:
+ ID_VENDOR_FROM_DATABASE=Amdek Corporation
+
+acpi:AMI*:
+ ID_VENDOR_FROM_DATABASE=American Megatrends Inc
+
+acpi:AML*:
+ ID_VENDOR_FROM_DATABASE=Anderson Multimedia Communications (HK) Limited
+
+acpi:AMN*:
+ ID_VENDOR_FROM_DATABASE=Amimon LTD.
+
+acpi:AMO*:
+ ID_VENDOR_FROM_DATABASE=Amino Technologies PLC and Amino Communications Limited
+
+acpi:AMP*:
+ ID_VENDOR_FROM_DATABASE=AMP Inc
+
+acpi:AMS *:
+ ID_VENDOR_FROM_DATABASE=ARMSTEL, Inc.
+
+acpi:AMT*:
+ ID_VENDOR_FROM_DATABASE=AMT International Industry
+
+acpi:AMX*:
+ ID_VENDOR_FROM_DATABASE=AMX LLC
+
+acpi:ANA*:
+ ID_VENDOR_FROM_DATABASE=Anakron
+
+acpi:ANC*:
+ ID_VENDOR_FROM_DATABASE=Ancot
+
+acpi:AND*:
+ ID_VENDOR_FROM_DATABASE=Adtran Inc
+
+acpi:ANI*:
+ ID_VENDOR_FROM_DATABASE=Anigma Inc
+
+acpi:ANK*:
+ ID_VENDOR_FROM_DATABASE=Anko Electronic Company Ltd
+
+acpi:ANL*:
+ ID_VENDOR_FROM_DATABASE=Analogix Semiconductor, Inc
+
+acpi:ANO*:
+ ID_VENDOR_FROM_DATABASE=Anorad Corporation
+
+acpi:ANP*:
+ ID_VENDOR_FROM_DATABASE=Andrew Network Production
+
+acpi:ANR*:
+ ID_VENDOR_FROM_DATABASE=ANR Ltd
+
+acpi:ANS*:
+ ID_VENDOR_FROM_DATABASE=Ansel Communication Company
+
+acpi:ANT*:
+ ID_VENDOR_FROM_DATABASE=Ace CAD Enterprise Company Ltd
+
+acpi:ANX*:
+ ID_VENDOR_FROM_DATABASE=Acer Netxus Inc
+
+acpi:AOA*:
+ ID_VENDOR_FROM_DATABASE=AOpen Inc.
+
+acpi:AOE*:
+ ID_VENDOR_FROM_DATABASE=Advanced Optics Electronics, Inc.
+
+acpi:AOL*:
+ ID_VENDOR_FROM_DATABASE=America OnLine
+
+acpi:AOT*:
+ ID_VENDOR_FROM_DATABASE=Alcatel
+
+acpi:APC*:
+ ID_VENDOR_FROM_DATABASE=American Power Conversion
+
+acpi:APD*:
+ ID_VENDOR_FROM_DATABASE=AppliAdata
+
+acpi:APG*:
+ ID_VENDOR_FROM_DATABASE=Horner Electric Inc
+
+acpi:API*:
+ ID_VENDOR_FROM_DATABASE=A Plus Info Corporation
+
+acpi:APL*:
+ ID_VENDOR_FROM_DATABASE=Aplicom Oy
+
+acpi:APM*:
+ ID_VENDOR_FROM_DATABASE=Applied Memory Tech
+
+acpi:APN*:
+ ID_VENDOR_FROM_DATABASE=Appian Tech Inc
+
+acpi:APP*:
+ ID_VENDOR_FROM_DATABASE=Apple Computer Inc
+
+acpi:APR*:
+ ID_VENDOR_FROM_DATABASE=Aprilia s.p.a.
+
+acpi:APS*:
+ ID_VENDOR_FROM_DATABASE=Autologic Inc
+
+acpi:APT*:
+ ID_VENDOR_FROM_DATABASE=Audio Processing Technology Ltd
+
+acpi:APV*:
+ ID_VENDOR_FROM_DATABASE=A+V Link
+
+acpi:APX*:
+ ID_VENDOR_FROM_DATABASE=AP Designs Ltd
+
+acpi:ARC*:
+ ID_VENDOR_FROM_DATABASE=Alta Research Corporation
+
+acpi:ARE*:
+ ID_VENDOR_FROM_DATABASE=ICET S.p.A.
+
+acpi:ARG*:
+ ID_VENDOR_FROM_DATABASE=Argus Electronics Co., LTD
+
+acpi:ARI*:
+ ID_VENDOR_FROM_DATABASE=Argosy Research Inc
+
+acpi:ARK*:
+ ID_VENDOR_FROM_DATABASE=Ark Logic Inc
+
+acpi:ARL*:
+ ID_VENDOR_FROM_DATABASE=Arlotto Comnet Inc
+
+acpi:ARM*:
+ ID_VENDOR_FROM_DATABASE=Arima
+
+acpi:ARO*:
+ ID_VENDOR_FROM_DATABASE=Poso International B.V.
+
+acpi:ARS*:
+ ID_VENDOR_FROM_DATABASE=Arescom Inc
+
+acpi:ART*:
+ ID_VENDOR_FROM_DATABASE=Corion Industrial Corporation
+
+acpi:ASC*:
+ ID_VENDOR_FROM_DATABASE=Ascom Strategic Technology Unit
+
+acpi:ASD*:
+ ID_VENDOR_FROM_DATABASE=USC Information Sciences Institute
+
+acpi:ASE*:
+ ID_VENDOR_FROM_DATABASE=AseV Display Labs
+
+acpi:ASI*:
+ ID_VENDOR_FROM_DATABASE=Ahead Systems
+
+acpi:ASK*:
+ ID_VENDOR_FROM_DATABASE=Ask A/S
+
+acpi:ASL*:
+ ID_VENDOR_FROM_DATABASE=AccuScene Corporation Ltd
+
+acpi:ASM*:
+ ID_VENDOR_FROM_DATABASE=ASEM S.p.A.
+
+acpi:ASN*:
+ ID_VENDOR_FROM_DATABASE=Asante Tech Inc
+
+acpi:ASP*:
+ ID_VENDOR_FROM_DATABASE=ASP Microelectronics Ltd
+
+acpi:AST*:
+ ID_VENDOR_FROM_DATABASE=AST Research Inc
+
+acpi:ASU*:
+ ID_VENDOR_FROM_DATABASE=Asuscom Network Inc
+
+acpi:ASX*:
+ ID_VENDOR_FROM_DATABASE=AudioScience
+
+acpi:ASY*:
+ ID_VENDOR_FROM_DATABASE=Rockwell Collins / Airshow Systems
+
+acpi:ATA*:
+ ID_VENDOR_FROM_DATABASE=Allied Telesyn International (Asia) Pte Ltd
+
+acpi:ATC*:
+ ID_VENDOR_FROM_DATABASE=Ably-Tech Corporation
+
+acpi:ATD*:
+ ID_VENDOR_FROM_DATABASE=Alpha Telecom Inc
+
+acpi:ATE*:
+ ID_VENDOR_FROM_DATABASE=Innovate Ltd
+
+acpi:ATH*:
+ ID_VENDOR_FROM_DATABASE=Athena Informatica S.R.L.
+
+acpi:ATI*:
+ ID_VENDOR_FROM_DATABASE=Allied Telesis KK
+
+acpi:ATK*:
+ ID_VENDOR_FROM_DATABASE=Allied Telesyn Int'l
+
+acpi:ATL*:
+ ID_VENDOR_FROM_DATABASE=Arcus Technology Ltd
+
+acpi:ATM*:
+ ID_VENDOR_FROM_DATABASE=ATM Ltd
+
+acpi:ATN*:
+ ID_VENDOR_FROM_DATABASE=Athena Smartcard Solutions Ltd.
+
+acpi:ATO*:
+ ID_VENDOR_FROM_DATABASE=ASTRO DESIGN, INC.
+
+acpi:ATP*:
+ ID_VENDOR_FROM_DATABASE=Alpha-Top Corporation
+
+acpi:ATT*:
+ ID_VENDOR_FROM_DATABASE=AT&T
+
+acpi:ATV*:
+ ID_VENDOR_FROM_DATABASE=Office Depot, Inc.
+
+acpi:ATX*:
+ ID_VENDOR_FROM_DATABASE=Athenix Corporation
+
+acpi:AUI*:
+ ID_VENDOR_FROM_DATABASE=Alps Electric Inc
+
+acpi:AUR*:
+ ID_VENDOR_FROM_DATABASE=Aureal Semiconductor
+
+acpi:AUT*:
+ ID_VENDOR_FROM_DATABASE=Autotime Corporation
+
+acpi:AVA*:
+ ID_VENDOR_FROM_DATABASE=Avaya Communication
+
+acpi:AVC*:
+ ID_VENDOR_FROM_DATABASE=Auravision Corporation
+
+acpi:AVD*:
+ ID_VENDOR_FROM_DATABASE=Avid Electronics Corporation
+
+acpi:AVE*:
+ ID_VENDOR_FROM_DATABASE=Add Value Enterpises (Asia) Pte Ltd
+
+acpi:AVI*:
+ ID_VENDOR_FROM_DATABASE=Nippon Avionics Co.,Ltd
+
+acpi:AVL*:
+ ID_VENDOR_FROM_DATABASE=Avalue Technology Inc.
+
+acpi:AVM*:
+ ID_VENDOR_FROM_DATABASE=AVM GmbH
+
+acpi:AVN *:
+ ID_VENDOR_FROM_DATABASE=Advance Computer Corporation
+
+acpi:AVO*:
+ ID_VENDOR_FROM_DATABASE=Avocent Corporation
+
+acpi:AVR*:
+ ID_VENDOR_FROM_DATABASE=AVer Information Inc.
+
+acpi:AVT*:
+ ID_VENDOR_FROM_DATABASE=Avtek (Electronics) Pty Ltd
+
+acpi:AVV*:
+ ID_VENDOR_FROM_DATABASE=SBS Technologies (Canada), Inc. (was Avvida Systems, Inc.)
+
+acpi:AWC*:
+ ID_VENDOR_FROM_DATABASE=Access Works Comm Inc
+
+acpi:AWL*:
+ ID_VENDOR_FROM_DATABASE=Aironet Wireless Communications, Inc
+
+acpi:AWS*:
+ ID_VENDOR_FROM_DATABASE=Wave Systems
+
+acpi:AXB*:
+ ID_VENDOR_FROM_DATABASE=Adrienne Electronics Corporation
+
+acpi:AXC*:
+ ID_VENDOR_FROM_DATABASE=AXIOMTEK CO., LTD.
+
+acpi:AXE*:
+ ID_VENDOR_FROM_DATABASE=D-Link Systems Inc (used as 2nd pnpid)
+
+acpi:AXI*:
+ ID_VENDOR_FROM_DATABASE=American Magnetics
+
+acpi:AXL*:
+ ID_VENDOR_FROM_DATABASE=Axel
+
+acpi:AXO*:
+ ID_VENDOR_FROM_DATABASE=Axonic Labs LLC
+
+acpi:AXP*:
+ ID_VENDOR_FROM_DATABASE=American Express
+
+acpi:AXT*:
+ ID_VENDOR_FROM_DATABASE=Axtend Technologies Inc
+
+acpi:AXX*:
+ ID_VENDOR_FROM_DATABASE=Axxon Computer Corporation
+
+acpi:AXY*:
+ ID_VENDOR_FROM_DATABASE=AXYZ Automation Services, Inc
+
+acpi:AYD*:
+ ID_VENDOR_FROM_DATABASE=Aydin Displays
+
+acpi:AYR*:
+ ID_VENDOR_FROM_DATABASE=Airlib, Inc
+
+acpi:AZM*:
+ ID_VENDOR_FROM_DATABASE=AZ Middelheim - Radiotherapy
+
+acpi:AZT*:
+ ID_VENDOR_FROM_DATABASE=Aztech Systems Ltd
+
+acpi:BAC*:
+ ID_VENDOR_FROM_DATABASE=Biometric Access Corporation
+
+acpi:BAN*:
+ ID_VENDOR_FROM_DATABASE=Banyan
+
+acpi:BBB*:
+ ID_VENDOR_FROM_DATABASE=an-najah university
+
+acpi:BBH*:
+ ID_VENDOR_FROM_DATABASE=B&Bh
+
+acpi:BBL*:
+ ID_VENDOR_FROM_DATABASE=Brain Boxes Limited
+
+acpi:BCC*:
+ ID_VENDOR_FROM_DATABASE=Beaver Computer Corporaton
+
+acpi:BCD*:
+ ID_VENDOR_FROM_DATABASE=Barco GmbH
+
+acpi:BCM*:
+ ID_VENDOR_FROM_DATABASE=Broadcom
+
+acpi:BCQ*:
+ ID_VENDOR_FROM_DATABASE=Deutsche Telekom Berkom GmbH
+
+acpi:BCS*:
+ ID_VENDOR_FROM_DATABASE=Booria CAD/CAM systems
+
+acpi:BDO*:
+ ID_VENDOR_FROM_DATABASE=Brahler ICS
+
+acpi:BDR*:
+ ID_VENDOR_FROM_DATABASE=Blonder Tongue Labs, Inc.
+
+acpi:BDS*:
+ ID_VENDOR_FROM_DATABASE=Barco Display Systems
+
+acpi:BEC*:
+ ID_VENDOR_FROM_DATABASE=Elektro Beckhoff GmbH
+
+acpi:BEI*:
+ ID_VENDOR_FROM_DATABASE=Beckworth Enterprises Inc
+
+acpi:BEK*:
+ ID_VENDOR_FROM_DATABASE=Beko Elektronik A.S.
+
+acpi:BEL*:
+ ID_VENDOR_FROM_DATABASE=Beltronic Industrieelektronik GmbH
+
+acpi:BEO*:
+ ID_VENDOR_FROM_DATABASE=Baug & Olufsen
+
+acpi:BFE*:
+ ID_VENDOR_FROM_DATABASE=B.F. Engineering Corporation
+
+acpi:BGB*:
+ ID_VENDOR_FROM_DATABASE=Barco Graphics N.V
+
+acpi:BGT*:
+ ID_VENDOR_FROM_DATABASE=Budzetron Inc
+
+acpi:BHZ*:
+ ID_VENDOR_FROM_DATABASE=BitHeadz, Inc.
+
+acpi:BIC*:
+ ID_VENDOR_FROM_DATABASE=Big Island Communications
+
+acpi:BII*:
+ ID_VENDOR_FROM_DATABASE=Boeckeler Instruments Inc
+
+acpi:BIL*:
+ ID_VENDOR_FROM_DATABASE=Billion Electric Company Ltd
+
+acpi:BIO*:
+ ID_VENDOR_FROM_DATABASE=BioLink Technologies International, Inc.
+
+acpi:BIT*:
+ ID_VENDOR_FROM_DATABASE=Bit 3 Computer
+
+acpi:BLI*:
+ ID_VENDOR_FROM_DATABASE=Busicom
+
+acpi:BLN*:
+ ID_VENDOR_FROM_DATABASE=BioLink Technologies
+
+acpi:BLP*:
+ ID_VENDOR_FROM_DATABASE=Bloomberg L.P.
+
+acpi:BMI*:
+ ID_VENDOR_FROM_DATABASE=Benson Medical Instruments Company
+
+acpi:BML*:
+ ID_VENDOR_FROM_DATABASE=BIOMED Lab
+
+acpi:BMS*:
+ ID_VENDOR_FROM_DATABASE=BIOMEDISYS
+
+acpi:BNE*:
+ ID_VENDOR_FROM_DATABASE=Bull AB
+
+acpi:BNK*:
+ ID_VENDOR_FROM_DATABASE=Banksia Tech Pty Ltd
+
+acpi:BNO*:
+ ID_VENDOR_FROM_DATABASE=Bang & Olufsen
+
+acpi:BNS*:
+ ID_VENDOR_FROM_DATABASE=Boulder Nonlinear Systems
+
+acpi:BOB*:
+ ID_VENDOR_FROM_DATABASE=Rainy Orchard
+
+acpi:BOE*:
+ ID_VENDOR_FROM_DATABASE=BOE
+
+acpi:BOI*:
+ ID_VENDOR_FROM_DATABASE=NINGBO BOIGLE DIGITAL TECHNOLOGY CO.,LTD
+
+acpi:BOS*:
+ ID_VENDOR_FROM_DATABASE=BOS
+
+acpi:BPD*:
+ ID_VENDOR_FROM_DATABASE=Micro Solutions, Inc.
+
+acpi:BPU*:
+ ID_VENDOR_FROM_DATABASE=Best Power
+
+acpi:BRA*:
+ ID_VENDOR_FROM_DATABASE=Braemac Pty Ltd
+
+acpi:BRC*:
+ ID_VENDOR_FROM_DATABASE=BARC
+
+acpi:BRG*:
+ ID_VENDOR_FROM_DATABASE=Bridge Information Co., Ltd
+
+acpi:BRI*:
+ ID_VENDOR_FROM_DATABASE=Boca Research Inc
+
+acpi:BRM*:
+ ID_VENDOR_FROM_DATABASE=Braemar Inc
+
+acpi:BRO*:
+ ID_VENDOR_FROM_DATABASE=BROTHER INDUSTRIES,LTD.
+
+acpi:BSE*:
+ ID_VENDOR_FROM_DATABASE=Bose Corporation
+
+acpi:BSL*:
+ ID_VENDOR_FROM_DATABASE=Biomedical Systems Laboratory
+
+acpi:BSN*:
+ ID_VENDOR_FROM_DATABASE=BRIGHTSIGN, LLC
+
+acpi:BST*:
+ ID_VENDOR_FROM_DATABASE=BodySound Technologies, Inc.
+
+acpi:BTC*:
+ ID_VENDOR_FROM_DATABASE=Bit 3 Computer
+
+acpi:BTE*:
+ ID_VENDOR_FROM_DATABASE=Brilliant Technology
+
+acpi:BTF*:
+ ID_VENDOR_FROM_DATABASE=Bitfield Oy
+
+acpi:BTI*:
+ ID_VENDOR_FROM_DATABASE=BusTech Inc
+
+acpi:BTO*:
+ ID_VENDOR_FROM_DATABASE=BioTao Ltd
+
+acpi:BUF*:
+ ID_VENDOR_FROM_DATABASE=Yasuhiko Shirai Melco Inc
+
+acpi:BUG*:
+ ID_VENDOR_FROM_DATABASE=B.U.G., Inc.
+
+acpi:BUJ*:
+ ID_VENDOR_FROM_DATABASE=ATI Tech Inc
+
+acpi:BUL*:
+ ID_VENDOR_FROM_DATABASE=Bull
+
+acpi:BUR*:
+ ID_VENDOR_FROM_DATABASE=Bernecker & Rainer Ind-Eletronik GmbH
+
+acpi:BUS*:
+ ID_VENDOR_FROM_DATABASE=BusTek
+
+acpi:BUT*:
+ ID_VENDOR_FROM_DATABASE=21ST CENTURY ENTERTAINMENT
+
+acpi:BWK*:
+ ID_VENDOR_FROM_DATABASE=Bitworks Inc.
+
+acpi:BXE*:
+ ID_VENDOR_FROM_DATABASE=Buxco Electronics
+
+acpi:BYD*:
+ ID_VENDOR_FROM_DATABASE=byd:sign corporation
+
+acpi:CAA*:
+ ID_VENDOR_FROM_DATABASE=Castles Automation Co., Ltd
+
+acpi:CAC*:
+ ID_VENDOR_FROM_DATABASE=CA & F Elettronica
+
+acpi:CAG*:
+ ID_VENDOR_FROM_DATABASE=CalComp
+
+acpi:CAI*:
+ ID_VENDOR_FROM_DATABASE=Canon Inc.
+
+acpi:CAL*:
+ ID_VENDOR_FROM_DATABASE=Acon
+
+acpi:CAM*:
+ ID_VENDOR_FROM_DATABASE=Cambridge Audio
+
+acpi:CAN*:
+ ID_VENDOR_FROM_DATABASE=Canopus Company Ltd
+
+acpi:CAR*:
+ ID_VENDOR_FROM_DATABASE=Cardinal Company Ltd
+
+acpi:CAS*:
+ ID_VENDOR_FROM_DATABASE=CASIO COMPUTER CO.,LTD
+
+acpi:CAT*:
+ ID_VENDOR_FROM_DATABASE=Consultancy in Advanced Technology
+
+acpi:CAV*:
+ ID_VENDOR_FROM_DATABASE=Cavium Networks, Inc
+
+acpi:CBI*:
+ ID_VENDOR_FROM_DATABASE=ComputerBoards Inc
+
+acpi:CBR*:
+ ID_VENDOR_FROM_DATABASE=Cebra Tech A/S
+
+acpi:CBT*:
+ ID_VENDOR_FROM_DATABASE=Cabletime Ltd
+
+acpi:CBX*:
+ ID_VENDOR_FROM_DATABASE=Cybex Computer Products Corporation
+
+acpi:CCC*:
+ ID_VENDOR_FROM_DATABASE=C-Cube Microsystems
+
+acpi:CCI*:
+ ID_VENDOR_FROM_DATABASE=Cache
+
+acpi:CCJ*:
+ ID_VENDOR_FROM_DATABASE=CONTEC CO.,LTD.
+
+acpi:CCL*:
+ ID_VENDOR_FROM_DATABASE=CCL/ITRI
+
+acpi:CCP*:
+ ID_VENDOR_FROM_DATABASE=Capetronic USA Inc
+
+acpi:CDC*:
+ ID_VENDOR_FROM_DATABASE=Core Dynamics Corporation
+
+acpi:CDD*:
+ ID_VENDOR_FROM_DATABASE=Convergent Data Devices
+
+acpi:CDE*:
+ ID_VENDOR_FROM_DATABASE=Colin.de
+
+acpi:CDG*:
+ ID_VENDOR_FROM_DATABASE=Christie Digital Systems Inc
+
+acpi:CDI*:
+ ID_VENDOR_FROM_DATABASE=Concept Development Inc
+
+acpi:CDK*:
+ ID_VENDOR_FROM_DATABASE=Cray Communications
+
+acpi:CDN*:
+ ID_VENDOR_FROM_DATABASE=Codenoll Technical Corporation
+
+acpi:CDP*:
+ ID_VENDOR_FROM_DATABASE=CalComp
+
+acpi:CDS*:
+ ID_VENDOR_FROM_DATABASE=Computer Diagnostic Systems
+
+acpi:CDT*:
+ ID_VENDOR_FROM_DATABASE=IBM Corporation
+
+acpi:CDV*:
+ ID_VENDOR_FROM_DATABASE=Convergent Design Inc.
+
+acpi:CEA*:
+ ID_VENDOR_FROM_DATABASE=Consumer Electronics Association
+
+acpi:CEC*:
+ ID_VENDOR_FROM_DATABASE=Chicony Electronics Company Ltd
+
+acpi:CED*:
+ ID_VENDOR_FROM_DATABASE=Cambridge Electronic Design Ltd
+
+acpi:CEF*:
+ ID_VENDOR_FROM_DATABASE=Cefar Digital Vision
+
+acpi:CEI*:
+ ID_VENDOR_FROM_DATABASE=Crestron Electronics, Inc.
+
+acpi:CEM*:
+ ID_VENDOR_FROM_DATABASE=MEC Electronics GmbH
+
+acpi:CEN*:
+ ID_VENDOR_FROM_DATABASE=Centurion Technologies P/L
+
+acpi:CEP*:
+ ID_VENDOR_FROM_DATABASE=C-DAC
+
+acpi:CER*:
+ ID_VENDOR_FROM_DATABASE=Ceronix
+
+acpi:CET*:
+ ID_VENDOR_FROM_DATABASE=TEC CORPORATION
+
+acpi:CFG*:
+ ID_VENDOR_FROM_DATABASE=Atlantis
+
+acpi:CGA*:
+ ID_VENDOR_FROM_DATABASE=Chunghwa Picture Tubes, LTD
+
+acpi:CGS*:
+ ID_VENDOR_FROM_DATABASE=Chyron Corp
+
+acpi:CGT*:
+ ID_VENDOR_FROM_DATABASE=congatec AG
+
+acpi:CHA*:
+ ID_VENDOR_FROM_DATABASE=Chase Research PLC
+
+acpi:CHC*:
+ ID_VENDOR_FROM_DATABASE=Chic Technology Corp.
+
+acpi:CHD*:
+ ID_VENDOR_FROM_DATABASE=ChangHong Electric Co.,Ltd
+
+acpi:CHE*:
+ ID_VENDOR_FROM_DATABASE=Acer Inc
+
+acpi:CHG*:
+ ID_VENDOR_FROM_DATABASE=Sichuan Changhong Electric CO, LTD.
+
+acpi:CHI*:
+ ID_VENDOR_FROM_DATABASE=Chrontel Inc
+
+acpi:CHL*:
+ ID_VENDOR_FROM_DATABASE=Chloride-R&D
+
+acpi:CHM*:
+ ID_VENDOR_FROM_DATABASE=CHIC TECHNOLOGY CORP.
+
+acpi:CHO*:
+ ID_VENDOR_FROM_DATABASE=Sichuang Changhong Corporation
+
+acpi:CHP*:
+ ID_VENDOR_FROM_DATABASE=CH Products
+
+acpi:CHS*:
+ ID_VENDOR_FROM_DATABASE=Agentur Chairos
+
+acpi:CHT*:
+ ID_VENDOR_FROM_DATABASE=Chunghwa Picture Tubes,LTD.
+
+acpi:CHY*:
+ ID_VENDOR_FROM_DATABASE=Cherry GmbH
+
+acpi:CIC*:
+ ID_VENDOR_FROM_DATABASE=Comm. Intelligence Corporation
+
+acpi:CII*:
+ ID_VENDOR_FROM_DATABASE=Cromack Industries Inc
+
+acpi:CIL*:
+ ID_VENDOR_FROM_DATABASE=Citicom Infotech Private Limited
+
+acpi:CIN*:
+ ID_VENDOR_FROM_DATABASE=Citron GmbH
+
+acpi:CIP*:
+ ID_VENDOR_FROM_DATABASE=Ciprico Inc
+
+acpi:CIR*:
+ ID_VENDOR_FROM_DATABASE=Cirrus Logic Inc
+
+acpi:CIS*:
+ ID_VENDOR_FROM_DATABASE=Cisco Systems Inc
+
+acpi:CIT*:
+ ID_VENDOR_FROM_DATABASE=Citifax Limited
+
+acpi:CKC*:
+ ID_VENDOR_FROM_DATABASE=The Concept Keyboard Company Ltd
+
+acpi:CKJ*:
+ ID_VENDOR_FROM_DATABASE=Carina System Co., Ltd.
+
+acpi:CLA*:
+ ID_VENDOR_FROM_DATABASE=Clarion Company Ltd
+
+acpi:CLD*:
+ ID_VENDOR_FROM_DATABASE=COMMAT L.t.d.
+
+acpi:CLE*:
+ ID_VENDOR_FROM_DATABASE=Classe Audio
+
+acpi:CLG*:
+ ID_VENDOR_FROM_DATABASE=CoreLogic
+
+acpi:CLI*:
+ ID_VENDOR_FROM_DATABASE=Cirrus Logic Inc
+
+acpi:CLM*:
+ ID_VENDOR_FROM_DATABASE=CrystaLake Multimedia
+
+acpi:CLO*:
+ ID_VENDOR_FROM_DATABASE=Clone Computers
+
+acpi:CLT*:
+ ID_VENDOR_FROM_DATABASE=automated computer control systems
+
+acpi:CLV*:
+ ID_VENDOR_FROM_DATABASE=Clevo Company
+
+acpi:CLX*:
+ ID_VENDOR_FROM_DATABASE=CardLogix
+
+acpi:CMC*:
+ ID_VENDOR_FROM_DATABASE=CMC Ltd
+
+acpi:CMD*:
+ ID_VENDOR_FROM_DATABASE=Colorado MicroDisplay, Inc.
+
+acpi:CMG*:
+ ID_VENDOR_FROM_DATABASE=Chenming Mold Ind. Corp.
+
+acpi:CMI*:
+ ID_VENDOR_FROM_DATABASE=C-Media Electronics
+
+acpi:CMM*:
+ ID_VENDOR_FROM_DATABASE=Comtime GmbH
+
+acpi:CMN*:
+ ID_VENDOR_FROM_DATABASE=Chimei Innolux Corporation
+
+acpi:CMO*:
+ ID_VENDOR_FROM_DATABASE=Chi Mei Optoelectronics corp.
+
+acpi:CMR*:
+ ID_VENDOR_FROM_DATABASE=Cambridge Research Systems Ltd
+
+acpi:CMS*:
+ ID_VENDOR_FROM_DATABASE=CompuMaster Srl
+
+acpi:CMX*:
+ ID_VENDOR_FROM_DATABASE=Comex Electronics AB
+
+acpi:CNB*:
+ ID_VENDOR_FROM_DATABASE=American Power Conversion
+
+acpi:CNC*:
+ ID_VENDOR_FROM_DATABASE=Alvedon Computers Ltd
+
+acpi:CNE*:
+ ID_VENDOR_FROM_DATABASE=Cine-tal
+
+acpi:CNI*:
+ ID_VENDOR_FROM_DATABASE=Connect Int'l A/S
+
+acpi:CNN*:
+ ID_VENDOR_FROM_DATABASE=Canon Inc
+
+acpi:CNT*:
+ ID_VENDOR_FROM_DATABASE=COINT Multimedia Systems
+
+acpi:COB*:
+ ID_VENDOR_FROM_DATABASE=COBY Electronics Co., Ltd
+
+acpi:COD*:
+ ID_VENDOR_FROM_DATABASE=CODAN Pty. Ltd.
+
+acpi:COI*:
+ ID_VENDOR_FROM_DATABASE=Codec Inc.
+
+acpi:COL*:
+ ID_VENDOR_FROM_DATABASE=Rockwell Collins, Inc.
+
+acpi:COM*:
+ ID_VENDOR_FROM_DATABASE=Comtrol Corporation
+
+acpi:CON*:
+ ID_VENDOR_FROM_DATABASE=Contec Company Ltd
+
+acpi:COO*:
+ ID_VENDOR_FROM_DATABASE=coolux GmbH
+
+acpi:COR*:
+ ID_VENDOR_FROM_DATABASE=Corollary Inc
+
+acpi:COS*:
+ ID_VENDOR_FROM_DATABASE=CoStar Corporation
+
+acpi:COT*:
+ ID_VENDOR_FROM_DATABASE=Core Technology Inc
+
+acpi:COW*:
+ ID_VENDOR_FROM_DATABASE=Polycow Productions
+
+acpi:COX*:
+ ID_VENDOR_FROM_DATABASE=Comrex
+
+acpi:CPC*:
+ ID_VENDOR_FROM_DATABASE=Ciprico Inc
+
+acpi:CPD*:
+ ID_VENDOR_FROM_DATABASE=CompuAdd
+
+acpi:CPI*:
+ ID_VENDOR_FROM_DATABASE=Computer Peripherals Inc
+
+acpi:CPL*:
+ ID_VENDOR_FROM_DATABASE=Compal Electronics Inc
+
+acpi:CPM*:
+ ID_VENDOR_FROM_DATABASE=Capella Microsystems Inc.
+
+acpi:CPQ*:
+ ID_VENDOR_FROM_DATABASE=Compaq Computer Company
+
+acpi:CPT*:
+ ID_VENDOR_FROM_DATABASE=cPATH
+
+acpi:CPX*:
+ ID_VENDOR_FROM_DATABASE=Powermatic Data Systems
+
+acpi:CRC*:
+ ID_VENDOR_FROM_DATABASE=CONRAC GmbH
+
+acpi:CRD*:
+ ID_VENDOR_FROM_DATABASE=Cardinal Technical Inc
+
+acpi:CRE*:
+ ID_VENDOR_FROM_DATABASE=Creative Labs Inc
+
+acpi:CRI*:
+ ID_VENDOR_FROM_DATABASE=Crio Inc.
+
+acpi:CRL*:
+ ID_VENDOR_FROM_DATABASE=Creative Logic  
+
+acpi:CRN*:
+ ID_VENDOR_FROM_DATABASE=Cornerstone Imaging
+
+acpi:CRO*:
+ ID_VENDOR_FROM_DATABASE=Extraordinary Technologies PTY Limited
+
+acpi:CRQ*:
+ ID_VENDOR_FROM_DATABASE=Cirque Corporation
+
+acpi:CRS*:
+ ID_VENDOR_FROM_DATABASE=Crescendo Communication Inc
+
+acpi:CRV*:
+ ID_VENDOR_FROM_DATABASE=Cerevo Inc.
+
+acpi:CRX*:
+ ID_VENDOR_FROM_DATABASE=Cyrix Corporation
+
+acpi:CSB*:
+ ID_VENDOR_FROM_DATABASE=Transtex SA
+
+acpi:CSC*:
+ ID_VENDOR_FROM_DATABASE=Crystal Semiconductor
+
+acpi:CSD*:
+ ID_VENDOR_FROM_DATABASE=Cresta Systems Inc
+
+acpi:CSE*:
+ ID_VENDOR_FROM_DATABASE=Concept Solutions & Engineering
+
+acpi:CSI*:
+ ID_VENDOR_FROM_DATABASE=Cabletron System Inc
+
+acpi:CSM*:
+ ID_VENDOR_FROM_DATABASE=Cosmic Engineering Inc.
+
+acpi:CSO*:
+ ID_VENDOR_FROM_DATABASE=California Institute of Technology
+
+acpi:CSS*:
+ ID_VENDOR_FROM_DATABASE=CSS Laboratories
+
+acpi:CST*:
+ ID_VENDOR_FROM_DATABASE=CSTI Inc
+
+acpi:CTA*:
+ ID_VENDOR_FROM_DATABASE=CoSystems Inc
+
+acpi:CTC*:
+ ID_VENDOR_FROM_DATABASE=CTC Communication Development Company Ltd
+
+acpi:CTE*:
+ ID_VENDOR_FROM_DATABASE=Chunghwa Telecom Co., Ltd.
+
+acpi:CTL*:
+ ID_VENDOR_FROM_DATABASE=Creative Technology Ltd
+
+acpi:CTM*:
+ ID_VENDOR_FROM_DATABASE=Computerm Corporation
+
+acpi:CTN*:
+ ID_VENDOR_FROM_DATABASE=Computone Products
+
+acpi:CTP*:
+ ID_VENDOR_FROM_DATABASE=Computer Technology Corporation
+
+acpi:CTS*:
+ ID_VENDOR_FROM_DATABASE=Comtec Systems Co., Ltd.
+
+acpi:CTX*:
+ ID_VENDOR_FROM_DATABASE=Creatix Polymedia GmbH
+
+acpi:CUB*:
+ ID_VENDOR_FROM_DATABASE=Cubix Corporation
+
+acpi:CUK*:
+ ID_VENDOR_FROM_DATABASE=Calibre UK Ltd
+
+acpi:CVA*:
+ ID_VENDOR_FROM_DATABASE=Covia Inc.
+
+acpi:CVS*:
+ ID_VENDOR_FROM_DATABASE=Clarity Visual Systems
+
+acpi:CWR*:
+ ID_VENDOR_FROM_DATABASE=Connectware Inc
+
+acpi:CXT*:
+ ID_VENDOR_FROM_DATABASE=Conexant Systems
+
+acpi:CYB*:
+ ID_VENDOR_FROM_DATABASE=CyberVision
+
+acpi:CYC*:
+ ID_VENDOR_FROM_DATABASE=Cylink Corporation
+
+acpi:CYD*:
+ ID_VENDOR_FROM_DATABASE=Cyclades Corporation
+
+acpi:CYL*:
+ ID_VENDOR_FROM_DATABASE=Cyberlabs
+
+acpi:CYT*:
+ ID_VENDOR_FROM_DATABASE=Cytechinfo Inc
+
+acpi:CYV*:
+ ID_VENDOR_FROM_DATABASE=Cyviz AS
+
+acpi:CYW*:
+ ID_VENDOR_FROM_DATABASE=Cyberware
+
+acpi:CYX*:
+ ID_VENDOR_FROM_DATABASE=Cyrix Corporation
+
+acpi:CZE*:
+ ID_VENDOR_FROM_DATABASE=Carl Zeiss AG
+
+acpi:DAC*:
+ ID_VENDOR_FROM_DATABASE=Digital Acoustics Corporation
+
+acpi:DAE*:
+ ID_VENDOR_FROM_DATABASE=Digatron Industrie Elektronik GmbH
+
+acpi:DAI*:
+ ID_VENDOR_FROM_DATABASE=DAIS SET Ltd.
+
+acpi:DAK*:
+ ID_VENDOR_FROM_DATABASE=Daktronics
+
+acpi:DAL*:
+ ID_VENDOR_FROM_DATABASE=Digital Audio Labs Inc
+
+acpi:DAN*:
+ ID_VENDOR_FROM_DATABASE=Danelec Marine A/S
+
+acpi:DAS*:
+ ID_VENDOR_FROM_DATABASE=DAVIS AS
+
+acpi:DAT*:
+ ID_VENDOR_FROM_DATABASE=Datel Inc
+
+acpi:DAU*:
+ ID_VENDOR_FROM_DATABASE=Daou Tech Inc
+
+acpi:DAV*:
+ ID_VENDOR_FROM_DATABASE=Davicom Semiconductor Inc
+
+acpi:DAW*:
+ ID_VENDOR_FROM_DATABASE=DA2 Technologies Inc
+
+acpi:DAX*:
+ ID_VENDOR_FROM_DATABASE=Data Apex Ltd
+
+acpi:DBD*:
+ ID_VENDOR_FROM_DATABASE=Diebold Inc.
+
+acpi:DBI*:
+ ID_VENDOR_FROM_DATABASE=DigiBoard Inc
+
+acpi:DBK*:
+ ID_VENDOR_FROM_DATABASE=Databook Inc
+
+acpi:DBL*:
+ ID_VENDOR_FROM_DATABASE=Doble Engineering Company
+
+acpi:DBN*:
+ ID_VENDOR_FROM_DATABASE=DB Networks Inc
+
+acpi:DCA*:
+ ID_VENDOR_FROM_DATABASE=Digital Communications Association
+
+acpi:DCC*:
+ ID_VENDOR_FROM_DATABASE=Dale Computer Corporation
+
+acpi:DCD*:
+ ID_VENDOR_FROM_DATABASE=Datacast LLC
+
+acpi:DCE*:
+ ID_VENDOR_FROM_DATABASE=dSPACE GmbH
+
+acpi:DCI*:
+ ID_VENDOR_FROM_DATABASE=Concepts Inc
+
+acpi:DCL*:
+ ID_VENDOR_FROM_DATABASE=Dynamic Controls Ltd
+
+acpi:DCM*:
+ ID_VENDOR_FROM_DATABASE=DCM Data Products
+
+acpi:DCO*:
+ ID_VENDOR_FROM_DATABASE=Dialogue Technology Corporation
+
+acpi:DCR*:
+ ID_VENDOR_FROM_DATABASE=Decros Ltd
+
+acpi:DCS*:
+ ID_VENDOR_FROM_DATABASE=Diamond Computer Systems Inc
+
+acpi:DCT*:
+ ID_VENDOR_FROM_DATABASE=Dancall Telecom A/S
+
+acpi:DCV*:
+ ID_VENDOR_FROM_DATABASE=Datatronics Technology Inc
+
+acpi:DDA*:
+ ID_VENDOR_FROM_DATABASE=DA2 Technologies Corporation
+
+acpi:DDD*:
+ ID_VENDOR_FROM_DATABASE=Danka Data Devices
+
+acpi:DDE*:
+ ID_VENDOR_FROM_DATABASE=Datasat Digital Entertainment
+
+acpi:DDI*:
+ ID_VENDOR_FROM_DATABASE=Data Display AG
+
+acpi:DDS*:
+ ID_VENDOR_FROM_DATABASE=Barco, n.v.
+
+acpi:DDT*:
+ ID_VENDOR_FROM_DATABASE=Datadesk Technologies Inc
+
+acpi:DDV*:
+ ID_VENDOR_FROM_DATABASE=Delta Information Systems, Inc
+
+acpi:DEC*:
+ ID_VENDOR_FROM_DATABASE=Digital Equipment Corporation
+
+acpi:DEI*:
+ ID_VENDOR_FROM_DATABASE=Deico Electronics
+
+acpi:DEL*:
+ ID_VENDOR_FROM_DATABASE=Dell Inc.
+
+acpi:DEN*:
+ ID_VENDOR_FROM_DATABASE=Densitron Computers Ltd
+
+acpi:DEX*:
+ ID_VENDOR_FROM_DATABASE=idex displays
+
+acpi:DFI*:
+ ID_VENDOR_FROM_DATABASE=DFI
+
+acpi:DFK*:
+ ID_VENDOR_FROM_DATABASE=SharkTec A/S
+
+acpi:DFT*:
+ ID_VENDOR_FROM_DATABASE=DEI Holdings dba Definitive Technology
+
+acpi:DGA*:
+ ID_VENDOR_FROM_DATABASE=Digiital Arts Inc
+
+acpi:DGC*:
+ ID_VENDOR_FROM_DATABASE=Data General Corporation
+
+acpi:DGI*:
+ ID_VENDOR_FROM_DATABASE=DIGI International
+
+acpi:DGK*:
+ ID_VENDOR_FROM_DATABASE=DugoTech Co., LTD
+
+acpi:DGP*:
+ ID_VENDOR_FROM_DATABASE=Digicorp European sales S.A.
+
+acpi:DGS*:
+ ID_VENDOR_FROM_DATABASE=Diagsoft Inc
+
+acpi:DGT*:
+ ID_VENDOR_FROM_DATABASE=The Dearborn Group
+
+acpi:DHP*:
+ ID_VENDOR_FROM_DATABASE=DH Print
+
+acpi:DHQ*:
+ ID_VENDOR_FROM_DATABASE=Quadram
+
+acpi:DHT*:
+ ID_VENDOR_FROM_DATABASE=Projectavision Inc
+
+acpi:DIA*:
+ ID_VENDOR_FROM_DATABASE=Diadem
+
+acpi:DIG*:
+ ID_VENDOR_FROM_DATABASE=Digicom S.p.A.
+
+acpi:DII*:
+ ID_VENDOR_FROM_DATABASE=Dataq Instruments Inc
+
+acpi:DIM*:
+ ID_VENDOR_FROM_DATABASE=dPict Imaging, Inc.
+
+acpi:DIN*:
+ ID_VENDOR_FROM_DATABASE=Daintelecom Co., Ltd
+
+acpi:DIS*:
+ ID_VENDOR_FROM_DATABASE=Diseda S.A.
+
+acpi:DIT*:
+ ID_VENDOR_FROM_DATABASE=Dragon Information Technology
+
+acpi:DJE*:
+ ID_VENDOR_FROM_DATABASE=Capstone Visual Product Development
+
+acpi:DJP*:
+ ID_VENDOR_FROM_DATABASE=Maygay Machines, Ltd
+
+acpi:DKY*:
+ ID_VENDOR_FROM_DATABASE=Datakey Inc
+
+acpi:DLB*:
+ ID_VENDOR_FROM_DATABASE=Dolby Laboratories Inc.
+
+acpi:DLC*:
+ ID_VENDOR_FROM_DATABASE=Diamond Lane Comm. Corporation
+
+acpi:DLG*:
+ ID_VENDOR_FROM_DATABASE=Digital-Logic GmbH
+
+acpi:DLK*:
+ ID_VENDOR_FROM_DATABASE=D-Link Systems Inc
+
+acpi:DLL*:
+ ID_VENDOR_FROM_DATABASE=Dell Inc
+
+acpi:DLT*:
+ ID_VENDOR_FROM_DATABASE=Digitelec Informatique Park Cadera
+
+acpi:DMB*:
+ ID_VENDOR_FROM_DATABASE=Digicom Systems Inc
+
+acpi:DMC*:
+ ID_VENDOR_FROM_DATABASE=Dune Microsystems Corporation
+
+acpi:DMM*:
+ ID_VENDOR_FROM_DATABASE=Dimond Multimedia Systems Inc
+
+acpi:DMP*:
+ ID_VENDOR_FROM_DATABASE=D&M Holdings Inc, Professional Business Company
+
+acpi:DMS*:
+ ID_VENDOR_FROM_DATABASE=DOME imaging systems
+
+acpi:DMT*:
+ ID_VENDOR_FROM_DATABASE=Distributed Management Task Force, Inc. (DMTF)
+
+acpi:DMV*:
+ ID_VENDOR_FROM_DATABASE=NDS Ltd
+
+acpi:DNA*:
+ ID_VENDOR_FROM_DATABASE=DNA Enterprises, Inc.
+
+acpi:DNG*:
+ ID_VENDOR_FROM_DATABASE=Apache Micro Peripherals Inc
+
+acpi:DNI*:
+ ID_VENDOR_FROM_DATABASE=Deterministic Networks Inc.
+
+acpi:DNT*:
+ ID_VENDOR_FROM_DATABASE=Dr. Neuhous Telekommunikation GmbH
+
+acpi:DNV*:
+ ID_VENDOR_FROM_DATABASE=DiCon
+
+acpi:DOL*:
+ ID_VENDOR_FROM_DATABASE=Dolman Technologies Group Inc
+
+acpi:DOM*:
+ ID_VENDOR_FROM_DATABASE=Dome Imaging Systems
+
+acpi:DON*:
+ ID_VENDOR_FROM_DATABASE=DENON, Ltd.
+
+acpi:DOT*:
+ ID_VENDOR_FROM_DATABASE=Dotronic Mikroelektronik GmbH
+
+acpi:DPA*:
+ ID_VENDOR_FROM_DATABASE=DigiTalk Pro AV
+
+acpi:DPC*:
+ ID_VENDOR_FROM_DATABASE=Delta Electronics Inc
+
+acpi:DPI*:
+ ID_VENDOR_FROM_DATABASE=DocuPoint
+
+acpi:DPL*:
+ ID_VENDOR_FROM_DATABASE=Digital Projection Limited
+
+acpi:DPM*:
+ ID_VENDOR_FROM_DATABASE=ADPM Synthesis sas
+
+acpi:DPS*:
+ ID_VENDOR_FROM_DATABASE=Digital Processing Systems
+
+acpi:DPT*:
+ ID_VENDOR_FROM_DATABASE=DPT
+
+acpi:DPX*:
+ ID_VENDOR_FROM_DATABASE=DpiX, Inc.
+
+acpi:DQB*:
+ ID_VENDOR_FROM_DATABASE=Datacube Inc
+
+acpi:DRB*:
+ ID_VENDOR_FROM_DATABASE=Dr. Bott KG
+
+acpi:DRC*:
+ ID_VENDOR_FROM_DATABASE=Data Ray Corp.
+
+acpi:DRD*:
+ ID_VENDOR_FROM_DATABASE=DIGITAL REFLECTION INC.
+
+acpi:DRI*:
+ ID_VENDOR_FROM_DATABASE=Data Race Inc
+
+acpi:DRS*:
+ ID_VENDOR_FROM_DATABASE=DRS Defense Solutions, LLC
+
+acpi:DSD*:
+ ID_VENDOR_FROM_DATABASE=DS Multimedia Pte Ltd
+
+acpi:DSI*:
+ ID_VENDOR_FROM_DATABASE=Digitan Systems Inc
+
+acpi:DSM*:
+ ID_VENDOR_FROM_DATABASE=DSM Digital Services GmbH
+
+acpi:DSP*:
+ ID_VENDOR_FROM_DATABASE=Domain Technology Inc
+
+acpi:DTA*:
+ ID_VENDOR_FROM_DATABASE=DELTATEC
+
+acpi:DTC*:
+ ID_VENDOR_FROM_DATABASE=DTC Tech Corporation
+
+acpi:DTE*:
+ ID_VENDOR_FROM_DATABASE=Dimension Technologies, Inc.
+
+acpi:DTI*:
+ ID_VENDOR_FROM_DATABASE=Diversified Technology, Inc.
+
+acpi:DTK*:
+ ID_VENDOR_FROM_DATABASE=Dynax Electronics (HK) Ltd
+
+acpi:DTL*:
+ ID_VENDOR_FROM_DATABASE=e-Net Inc
+
+acpi:DTN*:
+ ID_VENDOR_FROM_DATABASE=Datang  Telephone Co
+
+acpi:DTO*:
+ ID_VENDOR_FROM_DATABASE=Deutsche Thomson OHG
+
+acpi:DTT*:
+ ID_VENDOR_FROM_DATABASE=Design & Test Technology, Inc.
+
+acpi:DTX*:
+ ID_VENDOR_FROM_DATABASE=Data Translation
+
+acpi:DUA*:
+ ID_VENDOR_FROM_DATABASE=Dosch & Amand GmbH & Company KG
+
+acpi:DUN*:
+ ID_VENDOR_FROM_DATABASE=NCR Corporation
+
+acpi:DVD*:
+ ID_VENDOR_FROM_DATABASE=Dictaphone Corporation
+
+acpi:DVL*:
+ ID_VENDOR_FROM_DATABASE=Devolo AG
+
+acpi:DVS*:
+ ID_VENDOR_FROM_DATABASE=Digital Video System
+
+acpi:DVT*:
+ ID_VENDOR_FROM_DATABASE=Data Video
+
+acpi:DWE*:
+ ID_VENDOR_FROM_DATABASE=Daewoo Electronics Company Ltd
+
+acpi:DXC*:
+ ID_VENDOR_FROM_DATABASE=Digipronix Control Systems
+
+acpi:DXD*:
+ ID_VENDOR_FROM_DATABASE=DECIMATOR DESIGN PTY LTD
+
+acpi:DXL*:
+ ID_VENDOR_FROM_DATABASE=Dextera Labs Inc
+
+acpi:DXP*:
+ ID_VENDOR_FROM_DATABASE=Data Expert Corporation
+
+acpi:DXS*:
+ ID_VENDOR_FROM_DATABASE=Signet
+
+acpi:DYC*:
+ ID_VENDOR_FROM_DATABASE=Dycam Inc
+
+acpi:DYM*:
+ ID_VENDOR_FROM_DATABASE=Dymo-CoStar Corporation
+
+acpi:DYN*:
+ ID_VENDOR_FROM_DATABASE=Askey Computer Corporation
+
+acpi:DYX*:
+ ID_VENDOR_FROM_DATABASE=Dynax Electronics (HK) Ltd
+
+acpi:EAS*:
+ ID_VENDOR_FROM_DATABASE=Evans and Sutherland Computer
+
+acpi:EBH*:
+ ID_VENDOR_FROM_DATABASE=Data Price Informatica
+
+acpi:EBT*:
+ ID_VENDOR_FROM_DATABASE=HUALONG TECHNOLOGY CO., LTD
+
+acpi:ECA*:
+ ID_VENDOR_FROM_DATABASE=Electro Cam Corp.
+
+acpi:ECC*:
+ ID_VENDOR_FROM_DATABASE=ESSential Comm. Corporation
+
+acpi:ECI*:
+ ID_VENDOR_FROM_DATABASE=Enciris Technologies
+
+acpi:ECK*:
+ ID_VENDOR_FROM_DATABASE=Eugene Chukhlomin Sole Proprietorship, d.b.a.
+
+acpi:ECL*:
+ ID_VENDOR_FROM_DATABASE=Excel Company Ltd
+
+acpi:ECM*:
+ ID_VENDOR_FROM_DATABASE=E-Cmos Tech Corporation
+
+acpi:ECO*:
+ ID_VENDOR_FROM_DATABASE=Echo Speech Corporation
+
+acpi:ECP*:
+ ID_VENDOR_FROM_DATABASE=Elecom Company Ltd
+
+acpi:ECS*:
+ ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems Company Ltd
+
+acpi:ECT*:
+ ID_VENDOR_FROM_DATABASE=Enciris Technologies
+
+acpi:EDC*:
+ ID_VENDOR_FROM_DATABASE=e.Digital Corporation
+
+acpi:EDG*:
+ ID_VENDOR_FROM_DATABASE=Electronic-Design GmbH
+
+acpi:EDI*:
+ ID_VENDOR_FROM_DATABASE=Edimax Tech. Company Ltd
+
+acpi:EDM*:
+ ID_VENDOR_FROM_DATABASE=EDMI
+
+acpi:EDT*:
+ ID_VENDOR_FROM_DATABASE=Emerging Display Technologies Corp
+
+acpi:EEE*:
+ ID_VENDOR_FROM_DATABASE=ET&T Technology Company Ltd
+
+acpi:EEH*:
+ ID_VENDOR_FROM_DATABASE=EEH Datalink GmbH
+
+acpi:EEP*:
+ ID_VENDOR_FROM_DATABASE=E.E.P.D. GmbH
+
+acpi:EES*:
+ ID_VENDOR_FROM_DATABASE=EE Solutions, Inc.
+
+acpi:EGA*:
+ ID_VENDOR_FROM_DATABASE=Elgato Systems LLC
+
+acpi:EGD*:
+ ID_VENDOR_FROM_DATABASE=EIZO GmbH Display Technologies
+
+acpi:EGL*:
+ ID_VENDOR_FROM_DATABASE=Eagle Technology
+
+acpi:EGN*:
+ ID_VENDOR_FROM_DATABASE=Egenera, Inc.
+
+acpi:EGO*:
+ ID_VENDOR_FROM_DATABASE=Ergo Electronics
+
+acpi:EHJ*:
+ ID_VENDOR_FROM_DATABASE=Epson Research
+
+acpi:EHN*:
+ ID_VENDOR_FROM_DATABASE=Enhansoft
+
+acpi:EIC*:
+ ID_VENDOR_FROM_DATABASE=Eicon Technology Corporation
+
+acpi:EKA*:
+ ID_VENDOR_FROM_DATABASE=MagTek Inc.
+
+acpi:EKC*:
+ ID_VENDOR_FROM_DATABASE=Eastman Kodak Company
+
+acpi:EKS*:
+ ID_VENDOR_FROM_DATABASE=EKSEN YAZILIM
+
+acpi:ELA*:
+ ID_VENDOR_FROM_DATABASE=ELAD srl
+
+acpi:ELC*:
+ ID_VENDOR_FROM_DATABASE=Electro Scientific Ind
+
+acpi:ELE*:
+ ID_VENDOR_FROM_DATABASE=Elecom Company Ltd
+
+acpi:ELG*:
+ ID_VENDOR_FROM_DATABASE=Elmeg GmbH Kommunikationstechnik
+
+acpi:ELI*:
+ ID_VENDOR_FROM_DATABASE=Edsun Laboratories
+
+acpi:ELL*:
+ ID_VENDOR_FROM_DATABASE=Electrosonic Ltd
+
+acpi:ELM*:
+ ID_VENDOR_FROM_DATABASE=Elmic Systems Inc
+
+acpi:ELO*:
+ ID_VENDOR_FROM_DATABASE=Elo TouchSystems Inc
+
+acpi:ELS*:
+ ID_VENDOR_FROM_DATABASE=ELSA GmbH
+
+acpi:ELT*:
+ ID_VENDOR_FROM_DATABASE=Element Labs, Inc.
+
+acpi:ELX*:
+ ID_VENDOR_FROM_DATABASE=Elonex PLC
+
+acpi:EMB*:
+ ID_VENDOR_FROM_DATABASE=Embedded computing inc ltd
+
+acpi:EMC*:
+ ID_VENDOR_FROM_DATABASE=eMicro Corporation
+
+acpi:EME*:
+ ID_VENDOR_FROM_DATABASE=EMiNE TECHNOLOGY COMPANY, LTD.
+
+acpi:EMG*:
+ ID_VENDOR_FROM_DATABASE=EMG Consultants Inc
+
+acpi:EMI*:
+ ID_VENDOR_FROM_DATABASE=Ex Machina Inc
+
+acpi:EMK*:
+ ID_VENDOR_FROM_DATABASE=Emcore Corporation
+
+acpi:EMO*:
+ ID_VENDOR_FROM_DATABASE=ELMO COMPANY, LIMITED
+
+acpi:EMU*:
+ ID_VENDOR_FROM_DATABASE=Emulex Corporation
+
+acpi:ENC*:
+ ID_VENDOR_FROM_DATABASE=Eizo Nanao Corporation
+
+acpi:END*:
+ ID_VENDOR_FROM_DATABASE=ENIDAN Technologies Ltd
+
+acpi:ENE*:
+ ID_VENDOR_FROM_DATABASE=ENE Technology Inc.
+
+acpi:ENI*:
+ ID_VENDOR_FROM_DATABASE=Efficient Networks
+
+acpi:ENS*:
+ ID_VENDOR_FROM_DATABASE=Ensoniq Corporation
+
+acpi:ENT*:
+ ID_VENDOR_FROM_DATABASE=Enterprise Comm. & Computing Inc
+
+acpi:EPC*:
+ ID_VENDOR_FROM_DATABASE=Empac
+
+acpi:EPH *:
+ ID_VENDOR_FROM_DATABASE=Epiphan Systems Inc. 
+
+acpi:EPI*:
+ ID_VENDOR_FROM_DATABASE=Envision Peripherals, Inc
+
+acpi:EPN*:
+ ID_VENDOR_FROM_DATABASE=EPiCON Inc.
+
+acpi:EPS*:
+ ID_VENDOR_FROM_DATABASE=KEPS
+
+acpi:EQP*:
+ ID_VENDOR_FROM_DATABASE=Equipe Electronics Ltd.
+
+acpi:EQX*:
+ ID_VENDOR_FROM_DATABASE=Equinox Systems Inc
+
+acpi:ERG*:
+ ID_VENDOR_FROM_DATABASE=Ergo System
+
+acpi:ERI*:
+ ID_VENDOR_FROM_DATABASE=Ericsson Mobile Communications AB
+
+acpi:ERN*:
+ ID_VENDOR_FROM_DATABASE=Ericsson, Inc.
+
+acpi:ERP*:
+ ID_VENDOR_FROM_DATABASE=Euraplan GmbH
+
+acpi:ERT*:
+ ID_VENDOR_FROM_DATABASE=Escort Insturments Corporation
+
+acpi:ESA*:
+ ID_VENDOR_FROM_DATABASE=Elbit Systems of America
+
+acpi:ESC*:
+ ID_VENDOR_FROM_DATABASE=Eden Sistemas de Computacao S/A
+
+acpi:ESD*:
+ ID_VENDOR_FROM_DATABASE=Ensemble Designs, Inc
+
+acpi:ESG*:
+ ID_VENDOR_FROM_DATABASE=ELCON Systemtechnik GmbH
+
+acpi:ESI*:
+ ID_VENDOR_FROM_DATABASE=Extended Systems, Inc.
+
+acpi:ESK*:
+ ID_VENDOR_FROM_DATABASE=ES&S
+
+acpi:ESL*:
+ ID_VENDOR_FROM_DATABASE=Esterline Technologies
+
+acpi:ESN*:
+ ID_VENDOR_FROM_DATABASE=eSATURNUS
+
+acpi:ESS*:
+ ID_VENDOR_FROM_DATABASE=ESS Technology Inc
+
+acpi:EST*:
+ ID_VENDOR_FROM_DATABASE=Embedded Solution Technology
+
+acpi:ESY*:
+ ID_VENDOR_FROM_DATABASE=E-Systems Inc
+
+acpi:ETC*:
+ ID_VENDOR_FROM_DATABASE=Everton Technology Company Ltd
+
+acpi:ETD*:
+ ID_VENDOR_FROM_DATABASE=ELAN MICROELECTRONICS CORPORATION
+
+acpi:ETH*:
+ ID_VENDOR_FROM_DATABASE=Etherboot Project
+
+acpi:ETI*:
+ ID_VENDOR_FROM_DATABASE=Eclipse Tech Inc
+
+acpi:ETK*:
+ ID_VENDOR_FROM_DATABASE=eTEK Labs Inc.
+
+acpi:ETL*:
+ ID_VENDOR_FROM_DATABASE=Evertz Microsystems Ltd.
+
+acpi:ETS*:
+ ID_VENDOR_FROM_DATABASE=Electronic Trade Solutions Ltd
+
+acpi:ETT*:
+ ID_VENDOR_FROM_DATABASE=E-Tech Inc
+
+acpi:EUT*:
+ ID_VENDOR_FROM_DATABASE=Ericsson Mobile Networks B.V.
+
+acpi:EVE*:
+ ID_VENDOR_FROM_DATABASE=Advanced Micro Peripherals Ltd
+
+acpi:EVI*:
+ ID_VENDOR_FROM_DATABASE=eviateg GmbH
+
+acpi:EVX*:
+ ID_VENDOR_FROM_DATABASE=Everex
+
+acpi:EXA*:
+ ID_VENDOR_FROM_DATABASE=Exabyte
+
+acpi:EXC*:
+ ID_VENDOR_FROM_DATABASE=Excession Audio
+
+acpi:EXI*:
+ ID_VENDOR_FROM_DATABASE=Exide Electronics
+
+acpi:EXN*:
+ ID_VENDOR_FROM_DATABASE=RGB Systems, Inc. dba Extron Electronics
+
+acpi:EXP*:
+ ID_VENDOR_FROM_DATABASE=Data Export Corporation
+
+acpi:EXT*:
+ ID_VENDOR_FROM_DATABASE=Exatech Computadores & Servicos Ltda
+
+acpi:EXX*:
+ ID_VENDOR_FROM_DATABASE=Exxact GmbH
+
+acpi:EXY*:
+ ID_VENDOR_FROM_DATABASE=Exterity Ltd
+
+acpi:EYE*:
+ ID_VENDOR_FROM_DATABASE=eyevis GmbH
+
+acpi:EZE*:
+ ID_VENDOR_FROM_DATABASE=EzE Technologies
+
+acpi:EZP*:
+ ID_VENDOR_FROM_DATABASE=Storm Technology
+
+acpi:FAR*:
+ ID_VENDOR_FROM_DATABASE=Farallon Computing
+
+acpi:FBI*:
+ ID_VENDOR_FROM_DATABASE=Interface Corporation
+
+acpi:FCB*:
+ ID_VENDOR_FROM_DATABASE=Furukawa Electric Company Ltd
+
+acpi:FCG*:
+ ID_VENDOR_FROM_DATABASE=First International Computer Ltd
+
+acpi:FCS*:
+ ID_VENDOR_FROM_DATABASE=Focus Enhancements, Inc.
+
+acpi:FDC*:
+ ID_VENDOR_FROM_DATABASE=Future Domain
+
+acpi:FDT*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu Display Technologies Corp.
+
+acpi:FEC*:
+ ID_VENDOR_FROM_DATABASE=FURUNO ELECTRIC CO., LTD.
+
+acpi:FEL*:
+ ID_VENDOR_FROM_DATABASE=Fellowes & Questec
+
+acpi:FEN*:
+ ID_VENDOR_FROM_DATABASE=Fen Systems Ltd.
+
+acpi:FER*:
+ ID_VENDOR_FROM_DATABASE=Ferranti Int'L
+
+acpi:FFC*:
+ ID_VENDOR_FROM_DATABASE=FUJIFILM Corporation
+
+acpi:FFI*:
+ ID_VENDOR_FROM_DATABASE=Fairfield Industries
+
+acpi:FGD*:
+ ID_VENDOR_FROM_DATABASE=Lisa Draexlmaier GmbH
+
+acpi:FGL*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu General Limited.
+
+acpi:FHL*:
+ ID_VENDOR_FROM_DATABASE=FHLP
+
+acpi:FIC*:
+ ID_VENDOR_FROM_DATABASE=Formosa Industrial Computing Inc
+
+acpi:FIL*:
+ ID_VENDOR_FROM_DATABASE=Forefront Int'l Ltd
+
+acpi:FIN*:
+ ID_VENDOR_FROM_DATABASE=Finecom Co., Ltd.
+
+acpi:FIR*:
+ ID_VENDOR_FROM_DATABASE=Chaplet Systems Inc
+
+acpi:FIS*:
+ ID_VENDOR_FROM_DATABASE=FLY-IT Simulators
+
+acpi:FIT*:
+ ID_VENDOR_FROM_DATABASE=Feature Integration Technology Inc.
+
+acpi:FJC*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu Takamisawa Component Limited
+
+acpi:FJS*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu Spain
+
+acpi:FJT*:
+ ID_VENDOR_FROM_DATABASE=F.J. Tieman BV
+
+acpi:FLE*:
+ ID_VENDOR_FROM_DATABASE=ADTI Media, Inc
+
+acpi:FLI*:
+ ID_VENDOR_FROM_DATABASE=Faroudja Laboratories
+
+acpi:FLY*:
+ ID_VENDOR_FROM_DATABASE=Butterfly Communications
+
+acpi:FMA*:
+ ID_VENDOR_FROM_DATABASE=Fast Multimedia AG
+
+acpi:FMC*:
+ ID_VENDOR_FROM_DATABASE=Ford Microelectronics Inc
+
+acpi:FMI*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu Microelect Inc
+
+acpi:FML*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu Microelect Ltd
+
+acpi:FMZ*:
+ ID_VENDOR_FROM_DATABASE=Formoza-Altair
+
+acpi:FNC*:
+ ID_VENDOR_FROM_DATABASE=Fanuc LTD
+
+acpi:FNI*:
+ ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd.
+
+acpi:FOA*:
+ ID_VENDOR_FROM_DATABASE=FOR-A Company Limited
+
+acpi:FOS*:
+ ID_VENDOR_FROM_DATABASE=Foss Tecator
+
+acpi:FOX*:
+ ID_VENDOR_FROM_DATABASE=HON HAI PRECISON IND.CO.,LTD.
+
+acpi:FPE*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu Peripherals Ltd
+
+acpi:FPS*:
+ ID_VENDOR_FROM_DATABASE=Deltec Corporation
+
+acpi:FPX*:
+ ID_VENDOR_FROM_DATABASE=Cirel Systemes
+
+acpi:FRC*:
+ ID_VENDOR_FROM_DATABASE=Force Computers
+
+acpi:FRD*:
+ ID_VENDOR_FROM_DATABASE=Freedom Scientific BLV
+
+acpi:FRE*:
+ ID_VENDOR_FROM_DATABASE=Forvus Research Inc
+
+acpi:FRI*:
+ ID_VENDOR_FROM_DATABASE=Fibernet Research Inc
+
+acpi:FRS*:
+ ID_VENDOR_FROM_DATABASE=South Mountain Technologies, LTD
+
+acpi:FSC*:
+ ID_VENDOR_FROM_DATABASE=Future Systems Consulting KK
+
+acpi:FSI*:
+ ID_VENDOR_FROM_DATABASE=Fore Systems Inc
+
+acpi:FST*:
+ ID_VENDOR_FROM_DATABASE=Modesto PC Inc
+
+acpi:FTC*:
+ ID_VENDOR_FROM_DATABASE=Futuretouch Corporation
+
+acpi:FTE*:
+ ID_VENDOR_FROM_DATABASE=Frontline Test Equipment Inc.
+
+acpi:FTG*:
+ ID_VENDOR_FROM_DATABASE=FTG Data Systems
+
+acpi:FTI*:
+ ID_VENDOR_FROM_DATABASE=FastPoint Technologies, Inc.
+
+acpi:FTL*:
+ ID_VENDOR_FROM_DATABASE=FUJITSU TEN LIMITED
+
+acpi:FTN*:
+ ID_VENDOR_FROM_DATABASE=Fountain Technologies Inc
+
+acpi:FTR*:
+ ID_VENDOR_FROM_DATABASE=Mediasonic
+
+acpi:FTW*:
+ ID_VENDOR_FROM_DATABASE=MindTribe Product Engineering, Inc.
+
+acpi:FUJ*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu Ltd
+
+acpi:FUN*:
+ ID_VENDOR_FROM_DATABASE=sisel muhendislik
+
+acpi:FUS*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu Siemens Computers GmbH
+
+acpi:FVC*:
+ ID_VENDOR_FROM_DATABASE=First Virtual Corporation
+
+acpi:FVX*:
+ ID_VENDOR_FROM_DATABASE=C-C-C Group Plc
+
+acpi:FWA*:
+ ID_VENDOR_FROM_DATABASE=Attero Tech, LLC
+
+acpi:FWR*:
+ ID_VENDOR_FROM_DATABASE=Flat Connections Inc
+
+acpi:FXX*:
+ ID_VENDOR_FROM_DATABASE=Fuji Xerox
+
+acpi:FZC*:
+ ID_VENDOR_FROM_DATABASE=Founder Group Shenzhen Co.
+
+acpi:FZI*:
+ ID_VENDOR_FROM_DATABASE=FZI Forschungszentrum Informatik
+
+acpi:GAG*:
+ ID_VENDOR_FROM_DATABASE=Gage Applied Sciences Inc
+
+acpi:GAL*:
+ ID_VENDOR_FROM_DATABASE=Galil Motion Control
+
+acpi:GAU*:
+ ID_VENDOR_FROM_DATABASE=Gaudi Co., Ltd.
+
+acpi:GCC*:
+ ID_VENDOR_FROM_DATABASE=GCC Technologies Inc
+
+acpi:GCI*:
+ ID_VENDOR_FROM_DATABASE=Gateway Comm. Inc
+
+acpi:GCS*:
+ ID_VENDOR_FROM_DATABASE=Grey Cell Systems Ltd
+
+acpi:GDC*:
+ ID_VENDOR_FROM_DATABASE=General Datacom
+
+acpi:GDI*:
+ ID_VENDOR_FROM_DATABASE=G. Diehl ISDN GmbH
+
+acpi:GDS*:
+ ID_VENDOR_FROM_DATABASE=GDS
+
+acpi:GDT*:
+ ID_VENDOR_FROM_DATABASE=Vortex Computersysteme GmbH
+
+acpi:GEF*:
+ ID_VENDOR_FROM_DATABASE=GE Fanuc Embedded Systems
+
+acpi:GEH*:
+ ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms - Huntsville
+
+acpi:GEM*:
+ ID_VENDOR_FROM_DATABASE=Gem Plus
+
+acpi:GEN*:
+ ID_VENDOR_FROM_DATABASE=Genesys ATE Inc
+
+acpi:GEO*:
+ ID_VENDOR_FROM_DATABASE=GEO Sense
+
+acpi:GER*:
+ ID_VENDOR_FROM_DATABASE=GERMANEERS GmbH
+
+acpi:GES*:
+ ID_VENDOR_FROM_DATABASE=GES Singapore Pte Ltd
+
+acpi:GET*:
+ ID_VENDOR_FROM_DATABASE=Getac Technology Corporation
+
+acpi:GFM*:
+ ID_VENDOR_FROM_DATABASE=GFMesstechnik GmbH
+
+acpi:GFN*:
+ ID_VENDOR_FROM_DATABASE=Gefen Inc.
+
+acpi:GGL*:
+ ID_VENDOR_FROM_DATABASE=Google Inc.
+
+acpi:GIC*:
+ ID_VENDOR_FROM_DATABASE=General Inst. Corporation
+
+acpi:GIM*:
+ ID_VENDOR_FROM_DATABASE=Guillemont International
+
+acpi:GIP*:
+ ID_VENDOR_FROM_DATABASE=GI Provision Ltd
+
+acpi:GIS*:
+ ID_VENDOR_FROM_DATABASE=AT&T Global Info Solutions
+
+acpi:GJN*:
+ ID_VENDOR_FROM_DATABASE=Grand Junction Networks
+
+acpi:GLD*:
+ ID_VENDOR_FROM_DATABASE=Goldmund - Digital Audio SA
+
+acpi:GLE*:
+ ID_VENDOR_FROM_DATABASE=AD electronics
+
+acpi:GLM*:
+ ID_VENDOR_FROM_DATABASE=Genesys Logic
+
+acpi:GLS*:
+ ID_VENDOR_FROM_DATABASE=Gadget Labs LLC
+
+acpi:GMK*:
+ ID_VENDOR_FROM_DATABASE=GMK Electronic Design GmbH
+
+acpi:GML*:
+ ID_VENDOR_FROM_DATABASE=General Information Systems
+
+acpi:GMM*:
+ ID_VENDOR_FROM_DATABASE=GMM Research Inc
+
+acpi:GMN*:
+ ID_VENDOR_FROM_DATABASE=GEMINI 2000 Ltd
+
+acpi:GMX*:
+ ID_VENDOR_FROM_DATABASE=GMX Inc
+
+acpi:GND*:
+ ID_VENDOR_FROM_DATABASE=Gennum Corporation
+
+acpi:GNN*:
+ ID_VENDOR_FROM_DATABASE=GN Nettest Inc
+
+acpi:GNZ*:
+ ID_VENDOR_FROM_DATABASE=Gunze Ltd
+
+acpi:GRA*:
+ ID_VENDOR_FROM_DATABASE=Graphica Computer
+
+acpi:GRE*:
+ ID_VENDOR_FROM_DATABASE=GOLD RAIN ENTERPRISES CORP.
+
+acpi:GRH*:
+ ID_VENDOR_FROM_DATABASE=Granch Ltd
+
+acpi:GRM*:
+ ID_VENDOR_FROM_DATABASE=Garmin International
+
+acpi:GRV*:
+ ID_VENDOR_FROM_DATABASE=Advanced Gravis
+
+acpi:GRY*:
+ ID_VENDOR_FROM_DATABASE=Robert Gray Company
+
+acpi:GSB*:
+ ID_VENDOR_FROM_DATABASE=NIPPONDENCHI CO,.LTD
+
+acpi:GSC*:
+ ID_VENDOR_FROM_DATABASE=General Standards Corporation
+
+acpi:GSM*:
+ ID_VENDOR_FROM_DATABASE=Goldstar Company Ltd
+
+acpi:GST*:
+ ID_VENDOR_FROM_DATABASE=Graphic SystemTechnology
+
+acpi:GSY*:
+ ID_VENDOR_FROM_DATABASE=Grossenbacher Systeme AG
+
+acpi:GTC*:
+ ID_VENDOR_FROM_DATABASE=Graphtec Corporation
+
+acpi:GTI*:
+ ID_VENDOR_FROM_DATABASE=Goldtouch
+
+acpi:GTK*:
+ ID_VENDOR_FROM_DATABASE=G-Tech Corporation
+
+acpi:GTM*:
+ ID_VENDOR_FROM_DATABASE=Garnet System Company Ltd
+
+acpi:GTS*:
+ ID_VENDOR_FROM_DATABASE=Geotest Marvin Test Systems Inc
+
+acpi:GTT*:
+ ID_VENDOR_FROM_DATABASE=General Touch Technology Co., Ltd.
+
+acpi:GUD*:
+ ID_VENDOR_FROM_DATABASE=Guntermann & Drunck GmbH
+
+acpi:GUZ*:
+ ID_VENDOR_FROM_DATABASE=Guzik Technical Enterprises
+
+acpi:GVC*:
+ ID_VENDOR_FROM_DATABASE=GVC Corporation
+
+acpi:GVL*:
+ ID_VENDOR_FROM_DATABASE=Global Village Communication
+
+acpi:GWI*:
+ ID_VENDOR_FROM_DATABASE=GW Instruments
+
+acpi:GWY*:
+ ID_VENDOR_FROM_DATABASE=Gateway 2000
+
+acpi:GZE*:
+ ID_VENDOR_FROM_DATABASE=GUNZE Limited
+
+acpi:HAE*:
+ ID_VENDOR_FROM_DATABASE=Haider electronics
+
+acpi:HAI*:
+ ID_VENDOR_FROM_DATABASE=Haivision Systems Inc.
+
+acpi:HAL*:
+ ID_VENDOR_FROM_DATABASE=Halberthal
+
+acpi:HAN*:
+ ID_VENDOR_FROM_DATABASE=Hanchang System Corporation
+
+acpi:HAR*:
+ ID_VENDOR_FROM_DATABASE=Harris Corporation
+
+acpi:HAY*:
+ ID_VENDOR_FROM_DATABASE=Hayes Microcomputer Products Inc
+
+acpi:HCA*:
+ ID_VENDOR_FROM_DATABASE=DAT
+
+acpi:HCE*:
+ ID_VENDOR_FROM_DATABASE=Hitachi Consumer Electronics Co., Ltd
+
+acpi:HCL*:
+ ID_VENDOR_FROM_DATABASE=HCL America Inc
+
+acpi:HCM*:
+ ID_VENDOR_FROM_DATABASE=HCL Peripherals
+
+acpi:HCP*:
+ ID_VENDOR_FROM_DATABASE=Hitachi Computer Products Inc
+
+acpi:HCW*:
+ ID_VENDOR_FROM_DATABASE=Hauppauge Computer Works Inc
+
+acpi:HDC*:
+ ID_VENDOR_FROM_DATABASE=HardCom Elektronik & Datateknik
+
+acpi:HDI*:
+ ID_VENDOR_FROM_DATABASE=HD-INFO d.o.o.
+
+acpi:HDV*:
+ ID_VENDOR_FROM_DATABASE=Holografika kft.
+
+acpi:HEC*:
+ ID_VENDOR_FROM_DATABASE=Hisense Electric Co., Ltd.
+
+acpi:HEL*:
+ ID_VENDOR_FROM_DATABASE=Hitachi Micro Systems Europe Ltd
+
+acpi:HER*:
+ ID_VENDOR_FROM_DATABASE=Ascom Business Systems
+
+acpi:HET*:
+ ID_VENDOR_FROM_DATABASE=HETEC Datensysteme GmbH
+
+acpi:HHC*:
+ ID_VENDOR_FROM_DATABASE=HIRAKAWA HEWTECH CORP.
+
+acpi:HHI*:
+ ID_VENDOR_FROM_DATABASE=Fraunhofer Heinrich-Hertz-Institute
+
+acpi:HIB*:
+ ID_VENDOR_FROM_DATABASE=Hibino Corporation
+
+acpi:HIC*:
+ ID_VENDOR_FROM_DATABASE=Hitachi Information Technology Co., Ltd.
+
+acpi:HIK*:
+ ID_VENDOR_FROM_DATABASE=Hikom Co., Ltd.
+
+acpi:HIL*:
+ ID_VENDOR_FROM_DATABASE=Hilevel Technology
+
+acpi:HIQ*:
+ ID_VENDOR_FROM_DATABASE=Kaohsiung Opto Electronics Americas, Inc.
+
+acpi:HIT*:
+ ID_VENDOR_FROM_DATABASE=Hitachi America Ltd
+
+acpi:HJI*:
+ ID_VENDOR_FROM_DATABASE=Harris & Jeffries Inc
+
+acpi:HKA*:
+ ID_VENDOR_FROM_DATABASE=HONKO MFG. CO., LTD.
+
+acpi:HKG*:
+ ID_VENDOR_FROM_DATABASE=Josef Heim KG
+
+acpi:HMC*:
+ ID_VENDOR_FROM_DATABASE=Hualon Microelectric Corporation
+
+acpi:HMK*:
+ ID_VENDOR_FROM_DATABASE=hmk Daten-System-Technik BmbH
+
+acpi:HMX*:
+ ID_VENDOR_FROM_DATABASE=HUMAX Co., Ltd.
+
+acpi:HNS*:
+ ID_VENDOR_FROM_DATABASE=Hughes Network Systems
+
+acpi:HOB*:
+ ID_VENDOR_FROM_DATABASE=HOB Electronic GmbH
+
+acpi:HOE*:
+ ID_VENDOR_FROM_DATABASE=Hosiden Corporation
+
+acpi:HOL*:
+ ID_VENDOR_FROM_DATABASE=Holoeye Photonics AG
+
+acpi:HON*:
+ ID_VENDOR_FROM_DATABASE=Sonitronix
+
+acpi:HPA*:
+ ID_VENDOR_FROM_DATABASE=Zytor Communications
+
+acpi:HPC*:
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard Co.
+
+acpi:HPD*:
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard
+
+acpi:HPI*:
+ ID_VENDOR_FROM_DATABASE=Headplay, Inc.
+
+acpi:HPK*:
+ ID_VENDOR_FROM_DATABASE=HAMAMATSU PHOTONICS K.K.
+
+acpi:HPQ*:
+ ID_VENDOR_FROM_DATABASE=HP
+
+acpi:HPR*:
+ ID_VENDOR_FROM_DATABASE=H.P.R. Electronics GmbH
+
+acpi:HRC*:
+ ID_VENDOR_FROM_DATABASE=Hercules
+
+acpi:HRE*:
+ ID_VENDOR_FROM_DATABASE=Qingdao Haier Electronics Co., Ltd.
+
+acpi:HRI*:
+ ID_VENDOR_FROM_DATABASE=Hall Research
+
+acpi:HRL*:
+ ID_VENDOR_FROM_DATABASE=Herolab GmbH
+
+acpi:HRS*:
+ ID_VENDOR_FROM_DATABASE=Harris Semiconductor
+
+acpi:HRT*:
+ ID_VENDOR_FROM_DATABASE=HERCULES
+
+acpi:HSC*:
+ ID_VENDOR_FROM_DATABASE=Hagiwara Sys-Com Company Ltd
+
+acpi:HSD*:
+ ID_VENDOR_FROM_DATABASE=HannStar Display Corp
+
+acpi:HSM*:
+ ID_VENDOR_FROM_DATABASE=AT&T Microelectronics
+
+acpi:HSP*:
+ ID_VENDOR_FROM_DATABASE=HannStar Display Corp
+
+acpi:HTC*:
+ ID_VENDOR_FROM_DATABASE=Hitachi Ltd
+
+acpi:HTI*:
+ ID_VENDOR_FROM_DATABASE=Hampshire Company, Inc.
+
+acpi:HTK*:
+ ID_VENDOR_FROM_DATABASE=Holtek Microelectronics Inc
+
+acpi:HTX*:
+ ID_VENDOR_FROM_DATABASE=Hitex Systementwicklung GmbH
+
+acpi:HUB*:
+ ID_VENDOR_FROM_DATABASE=GAI-Tronics, A Hubbell Company
+
+acpi:HUM*:
+ ID_VENDOR_FROM_DATABASE=IMP Electronics Ltd.
+
+acpi:HWA*:
+ ID_VENDOR_FROM_DATABASE=Harris Canada Inc
+
+acpi:HWC*:
+ ID_VENDOR_FROM_DATABASE=DBA Hans Wedemeyer
+
+acpi:HWD*:
+ ID_VENDOR_FROM_DATABASE=Highwater Designs Ltd
+
+acpi:HWP*:
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard
+
+acpi:HXM*:
+ ID_VENDOR_FROM_DATABASE=Hexium Ltd.
+
+acpi:HYC*:
+ ID_VENDOR_FROM_DATABASE=Hypercope Gmbh Aachen
+
+acpi:HYD*:
+ ID_VENDOR_FROM_DATABASE=Hydis Technologies.Co.,LTD
+
+acpi:HYO*:
+ ID_VENDOR_FROM_DATABASE=HYC CO., LTD.
+
+acpi:HYP*:
+ ID_VENDOR_FROM_DATABASE=Hyphen Ltd
+
+acpi:HYR*:
+ ID_VENDOR_FROM_DATABASE=Hypertec Pty Ltd
+
+acpi:HYT*:
+ ID_VENDOR_FROM_DATABASE=Heng Yu Technology (HK) Limited
+
+acpi:HYV*:
+ ID_VENDOR_FROM_DATABASE=Hynix Semiconductor
+
+acpi:IAF*:
+ ID_VENDOR_FROM_DATABASE=Institut f r angewandte Funksystemtechnik GmbH
+
+acpi:IAI*:
+ ID_VENDOR_FROM_DATABASE=Integration Associates, Inc.
+
+acpi:IAT*:
+ ID_VENDOR_FROM_DATABASE=IAT Germany GmbH
+
+acpi:IBC*:
+ ID_VENDOR_FROM_DATABASE=Integrated Business Systems
+
+acpi:IBI*:
+ ID_VENDOR_FROM_DATABASE=INBINE.CO.LTD
+
+acpi:IBM*:
+ ID_VENDOR_FROM_DATABASE=IBM
+
+acpi:IBP*:
+ ID_VENDOR_FROM_DATABASE=IBP Instruments GmbH
+
+acpi:IBR*:
+ ID_VENDOR_FROM_DATABASE=IBR GmbH
+
+acpi:ICA*:
+ ID_VENDOR_FROM_DATABASE=ICA Inc
+
+acpi:ICC*:
+ ID_VENDOR_FROM_DATABASE=BICC Data Networks Ltd
+
+acpi:ICD*:
+ ID_VENDOR_FROM_DATABASE=ICD Inc
+
+acpi:ICE*:
+ ID_VENDOR_FROM_DATABASE=IC Ensemble
+
+acpi:ICI*:
+ ID_VENDOR_FROM_DATABASE=Infotek Communication Inc
+
+acpi:ICM*:
+ ID_VENDOR_FROM_DATABASE=Intracom SA
+
+acpi:ICN*:
+ ID_VENDOR_FROM_DATABASE=Sanyo Icon
+
+acpi:ICO*:
+ ID_VENDOR_FROM_DATABASE=Intel Corp
+
+acpi:ICS*:
+ ID_VENDOR_FROM_DATABASE=Integrated Circuit Systems
+
+acpi:ICV*:
+ ID_VENDOR_FROM_DATABASE=Inside Contactless
+
+acpi:ICX*:
+ ID_VENDOR_FROM_DATABASE=ICCC A/S
+
+acpi:IDC*:
+ ID_VENDOR_FROM_DATABASE=International Datacasting Corporation
+
+acpi:IDE*:
+ ID_VENDOR_FROM_DATABASE=IDE Associates
+
+acpi:IDK*:
+ ID_VENDOR_FROM_DATABASE=IDK Corporation
+
+acpi:IDN*:
+ ID_VENDOR_FROM_DATABASE=Idneo Technologies
+
+acpi:IDO*:
+ ID_VENDOR_FROM_DATABASE=IDEO Product Development
+
+acpi:IDP*:
+ ID_VENDOR_FROM_DATABASE=Integrated Device Technology, Inc.
+
+acpi:IDS*:
+ ID_VENDOR_FROM_DATABASE=Interdigital Sistemas de Informacao
+
+acpi:IDT*:
+ ID_VENDOR_FROM_DATABASE=International Display Technology
+
+acpi:IDX*:
+ ID_VENDOR_FROM_DATABASE=IDEXX Labs
+
+acpi:IEC*:
+ ID_VENDOR_FROM_DATABASE=Interlace Engineering Corporation
+
+acpi:IEE*:
+ ID_VENDOR_FROM_DATABASE=IEE
+
+acpi:IEI*:
+ ID_VENDOR_FROM_DATABASE=Interlink Electronics
+
+acpi:IFS*:
+ ID_VENDOR_FROM_DATABASE=In Focus Systems Inc
+
+acpi:IFT*:
+ ID_VENDOR_FROM_DATABASE=Informtech
+
+acpi:IFX*:
+ ID_VENDOR_FROM_DATABASE=Infineon Technologies AG
+
+acpi:IFZ*:
+ ID_VENDOR_FROM_DATABASE=Infinite Z
+
+acpi:IGC*:
+ ID_VENDOR_FROM_DATABASE=Intergate Pty Ltd
+
+acpi:IGM*:
+ ID_VENDOR_FROM_DATABASE=IGM Communi
+
+acpi:IHE*:
+ ID_VENDOR_FROM_DATABASE=InHand Electronics
+
+acpi:IIC*:
+ ID_VENDOR_FROM_DATABASE=ISIC Innoscan Industrial Computers A/S
+
+acpi:III*:
+ ID_VENDOR_FROM_DATABASE=Intelligent Instrumentation
+
+acpi:IIN*:
+ ID_VENDOR_FROM_DATABASE=IINFRA Co., Ltd
+
+acpi:IKS*:
+ ID_VENDOR_FROM_DATABASE=Ikos Systems Inc
+
+acpi:ILC*:
+ ID_VENDOR_FROM_DATABASE=Image Logic Corporation
+
+acpi:ILS*:
+ ID_VENDOR_FROM_DATABASE=Innotech Corporation
+
+acpi:IMA*:
+ ID_VENDOR_FROM_DATABASE=Imagraph
+
+acpi:IMB*:
+ ID_VENDOR_FROM_DATABASE=ART s.r.l.
+
+acpi:IMC*:
+ ID_VENDOR_FROM_DATABASE=IMC Networks
+
+acpi:IMD*:
+ ID_VENDOR_FROM_DATABASE=ImasDe Canarias S.A.
+
+acpi:IME*:
+ ID_VENDOR_FROM_DATABASE=Imagraph
+
+acpi:IMG*:
+ ID_VENDOR_FROM_DATABASE=IMAGENICS Co., Ltd.
+
+acpi:IMI*:
+ ID_VENDOR_FROM_DATABASE=International Microsystems Inc
+
+acpi:IMM*:
+ ID_VENDOR_FROM_DATABASE=Immersion Corporation
+
+acpi:IMN*:
+ ID_VENDOR_FROM_DATABASE=Impossible Production
+
+acpi:IMP*:
+ ID_VENDOR_FROM_DATABASE=Impression Products Incorporated
+
+acpi:IMT*:
+ ID_VENDOR_FROM_DATABASE=Inmax Technology Corporation
+
+acpi:INC*:
+ ID_VENDOR_FROM_DATABASE=Home Row Inc
+
+acpi:IND*:
+ ID_VENDOR_FROM_DATABASE=ILC
+
+acpi:INE*:
+ ID_VENDOR_FROM_DATABASE=Inventec Electronics (M) Sdn. Bhd.
+
+acpi:INF*:
+ ID_VENDOR_FROM_DATABASE=Inframetrics Inc
+
+acpi:ING*:
+ ID_VENDOR_FROM_DATABASE=Integraph Corporation
+
+acpi:INI*:
+ ID_VENDOR_FROM_DATABASE=Initio Corporation
+
+acpi:INK*:
+ ID_VENDOR_FROM_DATABASE=Indtek Co., Ltd.
+
+acpi:INL*:
+ ID_VENDOR_FROM_DATABASE=InnoLux Display Corporation
+
+acpi:INM*:
+ ID_VENDOR_FROM_DATABASE=InnoMedia Inc
+
+acpi:INN*:
+ ID_VENDOR_FROM_DATABASE=Innovent Systems, Inc.
+
+acpi:INO*:
+ ID_VENDOR_FROM_DATABASE=Innolab Pte Ltd
+
+acpi:INP*:
+ ID_VENDOR_FROM_DATABASE=Interphase Corporation
+
+acpi:INS*:
+ ID_VENDOR_FROM_DATABASE=Ines GmbH
+
+acpi:INT*:
+ ID_VENDOR_FROM_DATABASE=Interphase Corporation
+
+acpi:inu*:
+ ID_VENDOR_FROM_DATABASE=Inovatec S.p.A.
+
+acpi:INV*:
+ ID_VENDOR_FROM_DATABASE=Inviso, Inc.
+
+acpi:INZ*:
+ ID_VENDOR_FROM_DATABASE=Best Buy
+
+acpi:IOA*:
+ ID_VENDOR_FROM_DATABASE=CRE Technology Corporation
+
+acpi:IOD*:
+ ID_VENDOR_FROM_DATABASE=I-O Data Device Inc
+
+acpi:IOM*:
+ ID_VENDOR_FROM_DATABASE=Iomega
+
+acpi:ION*:
+ ID_VENDOR_FROM_DATABASE=Inside Out Networks
+
+acpi:IOS*:
+ ID_VENDOR_FROM_DATABASE=i-O Display System
+
+acpi:IOT*:
+ ID_VENDOR_FROM_DATABASE=I/OTech Inc
+
+acpi:IPC*:
+ ID_VENDOR_FROM_DATABASE=IPC Corporation
+
+acpi:IPD*:
+ ID_VENDOR_FROM_DATABASE=Industrial Products Design, Inc.
+
+acpi:IPI*:
+ ID_VENDOR_FROM_DATABASE=Intelligent Platform Management Interface (IPMI) forum (Intel, HP, NEC, Dell)
+
+acpi:IPM*:
+ ID_VENDOR_FROM_DATABASE=IPM Industria Politecnica Meridionale SpA
+
+acpi:IPN*:
+ ID_VENDOR_FROM_DATABASE=Performance Technologies
+
+acpi:IPP*:
+ ID_VENDOR_FROM_DATABASE=IP Power Technologies GmbH
+
+acpi:IPR*:
+ ID_VENDOR_FROM_DATABASE=Ithaca Peripherals
+
+acpi:IPS*:
+ ID_VENDOR_FROM_DATABASE=IPS, Inc. (Intellectual Property Solutions, Inc.)
+
+acpi:IPT*:
+ ID_VENDOR_FROM_DATABASE=International Power Technologies
+
+acpi:IPW*:
+ ID_VENDOR_FROM_DATABASE=IPWireless, Inc
+
+acpi:IQI*:
+ ID_VENDOR_FROM_DATABASE=IneoQuest Technologies, Inc
+
+acpi:IQT*:
+ ID_VENDOR_FROM_DATABASE=IMAGEQUEST Co., Ltd
+
+acpi:IRD*:
+ ID_VENDOR_FROM_DATABASE=IRdata
+
+acpi:ISA*:
+ ID_VENDOR_FROM_DATABASE=Symbol Technologies
+
+acpi:ISC*:
+ ID_VENDOR_FROM_DATABASE=Id3 Semiconductors
+
+acpi:ISG*:
+ ID_VENDOR_FROM_DATABASE=Insignia Solutions Inc
+
+acpi:ISI*:
+ ID_VENDOR_FROM_DATABASE=Interface Solutions
+
+acpi:ISL*:
+ ID_VENDOR_FROM_DATABASE=Isolation Systems
+
+acpi:ISM*:
+ ID_VENDOR_FROM_DATABASE=Image Stream Medical
+
+acpi:ISP*:
+ ID_VENDOR_FROM_DATABASE=IntreSource Systems Pte Ltd
+
+acpi:ISR*:
+ ID_VENDOR_FROM_DATABASE=INSIS Co., LTD.
+
+acpi:ISS*:
+ ID_VENDOR_FROM_DATABASE=ISS Inc
+
+acpi:IST*:
+ ID_VENDOR_FROM_DATABASE=Intersolve Technologies
+
+acpi:ISY*:
+ ID_VENDOR_FROM_DATABASE=International Integrated Systems,Inc.(IISI)
+
+acpi:ITA*:
+ ID_VENDOR_FROM_DATABASE=Itausa Export North America
+
+acpi:ITC*:
+ ID_VENDOR_FROM_DATABASE=Intercom Inc
+
+acpi:ITD*:
+ ID_VENDOR_FROM_DATABASE=Internet Technology Corporation
+
+acpi:ITE*:
+ ID_VENDOR_FROM_DATABASE=Integrated Tech Express Inc
+
+acpi:ITK*:
+ ID_VENDOR_FROM_DATABASE=ITK Telekommunikation AG
+
+acpi:ITL*:
+ ID_VENDOR_FROM_DATABASE=Inter-Tel
+
+acpi:ITM*:
+ ID_VENDOR_FROM_DATABASE=ITM inc.
+
+acpi:ITN*:
+ ID_VENDOR_FROM_DATABASE=The NTI Group
+
+acpi:ITP*:
+ ID_VENDOR_FROM_DATABASE=IT-PRO Consulting und Systemhaus GmbH
+
+acpi:ITR*:
+ ID_VENDOR_FROM_DATABASE=Infotronic America, Inc.
+
+acpi:ITS*:
+ ID_VENDOR_FROM_DATABASE=IDTECH
+
+acpi:ITT*:
+ ID_VENDOR_FROM_DATABASE=I&T Telecom.
+
+acpi:ITX*:
+ ID_VENDOR_FROM_DATABASE=integrated Technology Express Inc
+
+acpi:IUC*:
+ ID_VENDOR_FROM_DATABASE=ICSL
+
+acpi:IVI*:
+ ID_VENDOR_FROM_DATABASE=Intervoice Inc
+
+acpi:IVM*:
+ ID_VENDOR_FROM_DATABASE=Iiyama North America
+
+acpi:IVS*:
+ ID_VENDOR_FROM_DATABASE=Intevac Photonics Inc.
+
+acpi:IWR*:
+ ID_VENDOR_FROM_DATABASE=Icuiti Corporation
+
+acpi:IWX*:
+ ID_VENDOR_FROM_DATABASE=Intelliworxx, Inc.
+
+acpi:IXD*:
+ ID_VENDOR_FROM_DATABASE=Intertex Data AB
+
+acpi:JAC*:
+ ID_VENDOR_FROM_DATABASE=Astec Inc
+
+acpi:JAE*:
+ ID_VENDOR_FROM_DATABASE=Japan Aviation Electronics Industry, Limited
+
+acpi:JAS*:
+ ID_VENDOR_FROM_DATABASE=Janz Automationssysteme AG
+
+acpi:JAT*:
+ ID_VENDOR_FROM_DATABASE=Jaton Corporation
+
+acpi:JAZ*:
+ ID_VENDOR_FROM_DATABASE=Carrera Computer Inc
+
+acpi:JCE*:
+ ID_VENDOR_FROM_DATABASE=Jace Tech Inc
+
+acpi:JDL*:
+ ID_VENDOR_FROM_DATABASE=Japan Digital Laboratory Co.,Ltd.
+
+acpi:JEN*:
+ ID_VENDOR_FROM_DATABASE=N-Vision
+
+acpi:JET*:
+ ID_VENDOR_FROM_DATABASE=JET POWER TECHNOLOGY CO., LTD.
+
+acpi:JFX*:
+ ID_VENDOR_FROM_DATABASE=Jones Futurex Inc
+
+acpi:JGD*:
+ ID_VENDOR_FROM_DATABASE=University College
+
+acpi:JIC*:
+ ID_VENDOR_FROM_DATABASE=Jaeik Information & Communication Co., Ltd.
+
+acpi:JKC*:
+ ID_VENDOR_FROM_DATABASE=JVC KENWOOD Corporation
+
+acpi:JMT*:
+ ID_VENDOR_FROM_DATABASE=Micro Technical Company Ltd
+
+acpi:JPC*:
+ ID_VENDOR_FROM_DATABASE=JPC Technology Limited
+
+acpi:JPW*:
+ ID_VENDOR_FROM_DATABASE=Wallis Hamilton Industries
+
+acpi:JQE*:
+ ID_VENDOR_FROM_DATABASE=CNet Technical Inc
+
+acpi:JSD*:
+ ID_VENDOR_FROM_DATABASE=JS DigiTech, Inc
+
+acpi:JSI*:
+ ID_VENDOR_FROM_DATABASE=Jupiter Systems, Inc.
+
+acpi:JSK*:
+ ID_VENDOR_FROM_DATABASE=SANKEN ELECTRIC CO., LTD
+
+acpi:JTS*:
+ ID_VENDOR_FROM_DATABASE=JS Motorsports
+
+acpi:JTY*:
+ ID_VENDOR_FROM_DATABASE=jetway security micro,inc
+
+acpi:JUK*:
+ ID_VENDOR_FROM_DATABASE=Janich & Klass Computertechnik GmbH
+
+acpi:JUP*:
+ ID_VENDOR_FROM_DATABASE=Jupiter Systems
+
+acpi:JVC*:
+ ID_VENDOR_FROM_DATABASE=JVC
+
+acpi:JWD*:
+ ID_VENDOR_FROM_DATABASE=Video International Inc.
+
+acpi:JWL*:
+ ID_VENDOR_FROM_DATABASE=Jewell Instruments, LLC
+
+acpi:JWS*:
+ ID_VENDOR_FROM_DATABASE=JWSpencer & Co.
+
+acpi:JWY*:
+ ID_VENDOR_FROM_DATABASE=Jetway Information Co., Ltd
+
+acpi:KAR*:
+ ID_VENDOR_FROM_DATABASE=Karna
+
+acpi:KBI*:
+ ID_VENDOR_FROM_DATABASE=Kidboard Inc
+
+acpi:KBL*:
+ ID_VENDOR_FROM_DATABASE=Kobil Systems GmbH
+
+acpi:KCD*:
+ ID_VENDOR_FROM_DATABASE=Chunichi Denshi Co.,LTD.
+
+acpi:KCL*:
+ ID_VENDOR_FROM_DATABASE=Keycorp Ltd
+
+acpi:KDE*:
+ ID_VENDOR_FROM_DATABASE=KDE
+
+acpi:KDK*:
+ ID_VENDOR_FROM_DATABASE=Kodiak Tech
+
+acpi:KDM*:
+ ID_VENDOR_FROM_DATABASE=Korea Data Systems Co., Ltd.
+
+acpi:KDS*:
+ ID_VENDOR_FROM_DATABASE=KDS USA
+
+acpi:KDT*:
+ ID_VENDOR_FROM_DATABASE=KDDI Technology Corporation
+
+acpi:KEC*:
+ ID_VENDOR_FROM_DATABASE=Kyushu Electronics Systems Inc
+
+acpi:KEM*:
+ ID_VENDOR_FROM_DATABASE=Kontron Embedded Modules GmbH
+
+acpi:KES*:
+ ID_VENDOR_FROM_DATABASE=Kesa Corporation
+
+acpi:KEY*:
+ ID_VENDOR_FROM_DATABASE=Key Tech Inc
+
+acpi:KFC*:
+ ID_VENDOR_FROM_DATABASE=SCD Tech
+
+acpi:KFE*:
+ ID_VENDOR_FROM_DATABASE=Komatsu Forest
+
+acpi:KFX*:
+ ID_VENDOR_FROM_DATABASE=Kofax Image Products
+
+acpi:KGL*:
+ ID_VENDOR_FROM_DATABASE=KEISOKU GIKEN Co.,Ltd.
+
+acpi:KIS*:
+ ID_VENDOR_FROM_DATABASE=KiSS Technology A/S
+
+acpi:KMC*:
+ ID_VENDOR_FROM_DATABASE=Mitsumi Company Ltd
+
+acpi:KME*:
+ ID_VENDOR_FROM_DATABASE=KIMIN Electronics Co., Ltd.
+
+acpi:KML*:
+ ID_VENDOR_FROM_DATABASE=Kensington Microware Ltd
+
+acpi:KNC*:
+ ID_VENDOR_FROM_DATABASE=Konica corporation
+
+acpi:KNX*:
+ ID_VENDOR_FROM_DATABASE=Nutech Marketing PTL
+
+acpi:KOB*:
+ ID_VENDOR_FROM_DATABASE=Kobil Systems GmbH
+
+acpi:KOD*:
+ ID_VENDOR_FROM_DATABASE=Eastman Kodak Company
+
+acpi:KOE*:
+ ID_VENDOR_FROM_DATABASE=KOLTER ELECTRONIC
+
+acpi:KOL*:
+ ID_VENDOR_FROM_DATABASE=Kollmorgen Motion Technologies Group
+
+acpi:KOU*:
+ ID_VENDOR_FROM_DATABASE=KOUZIRO Co.,Ltd.
+
+acpi:KOW*:
+ ID_VENDOR_FROM_DATABASE=KOWA Company,LTD.
+
+acpi:KPC*:
+ ID_VENDOR_FROM_DATABASE=King Phoenix Company
+
+acpi:KRL*:
+ ID_VENDOR_FROM_DATABASE=Krell Industries Inc.
+
+acpi:KRM*:
+ ID_VENDOR_FROM_DATABASE=Kroma Telecom
+
+acpi:KRY*:
+ ID_VENDOR_FROM_DATABASE=Kroy LLC
+
+acpi:KSC*:
+ ID_VENDOR_FROM_DATABASE=Kinetic Systems Corporation
+
+acpi:KSL*:
+ ID_VENDOR_FROM_DATABASE=Karn Solutions Ltd.
+
+acpi:KSX*:
+ ID_VENDOR_FROM_DATABASE=King Tester Corporation
+
+acpi:KTC*:
+ ID_VENDOR_FROM_DATABASE=Kingston Tech Corporation
+
+acpi:KTD*:
+ ID_VENDOR_FROM_DATABASE=Takahata Electronics Co.,Ltd.
+
+acpi:KTE*:
+ ID_VENDOR_FROM_DATABASE=K-Tech
+
+acpi:KTG*:
+ ID_VENDOR_FROM_DATABASE=Kayser-Threde GmbH
+
+acpi:KTI*:
+ ID_VENDOR_FROM_DATABASE=Konica Technical Inc
+
+acpi:KTK*:
+ ID_VENDOR_FROM_DATABASE=Key Tronic Corporation
+
+acpi:KTN*:
+ ID_VENDOR_FROM_DATABASE=Katron Tech Inc
+
+acpi:KUR*:
+ ID_VENDOR_FROM_DATABASE=Kurta Corporation
+
+acpi:KVA*:
+ ID_VENDOR_FROM_DATABASE=Kvaser AB
+
+acpi:KVX*:
+ ID_VENDOR_FROM_DATABASE=KeyView
+
+acpi:KWD*:
+ ID_VENDOR_FROM_DATABASE=Kenwood Corporation
+
+acpi:KYC*:
+ ID_VENDOR_FROM_DATABASE=Kyocera Corporation
+
+acpi:KYE*:
+ ID_VENDOR_FROM_DATABASE=KYE Syst Corporation
+
+acpi:KYK*:
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics America Inc
+
+acpi:KZI*:
+ ID_VENDOR_FROM_DATABASE=K-Zone International co. Ltd.
+
+acpi:KZN*:
+ ID_VENDOR_FROM_DATABASE=K-Zone International
+
+acpi:LAB*:
+ ID_VENDOR_FROM_DATABASE=ACT Labs Ltd
+
+acpi:LAC*:
+ ID_VENDOR_FROM_DATABASE=LaCie
+
+acpi:LAF*:
+ ID_VENDOR_FROM_DATABASE=Microline
+
+acpi:LAG*:
+ ID_VENDOR_FROM_DATABASE=Laguna Systems
+
+acpi:LAN*:
+ ID_VENDOR_FROM_DATABASE=Sodeman Lancom Inc
+
+acpi:LAS*:
+ ID_VENDOR_FROM_DATABASE=LASAT Comm. A/S
+
+acpi:LAV*:
+ ID_VENDOR_FROM_DATABASE=Lava Computer MFG Inc
+
+acpi:LBO*:
+ ID_VENDOR_FROM_DATABASE=Lubosoft
+
+acpi:LCC*:
+ ID_VENDOR_FROM_DATABASE=LCI
+
+acpi:LCD*:
+ ID_VENDOR_FROM_DATABASE=Toshiba Matsushita Display Technology Co., Ltd
+
+acpi:LCE*:
+ ID_VENDOR_FROM_DATABASE=La Commande Electronique
+
+acpi:LCI*:
+ ID_VENDOR_FROM_DATABASE=Lite-On Communication Inc
+
+acpi:LCM*:
+ ID_VENDOR_FROM_DATABASE=Latitude Comm.
+
+acpi:LCN*:
+ ID_VENDOR_FROM_DATABASE=LEXICON
+
+acpi:LCS*:
+ ID_VENDOR_FROM_DATABASE=Longshine Electronics Company
+
+acpi:LCT*:
+ ID_VENDOR_FROM_DATABASE=Labcal Technologies
+
+acpi:LDT*:
+ ID_VENDOR_FROM_DATABASE=LogiDataTech Electronic GmbH
+
+acpi:LEC*:
+ ID_VENDOR_FROM_DATABASE=Lectron Company Ltd
+
+acpi:LED*:
+ ID_VENDOR_FROM_DATABASE=Long Engineering Design Inc
+
+acpi:LEG*:
+ ID_VENDOR_FROM_DATABASE=Legerity, Inc
+
+acpi:LEN*:
+ ID_VENDOR_FROM_DATABASE=Lenovo Group Limited
+
+acpi:LEO*:
+ ID_VENDOR_FROM_DATABASE=First International Computer Inc
+
+acpi:LEX*:
+ ID_VENDOR_FROM_DATABASE=Lexical Ltd
+
+acpi:LGC*:
+ ID_VENDOR_FROM_DATABASE=Logic Ltd
+
+acpi:LGI*:
+ ID_VENDOR_FROM_DATABASE=Logitech Inc
+
+acpi:LGS*:
+ ID_VENDOR_FROM_DATABASE=LG Semicom Company Ltd
+
+acpi:LGX*:
+ ID_VENDOR_FROM_DATABASE=Lasergraphics, Inc.
+
+acpi:LHA*:
+ ID_VENDOR_FROM_DATABASE=Lars Haagh ApS
+
+acpi:LHE*:
+ ID_VENDOR_FROM_DATABASE=Lung Hwa Electronics Company Ltd
+
+acpi:LHT*:
+ ID_VENDOR_FROM_DATABASE=Lighthouse Technologies Limited
+
+acpi:LIN*:
+ ID_VENDOR_FROM_DATABASE=Lenovo Beijing Co. Ltd.
+
+acpi:LIP*:
+ ID_VENDOR_FROM_DATABASE=Linked IP GmbH
+
+acpi:LIT*:
+ ID_VENDOR_FROM_DATABASE=Lithics Silicon Technology
+
+acpi:LJX*:
+ ID_VENDOR_FROM_DATABASE=Datalogic Corporation
+
+acpi:LKM*:
+ ID_VENDOR_FROM_DATABASE=Likom Technology Sdn. Bhd.
+
+acpi:LLL*:
+ ID_VENDOR_FROM_DATABASE=L-3 Communications
+
+acpi:LMG*:
+ ID_VENDOR_FROM_DATABASE=Lucent Technologies
+
+acpi:LMI*:
+ ID_VENDOR_FROM_DATABASE=Lexmark Int'l Inc
+
+acpi:LMP*:
+ ID_VENDOR_FROM_DATABASE=Leda Media Products
+
+acpi:LMT*:
+ ID_VENDOR_FROM_DATABASE=Laser Master
+
+acpi:LND*:
+ ID_VENDOR_FROM_DATABASE=Land Computer Company Ltd
+
+acpi:LNK*:
+ ID_VENDOR_FROM_DATABASE=Link Tech Inc
+
+acpi:LNR*:
+ ID_VENDOR_FROM_DATABASE=Linear Systems Ltd.
+
+acpi:LNT*:
+ ID_VENDOR_FROM_DATABASE=LANETCO International
+
+acpi:LNV*:
+ ID_VENDOR_FROM_DATABASE=Lenovo
+
+acpi:LOC*:
+ ID_VENDOR_FROM_DATABASE=Locamation B.V.
+
+acpi:LOE*:
+ ID_VENDOR_FROM_DATABASE=Loewe Opta GmbH
+
+acpi:LOG*:
+ ID_VENDOR_FROM_DATABASE=Logicode Technology Inc
+
+acpi:LOL*:
+ ID_VENDOR_FROM_DATABASE=Litelogic Operations Ltd
+
+acpi:LPE*:
+ ID_VENDOR_FROM_DATABASE=El-PUSK Co., Ltd.
+
+acpi:LPI*:
+ ID_VENDOR_FROM_DATABASE=Design Technology
+
+acpi:LSC*:
+ ID_VENDOR_FROM_DATABASE=LifeSize Communications
+
+acpi:LSD*:
+ ID_VENDOR_FROM_DATABASE=Intersil Corporation
+
+acpi:LSI*:
+ ID_VENDOR_FROM_DATABASE=Loughborough Sound Images
+
+acpi:LSJ*:
+ ID_VENDOR_FROM_DATABASE=LSI Japan Company Ltd
+
+acpi:LSL*:
+ ID_VENDOR_FROM_DATABASE=Logical Solutions
+
+acpi:LSY*:
+ ID_VENDOR_FROM_DATABASE=LSI Systems Inc
+
+acpi:LTC*:
+ ID_VENDOR_FROM_DATABASE=Labtec Inc
+
+acpi:LTI*:
+ ID_VENDOR_FROM_DATABASE=Jongshine Tech Inc
+
+acpi:LTK*:
+ ID_VENDOR_FROM_DATABASE=Lucidity Technology Company Ltd
+
+acpi:LTN*:
+ ID_VENDOR_FROM_DATABASE=Litronic Inc
+
+acpi:LTS*:
+ ID_VENDOR_FROM_DATABASE=LTS Scale LLC
+
+acpi:LTV*:
+ ID_VENDOR_FROM_DATABASE=Leitch Technology International Inc.
+
+acpi:LTW*:
+ ID_VENDOR_FROM_DATABASE=Lightware, Inc
+
+acpi:LUC*:
+ ID_VENDOR_FROM_DATABASE=Lucent Technologies
+
+acpi:LUM*:
+ ID_VENDOR_FROM_DATABASE=Lumagen, Inc.
+
+acpi:LUX*:
+ ID_VENDOR_FROM_DATABASE=Luxxell Research Inc
+
+acpi:LVI*:
+ ID_VENDOR_FROM_DATABASE=LVI Low Vision International AB
+
+acpi:LWC*:
+ ID_VENDOR_FROM_DATABASE=Labway Corporation
+
+acpi:LWR*:
+ ID_VENDOR_FROM_DATABASE=Lightware Visual Engineering
+
+acpi:LWW*:
+ ID_VENDOR_FROM_DATABASE=Lanier Worldwide
+
+acpi:LXC*:
+ ID_VENDOR_FROM_DATABASE=LXCO Technologies AG
+
+acpi:LXN*:
+ ID_VENDOR_FROM_DATABASE=Luxeon
+
+acpi:LXS*:
+ ID_VENDOR_FROM_DATABASE=ELEA CardWare
+
+acpi:LZX*:
+ ID_VENDOR_FROM_DATABASE=Lightwell Company Ltd
+
+acpi:MAC*:
+ ID_VENDOR_FROM_DATABASE=MAC System Company Ltd
+
+acpi:MAD*:
+ ID_VENDOR_FROM_DATABASE=Xedia Corporation
+
+acpi:MAE*:
+ ID_VENDOR_FROM_DATABASE=Maestro Pty Ltd
+
+acpi:MAG*:
+ ID_VENDOR_FROM_DATABASE=MAG InnoVision
+
+acpi:MAI*:
+ ID_VENDOR_FROM_DATABASE=Mutoh America Inc
+
+acpi:MAL*:
+ ID_VENDOR_FROM_DATABASE=Meridian Audio Ltd
+
+acpi:MAN*:
+ ID_VENDOR_FROM_DATABASE=LGIC
+
+acpi:MAS*:
+ ID_VENDOR_FROM_DATABASE=Mass Inc.
+
+acpi:MAT*:
+ ID_VENDOR_FROM_DATABASE=Matsushita Electric Ind. Company Ltd
+
+acpi:MAX*:
+ ID_VENDOR_FROM_DATABASE=Rogen Tech Distribution Inc
+
+acpi:MAY*:
+ ID_VENDOR_FROM_DATABASE=Maynard Electronics
+
+acpi:MAZ*:
+ ID_VENDOR_FROM_DATABASE=MAZeT GmbH
+
+acpi:MBC*:
+ ID_VENDOR_FROM_DATABASE=MBC
+
+acpi:MBD*:
+ ID_VENDOR_FROM_DATABASE=Microbus PLC
+
+acpi:MBM*:
+ ID_VENDOR_FROM_DATABASE=Marshall Electronics
+
+acpi:MBV*:
+ ID_VENDOR_FROM_DATABASE=Moreton Bay
+
+acpi:MCA*:
+ ID_VENDOR_FROM_DATABASE=American Nuclear Systems Inc
+
+acpi:MCC*:
+ ID_VENDOR_FROM_DATABASE=Micro Industries
+
+acpi:MCD*:
+ ID_VENDOR_FROM_DATABASE=McDATA Corporation
+
+acpi:MCE*:
+ ID_VENDOR_FROM_DATABASE=Metz-Werke GmbH & Co KG
+
+acpi:MCG*:
+ ID_VENDOR_FROM_DATABASE=Motorola Computer Group
+
+acpi:MCI*:
+ ID_VENDOR_FROM_DATABASE=Micronics Computers
+
+acpi:MCL*:
+ ID_VENDOR_FROM_DATABASE=Motorola Communications Israel
+
+acpi:MCM*:
+ ID_VENDOR_FROM_DATABASE=Metricom Inc
+
+acpi:MCN*:
+ ID_VENDOR_FROM_DATABASE=Micron Electronics Inc
+
+acpi:MCO*:
+ ID_VENDOR_FROM_DATABASE=Motion Computing Inc.
+
+acpi:MCP*:
+ ID_VENDOR_FROM_DATABASE=Magni Systems Inc
+
+acpi:MCQ*:
+ ID_VENDOR_FROM_DATABASE=Mat's Computers
+
+acpi:MCR*:
+ ID_VENDOR_FROM_DATABASE=Marina Communicaitons
+
+acpi:MCS*:
+ ID_VENDOR_FROM_DATABASE=Micro Computer Systems
+
+acpi:MCT*:
+ ID_VENDOR_FROM_DATABASE=Microtec
+
+acpi:MDA*:
+ ID_VENDOR_FROM_DATABASE=Media4 Inc
+
+acpi:MDC*:
+ ID_VENDOR_FROM_DATABASE=Midori Electronics
+
+acpi:MDD*:
+ ID_VENDOR_FROM_DATABASE=MODIS
+
+acpi:MDG*:
+ ID_VENDOR_FROM_DATABASE=Madge Networks
+
+acpi:MDI*:
+ ID_VENDOR_FROM_DATABASE=Micro Design Inc
+
+acpi:MDK*:
+ ID_VENDOR_FROM_DATABASE=Mediatek Corporation
+
+acpi:MDO*:
+ ID_VENDOR_FROM_DATABASE=Panasonic
+
+acpi:MDR*:
+ ID_VENDOR_FROM_DATABASE=Medar Inc
+
+acpi:MDS*:
+ ID_VENDOR_FROM_DATABASE=Micro Display Systems Inc
+
+acpi:MDT*:
+ ID_VENDOR_FROM_DATABASE=Magus Data Tech
+
+acpi:MDV*:
+ ID_VENDOR_FROM_DATABASE=MET Development Inc
+
+acpi:MDX*:
+ ID_VENDOR_FROM_DATABASE=MicroDatec GmbH
+
+acpi:MDY*:
+ ID_VENDOR_FROM_DATABASE=Microdyne Inc
+
+acpi:MEC*:
+ ID_VENDOR_FROM_DATABASE=Mega System Technologies Inc
+
+acpi:MED*:
+ ID_VENDOR_FROM_DATABASE=Messeltronik Dresden GmbH
+
+acpi:MEE*:
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Engineering Co., Ltd.
+
+acpi:MEG*:
+ ID_VENDOR_FROM_DATABASE=Abeam Tech Ltd
+
+acpi:MEI*:
+ ID_VENDOR_FROM_DATABASE=Panasonic Industry Company
+
+acpi:MEJ*:
+ ID_VENDOR_FROM_DATABASE=Mac-Eight Co., LTD.
+
+acpi:MEL*:
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corporation
+
+acpi:MEN*:
+ ID_VENDOR_FROM_DATABASE=MEN Mikroelectronik Nueruberg GmbH
+
+acpi:MEQ*:
+ ID_VENDOR_FROM_DATABASE=Matelect Ltd.
+
+acpi:MET*:
+ ID_VENDOR_FROM_DATABASE=Metheus Corporation
+
+acpi:MEX*:
+ ID_VENDOR_FROM_DATABASE=MSC Vertriebs GmbH
+
+acpi:MFG*:
+ ID_VENDOR_FROM_DATABASE=MicroField Graphics Inc
+
+acpi:MFI*:
+ ID_VENDOR_FROM_DATABASE=Micro Firmware
+
+acpi:MFR*:
+ ID_VENDOR_FROM_DATABASE=MediaFire Corp.
+
+acpi:MGA*:
+ ID_VENDOR_FROM_DATABASE=Mega System Technologies, Inc.
+
+acpi:MGC*:
+ ID_VENDOR_FROM_DATABASE=Mentor Graphics Corporation
+
+acpi:MGE*:
+ ID_VENDOR_FROM_DATABASE=Schneider Electric S.A.
+
+acpi:MGL*:
+ ID_VENDOR_FROM_DATABASE=M-G Technology Ltd
+
+acpi:MGT*:
+ ID_VENDOR_FROM_DATABASE=Megatech R & D Company
+
+acpi:MIC*:
+ ID_VENDOR_FROM_DATABASE=Micom Communications Inc
+
+acpi:MID*:
+ ID_VENDOR_FROM_DATABASE=miro Displays
+
+acpi:MII*:
+ ID_VENDOR_FROM_DATABASE=Mitec Inc
+
+acpi:MIL*:
+ ID_VENDOR_FROM_DATABASE=Marconi Instruments Ltd
+
+acpi:MIM*:
+ ID_VENDOR_FROM_DATABASE=Mimio – A Newell Rubbermaid Company
+
+acpi:MIN*:
+ ID_VENDOR_FROM_DATABASE=Minicom Digital Signage
+
+acpi:MIP*:
+ ID_VENDOR_FROM_DATABASE=micronpc.com
+
+acpi:MIR*:
+ ID_VENDOR_FROM_DATABASE=Miro Computer Prod.
+
+acpi:MIS*:
+ ID_VENDOR_FROM_DATABASE=Modular Industrial Solutions Inc
+
+acpi:MIT*:
+ ID_VENDOR_FROM_DATABASE=MCM Industrial Technology GmbH
+
+acpi:MJI*:
+ ID_VENDOR_FROM_DATABASE=MARANTZ JAPAN, INC.
+
+acpi:MJS*:
+ ID_VENDOR_FROM_DATABASE=MJS Designs
+
+acpi:MKC*:
+ ID_VENDOR_FROM_DATABASE=Media Tek Inc.
+
+acpi:MKT*:
+ ID_VENDOR_FROM_DATABASE=MICROTEK Inc.
+
+acpi:MKV*:
+ ID_VENDOR_FROM_DATABASE=Trtheim Technology
+
+acpi:MLD*:
+ ID_VENDOR_FROM_DATABASE=Deep Video Imaging Ltd
+
+acpi:MLG*:
+ ID_VENDOR_FROM_DATABASE=Micrologica AG
+
+acpi:MLI*:
+ ID_VENDOR_FROM_DATABASE=McIntosh Laboratory Inc.
+
+acpi:MLM*:
+ ID_VENDOR_FROM_DATABASE=Millennium Engineering Inc
+
+acpi:MLN*:
+ ID_VENDOR_FROM_DATABASE=Mark Levinson
+
+acpi:MLS*:
+ ID_VENDOR_FROM_DATABASE=Milestone EPE
+
+acpi:MLX*:
+ ID_VENDOR_FROM_DATABASE=Mylex Corporation
+
+acpi:MMA*:
+ ID_VENDOR_FROM_DATABASE=Micromedia AG
+
+acpi:MMD*:
+ ID_VENDOR_FROM_DATABASE=Micromed Biotecnologia Ltd
+
+acpi:MMF*:
+ ID_VENDOR_FROM_DATABASE=Minnesota Mining and Manufacturing
+
+acpi:MMI*:
+ ID_VENDOR_FROM_DATABASE=Multimax
+
+acpi:MMM*:
+ ID_VENDOR_FROM_DATABASE=Electronic Measurements
+
+acpi:MMN*:
+ ID_VENDOR_FROM_DATABASE=MiniMan Inc
+
+acpi:MMS*:
+ ID_VENDOR_FROM_DATABASE=MMS Electronics
+
+acpi:MNC*:
+ ID_VENDOR_FROM_DATABASE=Mini Micro Methods Ltd
+
+acpi:MNL*:
+ ID_VENDOR_FROM_DATABASE=Monorail Inc
+
+acpi:MNP*:
+ ID_VENDOR_FROM_DATABASE=Microcom
+
+acpi:MOD*:
+ ID_VENDOR_FROM_DATABASE=Modular Technology
+
+acpi:MOM*:
+ ID_VENDOR_FROM_DATABASE=Momentum Data Systems
+
+acpi:MOS*:
+ ID_VENDOR_FROM_DATABASE=Moses Corporation
+
+acpi:MOT*:
+ ID_VENDOR_FROM_DATABASE=Motorola UDS
+
+acpi:MPC*:
+ ID_VENDOR_FROM_DATABASE=M-Pact Inc
+
+acpi:MPI*:
+ ID_VENDOR_FROM_DATABASE=Mediatrix Peripherals Inc
+
+acpi:MPJ*:
+ ID_VENDOR_FROM_DATABASE=Microlab
+
+acpi:MPL*:
+ ID_VENDOR_FROM_DATABASE=Maple Research Inst. Company Ltd
+
+acpi:MPN*:
+ ID_VENDOR_FROM_DATABASE=Mainpine Limited
+
+acpi:MPS*:
+ ID_VENDOR_FROM_DATABASE=mps Software GmbH
+
+acpi:MPX*:
+ ID_VENDOR_FROM_DATABASE=Micropix Technologies, Ltd.
+
+acpi:MQP*:
+ ID_VENDOR_FROM_DATABASE=MultiQ Products AB
+
+acpi:MRA*:
+ ID_VENDOR_FROM_DATABASE=Miranda Technologies Inc
+
+acpi:MRC*:
+ ID_VENDOR_FROM_DATABASE=Marconi Simulation & Ty-Coch Way Training
+
+acpi:MRD*:
+ ID_VENDOR_FROM_DATABASE=MicroDisplay Corporation
+
+acpi:MRK*:
+ ID_VENDOR_FROM_DATABASE=Maruko & Company Ltd
+
+acpi:MRL*:
+ ID_VENDOR_FROM_DATABASE=Miratel
+
+acpi:MRO*:
+ ID_VENDOR_FROM_DATABASE=Medikro Oy
+
+acpi:MRT*:
+ ID_VENDOR_FROM_DATABASE=Merging Technologies
+
+acpi:MSA*:
+ ID_VENDOR_FROM_DATABASE=Micro Systemation AB
+
+acpi:MSC*:
+ ID_VENDOR_FROM_DATABASE=Mouse Systems Corporation
+
+acpi:MSD*:
+ ID_VENDOR_FROM_DATABASE=Datenerfassungs- und Informationssysteme
+
+acpi:MSF*:
+ ID_VENDOR_FROM_DATABASE=M-Systems Flash Disk Pioneers
+
+acpi:MSG*:
+ ID_VENDOR_FROM_DATABASE=MSI GmbH
+
+acpi:MSH*:
+ ID_VENDOR_FROM_DATABASE=Microsoft
+
+acpi:MSI*:
+ ID_VENDOR_FROM_DATABASE=Microstep
+
+acpi:MSK*:
+ ID_VENDOR_FROM_DATABASE=Megasoft Inc
+
+acpi:MSL*:
+ ID_VENDOR_FROM_DATABASE=MicroSlate Inc.
+
+acpi:MSM*:
+ ID_VENDOR_FROM_DATABASE=Advanced Digital Systems
+
+acpi:MSP*:
+ ID_VENDOR_FROM_DATABASE=Mistral Solutions [P] Ltd.
+
+acpi:MST*:
+ ID_VENDOR_FROM_DATABASE=MS Telematica
+
+acpi:MSU*:
+ ID_VENDOR_FROM_DATABASE=motorola
+
+acpi:MSV*:
+ ID_VENDOR_FROM_DATABASE=Mosgi Corporation
+
+acpi:MSX*:
+ ID_VENDOR_FROM_DATABASE=Micomsoft Co., Ltd.
+
+acpi:MSY*:
+ ID_VENDOR_FROM_DATABASE=MicroTouch Systems Inc
+
+acpi:MTB*:
+ ID_VENDOR_FROM_DATABASE=Media Technologies Ltd.
+
+acpi:MTC*:
+ ID_VENDOR_FROM_DATABASE=Mars-Tech Corporation
+
+acpi:MTD*:
+ ID_VENDOR_FROM_DATABASE=MindTech Display Co. Ltd
+
+acpi:MTE*:
+ ID_VENDOR_FROM_DATABASE=MediaTec GmbH
+
+acpi:MTH*:
+ ID_VENDOR_FROM_DATABASE=Micro-Tech Hearing Instruments
+
+acpi:MTI*:
+ ID_VENDOR_FROM_DATABASE=MaxCom Technical Inc
+
+acpi:MTK*:
+ ID_VENDOR_FROM_DATABASE=Microtek International Inc.
+
+acpi:MTL*:
+ ID_VENDOR_FROM_DATABASE=Mitel Corporation
+
+acpi:MTM*:
+ ID_VENDOR_FROM_DATABASE=Motium
+
+acpi:MTN*:
+ ID_VENDOR_FROM_DATABASE=Mtron Storage Technology Co., Ltd.
+
+acpi:MTR*:
+ ID_VENDOR_FROM_DATABASE=Mitron computer Inc
+
+acpi:MTS*:
+ ID_VENDOR_FROM_DATABASE=Multi-Tech Systems
+
+acpi:MTU*:
+ ID_VENDOR_FROM_DATABASE=Mark of the Unicorn Inc
+
+acpi:MTX*:
+ ID_VENDOR_FROM_DATABASE=Matrox
+
+acpi:MUD*:
+ ID_VENDOR_FROM_DATABASE=Multi-Dimension Institute
+
+acpi:MUK*:
+ ID_VENDOR_FROM_DATABASE=mainpine limited
+
+acpi:MVD*:
+ ID_VENDOR_FROM_DATABASE=Microvitec PLC
+
+acpi:MVI*:
+ ID_VENDOR_FROM_DATABASE=Media Vision Inc
+
+acpi:MVM*:
+ ID_VENDOR_FROM_DATABASE=SOBO VISION
+
+acpi:MVS*:
+ ID_VENDOR_FROM_DATABASE=Microvision
+
+acpi:MVX*:
+ ID_VENDOR_FROM_DATABASE=COM 1
+
+acpi:MWI*:
+ ID_VENDOR_FROM_DATABASE=Multiwave Innovation Pte Ltd
+
+acpi:MWR*:
+ ID_VENDOR_FROM_DATABASE=mware
+
+acpi:MWY*:
+ ID_VENDOR_FROM_DATABASE=Microway Inc
+
+acpi:MXD*:
+ ID_VENDOR_FROM_DATABASE=MaxData Computer GmbH & Co.KG
+
+acpi:MXI*:
+ ID_VENDOR_FROM_DATABASE=Macronix Inc
+
+acpi:MXL*:
+ ID_VENDOR_FROM_DATABASE=Hitachi Maxell, Ltd.
+
+acpi:MXP*:
+ ID_VENDOR_FROM_DATABASE=Maxpeed Corporation
+
+acpi:MXT*:
+ ID_VENDOR_FROM_DATABASE=Maxtech Corporation
+
+acpi:MXV*:
+ ID_VENDOR_FROM_DATABASE=MaxVision Corporation
+
+acpi:MYA*:
+ ID_VENDOR_FROM_DATABASE=Monydata
+
+acpi:MYR*:
+ ID_VENDOR_FROM_DATABASE=Myriad Solutions Ltd
+
+acpi:MYX*:
+ ID_VENDOR_FROM_DATABASE=Micronyx Inc
+
+acpi:NAC*:
+ ID_VENDOR_FROM_DATABASE=Ncast Corporation
+
+acpi:NAD*:
+ ID_VENDOR_FROM_DATABASE=NAD Electronics
+
+acpi:NAK*:
+ ID_VENDOR_FROM_DATABASE=Nakano Engineering Co.,Ltd.
+
+acpi:NAL*:
+ ID_VENDOR_FROM_DATABASE=Network Alchemy
+
+acpi:NAT*:
+ ID_VENDOR_FROM_DATABASE=NaturalPoint Inc.
+
+acpi:NAV*:
+ ID_VENDOR_FROM_DATABASE=Navigation Corporation
+
+acpi:NAX*:
+ ID_VENDOR_FROM_DATABASE=Naxos Tecnologia
+
+acpi:NBL*:
+ ID_VENDOR_FROM_DATABASE=N*Able Technologies Inc
+
+acpi:NBS*:
+ ID_VENDOR_FROM_DATABASE=National Key Lab. on ISN
+
+acpi:NBT*:
+ ID_VENDOR_FROM_DATABASE=NingBo Bestwinning Technology CO., Ltd
+
+acpi:NCA*:
+ ID_VENDOR_FROM_DATABASE=Nixdorf Company
+
+acpi:NCC*:
+ ID_VENDOR_FROM_DATABASE=NCR Corporation
+
+acpi:NCE*:
+ ID_VENDOR_FROM_DATABASE=Norcent Technology, Inc.
+
+acpi:NCI*:
+ ID_VENDOR_FROM_DATABASE=NewCom Inc
+
+acpi:NCL*:
+ ID_VENDOR_FROM_DATABASE=NetComm Ltd
+
+acpi:NCR*:
+ ID_VENDOR_FROM_DATABASE=NCR Electronics
+
+acpi:NCS*:
+ ID_VENDOR_FROM_DATABASE=Northgate Computer Systems
+
+acpi:NCT*:
+ ID_VENDOR_FROM_DATABASE=NEC CustomTechnica, Ltd.
+
+acpi:NDC*:
+ ID_VENDOR_FROM_DATABASE=National DataComm Corporaiton
+
+acpi:NDI*:
+ ID_VENDOR_FROM_DATABASE=National Display Systems
+
+acpi:NDK*:
+ ID_VENDOR_FROM_DATABASE=Naitoh Densei CO., LTD.
+
+acpi:NDL*:
+ ID_VENDOR_FROM_DATABASE=Network Designers
+
+acpi:NDS*:
+ ID_VENDOR_FROM_DATABASE=Nokia Data
+
+acpi:NEC*:
+ ID_VENDOR_FROM_DATABASE=NEC Corporation
+
+acpi:NEO*:
+ ID_VENDOR_FROM_DATABASE=NEO TELECOM CO.,LTD.
+
+acpi:NET*:
+ ID_VENDOR_FROM_DATABASE=Mettler Toledo
+
+acpi:NEU*:
+ ID_VENDOR_FROM_DATABASE=NEUROTEC - EMPRESA DE PESQUISA E DESENVOLVIMENTO EM BIOMEDICINA
+
+acpi:NEX*:
+ ID_VENDOR_FROM_DATABASE=Nexgen Mediatech Inc.,
+
+acpi:NFC*:
+ ID_VENDOR_FROM_DATABASE=BTC Korea Co., Ltd
+
+acpi:NFS*:
+ ID_VENDOR_FROM_DATABASE=Number Five Software
+
+acpi:NGC*:
+ ID_VENDOR_FROM_DATABASE=Network General
+
+acpi:NGS*:
+ ID_VENDOR_FROM_DATABASE=A D S Exports
+
+acpi:NHT*:
+ ID_VENDOR_FROM_DATABASE=Vinci Labs
+
+acpi:NIC*:
+ ID_VENDOR_FROM_DATABASE=National Instruments Corporation
+
+acpi:NIS*:
+ ID_VENDOR_FROM_DATABASE=Nissei Electric Company
+
+acpi:NIT*:
+ ID_VENDOR_FROM_DATABASE=Network Info Technology
+
+acpi:NIX*:
+ ID_VENDOR_FROM_DATABASE=Seanix Technology Inc
+
+acpi:NLC*:
+ ID_VENDOR_FROM_DATABASE=Next Level Communications
+
+acpi:NMP*:
+ ID_VENDOR_FROM_DATABASE=Nokia Mobile Phones
+
+acpi:NMS*:
+ ID_VENDOR_FROM_DATABASE=Natural Micro System
+
+acpi:NMV*:
+ ID_VENDOR_FROM_DATABASE=NEC-Mitsubishi Electric Visual Systems Corporation
+
+acpi:NMX*:
+ ID_VENDOR_FROM_DATABASE=Neomagic
+
+acpi:NNC*:
+ ID_VENDOR_FROM_DATABASE=NNC
+
+acpi:NOE*:
+ ID_VENDOR_FROM_DATABASE=NordicEye AB
+
+acpi:NOI*:
+ ID_VENDOR_FROM_DATABASE=North Invent A/S
+
+acpi:NOK*:
+ ID_VENDOR_FROM_DATABASE=Nokia Display Products
+
+acpi:NOR*:
+ ID_VENDOR_FROM_DATABASE=Norand Corporation
+
+acpi:NOT*:
+ ID_VENDOR_FROM_DATABASE=Not Limited Inc
+
+acpi:NPI*:
+ ID_VENDOR_FROM_DATABASE=Network Peripherals Inc
+
+acpi:NRL*:
+ ID_VENDOR_FROM_DATABASE=U.S. Naval Research Lab
+
+acpi:NRT*:
+ ID_VENDOR_FROM_DATABASE=Beijing Northern Radiantelecom Co.
+
+acpi:NRV*:
+ ID_VENDOR_FROM_DATABASE=Taugagreining hf
+
+acpi:NSC*:
+ ID_VENDOR_FROM_DATABASE=National Semiconductor Corporation
+
+acpi:NSI*:
+ ID_VENDOR_FROM_DATABASE=NISSEI ELECTRIC CO.,LTD
+
+acpi:NSP*:
+ ID_VENDOR_FROM_DATABASE=Nspire System Inc.
+
+acpi:NSS*:
+ ID_VENDOR_FROM_DATABASE=Newport Systems Solutions
+
+acpi:NST*:
+ ID_VENDOR_FROM_DATABASE=Network Security Technology Co
+
+acpi:NTC*:
+ ID_VENDOR_FROM_DATABASE=NeoTech S.R.L
+
+acpi:NTI*:
+ ID_VENDOR_FROM_DATABASE=New Tech Int'l Company
+
+acpi:NTL*:
+ ID_VENDOR_FROM_DATABASE=National Transcomm. Ltd
+
+acpi:NTN*:
+ ID_VENDOR_FROM_DATABASE=Nuvoton Technology Corporation
+
+acpi:NTR*:
+ ID_VENDOR_FROM_DATABASE=N-trig Innovative Technologies, Inc.
+
+acpi:NTS*:
+ ID_VENDOR_FROM_DATABASE=Nits Technology Inc.
+
+acpi:NTT*:
+ ID_VENDOR_FROM_DATABASE=NTT Advanced Technology Corporation
+
+acpi:NTW*:
+ ID_VENDOR_FROM_DATABASE=Networth Inc
+
+acpi:NTX*:
+ ID_VENDOR_FROM_DATABASE=Netaccess Inc
+
+acpi:NUG*:
+ ID_VENDOR_FROM_DATABASE=NU Technology, Inc.
+
+acpi:NUI*:
+ ID_VENDOR_FROM_DATABASE=NU Inc.
+
+acpi:NVC*:
+ ID_VENDOR_FROM_DATABASE=NetVision Corporation
+
+acpi:NVD*:
+ ID_VENDOR_FROM_DATABASE=Nvidia
+
+acpi:NVI*:
+ ID_VENDOR_FROM_DATABASE=NuVision US, Inc.
+
+acpi:NVL*:
+ ID_VENDOR_FROM_DATABASE=Novell Inc
+
+acpi:NVT*:
+ ID_VENDOR_FROM_DATABASE=Navatek Engineering Corporation
+
+acpi:NWC*:
+ ID_VENDOR_FROM_DATABASE=NW Computer Engineering
+
+acpi:NWP*:
+ ID_VENDOR_FROM_DATABASE=NovaWeb Technologies Inc
+
+acpi:NWS*:
+ ID_VENDOR_FROM_DATABASE=Newisys, Inc.
+
+acpi:NXC*:
+ ID_VENDOR_FROM_DATABASE=NextCom K.K.
+
+acpi:NXG*:
+ ID_VENDOR_FROM_DATABASE=Nexgen
+
+acpi:NXP*:
+ ID_VENDOR_FROM_DATABASE=NXP Semiconductors bv.
+
+acpi:NXQ*:
+ ID_VENDOR_FROM_DATABASE=Nexiq Technologies, Inc.
+
+acpi:NXS*:
+ ID_VENDOR_FROM_DATABASE=Technology Nexus Secure Open Systems AB
+
+acpi:NYC*:
+ ID_VENDOR_FROM_DATABASE=nakayo telecommunications,inc.
+
+acpi:OAK*:
+ ID_VENDOR_FROM_DATABASE=Oak Tech Inc
+
+acpi:OAS*:
+ ID_VENDOR_FROM_DATABASE=Oasys Technology Company
+
+acpi:OBS*:
+ ID_VENDOR_FROM_DATABASE=Optibase Technologies
+
+acpi:OCD*:
+ ID_VENDOR_FROM_DATABASE=Macraigor Systems Inc
+
+acpi:OCN*:
+ ID_VENDOR_FROM_DATABASE=Olfan
+
+acpi:OCS*:
+ ID_VENDOR_FROM_DATABASE=Open Connect Solutions
+
+acpi:ODM*:
+ ID_VENDOR_FROM_DATABASE=ODME Inc.
+
+acpi:ODR*:
+ ID_VENDOR_FROM_DATABASE=Odrac
+
+acpi:OEC*:
+ ID_VENDOR_FROM_DATABASE=ORION ELECTRIC CO.,LTD
+
+acpi:OEI*:
+ ID_VENDOR_FROM_DATABASE=Optum Engineering Inc.
+
+acpi:OIC*:
+ ID_VENDOR_FROM_DATABASE=Option Industrial Computers
+
+acpi:OIM*:
+ ID_VENDOR_FROM_DATABASE=Option International
+
+acpi:OIN*:
+ ID_VENDOR_FROM_DATABASE=Option International
+
+acpi:OKI*:
+ ID_VENDOR_FROM_DATABASE=OKI Electric Industrial Company Ltd
+
+acpi:OLC*:
+ ID_VENDOR_FROM_DATABASE=Olicom A/S
+
+acpi:OLD*:
+ ID_VENDOR_FROM_DATABASE=Olidata S.p.A.
+
+acpi:OLI*:
+ ID_VENDOR_FROM_DATABASE=Olivetti
+
+acpi:OLT*:
+ ID_VENDOR_FROM_DATABASE=Olitec S.A.
+
+acpi:OLV*:
+ ID_VENDOR_FROM_DATABASE=Olitec S.A.
+
+acpi:OLY*:
+ ID_VENDOR_FROM_DATABASE=OLYMPUS CORPORATION
+
+acpi:OMC*:
+ ID_VENDOR_FROM_DATABASE=OBJIX Multimedia Corporation
+
+acpi:OMN*:
+ ID_VENDOR_FROM_DATABASE=Omnitel
+
+acpi:OMR*:
+ ID_VENDOR_FROM_DATABASE=Omron Corporation
+
+acpi:ONE*:
+ ID_VENDOR_FROM_DATABASE=Oneac Corporation
+
+acpi:ONK*:
+ ID_VENDOR_FROM_DATABASE=ONKYO Corporation
+
+acpi:ONL*:
+ ID_VENDOR_FROM_DATABASE=OnLive, Inc
+
+acpi:ONS*:
+ ID_VENDOR_FROM_DATABASE=On Systems Inc
+
+acpi:ONW*:
+ ID_VENDOR_FROM_DATABASE=OPEN Networks Ltd
+
+acpi:ONX*:
+ ID_VENDOR_FROM_DATABASE=SOMELEC Z.I. Du Vert Galanta
+
+acpi:OOS*:
+ ID_VENDOR_FROM_DATABASE=OSRAM
+
+acpi:OPC*:
+ ID_VENDOR_FROM_DATABASE=Opcode Inc
+
+acpi:OPI*:
+ ID_VENDOR_FROM_DATABASE=D.N.S. Corporation
+
+acpi:OPP*:
+ ID_VENDOR_FROM_DATABASE=OPPO Digital, Inc.
+
+acpi:OPT*:
+ ID_VENDOR_FROM_DATABASE=OPTi Inc
+
+acpi:OPV*:
+ ID_VENDOR_FROM_DATABASE=Optivision Inc
+
+acpi:OQI*:
+ ID_VENDOR_FROM_DATABASE=Oksori Company Ltd
+
+acpi:ORG*:
+ ID_VENDOR_FROM_DATABASE=ORGA Kartensysteme GmbH
+
+acpi:ORI*:
+ ID_VENDOR_FROM_DATABASE=OSR Open Systems Resources, Inc.
+
+acpi:ORN*:
+ ID_VENDOR_FROM_DATABASE=ORION ELECTRIC CO., LTD.
+
+acpi:OSA*:
+ ID_VENDOR_FROM_DATABASE=OSAKA Micro Computer, Inc.
+
+acpi:OSP*:
+ ID_VENDOR_FROM_DATABASE=OPTI-UPS Corporation
+
+acpi:OSR*:
+ ID_VENDOR_FROM_DATABASE=Oksori Company Ltd
+
+acpi:OTB*:
+ ID_VENDOR_FROM_DATABASE=outsidetheboxstuff.com
+
+acpi:OTI*:
+ ID_VENDOR_FROM_DATABASE=Orchid Technology
+
+acpi:OTM*:
+ ID_VENDOR_FROM_DATABASE=Optoma Corporation          
+
+acpi:OTT*:
+ ID_VENDOR_FROM_DATABASE=OPTO22, Inc.
+
+acpi:OUK*:
+ ID_VENDOR_FROM_DATABASE=OUK Company Ltd
+
+acpi:OWL*:
+ ID_VENDOR_FROM_DATABASE=Mediacom Technologies Pte Ltd
+
+acpi:OXU*:
+ ID_VENDOR_FROM_DATABASE=Oxus Research S.A.
+
+acpi:OYO*:
+ ID_VENDOR_FROM_DATABASE=Shadow Systems
+
+acpi:OZC*:
+ ID_VENDOR_FROM_DATABASE=OZ Corporation
+
+acpi:OZO*:
+ ID_VENDOR_FROM_DATABASE=Tribe Computer Works Inc
+
+acpi:PAC*:
+ ID_VENDOR_FROM_DATABASE=Pacific Avionics Corporation
+
+acpi:PAD*:
+ ID_VENDOR_FROM_DATABASE=Promotion and Display Technology Ltd.
+
+acpi:PAK*:
+ ID_VENDOR_FROM_DATABASE=Many CNC System Co., Ltd.
+
+acpi:PAM*:
+ ID_VENDOR_FROM_DATABASE=Peter Antesberger Messtechnik
+
+acpi:PAN*:
+ ID_VENDOR_FROM_DATABASE=The Panda Project
+
+acpi:PAR*:
+ ID_VENDOR_FROM_DATABASE=Parallan Comp Inc
+
+acpi:PBI*:
+ ID_VENDOR_FROM_DATABASE=Pitney Bowes
+
+acpi:PBL*:
+ ID_VENDOR_FROM_DATABASE=Packard Bell Electronics
+
+acpi:PBN*:
+ ID_VENDOR_FROM_DATABASE=Packard Bell NEC
+
+acpi:PBV*:
+ ID_VENDOR_FROM_DATABASE=Pitney Bowes
+
+acpi:PCA*:
+ ID_VENDOR_FROM_DATABASE=Philips BU Add On Card
+
+acpi:PCB*:
+ ID_VENDOR_FROM_DATABASE=OCTAL S.A.
+
+acpi:PCC*:
+ ID_VENDOR_FROM_DATABASE=PowerCom Technology Company Ltd
+
+acpi:PCG*:
+ ID_VENDOR_FROM_DATABASE=First Industrial Computer Inc
+
+acpi:PCI*:
+ ID_VENDOR_FROM_DATABASE=Pioneer Computer Inc
+
+acpi:PCK*:
+ ID_VENDOR_FROM_DATABASE=PCBANK21
+
+acpi:PCL*:
+ ID_VENDOR_FROM_DATABASE=pentel.co.,ltd
+
+acpi:PCM*:
+ ID_VENDOR_FROM_DATABASE=PCM Systems Corporation
+
+acpi:PCO*:
+ ID_VENDOR_FROM_DATABASE=Performance Concepts Inc.,
+
+acpi:PCP*:
+ ID_VENDOR_FROM_DATABASE=Procomp USA Inc
+
+acpi:PCS*:
+ ID_VENDOR_FROM_DATABASE=TOSHIBA PERSONAL COMPUTER SYSTEM CORPRATION
+
+acpi:PCT*:
+ ID_VENDOR_FROM_DATABASE=PC-Tel Inc
+
+acpi:PCW*:
+ ID_VENDOR_FROM_DATABASE=Pacific CommWare Inc
+
+acpi:PCX*:
+ ID_VENDOR_FROM_DATABASE=PC Xperten
+
+acpi:PDM*:
+ ID_VENDOR_FROM_DATABASE=Psion Dacom Plc.
+
+acpi:PDN*:
+ ID_VENDOR_FROM_DATABASE=AT&T Paradyne
+
+acpi:PDR*:
+ ID_VENDOR_FROM_DATABASE=Pure Data Inc
+
+acpi:PDS*:
+ ID_VENDOR_FROM_DATABASE=PD Systems International Ltd
+
+acpi:PDT*:
+ ID_VENDOR_FROM_DATABASE=PDTS - Prozessdatentechnik und Systeme
+
+acpi:PDV*:
+ ID_VENDOR_FROM_DATABASE=Prodrive B.V.
+
+acpi:PEC*:
+ ID_VENDOR_FROM_DATABASE=POTRANS Electrical Corp.
+
+acpi:PEI*:
+ ID_VENDOR_FROM_DATABASE=PEI Electronics Inc
+
+acpi:PEL*:
+ ID_VENDOR_FROM_DATABASE=Primax Electric Ltd
+
+acpi:PEN*:
+ ID_VENDOR_FROM_DATABASE=Interactive Computer Products Inc
+
+acpi:PEP*:
+ ID_VENDOR_FROM_DATABASE=Peppercon AG
+
+acpi:PER*:
+ ID_VENDOR_FROM_DATABASE=Perceptive Signal Technologies
+
+acpi:PET*:
+ ID_VENDOR_FROM_DATABASE=Practical Electronic Tools
+
+acpi:PFT*:
+ ID_VENDOR_FROM_DATABASE=Telia ProSoft AB
+
+acpi:PGI*:
+ ID_VENDOR_FROM_DATABASE=PACSGEAR, Inc.
+
+acpi:PGM*:
+ ID_VENDOR_FROM_DATABASE=Paradigm Advanced Research Centre
+
+acpi:PGP*:
+ ID_VENDOR_FROM_DATABASE=propagamma kommunikation
+
+acpi:PGS*:
+ ID_VENDOR_FROM_DATABASE=Princeton Graphic Systems
+
+acpi:PHC*:
+ ID_VENDOR_FROM_DATABASE=Pijnenburg Beheer N.V.
+
+acpi:PHE*:
+ ID_VENDOR_FROM_DATABASE=Philips Medical Systems Boeblingen GmbH
+
+acpi:PHL*:
+ ID_VENDOR_FROM_DATABASE=Philips Consumer Electronics Company
+
+acpi:PHO*:
+ ID_VENDOR_FROM_DATABASE=Photonics Systems Inc.
+
+acpi:PHS*:
+ ID_VENDOR_FROM_DATABASE=Philips Communication Systems
+
+acpi:PHY*:
+ ID_VENDOR_FROM_DATABASE=Phylon Communications
+
+acpi:PIE*:
+ ID_VENDOR_FROM_DATABASE=Pacific Image Electronics Company Ltd
+
+acpi:PIM*:
+ ID_VENDOR_FROM_DATABASE=Prism, LLC
+
+acpi:PIO*:
+ ID_VENDOR_FROM_DATABASE=Pioneer Electronic Corporation
+
+acpi:PIX*:
+ ID_VENDOR_FROM_DATABASE=Pixie Tech Inc
+
+acpi:PJA*:
+ ID_VENDOR_FROM_DATABASE=Projecta
+
+acpi:PJD*:
+ ID_VENDOR_FROM_DATABASE=Projectiondesign AS
+
+acpi:PJT*:
+ ID_VENDOR_FROM_DATABASE=Pan Jit International Inc.
+
+acpi:PKA*:
+ ID_VENDOR_FROM_DATABASE=Acco UK ltd.
+
+acpi:PLC*:
+ ID_VENDOR_FROM_DATABASE=Pro-Log Corporation
+
+acpi:PLF*:
+ ID_VENDOR_FROM_DATABASE=Panasonic Avionics Corporation
+
+acpi:PLM*:
+ ID_VENDOR_FROM_DATABASE=PROLINK Microsystems Corp.
+
+acpi:PLT*:
+ ID_VENDOR_FROM_DATABASE=PT Hartono Istana Teknologi
+
+acpi:PLV*:
+ ID_VENDOR_FROM_DATABASE=PLUS Vision Corp.
+
+acpi:PLX*:
+ ID_VENDOR_FROM_DATABASE=Parallax Graphics
+
+acpi:PLY*:
+ ID_VENDOR_FROM_DATABASE=Polycom Inc.
+
+acpi:PMC*:
+ ID_VENDOR_FROM_DATABASE=PMC Consumer Electronics Ltd
+
+acpi:PMD*:
+ ID_VENDOR_FROM_DATABASE=TDK USA Corporation
+
+acpi:PMM*:
+ ID_VENDOR_FROM_DATABASE=Point Multimedia System
+
+acpi:PMT*:
+ ID_VENDOR_FROM_DATABASE=Promate Electronic Co., Ltd.
+
+acpi:PMX*:
+ ID_VENDOR_FROM_DATABASE=Photomatrix
+
+acpi:PNG*:
+ ID_VENDOR_FROM_DATABASE=Microsoft
+
+acpi:PNL*:
+ ID_VENDOR_FROM_DATABASE=Panelview, Inc.
+
+acpi:PNP*:
+ ID_VENDOR_FROM_DATABASE=Microsoft
+
+acpi:PNR*:
+ ID_VENDOR_FROM_DATABASE=Planar Systems, Inc.
+
+acpi:PNS*:
+ ID_VENDOR_FROM_DATABASE=PanaScope
+
+acpi:PNX*:
+ ID_VENDOR_FROM_DATABASE=Phoenix Technologies, Ltd.
+
+acpi:POL*:
+ ID_VENDOR_FROM_DATABASE=PolyComp (PTY) Ltd.
+
+acpi:PON*:
+ ID_VENDOR_FROM_DATABASE=Perpetual Technologies, LLC
+
+acpi:POR*:
+ ID_VENDOR_FROM_DATABASE=Portalis LC
+
+acpi:PPC*:
+ ID_VENDOR_FROM_DATABASE=Phoenixtec Power Company Ltd
+
+acpi:PPD*:
+ ID_VENDOR_FROM_DATABASE=MEPhI
+
+acpi:PPI*:
+ ID_VENDOR_FROM_DATABASE=Practical Peripherals
+
+acpi:PPM*:
+ ID_VENDOR_FROM_DATABASE=Clinton Electronics Corp.
+
+acpi:PPP*:
+ ID_VENDOR_FROM_DATABASE=Purup Prepress AS
+
+acpi:PPR*:
+ ID_VENDOR_FROM_DATABASE=PicPro
+
+acpi:PPX*:
+ ID_VENDOR_FROM_DATABASE=Perceptive Pixel Inc.
+
+acpi:PQI*:
+ ID_VENDOR_FROM_DATABASE=Pixel Qi
+
+acpi:PRA*:
+ ID_VENDOR_FROM_DATABASE=PRO/AUTOMATION
+
+acpi:PRC*:
+ ID_VENDOR_FROM_DATABASE=PerComm
+
+acpi:PRD*:
+ ID_VENDOR_FROM_DATABASE=Praim S.R.L.
+
+acpi:PRF*:
+ ID_VENDOR_FROM_DATABASE=Digital Electronics Corporation
+
+acpi:PRG*:
+ ID_VENDOR_FROM_DATABASE=The Phoenix Research Group Inc
+
+acpi:PRI*:
+ ID_VENDOR_FROM_DATABASE=Priva Hortimation BV
+
+acpi:PRM*:
+ ID_VENDOR_FROM_DATABASE=Prometheus
+
+acpi:PRO*:
+ ID_VENDOR_FROM_DATABASE=Proteon
+
+acpi:PRS*:
+ ID_VENDOR_FROM_DATABASE=Leutron Vision
+
+acpi:PRT*:
+ ID_VENDOR_FROM_DATABASE=Parade Technologies, Ltd.
+
+acpi:PRX*:
+ ID_VENDOR_FROM_DATABASE=Proxima Corporation
+
+acpi:PSA*:
+ ID_VENDOR_FROM_DATABASE=Advanced Signal Processing Technologies
+
+acpi:PSC*:
+ ID_VENDOR_FROM_DATABASE=Philips Semiconductors
+
+acpi:PSD*:
+ ID_VENDOR_FROM_DATABASE=Peus-Systems GmbH
+
+acpi:PSE*:
+ ID_VENDOR_FROM_DATABASE=Practical Solutions Pte., Ltd.
+
+acpi:PSI*:
+ ID_VENDOR_FROM_DATABASE=PSI-Perceptive Solutions Inc
+
+acpi:PSL*:
+ ID_VENDOR_FROM_DATABASE=Perle Systems Limited
+
+acpi:PSM*:
+ ID_VENDOR_FROM_DATABASE=Prosum
+
+acpi:PST*:
+ ID_VENDOR_FROM_DATABASE=Global Data SA
+
+acpi:PTA*:
+ ID_VENDOR_FROM_DATABASE=PAR Tech Inc.
+
+acpi:PTC*:
+ ID_VENDOR_FROM_DATABASE=PS Technology Corporation
+
+acpi:PTG*:
+ ID_VENDOR_FROM_DATABASE=Cipher Systems Inc
+
+acpi:PTH*:
+ ID_VENDOR_FROM_DATABASE=Pathlight Technology Inc
+
+acpi:PTI*:
+ ID_VENDOR_FROM_DATABASE=Promise Technology Inc
+
+acpi:PTL*:
+ ID_VENDOR_FROM_DATABASE=Pantel Inc
+
+acpi:PTS*:
+ ID_VENDOR_FROM_DATABASE=Plain Tree Systems Inc
+
+acpi:PVG*:
+ ID_VENDOR_FROM_DATABASE=Proview Global Co., Ltd
+
+acpi:PVI*:
+ ID_VENDOR_FROM_DATABASE=Prime view international Co., Ltd
+
+acpi:PVM*:
+ ID_VENDOR_FROM_DATABASE=Penta Studiotechnik GmbH
+
+acpi:PVN*:
+ ID_VENDOR_FROM_DATABASE=Pixel Vision
+
+acpi:PVP*:
+ ID_VENDOR_FROM_DATABASE=Klos Technologies, Inc.
+
+acpi:PXC*:
+ ID_VENDOR_FROM_DATABASE=Phoenix Contact
+
+acpi:PXE*:
+ ID_VENDOR_FROM_DATABASE=PIXELA CORPORATION
+
+acpi:PXL*:
+ ID_VENDOR_FROM_DATABASE=The Moving Pixel Company
+
+acpi:PXM*:
+ ID_VENDOR_FROM_DATABASE=Proxim Inc
+
+acpi:QCC*:
+ ID_VENDOR_FROM_DATABASE=QuakeCom Company Ltd
+
+acpi:QCH*:
+ ID_VENDOR_FROM_DATABASE=Metronics Inc
+
+acpi:QCI*:
+ ID_VENDOR_FROM_DATABASE=Quanta Computer Inc
+
+acpi:QCK*:
+ ID_VENDOR_FROM_DATABASE=Quick Corporation
+
+acpi:QCL*:
+ ID_VENDOR_FROM_DATABASE=Quadrant Components Inc
+
+acpi:QCP*:
+ ID_VENDOR_FROM_DATABASE=Qualcomm Inc
+
+acpi:QDI*:
+ ID_VENDOR_FROM_DATABASE=Quantum Data Incorporated
+
+acpi:QDM*:
+ ID_VENDOR_FROM_DATABASE=Quadram
+
+acpi:QDS*:
+ ID_VENDOR_FROM_DATABASE=Quanta Display Inc.
+
+acpi:QFF*:
+ ID_VENDOR_FROM_DATABASE=Padix Co., Inc.
+
+acpi:QFI*:
+ ID_VENDOR_FROM_DATABASE=Quickflex, Inc
+
+acpi:QLC*:
+ ID_VENDOR_FROM_DATABASE=Q-Logic
+
+acpi:QQQ*:
+ ID_VENDOR_FROM_DATABASE=Chuomusen Co., Ltd.
+
+acpi:QSI*:
+ ID_VENDOR_FROM_DATABASE=Quantum Solutions, Inc.
+
+acpi:QTD*:
+ ID_VENDOR_FROM_DATABASE=Quantum 3D Inc
+
+acpi:QTH*:
+ ID_VENDOR_FROM_DATABASE=Questech Ltd
+
+acpi:QTI*:
+ ID_VENDOR_FROM_DATABASE=Quicknet Technologies Inc
+
+acpi:QTM*:
+ ID_VENDOR_FROM_DATABASE=Quantum
+
+acpi:QTR*:
+ ID_VENDOR_FROM_DATABASE=Qtronix Corporation
+
+acpi:QUA*:
+ ID_VENDOR_FROM_DATABASE=Quatographic AG
+
+acpi:QUE*:
+ ID_VENDOR_FROM_DATABASE=Questra Consulting
+
+acpi:QVU*:
+ ID_VENDOR_FROM_DATABASE=Quartics
+
+acpi:RAC*:
+ ID_VENDOR_FROM_DATABASE=Racore Computer Products Inc
+
+acpi:RAD*:
+ ID_VENDOR_FROM_DATABASE=Radisys Corporation
+
+acpi:RAI*:
+ ID_VENDOR_FROM_DATABASE=Rockwell Automation/Intecolor
+
+acpi:RAN*:
+ ID_VENDOR_FROM_DATABASE=Rancho Tech Inc
+
+acpi:RAR*:
+ ID_VENDOR_FROM_DATABASE=Raritan, Inc.
+
+acpi:RAS*:
+ ID_VENDOR_FROM_DATABASE=RAScom Inc
+
+acpi:RAT*:
+ ID_VENDOR_FROM_DATABASE=Rent-A-Tech
+
+acpi:RAY*:
+ ID_VENDOR_FROM_DATABASE=Raylar Design, Inc.
+
+acpi:RCE*:
+ ID_VENDOR_FROM_DATABASE=Parc d'Activite des Bellevues
+
+acpi:RCH*:
+ ID_VENDOR_FROM_DATABASE=Reach Technology Inc
+
+acpi:RCI*:
+ ID_VENDOR_FROM_DATABASE=RC International
+
+acpi:RCN*:
+ ID_VENDOR_FROM_DATABASE=Radio Consult SRL
+
+acpi:RCO*:
+ ID_VENDOR_FROM_DATABASE=Rockwell Collins
+
+acpi:RDI*:
+ ID_VENDOR_FROM_DATABASE=Rainbow Displays, Inc.
+
+acpi:RDM*:
+ ID_VENDOR_FROM_DATABASE=Tremon Enterprises Company Ltd
+
+acpi:RDN*:
+ ID_VENDOR_FROM_DATABASE=RADIODATA GmbH
+
+acpi:RDS*:
+ ID_VENDOR_FROM_DATABASE=Radius Inc
+
+acpi:REA*:
+ ID_VENDOR_FROM_DATABASE=Real D
+
+acpi:REC*:
+ ID_VENDOR_FROM_DATABASE=ReCom
+
+acpi:RED*:
+ ID_VENDOR_FROM_DATABASE=Research Electronics Development Inc
+
+acpi:REF*:
+ ID_VENDOR_FROM_DATABASE=Reflectivity, Inc.
+
+acpi:REH*:
+ ID_VENDOR_FROM_DATABASE=Rehan Electronics Ltd.
+
+acpi:REL*:
+ ID_VENDOR_FROM_DATABASE=Reliance Electric Ind Corporation
+
+acpi:REM*:
+ ID_VENDOR_FROM_DATABASE=SCI Systems Inc.
+
+acpi:REN*:
+ ID_VENDOR_FROM_DATABASE=Renesas Technology Corp.
+
+acpi:RES*:
+ ID_VENDOR_FROM_DATABASE=ResMed Pty Ltd
+
+acpi:RET*:
+ ID_VENDOR_FROM_DATABASE=Resonance Technology, Inc.
+
+acpi:REX*:
+ ID_VENDOR_FROM_DATABASE=RATOC Systems, Inc.
+
+acpi:RGL*:
+ ID_VENDOR_FROM_DATABASE=Robertson Geologging Ltd
+
+acpi:RHD*:
+ ID_VENDOR_FROM_DATABASE=RightHand Technologies
+
+acpi:RHM*:
+ ID_VENDOR_FROM_DATABASE=Rohm Company Ltd
+
+acpi:RHT*:
+ ID_VENDOR_FROM_DATABASE=Red Hat, Inc.
+
+acpi:RIC*:
+ ID_VENDOR_FROM_DATABASE=RICOH COMPANY, LTD.
+
+acpi:RII*:
+ ID_VENDOR_FROM_DATABASE=Racal Interlan Inc
+
+acpi:RIO*:
+ ID_VENDOR_FROM_DATABASE=Rios Systems Company Ltd
+
+acpi:RIT*:
+ ID_VENDOR_FROM_DATABASE=Ritech Inc
+
+acpi:RIV*:
+ ID_VENDOR_FROM_DATABASE=Rivulet Communications
+
+acpi:RJA*:
+ ID_VENDOR_FROM_DATABASE=Roland Corporation
+
+acpi:RJS*:
+ ID_VENDOR_FROM_DATABASE=Advanced Engineering
+
+acpi:RKC*:
+ ID_VENDOR_FROM_DATABASE=Reakin Technolohy Corporation
+
+acpi:RLD*:
+ ID_VENDOR_FROM_DATABASE=MEPCO
+
+acpi:RLN*:
+ ID_VENDOR_FROM_DATABASE=RadioLAN Inc
+
+acpi:RMC*:
+ ID_VENDOR_FROM_DATABASE=Raritan Computer, Inc
+
+acpi:RMP*:
+ ID_VENDOR_FROM_DATABASE=Research Machines
+
+acpi:RMT*:
+ ID_VENDOR_FROM_DATABASE=Roper Mobile
+
+acpi:RNB*:
+ ID_VENDOR_FROM_DATABASE=Rainbow Technologies
+
+acpi:ROB*:
+ ID_VENDOR_FROM_DATABASE=Robust Electronics GmbH
+
+acpi:ROH*:
+ ID_VENDOR_FROM_DATABASE=Rohm Co., Ltd.
+
+acpi:ROK*:
+ ID_VENDOR_FROM_DATABASE=Rockwell International
+
+acpi:ROP*:
+ ID_VENDOR_FROM_DATABASE=Roper International Ltd
+
+acpi:ROS*:
+ ID_VENDOR_FROM_DATABASE=Rohde & Schwarz
+
+acpi:RPI*:
+ ID_VENDOR_FROM_DATABASE=RoomPro Technologies
+
+acpi:RPT*:
+ ID_VENDOR_FROM_DATABASE=R.P.T.Intergroups
+
+acpi:RRI*:
+ ID_VENDOR_FROM_DATABASE=Radicom Research Inc
+
+acpi:RSC*:
+ ID_VENDOR_FROM_DATABASE=PhotoTelesis
+
+acpi:RSH*:
+ ID_VENDOR_FROM_DATABASE=ADC-Centre
+
+acpi:RSI*:
+ ID_VENDOR_FROM_DATABASE=Rampage Systems Inc
+
+acpi:RSN*:
+ ID_VENDOR_FROM_DATABASE=Radiospire Networks, Inc.
+
+acpi:RSQ*:
+ ID_VENDOR_FROM_DATABASE=R Squared
+
+acpi:RSS*:
+ ID_VENDOR_FROM_DATABASE=Rockwell Semiconductor Systems
+
+acpi:RSV*:
+ ID_VENDOR_FROM_DATABASE=Ross Video Ltd
+
+acpi:RSX*:
+ ID_VENDOR_FROM_DATABASE=Rapid Tech Corporation
+
+acpi:RTC*:
+ ID_VENDOR_FROM_DATABASE=Relia Technologies
+
+acpi:RTI*:
+ ID_VENDOR_FROM_DATABASE=Rancho Tech Inc
+
+acpi:RTL*:
+ ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Company Ltd
+
+acpi:RTS*:
+ ID_VENDOR_FROM_DATABASE=Raintree Systems
+
+acpi:RUN*:
+ ID_VENDOR_FROM_DATABASE=RUNCO International
+
+acpi:RUP*:
+ ID_VENDOR_FROM_DATABASE=Ups Manufactoring s.r.l.
+
+acpi:RVC*:
+ ID_VENDOR_FROM_DATABASE=RSI Systems Inc
+
+acpi:RVI*:
+ ID_VENDOR_FROM_DATABASE=Realvision Inc
+
+acpi:RVL*:
+ ID_VENDOR_FROM_DATABASE=Reveal Computer Prod
+
+acpi:RWC*:
+ ID_VENDOR_FROM_DATABASE=Red Wing Corporation
+
+acpi:RXT*:
+ ID_VENDOR_FROM_DATABASE=Tectona SoftSolutions (P) Ltd.,
+
+acpi:SAA*:
+ ID_VENDOR_FROM_DATABASE=Sanritz Automation Co.,Ltd.
+
+acpi:SAE*:
+ ID_VENDOR_FROM_DATABASE=Saab Aerotech
+
+acpi:SAG*:
+ ID_VENDOR_FROM_DATABASE=Sedlbauer
+
+acpi:SAI*:
+ ID_VENDOR_FROM_DATABASE=Sage Inc
+
+acpi:SAK*:
+ ID_VENDOR_FROM_DATABASE=Saitek Ltd
+
+acpi:SAM*:
+ ID_VENDOR_FROM_DATABASE=Samsung Electric Company
+
+acpi:SAN*:
+ ID_VENDOR_FROM_DATABASE=Sanyo Electric Co.,Ltd.
+
+acpi:SAS*:
+ ID_VENDOR_FROM_DATABASE=Stores Automated Systems Inc
+
+acpi:SAT*:
+ ID_VENDOR_FROM_DATABASE=Shuttle Tech
+
+acpi:SBC*:
+ ID_VENDOR_FROM_DATABASE=Shanghai Bell Telephone Equip Mfg Co
+
+acpi:SBD*:
+ ID_VENDOR_FROM_DATABASE=Softbed - Consulting & Development Ltd
+
+acpi:SBI*:
+ ID_VENDOR_FROM_DATABASE=SMART Technologies Inc.
+
+acpi:SBS*:
+ ID_VENDOR_FROM_DATABASE=SBS-or Industrial Computers GmbH
+
+acpi:SBT*:
+ ID_VENDOR_FROM_DATABASE=Senseboard Technologies AB
+
+acpi:SCC*:
+ ID_VENDOR_FROM_DATABASE=SORD Computer Corporation
+
+acpi:SCD*:
+ ID_VENDOR_FROM_DATABASE=Sanyo Electric Company Ltd
+
+acpi:SCE*:
+ ID_VENDOR_FROM_DATABASE=Sun Corporation
+
+acpi:SCH*:
+ ID_VENDOR_FROM_DATABASE=Schlumberger Cards
+
+acpi:SCI*:
+ ID_VENDOR_FROM_DATABASE=System Craft
+
+acpi:SCL*:
+ ID_VENDOR_FROM_DATABASE=Sigmacom Co., Ltd.
+
+acpi:SCM*:
+ ID_VENDOR_FROM_DATABASE=SCM Microsystems Inc
+
+acpi:SCN*:
+ ID_VENDOR_FROM_DATABASE=Scanport, Inc.
+
+acpi:SCO*:
+ ID_VENDOR_FROM_DATABASE=SORCUS Computer GmbH
+
+acpi:SCP*:
+ ID_VENDOR_FROM_DATABASE=Scriptel Corporation
+
+acpi:SCR*:
+ ID_VENDOR_FROM_DATABASE=Systran Corporation
+
+acpi:SCS*:
+ ID_VENDOR_FROM_DATABASE=Nanomach Anstalt
+
+acpi:SCT*:
+ ID_VENDOR_FROM_DATABASE=Smart Card Technology
+
+acpi:SDA*:
+ ID_VENDOR_FROM_DATABASE=SAT (Societe Anonyme)
+
+acpi:SDD*:
+ ID_VENDOR_FROM_DATABASE=Intrada-SDD Ltd
+
+acpi:SDE*:
+ ID_VENDOR_FROM_DATABASE=Sherwood Digital Electronics Corporation
+
+acpi:SDF*:
+ ID_VENDOR_FROM_DATABASE=SODIFF E&T CO., Ltd.
+
+acpi:SDH*:
+ ID_VENDOR_FROM_DATABASE=Communications Specialies, Inc.
+
+acpi:SDI*:
+ ID_VENDOR_FROM_DATABASE=Samtron Displays Inc
+
+acpi:SDK*:
+ ID_VENDOR_FROM_DATABASE=SAIT-Devlonics
+
+acpi:SDR*:
+ ID_VENDOR_FROM_DATABASE=SDR Systems
+
+acpi:SDS*:
+ ID_VENDOR_FROM_DATABASE=SunRiver Data System
+
+acpi:SDT*:
+ ID_VENDOR_FROM_DATABASE=Siemens AG
+
+acpi:SDX*:
+ ID_VENDOR_FROM_DATABASE=SDX Business Systems Ltd
+
+acpi:SEA*:
+ ID_VENDOR_FROM_DATABASE=Seanix Technology Inc.
+
+acpi:SEB*:
+ ID_VENDOR_FROM_DATABASE=system elektronik GmbH
+
+acpi:SEC*:
+ ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation
+
+acpi:SEE*:
+ ID_VENDOR_FROM_DATABASE=SeeColor Corporation
+
+acpi:SEI*:
+ ID_VENDOR_FROM_DATABASE=Seitz & Associates Inc
+
+acpi:SEL*:
+ ID_VENDOR_FROM_DATABASE=Way2Call Communications
+
+acpi:SEM*:
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics Company Ltd
+
+acpi:SEN*:
+ ID_VENDOR_FROM_DATABASE=Sencore
+
+acpi:SEO*:
+ ID_VENDOR_FROM_DATABASE=SEOS Ltd
+
+acpi:SEP*:
+ ID_VENDOR_FROM_DATABASE=SEP Eletronica Ltda.
+
+acpi:SER*:
+ ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications Inc.
+
+acpi:SES*:
+ ID_VENDOR_FROM_DATABASE=Session Control LLC
+
+acpi:SET*:
+ ID_VENDOR_FROM_DATABASE=SendTek Corporation
+
+acpi:SFM*:
+ ID_VENDOR_FROM_DATABASE=TORNADO Company
+
+acpi:SFT*:
+ ID_VENDOR_FROM_DATABASE=Mikroforum Ring 3
+
+acpi:SGC*:
+ ID_VENDOR_FROM_DATABASE=Spectragraphics Corporation
+
+acpi:SGD*:
+ ID_VENDOR_FROM_DATABASE=Sigma Designs, Inc.
+
+acpi:SGE*:
+ ID_VENDOR_FROM_DATABASE=Kansai Electric Company Ltd
+
+acpi:SGI*:
+ ID_VENDOR_FROM_DATABASE=Scan Group Ltd
+
+acpi:SGL*:
+ ID_VENDOR_FROM_DATABASE=Super Gate Technology Company Ltd
+
+acpi:SGM*:
+ ID_VENDOR_FROM_DATABASE=SAGEM
+
+acpi:SGO*:
+ ID_VENDOR_FROM_DATABASE=Logos Design A/S
+
+acpi:SGT*:
+ ID_VENDOR_FROM_DATABASE=Stargate Technology
+
+acpi:SGW*:
+ ID_VENDOR_FROM_DATABASE=Shanghai Guowei Science and Technology Co., Ltd.
+
+acpi:SGX*:
+ ID_VENDOR_FROM_DATABASE=Silicon Graphics Inc
+
+acpi:SGZ*:
+ ID_VENDOR_FROM_DATABASE=Systec Computer GmbH
+
+acpi:SHC*:
+ ID_VENDOR_FROM_DATABASE=ShibaSoku Co., Ltd.
+
+acpi:SHG*:
+ ID_VENDOR_FROM_DATABASE=Soft & Hardware development Goldammer GmbH
+
+acpi:SHI*:
+ ID_VENDOR_FROM_DATABASE=Jiangsu Shinco Electronic Group Co., Ltd
+
+acpi:SHP*:
+ ID_VENDOR_FROM_DATABASE=Sharp Corporation
+
+acpi:SHR*:
+ ID_VENDOR_FROM_DATABASE=Digital Discovery
+
+acpi:SHT*:
+ ID_VENDOR_FROM_DATABASE=Shin Ho Tech
+
+acpi:SIA*:
+ ID_VENDOR_FROM_DATABASE=SIEMENS AG
+
+acpi:SIB*:
+ ID_VENDOR_FROM_DATABASE=Sanyo Electric Company Ltd
+
+acpi:SIC*:
+ ID_VENDOR_FROM_DATABASE=Sysmate Corporation
+
+acpi:SID*:
+ ID_VENDOR_FROM_DATABASE=Seiko Instruments Information Devices Inc
+
+acpi:SIE*:
+ ID_VENDOR_FROM_DATABASE=Siemens
+
+acpi:SIG*:
+ ID_VENDOR_FROM_DATABASE=Sigma Designs Inc
+
+acpi:SII*:
+ ID_VENDOR_FROM_DATABASE=Silicon Image, Inc.
+
+acpi:SIL*:
+ ID_VENDOR_FROM_DATABASE=Silicon Laboratories, Inc
+
+acpi:SIM*:
+ ID_VENDOR_FROM_DATABASE=S3 Inc
+
+acpi:SIN*:
+ ID_VENDOR_FROM_DATABASE=Singular Technology Co., Ltd.
+
+acpi:SIR*:
+ ID_VENDOR_FROM_DATABASE=Sirius Technologies Pty Ltd
+
+acpi:SIS*:
+ ID_VENDOR_FROM_DATABASE=Silicon Integrated Systems Corporation
+
+acpi:SIT*:
+ ID_VENDOR_FROM_DATABASE=Sitintel
+
+acpi:SIU*:
+ ID_VENDOR_FROM_DATABASE=Seiko Instruments USA Inc
+
+acpi:SIX*:
+ ID_VENDOR_FROM_DATABASE=Zuniq Data Corporation
+
+acpi:SJE*:
+ ID_VENDOR_FROM_DATABASE=Sejin Electron Inc
+
+acpi:SKD*:
+ ID_VENDOR_FROM_DATABASE=Schneider & Koch
+
+acpi:SKT*:
+ ID_VENDOR_FROM_DATABASE=Samsung Electro-Mechanics Company Ltd
+
+acpi:SKY*:
+ ID_VENDOR_FROM_DATABASE=SKYDATA S.P.A.
+
+acpi:SLA*:
+ ID_VENDOR_FROM_DATABASE=Systeme Lauer GmbH&Co KG
+
+acpi:SLB*:
+ ID_VENDOR_FROM_DATABASE=Shlumberger Ltd
+
+acpi:SLC*:
+ ID_VENDOR_FROM_DATABASE=Syslogic Datentechnik AG
+
+acpi:SLF*:
+ ID_VENDOR_FROM_DATABASE=StarLeaf
+
+acpi:SLH*:
+ ID_VENDOR_FROM_DATABASE=Silicon Library Inc.
+
+acpi:SLI*:
+ ID_VENDOR_FROM_DATABASE=Symbios Logic Inc
+
+acpi:SLK*:
+ ID_VENDOR_FROM_DATABASE=Silitek Corporation
+
+acpi:SLM*:
+ ID_VENDOR_FROM_DATABASE=Solomon Technology Corporation
+
+acpi:SLR*:
+ ID_VENDOR_FROM_DATABASE=Schlumberger Technology Corporate
+
+acpi:SLS*:
+ ID_VENDOR_FROM_DATABASE=Schnick-Schnack-Systems GmbH
+
+acpi:SLT*:
+ ID_VENDOR_FROM_DATABASE=Salt Internatioinal Corp.
+
+acpi:SLX*:
+ ID_VENDOR_FROM_DATABASE=Specialix
+
+acpi:SMA*:
+ ID_VENDOR_FROM_DATABASE=SMART Modular Technologies
+
+acpi:SMB*:
+ ID_VENDOR_FROM_DATABASE=Schlumberger
+
+acpi:SMC*:
+ ID_VENDOR_FROM_DATABASE=Standard Microsystems Corporation
+
+acpi:SME*:
+ ID_VENDOR_FROM_DATABASE=Sysmate Company
+
+acpi:SMI*:
+ ID_VENDOR_FROM_DATABASE=SpaceLabs Medical Inc
+
+acpi:SMK*:
+ ID_VENDOR_FROM_DATABASE=SMK CORPORATION
+
+acpi:SML*:
+ ID_VENDOR_FROM_DATABASE=Sumitomo Metal Industries, Ltd.
+
+acpi:SMM*:
+ ID_VENDOR_FROM_DATABASE=Shark Multimedia Inc
+
+acpi:SMO*:
+ ID_VENDOR_FROM_DATABASE=STMicroelectronics
+
+acpi:SMP*:
+ ID_VENDOR_FROM_DATABASE=Simple Computing
+
+acpi:SMR*:
+ ID_VENDOR_FROM_DATABASE=B.& V. s.r.l.
+
+acpi:SMS*:
+ ID_VENDOR_FROM_DATABASE=Silicom Multimedia Systems Inc
+
+acpi:SMT*:
+ ID_VENDOR_FROM_DATABASE=Silcom Manufacturing Tech Inc
+
+acpi:SNC*:
+ ID_VENDOR_FROM_DATABASE=Sentronic International Corp.
+
+acpi:SNI*:
+ ID_VENDOR_FROM_DATABASE=Siemens Microdesign GmbH
+
+acpi:SNK*:
+ ID_VENDOR_FROM_DATABASE=S&K Electronics
+
+acpi:SNO*:
+ ID_VENDOR_FROM_DATABASE=SINOSUN TECHNOLOGY CO., LTD
+
+acpi:SNP*:
+ ID_VENDOR_FROM_DATABASE=Siemens Nixdorf Info Systems
+
+acpi:SNS*:
+ ID_VENDOR_FROM_DATABASE=Cirtech (UK) Ltd
+
+acpi:SNT*:
+ ID_VENDOR_FROM_DATABASE=SuperNet Inc
+
+acpi:SNW*:
+ ID_VENDOR_FROM_DATABASE=Snell & Wilcox
+
+acpi:SNX*:
+ ID_VENDOR_FROM_DATABASE=Sonix Comm. Ltd
+
+acpi:SNY*:
+ ID_VENDOR_FROM_DATABASE=Sony
+
+acpi:SOI*:
+ ID_VENDOR_FROM_DATABASE=Silicon Optix Corporation
+
+acpi:SOL*:
+ ID_VENDOR_FROM_DATABASE=Solitron Technologies Inc
+
+acpi:SON*:
+ ID_VENDOR_FROM_DATABASE=Sony
+
+acpi:SOR*:
+ ID_VENDOR_FROM_DATABASE=Sorcus Computer GmbH
+
+acpi:SOT*:
+ ID_VENDOR_FROM_DATABASE=Sotec Company Ltd
+
+acpi:SOY*:
+ ID_VENDOR_FROM_DATABASE=SOYO Group, Inc
+
+acpi:SPC*:
+ ID_VENDOR_FROM_DATABASE=SpinCore Technologies, Inc
+
+acpi:SPE*:
+ ID_VENDOR_FROM_DATABASE=SPEA Software AG
+
+acpi:SPH*:
+ ID_VENDOR_FROM_DATABASE=G&W Instruments GmbH
+
+acpi:SPI*:
+ ID_VENDOR_FROM_DATABASE=SPACE-I Co., Ltd.
+
+acpi:SPK*:
+ ID_VENDOR_FROM_DATABASE=SpeakerCraft
+
+acpi:SPL*:
+ ID_VENDOR_FROM_DATABASE=Smart Silicon Systems Pty Ltd
+
+acpi:SPN*:
+ ID_VENDOR_FROM_DATABASE=Sapience Corporation
+
+acpi:SPR*:
+ ID_VENDOR_FROM_DATABASE=pmns GmbH
+
+acpi:SPS*:
+ ID_VENDOR_FROM_DATABASE=Synopsys Inc
+
+acpi:SPT*:
+ ID_VENDOR_FROM_DATABASE=Sceptre Tech Inc
+
+acpi:SPU*:
+ ID_VENDOR_FROM_DATABASE=SIM2 Multimedia S.P.A.
+
+acpi:SPX*:
+ ID_VENDOR_FROM_DATABASE=Simplex Time Recorder Co.
+
+acpi:SQT*:
+ ID_VENDOR_FROM_DATABASE=Sequent Computer Systems Inc
+
+acpi:SRC*:
+ ID_VENDOR_FROM_DATABASE=Integrated Tech Express Inc
+
+acpi:SRD*:
+ ID_VENDOR_FROM_DATABASE=Setred
+
+acpi:SRF*:
+ ID_VENDOR_FROM_DATABASE=Surf Communication Solutions Ltd
+
+acpi:SRG*:
+ ID_VENDOR_FROM_DATABASE=Intuitive Surgical, Inc.
+
+acpi:SRT*:
+ ID_VENDOR_FROM_DATABASE=SeeReal Technologies GmbH
+
+acpi:SSC*:
+ ID_VENDOR_FROM_DATABASE=Sierra Semiconductor Inc
+
+acpi:SSD*:
+ ID_VENDOR_FROM_DATABASE=FlightSafety International
+
+acpi:SSE*:
+ ID_VENDOR_FROM_DATABASE=Samsung Electronic Co.
+
+acpi:SSI*:
+ ID_VENDOR_FROM_DATABASE=S-S Technology Inc
+
+acpi:SSJ*:
+ ID_VENDOR_FROM_DATABASE=Sankyo Seiki Mfg.co., Ltd
+
+acpi:SSP*:
+ ID_VENDOR_FROM_DATABASE=Spectrum Signal Proecessing Inc
+
+acpi:SSS*:
+ ID_VENDOR_FROM_DATABASE=S3 Inc
+
+acpi:SST*:
+ ID_VENDOR_FROM_DATABASE=SystemSoft Corporation
+
+acpi:STA*:
+ ID_VENDOR_FROM_DATABASE=ST Electronics Systems Assembly Pte Ltd
+
+acpi:STB*:
+ ID_VENDOR_FROM_DATABASE=STB Systems Inc
+
+acpi:STC*:
+ ID_VENDOR_FROM_DATABASE=STAC Electronics
+
+acpi:STD*:
+ ID_VENDOR_FROM_DATABASE=STD Computer Inc
+
+acpi:STE*:
+ ID_VENDOR_FROM_DATABASE=SII Ido-Tsushin Inc
+
+acpi:STF*:
+ ID_VENDOR_FROM_DATABASE=Starflight Electronics
+
+acpi:STG*:
+ ID_VENDOR_FROM_DATABASE=StereoGraphics Corp.
+
+acpi:STH*:
+ ID_VENDOR_FROM_DATABASE=Semtech Corporation
+
+acpi:STI*:
+ ID_VENDOR_FROM_DATABASE=Smart Tech Inc
+
+acpi:STK*:
+ ID_VENDOR_FROM_DATABASE=SANTAK CORP.
+
+acpi:STL*:
+ ID_VENDOR_FROM_DATABASE=SigmaTel Inc
+
+acpi:STM*:
+ ID_VENDOR_FROM_DATABASE=SGS Thomson Microelectronics
+
+acpi:STN*:
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics America
+
+acpi:STO*:
+ ID_VENDOR_FROM_DATABASE=Stollmann E+V GmbH
+
+acpi:STP*:
+ ID_VENDOR_FROM_DATABASE=StreamPlay Ltd
+
+acpi:STR*:
+ ID_VENDOR_FROM_DATABASE=Starlight Networks Inc
+
+acpi:STS*:
+ ID_VENDOR_FROM_DATABASE=SITECSYSTEM CO., LTD.
+
+acpi:STT*:
+ ID_VENDOR_FROM_DATABASE=Star Paging Telecom Tech (Shenzhen) Co. Ltd.
+
+acpi:STU*:
+ ID_VENDOR_FROM_DATABASE=Sentelic Corporation
+
+acpi:STW*:
+ ID_VENDOR_FROM_DATABASE=Starwin Inc.
+
+acpi:STX*:
+ ID_VENDOR_FROM_DATABASE=ST-Ericsson
+
+acpi:STY*:
+ ID_VENDOR_FROM_DATABASE=SDS Technologies
+
+acpi:SUB*:
+ ID_VENDOR_FROM_DATABASE=Subspace Comm. Inc
+
+acpi:SUM*:
+ ID_VENDOR_FROM_DATABASE=Summagraphics Corporation
+
+acpi:SUN*:
+ ID_VENDOR_FROM_DATABASE=Sun Electronics Corporation
+
+acpi:SUP*:
+ ID_VENDOR_FROM_DATABASE=Supra Corporation
+
+acpi:SUR*:
+ ID_VENDOR_FROM_DATABASE=Surenam Computer Corporation
+
+acpi:SVA*:
+ ID_VENDOR_FROM_DATABASE=SGEG
+
+acpi:SVC*:
+ ID_VENDOR_FROM_DATABASE=Intellix Corp.
+
+acpi:SVD*:
+ ID_VENDOR_FROM_DATABASE=SVD Computer
+
+acpi:SVI*:
+ ID_VENDOR_FROM_DATABASE=Sun Microsystems
+
+acpi:SVS*:
+ ID_VENDOR_FROM_DATABASE=SVSI
+
+acpi:SVT*:
+ ID_VENDOR_FROM_DATABASE=SEVIT Co., Ltd.
+
+acpi:SWC*:
+ ID_VENDOR_FROM_DATABASE=Software Café
+
+acpi:SWI*:
+ ID_VENDOR_FROM_DATABASE=Sierra Wireless Inc.
+
+acpi:SWL*:
+ ID_VENDOR_FROM_DATABASE=Sharedware Ltd
+
+acpi:SWS*:
+ ID_VENDOR_FROM_DATABASE=Static
+
+acpi:SWT*:
+ ID_VENDOR_FROM_DATABASE=Software Technologies Group,Inc.
+
+acpi:SXB*:
+ ID_VENDOR_FROM_DATABASE=Syntax-Brillian
+
+acpi:SXD*:
+ ID_VENDOR_FROM_DATABASE=Silex technology, Inc.
+
+acpi:SXL*:
+ ID_VENDOR_FROM_DATABASE=SolutionInside
+
+acpi:SXT*:
+ ID_VENDOR_FROM_DATABASE=SHARP TAKAYA ELECTRONIC INDUSTRY CO.,LTD.
+
+acpi:SYC*:
+ ID_VENDOR_FROM_DATABASE=Sysmic
+
+acpi:SYE*:
+ ID_VENDOR_FROM_DATABASE=SY Electronics Ltd
+
+acpi:SYK*:
+ ID_VENDOR_FROM_DATABASE=Stryker Communications
+
+acpi:SYL*:
+ ID_VENDOR_FROM_DATABASE=Sylvania Computer Products
+
+acpi:SYM*:
+ ID_VENDOR_FROM_DATABASE=Symicron Computer Communications Ltd.
+
+acpi:SYN*:
+ ID_VENDOR_FROM_DATABASE=Synaptics Inc
+
+acpi:SYP*:
+ ID_VENDOR_FROM_DATABASE=SYPRO Co Ltd
+
+acpi:SYS*:
+ ID_VENDOR_FROM_DATABASE=Sysgration Ltd
+
+acpi:SYT*:
+ ID_VENDOR_FROM_DATABASE=Seyeon Tech Company Ltd
+
+acpi:SYV*:
+ ID_VENDOR_FROM_DATABASE=SYVAX Inc
+
+acpi:SYX*:
+ ID_VENDOR_FROM_DATABASE=Prime Systems, Inc.
+
+acpi:TAA*:
+ ID_VENDOR_FROM_DATABASE=Tandberg
+
+acpi:TAB*:
+ ID_VENDOR_FROM_DATABASE=Todos Data System AB
+
+acpi:TAG*:
+ ID_VENDOR_FROM_DATABASE=Teles AG
+
+acpi:TAI*:
+ ID_VENDOR_FROM_DATABASE=Toshiba America Info Systems Inc
+
+acpi:TAM*:
+ ID_VENDOR_FROM_DATABASE=Tamura Seisakusyo Ltd
+
+acpi:TAS*:
+ ID_VENDOR_FROM_DATABASE=Taskit Rechnertechnik GmbH
+
+acpi:TAT*:
+ ID_VENDOR_FROM_DATABASE=Teleliaison Inc
+
+acpi:TAX*:
+ ID_VENDOR_FROM_DATABASE=Taxan (Europe) Ltd
+
+acpi:TBB*:
+ ID_VENDOR_FROM_DATABASE=Triple S Engineering Inc
+
+acpi:TBC*:
+ ID_VENDOR_FROM_DATABASE=Turbo Communication, Inc
+
+acpi:TBS*:
+ ID_VENDOR_FROM_DATABASE=Turtle Beach System
+
+acpi:TCC*:
+ ID_VENDOR_FROM_DATABASE=Tandon Corporation
+
+acpi:TCD*:
+ ID_VENDOR_FROM_DATABASE=Taicom Data Systems Co., Ltd.
+
+acpi:TCE*:
+ ID_VENDOR_FROM_DATABASE=Century Corporation
+
+acpi:TCH*:
+ ID_VENDOR_FROM_DATABASE=Interaction Systems, Inc
+
+acpi:TCI*:
+ ID_VENDOR_FROM_DATABASE=Tulip Computers Int'l B.V.
+
+acpi:TCJ*:
+ ID_VENDOR_FROM_DATABASE=TEAC America Inc
+
+acpi:TCL*:
+ ID_VENDOR_FROM_DATABASE=Technical Concepts Ltd
+
+acpi:TCM*:
+ ID_VENDOR_FROM_DATABASE=3Com Corporation
+
+acpi:TCN*:
+ ID_VENDOR_FROM_DATABASE=Tecnetics (PTY) Ltd
+
+acpi:TCO*:
+ ID_VENDOR_FROM_DATABASE=Thomas-Conrad Corporation
+
+acpi:TCR*:
+ ID_VENDOR_FROM_DATABASE=Thomson Consumer Electronics
+
+acpi:TCS*:
+ ID_VENDOR_FROM_DATABASE=Tatung Company of America Inc
+
+acpi:TCT*:
+ ID_VENDOR_FROM_DATABASE=Telecom Technology Centre Co. Ltd.
+
+acpi:TCX*:
+ ID_VENDOR_FROM_DATABASE=FREEMARS Heavy Industries
+
+acpi:TDC*:
+ ID_VENDOR_FROM_DATABASE=Teradici
+
+acpi:TDD*:
+ ID_VENDOR_FROM_DATABASE=Tandberg Data Display AS
+
+acpi:TDK*:
+ ID_VENDOR_FROM_DATABASE=TDK USA Corporation
+
+acpi:TDM*:
+ ID_VENDOR_FROM_DATABASE=Tandem Computer Europe Inc
+
+acpi:TDP*:
+ ID_VENDOR_FROM_DATABASE=3D Perception
+
+acpi:TDS*:
+ ID_VENDOR_FROM_DATABASE=Tri-Data Systems Inc
+
+acpi:TDT*:
+ ID_VENDOR_FROM_DATABASE=TDT
+
+acpi:TDV*:
+ ID_VENDOR_FROM_DATABASE=TDVision Systems, Inc.
+
+acpi:TDY*:
+ ID_VENDOR_FROM_DATABASE=Tandy Electronics
+
+acpi:TEA*:
+ ID_VENDOR_FROM_DATABASE=TEAC System Corporation
+
+acpi:TEC*:
+ ID_VENDOR_FROM_DATABASE=Tecmar Inc
+
+acpi:TEK*:
+ ID_VENDOR_FROM_DATABASE=Tektronix Inc
+
+acpi:TEL*:
+ ID_VENDOR_FROM_DATABASE=Promotion and Display Technology Ltd.
+
+acpi:TER*:
+ ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH
+
+acpi:TGC*:
+ ID_VENDOR_FROM_DATABASE=Toshiba Global Commerce Solutions, Inc.
+
+acpi:TGI*:
+ ID_VENDOR_FROM_DATABASE=TriGem Computer Inc
+
+acpi:TGM*:
+ ID_VENDOR_FROM_DATABASE=TriGem Computer,Inc.
+
+acpi:TGS*:
+ ID_VENDOR_FROM_DATABASE=Torus Systems Ltd
+
+acpi:TGV*:
+ ID_VENDOR_FROM_DATABASE=Grass Valley Germany GmbH
+
+acpi:THN*:
+ ID_VENDOR_FROM_DATABASE=Thundercom Holdings Sdn. Bhd.
+
+acpi:TIC*:
+ ID_VENDOR_FROM_DATABASE=Trigem KinfoComm
+
+acpi:TIP*:
+ ID_VENDOR_FROM_DATABASE=TIPTEL AG
+
+acpi:TIV*:
+ ID_VENDOR_FROM_DATABASE=OOO Technoinvest
+
+acpi:TIX*:
+ ID_VENDOR_FROM_DATABASE=Tixi.Com GmbH
+
+acpi:TKC*:
+ ID_VENDOR_FROM_DATABASE=Taiko Electric Works.LTD
+
+acpi:TKN*:
+ ID_VENDOR_FROM_DATABASE=Teknor Microsystem Inc
+
+acpi:TKO*:
+ ID_VENDOR_FROM_DATABASE=TouchKo, Inc.
+
+acpi:TKS*:
+ ID_VENDOR_FROM_DATABASE=TimeKeeping Systems, Inc.
+
+acpi:TLA*:
+ ID_VENDOR_FROM_DATABASE=Ferrari Electronic GmbH
+
+acpi:TLD*:
+ ID_VENDOR_FROM_DATABASE=Telindus
+
+acpi:TLI*:
+ ID_VENDOR_FROM_DATABASE=TOSHIBA TELI CORPORATION
+
+acpi:TLK*:
+ ID_VENDOR_FROM_DATABASE=Telelink AG
+
+acpi:TLS*:
+ ID_VENDOR_FROM_DATABASE=Teleste Educational OY
+
+acpi:TLT*:
+ ID_VENDOR_FROM_DATABASE=Dai Telecom S.p.A.
+
+acpi:TLV*:
+ ID_VENDOR_FROM_DATABASE=S3 Inc
+
+acpi:TLX*:
+ ID_VENDOR_FROM_DATABASE=Telxon Corporation
+
+acpi:TMC*:
+ ID_VENDOR_FROM_DATABASE=Techmedia Computer Systems Corporation
+
+acpi:TME*:
+ ID_VENDOR_FROM_DATABASE=AT&T Microelectronics
+
+acpi:TMI*:
+ ID_VENDOR_FROM_DATABASE=Texas Microsystem
+
+acpi:TMM*:
+ ID_VENDOR_FROM_DATABASE=Time Management, Inc.
+
+acpi:TMR*:
+ ID_VENDOR_FROM_DATABASE=Taicom International Inc
+
+acpi:TMS*:
+ ID_VENDOR_FROM_DATABASE=Trident Microsystems Ltd
+
+acpi:TMT*:
+ ID_VENDOR_FROM_DATABASE=T-Metrics Inc.
+
+acpi:TMX*:
+ ID_VENDOR_FROM_DATABASE=Thermotrex Corporation
+
+acpi:TNC*:
+ ID_VENDOR_FROM_DATABASE=TNC Industrial Company Ltd
+
+acpi:TNM*:
+ ID_VENDOR_FROM_DATABASE=TECNIMAGEN SA
+
+acpi:TNY*:
+ ID_VENDOR_FROM_DATABASE=Tennyson Tech Pty Ltd
+
+acpi:TOE*:
+ ID_VENDOR_FROM_DATABASE=TOEI Electronics Co., Ltd.
+
+acpi:TOG*:
+ ID_VENDOR_FROM_DATABASE=The OPEN Group
+
+acpi:TON*:
+ ID_VENDOR_FROM_DATABASE=TONNA
+
+acpi:TOP*:
+ ID_VENDOR_FROM_DATABASE=Orion Communications Co., Ltd.
+
+acpi:TOS*:
+ ID_VENDOR_FROM_DATABASE=Toshiba Corporation
+
+acpi:TOU*:
+ ID_VENDOR_FROM_DATABASE=Touchstone Technology
+
+acpi:TPC*:
+ ID_VENDOR_FROM_DATABASE=Touch Panel Systems Corporation
+
+acpi:TPE*:
+ ID_VENDOR_FROM_DATABASE=Technology Power Enterprises Inc
+
+acpi:TPJ*:
+ ID_VENDOR_FROM_DATABASE=Junnila
+
+acpi:TPK*:
+ ID_VENDOR_FROM_DATABASE=TOPRE CORPORATION
+
+acpi:TPR*:
+ ID_VENDOR_FROM_DATABASE=Topro Technology Inc
+
+acpi:TPS*:
+ ID_VENDOR_FROM_DATABASE=Teleprocessing Systeme GmbH
+
+acpi:TPT*:
+ ID_VENDOR_FROM_DATABASE=Thruput Ltd
+
+acpi:TPV*:
+ ID_VENDOR_FROM_DATABASE=Top Victory Electronics ( Fujian ) Company Ltd
+
+acpi:TPZ*:
+ ID_VENDOR_FROM_DATABASE=Ypoaz Systems Inc
+
+acpi:TRA*:
+ ID_VENDOR_FROM_DATABASE=TriTech Microelectronics International
+
+acpi:TRC*:
+ ID_VENDOR_FROM_DATABASE=Trioc AB
+
+acpi:TRD*:
+ ID_VENDOR_FROM_DATABASE=Trident Microsystem Inc
+
+acpi:TRE*:
+ ID_VENDOR_FROM_DATABASE=Tremetrics
+
+acpi:TRI*:
+ ID_VENDOR_FROM_DATABASE=Tricord Systems
+
+acpi:TRL*:
+ ID_VENDOR_FROM_DATABASE=Royal Information
+
+acpi:TRM*:
+ ID_VENDOR_FROM_DATABASE=Tekram Technology Company Ltd
+
+acpi:TRN*:
+ ID_VENDOR_FROM_DATABASE=Datacommunicatie Tron B.V.
+
+acpi:TRS*:
+ ID_VENDOR_FROM_DATABASE=Torus Systems Ltd
+
+acpi:TRT*:
+ ID_VENDOR_FROM_DATABASE=Tritec Electronic AG
+
+acpi:TRU*:
+ ID_VENDOR_FROM_DATABASE=Aashima Technology B.V.
+
+acpi:TRV*:
+ ID_VENDOR_FROM_DATABASE=Trivisio Prototyping GmbH
+
+acpi:TRX*:
+ ID_VENDOR_FROM_DATABASE=Trex Enterprises
+
+acpi:TSB*:
+ ID_VENDOR_FROM_DATABASE=Toshiba America Info Systems Inc
+
+acpi:TSC*:
+ ID_VENDOR_FROM_DATABASE=Sanyo Electric Company Ltd
+
+acpi:TSD*:
+ ID_VENDOR_FROM_DATABASE=TechniSat Digital GmbH
+
+acpi:TSE*:
+ ID_VENDOR_FROM_DATABASE=Tottori Sanyo Electric
+
+acpi:TSF*:
+ ID_VENDOR_FROM_DATABASE=Racal-Airtech Software Forge Ltd
+
+acpi:TSG*:
+ ID_VENDOR_FROM_DATABASE=The Software Group Ltd
+
+acpi:TSI*:
+ ID_VENDOR_FROM_DATABASE=TeleVideo Systems
+
+acpi:TSL*:
+ ID_VENDOR_FROM_DATABASE=Tottori SANYO Electric Co., Ltd.
+
+acpi:TSP*:
+ ID_VENDOR_FROM_DATABASE=U.S. Navy
+
+acpi:TST*:
+ ID_VENDOR_FROM_DATABASE=Transtream Inc
+
+acpi:TSV*:
+ ID_VENDOR_FROM_DATABASE=TRANSVIDEO
+
+acpi:TSY*:
+ ID_VENDOR_FROM_DATABASE=TouchSystems
+
+acpi:TTA*:
+ ID_VENDOR_FROM_DATABASE=Topson Technology Co., Ltd.
+
+acpi:TTB*:
+ ID_VENDOR_FROM_DATABASE=National Semiconductor Japan Ltd
+
+acpi:TTC*:
+ ID_VENDOR_FROM_DATABASE=Telecommunications Techniques Corporation
+
+acpi:TTE*:
+ ID_VENDOR_FROM_DATABASE=TTE, Inc.
+
+acpi:TTI*:
+ ID_VENDOR_FROM_DATABASE=Trenton Terminals Inc
+
+acpi:TTK*:
+ ID_VENDOR_FROM_DATABASE=Totoku Electric Company Ltd
+
+acpi:TTL*:
+ ID_VENDOR_FROM_DATABASE=2-Tel B.V.
+
+acpi:TTS*:
+ ID_VENDOR_FROM_DATABASE=TechnoTrend Systemtechnik GmbH
+
+acpi:TTY*:
+ ID_VENDOR_FROM_DATABASE=TRIDELITY Display Solutions GmbH
+
+acpi:TUA*:
+ ID_VENDOR_FROM_DATABASE=T+A elektroakustik GmbH
+
+acpi:TUT*:
+ ID_VENDOR_FROM_DATABASE=Tut Systems
+
+acpi:TVD*:
+ ID_VENDOR_FROM_DATABASE=Tecnovision
+
+acpi:TVI*:
+ ID_VENDOR_FROM_DATABASE=Truevision
+
+acpi:TVM*:
+ ID_VENDOR_FROM_DATABASE=Taiwan Video & Monitor Corporation
+
+acpi:TVO*:
+ ID_VENDOR_FROM_DATABASE=TV One Ltd
+
+acpi:TVR*:
+ ID_VENDOR_FROM_DATABASE=TV Interactive Corporation
+
+acpi:TVS*:
+ ID_VENDOR_FROM_DATABASE=TVS Electronics Limited
+
+acpi:TVV*:
+ ID_VENDOR_FROM_DATABASE=TV1 GmbH
+
+acpi:TWA*:
+ ID_VENDOR_FROM_DATABASE=Tidewater Association
+
+acpi:TWE*:
+ ID_VENDOR_FROM_DATABASE=Kontron Electronik
+
+acpi:TWH*:
+ ID_VENDOR_FROM_DATABASE=Twinhead International Corporation
+
+acpi:TWI*:
+ ID_VENDOR_FROM_DATABASE=Easytel oy
+
+acpi:TWK*:
+ ID_VENDOR_FROM_DATABASE=TOWITOKO electronics GmbH
+
+acpi:TWX*:
+ ID_VENDOR_FROM_DATABASE=TEKWorx Limited
+
+acpi:TXL*:
+ ID_VENDOR_FROM_DATABASE=Trixel Ltd
+
+acpi:TXN*:
+ ID_VENDOR_FROM_DATABASE=Texas Insturments
+
+acpi:TXT*:
+ ID_VENDOR_FROM_DATABASE=Textron Defense System
+
+acpi:TYN*:
+ ID_VENDOR_FROM_DATABASE=Tyan Computer Corporation
+
+acpi:UAS*:
+ ID_VENDOR_FROM_DATABASE=Ultima Associates Pte Ltd
+
+acpi:UBI*:
+ ID_VENDOR_FROM_DATABASE=Ungermann-Bass Inc
+
+acpi:UBL*:
+ ID_VENDOR_FROM_DATABASE=Ubinetics Ltd.
+
+acpi:UDN*:
+ ID_VENDOR_FROM_DATABASE=Uniden Corporation
+
+acpi:UEC*:
+ ID_VENDOR_FROM_DATABASE=Ultima Electronics Corporation
+
+acpi:UEG*:
+ ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems Company Ltd
+
+acpi:UEI*:
+ ID_VENDOR_FROM_DATABASE=Universal Electronics Inc
+
+acpi:UET*:
+ ID_VENDOR_FROM_DATABASE=Universal Empowering Technologies
+
+acpi:UFG*:
+ ID_VENDOR_FROM_DATABASE=UNIGRAF-USA
+
+acpi:UFO*:
+ ID_VENDOR_FROM_DATABASE=UFO Systems Inc
+
+acpi:UHB*:
+ ID_VENDOR_FROM_DATABASE=XOCECO
+
+acpi:UIC*:
+ ID_VENDOR_FROM_DATABASE=Uniform Industrial Corporation
+
+acpi:UJR*:
+ ID_VENDOR_FROM_DATABASE=Ueda Japan Radio Co., Ltd.
+
+acpi:ULT*:
+ ID_VENDOR_FROM_DATABASE=Ultra Network Tech
+
+acpi:UMC*:
+ ID_VENDOR_FROM_DATABASE=United Microelectr Corporation
+
+acpi:UMG*:
+ ID_VENDOR_FROM_DATABASE=Umezawa Giken Co.,Ltd
+
+acpi:UMM*:
+ ID_VENDOR_FROM_DATABASE=Universal Multimedia
+
+acpi:UNA*:
+ ID_VENDOR_FROM_DATABASE=Unisys DSD
+
+acpi:UNB*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNC*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNI*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNM*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNO*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNP*:
+ ID_VENDOR_FROM_DATABASE=Unitop
+
+acpi:UNS*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNT*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNY*:
+ ID_VENDOR_FROM_DATABASE=Unicate
+
+acpi:UPP*:
+ ID_VENDOR_FROM_DATABASE=UPPI
+
+acpi:UPS*:
+ ID_VENDOR_FROM_DATABASE=Systems Enhancement
+
+acpi:URD*:
+ ID_VENDOR_FROM_DATABASE=Video Computer S.p.A.
+
+acpi:USA*:
+ ID_VENDOR_FROM_DATABASE=Utimaco Safeware AG
+
+acpi:USD*:
+ ID_VENDOR_FROM_DATABASE=U.S. Digital Corporation
+
+acpi:USI*:
+ ID_VENDOR_FROM_DATABASE=Universal Scientific Industrial Co., Ltd.
+
+acpi:USR*:
+ ID_VENDOR_FROM_DATABASE=U.S. Robotics Inc
+
+acpi:UTD*:
+ ID_VENDOR_FROM_DATABASE=Up to Date Tech
+
+acpi:UWC*:
+ ID_VENDOR_FROM_DATABASE=Uniwill Computer Corp.
+
+acpi:VAL*:
+ ID_VENDOR_FROM_DATABASE=Valence Computing Corporation
+
+acpi:VAR*:
+ ID_VENDOR_FROM_DATABASE=Varian Australia Pty Ltd
+
+acpi:VBR*:
+ ID_VENDOR_FROM_DATABASE=VBrick Systems Inc.
+
+acpi:VBT*:
+ ID_VENDOR_FROM_DATABASE=Valley Board Ltda
+
+acpi:VCC*:
+ ID_VENDOR_FROM_DATABASE=Virtual Computer Corporation
+
+acpi:VCI*:
+ ID_VENDOR_FROM_DATABASE=VistaCom Inc
+
+acpi:VCJ*:
+ ID_VENDOR_FROM_DATABASE=Victor Company of Japan, Limited
+
+acpi:VCM*:
+ ID_VENDOR_FROM_DATABASE=Vector Magnetics, LLC
+
+acpi:VCX*:
+ ID_VENDOR_FROM_DATABASE=VCONEX
+
+acpi:VDA*:
+ ID_VENDOR_FROM_DATABASE=Victor Data Systems
+
+acpi:VDC*:
+ ID_VENDOR_FROM_DATABASE=VDC Display Systems
+
+acpi:VDM*:
+ ID_VENDOR_FROM_DATABASE=Vadem
+
+acpi:VDO*:
+ ID_VENDOR_FROM_DATABASE=Video & Display Oriented Corporation
+
+acpi:VDS*:
+ ID_VENDOR_FROM_DATABASE=Vidisys GmbH & Company
+
+acpi:VDT*:
+ ID_VENDOR_FROM_DATABASE=Viditec, Inc.
+
+acpi:VEC*:
+ ID_VENDOR_FROM_DATABASE=Vector Informatik GmbH
+
+acpi:VEK*:
+ ID_VENDOR_FROM_DATABASE=Vektrex
+
+acpi:VES*:
+ ID_VENDOR_FROM_DATABASE=Vestel Elektronik Sanayi ve Ticaret A. S.
+
+acpi:VFI*:
+ ID_VENDOR_FROM_DATABASE=VeriFone Inc
+
+acpi:VHI*:
+ ID_VENDOR_FROM_DATABASE=Macrocad Development Inc.
+
+acpi:VIA*:
+ ID_VENDOR_FROM_DATABASE=VIA Tech Inc
+
+acpi:VIB*:
+ ID_VENDOR_FROM_DATABASE=Tatung UK Ltd
+
+acpi:VIC*:
+ ID_VENDOR_FROM_DATABASE=Victron B.V.
+
+acpi:VID*:
+ ID_VENDOR_FROM_DATABASE=Ingram Macrotron Germany
+
+acpi:VIK*:
+ ID_VENDOR_FROM_DATABASE=Viking Connectors
+
+acpi:VIN*:
+ ID_VENDOR_FROM_DATABASE=Vine Micros Ltd
+
+acpi:VIR*:
+ ID_VENDOR_FROM_DATABASE=Visual Interface, Inc
+
+acpi:VIS*:
+ ID_VENDOR_FROM_DATABASE=Visioneer
+
+acpi:VIT*:
+ ID_VENDOR_FROM_DATABASE=Visitech AS
+
+acpi:VIZ*:
+ ID_VENDOR_FROM_DATABASE=VIZIO, Inc
+
+acpi:VLB*:
+ ID_VENDOR_FROM_DATABASE=ValleyBoard Ltda.
+
+acpi:VLT*:
+ ID_VENDOR_FROM_DATABASE=VideoLan Technologies
+
+acpi:VMI*:
+ ID_VENDOR_FROM_DATABASE=Vermont Microsystems
+
+acpi:VML*:
+ ID_VENDOR_FROM_DATABASE=Vine Micros Limited
+
+acpi:VMW*:
+ ID_VENDOR_FROM_DATABASE=VMware Inc.,
+
+acpi:VNC*:
+ ID_VENDOR_FROM_DATABASE=Vinca Corporation
+
+acpi:VOB*:
+ ID_VENDOR_FROM_DATABASE=MaxData Computer AG
+
+acpi:VPI*:
+ ID_VENDOR_FROM_DATABASE=Video Products Inc
+
+acpi:VPR*:
+ ID_VENDOR_FROM_DATABASE=Best Buy
+
+acpi:VQ@*:
+ ID_VENDOR_FROM_DATABASE=Vision Quest
+
+acpi:VRC*:
+ ID_VENDOR_FROM_DATABASE=Virtual Resources Corporation
+
+acpi:VSC*:
+ ID_VENDOR_FROM_DATABASE=ViewSonic Corporation
+
+acpi:VSD*:
+ ID_VENDOR_FROM_DATABASE=3M
+
+acpi:VSI*:
+ ID_VENDOR_FROM_DATABASE=VideoServer
+
+acpi:VSN*:
+ ID_VENDOR_FROM_DATABASE=Ingram Macrotron
+
+acpi:VSP*:
+ ID_VENDOR_FROM_DATABASE=Vision Systems GmbH
+
+acpi:VSR*:
+ ID_VENDOR_FROM_DATABASE=V-Star Electronics Inc.
+
+acpi:VTC*:
+ ID_VENDOR_FROM_DATABASE=VTel Corporation
+
+acpi:VTG*:
+ ID_VENDOR_FROM_DATABASE=Voice Technologies Group Inc
+
+acpi:VTI*:
+ ID_VENDOR_FROM_DATABASE=VLSI Tech Inc
+
+acpi:VTK*:
+ ID_VENDOR_FROM_DATABASE=Viewteck Co., Ltd.
+
+acpi:VTL*:
+ ID_VENDOR_FROM_DATABASE=Vivid Technology Pte Ltd
+
+acpi:VTM*:
+ ID_VENDOR_FROM_DATABASE=Miltope Corporation
+
+acpi:VTN*:
+ ID_VENDOR_FROM_DATABASE=VIDEOTRON CORP.
+
+acpi:VTS*:
+ ID_VENDOR_FROM_DATABASE=VTech Computers Ltd
+
+acpi:VTV*:
+ ID_VENDOR_FROM_DATABASE=VATIV Technologies
+
+acpi:VTX*:
+ ID_VENDOR_FROM_DATABASE=Vestax Corporation
+
+acpi:VUT*:
+ ID_VENDOR_FROM_DATABASE=Vutrix (UK) Ltd
+
+acpi:VWB*:
+ ID_VENDOR_FROM_DATABASE=Vweb Corp.
+
+acpi:WAC*:
+ ID_VENDOR_FROM_DATABASE=Wacom Tech
+
+acpi:WAL*:
+ ID_VENDOR_FROM_DATABASE=Wave Access
+
+acpi:WAV*:
+ ID_VENDOR_FROM_DATABASE=Wavephore
+
+acpi:WBN*:
+ ID_VENDOR_FROM_DATABASE=MicroSoftWare
+
+acpi:WBS*:
+ ID_VENDOR_FROM_DATABASE=WB Systemtechnik GmbH
+
+acpi:WCI*:
+ ID_VENDOR_FROM_DATABASE=Wisecom Inc
+
+acpi:WCS*:
+ ID_VENDOR_FROM_DATABASE=Woodwind Communications Systems Inc
+
+acpi:WDC*:
+ ID_VENDOR_FROM_DATABASE=Western Digital
+
+acpi:WDE*:
+ ID_VENDOR_FROM_DATABASE=Westinghouse Digital Electronics
+
+acpi:WEB*:
+ ID_VENDOR_FROM_DATABASE=WebGear Inc
+
+acpi:WEC*:
+ ID_VENDOR_FROM_DATABASE=Winbond Electronics Corporation
+
+acpi:WEL *:
+ ID_VENDOR_FROM_DATABASE=W-DEV
+
+acpi:WEY*:
+ ID_VENDOR_FROM_DATABASE=WEY Design AG
+
+acpi:WHI*:
+ ID_VENDOR_FROM_DATABASE=Whistle Communications
+
+acpi:WII*:
+ ID_VENDOR_FROM_DATABASE=Innoware Inc
+
+acpi:WIL*:
+ ID_VENDOR_FROM_DATABASE=WIPRO Information Technology Ltd
+
+acpi:WIN*:
+ ID_VENDOR_FROM_DATABASE=Wintop Technology Inc
+
+acpi:WIP*:
+ ID_VENDOR_FROM_DATABASE=Wipro Infotech
+
+acpi:WKH*:
+ ID_VENDOR_FROM_DATABASE=Uni-Take Int'l Inc.
+
+acpi:WLD*:
+ ID_VENDOR_FROM_DATABASE=Wildfire Communications Inc
+
+acpi:WML*:
+ ID_VENDOR_FROM_DATABASE=Wolfson Microelectronics Ltd
+
+acpi:WMO*:
+ ID_VENDOR_FROM_DATABASE=Westermo Teleindustri AB
+
+acpi:WMT*:
+ ID_VENDOR_FROM_DATABASE=Winmate Communication Inc
+
+acpi:WNI*:
+ ID_VENDOR_FROM_DATABASE=WillNet Inc.
+
+acpi:WNV*:
+ ID_VENDOR_FROM_DATABASE=Winnov L.P.
+
+acpi:WNX*:
+ ID_VENDOR_FROM_DATABASE=Wincor Nixdorf International GmbH
+
+acpi:WPA*:
+ ID_VENDOR_FROM_DATABASE=Matsushita Communication Industrial Co., Ltd.
+
+acpi:WPI*:
+ ID_VENDOR_FROM_DATABASE=Wearnes Peripherals International (Pte) Ltd
+
+acpi:WRC*:
+ ID_VENDOR_FROM_DATABASE=WiNRADiO Communications
+
+acpi:WSC*:
+ ID_VENDOR_FROM_DATABASE=CIS Technology Inc
+
+acpi:WSP*:
+ ID_VENDOR_FROM_DATABASE=Wireless And Smart Products Inc.
+
+acpi:WST*:
+ ID_VENDOR_FROM_DATABASE=Wistron Corporation
+
+acpi:WTC*:
+ ID_VENDOR_FROM_DATABASE=ACC Microelectronics
+
+acpi:WTI*:
+ ID_VENDOR_FROM_DATABASE=WorkStation Tech
+
+acpi:WTK*:
+ ID_VENDOR_FROM_DATABASE=Wearnes Thakral Pte
+
+acpi:WTS*:
+ ID_VENDOR_FROM_DATABASE=Restek Electric Company Ltd
+
+acpi:WVM*:
+ ID_VENDOR_FROM_DATABASE=Wave Systems Corporation
+
+acpi:WWV*:
+ ID_VENDOR_FROM_DATABASE=World Wide Video, Inc.
+
+acpi:WXT*:
+ ID_VENDOR_FROM_DATABASE=Woxter Technology Co. Ltd
+
+acpi:WYS*:
+ ID_VENDOR_FROM_DATABASE=Myse Technology
+
+acpi:WYT*:
+ ID_VENDOR_FROM_DATABASE=Wooyoung Image & Information Co.,Ltd.
+
+acpi:XAC*:
+ ID_VENDOR_FROM_DATABASE=XAC Automation Corp
+
+acpi:XAD*:
+ ID_VENDOR_FROM_DATABASE=Alpha Data
+
+acpi:XDM*:
+ ID_VENDOR_FROM_DATABASE=XDM Ltd.
+
+acpi:XFG*:
+ ID_VENDOR_FROM_DATABASE=Jan Strapko - FOTO
+
+acpi:XFO*:
+ ID_VENDOR_FROM_DATABASE=EXFO Electro Optical Engineering
+
+acpi:XIN*:
+ ID_VENDOR_FROM_DATABASE=Xinex Networks Inc
+
+acpi:XIO*:
+ ID_VENDOR_FROM_DATABASE=Xiotech Corporation
+
+acpi:XIR*:
+ ID_VENDOR_FROM_DATABASE=Xirocm Inc
+
+acpi:XIT*:
+ ID_VENDOR_FROM_DATABASE=Xitel Pty ltd
+
+acpi:XLX*:
+ ID_VENDOR_FROM_DATABASE=Xilinx, Inc.
+
+acpi:XMM*:
+ ID_VENDOR_FROM_DATABASE=C3PO S.L.
+
+acpi:XNT*:
+ ID_VENDOR_FROM_DATABASE=XN Technologies, Inc.
+
+acpi:XQU*:
+ ID_VENDOR_FROM_DATABASE=SHANGHAI SVA-DAV ELECTRONICS CO., LTD
+
+acpi:XRC*:
+ ID_VENDOR_FROM_DATABASE=Xircom Inc
+
+acpi:XRO*:
+ ID_VENDOR_FROM_DATABASE=XORO ELECTRONICS (CHENGDU) LIMITED
+
+acpi:XSN*:
+ ID_VENDOR_FROM_DATABASE=Xscreen AS
+
+acpi:XST*:
+ ID_VENDOR_FROM_DATABASE=XS Technologies Inc
+
+acpi:XSY*:
+ ID_VENDOR_FROM_DATABASE=XSYS
+
+acpi:XTD*:
+ ID_VENDOR_FROM_DATABASE=Icuiti Corporation
+
+acpi:XTE*:
+ ID_VENDOR_FROM_DATABASE=X2E GmbH
+
+acpi:XTL*:
+ ID_VENDOR_FROM_DATABASE=Crystal Computer
+
+acpi:XTN*:
+ ID_VENDOR_FROM_DATABASE=X-10 (USA) Inc
+
+acpi:XYC*:
+ ID_VENDOR_FROM_DATABASE=Xycotec Computer GmbH
+
+acpi:YED*:
+ ID_VENDOR_FROM_DATABASE=Y-E Data Inc
+
+acpi:YHQ*:
+ ID_VENDOR_FROM_DATABASE=Yokogawa Electric Corporation
+
+acpi:YHW*:
+ ID_VENDOR_FROM_DATABASE=Exacom SA
+
+acpi:YMH*:
+ ID_VENDOR_FROM_DATABASE=Yamaha Corporation
+
+acpi:YOW*:
+ ID_VENDOR_FROM_DATABASE=American Biometric Company
+
+acpi:ZAN*:
+ ID_VENDOR_FROM_DATABASE=Zandar Technologies plc
+
+acpi:ZAX*:
+ ID_VENDOR_FROM_DATABASE=Zefiro Acoustics
+
+acpi:ZAZ*:
+ ID_VENDOR_FROM_DATABASE=Zazzle Technologies
+
+acpi:ZBR*:
+ ID_VENDOR_FROM_DATABASE=Zebra Technologies International, LLC
+
+acpi:ZCT*:
+ ID_VENDOR_FROM_DATABASE=ZeitControl cardsystems GmbH
+
+acpi:ZDS*:
+ ID_VENDOR_FROM_DATABASE=Zenith Data Systems
+
+acpi:ZGT*:
+ ID_VENDOR_FROM_DATABASE=Zenith Data Systems
+
+acpi:ZIC*:
+ ID_VENDOR_FROM_DATABASE=Nationz Technologies Inc.
+
+acpi:ZMT*:
+ ID_VENDOR_FROM_DATABASE=Zalman Tech Co., Ltd.
+
+acpi:ZMZ*:
+ ID_VENDOR_FROM_DATABASE=Z Microsystems
+
+acpi:ZNI*:
+ ID_VENDOR_FROM_DATABASE=Zetinet Inc
+
+acpi:ZNX*:
+ ID_VENDOR_FROM_DATABASE=Znyx Adv. Systems
+
+acpi:ZOW*:
+ ID_VENDOR_FROM_DATABASE=Zowie Intertainment, Inc
+
+acpi:ZRN*:
+ ID_VENDOR_FROM_DATABASE=Zoran Corporation
+
+acpi:ZSE*:
+ ID_VENDOR_FROM_DATABASE=Zenith Data Systems
+
+acpi:ZTC*:
+ ID_VENDOR_FROM_DATABASE=ZyDAS Technology Corporation
+
+acpi:ZTE*:
+ ID_VENDOR_FROM_DATABASE=ZTE Corporation
+
+acpi:ZTI*:
+ ID_VENDOR_FROM_DATABASE=Zoom Telephonics Inc
+
+acpi:ZTM*:
+ ID_VENDOR_FROM_DATABASE=ZT Group Int'l Inc.
+
+acpi:ZTT*:
+ ID_VENDOR_FROM_DATABASE=Z3 Technology
+
+acpi:ZYD*:
+ ID_VENDOR_FROM_DATABASE=Zydacron Inc
+
+acpi:ZYP*:
+ ID_VENDOR_FROM_DATABASE=Zypcom Inc
+
+acpi:ZYT*:
+ ID_VENDOR_FROM_DATABASE=Zytex Computers
+
+acpi:ZYX*:
+ ID_VENDOR_FROM_DATABASE=Zyxel
+
+acpi:ZZZ*:
+ ID_VENDOR_FROM_DATABASE=Boca Research Inc
diff --git a/hwdb/20-bluetooth-vendor-product.hwdb b/hwdb/20-bluetooth-vendor-product.hwdb
new file mode 100644 (file)
index 0000000..c8cb322
--- /dev/null
@@ -0,0 +1,541 @@
+# This file is part of systemd.
+#
+# Data imported from:
+#  http://www.bluetooth.org/Technical/AssignedNumbers/identifiers.htm
+
+bluetooth:v0000*
+ ID_VENDOR_FROM_DATABASE=Ericsson Technology Licensing
+
+bluetooth:v0001*
+ ID_VENDOR_FROM_DATABASE=Nokia Mobile Phones
+
+bluetooth:v0002*
+ ID_VENDOR_FROM_DATABASE=Intel Corp.
+
+bluetooth:v0003*
+ ID_VENDOR_FROM_DATABASE=IBM Corp.
+
+bluetooth:v0004*
+ ID_VENDOR_FROM_DATABASE=Toshiba Corp.
+
+bluetooth:v0005*
+ ID_VENDOR_FROM_DATABASE=3Com
+
+bluetooth:v0006*
+ ID_VENDOR_FROM_DATABASE=Microsoft
+
+bluetooth:v0007*
+ ID_VENDOR_FROM_DATABASE=Lucent
+
+bluetooth:v0008*
+ ID_VENDOR_FROM_DATABASE=Motorola
+
+bluetooth:v0009*
+ ID_VENDOR_FROM_DATABASE=Infineon Technologies AG
+
+bluetooth:v000A*
+ ID_VENDOR_FROM_DATABASE=Cambridge Silicon Radio
+
+bluetooth:v000B*
+ ID_VENDOR_FROM_DATABASE=Silicon Wave
+
+bluetooth:v000C*
+ ID_VENDOR_FROM_DATABASE=Digianswer A/S
+
+bluetooth:v000D*
+ ID_VENDOR_FROM_DATABASE=Texas Instruments Inc.
+
+bluetooth:v000E*
+ ID_VENDOR_FROM_DATABASE=Ceva, Inc. (formerly Parthus Technologies Inc.)
+
+bluetooth:v000F*
+ ID_VENDOR_FROM_DATABASE=Broadcom Corporation
+
+bluetooth:v0010*
+ ID_VENDOR_FROM_DATABASE=Mitel Semiconductor
+
+bluetooth:v0011*
+ ID_VENDOR_FROM_DATABASE=Widcomm, Inc.
+
+bluetooth:v0012*
+ ID_VENDOR_FROM_DATABASE=Zeevo, Inc.
+
+bluetooth:v0013*
+ ID_VENDOR_FROM_DATABASE=Atmel Corporation
+
+bluetooth:v0014*
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corporation
+
+bluetooth:v0015*
+ ID_VENDOR_FROM_DATABASE=RTX Telecom A/S
+
+bluetooth:v0016*
+ ID_VENDOR_FROM_DATABASE=KC Technology Inc.
+
+bluetooth:v0017*
+ ID_VENDOR_FROM_DATABASE=Newlogic
+
+bluetooth:v0018*
+ ID_VENDOR_FROM_DATABASE=Transilica, Inc.
+
+bluetooth:v0019*
+ ID_VENDOR_FROM_DATABASE=Rohde & Schwartz GmbH & Co. KG
+
+bluetooth:v001A*
+ ID_VENDOR_FROM_DATABASE=TTPCom Limited
+
+bluetooth:v001B*
+ ID_VENDOR_FROM_DATABASE=Signia Technologies, Inc.
+
+bluetooth:v001C*
+ ID_VENDOR_FROM_DATABASE=Conexant Systems Inc.
+
+bluetooth:v001D*
+ ID_VENDOR_FROM_DATABASE=Qualcomm
+
+bluetooth:v001E*
+ ID_VENDOR_FROM_DATABASE=Inventel
+
+bluetooth:v001F*
+ ID_VENDOR_FROM_DATABASE=AVM Berlin
+
+bluetooth:v0020*
+ ID_VENDOR_FROM_DATABASE=BandSpeed, Inc.
+
+bluetooth:v0021*
+ ID_VENDOR_FROM_DATABASE=Mansella Ltd
+
+bluetooth:v0022*
+ ID_VENDOR_FROM_DATABASE=NEC Corporation
+
+bluetooth:v0023*
+ ID_VENDOR_FROM_DATABASE=WavePlus Technology Co., Ltd.
+
+bluetooth:v0024*
+ ID_VENDOR_FROM_DATABASE=Alcatel
+
+bluetooth:v0025*
+ ID_VENDOR_FROM_DATABASE=Philips Semiconductors
+
+bluetooth:v0026*
+ ID_VENDOR_FROM_DATABASE=C Technologies
+
+bluetooth:v0027*
+ ID_VENDOR_FROM_DATABASE=Open Interface
+
+bluetooth:v0028*
+ ID_VENDOR_FROM_DATABASE=R F Micro Devices
+
+bluetooth:v0029*
+ ID_VENDOR_FROM_DATABASE=Hitachi Ltd
+
+bluetooth:v002A*
+ ID_VENDOR_FROM_DATABASE=Symbol Technologies, Inc.
+
+bluetooth:v002B*
+ ID_VENDOR_FROM_DATABASE=Tenovis
+
+bluetooth:v002C*
+ ID_VENDOR_FROM_DATABASE=Macronix International Co. Ltd.
+
+bluetooth:v002D*
+ ID_VENDOR_FROM_DATABASE=GCT Semiconductor
+
+bluetooth:v002E*
+ ID_VENDOR_FROM_DATABASE=Norwood Systems
+
+bluetooth:v002F*
+ ID_VENDOR_FROM_DATABASE=MewTel Technology Inc.
+
+bluetooth:v0030*
+ ID_VENDOR_FROM_DATABASE=ST Microelectronics
+
+bluetooth:v0031*
+ ID_VENDOR_FROM_DATABASE=Synopsys
+
+bluetooth:v0032*
+ ID_VENDOR_FROM_DATABASE=Red-M (Communications) Ltd
+
+bluetooth:v0033*
+ ID_VENDOR_FROM_DATABASE=Commil Ltd
+
+bluetooth:v0034*
+ ID_VENDOR_FROM_DATABASE=Computer Access Technology Corporation (CATC)
+
+bluetooth:v0035*
+ ID_VENDOR_FROM_DATABASE=Eclipse (HQ Espana) S.L.
+
+bluetooth:v0036*
+ ID_VENDOR_FROM_DATABASE=Renesas Technology Corp.
+
+bluetooth:v0037*
+ ID_VENDOR_FROM_DATABASE=Mobilian Corporation
+
+bluetooth:v0038*
+ ID_VENDOR_FROM_DATABASE=Terax
+
+bluetooth:v0039*
+ ID_VENDOR_FROM_DATABASE=Integrated System Solution Corp.
+
+bluetooth:v003A*
+ ID_VENDOR_FROM_DATABASE=Matsushita Electric Industrial Co., Ltd.
+
+bluetooth:v003B*
+ ID_VENDOR_FROM_DATABASE=Gennum Corporation
+
+bluetooth:v003C*
+ ID_VENDOR_FROM_DATABASE=Research In Motion
+
+bluetooth:v003D*
+ ID_VENDOR_FROM_DATABASE=IPextreme, Inc.
+
+bluetooth:v003E*
+ ID_VENDOR_FROM_DATABASE=Systems and Chips, Inc
+
+bluetooth:v003F*
+ ID_VENDOR_FROM_DATABASE=Bluetooth SIG, Inc
+
+bluetooth:v0040*
+ ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation
+
+bluetooth:v0041*
+ ID_VENDOR_FROM_DATABASE=Integrated Silicon Solution Taiwain, Inc.
+
+bluetooth:v0042*
+ ID_VENDOR_FROM_DATABASE=CONWISE Technology Corporation Ltd
+
+bluetooth:v0043*
+ ID_VENDOR_FROM_DATABASE=PARROT SA
+
+bluetooth:v0044*
+ ID_VENDOR_FROM_DATABASE=Socket Mobile
+
+bluetooth:v0045*
+ ID_VENDOR_FROM_DATABASE=Atheros Communications, Inc.
+
+bluetooth:v0046*
+ ID_VENDOR_FROM_DATABASE=MediaTek, Inc.
+
+bluetooth:v0047*
+ ID_VENDOR_FROM_DATABASE=Bluegiga
+
+bluetooth:v0048*
+ ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd.
+
+bluetooth:v0049*
+ ID_VENDOR_FROM_DATABASE=3DSP Corporation
+
+bluetooth:v004A*
+ ID_VENDOR_FROM_DATABASE=Accel Semiconductor Ltd.
+
+bluetooth:v004B*
+ ID_VENDOR_FROM_DATABASE=Continental Automotive Systems
+
+bluetooth:v004C*
+ ID_VENDOR_FROM_DATABASE=Apple, Inc.
+
+bluetooth:v004D*
+ ID_VENDOR_FROM_DATABASE=Staccato Communications, Inc.
+
+bluetooth:v004E*
+ ID_VENDOR_FROM_DATABASE=Avago Technologies
+
+bluetooth:v004F*
+ ID_VENDOR_FROM_DATABASE=APT Licensing Ltd.
+
+bluetooth:v0050*
+ ID_VENDOR_FROM_DATABASE=SiRF Technology, Inc.
+
+bluetooth:v0051*
+ ID_VENDOR_FROM_DATABASE=Tzero Technologies, Inc.
+
+bluetooth:v0052*
+ ID_VENDOR_FROM_DATABASE=J&M Corporation
+
+bluetooth:v0053*
+ ID_VENDOR_FROM_DATABASE=Free2move AB
+
+bluetooth:v0054*
+ ID_VENDOR_FROM_DATABASE=3DiJoy Corporation
+
+bluetooth:v0055*
+ ID_VENDOR_FROM_DATABASE=Plantronics, Inc.
+
+bluetooth:v0056*
+ ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications
+
+bluetooth:v0057*
+ ID_VENDOR_FROM_DATABASE=Harman International Industries, Inc.
+
+bluetooth:v0058*
+ ID_VENDOR_FROM_DATABASE=Vizio, Inc.
+
+bluetooth:v0059*
+ ID_VENDOR_FROM_DATABASE=Nordic Semiconductor ASA
+
+bluetooth:v005A*
+ ID_VENDOR_FROM_DATABASE=EM Microelectronic-Marin SA
+
+bluetooth:v005B*
+ ID_VENDOR_FROM_DATABASE=Ralink Technology Corporation
+
+bluetooth:v005C*
+ ID_VENDOR_FROM_DATABASE=Belkin International, Inc.
+
+bluetooth:v005D*
+ ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corporation
+
+bluetooth:v005E*
+ ID_VENDOR_FROM_DATABASE=Stonestreet One, LLC
+
+bluetooth:v005F*
+ ID_VENDOR_FROM_DATABASE=Wicentric, Inc.
+
+bluetooth:v0060*
+ ID_VENDOR_FROM_DATABASE=RivieraWaves S.A.S
+
+bluetooth:v0061*
+ ID_VENDOR_FROM_DATABASE=RDA Microelectronics
+
+bluetooth:v0062*
+ ID_VENDOR_FROM_DATABASE=Gibson Guitars
+
+bluetooth:v0063*
+ ID_VENDOR_FROM_DATABASE=MiCommand Inc.
+
+bluetooth:v0064*
+ ID_VENDOR_FROM_DATABASE=Band XI International, LLC
+
+bluetooth:v0065*
+ ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company
+
+bluetooth:v0066*
+ ID_VENDOR_FROM_DATABASE=9Solutions Oy
+
+bluetooth:v0067*
+ ID_VENDOR_FROM_DATABASE=GN Netcom A/S
+
+bluetooth:v0068*
+ ID_VENDOR_FROM_DATABASE=General Motors
+
+bluetooth:v0069*
+ ID_VENDOR_FROM_DATABASE=A&D Engineering, Inc.
+
+bluetooth:v006A*
+ ID_VENDOR_FROM_DATABASE=MindTree Ltd.
+
+bluetooth:v006B*
+ ID_VENDOR_FROM_DATABASE=Polar Electro OY
+
+bluetooth:v006C*
+ ID_VENDOR_FROM_DATABASE=Beautiful Enterprise Co., Ltd.
+
+bluetooth:v006D*
+ ID_VENDOR_FROM_DATABASE=BriarTek, Inc.
+
+bluetooth:v006E*
+ ID_VENDOR_FROM_DATABASE=Summit Data Communications, Inc.
+
+bluetooth:v006F*
+ ID_VENDOR_FROM_DATABASE=Sound ID
+
+bluetooth:v0070*
+ ID_VENDOR_FROM_DATABASE=Monster, LLC
+
+bluetooth:v0071*
+ ID_VENDOR_FROM_DATABASE=connectBlue AB
+
+bluetooth:v0072*
+ ID_VENDOR_FROM_DATABASE=ShangHai Super Smart Electronics Co. Ltd.
+
+bluetooth:v0073*
+ ID_VENDOR_FROM_DATABASE=Group Sense Ltd.
+
+bluetooth:v0074*
+ ID_VENDOR_FROM_DATABASE=Zomm, LLC
+
+bluetooth:v0075*
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics Co. Ltd.
+
+bluetooth:v0076*
+ ID_VENDOR_FROM_DATABASE=Creative Technology Ltd.
+
+bluetooth:v0077*
+ ID_VENDOR_FROM_DATABASE=Laird Technologies
+
+bluetooth:v0078*
+ ID_VENDOR_FROM_DATABASE=Nike, Inc.
+
+bluetooth:v0079*
+ ID_VENDOR_FROM_DATABASE=lesswire AG
+
+bluetooth:v007A*
+ ID_VENDOR_FROM_DATABASE=MStar Semiconductor, Inc.
+
+bluetooth:v007B*
+ ID_VENDOR_FROM_DATABASE=Hanlynn Technologies
+
+bluetooth:v007C*
+ ID_VENDOR_FROM_DATABASE=A & R Cambridge
+
+bluetooth:v007D*
+ ID_VENDOR_FROM_DATABASE=Seers Technology Co. Ltd.
+
+bluetooth:v007E*
+ ID_VENDOR_FROM_DATABASE=Sports Tracking Technologies Ltd.
+
+bluetooth:v007F*
+ ID_VENDOR_FROM_DATABASE=Autonet Mobile
+
+bluetooth:v0080*
+ ID_VENDOR_FROM_DATABASE=DeLorme Publishing Company, Inc.
+
+bluetooth:v0081*
+ ID_VENDOR_FROM_DATABASE=WuXi Vimicro
+
+bluetooth:v0082*
+ ID_VENDOR_FROM_DATABASE=Sennheiser Communications A/S
+
+bluetooth:v0083*
+ ID_VENDOR_FROM_DATABASE=TimeKeeping Systems, Inc.
+
+bluetooth:v0084*
+ ID_VENDOR_FROM_DATABASE=Ludus Helsinki Ltd.
+
+bluetooth:v0085*
+ ID_VENDOR_FROM_DATABASE=BlueRadios, Inc.
+
+bluetooth:v0086*
+ ID_VENDOR_FROM_DATABASE=equinux AG
+
+bluetooth:v0087*
+ ID_VENDOR_FROM_DATABASE=Garmin International, Inc.
+
+bluetooth:v0088*
+ ID_VENDOR_FROM_DATABASE=Ecotest
+
+bluetooth:v0089*
+ ID_VENDOR_FROM_DATABASE=GN ReSound A/S
+
+bluetooth:v008A*
+ ID_VENDOR_FROM_DATABASE=Jawbone
+
+bluetooth:v008B*
+ ID_VENDOR_FROM_DATABASE=Topcon Positioning Systems, LLC
+
+bluetooth:v008C*
+ ID_VENDOR_FROM_DATABASE=Qualcomm Labs, Inc.
+
+bluetooth:v008D*
+ ID_VENDOR_FROM_DATABASE=Zscan Software
+
+bluetooth:v008E*
+ ID_VENDOR_FROM_DATABASE=Quintic Corp.
+
+bluetooth:v008F*
+ ID_VENDOR_FROM_DATABASE=Stollmann E+V GmbH
+
+bluetooth:v0090*
+ ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd.
+
+bluetooth:v0091*
+ ID_VENDOR_FROM_DATABASE=Advanced PANMOBIL systems GmbH & Co. KG
+
+bluetooth:v0092*
+ ID_VENDOR_FROM_DATABASE=ThinkOptics, Inc.
+
+bluetooth:v0093*
+ ID_VENDOR_FROM_DATABASE=Universal Electronics, Inc.
+
+bluetooth:v0094*
+ ID_VENDOR_FROM_DATABASE=Airoha Technology Corp.
+
+bluetooth:v0095*
+ ID_VENDOR_FROM_DATABASE=NEC Lighting, Ltd.
+
+bluetooth:v0096*
+ ID_VENDOR_FROM_DATABASE=ODM Technology, Inc.
+
+bluetooth:v0097*
+ ID_VENDOR_FROM_DATABASE=Bluetrek Technologies Limited
+
+bluetooth:v0098*
+ ID_VENDOR_FROM_DATABASE=zero1.tv GmbH
+
+bluetooth:v0099*
+ ID_VENDOR_FROM_DATABASE=i.Tech Dynamic Global Distribution Ltd.
+
+bluetooth:v009A*
+ ID_VENDOR_FROM_DATABASE=Alpwise
+
+bluetooth:v009B*
+ ID_VENDOR_FROM_DATABASE=Jiangsu Toppower Automotive Electronics Co., Ltd.
+
+bluetooth:v009C*
+ ID_VENDOR_FROM_DATABASE=Colorfy, Inc.
+
+bluetooth:v009D*
+ ID_VENDOR_FROM_DATABASE=Geoforce Inc.
+
+bluetooth:v009E*
+ ID_VENDOR_FROM_DATABASE=Bose Corporation
+
+bluetooth:v009F*
+ ID_VENDOR_FROM_DATABASE=Suunto Oy
+
+bluetooth:v00A0*
+ ID_VENDOR_FROM_DATABASE=Kensington Computer Products Group
+
+bluetooth:v00A1*
+ ID_VENDOR_FROM_DATABASE=SR-Medizinelektronik
+
+bluetooth:v00A2*
+ ID_VENDOR_FROM_DATABASE=Vertu Corporation Limited
+
+bluetooth:v00A3*
+ ID_VENDOR_FROM_DATABASE=Meta Watch Ltd.
+
+bluetooth:v00A4*
+ ID_VENDOR_FROM_DATABASE=LINAK A/S
+
+bluetooth:v00A5*
+ ID_VENDOR_FROM_DATABASE=OTL Dynamics LLC
+
+bluetooth:v00A6*
+ ID_VENDOR_FROM_DATABASE=Panda Ocean Inc.
+
+bluetooth:v00A7*
+ ID_VENDOR_FROM_DATABASE=Visteon Corporation
+
+bluetooth:v00A8*
+ ID_VENDOR_FROM_DATABASE=ARP Devices Limited
+
+bluetooth:v00A9*
+ ID_VENDOR_FROM_DATABASE=Magneti Marelli S.p.A.
+
+bluetooth:v00AA*
+ ID_VENDOR_FROM_DATABASE=CAEN RFID srl
+
+bluetooth:v00AB*
+ ID_VENDOR_FROM_DATABASE=Ingenieur-Systemgruppe Zahn GmbH
+
+bluetooth:v00AC*
+ ID_VENDOR_FROM_DATABASE=Green Throttle Games
+
+bluetooth:v00AD*
+ ID_VENDOR_FROM_DATABASE=Peter Systemtechnik GmbH
+
+bluetooth:v00AE*
+ ID_VENDOR_FROM_DATABASE=Omegawave Oy
+
+bluetooth:v00AF*
+ ID_VENDOR_FROM_DATABASE=Cinetix
+
+bluetooth:v00B0*
+ ID_VENDOR_FROM_DATABASE=Passif Semiconductor Corp
+
+bluetooth:v00B1*
+ ID_VENDOR_FROM_DATABASE=Saris Cycling Group, Inc
+
+bluetooth:v00B2*
+ ID_VENDOR_FROM_DATABASE=Bekey A/S
diff --git a/hwdb/20-pci-classes.hwdb b/hwdb/20-pci-classes.hwdb
new file mode 100644 (file)
index 0000000..fd1d5d0
--- /dev/null
@@ -0,0 +1,531 @@
+# This file is part of systemd.
+#
+# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids
+
+pci:v*d*sv*sd*bc00*
+ ID_PCI_CLASS_FROM_DATABASE=Unclassified device
+
+pci:v*d*sv*sd*bc00sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Non-VGA unclassified device
+
+pci:v*d*sv*sd*bc00sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=VGA compatible unclassified device
+
+pci:v*d*sv*sd*bc01*
+ ID_PCI_CLASS_FROM_DATABASE=Mass storage controller
+
+pci:v*d*sv*sd*bc01sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=SCSI storage controller
+
+pci:v*d*sv*sd*bc01sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=IDE interface
+
+pci:v*d*sv*sd*bc01sc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Floppy disk controller
+
+pci:v*d*sv*sd*bc01sc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=IPI bus controller
+
+pci:v*d*sv*sd*bc01sc04*
+ ID_PCI_SUBCLASS_FROM_DATABASE=RAID bus controller
+
+pci:v*d*sv*sd*bc01sc05*
+ ID_PCI_SUBCLASS_FROM_DATABASE=ATA controller
+
+pci:v*d*sv*sd*bc01sc05i20*
+ ID_PCI_INTERFACE_FROM_DATABASE=ADMA single stepping
+
+pci:v*d*sv*sd*bc01sc05i30*
+ ID_PCI_INTERFACE_FROM_DATABASE=ADMA continuous operation
+
+pci:v*d*sv*sd*bc01sc06*
+ ID_PCI_SUBCLASS_FROM_DATABASE=SATA controller
+
+pci:v*d*sv*sd*bc01sc06i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=Vendor specific
+
+pci:v*d*sv*sd*bc01sc06i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=AHCI 1.0
+
+pci:v*d*sv*sd*bc01sc07*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Serial Attached SCSI controller
+
+pci:v*d*sv*sd*bc01sc08*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Non-Volatile memory controller
+
+pci:v*d*sv*sd*bc01sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Mass storage controller
+
+pci:v*d*sv*sd*bc02*
+ ID_PCI_CLASS_FROM_DATABASE=Network controller
+
+pci:v*d*sv*sd*bc02sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Ethernet controller
+
+pci:v*d*sv*sd*bc02sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Token ring network controller
+
+pci:v*d*sv*sd*bc02sc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=FDDI network controller
+
+pci:v*d*sv*sd*bc02sc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=ATM network controller
+
+pci:v*d*sv*sd*bc02sc04*
+ ID_PCI_SUBCLASS_FROM_DATABASE=ISDN controller
+
+pci:v*d*sv*sd*bc02sc05*
+ ID_PCI_SUBCLASS_FROM_DATABASE=WorldFip controller
+
+pci:v*d*sv*sd*bc02sc06*
+ ID_PCI_SUBCLASS_FROM_DATABASE=PICMG controller
+
+pci:v*d*sv*sd*bc02sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Network controller
+
+pci:v*d*sv*sd*bc03*
+ ID_PCI_CLASS_FROM_DATABASE=Display controller
+
+pci:v*d*sv*sd*bc03sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=VGA compatible controller
+
+pci:v*d*sv*sd*bc03sc00i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=VGA controller
+
+pci:v*d*sv*sd*bc03sc00i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=8514 controller
+
+pci:v*d*sv*sd*bc03sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=XGA compatible controller
+
+pci:v*d*sv*sd*bc03sc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=3D controller
+
+pci:v*d*sv*sd*bc03sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Display controller
+
+pci:v*d*sv*sd*bc04*
+ ID_PCI_CLASS_FROM_DATABASE=Multimedia controller
+
+pci:v*d*sv*sd*bc04sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Multimedia video controller
+
+pci:v*d*sv*sd*bc04sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Multimedia audio controller
+
+pci:v*d*sv*sd*bc04sc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Computer telephony device
+
+pci:v*d*sv*sd*bc04sc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Audio device
+
+pci:v*d*sv*sd*bc04sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Multimedia controller
+
+pci:v*d*sv*sd*bc05*
+ ID_PCI_CLASS_FROM_DATABASE=Memory controller
+
+pci:v*d*sv*sd*bc05sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=RAM memory
+
+pci:v*d*sv*sd*bc05sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=FLASH memory
+
+pci:v*d*sv*sd*bc05sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Memory controller
+
+pci:v*d*sv*sd*bc06*
+ ID_PCI_CLASS_FROM_DATABASE=Bridge
+
+pci:v*d*sv*sd*bc06sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Host bridge
+
+pci:v*d*sv*sd*bc06sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=ISA bridge
+
+pci:v*d*sv*sd*bc06sc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=EISA bridge
+
+pci:v*d*sv*sd*bc06sc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=MicroChannel bridge
+
+pci:v*d*sv*sd*bc06sc04*
+ ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge
+
+pci:v*d*sv*sd*bc06sc04i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=Normal decode
+
+pci:v*d*sv*sd*bc06sc04i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=Subtractive decode
+
+pci:v*d*sv*sd*bc06sc05*
+ ID_PCI_SUBCLASS_FROM_DATABASE=PCMCIA bridge
+
+pci:v*d*sv*sd*bc06sc06*
+ ID_PCI_SUBCLASS_FROM_DATABASE=NuBus bridge
+
+pci:v*d*sv*sd*bc06sc07*
+ ID_PCI_SUBCLASS_FROM_DATABASE=CardBus bridge
+
+pci:v*d*sv*sd*bc06sc08*
+ ID_PCI_SUBCLASS_FROM_DATABASE=RACEway bridge
+
+pci:v*d*sv*sd*bc06sc08i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=Transparent mode
+
+pci:v*d*sv*sd*bc06sc08i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=Endpoint mode
+
+pci:v*d*sv*sd*bc06sc09*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Semi-transparent PCI-to-PCI bridge
+
+pci:v*d*sv*sd*bc06sc09i40*
+ ID_PCI_INTERFACE_FROM_DATABASE=Primary bus towards host CPU
+
+pci:v*d*sv*sd*bc06sc09i80*
+ ID_PCI_INTERFACE_FROM_DATABASE=Secondary bus towards host CPU
+
+pci:v*d*sv*sd*bc06sc0A*
+ ID_PCI_SUBCLASS_FROM_DATABASE=InfiniBand to PCI host bridge
+
+pci:v*d*sv*sd*bc06sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Bridge
+
+pci:v*d*sv*sd*bc07*
+ ID_PCI_CLASS_FROM_DATABASE=Communication controller
+
+pci:v*d*sv*sd*bc07sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Serial controller
+
+pci:v*d*sv*sd*bc07sc00i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=8250
+
+pci:v*d*sv*sd*bc07sc00i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=16450
+
+pci:v*d*sv*sd*bc07sc00i02*
+ ID_PCI_INTERFACE_FROM_DATABASE=16550
+
+pci:v*d*sv*sd*bc07sc00i03*
+ ID_PCI_INTERFACE_FROM_DATABASE=16650
+
+pci:v*d*sv*sd*bc07sc00i04*
+ ID_PCI_INTERFACE_FROM_DATABASE=16750
+
+pci:v*d*sv*sd*bc07sc00i05*
+ ID_PCI_INTERFACE_FROM_DATABASE=16850
+
+pci:v*d*sv*sd*bc07sc00i06*
+ ID_PCI_INTERFACE_FROM_DATABASE=16950
+
+pci:v*d*sv*sd*bc07sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Parallel controller
+
+pci:v*d*sv*sd*bc07sc01i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=SPP
+
+pci:v*d*sv*sd*bc07sc01i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=BiDir
+
+pci:v*d*sv*sd*bc07sc01i02*
+ ID_PCI_INTERFACE_FROM_DATABASE=ECP
+
+pci:v*d*sv*sd*bc07sc01i03*
+ ID_PCI_INTERFACE_FROM_DATABASE=IEEE1284
+
+pci:v*d*sv*sd*bc07sc01iFE*
+ ID_PCI_INTERFACE_FROM_DATABASE=IEEE1284 Target
+
+pci:v*d*sv*sd*bc07sc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Multiport serial controller
+
+pci:v*d*sv*sd*bc07sc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Modem
+
+pci:v*d*sv*sd*bc07sc03i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=Generic
+
+pci:v*d*sv*sd*bc07sc03i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=Hayes/16450
+
+pci:v*d*sv*sd*bc07sc03i02*
+ ID_PCI_INTERFACE_FROM_DATABASE=Hayes/16550
+
+pci:v*d*sv*sd*bc07sc03i03*
+ ID_PCI_INTERFACE_FROM_DATABASE=Hayes/16650
+
+pci:v*d*sv*sd*bc07sc03i04*
+ ID_PCI_INTERFACE_FROM_DATABASE=Hayes/16750
+
+pci:v*d*sv*sd*bc07sc04*
+ ID_PCI_SUBCLASS_FROM_DATABASE=GPIB controller
+
+pci:v*d*sv*sd*bc07sc05*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Smard Card controller
+
+pci:v*d*sv*sd*bc07sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Communication controller
+
+pci:v*d*sv*sd*bc08*
+ ID_PCI_CLASS_FROM_DATABASE=Generic system peripheral
+
+pci:v*d*sv*sd*bc08sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=PIC
+
+pci:v*d*sv*sd*bc08sc00i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=8259
+
+pci:v*d*sv*sd*bc08sc00i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=ISA PIC
+
+pci:v*d*sv*sd*bc08sc00i02*
+ ID_PCI_INTERFACE_FROM_DATABASE=EISA PIC
+
+pci:v*d*sv*sd*bc08sc00i10*
+ ID_PCI_INTERFACE_FROM_DATABASE=IO-APIC
+
+pci:v*d*sv*sd*bc08sc00i20*
+ ID_PCI_INTERFACE_FROM_DATABASE=IO(X)-APIC
+
+pci:v*d*sv*sd*bc08sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=DMA controller
+
+pci:v*d*sv*sd*bc08sc01i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=8237
+
+pci:v*d*sv*sd*bc08sc01i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=ISA DMA
+
+pci:v*d*sv*sd*bc08sc01i02*
+ ID_PCI_INTERFACE_FROM_DATABASE=EISA DMA
+
+pci:v*d*sv*sd*bc08sc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Timer
+
+pci:v*d*sv*sd*bc08sc02i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=8254
+
+pci:v*d*sv*sd*bc08sc02i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=ISA Timer
+
+pci:v*d*sv*sd*bc08sc02i02*
+ ID_PCI_INTERFACE_FROM_DATABASE=EISA Timers
+
+pci:v*d*sv*sd*bc08sc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=RTC
+
+pci:v*d*sv*sd*bc08sc03i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=Generic
+
+pci:v*d*sv*sd*bc08sc03i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=ISA RTC
+
+pci:v*d*sv*sd*bc08sc04*
+ ID_PCI_SUBCLASS_FROM_DATABASE=PCI Hot-plug controller
+
+pci:v*d*sv*sd*bc08sc05*
+ ID_PCI_SUBCLASS_FROM_DATABASE=SD Host controller
+
+pci:v*d*sv*sd*bc08sc06*
+ ID_PCI_SUBCLASS_FROM_DATABASE=IOMMU
+
+pci:v*d*sv*sd*bc08sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=System peripheral
+
+pci:v*d*sv*sd*bc09*
+ ID_PCI_CLASS_FROM_DATABASE=Input device controller
+
+pci:v*d*sv*sd*bc09sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Keyboard controller
+
+pci:v*d*sv*sd*bc09sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Digitizer Pen
+
+pci:v*d*sv*sd*bc09sc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Mouse controller
+
+pci:v*d*sv*sd*bc09sc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Scanner controller
+
+pci:v*d*sv*sd*bc09sc04*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Gameport controller
+
+pci:v*d*sv*sd*bc09sc04i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=Generic
+
+pci:v*d*sv*sd*bc09sc04i10*
+ ID_PCI_INTERFACE_FROM_DATABASE=Extended
+
+pci:v*d*sv*sd*bc09sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Input device controller
+
+pci:v*d*sv*sd*bc0A*
+ ID_PCI_CLASS_FROM_DATABASE=Docking station
+
+pci:v*d*sv*sd*bc0Asc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Generic Docking Station
+
+pci:v*d*sv*sd*bc0Asc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Docking Station
+
+pci:v*d*sv*sd*bc0B*
+ ID_PCI_CLASS_FROM_DATABASE=Processor
+
+pci:v*d*sv*sd*bc0Bsc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=386
+
+pci:v*d*sv*sd*bc0Bsc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=486
+
+pci:v*d*sv*sd*bc0Bsc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Pentium
+
+pci:v*d*sv*sd*bc0Bsc10*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Alpha
+
+pci:v*d*sv*sd*bc0Bsc20*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Power PC
+
+pci:v*d*sv*sd*bc0Bsc30*
+ ID_PCI_SUBCLASS_FROM_DATABASE=MIPS
+
+pci:v*d*sv*sd*bc0Bsc40*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Co-processor
+
+pci:v*d*sv*sd*bc0C*
+ ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
+
+pci:v*d*sv*sd*bc0Csc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=FireWire (IEEE 1394)
+
+pci:v*d*sv*sd*bc0Csc00i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=Generic
+
+pci:v*d*sv*sd*bc0Csc00i10*
+ ID_PCI_INTERFACE_FROM_DATABASE=OHCI
+
+pci:v*d*sv*sd*bc0Csc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=ACCESS Bus
+
+pci:v*d*sv*sd*bc0Csc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=SSA
+
+pci:v*d*sv*sd*bc0Csc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
+
+pci:v*d*sv*sd*bc0Csc03i00*
+ ID_PCI_INTERFACE_FROM_DATABASE=UHCI
+
+pci:v*d*sv*sd*bc0Csc03i10*
+ ID_PCI_INTERFACE_FROM_DATABASE=OHCI
+
+pci:v*d*sv*sd*bc0Csc03i20*
+ ID_PCI_INTERFACE_FROM_DATABASE=EHCI
+
+pci:v*d*sv*sd*bc0Csc03i30*
+ ID_PCI_INTERFACE_FROM_DATABASE=XHCI
+
+pci:v*d*sv*sd*bc0Csc03i80*
+ ID_PCI_INTERFACE_FROM_DATABASE=Unspecified
+
+pci:v*d*sv*sd*bc0Csc03iFE*
+ ID_PCI_INTERFACE_FROM_DATABASE=USB Device
+
+pci:v*d*sv*sd*bc0Csc04*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Fibre Channel
+
+pci:v*d*sv*sd*bc0Csc05*
+ ID_PCI_SUBCLASS_FROM_DATABASE=SMBus
+
+pci:v*d*sv*sd*bc0Csc06*
+ ID_PCI_SUBCLASS_FROM_DATABASE=InfiniBand
+
+pci:v*d*sv*sd*bc0Csc07*
+ ID_PCI_SUBCLASS_FROM_DATABASE=IPMI SMIC interface
+
+pci:v*d*sv*sd*bc0Csc08*
+ ID_PCI_SUBCLASS_FROM_DATABASE=SERCOS interface
+
+pci:v*d*sv*sd*bc0Csc09*
+ ID_PCI_SUBCLASS_FROM_DATABASE=CANBUS
+
+pci:v*d*sv*sd*bc0D*
+ ID_PCI_CLASS_FROM_DATABASE=Wireless controller
+
+pci:v*d*sv*sd*bc0Dsc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=IRDA controller
+
+pci:v*d*sv*sd*bc0Dsc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Consumer IR controller
+
+pci:v*d*sv*sd*bc0Dsc10*
+ ID_PCI_SUBCLASS_FROM_DATABASE=RF controller
+
+pci:v*d*sv*sd*bc0Dsc11*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Bluetooth
+
+pci:v*d*sv*sd*bc0Dsc12*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Broadband
+
+pci:v*d*sv*sd*bc0Dsc20*
+ ID_PCI_SUBCLASS_FROM_DATABASE=802.1a controller
+
+pci:v*d*sv*sd*bc0Dsc21*
+ ID_PCI_SUBCLASS_FROM_DATABASE=802.1b controller
+
+pci:v*d*sv*sd*bc0Dsc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Wireless controller
+
+pci:v*d*sv*sd*bc0E*
+ ID_PCI_CLASS_FROM_DATABASE=Intelligent controller
+
+pci:v*d*sv*sd*bc0Esc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=I2O
+
+pci:v*d*sv*sd*bc0F*
+ ID_PCI_CLASS_FROM_DATABASE=Satellite communications controller
+
+pci:v*d*sv*sd*bc0Fsc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Satellite TV controller
+
+pci:v*d*sv*sd*bc0Fsc02*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Satellite audio communication controller
+
+pci:v*d*sv*sd*bc0Fsc03*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Satellite voice communication controller
+
+pci:v*d*sv*sd*bc0Fsc04*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Satellite data communication controller
+
+pci:v*d*sv*sd*bc10*
+ ID_PCI_CLASS_FROM_DATABASE=Encryption controller
+
+pci:v*d*sv*sd*bc10sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Network and computing encryption device
+
+pci:v*d*sv*sd*bc10sc10*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Entertainment encryption device
+
+pci:v*d*sv*sd*bc10sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Encryption controller
+
+pci:v*d*sv*sd*bc11*
+ ID_PCI_CLASS_FROM_DATABASE=Signal processing controller
+
+pci:v*d*sv*sd*bc11sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=DPIO module
+
+pci:v*d*sv*sd*bc11sc01*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Performance counters
+
+pci:v*d*sv*sd*bc11sc10*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Communication synchronizer
+
+pci:v*d*sv*sd*bc11sc20*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Signal processing management
+
+pci:v*d*sv*sd*bc11sc80*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Signal processing controller
+
+pci:v*d*sv*sd*bcFF*
+ ID_PCI_CLASS_FROM_DATABASE=Unassigned class
diff --git a/hwdb/20-pci-vendor-product.hwdb b/hwdb/20-pci-vendor-product.hwdb
new file mode 100644 (file)
index 0000000..2e87004
--- /dev/null
@@ -0,0 +1,63993 @@
+# This file is part of systemd.
+#
+# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids
+
+pci:v00000010*
+ ID_VENDOR_FROM_DATABASE=Allied Telesis, Inc
+
+pci:v00000010d00008139*
+ ID_PRODUCT_FROM_DATABASE=AT-2500TX V3 Ethernet
+
+pci:v0000001A*
+ ID_VENDOR_FROM_DATABASE=Ascend Communications, Inc.
+
+pci:v0000001C*
+ ID_VENDOR_FROM_DATABASE=PEAK-System Technik GmbH
+
+pci:v0000001Cd00000001*
+ ID_PRODUCT_FROM_DATABASE=PCAN-PCI CAN-Bus controller
+
+pci:v0000001Cd00000001sv0000001Csd00000004*
+ ID_PRODUCT_FROM_DATABASE=2 Channel CAN Bus SJC1000
+
+pci:v0000001Cd00000001sv0000001Csd00000005*
+ ID_PRODUCT_FROM_DATABASE=2 Channel CAN Bus SJC1000 (Optically Isolated)
+
+pci:v00000033*
+ ID_VENDOR_FROM_DATABASE=Paradyne corp.
+
+pci:v0000003D*
+ ID_VENDOR_FROM_DATABASE=Lockheed Martin-Marietta Corp
+
+pci:v00000059*
+ ID_VENDOR_FROM_DATABASE=Tiger Jet Network Inc. (Wrong ID)
+
+pci:v00000070*
+ ID_VENDOR_FROM_DATABASE=Hauppauge computer works Inc.
+
+pci:v00000070d00000003*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-250
+
+pci:v00000070d00000009*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-150
+
+pci:v00000070d00000801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-150
+
+pci:v00000070d00000807*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-150
+
+pci:v00000070d00004000*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-350
+
+pci:v00000070d00004001*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-250 (v1)
+
+pci:v00000070d00004009*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-250
+
+pci:v00000070d00004800*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-350
+
+pci:v00000070d00004801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-250 MCE
+
+pci:v00000070d00004803*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-250
+
+pci:v00000070d00007444*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-1600
+
+pci:v00000070d00007801*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-1800 MCE
+
+pci:v00000070d00008003*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-150
+
+pci:v00000070d00008801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-150
+
+pci:v00000070d0000C108*
+ ID_PRODUCT_FROM_DATABASE=WinTV-HVR-4400-HD model 1278
+
+pci:v00000070d0000C801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-150
+
+pci:v00000070d0000E807*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-500 MCE (1st tuner)
+
+pci:v00000070d0000E817*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-500 MCE (2nd tuner)
+
+pci:v00000071*
+ ID_VENDOR_FROM_DATABASE=Nebula Electronics Ltd.
+
+pci:v00000095*
+ ID_VENDOR_FROM_DATABASE=Silicon Image, Inc. (Wrong ID)
+
+pci:v00000095d00000680*
+ ID_PRODUCT_FROM_DATABASE=Ultra ATA/133 IDE RAID CONTROLLER CARD
+
+pci:v000000A7*
+ ID_VENDOR_FROM_DATABASE=Teles AG (Wrong ID)
+
+pci:v000000F5*
+ ID_VENDOR_FROM_DATABASE=BFG Technologies, Inc.
+
+pci:v00000100*
+ ID_VENDOR_FROM_DATABASE=Ncipher Corp Ltd
+
+pci:v00000123*
+ ID_VENDOR_FROM_DATABASE=General Dynamics
+
+pci:v0000018A*
+ ID_VENDOR_FROM_DATABASE=LevelOne
+
+pci:v0000018Ad00000106*
+ ID_PRODUCT_FROM_DATABASE=FPC-0106TX misprogrammed [RTL81xx]
+
+pci:v0000021B*
+ ID_VENDOR_FROM_DATABASE=Compaq Computer Corporation
+
+pci:v0000021Bd00008139*
+ ID_PRODUCT_FROM_DATABASE=HNE-300 (RealTek RTL8139c) [iPaq Networking]
+
+pci:v00000270*
+ ID_VENDOR_FROM_DATABASE=Hauppauge computer works Inc. (Wrong ID)
+
+pci:v00000291*
+ ID_VENDOR_FROM_DATABASE=Davicom Semiconductor, Inc.
+
+pci:v00000291d00008212*
+ ID_PRODUCT_FROM_DATABASE=DM9102A(DM9102AE, SM9102AF) Ethernet 100/10 MBit(Rev 40)
+
+pci:v000002AC*
+ ID_VENDOR_FROM_DATABASE=SpeedStream
+
+pci:v000002ACd00001012*
+ ID_PRODUCT_FROM_DATABASE=1012 PCMCIA 10/100 Ethernet Card [RTL81xx]
+
+pci:v000002E0*
+ ID_VENDOR_FROM_DATABASE=XFX Pine Group Inc
+
+pci:v00000303*
+ ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company (Wrong ID)
+
+pci:v00000308*
+ ID_VENDOR_FROM_DATABASE=ZyXEL Communications Corporation
+
+pci:v00000315*
+ ID_VENDOR_FROM_DATABASE=SK-Electronics Co., Ltd.
+
+pci:v00000357*
+ ID_VENDOR_FROM_DATABASE=TTTech AG
+
+pci:v00000357d0000000A*
+ ID_PRODUCT_FROM_DATABASE=TTP-Monitoring Card V2.0
+
+pci:v0000036F*
+ ID_VENDOR_FROM_DATABASE=Trigem Computer Inc.
+
+pci:v00000432*
+ ID_VENDOR_FROM_DATABASE=SCM Microsystems, Inc.
+
+pci:v00000432d00000001*
+ ID_PRODUCT_FROM_DATABASE=Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet]
+
+pci:v00000675*
+ ID_VENDOR_FROM_DATABASE=Dynalink
+
+pci:v00000675d00001700*
+ ID_PRODUCT_FROM_DATABASE=IS64PH ISDN Adapter
+
+pci:v00000675d00001702*
+ ID_PRODUCT_FROM_DATABASE=IS64PH ISDN Adapter
+
+pci:v00000675d00001703*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+
+pci:v00000675d00001704*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C)
+
+pci:v00000721*
+ ID_VENDOR_FROM_DATABASE=Sapphire, Inc.
+
+pci:v00000777*
+ ID_VENDOR_FROM_DATABASE=Ubiquiti Networks, Inc.
+
+pci:v00000777d00003005*
+ ID_PRODUCT_FROM_DATABASE=XtremeRange5
+
+pci:v00000795*
+ ID_VENDOR_FROM_DATABASE=Wired Inc.
+
+pci:v00000795d00006663*
+ ID_PRODUCT_FROM_DATABASE=Butane II (MPEG2 encoder board)
+
+pci:v00000795d00006666*
+ ID_PRODUCT_FROM_DATABASE=MediaPress (MPEG2 encoder board)
+
+pci:v000007CA*
+ ID_VENDOR_FROM_DATABASE=AVerMedia Technologies Inc.
+
+pci:v000007CAd0000534A*
+ ID_PRODUCT_FROM_DATABASE=Slim mobile Express DVB-T (Fujitsu)
+
+pci:v000007CAd0000A301*
+ ID_PRODUCT_FROM_DATABASE=AVerTV 301
+
+pci:v000007CAd0000B808*
+ ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T Volar (USB 2.0)
+
+pci:v000007D0*
+ ID_VENDOR_FROM_DATABASE=ITT Geospatial Systems
+
+pci:v000007D1*
+ ID_VENDOR_FROM_DATABASE=D-Link System Inc
+
+pci:v000007E2*
+ ID_VENDOR_FROM_DATABASE=ELMEG Communication Systems GmbH
+
+pci:v00000842*
+ ID_VENDOR_FROM_DATABASE=NPG, Personal Grand Technology
+
+pci:v000008E6*
+ ID_VENDOR_FROM_DATABASE=Gemalto NV
+
+pci:v000008FF*
+ ID_VENDOR_FROM_DATABASE=AuthenTec
+
+pci:v000008FFd0000AFE4*
+ ID_PRODUCT_FROM_DATABASE=[Anchor] AF-S2 FingerLoc Sensor Module
+
+pci:v00000925*
+ ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc. (Wrong ID)
+
+pci:v00000925d00001234*
+ ID_PRODUCT_FROM_DATABASE=VT82C686/A/B USB Controller
+
+pci:v0000093A*
+ ID_VENDOR_FROM_DATABASE=PixArt Imaging Inc.
+
+pci:v0000093Ad0000010E*
+ ID_PRODUCT_FROM_DATABASE=Innovage Mini Digital Camera
+
+pci:v0000093Ad0000010F*
+ ID_PRODUCT_FROM_DATABASE=SDC-300 Webcam
+
+pci:v0000093Ad0000020F*
+ ID_PRODUCT_FROM_DATABASE=Digital Photo Viewer
+
+pci:v0000093Ad00002468*
+ ID_PRODUCT_FROM_DATABASE=CIF Single Chip
+
+pci:v0000093Ad00002600*
+ ID_PRODUCT_FROM_DATABASE=PAC7311
+
+pci:v0000093Ad00002603*
+ ID_PRODUCT_FROM_DATABASE=Philips Webcam SPC500NC
+
+pci:v0000093Ad00002608*
+ ID_PRODUCT_FROM_DATABASE=Maxell MaxCam RotaWeb
+
+pci:v0000093Ad00002620*
+ ID_PRODUCT_FROM_DATABASE=C3 Tech Mod. 153
+
+pci:v000009C1*
+ ID_VENDOR_FROM_DATABASE=Arris
+
+pci:v000009C1d00000704*
+ ID_PRODUCT_FROM_DATABASE=CM 200E Cable Modem
+
+pci:v00000A89*
+ ID_VENDOR_FROM_DATABASE=BREA Technologies Inc
+
+pci:v00000B0B*
+ ID_VENDOR_FROM_DATABASE=Rhino Equipment Corp.
+
+pci:v00000B0Bd00000105*
+ ID_PRODUCT_FROM_DATABASE=Rhino R1T1
+
+pci:v00000B0Bd00000205*
+ ID_PRODUCT_FROM_DATABASE=Rhino R4FXO
+
+pci:v00000B0Bd00000206*
+ ID_PRODUCT_FROM_DATABASE=RCB4FXO 4-channel FXO analog telphony card
+
+pci:v00000B0Bd00000305*
+ ID_PRODUCT_FROM_DATABASE=Rhino R4T1
+
+pci:v00000B0Bd00000405*
+ ID_PRODUCT_FROM_DATABASE=Rhino R8FXX
+
+pci:v00000B0Bd00000406*
+ ID_PRODUCT_FROM_DATABASE=RCB8FXX 8-channel modular analog telphony card
+
+pci:v00000B0Bd00000505*
+ ID_PRODUCT_FROM_DATABASE=Rhino R24FXX
+
+pci:v00000B0Bd00000506*
+ ID_PRODUCT_FROM_DATABASE=RCB24FXS 24-Channel FXS analog telphony card
+
+pci:v00000B0Bd00000605*
+ ID_PRODUCT_FROM_DATABASE=Rhino R2T1
+
+pci:v00000B0Bd00000705*
+ ID_PRODUCT_FROM_DATABASE=Rhino R24FXS
+
+pci:v00000B0Bd00000706*
+ ID_PRODUCT_FROM_DATABASE=RCB24FXO 24-Channel FXO analog telphony card
+
+pci:v00000B0Bd00000905*
+ ID_PRODUCT_FROM_DATABASE=R1T3 Single T3 Digital Telephony Card
+
+pci:v00000B0Bd00000906*
+ ID_PRODUCT_FROM_DATABASE=RCB24FXX 24-channel modular analog telphony card
+
+pci:v00000B0Bd00000A06*
+ ID_PRODUCT_FROM_DATABASE=RCB672FXX 672-channel modular analog telphony card
+
+pci:v00000B3D*
+ ID_VENDOR_FROM_DATABASE=Brontes Technologies
+
+pci:v00000CCD*
+ ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH
+
+pci:v00000CCDd00000038*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T^2 DVB-T Receiver
+
+pci:v00000E11*
+ ID_VENDOR_FROM_DATABASE=Compaq Computer Corporation
+
+pci:v00000E11d00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI to EISA Bridge
+
+pci:v00000E11d00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI to ISA Bridge
+
+pci:v00000E11d00000046*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 64xx
+
+pci:v00000E11d00000046sv00000E11sd00004091*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 6i
+
+pci:v00000E11d00000046sv00000E11sd0000409A*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 641
+
+pci:v00000E11d00000046sv00000E11sd0000409B*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 642
+
+pci:v00000E11d00000046sv00000E11sd0000409C*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 6400
+
+pci:v00000E11d00000046sv00000E11sd0000409D*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 6400 EM
+
+pci:v00000E11d00000049*
+ ID_PRODUCT_FROM_DATABASE=NC7132 Gigabit Upgrade Module
+
+pci:v00000E11d0000004A*
+ ID_PRODUCT_FROM_DATABASE=NC6136 Gigabit Server Adapter
+
+pci:v00000E11d0000005A*
+ ID_PRODUCT_FROM_DATABASE=Remote Insight II board - Lights-Out
+
+pci:v00000E11d0000007C*
+ ID_PRODUCT_FROM_DATABASE=NC7770 1000BaseTX
+
+pci:v00000E11d0000007D*
+ ID_PRODUCT_FROM_DATABASE=NC6770 1000BaseTX
+
+pci:v00000E11d00000085*
+ ID_PRODUCT_FROM_DATABASE=NC7780 1000BaseTX
+
+pci:v00000E11d000000B1*
+ ID_PRODUCT_FROM_DATABASE=Remote Insight II board - PCI device
+
+pci:v00000E11d000000BB*
+ ID_PRODUCT_FROM_DATABASE=NC7760
+
+pci:v00000E11d000000CA*
+ ID_PRODUCT_FROM_DATABASE=NC7771
+
+pci:v00000E11d000000CB*
+ ID_PRODUCT_FROM_DATABASE=NC7781
+
+pci:v00000E11d000000CF*
+ ID_PRODUCT_FROM_DATABASE=NC7772
+
+pci:v00000E11d000000D0*
+ ID_PRODUCT_FROM_DATABASE=NC7782
+
+pci:v00000E11d000000D1*
+ ID_PRODUCT_FROM_DATABASE=NC7783
+
+pci:v00000E11d000000E3*
+ ID_PRODUCT_FROM_DATABASE=NC7761
+
+pci:v00000E11d00000508*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 4/16 Token Ring
+
+pci:v00000E11d00001000*
+ ID_PRODUCT_FROM_DATABASE=Triflex/Pentium Bridge, Model 1000
+
+pci:v00000E11d00002000*
+ ID_PRODUCT_FROM_DATABASE=Triflex/Pentium Bridge, Model 2000
+
+pci:v00000E11d00003032*
+ ID_PRODUCT_FROM_DATABASE=QVision 1280/p
+
+pci:v00000E11d00003033*
+ ID_PRODUCT_FROM_DATABASE=QVision 1280/p
+
+pci:v00000E11d00003034*
+ ID_PRODUCT_FROM_DATABASE=QVision 1280/p
+
+pci:v00000E11d00004000*
+ ID_PRODUCT_FROM_DATABASE=4000 [Triflex]
+
+pci:v00000E11d00004040*
+ ID_PRODUCT_FROM_DATABASE=Integrated Array
+
+pci:v00000E11d00004048*
+ ID_PRODUCT_FROM_DATABASE=Compaq Raid LC2
+
+pci:v00000E11d00004050*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 4200
+
+pci:v00000E11d00004051*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 4250ES
+
+pci:v00000E11d00004058*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 431
+
+pci:v00000E11d00004070*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 5300
+
+pci:v00000E11d00004080*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 5i
+
+pci:v00000E11d00004082*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 532
+
+pci:v00000E11d00004083*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 5312
+
+pci:v00000E11d00004091*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 6i
+
+pci:v00000E11d0000409A*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 641
+
+pci:v00000E11d0000409B*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 642
+
+pci:v00000E11d0000409C*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 6400
+
+pci:v00000E11d0000409D*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 6400 EM
+
+pci:v00000E11d00006010*
+ ID_PRODUCT_FROM_DATABASE=HotPlug PCI Bridge 6010
+
+pci:v00000E11d00007020*
+ ID_PRODUCT_FROM_DATABASE=USB Controller
+
+pci:v00000E11d0000A0EC*
+ ID_PRODUCT_FROM_DATABASE=Fibre Channel Host Controller
+
+pci:v00000E11d0000A0F0*
+ ID_PRODUCT_FROM_DATABASE=Advanced System Management Controller
+
+pci:v00000E11d0000A0F0sv00000E11sd0000B0F3*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL360
+
+pci:v00000E11d0000A0F3*
+ ID_PRODUCT_FROM_DATABASE=Triflex PCI to ISA Bridge
+
+pci:v00000E11d0000A0F7*
+ ID_PRODUCT_FROM_DATABASE=PCI Hotplug Controller
+
+pci:v00000E11d0000A0F7sv00008086sd0000002A*
+ ID_PRODUCT_FROM_DATABASE=PCI Hotplug Controller A
+
+pci:v00000E11d0000A0F7sv00008086sd0000002B*
+ ID_PRODUCT_FROM_DATABASE=PCI Hotplug Controller B
+
+pci:v00000E11d0000A0F8*
+ ID_PRODUCT_FROM_DATABASE=ZFMicro Chipset USB
+
+pci:v00000E11d0000A0FC*
+ ID_PRODUCT_FROM_DATABASE=FibreChannel HBA Tachyon
+
+pci:v00000E11d0000AE10*
+ ID_PRODUCT_FROM_DATABASE=Smart-2/P RAID Controller
+
+pci:v00000E11d0000AE10sv00000E11sd00004030*
+ ID_PRODUCT_FROM_DATABASE=Smart-2/P Array Controller
+
+pci:v00000E11d0000AE10sv00000E11sd00004031*
+ ID_PRODUCT_FROM_DATABASE=Smart-2SL Array Controller
+
+pci:v00000E11d0000AE10sv00000E11sd00004032*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 3200 Controller
+
+pci:v00000E11d0000AE10sv00000E11sd00004033*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 3100ES Controller
+
+pci:v00000E11d0000AE10sv00000E11sd00004034*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 221 Controller
+
+pci:v00000E11d0000AE29*
+ ID_PRODUCT_FROM_DATABASE=MIS-L
+
+pci:v00000E11d0000AE2A*
+ ID_PRODUCT_FROM_DATABASE=MPC
+
+pci:v00000E11d0000AE2B*
+ ID_PRODUCT_FROM_DATABASE=MIS-E
+
+pci:v00000E11d0000AE31*
+ ID_PRODUCT_FROM_DATABASE=System Management Controller
+
+pci:v00000E11d0000AE32*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 10/100 TX PCI UTP
+
+pci:v00000E11d0000AE33*
+ ID_PRODUCT_FROM_DATABASE=Triflex Dual EIDE Controller
+
+pci:v00000E11d0000AE34*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 10 T PCI UTP
+
+pci:v00000E11d0000AE35*
+ ID_PRODUCT_FROM_DATABASE=Integrated NetFlex-3/P
+
+pci:v00000E11d0000AE40*
+ ID_PRODUCT_FROM_DATABASE=Netelligent Dual 10/100 TX PCI UTP
+
+pci:v00000E11d0000AE43*
+ ID_PRODUCT_FROM_DATABASE=Netelligent Integrated 10/100 TX UTP
+
+pci:v00000E11d0000AE69*
+ ID_PRODUCT_FROM_DATABASE=CETUS-L
+
+pci:v00000E11d0000AE6C*
+ ID_PRODUCT_FROM_DATABASE=Northstar
+
+pci:v00000E11d0000AE6D*
+ ID_PRODUCT_FROM_DATABASE=NorthStar CPU to PCI Bridge
+
+pci:v00000E11d0000B011*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 10/100 TX Embedded UTP
+
+pci:v00000E11d0000B012*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 10 T/2 PCI UTP/Coax
+
+pci:v00000E11d0000B01E*
+ ID_PRODUCT_FROM_DATABASE=NC3120 Fast Ethernet NIC
+
+pci:v00000E11d0000B01F*
+ ID_PRODUCT_FROM_DATABASE=NC3122 Fast Ethernet NIC
+
+pci:v00000E11d0000B02F*
+ ID_PRODUCT_FROM_DATABASE=NC1120 Ethernet NIC
+
+pci:v00000E11d0000B030*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 10/100 TX UTP
+
+pci:v00000E11d0000B04A*
+ ID_PRODUCT_FROM_DATABASE=10/100 TX PCI Intel WOL UTP Controller
+
+pci:v00000E11d0000B060*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 5300 Controller
+
+pci:v00000E11d0000B0C6*
+ ID_PRODUCT_FROM_DATABASE=NC3161 Fast Ethernet NIC
+
+pci:v00000E11d0000B0C7*
+ ID_PRODUCT_FROM_DATABASE=NC3160 Fast Ethernet NIC
+
+pci:v00000E11d0000B0D7*
+ ID_PRODUCT_FROM_DATABASE=NC3121 Fast Ethernet NIC
+
+pci:v00000E11d0000B0DD*
+ ID_PRODUCT_FROM_DATABASE=NC3131 Fast Ethernet NIC
+
+pci:v00000E11d0000B0DE*
+ ID_PRODUCT_FROM_DATABASE=NC3132 Fast Ethernet Module
+
+pci:v00000E11d0000B0DF*
+ ID_PRODUCT_FROM_DATABASE=NC6132 Gigabit Module
+
+pci:v00000E11d0000B0E0*
+ ID_PRODUCT_FROM_DATABASE=NC6133 Gigabit Module
+
+pci:v00000E11d0000B0E1*
+ ID_PRODUCT_FROM_DATABASE=NC3133 Fast Ethernet Module
+
+pci:v00000E11d0000B123*
+ ID_PRODUCT_FROM_DATABASE=NC6134 Gigabit NIC
+
+pci:v00000E11d0000B134*
+ ID_PRODUCT_FROM_DATABASE=NC3163 Fast Ethernet NIC
+
+pci:v00000E11d0000B13C*
+ ID_PRODUCT_FROM_DATABASE=NC3162 Fast Ethernet NIC
+
+pci:v00000E11d0000B144*
+ ID_PRODUCT_FROM_DATABASE=NC3123 Fast Ethernet NIC
+
+pci:v00000E11d0000B163*
+ ID_PRODUCT_FROM_DATABASE=NC3134 Fast Ethernet NIC
+
+pci:v00000E11d0000B164*
+ ID_PRODUCT_FROM_DATABASE=NC3165 Fast Ethernet Upgrade Module
+
+pci:v00000E11d0000B178*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 5i/532
+
+pci:v00000E11d0000B178sv00000E11sd00004080*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 5i
+
+pci:v00000E11d0000B178sv00000E11sd00004082*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 532
+
+pci:v00000E11d0000B178sv00000E11sd00004083*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 5312
+
+pci:v00000E11d0000B1A4*
+ ID_PRODUCT_FROM_DATABASE=NC7131 Gigabit Server Adapter
+
+pci:v00000E11d0000B200*
+ ID_PRODUCT_FROM_DATABASE=Memory Hot-Plug Controller
+
+pci:v00000E11d0000B203*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights Out Controller
+
+pci:v00000E11d0000B204*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights Out  Processor
+
+pci:v00000E11d0000C000*
+ ID_PRODUCT_FROM_DATABASE=Remote Insight Lights-Out Edition
+
+pci:v00000E11d0000F130*
+ ID_PRODUCT_FROM_DATABASE=NetFlex-3/P ThunderLAN 1.0
+
+pci:v00000E11d0000F150*
+ ID_PRODUCT_FROM_DATABASE=NetFlex-3/P ThunderLAN 2.3
+
+pci:v00000E21*
+ ID_VENDOR_FROM_DATABASE=Cowon Systems, Inc.
+
+pci:v00000E55*
+ ID_VENDOR_FROM_DATABASE=HaSoTec GmbH
+
+pci:v00000EAC*
+ ID_VENDOR_FROM_DATABASE=SHF Communication Technologies AG
+
+pci:v00000EACd00000008*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Powerlink Managing Node 01
+
+pci:v00000F62*
+ ID_VENDOR_FROM_DATABASE=Acrox Technologies Co., Ltd.
+
+pci:v00001000*
+ ID_VENDOR_FROM_DATABASE=LSI Logic / Symbios Logic
+
+pci:v00001000d00000001*
+ ID_PRODUCT_FROM_DATABASE=53c810
+
+pci:v00001000d00000001sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C810AE PCI to SCSI I/O Processor
+
+pci:v00001000d00000002*
+ ID_PRODUCT_FROM_DATABASE=53c820
+
+pci:v00001000d00000003*
+ ID_PRODUCT_FROM_DATABASE=53c825
+
+pci:v00001000d00000003sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide)
+
+pci:v00001000d00000004*
+ ID_PRODUCT_FROM_DATABASE=53c815
+
+pci:v00001000d00000005*
+ ID_PRODUCT_FROM_DATABASE=53c810AP
+
+pci:v00001000d00000006*
+ ID_PRODUCT_FROM_DATABASE=53c860
+
+pci:v00001000d00000006sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C860E PCI to Ultra SCSI I/O Processor
+
+pci:v00001000d0000000A*
+ ID_PRODUCT_FROM_DATABASE=53c1510
+
+pci:v00001000d0000000Asv00000E11sd0000B143*
+ ID_PRODUCT_FROM_DATABASE=Integrated Dual Channel Wide Ultra2 SCSI Controller
+
+pci:v00001000d0000000Asv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode)
+
+pci:v00001000d0000000B*
+ ID_PRODUCT_FROM_DATABASE=53C896/897
+
+pci:v00001000d0000000Bsv00000E11sd00006004*
+ ID_PRODUCT_FROM_DATABASE=EOB003 Series SCSI host adapter
+
+pci:v00001000d0000000Bsv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller
+
+pci:v00001000d0000000Bsv00001000sd00001010*
+ ID_PRODUCT_FROM_DATABASE=LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter
+
+pci:v00001000d0000000Bsv00001000sd00001020*
+ ID_PRODUCT_FROM_DATABASE=LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter
+
+pci:v00001000d0000000Bsv000013E9sd00001000*
+ ID_PRODUCT_FROM_DATABASE=6221L-4U (Dual U2W SCSI, dual 10/100TX, graphics)
+
+pci:v00001000d0000000C*
+ ID_PRODUCT_FROM_DATABASE=53c895
+
+pci:v00001000d0000000Csv00001000sd00001010*
+ ID_PRODUCT_FROM_DATABASE=LSI8951U PCI to Ultra2 SCSI host adapter
+
+pci:v00001000d0000000Csv00001000sd00001020*
+ ID_PRODUCT_FROM_DATABASE=LSI8952U PCI to Ultra2 SCSI host adapter
+
+pci:v00001000d0000000Csv00001DE1sd00003906*
+ ID_PRODUCT_FROM_DATABASE=DC-390U2B SCSI adapter
+
+pci:v00001000d0000000Csv00001DE1sd00003907*
+ ID_PRODUCT_FROM_DATABASE=DC-390U2W
+
+pci:v00001000d0000000D*
+ ID_PRODUCT_FROM_DATABASE=53c885
+
+pci:v00001000d0000000F*
+ ID_PRODUCT_FROM_DATABASE=53c875
+
+pci:v00001000d0000000Fsv00000E11sd00007004*
+ ID_PRODUCT_FROM_DATABASE=Embedded Ultra Wide SCSI Controller
+
+pci:v00001000d0000000Fsv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C876/E PCI to Dual Channel SCSI Controller
+
+pci:v00001000d0000000Fsv00001000sd00001010*
+ ID_PRODUCT_FROM_DATABASE=LSI22801 PCI to Dual Channel Ultra SCSI host adapter
+
+pci:v00001000d0000000Fsv00001000sd00001020*
+ ID_PRODUCT_FROM_DATABASE=LSI22802 PCI to Dual Channel Ultra SCSI host adapter
+
+pci:v00001000d0000000Fsv00001092sd00008760*
+ ID_PRODUCT_FROM_DATABASE=FirePort 40 Dual SCSI Controller
+
+pci:v00001000d0000000Fsv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer Wide Ultra SCSI
+
+pci:v00001000d0000000Fsv00001775sd000010D1*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer Ultra SCSI
+
+pci:v00001000d0000000Fsv00001DE1sd00003904*
+ ID_PRODUCT_FROM_DATABASE=DC390F/U Ultra Wide SCSI Adapter
+
+pci:v00001000d0000000Fsv00004C53sd00001000*
+ ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+
+pci:v00001000d0000000Fsv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v00001000d00000010*
+ ID_PRODUCT_FROM_DATABASE=53C1510
+
+pci:v00001000d00000010sv00000E11sd00004040*
+ ID_PRODUCT_FROM_DATABASE=Integrated Smart Array Controller
+
+pci:v00001000d00000010sv00000E11sd00004048*
+ ID_PRODUCT_FROM_DATABASE=RAID LC2 Controller
+
+pci:v00001000d00000010sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode)
+
+pci:v00001000d00000012*
+ ID_PRODUCT_FROM_DATABASE=53c895a
+
+pci:v00001000d00000012sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C895A PCI to Ultra2 SCSI Controller
+
+pci:v00001000d00000013*
+ ID_PRODUCT_FROM_DATABASE=53c875a
+
+pci:v00001000d00000013sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C875A PCI to Ultra SCSI Controller
+
+pci:v00001000d00000020*
+ ID_PRODUCT_FROM_DATABASE=53c1010 Ultra3 SCSI Adapter
+
+pci:v00001000d00000020sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller
+
+pci:v00001000d00000020sv0000107Bsd00001040*
+ ID_PRODUCT_FROM_DATABASE=Server Onboard 53C1010-33
+
+pci:v00001000d00000020sv00001DE1sd00001020*
+ ID_PRODUCT_FROM_DATABASE=DC-390U3W
+
+pci:v00001000d00000021*
+ ID_PRODUCT_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter
+
+pci:v00001000d00000021sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller
+
+pci:v00001000d00000021sv00001000sd00001010*
+ ID_PRODUCT_FROM_DATABASE=Asus TR-DLS onboard 53C1010-66
+
+pci:v00001000d00000021sv0000103Csd00001300*
+ ID_PRODUCT_FROM_DATABASE=Ultra160 SCSI [AB306A]
+
+pci:v00001000d00000021sv0000103Csd00001310*
+ ID_PRODUCT_FROM_DATABASE=Ultra160 SCSI [A9918A]
+
+pci:v00001000d00000021sv0000103Csd00001330*
+ ID_PRODUCT_FROM_DATABASE=Ultra160 SCSI [A7059A]
+
+pci:v00001000d00000021sv0000103Csd00001340*
+ ID_PRODUCT_FROM_DATABASE=Ultra160 SCSI [A7060A]
+
+pci:v00001000d00000021sv0000124Bsd00001070*
+ ID_PRODUCT_FROM_DATABASE=PMC-USCSI3
+
+pci:v00001000d00000021sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00001000d00000021sv00004C53sd00001300*
+ ID_PRODUCT_FROM_DATABASE=P017 mezzanine (32-bit PMC)
+
+pci:v00001000d00000021sv00004C53sd00001310*
+ ID_PRODUCT_FROM_DATABASE=P017 mezzanine (64-bit PMC)
+
+pci:v00001000d0000002F*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 2208 IOV [Thunderbolt]
+
+pci:v00001000d0000002Fsv00001028sd00001F3E*
+ ID_PRODUCT_FROM_DATABASE=SPERC 8
+
+pci:v00001000d00000030*
+ ID_PRODUCT_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI
+
+pci:v00001000d00000030sv00000E11sd000000DA*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML 350
+
+pci:v00001000d00000030sv00001028sd00000123*
+ ID_PRODUCT_FROM_DATABASE=LSI Logic 1020/1030
+
+pci:v00001000d00000030sv00001028sd0000014A*
+ ID_PRODUCT_FROM_DATABASE=LSI Logic 1020/1030
+
+pci:v00001000d00000030sv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4)
+
+pci:v00001000d00000030sv00001028sd00000183*
+ ID_PRODUCT_FROM_DATABASE=LSI Logic 1020/1030
+
+pci:v00001000d00000030sv00001028sd0000018A*
+ ID_PRODUCT_FROM_DATABASE=PERC 4/IM
+
+pci:v00001000d00000030sv00001028sd00001010*
+ ID_PRODUCT_FROM_DATABASE=LSI U320 SCSI Controller
+
+pci:v00001000d00000030sv0000103Csd000012C5*
+ ID_PRODUCT_FROM_DATABASE=Ultra320 SCSI [A7173A]
+
+pci:v00001000d00000030sv0000103Csd00001323*
+ ID_PRODUCT_FROM_DATABASE=Core I/O LAN/SCSI Combo [AB314A]
+
+pci:v00001000d00000030sv0000103Csd00003108*
+ ID_PRODUCT_FROM_DATABASE=Single Channel Ultra320 SCSI HBA G2
+
+pci:v00001000d00000030sv0000124Bsd00001170*
+ ID_PRODUCT_FROM_DATABASE=PMC-USCSI320
+
+pci:v00001000d00000030sv000015ADsd00001976*
+ ID_PRODUCT_FROM_DATABASE=LSI Logic Parallel SCSI Controller
+
+pci:v00001000d00000030sv00001734sd00001052*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY BX/RX/TX S2 series onboard SCSI(IME)
+
+pci:v00001000d00000031*
+ ID_PRODUCT_FROM_DATABASE=53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
+
+pci:v00001000d00000032*
+ ID_PRODUCT_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
+
+pci:v00001000d00000032sv00001000sd00001000*
+ ID_PRODUCT_FROM_DATABASE=LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller
+
+pci:v00001000d00000033*
+ ID_PRODUCT_FROM_DATABASE=1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
+
+pci:v00001000d00000040*
+ ID_PRODUCT_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
+
+pci:v00001000d00000040sv00001000sd00000033*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SCSI 320-2XR
+
+pci:v00001000d00000040sv00001000sd00000066*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SCSI 320-2XRWS
+
+pci:v00001000d00000041*
+ ID_PRODUCT_FROM_DATABASE=53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
+
+pci:v00001000d00000050*
+ ID_PRODUCT_FROM_DATABASE=SAS1064 PCI-X Fusion-MPT SAS
+
+pci:v00001000d00000050sv00001028sd00001F04*
+ ID_PRODUCT_FROM_DATABASE=SAS 5/E
+
+pci:v00001000d00000050sv00001028sd00001F09*
+ ID_PRODUCT_FROM_DATABASE=SAS 5i/R
+
+pci:v00001000d00000054*
+ ID_PRODUCT_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS
+
+pci:v00001000d00000054sv00001028sd00001F04*
+ ID_PRODUCT_FROM_DATABASE=SAS 5/E Adapter Controller
+
+pci:v00001000d00000054sv00001028sd00001F05*
+ ID_PRODUCT_FROM_DATABASE=SAS 5/i Adapter Controller
+
+pci:v00001000d00000054sv00001028sd00001F06*
+ ID_PRODUCT_FROM_DATABASE=SAS 5/i Integrated Controller
+
+pci:v00001000d00000054sv00001028sd00001F07*
+ ID_PRODUCT_FROM_DATABASE=SAS 5/iR Integrated RAID Controller
+
+pci:v00001000d00000054sv00001028sd00001F08*
+ ID_PRODUCT_FROM_DATABASE=SAS 5/iR Integrated RAID Controller
+
+pci:v00001000d00000054sv00001028sd00001F09*
+ ID_PRODUCT_FROM_DATABASE=SAS 5/iR Adapter RAID Controller
+
+pci:v00001000d00000054sv000015ADsd00001976*
+ ID_PRODUCT_FROM_DATABASE=SAS Controller
+
+pci:v00001000d00000055*
+ ID_PRODUCT_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS
+
+pci:v00001000d00000055sv00001033sd00008336*
+ ID_PRODUCT_FROM_DATABASE=SAS1068
+
+pci:v00001000d00000056*
+ ID_PRODUCT_FROM_DATABASE=SAS1064ET PCI-Express Fusion-MPT SAS
+
+pci:v00001000d00000056sv00001014sd000003BB*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID BR10il SAS/SATA Controller v2
+
+pci:v00001000d00000057*
+ ID_PRODUCT_FROM_DATABASE=M1064E MegaRAID SAS
+
+pci:v00001000d00000057sv00008086sd0000346C*
+ ID_PRODUCT_FROM_DATABASE=Embedded Software RAID Technology II (ESTRII)
+
+pci:v00001000d00000058*
+ ID_PRODUCT_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS
+
+pci:v00001000d00000058sv00001000sd00003140*
+ ID_PRODUCT_FROM_DATABASE=SAS3081E-R 8-Port SAS/SATA Host Bus Adapter
+
+pci:v00001000d00000058sv00001028sd0000021D*
+ ID_PRODUCT_FROM_DATABASE=SAS 6/iR Integrated Workstations RAID Controller
+
+pci:v00001000d00000058sv00001028sd00001F0E*
+ ID_PRODUCT_FROM_DATABASE=SAS 6/iR Adapter RAID Controller
+
+pci:v00001000d00000058sv00001028sd00001F0F*
+ ID_PRODUCT_FROM_DATABASE=SAS 6/iR Integrated Blades RAID Controller
+
+pci:v00001000d00000058sv00001028sd00001F10*
+ ID_PRODUCT_FROM_DATABASE=SAS 6/iR Integrated RAID Controller
+
+pci:v00001000d00000058sv0000103Csd00003229*
+ ID_PRODUCT_FROM_DATABASE=SC44Ge Host Bus Adapter
+
+pci:v00001000d00000059*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8208ELP/8208ELP
+
+pci:v00001000d0000005A*
+ ID_PRODUCT_FROM_DATABASE=SAS1066E PCI-Express Fusion-MPT SAS
+
+pci:v00001000d0000005B*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt]
+
+pci:v00001000d0000005Bsv00001000sd00009265*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9265-8i
+
+pci:v00001000d0000005Bsv00001000sd00009266*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9266-8i
+
+pci:v00001000d0000005Bsv00001000sd00009267*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9267-8i
+
+pci:v00001000d0000005Bsv00001000sd00009268*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9265CV-8i / 9270CV-8i
+
+pci:v00001000d0000005Bsv00001000sd00009269*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9266-4i
+
+pci:v00001000d0000005Bsv00001000sd00009270*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9270-8i
+
+pci:v00001000d0000005Bsv00001000sd00009271*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9271-8i
+
+pci:v00001000d0000005Bsv00001000sd00009272*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9272-8i
+
+pci:v00001000d0000005Bsv00001000sd00009273*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9270CV-8i
+
+pci:v00001000d0000005Bsv00001000sd00009274*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9270-4i
+
+pci:v00001000d0000005Bsv00001000sd00009275*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9271-8iCC
+
+pci:v00001000d0000005Bsv00001000sd00009276*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9271-4i
+
+pci:v00001000d0000005Bsv00001000sd00009285*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9285-8e
+
+pci:v00001000d0000005Bsv00001000sd00009288*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9285CV-8e
+
+pci:v00001000d0000005Bsv00001000sd00009290*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9286-8e
+
+pci:v00001000d0000005Bsv00001000sd00009291*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9286CV-8e
+
+pci:v00001000d0000005Bsv00001000sd00009295*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9286CV-8eCC
+
+pci:v00001000d0000005Bsv00001014sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID M5110 SAS/SATA Controller
+
+pci:v00001000d0000005Bsv00001014sd00000412*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID M5110e SAS/SATA Controller
+
+pci:v00001000d0000005Bsv00001028sd00001F2D*
+ ID_PRODUCT_FROM_DATABASE=PERC H810 Adapter
+
+pci:v00001000d0000005Bsv00001028sd00001F30*
+ ID_PRODUCT_FROM_DATABASE=PERC H710 Embedded
+
+pci:v00001000d0000005Bsv00001028sd00001F31*
+ ID_PRODUCT_FROM_DATABASE=PERC H710P Adapter
+
+pci:v00001000d0000005Bsv00001028sd00001F33*
+ ID_PRODUCT_FROM_DATABASE=PERC H710P Mini (for blades)
+
+pci:v00001000d0000005Bsv00001028sd00001F34*
+ ID_PRODUCT_FROM_DATABASE=PERC H710P Mini (for monolithics)
+
+pci:v00001000d0000005Bsv00001028sd00001F35*
+ ID_PRODUCT_FROM_DATABASE=PERC H710 Adapter
+
+pci:v00001000d0000005Bsv00001028sd00001F37*
+ ID_PRODUCT_FROM_DATABASE=PERC H710 Mini (for blades)
+
+pci:v00001000d0000005Bsv00001028sd00001F38*
+ ID_PRODUCT_FROM_DATABASE=PERC H710 Mini (for monolithics)
+
+pci:v00001000d0000005Bsv00008086sd00003513*
+ ID_PRODUCT_FROM_DATABASE=RMS25CB080 RAID Controller
+
+pci:v00001000d0000005C*
+ ID_PRODUCT_FROM_DATABASE=SAS1064A PCI-X Fusion-MPT SAS
+
+pci:v00001000d0000005D*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader]
+
+pci:v00001000d0000005E*
+ ID_PRODUCT_FROM_DATABASE=SAS1066 PCI-X Fusion-MPT SAS
+
+pci:v00001000d0000005F*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury]
+
+pci:v00001000d00000060*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 1078
+
+pci:v00001000d00000060sv00001000sd00001006*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8888ELP
+
+pci:v00001000d00000060sv00001000sd0000100A*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8708ELP
+
+pci:v00001000d00000060sv00001000sd0000100E*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8884E
+
+pci:v00001000d00000060sv00001000sd0000100F*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8708E
+
+pci:v00001000d00000060sv00001000sd00001010*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 350-8ELP
+
+pci:v00001000d00000060sv00001000sd00001011*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 350-4ELP
+
+pci:v00001000d00000060sv00001000sd00001012*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8704ELP
+
+pci:v00001000d00000060sv00001000sd00001016*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8880EM2
+
+pci:v00001000d00000060sv00001014sd00000363*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000060sv00001014sd00000364*
+ ID_PRODUCT_FROM_DATABASE=SystemX MegaRAID SAS 8808E
+
+pci:v00001000d00000060sv00001014sd00000365*
+ ID_PRODUCT_FROM_DATABASE=SystemX MegaRAID SAS 8884E
+
+pci:v00001000d00000060sv00001014sd00000379*
+ ID_PRODUCT_FROM_DATABASE=SystemX MegaRAID SAS 8880EM2
+
+pci:v00001000d00000060sv00001028sd00001F0A*
+ ID_PRODUCT_FROM_DATABASE=PERC 6/E Adapter RAID Controller
+
+pci:v00001000d00000060sv00001028sd00001F0B*
+ ID_PRODUCT_FROM_DATABASE=PERC 6/i Adapter RAID Controller
+
+pci:v00001000d00000060sv00001028sd00001F0C*
+ ID_PRODUCT_FROM_DATABASE=PERC 6/i Integrated RAID Controller
+
+pci:v00001000d00000060sv00001028sd00001F0D*
+ ID_PRODUCT_FROM_DATABASE=PERC 6/i Integrated RAID Controller
+
+pci:v00001000d00000060sv00001028sd00001F11*
+ ID_PRODUCT_FROM_DATABASE=CERC 6/i Integrated RAID Controller
+
+pci:v00001000d00000060sv00001033sd0000835A*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000060sv00001043sd0000824D*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000060sv00001170sd0000002F*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000060sv00001170sd00000036*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000060sv000015D9sd0000C080*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000060sv000017AAsd00006B7C*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000060sv000018A1sd00000003*
+ ID_PRODUCT_FROM_DATABASE=LSI MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000060sv00008086sd00001006*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSAS28EP
+
+pci:v00001000d00000060sv00008086sd0000100A*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSAS28EV
+
+pci:v00001000d00000060sv00008086sd00001010*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSATA28E
+
+pci:v00001000d00000060sv00008086sd000034CC*
+ ID_PRODUCT_FROM_DATABASE=Integrated RAID Controller SROMBSAS28E
+
+pci:v00001000d00000060sv00008086sd000034CD*
+ ID_PRODUCT_FROM_DATABASE=Integrated RAID Controller SROMBSAS28E
+
+pci:v00001000d00000060sv00008086sd00003505*
+ ID_PRODUCT_FROM_DATABASE=Integrated RAID Controller SROMBSASMP2
+
+pci:v00001000d00000062*
+ ID_PRODUCT_FROM_DATABASE=SAS1078 PCI-Express Fusion-MPT SAS
+
+pci:v00001000d00000062sv00001000sd00000062*
+ ID_PRODUCT_FROM_DATABASE=SAS1078 PCI-Express Fusion-MPT SAS
+
+pci:v00001000d00000064*
+ ID_PRODUCT_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor]
+
+pci:v00001000d00000065*
+ ID_PRODUCT_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor]
+
+pci:v00001000d0000006E*
+ ID_PRODUCT_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000070*
+ ID_PRODUCT_FROM_DATABASE=SAS2004 PCI-Express Fusion-MPT SAS-2 [Spitfire]
+
+pci:v00001000d00000071*
+ ID_PRODUCT_FROM_DATABASE=MR SAS HBA 2004
+
+pci:v00001000d00000072*
+ ID_PRODUCT_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon]
+
+pci:v00001000d00000072sv00001028sd00001F1C*
+ ID_PRODUCT_FROM_DATABASE=6Gbps SAS HBA Adapter
+
+pci:v00001000d00000072sv00001028sd00001F1D*
+ ID_PRODUCT_FROM_DATABASE=PERC H200 Adapter
+
+pci:v00001000d00000072sv00001028sd00001F1E*
+ ID_PRODUCT_FROM_DATABASE=PERC H200 Integrated
+
+pci:v00001000d00000072sv00001028sd00001F1F*
+ ID_PRODUCT_FROM_DATABASE=PERC H200 Modular
+
+pci:v00001000d00000072sv00001028sd00001F20*
+ ID_PRODUCT_FROM_DATABASE=PERC H200 Embedded
+
+pci:v00001000d00000072sv00001028sd00001F22*
+ ID_PRODUCT_FROM_DATABASE=Internal Tape Adapter
+
+pci:v00001000d00000072sv00008086sd0000350F*
+ ID_PRODUCT_FROM_DATABASE=RMS2LL040 RAID Controller
+
+pci:v00001000d00000073*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 2008 [Falcon]
+
+pci:v00001000d00000073sv00001000sd00009240*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9240-8i
+
+pci:v00001000d00000073sv00001000sd00009241*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9240-4i
+
+pci:v00001000d00000073sv00001000sd000092A0*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9220-8i
+
+pci:v00001000d00000073sv00001014sd000003B1*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID M1015 SAS/SATA Controller
+
+pci:v00001000d00000073sv00001028sd00001F4E*
+ ID_PRODUCT_FROM_DATABASE=PERC H310 Adapter
+
+pci:v00001000d00000073sv00001028sd00001F4F*
+ ID_PRODUCT_FROM_DATABASE=PERC H310 Integrated
+
+pci:v00001000d00000073sv00001028sd00001F50*
+ ID_PRODUCT_FROM_DATABASE=PERC H310 Mini Blades
+
+pci:v00001000d00000073sv00001028sd00001F51*
+ ID_PRODUCT_FROM_DATABASE=PERC H310 Mini Monolithics
+
+pci:v00001000d00000073sv00001028sd00001F52*
+ ID_PRODUCT_FROM_DATABASE=PERC H310 Embedded1
+
+pci:v00001000d00000073sv00001028sd00001F53*
+ ID_PRODUCT_FROM_DATABASE=PERC H310 Embedded2
+
+pci:v00001000d00000073sv00001028sd00001F54*
+ ID_PRODUCT_FROM_DATABASE=PERC H310 Reserved
+
+pci:v00001000d00000073sv00001054sd00003035*
+ ID_PRODUCT_FROM_DATABASE=LSI MegaRAID SAS 9240-8i
+
+pci:v00001000d00000073sv00001137sd00000072*
+ ID_PRODUCT_FROM_DATABASE=2004 iMR ROMB
+
+pci:v00001000d00000073sv00001137sd00000073*
+ ID_PRODUCT_FROM_DATABASE=2008 ROMB
+
+pci:v00001000d00000073sv00001137sd000000B0*
+ ID_PRODUCT_FROM_DATABASE=UCSC RAID SAS 2008M-8i
+
+pci:v00001000d00000073sv00001137sd000000B1*
+ ID_PRODUCT_FROM_DATABASE=UCSC RAID SAS 2008M-8i
+
+pci:v00001000d00000073sv000015D9sd00000400*
+ ID_PRODUCT_FROM_DATABASE=Supermicro SMC2008-iMR
+
+pci:v00001000d00000073sv00001734sd00001177*
+ ID_PRODUCT_FROM_DATABASE=RAID Ctrl SAS 6G 0/1 (D2607)
+
+pci:v00001000d00000073sv00008086sd0000350D*
+ ID_PRODUCT_FROM_DATABASE=RMS2AF040 RAID Controller
+
+pci:v00001000d00000073sv00008086sd00009240*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller RS2WC080
+
+pci:v00001000d00000073sv00008086sd00009241*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller RS2WC040
+
+pci:v00001000d00000074*
+ ID_PRODUCT_FROM_DATABASE=SAS2108 PCI-Express Fusion-MPT SAS-2 [Liberator]
+
+pci:v00001000d00000076*
+ ID_PRODUCT_FROM_DATABASE=SAS2108 PCI-Express Fusion-MPT SAS-2 [Liberator]
+
+pci:v00001000d00000077*
+ ID_PRODUCT_FROM_DATABASE=SAS2108 PCI-Express Fusion-MPT SAS-2 [Liberator]
+
+pci:v00001000d00000079*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 2108 [Liberator]
+
+pci:v00001000d00000079sv00001000sd00009251*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260-4ix
+
+pci:v00001000d00000079sv00001000sd00009256*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260-8ix
+
+pci:v00001000d00000079sv00001000sd00009260*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260-4i
+
+pci:v00001000d00000079sv00001000sd00009261*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260-8i
+
+pci:v00001000d00000079sv00001000sd00009262*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9262-8i
+
+pci:v00001000d00000079sv00001000sd00009263*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9261-8i
+
+pci:v00001000d00000079sv00001000sd00009264*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9264-8i
+
+pci:v00001000d00000079sv00001000sd00009267*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260CV-4i
+
+pci:v00001000d00000079sv00001000sd00009268*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260CV-8i
+
+pci:v00001000d00000079sv00001000sd00009275*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9280-8ex
+
+pci:v00001000d00000079sv00001000sd00009276*
+ ID_PRODUCT_FROM_DATABASE=MR9260-16i
+
+pci:v00001000d00000079sv00001000sd00009280*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9280-8e
+
+pci:v00001000d00000079sv00001000sd00009281*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9281-8E
+
+pci:v00001000d00000079sv00001000sd00009282*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9280-4i4e
+
+pci:v00001000d00000079sv00001000sd00009290*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9280DE-24i4e
+
+pci:v00001000d00000079sv00001014sd000003B2*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID M5015 SAS/SATA Controller
+
+pci:v00001000d00000079sv00001014sd000003B3*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID M5025 SAS/SATA Controller
+
+pci:v00001000d00000079sv00001028sd00001F15*
+ ID_PRODUCT_FROM_DATABASE=PERC H800 Adapter
+
+pci:v00001000d00000079sv00001028sd00001F16*
+ ID_PRODUCT_FROM_DATABASE=PERC H700 Adapter
+
+pci:v00001000d00000079sv00001028sd00001F17*
+ ID_PRODUCT_FROM_DATABASE=PERC H700 Integrated
+
+pci:v00001000d00000079sv00001028sd00001F18*
+ ID_PRODUCT_FROM_DATABASE=PERC H700 Modular
+
+pci:v00001000d00000079sv00001028sd00001F1A*
+ ID_PRODUCT_FROM_DATABASE=PERC H800 Proto Adapter
+
+pci:v00001000d00000079sv00001028sd00001F1B*
+ ID_PRODUCT_FROM_DATABASE=PERC H700 Integrated
+
+pci:v00001000d00000079sv00001043sd00008480*
+ ID_PRODUCT_FROM_DATABASE=PIKE-2108 16PD
+
+pci:v00001000d00000079sv00001734sd00001176*
+ ID_PRODUCT_FROM_DATABASE=RAID Ctrl SAS 6G 5/6 512MB (D2616)
+
+pci:v00001000d00000079sv00001734sd00001177*
+ ID_PRODUCT_FROM_DATABASE=RAID Ctrl SAS 6G 0/1 (D2607)
+
+pci:v00001000d00000079sv00008086sd00009256*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260DE-8i
+
+pci:v00001000d00000079sv00008086sd00009260*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller RS2BL040
+
+pci:v00001000d00000079sv00008086sd00009261*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller RS2BL080
+
+pci:v00001000d00000079sv00008086sd00009264*
+ ID_PRODUCT_FROM_DATABASE=Warm Beach (Caster Lite)
+
+pci:v00001000d00000079sv00008086sd00009267*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller RS2VB040
+
+pci:v00001000d00000079sv00008086sd00009268*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller RS2VB080
+
+pci:v00001000d0000007C*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 1078DE
+
+pci:v00001000d0000007Csv00001014sd00000395*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-AR10is SAS/SATA Controller
+
+pci:v00001000d0000007E*
+ ID_PRODUCT_FROM_DATABASE=SSS6200 PCI-Express Flash SSD
+
+pci:v00001000d00000080*
+ ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000081*
+ ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000082*
+ ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000083*
+ ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000084*
+ ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000085*
+ ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000086*
+ ID_PRODUCT_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000087*
+ ID_PRODUCT_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2
+
+pci:v00001000d00000087sv00001590sd00000044*
+ ID_PRODUCT_FROM_DATABASE=H220i
+
+pci:v00001000d0000008F*
+ ID_PRODUCT_FROM_DATABASE=53c875J
+
+pci:v00001000d0000008Fsv00001092sd00008000*
+ ID_PRODUCT_FROM_DATABASE=FirePort 40 SCSI Controller
+
+pci:v00001000d0000008Fsv00001092sd00008760*
+ ID_PRODUCT_FROM_DATABASE=FirePort 40 Dual SCSI Host Adapter
+
+pci:v00001000d00000090*
+ ID_PRODUCT_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3
+
+pci:v00001000d00000091*
+ ID_PRODUCT_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3
+
+pci:v00001000d00000094*
+ ID_PRODUCT_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3
+
+pci:v00001000d00000095*
+ ID_PRODUCT_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3
+
+pci:v00001000d00000096*
+ ID_PRODUCT_FROM_DATABASE=SAS3004 PCI-Express Fusion-MPT SAS-3
+
+pci:v00001000d00000097*
+ ID_PRODUCT_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3
+
+pci:v00001000d00000407*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID
+
+pci:v00001000d00000407sv00001000sd00000530*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 530 SCSI 320-0X RAID Controller
+
+pci:v00001000d00000407sv00001000sd00000531*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 531 SCSI 320-4X RAID Controller
+
+pci:v00001000d00000407sv00001000sd00000532*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 532 SCSI 320-2X RAID Controller
+
+pci:v00001000d00000407sv00001028sd00000531*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC
+
+pci:v00001000d00000407sv00001028sd00000533*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC
+
+pci:v00001000d00000407sv00008086sd00000530*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID Intel RAID Controller SRCZCRX
+
+pci:v00001000d00000407sv00008086sd00000532*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID Intel RAID Controller SRCU42X
+
+pci:v00001000d00000408*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID
+
+pci:v00001000d00000408sv00001000sd00000001*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SCSI 320-1E RAID Controller
+
+pci:v00001000d00000408sv00001000sd00000002*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SCSI 320-2E RAID Controller
+
+pci:v00001000d00000408sv00001025sd0000004D*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID ACER ROMB-2E RAID Controller
+
+pci:v00001000d00000408sv00001028sd00000001*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller PERC4e/SC
+
+pci:v00001000d00000408sv00001028sd00000002*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller PERC4e/DC
+
+pci:v00001000d00000408sv00001028sd00000012*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller RAC4
+
+pci:v00001000d00000408sv00001028sd00000015*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller PERC5
+
+pci:v00001000d00000408sv00001028sd00001F03*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller PERC5
+
+pci:v00001000d00000408sv00001734sd00001065*
+ ID_PRODUCT_FROM_DATABASE=FSC MegaRAID PCI Express ROMB
+
+pci:v00001000d00000408sv00008086sd00000002*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID Intel RAID Controller SRCU42E
+
+pci:v00001000d00000408sv00008086sd00003449*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID Intel RAID Controller SROMBU
+
+pci:v00001000d00000409*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID
+
+pci:v00001000d00000409sv00001000sd00003004*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-4X RAID Controller
+
+pci:v00001000d00000409sv00001000sd00003008*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-8X RAID Controller
+
+pci:v00001000d00000409sv00008086sd00003008*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller SRCS28X
+
+pci:v00001000d00000409sv00008086sd00003431*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller Alief SROMBU42E
+
+pci:v00001000d00000409sv00008086sd00003499*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller Harwich SROMBU42E
+
+pci:v00001000d00000411*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 1068
+
+pci:v00001000d00000411sv00001000sd00001001*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8408E
+
+pci:v00001000d00000411sv00001000sd00001002*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8480E
+
+pci:v00001000d00000411sv00001000sd00001003*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8344ELP
+
+pci:v00001000d00000411sv00001000sd00001004*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8308ELP
+
+pci:v00001000d00000411sv00001000sd00001008*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 84016E
+
+pci:v00001000d00000411sv00001000sd0000100C*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-12E
+
+pci:v00001000d00000411sv00001000sd0000100D*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-16E
+
+pci:v00001000d00000411sv00001000sd00002004*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-8ELP
+
+pci:v00001000d00000411sv00001000sd00002005*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-4ELP
+
+pci:v00001000d00000411sv00001033sd00008287*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000411sv00001054sd00003016*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS RoMB Server
+
+pci:v00001000d00000411sv00001734sd00001081*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000411sv00001734sd000010A3*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+
+pci:v00001000d00000411sv00008086sd00001001*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSAS18E
+
+pci:v00001000d00000411sv00008086sd00001003*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSAS144E
+
+pci:v00001000d00000411sv00008086sd00003500*
+ ID_PRODUCT_FROM_DATABASE=SROMBSAS18E RAID Controller
+
+pci:v00001000d00000411sv00008086sd00003501*
+ ID_PRODUCT_FROM_DATABASE=SROMBSAS18E RAID Controller
+
+pci:v00001000d00000411sv00008086sd00003504*
+ ID_PRODUCT_FROM_DATABASE=SROMBSAS18E RAID Controller
+
+pci:v00001000d00000413*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 1068 [Verde ZCR]
+
+pci:v00001000d00000413sv00001000sd00001005*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8300XLP
+
+pci:v00001000d00000621*
+ ID_PRODUCT_FROM_DATABASE=FC909 Fibre Channel Adapter
+
+pci:v00001000d00000622*
+ ID_PRODUCT_FROM_DATABASE=FC929 Fibre Channel Adapter
+
+pci:v00001000d00000622sv00001000sd00001020*
+ ID_PRODUCT_FROM_DATABASE=44929 O Dual Fibre Channel card
+
+pci:v00001000d00000623*
+ ID_PRODUCT_FROM_DATABASE=FC929 LAN
+
+pci:v00001000d00000624*
+ ID_PRODUCT_FROM_DATABASE=FC919 Fibre Channel Adapter
+
+pci:v00001000d00000625*
+ ID_PRODUCT_FROM_DATABASE=FC919 LAN
+
+pci:v00001000d00000626*
+ ID_PRODUCT_FROM_DATABASE=FC929X Fibre Channel Adapter
+
+pci:v00001000d00000626sv00001000sd00001010*
+ ID_PRODUCT_FROM_DATABASE=7202-XP-LC Dual Fibre Channel card
+
+pci:v00001000d00000627*
+ ID_PRODUCT_FROM_DATABASE=FC929X LAN
+
+pci:v00001000d00000628*
+ ID_PRODUCT_FROM_DATABASE=FC919X Fibre Channel Adapter
+
+pci:v00001000d00000629*
+ ID_PRODUCT_FROM_DATABASE=FC919X LAN
+
+pci:v00001000d00000640*
+ ID_PRODUCT_FROM_DATABASE=FC949X Fibre Channel Adapter
+
+pci:v00001000d00000642*
+ ID_PRODUCT_FROM_DATABASE=FC939X Fibre Channel Adapter
+
+pci:v00001000d00000646*
+ ID_PRODUCT_FROM_DATABASE=FC949ES Fibre Channel Adapter
+
+pci:v00001000d00000701*
+ ID_PRODUCT_FROM_DATABASE=83C885 NT50 DigitalScape Fast Ethernet
+
+pci:v00001000d00000702*
+ ID_PRODUCT_FROM_DATABASE=Yellowfin G-NIC gigabit ethernet
+
+pci:v00001000d00000702sv00001318sd00000000*
+ ID_PRODUCT_FROM_DATABASE=PEI100X
+
+pci:v00001000d00000804*
+ ID_PRODUCT_FROM_DATABASE=SA2010
+
+pci:v00001000d00000805*
+ ID_PRODUCT_FROM_DATABASE=SA2010ZC
+
+pci:v00001000d00000806*
+ ID_PRODUCT_FROM_DATABASE=SA2020
+
+pci:v00001000d00000807*
+ ID_PRODUCT_FROM_DATABASE=SA2020ZC
+
+pci:v00001000d00000901*
+ ID_PRODUCT_FROM_DATABASE=61C102
+
+pci:v00001000d00001000*
+ ID_PRODUCT_FROM_DATABASE=63C815
+
+pci:v00001000d00001960*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID
+
+pci:v00001000d00001960sv00001000sd00000518*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 518 SCSI 320-2 Controller
+
+pci:v00001000d00001960sv00001000sd00000520*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 520 SCSI 320-1 Controller
+
+pci:v00001000d00001960sv00001000sd00000522*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 522 i4 133 RAID Controller
+
+pci:v00001000d00001960sv00001000sd00000523*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 150-6 RAID Controller
+
+pci:v00001000d00001960sv00001000sd00004523*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 150-4 RAID Controller
+
+pci:v00001000d00001960sv00001000sd0000A520*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID ZCR SCSI 320-0 Controller
+
+pci:v00001000d00001960sv00001028sd00000518*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 518 DELL PERC 4/DC RAID Controller
+
+pci:v00001000d00001960sv00001028sd00000520*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 520 DELL PERC 4/SC RAID Controller
+
+pci:v00001000d00001960sv00001028sd00000531*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC
+
+pci:v00001000d00001960sv00001028sd00000533*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC
+
+pci:v00001000d00001960sv00008086sd00000520*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller SRCU41L
+
+pci:v00001000d00001960sv00008086sd00000523*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller SRCS16
+
+pci:v00001000d00006001*
+ ID_PRODUCT_FROM_DATABASE=DX1 Multiformat Broadcast HD/SD Encoder/Decoder
+
+pci:v00001001*
+ ID_VENDOR_FROM_DATABASE=Kolter Electronic
+
+pci:v00001001d00000010*
+ ID_PRODUCT_FROM_DATABASE=PCI 1616 Measurement card with 32 digital I/O lines
+
+pci:v00001001d00000011*
+ ID_PRODUCT_FROM_DATABASE=OPTO-PCI Opto-Isolated digital I/O board
+
+pci:v00001001d00000012*
+ ID_PRODUCT_FROM_DATABASE=PCI-AD/DA Analogue I/O board
+
+pci:v00001001d00000013*
+ ID_PRODUCT_FROM_DATABASE=PCI-OPTO-RELAIS Digital I/O board with relay outputs
+
+pci:v00001001d00000014*
+ ID_PRODUCT_FROM_DATABASE=PCI-Counter/Timer Counter Timer board
+
+pci:v00001001d00000015*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAC416 Analogue output board
+
+pci:v00001001d00000016*
+ ID_PRODUCT_FROM_DATABASE=PCI-MFB Analogue I/O board
+
+pci:v00001001d00000017*
+ ID_PRODUCT_FROM_DATABASE=PROTO-3 PCI Prototyping board
+
+pci:v00001001d00009100*
+ ID_PRODUCT_FROM_DATABASE=INI-9100/9100W SCSI Host
+
+pci:v00001002*
+ ID_VENDOR_FROM_DATABASE=Advanced Micro Devices [AMD] nee ATI
+
+pci:v00001002d00001314*
+ ID_PRODUCT_FROM_DATABASE=Wrestler HDMI Audio [Radeon HD 6250/6310]
+
+pci:v00001002d00001314sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001002d00001714*
+ ID_PRODUCT_FROM_DATABASE=BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series]
+
+pci:v00001002d00001714sv0000103Csd0000168B*
+ ID_PRODUCT_FROM_DATABASE=ProBook 4535s
+
+pci:v00001002d00003150*
+ ID_PRODUCT_FROM_DATABASE=M24 1P [Radeon Mobility X600]
+
+pci:v00001002d00003150sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=nx8220
+
+pci:v00001002d00003151*
+ ID_PRODUCT_FROM_DATABASE=M24 [FireMV 2400]
+
+pci:v00001002d00003152*
+ ID_PRODUCT_FROM_DATABASE=RV370 [Mobility Radeon X300]
+
+pci:v00001002d00003154*
+ ID_PRODUCT_FROM_DATABASE=M24GL [Mobility FireGL V3200]
+
+pci:v00001002d00003171*
+ ID_PRODUCT_FROM_DATABASE=M24 [FireMV 2400] (Secondary)
+
+pci:v00001002d00003E50*
+ ID_PRODUCT_FROM_DATABASE=RV380 0x3e50 [Radeon X600]
+
+pci:v00001002d00003E54*
+ ID_PRODUCT_FROM_DATABASE=RV380 0x3e54 [FireGL V3200]
+
+pci:v00001002d00003E70*
+ ID_PRODUCT_FROM_DATABASE=RV380 [Radeon X600] (Secondary)
+
+pci:v00001002d00004136*
+ ID_PRODUCT_FROM_DATABASE=RS100 [Radeon IGP320(M)]
+
+pci:v00001002d00004137*
+ ID_PRODUCT_FROM_DATABASE=RS200 [Radeon IGP330/340/350]
+
+pci:v00001002d00004144*
+ ID_PRODUCT_FROM_DATABASE=R300 AD [Radeon 9500 Pro]
+
+pci:v00001002d00004145*
+ ID_PRODUCT_FROM_DATABASE=R300 AE [Radeon 9700 Pro]
+
+pci:v00001002d00004146*
+ ID_PRODUCT_FROM_DATABASE=R300 AF [Radeon 9700 Pro]
+
+pci:v00001002d00004147*
+ ID_PRODUCT_FROM_DATABASE=R300 AG [FireGL Z1/X1]
+
+pci:v00001002d00004148*
+ ID_PRODUCT_FROM_DATABASE=R350 AH [Radeon 9800]
+
+pci:v00001002d00004149*
+ ID_PRODUCT_FROM_DATABASE=R350 AI [Radeon 9800]
+
+pci:v00001002d0000414A*
+ ID_PRODUCT_FROM_DATABASE=R350 AJ [Radeon 9800]
+
+pci:v00001002d0000414B*
+ ID_PRODUCT_FROM_DATABASE=R350 AK [FireGL X2]
+
+pci:v00001002d00004150*
+ ID_PRODUCT_FROM_DATABASE=RV350 AP [Radeon 9600]
+
+pci:v00001002d00004150sv00001002sd00000002*
+ ID_PRODUCT_FROM_DATABASE=R9600 Pro primary (Asus OEM for HP)
+
+pci:v00001002d00004150sv00001002sd00000003*
+ ID_PRODUCT_FROM_DATABASE=R9600 Pro secondary (Asus OEM for HP)
+
+pci:v00001002d00004150sv00001002sd00004722*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 AGP Edition
+
+pci:v00001002d00004150sv00001458sd00004024*
+ ID_PRODUCT_FROM_DATABASE=Giga-Byte GV-R96128D (Primary)
+
+pci:v00001002d00004150sv0000148Csd00002064*
+ ID_PRODUCT_FROM_DATABASE=PowerColor R96A-C3N
+
+pci:v00001002d00004150sv0000148Csd00002066*
+ ID_PRODUCT_FROM_DATABASE=PowerColor R96A-C3N
+
+pci:v00001002d00004150sv0000174Bsd00007C19*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Atlantis Radeon 9600 Pro
+
+pci:v00001002d00004150sv0000174Bsd00007C29*
+ ID_PRODUCT_FROM_DATABASE=GC-R9600PRO [Sapphire] (Primary)
+
+pci:v00001002d00004150sv000017EEsd00002002*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600 256Mb Primary
+
+pci:v00001002d00004150sv000018BCsd00000101*
+ ID_PRODUCT_FROM_DATABASE=GC-R9600PRO (Primary)
+
+pci:v00001002d00004151*
+ ID_PRODUCT_FROM_DATABASE=RV350 AQ [Radeon 9600]
+
+pci:v00001002d00004151sv00001043sd0000C004*
+ ID_PRODUCT_FROM_DATABASE=A9600SE
+
+pci:v00001002d00004152*
+ ID_PRODUCT_FROM_DATABASE=RV350 AR [Radeon 9600]
+
+pci:v00001002d00004152sv00001002sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600XT
+
+pci:v00001002d00004152sv00001002sd00004772*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 9600 XT
+
+pci:v00001002d00004152sv00001043sd0000C002*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600 XT TVD
+
+pci:v00001002d00004152sv00001043sd0000C01A*
+ ID_PRODUCT_FROM_DATABASE=A9600XT/TD
+
+pci:v00001002d00004152sv0000174Bsd00007C29*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9600XT
+
+pci:v00001002d00004152sv00001787sd00004002*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600 XT
+
+pci:v00001002d00004153*
+ ID_PRODUCT_FROM_DATABASE=RV350 AS [Radeon 9550]
+
+pci:v00001002d00004153sv00001043sd0000010C*
+ ID_PRODUCT_FROM_DATABASE=A9550GE/TD
+
+pci:v00001002d00004153sv00001462sd0000932C*
+ ID_PRODUCT_FROM_DATABASE=RX9550SE-TD128 (MS-8932)
+
+pci:v00001002d00004154*
+ ID_PRODUCT_FROM_DATABASE=RV350 AT [FireGL T2]
+
+pci:v00001002d00004155*
+ ID_PRODUCT_FROM_DATABASE=RV350 AU [FireGL T2]
+
+pci:v00001002d00004156*
+ ID_PRODUCT_FROM_DATABASE=RV350 AV [FireGL T2]
+
+pci:v00001002d00004157*
+ ID_PRODUCT_FROM_DATABASE=RV350 AW [FireGL T2]
+
+pci:v00001002d00004158*
+ ID_PRODUCT_FROM_DATABASE=68800AX [Mach32]
+
+pci:v00001002d00004164*
+ ID_PRODUCT_FROM_DATABASE=R300 AD [Radeon 9500 Pro] (Secondary)
+
+pci:v00001002d00004165*
+ ID_PRODUCT_FROM_DATABASE=R300 AE [Radeon 9700 Pro] (Secondary)
+
+pci:v00001002d00004166*
+ ID_PRODUCT_FROM_DATABASE=R300 AF [Radeon 9700 Pro] (Secondary)
+
+pci:v00001002d00004168*
+ ID_PRODUCT_FROM_DATABASE=R350 [Radeon 9800] (Secondary)
+
+pci:v00001002d00004170*
+ ID_PRODUCT_FROM_DATABASE=RV350 AP [Radeon 9600] (Secondary)
+
+pci:v00001002d00004170sv00001002sd00000003*
+ ID_PRODUCT_FROM_DATABASE=R9600 Pro secondary (Asus OEM for HP)
+
+pci:v00001002d00004170sv00001002sd00004723*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 AGP Edition (Secondary)
+
+pci:v00001002d00004170sv00001458sd00004025*
+ ID_PRODUCT_FROM_DATABASE=Giga-Byte GV-R96128D (Secondary)
+
+pci:v00001002d00004170sv0000148Csd00002067*
+ ID_PRODUCT_FROM_DATABASE=PowerColor R96A-C3N (Secondary)
+
+pci:v00001002d00004170sv0000174Bsd00007C28*
+ ID_PRODUCT_FROM_DATABASE=GC-R9600PRO [Sapphire] (Secondary)
+
+pci:v00001002d00004170sv000017EEsd00002003*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600 256Mb (Secondary)
+
+pci:v00001002d00004170sv000018BCsd00000100*
+ ID_PRODUCT_FROM_DATABASE=GC-R9600PRO (Secondary)
+
+pci:v00001002d00004171*
+ ID_PRODUCT_FROM_DATABASE=RV350 AQ [Radeon 9600] (Secondary)
+
+pci:v00001002d00004171sv00001043sd0000C005*
+ ID_PRODUCT_FROM_DATABASE=A9600SE (Secondary)
+
+pci:v00001002d00004172*
+ ID_PRODUCT_FROM_DATABASE=RV350 AR [Radeon 9600] (Secondary)
+
+pci:v00001002d00004172sv00001002sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600XT (Secondary)
+
+pci:v00001002d00004172sv00001002sd00004773*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 9600 XT (Secondary)
+
+pci:v00001002d00004172sv00001043sd0000C003*
+ ID_PRODUCT_FROM_DATABASE=A9600XT (Secondary)
+
+pci:v00001002d00004172sv00001043sd0000C01B*
+ ID_PRODUCT_FROM_DATABASE=A9600XT/TD (Secondary)
+
+pci:v00001002d00004172sv0000174Bsd00007C28*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9600XT (Secondary)
+
+pci:v00001002d00004172sv00001787sd00004003*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600 XT (Secondary)
+
+pci:v00001002d00004173*
+ ID_PRODUCT_FROM_DATABASE=RV350 AS [Radeon 9550] (Secondary)
+
+pci:v00001002d00004173sv00001043sd0000010D*
+ ID_PRODUCT_FROM_DATABASE=A9550GE/TD (Secondary)
+
+pci:v00001002d00004237*
+ ID_PRODUCT_FROM_DATABASE=RS250 [Radeon Mobility 7000 IGP]
+
+pci:v00001002d00004242*
+ ID_PRODUCT_FROM_DATABASE=R200 BB [Radeon All in Wonder 8500DV]
+
+pci:v00001002d00004242sv00001002sd000002AA*
+ ID_PRODUCT_FROM_DATABASE=Radeon 8500 AIW DV Edition
+
+pci:v00001002d00004243*
+ ID_PRODUCT_FROM_DATABASE=R200 BC [Radeon All in Wonder 8500]
+
+pci:v00001002d00004336*
+ ID_PRODUCT_FROM_DATABASE=RS100 [Radeon IGP320M]
+
+pci:v00001002d00004336sv00001002sd00004336*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze4300 ATI Radeon Mobility U1 (IGP 320 M)
+
+pci:v00001002d00004336sv0000103Csd00000024*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin Video
+
+pci:v00001002d00004336sv0000161Fsd00002029*
+ ID_PRODUCT_FROM_DATABASE=eMachines M5312 builtin Video
+
+pci:v00001002d00004337*
+ ID_PRODUCT_FROM_DATABASE=RS200 [Radeon IGP330M/340M/350M]
+
+pci:v00001002d00004337sv00001014sd0000053A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v00001002d00004337sv0000103Csd00000850*
+ ID_PRODUCT_FROM_DATABASE=Radeon IGP 345M
+
+pci:v00001002d00004341*
+ ID_PRODUCT_FROM_DATABASE=IXP150 AC'97 Audio Controller
+
+pci:v00001002d00004342*
+ ID_PRODUCT_FROM_DATABASE=IXP200 3COM 3C920B Ethernet Controller
+
+pci:v00001002d00004345*
+ ID_PRODUCT_FROM_DATABASE=EHCI USB Controller
+
+pci:v00001002d00004347*
+ ID_PRODUCT_FROM_DATABASE=OHCI USB Controller #1
+
+pci:v00001002d00004348*
+ ID_PRODUCT_FROM_DATABASE=OHCI USB Controller #2
+
+pci:v00001002d00004349*
+ ID_PRODUCT_FROM_DATABASE=Dual Channel Bus Master PCI IDE Controller
+
+pci:v00001002d0000434D*
+ ID_PRODUCT_FROM_DATABASE=IXP AC'97 Modem
+
+pci:v00001002d00004353*
+ ID_PRODUCT_FROM_DATABASE=SMBus
+
+pci:v00001002d00004354*
+ ID_PRODUCT_FROM_DATABASE=215CT [Mach64 CT]
+
+pci:v00001002d00004358*
+ ID_PRODUCT_FROM_DATABASE=210888CX [Mach64 CX]
+
+pci:v00001002d00004361*
+ ID_PRODUCT_FROM_DATABASE=IXP SB300 AC'97 Audio Controller
+
+pci:v00001002d00004363*
+ ID_PRODUCT_FROM_DATABASE=SMBus
+
+pci:v00001002d0000436E*
+ ID_PRODUCT_FROM_DATABASE=436E Serial ATA Controller
+
+pci:v00001002d00004370*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 AC'97 Audio Controller
+
+pci:v00001002d00004370sv00001025sd00000079*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi
+
+pci:v00001002d00004370sv00001025sd00000091*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5032WXMi
+
+pci:v00001002d00004370sv0000103Csd00002A05*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001002d00004370sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004370sv0000105Bsd00000C81*
+ ID_PRODUCT_FROM_DATABASE=Realtek ALC 653
+
+pci:v00001002d00004370sv0000107Bsd00000300*
+ ID_PRODUCT_FROM_DATABASE=MX6421
+
+pci:v00001002d00004370sv00001462sd00000131*
+ ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook
+
+pci:v00001002d00004371*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 PCI-PCI Bridge
+
+pci:v00001002d00004371sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004371sv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00004372*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 SMBus Controller
+
+pci:v00001002d00004372sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi
+
+pci:v00001002d00004372sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001002d00004372sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004372sv00001462sd00000131*
+ ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook
+
+pci:v00001002d00004372sv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00004373*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 USB2 Host Controller
+
+pci:v00001002d00004373sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi
+
+pci:v00001002d00004373sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001002d00004373sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004373sv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00004374*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 USB Host Controller
+
+pci:v00001002d00004374sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001002d00004374sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004374sv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00004375*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 USB Host Controller
+
+pci:v00001002d00004375sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi
+
+pci:v00001002d00004375sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001002d00004375sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004375sv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00004376*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 IDE Controller
+
+pci:v00001002d00004376sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi
+
+pci:v00001002d00004376sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001002d00004376sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004376sv00001462sd00000131*
+ ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook
+
+pci:v00001002d00004376sv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00004377*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 PCI-ISA Bridge
+
+pci:v00001002d00004377sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi
+
+pci:v00001002d00004377sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001002d00004377sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004377sv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00004378*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 AC'97 Modem Controller
+
+pci:v00001002d00004378sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi
+
+pci:v00001002d00004378sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00004378sv00001462sd00000131*
+ ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook
+
+pci:v00001002d00004379*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 Serial ATA Controller
+
+pci:v00001002d00004379sv00001462sd00007141*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d0000437A*
+ ID_PRODUCT_FROM_DATABASE=IXP SB400 Serial ATA Controller
+
+pci:v00001002d0000437Asv00001002sd00004379*
+ ID_PRODUCT_FROM_DATABASE=4379 Serial ATA Controller
+
+pci:v00001002d0000437Asv00001002sd0000437A*
+ ID_PRODUCT_FROM_DATABASE=437A Serial ATA Controller
+
+pci:v00001002d0000437Asv00001462sd00007141*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d0000437Asv000014F1sd00008800*
+ ID_PRODUCT_FROM_DATABASE=Leadtek WinFast TV2000XP Expert
+
+pci:v00001002d0000437B*
+ ID_PRODUCT_FROM_DATABASE=IXP SB4x0 High Definition Audio Controller
+
+pci:v00001002d0000437Bsv00001002sd0000437B*
+ ID_PRODUCT_FROM_DATABASE=IXP SB4x0 High Definition Audio Controller
+
+pci:v00001002d0000437Bsv000010CFsd00001326*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu Lifebook A3040
+
+pci:v00001002d0000437Bsv00001734sd000010B8*
+ ID_PRODUCT_FROM_DATABASE=Realtek High Definition Audio
+
+pci:v00001002d00004380*
+ ID_PRODUCT_FROM_DATABASE=SB600 Non-Raid-5 SATA
+
+pci:v00001002d00004380sv0000103Csd00002813*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00004380sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00004380sv00001458sd0000B003*
+ ID_PRODUCT_FROM_DATABASE=GA-MA790FX-DS5 (rev. 1.0)
+
+pci:v00001002d00004380sv00001458sd0000B005*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte GA-MA69G-S3H Motherboard
+
+pci:v00001002d00004380sv00001462sd00007327*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d00004380sv000017F2sd00005999*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d00004381*
+ ID_PRODUCT_FROM_DATABASE=SB400 SATA Controller (RAID 5 mode)
+
+pci:v00001002d00004382*
+ ID_PRODUCT_FROM_DATABASE=SB600 AC97 Audio
+
+pci:v00001002d00004383*
+ ID_PRODUCT_FROM_DATABASE=SBx00 Azalia (Intel HDA)
+
+pci:v00001002d00004383sv0000103Csd00001611*
+ ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000
+
+pci:v00001002d00004383sv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00004383sv00001043sd00008230*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d00004383sv00001043sd0000836C*
+ ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard
+
+pci:v00001002d00004383sv00001043sd00008410*
+ ID_PRODUCT_FROM_DATABASE=M4A89GTD PRO/USB3 Motherboard
+
+pci:v00001002d00004383sv00001043sd0000841B*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001002d00004383sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00004383sv00001458sd0000A022*
+ ID_PRODUCT_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard
+
+pci:v00001002d00004383sv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d00004384*
+ ID_PRODUCT_FROM_DATABASE=SBx00 PCI to PCI Bridge
+
+pci:v00001002d00004385*
+ ID_PRODUCT_FROM_DATABASE=SBx00 SMBus Controller
+
+pci:v00001002d00004385sv0000103Csd00001611*
+ ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000
+
+pci:v00001002d00004385sv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00004385sv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d00004385sv00001043sd00008389*
+ ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard
+
+pci:v00001002d00004385sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00004385sv00001458sd00004385*
+ ID_PRODUCT_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard
+
+pci:v00001002d00004385sv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d00004385sv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v00001002d00004385sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001002d00004385sv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d00004386*
+ ID_PRODUCT_FROM_DATABASE=SB600 USB Controller (EHCI)
+
+pci:v00001002d00004386sv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00004386sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00004386sv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d00004386sv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d00004387*
+ ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI0)
+
+pci:v00001002d00004387sv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00004387sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00004387sv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d00004387sv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d00004388*
+ ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI1)
+
+pci:v00001002d00004388sv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00004388sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00004388sv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d00004388sv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d00004389*
+ ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI2)
+
+pci:v00001002d00004389sv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00004389sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00004389sv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d00004389sv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d0000438A*
+ ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI3)
+
+pci:v00001002d0000438Asv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d0000438Asv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d0000438Asv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d0000438Asv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d0000438B*
+ ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI4)
+
+pci:v00001002d0000438Bsv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d0000438Bsv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d0000438Bsv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d0000438Bsv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d0000438C*
+ ID_PRODUCT_FROM_DATABASE=SB600 IDE
+
+pci:v00001002d0000438Csv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d0000438Csv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d0000438Csv00001458sd00005002*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte GA-MA69G-S3H Motherboard
+
+pci:v00001002d0000438Csv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d0000438Csv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d0000438D*
+ ID_PRODUCT_FROM_DATABASE=SB600 PCI to LPC Bridge
+
+pci:v00001002d0000438Dsv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d0000438Dsv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d0000438Dsv00001462sd00007368*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d0000438Dsv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d0000438E*
+ ID_PRODUCT_FROM_DATABASE=SB600 AC97 Modem
+
+pci:v00001002d00004390*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode]
+
+pci:v00001002d00004390sv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d00004390sv00001043sd00008389*
+ ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard
+
+pci:v00001002d00004390sv00001458sd0000B002*
+ ID_PRODUCT_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard
+
+pci:v00001002d00004390sv00001849sd00004390*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v00001002d00004391*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode]
+
+pci:v00001002d00004391sv0000103Csd00001611*
+ ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000
+
+pci:v00001002d00004391sv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d00004391sv00001043sd00008443*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001002d00004391sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001002d00004392*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [Non-RAID5 mode]
+
+pci:v00001002d00004393*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [RAID5 mode]
+
+pci:v00001002d00004394*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode]
+
+pci:v00001002d00004395*
+ ID_PRODUCT_FROM_DATABASE=SB8x0/SB9x0 SATA Controller [Storage mode]
+
+pci:v00001002d00004396*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller
+
+pci:v00001002d00004396sv0000103Csd00001611*
+ ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000
+
+pci:v00001002d00004396sv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d00004396sv00001043sd00008443*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001002d00004396sv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v00001002d00004396sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001002d00004397*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
+
+pci:v00001002d00004397sv0000103Csd00001611*
+ ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000
+
+pci:v00001002d00004397sv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d00004397sv00001043sd00008443*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001002d00004397sv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v00001002d00004397sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001002d00004398*
+ ID_PRODUCT_FROM_DATABASE=SB7x0 USB OHCI1 Controller
+
+pci:v00001002d00004398sv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d00004398sv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v00001002d00004399*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller
+
+pci:v00001002d00004399sv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d00004399sv00001043sd00008443*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001002d00004399sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001002d0000439C*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller
+
+pci:v00001002d0000439Csv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d0000439D*
+ ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller
+
+pci:v00001002d0000439Dsv0000103Csd00001611*
+ ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000
+
+pci:v00001002d0000439Dsv00001043sd000082EF*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001002d0000439Dsv00001043sd00008443*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001002d0000439Dsv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001002d000043A0*
+ ID_PRODUCT_FROM_DATABASE=SB700/SB800/SB900 PCI to PCI bridge (PCIE port 0)
+
+pci:v00001002d000043A1*
+ ID_PRODUCT_FROM_DATABASE=SB700/SB800/SB900 PCI to PCI bridge (PCIE port 1)
+
+pci:v00001002d000043A2*
+ ID_PRODUCT_FROM_DATABASE=SB900 PCI to PCI bridge (PCIE port 2)
+
+pci:v00001002d000043A3*
+ ID_PRODUCT_FROM_DATABASE=SB900 PCI to PCI bridge (PCIE port 3)
+
+pci:v00001002d00004437*
+ ID_PRODUCT_FROM_DATABASE=RS250 [Radeon Mobility 7000 IGP]
+
+pci:v00001002d00004554*
+ ID_PRODUCT_FROM_DATABASE=210888ET [Mach64 ET]
+
+pci:v00001002d00004654*
+ ID_PRODUCT_FROM_DATABASE=Mach64 VT
+
+pci:v00001002d00004742*
+ ID_PRODUCT_FROM_DATABASE=3D Rage Pro AGP 1X/2X
+
+pci:v00001002d00004742sv00001002sd00000040*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00001002sd00000044*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00001002sd00000061*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro AIW AGP 2X
+
+pci:v00001002d00004742sv00001002sd00000062*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro AIW AGP 2X
+
+pci:v00001002d00004742sv00001002sd00000063*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro AIW AGP 2X
+
+pci:v00001002d00004742sv00001002sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00001002sd00000084*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00001002sd00004742*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00001002sd00008001*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00001028sd00000082*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00001028sd00004082*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX1 Onboard Display Adapter
+
+pci:v00001002d00004742sv00001028sd00008082*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00001028sd0000C082*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004742sv00008086sd00004152*
+ ID_PRODUCT_FROM_DATABASE=Xpert 98D AGP 2X
+
+pci:v00001002d00004742sv00008086sd0000464A*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X
+
+pci:v00001002d00004744*
+ ID_PRODUCT_FROM_DATABASE=3D Rage Pro AGP 1X
+
+pci:v00001002d00004744sv00001002sd00004744*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP
+
+pci:v00001002d00004744sv00008086sd00004D55*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D Pro AGP 1X [Intel MU440EX]
+
+pci:v00001002d00004747*
+ ID_PRODUCT_FROM_DATABASE=3D Rage Pro
+
+pci:v00001002d00004749*
+ ID_PRODUCT_FROM_DATABASE=3D Rage Pro
+
+pci:v00001002d00004749sv00001002sd00000061*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro AIW
+
+pci:v00001002d00004749sv00001002sd00000062*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro AIW
+
+pci:v00001002d0000474C*
+ ID_PRODUCT_FROM_DATABASE=Rage XC
+
+pci:v00001002d0000474D*
+ ID_PRODUCT_FROM_DATABASE=Rage XL AGP 2X
+
+pci:v00001002d0000474Dsv00001002sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Xpert 98 RXL AGP 2X
+
+pci:v00001002d0000474Dsv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Xpert 98 RXL AGP 2X
+
+pci:v00001002d0000474Dsv00001002sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Rage XL AGP 2X
+
+pci:v00001002d0000474Dsv00001002sd00000084*
+ ID_PRODUCT_FROM_DATABASE=Xpert 98 AGP 2X
+
+pci:v00001002d0000474Dsv00001002sd0000474D*
+ ID_PRODUCT_FROM_DATABASE=Rage XL AGP
+
+pci:v00001002d0000474Dsv00001033sd0000806A*
+ ID_PRODUCT_FROM_DATABASE=Rage XL AGP
+
+pci:v00001002d0000474E*
+ ID_PRODUCT_FROM_DATABASE=Rage XC AGP
+
+pci:v00001002d0000474Esv00001002sd0000474E*
+ ID_PRODUCT_FROM_DATABASE=Rage XC AGP
+
+pci:v00001002d0000474F*
+ ID_PRODUCT_FROM_DATABASE=Rage XL
+
+pci:v00001002d0000474Fsv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Rage XL
+
+pci:v00001002d0000474Fsv00001002sd0000474F*
+ ID_PRODUCT_FROM_DATABASE=Rage XL
+
+pci:v00001002d00004750*
+ ID_PRODUCT_FROM_DATABASE=3D Rage Pro 215GP
+
+pci:v00001002d00004750sv00001002sd00000040*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo
+
+pci:v00001002d00004750sv00001002sd00000044*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo
+
+pci:v00001002d00004750sv00001002sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo
+
+pci:v00001002d00004750sv00001002sd00000084*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo
+
+pci:v00001002d00004750sv00001002sd00004750*
+ ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo
+
+pci:v00001002d00004751*
+ ID_PRODUCT_FROM_DATABASE=3D Rage Pro 215GQ
+
+pci:v00001002d00004752*
+ ID_PRODUCT_FROM_DATABASE=Rage XL
+
+pci:v00001002d00004752sv00000E11sd0000001E*
+ ID_PRODUCT_FROM_DATABASE=Proliant Rage XL
+
+pci:v00001002d00004752sv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Rage XL
+
+pci:v00001002d00004752sv00001002sd00004752*
+ ID_PRODUCT_FROM_DATABASE=Proliant Rage XL
+
+pci:v00001002d00004752sv00001002sd00008008*
+ ID_PRODUCT_FROM_DATABASE=Rage XL
+
+pci:v00001002d00004752sv00001014sd00000240*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00001002d00004752sv00001028sd000000CE*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1400
+
+pci:v00001002d00004752sv00001028sd000000D1*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2550
+
+pci:v00001002d00004752sv00001028sd000000D9*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2500
+
+pci:v00001002d00004752sv00001028sd00000134*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 600SC
+
+pci:v00001002d00004752sv00001028sd0000014A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1750
+
+pci:v00001002d00004752sv00001028sd00000165*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 750
+
+pci:v00001002d00004752sv0000103Csd000010E1*
+ ID_PRODUCT_FROM_DATABASE=NetServer Rage XL
+
+pci:v00001002d00004752sv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00001002d00004752sv0000107Bsd00006400*
+ ID_PRODUCT_FROM_DATABASE=6400 Server
+
+pci:v00001002d00004752sv00001734sd0000007A*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard VGA
+
+pci:v00001002d00004752sv00008086sd00003411*
+ ID_PRODUCT_FROM_DATABASE=SDS2 Mainboard
+
+pci:v00001002d00004752sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00001002d00004752sv00008086sd00005744*
+ ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard
+
+pci:v00001002d00004753*
+ ID_PRODUCT_FROM_DATABASE=Rage XC
+
+pci:v00001002d00004753sv00001002sd00004753*
+ ID_PRODUCT_FROM_DATABASE=Rage XC
+
+pci:v00001002d00004754*
+ ID_PRODUCT_FROM_DATABASE=3D Rage I/II 215GT [Mach64 GT]
+
+pci:v00001002d00004755*
+ ID_PRODUCT_FROM_DATABASE=3D Rage II+ 215GTB [Mach64 GTB]
+
+pci:v00001002d00004756*
+ ID_PRODUCT_FROM_DATABASE=3D Rage IIC 215IIC [Mach64 GT IIC]
+
+pci:v00001002d00004756sv00001002sd00004756*
+ ID_PRODUCT_FROM_DATABASE=Rage IIC
+
+pci:v00001002d00004757*
+ ID_PRODUCT_FROM_DATABASE=3D Rage IIC AGP
+
+pci:v00001002d00004757sv00001002sd00004757*
+ ID_PRODUCT_FROM_DATABASE=Rage IIC AGP
+
+pci:v00001002d00004757sv00001028sd00000089*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D IIC
+
+pci:v00001002d00004757sv00001028sd0000008E*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1300 onboard video
+
+pci:v00001002d00004757sv00001028sd00004082*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D IIC
+
+pci:v00001002d00004757sv00001028sd00008082*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D IIC
+
+pci:v00001002d00004757sv00001028sd0000C082*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D IIC
+
+pci:v00001002d00004758*
+ ID_PRODUCT_FROM_DATABASE=210888GX [Mach64 GX]
+
+pci:v00001002d00004759*
+ ID_PRODUCT_FROM_DATABASE=3D Rage IIC
+
+pci:v00001002d0000475A*
+ ID_PRODUCT_FROM_DATABASE=3D Rage IIC AGP
+
+pci:v00001002d0000475Asv00001002sd00000084*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D Pro AGP 2x XPERT 98
+
+pci:v00001002d0000475Asv00001002sd00000087*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D IIC
+
+pci:v00001002d0000475Asv00001002sd0000475A*
+ ID_PRODUCT_FROM_DATABASE=Rage IIC AGP
+
+pci:v00001002d00004964*
+ ID_PRODUCT_FROM_DATABASE=RV250 Id [Radeon 9000]
+
+pci:v00001002d00004965*
+ ID_PRODUCT_FROM_DATABASE=RV250 Ie [Radeon 9000]
+
+pci:v00001002d00004966*
+ ID_PRODUCT_FROM_DATABASE=R250 If [Radeon 9000]
+
+pci:v00001002d00004966sv000010F1sd00000002*
+ ID_PRODUCT_FROM_DATABASE=RV250 If [Tachyon G9000 PRO]
+
+pci:v00001002d00004966sv0000148Csd00002039*
+ ID_PRODUCT_FROM_DATABASE=RV250 If [Radeon 9000 Pro "Evil Commando"]
+
+pci:v00001002d00004966sv00001509sd00009A00*
+ ID_PRODUCT_FROM_DATABASE=RV250 If [Radeon 9000 "AT009"]
+
+pci:v00001002d00004966sv00001681sd00000040*
+ ID_PRODUCT_FROM_DATABASE=RV250 If [3D prophet 9000]
+
+pci:v00001002d00004966sv0000174Bsd00007176*
+ ID_PRODUCT_FROM_DATABASE=RV250 If [Sapphire Radeon 9000 Pro]
+
+pci:v00001002d00004966sv0000174Bsd00007192*
+ ID_PRODUCT_FROM_DATABASE=RV250 If [Radeon 9000 "Atlantis"]
+
+pci:v00001002d00004966sv000017AFsd00002005*
+ ID_PRODUCT_FROM_DATABASE=RV250 If [Excalibur Radeon 9000 Pro]
+
+pci:v00001002d00004966sv000017AFsd00002006*
+ ID_PRODUCT_FROM_DATABASE=RV250 If [Excalibur Radeon 9000]
+
+pci:v00001002d00004967*
+ ID_PRODUCT_FROM_DATABASE=RV250 Ig [Radeon 9000]
+
+pci:v00001002d0000496E*
+ ID_PRODUCT_FROM_DATABASE=RV250 [Radeon 9000] (Secondary)
+
+pci:v00001002d00004A48*
+ ID_PRODUCT_FROM_DATABASE=R420 JH [Radeon X800]
+
+pci:v00001002d00004A49*
+ ID_PRODUCT_FROM_DATABASE=R420 JI [Radeon X800PRO]
+
+pci:v00001002d00004A4A*
+ ID_PRODUCT_FROM_DATABASE=R420 JJ [Radeon X800SE]
+
+pci:v00001002d00004A4B*
+ ID_PRODUCT_FROM_DATABASE=R420 JK [Radeon X800]
+
+pci:v00001002d00004A4C*
+ ID_PRODUCT_FROM_DATABASE=R420 JL [Radeon X800]
+
+pci:v00001002d00004A4D*
+ ID_PRODUCT_FROM_DATABASE=R420 JM [FireGL X3]
+
+pci:v00001002d00004A4E*
+ ID_PRODUCT_FROM_DATABASE=R420 JN [Mobility Radeon 9800]
+
+pci:v00001002d00004A4F*
+ ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800 AGP]
+
+pci:v00001002d00004A50*
+ ID_PRODUCT_FROM_DATABASE=R420 JP [Radeon X800XT]
+
+pci:v00001002d00004A54*
+ ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800 VE]
+
+pci:v00001002d00004A69*
+ ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800 PRO/GTO] (Secondary)
+
+pci:v00001002d00004A6A*
+ ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800] (Secondary)
+
+pci:v00001002d00004A6B*
+ ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800] (Secondary)
+
+pci:v00001002d00004A70*
+ ID_PRODUCT_FROM_DATABASE=R420 [X800XT-PE] (Secondary)
+
+pci:v00001002d00004A74*
+ ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800 VE] (Secondary)
+
+pci:v00001002d00004B48*
+ ID_PRODUCT_FROM_DATABASE=R481 [Radeon X850 PCIe]
+
+pci:v00001002d00004B49*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT]
+
+pci:v00001002d00004B4A*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850SE AGP]
+
+pci:v00001002d00004B4B*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850Pro]
+
+pci:v00001002d00004B4C*
+ ID_PRODUCT_FROM_DATABASE=R481 [Radeon X850XT-PE]
+
+pci:v00001002d00004B69*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT] (Secondary)
+
+pci:v00001002d00004B6B*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850Pro] (Secondary)
+
+pci:v00001002d00004B6C*
+ ID_PRODUCT_FROM_DATABASE=R481 [Radeon X850XT-PE] (Secondary)
+
+pci:v00001002d00004C42*
+ ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro AGP-133
+
+pci:v00001002d00004C42sv00000E11sd0000B0E7*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro (Compaq Presario 5240)
+
+pci:v00001002d00004C42sv00000E11sd0000B0E8*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D LT Pro
+
+pci:v00001002d00004C42sv00000E11sd0000B10E*
+ ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro (Compaq Armada 1750)
+
+pci:v00001002d00004C42sv00001002sd00000040*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro AGP 2X
+
+pci:v00001002d00004C42sv00001002sd00000044*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro AGP 2X
+
+pci:v00001002d00004C42sv00001002sd00004C42*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro AGP 2X
+
+pci:v00001002d00004C42sv00001002sd00008001*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro AGP 2X
+
+pci:v00001002d00004C42sv00001028sd00000085*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D LT Pro
+
+pci:v00001002d00004C44*
+ ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro AGP-66
+
+pci:v00001002d00004C45*
+ ID_PRODUCT_FROM_DATABASE=Rage Mobility M3 AGP
+
+pci:v00001002d00004C46*
+ ID_PRODUCT_FROM_DATABASE=Rage Mobility M3 AGP 2x
+
+pci:v00001002d00004C46sv00001002sd00000155*
+ ID_PRODUCT_FROM_DATABASE=IBM Thinkpad A22p
+
+pci:v00001002d00004C46sv00001014sd00000155*
+ ID_PRODUCT_FROM_DATABASE=IBM Thinkpad A22p
+
+pci:v00001002d00004C46sv00001028sd000000B1*
+ ID_PRODUCT_FROM_DATABASE=Latitude C600
+
+pci:v00001002d00004C47*
+ ID_PRODUCT_FROM_DATABASE=3D Rage LT-G 215LG
+
+pci:v00001002d00004C49*
+ ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro
+
+pci:v00001002d00004C49sv00001002sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro
+
+pci:v00001002d00004C49sv00001002sd00000040*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro
+
+pci:v00001002d00004C49sv00001002sd00000044*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro
+
+pci:v00001002d00004C49sv00001002sd00004C49*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro
+
+pci:v00001002d00004C4D*
+ ID_PRODUCT_FROM_DATABASE=Rage Mobility P/M AGP 2x
+
+pci:v00001002d00004C4Dsv00000E11sd0000B111*
+ ID_PRODUCT_FROM_DATABASE=Armada M700
+
+pci:v00001002d00004C4Dsv00000E11sd0000B160*
+ ID_PRODUCT_FROM_DATABASE=Armada E500
+
+pci:v00001002d00004C4Dsv00001002sd00000084*
+ ID_PRODUCT_FROM_DATABASE=Xpert 98 AGP 2X (Mobility)
+
+pci:v00001002d00004C4Dsv00001014sd00000154*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A20m/A21m
+
+pci:v00001002d00004C4Dsv00001028sd000000AA*
+ ID_PRODUCT_FROM_DATABASE=Latitude CPt
+
+pci:v00001002d00004C4Dsv00001028sd000000BB*
+ ID_PRODUCT_FROM_DATABASE=Latitude CPx
+
+pci:v00001002d00004C4Dsv00001179sd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Satellite 1715XCDS laptop
+
+pci:v00001002d00004C4Dsv000013BDsd00001019*
+ ID_PRODUCT_FROM_DATABASE=PC-AR10
+
+pci:v00001002d00004C4E*
+ ID_PRODUCT_FROM_DATABASE=Rage Mobility L AGP 2x
+
+pci:v00001002d00004C50*
+ ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro
+
+pci:v00001002d00004C50sv00001002sd00004C50*
+ ID_PRODUCT_FROM_DATABASE=Rage LT Pro
+
+pci:v00001002d00004C51*
+ ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro
+
+pci:v00001002d00004C52*
+ ID_PRODUCT_FROM_DATABASE=Rage Mobility P/M
+
+pci:v00001002d00004C52sv00001033sd00008112*
+ ID_PRODUCT_FROM_DATABASE=Versa Note VXi
+
+pci:v00001002d00004C53*
+ ID_PRODUCT_FROM_DATABASE=Rage Mobility L
+
+pci:v00001002d00004C54*
+ ID_PRODUCT_FROM_DATABASE=264LT [Mach64 LT]
+
+pci:v00001002d00004C57*
+ ID_PRODUCT_FROM_DATABASE=RV200 [Mobility Radeon 7500]
+
+pci:v00001002d00004C57sv00001014sd00000517*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T30
+
+pci:v00001002d00004C57sv00001014sd00000530*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T42 2373-4WU
+
+pci:v00001002d00004C57sv00001028sd000000E6*
+ ID_PRODUCT_FROM_DATABASE=Radeon Mobility M7 LW (Dell Inspiron 8100)
+
+pci:v00001002d00004C57sv00001028sd0000012A*
+ ID_PRODUCT_FROM_DATABASE=Latitude C640
+
+pci:v00001002d00004C57sv00001043sd00001622*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon M7 (L3C/S)
+
+pci:v00001002d00004C57sv0000144Dsd0000C006*
+ ID_PRODUCT_FROM_DATABASE=Radeon Mobility M7 LW in vpr Matrix 170B4
+
+pci:v00001002d00004C58*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV200 LX [Mobility FireGL 7800 M7]
+
+pci:v00001002d00004C59*
+ ID_PRODUCT_FROM_DATABASE=RV100 LY [Mobility Radeon 7000]
+
+pci:v00001002d00004C59sv00000E11sd0000B111*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v00001002d00004C59sv00001014sd00000235*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A30/A30p (2652/2653)
+
+pci:v00001002d00004C59sv00001014sd00000239*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad X22/X23/X24
+
+pci:v00001002d00004C59sv0000103Csd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v00001002d00004C59sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00001002d00004C59sv0000104Dsd00008140*
+ ID_PRODUCT_FROM_DATABASE=PCG-Z1SP laptop
+
+pci:v00001002d00004C59sv00001509sd00001930*
+ ID_PRODUCT_FROM_DATABASE=Medion MD9703
+
+pci:v00001002d00004C5A*
+ ID_PRODUCT_FROM_DATABASE=RV100 LZ [Mobility Radeon 7000]
+
+pci:v00001002d00004C64*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV250 Ld [Radeon Mobility 9000 M9]
+
+pci:v00001002d00004C65*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV250 Le [Radeon Mobility 9000 M9]
+
+pci:v00001002d00004C66*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV250 [Mobility FireGL 9000]
+
+pci:v00001002d00004C66sv00001014sd0000054D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T41
+
+pci:v00001002d00004C67*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV250 Lg [Radeon Mobility 9000 M9]
+
+pci:v00001002d00004C6E*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV250 Ln [Radeon Mobility 9000 M9] (Secondary)
+
+pci:v00001002d00004D46*
+ ID_PRODUCT_FROM_DATABASE=Rage Mobility M4 AGP
+
+pci:v00001002d00004D4C*
+ ID_PRODUCT_FROM_DATABASE=Rage Mobility M4 AGP
+
+pci:v00001002d00004D52*
+ ID_PRODUCT_FROM_DATABASE=Theater 550 PRO PCI [ATI TV Wonder 550]
+
+pci:v00001002d00004D53*
+ ID_PRODUCT_FROM_DATABASE=Theater 550 PRO PCIe
+
+pci:v00001002d00004E44*
+ ID_PRODUCT_FROM_DATABASE=Radeon R300 ND [Radeon 9700 Pro]
+
+pci:v00001002d00004E44sv00001002sd0000515E*
+ ID_PRODUCT_FROM_DATABASE=Radeon ES1000
+
+pci:v00001002d00004E44sv00001002sd00005965*
+ ID_PRODUCT_FROM_DATABASE=Radeon ES1000
+
+pci:v00001002d00004E45*
+ ID_PRODUCT_FROM_DATABASE=Radeon R300 NE [Radeon 9500 Pro]
+
+pci:v00001002d00004E45sv00001002sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Radeon R300 NE [Radeon 9500 Pro]
+
+pci:v00001002d00004E45sv00001681sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro]
+
+pci:v00001002d00004E46*
+ ID_PRODUCT_FROM_DATABASE=R300 NF [Radeon 9600 TX]
+
+pci:v00001002d00004E47*
+ ID_PRODUCT_FROM_DATABASE=Radeon R300 NG [FireGL X1]
+
+pci:v00001002d00004E48*
+ ID_PRODUCT_FROM_DATABASE=Radeon R350 [Radeon 9800 Pro]
+
+pci:v00001002d00004E49*
+ ID_PRODUCT_FROM_DATABASE=Radeon R350 [Radeon 9800]
+
+pci:v00001002d00004E4A*
+ ID_PRODUCT_FROM_DATABASE=R360 NJ [Radeon 9800 XT]
+
+pci:v00001002d00004E4Asv00001002sd00004E4A*
+ ID_PRODUCT_FROM_DATABASE=R360 [Radeon 9800 XT]
+
+pci:v00001002d00004E4B*
+ ID_PRODUCT_FROM_DATABASE=R350 NK [FireGL X2]
+
+pci:v00001002d00004E50*
+ ID_PRODUCT_FROM_DATABASE=RV350 [Mobility Radeon 9600 M10]
+
+pci:v00001002d00004E50sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00001002d00004E50sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00001002d00004E50sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00001002d00004E50sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P35 notebook
+
+pci:v00001002d00004E50sv00001462sd00000311*
+ ID_PRODUCT_FROM_DATABASE=MSI M510A
+
+pci:v00001002d00004E50sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420W
+
+pci:v00001002d00004E51*
+ ID_PRODUCT_FROM_DATABASE=RV350 NQ [Mobility Radeon 9600]
+
+pci:v00001002d00004E52*
+ ID_PRODUCT_FROM_DATABASE=RV350 [Mobility Radeon 9600 M10]
+
+pci:v00001002d00004E52sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P35 notebook
+
+pci:v00001002d00004E53*
+ ID_PRODUCT_FROM_DATABASE=RV350 NS [Mobility Radeon 9600]
+
+pci:v00001002d00004E54*
+ ID_PRODUCT_FROM_DATABASE=M10 NT [FireGL Mobility T2]
+
+pci:v00001002d00004E56*
+ ID_PRODUCT_FROM_DATABASE=M11 NV [FireGL Mobility T2e]
+
+pci:v00001002d00004E64*
+ ID_PRODUCT_FROM_DATABASE=Radeon R300 [Radeon 9700 Pro] (Secondary)
+
+pci:v00001002d00004E65*
+ ID_PRODUCT_FROM_DATABASE=Radeon R300 [Radeon 9500 Pro] (Secondary)
+
+pci:v00001002d00004E65sv00001002sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Radeon R300 NE [Radeon 9500 Pro]
+
+pci:v00001002d00004E65sv00001681sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary)
+
+pci:v00001002d00004E66*
+ ID_PRODUCT_FROM_DATABASE=RV350 NF [Radeon 9600] (Secondary)
+
+pci:v00001002d00004E67*
+ ID_PRODUCT_FROM_DATABASE=Radeon R300 [FireGL X1] (Secondary)
+
+pci:v00001002d00004E68*
+ ID_PRODUCT_FROM_DATABASE=Radeon R350 [Radeon 9800 Pro] (Secondary)
+
+pci:v00001002d00004E69*
+ ID_PRODUCT_FROM_DATABASE=Radeon R350 [Radeon 9800] (Secondary)
+
+pci:v00001002d00004E6A*
+ ID_PRODUCT_FROM_DATABASE=RV350 NJ [Radeon 9800 XT] (Secondary)
+
+pci:v00001002d00004E6Asv00001002sd00004E6A*
+ ID_PRODUCT_FROM_DATABASE=R360 [Radeon 9800 XT] (Secondary)
+
+pci:v00001002d00004E6Asv00001002sd00004E71*
+ ID_PRODUCT_FROM_DATABASE=M10 NQ [Radeon Mobility 9600]
+
+pci:v00001002d00004E71*
+ ID_PRODUCT_FROM_DATABASE=M10 NQ [Radeon Mobility 9600] (Secondary)
+
+pci:v00001002d00004F72*
+ ID_PRODUCT_FROM_DATABASE=RV250 [Radeon 9000 Series]
+
+pci:v00001002d00004F73*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV250 [Radeon 9000 Series] (Secondary)
+
+pci:v00001002d00005041*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PA/PRO
+
+pci:v00001002d00005042*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PB/PRO AGP 2x
+
+pci:v00001002d00005043*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PC/PRO AGP 4x
+
+pci:v00001002d00005044*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PD/PRO TMDS
+
+pci:v00001002d00005044sv00001002sd00000028*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW
+
+pci:v00001002d00005044sv00001002sd00000029*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW
+
+pci:v00001002d00005045*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PE/PRO AGP 2x TMDS
+
+pci:v00001002d00005046*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PF/PRO AGP 4x TMDS
+
+pci:v00001002d00005046sv00001002sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury Pro
+
+pci:v00001002d00005046sv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro
+
+pci:v00001002d00005046sv00001002sd00000014*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury Pro
+
+pci:v00001002d00005046sv00001002sd00000018*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro
+
+pci:v00001002d00005046sv00001002sd00000028*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro AIW AGP
+
+pci:v00001002d00005046sv00001002sd0000002A*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro AIW AGP
+
+pci:v00001002d00005046sv00001002sd00000048*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury Pro
+
+pci:v00001002d00005046sv00001002sd00002000*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury MAXX AGP 4x (TMDS) (VGA device)
+
+pci:v00001002d00005046sv00001002sd00002001*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)
+
+pci:v00001002d00005047*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PG/PRO
+
+pci:v00001002d00005048*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PH/PRO AGP 2x
+
+pci:v00001002d00005049*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PI/PRO AGP 4x
+
+pci:v00001002d0000504A*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PJ/PRO TMDS
+
+pci:v00001002d0000504B*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PK/PRO AGP 2x TMDS
+
+pci:v00001002d0000504C*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PL/PRO AGP 4x TMDS
+
+pci:v00001002d0000504D*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PM/PRO
+
+pci:v00001002d0000504E*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PN/PRO AGP 2x
+
+pci:v00001002d0000504F*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PO/PRO AGP 4x
+
+pci:v00001002d00005050*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PP/PRO TMDS [Xpert 128]
+
+pci:v00001002d00005050sv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Xpert 128
+
+pci:v00001002d00005051*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PQ/PRO AGP 2x TMDS
+
+pci:v00001002d00005052*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PR/PRO AGP 4x TMDS
+
+pci:v00001002d00005053*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PS/PRO
+
+pci:v00001002d00005054*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PT/PRO AGP 2x
+
+pci:v00001002d00005055*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PU/PRO AGP 4x
+
+pci:v00001002d00005056*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PV/PRO TMDS
+
+pci:v00001002d00005057*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PW/PRO AGP 2x TMDS
+
+pci:v00001002d00005058*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 PX/PRO AGP 4x TMDS
+
+pci:v00001002d00005144*
+ ID_PRODUCT_FROM_DATABASE=Radeon R100 QD [Radeon 7200]
+
+pci:v00001002d00005144sv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE
+
+pci:v00001002d00005144sv00001002sd00000009*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd0000001A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd00000029*
+ ID_PRODUCT_FROM_DATABASE=Radeon AIW
+
+pci:v00001002d00005144sv00001002sd00000038*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd00000039*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd0000008A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd000000BA*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd0000028A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005144sv00001002sd000002AA*
+ ID_PRODUCT_FROM_DATABASE=Radeon AIW
+
+pci:v00001002d00005144sv00001002sd0000053A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon
+
+pci:v00001002d00005145*
+ ID_PRODUCT_FROM_DATABASE=Radeon R100 QE
+
+pci:v00001002d00005146*
+ ID_PRODUCT_FROM_DATABASE=Radeon R100 QF
+
+pci:v00001002d00005147*
+ ID_PRODUCT_FROM_DATABASE=Radeon R100 QG
+
+pci:v00001002d00005148*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QH [Radeon 8500]
+
+pci:v00001002d00005148sv00001002sd0000010A*
+ ID_PRODUCT_FROM_DATABASE=FireGL 8800 64Mb
+
+pci:v00001002d00005148sv00001002sd00000152*
+ ID_PRODUCT_FROM_DATABASE=FireGL 8800 128Mb
+
+pci:v00001002d00005148sv00001002sd00000162*
+ ID_PRODUCT_FROM_DATABASE=FireGL 8700 32Mb
+
+pci:v00001002d00005148sv00001002sd00000172*
+ ID_PRODUCT_FROM_DATABASE=FireGL 8700 64Mb
+
+pci:v00001002d00005149*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QI
+
+pci:v00001002d0000514A*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QJ
+
+pci:v00001002d0000514B*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QK
+
+pci:v00001002d0000514C*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QL [Radeon 8500 LE]
+
+pci:v00001002d0000514Csv00001002sd0000003A*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QL [Radeon 8500 LE]
+
+pci:v00001002d0000514Csv00001002sd0000013A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 8500
+
+pci:v00001002d0000514Csv0000148Csd00002026*
+ ID_PRODUCT_FROM_DATABASE=R200 QL [Radeon 8500 Evil Master II Multi Display Edition]
+
+pci:v00001002d0000514Csv00001681sd00000010*
+ ID_PRODUCT_FROM_DATABASE=Radeon 8500 [3D Prophet 8500 128Mb]
+
+pci:v00001002d0000514Csv0000174Bsd00007149*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QL [Sapphire Radeon 8500 LE]
+
+pci:v00001002d0000514Csv00001787sd00000F08*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QL [PowerMagic Radeon 8500]
+
+pci:v00001002d0000514D*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QM [Radeon 9100]
+
+pci:v00001002d0000514E*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QN [Radeon 8500LE]
+
+pci:v00001002d0000514F*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 QO [Radeon 8500LE]
+
+pci:v00001002d00005154*
+ ID_PRODUCT_FROM_DATABASE=R200 QT [Radeon 8500]
+
+pci:v00001002d00005155*
+ ID_PRODUCT_FROM_DATABASE=R200 QU [Radeon 9100]
+
+pci:v00001002d00005157*
+ ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500]
+
+pci:v00001002d00005157sv00001002sd0000013A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7500
+
+pci:v00001002d00005157sv00001002sd00000F2B*
+ ID_PRODUCT_FROM_DATABASE=ALL-IN-WONDER VE PCI
+
+pci:v00001002d00005157sv00001002sd0000103A*
+ ID_PRODUCT_FROM_DATABASE=Dell Optiplex GX260
+
+pci:v00001002d00005157sv00001458sd00004000*
+ ID_PRODUCT_FROM_DATABASE=RV200 QW [RADEON 7500 PRO MAYA AR]
+
+pci:v00001002d00005157sv0000148Csd00002024*
+ ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500LE Dual Display]
+
+pci:v00001002d00005157sv0000148Csd00002025*
+ ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500 Evil Master Multi Display Edition]
+
+pci:v00001002d00005157sv0000148Csd00002036*
+ ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500 PCI Dual Display]
+
+pci:v00001002d00005157sv0000174Bsd00007146*
+ ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500 LE]
+
+pci:v00001002d00005157sv0000174Bsd00007147*
+ ID_PRODUCT_FROM_DATABASE=RV200 QW [Sapphire Radeon 7500LE]
+
+pci:v00001002d00005157sv0000174Bsd00007161*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV200 QW [Radeon 7500 LE]
+
+pci:v00001002d00005157sv000017AFsd00000202*
+ ID_PRODUCT_FROM_DATABASE=RV200 QW [Excalibur Radeon 7500LE]
+
+pci:v00001002d00005158*
+ ID_PRODUCT_FROM_DATABASE=RV200 QX [Radeon 7500]
+
+pci:v00001002d00005159*
+ ID_PRODUCT_FROM_DATABASE=RV100 QY [Radeon 7000/VE]
+
+pci:v00001002d00005159sv00001002sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE
+
+pci:v00001002d00005159sv00001002sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000
+
+pci:v00001002d00005159sv00001002sd00000038*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE
+
+pci:v00001002d00005159sv00001002sd0000003A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE
+
+pci:v00001002d00005159sv00001002sd000000BA*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE
+
+pci:v00001002d00005159sv00001002sd0000013A*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE
+
+pci:v00001002d00005159sv00001002sd00000908*
+ ID_PRODUCT_FROM_DATABASE=XVR-100 (supplied by Sun)
+
+pci:v00001002d00005159sv00001014sd0000029A*
+ ID_PRODUCT_FROM_DATABASE=Remote Supervisor Adapter II (RSA2)
+
+pci:v00001002d00005159sv00001014sd000002C8*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00001002d00005159sv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 Embedded Radeon 7000/VE
+
+pci:v00001002d00005159sv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 Embedded Radeon 7000-M
+
+pci:v00001002d00005159sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Embedded Radeon 7000/VE
+
+pci:v00001002d00005159sv00001028sd0000019A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425
+
+pci:v00001002d00005159sv0000103Csd00001292*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000
+
+pci:v00001002d00005159sv00001043sd0000C00A*
+ ID_PRODUCT_FROM_DATABASE=A7000/T/64M
+
+pci:v00001002d00005159sv00001458sd00004002*
+ ID_PRODUCT_FROM_DATABASE=RV100 QY [RADEON 7000 PRO MAYA AV Series]
+
+pci:v00001002d00005159sv0000148Csd00002003*
+ ID_PRODUCT_FROM_DATABASE=RV100 QY [Radeon 7000 Multi-Display Edition]
+
+pci:v00001002d00005159sv0000148Csd00002023*
+ ID_PRODUCT_FROM_DATABASE=RV100 QY [Radeon 7000 Evil Master Multi-Display]
+
+pci:v00001002d00005159sv0000174Bsd00000280*
+ ID_PRODUCT_FROM_DATABASE=Radeon RV100 QY [Radeon 7000/VE]
+
+pci:v00001002d00005159sv0000174Bsd00007112*
+ ID_PRODUCT_FROM_DATABASE=RV100 QY [Sapphire Radeon VE 7000]
+
+pci:v00001002d00005159sv0000174Bsd00007C28*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon VE 7000 DDR
+
+pci:v00001002d00005159sv00001787sd00000202*
+ ID_PRODUCT_FROM_DATABASE=RV100 QY [Excalibur Radeon 7000]
+
+pci:v00001002d00005159sv000017EEsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Radeon 7000 64MB DDR + DVI
+
+pci:v00001002d0000515A*
+ ID_PRODUCT_FROM_DATABASE=RV100 QZ [Radeon 7000/VE]
+
+pci:v00001002d0000515E*
+ ID_PRODUCT_FROM_DATABASE=ES1000
+
+pci:v00001002d0000515Esv00001028sd000001BB*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00001002d0000515Esv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00001002d0000515Esv00001028sd000001F0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R900 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd0000020B*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T605 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd00000221*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd00000223*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R905 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv00001028sd0000023C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R200 Embedded ATI ES1000
+
+pci:v00001002d0000515Esv0000103Csd00001304*
+ ID_PRODUCT_FROM_DATABASE=Integrity iLO2 Advanced KVM VGA [AD307A]
+
+pci:v00001002d0000515Esv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00001002d0000515Esv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=S5000PSLSATA Server Board
+
+pci:v00001002d0000515F*
+ ID_PRODUCT_FROM_DATABASE=ES1000
+
+pci:v00001002d00005168*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 Qh
+
+pci:v00001002d00005169*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 Qi
+
+pci:v00001002d0000516A*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 Qj
+
+pci:v00001002d0000516B*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 Qk
+
+pci:v00001002d0000516C*
+ ID_PRODUCT_FROM_DATABASE=Radeon R200 Ql
+
+pci:v00001002d00005245*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 RE/SG
+
+pci:v00001002d00005245sv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Xpert 128
+
+pci:v00001002d00005245sv00001002sd00000028*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW
+
+pci:v00001002d00005245sv00001002sd00000029*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW
+
+pci:v00001002d00005245sv00001002sd00000068*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW
+
+pci:v00001002d00005246*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 RF/SG AGP
+
+pci:v00001002d00005246sv00001002sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Magnum/Xpert 128/Xpert 99
+
+pci:v00001002d00005246sv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Magnum/Xpert128/X99/Xpert2000
+
+pci:v00001002d00005246sv00001002sd00000028*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW AGP
+
+pci:v00001002d00005246sv00001002sd00000044*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000
+
+pci:v00001002d00005246sv00001002sd00000068*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW AGP
+
+pci:v00001002d00005246sv00001002sd00000448*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury
+
+pci:v00001002d00005247*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 RG
+
+pci:v00001002d0000524B*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 RK/VR
+
+pci:v00001002d0000524C*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 RL/VR AGP
+
+pci:v00001002d0000524Csv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Xpert 99/Xpert 2000
+
+pci:v00001002d0000524Csv00001002sd00000088*
+ ID_PRODUCT_FROM_DATABASE=Xpert 99
+
+pci:v00001002d00005345*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 SE/4x
+
+pci:v00001002d00005346*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 SF/4x AGP 2x
+
+pci:v00001002d00005346sv00001002sd00000048*
+ ID_PRODUCT_FROM_DATABASE=RAGE 128 16MB VGA TVOUT AMC PAL
+
+pci:v00001002d00005347*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 SG/4x AGP 4x
+
+pci:v00001002d00005348*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 SH
+
+pci:v00001002d0000534B*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 SK/4x
+
+pci:v00001002d0000534C*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 SL/4x AGP 2x
+
+pci:v00001002d0000534D*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 SM/4x AGP 4x
+
+pci:v00001002d0000534Dsv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Xpert 99/Xpert 2000
+
+pci:v00001002d0000534Dsv00001002sd00000018*
+ ID_PRODUCT_FROM_DATABASE=Xpert 2000
+
+pci:v00001002d0000534E*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 4x
+
+pci:v00001002d00005354*
+ ID_PRODUCT_FROM_DATABASE=Mach 64 VT
+
+pci:v00001002d00005354sv00001002sd00005654*
+ ID_PRODUCT_FROM_DATABASE=Mach 64 reference
+
+pci:v00001002d00005446*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TF
+
+pci:v00001002d00005446sv00001002sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury Pro
+
+pci:v00001002d00005446sv00001002sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro
+
+pci:v00001002d00005446sv00001002sd00000018*
+ ID_PRODUCT_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro
+
+pci:v00001002d00005446sv00001002sd00000028*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW Pro AGP
+
+pci:v00001002d00005446sv00001002sd00000029*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW
+
+pci:v00001002d00005446sv00001002sd0000002A*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW Pro AGP
+
+pci:v00001002d00005446sv00001002sd0000002B*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 AIW
+
+pci:v00001002d00005446sv00001002sd00000048*
+ ID_PRODUCT_FROM_DATABASE=Xpert 2000 Pro
+
+pci:v00001002d0000544C*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TL
+
+pci:v00001002d00005452*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TR
+
+pci:v00001002d00005452sv00001002sd0000001C*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro 4XL
+
+pci:v00001002d00005452sv0000103Csd00001279*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro 4XL
+
+pci:v00001002d00005453*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TS
+
+pci:v00001002d00005454*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TT
+
+pci:v00001002d00005455*
+ ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TU
+
+pci:v00001002d00005460*
+ ID_PRODUCT_FROM_DATABASE=RV370 [Mobility Radeon X300]
+
+pci:v00001002d00005460sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00001002d00005461*
+ ID_PRODUCT_FROM_DATABASE=RV370 [Mobility Radeon X300]
+
+pci:v00001002d00005462*
+ ID_PRODUCT_FROM_DATABASE=RV380 [Mobility Radeon X600]
+
+pci:v00001002d00005464*
+ ID_PRODUCT_FROM_DATABASE=RV370 [Mobility FireGL V3100]
+
+pci:v00001002d00005548*
+ ID_PRODUCT_FROM_DATABASE=R423 UH [Radeon X800 (PCIE)]
+
+pci:v00001002d00005549*
+ ID_PRODUCT_FROM_DATABASE=R423 UI [Radeon X800PRO (PCIE)]
+
+pci:v00001002d0000554A*
+ ID_PRODUCT_FROM_DATABASE=R423 UJ [Radeon X800LE (PCIE)]
+
+pci:v00001002d0000554B*
+ ID_PRODUCT_FROM_DATABASE=R423 UK [Radeon X800SE (PCIE)]
+
+pci:v00001002d0000554C*
+ ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800XTP PCIe]
+
+pci:v00001002d0000554D*
+ ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800 XL] (PCIe)
+
+pci:v00001002d0000554Dsv00001458sd00002124*
+ ID_PRODUCT_FROM_DATABASE=GV-R80L256V-B (AGP)
+
+pci:v00001002d0000554E*
+ ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800 SE PCIe]
+
+pci:v00001002d0000554F*
+ ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800 (PCIE)]
+
+pci:v00001002d00005550*
+ ID_PRODUCT_FROM_DATABASE=R423 [FireGL V7100]
+
+pci:v00001002d00005551*
+ ID_PRODUCT_FROM_DATABASE=R423 [FireGL V5100 (PCIE)]
+
+pci:v00001002d00005552*
+ ID_PRODUCT_FROM_DATABASE=R423 UR [FireGL V5100 (PCIE)]
+
+pci:v00001002d00005554*
+ ID_PRODUCT_FROM_DATABASE=R423 UT [FireGL V7100 (PCIE)]
+
+pci:v00001002d00005555*
+ ID_PRODUCT_FROM_DATABASE=R430 GL PRO
+
+pci:v00001002d00005569*
+ ID_PRODUCT_FROM_DATABASE=R423 UI [Radeon X800PRO (PCIE)] (Secondary)
+
+pci:v00001002d0000556B*
+ ID_PRODUCT_FROM_DATABASE=Radeon R423 UK (PCIE) [X800 SE] (Secondary)
+
+pci:v00001002d0000556D*
+ ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800 XL] (PCIe) (Secondary)
+
+pci:v00001002d0000556Dsv00001458sd00002125*
+ ID_PRODUCT_FROM_DATABASE=GV-R80L256V-B (AGP)
+
+pci:v00001002d0000556F*
+ ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800] (PCIE) (Secondary)
+
+pci:v00001002d00005571*
+ ID_PRODUCT_FROM_DATABASE=R423GL-SE [FireGL V5100 (PCIE)] (Secondary)
+
+pci:v00001002d0000564A*
+ ID_PRODUCT_FROM_DATABASE=M26 [Mobility FireGL V5000]
+
+pci:v00001002d0000564B*
+ ID_PRODUCT_FROM_DATABASE=M26 [Mobility FireGL V5000]
+
+pci:v00001002d0000564F*
+ ID_PRODUCT_FROM_DATABASE=M26 [Radeon Mobility X700 XL (PCIE)]
+
+pci:v00001002d00005652*
+ ID_PRODUCT_FROM_DATABASE=M26 [Radeon Mobility X700]
+
+pci:v00001002d00005653*
+ ID_PRODUCT_FROM_DATABASE=Radeon Mobility X700 (PCIE)
+
+pci:v00001002d00005653sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi
+
+pci:v00001002d00005653sv0000103Csd00000940*
+ ID_PRODUCT_FROM_DATABASE=HP Compaq NW8240 Mobile Workstation
+
+pci:v00001002d00005654*
+ ID_PRODUCT_FROM_DATABASE=264VT [Mach64 VT]
+
+pci:v00001002d00005654sv00001002sd00005654*
+ ID_PRODUCT_FROM_DATABASE=Mach64VT Reference
+
+pci:v00001002d00005655*
+ ID_PRODUCT_FROM_DATABASE=264VT3 [Mach64 VT3]
+
+pci:v00001002d00005656*
+ ID_PRODUCT_FROM_DATABASE=264VT4 [Mach64 VT4]
+
+pci:v00001002d00005657*
+ ID_PRODUCT_FROM_DATABASE=Radeon X550/X700 Series (RV410)
+
+pci:v00001002d00005830*
+ ID_PRODUCT_FROM_DATABASE=RS300 Host Bridge
+
+pci:v00001002d00005831*
+ ID_PRODUCT_FROM_DATABASE=RS300 Host Bridge
+
+pci:v00001002d00005832*
+ ID_PRODUCT_FROM_DATABASE=RS300 Host Bridge
+
+pci:v00001002d00005833*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9100 IGP Host Bridge
+
+pci:v00001002d00005834*
+ ID_PRODUCT_FROM_DATABASE=RS300 [Radeon 9100 IGP]
+
+pci:v00001002d00005835*
+ ID_PRODUCT_FROM_DATABASE=RS300M AGP [Radeon Mobility 9100IGP]
+
+pci:v00001002d00005838*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9100 IGP AGP Bridge
+
+pci:v00001002d00005854*
+ ID_PRODUCT_FROM_DATABASE=Radeon Xpress Series (RS480)
+
+pci:v00001002d00005874*
+ ID_PRODUCT_FROM_DATABASE=Radeon Xpress Series (RS482)
+
+pci:v00001002d00005940*
+ ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 PRO] (Secondary)
+
+pci:v00001002d00005940sv000017AFsd00002021*
+ ID_PRODUCT_FROM_DATABASE=Excalibur Radeon 9250 (Secondary)
+
+pci:v00001002d00005941*
+ ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200] (Secondary)
+
+pci:v00001002d00005941sv00001458sd00004019*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte Radeon 9200
+
+pci:v00001002d00005941sv0000174Bsd00007C12*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200
+
+pci:v00001002d00005941sv000017AFsd0000200D*
+ ID_PRODUCT_FROM_DATABASE=Excalibur Radeon 9200
+
+pci:v00001002d00005941sv000018BCsd00000050*
+ ID_PRODUCT_FROM_DATABASE=GeXcube GC-R9200-C3 (Secondary)
+
+pci:v00001002d00005944*
+ ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 SE (PCI)]
+
+pci:v00001002d00005950*
+ ID_PRODUCT_FROM_DATABASE=RS480 Host Bridge
+
+pci:v00001002d00005950sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi
+
+pci:v00001002d00005950sv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00005950sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001002d00005950sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00005950sv00001462sd00000131*
+ ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook
+
+pci:v00001002d00005950sv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00005951*
+ ID_PRODUCT_FROM_DATABASE=Radeon Xpress 200 (RS480/RS482/RX480/RX482) Chipset - Host bridge
+
+pci:v00001002d00005952*
+ ID_PRODUCT_FROM_DATABASE=RD580 [CrossFire Xpress 3200] Chipset Host Bridge
+
+pci:v00001002d00005954*
+ ID_PRODUCT_FROM_DATABASE=RS480 [Radeon Xpress 200G Series]
+
+pci:v00001002d00005954sv00001002sd00005954*
+ ID_PRODUCT_FROM_DATABASE=RV370 [Radeon Xpress 200G Series]
+
+pci:v00001002d00005955*
+ ID_PRODUCT_FROM_DATABASE=Radeon XPRESS 200M 5955 (PCIE)
+
+pci:v00001002d00005955sv00001002sd00005955*
+ ID_PRODUCT_FROM_DATABASE=RS480 0x5955 [Radeon XPRESS 200M 5955 (PCIE)]
+
+pci:v00001002d00005955sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v00001002d00005955sv00001462sd00000131*
+ ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook
+
+pci:v00001002d00005956*
+ ID_PRODUCT_FROM_DATABASE=RD790 Northbridge only dual slot PCI-e_GFX and HT3 K8 part
+
+pci:v00001002d00005957*
+ ID_PRODUCT_FROM_DATABASE=RX780/RX790 Chipset Host Bridge
+
+pci:v00001002d00005957sv00001849sd00005957*
+ ID_PRODUCT_FROM_DATABASE=A770CrossFire Motherboard
+
+pci:v00001002d00005958*
+ ID_PRODUCT_FROM_DATABASE=RD780 Northbridge only dual slot PCI-e_GFX and HT1 K8 part
+
+pci:v00001002d00005960*
+ ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 PRO]
+
+pci:v00001002d00005960sv000017AFsd00002020*
+ ID_PRODUCT_FROM_DATABASE=Excalibur Radeon 9250
+
+pci:v00001002d00005961*
+ ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200]
+
+pci:v00001002d00005961sv00001002sd00002F72*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 9200 Series
+
+pci:v00001002d00005961sv00001019sd00004C30*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 VIVO
+
+pci:v00001002d00005961sv000012ABsd00005961*
+ ID_PRODUCT_FROM_DATABASE=YUAN SMARTVGA Radeon 9200
+
+pci:v00001002d00005961sv00001458sd00004018*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte Radeon 9200
+
+pci:v00001002d00005961sv0000174Bsd00007C13*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200
+
+pci:v00001002d00005961sv000017AFsd0000200C*
+ ID_PRODUCT_FROM_DATABASE=Excalibur Radeon 9200
+
+pci:v00001002d00005961sv000018BCsd00000050*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 Game Buster
+
+pci:v00001002d00005961sv000018BCsd00000051*
+ ID_PRODUCT_FROM_DATABASE=GeXcube GC-R9200-C3
+
+pci:v00001002d00005961sv000018BCsd00000053*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 Game Buster VIVO
+
+pci:v00001002d00005962*
+ ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200]
+
+pci:v00001002d00005964*
+ ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 SE]
+
+pci:v00001002d00005964sv00001002sd00005964*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE, 64-bit 128MB DDR, 200/166MHz
+
+pci:v00001002d00005964sv00001043sd0000C006*
+ ID_PRODUCT_FROM_DATABASE=ASUS Radeon 9200 SE / TD / 128M
+
+pci:v00001002d00005964sv00001458sd00004018*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE
+
+pci:v00001002d00005964sv00001458sd00004032*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE 128MB
+
+pci:v00001002d00005964sv0000147Bsd00006191*
+ ID_PRODUCT_FROM_DATABASE=R9200SE-DT
+
+pci:v00001002d00005964sv0000148Csd00002073*
+ ID_PRODUCT_FROM_DATABASE=CN-AG92E
+
+pci:v00001002d00005964sv0000174Bsd00007C13*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200 SE
+
+pci:v00001002d00005964sv00001787sd00005964*
+ ID_PRODUCT_FROM_DATABASE=Excalibur 9200SE VIVO 128M
+
+pci:v00001002d00005964sv000017AFsd00002012*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE Excalibur
+
+pci:v00001002d00005964sv000018BCsd00000170*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200 SE 128MB Game Buster
+
+pci:v00001002d00005964sv000018BCsd00000173*
+ ID_PRODUCT_FROM_DATABASE=GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
+
+pci:v00001002d00005965*
+ ID_PRODUCT_FROM_DATABASE=RV280 [FireMV 2200 PCI]
+
+pci:v00001002d00005969*
+ ID_PRODUCT_FROM_DATABASE=ES1000
+
+pci:v00001002d00005974*
+ ID_PRODUCT_FROM_DATABASE=RS482 [Radeon Xpress 200]
+
+pci:v00001002d00005974sv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v00001002d00005974sv00001462sd00007141*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00005975*
+ ID_PRODUCT_FROM_DATABASE=RS482 [Radeon Xpress 200M]
+
+pci:v00001002d00005978*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx0 port A)
+
+pci:v00001002d00005978sv00001849sd00005957*
+ ID_PRODUCT_FROM_DATABASE=A770CrossFire Motherboard
+
+pci:v00001002d00005979*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx0 port B)
+
+pci:v00001002d0000597A*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port A)
+
+pci:v00001002d0000597B*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port B)
+
+pci:v00001002d0000597C*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port C)
+
+pci:v00001002d0000597D*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port D)
+
+pci:v00001002d0000597E*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port E)
+
+pci:v00001002d0000597Esv00001849sd00005957*
+ ID_PRODUCT_FROM_DATABASE=A770CrossFire Motherboard
+
+pci:v00001002d0000597F*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port F)
+
+pci:v00001002d0000597Fsv00001849sd00005957*
+ ID_PRODUCT_FROM_DATABASE=A770CrossFire Motherboard
+
+pci:v00001002d00005980*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx1 port A)
+
+pci:v00001002d00005981*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx1 port B)
+
+pci:v00001002d00005982*
+ ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (NB-SB link)
+
+pci:v00001002d00005A10*
+ ID_PRODUCT_FROM_DATABASE=RD890 Northbridge only dual slot (2x16) PCI-e GFX Hydra part
+
+pci:v00001002d00005A11*
+ ID_PRODUCT_FROM_DATABASE=RD890 Northbridge only single slot PCI-e GFX Hydra part
+
+pci:v00001002d00005A12*
+ ID_PRODUCT_FROM_DATABASE=RD890 Northbridge only dual slot (2x8) PCI-e GFX Hydra part
+
+pci:v00001002d00005A12sv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v00001002d00005A13*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx0 port A)
+
+pci:v00001002d00005A14*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx0 port B)
+
+pci:v00001002d00005A15*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port A)
+
+pci:v00001002d00005A16*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port B)
+
+pci:v00001002d00005A17*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port C)
+
+pci:v00001002d00005A18*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port D)
+
+pci:v00001002d00005A18sv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v00001002d00005A19*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port E)
+
+pci:v00001002d00005A1A*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port F)
+
+pci:v00001002d00005A1B*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port G)
+
+pci:v00001002d00005A1C*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port H)
+
+pci:v00001002d00005A1D*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx1 port A)
+
+pci:v00001002d00005A1E*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx1 port B)
+
+pci:v00001002d00005A1F*
+ ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (NB-SB link)
+
+pci:v00001002d00005A1Fsv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v00001002d00005A20*
+ ID_PRODUCT_FROM_DATABASE=RD890S PCI Express bridge for GPP2 port 1
+
+pci:v00001002d00005A23*
+ ID_PRODUCT_FROM_DATABASE=RD990 I/O Memory Management Unit (IOMMU)
+
+pci:v00001002d00005A33*
+ ID_PRODUCT_FROM_DATABASE=Radeon Xpress 200 Host Bridge
+
+pci:v00001002d00005A34*
+ ID_PRODUCT_FROM_DATABASE=RS480 PCI-X Root Port
+
+pci:v00001002d00005A36*
+ ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge
+
+pci:v00001002d00005A37*
+ ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge
+
+pci:v00001002d00005A38*
+ ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge
+
+pci:v00001002d00005A39*
+ ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge
+
+pci:v00001002d00005A3F*
+ ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge
+
+pci:v00001002d00005A3Fsv00001462sd00007217*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001002d00005A41*
+ ID_PRODUCT_FROM_DATABASE=RS400 [Radeon Xpress 200]
+
+pci:v00001002d00005A42*
+ ID_PRODUCT_FROM_DATABASE=RS400 [Radeon Xpress 200M]
+
+pci:v00001002d00005A43*
+ ID_PRODUCT_FROM_DATABASE=Radeon Xpress Series (RS400)
+
+pci:v00001002d00005A61*
+ ID_PRODUCT_FROM_DATABASE=RC410 [Radeon Xpress 200]
+
+pci:v00001002d00005A62*
+ ID_PRODUCT_FROM_DATABASE=RC410 [Radeon Xpress 200M]
+
+pci:v00001002d00005A63*
+ ID_PRODUCT_FROM_DATABASE=Radeon Xpress Series (RC410)
+
+pci:v00001002d00005B60*
+ ID_PRODUCT_FROM_DATABASE=RV370 5B60 [Radeon X300 (PCIE)]
+
+pci:v00001002d00005B60sv00001043sd0000002A*
+ ID_PRODUCT_FROM_DATABASE=Extreme AX300SE-X
+
+pci:v00001002d00005B60sv00001043sd0000032E*
+ ID_PRODUCT_FROM_DATABASE=Extreme AX300/TD
+
+pci:v00001002d00005B60sv00001458sd00002102*
+ ID_PRODUCT_FROM_DATABASE=GV-RX30S128D (X300SE)
+
+pci:v00001002d00005B60sv00001462sd00000400*
+ ID_PRODUCT_FROM_DATABASE=RX300SE-TD128E (MS-8940 REV:200)
+
+pci:v00001002d00005B60sv00001462sd00000402*
+ ID_PRODUCT_FROM_DATABASE=RX300SE-TD128E (MS-8940)
+
+pci:v00001002d00005B60sv0000174Bsd00000500*
+ ID_PRODUCT_FROM_DATABASE=Radeon X300 (PCIE)
+
+pci:v00001002d00005B60sv0000196Dsd00001086*
+ ID_PRODUCT_FROM_DATABASE=X300SE HM
+
+pci:v00001002d00005B62*
+ ID_PRODUCT_FROM_DATABASE=RV380 [Radeon X600 (PCIE)]
+
+pci:v00001002d00005B63*
+ ID_PRODUCT_FROM_DATABASE=RV370 [Radeon X550]
+
+pci:v00001002d00005B64*
+ ID_PRODUCT_FROM_DATABASE=RV370 5B64 [FireGL V3100 (PCIE)]
+
+pci:v00001002d00005B65*
+ ID_PRODUCT_FROM_DATABASE=RV370 5B65 [FireGL D1100 (PCIE)]
+
+pci:v00001002d00005B66*
+ ID_PRODUCT_FROM_DATABASE=RV370X
+
+pci:v00001002d00005B70*
+ ID_PRODUCT_FROM_DATABASE=RV370 [Radeon X300SE]
+
+pci:v00001002d00005B70sv00001462sd00000403*
+ ID_PRODUCT_FROM_DATABASE=RX300SE-TD128E (MS-8940) (secondary display)
+
+pci:v00001002d00005B70sv0000174Bsd00000501*
+ ID_PRODUCT_FROM_DATABASE=Radeon X300SE
+
+pci:v00001002d00005B70sv0000196Dsd00001087*
+ ID_PRODUCT_FROM_DATABASE=X300SE HM
+
+pci:v00001002d00005B72*
+ ID_PRODUCT_FROM_DATABASE=RV380 [Radeon X600]
+
+pci:v00001002d00005B73*
+ ID_PRODUCT_FROM_DATABASE=RV370 secondary [Sapphire X550 Silent]
+
+pci:v00001002d00005B74*
+ ID_PRODUCT_FROM_DATABASE=RV370 5B64 [FireGL V3100 (PCIE)] (Secondary)
+
+pci:v00001002d00005B75*
+ ID_PRODUCT_FROM_DATABASE=RV370 5B75 [FireGL D1100 (PCIE)] (Secondary)
+
+pci:v00001002d00005C61*
+ ID_PRODUCT_FROM_DATABASE=M9+ 5C61 [Radeon Mobility 9200 (AGP)]
+
+pci:v00001002d00005C63*
+ ID_PRODUCT_FROM_DATABASE=M9+ 5C63 [Radeon Mobility 9200 (AGP)]
+
+pci:v00001002d00005C63sv00001002sd00005C63*
+ ID_PRODUCT_FROM_DATABASE=Apple iBook G4 2004
+
+pci:v00001002d00005C63sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30 notebook
+
+pci:v00001002d00005D44*
+ ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary)
+
+pci:v00001002d00005D44sv00001458sd00004019*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE (Secondary)
+
+pci:v00001002d00005D44sv00001458sd00004032*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE 128MB
+
+pci:v00001002d00005D44sv0000147Bsd00006190*
+ ID_PRODUCT_FROM_DATABASE=R9200SE-DT (Secondary)
+
+pci:v00001002d00005D44sv0000174Bsd00007C12*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200 SE (Secondary)
+
+pci:v00001002d00005D44sv00001787sd00005965*
+ ID_PRODUCT_FROM_DATABASE=Excalibur 9200SE VIVO 128M (Secondary)
+
+pci:v00001002d00005D44sv000017AFsd00002013*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE Excalibur (Secondary)
+
+pci:v00001002d00005D44sv000018BCsd00000171*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE 128MB Game Buster (Secondary)
+
+pci:v00001002d00005D44sv000018BCsd00000172*
+ ID_PRODUCT_FROM_DATABASE=GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
+
+pci:v00001002d00005D45*
+ ID_PRODUCT_FROM_DATABASE=RV280 [FireMV 2200 PCI] (secondary)
+
+pci:v00001002d00005D48*
+ ID_PRODUCT_FROM_DATABASE=M28 [Radeon Mobility X800XT]
+
+pci:v00001002d00005D49*
+ ID_PRODUCT_FROM_DATABASE=M28 [Mobility FireGL V5100]
+
+pci:v00001002d00005D4A*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon X800
+
+pci:v00001002d00005D4C*
+ ID_PRODUCT_FROM_DATABASE=Radeon X850 (PCIE)
+
+pci:v00001002d00005D4D*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT Platinum (PCIE)]
+
+pci:v00001002d00005D4E*
+ ID_PRODUCT_FROM_DATABASE=Radeon X850 SE (R480) (PCIE)
+
+pci:v00001002d00005D4F*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X800 GTO (PCIE)]
+
+pci:v00001002d00005D50*
+ ID_PRODUCT_FROM_DATABASE=R480 [FireGL V7200 (PCIE)]
+
+pci:v00001002d00005D51*
+ ID_PRODUCT_FROM_DATABASE=R480 GL 12P
+
+pci:v00001002d00005D52*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT (PCIE)] (Primary)
+
+pci:v00001002d00005D52sv00001002sd00000B12*
+ ID_PRODUCT_FROM_DATABASE=PowerColor X850XT PCIe (Primary)
+
+pci:v00001002d00005D52sv00001002sd00000B13*
+ ID_PRODUCT_FROM_DATABASE=PowerColor X850XT PCIe (Secondary)
+
+pci:v00001002d00005D57*
+ ID_PRODUCT_FROM_DATABASE=R423 5F57 [Radeon X800XT (PCIE)]
+
+pci:v00001002d00005D6D*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT Platinum (PCIE)] (Secondary)
+
+pci:v00001002d00005D6F*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X800 GTO (PCIE)] (Secondary)
+
+pci:v00001002d00005D72*
+ ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT (PCIE)] (Secondary)
+
+pci:v00001002d00005D77*
+ ID_PRODUCT_FROM_DATABASE=R423 5F57 [Radeon X800XT (PCIE)] (Secondary)
+
+pci:v00001002d00005E48*
+ ID_PRODUCT_FROM_DATABASE=RV410 [FireGL V5000]
+
+pci:v00001002d00005E49*
+ ID_PRODUCT_FROM_DATABASE=RV410 [FireGL V3300]
+
+pci:v00001002d00005E4A*
+ ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700XT]
+
+pci:v00001002d00005E4B*
+ ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700 Pro (PCIE)]
+
+pci:v00001002d00005E4C*
+ ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700SE]
+
+pci:v00001002d00005E4D*
+ ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700 (PCIE)]
+
+pci:v00001002d00005E4Dsv0000148Csd00002116*
+ ID_PRODUCT_FROM_DATABASE=PowerColor Bravo X700
+
+pci:v00001002d00005E4F*
+ ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700]
+
+pci:v00001002d00005E6B*
+ ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700 Pro (PCIE)] (Secondary)
+
+pci:v00001002d00005E6D*
+ ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700 (PCIE)] (Secondary)
+
+pci:v00001002d00005E6Dsv0000148Csd00002117*
+ ID_PRODUCT_FROM_DATABASE=PowerColor Bravo X700
+
+pci:v00001002d00005F57*
+ ID_PRODUCT_FROM_DATABASE=R423 [Radeon X800XT (PCIE)]
+
+pci:v00001002d00006600*
+ ID_PRODUCT_FROM_DATABASE=Mars [Radeon HD 8600/8700M Series]
+
+pci:v00001002d00006601*
+ ID_PRODUCT_FROM_DATABASE=Mars [Radeon HD 8500/8700M Series]
+
+pci:v00001002d00006606*
+ ID_PRODUCT_FROM_DATABASE=Mars [Radeon HD 8790M]
+
+pci:v00001002d00006610*
+ ID_PRODUCT_FROM_DATABASE=Oland [Radeon HD 8600 Series]
+
+pci:v00001002d00006611*
+ ID_PRODUCT_FROM_DATABASE=Oland [Radeon HD 8500 Series]
+
+pci:v00001002d00006704*
+ ID_PRODUCT_FROM_DATABASE=Cayman PRO GL [FirePro V7900]
+
+pci:v00001002d00006707*
+ ID_PRODUCT_FROM_DATABASE=Cayman LE GL [FirePro V5900]
+
+pci:v00001002d00006718*
+ ID_PRODUCT_FROM_DATABASE=Cayman XT [Radeon HD 6970]
+
+pci:v00001002d00006719*
+ ID_PRODUCT_FROM_DATABASE=Cayman PRO [Radeon HD 6950]
+
+pci:v00001002d0000671D*
+ ID_PRODUCT_FROM_DATABASE=Antilles [AMD Radeon HD 6990]
+
+pci:v00001002d0000671F*
+ ID_PRODUCT_FROM_DATABASE=Cayman [Radeon HD 6900 Series]
+
+pci:v00001002d00006720*
+ ID_PRODUCT_FROM_DATABASE=Blackcomb [Radeon HD 6900M series]
+
+pci:v00001002d00006738*
+ ID_PRODUCT_FROM_DATABASE=Barts XT [Radeon HD 6800 Series]
+
+pci:v00001002d00006739*
+ ID_PRODUCT_FROM_DATABASE=Barts PRO [Radeon HD 6800 Series]
+
+pci:v00001002d00006739sv00001043sd000003B4*
+ ID_PRODUCT_FROM_DATABASE=EAH6850 [Radeon HD 6850]
+
+pci:v00001002d0000673E*
+ ID_PRODUCT_FROM_DATABASE=Barts LE [AMD Radeon HD 6700 Series]
+
+pci:v00001002d00006740*
+ ID_PRODUCT_FROM_DATABASE=Whistler XT [AMD Radeon HD 6700M Series]
+
+pci:v00001002d00006741*
+ ID_PRODUCT_FROM_DATABASE=Whistler [AMD Radeon HD 6600M Series]
+
+pci:v00001002d00006741sv0000106Bsd000000E2*
+ ID_PRODUCT_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", Late 2011]
+
+pci:v00001002d00006742*
+ ID_PRODUCT_FROM_DATABASE=Whistler LE [AMD Radeon HD 6625M Graphics]
+
+pci:v00001002d00006743*
+ ID_PRODUCT_FROM_DATABASE=Whistler [Radeon E6760]
+
+pci:v00001002d00006749*
+ ID_PRODUCT_FROM_DATABASE=Turks [FirePro V4900]
+
+pci:v00001002d0000674A*
+ ID_PRODUCT_FROM_DATABASE=Turks [AMD FirePro V3900]
+
+pci:v00001002d00006750*
+ ID_PRODUCT_FROM_DATABASE=Turks [AMD Radeon HD 6570]
+
+pci:v00001002d00006751*
+ ID_PRODUCT_FROM_DATABASE=Turks [Radeon HD 7600A Series]
+
+pci:v00001002d00006758*
+ ID_PRODUCT_FROM_DATABASE=Turks [Radeon HD 6670]
+
+pci:v00001002d00006759*
+ ID_PRODUCT_FROM_DATABASE=Turks [Radeon HD 6570]
+
+pci:v00001002d0000675D*
+ ID_PRODUCT_FROM_DATABASE=Turks [Radeon HD 7500 Series]
+
+pci:v00001002d00006760*
+ ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 6400M/7400M Series]
+
+pci:v00001002d00006760sv00001028sd000004CC*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00001002d00006761*
+ ID_PRODUCT_FROM_DATABASE=Seymour LP [Radeon HD 6430M]
+
+pci:v00001002d00006763*
+ ID_PRODUCT_FROM_DATABASE=Seymour [Radeon E6460]
+
+pci:v00001002d00006770*
+ ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 6400 Series]
+
+pci:v00001002d00006772*
+ ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 7400A Series]
+
+pci:v00001002d00006778*
+ ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 7000 Series]
+
+pci:v00001002d00006779*
+ ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 6450]
+
+pci:v00001002d00006779sv0000174Bsd0000E164*
+ ID_PRODUCT_FROM_DATABASE=Sapphire HD 6450 1GB DDR3
+
+pci:v00001002d0000677B*
+ ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 7400 Series]
+
+pci:v00001002d00006798*
+ ID_PRODUCT_FROM_DATABASE=Tahiti XT [Radeon HD 7970]
+
+pci:v00001002d00006799*
+ ID_PRODUCT_FROM_DATABASE=New Zealand [Radeon HD 7990]
+
+pci:v00001002d0000679A*
+ ID_PRODUCT_FROM_DATABASE=Tahiti PRO [Radeon HD 7950]
+
+pci:v00001002d0000679E*
+ ID_PRODUCT_FROM_DATABASE=Tahiti LE [Radeon HD 7800 Series]
+
+pci:v00001002d00006800*
+ ID_PRODUCT_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M]
+
+pci:v00001002d00006818*
+ ID_PRODUCT_FROM_DATABASE=Pitcairn [Radeon HD 7800]
+
+pci:v00001002d00006819*
+ ID_PRODUCT_FROM_DATABASE=Pitcairn PRO [Radeon HD 7800]
+
+pci:v00001002d00006820*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 8800M Series
+
+pci:v00001002d00006821*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 8800M Series
+
+pci:v00001002d00006823*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 8800M Series
+
+pci:v00001002d00006825*
+ ID_PRODUCT_FROM_DATABASE=Cape Verde [Radeon HD 7800M Series]
+
+pci:v00001002d0000682B*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 8800M Series
+
+pci:v00001002d0000682F*
+ ID_PRODUCT_FROM_DATABASE=Cape Verde [Radeon HD 7700M Series]
+
+pci:v00001002d0000683B*
+ ID_PRODUCT_FROM_DATABASE=Cape Verde [Radeon HD 7700 Series]
+
+pci:v00001002d0000683D*
+ ID_PRODUCT_FROM_DATABASE=Cape Verde [Radeon HD 7700 Series]
+
+pci:v00001002d0000683F*
+ ID_PRODUCT_FROM_DATABASE=Cape Verde PRO [Radeon HD 7700 Series]
+
+pci:v00001002d00006840*
+ ID_PRODUCT_FROM_DATABASE=Thames XT/GL [Radeon HD 7600M Series]
+
+pci:v00001002d00006841*
+ ID_PRODUCT_FROM_DATABASE=Thames [Radeon 7500M/7600M Series]
+
+pci:v00001002d00006842*
+ ID_PRODUCT_FROM_DATABASE=Thames LE [Radeon HD 7000M Series]
+
+pci:v00001002d00006843*
+ ID_PRODUCT_FROM_DATABASE=Thames [Radeon HD 7670M]
+
+pci:v00001002d00006850*
+ ID_PRODUCT_FROM_DATABASE=Lombok GL AIO [Radeon HD 7570]
+
+pci:v00001002d00006858*
+ ID_PRODUCT_FROM_DATABASE=Lombok [Radeon HD 7400 series]
+
+pci:v00001002d00006888*
+ ID_PRODUCT_FROM_DATABASE=Cypress [FirePro 3D V8800]
+
+pci:v00001002d00006889*
+ ID_PRODUCT_FROM_DATABASE=Cypress [FirePro V7800]
+
+pci:v00001002d0000688A*
+ ID_PRODUCT_FROM_DATABASE=Cypress XT [FirePro 3D V9800]
+
+pci:v00001002d0000688C*
+ ID_PRODUCT_FROM_DATABASE=Cypress [AMD FireStream 9370]
+
+pci:v00001002d0000688D*
+ ID_PRODUCT_FROM_DATABASE=Cypress [AMD FireStream 9350]
+
+pci:v00001002d00006898*
+ ID_PRODUCT_FROM_DATABASE=Cypress XT [Radeon HD 5870]
+
+pci:v00001002d00006898sv00001462sd00008032*
+ ID_PRODUCT_FROM_DATABASE=R5870 PM2D1G
+
+pci:v00001002d00006899*
+ ID_PRODUCT_FROM_DATABASE=Cypress PRO [Radeon HD 5800 Series]
+
+pci:v00001002d00006899sv00001043sd00000330*
+ ID_PRODUCT_FROM_DATABASE=EAH5850 [Radeon HD5850]
+
+pci:v00001002d0000689B*
+ ID_PRODUCT_FROM_DATABASE=Cypress [Radeon HD 6800 Series]
+
+pci:v00001002d0000689C*
+ ID_PRODUCT_FROM_DATABASE=Hemlock [Radeon HD 5900 Series]
+
+pci:v00001002d0000689E*
+ ID_PRODUCT_FROM_DATABASE=Cypress LE [Radeon HD 5800 Series]
+
+pci:v00001002d000068A0*
+ ID_PRODUCT_FROM_DATABASE=Broadway XT [Mobility Radeon HD 5800 Series]
+
+pci:v00001002d000068A0sv0000103Csd00001520*
+ ID_PRODUCT_FROM_DATABASE=Broadway XT [FirePro M7820]
+
+pci:v00001002d000068A1*
+ ID_PRODUCT_FROM_DATABASE=Broadway PRO [Mobility Radeon HD 5800 Series]
+
+pci:v00001002d000068A8*
+ ID_PRODUCT_FROM_DATABASE=Broadway [ATI Mobility Radeon HD 6800 Series]
+
+pci:v00001002d000068A9*
+ ID_PRODUCT_FROM_DATABASE=Juniper XT [FirePro 3D V5800]
+
+pci:v00001002d000068B8*
+ ID_PRODUCT_FROM_DATABASE=Juniper [Radeon HD 5700 Series]
+
+pci:v00001002d000068B8sv0000106Bsd000000CF*
+ ID_PRODUCT_FROM_DATABASE=MacPro5,1 [Mac Pro 2.8GHz DDR3]
+
+pci:v00001002d000068B9*
+ ID_PRODUCT_FROM_DATABASE=Juniper [Radeon HD 5600/5700]
+
+pci:v00001002d000068BA*
+ ID_PRODUCT_FROM_DATABASE=Juniper XT [AMD Radeon HD 6000 Series]
+
+pci:v00001002d000068BE*
+ ID_PRODUCT_FROM_DATABASE=Juniper [Radeon HD 5700 Series]
+
+pci:v00001002d000068BF*
+ ID_PRODUCT_FROM_DATABASE=Juniper LE [Radeon HD 6700 Series]
+
+pci:v00001002d000068C0*
+ ID_PRODUCT_FROM_DATABASE=Madison [Mobility Radeon HD 5000 Series]
+
+pci:v00001002d000068C0sv0000103Csd00001521*
+ ID_PRODUCT_FROM_DATABASE=Madison XT [FirePro M5800]
+
+pci:v00001002d000068C1*
+ ID_PRODUCT_FROM_DATABASE=Madison [Radeon HD 5000M Series]
+
+pci:v00001002d000068C1sv00001025sd0000033D*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 5650
+
+pci:v00001002d000068C1sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00001002d000068C1sv0000103Csd00001521*
+ ID_PRODUCT_FROM_DATABASE=Madison Pro [FirePro M5800]
+
+pci:v00001002d000068C7*
+ ID_PRODUCT_FROM_DATABASE=Pinewood [Radeon HD 5570]
+
+pci:v00001002d000068C8*
+ ID_PRODUCT_FROM_DATABASE=FirePro V4800
+
+pci:v00001002d000068D8*
+ ID_PRODUCT_FROM_DATABASE=Redwood [Radeon HD 5670]
+
+pci:v00001002d000068D9*
+ ID_PRODUCT_FROM_DATABASE=Redwood PRO [Radeon HD 5500 Series]
+
+pci:v00001002d000068DA*
+ ID_PRODUCT_FROM_DATABASE=Redwood PRO [Radeon HD 5500 Series]
+
+pci:v00001002d000068E0*
+ ID_PRODUCT_FROM_DATABASE=Manhattan [Mobility Radeon HD 5400 Series]
+
+pci:v00001002d000068E0sv0000103Csd00001486*
+ ID_PRODUCT_FROM_DATABASE=TouchSmart tm2-2050er discrete GPU (Mobility Radeon HD 5450)
+
+pci:v00001002d000068E1*
+ ID_PRODUCT_FROM_DATABASE=Manhattan [Mobility Radeon HD 5430 Series]
+
+pci:v00001002d000068E4*
+ ID_PRODUCT_FROM_DATABASE=Robson CE [AMD Radeon HD 6300 Series]
+
+pci:v00001002d000068E5*
+ ID_PRODUCT_FROM_DATABASE=Robson LE [AMD Radeon HD 6300M Series]
+
+pci:v00001002d000068F1*
+ ID_PRODUCT_FROM_DATABASE=Cedar [FirePro 2460]
+
+pci:v00001002d000068F2*
+ ID_PRODUCT_FROM_DATABASE=Cedar [FirePro 2270]
+
+pci:v00001002d000068F9*
+ ID_PRODUCT_FROM_DATABASE=Cedar PRO [Radeon HD 5450/6350]
+
+pci:v00001002d000068F9sv00001028sd0000010E*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00001002d000068FA*
+ ID_PRODUCT_FROM_DATABASE=EG Cedar [Radeon HD 7300 Series]
+
+pci:v00001002d0000700F*
+ ID_PRODUCT_FROM_DATABASE=PCI Bridge [IGP 320M]
+
+pci:v00001002d00007010*
+ ID_PRODUCT_FROM_DATABASE=PCI Bridge [IGP 340M]
+
+pci:v00001002d00007100*
+ ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800]
+
+pci:v00001002d00007102*
+ ID_PRODUCT_FROM_DATABASE=M58 [Radeon Mobility X1800]
+
+pci:v00001002d00007103*
+ ID_PRODUCT_FROM_DATABASE=M58 [Mobility FireGL V7200]
+
+pci:v00001002d00007104*
+ ID_PRODUCT_FROM_DATABASE=R520GL [FireGL V7200] (Primary)
+
+pci:v00001002d00007105*
+ ID_PRODUCT_FROM_DATABASE=R520 [FireGL]
+
+pci:v00001002d00007106*
+ ID_PRODUCT_FROM_DATABASE=M58 [Mobility FireGL V7100]
+
+pci:v00001002d00007108*
+ ID_PRODUCT_FROM_DATABASE=M58 [Radeon Mobility X1800]
+
+pci:v00001002d00007109*
+ ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800]
+
+pci:v00001002d00007109sv00001002sd00000322*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder X1800XL
+
+pci:v00001002d00007109sv00001002sd00000D02*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1800 CrossFire Edition
+
+pci:v00001002d0000710A*
+ ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800]
+
+pci:v00001002d0000710B*
+ ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800]
+
+pci:v00001002d0000710C*
+ ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800]
+
+pci:v00001002d00007120*
+ ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] (Secondary)
+
+pci:v00001002d00007124*
+ ID_PRODUCT_FROM_DATABASE=R520GL [FireGL V7200] (Secondary)
+
+pci:v00001002d00007129*
+ ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] (Secondary)
+
+pci:v00001002d00007129sv00001002sd00000323*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder X1800XL (Secondary)
+
+pci:v00001002d00007129sv00001002sd00000D03*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1800 CrossFire Edition (Secondary)
+
+pci:v00001002d00007140*
+ ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1600]
+
+pci:v00001002d00007142*
+ ID_PRODUCT_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series]
+
+pci:v00001002d00007142sv00001002sd00000322*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition
+
+pci:v00001002d00007142sv00001043sd00000142*
+ ID_PRODUCT_FROM_DATABASE=EAX1300PRO/TD/256M
+
+pci:v00001002d00007143*
+ ID_PRODUCT_FROM_DATABASE=RV505 [Radeon X1550 Series]
+
+pci:v00001002d00007145*
+ ID_PRODUCT_FROM_DATABASE=Radeon Mobility X1400
+
+pci:v00001002d00007145sv000017AAsd00002006*
+ ID_PRODUCT_FROM_DATABASE=Thinkpad T60 model 2007
+
+pci:v00001002d00007146*
+ ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1300]
+
+pci:v00001002d00007146sv00001002sd00000322*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition
+
+pci:v00001002d00007146sv00001545sd00001996*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1300 512MB PCI-e
+
+pci:v00001002d00007147*
+ ID_PRODUCT_FROM_DATABASE=RV505 [Radeon X1550 64-bit]
+
+pci:v00001002d00007149*
+ ID_PRODUCT_FROM_DATABASE=M52 [Mobility Radeon X1300]
+
+pci:v00001002d0000714A*
+ ID_PRODUCT_FROM_DATABASE=M52 [Mobility Radeon X1300]
+
+pci:v00001002d0000714B*
+ ID_PRODUCT_FROM_DATABASE=M52 [Mobility Radeon X1300]
+
+pci:v00001002d0000714C*
+ ID_PRODUCT_FROM_DATABASE=M52 [Mobility Radeon X1300]
+
+pci:v00001002d0000714D*
+ ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1300]
+
+pci:v00001002d0000714E*
+ ID_PRODUCT_FROM_DATABASE=RV515LE [Radeon X1300]
+
+pci:v00001002d00007152*
+ ID_PRODUCT_FROM_DATABASE=RV515GL [FireGL V3300] (Primary)
+
+pci:v00001002d00007153*
+ ID_PRODUCT_FROM_DATABASE=RV515GL [FireGL V3350]
+
+pci:v00001002d0000715E*
+ ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1300]
+
+pci:v00001002d0000715F*
+ ID_PRODUCT_FROM_DATABASE=RV505 CE [Radeon X1550 64-bit]
+
+pci:v00001002d00007162*
+ ID_PRODUCT_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series] (Secondary)
+
+pci:v00001002d00007162sv00001002sd00000323*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition (Secondary)
+
+pci:v00001002d00007163*
+ ID_PRODUCT_FROM_DATABASE=RV505 [Radeon X1550 Series] (Secondary)
+
+pci:v00001002d00007166*
+ ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1300] (Secondary)
+
+pci:v00001002d00007166sv00001002sd00000323*
+ ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition (Secondary)
+
+pci:v00001002d00007166sv00001545sd00001997*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1300 512MB PCI-e (Secondary)
+
+pci:v00001002d00007167*
+ ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1550 64-bit] (Secondary)
+
+pci:v00001002d0000716E*
+ ID_PRODUCT_FROM_DATABASE=RV515LE [Radeon X1300] Secondary
+
+pci:v00001002d00007172*
+ ID_PRODUCT_FROM_DATABASE=RV515GL [FireGL V3300] (Secondary)
+
+pci:v00001002d00007173*
+ ID_PRODUCT_FROM_DATABASE=RV515GL [FireGL V3350] (Secondary)
+
+pci:v00001002d00007180*
+ ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series]
+
+pci:v00001002d00007181*
+ ID_PRODUCT_FROM_DATABASE=RV516 XT Radeon X1600 Series (Primary)
+
+pci:v00001002d00007183*
+ ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series]
+
+pci:v00001002d00007186*
+ ID_PRODUCT_FROM_DATABASE=RV515 [Radeon Mobility X1450]
+
+pci:v00001002d00007187*
+ ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series]
+
+pci:v00001002d00007188*
+ ID_PRODUCT_FROM_DATABASE=M64-S [Mobility Radeon X2300]
+
+pci:v00001002d00007188sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=6910p
+
+pci:v00001002d0000718A*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon X2300
+
+pci:v00001002d0000718C*
+ ID_PRODUCT_FROM_DATABASE=M62CSP64 [Mobility Radeon X1350]
+
+pci:v00001002d0000718D*
+ ID_PRODUCT_FROM_DATABASE=M64CSP128 [Mobility Radeon X1450]
+
+pci:v00001002d00007193*
+ ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1550 Series]
+
+pci:v00001002d00007196*
+ ID_PRODUCT_FROM_DATABASE=RV516 [Mobility Radeon X1350]
+
+pci:v00001002d0000719B*
+ ID_PRODUCT_FROM_DATABASE=FireMV 2250
+
+pci:v00001002d0000719F*
+ ID_PRODUCT_FROM_DATABASE=RV516LE [Radeon X1550 64-bit]
+
+pci:v00001002d000071A0*
+ ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series] (Secondary)
+
+pci:v00001002d000071A1*
+ ID_PRODUCT_FROM_DATABASE=RV516 XT Radeon X1600 Series (Secondary)
+
+pci:v00001002d000071A3*
+ ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300 Pro] (Secondary)
+
+pci:v00001002d000071A7*
+ ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series] (Secondary)
+
+pci:v00001002d000071BB*
+ ID_PRODUCT_FROM_DATABASE=FireMV 2250 (Secondary)
+
+pci:v00001002d000071C0*
+ ID_PRODUCT_FROM_DATABASE=RV530 [Radeon X1600]
+
+pci:v00001002d000071C1*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1650 Pro
+
+pci:v00001002d000071C2*
+ ID_PRODUCT_FROM_DATABASE=RV530 [Radeon X1600]
+
+pci:v00001002d000071C4*
+ ID_PRODUCT_FROM_DATABASE=M56GL [Mobility FireGL V5200]
+
+pci:v00001002d000071C4sv000017AAsd00002007*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60p
+
+pci:v00001002d000071C5*
+ ID_PRODUCT_FROM_DATABASE=M56P [Radeon Mobility X1600]
+
+pci:v00001002d000071C5sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00001002d000071C5sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq NW8440
+
+pci:v00001002d000071C5sv00001043sd000010B2*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00001002d000071C5sv0000106Bsd00000080*
+ ID_PRODUCT_FROM_DATABASE=MacBook Pro
+
+pci:v00001002d000071C6*
+ ID_PRODUCT_FROM_DATABASE=RV530LE [Radeon X1600/X1650 PRO]
+
+pci:v00001002d000071C7*
+ ID_PRODUCT_FROM_DATABASE=RV535 [Radeon X1650 Series]
+
+pci:v00001002d000071CE*
+ ID_PRODUCT_FROM_DATABASE=RV530LE [Radeon X1600]
+
+pci:v00001002d000071D2*
+ ID_PRODUCT_FROM_DATABASE=RV530GL [FireGL V3400]
+
+pci:v00001002d000071D4*
+ ID_PRODUCT_FROM_DATABASE=M66GL [ATI Mobility FireGL V5250]
+
+pci:v00001002d000071D5*
+ ID_PRODUCT_FROM_DATABASE=M66-P [Mobility Radeon X1700]
+
+pci:v00001002d000071D6*
+ ID_PRODUCT_FROM_DATABASE=M66-XT [Mobility Radeon X1700]
+
+pci:v00001002d000071DE*
+ ID_PRODUCT_FROM_DATABASE=RV530LE [Radeon X1600]
+
+pci:v00001002d000071E0*
+ ID_PRODUCT_FROM_DATABASE=RV530 [Radeon X1600] (Secondary)
+
+pci:v00001002d000071E1*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1650 Pro (Secondary)
+
+pci:v00001002d000071E2*
+ ID_PRODUCT_FROM_DATABASE=RV530 [Radeon X1600] (Secondary)
+
+pci:v00001002d000071E6*
+ ID_PRODUCT_FROM_DATABASE=RV530LE [Radeon X1650 PRO] (Secondary)
+
+pci:v00001002d000071E7*
+ ID_PRODUCT_FROM_DATABASE=RV535 [Radeon X1650 Series]
+
+pci:v00001002d000071F2*
+ ID_PRODUCT_FROM_DATABASE=RV530GL [FireGL V3400 (Secondary)]
+
+pci:v00001002d00007210*
+ ID_PRODUCT_FROM_DATABASE=M71 [Mobility Radeon X2100]
+
+pci:v00001002d00007211*
+ ID_PRODUCT_FROM_DATABASE=M71 [Mobility Radeon X2100] (Secondary)
+
+pci:v00001002d00007240*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007241*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007242*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007243*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007244*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007245*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007246*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007247*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007248*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d00007249*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900 XT] (Primary)
+
+pci:v00001002d0000724A*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d0000724B*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d0000724Bsv00001002sd00000B12*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1900 (Primary)
+
+pci:v00001002d0000724Bsv00001002sd00000B13*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1900 (Secondary)
+
+pci:v00001002d0000724C*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d0000724D*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d0000724E*
+ ID_PRODUCT_FROM_DATABASE=R580 [AMD Stream Processor]
+
+pci:v00001002d00007269*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900 XT] (Secondary)
+
+pci:v00001002d0000726B*
+ ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900]
+
+pci:v00001002d0000726E*
+ ID_PRODUCT_FROM_DATABASE=R580 [AMD Stream Processor] (Secondary)
+
+pci:v00001002d00007280*
+ ID_PRODUCT_FROM_DATABASE=RV570 [Radeon X1950 Pro]
+
+pci:v00001002d00007288*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1950 GT
+
+pci:v00001002d00007291*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1650 XT (Primary) (PCIE)
+
+pci:v00001002d00007293*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1650 Series
+
+pci:v00001002d000072A0*
+ ID_PRODUCT_FROM_DATABASE=RV570 [Radeon X1950 Pro] (secondary)
+
+pci:v00001002d000072A8*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1950 GT (Secondary)
+
+pci:v00001002d000072B1*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1650 XT (Secondary) (PCIE)
+
+pci:v00001002d000072B3*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1650 Series (Secondary)
+
+pci:v00001002d00007833*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9100 IGP Host Bridge
+
+pci:v00001002d00007834*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9100 PRO IGP
+
+pci:v00001002d00007835*
+ ID_PRODUCT_FROM_DATABASE=Radeon Mobility 9200 IGP
+
+pci:v00001002d00007838*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9100 IGP PCI/AGP Bridge
+
+pci:v00001002d00007910*
+ ID_PRODUCT_FROM_DATABASE=RS690 Host Bridge
+
+pci:v00001002d00007910sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00007910sv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d00007911*
+ ID_PRODUCT_FROM_DATABASE=RS690 Host Bridge
+
+pci:v00001002d00007912*
+ ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (Internal gfx)
+
+pci:v00001002d00007913*
+ ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Graphics Port 0)
+
+pci:v00001002d00007915*
+ ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 1)
+
+pci:v00001002d00007916*
+ ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 2)
+
+pci:v00001002d00007917*
+ ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 3)
+
+pci:v00001002d00007917sv00001002sd00007910*
+ ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge
+
+pci:v00001002d00007919*
+ ID_PRODUCT_FROM_DATABASE=Radeon X1200 Series Audio Controller
+
+pci:v00001002d00007919sv00001179sd00007919*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00007919sv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d0000791E*
+ ID_PRODUCT_FROM_DATABASE=RS690 [Radeon X1200 Series]
+
+pci:v00001002d0000791Esv00001462sd00007327*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v00001002d0000791Esv000017F2sd00005000*
+ ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard
+
+pci:v00001002d0000791F*
+ ID_PRODUCT_FROM_DATABASE=RS690M [Radeon X1200 Series]
+
+pci:v00001002d0000791Fsv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001002d00007930*
+ ID_PRODUCT_FROM_DATABASE=RS600 Host Bridge
+
+pci:v00001002d00007932*
+ ID_PRODUCT_FROM_DATABASE=RS600 PCI to PCI Bridge (Internal gfx)
+
+pci:v00001002d00007933*
+ ID_PRODUCT_FROM_DATABASE=RS600 PCI to PCI Bridge (PCI Express Graphics Port 0)
+
+pci:v00001002d00007935*
+ ID_PRODUCT_FROM_DATABASE=RS600 PCI to PCI Bridge (PCI Express Port 1)
+
+pci:v00001002d00007936*
+ ID_PRODUCT_FROM_DATABASE=RS600 PCI to PCI Bridge (PCI Express Port 2)
+
+pci:v00001002d00007937*
+ ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 3)
+
+pci:v00001002d0000793B*
+ ID_PRODUCT_FROM_DATABASE=RS600 HDMI Audio [Radeon Xpress 1250]
+
+pci:v00001002d0000793F*
+ ID_PRODUCT_FROM_DATABASE=RS600 [Radeon Xpress 1250]
+
+pci:v00001002d00007941*
+ ID_PRODUCT_FROM_DATABASE=RS600 [Radeon Xpress 1250]
+
+pci:v00001002d00007942*
+ ID_PRODUCT_FROM_DATABASE=RS600 [Radeon Xpress 1250]
+
+pci:v00001002d0000796E*
+ ID_PRODUCT_FROM_DATABASE=Radeon 2100
+
+pci:v00001002d00007C37*
+ ID_PRODUCT_FROM_DATABASE=RV350 AQ [Radeon 9600 SE]
+
+pci:v00001002d00009400*
+ ID_PRODUCT_FROM_DATABASE=R600 [Radeon HD 2900 Series]
+
+pci:v00001002d00009400sv00001002sd00003000*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon HD 2900 XT
+
+pci:v00001002d00009400sv00001002sd00003142*
+ ID_PRODUCT_FROM_DATABASE=HIS Radeon HD 2900XT 512MB GDDR3 VIVO PCIe
+
+pci:v00001002d00009403*
+ ID_PRODUCT_FROM_DATABASE=R600 [Radeon HD 2900 PRO]
+
+pci:v00001002d0000940A*
+ ID_PRODUCT_FROM_DATABASE=R600GL [Fire GL V8650]
+
+pci:v00001002d0000940B*
+ ID_PRODUCT_FROM_DATABASE=R600GL [Fire GL V8600]
+
+pci:v00001002d0000940F*
+ ID_PRODUCT_FROM_DATABASE=R600 [FireGL V7600]
+
+pci:v00001002d00009440*
+ ID_PRODUCT_FROM_DATABASE=RV770 [Radeon HD 4870]
+
+pci:v00001002d00009441*
+ ID_PRODUCT_FROM_DATABASE=R700 [Radeon HD 4870 X2]
+
+pci:v00001002d00009442*
+ ID_PRODUCT_FROM_DATABASE=RV770 [Radeon HD 4850]
+
+pci:v00001002d00009442sv00001002sd00000502*
+ ID_PRODUCT_FROM_DATABASE=MSI R4850-T2D512
+
+pci:v00001002d00009442sv0000174Bsd0000E810*
+ ID_PRODUCT_FROM_DATABASE=Sapphire HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink
+
+pci:v00001002d00009443*
+ ID_PRODUCT_FROM_DATABASE=R700 [Radeon HD 4850]
+
+pci:v00001002d0000944A*
+ ID_PRODUCT_FROM_DATABASE=M98L [Mobility Radeon HD 4850]
+
+pci:v00001002d0000944C*
+ ID_PRODUCT_FROM_DATABASE=RV770 LE [Radeon HD 4800 Series]
+
+pci:v00001002d0000944E*
+ ID_PRODUCT_FROM_DATABASE=RV770 CE [Radeon HD 4710]
+
+pci:v00001002d00009450*
+ ID_PRODUCT_FROM_DATABASE=RV770 [FireStream 9270]
+
+pci:v00001002d00009452*
+ ID_PRODUCT_FROM_DATABASE=RV770 [FireStream 9250]
+
+pci:v00001002d0000945A*
+ ID_PRODUCT_FROM_DATABASE=M98 XT [Mobility Radeon HD 4870]
+
+pci:v00001002d00009460*
+ ID_PRODUCT_FROM_DATABASE=RV790 [Radeon HD 4890]
+
+pci:v00001002d00009462*
+ ID_PRODUCT_FROM_DATABASE=RV790LE [Radeon HD 4800 Series]
+
+pci:v00001002d00009480*
+ ID_PRODUCT_FROM_DATABASE=M96 [Mobility Radeon HD 4650]
+
+pci:v00001002d00009480sv0000103Csd00003628*
+ ID_PRODUCT_FROM_DATABASE=ATI Mobility Radeon HD 4650 [dv6-1190en]
+
+pci:v00001002d00009485*
+ ID_PRODUCT_FROM_DATABASE=RV740 Pro [Radeon HD 4770]
+
+pci:v00001002d00009488*
+ ID_PRODUCT_FROM_DATABASE=RV730 XT [Mobility Radeon HD 4670]
+
+pci:v00001002d00009489*
+ ID_PRODUCT_FROM_DATABASE=M96 XT [Mobility FireGL V5725]
+
+pci:v00001002d00009490*
+ ID_PRODUCT_FROM_DATABASE=RV730XT [Radeon HD 4670]
+
+pci:v00001002d00009490sv0000174Bsd0000E880*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 4670 512MB DDR3
+
+pci:v00001002d00009491*
+ ID_PRODUCT_FROM_DATABASE=M96 CSP [ATI RADEON E4690]
+
+pci:v00001002d00009495*
+ ID_PRODUCT_FROM_DATABASE=RV730 Pro AGP [Radeon HD 4600 Series]
+
+pci:v00001002d00009495sv00001002sd00009495*
+ ID_PRODUCT_FROM_DATABASE=RV730 XT [PowerColor Radeon HD4670 AGP 1GB DDR]
+
+pci:v00001002d00009495sv00001458sd00000028*
+ ID_PRODUCT_FROM_DATABASE=HD4650
+
+pci:v00001002d00009498*
+ ID_PRODUCT_FROM_DATABASE=RV730 PRO [Radeon HD 4650]
+
+pci:v00001002d0000949E*
+ ID_PRODUCT_FROM_DATABASE=RV370 [FirePro V5700]
+
+pci:v00001002d0000949F*
+ ID_PRODUCT_FROM_DATABASE=RV730 [FirePro V5700]
+
+pci:v00001002d000094A0*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 4830 [M97]
+
+pci:v00001002d000094A1*
+ ID_PRODUCT_FROM_DATABASE=[M97 XT] Mobility Radeon HD 4860
+
+pci:v00001002d000094A3*
+ ID_PRODUCT_FROM_DATABASE=M97 GL [ATI FirePro M7740]
+
+pci:v00001002d000094B3*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 4770 [RV740]
+
+pci:v00001002d000094B4*
+ ID_PRODUCT_FROM_DATABASE=RV740 LE [ATI Radeon HD 4700 Series]
+
+pci:v00001002d000094C1*
+ ID_PRODUCT_FROM_DATABASE=RV610 [Radeon HD 2400 XT]
+
+pci:v00001002d000094C1sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00001002d000094C1sv00001028sd00000D02*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00001002d000094C3*
+ ID_PRODUCT_FROM_DATABASE=RV610 video device [Radeon HD 2400 PRO]
+
+pci:v00001002d000094C3sv00001002sd000094C3*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 2400PRO
+
+pci:v00001002d000094C3sv00001028sd00000302*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 2400 Pro
+
+pci:v00001002d000094C3sv0000174Bsd0000E400*
+ ID_PRODUCT_FROM_DATABASE=Sapphire HD 2400 PRO video device
+
+pci:v00001002d000094C3sv000018BCsd00003550*
+ ID_PRODUCT_FROM_DATABASE=GeCube Radeon HD2400 PRO
+
+pci:v00001002d000094C4*
+ ID_PRODUCT_FROM_DATABASE=RV610 LE AGP [Radeon HD 2400 PRO AGP]
+
+pci:v00001002d000094C8*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 2400 XT
+
+pci:v00001002d000094C9*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 2400
+
+pci:v00001002d000094C9sv00001002sd000094C9*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD2400
+
+pci:v00001002d000094CB*
+ ID_PRODUCT_FROM_DATABASE=Radeon E2400
+
+pci:v00001002d000094CC*
+ ID_PRODUCT_FROM_DATABASE=RV610 LE [Radeon HD 2400 Pro PCI]
+
+pci:v00001002d00009501*
+ ID_PRODUCT_FROM_DATABASE=RV670 [Radeon HD 3870]
+
+pci:v00001002d00009501sv0000174Bsd0000E620*
+ ID_PRODUCT_FROM_DATABASE=Sapphire Radeon HD 3870 PCIe 2.0
+
+pci:v00001002d00009504*
+ ID_PRODUCT_FROM_DATABASE=RV670 [Mobility Radeon HD 3850]
+
+pci:v00001002d00009505*
+ ID_PRODUCT_FROM_DATABASE=RV670PRO [Radeon HD 3850]
+
+pci:v00001002d00009507*
+ ID_PRODUCT_FROM_DATABASE=RV670 [Radeon HD 3850]
+
+pci:v00001002d00009508*
+ ID_PRODUCT_FROM_DATABASE=M88 XT Mobility Radeon HD 3870]
+
+pci:v00001002d0000950F*
+ ID_PRODUCT_FROM_DATABASE=R680 [Radeon HD 3870 x2]
+
+pci:v00001002d00009511*
+ ID_PRODUCT_FROM_DATABASE=RV670 [FireGL 7700]
+
+pci:v00001002d00009515*
+ ID_PRODUCT_FROM_DATABASE=RV670 AGP [Radeon HD 3850]
+
+pci:v00001002d00009519*
+ ID_PRODUCT_FROM_DATABASE=RV670 [FireStream 9170]
+
+pci:v00001002d00009540*
+ ID_PRODUCT_FROM_DATABASE=RV710 [Radeon HD 4550]
+
+pci:v00001002d0000954F*
+ ID_PRODUCT_FROM_DATABASE=RV710 [Radeon HD 4350]
+
+pci:v00001002d0000954Fsv00001462sd00001618*
+ ID_PRODUCT_FROM_DATABASE=R4350 MD512H (MS-V161)
+
+pci:v00001002d00009552*
+ ID_PRODUCT_FROM_DATABASE=RV710 [Mobility Radeon HD 4300 Series]
+
+pci:v00001002d00009553*
+ ID_PRODUCT_FROM_DATABASE=RV710 [Mobility Radeon HD 4500/5100 Series]
+
+pci:v00001002d00009553sv00001179sd0000FF82*
+ ID_PRODUCT_FROM_DATABASE=Satellite L505-13T GPU (Mobility Radeon HD 5145)
+
+pci:v00001002d00009555*
+ ID_PRODUCT_FROM_DATABASE=RV710 [Mobility Radeon HD 4300/4500 Series]
+
+pci:v00001002d00009555sv0000103Csd00001411*
+ ID_PRODUCT_FROM_DATABASE=ProBook 4720s GPU (Mobility Radeon HD 4350)
+
+pci:v00001002d00009559*
+ ID_PRODUCT_FROM_DATABASE=RV635 [Mobility Radeon HD 3600 Series]
+
+pci:v00001002d0000955F*
+ ID_PRODUCT_FROM_DATABASE=RV710 [Mobility Radeon HD 4330]
+
+pci:v00001002d00009581*
+ ID_PRODUCT_FROM_DATABASE=RV630 [Mobility Radeon HD 2600]
+
+pci:v00001002d00009583*
+ ID_PRODUCT_FROM_DATABASE=RV630 [Mobility Radeon HD 2600 XT]
+
+pci:v00001002d00009586*
+ ID_PRODUCT_FROM_DATABASE=RV 630 XT AGP [Radeon HD 2600 XT AGP]
+
+pci:v00001002d00009587*
+ ID_PRODUCT_FROM_DATABASE=RV630 PRO AGP [Radeon HD 2600 PRO AGP]
+
+pci:v00001002d00009588*
+ ID_PRODUCT_FROM_DATABASE=RV630 [Radeon HD 2600XT]
+
+pci:v00001002d00009588sv00001458sd0000216C*
+ ID_PRODUCT_FROM_DATABASE=Radeon HD 2600 XT, 256MB GDDR3, 2x DVI, TV-out, PCIe (GV-RX26T256H)
+
+pci:v00001002d00009589*
+ ID_PRODUCT_FROM_DATABASE=RV630 [Radeon HD 2600 Series]
+
+pci:v00001002d0000958C*
+ ID_PRODUCT_FROM_DATABASE=RV630GL [FireGL v5600]
+
+pci:v00001002d0000958D*
+ ID_PRODUCT_FROM_DATABASE=RV630 [FireGL V3600]
+
+pci:v00001002d00009591*
+ ID_PRODUCT_FROM_DATABASE=RV635 [Mobility Radeon HD 3650]
+
+pci:v00001002d00009591sv00001002sd00009591*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 3650
+
+pci:v00001002d00009593*
+ ID_PRODUCT_FROM_DATABASE=RV635 [Mobility Radeon HD 3670]
+
+pci:v00001002d00009595*
+ ID_PRODUCT_FROM_DATABASE=M86GL [Mobility FireGL V5700]
+
+pci:v00001002d00009596*
+ ID_PRODUCT_FROM_DATABASE=RV635 PRO AGP [Radeon HD 3650]
+
+pci:v00001002d00009596sv00001043sd00000028*
+ ID_PRODUCT_FROM_DATABASE=EAH3650 SILENT/HTDI/512M/A
+
+pci:v00001002d00009598*
+ ID_PRODUCT_FROM_DATABASE=RV630 [Radeon HD 3600 Series]
+
+pci:v00001002d00009598sv00001002sd00009598*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 3600
+
+pci:v00001002d00009598sv00001043sd000001D6*
+ ID_PRODUCT_FROM_DATABASE=EAH3650 Silent
+
+pci:v00001002d000095C0*
+ ID_PRODUCT_FROM_DATABASE=RV620 PRO [Radeon HD 3470]
+
+pci:v00001002d000095C0sv00001002sd000095C0*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 3470
+
+pci:v00001002d000095C4*
+ ID_PRODUCT_FROM_DATABASE=RV620 [Mobility Radeon HD 3400 Series]
+
+pci:v00001002d000095C4sv00001002sd000095C4*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 3400
+
+pci:v00001002d000095C5*
+ ID_PRODUCT_FROM_DATABASE=RV620 LE [Radeon HD 3450]
+
+pci:v00001002d000095C5sv00001028sd00000342*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00001002d000095C6*
+ ID_PRODUCT_FROM_DATABASE=RV620 LE AGP [Radeon HD 3450]
+
+pci:v00001002d000095C7*
+ ID_PRODUCT_FROM_DATABASE=RV620 CE [Radeon HD 3430]
+
+pci:v00001002d000095C9*
+ ID_PRODUCT_FROM_DATABASE=RV620 PCI [Radeon HD 3450]
+
+pci:v00001002d000095CC*
+ ID_PRODUCT_FROM_DATABASE=RV620 [ATI FireGL V3700]
+
+pci:v00001002d000095CD*
+ ID_PRODUCT_FROM_DATABASE=RV620 [FireMV 2450]
+
+pci:v00001002d000095CE*
+ ID_PRODUCT_FROM_DATABASE=RV620 [FirePro 2260]
+
+pci:v00001002d000095CF*
+ ID_PRODUCT_FROM_DATABASE=RV620 [FirePro 2260]
+
+pci:v00001002d0000960F*
+ ID_PRODUCT_FROM_DATABASE=RS780 HDMI Audio [Radeon HD 3000-3300 Series]
+
+pci:v00001002d00009610*
+ ID_PRODUCT_FROM_DATABASE=RS780 [Radeon HD 3200]
+
+pci:v00001002d00009610sv00001458sd0000D000*
+ ID_PRODUCT_FROM_DATABASE=GA-MA78GM-S2H Motherboard
+
+pci:v00001002d00009611*
+ ID_PRODUCT_FROM_DATABASE=RS780C [Radeon HD 3100]
+
+pci:v00001002d00009612*
+ ID_PRODUCT_FROM_DATABASE=RS780M/RS780MN [Mobility Radeon HD 3200 Graphics]
+
+pci:v00001002d00009613*
+ ID_PRODUCT_FROM_DATABASE=RS780MC [Mobility Radeon HD 3100 Graphics]
+
+pci:v00001002d00009614*
+ ID_PRODUCT_FROM_DATABASE=RS780D [Radeon HD 3300]
+
+pci:v00001002d00009615*
+ ID_PRODUCT_FROM_DATABASE=RS780E [Radeon HD 3200]
+
+pci:v00001002d00009616*
+ ID_PRODUCT_FROM_DATABASE=RS780L [Radeon HD 3000]
+
+pci:v00001002d00009640*
+ ID_PRODUCT_FROM_DATABASE=BeaverCreek [Radeon HD 6550D]
+
+pci:v00001002d00009641*
+ ID_PRODUCT_FROM_DATABASE=BeaverCreek [Mobility Radeon HD 6620G]
+
+pci:v00001002d00009647*
+ ID_PRODUCT_FROM_DATABASE=BeaverCreek [Radeon HD 6520G]
+
+pci:v00001002d0000964A*
+ ID_PRODUCT_FROM_DATABASE=BeaverCreek [Radeon HD 6530D]
+
+pci:v00001002d0000970F*
+ ID_PRODUCT_FROM_DATABASE=RS880 HDMI Audio [Radeon HD 4200 Series]
+
+pci:v00001002d0000970Fsv00001043sd000083A2*
+ ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard
+
+pci:v00001002d0000970Fsv00001043sd0000843E*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001002d00009710*
+ ID_PRODUCT_FROM_DATABASE=RS880 [Radeon HD 4200]
+
+pci:v00001002d00009710sv00001043sd000083A2*
+ ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard
+
+pci:v00001002d00009712*
+ ID_PRODUCT_FROM_DATABASE=RS880M [Mobility Radeon HD 4200 Series]
+
+pci:v00001002d00009713*
+ ID_PRODUCT_FROM_DATABASE=RS880M [Mobility Radeon HD 4100]
+
+pci:v00001002d00009714*
+ ID_PRODUCT_FROM_DATABASE=RS880 [Radeon HD 4290]
+
+pci:v00001002d00009715*
+ ID_PRODUCT_FROM_DATABASE=RS880 [Radeon HD 4250]
+
+pci:v00001002d00009715sv00001043sd0000843E*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001002d00009802*
+ ID_PRODUCT_FROM_DATABASE=Wrestler [Radeon HD 6310]
+
+pci:v00001002d00009802sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001002d00009804*
+ ID_PRODUCT_FROM_DATABASE=Wrestler [Radeon HD 6250]
+
+pci:v00001002d00009806*
+ ID_PRODUCT_FROM_DATABASE=Wrestler [Radeon HD 6320]
+
+pci:v00001002d00009807*
+ ID_PRODUCT_FROM_DATABASE=Wrestler [Radeon HD 6290]
+
+pci:v00001002d00009901*
+ ID_PRODUCT_FROM_DATABASE=Trinity [Radeon HD 7660D]
+
+pci:v00001002d00009902*
+ ID_PRODUCT_FROM_DATABASE=Trinity HDMI Audio Controller
+
+pci:v00001002d00009904*
+ ID_PRODUCT_FROM_DATABASE=Trinity [Radeon HD 7560D]
+
+pci:v00001002d00009990*
+ ID_PRODUCT_FROM_DATABASE=Trinity [Radeon HD 7520G]
+
+pci:v00001002d0000AA00*
+ ID_PRODUCT_FROM_DATABASE=R600 Audio Device [Radeon HD 2900 Series]
+
+pci:v00001002d0000AA08*
+ ID_PRODUCT_FROM_DATABASE=RV630 audio device [Radeon HD 2600 Series]
+
+pci:v00001002d0000AA10*
+ ID_PRODUCT_FROM_DATABASE=RV610 HDMI Audio [Radeon HD 2350/2400 Series]
+
+pci:v00001002d0000AA10sv0000174Bsd0000AA10*
+ ID_PRODUCT_FROM_DATABASE=Sapphire HD 2400 PRO audio device
+
+pci:v00001002d0000AA10sv000018BCsd0000AA10*
+ ID_PRODUCT_FROM_DATABASE=GeCube Radeon HD 2400 PRO HDCP-capable digital-only audio device
+
+pci:v00001002d0000AA18*
+ ID_PRODUCT_FROM_DATABASE=RV670/680 HDMI Audio [Radeon HD 3690/3800 Series]
+
+pci:v00001002d0000AA20*
+ ID_PRODUCT_FROM_DATABASE=RV635 HDMI Audio [Radeon HD 3600 Series]
+
+pci:v00001002d0000AA28*
+ ID_PRODUCT_FROM_DATABASE=RV620 HDMI Audio [Radeon HD 3400 Series]
+
+pci:v00001002d0000AA30*
+ ID_PRODUCT_FROM_DATABASE=RV770 HDMI Audio [Radeon HD 4850/4870]
+
+pci:v00001002d0000AA30sv0000174Bsd0000AA30*
+ ID_PRODUCT_FROM_DATABASE=Sapphire HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink
+
+pci:v00001002d0000AA38*
+ ID_PRODUCT_FROM_DATABASE=RV710/730 HDMI Audio [Radeon HD 4000 series]
+
+pci:v00001002d0000AA38sv0000103Csd00003628*
+ ID_PRODUCT_FROM_DATABASE=ATI RV710/730 [dv6-1190en]
+
+pci:v00001002d0000AA38sv0000174Bsd0000AA38*
+ ID_PRODUCT_FROM_DATABASE=R700 Audio Device [Radeon HD 4000 Series]
+
+pci:v00001002d0000AA50*
+ ID_PRODUCT_FROM_DATABASE=Cypress HDMI Audio [Radeon HD 5800 Series]
+
+pci:v00001002d0000AA58*
+ ID_PRODUCT_FROM_DATABASE=Juniper HDMI Audio [Radeon HD 5700 Series]
+
+pci:v00001002d0000AA60*
+ ID_PRODUCT_FROM_DATABASE=Redwood HDMI Audio [Radeon HD 5000 Series]
+
+pci:v00001002d0000AA60sv00001025sd0000033D*
+ ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 5650
+
+pci:v00001002d0000AA60sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00001002d0000AA68*
+ ID_PRODUCT_FROM_DATABASE=Cedar HDMI Audio [Radeon HD 5400/6300 Series]
+
+pci:v00001002d0000AA68sv00001028sd0000AA68*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00001002d0000AA80*
+ ID_PRODUCT_FROM_DATABASE=Cayman/Antilles HDMI Audio [Radeon HD 6900 Series]
+
+pci:v00001002d0000AA88*
+ ID_PRODUCT_FROM_DATABASE=Barts HDMI Audio [Radeon HD 6800 Series]
+
+pci:v00001002d0000AA90*
+ ID_PRODUCT_FROM_DATABASE=Turks/Whistler HDMI Audio [Radeon HD 6000 Series]
+
+pci:v00001002d0000AA98*
+ ID_PRODUCT_FROM_DATABASE=Caicos HDMI Audio [Radeon HD 6400 Series]
+
+pci:v00001002d0000AA98sv0000174Bsd0000AA98*
+ ID_PRODUCT_FROM_DATABASE=Sapphire HD 6450 1GB DDR3
+
+pci:v00001002d0000AAA0*
+ ID_PRODUCT_FROM_DATABASE=Tahiti XT HDMI Audio [Radeon HD 7970 Series]
+
+pci:v00001002d0000AC00*
+ ID_PRODUCT_FROM_DATABASE=Theater 600 Pro
+
+pci:v00001002d0000AC02*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder HD 600 PCIe
+
+pci:v00001002d0000AC12*
+ ID_PRODUCT_FROM_DATABASE=Theater HD T507 (DVB-T) TV tuner/capture device
+
+pci:v00001002d0000CAB0*
+ ID_PRODUCT_FROM_DATABASE=RS100 AGP Bridge [IGP 320M]
+
+pci:v00001002d0000CAB2*
+ ID_PRODUCT_FROM_DATABASE=RS200/RS200M AGP Bridge [IGP 340M]
+
+pci:v00001002d0000CAB3*
+ ID_PRODUCT_FROM_DATABASE=R200 AGP Bridge [Mobility Radeon 7000 IGP]
+
+pci:v00001002d0000CBB2*
+ ID_PRODUCT_FROM_DATABASE=RS200/RS200M AGP Bridge [IGP 340M]
+
+pci:v00001003*
+ ID_VENDOR_FROM_DATABASE=ULSI Systems
+
+pci:v00001003d00000201*
+ ID_PRODUCT_FROM_DATABASE=US201
+
+pci:v00001004*
+ ID_VENDOR_FROM_DATABASE=VLSI Technology Inc
+
+pci:v00001004d00000005*
+ ID_PRODUCT_FROM_DATABASE=82C592-FC1
+
+pci:v00001004d00000006*
+ ID_PRODUCT_FROM_DATABASE=82C593-FC1
+
+pci:v00001004d00000007*
+ ID_PRODUCT_FROM_DATABASE=82C594-AFC2
+
+pci:v00001004d00000008*
+ ID_PRODUCT_FROM_DATABASE=82C596/7 [Wildcat]
+
+pci:v00001004d00000009*
+ ID_PRODUCT_FROM_DATABASE=82C597-AFC2
+
+pci:v00001004d0000000C*
+ ID_PRODUCT_FROM_DATABASE=82C541 [Lynx]
+
+pci:v00001004d0000000D*
+ ID_PRODUCT_FROM_DATABASE=82C543 [Lynx]
+
+pci:v00001004d00000101*
+ ID_PRODUCT_FROM_DATABASE=82C532
+
+pci:v00001004d00000102*
+ ID_PRODUCT_FROM_DATABASE=82C534 [Eagle]
+
+pci:v00001004d00000103*
+ ID_PRODUCT_FROM_DATABASE=82C538
+
+pci:v00001004d00000104*
+ ID_PRODUCT_FROM_DATABASE=82C535
+
+pci:v00001004d00000105*
+ ID_PRODUCT_FROM_DATABASE=82C147
+
+pci:v00001004d00000200*
+ ID_PRODUCT_FROM_DATABASE=82C975
+
+pci:v00001004d00000280*
+ ID_PRODUCT_FROM_DATABASE=82C925
+
+pci:v00001004d00000304*
+ ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio
+
+pci:v00001004d00000304sv00001004sd00000304*
+ ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio
+
+pci:v00001004d00000304sv0000122Dsd00001206*
+ ID_PRODUCT_FROM_DATABASE=DSP368 Audio
+
+pci:v00001004d00000304sv00001483sd00005020*
+ ID_PRODUCT_FROM_DATABASE=XWave Thunder 3D Audio
+
+pci:v00001004d00000305*
+ ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio Gameport
+
+pci:v00001004d00000305sv00001004sd00000305*
+ ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio Gameport
+
+pci:v00001004d00000305sv0000122Dsd00001207*
+ ID_PRODUCT_FROM_DATABASE=DSP368 Audio Gameport
+
+pci:v00001004d00000305sv00001483sd00005021*
+ ID_PRODUCT_FROM_DATABASE=XWave Thunder 3D Audio Gameport
+
+pci:v00001004d00000306*
+ ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio Support Registers
+
+pci:v00001004d00000306sv00001004sd00000306*
+ ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio Support Registers
+
+pci:v00001004d00000306sv0000122Dsd00001208*
+ ID_PRODUCT_FROM_DATABASE=DSP368 Audio Support Registers
+
+pci:v00001004d00000306sv00001483sd00005022*
+ ID_PRODUCT_FROM_DATABASE=XWave Thunder 3D Audio Support Registers
+
+pci:v00001004d00000307*
+ ID_PRODUCT_FROM_DATABASE=SAA7785 ThunderBird PCI Audio
+
+pci:v00001004d00000307sv00001004sd00000703*
+ ID_PRODUCT_FROM_DATABASE=Philips Rhythmic Edge PSC703
+
+pci:v00001004d00000307sv00001004sd00000705*
+ ID_PRODUCT_FROM_DATABASE=Philips Seismic Edge PSC705
+
+pci:v00001004d00000307sv00001004sd00000706*
+ ID_PRODUCT_FROM_DATABASE=Philips Acoustic Edge PSC706
+
+pci:v00001004d00000308*
+ ID_PRODUCT_FROM_DATABASE=SAA7785 ThunderBird PCI Audio Gameport
+
+pci:v00001004d00000702*
+ ID_PRODUCT_FROM_DATABASE=VAS96011 [Golden Gate II]
+
+pci:v00001004d00000703*
+ ID_PRODUCT_FROM_DATABASE=Tollgate
+
+pci:v00001005*
+ ID_VENDOR_FROM_DATABASE=Avance Logic Inc. [ALI]
+
+pci:v00001005d00002064*
+ ID_PRODUCT_FROM_DATABASE=ALG2032/2064
+
+pci:v00001005d00002128*
+ ID_PRODUCT_FROM_DATABASE=ALG2364A
+
+pci:v00001005d00002301*
+ ID_PRODUCT_FROM_DATABASE=ALG2301
+
+pci:v00001005d00002302*
+ ID_PRODUCT_FROM_DATABASE=ALG2302
+
+pci:v00001005d00002364*
+ ID_PRODUCT_FROM_DATABASE=ALG2364
+
+pci:v00001005d00002464*
+ ID_PRODUCT_FROM_DATABASE=ALG2364A
+
+pci:v00001005d00002501*
+ ID_PRODUCT_FROM_DATABASE=ALG2564A/25128A
+
+pci:v00001006*
+ ID_VENDOR_FROM_DATABASE=Reply Group
+
+pci:v00001007*
+ ID_VENDOR_FROM_DATABASE=NetFrame Systems Inc
+
+pci:v00001008*
+ ID_VENDOR_FROM_DATABASE=Epson
+
+pci:v0000100A*
+ ID_VENDOR_FROM_DATABASE=Phoenix Technologies
+
+pci:v0000100B*
+ ID_VENDOR_FROM_DATABASE=National Semiconductor Corporation
+
+pci:v0000100Bd00000001*
+ ID_PRODUCT_FROM_DATABASE=DP83810
+
+pci:v0000100Bd00000002*
+ ID_PRODUCT_FROM_DATABASE=87415/87560 IDE
+
+pci:v0000100Bd0000000E*
+ ID_PRODUCT_FROM_DATABASE=87560 Legacy I/O
+
+pci:v0000100Bd0000000F*
+ ID_PRODUCT_FROM_DATABASE=FireWire Controller
+
+pci:v0000100Bd00000011*
+ ID_PRODUCT_FROM_DATABASE=NS87560 National PCI System I/O
+
+pci:v0000100Bd00000012*
+ ID_PRODUCT_FROM_DATABASE=USB Controller
+
+pci:v0000100Bd00000020*
+ ID_PRODUCT_FROM_DATABASE=DP83815 (MacPhyter) Ethernet Controller
+
+pci:v0000100Bd00000020sv0000103Csd00000024*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin Network
+
+pci:v0000100Bd00000020sv000012D9sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=Aculab E1/T1 PMXc cPCI carrier card
+
+pci:v0000100Bd00000020sv00001385sd0000F311*
+ ID_PRODUCT_FROM_DATABASE=FA311 / FA312 (FA311 with WoL HW)
+
+pci:v0000100Bd00000021*
+ ID_PRODUCT_FROM_DATABASE=PC87200 PCI to ISA Bridge
+
+pci:v0000100Bd00000022*
+ ID_PRODUCT_FROM_DATABASE=DP83820 10/100/1000 Ethernet Controller
+
+pci:v0000100Bd00000022sv00001186sd00004900*
+ ID_PRODUCT_FROM_DATABASE=DGE-500T
+
+pci:v0000100Bd00000022sv00001385sd0000621A*
+ ID_PRODUCT_FROM_DATABASE=GA621
+
+pci:v0000100Bd00000022sv00001385sd0000622A*
+ ID_PRODUCT_FROM_DATABASE=GA622T
+
+pci:v0000100Bd00000028*
+ ID_PRODUCT_FROM_DATABASE=Geode GX2 Host Bridge
+
+pci:v0000100Bd0000002A*
+ ID_PRODUCT_FROM_DATABASE=CS5535 South Bridge
+
+pci:v0000100Bd0000002B*
+ ID_PRODUCT_FROM_DATABASE=CS5535 ISA bridge
+
+pci:v0000100Bd0000002D*
+ ID_PRODUCT_FROM_DATABASE=CS5535 IDE
+
+pci:v0000100Bd0000002E*
+ ID_PRODUCT_FROM_DATABASE=CS5535 Audio
+
+pci:v0000100Bd0000002F*
+ ID_PRODUCT_FROM_DATABASE=CS5535 USB
+
+pci:v0000100Bd00000030*
+ ID_PRODUCT_FROM_DATABASE=Geode GX2 Graphics Processor
+
+pci:v0000100Bd00000035*
+ ID_PRODUCT_FROM_DATABASE=DP83065 [Saturn] 10/100/1000 Ethernet Controller
+
+pci:v0000100Bd00000500*
+ ID_PRODUCT_FROM_DATABASE=SCx200 Bridge
+
+pci:v0000100Bd00000501*
+ ID_PRODUCT_FROM_DATABASE=SCx200 SMI
+
+pci:v0000100Bd00000502*
+ ID_PRODUCT_FROM_DATABASE=SCx200, SC1100 IDE controller
+
+pci:v0000100Bd00000502sv0000100Bsd00000502*
+ ID_PRODUCT_FROM_DATABASE=IDE Controller
+
+pci:v0000100Bd00000503*
+ ID_PRODUCT_FROM_DATABASE=SCx200, SC1100 Audio Controller
+
+pci:v0000100Bd00000503sv0000100Bsd00000503*
+ ID_PRODUCT_FROM_DATABASE=XpressAudio controller
+
+pci:v0000100Bd00000504*
+ ID_PRODUCT_FROM_DATABASE=SCx200 Video
+
+pci:v0000100Bd00000505*
+ ID_PRODUCT_FROM_DATABASE=SCx200 XBus
+
+pci:v0000100Bd00000510*
+ ID_PRODUCT_FROM_DATABASE=SC1100 Bridge
+
+pci:v0000100Bd00000510sv0000100Bsd00000500*
+ ID_PRODUCT_FROM_DATABASE=GPIO and LPC support bridge
+
+pci:v0000100Bd00000511*
+ ID_PRODUCT_FROM_DATABASE=SC1100 SMI & ACPI
+
+pci:v0000100Bd00000511sv0000100Bsd00000501*
+ ID_PRODUCT_FROM_DATABASE=SC1100 SMI & ACPI bridge
+
+pci:v0000100Bd00000515*
+ ID_PRODUCT_FROM_DATABASE=SC1100 XBus
+
+pci:v0000100Bd00000515sv0000100Bsd00000505*
+ ID_PRODUCT_FROM_DATABASE=SC1100 PCI to XBus bridge
+
+pci:v0000100Bd0000D001*
+ ID_PRODUCT_FROM_DATABASE=87410 IDE
+
+pci:v0000100C*
+ ID_VENDOR_FROM_DATABASE=Tseng Labs Inc
+
+pci:v0000100Cd00003202*
+ ID_PRODUCT_FROM_DATABASE=ET4000/W32p rev A
+
+pci:v0000100Cd00003205*
+ ID_PRODUCT_FROM_DATABASE=ET4000/W32p rev B
+
+pci:v0000100Cd00003206*
+ ID_PRODUCT_FROM_DATABASE=ET4000/W32p rev C
+
+pci:v0000100Cd00003207*
+ ID_PRODUCT_FROM_DATABASE=ET4000/W32p rev D
+
+pci:v0000100Cd00003208*
+ ID_PRODUCT_FROM_DATABASE=ET6000
+
+pci:v0000100Cd00004702*
+ ID_PRODUCT_FROM_DATABASE=ET6300
+
+pci:v0000100D*
+ ID_VENDOR_FROM_DATABASE=AST Research Inc
+
+pci:v0000100E*
+ ID_VENDOR_FROM_DATABASE=Weitek
+
+pci:v0000100Ed00009000*
+ ID_PRODUCT_FROM_DATABASE=P9000 Viper
+
+pci:v0000100Ed00009001*
+ ID_PRODUCT_FROM_DATABASE=P9000 Viper
+
+pci:v0000100Ed00009002*
+ ID_PRODUCT_FROM_DATABASE=P9000 Viper
+
+pci:v0000100Ed00009100*
+ ID_PRODUCT_FROM_DATABASE=P9100 Viper Pro/SE
+
+pci:v00001010*
+ ID_VENDOR_FROM_DATABASE=Video Logic, Ltd.
+
+pci:v00001011*
+ ID_VENDOR_FROM_DATABASE=Digital Equipment Corporation
+
+pci:v00001011d00000001*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21050
+
+pci:v00001011d00000002*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21040 [Tulip]
+
+pci:v00001011d00000004*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21030 [TGA]
+
+pci:v00001011d00000007*
+ ID_PRODUCT_FROM_DATABASE=NVRAM [Zephyr NVRAM]
+
+pci:v00001011d00000008*
+ ID_PRODUCT_FROM_DATABASE=KZPSA [KZPSA]
+
+pci:v00001011d00000009*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21140 [FasterNet]
+
+pci:v00001011d00000009sv00001025sd00000310*
+ ID_PRODUCT_FROM_DATABASE=21140 Fast Ethernet
+
+pci:v00001011d00000009sv000010B8sd00002001*
+ ID_PRODUCT_FROM_DATABASE=SMC9332BDT EtherPower 10/100
+
+pci:v00001011d00000009sv000010B8sd00002002*
+ ID_PRODUCT_FROM_DATABASE=SMC9332BVT EtherPower T4 10/100
+
+pci:v00001011d00000009sv000010B8sd00002003*
+ ID_PRODUCT_FROM_DATABASE=SMC9334BDT EtherPower 10/100 (1-port)
+
+pci:v00001011d00000009sv00001109sd00002400*
+ ID_PRODUCT_FROM_DATABASE=ANA-6944A/TX Fast Ethernet
+
+pci:v00001011d00000009sv00001112sd00002300*
+ ID_PRODUCT_FROM_DATABASE=RNS2300 Fast Ethernet
+
+pci:v00001011d00000009sv00001112sd00002320*
+ ID_PRODUCT_FROM_DATABASE=RNS2320 Fast Ethernet
+
+pci:v00001011d00000009sv00001112sd00002340*
+ ID_PRODUCT_FROM_DATABASE=RNS2340 Fast Ethernet
+
+pci:v00001011d00000009sv00001113sd00001207*
+ ID_PRODUCT_FROM_DATABASE=EN-1207-TX Fast Ethernet
+
+pci:v00001011d00000009sv00001186sd00001100*
+ ID_PRODUCT_FROM_DATABASE=DFE-500TX Fast Ethernet
+
+pci:v00001011d00000009sv00001186sd00001112*
+ ID_PRODUCT_FROM_DATABASE=DFE-570TX Fast Ethernet
+
+pci:v00001011d00000009sv00001186sd00001140*
+ ID_PRODUCT_FROM_DATABASE=DFE-660 Cardbus Ethernet 10/100
+
+pci:v00001011d00000009sv00001186sd00001142*
+ ID_PRODUCT_FROM_DATABASE=DFE-660 Cardbus Ethernet 10/100
+
+pci:v00001011d00000009sv000011F6sd00000503*
+ ID_PRODUCT_FROM_DATABASE=Freedomline Fast Ethernet
+
+pci:v00001011d00000009sv00001282sd00009100*
+ ID_PRODUCT_FROM_DATABASE=AEF-380TXD Fast Ethernet
+
+pci:v00001011d00000009sv00001385sd00001100*
+ ID_PRODUCT_FROM_DATABASE=FA310TX Fast Ethernet
+
+pci:v00001011d00000009sv00002646sd00000001*
+ ID_PRODUCT_FROM_DATABASE=KNE100TX Fast Ethernet
+
+pci:v00001011d0000000A*
+ ID_PRODUCT_FROM_DATABASE=21230 Video Codec
+
+pci:v00001011d0000000D*
+ ID_PRODUCT_FROM_DATABASE=PBXGB [TGA2]
+
+pci:v00001011d0000000F*
+ ID_PRODUCT_FROM_DATABASE=PCI-to-PDQ Interface Chip [PFI]
+
+pci:v00001011d0000000Fsv00001011sd0000DEF1*
+ ID_PRODUCT_FROM_DATABASE=FDDI controller (DEFPA)
+
+pci:v00001011d0000000Fsv0000103Csd0000DEF1*
+ ID_PRODUCT_FROM_DATABASE=FDDI controller (3X-DEFPA)
+
+pci:v00001011d00000014*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21041 [Tulip Pass 3]
+
+pci:v00001011d00000014sv00001186sd00000100*
+ ID_PRODUCT_FROM_DATABASE=DE-530+
+
+pci:v00001011d00000016*
+ ID_PRODUCT_FROM_DATABASE=DGLPB [OPPO]
+
+pci:v00001011d00000017*
+ ID_PRODUCT_FROM_DATABASE=PV-PCI Graphics Controller (ZLXp-L)
+
+pci:v00001011d00000018*
+ ID_PRODUCT_FROM_DATABASE=Memory Channel interface
+
+pci:v00001011d00000019*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21142/43
+
+pci:v00001011d00000019sv00001011sd0000500A*
+ ID_PRODUCT_FROM_DATABASE=DE500A Fast Ethernet
+
+pci:v00001011d00000019sv00001011sd0000500B*
+ ID_PRODUCT_FROM_DATABASE=DE500B Fast Ethernet
+
+pci:v00001011d00000019sv00001014sd00000001*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus
+
+pci:v00001011d00000019sv00001025sd00000315*
+ ID_PRODUCT_FROM_DATABASE=ALN315 Fast Ethernet
+
+pci:v00001011d00000019sv00001033sd0000800C*
+ ID_PRODUCT_FROM_DATABASE=PC-9821-CS01 100BASE-TX Interface Card
+
+pci:v00001011d00000019sv00001033sd0000800D*
+ ID_PRODUCT_FROM_DATABASE=PC-9821NR-B06 100BASE-TX Interface Card
+
+pci:v00001011d00000019sv0000103Csd0000125A*
+ ID_PRODUCT_FROM_DATABASE=10/100Base-TX (PCI) [A5506B]
+
+pci:v00001011d00000019sv0000108Dsd00000016*
+ ID_PRODUCT_FROM_DATABASE=Rapidfire 2327 10/100 Ethernet
+
+pci:v00001011d00000019sv0000108Dsd00000017*
+ ID_PRODUCT_FROM_DATABASE=GoCard 2250 Ethernet 10/100 Cardbus
+
+pci:v00001011d00000019sv000010B8sd00002005*
+ ID_PRODUCT_FROM_DATABASE=SMC8032DT Extreme Ethernet 10/100
+
+pci:v00001011d00000019sv000010B8sd00008034*
+ ID_PRODUCT_FROM_DATABASE=SMC8034 Extreme Ethernet 10/100
+
+pci:v00001011d00000019sv000010EFsd00008169*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Fast Ethernet
+
+pci:v00001011d00000019sv00001109sd00002A00*
+ ID_PRODUCT_FROM_DATABASE=ANA-6911A/TX Fast Ethernet
+
+pci:v00001011d00000019sv00001109sd00002B00*
+ ID_PRODUCT_FROM_DATABASE=ANA-6911A/TXC Fast Ethernet
+
+pci:v00001011d00000019sv00001109sd00003000*
+ ID_PRODUCT_FROM_DATABASE=ANA-6922/TX Fast Ethernet
+
+pci:v00001011d00000019sv00001113sd00001207*
+ ID_PRODUCT_FROM_DATABASE=Cheetah Fast Ethernet
+
+pci:v00001011d00000019sv00001113sd00002220*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Fast Ethernet
+
+pci:v00001011d00000019sv0000115Dsd00000002*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v00001011d00000019sv00001179sd00000203*
+ ID_PRODUCT_FROM_DATABASE=Fast Ethernet
+
+pci:v00001011d00000019sv00001179sd00000204*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Fast Ethernet
+
+pci:v00001011d00000019sv00001186sd00001100*
+ ID_PRODUCT_FROM_DATABASE=DFE-500TX Fast Ethernet
+
+pci:v00001011d00000019sv00001186sd00001101*
+ ID_PRODUCT_FROM_DATABASE=DFE-500TX Fast Ethernet
+
+pci:v00001011d00000019sv00001186sd00001102*
+ ID_PRODUCT_FROM_DATABASE=DFE-500TX Fast Ethernet
+
+pci:v00001011d00000019sv00001186sd00001112*
+ ID_PRODUCT_FROM_DATABASE=DFE-570TX Quad Fast Ethernet
+
+pci:v00001011d00000019sv00001259sd00002800*
+ ID_PRODUCT_FROM_DATABASE=AT-2800Tx Fast Ethernet
+
+pci:v00001011d00000019sv00001266sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Eagle Fast EtherMAX
+
+pci:v00001011d00000019sv000012AFsd00000019*
+ ID_PRODUCT_FROM_DATABASE=NetFlyer Cardbus Fast Ethernet
+
+pci:v00001011d00000019sv00001374sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet Card 10/100
+
+pci:v00001011d00000019sv00001374sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet Card 10/100
+
+pci:v00001011d00000019sv00001374sd00000007*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet Card 10/100
+
+pci:v00001011d00000019sv00001374sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet Card 10/100
+
+pci:v00001011d00000019sv00001385sd00002100*
+ ID_PRODUCT_FROM_DATABASE=FA510
+
+pci:v00001011d00000019sv00001395sd00000001*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet CardBus PC Card
+
+pci:v00001011d00000019sv000013D1sd0000AB01*
+ ID_PRODUCT_FROM_DATABASE=EtherFast 10/100 Cardbus (PCMPC200)
+
+pci:v00001011d00000019sv00001498sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=TPMC880-10 10/100Base-T and 10Base2 PMC Ethernet Adapter
+
+pci:v00001011d00000019sv00001498sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=TPMC880-11 Single 10/100Base-T PMC Ethernet Adapter
+
+pci:v00001011d00000019sv00001498sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=TPMC880-12 Single 10Base2 PMC Ethernet Adapter
+
+pci:v00001011d00000019sv000014CBsd00000100*
+ ID_PRODUCT_FROM_DATABASE=LNDL-100N 100Base-TX Ethernet PC Card
+
+pci:v00001011d00000019sv00001668sd00002000*
+ ID_PRODUCT_FROM_DATABASE=FastNet Pro (PE2000)
+
+pci:v00001011d00000019sv00002646sd00000001*
+ ID_PRODUCT_FROM_DATABASE=KNE100TX
+
+pci:v00001011d00000019sv00002646sd00000002*
+ ID_PRODUCT_FROM_DATABASE=KNE-CB4TX
+
+pci:v00001011d00000019sv00008086sd00000001*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32
+
+pci:v00001011d0000001A*
+ ID_PRODUCT_FROM_DATABASE=Farallon PN9000SX Gigabit Ethernet
+
+pci:v00001011d00000021*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21052
+
+pci:v00001011d00000022*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21150
+
+pci:v00001011d00000023*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21150
+
+pci:v00001011d00000024*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21152
+
+pci:v00001011d00000025*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21153
+
+pci:v00001011d00000026*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21154
+
+pci:v00001011d00000034*
+ ID_PRODUCT_FROM_DATABASE=56k Modem Cardbus
+
+pci:v00001011d00000034sv00001374sd00000003*
+ ID_PRODUCT_FROM_DATABASE=56k Modem Cardbus
+
+pci:v00001011d00000045*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21553
+
+pci:v00001011d00000046*
+ ID_PRODUCT_FROM_DATABASE=DECchip 21554
+
+pci:v00001011d00000046sv00000E11sd00004050*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 4200 Controller
+
+pci:v00001011d00000046sv00000E11sd00004051*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 4250ES Controller
+
+pci:v00001011d00000046sv00000E11sd00004058*
+ ID_PRODUCT_FROM_DATABASE=Smart Array 431 Controller
+
+pci:v00001011d00000046sv0000103Csd000010C2*
+ ID_PRODUCT_FROM_DATABASE=NetRAID-4M
+
+pci:v00001011d00000046sv000012D9sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=IP Telephony card
+
+pci:v00001011d00000046sv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v00001011d00000046sv00004C53sd00001051*
+ ID_PRODUCT_FROM_DATABASE=CE7 mainboard
+
+pci:v00001011d00000046sv00009005sd00000364*
+ ID_PRODUCT_FROM_DATABASE=5400S (Mustang)
+
+pci:v00001011d00000046sv00009005sd00000365*
+ ID_PRODUCT_FROM_DATABASE=5400S (Mustang)
+
+pci:v00001011d00000046sv00009005sd00001364*
+ ID_PRODUCT_FROM_DATABASE=Dell PowerEdge RAID Controller 2
+
+pci:v00001011d00000046sv00009005sd00001365*
+ ID_PRODUCT_FROM_DATABASE=Dell PowerEdge RAID Controller 2
+
+pci:v00001011d00000046sv0000E4BFsd00001000*
+ ID_PRODUCT_FROM_DATABASE=CC8-1-BLUES
+
+pci:v00001011d00001065*
+ ID_PRODUCT_FROM_DATABASE=StrongARM DC21285
+
+pci:v00001011d00001065sv00001069sd00000020*
+ ID_PRODUCT_FROM_DATABASE=DAC960P / DAC1164P
+
+pci:v00001012*
+ ID_VENDOR_FROM_DATABASE=Micronics Computers Inc
+
+pci:v00001013*
+ ID_VENDOR_FROM_DATABASE=Cirrus Logic
+
+pci:v00001013d00000038*
+ ID_PRODUCT_FROM_DATABASE=GD 7548
+
+pci:v00001013d00000040*
+ ID_PRODUCT_FROM_DATABASE=GD 7555 Flat Panel GUI Accelerator
+
+pci:v00001013d0000004C*
+ ID_PRODUCT_FROM_DATABASE=GD 7556 Video/Graphics LCD/CRT Ctrlr
+
+pci:v00001013d000000A0*
+ ID_PRODUCT_FROM_DATABASE=GD 5430/40 [Alpine]
+
+pci:v00001013d000000A2*
+ ID_PRODUCT_FROM_DATABASE=GD 5432 [Alpine]
+
+pci:v00001013d000000A4*
+ ID_PRODUCT_FROM_DATABASE=GD 5434-4 [Alpine]
+
+pci:v00001013d000000A8*
+ ID_PRODUCT_FROM_DATABASE=GD 5434-8 [Alpine]
+
+pci:v00001013d000000AC*
+ ID_PRODUCT_FROM_DATABASE=GD 5436 [Alpine]
+
+pci:v00001013d000000B0*
+ ID_PRODUCT_FROM_DATABASE=GD 5440
+
+pci:v00001013d000000B8*
+ ID_PRODUCT_FROM_DATABASE=GD 5446
+
+pci:v00001013d000000BC*
+ ID_PRODUCT_FROM_DATABASE=GD 5480
+
+pci:v00001013d000000BCsv00001013sd000000BC*
+ ID_PRODUCT_FROM_DATABASE=CL-GD5480
+
+pci:v00001013d000000D0*
+ ID_PRODUCT_FROM_DATABASE=GD 5462
+
+pci:v00001013d000000D2*
+ ID_PRODUCT_FROM_DATABASE=GD 5462 [Laguna I]
+
+pci:v00001013d000000D4*
+ ID_PRODUCT_FROM_DATABASE=GD 5464 [Laguna]
+
+pci:v00001013d000000D5*
+ ID_PRODUCT_FROM_DATABASE=GD 5464 BD [Laguna]
+
+pci:v00001013d000000D6*
+ ID_PRODUCT_FROM_DATABASE=GD 5465 [Laguna]
+
+pci:v00001013d000000D6sv000013CEsd00008031*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 2 Megapixel, Dual Head
+
+pci:v00001013d000000D6sv000013CFsd00008031*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 2 Megapixel, Dual Head
+
+pci:v00001013d000000E8*
+ ID_PRODUCT_FROM_DATABASE=GD 5436U
+
+pci:v00001013d00001100*
+ ID_PRODUCT_FROM_DATABASE=CL 6729
+
+pci:v00001013d00001110*
+ ID_PRODUCT_FROM_DATABASE=PD 6832 PCMCIA/CardBus Ctrlr
+
+pci:v00001013d00001112*
+ ID_PRODUCT_FROM_DATABASE=PD 6834 PCMCIA/CardBus Ctrlr
+
+pci:v00001013d00001113*
+ ID_PRODUCT_FROM_DATABASE=PD 6833 PCMCIA/CardBus Ctrlr
+
+pci:v00001013d00001200*
+ ID_PRODUCT_FROM_DATABASE=GD 7542 [Nordic]
+
+pci:v00001013d00001202*
+ ID_PRODUCT_FROM_DATABASE=GD 7543 [Viking]
+
+pci:v00001013d00001204*
+ ID_PRODUCT_FROM_DATABASE=GD 7541 [Nordic Light]
+
+pci:v00001013d00004000*
+ ID_PRODUCT_FROM_DATABASE=MD 5620 [CLM Data Fax Voice]
+
+pci:v00001013d00004400*
+ ID_PRODUCT_FROM_DATABASE=CD 4400
+
+pci:v00001013d00006001*
+ ID_PRODUCT_FROM_DATABASE=CS 4610/11 [CrystalClear SoundFusion Audio Accelerator]
+
+pci:v00001013d00006001sv00001014sd00001010*
+ ID_PRODUCT_FROM_DATABASE=CS4610 SoundFusion Audio Accelerator
+
+pci:v00001013d00006003*
+ ID_PRODUCT_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator]
+
+pci:v00001013d00006003sv00001013sd00004280*
+ ID_PRODUCT_FROM_DATABASE=Crystal SoundFusion PCI Audio Accelerator
+
+pci:v00001013d00006003sv00001014sd00000153*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 600X/A20m
+
+pci:v00001013d00006003sv0000153Bsd0000112E*
+ ID_PRODUCT_FROM_DATABASE=DMX XFire 1024
+
+pci:v00001013d00006003sv0000153Bsd00001136*
+ ID_PRODUCT_FROM_DATABASE=SiXPack 5.1+
+
+pci:v00001013d00006003sv00001681sd00000050*
+ ID_PRODUCT_FROM_DATABASE=Game Theater XP
+
+pci:v00001013d00006003sv00001681sd0000A010*
+ ID_PRODUCT_FROM_DATABASE=Gamesurround Fortissimo II
+
+pci:v00001013d00006003sv00001681sd0000A011*
+ ID_PRODUCT_FROM_DATABASE=Gamesurround Fortissimo III 7.1
+
+pci:v00001013d00006003sv00005053sd00003357*
+ ID_PRODUCT_FROM_DATABASE=Santa Cruz
+
+pci:v00001013d00006004*
+ ID_PRODUCT_FROM_DATABASE=CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
+
+pci:v00001013d00006005*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv00001013sd00004281*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv000010CFsd000010A8*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv000010CFsd000010A9*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv000010CFsd000010AA*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv000010CFsd000010AB*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv000010CFsd000010AC*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv000010CFsd000010AD*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv000010CFsd000010B4*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001013d00006005sv000014C0sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio
+
+pci:v00001014*
+ ID_VENDOR_FROM_DATABASE=IBM
+
+pci:v00001014d00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI to MCA Bridge
+
+pci:v00001014d00000005*
+ ID_PRODUCT_FROM_DATABASE=Processor to I/O Controller [Alta Lite]
+
+pci:v00001014d00000007*
+ ID_PRODUCT_FROM_DATABASE=Processor to I/O Controller [Alta MP]
+
+pci:v00001014d0000000A*
+ ID_PRODUCT_FROM_DATABASE=PCI to ISA Bridge (IBM27-82376) [Fire Coral]
+
+pci:v00001014d00000017*
+ ID_PRODUCT_FROM_DATABASE=CPU to PCI Bridge
+
+pci:v00001014d00000018*
+ ID_PRODUCT_FROM_DATABASE=TR Auto LANstreamer
+
+pci:v00001014d0000001B*
+ ID_PRODUCT_FROM_DATABASE=GXT-150P
+
+pci:v00001014d0000001C*
+ ID_PRODUCT_FROM_DATABASE=Carrera
+
+pci:v00001014d0000001D*
+ ID_PRODUCT_FROM_DATABASE=SCSI-2 FAST PCI Adapter (82G2675)
+
+pci:v00001014d00000020*
+ ID_PRODUCT_FROM_DATABASE=GXT1000 Graphics Adapter
+
+pci:v00001014d00000022*
+ ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge (IBM27-82351)
+
+pci:v00001014d0000002D*
+ ID_PRODUCT_FROM_DATABASE=Processor to I/O Controller [Python]
+
+pci:v00001014d0000002E*
+ ID_PRODUCT_FROM_DATABASE=SCSI RAID Adapter [ServeRAID]
+
+pci:v00001014d0000002Esv00001014sd0000002E*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-3x
+
+pci:v00001014d0000002Esv00001014sd0000022E*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-4H
+
+pci:v00001014d00000031*
+ ID_PRODUCT_FROM_DATABASE=2 Port Serial Adapter
+
+pci:v00001014d00000031sv00001014sd00000031*
+ ID_PRODUCT_FROM_DATABASE=2721 WAN IOA - 2 Port Sync Serial Adapter
+
+pci:v00001014d00000036*
+ ID_PRODUCT_FROM_DATABASE=PCI to 32-bit LocalBus Bridge [Miami]
+
+pci:v00001014d00000037*
+ ID_PRODUCT_FROM_DATABASE=PowerPC to PCI Bridge (IBM27-82660)
+
+pci:v00001014d0000003A*
+ ID_PRODUCT_FROM_DATABASE=CPU to PCI Bridge
+
+pci:v00001014d0000003C*
+ ID_PRODUCT_FROM_DATABASE=GXT250P/GXT255P Graphics Adapter
+
+pci:v00001014d0000003E*
+ ID_PRODUCT_FROM_DATABASE=16/4 Token ring UTP/STP controller
+
+pci:v00001014d0000003Esv00001014sd0000003E*
+ ID_PRODUCT_FROM_DATABASE=Token-Ring Adapter
+
+pci:v00001014d0000003Esv00001014sd000000CD*
+ ID_PRODUCT_FROM_DATABASE=Token-Ring Adapter + Wake-On-LAN
+
+pci:v00001014d0000003Esv00001014sd000000CE*
+ ID_PRODUCT_FROM_DATABASE=16/4 Token-Ring Adapter 2
+
+pci:v00001014d0000003Esv00001014sd000000CF*
+ ID_PRODUCT_FROM_DATABASE=16/4 Token-Ring Adapter Special
+
+pci:v00001014d0000003Esv00001014sd000000E4*
+ ID_PRODUCT_FROM_DATABASE=High-Speed 100/16/4 Token-Ring Adapter
+
+pci:v00001014d0000003Esv00001014sd000000E5*
+ ID_PRODUCT_FROM_DATABASE=16/4 Token-Ring Adapter 2 + Wake-On-LAN
+
+pci:v00001014d0000003Esv00001014sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=iSeries 2744 Card
+
+pci:v00001014d00000045*
+ ID_PRODUCT_FROM_DATABASE=SSA Adapter
+
+pci:v00001014d00000046*
+ ID_PRODUCT_FROM_DATABASE=MPIC interrupt controller
+
+pci:v00001014d00000047*
+ ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge
+
+pci:v00001014d00000048*
+ ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge
+
+pci:v00001014d00000049*
+ ID_PRODUCT_FROM_DATABASE=Warhead SCSI Controller
+
+pci:v00001014d0000004E*
+ ID_PRODUCT_FROM_DATABASE=ATM Controller (14104e00)
+
+pci:v00001014d0000004F*
+ ID_PRODUCT_FROM_DATABASE=ATM Controller (14104f00)
+
+pci:v00001014d00000050*
+ ID_PRODUCT_FROM_DATABASE=ATM Controller (14105000)
+
+pci:v00001014d00000053*
+ ID_PRODUCT_FROM_DATABASE=25 MBit ATM Controller
+
+pci:v00001014d00000054*
+ ID_PRODUCT_FROM_DATABASE=GXT500P/GXT550P Graphics Adapter
+
+pci:v00001014d00000057*
+ ID_PRODUCT_FROM_DATABASE=MPEG PCI Bridge
+
+pci:v00001014d00000058*
+ ID_PRODUCT_FROM_DATABASE=SSA Adapter [Advanced SerialRAID/X]
+
+pci:v00001014d0000005C*
+ ID_PRODUCT_FROM_DATABASE=i82557B 10/100
+
+pci:v00001014d0000005E*
+ ID_PRODUCT_FROM_DATABASE=GXT800P Graphics Adapter
+
+pci:v00001014d0000007C*
+ ID_PRODUCT_FROM_DATABASE=ATM Controller (14107c00)
+
+pci:v00001014d0000007D*
+ ID_PRODUCT_FROM_DATABASE=3780IDSP [MWave]
+
+pci:v00001014d0000008B*
+ ID_PRODUCT_FROM_DATABASE=EADS PCI to PCI Bridge
+
+pci:v00001014d0000008E*
+ ID_PRODUCT_FROM_DATABASE=GXT3000P Graphics Adapter
+
+pci:v00001014d00000090*
+ ID_PRODUCT_FROM_DATABASE=GXT 3000P
+
+pci:v00001014d00000090sv00001014sd0000008E*
+ ID_PRODUCT_FROM_DATABASE=GXT-3000P
+
+pci:v00001014d00000091*
+ ID_PRODUCT_FROM_DATABASE=SSA Adapter
+
+pci:v00001014d00000095*
+ ID_PRODUCT_FROM_DATABASE=20H2999 PCI Docking Bridge
+
+pci:v00001014d00000096*
+ ID_PRODUCT_FROM_DATABASE=Chukar chipset SCSI controller
+
+pci:v00001014d00000096sv00001014sd00000097*
+ ID_PRODUCT_FROM_DATABASE=iSeries 2778 DASD IOA
+
+pci:v00001014d00000096sv00001014sd00000098*
+ ID_PRODUCT_FROM_DATABASE=iSeries 2763 DASD IOA
+
+pci:v00001014d00000096sv00001014sd00000099*
+ ID_PRODUCT_FROM_DATABASE=iSeries 2748 DASD IOA
+
+pci:v00001014d0000009F*
+ ID_PRODUCT_FROM_DATABASE=PCI 4758 Cryptographic Accelerator
+
+pci:v00001014d000000A5*
+ ID_PRODUCT_FROM_DATABASE=ATM Controller (1410a500)
+
+pci:v00001014d000000A6*
+ ID_PRODUCT_FROM_DATABASE=ATM 155MBPS MM Controller (1410a600)
+
+pci:v00001014d000000B7*
+ ID_PRODUCT_FROM_DATABASE=256-bit Graphics Rasterizer [FireGL1]
+
+pci:v00001014d000000B7sv00001092sd000000B8*
+ ID_PRODUCT_FROM_DATABASE=FireGL1 AGP 32Mb
+
+pci:v00001014d000000B8*
+ ID_PRODUCT_FROM_DATABASE=GXT2000P Graphics Adapter
+
+pci:v00001014d000000BE*
+ ID_PRODUCT_FROM_DATABASE=ATM 622MBPS Controller (1410be00)
+
+pci:v00001014d000000DC*
+ ID_PRODUCT_FROM_DATABASE=Advanced Systems Management Adapter (ASMA)
+
+pci:v00001014d000000FC*
+ ID_PRODUCT_FROM_DATABASE=CPC710 Dual Bridge and Memory Controller (PCI-64)
+
+pci:v00001014d00000104*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX Adapter
+
+pci:v00001014d00000105*
+ ID_PRODUCT_FROM_DATABASE=CPC710 Dual Bridge and Memory Controller (PCI-32)
+
+pci:v00001014d0000010F*
+ ID_PRODUCT_FROM_DATABASE=Remote Supervisor Adapter (RSA)
+
+pci:v00001014d00000142*
+ ID_PRODUCT_FROM_DATABASE=Yotta Video Compositor Input
+
+pci:v00001014d00000142sv00001014sd00000143*
+ ID_PRODUCT_FROM_DATABASE=Yotta Input Controller (ytin)
+
+pci:v00001014d00000144*
+ ID_PRODUCT_FROM_DATABASE=Yotta Video Compositor Output
+
+pci:v00001014d00000144sv00001014sd00000145*
+ ID_PRODUCT_FROM_DATABASE=Yotta Output Controller (ytout)
+
+pci:v00001014d00000156*
+ ID_PRODUCT_FROM_DATABASE=405GP PLB to PCI Bridge
+
+pci:v00001014d0000015E*
+ ID_PRODUCT_FROM_DATABASE=622Mbps ATM PCI Adapter
+
+pci:v00001014d00000160*
+ ID_PRODUCT_FROM_DATABASE=64bit/66MHz PCI ATM 155 MMF
+
+pci:v00001014d0000016E*
+ ID_PRODUCT_FROM_DATABASE=GXT4000P Graphics Adapter
+
+pci:v00001014d00000170*
+ ID_PRODUCT_FROM_DATABASE=GXT6000P Graphics Adapter
+
+pci:v00001014d0000017D*
+ ID_PRODUCT_FROM_DATABASE=GXT300P Graphics Adapter
+
+pci:v00001014d00000180*
+ ID_PRODUCT_FROM_DATABASE=Snipe chipset SCSI controller
+
+pci:v00001014d00000180sv00001014sd00000241*
+ ID_PRODUCT_FROM_DATABASE=iSeries 2757 DASD IOA
+
+pci:v00001014d00000180sv00001014sd00000264*
+ ID_PRODUCT_FROM_DATABASE=Quad Channel PCI-X U320 SCSI RAID Adapter (2780)
+
+pci:v00001014d00000188*
+ ID_PRODUCT_FROM_DATABASE=EADS-X PCI-X to PCI-X Bridge
+
+pci:v00001014d000001A7*
+ ID_PRODUCT_FROM_DATABASE=PCI-X to PCI-X Bridge
+
+pci:v00001014d000001BD*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID Controller
+
+pci:v00001014d000001BDsv00001014sd000001BD*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 4Lx
+
+pci:v00001014d000001BDsv00001014sd000001BE*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-4M
+
+pci:v00001014d000001BDsv00001014sd000001BF*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-4L
+
+pci:v00001014d000001BDsv00001014sd00000208*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-4Mx
+
+pci:v00001014d000001BDsv00001014sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-4Lx
+
+pci:v00001014d000001BDsv00001014sd0000022E*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-4H
+
+pci:v00001014d000001BDsv00001014sd00000258*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-5i
+
+pci:v00001014d000001BDsv00001014sd00000259*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID-5i
+
+pci:v00001014d000001C1*
+ ID_PRODUCT_FROM_DATABASE=64bit/66MHz PCI ATM 155 UTP
+
+pci:v00001014d000001E6*
+ ID_PRODUCT_FROM_DATABASE=Cryptographic Accelerator
+
+pci:v00001014d000001EF*
+ ID_PRODUCT_FROM_DATABASE=PowerPC 440GP PCI Bridge
+
+pci:v00001014d000001EFsv00001734sd0000102B*
+ ID_PRODUCT_FROM_DATABASE=PCEAS PCI-X Dual Port ESCON Adapter
+
+pci:v00001014d000001EFsv00001734sd000010F8*
+ ID_PRODUCT_FROM_DATABASE=PCEAT PCI-Express Dual Port ESCON Adapter
+
+pci:v00001014d000001FF*
+ ID_PRODUCT_FROM_DATABASE=10/100 Mbps Ethernet
+
+pci:v00001014d00000219*
+ ID_PRODUCT_FROM_DATABASE=Multiport Serial Adapter
+
+pci:v00001014d00000219sv00001014sd0000021A*
+ ID_PRODUCT_FROM_DATABASE=Dual RVX
+
+pci:v00001014d00000219sv00001014sd00000251*
+ ID_PRODUCT_FROM_DATABASE=Internal Modem/RVX
+
+pci:v00001014d00000219sv00001014sd00000252*
+ ID_PRODUCT_FROM_DATABASE=Quad Internal Modem
+
+pci:v00001014d0000021B*
+ ID_PRODUCT_FROM_DATABASE=GXT6500P Graphics Adapter
+
+pci:v00001014d0000021C*
+ ID_PRODUCT_FROM_DATABASE=GXT4500P Graphics Adapter
+
+pci:v00001014d00000233*
+ ID_PRODUCT_FROM_DATABASE=GXT135P Graphics Adapter
+
+pci:v00001014d00000266*
+ ID_PRODUCT_FROM_DATABASE=PCI-X Dual Channel SCSI
+
+pci:v00001014d00000268*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX Adapter (PCI-X)
+
+pci:v00001014d00000269*
+ ID_PRODUCT_FROM_DATABASE=10/100/1000 Base-TX Ethernet Adapter (PCI-X)
+
+pci:v00001014d0000028C*
+ ID_PRODUCT_FROM_DATABASE=Citrine chipset SCSI controller
+
+pci:v00001014d0000028Csv00001014sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X DDR SAS RAID Adapter (572E)
+
+pci:v00001014d0000028Csv00001014sd000002BE*
+ ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B)
+
+pci:v00001014d0000028Csv00001014sd000002C0*
+ ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X DDR U320 SCSI Adapter (571A)
+
+pci:v00001014d0000028Csv00001014sd0000030D*
+ ID_PRODUCT_FROM_DATABASE=PCI-X DDR Auxiliary Cache Adapter (575B)
+
+pci:v00001014d000002A1*
+ ID_PRODUCT_FROM_DATABASE=Calgary PCI-X Host Bridge
+
+pci:v00001014d000002BD*
+ ID_PRODUCT_FROM_DATABASE=Obsidian chipset SCSI controller
+
+pci:v00001014d000002BDsv00001014sd000002C1*
+ ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS Adapter (572A/572C)
+
+pci:v00001014d000002BDsv00001014sd000002C2*
+ ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572B/571D)
+
+pci:v00001014d000002BDsv00001014sd00000338*
+ ID_PRODUCT_FROM_DATABASE=PCI-X DDR Auxiliary Cache Adapter (575C)
+
+pci:v00001014d00000302*
+ ID_PRODUCT_FROM_DATABASE=Winnipeg PCI-X Host Bridge
+
+pci:v00001014d00000308*
+ ID_PRODUCT_FROM_DATABASE=CalIOC2 PCI-E Root Port
+
+pci:v00001014d00000314*
+ ID_PRODUCT_FROM_DATABASE=ZISC 036 Neural accelerator card
+
+pci:v00001014d0000032D*
+ ID_PRODUCT_FROM_DATABASE=Axon - Cell Companion Chip
+
+pci:v00001014d0000032Dsv00001014sd000003A1*
+ ID_PRODUCT_FROM_DATABASE=PCIe PowerXCell 8i Cell Accelerator Board
+
+pci:v00001014d00000339*
+ ID_PRODUCT_FROM_DATABASE=Obsidian-E PCI-E SCSI controller
+
+pci:v00001014d00000339sv00001014sd0000030A*
+ ID_PRODUCT_FROM_DATABASE=PCIe 3Gb SAS RAID Adapter (574E)
+
+pci:v00001014d00000339sv00001014sd0000033A*
+ ID_PRODUCT_FROM_DATABASE=PCIe 3Gb SAS Adapter (57B3)
+
+pci:v00001014d00000339sv00001014sd0000035C*
+ ID_PRODUCT_FROM_DATABASE=PCIe x8 Internal 3Gb SAS adapter (57CC)
+
+pci:v00001014d00000339sv00001014sd00000360*
+ ID_PRODUCT_FROM_DATABASE=PCI-E Auxiliary Cache Adapter (57B7)
+
+pci:v00001014d0000033D*
+ ID_PRODUCT_FROM_DATABASE=PCI-E IPR SAS Adapter (FPGA)
+
+pci:v00001014d0000033Dsv00001014sd0000033C*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 1.8GB Cache 6Gb SAS RAID Adapter Tri-port (57B5)
+
+pci:v00001014d0000033Dsv00001014sd00000353*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 3.1GB Cache 6Gb SAS RAID Enclosure (57C3)
+
+pci:v00001014d0000033Dsv00001014sd00000354*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 6Gb SAS Adapter Dual-port (57C4)
+
+pci:v00001014d0000033Dsv00001014sd00000356*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 1.8GB Cache 6Gb SAS RAID & SSD Adapter (574D)
+
+pci:v00001014d0000033Dsv00001014sd0000035F*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 6Gb SAS Adapter Quad-port (57B2)
+
+pci:v00001014d0000034A*
+ ID_PRODUCT_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC)
+
+pci:v00001014d0000034Asv00001014sd0000033B*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 6Gb SAS RAID Adapter Quad-port (57B4)
+
+pci:v00001014d0000034Asv00001014sd00000355*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 3.6GB Cache 6Gb SAS RAID Adapter Quad-port (57B1)
+
+pci:v00001014d0000034Asv00001014sd00000357*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 6Gb SAS Adapter Quad-port (57C6)
+
+pci:v00001014d0000034Asv00001014sd0000035D*
+ ID_PRODUCT_FROM_DATABASE=PCIe3 1.8GB Cache RAID SAS Adapter Quad-port 6GB (57C8)
+
+pci:v00001014d0000034Asv00001014sd0000035E*
+ ID_PRODUCT_FROM_DATABASE=PCIe2 3.6GB Cache 6Gb SAS RAID Adapter Quad-port (57CE)
+
+pci:v00001014d0000034Asv00001014sd000003FB*
+ ID_PRODUCT_FROM_DATABASE=PCIe3 28GB Cache RAID SAS Enclosure 6Gb x 16 (57D5)
+
+pci:v00001014d00003022*
+ ID_PRODUCT_FROM_DATABASE=QLA3022 Network Adapter
+
+pci:v00001014d00004022*
+ ID_PRODUCT_FROM_DATABASE=QLA3022 Network Adapter
+
+pci:v00001014d0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=MPIC-2 interrupt controller
+
+pci:v00001015*
+ ID_VENDOR_FROM_DATABASE=LSI Logic Corp of Canada
+
+pci:v00001016*
+ ID_VENDOR_FROM_DATABASE=ICL Personal Systems
+
+pci:v00001017*
+ ID_VENDOR_FROM_DATABASE=SPEA Software AG
+
+pci:v00001017d00005343*
+ ID_PRODUCT_FROM_DATABASE=SPEA 3D Accelerator
+
+pci:v00001018*
+ ID_VENDOR_FROM_DATABASE=Unisys Systems
+
+pci:v00001019*
+ ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems
+
+pci:v0000101A*
+ ID_VENDOR_FROM_DATABASE=AT&T GIS (NCR)
+
+pci:v0000101Ad00000005*
+ ID_PRODUCT_FROM_DATABASE=100VG ethernet
+
+pci:v0000101Ad00000007*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC4G/2C/2G
+
+pci:v0000101Ad00000007sv0000101Asd00000019*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC2C
+
+pci:v0000101Ad00000007sv0000101Asd0000001C*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC2G
+
+pci:v0000101Ad00000007sv0000101Asd0000001F*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC4G
+
+pci:v0000101Ad00000009*
+ ID_PRODUCT_FROM_DATABASE=PQS Memory Controller
+
+pci:v0000101Ad0000000A*
+ ID_PRODUCT_FROM_DATABASE=BYNET BPCI Adapter
+
+pci:v0000101Ad0000000B*
+ ID_PRODUCT_FROM_DATABASE=BYNET 4 Port BYA Switch (BYA4P)
+
+pci:v0000101Ad0000000C*
+ ID_PRODUCT_FROM_DATABASE=BYNET 4 Port BYA Switch (BYA4G)
+
+pci:v0000101Ad00000010*
+ ID_PRODUCT_FROM_DATABASE=NCR AMC Memory Controller
+
+pci:v0000101Ad00001DC1*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC2M/BIC4M/BYA4M
+
+pci:v0000101Ad00001DC1sv0000101Asd00000019*
+ ID_PRODUCT_FROM_DATABASE=BIC2M
+
+pci:v0000101Ad00001DC1sv0000101Asd0000001F*
+ ID_PRODUCT_FROM_DATABASE=BIC4M
+
+pci:v0000101Ad00001DC1sv0000101Asd00000ECE*
+ ID_PRODUCT_FROM_DATABASE=BYA4M
+
+pci:v0000101Ad00001FA8*
+ ID_PRODUCT_FROM_DATABASE=BYNET Multi-port BIC Adapter (XBIC Based)
+
+pci:v0000101Ad00001FA8sv0000101Asd000000C3*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC2SE
+
+pci:v0000101B*
+ ID_VENDOR_FROM_DATABASE=Vitesse Semiconductor
+
+pci:v0000101Bd00000452*
+ ID_PRODUCT_FROM_DATABASE=VSC452 [SuperBMC]
+
+pci:v0000101C*
+ ID_VENDOR_FROM_DATABASE=Western Digital
+
+pci:v0000101Cd00000193*
+ ID_PRODUCT_FROM_DATABASE=33C193A
+
+pci:v0000101Cd00000196*
+ ID_PRODUCT_FROM_DATABASE=33C196A
+
+pci:v0000101Cd00000197*
+ ID_PRODUCT_FROM_DATABASE=33C197A
+
+pci:v0000101Cd00000296*
+ ID_PRODUCT_FROM_DATABASE=33C296A
+
+pci:v0000101Cd00003193*
+ ID_PRODUCT_FROM_DATABASE=7193
+
+pci:v0000101Cd00003197*
+ ID_PRODUCT_FROM_DATABASE=7197
+
+pci:v0000101Cd00003296*
+ ID_PRODUCT_FROM_DATABASE=33C296A
+
+pci:v0000101Cd00004296*
+ ID_PRODUCT_FROM_DATABASE=34C296
+
+pci:v0000101Cd00009710*
+ ID_PRODUCT_FROM_DATABASE=Pipeline 9710
+
+pci:v0000101Cd00009712*
+ ID_PRODUCT_FROM_DATABASE=Pipeline 9712
+
+pci:v0000101Cd0000C24A*
+ ID_PRODUCT_FROM_DATABASE=90C
+
+pci:v0000101D*
+ ID_VENDOR_FROM_DATABASE=Maxim Integrated Products
+
+pci:v0000101E*
+ ID_VENDOR_FROM_DATABASE=American Megatrends Inc.
+
+pci:v0000101Ed00000009*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 428 Ultra RAID Controller (rev 03)
+
+pci:v0000101Ed00001960*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID
+
+pci:v0000101Ed00001960sv0000101Esd00000471*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 471 Enterprise 1600 RAID Controller
+
+pci:v0000101Ed00001960sv0000101Esd00000475*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 475 Express 500/500LC RAID Controller
+
+pci:v0000101Ed00001960sv0000101Esd00000477*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 477 Elite 3100 RAID Controller
+
+pci:v0000101Ed00001960sv0000101Esd00000493*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 493 Elite 1600 RAID Controller
+
+pci:v0000101Ed00001960sv0000101Esd00000494*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 494 Elite 1650 RAID Controller
+
+pci:v0000101Ed00001960sv0000101Esd00000503*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 503 Enterprise 1650 RAID Controller
+
+pci:v0000101Ed00001960sv0000101Esd00000511*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 511 i4 IDE RAID Controller
+
+pci:v0000101Ed00001960sv0000101Esd00000522*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 522 i4133 RAID Controller
+
+pci:v0000101Ed00001960sv00001028sd00000471*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller 3/QC
+
+pci:v0000101Ed00001960sv00001028sd00000475*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller 3/SC
+
+pci:v0000101Ed00001960sv00001028sd00000493*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller 3/DC
+
+pci:v0000101Ed00001960sv00001028sd00000511*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Cost Effective RAID Controller ATA100/4Ch
+
+pci:v0000101Ed00001960sv0000103Csd000060E7*
+ ID_PRODUCT_FROM_DATABASE=NetRAID-1M
+
+pci:v0000101Ed00009010*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 428 Ultra RAID Controller
+
+pci:v0000101Ed00009030*
+ ID_PRODUCT_FROM_DATABASE=EIDE Controller
+
+pci:v0000101Ed00009031*
+ ID_PRODUCT_FROM_DATABASE=EIDE Controller
+
+pci:v0000101Ed00009032*
+ ID_PRODUCT_FROM_DATABASE=EIDE & SCSI Controller
+
+pci:v0000101Ed00009033*
+ ID_PRODUCT_FROM_DATABASE=SCSI Controller
+
+pci:v0000101Ed00009040*
+ ID_PRODUCT_FROM_DATABASE=Multimedia card
+
+pci:v0000101Ed00009060*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 434 Ultra GT RAID Controller
+
+pci:v0000101Ed00009063*
+ ID_PRODUCT_FROM_DATABASE=MegaRAC
+
+pci:v0000101Ed00009063sv0000101Esd00000767*
+ ID_PRODUCT_FROM_DATABASE=Dell Remote Assistant Card 2
+
+pci:v0000101F*
+ ID_VENDOR_FROM_DATABASE=PictureTel
+
+pci:v00001020*
+ ID_VENDOR_FROM_DATABASE=Hitachi Computer Products
+
+pci:v00001021*
+ ID_VENDOR_FROM_DATABASE=OKI Electric Industry Co. Ltd.
+
+pci:v00001022*
+ ID_VENDOR_FROM_DATABASE=Advanced Micro Devices [AMD]
+
+pci:v00001022d00001100*
+ ID_PRODUCT_FROM_DATABASE=K8 [Athlon64/Opteron] HyperTransport Technology Configuration
+
+pci:v00001022d00001101*
+ ID_PRODUCT_FROM_DATABASE=K8 [Athlon64/Opteron] Address Map
+
+pci:v00001022d00001102*
+ ID_PRODUCT_FROM_DATABASE=K8 [Athlon64/Opteron] DRAM Controller
+
+pci:v00001022d00001103*
+ ID_PRODUCT_FROM_DATABASE=K8 [Athlon64/Opteron] Miscellaneous Control
+
+pci:v00001022d00001200*
+ ID_PRODUCT_FROM_DATABASE=Family 10h Processor HyperTransport Configuration
+
+pci:v00001022d00001201*
+ ID_PRODUCT_FROM_DATABASE=Family 10h Processor Address Map
+
+pci:v00001022d00001202*
+ ID_PRODUCT_FROM_DATABASE=Family 10h Processor DRAM Controller
+
+pci:v00001022d00001203*
+ ID_PRODUCT_FROM_DATABASE=Family 10h Processor Miscellaneous Control
+
+pci:v00001022d00001204*
+ ID_PRODUCT_FROM_DATABASE=Family 10h Processor Link Control
+
+pci:v00001022d00001300*
+ ID_PRODUCT_FROM_DATABASE=Family 11h Processor HyperTransport Configuration
+
+pci:v00001022d00001301*
+ ID_PRODUCT_FROM_DATABASE=Family 11h Processor Address Map
+
+pci:v00001022d00001302*
+ ID_PRODUCT_FROM_DATABASE=Family 11h Processor DRAM Controller
+
+pci:v00001022d00001303*
+ ID_PRODUCT_FROM_DATABASE=Family 11h Processor Miscellaneous Control
+
+pci:v00001022d00001304*
+ ID_PRODUCT_FROM_DATABASE=Family 11h Processor Link Control
+
+pci:v00001022d00001400*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 0
+
+pci:v00001022d00001401*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 1
+
+pci:v00001022d00001402*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 2
+
+pci:v00001022d00001403*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 3
+
+pci:v00001022d00001404*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 4
+
+pci:v00001022d00001405*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 5
+
+pci:v00001022d00001410*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Complex
+
+pci:v00001022d00001412*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port
+
+pci:v00001022d00001413*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port
+
+pci:v00001022d00001414*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port
+
+pci:v00001022d00001415*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port
+
+pci:v00001022d00001416*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port
+
+pci:v00001022d00001417*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port
+
+pci:v00001022d00001418*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port
+
+pci:v00001022d00001419*
+ ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) I/O Memory Management Unit
+
+pci:v00001022d00001439*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Functions 5:1
+
+pci:v00001022d00001510*
+ ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Complex
+
+pci:v00001022d00001510sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001022d00001512*
+ ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port
+
+pci:v00001022d00001512sv0000174Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini
+
+pci:v00001022d00001513*
+ ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port
+
+pci:v00001022d00001514*
+ ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port
+
+pci:v00001022d00001515*
+ ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port
+
+pci:v00001022d00001516*
+ ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port
+
+pci:v00001022d00001530*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 0
+
+pci:v00001022d00001531*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 1
+
+pci:v00001022d00001532*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 2
+
+pci:v00001022d00001533*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 3
+
+pci:v00001022d00001534*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 4
+
+pci:v00001022d00001535*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 5
+
+pci:v00001022d00001536*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Root Complex
+
+pci:v00001022d00001538*
+ ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 0
+
+pci:v00001022d00001600*
+ ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 0
+
+pci:v00001022d00001601*
+ ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 1
+
+pci:v00001022d00001602*
+ ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 2
+
+pci:v00001022d00001603*
+ ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 3
+
+pci:v00001022d00001604*
+ ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 4
+
+pci:v00001022d00001605*
+ ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 5
+
+pci:v00001022d00001700*
+ ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 0
+
+pci:v00001022d00001701*
+ ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 1
+
+pci:v00001022d00001702*
+ ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 2
+
+pci:v00001022d00001703*
+ ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 3
+
+pci:v00001022d00001704*
+ ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 4
+
+pci:v00001022d00001705*
+ ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Complex
+
+pci:v00001022d00001707*
+ ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port
+
+pci:v00001022d00001708*
+ ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port
+
+pci:v00001022d00001709*
+ ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port
+
+pci:v00001022d0000170A*
+ ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port
+
+pci:v00001022d0000170B*
+ ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port
+
+pci:v00001022d0000170C*
+ ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port
+
+pci:v00001022d0000170D*
+ ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port
+
+pci:v00001022d00001716*
+ ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 5
+
+pci:v00001022d00001718*
+ ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 6
+
+pci:v00001022d00001719*
+ ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 7
+
+pci:v00001022d00002000*
+ ID_PRODUCT_FROM_DATABASE=79c970 [PCnet32 LANCE]
+
+pci:v00001022d00002000sv00001014sd00002000*
+ ID_PRODUCT_FROM_DATABASE=NetFinity 10/100 Fast Ethernet
+
+pci:v00001022d00002000sv00001022sd00002000*
+ ID_PRODUCT_FROM_DATABASE=PCnet - Fast 79C971
+
+pci:v00001022d00002000sv0000103Csd0000104C*
+ ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter
+
+pci:v00001022d00002000sv0000103Csd00001064*
+ ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter
+
+pci:v00001022d00002000sv0000103Csd00001065*
+ ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter
+
+pci:v00001022d00002000sv0000103Csd0000106C*
+ ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter
+
+pci:v00001022d00002000sv0000103Csd0000106E*
+ ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter
+
+pci:v00001022d00002000sv0000103Csd000010EA*
+ ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter
+
+pci:v00001022d00002000sv00001113sd00001220*
+ ID_PRODUCT_FROM_DATABASE=EN1220 10/100 Fast Ethernet
+
+pci:v00001022d00002000sv00001259sd00002450*
+ ID_PRODUCT_FROM_DATABASE=AT-2450 10/100 Fast Ethernet
+
+pci:v00001022d00002000sv00001259sd00002454*
+ ID_PRODUCT_FROM_DATABASE=AT-2450v4 10Mb Ethernet Adapter
+
+pci:v00001022d00002000sv00001259sd00002700*
+ ID_PRODUCT_FROM_DATABASE=AT-2700TX 10/100 Fast Ethernet
+
+pci:v00001022d00002000sv00001259sd00002701*
+ ID_PRODUCT_FROM_DATABASE=AT-2700FX 100Mb Ethernet
+
+pci:v00001022d00002000sv00001259sd00002702*
+ ID_PRODUCT_FROM_DATABASE=AT-2700FTX 10/100 Mb Fiber/Copper Fast Ethernet
+
+pci:v00001022d00002000sv00001259sd00002703*
+ ID_PRODUCT_FROM_DATABASE=AT-2701FX
+
+pci:v00001022d00002000sv00001259sd00002704*
+ ID_PRODUCT_FROM_DATABASE=AT-2701FTX 10/100 Mb Fiber/Copper Fast Ethernet
+
+pci:v00001022d00002000sv00004C53sd00001000*
+ ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+
+pci:v00001022d00002000sv00004C53sd00001010*
+ ID_PRODUCT_FROM_DATABASE=CP5/CR6 mainboard
+
+pci:v00001022d00002000sv00004C53sd00001020*
+ ID_PRODUCT_FROM_DATABASE=VR6 mainboard
+
+pci:v00001022d00002000sv00004C53sd00001030*
+ ID_PRODUCT_FROM_DATABASE=PC5 mainboard
+
+pci:v00001022d00002000sv00004C53sd00001040*
+ ID_PRODUCT_FROM_DATABASE=CL7 mainboard
+
+pci:v00001022d00002000sv00004C53sd00001060*
+ ID_PRODUCT_FROM_DATABASE=PC7 mainboard
+
+pci:v00001022d00002001*
+ ID_PRODUCT_FROM_DATABASE=79c978 [HomePNA]
+
+pci:v00001022d00002001sv00001092sd00000A78*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Home Network Adapter
+
+pci:v00001022d00002001sv00001668sd00000299*
+ ID_PRODUCT_FROM_DATABASE=ActionLink Home Network Adapter
+
+pci:v00001022d00002003*
+ ID_PRODUCT_FROM_DATABASE=Am 1771 MBW [Alchemy]
+
+pci:v00001022d00002020*
+ ID_PRODUCT_FROM_DATABASE=53c974 [PCscsi]
+
+pci:v00001022d00002040*
+ ID_PRODUCT_FROM_DATABASE=79c974
+
+pci:v00001022d00002080*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] Host Bridge
+
+pci:v00001022d00002081*
+ ID_PRODUCT_FROM_DATABASE=Geode LX Video
+
+pci:v00001022d00002082*
+ ID_PRODUCT_FROM_DATABASE=Geode LX AES Security Block
+
+pci:v00001022d0000208F*
+ ID_PRODUCT_FROM_DATABASE=CS5536 GeodeLink PCI South Bridge
+
+pci:v00001022d00002090*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] ISA
+
+pci:v00001022d00002091*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] FLASH
+
+pci:v00001022d00002093*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] Audio
+
+pci:v00001022d00002094*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] OHC
+
+pci:v00001022d00002095*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] EHC
+
+pci:v00001022d00002096*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] UDC
+
+pci:v00001022d00002097*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] UOC
+
+pci:v00001022d0000209A*
+ ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] IDE
+
+pci:v00001022d00003000*
+ ID_PRODUCT_FROM_DATABASE=ELanSC520 Microcontroller
+
+pci:v00001022d000043A0*
+ ID_PRODUCT_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 0)
+
+pci:v00001022d000043A1*
+ ID_PRODUCT_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 1)
+
+pci:v00001022d000043A2*
+ ID_PRODUCT_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 2)
+
+pci:v00001022d000043A3*
+ ID_PRODUCT_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 3)
+
+pci:v00001022d00007006*
+ ID_PRODUCT_FROM_DATABASE=AMD-751 [Irongate] System Controller
+
+pci:v00001022d00007007*
+ ID_PRODUCT_FROM_DATABASE=AMD-751 [Irongate] AGP Bridge
+
+pci:v00001022d0000700A*
+ ID_PRODUCT_FROM_DATABASE=AMD-IGR4 AGP Host to PCI Bridge
+
+pci:v00001022d0000700B*
+ ID_PRODUCT_FROM_DATABASE=AMD-IGR4 PCI to PCI Bridge
+
+pci:v00001022d0000700C*
+ ID_PRODUCT_FROM_DATABASE=AMD-760 MP [IGD4-2P] System Controller
+
+pci:v00001022d0000700D*
+ ID_PRODUCT_FROM_DATABASE=AMD-760 MP [IGD4-2P] AGP Bridge
+
+pci:v00001022d0000700E*
+ ID_PRODUCT_FROM_DATABASE=AMD-760 [IGD4-1P] System Controller
+
+pci:v00001022d0000700F*
+ ID_PRODUCT_FROM_DATABASE=AMD-760 [IGD4-1P] AGP Bridge
+
+pci:v00001022d00007400*
+ ID_PRODUCT_FROM_DATABASE=AMD-755 [Cobra] ISA
+
+pci:v00001022d00007401*
+ ID_PRODUCT_FROM_DATABASE=AMD-755 [Cobra] IDE
+
+pci:v00001022d00007403*
+ ID_PRODUCT_FROM_DATABASE=AMD-755 [Cobra] ACPI
+
+pci:v00001022d00007404*
+ ID_PRODUCT_FROM_DATABASE=AMD-755 [Cobra] USB
+
+pci:v00001022d00007408*
+ ID_PRODUCT_FROM_DATABASE=AMD-756 [Viper] ISA
+
+pci:v00001022d00007409*
+ ID_PRODUCT_FROM_DATABASE=AMD-756 [Viper] IDE
+
+pci:v00001022d0000740B*
+ ID_PRODUCT_FROM_DATABASE=AMD-756 [Viper] ACPI
+
+pci:v00001022d0000740C*
+ ID_PRODUCT_FROM_DATABASE=AMD-756 [Viper] USB
+
+pci:v00001022d00007410*
+ ID_PRODUCT_FROM_DATABASE=AMD-766 [ViperPlus] ISA
+
+pci:v00001022d00007411*
+ ID_PRODUCT_FROM_DATABASE=AMD-766 [ViperPlus] IDE
+
+pci:v00001022d00007413*
+ ID_PRODUCT_FROM_DATABASE=AMD-766 [ViperPlus] ACPI
+
+pci:v00001022d00007414*
+ ID_PRODUCT_FROM_DATABASE=AMD-766 [ViperPlus] USB
+
+pci:v00001022d00007440*
+ ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] ISA
+
+pci:v00001022d00007440sv00001043sd00008044*
+ ID_PRODUCT_FROM_DATABASE=A7M-D Mainboard
+
+pci:v00001022d00007441*
+ ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] IDE
+
+pci:v00001022d00007443*
+ ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] ACPI
+
+pci:v00001022d00007443sv00001043sd00008044*
+ ID_PRODUCT_FROM_DATABASE=A7M-D Mainboard
+
+pci:v00001022d00007445*
+ ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] Audio
+
+pci:v00001022d00007446*
+ ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] MC97 Modem
+
+pci:v00001022d00007448*
+ ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] PCI
+
+pci:v00001022d00007449*
+ ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] USB
+
+pci:v00001022d00007450*
+ ID_PRODUCT_FROM_DATABASE=AMD-8131 PCI-X Bridge
+
+pci:v00001022d00007451*
+ ID_PRODUCT_FROM_DATABASE=AMD-8131 PCI-X IOAPIC
+
+pci:v00001022d00007454*
+ ID_PRODUCT_FROM_DATABASE=AMD-8151 System Controller
+
+pci:v00001022d00007455*
+ ID_PRODUCT_FROM_DATABASE=AMD-8151 AGP Bridge
+
+pci:v00001022d00007458*
+ ID_PRODUCT_FROM_DATABASE=AMD-8132 PCI-X Bridge
+
+pci:v00001022d00007459*
+ ID_PRODUCT_FROM_DATABASE=AMD-8132 PCI-X IOAPIC
+
+pci:v00001022d00007460*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 PCI
+
+pci:v00001022d00007460sv0000161Fsd00003017*
+ ID_PRODUCT_FROM_DATABASE=HDAMB
+
+pci:v00001022d00007461*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 USB
+
+pci:v00001022d00007462*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 Ethernet
+
+pci:v00001022d00007463*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 USB EHCI
+
+pci:v00001022d00007464*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 USB OHCI
+
+pci:v00001022d00007464sv0000161Fsd00003017*
+ ID_PRODUCT_FROM_DATABASE=HDAMB
+
+pci:v00001022d00007468*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 LPC
+
+pci:v00001022d00007468sv0000161Fsd00003017*
+ ID_PRODUCT_FROM_DATABASE=HDAMB
+
+pci:v00001022d00007469*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 IDE
+
+pci:v00001022d00007469sv00001022sd00002B80*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 IDE [Quartet]
+
+pci:v00001022d00007469sv0000161Fsd00003017*
+ ID_PRODUCT_FROM_DATABASE=HDAMB
+
+pci:v00001022d0000746A*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 SMBus 2.0
+
+pci:v00001022d0000746B*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 ACPI
+
+pci:v00001022d0000746Bsv0000161Fsd00003017*
+ ID_PRODUCT_FROM_DATABASE=HDAMB
+
+pci:v00001022d0000746D*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 AC97 Audio
+
+pci:v00001022d0000746Dsv0000161Fsd00003017*
+ ID_PRODUCT_FROM_DATABASE=HDAMB
+
+pci:v00001022d0000746E*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 MC97 Modem
+
+pci:v00001022d0000756B*
+ ID_PRODUCT_FROM_DATABASE=AMD-8111 ACPI
+
+pci:v00001022d00007800*
+ ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [IDE mode]
+
+pci:v00001022d00007801*
+ ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [AHCI mode]
+
+pci:v00001022d00007802*
+ ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [RAID mode]
+
+pci:v00001022d00007803*
+ ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [RAID mode]
+
+pci:v00001022d00007804*
+ ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [AHCI mode]
+
+pci:v00001022d00007805*
+ ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [RAID mode]
+
+pci:v00001022d00007806*
+ ID_PRODUCT_FROM_DATABASE=FCH SD Flash Controller
+
+pci:v00001022d00007807*
+ ID_PRODUCT_FROM_DATABASE=FCH USB OHCI Controller
+
+pci:v00001022d00007808*
+ ID_PRODUCT_FROM_DATABASE=FCH USB EHCI Controller
+
+pci:v00001022d00007809*
+ ID_PRODUCT_FROM_DATABASE=FCH USB OHCI Controller
+
+pci:v00001022d0000780B*
+ ID_PRODUCT_FROM_DATABASE=FCH SMBus Controller
+
+pci:v00001022d0000780C*
+ ID_PRODUCT_FROM_DATABASE=FCH IDE Controller
+
+pci:v00001022d0000780D*
+ ID_PRODUCT_FROM_DATABASE=FCH Azalia Controller
+
+pci:v00001022d0000780E*
+ ID_PRODUCT_FROM_DATABASE=FCH LPC Bridge
+
+pci:v00001022d0000780F*
+ ID_PRODUCT_FROM_DATABASE=FCH PCI Bridge
+
+pci:v00001022d00007812*
+ ID_PRODUCT_FROM_DATABASE=FCH USB XHCI Controller
+
+pci:v00001022d00007813*
+ ID_PRODUCT_FROM_DATABASE=FCH SD Flash Controller
+
+pci:v00001022d00007814*
+ ID_PRODUCT_FROM_DATABASE=FCH USB XHCI Controller
+
+pci:v00001022d00009600*
+ ID_PRODUCT_FROM_DATABASE=RS780 Host Bridge
+
+pci:v00001022d00009600sv00001043sd000082F1*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v00001022d00009601*
+ ID_PRODUCT_FROM_DATABASE=RS880 Host Bridge
+
+pci:v00001022d00009601sv00001043sd0000843E*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001022d00009602*
+ ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (int gfx)
+
+pci:v00001022d00009603*
+ ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (ext gfx port 0)
+
+pci:v00001022d00009604*
+ ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 0)
+
+pci:v00001022d00009605*
+ ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 1)
+
+pci:v00001022d00009606*
+ ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (PCIE port 2)
+
+pci:v00001022d00009607*
+ ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (PCIE port 3)
+
+pci:v00001022d00009608*
+ ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 4)
+
+pci:v00001022d00009609*
+ ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 5)
+
+pci:v00001022d0000960A*
+ ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (NB-SB link)
+
+pci:v00001022d0000960B*
+ ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (ext gfx port 1)
+
+pci:v00001023*
+ ID_VENDOR_FROM_DATABASE=Trident Microsystems
+
+pci:v00001023d00000194*
+ ID_PRODUCT_FROM_DATABASE=82C194
+
+pci:v00001023d00002000*
+ ID_PRODUCT_FROM_DATABASE=4DWave DX
+
+pci:v00001023d00002001*
+ ID_PRODUCT_FROM_DATABASE=4DWave NX
+
+pci:v00001023d00002001sv0000122Dsd00001400*
+ ID_PRODUCT_FROM_DATABASE=Trident PCI288-Q3DII (NX)
+
+pci:v00001023d00002100*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade XP4m32
+
+pci:v00001023d00002200*
+ ID_PRODUCT_FROM_DATABASE=XGI Volari XP5
+
+pci:v00001023d00008400*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade/i7
+
+pci:v00001023d00008400sv00001023sd00008400*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade i7 AGP
+
+pci:v00001023d00008420*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade/i7d
+
+pci:v00001023d00008420sv00000E11sd0000B15A*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade i7 AGP
+
+pci:v00001023d00008500*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade/i1
+
+pci:v00001023d00008520*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade i1
+
+pci:v00001023d00008520sv00000E11sd0000B16E*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade i1 AGP
+
+pci:v00001023d00008520sv00001023sd00008520*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade i1 AGP
+
+pci:v00001023d00008620*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade/i1
+
+pci:v00001023d00008620sv00001014sd00000502*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R30/T30
+
+pci:v00001023d00008620sv00001014sd00001025*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 352TE
+
+pci:v00001023d00008820*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade XPAi1
+
+pci:v00001023d00009320*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9320
+
+pci:v00001023d00009350*
+ ID_PRODUCT_FROM_DATABASE=GUI Accelerator
+
+pci:v00001023d00009360*
+ ID_PRODUCT_FROM_DATABASE=Flat panel GUI Accelerator
+
+pci:v00001023d00009382*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9382 [Reference design]
+
+pci:v00001023d00009383*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9383 [Reference design]
+
+pci:v00001023d00009385*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9385 [Reference design]
+
+pci:v00001023d00009386*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9386
+
+pci:v00001023d00009388*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9388
+
+pci:v00001023d00009397*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9397
+
+pci:v00001023d0000939A*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9397DVD
+
+pci:v00001023d00009420*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9420
+
+pci:v00001023d00009430*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9430
+
+pci:v00001023d00009440*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9440
+
+pci:v00001023d00009460*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9460
+
+pci:v00001023d00009470*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9470
+
+pci:v00001023d00009520*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9520
+
+pci:v00001023d00009525*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9525
+
+pci:v00001023d00009540*
+ ID_PRODUCT_FROM_DATABASE=Cyber 9540
+
+pci:v00001023d00009660*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9660/938x/968x
+
+pci:v00001023d00009680*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9680
+
+pci:v00001023d00009682*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9682
+
+pci:v00001023d00009683*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9683
+
+pci:v00001023d00009685*
+ ID_PRODUCT_FROM_DATABASE=ProVIDIA 9685
+
+pci:v00001023d00009750*
+ ID_PRODUCT_FROM_DATABASE=3DImage 9750
+
+pci:v00001023d00009750sv00001014sd00009750*
+ ID_PRODUCT_FROM_DATABASE=3DImage 9750
+
+pci:v00001023d00009750sv00001023sd00009750*
+ ID_PRODUCT_FROM_DATABASE=3DImage 9750
+
+pci:v00001023d00009753*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9753
+
+pci:v00001023d00009754*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9754
+
+pci:v00001023d00009759*
+ ID_PRODUCT_FROM_DATABASE=TGUI 975
+
+pci:v00001023d00009783*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9783
+
+pci:v00001023d00009785*
+ ID_PRODUCT_FROM_DATABASE=TGUI 9785
+
+pci:v00001023d00009850*
+ ID_PRODUCT_FROM_DATABASE=3DImage 9850
+
+pci:v00001023d00009880*
+ ID_PRODUCT_FROM_DATABASE=Blade 3D PCI/AGP
+
+pci:v00001023d00009880sv00001023sd00009880*
+ ID_PRODUCT_FROM_DATABASE=Blade 3D
+
+pci:v00001023d00009910*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade/XP
+
+pci:v00001023d00009930*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade/XPm
+
+pci:v00001023d00009960*
+ ID_PRODUCT_FROM_DATABASE=CyberBlade XP2
+
+pci:v00001024*
+ ID_VENDOR_FROM_DATABASE=Zenith Data Systems
+
+pci:v00001025*
+ ID_VENDOR_FROM_DATABASE=Acer Incorporated [ALI]
+
+pci:v00001025d00001435*
+ ID_PRODUCT_FROM_DATABASE=M1435
+
+pci:v00001025d00001445*
+ ID_PRODUCT_FROM_DATABASE=M1445
+
+pci:v00001025d00001449*
+ ID_PRODUCT_FROM_DATABASE=M1449
+
+pci:v00001025d00001451*
+ ID_PRODUCT_FROM_DATABASE=M1451
+
+pci:v00001025d00001461*
+ ID_PRODUCT_FROM_DATABASE=M1461
+
+pci:v00001025d00001489*
+ ID_PRODUCT_FROM_DATABASE=M1489
+
+pci:v00001025d00001511*
+ ID_PRODUCT_FROM_DATABASE=M1511
+
+pci:v00001025d00001512*
+ ID_PRODUCT_FROM_DATABASE=ALI M1512 Aladdin
+
+pci:v00001025d00001513*
+ ID_PRODUCT_FROM_DATABASE=M1513
+
+pci:v00001025d00001521*
+ ID_PRODUCT_FROM_DATABASE=ALI M1521 Aladdin III CPU Bridge
+
+pci:v00001025d00001521sv000010B9sd00001521*
+ ID_PRODUCT_FROM_DATABASE=ALI M1521 Aladdin III CPU Bridge
+
+pci:v00001025d00001523*
+ ID_PRODUCT_FROM_DATABASE=ALI M1523 ISA Bridge
+
+pci:v00001025d00001523sv000010B9sd00001523*
+ ID_PRODUCT_FROM_DATABASE=ALI M1523 ISA Bridge
+
+pci:v00001025d00001531*
+ ID_PRODUCT_FROM_DATABASE=M1531 Northbridge [Aladdin IV/IV+]
+
+pci:v00001025d00001533*
+ ID_PRODUCT_FROM_DATABASE=M1533 PCI-to-ISA Bridge
+
+pci:v00001025d00001533sv000010B9sd00001533*
+ ID_PRODUCT_FROM_DATABASE=ALI M1533 Aladdin IV/V ISA South Bridge
+
+pci:v00001025d00001535*
+ ID_PRODUCT_FROM_DATABASE=M1535 PCI Bridge + Super I/O + FIR
+
+pci:v00001025d00001541*
+ ID_PRODUCT_FROM_DATABASE=M1541 Northbridge [Aladdin V]
+
+pci:v00001025d00001541sv000010B9sd00001541*
+ ID_PRODUCT_FROM_DATABASE=ALI M1541 Aladdin V/V+ AGP+PCI North Bridge
+
+pci:v00001025d00001542*
+ ID_PRODUCT_FROM_DATABASE=M1542 Northbridge [Aladdin V]
+
+pci:v00001025d00001543*
+ ID_PRODUCT_FROM_DATABASE=M1543 PCI-to-ISA Bridge + Super I/O + FIR
+
+pci:v00001025d00001561*
+ ID_PRODUCT_FROM_DATABASE=M1561 Northbridge [Aladdin 7]
+
+pci:v00001025d00001621*
+ ID_PRODUCT_FROM_DATABASE=M1621 Northbridge [Aladdin-Pro II]
+
+pci:v00001025d00001631*
+ ID_PRODUCT_FROM_DATABASE=M1631 Northbridge+3D Graphics [Aladdin TNT2]
+
+pci:v00001025d00001641*
+ ID_PRODUCT_FROM_DATABASE=M1641 Northbridge [Aladdin-Pro IV]
+
+pci:v00001025d00001647*
+ ID_PRODUCT_FROM_DATABASE=M1647 [MaGiK1] PCI North Bridge
+
+pci:v00001025d00001671*
+ ID_PRODUCT_FROM_DATABASE=M1671 Northbridge [ALADDiN-P4]
+
+pci:v00001025d00001672*
+ ID_PRODUCT_FROM_DATABASE=Northbridge [CyberALADDiN-P4]
+
+pci:v00001025d00003141*
+ ID_PRODUCT_FROM_DATABASE=M3141
+
+pci:v00001025d00003143*
+ ID_PRODUCT_FROM_DATABASE=M3143
+
+pci:v00001025d00003145*
+ ID_PRODUCT_FROM_DATABASE=M3145
+
+pci:v00001025d00003147*
+ ID_PRODUCT_FROM_DATABASE=M3147
+
+pci:v00001025d00003149*
+ ID_PRODUCT_FROM_DATABASE=M3149
+
+pci:v00001025d00003151*
+ ID_PRODUCT_FROM_DATABASE=M3151
+
+pci:v00001025d00003307*
+ ID_PRODUCT_FROM_DATABASE=M3307 MPEG-I Video Controller
+
+pci:v00001025d00003309*
+ ID_PRODUCT_FROM_DATABASE=M3309 MPEG-II Video w/ Software Audio Decoder
+
+pci:v00001025d00003321*
+ ID_PRODUCT_FROM_DATABASE=M3321 MPEG-II Audio/Video Decoder
+
+pci:v00001025d00005212*
+ ID_PRODUCT_FROM_DATABASE=M4803
+
+pci:v00001025d00005215*
+ ID_PRODUCT_FROM_DATABASE=ALI PCI EIDE Controller
+
+pci:v00001025d00005217*
+ ID_PRODUCT_FROM_DATABASE=M5217H
+
+pci:v00001025d00005219*
+ ID_PRODUCT_FROM_DATABASE=M5219
+
+pci:v00001025d00005225*
+ ID_PRODUCT_FROM_DATABASE=M5225
+
+pci:v00001025d00005229*
+ ID_PRODUCT_FROM_DATABASE=M5229
+
+pci:v00001025d00005235*
+ ID_PRODUCT_FROM_DATABASE=M5235
+
+pci:v00001025d00005237*
+ ID_PRODUCT_FROM_DATABASE=M5237 PCI USB Host Controller
+
+pci:v00001025d00005240*
+ ID_PRODUCT_FROM_DATABASE=EIDE Controller
+
+pci:v00001025d00005241*
+ ID_PRODUCT_FROM_DATABASE=PCMCIA Bridge
+
+pci:v00001025d00005242*
+ ID_PRODUCT_FROM_DATABASE=General Purpose Controller
+
+pci:v00001025d00005243*
+ ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge Controller
+
+pci:v00001025d00005244*
+ ID_PRODUCT_FROM_DATABASE=Floppy Disk Controller
+
+pci:v00001025d00005247*
+ ID_PRODUCT_FROM_DATABASE=M1541 PCI to PCI Bridge
+
+pci:v00001025d00005251*
+ ID_PRODUCT_FROM_DATABASE=M5251 P1394 Controller
+
+pci:v00001025d00005427*
+ ID_PRODUCT_FROM_DATABASE=PCI to AGP Bridge
+
+pci:v00001025d00005451*
+ ID_PRODUCT_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device
+
+pci:v00001025d00005453*
+ ID_PRODUCT_FROM_DATABASE=M5453 PCI AC-Link Controller Modem Device
+
+pci:v00001025d00007101*
+ ID_PRODUCT_FROM_DATABASE=M7101 PCI PMU Power Management Controller
+
+pci:v00001025d00007101sv000010B9sd00007101*
+ ID_PRODUCT_FROM_DATABASE=M7101 PCI PMU Power Management Controller
+
+pci:v00001025d00009602*
+ ID_PRODUCT_FROM_DATABASE=AMD RS780/RS880 PCI to PCI bridge (int gfx)
+
+pci:v00001028*
+ ID_VENDOR_FROM_DATABASE=Dell
+
+pci:v00001028d00000001*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/Si
+
+pci:v00001028d00000001sv00001028sd00000001*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2400
+
+pci:v00001028d00000002*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di
+
+pci:v00001028d00000002sv00001028sd00000002*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 4400
+
+pci:v00001028d00000002sv00001028sd000000D1*
+ ID_PRODUCT_FROM_DATABASE=PERC 3/DiV [Viper]
+
+pci:v00001028d00000002sv00001028sd000000D9*
+ ID_PRODUCT_FROM_DATABASE=PERC 3/DiL [Lexus]
+
+pci:v00001028d00000003*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Si
+
+pci:v00001028d00000003sv00001028sd00000003*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2450
+
+pci:v00001028d00000004*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di [Iguana]
+
+pci:v00001028d00000004sv00001028sd00000004*
+ ID_PRODUCT_FROM_DATABASE=PERC 3/DiF [Iguana]
+
+pci:v00001028d00000006*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di
+
+pci:v00001028d00000007*
+ ID_PRODUCT_FROM_DATABASE=Remote Access Card III
+
+pci:v00001028d00000008*
+ ID_PRODUCT_FROM_DATABASE=Remote Access Card III
+
+pci:v00001028d00000009*
+ ID_PRODUCT_FROM_DATABASE=Remote Access Card III: BMC/SMIC device not present
+
+pci:v00001028d0000000A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di
+
+pci:v00001028d0000000Asv00001028sd00000106*
+ ID_PRODUCT_FROM_DATABASE=PERC 3/DiJ [Jaguar]
+
+pci:v00001028d0000000Asv00001028sd0000011B*
+ ID_PRODUCT_FROM_DATABASE=PERC 3/DiD [Dagger]
+
+pci:v00001028d0000000Asv00001028sd00000121*
+ ID_PRODUCT_FROM_DATABASE=PERC 3/DiB [Boxster]
+
+pci:v00001028d0000000C*
+ ID_PRODUCT_FROM_DATABASE=Embedded Remote Access or ERA/O
+
+pci:v00001028d0000000D*
+ ID_PRODUCT_FROM_DATABASE=Embedded Remote Access: BMC/SMIC device
+
+pci:v00001028d0000000E*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller 4/Di
+
+pci:v00001028d0000000F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller 4/Di
+
+pci:v00001028d0000000Fsv00001028sd0000014A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1750
+
+pci:v00001028d00000010*
+ ID_PRODUCT_FROM_DATABASE=Remote Access Card 4
+
+pci:v00001028d00000011*
+ ID_PRODUCT_FROM_DATABASE=Remote Access Card 4 Daughter Card
+
+pci:v00001028d00000012*
+ ID_PRODUCT_FROM_DATABASE=Remote Access Card 4 Daughter Card Virtual UART
+
+pci:v00001028d00000013*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller 4
+
+pci:v00001028d00000013sv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Si
+
+pci:v00001028d00000013sv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di
+
+pci:v00001028d00000013sv00001028sd0000016E*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di
+
+pci:v00001028d00000013sv00001028sd0000016F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di
+
+pci:v00001028d00000013sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di
+
+pci:v00001028d00000014*
+ ID_PRODUCT_FROM_DATABASE=Remote Access Card 4 Daughter Card SMIC interface
+
+pci:v00001028d00000015*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller 5
+
+pci:v00001028d00000015sv00001028sd00001F01*
+ ID_PRODUCT_FROM_DATABASE=PERC 5/E Adapter RAID Controller
+
+pci:v00001028d00000015sv00001028sd00001F02*
+ ID_PRODUCT_FROM_DATABASE=PERC 5/i Adapter RAID Controller
+
+pci:v00001028d00000015sv00001028sd00001F03*
+ ID_PRODUCT_FROM_DATABASE=PERC 5/i Integrated RAID Controller
+
+pci:v00001028d00000016*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller S300
+
+pci:v00001028d00000016sv00001028sd00001F24*
+ ID_PRODUCT_FROM_DATABASE=PERC S300 Controller
+
+pci:v00001029*
+ ID_VENDOR_FROM_DATABASE=Siemens Nixdorf IS
+
+pci:v0000102A*
+ ID_VENDOR_FROM_DATABASE=LSI Logic
+
+pci:v0000102Ad00000000*
+ ID_PRODUCT_FROM_DATABASE=HYDRA
+
+pci:v0000102Ad00000010*
+ ID_PRODUCT_FROM_DATABASE=ASPEN
+
+pci:v0000102Ad0000001F*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U2/U2W /7890/7891 SCSI Controllers
+
+pci:v0000102Ad0000001Fsv00009005sd0000000F*
+ ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller
+
+pci:v0000102Ad0000001Fsv00009005sd00000106*
+ ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller
+
+pci:v0000102Ad0000001Fsv00009005sd0000A180*
+ ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller
+
+pci:v0000102Ad000000C5*
+ ID_PRODUCT_FROM_DATABASE=AIC-7899 U160/m SCSI Controller
+
+pci:v0000102Ad000000C5sv00001028sd000000C5*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2550/2650/4600
+
+pci:v0000102Ad000000CF*
+ ID_PRODUCT_FROM_DATABASE=AIC-7899P U160/m
+
+pci:v0000102Ad000000CFsv00001028sd00000106*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 4600
+
+pci:v0000102Ad000000CFsv00001028sd00000121*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2650
+
+pci:v0000102B*
+ ID_VENDOR_FROM_DATABASE=Matrox Electronics Systems Ltd.
+
+pci:v0000102Bd00000010*
+ ID_PRODUCT_FROM_DATABASE=MGA-I [Impression?]
+
+pci:v0000102Bd00000100*
+ ID_PRODUCT_FROM_DATABASE=MGA 1064SG [Mystique]
+
+pci:v0000102Bd00000518*
+ ID_PRODUCT_FROM_DATABASE=MGA-II [Athena]
+
+pci:v0000102Bd00000519*
+ ID_PRODUCT_FROM_DATABASE=MGA 2064W [Millennium]
+
+pci:v0000102Bd0000051A*
+ ID_PRODUCT_FROM_DATABASE=MGA 1064SG [Mystique]
+
+pci:v0000102Bd0000051Asv0000102Bsd00000100*
+ ID_PRODUCT_FROM_DATABASE=MGA-1064SG Mystique
+
+pci:v0000102Bd0000051Asv0000102Bsd00001100*
+ ID_PRODUCT_FROM_DATABASE=MGA-1084SG Mystique
+
+pci:v0000102Bd0000051Asv0000102Bsd00001200*
+ ID_PRODUCT_FROM_DATABASE=MGA-1084SG Mystique
+
+pci:v0000102Bd0000051Asv00001100sd0000102B*
+ ID_PRODUCT_FROM_DATABASE=MGA-1084SG Mystique
+
+pci:v0000102Bd0000051Asv0000110Asd00000018*
+ ID_PRODUCT_FROM_DATABASE=Scenic Pro C5 (D1025)
+
+pci:v0000102Bd0000051B*
+ ID_PRODUCT_FROM_DATABASE=MGA 2164W [Millennium II]
+
+pci:v0000102Bd0000051Bsv0000102Bsd0000051B*
+ ID_PRODUCT_FROM_DATABASE=MGA-2164W Millennium II
+
+pci:v0000102Bd0000051Bsv0000102Bsd00001100*
+ ID_PRODUCT_FROM_DATABASE=MGA-2164W Millennium II
+
+pci:v0000102Bd0000051Bsv0000102Bsd00001200*
+ ID_PRODUCT_FROM_DATABASE=MGA-2164W Millennium II
+
+pci:v0000102Bd0000051Bsv0000102Bsd00002100*
+ ID_PRODUCT_FROM_DATABASE=MGA-2164W Millennium II
+
+pci:v0000102Bd0000051E*
+ ID_PRODUCT_FROM_DATABASE=MGA 1064SG [Mystique] AGP
+
+pci:v0000102Bd0000051F*
+ ID_PRODUCT_FROM_DATABASE=MGA 2164W [Millennium II] AGP
+
+pci:v0000102Bd00000520*
+ ID_PRODUCT_FROM_DATABASE=MGA G200
+
+pci:v0000102Bd00000520sv0000102Bsd0000DBC2*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000520sv0000102Bsd0000DBC8*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000520sv0000102Bsd0000DBE2*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000520sv0000102Bsd0000DBE8*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000520sv0000102Bsd0000FF03*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 SD
+
+pci:v0000102Bd00000520sv0000102Bsd0000FF04*
+ ID_PRODUCT_FROM_DATABASE=Marvel G200
+
+pci:v0000102Bd00000521*
+ ID_PRODUCT_FROM_DATABASE=MGA G200 AGP
+
+pci:v0000102Bd00000521sv00001014sd0000FF03*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd000048E9*
+ ID_PRODUCT_FROM_DATABASE=Mystique G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd000048F8*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 SD AGP
+
+pci:v0000102Bd00000521sv0000102Bsd00004A60*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 LE AGP
+
+pci:v0000102Bd00000521sv0000102Bsd00004A64*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000C93C*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000C9B0*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000C9BC*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000CA60*
+ ID_PRODUCT_FROM_DATABASE=Millennium G250 LE AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000CA6C*
+ ID_PRODUCT_FROM_DATABASE=Millennium G250 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBBC*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBC2*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 MMS (Dual G200)
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBC3*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBC8*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 MMS (Dual G200)
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBD2*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBD3*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBD4*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBD5*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBD8*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBD9*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBE2*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 MMS (Quad G200)
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBE3*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBE8*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 MMS (Quad G200)
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBF2*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBF3*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBF4*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBF5*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBF8*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000DBF9*
+ ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor
+
+pci:v0000102Bd00000521sv0000102Bsd0000F806*
+ ID_PRODUCT_FROM_DATABASE=Mystique G200 Video AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=MGA-G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000FF02*
+ ID_PRODUCT_FROM_DATABASE=Mystique G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000FF03*
+ ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP
+
+pci:v0000102Bd00000521sv0000102Bsd0000FF04*
+ ID_PRODUCT_FROM_DATABASE=Marvel G200 AGP
+
+pci:v0000102Bd00000521sv0000110Asd00000032*
+ ID_PRODUCT_FROM_DATABASE=MGA-G200 AGP
+
+pci:v0000102Bd00000522*
+ ID_PRODUCT_FROM_DATABASE=MGA G200e [Pilot] ServerEngines (SEP1)
+
+pci:v0000102Bd00000522sv0000103Csd000031FA*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v0000102Bd00000525*
+ ID_PRODUCT_FROM_DATABASE=MGA G400/G450
+
+pci:v0000102Bd00000525sv00000E11sd0000B16F*
+ ID_PRODUCT_FROM_DATABASE=MGA-G400 AGP
+
+pci:v0000102Bd00000525sv0000102Bsd00000328*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 16Mb SDRAM
+
+pci:v0000102Bd00000525sv0000102Bsd00000338*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 16Mb SDRAM
+
+pci:v0000102Bd00000525sv0000102Bsd00000378*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 32Mb SDRAM
+
+pci:v0000102Bd00000525sv0000102Bsd00000541*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head
+
+pci:v0000102Bd00000525sv0000102Bsd00000542*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head LX
+
+pci:v0000102Bd00000525sv0000102Bsd00000543*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Single Head LX
+
+pci:v0000102Bd00000525sv0000102Bsd00000641*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 32Mb SDRAM Dual Head
+
+pci:v0000102Bd00000525sv0000102Bsd00000642*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 32Mb SDRAM Dual Head LX
+
+pci:v0000102Bd00000525sv0000102Bsd00000643*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 32Mb SDRAM Single Head LX
+
+pci:v0000102Bd00000525sv0000102Bsd000007C0*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head LE
+
+pci:v0000102Bd00000525sv0000102Bsd000007C1*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 SDR Dual Head LE
+
+pci:v0000102Bd00000525sv0000102Bsd00000D41*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head PCI
+
+pci:v0000102Bd00000525sv0000102Bsd00000D42*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head LX PCI
+
+pci:v0000102Bd00000525sv0000102Bsd00000D43*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 32Mb Dual Head PCI
+
+pci:v0000102Bd00000525sv0000102Bsd00000E00*
+ ID_PRODUCT_FROM_DATABASE=Marvel G450 eTV
+
+pci:v0000102Bd00000525sv0000102Bsd00000E01*
+ ID_PRODUCT_FROM_DATABASE=Marvel G450 eTV
+
+pci:v0000102Bd00000525sv0000102Bsd00000E02*
+ ID_PRODUCT_FROM_DATABASE=Marvel G450 eTV
+
+pci:v0000102Bd00000525sv0000102Bsd00000E03*
+ ID_PRODUCT_FROM_DATABASE=Marvel G450 eTV
+
+pci:v0000102Bd00000525sv0000102Bsd00000F80*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Low Profile
+
+pci:v0000102Bd00000525sv0000102Bsd00000F81*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Low Profile
+
+pci:v0000102Bd00000525sv0000102Bsd00000F82*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Low Profile DVI
+
+pci:v0000102Bd00000525sv0000102Bsd00000F83*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 Low Profile DVI
+
+pci:v0000102Bd00000525sv0000102Bsd000019D8*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 16Mb SGRAM
+
+pci:v0000102Bd00000525sv0000102Bsd000019F8*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 32Mb SGRAM
+
+pci:v0000102Bd00000525sv0000102Bsd00002159*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 Dual Head 16Mb
+
+pci:v0000102Bd00000525sv0000102Bsd00002179*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 MAX/Dual Head 32Mb
+
+pci:v0000102Bd00000525sv0000102Bsd0000217D*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 Dual Head Max
+
+pci:v0000102Bd00000525sv0000102Bsd000023C0*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450
+
+pci:v0000102Bd00000525sv0000102Bsd000023C1*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450
+
+pci:v0000102Bd00000525sv0000102Bsd000023C2*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 DVI
+
+pci:v0000102Bd00000525sv0000102Bsd000023C3*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 DVI
+
+pci:v0000102Bd00000525sv0000102Bsd00002F58*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400
+
+pci:v0000102Bd00000525sv0000102Bsd00002F78*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400
+
+pci:v0000102Bd00000525sv0000102Bsd00003693*
+ ID_PRODUCT_FROM_DATABASE=Marvel G400 AGP
+
+pci:v0000102Bd00000525sv0000102Bsd00005DD0*
+ ID_PRODUCT_FROM_DATABASE=4Sight II
+
+pci:v0000102Bd00000525sv0000102Bsd00005F50*
+ ID_PRODUCT_FROM_DATABASE=4Sight II
+
+pci:v0000102Bd00000525sv0000102Bsd00005F51*
+ ID_PRODUCT_FROM_DATABASE=4Sight II
+
+pci:v0000102Bd00000525sv0000102Bsd00005F52*
+ ID_PRODUCT_FROM_DATABASE=4Sight II
+
+pci:v0000102Bd00000525sv0000102Bsd00009010*
+ ID_PRODUCT_FROM_DATABASE=Millennium G400 Dual Head
+
+pci:v0000102Bd00000525sv00001458sd00000400*
+ ID_PRODUCT_FROM_DATABASE=GA-G400
+
+pci:v0000102Bd00000525sv00001705sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 32MB SGRAM
+
+pci:v0000102Bd00000525sv00001705sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 16MB SGRAM
+
+pci:v0000102Bd00000525sv00001705sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 32MB
+
+pci:v0000102Bd00000525sv00001705sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Millennium G450 16MB
+
+pci:v0000102Bd00000527*
+ ID_PRODUCT_FROM_DATABASE=Parhelia
+
+pci:v0000102Bd00000527sv0000102Bsd00000840*
+ ID_PRODUCT_FROM_DATABASE=Parhelia 128Mb
+
+pci:v0000102Bd00000527sv0000102Bsd00000850*
+ ID_PRODUCT_FROM_DATABASE=Parhelia 256MB
+
+pci:v0000102Bd00000527sv0000102Bsd00000870*
+ ID_PRODUCT_FROM_DATABASE=MED2mp-DVI
+
+pci:v0000102Bd00000527sv0000102Bsd00000880*
+ ID_PRODUCT_FROM_DATABASE=P-256 Edge Overlap Controller
+
+pci:v0000102Bd00000528*
+ ID_PRODUCT_FROM_DATABASE=Parhelia
+
+pci:v0000102Bd00000528sv0000102Bsd00001020*
+ ID_PRODUCT_FROM_DATABASE=Parhelia 128MB
+
+pci:v0000102Bd00000528sv0000102Bsd00001030*
+ ID_PRODUCT_FROM_DATABASE=Parhelia 256 MB Dual DVI
+
+pci:v0000102Bd00000528sv0000102Bsd00001040*
+ ID_PRODUCT_FROM_DATABASE=MED2mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd00001050*
+ ID_PRODUCT_FROM_DATABASE=Sono S20
+
+pci:v0000102Bd00000528sv0000102Bsd00001060*
+ ID_PRODUCT_FROM_DATABASE=PJ-30L
+
+pci:v0000102Bd00000528sv0000102Bsd00001070*
+ ID_PRODUCT_FROM_DATABASE=PJ-40L
+
+pci:v0000102Bd00000528sv0000102Bsd00001421*
+ ID_PRODUCT_FROM_DATABASE=MED5mp
+
+pci:v0000102Bd00000528sv0000102Bsd00001431*
+ ID_PRODUCT_FROM_DATABASE=MED3mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd00001451*
+ ID_PRODUCT_FROM_DATABASE=MED5mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd00001491*
+ ID_PRODUCT_FROM_DATABASE=MED2mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd000014B1*
+ ID_PRODUCT_FROM_DATABASE=MED3mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd000014C1*
+ ID_PRODUCT_FROM_DATABASE=MED5mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd000014E1*
+ ID_PRODUCT_FROM_DATABASE=Parhelia PCI 256MB
+
+pci:v0000102Bd00000528sv0000102Bsd000014F1*
+ ID_PRODUCT_FROM_DATABASE=Parhelia Precision SGT
+
+pci:v0000102Bd00000528sv0000102Bsd00001501*
+ ID_PRODUCT_FROM_DATABASE=ATC-4MP
+
+pci:v0000102Bd00000528sv0000102Bsd00001511*
+ ID_PRODUCT_FROM_DATABASE=ATC-4MP
+
+pci:v0000102Bd00000528sv0000102Bsd00001521*
+ ID_PRODUCT_FROM_DATABASE=TheatreVUE T30
+
+pci:v0000102Bd00000528sv0000102Bsd00001531*
+ ID_PRODUCT_FROM_DATABASE=TheatreVUE T20
+
+pci:v0000102Bd00000528sv0000102Bsd00001541*
+ ID_PRODUCT_FROM_DATABASE=MED2mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd00001551*
+ ID_PRODUCT_FROM_DATABASE=MED3mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd00001561*
+ ID_PRODUCT_FROM_DATABASE=MED5mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd00001571*
+ ID_PRODUCT_FROM_DATABASE=Parhelia DL256 PCI
+
+pci:v0000102Bd00000528sv0000102Bsd00001591*
+ ID_PRODUCT_FROM_DATABASE=Parhelia Precision SDT
+
+pci:v0000102Bd00000528sv0000102Bsd000015A1*
+ ID_PRODUCT_FROM_DATABASE=MED4mp-DVI
+
+pci:v0000102Bd00000528sv0000102Bsd00002011*
+ ID_PRODUCT_FROM_DATABASE=Parhelia HR256
+
+pci:v0000102Bd00000528sv0000102Bsd00002021*
+ ID_PRODUCT_FROM_DATABASE=QID Pro
+
+pci:v0000102Bd00000528sv0000102Bsd00002061*
+ ID_PRODUCT_FROM_DATABASE=PJ-40LP
+
+pci:v0000102Bd00000528sv0000102Bsd00002081*
+ ID_PRODUCT_FROM_DATABASE=EWS Quad
+
+pci:v0000102Bd00000528sv0000102Bsd00002411*
+ ID_PRODUCT_FROM_DATABASE=PPX-OUT8
+
+pci:v0000102Bd00000528sv0000102Bsd00002421*
+ ID_PRODUCT_FROM_DATABASE=VPX-OUT8
+
+pci:v0000102Bd00000528sv0000102Bsd00002441*
+ ID_PRODUCT_FROM_DATABASE=PPX-OUT4
+
+pci:v0000102Bd00000528sv0000102Bsd00002451*
+ ID_PRODUCT_FROM_DATABASE=VPX-OUT4
+
+pci:v0000102Bd00000528sv0000102Bsd00002491*
+ ID_PRODUCT_FROM_DATABASE=LPX-OUT4
+
+pci:v0000102Bd00000530*
+ ID_PRODUCT_FROM_DATABASE=MGA G200EV
+
+pci:v0000102Bd00000532*
+ ID_PRODUCT_FROM_DATABASE=MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv00001028sd000002A4*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T310 MGA G200eW WPCM450
+
+pci:v0000102Bd00000532sv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v0000102Bd00000533*
+ ID_PRODUCT_FROM_DATABASE=MGA G200EH
+
+pci:v0000102Bd00000533sv0000103Csd00003381*
+ ID_PRODUCT_FROM_DATABASE=iLO4
+
+pci:v0000102Bd00000534*
+ ID_PRODUCT_FROM_DATABASE=G200eR2
+
+pci:v0000102Bd00000540*
+ ID_PRODUCT_FROM_DATABASE=M91XX
+
+pci:v0000102Bd00000540sv0000102Bsd00002080*
+ ID_PRODUCT_FROM_DATABASE=M9140 LP PCIe x16
+
+pci:v0000102Bd00000540sv0000102Bsd000020C0*
+ ID_PRODUCT_FROM_DATABASE=Xenia
+
+pci:v0000102Bd00000540sv0000102Bsd000020C1*
+ ID_PRODUCT_FROM_DATABASE=Xenia Pro
+
+pci:v0000102Bd00000540sv0000102Bsd00002100*
+ ID_PRODUCT_FROM_DATABASE=M9120 PCIe x16
+
+pci:v0000102Bd00000540sv0000102Bsd00002140*
+ ID_PRODUCT_FROM_DATABASE=M9125 PCIe x16
+
+pci:v0000102Bd00000540sv0000102Bsd00002180*
+ ID_PRODUCT_FROM_DATABASE=M9120 Plus LP PCIe x16
+
+pci:v0000102Bd00000540sv0000102Bsd000021C0*
+ ID_PRODUCT_FROM_DATABASE=M9120 Plus LP PCIe x1
+
+pci:v0000102Bd00000540sv0000102Bsd00002200*
+ ID_PRODUCT_FROM_DATABASE=VDA1164 Output Board
+
+pci:v0000102Bd00000540sv0000102Bsd00002240*
+ ID_PRODUCT_FROM_DATABASE=M9148 LP PCIe x16
+
+pci:v0000102Bd00000540sv0000102Bsd00002241*
+ ID_PRODUCT_FROM_DATABASE=M9138 LP PCIe x16
+
+pci:v0000102Bd00000540sv0000102Bsd00002280*
+ ID_PRODUCT_FROM_DATABASE=M9188 ATX PCIe x16
+
+pci:v0000102Bd00000540sv0000102Bsd000022C0*
+ ID_PRODUCT_FROM_DATABASE=M9128 LP PCIe x16
+
+pci:v0000102Bd00000D10*
+ ID_PRODUCT_FROM_DATABASE=MGA Ultima/Impression
+
+pci:v0000102Bd00001000*
+ ID_PRODUCT_FROM_DATABASE=MGA G100 [Productiva]
+
+pci:v0000102Bd00001000sv0000102Bsd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=Productiva G100
+
+pci:v0000102Bd00001000sv0000102Bsd0000FF05*
+ ID_PRODUCT_FROM_DATABASE=Productiva G100 Multi-Monitor
+
+pci:v0000102Bd00001001*
+ ID_PRODUCT_FROM_DATABASE=MGA G100 [Productiva] AGP
+
+pci:v0000102Bd00001001sv0000102Bsd00001001*
+ ID_PRODUCT_FROM_DATABASE=MGA-G100 AGP
+
+pci:v0000102Bd00001001sv0000102Bsd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=MGA-G100 AGP
+
+pci:v0000102Bd00001001sv0000102Bsd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=MGA-G100 Productiva AGP
+
+pci:v0000102Bd00001001sv0000102Bsd0000FF03*
+ ID_PRODUCT_FROM_DATABASE=Millennium G100 AGP
+
+pci:v0000102Bd00001001sv0000102Bsd0000FF04*
+ ID_PRODUCT_FROM_DATABASE=MGA-G100 AGP
+
+pci:v0000102Bd00001001sv0000102Bsd0000FF05*
+ ID_PRODUCT_FROM_DATABASE=MGA-G100 Productiva AGP Multi-Monitor
+
+pci:v0000102Bd00001001sv0000110Asd0000001E*
+ ID_PRODUCT_FROM_DATABASE=MGA-G100 AGP
+
+pci:v0000102Bd00002007*
+ ID_PRODUCT_FROM_DATABASE=MGA Mistral
+
+pci:v0000102Bd00002527*
+ ID_PRODUCT_FROM_DATABASE=Millennium G550
+
+pci:v0000102Bd00002527sv0000102Bsd00000F83*
+ ID_PRODUCT_FROM_DATABASE=Millennium G550
+
+pci:v0000102Bd00002527sv0000102Bsd00000F84*
+ ID_PRODUCT_FROM_DATABASE=Millennium G550 Dual Head DDR 32Mb
+
+pci:v0000102Bd00002527sv0000102Bsd00001E41*
+ ID_PRODUCT_FROM_DATABASE=Millennium G550
+
+pci:v0000102Bd00002527sv0000102Bsd00002300*
+ ID_PRODUCT_FROM_DATABASE=Millennium G550 LP PCIE
+
+pci:v0000102Bd00002537*
+ ID_PRODUCT_FROM_DATABASE=Millenium P650/P750
+
+pci:v0000102Bd00002537sv0000102Bsd00001820*
+ ID_PRODUCT_FROM_DATABASE=Millennium P750 64MB
+
+pci:v0000102Bd00002537sv0000102Bsd00001830*
+ ID_PRODUCT_FROM_DATABASE=Millennium P650 64MB
+
+pci:v0000102Bd00002537sv0000102Bsd00001850*
+ ID_PRODUCT_FROM_DATABASE=RAD2mp
+
+pci:v0000102Bd00002537sv0000102Bsd00001860*
+ ID_PRODUCT_FROM_DATABASE=RAD3mp
+
+pci:v0000102Bd00002537sv0000102Bsd00001880*
+ ID_PRODUCT_FROM_DATABASE=Sono S10
+
+pci:v0000102Bd00002537sv0000102Bsd00001C10*
+ ID_PRODUCT_FROM_DATABASE=QID 128MB
+
+pci:v0000102Bd00002537sv0000102Bsd00002811*
+ ID_PRODUCT_FROM_DATABASE=Millennium P650 Low-profile PCI 64MB
+
+pci:v0000102Bd00002537sv0000102Bsd00002821*
+ ID_PRODUCT_FROM_DATABASE=Millenium P650 Low-profile PCI
+
+pci:v0000102Bd00002537sv0000102Bsd00002841*
+ ID_PRODUCT_FROM_DATABASE=RAD PCI
+
+pci:v0000102Bd00002537sv0000102Bsd00002851*
+ ID_PRODUCT_FROM_DATABASE=Spectrum PCI
+
+pci:v0000102Bd00002537sv0000102Bsd00002871*
+ ID_PRODUCT_FROM_DATABASE=EpicA TC2
+
+pci:v0000102Bd00002537sv0000102Bsd00002C11*
+ ID_PRODUCT_FROM_DATABASE=QID Low-profile PCI
+
+pci:v0000102Bd00002537sv0000102Bsd00002C21*
+ ID_PRODUCT_FROM_DATABASE=QID LP PCI LW
+
+pci:v0000102Bd00002537sv0000102Bsd00002C31*
+ ID_PRODUCT_FROM_DATABASE=QID LP PCI
+
+pci:v0000102Bd00002537sv0000102Bsd00002C41*
+ ID_PRODUCT_FROM_DATABASE=EpicA TC4
+
+pci:v0000102Bd00002537sv0000102Bsd00003001*
+ ID_PRODUCT_FROM_DATABASE=Extio F1400
+
+pci:v0000102Bd00002537sv0000102Bsd00003011*
+ ID_PRODUCT_FROM_DATABASE=Extio F1220
+
+pci:v0000102Bd00002537sv0000102Bsd00003041*
+ ID_PRODUCT_FROM_DATABASE=RG-200DL
+
+pci:v0000102Bd00002537sv0000102Bsd00003051*
+ ID_PRODUCT_FROM_DATABASE=RG-400SL
+
+pci:v0000102Bd00002537sv0000102Bsd00003061*
+ ID_PRODUCT_FROM_DATABASE=Extio F1420
+
+pci:v0000102Bd00002537sv0000102Bsd00003081*
+ ID_PRODUCT_FROM_DATABASE=Extio F1240
+
+pci:v0000102Bd00002538*
+ ID_PRODUCT_FROM_DATABASE=Millenium P650 PCIe
+
+pci:v0000102Bd00002538sv0000102Bsd00000847*
+ ID_PRODUCT_FROM_DATABASE=RAD PCIe
+
+pci:v0000102Bd00002538sv0000102Bsd000008C7*
+ ID_PRODUCT_FROM_DATABASE=Millennium P650 PCIe 128MB
+
+pci:v0000102Bd00002538sv0000102Bsd00000907*
+ ID_PRODUCT_FROM_DATABASE=Millennium P650 PCIe 64MB
+
+pci:v0000102Bd00002538sv0000102Bsd00000947*
+ ID_PRODUCT_FROM_DATABASE=Parhelia APVe
+
+pci:v0000102Bd00002538sv0000102Bsd00000987*
+ ID_PRODUCT_FROM_DATABASE=ATC PCIe 4MP
+
+pci:v0000102Bd00002538sv0000102Bsd00001047*
+ ID_PRODUCT_FROM_DATABASE=Millennium P650 LP PCIe 128MB
+
+pci:v0000102Bd00002538sv0000102Bsd00001087*
+ ID_PRODUCT_FROM_DATABASE=Millennium P650 LP PCIe 64MB
+
+pci:v0000102Bd00002538sv0000102Bsd00001801*
+ ID_PRODUCT_FROM_DATABASE=Millenium P650 PCIe x1
+
+pci:v0000102Bd00002538sv0000102Bsd00002538*
+ ID_PRODUCT_FROM_DATABASE=Parhelia APVe
+
+pci:v0000102Bd00002538sv0000102Bsd00003007*
+ ID_PRODUCT_FROM_DATABASE=QID Low-profile PCIe
+
+pci:v0000102Bd00002538sv0000102Bsd00003087*
+ ID_PRODUCT_FROM_DATABASE=Aurora VX3mp
+
+pci:v0000102Bd00002538sv0000102Bsd000030C7*
+ ID_PRODUCT_FROM_DATABASE=QID LP PCIe
+
+pci:v0000102Bd00002539*
+ ID_PRODUCT_FROM_DATABASE=Millennium P690
+
+pci:v0000102Bd00002539sv0000102Bsd00000040*
+ ID_PRODUCT_FROM_DATABASE=Millenium P690 PCIe x16
+
+pci:v0000102Bd00002539sv0000102Bsd00000042*
+ ID_PRODUCT_FROM_DATABASE=ONYX
+
+pci:v0000102Bd00002539sv0000102Bsd00000043*
+ ID_PRODUCT_FROM_DATABASE=SPECTRA
+
+pci:v0000102Bd00002539sv0000102Bsd00000080*
+ ID_PRODUCT_FROM_DATABASE=Millenium P690 Plus LP PCIe x16
+
+pci:v0000102Bd00002539sv0000102Bsd00000081*
+ ID_PRODUCT_FROM_DATABASE=Millenium P690 LP PCIe x16
+
+pci:v0000102Bd00002539sv0000102Bsd00000082*
+ ID_PRODUCT_FROM_DATABASE=RAD LPX PCIe x16
+
+pci:v0000102Bd00002539sv0000102Bsd000000C0*
+ ID_PRODUCT_FROM_DATABASE=Millenium P690 Plus LP PCI
+
+pci:v0000102Bd00002539sv0000102Bsd000000C2*
+ ID_PRODUCT_FROM_DATABASE=Millenium P690 LP PCI
+
+pci:v0000102Bd00002539sv0000102Bsd000000C3*
+ ID_PRODUCT_FROM_DATABASE=RAD LPX PCI
+
+pci:v0000102Bd00002539sv0000102Bsd00000101*
+ ID_PRODUCT_FROM_DATABASE=Millenium P690 PCI
+
+pci:v0000102Bd00002539sv0000102Bsd00000140*
+ ID_PRODUCT_FROM_DATABASE=Millenium P690 LP PCIe x1
+
+pci:v0000102Bd00002539sv0000102Bsd00000180*
+ ID_PRODUCT_FROM_DATABASE=Display Wall IP Decode 128 MB
+
+pci:v0000102Bd00004164*
+ ID_PRODUCT_FROM_DATABASE=Morphis QxT frame grabber
+
+pci:v0000102Bd000043B4*
+ ID_PRODUCT_FROM_DATABASE=Morphis Qxt encoding engine
+
+pci:v0000102Bd00004510*
+ ID_PRODUCT_FROM_DATABASE=Morphis COM port
+
+pci:v0000102Bd00004536*
+ ID_PRODUCT_FROM_DATABASE=VIA Framegrabber
+
+pci:v0000102Bd00004686*
+ ID_PRODUCT_FROM_DATABASE=Concord GX (customized Intel 82541)
+
+pci:v0000102Bd0000475B*
+ ID_PRODUCT_FROM_DATABASE=Solios eCL/XCL-B frame grabber
+
+pci:v0000102Bd0000475D*
+ ID_PRODUCT_FROM_DATABASE=Vio frame grabber family
+
+pci:v0000102Bd0000475Dsv0000102Bsd00004B90*
+ ID_PRODUCT_FROM_DATABASE=Vio Duo frame grabber (single channel)
+
+pci:v0000102Bd0000475Dsv0000102Bsd00004B91*
+ ID_PRODUCT_FROM_DATABASE=Vio Duo frame grabber
+
+pci:v0000102Bd0000475Dsv0000102Bsd00004B92*
+ ID_PRODUCT_FROM_DATABASE=Vio Analog frame grabber
+
+pci:v0000102Bd0000475Dsv0000102Bsd00004B93*
+ ID_PRODUCT_FROM_DATABASE=Vio SDI Frame Grabber
+
+pci:v0000102Bd0000475Dsv0000102Bsd00004B94*
+ ID_PRODUCT_FROM_DATABASE=Vio DVI-A frame grabber
+
+pci:v0000102Bd0000475F*
+ ID_PRODUCT_FROM_DATABASE=Solios (single-Full) CL frame grabber
+
+pci:v0000102Bd0000475Fsv0000102Bsd0000475F*
+ ID_PRODUCT_FROM_DATABASE=Solios eCL/XCL-F frame grabber
+
+pci:v0000102Bd0000475Fsv0000102Bsd00004D5F*
+ ID_PRODUCT_FROM_DATABASE=Solios eV-CL (single-Full) frame grabber
+
+pci:v0000102Bd0000475Fsv0000102Bsd00004E5F*
+ ID_PRODUCT_FROM_DATABASE=Solios eM-CL (single-Full) frame grabber
+
+pci:v0000102Bd000047A1*
+ ID_PRODUCT_FROM_DATABASE=Solios eA/XA frame grabber
+
+pci:v0000102Bd000047A1sv0000102Bsd00004BE0*
+ ID_PRODUCT_FROM_DATABASE=Solios eA/XA (single) frame grabber
+
+pci:v0000102Bd000047A1sv0000102Bsd00004BE1*
+ ID_PRODUCT_FROM_DATABASE=Solios eA/XA (dual) frame grabber
+
+pci:v0000102Bd000047A1sv0000102Bsd00004BE2*
+ ID_PRODUCT_FROM_DATABASE=Solios eA/XA (quad) frame grabber
+
+pci:v0000102Bd000047A2*
+ ID_PRODUCT_FROM_DATABASE=Solios COM port
+
+pci:v0000102Bd000047C1*
+ ID_PRODUCT_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber
+
+pci:v0000102Bd000047C1sv0000102Bsd00000000*
+ ID_PRODUCT_FROM_DATABASE=Solios frame grabber
+
+pci:v0000102Bd000047C1sv0000102Bsd00004B80*
+ ID_PRODUCT_FROM_DATABASE=Solios eCL/XCL (single-Medium) frame grabber
+
+pci:v0000102Bd000047C1sv0000102Bsd00004B81*
+ ID_PRODUCT_FROM_DATABASE=Solios eCL/XCL (dual-Base) frame grabber
+
+pci:v0000102Bd000047C1sv0000102Bsd00004D80*
+ ID_PRODUCT_FROM_DATABASE=Solios eV-CL (single-Medium) frame grabber
+
+pci:v0000102Bd000047C1sv0000102Bsd00004D81*
+ ID_PRODUCT_FROM_DATABASE=Solios eV-CL (dual-Base) frame grabber
+
+pci:v0000102Bd000047C1sv0000102Bsd00004E80*
+ ID_PRODUCT_FROM_DATABASE=Solios eM-CL (single-Medium) frame grabber
+
+pci:v0000102Bd000047C1sv0000102Bsd00004E81*
+ ID_PRODUCT_FROM_DATABASE=Solios eM-CL (dual-Base) frame grabber
+
+pci:v0000102Bd000047C2*
+ ID_PRODUCT_FROM_DATABASE=Solios COM port
+
+pci:v0000102Bd00004949*
+ ID_PRODUCT_FROM_DATABASE=Radient frame grabber family
+
+pci:v0000102Bd00004949sv0000102Bsd00000010*
+ ID_PRODUCT_FROM_DATABASE=Radient eCL (Single-full) frame grabber
+
+pci:v0000102Bd00004949sv0000102Bsd00000020*
+ ID_PRODUCT_FROM_DATABASE=Radient eCL (Dual-base) frame grabber
+
+pci:v0000102Bd00004949sv0000102Bsd00000030*
+ ID_PRODUCT_FROM_DATABASE=Radient eCL (Dual-full) frame grabber
+
+pci:v0000102Bd00004949sv0000102Bsd00000040*
+ ID_PRODUCT_FROM_DATABASE=Radient eCL (Quad-base) frame grabber
+
+pci:v0000102Bd00004949sv0000102Bsd00000050*
+ ID_PRODUCT_FROM_DATABASE=Radient eCL (Golden) frame grabber
+
+pci:v0000102Bd00004CDC*
+ ID_PRODUCT_FROM_DATABASE=Morphis JPEG2000 accelerator
+
+pci:v0000102Bd00004F54*
+ ID_PRODUCT_FROM_DATABASE=Morphis (e)Quad frame grabber
+
+pci:v0000102Bd00004FC5*
+ ID_PRODUCT_FROM_DATABASE=Morphis (e)Dual frame grabber
+
+pci:v0000102Bd00005E10*
+ ID_PRODUCT_FROM_DATABASE=Morphis aux I/O
+
+pci:v0000102Bd00006573*
+ ID_PRODUCT_FROM_DATABASE=Shark 10/100 Multiport SwitchNIC
+
+pci:v0000102C*
+ ID_VENDOR_FROM_DATABASE=Chips and Technologies
+
+pci:v0000102Cd000000B8*
+ ID_PRODUCT_FROM_DATABASE=F64310
+
+pci:v0000102Cd000000C0*
+ ID_PRODUCT_FROM_DATABASE=F69000 HiQVideo
+
+pci:v0000102Cd000000C0sv0000102Csd000000C0*
+ ID_PRODUCT_FROM_DATABASE=F69000 HiQVideo
+
+pci:v0000102Cd000000C0sv00004C53sd00001000*
+ ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+
+pci:v0000102Cd000000C0sv00004C53sd00001010*
+ ID_PRODUCT_FROM_DATABASE=CP5/CR6 mainboard
+
+pci:v0000102Cd000000C0sv00004C53sd00001020*
+ ID_PRODUCT_FROM_DATABASE=VR6 mainboard
+
+pci:v0000102Cd000000C0sv00004C53sd00001030*
+ ID_PRODUCT_FROM_DATABASE=PC5 mainboard
+
+pci:v0000102Cd000000C0sv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v0000102Cd000000C0sv00004C53sd00001051*
+ ID_PRODUCT_FROM_DATABASE=CE7 mainboard
+
+pci:v0000102Cd000000D0*
+ ID_PRODUCT_FROM_DATABASE=F65545
+
+pci:v0000102Cd000000D8*
+ ID_PRODUCT_FROM_DATABASE=F65545
+
+pci:v0000102Cd000000DC*
+ ID_PRODUCT_FROM_DATABASE=F65548
+
+pci:v0000102Cd000000E0*
+ ID_PRODUCT_FROM_DATABASE=F65550
+
+pci:v0000102Cd000000E4*
+ ID_PRODUCT_FROM_DATABASE=F65554
+
+pci:v0000102Cd000000E5*
+ ID_PRODUCT_FROM_DATABASE=F65555 HiQVPro
+
+pci:v0000102Cd000000E5sv00000E11sd0000B049*
+ ID_PRODUCT_FROM_DATABASE=Armada 1700 Laptop Display Controller
+
+pci:v0000102Cd000000E5sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Satellite Pro/Satellite
+
+pci:v0000102Cd000000F0*
+ ID_PRODUCT_FROM_DATABASE=F68554
+
+pci:v0000102Cd000000F4*
+ ID_PRODUCT_FROM_DATABASE=F68554 HiQVision
+
+pci:v0000102Cd000000F5*
+ ID_PRODUCT_FROM_DATABASE=F68555
+
+pci:v0000102Cd00000C30*
+ ID_PRODUCT_FROM_DATABASE=F69030
+
+pci:v0000102Cd00000C30sv00004C53sd00001000*
+ ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+
+pci:v0000102Cd00000C30sv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v0000102Cd00000C30sv00004C53sd00001051*
+ ID_PRODUCT_FROM_DATABASE=CE7 mainboard
+
+pci:v0000102Cd00000C30sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v0000102D*
+ ID_VENDOR_FROM_DATABASE=Wyse Technology Inc.
+
+pci:v0000102Dd000050DC*
+ ID_PRODUCT_FROM_DATABASE=3328 Audio
+
+pci:v0000102E*
+ ID_VENDOR_FROM_DATABASE=Olivetti Advanced Technology
+
+pci:v0000102F*
+ ID_VENDOR_FROM_DATABASE=Toshiba America
+
+pci:v0000102Fd00000009*
+ ID_PRODUCT_FROM_DATABASE=r4x00
+
+pci:v0000102Fd0000000A*
+ ID_PRODUCT_FROM_DATABASE=TX3927 MIPS RISC PCI Controller
+
+pci:v0000102Fd00000020*
+ ID_PRODUCT_FROM_DATABASE=ATM Meteor 155
+
+pci:v0000102Fd00000020sv0000102Fsd000000F8*
+ ID_PRODUCT_FROM_DATABASE=ATM Meteor 155
+
+pci:v0000102Fd00000030*
+ ID_PRODUCT_FROM_DATABASE=TC35815CF PCI 10/100 Mbit Ethernet Controller
+
+pci:v0000102Fd00000031*
+ ID_PRODUCT_FROM_DATABASE=TC35815CF PCI 10/100 Mbit Ethernet Controller with WOL
+
+pci:v0000102Fd00000032*
+ ID_PRODUCT_FROM_DATABASE=TC35815CF PCI 10/100 Mbit Ethernet Controller on TX4939
+
+pci:v0000102Fd00000105*
+ ID_PRODUCT_FROM_DATABASE=TC86C001 [goku-s] IDE
+
+pci:v0000102Fd00000106*
+ ID_PRODUCT_FROM_DATABASE=TC86C001 [goku-s] USB 1.1 Host
+
+pci:v0000102Fd00000107*
+ ID_PRODUCT_FROM_DATABASE=TC86C001 [goku-s] USB Device Controller
+
+pci:v0000102Fd00000108*
+ ID_PRODUCT_FROM_DATABASE=TC86C001 [goku-s] I2C/SIO/GPIO Controller
+
+pci:v0000102Fd00000180*
+ ID_PRODUCT_FROM_DATABASE=TX4927/38 MIPS RISC PCI Controller
+
+pci:v0000102Fd00000181*
+ ID_PRODUCT_FROM_DATABASE=TX4925 MIPS RISC PCI Controller
+
+pci:v0000102Fd00000182*
+ ID_PRODUCT_FROM_DATABASE=TX4937 MIPS RISC PCI Controller
+
+pci:v0000102Fd000001B4*
+ ID_PRODUCT_FROM_DATABASE=Celleb platform IDE interface
+
+pci:v0000102Fd000001B5*
+ ID_PRODUCT_FROM_DATABASE=SCC USB 2.0 EHCI controller
+
+pci:v0000102Fd000001B6*
+ ID_PRODUCT_FROM_DATABASE=SCC USB 1.1 OHCI controller
+
+pci:v00001030*
+ ID_VENDOR_FROM_DATABASE=TMC Research
+
+pci:v00001031*
+ ID_VENDOR_FROM_DATABASE=Miro Computer Products AG
+
+pci:v00001031d00005601*
+ ID_PRODUCT_FROM_DATABASE=DC20 ASIC
+
+pci:v00001031d00005607*
+ ID_PRODUCT_FROM_DATABASE=Video I/O & motion JPEG compressor
+
+pci:v00001031d00005631*
+ ID_PRODUCT_FROM_DATABASE=Media 3D
+
+pci:v00001031d00006057*
+ ID_PRODUCT_FROM_DATABASE=MiroVideo DC10/DC30+
+
+pci:v00001032*
+ ID_VENDOR_FROM_DATABASE=Compaq
+
+pci:v00001033*
+ ID_VENDOR_FROM_DATABASE=NEC Corporation
+
+pci:v00001033d00000000*
+ ID_PRODUCT_FROM_DATABASE=Vr4181A USB Host or Function Control Unit
+
+pci:v00001033d00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI to 486-like bus Bridge
+
+pci:v00001033d00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI to VL98 Bridge
+
+pci:v00001033d00000003*
+ ID_PRODUCT_FROM_DATABASE=ATM Controller
+
+pci:v00001033d00000004*
+ ID_PRODUCT_FROM_DATABASE=R4000 PCI Bridge
+
+pci:v00001033d00000005*
+ ID_PRODUCT_FROM_DATABASE=PCI to 486-like bus Bridge
+
+pci:v00001033d00000006*
+ ID_PRODUCT_FROM_DATABASE=PC-9800 Graphic Accelerator
+
+pci:v00001033d00000007*
+ ID_PRODUCT_FROM_DATABASE=PCI to UX-Bus Bridge
+
+pci:v00001033d00000008*
+ ID_PRODUCT_FROM_DATABASE=PC-9800 Graphic Accelerator
+
+pci:v00001033d00000009*
+ ID_PRODUCT_FROM_DATABASE=PCI to PC9800 Core-Graph Bridge
+
+pci:v00001033d00000016*
+ ID_PRODUCT_FROM_DATABASE=PCI to VL Bridge
+
+pci:v00001033d0000001A*
+ ID_PRODUCT_FROM_DATABASE=[Nile II]
+
+pci:v00001033d00000021*
+ ID_PRODUCT_FROM_DATABASE=Vrc4373 [Nile I]
+
+pci:v00001033d00000029*
+ ID_PRODUCT_FROM_DATABASE=PowerVR PCX1
+
+pci:v00001033d0000002A*
+ ID_PRODUCT_FROM_DATABASE=PowerVR 3D
+
+pci:v00001033d0000002C*
+ ID_PRODUCT_FROM_DATABASE=Star Alpha 2
+
+pci:v00001033d0000002D*
+ ID_PRODUCT_FROM_DATABASE=PCI to C-bus Bridge
+
+pci:v00001033d00000035*
+ ID_PRODUCT_FROM_DATABASE=USB
+
+pci:v00001033d00000035sv00001033sd00000035*
+ ID_PRODUCT_FROM_DATABASE=Hama USB 2.0 CardBus
+
+pci:v00001033d00000035sv0000103Csd00001293*
+ ID_PRODUCT_FROM_DATABASE=USB add-in card
+
+pci:v00001033d00000035sv0000103Csd00001294*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 add-in card
+
+pci:v00001033d00000035sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=USB
+
+pci:v00001033d00000035sv000012EEsd00007000*
+ ID_PRODUCT_FROM_DATABASE=Root Hub
+
+pci:v00001033d00000035sv000014C2sd00000105*
+ ID_PRODUCT_FROM_DATABASE=PTI-205N USB 2.0 Host Controller
+
+pci:v00001033d00000035sv00001799sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Root Hub
+
+pci:v00001033d00000035sv00001931sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=GlobeTrotter Fusion Quad Lite (PPP data)
+
+pci:v00001033d00000035sv00001931sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=GlobeTrotter Fusion Quad Lite (GSM data)
+
+pci:v00001033d00000035sv0000807Dsd00000035*
+ ID_PRODUCT_FROM_DATABASE=PCI-USB2 (OHCI subsystem)
+
+pci:v00001033d0000003B*
+ ID_PRODUCT_FROM_DATABASE=PCI to C-bus Bridge
+
+pci:v00001033d0000003E*
+ ID_PRODUCT_FROM_DATABASE=NAPCCARD Cardbus Controller
+
+pci:v00001033d00000046*
+ ID_PRODUCT_FROM_DATABASE=PowerVR PCX2 [midas]
+
+pci:v00001033d0000005A*
+ ID_PRODUCT_FROM_DATABASE=Vrc5074 [Nile 4]
+
+pci:v00001033d00000063*
+ ID_PRODUCT_FROM_DATABASE=uPD72862 [Firewarden] IEEE1394 OHCI 1.0 Link Controller
+
+pci:v00001033d00000067*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 Chipset
+
+pci:v00001033d00000067sv00001010sd00000020*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb
+
+pci:v00001033d00000067sv00001010sd00000080*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 16Mb
+
+pci:v00001033d00000067sv00001010sd00000088*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 16Mb
+
+pci:v00001033d00000067sv00001010sd00000090*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 16Mb
+
+pci:v00001033d00000067sv00001010sd00000098*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 16Mb
+
+pci:v00001033d00000067sv00001010sd000000A0*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb
+
+pci:v00001033d00000067sv00001010sd000000A8*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 32Mb
+
+pci:v00001033d00000067sv00001010sd00000120*
+ ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb
+
+pci:v00001033d00000072*
+ ID_PRODUCT_FROM_DATABASE=uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
+
+pci:v00001033d00000074*
+ ID_PRODUCT_FROM_DATABASE=56k Voice Modem
+
+pci:v00001033d00000074sv00001033sd00008014*
+ ID_PRODUCT_FROM_DATABASE=RCV56ACF 56k Voice Modem
+
+pci:v00001033d0000009B*
+ ID_PRODUCT_FROM_DATABASE=Vrc5476
+
+pci:v00001033d000000A5*
+ ID_PRODUCT_FROM_DATABASE=VRC4173
+
+pci:v00001033d000000A6*
+ ID_PRODUCT_FROM_DATABASE=VRC5477 AC97
+
+pci:v00001033d000000CD*
+ ID_PRODUCT_FROM_DATABASE=uPD72870 [Firewarden] IEEE1394a OHCI 1.0 Link/3-port PHY Controller
+
+pci:v00001033d000000CDsv000012EEsd00008011*
+ ID_PRODUCT_FROM_DATABASE=Root hub
+
+pci:v00001033d000000CE*
+ ID_PRODUCT_FROM_DATABASE=uPD72871 [Firewarden] IEEE1394a OHCI 1.0 Link/1-port PHY Controller
+
+pci:v00001033d000000DF*
+ ID_PRODUCT_FROM_DATABASE=Vr4131
+
+pci:v00001033d000000E0*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0
+
+pci:v00001033d000000E0sv000012EEsd00007001*
+ ID_PRODUCT_FROM_DATABASE=Root hub
+
+pci:v00001033d000000E0sv000014C2sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PTI-205N USB 2.0 Host Controller
+
+pci:v00001033d000000E0sv00001799sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Root Hub
+
+pci:v00001033d000000E0sv0000807Dsd00001043*
+ ID_PRODUCT_FROM_DATABASE=PCI-USB2 (EHCI subsystem)
+
+pci:v00001033d000000E7*
+ ID_PRODUCT_FROM_DATABASE=uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller
+
+pci:v00001033d000000F2*
+ ID_PRODUCT_FROM_DATABASE=uPD72874 [Firewarden] IEEE1394a OHCI 1.1 Link/3-port PHY Controller
+
+pci:v00001033d000000F3*
+ ID_PRODUCT_FROM_DATABASE=uPD6113x Multimedia Decoder/Processor [EMMA2]
+
+pci:v00001033d0000010C*
+ ID_PRODUCT_FROM_DATABASE=VR7701
+
+pci:v00001033d00000125*
+ ID_PRODUCT_FROM_DATABASE=uPD720400 PCI Express - PCI/PCI-X Bridge
+
+pci:v00001033d0000013A*
+ ID_PRODUCT_FROM_DATABASE=Dual Tuner/MPEG Encoder
+
+pci:v00001033d00000194*
+ ID_PRODUCT_FROM_DATABASE=uPD720200 USB 3.0 Host Controller
+
+pci:v00001033d00000194sv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00001033d00000194sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00001033d00000194sv00001043sd00008413*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00001033d00000194sv00001B96sd00000001*
+ ID_PRODUCT_FROM_DATABASE=USB 3.0 PCIe Card
+
+pci:v00001033d000001E7*
+ ID_PRODUCT_FROM_DATABASE=uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller
+
+pci:v00001033d000001F2*
+ ID_PRODUCT_FROM_DATABASE=uPD72874 [Firewarden] IEEE1394a OHCI 1.1 Link/3-port PHY Controller
+
+pci:v00001034*
+ ID_VENDOR_FROM_DATABASE=Framatome Connectors USA Inc.
+
+pci:v00001035*
+ ID_VENDOR_FROM_DATABASE=Comp. & Comm. Research Lab
+
+pci:v00001036*
+ ID_VENDOR_FROM_DATABASE=Future Domain Corp.
+
+pci:v00001036d00000000*
+ ID_PRODUCT_FROM_DATABASE=TMC-18C30 [36C70]
+
+pci:v00001037*
+ ID_VENDOR_FROM_DATABASE=Hitachi Micro Systems
+
+pci:v00001038*
+ ID_VENDOR_FROM_DATABASE=AMP, Inc
+
+pci:v00001039*
+ ID_VENDOR_FROM_DATABASE=Silicon Integrated Systems [SiS]
+
+pci:v00001039d00000001*
+ ID_PRODUCT_FROM_DATABASE=AGP Port (virtual PCI-to-PCI bridge)
+
+pci:v00001039d00000002*
+ ID_PRODUCT_FROM_DATABASE=AGP Port (virtual PCI-to-PCI bridge)
+
+pci:v00001039d00000003*
+ ID_PRODUCT_FROM_DATABASE=AGP Port (virtual PCI-to-PCI bridge)
+
+pci:v00001039d00000004*
+ ID_PRODUCT_FROM_DATABASE=PCI-to-PCI bridge
+
+pci:v00001039d00000006*
+ ID_PRODUCT_FROM_DATABASE=85C501/2/3
+
+pci:v00001039d00000008*
+ ID_PRODUCT_FROM_DATABASE=SiS85C503/5513 (LPC Bridge)
+
+pci:v00001039d00000009*
+ ID_PRODUCT_FROM_DATABASE=5595 Power Management Controller
+
+pci:v00001039d0000000A*
+ ID_PRODUCT_FROM_DATABASE=PCI-to-PCI bridge
+
+pci:v00001039d00000016*
+ ID_PRODUCT_FROM_DATABASE=SiS961/2/3 SMBus controller
+
+pci:v00001039d00000018*
+ ID_PRODUCT_FROM_DATABASE=SiS85C503/5513 (LPC Bridge)
+
+pci:v00001039d00000180*
+ ID_PRODUCT_FROM_DATABASE=RAID bus controller 180 SATA/PATA  [SiS]
+
+pci:v00001039d00000181*
+ ID_PRODUCT_FROM_DATABASE=SATA
+
+pci:v00001039d00000182*
+ ID_PRODUCT_FROM_DATABASE=182 SATA/RAID Controller
+
+pci:v00001039d00000182sv00001734sd00001095*
+ ID_PRODUCT_FROM_DATABASE=D2030-A1
+
+pci:v00001039d00000186*
+ ID_PRODUCT_FROM_DATABASE=AHCI Controller (0106)
+
+pci:v00001039d00000190*
+ ID_PRODUCT_FROM_DATABASE=190 Ethernet Adapter
+
+pci:v00001039d00000191*
+ ID_PRODUCT_FROM_DATABASE=191 Gigabit Ethernet Adapter
+
+pci:v00001039d00000200*
+ ID_PRODUCT_FROM_DATABASE=5597/5598/6326 VGA
+
+pci:v00001039d00000200sv00001039sd00000000*
+ ID_PRODUCT_FROM_DATABASE=SiS5597 SVGA (Shared RAM)
+
+pci:v00001039d00000204*
+ ID_PRODUCT_FROM_DATABASE=82C204
+
+pci:v00001039d00000205*
+ ID_PRODUCT_FROM_DATABASE=SG86C205
+
+pci:v00001039d00000300*
+ ID_PRODUCT_FROM_DATABASE=300/305 PCI/AGP VGA Display Adapter
+
+pci:v00001039d00000300sv0000107Dsd00002720*
+ ID_PRODUCT_FROM_DATABASE=Leadtek WinFast VR300
+
+pci:v00001039d00000310*
+ ID_PRODUCT_FROM_DATABASE=315H PCI/AGP VGA Display Adapter
+
+pci:v00001039d00000315*
+ ID_PRODUCT_FROM_DATABASE=315 PCI/AGP VGA Display Adapter
+
+pci:v00001039d00000325*
+ ID_PRODUCT_FROM_DATABASE=315PRO PCI/AGP VGA Display Adapter
+
+pci:v00001039d00000330*
+ ID_PRODUCT_FROM_DATABASE=330 [Xabre] PCI/AGP VGA Display Adapter
+
+pci:v00001039d00000406*
+ ID_PRODUCT_FROM_DATABASE=85C501/2
+
+pci:v00001039d00000496*
+ ID_PRODUCT_FROM_DATABASE=85C496
+
+pci:v00001039d00000530*
+ ID_PRODUCT_FROM_DATABASE=530 Host
+
+pci:v00001039d00000540*
+ ID_PRODUCT_FROM_DATABASE=540 Host
+
+pci:v00001039d00000550*
+ ID_PRODUCT_FROM_DATABASE=550 Host
+
+pci:v00001039d00000597*
+ ID_PRODUCT_FROM_DATABASE=5513C
+
+pci:v00001039d00000601*
+ ID_PRODUCT_FROM_DATABASE=85C601
+
+pci:v00001039d00000620*
+ ID_PRODUCT_FROM_DATABASE=620 Host
+
+pci:v00001039d00000630*
+ ID_PRODUCT_FROM_DATABASE=630 Host
+
+pci:v00001039d00000633*
+ ID_PRODUCT_FROM_DATABASE=633 Host
+
+pci:v00001039d00000635*
+ ID_PRODUCT_FROM_DATABASE=635 Host
+
+pci:v00001039d00000645*
+ ID_PRODUCT_FROM_DATABASE=SiS645 Host & Memory & AGP Controller
+
+pci:v00001039d00000646*
+ ID_PRODUCT_FROM_DATABASE=SiS645DX Host & Memory & AGP Controller
+
+pci:v00001039d00000648*
+ ID_PRODUCT_FROM_DATABASE=645xx
+
+pci:v00001039d00000649*
+ ID_PRODUCT_FROM_DATABASE=SiS649 Host
+
+pci:v00001039d00000650*
+ ID_PRODUCT_FROM_DATABASE=650/M650 Host
+
+pci:v00001039d00000651*
+ ID_PRODUCT_FROM_DATABASE=651 Host
+
+pci:v00001039d00000655*
+ ID_PRODUCT_FROM_DATABASE=655 Host
+
+pci:v00001039d00000660*
+ ID_PRODUCT_FROM_DATABASE=660 Host
+
+pci:v00001039d00000661*
+ ID_PRODUCT_FROM_DATABASE=661FX/M661FX/M661MX Host
+
+pci:v00001039d00000662*
+ ID_PRODUCT_FROM_DATABASE=662 Host
+
+pci:v00001039d00000671*
+ ID_PRODUCT_FROM_DATABASE=671MX
+
+pci:v00001039d00000730*
+ ID_PRODUCT_FROM_DATABASE=730 Host
+
+pci:v00001039d00000733*
+ ID_PRODUCT_FROM_DATABASE=733 Host
+
+pci:v00001039d00000735*
+ ID_PRODUCT_FROM_DATABASE=735 Host
+
+pci:v00001039d00000740*
+ ID_PRODUCT_FROM_DATABASE=740 Host
+
+pci:v00001039d00000741*
+ ID_PRODUCT_FROM_DATABASE=741/741GX/M741 Host
+
+pci:v00001039d00000741sv00001849sd00000741*
+ ID_PRODUCT_FROM_DATABASE=K7S41/K7S41GX motherboard
+
+pci:v00001039d00000745*
+ ID_PRODUCT_FROM_DATABASE=745 Host
+
+pci:v00001039d00000746*
+ ID_PRODUCT_FROM_DATABASE=746 Host
+
+pci:v00001039d00000755*
+ ID_PRODUCT_FROM_DATABASE=755 Host
+
+pci:v00001039d00000760*
+ ID_PRODUCT_FROM_DATABASE=760/M760 Host
+
+pci:v00001039d00000761*
+ ID_PRODUCT_FROM_DATABASE=761/M761 Host
+
+pci:v00001039d00000761sv00001734sd00001099*
+ ID_PRODUCT_FROM_DATABASE=D2030-A1 Motherboard
+
+pci:v00001039d00000900*
+ ID_PRODUCT_FROM_DATABASE=SiS900 PCI Fast Ethernet
+
+pci:v00001039d00000900sv00001019sd00000A14*
+ ID_PRODUCT_FROM_DATABASE=K7S5A motherboard
+
+pci:v00001039d00000900sv00001039sd00000900*
+ ID_PRODUCT_FROM_DATABASE=SiS900 10/100 Ethernet Adapter onboard [Asus P4SC-EA]
+
+pci:v00001039d00000900sv00001043sd00008035*
+ ID_PRODUCT_FROM_DATABASE=CUSI-FX motherboard
+
+pci:v00001039d00000900sv00001043sd000080A7*
+ ID_PRODUCT_FROM_DATABASE=Motherboard P4S800D-X
+
+pci:v00001039d00000900sv00001462sd00000900*
+ ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard
+
+pci:v00001039d00000961*
+ ID_PRODUCT_FROM_DATABASE=SiS961 [MuTIOL Media IO]
+
+pci:v00001039d00000962*
+ ID_PRODUCT_FROM_DATABASE=SiS962 [MuTIOL Media IO] LPC Controller
+
+pci:v00001039d00000963*
+ ID_PRODUCT_FROM_DATABASE=SiS963 [MuTIOL Media IO] LPC Controller
+
+pci:v00001039d00000964*
+ ID_PRODUCT_FROM_DATABASE=SiS964 [MuTIOL Media IO] LPC Controller
+
+pci:v00001039d00000965*
+ ID_PRODUCT_FROM_DATABASE=SiS965 [MuTIOL Media IO]
+
+pci:v00001039d00000966*
+ ID_PRODUCT_FROM_DATABASE=SiS966 [MuTIOL Media IO]
+
+pci:v00001039d00000968*
+ ID_PRODUCT_FROM_DATABASE=SiS968 [MuTIOL Media IO]
+
+pci:v00001039d00001180*
+ ID_PRODUCT_FROM_DATABASE=SATA Controller / IDE mode
+
+pci:v00001039d00001182*
+ ID_PRODUCT_FROM_DATABASE=SATA Controller / RAID mode
+
+pci:v00001039d00001183*
+ ID_PRODUCT_FROM_DATABASE=SATA Controller / IDE mode
+
+pci:v00001039d00001184*
+ ID_PRODUCT_FROM_DATABASE=AHCI Controller / RAID mode
+
+pci:v00001039d00001185*
+ ID_PRODUCT_FROM_DATABASE=AHCI IDE Controller (0106)
+
+pci:v00001039d00003602*
+ ID_PRODUCT_FROM_DATABASE=83C602
+
+pci:v00001039d00005107*
+ ID_PRODUCT_FROM_DATABASE=5107
+
+pci:v00001039d00005300*
+ ID_PRODUCT_FROM_DATABASE=SiS540 PCI Display Adapter
+
+pci:v00001039d00005315*
+ ID_PRODUCT_FROM_DATABASE=550 PCI/AGP VGA Display Adapter
+
+pci:v00001039d00005401*
+ ID_PRODUCT_FROM_DATABASE=486 PCI Chipset
+
+pci:v00001039d00005511*
+ ID_PRODUCT_FROM_DATABASE=5511/5512
+
+pci:v00001039d00005513*
+ ID_PRODUCT_FROM_DATABASE=5513 IDE Controller
+
+pci:v00001039d00005513sv00001019sd00000970*
+ ID_PRODUCT_FROM_DATABASE=P6STP-FL motherboard
+
+pci:v00001039d00005513sv00001039sd00005513*
+ ID_PRODUCT_FROM_DATABASE=SiS5513 EIDE Controller (A,B step)
+
+pci:v00001039d00005513sv00001043sd00008035*
+ ID_PRODUCT_FROM_DATABASE=CUSI-FX motherboard
+
+pci:v00001039d00005513sv00001462sd00007010*
+ ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard
+
+pci:v00001039d00005513sv00001631sd00005513*
+ ID_PRODUCT_FROM_DATABASE=GA-8SIML Rev1.0 Motherboard
+
+pci:v00001039d00005513sv00001734sd00001095*
+ ID_PRODUCT_FROM_DATABASE=D2030-A1 Motherboard
+
+pci:v00001039d00005517*
+ ID_PRODUCT_FROM_DATABASE=5517
+
+pci:v00001039d00005571*
+ ID_PRODUCT_FROM_DATABASE=5571
+
+pci:v00001039d00005581*
+ ID_PRODUCT_FROM_DATABASE=5581 Pentium Chipset
+
+pci:v00001039d00005582*
+ ID_PRODUCT_FROM_DATABASE=5582
+
+pci:v00001039d00005591*
+ ID_PRODUCT_FROM_DATABASE=5591/5592 Host
+
+pci:v00001039d00005596*
+ ID_PRODUCT_FROM_DATABASE=5596 Pentium Chipset
+
+pci:v00001039d00005597*
+ ID_PRODUCT_FROM_DATABASE=5597 [SiS5582]
+
+pci:v00001039d00005600*
+ ID_PRODUCT_FROM_DATABASE=5600 Host
+
+pci:v00001039d00006204*
+ ID_PRODUCT_FROM_DATABASE=Video decoder & MPEG interface
+
+pci:v00001039d00006205*
+ ID_PRODUCT_FROM_DATABASE=VGA Controller
+
+pci:v00001039d00006236*
+ ID_PRODUCT_FROM_DATABASE=6236 3D-AGP
+
+pci:v00001039d00006300*
+ ID_PRODUCT_FROM_DATABASE=630/730 PCI/AGP VGA Display Adapter
+
+pci:v00001039d00006300sv00001019sd00000970*
+ ID_PRODUCT_FROM_DATABASE=P6STP-FL motherboard
+
+pci:v00001039d00006300sv00001043sd00008035*
+ ID_PRODUCT_FROM_DATABASE=CUSI-FX motherboard
+
+pci:v00001039d00006300sv0000104Dsd000080E2*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCV-J200
+
+pci:v00001039d00006306*
+ ID_PRODUCT_FROM_DATABASE=530/620 PCI/AGP VGA Display Adapter
+
+pci:v00001039d00006325*
+ ID_PRODUCT_FROM_DATABASE=65x/M650/740 PCI/AGP VGA Display Adapter
+
+pci:v00001039d00006325sv00001039sd00006325*
+ ID_PRODUCT_FROM_DATABASE=SiS 651 onboard [Asus P4SC-EA]
+
+pci:v00001039d00006325sv00001631sd00001004*
+ ID_PRODUCT_FROM_DATABASE=SiS 651C onboard [Gigabyte GA-8SIML Rev1.0]
+
+pci:v00001039d00006326*
+ ID_PRODUCT_FROM_DATABASE=86C326 5598/6326
+
+pci:v00001039d00006326sv00001039sd00006326*
+ ID_PRODUCT_FROM_DATABASE=SiS6326 GUI Accelerator
+
+pci:v00001039d00006326sv00001092sd00000A50*
+ ID_PRODUCT_FROM_DATABASE=SpeedStar A50
+
+pci:v00001039d00006326sv00001092sd00000A70*
+ ID_PRODUCT_FROM_DATABASE=SpeedStar A70
+
+pci:v00001039d00006326sv00001092sd00004910*
+ ID_PRODUCT_FROM_DATABASE=SpeedStar A70
+
+pci:v00001039d00006326sv00001092sd00004920*
+ ID_PRODUCT_FROM_DATABASE=SpeedStar A70
+
+pci:v00001039d00006326sv000010B0sd00006326*
+ ID_PRODUCT_FROM_DATABASE=S6110-B (AGP)
+
+pci:v00001039d00006326sv00001569sd00006326*
+ ID_PRODUCT_FROM_DATABASE=SiS6326 GUI Accelerator
+
+pci:v00001039d00006330*
+ ID_PRODUCT_FROM_DATABASE=661/741/760 PCI/AGP or 662/761Gx PCIE VGA Display Adapter
+
+pci:v00001039d00006330sv00001039sd00006330*
+ ID_PRODUCT_FROM_DATABASE=[M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter
+
+pci:v00001039d00006330sv00001043sd00008113*
+ ID_PRODUCT_FROM_DATABASE=SiS Real 256E (ASUS P5S800-VM motherboard)
+
+pci:v00001039d00006330sv00001458sd0000D000*
+ ID_PRODUCT_FROM_DATABASE=SiS661FX GUI 2D/3D Accelerator
+
+pci:v00001039d00006330sv00001734sd00001099*
+ ID_PRODUCT_FROM_DATABASE=D2030-A1
+
+pci:v00001039d00006350*
+ ID_PRODUCT_FROM_DATABASE=770/670 PCIE VGA Display Adapter
+
+pci:v00001039d00006351*
+ ID_PRODUCT_FROM_DATABASE=771/671 PCIE VGA Display Adapter
+
+pci:v00001039d00007001*
+ ID_PRODUCT_FROM_DATABASE=USB 1.1 Controller
+
+pci:v00001039d00007001sv00001019sd00000A14*
+ ID_PRODUCT_FROM_DATABASE=K7S5A motherboard
+
+pci:v00001039d00007001sv00001039sd00007000*
+ ID_PRODUCT_FROM_DATABASE=Onboard USB Controller
+
+pci:v00001039d00007001sv00001462sd00005470*
+ ID_PRODUCT_FROM_DATABASE=ECS K7SOM+ motherboard
+
+pci:v00001039d00007001sv00001462sd00007010*
+ ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard
+
+pci:v00001039d00007001sv00001734sd00001095*
+ ID_PRODUCT_FROM_DATABASE=D2030-A1 Motherboard
+
+pci:v00001039d00007002*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Controller
+
+pci:v00001039d00007002sv00001462sd00005470*
+ ID_PRODUCT_FROM_DATABASE=K7SOM+ 5.2C Motherboard
+
+pci:v00001039d00007002sv00001462sd00007010*
+ ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard
+
+pci:v00001039d00007002sv00001509sd00007002*
+ ID_PRODUCT_FROM_DATABASE=Onboard USB Controller
+
+pci:v00001039d00007002sv00001734sd00001095*
+ ID_PRODUCT_FROM_DATABASE=D2030-A1
+
+pci:v00001039d00007007*
+ ID_PRODUCT_FROM_DATABASE=FireWire Controller
+
+pci:v00001039d00007007sv00001462sd0000701D*
+ ID_PRODUCT_FROM_DATABASE=MS-6701
+
+pci:v00001039d00007012*
+ ID_PRODUCT_FROM_DATABASE=SiS7012 AC'97 Sound Controller
+
+pci:v00001039d00007012sv00001019sd00000F05*
+ ID_PRODUCT_FROM_DATABASE=A928 (i-Buddie)
+
+pci:v00001039d00007012sv00001039sd00007012*
+ ID_PRODUCT_FROM_DATABASE=SiS 7012 onboard [Asus P4SC-EA] AC'97 Sound Controller
+
+pci:v00001039d00007012sv00001043sd0000818F*
+ ID_PRODUCT_FROM_DATABASE=A8S-X Motherboard
+
+pci:v00001039d00007012sv000013F6sd00000300*
+ ID_PRODUCT_FROM_DATABASE=CMI9739(A) on ECS K7SOM+ motherboard
+
+pci:v00001039d00007012sv00001462sd00005850*
+ ID_PRODUCT_FROM_DATABASE=MSI 648 Max (MS-6585)
+
+pci:v00001039d00007012sv00001462sd00007010*
+ ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard
+
+pci:v00001039d00007012sv000015BDsd00001001*
+ ID_PRODUCT_FROM_DATABASE=DFI 661FX motherboard
+
+pci:v00001039d00007012sv00001734sd0000109F*
+ ID_PRODUCT_FROM_DATABASE=D2030-A1 Motherboard
+
+pci:v00001039d00007012sv00001849sd00007012*
+ ID_PRODUCT_FROM_DATABASE=K7S41GX motherboard
+
+pci:v00001039d00007013*
+ ID_PRODUCT_FROM_DATABASE=AC'97 Modem Controller
+
+pci:v00001039d00007016*
+ ID_PRODUCT_FROM_DATABASE=SiS7016 PCI Fast Ethernet Adapter
+
+pci:v00001039d00007016sv00001039sd00007016*
+ ID_PRODUCT_FROM_DATABASE=SiS7016 10/100 Ethernet Adapter
+
+pci:v00001039d00007018*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001014sd000001B6*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001014sd000001B7*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001019sd00007018*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001025sd0000000E*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001025sd00000018*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001039sd00007018*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001043sd00001453*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001043sd0000800B*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv0000104Dsd000080E2*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCV-J200
+
+pci:v00001039d00007018sv00001054sd00007018*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv0000107Dsd00005330*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv0000107Dsd00005350*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001170sd00003209*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001462sd0000400A*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv000014A4sd00002089*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv000014CDsd00002194*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv000014FFsd00001100*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv0000152Dsd00008808*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001558sd00001103*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001558sd00002200*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv00001563sd00007018*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv000015C5sd00000111*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv0000270Fsd0000A171*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007018sv0000A0A0sd00000022*
+ ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator
+
+pci:v00001039d00007019*
+ ID_PRODUCT_FROM_DATABASE=SiS7019 Audio Accelerator
+
+pci:v00001039d00007502*
+ ID_PRODUCT_FROM_DATABASE=Azalia Audio Controller
+
+pci:v0000103A*
+ ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation
+
+pci:v0000103B*
+ ID_VENDOR_FROM_DATABASE=Tatung Corp. Of America
+
+pci:v0000103C*
+ ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company
+
+pci:v0000103Cd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v0000103Cd0000002A*
+ ID_PRODUCT_FROM_DATABASE=NX9000 Notebook
+
+pci:v0000103Cd000008BC*
+ ID_PRODUCT_FROM_DATABASE=NX5000 Notebook
+
+pci:v0000103Cd00001005*
+ ID_PRODUCT_FROM_DATABASE=A4977A Visualize EG
+
+pci:v0000103Cd00001008*
+ ID_PRODUCT_FROM_DATABASE=Visualize FX
+
+pci:v0000103Cd00001028*
+ ID_PRODUCT_FROM_DATABASE=Tach TL Fibre Channel Host Adapter
+
+pci:v0000103Cd00001029*
+ ID_PRODUCT_FROM_DATABASE=Tach XL2 Fibre Channel Host Adapter
+
+pci:v0000103Cd00001029sv0000107Esd0000000F*
+ ID_PRODUCT_FROM_DATABASE=Interphase 5560 Fibre Channel Adapter
+
+pci:v0000103Cd00001029sv00009004sd00009210*
+ ID_PRODUCT_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller
+
+pci:v0000103Cd00001029sv00009004sd00009211*
+ ID_PRODUCT_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller
+
+pci:v0000103Cd0000102A*
+ ID_PRODUCT_FROM_DATABASE=Tach TS Fibre Channel Host Adapter
+
+pci:v0000103Cd0000102Asv0000107Esd0000000E*
+ ID_PRODUCT_FROM_DATABASE=Interphase 5540/5541 Fibre Channel Adapter
+
+pci:v0000103Cd0000102Asv00009004sd00009110*
+ ID_PRODUCT_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller
+
+pci:v0000103Cd0000102Asv00009004sd00009111*
+ ID_PRODUCT_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller
+
+pci:v0000103Cd00001030*
+ ID_PRODUCT_FROM_DATABASE=J2585A DeskDirect 10/100VG NIC
+
+pci:v0000103Cd00001031*
+ ID_PRODUCT_FROM_DATABASE=J2585B HP 10/100VG PCI LAN Adapter
+
+pci:v0000103Cd00001031sv0000103Csd00001040*
+ ID_PRODUCT_FROM_DATABASE=J2973A DeskDirect 10BaseT NIC
+
+pci:v0000103Cd00001031sv0000103Csd00001041*
+ ID_PRODUCT_FROM_DATABASE=J2585B DeskDirect 10/100VG NIC
+
+pci:v0000103Cd00001031sv0000103Csd00001042*
+ ID_PRODUCT_FROM_DATABASE=J2970A DeskDirect 10BaseT/2 NIC
+
+pci:v0000103Cd00001040*
+ ID_PRODUCT_FROM_DATABASE=J2973A DeskDirect 10BaseT NIC
+
+pci:v0000103Cd00001041*
+ ID_PRODUCT_FROM_DATABASE=J2585B DeskDirect 10/100 NIC
+
+pci:v0000103Cd00001042*
+ ID_PRODUCT_FROM_DATABASE=J2970A DeskDirect 10BaseT/2 NIC
+
+pci:v0000103Cd00001048*
+ ID_PRODUCT_FROM_DATABASE=Diva Serial [GSP] Multiport UART
+
+pci:v0000103Cd00001048sv0000103Csd00001049*
+ ID_PRODUCT_FROM_DATABASE=Tosca Console
+
+pci:v0000103Cd00001048sv0000103Csd0000104A*
+ ID_PRODUCT_FROM_DATABASE=Tosca Secondary
+
+pci:v0000103Cd00001048sv0000103Csd0000104B*
+ ID_PRODUCT_FROM_DATABASE=Maestro SP2
+
+pci:v0000103Cd00001048sv0000103Csd00001223*
+ ID_PRODUCT_FROM_DATABASE=Superdome Console
+
+pci:v0000103Cd00001048sv0000103Csd00001226*
+ ID_PRODUCT_FROM_DATABASE=Keystone SP2
+
+pci:v0000103Cd00001048sv0000103Csd00001227*
+ ID_PRODUCT_FROM_DATABASE=Powerbar SP2
+
+pci:v0000103Cd00001048sv0000103Csd00001282*
+ ID_PRODUCT_FROM_DATABASE=Everest SP2
+
+pci:v0000103Cd00001048sv0000103Csd00001301*
+ ID_PRODUCT_FROM_DATABASE=Diva RMP3
+
+pci:v0000103Cd00001054*
+ ID_PRODUCT_FROM_DATABASE=PCI Local Bus Adapter
+
+pci:v0000103Cd00001064*
+ ID_PRODUCT_FROM_DATABASE=79C970 PCnet Ethernet Controller
+
+pci:v0000103Cd0000108B*
+ ID_PRODUCT_FROM_DATABASE=Visualize FXe
+
+pci:v0000103Cd000010C1*
+ ID_PRODUCT_FROM_DATABASE=NetServer Smart IRQ Router
+
+pci:v0000103Cd000010ED*
+ ID_PRODUCT_FROM_DATABASE=TopTools Remote Control
+
+pci:v0000103Cd000010F0*
+ ID_PRODUCT_FROM_DATABASE=rio System Bus Adapter
+
+pci:v0000103Cd000010F1*
+ ID_PRODUCT_FROM_DATABASE=rio I/O Controller
+
+pci:v0000103Cd00001200*
+ ID_PRODUCT_FROM_DATABASE=82557B 10/100 NIC
+
+pci:v0000103Cd00001219*
+ ID_PRODUCT_FROM_DATABASE=NetServer PCI Hot-Plug Controller
+
+pci:v0000103Cd0000121A*
+ ID_PRODUCT_FROM_DATABASE=NetServer SMIC Controller
+
+pci:v0000103Cd0000121B*
+ ID_PRODUCT_FROM_DATABASE=NetServer Legacy COM Port Decoder
+
+pci:v0000103Cd0000121C*
+ ID_PRODUCT_FROM_DATABASE=NetServer PCI COM Port Decoder
+
+pci:v0000103Cd00001229*
+ ID_PRODUCT_FROM_DATABASE=zx1 System Bus Adapter
+
+pci:v0000103Cd0000122A*
+ ID_PRODUCT_FROM_DATABASE=zx1 I/O Controller
+
+pci:v0000103Cd0000122E*
+ ID_PRODUCT_FROM_DATABASE=PCI-X Local Bus Adapter
+
+pci:v0000103Cd0000127B*
+ ID_PRODUCT_FROM_DATABASE=sx1000 System Bus Adapter
+
+pci:v0000103Cd0000127C*
+ ID_PRODUCT_FROM_DATABASE=sx1000 I/O Controller
+
+pci:v0000103Cd00001290*
+ ID_PRODUCT_FROM_DATABASE=Auxiliary Diva Serial Port
+
+pci:v0000103Cd00001290sv0000103Csd00001291*
+ ID_PRODUCT_FROM_DATABASE=Diva SP2
+
+pci:v0000103Cd00001291*
+ ID_PRODUCT_FROM_DATABASE=Auxiliary Diva Serial Port
+
+pci:v0000103Cd000012B4*
+ ID_PRODUCT_FROM_DATABASE=zx1 QuickSilver AGP8x Local Bus Adapter
+
+pci:v0000103Cd000012EB*
+ ID_PRODUCT_FROM_DATABASE=sx2000 System Bus Adapter
+
+pci:v0000103Cd000012EC*
+ ID_PRODUCT_FROM_DATABASE=sx2000 I/O Controller
+
+pci:v0000103Cd000012EE*
+ ID_PRODUCT_FROM_DATABASE=PCI-X 2.0 Local Bus Adapter
+
+pci:v0000103Cd000012F8*
+ ID_PRODUCT_FROM_DATABASE=Broadcom BCM4306 802.11b/g Wireless LAN
+
+pci:v0000103Cd000012FA*
+ ID_PRODUCT_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller
+
+pci:v0000103Cd00001302*
+ ID_PRODUCT_FROM_DATABASE=RMP-3 Shared Memory Driver
+
+pci:v0000103Cd00001303*
+ ID_PRODUCT_FROM_DATABASE=RMP-3 (Remote Management Processor)
+
+pci:v0000103Cd00001361*
+ ID_PRODUCT_FROM_DATABASE=BCM4312 802.11a/b/g WLAN Controller
+
+pci:v0000103Cd00001371*
+ ID_PRODUCT_FROM_DATABASE=Broadcom Corporation BCM4312 802.11a/b/g (rev 02)
+
+pci:v0000103Cd00001717*
+ ID_PRODUCT_FROM_DATABASE=Intel 82571EB dual 1 Gb Ethernet controller
+
+pci:v0000103Cd0000179B*
+ ID_PRODUCT_FROM_DATABASE=EliteBook 8470p Notebook
+
+pci:v0000103Cd0000179D*
+ ID_PRODUCT_FROM_DATABASE=EliteBook 8470p Notebook
+
+pci:v0000103Cd00002910*
+ ID_PRODUCT_FROM_DATABASE=E2910A PCIBus Exerciser
+
+pci:v0000103Cd00002925*
+ ID_PRODUCT_FROM_DATABASE=E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer
+
+pci:v0000103Cd00003080*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze2028ea
+
+pci:v0000103Cd00003085*
+ ID_PRODUCT_FROM_DATABASE=Realtek RTL8139/8139C/8139C+
+
+pci:v0000103Cd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq NW8440 Notebook
+
+pci:v0000103Cd000030B5*
+ ID_PRODUCT_FROM_DATABASE=Compaq Presario V3000Z
+
+pci:v0000103Cd000031FB*
+ ID_PRODUCT_FROM_DATABASE=DL365 ATI ES1000 VGA controller
+
+pci:v0000103Cd00003206*
+ ID_PRODUCT_FROM_DATABASE=Adaptec Embedded Serial ATA HostRAID
+
+pci:v0000103Cd00003220*
+ ID_PRODUCT_FROM_DATABASE=Smart Array P600
+
+pci:v0000103Cd00003220sv0000103Csd00003225*
+ ID_PRODUCT_FROM_DATABASE=3 Gb/s SAS RAID
+
+pci:v0000103Cd00003230*
+ ID_PRODUCT_FROM_DATABASE=Smart Array Controller
+
+pci:v0000103Cd00003230sv0000103Csd00003223*
+ ID_PRODUCT_FROM_DATABASE=Smart Array P800
+
+pci:v0000103Cd00003230sv0000103Csd00003234*
+ ID_PRODUCT_FROM_DATABASE=P400 SAS Controller
+
+pci:v0000103Cd00003230sv0000103Csd00003235*
+ ID_PRODUCT_FROM_DATABASE=P400i SAS Controller
+
+pci:v0000103Cd00003230sv0000103Csd00003237*
+ ID_PRODUCT_FROM_DATABASE=E500 SAS Controller
+
+pci:v0000103Cd00003230sv0000103Csd0000323D*
+ ID_PRODUCT_FROM_DATABASE=P700m SAS Controller
+
+pci:v0000103Cd00003238*
+ ID_PRODUCT_FROM_DATABASE=Smart Array E200i (SAS Controller)
+
+pci:v0000103Cd00003238sv0000103Csd00003211*
+ ID_PRODUCT_FROM_DATABASE=Smart Array E200i
+
+pci:v0000103Cd00003238sv0000103Csd00003212*
+ ID_PRODUCT_FROM_DATABASE=Smart Array E200
+
+pci:v0000103Cd0000323A*
+ ID_PRODUCT_FROM_DATABASE=Smart Array G6 controllers
+
+pci:v0000103Cd0000323Asv0000103Csd00003241*
+ ID_PRODUCT_FROM_DATABASE=Smart Array P212
+
+pci:v0000103Cd0000323Asv0000103Csd00003243*
+ ID_PRODUCT_FROM_DATABASE=Smart Array P410
+
+pci:v0000103Cd0000323Asv0000103Csd00003245*
+ ID_PRODUCT_FROM_DATABASE=Smart Array P410i
+
+pci:v0000103Cd0000323Asv0000103Csd00003247*
+ ID_PRODUCT_FROM_DATABASE=Smart Array P411
+
+pci:v0000103Cd0000323Asv0000103Csd00003249*
+ ID_PRODUCT_FROM_DATABASE=Smart Array P812
+
+pci:v0000103Cd0000323Asv0000103Csd0000324A*
+ ID_PRODUCT_FROM_DATABASE=HP Smart Array 712m (Mezzanine RAID controller)
+
+pci:v0000103Cd0000323Asv0000103Csd0000324B*
+ ID_PRODUCT_FROM_DATABASE=Smart Array P711m (Mezzanine RAID controller)
+
+pci:v0000103Cd0000323B*
+ ID_PRODUCT_FROM_DATABASE=Smart Array Gen8 Controllers
+
+pci:v0000103Cd0000323Bsv0000103Csd00003350*
+ ID_PRODUCT_FROM_DATABASE=P222
+
+pci:v0000103Cd0000323Bsv0000103Csd00003351*
+ ID_PRODUCT_FROM_DATABASE=P420
+
+pci:v0000103Cd0000323Bsv0000103Csd00003352*
+ ID_PRODUCT_FROM_DATABASE=P421
+
+pci:v0000103Cd0000323Bsv0000103Csd00003354*
+ ID_PRODUCT_FROM_DATABASE=P420i
+
+pci:v0000103Cd0000323Bsv0000103Csd00003355*
+ ID_PRODUCT_FROM_DATABASE=P220i
+
+pci:v0000103Cd00003300*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller
+
+pci:v0000103Cd00003300sv0000103Csd00003304*
+ ID_PRODUCT_FROM_DATABASE=iLO2
+
+pci:v0000103Cd00003300sv0000103Csd00003305*
+ ID_PRODUCT_FROM_DATABASE=iLO2
+
+pci:v0000103Cd00003300sv0000103Csd00003309*
+ ID_PRODUCT_FROM_DATABASE=iLO2 GXL/iLO3 GXE
+
+pci:v0000103Cd00003300sv0000103Csd0000330E*
+ ID_PRODUCT_FROM_DATABASE=iLO3
+
+pci:v0000103Cd00003300sv0000103Csd00003381*
+ ID_PRODUCT_FROM_DATABASE=iLO4
+
+pci:v0000103Cd00003301*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard Serial Port
+
+pci:v0000103Cd00003301sv0000103Csd00003304*
+ ID_PRODUCT_FROM_DATABASE=iLO2
+
+pci:v0000103Cd00003301sv0000103Csd00003305*
+ ID_PRODUCT_FROM_DATABASE=iLO2
+
+pci:v0000103Cd00003301sv0000103Csd0000330E*
+ ID_PRODUCT_FROM_DATABASE=iLO3
+
+pci:v0000103Cd00003301sv0000103Csd00003381*
+ ID_PRODUCT_FROM_DATABASE=iLO4
+
+pci:v0000103Cd00003302*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard KCS Interface
+
+pci:v0000103Cd00003302sv0000103Csd00003304*
+ ID_PRODUCT_FROM_DATABASE=iLO2
+
+pci:v0000103Cd00003302sv0000103Csd00003305*
+ ID_PRODUCT_FROM_DATABASE=iLO2
+
+pci:v0000103Cd00003302sv0000103Csd0000330E*
+ ID_PRODUCT_FROM_DATABASE=iLO3
+
+pci:v0000103Cd00003302sv0000103Csd00003381*
+ ID_PRODUCT_FROM_DATABASE=iLO4
+
+pci:v0000103Cd00003305*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out (iLO2) Controller
+
+pci:v0000103Cd00003306*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard Slave Instrumentation & System Support
+
+pci:v0000103Cd00003306sv0000103Csd0000330E*
+ ID_PRODUCT_FROM_DATABASE=iLO3
+
+pci:v0000103Cd00003306sv0000103Csd00003381*
+ ID_PRODUCT_FROM_DATABASE=iLO4
+
+pci:v0000103Cd00003307*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard Management Processor Support and Messaging
+
+pci:v0000103Cd00003307sv0000103Csd00003309*
+ ID_PRODUCT_FROM_DATABASE=iLO 2
+
+pci:v0000103Cd00003307sv0000103Csd0000330E*
+ ID_PRODUCT_FROM_DATABASE=iLO3
+
+pci:v0000103Cd00003307sv0000103Csd00003381*
+ ID_PRODUCT_FROM_DATABASE=iLO4
+
+pci:v0000103Cd00003308*
+ ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard MS Watchdog Timer
+
+pci:v0000103Cd00003308sv0000103Csd0000330E*
+ ID_PRODUCT_FROM_DATABASE=iLO3
+
+pci:v0000103Cd00003308sv0000103Csd00003381*
+ ID_PRODUCT_FROM_DATABASE=iLO4
+
+pci:v0000103Cd0000402F*
+ ID_PRODUCT_FROM_DATABASE=PCIe Root Port
+
+pci:v0000103Cd00004030*
+ ID_PRODUCT_FROM_DATABASE=zx2 System Bus Adapter
+
+pci:v0000103Cd00004031*
+ ID_PRODUCT_FROM_DATABASE=zx2 I/O Controller
+
+pci:v0000103Cd00004037*
+ ID_PRODUCT_FROM_DATABASE=PCIe Local Bus Adapter
+
+pci:v0000103Cd0000403B*
+ ID_PRODUCT_FROM_DATABASE=PCIe Root Port
+
+pci:v0000103Cd000060E8*
+ ID_PRODUCT_FROM_DATABASE=NetRAID-2M : ZX1/M (OEM AMI MegaRAID 493)
+
+pci:v0000103E*
+ ID_VENDOR_FROM_DATABASE=Solliday Engineering
+
+pci:v0000103F*
+ ID_VENDOR_FROM_DATABASE=Synopsys/Logic Modeling Group
+
+pci:v00001040*
+ ID_VENDOR_FROM_DATABASE=Accelgraphics Inc.
+
+pci:v00001041*
+ ID_VENDOR_FROM_DATABASE=Computrend
+
+pci:v00001042*
+ ID_VENDOR_FROM_DATABASE=Micron
+
+pci:v00001042d00001000*
+ ID_PRODUCT_FROM_DATABASE=PC Tech RZ1000
+
+pci:v00001042d00001001*
+ ID_PRODUCT_FROM_DATABASE=PC Tech RZ1001
+
+pci:v00001042d00003000*
+ ID_PRODUCT_FROM_DATABASE=Samurai_0
+
+pci:v00001042d00003010*
+ ID_PRODUCT_FROM_DATABASE=Samurai_1
+
+pci:v00001042d00003020*
+ ID_PRODUCT_FROM_DATABASE=Samurai_IDE
+
+pci:v00001043*
+ ID_VENDOR_FROM_DATABASE=ASUSTeK Computer Inc.
+
+pci:v00001043d00000675*
+ ID_PRODUCT_FROM_DATABASE=ISDNLink P-IN100-ST-D
+
+pci:v00001043d00000675sv00000675sd00001704*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C)
+
+pci:v00001043d00000675sv00000675sd00001707*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+
+pci:v00001043d00000675sv000010CFsd0000105E*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+
+pci:v00001043d00000C11*
+ ID_PRODUCT_FROM_DATABASE=A7N8X Motherboard nForce2 IDE/USB/SMBus
+
+pci:v00001043d00004015*
+ ID_PRODUCT_FROM_DATABASE=v7100 SDRAM [GeForce2 MX]
+
+pci:v00001043d00004021*
+ ID_PRODUCT_FROM_DATABASE=v7100 Combo Deluxe [GeForce2 MX + TV tuner]
+
+pci:v00001043d00004057*
+ ID_PRODUCT_FROM_DATABASE=v8200 GeForce 3
+
+pci:v00001043d00008043*
+ ID_PRODUCT_FROM_DATABASE=v8240 PAL 128M [P4T] Motherboard
+
+pci:v00001043d00008047*
+ ID_PRODUCT_FROM_DATABASE=v8420 Deluxe [GeForce4 Ti4200]
+
+pci:v00001043d0000807B*
+ ID_PRODUCT_FROM_DATABASE=v9280/TD [GeForce4 TI4200 8X With TV-Out and DVI]
+
+pci:v00001043d00008095*
+ ID_PRODUCT_FROM_DATABASE=A7N8X Motherboard nForce2 AC97 Audio
+
+pci:v00001043d000080AC*
+ ID_PRODUCT_FROM_DATABASE=A7N8X Motherboard nForce2 AGP/Memory
+
+pci:v00001043d000080BB*
+ ID_PRODUCT_FROM_DATABASE=v9180 Magic/T [GeForce4 MX440 AGP 8x 64MB TV-out]
+
+pci:v00001043d000080C5*
+ ID_PRODUCT_FROM_DATABASE=nForce3 chipset motherboard [SK8N]
+
+pci:v00001043d000080DF*
+ ID_PRODUCT_FROM_DATABASE=v9520 Magic/T
+
+pci:v00001043d0000815A*
+ ID_PRODUCT_FROM_DATABASE=A8N-SLI Motherboard nForce4 SATA
+
+pci:v00001043d00008168*
+ ID_PRODUCT_FROM_DATABASE=Realtek PCI-E Gigabit Ethernet Controller (RTL8111B)
+
+pci:v00001043d00008187*
+ ID_PRODUCT_FROM_DATABASE=802.11a/b/g Wireless LAN Card
+
+pci:v00001043d00008188*
+ ID_PRODUCT_FROM_DATABASE=Tiger Hybrid TV Capture Device
+
+pci:v00001043d000081E7*
+ ID_PRODUCT_FROM_DATABASE=Realtek ALC-660 6-channel CODEC
+
+pci:v00001043d000081F4*
+ ID_PRODUCT_FROM_DATABASE=EN7300TC512/TD/128M/A(C262G) [Graphics Card EN7300TC512]
+
+pci:v00001043d00008233*
+ ID_PRODUCT_FROM_DATABASE=EEE-PC 701 Netbook
+
+pci:v00001043d000082CA*
+ ID_PRODUCT_FROM_DATABASE=G96 GeForce 9500 GT
+
+pci:v00001043d000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v00001043d00008383*
+ ID_PRODUCT_FROM_DATABASE=P7P55D Series Motherboard
+
+pci:v00001043d000083A4*
+ ID_PRODUCT_FROM_DATABASE=Motherboard M2N68-AM SE2
+
+pci:v00001043d00008410*
+ ID_PRODUCT_FROM_DATABASE=SBx00 [Azalia]
+
+pci:v00001043d0000843E*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001043d00009602*
+ ID_PRODUCT_FROM_DATABASE=RS880 PCI to PCI bridge (int gfx)
+
+pci:v00001043d00009602sv00001043sd000083A2*
+ ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard
+
+pci:v00001044*
+ ID_VENDOR_FROM_DATABASE=Adaptec (formerly DPT)
+
+pci:v00001044d00001012*
+ ID_PRODUCT_FROM_DATABASE=Domino RAID Engine
+
+pci:v00001044d0000A400*
+ ID_PRODUCT_FROM_DATABASE=SmartCache/Raid I-IV Controller
+
+pci:v00001044d0000A500*
+ ID_PRODUCT_FROM_DATABASE=PCI Bridge
+
+pci:v00001044d0000A501*
+ ID_PRODUCT_FROM_DATABASE=SmartRAID V Controller
+
+pci:v00001044d0000A501sv00001044sd0000C001*
+ ID_PRODUCT_FROM_DATABASE=PM1554U2 Ultra2 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C002*
+ ID_PRODUCT_FROM_DATABASE=PM1654U2 Ultra2 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C003*
+ ID_PRODUCT_FROM_DATABASE=PM1564U3 Ultra3 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C004*
+ ID_PRODUCT_FROM_DATABASE=PM1564U3 Ultra3 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C005*
+ ID_PRODUCT_FROM_DATABASE=PM1554U2 Ultra2 Single Channel (NON ACPI)
+
+pci:v00001044d0000A501sv00001044sd0000C00A*
+ ID_PRODUCT_FROM_DATABASE=PM2554U2 Ultra2 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C00B*
+ ID_PRODUCT_FROM_DATABASE=PM2654U2 Ultra2 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=PM2664U3 Ultra3 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C00D*
+ ID_PRODUCT_FROM_DATABASE=PM2664U3 Ultra3 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C00E*
+ ID_PRODUCT_FROM_DATABASE=PM2554U2 Ultra2 Single Channel (NON ACPI)
+
+pci:v00001044d0000A501sv00001044sd0000C00F*
+ ID_PRODUCT_FROM_DATABASE=PM2654U2 Ultra2 Single Channel (NON ACPI)
+
+pci:v00001044d0000A501sv00001044sd0000C014*
+ ID_PRODUCT_FROM_DATABASE=PM3754U2 Ultra2 Single Channel (NON ACPI)
+
+pci:v00001044d0000A501sv00001044sd0000C015*
+ ID_PRODUCT_FROM_DATABASE=PM3755U2B Ultra2 Single Channel (NON ACPI)
+
+pci:v00001044d0000A501sv00001044sd0000C016*
+ ID_PRODUCT_FROM_DATABASE=PM3755F Fibre Channel (NON ACPI)
+
+pci:v00001044d0000A501sv00001044sd0000C01E*
+ ID_PRODUCT_FROM_DATABASE=PM3757U2 Ultra2 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C01F*
+ ID_PRODUCT_FROM_DATABASE=PM3757U2 Ultra2 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C020*
+ ID_PRODUCT_FROM_DATABASE=PM3767U3 Ultra3 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C021*
+ ID_PRODUCT_FROM_DATABASE=PM3767U3 Ultra3 Quad Channel
+
+pci:v00001044d0000A501sv00001044sd0000C028*
+ ID_PRODUCT_FROM_DATABASE=PM2865U3 Ultra3 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C029*
+ ID_PRODUCT_FROM_DATABASE=PM2865U3 Ultra3 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C02A*
+ ID_PRODUCT_FROM_DATABASE=PM2865F Fibre Channel
+
+pci:v00001044d0000A501sv00001044sd0000C03C*
+ ID_PRODUCT_FROM_DATABASE=2000S Ultra3 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C03D*
+ ID_PRODUCT_FROM_DATABASE=2000S Ultra3 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C03E*
+ ID_PRODUCT_FROM_DATABASE=2000F Fibre Channel
+
+pci:v00001044d0000A501sv00001044sd0000C046*
+ ID_PRODUCT_FROM_DATABASE=3000S Ultra3 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C047*
+ ID_PRODUCT_FROM_DATABASE=3000S Ultra3 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C048*
+ ID_PRODUCT_FROM_DATABASE=3000F Fibre Channel
+
+pci:v00001044d0000A501sv00001044sd0000C050*
+ ID_PRODUCT_FROM_DATABASE=5000S Ultra3 Single Channel
+
+pci:v00001044d0000A501sv00001044sd0000C051*
+ ID_PRODUCT_FROM_DATABASE=5000S Ultra3 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C052*
+ ID_PRODUCT_FROM_DATABASE=5000F Fibre Channel
+
+pci:v00001044d0000A501sv00001044sd0000C05A*
+ ID_PRODUCT_FROM_DATABASE=2400A UDMA Four Channel
+
+pci:v00001044d0000A501sv00001044sd0000C05B*
+ ID_PRODUCT_FROM_DATABASE=2400A UDMA Four Channel DAC
+
+pci:v00001044d0000A501sv00001044sd0000C064*
+ ID_PRODUCT_FROM_DATABASE=3010S Ultra3 Dual Channel
+
+pci:v00001044d0000A501sv00001044sd0000C065*
+ ID_PRODUCT_FROM_DATABASE=3410S Ultra160 Four Channel
+
+pci:v00001044d0000A501sv00001044sd0000C066*
+ ID_PRODUCT_FROM_DATABASE=3010S Fibre Channel
+
+pci:v00001044d0000A511*
+ ID_PRODUCT_FROM_DATABASE=SmartRAID V Controller
+
+pci:v00001044d0000A511sv00001044sd0000C032*
+ ID_PRODUCT_FROM_DATABASE=ASR-2005S I2O Zero Channel
+
+pci:v00001044d0000A511sv00001044sd0000C035*
+ ID_PRODUCT_FROM_DATABASE=ASR-2010S I2O Zero Channel
+
+pci:v00001044d0000C066*
+ ID_PRODUCT_FROM_DATABASE=3010S Ultra3 Dual Channel
+
+pci:v00001045*
+ ID_VENDOR_FROM_DATABASE=OPTi Inc.
+
+pci:v00001045d0000A0F8*
+ ID_PRODUCT_FROM_DATABASE=82C750 [Vendetta] USB Controller
+
+pci:v00001045d0000C101*
+ ID_PRODUCT_FROM_DATABASE=92C264
+
+pci:v00001045d0000C178*
+ ID_PRODUCT_FROM_DATABASE=92C178
+
+pci:v00001045d0000C556*
+ ID_PRODUCT_FROM_DATABASE=82X556 [Viper]
+
+pci:v00001045d0000C557*
+ ID_PRODUCT_FROM_DATABASE=82C557 [Viper-M]
+
+pci:v00001045d0000C558*
+ ID_PRODUCT_FROM_DATABASE=82C558 [Viper-M ISA+IDE]
+
+pci:v00001045d0000C567*
+ ID_PRODUCT_FROM_DATABASE=82C750 [Vendetta], device 0
+
+pci:v00001045d0000C568*
+ ID_PRODUCT_FROM_DATABASE=82C750 [Vendetta], device 1
+
+pci:v00001045d0000C569*
+ ID_PRODUCT_FROM_DATABASE=82C579 [Viper XPress+ Chipset]
+
+pci:v00001045d0000C621*
+ ID_PRODUCT_FROM_DATABASE=82C621 [Viper-M/N+]
+
+pci:v00001045d0000C700*
+ ID_PRODUCT_FROM_DATABASE=82C700 [FireStar]
+
+pci:v00001045d0000C701*
+ ID_PRODUCT_FROM_DATABASE=82C701 [FireStar Plus]
+
+pci:v00001045d0000C814*
+ ID_PRODUCT_FROM_DATABASE=82C814 [Firebridge 1]
+
+pci:v00001045d0000C822*
+ ID_PRODUCT_FROM_DATABASE=82C822
+
+pci:v00001045d0000C824*
+ ID_PRODUCT_FROM_DATABASE=82C824
+
+pci:v00001045d0000C825*
+ ID_PRODUCT_FROM_DATABASE=82C825 [Firebridge 2]
+
+pci:v00001045d0000C832*
+ ID_PRODUCT_FROM_DATABASE=82C832
+
+pci:v00001045d0000C861*
+ ID_PRODUCT_FROM_DATABASE=82C861
+
+pci:v00001045d0000C881*
+ ID_PRODUCT_FROM_DATABASE=82C881 [FireLink] 1394 OHCI Link Controller
+
+pci:v00001045d0000C895*
+ ID_PRODUCT_FROM_DATABASE=82C895
+
+pci:v00001045d0000C935*
+ ID_PRODUCT_FROM_DATABASE=EV1935 ECTIVA MachOne PCIAudio
+
+pci:v00001045d0000D568*
+ ID_PRODUCT_FROM_DATABASE=82C825 [Firebridge 2]
+
+pci:v00001045d0000D721*
+ ID_PRODUCT_FROM_DATABASE=IDE [FireStar]
+
+pci:v00001046*
+ ID_VENDOR_FROM_DATABASE=IPC Corporation, Ltd.
+
+pci:v00001047*
+ ID_VENDOR_FROM_DATABASE=Genoa Systems Corp
+
+pci:v00001048*
+ ID_VENDOR_FROM_DATABASE=Elsa AG
+
+pci:v00001048d00000C60*
+ ID_PRODUCT_FROM_DATABASE=Gladiac MX
+
+pci:v00001048d00000D22*
+ ID_PRODUCT_FROM_DATABASE=Quadro4 900XGL [ELSA GLoria4 900XGL]
+
+pci:v00001048d00001000*
+ ID_PRODUCT_FROM_DATABASE=QuickStep 1000
+
+pci:v00001048d00003000*
+ ID_PRODUCT_FROM_DATABASE=QuickStep 3000
+
+pci:v00001048d00008901*
+ ID_PRODUCT_FROM_DATABASE=Gloria XL
+
+pci:v00001048d00008901sv00001048sd00000935*
+ ID_PRODUCT_FROM_DATABASE=GLoria XL (Virge)
+
+pci:v00001049*
+ ID_VENDOR_FROM_DATABASE=Fountain Technologies, Inc.
+
+pci:v0000104A*
+ ID_VENDOR_FROM_DATABASE=STMicroelectronics
+
+pci:v0000104Ad00000000*
+ ID_PRODUCT_FROM_DATABASE=STLS2F Host Bridge
+
+pci:v0000104Ad00000008*
+ ID_PRODUCT_FROM_DATABASE=STG 2000X
+
+pci:v0000104Ad00000009*
+ ID_PRODUCT_FROM_DATABASE=STG 1764X
+
+pci:v0000104Ad00000010*
+ ID_PRODUCT_FROM_DATABASE=STG4000 [3D Prophet Kyro Series]
+
+pci:v0000104Ad00000010sv00001681sd0000C069*
+ ID_PRODUCT_FROM_DATABASE=3D Prophet 4000XT
+
+pci:v0000104Ad00000201*
+ ID_PRODUCT_FROM_DATABASE=STPC Vega Northbridge
+
+pci:v0000104Ad00000209*
+ ID_PRODUCT_FROM_DATABASE=STPC Consumer/Industrial North- and Southbridge
+
+pci:v0000104Ad0000020A*
+ ID_PRODUCT_FROM_DATABASE=STPC Atlas/ConsumerS/Consumer IIA Northbridge
+
+pci:v0000104Ad0000020B*
+ ID_PRODUCT_FROM_DATABASE=STPC Consumer II ISA Bridge
+
+pci:v0000104Ad00000210*
+ ID_PRODUCT_FROM_DATABASE=STPC Atlas ISA Bridge
+
+pci:v0000104Ad0000021A*
+ ID_PRODUCT_FROM_DATABASE=STPC Consumer S Southbridge
+
+pci:v0000104Ad0000021B*
+ ID_PRODUCT_FROM_DATABASE=STPC Consumer IIA Southbridge
+
+pci:v0000104Ad00000220*
+ ID_PRODUCT_FROM_DATABASE=STPC Industrial PCI to PCCard bridge
+
+pci:v0000104Ad00000228*
+ ID_PRODUCT_FROM_DATABASE=STPC Atlas IDE
+
+pci:v0000104Ad00000229*
+ ID_PRODUCT_FROM_DATABASE=STPC Vega IDE
+
+pci:v0000104Ad00000230*
+ ID_PRODUCT_FROM_DATABASE=STPC Atlas/Vega OHCI USB Controller
+
+pci:v0000104Ad00000238*
+ ID_PRODUCT_FROM_DATABASE=STPC Vega LAN
+
+pci:v0000104Ad00000500*
+ ID_PRODUCT_FROM_DATABASE=ST70137 [Unicorn] ADSL DMT Transceiver
+
+pci:v0000104Ad00000500sv0000104Asd00000500*
+ ID_PRODUCT_FROM_DATABASE=BeWAN ADSL PCI st
+
+pci:v0000104Ad00000564*
+ ID_PRODUCT_FROM_DATABASE=STPC Client Northbridge
+
+pci:v0000104Ad00000981*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v0000104Ad00001746*
+ ID_PRODUCT_FROM_DATABASE=STG 1764X
+
+pci:v0000104Ad00002774*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v0000104Ad00003520*
+ ID_PRODUCT_FROM_DATABASE=MPEG-II decoder card
+
+pci:v0000104Ad000055CC*
+ ID_PRODUCT_FROM_DATABASE=STPC Client Southbridge
+
+pci:v0000104B*
+ ID_VENDOR_FROM_DATABASE=BusLogic
+
+pci:v0000104Bd00000140*
+ ID_PRODUCT_FROM_DATABASE=BT-946C (old) [multimaster  01]
+
+pci:v0000104Bd00001040*
+ ID_PRODUCT_FROM_DATABASE=BT-946C (BA80C30) [MultiMaster 10]
+
+pci:v0000104Bd00008130*
+ ID_PRODUCT_FROM_DATABASE=Flashpoint LT
+
+pci:v0000104C*
+ ID_VENDOR_FROM_DATABASE=Texas Instruments
+
+pci:v0000104Cd00000500*
+ ID_PRODUCT_FROM_DATABASE=100 MBit LAN Controller
+
+pci:v0000104Cd00000508*
+ ID_PRODUCT_FROM_DATABASE=TMS380C2X Compressor Interface
+
+pci:v0000104Cd00001000*
+ ID_PRODUCT_FROM_DATABASE=Eagle i/f AS
+
+pci:v0000104Cd0000104C*
+ ID_PRODUCT_FROM_DATABASE=PCI1510 PC card Cardbus Controller
+
+pci:v0000104Cd00003D04*
+ ID_PRODUCT_FROM_DATABASE=TVP4010 [Permedia]
+
+pci:v0000104Cd00003D07*
+ ID_PRODUCT_FROM_DATABASE=TVP4020 [Permedia 2]
+
+pci:v0000104Cd00003D07sv00001011sd00004D10*
+ ID_PRODUCT_FROM_DATABASE=Comet
+
+pci:v0000104Cd00003D07sv00001040sd0000000F*
+ ID_PRODUCT_FROM_DATABASE=AccelStar II
+
+pci:v0000104Cd00003D07sv00001040sd00000011*
+ ID_PRODUCT_FROM_DATABASE=AccelStar II
+
+pci:v0000104Cd00003D07sv00001048sd00000A31*
+ ID_PRODUCT_FROM_DATABASE=WINNER 2000
+
+pci:v0000104Cd00003D07sv00001048sd00000A32*
+ ID_PRODUCT_FROM_DATABASE=GLoria Synergy
+
+pci:v0000104Cd00003D07sv00001048sd00000A34*
+ ID_PRODUCT_FROM_DATABASE=GLoria Synergy
+
+pci:v0000104Cd00003D07sv00001048sd00000A35*
+ ID_PRODUCT_FROM_DATABASE=GLoria Synergy
+
+pci:v0000104Cd00003D07sv00001048sd00000A36*
+ ID_PRODUCT_FROM_DATABASE=GLoria Synergy
+
+pci:v0000104Cd00003D07sv00001048sd00000A43*
+ ID_PRODUCT_FROM_DATABASE=GLoria Synergy
+
+pci:v0000104Cd00003D07sv00001048sd00000A44*
+ ID_PRODUCT_FROM_DATABASE=GLoria Synergy
+
+pci:v0000104Cd00003D07sv0000107Dsd00002633*
+ ID_PRODUCT_FROM_DATABASE=WinFast 3D L2300
+
+pci:v0000104Cd00003D07sv00001092sd00000126*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000127*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000136*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000141*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000146*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000148*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000149*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000152*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000154*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000155*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000156*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001092sd00000157*
+ ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO
+
+pci:v0000104Cd00003D07sv00001097sd00003D01*
+ ID_PRODUCT_FROM_DATABASE=Jeronimo Pro
+
+pci:v0000104Cd00003D07sv00001102sd0000100F*
+ ID_PRODUCT_FROM_DATABASE=Graphics Blaster Extreme
+
+pci:v0000104Cd00003D07sv00003D3Dsd00000100*
+ ID_PRODUCT_FROM_DATABASE=Reference Permedia 2 3D
+
+pci:v0000104Cd00008000*
+ ID_PRODUCT_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
+
+pci:v0000104Cd00008000sv0000105Esd00008003*
+ ID_PRODUCT_FROM_DATABASE=FireBoard200
+
+pci:v0000104Cd00008000sv00001443sd00008003*
+ ID_PRODUCT_FROM_DATABASE=FireBoard200
+
+pci:v0000104Cd00008000sv00001443sd00008005*
+ ID_PRODUCT_FROM_DATABASE=FireBoard400
+
+pci:v0000104Cd00008000sv00001443sd00008006*
+ ID_PRODUCT_FROM_DATABASE=FireBoard400
+
+pci:v0000104Cd00008000sv0000E4BFsd00001010*
+ ID_PRODUCT_FROM_DATABASE=CF1-1-SNARE
+
+pci:v0000104Cd00008000sv0000E4BFsd00001020*
+ ID_PRODUCT_FROM_DATABASE=CF1-2-SNARE
+
+pci:v0000104Cd00008000sv0000E4BFsd00001040*
+ ID_PRODUCT_FROM_DATABASE=FireCompact400
+
+pci:v0000104Cd00008009*
+ ID_PRODUCT_FROM_DATABASE=TSB12LV22 IEEE-1394 Controller
+
+pci:v0000104Cd00008009sv0000104Dsd00008032*
+ ID_PRODUCT_FROM_DATABASE=8032 OHCI i.LINK (IEEE 1394) Controller
+
+pci:v0000104Cd00008009sv00001443sd00008010*
+ ID_PRODUCT_FROM_DATABASE=FireBoard400-OHCI
+
+pci:v0000104Cd00008017*
+ ID_PRODUCT_FROM_DATABASE=PCI4410 FireWire Controller
+
+pci:v0000104Cd00008019*
+ ID_PRODUCT_FROM_DATABASE=TSB12LV23 IEEE-1394 Controller
+
+pci:v0000104Cd00008019sv000011BDsd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Studio DV500-1394
+
+pci:v0000104Cd00008019sv000011BDsd0000000E*
+ ID_PRODUCT_FROM_DATABASE=Studio DV
+
+pci:v0000104Cd00008019sv00001443sd00008010*
+ ID_PRODUCT_FROM_DATABASE=FireBoard400-OHCI
+
+pci:v0000104Cd00008019sv0000E4BFsd00001010*
+ ID_PRODUCT_FROM_DATABASE=CF2-1-CYMBAL
+
+pci:v0000104Cd00008020*
+ ID_PRODUCT_FROM_DATABASE=TSB12LV26 IEEE-1394 Controller (Link)
+
+pci:v0000104Cd00008020sv00001028sd000000D8*
+ ID_PRODUCT_FROM_DATABASE=Precision 530
+
+pci:v0000104Cd00008020sv0000104Dsd000080E2*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCV-J200
+
+pci:v0000104Cd00008020sv000011BDsd0000000F*
+ ID_PRODUCT_FROM_DATABASE=Studio DV500-1394
+
+pci:v0000104Cd00008020sv000011BDsd0000001C*
+ ID_PRODUCT_FROM_DATABASE=Excalibur 4.1
+
+pci:v0000104Cd00008020sv00001443sd00008010*
+ ID_PRODUCT_FROM_DATABASE=FireBoard400-OHCI
+
+pci:v0000104Cd00008021*
+ ID_PRODUCT_FROM_DATABASE=TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated)
+
+pci:v0000104Cd00008021sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v0000104Cd00008021sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v0000104Cd00008022*
+ ID_PRODUCT_FROM_DATABASE=TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx]
+
+pci:v0000104Cd00008022sv0000104Csd00008023*
+ ID_PRODUCT_FROM_DATABASE=TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link)
+
+pci:v0000104Cd00008023*
+ ID_PRODUCT_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx]
+
+pci:v0000104Cd00008023sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v0000104Cd00008023sv00001043sd0000808B*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E Mainboard
+
+pci:v0000104Cd00008023sv00001043sd0000815B*
+ ID_PRODUCT_FROM_DATABASE=P5W DH Deluxe Motherboard
+
+pci:v0000104Cd00008023sv00001443sd00008023*
+ ID_PRODUCT_FROM_DATABASE=FireCard400
+
+pci:v0000104Cd00008023sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v0000104Cd00008024*
+ ID_PRODUCT_FROM_DATABASE=TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link)
+
+pci:v0000104Cd00008024sv0000107Dsd00006620*
+ ID_PRODUCT_FROM_DATABASE=Winfast DV2000 FireWire Controller
+
+pci:v0000104Cd00008024sv00001443sd00008024*
+ ID_PRODUCT_FROM_DATABASE=FireBoard Blue
+
+pci:v0000104Cd00008024sv00001458sd00001000*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v0000104Cd00008025*
+ ID_PRODUCT_FROM_DATABASE=TSB82AA2 IEEE-1394b Link Layer Controller
+
+pci:v0000104Cd00008025sv00001043sd0000813C*
+ ID_PRODUCT_FROM_DATABASE=P5P series mainboard
+
+pci:v0000104Cd00008025sv00001443sd00008025*
+ ID_PRODUCT_FROM_DATABASE=FireBoard800
+
+pci:v0000104Cd00008025sv00001458sd00001000*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v0000104Cd00008025sv00001546sd00008025*
+ ID_PRODUCT_FROM_DATABASE=FWB-PCI01
+
+pci:v0000104Cd00008025sv000017FCsd00008025*
+ ID_PRODUCT_FROM_DATABASE=GIC3800
+
+pci:v0000104Cd00008026*
+ ID_PRODUCT_FROM_DATABASE=TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link)
+
+pci:v0000104Cd00008026sv00001025sd00000035*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 660
+
+pci:v0000104Cd00008026sv00001025sd0000003C*
+ ID_PRODUCT_FROM_DATABASE=Aspire 2001WLCi (Compaq CL50 motherboard)
+
+pci:v0000104Cd00008026sv0000103Csd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v0000104Cd00008026sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v0000104Cd00008026sv00001043sd0000808D*
+ ID_PRODUCT_FROM_DATABASE=A7V333 mainboard.
+
+pci:v0000104Cd00008027*
+ ID_PRODUCT_FROM_DATABASE=PCI4451 IEEE-1394 Controller
+
+pci:v0000104Cd00008027sv00001028sd000000E6*
+ ID_PRODUCT_FROM_DATABASE=PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
+
+pci:v0000104Cd00008029*
+ ID_PRODUCT_FROM_DATABASE=PCI4510 IEEE-1394 Controller
+
+pci:v0000104Cd00008029sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v0000104Cd00008029sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v0000104Cd00008029sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2900
+
+pci:v0000104Cd0000802B*
+ ID_PRODUCT_FROM_DATABASE=PCI7410,7510,7610 OHCI-Lynx Controller
+
+pci:v0000104Cd0000802Bsv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v0000104Cd0000802Bsv00001028sd0000014E*
+ ID_PRODUCT_FROM_DATABASE=PCI7410,7510,7610 OHCI-Lynx Controller (Latitude D800)
+
+pci:v0000104Cd0000802E*
+ ID_PRODUCT_FROM_DATABASE=PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller
+
+pci:v0000104Cd0000802Esv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v0000104Cd00008031*
+ ID_PRODUCT_FROM_DATABASE=PCIxx21/x515 Cardbus Controller
+
+pci:v0000104Cd00008031sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi
+
+pci:v0000104Cd00008031sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v0000104Cd00008031sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v0000104Cd00008031sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v0000104Cd00008032*
+ ID_PRODUCT_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller
+
+pci:v0000104Cd00008032sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi
+
+pci:v0000104Cd00008032sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v0000104Cd00008032sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v0000104Cd00008032sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v0000104Cd00008033*
+ ID_PRODUCT_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller
+
+pci:v0000104Cd00008033sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi
+
+pci:v0000104Cd00008033sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v0000104Cd00008033sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v0000104Cd00008033sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v0000104Cd00008034*
+ ID_PRODUCT_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller
+
+pci:v0000104Cd00008034sv00001025sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi
+
+pci:v0000104Cd00008034sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v0000104Cd00008034sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v0000104Cd00008034sv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v0000104Cd00008035*
+ ID_PRODUCT_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller
+
+pci:v0000104Cd00008035sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v0000104Cd00008035sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v0000104Cd00008036*
+ ID_PRODUCT_FROM_DATABASE=PCI6515 Cardbus Controller
+
+pci:v0000104Cd00008038*
+ ID_PRODUCT_FROM_DATABASE=PCI6515 SmartCard Controller
+
+pci:v0000104Cd00008039*
+ ID_PRODUCT_FROM_DATABASE=PCIxx12 Cardbus Controller
+
+pci:v0000104Cd00008039sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v0000104Cd00008039sv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v0000104Cd00008039sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v0000104Cd00008039sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v0000104Cd0000803A*
+ ID_PRODUCT_FROM_DATABASE=PCIxx12 OHCI Compliant IEEE 1394 Host Controller
+
+pci:v0000104Cd0000803Asv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=nx9420
+
+pci:v0000104Cd0000803Asv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v0000104Cd0000803Asv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v0000104Cd0000803Asv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v0000104Cd0000803B*
+ ID_PRODUCT_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD)
+
+pci:v0000104Cd0000803Bsv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=nx9420
+
+pci:v0000104Cd0000803Bsv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v0000104Cd0000803Bsv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v0000104Cd0000803C*
+ ID_PRODUCT_FROM_DATABASE=PCIxx12 SDA Standard Compliant SD Host Controller
+
+pci:v0000104Cd0000803Csv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=nx9420
+
+pci:v0000104Cd0000803Csv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v0000104Cd0000803D*
+ ID_PRODUCT_FROM_DATABASE=PCIxx12 GemCore based SmartCard controller
+
+pci:v0000104Cd0000803Dsv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v0000104Cd0000803Dsv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v0000104Cd0000803Dsv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=nc8430
+
+pci:v0000104Cd0000803Dsv0000103Csd000030AA*
+ ID_PRODUCT_FROM_DATABASE=nc6310
+
+pci:v0000104Cd00008101*
+ ID_PRODUCT_FROM_DATABASE=TSB43DB42 IEEE-1394a-2000 Controller (PHY/Link)
+
+pci:v0000104Cd00008201*
+ ID_PRODUCT_FROM_DATABASE=PCI1620 Firmware Loading Function
+
+pci:v0000104Cd00008204*
+ ID_PRODUCT_FROM_DATABASE=PCI7410,7510,7610 PCI Firmware Loading Function
+
+pci:v0000104Cd00008204sv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v0000104Cd00008204sv00001028sd0000014E*
+ ID_PRODUCT_FROM_DATABASE=Latitude D800
+
+pci:v0000104Cd00008231*
+ ID_PRODUCT_FROM_DATABASE=XIO2000(A)/XIO2200A PCI Express-to-PCI Bridge
+
+pci:v0000104Cd00008231sv00005678sd00001234*
+ ID_PRODUCT_FROM_DATABASE=DC-1394 PCIe
+
+pci:v0000104Cd00008232*
+ ID_PRODUCT_FROM_DATABASE=XIO3130 PCI Express Switch (Upstream)
+
+pci:v0000104Cd00008233*
+ ID_PRODUCT_FROM_DATABASE=XIO3130 PCI Express Switch (Downstream)
+
+pci:v0000104Cd00008235*
+ ID_PRODUCT_FROM_DATABASE=XIO2200A IEEE-1394a-2000 Controller (PHY/Link)
+
+pci:v0000104Cd00008235sv00005678sd00001234*
+ ID_PRODUCT_FROM_DATABASE=DC-1394 PCIe
+
+pci:v0000104Cd0000823E*
+ ID_PRODUCT_FROM_DATABASE=XIO2213A/B/XIO2221 PCI Express to PCI Bridge [Cheetah Express]
+
+pci:v0000104Cd0000823F*
+ ID_PRODUCT_FROM_DATABASE=XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express]
+
+pci:v0000104Cd0000823Fsv00001546sd0000803C*
+ ID_PRODUCT_FROM_DATABASE=FWB-PCIE1X11B
+
+pci:v0000104Cd00008240*
+ ID_PRODUCT_FROM_DATABASE=XIO2001 PCI Express-to-PCI Bridge
+
+pci:v0000104Cd00008241*
+ ID_PRODUCT_FROM_DATABASE=TUSB73x0 SuperSpeed USB 3.0 xHCI Host Controller
+
+pci:v0000104Cd00008400*
+ ID_PRODUCT_FROM_DATABASE=ACX 100 22Mbps Wireless Interface
+
+pci:v0000104Cd00008400sv00001186sd00003B00*
+ ID_PRODUCT_FROM_DATABASE=DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus]
+
+pci:v0000104Cd00008400sv00001186sd00003B01*
+ ID_PRODUCT_FROM_DATABASE=DWL-520+ 22Mbps PCI Wireless Adapter
+
+pci:v0000104Cd00008400sv00001395sd00002201*
+ ID_PRODUCT_FROM_DATABASE=WL22-PC
+
+pci:v0000104Cd00008400sv000016ABsd00008501*
+ ID_PRODUCT_FROM_DATABASE=WL-8305 IEEE802.11b+ Wireless LAN PCI Adapter
+
+pci:v0000104Cd00008401*
+ ID_PRODUCT_FROM_DATABASE=ACX 100 22Mbps Wireless Interface
+
+pci:v0000104Cd00009000*
+ ID_PRODUCT_FROM_DATABASE=Wireless Interface (of unknown type)
+
+pci:v0000104Cd00009065*
+ ID_PRODUCT_FROM_DATABASE=TMS320DM642
+
+pci:v0000104Cd00009066*
+ ID_PRODUCT_FROM_DATABASE=ACX 111 54Mbps Wireless Interface
+
+pci:v0000104Cd00009066sv00000308sd00003404*
+ ID_PRODUCT_FROM_DATABASE=G-102 v1 802.11g Wireless Cardbus Adapter
+
+pci:v0000104Cd00009066sv00000308sd00003406*
+ ID_PRODUCT_FROM_DATABASE=G-162 v2 802.11g Wireless Cardbus Adapter
+
+pci:v0000104Cd00009066sv0000104Csd00009066*
+ ID_PRODUCT_FROM_DATABASE=WL212 Sitecom Wireless Network PCI-Card 100M (Version 1)
+
+pci:v0000104Cd00009066sv0000104Csd00009096*
+ ID_PRODUCT_FROM_DATABASE=Trendnet TEW-412PC Wireless PCI Adapter (Version A)
+
+pci:v0000104Cd00009066sv00001186sd00003B04*
+ ID_PRODUCT_FROM_DATABASE=DWL-G520+ Wireless PCI Adapter
+
+pci:v0000104Cd00009066sv00001186sd00003B05*
+ ID_PRODUCT_FROM_DATABASE=DWL-G650+ AirPlusG+ CardBus Wireless LAN
+
+pci:v0000104Cd00009066sv00001186sd00003B08*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.B1)
+
+pci:v0000104Cd00009066sv00001385sd00004C00*
+ ID_PRODUCT_FROM_DATABASE=WG311v2 802.11g Wireless PCI Adapter
+
+pci:v0000104Cd00009066sv000013D1sd0000ABA0*
+ ID_PRODUCT_FROM_DATABASE=SWLMP-54108 108Mbps Wireless mini PCI card 802.11g+
+
+pci:v0000104Cd00009066sv000014EAsd0000AB07*
+ ID_PRODUCT_FROM_DATABASE=GW-NS54GM Wireless Cardbus Adapter
+
+pci:v0000104Cd00009066sv000016ECsd0000010D*
+ ID_PRODUCT_FROM_DATABASE=USR5416 802.11g Wireless Turbo PCI Adapter
+
+pci:v0000104Cd00009066sv000016ECsd0000010E*
+ ID_PRODUCT_FROM_DATABASE=USR5410 802.11g Wireless Cardbus Adapter
+
+pci:v0000104Cd00009066sv00001737sd00000033*
+ ID_PRODUCT_FROM_DATABASE=WPC54G v2 802.11g Wireless-G Notebook Adapter
+
+pci:v0000104Cd00009066sv000017CFsd00000032*
+ ID_PRODUCT_FROM_DATABASE=G-162 v1 802.11g Wireless Cardbus Adapter
+
+pci:v0000104Cd00009066sv000017CFsd00000033*
+ ID_PRODUCT_FROM_DATABASE=Z-Com XG650 Wireless miniPCI 802.11b/g
+
+pci:v0000104Cd00009066sv0000187Esd0000340B*
+ ID_PRODUCT_FROM_DATABASE=G-302 v2 802.11g Wireless PCI Adapter
+
+pci:v0000104Cd00009066sv0000187Esd0000340C*
+ ID_PRODUCT_FROM_DATABASE=G-360 v2 802.11g Wireless PCI Adapter
+
+pci:v0000104Cd0000A001*
+ ID_PRODUCT_FROM_DATABASE=TDC1570
+
+pci:v0000104Cd0000A100*
+ ID_PRODUCT_FROM_DATABASE=TDC1561
+
+pci:v0000104Cd0000A102*
+ ID_PRODUCT_FROM_DATABASE=TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f
+
+pci:v0000104Cd0000A106*
+ ID_PRODUCT_FROM_DATABASE=TMS320C6414 TMS320C6415 TMS320C6416
+
+pci:v0000104Cd0000A106sv0000175Csd00005000*
+ ID_PRODUCT_FROM_DATABASE=ASI50xx Audio Adapter
+
+pci:v0000104Cd0000A106sv0000175Csd00006400*
+ ID_PRODUCT_FROM_DATABASE=ASI6400 Cobranet series
+
+pci:v0000104Cd0000A106sv0000175Csd00008700*
+ ID_PRODUCT_FROM_DATABASE=ASI87xx Radio Tuner card
+
+pci:v0000104Cd0000AC10*
+ ID_PRODUCT_FROM_DATABASE=PCI1050
+
+pci:v0000104Cd0000AC11*
+ ID_PRODUCT_FROM_DATABASE=PCI1053
+
+pci:v0000104Cd0000AC12*
+ ID_PRODUCT_FROM_DATABASE=PCI1130
+
+pci:v0000104Cd0000AC13*
+ ID_PRODUCT_FROM_DATABASE=PCI1031
+
+pci:v0000104Cd0000AC15*
+ ID_PRODUCT_FROM_DATABASE=PCI1131
+
+pci:v0000104Cd0000AC16*
+ ID_PRODUCT_FROM_DATABASE=PCI1250
+
+pci:v0000104Cd0000AC16sv00001014sd00000092*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 600
+
+pci:v0000104Cd0000AC17*
+ ID_PRODUCT_FROM_DATABASE=PCI1220
+
+pci:v0000104Cd0000AC18*
+ ID_PRODUCT_FROM_DATABASE=PCI1260
+
+pci:v0000104Cd0000AC19*
+ ID_PRODUCT_FROM_DATABASE=PCI1221
+
+pci:v0000104Cd0000AC1A*
+ ID_PRODUCT_FROM_DATABASE=PCI1210
+
+pci:v0000104Cd0000AC1B*
+ ID_PRODUCT_FROM_DATABASE=PCI1450
+
+pci:v0000104Cd0000AC1Bsv00000E11sd0000B113*
+ ID_PRODUCT_FROM_DATABASE=Armada M700
+
+pci:v0000104Cd0000AC1Bsv00001014sd00000130*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 600X/A21m/T20/T22
+
+pci:v0000104Cd0000AC1C*
+ ID_PRODUCT_FROM_DATABASE=PCI1225
+
+pci:v0000104Cd0000AC1Csv00000E11sd0000B121*
+ ID_PRODUCT_FROM_DATABASE=Armada E500
+
+pci:v0000104Cd0000AC1Csv00001028sd00000088*
+ ID_PRODUCT_FROM_DATABASE=Latitude CPi A400XT
+
+pci:v0000104Cd0000AC1D*
+ ID_PRODUCT_FROM_DATABASE=PCI1251A
+
+pci:v0000104Cd0000AC1E*
+ ID_PRODUCT_FROM_DATABASE=PCI1211
+
+pci:v0000104Cd0000AC1F*
+ ID_PRODUCT_FROM_DATABASE=PCI1251B
+
+pci:v0000104Cd0000AC20*
+ ID_PRODUCT_FROM_DATABASE=TI 2030
+
+pci:v0000104Cd0000AC21*
+ ID_PRODUCT_FROM_DATABASE=PCI2031
+
+pci:v0000104Cd0000AC22*
+ ID_PRODUCT_FROM_DATABASE=PCI2032 PCI Docking Bridge
+
+pci:v0000104Cd0000AC23*
+ ID_PRODUCT_FROM_DATABASE=PCI2250 PCI-to-PCI Bridge
+
+pci:v0000104Cd0000AC28*
+ ID_PRODUCT_FROM_DATABASE=PCI2050 PCI-to-PCI Bridge
+
+pci:v0000104Cd0000AC2C*
+ ID_PRODUCT_FROM_DATABASE=PCI2060 PCI-to-PCI Bridge
+
+pci:v0000104Cd0000AC30*
+ ID_PRODUCT_FROM_DATABASE=PCI1260 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC40*
+ ID_PRODUCT_FROM_DATABASE=PCI4450 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC41*
+ ID_PRODUCT_FROM_DATABASE=PCI4410 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC42*
+ ID_PRODUCT_FROM_DATABASE=PCI4451 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC42sv00001028sd000000E6*
+ ID_PRODUCT_FROM_DATABASE=PCI4451 PC card CardBus Controller (Inspiron 8100)
+
+pci:v0000104Cd0000AC44*
+ ID_PRODUCT_FROM_DATABASE=PCI4510 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC44sv00001028sd00000149*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5100
+
+pci:v0000104Cd0000AC44sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v0000104Cd0000AC44sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v0000104Cd0000AC44sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v0000104Cd0000AC46*
+ ID_PRODUCT_FROM_DATABASE=PCI4520 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC46sv00001014sd00000552*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad
+
+pci:v0000104Cd0000AC47*
+ ID_PRODUCT_FROM_DATABASE=PCI7510 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC47sv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v0000104Cd0000AC47sv00001028sd0000013F*
+ ID_PRODUCT_FROM_DATABASE=Precision M60
+
+pci:v0000104Cd0000AC47sv00001028sd0000014E*
+ ID_PRODUCT_FROM_DATABASE=Latitude D800
+
+pci:v0000104Cd0000AC48*
+ ID_PRODUCT_FROM_DATABASE=PCI7610 PC Card Cardbus Controller
+
+pci:v0000104Cd0000AC49*
+ ID_PRODUCT_FROM_DATABASE=PCI7410 PC Card Cardbus Controller
+
+pci:v0000104Cd0000AC4A*
+ ID_PRODUCT_FROM_DATABASE=PCI7510,7610 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC4Asv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v0000104Cd0000AC4Asv00001028sd0000014E*
+ ID_PRODUCT_FROM_DATABASE=Latitude D800
+
+pci:v0000104Cd0000AC4B*
+ ID_PRODUCT_FROM_DATABASE=PCI7610 SD/MMC controller
+
+pci:v0000104Cd0000AC4C*
+ ID_PRODUCT_FROM_DATABASE=PCI7610 Memory Stick controller
+
+pci:v0000104Cd0000AC50*
+ ID_PRODUCT_FROM_DATABASE=PCI1410 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC51*
+ ID_PRODUCT_FROM_DATABASE=PCI1420 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC51sv00000E11sd0000004E*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v0000104Cd0000AC51sv00001014sd00000148*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A20m
+
+pci:v0000104Cd0000AC51sv00001014sd0000023B*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T23
+
+pci:v0000104Cd0000AC51sv00001028sd000000B1*
+ ID_PRODUCT_FROM_DATABASE=Latitude C600
+
+pci:v0000104Cd0000AC51sv00001028sd0000012A*
+ ID_PRODUCT_FROM_DATABASE=Latitude C640
+
+pci:v0000104Cd0000AC51sv00001033sd000080CD*
+ ID_PRODUCT_FROM_DATABASE=Versa Note VXi
+
+pci:v0000104Cd0000AC51sv000010CFsd00001095*
+ ID_PRODUCT_FROM_DATABASE=Lifebook S-4510/C6155
+
+pci:v0000104Cd0000AC51sv0000E4BFsd00001000*
+ ID_PRODUCT_FROM_DATABASE=CP2-2-HIPHOP
+
+pci:v0000104Cd0000AC52*
+ ID_PRODUCT_FROM_DATABASE=PCI1451 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC53*
+ ID_PRODUCT_FROM_DATABASE=PCI1421 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC54*
+ ID_PRODUCT_FROM_DATABASE=PCI1620 PC Card Controller
+
+pci:v0000104Cd0000AC54sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v0000104Cd0000AC55*
+ ID_PRODUCT_FROM_DATABASE=PCI1520 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC55sv00001014sd00000512*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T30/T40
+
+pci:v0000104Cd0000AC55sv0000103Csd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v0000104Cd0000AC56*
+ ID_PRODUCT_FROM_DATABASE=PCI1510 PC card Cardbus Controller
+
+pci:v0000104Cd0000AC56sv00001014sd00000512*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R50e
+
+pci:v0000104Cd0000AC56sv00001014sd00000528*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v0000104Cd0000AC56sv000017AAsd00002012*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v0000104Cd0000AC60*
+ ID_PRODUCT_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller
+
+pci:v0000104Cd0000AC60sv0000175Csd00005100*
+ ID_PRODUCT_FROM_DATABASE=ASI51xx Audio Adapter
+
+pci:v0000104Cd0000AC60sv0000175Csd00006100*
+ ID_PRODUCT_FROM_DATABASE=ASI61xx Audio Adapter
+
+pci:v0000104Cd0000AC60sv0000175Csd00006200*
+ ID_PRODUCT_FROM_DATABASE=ASI62xx Audio Adapter
+
+pci:v0000104Cd0000AC60sv0000175Csd00008800*
+ ID_PRODUCT_FROM_DATABASE=ASI88xx Audio Adapter
+
+pci:v0000104Cd0000AC60sv0000186Fsd00003001*
+ ID_PRODUCT_FROM_DATABASE=WR-G303 PCI radio receiver
+
+pci:v0000104Cd0000AC60sv0000186Fsd00003005*
+ ID_PRODUCT_FROM_DATABASE=WR-G305 PCI radio receiver
+
+pci:v0000104Cd0000AC60sv0000186Fsd00003101*
+ ID_PRODUCT_FROM_DATABASE=WR-G313 PCI radio receiver
+
+pci:v0000104Cd0000AC60sv0000186Fsd00003105*
+ ID_PRODUCT_FROM_DATABASE=WR-G315 PCI radio receiver
+
+pci:v0000104Cd0000AC8D*
+ ID_PRODUCT_FROM_DATABASE=PCI 7620
+
+pci:v0000104Cd0000AC8E*
+ ID_PRODUCT_FROM_DATABASE=PCI7420 CardBus Controller
+
+pci:v0000104Cd0000AC8Esv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v0000104Cd0000AC8F*
+ ID_PRODUCT_FROM_DATABASE=PCI7420/7620 Combo CardBus, 1394a-2000 OHCI and SD/MS-Pro Controller
+
+pci:v0000104Cd0000AC8Fsv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v0000104Cd0000B001*
+ ID_PRODUCT_FROM_DATABASE=TMS320C6424
+
+pci:v0000104Cd0000FE00*
+ ID_PRODUCT_FROM_DATABASE=FireWire Host Controller
+
+pci:v0000104Cd0000FE03*
+ ID_PRODUCT_FROM_DATABASE=12C01A FireWire Host Controller
+
+pci:v0000104D*
+ ID_VENDOR_FROM_DATABASE=Sony Corporation
+
+pci:v0000104Dd00008004*
+ ID_PRODUCT_FROM_DATABASE=DTL-H2500 [Playstation development board]
+
+pci:v0000104Dd00008009*
+ ID_PRODUCT_FROM_DATABASE=CXD1947Q i.LINK Controller
+
+pci:v0000104Dd00008039*
+ ID_PRODUCT_FROM_DATABASE=CXD3222 i.LINK Controller
+
+pci:v0000104Dd00008056*
+ ID_PRODUCT_FROM_DATABASE=Rockwell HCF 56K modem
+
+pci:v0000104Dd0000808A*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Controller
+
+pci:v0000104Dd000081CE*
+ ID_PRODUCT_FROM_DATABASE=SxS Pro memory card
+
+pci:v0000104Dd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v0000104E*
+ ID_VENDOR_FROM_DATABASE=Oak Technology, Inc
+
+pci:v0000104Ed00000017*
+ ID_PRODUCT_FROM_DATABASE=OTI-64017
+
+pci:v0000104Ed00000107*
+ ID_PRODUCT_FROM_DATABASE=OTI-107 [Spitfire]
+
+pci:v0000104Ed00000109*
+ ID_PRODUCT_FROM_DATABASE=Video Adapter
+
+pci:v0000104Ed00000111*
+ ID_PRODUCT_FROM_DATABASE=OTI-64111 [Spitfire]
+
+pci:v0000104Ed00000217*
+ ID_PRODUCT_FROM_DATABASE=OTI-64217
+
+pci:v0000104Ed00000317*
+ ID_PRODUCT_FROM_DATABASE=OTI-64317
+
+pci:v0000104F*
+ ID_VENDOR_FROM_DATABASE=Co-time Computer Ltd
+
+pci:v00001050*
+ ID_VENDOR_FROM_DATABASE=Winbond Electronics Corp
+
+pci:v00001050d00000000*
+ ID_PRODUCT_FROM_DATABASE=NE2000
+
+pci:v00001050d00000001*
+ ID_PRODUCT_FROM_DATABASE=W83769F
+
+pci:v00001050d00000033*
+ ID_PRODUCT_FROM_DATABASE=W89C33D 802.11 a/b/g BB/MAC
+
+pci:v00001050d00000105*
+ ID_PRODUCT_FROM_DATABASE=W82C105
+
+pci:v00001050d00000840*
+ ID_PRODUCT_FROM_DATABASE=W89C840
+
+pci:v00001050d00000840sv00001050sd00000001*
+ ID_PRODUCT_FROM_DATABASE=W89C840 Ethernet Adapter
+
+pci:v00001050d00000840sv00001050sd00000840*
+ ID_PRODUCT_FROM_DATABASE=W89C840 Ethernet Adapter
+
+pci:v00001050d00000940*
+ ID_PRODUCT_FROM_DATABASE=W89C940
+
+pci:v00001050d00005A5A*
+ ID_PRODUCT_FROM_DATABASE=W89C940F
+
+pci:v00001050d00006692*
+ ID_PRODUCT_FROM_DATABASE=W6692
+
+pci:v00001050d00006692sv00001043sd00001702*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, W)
+
+pci:v00001050d00006692sv00001043sd00001703*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+
+pci:v00001050d00006692sv00001043sd00001707*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+
+pci:v00001050d00006692sv0000144Fsd00001702*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, W)
+
+pci:v00001050d00006692sv0000144Fsd00001703*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+
+pci:v00001050d00006692sv0000144Fsd00001707*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+
+pci:v00001050d00009921*
+ ID_PRODUCT_FROM_DATABASE=W99200F MPEG-1 Video Encoder
+
+pci:v00001050d00009922*
+ ID_PRODUCT_FROM_DATABASE=W99200F/W9922PF MPEG-1/2 Video Encoder
+
+pci:v00001050d00009970*
+ ID_PRODUCT_FROM_DATABASE=W9970CF
+
+pci:v00001051*
+ ID_VENDOR_FROM_DATABASE=Anigma, Inc.
+
+pci:v00001052*
+ ID_VENDOR_FROM_DATABASE=?Young Micro Systems
+
+pci:v00001053*
+ ID_VENDOR_FROM_DATABASE=Young Micro Systems
+
+pci:v00001054*
+ ID_VENDOR_FROM_DATABASE=Hitachi, Ltd
+
+pci:v00001054d00003009*
+ ID_PRODUCT_FROM_DATABASE=2Gbps Fibre Channel to PCI HBA 3009
+
+pci:v00001054d0000300A*
+ ID_PRODUCT_FROM_DATABASE=4Gbps Fibre Channel to PCI-X HBA 300a
+
+pci:v00001054d0000300B*
+ ID_PRODUCT_FROM_DATABASE=4Gbps Fibre Channel to PCI-X HBA 300b
+
+pci:v00001054d0000300F*
+ ID_PRODUCT_FROM_DATABASE=ColdFusion 3 Chipset Processor to I/O Controller
+
+pci:v00001054d00003010*
+ ID_PRODUCT_FROM_DATABASE=ColdFusion 3 Chipset Memory Controller Hub
+
+pci:v00001054d00003011*
+ ID_PRODUCT_FROM_DATABASE=ColdFusion 3e Chipset Processor to I/O Controller
+
+pci:v00001054d00003012*
+ ID_PRODUCT_FROM_DATABASE=ColdFusion 3e Chipset Memory Controller Hub
+
+pci:v00001054d00003017*
+ ID_PRODUCT_FROM_DATABASE=Unassigned Hitachi Shared FC Device 3017
+
+pci:v00001054d0000301B*
+ ID_PRODUCT_FROM_DATABASE=Virtual VGA Device
+
+pci:v00001054d0000301D*
+ ID_PRODUCT_FROM_DATABASE=PCIe-to-PCIe Bridge with Virtualization IO Assist Feature
+
+pci:v00001054d00003020*
+ ID_PRODUCT_FROM_DATABASE=FIVE-EX based Fibre Channel to PCIe HBA
+
+pci:v00001054d0000302C*
+ ID_PRODUCT_FROM_DATABASE=M001 PCI Express Switch Upstream Port
+
+pci:v00001054d0000302D*
+ ID_PRODUCT_FROM_DATABASE=M001 PCI Express Switch Downstream Port
+
+pci:v00001054d00003505*
+ ID_PRODUCT_FROM_DATABASE=SH7751 PCI Controller (PCIC)
+
+pci:v00001054d0000350E*
+ ID_PRODUCT_FROM_DATABASE=SH7751R PCI Controller (PCIC)
+
+pci:v00001055*
+ ID_VENDOR_FROM_DATABASE=Efar Microsystems
+
+pci:v00001055d00009130*
+ ID_PRODUCT_FROM_DATABASE=SLC90E66 [Victory66] IDE
+
+pci:v00001055d00009460*
+ ID_PRODUCT_FROM_DATABASE=SLC90E66 [Victory66] ISA
+
+pci:v00001055d00009462*
+ ID_PRODUCT_FROM_DATABASE=SLC90E66 [Victory66] USB
+
+pci:v00001055d00009463*
+ ID_PRODUCT_FROM_DATABASE=SLC90E66 [Victory66] ACPI
+
+pci:v00001055d0000E420*
+ ID_PRODUCT_FROM_DATABASE=LAN9420/LAN9420i
+
+pci:v00001056*
+ ID_VENDOR_FROM_DATABASE=ICL
+
+pci:v00001057*
+ ID_VENDOR_FROM_DATABASE=Motorola
+
+pci:v00001057d00000001*
+ ID_PRODUCT_FROM_DATABASE=MPC105 [Eagle]
+
+pci:v00001057d00000002*
+ ID_PRODUCT_FROM_DATABASE=MPC106 [Grackle]
+
+pci:v00001057d00000003*
+ ID_PRODUCT_FROM_DATABASE=MPC8240 [Kahlua]
+
+pci:v00001057d00000004*
+ ID_PRODUCT_FROM_DATABASE=MPC107
+
+pci:v00001057d00000006*
+ ID_PRODUCT_FROM_DATABASE=MPC8245 [Unity]
+
+pci:v00001057d00000008*
+ ID_PRODUCT_FROM_DATABASE=MPC8540
+
+pci:v00001057d00000009*
+ ID_PRODUCT_FROM_DATABASE=MPC8560
+
+pci:v00001057d00000012*
+ ID_PRODUCT_FROM_DATABASE=MPC8548 [PowerQUICC III]
+
+pci:v00001057d00000100*
+ ID_PRODUCT_FROM_DATABASE=MC145575 [HFC-PCI]
+
+pci:v00001057d00000431*
+ ID_PRODUCT_FROM_DATABASE=KTI829c 100VG
+
+pci:v00001057d00001073*
+ ID_PRODUCT_FROM_DATABASE=Nokia N770
+
+pci:v00001057d00001219*
+ ID_PRODUCT_FROM_DATABASE=Nokia N800
+
+pci:v00001057d00001801*
+ ID_PRODUCT_FROM_DATABASE=DSP56301 Digital Signal Processor
+
+pci:v00001057d00001801sv000014FBsd00000101*
+ ID_PRODUCT_FROM_DATABASE=Transas Radar Imitator Board [RIM]
+
+pci:v00001057d00001801sv000014FBsd00000102*
+ ID_PRODUCT_FROM_DATABASE=Transas Radar Imitator Board [RIM-2]
+
+pci:v00001057d00001801sv000014FBsd00000202*
+ ID_PRODUCT_FROM_DATABASE=Transas Radar Integrator Board [RIB-2]
+
+pci:v00001057d00001801sv000014FBsd00000611*
+ ID_PRODUCT_FROM_DATABASE=1 channel CAN bus Controller [CanPci-1]
+
+pci:v00001057d00001801sv000014FBsd00000612*
+ ID_PRODUCT_FROM_DATABASE=2 channels CAN bus Controller [CanPci-2]
+
+pci:v00001057d00001801sv000014FBsd00000613*
+ ID_PRODUCT_FROM_DATABASE=3 channels CAN bus Controller [CanPci-3]
+
+pci:v00001057d00001801sv000014FBsd00000614*
+ ID_PRODUCT_FROM_DATABASE=4 channels CAN bus Controller [CanPci-4]
+
+pci:v00001057d00001801sv000014FBsd00000621*
+ ID_PRODUCT_FROM_DATABASE=1 channel CAN bus Controller [CanPci2-1]
+
+pci:v00001057d00001801sv000014FBsd00000622*
+ ID_PRODUCT_FROM_DATABASE=2 channels CAN bus Controller [CanPci2-2]
+
+pci:v00001057d00001801sv000014FBsd00000810*
+ ID_PRODUCT_FROM_DATABASE=Transas VTS Radar Integrator Board [RIB-4]
+
+pci:v00001057d00001801sv0000175Csd00004200*
+ ID_PRODUCT_FROM_DATABASE=ASI4215 Audio Adapter
+
+pci:v00001057d00001801sv0000175Csd00004300*
+ ID_PRODUCT_FROM_DATABASE=ASI43xx Audio Adapter
+
+pci:v00001057d00001801sv0000175Csd00004400*
+ ID_PRODUCT_FROM_DATABASE=ASI4401 Audio Adapter
+
+pci:v00001057d00001801sv0000ECC0sd00000010*
+ ID_PRODUCT_FROM_DATABASE=Darla
+
+pci:v00001057d00001801sv0000ECC0sd00000020*
+ ID_PRODUCT_FROM_DATABASE=Gina
+
+pci:v00001057d00001801sv0000ECC0sd00000030*
+ ID_PRODUCT_FROM_DATABASE=Layla rev.0
+
+pci:v00001057d00001801sv0000ECC0sd00000031*
+ ID_PRODUCT_FROM_DATABASE=Layla rev.1
+
+pci:v00001057d00001801sv0000ECC0sd00000040*
+ ID_PRODUCT_FROM_DATABASE=Darla24 rev.0
+
+pci:v00001057d00001801sv0000ECC0sd00000041*
+ ID_PRODUCT_FROM_DATABASE=Darla24 rev.1
+
+pci:v00001057d00001801sv0000ECC0sd00000050*
+ ID_PRODUCT_FROM_DATABASE=Gina24 rev.0
+
+pci:v00001057d00001801sv0000ECC0sd00000051*
+ ID_PRODUCT_FROM_DATABASE=Gina24 rev.1
+
+pci:v00001057d00001801sv0000ECC0sd00000070*
+ ID_PRODUCT_FROM_DATABASE=Mona rev.0
+
+pci:v00001057d00001801sv0000ECC0sd00000071*
+ ID_PRODUCT_FROM_DATABASE=Mona rev.1
+
+pci:v00001057d00001801sv0000ECC0sd00000072*
+ ID_PRODUCT_FROM_DATABASE=Mona rev.2
+
+pci:v00001057d000018C0*
+ ID_PRODUCT_FROM_DATABASE=MPC8265A/8266/8272
+
+pci:v00001057d000018C1*
+ ID_PRODUCT_FROM_DATABASE=MPC8271/MPC8272
+
+pci:v00001057d00003052*
+ ID_PRODUCT_FROM_DATABASE=SM56 Data Fax Modem
+
+pci:v00001057d00003055*
+ ID_PRODUCT_FROM_DATABASE=SM56 Data Fax Modem
+
+pci:v00001057d00003410*
+ ID_PRODUCT_FROM_DATABASE=DSP56361 Digital Signal Processor
+
+pci:v00001057d00003410sv0000ECC0sd00000050*
+ ID_PRODUCT_FROM_DATABASE=Gina24 rev.0
+
+pci:v00001057d00003410sv0000ECC0sd00000051*
+ ID_PRODUCT_FROM_DATABASE=Gina24 rev.1
+
+pci:v00001057d00003410sv0000ECC0sd00000060*
+ ID_PRODUCT_FROM_DATABASE=Layla24
+
+pci:v00001057d00003410sv0000ECC0sd00000070*
+ ID_PRODUCT_FROM_DATABASE=Mona rev.0
+
+pci:v00001057d00003410sv0000ECC0sd00000071*
+ ID_PRODUCT_FROM_DATABASE=Mona rev.1
+
+pci:v00001057d00003410sv0000ECC0sd00000072*
+ ID_PRODUCT_FROM_DATABASE=Mona rev.2
+
+pci:v00001057d00003410sv0000ECC0sd00000080*
+ ID_PRODUCT_FROM_DATABASE=Mia rev.0
+
+pci:v00001057d00003410sv0000ECC0sd00000081*
+ ID_PRODUCT_FROM_DATABASE=Mia rev.1
+
+pci:v00001057d00003410sv0000ECC0sd00000090*
+ ID_PRODUCT_FROM_DATABASE=Indigo
+
+pci:v00001057d00003410sv0000ECC0sd000000A0*
+ ID_PRODUCT_FROM_DATABASE=Indigo IO
+
+pci:v00001057d00003410sv0000ECC0sd000000B0*
+ ID_PRODUCT_FROM_DATABASE=Indigo DJ
+
+pci:v00001057d00003410sv0000ECC0sd00000100*
+ ID_PRODUCT_FROM_DATABASE=3G
+
+pci:v00001057d00004801*
+ ID_PRODUCT_FROM_DATABASE=Raven
+
+pci:v00001057d00004802*
+ ID_PRODUCT_FROM_DATABASE=Falcon
+
+pci:v00001057d00004803*
+ ID_PRODUCT_FROM_DATABASE=Hawk
+
+pci:v00001057d00004806*
+ ID_PRODUCT_FROM_DATABASE=CPX8216
+
+pci:v00001057d00004D68*
+ ID_PRODUCT_FROM_DATABASE=20268
+
+pci:v00001057d00005600*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Modem
+
+pci:v00001057d00005600sv00001057sd00000300*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem
+
+pci:v00001057d00005600sv00001057sd00000301*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice Modem
+
+pci:v00001057d00005600sv00001057sd00000302*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem
+
+pci:v00001057d00005600sv00001057sd00005600*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice modem
+
+pci:v00001057d00005600sv000013D2sd00000300*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem
+
+pci:v00001057d00005600sv000013D2sd00000301*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice modem
+
+pci:v00001057d00005600sv000013D2sd00000302*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem
+
+pci:v00001057d00005600sv00001436sd00000300*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem
+
+pci:v00001057d00005600sv00001436sd00000301*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice modem
+
+pci:v00001057d00005600sv00001436sd00000302*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem
+
+pci:v00001057d00005600sv0000144Fsd0000100C*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem
+
+pci:v00001057d00005600sv00001494sd00000300*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem
+
+pci:v00001057d00005600sv00001494sd00000301*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice modem
+
+pci:v00001057d00005600sv000014C8sd00000300*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem
+
+pci:v00001057d00005600sv000014C8sd00000302*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem
+
+pci:v00001057d00005600sv00001668sd00000300*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem
+
+pci:v00001057d00005600sv00001668sd00000302*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem
+
+pci:v00001057d00005608*
+ ID_PRODUCT_FROM_DATABASE=Wildcard X100P
+
+pci:v00001057d00005803*
+ ID_PRODUCT_FROM_DATABASE=MPC5200
+
+pci:v00001057d00005806*
+ ID_PRODUCT_FROM_DATABASE=MCF54 Coldfire
+
+pci:v00001057d00005808*
+ ID_PRODUCT_FROM_DATABASE=MPC8220
+
+pci:v00001057d00005809*
+ ID_PRODUCT_FROM_DATABASE=MPC5200B
+
+pci:v00001057d00006400*
+ ID_PRODUCT_FROM_DATABASE=MPC190 Security Processor (S1 family, encryption)
+
+pci:v00001057d00006405*
+ ID_PRODUCT_FROM_DATABASE=MPC184 Security Processor (S1 family)
+
+pci:v00001058*
+ ID_VENDOR_FROM_DATABASE=Electronics & Telecommunications RSH
+
+pci:v00001059*
+ ID_VENDOR_FROM_DATABASE=Kontron
+
+pci:v0000105A*
+ ID_VENDOR_FROM_DATABASE=Promise Technology, Inc.
+
+pci:v0000105Ad00000D30*
+ ID_PRODUCT_FROM_DATABASE=PDC20265 (FastTrak100 Lite/Ultra100)
+
+pci:v0000105Ad00000D30sv00001043sd00008042*
+ ID_PRODUCT_FROM_DATABASE=AV7266-E South Bridge Promise RAID
+
+pci:v0000105Ad00000D30sv0000105Asd00004D33*
+ ID_PRODUCT_FROM_DATABASE=Ultra100
+
+pci:v0000105Ad00000D38*
+ ID_PRODUCT_FROM_DATABASE=20263
+
+pci:v0000105Ad00000D38sv0000105Asd00004D39*
+ ID_PRODUCT_FROM_DATABASE=Fasttrak66
+
+pci:v0000105Ad00001275*
+ ID_PRODUCT_FROM_DATABASE=20275
+
+pci:v0000105Ad00003318*
+ ID_PRODUCT_FROM_DATABASE=PDC20318 (SATA150 TX4)
+
+pci:v0000105Ad00003319*
+ ID_PRODUCT_FROM_DATABASE=PDC20319 (FastTrak S150 TX4)
+
+pci:v0000105Ad00003319sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v0000105Ad00003371*
+ ID_PRODUCT_FROM_DATABASE=PDC20371 (FastTrak S150 TX2plus)
+
+pci:v0000105Ad00003373*
+ ID_PRODUCT_FROM_DATABASE=PDC20378 (FastTrak 378/SATA 378)
+
+pci:v0000105Ad00003373sv00001043sd000080F5*
+ ID_PRODUCT_FROM_DATABASE=K8V Deluxe/PC-DL Deluxe motherboard
+
+pci:v0000105Ad00003373sv00001462sd0000590D*
+ ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+
+pci:v0000105Ad00003373sv00001462sd0000702E*
+ ID_PRODUCT_FROM_DATABASE=K8T NEO FIS2R motherboard
+
+pci:v0000105Ad00003375*
+ ID_PRODUCT_FROM_DATABASE=PDC20375 (SATA150 TX2plus)
+
+pci:v0000105Ad00003376*
+ ID_PRODUCT_FROM_DATABASE=PDC20376 (FastTrak 376)
+
+pci:v0000105Ad00003376sv00001043sd0000809E*
+ ID_PRODUCT_FROM_DATABASE=A7V8X motherboard
+
+pci:v0000105Ad00003515*
+ ID_PRODUCT_FROM_DATABASE=PDC40719 [FastTrak TX4300/TX4310]
+
+pci:v0000105Ad00003519*
+ ID_PRODUCT_FROM_DATABASE=PDC40519 (FastTrak TX4200)
+
+pci:v0000105Ad00003570*
+ ID_PRODUCT_FROM_DATABASE=PDC20771 [FastTrak TX2300]
+
+pci:v0000105Ad00003571*
+ ID_PRODUCT_FROM_DATABASE=PDC20571 (FastTrak TX2200)
+
+pci:v0000105Ad00003574*
+ ID_PRODUCT_FROM_DATABASE=PDC20579 SATAII 150 IDE Controller
+
+pci:v0000105Ad00003577*
+ ID_PRODUCT_FROM_DATABASE=PDC40779 (SATA 300 779)
+
+pci:v0000105Ad00003D17*
+ ID_PRODUCT_FROM_DATABASE=PDC40718 (SATA 300 TX4)
+
+pci:v0000105Ad00003D18*
+ ID_PRODUCT_FROM_DATABASE=PDC20518/PDC40518 (SATAII 150 TX4)
+
+pci:v0000105Ad00003D73*
+ ID_PRODUCT_FROM_DATABASE=PDC40775 (SATA 300 TX2plus)
+
+pci:v0000105Ad00003D75*
+ ID_PRODUCT_FROM_DATABASE=PDC20575 (SATAII150 TX2plus)
+
+pci:v0000105Ad00003F20*
+ ID_PRODUCT_FROM_DATABASE=PDC42819 [FastTrak TX2650/TX4650]
+
+pci:v0000105Ad00004302*
+ ID_PRODUCT_FROM_DATABASE=80333 [SuperTrak EX4350]
+
+pci:v0000105Ad00004D30*
+ ID_PRODUCT_FROM_DATABASE=PDC20267 (FastTrak100/Ultra100)
+
+pci:v0000105Ad00004D30sv0000105Asd00004D33*
+ ID_PRODUCT_FROM_DATABASE=Ultra100
+
+pci:v0000105Ad00004D30sv0000105Asd00004D39*
+ ID_PRODUCT_FROM_DATABASE=FastTrak100
+
+pci:v0000105Ad00004D30sv00008086sd00005744*
+ ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard
+
+pci:v0000105Ad00004D33*
+ ID_PRODUCT_FROM_DATABASE=20246
+
+pci:v0000105Ad00004D33sv0000105Asd00004D33*
+ ID_PRODUCT_FROM_DATABASE=20246 IDE Controller
+
+pci:v0000105Ad00004D38*
+ ID_PRODUCT_FROM_DATABASE=PDC20262 (FastTrak66/Ultra66)
+
+pci:v0000105Ad00004D38sv0000105Asd00004D30*
+ ID_PRODUCT_FROM_DATABASE=Ultra Device on SuperTrak
+
+pci:v0000105Ad00004D38sv0000105Asd00004D33*
+ ID_PRODUCT_FROM_DATABASE=Ultra66
+
+pci:v0000105Ad00004D38sv0000105Asd00004D39*
+ ID_PRODUCT_FROM_DATABASE=FastTrak66
+
+pci:v0000105Ad00004D68*
+ ID_PRODUCT_FROM_DATABASE=PDC20268 [Ultra100 TX2]
+
+pci:v0000105Ad00004D68sv0000105Asd00004D68*
+ ID_PRODUCT_FROM_DATABASE=Ultra100 TX2
+
+pci:v0000105Ad00004D69*
+ ID_PRODUCT_FROM_DATABASE=20269
+
+pci:v0000105Ad00004D69sv0000105Asd00004D68*
+ ID_PRODUCT_FROM_DATABASE=Ultra133TX2
+
+pci:v0000105Ad00005275*
+ ID_PRODUCT_FROM_DATABASE=PDC20276 (MBFastTrak133 Lite)
+
+pci:v0000105Ad00005275sv00001043sd0000807E*
+ ID_PRODUCT_FROM_DATABASE=A7V333 motherboard.
+
+pci:v0000105Ad00005275sv0000105Asd00000275*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak SX6000 IDE
+
+pci:v0000105Ad00005275sv0000105Asd00001275*
+ ID_PRODUCT_FROM_DATABASE=MBFastTrak133 Lite (tm) Controller (RAID mode)
+
+pci:v0000105Ad00005275sv00001458sd0000B001*
+ ID_PRODUCT_FROM_DATABASE=MBUltra 133
+
+pci:v0000105Ad00005300*
+ ID_PRODUCT_FROM_DATABASE=DC5300
+
+pci:v0000105Ad00006268*
+ ID_PRODUCT_FROM_DATABASE=PDC20270 (FastTrak100 LP/TX2/TX4)
+
+pci:v0000105Ad00006268sv0000105Asd00004D68*
+ ID_PRODUCT_FROM_DATABASE=FastTrak100 TX2
+
+pci:v0000105Ad00006269*
+ ID_PRODUCT_FROM_DATABASE=PDC20271 (FastTrak TX2000)
+
+pci:v0000105Ad00006269sv0000105Asd00006269*
+ ID_PRODUCT_FROM_DATABASE=FastTrak TX2/TX2000
+
+pci:v0000105Ad00006300*
+ ID_PRODUCT_FROM_DATABASE=PDC81731 [FastTrak SX8300]
+
+pci:v0000105Ad00006621*
+ ID_PRODUCT_FROM_DATABASE=PDC20621 (FastTrak S150 SX4/FastTrak SX4000 lite)
+
+pci:v0000105Ad00006622*
+ ID_PRODUCT_FROM_DATABASE=PDC20621 [SATA150 SX4] 4 Channel IDE RAID Controller
+
+pci:v0000105Ad00006624*
+ ID_PRODUCT_FROM_DATABASE=PDC20621 [FastTrak SX4100]
+
+pci:v0000105Ad00006626*
+ ID_PRODUCT_FROM_DATABASE=PDC20618 (Ultra 618)
+
+pci:v0000105Ad00006629*
+ ID_PRODUCT_FROM_DATABASE=PDC20619 (FastTrak TX4000)
+
+pci:v0000105Ad00007275*
+ ID_PRODUCT_FROM_DATABASE=PDC20277 (SBFastTrak133 Lite)
+
+pci:v0000105Ad00008002*
+ ID_PRODUCT_FROM_DATABASE=SATAII150 SX8
+
+pci:v0000105Ad00008350*
+ ID_PRODUCT_FROM_DATABASE=80333 [SuperTrak EX8350/EX16350], 80331 [SuperTrak EX8300/EX16300]
+
+pci:v0000105Ad00008650*
+ ID_PRODUCT_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller]
+
+pci:v0000105Ad00008650sv0000105Asd00004600*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX4650A
+
+pci:v0000105Ad00008650sv0000105Asd00004601*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX4650
+
+pci:v0000105Ad00008650sv0000105Asd00004610*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX4650EL
+
+pci:v0000105Ad00008650sv0000105Asd00008600*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX8650EL
+
+pci:v0000105Ad00008650sv0000105Asd00008601*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX8650A
+
+pci:v0000105Ad00008650sv0000105Asd00008602*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX8654
+
+pci:v0000105Ad00008650sv0000105Asd00008603*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX8658
+
+pci:v0000105Ad00008650sv0000105Asd00008604*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX8650
+
+pci:v0000105Ad00008650sv0000105Asd00008610*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX8650M
+
+pci:v0000105Ad00008650sv0000105Asd0000A600*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX12650
+
+pci:v0000105Ad00008650sv0000105Asd0000B600*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX16650
+
+pci:v0000105Ad00008650sv0000105Asd0000B601*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX16654
+
+pci:v0000105Ad00008650sv0000105Asd0000B602*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak EX16658
+
+pci:v0000105Ad00008760*
+ ID_PRODUCT_FROM_DATABASE=PM8010 [SuperTrak EX SAS and SATA 6G RAID Controller]
+
+pci:v0000105Ad0000C350*
+ ID_PRODUCT_FROM_DATABASE=80333 [SuperTrak EX12350]
+
+pci:v0000105Ad0000E350*
+ ID_PRODUCT_FROM_DATABASE=80333 [SuperTrak EX24350]
+
+pci:v0000105B*
+ ID_VENDOR_FROM_DATABASE=Foxconn International, Inc.
+
+pci:v0000105Bd00000C4D*
+ ID_PRODUCT_FROM_DATABASE=SiS AC'97 Sound Controller
+
+pci:v0000105C*
+ ID_VENDOR_FROM_DATABASE=Wipro Infotech Limited
+
+pci:v0000105D*
+ ID_VENDOR_FROM_DATABASE=Number 9 Computer Company
+
+pci:v0000105Dd00002309*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128
+
+pci:v0000105Dd00002339*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128-II
+
+pci:v0000105Dd00002339sv0000105Dsd00000000*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000001*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000002*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000003*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000004*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000005*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000006*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000007*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000008*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2e 4Mb DRAM
+
+pci:v0000105Dd00002339sv0000105Dsd00000009*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2e 4Mb DRAM
+
+pci:v0000105Dd00002339sv0000105Dsd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 8Mb VRAM
+
+pci:v0000105Dd00002339sv0000105Dsd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 8Mb H-VRAM
+
+pci:v0000105Dd00002339sv000011A4sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd00002339sv000013CCsd00000000*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd00002339sv000013CCsd00000004*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd00002339sv000013CCsd00000005*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd00002339sv000013CCsd00000006*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd00002339sv000013CCsd00000008*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd00002339sv000013CCsd00000009*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd00002339sv000013CCsd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd00002339sv000013CCsd0000000C*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel
+
+pci:v0000105Dd0000493D*
+ ID_PRODUCT_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride]
+
+pci:v0000105Dd0000493Dsv000011A4sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+
+pci:v0000105Dd0000493Dsv000011A4sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+
+pci:v0000105Dd0000493Dsv000013CCsd00000002*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 4 Megapixel, Dual Head
+
+pci:v0000105Dd0000493Dsv000013CCsd00000003*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+
+pci:v0000105Dd0000493Dsv000013CCsd00000007*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+
+pci:v0000105Dd0000493Dsv000013CCsd00000008*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+
+pci:v0000105Dd0000493Dsv000013CCsd00000009*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+
+pci:v0000105Dd0000493Dsv000013CCsd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+
+pci:v0000105Dd00005348*
+ ID_PRODUCT_FROM_DATABASE=Revolution 4
+
+pci:v0000105Dd00005348sv0000105Dsd00000037*
+ ID_PRODUCT_FROM_DATABASE=Revolution IV-FP AGP (For SGI 1600SW)
+
+pci:v0000105Dd00005348sv000011A4sd00000028*
+ ID_PRODUCT_FROM_DATABASE=PVS5600M
+
+pci:v0000105Dd00005348sv000011A4sd00000038*
+ ID_PRODUCT_FROM_DATABASE=PVS5600D
+
+pci:v0000105E*
+ ID_VENDOR_FROM_DATABASE=Vtech Computers Ltd
+
+pci:v0000105F*
+ ID_VENDOR_FROM_DATABASE=Infotronic America Inc
+
+pci:v00001060*
+ ID_VENDOR_FROM_DATABASE=United Microelectronics [UMC]
+
+pci:v00001060d00000001*
+ ID_PRODUCT_FROM_DATABASE=UM82C881
+
+pci:v00001060d00000002*
+ ID_PRODUCT_FROM_DATABASE=UM82C886
+
+pci:v00001060d00000101*
+ ID_PRODUCT_FROM_DATABASE=UM8673F
+
+pci:v00001060d00000881*
+ ID_PRODUCT_FROM_DATABASE=UM8881
+
+pci:v00001060d00000886*
+ ID_PRODUCT_FROM_DATABASE=UM8886F
+
+pci:v00001060d00000891*
+ ID_PRODUCT_FROM_DATABASE=UM8891A
+
+pci:v00001060d00001001*
+ ID_PRODUCT_FROM_DATABASE=UM886A
+
+pci:v00001060d0000673A*
+ ID_PRODUCT_FROM_DATABASE=UM8886BF
+
+pci:v00001060d0000673B*
+ ID_PRODUCT_FROM_DATABASE=EIDE Master/DMA
+
+pci:v00001060d00008710*
+ ID_PRODUCT_FROM_DATABASE=UM8710
+
+pci:v00001060d0000886A*
+ ID_PRODUCT_FROM_DATABASE=UM8886A
+
+pci:v00001060d00008881*
+ ID_PRODUCT_FROM_DATABASE=UM8881F
+
+pci:v00001060d00008886*
+ ID_PRODUCT_FROM_DATABASE=UM8886F
+
+pci:v00001060d0000888A*
+ ID_PRODUCT_FROM_DATABASE=UM8886A
+
+pci:v00001060d00008891*
+ ID_PRODUCT_FROM_DATABASE=UM8891A
+
+pci:v00001060d00009017*
+ ID_PRODUCT_FROM_DATABASE=UM9017F
+
+pci:v00001060d00009018*
+ ID_PRODUCT_FROM_DATABASE=UM9018
+
+pci:v00001060d00009026*
+ ID_PRODUCT_FROM_DATABASE=UM9026
+
+pci:v00001060d0000E881*
+ ID_PRODUCT_FROM_DATABASE=UM8881N
+
+pci:v00001060d0000E886*
+ ID_PRODUCT_FROM_DATABASE=UM8886N
+
+pci:v00001060d0000E88A*
+ ID_PRODUCT_FROM_DATABASE=UM8886N
+
+pci:v00001060d0000E891*
+ ID_PRODUCT_FROM_DATABASE=UM8891N
+
+pci:v00001061*
+ ID_VENDOR_FROM_DATABASE=I.I.T.
+
+pci:v00001061d00000001*
+ ID_PRODUCT_FROM_DATABASE=AGX016
+
+pci:v00001061d00000002*
+ ID_PRODUCT_FROM_DATABASE=IIT3204/3501
+
+pci:v00001062*
+ ID_VENDOR_FROM_DATABASE=Maspar Computer Corp
+
+pci:v00001063*
+ ID_VENDOR_FROM_DATABASE=Ocean Office Automation
+
+pci:v00001064*
+ ID_VENDOR_FROM_DATABASE=Alcatel
+
+pci:v00001064d00001102*
+ ID_PRODUCT_FROM_DATABASE=Dynamite 2840 (ADSL PCI modem)
+
+pci:v00001065*
+ ID_VENDOR_FROM_DATABASE=Texas Microsystems
+
+pci:v00001066*
+ ID_VENDOR_FROM_DATABASE=PicoPower Technology
+
+pci:v00001066d00000000*
+ ID_PRODUCT_FROM_DATABASE=PT80C826
+
+pci:v00001066d00000001*
+ ID_PRODUCT_FROM_DATABASE=PT86C521 [Vesuvius v1] Host Bridge
+
+pci:v00001066d00000002*
+ ID_PRODUCT_FROM_DATABASE=PT86C523 [Vesuvius v3] PCI-ISA Bridge Master
+
+pci:v00001066d00000003*
+ ID_PRODUCT_FROM_DATABASE=PT86C524 [Nile] PCI-to-PCI Bridge
+
+pci:v00001066d00000004*
+ ID_PRODUCT_FROM_DATABASE=PT86C525 [Nile-II] PCI-to-PCI Bridge
+
+pci:v00001066d00000005*
+ ID_PRODUCT_FROM_DATABASE=National PC87550 System Controller
+
+pci:v00001066d00008002*
+ ID_PRODUCT_FROM_DATABASE=PT86C523 [Vesuvius v3] PCI-ISA Bridge Slave
+
+pci:v00001067*
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Electric
+
+pci:v00001067d00000301*
+ ID_PRODUCT_FROM_DATABASE=AccelGraphics AccelECLIPSE
+
+pci:v00001067d00000304*
+ ID_PRODUCT_FROM_DATABASE=AccelGALAXY A2100 [OEM Evans & Sutherland]
+
+pci:v00001067d00000308*
+ ID_PRODUCT_FROM_DATABASE=Tornado 3000 [OEM Evans & Sutherland]
+
+pci:v00001067d00001002*
+ ID_PRODUCT_FROM_DATABASE=VG500 [VolumePro Volume Rendering Accelerator]
+
+pci:v00001068*
+ ID_VENDOR_FROM_DATABASE=Diversified Technology
+
+pci:v00001069*
+ ID_VENDOR_FROM_DATABASE=Mylex Corporation
+
+pci:v00001069d00000001*
+ ID_PRODUCT_FROM_DATABASE=DAC960P
+
+pci:v00001069d00000002*
+ ID_PRODUCT_FROM_DATABASE=DAC960PD
+
+pci:v00001069d00000010*
+ ID_PRODUCT_FROM_DATABASE=DAC960PG
+
+pci:v00001069d00000020*
+ ID_PRODUCT_FROM_DATABASE=DAC960LA
+
+pci:v00001069d00000050*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID 352/170/160 support Device
+
+pci:v00001069d00000050sv00001069sd00000050*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID 352 support Device
+
+pci:v00001069d00000050sv00001069sd00000052*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID 170 support Device
+
+pci:v00001069d00000050sv00001069sd00000054*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID 160 support Device
+
+pci:v00001069d0000B166*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device
+
+pci:v00001069d0000B166sv00001014sd00000242*
+ ID_PRODUCT_FROM_DATABASE=iSeries 2872 DASD IOA
+
+pci:v00001069d0000B166sv00001014sd00000266*
+ ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X U320 SCSI Adapter
+
+pci:v00001069d0000B166sv00001014sd00000278*
+ ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X U320 SCSI RAID Adapter
+
+pci:v00001069d0000B166sv00001014sd000002D3*
+ ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X U320 SCSI Adapter
+
+pci:v00001069d0000B166sv00001014sd000002D4*
+ ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X U320 SCSI RAID Adapter
+
+pci:v00001069d0000B166sv00001069sd00000200*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID 400, Single Channel, PCI-X, U320, SCSI RAID
+
+pci:v00001069d0000B166sv00001069sd00000202*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID Sapphire, Dual Channel, PCI-X, U320, SCSI RAID
+
+pci:v00001069d0000B166sv00001069sd00000204*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID 500, Dual Channel, Low-Profile, PCI-X, U320, SCSI RAID
+
+pci:v00001069d0000B166sv00001069sd00000206*
+ ID_PRODUCT_FROM_DATABASE=AcceleRAID 600, Dual Channel, PCI-X, U320, SCSI RAID
+
+pci:v00001069d0000BA55*
+ ID_PRODUCT_FROM_DATABASE=eXtremeRAID 1100 support Device
+
+pci:v00001069d0000BA56*
+ ID_PRODUCT_FROM_DATABASE=eXtremeRAID 2000/3000 support Device
+
+pci:v00001069d0000BA56sv00001069sd00000030*
+ ID_PRODUCT_FROM_DATABASE=eXtremeRAID 3000 support Device
+
+pci:v00001069d0000BA56sv00001069sd00000040*
+ ID_PRODUCT_FROM_DATABASE=eXtremeRAID 2000 support Device
+
+pci:v00001069d0000BA57*
+ ID_PRODUCT_FROM_DATABASE=eXtremeRAID 4000/5000 support Device
+
+pci:v00001069d0000BA57sv00001069sd00000072*
+ ID_PRODUCT_FROM_DATABASE=eXtremeRAID 5000 support Device
+
+pci:v0000106A*
+ ID_VENDOR_FROM_DATABASE=Aten Research Inc
+
+pci:v0000106B*
+ ID_VENDOR_FROM_DATABASE=Apple Inc.
+
+pci:v0000106Bd00000001*
+ ID_PRODUCT_FROM_DATABASE=Bandit PowerPC host bridge
+
+pci:v0000106Bd00000002*
+ ID_PRODUCT_FROM_DATABASE=Grand Central I/O
+
+pci:v0000106Bd00000003*
+ ID_PRODUCT_FROM_DATABASE=Control Video
+
+pci:v0000106Bd00000004*
+ ID_PRODUCT_FROM_DATABASE=PlanB Video-In
+
+pci:v0000106Bd00000007*
+ ID_PRODUCT_FROM_DATABASE=O'Hare I/O
+
+pci:v0000106Bd0000000C*
+ ID_PRODUCT_FROM_DATABASE=DOS on Mac
+
+pci:v0000106Bd0000000E*
+ ID_PRODUCT_FROM_DATABASE=Hydra Mac I/O
+
+pci:v0000106Bd00000010*
+ ID_PRODUCT_FROM_DATABASE=Heathrow Mac I/O
+
+pci:v0000106Bd00000017*
+ ID_PRODUCT_FROM_DATABASE=Paddington Mac I/O
+
+pci:v0000106Bd00000018*
+ ID_PRODUCT_FROM_DATABASE=UniNorth FireWire
+
+pci:v0000106Bd00000019*
+ ID_PRODUCT_FROM_DATABASE=KeyLargo USB
+
+pci:v0000106Bd0000001E*
+ ID_PRODUCT_FROM_DATABASE=UniNorth Internal PCI
+
+pci:v0000106Bd0000001F*
+ ID_PRODUCT_FROM_DATABASE=UniNorth PCI
+
+pci:v0000106Bd00000020*
+ ID_PRODUCT_FROM_DATABASE=UniNorth AGP
+
+pci:v0000106Bd00000021*
+ ID_PRODUCT_FROM_DATABASE=UniNorth GMAC (Sun GEM)
+
+pci:v0000106Bd00000022*
+ ID_PRODUCT_FROM_DATABASE=KeyLargo Mac I/O
+
+pci:v0000106Bd00000024*
+ ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea GMAC (Sun GEM)
+
+pci:v0000106Bd00000025*
+ ID_PRODUCT_FROM_DATABASE=KeyLargo/Pangea Mac I/O
+
+pci:v0000106Bd00000026*
+ ID_PRODUCT_FROM_DATABASE=KeyLargo/Pangea USB
+
+pci:v0000106Bd00000027*
+ ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea AGP
+
+pci:v0000106Bd00000028*
+ ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea PCI
+
+pci:v0000106Bd00000029*
+ ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea Internal PCI
+
+pci:v0000106Bd0000002D*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 1.5 AGP
+
+pci:v0000106Bd0000002E*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 1.5 PCI
+
+pci:v0000106Bd0000002F*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 1.5 Internal PCI
+
+pci:v0000106Bd00000030*
+ ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea FireWire
+
+pci:v0000106Bd00000031*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 2 FireWire
+
+pci:v0000106Bd00000031sv0000106Bsd00005811*
+ ID_PRODUCT_FROM_DATABASE=iBook G4 2004
+
+pci:v0000106Bd00000032*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 2 GMAC (Sun GEM)
+
+pci:v0000106Bd00000033*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 2 ATA/100
+
+pci:v0000106Bd00000034*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 2 AGP
+
+pci:v0000106Bd00000035*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 2 PCI
+
+pci:v0000106Bd00000036*
+ ID_PRODUCT_FROM_DATABASE=UniNorth 2 Internal PCI
+
+pci:v0000106Bd0000003B*
+ ID_PRODUCT_FROM_DATABASE=UniNorth/Intrepid ATA/100
+
+pci:v0000106Bd0000003E*
+ ID_PRODUCT_FROM_DATABASE=KeyLargo/Intrepid Mac I/O
+
+pci:v0000106Bd0000003F*
+ ID_PRODUCT_FROM_DATABASE=KeyLargo/Intrepid USB
+
+pci:v0000106Bd00000040*
+ ID_PRODUCT_FROM_DATABASE=K2 KeyLargo USB
+
+pci:v0000106Bd00000041*
+ ID_PRODUCT_FROM_DATABASE=K2 KeyLargo Mac/IO
+
+pci:v0000106Bd00000042*
+ ID_PRODUCT_FROM_DATABASE=K2 FireWire
+
+pci:v0000106Bd00000043*
+ ID_PRODUCT_FROM_DATABASE=K2 ATA/100
+
+pci:v0000106Bd00000045*
+ ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge
+
+pci:v0000106Bd00000046*
+ ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge
+
+pci:v0000106Bd00000047*
+ ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge
+
+pci:v0000106Bd00000048*
+ ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge
+
+pci:v0000106Bd00000049*
+ ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge
+
+pci:v0000106Bd0000004A*
+ ID_PRODUCT_FROM_DATABASE=CPC945 HT Bridge
+
+pci:v0000106Bd0000004B*
+ ID_PRODUCT_FROM_DATABASE=U3 AGP
+
+pci:v0000106Bd0000004C*
+ ID_PRODUCT_FROM_DATABASE=K2 GMAC (Sun GEM)
+
+pci:v0000106Bd0000004F*
+ ID_PRODUCT_FROM_DATABASE=Shasta Mac I/O
+
+pci:v0000106Bd00000050*
+ ID_PRODUCT_FROM_DATABASE=Shasta IDE
+
+pci:v0000106Bd00000051*
+ ID_PRODUCT_FROM_DATABASE=Shasta (Sun GEM)
+
+pci:v0000106Bd00000052*
+ ID_PRODUCT_FROM_DATABASE=Shasta Firewire
+
+pci:v0000106Bd00000053*
+ ID_PRODUCT_FROM_DATABASE=Shasta PCI Bridge
+
+pci:v0000106Bd00000054*
+ ID_PRODUCT_FROM_DATABASE=Shasta PCI Bridge
+
+pci:v0000106Bd00000055*
+ ID_PRODUCT_FROM_DATABASE=Shasta PCI Bridge
+
+pci:v0000106Bd00000056*
+ ID_PRODUCT_FROM_DATABASE=U4 PCIe
+
+pci:v0000106Bd00000057*
+ ID_PRODUCT_FROM_DATABASE=U3 HT Bridge
+
+pci:v0000106Bd00000058*
+ ID_PRODUCT_FROM_DATABASE=U3L AGP Bridge
+
+pci:v0000106Bd00000059*
+ ID_PRODUCT_FROM_DATABASE=U3H AGP Bridge
+
+pci:v0000106Bd0000005B*
+ ID_PRODUCT_FROM_DATABASE=CPC945 PCIe Bridge
+
+pci:v0000106Bd00000066*
+ ID_PRODUCT_FROM_DATABASE=Intrepid2 AGP Bridge
+
+pci:v0000106Bd00000067*
+ ID_PRODUCT_FROM_DATABASE=Intrepid2 PCI Bridge
+
+pci:v0000106Bd00000068*
+ ID_PRODUCT_FROM_DATABASE=Intrepid2 PCI Bridge
+
+pci:v0000106Bd00000069*
+ ID_PRODUCT_FROM_DATABASE=Intrepid2 ATA/100
+
+pci:v0000106Bd0000006A*
+ ID_PRODUCT_FROM_DATABASE=Intrepid2 Firewire
+
+pci:v0000106Bd0000006B*
+ ID_PRODUCT_FROM_DATABASE=Intrepid2 GMAC (Sun GEM)
+
+pci:v0000106Bd00000074*
+ ID_PRODUCT_FROM_DATABASE=U4 HT Bridge
+
+pci:v0000106Bd00001645*
+ ID_PRODUCT_FROM_DATABASE=Tigon3 Gigabit Ethernet NIC (BCM5701)
+
+pci:v0000106C*
+ ID_VENDOR_FROM_DATABASE=Hynix Semiconductor
+
+pci:v0000106Cd00008139*
+ ID_PRODUCT_FROM_DATABASE=8139c 100BaseTX Ethernet Controller
+
+pci:v0000106Cd00008801*
+ ID_PRODUCT_FROM_DATABASE=Dual Pentium ISA/PCI Motherboard
+
+pci:v0000106Cd00008802*
+ ID_PRODUCT_FROM_DATABASE=PowerPC ISA/PCI Motherboard
+
+pci:v0000106Cd00008803*
+ ID_PRODUCT_FROM_DATABASE=Dual Window Graphics Accelerator
+
+pci:v0000106Cd00008804*
+ ID_PRODUCT_FROM_DATABASE=LAN Controller
+
+pci:v0000106Cd00008805*
+ ID_PRODUCT_FROM_DATABASE=100-BaseT LAN
+
+pci:v0000106D*
+ ID_VENDOR_FROM_DATABASE=Sequent Computer Systems
+
+pci:v0000106E*
+ ID_VENDOR_FROM_DATABASE=DFI, Inc
+
+pci:v0000106F*
+ ID_VENDOR_FROM_DATABASE=City Gate Development Ltd
+
+pci:v00001070*
+ ID_VENDOR_FROM_DATABASE=Daewoo Telecom Ltd
+
+pci:v00001071*
+ ID_VENDOR_FROM_DATABASE=Mitac
+
+pci:v00001071d00008160*
+ ID_PRODUCT_FROM_DATABASE=Mitac 8060B Mobile Platform
+
+pci:v00001072*
+ ID_VENDOR_FROM_DATABASE=GIT Co Ltd
+
+pci:v00001073*
+ ID_VENDOR_FROM_DATABASE=Yamaha Corporation
+
+pci:v00001073d00000001*
+ ID_PRODUCT_FROM_DATABASE=3D GUI Accelerator
+
+pci:v00001073d00000002*
+ ID_PRODUCT_FROM_DATABASE=YGV615 [RPA3 3D-Graphics Controller]
+
+pci:v00001073d00000003*
+ ID_PRODUCT_FROM_DATABASE=YMF-740
+
+pci:v00001073d00000004*
+ ID_PRODUCT_FROM_DATABASE=YMF-724
+
+pci:v00001073d00000004sv00001073sd00000004*
+ ID_PRODUCT_FROM_DATABASE=YMF724-Based PCI Audio Adapter
+
+pci:v00001073d00000005*
+ ID_PRODUCT_FROM_DATABASE=DS1 Audio
+
+pci:v00001073d00000005sv00001073sd00000005*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC
+
+pci:v00001073d00000006*
+ ID_PRODUCT_FROM_DATABASE=DS1 Audio
+
+pci:v00001073d00000008*
+ ID_PRODUCT_FROM_DATABASE=DS1 Audio
+
+pci:v00001073d00000008sv00001073sd00000008*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC
+
+pci:v00001073d0000000A*
+ ID_PRODUCT_FROM_DATABASE=DS1L Audio
+
+pci:v00001073d0000000Asv00001073sd00000004*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC
+
+pci:v00001073d0000000Asv00001073sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC
+
+pci:v00001073d0000000Asv00008086sd00004D55*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC [Intel MU440EX]
+
+pci:v00001073d0000000C*
+ ID_PRODUCT_FROM_DATABASE=YMF-740C [DS-1L Audio Controller]
+
+pci:v00001073d0000000Csv0000107Asd0000000C*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC
+
+pci:v00001073d0000000D*
+ ID_PRODUCT_FROM_DATABASE=YMF-724F [DS-1 Audio Controller]
+
+pci:v00001073d0000000Dsv00001073sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC
+
+pci:v00001073d00000010*
+ ID_PRODUCT_FROM_DATABASE=YMF-744B [DS-1S Audio Controller]
+
+pci:v00001073d00000010sv00001073sd00000006*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC
+
+pci:v00001073d00000010sv00001073sd00000010*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC
+
+pci:v00001073d00000012*
+ ID_PRODUCT_FROM_DATABASE=YMF-754 [DS-1E Audio Controller]
+
+pci:v00001073d00000012sv00001073sd00000012*
+ ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio Codec
+
+pci:v00001073d00000020*
+ ID_PRODUCT_FROM_DATABASE=DS-1 Audio
+
+pci:v00001073d00001000*
+ ID_PRODUCT_FROM_DATABASE=SW1000XG [XG Factory]
+
+pci:v00001073d00002000*
+ ID_PRODUCT_FROM_DATABASE=DS2416 Digital Mixing Card
+
+pci:v00001073d00002000sv00001073sd00002000*
+ ID_PRODUCT_FROM_DATABASE=DS2416 Digital Mixing Card
+
+pci:v00001074*
+ ID_VENDOR_FROM_DATABASE=NexGen Microsystems
+
+pci:v00001074d00004E78*
+ ID_PRODUCT_FROM_DATABASE=82c500/1
+
+pci:v00001075*
+ ID_VENDOR_FROM_DATABASE=Advanced Integrations Research
+
+pci:v00001076*
+ ID_VENDOR_FROM_DATABASE=Chaintech Computer Co. Ltd
+
+pci:v00001077*
+ ID_VENDOR_FROM_DATABASE=QLogic Corp.
+
+pci:v00001077d00001016*
+ ID_PRODUCT_FROM_DATABASE=ISP10160 Single Channel Ultra3 SCSI Processor
+
+pci:v00001077d00001020*
+ ID_PRODUCT_FROM_DATABASE=ISP1020 Fast-wide SCSI
+
+pci:v00001077d00001022*
+ ID_PRODUCT_FROM_DATABASE=ISP1022 Fast-wide SCSI
+
+pci:v00001077d00001080*
+ ID_PRODUCT_FROM_DATABASE=ISP1080 SCSI Host Adapter
+
+pci:v00001077d00001216*
+ ID_PRODUCT_FROM_DATABASE=ISP12160 Dual Channel Ultra3 SCSI Processor
+
+pci:v00001077d00001216sv0000101Esd00008471*
+ ID_PRODUCT_FROM_DATABASE=QLA12160 on AMI MegaRAID
+
+pci:v00001077d00001216sv0000101Esd00008493*
+ ID_PRODUCT_FROM_DATABASE=QLA12160 on AMI MegaRAID
+
+pci:v00001077d00001240*
+ ID_PRODUCT_FROM_DATABASE=ISP1240 SCSI Host Adapter
+
+pci:v00001077d00001280*
+ ID_PRODUCT_FROM_DATABASE=ISP1280 SCSI Host Adapter
+
+pci:v00001077d00002020*
+ ID_PRODUCT_FROM_DATABASE=ISP2020A Fast!SCSI Basic Adapter
+
+pci:v00001077d00002100*
+ ID_PRODUCT_FROM_DATABASE=QLA2100 64-bit Fibre Channel Adapter
+
+pci:v00001077d00002100sv00001077sd00000001*
+ ID_PRODUCT_FROM_DATABASE=QLA2100 64-bit Fibre Channel Adapter
+
+pci:v00001077d00002200*
+ ID_PRODUCT_FROM_DATABASE=QLA2200 64-bit Fibre Channel Adapter
+
+pci:v00001077d00002200sv00001077sd00000002*
+ ID_PRODUCT_FROM_DATABASE=QLA2200
+
+pci:v00001077d00002300*
+ ID_PRODUCT_FROM_DATABASE=QLA2300 64-bit Fibre Channel Adapter
+
+pci:v00001077d00002312*
+ ID_PRODUCT_FROM_DATABASE=ISP2312-based 2Gb Fibre Channel to PCI-X HBA
+
+pci:v00001077d00002312sv0000103Csd00000131*
+ ID_PRODUCT_FROM_DATABASE=2Gb Fibre Channel - Single port [A7538A]
+
+pci:v00001077d00002312sv0000103Csd000012BA*
+ ID_PRODUCT_FROM_DATABASE=2Gb Fibre Channel - Dual port [A6826A]
+
+pci:v00001077d00002322*
+ ID_PRODUCT_FROM_DATABASE=ISP2322-based 2Gb Fibre Channel to PCI-X HBA
+
+pci:v00001077d00002422*
+ ID_PRODUCT_FROM_DATABASE=ISP2422-based 4Gb Fibre Channel to PCI-X HBA
+
+pci:v00001077d00002422sv0000103Csd000012D7*
+ ID_PRODUCT_FROM_DATABASE=4Gb Fibre Channel [AB379A]
+
+pci:v00001077d00002422sv0000103Csd000012DD*
+ ID_PRODUCT_FROM_DATABASE=4Gb Fibre Channel [AB429A]
+
+pci:v00001077d00002432*
+ ID_PRODUCT_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA
+
+pci:v00001077d00002532*
+ ID_PRODUCT_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA
+
+pci:v00001077d00002532sv00001077sd00000167*
+ ID_PRODUCT_FROM_DATABASE=QME2572 Dual Port FC8 HBA Mezzanine
+
+pci:v00001077d00003022*
+ ID_PRODUCT_FROM_DATABASE=ISP4022-based Ethernet NIC
+
+pci:v00001077d00003032*
+ ID_PRODUCT_FROM_DATABASE=ISP4032-based Ethernet IPv6 NIC
+
+pci:v00001077d00004010*
+ ID_PRODUCT_FROM_DATABASE=ISP4010-based iSCSI TOE HBA
+
+pci:v00001077d00004022*
+ ID_PRODUCT_FROM_DATABASE=ISP4022-based iSCSI TOE HBA
+
+pci:v00001077d00004032*
+ ID_PRODUCT_FROM_DATABASE=ISP4032-based iSCSI TOE IPv6 HBA
+
+pci:v00001077d00005432*
+ ID_PRODUCT_FROM_DATABASE=SP232-based 4Gb Fibre Channel to PCI Express HBA
+
+pci:v00001077d00006312*
+ ID_PRODUCT_FROM_DATABASE=SP202-based 2Gb Fibre Channel to PCI-X HBA
+
+pci:v00001077d00006322*
+ ID_PRODUCT_FROM_DATABASE=SP212-based 2Gb Fibre Channel to PCI-X HBA
+
+pci:v00001077d00007220*
+ ID_PRODUCT_FROM_DATABASE=IBA7220 InfiniBand HCA
+
+pci:v00001077d00007322*
+ ID_PRODUCT_FROM_DATABASE=IBA7322 QDR InfiniBand HCA
+
+pci:v00001077d00008000*
+ ID_PRODUCT_FROM_DATABASE=10GbE Converged Network Adapter (TCP/IP Networking)
+
+pci:v00001077d00008001*
+ ID_PRODUCT_FROM_DATABASE=10GbE Converged Network Adapter (FCoE)
+
+pci:v00001077d00008020*
+ ID_PRODUCT_FROM_DATABASE=cLOM8214 1/10GbE Controller
+
+pci:v00001077d00008020sv0000103Csd00003346*
+ ID_PRODUCT_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter
+
+pci:v00001077d00008020sv0000103Csd00003733*
+ ID_PRODUCT_FROM_DATABASE=NC523SFP 10Gb 2-port Server Adapter
+
+pci:v00001077d00008020sv00001077sd00000203*
+ ID_PRODUCT_FROM_DATABASE=8200 Series Single Port 10GbE Converged Network Adapter (TCP/IP Networking)
+
+pci:v00001077d00008020sv00001077sd00000207*
+ ID_PRODUCT_FROM_DATABASE=8200 Series Dual Port 10GbE Converged Network Adapter (TCP/IP Networking)
+
+pci:v00001077d00008020sv00001077sd0000020B*
+ ID_PRODUCT_FROM_DATABASE=3200 Series Dual Port 10Gb Intelligent Ethernet Adapter
+
+pci:v00001077d00008020sv00001077sd0000020C*
+ ID_PRODUCT_FROM_DATABASE=3200 Series Quad Port 1Gb Intelligent Ethernet Adapter
+
+pci:v00001077d00008020sv00001077sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=3200 Series Single Port 10Gb Intelligent Ethernet Adapter
+
+pci:v00001077d00008020sv00001077sd00000210*
+ ID_PRODUCT_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card
+
+pci:v00001077d00008021*
+ ID_PRODUCT_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (FCoE)
+
+pci:v00001077d00008021sv0000103Csd00003348*
+ ID_PRODUCT_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter
+
+pci:v00001077d00008021sv00001077sd00000211*
+ ID_PRODUCT_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card, FCoE
+
+pci:v00001077d00008022*
+ ID_PRODUCT_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (iSCSI)
+
+pci:v00001077d00008022sv0000103Csd00003347*
+ ID_PRODUCT_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter
+
+pci:v00001077d00008022sv00001077sd00000212*
+ ID_PRODUCT_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card, iSCSI
+
+pci:v00001077d00008432*
+ ID_PRODUCT_FROM_DATABASE=ISP2432M-based 10GbE Converged Network Adapter (CNA)
+
+pci:v00001078*
+ ID_VENDOR_FROM_DATABASE=Cyrix Corporation
+
+pci:v00001078d00000000*
+ ID_PRODUCT_FROM_DATABASE=5510 [Grappa]
+
+pci:v00001078d00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI Master
+
+pci:v00001078d00000002*
+ ID_PRODUCT_FROM_DATABASE=5520 [Cognac]
+
+pci:v00001078d00000100*
+ ID_PRODUCT_FROM_DATABASE=5530 Legacy [Kahlua]
+
+pci:v00001078d00000101*
+ ID_PRODUCT_FROM_DATABASE=5530 SMI [Kahlua]
+
+pci:v00001078d00000102*
+ ID_PRODUCT_FROM_DATABASE=5530 IDE [Kahlua]
+
+pci:v00001078d00000103*
+ ID_PRODUCT_FROM_DATABASE=5530 Audio [Kahlua]
+
+pci:v00001078d00000104*
+ ID_PRODUCT_FROM_DATABASE=5530 Video [Kahlua]
+
+pci:v00001078d00000400*
+ ID_PRODUCT_FROM_DATABASE=ZFMicro PCI Bridge
+
+pci:v00001078d00000401*
+ ID_PRODUCT_FROM_DATABASE=ZFMicro Chipset SMI
+
+pci:v00001078d00000402*
+ ID_PRODUCT_FROM_DATABASE=ZFMicro Chipset IDE
+
+pci:v00001078d00000403*
+ ID_PRODUCT_FROM_DATABASE=ZFMicro Expansion Bus
+
+pci:v00001079*
+ ID_VENDOR_FROM_DATABASE=I-Bus
+
+pci:v0000107A*
+ ID_VENDOR_FROM_DATABASE=NetWorth
+
+pci:v0000107B*
+ ID_VENDOR_FROM_DATABASE=Gateway 2000
+
+pci:v0000107C*
+ ID_VENDOR_FROM_DATABASE=LG Electronics [Lucky Goldstar Co. Ltd]
+
+pci:v0000107D*
+ ID_VENDOR_FROM_DATABASE=LeadTek Research Inc.
+
+pci:v0000107Dd00000000*
+ ID_PRODUCT_FROM_DATABASE=P86C850
+
+pci:v0000107Dd00002134*
+ ID_PRODUCT_FROM_DATABASE=WinFast 3D S320 II
+
+pci:v0000107Dd00006609*
+ ID_PRODUCT_FROM_DATABASE=Winfast TV 2000 XP RM
+
+pci:v0000107Dd00006654*
+ ID_PRODUCT_FROM_DATABASE=Conexant CX23883 [WinFast DTV1800 H]
+
+pci:v0000107Dd00006F22*
+ ID_PRODUCT_FROM_DATABASE=WinFast PxTV1200
+
+pci:v0000107Dd00006F34*
+ ID_PRODUCT_FROM_DATABASE=WinFast DVR3100 H
+
+pci:v0000107E*
+ ID_VENDOR_FROM_DATABASE=Interphase Corporation
+
+pci:v0000107Ed00000001*
+ ID_PRODUCT_FROM_DATABASE=5515 ATM Adapter [Flipper]
+
+pci:v0000107Ed00000002*
+ ID_PRODUCT_FROM_DATABASE=100 VG AnyLan Controller
+
+pci:v0000107Ed00000004*
+ ID_PRODUCT_FROM_DATABASE=5526 Fibre Channel Host Adapter
+
+pci:v0000107Ed00000005*
+ ID_PRODUCT_FROM_DATABASE=x526 Fibre Channel Host Adapter
+
+pci:v0000107Ed00000008*
+ ID_PRODUCT_FROM_DATABASE=5525/5575 ATM Adapter (155 Mbit) [Atlantic]
+
+pci:v0000107Ed00009003*
+ ID_PRODUCT_FROM_DATABASE=5535-4P-BRI-ST
+
+pci:v0000107Ed00009007*
+ ID_PRODUCT_FROM_DATABASE=5535-4P-BRI-U
+
+pci:v0000107Ed00009008*
+ ID_PRODUCT_FROM_DATABASE=5535-1P-SR
+
+pci:v0000107Ed0000900C*
+ ID_PRODUCT_FROM_DATABASE=5535-1P-SR-ST
+
+pci:v0000107Ed0000900E*
+ ID_PRODUCT_FROM_DATABASE=5535-1P-SR-U
+
+pci:v0000107Ed00009011*
+ ID_PRODUCT_FROM_DATABASE=5535-1P-PRI
+
+pci:v0000107Ed00009013*
+ ID_PRODUCT_FROM_DATABASE=5535-2P-PRI
+
+pci:v0000107Ed00009023*
+ ID_PRODUCT_FROM_DATABASE=5536-4P-BRI-ST
+
+pci:v0000107Ed00009027*
+ ID_PRODUCT_FROM_DATABASE=5536-4P-BRI-U
+
+pci:v0000107Ed00009031*
+ ID_PRODUCT_FROM_DATABASE=5536-1P-PRI
+
+pci:v0000107Ed00009033*
+ ID_PRODUCT_FROM_DATABASE=5536-2P-PRI
+
+pci:v0000107F*
+ ID_VENDOR_FROM_DATABASE=Data Technology Corporation
+
+pci:v0000107Fd00000802*
+ ID_PRODUCT_FROM_DATABASE=SL82C105
+
+pci:v00001080*
+ ID_VENDOR_FROM_DATABASE=Contaq Microsystems
+
+pci:v00001080d00000600*
+ ID_PRODUCT_FROM_DATABASE=82C599
+
+pci:v00001080d0000C691*
+ ID_PRODUCT_FROM_DATABASE=Cypress CY82C691
+
+pci:v00001080d0000C693*
+ ID_PRODUCT_FROM_DATABASE=82c693
+
+pci:v00001081*
+ ID_VENDOR_FROM_DATABASE=Supermac Technology
+
+pci:v00001081d00000D47*
+ ID_PRODUCT_FROM_DATABASE=Radius PCI to NuBUS Bridge
+
+pci:v00001082*
+ ID_VENDOR_FROM_DATABASE=EFA Corporation of America
+
+pci:v00001083*
+ ID_VENDOR_FROM_DATABASE=Forex Computer Corporation
+
+pci:v00001083d00000001*
+ ID_PRODUCT_FROM_DATABASE=FR710
+
+pci:v00001084*
+ ID_VENDOR_FROM_DATABASE=Parador
+
+pci:v00001085*
+ ID_VENDOR_FROM_DATABASE=Tulip Computers Int.B.V.
+
+pci:v00001086*
+ ID_VENDOR_FROM_DATABASE=J. Bond Computer Systems
+
+pci:v00001087*
+ ID_VENDOR_FROM_DATABASE=Cache Computer
+
+pci:v00001088*
+ ID_VENDOR_FROM_DATABASE=Microcomputer Systems (M) Son
+
+pci:v00001089*
+ ID_VENDOR_FROM_DATABASE=Data General Corporation
+
+pci:v0000108A*
+ ID_VENDOR_FROM_DATABASE=SBS Technologies
+
+pci:v0000108Ad00000001*
+ ID_PRODUCT_FROM_DATABASE=VME Bridge Model 617
+
+pci:v0000108Ad00000010*
+ ID_PRODUCT_FROM_DATABASE=VME Bridge Model 618
+
+pci:v0000108Ad00000040*
+ ID_PRODUCT_FROM_DATABASE=dataBLIZZARD
+
+pci:v0000108Ad00003000*
+ ID_PRODUCT_FROM_DATABASE=VME Bridge Model 2706
+
+pci:v0000108C*
+ ID_VENDOR_FROM_DATABASE=Oakleigh Systems Inc.
+
+pci:v0000108D*
+ ID_VENDOR_FROM_DATABASE=Olicom
+
+pci:v0000108Dd00000001*
+ ID_PRODUCT_FROM_DATABASE=Token-Ring 16/4 PCI Adapter (3136/3137)
+
+pci:v0000108Dd00000002*
+ ID_PRODUCT_FROM_DATABASE=16/4 Token Ring
+
+pci:v0000108Dd00000004*
+ ID_PRODUCT_FROM_DATABASE=RapidFire 3139 Token-Ring 16/4 PCI Adapter
+
+pci:v0000108Dd00000004sv0000108Dsd00000004*
+ ID_PRODUCT_FROM_DATABASE=OC-3139/3140 RapidFire Token-Ring 16/4 Adapter
+
+pci:v0000108Dd00000005*
+ ID_PRODUCT_FROM_DATABASE=GoCard 3250 Token-Ring 16/4 CardBus PC Card
+
+pci:v0000108Dd00000006*
+ ID_PRODUCT_FROM_DATABASE=OC-3530 RapidFire Token-Ring 100
+
+pci:v0000108Dd00000007*
+ ID_PRODUCT_FROM_DATABASE=RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter
+
+pci:v0000108Dd00000007sv0000108Dsd00000007*
+ ID_PRODUCT_FROM_DATABASE=OC-3141 RapidFire Token-Ring 16/4 Adapter
+
+pci:v0000108Dd00000008*
+ ID_PRODUCT_FROM_DATABASE=RapidFire 3540 HSTR 100/16/4 PCI Adapter
+
+pci:v0000108Dd00000008sv0000108Dsd00000008*
+ ID_PRODUCT_FROM_DATABASE=OC-3540 RapidFire HSTR 100/16/4 Adapter
+
+pci:v0000108Dd00000011*
+ ID_PRODUCT_FROM_DATABASE=OC-2315
+
+pci:v0000108Dd00000012*
+ ID_PRODUCT_FROM_DATABASE=OC-2325
+
+pci:v0000108Dd00000013*
+ ID_PRODUCT_FROM_DATABASE=OC-2183/2185
+
+pci:v0000108Dd00000014*
+ ID_PRODUCT_FROM_DATABASE=OC-2326
+
+pci:v0000108Dd00000019*
+ ID_PRODUCT_FROM_DATABASE=OC-2327/2250 10/100 Ethernet Adapter
+
+pci:v0000108Dd00000019sv0000108Dsd00000016*
+ ID_PRODUCT_FROM_DATABASE=OC-2327 Rapidfire 10/100 Ethernet Adapter
+
+pci:v0000108Dd00000019sv0000108Dsd00000017*
+ ID_PRODUCT_FROM_DATABASE=OC-2250 GoCard 10/100 Ethernet Adapter
+
+pci:v0000108Dd00000021*
+ ID_PRODUCT_FROM_DATABASE=OC-6151/6152 [RapidFire ATM 155]
+
+pci:v0000108Dd00000022*
+ ID_PRODUCT_FROM_DATABASE=ATM Adapter
+
+pci:v0000108E*
+ ID_VENDOR_FROM_DATABASE=Oracle/SUN
+
+pci:v0000108Ed00000001*
+ ID_PRODUCT_FROM_DATABASE=EBUS
+
+pci:v0000108Ed00001000*
+ ID_PRODUCT_FROM_DATABASE=EBUS
+
+pci:v0000108Ed00001001*
+ ID_PRODUCT_FROM_DATABASE=Happy Meal 10/100 Ethernet [hme]
+
+pci:v0000108Ed00001100*
+ ID_PRODUCT_FROM_DATABASE=RIO EBUS
+
+pci:v0000108Ed00001100sv0000108Esd00001100*
+ ID_PRODUCT_FROM_DATABASE=RIO EBUS on Blade 100 motherboard
+
+pci:v0000108Ed00001101*
+ ID_PRODUCT_FROM_DATABASE=RIO 10/100 Ethernet [eri]
+
+pci:v0000108Ed00001101sv0000108Esd00001101*
+ ID_PRODUCT_FROM_DATABASE=RIO GEM on Blade 100 motherboard
+
+pci:v0000108Ed00001102*
+ ID_PRODUCT_FROM_DATABASE=RIO 1394
+
+pci:v0000108Ed00001102sv0000108Esd00001102*
+ ID_PRODUCT_FROM_DATABASE=RIO 1394 on Blade 100 motherboard
+
+pci:v0000108Ed00001103*
+ ID_PRODUCT_FROM_DATABASE=RIO USB
+
+pci:v0000108Ed00001103sv0000108Esd00001103*
+ ID_PRODUCT_FROM_DATABASE=RIO USB on Blade 100 motherboard
+
+pci:v0000108Ed00001647*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge]
+
+pci:v0000108Ed00001648*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge]
+
+pci:v0000108Ed000016A7*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge]
+
+pci:v0000108Ed000016A8*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge]
+
+pci:v0000108Ed00002BAD*
+ ID_PRODUCT_FROM_DATABASE=GEM 10/100/1000 Ethernet [ge]
+
+pci:v0000108Ed00005000*
+ ID_PRODUCT_FROM_DATABASE=Simba Advanced PCI Bridge
+
+pci:v0000108Ed00005000sv0000108Esd00005000*
+ ID_PRODUCT_FROM_DATABASE=Netra AX1105-500
+
+pci:v0000108Ed00005043*
+ ID_PRODUCT_FROM_DATABASE=SunPCI Co-processor
+
+pci:v0000108Ed00005CA0*
+ ID_PRODUCT_FROM_DATABASE=Crypto Accelerator 6000 [mca]
+
+pci:v0000108Ed00006300*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006301*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006302*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006303*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006310*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006311*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006312*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006313*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006320*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006323*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006330*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006331*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006332*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006333*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006340*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006343*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006350*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006353*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed00006722*
+ ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554]
+
+pci:v0000108Ed0000676E*
+ ID_PRODUCT_FROM_DATABASE=SunPCiIII
+
+pci:v0000108Ed00007063*
+ ID_PRODUCT_FROM_DATABASE=SunPCiII / SunPCiIIpro
+
+pci:v0000108Ed00008000*
+ ID_PRODUCT_FROM_DATABASE=Psycho PCI Bus Module
+
+pci:v0000108Ed00008001*
+ ID_PRODUCT_FROM_DATABASE=Schizo PCI Bus Module
+
+pci:v0000108Ed00008002*
+ ID_PRODUCT_FROM_DATABASE=Schizo+ PCI Bus Module
+
+pci:v0000108Ed000080F0*
+ ID_PRODUCT_FROM_DATABASE=PCIe switch [px]
+
+pci:v0000108Ed000080F8*
+ ID_PRODUCT_FROM_DATABASE=PCIe switch [px]
+
+pci:v0000108Ed00009010*
+ ID_PRODUCT_FROM_DATABASE=PCIe/PCI bridge switch [pxb_plx]
+
+pci:v0000108Ed00009020*
+ ID_PRODUCT_FROM_DATABASE=PCIe/PCI bridge switch [pxb_plx]
+
+pci:v0000108Ed00009102*
+ ID_PRODUCT_FROM_DATABASE=Davicom Fast Ethernet driver for Davicom DM9102A [dmfe]
+
+pci:v0000108Ed0000A000*
+ ID_PRODUCT_FROM_DATABASE=Psycho UPA-PCI Bus Module [pcipsy]
+
+pci:v0000108Ed0000A001*
+ ID_PRODUCT_FROM_DATABASE=Psycho UPA-PCI Bus Module [pcipsy]
+
+pci:v0000108Ed0000A001sv0000108Esd0000A001*
+ ID_PRODUCT_FROM_DATABASE=Ultra IIe on Blade 100 motherboard
+
+pci:v0000108Ed0000A801*
+ ID_PRODUCT_FROM_DATABASE=Schizo Fireplane-PCI bus bridge module [pcisch]
+
+pci:v0000108Ed0000AAAA*
+ ID_PRODUCT_FROM_DATABASE=Multithreaded Shared 10GbE Ethernet Network Controller
+
+pci:v0000108Ed0000ABBA*
+ ID_PRODUCT_FROM_DATABASE=Cassini 10/100/1000
+
+pci:v0000108Ed0000ABCD*
+ ID_PRODUCT_FROM_DATABASE=Multithreaded 10-Gigabit Ethernet Network Controller
+
+pci:v0000108Ed0000C416*
+ ID_PRODUCT_FROM_DATABASE=Sun Fire System/System Controller Interface chip [sbbc]
+
+pci:v0000108F*
+ ID_VENDOR_FROM_DATABASE=Systemsoft
+
+pci:v00001090*
+ ID_VENDOR_FROM_DATABASE=Compro Computer Services, Inc.
+
+pci:v00001090d00004610*
+ ID_PRODUCT_FROM_DATABASE=PCI RTOM
+
+pci:v00001090d00004620*
+ ID_PRODUCT_FROM_DATABASE=GPIO HSD
+
+pci:v00001091*
+ ID_VENDOR_FROM_DATABASE=Intergraph Corporation
+
+pci:v00001091d00000020*
+ ID_PRODUCT_FROM_DATABASE=3D graphics processor
+
+pci:v00001091d00000021*
+ ID_PRODUCT_FROM_DATABASE=3D graphics processor w/Texturing
+
+pci:v00001091d00000040*
+ ID_PRODUCT_FROM_DATABASE=3D graphics frame buffer
+
+pci:v00001091d00000041*
+ ID_PRODUCT_FROM_DATABASE=3D graphics frame buffer
+
+pci:v00001091d00000060*
+ ID_PRODUCT_FROM_DATABASE=Proprietary bus bridge
+
+pci:v00001091d000000E4*
+ ID_PRODUCT_FROM_DATABASE=Powerstorm 4D50T
+
+pci:v00001091d00000720*
+ ID_PRODUCT_FROM_DATABASE=Motion JPEG codec
+
+pci:v00001091d00000780*
+ ID_PRODUCT_FROM_DATABASE=Intense3D Wildcat 3410 (MSMT496)
+
+pci:v00001091d000007A0*
+ ID_PRODUCT_FROM_DATABASE=Sun Expert3D-Lite Graphics Accelerator
+
+pci:v00001091d00001091*
+ ID_PRODUCT_FROM_DATABASE=Sun Expert3D Graphics Accelerator
+
+pci:v00001092*
+ ID_VENDOR_FROM_DATABASE=Diamond Multimedia Systems
+
+pci:v00001092d00000028*
+ ID_PRODUCT_FROM_DATABASE=Viper V770
+
+pci:v00001092d00000028sv00001092sd00004A00*
+ ID_PRODUCT_FROM_DATABASE=Viper V770 32MB
+
+pci:v00001092d000000A0*
+ ID_PRODUCT_FROM_DATABASE=Speedstar Pro SE
+
+pci:v00001092d000000A8*
+ ID_PRODUCT_FROM_DATABASE=Speedstar 64
+
+pci:v00001092d00000550*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v00001092d000008D4*
+ ID_PRODUCT_FROM_DATABASE=Supra 2260 Modem
+
+pci:v00001092d0000094C*
+ ID_PRODUCT_FROM_DATABASE=SupraExpress 56i Pro
+
+pci:v00001092d00001001*
+ ID_PRODUCT_FROM_DATABASE=Video Crunch It 1001 capture card
+
+pci:v00001092d00001092*
+ ID_PRODUCT_FROM_DATABASE=Viper V330
+
+pci:v00001092d00006120*
+ ID_PRODUCT_FROM_DATABASE=Maximum DVD
+
+pci:v00001092d00008810*
+ ID_PRODUCT_FROM_DATABASE=Stealth SE
+
+pci:v00001092d00008811*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64/SE
+
+pci:v00001092d00008880*
+ ID_PRODUCT_FROM_DATABASE=Stealth
+
+pci:v00001092d00008881*
+ ID_PRODUCT_FROM_DATABASE=Stealth
+
+pci:v00001092d000088B0*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64
+
+pci:v00001092d000088B1*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64
+
+pci:v00001092d000088C0*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64
+
+pci:v00001092d000088C1*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64
+
+pci:v00001092d000088D0*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64
+
+pci:v00001092d000088D1*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64
+
+pci:v00001092d000088F0*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64
+
+pci:v00001092d000088F1*
+ ID_PRODUCT_FROM_DATABASE=Stealth 64
+
+pci:v00001092d00009999*
+ ID_PRODUCT_FROM_DATABASE=DMD-I0928-1 "Monster sound" sound chip
+
+pci:v00001093*
+ ID_VENDOR_FROM_DATABASE=National Instruments
+
+pci:v00001093d00000160*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-96
+
+pci:v00001093d00000162*
+ ID_PRODUCT_FROM_DATABASE=PCI-MIO-16XE-50
+
+pci:v00001093d00001150*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-32HS High Speed Digital I/O Board
+
+pci:v00001093d00001170*
+ ID_PRODUCT_FROM_DATABASE=PCI-MIO-16XE-10
+
+pci:v00001093d00001180*
+ ID_PRODUCT_FROM_DATABASE=PCI-MIO-16E-1
+
+pci:v00001093d00001190*
+ ID_PRODUCT_FROM_DATABASE=PCI-MIO-16E-4
+
+pci:v00001093d000011B0*
+ ID_PRODUCT_FROM_DATABASE=PXI-6070E
+
+pci:v00001093d000011C0*
+ ID_PRODUCT_FROM_DATABASE=PXI-6040e
+
+pci:v00001093d000011D0*
+ ID_PRODUCT_FROM_DATABASE=PXI-6030e
+
+pci:v00001093d00001270*
+ ID_PRODUCT_FROM_DATABASE=PCI-6032e
+
+pci:v00001093d00001310*
+ ID_PRODUCT_FROM_DATABASE=PCI-6602
+
+pci:v00001093d00001330*
+ ID_PRODUCT_FROM_DATABASE=PCI-6031E
+
+pci:v00001093d00001340*
+ ID_PRODUCT_FROM_DATABASE=PCI-6033e
+
+pci:v00001093d00001350*
+ ID_PRODUCT_FROM_DATABASE=PCI-6071E
+
+pci:v00001093d00001360*
+ ID_PRODUCT_FROM_DATABASE=PXI-6602
+
+pci:v00001093d000014E0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6110
+
+pci:v00001093d000014F0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6111
+
+pci:v00001093d00001580*
+ ID_PRODUCT_FROM_DATABASE=PXI-6031E
+
+pci:v00001093d000015B0*
+ ID_PRODUCT_FROM_DATABASE=PXI-6071E
+
+pci:v00001093d00001710*
+ ID_PRODUCT_FROM_DATABASE=PXI-6509
+
+pci:v00001093d000017D0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6503
+
+pci:v00001093d00001870*
+ ID_PRODUCT_FROM_DATABASE=PCI-6713
+
+pci:v00001093d00001880*
+ ID_PRODUCT_FROM_DATABASE=PCI-6711
+
+pci:v00001093d000018B0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6052E
+
+pci:v00001093d000018C0*
+ ID_PRODUCT_FROM_DATABASE=PXI-6052E
+
+pci:v00001093d00002410*
+ ID_PRODUCT_FROM_DATABASE=PCI-6733
+
+pci:v00001093d00002420*
+ ID_PRODUCT_FROM_DATABASE=PXI-6733
+
+pci:v00001093d00002430*
+ ID_PRODUCT_FROM_DATABASE=PCI-6731
+
+pci:v00001093d00002880*
+ ID_PRODUCT_FROM_DATABASE=DAQCard-6601
+
+pci:v00001093d00002890*
+ ID_PRODUCT_FROM_DATABASE=PCI-6036E
+
+pci:v00001093d000028C0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6014
+
+pci:v00001093d00002A60*
+ ID_PRODUCT_FROM_DATABASE=PCI-6023E
+
+pci:v00001093d00002A70*
+ ID_PRODUCT_FROM_DATABASE=PCI-6024E
+
+pci:v00001093d00002A80*
+ ID_PRODUCT_FROM_DATABASE=PCI-6025E
+
+pci:v00001093d00002AB0*
+ ID_PRODUCT_FROM_DATABASE=PXI-6025e
+
+pci:v00001093d00002B80*
+ ID_PRODUCT_FROM_DATABASE=PXI-6713
+
+pci:v00001093d00002B90*
+ ID_PRODUCT_FROM_DATABASE=PXI-6711
+
+pci:v00001093d00002C60*
+ ID_PRODUCT_FROM_DATABASE=PCI-6601
+
+pci:v00001093d00002C70*
+ ID_PRODUCT_FROM_DATABASE=PXI-6601
+
+pci:v00001093d00002C80*
+ ID_PRODUCT_FROM_DATABASE=PCI-6035E
+
+pci:v00001093d00002CA0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6034E
+
+pci:v00001093d00002CC0*
+ ID_PRODUCT_FROM_DATABASE=PXI-6608
+
+pci:v00001093d00002DB0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6608
+
+pci:v00001093d000070A9*
+ ID_PRODUCT_FROM_DATABASE=PCI-6528 (Digital I/O at 60V)
+
+pci:v00001093d000070AA*
+ ID_PRODUCT_FROM_DATABASE=PCI-6229
+
+pci:v00001093d000070AB*
+ ID_PRODUCT_FROM_DATABASE=PCI-6259
+
+pci:v00001093d000070AC*
+ ID_PRODUCT_FROM_DATABASE=PCI-6289
+
+pci:v00001093d000070AE*
+ ID_PRODUCT_FROM_DATABASE=PXI-6220
+
+pci:v00001093d000070AF*
+ ID_PRODUCT_FROM_DATABASE=PCI-6221
+
+pci:v00001093d000070B0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6220
+
+pci:v00001093d000070B4*
+ ID_PRODUCT_FROM_DATABASE=PCI-6250
+
+pci:v00001093d000070B6*
+ ID_PRODUCT_FROM_DATABASE=PCI-6280
+
+pci:v00001093d000070B7*
+ ID_PRODUCT_FROM_DATABASE=PCI-6254
+
+pci:v00001093d000070B8*
+ ID_PRODUCT_FROM_DATABASE=PCI-6251 [M Series - High Speed Multifunction DAQ]
+
+pci:v00001093d000070BC*
+ ID_PRODUCT_FROM_DATABASE=PCI-6284
+
+pci:v00001093d000070BD*
+ ID_PRODUCT_FROM_DATABASE=PCI-6281
+
+pci:v00001093d000070BF*
+ ID_PRODUCT_FROM_DATABASE=PXI-6281
+
+pci:v00001093d000070C0*
+ ID_PRODUCT_FROM_DATABASE=PCI-6143
+
+pci:v00001093d000070F2*
+ ID_PRODUCT_FROM_DATABASE=PCI-6224
+
+pci:v00001093d00007144*
+ ID_PRODUCT_FROM_DATABASE=PXI-5124 (12-bit 200 MS/s Digitizer)
+
+pci:v00001093d0000716C*
+ ID_PRODUCT_FROM_DATABASE=PCI-6225
+
+pci:v00001093d0000717D*
+ ID_PRODUCT_FROM_DATABASE=PCIE-6251
+
+pci:v00001093d0000717F*
+ ID_PRODUCT_FROM_DATABASE=PCIe-6259
+
+pci:v00001093d000071BC*
+ ID_PRODUCT_FROM_DATABASE=PCI-6221 (37pin)
+
+pci:v00001093d000071D0*
+ ID_PRODUCT_FROM_DATABASE=PXI-6143
+
+pci:v00001093d0000B001*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1408
+
+pci:v00001093d0000B011*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PXI-1408
+
+pci:v00001093d0000B021*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1424
+
+pci:v00001093d0000B031*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1413
+
+pci:v00001093d0000B041*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1407
+
+pci:v00001093d0000B051*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PXI-1407
+
+pci:v00001093d0000B061*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1411
+
+pci:v00001093d0000B071*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1422
+
+pci:v00001093d0000B081*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PXI-1422
+
+pci:v00001093d0000B091*
+ ID_PRODUCT_FROM_DATABASE=IMAQ-PXI-1411
+
+pci:v00001093d0000C4C4*
+ ID_PRODUCT_FROM_DATABASE=PXIe-4353
+
+pci:v00001093d0000C801*
+ ID_PRODUCT_FROM_DATABASE=PCI-GPIB
+
+pci:v00001093d0000C831*
+ ID_PRODUCT_FROM_DATABASE=PCI-GPIB bridge
+
+pci:v00001094*
+ ID_VENDOR_FROM_DATABASE=First International Computers [FIC]
+
+pci:v00001095*
+ ID_VENDOR_FROM_DATABASE=Silicon Image, Inc.
+
+pci:v00001095d00000240*
+ ID_PRODUCT_FROM_DATABASE=Adaptec AAR-1210SA SATA HostRAID Controller
+
+pci:v00001095d00000640*
+ ID_PRODUCT_FROM_DATABASE=PCI0640
+
+pci:v00001095d00000643*
+ ID_PRODUCT_FROM_DATABASE=PCI0643
+
+pci:v00001095d00000646*
+ ID_PRODUCT_FROM_DATABASE=PCI0646
+
+pci:v00001095d00000647*
+ ID_PRODUCT_FROM_DATABASE=PCI0647
+
+pci:v00001095d00000648*
+ ID_PRODUCT_FROM_DATABASE=PCI0648
+
+pci:v00001095d00000648sv00001043sd00008025*
+ ID_PRODUCT_FROM_DATABASE=CUBX motherboard
+
+pci:v00001095d00000649*
+ ID_PRODUCT_FROM_DATABASE=SiI 0649 Ultra ATA/100 PCI to ATA Host Controller
+
+pci:v00001095d00000649sv00000E11sd0000005D*
+ ID_PRODUCT_FROM_DATABASE=Integrated Ultra ATA-100 Dual Channel Controller
+
+pci:v00001095d00000649sv00000E11sd0000007E*
+ ID_PRODUCT_FROM_DATABASE=Integrated Ultra ATA-100 IDE RAID Controller
+
+pci:v00001095d00000649sv0000101Esd00000649*
+ ID_PRODUCT_FROM_DATABASE=AMI MegaRAID IDE 100 Controller
+
+pci:v00001095d00000650*
+ ID_PRODUCT_FROM_DATABASE=PBC0650A
+
+pci:v00001095d00000670*
+ ID_PRODUCT_FROM_DATABASE=USB0670
+
+pci:v00001095d00000670sv00001095sd00000670*
+ ID_PRODUCT_FROM_DATABASE=USB0670
+
+pci:v00001095d00000673*
+ ID_PRODUCT_FROM_DATABASE=USB0673
+
+pci:v00001095d00000680*
+ ID_PRODUCT_FROM_DATABASE=PCI0680 Ultra ATA-133 Host Controller
+
+pci:v00001095d00000680sv00001095sd00000680*
+ ID_PRODUCT_FROM_DATABASE=SiI 0680 ATA/133 Controller
+
+pci:v00001095d00000680sv00001095sd00003680*
+ ID_PRODUCT_FROM_DATABASE=Winic W-680 (Silicon Image 680 based)
+
+pci:v00001095d00003112*
+ ID_PRODUCT_FROM_DATABASE=SiI 3112 [SATALink/SATARaid] Serial ATA Controller
+
+pci:v00001095d00003112sv00001095sd00003112*
+ ID_PRODUCT_FROM_DATABASE=SiI 3112 SATALink Controller
+
+pci:v00001095d00003112sv00001095sd00006112*
+ ID_PRODUCT_FROM_DATABASE=SiI 3112 SATARaid Controller
+
+pci:v00001095d00003112sv00009005sd00000250*
+ ID_PRODUCT_FROM_DATABASE=SATAConnect 1205SA Host Controller
+
+pci:v00001095d00003114*
+ ID_PRODUCT_FROM_DATABASE=SiI 3114 [SATALink/SATARaid] Serial ATA Controller
+
+pci:v00001095d00003114sv00001095sd00003114*
+ ID_PRODUCT_FROM_DATABASE=SiI 3114 SATALink Controller
+
+pci:v00001095d00003114sv00001095sd00006114*
+ ID_PRODUCT_FROM_DATABASE=SiI 3114 SATARaid Controller
+
+pci:v00001095d00003124*
+ ID_PRODUCT_FROM_DATABASE=SiI 3124 PCI-X Serial ATA Controller
+
+pci:v00001095d00003124sv00001095sd00003124*
+ ID_PRODUCT_FROM_DATABASE=SiI 3124 PCI-X Serial ATA Controller
+
+pci:v00001095d00003132*
+ ID_PRODUCT_FROM_DATABASE=SiI 3132 Serial ATA Raid II Controller
+
+pci:v00001095d00003512*
+ ID_PRODUCT_FROM_DATABASE=SiI 3512 [SATALink/SATARaid] Serial ATA Controller
+
+pci:v00001095d00003512sv00001095sd00003512*
+ ID_PRODUCT_FROM_DATABASE=SiI 3512 SATALink Controller
+
+pci:v00001095d00003512sv00001095sd00006512*
+ ID_PRODUCT_FROM_DATABASE=SiI 3512 SATARaid Controller
+
+pci:v00001095d00003531*
+ ID_PRODUCT_FROM_DATABASE=SiI 3531 [SATALink/SATARaid] Serial ATA Controller
+
+pci:v00001096*
+ ID_VENDOR_FROM_DATABASE=Alacron
+
+pci:v00001097*
+ ID_VENDOR_FROM_DATABASE=Appian Technology
+
+pci:v00001098*
+ ID_VENDOR_FROM_DATABASE=Quantum Designs (H.K.) Ltd
+
+pci:v00001098d00000001*
+ ID_PRODUCT_FROM_DATABASE=QD-8500
+
+pci:v00001098d00000002*
+ ID_PRODUCT_FROM_DATABASE=QD-8580
+
+pci:v00001099*
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics Co., Ltd
+
+pci:v0000109A*
+ ID_VENDOR_FROM_DATABASE=Packard Bell
+
+pci:v0000109B*
+ ID_VENDOR_FROM_DATABASE=Gemlight Computer Ltd.
+
+pci:v0000109C*
+ ID_VENDOR_FROM_DATABASE=Megachips Corporation
+
+pci:v0000109D*
+ ID_VENDOR_FROM_DATABASE=Zida Technologies Ltd.
+
+pci:v0000109E*
+ ID_VENDOR_FROM_DATABASE=Brooktree Corporation
+
+pci:v0000109Ed00000310*
+ ID_PRODUCT_FROM_DATABASE=Bt848 Video Capture
+
+pci:v0000109Ed0000032E*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture
+
+pci:v0000109Ed00000350*
+ ID_PRODUCT_FROM_DATABASE=Bt848 Video Capture
+
+pci:v0000109Ed00000351*
+ ID_PRODUCT_FROM_DATABASE=Bt849A Video capture
+
+pci:v0000109Ed00000369*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture
+
+pci:v0000109Ed00000369sv00001002sd00000001*
+ ID_PRODUCT_FROM_DATABASE=TV-Wonder
+
+pci:v0000109Ed00000369sv00001002sd00000003*
+ ID_PRODUCT_FROM_DATABASE=TV-Wonder/VE
+
+pci:v0000109Ed0000036C*
+ ID_PRODUCT_FROM_DATABASE=Bt879(??) Video Capture
+
+pci:v0000109Ed0000036Csv000013E9sd00000070*
+ ID_PRODUCT_FROM_DATABASE=Win/TV (Video Section)
+
+pci:v0000109Ed0000036E*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture
+
+pci:v0000109Ed0000036Esv00000070sd000013EB*
+ ID_PRODUCT_FROM_DATABASE=WinTV Series
+
+pci:v0000109Ed0000036Esv00000070sd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=Viewcast Osprey 200
+
+pci:v0000109Ed0000036Esv00000071sd00000101*
+ ID_PRODUCT_FROM_DATABASE=DigiTV PCI
+
+pci:v0000109Ed0000036Esv0000107Dsd00006606*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV 2000
+
+pci:v0000109Ed0000036Esv000011BDsd00000012*
+ ID_PRODUCT_FROM_DATABASE=PCTV pro (TV + FM stereo receiver)
+
+pci:v0000109Ed0000036Esv000011BDsd0000001C*
+ ID_PRODUCT_FROM_DATABASE=PCTV Sat (DBC receiver)
+
+pci:v0000109Ed0000036Esv0000127Asd00000001*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Mediastream Controller NTSC
+
+pci:v0000109Ed0000036Esv0000127Asd00000002*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Mediastream Controller PAL BG
+
+pci:v0000109Ed0000036Esv0000127Asd00000003*
+ ID_PRODUCT_FROM_DATABASE=Bt878a Mediastream Controller PAL BG
+
+pci:v0000109Ed0000036Esv0000127Asd00000048*
+ ID_PRODUCT_FROM_DATABASE=Bt878/832 Mediastream Controller
+
+pci:v0000109Ed0000036Esv0000144Fsd00003000*
+ ID_PRODUCT_FROM_DATABASE=MagicTView CPH060 - Video
+
+pci:v0000109Ed0000036Esv00001461sd00000002*
+ ID_PRODUCT_FROM_DATABASE=TV98 Series (TV/No FM/Remote)
+
+pci:v0000109Ed0000036Esv00001461sd00000003*
+ ID_PRODUCT_FROM_DATABASE=AverMedia UltraTV PCI 350
+
+pci:v0000109Ed0000036Esv00001461sd00000004*
+ ID_PRODUCT_FROM_DATABASE=AVerTV WDM Video Capture
+
+pci:v0000109Ed0000036Esv00001461sd00000761*
+ ID_PRODUCT_FROM_DATABASE=AverTV DVB-T
+
+pci:v0000109Ed0000036Esv00001461sd00000771*
+ ID_PRODUCT_FROM_DATABASE=AverMedia AVerTV DVB-T 771
+
+pci:v0000109Ed0000036Esv000014F1sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Mediastream Controller NTSC
+
+pci:v0000109Ed0000036Esv000014F1sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Mediastream Controller PAL BG
+
+pci:v0000109Ed0000036Esv000014F1sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Bt878a Mediastream Controller PAL BG
+
+pci:v0000109Ed0000036Esv000014F1sd00000048*
+ ID_PRODUCT_FROM_DATABASE=Bt878/832 Mediastream Controller
+
+pci:v0000109Ed0000036Esv00001822sd00000001*
+ ID_PRODUCT_FROM_DATABASE=VisionPlus DVB card
+
+pci:v0000109Ed0000036Esv00001851sd00001850*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo'98 - Video
+
+pci:v0000109Ed0000036Esv00001851sd00001851*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo II
+
+pci:v0000109Ed0000036Esv00001852sd00001852*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo'98 - Video (with FM Tuner)
+
+pci:v0000109Ed0000036Esv000018ACsd0000D500*
+ ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV5 Lite
+
+pci:v0000109Ed0000036Esv0000270Fsd0000FC00*
+ ID_PRODUCT_FROM_DATABASE=Digitop DTT-1000
+
+pci:v0000109Ed0000036Esv0000BD11sd00001200*
+ ID_PRODUCT_FROM_DATABASE=PCTV pro (TV + FM stereo receiver)
+
+pci:v0000109Ed0000036F*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture
+
+pci:v0000109Ed0000036Fsv0000127Asd00000044*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv0000127Asd00000122*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL I
+
+pci:v0000109Ed0000036Fsv0000127Asd00000144*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv0000127Asd00000222*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL BG
+
+pci:v0000109Ed0000036Fsv0000127Asd00000244*
+ ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv0000127Asd00000322*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv0000127Asd00000422*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv0000127Asd00001122*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL I
+
+pci:v0000109Ed0000036Fsv0000127Asd00001222*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL BG
+
+pci:v0000109Ed0000036Fsv0000127Asd00001322*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv0000127Asd00001522*
+ ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture PAL I
+
+pci:v0000109Ed0000036Fsv0000127Asd00001622*
+ ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture PAL BG
+
+pci:v0000109Ed0000036Fsv0000127Asd00001722*
+ ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv000014F1sd00000044*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv000014F1sd00000122*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL I
+
+pci:v0000109Ed0000036Fsv000014F1sd00000144*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv000014F1sd00000222*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL BG
+
+pci:v0000109Ed0000036Fsv000014F1sd00000244*
+ ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv000014F1sd00000322*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv000014F1sd00000422*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv000014F1sd00001122*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL I
+
+pci:v0000109Ed0000036Fsv000014F1sd00001222*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL BG
+
+pci:v0000109Ed0000036Fsv000014F1sd00001322*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv000014F1sd00001522*
+ ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture PAL I
+
+pci:v0000109Ed0000036Fsv000014F1sd00001622*
+ ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture PAL BG
+
+pci:v0000109Ed0000036Fsv000014F1sd00001722*
+ ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture NTSC
+
+pci:v0000109Ed0000036Fsv00001851sd00001850*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo'98 - Video
+
+pci:v0000109Ed0000036Fsv00001851sd00001851*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo II
+
+pci:v0000109Ed0000036Fsv00001852sd00001852*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo'98 - Video (with FM Tuner)
+
+pci:v0000109Ed00000370*
+ ID_PRODUCT_FROM_DATABASE=Bt880 Video Capture
+
+pci:v0000109Ed00000370sv00001851sd00001850*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo'98
+
+pci:v0000109Ed00000370sv00001851sd00001851*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo'98 EZ - video
+
+pci:v0000109Ed00000370sv00001852sd00001852*
+ ID_PRODUCT_FROM_DATABASE=FlyVideo'98 (with FM Tuner)
+
+pci:v0000109Ed00000878*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Audio Capture
+
+pci:v0000109Ed00000878sv00000070sd000013EB*
+ ID_PRODUCT_FROM_DATABASE=WinTV Series
+
+pci:v0000109Ed00000878sv00000070sd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=Viewcast Osprey 200
+
+pci:v0000109Ed00000878sv00000071sd00000101*
+ ID_PRODUCT_FROM_DATABASE=DigiTV PCI
+
+pci:v0000109Ed00000878sv00001002sd00000001*
+ ID_PRODUCT_FROM_DATABASE=TV-Wonder
+
+pci:v0000109Ed00000878sv00001002sd00000003*
+ ID_PRODUCT_FROM_DATABASE=TV-Wonder/VE
+
+pci:v0000109Ed00000878sv000011BDsd00000012*
+ ID_PRODUCT_FROM_DATABASE=PCTV pro (TV + FM stereo receiver, audio section)
+
+pci:v0000109Ed00000878sv000011BDsd0000001C*
+ ID_PRODUCT_FROM_DATABASE=PCTV Sat (DBC receiver)
+
+pci:v0000109Ed00000878sv0000127Asd00000001*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+
+pci:v0000109Ed00000878sv0000127Asd00000002*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+
+pci:v0000109Ed00000878sv0000127Asd00000003*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+
+pci:v0000109Ed00000878sv0000127Asd00000048*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+
+pci:v0000109Ed00000878sv000013E9sd00000070*
+ ID_PRODUCT_FROM_DATABASE=Win/TV (Audio Section)
+
+pci:v0000109Ed00000878sv0000144Fsd00003000*
+ ID_PRODUCT_FROM_DATABASE=MagicTView CPH060 - Audio
+
+pci:v0000109Ed00000878sv00001461sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Avermedia PCTV98 Audio Capture
+
+pci:v0000109Ed00000878sv00001461sd00000003*
+ ID_PRODUCT_FROM_DATABASE=UltraTV PCI 350
+
+pci:v0000109Ed00000878sv00001461sd00000004*
+ ID_PRODUCT_FROM_DATABASE=AVerTV WDM Audio Capture
+
+pci:v0000109Ed00000878sv00001461sd00000761*
+ ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T
+
+pci:v0000109Ed00000878sv00001461sd00000771*
+ ID_PRODUCT_FROM_DATABASE=AverMedia AVerTV DVB-T 771
+
+pci:v0000109Ed00000878sv000014F1sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+
+pci:v0000109Ed00000878sv000014F1sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+
+pci:v0000109Ed00000878sv000014F1sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+
+pci:v0000109Ed00000878sv000014F1sd00000048*
+ ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+
+pci:v0000109Ed00000878sv00001822sd00000001*
+ ID_PRODUCT_FROM_DATABASE=VisionPlus DVB Card
+
+pci:v0000109Ed00000878sv000018ACsd0000D500*
+ ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV5 Lite
+
+pci:v0000109Ed00000878sv0000270Fsd0000FC00*
+ ID_PRODUCT_FROM_DATABASE=Digitop DTT-1000
+
+pci:v0000109Ed00000878sv0000BD11sd00001200*
+ ID_PRODUCT_FROM_DATABASE=PCTV pro (TV + FM stereo receiver, audio section)
+
+pci:v0000109Ed00000879*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Audio Capture
+
+pci:v0000109Ed00000879sv0000127Asd00000044*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00000122*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00000144*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00000222*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00000244*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00000322*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00000422*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00001122*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00001222*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00001322*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00001522*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00001622*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv0000127Asd00001722*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00000044*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00000122*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00000144*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00000222*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00000244*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00000322*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00000422*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00001122*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00001222*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00001322*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00001522*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00001622*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000879sv000014F1sd00001722*
+ ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+
+pci:v0000109Ed00000880*
+ ID_PRODUCT_FROM_DATABASE=Bt880 Audio Capture
+
+pci:v0000109Ed00002115*
+ ID_PRODUCT_FROM_DATABASE=BtV 2115 Mediastream controller
+
+pci:v0000109Ed00002125*
+ ID_PRODUCT_FROM_DATABASE=BtV 2125 Mediastream controller
+
+pci:v0000109Ed00002164*
+ ID_PRODUCT_FROM_DATABASE=BtV 2164
+
+pci:v0000109Ed00002165*
+ ID_PRODUCT_FROM_DATABASE=BtV 2165
+
+pci:v0000109Ed00008230*
+ ID_PRODUCT_FROM_DATABASE=Bt8230 ATM Segment/Reassembly Ctrlr (SRC)
+
+pci:v0000109Ed00008472*
+ ID_PRODUCT_FROM_DATABASE=Bt8472
+
+pci:v0000109Ed00008474*
+ ID_PRODUCT_FROM_DATABASE=Bt8474
+
+pci:v0000109F*
+ ID_VENDOR_FROM_DATABASE=Trigem Computer Inc.
+
+pci:v000010A0*
+ ID_VENDOR_FROM_DATABASE=Meidensha Corporation
+
+pci:v000010A1*
+ ID_VENDOR_FROM_DATABASE=Juko Electronics Ind. Co. Ltd
+
+pci:v000010A2*
+ ID_VENDOR_FROM_DATABASE=Quantum Corporation
+
+pci:v000010A3*
+ ID_VENDOR_FROM_DATABASE=Everex Systems Inc
+
+pci:v000010A4*
+ ID_VENDOR_FROM_DATABASE=Globe Manufacturing Sales
+
+pci:v000010A5*
+ ID_VENDOR_FROM_DATABASE=Smart Link Ltd.
+
+pci:v000010A5d00003052*
+ ID_PRODUCT_FROM_DATABASE=SmartPCI562 56K Modem
+
+pci:v000010A5d00005449*
+ ID_PRODUCT_FROM_DATABASE=SmartPCI561 modem
+
+pci:v000010A6*
+ ID_VENDOR_FROM_DATABASE=Informtech Industrial Ltd.
+
+pci:v000010A7*
+ ID_VENDOR_FROM_DATABASE=Benchmarq Microelectronics
+
+pci:v000010A8*
+ ID_VENDOR_FROM_DATABASE=Sierra Semiconductor
+
+pci:v000010A8d00000000*
+ ID_PRODUCT_FROM_DATABASE=STB Horizon 64
+
+pci:v000010A9*
+ ID_VENDOR_FROM_DATABASE=Silicon Graphics Intl. Corp.
+
+pci:v000010A9d00000001*
+ ID_PRODUCT_FROM_DATABASE=Crosstalk to PCI Bridge
+
+pci:v000010A9d00000002*
+ ID_PRODUCT_FROM_DATABASE=Linc I/O controller
+
+pci:v000010A9d00000003*
+ ID_PRODUCT_FROM_DATABASE=IOC3 I/O controller
+
+pci:v000010A9d00000004*
+ ID_PRODUCT_FROM_DATABASE=O2 MACE
+
+pci:v000010A9d00000005*
+ ID_PRODUCT_FROM_DATABASE=RAD Audio
+
+pci:v000010A9d00000006*
+ ID_PRODUCT_FROM_DATABASE=HPCEX
+
+pci:v000010A9d00000007*
+ ID_PRODUCT_FROM_DATABASE=RPCEX
+
+pci:v000010A9d00000008*
+ ID_PRODUCT_FROM_DATABASE=DiVO VIP
+
+pci:v000010A9d00000009*
+ ID_PRODUCT_FROM_DATABASE=AceNIC Gigabit Ethernet
+
+pci:v000010A9d00000009sv000010A9sd00008002*
+ ID_PRODUCT_FROM_DATABASE=AceNIC Gigabit Ethernet
+
+pci:v000010A9d00000010*
+ ID_PRODUCT_FROM_DATABASE=AMP Video I/O
+
+pci:v000010A9d00000011*
+ ID_PRODUCT_FROM_DATABASE=GRIP
+
+pci:v000010A9d00000012*
+ ID_PRODUCT_FROM_DATABASE=SGH PSHAC GSN
+
+pci:v000010A9d00000208*
+ ID_PRODUCT_FROM_DATABASE=SSIM1 SAS Adapter
+
+pci:v000010A9d00001001*
+ ID_PRODUCT_FROM_DATABASE=Magic Carpet
+
+pci:v000010A9d00001002*
+ ID_PRODUCT_FROM_DATABASE=Lithium
+
+pci:v000010A9d00001003*
+ ID_PRODUCT_FROM_DATABASE=Dual JPEG 1
+
+pci:v000010A9d00001004*
+ ID_PRODUCT_FROM_DATABASE=Dual JPEG 2
+
+pci:v000010A9d00001005*
+ ID_PRODUCT_FROM_DATABASE=Dual JPEG 3
+
+pci:v000010A9d00001006*
+ ID_PRODUCT_FROM_DATABASE=Dual JPEG 4
+
+pci:v000010A9d00001007*
+ ID_PRODUCT_FROM_DATABASE=Dual JPEG 5
+
+pci:v000010A9d00001008*
+ ID_PRODUCT_FROM_DATABASE=Cesium
+
+pci:v000010A9d0000100A*
+ ID_PRODUCT_FROM_DATABASE=IOC4 I/O controller
+
+pci:v000010A9d00001504*
+ ID_PRODUCT_FROM_DATABASE=SSIM1 Fibre Channel Adapter
+
+pci:v000010A9d00002001*
+ ID_PRODUCT_FROM_DATABASE=Fibre Channel
+
+pci:v000010A9d00002002*
+ ID_PRODUCT_FROM_DATABASE=ASDE
+
+pci:v000010A9d00004001*
+ ID_PRODUCT_FROM_DATABASE=TIO-CE PCI Express Bridge
+
+pci:v000010A9d00004002*
+ ID_PRODUCT_FROM_DATABASE=TIO-CE PCI Express Port
+
+pci:v000010A9d00008001*
+ ID_PRODUCT_FROM_DATABASE=O2 1394
+
+pci:v000010A9d00008002*
+ ID_PRODUCT_FROM_DATABASE=G-net NT
+
+pci:v000010AA*
+ ID_VENDOR_FROM_DATABASE=ACC Microelectronics
+
+pci:v000010AAd00000000*
+ ID_PRODUCT_FROM_DATABASE=ACCM 2188
+
+pci:v000010AAd00002051*
+ ID_PRODUCT_FROM_DATABASE=2051 CPU bridge
+
+pci:v000010AAd00005842*
+ ID_PRODUCT_FROM_DATABASE=2051 ISA bridge
+
+pci:v000010AB*
+ ID_VENDOR_FROM_DATABASE=Digicom
+
+pci:v000010AC*
+ ID_VENDOR_FROM_DATABASE=Honeywell IAC
+
+pci:v000010AD*
+ ID_VENDOR_FROM_DATABASE=Symphony Labs
+
+pci:v000010ADd00000001*
+ ID_PRODUCT_FROM_DATABASE=W83769F
+
+pci:v000010ADd00000003*
+ ID_PRODUCT_FROM_DATABASE=SL82C103
+
+pci:v000010ADd00000005*
+ ID_PRODUCT_FROM_DATABASE=SL82C105
+
+pci:v000010ADd00000103*
+ ID_PRODUCT_FROM_DATABASE=SL82c103
+
+pci:v000010ADd00000105*
+ ID_PRODUCT_FROM_DATABASE=SL82c105
+
+pci:v000010ADd00000565*
+ ID_PRODUCT_FROM_DATABASE=W83C553F/W83C554F
+
+pci:v000010AE*
+ ID_VENDOR_FROM_DATABASE=Cornerstone Technology
+
+pci:v000010AF*
+ ID_VENDOR_FROM_DATABASE=Micro Computer Systems Inc
+
+pci:v000010B0*
+ ID_VENDOR_FROM_DATABASE=CardExpert Technology
+
+pci:v000010B1*
+ ID_VENDOR_FROM_DATABASE=Cabletron Systems Inc
+
+pci:v000010B2*
+ ID_VENDOR_FROM_DATABASE=Raytheon Company
+
+pci:v000010B3*
+ ID_VENDOR_FROM_DATABASE=Databook Inc
+
+pci:v000010B3d00003106*
+ ID_PRODUCT_FROM_DATABASE=DB87144
+
+pci:v000010B3d0000B106*
+ ID_PRODUCT_FROM_DATABASE=DB87144
+
+pci:v000010B4*
+ ID_VENDOR_FROM_DATABASE=STB Systems Inc
+
+pci:v000010B4d00001B1D*
+ ID_PRODUCT_FROM_DATABASE=Velocity 128 3D
+
+pci:v000010B4d00001B1Dsv000010B4sd0000237E*
+ ID_PRODUCT_FROM_DATABASE=Velocity 4400
+
+pci:v000010B5*
+ ID_VENDOR_FROM_DATABASE=PLX Technology, Inc.
+
+pci:v000010B5d00000001*
+ ID_PRODUCT_FROM_DATABASE=i960 PCI bus interface
+
+pci:v000010B5d00000557*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00000557sv0000105Bsd00009030*
+ ID_PRODUCT_FROM_DATABASE=Digium Tormenta 2 T400P-SS7 or E400P-SS7 Quad T1 or E1 PCI card
+
+pci:v000010B5d00001000*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00001000sv0000105Bsd00009030*
+ ID_PRODUCT_FROM_DATABASE=ATCOM AT400P Quad T1 PCI card
+
+pci:v000010B5d00001024*
+ ID_PRODUCT_FROM_DATABASE=Acromag, Inc. IndustryPack Carrier Card
+
+pci:v000010B5d00001042*
+ ID_PRODUCT_FROM_DATABASE=Brandywine / jxi2, Inc. - PMC-SyncClock32, IRIG A & B, Nasa 36
+
+pci:v000010B5d0000106A*
+ ID_PRODUCT_FROM_DATABASE=Dual OX16C952 4 port serial adapter [Megawolf Romulus/4]
+
+pci:v000010B5d00001076*
+ ID_PRODUCT_FROM_DATABASE=VScom 800 8 port serial adaptor
+
+pci:v000010B5d00001077*
+ ID_PRODUCT_FROM_DATABASE=VScom 400 4 port serial adaptor
+
+pci:v000010B5d00001078*
+ ID_PRODUCT_FROM_DATABASE=VScom 210 2 port serial and 1 port parallel adaptor
+
+pci:v000010B5d00001103*
+ ID_PRODUCT_FROM_DATABASE=VScom 200 2 port serial adaptor
+
+pci:v000010B5d00001146*
+ ID_PRODUCT_FROM_DATABASE=VScom 010 1 port parallel adaptor
+
+pci:v000010B5d00001147*
+ ID_PRODUCT_FROM_DATABASE=VScom 020 2 port parallel adaptor
+
+pci:v000010B5d00002000*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00002000sv0000105Bsd00009030*
+ ID_PRODUCT_FROM_DATABASE=ATCOM AE400P Quad E1 PCI card
+
+pci:v000010B5d00002540*
+ ID_PRODUCT_FROM_DATABASE=IXXAT CAN-Interface PC-I 04/PCI
+
+pci:v000010B5d00002724*
+ ID_PRODUCT_FROM_DATABASE=Thales PCSM Security Card
+
+pci:v000010B5d00003376*
+ ID_PRODUCT_FROM_DATABASE=Cosateq 4 Port CAN Card
+
+pci:v000010B5d00004000*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00004000sv000010B5sd00009030*
+ ID_PRODUCT_FROM_DATABASE=Tormenta 3 Varion V400P/ATCOM TE400P Quad E1/T1/J1 PCI card
+
+pci:v000010B5d00004001*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00004001sv0000105Bsd00009030*
+ ID_PRODUCT_FROM_DATABASE=ATCOM A400PE Quad E1 PCI card
+
+pci:v000010B5d00004002*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00004002sv0000105Bsd00009030*
+ ID_PRODUCT_FROM_DATABASE=ATCOM A400PT Quad T1 PCI card
+
+pci:v000010B5d00006140*
+ ID_PRODUCT_FROM_DATABASE=PCI6140 32-bit 33MHz PCI-to-PCI Bridge
+
+pci:v000010B5d00006150*
+ ID_PRODUCT_FROM_DATABASE=PCI6150 32-bit 33MHz PCI-to-PCI Bridge
+
+pci:v000010B5d00006152*
+ ID_PRODUCT_FROM_DATABASE=PCI6152 32-bit 66MHz PCI-to-PCI Bridge
+
+pci:v000010B5d00006154*
+ ID_PRODUCT_FROM_DATABASE=PCI6154 64-bit 66MHz PCI-to-PCI Bridge
+
+pci:v000010B5d00006254*
+ ID_PRODUCT_FROM_DATABASE=PCI6254 64-bit 66MHz PCI-to-PCI Bridge
+
+pci:v000010B5d00006466*
+ ID_PRODUCT_FROM_DATABASE=PCI6466 64-bit 66MHz PCI-to-PCI Bridge
+
+pci:v000010B5d00006520*
+ ID_PRODUCT_FROM_DATABASE=PCI6520 64-bit 133MHz PCI-X-to-PCI-X Bridge
+
+pci:v000010B5d00006540*
+ ID_PRODUCT_FROM_DATABASE=PCI6540 64-bit 133MHz PCI-X-to-PCI-X Bridge
+
+pci:v000010B5d00006540sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11 Single Board Computer
+
+pci:v000010B5d00006540sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v000010B5d00006541*
+ ID_PRODUCT_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, primary side)
+
+pci:v000010B5d00006541sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11 Single Board Computer
+
+pci:v000010B5d00006541sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v000010B5d00006542*
+ ID_PRODUCT_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, secondary side)
+
+pci:v000010B5d00006542sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11 Single Board Computer
+
+pci:v000010B5d00006542sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v000010B5d00008111*
+ ID_PRODUCT_FROM_DATABASE=PEX 8111 PCI Express-to-PCI Bridge
+
+pci:v000010B5d00008112*
+ ID_PRODUCT_FROM_DATABASE=PEX8112 x1 Lane PCI Express-to-PCI Bridge
+
+pci:v000010B5d00008114*
+ ID_PRODUCT_FROM_DATABASE=PEX 8114 PCI Express-to-PCI/PCI-X Bridge
+
+pci:v000010B5d00008311*
+ ID_PRODUCT_FROM_DATABASE=PEX8311 x1 Lane PCI Express-to-Generic Local Bus Bridge
+
+pci:v000010B5d00008505*
+ ID_PRODUCT_FROM_DATABASE=PEX 8505 5-lane, 5-port PCI Express Switch
+
+pci:v000010B5d00008508*
+ ID_PRODUCT_FROM_DATABASE=PEX 8508 8-lane, 5-port PCI Express Switch
+
+pci:v000010B5d00008509*
+ ID_PRODUCT_FROM_DATABASE=PEX 8509 8-lane, 8-port PCI Express Switch
+
+pci:v000010B5d00008512*
+ ID_PRODUCT_FROM_DATABASE=PEX 8512 12-lane, 5-port PCI Express Switch
+
+pci:v000010B5d00008516*
+ ID_PRODUCT_FROM_DATABASE=PEX 8516  Versatile PCI Express Switch
+
+pci:v000010B5d00008517*
+ ID_PRODUCT_FROM_DATABASE=PEX 8517 16-lane, 5-port PCI Express Switch
+
+pci:v000010B5d00008518*
+ ID_PRODUCT_FROM_DATABASE=PEX 8518 16-lane, 5-port PCI Express Switch
+
+pci:v000010B5d00008524*
+ ID_PRODUCT_FROM_DATABASE=PEX 8524 24-lane, 6-port PCI Express Switch
+
+pci:v000010B5d00008525*
+ ID_PRODUCT_FROM_DATABASE=PEX 8525 24-lane, 5-port PCI Express Switch
+
+pci:v000010B5d00008532*
+ ID_PRODUCT_FROM_DATABASE=PEX 8532  Versatile PCI Express Switch
+
+pci:v000010B5d00008533*
+ ID_PRODUCT_FROM_DATABASE=PEX 8533 32-lane, 6-port PCI Express Switch
+
+pci:v000010B5d00008547*
+ ID_PRODUCT_FROM_DATABASE=PEX 8547 48-lane, 3-port PCI Express Switch
+
+pci:v000010B5d00008548*
+ ID_PRODUCT_FROM_DATABASE=PEX 8548 48-lane, 9-port PCI Express Switch
+
+pci:v000010B5d00008604*
+ ID_PRODUCT_FROM_DATABASE=PEX 8604 4-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008605*
+ ID_PRODUCT_FROM_DATABASE=PEX 8605 PCI Express 4-port Gen2 Switch
+
+pci:v000010B5d00008606*
+ ID_PRODUCT_FROM_DATABASE=PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008608*
+ ID_PRODUCT_FROM_DATABASE=PEX 8608 8-lane, 8-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008609*
+ ID_PRODUCT_FROM_DATABASE=PEX 8609 8-lane, 8-Port PCI Express Gen 2 (5.0 GT/s) Switch with DMA
+
+pci:v000010B5d00008612*
+ ID_PRODUCT_FROM_DATABASE=PEX 8612 12-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008613*
+ ID_PRODUCT_FROM_DATABASE=PEX 8613 12-lane, 3-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008614*
+ ID_PRODUCT_FROM_DATABASE=PEX 8614 12-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008615*
+ ID_PRODUCT_FROM_DATABASE=PEX 8615 12-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch with DMA
+
+pci:v000010B5d00008616*
+ ID_PRODUCT_FROM_DATABASE=PEX 8616 16-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008617*
+ ID_PRODUCT_FROM_DATABASE=PEX 8617 16-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch with P2P
+
+pci:v000010B5d00008618*
+ ID_PRODUCT_FROM_DATABASE=PEX 8618 16-lane, 16-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008619*
+ ID_PRODUCT_FROM_DATABASE=PEX 8619 16-lane, 16-Port PCI Express Gen 2 (5.0 GT/s) Switch with DMA
+
+pci:v000010B5d00008624*
+ ID_PRODUCT_FROM_DATABASE=PEX 8624 24-lane, 6-Port PCI Express Gen 2 (5.0 GT/s) Switch [ExpressLane]
+
+pci:v000010B5d00008624sv000013A3sd00001845*
+ ID_PRODUCT_FROM_DATABASE=DX1845 Acceleration Card
+
+pci:v000010B5d00008625*
+ ID_PRODUCT_FROM_DATABASE=PEX 8625 24-lane, 24-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008632*
+ ID_PRODUCT_FROM_DATABASE=PEX 8632 32-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008636*
+ ID_PRODUCT_FROM_DATABASE=PEX 8636 36-lane, 24-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008647*
+ ID_PRODUCT_FROM_DATABASE=PEX 8647 48-Lane, 3-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008648*
+ ID_PRODUCT_FROM_DATABASE=PEX 8648 48-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008649*
+ ID_PRODUCT_FROM_DATABASE=PEX 8649 48-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008664*
+ ID_PRODUCT_FROM_DATABASE=PEX 8664 64-lane, 16-Port PCI Express Gen 2 (5.0 GT/s) Switch
+
+pci:v000010B5d00008680*
+ ID_PRODUCT_FROM_DATABASE=PEX 8680 80-lane, 20-Port PCI Express Gen 2 (5.0 GT/s) Multi-Root Switch
+
+pci:v000010B5d00008696*
+ ID_PRODUCT_FROM_DATABASE=PEX 8696 96-lane, 24-Port PCI Express Gen 2 (5.0 GT/s) Multi-Root Switch
+
+pci:v000010B5d00008732*
+ ID_PRODUCT_FROM_DATABASE=PEX 8732 32-lane, 8-Port PCI Express Gen 3 (8.0 GT/s) Switch
+
+pci:v000010B5d000087B0*
+ ID_PRODUCT_FROM_DATABASE=PEX 8732 32-lane, 8-Port PCI Express Gen 3 (8.0 GT/s) Switch
+
+pci:v000010B5d00009016*
+ ID_PRODUCT_FROM_DATABASE=PLX 9016 8-port serial controller
+
+pci:v000010B5d00009030*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00009030sv000010B5sd00002695*
+ ID_PRODUCT_FROM_DATABASE=Hilscher CIF50-PB/DPS Profibus
+
+pci:v000010B5d00009030sv000010B5sd00002862*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board
+
+pci:v000010B5d00009030sv000010B5sd00002906*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board
+
+pci:v000010B5d00009030sv000010B5sd00002940*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board
+
+pci:v000010B5d00009030sv000010B5sd00002977*
+ ID_PRODUCT_FROM_DATABASE=IXXAT iPC-I XC16/PCI CAN Board
+
+pci:v000010B5d00009030sv000010B5sd00002978*
+ ID_PRODUCT_FROM_DATABASE=SH ARC-PCIu/SH ARC-PCI104/SH ARC-PCIe SOHARD ARCNET card
+
+pci:v000010B5d00009030sv000010B5sd00003025*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board
+
+pci:v000010B5d00009030sv000010B5sd00003068*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board
+
+pci:v000010B5d00009030sv000010B5sd00003463*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI D (v2) (3V/5V): Timecode Reader Board
+
+pci:v000010B5d00009030sv000012FEsd00000111*
+ ID_PRODUCT_FROM_DATABASE=CPCI-ASIO4 (ESD 4-port Serial Interface Board)
+
+pci:v000010B5d00009030sv00001369sd00009C01*
+ ID_PRODUCT_FROM_DATABASE=VX222v2
+
+pci:v000010B5d00009030sv00001369sd00009D01*
+ ID_PRODUCT_FROM_DATABASE=VX222-Mic
+
+pci:v000010B5d00009030sv00001369sd00009D02*
+ ID_PRODUCT_FROM_DATABASE=VX222-Mic
+
+pci:v000010B5d00009030sv00001369sd00009E01*
+ ID_PRODUCT_FROM_DATABASE=PCX924v2
+
+pci:v000010B5d00009030sv00001369sd00009F01*
+ ID_PRODUCT_FROM_DATABASE=PCX924-Mic
+
+pci:v000010B5d00009030sv00001369sd00009F02*
+ ID_PRODUCT_FROM_DATABASE=PCX924-Mic
+
+pci:v000010B5d00009030sv00001369sd0000A001*
+ ID_PRODUCT_FROM_DATABASE=PCX22v2
+
+pci:v000010B5d00009030sv00001369sd0000A701*
+ ID_PRODUCT_FROM_DATABASE=LCM220v2
+
+pci:v000010B5d00009030sv00001369sd0000A801*
+ ID_PRODUCT_FROM_DATABASE=LCM200
+
+pci:v000010B5d00009030sv00001397sd00003136*
+ ID_PRODUCT_FROM_DATABASE=4xS0-ISDN PCI Adapter
+
+pci:v000010B5d00009030sv00001397sd00003137*
+ ID_PRODUCT_FROM_DATABASE=S2M-E1-ISDN PCI Adapter
+
+pci:v000010B5d00009030sv00001518sd00000200*
+ ID_PRODUCT_FROM_DATABASE=Kontron ThinkIO-C
+
+pci:v000010B5d00009030sv000015EDsd00001002*
+ ID_PRODUCT_FROM_DATABASE=MCCS 8-port Serial Hot Swap
+
+pci:v000010B5d00009030sv000015EDsd00001003*
+ ID_PRODUCT_FROM_DATABASE=MCCS 16-port Serial Hot Swap
+
+pci:v000010B5d00009030sv0000E1C5sd00000001*
+ ID_PRODUCT_FROM_DATABASE=TE1-PCI
+
+pci:v000010B5d00009030sv0000E1C5sd00000005*
+ ID_PRODUCT_FROM_DATABASE=TA1-PCI
+
+pci:v000010B5d00009030sv0000E1C5sd00000006*
+ ID_PRODUCT_FROM_DATABASE=TA1-PCI4
+
+pci:v000010B5d00009036*
+ ID_PRODUCT_FROM_DATABASE=9036
+
+pci:v000010B5d00009050*
+ ID_PRODUCT_FROM_DATABASE=PCI <-> IOBus Bridge
+
+pci:v000010B5d00009050sv000010B5sd00001067*
+ ID_PRODUCT_FROM_DATABASE=IXXAT CAN i165
+
+pci:v000010B5d00009050sv000010B5sd0000114E*
+ ID_PRODUCT_FROM_DATABASE=Wasco WITIO PCI168extended
+
+pci:v000010B5d00009050sv000010B5sd00001169*
+ ID_PRODUCT_FROM_DATABASE=Wasco OPTOIO32standard 32 digital in, 32 digital out
+
+pci:v000010B5d00009050sv000010B5sd00001172*
+ ID_PRODUCT_FROM_DATABASE=IK220 (Heidenhain)
+
+pci:v000010B5d00009050sv000010B5sd00002036*
+ ID_PRODUCT_FROM_DATABASE=SatPak GPS
+
+pci:v000010B5d00009050sv000010B5sd00002221*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI LV: Timecode Reader Board
+
+pci:v000010B5d00009050sv000010B5sd00002273*
+ ID_PRODUCT_FROM_DATABASE=SH ARC-PCI SOHARD ARCNET card
+
+pci:v000010B5d00009050sv000010B5sd00002431*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI D: Timecode Reader Board
+
+pci:v000010B5d00009050sv000010B5sd00002905*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCI TS: Time Synchronisation Board
+
+pci:v000010B5d00009050sv000010B5sd00003196*
+ ID_PRODUCT_FROM_DATABASE=Goramo PLX200SYN sync serial card
+
+pci:v000010B5d00009050sv000010B5sd00009050*
+ ID_PRODUCT_FROM_DATABASE=PCI-I04 PCI Passive PC/CAN Interface
+
+pci:v000010B5d00009050sv00001369sd00008901*
+ ID_PRODUCT_FROM_DATABASE=PCX11+ PCI
+
+pci:v000010B5d00009050sv00001369sd00008F01*
+ ID_PRODUCT_FROM_DATABASE=VX222
+
+pci:v000010B5d00009050sv00001369sd00009401*
+ ID_PRODUCT_FROM_DATABASE=PCX924
+
+pci:v000010B5d00009050sv00001369sd00009501*
+ ID_PRODUCT_FROM_DATABASE=PCX22
+
+pci:v000010B5d00009050sv00001498sd00000362*
+ ID_PRODUCT_FROM_DATABASE=TPMC866 8 Channel Serial Card
+
+pci:v000010B5d00009050sv00001522sd00000001*
+ ID_PRODUCT_FROM_DATABASE=RockForce 4 Port V.90 Data/Fax/Voice Modem
+
+pci:v000010B5d00009050sv00001522sd00000002*
+ ID_PRODUCT_FROM_DATABASE=RockForce 2 Port V.90 Data/Fax/Voice Modem
+
+pci:v000010B5d00009050sv00001522sd00000003*
+ ID_PRODUCT_FROM_DATABASE=RockForce 6 Port V.90 Data/Fax/Voice Modem
+
+pci:v000010B5d00009050sv00001522sd00000004*
+ ID_PRODUCT_FROM_DATABASE=RockForce 8 Port V.90 Data/Fax/Voice Modem
+
+pci:v000010B5d00009050sv00001522sd00000010*
+ ID_PRODUCT_FROM_DATABASE=RockForce2000 4 Port V.90 Data/Fax/Voice Modem
+
+pci:v000010B5d00009050sv00001522sd00000020*
+ ID_PRODUCT_FROM_DATABASE=RockForce2000 2 Port V.90 Data/Fax/Voice Modem
+
+pci:v000010B5d00009050sv000015EDsd00001000*
+ ID_PRODUCT_FROM_DATABASE=Macrolink MCCS 8-port Serial
+
+pci:v000010B5d00009050sv000015EDsd00001001*
+ ID_PRODUCT_FROM_DATABASE=Macrolink MCCS 16-port Serial
+
+pci:v000010B5d00009050sv000015EDsd00001002*
+ ID_PRODUCT_FROM_DATABASE=Macrolink MCCS 8-port Serial Hot Swap
+
+pci:v000010B5d00009050sv000015EDsd00001003*
+ ID_PRODUCT_FROM_DATABASE=Macrolink MCCS 16-port Serial Hot Swap
+
+pci:v000010B5d00009050sv00005654sd00002036*
+ ID_PRODUCT_FROM_DATABASE=OpenSwitch 6 Telephony card
+
+pci:v000010B5d00009050sv00005654sd00003132*
+ ID_PRODUCT_FROM_DATABASE=OpenSwitch 12 Telephony card
+
+pci:v000010B5d00009050sv00005654sd00005634*
+ ID_PRODUCT_FROM_DATABASE=OpenLine4 Telephony Card
+
+pci:v000010B5d00009050sv0000D531sd0000C002*
+ ID_PRODUCT_FROM_DATABASE=PCIntelliCAN 2xSJA1000 CAN bus
+
+pci:v000010B5d00009050sv0000D84Dsd00004006*
+ ID_PRODUCT_FROM_DATABASE=EX-4006 1P
+
+pci:v000010B5d00009050sv0000D84Dsd00004008*
+ ID_PRODUCT_FROM_DATABASE=EX-4008 1P EPP/ECP
+
+pci:v000010B5d00009050sv0000D84Dsd00004014*
+ ID_PRODUCT_FROM_DATABASE=EX-4014 2P
+
+pci:v000010B5d00009050sv0000D84Dsd00004018*
+ ID_PRODUCT_FROM_DATABASE=EX-4018 3P EPP/ECP
+
+pci:v000010B5d00009050sv0000D84Dsd00004025*
+ ID_PRODUCT_FROM_DATABASE=EX-4025 1S(16C550) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004027*
+ ID_PRODUCT_FROM_DATABASE=EX-4027 1S(16C650) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004028*
+ ID_PRODUCT_FROM_DATABASE=EX-4028 1S(16C850) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004036*
+ ID_PRODUCT_FROM_DATABASE=EX-4036 2S(16C650) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004037*
+ ID_PRODUCT_FROM_DATABASE=EX-4037 2S(16C650) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004038*
+ ID_PRODUCT_FROM_DATABASE=EX-4038 2S(16C850) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004052*
+ ID_PRODUCT_FROM_DATABASE=EX-4052 1S(16C550) RS-422/485
+
+pci:v000010B5d00009050sv0000D84Dsd00004053*
+ ID_PRODUCT_FROM_DATABASE=EX-4053 2S(16C550) RS-422/485
+
+pci:v000010B5d00009050sv0000D84Dsd00004055*
+ ID_PRODUCT_FROM_DATABASE=EX-4055 4S(16C550) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004058*
+ ID_PRODUCT_FROM_DATABASE=EX-4055 4S(16C650) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004065*
+ ID_PRODUCT_FROM_DATABASE=EX-4065 8S(16C550) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004068*
+ ID_PRODUCT_FROM_DATABASE=EX-4068 8S(16C650) RS-232
+
+pci:v000010B5d00009050sv0000D84Dsd00004078*
+ ID_PRODUCT_FROM_DATABASE=EX-4078 2S(16C552) RS-232+1P
+
+pci:v000010B5d00009052*
+ ID_PRODUCT_FROM_DATABASE=PCI9052 PCI <-> IOBus Bridge
+
+pci:v000010B5d00009054*
+ ID_PRODUCT_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00009054sv000010B5sd00002455*
+ ID_PRODUCT_FROM_DATABASE=Wessex Techology PHIL-PCI
+
+pci:v000010B5d00009054sv000010B5sd00002696*
+ ID_PRODUCT_FROM_DATABASE=Innes Corp AM Radcap card
+
+pci:v000010B5d00009054sv000010B5sd00002717*
+ ID_PRODUCT_FROM_DATABASE=Innes Corp Auricon card
+
+pci:v000010B5d00009054sv000010B5sd00002844*
+ ID_PRODUCT_FROM_DATABASE=Innes Corp TVS Encoder card
+
+pci:v000010B5d00009054sv000012C7sd00004001*
+ ID_PRODUCT_FROM_DATABASE=Intel Dialogic DM/V960-4T1 PCI
+
+pci:v000010B5d00009054sv000012D9sd00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI Prosody Card rev 1.5
+
+pci:v000010B5d00009054sv000014B4sd0000D100*
+ ID_PRODUCT_FROM_DATABASE=Dektec DTA-100
+
+pci:v000010B5d00009054sv000014B4sd0000D114*
+ ID_PRODUCT_FROM_DATABASE=Dektec DTA-120
+
+pci:v000010B5d00009054sv000016DFsd00000011*
+ ID_PRODUCT_FROM_DATABASE=PIKA PrimeNet MM PCI
+
+pci:v000010B5d00009054sv000016DFsd00000012*
+ ID_PRODUCT_FROM_DATABASE=PIKA PrimeNet MM cPCI 8
+
+pci:v000010B5d00009054sv000016DFsd00000013*
+ ID_PRODUCT_FROM_DATABASE=PIKA PrimeNet MM cPCI 8 (without CAS Signaling)
+
+pci:v000010B5d00009054sv000016DFsd00000014*
+ ID_PRODUCT_FROM_DATABASE=PIKA PrimeNet MM cPCI 4
+
+pci:v000010B5d00009054sv000016DFsd00000015*
+ ID_PRODUCT_FROM_DATABASE=PIKA Daytona MM
+
+pci:v000010B5d00009054sv000016DFsd00000016*
+ ID_PRODUCT_FROM_DATABASE=PIKA InLine MM
+
+pci:v000010B5d00009056*
+ ID_PRODUCT_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00009056sv000010B5sd00002979*
+ ID_PRODUCT_FROM_DATABASE=CellinkBlade 11 - CPCI board VoATM AAL1
+
+pci:v000010B5d00009056sv000010B5sd00003268*
+ ID_PRODUCT_FROM_DATABASE=IXXAT iPC-I XC16/PCIe CAN Board
+
+pci:v000010B5d00009056sv000010B5sd00003352*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCIe HD: Timecode Reader Board
+
+pci:v000010B5d00009056sv000010B5sd00003353*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCIe D: Timecode Reader Board
+
+pci:v000010B5d00009056sv000010B5sd00003354*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCIe LV: Timecode Reader Board
+
+pci:v000010B5d00009056sv000010B5sd00003355*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCIe L: Timecode Reader Board
+
+pci:v000010B5d00009056sv000010B5sd00003415*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCIe TS: Time Synchronisation Board
+
+pci:v000010B5d00009056sv00001369sd0000C001*
+ ID_PRODUCT_FROM_DATABASE=LX6464ES
+
+pci:v000010B5d00009056sv00001369sd0000C201*
+ ID_PRODUCT_FROM_DATABASE=LX1616ES
+
+pci:v000010B5d00009056sv000014B4sd0000D10A*
+ ID_PRODUCT_FROM_DATABASE=DekTec DTA-110T
+
+pci:v000010B5d00009056sv000014B4sd0000D140*
+ ID_PRODUCT_FROM_DATABASE=Dektec DTA-140
+
+pci:v000010B5d00009056sv00001A0Esd0000006F*
+ ID_PRODUCT_FROM_DATABASE=Dektec DTA-111
+
+pci:v000010B5d00009060*
+ ID_PRODUCT_FROM_DATABASE=PCI9060 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d0000906D*
+ ID_PRODUCT_FROM_DATABASE=9060SD
+
+pci:v000010B5d0000906Dsv0000125Csd00000640*
+ ID_PRODUCT_FROM_DATABASE=Aries 16000P
+
+pci:v000010B5d0000906E*
+ ID_PRODUCT_FROM_DATABASE=9060ES
+
+pci:v000010B5d00009080*
+ ID_PRODUCT_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d00009080sv0000103Csd000010EB*
+ ID_PRODUCT_FROM_DATABASE=(Agilent) E2777B 83K Series Optical Communication Interface
+
+pci:v000010B5d00009080sv0000103Csd000010EC*
+ ID_PRODUCT_FROM_DATABASE=(Agilent) E6978-66442 PCI CIC
+
+pci:v000010B5d00009080sv000010B5sd00001123*
+ ID_PRODUCT_FROM_DATABASE=Sectra KK631 encryption board
+
+pci:v000010B5d00009080sv000010B5sd00009080*
+ ID_PRODUCT_FROM_DATABASE=9080 [real subsystem ID not set]
+
+pci:v000010B5d00009080sv000012D9sd00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI Prosody Card
+
+pci:v000010B5d00009080sv000012DFsd00004422*
+ ID_PRODUCT_FROM_DATABASE=4422PCI ["Do-All" Telemetry Data Aquisition System]
+
+pci:v000010B5d00009080sv00001369sd00009601*
+ ID_PRODUCT_FROM_DATABASE=PCX822np
+
+pci:v000010B5d00009080sv00001369sd0000A102*
+ ID_PRODUCT_FROM_DATABASE=PCX822v2
+
+pci:v000010B5d00009080sv00001369sd0000A201*
+ ID_PRODUCT_FROM_DATABASE=PCX442
+
+pci:v000010B5d00009080sv00001369sd0000A301*
+ ID_PRODUCT_FROM_DATABASE=LCM440v2
+
+pci:v000010B5d00009080sv00001369sd0000A401*
+ ID_PRODUCT_FROM_DATABASE=VX822
+
+pci:v000010B5d00009080sv00001369sd0000A402*
+ ID_PRODUCT_FROM_DATABASE=VX822v2
+
+pci:v000010B5d00009080sv00001369sd0000A901*
+ ID_PRODUCT_FROM_DATABASE=LCM420
+
+pci:v000010B5d00009080sv00001369sd0000AA01*
+ ID_PRODUCT_FROM_DATABASE=VX820v2
+
+pci:v000010B5d00009080sv00001517sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=ECSG-1R3ADC-PMC Clock synthesizer
+
+pci:v000010B5d00009656*
+ ID_PRODUCT_FROM_DATABASE=PCI9656 PCI <-> IOBus Bridge
+
+pci:v000010B5d00009656sv00001517sd0000000F*
+ ID_PRODUCT_FROM_DATABASE=ECDR-GC314-PMC Receiver
+
+pci:v000010B5d00009656sv00001885sd00000700*
+ ID_PRODUCT_FROM_DATABASE=Tsunami FPGA PMC with Altera Stratix S40
+
+pci:v000010B5d00009656sv00001885sd00000701*
+ ID_PRODUCT_FROM_DATABASE=Tsunami FPGA PMC with Altera Stratix S30
+
+pci:v000010B5d0000A100*
+ ID_PRODUCT_FROM_DATABASE=Blackmagic Design DeckLink
+
+pci:v000010B5d0000BB04*
+ ID_PRODUCT_FROM_DATABASE=B&B 3PCIOSD1A Isolated PCI Serial
+
+pci:v000010B5d0000C001*
+ ID_PRODUCT_FROM_DATABASE=CronyxOmega-PCI (8-port RS232)
+
+pci:v000010B5d0000D00D*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d0000D00Dsv000010B5sd00009030*
+ ID_PRODUCT_FROM_DATABASE=Digium Tormenta 2 T400P or E400P Quad T1 or E1 PCI card
+
+pci:v000010B5d0000D33D*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d0000D33Dsv0000105Bsd00009030*
+ ID_PRODUCT_FROM_DATABASE=Tormenta 3 Varion V401PT Quad T1/J1 PCI card
+
+pci:v000010B5d0000D44D*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d0000D44Dsv0000105Bsd00009030*
+ ID_PRODUCT_FROM_DATABASE=Tormenta 3 Varion V401PE Quad E1 PCI card
+
+pci:v000010B5d0000D44Dsv000010B5sd000017F6*
+ ID_PRODUCT_FROM_DATABASE=Allo CP100P/E 1-port E1/T1/J1 PCI/PCIe card
+
+pci:v000010B5d0000D44Dsv000010B5sd000017F7*
+ ID_PRODUCT_FROM_DATABASE=Allo CP400P/E 4-port E1/T1/J1 PCI/PCIe card
+
+pci:v000010B5d0000D44Dsv000010B5sd000017F8*
+ ID_PRODUCT_FROM_DATABASE=Allo CP200P/E 2-port E1/T1/J1 PCI/PCIe card
+
+pci:v000010B6*
+ ID_VENDOR_FROM_DATABASE=Madge Networks
+
+pci:v000010B6d00000001*
+ ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode
+
+pci:v000010B6d00000002*
+ ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk2
+
+pci:v000010B6d00000002sv000010B6sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk2
+
+pci:v000010B6d00000002sv000010B6sd00000006*
+ ID_PRODUCT_FROM_DATABASE=16/4 CardBus Adapter
+
+pci:v000010B6d00000003*
+ ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk3
+
+pci:v000010B6d00000003sv00000E11sd0000B0FD*
+ ID_PRODUCT_FROM_DATABASE=Compaq NC4621 PCI, 4/16, WOL
+
+pci:v000010B6d00000003sv000010B6sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk3
+
+pci:v000010B6d00000003sv000010B6sd00000007*
+ ID_PRODUCT_FROM_DATABASE=Presto PCI Plus Adapter
+
+pci:v000010B6d00000004*
+ ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk1
+
+pci:v000010B6d00000006*
+ ID_PRODUCT_FROM_DATABASE=16/4 Cardbus Adapter
+
+pci:v000010B6d00000006sv000010B6sd00000006*
+ ID_PRODUCT_FROM_DATABASE=16/4 CardBus Adapter
+
+pci:v000010B6d00000007*
+ ID_PRODUCT_FROM_DATABASE=Presto PCI Adapter
+
+pci:v000010B6d00000007sv000010B6sd00000007*
+ ID_PRODUCT_FROM_DATABASE=Presto PCI
+
+pci:v000010B6d00000009*
+ ID_PRODUCT_FROM_DATABASE=Smart 100/16/4 PCI-HS Ringnode
+
+pci:v000010B6d00000009sv000010B6sd00000009*
+ ID_PRODUCT_FROM_DATABASE=Smart 100/16/4 PCI-HS Ringnode
+
+pci:v000010B6d0000000A*
+ ID_PRODUCT_FROM_DATABASE=Smart 100/16/4 PCI Ringnode
+
+pci:v000010B6d0000000Asv000010B6sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Smart 100/16/4 PCI Ringnode
+
+pci:v000010B6d0000000B*
+ ID_PRODUCT_FROM_DATABASE=16/4 CardBus Adapter Mk2
+
+pci:v000010B6d0000000Bsv000010B6sd00000008*
+ ID_PRODUCT_FROM_DATABASE=16/4 CardBus Adapter Mk2
+
+pci:v000010B6d0000000Bsv000010B6sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=16/4 Cardbus Adapter Mk2
+
+pci:v000010B6d0000000C*
+ ID_PRODUCT_FROM_DATABASE=RapidFire 3140V2 16/4 TR Adapter
+
+pci:v000010B6d0000000Csv000010B6sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=RapidFire 3140V2 16/4 TR Adapter
+
+pci:v000010B6d00001000*
+ ID_PRODUCT_FROM_DATABASE=Collage 25/155 ATM Client Adapter
+
+pci:v000010B6d00001001*
+ ID_PRODUCT_FROM_DATABASE=Collage 155 ATM Server Adapter
+
+pci:v000010B7*
+ ID_VENDOR_FROM_DATABASE=3Com Corporation
+
+pci:v000010B7d00000001*
+ ID_PRODUCT_FROM_DATABASE=3c985 1000BaseSX (SX/TX)
+
+pci:v000010B7d00000013*
+ ID_PRODUCT_FROM_DATABASE=AR5212 802.11abg NIC (3CRDAG675)
+
+pci:v000010B7d00000013sv000010B7sd00002031*
+ ID_PRODUCT_FROM_DATABASE=3CRDAG675 11a/b/g Wireless PCI Adapter
+
+pci:v000010B7d00000910*
+ ID_PRODUCT_FROM_DATABASE=3C910-A01
+
+pci:v000010B7d00001006*
+ ID_PRODUCT_FROM_DATABASE=MINI PCI type 3B Data Fax Modem
+
+pci:v000010B7d00001007*
+ ID_PRODUCT_FROM_DATABASE=Mini PCI 56k Winmodem
+
+pci:v000010B7d00001007sv000010B7sd0000615B*
+ ID_PRODUCT_FROM_DATABASE=Mini PCI 56K Modem
+
+pci:v000010B7d00001007sv000010B7sd0000615C*
+ ID_PRODUCT_FROM_DATABASE=Mini PCI 56K Modem
+
+pci:v000010B7d00001201*
+ ID_PRODUCT_FROM_DATABASE=3c982-TXM 10/100baseTX Dual Port A [Hydra]
+
+pci:v000010B7d00001202*
+ ID_PRODUCT_FROM_DATABASE=3c982-TXM 10/100baseTX Dual Port B [Hydra]
+
+pci:v000010B7d00001700*
+ ID_PRODUCT_FROM_DATABASE=3c940 10/100/1000Base-T [Marvell]
+
+pci:v000010B7d00001700sv00001043sd000080EB*
+ ID_PRODUCT_FROM_DATABASE=A7V600/P4P800/K8V motherboard
+
+pci:v000010B7d00001700sv000010B7sd00000010*
+ ID_PRODUCT_FROM_DATABASE=3C940 Gigabit LOM Ethernet Adapter
+
+pci:v000010B7d00001700sv000010B7sd00000020*
+ ID_PRODUCT_FROM_DATABASE=3C941 Gigabit LOM Ethernet Adapter
+
+pci:v000010B7d00001700sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v000010B7d00003390*
+ ID_PRODUCT_FROM_DATABASE=3c339 TokenLink Velocity
+
+pci:v000010B7d00003590*
+ ID_PRODUCT_FROM_DATABASE=3c359 TokenLink Velocity XL
+
+pci:v000010B7d00003590sv000010B7sd00003590*
+ ID_PRODUCT_FROM_DATABASE=TokenLink Velocity XL Adapter (3C359/359B)
+
+pci:v000010B7d00004500*
+ ID_PRODUCT_FROM_DATABASE=3c450 HomePNA [Tornado]
+
+pci:v000010B7d00005055*
+ ID_PRODUCT_FROM_DATABASE=3c555 Laptop Hurricane
+
+pci:v000010B7d00005057*
+ ID_PRODUCT_FROM_DATABASE=3c575 Megahertz 10/100 LAN CardBus [Boomerang]
+
+pci:v000010B7d00005057sv000010B7sd00005A57*
+ ID_PRODUCT_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card
+
+pci:v000010B7d00005157*
+ ID_PRODUCT_FROM_DATABASE=3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone]
+
+pci:v000010B7d00005157sv000010B7sd00005B57*
+ ID_PRODUCT_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card
+
+pci:v000010B7d00005257*
+ ID_PRODUCT_FROM_DATABASE=3cCFE575CT CardBus [Cyclone]
+
+pci:v000010B7d00005257sv000010B7sd00005C57*
+ ID_PRODUCT_FROM_DATABASE=FE575C-3Com 10/100 LAN CardBus-Fast Ethernet
+
+pci:v000010B7d00005900*
+ ID_PRODUCT_FROM_DATABASE=3c590 10BaseT [Vortex]
+
+pci:v000010B7d00005920*
+ ID_PRODUCT_FROM_DATABASE=3c592 EISA 10mbps Demon/Vortex
+
+pci:v000010B7d00005950*
+ ID_PRODUCT_FROM_DATABASE=3c595 100BaseTX [Vortex]
+
+pci:v000010B7d00005951*
+ ID_PRODUCT_FROM_DATABASE=3c595 100BaseT4 [Vortex]
+
+pci:v000010B7d00005952*
+ ID_PRODUCT_FROM_DATABASE=3c595 100Base-MII [Vortex]
+
+pci:v000010B7d00005970*
+ ID_PRODUCT_FROM_DATABASE=3c597 EISA Fast Demon/Vortex
+
+pci:v000010B7d00005B57*
+ ID_PRODUCT_FROM_DATABASE=3c595 Megahertz 10/100 LAN CardBus [Boomerang]
+
+pci:v000010B7d00005B57sv000010B7sd00005B57*
+ ID_PRODUCT_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card
+
+pci:v000010B7d00006000*
+ ID_PRODUCT_FROM_DATABASE=3CRSHPW796 [OfficeConnect Wireless CardBus]
+
+pci:v000010B7d00006001*
+ ID_PRODUCT_FROM_DATABASE=3com 3CRWE154G72 [Office Connect Wireless LAN Adapter]
+
+pci:v000010B7d00006055*
+ ID_PRODUCT_FROM_DATABASE=3c556 Hurricane CardBus [Cyclone]
+
+pci:v000010B7d00006056*
+ ID_PRODUCT_FROM_DATABASE=3c556B CardBus [Tornado]
+
+pci:v000010B7d00006056sv000010B7sd00006556*
+ ID_PRODUCT_FROM_DATABASE=10/100 Mini PCI Ethernet Adapter
+
+pci:v000010B7d00006560*
+ ID_PRODUCT_FROM_DATABASE=3cCFE656 CardBus [Cyclone]
+
+pci:v000010B7d00006560sv000010B7sd0000656A*
+ ID_PRODUCT_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus
+
+pci:v000010B7d00006561*
+ ID_PRODUCT_FROM_DATABASE=3cCFEM656 10/100 LAN+56K Modem CardBus
+
+pci:v000010B7d00006561sv000010B7sd0000656B*
+ ID_PRODUCT_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus
+
+pci:v000010B7d00006562*
+ ID_PRODUCT_FROM_DATABASE=3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone]
+
+pci:v000010B7d00006562sv000010B7sd0000656B*
+ ID_PRODUCT_FROM_DATABASE=3CCFEM656B 10/100 LAN+56K Modem CardBus
+
+pci:v000010B7d00006563*
+ ID_PRODUCT_FROM_DATABASE=3cCFEM656B 10/100 LAN+56K Modem CardBus
+
+pci:v000010B7d00006563sv000010B7sd0000656B*
+ ID_PRODUCT_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus
+
+pci:v000010B7d00006564*
+ ID_PRODUCT_FROM_DATABASE=3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado]
+
+pci:v000010B7d00007646*
+ ID_PRODUCT_FROM_DATABASE=3cSOHO100-TX Hurricane
+
+pci:v000010B7d00007770*
+ ID_PRODUCT_FROM_DATABASE=3CRWE777 PCI(PLX) Wireless Adaptor [Airconnect]
+
+pci:v000010B7d00007940*
+ ID_PRODUCT_FROM_DATABASE=3c803 FDDILink UTP Controller
+
+pci:v000010B7d00007980*
+ ID_PRODUCT_FROM_DATABASE=3c804 FDDILink SAS Controller
+
+pci:v000010B7d00007990*
+ ID_PRODUCT_FROM_DATABASE=3c805 FDDILink DAS Controller
+
+pci:v000010B7d000080EB*
+ ID_PRODUCT_FROM_DATABASE=3c940B 10/100/1000Base-T
+
+pci:v000010B7d00008811*
+ ID_PRODUCT_FROM_DATABASE=Token ring
+
+pci:v000010B7d00009000*
+ ID_PRODUCT_FROM_DATABASE=3c900 10BaseT [Boomerang]
+
+pci:v000010B7d00009001*
+ ID_PRODUCT_FROM_DATABASE=3c900 10Mbps Combo [Boomerang]
+
+pci:v000010B7d00009004*
+ ID_PRODUCT_FROM_DATABASE=3c900B-TPO Etherlink XL [Cyclone]
+
+pci:v000010B7d00009004sv000010B7sd00009004*
+ ID_PRODUCT_FROM_DATABASE=3C900B-TPO Etherlink XL TPO 10Mb
+
+pci:v000010B7d00009005*
+ ID_PRODUCT_FROM_DATABASE=3c900B-Combo Etherlink XL [Cyclone]
+
+pci:v000010B7d00009005sv000010B7sd00009005*
+ ID_PRODUCT_FROM_DATABASE=3C900B-Combo Etherlink XL Combo
+
+pci:v000010B7d00009006*
+ ID_PRODUCT_FROM_DATABASE=3c900B-TPC Etherlink XL [Cyclone]
+
+pci:v000010B7d0000900A*
+ ID_PRODUCT_FROM_DATABASE=3c900B-FL 10base-FL [Cyclone]
+
+pci:v000010B7d00009050*
+ ID_PRODUCT_FROM_DATABASE=3c905 100BaseTX [Boomerang]
+
+pci:v000010B7d00009051*
+ ID_PRODUCT_FROM_DATABASE=3c905 100BaseT4 [Boomerang]
+
+pci:v000010B7d00009054*
+ ID_PRODUCT_FROM_DATABASE=3C905B-TX Fast Etherlink XL PCI
+
+pci:v000010B7d00009054sv000010B7sd00009054*
+ ID_PRODUCT_FROM_DATABASE=3C905B-TX Fast Etherlink XL PCI
+
+pci:v000010B7d00009055*
+ ID_PRODUCT_FROM_DATABASE=3c905B 100BaseTX [Cyclone]
+
+pci:v000010B7d00009055sv00001028sd00000080*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000081*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000082*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000083*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000084*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000085*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000086*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000087*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000088*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000089*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000090*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000091*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000092*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000093*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000094*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000095*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000096*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000097*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000098*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv00001028sd00000099*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009055sv000010B7sd00009055*
+ ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+
+pci:v000010B7d00009056*
+ ID_PRODUCT_FROM_DATABASE=3c905B-T4 Fast EtherLink XL [Cyclone]
+
+pci:v000010B7d00009058*
+ ID_PRODUCT_FROM_DATABASE=3c905B Deluxe Etherlink 10/100/BNC [Cyclone]
+
+pci:v000010B7d0000905A*
+ ID_PRODUCT_FROM_DATABASE=3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone]
+
+pci:v000010B7d00009200*
+ ID_PRODUCT_FROM_DATABASE=3c905C-TX/TX-M [Tornado]
+
+pci:v000010B7d00009200sv00001028sd00000095*
+ ID_PRODUCT_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller
+
+pci:v000010B7d00009200sv00001028sd00000097*
+ ID_PRODUCT_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller
+
+pci:v000010B7d00009200sv00001028sd000000B4*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX110
+
+pci:v000010B7d00009200sv00001028sd000000D8*
+ ID_PRODUCT_FROM_DATABASE=Precision 530
+
+pci:v000010B7d00009200sv00001028sd000000FE*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX240
+
+pci:v000010B7d00009200sv00001028sd0000012A*
+ ID_PRODUCT_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller [Latitude C640]
+
+pci:v000010B7d00009200sv000010B7sd00001000*
+ ID_PRODUCT_FROM_DATABASE=3C905CX-TX/TX-M Fast Etherlink for PC Management NIC
+
+pci:v000010B7d00009200sv000010B7sd00007000*
+ ID_PRODUCT_FROM_DATABASE=10/100 Mini PCI Ethernet Adapter
+
+pci:v000010B7d00009200sv000010F1sd00002466*
+ ID_PRODUCT_FROM_DATABASE=Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller)
+
+pci:v000010B7d00009200sv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v000010B7d00009201*
+ ID_PRODUCT_FROM_DATABASE=3C920B-EMB Integrated Fast Ethernet Controller [Tornado]
+
+pci:v000010B7d00009201sv00001043sd000080AB*
+ ID_PRODUCT_FROM_DATABASE=A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller
+
+pci:v000010B7d00009202*
+ ID_PRODUCT_FROM_DATABASE=3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller
+
+pci:v000010B7d00009210*
+ ID_PRODUCT_FROM_DATABASE=3C920B-EMB-WNM Integrated Fast Ethernet Controller
+
+pci:v000010B7d00009300*
+ ID_PRODUCT_FROM_DATABASE=3CSOHO100B-TX 910-A01 [tulip]
+
+pci:v000010B7d00009800*
+ ID_PRODUCT_FROM_DATABASE=3c980-TX Fast Etherlink XL Server Adapter [Cyclone]
+
+pci:v000010B7d00009800sv000010B7sd00009800*
+ ID_PRODUCT_FROM_DATABASE=3c980-TX Fast Etherlink XL Server Adapter
+
+pci:v000010B7d00009805*
+ ID_PRODUCT_FROM_DATABASE=3c980-C 10/100baseTX NIC [Python-T]
+
+pci:v000010B7d00009805sv000010B7sd00001201*
+ ID_PRODUCT_FROM_DATABASE=EtherLink Server 10/100 Dual Port A
+
+pci:v000010B7d00009805sv000010B7sd00001202*
+ ID_PRODUCT_FROM_DATABASE=EtherLink Server 10/100 Dual Port B
+
+pci:v000010B7d00009805sv000010B7sd00009805*
+ ID_PRODUCT_FROM_DATABASE=3c980 10/100baseTX NIC [Python-T]
+
+pci:v000010B7d00009805sv000010F1sd00002462*
+ ID_PRODUCT_FROM_DATABASE=Thunder K7 S2462
+
+pci:v000010B7d00009900*
+ ID_PRODUCT_FROM_DATABASE=3C990-TX [Typhoon]
+
+pci:v000010B7d00009902*
+ ID_PRODUCT_FROM_DATABASE=3CR990-TX-95 [Typhoon 56-bit]
+
+pci:v000010B7d00009903*
+ ID_PRODUCT_FROM_DATABASE=3CR990-TX-97 [Typhoon 168-bit]
+
+pci:v000010B7d00009904*
+ ID_PRODUCT_FROM_DATABASE=3C990B-TX-M/3C990BSVR [Typhoon2]
+
+pci:v000010B7d00009904sv000010B7sd00001000*
+ ID_PRODUCT_FROM_DATABASE=3CR990B-TX-M [Typhoon2]
+
+pci:v000010B7d00009904sv000010B7sd00002000*
+ ID_PRODUCT_FROM_DATABASE=3CR990BSVR [Typhoon2 Server]
+
+pci:v000010B7d00009905*
+ ID_PRODUCT_FROM_DATABASE=3CR990-FX-95/97/95 [Typhon Fiber]
+
+pci:v000010B7d00009905sv000010B7sd00001101*
+ ID_PRODUCT_FROM_DATABASE=3CR990-FX-95 [Typhoon Fiber 56-bit]
+
+pci:v000010B7d00009905sv000010B7sd00001102*
+ ID_PRODUCT_FROM_DATABASE=3CR990-FX-97 [Typhoon Fiber 168-bit]
+
+pci:v000010B7d00009905sv000010B7sd00002101*
+ ID_PRODUCT_FROM_DATABASE=3CR990-FX-95 Server [Typhoon Fiber 56-bit]
+
+pci:v000010B7d00009905sv000010B7sd00002102*
+ ID_PRODUCT_FROM_DATABASE=3CR990-FX-97 Server [Typhoon Fiber 168-bit]
+
+pci:v000010B7d00009908*
+ ID_PRODUCT_FROM_DATABASE=3CR990SVR95 [Typhoon Server 56-bit]
+
+pci:v000010B7d00009909*
+ ID_PRODUCT_FROM_DATABASE=3CR990SVR97 [Typhoon Server 168-bit]
+
+pci:v000010B7d0000990A*
+ ID_PRODUCT_FROM_DATABASE=3C990SVR [Typhoon Server]
+
+pci:v000010B7d0000990B*
+ ID_PRODUCT_FROM_DATABASE=3C990SVR [Typhoon Server]
+
+pci:v000010B8*
+ ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp [SMC]
+
+pci:v000010B8d00000005*
+ ID_PRODUCT_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter
+
+pci:v000010B8d00000005sv00001055sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC 10/100 [EVB171Q-PCI]
+
+pci:v000010B8d00000005sv00001055sd0000E002*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC 10/100 [EVB171G-PCI]
+
+pci:v000010B8d00000005sv000010B8sd0000A011*
+ ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100
+
+pci:v000010B8d00000005sv000010B8sd0000A014*
+ ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100
+
+pci:v000010B8d00000005sv000010B8sd0000A015*
+ ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100
+
+pci:v000010B8d00000005sv000010B8sd0000A016*
+ ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100
+
+pci:v000010B8d00000005sv000010B8sd0000A017*
+ ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100
+
+pci:v000010B8d00000006*
+ ID_PRODUCT_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter
+
+pci:v000010B8d00000006sv00001055sd0000E100*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+
+pci:v000010B8d00000006sv00001055sd0000E102*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+
+pci:v000010B8d00000006sv00001055sd0000E300*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+
+pci:v000010B8d00000006sv00001055sd0000E302*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+
+pci:v000010B8d00000006sv000010B8sd0000A012*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+
+pci:v000010B8d00000006sv000013A2sd00008002*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+
+pci:v000010B8d00000006sv000013A2sd00008006*
+ ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+
+pci:v000010B8d00001000*
+ ID_PRODUCT_FROM_DATABASE=FDC 37c665
+
+pci:v000010B8d00001001*
+ ID_PRODUCT_FROM_DATABASE=FDC 37C922
+
+pci:v000010B8d0000A011*
+ ID_PRODUCT_FROM_DATABASE=83C170QF
+
+pci:v000010B8d0000B106*
+ ID_PRODUCT_FROM_DATABASE=SMC34C90
+
+pci:v000010B9*
+ ID_VENDOR_FROM_DATABASE=ULi Electronics Inc.
+
+pci:v000010B9d00000101*
+ ID_PRODUCT_FROM_DATABASE=CMI8338/C3DX PCI Audio Device
+
+pci:v000010B9d00000111*
+ ID_PRODUCT_FROM_DATABASE=C-Media CMI8738/C3DX Audio Device (OEM)
+
+pci:v000010B9d00000111sv000010B9sd00000111*
+ ID_PRODUCT_FROM_DATABASE=C-Media CMI8738/C3DX Audio Device (OEM)
+
+pci:v000010B9d00000780*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v000010B9d00000782*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v000010B9d00001435*
+ ID_PRODUCT_FROM_DATABASE=M1435
+
+pci:v000010B9d00001445*
+ ID_PRODUCT_FROM_DATABASE=M1445
+
+pci:v000010B9d00001449*
+ ID_PRODUCT_FROM_DATABASE=M1449
+
+pci:v000010B9d00001451*
+ ID_PRODUCT_FROM_DATABASE=M1451
+
+pci:v000010B9d00001461*
+ ID_PRODUCT_FROM_DATABASE=M1461
+
+pci:v000010B9d00001489*
+ ID_PRODUCT_FROM_DATABASE=M1489
+
+pci:v000010B9d00001511*
+ ID_PRODUCT_FROM_DATABASE=M1511 [Aladdin]
+
+pci:v000010B9d00001512*
+ ID_PRODUCT_FROM_DATABASE=M1512 [Aladdin]
+
+pci:v000010B9d00001513*
+ ID_PRODUCT_FROM_DATABASE=M1513 [Aladdin]
+
+pci:v000010B9d00001521*
+ ID_PRODUCT_FROM_DATABASE=M1521 [Aladdin III]
+
+pci:v000010B9d00001521sv000010B9sd00001521*
+ ID_PRODUCT_FROM_DATABASE=ALI M1521 Aladdin III CPU Bridge
+
+pci:v000010B9d00001523*
+ ID_PRODUCT_FROM_DATABASE=M1523
+
+pci:v000010B9d00001523sv000010B9sd00001523*
+ ID_PRODUCT_FROM_DATABASE=ALI M1523 ISA Bridge
+
+pci:v000010B9d00001531*
+ ID_PRODUCT_FROM_DATABASE=M1531 [Aladdin IV]
+
+pci:v000010B9d00001533*
+ ID_PRODUCT_FROM_DATABASE=M1533/M1535/M1543 PCI to ISA Bridge [Aladdin IV/V/V+]
+
+pci:v000010B9d00001533sv00001014sd0000053B*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v000010B9d00001533sv000010B9sd00001533*
+ ID_PRODUCT_FROM_DATABASE=ALi M1533 Aladdin IV/V ISA Bridge
+
+pci:v000010B9d00001541*
+ ID_PRODUCT_FROM_DATABASE=M1541
+
+pci:v000010B9d00001541sv000010B9sd00001541*
+ ID_PRODUCT_FROM_DATABASE=ALI M1541 Aladdin V/V+ AGP System Controller
+
+pci:v000010B9d00001543*
+ ID_PRODUCT_FROM_DATABASE=M1543
+
+pci:v000010B9d00001563*
+ ID_PRODUCT_FROM_DATABASE=M1563 HyperTransport South Bridge
+
+pci:v000010B9d00001563sv000010B9sd00001563*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010B9d00001563sv00001849sd00001563*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010B9d00001573*
+ ID_PRODUCT_FROM_DATABASE=PCI to LPC Controller
+
+pci:v000010B9d00001575*
+ ID_PRODUCT_FROM_DATABASE=M1575 South Bridge
+
+pci:v000010B9d00001621*
+ ID_PRODUCT_FROM_DATABASE=M1621
+
+pci:v000010B9d00001631*
+ ID_PRODUCT_FROM_DATABASE=ALI M1631 PCI North Bridge Aladdin Pro III
+
+pci:v000010B9d00001632*
+ ID_PRODUCT_FROM_DATABASE=M1632M Northbridge+Trident
+
+pci:v000010B9d00001641*
+ ID_PRODUCT_FROM_DATABASE=ALI M1641 PCI North Bridge Aladdin Pro IV
+
+pci:v000010B9d00001644*
+ ID_PRODUCT_FROM_DATABASE=M1644/M1644T Northbridge+Trident
+
+pci:v000010B9d00001646*
+ ID_PRODUCT_FROM_DATABASE=M1646 Northbridge+Trident
+
+pci:v000010B9d00001647*
+ ID_PRODUCT_FROM_DATABASE=M1647 Northbridge [MAGiK 1 / MobileMAGiK 1]
+
+pci:v000010B9d00001651*
+ ID_PRODUCT_FROM_DATABASE=M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM]
+
+pci:v000010B9d00001671*
+ ID_PRODUCT_FROM_DATABASE=M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR]
+
+pci:v000010B9d00001672*
+ ID_PRODUCT_FROM_DATABASE=M1672 Northbridge [CyberALADDiN-P4]
+
+pci:v000010B9d00001681*
+ ID_PRODUCT_FROM_DATABASE=M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR]
+
+pci:v000010B9d00001687*
+ ID_PRODUCT_FROM_DATABASE=M1687 K8 Northbridge [AGP8X and HyperTransport]
+
+pci:v000010B9d00001689*
+ ID_PRODUCT_FROM_DATABASE=M1689 K8 Northbridge [Super K8 Single Chip]
+
+pci:v000010B9d00001695*
+ ID_PRODUCT_FROM_DATABASE=M1695 K8 Northbridge [PCI Express and HyperTransport]
+
+pci:v000010B9d00001697*
+ ID_PRODUCT_FROM_DATABASE=M1697 HTT Host Bridge
+
+pci:v000010B9d00003141*
+ ID_PRODUCT_FROM_DATABASE=M3141
+
+pci:v000010B9d00003143*
+ ID_PRODUCT_FROM_DATABASE=M3143
+
+pci:v000010B9d00003145*
+ ID_PRODUCT_FROM_DATABASE=M3145
+
+pci:v000010B9d00003147*
+ ID_PRODUCT_FROM_DATABASE=M3147
+
+pci:v000010B9d00003149*
+ ID_PRODUCT_FROM_DATABASE=M3149
+
+pci:v000010B9d00003151*
+ ID_PRODUCT_FROM_DATABASE=M3151
+
+pci:v000010B9d00003307*
+ ID_PRODUCT_FROM_DATABASE=M3307
+
+pci:v000010B9d00003309*
+ ID_PRODUCT_FROM_DATABASE=M3309
+
+pci:v000010B9d00003323*
+ ID_PRODUCT_FROM_DATABASE=M3325 Video/Audio Decoder
+
+pci:v000010B9d00005212*
+ ID_PRODUCT_FROM_DATABASE=M4803
+
+pci:v000010B9d00005215*
+ ID_PRODUCT_FROM_DATABASE=MS4803
+
+pci:v000010B9d00005217*
+ ID_PRODUCT_FROM_DATABASE=M5217H
+
+pci:v000010B9d00005219*
+ ID_PRODUCT_FROM_DATABASE=M5219
+
+pci:v000010B9d00005225*
+ ID_PRODUCT_FROM_DATABASE=M5225
+
+pci:v000010B9d00005228*
+ ID_PRODUCT_FROM_DATABASE=M5228 ALi ATA/RAID Controller
+
+pci:v000010B9d00005229*
+ ID_PRODUCT_FROM_DATABASE=M5229 IDE
+
+pci:v000010B9d00005229sv00001014sd0000050F*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R30
+
+pci:v000010B9d00005229sv00001014sd0000053D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v000010B9d00005229sv0000103Csd00000024*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin IDE
+
+pci:v000010B9d00005229sv0000103Csd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v000010B9d00005229sv00001043sd00008053*
+ ID_PRODUCT_FROM_DATABASE=A7A266 Motherboard IDE
+
+pci:v000010B9d00005229sv00001849sd00005229*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard IDE (PATA)
+
+pci:v000010B9d00005235*
+ ID_PRODUCT_FROM_DATABASE=M5225
+
+pci:v000010B9d00005237*
+ ID_PRODUCT_FROM_DATABASE=USB 1.1 Controller
+
+pci:v000010B9d00005237sv00001014sd00000540*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v000010B9d00005237sv0000103Csd00000024*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin USB
+
+pci:v000010B9d00005237sv0000103Csd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v000010B9d00005237sv0000104Dsd0000810F*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-U1 USB/OHCI Revision 1.0
+
+pci:v000010B9d00005237sv000010B9sd00005237*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010B9d00005237sv00001849sd00005237*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010B9d00005239*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Controller
+
+pci:v000010B9d00005239sv000010B9sd00005239*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010B9d00005239sv00001849sd00005239*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010B9d00005243*
+ ID_PRODUCT_FROM_DATABASE=M1541 PCI to AGP Controller
+
+pci:v000010B9d00005246*
+ ID_PRODUCT_FROM_DATABASE=AGP8X Controller
+
+pci:v000010B9d00005247*
+ ID_PRODUCT_FROM_DATABASE=PCI to AGP Controller
+
+pci:v000010B9d00005249*
+ ID_PRODUCT_FROM_DATABASE=M5249 HTT to PCI Bridge
+
+pci:v000010B9d0000524B*
+ ID_PRODUCT_FROM_DATABASE=PCI Express Root Port
+
+pci:v000010B9d0000524C*
+ ID_PRODUCT_FROM_DATABASE=PCI Express Root Port
+
+pci:v000010B9d0000524D*
+ ID_PRODUCT_FROM_DATABASE=PCI Express Root Port
+
+pci:v000010B9d0000524E*
+ ID_PRODUCT_FROM_DATABASE=PCI Express Root Port
+
+pci:v000010B9d00005251*
+ ID_PRODUCT_FROM_DATABASE=M5251 P1394 OHCI 1.0 Controller
+
+pci:v000010B9d00005253*
+ ID_PRODUCT_FROM_DATABASE=M5253 P1394 OHCI 1.1 Controller
+
+pci:v000010B9d00005261*
+ ID_PRODUCT_FROM_DATABASE=M5261 Ethernet Controller
+
+pci:v000010B9d00005263*
+ ID_PRODUCT_FROM_DATABASE=ULi 1689,1573 integrated ethernet.
+
+pci:v000010B9d00005281*
+ ID_PRODUCT_FROM_DATABASE=ALi M5281 Serial ATA / RAID Host Controller
+
+pci:v000010B9d00005287*
+ ID_PRODUCT_FROM_DATABASE=ULi 5287 SATA
+
+pci:v000010B9d00005288*
+ ID_PRODUCT_FROM_DATABASE=ULi M5288 SATA
+
+pci:v000010B9d00005288sv00001043sd00008056*
+ ID_PRODUCT_FROM_DATABASE=A8R-MVP Mainboard
+
+pci:v000010B9d00005289*
+ ID_PRODUCT_FROM_DATABASE=ULi 5289 SATA
+
+pci:v000010B9d00005450*
+ ID_PRODUCT_FROM_DATABASE=Lucent Technologies Soft Modem AMR
+
+pci:v000010B9d00005451*
+ ID_PRODUCT_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device
+
+pci:v000010B9d00005451sv00001014sd00000506*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R30
+
+pci:v000010B9d00005451sv00001014sd0000053E*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v000010B9d00005451sv0000103Csd00000024*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin Audio
+
+pci:v000010B9d00005451sv0000103Csd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v000010B9d00005453*
+ ID_PRODUCT_FROM_DATABASE=M5453 PCI AC-Link Controller Modem Device
+
+pci:v000010B9d00005455*
+ ID_PRODUCT_FROM_DATABASE=M5455 PCI AC-Link Controller Audio Device
+
+pci:v000010B9d00005455sv000010B9sd00005455*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010B9d00005455sv00001849sd00000850*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010B9d00005457*
+ ID_PRODUCT_FROM_DATABASE=M5457 AC'97 Modem Controller
+
+pci:v000010B9d00005457sv00001014sd00000535*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v000010B9d00005457sv0000103Csd00000024*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin Modem Device
+
+pci:v000010B9d00005457sv0000103Csd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v000010B9d00005459*
+ ID_PRODUCT_FROM_DATABASE=SmartLink SmartPCI561 56K Modem
+
+pci:v000010B9d0000545A*
+ ID_PRODUCT_FROM_DATABASE=SmartLink SmartPCI563 56K Modem
+
+pci:v000010B9d00005461*
+ ID_PRODUCT_FROM_DATABASE=HD Audio Controller
+
+pci:v000010B9d00005471*
+ ID_PRODUCT_FROM_DATABASE=M5471 Memory Stick Controller
+
+pci:v000010B9d00005473*
+ ID_PRODUCT_FROM_DATABASE=M5473 SD-MMC Controller
+
+pci:v000010B9d00007101*
+ ID_PRODUCT_FROM_DATABASE=M7101 Power Management Controller [PMU]
+
+pci:v000010B9d00007101sv00001014sd00000510*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R30
+
+pci:v000010B9d00007101sv00001014sd0000053C*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v000010B9d00007101sv0000103Csd00000024*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ze4400
+
+pci:v000010B9d00007101sv0000103Csd00000025*
+ ID_PRODUCT_FROM_DATABASE=XE4500 Notebook
+
+pci:v000010B9d00007101sv00001849sd00007101*
+ ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+
+pci:v000010BA*
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corp.
+
+pci:v000010BAd00000301*
+ ID_PRODUCT_FROM_DATABASE=AccelGraphics AccelECLIPSE
+
+pci:v000010BAd00000304*
+ ID_PRODUCT_FROM_DATABASE=AccelGALAXY A2100 [OEM Evans & Sutherland]
+
+pci:v000010BAd00000308*
+ ID_PRODUCT_FROM_DATABASE=Tornado 3000 [OEM Evans & Sutherland]
+
+pci:v000010BAd00000308sv000010DDsd00000024*
+ ID_PRODUCT_FROM_DATABASE=Tornado 3000
+
+pci:v000010BAd00001002*
+ ID_PRODUCT_FROM_DATABASE=VG500 [VolumePro Volume Rendering Accelerator]
+
+pci:v000010BB*
+ ID_VENDOR_FROM_DATABASE=Dapha Electronics Corporation
+
+pci:v000010BC*
+ ID_VENDOR_FROM_DATABASE=Advanced Logic Research
+
+pci:v000010BD*
+ ID_VENDOR_FROM_DATABASE=Surecom Technology
+
+pci:v000010BDd00000E34*
+ ID_PRODUCT_FROM_DATABASE=NE-34
+
+pci:v000010BE*
+ ID_VENDOR_FROM_DATABASE=Tseng Labs International Co.
+
+pci:v000010BF*
+ ID_VENDOR_FROM_DATABASE=Most Inc
+
+pci:v000010C0*
+ ID_VENDOR_FROM_DATABASE=Boca Research Inc.
+
+pci:v000010C1*
+ ID_VENDOR_FROM_DATABASE=ICM Co., Ltd.
+
+pci:v000010C2*
+ ID_VENDOR_FROM_DATABASE=Auspex Systems Inc.
+
+pci:v000010C3*
+ ID_VENDOR_FROM_DATABASE=Samsung Semiconductors, Inc.
+
+pci:v000010C3d00001100*
+ ID_PRODUCT_FROM_DATABASE=Smartether100 SC1100 LAN Adapter (i82557B)
+
+pci:v000010C4*
+ ID_VENDOR_FROM_DATABASE=Award Software International Inc.
+
+pci:v000010C5*
+ ID_VENDOR_FROM_DATABASE=Xerox Corporation
+
+pci:v000010C6*
+ ID_VENDOR_FROM_DATABASE=Rambus Inc.
+
+pci:v000010C7*
+ ID_VENDOR_FROM_DATABASE=Media Vision
+
+pci:v000010C8*
+ ID_VENDOR_FROM_DATABASE=Neomagic Corporation
+
+pci:v000010C8d00000001*
+ ID_PRODUCT_FROM_DATABASE=NM2070 [MagicGraph 128]
+
+pci:v000010C8d00000002*
+ ID_PRODUCT_FROM_DATABASE=NM2090 [MagicGraph 128V]
+
+pci:v000010C8d00000003*
+ ID_PRODUCT_FROM_DATABASE=NM2093 [MagicGraph 128ZV]
+
+pci:v000010C8d00000004*
+ ID_PRODUCT_FROM_DATABASE=NM2160 [MagicGraph 128XD]
+
+pci:v000010C8d00000004sv00001014sd000000BA*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv00001025sd00001007*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv00001028sd00000074*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv00001028sd00000075*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv00001028sd0000007D*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv00001028sd0000007E*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv00001033sd0000802F*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv0000104Dsd0000801B*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv0000104Dsd0000802F*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv0000104Dsd0000830B*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv000010BAsd00000E00*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv000010C8sd00000004*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv000010CFsd00001029*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv000010F7sd00008308*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv000010F7sd00008309*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv000010F7sd0000830B*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv000010F7sd0000830D*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000004sv000010F7sd00008312*
+ ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD
+
+pci:v000010C8d00000005*
+ ID_PRODUCT_FROM_DATABASE=NM2200 [MagicGraph 256AV]
+
+pci:v000010C8d00000005sv00001014sd000000DD*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 570
+
+pci:v000010C8d00000005sv00001028sd00000088*
+ ID_PRODUCT_FROM_DATABASE=Latitude CPi A
+
+pci:v000010C8d00000006*
+ ID_PRODUCT_FROM_DATABASE=NM2360 [MagicMedia 256ZX]
+
+pci:v000010C8d00000006sv00001014sd00000152*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 600X
+
+pci:v000010C8d00000016*
+ ID_PRODUCT_FROM_DATABASE=NM2380 [MagicMedia 256XL+]
+
+pci:v000010C8d00000016sv000010C8sd00000016*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256XL+
+
+pci:v000010C8d00000025*
+ ID_PRODUCT_FROM_DATABASE=NM2230 [MagicGraph 256AV+]
+
+pci:v000010C8d00000083*
+ ID_PRODUCT_FROM_DATABASE=NM2093 [MagicGraph 128ZV+]
+
+pci:v000010C8d00008005*
+ ID_PRODUCT_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio]
+
+pci:v000010C8d00008005sv00000E11sd0000B0D1*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Discovery
+
+pci:v000010C8d00008005sv00000E11sd0000B126*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Durango
+
+pci:v000010C8d00008005sv00001014sd000000DD*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 390/i1720/i1721
+
+pci:v000010C8d00008005sv00001025sd00001003*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on TravelMate 720
+
+pci:v000010C8d00008005sv00001028sd00000088*
+ ID_PRODUCT_FROM_DATABASE=Latitude CPi A
+
+pci:v000010C8d00008005sv00001028sd0000008F*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Colorado Inspiron
+
+pci:v000010C8d00008005sv0000103Csd00000007*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Voyager II
+
+pci:v000010C8d00008005sv0000103Csd00000008*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Voyager III
+
+pci:v000010C8d00008005sv0000103Csd0000000D*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Omnibook 900
+
+pci:v000010C8d00008005sv000010C8sd00008005*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on FireAnt
+
+pci:v000010C8d00008005sv0000110Asd00008005*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device
+
+pci:v000010C8d00008005sv000014C0sd00000004*
+ ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device
+
+pci:v000010C8d00008006*
+ ID_PRODUCT_FROM_DATABASE=NM2360 [MagicMedia 256ZX Audio]
+
+pci:v000010C8d00008016*
+ ID_PRODUCT_FROM_DATABASE=NM2380 [MagicMedia 256XL+ Audio]
+
+pci:v000010C9*
+ ID_VENDOR_FROM_DATABASE=Dataexpert Corporation
+
+pci:v000010CA*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Microelectr., Inc.
+
+pci:v000010CB*
+ ID_VENDOR_FROM_DATABASE=Omron Corporation
+
+pci:v000010CC*
+ ID_VENDOR_FROM_DATABASE=Mai Logic Incorporated
+
+pci:v000010CCd00000660*
+ ID_PRODUCT_FROM_DATABASE=Articia S Host Bridge
+
+pci:v000010CCd00000661*
+ ID_PRODUCT_FROM_DATABASE=Articia S PCI Bridge
+
+pci:v000010CD*
+ ID_VENDOR_FROM_DATABASE=Advanced System Products, Inc
+
+pci:v000010CDd00001100*
+ ID_PRODUCT_FROM_DATABASE=ASC1100
+
+pci:v000010CDd00001200*
+ ID_PRODUCT_FROM_DATABASE=ASC1200 [(abp940) Fast SCSI-II]
+
+pci:v000010CDd00001300*
+ ID_PRODUCT_FROM_DATABASE=ABP940-U / ABP960-U
+
+pci:v000010CDd00001300sv000010CDsd00001310*
+ ID_PRODUCT_FROM_DATABASE=ASC1300 SCSI Adapter
+
+pci:v000010CDd00001300sv00001195sd00001320*
+ ID_PRODUCT_FROM_DATABASE=Ultra-SCSI CardBus PC Card REX CB31
+
+pci:v000010CDd00002300*
+ ID_PRODUCT_FROM_DATABASE=ABP940-UW
+
+pci:v000010CDd00002500*
+ ID_PRODUCT_FROM_DATABASE=ABP940-U2W
+
+pci:v000010CDd00002700*
+ ID_PRODUCT_FROM_DATABASE=ABP3950-U3W
+
+pci:v000010CE*
+ ID_VENDOR_FROM_DATABASE=Radius
+
+pci:v000010CF*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Limited.
+
+pci:v000010CFd000001EF*
+ ID_PRODUCT_FROM_DATABASE=PCEA4 PCI-Express Dual Port ESCON Adapter
+
+pci:v000010CFd00001414*
+ ID_PRODUCT_FROM_DATABASE=On-board USB 1.1 companion controller
+
+pci:v000010CFd00001415*
+ ID_PRODUCT_FROM_DATABASE=On-board USB 2.0 EHCI controller
+
+pci:v000010CFd00001422*
+ ID_PRODUCT_FROM_DATABASE=E8410 nVidia graphics adapter
+
+pci:v000010CFd0000142D*
+ ID_PRODUCT_FROM_DATABASE=HD audio (Realtek ALC262)
+
+pci:v000010CFd00001430*
+ ID_PRODUCT_FROM_DATABASE=82566MM Intel 1Gb copper LAN interface
+
+pci:v000010CFd00001623*
+ ID_PRODUCT_FROM_DATABASE=PCEA4 PCI-Express Dual Port ESCON Adapter
+
+pci:v000010CFd00002001*
+ ID_PRODUCT_FROM_DATABASE=mb86605
+
+pci:v000010CFd0000200C*
+ ID_PRODUCT_FROM_DATABASE=MB86613L IEEE1394 OHCI 1.0 Controller
+
+pci:v000010CFd00002010*
+ ID_PRODUCT_FROM_DATABASE=MB86613S IEEE1394 OHCI 1.1 Controller
+
+pci:v000010CFd00002019*
+ ID_PRODUCT_FROM_DATABASE=MB86295S [CORAL P]
+
+pci:v000010CFd0000201E*
+ ID_PRODUCT_FROM_DATABASE=MB86296S [CORAL PA]
+
+pci:v000010CFd0000202B*
+ ID_PRODUCT_FROM_DATABASE=MB86297A [Carmine Graphics Controller]
+
+pci:v000010D1*
+ ID_VENDOR_FROM_DATABASE=FuturePlus Systems Corp.
+
+pci:v000010D2*
+ ID_VENDOR_FROM_DATABASE=Molex Incorporated
+
+pci:v000010D3*
+ ID_VENDOR_FROM_DATABASE=Jabil Circuit Inc
+
+pci:v000010D4*
+ ID_VENDOR_FROM_DATABASE=Hualon Microelectronics
+
+pci:v000010D5*
+ ID_VENDOR_FROM_DATABASE=Autologic Inc.
+
+pci:v000010D6*
+ ID_VENDOR_FROM_DATABASE=Cetia
+
+pci:v000010D7*
+ ID_VENDOR_FROM_DATABASE=BCM Advanced Research
+
+pci:v000010D8*
+ ID_VENDOR_FROM_DATABASE=Advanced Peripherals Labs
+
+pci:v000010D9*
+ ID_VENDOR_FROM_DATABASE=Macronix, Inc. [MXIC]
+
+pci:v000010D9d00000431*
+ ID_PRODUCT_FROM_DATABASE=MX98715
+
+pci:v000010D9d00000512*
+ ID_PRODUCT_FROM_DATABASE=MX98713
+
+pci:v000010D9d00000531*
+ ID_PRODUCT_FROM_DATABASE=MX987x5
+
+pci:v000010D9d00000531sv00001186sd00001200*
+ ID_PRODUCT_FROM_DATABASE=DFE-540TX ProFAST 10/100 Adapter
+
+pci:v000010D9d00008625*
+ ID_PRODUCT_FROM_DATABASE=MX86250
+
+pci:v000010D9d00008626*
+ ID_PRODUCT_FROM_DATABASE=Macronix MX86251 + 3Dfx Voodoo Rush
+
+pci:v000010D9d00008888*
+ ID_PRODUCT_FROM_DATABASE=MX86200
+
+pci:v000010DA*
+ ID_VENDOR_FROM_DATABASE=Compaq IPG-Austin
+
+pci:v000010DAd00000508*
+ ID_PRODUCT_FROM_DATABASE=TC4048 Token Ring 4/16
+
+pci:v000010DAd00003390*
+ ID_PRODUCT_FROM_DATABASE=Tl3c3x9
+
+pci:v000010DB*
+ ID_VENDOR_FROM_DATABASE=Rohm LSI Systems, Inc.
+
+pci:v000010DC*
+ ID_VENDOR_FROM_DATABASE=CERN/ECP/EDU
+
+pci:v000010DCd00000001*
+ ID_PRODUCT_FROM_DATABASE=STAR/RD24 SCI-PCI (PMC)
+
+pci:v000010DCd00000002*
+ ID_PRODUCT_FROM_DATABASE=TAR/RD24 SCI-PCI (PMC)
+
+pci:v000010DCd00000021*
+ ID_PRODUCT_FROM_DATABASE=HIPPI destination
+
+pci:v000010DCd00000022*
+ ID_PRODUCT_FROM_DATABASE=HIPPI source
+
+pci:v000010DCd000010DC*
+ ID_PRODUCT_FROM_DATABASE=ATT2C15-3 FPGA
+
+pci:v000010DD*
+ ID_VENDOR_FROM_DATABASE=Evans & Sutherland
+
+pci:v000010DDd00000100*
+ ID_PRODUCT_FROM_DATABASE=Lightning 1200
+
+pci:v000010DDd00000100sv000010DDsd00000023*
+ ID_PRODUCT_FROM_DATABASE=Lightning 1200 15+16M
+
+pci:v000010DE*
+ ID_VENDOR_FROM_DATABASE=NVIDIA Corporation
+
+pci:v000010DEd00000008*
+ ID_PRODUCT_FROM_DATABASE=NV1 [EDGE 3D]
+
+pci:v000010DEd00000009*
+ ID_PRODUCT_FROM_DATABASE=NV1 [EDGE 3D]
+
+pci:v000010DEd00000020*
+ ID_PRODUCT_FROM_DATABASE=NV4 [RIVA TNT]
+
+pci:v000010DEd00000020sv00001043sd00000200*
+ ID_PRODUCT_FROM_DATABASE=V3400 TNT
+
+pci:v000010DEd00000020sv00001048sd00000C18*
+ ID_PRODUCT_FROM_DATABASE=Erazor II SGRAM
+
+pci:v000010DEd00000020sv00001048sd00000C19*
+ ID_PRODUCT_FROM_DATABASE=Erazor II
+
+pci:v000010DEd00000020sv00001048sd00000C1B*
+ ID_PRODUCT_FROM_DATABASE=Erazor II
+
+pci:v000010DEd00000020sv00001048sd00000C1C*
+ ID_PRODUCT_FROM_DATABASE=Erazor II
+
+pci:v000010DEd00000020sv00001092sd00000550*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00000552*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00004804*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00004808*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00004810*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00004812*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00004815*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00004820*
+ ID_PRODUCT_FROM_DATABASE=Viper V550 with TV out
+
+pci:v000010DEd00000020sv00001092sd00004822*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00004904*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00004914*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv00001092sd00008225*
+ ID_PRODUCT_FROM_DATABASE=Viper V550
+
+pci:v000010DEd00000020sv000010B4sd0000273D*
+ ID_PRODUCT_FROM_DATABASE=Velocity 4400
+
+pci:v000010DEd00000020sv000010B4sd0000273E*
+ ID_PRODUCT_FROM_DATABASE=Velocity 4400
+
+pci:v000010DEd00000020sv000010B4sd00002740*
+ ID_PRODUCT_FROM_DATABASE=Velocity 4400
+
+pci:v000010DEd00000020sv000010DEsd00000020*
+ ID_PRODUCT_FROM_DATABASE=Riva TNT
+
+pci:v000010DEd00000020sv00001102sd00001015*
+ ID_PRODUCT_FROM_DATABASE=Graphics Blaster CT6710
+
+pci:v000010DEd00000020sv00001102sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Graphics Blaster RIVA TNT
+
+pci:v000010DEd00000028*
+ ID_PRODUCT_FROM_DATABASE=NV5 [RIVA TNT2/TNT2 Pro]
+
+pci:v000010DEd00000028sv00001043sd00000200*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800 SGRAM
+
+pci:v000010DEd00000028sv00001043sd00000201*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800 SDRAM
+
+pci:v000010DEd00000028sv00001043sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PCI-V3800
+
+pci:v000010DEd00000028sv00001043sd00004000*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800PRO
+
+pci:v000010DEd00000028sv00001048sd00000C21*
+ ID_PRODUCT_FROM_DATABASE=Synergy II
+
+pci:v000010DEd00000028sv00001048sd00000C28*
+ ID_PRODUCT_FROM_DATABASE=Erazor III
+
+pci:v000010DEd00000028sv00001048sd00000C29*
+ ID_PRODUCT_FROM_DATABASE=Erazor III
+
+pci:v000010DEd00000028sv00001048sd00000C2A*
+ ID_PRODUCT_FROM_DATABASE=Erazor III
+
+pci:v000010DEd00000028sv00001048sd00000C2B*
+ ID_PRODUCT_FROM_DATABASE=Erazor III
+
+pci:v000010DEd00000028sv00001048sd00000C31*
+ ID_PRODUCT_FROM_DATABASE=Erazor III Pro
+
+pci:v000010DEd00000028sv00001048sd00000C32*
+ ID_PRODUCT_FROM_DATABASE=Erazor III Pro
+
+pci:v000010DEd00000028sv00001048sd00000C33*
+ ID_PRODUCT_FROM_DATABASE=Erazor III Pro
+
+pci:v000010DEd00000028sv00001048sd00000C34*
+ ID_PRODUCT_FROM_DATABASE=Erazor III Pro
+
+pci:v000010DEd00000028sv0000107Dsd00002134*
+ ID_PRODUCT_FROM_DATABASE=WinFast 3D S320 II + TV-Out
+
+pci:v000010DEd00000028sv00001092sd00004804*
+ ID_PRODUCT_FROM_DATABASE=Viper V770
+
+pci:v000010DEd00000028sv00001092sd00004A00*
+ ID_PRODUCT_FROM_DATABASE=Viper V770
+
+pci:v000010DEd00000028sv00001092sd00004A02*
+ ID_PRODUCT_FROM_DATABASE=Viper V770 Ultra
+
+pci:v000010DEd00000028sv00001092sd00005A00*
+ ID_PRODUCT_FROM_DATABASE=RIVA TNT2/TNT2 Pro
+
+pci:v000010DEd00000028sv00001092sd00006A02*
+ ID_PRODUCT_FROM_DATABASE=Viper V770 Ultra
+
+pci:v000010DEd00000028sv00001092sd00007A02*
+ ID_PRODUCT_FROM_DATABASE=Viper V770 Ultra
+
+pci:v000010DEd00000028sv000010DEsd00000005*
+ ID_PRODUCT_FROM_DATABASE=RIVA TNT2 Pro
+
+pci:v000010DEd00000028sv000010DEsd0000000F*
+ ID_PRODUCT_FROM_DATABASE=Compaq NVIDIA TNT2 Pro
+
+pci:v000010DEd00000028sv00001102sd00001020*
+ ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2
+
+pci:v000010DEd00000028sv00001102sd00001026*
+ ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 Digital
+
+pci:v000010DEd00000028sv00001462sd00008806*
+ ID_PRODUCT_FROM_DATABASE=MS-8806 AGPhantom Graphics Card
+
+pci:v000010DEd00000028sv000014AFsd00005810*
+ ID_PRODUCT_FROM_DATABASE=Maxi Gamer Xentor
+
+pci:v000010DEd00000029*
+ ID_PRODUCT_FROM_DATABASE=NV5 [RIVA TNT2 Ultra]
+
+pci:v000010DEd00000029sv00001043sd00000200*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800 Deluxe
+
+pci:v000010DEd00000029sv00001043sd00000201*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800 Ultra SDRAM
+
+pci:v000010DEd00000029sv00001043sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PCI-V3800 Ultra
+
+pci:v000010DEd00000029sv00001048sd00000C2E*
+ ID_PRODUCT_FROM_DATABASE=Erazor III Ultra
+
+pci:v000010DEd00000029sv00001048sd00000C2F*
+ ID_PRODUCT_FROM_DATABASE=Erazor III Ultra
+
+pci:v000010DEd00000029sv00001048sd00000C30*
+ ID_PRODUCT_FROM_DATABASE=Erazor III Ultra
+
+pci:v000010DEd00000029sv00001102sd00001021*
+ ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra
+
+pci:v000010DEd00000029sv00001102sd00001029*
+ ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra
+
+pci:v000010DEd00000029sv00001102sd0000102F*
+ ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra
+
+pci:v000010DEd00000029sv000014AFsd00005820*
+ ID_PRODUCT_FROM_DATABASE=Maxi Gamer Xentor 32
+
+pci:v000010DEd0000002A*
+ ID_PRODUCT_FROM_DATABASE=NV5 [Riva TNT2]
+
+pci:v000010DEd0000002B*
+ ID_PRODUCT_FROM_DATABASE=NV5 [Riva TNT2]
+
+pci:v000010DEd0000002C*
+ ID_PRODUCT_FROM_DATABASE=NV6 [Vanta/Vanta LT]
+
+pci:v000010DEd0000002Csv00001043sd00000200*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800 Combat SDRAM
+
+pci:v000010DEd0000002Csv00001043sd00000201*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800 Combat
+
+pci:v000010DEd0000002Csv00001048sd00000C20*
+ ID_PRODUCT_FROM_DATABASE=TNT2 Vanta
+
+pci:v000010DEd0000002Csv00001048sd00000C21*
+ ID_PRODUCT_FROM_DATABASE=TNT2 Vanta
+
+pci:v000010DEd0000002Csv00001092sd00006820*
+ ID_PRODUCT_FROM_DATABASE=Viper V730
+
+pci:v000010DEd0000002Csv00001102sd00001031*
+ ID_PRODUCT_FROM_DATABASE=CT6938 VANTA 8MB
+
+pci:v000010DEd0000002Csv00001102sd00001034*
+ ID_PRODUCT_FROM_DATABASE=CT6894 VANTA 16MB
+
+pci:v000010DEd0000002Csv000014AFsd00005008*
+ ID_PRODUCT_FROM_DATABASE=Maxi Gamer Phoenix 2
+
+pci:v000010DEd0000002D*
+ ID_PRODUCT_FROM_DATABASE=NV5M64 [RIVA TNT2 Model 64/Model 64 Pro]
+
+pci:v000010DEd0000002Dsv00001043sd00000200*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800M
+
+pci:v000010DEd0000002Dsv00001043sd00000201*
+ ID_PRODUCT_FROM_DATABASE=AGP-V3800M
+
+pci:v000010DEd0000002Dsv00001048sd00000C3A*
+ ID_PRODUCT_FROM_DATABASE=Erazor III LT
+
+pci:v000010DEd0000002Dsv00001048sd00000C3B*
+ ID_PRODUCT_FROM_DATABASE=Erazor III LT
+
+pci:v000010DEd0000002Dsv000010DEsd00000006*
+ ID_PRODUCT_FROM_DATABASE=RIVA TNT2 Model 64/Model 64 Pro
+
+pci:v000010DEd0000002Dsv000010DEsd0000001E*
+ ID_PRODUCT_FROM_DATABASE=M64 AGP4x
+
+pci:v000010DEd0000002Dsv00001102sd00001023*
+ ID_PRODUCT_FROM_DATABASE=CT6892 RIVA TNT2 Value
+
+pci:v000010DEd0000002Dsv00001102sd00001024*
+ ID_PRODUCT_FROM_DATABASE=CT6932 RIVA TNT2 Value 32Mb
+
+pci:v000010DEd0000002Dsv00001102sd0000102C*
+ ID_PRODUCT_FROM_DATABASE=CT6931 RIVA TNT2 Value [Jumper]
+
+pci:v000010DEd0000002Dsv00001462sd00008808*
+ ID_PRODUCT_FROM_DATABASE=MSI-8808
+
+pci:v000010DEd0000002Dsv00001554sd00001041*
+ ID_PRODUCT_FROM_DATABASE=Pixelview RIVA TNT2 M64
+
+pci:v000010DEd0000002Dsv00001569sd0000002D*
+ ID_PRODUCT_FROM_DATABASE=Palit Microsystems Daytona TNT2 M64
+
+pci:v000010DEd0000002E*
+ ID_PRODUCT_FROM_DATABASE=NV6 [Vanta]
+
+pci:v000010DEd0000002F*
+ ID_PRODUCT_FROM_DATABASE=NV6 [Vanta]
+
+pci:v000010DEd00000034*
+ ID_PRODUCT_FROM_DATABASE=MCP04 SMBus
+
+pci:v000010DEd00000035*
+ ID_PRODUCT_FROM_DATABASE=MCP04 IDE
+
+pci:v000010DEd00000036*
+ ID_PRODUCT_FROM_DATABASE=MCP04 Serial ATA Controller
+
+pci:v000010DEd00000037*
+ ID_PRODUCT_FROM_DATABASE=MCP04 Ethernet Controller
+
+pci:v000010DEd00000038*
+ ID_PRODUCT_FROM_DATABASE=MCP04 Ethernet Controller
+
+pci:v000010DEd0000003A*
+ ID_PRODUCT_FROM_DATABASE=MCP04 AC'97 Audio Controller
+
+pci:v000010DEd0000003B*
+ ID_PRODUCT_FROM_DATABASE=MCP04 USB Controller
+
+pci:v000010DEd0000003C*
+ ID_PRODUCT_FROM_DATABASE=MCP04 USB Controller
+
+pci:v000010DEd0000003D*
+ ID_PRODUCT_FROM_DATABASE=MCP04 PCI Bridge
+
+pci:v000010DEd0000003E*
+ ID_PRODUCT_FROM_DATABASE=MCP04 Serial ATA Controller
+
+pci:v000010DEd00000040*
+ ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 Ultra]
+
+pci:v000010DEd00000041*
+ ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800]
+
+pci:v000010DEd00000041sv00001043sd0000817B*
+ ID_PRODUCT_FROM_DATABASE=V9999 Gamer Edition
+
+pci:v000010DEd00000042*
+ ID_PRODUCT_FROM_DATABASE=NV40.2 [GeForce 6800 LE]
+
+pci:v000010DEd00000043*
+ ID_PRODUCT_FROM_DATABASE=NV40.3 [GeForce 6800 XE]
+
+pci:v000010DEd00000044*
+ ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 XT]
+
+pci:v000010DEd00000045*
+ ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 GT]
+
+pci:v000010DEd00000046*
+ ID_PRODUCT_FROM_DATABASE=NV45 [GeForce 6800 GT]
+
+pci:v000010DEd00000047*
+ ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 GS]
+
+pci:v000010DEd00000047sv00001682sd00002109*
+ ID_PRODUCT_FROM_DATABASE=GeForce 6800 GS
+
+pci:v000010DEd00000048*
+ ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 XT]
+
+pci:v000010DEd00000049*
+ ID_PRODUCT_FROM_DATABASE=NV40GL
+
+pci:v000010DEd0000004D*
+ ID_PRODUCT_FROM_DATABASE=NV40GL [Quadro FX 4000]
+
+pci:v000010DEd0000004E*
+ ID_PRODUCT_FROM_DATABASE=NV40GL [Quadro FX 4000]
+
+pci:v000010DEd00000050*
+ ID_PRODUCT_FROM_DATABASE=CK804 ISA Bridge
+
+pci:v000010DEd00000050sv00001043sd0000815A*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard
+
+pci:v000010DEd00000050sv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd00000050sv00001458sd00000C11*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd00000050sv00001462sd00007100*
+ ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond
+
+pci:v000010DEd00000050sv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd00000050sv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd00000050sv00001565sd00003402*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd00000051*
+ ID_PRODUCT_FROM_DATABASE=CK804 ISA Bridge
+
+pci:v000010DEd00000051sv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 ISA Bridge
+
+pci:v000010DEd00000052*
+ ID_PRODUCT_FROM_DATABASE=CK804 SMBus
+
+pci:v000010DEd00000052sv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 SMBus
+
+pci:v000010DEd00000052sv00001043sd0000815A*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard
+
+pci:v000010DEd00000052sv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd00000052sv00001458sd00000C11*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd00000052sv00001462sd00007100*
+ ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond
+
+pci:v000010DEd00000052sv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd00000052sv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd00000052sv00001565sd00003402*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd00000053*
+ ID_PRODUCT_FROM_DATABASE=CK804 IDE
+
+pci:v000010DEd00000053sv00001043sd0000815A*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard
+
+pci:v000010DEd00000053sv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd00000053sv00001458sd00005002*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd00000053sv00001462sd00007100*
+ ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond
+
+pci:v000010DEd00000053sv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd00000053sv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd00000053sv00001565sd00003402*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd00000054*
+ ID_PRODUCT_FROM_DATABASE=CK804 Serial ATA Controller
+
+pci:v000010DEd00000054sv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Serial ATA
+
+pci:v000010DEd00000054sv00001043sd0000815A*
+ ID_PRODUCT_FROM_DATABASE=A8N-E Mainboard
+
+pci:v000010DEd00000054sv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd00000054sv00001458sd0000B003*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd00000054sv00001462sd00007100*
+ ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond
+
+pci:v000010DEd00000054sv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd00000054sv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd00000054sv00001565sd00005401*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd00000055*
+ ID_PRODUCT_FROM_DATABASE=CK804 Serial ATA Controller
+
+pci:v000010DEd00000055sv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Serial ATA
+
+pci:v000010DEd00000055sv00001043sd0000815A*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard
+
+pci:v000010DEd00000055sv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd00000055sv00001458sd0000B003*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd00000055sv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd00000055sv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd00000055sv00001565sd00005401*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd00000056*
+ ID_PRODUCT_FROM_DATABASE=CK804 Ethernet Controller
+
+pci:v000010DEd00000057*
+ ID_PRODUCT_FROM_DATABASE=CK804 Ethernet Controller
+
+pci:v000010DEd00000057sv00001043sd00008141*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard
+
+pci:v000010DEd00000057sv000010DEsd0000CB84*
+ ID_PRODUCT_FROM_DATABASE=NF4 Lanparty
+
+pci:v000010DEd00000057sv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd00000057sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd00000057sv00001462sd00007100*
+ ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond
+
+pci:v000010DEd00000057sv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd00000057sv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd00000057sv00001565sd00002501*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd00000058*
+ ID_PRODUCT_FROM_DATABASE=CK804 AC'97 Modem
+
+pci:v000010DEd00000059*
+ ID_PRODUCT_FROM_DATABASE=CK804 AC'97 Audio Controller
+
+pci:v000010DEd00000059sv00001043sd0000812A*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard
+
+pci:v000010DEd00000059sv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd00000059sv00001462sd00007585*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd00000059sv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd00000059sv00001565sd00008211*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd0000005A*
+ ID_PRODUCT_FROM_DATABASE=CK804 USB Controller
+
+pci:v000010DEd0000005Asv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 onboard USB
+
+pci:v000010DEd0000005Asv00001043sd0000815A*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard
+
+pci:v000010DEd0000005Asv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd0000005Asv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd0000005Asv00001462sd00007100*
+ ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond
+
+pci:v000010DEd0000005Asv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd0000005Asv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd0000005Asv00001565sd00003402*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd0000005B*
+ ID_PRODUCT_FROM_DATABASE=CK804 USB Controller
+
+pci:v000010DEd0000005Bsv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 onboard USB
+
+pci:v000010DEd0000005Bsv00001043sd0000815A*
+ ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard
+
+pci:v000010DEd0000005Bsv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd0000005Bsv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd0000005Bsv00001462sd00007100*
+ ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond
+
+pci:v000010DEd0000005Bsv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard
+
+pci:v000010DEd0000005Bsv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd0000005Bsv00001565sd00003402*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd0000005C*
+ ID_PRODUCT_FROM_DATABASE=CK804 PCI Bridge
+
+pci:v000010DEd0000005D*
+ ID_PRODUCT_FROM_DATABASE=CK804 PCIE Bridge
+
+pci:v000010DEd0000005E*
+ ID_PRODUCT_FROM_DATABASE=CK804 Memory Controller
+
+pci:v000010DEd0000005Esv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Memory Controller
+
+pci:v000010DEd0000005Esv00001043sd0000815A*
+ ID_PRODUCT_FROM_DATABASE=A8N-E Mainboard
+
+pci:v000010DEd0000005Esv000010DEsd0000005E*
+ ID_PRODUCT_FROM_DATABASE=ECS Elitegroup NFORCE3-A939 motherboard.
+
+pci:v000010DEd0000005Esv000010F1sd00002865*
+ ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865)
+
+pci:v000010DEd0000005Esv000010F1sd00002891*
+ ID_PRODUCT_FROM_DATABASE=Thunder K8SRE Mainboard
+
+pci:v000010DEd0000005Esv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+
+pci:v000010DEd0000005Esv00001462sd00007100*
+ ID_PRODUCT_FROM_DATABASE=K8N Diamond Mainboard
+
+pci:v000010DEd0000005Esv00001462sd00007125*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo4-F Mainboard
+
+pci:v000010DEd0000005Esv0000147Bsd00001C1A*
+ ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard
+
+pci:v000010DEd0000005Esv00001565sd00003402*
+ ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard
+
+pci:v000010DEd0000005F*
+ ID_PRODUCT_FROM_DATABASE=CK804 Memory Controller
+
+pci:v000010DEd00000060*
+ ID_PRODUCT_FROM_DATABASE=nForce2 ISA Bridge
+
+pci:v000010DEd00000060sv00001043sd000080AD*
+ ID_PRODUCT_FROM_DATABASE=A7N8X Mainboard
+
+pci:v000010DEd00000060sv0000147Bsd00001C02*
+ ID_PRODUCT_FROM_DATABASE=NF7-S/NF7 (nVidia-nForce2) 2.X
+
+pci:v000010DEd00000060sv0000A0A0sd000003BA*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd00000064*
+ ID_PRODUCT_FROM_DATABASE=nForce2 SMBus (MCP)
+
+pci:v000010DEd00000064sv0000147Bsd00001C02*
+ ID_PRODUCT_FROM_DATABASE=NF7-S/NF7 (nVidia-nForce2) 2.X
+
+pci:v000010DEd00000064sv0000A0A0sd000003BB*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd00000065*
+ ID_PRODUCT_FROM_DATABASE=nForce2 IDE
+
+pci:v000010DEd00000065sv000010DEsd00000C11*
+ ID_PRODUCT_FROM_DATABASE=nForce 2 EIDE Controller
+
+pci:v000010DEd00000065sv0000A0A0sd000003B2*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd00000066*
+ ID_PRODUCT_FROM_DATABASE=nForce2 Ethernet Controller
+
+pci:v000010DEd00000066sv00001043sd000080A7*
+ ID_PRODUCT_FROM_DATABASE=A7N8X Mainboard onboard nForce2 Ethernet
+
+pci:v000010DEd00000066sv000010DEsd00000C11*
+ ID_PRODUCT_FROM_DATABASE=nForce MCP-T Networking Adapter
+
+pci:v000010DEd00000066sv0000A0A0sd000003B3*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd00000067*
+ ID_PRODUCT_FROM_DATABASE=nForce2 USB Controller
+
+pci:v000010DEd00000067sv00001043sd00000C11*
+ ID_PRODUCT_FROM_DATABASE=A7N8X Mainboard
+
+pci:v000010DEd00000067sv0000A0A0sd000003B4*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd00000068*
+ ID_PRODUCT_FROM_DATABASE=nForce2 USB Controller
+
+pci:v000010DEd00000068sv00001043sd00000C11*
+ ID_PRODUCT_FROM_DATABASE=A7N8X Mainboard
+
+pci:v000010DEd00000068sv0000A0A0sd000003B4*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd0000006A*
+ ID_PRODUCT_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP)
+
+pci:v000010DEd0000006Asv00001043sd00008095*
+ ID_PRODUCT_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP)
+
+pci:v000010DEd0000006Asv0000A0A0sd00000304*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd0000006B*
+ ID_PRODUCT_FROM_DATABASE=nForce Audio Processing Unit
+
+pci:v000010DEd0000006Bsv000010DEsd0000006B*
+ ID_PRODUCT_FROM_DATABASE=nForce2 MCP Audio Processing Unit
+
+pci:v000010DEd0000006Bsv0000A0A0sd00000304*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd0000006C*
+ ID_PRODUCT_FROM_DATABASE=nForce2 External PCI Bridge
+
+pci:v000010DEd0000006D*
+ ID_PRODUCT_FROM_DATABASE=nForce2 PCI Bridge
+
+pci:v000010DEd0000006E*
+ ID_PRODUCT_FROM_DATABASE=nForce2 FireWire (IEEE 1394) Controller
+
+pci:v000010DEd0000006Esv0000A0A0sd00000306*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd00000080*
+ ID_PRODUCT_FROM_DATABASE=MCP2A ISA bridge
+
+pci:v000010DEd00000080sv0000147Bsd00001C09*
+ ID_PRODUCT_FROM_DATABASE=NV7 Motherboard
+
+pci:v000010DEd00000084*
+ ID_PRODUCT_FROM_DATABASE=MCP2A SMBus
+
+pci:v000010DEd00000084sv0000147Bsd00001C09*
+ ID_PRODUCT_FROM_DATABASE=NV7 Motherboard
+
+pci:v000010DEd00000085*
+ ID_PRODUCT_FROM_DATABASE=MCP2A IDE
+
+pci:v000010DEd00000085sv0000147Bsd00001C09*
+ ID_PRODUCT_FROM_DATABASE=NV7 Motherboard
+
+pci:v000010DEd00000086*
+ ID_PRODUCT_FROM_DATABASE=MCP2A Ethernet Controller
+
+pci:v000010DEd00000087*
+ ID_PRODUCT_FROM_DATABASE=MCP2A USB Controller
+
+pci:v000010DEd00000087sv0000147Bsd00001C09*
+ ID_PRODUCT_FROM_DATABASE=NV7 Motherboard
+
+pci:v000010DEd00000088*
+ ID_PRODUCT_FROM_DATABASE=MCP2A USB Controller
+
+pci:v000010DEd00000088sv0000147Bsd00001C09*
+ ID_PRODUCT_FROM_DATABASE=NV7 Motherboard
+
+pci:v000010DEd0000008A*
+ ID_PRODUCT_FROM_DATABASE=MCP2S AC'97 Audio Controller
+
+pci:v000010DEd0000008Asv0000147Bsd00001C09*
+ ID_PRODUCT_FROM_DATABASE=NV7 Motherboard
+
+pci:v000010DEd0000008B*
+ ID_PRODUCT_FROM_DATABASE=MCP2A PCI Bridge
+
+pci:v000010DEd0000008C*
+ ID_PRODUCT_FROM_DATABASE=MCP2A Ethernet Controller
+
+pci:v000010DEd0000008E*
+ ID_PRODUCT_FROM_DATABASE=nForce2 Serial ATA Controller
+
+pci:v000010DEd00000090*
+ ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GTX]
+
+pci:v000010DEd00000091*
+ ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GTX]
+
+pci:v000010DEd00000092*
+ ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GT]
+
+pci:v000010DEd00000093*
+ ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GS]
+
+pci:v000010DEd00000095*
+ ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 SLI]
+
+pci:v000010DEd00000098*
+ ID_PRODUCT_FROM_DATABASE=G70 [GeForce Go 7800]
+
+pci:v000010DEd00000099*
+ ID_PRODUCT_FROM_DATABASE=G70 [GeForce Go 7800 GTX]
+
+pci:v000010DEd0000009D*
+ ID_PRODUCT_FROM_DATABASE=G70GL [Quadro FX 4500]
+
+pci:v000010DEd000000A0*
+ ID_PRODUCT_FROM_DATABASE=NV5 [Aladdin TNT2]
+
+pci:v000010DEd000000A0sv000014AFsd00005810*
+ ID_PRODUCT_FROM_DATABASE=Maxi Gamer Xentor
+
+pci:v000010DEd000000C0*
+ ID_PRODUCT_FROM_DATABASE=NV41 [GeForce 6800 GS]
+
+pci:v000010DEd000000C1*
+ ID_PRODUCT_FROM_DATABASE=NV41.1 [GeForce 6800]
+
+pci:v000010DEd000000C2*
+ ID_PRODUCT_FROM_DATABASE=NV41.2 [GeForce 6800 LE]
+
+pci:v000010DEd000000C3*
+ ID_PRODUCT_FROM_DATABASE=NV42 [GeForce 6800 XT]
+
+pci:v000010DEd000000C8*
+ ID_PRODUCT_FROM_DATABASE=NV41.8 [GeForce Go 6800]
+
+pci:v000010DEd000000C9*
+ ID_PRODUCT_FROM_DATABASE=NV41.9 [GeForce Go 6800 Ultra]
+
+pci:v000010DEd000000CC*
+ ID_PRODUCT_FROM_DATABASE=NV41 [Quadro FX Go1400]
+
+pci:v000010DEd000000CD*
+ ID_PRODUCT_FROM_DATABASE=NV41 [Quadro FX 3450/4000 SDI]
+
+pci:v000010DEd000000CDsv000010DEsd0000029B*
+ ID_PRODUCT_FROM_DATABASE=wx4300 Workstation
+
+pci:v000010DEd000000CE*
+ ID_PRODUCT_FROM_DATABASE=NV41GL [Quadro FX 1400]
+
+pci:v000010DEd000000D0*
+ ID_PRODUCT_FROM_DATABASE=nForce3 LPC Bridge
+
+pci:v000010DEd000000D1*
+ ID_PRODUCT_FROM_DATABASE=nForce3 Host Bridge
+
+pci:v000010DEd000000D2*
+ ID_PRODUCT_FROM_DATABASE=nForce3 AGP Bridge
+
+pci:v000010DEd000000D3*
+ ID_PRODUCT_FROM_DATABASE=CK804 Memory Controller
+
+pci:v000010DEd000000D4*
+ ID_PRODUCT_FROM_DATABASE=nForce3 SMBus
+
+pci:v000010DEd000000D5*
+ ID_PRODUCT_FROM_DATABASE=nForce3 IDE
+
+pci:v000010DEd000000D6*
+ ID_PRODUCT_FROM_DATABASE=nForce3 Ethernet
+
+pci:v000010DEd000000D7*
+ ID_PRODUCT_FROM_DATABASE=nForce3 USB 1.1
+
+pci:v000010DEd000000D8*
+ ID_PRODUCT_FROM_DATABASE=nForce3 USB 2.0
+
+pci:v000010DEd000000D9*
+ ID_PRODUCT_FROM_DATABASE=nForce3 Audio
+
+pci:v000010DEd000000DA*
+ ID_PRODUCT_FROM_DATABASE=nForce3 Audio
+
+pci:v000010DEd000000DD*
+ ID_PRODUCT_FROM_DATABASE=nForce3 PCI Bridge
+
+pci:v000010DEd000000DF*
+ ID_PRODUCT_FROM_DATABASE=CK8S Ethernet Controller
+
+pci:v000010DEd000000DFsv00001043sd000080A7*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000DFsv0000105Bsd00000C43*
+ ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA
+
+pci:v000010DEd000000DFsv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000E0*
+ ID_PRODUCT_FROM_DATABASE=nForce3 250Gb LPC Bridge
+
+pci:v000010DEd000000E0sv00001043sd0000813F*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000E0sv000010DEsd00000C11*
+ ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA
+
+pci:v000010DEd000000E0sv00001462sd00007030*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0
+
+pci:v000010DEd000000E0sv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000E0sv00001849sd000000E0*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010DEd000000E1*
+ ID_PRODUCT_FROM_DATABASE=nForce3 250Gb Host Bridge
+
+pci:v000010DEd000000E1sv00001043sd0000813F*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000E1sv00001462sd00007030*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0
+
+pci:v000010DEd000000E1sv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000E1sv00001849sd000000E1*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010DEd000000E2*
+ ID_PRODUCT_FROM_DATABASE=nForce3 250Gb AGP Host to PCI Bridge
+
+pci:v000010DEd000000E3*
+ ID_PRODUCT_FROM_DATABASE=nForce3 Serial ATA Controller
+
+pci:v000010DEd000000E3sv00001043sd0000813F*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000E3sv0000105Bsd00000C43*
+ ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA
+
+pci:v000010DEd000000E3sv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000E3sv00001849sd000000E3*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010DEd000000E4*
+ ID_PRODUCT_FROM_DATABASE=nForce 250Gb PCI System Management
+
+pci:v000010DEd000000E4sv00001043sd0000813F*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000E4sv0000105Bsd00000C43*
+ ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA
+
+pci:v000010DEd000000E4sv00001462sd00007030*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0
+
+pci:v000010DEd000000E4sv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000E4sv00001849sd000000E4*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010DEd000000E5*
+ ID_PRODUCT_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5)
+
+pci:v000010DEd000000E5sv00001043sd0000813F*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000E5sv0000105Bsd00000C43*
+ ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA
+
+pci:v000010DEd000000E5sv00001462sd00007030*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0
+
+pci:v000010DEd000000E5sv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000E5sv00001849sd000000E5*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010DEd000000E5sv0000F849sd000000E5*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010DEd000000E6*
+ ID_PRODUCT_FROM_DATABASE=CK8S Ethernet Controller
+
+pci:v000010DEd000000E7*
+ ID_PRODUCT_FROM_DATABASE=CK8S USB Controller
+
+pci:v000010DEd000000E7sv00001043sd0000813F*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000E7sv0000105Bsd00000C43*
+ ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA
+
+pci:v000010DEd000000E7sv00001462sd00007030*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0
+
+pci:v000010DEd000000E7sv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000E7sv00001849sd000000E7*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010DEd000000E8*
+ ID_PRODUCT_FROM_DATABASE=nForce3 EHCI USB 2.0 Controller
+
+pci:v000010DEd000000E8sv00001043sd0000813F*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000E8sv0000105Bsd00000C43*
+ ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA
+
+pci:v000010DEd000000E8sv00001462sd00007030*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0
+
+pci:v000010DEd000000E8sv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000E8sv00001849sd000000E8*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010DEd000000EA*
+ ID_PRODUCT_FROM_DATABASE=nForce3 250Gb AC'97 Audio Controller
+
+pci:v000010DEd000000EAsv00001043sd0000819D*
+ ID_PRODUCT_FROM_DATABASE=K8N-E
+
+pci:v000010DEd000000EAsv0000105Bsd00000C43*
+ ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA
+
+pci:v000010DEd000000EAsv00001462sd0000B010*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0
+
+pci:v000010DEd000000EAsv0000147Bsd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=NF8 Mainboard
+
+pci:v000010DEd000000ED*
+ ID_PRODUCT_FROM_DATABASE=nForce3 250Gb PCI-to-PCI Bridge
+
+pci:v000010DEd000000EE*
+ ID_PRODUCT_FROM_DATABASE=nForce3 Serial ATA Controller 2
+
+pci:v000010DEd000000F0*
+ ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 Ultra]
+
+pci:v000010DEd000000F1*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 GT]
+
+pci:v000010DEd000000F1sv00001043sd000081A6*
+ ID_PRODUCT_FROM_DATABASE=N6600GT TD 128M AGP
+
+pci:v000010DEd000000F1sv00001043sd000081C6*
+ ID_PRODUCT_FROM_DATABASE=N6600GT TD 128M AGP
+
+pci:v000010DEd000000F1sv00001458sd00003150*
+ ID_PRODUCT_FROM_DATABASE=GV-N66T128VP
+
+pci:v000010DEd000000F1sv00001554sd00001191*
+ ID_PRODUCT_FROM_DATABASE=PixelView PV-N43UA (128KD)
+
+pci:v000010DEd000000F1sv00001682sd00002119*
+ ID_PRODUCT_FROM_DATABASE=GeForce 6600 GT AGP
+
+pci:v000010DEd000000F2*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600]
+
+pci:v000010DEd000000F2sv00001554sd00001194*
+ ID_PRODUCT_FROM_DATABASE=PixelView PV-N43AT (256KD)
+
+pci:v000010DEd000000F2sv00001682sd0000211C*
+ ID_PRODUCT_FROM_DATABASE=GeForce 6600 256MB DDR DUAL DVI TV
+
+pci:v000010DEd000000F3*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6200]
+
+pci:v000010DEd000000F4*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 LE]
+
+pci:v000010DEd000000F5*
+ ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GS]
+
+pci:v000010DEd000000F6*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6800 GS]
+
+pci:v000010DEd000000F6sv00001682sd0000217E*
+ ID_PRODUCT_FROM_DATABASE=XFX GeForce 6800 XTreme 256MB DDR3 AGP
+
+pci:v000010DEd000000F8*
+ ID_PRODUCT_FROM_DATABASE=NV45GL [Quadro FX 3400/4400]
+
+pci:v000010DEd000000F9*
+ ID_PRODUCT_FROM_DATABASE=NV45 [GeForce 6800 GTO]
+
+pci:v000010DEd000000F9sv000010DEsd000000F9*
+ ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 GT]
+
+pci:v000010DEd000000F9sv00001682sd00002120*
+ ID_PRODUCT_FROM_DATABASE=GEFORCE 6800 GT PCI-E
+
+pci:v000010DEd000000FA*
+ ID_PRODUCT_FROM_DATABASE=NV36 [GeForce PCX 5750]
+
+pci:v000010DEd000000FB*
+ ID_PRODUCT_FROM_DATABASE=NV35 [GeForce PCX 5900]
+
+pci:v000010DEd000000FC*
+ ID_PRODUCT_FROM_DATABASE=NV37GL [Quadro FX 330/GeForce PCX 5300]
+
+pci:v000010DEd000000FD*
+ ID_PRODUCT_FROM_DATABASE=NV37GL [Quadro PCI-E Series]
+
+pci:v000010DEd000000FE*
+ ID_PRODUCT_FROM_DATABASE=NV38GL [Quadro FX 1300]
+
+pci:v000010DEd000000FF*
+ ID_PRODUCT_FROM_DATABASE=NV18 [GeForce PCX 4300]
+
+pci:v000010DEd00000100*
+ ID_PRODUCT_FROM_DATABASE=NV10 [GeForce 256 SDR]
+
+pci:v000010DEd00000100sv00001043sd00000200*
+ ID_PRODUCT_FROM_DATABASE=AGP-V6600 SGRAM
+
+pci:v000010DEd00000100sv00001043sd00000201*
+ ID_PRODUCT_FROM_DATABASE=AGP-V6600 SDRAM
+
+pci:v000010DEd00000100sv00001043sd00004008*
+ ID_PRODUCT_FROM_DATABASE=AGP-V6600 SGRAM
+
+pci:v000010DEd00000100sv00001043sd00004009*
+ ID_PRODUCT_FROM_DATABASE=AGP-V6600 SDRAM
+
+pci:v000010DEd00000100sv00001048sd00000C41*
+ ID_PRODUCT_FROM_DATABASE=Erazor X
+
+pci:v000010DEd00000100sv00001048sd00000C43*
+ ID_PRODUCT_FROM_DATABASE=ERAZOR X PCI
+
+pci:v000010DEd00000100sv00001048sd00000C48*
+ ID_PRODUCT_FROM_DATABASE=Synergy Force
+
+pci:v000010DEd00000100sv00001102sd0000102D*
+ ID_PRODUCT_FROM_DATABASE=CT6941 GeForce 256
+
+pci:v000010DEd00000100sv000014AFsd00005022*
+ ID_PRODUCT_FROM_DATABASE=3D Prophet SE
+
+pci:v000010DEd00000101*
+ ID_PRODUCT_FROM_DATABASE=NV10DDR [GeForce 256 DDR]
+
+pci:v000010DEd00000101sv00001043sd00000202*
+ ID_PRODUCT_FROM_DATABASE=AGP-V6800 DDR
+
+pci:v000010DEd00000101sv00001043sd0000400A*
+ ID_PRODUCT_FROM_DATABASE=AGP-V6800 DDR SGRAM
+
+pci:v000010DEd00000101sv00001043sd0000400B*
+ ID_PRODUCT_FROM_DATABASE=AGP-V6800 DDR SDRAM
+
+pci:v000010DEd00000101sv00001048sd00000C42*
+ ID_PRODUCT_FROM_DATABASE=Erazor X
+
+pci:v000010DEd00000101sv0000107Dsd00002822*
+ ID_PRODUCT_FROM_DATABASE=WinFast GeForce 256
+
+pci:v000010DEd00000101sv00001102sd0000102E*
+ ID_PRODUCT_FROM_DATABASE=CT6971 GeForce 256 DDR
+
+pci:v000010DEd00000101sv000014AFsd00005021*
+ ID_PRODUCT_FROM_DATABASE=3D Prophet DDR-DVI
+
+pci:v000010DEd00000103*
+ ID_PRODUCT_FROM_DATABASE=NV10GL [Quadro]
+
+pci:v000010DEd00000103sv00001048sd00000C40*
+ ID_PRODUCT_FROM_DATABASE=GLoria II-64
+
+pci:v000010DEd00000103sv00001048sd00000C44*
+ ID_PRODUCT_FROM_DATABASE=GLoria II
+
+pci:v000010DEd00000103sv00001048sd00000C45*
+ ID_PRODUCT_FROM_DATABASE=GLoria II
+
+pci:v000010DEd00000103sv00001048sd00000C4A*
+ ID_PRODUCT_FROM_DATABASE=GLoria II-64 Pro
+
+pci:v000010DEd00000103sv00001048sd00000C4B*
+ ID_PRODUCT_FROM_DATABASE=GLoria II-64 Pro DVII
+
+pci:v000010DEd00000110*
+ ID_PRODUCT_FROM_DATABASE=NV11 [GeForce2 MX/MX 400]
+
+pci:v000010DEd00000110sv00001043sd00004015*
+ ID_PRODUCT_FROM_DATABASE=AGP-V7100 Pro
+
+pci:v000010DEd00000110sv00001043sd00004021*
+ ID_PRODUCT_FROM_DATABASE=V7100 Deluxe Combo
+
+pci:v000010DEd00000110sv00001043sd00004031*
+ ID_PRODUCT_FROM_DATABASE=V7100 Pro with TV output
+
+pci:v000010DEd00000110sv00001048sd00000C60*
+ ID_PRODUCT_FROM_DATABASE=Gladiac MX
+
+pci:v000010DEd00000110sv00001048sd00000C61*
+ ID_PRODUCT_FROM_DATABASE=Gladiac 511PCI
+
+pci:v000010DEd00000110sv00001048sd00000C63*
+ ID_PRODUCT_FROM_DATABASE=Gladiac 511TV-OUT 32MB
+
+pci:v000010DEd00000110sv00001048sd00000C64*
+ ID_PRODUCT_FROM_DATABASE=Gladiac 511TV-OUT 64MB
+
+pci:v000010DEd00000110sv00001048sd00000C65*
+ ID_PRODUCT_FROM_DATABASE=Gladiac 511TWIN
+
+pci:v000010DEd00000110sv00001048sd00000C66*
+ ID_PRODUCT_FROM_DATABASE=Gladiac 311
+
+pci:v000010DEd00000110sv000010DEsd00000091*
+ ID_PRODUCT_FROM_DATABASE=Dell OEM GeForce 2 MX 400
+
+pci:v000010DEd00000110sv000010DEsd000000A1*
+ ID_PRODUCT_FROM_DATABASE=Apple OEM GeForce2 MX
+
+pci:v000010DEd00000110sv00001462sd00008817*
+ ID_PRODUCT_FROM_DATABASE=MSI GeForce2 MX400 Pro32S [MS-8817]
+
+pci:v000010DEd00000110sv000014AFsd00007102*
+ ID_PRODUCT_FROM_DATABASE=3D Prophet II MX
+
+pci:v000010DEd00000110sv000014AFsd00007103*
+ ID_PRODUCT_FROM_DATABASE=3D Prophet II MX Dual-Display
+
+pci:v000010DEd00000110sv00001545sd00000023*
+ ID_PRODUCT_FROM_DATABASE=Xtasy Rev. B2
+
+pci:v000010DEd00000111*
+ ID_PRODUCT_FROM_DATABASE=NV11DDR [GeForce2 MX200]
+
+pci:v000010DEd00000112*
+ ID_PRODUCT_FROM_DATABASE=NV11 [GeForce2 Go]
+
+pci:v000010DEd00000113*
+ ID_PRODUCT_FROM_DATABASE=NV11GL [Quadro2 MXR/EX/Go]
+
+pci:v000010DEd00000140*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 GT]
+
+pci:v000010DEd00000141*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600]
+
+pci:v000010DEd00000141sv00001043sd000081B0*
+ ID_PRODUCT_FROM_DATABASE=EN6600 Silencer
+
+pci:v000010DEd00000141sv00001458sd00003124*
+ ID_PRODUCT_FROM_DATABASE=GV-NX66128DP Turbo Force Edition
+
+pci:v000010DEd00000142*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 LE]
+
+pci:v000010DEd00000143*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 VE]
+
+pci:v000010DEd00000144*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce Go 6600]
+
+pci:v000010DEd00000145*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6610 XL]
+
+pci:v000010DEd00000146*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce Go 6600TE/6200TE]
+
+pci:v000010DEd00000147*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6700 XL]
+
+pci:v000010DEd00000148*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce Go 6600]
+
+pci:v000010DEd00000149*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce Go 6600 GT]
+
+pci:v000010DEd0000014A*
+ ID_PRODUCT_FROM_DATABASE=NV43 [Quadro NVS 440]
+
+pci:v000010DEd0000014C*
+ ID_PRODUCT_FROM_DATABASE=NV43 [Quadro FX 540 MXM]
+
+pci:v000010DEd0000014D*
+ ID_PRODUCT_FROM_DATABASE=NV43GL [Quadro FX 550]
+
+pci:v000010DEd0000014E*
+ ID_PRODUCT_FROM_DATABASE=NV43GL [Quadro FX 540]
+
+pci:v000010DEd0000014F*
+ ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6200]
+
+pci:v000010DEd00000150*
+ ID_PRODUCT_FROM_DATABASE=NV15 [GeForce2 GTS/Pro]
+
+pci:v000010DEd00000150sv00001043sd00004016*
+ ID_PRODUCT_FROM_DATABASE=V7700 AGP Video Card
+
+pci:v000010DEd00000150sv00001048sd00000C50*
+ ID_PRODUCT_FROM_DATABASE=Gladiac
+
+pci:v000010DEd00000150sv00001048sd00000C52*
+ ID_PRODUCT_FROM_DATABASE=Gladiac-64
+
+pci:v000010DEd00000150sv0000107Dsd00002840*
+ ID_PRODUCT_FROM_DATABASE=WinFast GeForce2 GTS with TV output
+
+pci:v000010DEd00000150sv0000107Dsd00002842*
+ ID_PRODUCT_FROM_DATABASE=WinFast GeForce 2 Pro
+
+pci:v000010DEd00000150sv000010DEsd0000002E*
+ ID_PRODUCT_FROM_DATABASE=GeForce2 GTS
+
+pci:v000010DEd00000150sv00001462sd00008831*
+ ID_PRODUCT_FROM_DATABASE=Creative GeForce2 Pro
+
+pci:v000010DEd00000151*
+ ID_PRODUCT_FROM_DATABASE=NV15DDR [GeForce2 Ti]
+
+pci:v000010DEd00000151sv00001043sd0000405F*
+ ID_PRODUCT_FROM_DATABASE=V7700Ti
+
+pci:v000010DEd00000151sv00001462sd00005506*
+ ID_PRODUCT_FROM_DATABASE=Creative 3D Blaster GeForce2 Titanium
+
+pci:v000010DEd00000152*
+ ID_PRODUCT_FROM_DATABASE=NV15BR [GeForce2 Ultra, Bladerunner]
+
+pci:v000010DEd00000152sv00001048sd00000C56*
+ ID_PRODUCT_FROM_DATABASE=GLADIAC Ultra
+
+pci:v000010DEd00000153*
+ ID_PRODUCT_FROM_DATABASE=NV15GL [Quadro2 Pro]
+
+pci:v000010DEd00000160*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6500]
+
+pci:v000010DEd00000161*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6200 TurboCache(TM)]
+
+pci:v000010DEd00000162*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6200SE TurboCache (TM)]
+
+pci:v000010DEd00000163*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6200 LE]
+
+pci:v000010DEd00000164*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce Go 6200]
+
+pci:v000010DEd00000165*
+ ID_PRODUCT_FROM_DATABASE=NV44 [Quadro NVS 285]
+
+pci:v000010DEd00000166*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce Go 6400]
+
+pci:v000010DEd00000167*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce Go 6200]
+
+pci:v000010DEd00000168*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce Go 6400]
+
+pci:v000010DEd00000169*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6250]
+
+pci:v000010DEd0000016A*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 7100 GS]
+
+pci:v000010DEd00000170*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 MX 460]
+
+pci:v000010DEd00000171*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 MX 440]
+
+pci:v000010DEd00000171sv000010B0sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Gainward Pro/600 TV
+
+pci:v000010DEd00000171sv000010DEsd00000008*
+ ID_PRODUCT_FROM_DATABASE=Apple OEM GeForce4 MX 440
+
+pci:v000010DEd00000171sv00001462sd00008661*
+ ID_PRODUCT_FROM_DATABASE=G4MX440-VTP
+
+pci:v000010DEd00000171sv00001462sd00008730*
+ ID_PRODUCT_FROM_DATABASE=MX440SES-T (MS-8873)
+
+pci:v000010DEd00000171sv00001462sd00008852*
+ ID_PRODUCT_FROM_DATABASE=GeForce4 MX440 PCI
+
+pci:v000010DEd00000171sv0000147Bsd00008F00*
+ ID_PRODUCT_FROM_DATABASE=Abit Siluro GeForce4MX440
+
+pci:v000010DEd00000172*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 MX 420]
+
+pci:v000010DEd00000173*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 MX 440-SE]
+
+pci:v000010DEd00000174*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 440 Go]
+
+pci:v000010DEd00000175*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 420 Go]
+
+pci:v000010DEd00000176*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 420 Go 32M]
+
+pci:v000010DEd00000176sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v000010DEd00000176sv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v000010DEd00000176sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v000010DEd00000177*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 460 Go]
+
+pci:v000010DEd00000178*
+ ID_PRODUCT_FROM_DATABASE=NV17GL [Quadro4 550 XGL]
+
+pci:v000010DEd00000179*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 440 Go 64M]
+
+pci:v000010DEd00000179sv000010DEsd00000179*
+ ID_PRODUCT_FROM_DATABASE=GeForce4 MX (Mac)
+
+pci:v000010DEd0000017A*
+ ID_PRODUCT_FROM_DATABASE=NV17GL [Quadro NVS]
+
+pci:v000010DEd0000017B*
+ ID_PRODUCT_FROM_DATABASE=NV17GL [Quadro4 550 XGL]
+
+pci:v000010DEd0000017C*
+ ID_PRODUCT_FROM_DATABASE=NV17GL [Quadro4 500 GoGL]
+
+pci:v000010DEd0000017D*
+ ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 410 Go 16M]
+
+pci:v000010DEd00000181*
+ ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x]
+
+pci:v000010DEd00000181sv00001043sd00008063*
+ ID_PRODUCT_FROM_DATABASE=GeForce4 MX 440 AGP 8X
+
+pci:v000010DEd00000181sv00001043sd0000806F*
+ ID_PRODUCT_FROM_DATABASE=V9180 Magic
+
+pci:v000010DEd00000181sv00001462sd00008880*
+ ID_PRODUCT_FROM_DATABASE=MS-StarForce GeForce4 MX 440 with AGP8X
+
+pci:v000010DEd00000181sv00001462sd00008900*
+ ID_PRODUCT_FROM_DATABASE=MS-8890 GeForce 4 MX440 AGP8X
+
+pci:v000010DEd00000181sv00001462sd00009350*
+ ID_PRODUCT_FROM_DATABASE=MSI GeForce4 MX T8X with AGP8X
+
+pci:v000010DEd00000181sv0000147Bsd00008F0D*
+ ID_PRODUCT_FROM_DATABASE=Siluro GF4 MX-8X
+
+pci:v000010DEd00000181sv00001554sd00001111*
+ ID_PRODUCT_FROM_DATABASE=PixelView MVGA-NVG18A
+
+pci:v000010DEd00000182*
+ ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX 440SE AGP 8x]
+
+pci:v000010DEd00000183*
+ ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX 420 AGP 8x]
+
+pci:v000010DEd00000184*
+ ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX]
+
+pci:v000010DEd00000185*
+ ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX 4000]
+
+pci:v000010DEd00000186*
+ ID_PRODUCT_FROM_DATABASE=NV18M [GeForce4 448 Go]
+
+pci:v000010DEd00000187*
+ ID_PRODUCT_FROM_DATABASE=NV18M [GeForce4 488 Go]
+
+pci:v000010DEd00000188*
+ ID_PRODUCT_FROM_DATABASE=NV18GL [Quadro4 580 XGL]
+
+pci:v000010DEd00000189*
+ ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX with AGP8X (Mac)]
+
+pci:v000010DEd0000018A*
+ ID_PRODUCT_FROM_DATABASE=NV18GL [Quadro NVS 280 SD]
+
+pci:v000010DEd0000018B*
+ ID_PRODUCT_FROM_DATABASE=NV18GL [Quadro4 380 XGL]
+
+pci:v000010DEd0000018C*
+ ID_PRODUCT_FROM_DATABASE=NV18GL [Quadro NVS 50 PCI]
+
+pci:v000010DEd0000018D*
+ ID_PRODUCT_FROM_DATABASE=NV18M [GeForce4 448 Go]
+
+pci:v000010DEd00000191*
+ ID_PRODUCT_FROM_DATABASE=G80 [GeForce 8800 GTX]
+
+pci:v000010DEd00000193*
+ ID_PRODUCT_FROM_DATABASE=G80 [GeForce 8800 GTS]
+
+pci:v000010DEd00000193sv0000107Dsd000020BD*
+ ID_PRODUCT_FROM_DATABASE=WinFast PX 8800 GTS TDH
+
+pci:v000010DEd00000194*
+ ID_PRODUCT_FROM_DATABASE=G80 [GeForce 8800 Ultra]
+
+pci:v000010DEd00000197*
+ ID_PRODUCT_FROM_DATABASE=G80 [Tesla C870]
+
+pci:v000010DEd0000019D*
+ ID_PRODUCT_FROM_DATABASE=G80 [Quadro FX 5600]
+
+pci:v000010DEd0000019E*
+ ID_PRODUCT_FROM_DATABASE=G80 [Quadro FX 4600]
+
+pci:v000010DEd000001A0*
+ ID_PRODUCT_FROM_DATABASE=nForce 220/420 NV11 [GeForce2 MX]
+
+pci:v000010DEd000001A4*
+ ID_PRODUCT_FROM_DATABASE=nForce CPU bridge
+
+pci:v000010DEd000001AB*
+ ID_PRODUCT_FROM_DATABASE=nForce 420 Memory Controller (DDR)
+
+pci:v000010DEd000001AC*
+ ID_PRODUCT_FROM_DATABASE=nForce 220/420 Memory Controller
+
+pci:v000010DEd000001AD*
+ ID_PRODUCT_FROM_DATABASE=nForce 220/420 Memory Controller
+
+pci:v000010DEd000001B0*
+ ID_PRODUCT_FROM_DATABASE=nForce Audio Processing Unit
+
+pci:v000010DEd000001B1*
+ ID_PRODUCT_FROM_DATABASE=nForce AC'97 Audio Controller
+
+pci:v000010DEd000001B2*
+ ID_PRODUCT_FROM_DATABASE=nForce ISA Bridge
+
+pci:v000010DEd000001B4*
+ ID_PRODUCT_FROM_DATABASE=nForce PCI System Management
+
+pci:v000010DEd000001B7*
+ ID_PRODUCT_FROM_DATABASE=nForce AGP to PCI Bridge
+
+pci:v000010DEd000001B8*
+ ID_PRODUCT_FROM_DATABASE=nForce PCI-to-PCI bridge
+
+pci:v000010DEd000001BC*
+ ID_PRODUCT_FROM_DATABASE=nForce IDE
+
+pci:v000010DEd000001C1*
+ ID_PRODUCT_FROM_DATABASE=nForce AC'97 Modem Controller
+
+pci:v000010DEd000001C2*
+ ID_PRODUCT_FROM_DATABASE=nForce USB Controller
+
+pci:v000010DEd000001C3*
+ ID_PRODUCT_FROM_DATABASE=nForce Ethernet Controller
+
+pci:v000010DEd000001D0*
+ ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7350 LE]
+
+pci:v000010DEd000001D1*
+ ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7300 LE]
+
+pci:v000010DEd000001D1sv00001462sd00000345*
+ ID_PRODUCT_FROM_DATABASE=7300LE PCI Express Graphics Adapter
+
+pci:v000010DEd000001D2*
+ ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7550 LE]
+
+pci:v000010DEd000001D3*
+ ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7300 SE/7200 GS]
+
+pci:v000010DEd000001D6*
+ ID_PRODUCT_FROM_DATABASE=G72M [GeForce Go 7200]
+
+pci:v000010DEd000001D7*
+ ID_PRODUCT_FROM_DATABASE=G72M [Quadro NVS 110M/GeForce Go 7300]
+
+pci:v000010DEd000001D8*
+ ID_PRODUCT_FROM_DATABASE=G72M [GeForce Go 7400]
+
+pci:v000010DEd000001D8sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v000010DEd000001D9*
+ ID_PRODUCT_FROM_DATABASE=G72M [GeForce Go 7450]
+
+pci:v000010DEd000001DA*
+ ID_PRODUCT_FROM_DATABASE=G72M [Quadro NVS 110M]
+
+pci:v000010DEd000001DB*
+ ID_PRODUCT_FROM_DATABASE=G72M [Quadro NVS 120M]
+
+pci:v000010DEd000001DC*
+ ID_PRODUCT_FROM_DATABASE=G72GL [Quadro FX 350M]
+
+pci:v000010DEd000001DD*
+ ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7500 LE]
+
+pci:v000010DEd000001DE*
+ ID_PRODUCT_FROM_DATABASE=G72GL [Quadro FX 350]
+
+pci:v000010DEd000001DEsv000010DEsd000001DC*
+ ID_PRODUCT_FROM_DATABASE=Quadro  FX Go350M
+
+pci:v000010DEd000001DF*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7300 GS]
+
+pci:v000010DEd000001E0*
+ ID_PRODUCT_FROM_DATABASE=nForce2 IGP2
+
+pci:v000010DEd000001E0sv0000147Bsd00001C09*
+ ID_PRODUCT_FROM_DATABASE=NV7 Motherboard
+
+pci:v000010DEd000001E8*
+ ID_PRODUCT_FROM_DATABASE=nForce2 AGP
+
+pci:v000010DEd000001EA*
+ ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 0
+
+pci:v000010DEd000001EAsv0000A0A0sd000003B9*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd000001EB*
+ ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 1
+
+pci:v000010DEd000001EBsv0000A0A0sd000003B9*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd000001EC*
+ ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 2
+
+pci:v000010DEd000001ECsv0000A0A0sd000003B9*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd000001ED*
+ ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 3
+
+pci:v000010DEd000001EDsv0000A0A0sd000003B9*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd000001EE*
+ ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 4
+
+pci:v000010DEd000001EEsv000010DEsd000001EE*
+ ID_PRODUCT_FROM_DATABASE=MSI Delta-L nForce2 memory controller
+
+pci:v000010DEd000001EEsv0000A0A0sd000003B9*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd000001EF*
+ ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 5
+
+pci:v000010DEd000001EFsv0000A0A0sd000003B9*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd000001F0*
+ ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX - nForce GPU]
+
+pci:v000010DEd000001F0sv0000A0A0sd000003B5*
+ ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard
+
+pci:v000010DEd00000200*
+ ID_PRODUCT_FROM_DATABASE=NV20 [GeForce3]
+
+pci:v000010DEd00000200sv00001043sd0000402F*
+ ID_PRODUCT_FROM_DATABASE=AGP-V8200 DDR
+
+pci:v000010DEd00000200sv00001048sd00000C70*
+ ID_PRODUCT_FROM_DATABASE=GLADIAC 920
+
+pci:v000010DEd00000201*
+ ID_PRODUCT_FROM_DATABASE=NV20 [GeForce3 Ti 200]
+
+pci:v000010DEd00000202*
+ ID_PRODUCT_FROM_DATABASE=NV20 [GeForce3 Ti 500]
+
+pci:v000010DEd00000202sv00001043sd0000405B*
+ ID_PRODUCT_FROM_DATABASE=V8200 T5
+
+pci:v000010DEd00000202sv00001545sd0000002F*
+ ID_PRODUCT_FROM_DATABASE=Xtasy 6964
+
+pci:v000010DEd00000203*
+ ID_PRODUCT_FROM_DATABASE=NV20DCC [Quadro DCC]
+
+pci:v000010DEd00000211*
+ ID_PRODUCT_FROM_DATABASE=NV48 [GeForce 6800]
+
+pci:v000010DEd00000212*
+ ID_PRODUCT_FROM_DATABASE=NV48 [GeForce 6800 LE]
+
+pci:v000010DEd00000215*
+ ID_PRODUCT_FROM_DATABASE=NV48 [GeForce 6800 GT]
+
+pci:v000010DEd00000218*
+ ID_PRODUCT_FROM_DATABASE=NV48 [GeForce 6800 XT]
+
+pci:v000010DEd00000221*
+ ID_PRODUCT_FROM_DATABASE=NV44A [GeForce 6200]
+
+pci:v000010DEd00000221sv00001043sd000081E1*
+ ID_PRODUCT_FROM_DATABASE=N6200/TD/256M/A
+
+pci:v000010DEd00000221sv00003842sd0000A341*
+ ID_PRODUCT_FROM_DATABASE=256A8N341DX
+
+pci:v000010DEd00000222*
+ ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6200 A-LE]
+
+pci:v000010DEd00000240*
+ ID_PRODUCT_FROM_DATABASE=C51PV [GeForce 6150]
+
+pci:v000010DEd00000240sv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM
+
+pci:v000010DEd00000240sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000241*
+ ID_PRODUCT_FROM_DATABASE=C51 [GeForce 6150 LE]
+
+pci:v000010DEd00000242*
+ ID_PRODUCT_FROM_DATABASE=C51G [GeForce 6100]
+
+pci:v000010DEd00000242sv0000105Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd00000243*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd00000244*
+ ID_PRODUCT_FROM_DATABASE=C51 [GeForce Go 6150]
+
+pci:v000010DEd00000244sv0000103Csd000030B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v000010DEd00000244sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000244sv000010DEsd00000244*
+ ID_PRODUCT_FROM_DATABASE=GeForce Go 6150
+
+pci:v000010DEd00000245*
+ ID_PRODUCT_FROM_DATABASE=C51 [Quadro NVS 210S/GeForce 6150LE]
+
+pci:v000010DEd00000246*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd00000247*
+ ID_PRODUCT_FROM_DATABASE=C51 [GeForce Go 6100]
+
+pci:v000010DEd00000247sv00001043sd00001382*
+ ID_PRODUCT_FROM_DATABASE=MCP51 PCI-X GeForce Go 6100
+
+pci:v000010DEd00000248*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd00000249*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd0000024A*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd0000024B*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd0000024C*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd0000024D*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd0000024E*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd0000024F*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd00000250*
+ ID_PRODUCT_FROM_DATABASE=NV25 [GeForce4 Ti 4600]
+
+pci:v000010DEd00000251*
+ ID_PRODUCT_FROM_DATABASE=NV25 [GeForce4 Ti 4400]
+
+pci:v000010DEd00000251sv00001043sd00008023*
+ ID_PRODUCT_FROM_DATABASE=v8440 GeForce 4 Ti4400
+
+pci:v000010DEd00000251sv000010DEsd00000251*
+ ID_PRODUCT_FROM_DATABASE=PNY GeForce4 Ti 4400
+
+pci:v000010DEd00000251sv00001462sd00008710*
+ ID_PRODUCT_FROM_DATABASE=PNY GeForce4 Ti 4400
+
+pci:v000010DEd00000252*
+ ID_PRODUCT_FROM_DATABASE=NV25 [GeForce4 Ti]
+
+pci:v000010DEd00000253*
+ ID_PRODUCT_FROM_DATABASE=NV25 [GeForce4 Ti 4200]
+
+pci:v000010DEd00000253sv0000107Dsd00002896*
+ ID_PRODUCT_FROM_DATABASE=WinFast A250 LE TD (Dual VGA/TV-out/DVI)
+
+pci:v000010DEd00000253sv0000147Bsd00008F09*
+ ID_PRODUCT_FROM_DATABASE=Siluro (Dual VGA/TV-out/DVI)
+
+pci:v000010DEd00000258*
+ ID_PRODUCT_FROM_DATABASE=NV25GL [Quadro4 900 XGL]
+
+pci:v000010DEd00000259*
+ ID_PRODUCT_FROM_DATABASE=NV25GL [Quadro4 750 XGL]
+
+pci:v000010DEd0000025B*
+ ID_PRODUCT_FROM_DATABASE=NV25GL [Quadro4 700 XGL]
+
+pci:v000010DEd00000260*
+ ID_PRODUCT_FROM_DATABASE=MCP51 LPC Bridge
+
+pci:v000010DEd00000260sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd00000260sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000260sv00001043sd000081BC*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd00000260sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd00000260sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000261*
+ ID_PRODUCT_FROM_DATABASE=MCP51 LPC Bridge
+
+pci:v000010DEd00000261sv0000105Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd00000262*
+ ID_PRODUCT_FROM_DATABASE=MCP51 LPC Bridge
+
+pci:v000010DEd00000263*
+ ID_PRODUCT_FROM_DATABASE=MCP51 LPC Bridge
+
+pci:v000010DEd00000264*
+ ID_PRODUCT_FROM_DATABASE=MCP51 SMBus
+
+pci:v000010DEd00000264sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd00000264sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000264sv00001043sd000081BC*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd00000264sv0000105Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd00000264sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000265*
+ ID_PRODUCT_FROM_DATABASE=MCP51 IDE
+
+pci:v000010DEd00000265sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd00000265sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000265sv00001043sd000081BC*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd00000265sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000265sv0000F05Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd00000266*
+ ID_PRODUCT_FROM_DATABASE=MCP51 Serial ATA Controller
+
+pci:v000010DEd00000266sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd00000266sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000266sv00001043sd000081BC*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd00000266sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000267*
+ ID_PRODUCT_FROM_DATABASE=MCP51 Serial ATA Controller
+
+pci:v000010DEd00000267sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd00000267sv00001043sd000081BC*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd00000267sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000268*
+ ID_PRODUCT_FROM_DATABASE=MCP51 Ethernet Controller
+
+pci:v000010DEd00000269*
+ ID_PRODUCT_FROM_DATABASE=MCP51 Ethernet Controller
+
+pci:v000010DEd00000269sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd00000269sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000269sv00001043sd00008141*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd00000269sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd0000026A*
+ ID_PRODUCT_FROM_DATABASE=MCP51 MCI
+
+pci:v000010DEd0000026B*
+ ID_PRODUCT_FROM_DATABASE=MCP51 AC97 Audio Controller
+
+pci:v000010DEd0000026Bsv0000105Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd0000026C*
+ ID_PRODUCT_FROM_DATABASE=MCP51 High Definition Audio
+
+pci:v000010DEd0000026Csv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd0000026Csv0000103Csd000030B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v000010DEd0000026Csv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd0000026Csv000010DEsd0000CB84*
+ ID_PRODUCT_FROM_DATABASE=ASUSTeK Computer Inc. A8N-VM CSM Mainboard
+
+pci:v000010DEd0000026Csv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd0000026D*
+ ID_PRODUCT_FROM_DATABASE=MCP51 USB Controller
+
+pci:v000010DEd0000026Dsv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd0000026Dsv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd0000026Dsv00001043sd000081BC*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd0000026Dsv0000105Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd0000026Dsv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd0000026E*
+ ID_PRODUCT_FROM_DATABASE=MCP51 USB Controller
+
+pci:v000010DEd0000026Esv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd0000026Esv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd0000026Esv00001043sd000081BC*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd0000026Esv0000105Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd0000026Esv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd0000026F*
+ ID_PRODUCT_FROM_DATABASE=MCP51 PCI Bridge
+
+pci:v000010DEd0000026Fsv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000270*
+ ID_PRODUCT_FROM_DATABASE=MCP51 Host Bridge
+
+pci:v000010DEd00000270sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd00000270sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000270sv00001043sd000081BC*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd00000270sv0000105Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd00000270sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd00000270sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000271*
+ ID_PRODUCT_FROM_DATABASE=MCP51 PMU
+
+pci:v000010DEd00000271sv0000103Csd000030B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v000010DEd00000271sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd00000272*
+ ID_PRODUCT_FROM_DATABASE=MCP51 Memory Controller 0
+
+pci:v000010DEd00000272sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd00000272sv0000105Bsd00000CAD*
+ ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB
+
+pci:v000010DEd0000027E*
+ ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 2
+
+pci:v000010DEd0000027Esv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd0000027Esv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd0000027Esv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd0000027Esv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd0000027Esv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd0000027F*
+ ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 3
+
+pci:v000010DEd0000027Fsv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd0000027Fsv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd0000027Fsv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd0000027Fsv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd0000027Fsv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000280*
+ ID_PRODUCT_FROM_DATABASE=NV28 [GeForce4 Ti 4800]
+
+pci:v000010DEd00000281*
+ ID_PRODUCT_FROM_DATABASE=NV28 [GeForce4 Ti 4200 AGP 8x]
+
+pci:v000010DEd00000282*
+ ID_PRODUCT_FROM_DATABASE=NV28 [GeForce4 Ti 4800 SE]
+
+pci:v000010DEd00000286*
+ ID_PRODUCT_FROM_DATABASE=NV28 [GeForce4 Ti 4200 Go AGP 8x]
+
+pci:v000010DEd00000288*
+ ID_PRODUCT_FROM_DATABASE=NV28GL [Quadro4 980 XGL]
+
+pci:v000010DEd00000289*
+ ID_PRODUCT_FROM_DATABASE=NV28GL [Quadro4 780 XGL]
+
+pci:v000010DEd0000028C*
+ ID_PRODUCT_FROM_DATABASE=NV28GLM [Quadro4 Go700]
+
+pci:v000010DEd00000290*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GTX]
+
+pci:v000010DEd00000291*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GT/GTO]
+
+pci:v000010DEd00000291sv000010DEsd0000042B*
+ ID_PRODUCT_FROM_DATABASE=NX7900GTO-T2D512E [7900 GTO]
+
+pci:v000010DEd00000292*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GS]
+
+pci:v000010DEd00000293*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GX2]
+
+pci:v000010DEd00000294*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7950 GX2]
+
+pci:v000010DEd00000295*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7950 GT]
+
+pci:v000010DEd00000295sv00001043sd00008225*
+ ID_PRODUCT_FROM_DATABASE=GeForce 7950 GT
+
+pci:v000010DEd00000295sv0000107Dsd00002A68*
+ ID_PRODUCT_FROM_DATABASE=WinFast PX7950GT TDH
+
+pci:v000010DEd00000295sv00001462sd00000663*
+ ID_PRODUCT_FROM_DATABASE=NX7950GT-VT2D512EZ-HD
+
+pci:v000010DEd00000297*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce Go 7950 GTX]
+
+pci:v000010DEd00000298*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce Go 7900 GS]
+
+pci:v000010DEd00000299*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce Go 7900 GTX]
+
+pci:v000010DEd0000029A*
+ ID_PRODUCT_FROM_DATABASE=G71 [Quadro FX 2500M]
+
+pci:v000010DEd0000029B*
+ ID_PRODUCT_FROM_DATABASE=G71 [Quadro FX 1500M]
+
+pci:v000010DEd0000029C*
+ ID_PRODUCT_FROM_DATABASE=G71 [Quadro FX 5500]
+
+pci:v000010DEd0000029D*
+ ID_PRODUCT_FROM_DATABASE=G71GL [Quadro FX 3500]
+
+pci:v000010DEd0000029E*
+ ID_PRODUCT_FROM_DATABASE=G71 [Quadro FX 1500]
+
+pci:v000010DEd0000029F*
+ ID_PRODUCT_FROM_DATABASE=G70 [Quadro FX 4500 X2]
+
+pci:v000010DEd000002A0*
+ ID_PRODUCT_FROM_DATABASE=NV2A [XGPU]
+
+pci:v000010DEd000002A5*
+ ID_PRODUCT_FROM_DATABASE=MCPX CPU Bridge
+
+pci:v000010DEd000002A6*
+ ID_PRODUCT_FROM_DATABASE=MCPX Memory Controller
+
+pci:v000010DEd000002E0*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 GT]
+
+pci:v000010DEd000002E0sv000002E0sd00002249*
+ ID_PRODUCT_FROM_DATABASE=GF 7600GT 560M 256MB DDR3 DUAL DVI TV
+
+pci:v000010DEd000002E1*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 GS]
+
+pci:v000010DEd000002E1sv00001682sd0000222B*
+ ID_PRODUCT_FROM_DATABASE=PV-T73K-UAL3 (256MB)
+
+pci:v000010DEd000002E1sv00001682sd00002247*
+ ID_PRODUCT_FROM_DATABASE=GF 7600GS 512MB DDR2
+
+pci:v000010DEd000002E2*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7300 GT]
+
+pci:v000010DEd000002E3*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GS]
+
+pci:v000010DEd000002E4*
+ ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7950 GT]
+
+pci:v000010DEd000002E4sv00001682sd00002271*
+ ID_PRODUCT_FROM_DATABASE=PV-T71A-YDF7 (512MB)
+
+pci:v000010DEd000002F0*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002F0sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd000002F0sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd000002F0sv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd000002F0sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd000002F1*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002F1sv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd000002F2*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002F3*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002F4*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002F5*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002F6*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002F7*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002F8*
+ ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 5
+
+pci:v000010DEd000002F8sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd000002F8sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd000002F8sv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd000002F8sv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd000002F8sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd000002F9*
+ ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 4
+
+pci:v000010DEd000002F9sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd000002F9sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd000002F9sv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd000002F9sv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd000002F9sv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd000002FA*
+ ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 0
+
+pci:v000010DEd000002FAsv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd000002FAsv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd000002FAsv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd000002FAsv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd000002FAsv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd000002FB*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd000002FC*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd000002FCsv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd000002FD*
+ ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge
+
+pci:v000010DEd000002FDsv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd000002FE*
+ ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 1
+
+pci:v000010DEd000002FEsv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd000002FEsv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd000002FEsv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd000002FEsv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd000002FEsv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd000002FF*
+ ID_PRODUCT_FROM_DATABASE=C51 Host Bridge
+
+pci:v000010DEd000002FFsv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000010DEd000002FFsv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v000010DEd000002FFsv00001043sd000081CD*
+ ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard
+
+pci:v000010DEd000002FFsv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G
+
+pci:v000010DEd000002FFsv00001462sd00007207*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series
+
+pci:v000010DEd00000300*
+ ID_PRODUCT_FROM_DATABASE=NV30 [GeForce FX]
+
+pci:v000010DEd00000301*
+ ID_PRODUCT_FROM_DATABASE=NV30 [GeForce FX 5800 Ultra]
+
+pci:v000010DEd00000302*
+ ID_PRODUCT_FROM_DATABASE=NV30 [GeForce FX 5800]
+
+pci:v000010DEd00000308*
+ ID_PRODUCT_FROM_DATABASE=NV30GL [Quadro FX 2000]
+
+pci:v000010DEd00000309*
+ ID_PRODUCT_FROM_DATABASE=NV30GL [Quadro FX 1000]
+
+pci:v000010DEd00000311*
+ ID_PRODUCT_FROM_DATABASE=NV31 [GeForce FX 5600 Ultra]
+
+pci:v000010DEd00000312*
+ ID_PRODUCT_FROM_DATABASE=NV31 [GeForce FX 5600]
+
+pci:v000010DEd00000313*
+ ID_PRODUCT_FROM_DATABASE=NV31
+
+pci:v000010DEd00000314*
+ ID_PRODUCT_FROM_DATABASE=NV31 [GeForce FX 5600XT]
+
+pci:v000010DEd00000314sv00001043sd0000814A*
+ ID_PRODUCT_FROM_DATABASE=V9560XT/TD
+
+pci:v000010DEd00000316*
+ ID_PRODUCT_FROM_DATABASE=NV31M
+
+pci:v000010DEd00000317*
+ ID_PRODUCT_FROM_DATABASE=NV31M Pro
+
+pci:v000010DEd0000031A*
+ ID_PRODUCT_FROM_DATABASE=NV31M [GeForce FX Go5600]
+
+pci:v000010DEd0000031B*
+ ID_PRODUCT_FROM_DATABASE=NV31M [GeForce FX Go5650]
+
+pci:v000010DEd0000031C*
+ ID_PRODUCT_FROM_DATABASE=NV31 [Quadro FX Go700]
+
+pci:v000010DEd0000031D*
+ ID_PRODUCT_FROM_DATABASE=NV31GLM
+
+pci:v000010DEd0000031E*
+ ID_PRODUCT_FROM_DATABASE=NV31GLM Pro
+
+pci:v000010DEd0000031F*
+ ID_PRODUCT_FROM_DATABASE=NV31GLM Pro
+
+pci:v000010DEd00000320*
+ ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5200]
+
+pci:v000010DEd00000321*
+ ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5200 Ultra]
+
+pci:v000010DEd00000322*
+ ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5200]
+
+pci:v000010DEd00000322sv00001043sd000002FB*
+ ID_PRODUCT_FROM_DATABASE=V9250 Magic
+
+pci:v000010DEd00000322sv00001043sd00008180*
+ ID_PRODUCT_FROM_DATABASE=V9520-X/TD/128M
+
+pci:v000010DEd00000322sv00001462sd00009110*
+ ID_PRODUCT_FROM_DATABASE=MS-8911 (FX5200-TD128)
+
+pci:v000010DEd00000322sv00001462sd00009171*
+ ID_PRODUCT_FROM_DATABASE=MS-8917 (FX5200-T128)
+
+pci:v000010DEd00000322sv00001462sd00009360*
+ ID_PRODUCT_FROM_DATABASE=MS-8936 (FX5200-T128)
+
+pci:v000010DEd00000322sv00001682sd00001351*
+ ID_PRODUCT_FROM_DATABASE=GeForce FX 5200
+
+pci:v000010DEd00000323*
+ ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5200LE]
+
+pci:v000010DEd00000324*
+ ID_PRODUCT_FROM_DATABASE=NV34M [GeForce FX Go5200 64M]
+
+pci:v000010DEd00000324sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v000010DEd00000324sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=Pavilion ZD7000 laptop
+
+pci:v000010DEd00000324sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v000010DEd00000325*
+ ID_PRODUCT_FROM_DATABASE=NV34M [GeForce FX Go5250]
+
+pci:v000010DEd00000326*
+ ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5500]
+
+pci:v000010DEd00000326sv00001458sd0000310D*
+ ID_PRODUCT_FROM_DATABASE=GeForce FX 5500 128 MB
+
+pci:v000010DEd00000326sv00001682sd00002034*
+ ID_PRODUCT_FROM_DATABASE=GeForce 5500 256 MB
+
+pci:v000010DEd00000327*
+ ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5100]
+
+pci:v000010DEd00000328*
+ ID_PRODUCT_FROM_DATABASE=NV34M [GeForce FX Go5200 32M/64M]
+
+pci:v000010DEd00000329*
+ ID_PRODUCT_FROM_DATABASE=NV34M [GeForce FX Go5200]
+
+pci:v000010DEd00000329sv000010DEsd00000010*
+ ID_PRODUCT_FROM_DATABASE=Powerbook G4
+
+pci:v000010DEd0000032A*
+ ID_PRODUCT_FROM_DATABASE=NV34GL [Quadro NVS 280 PCI]
+
+pci:v000010DEd0000032B*
+ ID_PRODUCT_FROM_DATABASE=NV34GL [Quadro FX 500/600 PCI]
+
+pci:v000010DEd0000032C*
+ ID_PRODUCT_FROM_DATABASE=NV34GLM [GeForce FX Go 5300]
+
+pci:v000010DEd0000032D*
+ ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX Go5100]
+
+pci:v000010DEd0000032F*
+ ID_PRODUCT_FROM_DATABASE=NV34GL
+
+pci:v000010DEd00000330*
+ ID_PRODUCT_FROM_DATABASE=NV35 [GeForce FX 5900 Ultra]
+
+pci:v000010DEd00000330sv00001043sd00008137*
+ ID_PRODUCT_FROM_DATABASE=V9950 Ultra / 256 MB
+
+pci:v000010DEd00000331*
+ ID_PRODUCT_FROM_DATABASE=NV35 [GeForce FX 5900]
+
+pci:v000010DEd00000331sv00001043sd00008145*
+ ID_PRODUCT_FROM_DATABASE=V9950GE
+
+pci:v000010DEd00000332*
+ ID_PRODUCT_FROM_DATABASE=NV35 [GeForce FX 5900XT]
+
+pci:v000010DEd00000333*
+ ID_PRODUCT_FROM_DATABASE=NV38 [GeForce FX 5950 Ultra]
+
+pci:v000010DEd00000334*
+ ID_PRODUCT_FROM_DATABASE=NV35 [GeForce FX 5900ZT]
+
+pci:v000010DEd00000334sv00001462sd00009373*
+ ID_PRODUCT_FROM_DATABASE=FX5900ZT-VTD128 (MS-8937)
+
+pci:v000010DEd00000338*
+ ID_PRODUCT_FROM_DATABASE=NV35GL [Quadro FX 3000]
+
+pci:v000010DEd0000033F*
+ ID_PRODUCT_FROM_DATABASE=NV35GL [Quadro FX 700]
+
+pci:v000010DEd00000341*
+ ID_PRODUCT_FROM_DATABASE=NV36.1 [GeForce FX 5700 Ultra]
+
+pci:v000010DEd00000341sv00001462sd00009380*
+ ID_PRODUCT_FROM_DATABASE=MS-8938 (FX5700U-TD128)
+
+pci:v000010DEd00000342*
+ ID_PRODUCT_FROM_DATABASE=NV36.2 [GeForce FX 5700]
+
+pci:v000010DEd00000343*
+ ID_PRODUCT_FROM_DATABASE=NV36 [GeForce FX 5700LE]
+
+pci:v000010DEd00000344*
+ ID_PRODUCT_FROM_DATABASE=NV36.4 [GeForce FX 5700VE]
+
+pci:v000010DEd00000345*
+ ID_PRODUCT_FROM_DATABASE=NV36.5
+
+pci:v000010DEd00000347*
+ ID_PRODUCT_FROM_DATABASE=NV36 [GeForce FX Go5700]
+
+pci:v000010DEd00000347sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v000010DEd00000348*
+ ID_PRODUCT_FROM_DATABASE=NV36 [GeForce FX Go5700]
+
+pci:v000010DEd00000349*
+ ID_PRODUCT_FROM_DATABASE=NV36M Pro
+
+pci:v000010DEd0000034B*
+ ID_PRODUCT_FROM_DATABASE=NV36MAP
+
+pci:v000010DEd0000034C*
+ ID_PRODUCT_FROM_DATABASE=NV36 [Quadro FX Go1000]
+
+pci:v000010DEd0000034E*
+ ID_PRODUCT_FROM_DATABASE=NV36GL [Quadro FX 1100]
+
+pci:v000010DEd0000034F*
+ ID_PRODUCT_FROM_DATABASE=NV36GL
+
+pci:v000010DEd00000360*
+ ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge
+
+pci:v000010DEd00000361*
+ ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge
+
+pci:v000010DEd00000361sv00001028sd00000221*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 LPC Bridge
+
+pci:v000010DEd00000362*
+ ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge
+
+pci:v000010DEd00000362sv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd00000363*
+ ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge
+
+pci:v000010DEd00000364*
+ ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge
+
+pci:v000010DEd00000364sv00001028sd00000221*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 LPC Bridge
+
+pci:v000010DEd00000365*
+ ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge
+
+pci:v000010DEd00000366*
+ ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge
+
+pci:v000010DEd00000367*
+ ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge
+
+pci:v000010DEd00000368*
+ ID_PRODUCT_FROM_DATABASE=MCP55 SMBus
+
+pci:v000010DEd00000368sv00001028sd0000020C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M605 MCP55 SMBus
+
+pci:v000010DEd00000368sv00001028sd00000221*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 SMBus
+
+pci:v000010DEd00000368sv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd00000369*
+ ID_PRODUCT_FROM_DATABASE=MCP55 Memory Controller
+
+pci:v000010DEd00000369sv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd0000036A*
+ ID_PRODUCT_FROM_DATABASE=MCP55 Memory Controller
+
+pci:v000010DEd0000036B*
+ ID_PRODUCT_FROM_DATABASE=MCP55 SMU
+
+pci:v000010DEd0000036C*
+ ID_PRODUCT_FROM_DATABASE=MCP55 USB Controller
+
+pci:v000010DEd0000036Csv00001028sd0000020C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M605 MCP55 USB Controller
+
+pci:v000010DEd0000036Csv00001028sd00000221*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 USB Controller
+
+pci:v000010DEd0000036Csv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd0000036D*
+ ID_PRODUCT_FROM_DATABASE=MCP55 USB Controller
+
+pci:v000010DEd0000036Dsv00001028sd0000020C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M605 MCP55 USB Controller
+
+pci:v000010DEd0000036Dsv00001028sd00000221*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 USB Controller
+
+pci:v000010DEd0000036Dsv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd0000036E*
+ ID_PRODUCT_FROM_DATABASE=MCP55 IDE
+
+pci:v000010DEd0000036Esv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd00000370*
+ ID_PRODUCT_FROM_DATABASE=MCP55 PCI bridge
+
+pci:v000010DEd00000371*
+ ID_PRODUCT_FROM_DATABASE=MCP55 High Definition Audio
+
+pci:v000010DEd00000371sv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd00000372*
+ ID_PRODUCT_FROM_DATABASE=MCP55 Ethernet
+
+pci:v000010DEd00000373*
+ ID_PRODUCT_FROM_DATABASE=MCP55 Ethernet
+
+pci:v000010DEd00000373sv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd00000374*
+ ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge
+
+pci:v000010DEd00000375*
+ ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge
+
+pci:v000010DEd00000376*
+ ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge
+
+pci:v000010DEd00000377*
+ ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge
+
+pci:v000010DEd00000378*
+ ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge
+
+pci:v000010DEd0000037A*
+ ID_PRODUCT_FROM_DATABASE=MCP55 Memory Controller
+
+pci:v000010DEd0000037E*
+ ID_PRODUCT_FROM_DATABASE=MCP55 SATA Controller
+
+pci:v000010DEd0000037F*
+ ID_PRODUCT_FROM_DATABASE=MCP55 SATA Controller
+
+pci:v000010DEd0000037Fsv00001028sd00000221*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 SATA Controller
+
+pci:v000010DEd0000037Fsv0000147Bsd00001C24*
+ ID_PRODUCT_FROM_DATABASE=KN9 series mainboard
+
+pci:v000010DEd0000038B*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7650 GS]
+
+pci:v000010DEd00000390*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7650 GS]
+
+pci:v000010DEd00000391*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 GT]
+
+pci:v000010DEd00000391sv00001458sd00003427*
+ ID_PRODUCT_FROM_DATABASE=GV-NX76T128D-RH
+
+pci:v000010DEd00000392*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 GS]
+
+pci:v000010DEd00000392sv00001462sd00000622*
+ ID_PRODUCT_FROM_DATABASE=NX7600GS-T2D256EH
+
+pci:v000010DEd00000393*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7300 GT]
+
+pci:v000010DEd00000393sv000010DEsd00000412*
+ ID_PRODUCT_FROM_DATABASE=NX7300GT-TD256EH
+
+pci:v000010DEd00000393sv00001462sd00000412*
+ ID_PRODUCT_FROM_DATABASE=NX7300GT-TD256EH
+
+pci:v000010DEd00000394*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 LE]
+
+pci:v000010DEd00000395*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7300 GT]
+
+pci:v000010DEd00000397*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce Go 7700]
+
+pci:v000010DEd00000398*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce Go 7600]
+
+pci:v000010DEd00000398sv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=Acer 9814 WKMI
+
+pci:v000010DEd00000399*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce Go 7600 GT]
+
+pci:v000010DEd0000039A*
+ ID_PRODUCT_FROM_DATABASE=G73M [Quadro NVS 300M]
+
+pci:v000010DEd0000039B*
+ ID_PRODUCT_FROM_DATABASE=G73 [GeForce Go 7900 SE]
+
+pci:v000010DEd0000039C*
+ ID_PRODUCT_FROM_DATABASE=G73 [Quadro FX 550M]
+
+pci:v000010DEd0000039Csv000010DEsd0000039C*
+ ID_PRODUCT_FROM_DATABASE=Quadro FX 560M
+
+pci:v000010DEd0000039E*
+ ID_PRODUCT_FROM_DATABASE=G73GL [Quadro FX 560]
+
+pci:v000010DEd000003A0*
+ ID_PRODUCT_FROM_DATABASE=C55 Host Bridge
+
+pci:v000010DEd000003A1*
+ ID_PRODUCT_FROM_DATABASE=C55 Host Bridge
+
+pci:v000010DEd000003A2*
+ ID_PRODUCT_FROM_DATABASE=C55 Host Bridge
+
+pci:v000010DEd000003A3*
+ ID_PRODUCT_FROM_DATABASE=C55 Host Bridge
+
+pci:v000010DEd000003A4*
+ ID_PRODUCT_FROM_DATABASE=C55 Host Bridge
+
+pci:v000010DEd000003A5*
+ ID_PRODUCT_FROM_DATABASE=C55 Host Bridge
+
+pci:v000010DEd000003A6*
+ ID_PRODUCT_FROM_DATABASE=C55 Host Bridge
+
+pci:v000010DEd000003A7*
+ ID_PRODUCT_FROM_DATABASE=C55 Host Bridge
+
+pci:v000010DEd000003A8*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003A9*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003AA*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003AB*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003AC*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003AD*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003AE*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003AF*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003B0*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003B1*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003B2*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003B3*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003B4*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003B5*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003B6*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003B7*
+ ID_PRODUCT_FROM_DATABASE=C55 PCI Express bridge
+
+pci:v000010DEd000003B8*
+ ID_PRODUCT_FROM_DATABASE=C55 PCI Express bridge
+
+pci:v000010DEd000003B9*
+ ID_PRODUCT_FROM_DATABASE=C55 PCI Express bridge
+
+pci:v000010DEd000003BA*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003BB*
+ ID_PRODUCT_FROM_DATABASE=C55 PCI Express bridge
+
+pci:v000010DEd000003BC*
+ ID_PRODUCT_FROM_DATABASE=C55 Memory Controller
+
+pci:v000010DEd000003D0*
+ ID_PRODUCT_FROM_DATABASE=C61 [GeForce 6150SE nForce 430]
+
+pci:v000010DEd000003D0sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003D1*
+ ID_PRODUCT_FROM_DATABASE=C61 [GeForce 6100 nForce 405]
+
+pci:v000010DEd000003D2*
+ ID_PRODUCT_FROM_DATABASE=C61 [GeForce 6100 nForce 400]
+
+pci:v000010DEd000003D5*
+ ID_PRODUCT_FROM_DATABASE=C61 [GeForce 6100 nForce 420]
+
+pci:v000010DEd000003D6*
+ ID_PRODUCT_FROM_DATABASE=C61 [GeForce 7025 / nForce 630a]
+
+pci:v000010DEd000003E0*
+ ID_PRODUCT_FROM_DATABASE=MCP61 LPC Bridge
+
+pci:v000010DEd000003E0sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003E0sv00001849sd000003E0*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003E1*
+ ID_PRODUCT_FROM_DATABASE=MCP61 LPC Bridge
+
+pci:v000010DEd000003E1sv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003E2*
+ ID_PRODUCT_FROM_DATABASE=MCP61 Host Bridge
+
+pci:v000010DEd000003E2sv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003E3*
+ ID_PRODUCT_FROM_DATABASE=MCP61 LPC Bridge
+
+pci:v000010DEd000003E4*
+ ID_PRODUCT_FROM_DATABASE=MCP61 High Definition Audio
+
+pci:v000010DEd000003E5*
+ ID_PRODUCT_FROM_DATABASE=MCP61 Ethernet
+
+pci:v000010DEd000003E6*
+ ID_PRODUCT_FROM_DATABASE=MCP61 Ethernet
+
+pci:v000010DEd000003E7*
+ ID_PRODUCT_FROM_DATABASE=MCP61 SATA Controller
+
+pci:v000010DEd000003E8*
+ ID_PRODUCT_FROM_DATABASE=MCP61 PCI Express bridge
+
+pci:v000010DEd000003E8sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003E8sv00001849sd000003E8*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003E9*
+ ID_PRODUCT_FROM_DATABASE=MCP61 PCI Express bridge
+
+pci:v000010DEd000003E9sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003E9sv00001849sd000003E9*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003EA*
+ ID_PRODUCT_FROM_DATABASE=MCP61 Memory Controller
+
+pci:v000010DEd000003EAsv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003EAsv00001849sd000003EA*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003EB*
+ ID_PRODUCT_FROM_DATABASE=MCP61 SMBus
+
+pci:v000010DEd000003EBsv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003EBsv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003EBsv00001849sd000003EB*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003EC*
+ ID_PRODUCT_FROM_DATABASE=MCP61 IDE
+
+pci:v000010DEd000003ECsv00001025sd00000392*
+ ID_PRODUCT_FROM_DATABASE=ET1350
+
+pci:v000010DEd000003ECsv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003ECsv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003ECsv00001849sd000003EC*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003EE*
+ ID_PRODUCT_FROM_DATABASE=MCP61 Ethernet
+
+pci:v000010DEd000003EF*
+ ID_PRODUCT_FROM_DATABASE=MCP61 Ethernet
+
+pci:v000010DEd000003EFsv00001025sd00008000*
+ ID_PRODUCT_FROM_DATABASE=ET1350
+
+pci:v000010DEd000003EFsv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003EFsv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003EFsv00001849sd000003EF*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003F0*
+ ID_PRODUCT_FROM_DATABASE=MCP61 High Definition Audio
+
+pci:v000010DEd000003F0sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003F0sv00001043sd00008415*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003F0sv00001849sd00000888*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003F1*
+ ID_PRODUCT_FROM_DATABASE=MCP61 USB 1.1 Controller
+
+pci:v000010DEd000003F1sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003F1sv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003F1sv00001849sd000003F1*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003F2*
+ ID_PRODUCT_FROM_DATABASE=MCP61 USB 2.0 Controller
+
+pci:v000010DEd000003F2sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003F2sv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003F2sv00001849sd000003F2*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003F3*
+ ID_PRODUCT_FROM_DATABASE=MCP61 PCI bridge
+
+pci:v000010DEd000003F3sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003F3sv00001849sd000003F3*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003F4*
+ ID_PRODUCT_FROM_DATABASE=MCP61 SMU
+
+pci:v000010DEd000003F5*
+ ID_PRODUCT_FROM_DATABASE=MCP61 Memory Controller
+
+pci:v000010DEd000003F5sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003F5sv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003F5sv00001849sd000003EB*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003F6*
+ ID_PRODUCT_FROM_DATABASE=MCP61 SATA Controller
+
+pci:v000010DEd000003F6sv00001028sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 531
+
+pci:v000010DEd000003F6sv00001043sd000083A4*
+ ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard
+
+pci:v000010DEd000003F6sv00001849sd000003F6*
+ ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board
+
+pci:v000010DEd000003F7*
+ ID_PRODUCT_FROM_DATABASE=MCP61 SATA Controller
+
+pci:v000010DEd00000400*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600 GTS]
+
+pci:v000010DEd00000400sv00001043sd00008241*
+ ID_PRODUCT_FROM_DATABASE=EN8600GTS
+
+pci:v000010DEd00000401*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600GT]
+
+pci:v000010DEd00000402*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600 GT]
+
+pci:v000010DEd00000402sv00001458sd00003455*
+ ID_PRODUCT_FROM_DATABASE=GV-NX86T512H
+
+pci:v000010DEd00000402sv00001462sd00000910*
+ ID_PRODUCT_FROM_DATABASE=NX8600GT-T2D256EZ
+
+pci:v000010DEd00000403*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600 GS]
+
+pci:v000010DEd00000404*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8400 GS]
+
+pci:v000010DEd00000404sv00001462sd00001230*
+ ID_PRODUCT_FROM_DATABASE=NX8400GS-TD256E
+
+pci:v000010DEd00000405*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 9500M GS]
+
+pci:v000010DEd00000406*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8300 GS]
+
+pci:v000010DEd00000407*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600M GT]
+
+pci:v000010DEd00000408*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 9650M GS]
+
+pci:v000010DEd00000409*
+ ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8700M GT]
+
+pci:v000010DEd0000040A*
+ ID_PRODUCT_FROM_DATABASE=G84 [Quadro FX 370]
+
+pci:v000010DEd0000040B*
+ ID_PRODUCT_FROM_DATABASE=G84M [Quadro NVS 320M]
+
+pci:v000010DEd0000040C*
+ ID_PRODUCT_FROM_DATABASE=G84M [Quadro FX 570M]
+
+pci:v000010DEd0000040Csv000017AAsd000020D9*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61p
+
+pci:v000010DEd0000040D*
+ ID_PRODUCT_FROM_DATABASE=G84 [Quadro FX 1600M]
+
+pci:v000010DEd0000040E*
+ ID_PRODUCT_FROM_DATABASE=G84 [Quadro FX 570]
+
+pci:v000010DEd0000040F*
+ ID_PRODUCT_FROM_DATABASE=G84 [Quadro FX 1700]
+
+pci:v000010DEd00000410*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce GT 330]
+
+pci:v000010DEd00000420*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400 SE]
+
+pci:v000010DEd00000421*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8500 GT]
+
+pci:v000010DEd00000421sv00001462sd00000960*
+ ID_PRODUCT_FROM_DATABASE=NX8500GT-TD512EH/M2
+
+pci:v000010DEd00000422*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400 GS]
+
+pci:v000010DEd00000423*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8300 GS]
+
+pci:v000010DEd00000424*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400 GS]
+
+pci:v000010DEd00000425*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8600M GS]
+
+pci:v000010DEd00000425sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v000010DEd00000426*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400M GT]
+
+pci:v000010DEd00000427*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400M GS]
+
+pci:v000010DEd00000427sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v000010DEd00000428*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400M G]
+
+pci:v000010DEd00000429*
+ ID_PRODUCT_FROM_DATABASE=G86 [Quadro NVS 140M]
+
+pci:v000010DEd00000429sv000017AAsd000020D8*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v000010DEd0000042A*
+ ID_PRODUCT_FROM_DATABASE=G86M [Quadro NVS 130M]
+
+pci:v000010DEd0000042B*
+ ID_PRODUCT_FROM_DATABASE=G86M [Quadro NVS 135M]
+
+pci:v000010DEd0000042C*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 9400 GT]
+
+pci:v000010DEd0000042D*
+ ID_PRODUCT_FROM_DATABASE=G86M [Quadro FX 360M]
+
+pci:v000010DEd0000042E*
+ ID_PRODUCT_FROM_DATABASE=G86 [GeForce 9300M G]
+
+pci:v000010DEd0000042F*
+ ID_PRODUCT_FROM_DATABASE=G86 [Quadro NVS 290]
+
+pci:v000010DEd00000440*
+ ID_PRODUCT_FROM_DATABASE=MCP65 LPC Bridge
+
+pci:v000010DEd00000441*
+ ID_PRODUCT_FROM_DATABASE=MCP65 LPC Bridge
+
+pci:v000010DEd00000442*
+ ID_PRODUCT_FROM_DATABASE=MCP65 LPC Bridge
+
+pci:v000010DEd00000443*
+ ID_PRODUCT_FROM_DATABASE=MCP65 LPC Bridge
+
+pci:v000010DEd00000444*
+ ID_PRODUCT_FROM_DATABASE=MCP65 Memory Controller
+
+pci:v000010DEd00000445*
+ ID_PRODUCT_FROM_DATABASE=MCP65 Memory Controller
+
+pci:v000010DEd00000446*
+ ID_PRODUCT_FROM_DATABASE=MCP65 SMBus
+
+pci:v000010DEd00000447*
+ ID_PRODUCT_FROM_DATABASE=MCP65 SMU
+
+pci:v000010DEd00000448*
+ ID_PRODUCT_FROM_DATABASE=MCP65 IDE
+
+pci:v000010DEd00000449*
+ ID_PRODUCT_FROM_DATABASE=MCP65 PCI bridge
+
+pci:v000010DEd0000044A*
+ ID_PRODUCT_FROM_DATABASE=MCP65 High Definition Audio
+
+pci:v000010DEd0000044B*
+ ID_PRODUCT_FROM_DATABASE=MCP65 High Definition Audio
+
+pci:v000010DEd0000044C*
+ ID_PRODUCT_FROM_DATABASE=MCP65 AHCI Controller
+
+pci:v000010DEd0000044D*
+ ID_PRODUCT_FROM_DATABASE=MCP65 AHCI Controller
+
+pci:v000010DEd0000044E*
+ ID_PRODUCT_FROM_DATABASE=MCP65 AHCI Controller
+
+pci:v000010DEd0000044F*
+ ID_PRODUCT_FROM_DATABASE=MCP65 AHCI Controller
+
+pci:v000010DEd00000450*
+ ID_PRODUCT_FROM_DATABASE=MCP65 Ethernet
+
+pci:v000010DEd00000451*
+ ID_PRODUCT_FROM_DATABASE=MCP65 Ethernet
+
+pci:v000010DEd00000452*
+ ID_PRODUCT_FROM_DATABASE=MCP65 Ethernet
+
+pci:v000010DEd00000453*
+ ID_PRODUCT_FROM_DATABASE=MCP65 Ethernet
+
+pci:v000010DEd00000454*
+ ID_PRODUCT_FROM_DATABASE=MCP65 USB Controller
+
+pci:v000010DEd00000455*
+ ID_PRODUCT_FROM_DATABASE=MCP65 USB Controller
+
+pci:v000010DEd00000456*
+ ID_PRODUCT_FROM_DATABASE=MCP65 USB Controller
+
+pci:v000010DEd00000457*
+ ID_PRODUCT_FROM_DATABASE=MCP65 USB Controller
+
+pci:v000010DEd00000458*
+ ID_PRODUCT_FROM_DATABASE=MCP65 PCI Express bridge
+
+pci:v000010DEd00000459*
+ ID_PRODUCT_FROM_DATABASE=MCP65 PCI Express bridge
+
+pci:v000010DEd0000045A*
+ ID_PRODUCT_FROM_DATABASE=MCP65 PCI Express bridge
+
+pci:v000010DEd0000045C*
+ ID_PRODUCT_FROM_DATABASE=MCP65 SATA Controller
+
+pci:v000010DEd0000045D*
+ ID_PRODUCT_FROM_DATABASE=MCP65 SATA Controller
+
+pci:v000010DEd0000045E*
+ ID_PRODUCT_FROM_DATABASE=MCP65 SATA Controller
+
+pci:v000010DEd0000045F*
+ ID_PRODUCT_FROM_DATABASE=MCP65 SATA Controller
+
+pci:v000010DEd00000531*
+ ID_PRODUCT_FROM_DATABASE=C67 [GeForce 7150M / nForce 630M]
+
+pci:v000010DEd00000533*
+ ID_PRODUCT_FROM_DATABASE=C67 [GeForce 7000M / nForce 610M]
+
+pci:v000010DEd0000053A*
+ ID_PRODUCT_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a]
+
+pci:v000010DEd0000053B*
+ ID_PRODUCT_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a]
+
+pci:v000010DEd0000053Bsv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherbord
+
+pci:v000010DEd0000053E*
+ ID_PRODUCT_FROM_DATABASE=C68 [GeForce 7025 / nForce 630a]
+
+pci:v000010DEd00000541*
+ ID_PRODUCT_FROM_DATABASE=MCP67 Memory Controller
+
+pci:v000010DEd00000542*
+ ID_PRODUCT_FROM_DATABASE=MCP67 SMBus
+
+pci:v000010DEd00000542sv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherbord
+
+pci:v000010DEd00000543*
+ ID_PRODUCT_FROM_DATABASE=MCP67 Co-processor
+
+pci:v000010DEd00000547*
+ ID_PRODUCT_FROM_DATABASE=MCP67 Memory Controller
+
+pci:v000010DEd00000547sv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherbord
+
+pci:v000010DEd00000547sv00001849sd00000547*
+ ID_PRODUCT_FROM_DATABASE=ALiveNF7G-HDready
+
+pci:v000010DEd00000548*
+ ID_PRODUCT_FROM_DATABASE=MCP67 ISA Bridge
+
+pci:v000010DEd00000548sv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard
+
+pci:v000010DEd0000054C*
+ ID_PRODUCT_FROM_DATABASE=MCP67 Ethernet
+
+pci:v000010DEd0000054Csv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherbord
+
+pci:v000010DEd0000054Csv00001849sd0000054C*
+ ID_PRODUCT_FROM_DATABASE=ALiveNF7G-HDready, MCP67 Gigabit Ethernet
+
+pci:v000010DEd0000054D*
+ ID_PRODUCT_FROM_DATABASE=MCP67 Ethernet
+
+pci:v000010DEd0000054E*
+ ID_PRODUCT_FROM_DATABASE=MCP67 Ethernet
+
+pci:v000010DEd0000054F*
+ ID_PRODUCT_FROM_DATABASE=MCP67 Ethernet
+
+pci:v000010DEd00000550*
+ ID_PRODUCT_FROM_DATABASE=MCP67 AHCI Controller
+
+pci:v000010DEd00000550sv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard
+
+pci:v000010DEd00000554*
+ ID_PRODUCT_FROM_DATABASE=MCP67 AHCI Controller
+
+pci:v000010DEd00000554sv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard
+
+pci:v000010DEd00000555*
+ ID_PRODUCT_FROM_DATABASE=MCP67 SATA Controller
+
+pci:v000010DEd00000555sv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard
+
+pci:v000010DEd0000055C*
+ ID_PRODUCT_FROM_DATABASE=MCP67 High Definition Audio
+
+pci:v000010DEd0000055Csv00001043sd00008290*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard
+
+pci:v000010DEd0000055D*
+ ID_PRODUCT_FROM_DATABASE=MCP67 High Definition Audio
+
+pci:v000010DEd0000055E*
+ ID_PRODUCT_FROM_DATABASE=MCP67 OHCI USB 1.1 Controller
+
+pci:v000010DEd0000055Esv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard
+
+pci:v000010DEd0000055F*
+ ID_PRODUCT_FROM_DATABASE=MCP67 EHCI USB 2.0 Controller
+
+pci:v000010DEd0000055Fsv00001043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard
+
+pci:v000010DEd00000560*
+ ID_PRODUCT_FROM_DATABASE=MCP67 IDE Controller
+
+pci:v000010DEd00000560sv0000F043sd00008308*
+ ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard
+
+pci:v000010DEd00000561*
+ ID_PRODUCT_FROM_DATABASE=MCP67 PCI Bridge
+
+pci:v000010DEd00000562*
+ ID_PRODUCT_FROM_DATABASE=MCP67 PCI Express Bridge
+
+pci:v000010DEd00000562sv00001849sd00000562*
+ ID_PRODUCT_FROM_DATABASE=ALiveNF7G-HDready
+
+pci:v000010DEd00000563*
+ ID_PRODUCT_FROM_DATABASE=MCP67 PCI Express Bridge
+
+pci:v000010DEd00000568*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller
+
+pci:v000010DEd00000568sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000568sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000568sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000568sv00001849sd00000568*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller
+
+pci:v000010DEd00000569*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge
+
+pci:v000010DEd00000569sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000569sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000569sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000569sv00001849sd00000569*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge
+
+pci:v000010DEd0000056A*
+ ID_PRODUCT_FROM_DATABASE=MCP73 [nForce 630i] USB 2.0 Controller (EHCI)
+
+pci:v000010DEd0000056Asv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd0000056C*
+ ID_PRODUCT_FROM_DATABASE=MCP73 IDE
+
+pci:v000010DEd0000056Csv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd0000056Csv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd0000056D*
+ ID_PRODUCT_FROM_DATABASE=MCP73 PCI Express bridge
+
+pci:v000010DEd0000056Dsv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd0000056E*
+ ID_PRODUCT_FROM_DATABASE=MCP73 PCI Express bridge
+
+pci:v000010DEd0000056Esv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd0000056F*
+ ID_PRODUCT_FROM_DATABASE=MCP73 PCI Express bridge
+
+pci:v000010DEd0000056Fsv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000005B1*
+ ID_PRODUCT_FROM_DATABASE=NF200 PCIe 2.0 switch
+
+pci:v000010DEd000005B8*
+ ID_PRODUCT_FROM_DATABASE=NF200 PCIe 2.0 switch for GTX 295
+
+pci:v000010DEd000005BE*
+ ID_PRODUCT_FROM_DATABASE=NF200 PCIe 2.0 switch for Quadro Plex S4 / Tesla S870 / Tesla S1070 / Tesla S2050
+
+pci:v000010DEd000005E0*
+ ID_PRODUCT_FROM_DATABASE=GT200b [GeForce GTX 295]
+
+pci:v000010DEd000005E1*
+ ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 280]
+
+pci:v000010DEd000005E2*
+ ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 260]
+
+pci:v000010DEd000005E3*
+ ID_PRODUCT_FROM_DATABASE=GT200b [GeForce GTX 285]
+
+pci:v000010DEd000005E6*
+ ID_PRODUCT_FROM_DATABASE=GT200b [GeForce GTX 275]
+
+pci:v000010DEd000005E7*
+ ID_PRODUCT_FROM_DATABASE=GT200 [Tesla C1060]
+
+pci:v000010DEd000005EA*
+ ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 260]
+
+pci:v000010DEd000005EB*
+ ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 295]
+
+pci:v000010DEd000005ED*
+ ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro Plex 2200 D2]
+
+pci:v000010DEd000005F8*
+ ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro Plex 2200 S4]
+
+pci:v000010DEd000005F9*
+ ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro CX]
+
+pci:v000010DEd000005FD*
+ ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro FX 5800]
+
+pci:v000010DEd000005FE*
+ ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro FX 4800]
+
+pci:v000010DEd000005FF*
+ ID_PRODUCT_FROM_DATABASE=GT200GL [NVIDIA Quadro FX 3800]
+
+pci:v000010DEd00000600*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GTS 512]
+
+pci:v000010DEd00000601*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GT]
+
+pci:v000010DEd00000602*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GT]
+
+pci:v000010DEd00000603*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce GT 230]
+
+pci:v000010DEd00000604*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GX2]
+
+pci:v000010DEd00000605*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GT]
+
+pci:v000010DEd00000606*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GS]
+
+pci:v000010DEd00000607*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce GTS 240]
+
+pci:v000010DEd00000608*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800M GTX]
+
+pci:v000010DEd00000609*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800M GTS]
+
+pci:v000010DEd0000060A*
+ ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 280M]
+
+pci:v000010DEd0000060B*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800M GT]
+
+pci:v000010DEd0000060C*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800M GTX]
+
+pci:v000010DEd0000060D*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GS]
+
+pci:v000010DEd0000060F*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce GTX 285M]
+
+pci:v000010DEd00000610*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9600 GSO]
+
+pci:v000010DEd00000610sv00001682sd00002385*
+ ID_PRODUCT_FROM_DATABASE=GeForce 9600 GSO 768mb
+
+pci:v000010DEd00000611*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GT]
+
+pci:v000010DEd00000611sv0000107Dsd00002AB0*
+ ID_PRODUCT_FROM_DATABASE=Winfast PX8800 GT PCI-E
+
+pci:v000010DEd00000611sv000019DAsd00001040*
+ ID_PRODUCT_FROM_DATABASE=ZT-88TES2P-FSP
+
+pci:v000010DEd00000612*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GTX]
+
+pci:v000010DEd00000613*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GTX+]
+
+pci:v000010DEd00000614*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GT]
+
+pci:v000010DEd00000614sv0000107Dsd00002AB3*
+ ID_PRODUCT_FROM_DATABASE=WinFast PX9800 GT (S-Fanpipe)
+
+pci:v000010DEd00000615*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce GTS 250]
+
+pci:v000010DEd00000615sv00003842sd00001150*
+ ID_PRODUCT_FROM_DATABASE=GeForce GTS 250 P/N 512-P3-1150-TR
+
+pci:v000010DEd00000615sv00003842sd00001151*
+ ID_PRODUCT_FROM_DATABASE=GeForce GTS 250 P/N 512-P3-1151-TR
+
+pci:v000010DEd00000615sv00003842sd00001155*
+ ID_PRODUCT_FROM_DATABASE=GeForce GTS 250 P/N 01G-P3-1155-TR
+
+pci:v000010DEd00000615sv00003842sd00001156*
+ ID_PRODUCT_FROM_DATABASE=GeForce GTS 250 P/N 01G-P3-1156-TR
+
+pci:v000010DEd00000617*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800M GTX]
+
+pci:v000010DEd00000618*
+ ID_PRODUCT_FROM_DATABASE=G92 [GeForce GTX 260M]
+
+pci:v000010DEd00000619*
+ ID_PRODUCT_FROM_DATABASE=G92GL [Quadro FX 4700 X2]
+
+pci:v000010DEd0000061A*
+ ID_PRODUCT_FROM_DATABASE=G92 [Quadro FX 3700]
+
+pci:v000010DEd0000061B*
+ ID_PRODUCT_FROM_DATABASE=G92GL [Quadro VX 200]
+
+pci:v000010DEd0000061C*
+ ID_PRODUCT_FROM_DATABASE=G92M [Quadro FX 3600M]
+
+pci:v000010DEd0000061D*
+ ID_PRODUCT_FROM_DATABASE=G92 [Quadro FX 2800M]
+
+pci:v000010DEd0000061E*
+ ID_PRODUCT_FROM_DATABASE=G92 [Quadro FX 3700M]
+
+pci:v000010DEd0000061F*
+ ID_PRODUCT_FROM_DATABASE=G92 [Quadro FX 3800M]
+
+pci:v000010DEd00000622*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT]
+
+pci:v000010DEd00000622sv0000107Dsd00002AC1*
+ ID_PRODUCT_FROM_DATABASE=WinFast PX9600GT 1024MB
+
+pci:v000010DEd00000622sv00001458sd00003481*
+ ID_PRODUCT_FROM_DATABASE=GV-NX96T512HP
+
+pci:v000010DEd00000623*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GS]
+
+pci:v000010DEd00000624*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT Green Edition]
+
+pci:v000010DEd00000625*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GSO 512]
+
+pci:v000010DEd00000626*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce GT 130]
+
+pci:v000010DEd00000627*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce GT 140]
+
+pci:v000010DEd00000628*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9800M GTS]
+
+pci:v000010DEd0000062A*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9700M GTS]
+
+pci:v000010DEd0000062B*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9800M GS]
+
+pci:v000010DEd0000062C*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9800M GTS]
+
+pci:v000010DEd0000062D*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT]
+
+pci:v000010DEd0000062E*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT]
+
+pci:v000010DEd00000631*
+ ID_PRODUCT_FROM_DATABASE=G94M [GeForce GTS 160M]
+
+pci:v000010DEd00000632*
+ ID_PRODUCT_FROM_DATABASE=G94M [GeForce GTS 150M]
+
+pci:v000010DEd00000635*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GSO]
+
+pci:v000010DEd00000637*
+ ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT]
+
+pci:v000010DEd00000638*
+ ID_PRODUCT_FROM_DATABASE=G94 [Quadro FX 1800]
+
+pci:v000010DEd0000063A*
+ ID_PRODUCT_FROM_DATABASE=G94M [Quadro FX 2700M]
+
+pci:v000010DEd00000640*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500 GT]
+
+pci:v000010DEd00000641*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9400 GT]
+
+pci:v000010DEd00000643*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500 GT]
+
+pci:v000010DEd00000644*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500 GS]
+
+pci:v000010DEd00000645*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500 GS]
+
+pci:v000010DEd00000646*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce GT 120]
+
+pci:v000010DEd00000647*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9600M GT]
+
+pci:v000010DEd00000648*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9600M GS]
+
+pci:v000010DEd00000649*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9600M GT]
+
+pci:v000010DEd0000064A*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9700M GT]
+
+pci:v000010DEd0000064B*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500M G]
+
+pci:v000010DEd0000064C*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9650M GT]
+
+pci:v000010DEd00000651*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce G 110M]
+
+pci:v000010DEd00000652*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce GT 130M]
+
+pci:v000010DEd00000653*
+ ID_PRODUCT_FROM_DATABASE=G96M [GeForce GT 120M]
+
+pci:v000010DEd00000654*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce GT 220M]
+
+pci:v000010DEd00000656*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9650 S]
+
+pci:v000010DEd00000658*
+ ID_PRODUCT_FROM_DATABASE=G96 [Quadro FX 380]
+
+pci:v000010DEd00000659*
+ ID_PRODUCT_FROM_DATABASE=G96 [Quadro FX 580]
+
+pci:v000010DEd0000065A*
+ ID_PRODUCT_FROM_DATABASE=G96 [Quadro FX 1700M]
+
+pci:v000010DEd0000065B*
+ ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9400 GT]
+
+pci:v000010DEd0000065C*
+ ID_PRODUCT_FROM_DATABASE=G96M [Quadro FX 770M]
+
+pci:v000010DEd000006C0*
+ ID_PRODUCT_FROM_DATABASE=GF100 [GeForce GTX 480]
+
+pci:v000010DEd000006CD*
+ ID_PRODUCT_FROM_DATABASE=GF100 [GeForce GTX 470]
+
+pci:v000010DEd000006D1*
+ ID_PRODUCT_FROM_DATABASE=GF100 [Tesla C2050 / C2070]
+
+pci:v000010DEd000006D2*
+ ID_PRODUCT_FROM_DATABASE=GF100 [Tesla M2070]
+
+pci:v000010DEd000006D8*
+ ID_PRODUCT_FROM_DATABASE=GF100GL [Quadro 6000]
+
+pci:v000010DEd000006D9*
+ ID_PRODUCT_FROM_DATABASE=GF100GL [Quadro 5000]
+
+pci:v000010DEd000006DD*
+ ID_PRODUCT_FROM_DATABASE=GF100GL [Quadro 4000]
+
+pci:v000010DEd000006DE*
+ ID_PRODUCT_FROM_DATABASE=GF100 [Tesla S2050]
+
+pci:v000010DEd000006DF*
+ ID_PRODUCT_FROM_DATABASE=GF100 [Tesla M2070Q]
+
+pci:v000010DEd000006E0*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300 GE]
+
+pci:v000010DEd000006E1*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300 GS]
+
+pci:v000010DEd000006E2*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8400]
+
+pci:v000010DEd000006E3*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8300 GS]
+
+pci:v000010DEd000006E4*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8400 GS]
+
+pci:v000010DEd000006E4sv00001458sd00003475*
+ ID_PRODUCT_FROM_DATABASE=GV-NX84S256HE [GeForce 8400 GS]
+
+pci:v000010DEd000006E5*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300M GS]
+
+pci:v000010DEd000006E6*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce G 100]
+
+pci:v000010DEd000006E7*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300 SE]
+
+pci:v000010DEd000006E8*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9200M GS]
+
+pci:v000010DEd000006E9*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300M GS]
+
+pci:v000010DEd000006E9sv00001043sd000019B2*
+ ID_PRODUCT_FROM_DATABASE=U6V laptop
+
+pci:v000010DEd000006EA*
+ ID_PRODUCT_FROM_DATABASE=G86M [Quadro NVS 150M]
+
+pci:v000010DEd000006EB*
+ ID_PRODUCT_FROM_DATABASE=G98M [Quadro NVS 160M]
+
+pci:v000010DEd000006EC*
+ ID_PRODUCT_FROM_DATABASE=G98M [GeForce G 105M]
+
+pci:v000010DEd000006EF*
+ ID_PRODUCT_FROM_DATABASE=G98M [GeForce G 103M]
+
+pci:v000010DEd000006F1*
+ ID_PRODUCT_FROM_DATABASE=G98M [GeForce G 105M]
+
+pci:v000010DEd000006F8*
+ ID_PRODUCT_FROM_DATABASE=G98 [Quadro NVS 420]
+
+pci:v000010DEd000006F9*
+ ID_PRODUCT_FROM_DATABASE=G98 [Quadro FX 370 LP]
+
+pci:v000010DEd000006FA*
+ ID_PRODUCT_FROM_DATABASE=G98 [Quadro NVS 450]
+
+pci:v000010DEd000006FB*
+ ID_PRODUCT_FROM_DATABASE=G98 [Quadro FX 370M]
+
+pci:v000010DEd000006FD*
+ ID_PRODUCT_FROM_DATABASE=G98 [Quadro NVS 295]
+
+pci:v000010DEd000006FF*
+ ID_PRODUCT_FROM_DATABASE=G98 [HICx16 + Graphics]
+
+pci:v000010DEd00000751*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller
+
+pci:v000010DEd00000751sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000751sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000751sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000751sv00001849sd00000751*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller
+
+pci:v000010DEd00000752*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] SMBus
+
+pci:v000010DEd00000752sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000752sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000752sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000752sv00001849sd00000752*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 SMBus
+
+pci:v000010DEd00000753*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] Co-Processor
+
+pci:v000010DEd00000753sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000753sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000753sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000753sv00001849sd00000753*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Co-Processor
+
+pci:v000010DEd00000754*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller
+
+pci:v000010DEd00000754sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000754sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000754sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000754sv00001849sd00000754*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller
+
+pci:v000010DEd00000759*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] IDE
+
+pci:v000010DEd00000759sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000759sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000759sv00001849sd00000759*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 IDE
+
+pci:v000010DEd0000075A*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge
+
+pci:v000010DEd0000075Asv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd0000075Asv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd0000075Asv00001849sd0000075A*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Bridge
+
+pci:v000010DEd0000075B*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge
+
+pci:v000010DEd0000075Bsv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd0000075Bsv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd0000075Bsv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd0000075Bsv00001849sd0000075B*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge
+
+pci:v000010DEd0000075C*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge
+
+pci:v000010DEd0000075Csv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd0000075Csv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd0000075Csv00001849sd0000075C*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 LPC Bridge
+
+pci:v000010DEd0000075D*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge
+
+pci:v000010DEd0000075Dsv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000760*
+ ID_PRODUCT_FROM_DATABASE=MCP77 Ethernet
+
+pci:v000010DEd00000760sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000760sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000760sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000760sv00001849sd00000760*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Ethernet
+
+pci:v000010DEd00000761*
+ ID_PRODUCT_FROM_DATABASE=MCP77 Ethernet
+
+pci:v000010DEd00000762*
+ ID_PRODUCT_FROM_DATABASE=MCP77 Ethernet
+
+pci:v000010DEd00000763*
+ ID_PRODUCT_FROM_DATABASE=MCP77 Ethernet
+
+pci:v000010DEd00000774*
+ ID_PRODUCT_FROM_DATABASE=MCP72XE/MCP72P/MCP78U/MCP78S High Definition Audio
+
+pci:v000010DEd00000774sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000774sv00001043sd000082FE*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000774sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000774sv00001849sd00003662*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 High Definition Audio
+
+pci:v000010DEd00000778*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge
+
+pci:v000010DEd00000778sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000778sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000778sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000778sv00001849sd00000778*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge
+
+pci:v000010DEd0000077A*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge
+
+pci:v000010DEd0000077Asv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd0000077Asv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd0000077Asv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd0000077Asv00001849sd0000077A*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Bridge
+
+pci:v000010DEd0000077B*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller
+
+pci:v000010DEd0000077Bsv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd0000077Bsv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd0000077Bsv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd0000077Bsv00001849sd0000077B*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 OHCI USB 1.1 Controller
+
+pci:v000010DEd0000077C*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller
+
+pci:v000010DEd0000077Csv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd0000077Csv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd0000077Csv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd0000077Csv00001849sd0000077C*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 EHCI USB 2.0 Controller
+
+pci:v000010DEd0000077D*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller
+
+pci:v000010DEd0000077Dsv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd0000077Dsv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd0000077Dsv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd0000077Dsv00001849sd0000077D*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 OHCI USB 1.1 Controller
+
+pci:v000010DEd0000077E*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller
+
+pci:v000010DEd0000077Esv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd0000077Esv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd0000077Esv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd0000077Esv00001849sd0000077E*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 EHCI USB 2.0 Controller
+
+pci:v000010DEd000007C0*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Host Bridge
+
+pci:v000010DEd000007C0sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007C1*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Host Bridge
+
+pci:v000010DEd000007C1sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007C2*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Host Bridge
+
+pci:v000010DEd000007C5*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Host Bridge
+
+pci:v000010DEd000007C8*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Memory Controller
+
+pci:v000010DEd000007C8sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007C8sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007CB*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007CBsv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007CBsv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007CD*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007CDsv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007CDsv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007CE*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007CEsv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007CEsv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007CF*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007CFsv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007CFsv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007D0*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007D0sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007D0sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007D1*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007D1sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007D1sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007D2*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007D2sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007D2sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007D3*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007D3sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007D3sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007D6*
+ ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller
+
+pci:v000010DEd000007D6sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007D6sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007D7*
+ ID_PRODUCT_FROM_DATABASE=MCP73 LPC Bridge
+
+pci:v000010DEd000007D7sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007D7sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007D8*
+ ID_PRODUCT_FROM_DATABASE=MCP73 SMBus
+
+pci:v000010DEd000007D8sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007D8sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007D9*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Memory Controller
+
+pci:v000010DEd000007D9sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007D9sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007DA*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Co-processor
+
+pci:v000010DEd000007DAsv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007DC*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Ethernet
+
+pci:v000010DEd000007DD*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Ethernet
+
+pci:v000010DEd000007DE*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Ethernet
+
+pci:v000010DEd000007DF*
+ ID_PRODUCT_FROM_DATABASE=MCP73 Ethernet
+
+pci:v000010DEd000007E0*
+ ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7150 / nForce 630i]
+
+pci:v000010DEd000007E0sv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd000007E1*
+ ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7100 / nForce 630i]
+
+pci:v000010DEd000007E1sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007E2*
+ ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7050 / nForce 630i]
+
+pci:v000010DEd000007E3*
+ ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7050 / nForce 610i]
+
+pci:v000010DEd000007E5*
+ ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7100 / nForce 620i]
+
+pci:v000010DEd000007F0*
+ ID_PRODUCT_FROM_DATABASE=MCP73 IDE
+
+pci:v000010DEd000007F4*
+ ID_PRODUCT_FROM_DATABASE=GeForce 7100/nForce 630i SATA
+
+pci:v000010DEd000007F4sv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007F8*
+ ID_PRODUCT_FROM_DATABASE=MCP73 SATA RAID Controller
+
+pci:v000010DEd000007FC*
+ ID_PRODUCT_FROM_DATABASE=MCP73 High Definition Audio
+
+pci:v000010DEd000007FCsv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007FCsv000010DEsd000007FC*
+ ID_PRODUCT_FROM_DATABASE=MCP73 High Definition Audio
+
+pci:v000010DEd000007FE*
+ ID_PRODUCT_FROM_DATABASE=GeForce 7100/nForce 630i USB
+
+pci:v000010DEd000007FEsv00001019sd0000297A*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010DEd000007FEsv00001AFAsd00007150*
+ ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD
+
+pci:v000010DEd00000844*
+ ID_PRODUCT_FROM_DATABASE=C77 [GeForce 9100M G]
+
+pci:v000010DEd00000845*
+ ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8200M G]
+
+pci:v000010DEd00000846*
+ ID_PRODUCT_FROM_DATABASE=C77 [GeForce 9200]
+
+pci:v000010DEd00000847*
+ ID_PRODUCT_FROM_DATABASE=C78 [GeForce 9100]
+
+pci:v000010DEd00000847sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000848*
+ ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8300]
+
+pci:v000010DEd00000849*
+ ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8200]
+
+pci:v000010DEd00000849sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000849sv00001849sd00000849*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 GeForce 8200
+
+pci:v000010DEd0000084A*
+ ID_PRODUCT_FROM_DATABASE=C77 [nForce 730a]
+
+pci:v000010DEd0000084B*
+ ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8200]
+
+pci:v000010DEd0000084C*
+ ID_PRODUCT_FROM_DATABASE=C77 [nForce 780a SLI]
+
+pci:v000010DEd0000084D*
+ ID_PRODUCT_FROM_DATABASE=C77 [nForce 750a SLI]
+
+pci:v000010DEd0000084Dsv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D mGPU
+
+pci:v000010DEd0000084F*
+ ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8100 / nForce 720a]
+
+pci:v000010DEd00000860*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9300]
+
+pci:v000010DEd00000861*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400]
+
+pci:v000010DEd00000862*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400M G]
+
+pci:v000010DEd00000863*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400M]
+
+pci:v000010DEd00000864*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9300]
+
+pci:v000010DEd00000865*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9300]
+
+pci:v000010DEd00000866*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400M G]
+
+pci:v000010DEd00000867*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400]
+
+pci:v000010DEd00000868*
+ ID_PRODUCT_FROM_DATABASE=C79 [nForce 760i SLI]
+
+pci:v000010DEd0000086A*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400]
+
+pci:v000010DEd0000086C*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9300 / nForce 730i]
+
+pci:v000010DEd0000086D*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9200]
+
+pci:v000010DEd0000086E*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9100M G]
+
+pci:v000010DEd0000086F*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9200M G]
+
+pci:v000010DEd00000870*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400M]
+
+pci:v000010DEd00000871*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9200]
+
+pci:v000010DEd00000872*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce G102M]
+
+pci:v000010DEd00000873*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce G102M]
+
+pci:v000010DEd00000874*
+ ID_PRODUCT_FROM_DATABASE=C79 [ION]
+
+pci:v000010DEd00000876*
+ ID_PRODUCT_FROM_DATABASE=ION VGA [GeForce 9400M]
+
+pci:v000010DEd0000087A*
+ ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400]
+
+pci:v000010DEd0000087D*
+ ID_PRODUCT_FROM_DATABASE=ION VGA
+
+pci:v000010DEd0000087Dsv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd0000087E*
+ ID_PRODUCT_FROM_DATABASE=ION LE VGA
+
+pci:v000010DEd0000087F*
+ ID_PRODUCT_FROM_DATABASE=ION LE VGA
+
+pci:v000010DEd000008A3*
+ ID_PRODUCT_FROM_DATABASE=MCP89 [GeForce 320M]
+
+pci:v000010DEd000008A4*
+ ID_PRODUCT_FROM_DATABASE=MCP89 [GeForce 320M]
+
+pci:v000010DEd00000A20*
+ ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 220]
+
+pci:v000010DEd00000A20sv00001043sd00008311*
+ ID_PRODUCT_FROM_DATABASE=ENGT220/DI/1GD3(LP)/V2
+
+pci:v000010DEd00000A23*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 210]
+
+pci:v000010DEd00000A28*
+ ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 230M]
+
+pci:v000010DEd00000A29*
+ ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 330M]
+
+pci:v000010DEd00000A2A*
+ ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 230M]
+
+pci:v000010DEd00000A2B*
+ ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 330M]
+
+pci:v000010DEd00000A2C*
+ ID_PRODUCT_FROM_DATABASE=GT216 [NVS 5100M]
+
+pci:v000010DEd00000A2D*
+ ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 320M]
+
+pci:v000010DEd00000A34*
+ ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 240M]
+
+pci:v000010DEd00000A35*
+ ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 325M]
+
+pci:v000010DEd00000A38*
+ ID_PRODUCT_FROM_DATABASE=GT216GL [Quadro 400]
+
+pci:v000010DEd00000A3C*
+ ID_PRODUCT_FROM_DATABASE=GT216 [Quadro FX 880M]
+
+pci:v000010DEd00000A60*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce G210]
+
+pci:v000010DEd00000A62*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 205]
+
+pci:v000010DEd00000A63*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310]
+
+pci:v000010DEd00000A64*
+ ID_PRODUCT_FROM_DATABASE=GT218 [ION]
+
+pci:v000010DEd00000A65*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 210]
+
+pci:v000010DEd00000A65sv00001043sd00008334*
+ ID_PRODUCT_FROM_DATABASE=EN210 SILENT
+
+pci:v000010DEd00000A66*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310]
+
+pci:v000010DEd00000A67*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 315]
+
+pci:v000010DEd00000A68*
+ ID_PRODUCT_FROM_DATABASE=G98M [GeForce G105M]
+
+pci:v000010DEd00000A69*
+ ID_PRODUCT_FROM_DATABASE=G98M [GeForce G105M]
+
+pci:v000010DEd00000A6A*
+ ID_PRODUCT_FROM_DATABASE=GT218 [NVS 2100M]
+
+pci:v000010DEd00000A6C*
+ ID_PRODUCT_FROM_DATABASE=GT218 [NVS 3100M]
+
+pci:v000010DEd00000A6Csv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v000010DEd00000A6Csv000017AAsd00002142*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T410
+
+pci:v000010DEd00000A6E*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 305M]
+
+pci:v000010DEd00000A6F*
+ ID_PRODUCT_FROM_DATABASE=GT218 [ION]
+
+pci:v000010DEd00000A70*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310M]
+
+pci:v000010DEd00000A71*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 305M]
+
+pci:v000010DEd00000A72*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310M]
+
+pci:v000010DEd00000A73*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 305M]
+
+pci:v000010DEd00000A74*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce G210M]
+
+pci:v000010DEd00000A75*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310M]
+
+pci:v000010DEd00000A76*
+ ID_PRODUCT_FROM_DATABASE=GT218 [ION 2]
+
+pci:v000010DEd00000A78*
+ ID_PRODUCT_FROM_DATABASE=GT218GL [Quadro FX 380 LP]
+
+pci:v000010DEd00000A7C*
+ ID_PRODUCT_FROM_DATABASE=GT218 [Quadro FX 380M]
+
+pci:v000010DEd00000A80*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge
+
+pci:v000010DEd00000A81*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge
+
+pci:v000010DEd00000A82*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge
+
+pci:v000010DEd00000A83*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge
+
+pci:v000010DEd00000A84*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge
+
+pci:v000010DEd00000A85*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge
+
+pci:v000010DEd00000A86*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge
+
+pci:v000010DEd00000A87*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge
+
+pci:v000010DEd00000A88*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Memory Controller
+
+pci:v000010DEd00000A89*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Memory Controller
+
+pci:v000010DEd00000AA0*
+ ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge
+
+pci:v000010DEd00000AA2*
+ ID_PRODUCT_FROM_DATABASE=MCP79 SMBus
+
+pci:v000010DEd00000AA2sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AA3*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Co-processor
+
+pci:v000010DEd00000AA3sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AA4*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Memory Controller
+
+pci:v000010DEd00000AA4sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AA5*
+ ID_PRODUCT_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller
+
+pci:v000010DEd00000AA5sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AA6*
+ ID_PRODUCT_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller
+
+pci:v000010DEd00000AA6sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AA7*
+ ID_PRODUCT_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller
+
+pci:v000010DEd00000AA7sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AA8*
+ ID_PRODUCT_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller
+
+pci:v000010DEd00000AA9*
+ ID_PRODUCT_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller
+
+pci:v000010DEd00000AA9sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AAA*
+ ID_PRODUCT_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller
+
+pci:v000010DEd00000AAB*
+ ID_PRODUCT_FROM_DATABASE=MCP79 PCI Bridge
+
+pci:v000010DEd00000AAC*
+ ID_PRODUCT_FROM_DATABASE=MCP79 LPC Bridge
+
+pci:v000010DEd00000AAD*
+ ID_PRODUCT_FROM_DATABASE=MCP79 LPC Bridge
+
+pci:v000010DEd00000AADsv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AAE*
+ ID_PRODUCT_FROM_DATABASE=MCP79 LPC Bridge
+
+pci:v000010DEd00000AAF*
+ ID_PRODUCT_FROM_DATABASE=MCP79 LPC Bridge
+
+pci:v000010DEd00000AB0*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Ethernet
+
+pci:v000010DEd00000AB0sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AB1*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Ethernet
+
+pci:v000010DEd00000AB2*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Ethernet
+
+pci:v000010DEd00000AB3*
+ ID_PRODUCT_FROM_DATABASE=MCP79 Ethernet
+
+pci:v000010DEd00000AB4*
+ ID_PRODUCT_FROM_DATABASE=MCP79 SATA Controller
+
+pci:v000010DEd00000AB4sv000019DAsd0000A123*
+ ID_PRODUCT_FROM_DATABASE=IONITX-F-E
+
+pci:v000010DEd00000AB5*
+ ID_PRODUCT_FROM_DATABASE=MCP79 SATA Controller
+
+pci:v000010DEd00000AB6*
+ ID_PRODUCT_FROM_DATABASE=MCP79 SATA Controller
+
+pci:v000010DEd00000AB7*
+ ID_PRODUCT_FROM_DATABASE=MCP79 SATA Controller
+
+pci:v000010DEd00000AB8*
+ ID_PRODUCT_FROM_DATABASE=MCP79 AHCI Controller
+
+pci:v000010DEd00000AB9*
+ ID_PRODUCT_FROM_DATABASE=MCP79 AHCI Controller
+
+pci:v000010DEd00000ABA*
+ ID_PRODUCT_FROM_DATABASE=MCP79 AHCI Controller
+
+pci:v000010DEd00000ABB*
+ ID_PRODUCT_FROM_DATABASE=MCP79 AHCI Controller
+
+pci:v000010DEd00000ABC*
+ ID_PRODUCT_FROM_DATABASE=MCP79 RAID Controller
+
+pci:v000010DEd00000ABD*
+ ID_PRODUCT_FROM_DATABASE=MCP79 RAID Controller
+
+pci:v000010DEd00000ABE*
+ ID_PRODUCT_FROM_DATABASE=MCP79 RAID Controller
+
+pci:v000010DEd00000ABF*
+ ID_PRODUCT_FROM_DATABASE=MCP79 RAID Controller
+
+pci:v000010DEd00000AC0*
+ ID_PRODUCT_FROM_DATABASE=MCP79 High Definition Audio
+
+pci:v000010DEd00000AC1*
+ ID_PRODUCT_FROM_DATABASE=MCP79 High Definition Audio
+
+pci:v000010DEd00000AC2*
+ ID_PRODUCT_FROM_DATABASE=MCP79 High Definition Audio
+
+pci:v000010DEd00000AC3*
+ ID_PRODUCT_FROM_DATABASE=MCP79 High Definition Audio
+
+pci:v000010DEd00000AC4*
+ ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge
+
+pci:v000010DEd00000AC5*
+ ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge
+
+pci:v000010DEd00000AC6*
+ ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge
+
+pci:v000010DEd00000AC7*
+ ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge
+
+pci:v000010DEd00000AC8*
+ ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge
+
+pci:v000010DEd00000AD0*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] SATA Controller (non-AHCI mode)
+
+pci:v000010DEd00000AD0sv00001462sd00007508*
+ ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH
+
+pci:v000010DEd00000AD0sv00001849sd00000AD0*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 IDE
+
+pci:v000010DEd00000AD4*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] AHCI Controller
+
+pci:v000010DEd00000AD4sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000010DEd00000AD4sv00001043sd000082E8*
+ ID_PRODUCT_FROM_DATABASE=M3N72-D
+
+pci:v000010DEd00000AD4sv00001849sd00000AD4*
+ ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 AHCI Controller
+
+pci:v000010DEd00000AD8*
+ ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] SATA Controller (RAID mode)
+
+pci:v000010DEd00000BE2*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio Controller
+
+pci:v000010DEd00000BE2sv00001043sd00008311*
+ ID_PRODUCT_FROM_DATABASE=ENGT220/DI/1GD3(LP)/V2
+
+pci:v000010DEd00000BE3*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio Controller
+
+pci:v000010DEd00000BE3sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v000010DEd00000BE3sv000010DEsd0000066D*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8400GS]
+
+pci:v000010DEd00000BE4*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio Controller
+
+pci:v000010DEd00000BE5*
+ ID_PRODUCT_FROM_DATABASE=GF100 High Definition Audio Controller
+
+pci:v000010DEd00000BE9*
+ ID_PRODUCT_FROM_DATABASE=GF106 High Definition Audio Controller
+
+pci:v000010DEd00000BE9sv00001558sd00008687*
+ ID_PRODUCT_FROM_DATABASE=CLEVO/KAPOK W860CU
+
+pci:v000010DEd00000BEA*
+ ID_PRODUCT_FROM_DATABASE=GF108 High Definition Audio Controller
+
+pci:v000010DEd00000BEAsv00003842sd00001430*
+ ID_PRODUCT_FROM_DATABASE=GeForce GT 430
+
+pci:v000010DEd00000BEB*
+ ID_PRODUCT_FROM_DATABASE=GF104 High Definition Audio Controller
+
+pci:v000010DEd00000BEBsv00001462sd00002322*
+ ID_PRODUCT_FROM_DATABASE=N460GTX Cyclone 1GD5/OC
+
+pci:v000010DEd00000BEE*
+ ID_PRODUCT_FROM_DATABASE=GF116 High Definition Audio Controller
+
+pci:v000010DEd00000CA0*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 330]
+
+pci:v000010DEd00000CA2*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 320]
+
+pci:v000010DEd00000CA3*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 240]
+
+pci:v000010DEd00000CA4*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 340]
+
+pci:v000010DEd00000CA5*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 220]
+
+pci:v000010DEd00000CA7*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 330]
+
+pci:v000010DEd00000CA8*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GTS 260M]
+
+pci:v000010DEd00000CA9*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GTS 250M]
+
+pci:v000010DEd00000CAC*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 220]
+
+pci:v000010DEd00000CAF*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 335M]
+
+pci:v000010DEd00000CB0*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GTS 350M]
+
+pci:v000010DEd00000CB1*
+ ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GTS 360M]
+
+pci:v000010DEd00000CBC*
+ ID_PRODUCT_FROM_DATABASE=GT215 [Quadro FX 1800M]
+
+pci:v000010DEd00000D60*
+ ID_PRODUCT_FROM_DATABASE=MCP89 HOST Bridge
+
+pci:v000010DEd00000D68*
+ ID_PRODUCT_FROM_DATABASE=MCP89 Memory Controller
+
+pci:v000010DEd00000D69*
+ ID_PRODUCT_FROM_DATABASE=MCP89 Memory Controller
+
+pci:v000010DEd00000D76*
+ ID_PRODUCT_FROM_DATABASE=MCP89 PCI Express Bridge
+
+pci:v000010DEd00000D79*
+ ID_PRODUCT_FROM_DATABASE=MCP89 SMBus
+
+pci:v000010DEd00000D7A*
+ ID_PRODUCT_FROM_DATABASE=MCP89 Co-Processor
+
+pci:v000010DEd00000D7B*
+ ID_PRODUCT_FROM_DATABASE=MCP89 Memory Controller
+
+pci:v000010DEd00000D7D*
+ ID_PRODUCT_FROM_DATABASE=MCP89 Ethernet
+
+pci:v000010DEd00000D80*
+ ID_PRODUCT_FROM_DATABASE=MCP89 LPC Bridge
+
+pci:v000010DEd00000D85*
+ ID_PRODUCT_FROM_DATABASE=MCP89 SATA Controller
+
+pci:v000010DEd00000D88*
+ ID_PRODUCT_FROM_DATABASE=MCP89 SATA Controller (AHCI mode)
+
+pci:v000010DEd00000D89*
+ ID_PRODUCT_FROM_DATABASE=MCP89 SATA Controller (AHCI mode)
+
+pci:v000010DEd00000D8D*
+ ID_PRODUCT_FROM_DATABASE=MCP89 SATA Controller (RAID mode)
+
+pci:v000010DEd00000D94*
+ ID_PRODUCT_FROM_DATABASE=MCP89 High Definition Audio
+
+pci:v000010DEd00000D9C*
+ ID_PRODUCT_FROM_DATABASE=MCP89 OHCI USB 1.1 Controller
+
+pci:v000010DEd00000D9D*
+ ID_PRODUCT_FROM_DATABASE=MCP89 EHCI USB 2.0 Controller
+
+pci:v000010DEd00000DC0*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 440]
+
+pci:v000010DEd00000DC4*
+ ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GTS 450]
+
+pci:v000010DEd00000DC5*
+ ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GTS 450]
+
+pci:v000010DEd00000DC6*
+ ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GTS 450]
+
+pci:v000010DEd00000DCD*
+ ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GT 555M]
+
+pci:v000010DEd00000DCE*
+ ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GT 555M]
+
+pci:v000010DEd00000DD1*
+ ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GTX 460M]
+
+pci:v000010DEd00000DD1sv00001558sd00008687*
+ ID_PRODUCT_FROM_DATABASE=CLEVO/KAPOK W860CU
+
+pci:v000010DEd00000DD2*
+ ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GT 445M]
+
+pci:v000010DEd00000DD8*
+ ID_PRODUCT_FROM_DATABASE=GF106GL [Quadro 2000]
+
+pci:v000010DEd00000DDA*
+ ID_PRODUCT_FROM_DATABASE=GF106GLM [Quadro 2000M]
+
+pci:v000010DEd00000DE0*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 440]
+
+pci:v000010DEd00000DE1*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 430]
+
+pci:v000010DEd00000DE1sv00003842sd00001430*
+ ID_PRODUCT_FROM_DATABASE=GeForce GT 430
+
+pci:v000010DEd00000DE2*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 420]
+
+pci:v000010DEd00000DE4*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 520]
+
+pci:v000010DEd00000DE5*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 530]
+
+pci:v000010DEd00000DE9*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 630M]
+
+pci:v000010DEd00000DEB*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 555M]
+
+pci:v000010DEd00000DEE*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 415M]
+
+pci:v000010DEd00000DEF*
+ ID_PRODUCT_FROM_DATABASE=GF108 [Quadro NVS 5400M]
+
+pci:v000010DEd00000DF0*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 425M]
+
+pci:v000010DEd00000DF2*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 435M]
+
+pci:v000010DEd00000DF4*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 540M]
+
+pci:v000010DEd00000DF5*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 540M]
+
+pci:v000010DEd00000DF7*
+ ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 520M]
+
+pci:v000010DEd00000DF8*
+ ID_PRODUCT_FROM_DATABASE=GF108GL [Quadro 600]
+
+pci:v000010DEd00000DF9*
+ ID_PRODUCT_FROM_DATABASE=GF108GLM [Quadro 500M]
+
+pci:v000010DEd00000DFA*
+ ID_PRODUCT_FROM_DATABASE=GF108GLM [Quadro 1000M]
+
+pci:v000010DEd00000E08*
+ ID_PRODUCT_FROM_DATABASE=GF119 HDMI Audio Controller
+
+pci:v000010DEd00000E09*
+ ID_PRODUCT_FROM_DATABASE=GF110 High Definition Audio Controller
+
+pci:v000010DEd00000E0A*
+ ID_PRODUCT_FROM_DATABASE=GK104 HDMI Audio Controller
+
+pci:v000010DEd00000E0C*
+ ID_PRODUCT_FROM_DATABASE=GF114 HDMI Audio Controller
+
+pci:v000010DEd00000E1B*
+ ID_PRODUCT_FROM_DATABASE=GK107 HDMI Audio Controller
+
+pci:v000010DEd00000E1Bsv00001043sd00008428*
+ ID_PRODUCT_FROM_DATABASE=GTX650-DC-1GD5
+
+pci:v000010DEd00000E22*
+ ID_PRODUCT_FROM_DATABASE=GF104 [GeForce GTX 460]
+
+pci:v000010DEd00000E22sv00001462sd00002322*
+ ID_PRODUCT_FROM_DATABASE=N460GTX Cyclone 1GD5/OC
+
+pci:v000010DEd00000E23*
+ ID_PRODUCT_FROM_DATABASE=GF104 [GeForce GTX 460 SE]
+
+pci:v000010DEd00000E24*
+ ID_PRODUCT_FROM_DATABASE=GF104 [GeForce GTX 460]
+
+pci:v000010DEd00000E3A*
+ ID_PRODUCT_FROM_DATABASE=GF104 [Quadro 3000M]
+
+pci:v000010DEd00000E3B*
+ ID_PRODUCT_FROM_DATABASE=GF104 [Quadro 4000M]
+
+pci:v000010DEd00000F00*
+ ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 630]
+
+pci:v000010DEd00000F01*
+ ID_PRODUCT_FROM_DATABASE=GeForce GT 620
+
+pci:v000010DEd00000FC0*
+ ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 640]
+
+pci:v000010DEd00000FC1*
+ ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 640]
+
+pci:v000010DEd00000FC6*
+ ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GTX 650]
+
+pci:v000010DEd00000FC6sv00001043sd00008428*
+ ID_PRODUCT_FROM_DATABASE=GTX650-DC-1GD5
+
+pci:v000010DEd00000FD1*
+ ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 650M]
+
+pci:v000010DEd00000FD1sv00001043sd00002103*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v000010DEd00000FD2*
+ ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 640M]
+
+pci:v000010DEd00000FF2*
+ ID_PRODUCT_FROM_DATABASE=GK107 [VGX K1]
+
+pci:v000010DEd00000FFA*
+ ID_PRODUCT_FROM_DATABASE=GK107 [Quadro K600]
+
+pci:v000010DEd00000FFB*
+ ID_PRODUCT_FROM_DATABASE=GK107 [Quadro K2000M]
+
+pci:v000010DEd00000FFC*
+ ID_PRODUCT_FROM_DATABASE=GK107 [Quadro K1000M]
+
+pci:v000010DEd00000FFE*
+ ID_PRODUCT_FROM_DATABASE=GK107 [Quadro K2000]
+
+pci:v000010DEd00000FFF*
+ ID_PRODUCT_FROM_DATABASE=GK107 [Quadro 410]
+
+pci:v000010DEd00001040*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 520]
+
+pci:v000010DEd00001042*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce 510]
+
+pci:v000010DEd00001048*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce 605]
+
+pci:v000010DEd00001049*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 620]
+
+pci:v000010DEd0000104A*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 610]
+
+pci:v000010DEd00001050*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 520M]
+
+pci:v000010DEd00001051*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 520MX]
+
+pci:v000010DEd00001055*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce 410M]
+
+pci:v000010DEd00001056*
+ ID_PRODUCT_FROM_DATABASE=GF119 [Quadro NVS 4200M]
+
+pci:v000010DEd00001057*
+ ID_PRODUCT_FROM_DATABASE=GF119 [Quadro NVS 4200M]
+
+pci:v000010DEd0000105A*
+ ID_PRODUCT_FROM_DATABASE=GF119 [GeForce 610M]
+
+pci:v000010DEd0000107D*
+ ID_PRODUCT_FROM_DATABASE=GF119 [Quadro NVS 310]
+
+pci:v000010DEd00001080*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 580]
+
+pci:v000010DEd00001081*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 570]
+
+pci:v000010DEd00001081sv000010DEsd0000087E*
+ ID_PRODUCT_FROM_DATABASE=Leadtek WinFast GTX 570
+
+pci:v000010DEd00001082*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 560 Ti]
+
+pci:v000010DEd00001084*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 560]
+
+pci:v000010DEd00001086*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 570 HD]
+
+pci:v000010DEd00001087*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 560 Ti 448 Cores]
+
+pci:v000010DEd00001088*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 590]
+
+pci:v000010DEd00001089*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 580]
+
+pci:v000010DEd0000108B*
+ ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 580]
+
+pci:v000010DEd00001091*
+ ID_PRODUCT_FROM_DATABASE=Tesla M2090
+
+pci:v000010DEd00001094*
+ ID_PRODUCT_FROM_DATABASE=Tesla M2075 Dual-Slot Computing Processor Module
+
+pci:v000010DEd00001096*
+ ID_PRODUCT_FROM_DATABASE=Tesla C2075
+
+pci:v000010DEd0000109B*
+ ID_PRODUCT_FROM_DATABASE=GF100GL [Quadro 7000]
+
+pci:v000010DEd000010C3*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 8400 GS]
+
+pci:v000010DEd000010C3sv000010DEsd0000066D*
+ ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8400GS]
+
+pci:v000010DEd000010C5*
+ ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 405]
+
+pci:v000010DEd000010D8*
+ ID_PRODUCT_FROM_DATABASE=GT218 [Quadro NVS 300]
+
+pci:v000010DEd00001180*
+ ID_PRODUCT_FROM_DATABASE=GK104 [GeForce GTX 680]
+
+pci:v000010DEd00001183*
+ ID_PRODUCT_FROM_DATABASE=GK104 [GeForce GTX 660 Ti]
+
+pci:v000010DEd00001188*
+ ID_PRODUCT_FROM_DATABASE=GK104 [GeForce GTX 690]
+
+pci:v000010DEd00001189*
+ ID_PRODUCT_FROM_DATABASE=GK104 [GeForce GTX 670]
+
+pci:v000010DEd000011BA*
+ ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K5000]
+
+pci:v000010DEd000011BC*
+ ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K5000M]
+
+pci:v000010DEd000011BD*
+ ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K4000M]
+
+pci:v000010DEd000011BE*
+ ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K3000M]
+
+pci:v000010DEd000011BF*
+ ID_PRODUCT_FROM_DATABASE=GK104GL [VGX K2]
+
+pci:v000010DEd000011FA*
+ ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K4000]
+
+pci:v000010DEd00001200*
+ ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 560 Ti]
+
+pci:v000010DEd00001201*
+ ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 560]
+
+pci:v000010DEd00001205*
+ ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 460 v2]
+
+pci:v000010DEd00001206*
+ ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 555]
+
+pci:v000010DEd00001207*
+ ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 645]
+
+pci:v000010DEd00001208*
+ ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 560 SE]
+
+pci:v000010DEd00001210*
+ ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 570M]
+
+pci:v000010DEd00001241*
+ ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GT 545]
+
+pci:v000010DEd00001243*
+ ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GT 545]
+
+pci:v000010DEd00001244*
+ ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GTX 550 Ti]
+
+pci:v000010DEd00001245*
+ ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GTS 450]
+
+pci:v000010DEd00001247*
+ ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GT 555M]
+
+pci:v000010DEd00001249*
+ ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GTS 450]
+
+pci:v000010DEd0000124B*
+ ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GT 640]
+
+pci:v000010DF*
+ ID_VENDOR_FROM_DATABASE=Emulex Corporation
+
+pci:v000010DFd00000720*
+ ID_PRODUCT_FROM_DATABASE=OneConnect NIC (Skyhawk)
+
+pci:v000010DFd00000722*
+ ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator (Skyhawk)
+
+pci:v000010DFd00000723*
+ ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator + Target (Skyhawk)
+
+pci:v000010DFd00000724*
+ ID_PRODUCT_FROM_DATABASE=OneConnect FCoE Initiator (Skyhawk)
+
+pci:v000010DFd00000728*
+ ID_PRODUCT_FROM_DATABASE=OneConnect NIC (Skyhawk-VF)
+
+pci:v000010DFd0000072A*
+ ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator (Skyhawk-VF)
+
+pci:v000010DFd0000072B*
+ ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator + Target (Skyhawk-VF)
+
+pci:v000010DFd0000072C*
+ ID_PRODUCT_FROM_DATABASE=OneConnect FCoE Initiator (Skyhawk-VF)
+
+pci:v000010DFd00001AE5*
+ ID_PRODUCT_FROM_DATABASE=LP6000 Fibre Channel Host Adapter
+
+pci:v000010DFd0000E100*
+ ID_PRODUCT_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter
+
+pci:v000010DFd0000E131*
+ ID_PRODUCT_FROM_DATABASE=LightPulse 8Gb/s PCIe Shared I/O Fibre Channel Adapter
+
+pci:v000010DFd0000E180*
+ ID_PRODUCT_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter
+
+pci:v000010DFd0000E200*
+ ID_PRODUCT_FROM_DATABASE=Lancer-X: LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000E208*
+ ID_PRODUCT_FROM_DATABASE=LightPulse 16Gb Fibre Channel Host Adapter (Lancer-VF)
+
+pci:v000010DFd0000E220*
+ ID_PRODUCT_FROM_DATABASE=OneConnect NIC (Lancer)
+
+pci:v000010DFd0000E240*
+ ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator (Lancer)
+
+pci:v000010DFd0000E260*
+ ID_PRODUCT_FROM_DATABASE=OneConnect FCoE Initiator (Lancer)
+
+pci:v000010DFd0000E268*
+ ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb FCoE Converged Network Adapter (Lancer-VF)
+
+pci:v000010DFd0000F011*
+ ID_PRODUCT_FROM_DATABASE=Saturn: LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F015*
+ ID_PRODUCT_FROM_DATABASE=Saturn: LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F085*
+ ID_PRODUCT_FROM_DATABASE=LP850 Fibre Channel Host Adapter
+
+pci:v000010DFd0000F095*
+ ID_PRODUCT_FROM_DATABASE=LP952 Fibre Channel Host Adapter
+
+pci:v000010DFd0000F098*
+ ID_PRODUCT_FROM_DATABASE=LP982 Fibre Channel Host Adapter
+
+pci:v000010DFd0000F0A1*
+ ID_PRODUCT_FROM_DATABASE=Thor LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F0A5*
+ ID_PRODUCT_FROM_DATABASE=Thor LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F0B5*
+ ID_PRODUCT_FROM_DATABASE=Viper LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F0D1*
+ ID_PRODUCT_FROM_DATABASE=Helios LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F0D5*
+ ID_PRODUCT_FROM_DATABASE=Helios LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F0E1*
+ ID_PRODUCT_FROM_DATABASE=Zephyr LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F0E5*
+ ID_PRODUCT_FROM_DATABASE=Zephyr LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F0F5*
+ ID_PRODUCT_FROM_DATABASE=Neptune LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F100*
+ ID_PRODUCT_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F111*
+ ID_PRODUCT_FROM_DATABASE=Saturn-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F112*
+ ID_PRODUCT_FROM_DATABASE=Saturn-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000F180*
+ ID_PRODUCT_FROM_DATABASE=LPSe12002 EmulexSecure Fibre Channel Adapter
+
+pci:v000010DFd0000F700*
+ ID_PRODUCT_FROM_DATABASE=LP7000 Fibre Channel Host Adapter
+
+pci:v000010DFd0000F701*
+ ID_PRODUCT_FROM_DATABASE=LP7000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
+
+pci:v000010DFd0000F800*
+ ID_PRODUCT_FROM_DATABASE=LP8000 Fibre Channel Host Adapter
+
+pci:v000010DFd0000F801*
+ ID_PRODUCT_FROM_DATABASE=LP8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
+
+pci:v000010DFd0000F900*
+ ID_PRODUCT_FROM_DATABASE=LP9000 Fibre Channel Host Adapter
+
+pci:v000010DFd0000F901*
+ ID_PRODUCT_FROM_DATABASE=LP9000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
+
+pci:v000010DFd0000F980*
+ ID_PRODUCT_FROM_DATABASE=LP9802 Fibre Channel Host Adapter
+
+pci:v000010DFd0000F981*
+ ID_PRODUCT_FROM_DATABASE=LP9802 Fibre Channel Host Adapter Alternate ID
+
+pci:v000010DFd0000F982*
+ ID_PRODUCT_FROM_DATABASE=LP9802 Fibre Channel Host Adapter Alternate ID
+
+pci:v000010DFd0000FA00*
+ ID_PRODUCT_FROM_DATABASE=Thor-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FB00*
+ ID_PRODUCT_FROM_DATABASE=Viper LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FC00*
+ ID_PRODUCT_FROM_DATABASE=Thor-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FC00sv000010DFsd0000FC00*
+ ID_PRODUCT_FROM_DATABASE=LP10000 LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FC10*
+ ID_PRODUCT_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FC20*
+ ID_PRODUCT_FROM_DATABASE=Zephyr-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FC40*
+ ID_PRODUCT_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FC50*
+ ID_PRODUCT_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter
+
+pci:v000010DFd0000FD00*
+ ID_PRODUCT_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FD11*
+ ID_PRODUCT_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FD12*
+ ID_PRODUCT_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FE00*
+ ID_PRODUCT_FROM_DATABASE=Zephyr-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FE05*
+ ID_PRODUCT_FROM_DATABASE=Zephyr-X: LightPulse FCoE Adapter
+
+pci:v000010DFd0000FE11*
+ ID_PRODUCT_FROM_DATABASE=Zephyr-X LightPulse Fibre Channel Host Adapter
+
+pci:v000010DFd0000FE12*
+ ID_PRODUCT_FROM_DATABASE=Zephyr-X LightPulse FCoE Adapter
+
+pci:v000010DFd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Neptune LightPulse Fibre Channel Host Adapter
+
+pci:v000010E0*
+ ID_VENDOR_FROM_DATABASE=Integrated Micro Solutions Inc.
+
+pci:v000010E0d00005026*
+ ID_PRODUCT_FROM_DATABASE=IMS5026/27/28
+
+pci:v000010E0d00005027*
+ ID_PRODUCT_FROM_DATABASE=IMS5027
+
+pci:v000010E0d00005028*
+ ID_PRODUCT_FROM_DATABASE=IMS5028
+
+pci:v000010E0d00008849*
+ ID_PRODUCT_FROM_DATABASE=IMS8849
+
+pci:v000010E0d00008853*
+ ID_PRODUCT_FROM_DATABASE=IMS8853
+
+pci:v000010E0d00009128*
+ ID_PRODUCT_FROM_DATABASE=IMS9128 [Twin turbo 128]
+
+pci:v000010E1*
+ ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd.
+
+pci:v000010E1d00000391*
+ ID_PRODUCT_FROM_DATABASE=TRM-S1040
+
+pci:v000010E1d00000391sv000010E1sd00000391*
+ ID_PRODUCT_FROM_DATABASE=DC-315U SCSI-3 Host Adapter
+
+pci:v000010E1d0000690C*
+ ID_PRODUCT_FROM_DATABASE=DC-690c
+
+pci:v000010E1d0000DC29*
+ ID_PRODUCT_FROM_DATABASE=DC-290
+
+pci:v000010E2*
+ ID_VENDOR_FROM_DATABASE=Aptix Corporation
+
+pci:v000010E3*
+ ID_VENDOR_FROM_DATABASE=Tundra Semiconductor Corp.
+
+pci:v000010E3d00000000*
+ ID_PRODUCT_FROM_DATABASE=CA91C042 [Universe]
+
+pci:v000010E3d00000108*
+ ID_PRODUCT_FROM_DATABASE=Tsi108 Host Bridge for Single PowerPC
+
+pci:v000010E3d00000148*
+ ID_PRODUCT_FROM_DATABASE=Tsi148 [Tempe]
+
+pci:v000010E3d00000148sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=VR11 Single Board Computer
+
+pci:v000010E3d00000860*
+ ID_PRODUCT_FROM_DATABASE=CA91C860 [QSpan]
+
+pci:v000010E3d00000862*
+ ID_PRODUCT_FROM_DATABASE=CA91C862A [QSpan-II]
+
+pci:v000010E3d00008260*
+ ID_PRODUCT_FROM_DATABASE=CA91L8200B [Dual PCI PowerSpan II]
+
+pci:v000010E3d00008261*
+ ID_PRODUCT_FROM_DATABASE=CA91L8260B [Single PCI PowerSpan II]
+
+pci:v000010E3d0000A108*
+ ID_PRODUCT_FROM_DATABASE=Tsi109 Host Bridge for Dual PowerPC
+
+pci:v000010E4*
+ ID_VENDOR_FROM_DATABASE=Tandem Computers
+
+pci:v000010E4d00008029*
+ ID_PRODUCT_FROM_DATABASE=Realtek 8029 Network Card
+
+pci:v000010E5*
+ ID_VENDOR_FROM_DATABASE=Micro Industries Corporation
+
+pci:v000010E6*
+ ID_VENDOR_FROM_DATABASE=Gainbery Computer Products Inc.
+
+pci:v000010E7*
+ ID_VENDOR_FROM_DATABASE=Vadem
+
+pci:v000010E8*
+ ID_VENDOR_FROM_DATABASE=Applied Micro Circuits Corp.
+
+pci:v000010E8d00001072*
+ ID_PRODUCT_FROM_DATABASE=INES GPIB-PCI (AMCC5920 based)
+
+pci:v000010E8d00002011*
+ ID_PRODUCT_FROM_DATABASE=Q-Motion Video Capture/Edit board
+
+pci:v000010E8d00004750*
+ ID_PRODUCT_FROM_DATABASE=S5930 [Matchmaker]
+
+pci:v000010E8d00005920*
+ ID_PRODUCT_FROM_DATABASE=S5920
+
+pci:v000010E8d00008043*
+ ID_PRODUCT_FROM_DATABASE=LANai4.x [Myrinet LANai interface chip]
+
+pci:v000010E8d00008062*
+ ID_PRODUCT_FROM_DATABASE=S5933_PARASTATION
+
+pci:v000010E8d0000807D*
+ ID_PRODUCT_FROM_DATABASE=S5933 [Matchmaker]
+
+pci:v000010E8d00008088*
+ ID_PRODUCT_FROM_DATABASE=Kongsberg Spacetec Format Synchronizer
+
+pci:v000010E8d00008089*
+ ID_PRODUCT_FROM_DATABASE=Kongsberg Spacetec Serial Output Board
+
+pci:v000010E8d0000809C*
+ ID_PRODUCT_FROM_DATABASE=S5933_HEPC3
+
+pci:v000010E8d000080B9*
+ ID_PRODUCT_FROM_DATABASE=Harmonix Hi-Card P8 (4x active ISDN BRI)
+
+pci:v000010E8d000080D7*
+ ID_PRODUCT_FROM_DATABASE=PCI-9112
+
+pci:v000010E8d000080D8*
+ ID_PRODUCT_FROM_DATABASE=PCI-7200
+
+pci:v000010E8d000080D9*
+ ID_PRODUCT_FROM_DATABASE=PCI-9118
+
+pci:v000010E8d000080DA*
+ ID_PRODUCT_FROM_DATABASE=PCI-9812
+
+pci:v000010E8d000080FC*
+ ID_PRODUCT_FROM_DATABASE=APCI1500 Signal processing controller (16 dig. inputs + 16 dig. outputs)
+
+pci:v000010E8d0000811A*
+ ID_PRODUCT_FROM_DATABASE=PCI-IEEE1355-DS-DE Interface
+
+pci:v000010E8d0000814C*
+ ID_PRODUCT_FROM_DATABASE=Fastcom ESCC-PCI (Commtech, Inc.)
+
+pci:v000010E8d00008170*
+ ID_PRODUCT_FROM_DATABASE=S5933 [Matchmaker] (Chipset Development Tool)
+
+pci:v000010E8d000081E6*
+ ID_PRODUCT_FROM_DATABASE=Multimedia video controller
+
+pci:v000010E8d0000828D*
+ ID_PRODUCT_FROM_DATABASE=APCI3001 Signal processing controller (up to 16 analog inputs)
+
+pci:v000010E8d00008291*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 232/8-PCI (Commtech, Inc.)
+
+pci:v000010E8d000082C4*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 422/4-PCI (Commtech, Inc.)
+
+pci:v000010E8d000082C5*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 422/2-PCI (Commtech, Inc.)
+
+pci:v000010E8d000082C6*
+ ID_PRODUCT_FROM_DATABASE=Fastcom IG422/1-PCI (Commtech, Inc.)
+
+pci:v000010E8d000082C7*
+ ID_PRODUCT_FROM_DATABASE=Fastcom IG232/2-PCI (Commtech, Inc.)
+
+pci:v000010E8d000082CA*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 232/4-PCI (Commtech, Inc.)
+
+pci:v000010E8d000082DB*
+ ID_PRODUCT_FROM_DATABASE=AJA HDNTV HD SDI Framestore
+
+pci:v000010E8d000082E2*
+ ID_PRODUCT_FROM_DATABASE=Fastcom DIO24H-PCI (Commtech, Inc.)
+
+pci:v000010E8d00008406*
+ ID_PRODUCT_FROM_DATABASE=PCIcanx/PCIcan CAN interface [Kvaser AB]
+
+pci:v000010E8d00008407*
+ ID_PRODUCT_FROM_DATABASE=PCIcan II CAN interface (A1021, PCB-07, PCB-08) [Kvaser AB]
+
+pci:v000010E8d00008851*
+ ID_PRODUCT_FROM_DATABASE=S5933 on Innes Corp FM Radio Capture card
+
+pci:v000010E9*
+ ID_VENDOR_FROM_DATABASE=Alps Electric Co., Ltd.
+
+pci:v000010EA*
+ ID_VENDOR_FROM_DATABASE=Integraphics
+
+pci:v000010EAd00001680*
+ ID_PRODUCT_FROM_DATABASE=IGA-1680
+
+pci:v000010EAd00001682*
+ ID_PRODUCT_FROM_DATABASE=IGA-1682
+
+pci:v000010EAd00001683*
+ ID_PRODUCT_FROM_DATABASE=IGA-1683
+
+pci:v000010EAd00002000*
+ ID_PRODUCT_FROM_DATABASE=CyberPro 2000
+
+pci:v000010EAd00002010*
+ ID_PRODUCT_FROM_DATABASE=CyberPro 2000A
+
+pci:v000010EAd00005000*
+ ID_PRODUCT_FROM_DATABASE=CyberPro 5000
+
+pci:v000010EAd00005050*
+ ID_PRODUCT_FROM_DATABASE=CyberPro 5050
+
+pci:v000010EAd00005202*
+ ID_PRODUCT_FROM_DATABASE=CyberPro 5202
+
+pci:v000010EAd00005252*
+ ID_PRODUCT_FROM_DATABASE=CyberPro5252
+
+pci:v000010EB*
+ ID_VENDOR_FROM_DATABASE=Artists Graphics
+
+pci:v000010EBd00000101*
+ ID_PRODUCT_FROM_DATABASE=3GA
+
+pci:v000010EBd00008111*
+ ID_PRODUCT_FROM_DATABASE=Twist3 Frame Grabber
+
+pci:v000010EC*
+ ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Co., Ltd.
+
+pci:v000010ECd00000139*
+ ID_PRODUCT_FROM_DATABASE=Zonet Zen3200
+
+pci:v000010ECd00000260*
+ ID_PRODUCT_FROM_DATABASE=Realtek 260 High Definition Audio
+
+pci:v000010ECd00000261*
+ ID_PRODUCT_FROM_DATABASE=Realtek 261 High Definition Audio
+
+pci:v000010ECd00000262*
+ ID_PRODUCT_FROM_DATABASE=Realtek 262 High Definition Audio
+
+pci:v000010ECd00000269*
+ ID_PRODUCT_FROM_DATABASE=Realtek ALC269 High Definition Audio (82801G)
+
+pci:v000010ECd00000280*
+ ID_PRODUCT_FROM_DATABASE=Realtek 280 High Definition Audio
+
+pci:v000010ECd00000660*
+ ID_PRODUCT_FROM_DATABASE=Realtek 660 High Definition Audio
+
+pci:v000010ECd00000662*
+ ID_PRODUCT_FROM_DATABASE=Realtek 662 High Definition Audio
+
+pci:v000010ECd00000861*
+ ID_PRODUCT_FROM_DATABASE=Realtek 861 High Definition Audio
+
+pci:v000010ECd00000862*
+ ID_PRODUCT_FROM_DATABASE=Realtek 862 High Definition Audio
+
+pci:v000010ECd00000880*
+ ID_PRODUCT_FROM_DATABASE=Realtek 880 High Definition Audio
+
+pci:v000010ECd00000883*
+ ID_PRODUCT_FROM_DATABASE=Realtek 883 High Definition Audio
+
+pci:v000010ECd00000883sv00001025sd00001605*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 5600 series
+
+pci:v000010ECd00000885*
+ ID_PRODUCT_FROM_DATABASE=Realtek 885 High Definition Audio
+
+pci:v000010ECd00000888*
+ ID_PRODUCT_FROM_DATABASE=Realtek 888 High Definition Audio
+
+pci:v000010ECd00000888sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v000010ECd00000892*
+ ID_PRODUCT_FROM_DATABASE=Realtek 892 High Definition Audio
+
+pci:v000010ECd00005209*
+ ID_PRODUCT_FROM_DATABASE=RTS5209 PCI Express Card Reader
+
+pci:v000010ECd00005229*
+ ID_PRODUCT_FROM_DATABASE=RTS5229 PCI Express Card Reader
+
+pci:v000010ECd00005288*
+ ID_PRODUCT_FROM_DATABASE=Barossa PCI Express Card Reader
+
+pci:v000010ECd00008029*
+ ID_PRODUCT_FROM_DATABASE=RTL-8029(AS)
+
+pci:v000010ECd00008029sv000010B8sd00002011*
+ ID_PRODUCT_FROM_DATABASE=EZ-Card (SMC1208)
+
+pci:v000010ECd00008029sv000010ECsd00008029*
+ ID_PRODUCT_FROM_DATABASE=RTL-8029(AS)
+
+pci:v000010ECd00008029sv00001113sd00001208*
+ ID_PRODUCT_FROM_DATABASE=EN1208
+
+pci:v000010ECd00008029sv00001186sd00000300*
+ ID_PRODUCT_FROM_DATABASE=DE-528
+
+pci:v000010ECd00008029sv00001259sd00002400*
+ ID_PRODUCT_FROM_DATABASE=AT-2400
+
+pci:v000010ECd00008029sv00001AF4sd00001100*
+ ID_PRODUCT_FROM_DATABASE=Qemu virtual machine
+
+pci:v000010ECd00008129*
+ ID_PRODUCT_FROM_DATABASE=RTL-8129
+
+pci:v000010ECd00008129sv000010ECsd00008129*
+ ID_PRODUCT_FROM_DATABASE=RT8129 Fast Ethernet Adapter
+
+pci:v000010ECd00008129sv000011ECsd00008129*
+ ID_PRODUCT_FROM_DATABASE=RT8129 Fast Ethernet Adapter
+
+pci:v000010ECd00008136*
+ ID_PRODUCT_FROM_DATABASE=RTL8101E/RTL8102E PCI Express Fast Ethernet controller
+
+pci:v000010ECd00008136sv0000103Csd00002AB1*
+ ID_PRODUCT_FROM_DATABASE=Pavillion p6774
+
+pci:v000010ECd00008136sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v000010ECd00008136sv00001179sd0000FF64*
+ ID_PRODUCT_FROM_DATABASE=RTL8102E PCI-E Fast Ethernet NIC
+
+pci:v000010ECd00008138*
+ ID_PRODUCT_FROM_DATABASE=RT8139 (B/C) Cardbus Fast Ethernet Adapter
+
+pci:v000010ECd00008138sv000010ECsd00008138*
+ ID_PRODUCT_FROM_DATABASE=RT8139 (B/C) Fast Ethernet Adapter
+
+pci:v000010ECd00008139*
+ ID_PRODUCT_FROM_DATABASE=RTL-8139/8139C/8139C+
+
+pci:v000010ECd00008139sv00000357sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=TTP-Monitoring Card V2.0
+
+pci:v000010ECd00008139sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v000010ECd00008139sv00001025sd00008920*
+ ID_PRODUCT_FROM_DATABASE=ALN-325
+
+pci:v000010ECd00008139sv00001025sd00008921*
+ ID_PRODUCT_FROM_DATABASE=ALN-325
+
+pci:v000010ECd00008139sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v000010ECd00008139sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v000010ECd00008139sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v000010ECd00008139sv00001043sd00001045*
+ ID_PRODUCT_FROM_DATABASE=L8400B or L3C/S notebook
+
+pci:v000010ECd00008139sv00001043sd00008109*
+ ID_PRODUCT_FROM_DATABASE=P5P800-MX Mainboard
+
+pci:v000010ECd00008139sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v000010ECd00008139sv000010BDsd00000320*
+ ID_PRODUCT_FROM_DATABASE=EP-320X-R
+
+pci:v000010ECd00008139sv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop
+
+pci:v000010ECd00008139sv00001113sd0000EC01*
+ ID_PRODUCT_FROM_DATABASE=FNC-0107TX
+
+pci:v000010ECd00008139sv00001186sd00001300*
+ ID_PRODUCT_FROM_DATABASE=DFE-538TX
+
+pci:v000010ECd00008139sv00001186sd00001320*
+ ID_PRODUCT_FROM_DATABASE=SN5200
+
+pci:v000010ECd00008139sv00001186sd00008139*
+ ID_PRODUCT_FROM_DATABASE=DRN-32TX
+
+pci:v000010ECd00008139sv000011F6sd00008139*
+ ID_PRODUCT_FROM_DATABASE=FN22-3(A) LinxPRO Ethernet Adapter
+
+pci:v000010ECd00008139sv00001259sd00002500*
+ ID_PRODUCT_FROM_DATABASE=AT-2500TX
+
+pci:v000010ECd00008139sv00001259sd00002503*
+ ID_PRODUCT_FROM_DATABASE=AT-2500TX/ACPI
+
+pci:v000010ECd00008139sv00001385sd0000F31D*
+ ID_PRODUCT_FROM_DATABASE=FA311 v2
+
+pci:v000010ECd00008139sv00001395sd00002100*
+ ID_PRODUCT_FROM_DATABASE=AMB2100
+
+pci:v000010ECd00008139sv00001429sd0000D010*
+ ID_PRODUCT_FROM_DATABASE=ND010/ND012
+
+pci:v000010ECd00008139sv00001432sd00009130*
+ ID_PRODUCT_FROM_DATABASE=EN-9130TX
+
+pci:v000010ECd00008139sv00001436sd00008139*
+ ID_PRODUCT_FROM_DATABASE=RT8139
+
+pci:v000010ECd00008139sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v000010ECd00008139sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=GA-7VM400M/7VT600 Motherboard
+
+pci:v000010ECd00008139sv00001462sd00000131*
+ ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook
+
+pci:v000010ECd00008139sv00001462sd0000217C*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v000010ECd00008139sv00001462sd0000788C*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2-V Mainboard
+
+pci:v000010ECd00008139sv0000146Csd00001439*
+ ID_PRODUCT_FROM_DATABASE=FE-1439TX
+
+pci:v000010ECd00008139sv00001489sd00006001*
+ ID_PRODUCT_FROM_DATABASE=GF100TXRII
+
+pci:v000010ECd00008139sv00001489sd00006002*
+ ID_PRODUCT_FROM_DATABASE=GF100TXRA
+
+pci:v000010ECd00008139sv0000149Csd0000139A*
+ ID_PRODUCT_FROM_DATABASE=LFE-8139ATX
+
+pci:v000010ECd00008139sv0000149Csd00008139*
+ ID_PRODUCT_FROM_DATABASE=LFE-8139TX
+
+pci:v000010ECd00008139sv000014CBsd00000200*
+ ID_PRODUCT_FROM_DATABASE=LNR-100 Family 10/100 Base-TX Ethernet
+
+pci:v000010ECd00008139sv00001565sd00002300*
+ ID_PRODUCT_FROM_DATABASE=P4TSV Onboard LAN (RTL8100B)
+
+pci:v000010ECd00008139sv00001631sd00007003*
+ ID_PRODUCT_FROM_DATABASE=Onboard RTL8111 on GA-8SIML Rev1.0 Mainboard
+
+pci:v000010ECd00008139sv00001695sd00009001*
+ ID_PRODUCT_FROM_DATABASE=Onboard RTL8101L 10/100 MBit
+
+pci:v000010ECd00008139sv000016ECsd000000FF*
+ ID_PRODUCT_FROM_DATABASE=USR997900A
+
+pci:v000010ECd00008139sv00001799sd00005000*
+ ID_PRODUCT_FROM_DATABASE=F5D5000 PCI Card/Desktop Network PCI Card
+
+pci:v000010ECd00008139sv00001799sd00005010*
+ ID_PRODUCT_FROM_DATABASE=F5D5010 CardBus Notebook Network Card
+
+pci:v000010ECd00008139sv0000187Esd00003303*
+ ID_PRODUCT_FROM_DATABASE=FN312
+
+pci:v000010ECd00008139sv00001904sd00008139*
+ ID_PRODUCT_FROM_DATABASE=RTL8139D Fast Ethernet Adapter
+
+pci:v000010ECd00008139sv00002646sd00000001*
+ ID_PRODUCT_FROM_DATABASE=KNE120TX
+
+pci:v000010ECd00008139sv00008E2Esd00007000*
+ ID_PRODUCT_FROM_DATABASE=KF-230TX
+
+pci:v000010ECd00008139sv00008E2Esd00007100*
+ ID_PRODUCT_FROM_DATABASE=KF-230TX/2
+
+pci:v000010ECd00008139sv0000A0A0sd00000007*
+ ID_PRODUCT_FROM_DATABASE=ALN-325C
+
+pci:v000010ECd00008167*
+ ID_PRODUCT_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet
+
+pci:v000010ECd00008167sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=GA-MA69G-S3H Motherboard
+
+pci:v000010ECd00008167sv00001462sd0000235C*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v000010ECd00008167sv00001462sd0000236C*
+ ID_PRODUCT_FROM_DATABASE=945P Neo3-F motherboard
+
+pci:v000010ECd00008168*
+ ID_PRODUCT_FROM_DATABASE=RTL8111/8168B PCI Express Gigabit Ethernet controller
+
+pci:v000010ECd00008168sv00001019sd00008168*
+ ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM
+
+pci:v000010ECd00008168sv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v000010ECd00008168sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v000010ECd00008168sv0000103Csd00001611*
+ ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000
+
+pci:v000010ECd00008168sv00001043sd000011F5*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v000010ECd00008168sv00001043sd000016D5*
+ ID_PRODUCT_FROM_DATABASE=U6V/U31J laptop
+
+pci:v000010ECd00008168sv00001043sd000081AA*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v000010ECd00008168sv00001043sd000082C6*
+ ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard
+
+pci:v000010ECd00008168sv00001043sd000083A3*
+ ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard
+
+pci:v000010ECd00008168sv00001043sd00008432*
+ ID_PRODUCT_FROM_DATABASE=P8P67 and other motherboards
+
+pci:v000010ECd00008168sv000010ECsd00008168*
+ ID_PRODUCT_FROM_DATABASE=TEG-ECTX Gigabit PCI-E Adapter [Trendnet]
+
+pci:v000010ECd00008168sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v000010ECd00008168sv00001462sd0000238C*
+ ID_PRODUCT_FROM_DATABASE=Onboard RTL8111b on MSI P965 Platinum Mainboard
+
+pci:v000010ECd00008168sv00001462sd0000368C*
+ ID_PRODUCT_FROM_DATABASE=K9AG Neo2
+
+pci:v000010ECd00008168sv00001462sd00007522*
+ ID_PRODUCT_FROM_DATABASE=X58 Pro-E
+
+pci:v000010ECd00008168sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v000010ECd00008168sv00001849sd00008168*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v000010ECd00008168sv00008086sd0000D615*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D510MO
+
+pci:v000010ECd00008169*
+ ID_PRODUCT_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller
+
+pci:v000010ECd00008169sv00001025sd00000079*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi
+
+pci:v000010ECd00008169sv000010BDsd00003202*
+ ID_PRODUCT_FROM_DATABASE=EP-320G-TX1 32-bit PCI Gigabit Ethernet Adapter
+
+pci:v000010ECd00008169sv000010ECsd00008169*
+ ID_PRODUCT_FROM_DATABASE=RTL8169/8110 Family PCI Gigabit Ethernet NIC
+
+pci:v000010ECd00008169sv00001259sd0000C107*
+ ID_PRODUCT_FROM_DATABASE=CG-LAPCIGT
+
+pci:v000010ECd00008169sv00001371sd0000434E*
+ ID_PRODUCT_FROM_DATABASE=ProG-2000L
+
+pci:v000010ECd00008169sv00001385sd0000311A*
+ ID_PRODUCT_FROM_DATABASE=GA311
+
+pci:v000010ECd00008169sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v000010ECd00008169sv00001462sd0000030C*
+ ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 mainboard
+
+pci:v000010ECd00008169sv00001462sd0000065C*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v000010ECd00008169sv00001462sd0000702C*
+ ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard
+
+pci:v000010ECd00008169sv00001462sd00007094*
+ ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0
+
+pci:v000010ECd00008169sv000016ECsd0000011F*
+ ID_PRODUCT_FROM_DATABASE=USR997903
+
+pci:v000010ECd00008169sv00001734sd00001091*
+ ID_PRODUCT_FROM_DATABASE=D2030-A1
+
+pci:v000010ECd00008169sv0000A0A0sd00000449*
+ ID_PRODUCT_FROM_DATABASE=AK86-L motherboard
+
+pci:v000010ECd00008171*
+ ID_PRODUCT_FROM_DATABASE=RTL8191SEvA Wireless LAN Controller
+
+pci:v000010ECd00008172*
+ ID_PRODUCT_FROM_DATABASE=RTL8191SEvB Wireless LAN Controller
+
+pci:v000010ECd00008173*
+ ID_PRODUCT_FROM_DATABASE=RTL8192SE Wireless LAN Controller
+
+pci:v000010ECd00008174*
+ ID_PRODUCT_FROM_DATABASE=RTL8192SE Wireless LAN Controller
+
+pci:v000010ECd00008176*
+ ID_PRODUCT_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter
+
+pci:v000010ECd00008176sv00001A3Bsd00001139*
+ ID_PRODUCT_FROM_DATABASE=AW-NE139H Half-size Mini PCIe Card
+
+pci:v000010ECd00008177*
+ ID_PRODUCT_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter
+
+pci:v000010ECd00008178*
+ ID_PRODUCT_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter
+
+pci:v000010ECd00008180*
+ ID_PRODUCT_FROM_DATABASE=RTL8180L 802.11b MAC
+
+pci:v000010ECd00008180sv00001385sd00004700*
+ ID_PRODUCT_FROM_DATABASE=MA521 802.11b Wireless PC Card
+
+pci:v000010ECd00008180sv00001737sd00000019*
+ ID_PRODUCT_FROM_DATABASE=WPC11v4 802.11b Wireless-B Notebook Adapter
+
+pci:v000010ECd00008185*
+ ID_PRODUCT_FROM_DATABASE=RTL-8185 IEEE 802.11a/b/g Wireless LAN Controller
+
+pci:v000010ECd00008190*
+ ID_PRODUCT_FROM_DATABASE=RTL8190 802.11n Wireless LAN
+
+pci:v000010ECd00008191*
+ ID_PRODUCT_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter
+
+pci:v000010ECd00008192*
+ ID_PRODUCT_FROM_DATABASE=RTL8192E/RTL8192SE Wireless LAN Controller
+
+pci:v000010ECd00008193*
+ ID_PRODUCT_FROM_DATABASE=RTL8192DE Wireless LAN Controller
+
+pci:v000010ECd00008197*
+ ID_PRODUCT_FROM_DATABASE=SmartLAN56 56K Modem
+
+pci:v000010ECd00008199*
+ ID_PRODUCT_FROM_DATABASE=RTL8187SE Wireless LAN Controller
+
+pci:v000010ECd00008199sv00001462sd00006894*
+ ID_PRODUCT_FROM_DATABASE=MN54G2 / MS-6894 Wireless Mini PCIe Card
+
+pci:v000010ED*
+ ID_VENDOR_FROM_DATABASE=Ascii Corporation
+
+pci:v000010EDd00007310*
+ ID_PRODUCT_FROM_DATABASE=V7310
+
+pci:v000010EE*
+ ID_VENDOR_FROM_DATABASE=Xilinx Corporation
+
+pci:v000010EEd00000001*
+ ID_PRODUCT_FROM_DATABASE=EUROCOM for PCI (ECOMP)
+
+pci:v000010EEd00000002*
+ ID_PRODUCT_FROM_DATABASE=Octal E1/T1 for PCI ETP Card
+
+pci:v000010EEd00000007*
+ ID_PRODUCT_FROM_DATABASE=Default PCIe endpoint ID
+
+pci:v000010EEd00000205*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE205P
+
+pci:v000010EEd00000210*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE210P
+
+pci:v000010EEd00000300*
+ ID_PRODUCT_FROM_DATABASE=Spartan 3 Designs (Xilinx IP)
+
+pci:v000010EEd00000314*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE405P/TE410P (1st Gen)
+
+pci:v000010EEd00000405*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE405P (2nd Gen)
+
+pci:v000010EEd00000410*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE410P (2nd Gen)
+
+pci:v000010EEd00000600*
+ ID_PRODUCT_FROM_DATABASE=Xilinx 6 Designs (Xilinx IP)
+
+pci:v000010EEd00002B00*
+ ID_PRODUCT_FROM_DATABASE=Zomojo Zcard
+
+pci:v000010EEd00003FC0*
+ ID_PRODUCT_FROM_DATABASE=RME Digi96
+
+pci:v000010EEd00003FC1*
+ ID_PRODUCT_FROM_DATABASE=RME Digi96/8
+
+pci:v000010EEd00003FC2*
+ ID_PRODUCT_FROM_DATABASE=RME Digi96/8 Pro
+
+pci:v000010EEd00003FC3*
+ ID_PRODUCT_FROM_DATABASE=RME Digi96/8 Pad
+
+pci:v000010EEd00003FC4*
+ ID_PRODUCT_FROM_DATABASE=RME Digi9652 (Hammerfall)
+
+pci:v000010EEd00003FC5*
+ ID_PRODUCT_FROM_DATABASE=RME Hammerfall DSP
+
+pci:v000010EEd00003FC6*
+ ID_PRODUCT_FROM_DATABASE=RME Hammerfall DSP MADI
+
+pci:v000010EEd00008380*
+ ID_PRODUCT_FROM_DATABASE=Ellips ProfiXpress Profibus Master
+
+pci:v000010EEd00008381*
+ ID_PRODUCT_FROM_DATABASE=Ellips Santos Frame Grabber
+
+pci:v000010EEd0000D154*
+ ID_PRODUCT_FROM_DATABASE=Copley Controls CAN card (PCI-CAN-02)
+
+pci:v000010EEd0000EBF0*
+ ID_PRODUCT_FROM_DATABASE=SED Systems Modulator/Demodulator
+
+pci:v000010EEd0000EBF1*
+ ID_PRODUCT_FROM_DATABASE=SED Systems Audio Interface Card
+
+pci:v000010EEd0000EBF2*
+ ID_PRODUCT_FROM_DATABASE=SED Systems Common PCI Interface
+
+pci:v000010EF*
+ ID_VENDOR_FROM_DATABASE=Racore Computer Products, Inc.
+
+pci:v000010EFd00008154*
+ ID_PRODUCT_FROM_DATABASE=M815x Token Ring Adapter
+
+pci:v000010F0*
+ ID_VENDOR_FROM_DATABASE=Peritek Corporation
+
+pci:v000010F1*
+ ID_VENDOR_FROM_DATABASE=Tyan Computer
+
+pci:v000010F1d00002865*
+ ID_PRODUCT_FROM_DATABASE=Tyan Thunder K8E S2865
+
+pci:v000010F1d00005300*
+ ID_PRODUCT_FROM_DATABASE=Tyan S5380 Mainboard
+
+pci:v000010F2*
+ ID_VENDOR_FROM_DATABASE=Achme Computer, Inc.
+
+pci:v000010F3*
+ ID_VENDOR_FROM_DATABASE=Alaris, Inc.
+
+pci:v000010F4*
+ ID_VENDOR_FROM_DATABASE=S-MOS Systems, Inc.
+
+pci:v000010F5*
+ ID_VENDOR_FROM_DATABASE=NKK Corporation
+
+pci:v000010F5d0000A001*
+ ID_PRODUCT_FROM_DATABASE=NDR4000 [NR4600 Bridge]
+
+pci:v000010F6*
+ ID_VENDOR_FROM_DATABASE=Creative Electronic Systems SA
+
+pci:v000010F7*
+ ID_VENDOR_FROM_DATABASE=Matsushita Electric Industrial Co., Ltd.
+
+pci:v000010F8*
+ ID_VENDOR_FROM_DATABASE=Altos India Ltd
+
+pci:v000010F9*
+ ID_VENDOR_FROM_DATABASE=PC Direct
+
+pci:v000010FA*
+ ID_VENDOR_FROM_DATABASE=Truevision
+
+pci:v000010FAd0000000C*
+ ID_PRODUCT_FROM_DATABASE=TARGA 1000
+
+pci:v000010FB*
+ ID_VENDOR_FROM_DATABASE=Thesys Gesellschaft fuer Mikroelektronik mbH
+
+pci:v000010FBd0000186F*
+ ID_PRODUCT_FROM_DATABASE=TH 6255
+
+pci:v000010FC*
+ ID_VENDOR_FROM_DATABASE=I-O Data Device, Inc.
+
+pci:v000010FCd00000003*
+ ID_PRODUCT_FROM_DATABASE=Cardbus IDE Controller
+
+pci:v000010FCd00000005*
+ ID_PRODUCT_FROM_DATABASE=Cardbus SCSI CBSC II
+
+pci:v000010FD*
+ ID_VENDOR_FROM_DATABASE=Soyo Computer, Inc
+
+pci:v000010FE*
+ ID_VENDOR_FROM_DATABASE=Fast Multimedia AG
+
+pci:v000010FF*
+ ID_VENDOR_FROM_DATABASE=NCube
+
+pci:v00001100*
+ ID_VENDOR_FROM_DATABASE=Jazz Multimedia
+
+pci:v00001101*
+ ID_VENDOR_FROM_DATABASE=Initio Corporation
+
+pci:v00001101d00000002*
+ ID_PRODUCT_FROM_DATABASE=INI-920 Ultra SCSI Adapter
+
+pci:v00001101d00001060*
+ ID_PRODUCT_FROM_DATABASE=INI-A100U2W
+
+pci:v00001101d00001622*
+ ID_PRODUCT_FROM_DATABASE=INI-1623 PCI SATA-II Controller
+
+pci:v00001101d00009100*
+ ID_PRODUCT_FROM_DATABASE=INI-9100/9100W
+
+pci:v00001101d00009400*
+ ID_PRODUCT_FROM_DATABASE=INI-940 Fast Wide SCSI Adapter
+
+pci:v00001101d00009401*
+ ID_PRODUCT_FROM_DATABASE=INI-935 Fast Wide SCSI Adapter
+
+pci:v00001101d00009500*
+ ID_PRODUCT_FROM_DATABASE=INI-950 SCSI Adapter
+
+pci:v00001101d00009502*
+ ID_PRODUCT_FROM_DATABASE=INI-950P Ultra Wide SCSI Adapter
+
+pci:v00001102*
+ ID_VENDOR_FROM_DATABASE=Creative Labs
+
+pci:v00001102d00000002*
+ ID_PRODUCT_FROM_DATABASE=SB Live! EMU10k1
+
+pci:v00001102d00000002sv0000100Asd00001102*
+ ID_PRODUCT_FROM_DATABASE=SB Live! 5.1 Digital OEM SB0220 EMU10K1-JFF
+
+pci:v00001102d00000002sv00001102sd00000020*
+ ID_PRODUCT_FROM_DATABASE=CT4850 SBLive! Value
+
+pci:v00001102d00000002sv00001102sd00000021*
+ ID_PRODUCT_FROM_DATABASE=CT4620 SBLive!
+
+pci:v00001102d00000002sv00001102sd0000002F*
+ ID_PRODUCT_FROM_DATABASE=SBLive! mainboard implementation
+
+pci:v00001102d00000002sv00001102sd0000100A*
+ ID_PRODUCT_FROM_DATABASE=SB Live! 5.1 Digital OEM [SB0220]
+
+pci:v00001102d00000002sv00001102sd00004001*
+ ID_PRODUCT_FROM_DATABASE=E-mu APS
+
+pci:v00001102d00000002sv00001102sd00008022*
+ ID_PRODUCT_FROM_DATABASE=CT4780 SBLive! Value
+
+pci:v00001102d00000002sv00001102sd00008023*
+ ID_PRODUCT_FROM_DATABASE=CT4790 SoundBlaster PCI512
+
+pci:v00001102d00000002sv00001102sd00008024*
+ ID_PRODUCT_FROM_DATABASE=CT4760 SBLive!
+
+pci:v00001102d00000002sv00001102sd00008025*
+ ID_PRODUCT_FROM_DATABASE=SBLive! Mainboard Implementation
+
+pci:v00001102d00000002sv00001102sd00008026*
+ ID_PRODUCT_FROM_DATABASE=CT4830 SBLive! Value
+
+pci:v00001102d00000002sv00001102sd00008027*
+ ID_PRODUCT_FROM_DATABASE=CT4832 SBLive! Value
+
+pci:v00001102d00000002sv00001102sd00008028*
+ ID_PRODUCT_FROM_DATABASE=CT4760 SBLive! OEM version
+
+pci:v00001102d00000002sv00001102sd00008031*
+ ID_PRODUCT_FROM_DATABASE=CT4831 SBLive! Value
+
+pci:v00001102d00000002sv00001102sd00008040*
+ ID_PRODUCT_FROM_DATABASE=CT4760 SBLive!
+
+pci:v00001102d00000002sv00001102sd00008051*
+ ID_PRODUCT_FROM_DATABASE=CT4850 SBLive! Value
+
+pci:v00001102d00000002sv00001102sd00008061*
+ ID_PRODUCT_FROM_DATABASE=SBLive! Player 5.1
+
+pci:v00001102d00000002sv00001102sd00008064*
+ ID_PRODUCT_FROM_DATABASE=SBLive! 5.1 Model SB0100
+
+pci:v00001102d00000002sv00001102sd00008065*
+ ID_PRODUCT_FROM_DATABASE=SBLive! 5.1 Digital Model SB0220
+
+pci:v00001102d00000002sv00001102sd00008066*
+ ID_PRODUCT_FROM_DATABASE=Live! 5.1 Digital [SB0228]
+
+pci:v00001102d00000002sv00001102sd00008067*
+ ID_PRODUCT_FROM_DATABASE=SBLive! 5.1 eMicro 28028
+
+pci:v00001102d00000004*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy
+
+pci:v00001102d00000004sv00001102sd00000051*
+ ID_PRODUCT_FROM_DATABASE=SB0090 Audigy Player
+
+pci:v00001102d00000004sv00001102sd00000053*
+ ID_PRODUCT_FROM_DATABASE=SB0090 Audigy Player/OEM
+
+pci:v00001102d00000004sv00001102sd00000058*
+ ID_PRODUCT_FROM_DATABASE=SB0090 Audigy Player/OEM
+
+pci:v00001102d00000004sv00001102sd00001002*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy2 Platinum
+
+pci:v00001102d00000004sv00001102sd00001007*
+ ID_PRODUCT_FROM_DATABASE=SB0240 Audigy 2 Platinum 6.1
+
+pci:v00001102d00000004sv00001102sd00001009*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy2 OEM HP
+
+pci:v00001102d00000004sv00001102sd00002002*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy 2 ZS (SB0350)
+
+pci:v00001102d00000004sv00001102sd00004001*
+ ID_PRODUCT_FROM_DATABASE=E-MU 1010
+
+pci:v00001102d00000004sv00001102sd00004002*
+ ID_PRODUCT_FROM_DATABASE=E-MU 0404
+
+pci:v00001102d00000005*
+ ID_PRODUCT_FROM_DATABASE=SB X-Fi
+
+pci:v00001102d00000005sv00001102sd00000021*
+ ID_PRODUCT_FROM_DATABASE=X-Fi Platinum
+
+pci:v00001102d00000005sv00001102sd0000002C*
+ ID_PRODUCT_FROM_DATABASE=X-Fi XtremeGamer FATAL1TY PRO
+
+pci:v00001102d00000005sv00001102sd00001003*
+ ID_PRODUCT_FROM_DATABASE=X-Fi XtremeMusic
+
+pci:v00001102d00000006*
+ ID_PRODUCT_FROM_DATABASE=[SB Live! Value] EMU10k1X
+
+pci:v00001102d00000007*
+ ID_PRODUCT_FROM_DATABASE=CA0106 Soundblaster
+
+pci:v00001102d00000007sv00001102sd00000007*
+ ID_PRODUCT_FROM_DATABASE=SBLive! 24bit
+
+pci:v00001102d00000007sv00001102sd00001001*
+ ID_PRODUCT_FROM_DATABASE=SB0310 Audigy LS
+
+pci:v00001102d00000007sv00001102sd00001002*
+ ID_PRODUCT_FROM_DATABASE=SB0312 Audigy LS
+
+pci:v00001102d00000007sv00001102sd00001006*
+ ID_PRODUCT_FROM_DATABASE=SB0410 SBLive! 24-bit
+
+pci:v00001102d00000007sv00001102sd0000100A*
+ ID_PRODUCT_FROM_DATABASE=SB0570 [SB Audigy SE]
+
+pci:v00001102d00000007sv00001102sd00001012*
+ ID_PRODUCT_FROM_DATABASE=SB0790 X-Fi XA
+
+pci:v00001102d00000007sv00001102sd00001013*
+ ID_PRODUCT_FROM_DATABASE=Soundblaster X-Fi Xtreme Audio
+
+pci:v00001102d00000007sv00001462sd00001009*
+ ID_PRODUCT_FROM_DATABASE=K8N Diamond
+
+pci:v00001102d00000008*
+ ID_PRODUCT_FROM_DATABASE=SB0400 Audigy2 Value
+
+pci:v00001102d00000008sv00001102sd00000008*
+ ID_PRODUCT_FROM_DATABASE=EMU0404 Digital Audio System
+
+pci:v00001102d00000008sv00001102sd00004004*
+ ID_PRODUCT_FROM_DATABASE=EMU1010 Digital Audio System [MAEM8960]
+
+pci:v00001102d00000009*
+ ID_PRODUCT_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG
+
+pci:v00001102d00000009sv00001102sd00000010*
+ ID_PRODUCT_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG
+
+pci:v00001102d00000009sv00001102sd00000018*
+ ID_PRODUCT_FROM_DATABASE=SB1040
+
+pci:v00001102d0000000B*
+ ID_PRODUCT_FROM_DATABASE=EMU20k2 [X-Fi Titanium Series]
+
+pci:v00001102d0000000Bsv00001102sd00000041*
+ ID_PRODUCT_FROM_DATABASE=SB0880 [SoundBlaster X-Fi Titanium PCI-e]
+
+pci:v00001102d00004001*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy FireWire Port
+
+pci:v00001102d00004001sv00001102sd00000010*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy FireWire Port
+
+pci:v00001102d00007002*
+ ID_PRODUCT_FROM_DATABASE=SB Live! Game Port
+
+pci:v00001102d00007002sv00001102sd00000020*
+ ID_PRODUCT_FROM_DATABASE=Gameport Joystick
+
+pci:v00001102d00007003*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy Game Port
+
+pci:v00001102d00007003sv00001102sd00000040*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy Game Port
+
+pci:v00001102d00007003sv00001102sd00000060*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy2 MIDI/Game Port
+
+pci:v00001102d00007004*
+ ID_PRODUCT_FROM_DATABASE=[SB Live! Value] Input device controller
+
+pci:v00001102d00007005*
+ ID_PRODUCT_FROM_DATABASE=SB Audigy LS Game Port
+
+pci:v00001102d00007005sv00001102sd00001001*
+ ID_PRODUCT_FROM_DATABASE=SB0310 Audigy LS MIDI/Game port
+
+pci:v00001102d00007005sv00001102sd00001002*
+ ID_PRODUCT_FROM_DATABASE=SB0312 Audigy LS MIDI/Game port
+
+pci:v00001102d00007006*
+ ID_PRODUCT_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG PCI to PCIe Bridge
+
+pci:v00001102d00008938*
+ ID_PRODUCT_FROM_DATABASE=Ectiva EV1938
+
+pci:v00001102d00008938sv00001033sd000080E5*
+ ID_PRODUCT_FROM_DATABASE=SlimTower-Jim (NEC)
+
+pci:v00001102d00008938sv00001071sd00007150*
+ ID_PRODUCT_FROM_DATABASE=Mitac 7150
+
+pci:v00001102d00008938sv0000110Asd00005938*
+ ID_PRODUCT_FROM_DATABASE=Siemens Scenic Mobile 510PIII
+
+pci:v00001102d00008938sv000013BDsd0000100C*
+ ID_PRODUCT_FROM_DATABASE=Ceres-C (Sharp, Intel BX)
+
+pci:v00001102d00008938sv000013BDsd0000100D*
+ ID_PRODUCT_FROM_DATABASE=Sharp, Intel Banister
+
+pci:v00001102d00008938sv000013BDsd0000100E*
+ ID_PRODUCT_FROM_DATABASE=TwinHead P09S/P09S3 (Sharp)
+
+pci:v00001102d00008938sv000013BDsd0000F6F1*
+ ID_PRODUCT_FROM_DATABASE=Marlin (Sharp)
+
+pci:v00001102d00008938sv000014FFsd00000E70*
+ ID_PRODUCT_FROM_DATABASE=P88TE (TWINHEAD INTERNATIONAL Corp)
+
+pci:v00001102d00008938sv000014FFsd0000C401*
+ ID_PRODUCT_FROM_DATABASE=Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp)
+
+pci:v00001102d00008938sv0000156Dsd0000B400*
+ ID_PRODUCT_FROM_DATABASE=G400 - Geo (AlphaTop (Taiwan))
+
+pci:v00001102d00008938sv0000156Dsd0000B550*
+ ID_PRODUCT_FROM_DATABASE=G560  (AlphaTop (Taiwan))
+
+pci:v00001102d00008938sv0000156Dsd0000B560*
+ ID_PRODUCT_FROM_DATABASE=G560  (AlphaTop (Taiwan))
+
+pci:v00001102d00008938sv0000156Dsd0000B700*
+ ID_PRODUCT_FROM_DATABASE=G700/U700  (AlphaTop (Taiwan))
+
+pci:v00001102d00008938sv0000156Dsd0000B795*
+ ID_PRODUCT_FROM_DATABASE=G795  (AlphaTop (Taiwan))
+
+pci:v00001102d00008938sv0000156Dsd0000B797*
+ ID_PRODUCT_FROM_DATABASE=G797  (AlphaTop (Taiwan))
+
+pci:v00001103*
+ ID_VENDOR_FROM_DATABASE=HighPoint Technologies, Inc.
+
+pci:v00001103d00000003*
+ ID_PRODUCT_FROM_DATABASE=HPT343/345/346/363
+
+pci:v00001103d00000004*
+ ID_PRODUCT_FROM_DATABASE=HPT366/368/370/370A/372/372N
+
+pci:v00001103d00000004sv00001103sd00000001*
+ ID_PRODUCT_FROM_DATABASE=HPT370A
+
+pci:v00001103d00000004sv00001103sd00000004*
+ ID_PRODUCT_FROM_DATABASE=HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4)
+
+pci:v00001103d00000004sv00001103sd00000005*
+ ID_PRODUCT_FROM_DATABASE=HPT370 UDMA100
+
+pci:v00001103d00000004sv00001103sd00000006*
+ ID_PRODUCT_FROM_DATABASE=HPT302/302N
+
+pci:v00001103d00000005*
+ ID_PRODUCT_FROM_DATABASE=HPT372A/372N
+
+pci:v00001103d00000006*
+ ID_PRODUCT_FROM_DATABASE=HPT302/302N
+
+pci:v00001103d00000007*
+ ID_PRODUCT_FROM_DATABASE=HPT371/371N
+
+pci:v00001103d00000008*
+ ID_PRODUCT_FROM_DATABASE=HPT374
+
+pci:v00001103d00000009*
+ ID_PRODUCT_FROM_DATABASE=HPT372N
+
+pci:v00001103d00000620*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 620 2 Port SATA-III Controller
+
+pci:v00001103d00000622*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 622 2 Port SATA-III Controller
+
+pci:v00001103d00000640*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 640 4 Port SATA-III Controller
+
+pci:v00001103d00001720*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 1720 (2x SATA II RAID Controller)
+
+pci:v00001103d00001740*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 1740
+
+pci:v00001103d00001742*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 1742
+
+pci:v00001103d00002210*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2210 SATA-II Controller
+
+pci:v00001103d00002300*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 230x 4 Port SATA-II Controller
+
+pci:v00001103d00002310*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2310 4 Port SATA-II Controller
+
+pci:v00001103d00002320*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2320 SATA-II Controller
+
+pci:v00001103d00002322*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2322 SATA-II Controller
+
+pci:v00001103d00002340*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2340 16 Port SATA-II Controller
+
+pci:v00001103d00002640*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2640 SAS/SATA Controller
+
+pci:v00001103d00002722*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2722
+
+pci:v00001103d00002740*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2740
+
+pci:v00001103d00002744*
+ ID_PRODUCT_FROM_DATABASE=RocketRaid 2744
+
+pci:v00001103d00002782*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 2782
+
+pci:v00001103d00003120*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 3120
+
+pci:v00001103d00003220*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 3220
+
+pci:v00001103d00003320*
+ ID_PRODUCT_FROM_DATABASE=RocketRAID 3320
+
+pci:v00001103d00004310*
+ ID_PRODUCT_FROM_DATABASE=RocketRaid 4310
+
+pci:v00001104*
+ ID_VENDOR_FROM_DATABASE=RasterOps Corp.
+
+pci:v00001105*
+ ID_VENDOR_FROM_DATABASE=Sigma Designs, Inc.
+
+pci:v00001105d00001105*
+ ID_PRODUCT_FROM_DATABASE=REALmagic Xcard MPEG 1/2/3/4 DVD Decoder
+
+pci:v00001105d00008300*
+ ID_PRODUCT_FROM_DATABASE=REALmagic Hollywood Plus DVD Decoder
+
+pci:v00001105d00008400*
+ ID_PRODUCT_FROM_DATABASE=EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder
+
+pci:v00001105d00008401*
+ ID_PRODUCT_FROM_DATABASE=EM8401 REALmagic DVD/MPEG-2 A/V Decoder
+
+pci:v00001105d00008470*
+ ID_PRODUCT_FROM_DATABASE=EM8470 REALmagic DVD/MPEG-4 A/V Decoder
+
+pci:v00001105d00008471*
+ ID_PRODUCT_FROM_DATABASE=EM8471 REALmagic DVD/MPEG-4 A/V Decoder
+
+pci:v00001105d00008475*
+ ID_PRODUCT_FROM_DATABASE=EM8475 REALmagic DVD/MPEG-4 A/V Decoder
+
+pci:v00001105d00008475sv00001105sd00000001*
+ ID_PRODUCT_FROM_DATABASE=REALmagic X-Card
+
+pci:v00001105d00008476*
+ ID_PRODUCT_FROM_DATABASE=EM8476 REALmagic DVD/MPEG-4 A/V Decoder
+
+pci:v00001105d00008476sv0000127Dsd00000000*
+ ID_PRODUCT_FROM_DATABASE=CineView II
+
+pci:v00001105d00008485*
+ ID_PRODUCT_FROM_DATABASE=EM8485 REALmagic DVD/MPEG-4 A/V Decoder
+
+pci:v00001105d00008486*
+ ID_PRODUCT_FROM_DATABASE=EM8486 REALmagic DVD/MPEG-4 A/V Decoder
+
+pci:v00001105d0000C622*
+ ID_PRODUCT_FROM_DATABASE=EM8622L MPEG-4.10 (H.264) and SMPTE 421M (VC-1) A/V Decoder
+
+pci:v00001106*
+ ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc.
+
+pci:v00001106d00000102*
+ ID_PRODUCT_FROM_DATABASE=Embedded VIA Ethernet Controller
+
+pci:v00001106d00000130*
+ ID_PRODUCT_FROM_DATABASE=VT6305 1394.A Controller
+
+pci:v00001106d00000198*
+ ID_PRODUCT_FROM_DATABASE=P4X600 Host Bridge
+
+pci:v00001106d00000204*
+ ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge
+
+pci:v00001106d00000208*
+ ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge
+
+pci:v00001106d00000238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge
+
+pci:v00001106d00000258*
+ ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge
+
+pci:v00001106d00000259*
+ ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge
+
+pci:v00001106d00000269*
+ ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge
+
+pci:v00001106d00000282*
+ ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge
+
+pci:v00001106d00000282sv00001043sd000080A3*
+ ID_PRODUCT_FROM_DATABASE=A8V Deluxe
+
+pci:v00001106d00000290*
+ ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge
+
+pci:v00001106d00000293*
+ ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge
+
+pci:v00001106d00000296*
+ ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge
+
+pci:v00001106d00000305*
+ ID_PRODUCT_FROM_DATABASE=VT8363/8365 [KT133/KM133]
+
+pci:v00001106d00000305sv00001019sd00000987*
+ ID_PRODUCT_FROM_DATABASE=K7VZA Mainboard
+
+pci:v00001106d00000305sv00001043sd00008033*
+ ID_PRODUCT_FROM_DATABASE=A7V Mainboard
+
+pci:v00001106d00000305sv00001043sd0000803E*
+ ID_PRODUCT_FROM_DATABASE=A7V-E Mainboard
+
+pci:v00001106d00000305sv00001043sd00008042*
+ ID_PRODUCT_FROM_DATABASE=A7V133/A7V133-C Mainboard
+
+pci:v00001106d00000305sv0000147Bsd0000A401*
+ ID_PRODUCT_FROM_DATABASE=KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard
+
+pci:v00001106d00000308*
+ ID_PRODUCT_FROM_DATABASE=PT880 Ultra/PT894 Host Bridge
+
+pci:v00001106d00000308sv00001043sd00008199*
+ ID_PRODUCT_FROM_DATABASE=P4V800D-X Mainboard
+
+pci:v00001106d00000314*
+ ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge
+
+pci:v00001106d00000324*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge
+
+pci:v00001106d00000327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge
+
+pci:v00001106d00000336*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge
+
+pci:v00001106d00000340*
+ ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge
+
+pci:v00001106d00000351*
+ ID_PRODUCT_FROM_DATABASE=K8T890CF Host Bridge
+
+pci:v00001106d00000353*
+ ID_PRODUCT_FROM_DATABASE=VX800 Host Bridge
+
+pci:v00001106d00000364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge
+
+pci:v00001106d00000364sv00001043sd000081CE*
+ ID_PRODUCT_FROM_DATABASE=P5VD2-VM mothervoard
+
+pci:v00001106d00000391*
+ ID_PRODUCT_FROM_DATABASE=VT8371 [KX133]
+
+pci:v00001106d00000397*
+ ID_PRODUCT_FROM_DATABASE=VT1708S HD Audio
+
+pci:v00001106d00000397sv00001043sd0000836C*
+ ID_PRODUCT_FROM_DATABASE=P7H55
+
+pci:v00001106d00000397sv00001043sd000083C7*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-AM EPU
+
+pci:v00001106d00000409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 Host Bridge: Host Control
+
+pci:v00001106d00000410*
+ ID_PRODUCT_FROM_DATABASE=VX900 Host Bridge: Host Control
+
+pci:v00001106d00000415*
+ ID_PRODUCT_FROM_DATABASE=VT6415 PATA IDE Host Controller
+
+pci:v00001106d00000415sv00001043sd0000838F*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001106d00000501*
+ ID_PRODUCT_FROM_DATABASE=VT8501 [Apollo MVP4]
+
+pci:v00001106d00000505*
+ ID_PRODUCT_FROM_DATABASE=VT82C505
+
+pci:v00001106d00000561*
+ ID_PRODUCT_FROM_DATABASE=VT82C576MV
+
+pci:v00001106d00000571*
+ ID_PRODUCT_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE
+
+pci:v00001106d00000571sv00001019sd00000985*
+ ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard
+
+pci:v00001106d00000571sv00001019sd00000A81*
+ ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+
+pci:v00001106d00000571sv00001043sd00008052*
+ ID_PRODUCT_FROM_DATABASE=VT8233A Bus Master ATA100/66/33 IDE
+
+pci:v00001106d00000571sv00001043sd0000808C*
+ ID_PRODUCT_FROM_DATABASE=A7V8X / A7V333 motherboard
+
+pci:v00001106d00000571sv00001043sd000080A1*
+ ID_PRODUCT_FROM_DATABASE=A7V8X-X motherboard rev. 1.01
+
+pci:v00001106d00000571sv00001043sd000080ED*
+ ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard
+
+pci:v00001106d00000571sv00001106sd00000571*
+ ID_PRODUCT_FROM_DATABASE=VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
+
+pci:v00001106d00000571sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Magnia Z310
+
+pci:v00001106d00000571sv00001297sd0000F641*
+ ID_PRODUCT_FROM_DATABASE=FX41 motherboard
+
+pci:v00001106d00000571sv00001458sd00005002*
+ ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard
+
+pci:v00001106d00000571sv00001462sd00005901*
+ ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+
+pci:v00001106d00000571sv00001462sd00007020*
+ ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard
+
+pci:v00001106d00000571sv00001462sd00007094*
+ ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0
+
+pci:v00001106d00000571sv00001462sd00007120*
+ ID_PRODUCT_FROM_DATABASE=KT4AV motherboard
+
+pci:v00001106d00000571sv00001462sd00007181*
+ ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard
+
+pci:v00001106d00000571sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v00001106d00000571sv00001849sd00000571*
+ ID_PRODUCT_FROM_DATABASE=K7VT2/K7VT6 motherboard
+
+pci:v00001106d00000576*
+ ID_PRODUCT_FROM_DATABASE=VT82C576 3V [Apollo Master]
+
+pci:v00001106d00000581*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 RAID Controller
+
+pci:v00001106d00000581sv00001106sd00000581*
+ ID_PRODUCT_FROM_DATABASE=Wrong IDE ID
+
+pci:v00001106d00000585*
+ ID_PRODUCT_FROM_DATABASE=VT82C585VP [Apollo VP1/VPX]
+
+pci:v00001106d00000586*
+ ID_PRODUCT_FROM_DATABASE=VT82C586/A/B PCI-to-ISA [Apollo VP]
+
+pci:v00001106d00000586sv00001106sd00000000*
+ ID_PRODUCT_FROM_DATABASE=MVP3 ISA Bridge
+
+pci:v00001106d00000591*
+ ID_PRODUCT_FROM_DATABASE=VT8237A SATA 2-Port Controller
+
+pci:v00001106d00000595*
+ ID_PRODUCT_FROM_DATABASE=VT82C595 [Apollo VP2]
+
+pci:v00001106d00000596*
+ ID_PRODUCT_FROM_DATABASE=VT82C596 ISA [Mobile South]
+
+pci:v00001106d00000596sv00001106sd00000000*
+ ID_PRODUCT_FROM_DATABASE=VT82C596/A/B PCI to ISA Bridge
+
+pci:v00001106d00000596sv00001458sd00000596*
+ ID_PRODUCT_FROM_DATABASE=VT82C596/A/B PCI to ISA Bridge
+
+pci:v00001106d00000597*
+ ID_PRODUCT_FROM_DATABASE=VT82C597 [Apollo VP3]
+
+pci:v00001106d00000598*
+ ID_PRODUCT_FROM_DATABASE=VT82C598 [Apollo MVP3]
+
+pci:v00001106d00000601*
+ ID_PRODUCT_FROM_DATABASE=VT8601 [Apollo ProMedia]
+
+pci:v00001106d00000605*
+ ID_PRODUCT_FROM_DATABASE=VT8605 [ProSavage PM133]
+
+pci:v00001106d00000605sv0000103Csd00001254*
+ ID_PRODUCT_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard]
+
+pci:v00001106d00000605sv00001043sd0000802C*
+ ID_PRODUCT_FROM_DATABASE=CUV4X mainboard
+
+pci:v00001106d00000680*
+ ID_PRODUCT_FROM_DATABASE=VT82C680 [Apollo P6]
+
+pci:v00001106d00000686*
+ ID_PRODUCT_FROM_DATABASE=VT82C686 [Apollo Super South]
+
+pci:v00001106d00000686sv00001019sd00000985*
+ ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard
+
+pci:v00001106d00000686sv0000103Csd00001256*
+ ID_PRODUCT_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard]
+
+pci:v00001106d00000686sv00001043sd0000802C*
+ ID_PRODUCT_FROM_DATABASE=CUV4X mainboard
+
+pci:v00001106d00000686sv00001043sd00008033*
+ ID_PRODUCT_FROM_DATABASE=A7V Mainboard
+
+pci:v00001106d00000686sv00001043sd0000803E*
+ ID_PRODUCT_FROM_DATABASE=A7V-E Mainboard
+
+pci:v00001106d00000686sv00001043sd00008040*
+ ID_PRODUCT_FROM_DATABASE=A7M266 Mainboard
+
+pci:v00001106d00000686sv00001043sd00008042*
+ ID_PRODUCT_FROM_DATABASE=A7V133/A7V133-C Mainboard
+
+pci:v00001106d00000686sv00001106sd00000000*
+ ID_PRODUCT_FROM_DATABASE=VT82C686/A PCI to ISA Bridge
+
+pci:v00001106d00000686sv00001106sd00000686*
+ ID_PRODUCT_FROM_DATABASE=VT82C686/A PCI to ISA Bridge
+
+pci:v00001106d00000686sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Magnia Z310
+
+pci:v00001106d00000686sv0000147Bsd0000A702*
+ ID_PRODUCT_FROM_DATABASE=KG7-Lite Mainboard
+
+pci:v00001106d00000691*
+ ID_PRODUCT_FROM_DATABASE=VT82C693A/694x [Apollo PRO133x]
+
+pci:v00001106d00000691sv00001019sd00000985*
+ ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard
+
+pci:v00001106d00000691sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Magnia Z310
+
+pci:v00001106d00000691sv00001458sd00000691*
+ ID_PRODUCT_FROM_DATABASE=VT82C691 Apollo Pro System Controller
+
+pci:v00001106d00000693*
+ ID_PRODUCT_FROM_DATABASE=VT82C693 [Apollo Pro Plus]
+
+pci:v00001106d00000698*
+ ID_PRODUCT_FROM_DATABASE=VT82C693A [Apollo Pro133 AGP]
+
+pci:v00001106d00000926*
+ ID_PRODUCT_FROM_DATABASE=VT82C926 [Amazon]
+
+pci:v00001106d00001000*
+ ID_PRODUCT_FROM_DATABASE=VT82C570MV
+
+pci:v00001106d00001106*
+ ID_PRODUCT_FROM_DATABASE=VT82C570MV
+
+pci:v00001106d00001122*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 Chrome 9 HC3 Integrated Graphics
+
+pci:v00001106d00001204*
+ ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge
+
+pci:v00001106d00001208*
+ ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge
+
+pci:v00001106d00001238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge
+
+pci:v00001106d00001258*
+ ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge
+
+pci:v00001106d00001259*
+ ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge
+
+pci:v00001106d00001269*
+ ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge
+
+pci:v00001106d00001282*
+ ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge
+
+pci:v00001106d00001290*
+ ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge
+
+pci:v00001106d00001293*
+ ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge
+
+pci:v00001106d00001296*
+ ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge
+
+pci:v00001106d00001308*
+ ID_PRODUCT_FROM_DATABASE=PT894 Host Bridge
+
+pci:v00001106d00001314*
+ ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge
+
+pci:v00001106d00001324*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge
+
+pci:v00001106d00001327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge
+
+pci:v00001106d00001336*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge
+
+pci:v00001106d00001340*
+ ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge
+
+pci:v00001106d00001351*
+ ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge
+
+pci:v00001106d00001353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 Error Reporting
+
+pci:v00001106d00001364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge
+
+pci:v00001106d00001409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 Error Reporting
+
+pci:v00001106d00001410*
+ ID_PRODUCT_FROM_DATABASE=VX900 Error Reporting
+
+pci:v00001106d00001571*
+ ID_PRODUCT_FROM_DATABASE=VT82C576M/VT82C586
+
+pci:v00001106d00001595*
+ ID_PRODUCT_FROM_DATABASE=VT82C595/97 [Apollo VP2/97]
+
+pci:v00001106d00001732*
+ ID_PRODUCT_FROM_DATABASE=VT1732 [Envy24 II] PCI Multi-Channel Audio Controller
+
+pci:v00001106d00002106*
+ ID_PRODUCT_FROM_DATABASE=VIA Rhine Family Fast Ethernet Adapter (VT6105)
+
+pci:v00001106d00002204*
+ ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge
+
+pci:v00001106d00002208*
+ ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge
+
+pci:v00001106d00002238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge
+
+pci:v00001106d00002258*
+ ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge
+
+pci:v00001106d00002259*
+ ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 CPU Host Bridge
+
+pci:v00001106d00002269*
+ ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge
+
+pci:v00001106d00002282*
+ ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge
+
+pci:v00001106d00002290*
+ ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge
+
+pci:v00001106d00002293*
+ ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge
+
+pci:v00001106d00002296*
+ ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge
+
+pci:v00001106d00002308*
+ ID_PRODUCT_FROM_DATABASE=PT894 Host Bridge
+
+pci:v00001106d00002314*
+ ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge
+
+pci:v00001106d00002324*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge
+
+pci:v00001106d00002327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge
+
+pci:v00001106d00002336*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge
+
+pci:v00001106d00002340*
+ ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge
+
+pci:v00001106d00002351*
+ ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge
+
+pci:v00001106d00002353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 Host Bus Control
+
+pci:v00001106d00002364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge
+
+pci:v00001106d00002409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 Host Bus Control
+
+pci:v00001106d00002410*
+ ID_PRODUCT_FROM_DATABASE=VX900 CPU Bus Controller
+
+pci:v00001106d0000287A*
+ ID_PRODUCT_FROM_DATABASE=VT8251 PCI to PCI Bridge
+
+pci:v00001106d0000287B*
+ ID_PRODUCT_FROM_DATABASE=VT8251 Host Bridge
+
+pci:v00001106d0000287C*
+ ID_PRODUCT_FROM_DATABASE=VT8251 PCIE Root Port
+
+pci:v00001106d0000287D*
+ ID_PRODUCT_FROM_DATABASE=VT8251 PCIE Root Port
+
+pci:v00001106d0000287E*
+ ID_PRODUCT_FROM_DATABASE=VT8237/8251 Ultra VLINK Controller
+
+pci:v00001106d00003022*
+ ID_PRODUCT_FROM_DATABASE=CLE266
+
+pci:v00001106d00003038*
+ ID_PRODUCT_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller
+
+pci:v00001106d00003038sv00000925sd00001234*
+ ID_PRODUCT_FROM_DATABASE=VA-502 Mainboard
+
+pci:v00001106d00003038sv00001019sd00000985*
+ ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard
+
+pci:v00001106d00003038sv00001019sd00000A81*
+ ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+
+pci:v00001106d00003038sv00001043sd00008080*
+ ID_PRODUCT_FROM_DATABASE=A7V333 motherboard
+
+pci:v00001106d00003038sv00001043sd0000808C*
+ ID_PRODUCT_FROM_DATABASE=VT6202 USB2.0 4 port controller
+
+pci:v00001106d00003038sv00001043sd000080A1*
+ ID_PRODUCT_FROM_DATABASE=A7V8X-X motherboard
+
+pci:v00001106d00003038sv00001043sd000080ED*
+ ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard
+
+pci:v00001106d00003038sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Magnia Z310
+
+pci:v00001106d00003038sv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard
+
+pci:v00001106d00003038sv00001462sd00005901*
+ ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+
+pci:v00001106d00003038sv00001462sd00007020*
+ ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard
+
+pci:v00001106d00003038sv00001462sd00007094*
+ ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0
+
+pci:v00001106d00003038sv00001462sd00007120*
+ ID_PRODUCT_FROM_DATABASE=KT4AV motherboard
+
+pci:v00001106d00003038sv00001462sd00007181*
+ ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard
+
+pci:v00001106d00003038sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v00001106d00003038sv0000182Dsd0000201D*
+ ID_PRODUCT_FROM_DATABASE=CN-029 USB2.0 4 port PCI Card
+
+pci:v00001106d00003038sv00001849sd00003038*
+ ID_PRODUCT_FROM_DATABASE=K7VT6
+
+pci:v00001106d00003038sv000019DAsd0000A179*
+ ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01
+
+pci:v00001106d00003040*
+ ID_PRODUCT_FROM_DATABASE=VT82C586B ACPI
+
+pci:v00001106d00003043*
+ ID_PRODUCT_FROM_DATABASE=VT86C100A [Rhine]
+
+pci:v00001106d00003043sv000010BDsd00000000*
+ ID_PRODUCT_FROM_DATABASE=VT86C100A Fast Ethernet Adapter
+
+pci:v00001106d00003043sv00001106sd00000100*
+ ID_PRODUCT_FROM_DATABASE=VT86C100A Fast Ethernet Adapter
+
+pci:v00001106d00003043sv00001186sd00001400*
+ ID_PRODUCT_FROM_DATABASE=DFE-530TX rev A
+
+pci:v00001106d00003044*
+ ID_PRODUCT_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller
+
+pci:v00001106d00003044sv00000010sd00000001*
+ ID_PRODUCT_FROM_DATABASE=IEEE 1394 4port DCST 1394-3+1B
+
+pci:v00001106d00003044sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00001106d00003044sv0000103Csd00002A20*
+ ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC
+
+pci:v00001106d00003044sv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Media Center PC m7590n
+
+pci:v00001106d00003044sv00001043sd0000808A*
+ ID_PRODUCT_FROM_DATABASE=A8V/A8N/P4P800 series motherboard
+
+pci:v00001106d00003044sv00001043sd000081FE*
+ ID_PRODUCT_FROM_DATABASE=M4A series motherboard
+
+pci:v00001106d00003044sv00001458sd00001000*
+ ID_PRODUCT_FROM_DATABASE=GA-7VT600-1394 Motherboard
+
+pci:v00001106d00003044sv00001462sd0000207D*
+ ID_PRODUCT_FROM_DATABASE=K8NGM2 series motherboard
+
+pci:v00001106d00003044sv00001462sd0000217D*
+ ID_PRODUCT_FROM_DATABASE=Aspire L250
+
+pci:v00001106d00003044sv00001462sd0000590D*
+ ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+
+pci:v00001106d00003044sv00001462sd0000702D*
+ ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard
+
+pci:v00001106d00003044sv00001462sd0000971D*
+ ID_PRODUCT_FROM_DATABASE=MS-6917
+
+pci:v00001106d00003050*
+ ID_PRODUCT_FROM_DATABASE=VT82C596 Power Management
+
+pci:v00001106d00003051*
+ ID_PRODUCT_FROM_DATABASE=VT82C596 Power Management
+
+pci:v00001106d00003053*
+ ID_PRODUCT_FROM_DATABASE=VT6105M [Rhine-III]
+
+pci:v00001106d00003057*
+ ID_PRODUCT_FROM_DATABASE=VT82C686 [Apollo Super ACPI]
+
+pci:v00001106d00003057sv00001019sd00000985*
+ ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard
+
+pci:v00001106d00003057sv00001019sd00000987*
+ ID_PRODUCT_FROM_DATABASE=K7VZA Motherboard
+
+pci:v00001106d00003057sv00001043sd00008033*
+ ID_PRODUCT_FROM_DATABASE=A7V Mainboard
+
+pci:v00001106d00003057sv00001043sd0000803E*
+ ID_PRODUCT_FROM_DATABASE=A7V-E Mainboard
+
+pci:v00001106d00003057sv00001043sd00008040*
+ ID_PRODUCT_FROM_DATABASE=A7M266 Mainboard
+
+pci:v00001106d00003057sv00001043sd00008042*
+ ID_PRODUCT_FROM_DATABASE=A7V133/A7V133-C Mainboard
+
+pci:v00001106d00003057sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Magnia Z310
+
+pci:v00001106d00003058*
+ ID_PRODUCT_FROM_DATABASE=VT82C686 AC97 Audio Controller
+
+pci:v00001106d00003058sv00000E11sd00000097*
+ ID_PRODUCT_FROM_DATABASE=SoundMax Digital Integrated Audio
+
+pci:v00001106d00003058sv00000E11sd0000B194*
+ ID_PRODUCT_FROM_DATABASE=Soundmax integrated digital audio
+
+pci:v00001106d00003058sv00001019sd00000985*
+ ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard
+
+pci:v00001106d00003058sv00001019sd00000987*
+ ID_PRODUCT_FROM_DATABASE=K7VZA Motherboard
+
+pci:v00001106d00003058sv0000103Csd00001251*
+ ID_PRODUCT_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard]
+
+pci:v00001106d00003058sv00001043sd00001106*
+ ID_PRODUCT_FROM_DATABASE=A7V133/A7V133-C Mainboard
+
+pci:v00001106d00003058sv00001106sd00004511*
+ ID_PRODUCT_FROM_DATABASE=Onboard Audio on EP7KXA
+
+pci:v00001106d00003058sv00001106sd0000AA03*
+ ID_PRODUCT_FROM_DATABASE=VT1612A AC'97 Audio Controller
+
+pci:v00001106d00003058sv000011D4sd00005348*
+ ID_PRODUCT_FROM_DATABASE=AD1881A audio
+
+pci:v00001106d00003058sv00001458sd00007600*
+ ID_PRODUCT_FROM_DATABASE=Onboard Audio
+
+pci:v00001106d00003058sv00001462sd00003091*
+ ID_PRODUCT_FROM_DATABASE=MS-6309 Onboard Audio
+
+pci:v00001106d00003058sv00001462sd00003092*
+ ID_PRODUCT_FROM_DATABASE=MS-6309 v2.x Mainboard (VIA VT1611A codec)
+
+pci:v00001106d00003058sv00001462sd00003300*
+ ID_PRODUCT_FROM_DATABASE=MS-6330 Onboard Audio
+
+pci:v00001106d00003058sv000015DDsd00007609*
+ ID_PRODUCT_FROM_DATABASE=Onboard Audio
+
+pci:v00001106d00003059*
+ ID_PRODUCT_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller
+
+pci:v00001106d00003059sv00001019sd00000A81*
+ ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+
+pci:v00001106d00003059sv00001019sd00001877*
+ ID_PRODUCT_FROM_DATABASE=K8M800-M2 (V2.0) onboard audio
+
+pci:v00001106d00003059sv00001043sd00008095*
+ ID_PRODUCT_FROM_DATABASE=A7V8X Motherboard (Realtek ALC650 codec)
+
+pci:v00001106d00003059sv00001043sd000080A1*
+ ID_PRODUCT_FROM_DATABASE=A7V8X-X Motherboard
+
+pci:v00001106d00003059sv00001043sd000080B0*
+ ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX])
+
+pci:v00001106d00003059sv00001043sd0000810D*
+ ID_PRODUCT_FROM_DATABASE=Asus P5VD1-X (AD1888 codec [SoundMax])
+
+pci:v00001106d00003059sv00001043sd0000812A*
+ ID_PRODUCT_FROM_DATABASE=A8V Deluxe motherboard (Realtek ALC850 codec)
+
+pci:v00001106d00003059sv000010ECsd00008168*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio
+
+pci:v00001106d00003059sv00001106sd00003059*
+ ID_PRODUCT_FROM_DATABASE=L7VMM2 Motherboard
+
+pci:v00001106d00003059sv00001106sd00004161*
+ ID_PRODUCT_FROM_DATABASE=K7VT2 motherboard
+
+pci:v00001106d00003059sv00001106sd00004170*
+ ID_PRODUCT_FROM_DATABASE=PCPartner P4M800-8237R Motherboard
+
+pci:v00001106d00003059sv00001106sd00004552*
+ ID_PRODUCT_FROM_DATABASE=Soyo KT-600 Dragon Plus (Realtek ALC 650)
+
+pci:v00001106d00003059sv00001297sd0000C160*
+ ID_PRODUCT_FROM_DATABASE=FX41 motherboard (Realtek ALC650 codec)
+
+pci:v00001106d00003059sv00001413sd0000147B*
+ ID_PRODUCT_FROM_DATABASE=KV8 Pro motherboard onboard audio
+
+pci:v00001106d00003059sv00001458sd0000A002*
+ ID_PRODUCT_FROM_DATABASE=GA-7VAX Onboard Audio (Realtek ALC650)
+
+pci:v00001106d00003059sv00001462sd00000080*
+ ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard
+
+pci:v00001106d00003059sv00001462sd00003800*
+ ID_PRODUCT_FROM_DATABASE=KT266 onboard audio
+
+pci:v00001106d00003059sv00001462sd00005901*
+ ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+
+pci:v00001106d00003059sv00001462sd00007181*
+ ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard
+
+pci:v00001106d00003059sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v00001106d00003059sv00001695sd0000300C*
+ ID_PRODUCT_FROM_DATABASE=EP-8KRA2+ Mainboard
+
+pci:v00001106d00003059sv00001849sd00000850*
+ ID_PRODUCT_FROM_DATABASE=ASRock 775Dual-880 Pro onboard audio (Realtek ALC850)
+
+pci:v00001106d00003059sv00001849sd00009739*
+ ID_PRODUCT_FROM_DATABASE=P4VT8 Mainboard (C-Media CMI9739A codec)
+
+pci:v00001106d00003059sv00001849sd00009761*
+ ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard
+
+pci:v00001106d00003059sv00004005sd00004710*
+ ID_PRODUCT_FROM_DATABASE=MSI K7T266 Pro2-RU (MSI-6380 v2) onboard audio (Realtek/ALC 200/200P)
+
+pci:v00001106d00003059sv0000A0A0sd000001B6*
+ ID_PRODUCT_FROM_DATABASE=AK77-8XN onboard audio
+
+pci:v00001106d00003059sv0000A0A0sd00000342*
+ ID_PRODUCT_FROM_DATABASE=AK86-L motherboard
+
+pci:v00001106d00003065*
+ ID_PRODUCT_FROM_DATABASE=VT6102 [Rhine-II]
+
+pci:v00001106d00003065sv00001043sd000080A1*
+ ID_PRODUCT_FROM_DATABASE=A7V8X-X Motherboard
+
+pci:v00001106d00003065sv00001043sd000080ED*
+ ID_PRODUCT_FROM_DATABASE=A7V600-X Motherboard
+
+pci:v00001106d00003065sv00001106sd00000102*
+ ID_PRODUCT_FROM_DATABASE=VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
+
+pci:v00001106d00003065sv00001186sd00001400*
+ ID_PRODUCT_FROM_DATABASE=DFE-530TX rev A
+
+pci:v00001106d00003065sv00001186sd00001401*
+ ID_PRODUCT_FROM_DATABASE=DFE-530TX rev B
+
+pci:v00001106d00003065sv000013B9sd00001421*
+ ID_PRODUCT_FROM_DATABASE=LD-10/100AL PCI Fast Ethernet Adapter (rev.B)
+
+pci:v00001106d00003065sv00001462sd00007061*
+ ID_PRODUCT_FROM_DATABASE=MS-7061
+
+pci:v00001106d00003065sv00001462sd00007181*
+ ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard
+
+pci:v00001106d00003065sv0000147Bsd00001C09*
+ ID_PRODUCT_FROM_DATABASE=NV7 Motherboard
+
+pci:v00001106d00003065sv00001695sd00003005*
+ ID_PRODUCT_FROM_DATABASE=VT6103
+
+pci:v00001106d00003065sv00001695sd0000300C*
+ ID_PRODUCT_FROM_DATABASE=Realtek ALC655 sound chip
+
+pci:v00001106d00003065sv00001849sd00003065*
+ ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard
+
+pci:v00001106d00003068*
+ ID_PRODUCT_FROM_DATABASE=AC'97 Modem Controller
+
+pci:v00001106d00003068sv00001462sd0000309E*
+ ID_PRODUCT_FROM_DATABASE=MS-6309 Saturn Motherboard
+
+pci:v00001106d00003074*
+ ID_PRODUCT_FROM_DATABASE=VT8233 PCI to ISA Bridge
+
+pci:v00001106d00003074sv00001043sd00008052*
+ ID_PRODUCT_FROM_DATABASE=VT8233A
+
+pci:v00001106d00003091*
+ ID_PRODUCT_FROM_DATABASE=VT8633 [Apollo Pro266]
+
+pci:v00001106d00003099*
+ ID_PRODUCT_FROM_DATABASE=VT8366/A/7 [Apollo KT266/A/333]
+
+pci:v00001106d00003099sv00001043sd00008064*
+ ID_PRODUCT_FROM_DATABASE=A7V266-E Mainboard
+
+pci:v00001106d00003099sv00001043sd0000807F*
+ ID_PRODUCT_FROM_DATABASE=A7V333 Mainboard
+
+pci:v00001106d00003099sv00001849sd00003099*
+ ID_PRODUCT_FROM_DATABASE=K7VT2 motherboard
+
+pci:v00001106d00003101*
+ ID_PRODUCT_FROM_DATABASE=VT8653 Host Bridge
+
+pci:v00001106d00003102*
+ ID_PRODUCT_FROM_DATABASE=VT8662 Host Bridge
+
+pci:v00001106d00003103*
+ ID_PRODUCT_FROM_DATABASE=VT8615 Host Bridge
+
+pci:v00001106d00003104*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0
+
+pci:v00001106d00003104sv00001019sd00000A81*
+ ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+
+pci:v00001106d00003104sv00001043sd0000808C*
+ ID_PRODUCT_FROM_DATABASE=A7V8X motherboard
+
+pci:v00001106d00003104sv00001043sd000080A1*
+ ID_PRODUCT_FROM_DATABASE=A7V8X-X motherboard rev 1.01
+
+pci:v00001106d00003104sv00001043sd000080ED*
+ ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard
+
+pci:v00001106d00003104sv00001297sd0000F641*
+ ID_PRODUCT_FROM_DATABASE=FX41 motherboard
+
+pci:v00001106d00003104sv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard
+
+pci:v00001106d00003104sv00001462sd00005901*
+ ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+
+pci:v00001106d00003104sv00001462sd00007020*
+ ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard
+
+pci:v00001106d00003104sv00001462sd00007094*
+ ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0
+
+pci:v00001106d00003104sv00001462sd00007120*
+ ID_PRODUCT_FROM_DATABASE=KT4AV motherboard
+
+pci:v00001106d00003104sv00001462sd00007181*
+ ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard
+
+pci:v00001106d00003104sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v00001106d00003104sv0000182Dsd0000201D*
+ ID_PRODUCT_FROM_DATABASE=CN-029 USB 2.0 4 port PCI Card
+
+pci:v00001106d00003104sv00001849sd00003104*
+ ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard
+
+pci:v00001106d00003104sv000019DAsd0000A179*
+ ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01
+
+pci:v00001106d00003106*
+ ID_PRODUCT_FROM_DATABASE=VT6105/VT6106S [Rhine-III]
+
+pci:v00001106d00003106sv00001106sd00000105*
+ ID_PRODUCT_FROM_DATABASE=VT6106S [Rhine-III]
+
+pci:v00001106d00003106sv00001186sd00001403*
+ ID_PRODUCT_FROM_DATABASE=DFE-530TX rev C
+
+pci:v00001106d00003106sv00001186sd00001406*
+ ID_PRODUCT_FROM_DATABASE=DFE-530TX+ rev F2
+
+pci:v00001106d00003106sv00001186sd00001407*
+ ID_PRODUCT_FROM_DATABASE=DFE-538TX
+
+pci:v00001106d00003108*
+ ID_PRODUCT_FROM_DATABASE=K8M800/K8N800/K8N800A [S3 UniChrome Pro]
+
+pci:v00001106d00003109*
+ ID_PRODUCT_FROM_DATABASE=VT8233C PCI to ISA Bridge
+
+pci:v00001106d00003112*
+ ID_PRODUCT_FROM_DATABASE=VT8361 [KLE133] Host Bridge
+
+pci:v00001106d00003113*
+ ID_PRODUCT_FROM_DATABASE=VPX/VPX2 PCI to PCI Bridge Controller
+
+pci:v00001106d00003116*
+ ID_PRODUCT_FROM_DATABASE=VT8375 [KM266/KL266] Host Bridge
+
+pci:v00001106d00003116sv00001297sd0000F641*
+ ID_PRODUCT_FROM_DATABASE=FX41 motherboard
+
+pci:v00001106d00003118*
+ ID_PRODUCT_FROM_DATABASE=CN400/PM800/PM880/PN800/PN880 [S3 UniChrome Pro]
+
+pci:v00001106d00003119*
+ ID_PRODUCT_FROM_DATABASE=VT6120/VT6121/VT6122 Gigabit Ethernet Adapter
+
+pci:v00001106d00003122*
+ ID_PRODUCT_FROM_DATABASE=VT8623 [Apollo CLE266] integrated CastleRock graphics
+
+pci:v00001106d00003123*
+ ID_PRODUCT_FROM_DATABASE=VT8623 [Apollo CLE266]
+
+pci:v00001106d00003128*
+ ID_PRODUCT_FROM_DATABASE=VT8753 [P4X266 AGP]
+
+pci:v00001106d00003133*
+ ID_PRODUCT_FROM_DATABASE=VT3133 Host Bridge
+
+pci:v00001106d00003142*
+ ID_PRODUCT_FROM_DATABASE=VT6651 WiFi Adapter, 802.11b
+
+pci:v00001106d00003147*
+ ID_PRODUCT_FROM_DATABASE=VT8233A ISA Bridge
+
+pci:v00001106d00003147sv00001043sd0000808C*
+ ID_PRODUCT_FROM_DATABASE=A7V333 motherboard
+
+pci:v00001106d00003148*
+ ID_PRODUCT_FROM_DATABASE=P4M266 Host Bridge
+
+pci:v00001106d00003149*
+ ID_PRODUCT_FROM_DATABASE=VIA VT6420 SATA RAID Controller
+
+pci:v00001106d00003149sv00001043sd000080ED*
+ ID_PRODUCT_FROM_DATABASE=A7V600/K8V Deluxe/K8V-X/A8V Deluxe motherboard
+
+pci:v00001106d00003149sv00001458sd0000B003*
+ ID_PRODUCT_FROM_DATABASE=GA-7VM400AM(F) Motherboard
+
+pci:v00001106d00003149sv00001462sd00005901*
+ ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+
+pci:v00001106d00003149sv00001462sd00007020*
+ ID_PRODUCT_FROM_DATABASE=K8T Neo 2 Motherboard
+
+pci:v00001106d00003149sv00001462sd00007094*
+ ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0
+
+pci:v00001106d00003149sv00001462sd00007181*
+ ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard
+
+pci:v00001106d00003149sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v00001106d00003149sv0000147Bsd00001408*
+ ID_PRODUCT_FROM_DATABASE=KV7
+
+pci:v00001106d00003149sv00001849sd00003149*
+ ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard
+
+pci:v00001106d00003149sv0000A0A0sd000004AD*
+ ID_PRODUCT_FROM_DATABASE=AK86-L motherboard
+
+pci:v00001106d00003156*
+ ID_PRODUCT_FROM_DATABASE=P/KN266 Host Bridge
+
+pci:v00001106d00003157*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 [S3 UniChrome Pro]
+
+pci:v00001106d00003164*
+ ID_PRODUCT_FROM_DATABASE=VT6410 ATA133 RAID controller
+
+pci:v00001106d00003164sv00001043sd000080F4*
+ ID_PRODUCT_FROM_DATABASE=P4P800 Mainboard Deluxe ATX
+
+pci:v00001106d00003164sv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00001106d00003168*
+ ID_PRODUCT_FROM_DATABASE=P4X333/P4X400/PT800 AGP Bridge
+
+pci:v00001106d00003168sv00001849sd00003168*
+ ID_PRODUCT_FROM_DATABASE=P4VT8 Mainboard
+
+pci:v00001106d00003177*
+ ID_PRODUCT_FROM_DATABASE=VT8235 ISA Bridge
+
+pci:v00001106d00003177sv00001019sd00000A81*
+ ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+
+pci:v00001106d00003177sv00001043sd0000808C*
+ ID_PRODUCT_FROM_DATABASE=A7V8X motherboard
+
+pci:v00001106d00003177sv00001043sd000080A1*
+ ID_PRODUCT_FROM_DATABASE=A7V8X-X motherboard
+
+pci:v00001106d00003177sv00001106sd00000000*
+ ID_PRODUCT_FROM_DATABASE=KT4AV motherboard
+
+pci:v00001106d00003177sv00001297sd0000F641*
+ ID_PRODUCT_FROM_DATABASE=FX41 motherboard
+
+pci:v00001106d00003177sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard
+
+pci:v00001106d00003177sv00001849sd00003177*
+ ID_PRODUCT_FROM_DATABASE=K7VT2 motherboard
+
+pci:v00001106d00003178*
+ ID_PRODUCT_FROM_DATABASE=ProSavageDDR P4N333 Host Bridge
+
+pci:v00001106d00003188*
+ ID_PRODUCT_FROM_DATABASE=VT8385 [K8T800 AGP] Host Bridge
+
+pci:v00001106d00003188sv00001043sd000080A3*
+ ID_PRODUCT_FROM_DATABASE=K8V Deluxe/K8V-X motherboard
+
+pci:v00001106d00003188sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v00001106d00003189*
+ ID_PRODUCT_FROM_DATABASE=VT8377 [KT400/KT600 AGP] Host Bridge
+
+pci:v00001106d00003189sv00001043sd0000807F*
+ ID_PRODUCT_FROM_DATABASE=A7V8X motherboard
+
+pci:v00001106d00003189sv00001106sd00000000*
+ ID_PRODUCT_FROM_DATABASE=KT4AV motherboard (KT400A)
+
+pci:v00001106d00003189sv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard
+
+pci:v00001106d00003189sv00001849sd00003189*
+ ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard
+
+pci:v00001106d00003204*
+ ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge
+
+pci:v00001106d00003205*
+ ID_PRODUCT_FROM_DATABASE=VT8378 [KM400/A] Chipset Host Bridge
+
+pci:v00001106d00003205sv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-7VM400M Motherboard
+
+pci:v00001106d00003208*
+ ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge
+
+pci:v00001106d00003213*
+ ID_PRODUCT_FROM_DATABASE=VPX/VPX2 PCI to PCI Bridge Controller
+
+pci:v00001106d00003218*
+ ID_PRODUCT_FROM_DATABASE=K8T800M Host Bridge
+
+pci:v00001106d00003227*
+ ID_PRODUCT_FROM_DATABASE=VT8237 ISA bridge [KT600/K8T800/K8T890 South]
+
+pci:v00001106d00003227sv00001043sd000080ED*
+ ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard
+
+pci:v00001106d00003227sv00001106sd00003227*
+ ID_PRODUCT_FROM_DATABASE=DFI KT600-AL / Soltek SL-B9D-FGR Motherboard
+
+pci:v00001106d00003227sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-7VT600 Motherboard
+
+pci:v00001106d00003227sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v00001106d00003227sv00001849sd00003227*
+ ID_PRODUCT_FROM_DATABASE=K7VT4 motherboard
+
+pci:v00001106d00003230*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE/K8N890CE [Chrome 9]
+
+pci:v00001106d00003238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge
+
+pci:v00001106d00003249*
+ ID_PRODUCT_FROM_DATABASE=VT6421 IDE/SATA Controller
+
+pci:v00001106d0000324A*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 PCI to PCI Bridge
+
+pci:v00001106d0000324B*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge
+
+pci:v00001106d0000324E*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 Internal Module Bus
+
+pci:v00001106d00003253*
+ ID_PRODUCT_FROM_DATABASE=VT6655 WiFi Adapter, 802.11a/b/g
+
+pci:v00001106d00003258*
+ ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge
+
+pci:v00001106d00003259*
+ ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge
+
+pci:v00001106d00003260*
+ ID_PRODUCT_FROM_DATABASE=VIA Chrome9 HC IGP
+
+pci:v00001106d00003269*
+ ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge
+
+pci:v00001106d00003282*
+ ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge
+
+pci:v00001106d00003287*
+ ID_PRODUCT_FROM_DATABASE=VT8251 PCI to ISA Bridge
+
+pci:v00001106d00003288*
+ ID_PRODUCT_FROM_DATABASE=VT8237A/VT8251 HDA Controller
+
+pci:v00001106d00003288sv000019DAsd0000A179*
+ ID_PRODUCT_FROM_DATABASE=ZBOX VD01
+
+pci:v00001106d00003290*
+ ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge
+
+pci:v00001106d00003296*
+ ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge
+
+pci:v00001106d00003324*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge
+
+pci:v00001106d00003327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge
+
+pci:v00001106d00003336*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge
+
+pci:v00001106d00003337*
+ ID_PRODUCT_FROM_DATABASE=VT8237A PCI to ISA Bridge
+
+pci:v00001106d00003340*
+ ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge
+
+pci:v00001106d00003343*
+ ID_PRODUCT_FROM_DATABASE=P4M890 [S3 UniChrome Pro]
+
+pci:v00001106d00003344*
+ ID_PRODUCT_FROM_DATABASE=CN700/P4M800 Pro/P4M800 CE/VN800 Graphics [S3 UniChrome Pro]
+
+pci:v00001106d00003349*
+ ID_PRODUCT_FROM_DATABASE=VT8251 AHCI/SATA 4-Port Controller
+
+pci:v00001106d00003351*
+ ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge
+
+pci:v00001106d00003353*
+ ID_PRODUCT_FROM_DATABASE=VX800 PCI to PCI Bridge
+
+pci:v00001106d00003364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge
+
+pci:v00001106d00003371*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 [Chrome 9 HC]
+
+pci:v00001106d00003372*
+ ID_PRODUCT_FROM_DATABASE=VT8237S PCI to ISA Bridge
+
+pci:v00001106d0000337A*
+ ID_PRODUCT_FROM_DATABASE=VT8237A PCI to PCI Bridge
+
+pci:v00001106d0000337B*
+ ID_PRODUCT_FROM_DATABASE=VT8237A Host Bridge
+
+pci:v00001106d00003403*
+ ID_PRODUCT_FROM_DATABASE=VT6315 Series Firewire Controller
+
+pci:v00001106d00003403sv00001043sd00008374*
+ ID_PRODUCT_FROM_DATABASE=M5A88-V EVO
+
+pci:v00001106d00003403sv00001043sd00008384*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00001106d00003409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 DRAM Bus Control
+
+pci:v00001106d00003410*
+ ID_PRODUCT_FROM_DATABASE=VX900 DRAM Bus Control
+
+pci:v00001106d00003410sv000019DAsd0000A179*
+ ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01
+
+pci:v00001106d00003432*
+ ID_PRODUCT_FROM_DATABASE=VL80x xHCI USB 3.0 Controller
+
+pci:v00001106d00004149*
+ ID_PRODUCT_FROM_DATABASE=VIA VT6420 (ATA133) Controller
+
+pci:v00001106d00004204*
+ ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge
+
+pci:v00001106d00004208*
+ ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge
+
+pci:v00001106d00004238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge
+
+pci:v00001106d00004258*
+ ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge
+
+pci:v00001106d00004259*
+ ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge
+
+pci:v00001106d00004269*
+ ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge
+
+pci:v00001106d00004282*
+ ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge
+
+pci:v00001106d00004290*
+ ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge
+
+pci:v00001106d00004293*
+ ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge
+
+pci:v00001106d00004296*
+ ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge
+
+pci:v00001106d00004308*
+ ID_PRODUCT_FROM_DATABASE=PT894 Host Bridge
+
+pci:v00001106d00004314*
+ ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge
+
+pci:v00001106d00004324*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge
+
+pci:v00001106d00004327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge
+
+pci:v00001106d00004336*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge
+
+pci:v00001106d00004340*
+ ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge
+
+pci:v00001106d00004351*
+ ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge
+
+pci:v00001106d00004353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 Power Management Control
+
+pci:v00001106d00004364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge
+
+pci:v00001106d00004397*
+ ID_PRODUCT_FROM_DATABASE=VT1708B/1702S/1708S HD audio codec
+
+pci:v00001106d00004409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 Power Management Control
+
+pci:v00001106d00004410*
+ ID_PRODUCT_FROM_DATABASE=VX900 Power Management and Chip Testing Control
+
+pci:v00001106d00004410sv000019DAsd0000A179*
+ ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01
+
+pci:v00001106d00004428*
+ ID_PRODUCT_FROM_DATABASE=VT1718S HD Audio Codec
+
+pci:v00001106d00005030*
+ ID_PRODUCT_FROM_DATABASE=VT82C596 ACPI [Apollo PRO]
+
+pci:v00001106d00005122*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 Chrome 9 HCM Integrated Graphics
+
+pci:v00001106d00005208*
+ ID_PRODUCT_FROM_DATABASE=PT890 I/O APIC Interrupt Controller
+
+pci:v00001106d00005238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 I/O APIC Interrupt Controller
+
+pci:v00001106d00005287*
+ ID_PRODUCT_FROM_DATABASE=VT8251 Serial ATA Controller
+
+pci:v00001106d00005290*
+ ID_PRODUCT_FROM_DATABASE=K8M890 I/O APIC Interrupt Controller
+
+pci:v00001106d00005308*
+ ID_PRODUCT_FROM_DATABASE=PT894 I/O APIC Interrupt Controller
+
+pci:v00001106d00005324*
+ ID_PRODUCT_FROM_DATABASE=VX800 Serial ATA and EIDE Controller
+
+pci:v00001106d00005327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 I/O APIC Interrupt Controller
+
+pci:v00001106d00005336*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE I/O APIC Interrupt Controller
+
+pci:v00001106d00005340*
+ ID_PRODUCT_FROM_DATABASE=PT900 I/O APIC Interrupt Controller
+
+pci:v00001106d00005351*
+ ID_PRODUCT_FROM_DATABASE=VT3351 I/O APIC Interrupt Controller
+
+pci:v00001106d00005353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 APIC and Central Traffic Control
+
+pci:v00001106d00005364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 I/O APIC Interrupt Controller
+
+pci:v00001106d00005372*
+ ID_PRODUCT_FROM_DATABASE=VT8237/8251 Serial ATA Controller
+
+pci:v00001106d00005409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 APIC and Central Traffic Control
+
+pci:v00001106d00005410*
+ ID_PRODUCT_FROM_DATABASE=VX900 APIC and Central Traffic Control
+
+pci:v00001106d00006100*
+ ID_PRODUCT_FROM_DATABASE=VT85C100A [Rhine II]
+
+pci:v00001106d00006287*
+ ID_PRODUCT_FROM_DATABASE=SATA RAID Controller
+
+pci:v00001106d00006290*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge
+
+pci:v00001106d00006327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 Security Device
+
+pci:v00001106d00006353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 Scratch Registers
+
+pci:v00001106d00006364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Security Device
+
+pci:v00001106d00006409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 Scratch Registers
+
+pci:v00001106d00006410*
+ ID_PRODUCT_FROM_DATABASE=VX900 Scratch Registers
+
+pci:v00001106d00006410sv000019DAsd0000A179*
+ ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01
+
+pci:v00001106d00007122*
+ ID_PRODUCT_FROM_DATABASE=VX900 Graphics [Chrome9 HD]
+
+pci:v00001106d00007204*
+ ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge
+
+pci:v00001106d00007205*
+ ID_PRODUCT_FROM_DATABASE=KM400/KN400/P4M800 [S3 UniChrome]
+
+pci:v00001106d00007205sv00001458sd0000D000*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte GA-7VM400(A)M(F) Motherboard
+
+pci:v00001106d00007205sv00001462sd00007061*
+ ID_PRODUCT_FROM_DATABASE=MS-7061
+
+pci:v00001106d00007208*
+ ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge
+
+pci:v00001106d00007238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge
+
+pci:v00001106d00007258*
+ ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge
+
+pci:v00001106d00007259*
+ ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge
+
+pci:v00001106d00007269*
+ ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge
+
+pci:v00001106d00007282*
+ ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge
+
+pci:v00001106d00007290*
+ ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge
+
+pci:v00001106d00007293*
+ ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge
+
+pci:v00001106d00007296*
+ ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge
+
+pci:v00001106d00007308*
+ ID_PRODUCT_FROM_DATABASE=PT894 Host Bridge
+
+pci:v00001106d00007314*
+ ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge
+
+pci:v00001106d00007324*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge
+
+pci:v00001106d00007327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge
+
+pci:v00001106d00007336*
+ ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge
+
+pci:v00001106d00007340*
+ ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge
+
+pci:v00001106d00007351*
+ ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge
+
+pci:v00001106d00007353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 North-South Module Interface Control
+
+pci:v00001106d00007364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge
+
+pci:v00001106d00007409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 North-South Module Interface Control
+
+pci:v00001106d00007410*
+ ID_PRODUCT_FROM_DATABASE=VX900 North-South Module Interface Control
+
+pci:v00001106d00007410sv000019DAsd0000A179*
+ ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01
+
+pci:v00001106d00008231*
+ ID_PRODUCT_FROM_DATABASE=VT8231 [PCI-to-ISA Bridge]
+
+pci:v00001106d00008235*
+ ID_PRODUCT_FROM_DATABASE=VT8235 ACPI
+
+pci:v00001106d00008305*
+ ID_PRODUCT_FROM_DATABASE=VT8363/8365 [KT133/KM133 AGP]
+
+pci:v00001106d00008324*
+ ID_PRODUCT_FROM_DATABASE=CX700/VX700 PCI to ISA Bridge
+
+pci:v00001106d00008353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 Bus Control and Power Management
+
+pci:v00001106d00008391*
+ ID_PRODUCT_FROM_DATABASE=VT8371 [KX133 AGP]
+
+pci:v00001106d00008400*
+ ID_PRODUCT_FROM_DATABASE=MVP4
+
+pci:v00001106d00008409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 Bus Control and Power Management
+
+pci:v00001106d00008410*
+ ID_PRODUCT_FROM_DATABASE=VX900 Bus Control and Power Management
+
+pci:v00001106d00008410sv000019DAsd0000A179*
+ ID_PRODUCT_FROM_DATABASE=ZBOX VD01
+
+pci:v00001106d00008500*
+ ID_PRODUCT_FROM_DATABASE=KLE133/PLE133/PLE133T
+
+pci:v00001106d00008501*
+ ID_PRODUCT_FROM_DATABASE=VT8501 [Apollo MVP4 AGP]
+
+pci:v00001106d00008596*
+ ID_PRODUCT_FROM_DATABASE=VT82C596 [Apollo PRO AGP]
+
+pci:v00001106d00008597*
+ ID_PRODUCT_FROM_DATABASE=VT82C597 [Apollo VP3 AGP]
+
+pci:v00001106d00008598*
+ ID_PRODUCT_FROM_DATABASE=VT82C598/694x [Apollo MVP3/Pro133x AGP]
+
+pci:v00001106d00008598sv00001019sd00000985*
+ ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard
+
+pci:v00001106d00008601*
+ ID_PRODUCT_FROM_DATABASE=VT8601 [Apollo ProMedia AGP]
+
+pci:v00001106d00008605*
+ ID_PRODUCT_FROM_DATABASE=VT8605 [PM133 AGP]
+
+pci:v00001106d00008691*
+ ID_PRODUCT_FROM_DATABASE=VT82C691 [Apollo Pro]
+
+pci:v00001106d00008693*
+ ID_PRODUCT_FROM_DATABASE=VT82C693 [Apollo Pro Plus] PCI Bridge
+
+pci:v00001106d00008A25*
+ ID_PRODUCT_FROM_DATABASE=PL133/PL133T [S3 ProSavage]
+
+pci:v00001106d00008A26*
+ ID_PRODUCT_FROM_DATABASE=KL133/KL133A/KM133/KM133A [S3 ProSavage]
+
+pci:v00001106d00008D01*
+ ID_PRODUCT_FROM_DATABASE=PN133/PN133T [S3 Twister]
+
+pci:v00001106d00008D04*
+ ID_PRODUCT_FROM_DATABASE=KM266/P4M266/P4M266A/P4N266 [S3 ProSavageDDR]
+
+pci:v00001106d00009001*
+ ID_PRODUCT_FROM_DATABASE=VX900 Serial ATA Controller
+
+pci:v00001106d00009530*
+ ID_PRODUCT_FROM_DATABASE=Secure Digital Memory Card Controller
+
+pci:v00001106d000095D0*
+ ID_PRODUCT_FROM_DATABASE=SDIO Host Controller
+
+pci:v00001106d0000A208*
+ ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000A238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000A327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000A353*
+ ID_PRODUCT_FROM_DATABASE=VX8xx South-North Module Interface Control
+
+pci:v00001106d0000A364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 PCI to PCI Bridge Controller
+
+pci:v00001106d0000A409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 USB Device Controller
+
+pci:v00001106d0000B091*
+ ID_PRODUCT_FROM_DATABASE=VT8633 [Apollo Pro266 AGP]
+
+pci:v00001106d0000B099*
+ ID_PRODUCT_FROM_DATABASE=VT8366/A/7 [Apollo KT266/A/333 AGP]
+
+pci:v00001106d0000B101*
+ ID_PRODUCT_FROM_DATABASE=VT8653 AGP Bridge
+
+pci:v00001106d0000B102*
+ ID_PRODUCT_FROM_DATABASE=VT8362 AGP Bridge
+
+pci:v00001106d0000B103*
+ ID_PRODUCT_FROM_DATABASE=VT8615 AGP Bridge
+
+pci:v00001106d0000B112*
+ ID_PRODUCT_FROM_DATABASE=VT8361 [KLE133] AGP Bridge
+
+pci:v00001106d0000B113*
+ ID_PRODUCT_FROM_DATABASE=VPX/VPX2 I/O APIC Interrupt Controller
+
+pci:v00001106d0000B115*
+ ID_PRODUCT_FROM_DATABASE=VT8363/8365 [KT133/KM133] PCI Bridge
+
+pci:v00001106d0000B168*
+ ID_PRODUCT_FROM_DATABASE=VT8235 PCI Bridge
+
+pci:v00001106d0000B188*
+ ID_PRODUCT_FROM_DATABASE=VT8237/8251 PCI bridge [K8M890/K8T800/K8T890 South]
+
+pci:v00001106d0000B188sv0000147Bsd00001407*
+ ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard
+
+pci:v00001106d0000B198*
+ ID_PRODUCT_FROM_DATABASE=VT8237/VX700 PCI Bridge
+
+pci:v00001106d0000B213*
+ ID_PRODUCT_FROM_DATABASE=VPX/VPX2 I/O APIC Interrupt Controller
+
+pci:v00001106d0000B353*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875/VX900 PCI to PCI Bridge
+
+pci:v00001106d0000B999*
+ ID_PRODUCT_FROM_DATABASE=[K8T890 North / VT8237 South] PCI Bridge
+
+pci:v00001106d0000C208*
+ ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000C238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000C327*
+ ID_PRODUCT_FROM_DATABASE=P4M890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000C340*
+ ID_PRODUCT_FROM_DATABASE=PT900 PCI to PCI Bridge Controller
+
+pci:v00001106d0000C353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 PCI Express Root Port
+
+pci:v00001106d0000C364*
+ ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 PCI to PCI Bridge Controller
+
+pci:v00001106d0000C409*
+ ID_PRODUCT_FROM_DATABASE=VX855/VX875 EIDE Controller
+
+pci:v00001106d0000D104*
+ ID_PRODUCT_FROM_DATABASE=VT8237R USB UDCI Controller
+
+pci:v00001106d0000D208*
+ ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000D213*
+ ID_PRODUCT_FROM_DATABASE=VPX/VPX2 PCI to PCI Bridge Controller
+
+pci:v00001106d0000D238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000D340*
+ ID_PRODUCT_FROM_DATABASE=PT900 PCI to PCI Bridge Controller
+
+pci:v00001106d0000E208*
+ ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000E238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000E340*
+ ID_PRODUCT_FROM_DATABASE=PT900 PCI to PCI Bridge Controller
+
+pci:v00001106d0000E353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 PCI Express Root Port
+
+pci:v00001106d0000E721*
+ ID_PRODUCT_FROM_DATABASE=VT1708B 8-channel High Definition Audio CODEC
+
+pci:v00001106d0000F208*
+ ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000F238*
+ ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller
+
+pci:v00001106d0000F340*
+ ID_PRODUCT_FROM_DATABASE=PT900 PCI to PCI Bridge Controller
+
+pci:v00001106d0000F353*
+ ID_PRODUCT_FROM_DATABASE=VX800/VX820 PCI Express Root Port
+
+pci:v00001107*
+ ID_VENDOR_FROM_DATABASE=Stratus Computers
+
+pci:v00001107d00000576*
+ ID_PRODUCT_FROM_DATABASE=VIA VT82C570MV [Apollo] (Wrong vendor ID!)
+
+pci:v00001108*
+ ID_VENDOR_FROM_DATABASE=Proteon, Inc.
+
+pci:v00001108d00000100*
+ ID_PRODUCT_FROM_DATABASE=p1690plus_AA
+
+pci:v00001108d00000101*
+ ID_PRODUCT_FROM_DATABASE=p1690plus_AB
+
+pci:v00001108d00000105*
+ ID_PRODUCT_FROM_DATABASE=P1690Plus
+
+pci:v00001108d00000108*
+ ID_PRODUCT_FROM_DATABASE=P1690Plus
+
+pci:v00001108d00000138*
+ ID_PRODUCT_FROM_DATABASE=P1690Plus
+
+pci:v00001108d00000139*
+ ID_PRODUCT_FROM_DATABASE=P1690Plus
+
+pci:v00001108d0000013C*
+ ID_PRODUCT_FROM_DATABASE=P1690Plus
+
+pci:v00001108d0000013D*
+ ID_PRODUCT_FROM_DATABASE=P1690Plus
+
+pci:v00001109*
+ ID_VENDOR_FROM_DATABASE=Cogent Data Technologies, Inc.
+
+pci:v00001109d00001400*
+ ID_PRODUCT_FROM_DATABASE=EM110TX [EX110TX]
+
+pci:v0000110A*
+ ID_VENDOR_FROM_DATABASE=Siemens Nixdorf AG
+
+pci:v0000110Ad00000002*
+ ID_PRODUCT_FROM_DATABASE=Pirahna 2-port
+
+pci:v0000110Ad00000005*
+ ID_PRODUCT_FROM_DATABASE=Tulip controller, power management, switch extender
+
+pci:v0000110Ad00000006*
+ ID_PRODUCT_FROM_DATABASE=FSC PINC (I/O-APIC)
+
+pci:v0000110Ad00000015*
+ ID_PRODUCT_FROM_DATABASE=FSC Multiprocessor Interrupt Controller
+
+pci:v0000110Ad0000001D*
+ ID_PRODUCT_FROM_DATABASE=FSC Copernicus Management Controller
+
+pci:v0000110Ad0000007B*
+ ID_PRODUCT_FROM_DATABASE=FSC Remote Service Controller, mailbox device
+
+pci:v0000110Ad0000007C*
+ ID_PRODUCT_FROM_DATABASE=FSC Remote Service Controller, shared memory device
+
+pci:v0000110Ad0000007D*
+ ID_PRODUCT_FROM_DATABASE=FSC Remote Service Controller, SMIC device
+
+pci:v0000110Ad00002101*
+ ID_PRODUCT_FROM_DATABASE=HST SAPHIR V Primary PCI (ISDN/PMx)
+
+pci:v0000110Ad00002102*
+ ID_PRODUCT_FROM_DATABASE=DSCC4 PEB/PEF 20534 DMA Supported Serial Communication Controller with 4 Channels
+
+pci:v0000110Ad00002104*
+ ID_PRODUCT_FROM_DATABASE=Eicon Diva 2.02 compatible passive ISDN card
+
+pci:v0000110Ad00003141*
+ ID_PRODUCT_FROM_DATABASE=SIMATIC NET CP 5611 (Profibus Adapter)
+
+pci:v0000110Ad00003142*
+ ID_PRODUCT_FROM_DATABASE=SIMATIC NET CP 5613A1 (Profibus Adapter)
+
+pci:v0000110Ad00004021*
+ ID_PRODUCT_FROM_DATABASE=SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter)
+
+pci:v0000110Ad00004029*
+ ID_PRODUCT_FROM_DATABASE=SIMATIC NET CP 5613A2 (Profibus Adapter)
+
+pci:v0000110Ad00004942*
+ ID_PRODUCT_FROM_DATABASE=FPGA I-Bus Tracer for MBD
+
+pci:v0000110Ad00006120*
+ ID_PRODUCT_FROM_DATABASE=SZB6120
+
+pci:v0000110B*
+ ID_VENDOR_FROM_DATABASE=Chromatic Research Inc.
+
+pci:v0000110Bd00000001*
+ ID_PRODUCT_FROM_DATABASE=Mpact Media Processor
+
+pci:v0000110Bd00000004*
+ ID_PRODUCT_FROM_DATABASE=Mpact 2
+
+pci:v0000110C*
+ ID_VENDOR_FROM_DATABASE=Mini-Max Technology, Inc.
+
+pci:v0000110D*
+ ID_VENDOR_FROM_DATABASE=Znyx Advanced Systems
+
+pci:v0000110E*
+ ID_VENDOR_FROM_DATABASE=CPU Technology
+
+pci:v0000110F*
+ ID_VENDOR_FROM_DATABASE=Ross Technology
+
+pci:v00001110*
+ ID_VENDOR_FROM_DATABASE=Powerhouse Systems
+
+pci:v00001110d00006037*
+ ID_PRODUCT_FROM_DATABASE=Firepower Powerized SMP I/O ASIC
+
+pci:v00001110d00006073*
+ ID_PRODUCT_FROM_DATABASE=Firepower Powerized SMP I/O ASIC
+
+pci:v00001111*
+ ID_VENDOR_FROM_DATABASE=Santa Cruz Operation
+
+pci:v00001112*
+ ID_VENDOR_FROM_DATABASE=Osicom Technologies Inc
+
+pci:v00001112d00002200*
+ ID_PRODUCT_FROM_DATABASE=FDDI Adapter
+
+pci:v00001112d00002300*
+ ID_PRODUCT_FROM_DATABASE=Fast Ethernet Adapter
+
+pci:v00001112d00002340*
+ ID_PRODUCT_FROM_DATABASE=4 Port Fast Ethernet Adapter
+
+pci:v00001112d00002400*
+ ID_PRODUCT_FROM_DATABASE=ATM Adapter
+
+pci:v00001113*
+ ID_VENDOR_FROM_DATABASE=Accton Technology Corporation
+
+pci:v00001113d00001211*
+ ID_PRODUCT_FROM_DATABASE=SMC2-1211TX
+
+pci:v00001113d00001211sv0000103Csd00001207*
+ ID_PRODUCT_FROM_DATABASE=EN-1207D Fast Ethernet Adapter
+
+pci:v00001113d00001211sv00001113sd00001211*
+ ID_PRODUCT_FROM_DATABASE=EN-1207D Fast Ethernet Adapter
+
+pci:v00001113d00001216*
+ ID_PRODUCT_FROM_DATABASE=EN-1216 Ethernet Adapter
+
+pci:v00001113d00001216sv00001113sd00001216*
+ ID_PRODUCT_FROM_DATABASE=EN1207F series PCI Fast Ethernet Adapter
+
+pci:v00001113d00001216sv00001113sd00002220*
+ ID_PRODUCT_FROM_DATABASE=EN2220A Cardbus Fast Ethernet Adapter
+
+pci:v00001113d00001216sv00001113sd00002242*
+ ID_PRODUCT_FROM_DATABASE=EN2242 10/100 Ethernet Mini-PCI Card
+
+pci:v00001113d00001216sv0000111Asd00001020*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]
+
+pci:v00001113d00001217*
+ ID_PRODUCT_FROM_DATABASE=EN-1217 Ethernet Adapter
+
+pci:v00001113d00005105*
+ ID_PRODUCT_FROM_DATABASE=10Mbps Network card
+
+pci:v00001113d00009211*
+ ID_PRODUCT_FROM_DATABASE=EN-1207D Fast Ethernet Adapter
+
+pci:v00001113d00009211sv00001113sd00009211*
+ ID_PRODUCT_FROM_DATABASE=EN-1207D Fast Ethernet Adapter
+
+pci:v00001113d00009511*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible Fast Ethernet
+
+pci:v00001113d0000D301*
+ ID_PRODUCT_FROM_DATABASE=CPWNA100 (Philips wireless PCMCIA)
+
+pci:v00001113d0000EC02*
+ ID_PRODUCT_FROM_DATABASE=SMC 1244TX v3
+
+pci:v00001113d0000EE23*
+ ID_PRODUCT_FROM_DATABASE=SMCWPCIT-G 108Mbps Wireless PCI adapter
+
+pci:v00001114*
+ ID_VENDOR_FROM_DATABASE=Atmel Corporation
+
+pci:v00001114d00000506*
+ ID_PRODUCT_FROM_DATABASE=at76c506 802.11b Wireless Network Adaptor
+
+pci:v00001115*
+ ID_VENDOR_FROM_DATABASE=3D Labs
+
+pci:v00001116*
+ ID_VENDOR_FROM_DATABASE=Data Translation
+
+pci:v00001116d00000022*
+ ID_PRODUCT_FROM_DATABASE=DT3001
+
+pci:v00001116d00000023*
+ ID_PRODUCT_FROM_DATABASE=DT3002
+
+pci:v00001116d00000024*
+ ID_PRODUCT_FROM_DATABASE=DT3003
+
+pci:v00001116d00000025*
+ ID_PRODUCT_FROM_DATABASE=DT3004
+
+pci:v00001116d00000026*
+ ID_PRODUCT_FROM_DATABASE=DT3005
+
+pci:v00001116d00000027*
+ ID_PRODUCT_FROM_DATABASE=DT3001-PGL
+
+pci:v00001116d00000028*
+ ID_PRODUCT_FROM_DATABASE=DT3003-PGL
+
+pci:v00001116d00000051*
+ ID_PRODUCT_FROM_DATABASE=DT322
+
+pci:v00001116d00000060*
+ ID_PRODUCT_FROM_DATABASE=DT340
+
+pci:v00001116d00000069*
+ ID_PRODUCT_FROM_DATABASE=DT332
+
+pci:v00001116d000080C2*
+ ID_PRODUCT_FROM_DATABASE=DT3162
+
+pci:v00001117*
+ ID_VENDOR_FROM_DATABASE=Datacube, Inc
+
+pci:v00001117d00009500*
+ ID_PRODUCT_FROM_DATABASE=Max-1C SVGA card
+
+pci:v00001117d00009501*
+ ID_PRODUCT_FROM_DATABASE=Max-1C image processing
+
+pci:v00001118*
+ ID_VENDOR_FROM_DATABASE=Berg Electronics
+
+pci:v00001119*
+ ID_VENDOR_FROM_DATABASE=ICP Vortex Computersysteme GmbH
+
+pci:v00001119d00000000*
+ ID_PRODUCT_FROM_DATABASE=GDT 6000/6020/6050
+
+pci:v00001119d00000001*
+ ID_PRODUCT_FROM_DATABASE=GDT 6000B/6010
+
+pci:v00001119d00000002*
+ ID_PRODUCT_FROM_DATABASE=GDT 6110/6510
+
+pci:v00001119d00000003*
+ ID_PRODUCT_FROM_DATABASE=GDT 6120/6520
+
+pci:v00001119d00000004*
+ ID_PRODUCT_FROM_DATABASE=GDT 6530
+
+pci:v00001119d00000005*
+ ID_PRODUCT_FROM_DATABASE=GDT 6550
+
+pci:v00001119d00000006*
+ ID_PRODUCT_FROM_DATABASE=GDT 6117/6517
+
+pci:v00001119d00000007*
+ ID_PRODUCT_FROM_DATABASE=GDT 6127/6527
+
+pci:v00001119d00000008*
+ ID_PRODUCT_FROM_DATABASE=GDT 6537
+
+pci:v00001119d00000009*
+ ID_PRODUCT_FROM_DATABASE=GDT 6557/6557-ECC
+
+pci:v00001119d0000000A*
+ ID_PRODUCT_FROM_DATABASE=GDT 6115/6515
+
+pci:v00001119d0000000B*
+ ID_PRODUCT_FROM_DATABASE=GDT 6125/6525
+
+pci:v00001119d0000000C*
+ ID_PRODUCT_FROM_DATABASE=GDT 6535
+
+pci:v00001119d0000000D*
+ ID_PRODUCT_FROM_DATABASE=GDT 6555/6555-ECC
+
+pci:v00001119d00000100*
+ ID_PRODUCT_FROM_DATABASE=GDT 6117RP/6517RP
+
+pci:v00001119d00000101*
+ ID_PRODUCT_FROM_DATABASE=GDT 6127RP/6527RP
+
+pci:v00001119d00000102*
+ ID_PRODUCT_FROM_DATABASE=GDT 6537RP
+
+pci:v00001119d00000103*
+ ID_PRODUCT_FROM_DATABASE=GDT 6557RP
+
+pci:v00001119d00000104*
+ ID_PRODUCT_FROM_DATABASE=GDT 6111RP/6511RP
+
+pci:v00001119d00000105*
+ ID_PRODUCT_FROM_DATABASE=GDT 6121RP/6521RP
+
+pci:v00001119d00000110*
+ ID_PRODUCT_FROM_DATABASE=GDT 6117RD/6517RD
+
+pci:v00001119d00000111*
+ ID_PRODUCT_FROM_DATABASE=GDT 6127RD/6527RD
+
+pci:v00001119d00000112*
+ ID_PRODUCT_FROM_DATABASE=GDT 6537RD
+
+pci:v00001119d00000113*
+ ID_PRODUCT_FROM_DATABASE=GDT 6557RD
+
+pci:v00001119d00000114*
+ ID_PRODUCT_FROM_DATABASE=GDT 6111RD/6511RD
+
+pci:v00001119d00000115*
+ ID_PRODUCT_FROM_DATABASE=GDT 6121RD/6521RD
+
+pci:v00001119d00000118*
+ ID_PRODUCT_FROM_DATABASE=GDT 6118RD/6518RD/6618RD
+
+pci:v00001119d00000119*
+ ID_PRODUCT_FROM_DATABASE=GDT 6128RD/6528RD/6628RD
+
+pci:v00001119d0000011A*
+ ID_PRODUCT_FROM_DATABASE=GDT 6538RD/6638RD
+
+pci:v00001119d0000011B*
+ ID_PRODUCT_FROM_DATABASE=GDT 6558RD/6658RD
+
+pci:v00001119d00000120*
+ ID_PRODUCT_FROM_DATABASE=GDT 6117RP2/6517RP2
+
+pci:v00001119d00000121*
+ ID_PRODUCT_FROM_DATABASE=GDT 6127RP2/6527RP2
+
+pci:v00001119d00000122*
+ ID_PRODUCT_FROM_DATABASE=GDT 6537RP2
+
+pci:v00001119d00000123*
+ ID_PRODUCT_FROM_DATABASE=GDT 6557RP2
+
+pci:v00001119d00000124*
+ ID_PRODUCT_FROM_DATABASE=GDT 6111RP2/6511RP2
+
+pci:v00001119d00000125*
+ ID_PRODUCT_FROM_DATABASE=GDT 6121RP2/6521RP2
+
+pci:v00001119d00000136*
+ ID_PRODUCT_FROM_DATABASE=GDT 6113RS/6513RS
+
+pci:v00001119d00000137*
+ ID_PRODUCT_FROM_DATABASE=GDT 6123RS/6523RS
+
+pci:v00001119d00000138*
+ ID_PRODUCT_FROM_DATABASE=GDT 6118RS/6518RS/6618RS
+
+pci:v00001119d00000139*
+ ID_PRODUCT_FROM_DATABASE=GDT 6128RS/6528RS/6628RS
+
+pci:v00001119d0000013A*
+ ID_PRODUCT_FROM_DATABASE=GDT 6538RS/6638RS
+
+pci:v00001119d0000013B*
+ ID_PRODUCT_FROM_DATABASE=GDT 6558RS/6658RS
+
+pci:v00001119d0000013C*
+ ID_PRODUCT_FROM_DATABASE=GDT 6533RS/6633RS
+
+pci:v00001119d0000013D*
+ ID_PRODUCT_FROM_DATABASE=GDT 6543RS/6643RS
+
+pci:v00001119d0000013E*
+ ID_PRODUCT_FROM_DATABASE=GDT 6553RS/6653RS
+
+pci:v00001119d0000013F*
+ ID_PRODUCT_FROM_DATABASE=GDT 6563RS/6663RS
+
+pci:v00001119d00000166*
+ ID_PRODUCT_FROM_DATABASE=GDT 7113RN/7513RN/7613RN
+
+pci:v00001119d00000167*
+ ID_PRODUCT_FROM_DATABASE=GDT 7123RN/7523RN/7623RN
+
+pci:v00001119d00000168*
+ ID_PRODUCT_FROM_DATABASE=GDT 7118RN/7518RN/7518RN
+
+pci:v00001119d00000169*
+ ID_PRODUCT_FROM_DATABASE=GDT 7128RN/7528RN/7628RN
+
+pci:v00001119d0000016A*
+ ID_PRODUCT_FROM_DATABASE=GDT 7538RN/7638RN
+
+pci:v00001119d0000016B*
+ ID_PRODUCT_FROM_DATABASE=GDT 7558RN/7658RN
+
+pci:v00001119d0000016C*
+ ID_PRODUCT_FROM_DATABASE=GDT 7533RN/7633RN
+
+pci:v00001119d0000016D*
+ ID_PRODUCT_FROM_DATABASE=GDT 7543RN/7643RN
+
+pci:v00001119d0000016E*
+ ID_PRODUCT_FROM_DATABASE=GDT 7553RN/7653RN
+
+pci:v00001119d0000016F*
+ ID_PRODUCT_FROM_DATABASE=GDT 7563RN/7663RN
+
+pci:v00001119d000001D6*
+ ID_PRODUCT_FROM_DATABASE=GDT 4x13RZ
+
+pci:v00001119d000001D7*
+ ID_PRODUCT_FROM_DATABASE=GDT 4x23RZ
+
+pci:v00001119d000001F6*
+ ID_PRODUCT_FROM_DATABASE=GDT 8x13RZ
+
+pci:v00001119d000001F7*
+ ID_PRODUCT_FROM_DATABASE=GDT 8x23RZ
+
+pci:v00001119d000001FC*
+ ID_PRODUCT_FROM_DATABASE=GDT 8x33RZ
+
+pci:v00001119d000001FD*
+ ID_PRODUCT_FROM_DATABASE=GDT 8x43RZ
+
+pci:v00001119d000001FE*
+ ID_PRODUCT_FROM_DATABASE=GDT 8x53RZ
+
+pci:v00001119d000001FF*
+ ID_PRODUCT_FROM_DATABASE=GDT 8x63RZ
+
+pci:v00001119d00000210*
+ ID_PRODUCT_FROM_DATABASE=GDT 6519RD/6619RD
+
+pci:v00001119d00000211*
+ ID_PRODUCT_FROM_DATABASE=GDT 6529RD/6629RD
+
+pci:v00001119d00000260*
+ ID_PRODUCT_FROM_DATABASE=GDT 7519RN/7619RN
+
+pci:v00001119d00000261*
+ ID_PRODUCT_FROM_DATABASE=GDT 7529RN/7629RN
+
+pci:v00001119d000002FF*
+ ID_PRODUCT_FROM_DATABASE=GDT MAXRP
+
+pci:v00001119d00000300*
+ ID_PRODUCT_FROM_DATABASE=GDT NEWRX
+
+pci:v00001119d00000301*
+ ID_PRODUCT_FROM_DATABASE=GDT NEWRX2
+
+pci:v0000111A*
+ ID_VENDOR_FROM_DATABASE=Efficient Networks, Inc
+
+pci:v0000111Ad00000000*
+ ID_PRODUCT_FROM_DATABASE=155P-MF1 (FPGA)
+
+pci:v0000111Ad00000002*
+ ID_PRODUCT_FROM_DATABASE=155P-MF1 (ASIC)
+
+pci:v0000111Ad00000003*
+ ID_PRODUCT_FROM_DATABASE=ENI-25P ATM
+
+pci:v0000111Ad00000003sv0000111Asd00000000*
+ ID_PRODUCT_FROM_DATABASE=ENI-25p Miniport ATM Adapter
+
+pci:v0000111Ad00000005*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream (LANAI)
+
+pci:v0000111Ad00000005sv0000111Asd00000001*
+ ID_PRODUCT_FROM_DATABASE=ENI-3010 ATM
+
+pci:v0000111Ad00000005sv0000111Asd00000009*
+ ID_PRODUCT_FROM_DATABASE=ENI-3060 ADSL (VPI=0)
+
+pci:v0000111Ad00000005sv0000111Asd00000101*
+ ID_PRODUCT_FROM_DATABASE=ENI-3010 ATM
+
+pci:v0000111Ad00000005sv0000111Asd00000109*
+ ID_PRODUCT_FROM_DATABASE=ENI-3060CO ADSL (VPI=0)
+
+pci:v0000111Ad00000005sv0000111Asd00000809*
+ ID_PRODUCT_FROM_DATABASE=ENI-3060 ADSL (VPI=0 or 8)
+
+pci:v0000111Ad00000005sv0000111Asd00000909*
+ ID_PRODUCT_FROM_DATABASE=ENI-3060CO ADSL (VPI=0 or 8)
+
+pci:v0000111Ad00000005sv0000111Asd00000A09*
+ ID_PRODUCT_FROM_DATABASE=ENI-3060 ADSL (VPI=<0..15>)
+
+pci:v0000111Ad00000007*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream ADSL
+
+pci:v0000111Ad00000007sv0000111Asd00001001*
+ ID_PRODUCT_FROM_DATABASE=ENI-3061 ADSL [ASIC]
+
+pci:v0000111Ad00001020*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream PCI 10/100 Network Card
+
+pci:v0000111Ad00001203*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 1023 Wireless PCI Adapter
+
+pci:v0000111B*
+ ID_VENDOR_FROM_DATABASE=Teledyne Electronic Systems
+
+pci:v0000111C*
+ ID_VENDOR_FROM_DATABASE=Tricord Systems Inc.
+
+pci:v0000111Cd00000001*
+ ID_PRODUCT_FROM_DATABASE=Powerbis Bridge
+
+pci:v0000111D*
+ ID_VENDOR_FROM_DATABASE=Integrated Device Technology, Inc.
+
+pci:v0000111Dd00000001*
+ ID_PRODUCT_FROM_DATABASE=IDT77201/77211 155Mbps ATM SAR Controller [NICStAR]
+
+pci:v0000111Dd00000003*
+ ID_PRODUCT_FROM_DATABASE=IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller
+
+pci:v0000111Dd00000004*
+ ID_PRODUCT_FROM_DATABASE=IDT77V252 155Mbps ATM MICRO ABR SAR Controller
+
+pci:v0000111Dd00000005*
+ ID_PRODUCT_FROM_DATABASE=IDT77V222 155Mbps ATM MICRO ABR SAR Controller
+
+pci:v0000111Dd00008018*
+ ID_PRODUCT_FROM_DATABASE=PES12N3A PCI Express Switch
+
+pci:v0000111Dd0000801C*
+ ID_PRODUCT_FROM_DATABASE=PES24N3A PCI Express Switch
+
+pci:v0000111Dd00008028*
+ ID_PRODUCT_FROM_DATABASE=PES4T4 PCI Express Switch
+
+pci:v0000111Dd0000802B*
+ ID_PRODUCT_FROM_DATABASE=PES8T5A PCI Express Switch
+
+pci:v0000111Dd0000802C*
+ ID_PRODUCT_FROM_DATABASE=PES16T4 PCI Express Switch
+
+pci:v0000111Dd0000802D*
+ ID_PRODUCT_FROM_DATABASE=PES16T7 PCI Express Switch
+
+pci:v0000111Dd0000802E*
+ ID_PRODUCT_FROM_DATABASE=PES24T6 PCI Express Switch
+
+pci:v0000111Dd0000802F*
+ ID_PRODUCT_FROM_DATABASE=PES32T8 PCI Express Switch
+
+pci:v0000111Dd00008032*
+ ID_PRODUCT_FROM_DATABASE=PES48T12 PCI Express Switch
+
+pci:v0000111Dd00008034*
+ ID_PRODUCT_FROM_DATABASE=PES16/22/34H16 PCI Express Switch
+
+pci:v0000111Dd00008035*
+ ID_PRODUCT_FROM_DATABASE=PES32H8 PCI Express Switch
+
+pci:v0000111Dd00008036*
+ ID_PRODUCT_FROM_DATABASE=PES48H12 PCI Express Switch
+
+pci:v0000111Dd00008037*
+ ID_PRODUCT_FROM_DATABASE=PES64H16 PCI Express Switch
+
+pci:v0000111Dd00008039*
+ ID_PRODUCT_FROM_DATABASE=PES3T3 PCI Express Switch
+
+pci:v0000111Dd0000803A*
+ ID_PRODUCT_FROM_DATABASE=PES4T4 PCI Express Switch
+
+pci:v0000111Dd0000803C*
+ ID_PRODUCT_FROM_DATABASE=PES5T5 PCI Express Switch
+
+pci:v0000111Dd0000803D*
+ ID_PRODUCT_FROM_DATABASE=PES6T5 PCI Express Switch
+
+pci:v0000111Dd00008048*
+ ID_PRODUCT_FROM_DATABASE=PES8NT2 PCI Express Switch
+
+pci:v0000111Dd00008049*
+ ID_PRODUCT_FROM_DATABASE=PES8NT2 PCI Express Switch
+
+pci:v0000111Dd0000804A*
+ ID_PRODUCT_FROM_DATABASE=PES8NT2 PCI Express Internal NTB
+
+pci:v0000111Dd0000804B*
+ ID_PRODUCT_FROM_DATABASE=PES8NT2 PCI Express External NTB
+
+pci:v0000111Dd0000804C*
+ ID_PRODUCT_FROM_DATABASE=PES16NT2 PCI Express Switch
+
+pci:v0000111Dd0000804D*
+ ID_PRODUCT_FROM_DATABASE=PES16NT2 PCI Express Switch
+
+pci:v0000111Dd0000804E*
+ ID_PRODUCT_FROM_DATABASE=PES16NT2 PCI Express Internal NTB
+
+pci:v0000111Dd0000804F*
+ ID_PRODUCT_FROM_DATABASE=PES16NT2 PCI Express External NTB
+
+pci:v0000111Dd00008058*
+ ID_PRODUCT_FROM_DATABASE=PES12NT3 PCI Express Switch
+
+pci:v0000111Dd00008059*
+ ID_PRODUCT_FROM_DATABASE=PES12NT3 PCI Express Switch
+
+pci:v0000111Dd0000805A*
+ ID_PRODUCT_FROM_DATABASE=PES12NT3 PCI Express Internal NTB
+
+pci:v0000111Dd0000805B*
+ ID_PRODUCT_FROM_DATABASE=PES12NT3 PCI Express External NTB
+
+pci:v0000111Dd0000805C*
+ ID_PRODUCT_FROM_DATABASE=PES24NT3 PCI Express Switch
+
+pci:v0000111Dd0000805D*
+ ID_PRODUCT_FROM_DATABASE=PES24NT3 PCI Express Switch
+
+pci:v0000111Dd0000805E*
+ ID_PRODUCT_FROM_DATABASE=PES24NT3 PCI Express Internal NTB
+
+pci:v0000111Dd0000805F*
+ ID_PRODUCT_FROM_DATABASE=PES24NT3 PCI Express External NTB
+
+pci:v0000111Dd00008060*
+ ID_PRODUCT_FROM_DATABASE=PES16T4G2 PCI Express Gen2 Switch
+
+pci:v0000111Dd00008061*
+ ID_PRODUCT_FROM_DATABASE=PES12T3G2 PCI Express Gen2 Switch
+
+pci:v0000111Dd00008068*
+ ID_PRODUCT_FROM_DATABASE=PES6T6G2 PCI Express Gen2 Switch
+
+pci:v0000111Dd0000806A*
+ ID_PRODUCT_FROM_DATABASE=PES24T3G2 PCI Express Gen2 Switch
+
+pci:v0000111Dd0000806Asv000014C1sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=10G-PCIE2-8B2
+
+pci:v0000111Dd0000806C*
+ ID_PRODUCT_FROM_DATABASE=PES16T4A/4T4G2 PCI Express Gen2 Switch
+
+pci:v0000111Dd0000806E*
+ ID_PRODUCT_FROM_DATABASE=PES24T6G2 PCI Express Gen2 Switch
+
+pci:v0000111Dd0000806F*
+ ID_PRODUCT_FROM_DATABASE=HIO524G2 PCI Express Gen2 Switch
+
+pci:v0000111E*
+ ID_VENDOR_FROM_DATABASE=Eldec
+
+pci:v0000111F*
+ ID_VENDOR_FROM_DATABASE=Precision Digital Images
+
+pci:v0000111Fd00004A47*
+ ID_PRODUCT_FROM_DATABASE=Precision MX Video engine interface
+
+pci:v0000111Fd00005243*
+ ID_PRODUCT_FROM_DATABASE=Frame capture bus interface
+
+pci:v00001120*
+ ID_VENDOR_FROM_DATABASE=EMC Corporation
+
+pci:v00001121*
+ ID_VENDOR_FROM_DATABASE=Zilog
+
+pci:v00001122*
+ ID_VENDOR_FROM_DATABASE=Multi-tech Systems, Inc.
+
+pci:v00001123*
+ ID_VENDOR_FROM_DATABASE=Excellent Design, Inc.
+
+pci:v00001124*
+ ID_VENDOR_FROM_DATABASE=Leutron Vision AG
+
+pci:v00001124d00002581*
+ ID_PRODUCT_FROM_DATABASE=Picport Monochrome
+
+pci:v00001125*
+ ID_VENDOR_FROM_DATABASE=Eurocore
+
+pci:v00001126*
+ ID_VENDOR_FROM_DATABASE=Vigra
+
+pci:v00001127*
+ ID_VENDOR_FROM_DATABASE=FORE Systems Inc
+
+pci:v00001127d00000200*
+ ID_PRODUCT_FROM_DATABASE=ForeRunner PCA-200 ATM
+
+pci:v00001127d00000210*
+ ID_PRODUCT_FROM_DATABASE=PCA-200PC
+
+pci:v00001127d00000250*
+ ID_PRODUCT_FROM_DATABASE=ATM
+
+pci:v00001127d00000300*
+ ID_PRODUCT_FROM_DATABASE=ForeRunner PCA-200EPC ATM
+
+pci:v00001127d00000310*
+ ID_PRODUCT_FROM_DATABASE=ATM
+
+pci:v00001127d00000400*
+ ID_PRODUCT_FROM_DATABASE=ForeRunnerHE ATM Adapter
+
+pci:v00001127d00000400sv00001127sd00000400*
+ ID_PRODUCT_FROM_DATABASE=ForeRunnerHE ATM
+
+pci:v00001129*
+ ID_VENDOR_FROM_DATABASE=Firmworks
+
+pci:v0000112A*
+ ID_VENDOR_FROM_DATABASE=Hermes Electronics Company, Ltd.
+
+pci:v0000112B*
+ ID_VENDOR_FROM_DATABASE=Linotype - Hell AG
+
+pci:v0000112C*
+ ID_VENDOR_FROM_DATABASE=Zenith Data Systems
+
+pci:v0000112D*
+ ID_VENDOR_FROM_DATABASE=Ravicad
+
+pci:v0000112E*
+ ID_VENDOR_FROM_DATABASE=Infomedia Microelectronics Inc.
+
+pci:v0000112F*
+ ID_VENDOR_FROM_DATABASE=Dalsa Inc.
+
+pci:v0000112Fd00000000*
+ ID_PRODUCT_FROM_DATABASE=MVC IC-PCI
+
+pci:v0000112Fd00000001*
+ ID_PRODUCT_FROM_DATABASE=MVC IM-PCI Video frame grabber/processor
+
+pci:v0000112Fd00000008*
+ ID_PRODUCT_FROM_DATABASE=PC-CamLink PCI framegrabber
+
+pci:v00001130*
+ ID_VENDOR_FROM_DATABASE=Computervision
+
+pci:v00001131*
+ ID_VENDOR_FROM_DATABASE=Philips Semiconductors
+
+pci:v00001131d00001561*
+ ID_PRODUCT_FROM_DATABASE=USB 1.1 Host Controller
+
+pci:v00001131d00001561sv00001775sd0000C200*
+ ID_PRODUCT_FROM_DATABASE=C2K onboard USB 1.1 host controller
+
+pci:v00001131d00001562*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Host Controller
+
+pci:v00001131d00001562sv00001775sd0000C200*
+ ID_PRODUCT_FROM_DATABASE=C2K onboard USB 2.0 host controller
+
+pci:v00001131d00003400*
+ ID_PRODUCT_FROM_DATABASE=SmartPCI56(UCB1500) 56K Modem
+
+pci:v00001131d00005400*
+ ID_PRODUCT_FROM_DATABASE=TriMedia TM1000/1100
+
+pci:v00001131d00005400sv000012CAsd00000000*
+ ID_PRODUCT_FROM_DATABASE=BlueICE
+
+pci:v00001131d00005402*
+ ID_PRODUCT_FROM_DATABASE=TriMedia TM1300
+
+pci:v00001131d00005402sv00001244sd00000F00*
+ ID_PRODUCT_FROM_DATABASE=Fritz!Card DSL
+
+pci:v00001131d00005402sv000015EBsd00001300*
+ ID_PRODUCT_FROM_DATABASE=DT1300
+
+pci:v00001131d00005402sv000015EBsd00001302*
+ ID_PRODUCT_FROM_DATABASE=DT1302
+
+pci:v00001131d00005402sv000015EBsd00001304*
+ ID_PRODUCT_FROM_DATABASE=DT1304
+
+pci:v00001131d00005402sv000015EBsd00001305*
+ ID_PRODUCT_FROM_DATABASE=DT1305
+
+pci:v00001131d00005402sv000015EBsd00001306*
+ ID_PRODUCT_FROM_DATABASE=PMCDT1306
+
+pci:v00001131d00005402sv000015EBsd00001308*
+ ID_PRODUCT_FROM_DATABASE=DT1308
+
+pci:v00001131d00005402sv000015EBsd00001331*
+ ID_PRODUCT_FROM_DATABASE=DT1301 with SAA7121
+
+pci:v00001131d00005402sv000015EBsd00001337*
+ ID_PRODUCT_FROM_DATABASE=DT1301 with SAA7127
+
+pci:v00001131d00005402sv000015EBsd00002D3D*
+ ID_PRODUCT_FROM_DATABASE=X3D
+
+pci:v00001131d00005402sv000015EBsd00007022*
+ ID_PRODUCT_FROM_DATABASE=PTM1300
+
+pci:v00001131d00005405*
+ ID_PRODUCT_FROM_DATABASE=TriMedia TM1500
+
+pci:v00001131d00005405sv00001136sd00000005*
+ ID_PRODUCT_FROM_DATABASE=LCP-1500
+
+pci:v00001131d00005406*
+ ID_PRODUCT_FROM_DATABASE=TriMedia TM1700
+
+pci:v00001131d0000540B*
+ ID_PRODUCT_FROM_DATABASE=PNX1005 Media Processor
+
+pci:v00001131d0000540Bsv00001131sd00000020*
+ ID_PRODUCT_FROM_DATABASE=PNXLite PCI Demo Board
+
+pci:v00001131d00007130*
+ ID_PRODUCT_FROM_DATABASE=SAA7130 Video Broadcast Decoder
+
+pci:v00001131d00007130sv00000000sd00004016*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 401
+
+pci:v00001131d00007130sv00000000sd00004051*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 405 FM
+
+pci:v00001131d00007130sv00000000sd00005051*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 505 RDS
+
+pci:v00001131d00007130sv00000000sd0000505B*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 505 RDS
+
+pci:v00001131d00007130sv0000102Bsd000048D0*
+ ID_PRODUCT_FROM_DATABASE=Matrox CronosPlus
+
+pci:v00001131d00007130sv00001048sd0000226B*
+ ID_PRODUCT_FROM_DATABASE=ELSA EX-VISION 300TV
+
+pci:v00001131d00007130sv0000107Dsd00006655*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV1000S
+
+pci:v00001131d00007130sv00001131sd00000000*
+ ID_PRODUCT_FROM_DATABASE=SAA7130-based TV tuner card
+
+pci:v00001131d00007130sv00001131sd00002001*
+ ID_PRODUCT_FROM_DATABASE=10MOONS PCI TV CAPTURE CARD
+
+pci:v00001131d00007130sv00001131sd00002005*
+ ID_PRODUCT_FROM_DATABASE=Techcom (India) TV Tuner Card (SSD-TV-670)
+
+pci:v00001131d00007130sv00001458sd00009006*
+ ID_PRODUCT_FROM_DATABASE=GT-PS700 DVB-S tuner
+
+pci:v00001131d00007130sv00001461sd0000050C*
+ ID_PRODUCT_FROM_DATABASE=Nagase Sangyo TransGear 3000TV
+
+pci:v00001131d00007130sv00001461sd000010FF*
+ ID_PRODUCT_FROM_DATABASE=AVerMedia DVD EZMaker
+
+pci:v00001131d00007130sv00001461sd00002108*
+ ID_PRODUCT_FROM_DATABASE=AverMedia AverTV/305
+
+pci:v00001131d00007130sv00001461sd00002115*
+ ID_PRODUCT_FROM_DATABASE=AverMedia AverTV Studio 305
+
+pci:v00001131d00007130sv0000153Bsd00001152*
+ ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 200 TV
+
+pci:v00001131d00007130sv0000185Bsd0000C100*
+ ID_PRODUCT_FROM_DATABASE=Compro VideoMate TV PVR/FM
+
+pci:v00001131d00007130sv0000185Bsd0000C901*
+ ID_PRODUCT_FROM_DATABASE=Videomate DVB-T200
+
+pci:v00001131d00007130sv00005168sd00000138*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyVIDEO2000
+
+pci:v00001131d00007130sv00005ACEsd00005010*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 501
+
+pci:v00001131d00007130sv00005ACEsd00005050*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 505 FM
+
+pci:v00001131d00007133*
+ ID_PRODUCT_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder
+
+pci:v00001131d00007133sv00000000sd00004091*
+ ID_PRODUCT_FROM_DATABASE=Beholder BeholdTV 409 FM
+
+pci:v00001131d00007133sv00000000sd00005071*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 507 RDS
+
+pci:v00001131d00007133sv00000000sd0000507B*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 507 RDS
+
+pci:v00001131d00007133sv00000000sd00005201*
+ ID_PRODUCT_FROM_DATABASE=Behold TV Columbus
+
+pci:v00001131d00007133sv00000070sd00006701*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-1110
+
+pci:v00001131d00007133sv00001019sd00004CB5*
+ ID_PRODUCT_FROM_DATABASE=Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)
+
+pci:v00001131d00007133sv00001043sd00000210*
+ ID_PRODUCT_FROM_DATABASE=FlyTV mini Asus Digimatrix
+
+pci:v00001131d00007133sv00001043sd00004843*
+ ID_PRODUCT_FROM_DATABASE=ASUS TV-FM 7133
+
+pci:v00001131d00007133sv00001043sd00004845*
+ ID_PRODUCT_FROM_DATABASE=TV-FM 7135
+
+pci:v00001131d00007133sv00001043sd00004862*
+ ID_PRODUCT_FROM_DATABASE=P7131 Dual
+
+pci:v00001131d00007133sv00001043sd00004876*
+ ID_PRODUCT_FROM_DATABASE=My Cinema-P7131 Hybrid
+
+pci:v00001131d00007133sv00001131sd00000000*
+ ID_PRODUCT_FROM_DATABASE=SAA713x-based TV tuner card
+
+pci:v00001131d00007133sv00001131sd00002001*
+ ID_PRODUCT_FROM_DATABASE=Proteus Pro [philips reference design]
+
+pci:v00001131d00007133sv00001131sd00002018*
+ ID_PRODUCT_FROM_DATABASE=Tiger reference design
+
+pci:v00001131d00007133sv00001131sd00004EE9*
+ ID_PRODUCT_FROM_DATABASE=MonsterTV Mobile
+
+pci:v00001131d00007133sv00001131sd00007133*
+ ID_PRODUCT_FROM_DATABASE=Pinnacle PCTV 301i
+
+pci:v00001131d00007133sv000011BDsd0000002B*
+ ID_PRODUCT_FROM_DATABASE=PCTV Stereo
+
+pci:v00001131d00007133sv000011BDsd0000002E*
+ ID_PRODUCT_FROM_DATABASE=PCTV 110i (saa7133)
+
+pci:v00001131d00007133sv000012ABsd00000800*
+ ID_PRODUCT_FROM_DATABASE=PURPLE TV
+
+pci:v00001131d00007133sv000013C2sd00002804*
+ ID_PRODUCT_FROM_DATABASE=Technotrend Budget T-3000 Hybrid
+
+pci:v00001131d00007133sv00001421sd00000335*
+ ID_PRODUCT_FROM_DATABASE=Instant TV DVB-T Cardbus
+
+pci:v00001131d00007133sv00001421sd00001370*
+ ID_PRODUCT_FROM_DATABASE=Instant TV (saa7135)
+
+pci:v00001131d00007133sv00001435sd00007330*
+ ID_PRODUCT_FROM_DATABASE=VFG7330
+
+pci:v00001131d00007133sv00001435sd00007350*
+ ID_PRODUCT_FROM_DATABASE=VFG7350
+
+pci:v00001131d00007133sv00001458sd00009002*
+ ID_PRODUCT_FROM_DATABASE=GT-PTV-TAF-RH DVB-T/Analog TV/FM tuner
+
+pci:v00001131d00007133sv00001458sd00009003*
+ ID_PRODUCT_FROM_DATABASE=GT-PTV-AF-RH Analog TV/FM tuner
+
+pci:v00001131d00007133sv00001458sd00009004*
+ ID_PRODUCT_FROM_DATABASE=GT-P8000 DVB-T/Analog TV/FM tuner
+
+pci:v00001131d00007133sv00001458sd00009005*
+ ID_PRODUCT_FROM_DATABASE=GT-P6000 Analog TV/FM tuner
+
+pci:v00001131d00007133sv00001458sd00009008*
+ ID_PRODUCT_FROM_DATABASE=GT-P5100 Analog TV tuner
+
+pci:v00001131d00007133sv00001461sd00001044*
+ ID_PRODUCT_FROM_DATABASE=AVerTVHD MCE A180
+
+pci:v00001131d00007133sv00001461sd00004836*
+ ID_PRODUCT_FROM_DATABASE=M10D Hybrid DVBT
+
+pci:v00001131d00007133sv00001461sd0000861E*
+ ID_PRODUCT_FROM_DATABASE=M105 PAL/SECAM/NTSC/FM Tuner
+
+pci:v00001131d00007133sv00001461sd0000A14B*
+ ID_PRODUCT_FROM_DATABASE=AVerTV Studio 509
+
+pci:v00001131d00007133sv00001461sd0000A836*
+ ID_PRODUCT_FROM_DATABASE=M115 DVB-T, PAL/SECAM/NTSC Tuner
+
+pci:v00001131d00007133sv00001461sd0000F01D*
+ ID_PRODUCT_FROM_DATABASE=DVB-T Super 007
+
+pci:v00001131d00007133sv00001461sd0000F31F*
+ ID_PRODUCT_FROM_DATABASE=Avermedia AVerTV GO 007 FM
+
+pci:v00001131d00007133sv00001461sd0000F936*
+ ID_PRODUCT_FROM_DATABASE=Hybrid+FM PCI (rev A16D)
+
+pci:v00001131d00007133sv00001462sd00006231*
+ ID_PRODUCT_FROM_DATABASE=TV@nywhere Plus
+
+pci:v00001131d00007133sv00001489sd00000214*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyTV Platinum FM
+
+pci:v00001131d00007133sv000014C0sd00001212*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyTV Platinum Mini2
+
+pci:v00001131d00007133sv0000153Bsd00001160*
+ ID_PRODUCT_FROM_DATABASE=Cinergy 250 PCI TV
+
+pci:v00001131d00007133sv0000153Bsd00001162*
+ ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 400 mobile
+
+pci:v00001131d00007133sv000017DEsd00007350*
+ ID_PRODUCT_FROM_DATABASE=ATSC 110 Digital / Analog HDTV Tuner
+
+pci:v00001131d00007133sv000017DEsd00007352*
+ ID_PRODUCT_FROM_DATABASE=ATSC 115 Digital / Analog HDTV Tuner
+
+pci:v00001131d00007133sv0000185Bsd0000C100*
+ ID_PRODUCT_FROM_DATABASE=VideoMate TV
+
+pci:v00001131d00007133sv0000185Bsd0000C900*
+ ID_PRODUCT_FROM_DATABASE=VideoMate T750
+
+pci:v00001131d00007133sv00005168sd00000306*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-T DUO
+
+pci:v00001131d00007133sv00005168sd00000319*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB Trio
+
+pci:v00001131d00007133sv00005168sd00000502*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-T Duo CardBus
+
+pci:v00001131d00007133sv00005168sd00000520*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB Trio CardBus
+
+pci:v00001131d00007133sv00005168sd00001502*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyTV CardBus
+
+pci:v00001131d00007133sv00005168sd00002502*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-T CardBus
+
+pci:v00001131d00007133sv00005168sd00002520*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-S Duo CardBus
+
+pci:v00001131d00007133sv00005168sd00003502*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-T Hybrid CardBus
+
+pci:v00001131d00007133sv00005168sd00003520*
+ ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB Trio N CardBus
+
+pci:v00001131d00007133sv00005ACEsd00005030*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 503 FM
+
+pci:v00001131d00007133sv00005ACEsd00005090*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 509 FM
+
+pci:v00001131d00007133sv00005ACEsd00006090*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 609 FM
+
+pci:v00001131d00007133sv00005ACEsd00006091*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 609 FM
+
+pci:v00001131d00007133sv00005ACEsd00006092*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 609 RDS
+
+pci:v00001131d00007133sv00005ACEsd00006093*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 609 RDS
+
+pci:v00001131d00007133sv00005ACEsd00006190*
+ ID_PRODUCT_FROM_DATABASE=Behold TV M6
+
+pci:v00001131d00007133sv00005ACEsd00006191*
+ ID_PRODUCT_FROM_DATABASE=Behold TV M63
+
+pci:v00001131d00007133sv00005ACEsd00006193*
+ ID_PRODUCT_FROM_DATABASE=Behold TV M6 Extra
+
+pci:v00001131d00007133sv00005ACEsd00006290*
+ ID_PRODUCT_FROM_DATABASE=Behold TV H6
+
+pci:v00001131d00007133sv00005ACEsd00007090*
+ ID_PRODUCT_FROM_DATABASE=Behold TV A7
+
+pci:v00001131d00007133sv00005ACEsd00007190*
+ ID_PRODUCT_FROM_DATABASE=Behold TV H7
+
+pci:v00001131d00007133sv00005ACEsd00007595*
+ ID_PRODUCT_FROM_DATABASE=Behold TV X7
+
+pci:v00001131d00007134*
+ ID_PRODUCT_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder
+
+pci:v00001131d00007134sv00000000sd00004036*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 403
+
+pci:v00001131d00007134sv00000000sd00004037*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 403 FM
+
+pci:v00001131d00007134sv00000000sd00004071*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 407 FM
+
+pci:v00001131d00007134sv00001019sd00004CB4*
+ ID_PRODUCT_FROM_DATABASE=Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM)
+
+pci:v00001131d00007134sv00001043sd00000210*
+ ID_PRODUCT_FROM_DATABASE=Digimatrix TV
+
+pci:v00001131d00007134sv00001043sd00004840*
+ ID_PRODUCT_FROM_DATABASE=ASUS TV-FM 7134
+
+pci:v00001131d00007134sv00001043sd00004842*
+ ID_PRODUCT_FROM_DATABASE=TV-FM 7134
+
+pci:v00001131d00007134sv00001131sd00000000*
+ ID_PRODUCT_FROM_DATABASE=SAA713x-based TV tuner card
+
+pci:v00001131d00007134sv00001131sd00002004*
+ ID_PRODUCT_FROM_DATABASE=EUROPA V3 reference design
+
+pci:v00001131d00007134sv00001131sd00004E85*
+ ID_PRODUCT_FROM_DATABASE=SKNet Monster TV
+
+pci:v00001131d00007134sv00001131sd00006752*
+ ID_PRODUCT_FROM_DATABASE=EMPRESS
+
+pci:v00001131d00007134sv000011BDsd0000002B*
+ ID_PRODUCT_FROM_DATABASE=PCTV Stereo
+
+pci:v00001131d00007134sv000011BDsd0000002D*
+ ID_PRODUCT_FROM_DATABASE=PCTV 300i DVB-T + PAL
+
+pci:v00001131d00007134sv00001461sd00002C00*
+ ID_PRODUCT_FROM_DATABASE=AverTV Hybrid+FM PCI
+
+pci:v00001131d00007134sv00001461sd00009715*
+ ID_PRODUCT_FROM_DATABASE=AVerTV Studio 307
+
+pci:v00001131d00007134sv00001461sd0000A70A*
+ ID_PRODUCT_FROM_DATABASE=Avermedia AVerTV 307
+
+pci:v00001131d00007134sv00001461sd0000A70B*
+ ID_PRODUCT_FROM_DATABASE=AverMedia M156 / Medion 2819
+
+pci:v00001131d00007134sv00001461sd0000D6EE*
+ ID_PRODUCT_FROM_DATABASE=Cardbus TV/Radio (E500)
+
+pci:v00001131d00007134sv00001471sd0000B7E9*
+ ID_PRODUCT_FROM_DATABASE=AVerTV Cardbus plus
+
+pci:v00001131d00007134sv0000153Bsd00001142*
+ ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 400 TV
+
+pci:v00001131d00007134sv0000153Bsd00001143*
+ ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 600 TV
+
+pci:v00001131d00007134sv0000153Bsd00001158*
+ ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 600 TV MK3
+
+pci:v00001131d00007134sv00001540sd00009524*
+ ID_PRODUCT_FROM_DATABASE=ProVideo PV952
+
+pci:v00001131d00007134sv000016BEsd00000003*
+ ID_PRODUCT_FROM_DATABASE=Medion 7134
+
+pci:v00001131d00007134sv0000185Bsd0000C200*
+ ID_PRODUCT_FROM_DATABASE=Compro VideoMate Gold+ Pal
+
+pci:v00001131d00007134sv0000185Bsd0000C900*
+ ID_PRODUCT_FROM_DATABASE=Videomate DVB-T300
+
+pci:v00001131d00007134sv00001894sd0000A006*
+ ID_PRODUCT_FROM_DATABASE=KNC One TV-Station DVR
+
+pci:v00001131d00007134sv00001894sd0000FE01*
+ ID_PRODUCT_FROM_DATABASE=KNC One TV-Station RDS / Typhoon TV Tuner RDS
+
+pci:v00001131d00007134sv00005168sd00000138*
+ ID_PRODUCT_FROM_DATABASE=FLY TV PRIME 34FM
+
+pci:v00001131d00007134sv00005ACEsd00005070*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 507 FM
+
+pci:v00001131d00007134sv00005ACEsd00006070*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 607 FM
+
+pci:v00001131d00007134sv00005ACEsd00006071*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 607 FM
+
+pci:v00001131d00007134sv00005ACEsd00006072*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 607 RDS
+
+pci:v00001131d00007134sv00005ACEsd00006073*
+ ID_PRODUCT_FROM_DATABASE=Behold TV 607 RDS
+
+pci:v00001131d00007145*
+ ID_PRODUCT_FROM_DATABASE=SAA7145
+
+pci:v00001131d00007146*
+ ID_PRODUCT_FROM_DATABASE=SAA7146
+
+pci:v00001131d00007146sv0000110Asd00000000*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu/Siemens DVB-C card rev1.5
+
+pci:v00001131d00007146sv0000110Asd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu/Siemens DVB-C card rev1.5
+
+pci:v00001131d00007146sv00001124sd00002581*
+ ID_PRODUCT_FROM_DATABASE=Leutron Vision PicPort
+
+pci:v00001131d00007146sv00001131sd00004F56*
+ ID_PRODUCT_FROM_DATABASE=KNC1 DVB-S Budget
+
+pci:v00001131d00007146sv00001131sd00004F60*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu-Siemens Activy DVB-S Budget Rev AL
+
+pci:v00001131d00007146sv00001131sd00004F61*
+ ID_PRODUCT_FROM_DATABASE=Activy DVB-S Budget Rev GR
+
+pci:v00001131d00007146sv00001131sd00005F61*
+ ID_PRODUCT_FROM_DATABASE=Activy DVB-T Budget
+
+pci:v00001131d00007146sv0000114Bsd00002003*
+ ID_PRODUCT_FROM_DATABASE=DVRaptor Video Edit/Capture Card
+
+pci:v00001131d00007146sv000011BDsd00000006*
+ ID_PRODUCT_FROM_DATABASE=DV500 Overlay
+
+pci:v00001131d00007146sv000011BDsd0000000A*
+ ID_PRODUCT_FROM_DATABASE=DV500 Overlay
+
+pci:v00001131d00007146sv000011BDsd0000000F*
+ ID_PRODUCT_FROM_DATABASE=DV500 Overlay
+
+pci:v00001131d00007146sv000013C2sd00000000*
+ ID_PRODUCT_FROM_DATABASE=Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5
+
+pci:v00001131d00007146sv000013C2sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev1.3 or rev1.6
+
+pci:v00001131d00007146sv000013C2sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1
+
+pci:v00001131d00007146sv000013C2sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1
+
+pci:v00001131d00007146sv000013C2sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1
+
+pci:v00001131d00007146sv000013C2sd00000006*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev1.3 or rev1.6
+
+pci:v00001131d00007146sv000013C2sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB-T
+
+pci:v00001131d00007146sv000013C2sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Octal/Technotrend DVB-C for iTV
+
+pci:v00001131d00007146sv000013C2sd0000000E*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.3
+
+pci:v00001131d00007146sv000013C2sd00001003*
+ ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-S DVB card
+
+pci:v00001131d00007146sv000013C2sd00001004*
+ ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-C DVB card
+
+pci:v00001131d00007146sv000013C2sd00001005*
+ ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card
+
+pci:v00001131d00007146sv000013C2sd0000100C*
+ ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card
+
+pci:v00001131d00007146sv000013C2sd0000100F*
+ ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card
+
+pci:v00001131d00007146sv000013C2sd00001010*
+ ID_PRODUCT_FROM_DATABASE=DVB C-1500
+
+pci:v00001131d00007146sv000013C2sd00001011*
+ ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card
+
+pci:v00001131d00007146sv000013C2sd00001012*
+ ID_PRODUCT_FROM_DATABASE=DVB T-1500
+
+pci:v00001131d00007146sv000013C2sd00001013*
+ ID_PRODUCT_FROM_DATABASE=SATELCO Multimedia DVB
+
+pci:v00001131d00007146sv000013C2sd00001016*
+ ID_PRODUCT_FROM_DATABASE=WinTV-NOVA-SE DVB card
+
+pci:v00001131d00007146sv000013C2sd00001018*
+ ID_PRODUCT_FROM_DATABASE=DVB S-1401
+
+pci:v00001131d00007146sv000013C2sd00001019*
+ ID_PRODUCT_FROM_DATABASE=S2-3200
+
+pci:v00001131d00007146sv000013C2sd00001102*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1
+
+pci:v00001131d00007146sv0000153Bsd00001155*
+ ID_PRODUCT_FROM_DATABASE=Cinergy 1200 DVB-S
+
+pci:v00001131d00007146sv0000153Bsd00001156*
+ ID_PRODUCT_FROM_DATABASE=Terratec Cynergy 1200C
+
+pci:v00001131d00007146sv0000153Bsd00001157*
+ ID_PRODUCT_FROM_DATABASE=Cinergy 1200 DVB-T
+
+pci:v00001131d00007146sv00001894sd00000020*
+ ID_PRODUCT_FROM_DATABASE=KNC One DVB-C V1.0
+
+pci:v00001131d00007146sv00001894sd00000023*
+ ID_PRODUCT_FROM_DATABASE=TVStation DVB-C plus
+
+pci:v00001131d00007160*
+ ID_PRODUCT_FROM_DATABASE=SAA7160
+
+pci:v00001131d00007160sv00001458sd00009009*
+ ID_PRODUCT_FROM_DATABASE=E8000 DVB-T/Analog TV/FM tuner
+
+pci:v00001131d00007162*
+ ID_PRODUCT_FROM_DATABASE=SAA7162
+
+pci:v00001131d00007162sv000011BDsd00000101*
+ ID_PRODUCT_FROM_DATABASE=Pinnacle PCTV 7010iX TV Card
+
+pci:v00001131d00007164*
+ ID_PRODUCT_FROM_DATABASE=SAA7164
+
+pci:v00001131d00007164sv00000070sd00008800*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250
+
+pci:v00001131d00007164sv00000070sd00008810*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250
+
+pci:v00001131d00007164sv00000070sd00008851*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250
+
+pci:v00001131d00007164sv00000070sd00008853*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250
+
+pci:v00001131d00007164sv00000070sd00008880*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250
+
+pci:v00001131d00007164sv00000070sd00008891*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250
+
+pci:v00001131d00007164sv00000070sd000088A0*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250
+
+pci:v00001131d00007164sv00000070sd000088A1*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250
+
+pci:v00001131d00007164sv00000070sd00008900*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007164sv00000070sd00008901*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007164sv00000070sd00008940*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 (submodel 89619)
+
+pci:v00001131d00007164sv00000070sd00008951*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007164sv00000070sd00008953*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007164sv00000070sd00008980*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007164sv00000070sd00008991*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007164sv00000070sd00008993*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007164sv00000070sd000089A0*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007164sv00000070sd000089A1*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200
+
+pci:v00001131d00007231*
+ ID_PRODUCT_FROM_DATABASE=SAA7231
+
+pci:v00001131d00007231sv00005ACEsd00008000*
+ ID_PRODUCT_FROM_DATABASE=Behold TV H8
+
+pci:v00001131d00007231sv00005ACEsd00008100*
+ ID_PRODUCT_FROM_DATABASE=Behold TV A8
+
+pci:v00001131d00009730*
+ ID_PRODUCT_FROM_DATABASE=SAA9730 Integrated Multimedia and Peripheral Controller
+
+pci:v00001131d00009730sv00001131sd00000000*
+ ID_PRODUCT_FROM_DATABASE=Integrated Multimedia and Peripheral Controller
+
+pci:v00001132*
+ ID_VENDOR_FROM_DATABASE=Mitel Corp.
+
+pci:v00001133*
+ ID_VENDOR_FROM_DATABASE=Dialogic Corporation
+
+pci:v00001133d00007701*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard C90
+
+pci:v00001133d00007711*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard C91
+
+pci:v00001133d00007901*
+ ID_PRODUCT_FROM_DATABASE=EiconCard S90
+
+pci:v00001133d00007902*
+ ID_PRODUCT_FROM_DATABASE=EiconCard S90
+
+pci:v00001133d00007911*
+ ID_PRODUCT_FROM_DATABASE=EiconCard S91
+
+pci:v00001133d00007912*
+ ID_PRODUCT_FROM_DATABASE=EiconCard S91
+
+pci:v00001133d00007921*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard S92
+
+pci:v00001133d00007941*
+ ID_PRODUCT_FROM_DATABASE=EiconCard S94
+
+pci:v00001133d00007942*
+ ID_PRODUCT_FROM_DATABASE=EiconCard S94
+
+pci:v00001133d00007943*
+ ID_PRODUCT_FROM_DATABASE=EiconCard S94
+
+pci:v00001133d00007944*
+ ID_PRODUCT_FROM_DATABASE=EiconCard S94
+
+pci:v00001133d00007945*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard S94
+
+pci:v00001133d00007948*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard S94 64bit/66MHz
+
+pci:v00001133d00009711*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard S91 V2
+
+pci:v00001133d00009911*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard S91 V2
+
+pci:v00001133d00009941*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard S94 V2
+
+pci:v00001133d00009A41*
+ ID_PRODUCT_FROM_DATABASE=Eiconcard S94 PCIe
+
+pci:v00001133d0000B921*
+ ID_PRODUCT_FROM_DATABASE=EiconCard P92
+
+pci:v00001133d0000B922*
+ ID_PRODUCT_FROM_DATABASE=EiconCard P92
+
+pci:v00001133d0000B923*
+ ID_PRODUCT_FROM_DATABASE=EiconCard P92
+
+pci:v00001133d0000E001*
+ ID_PRODUCT_FROM_DATABASE=Diva Pro 2.0 S/T
+
+pci:v00001133d0000E002*
+ ID_PRODUCT_FROM_DATABASE=Diva 2.0 S/T PCI
+
+pci:v00001133d0000E003*
+ ID_PRODUCT_FROM_DATABASE=Diva Pro 2.0 U
+
+pci:v00001133d0000E004*
+ ID_PRODUCT_FROM_DATABASE=Diva 2.0 U PCI
+
+pci:v00001133d0000E005*
+ ID_PRODUCT_FROM_DATABASE=Diva 2.01 S/T PCI
+
+pci:v00001133d0000E006*
+ ID_PRODUCT_FROM_DATABASE=Diva CT S/T PCI
+
+pci:v00001133d0000E007*
+ ID_PRODUCT_FROM_DATABASE=Diva CT U PCI
+
+pci:v00001133d0000E008*
+ ID_PRODUCT_FROM_DATABASE=Diva CT Lite S/T PCI
+
+pci:v00001133d0000E009*
+ ID_PRODUCT_FROM_DATABASE=Diva CT Lite U PCI
+
+pci:v00001133d0000E00A*
+ ID_PRODUCT_FROM_DATABASE=Diva ISDN+V.90 PCI
+
+pci:v00001133d0000E00B*
+ ID_PRODUCT_FROM_DATABASE=Diva ISDN PCI 2.02
+
+pci:v00001133d0000E00C*
+ ID_PRODUCT_FROM_DATABASE=Diva 2.02 PCI U
+
+pci:v00001133d0000E00D*
+ ID_PRODUCT_FROM_DATABASE=Diva Pro 3.0 PCI
+
+pci:v00001133d0000E00E*
+ ID_PRODUCT_FROM_DATABASE=Diva ISDN+CT S/T PCI Rev 2
+
+pci:v00001133d0000E010*
+ ID_PRODUCT_FROM_DATABASE=Diva Server BRI-2M PCI
+
+pci:v00001133d0000E010sv0000110Asd00000021*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu Siemens ISDN S0
+
+pci:v00001133d0000E011*
+ ID_PRODUCT_FROM_DATABASE=Diva Server BRI S/T Rev 2
+
+pci:v00001133d0000E012*
+ ID_PRODUCT_FROM_DATABASE=Diva Server 4BRI-8M PCI
+
+pci:v00001133d0000E013*
+ ID_PRODUCT_FROM_DATABASE=4BRI
+
+pci:v00001133d0000E013sv00001133sd00001300*
+ ID_PRODUCT_FROM_DATABASE=Diva V-4BRI-8 PCI v2
+
+pci:v00001133d0000E013sv00001133sd0000E013*
+ ID_PRODUCT_FROM_DATABASE=Diva 4BRI-8 PCI v2
+
+pci:v00001133d0000E014*
+ ID_PRODUCT_FROM_DATABASE=Diva Server PRI-30M PCI
+
+pci:v00001133d0000E015*
+ ID_PRODUCT_FROM_DATABASE=Diva PRI PCI v2
+
+pci:v00001133d0000E016*
+ ID_PRODUCT_FROM_DATABASE=Diva Server Voice 4BRI PCI
+
+pci:v00001133d0000E017*
+ ID_PRODUCT_FROM_DATABASE=Diva Server Voice 4BRI Rev 2
+
+pci:v00001133d0000E017sv00001133sd0000E017*
+ ID_PRODUCT_FROM_DATABASE=Diva Server Voice 4BRI-8M 2.0 PCI
+
+pci:v00001133d0000E018*
+ ID_PRODUCT_FROM_DATABASE=BRI
+
+pci:v00001133d0000E018sv00001133sd00001800*
+ ID_PRODUCT_FROM_DATABASE=Diva V-BRI-2 PCI v2
+
+pci:v00001133d0000E018sv00001133sd0000E018*
+ ID_PRODUCT_FROM_DATABASE=Diva BRI-2 PCI v2
+
+pci:v00001133d0000E019*
+ ID_PRODUCT_FROM_DATABASE=Diva Server Voice PRI Rev 2
+
+pci:v00001133d0000E019sv00001133sd0000E019*
+ ID_PRODUCT_FROM_DATABASE=Diva Server Voice PRI 2.0 PCI
+
+pci:v00001133d0000E01A*
+ ID_PRODUCT_FROM_DATABASE=Diva BRI-2FX PCI v2
+
+pci:v00001133d0000E01B*
+ ID_PRODUCT_FROM_DATABASE=Diva Server Voice BRI-2M 2.0 PCI
+
+pci:v00001133d0000E01Bsv00001133sd0000E01B*
+ ID_PRODUCT_FROM_DATABASE=Diva Server Voice BRI-2M 2.0 PCI
+
+pci:v00001133d0000E01C*
+ ID_PRODUCT_FROM_DATABASE=PRI
+
+pci:v00001133d0000E01Csv00001133sd00001C01*
+ ID_PRODUCT_FROM_DATABASE=Diva PRI/E1/T1-8 PCI v3
+
+pci:v00001133d0000E01Csv00001133sd00001C02*
+ ID_PRODUCT_FROM_DATABASE=Diva PRI/T1-24 PCI(e) v3
+
+pci:v00001133d0000E01Csv00001133sd00001C03*
+ ID_PRODUCT_FROM_DATABASE=Diva PRI/E1-30 PCI(e) v3
+
+pci:v00001133d0000E01Csv00001133sd00001C04*
+ ID_PRODUCT_FROM_DATABASE=Diva PRI/E1/T1-CTI PCI(e) v3
+
+pci:v00001133d0000E01Csv00001133sd00001C05*
+ ID_PRODUCT_FROM_DATABASE=Diva V-PRI/T1-24 PCI(e) v3
+
+pci:v00001133d0000E01Csv00001133sd00001C06*
+ ID_PRODUCT_FROM_DATABASE=Diva V-PRI/E1-30 PCI(e) v3
+
+pci:v00001133d0000E01Csv00001133sd00001C07*
+ ID_PRODUCT_FROM_DATABASE=Diva Server PRI/E1/T1-8 Cornet NQ
+
+pci:v00001133d0000E01Csv00001133sd00001C08*
+ ID_PRODUCT_FROM_DATABASE=Diva Server PRI/T1-24 Cornet NQ
+
+pci:v00001133d0000E01Csv00001133sd00001C09*
+ ID_PRODUCT_FROM_DATABASE=Diva Server PRI/E1-30 Cornet NQ
+
+pci:v00001133d0000E01Csv00001133sd00001C0A*
+ ID_PRODUCT_FROM_DATABASE=Diva Server PRI/E1/T1 Cornet NQ
+
+pci:v00001133d0000E01Csv00001133sd00001C0B*
+ ID_PRODUCT_FROM_DATABASE=Diva Server V-PRI/T1-24 Cornet NQ
+
+pci:v00001133d0000E01Csv00001133sd00001C0C*
+ ID_PRODUCT_FROM_DATABASE=Diva Server V-PRI/E1-30 Cornet NQ
+
+pci:v00001133d0000E01E*
+ ID_PRODUCT_FROM_DATABASE=2PRI
+
+pci:v00001133d0000E01Esv00001133sd00001E01*
+ ID_PRODUCT_FROM_DATABASE=Diva 2PRI/E1/T1-60 PCI v1
+
+pci:v00001133d0000E01Esv00001133sd0000E01E*
+ ID_PRODUCT_FROM_DATABASE=Diva V-2PRI/E1/T1-60 PCI v1
+
+pci:v00001133d0000E020*
+ ID_PRODUCT_FROM_DATABASE=4PRI
+
+pci:v00001133d0000E020sv00001133sd00002001*
+ ID_PRODUCT_FROM_DATABASE=Diva 4PRI/E1/T1-120 PCI v1
+
+pci:v00001133d0000E020sv00001133sd0000E020*
+ ID_PRODUCT_FROM_DATABASE=Diva V-4PRI/E1/T1-120 PCI v1
+
+pci:v00001133d0000E022*
+ ID_PRODUCT_FROM_DATABASE=Analog-2
+
+pci:v00001133d0000E022sv00001133sd00002200*
+ ID_PRODUCT_FROM_DATABASE=Diva V-Analog-2 PCI v1
+
+pci:v00001133d0000E022sv00001133sd0000E022*
+ ID_PRODUCT_FROM_DATABASE=Diva Analog-2 PCI v1
+
+pci:v00001133d0000E024*
+ ID_PRODUCT_FROM_DATABASE=Analog-4
+
+pci:v00001133d0000E024sv00001133sd00002400*
+ ID_PRODUCT_FROM_DATABASE=Diva V-Analog-4 PCI v1
+
+pci:v00001133d0000E024sv00001133sd0000E024*
+ ID_PRODUCT_FROM_DATABASE=Diva Analog-4 PCI v1
+
+pci:v00001133d0000E028*
+ ID_PRODUCT_FROM_DATABASE=Analog-8
+
+pci:v00001133d0000E028sv00001133sd00002800*
+ ID_PRODUCT_FROM_DATABASE=Diva V-Analog-8 PCI v1
+
+pci:v00001133d0000E028sv00001133sd0000E028*
+ ID_PRODUCT_FROM_DATABASE=Diva Analog-8 PCI v1
+
+pci:v00001133d0000E02A*
+ ID_PRODUCT_FROM_DATABASE=Diva IPM-300 PCI v1
+
+pci:v00001133d0000E02C*
+ ID_PRODUCT_FROM_DATABASE=Diva IPM-600 PCI v1
+
+pci:v00001133d0000E02E*
+ ID_PRODUCT_FROM_DATABASE=4BRI
+
+pci:v00001133d0000E02Esv00001133sd00002E01*
+ ID_PRODUCT_FROM_DATABASE=Diva V-4BRI-8 PCIe v2
+
+pci:v00001133d0000E02Esv00001133sd0000E02E*
+ ID_PRODUCT_FROM_DATABASE=Diva 4BRI-8 PCIe v2
+
+pci:v00001133d0000E032*
+ ID_PRODUCT_FROM_DATABASE=BRI
+
+pci:v00001133d0000E032sv00001133sd00003201*
+ ID_PRODUCT_FROM_DATABASE=Diva V-BRI-2 PCIe v2
+
+pci:v00001133d0000E032sv00001133sd0000E032*
+ ID_PRODUCT_FROM_DATABASE=Diva BRI-2 PCIe v2
+
+pci:v00001133d0000E034*
+ ID_PRODUCT_FROM_DATABASE=Diva BRI-CTI PCI v2
+
+pci:v00001134*
+ ID_VENDOR_FROM_DATABASE=Mercury Computer Systems
+
+pci:v00001134d00000001*
+ ID_PRODUCT_FROM_DATABASE=Raceway Bridge
+
+pci:v00001134d00000002*
+ ID_PRODUCT_FROM_DATABASE=Dual PCI to RapidIO Bridge
+
+pci:v00001134d0000000B*
+ ID_PRODUCT_FROM_DATABASE=POET Serial RapidIO Bridge
+
+pci:v00001134d0000000D*
+ ID_PRODUCT_FROM_DATABASE=POET PSDMS Device
+
+pci:v00001135*
+ ID_VENDOR_FROM_DATABASE=Fuji Xerox Co Ltd
+
+pci:v00001135d00000001*
+ ID_PRODUCT_FROM_DATABASE=Printer controller
+
+pci:v00001136*
+ ID_VENDOR_FROM_DATABASE=Momentum Data Systems
+
+pci:v00001136d00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI-JTAG
+
+pci:v00001137*
+ ID_VENDOR_FROM_DATABASE=Cisco Systems Inc
+
+pci:v00001137d00000023*
+ ID_PRODUCT_FROM_DATABASE=VIC 81 PCIe Upstream Port
+
+pci:v00001137d00000040*
+ ID_PRODUCT_FROM_DATABASE=VIC PCIe Upstream Port
+
+pci:v00001137d00000041*
+ ID_PRODUCT_FROM_DATABASE=VIC PCIe Downstream Port
+
+pci:v00001137d00000042*
+ ID_PRODUCT_FROM_DATABASE=VIC Management Controller
+
+pci:v00001137d00000042sv00001137sd00000047*
+ ID_PRODUCT_FROM_DATABASE=VIC P81E PCIe Management Controller
+
+pci:v00001137d00000043*
+ ID_PRODUCT_FROM_DATABASE=VIC Ethernet NIC
+
+pci:v00001137d00000043sv00001137sd00000047*
+ ID_PRODUCT_FROM_DATABASE=VIC P81E PCIe Ethernet NIC
+
+pci:v00001137d00000043sv00001137sd00000048*
+ ID_PRODUCT_FROM_DATABASE=VIC M81KR Mezzanine Ethernet NIC
+
+pci:v00001137d00000043sv00001137sd0000004F*
+ ID_PRODUCT_FROM_DATABASE=VIC 1280 Mezzanine Ethernet NIC
+
+pci:v00001137d00000043sv00001137sd00000084*
+ ID_PRODUCT_FROM_DATABASE=VIC 1240 MLOM Ethernet NIC
+
+pci:v00001137d00000043sv00001137sd00000085*
+ ID_PRODUCT_FROM_DATABASE=VIC 1225 PCIe Ethernet NIC
+
+pci:v00001137d00000044*
+ ID_PRODUCT_FROM_DATABASE=VIC Ethernet NIC Dynamic
+
+pci:v00001137d00000044sv00001137sd00000047*
+ ID_PRODUCT_FROM_DATABASE=VIC P81E PCIe Ethernet NIC Dynamic
+
+pci:v00001137d00000044sv00001137sd00000048*
+ ID_PRODUCT_FROM_DATABASE=VIC M81KR Mezzanine Ethernet NIC Dynamic
+
+pci:v00001137d00000044sv00001137sd0000004F*
+ ID_PRODUCT_FROM_DATABASE=VIC 1280 Mezzanine Ethernet NIC Dynamic
+
+pci:v00001137d00000044sv00001137sd00000084*
+ ID_PRODUCT_FROM_DATABASE=VIC 1240 MLOM Ethernet NIC Dynamic
+
+pci:v00001137d00000044sv00001137sd00000085*
+ ID_PRODUCT_FROM_DATABASE=VIC 1225 PCIe Ethernet NIC Dynamic
+
+pci:v00001137d00000045*
+ ID_PRODUCT_FROM_DATABASE=VIC FCoE HBA
+
+pci:v00001137d00000045sv00001137sd00000047*
+ ID_PRODUCT_FROM_DATABASE=VIC P81E PCIe FCoE HBA
+
+pci:v00001137d00000045sv00001137sd00000048*
+ ID_PRODUCT_FROM_DATABASE=VIC M81KR Mezzanine FCoE HBA
+
+pci:v00001137d00000045sv00001137sd0000004F*
+ ID_PRODUCT_FROM_DATABASE=VIC 1280 Mezzanine FCoE HBA
+
+pci:v00001137d0000004E*
+ ID_PRODUCT_FROM_DATABASE=VIC 82 PCIe Upstream Port
+
+pci:v00001138*
+ ID_VENDOR_FROM_DATABASE=Ziatech Corporation
+
+pci:v00001138d00008905*
+ ID_PRODUCT_FROM_DATABASE=8905 [STD 32 Bridge]
+
+pci:v00001139*
+ ID_VENDOR_FROM_DATABASE=Dynamic Pictures, Inc
+
+pci:v00001139d00000001*
+ ID_PRODUCT_FROM_DATABASE=VGA Compatable 3D Graphics
+
+pci:v0000113A*
+ ID_VENDOR_FROM_DATABASE=FWB Inc
+
+pci:v0000113B*
+ ID_VENDOR_FROM_DATABASE=Network Computing Devices
+
+pci:v0000113C*
+ ID_VENDOR_FROM_DATABASE=Cyclone Microsystems, Inc.
+
+pci:v0000113Cd00000000*
+ ID_PRODUCT_FROM_DATABASE=PCI-9060 i960 Bridge
+
+pci:v0000113Cd00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI-SDK [PCI i960 Evaluation Platform]
+
+pci:v0000113Cd00000911*
+ ID_PRODUCT_FROM_DATABASE=PCI-911 [i960Jx-based Intelligent I/O Controller]
+
+pci:v0000113Cd00000912*
+ ID_PRODUCT_FROM_DATABASE=PCI-912 [i960CF-based Intelligent I/O Controller]
+
+pci:v0000113Cd00000913*
+ ID_PRODUCT_FROM_DATABASE=PCI-913
+
+pci:v0000113Cd00000914*
+ ID_PRODUCT_FROM_DATABASE=PCI-914 [I/O Controller w/ secondary PCI bus]
+
+pci:v0000113D*
+ ID_VENDOR_FROM_DATABASE=Leading Edge Products Inc
+
+pci:v0000113E*
+ ID_VENDOR_FROM_DATABASE=Sanyo Electric Co - Computer Engineering Dept
+
+pci:v0000113F*
+ ID_VENDOR_FROM_DATABASE=Equinox Systems, Inc.
+
+pci:v0000113Fd00000808*
+ ID_PRODUCT_FROM_DATABASE=SST-64P Adapter
+
+pci:v0000113Fd00001010*
+ ID_PRODUCT_FROM_DATABASE=SST-128P Adapter
+
+pci:v0000113Fd000080C0*
+ ID_PRODUCT_FROM_DATABASE=SST-16P DB Adapter
+
+pci:v0000113Fd000080C4*
+ ID_PRODUCT_FROM_DATABASE=SST-16P RJ Adapter
+
+pci:v0000113Fd000080C8*
+ ID_PRODUCT_FROM_DATABASE=SST-16P Adapter
+
+pci:v0000113Fd00008888*
+ ID_PRODUCT_FROM_DATABASE=SST-4P Adapter
+
+pci:v0000113Fd00009090*
+ ID_PRODUCT_FROM_DATABASE=SST-8P Adapter
+
+pci:v00001140*
+ ID_VENDOR_FROM_DATABASE=Intervoice Inc
+
+pci:v00001141*
+ ID_VENDOR_FROM_DATABASE=Crest Microsystem Inc
+
+pci:v00001142*
+ ID_VENDOR_FROM_DATABASE=Alliance Semiconductor Corporation
+
+pci:v00001142d00003210*
+ ID_PRODUCT_FROM_DATABASE=AP6410
+
+pci:v00001142d00006422*
+ ID_PRODUCT_FROM_DATABASE=ProVideo 6422
+
+pci:v00001142d00006424*
+ ID_PRODUCT_FROM_DATABASE=ProVideo 6424
+
+pci:v00001142d00006425*
+ ID_PRODUCT_FROM_DATABASE=ProMotion AT25
+
+pci:v00001142d0000643D*
+ ID_PRODUCT_FROM_DATABASE=ProMotion AT3D
+
+pci:v00001143*
+ ID_VENDOR_FROM_DATABASE=NetPower, Inc
+
+pci:v00001144*
+ ID_VENDOR_FROM_DATABASE=Cincinnati Milacron
+
+pci:v00001144d00000001*
+ ID_PRODUCT_FROM_DATABASE=Noservo controller
+
+pci:v00001145*
+ ID_VENDOR_FROM_DATABASE=Workbit Corporation
+
+pci:v00001145d00008007*
+ ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Workbit
+
+pci:v00001145d0000F007*
+ ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 KME
+
+pci:v00001145d0000F010*
+ ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Workbit
+
+pci:v00001145d0000F012*
+ ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Logitec
+
+pci:v00001145d0000F013*
+ ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Logitec
+
+pci:v00001145d0000F015*
+ ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Melco
+
+pci:v00001145d0000F020*
+ ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Sony PCGA-DVD51
+
+pci:v00001145d0000F021*
+ ID_PRODUCT_FROM_DATABASE=NinjaPATA-32 Delkin Cardbus UDMA
+
+pci:v00001145d0000F024*
+ ID_PRODUCT_FROM_DATABASE=NinjaPATA-32 Delkin Cardbus UDMA
+
+pci:v00001145d0000F103*
+ ID_PRODUCT_FROM_DATABASE=NinjaPATA-32 Delkin Cardbus UDMA
+
+pci:v00001146*
+ ID_VENDOR_FROM_DATABASE=Force Computers
+
+pci:v00001147*
+ ID_VENDOR_FROM_DATABASE=Interface Corp
+
+pci:v00001148*
+ ID_VENDOR_FROM_DATABASE=SysKonnect
+
+pci:v00001148d00004000*
+ ID_PRODUCT_FROM_DATABASE=FDDI Adapter
+
+pci:v00001148d00004000sv00000E11sd0000B03B*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI DAS Fibre SC
+
+pci:v00001148d00004000sv00000E11sd0000B03C*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI SAS Fibre SC
+
+pci:v00001148d00004000sv00000E11sd0000B03D*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI DAS UTP
+
+pci:v00001148d00004000sv00000E11sd0000B03E*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI SAS UTP
+
+pci:v00001148d00004000sv00000E11sd0000B03F*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI SAS Fibre MIC
+
+pci:v00001148d00004000sv00001148sd00005521*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5521 (SK-NET FDDI-UP)
+
+pci:v00001148d00004000sv00001148sd00005522*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5522 (SK-NET FDDI-UP DAS)
+
+pci:v00001148d00004000sv00001148sd00005541*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5541 (SK-NET FDDI-FP)
+
+pci:v00001148d00004000sv00001148sd00005543*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5543 (SK-NET FDDI-LP)
+
+pci:v00001148d00004000sv00001148sd00005544*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5544 (SK-NET FDDI-LP DAS)
+
+pci:v00001148d00004000sv00001148sd00005821*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5821 (SK-NET FDDI-UP64)
+
+pci:v00001148d00004000sv00001148sd00005822*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5822 (SK-NET FDDI-UP64 DAS)
+
+pci:v00001148d00004000sv00001148sd00005841*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5841 (SK-NET FDDI-FP64)
+
+pci:v00001148d00004000sv00001148sd00005843*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5843 (SK-NET FDDI-LP64)
+
+pci:v00001148d00004000sv00001148sd00005844*
+ ID_PRODUCT_FROM_DATABASE=FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
+
+pci:v00001148d00004200*
+ ID_PRODUCT_FROM_DATABASE=Token Ring adapter
+
+pci:v00001148d00004300*
+ ID_PRODUCT_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
+
+pci:v00001148d00004300sv00001148sd00009821*
+ ID_PRODUCT_FROM_DATABASE=SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
+
+pci:v00001148d00004300sv00001148sd00009822*
+ ID_PRODUCT_FROM_DATABASE=SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
+
+pci:v00001148d00004300sv00001148sd00009841*
+ ID_PRODUCT_FROM_DATABASE=SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
+
+pci:v00001148d00004300sv00001148sd00009842*
+ ID_PRODUCT_FROM_DATABASE=SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
+
+pci:v00001148d00004300sv00001148sd00009843*
+ ID_PRODUCT_FROM_DATABASE=SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
+
+pci:v00001148d00004300sv00001148sd00009844*
+ ID_PRODUCT_FROM_DATABASE=SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
+
+pci:v00001148d00004300sv00001148sd00009861*
+ ID_PRODUCT_FROM_DATABASE=SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
+
+pci:v00001148d00004300sv00001148sd00009862*
+ ID_PRODUCT_FROM_DATABASE=SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
+
+pci:v00001148d00004300sv00001148sd00009871*
+ ID_PRODUCT_FROM_DATABASE=SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
+
+pci:v00001148d00004300sv00001148sd00009872*
+ ID_PRODUCT_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
+
+pci:v00001148d00004300sv00001259sd00002970*
+ ID_PRODUCT_FROM_DATABASE=AT-2970SX Gigabit Ethernet Adapter
+
+pci:v00001148d00004300sv00001259sd00002971*
+ ID_PRODUCT_FROM_DATABASE=AT-2970LX Gigabit Ethernet Adapter
+
+pci:v00001148d00004300sv00001259sd00002972*
+ ID_PRODUCT_FROM_DATABASE=AT-2970TX Gigabit Ethernet Adapter
+
+pci:v00001148d00004300sv00001259sd00002973*
+ ID_PRODUCT_FROM_DATABASE=AT-2971SX Gigabit Ethernet Adapter
+
+pci:v00001148d00004300sv00001259sd00002974*
+ ID_PRODUCT_FROM_DATABASE=AT-2971T Gigabit Ethernet Adapter
+
+pci:v00001148d00004300sv00001259sd00002975*
+ ID_PRODUCT_FROM_DATABASE=AT-2970SX/2SC Gigabit Ethernet Adapter
+
+pci:v00001148d00004300sv00001259sd00002976*
+ ID_PRODUCT_FROM_DATABASE=AT-2970LX/2SC Gigabit Ethernet Adapter
+
+pci:v00001148d00004300sv00001259sd00002977*
+ ID_PRODUCT_FROM_DATABASE=AT-2970TX/2TX Gigabit Ethernet Adapter
+
+pci:v00001148d00004320*
+ ID_PRODUCT_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC
+
+pci:v00001148d00004320sv00001148sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8001 Adapter
+
+pci:v00001148d00004320sv00001148sd00000221*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8002 Adapter
+
+pci:v00001148d00004320sv00001148sd00000321*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8003 Adapter
+
+pci:v00001148d00004320sv00001148sd00000421*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8004 Adapter
+
+pci:v00001148d00004320sv00001148sd00000621*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8006 Adapter
+
+pci:v00001148d00004320sv00001148sd00000721*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8007 Adapter
+
+pci:v00001148d00004320sv00001148sd00000821*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8008 Adapter
+
+pci:v00001148d00004320sv00001148sd00000921*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8009 Adapter
+
+pci:v00001148d00004320sv00001148sd00001121*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8011 Adapter
+
+pci:v00001148d00004320sv00001148sd00001221*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8012 Adapter
+
+pci:v00001148d00004320sv00001148sd00003221*
+ ID_PRODUCT_FROM_DATABASE=SK-9521 V2.0 10/100/1000Base-T Adapter
+
+pci:v00001148d00004320sv00001148sd00005021*
+ ID_PRODUCT_FROM_DATABASE=SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
+
+pci:v00001148d00004320sv00001148sd00005041*
+ ID_PRODUCT_FROM_DATABASE=SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
+
+pci:v00001148d00004320sv00001148sd00005043*
+ ID_PRODUCT_FROM_DATABASE=SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+
+pci:v00001148d00004320sv00001148sd00005051*
+ ID_PRODUCT_FROM_DATABASE=SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+
+pci:v00001148d00004320sv00001148sd00005061*
+ ID_PRODUCT_FROM_DATABASE=SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+
+pci:v00001148d00004320sv00001148sd00005071*
+ ID_PRODUCT_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+
+pci:v00001148d00004320sv00001148sd00009521*
+ ID_PRODUCT_FROM_DATABASE=SK-9521 10/100/1000Base-T Adapter
+
+pci:v00001148d00004400*
+ ID_PRODUCT_FROM_DATABASE=SK-9Dxx Gigabit Ethernet Adapter
+
+pci:v00001148d00004500*
+ ID_PRODUCT_FROM_DATABASE=SK-9Mxx Gigabit Ethernet Adapter
+
+pci:v00001148d00009000*
+ ID_PRODUCT_FROM_DATABASE=SK-9S21 10/100/1000Base-T Server Adapter, PCI-X, Copper RJ-45
+
+pci:v00001148d00009843*
+ ID_PRODUCT_FROM_DATABASE=[Fujitsu] Gigabit Ethernet
+
+pci:v00001148d00009E00*
+ ID_PRODUCT_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45
+
+pci:v00001148d00009E00sv00001148sd00002100*
+ ID_PRODUCT_FROM_DATABASE=SK-9E21 Server Adapter
+
+pci:v00001148d00009E00sv00001148sd000021D0*
+ ID_PRODUCT_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter
+
+pci:v00001148d00009E00sv00001148sd00002200*
+ ID_PRODUCT_FROM_DATABASE=SK-9E22 Server Adapter
+
+pci:v00001148d00009E00sv00001148sd00008100*
+ ID_PRODUCT_FROM_DATABASE=SK-9E81 Server Adapter
+
+pci:v00001148d00009E00sv00001148sd00008200*
+ ID_PRODUCT_FROM_DATABASE=SK-9E82 Server Adapter
+
+pci:v00001148d00009E00sv00001148sd00009100*
+ ID_PRODUCT_FROM_DATABASE=SK-9E91 Server Adapter
+
+pci:v00001148d00009E00sv00001148sd00009200*
+ ID_PRODUCT_FROM_DATABASE=SK-9E92 Server Adapter
+
+pci:v00001148d00009E01*
+ ID_PRODUCT_FROM_DATABASE=SK-9E21M 10/100/1000Base-T Adapter
+
+pci:v00001149*
+ ID_VENDOR_FROM_DATABASE=Win System Corporation
+
+pci:v0000114A*
+ ID_VENDOR_FROM_DATABASE=VMIC
+
+pci:v0000114Ad00005565*
+ ID_PRODUCT_FROM_DATABASE=GE-IP PCI5565,PMC5565 Reflective Memory Node
+
+pci:v0000114Ad00005579*
+ ID_PRODUCT_FROM_DATABASE=VMIPCI-5579 (Reflective Memory Card)
+
+pci:v0000114Ad00005587*
+ ID_PRODUCT_FROM_DATABASE=VMIPCI-5587 (Reflective Memory Card)
+
+pci:v0000114Ad00006504*
+ ID_PRODUCT_FROM_DATABASE=VMIC PCI 7755 FPGA
+
+pci:v0000114Ad00007587*
+ ID_PRODUCT_FROM_DATABASE=VMIVME-7587
+
+pci:v0000114B*
+ ID_VENDOR_FROM_DATABASE=Canopus Co., Ltd
+
+pci:v0000114C*
+ ID_VENDOR_FROM_DATABASE=Annabooks
+
+pci:v0000114D*
+ ID_VENDOR_FROM_DATABASE=IC Corporation
+
+pci:v0000114E*
+ ID_VENDOR_FROM_DATABASE=Nikon Systems Inc
+
+pci:v0000114F*
+ ID_VENDOR_FROM_DATABASE=Digi International
+
+pci:v0000114Fd00000002*
+ ID_PRODUCT_FROM_DATABASE=AccelePort EPC
+
+pci:v0000114Fd00000003*
+ ID_PRODUCT_FROM_DATABASE=RightSwitch SE-6
+
+pci:v0000114Fd00000004*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xem
+
+pci:v0000114Fd00000005*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xr
+
+pci:v0000114Fd00000006*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xr,C/X
+
+pci:v0000114Fd00000009*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xr/J
+
+pci:v0000114Fd0000000A*
+ ID_PRODUCT_FROM_DATABASE=AccelePort EPC/J
+
+pci:v0000114Fd0000000C*
+ ID_PRODUCT_FROM_DATABASE=DataFirePRIme T1 (1-port)
+
+pci:v0000114Fd0000000D*
+ ID_PRODUCT_FROM_DATABASE=SyncPort 2-Port (x.25/FR)
+
+pci:v0000114Fd00000011*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 8r EIA-232 (IBM)
+
+pci:v0000114Fd00000012*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 8r EIA-422
+
+pci:v0000114Fd00000013*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xr
+
+pci:v0000114Fd00000014*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 8r EIA-422
+
+pci:v0000114Fd00000015*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xem
+
+pci:v0000114Fd00000016*
+ ID_PRODUCT_FROM_DATABASE=AccelePort EPC/X
+
+pci:v0000114Fd00000017*
+ ID_PRODUCT_FROM_DATABASE=AccelePort C/X
+
+pci:v0000114Fd0000001A*
+ ID_PRODUCT_FROM_DATABASE=DataFirePRIme E1 (1-port)
+
+pci:v0000114Fd0000001B*
+ ID_PRODUCT_FROM_DATABASE=AccelePort C/X (IBM)
+
+pci:v0000114Fd0000001C*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xr (SAIP)
+
+pci:v0000114Fd0000001D*
+ ID_PRODUCT_FROM_DATABASE=DataFire RAS T1/E1/PRI
+
+pci:v0000114Fd0000001Dsv0000114Fsd00000050*
+ ID_PRODUCT_FROM_DATABASE=DataFire RAS E1 Adapter
+
+pci:v0000114Fd0000001Dsv0000114Fsd00000051*
+ ID_PRODUCT_FROM_DATABASE=DataFire RAS Dual E1 Adapter
+
+pci:v0000114Fd0000001Dsv0000114Fsd00000052*
+ ID_PRODUCT_FROM_DATABASE=DataFire RAS T1 Adapter
+
+pci:v0000114Fd0000001Dsv0000114Fsd00000053*
+ ID_PRODUCT_FROM_DATABASE=DataFire RAS Dual T1 Adapter
+
+pci:v0000114Fd00000023*
+ ID_PRODUCT_FROM_DATABASE=AccelePort RAS
+
+pci:v0000114Fd00000024*
+ ID_PRODUCT_FROM_DATABASE=DataFire RAS B4 ST/U
+
+pci:v0000114Fd00000024sv0000114Fsd00000030*
+ ID_PRODUCT_FROM_DATABASE=DataFire RAS BRI U Adapter
+
+pci:v0000114Fd00000024sv0000114Fsd00000031*
+ ID_PRODUCT_FROM_DATABASE=DataFire RAS BRI S/T Adapter
+
+pci:v0000114Fd00000026*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 4r 920
+
+pci:v0000114Fd00000027*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xr 920
+
+pci:v0000114Fd00000028*
+ ID_PRODUCT_FROM_DATABASE=ClassicBoard 4
+
+pci:v0000114Fd00000029*
+ ID_PRODUCT_FROM_DATABASE=ClassicBoard 8
+
+pci:v0000114Fd00000034*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 2r 920
+
+pci:v0000114Fd00000035*
+ ID_PRODUCT_FROM_DATABASE=DataFire DSP T1/E1/PRI cPCI
+
+pci:v0000114Fd00000040*
+ ID_PRODUCT_FROM_DATABASE=AccelePort Xp
+
+pci:v0000114Fd00000040sv0000114Fsd00000042*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 2p PCI
+
+pci:v0000114Fd00000040sv0000114Fsd00000043*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 4p PCI
+
+pci:v0000114Fd00000040sv0000114Fsd00000044*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 8p PCI
+
+pci:v0000114Fd00000040sv0000114Fsd00000045*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 16p PCI
+
+pci:v0000114Fd00000040sv0000114Fsd0000004E*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 32p PCI
+
+pci:v0000114Fd00000042*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 2p
+
+pci:v0000114Fd00000043*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 4p
+
+pci:v0000114Fd00000044*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 8p
+
+pci:v0000114Fd00000045*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 16p
+
+pci:v0000114Fd0000004E*
+ ID_PRODUCT_FROM_DATABASE=AccelePort 32p
+
+pci:v0000114Fd00000070*
+ ID_PRODUCT_FROM_DATABASE=Datafire Micro V IOM2 (Europe)
+
+pci:v0000114Fd00000071*
+ ID_PRODUCT_FROM_DATABASE=Datafire Micro V (Europe)
+
+pci:v0000114Fd00000072*
+ ID_PRODUCT_FROM_DATABASE=Datafire Micro V IOM2 (North America)
+
+pci:v0000114Fd00000073*
+ ID_PRODUCT_FROM_DATABASE=Datafire Micro V (North America)
+
+pci:v0000114Fd000000B0*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 4
+
+pci:v0000114Fd000000B1*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 8
+
+pci:v0000114Fd000000C8*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 2 DB9
+
+pci:v0000114Fd000000C9*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 2 DB9 PRI
+
+pci:v0000114Fd000000CA*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 2 RJ45
+
+pci:v0000114Fd000000CB*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 2 RJ45 PRI
+
+pci:v0000114Fd000000CC*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 1 422
+
+pci:v0000114Fd000000CD*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 1 422 485
+
+pci:v0000114Fd000000CE*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 2 422 485
+
+pci:v0000114Fd000000D0*
+ ID_PRODUCT_FROM_DATABASE=ClassicBoard 4 422
+
+pci:v0000114Fd000000D1*
+ ID_PRODUCT_FROM_DATABASE=ClassicBoard 8 422
+
+pci:v0000114Fd000000F1*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo PCI-E 4 port
+
+pci:v0000114Fd000000F4*
+ ID_PRODUCT_FROM_DATABASE=Digi Neo 4 (IBM version)
+
+pci:v0000114Fd00006001*
+ ID_PRODUCT_FROM_DATABASE=Avanstar
+
+pci:v00001150*
+ ID_VENDOR_FROM_DATABASE=Thinking Machines Corp
+
+pci:v00001151*
+ ID_VENDOR_FROM_DATABASE=JAE Electronics Inc.
+
+pci:v00001152*
+ ID_VENDOR_FROM_DATABASE=Megatek
+
+pci:v00001153*
+ ID_VENDOR_FROM_DATABASE=Land Win Electronic Corp
+
+pci:v00001154*
+ ID_VENDOR_FROM_DATABASE=Melco Inc
+
+pci:v00001155*
+ ID_VENDOR_FROM_DATABASE=Pine Technology Ltd
+
+pci:v00001156*
+ ID_VENDOR_FROM_DATABASE=Periscope Engineering
+
+pci:v00001157*
+ ID_VENDOR_FROM_DATABASE=Avsys Corporation
+
+pci:v00001158*
+ ID_VENDOR_FROM_DATABASE=Voarx R & D Inc
+
+pci:v00001158d00003011*
+ ID_PRODUCT_FROM_DATABASE=Tokenet/vg 1001/10m anylan
+
+pci:v00001158d00009050*
+ ID_PRODUCT_FROM_DATABASE=Lanfleet/Truevalue
+
+pci:v00001158d00009051*
+ ID_PRODUCT_FROM_DATABASE=Lanfleet/Truevalue
+
+pci:v00001159*
+ ID_VENDOR_FROM_DATABASE=Mutech Corp
+
+pci:v00001159d00000001*
+ ID_PRODUCT_FROM_DATABASE=MV-1000
+
+pci:v00001159d00000002*
+ ID_PRODUCT_FROM_DATABASE=MV-1500
+
+pci:v0000115A*
+ ID_VENDOR_FROM_DATABASE=Harlequin Ltd
+
+pci:v0000115B*
+ ID_VENDOR_FROM_DATABASE=Parallax Graphics
+
+pci:v0000115C*
+ ID_VENDOR_FROM_DATABASE=Photron Ltd.
+
+pci:v0000115D*
+ ID_VENDOR_FROM_DATABASE=Xircom
+
+pci:v0000115Dd00000003*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000003sv00001014sd00000181*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd00000003sv00001014sd00001181*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd00000003sv00001014sd00008181*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd00000003sv00001014sd00009181*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd00000003sv0000115Dsd00000181*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000003sv0000115Dsd00000182*
+ ID_PRODUCT_FROM_DATABASE=RealPort2 CardBus Ethernet 10/100 (R2BE-100)
+
+pci:v0000115Dd00000003sv0000115Dsd00001181*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000003sv00001179sd00000181*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000003sv00008086sd00008181*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32 Adapter
+
+pci:v0000115Dd00000003sv00008086sd00009181*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32 Adapter
+
+pci:v0000115Dd00000005*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000005sv00001014sd00000182*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd00000005sv00001014sd00001182*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd00000005sv0000115Dsd00000182*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000005sv0000115Dsd00001182*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000007*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000007sv00001014sd00000182*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd00000007sv00001014sd00001182*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd00000007sv0000115Dsd00000182*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd00000007sv0000115Dsd00001182*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd0000000Bsv00001014sd00000183*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd0000000Bsv0000115Dsd00000183*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd0000000C*
+ ID_PRODUCT_FROM_DATABASE=Mini-PCI V.90 56k Modem
+
+pci:v0000115Dd0000000F*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd0000000Fsv00001014sd00000183*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+
+pci:v0000115Dd0000000Fsv0000115Dsd00000183*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100
+
+pci:v0000115Dd000000D4*
+ ID_PRODUCT_FROM_DATABASE=Mini-PCI K56Flex Modem
+
+pci:v0000115Dd00000101*
+ ID_PRODUCT_FROM_DATABASE=Cardbus 56k modem
+
+pci:v0000115Dd00000101sv0000115Dsd00001081*
+ ID_PRODUCT_FROM_DATABASE=Cardbus 56k Modem
+
+pci:v0000115Dd00000103*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet + 56k Modem
+
+pci:v0000115Dd00000103sv00001014sd00009181*
+ ID_PRODUCT_FROM_DATABASE=Cardbus 56k Modem
+
+pci:v0000115Dd00000103sv00001115sd00001181*
+ ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 100 + 56k Modem
+
+pci:v0000115Dd00000103sv0000115Dsd00001181*
+ ID_PRODUCT_FROM_DATABASE=CBEM56G-100 Ethernet + 56k Modem
+
+pci:v0000115Dd00000103sv00008086sd00009181*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 LAN + Modem56 CardBus
+
+pci:v0000115E*
+ ID_VENDOR_FROM_DATABASE=Peer Protocols Inc
+
+pci:v0000115F*
+ ID_VENDOR_FROM_DATABASE=Maxtor Corporation
+
+pci:v00001160*
+ ID_VENDOR_FROM_DATABASE=Megasoft Inc
+
+pci:v00001161*
+ ID_VENDOR_FROM_DATABASE=PFU Limited
+
+pci:v00001162*
+ ID_VENDOR_FROM_DATABASE=OA Laboratory Co Ltd
+
+pci:v00001163*
+ ID_VENDOR_FROM_DATABASE=Rendition
+
+pci:v00001163d00000001*
+ ID_PRODUCT_FROM_DATABASE=Verite 1000
+
+pci:v00001163d00002000*
+ ID_PRODUCT_FROM_DATABASE=Verite V2000/V2100/V2200
+
+pci:v00001163d00002000sv00001092sd00002000*
+ ID_PRODUCT_FROM_DATABASE=Stealth II S220
+
+pci:v00001164*
+ ID_VENDOR_FROM_DATABASE=Advanced Peripherals Technologies
+
+pci:v00001165*
+ ID_VENDOR_FROM_DATABASE=Imagraph Corporation
+
+pci:v00001165d00000001*
+ ID_PRODUCT_FROM_DATABASE=Motion TPEG Recorder/Player with audio
+
+pci:v00001166*
+ ID_VENDOR_FROM_DATABASE=Broadcom
+
+pci:v00001166d00000000*
+ ID_PRODUCT_FROM_DATABASE=CMIC-LE
+
+pci:v00001166d00000005*
+ ID_PRODUCT_FROM_DATABASE=CNB20-LE Host Bridge
+
+pci:v00001166d00000006*
+ ID_PRODUCT_FROM_DATABASE=CNB20HE Host Bridge
+
+pci:v00001166d00000007*
+ ID_PRODUCT_FROM_DATABASE=CNB20-LE Host Bridge
+
+pci:v00001166d00000008*
+ ID_PRODUCT_FROM_DATABASE=CNB20HE Host Bridge
+
+pci:v00001166d00000009*
+ ID_PRODUCT_FROM_DATABASE=CNB20LE Host Bridge
+
+pci:v00001166d00000010*
+ ID_PRODUCT_FROM_DATABASE=CIOB30
+
+pci:v00001166d00000011*
+ ID_PRODUCT_FROM_DATABASE=CMIC-HE
+
+pci:v00001166d00000012*
+ ID_PRODUCT_FROM_DATABASE=CMIC-WS Host Bridge (GC-LE chipset)
+
+pci:v00001166d00000013*
+ ID_PRODUCT_FROM_DATABASE=CNB20-HE Host Bridge
+
+pci:v00001166d00000014*
+ ID_PRODUCT_FROM_DATABASE=CMIC-LE Host Bridge (GC-LE chipset)
+
+pci:v00001166d00000015*
+ ID_PRODUCT_FROM_DATABASE=CMIC-GC Host Bridge
+
+pci:v00001166d00000016*
+ ID_PRODUCT_FROM_DATABASE=CMIC-GC Host Bridge
+
+pci:v00001166d00000017*
+ ID_PRODUCT_FROM_DATABASE=GCNB-LE Host Bridge
+
+pci:v00001166d00000031*
+ ID_PRODUCT_FROM_DATABASE=HT1100 HPX0 HT Host Bridge
+
+pci:v00001166d00000036*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] PCI/PCI-X Bridge
+
+pci:v00001166d00000101*
+ ID_PRODUCT_FROM_DATABASE=CIOB-X2 PCI-X I/O Bridge
+
+pci:v00001166d00000103*
+ ID_PRODUCT_FROM_DATABASE=EPB PCI-Express to PCI-X Bridge
+
+pci:v00001166d00000104*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] PCI/PCI-X Bridge
+
+pci:v00001166d00000110*
+ ID_PRODUCT_FROM_DATABASE=CIOB-E I/O Bridge with Gigabit Ethernet
+
+pci:v00001166d00000130*
+ ID_PRODUCT_FROM_DATABASE=BCM5780 [HT2000] PCI-X bridge
+
+pci:v00001166d00000132*
+ ID_PRODUCT_FROM_DATABASE=BCM5780 [HT2000] PCI-Express Bridge
+
+pci:v00001166d00000132sv00001166sd00000132*
+ ID_PRODUCT_FROM_DATABASE=HT2000 PCI-Express bridge
+
+pci:v00001166d00000140*
+ ID_PRODUCT_FROM_DATABASE=HT2100 PCI-Express Bridge
+
+pci:v00001166d00000141*
+ ID_PRODUCT_FROM_DATABASE=HT2100 PCI-Express Bridge
+
+pci:v00001166d00000142*
+ ID_PRODUCT_FROM_DATABASE=HT2100 PCI-Express Bridge
+
+pci:v00001166d00000144*
+ ID_PRODUCT_FROM_DATABASE=HT2100 PCI-Express Bridge
+
+pci:v00001166d00000200*
+ ID_PRODUCT_FROM_DATABASE=OSB4 South Bridge
+
+pci:v00001166d00000201*
+ ID_PRODUCT_FROM_DATABASE=CSB5 South Bridge
+
+pci:v00001166d00000201sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00001166d00000203*
+ ID_PRODUCT_FROM_DATABASE=CSB6 South Bridge
+
+pci:v00001166d00000203sv00001734sd00001012*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series
+
+pci:v00001166d00000205*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] Legacy South Bridge
+
+pci:v00001166d00000211*
+ ID_PRODUCT_FROM_DATABASE=OSB4 IDE Controller
+
+pci:v00001166d00000212*
+ ID_PRODUCT_FROM_DATABASE=CSB5 IDE Controller
+
+pci:v00001166d00000212sv00001028sd0000014A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1750
+
+pci:v00001166d00000212sv00001028sd0000810B*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1650/2550
+
+pci:v00001166d00000212sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00001166d00000213*
+ ID_PRODUCT_FROM_DATABASE=CSB6 RAID/IDE Controller
+
+pci:v00001166d00000213sv00001028sd00004134*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 600SC
+
+pci:v00001166d00000213sv00001028sd0000C134*
+ ID_PRODUCT_FROM_DATABASE=Poweredge SC600
+
+pci:v00001166d00000213sv00001734sd00001012*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard IDE
+
+pci:v00001166d00000214*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] IDE
+
+pci:v00001166d00000214sv00001028sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 HT1000 IDE
+
+pci:v00001166d00000217*
+ ID_PRODUCT_FROM_DATABASE=CSB6 IDE Controller
+
+pci:v00001166d00000217sv00001028sd00004134*
+ ID_PRODUCT_FROM_DATABASE=Poweredge SC600
+
+pci:v00001166d0000021B*
+ ID_PRODUCT_FROM_DATABASE=HT1100 HD Audio
+
+pci:v00001166d00000220*
+ ID_PRODUCT_FROM_DATABASE=OSB4/CSB5 OHCI USB Controller
+
+pci:v00001166d00000220sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00001166d00000221*
+ ID_PRODUCT_FROM_DATABASE=CSB6 OHCI USB Controller
+
+pci:v00001166d00000221sv00001734sd00001012*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard OHCI
+
+pci:v00001166d00000223*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] USB
+
+pci:v00001166d00000223sv00001028sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 HT1000 USB Controller
+
+pci:v00001166d00000223sv00001028sd0000020B*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T605 HT1000 USB Controller
+
+pci:v00001166d00000225*
+ ID_PRODUCT_FROM_DATABASE=CSB5 LPC bridge
+
+pci:v00001166d00000227*
+ ID_PRODUCT_FROM_DATABASE=GCLE-2 Host Bridge
+
+pci:v00001166d00000227sv00001734sd00001012*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series
+
+pci:v00001166d00000230*
+ ID_PRODUCT_FROM_DATABASE=CSB5 LPC bridge
+
+pci:v00001166d00000230sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00001166d00000234*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] LPC
+
+pci:v00001166d00000234sv00001028sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 HT1000 LPC
+
+pci:v00001166d00000234sv00001028sd0000020B*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T605 HT1000 LPC
+
+pci:v00001166d00000235*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] XIOAPIC0-2
+
+pci:v00001166d00000238*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] WDTimer
+
+pci:v00001166d00000240*
+ ID_PRODUCT_FROM_DATABASE=K2 SATA
+
+pci:v00001166d00000241*
+ ID_PRODUCT_FROM_DATABASE=RAIDCore RC4000
+
+pci:v00001166d00000242*
+ ID_PRODUCT_FROM_DATABASE=RAIDCore BC4000
+
+pci:v00001166d0000024A*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] SATA (Native SATA Mode)
+
+pci:v00001166d0000024Asv00001028sd0000020B*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T605 onboard SATA Controller
+
+pci:v00001166d0000024B*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] SATA (PATA/IDE Mode)
+
+pci:v00001166d0000024Bsv00001028sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 HT1000 SATA controller
+
+pci:v00001166d00000406*
+ ID_PRODUCT_FROM_DATABASE=HT1100 PCI-X Bridge
+
+pci:v00001166d00000408*
+ ID_PRODUCT_FROM_DATABASE=HT1100 Legacy Device
+
+pci:v00001166d0000040A*
+ ID_PRODUCT_FROM_DATABASE=HT1100 ISA-LPC Bridge
+
+pci:v00001166d0000040Asv00001028sd00000223*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R905 HT1100 ISA-LPC Bridge
+
+pci:v00001166d00000410*
+ ID_PRODUCT_FROM_DATABASE=HT1100 SATA Controller (Native SATA Mode)
+
+pci:v00001166d00000411*
+ ID_PRODUCT_FROM_DATABASE=HT1100 SATA Controller (PATA / IDE Mode)
+
+pci:v00001166d00000412*
+ ID_PRODUCT_FROM_DATABASE=HT1100 USB OHCI Controller
+
+pci:v00001166d00000414*
+ ID_PRODUCT_FROM_DATABASE=HT1100 USB EHCI Controller
+
+pci:v00001166d00000416*
+ ID_PRODUCT_FROM_DATABASE=HT1100 USB EHCI Controller (with Debug Port)
+
+pci:v00001166d00000420*
+ ID_PRODUCT_FROM_DATABASE=HT1100 PCI-Express Bridge
+
+pci:v00001166d00000421*
+ ID_PRODUCT_FROM_DATABASE=HT1100 SAS/SATA Controller
+
+pci:v00001166d00000422*
+ ID_PRODUCT_FROM_DATABASE=HT1100 PCI-Express Bridge
+
+pci:v00001167*
+ ID_VENDOR_FROM_DATABASE=Mutoh Industries Inc
+
+pci:v00001168*
+ ID_VENDOR_FROM_DATABASE=Thine Electronics Inc
+
+pci:v00001169*
+ ID_VENDOR_FROM_DATABASE=Centre for Development of Advanced Computing
+
+pci:v0000116A*
+ ID_VENDOR_FROM_DATABASE=Luminex Software, Inc.
+
+pci:v0000116Ad00006100*
+ ID_PRODUCT_FROM_DATABASE=Bus/Tag Channel
+
+pci:v0000116Ad00006800*
+ ID_PRODUCT_FROM_DATABASE=Escon Channel
+
+pci:v0000116Ad00007100*
+ ID_PRODUCT_FROM_DATABASE=Bus/Tag Channel
+
+pci:v0000116Ad00007800*
+ ID_PRODUCT_FROM_DATABASE=Escon Channel
+
+pci:v0000116B*
+ ID_VENDOR_FROM_DATABASE=Connectware Inc
+
+pci:v0000116C*
+ ID_VENDOR_FROM_DATABASE=Intelligent Resources Integrated Systems
+
+pci:v0000116D*
+ ID_VENDOR_FROM_DATABASE=Martin-Marietta
+
+pci:v0000116E*
+ ID_VENDOR_FROM_DATABASE=Electronics for Imaging
+
+pci:v0000116F*
+ ID_VENDOR_FROM_DATABASE=Workstation Technology
+
+pci:v00001170*
+ ID_VENDOR_FROM_DATABASE=Inventec Corporation
+
+pci:v00001171*
+ ID_VENDOR_FROM_DATABASE=Loughborough Sound Images Plc
+
+pci:v00001172*
+ ID_VENDOR_FROM_DATABASE=Altera Corporation
+
+pci:v00001173*
+ ID_VENDOR_FROM_DATABASE=Adobe Systems, Inc
+
+pci:v00001174*
+ ID_VENDOR_FROM_DATABASE=Bridgeport Machines
+
+pci:v00001175*
+ ID_VENDOR_FROM_DATABASE=Mitron Computer Inc.
+
+pci:v00001176*
+ ID_VENDOR_FROM_DATABASE=SBE Incorporated
+
+pci:v00001177*
+ ID_VENDOR_FROM_DATABASE=Silicon Engineering
+
+pci:v00001178*
+ ID_VENDOR_FROM_DATABASE=Alfa, Inc.
+
+pci:v00001178d0000AFA1*
+ ID_PRODUCT_FROM_DATABASE=Fast Ethernet Adapter
+
+pci:v00001179*
+ ID_VENDOR_FROM_DATABASE=Toshiba America Info Systems
+
+pci:v00001179d00000102*
+ ID_PRODUCT_FROM_DATABASE=Extended IDE Controller
+
+pci:v00001179d00000103*
+ ID_PRODUCT_FROM_DATABASE=EX-IDE Type-B
+
+pci:v00001179d00000404*
+ ID_PRODUCT_FROM_DATABASE=DVD Decoder card
+
+pci:v00001179d00000406*
+ ID_PRODUCT_FROM_DATABASE=Tecra Video Capture device
+
+pci:v00001179d00000407*
+ ID_PRODUCT_FROM_DATABASE=DVD Decoder card (Version 2)
+
+pci:v00001179d00000601*
+ ID_PRODUCT_FROM_DATABASE=CPU to PCI bridge
+
+pci:v00001179d00000601sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Satellite Pro
+
+pci:v00001179d00000602*
+ ID_PRODUCT_FROM_DATABASE=PCI to ISA bridge
+
+pci:v00001179d00000603*
+ ID_PRODUCT_FROM_DATABASE=ToPIC95 PCI to CardBus Bridge for Notebooks
+
+pci:v00001179d00000604*
+ ID_PRODUCT_FROM_DATABASE=PCI-Docking Host bridge
+
+pci:v00001179d0000060A*
+ ID_PRODUCT_FROM_DATABASE=ToPIC95
+
+pci:v00001179d0000060Asv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Satellite Pro
+
+pci:v00001179d0000060F*
+ ID_PRODUCT_FROM_DATABASE=ToPIC97
+
+pci:v00001179d0000060Fsv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Satellite 4010
+
+pci:v00001179d00000617*
+ ID_PRODUCT_FROM_DATABASE=ToPIC100 PCI to Cardbus Bridge with ZV Support
+
+pci:v00001179d00000618*
+ ID_PRODUCT_FROM_DATABASE=CPU to PCI and PCI to ISA bridge
+
+pci:v00001179d00000701*
+ ID_PRODUCT_FROM_DATABASE=FIR Port Type-O
+
+pci:v00001179d00000804*
+ ID_PRODUCT_FROM_DATABASE=TC6371AF SmartMedia Controller
+
+pci:v00001179d00000805*
+ ID_PRODUCT_FROM_DATABASE=SD TypA Controller
+
+pci:v00001179d00000D01*
+ ID_PRODUCT_FROM_DATABASE=FIR Port Type-DO
+
+pci:v00001179d00000D01sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=FIR Port Type-DO
+
+pci:v0000117A*
+ ID_VENDOR_FROM_DATABASE=A-Trend Technology
+
+pci:v0000117B*
+ ID_VENDOR_FROM_DATABASE=L G Electronics, Inc.
+
+pci:v0000117C*
+ ID_VENDOR_FROM_DATABASE=ATTO Technology, Inc.
+
+pci:v0000117Cd0000002C*
+ ID_PRODUCT_FROM_DATABASE=SAS RAID Adapter
+
+pci:v0000117Cd00000030*
+ ID_PRODUCT_FROM_DATABASE=Ultra320 SCSI Host Adapter
+
+pci:v0000117Cd00000030sv0000117Csd00008013*
+ ID_PRODUCT_FROM_DATABASE=ExpressPCI UL4D
+
+pci:v0000117Cd00000030sv0000117Csd00008014*
+ ID_PRODUCT_FROM_DATABASE=ExpressPCI UL4S
+
+pci:v0000117Cd00000030sv0000117Csd00008027*
+ ID_PRODUCT_FROM_DATABASE=ExpressPCI UL5D
+
+pci:v0000117Cd00000030sv0000117Csd0000802F*
+ ID_PRODUCT_FROM_DATABASE=ExpressPCI UL5D Low Profile
+
+pci:v0000117Cd00000033*
+ ID_PRODUCT_FROM_DATABASE=SAS Adapter
+
+pci:v0000117D*
+ ID_VENDOR_FROM_DATABASE=Becton & Dickinson
+
+pci:v0000117E*
+ ID_VENDOR_FROM_DATABASE=T/R Systems
+
+pci:v0000117F*
+ ID_VENDOR_FROM_DATABASE=Integrated Circuit Systems
+
+pci:v00001180*
+ ID_VENDOR_FROM_DATABASE=Ricoh Co Ltd
+
+pci:v00001180d00000465*
+ ID_PRODUCT_FROM_DATABASE=RL5c465
+
+pci:v00001180d00000466*
+ ID_PRODUCT_FROM_DATABASE=RL5c466
+
+pci:v00001180d00000475*
+ ID_PRODUCT_FROM_DATABASE=RL5c475
+
+pci:v00001180d00000475sv0000144Dsd0000C006*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 CardBus bridge
+
+pci:v00001180d00000476*
+ ID_PRODUCT_FROM_DATABASE=RL5c476 II
+
+pci:v00001180d00000476sv00001014sd00000185*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00001180d00000476sv00001014sd0000056C*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad Z60t
+
+pci:v00001180d00000476sv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300 laptop
+
+pci:v00001180d00000476sv00001028sd00000188*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop
+
+pci:v00001180d00000476sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00001180d00000476sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00001180d00000476sv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00001180d00000476sv00001043sd00001967*
+ ID_PRODUCT_FROM_DATABASE=V6800V
+
+pci:v00001180d00000476sv00001043sd00001987*
+ ID_PRODUCT_FROM_DATABASE=Asus A4K and Z81K notebooks, possibly others ( mid-2005 machines )
+
+pci:v00001180d00000476sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00001180d00000476sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00001180d00000476sv0000104Dsd0000814E*
+ ID_PRODUCT_FROM_DATABASE=VAIO GRZ390Z
+
+pci:v00001180d00000476sv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop
+
+pci:v00001180d00000476sv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00001180d00000476sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00001180d00000476sv000014EFsd00000220*
+ ID_PRODUCT_FROM_DATABASE=PCD-RP-220S
+
+pci:v00001180d00000476sv000017AAsd0000201C*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad X60s
+
+pci:v00001180d00000476sv000017AAsd000020C4*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00001180d00000477*
+ ID_PRODUCT_FROM_DATABASE=RL5c477
+
+pci:v00001180d00000478*
+ ID_PRODUCT_FROM_DATABASE=RL5c478
+
+pci:v00001180d00000478sv00001014sd00000184*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A30p
+
+pci:v00001180d00000511*
+ ID_PRODUCT_FROM_DATABASE=R5C511
+
+pci:v00001180d00000522*
+ ID_PRODUCT_FROM_DATABASE=R5C522 IEEE 1394 Controller
+
+pci:v00001180d00000522sv00001014sd000001CF*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A30p
+
+pci:v00001180d00000522sv00001043sd00001967*
+ ID_PRODUCT_FROM_DATABASE=V6800V
+
+pci:v00001180d00000551*
+ ID_PRODUCT_FROM_DATABASE=R5C551 IEEE 1394 Controller
+
+pci:v00001180d00000551sv0000144Dsd0000C006*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4
+
+pci:v00001180d00000552*
+ ID_PRODUCT_FROM_DATABASE=R5C552 IEEE 1394 Controller
+
+pci:v00001180d00000552sv00001014sd00000511*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00001180d00000552sv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300 laptop
+
+pci:v00001180d00000552sv00001028sd00000188*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop
+
+pci:v00001180d00000552sv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00001180d00000552sv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00001180d00000552sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00001180d00000552sv000017AAsd0000201E*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad X60s
+
+pci:v00001180d00000554*
+ ID_PRODUCT_FROM_DATABASE=R5C554
+
+pci:v00001180d00000575*
+ ID_PRODUCT_FROM_DATABASE=R5C575 SD Bus Host Adapter
+
+pci:v00001180d00000576*
+ ID_PRODUCT_FROM_DATABASE=R5C576 SD Bus Host Adapter
+
+pci:v00001180d00000592*
+ ID_PRODUCT_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter
+
+pci:v00001180d00000592sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00001180d00000592sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00001180d00000592sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00001180d00000592sv0000103Csd000030B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v00001180d00000592sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v00001180d00000592sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00001180d00000592sv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00001180d00000592sv00001043sd00001967*
+ ID_PRODUCT_FROM_DATABASE=V6800V
+
+pci:v00001180d00000592sv0000144Dsd0000C018*
+ ID_PRODUCT_FROM_DATABASE=X20 IV
+
+pci:v00001180d00000592sv000017AAsd000020CA*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00001180d00000811*
+ ID_PRODUCT_FROM_DATABASE=R5C811
+
+pci:v00001180d00000822*
+ ID_PRODUCT_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter
+
+pci:v00001180d00000822sv00001014sd00000556*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad X60s / Z60t
+
+pci:v00001180d00000822sv00001014sd00000598*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad Z60m
+
+pci:v00001180d00000822sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00001180d00000822sv00001028sd00000188*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop
+
+pci:v00001180d00000822sv00001028sd000001A2*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 9200
+
+pci:v00001180d00000822sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00001180d00000822sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00001180d00000822sv0000103Csd000003B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v00001180d00000822sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v00001180d00000822sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00001180d00000822sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00001180d00000822sv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00001180d00000822sv00001043sd00001967*
+ ID_PRODUCT_FROM_DATABASE=ASUS V6800V
+
+pci:v00001180d00000822sv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop
+
+pci:v00001180d00000822sv0000144Dsd0000C018*
+ ID_PRODUCT_FROM_DATABASE=X20 IV
+
+pci:v00001180d00000822sv000017AAsd0000201D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad X60s
+
+pci:v00001180d00000822sv000017AAsd000020C7*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00001180d00000832*
+ ID_PRODUCT_FROM_DATABASE=R5C832 IEEE 1394 Controller
+
+pci:v00001180d00000832sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00001180d00000832sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00001180d00000832sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00001180d00000832sv0000103Csd000030B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v00001180d00000832sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v00001180d00000832sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00001180d00000832sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00001180d00000841*
+ ID_PRODUCT_FROM_DATABASE=R5C841 CardBus/SD/SDIO/MMC/MS/MSPro/xD/IEEE1394
+
+pci:v00001180d00000843*
+ ID_PRODUCT_FROM_DATABASE=R5C843 MMC Host Controller
+
+pci:v00001180d00000843sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00001180d00000843sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00001180d00000843sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00001180d00000843sv00001028sd000001F5*
+ ID_PRODUCT_FROM_DATABASE=Dell Inspiron 1501
+
+pci:v00001180d00000843sv00001028sd0000024F*
+ ID_PRODUCT_FROM_DATABASE=Dell Latitude e6500
+
+pci:v00001180d00000843sv0000103Csd000003B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v00001180d00000843sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v00001180d00000843sv00001183sd00000843*
+ ID_PRODUCT_FROM_DATABASE=Alienware Aurora m9700
+
+pci:v00001180d00000852*
+ ID_PRODUCT_FROM_DATABASE=xD-Picture Card Controller
+
+pci:v00001180d00000852sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00001180d00000852sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00001180d00000852sv0000103Csd000030B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v00001180d00000852sv0000103Csd000030B7*
+ ID_PRODUCT_FROM_DATABASE=Presario V6133CL
+
+pci:v00001180d00000852sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00001180d00000852sv00001043sd00001967*
+ ID_PRODUCT_FROM_DATABASE=V6800V
+
+pci:v00001180d00000852sv00001180sd00000852*
+ ID_PRODUCT_FROM_DATABASE=Pavilion 2410us
+
+pci:v00001180d00000852sv00001324sd000010CF*
+ ID_PRODUCT_FROM_DATABASE=P7120
+
+pci:v00001180d0000E230*
+ ID_PRODUCT_FROM_DATABASE=R5U2xx (R5U230 / R5U231 / R5U241) [Memory Stick Host Controller]
+
+pci:v00001180d0000E476*
+ ID_PRODUCT_FROM_DATABASE=CardBus bridge
+
+pci:v00001180d0000E476sv00001028sd0000040A*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6410
+
+pci:v00001180d0000E476sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00001180d0000E822*
+ ID_PRODUCT_FROM_DATABASE=MMC/SD Host Controller
+
+pci:v00001180d0000E822sv00001028sd0000040A*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6410
+
+pci:v00001180d0000E822sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00001180d0000E823*
+ ID_PRODUCT_FROM_DATABASE=PCIe SDXC/MMC Host Controller
+
+pci:v00001180d0000E832*
+ ID_PRODUCT_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller
+
+pci:v00001180d0000E832sv00001028sd0000040A*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6410
+
+pci:v00001180d0000E832sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00001180d0000E852*
+ ID_PRODUCT_FROM_DATABASE=PCIe xD-Picture Card Controller
+
+pci:v00001181*
+ ID_VENDOR_FROM_DATABASE=Telmatics International
+
+pci:v00001183*
+ ID_VENDOR_FROM_DATABASE=Fujikura Ltd
+
+pci:v00001184*
+ ID_VENDOR_FROM_DATABASE=Forks Inc
+
+pci:v00001185*
+ ID_VENDOR_FROM_DATABASE=Dataworld International Ltd
+
+pci:v00001186*
+ ID_VENDOR_FROM_DATABASE=D-Link System Inc
+
+pci:v00001186d00000100*
+ ID_PRODUCT_FROM_DATABASE=DC21041
+
+pci:v00001186d00001002*
+ ID_PRODUCT_FROM_DATABASE=DL10050 Sundance Ethernet
+
+pci:v00001186d00001002sv00001186sd00001002*
+ ID_PRODUCT_FROM_DATABASE=DFE-550TX/FX
+
+pci:v00001186d00001002sv00001186sd00001012*
+ ID_PRODUCT_FROM_DATABASE=DFE-580TX
+
+pci:v00001186d00001025*
+ ID_PRODUCT_FROM_DATABASE=AirPlus Xtreme G DWL-G650 Adapter
+
+pci:v00001186d00001026*
+ ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter
+
+pci:v00001186d00001043*
+ ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter
+
+pci:v00001186d00001300*
+ ID_PRODUCT_FROM_DATABASE=RTL8139 Ethernet
+
+pci:v00001186d00001300sv00001186sd00001300*
+ ID_PRODUCT_FROM_DATABASE=DFE-538TX 10/100 Ethernet Adapter
+
+pci:v00001186d00001300sv00001186sd00001301*
+ ID_PRODUCT_FROM_DATABASE=DFE-530TX+ 10/100 Ethernet Adapter
+
+pci:v00001186d00001300sv00001186sd00001303*
+ ID_PRODUCT_FROM_DATABASE=DFE-528TX 10/100 Fast Ethernet PCI Adapter
+
+pci:v00001186d00001340*
+ ID_PRODUCT_FROM_DATABASE=DFE-690TXD CardBus PC Card
+
+pci:v00001186d00001405*
+ ID_PRODUCT_FROM_DATABASE=DFE-520TX Fast Ethernet PCI Adapter
+
+pci:v00001186d00001540*
+ ID_PRODUCT_FROM_DATABASE=DFE-680TX
+
+pci:v00001186d00001541*
+ ID_PRODUCT_FROM_DATABASE=DFE-680TXD CardBus PC Card
+
+pci:v00001186d00001561*
+ ID_PRODUCT_FROM_DATABASE=DRP-32TXD Cardbus PC Card
+
+pci:v00001186d00003300*
+ ID_PRODUCT_FROM_DATABASE=DWL-510 / DWL-610 802.11b [Realtek RTL8180L]
+
+pci:v00001186d00003300sv00001186sd00003300*
+ ID_PRODUCT_FROM_DATABASE=DWL-610 Wireless Cardbus Adapter
+
+pci:v00001186d00003300sv00001186sd00003301*
+ ID_PRODUCT_FROM_DATABASE=DWL-510 Wireless PCI Adapter
+
+pci:v00001186d00003A03*
+ ID_PRODUCT_FROM_DATABASE=AirPro DWL-A650 Wireless Cardbus Adapter(rev.B)
+
+pci:v00001186d00003A04*
+ ID_PRODUCT_FROM_DATABASE=AirPro DWL-AB650 Multimode Wireless Cardbus Adapter
+
+pci:v00001186d00003A05*
+ ID_PRODUCT_FROM_DATABASE=AirPro DWL-AB520 Multimode Wireless PCI Adapter
+
+pci:v00001186d00003A07*
+ ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter
+
+pci:v00001186d00003A08*
+ ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG520 Wireless PCI Adapter
+
+pci:v00001186d00003A10*
+ ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B)
+
+pci:v00001186d00003A11*
+ ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG520 Wireless PCI Adapter(rev.B)
+
+pci:v00001186d00003A12*
+ ID_PRODUCT_FROM_DATABASE=AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
+
+pci:v00001186d00003A63*
+ ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG660 Wireless Cardbus Adapter
+
+pci:v00001186d00003A70*
+ ID_PRODUCT_FROM_DATABASE=DWA-556 Xtreme N PCI Express Desktop Adapter
+
+pci:v00001186d00003C00*
+ ID_PRODUCT_FROM_DATABASE=D-link DWL-G650X
+
+pci:v00001186d00003C09*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G510
+
+pci:v00001186d00004000*
+ ID_PRODUCT_FROM_DATABASE=DL2000-based Gigabit Ethernet
+
+pci:v00001186d00004001*
+ ID_PRODUCT_FROM_DATABASE=DGE-550SX PCI-X Gigabit Ethernet Adapter
+
+pci:v00001186d00004300*
+ ID_PRODUCT_FROM_DATABASE=DGE-528T Gigabit Ethernet Adapter
+
+pci:v00001186d00004300sv00001186sd00004B10*
+ ID_PRODUCT_FROM_DATABASE=DGE-560T PCI Express (x1) Gigabit Ethernet Adapter
+
+pci:v00001186d00004302*
+ ID_PRODUCT_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter (rev.C1) [Realtek RTL8169]
+
+pci:v00001186d00004800*
+ ID_PRODUCT_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter (rev 11)
+
+pci:v00001186d00004B00*
+ ID_PRODUCT_FROM_DATABASE=DGE-560T PCI Express Gigabit Ethernet Adapter
+
+pci:v00001186d00004B01*
+ ID_PRODUCT_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter (rev 11)
+
+pci:v00001186d00004B02*
+ ID_PRODUCT_FROM_DATABASE=DGE-560SX PCI Express Gigabit Ethernet Adapter
+
+pci:v00001186d00004B03*
+ ID_PRODUCT_FROM_DATABASE=DGE-550T Gigabit Ethernet Adapter V.B1
+
+pci:v00001186d00004C00*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet Adapter
+
+pci:v00001186d00004C00sv00001186sd00004C00*
+ ID_PRODUCT_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter
+
+pci:v00001186d00008400*
+ ID_PRODUCT_FROM_DATABASE=D-Link DWL-650+ CardBus PC Card
+
+pci:v00001187*
+ ID_VENDOR_FROM_DATABASE=Advanced Technology Laboratories, Inc.
+
+pci:v00001188*
+ ID_VENDOR_FROM_DATABASE=Shima Seiki Manufacturing Ltd.
+
+pci:v00001189*
+ ID_VENDOR_FROM_DATABASE=Matsushita Electronics Co Ltd
+
+pci:v0000118A*
+ ID_VENDOR_FROM_DATABASE=Hilevel Technology
+
+pci:v0000118B*
+ ID_VENDOR_FROM_DATABASE=Hypertec Pty Limited
+
+pci:v0000118C*
+ ID_VENDOR_FROM_DATABASE=Corollary, Inc
+
+pci:v0000118Cd00000014*
+ ID_PRODUCT_FROM_DATABASE=PCIB [C-bus II to PCI bus host bridge chip]
+
+pci:v0000118Cd00001117*
+ ID_PRODUCT_FROM_DATABASE=Intel 8-way XEON Profusion Chipset [Cache Coherency Filter]
+
+pci:v0000118D*
+ ID_VENDOR_FROM_DATABASE=BitFlow Inc
+
+pci:v0000118Dd00000001*
+ ID_PRODUCT_FROM_DATABASE=Raptor-PCI framegrabber
+
+pci:v0000118Dd00000012*
+ ID_PRODUCT_FROM_DATABASE=Model 12 Road Runner Frame Grabber
+
+pci:v0000118Dd00000014*
+ ID_PRODUCT_FROM_DATABASE=Model 14 Road Runner Frame Grabber
+
+pci:v0000118Dd00000024*
+ ID_PRODUCT_FROM_DATABASE=Model 24 Road Runner Frame Grabber
+
+pci:v0000118Dd00000044*
+ ID_PRODUCT_FROM_DATABASE=Model 44 Road Runner Frame Grabber
+
+pci:v0000118Dd00000112*
+ ID_PRODUCT_FROM_DATABASE=Model 12 Road Runner Frame Grabber
+
+pci:v0000118Dd00000114*
+ ID_PRODUCT_FROM_DATABASE=Model 14 Road Runner Frame Grabber
+
+pci:v0000118Dd00000124*
+ ID_PRODUCT_FROM_DATABASE=Model 24 Road Runner Frame Grabber
+
+pci:v0000118Dd00000144*
+ ID_PRODUCT_FROM_DATABASE=Model 44 Road Runner Frame Grabber
+
+pci:v0000118Dd00000212*
+ ID_PRODUCT_FROM_DATABASE=Model 12 Road Runner Frame Grabber
+
+pci:v0000118Dd00000214*
+ ID_PRODUCT_FROM_DATABASE=Model 14 Road Runner Frame Grabber
+
+pci:v0000118Dd00000224*
+ ID_PRODUCT_FROM_DATABASE=Model 24 Road Runner Frame Grabber
+
+pci:v0000118Dd00000244*
+ ID_PRODUCT_FROM_DATABASE=Model 44 Road Runner Frame Grabber
+
+pci:v0000118Dd00000312*
+ ID_PRODUCT_FROM_DATABASE=Model 12 Road Runner Frame Grabber
+
+pci:v0000118Dd00000314*
+ ID_PRODUCT_FROM_DATABASE=Model 14 Road Runner Frame Grabber
+
+pci:v0000118Dd00000324*
+ ID_PRODUCT_FROM_DATABASE=Model 24 Road Runner Frame Grabber
+
+pci:v0000118Dd00000344*
+ ID_PRODUCT_FROM_DATABASE=Model 44 Road Runner Frame Grabber
+
+pci:v0000118E*
+ ID_VENDOR_FROM_DATABASE=Hermstedt GmbH
+
+pci:v0000118F*
+ ID_VENDOR_FROM_DATABASE=Green Logic
+
+pci:v00001190*
+ ID_VENDOR_FROM_DATABASE=Tripace
+
+pci:v00001190d0000C731*
+ ID_PRODUCT_FROM_DATABASE=TP-910/920/940 PCI Ultra(Wide) SCSI Adapter
+
+pci:v00001191*
+ ID_VENDOR_FROM_DATABASE=Artop Electronic Corp
+
+pci:v00001191d00000003*
+ ID_PRODUCT_FROM_DATABASE=SCSI Cache Host Adapter
+
+pci:v00001191d00000004*
+ ID_PRODUCT_FROM_DATABASE=ATP8400
+
+pci:v00001191d00000005*
+ ID_PRODUCT_FROM_DATABASE=ATP850UF
+
+pci:v00001191d00000006*
+ ID_PRODUCT_FROM_DATABASE=ATP860 NO-BIOS
+
+pci:v00001191d00000007*
+ ID_PRODUCT_FROM_DATABASE=ATP860
+
+pci:v00001191d00000008*
+ ID_PRODUCT_FROM_DATABASE=ATP865 NO-ROM
+
+pci:v00001191d00000009*
+ ID_PRODUCT_FROM_DATABASE=ATP865
+
+pci:v00001191d0000000A*
+ ID_PRODUCT_FROM_DATABASE=ATP867-A
+
+pci:v00001191d0000000B*
+ ID_PRODUCT_FROM_DATABASE=ATP867-B
+
+pci:v00001191d0000000D*
+ ID_PRODUCT_FROM_DATABASE=ATP8620
+
+pci:v00001191d0000000E*
+ ID_PRODUCT_FROM_DATABASE=ATP8620
+
+pci:v00001191d00008002*
+ ID_PRODUCT_FROM_DATABASE=AEC6710 SCSI-2 Host Adapter
+
+pci:v00001191d00008010*
+ ID_PRODUCT_FROM_DATABASE=AEC6712UW SCSI
+
+pci:v00001191d00008020*
+ ID_PRODUCT_FROM_DATABASE=AEC6712U SCSI
+
+pci:v00001191d00008030*
+ ID_PRODUCT_FROM_DATABASE=AEC6712S SCSI
+
+pci:v00001191d00008040*
+ ID_PRODUCT_FROM_DATABASE=AEC6712D SCSI
+
+pci:v00001191d00008050*
+ ID_PRODUCT_FROM_DATABASE=AEC6712SUW SCSI
+
+pci:v00001191d00008060*
+ ID_PRODUCT_FROM_DATABASE=AEC6712 SCSI
+
+pci:v00001191d00008080*
+ ID_PRODUCT_FROM_DATABASE=AEC67160 SCSI
+
+pci:v00001191d00008081*
+ ID_PRODUCT_FROM_DATABASE=AEC67160S SCSI
+
+pci:v00001191d0000808A*
+ ID_PRODUCT_FROM_DATABASE=AEC67162 2-ch. LVD SCSI
+
+pci:v00001192*
+ ID_VENDOR_FROM_DATABASE=Densan Company Ltd
+
+pci:v00001193*
+ ID_VENDOR_FROM_DATABASE=Zeitnet Inc.
+
+pci:v00001193d00000001*
+ ID_PRODUCT_FROM_DATABASE=1221
+
+pci:v00001193d00000002*
+ ID_PRODUCT_FROM_DATABASE=1225
+
+pci:v00001194*
+ ID_VENDOR_FROM_DATABASE=Toucan Technology
+
+pci:v00001195*
+ ID_VENDOR_FROM_DATABASE=Ratoc System Inc
+
+pci:v00001196*
+ ID_VENDOR_FROM_DATABASE=Hytec Electronics Ltd
+
+pci:v00001197*
+ ID_VENDOR_FROM_DATABASE=Gage Applied Sciences, Inc.
+
+pci:v00001197d0000010C*
+ ID_PRODUCT_FROM_DATABASE=CompuScope 82G 8bit 2GS/s Analog Input Card
+
+pci:v00001198*
+ ID_VENDOR_FROM_DATABASE=Lambda Systems Inc
+
+pci:v00001199*
+ ID_VENDOR_FROM_DATABASE=Attachmate Corporation
+
+pci:v00001199d00000101*
+ ID_PRODUCT_FROM_DATABASE=Advanced ISCA/PCI Adapter
+
+pci:v00001199d00006832*
+ ID_PRODUCT_FROM_DATABASE=Sierra Wireless MC8780 Device
+
+pci:v0000119A*
+ ID_VENDOR_FROM_DATABASE=Mind Share, Inc.
+
+pci:v0000119B*
+ ID_VENDOR_FROM_DATABASE=Omega Micro Inc.
+
+pci:v0000119Bd00001221*
+ ID_PRODUCT_FROM_DATABASE=82C092G
+
+pci:v0000119C*
+ ID_VENDOR_FROM_DATABASE=Information Technology Inst.
+
+pci:v0000119D*
+ ID_VENDOR_FROM_DATABASE=Bug, Inc. Sapporo Japan
+
+pci:v0000119E*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Microelectronics Ltd.
+
+pci:v0000119Ed00000001*
+ ID_PRODUCT_FROM_DATABASE=FireStream 155
+
+pci:v0000119Ed00000003*
+ ID_PRODUCT_FROM_DATABASE=FireStream 50
+
+pci:v0000119F*
+ ID_VENDOR_FROM_DATABASE=Bull HN Information Systems
+
+pci:v000011A0*
+ ID_VENDOR_FROM_DATABASE=Convex Computer Corporation
+
+pci:v000011A1*
+ ID_VENDOR_FROM_DATABASE=Hamamatsu Photonics K.K.
+
+pci:v000011A2*
+ ID_VENDOR_FROM_DATABASE=Sierra Research and Technology
+
+pci:v000011A3*
+ ID_VENDOR_FROM_DATABASE=Deuretzbacher GmbH & Co. Eng. KG
+
+pci:v000011A4*
+ ID_VENDOR_FROM_DATABASE=Barco Graphics NV
+
+pci:v000011A5*
+ ID_VENDOR_FROM_DATABASE=Microunity Systems Eng. Inc
+
+pci:v000011A6*
+ ID_VENDOR_FROM_DATABASE=Pure Data Ltd.
+
+pci:v000011A7*
+ ID_VENDOR_FROM_DATABASE=Power Computing Corp.
+
+pci:v000011A8*
+ ID_VENDOR_FROM_DATABASE=Systech Corp.
+
+pci:v000011A9*
+ ID_VENDOR_FROM_DATABASE=InnoSys Inc.
+
+pci:v000011A9d00004240*
+ ID_PRODUCT_FROM_DATABASE=AMCC S933Q Intelligent Serial Card
+
+pci:v000011AA*
+ ID_VENDOR_FROM_DATABASE=Actel
+
+pci:v000011AB*
+ ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd.
+
+pci:v000011ABd00000146*
+ ID_PRODUCT_FROM_DATABASE=GT-64010/64010A System Controller
+
+pci:v000011ABd00000F53*
+ ID_PRODUCT_FROM_DATABASE=88E6318 Link Street network controller
+
+pci:v000011ABd000011AB*
+ ID_PRODUCT_FROM_DATABASE=MV88SE614x SATA II PCI-E controller
+
+pci:v000011ABd0000138F*
+ ID_PRODUCT_FROM_DATABASE=W8300 802.11 Adapter (rev 07)
+
+pci:v000011ABd00001FA6*
+ ID_PRODUCT_FROM_DATABASE=Marvell W8300 802.11 Adapter
+
+pci:v000011ABd00001FA6sv00001186sd00003B08*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.A1)
+
+pci:v000011ABd00001FA7*
+ ID_PRODUCT_FROM_DATABASE=88W8310 and 88W8000G [Libertas] 802.11g client chipset
+
+pci:v000011ABd00001FAA*
+ ID_PRODUCT_FROM_DATABASE=88w8335 [Libertas] 802.11b/g Wireless
+
+pci:v000011ABd00001FAAsv00001385sd00004E00*
+ ID_PRODUCT_FROM_DATABASE=WG511v2 54 Mbps Wireless PC Card
+
+pci:v000011ABd00001FAAsv00001385sd00006B00*
+ ID_PRODUCT_FROM_DATABASE=WG311v3 802.11g Wireless PCI Adapter
+
+pci:v000011ABd00001FAAsv00001737sd00000040*
+ ID_PRODUCT_FROM_DATABASE=WPC54G v5 802.11g Wireless-G Notebook Adapter
+
+pci:v000011ABd00002211*
+ ID_PRODUCT_FROM_DATABASE=88SB2211 PCI Express to PCI Bridge
+
+pci:v000011ABd00002A01*
+ ID_PRODUCT_FROM_DATABASE=88W8335 [Libertas] 802.11b/g Wireless
+
+pci:v000011ABd00002A02*
+ ID_PRODUCT_FROM_DATABASE=88W8361 [TopDog] 802.11n Wireless
+
+pci:v000011ABd00002A02sv000007D1sd00003B02*
+ ID_PRODUCT_FROM_DATABASE=DIR-615 rev. A1 Mini PCI Wireless Module
+
+pci:v000011ABd00002A02sv00001385sd00007C01*
+ ID_PRODUCT_FROM_DATABASE=WN511T RangeMax Next 300 Mbps Wireless Notebook Adapter
+
+pci:v000011ABd00002A02sv00001385sd00007E00*
+ ID_PRODUCT_FROM_DATABASE=WN311T RangeMax Next 300 Mbps Wireless PCI Adapter
+
+pci:v000011ABd00002A02sv00001799sd0000801B*
+ ID_PRODUCT_FROM_DATABASE=F5D8011 v2 802.11n N1 Wireless Notebook Card
+
+pci:v000011ABd00002A08*
+ ID_PRODUCT_FROM_DATABASE=88W8362e [TopDog] 802.11a/b/g/n Wireless
+
+pci:v000011ABd00002A0A*
+ ID_PRODUCT_FROM_DATABASE=88W8363 [TopDog] 802.11n Wireless
+
+pci:v000011ABd00002A0C*
+ ID_PRODUCT_FROM_DATABASE=88W8363 [TopDog] 802.11n Wireless
+
+pci:v000011ABd00002A24*
+ ID_PRODUCT_FROM_DATABASE=88W8363 [TopDog] 802.11n Wireless
+
+pci:v000011ABd00002A2B*
+ ID_PRODUCT_FROM_DATABASE=88W8687 [TopDog] 802.11b/g Wireless
+
+pci:v000011ABd00002A30*
+ ID_PRODUCT_FROM_DATABASE=88W8687 [TopDog] 802.11b/g Wireless
+
+pci:v000011ABd00002A40*
+ ID_PRODUCT_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless
+
+pci:v000011ABd00002A43*
+ ID_PRODUCT_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless
+
+pci:v000011ABd00004101*
+ ID_PRODUCT_FROM_DATABASE=OLPC Cafe Controller Secure Digital Controller
+
+pci:v000011ABd00004320*
+ ID_PRODUCT_FROM_DATABASE=88E8001 Gigabit Ethernet Controller
+
+pci:v000011ABd00004320sv00001019sd00000F38*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (ECS)
+
+pci:v000011ABd00004320sv00001019sd00008001*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (ECS)
+
+pci:v000011ABd00004320sv00001043sd0000173C*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Asus)
+
+pci:v000011ABd00004320sv00001043sd0000811A*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Asus)
+
+pci:v000011ABd00004320sv0000105Bsd00000C19*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
+
+pci:v000011ABd00004320sv000010B8sd0000B452*
+ ID_PRODUCT_FROM_DATABASE=EZ Card 1000 (SMC9452TXV.2)
+
+pci:v000011ABd00004320sv000011ABsd00000121*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8001
+
+pci:v000011ABd00004320sv000011ABsd00000321*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8003
+
+pci:v000011ABd00004320sv000011ABsd00001021*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8010
+
+pci:v000011ABd00004320sv000011ABsd00004320*
+ ID_PRODUCT_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Baset-T Constroller (Asus)
+
+pci:v000011ABd00004320sv000011ABsd00005021*
+ ID_PRODUCT_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
+
+pci:v000011ABd00004320sv000011ABsd00009521*
+ ID_PRODUCT_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
+
+pci:v000011ABd00004320sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
+
+pci:v000011ABd00004320sv0000147Bsd00001406*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Abit)
+
+pci:v000011ABd00004320sv000015D4sd00000047*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
+
+pci:v000011ABd00004320sv00001695sd00009025*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Epox)
+
+pci:v000011ABd00004320sv000017F2sd00001C03*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
+
+pci:v000011ABd00004320sv0000270Fsd00002803*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
+
+pci:v000011ABd00004340*
+ ID_PRODUCT_FROM_DATABASE=88E8021 PCI-X IPMI Gigabit Ethernet Controller
+
+pci:v000011ABd00004341*
+ ID_PRODUCT_FROM_DATABASE=88E8022 PCI-X IPMI Gigabit Ethernet Controller
+
+pci:v000011ABd00004342*
+ ID_PRODUCT_FROM_DATABASE=88E8061 PCI-E IPMI Gigabit Ethernet Controller
+
+pci:v000011ABd00004343*
+ ID_PRODUCT_FROM_DATABASE=88E8062 PCI-E IPMI Gigabit Ethernet Controller
+
+pci:v000011ABd00004344*
+ ID_PRODUCT_FROM_DATABASE=88E8021 PCI-X IPMI Gigabit Ethernet Controller
+
+pci:v000011ABd00004345*
+ ID_PRODUCT_FROM_DATABASE=88E8022 PCI-X IPMI Gigabit Ethernet Controller
+
+pci:v000011ABd00004346*
+ ID_PRODUCT_FROM_DATABASE=88E8061 PCI-E IPMI Gigabit Ethernet Controller
+
+pci:v000011ABd00004347*
+ ID_PRODUCT_FROM_DATABASE=88E8062 PCI-E IPMI Gigabit Ethernet Controller
+
+pci:v000011ABd00004347sv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 PrAMC Gigabit Ethernet
+
+pci:v000011ABd00004350*
+ ID_PRODUCT_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller
+
+pci:v000011ABd00004350sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (Toshiba)
+
+pci:v000011ABd00004350sv000011ABsd00003521*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8035
+
+pci:v000011ABd00004350sv00001854sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd0000000E*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd0000000F*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd00000011*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd00000012*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd00000016*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd00000017*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd00000018*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd00000019*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd0000001C*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd0000001E*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004350sv00001854sd00000020*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351*
+ ID_PRODUCT_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller
+
+pci:v000011ABd00004351sv0000107Bsd00004009*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Wistron)
+
+pci:v000011ABd00004351sv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Panasonic)
+
+pci:v000011ABd00004351sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Toshiba)
+
+pci:v000011ABd00004351sv00001179sd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Compal)
+
+pci:v000011ABd00004351sv00001179sd0000FF10*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Inventec)
+
+pci:v000011ABd00004351sv000011ABsd00003621*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8036
+
+pci:v000011ABd00004351sv000013D1sd0000AC12*
+ ID_PRODUCT_FROM_DATABASE=Abocom EFE3K - 10/100 Ethernet Expresscard
+
+pci:v000011ABd00004351sv0000161Fsd0000203D*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Arima)
+
+pci:v000011ABd00004351sv00001854sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd0000000E*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd0000000F*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd00000011*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd00000012*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd00000016*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd00000017*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd00000018*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd00000019*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd0000001C*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd0000001E*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004351sv00001854sd00000020*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+
+pci:v000011ABd00004352*
+ ID_PRODUCT_FROM_DATABASE=88E8038 PCI-E Fast Ethernet Controller
+
+pci:v000011ABd00004353*
+ ID_PRODUCT_FROM_DATABASE=88E8039 PCI-E Fast Ethernet Controller
+
+pci:v000011ABd00004353sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v000011ABd00004354*
+ ID_PRODUCT_FROM_DATABASE=88E8040 PCI-E Fast Ethernet Controller
+
+pci:v000011ABd00004354sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v000011ABd00004355*
+ ID_PRODUCT_FROM_DATABASE=88E8040T PCI-E Fast Ethernet Controller
+
+pci:v000011ABd00004355sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v000011ABd00004356*
+ ID_PRODUCT_FROM_DATABASE=88EC033 PCI-E Fast Ethernet Controller
+
+pci:v000011ABd00004357*
+ ID_PRODUCT_FROM_DATABASE=88E8042 PCI-E Fast Ethernet Controller
+
+pci:v000011ABd0000435A*
+ ID_PRODUCT_FROM_DATABASE=88E8048 PCI-E Fast Ethernet Controller
+
+pci:v000011ABd00004360*
+ ID_PRODUCT_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller
+
+pci:v000011ABd00004360sv00001043sd00008134*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Asus)
+
+pci:v000011ABd00004360sv0000107Bsd00004009*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
+
+pci:v000011ABd00004360sv000011ABsd00005221*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8052
+
+pci:v000011ABd00004360sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
+
+pci:v000011ABd00004360sv00001462sd0000052C*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (MSI)
+
+pci:v000011ABd00004360sv00001849sd00008052*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
+
+pci:v000011ABd00004360sv0000A0A0sd00000509*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
+
+pci:v000011ABd00004361*
+ ID_PRODUCT_FROM_DATABASE=88E8050 PCI-E ASF Gigabit Ethernet Controller
+
+pci:v000011ABd00004361sv0000107Bsd00003015*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Gateway)
+
+pci:v000011ABd00004361sv000011ABsd00005021*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Intel)
+
+pci:v000011ABd00004361sv00008086sd00003063*
+ ID_PRODUCT_FROM_DATABASE=D925XCVLK mainboard
+
+pci:v000011ABd00004361sv00008086sd00003439*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Intel)
+
+pci:v000011ABd00004362*
+ ID_PRODUCT_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd00004362sv0000103Csd00002A0D*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Asus)
+
+pci:v000011ABd00004362sv00001043sd00008142*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet controller PCIe (Asus)
+
+pci:v000011ABd00004362sv0000109Fsd00003197*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
+
+pci:v000011ABd00004362sv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Panasonic)
+
+pci:v000011ABd00004362sv000010FDsd0000A430*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
+
+pci:v000011ABd00004362sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
+
+pci:v000011ABd00004362sv00001179sd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Compal)
+
+pci:v000011ABd00004362sv00001179sd0000FF10*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
+
+pci:v000011ABd00004362sv000011ABsd00005321*
+ ID_PRODUCT_FROM_DATABASE=Marvell RDK-8053
+
+pci:v000011ABd00004362sv00001297sd0000C240*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+
+pci:v000011ABd00004362sv00001297sd0000C241*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+
+pci:v000011ABd00004362sv00001297sd0000C242*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+
+pci:v000011ABd00004362sv00001297sd0000C243*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+
+pci:v000011ABd00004362sv00001297sd0000C244*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+
+pci:v000011ABd00004362sv000013D1sd0000AC11*
+ ID_PRODUCT_FROM_DATABASE=EGE5K - Giga Ethernet Expresscard
+
+pci:v000011ABd00004362sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
+
+pci:v000011ABd00004362sv00001462sd0000058C*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (MSI)
+
+pci:v000011ABd00004362sv000014C0sd00000012*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Compal)
+
+pci:v000011ABd00004362sv00001558sd000004A0*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
+
+pci:v000011ABd00004362sv000015BDsd00001003*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (DFI)
+
+pci:v000011ABd00004362sv0000161Fsd0000203C*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Arima)
+
+pci:v000011ABd00004362sv0000161Fsd0000203D*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Arima)
+
+pci:v000011ABd00004362sv00001695sd00009029*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Epox)
+
+pci:v000011ABd00004362sv000017F2sd00002C08*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
+
+pci:v000011ABd00004362sv000017FFsd00000585*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
+
+pci:v000011ABd00004362sv00001849sd00008053*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
+
+pci:v000011ABd00004362sv00001854sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd00000010*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd00000013*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd00000014*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd00000015*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd0000001A*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd0000001B*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd0000001D*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd0000001F*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd00000021*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv00001854sd00000022*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+
+pci:v000011ABd00004362sv0000270Fsd00002801*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
+
+pci:v000011ABd00004362sv0000A0A0sd00000506*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
+
+pci:v000011ABd00004363*
+ ID_PRODUCT_FROM_DATABASE=88E8055 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd00004364*
+ ID_PRODUCT_FROM_DATABASE=88E8056 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd00004364sv000011BAsd000000BA*
+ ID_PRODUCT_FROM_DATABASE=8056 Gigabit Ethernet Controller
+
+pci:v000011ABd00004365*
+ ID_PRODUCT_FROM_DATABASE=88E8070 based Ethernet Controller
+
+pci:v000011ABd00004366*
+ ID_PRODUCT_FROM_DATABASE=88EC036 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd00004367*
+ ID_PRODUCT_FROM_DATABASE=88EC032 Ethernet Controller
+
+pci:v000011ABd00004368*
+ ID_PRODUCT_FROM_DATABASE=88EC034 Ethernet Controller
+
+pci:v000011ABd00004369*
+ ID_PRODUCT_FROM_DATABASE=88EC042 Ethernet Controller
+
+pci:v000011ABd0000436A*
+ ID_PRODUCT_FROM_DATABASE=88E8058 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd0000436Asv000011ABsd000000BA*
+ ID_PRODUCT_FROM_DATABASE=Imac 8,1 Wired Ethernet Adapter
+
+pci:v000011ABd0000436B*
+ ID_PRODUCT_FROM_DATABASE=88E8071 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd0000436C*
+ ID_PRODUCT_FROM_DATABASE=88E8072 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd0000436D*
+ ID_PRODUCT_FROM_DATABASE=88E8055 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd00004370*
+ ID_PRODUCT_FROM_DATABASE=88E8075 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd00004380*
+ ID_PRODUCT_FROM_DATABASE=88E8057 PCI-E Gigabit Ethernet Controller
+
+pci:v000011ABd00004381*
+ ID_PRODUCT_FROM_DATABASE=Yukon Optima 88E8059 [PCIe Gigabit Ethernet Controller with AVB]
+
+pci:v000011ABd00004611*
+ ID_PRODUCT_FROM_DATABASE=GT-64115 System Controller
+
+pci:v000011ABd00004620*
+ ID_PRODUCT_FROM_DATABASE=GT-64120/64120A/64121A System Controller
+
+pci:v000011ABd00004801*
+ ID_PRODUCT_FROM_DATABASE=GT-48001
+
+pci:v000011ABd00005005*
+ ID_PRODUCT_FROM_DATABASE=Belkin F5D5005 Gigabit Desktop Network PCI Card
+
+pci:v000011ABd00005040*
+ ID_PRODUCT_FROM_DATABASE=MV88SX5040 4-port SATA I PCI-X Controller
+
+pci:v000011ABd00005041*
+ ID_PRODUCT_FROM_DATABASE=MV88SX5041 4-port SATA I PCI-X Controller
+
+pci:v000011ABd00005080*
+ ID_PRODUCT_FROM_DATABASE=MV88SX5080 8-port SATA I PCI-X Controller
+
+pci:v000011ABd00005081*
+ ID_PRODUCT_FROM_DATABASE=MV88SX5081 8-port SATA I PCI-X Controller
+
+pci:v000011ABd00005181*
+ ID_PRODUCT_FROM_DATABASE=88f5181 [Orion-1] ARM SoC
+
+pci:v000011ABd00005182*
+ ID_PRODUCT_FROM_DATABASE=88f5182 [Orion-NAS] ARM SoC
+
+pci:v000011ABd00005281*
+ ID_PRODUCT_FROM_DATABASE=88f5281 [Orion-2] ARM SoC
+
+pci:v000011ABd00006041*
+ ID_PRODUCT_FROM_DATABASE=MV88SX6041 4-port SATA II PCI-X Controller
+
+pci:v000011ABd00006042*
+ ID_PRODUCT_FROM_DATABASE=88SX6042 PCI-X 4-Port SATA-II
+
+pci:v000011ABd00006081*
+ ID_PRODUCT_FROM_DATABASE=MV88SX6081 8-port SATA II PCI-X Controller
+
+pci:v000011ABd00006101*
+ ID_PRODUCT_FROM_DATABASE=88SE6101/6102 single-port PATA133 interface
+
+pci:v000011ABd00006111*
+ ID_PRODUCT_FROM_DATABASE=88SE6111 1-port PATA133(IDE) and 1-port SATA II Controllers
+
+pci:v000011ABd00006121*
+ ID_PRODUCT_FROM_DATABASE=88SE6121 SATA II / PATA Controller
+
+pci:v000011ABd00006141*
+ ID_PRODUCT_FROM_DATABASE=88SE614x SATA II PCI-E controller
+
+pci:v000011ABd00006145*
+ ID_PRODUCT_FROM_DATABASE=88SE6145 SATA II PCI-E controller
+
+pci:v000011ABd00006180*
+ ID_PRODUCT_FROM_DATABASE=88F6180 [Kirkwood] ARM SoC
+
+pci:v000011ABd00006192*
+ ID_PRODUCT_FROM_DATABASE=88F6190/6192 [Kirkwood] ARM SoC
+
+pci:v000011ABd00006281*
+ ID_PRODUCT_FROM_DATABASE=88F6281 [Kirkwood] ARM SoC
+
+pci:v000011ABd00006381*
+ ID_PRODUCT_FROM_DATABASE=MV78xx0 [Discovery Innovation] ARM SoC
+
+pci:v000011ABd00006440*
+ ID_PRODUCT_FROM_DATABASE=88SE6440 SAS/SATA PCIe controller
+
+pci:v000011ABd00006450*
+ ID_PRODUCT_FROM_DATABASE=64560 System Controller
+
+pci:v000011ABd00006460*
+ ID_PRODUCT_FROM_DATABASE=MV64360/64361/64362 System Controller
+
+pci:v000011ABd00006480*
+ ID_PRODUCT_FROM_DATABASE=MV64460/64461/64462 System Controller
+
+pci:v000011ABd00006480sv00001775sd0000C200*
+ ID_PRODUCT_FROM_DATABASE=C2K CompactPCI single board computer
+
+pci:v000011ABd00006485*
+ ID_PRODUCT_FROM_DATABASE=MV64460/64461/64462 System Controller, Revision B
+
+pci:v000011ABd00007042*
+ ID_PRODUCT_FROM_DATABASE=88SX7042 PCI-e 4-port SATA-II
+
+pci:v000011ABd00007042sv000016B8sd0000434B*
+ ID_PRODUCT_FROM_DATABASE=Tempo SATA E4P
+
+pci:v000011ABd00007810*
+ ID_PRODUCT_FROM_DATABASE=MV78100 [Discovery Innovation] ARM SoC
+
+pci:v000011ABd00007820*
+ ID_PRODUCT_FROM_DATABASE=MV78200 [Discovery Innovation] ARM SoC
+
+pci:v000011ABd0000F003*
+ ID_PRODUCT_FROM_DATABASE=GT-64010 Primary Image Piranha Image Generator
+
+pci:v000011AC*
+ ID_VENDOR_FROM_DATABASE=Canon Information Systems Research Aust.
+
+pci:v000011AD*
+ ID_VENDOR_FROM_DATABASE=Lite-On Communications Inc
+
+pci:v000011ADd00000002*
+ ID_PRODUCT_FROM_DATABASE=LNE100TX
+
+pci:v000011ADd00000002sv000011ADsd00000002*
+ ID_PRODUCT_FROM_DATABASE=LNE100TX
+
+pci:v000011ADd00000002sv000011ADsd00000003*
+ ID_PRODUCT_FROM_DATABASE=LNE100TX
+
+pci:v000011ADd00000002sv000011ADsd0000F003*
+ ID_PRODUCT_FROM_DATABASE=LNE100TX
+
+pci:v000011ADd00000002sv000011ADsd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=LNE100TX
+
+pci:v000011ADd00000002sv00001385sd0000F004*
+ ID_PRODUCT_FROM_DATABASE=FA310TX
+
+pci:v000011ADd00000002sv00002646sd0000F002*
+ ID_PRODUCT_FROM_DATABASE=KNE110TX EtheRx Fast Ethernet
+
+pci:v000011ADd0000C115*
+ ID_PRODUCT_FROM_DATABASE=LNE100TX [Linksys EtherFast 10/100]
+
+pci:v000011ADd0000C115sv000011ADsd0000C001*
+ ID_PRODUCT_FROM_DATABASE=LNE100TX [ver 2.0]
+
+pci:v000011ADd0000C115sv00002646sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=KNE111TX
+
+pci:v000011AE*
+ ID_VENDOR_FROM_DATABASE=Aztech System Ltd
+
+pci:v000011AF*
+ ID_VENDOR_FROM_DATABASE=Avid Technology Inc.
+
+pci:v000011AFd00000001*
+ ID_PRODUCT_FROM_DATABASE=Cinema
+
+pci:v000011AFd0000EE40*
+ ID_PRODUCT_FROM_DATABASE=Digidesign Audiomedia III
+
+pci:v000011B0*
+ ID_VENDOR_FROM_DATABASE=V3 Semiconductor Inc.
+
+pci:v000011B0d00000002*
+ ID_PRODUCT_FROM_DATABASE=V300PSC
+
+pci:v000011B0d00000292*
+ ID_PRODUCT_FROM_DATABASE=V292PBC [Am29030/40 Bridge]
+
+pci:v000011B0d00000960*
+ ID_PRODUCT_FROM_DATABASE=V96xPBC
+
+pci:v000011B0d0000C960*
+ ID_PRODUCT_FROM_DATABASE=V96DPC
+
+pci:v000011B1*
+ ID_VENDOR_FROM_DATABASE=Apricot Computers
+
+pci:v000011B2*
+ ID_VENDOR_FROM_DATABASE=Eastman Kodak
+
+pci:v000011B3*
+ ID_VENDOR_FROM_DATABASE=Barr Systems Inc.
+
+pci:v000011B4*
+ ID_VENDOR_FROM_DATABASE=Leitch Technology International
+
+pci:v000011B5*
+ ID_VENDOR_FROM_DATABASE=Radstone Technology Plc
+
+pci:v000011B6*
+ ID_VENDOR_FROM_DATABASE=United Video Corp
+
+pci:v000011B7*
+ ID_VENDOR_FROM_DATABASE=Motorola
+
+pci:v000011B8*
+ ID_VENDOR_FROM_DATABASE=XPoint Technologies, Inc
+
+pci:v000011B8d00000001*
+ ID_PRODUCT_FROM_DATABASE=Quad PeerMaster
+
+pci:v000011B9*
+ ID_VENDOR_FROM_DATABASE=Pathlight Technology Inc.
+
+pci:v000011B9d0000C0ED*
+ ID_PRODUCT_FROM_DATABASE=SSA Controller
+
+pci:v000011BA*
+ ID_VENDOR_FROM_DATABASE=Videotron Corp
+
+pci:v000011BB*
+ ID_VENDOR_FROM_DATABASE=Pyramid Technology
+
+pci:v000011BC*
+ ID_VENDOR_FROM_DATABASE=Network Peripherals Inc
+
+pci:v000011BCd00000001*
+ ID_PRODUCT_FROM_DATABASE=NP-PCI
+
+pci:v000011BD*
+ ID_VENDOR_FROM_DATABASE=Pinnacle Systems Inc.
+
+pci:v000011BDd0000002E*
+ ID_PRODUCT_FROM_DATABASE=PCTV 40i
+
+pci:v000011BDd00000040*
+ ID_PRODUCT_FROM_DATABASE=Royal TS Function 1
+
+pci:v000011BDd00000040sv000011BDsd00000044*
+ ID_PRODUCT_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Tuner 1
+
+pci:v000011BDd00000040sv000011BDsd00000045*
+ ID_PRODUCT_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Tuner 1
+
+pci:v000011BDd00000041*
+ ID_PRODUCT_FROM_DATABASE=RoyalTS Function 2
+
+pci:v000011BDd00000041sv000011BDsd00000044*
+ ID_PRODUCT_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Tuner 2
+
+pci:v000011BDd00000041sv000011BDsd00000045*
+ ID_PRODUCT_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Tuner 2
+
+pci:v000011BDd00000042*
+ ID_PRODUCT_FROM_DATABASE=Royal TS Function 3
+
+pci:v000011BDd00000042sv000011BDsd00000044*
+ ID_PRODUCT_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Common
+
+pci:v000011BDd00000042sv000011BDsd00000045*
+ ID_PRODUCT_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Common
+
+pci:v000011BDd00000051*
+ ID_PRODUCT_FROM_DATABASE=PCTV HD 800i
+
+pci:v000011BDd0000BEDE*
+ ID_PRODUCT_FROM_DATABASE=AV/DV Studio Capture Card
+
+pci:v000011BE*
+ ID_VENDOR_FROM_DATABASE=International Microcircuits Inc
+
+pci:v000011BF*
+ ID_VENDOR_FROM_DATABASE=Astrodesign, Inc.
+
+pci:v000011C0*
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard
+
+pci:v000011C1*
+ ID_VENDOR_FROM_DATABASE=LSI Corporation
+
+pci:v000011C1d00000440*
+ ID_PRODUCT_FROM_DATABASE=56k WinModem
+
+pci:v000011C1d00000440sv00001033sd00008015*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv00001033sd00008047*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv00001033sd0000804F*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv000010CFsd0000102C*
+ ID_PRODUCT_FROM_DATABASE=LB LT Modem V.90 56k
+
+pci:v000011C1d00000440sv000010CFsd0000104A*
+ ID_PRODUCT_FROM_DATABASE=BIBLO LT Modem 56k
+
+pci:v000011C1d00000440sv000010CFsd0000105F*
+ ID_PRODUCT_FROM_DATABASE=LB2 LT Modem V.90 56k
+
+pci:v000011C1d00000440sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Internal V.90 Modem
+
+pci:v000011C1d00000440sv000011C1sd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv0000122Dsd00004101*
+ ID_PRODUCT_FROM_DATABASE=MDP7800-U Modem
+
+pci:v000011C1d00000440sv0000122Dsd00004102*
+ ID_PRODUCT_FROM_DATABASE=MDP7800SP-U Modem
+
+pci:v000011C1d00000440sv000013E0sd00000040*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv000013E0sd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv000013E0sd00000441*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv000013E0sd00000450*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv000013E0sd0000F100*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv000013E0sd0000F101*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000440sv0000144Dsd00002101*
+ ID_PRODUCT_FROM_DATABASE=LT56PV Modem
+
+pci:v000011C1d00000440sv0000149Fsd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000441*
+ ID_PRODUCT_FROM_DATABASE=56k WinModem
+
+pci:v000011C1d00000441sv00001033sd0000804D*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv00001033sd00008065*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv00001092sd00000440*
+ ID_PRODUCT_FROM_DATABASE=Supra 56i
+
+pci:v000011C1d00000441sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Internal V.90 Modem
+
+pci:v000011C1d00000441sv000011C1sd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv000011C1sd00000441*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv0000122Dsd00004100*
+ ID_PRODUCT_FROM_DATABASE=MDP7800-U Modem
+
+pci:v000011C1d00000441sv000013E0sd00000040*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv000013E0sd00000100*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv000013E0sd00000410*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv000013E0sd00000420*
+ ID_PRODUCT_FROM_DATABASE=TelePath Internet 56k WinModem
+
+pci:v000011C1d00000441sv000013E0sd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv000013E0sd00000443*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv000013E0sd0000F102*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv00001416sd00009804*
+ ID_PRODUCT_FROM_DATABASE=CommWave 56k Modem
+
+pci:v000011C1d00000441sv0000141Dsd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000441sv0000144Fsd00000441*
+ ID_PRODUCT_FROM_DATABASE=Lucent 56k V.90 DF Modem
+
+pci:v000011C1d00000441sv0000144Fsd00000449*
+ ID_PRODUCT_FROM_DATABASE=Lucent 56k V.90 DF Modem
+
+pci:v000011C1d00000441sv0000144Fsd0000110D*
+ ID_PRODUCT_FROM_DATABASE=Lucent Win Modem
+
+pci:v000011C1d00000441sv00001468sd00000441*
+ ID_PRODUCT_FROM_DATABASE=Presario 56k V.90 DF Modem
+
+pci:v000011C1d00000441sv00001668sd00000440*
+ ID_PRODUCT_FROM_DATABASE=Lucent Win Modem
+
+pci:v000011C1d00000442*
+ ID_PRODUCT_FROM_DATABASE=56k WinModem
+
+pci:v000011C1d00000442sv000011C1sd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d00000442sv000011C1sd00000442*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d00000442sv000013E0sd00000412*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d00000442sv000013E0sd00000442*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d00000442sv000013FCsd00002471*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d00000442sv0000144Dsd00002104*
+ ID_PRODUCT_FROM_DATABASE=LT56PT Modem
+
+pci:v000011C1d00000442sv0000144Fsd00001104*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d00000442sv0000149Fsd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d00000442sv00001668sd00000440*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d00000443*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000444*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000445*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000445sv00008086sd00002203*
+ ID_PRODUCT_FROM_DATABASE=PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card)
+
+pci:v000011C1d00000445sv00008086sd00002204*
+ ID_PRODUCT_FROM_DATABASE=PRO/100+ MiniPCI on Armada E500
+
+pci:v000011C1d00000446*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000447*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000448*
+ ID_PRODUCT_FROM_DATABASE=WinModem 56k
+
+pci:v000011C1d00000448sv00001014sd00000131*
+ ID_PRODUCT_FROM_DATABASE=Lucent Win Modem
+
+pci:v000011C1d00000448sv00001033sd00008066*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000448sv000013E0sd00000030*
+ ID_PRODUCT_FROM_DATABASE=56k Voice Modem
+
+pci:v000011C1d00000448sv000013E0sd00000040*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+
+pci:v000011C1d00000448sv00001668sd00002400*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k (MiniPCI Ethernet+Modem)
+
+pci:v000011C1d00000449*
+ ID_PRODUCT_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k
+
+pci:v000011C1d00000449sv00000E11sd0000B14D*
+ ID_PRODUCT_FROM_DATABASE=56k V.90 Modem
+
+pci:v000011C1d00000449sv00001014sd0000018C*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 600X
+
+pci:v000011C1d00000449sv000013E0sd00000020*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax
+
+pci:v000011C1d00000449sv000013E0sd00000041*
+ ID_PRODUCT_FROM_DATABASE=TelePath Internet 56k WinModem
+
+pci:v000011C1d00000449sv00001436sd00000440*
+ ID_PRODUCT_FROM_DATABASE=Lucent Win Modem
+
+pci:v000011C1d00000449sv0000144Fsd00000449*
+ ID_PRODUCT_FROM_DATABASE=Lucent 56k V.90 DFi Modem
+
+pci:v000011C1d00000449sv00001468sd00000410*
+ ID_PRODUCT_FROM_DATABASE=IBM ThinkPad T23
+
+pci:v000011C1d00000449sv00001468sd00000440*
+ ID_PRODUCT_FROM_DATABASE=Lucent Win Modem
+
+pci:v000011C1d00000449sv00001468sd00000449*
+ ID_PRODUCT_FROM_DATABASE=Presario 56k V.90 DFi Modem
+
+pci:v000011C1d0000044A*
+ ID_PRODUCT_FROM_DATABASE=F-1156IV WinModem (V90, 56KFlex)
+
+pci:v000011C1d0000044Asv000010CFsd00001072*
+ ID_PRODUCT_FROM_DATABASE=LB Global LT Modem
+
+pci:v000011C1d0000044Asv000013E0sd00000012*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d0000044Asv000013E0sd00000042*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d0000044Asv0000144Fsd00001005*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+
+pci:v000011C1d0000044B*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d0000044C*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d0000044D*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d0000044E*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d0000044F*
+ ID_PRODUCT_FROM_DATABASE=V90 WildWire Modem
+
+pci:v000011C1d00000450*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000450sv00001033sd000080A8*
+ ID_PRODUCT_FROM_DATABASE=Versa Note Vxi
+
+pci:v000011C1d00000450sv0000144Fsd00004005*
+ ID_PRODUCT_FROM_DATABASE=Magnia SG20
+
+pci:v000011C1d00000450sv00001468sd00000450*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v000011C1d00000451*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000452*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000453*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000454*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000455*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000456*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000457*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000458*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000459*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d0000045A*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d0000045C*
+ ID_PRODUCT_FROM_DATABASE=LT WinModem
+
+pci:v000011C1d00000461*
+ ID_PRODUCT_FROM_DATABASE=V90 WildWire Modem
+
+pci:v000011C1d00000462*
+ ID_PRODUCT_FROM_DATABASE=V90 WildWire Modem
+
+pci:v000011C1d00000480*
+ ID_PRODUCT_FROM_DATABASE=Venus Modem (V90, 56KFlex)
+
+pci:v000011C1d0000048C*
+ ID_PRODUCT_FROM_DATABASE=V.92 56K WinModem
+
+pci:v000011C1d0000048F*
+ ID_PRODUCT_FROM_DATABASE=V.92 56k WinModem
+
+pci:v000011C1d00000620*
+ ID_PRODUCT_FROM_DATABASE=Lucent V.92 Data/Fax Modem
+
+pci:v000011C1d00001040*
+ ID_PRODUCT_FROM_DATABASE=HDA softmodem
+
+pci:v000011C1d00002600*
+ ID_PRODUCT_FROM_DATABASE=StarPro26XX family (SP2601, SP2603, SP2612) DSP
+
+pci:v000011C1d00003026*
+ ID_PRODUCT_FROM_DATABASE=HDA Modem
+
+pci:v000011C1d00005400*
+ ID_PRODUCT_FROM_DATABASE=OR3TP12 FPSC
+
+pci:v000011C1d00005656*
+ ID_PRODUCT_FROM_DATABASE=Venus Modem
+
+pci:v000011C1d00005801*
+ ID_PRODUCT_FROM_DATABASE=USB
+
+pci:v000011C1d00005802*
+ ID_PRODUCT_FROM_DATABASE=USS-312 USB Controller
+
+pci:v000011C1d00005803*
+ ID_PRODUCT_FROM_DATABASE=USS-344S USB Controller
+
+pci:v000011C1d00005811*
+ ID_PRODUCT_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller
+
+pci:v000011C1d00005811sv0000103Csd00002A34*
+ ID_PRODUCT_FROM_DATABASE=Pavilion a1677c
+
+pci:v000011C1d00005811sv0000103Csd00002A9E*
+ ID_PRODUCT_FROM_DATABASE=Pavilion p6310f
+
+pci:v000011C1d00005811sv00001043sd00008294*
+ ID_PRODUCT_FROM_DATABASE=LSI FW322/323 IEEE 1394a FireWire Controller
+
+pci:v000011C1d00005811sv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v000011C1d00005811sv0000DEADsd00000800*
+ ID_PRODUCT_FROM_DATABASE=FireWire Host Bus Adapter
+
+pci:v000011C1d00005901*
+ ID_PRODUCT_FROM_DATABASE=FW643 [TrueFire] PCIe 1394b Controller
+
+pci:v000011C1d00005901sv000011C1sd00005900*
+ ID_PRODUCT_FROM_DATABASE=FW643 [TrueFire] PCIe 1394b Controller
+
+pci:v000011C1d00005901sv00001443sd00000643*
+ ID_PRODUCT_FROM_DATABASE=FireBoard800-e V.2
+
+pci:v000011C1d00005901sv00001546sd00000643*
+ ID_PRODUCT_FROM_DATABASE=FWB-PCIE1X2x
+
+pci:v000011C1d00005903*
+ ID_PRODUCT_FROM_DATABASE=FW533 [TrueFire] PCIe 1394a Controller
+
+pci:v000011C1d00008110*
+ ID_PRODUCT_FROM_DATABASE=T8110 H.100/H.110 TDM switch
+
+pci:v000011C1d00008110sv000012D9sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=E1/T1 PMXc cPCI carrier card
+
+pci:v000011C1d0000AB10*
+ ID_PRODUCT_FROM_DATABASE=WL60010 Wireless LAN MAC
+
+pci:v000011C1d0000AB11*
+ ID_PRODUCT_FROM_DATABASE=WL60040 Multimode Wireles LAN MAC
+
+pci:v000011C1d0000AB11sv000011C1sd0000AB12*
+ ID_PRODUCT_FROM_DATABASE=WaveLAN 11abg Cardbus card (Model 1102)
+
+pci:v000011C1d0000AB11sv000011C1sd0000AB13*
+ ID_PRODUCT_FROM_DATABASE=WaveLAN 11abg MiniPCI card (Model 0512)
+
+pci:v000011C1d0000AB11sv000011C1sd0000AB15*
+ ID_PRODUCT_FROM_DATABASE=WaveLAN 11abg Cardbus card (Model 1106)
+
+pci:v000011C1d0000AB11sv000011C1sd0000AB16*
+ ID_PRODUCT_FROM_DATABASE=WaveLAN 11abg MiniPCI card (Model 0516)
+
+pci:v000011C1d0000AB20*
+ ID_PRODUCT_FROM_DATABASE=ORiNOCO PCI Adapter
+
+pci:v000011C1d0000AB21*
+ ID_PRODUCT_FROM_DATABASE=Agere Wireless PCI Adapter
+
+pci:v000011C1d0000AB30*
+ ID_PRODUCT_FROM_DATABASE=Hermes2 Mini-PCI WaveLAN a/b/g
+
+pci:v000011C1d0000AB30sv000014CDsd00002012*
+ ID_PRODUCT_FROM_DATABASE=Hermes2 Mini-PCI WaveLAN a/b/g
+
+pci:v000011C1d0000ED00*
+ ID_PRODUCT_FROM_DATABASE=ET-131x PCI-E Ethernet Controller
+
+pci:v000011C1d0000ED01*
+ ID_PRODUCT_FROM_DATABASE=ET-131x PCI-E Ethernet Controller
+
+pci:v000011C2*
+ ID_VENDOR_FROM_DATABASE=Sand Microelectronics
+
+pci:v000011C3*
+ ID_VENDOR_FROM_DATABASE=NEC Corporation
+
+pci:v000011C4*
+ ID_VENDOR_FROM_DATABASE=Document Technologies, Inc
+
+pci:v000011C5*
+ ID_VENDOR_FROM_DATABASE=Shiva Corporation
+
+pci:v000011C6*
+ ID_VENDOR_FROM_DATABASE=Dainippon Screen Mfg. Co. Ltd
+
+pci:v000011C7*
+ ID_VENDOR_FROM_DATABASE=D.C.M. Data Systems
+
+pci:v000011C8*
+ ID_VENDOR_FROM_DATABASE=Dolphin Interconnect Solutions AS
+
+pci:v000011C8d00000658*
+ ID_PRODUCT_FROM_DATABASE=PSB32 SCI-Adapter D31x
+
+pci:v000011C8d0000D665*
+ ID_PRODUCT_FROM_DATABASE=PSB64 SCI-Adapter D32x
+
+pci:v000011C8d0000D667*
+ ID_PRODUCT_FROM_DATABASE=PSB66 SCI-Adapter D33x
+
+pci:v000011C9*
+ ID_VENDOR_FROM_DATABASE=Magma
+
+pci:v000011C9d00000010*
+ ID_PRODUCT_FROM_DATABASE=16-line serial port w/- DMA
+
+pci:v000011C9d00000011*
+ ID_PRODUCT_FROM_DATABASE=4-line serial port w/- DMA
+
+pci:v000011CA*
+ ID_VENDOR_FROM_DATABASE=LSI Systems, Inc
+
+pci:v000011CB*
+ ID_VENDOR_FROM_DATABASE=Specialix Research Ltd.
+
+pci:v000011CBd00002000*
+ ID_PRODUCT_FROM_DATABASE=PCI_9050
+
+pci:v000011CBd00002000sv000011CBsd00000200*
+ ID_PRODUCT_FROM_DATABASE=SX
+
+pci:v000011CBd00002000sv000011CBsd0000B008*
+ ID_PRODUCT_FROM_DATABASE=I/O8+
+
+pci:v000011CBd00004000*
+ ID_PRODUCT_FROM_DATABASE=SUPI_1
+
+pci:v000011CBd00008000*
+ ID_PRODUCT_FROM_DATABASE=T225
+
+pci:v000011CC*
+ ID_VENDOR_FROM_DATABASE=Michels & Kleberhoff Computer GmbH
+
+pci:v000011CD*
+ ID_VENDOR_FROM_DATABASE=HAL Computer Systems, Inc.
+
+pci:v000011CE*
+ ID_VENDOR_FROM_DATABASE=Netaccess
+
+pci:v000011CF*
+ ID_VENDOR_FROM_DATABASE=Pioneer Electronic Corporation
+
+pci:v000011D0*
+ ID_VENDOR_FROM_DATABASE=Lockheed Martin Federal Systems-Manassas
+
+pci:v000011D1*
+ ID_VENDOR_FROM_DATABASE=Auravision
+
+pci:v000011D1d000001F7*
+ ID_PRODUCT_FROM_DATABASE=VxP524
+
+pci:v000011D1d000001F9*
+ ID_PRODUCT_FROM_DATABASE=VxP951
+
+pci:v000011D2*
+ ID_VENDOR_FROM_DATABASE=Intercom Inc.
+
+pci:v000011D3*
+ ID_VENDOR_FROM_DATABASE=Trancell Systems Inc
+
+pci:v000011D4*
+ ID_VENDOR_FROM_DATABASE=Analog Devices
+
+pci:v000011D4d00000078*
+ ID_PRODUCT_FROM_DATABASE=AD1986HD sound chip
+
+pci:v000011D4d00001535*
+ ID_PRODUCT_FROM_DATABASE=Blackfin BF535 processor
+
+pci:v000011D4d00001805*
+ ID_PRODUCT_FROM_DATABASE=SM56 PCI modem
+
+pci:v000011D4d00001889*
+ ID_PRODUCT_FROM_DATABASE=AD1889 sound chip
+
+pci:v000011D4d0000194A*
+ ID_PRODUCT_FROM_DATABASE=AD1984A sound chip
+
+pci:v000011D4d00001981*
+ ID_PRODUCT_FROM_DATABASE=AD1981HD sound chip
+
+pci:v000011D4d00001983*
+ ID_PRODUCT_FROM_DATABASE=AD1983HD sound chip
+
+pci:v000011D4d00001984*
+ ID_PRODUCT_FROM_DATABASE=AD1984HD sound chip
+
+pci:v000011D4d00001984sv000017AAsd000020BB*
+ ID_PRODUCT_FROM_DATABASE=T61p Notebook
+
+pci:v000011D4d00001986*
+ ID_PRODUCT_FROM_DATABASE=AD1986A sound chip
+
+pci:v000011D4d00001986sv000011D4sd00001986*
+ ID_PRODUCT_FROM_DATABASE=Lenovo N100 B9G
+
+pci:v000011D4d0000198B*
+ ID_PRODUCT_FROM_DATABASE=AD1988B Sound Chip
+
+pci:v000011D4d00005340*
+ ID_PRODUCT_FROM_DATABASE=AD1881 sound chip
+
+pci:v000011D5*
+ ID_VENDOR_FROM_DATABASE=Ikon Corporation
+
+pci:v000011D5d00000115*
+ ID_PRODUCT_FROM_DATABASE=10115
+
+pci:v000011D5d00000117*
+ ID_PRODUCT_FROM_DATABASE=10117
+
+pci:v000011D6*
+ ID_VENDOR_FROM_DATABASE=Tekelec Telecom
+
+pci:v000011D7*
+ ID_VENDOR_FROM_DATABASE=Trenton Technology, Inc.
+
+pci:v000011D8*
+ ID_VENDOR_FROM_DATABASE=Image Technologies Development
+
+pci:v000011D9*
+ ID_VENDOR_FROM_DATABASE=TEC Corporation
+
+pci:v000011DA*
+ ID_VENDOR_FROM_DATABASE=Novell
+
+pci:v000011DB*
+ ID_VENDOR_FROM_DATABASE=Sega Enterprises Ltd
+
+pci:v000011DC*
+ ID_VENDOR_FROM_DATABASE=Questra Corporation
+
+pci:v000011DD*
+ ID_VENDOR_FROM_DATABASE=Crosfield Electronics Limited
+
+pci:v000011DE*
+ ID_VENDOR_FROM_DATABASE=Zoran Corporation
+
+pci:v000011DEd00006017*
+ ID_PRODUCT_FROM_DATABASE=miroVIDEO DC30
+
+pci:v000011DEd00006057*
+ ID_PRODUCT_FROM_DATABASE=ZR36057PQC Video cutting chipset
+
+pci:v000011DEd00006057sv00001031sd00007EFE*
+ ID_PRODUCT_FROM_DATABASE=DC10 Plus
+
+pci:v000011DEd00006057sv00001031sd0000FC00*
+ ID_PRODUCT_FROM_DATABASE=MiroVIDEO DC50, Motion JPEG Capture/CODEC Board
+
+pci:v000011DEd00006057sv000012F8sd00008A02*
+ ID_PRODUCT_FROM_DATABASE=Tekram Video Kit
+
+pci:v000011DEd00006057sv000013CAsd00004231*
+ ID_PRODUCT_FROM_DATABASE=JPEG/TV Card
+
+pci:v000011DEd00006120*
+ ID_PRODUCT_FROM_DATABASE=ZR36120
+
+pci:v000011DEd00006120sv00001328sd0000F001*
+ ID_PRODUCT_FROM_DATABASE=Cinemaster C DVD Decoder
+
+pci:v000011DEd00006120sv000013C2sd00000000*
+ ID_PRODUCT_FROM_DATABASE=MediaFocus Satellite TV Card
+
+pci:v000011DEd00006120sv00001DE1sd00009FFF*
+ ID_PRODUCT_FROM_DATABASE=Video Kit C210
+
+pci:v000011DF*
+ ID_VENDOR_FROM_DATABASE=New Wave PDG
+
+pci:v000011E0*
+ ID_VENDOR_FROM_DATABASE=Cray Communications A/S
+
+pci:v000011E1*
+ ID_VENDOR_FROM_DATABASE=GEC Plessey Semi Inc.
+
+pci:v000011E2*
+ ID_VENDOR_FROM_DATABASE=Samsung Information Systems America
+
+pci:v000011E3*
+ ID_VENDOR_FROM_DATABASE=Quicklogic Corporation
+
+pci:v000011E3d00000001*
+ ID_PRODUCT_FROM_DATABASE=COM-ON-AIR Dosch&Amand DECT
+
+pci:v000011E3d00000560*
+ ID_PRODUCT_FROM_DATABASE=QL5064 Companion Design Demo Board
+
+pci:v000011E3d00005030*
+ ID_PRODUCT_FROM_DATABASE=PC Watchdog
+
+pci:v000011E3d00008417*
+ ID_PRODUCT_FROM_DATABASE=QL5064 [QuickPCI] PCI v2.2 bridge for SMT417 Dual TMS320C6416T PMC Module
+
+pci:v000011E4*
+ ID_VENDOR_FROM_DATABASE=Second Wave Inc
+
+pci:v000011E5*
+ ID_VENDOR_FROM_DATABASE=IIX Consulting
+
+pci:v000011E6*
+ ID_VENDOR_FROM_DATABASE=Mitsui-Zosen System Research
+
+pci:v000011E7*
+ ID_VENDOR_FROM_DATABASE=Toshiba America, Elec. Company
+
+pci:v000011E8*
+ ID_VENDOR_FROM_DATABASE=Digital Processing Systems Inc.
+
+pci:v000011E9*
+ ID_VENDOR_FROM_DATABASE=Highwater Designs Ltd.
+
+pci:v000011EA*
+ ID_VENDOR_FROM_DATABASE=Elsag Bailey
+
+pci:v000011EB*
+ ID_VENDOR_FROM_DATABASE=Formation Inc.
+
+pci:v000011EC*
+ ID_VENDOR_FROM_DATABASE=Coreco Inc
+
+pci:v000011ECd0000000D*
+ ID_PRODUCT_FROM_DATABASE=Oculus-F/64P
+
+pci:v000011ECd00001800*
+ ID_PRODUCT_FROM_DATABASE=Cobra/C6
+
+pci:v000011ED*
+ ID_VENDOR_FROM_DATABASE=Mediamatics
+
+pci:v000011EE*
+ ID_VENDOR_FROM_DATABASE=Dome Imaging Systems Inc
+
+pci:v000011EF*
+ ID_VENDOR_FROM_DATABASE=Nicolet Technologies B.V.
+
+pci:v000011F0*
+ ID_VENDOR_FROM_DATABASE=Compu-Shack
+
+pci:v000011F0d00004231*
+ ID_PRODUCT_FROM_DATABASE=FDDI
+
+pci:v000011F0d00004232*
+ ID_PRODUCT_FROM_DATABASE=FASTline UTP Quattro
+
+pci:v000011F0d00004233*
+ ID_PRODUCT_FROM_DATABASE=FASTline FO
+
+pci:v000011F0d00004234*
+ ID_PRODUCT_FROM_DATABASE=FASTline UTP
+
+pci:v000011F0d00004235*
+ ID_PRODUCT_FROM_DATABASE=FASTline-II UTP
+
+pci:v000011F0d00004236*
+ ID_PRODUCT_FROM_DATABASE=FASTline-II FO
+
+pci:v000011F0d00004731*
+ ID_PRODUCT_FROM_DATABASE=GIGAline
+
+pci:v000011F1*
+ ID_VENDOR_FROM_DATABASE=Symbios Logic Inc
+
+pci:v000011F2*
+ ID_VENDOR_FROM_DATABASE=Picture Tel Japan K.K.
+
+pci:v000011F3*
+ ID_VENDOR_FROM_DATABASE=Keithley Metrabyte
+
+pci:v000011F3d00000011*
+ ID_PRODUCT_FROM_DATABASE=KPCI-PIO24
+
+pci:v000011F4*
+ ID_VENDOR_FROM_DATABASE=Kinetic Systems Corporation
+
+pci:v000011F4d00002915*
+ ID_PRODUCT_FROM_DATABASE=CAMAC controller
+
+pci:v000011F5*
+ ID_VENDOR_FROM_DATABASE=Computing Devices International
+
+pci:v000011F6*
+ ID_VENDOR_FROM_DATABASE=Compex
+
+pci:v000011F6d00000112*
+ ID_PRODUCT_FROM_DATABASE=ENet100VG4
+
+pci:v000011F6d00000113*
+ ID_PRODUCT_FROM_DATABASE=FreedomLine 100
+
+pci:v000011F6d00001401*
+ ID_PRODUCT_FROM_DATABASE=ReadyLink 2000
+
+pci:v000011F6d00002011*
+ ID_PRODUCT_FROM_DATABASE=RL100-ATX 10/100
+
+pci:v000011F6d00002011sv000011F6sd00002011*
+ ID_PRODUCT_FROM_DATABASE=RL100-ATX
+
+pci:v000011F6d00002201*
+ ID_PRODUCT_FROM_DATABASE=ReadyLink 100TX (Winbond W89C840)
+
+pci:v000011F6d00002201sv000011F6sd00002011*
+ ID_PRODUCT_FROM_DATABASE=ReadyLink 100TX
+
+pci:v000011F6d00009881*
+ ID_PRODUCT_FROM_DATABASE=RL100TX Fast Ethernet
+
+pci:v000011F7*
+ ID_VENDOR_FROM_DATABASE=Scientific Atlanta
+
+pci:v000011F8*
+ ID_VENDOR_FROM_DATABASE=PMC-Sierra Inc.
+
+pci:v000011F8d00005220*
+ ID_PRODUCT_FROM_DATABASE=BR522x [PMC-Sierra maxRAID SAS Controller]
+
+pci:v000011F8d00007364*
+ ID_PRODUCT_FROM_DATABASE=PM7364 [FREEDM - 32 Frame Engine & Datalink Mgr]
+
+pci:v000011F8d00007375*
+ ID_PRODUCT_FROM_DATABASE=PM7375 [LASAR-155 ATM SAR]
+
+pci:v000011F8d00007384*
+ ID_PRODUCT_FROM_DATABASE=PM7384 [FREEDM - 84P672 Frm Engine & Datalink Mgr]
+
+pci:v000011F8d00008000*
+ ID_PRODUCT_FROM_DATABASE=PM8000  [SPC - SAS Protocol Controller]
+
+pci:v000011F9*
+ ID_VENDOR_FROM_DATABASE=I-Cube Inc
+
+pci:v000011FA*
+ ID_VENDOR_FROM_DATABASE=Kasan Electronics Company, Ltd.
+
+pci:v000011FB*
+ ID_VENDOR_FROM_DATABASE=Datel Inc
+
+pci:v000011FC*
+ ID_VENDOR_FROM_DATABASE=Silicon Magic
+
+pci:v000011FD*
+ ID_VENDOR_FROM_DATABASE=High Street Consultants
+
+pci:v000011FE*
+ ID_VENDOR_FROM_DATABASE=Comtrol Corporation
+
+pci:v000011FEd00000001*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 32 port w/external I/F
+
+pci:v000011FEd00000002*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 8 port w/external I/F
+
+pci:v000011FEd00000003*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 16 port w/external I/F
+
+pci:v000011FEd00000004*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 4 port w/quad cable
+
+pci:v000011FEd00000005*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 8 port w/octa cable
+
+pci:v000011FEd00000006*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 8 port w/RJ11 connectors
+
+pci:v000011FEd00000007*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 4 port w/RJ11 connectors
+
+pci:v000011FEd00000008*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 8 port w/ DB78 SNI (Siemens) connector
+
+pci:v000011FEd00000009*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 16 port w/ DB78 SNI (Siemens) connector
+
+pci:v000011FEd0000000A*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Plus 4 port
+
+pci:v000011FEd0000000B*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Plus 8 port
+
+pci:v000011FEd0000000C*
+ ID_PRODUCT_FROM_DATABASE=RocketModem 6 port
+
+pci:v000011FEd0000000D*
+ ID_PRODUCT_FROM_DATABASE=RocketModem 4-port
+
+pci:v000011FEd0000000E*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Plus 2 port RS232
+
+pci:v000011FEd0000000F*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Plus 2 port RS422
+
+pci:v000011FEd00000040*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity Octa, 8port, RJ45
+
+pci:v000011FEd00000041*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 32port, External Interface
+
+pci:v000011FEd00000042*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 8port, External Interface
+
+pci:v000011FEd00000043*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 16port, External Interface
+
+pci:v000011FEd00000044*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity Quad, 4port, DB
+
+pci:v000011FEd00000045*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity Octa, 8port, DB
+
+pci:v000011FEd00000047*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 4port, RJ45
+
+pci:v000011FEd0000004F*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 2port, SMPTE
+
+pci:v000011FEd00000052*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Infinity Octa, 8port, SMPTE
+
+pci:v000011FEd00000801*
+ ID_PRODUCT_FROM_DATABASE=RocketPort UPCI 32 port w/external I/F
+
+pci:v000011FEd00000802*
+ ID_PRODUCT_FROM_DATABASE=RocketPort UPCI 8 port w/external I/F
+
+pci:v000011FEd00000803*
+ ID_PRODUCT_FROM_DATABASE=RocketPort UPCI 16 port w/external I/F
+
+pci:v000011FEd00000805*
+ ID_PRODUCT_FROM_DATABASE=RocketPort UPCI 8 port w/octa cable
+
+pci:v000011FEd0000080C*
+ ID_PRODUCT_FROM_DATABASE=RocketModem III 8 port
+
+pci:v000011FEd0000080D*
+ ID_PRODUCT_FROM_DATABASE=RocketModem III 4 port
+
+pci:v000011FEd00000810*
+ ID_PRODUCT_FROM_DATABASE=RocketPort UPCI Plus 4 port RS232
+
+pci:v000011FEd00000811*
+ ID_PRODUCT_FROM_DATABASE=RocketPort UPCI Plus 8 port RS232
+
+pci:v000011FEd00000812*
+ ID_PRODUCT_FROM_DATABASE=RocketPort UPCI Plus 8 port RS422
+
+pci:v000011FEd00000903*
+ ID_PRODUCT_FROM_DATABASE=RocketPort Compact PCI 16 port w/external I/F
+
+pci:v000011FEd00008015*
+ ID_PRODUCT_FROM_DATABASE=RocketPort 4-port UART 16954
+
+pci:v000011FF*
+ ID_VENDOR_FROM_DATABASE=Scion Corporation
+
+pci:v000011FFd00000003*
+ ID_PRODUCT_FROM_DATABASE=AG-5
+
+pci:v00001200*
+ ID_VENDOR_FROM_DATABASE=CSS Corporation
+
+pci:v00001201*
+ ID_VENDOR_FROM_DATABASE=Vista Controls Corp
+
+pci:v00001202*
+ ID_VENDOR_FROM_DATABASE=Network General Corp.
+
+pci:v00001202d00004300*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet Adapter
+
+pci:v00001202d00004300sv00001202sd00009841*
+ ID_PRODUCT_FROM_DATABASE=SK-9841 LX
+
+pci:v00001202d00004300sv00001202sd00009842*
+ ID_PRODUCT_FROM_DATABASE=SK-9841 LX dual link
+
+pci:v00001202d00004300sv00001202sd00009843*
+ ID_PRODUCT_FROM_DATABASE=SK-9843 SX
+
+pci:v00001202d00004300sv00001202sd00009844*
+ ID_PRODUCT_FROM_DATABASE=SK-9843 SX dual link
+
+pci:v00001203*
+ ID_VENDOR_FROM_DATABASE=Bayer Corporation, Agfa Division
+
+pci:v00001204*
+ ID_VENDOR_FROM_DATABASE=Lattice Semiconductor Corporation
+
+pci:v00001205*
+ ID_VENDOR_FROM_DATABASE=Array Corporation
+
+pci:v00001206*
+ ID_VENDOR_FROM_DATABASE=Amdahl Corporation
+
+pci:v00001208*
+ ID_VENDOR_FROM_DATABASE=Parsytec GmbH
+
+pci:v00001208d00004853*
+ ID_PRODUCT_FROM_DATABASE=HS-Link Device
+
+pci:v00001209*
+ ID_VENDOR_FROM_DATABASE=SCI Systems Inc
+
+pci:v0000120A*
+ ID_VENDOR_FROM_DATABASE=Synaptel
+
+pci:v0000120B*
+ ID_VENDOR_FROM_DATABASE=Adaptive Solutions
+
+pci:v0000120C*
+ ID_VENDOR_FROM_DATABASE=Technical Corp.
+
+pci:v0000120D*
+ ID_VENDOR_FROM_DATABASE=Compression Labs, Inc.
+
+pci:v0000120E*
+ ID_VENDOR_FROM_DATABASE=Cyclades Corporation
+
+pci:v0000120Ed00000100*
+ ID_PRODUCT_FROM_DATABASE=Cyclom-Y below first megabyte
+
+pci:v0000120Ed00000101*
+ ID_PRODUCT_FROM_DATABASE=Cyclom-Y above first megabyte
+
+pci:v0000120Ed00000102*
+ ID_PRODUCT_FROM_DATABASE=Cyclom-4Y below first megabyte
+
+pci:v0000120Ed00000103*
+ ID_PRODUCT_FROM_DATABASE=Cyclom-4Y above first megabyte
+
+pci:v0000120Ed00000104*
+ ID_PRODUCT_FROM_DATABASE=Cyclom-8Y below first megabyte
+
+pci:v0000120Ed00000105*
+ ID_PRODUCT_FROM_DATABASE=Cyclom-8Y above first megabyte
+
+pci:v0000120Ed00000200*
+ ID_PRODUCT_FROM_DATABASE=Cyclades-Z below first megabyte
+
+pci:v0000120Ed00000201*
+ ID_PRODUCT_FROM_DATABASE=Cyclades-Z above first megabyte
+
+pci:v0000120Ed00000300*
+ ID_PRODUCT_FROM_DATABASE=PC300/RSV or /X21 (2 ports)
+
+pci:v0000120Ed00000301*
+ ID_PRODUCT_FROM_DATABASE=PC300/RSV or /X21 (1 port)
+
+pci:v0000120Ed00000310*
+ ID_PRODUCT_FROM_DATABASE=PC300/TE (2 ports)
+
+pci:v0000120Ed00000311*
+ ID_PRODUCT_FROM_DATABASE=PC300/TE (1 port)
+
+pci:v0000120Ed00000320*
+ ID_PRODUCT_FROM_DATABASE=PC300/TE-M (2 ports)
+
+pci:v0000120Ed00000321*
+ ID_PRODUCT_FROM_DATABASE=PC300/TE-M (1 port)
+
+pci:v0000120Ed00000400*
+ ID_PRODUCT_FROM_DATABASE=PC400
+
+pci:v0000120F*
+ ID_VENDOR_FROM_DATABASE=Essential Communications
+
+pci:v0000120Fd00000001*
+ ID_PRODUCT_FROM_DATABASE=Roadrunner serial HIPPI
+
+pci:v00001210*
+ ID_VENDOR_FROM_DATABASE=Hyperparallel Technologies
+
+pci:v00001211*
+ ID_VENDOR_FROM_DATABASE=Braintech Inc
+
+pci:v00001212*
+ ID_VENDOR_FROM_DATABASE=Kingston Technology Corp.
+
+pci:v00001213*
+ ID_VENDOR_FROM_DATABASE=Applied Intelligent Systems, Inc.
+
+pci:v00001214*
+ ID_VENDOR_FROM_DATABASE=Performance Technologies, Inc.
+
+pci:v00001215*
+ ID_VENDOR_FROM_DATABASE=Interware Co., Ltd
+
+pci:v00001216*
+ ID_VENDOR_FROM_DATABASE=Purup Prepress A/S
+
+pci:v00001217*
+ ID_VENDOR_FROM_DATABASE=O2 Micro, Inc.
+
+pci:v00001217d000000F7*
+ ID_PRODUCT_FROM_DATABASE=Firewire (IEEE 1394)
+
+pci:v00001217d000000F7sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001217d000010F7*
+ ID_PRODUCT_FROM_DATABASE=1394 OHCI Compliant Host Controller
+
+pci:v00001217d000011F7*
+ ID_PRODUCT_FROM_DATABASE=OZ600 1394a-2000 Controller
+
+pci:v00001217d000013F7*
+ ID_PRODUCT_FROM_DATABASE=1394 OHCI Compliant Host Controller
+
+pci:v00001217d00006729*
+ ID_PRODUCT_FROM_DATABASE=OZ6729
+
+pci:v00001217d0000673A*
+ ID_PRODUCT_FROM_DATABASE=OZ6730
+
+pci:v00001217d00006832*
+ ID_PRODUCT_FROM_DATABASE=OZ6832/6833 CardBus Controller
+
+pci:v00001217d00006836*
+ ID_PRODUCT_FROM_DATABASE=OZ6836/6860 CardBus Controller
+
+pci:v00001217d00006872*
+ ID_PRODUCT_FROM_DATABASE=OZ6812 CardBus Controller
+
+pci:v00001217d00006925*
+ ID_PRODUCT_FROM_DATABASE=OZ6922 CardBus Controller
+
+pci:v00001217d00006933*
+ ID_PRODUCT_FROM_DATABASE=OZ6933/711E1 CardBus/SmartCardBus Controller
+
+pci:v00001217d00006933sv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX
+
+pci:v00001217d00006972*
+ ID_PRODUCT_FROM_DATABASE=OZ601/6912/711E0 CardBus/SmartCardBus Controller
+
+pci:v00001217d00006972sv00001014sd0000020C*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R30
+
+pci:v00001217d00006972sv00001028sd00000152*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00001217d00006972sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Magnia Z310
+
+pci:v00001217d00007110*
+ ID_PRODUCT_FROM_DATABASE=OZ711Mx 4-in-1 MemoryCardBus Accelerator
+
+pci:v00001217d00007110sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00001217d00007110sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00001217d00007110sv00001734sd0000106C*
+ ID_PRODUCT_FROM_DATABASE=Amilo A1645
+
+pci:v00001217d00007112*
+ ID_PRODUCT_FROM_DATABASE=OZ711EC1/M1 SmartCardBus/MemoryCardBus Controller
+
+pci:v00001217d00007113*
+ ID_PRODUCT_FROM_DATABASE=OZ711EC1 SmartCardBus Controller
+
+pci:v00001217d00007113sv00001025sd00000035*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 660
+
+pci:v00001217d00007114*
+ ID_PRODUCT_FROM_DATABASE=OZ711M1/MC1 4-in-1 MemoryCardBus Controller
+
+pci:v00001217d00007120*
+ ID_PRODUCT_FROM_DATABASE=Integrated MMC/SD Controller
+
+pci:v00001217d00007120sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001217d00007130*
+ ID_PRODUCT_FROM_DATABASE=Integrated MS/xD Controller
+
+pci:v00001217d00007130sv00001179sd0000FF50*
+ ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E
+
+pci:v00001217d00007134*
+ ID_PRODUCT_FROM_DATABASE=OZ711MP1/MS1 MemoryCardBus Controller
+
+pci:v00001217d00007135*
+ ID_PRODUCT_FROM_DATABASE=Cardbus bridge
+
+pci:v00001217d00007136*
+ ID_PRODUCT_FROM_DATABASE=OZ711SP1 Memory CardBus Controller
+
+pci:v00001217d000071E2*
+ ID_PRODUCT_FROM_DATABASE=OZ711E2 SmartCardBus Controller
+
+pci:v00001217d00007212*
+ ID_PRODUCT_FROM_DATABASE=OZ711M2 4-in-1 MemoryCardBus Controller
+
+pci:v00001217d00007213*
+ ID_PRODUCT_FROM_DATABASE=OZ6933E CardBus Controller
+
+pci:v00001217d00007223*
+ ID_PRODUCT_FROM_DATABASE=OZ711M3/MC3 4-in-1 MemoryCardBus Controller
+
+pci:v00001217d00007223sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00001217d00007223sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00001217d00007223sv000010CFsd000011C4*
+ ID_PRODUCT_FROM_DATABASE=Lifebook P5020D Laptop
+
+pci:v00001217d00007233*
+ ID_PRODUCT_FROM_DATABASE=OZ711MP3/MS3 4-in-1 MemoryCardBus Controller
+
+pci:v00001217d00008120*
+ ID_PRODUCT_FROM_DATABASE=Integrated MMC/SD Controller
+
+pci:v00001217d00008130*
+ ID_PRODUCT_FROM_DATABASE=Integrated MS/MSPRO/xD Controller
+
+pci:v00001217d00008321*
+ ID_PRODUCT_FROM_DATABASE=Integrated MMC/SD controller
+
+pci:v00001217d00008331*
+ ID_PRODUCT_FROM_DATABASE=O2 Flash Memory Card
+
+pci:v00001218*
+ ID_VENDOR_FROM_DATABASE=Hybricon Corp.
+
+pci:v00001219*
+ ID_VENDOR_FROM_DATABASE=First Virtual Corporation
+
+pci:v0000121A*
+ ID_VENDOR_FROM_DATABASE=3Dfx Interactive, Inc.
+
+pci:v0000121Ad00000001*
+ ID_PRODUCT_FROM_DATABASE=Voodoo
+
+pci:v0000121Ad00000002*
+ ID_PRODUCT_FROM_DATABASE=Voodoo 2
+
+pci:v0000121Ad00000003*
+ ID_PRODUCT_FROM_DATABASE=Voodoo Banshee
+
+pci:v0000121Ad00000003sv00001092sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Monster Fusion
+
+pci:v0000121Ad00000003sv00001092sd00004000*
+ ID_PRODUCT_FROM_DATABASE=Monster Fusion
+
+pci:v0000121Ad00000003sv00001092sd00004002*
+ ID_PRODUCT_FROM_DATABASE=Monster Fusion
+
+pci:v0000121Ad00000003sv00001092sd00004801*
+ ID_PRODUCT_FROM_DATABASE=Monster Fusion AGP
+
+pci:v0000121Ad00000003sv00001092sd00004803*
+ ID_PRODUCT_FROM_DATABASE=Monster Fusion AGP
+
+pci:v0000121Ad00000003sv00001092sd00008030*
+ ID_PRODUCT_FROM_DATABASE=Monster Fusion
+
+pci:v0000121Ad00000003sv00001092sd00008035*
+ ID_PRODUCT_FROM_DATABASE=Monster Fusion AGP
+
+pci:v0000121Ad00000003sv000010B0sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Dragon 4000
+
+pci:v0000121Ad00000003sv00001102sd00001017*
+ ID_PRODUCT_FROM_DATABASE=3D Blaster Banshee PCI (CT6760)
+
+pci:v0000121Ad00000003sv00001102sd00001018*
+ ID_PRODUCT_FROM_DATABASE=3D Blaster Banshee VE
+
+pci:v0000121Ad00000003sv0000121Asd00000001*
+ ID_PRODUCT_FROM_DATABASE=Voodoo Banshee AGP
+
+pci:v0000121Ad00000003sv0000121Asd00000003*
+ ID_PRODUCT_FROM_DATABASE=Voodoo Banshee AGP SGRAM
+
+pci:v0000121Ad00000003sv0000121Asd00000004*
+ ID_PRODUCT_FROM_DATABASE=Voodoo Banshee
+
+pci:v0000121Ad00000003sv0000139Csd00000016*
+ ID_PRODUCT_FROM_DATABASE=Raven
+
+pci:v0000121Ad00000003sv0000139Csd00000017*
+ ID_PRODUCT_FROM_DATABASE=Raven
+
+pci:v0000121Ad00000003sv000014AFsd00000002*
+ ID_PRODUCT_FROM_DATABASE=Maxi Gamer Phoenix
+
+pci:v0000121Ad00000004*
+ ID_PRODUCT_FROM_DATABASE=Voodoo Banshee [Velocity 100]
+
+pci:v0000121Ad00000005*
+ ID_PRODUCT_FROM_DATABASE=Voodoo 3
+
+pci:v0000121Ad00000005sv0000121Asd00000004*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000030*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000031*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000034*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000036*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 2000 PCI
+
+pci:v0000121Ad00000005sv0000121Asd00000037*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000038*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd0000003A*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000044*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3
+
+pci:v0000121Ad00000005sv0000121Asd0000004B*
+ ID_PRODUCT_FROM_DATABASE=Velocity 100
+
+pci:v0000121Ad00000005sv0000121Asd0000004C*
+ ID_PRODUCT_FROM_DATABASE=Velocity 200
+
+pci:v0000121Ad00000005sv0000121Asd0000004D*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd0000004E*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000051*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000052*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP
+
+pci:v0000121Ad00000005sv0000121Asd00000057*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 3000 PCI
+
+pci:v0000121Ad00000005sv0000121Asd00000060*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 3500 TV (NTSC)
+
+pci:v0000121Ad00000005sv0000121Asd00000061*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 3500 TV (PAL)
+
+pci:v0000121Ad00000005sv0000121Asd00000062*
+ ID_PRODUCT_FROM_DATABASE=Voodoo3 3500 TV (SECAM)
+
+pci:v0000121Ad00000009*
+ ID_PRODUCT_FROM_DATABASE=Voodoo 4 / Voodoo 5
+
+pci:v0000121Ad00000009sv0000121Asd00000003*
+ ID_PRODUCT_FROM_DATABASE=Voodoo5 PCI 5500
+
+pci:v0000121Ad00000009sv0000121Asd00000009*
+ ID_PRODUCT_FROM_DATABASE=Voodoo5 AGP 5500/6000
+
+pci:v0000121Ad00000057*
+ ID_PRODUCT_FROM_DATABASE=Voodoo 3/3000 [Avenger]
+
+pci:v0000121B*
+ ID_VENDOR_FROM_DATABASE=Advanced Telecommunications Modules
+
+pci:v0000121C*
+ ID_VENDOR_FROM_DATABASE=Nippon Texaco., Ltd
+
+pci:v0000121D*
+ ID_VENDOR_FROM_DATABASE=LiPPERT ADLINK Technology GmbH
+
+pci:v0000121E*
+ ID_VENDOR_FROM_DATABASE=CSPI
+
+pci:v0000121Ed00000201*
+ ID_PRODUCT_FROM_DATABASE=Myrinet 2000 Scalable Cluster Interconnect
+
+pci:v0000121F*
+ ID_VENDOR_FROM_DATABASE=Arcus Technology, Inc.
+
+pci:v00001220*
+ ID_VENDOR_FROM_DATABASE=Ariel Corporation
+
+pci:v00001220d00001220*
+ ID_PRODUCT_FROM_DATABASE=AMCC 5933 TMS320C80 DSP/Imaging board
+
+pci:v00001221*
+ ID_VENDOR_FROM_DATABASE=Contec Co., Ltd
+
+pci:v00001221d00009172*
+ ID_PRODUCT_FROM_DATABASE=PO-64L(PCI)H [Isolated Digital Output Board for PCI]
+
+pci:v00001221d000091A2*
+ ID_PRODUCT_FROM_DATABASE=PO-32L(PCI)H [Isolated Digital Output Board for PCI]
+
+pci:v00001221d000091C3*
+ ID_PRODUCT_FROM_DATABASE=DA16-16(LPCI)L [Un-insulated highly precise analog output board for Low Profile PCI]
+
+pci:v00001221d0000B152*
+ ID_PRODUCT_FROM_DATABASE=DIO-96D2-LPCI
+
+pci:v00001221d0000C103*
+ ID_PRODUCT_FROM_DATABASE=ADA16-32/2(PCI)F [High-Speed Analog I/O Board for PCI]
+
+pci:v00001222*
+ ID_VENDOR_FROM_DATABASE=Ancor Communications, Inc.
+
+pci:v00001223*
+ ID_VENDOR_FROM_DATABASE=Artesyn Communication Products
+
+pci:v00001223d00000003*
+ ID_PRODUCT_FROM_DATABASE=PM/Link
+
+pci:v00001223d00000004*
+ ID_PRODUCT_FROM_DATABASE=PM/T1
+
+pci:v00001223d00000005*
+ ID_PRODUCT_FROM_DATABASE=PM/E1
+
+pci:v00001223d00000008*
+ ID_PRODUCT_FROM_DATABASE=PM/SLS
+
+pci:v00001223d00000009*
+ ID_PRODUCT_FROM_DATABASE=BajaSpan Resource Target
+
+pci:v00001223d0000000A*
+ ID_PRODUCT_FROM_DATABASE=BajaSpan Section 0
+
+pci:v00001223d0000000B*
+ ID_PRODUCT_FROM_DATABASE=BajaSpan Section 1
+
+pci:v00001223d0000000C*
+ ID_PRODUCT_FROM_DATABASE=BajaSpan Section 2
+
+pci:v00001223d0000000D*
+ ID_PRODUCT_FROM_DATABASE=BajaSpan Section 3
+
+pci:v00001223d0000000E*
+ ID_PRODUCT_FROM_DATABASE=PM/PPC
+
+pci:v00001224*
+ ID_VENDOR_FROM_DATABASE=Interactive Images
+
+pci:v00001225*
+ ID_VENDOR_FROM_DATABASE=Power I/O, Inc.
+
+pci:v00001227*
+ ID_VENDOR_FROM_DATABASE=Tech-Source
+
+pci:v00001227d00000006*
+ ID_PRODUCT_FROM_DATABASE=Raptor GFX 8P
+
+pci:v00001227d00000023*
+ ID_PRODUCT_FROM_DATABASE=Raptor GFX [1100T]
+
+pci:v00001227d00000045*
+ ID_PRODUCT_FROM_DATABASE=Raptor 4000-L [Linux version]
+
+pci:v00001227d0000004A*
+ ID_PRODUCT_FROM_DATABASE=Raptor 4000-LR-L [Linux version]
+
+pci:v00001228*
+ ID_VENDOR_FROM_DATABASE=Norsk Elektro Optikk A/S
+
+pci:v00001229*
+ ID_VENDOR_FROM_DATABASE=Data Kinesis Inc.
+
+pci:v0000122A*
+ ID_VENDOR_FROM_DATABASE=Integrated Telecom
+
+pci:v0000122B*
+ ID_VENDOR_FROM_DATABASE=LG Industrial Systems Co., Ltd
+
+pci:v0000122C*
+ ID_VENDOR_FROM_DATABASE=Sican GmbH
+
+pci:v0000122D*
+ ID_VENDOR_FROM_DATABASE=Aztech System Ltd
+
+pci:v0000122Dd00001206*
+ ID_PRODUCT_FROM_DATABASE=368DSP
+
+pci:v0000122Dd00001400*
+ ID_PRODUCT_FROM_DATABASE=Trident PCI288-Q3DII (NX)
+
+pci:v0000122Dd000050DC*
+ ID_PRODUCT_FROM_DATABASE=3328 Audio
+
+pci:v0000122Dd000050DCsv0000122Dsd00000001*
+ ID_PRODUCT_FROM_DATABASE=3328 Audio
+
+pci:v0000122Dd000080DA*
+ ID_PRODUCT_FROM_DATABASE=3328 Audio
+
+pci:v0000122Dd000080DAsv0000122Dsd00000001*
+ ID_PRODUCT_FROM_DATABASE=3328 Audio
+
+pci:v0000122E*
+ ID_VENDOR_FROM_DATABASE=Xyratex
+
+pci:v0000122Ed00007722*
+ ID_PRODUCT_FROM_DATABASE=Napatech XL1
+
+pci:v0000122Ed00007724*
+ ID_PRODUCT_FROM_DATABASE=Napatech XL2/XA
+
+pci:v0000122Ed00007729*
+ ID_PRODUCT_FROM_DATABASE=Napatech XD
+
+pci:v0000122F*
+ ID_VENDOR_FROM_DATABASE=Andrew Corporation
+
+pci:v00001230*
+ ID_VENDOR_FROM_DATABASE=Fishcamp Engineering
+
+pci:v00001231*
+ ID_VENDOR_FROM_DATABASE=Woodward McCoach, Inc.
+
+pci:v00001231d000004E1*
+ ID_PRODUCT_FROM_DATABASE=Desktop PCI Telephony 4
+
+pci:v00001231d000005E1*
+ ID_PRODUCT_FROM_DATABASE=Desktop PCI Telephony 5/6
+
+pci:v00001231d00000D00*
+ ID_PRODUCT_FROM_DATABASE=LightParser
+
+pci:v00001231d00000D02*
+ ID_PRODUCT_FROM_DATABASE=LightParser 2
+
+pci:v00001231d00000D13*
+ ID_PRODUCT_FROM_DATABASE=Desktop PCI L1/L3 Telephony
+
+pci:v00001232*
+ ID_VENDOR_FROM_DATABASE=GPT Limited
+
+pci:v00001233*
+ ID_VENDOR_FROM_DATABASE=Bus-Tech, Inc.
+
+pci:v00001235*
+ ID_VENDOR_FROM_DATABASE=Risq Modular Systems, Inc.
+
+pci:v00001236*
+ ID_VENDOR_FROM_DATABASE=Sigma Designs Corporation
+
+pci:v00001236d00000000*
+ ID_PRODUCT_FROM_DATABASE=RealMagic64/GX
+
+pci:v00001236d00006401*
+ ID_PRODUCT_FROM_DATABASE=REALmagic 64/GX (SD 6425)
+
+pci:v00001237*
+ ID_VENDOR_FROM_DATABASE=Alta Technology Corporation
+
+pci:v00001238*
+ ID_VENDOR_FROM_DATABASE=Adtran
+
+pci:v00001239*
+ ID_VENDOR_FROM_DATABASE=3DO Company
+
+pci:v0000123A*
+ ID_VENDOR_FROM_DATABASE=Visicom Laboratories, Inc.
+
+pci:v0000123B*
+ ID_VENDOR_FROM_DATABASE=Seeq Technology, Inc.
+
+pci:v0000123C*
+ ID_VENDOR_FROM_DATABASE=Century Systems, Inc.
+
+pci:v0000123D*
+ ID_VENDOR_FROM_DATABASE=Engineering Design Team, Inc.
+
+pci:v0000123Dd00000000*
+ ID_PRODUCT_FROM_DATABASE=EasyConnect 8/32
+
+pci:v0000123Dd00000002*
+ ID_PRODUCT_FROM_DATABASE=EasyConnect 8/64
+
+pci:v0000123Dd00000003*
+ ID_PRODUCT_FROM_DATABASE=EasyIO
+
+pci:v0000123E*
+ ID_VENDOR_FROM_DATABASE=Simutech, Inc.
+
+pci:v0000123F*
+ ID_VENDOR_FROM_DATABASE=C-Cube Microsystems
+
+pci:v0000123Fd000000E4*
+ ID_PRODUCT_FROM_DATABASE=MPEG
+
+pci:v0000123Fd00008120*
+ ID_PRODUCT_FROM_DATABASE=E4?
+
+pci:v0000123Fd00008120sv000011BDsd00000006*
+ ID_PRODUCT_FROM_DATABASE=DV500 E4
+
+pci:v0000123Fd00008120sv000011BDsd0000000A*
+ ID_PRODUCT_FROM_DATABASE=DV500 E4
+
+pci:v0000123Fd00008120sv000011BDsd0000000F*
+ ID_PRODUCT_FROM_DATABASE=DV500 E4
+
+pci:v0000123Fd00008120sv00001809sd00000016*
+ ID_PRODUCT_FROM_DATABASE=Emuzed MAUI-III PCI PVR FM TV
+
+pci:v0000123Fd00008888*
+ ID_PRODUCT_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder
+
+pci:v0000123Fd00008888sv00001002sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder
+
+pci:v0000123Fd00008888sv00001002sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder
+
+pci:v0000123Fd00008888sv00001328sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder
+
+pci:v00001240*
+ ID_VENDOR_FROM_DATABASE=Marathon Technologies Corp.
+
+pci:v00001241*
+ ID_VENDOR_FROM_DATABASE=DSC Communications
+
+pci:v00001242*
+ ID_VENDOR_FROM_DATABASE=JNI Corporation
+
+pci:v00001242d00001560*
+ ID_PRODUCT_FROM_DATABASE=JNIC-1560 PCI-X Fibre Channel Controller
+
+pci:v00001242d00001560sv00001242sd00006562*
+ ID_PRODUCT_FROM_DATABASE=FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
+
+pci:v00001242d00001560sv00001242sd0000656A*
+ ID_PRODUCT_FROM_DATABASE=FCX-6562 PCI-X Fibre Channel Adapter
+
+pci:v00001242d00004643*
+ ID_PRODUCT_FROM_DATABASE=FCI-1063 Fibre Channel Adapter
+
+pci:v00001242d00006562*
+ ID_PRODUCT_FROM_DATABASE=FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
+
+pci:v00001242d0000656A*
+ ID_PRODUCT_FROM_DATABASE=FCX-6562 PCI-X Fibre Channel Adapter
+
+pci:v00001243*
+ ID_VENDOR_FROM_DATABASE=Delphax
+
+pci:v00001244*
+ ID_VENDOR_FROM_DATABASE=AVM GmbH
+
+pci:v00001244d00000700*
+ ID_PRODUCT_FROM_DATABASE=B1 ISDN
+
+pci:v00001244d00000800*
+ ID_PRODUCT_FROM_DATABASE=C4 ISDN
+
+pci:v00001244d00000A00*
+ ID_PRODUCT_FROM_DATABASE=A1 ISDN [Fritz]
+
+pci:v00001244d00000A00sv00001244sd00000A00*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Card ISDN Controller
+
+pci:v00001244d00000E00*
+ ID_PRODUCT_FROM_DATABASE=Fritz!PCI v2.0 ISDN
+
+pci:v00001244d00001100*
+ ID_PRODUCT_FROM_DATABASE=C2 ISDN
+
+pci:v00001244d00001200*
+ ID_PRODUCT_FROM_DATABASE=T1 ISDN
+
+pci:v00001244d00002700*
+ ID_PRODUCT_FROM_DATABASE=Fritz!Card DSL SL
+
+pci:v00001244d00002900*
+ ID_PRODUCT_FROM_DATABASE=Fritz!Card DSL v2.0
+
+pci:v00001245*
+ ID_VENDOR_FROM_DATABASE=A.P.D., S.A.
+
+pci:v00001246*
+ ID_VENDOR_FROM_DATABASE=Dipix Technologies, Inc.
+
+pci:v00001247*
+ ID_VENDOR_FROM_DATABASE=Xylon Research, Inc.
+
+pci:v00001248*
+ ID_VENDOR_FROM_DATABASE=Central Data Corporation
+
+pci:v00001249*
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics Co., Ltd.
+
+pci:v0000124A*
+ ID_VENDOR_FROM_DATABASE=AEG Electrocom GmbH
+
+pci:v0000124B*
+ ID_VENDOR_FROM_DATABASE=SBS/Greenspring Modular I/O
+
+pci:v0000124Bd00000040*
+ ID_PRODUCT_FROM_DATABASE=PCI-40A or cPCI-200 Quad IndustryPack carrier
+
+pci:v0000124Bd00000040sv0000124Bsd00009080*
+ ID_PRODUCT_FROM_DATABASE=PCI9080 Bridge
+
+pci:v0000124C*
+ ID_VENDOR_FROM_DATABASE=Solitron Technologies, Inc.
+
+pci:v0000124D*
+ ID_VENDOR_FROM_DATABASE=Stallion Technologies, Inc.
+
+pci:v0000124Dd00000000*
+ ID_PRODUCT_FROM_DATABASE=EasyConnection 8/32
+
+pci:v0000124Dd00000002*
+ ID_PRODUCT_FROM_DATABASE=EasyConnection 8/64
+
+pci:v0000124Dd00000003*
+ ID_PRODUCT_FROM_DATABASE=EasyIO
+
+pci:v0000124Dd00000004*
+ ID_PRODUCT_FROM_DATABASE=EasyConnection/RA
+
+pci:v0000124E*
+ ID_VENDOR_FROM_DATABASE=Cylink
+
+pci:v0000124F*
+ ID_VENDOR_FROM_DATABASE=Infortrend Technology, Inc.
+
+pci:v0000124Fd00000041*
+ ID_PRODUCT_FROM_DATABASE=IFT-2000 Series RAID Controller
+
+pci:v00001250*
+ ID_VENDOR_FROM_DATABASE=Hitachi Microcomputer System Ltd
+
+pci:v00001251*
+ ID_VENDOR_FROM_DATABASE=VLSI Solutions Oy
+
+pci:v00001253*
+ ID_VENDOR_FROM_DATABASE=Guzik Technical Enterprises
+
+pci:v00001254*
+ ID_VENDOR_FROM_DATABASE=Linear Systems Ltd.
+
+pci:v00001254d00000065*
+ ID_PRODUCT_FROM_DATABASE=DVB Master FD
+
+pci:v00001254d0000007C*
+ ID_PRODUCT_FROM_DATABASE=DVB Master Quad/o
+
+pci:v00001255*
+ ID_VENDOR_FROM_DATABASE=Optibase Ltd
+
+pci:v00001255d00001110*
+ ID_PRODUCT_FROM_DATABASE=MPEG Forge
+
+pci:v00001255d00001210*
+ ID_PRODUCT_FROM_DATABASE=MPEG Fusion
+
+pci:v00001255d00002110*
+ ID_PRODUCT_FROM_DATABASE=VideoPlex
+
+pci:v00001255d00002120*
+ ID_PRODUCT_FROM_DATABASE=VideoPlex CC
+
+pci:v00001255d00002130*
+ ID_PRODUCT_FROM_DATABASE=VideoQuest
+
+pci:v00001256*
+ ID_VENDOR_FROM_DATABASE=Perceptive Solutions, Inc.
+
+pci:v00001256d00004201*
+ ID_PRODUCT_FROM_DATABASE=PCI-2220I
+
+pci:v00001256d00004401*
+ ID_PRODUCT_FROM_DATABASE=PCI-2240I
+
+pci:v00001256d00005201*
+ ID_PRODUCT_FROM_DATABASE=PCI-2000
+
+pci:v00001257*
+ ID_VENDOR_FROM_DATABASE=Vertex Networks, Inc.
+
+pci:v00001258*
+ ID_VENDOR_FROM_DATABASE=Gilbarco, Inc.
+
+pci:v00001259*
+ ID_VENDOR_FROM_DATABASE=Allied Telesis
+
+pci:v00001259d00002560*
+ ID_PRODUCT_FROM_DATABASE=AT-2560 Fast Ethernet Adapter (i82557B)
+
+pci:v00001259d00002801*
+ ID_PRODUCT_FROM_DATABASE=AT-2801FX (RTL-8139)
+
+pci:v00001259d0000A117*
+ ID_PRODUCT_FROM_DATABASE=RTL81xx Fast Ethernet
+
+pci:v00001259d0000A11E*
+ ID_PRODUCT_FROM_DATABASE=RTL81xx Fast Ethernet
+
+pci:v00001259d0000A120*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v0000125A*
+ ID_VENDOR_FROM_DATABASE=ABB Power Systems
+
+pci:v0000125B*
+ ID_VENDOR_FROM_DATABASE=Asix Electronics Corporation
+
+pci:v0000125Bd00001400*
+ ID_PRODUCT_FROM_DATABASE=AX88141 Fast Ethernet Controller
+
+pci:v0000125Bd00001400sv00001186sd00001100*
+ ID_PRODUCT_FROM_DATABASE=AX8814X Based PCI Fast Ethernet Adapter
+
+pci:v0000125C*
+ ID_VENDOR_FROM_DATABASE=Aurora Technologies, Inc.
+
+pci:v0000125Cd00000101*
+ ID_PRODUCT_FROM_DATABASE=Saturn 4520P
+
+pci:v0000125Cd00000640*
+ ID_PRODUCT_FROM_DATABASE=Aries 16000P
+
+pci:v0000125D*
+ ID_VENDOR_FROM_DATABASE=ESS Technology
+
+pci:v0000125Dd00000000*
+ ID_PRODUCT_FROM_DATABASE=ES336H Fax Modem (Early Model)
+
+pci:v0000125Dd00001948*
+ ID_PRODUCT_FROM_DATABASE=ES1948 Maestro-1
+
+pci:v0000125Dd00001968*
+ ID_PRODUCT_FROM_DATABASE=ES1968 Maestro 2
+
+pci:v0000125Dd00001968sv00001028sd00000085*
+ ID_PRODUCT_FROM_DATABASE=ES1968 Maestro-2 PCI
+
+pci:v0000125Dd00001968sv00001033sd00008051*
+ ID_PRODUCT_FROM_DATABASE=ES1968 Maestro-2 Audiodrive
+
+pci:v0000125Dd00001969*
+ ID_PRODUCT_FROM_DATABASE=ES1938/ES1946/ES1969 Solo-1 Audiodrive
+
+pci:v0000125Dd00001969sv00001014sd00000166*
+ ID_PRODUCT_FROM_DATABASE=ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard
+
+pci:v0000125Dd00001969sv0000125Dsd00008888*
+ ID_PRODUCT_FROM_DATABASE=Solo-1 Audio Adapter
+
+pci:v0000125Dd00001969sv0000153Bsd0000111B*
+ ID_PRODUCT_FROM_DATABASE=Terratec 128i PCI
+
+pci:v0000125Dd00001978*
+ ID_PRODUCT_FROM_DATABASE=ES1978 Maestro 2E
+
+pci:v0000125Dd00001978sv00000E11sd0000B112*
+ ID_PRODUCT_FROM_DATABASE=Armada M700/E500
+
+pci:v0000125Dd00001978sv00001033sd0000803C*
+ ID_PRODUCT_FROM_DATABASE=ES1978 Maestro-2E Audiodrive
+
+pci:v0000125Dd00001978sv00001033sd00008058*
+ ID_PRODUCT_FROM_DATABASE=ES1978 Maestro-2E Audiodrive
+
+pci:v0000125Dd00001978sv00001092sd00004000*
+ ID_PRODUCT_FROM_DATABASE=Monster Sound MX400
+
+pci:v0000125Dd00001978sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=ES1978 Maestro-2E Audiodrive
+
+pci:v0000125Dd00001988*
+ ID_PRODUCT_FROM_DATABASE=ES1988 Allegro-1
+
+pci:v0000125Dd00001988sv00000E11sd00000098*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v0000125Dd00001988sv00001092sd00004100*
+ ID_PRODUCT_FROM_DATABASE=Sonic Impact S100
+
+pci:v0000125Dd00001988sv0000125Dsd00000431*
+ ID_PRODUCT_FROM_DATABASE=Allegro AudioDrive
+
+pci:v0000125Dd00001988sv0000125Dsd00001988*
+ ID_PRODUCT_FROM_DATABASE=ESS Allegro-1 Audiodrive
+
+pci:v0000125Dd00001988sv0000125Dsd00001998*
+ ID_PRODUCT_FROM_DATABASE=Allegro AudioDrive
+
+pci:v0000125Dd00001988sv0000125Dsd00001999*
+ ID_PRODUCT_FROM_DATABASE=Allegro-1 AudioDrive
+
+pci:v0000125Dd00001989*
+ ID_PRODUCT_FROM_DATABASE=ESS Modem
+
+pci:v0000125Dd00001989sv0000125Dsd00001989*
+ ID_PRODUCT_FROM_DATABASE=ESS Modem
+
+pci:v0000125Dd00001998*
+ ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i PCI Audio Accelerator
+
+pci:v0000125Dd00001998sv00001028sd000000B1*
+ ID_PRODUCT_FROM_DATABASE=Latitude C600
+
+pci:v0000125Dd00001998sv00001028sd000000E6*
+ ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i (Dell Inspiron 8100)
+
+pci:v0000125Dd00001999*
+ ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i PCI Modem Accelerator
+
+pci:v0000125Dd0000199A*
+ ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i PCI Audio Accelerator
+
+pci:v0000125Dd0000199B*
+ ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i PCI Modem Accelerator
+
+pci:v0000125Dd00002808*
+ ID_PRODUCT_FROM_DATABASE=ES336H Fax Modem (Later Model)
+
+pci:v0000125Dd00002838*
+ ID_PRODUCT_FROM_DATABASE=ES2838/2839 SuperLink Modem
+
+pci:v0000125Dd00002898*
+ ID_PRODUCT_FROM_DATABASE=ES2898 Modem
+
+pci:v0000125Dd00002898sv0000125Dsd00000424*
+ ID_PRODUCT_FROM_DATABASE=ES56-PI Data Fax Modem
+
+pci:v0000125Dd00002898sv0000125Dsd00000425*
+ ID_PRODUCT_FROM_DATABASE=ES56T-PI Data Fax Modem
+
+pci:v0000125Dd00002898sv0000125Dsd00000426*
+ ID_PRODUCT_FROM_DATABASE=ES56V-PI Data Fax Modem
+
+pci:v0000125Dd00002898sv0000125Dsd00000427*
+ ID_PRODUCT_FROM_DATABASE=VW-PI Data Fax Modem
+
+pci:v0000125Dd00002898sv0000125Dsd00000428*
+ ID_PRODUCT_FROM_DATABASE=ES56ST-PI Data Fax Modem
+
+pci:v0000125Dd00002898sv0000125Dsd00000429*
+ ID_PRODUCT_FROM_DATABASE=ES56SV-PI Data Fax Modem
+
+pci:v0000125Dd00002898sv0000147Asd0000C001*
+ ID_PRODUCT_FROM_DATABASE=ES56-PI Data Fax Modem
+
+pci:v0000125Dd00002898sv0000148Dsd00001030*
+ ID_PRODUCT_FROM_DATABASE=HCF WV-PI56 [ESS ES56-PI Data Fax Modem]
+
+pci:v0000125Dd00002898sv000014FEsd00000428*
+ ID_PRODUCT_FROM_DATABASE=ES56-PI Data Fax Modem
+
+pci:v0000125Dd00002898sv000014FEsd00000429*
+ ID_PRODUCT_FROM_DATABASE=ES56-PI Data Fax Modem
+
+pci:v0000125E*
+ ID_VENDOR_FROM_DATABASE=Specialvideo Engineering SRL
+
+pci:v0000125F*
+ ID_VENDOR_FROM_DATABASE=Concurrent Technologies, Inc.
+
+pci:v00001260*
+ ID_VENDOR_FROM_DATABASE=Intersil Corporation
+
+pci:v00001260d00003872*
+ ID_PRODUCT_FROM_DATABASE=ISL3872 [Prism 3]
+
+pci:v00001260d00003872sv00001468sd00000202*
+ ID_PRODUCT_FROM_DATABASE=LAN-Express IEEE 802.11b Wireless LAN
+
+pci:v00001260d00003873*
+ ID_PRODUCT_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3]
+
+pci:v00001260d00003873sv000010CFsd00001169*
+ ID_PRODUCT_FROM_DATABASE=MBH7WM01-8734 802.11b Wireless Mini PCI Card [ISL3874]
+
+pci:v00001260d00003873sv00001186sd00003501*
+ ID_PRODUCT_FROM_DATABASE=DWL-520 Wireless PCI Adapter (rev A or B) [ISL3874]
+
+pci:v00001260d00003873sv00001186sd00003700*
+ ID_PRODUCT_FROM_DATABASE=DWL-520 Wireless PCI Adapter (rev E1) [ISL3872]
+
+pci:v00001260d00003873sv00001385sd00004105*
+ ID_PRODUCT_FROM_DATABASE=MA311 802.11b wireless adapter [ISL3874]
+
+pci:v00001260d00003873sv00001668sd00000414*
+ ID_PRODUCT_FROM_DATABASE=HWP01170-01 802.11b PCI Wireless Adapter
+
+pci:v00001260d00003873sv000016A5sd00001601*
+ ID_PRODUCT_FROM_DATABASE=AIR.mate PC-400 PCI Wireless LAN Adapter
+
+pci:v00001260d00003873sv00001737sd00003874*
+ ID_PRODUCT_FROM_DATABASE=WMP11 v1 802.11b Wireless-B PCI Adapter [ISL3874]
+
+pci:v00001260d00003873sv00004033sd00007033*
+ ID_PRODUCT_FROM_DATABASE=PCW200 802.11b Wireless PCI Adapter [ISL3874]
+
+pci:v00001260d00003873sv00008086sd00002510*
+ ID_PRODUCT_FROM_DATABASE=M3AWEB Wireless 802.11b MiniPCI Adapter
+
+pci:v00001260d00003873sv00008086sd00002513*
+ ID_PRODUCT_FROM_DATABASE=Wireless 802.11b MiniPCI Adapter
+
+pci:v00001260d00003877*
+ ID_PRODUCT_FROM_DATABASE=ISL3877 [Prism Indigo]
+
+pci:v00001260d00003886*
+ ID_PRODUCT_FROM_DATABASE=ISL3886 [Prism Javelin/Prism Xbow]
+
+pci:v00001260d00003886sv000017CFsd00000037*
+ ID_PRODUCT_FROM_DATABASE=XG-901 and clones Wireless Adapter
+
+pci:v00001260d00003890*
+ ID_PRODUCT_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow]
+
+pci:v00001260d00003890sv000010B8sd00002802*
+ ID_PRODUCT_FROM_DATABASE=SMC2802W V1 Wireless PCI Adapter [ISL3890]
+
+pci:v00001260d00003890sv000010B8sd00002835*
+ ID_PRODUCT_FROM_DATABASE=SMC2835W Wireless Cardbus Adapter
+
+pci:v00001260d00003890sv000010B8sd0000A835*
+ ID_PRODUCT_FROM_DATABASE=SMC2835W V2 Wireless Cardbus Adapter
+
+pci:v00001260d00003890sv00001113sd00004203*
+ ID_PRODUCT_FROM_DATABASE=WN4201B
+
+pci:v00001260d00003890sv00001113sd00008201*
+ ID_PRODUCT_FROM_DATABASE=T-Com T-Sinus 154pcicard Wireless PCI Adapter
+
+pci:v00001260d00003890sv00001113sd0000B301*
+ ID_PRODUCT_FROM_DATABASE=T-Sinus 154card Cardbus
+
+pci:v00001260d00003890sv00001113sd0000EE03*
+ ID_PRODUCT_FROM_DATABASE=SMC2802W V2 Wireless PCI Adapter [ISL3886]
+
+pci:v00001260d00003890sv00001113sd0000EE08*
+ ID_PRODUCT_FROM_DATABASE=SMC2835W V3 EU Wireless Cardbus Adapter
+
+pci:v00001260d00003890sv00001186sd00003202*
+ ID_PRODUCT_FROM_DATABASE=DWL-G650 A1 Wireless Adapter
+
+pci:v00001260d00003890sv00001259sd0000C104*
+ ID_PRODUCT_FROM_DATABASE=CG-WLCB54GT Wireless Adapter
+
+pci:v00001260d00003890sv00001260sd00000000*
+ ID_PRODUCT_FROM_DATABASE=WG511 v1 54 Mbps Wireless PC Card
+
+pci:v00001260d00003890sv00001385sd00004800*
+ ID_PRODUCT_FROM_DATABASE=WG511 v2/v3 54 Mbps Wireless PC Card
+
+pci:v00001260d00003890sv000016A5sd00001605*
+ ID_PRODUCT_FROM_DATABASE=ALLNET ALL0271 Wireless PCI Adapter
+
+pci:v00001260d00003890sv000017CFsd00000014*
+ ID_PRODUCT_FROM_DATABASE=XG-600 and clones Wireless Adapter
+
+pci:v00001260d00003890sv000017CFsd00000020*
+ ID_PRODUCT_FROM_DATABASE=XG-900 and clones Wireless Adapter
+
+pci:v00001260d00003890sv0000187Esd00003403*
+ ID_PRODUCT_FROM_DATABASE=G-110 802.11g Wireless Cardbus Adapter
+
+pci:v00001260d00008130*
+ ID_PRODUCT_FROM_DATABASE=HMP8130 NTSC/PAL Video Decoder
+
+pci:v00001260d00008131*
+ ID_PRODUCT_FROM_DATABASE=HMP8131 NTSC/PAL Video Decoder
+
+pci:v00001260d0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=ISL3886IK
+
+pci:v00001260d0000FFFFsv00001260sd00000000*
+ ID_PRODUCT_FROM_DATABASE=Senao 3054MP+ (J) mini-PCI WLAN 802.11g adapter
+
+pci:v00001261*
+ ID_VENDOR_FROM_DATABASE=Matsushita-Kotobuki Electronics Industries, Ltd.
+
+pci:v00001262*
+ ID_VENDOR_FROM_DATABASE=ES Computer Company, Ltd.
+
+pci:v00001263*
+ ID_VENDOR_FROM_DATABASE=Sonic Solutions
+
+pci:v00001264*
+ ID_VENDOR_FROM_DATABASE=Aval Nagasaki Corporation
+
+pci:v00001265*
+ ID_VENDOR_FROM_DATABASE=Casio Computer Co., Ltd.
+
+pci:v00001266*
+ ID_VENDOR_FROM_DATABASE=Microdyne Corporation
+
+pci:v00001266d00000001*
+ ID_PRODUCT_FROM_DATABASE=NE10/100 Adapter (i82557B)
+
+pci:v00001266d00001910*
+ ID_PRODUCT_FROM_DATABASE=NE2000Plus (RT8029) Ethernet Adapter
+
+pci:v00001266d00001910sv00001266sd00001910*
+ ID_PRODUCT_FROM_DATABASE=NE2000Plus Ethernet Adapter
+
+pci:v00001267*
+ ID_VENDOR_FROM_DATABASE=S. A. Telecommunications
+
+pci:v00001267d00005352*
+ ID_PRODUCT_FROM_DATABASE=PCR2101
+
+pci:v00001267d00005A4B*
+ ID_PRODUCT_FROM_DATABASE=Telsat Turbo
+
+pci:v00001268*
+ ID_VENDOR_FROM_DATABASE=Tektronix
+
+pci:v00001269*
+ ID_VENDOR_FROM_DATABASE=Thomson-CSF/TTM
+
+pci:v0000126A*
+ ID_VENDOR_FROM_DATABASE=Lexmark International, Inc.
+
+pci:v0000126B*
+ ID_VENDOR_FROM_DATABASE=Adax, Inc.
+
+pci:v0000126C*
+ ID_VENDOR_FROM_DATABASE=Northern Telecom
+
+pci:v0000126Cd00001211*
+ ID_PRODUCT_FROM_DATABASE=10/100BaseTX [RTL81xx]
+
+pci:v0000126Cd0000126C*
+ ID_PRODUCT_FROM_DATABASE=802.11b Wireless Ethernet Adapter
+
+pci:v0000126D*
+ ID_VENDOR_FROM_DATABASE=Splash Technology, Inc.
+
+pci:v0000126E*
+ ID_VENDOR_FROM_DATABASE=Sumitomo Metal Industries, Ltd.
+
+pci:v0000126F*
+ ID_VENDOR_FROM_DATABASE=Silicon Motion, Inc.
+
+pci:v0000126Fd00000501*
+ ID_PRODUCT_FROM_DATABASE=SM501 VoyagerGX Rev. AA
+
+pci:v0000126Fd00000510*
+ ID_PRODUCT_FROM_DATABASE=SM501 VoyagerGX Rev. B
+
+pci:v0000126Fd00000710*
+ ID_PRODUCT_FROM_DATABASE=SM710 LynxEM
+
+pci:v0000126Fd00000712*
+ ID_PRODUCT_FROM_DATABASE=SM712 LynxEM+
+
+pci:v0000126Fd00000720*
+ ID_PRODUCT_FROM_DATABASE=SM720 Lynx3DM
+
+pci:v0000126Fd00000730*
+ ID_PRODUCT_FROM_DATABASE=SM731 Cougar3DR
+
+pci:v0000126Fd00000810*
+ ID_PRODUCT_FROM_DATABASE=SM810 LynxE
+
+pci:v0000126Fd00000811*
+ ID_PRODUCT_FROM_DATABASE=SM811 LynxE
+
+pci:v0000126Fd00000820*
+ ID_PRODUCT_FROM_DATABASE=SM820 Lynx3D
+
+pci:v0000126Fd00000910*
+ ID_PRODUCT_FROM_DATABASE=SM910
+
+pci:v00001270*
+ ID_VENDOR_FROM_DATABASE=Olympus Optical Co., Ltd.
+
+pci:v00001271*
+ ID_VENDOR_FROM_DATABASE=GW Instruments
+
+pci:v00001272*
+ ID_VENDOR_FROM_DATABASE=Telematics International
+
+pci:v00001273*
+ ID_VENDOR_FROM_DATABASE=Hughes Network Systems
+
+pci:v00001273d00000002*
+ ID_PRODUCT_FROM_DATABASE=DirecPC
+
+pci:v00001274*
+ ID_VENDOR_FROM_DATABASE=Ensoniq
+
+pci:v00001274d00001171*
+ ID_PRODUCT_FROM_DATABASE=ES1373 [AudioPCI] (also Creative Labs CT5803)
+
+pci:v00001274d00001371*
+ ID_PRODUCT_FROM_DATABASE=ES1371 [AudioPCI-97]
+
+pci:v00001274d00001371sv00000E11sd00000024*
+ ID_PRODUCT_FROM_DATABASE=AudioPCI on Motherboard Compaq Deskpro
+
+pci:v00001274d00001371sv00000E11sd0000B1A7*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI
+
+pci:v00001274d00001371sv00001033sd000080AC*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI
+
+pci:v00001274d00001371sv00001042sd00001854*
+ ID_PRODUCT_FROM_DATABASE=Tazer
+
+pci:v00001274d00001371sv0000107Bsd00008054*
+ ID_PRODUCT_FROM_DATABASE=Tabor2
+
+pci:v00001274d00001371sv00001274sd00001371*
+ ID_PRODUCT_FROM_DATABASE=Creative Sound Blaster AudioPCI64V, AudioPCI128
+
+pci:v00001274d00001371sv00001274sd00008001*
+ ID_PRODUCT_FROM_DATABASE=CT4751 board
+
+pci:v00001274d00001371sv00001462sd00006470*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A
+
+pci:v00001274d00001371sv00001462sd00006560*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10
+
+pci:v00001274d00001371sv00001462sd00006630*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A
+
+pci:v00001274d00001371sv00001462sd00006631*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A
+
+pci:v00001274d00001371sv00001462sd00006632*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A
+
+pci:v00001274d00001371sv00001462sd00006633*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A
+
+pci:v00001274d00001371sv00001462sd00006820*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00
+
+pci:v00001274d00001371sv00001462sd00006822*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A
+
+pci:v00001274d00001371sv00001462sd00006830*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00
+
+pci:v00001274d00001371sv00001462sd00006880*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00
+
+pci:v00001274d00001371sv00001462sd00006900*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00
+
+pci:v00001274d00001371sv00001462sd00006910*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6191
+
+pci:v00001274d00001371sv00001462sd00006930*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6193
+
+pci:v00001274d00001371sv00001462sd00006990*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A
+
+pci:v00001274d00001371sv00001462sd00006991*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A
+
+pci:v00001274d00001371sv000014A4sd00002077*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KR639
+
+pci:v00001274d00001371sv000014A4sd00002105*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MR800
+
+pci:v00001274d00001371sv000014A4sd00002107*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MR801
+
+pci:v00001274d00001371sv000014A4sd00002172*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard DR739
+
+pci:v00001274d00001371sv00001509sd00009902*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KW11
+
+pci:v00001274d00001371sv00001509sd00009903*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KW31
+
+pci:v00001274d00001371sv00001509sd00009904*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KA11
+
+pci:v00001274d00001371sv00001509sd00009905*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KC13
+
+pci:v00001274d00001371sv0000152Dsd00008801*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard CP810E
+
+pci:v00001274d00001371sv0000152Dsd00008802*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard CP810
+
+pci:v00001274d00001371sv0000152Dsd00008803*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3810E
+
+pci:v00001274d00001371sv0000152Dsd00008804*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3810-S
+
+pci:v00001274d00001371sv0000152Dsd00008805*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3820-S
+
+pci:v00001274d00001371sv0000270Fsd00002001*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6CTR
+
+pci:v00001274d00001371sv0000270Fsd00002200*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WTX
+
+pci:v00001274d00001371sv0000270Fsd00003000*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WSV
+
+pci:v00001274d00001371sv0000270Fsd00003100*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WIV2
+
+pci:v00001274d00001371sv0000270Fsd00003102*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WIV
+
+pci:v00001274d00001371sv0000270Fsd00007060*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6ASA2
+
+pci:v00001274d00001371sv00008086sd00004249*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BI440ZX
+
+pci:v00001274d00001371sv00008086sd0000424C*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BL440ZX
+
+pci:v00001274d00001371sv00008086sd0000425A*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BZ440ZX
+
+pci:v00001274d00001371sv00008086sd00004341*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Cayman
+
+pci:v00001274d00001371sv00008086sd00004343*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Cape Cod
+
+pci:v00001274d00001371sv00008086sd00004541*
+ ID_PRODUCT_FROM_DATABASE=D815EEA Motherboard
+
+pci:v00001274d00001371sv00008086sd00004649*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Fire Island
+
+pci:v00001274d00001371sv00008086sd0000464A*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard FJ440ZX
+
+pci:v00001274d00001371sv00008086sd00004D4F*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Montreal
+
+pci:v00001274d00001371sv00008086sd00004F43*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard OC440LX
+
+pci:v00001274d00001371sv00008086sd00005243*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard RC440BX
+
+pci:v00001274d00001371sv00008086sd00005352*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard SunRiver
+
+pci:v00001274d00001371sv00008086sd00005643*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Vancouver
+
+pci:v00001274d00001371sv00008086sd00005753*
+ ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard WS440BX
+
+pci:v00001274d00005000*
+ ID_PRODUCT_FROM_DATABASE=ES1370 [AudioPCI]
+
+pci:v00001274d00005880*
+ ID_PRODUCT_FROM_DATABASE=5880B [AudioPCI]
+
+pci:v00001274d00005880sv00001274sd00002000*
+ ID_PRODUCT_FROM_DATABASE=Creative Sound Blaster AudioPCI128
+
+pci:v00001274d00005880sv00001274sd00002003*
+ ID_PRODUCT_FROM_DATABASE=Creative SoundBlaster AudioPCI 128
+
+pci:v00001274d00005880sv00001274sd00005880*
+ ID_PRODUCT_FROM_DATABASE=Creative Sound Blaster AudioPCI128
+
+pci:v00001274d00005880sv00001274sd00008001*
+ ID_PRODUCT_FROM_DATABASE=Sound Blaster 16PCI 4.1ch
+
+pci:v00001274d00005880sv00001458sd0000A000*
+ ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard 6OXET
+
+pci:v00001274d00005880sv00001462sd00006880*
+ ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard MS-6188 1.00
+
+pci:v00001274d00005880sv0000270Fsd00002001*
+ ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard 6CTR
+
+pci:v00001274d00005880sv0000270Fsd00002200*
+ ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard 6WTX
+
+pci:v00001274d00005880sv0000270Fsd00007040*
+ ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard 6ATA4
+
+pci:v00001274d00008001*
+ ID_PRODUCT_FROM_DATABASE=CT5880 [AudioPCI]
+
+pci:v00001274d00008002*
+ ID_PRODUCT_FROM_DATABASE=5880A [AudioPCI]
+
+pci:v00001275*
+ ID_VENDOR_FROM_DATABASE=Network Appliance Corporation
+
+pci:v00001276*
+ ID_VENDOR_FROM_DATABASE=Switched Network Technologies, Inc.
+
+pci:v00001277*
+ ID_VENDOR_FROM_DATABASE=Comstream
+
+pci:v00001278*
+ ID_VENDOR_FROM_DATABASE=Transtech Parallel Systems Ltd.
+
+pci:v00001278d00000701*
+ ID_PRODUCT_FROM_DATABASE=TPE3/TM3 PowerPC Node
+
+pci:v00001278d00000710*
+ ID_PRODUCT_FROM_DATABASE=TPE5 PowerPC PCI board
+
+pci:v00001278d00001100*
+ ID_PRODUCT_FROM_DATABASE=PMC-FPGA02
+
+pci:v00001278d00001101*
+ ID_PRODUCT_FROM_DATABASE=TS-C43 card with 4 ADSP-TS101 processors
+
+pci:v00001279*
+ ID_VENDOR_FROM_DATABASE=Transmeta Corporation
+
+pci:v00001279d00000060*
+ ID_PRODUCT_FROM_DATABASE=TM8000 Northbridge
+
+pci:v00001279d00000061*
+ ID_PRODUCT_FROM_DATABASE=TM8000 AGP bridge
+
+pci:v00001279d00000295*
+ ID_PRODUCT_FROM_DATABASE=Northbridge
+
+pci:v00001279d00000395*
+ ID_PRODUCT_FROM_DATABASE=LongRun Northbridge
+
+pci:v00001279d00000396*
+ ID_PRODUCT_FROM_DATABASE=SDRAM controller
+
+pci:v00001279d00000397*
+ ID_PRODUCT_FROM_DATABASE=BIOS scratchpad
+
+pci:v0000127A*
+ ID_VENDOR_FROM_DATABASE=Rockwell International
+
+pci:v0000127Ad00001002*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v0000127Ad00001002sv00001092sd0000094C*
+ ID_PRODUCT_FROM_DATABASE=SupraExpress 56i PRO [Diamond SUP2380]
+
+pci:v0000127Ad00001002sv0000122Dsd00004002*
+ ID_PRODUCT_FROM_DATABASE=HPG / MDP3858-U
+
+pci:v0000127Ad00001002sv0000122Dsd00004005*
+ ID_PRODUCT_FROM_DATABASE=MDP3858-E
+
+pci:v0000127Ad00001002sv0000122Dsd00004007*
+ ID_PRODUCT_FROM_DATABASE=MDP3858-A/-NZ
+
+pci:v0000127Ad00001002sv0000122Dsd00004012*
+ ID_PRODUCT_FROM_DATABASE=MDP3858-SA
+
+pci:v0000127Ad00001002sv0000122Dsd00004017*
+ ID_PRODUCT_FROM_DATABASE=MDP3858-W
+
+pci:v0000127Ad00001002sv0000122Dsd00004018*
+ ID_PRODUCT_FROM_DATABASE=MDP3858-W
+
+pci:v0000127Ad00001002sv0000127Asd00001002*
+ ID_PRODUCT_FROM_DATABASE=Rockwell 56K D/F HCF Modem
+
+pci:v0000127Ad00001003*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v0000127Ad00001003sv00000E11sd0000B0BC*
+ ID_PRODUCT_FROM_DATABASE=229-DF Zephyr
+
+pci:v0000127Ad00001003sv00000E11sd0000B114*
+ ID_PRODUCT_FROM_DATABASE=229-DF Cheetah
+
+pci:v0000127Ad00001003sv00001033sd0000802B*
+ ID_PRODUCT_FROM_DATABASE=229-DF
+
+pci:v0000127Ad00001003sv000013DFsd00001003*
+ ID_PRODUCT_FROM_DATABASE=PCI56RX Modem
+
+pci:v0000127Ad00001003sv000013E0sd00000117*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001003sv000013E0sd00000147*
+ ID_PRODUCT_FROM_DATABASE=IBM F-1156IV+/R3 Spain V.90 Modem
+
+pci:v0000127Ad00001003sv000013E0sd00000197*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001003sv000013E0sd000001C7*
+ ID_PRODUCT_FROM_DATABASE=IBM F-1156IV+/R3 WW V.90 Modem
+
+pci:v0000127Ad00001003sv000013E0sd000001F7*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001003sv00001436sd00001003*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001003sv00001436sd00001103*
+ ID_PRODUCT_FROM_DATABASE=IBM 5614PM3G V.90 Modem
+
+pci:v0000127Ad00001003sv00001436sd00001602*
+ ID_PRODUCT_FROM_DATABASE=Compaq 229-DF Ducati
+
+pci:v0000127Ad00001004*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
+
+pci:v0000127Ad00001004sv00001048sd00001500*
+ ID_PRODUCT_FROM_DATABASE=MicroLink 56k Modem
+
+pci:v0000127Ad00001004sv000010CFsd00001059*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu 229-DFRT
+
+pci:v0000127Ad00001005*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v0000127Ad00001005sv00001005sd0000127A*
+ ID_PRODUCT_FROM_DATABASE=AOpen FM56-P
+
+pci:v0000127Ad00001005sv00001033sd00008029*
+ ID_PRODUCT_FROM_DATABASE=229-DFSV
+
+pci:v0000127Ad00001005sv00001033sd00008054*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v0000127Ad00001005sv000010CFsd0000103C*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu
+
+pci:v0000127Ad00001005sv000010CFsd00001055*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu 229-DFSV
+
+pci:v0000127Ad00001005sv000010CFsd00001056*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu 229-DFSV
+
+pci:v0000127Ad00001005sv0000122Dsd00004003*
+ ID_PRODUCT_FROM_DATABASE=MDP3858SP-U
+
+pci:v0000127Ad00001005sv0000122Dsd00004006*
+ ID_PRODUCT_FROM_DATABASE=Packard Bell MDP3858V-E
+
+pci:v0000127Ad00001005sv0000122Dsd00004008*
+ ID_PRODUCT_FROM_DATABASE=MDP3858SP-A/SP-NZ
+
+pci:v0000127Ad00001005sv0000122Dsd00004009*
+ ID_PRODUCT_FROM_DATABASE=MDP3858SP-E
+
+pci:v0000127Ad00001005sv0000122Dsd00004010*
+ ID_PRODUCT_FROM_DATABASE=MDP3858V-U
+
+pci:v0000127Ad00001005sv0000122Dsd00004011*
+ ID_PRODUCT_FROM_DATABASE=MDP3858SP-SA
+
+pci:v0000127Ad00001005sv0000122Dsd00004013*
+ ID_PRODUCT_FROM_DATABASE=MDP3858V-A/V-NZ
+
+pci:v0000127Ad00001005sv0000122Dsd00004015*
+ ID_PRODUCT_FROM_DATABASE=MDP3858SP-W
+
+pci:v0000127Ad00001005sv0000122Dsd00004016*
+ ID_PRODUCT_FROM_DATABASE=MDP3858V-W
+
+pci:v0000127Ad00001005sv0000122Dsd00004019*
+ ID_PRODUCT_FROM_DATABASE=MDP3858V-SA
+
+pci:v0000127Ad00001005sv000013DFsd00001005*
+ ID_PRODUCT_FROM_DATABASE=PCI56RVP Modem
+
+pci:v0000127Ad00001005sv000013E0sd00000187*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001005sv000013E0sd000001A7*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001005sv000013E0sd000001B7*
+ ID_PRODUCT_FROM_DATABASE=IBM DF-1156IV+/R3 Spain V.90 Modem
+
+pci:v0000127Ad00001005sv000013E0sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=IBM DF-1156IV+/R3 WW V.90 Modem
+
+pci:v0000127Ad00001005sv00001436sd00001005*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001005sv00001436sd00001105*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001005sv00001437sd00001105*
+ ID_PRODUCT_FROM_DATABASE=IBM 5614PS3G V.90 Modem
+
+pci:v0000127Ad00001022*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v0000127Ad00001022sv00001436sd00001303*
+ ID_PRODUCT_FROM_DATABASE=M3-5614PM3G V.90 Modem
+
+pci:v0000127Ad00001023*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v0000127Ad00001023sv0000122Dsd00004020*
+ ID_PRODUCT_FROM_DATABASE=Packard Bell MDP3858-WE
+
+pci:v0000127Ad00001023sv0000122Dsd00004023*
+ ID_PRODUCT_FROM_DATABASE=MDP3858-UE
+
+pci:v0000127Ad00001023sv000013E0sd00000247*
+ ID_PRODUCT_FROM_DATABASE=IBM F-1156IV+/R6 Spain V.90 Modem
+
+pci:v0000127Ad00001023sv000013E0sd00000297*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001023sv000013E0sd000002C7*
+ ID_PRODUCT_FROM_DATABASE=IBM F-1156IV+/R6 WW V.90 Modem
+
+pci:v0000127Ad00001023sv00001436sd00001203*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001023sv00001436sd00001303*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v0000127Ad00001024*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
+
+pci:v0000127Ad00001025*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v0000127Ad00001025sv000010CFsd0000106A*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu 235-DFSV
+
+pci:v0000127Ad00001025sv0000122Dsd00004021*
+ ID_PRODUCT_FROM_DATABASE=Packard Bell MDP3858V-WE
+
+pci:v0000127Ad00001025sv0000122Dsd00004022*
+ ID_PRODUCT_FROM_DATABASE=MDP3858SP-WE
+
+pci:v0000127Ad00001025sv0000122Dsd00004024*
+ ID_PRODUCT_FROM_DATABASE=MDP3858V-UE
+
+pci:v0000127Ad00001025sv0000122Dsd00004025*
+ ID_PRODUCT_FROM_DATABASE=MDP3858SP-UE
+
+pci:v0000127Ad00001026*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k PCI Speakerphone Modem
+
+pci:v0000127Ad00001032*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v0000127Ad00001033*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v0000127Ad00001034*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v0000127Ad00001035*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k PCI Speakerphone Modem
+
+pci:v0000127Ad00001036*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v0000127Ad00001085*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Volcano PCI Modem
+
+pci:v0000127Ad00002004*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v0000127Ad00002005*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v0000127Ad00002005sv0000104Dsd00008044*
+ ID_PRODUCT_FROM_DATABASE=229-DFSV
+
+pci:v0000127Ad00002005sv0000104Dsd00008045*
+ ID_PRODUCT_FROM_DATABASE=229-DFSV
+
+pci:v0000127Ad00002005sv0000104Dsd00008055*
+ ID_PRODUCT_FROM_DATABASE=PBE/Aztech 235W-DFSV
+
+pci:v0000127Ad00002005sv0000104Dsd00008056*
+ ID_PRODUCT_FROM_DATABASE=235-DFSV
+
+pci:v0000127Ad00002005sv0000104Dsd0000805A*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v0000127Ad00002005sv0000104Dsd0000805F*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v0000127Ad00002005sv0000104Dsd00008074*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v0000127Ad00002013*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem
+
+pci:v0000127Ad00002013sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v0000127Ad00002013sv00001179sd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v0000127Ad00002014*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem
+
+pci:v0000127Ad00002014sv000010CFsd00001057*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu Citicorp III
+
+pci:v0000127Ad00002014sv0000122Dsd00004050*
+ ID_PRODUCT_FROM_DATABASE=MSP3880-U
+
+pci:v0000127Ad00002014sv0000122Dsd00004055*
+ ID_PRODUCT_FROM_DATABASE=MSP3880-W
+
+pci:v0000127Ad00002015*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v0000127Ad00002015sv000010CFsd00001063*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu
+
+pci:v0000127Ad00002015sv000010CFsd00001064*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu
+
+pci:v0000127Ad00002015sv00001468sd00002015*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu
+
+pci:v0000127Ad00002016*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem
+
+pci:v0000127Ad00002016sv0000122Dsd00004051*
+ ID_PRODUCT_FROM_DATABASE=MSP3880V-W
+
+pci:v0000127Ad00002016sv0000122Dsd00004052*
+ ID_PRODUCT_FROM_DATABASE=MSP3880SP-W
+
+pci:v0000127Ad00002016sv0000122Dsd00004054*
+ ID_PRODUCT_FROM_DATABASE=MSP3880V-U
+
+pci:v0000127Ad00002016sv0000122Dsd00004056*
+ ID_PRODUCT_FROM_DATABASE=MSP3880SP-U
+
+pci:v0000127Ad00002016sv0000122Dsd00004057*
+ ID_PRODUCT_FROM_DATABASE=MSP3880SP-A
+
+pci:v0000127Ad00004311*
+ ID_PRODUCT_FROM_DATABASE=Riptide HSF 56k PCI Modem
+
+pci:v0000127Ad00004311sv0000127Asd00004311*
+ ID_PRODUCT_FROM_DATABASE=Ring Modular? Riptide HSF RT HP Dom
+
+pci:v0000127Ad00004311sv000013E0sd00000210*
+ ID_PRODUCT_FROM_DATABASE=HP-GVC
+
+pci:v0000127Ad00004320*
+ ID_PRODUCT_FROM_DATABASE=Riptide PCI Audio Controller
+
+pci:v0000127Ad00004320sv00001235sd00004320*
+ ID_PRODUCT_FROM_DATABASE=Riptide PCI Audio Controller
+
+pci:v0000127Ad00004321*
+ ID_PRODUCT_FROM_DATABASE=Riptide HCF 56k PCI Modem
+
+pci:v0000127Ad00004321sv00001235sd00004321*
+ ID_PRODUCT_FROM_DATABASE=Hewlett Packard DF
+
+pci:v0000127Ad00004321sv00001235sd00004324*
+ ID_PRODUCT_FROM_DATABASE=Hewlett Packard DF
+
+pci:v0000127Ad00004321sv000013E0sd00000210*
+ ID_PRODUCT_FROM_DATABASE=Hewlett Packard DF
+
+pci:v0000127Ad00004321sv0000144Dsd00002321*
+ ID_PRODUCT_FROM_DATABASE=Riptide
+
+pci:v0000127Ad00004322*
+ ID_PRODUCT_FROM_DATABASE=Riptide PCI Game Controller
+
+pci:v0000127Ad00004322sv00001235sd00004322*
+ ID_PRODUCT_FROM_DATABASE=Riptide PCI Game Controller
+
+pci:v0000127Ad00008234*
+ ID_PRODUCT_FROM_DATABASE=RapidFire 616X ATM155 Adapter
+
+pci:v0000127Ad00008234sv0000108Dsd00000022*
+ ID_PRODUCT_FROM_DATABASE=RapidFire 616X ATM155 Adapter
+
+pci:v0000127Ad00008234sv0000108Dsd00000027*
+ ID_PRODUCT_FROM_DATABASE=RapidFire 616X ATM155 Adapter
+
+pci:v0000127B*
+ ID_VENDOR_FROM_DATABASE=Pixera Corporation
+
+pci:v0000127C*
+ ID_VENDOR_FROM_DATABASE=Crosspoint Solutions, Inc.
+
+pci:v0000127D*
+ ID_VENDOR_FROM_DATABASE=Vela Research
+
+pci:v0000127E*
+ ID_VENDOR_FROM_DATABASE=Winnov, L.P.
+
+pci:v0000127Ed00000010*
+ ID_PRODUCT_FROM_DATABASE=Videum 1000 Plus
+
+pci:v0000127F*
+ ID_VENDOR_FROM_DATABASE=Fujifilm
+
+pci:v00001280*
+ ID_VENDOR_FROM_DATABASE=Photoscript Group Ltd.
+
+pci:v00001281*
+ ID_VENDOR_FROM_DATABASE=Yokogawa Electric Corporation
+
+pci:v00001282*
+ ID_VENDOR_FROM_DATABASE=Davicom Semiconductor, Inc.
+
+pci:v00001282d00006585*
+ ID_PRODUCT_FROM_DATABASE=DM562P V90 Modem
+
+pci:v00001282d00009009*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 100/10 MBit
+
+pci:v00001282d00009100*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v00001282d00009102*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v00001282d00009102sv00000291sd00008212*
+ ID_PRODUCT_FROM_DATABASE=DM9102A (DM9102AE, SM9102AF) Ethernet 100/10 MBit
+
+pci:v00001282d00009132*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 100/10 MBit
+
+pci:v00001283*
+ ID_VENDOR_FROM_DATABASE=Integrated Technology Express, Inc.
+
+pci:v00001283d0000673A*
+ ID_PRODUCT_FROM_DATABASE=IT8330G
+
+pci:v00001283d00008152*
+ ID_PRODUCT_FROM_DATABASE=IT8152F/G Advanced RISC-to-PCI Companion Chip
+
+pci:v00001283d00008211*
+ ID_PRODUCT_FROM_DATABASE=ITE 8211F Single Channel UDMA 133
+
+pci:v00001283d00008211sv00001043sd00008138*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00001283d00008212*
+ ID_PRODUCT_FROM_DATABASE=IT8212 Dual channel ATA RAID controller
+
+pci:v00001283d00008212sv00001283sd00000001*
+ ID_PRODUCT_FROM_DATABASE=IT/ITE8212 Dual channel ATA RAID controller
+
+pci:v00001283d00008213*
+ ID_PRODUCT_FROM_DATABASE=IT8213 IDE Controller
+
+pci:v00001283d00008213sv00001458sd0000B000*
+ ID_PRODUCT_FROM_DATABASE=GA-EG45M-DS2H Mainboard
+
+pci:v00001283d00008330*
+ ID_PRODUCT_FROM_DATABASE=IT8330G
+
+pci:v00001283d00008872*
+ ID_PRODUCT_FROM_DATABASE=IT8874F PCI Dual Serial Port Controller
+
+pci:v00001283d00008888*
+ ID_PRODUCT_FROM_DATABASE=IT8888F/G PCI to ISA Bridge with SMB [Golden Gate]
+
+pci:v00001283d00008889*
+ ID_PRODUCT_FROM_DATABASE=IT8889F PCI to ISA Bridge
+
+pci:v00001283d0000E886*
+ ID_PRODUCT_FROM_DATABASE=IT8330G
+
+pci:v00001284*
+ ID_VENDOR_FROM_DATABASE=Sahara Networks, Inc.
+
+pci:v00001285*
+ ID_VENDOR_FROM_DATABASE=Platform Technologies, Inc.
+
+pci:v00001285d00000100*
+ ID_PRODUCT_FROM_DATABASE=AGOGO sound chip (aka ESS Maestro 1)
+
+pci:v00001286*
+ ID_VENDOR_FROM_DATABASE=Mazet GmbH
+
+pci:v00001287*
+ ID_VENDOR_FROM_DATABASE=M-Pact, Inc.
+
+pci:v00001287d0000001E*
+ ID_PRODUCT_FROM_DATABASE=LS220D DVD Decoder
+
+pci:v00001287d0000001F*
+ ID_PRODUCT_FROM_DATABASE=LS220C DVD Decoder
+
+pci:v00001288*
+ ID_VENDOR_FROM_DATABASE=Timestep Corporation
+
+pci:v00001289*
+ ID_VENDOR_FROM_DATABASE=AVC Technology, Inc.
+
+pci:v0000128A*
+ ID_VENDOR_FROM_DATABASE=Asante Technologies, Inc.
+
+pci:v0000128B*
+ ID_VENDOR_FROM_DATABASE=Transwitch Corporation
+
+pci:v0000128C*
+ ID_VENDOR_FROM_DATABASE=Retix Corporation
+
+pci:v0000128D*
+ ID_VENDOR_FROM_DATABASE=G2 Networks, Inc.
+
+pci:v0000128Dd00000021*
+ ID_PRODUCT_FROM_DATABASE=ATM155 Adapter
+
+pci:v0000128E*
+ ID_VENDOR_FROM_DATABASE=Hoontech Corporation/Samho Multi Tech Ltd.
+
+pci:v0000128Ed00000008*
+ ID_PRODUCT_FROM_DATABASE=ST128 WSS/SB
+
+pci:v0000128Ed00000009*
+ ID_PRODUCT_FROM_DATABASE=ST128 SAM9407
+
+pci:v0000128Ed0000000A*
+ ID_PRODUCT_FROM_DATABASE=ST128 Game Port
+
+pci:v0000128Ed0000000B*
+ ID_PRODUCT_FROM_DATABASE=ST128 MPU Port
+
+pci:v0000128Ed0000000C*
+ ID_PRODUCT_FROM_DATABASE=ST128 Ctrl Port
+
+pci:v0000128F*
+ ID_VENDOR_FROM_DATABASE=Tateno Dennou, Inc.
+
+pci:v00001290*
+ ID_VENDOR_FROM_DATABASE=Sord Computer Corporation
+
+pci:v00001291*
+ ID_VENDOR_FROM_DATABASE=NCS Computer Italia
+
+pci:v00001292*
+ ID_VENDOR_FROM_DATABASE=Tritech Microelectronics Inc
+
+pci:v00001292d0000FC02*
+ ID_PRODUCT_FROM_DATABASE=Pyramid3D TR25202
+
+pci:v00001293*
+ ID_VENDOR_FROM_DATABASE=Media Reality Technology
+
+pci:v00001294*
+ ID_VENDOR_FROM_DATABASE=Rhetorex, Inc.
+
+pci:v00001295*
+ ID_VENDOR_FROM_DATABASE=Imagenation Corporation
+
+pci:v00001295d00000800*
+ ID_PRODUCT_FROM_DATABASE=PXR800
+
+pci:v00001295d00001000*
+ ID_PRODUCT_FROM_DATABASE=PXD1000
+
+pci:v00001296*
+ ID_VENDOR_FROM_DATABASE=Kofax Image Products
+
+pci:v00001297*
+ ID_VENDOR_FROM_DATABASE=Holco Enterprise Co, Ltd/Shuttle Computer
+
+pci:v00001298*
+ ID_VENDOR_FROM_DATABASE=Spellcaster Telecommunications Inc.
+
+pci:v00001299*
+ ID_VENDOR_FROM_DATABASE=Knowledge Technology Lab.
+
+pci:v0000129A*
+ ID_VENDOR_FROM_DATABASE=VMetro, inc.
+
+pci:v0000129Ad00000615*
+ ID_PRODUCT_FROM_DATABASE=PBT-615 PCI-X Bus Analyzer
+
+pci:v0000129Ad00001100*
+ ID_PRODUCT_FROM_DATABASE=PMC-FPGA05
+
+pci:v0000129Ad00001106*
+ ID_PRODUCT_FROM_DATABASE=XMC-FPGA05F, PCI interface
+
+pci:v0000129Ad00001107*
+ ID_PRODUCT_FROM_DATABASE=XMC-FPGA05F, PCIe interface
+
+pci:v0000129Ad00001108*
+ ID_PRODUCT_FROM_DATABASE=XMC-FPGA05D, PCI interface
+
+pci:v0000129Ad00001109*
+ ID_PRODUCT_FROM_DATABASE=XMC-FPGA05D, PCIe interface
+
+pci:v0000129B*
+ ID_VENDOR_FROM_DATABASE=Image Access
+
+pci:v0000129C*
+ ID_VENDOR_FROM_DATABASE=Jaycor
+
+pci:v0000129D*
+ ID_VENDOR_FROM_DATABASE=Compcore Multimedia, Inc.
+
+pci:v0000129E*
+ ID_VENDOR_FROM_DATABASE=Victor Company of Japan, Ltd.
+
+pci:v0000129F*
+ ID_VENDOR_FROM_DATABASE=OEC Medical Systems, Inc.
+
+pci:v000012A0*
+ ID_VENDOR_FROM_DATABASE=Allen-Bradley Company
+
+pci:v000012A1*
+ ID_VENDOR_FROM_DATABASE=Simpact Associates, Inc.
+
+pci:v000012A2*
+ ID_VENDOR_FROM_DATABASE=Newgen Systems Corporation
+
+pci:v000012A3*
+ ID_VENDOR_FROM_DATABASE=Lucent Technologies
+
+pci:v000012A3d00008105*
+ ID_PRODUCT_FROM_DATABASE=T8105 H100 Digital Switch
+
+pci:v000012A4*
+ ID_VENDOR_FROM_DATABASE=NTT Electronics Technology Company
+
+pci:v000012A5*
+ ID_VENDOR_FROM_DATABASE=Vision Dynamics Ltd.
+
+pci:v000012A6*
+ ID_VENDOR_FROM_DATABASE=Scalable Networks, Inc.
+
+pci:v000012A7*
+ ID_VENDOR_FROM_DATABASE=AMO GmbH
+
+pci:v000012A8*
+ ID_VENDOR_FROM_DATABASE=News Datacom
+
+pci:v000012A9*
+ ID_VENDOR_FROM_DATABASE=Xiotech Corporation
+
+pci:v000012AA*
+ ID_VENDOR_FROM_DATABASE=SDL Communications, Inc.
+
+pci:v000012AB*
+ ID_VENDOR_FROM_DATABASE=Yuan Yuan Enterprise Co., Ltd.
+
+pci:v000012ABd00000000*
+ ID_PRODUCT_FROM_DATABASE=MPG160/Kuroutoshikou ITVC15-STVLP
+
+pci:v000012ABd00000002*
+ ID_PRODUCT_FROM_DATABASE=AU8830 [Vortex2] Based Sound Card With A3D Support
+
+pci:v000012ABd00000003*
+ ID_PRODUCT_FROM_DATABASE=T507 (DVB-T) TV tuner/capture device
+
+pci:v000012ABd00002300*
+ ID_PRODUCT_FROM_DATABASE=Club-3D Zap TV2100
+
+pci:v000012ABd00003000*
+ ID_PRODUCT_FROM_DATABASE=MPG-200C PCI DVD Decoder Card
+
+pci:v000012ABd00004789*
+ ID_PRODUCT_FROM_DATABASE=MPC788 MiniPCI Hybrid TV Tuner
+
+pci:v000012ABd0000FFF3*
+ ID_PRODUCT_FROM_DATABASE=MPG600/Kuroutoshikou ITVC16-STVLP
+
+pci:v000012ABd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=MPG600/Kuroutoshikou ITVC16-STVLP
+
+pci:v000012AC*
+ ID_VENDOR_FROM_DATABASE=Measurex Corporation
+
+pci:v000012AD*
+ ID_VENDOR_FROM_DATABASE=Multidata GmbH
+
+pci:v000012AE*
+ ID_VENDOR_FROM_DATABASE=Alteon Networks Inc.
+
+pci:v000012AEd00000001*
+ ID_PRODUCT_FROM_DATABASE=AceNIC Gigabit Ethernet
+
+pci:v000012AEd00000001sv00001014sd00000104*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX PCI Adapter
+
+pci:v000012AEd00000001sv000012AEsd00000001*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX (Universal)
+
+pci:v000012AEd00000001sv00001410sd00000104*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX PCI Adapter
+
+pci:v000012AEd00000002*
+ ID_PRODUCT_FROM_DATABASE=AceNIC Gigabit Ethernet (Copper)
+
+pci:v000012AEd00000002sv000010A9sd00008002*
+ ID_PRODUCT_FROM_DATABASE=Acenic Gigabit Ethernet
+
+pci:v000012AEd00000002sv000012AEsd00000002*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-T (3C986-T)
+
+pci:v000012AEd000000FA*
+ ID_PRODUCT_FROM_DATABASE=Farallon PN9100-T Gigabit Ethernet
+
+pci:v000012AF*
+ ID_VENDOR_FROM_DATABASE=TDK USA Corp
+
+pci:v000012B0*
+ ID_VENDOR_FROM_DATABASE=Jorge Scientific Corp
+
+pci:v000012B1*
+ ID_VENDOR_FROM_DATABASE=GammaLink
+
+pci:v000012B2*
+ ID_VENDOR_FROM_DATABASE=General Signal Networks
+
+pci:v000012B3*
+ ID_VENDOR_FROM_DATABASE=Inter-Face Co Ltd
+
+pci:v000012B4*
+ ID_VENDOR_FROM_DATABASE=FutureTel Inc
+
+pci:v000012B5*
+ ID_VENDOR_FROM_DATABASE=Granite Systems Inc.
+
+pci:v000012B6*
+ ID_VENDOR_FROM_DATABASE=Natural Microsystems
+
+pci:v000012B7*
+ ID_VENDOR_FROM_DATABASE=Cognex Modular Vision Systems Div. - Acumen Inc.
+
+pci:v000012B8*
+ ID_VENDOR_FROM_DATABASE=Korg
+
+pci:v000012B9*
+ ID_VENDOR_FROM_DATABASE=3Com Corp, Modem Division
+
+pci:v000012B9d00001006*
+ ID_PRODUCT_FROM_DATABASE=WinModem
+
+pci:v000012B9d00001006sv000012B9sd0000005C*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 3472)
+
+pci:v000012B9d00001006sv000012B9sd0000005E*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem (Models 662975)
+
+pci:v000012B9d00001006sv000012B9sd00000062*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 662978)
+
+pci:v000012B9d00001006sv000012B9sd00000068*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 5690)
+
+pci:v000012B9d00001006sv000012B9sd0000007A*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 662974)
+
+pci:v000012B9d00001006sv000012B9sd0000007F*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem (Models 5698, 5699)
+
+pci:v000012B9d00001006sv000012B9sd00000080*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem (Models 2975, 3528)
+
+pci:v000012B9d00001006sv000012B9sd00000081*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Models 2974, 3529)
+
+pci:v000012B9d00001006sv000012B9sd00000091*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 2978)
+
+pci:v000012B9d00001007*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem
+
+pci:v000012B9d00001007sv000012B9sd000000A3*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem (Model 3595)
+
+pci:v000012B9d00001007sv000012B9sd000000C4*
+ ID_PRODUCT_FROM_DATABASE=U.S. Robotics V.92 Voice Faxmodem (2884A/B/C)
+
+pci:v000012B9d00001008*
+ ID_PRODUCT_FROM_DATABASE=56K FaxModem Model 5610
+
+pci:v000012B9d00001008sv000012B9sd000000A2*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal FAX Modem (Model 2977)
+
+pci:v000012B9d00001008sv000012B9sd000000AA*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice Modem (Model 2976)
+
+pci:v000012B9d00001008sv000012B9sd000000AB*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice Modem (Model 5609)
+
+pci:v000012B9d00001008sv000012B9sd000000AC*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice Modem (Model 3298)
+
+pci:v000012B9d00001008sv000012B9sd000000AD*
+ ID_PRODUCT_FROM_DATABASE=USR 56k Internal FAX Modem (Model 5610)
+
+pci:v000012B9d00001008sv000012B9sd000000D3*
+ ID_PRODUCT_FROM_DATABASE=USR 56K Internal V92 FAX Modem (Model 5610)
+
+pci:v000012B9d00001008sv000012B9sd0000BABA*
+ ID_PRODUCT_FROM_DATABASE=USR 56K Internal Voice Modem 3CP3298-DEL (Model 5601) [Hawk]
+
+pci:v000012BA*
+ ID_VENDOR_FROM_DATABASE=BittWare, Inc.
+
+pci:v000012BB*
+ ID_VENDOR_FROM_DATABASE=Nippon Unisoft Corporation
+
+pci:v000012BC*
+ ID_VENDOR_FROM_DATABASE=Array Microsystems
+
+pci:v000012BD*
+ ID_VENDOR_FROM_DATABASE=Computerm Corp.
+
+pci:v000012BE*
+ ID_VENDOR_FROM_DATABASE=Anchor Chips Inc.
+
+pci:v000012BEd00003041*
+ ID_PRODUCT_FROM_DATABASE=AN3041Q CO-MEM
+
+pci:v000012BEd00003042*
+ ID_PRODUCT_FROM_DATABASE=AN3042Q CO-MEM Lite
+
+pci:v000012BEd00003042sv000012BEsd00003042*
+ ID_PRODUCT_FROM_DATABASE=Anchor Chips Lite Evaluation Board
+
+pci:v000012BF*
+ ID_VENDOR_FROM_DATABASE=Fujifilm Microdevices
+
+pci:v000012C0*
+ ID_VENDOR_FROM_DATABASE=Infimed
+
+pci:v000012C1*
+ ID_VENDOR_FROM_DATABASE=GMM Research Corp
+
+pci:v000012C2*
+ ID_VENDOR_FROM_DATABASE=Mentec Limited
+
+pci:v000012C3*
+ ID_VENDOR_FROM_DATABASE=Holtek Microelectronics Inc
+
+pci:v000012C3d00000058*
+ ID_PRODUCT_FROM_DATABASE=PCI NE2K Ethernet
+
+pci:v000012C3d00005598*
+ ID_PRODUCT_FROM_DATABASE=PCI NE2K Ethernet
+
+pci:v000012C4*
+ ID_VENDOR_FROM_DATABASE=Connect Tech Inc
+
+pci:v000012C4d00000001*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 8 (RS232/CL/RJ11)
+
+pci:v000012C4d00000002*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 4 (RS232)
+
+pci:v000012C4d00000003*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2 (RS232)
+
+pci:v000012C4d00000004*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 8 (UNIV, RS485)
+
+pci:v000012C4d00000005*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 4+4/6+2 (UNIV, RS232/485)
+
+pci:v000012C4d00000006*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 4 (OPTO, RS485)
+
+pci:v000012C4d00000007*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2+2 (RS232/485)
+
+pci:v000012C4d00000008*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2 (OPTO, Tx, RS485)
+
+pci:v000012C4d00000009*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2+6 (RS232/485)
+
+pci:v000012C4d0000000A*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 8 (Tx, RS485)
+
+pci:v000012C4d0000000B*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 4 (Tx, RS485)
+
+pci:v000012C4d0000000C*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2 (20 MHz, RS485)
+
+pci:v000012C4d0000000D*
+ ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2 PTM
+
+pci:v000012C4d00000100*
+ ID_PRODUCT_FROM_DATABASE=NT960/PCI
+
+pci:v000012C4d00000201*
+ ID_PRODUCT_FROM_DATABASE=cPCI Titan - 2 Port
+
+pci:v000012C4d00000202*
+ ID_PRODUCT_FROM_DATABASE=cPCI Titan - 4 Port
+
+pci:v000012C4d00000300*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 2 (RS232)
+
+pci:v000012C4d00000301*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 4 (RS232)
+
+pci:v000012C4d00000302*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 8 (RS232)
+
+pci:v000012C4d00000310*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 1+1 (RS232/485)
+
+pci:v000012C4d00000311*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 2+2 (RS232/485)
+
+pci:v000012C4d00000312*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 4+4 (RS232/485)
+
+pci:v000012C4d00000320*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 2
+
+pci:v000012C4d00000321*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 4
+
+pci:v000012C4d00000322*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 8
+
+pci:v000012C4d00000330*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 2 (RS485)
+
+pci:v000012C4d00000331*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 4 (RS485)
+
+pci:v000012C4d00000332*
+ ID_PRODUCT_FROM_DATABASE=CTI PCI UART 8 (RS485)
+
+pci:v000012C5*
+ ID_VENDOR_FROM_DATABASE=Picture Elements Incorporated
+
+pci:v000012C5d0000007E*
+ ID_PRODUCT_FROM_DATABASE=Imaging/Scanning Subsystem Engine
+
+pci:v000012C5d0000007F*
+ ID_PRODUCT_FROM_DATABASE=Imaging/Scanning Subsystem Engine
+
+pci:v000012C5d00000081*
+ ID_PRODUCT_FROM_DATABASE=PCIVST [Grayscale Thresholding Engine]
+
+pci:v000012C5d00000085*
+ ID_PRODUCT_FROM_DATABASE=Video Simulator/Sender
+
+pci:v000012C5d00000086*
+ ID_PRODUCT_FROM_DATABASE=THR2 Multi-scale Thresholder
+
+pci:v000012C6*
+ ID_VENDOR_FROM_DATABASE=Mitani Corporation
+
+pci:v000012C7*
+ ID_VENDOR_FROM_DATABASE=Dialogic Corp
+
+pci:v000012C7d00000546*
+ ID_PRODUCT_FROM_DATABASE=Springware D/120JCT-LS
+
+pci:v000012C7d00000647*
+ ID_PRODUCT_FROM_DATABASE=Springware D/240JCT-T1
+
+pci:v000012C7d00000676*
+ ID_PRODUCT_FROM_DATABASE=Springware D/41JCT-LS
+
+pci:v000012C7d00000685*
+ ID_PRODUCT_FROM_DATABASE=Springware D/480JCT-2T1
+
+pci:v000012C8*
+ ID_VENDOR_FROM_DATABASE=G Force Co, Ltd
+
+pci:v000012C9*
+ ID_VENDOR_FROM_DATABASE=Gigi Operations
+
+pci:v000012CA*
+ ID_VENDOR_FROM_DATABASE=Integrated Computing Engines
+
+pci:v000012CB*
+ ID_VENDOR_FROM_DATABASE=Antex Electronics Corporation
+
+pci:v000012CBd00000027*
+ ID_PRODUCT_FROM_DATABASE=SC4 (StudioCard)
+
+pci:v000012CBd0000002E*
+ ID_PRODUCT_FROM_DATABASE=StudioCard 2000
+
+pci:v000012CC*
+ ID_VENDOR_FROM_DATABASE=Pluto Technologies International
+
+pci:v000012CD*
+ ID_VENDOR_FROM_DATABASE=Aims Lab
+
+pci:v000012CE*
+ ID_VENDOR_FROM_DATABASE=Netspeed Inc.
+
+pci:v000012CF*
+ ID_VENDOR_FROM_DATABASE=Prophet Systems, Inc.
+
+pci:v000012D0*
+ ID_VENDOR_FROM_DATABASE=GDE Systems, Inc.
+
+pci:v000012D1*
+ ID_VENDOR_FROM_DATABASE=PSITech
+
+pci:v000012D2*
+ ID_VENDOR_FROM_DATABASE=NVidia / SGS Thomson (Joint Venture)
+
+pci:v000012D2d00000008*
+ ID_PRODUCT_FROM_DATABASE=NV1
+
+pci:v000012D2d00000009*
+ ID_PRODUCT_FROM_DATABASE=DAC64
+
+pci:v000012D2d00000018*
+ ID_PRODUCT_FROM_DATABASE=Riva128
+
+pci:v000012D2d00000018sv00001048sd00000C10*
+ ID_PRODUCT_FROM_DATABASE=VICTORY Erazor
+
+pci:v000012D2d00000018sv0000107Bsd00008030*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128
+
+pci:v000012D2d00000018sv00001092sd00000350*
+ ID_PRODUCT_FROM_DATABASE=Viper V330
+
+pci:v000012D2d00000018sv00001092sd00001092*
+ ID_PRODUCT_FROM_DATABASE=Viper V330
+
+pci:v000012D2d00000018sv000010B4sd00001B1B*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128
+
+pci:v000012D2d00000018sv000010B4sd00001B1D*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128
+
+pci:v000012D2d00000018sv000010B4sd00001B1E*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128, PAL TV-Out
+
+pci:v000012D2d00000018sv000010B4sd00001B20*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128 Sapphire
+
+pci:v000012D2d00000018sv000010B4sd00001B21*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128
+
+pci:v000012D2d00000018sv000010B4sd00001B22*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128 AGP, NTSC TV-Out
+
+pci:v000012D2d00000018sv000010B4sd00001B23*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128 AGP, PAL TV-Out
+
+pci:v000012D2d00000018sv000010B4sd00001B27*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128 DVD
+
+pci:v000012D2d00000018sv000010B4sd00001B88*
+ ID_PRODUCT_FROM_DATABASE=MVP Pro 128
+
+pci:v000012D2d00000018sv000010B4sd0000222A*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128 AGP
+
+pci:v000012D2d00000018sv000010B4sd00002230*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128
+
+pci:v000012D2d00000018sv000010B4sd00002232*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128
+
+pci:v000012D2d00000018sv000010B4sd00002235*
+ ID_PRODUCT_FROM_DATABASE=STB Velocity 128 AGP
+
+pci:v000012D2d00000018sv00002A15sd000054A3*
+ ID_PRODUCT_FROM_DATABASE=3DVision-SAGP / 3DexPlorer 3000
+
+pci:v000012D2d00000019*
+ ID_PRODUCT_FROM_DATABASE=Riva128ZX
+
+pci:v000012D2d00000020*
+ ID_PRODUCT_FROM_DATABASE=TNT
+
+pci:v000012D2d00000028*
+ ID_PRODUCT_FROM_DATABASE=TNT2
+
+pci:v000012D2d00000029*
+ ID_PRODUCT_FROM_DATABASE=UTNT2
+
+pci:v000012D2d0000002C*
+ ID_PRODUCT_FROM_DATABASE=VTNT2
+
+pci:v000012D2d000000A0*
+ ID_PRODUCT_FROM_DATABASE=ITNT2
+
+pci:v000012D3*
+ ID_VENDOR_FROM_DATABASE=Vingmed Sound A/S
+
+pci:v000012D4*
+ ID_VENDOR_FROM_DATABASE=Ulticom (Formerly DGM&S)
+
+pci:v000012D4d00000200*
+ ID_PRODUCT_FROM_DATABASE=T1 Card
+
+pci:v000012D5*
+ ID_VENDOR_FROM_DATABASE=Equator Technologies Inc
+
+pci:v000012D5d00000003*
+ ID_PRODUCT_FROM_DATABASE=BSP16
+
+pci:v000012D5d00001000*
+ ID_PRODUCT_FROM_DATABASE=BSP15
+
+pci:v000012D6*
+ ID_VENDOR_FROM_DATABASE=Analogic Corp
+
+pci:v000012D7*
+ ID_VENDOR_FROM_DATABASE=Biotronic SRL
+
+pci:v000012D8*
+ ID_VENDOR_FROM_DATABASE=Pericom Semiconductor
+
+pci:v000012D8d000001A7*
+ ID_PRODUCT_FROM_DATABASE=PI7C21P100 PCI to PCI Bridge
+
+pci:v000012D8d0000400A*
+ ID_PRODUCT_FROM_DATABASE=PI7C9X442SL PCI Express Bridge Port
+
+pci:v000012D8d0000400E*
+ ID_PRODUCT_FROM_DATABASE=PI7C9X442SL USB OHCI Controller
+
+pci:v000012D8d0000400F*
+ ID_PRODUCT_FROM_DATABASE=PI7C9X442SL USB EHCI Controller
+
+pci:v000012D8d000071E2*
+ ID_PRODUCT_FROM_DATABASE=PI7C7300A/PI7C7300D PCI-to-PCI Bridge
+
+pci:v000012D8d000071E3*
+ ID_PRODUCT_FROM_DATABASE=PI7C7300A/PI7C7300D PCI-to-PCI Bridge (Secondary Bus 2)
+
+pci:v000012D8d00008140*
+ ID_PRODUCT_FROM_DATABASE=PI7C8140A PCI-to-PCI Bridge
+
+pci:v000012D8d00008148*
+ ID_PRODUCT_FROM_DATABASE=PI7C8148A/PI7C8148B PCI-to-PCI Bridge
+
+pci:v000012D8d00008150*
+ ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge
+
+pci:v000012D8d00008152*
+ ID_PRODUCT_FROM_DATABASE=PI7C8152A/PI7C8152B/PI7C8152BI PCI-to-PCI Bridge
+
+pci:v000012D8d00008154*
+ ID_PRODUCT_FROM_DATABASE=PI7C8154A/PI7C8154B/PI7C8154BI PCI-to-PCI Bridge
+
+pci:v000012D8d0000E110*
+ ID_PRODUCT_FROM_DATABASE=PI7C9X110 PCI Express to PCI bridge
+
+pci:v000012D8d0000E110sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11 CompactPCI Bridge
+
+pci:v000012D8d0000E130*
+ ID_PRODUCT_FROM_DATABASE=PCI Express to PCI-XPI7C9X130 PCI-X Bridge
+
+pci:v000012D9*
+ ID_VENDOR_FROM_DATABASE=Aculab PLC
+
+pci:v000012D9d00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI Prosody
+
+pci:v000012D9d00000004*
+ ID_PRODUCT_FROM_DATABASE=cPCI Prosody
+
+pci:v000012D9d00000005*
+ ID_PRODUCT_FROM_DATABASE=Aculab E1/T1 PCI card
+
+pci:v000012D9d00001078*
+ ID_PRODUCT_FROM_DATABASE=Prosody X class e1000 device
+
+pci:v000012D9d00001078sv000012D9sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=Prosody X PCI
+
+pci:v000012D9d00001078sv000012D9sd0000000E*
+ ID_PRODUCT_FROM_DATABASE=Prosody X cPCI
+
+pci:v000012DA*
+ ID_VENDOR_FROM_DATABASE=True Time Inc.
+
+pci:v000012DB*
+ ID_VENDOR_FROM_DATABASE=Annapolis Micro Systems, Inc
+
+pci:v000012DC*
+ ID_VENDOR_FROM_DATABASE=Symicron Computer Communication Ltd.
+
+pci:v000012DD*
+ ID_VENDOR_FROM_DATABASE=Management Graphics
+
+pci:v000012DE*
+ ID_VENDOR_FROM_DATABASE=Rainbow Technologies
+
+pci:v000012DEd00000200*
+ ID_PRODUCT_FROM_DATABASE=CryptoSwift CS200
+
+pci:v000012DF*
+ ID_VENDOR_FROM_DATABASE=SBS Technologies Inc
+
+pci:v000012E0*
+ ID_VENDOR_FROM_DATABASE=Chase Research
+
+pci:v000012E0d00000010*
+ ID_PRODUCT_FROM_DATABASE=ST16C654 Quad UART
+
+pci:v000012E0d00000020*
+ ID_PRODUCT_FROM_DATABASE=ST16C654 Quad UART
+
+pci:v000012E0d00000030*
+ ID_PRODUCT_FROM_DATABASE=ST16C654 Quad UART
+
+pci:v000012E1*
+ ID_VENDOR_FROM_DATABASE=Nintendo Co, Ltd
+
+pci:v000012E2*
+ ID_VENDOR_FROM_DATABASE=Datum Inc. Bancomm-Timing Division
+
+pci:v000012E3*
+ ID_VENDOR_FROM_DATABASE=Imation Corp - Medical Imaging Systems
+
+pci:v000012E4*
+ ID_VENDOR_FROM_DATABASE=Brooktrout Technology Inc
+
+pci:v000012E5*
+ ID_VENDOR_FROM_DATABASE=Apex Semiconductor Inc
+
+pci:v000012E6*
+ ID_VENDOR_FROM_DATABASE=Cirel Systems
+
+pci:v000012E7*
+ ID_VENDOR_FROM_DATABASE=Sunsgroup Corporation
+
+pci:v000012E8*
+ ID_VENDOR_FROM_DATABASE=Crisc Corp
+
+pci:v000012E9*
+ ID_VENDOR_FROM_DATABASE=GE Spacenet
+
+pci:v000012EA*
+ ID_VENDOR_FROM_DATABASE=Zuken
+
+pci:v000012EB*
+ ID_VENDOR_FROM_DATABASE=Aureal Semiconductor
+
+pci:v000012EBd00000001*
+ ID_PRODUCT_FROM_DATABASE=Vortex 1
+
+pci:v000012EBd00000001sv0000104Dsd00008036*
+ ID_PRODUCT_FROM_DATABASE=AU8820 Vortex Digital Audio Processor
+
+pci:v000012EBd00000001sv00001092sd00002000*
+ ID_PRODUCT_FROM_DATABASE=Sonic Impact A3D
+
+pci:v000012EBd00000001sv00001092sd00002100*
+ ID_PRODUCT_FROM_DATABASE=Sonic Impact A3D
+
+pci:v000012EBd00000001sv00001092sd00002110*
+ ID_PRODUCT_FROM_DATABASE=Sonic Impact A3D
+
+pci:v000012EBd00000001sv00001092sd00002200*
+ ID_PRODUCT_FROM_DATABASE=Sonic Impact A3D
+
+pci:v000012EBd00000001sv0000122Dsd00001002*
+ ID_PRODUCT_FROM_DATABASE=AU8820 Vortex Digital Audio Processor
+
+pci:v000012EBd00000001sv000012EBsd00000001*
+ ID_PRODUCT_FROM_DATABASE=AU8820 Vortex Digital Audio Processor
+
+pci:v000012EBd00000001sv00005053sd00003355*
+ ID_PRODUCT_FROM_DATABASE=Montego
+
+pci:v000012EBd00000002*
+ ID_PRODUCT_FROM_DATABASE=Vortex 2
+
+pci:v000012EBd00000002sv0000104Dsd00008049*
+ ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+
+pci:v000012EBd00000002sv0000104Dsd0000807B*
+ ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+
+pci:v000012EBd00000002sv00001092sd00003000*
+ ID_PRODUCT_FROM_DATABASE=Monster Sound II
+
+pci:v000012EBd00000002sv00001092sd00003001*
+ ID_PRODUCT_FROM_DATABASE=Monster Sound II
+
+pci:v000012EBd00000002sv00001092sd00003002*
+ ID_PRODUCT_FROM_DATABASE=Monster Sound II
+
+pci:v000012EBd00000002sv00001092sd00003003*
+ ID_PRODUCT_FROM_DATABASE=Monster Sound II
+
+pci:v000012EBd00000002sv00001092sd00003004*
+ ID_PRODUCT_FROM_DATABASE=Monster Sound II
+
+pci:v000012EBd00000002sv000012EBsd00000002*
+ ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+
+pci:v000012EBd00000002sv000012EBsd00000088*
+ ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+
+pci:v000012EBd00000002sv0000144Dsd00003510*
+ ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+
+pci:v000012EBd00000002sv00005053sd00003356*
+ ID_PRODUCT_FROM_DATABASE=Montego II
+
+pci:v000012EBd00000003*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv0000104Dsd00008049*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv0000104Dsd00008077*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv0000109Fsd00001000*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv000012EBsd00000003*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv00001462sd00006780*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv000014A4sd00002073*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv000014A4sd00002091*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv000014A4sd00002104*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00000003sv000014A4sd00002106*
+ ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
+
+pci:v000012EBd00008803*
+ ID_PRODUCT_FROM_DATABASE=Vortex 56k Software Modem
+
+pci:v000012EBd00008803sv000012EBsd00008803*
+ ID_PRODUCT_FROM_DATABASE=Vortex 56k Software Modem
+
+pci:v000012EC*
+ ID_VENDOR_FROM_DATABASE=3A International, Inc.
+
+pci:v000012ED*
+ ID_VENDOR_FROM_DATABASE=Optivision Inc.
+
+pci:v000012EE*
+ ID_VENDOR_FROM_DATABASE=Orange Micro
+
+pci:v000012EF*
+ ID_VENDOR_FROM_DATABASE=Vienna Systems
+
+pci:v000012F0*
+ ID_VENDOR_FROM_DATABASE=Pentek
+
+pci:v000012F1*
+ ID_VENDOR_FROM_DATABASE=Sorenson Vision Inc
+
+pci:v000012F2*
+ ID_VENDOR_FROM_DATABASE=Gammagraphx, Inc.
+
+pci:v000012F3*
+ ID_VENDOR_FROM_DATABASE=Radstone Technology
+
+pci:v000012F4*
+ ID_VENDOR_FROM_DATABASE=Megatel
+
+pci:v000012F5*
+ ID_VENDOR_FROM_DATABASE=Forks
+
+pci:v000012F6*
+ ID_VENDOR_FROM_DATABASE=Dawson France
+
+pci:v000012F7*
+ ID_VENDOR_FROM_DATABASE=Cognex
+
+pci:v000012F8*
+ ID_VENDOR_FROM_DATABASE=Electronic Design GmbH
+
+pci:v000012F8d00000002*
+ ID_PRODUCT_FROM_DATABASE=VideoMaker
+
+pci:v000012F9*
+ ID_VENDOR_FROM_DATABASE=Four Fold Ltd
+
+pci:v000012FB*
+ ID_VENDOR_FROM_DATABASE=Spectrum Signal Processing
+
+pci:v000012FBd00000001*
+ ID_PRODUCT_FROM_DATABASE=PMC-MAI
+
+pci:v000012FBd000000F5*
+ ID_PRODUCT_FROM_DATABASE=F5 Dakar
+
+pci:v000012FBd000002AD*
+ ID_PRODUCT_FROM_DATABASE=PMC-2MAI
+
+pci:v000012FBd00002ADC*
+ ID_PRODUCT_FROM_DATABASE=ePMC-2ADC
+
+pci:v000012FBd00003100*
+ ID_PRODUCT_FROM_DATABASE=PRO-3100
+
+pci:v000012FBd00003500*
+ ID_PRODUCT_FROM_DATABASE=PRO-3500
+
+pci:v000012FBd00004D4F*
+ ID_PRODUCT_FROM_DATABASE=Modena
+
+pci:v000012FBd00008120*
+ ID_PRODUCT_FROM_DATABASE=ePMC-8120
+
+pci:v000012FBd0000DA62*
+ ID_PRODUCT_FROM_DATABASE=Daytona C6201 PCI (Hurricane)
+
+pci:v000012FBd0000DB62*
+ ID_PRODUCT_FROM_DATABASE=Ingliston XBIF
+
+pci:v000012FBd0000DC62*
+ ID_PRODUCT_FROM_DATABASE=Ingliston PLX9054
+
+pci:v000012FBd0000DD62*
+ ID_PRODUCT_FROM_DATABASE=Ingliston JTAG/ISP
+
+pci:v000012FBd0000EDDC*
+ ID_PRODUCT_FROM_DATABASE=ePMC-MSDDC
+
+pci:v000012FBd0000FA01*
+ ID_PRODUCT_FROM_DATABASE=ePMC-FPGA
+
+pci:v000012FC*
+ ID_VENDOR_FROM_DATABASE=Capital Equipment Corp
+
+pci:v000012FD*
+ ID_VENDOR_FROM_DATABASE=I2S
+
+pci:v000012FE*
+ ID_VENDOR_FROM_DATABASE=ESD Electronic System Design GmbH
+
+pci:v000012FF*
+ ID_VENDOR_FROM_DATABASE=Lexicon
+
+pci:v00001300*
+ ID_VENDOR_FROM_DATABASE=Harman International Industries Inc
+
+pci:v00001302*
+ ID_VENDOR_FROM_DATABASE=Computer Sciences Corp
+
+pci:v00001303*
+ ID_VENDOR_FROM_DATABASE=Innovative Integration
+
+pci:v00001303d00000030*
+ ID_PRODUCT_FROM_DATABASE=X3-SDF 4-channel XMC acquisition board
+
+pci:v00001304*
+ ID_VENDOR_FROM_DATABASE=Juniper Networks
+
+pci:v00001305*
+ ID_VENDOR_FROM_DATABASE=Netphone, Inc
+
+pci:v00001306*
+ ID_VENDOR_FROM_DATABASE=Duet Technologies
+
+pci:v00001307*
+ ID_VENDOR_FROM_DATABASE=Measurement Computing
+
+pci:v00001307d00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS1602/16
+
+pci:v00001307d0000000B*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO48H
+
+pci:v00001307d0000000C*
+ ID_PRODUCT_FROM_DATABASE=PCI-PDISO8
+
+pci:v00001307d0000000D*
+ ID_PRODUCT_FROM_DATABASE=PCI-PDISO16
+
+pci:v00001307d0000000F*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS1200
+
+pci:v00001307d00000010*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS1602/12
+
+pci:v00001307d00000014*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO24H
+
+pci:v00001307d00000015*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO24H/CTR3
+
+pci:v00001307d00000016*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO48H/CTR15
+
+pci:v00001307d00000017*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO96H
+
+pci:v00001307d00000018*
+ ID_PRODUCT_FROM_DATABASE=PCI-CTR05
+
+pci:v00001307d00000019*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS1200/JR
+
+pci:v00001307d0000001A*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS1001
+
+pci:v00001307d0000001B*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS1002
+
+pci:v00001307d0000001C*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS1602JR/16
+
+pci:v00001307d0000001D*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6402/16
+
+pci:v00001307d0000001E*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6402/12
+
+pci:v00001307d0000001F*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS16/M1
+
+pci:v00001307d00000020*
+ ID_PRODUCT_FROM_DATABASE=PCI-DDA02/12
+
+pci:v00001307d00000021*
+ ID_PRODUCT_FROM_DATABASE=PCI-DDA04/12
+
+pci:v00001307d00000022*
+ ID_PRODUCT_FROM_DATABASE=PCI-DDA08/12
+
+pci:v00001307d00000023*
+ ID_PRODUCT_FROM_DATABASE=PCI-DDA02/16
+
+pci:v00001307d00000024*
+ ID_PRODUCT_FROM_DATABASE=PCI-DDA04/16
+
+pci:v00001307d00000025*
+ ID_PRODUCT_FROM_DATABASE=PCI-DDA08/16
+
+pci:v00001307d00000026*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAC04/12-HS
+
+pci:v00001307d00000027*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAC04/16-HS
+
+pci:v00001307d00000028*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO24
+
+pci:v00001307d00000029*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS08
+
+pci:v00001307d0000002C*
+ ID_PRODUCT_FROM_DATABASE=PCI-INT32
+
+pci:v00001307d00000033*
+ ID_PRODUCT_FROM_DATABASE=PCI-DUAL-AC5
+
+pci:v00001307d00000034*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS-TC
+
+pci:v00001307d00000035*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS64/M1/16
+
+pci:v00001307d00000036*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS64/M2/16
+
+pci:v00001307d00000037*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS64/M3/16
+
+pci:v00001307d0000004C*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS1000
+
+pci:v00001307d0000004D*
+ ID_PRODUCT_FROM_DATABASE=PCI-QUAD04
+
+pci:v00001307d00000052*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS4020/12
+
+pci:v00001307d00000053*
+ ID_PRODUCT_FROM_DATABASE=PCIM-DDA06/16
+
+pci:v00001307d00000054*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO96
+
+pci:v00001307d0000005D*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6023
+
+pci:v00001307d0000005E*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6025
+
+pci:v00001307d0000005F*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6030
+
+pci:v00001307d00000060*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6031
+
+pci:v00001307d00000061*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6032
+
+pci:v00001307d00000062*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6033
+
+pci:v00001307d00000063*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6034
+
+pci:v00001307d00000064*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6035
+
+pci:v00001307d00000065*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6040
+
+pci:v00001307d00000066*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6052
+
+pci:v00001307d00000067*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6070
+
+pci:v00001307d00000068*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6071
+
+pci:v00001307d0000006F*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6036
+
+pci:v00001307d00000070*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAC6702
+
+pci:v00001307d00000078*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6013
+
+pci:v00001307d00000079*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAS6014
+
+pci:v00001307d00000115*
+ ID_PRODUCT_FROM_DATABASE=PCIe-DAS1602/16
+
+pci:v00001308*
+ ID_VENDOR_FROM_DATABASE=Jato Technologies Inc.
+
+pci:v00001308d00000001*
+ ID_PRODUCT_FROM_DATABASE=NetCelerator Adapter
+
+pci:v00001308d00000001sv00001308sd00000001*
+ ID_PRODUCT_FROM_DATABASE=NetCelerator Adapter
+
+pci:v00001309*
+ ID_VENDOR_FROM_DATABASE=AB Semiconductor Ltd
+
+pci:v0000130A*
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Microcomputer
+
+pci:v0000130B*
+ ID_VENDOR_FROM_DATABASE=Colorgraphic Communications Corp
+
+pci:v0000130C*
+ ID_VENDOR_FROM_DATABASE=Ambex Technologies, Inc
+
+pci:v0000130D*
+ ID_VENDOR_FROM_DATABASE=Accelerix Inc
+
+pci:v0000130E*
+ ID_VENDOR_FROM_DATABASE=Yamatake-Honeywell Co. Ltd
+
+pci:v0000130F*
+ ID_VENDOR_FROM_DATABASE=Advanet Inc
+
+pci:v00001310*
+ ID_VENDOR_FROM_DATABASE=Gespac
+
+pci:v00001311*
+ ID_VENDOR_FROM_DATABASE=Videoserver, Inc
+
+pci:v00001312*
+ ID_VENDOR_FROM_DATABASE=Acuity Imaging, Inc
+
+pci:v00001313*
+ ID_VENDOR_FROM_DATABASE=Yaskawa Electric Co.
+
+pci:v00001315*
+ ID_VENDOR_FROM_DATABASE=Wavesat
+
+pci:v00001316*
+ ID_VENDOR_FROM_DATABASE=Teradyne Inc
+
+pci:v00001317*
+ ID_VENDOR_FROM_DATABASE=ADMtek
+
+pci:v00001317d00000981*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v00001317d00000985*
+ ID_PRODUCT_FROM_DATABASE=NC100 Network Everywhere Fast Ethernet 10/100
+
+pci:v00001317d00000985sv00001734sd0000100C*
+ ID_PRODUCT_FROM_DATABASE=Scenic N300 ADMtek AN983 10/100 Mbps PCI Adapter
+
+pci:v00001317d00001985*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v00001317d00001985sv00001385sd0000511A*
+ ID_PRODUCT_FROM_DATABASE=FA511
+
+pci:v00001317d00001985sv00001395sd00002103*
+ ID_PRODUCT_FROM_DATABASE=CB100-EZ (4-LED version)
+
+pci:v00001317d00002850*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v00001317d00005120*
+ ID_PRODUCT_FROM_DATABASE=ADM5120 OpenGate System-on-Chip
+
+pci:v00001317d00008201*
+ ID_PRODUCT_FROM_DATABASE=ADM8211 802.11b Wireless Interface
+
+pci:v00001317d00008201sv000010B8sd00002635*
+ ID_PRODUCT_FROM_DATABASE=SMC2635W v1 802.11b Wireless Cardbus Adapter
+
+pci:v00001317d00008201sv00001317sd00008201*
+ ID_PRODUCT_FROM_DATABASE=SMC2635W v2 802.11b Wireless Cardbus Adapter
+
+pci:v00001317d00008211*
+ ID_PRODUCT_FROM_DATABASE=ADM8211 802.11b Wireless Interface
+
+pci:v00001317d00009511*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v00001318*
+ ID_VENDOR_FROM_DATABASE=Packet Engines Inc.
+
+pci:v00001318d00000911*
+ ID_PRODUCT_FROM_DATABASE=GNIC-II PCI Gigabit Ethernet [Hamachi]
+
+pci:v00001319*
+ ID_VENDOR_FROM_DATABASE=Fortemedia, Inc
+
+pci:v00001319d00000801*
+ ID_PRODUCT_FROM_DATABASE=Xwave QS3000A [FM801]
+
+pci:v00001319d00000801sv00001319sd00001319*
+ ID_PRODUCT_FROM_DATABASE=FM801 PCI Audio
+
+pci:v00001319d00000802*
+ ID_PRODUCT_FROM_DATABASE=Xwave QS3000A [FM801 game port]
+
+pci:v00001319d00000802sv00001319sd00001319*
+ ID_PRODUCT_FROM_DATABASE=FM801 PCI Joystick
+
+pci:v00001319d00001000*
+ ID_PRODUCT_FROM_DATABASE=FM801 PCI Audio
+
+pci:v00001319d00001001*
+ ID_PRODUCT_FROM_DATABASE=FM801 PCI Joystick
+
+pci:v0000131A*
+ ID_VENDOR_FROM_DATABASE=Finisar Corp.
+
+pci:v0000131C*
+ ID_VENDOR_FROM_DATABASE=Nippon Electro-Sensory Devices Corp
+
+pci:v0000131D*
+ ID_VENDOR_FROM_DATABASE=Sysmic, Inc.
+
+pci:v0000131E*
+ ID_VENDOR_FROM_DATABASE=Xinex Networks Inc
+
+pci:v0000131F*
+ ID_VENDOR_FROM_DATABASE=Siig Inc
+
+pci:v0000131Fd00001000*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16550
+
+pci:v0000131Fd00001001*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16650
+
+pci:v0000131Fd00001002*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16850
+
+pci:v0000131Fd00001010*
+ ID_PRODUCT_FROM_DATABASE=Duet 1S(16550)+1P
+
+pci:v0000131Fd00001011*
+ ID_PRODUCT_FROM_DATABASE=Duet 1S(16650)+1P
+
+pci:v0000131Fd00001012*
+ ID_PRODUCT_FROM_DATABASE=Duet 1S(16850)+1P
+
+pci:v0000131Fd00001020*
+ ID_PRODUCT_FROM_DATABASE=CyberParallel (1-port)
+
+pci:v0000131Fd00001021*
+ ID_PRODUCT_FROM_DATABASE=CyberParallel (2-port)
+
+pci:v0000131Fd00001030*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16550
+
+pci:v0000131Fd00001031*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16650
+
+pci:v0000131Fd00001032*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16850
+
+pci:v0000131Fd00001034*
+ ID_PRODUCT_FROM_DATABASE=Trio 2S(16550)+1P
+
+pci:v0000131Fd00001035*
+ ID_PRODUCT_FROM_DATABASE=Trio 2S(16650)+1P
+
+pci:v0000131Fd00001036*
+ ID_PRODUCT_FROM_DATABASE=Trio 2S(16850)+1P
+
+pci:v0000131Fd00001050*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16550
+
+pci:v0000131Fd00001051*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16650
+
+pci:v0000131Fd00001052*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16850
+
+pci:v0000131Fd00002000*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16550
+
+pci:v0000131Fd00002001*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16650
+
+pci:v0000131Fd00002002*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16850
+
+pci:v0000131Fd00002010*
+ ID_PRODUCT_FROM_DATABASE=Duet 1S(16550)+1P
+
+pci:v0000131Fd00002011*
+ ID_PRODUCT_FROM_DATABASE=Duet 1S(16650)+1P
+
+pci:v0000131Fd00002012*
+ ID_PRODUCT_FROM_DATABASE=Duet 1S(16850)+1P
+
+pci:v0000131Fd00002020*
+ ID_PRODUCT_FROM_DATABASE=CyberParallel (1-port)
+
+pci:v0000131Fd00002021*
+ ID_PRODUCT_FROM_DATABASE=CyberParallel (2-port)
+
+pci:v0000131Fd00002030*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16550
+
+pci:v0000131Fd00002030sv0000131Fsd00002030*
+ ID_PRODUCT_FROM_DATABASE=PCI Serial Card
+
+pci:v0000131Fd00002031*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16650
+
+pci:v0000131Fd00002032*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16850
+
+pci:v0000131Fd00002040*
+ ID_PRODUCT_FROM_DATABASE=Trio 1S(16550)+2P
+
+pci:v0000131Fd00002041*
+ ID_PRODUCT_FROM_DATABASE=Trio 1S(16650)+2P
+
+pci:v0000131Fd00002042*
+ ID_PRODUCT_FROM_DATABASE=Trio 1S(16850)+2P
+
+pci:v0000131Fd00002050*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16550
+
+pci:v0000131Fd00002051*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16650
+
+pci:v0000131Fd00002052*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16850
+
+pci:v0000131Fd00002060*
+ ID_PRODUCT_FROM_DATABASE=Trio 2S(16550)+1P
+
+pci:v0000131Fd00002061*
+ ID_PRODUCT_FROM_DATABASE=Trio 2S(16650)+1P
+
+pci:v0000131Fd00002062*
+ ID_PRODUCT_FROM_DATABASE=Trio 2S(16850)+1P
+
+pci:v0000131Fd00002081*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial (8-port) ST16654
+
+pci:v00001320*
+ ID_VENDOR_FROM_DATABASE=Crypto AG
+
+pci:v00001321*
+ ID_VENDOR_FROM_DATABASE=Arcobel Graphics BV
+
+pci:v00001322*
+ ID_VENDOR_FROM_DATABASE=MTT Co., Ltd
+
+pci:v00001323*
+ ID_VENDOR_FROM_DATABASE=Dome Inc
+
+pci:v00001324*
+ ID_VENDOR_FROM_DATABASE=Sphere Communications
+
+pci:v00001325*
+ ID_VENDOR_FROM_DATABASE=Salix Technologies, Inc
+
+pci:v00001326*
+ ID_VENDOR_FROM_DATABASE=Seachange international
+
+pci:v00001327*
+ ID_VENDOR_FROM_DATABASE=Voss scientific
+
+pci:v00001328*
+ ID_VENDOR_FROM_DATABASE=quadrant international
+
+pci:v00001329*
+ ID_VENDOR_FROM_DATABASE=Productivity Enhancement
+
+pci:v0000132A*
+ ID_VENDOR_FROM_DATABASE=Microcom Inc.
+
+pci:v0000132B*
+ ID_VENDOR_FROM_DATABASE=Broadband Technologies
+
+pci:v0000132C*
+ ID_VENDOR_FROM_DATABASE=Micrel Inc
+
+pci:v0000132D*
+ ID_VENDOR_FROM_DATABASE=Integrated Silicon Solution, Inc.
+
+pci:v00001330*
+ ID_VENDOR_FROM_DATABASE=MMC Networks
+
+pci:v00001331*
+ ID_VENDOR_FROM_DATABASE=RadiSys Corporation
+
+pci:v00001331d00000030*
+ ID_PRODUCT_FROM_DATABASE=ENP-2611
+
+pci:v00001331d00008200*
+ ID_PRODUCT_FROM_DATABASE=82600 Host Bridge
+
+pci:v00001331d00008201*
+ ID_PRODUCT_FROM_DATABASE=82600 IDE
+
+pci:v00001331d00008202*
+ ID_PRODUCT_FROM_DATABASE=82600 USB
+
+pci:v00001331d00008210*
+ ID_PRODUCT_FROM_DATABASE=82600 PCI Bridge
+
+pci:v00001332*
+ ID_VENDOR_FROM_DATABASE=Micro Memory
+
+pci:v00001332d00005415*
+ ID_PRODUCT_FROM_DATABASE=MM-5415CN PCI Memory Module with Battery Backup
+
+pci:v00001332d00005425*
+ ID_PRODUCT_FROM_DATABASE=MM-5425CN PCI 64/66 Memory Module with Battery Backup
+
+pci:v00001332d00006140*
+ ID_PRODUCT_FROM_DATABASE=MM-6140D
+
+pci:v00001334*
+ ID_VENDOR_FROM_DATABASE=Redcreek Communications, Inc
+
+pci:v00001335*
+ ID_VENDOR_FROM_DATABASE=Videomail, Inc
+
+pci:v00001337*
+ ID_VENDOR_FROM_DATABASE=Third Planet Publishing
+
+pci:v00001338*
+ ID_VENDOR_FROM_DATABASE=BT Electronics
+
+pci:v0000133A*
+ ID_VENDOR_FROM_DATABASE=Vtel Corp
+
+pci:v0000133B*
+ ID_VENDOR_FROM_DATABASE=Softcom Microsystems
+
+pci:v0000133C*
+ ID_VENDOR_FROM_DATABASE=Holontech Corp
+
+pci:v0000133D*
+ ID_VENDOR_FROM_DATABASE=SS Technologies
+
+pci:v0000133E*
+ ID_VENDOR_FROM_DATABASE=Virtual Computer Corp
+
+pci:v0000133F*
+ ID_VENDOR_FROM_DATABASE=SCM Microsystems
+
+pci:v00001340*
+ ID_VENDOR_FROM_DATABASE=Atalla Corp
+
+pci:v00001341*
+ ID_VENDOR_FROM_DATABASE=Kyoto Microcomputer Co
+
+pci:v00001342*
+ ID_VENDOR_FROM_DATABASE=Promax Systems Inc
+
+pci:v00001343*
+ ID_VENDOR_FROM_DATABASE=Phylon Communications Inc
+
+pci:v00001344*
+ ID_VENDOR_FROM_DATABASE=Micron Technology Inc
+
+pci:v00001344d00005150*
+ ID_PRODUCT_FROM_DATABASE=RealSSD P320h
+
+pci:v00001344d00005151*
+ ID_PRODUCT_FROM_DATABASE=RealSSD P320m
+
+pci:v00001344d00005152*
+ ID_PRODUCT_FROM_DATABASE=RealSSD P320s
+
+pci:v00001344d00005153*
+ ID_PRODUCT_FROM_DATABASE=RealSSD P325m
+
+pci:v00001344d00005160*
+ ID_PRODUCT_FROM_DATABASE=RealSSD P420h
+
+pci:v00001344d00005161*
+ ID_PRODUCT_FROM_DATABASE=RealSSD P420m
+
+pci:v00001344d00005163*
+ ID_PRODUCT_FROM_DATABASE=RealSSD P425m
+
+pci:v00001345*
+ ID_VENDOR_FROM_DATABASE=Arescom Inc
+
+pci:v00001347*
+ ID_VENDOR_FROM_DATABASE=Odetics
+
+pci:v00001349*
+ ID_VENDOR_FROM_DATABASE=Sumitomo Electric Industries, Ltd.
+
+pci:v0000134A*
+ ID_VENDOR_FROM_DATABASE=DTC Technology Corp.
+
+pci:v0000134Ad00000001*
+ ID_PRODUCT_FROM_DATABASE=Domex 536
+
+pci:v0000134Ad00000002*
+ ID_PRODUCT_FROM_DATABASE=Domex DMX3194UP SCSI Adapter
+
+pci:v0000134B*
+ ID_VENDOR_FROM_DATABASE=ARK Research Corp.
+
+pci:v0000134C*
+ ID_VENDOR_FROM_DATABASE=Chori Joho System Co. Ltd
+
+pci:v0000134D*
+ ID_VENDOR_FROM_DATABASE=PCTel Inc
+
+pci:v0000134Dd00002189*
+ ID_PRODUCT_FROM_DATABASE=HSP56 MicroModem
+
+pci:v0000134Dd00002486*
+ ID_PRODUCT_FROM_DATABASE=2304WT V.92 MDC Modem
+
+pci:v0000134Dd00007890*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134Dd00007890sv0000134Dsd00000001*
+ ID_PRODUCT_FROM_DATABASE=PCT789 adapter
+
+pci:v0000134Dd00007891*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134Dd00007891sv0000134Dsd00000001*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134Dd00007892*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134Dd00007893*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134Dd00007894*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134Dd00007895*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134Dd00007896*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134Dd00007897*
+ ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56
+
+pci:v0000134E*
+ ID_VENDOR_FROM_DATABASE=CSTI
+
+pci:v0000134F*
+ ID_VENDOR_FROM_DATABASE=Algo System Co Ltd
+
+pci:v00001350*
+ ID_VENDOR_FROM_DATABASE=Systec Co. Ltd
+
+pci:v00001351*
+ ID_VENDOR_FROM_DATABASE=Sonix Inc
+
+pci:v00001353*
+ ID_VENDOR_FROM_DATABASE=Vierling Communication SAS
+
+pci:v00001353d00000002*
+ ID_PRODUCT_FROM_DATABASE=Proserver
+
+pci:v00001353d00000003*
+ ID_PRODUCT_FROM_DATABASE=PCI-FUT
+
+pci:v00001353d00000004*
+ ID_PRODUCT_FROM_DATABASE=PCI-S0
+
+pci:v00001353d00000005*
+ ID_PRODUCT_FROM_DATABASE=PCI-FUT-S0
+
+pci:v00001354*
+ ID_VENDOR_FROM_DATABASE=Dwave System Inc
+
+pci:v00001355*
+ ID_VENDOR_FROM_DATABASE=Kratos Analytical Ltd
+
+pci:v00001356*
+ ID_VENDOR_FROM_DATABASE=The Logical Co
+
+pci:v00001359*
+ ID_VENDOR_FROM_DATABASE=Prisa Networks
+
+pci:v0000135A*
+ ID_VENDOR_FROM_DATABASE=Brain Boxes
+
+pci:v0000135Ad00000A61*
+ ID_PRODUCT_FROM_DATABASE=UC-324 [VELOCITY RS422/485]
+
+pci:v0000135B*
+ ID_VENDOR_FROM_DATABASE=Giganet Inc
+
+pci:v0000135C*
+ ID_VENDOR_FROM_DATABASE=Quatech Inc
+
+pci:v0000135Cd00000010*
+ ID_PRODUCT_FROM_DATABASE=QSC-100
+
+pci:v0000135Cd00000020*
+ ID_PRODUCT_FROM_DATABASE=DSC-100
+
+pci:v0000135Cd00000030*
+ ID_PRODUCT_FROM_DATABASE=DSC-200/300
+
+pci:v0000135Cd00000040*
+ ID_PRODUCT_FROM_DATABASE=QSC-200/300
+
+pci:v0000135Cd00000050*
+ ID_PRODUCT_FROM_DATABASE=ESC-100D
+
+pci:v0000135Cd00000060*
+ ID_PRODUCT_FROM_DATABASE=ESC-100M
+
+pci:v0000135Cd000000F0*
+ ID_PRODUCT_FROM_DATABASE=MPAC-100 Syncronous Serial Card (Zilog 85230)
+
+pci:v0000135Cd00000170*
+ ID_PRODUCT_FROM_DATABASE=QSCLP-100
+
+pci:v0000135Cd00000180*
+ ID_PRODUCT_FROM_DATABASE=DSCLP-100
+
+pci:v0000135Cd00000190*
+ ID_PRODUCT_FROM_DATABASE=SSCLP-100
+
+pci:v0000135Cd000001A0*
+ ID_PRODUCT_FROM_DATABASE=QSCLP-200/300
+
+pci:v0000135Cd000001B0*
+ ID_PRODUCT_FROM_DATABASE=DSCLP-200/300
+
+pci:v0000135Cd000001C0*
+ ID_PRODUCT_FROM_DATABASE=SSCLP-200/300
+
+pci:v0000135Cd00000258*
+ ID_PRODUCT_FROM_DATABASE=DSPSX-200/300
+
+pci:v0000135D*
+ ID_VENDOR_FROM_DATABASE=ABB Network Partner AB
+
+pci:v0000135E*
+ ID_VENDOR_FROM_DATABASE=Sealevel Systems Inc
+
+pci:v0000135Ed00005101*
+ ID_PRODUCT_FROM_DATABASE=Route 56.PCI - Multi-Protocol Serial Interface (Zilog Z16C32)
+
+pci:v0000135Ed00007101*
+ ID_PRODUCT_FROM_DATABASE=Single Port RS-232/422/485/530
+
+pci:v0000135Ed00007201*
+ ID_PRODUCT_FROM_DATABASE=Dual Port RS-232/422/485 Interface
+
+pci:v0000135Ed00007202*
+ ID_PRODUCT_FROM_DATABASE=Dual Port RS-232 Interface
+
+pci:v0000135Ed00007401*
+ ID_PRODUCT_FROM_DATABASE=Four Port RS-232 Interface
+
+pci:v0000135Ed00007402*
+ ID_PRODUCT_FROM_DATABASE=Four Port RS-422/485 Interface
+
+pci:v0000135Ed00007801*
+ ID_PRODUCT_FROM_DATABASE=Eight Port RS-232 Interface
+
+pci:v0000135Ed00007804*
+ ID_PRODUCT_FROM_DATABASE=Eight Port RS-232/422/485 Interface
+
+pci:v0000135Ed00008001*
+ ID_PRODUCT_FROM_DATABASE=8001 Digital I/O Adapter
+
+pci:v0000135F*
+ ID_VENDOR_FROM_DATABASE=I-Data International A-S
+
+pci:v00001360*
+ ID_VENDOR_FROM_DATABASE=Meinberg Funkuhren
+
+pci:v00001360d00000101*
+ ID_PRODUCT_FROM_DATABASE=PCI32 DCF77 Radio Clock
+
+pci:v00001360d00000102*
+ ID_PRODUCT_FROM_DATABASE=PCI509 DCF77 Radio Clock
+
+pci:v00001360d00000103*
+ ID_PRODUCT_FROM_DATABASE=PCI510 DCF77 Radio Clock
+
+pci:v00001360d00000104*
+ ID_PRODUCT_FROM_DATABASE=PCI511 DCF77 Radio Clock
+
+pci:v00001360d00000105*
+ ID_PRODUCT_FROM_DATABASE=PEX511 DCF77 Radio Clock (PCI Express)
+
+pci:v00001360d00000106*
+ ID_PRODUCT_FROM_DATABASE=PZF180PEX High Precision DCF77 Radio Clock (PCI Express)
+
+pci:v00001360d00000201*
+ ID_PRODUCT_FROM_DATABASE=GPS167PCI GPS Receiver
+
+pci:v00001360d00000202*
+ ID_PRODUCT_FROM_DATABASE=GPS168PCI GPS Receiver
+
+pci:v00001360d00000203*
+ ID_PRODUCT_FROM_DATABASE=GPS169PCI GPS Receiver
+
+pci:v00001360d00000204*
+ ID_PRODUCT_FROM_DATABASE=GPS170PCI GPS Receiver
+
+pci:v00001360d00000205*
+ ID_PRODUCT_FROM_DATABASE=GPS170PEX GPS Receiver (PCI Express)
+
+pci:v00001360d00000206*
+ ID_PRODUCT_FROM_DATABASE=GPS180PEX GPS Receiver (PCI Express)
+
+pci:v00001360d00000301*
+ ID_PRODUCT_FROM_DATABASE=TCR510PCI IRIG Timecode Reader
+
+pci:v00001360d00000302*
+ ID_PRODUCT_FROM_DATABASE=TCR167PCI IRIG Timecode Reader
+
+pci:v00001360d00000303*
+ ID_PRODUCT_FROM_DATABASE=TCR511PCI IRIG Timecode Reader
+
+pci:v00001360d00000304*
+ ID_PRODUCT_FROM_DATABASE=TCR511PEX IRIG Timecode Reader (PCI Express)
+
+pci:v00001360d00000305*
+ ID_PRODUCT_FROM_DATABASE=TCR170PEX IRIG Timecode Reader (PCI Express)
+
+pci:v00001360d00000306*
+ ID_PRODUCT_FROM_DATABASE=TCR180PEX IRIG Timecode Reader (PCI Express)
+
+pci:v00001360d00000501*
+ ID_PRODUCT_FROM_DATABASE=PTP270PEX PTP/IEEE1588 slave card (PCI Express)
+
+pci:v00001360d00000601*
+ ID_PRODUCT_FROM_DATABASE=FRC511PEX Free Running Clock (PCI Express)
+
+pci:v00001361*
+ ID_VENDOR_FROM_DATABASE=Soliton Systems K.K.
+
+pci:v00001362*
+ ID_VENDOR_FROM_DATABASE=Fujifacom Corporation
+
+pci:v00001363*
+ ID_VENDOR_FROM_DATABASE=Phoenix Technology Ltd
+
+pci:v00001364*
+ ID_VENDOR_FROM_DATABASE=ATM Communications Inc
+
+pci:v00001365*
+ ID_VENDOR_FROM_DATABASE=Hypercope GmbH
+
+pci:v00001366*
+ ID_VENDOR_FROM_DATABASE=Teijin Seiki Co. Ltd
+
+pci:v00001367*
+ ID_VENDOR_FROM_DATABASE=Hitachi Zosen Corporation
+
+pci:v00001368*
+ ID_VENDOR_FROM_DATABASE=Skyware Corporation
+
+pci:v00001369*
+ ID_VENDOR_FROM_DATABASE=Digigram
+
+pci:v0000136A*
+ ID_VENDOR_FROM_DATABASE=High Soft Tech
+
+pci:v0000136Ad00000004*
+ ID_PRODUCT_FROM_DATABASE=HST Saphir VII mini PCI
+
+pci:v0000136Ad00000007*
+ ID_PRODUCT_FROM_DATABASE=HST Saphir III E MultiLink 4
+
+pci:v0000136Ad00000008*
+ ID_PRODUCT_FROM_DATABASE=HST Saphir III E MultiLink 8
+
+pci:v0000136Ad0000000A*
+ ID_PRODUCT_FROM_DATABASE=HST Saphir III E MultiLink 2
+
+pci:v0000136B*
+ ID_VENDOR_FROM_DATABASE=Kawasaki Steel Corporation
+
+pci:v0000136Bd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=KL5A72002 Motion JPEG
+
+pci:v0000136C*
+ ID_VENDOR_FROM_DATABASE=Adtek System Science Co Ltd
+
+pci:v0000136D*
+ ID_VENDOR_FROM_DATABASE=Gigalabs Inc
+
+pci:v0000136F*
+ ID_VENDOR_FROM_DATABASE=Applied Magic Inc
+
+pci:v00001370*
+ ID_VENDOR_FROM_DATABASE=ATL Products
+
+pci:v00001371*
+ ID_VENDOR_FROM_DATABASE=CNet Technology Inc
+
+pci:v00001371d0000434E*
+ ID_PRODUCT_FROM_DATABASE=GigaCard Network Adapter
+
+pci:v00001371d0000434Esv00001371sd0000434E*
+ ID_PRODUCT_FROM_DATABASE=N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
+
+pci:v00001373*
+ ID_VENDOR_FROM_DATABASE=Silicon Vision Inc
+
+pci:v00001374*
+ ID_VENDOR_FROM_DATABASE=Silicom Ltd.
+
+pci:v00001374d00000024*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Giga Ethernet BGE Bypass Server Adapter
+
+pci:v00001374d00000025*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Giga Ethernet BGE Bypass Server Adapter
+
+pci:v00001374d00000026*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Giga Ethernet 546 Bypass Server Adapter
+
+pci:v00001374d00000027*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber LX Giga Ethernet 546 Bypass Server Adapter
+
+pci:v00001374d00000029*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Giga Ethernet 546GB Bypass Server Adapter
+
+pci:v00001374d0000002A*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Giga Ethernet 546 TAP/Bypass Server Adapter
+
+pci:v00001374d0000002B*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Fast Ethernet 546 TAP/Bypass Server Adapter (PXE2TBI)
+
+pci:v00001374d0000002C*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Copper Giga Ethernet 546GB Bypass Server Adapter (PXG4BPI)
+
+pci:v00001374d0000002D*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-SX Giga Ethernet 546GB Bypass Server Adapter (PXG4BPFI)
+
+pci:v00001374d0000002E*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-LX Giga Ethernet 546GB Bypass Server Adapter (PXG4BPFI-LX)
+
+pci:v00001374d0000002F*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-SX Giga Ethernet 546GB Low profile Bypass Server Adapter (PXG2BPFIL)
+
+pci:v00001374d00000030*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-LX Giga Ethernet 546GB Low profile Bypass Server Adapter
+
+pci:v00001374d00000031*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Copper Giga Ethernet PCI-E Bypass Server Adapter
+
+pci:v00001374d00000032*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Fast Ethernet 546 TAP/Bypass Server Adapter
+
+pci:v00001374d00000034*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Giga Ethernet PCI-E BGE Bypass Server Adapter
+
+pci:v00001374d00000035*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Copper Giga Ethernet PCI-E BGE Bypass Server Adapter
+
+pci:v00001374d00000036*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Giga Ethernet PCI-E BGE Bypass Server Adapter
+
+pci:v00001374d00000037*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Ethernet PCI-E Intel based Bypass Server Adapter
+
+pci:v00001374d00000038*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Copper Ethernet PCI-E Intel based Bypass Server Adapter
+
+pci:v00001374d00000039*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-SX Ethernet PCI-E Intel based Bypass Server Adapter
+
+pci:v00001374d0000003A*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-LX Ethernet PCI-E Intel based Bypass Server Adapter
+
+pci:v00001374d0000003B*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Ethernet PMC Intel based Bypass Server Adapter (PMCX2BPFI)
+
+pci:v00001374d0000003C*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Ethernet PCI-X BGE based Bypass Server Adapter (PXG2BPRB)
+
+pci:v00001374d0000003D*
+ ID_PRODUCT_FROM_DATABASE=2-port Copper GBE Bypass with Caviume 1010 PCI-X
+
+pci:v00001374d0000003E*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Giga Ethernet PCI-E 571 TAP/Bypass Server Adapter (PEG2TBFI)
+
+pci:v00001374d0000003F*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Giga Ethernet PCI-X 546 TAP/Bypass Server Adapter (PXG2TBI)
+
+pci:v00001374d00000040*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-SX Giga Ethernet 571 Bypass Server Adapter (PEG4BPFI)
+
+pci:v00001374d00000042*
+ ID_PRODUCT_FROM_DATABASE=4-port Copper GBE PMC-X Bypass
+
+pci:v00001374d00000043*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-SX Giga Ethernet 546 Bypass Server Adapter (PXG4BPFID)
+
+pci:v00001374d00000045*
+ ID_PRODUCT_FROM_DATABASE=Silicom 6 port Copper Giga Ethernet 546 Bypass Server Adapter (PXG6BPI)
+
+pci:v00001374d00000046*
+ ID_PRODUCT_FROM_DATABASE=4-port bypass PCI-E w disconnect low profile
+
+pci:v00001374d00000047*
+ ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-SX Giga Ethernet 571 Bypass Disconnect Server Adapter (PEG2BPFID)
+
+pci:v00001374d0000004A*
+ ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-LX Giga Ethernet 571 Bypass Server Adapter (PEG4BPFI-LX)
+
+pci:v00001374d0000004D*
+ ID_PRODUCT_FROM_DATABASE=Dual port Copper Giga Ethernet PCI-E Bypass Server Adapter
+
+pci:v00001374d00000401*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet ExpressModule Bypass Server Adapter
+
+pci:v00001374d00000420*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet ExpressModule Bypass Server Adapter
+
+pci:v00001374d00000460*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet Express Module Bypass Server Adapter
+
+pci:v00001374d00000461*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet ExpressModule Bypass Server Adapter
+
+pci:v00001374d00000462*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet ExpressModule Bypass Server Adapter
+
+pci:v00001374d00000470*
+ ID_PRODUCT_FROM_DATABASE=Octal-port Copper Gigabit Ethernet Express Module Bypass Server Adapter
+
+pci:v00001374d00000482*
+ ID_PRODUCT_FROM_DATABASE=Dual-port Fiber (SR) 10 Gigabit Ethernet ExpressModule Bypass Server Adapter
+
+pci:v00001374d00000483*
+ ID_PRODUCT_FROM_DATABASE=Dual-port Fiber (LR) 10 Gigabit Ethernet ExpressModule Bypass Server Adapter
+
+pci:v00001375*
+ ID_VENDOR_FROM_DATABASE=Argosystems Inc
+
+pci:v00001376*
+ ID_VENDOR_FROM_DATABASE=LMC
+
+pci:v00001377*
+ ID_VENDOR_FROM_DATABASE=Electronic Equipment Production & Distribution GmbH
+
+pci:v00001378*
+ ID_VENDOR_FROM_DATABASE=Telemann Co. Ltd
+
+pci:v00001379*
+ ID_VENDOR_FROM_DATABASE=Asahi Kasei Microsystems Co Ltd
+
+pci:v0000137A*
+ ID_VENDOR_FROM_DATABASE=Mark of the Unicorn Inc
+
+pci:v0000137Ad00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI-324 Audiowire Interface
+
+pci:v0000137B*
+ ID_VENDOR_FROM_DATABASE=PPT Vision
+
+pci:v0000137C*
+ ID_VENDOR_FROM_DATABASE=Iwatsu Electric Co Ltd
+
+pci:v0000137D*
+ ID_VENDOR_FROM_DATABASE=Dynachip Corporation
+
+pci:v0000137E*
+ ID_VENDOR_FROM_DATABASE=Patriot Scientific Corporation
+
+pci:v0000137F*
+ ID_VENDOR_FROM_DATABASE=Japan Satellite Systems Inc
+
+pci:v00001380*
+ ID_VENDOR_FROM_DATABASE=Sanritz Automation Co Ltd
+
+pci:v00001381*
+ ID_VENDOR_FROM_DATABASE=Brains Co. Ltd
+
+pci:v00001382*
+ ID_VENDOR_FROM_DATABASE=Marian - Electronic & Software
+
+pci:v00001382d00000001*
+ ID_PRODUCT_FROM_DATABASE=ARC88 audio recording card
+
+pci:v00001382d00002008*
+ ID_PRODUCT_FROM_DATABASE=Prodif 96 Pro sound system
+
+pci:v00001382d00002048*
+ ID_PRODUCT_FROM_DATABASE=Prodif Plus sound system
+
+pci:v00001382d00002088*
+ ID_PRODUCT_FROM_DATABASE=Marc 8 Midi sound system
+
+pci:v00001382d000020C8*
+ ID_PRODUCT_FROM_DATABASE=Marc A sound system
+
+pci:v00001382d00004008*
+ ID_PRODUCT_FROM_DATABASE=Marc 2 sound system
+
+pci:v00001382d00004010*
+ ID_PRODUCT_FROM_DATABASE=Marc 2 Pro sound system
+
+pci:v00001382d00004048*
+ ID_PRODUCT_FROM_DATABASE=Marc 4 MIDI sound system
+
+pci:v00001382d00004088*
+ ID_PRODUCT_FROM_DATABASE=Marc 4 Digi sound system
+
+pci:v00001382d00004248*
+ ID_PRODUCT_FROM_DATABASE=Marc X sound system
+
+pci:v00001382d00004424*
+ ID_PRODUCT_FROM_DATABASE=TRACE D4 Sound System
+
+pci:v00001383*
+ ID_VENDOR_FROM_DATABASE=Controlnet Inc
+
+pci:v00001384*
+ ID_VENDOR_FROM_DATABASE=Reality Simulation Systems Inc
+
+pci:v00001385*
+ ID_VENDOR_FROM_DATABASE=Netgear
+
+pci:v00001385d0000006B*
+ ID_PRODUCT_FROM_DATABASE=WA301 802.11b Wireless PCI Adapter
+
+pci:v00001385d00004100*
+ ID_PRODUCT_FROM_DATABASE=MA301 802.11b Wireless PCI Adapter
+
+pci:v00001385d00004105*
+ ID_PRODUCT_FROM_DATABASE=MA311 802.11b Wireless PCI Adapter
+
+pci:v00001385d00004400*
+ ID_PRODUCT_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card
+
+pci:v00001385d00004600*
+ ID_PRODUCT_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card
+
+pci:v00001385d00004601*
+ ID_PRODUCT_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card
+
+pci:v00001385d00004610*
+ ID_PRODUCT_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card
+
+pci:v00001385d00004A00*
+ ID_PRODUCT_FROM_DATABASE=WAG311 802.11a/g Wireless PCI Adapter
+
+pci:v00001385d00005200*
+ ID_PRODUCT_FROM_DATABASE=GA511 Gigabit PC Card
+
+pci:v00001385d0000620A*
+ ID_PRODUCT_FROM_DATABASE=GA620 Gigabit Ethernet
+
+pci:v00001385d0000630A*
+ ID_PRODUCT_FROM_DATABASE=GA630 Gigabit Ethernet
+
+pci:v00001385d00006D00*
+ ID_PRODUCT_FROM_DATABASE=WPNT511 RangeMax 240 Mbps Wireless PC Card
+
+pci:v00001385d00007B00*
+ ID_PRODUCT_FROM_DATABASE=WN511B RangeMax Next 270 Mbps Wireless PC Card
+
+pci:v00001385d00007C00*
+ ID_PRODUCT_FROM_DATABASE=WN511T RangeMax Next 300 Mbps Wireless PC Card
+
+pci:v00001385d0000F004*
+ ID_PRODUCT_FROM_DATABASE=FA310TX
+
+pci:v00001385d0000F312*
+ ID_PRODUCT_FROM_DATABASE=FA312 REV-A1 Fast Ethernet PCI Adapter
+
+pci:v00001386*
+ ID_VENDOR_FROM_DATABASE=Video Domain Technologies
+
+pci:v00001387*
+ ID_VENDOR_FROM_DATABASE=Systran Corp
+
+pci:v00001388*
+ ID_VENDOR_FROM_DATABASE=Hitachi Information Technology Co Ltd
+
+pci:v00001389*
+ ID_VENDOR_FROM_DATABASE=Applicom International
+
+pci:v00001389d00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI1500PFB [Intelligent fieldbus adaptor]
+
+pci:v0000138A*
+ ID_VENDOR_FROM_DATABASE=Fusion Micromedia Corp
+
+pci:v0000138Ad0000003D*
+ ID_PRODUCT_FROM_DATABASE=VFS491 Validity Sensor
+
+pci:v0000138B*
+ ID_VENDOR_FROM_DATABASE=Tokimec Inc
+
+pci:v0000138C*
+ ID_VENDOR_FROM_DATABASE=Silicon Reality
+
+pci:v0000138D*
+ ID_VENDOR_FROM_DATABASE=Future Techno Designs pte Ltd
+
+pci:v0000138E*
+ ID_VENDOR_FROM_DATABASE=Basler GmbH
+
+pci:v0000138F*
+ ID_VENDOR_FROM_DATABASE=Patapsco Designs Inc
+
+pci:v00001390*
+ ID_VENDOR_FROM_DATABASE=Concept Development Inc
+
+pci:v00001391*
+ ID_VENDOR_FROM_DATABASE=Development Concepts Inc
+
+pci:v00001392*
+ ID_VENDOR_FROM_DATABASE=Medialight Inc
+
+pci:v00001393*
+ ID_VENDOR_FROM_DATABASE=Moxa Technologies Co Ltd
+
+pci:v00001393d00000001*
+ ID_PRODUCT_FROM_DATABASE=UC7000 Serial
+
+pci:v00001393d00001020*
+ ID_PRODUCT_FROM_DATABASE=CP102 (2-port RS-232 PCI)
+
+pci:v00001393d00001021*
+ ID_PRODUCT_FROM_DATABASE=CP102UL (2-port RS-232 Universal PCI)
+
+pci:v00001393d00001022*
+ ID_PRODUCT_FROM_DATABASE=CP102U (2-port RS-232 Universal PCI)
+
+pci:v00001393d00001023*
+ ID_PRODUCT_FROM_DATABASE=CP-102UF
+
+pci:v00001393d00001024*
+ ID_PRODUCT_FROM_DATABASE=CP-102E (2-port RS-232 Smart PCI Express Serial Board)
+
+pci:v00001393d00001025*
+ ID_PRODUCT_FROM_DATABASE=CP-102EL (2-port RS-232 Smart PCI Express Serial Board)
+
+pci:v00001393d00001040*
+ ID_PRODUCT_FROM_DATABASE=Smartio C104H/PCI
+
+pci:v00001393d00001041*
+ ID_PRODUCT_FROM_DATABASE=CP104U (4-port RS-232 Universal PCI)
+
+pci:v00001393d00001042*
+ ID_PRODUCT_FROM_DATABASE=CP104JU (4-port RS-232 Universal PCI)
+
+pci:v00001393d00001043*
+ ID_PRODUCT_FROM_DATABASE=CP104EL (4-port RS-232 Smart PCI Express)
+
+pci:v00001393d00001044*
+ ID_PRODUCT_FROM_DATABASE=POS104UL (4-port RS-232 Universal PCI)
+
+pci:v00001393d00001045*
+ ID_PRODUCT_FROM_DATABASE=CP-104EL-A (4-port RS-232 PCI Express Serial Board)
+
+pci:v00001393d00001080*
+ ID_PRODUCT_FROM_DATABASE=CB108 (8-port RS-232 PC/104-plus Module)
+
+pci:v00001393d00001140*
+ ID_PRODUCT_FROM_DATABASE=CT-114 series
+
+pci:v00001393d00001141*
+ ID_PRODUCT_FROM_DATABASE=Industrio CP-114
+
+pci:v00001393d00001142*
+ ID_PRODUCT_FROM_DATABASE=CB114 (4-port RS-232/422/485 PC/104-plus Module)
+
+pci:v00001393d00001143*
+ ID_PRODUCT_FROM_DATABASE=CP-114UL (4-port RS-232/422/485 Smart Universal PCI Serial Board)
+
+pci:v00001393d00001144*
+ ID_PRODUCT_FROM_DATABASE=CP-114EL (4-port RS-232/422/485 Smart PCI Express Serial Board)
+
+pci:v00001393d00001180*
+ ID_PRODUCT_FROM_DATABASE=CP118U (8-port RS-232/422/485 Smart Universal PCI)
+
+pci:v00001393d00001181*
+ ID_PRODUCT_FROM_DATABASE=CP118EL (8-port RS-232/422/485 Smart PCI Express)
+
+pci:v00001393d00001182*
+ ID_PRODUCT_FROM_DATABASE=CP-118EL-A (8-port RS-232/422/485 PCI Express Serial Board)
+
+pci:v00001393d00001320*
+ ID_PRODUCT_FROM_DATABASE=CP132 (2-port RS-422/485 PCI)
+
+pci:v00001393d00001321*
+ ID_PRODUCT_FROM_DATABASE=CP132U (2-Port RS-422/485 Universal PCI)
+
+pci:v00001393d00001322*
+ ID_PRODUCT_FROM_DATABASE=CP-132EL (2-port RS-422/485 Smart PCI Express Serial Board)
+
+pci:v00001393d00001340*
+ ID_PRODUCT_FROM_DATABASE=CP134U (4-Port RS-422/485 Universal PCI)
+
+pci:v00001393d00001341*
+ ID_PRODUCT_FROM_DATABASE=CB134I (4-port RS-422/485 PC/104-plus Module)
+
+pci:v00001393d00001380*
+ ID_PRODUCT_FROM_DATABASE=CP138U (8-port RS-232/422/485 Smart Universal PCI)
+
+pci:v00001393d00001680*
+ ID_PRODUCT_FROM_DATABASE=Smartio C168H/PCI
+
+pci:v00001393d00001681*
+ ID_PRODUCT_FROM_DATABASE=CP-168U V2 Smart Serial Board (8-port RS-232)
+
+pci:v00001393d00001682*
+ ID_PRODUCT_FROM_DATABASE=CP168EL (8-port RS-232 Smart PCI Express)
+
+pci:v00001393d00001683*
+ ID_PRODUCT_FROM_DATABASE=CP-168EL-A (8-port RS-232 PCI Express Serial Board)
+
+pci:v00001393d00002040*
+ ID_PRODUCT_FROM_DATABASE=Intellio CP-204J
+
+pci:v00001393d00002180*
+ ID_PRODUCT_FROM_DATABASE=Intellio C218 Turbo PCI
+
+pci:v00001393d00003200*
+ ID_PRODUCT_FROM_DATABASE=Intellio C320 Turbo PCI
+
+pci:v00001394*
+ ID_VENDOR_FROM_DATABASE=Level One Communications
+
+pci:v00001394d00000001*
+ ID_PRODUCT_FROM_DATABASE=LXT1001 Gigabit Ethernet
+
+pci:v00001394d00000001sv00001186sd00004800*
+ ID_PRODUCT_FROM_DATABASE=DGE-500SX
+
+pci:v00001394d00000001sv00001394sd00000001*
+ ID_PRODUCT_FROM_DATABASE=NetCelerator Adapter
+
+pci:v00001395*
+ ID_VENDOR_FROM_DATABASE=Ambicom Inc
+
+pci:v00001396*
+ ID_VENDOR_FROM_DATABASE=Cipher Systems Inc
+
+pci:v00001397*
+ ID_VENDOR_FROM_DATABASE=Cologne Chip Designs GmbH
+
+pci:v00001397d000008B4*
+ ID_PRODUCT_FROM_DATABASE=ISDN network Controller [HFC-4S]
+
+pci:v00001397d000008B4sv00001397sd0000B520*
+ ID_PRODUCT_FROM_DATABASE=HFC-4S [IOB4ST]
+
+pci:v00001397d000008B4sv00001397sd0000B540*
+ ID_PRODUCT_FROM_DATABASE=HFC-4S [Swyx 4xS0 SX2 QuadBri]
+
+pci:v00001397d000008B4sv00001397sd0000B550*
+ ID_PRODUCT_FROM_DATABASE=HFC-4S [Junghanns quadBRI]
+
+pci:v00001397d000008B4sv00001397sd0000B556*
+ ID_PRODUCT_FROM_DATABASE=HFC-4S [Junghanns DuoDBRI]
+
+pci:v00001397d000008B4sv00001397sd0000E888*
+ ID_PRODUCT_FROM_DATABASE=HFC-4S [OpenVox B200P / B400P]
+
+pci:v00001397d000016B8*
+ ID_PRODUCT_FROM_DATABASE=ISDN network Controller [HFC-8S]
+
+pci:v00001397d000016B8sv00001397sd0000B562*
+ ID_PRODUCT_FROM_DATABASE=HFC-8S [IOB8ST]
+
+pci:v00001397d00002BD0*
+ ID_PRODUCT_FROM_DATABASE=ISDN network controller [HFC-PCI]
+
+pci:v00001397d00002BD0sv00000675sd00001704*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C)
+
+pci:v00001397d00002BD0sv00000675sd00001708*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C, ACPI)
+
+pci:v00001397d00002BD0sv00001397sd00002BD0*
+ ID_PRODUCT_FROM_DATABASE=ISDN Board
+
+pci:v00001397d00002BD0sv0000E4BFsd00001000*
+ ID_PRODUCT_FROM_DATABASE=CI1-1-Harp
+
+pci:v00001397d000030B1*
+ ID_PRODUCT_FROM_DATABASE=ISDN network Controller [HFC-E1]
+
+pci:v00001397d0000B700*
+ ID_PRODUCT_FROM_DATABASE=ISDN network controller PrimuX S0 [HFC-PCI]
+
+pci:v00001397d0000F001*
+ ID_PRODUCT_FROM_DATABASE=GSM Network Controller [HFC-4GSM]
+
+pci:v00001398*
+ ID_VENDOR_FROM_DATABASE=Clarion co. Ltd
+
+pci:v00001399*
+ ID_VENDOR_FROM_DATABASE=Rios systems Co Ltd
+
+pci:v0000139A*
+ ID_VENDOR_FROM_DATABASE=Alacritech Inc
+
+pci:v0000139Ad00000001*
+ ID_PRODUCT_FROM_DATABASE=Quad Port 10/100 Server Accelerator
+
+pci:v0000139Ad00000003*
+ ID_PRODUCT_FROM_DATABASE=Single Port 10/100 Server Accelerator
+
+pci:v0000139Ad00000005*
+ ID_PRODUCT_FROM_DATABASE=Single Port Gigabit Server Accelerator
+
+pci:v0000139B*
+ ID_VENDOR_FROM_DATABASE=Mediasonic Multimedia Systems Ltd
+
+pci:v0000139C*
+ ID_VENDOR_FROM_DATABASE=Quantum 3d Inc
+
+pci:v0000139D*
+ ID_VENDOR_FROM_DATABASE=EPL limited
+
+pci:v0000139E*
+ ID_VENDOR_FROM_DATABASE=Media4
+
+pci:v0000139F*
+ ID_VENDOR_FROM_DATABASE=Aethra s.r.l.
+
+pci:v000013A0*
+ ID_VENDOR_FROM_DATABASE=Crystal Group Inc
+
+pci:v000013A1*
+ ID_VENDOR_FROM_DATABASE=Kawasaki Heavy Industries Ltd
+
+pci:v000013A2*
+ ID_VENDOR_FROM_DATABASE=Ositech Communications Inc
+
+pci:v000013A3*
+ ID_VENDOR_FROM_DATABASE=Hifn Inc.
+
+pci:v000013A3d00000005*
+ ID_PRODUCT_FROM_DATABASE=7751 Security Processor
+
+pci:v000013A3d00000006*
+ ID_PRODUCT_FROM_DATABASE=6500 Public Key Processor
+
+pci:v000013A3d00000007*
+ ID_PRODUCT_FROM_DATABASE=7811 Security Processor
+
+pci:v000013A3d00000012*
+ ID_PRODUCT_FROM_DATABASE=7951 Security Processor
+
+pci:v000013A3d00000014*
+ ID_PRODUCT_FROM_DATABASE=78XX Security Processor
+
+pci:v000013A3d00000016*
+ ID_PRODUCT_FROM_DATABASE=8065 Security Processor
+
+pci:v000013A3d00000017*
+ ID_PRODUCT_FROM_DATABASE=8165 Security Processor
+
+pci:v000013A3d00000018*
+ ID_PRODUCT_FROM_DATABASE=8154 Security Processor
+
+pci:v000013A3d0000001D*
+ ID_PRODUCT_FROM_DATABASE=7956 Security Processor
+
+pci:v000013A3d0000001F*
+ ID_PRODUCT_FROM_DATABASE=7855 Security Processor
+
+pci:v000013A3d00000020*
+ ID_PRODUCT_FROM_DATABASE=7955 Security Processor
+
+pci:v000013A3d00000026*
+ ID_PRODUCT_FROM_DATABASE=8155 Security Processor
+
+pci:v000013A3d0000002E*
+ ID_PRODUCT_FROM_DATABASE=9630 Compression Processor
+
+pci:v000013A3d0000002F*
+ ID_PRODUCT_FROM_DATABASE=9725 Compression and Security Processor
+
+pci:v000013A3d0000002Fsv000013A3sd00001600*
+ ID_PRODUCT_FROM_DATABASE=DR1600 Acceleration Card
+
+pci:v000013A3d0000002Fsv000013A3sd00001605*
+ ID_PRODUCT_FROM_DATABASE=DR1605 Acceleration Card
+
+pci:v000013A3d0000002Fsv000013A3sd00001610*
+ ID_PRODUCT_FROM_DATABASE=DR1610 Acceleration Card
+
+pci:v000013A3d0000002Fsv000013A3sd00001615*
+ ID_PRODUCT_FROM_DATABASE=DR1615 Acceleration Card
+
+pci:v000013A3d0000002Fsv000013A3sd00001620*
+ ID_PRODUCT_FROM_DATABASE=DR1620 Acceleration Card
+
+pci:v000013A3d0000002Fsv000013A3sd00001625*
+ ID_PRODUCT_FROM_DATABASE=DR1625 Acceleration Card
+
+pci:v000013A3d00000033*
+ ID_PRODUCT_FROM_DATABASE=8201 Acceleration Processor
+
+pci:v000013A3d00000033sv000013A3sd00000036*
+ ID_PRODUCT_FROM_DATABASE=DX1710 Acceleration Card
+
+pci:v000013A3d00000034*
+ ID_PRODUCT_FROM_DATABASE=8202 Acceleration Processor
+
+pci:v000013A3d00000034sv000013A3sd00000036*
+ ID_PRODUCT_FROM_DATABASE=DX1720 Acceleration Card
+
+pci:v000013A3d00000035*
+ ID_PRODUCT_FROM_DATABASE=8203 Acceleration Processor
+
+pci:v000013A3d00000035sv000013A3sd00000036*
+ ID_PRODUCT_FROM_DATABASE=DX1730 Acceleration Card
+
+pci:v000013A3d00000037*
+ ID_PRODUCT_FROM_DATABASE=8204 Acceleration Processor
+
+pci:v000013A3d00000037sv000013A3sd00000036*
+ ID_PRODUCT_FROM_DATABASE=DX1740 Acceleration Card
+
+pci:v000013A4*
+ ID_VENDOR_FROM_DATABASE=Rascom Inc
+
+pci:v000013A5*
+ ID_VENDOR_FROM_DATABASE=Audio Digital Imaging Inc
+
+pci:v000013A6*
+ ID_VENDOR_FROM_DATABASE=Videonics Inc
+
+pci:v000013A7*
+ ID_VENDOR_FROM_DATABASE=Teles AG
+
+pci:v000013A8*
+ ID_VENDOR_FROM_DATABASE=Exar Corp.
+
+pci:v000013A8d00000152*
+ ID_PRODUCT_FROM_DATABASE=XR17C/D152 Dual PCI UART
+
+pci:v000013A8d00000154*
+ ID_PRODUCT_FROM_DATABASE=XR17C154 Quad UART
+
+pci:v000013A8d00000158*
+ ID_PRODUCT_FROM_DATABASE=XR17C158 Octal UART
+
+pci:v000013A8d00000252*
+ ID_PRODUCT_FROM_DATABASE=XR17V252 Dual UART PCI controller
+
+pci:v000013A8d00000254*
+ ID_PRODUCT_FROM_DATABASE=XR17V254 Quad UART PCI controller
+
+pci:v000013A8d00000258*
+ ID_PRODUCT_FROM_DATABASE=XR17V258 Octal UART PCI controller
+
+pci:v000013A9*
+ ID_VENDOR_FROM_DATABASE=Siemens Medical Systems, Ultrasound Group
+
+pci:v000013AA*
+ ID_VENDOR_FROM_DATABASE=Broadband Networks Inc
+
+pci:v000013AB*
+ ID_VENDOR_FROM_DATABASE=Arcom Control Systems Ltd
+
+pci:v000013AC*
+ ID_VENDOR_FROM_DATABASE=Motion Media Technology Ltd
+
+pci:v000013AD*
+ ID_VENDOR_FROM_DATABASE=Nexus Inc
+
+pci:v000013AE*
+ ID_VENDOR_FROM_DATABASE=ALD Technology Ltd
+
+pci:v000013AF*
+ ID_VENDOR_FROM_DATABASE=T.Sqware
+
+pci:v000013B0*
+ ID_VENDOR_FROM_DATABASE=Maxspeed Corp
+
+pci:v000013B1*
+ ID_VENDOR_FROM_DATABASE=Tamura corporation
+
+pci:v000013B2*
+ ID_VENDOR_FROM_DATABASE=Techno Chips Co. Ltd
+
+pci:v000013B3*
+ ID_VENDOR_FROM_DATABASE=Lanart Corporation
+
+pci:v000013B4*
+ ID_VENDOR_FROM_DATABASE=Wellbean Co Inc
+
+pci:v000013B5*
+ ID_VENDOR_FROM_DATABASE=ARM
+
+pci:v000013B6*
+ ID_VENDOR_FROM_DATABASE=Dlog GmbH
+
+pci:v000013B7*
+ ID_VENDOR_FROM_DATABASE=Logic Devices Inc
+
+pci:v000013B8*
+ ID_VENDOR_FROM_DATABASE=Nokia Telecommunications oy
+
+pci:v000013B9*
+ ID_VENDOR_FROM_DATABASE=Elecom Co Ltd
+
+pci:v000013BA*
+ ID_VENDOR_FROM_DATABASE=Oxford Instruments
+
+pci:v000013BB*
+ ID_VENDOR_FROM_DATABASE=Sanyo Technosound Co Ltd
+
+pci:v000013BC*
+ ID_VENDOR_FROM_DATABASE=Bitran Corporation
+
+pci:v000013BD*
+ ID_VENDOR_FROM_DATABASE=Sharp corporation
+
+pci:v000013BE*
+ ID_VENDOR_FROM_DATABASE=Miroku Jyoho Service Co. Ltd
+
+pci:v000013BF*
+ ID_VENDOR_FROM_DATABASE=Sharewave Inc
+
+pci:v000013C0*
+ ID_VENDOR_FROM_DATABASE=Microgate Corporation
+
+pci:v000013C0d00000010*
+ ID_PRODUCT_FROM_DATABASE=SyncLink Adapter v1
+
+pci:v000013C0d00000020*
+ ID_PRODUCT_FROM_DATABASE=SyncLink SCC Adapter
+
+pci:v000013C0d00000030*
+ ID_PRODUCT_FROM_DATABASE=SyncLink Multiport Adapter
+
+pci:v000013C0d00000070*
+ ID_PRODUCT_FROM_DATABASE=SyncLink GT Adapter
+
+pci:v000013C0d00000080*
+ ID_PRODUCT_FROM_DATABASE=SyncLink GT4 Adapter
+
+pci:v000013C0d000000A0*
+ ID_PRODUCT_FROM_DATABASE=SyncLink GT2 Adapter
+
+pci:v000013C0d00000210*
+ ID_PRODUCT_FROM_DATABASE=SyncLink Adapter v2
+
+pci:v000013C1*
+ ID_VENDOR_FROM_DATABASE=3ware Inc
+
+pci:v000013C1d00001000*
+ ID_PRODUCT_FROM_DATABASE=5xxx/6xxx-series PATA-RAID
+
+pci:v000013C1d00001001*
+ ID_PRODUCT_FROM_DATABASE=7xxx/8xxx-series PATA/SATA-RAID
+
+pci:v000013C1d00001001sv000013C1sd00001001*
+ ID_PRODUCT_FROM_DATABASE=7xxx/8xxx-series PATA/SATA-RAID
+
+pci:v000013C1d00001002*
+ ID_PRODUCT_FROM_DATABASE=9xxx-series SATA-RAID
+
+pci:v000013C1d00001003*
+ ID_PRODUCT_FROM_DATABASE=9550SX SATA-II RAID PCI-X
+
+pci:v000013C1d00001004*
+ ID_PRODUCT_FROM_DATABASE=9650SE SATA-II RAID PCIe
+
+pci:v000013C1d00001005*
+ ID_PRODUCT_FROM_DATABASE=9690SA SAS/SATA-II RAID PCIe
+
+pci:v000013C1d00001010*
+ ID_PRODUCT_FROM_DATABASE=9750 SAS2/SATA-II RAID PCIe
+
+pci:v000013C2*
+ ID_VENDOR_FROM_DATABASE=Technotrend Systemtechnik GmbH
+
+pci:v000013C2d0000000E*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.3
+
+pci:v000013C2d00001019*
+ ID_PRODUCT_FROM_DATABASE=TTechnoTrend-budget DVB S2-3200
+
+pci:v000013C3*
+ ID_VENDOR_FROM_DATABASE=Janz Computer AG
+
+pci:v000013C4*
+ ID_VENDOR_FROM_DATABASE=Phase Metrics
+
+pci:v000013C5*
+ ID_VENDOR_FROM_DATABASE=Alphi Technology Corp
+
+pci:v000013C6*
+ ID_VENDOR_FROM_DATABASE=Condor Engineering Inc
+
+pci:v000013C6d00000520*
+ ID_PRODUCT_FROM_DATABASE=CEI-520 A429 Card
+
+pci:v000013C6d00000620*
+ ID_PRODUCT_FROM_DATABASE=CEI-620 A429 Card
+
+pci:v000013C6d00000820*
+ ID_PRODUCT_FROM_DATABASE=CEI-820 A429 Card
+
+pci:v000013C6d00000830*
+ ID_PRODUCT_FROM_DATABASE=CEI-830 A429 Card
+
+pci:v000013C6d00001004*
+ ID_PRODUCT_FROM_DATABASE=P-SER Multi-channel PMC to RS-485/422/232 adapter
+
+pci:v000013C7*
+ ID_VENDOR_FROM_DATABASE=Blue Chip Technology Ltd
+
+pci:v000013C7d00000ADC*
+ ID_PRODUCT_FROM_DATABASE=PCI-ADC
+
+pci:v000013C7d00000B10*
+ ID_PRODUCT_FROM_DATABASE=PCI-PIO
+
+pci:v000013C7d00000D10*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO
+
+pci:v000013C7d0000524C*
+ ID_PRODUCT_FROM_DATABASE=PCI-RLY
+
+pci:v000013C7d00005744*
+ ID_PRODUCT_FROM_DATABASE=PCI-WDT
+
+pci:v000013C8*
+ ID_VENDOR_FROM_DATABASE=Apptech Inc
+
+pci:v000013C9*
+ ID_VENDOR_FROM_DATABASE=Eaton Corporation
+
+pci:v000013CA*
+ ID_VENDOR_FROM_DATABASE=Iomega Corporation
+
+pci:v000013CB*
+ ID_VENDOR_FROM_DATABASE=Yano Electric Co Ltd
+
+pci:v000013CC*
+ ID_VENDOR_FROM_DATABASE=Metheus Corporation
+
+pci:v000013CD*
+ ID_VENDOR_FROM_DATABASE=Compatible Systems Corporation
+
+pci:v000013CE*
+ ID_VENDOR_FROM_DATABASE=Cocom A/S
+
+pci:v000013CF*
+ ID_VENDOR_FROM_DATABASE=Studio Audio & Video Ltd
+
+pci:v000013D0*
+ ID_VENDOR_FROM_DATABASE=Techsan Electronics Co Ltd
+
+pci:v000013D0d00002103*
+ ID_PRODUCT_FROM_DATABASE=B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card
+
+pci:v000013D0d00002104*
+ ID_PRODUCT_FROM_DATABASE=B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card (rev 01)
+
+pci:v000013D0d00002200*
+ ID_PRODUCT_FROM_DATABASE=B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card
+
+pci:v000013D1*
+ ID_VENDOR_FROM_DATABASE=Abocom Systems Inc
+
+pci:v000013D1d0000AB02*
+ ID_PRODUCT_FROM_DATABASE=ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter
+
+pci:v000013D1d0000AB03*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v000013D1d0000AB06*
+ ID_PRODUCT_FROM_DATABASE=RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter
+
+pci:v000013D1d0000AB08*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v000013D2*
+ ID_VENDOR_FROM_DATABASE=Shark Multimedia Inc
+
+pci:v000013D4*
+ ID_VENDOR_FROM_DATABASE=Graphics Microsystems Inc
+
+pci:v000013D5*
+ ID_VENDOR_FROM_DATABASE=Media 100 Inc
+
+pci:v000013D6*
+ ID_VENDOR_FROM_DATABASE=K.I. Technology Co Ltd
+
+pci:v000013D7*
+ ID_VENDOR_FROM_DATABASE=Toshiba Engineering Corporation
+
+pci:v000013D8*
+ ID_VENDOR_FROM_DATABASE=Phobos corporation
+
+pci:v000013D9*
+ ID_VENDOR_FROM_DATABASE=Apex PC Solutions Inc
+
+pci:v000013DA*
+ ID_VENDOR_FROM_DATABASE=Intresource Systems pte Ltd
+
+pci:v000013DB*
+ ID_VENDOR_FROM_DATABASE=Janich & Klass Computertechnik GmbH
+
+pci:v000013DC*
+ ID_VENDOR_FROM_DATABASE=Netboost Corporation
+
+pci:v000013DD*
+ ID_VENDOR_FROM_DATABASE=Multimedia Bundle Inc
+
+pci:v000013DE*
+ ID_VENDOR_FROM_DATABASE=ABB Robotics Products AB
+
+pci:v000013DF*
+ ID_VENDOR_FROM_DATABASE=E-Tech Inc
+
+pci:v000013DFd00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI56RVP Modem
+
+pci:v000013DFd00000001sv000013DFsd00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI56RVP Modem
+
+pci:v000013E0*
+ ID_VENDOR_FROM_DATABASE=GVC Corporation
+
+pci:v000013E1*
+ ID_VENDOR_FROM_DATABASE=Silicom Multimedia Systems Inc
+
+pci:v000013E2*
+ ID_VENDOR_FROM_DATABASE=Dynamics Research Corporation
+
+pci:v000013E3*
+ ID_VENDOR_FROM_DATABASE=Nest Inc
+
+pci:v000013E4*
+ ID_VENDOR_FROM_DATABASE=Calculex Inc
+
+pci:v000013E5*
+ ID_VENDOR_FROM_DATABASE=Telesoft Design Ltd
+
+pci:v000013E6*
+ ID_VENDOR_FROM_DATABASE=Argosy research Inc
+
+pci:v000013E7*
+ ID_VENDOR_FROM_DATABASE=NAC Incorporated
+
+pci:v000013E8*
+ ID_VENDOR_FROM_DATABASE=Chip Express Corporation
+
+pci:v000013E9*
+ ID_VENDOR_FROM_DATABASE=Intraserver Technology Inc
+
+pci:v000013EA*
+ ID_VENDOR_FROM_DATABASE=Dallas Semiconductor
+
+pci:v000013EB*
+ ID_VENDOR_FROM_DATABASE=Hauppauge Computer Works Inc
+
+pci:v000013EC*
+ ID_VENDOR_FROM_DATABASE=Zydacron Inc
+
+pci:v000013ECd0000000A*
+ ID_PRODUCT_FROM_DATABASE=NPC-RC01 Remote control receiver
+
+pci:v000013ED*
+ ID_VENDOR_FROM_DATABASE=Raytheion E-Systems
+
+pci:v000013EE*
+ ID_VENDOR_FROM_DATABASE=Hayes Microcomputer Products Inc
+
+pci:v000013EF*
+ ID_VENDOR_FROM_DATABASE=Coppercom Inc
+
+pci:v000013F0*
+ ID_VENDOR_FROM_DATABASE=Sundance Technology Inc / IC Plus Corp
+
+pci:v000013F0d00000200*
+ ID_PRODUCT_FROM_DATABASE=IC Plus IP100A Integrated 10/100 Ethernet MAC + PHY
+
+pci:v000013F0d00000200sv00001043sd00008213*
+ ID_PRODUCT_FROM_DATABASE=NX1001
+
+pci:v000013F0d00000201*
+ ID_PRODUCT_FROM_DATABASE=ST201 Sundance Ethernet
+
+pci:v000013F0d00001021*
+ ID_PRODUCT_FROM_DATABASE=TC902x Gigabit Ethernet
+
+pci:v000013F0d00001023*
+ ID_PRODUCT_FROM_DATABASE=IP1000 Family Gigabit Ethernet
+
+pci:v000013F0d00001023sv00001043sd00008180*
+ ID_PRODUCT_FROM_DATABASE=NX1101
+
+pci:v000013F1*
+ ID_VENDOR_FROM_DATABASE=Oce' - Technologies B.V.
+
+pci:v000013F2*
+ ID_VENDOR_FROM_DATABASE=Ford Microelectronics Inc
+
+pci:v000013F3*
+ ID_VENDOR_FROM_DATABASE=Mcdata Corporation
+
+pci:v000013F4*
+ ID_VENDOR_FROM_DATABASE=Troika Networks, Inc.
+
+pci:v000013F4d00001401*
+ ID_PRODUCT_FROM_DATABASE=Zentai Fibre Channel Adapter
+
+pci:v000013F5*
+ ID_VENDOR_FROM_DATABASE=Kansai Electric Co. Ltd
+
+pci:v000013F6*
+ ID_VENDOR_FROM_DATABASE=C-Media Electronics Inc
+
+pci:v000013F6d00000011*
+ ID_PRODUCT_FROM_DATABASE=CMI8738
+
+pci:v000013F6d00000100*
+ ID_PRODUCT_FROM_DATABASE=CM8338A
+
+pci:v000013F6d00000100sv000013F6sd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=CMI8338/C3DX PCI Audio Device
+
+pci:v000013F6d00000101*
+ ID_PRODUCT_FROM_DATABASE=CM8338B
+
+pci:v000013F6d00000101sv000013F6sd00000101*
+ ID_PRODUCT_FROM_DATABASE=CMI8338-031 PCI Audio Device
+
+pci:v000013F6d00000111*
+ ID_PRODUCT_FROM_DATABASE=CMI8738/CMI8768 PCI Audio
+
+pci:v000013F6d00000111sv00001019sd00000970*
+ ID_PRODUCT_FROM_DATABASE=P6STP-FL motherboard
+
+pci:v000013F6d00000111sv00001043sd00008035*
+ ID_PRODUCT_FROM_DATABASE=CUSI-FX motherboard
+
+pci:v000013F6d00000111sv00001043sd00008077*
+ ID_PRODUCT_FROM_DATABASE=CMI8738 6-channel audio controller
+
+pci:v000013F6d00000111sv00001043sd000080E2*
+ ID_PRODUCT_FROM_DATABASE=CMI8738 6ch-MX
+
+pci:v000013F6d00000111sv000013F6sd00000111*
+ ID_PRODUCT_FROM_DATABASE=CMI8738/C3DX PCI Audio Device
+
+pci:v000013F6d00000111sv000013F6sd00009761*
+ ID_PRODUCT_FROM_DATABASE=Theatron Agrippa
+
+pci:v000013F6d00000111sv0000153Bsd00001144*
+ ID_PRODUCT_FROM_DATABASE=Aureon 5.1
+
+pci:v000013F6d00000111sv0000153Bsd00001170*
+ ID_PRODUCT_FROM_DATABASE=Aureon 7.1
+
+pci:v000013F6d00000111sv00001681sd0000A000*
+ ID_PRODUCT_FROM_DATABASE=Gamesurround MUSE XL
+
+pci:v000013F6d00000111sv000017ABsd00000604*
+ ID_PRODUCT_FROM_DATABASE=PSC604 Dynamic Edge
+
+pci:v000013F6d00000111sv000017ABsd00000605*
+ ID_PRODUCT_FROM_DATABASE=PSC605 Sonic Edge
+
+pci:v000013F6d00000111sv000017ABsd00007777*
+ ID_PRODUCT_FROM_DATABASE=PSC605 Sonic Edge
+
+pci:v000013F6d00000111sv0000270Fsd00001103*
+ ID_PRODUCT_FROM_DATABASE=CT-7NJS Ultra motherboard
+
+pci:v000013F6d00000111sv0000270Fsd0000F462*
+ ID_PRODUCT_FROM_DATABASE=7NJL1 motherboard
+
+pci:v000013F6d00000111sv0000584Dsd00003731*
+ ID_PRODUCT_FROM_DATABASE=Digital X-Mystique
+
+pci:v000013F6d00000111sv0000584Dsd00003741*
+ ID_PRODUCT_FROM_DATABASE=X-Plosion 7.1
+
+pci:v000013F6d00000111sv0000584Dsd00003751*
+ ID_PRODUCT_FROM_DATABASE=X-Raider 7.1
+
+pci:v000013F6d00000111sv0000584Dsd00003761*
+ ID_PRODUCT_FROM_DATABASE=X-Mystique 7.1 LP
+
+pci:v000013F6d00000111sv0000584Dsd00003771*
+ ID_PRODUCT_FROM_DATABASE=X-Mystique 7.1 LP Value
+
+pci:v000013F6d00000111sv00007284sd00008384*
+ ID_PRODUCT_FROM_DATABASE=Striker 7.1
+
+pci:v000013F6d00000211*
+ ID_PRODUCT_FROM_DATABASE=CM8738
+
+pci:v000013F6d00005011*
+ ID_PRODUCT_FROM_DATABASE=CM8888 [Oxygen Express]
+
+pci:v000013F6d00005011sv000013F6sd00005011*
+ ID_PRODUCT_FROM_DATABASE=HDA Controller
+
+pci:v000013F6d00008788*
+ ID_PRODUCT_FROM_DATABASE=CMI8788 [Oxygen HD Audio]
+
+pci:v000013F6d00008788sv00001043sd00008269*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 200 (Xonar D2)
+
+pci:v000013F6d00008788sv00001043sd00008275*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar DX)
+
+pci:v000013F6d00008788sv00001043sd000082B7*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 200 (Xonar D2X)
+
+pci:v000013F6d00008788sv00001043sd00008314*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 200 (Xonar HDAV1.3)
+
+pci:v000013F6d00008788sv00001043sd00008327*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar DX)
+
+pci:v000013F6d00008788sv00001043sd0000834F*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar D1)
+
+pci:v000013F6d00008788sv00001043sd0000835C*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar Essence STX)
+
+pci:v000013F6d00008788sv00001043sd0000835D*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar ST)
+
+pci:v000013F6d00008788sv00001043sd0000835E*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 200 (Xonar HDAV1.3 Slim)
+
+pci:v000013F6d00008788sv00001043sd0000838E*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 66 (Xonar DS)
+
+pci:v000013F6d00008788sv00001043sd00008428*
+ ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar Xense)
+
+pci:v000013F6d00008788sv00001043sd00008467*
+ ID_PRODUCT_FROM_DATABASE=CMI8786 (Xonar DG)
+
+pci:v000013F6d00008788sv000013F6sd00008782*
+ ID_PRODUCT_FROM_DATABASE=PCI 2.0 HD Audio
+
+pci:v000013F6d00008788sv000013F6sd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=CMI8787-HG2PCI
+
+pci:v000013F6d00008788sv000014C3sd00001710*
+ ID_PRODUCT_FROM_DATABASE=HiFier Fantasia
+
+pci:v000013F6d00008788sv000014C3sd00001711*
+ ID_PRODUCT_FROM_DATABASE=HiFier Serenade
+
+pci:v000013F6d00008788sv00001A58sd00000910*
+ ID_PRODUCT_FROM_DATABASE=Barracuda AC-1
+
+pci:v000013F6d00008788sv0000415Asd00005431*
+ ID_PRODUCT_FROM_DATABASE=X-Meridian 7.1
+
+pci:v000013F6d00008788sv00005431sd0000017A*
+ ID_PRODUCT_FROM_DATABASE=X-Meridian 7.1 2G
+
+pci:v000013F6d00008788sv0000584Dsd00003781*
+ ID_PRODUCT_FROM_DATABASE=HDA X-Purity 7.1 Platinum
+
+pci:v000013F6d00008788sv00007284sd00009761*
+ ID_PRODUCT_FROM_DATABASE=CLARO
+
+pci:v000013F6d00008788sv00007284sd00009781*
+ ID_PRODUCT_FROM_DATABASE=CLARO halo
+
+pci:v000013F6d00008788sv00007284sd00009783*
+ ID_PRODUCT_FROM_DATABASE=eCLARO
+
+pci:v000013F6d00008788sv00007284sd00009787*
+ ID_PRODUCT_FROM_DATABASE=CLARO II
+
+pci:v000013F6d00009880*
+ ID_PRODUCT_FROM_DATABASE=CM9880
+
+pci:v000013F7*
+ ID_VENDOR_FROM_DATABASE=Wildfire Communications
+
+pci:v000013F8*
+ ID_VENDOR_FROM_DATABASE=Ad Lib Multimedia Inc
+
+pci:v000013F9*
+ ID_VENDOR_FROM_DATABASE=NTT Advanced Technology Corp.
+
+pci:v000013FA*
+ ID_VENDOR_FROM_DATABASE=Pentland Systems Ltd
+
+pci:v000013FB*
+ ID_VENDOR_FROM_DATABASE=Aydin Corp
+
+pci:v000013FC*
+ ID_VENDOR_FROM_DATABASE=Computer Peripherals International
+
+pci:v000013FD*
+ ID_VENDOR_FROM_DATABASE=Micro Science Inc
+
+pci:v000013FE*
+ ID_VENDOR_FROM_DATABASE=Advantech Co. Ltd
+
+pci:v000013FEd00001240*
+ ID_PRODUCT_FROM_DATABASE=PCI-1240 4-channel stepper motor controller card
+
+pci:v000013FEd00001600*
+ ID_PRODUCT_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 0)
+
+pci:v000013FEd00001600sv00001601sd00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI-1601 2-port unisolated RS-422/485
+
+pci:v000013FEd00001600sv00001602sd00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI-1602 2-port isolated RS-422/485
+
+pci:v000013FEd00001600sv00001612sd00000004*
+ ID_PRODUCT_FROM_DATABASE=PCI-1612 4-port RS-232/422/485
+
+pci:v000013FEd00001603*
+ ID_PRODUCT_FROM_DATABASE=PCI-1603 2-port isolated RS-232/current loop
+
+pci:v000013FEd00001604*
+ ID_PRODUCT_FROM_DATABASE=PCI-1604 2-port RS-232
+
+pci:v000013FEd000016FF*
+ ID_PRODUCT_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 1: RX/TX steering CPLD)
+
+pci:v000013FEd000016FFsv00001601sd00000000*
+ ID_PRODUCT_FROM_DATABASE=PCI-1601 2-port unisolated RS-422/485 PCI communications card
+
+pci:v000013FEd000016FFsv00001602sd00000000*
+ ID_PRODUCT_FROM_DATABASE=PCI-1602 2-port isolated RS-422/485
+
+pci:v000013FEd000016FFsv00001612sd00000000*
+ ID_PRODUCT_FROM_DATABASE=PCI-1612 4-port RS-232/422/485
+
+pci:v000013FEd00001711*
+ ID_PRODUCT_FROM_DATABASE=PCI-1711 16-channel data acquisition card 12-bit, 100kS/s
+
+pci:v000013FEd00001733*
+ ID_PRODUCT_FROM_DATABASE=PCI-1733 32-channel isolated digital input card
+
+pci:v000013FEd00001752*
+ ID_PRODUCT_FROM_DATABASE=PCI-1752
+
+pci:v000013FEd00001754*
+ ID_PRODUCT_FROM_DATABASE=PCI-1754
+
+pci:v000013FEd00001756*
+ ID_PRODUCT_FROM_DATABASE=PCI-1756
+
+pci:v000013FF*
+ ID_VENDOR_FROM_DATABASE=Silicon Spice Inc
+
+pci:v00001400*
+ ID_VENDOR_FROM_DATABASE=Artx Inc
+
+pci:v00001400d00001401*
+ ID_PRODUCT_FROM_DATABASE=9432 TX
+
+pci:v00001401*
+ ID_VENDOR_FROM_DATABASE=CR-Systems A/S
+
+pci:v00001402*
+ ID_VENDOR_FROM_DATABASE=Meilhaus Electronic GmbH
+
+pci:v00001402d00000630*
+ ID_PRODUCT_FROM_DATABASE=ME-630
+
+pci:v00001402d00000940*
+ ID_PRODUCT_FROM_DATABASE=ME-94
+
+pci:v00001402d00000950*
+ ID_PRODUCT_FROM_DATABASE=ME-95
+
+pci:v00001402d00000960*
+ ID_PRODUCT_FROM_DATABASE=ME-96
+
+pci:v00001402d00001000*
+ ID_PRODUCT_FROM_DATABASE=ME-1000
+
+pci:v00001402d0000100A*
+ ID_PRODUCT_FROM_DATABASE=ME-1000
+
+pci:v00001402d0000100B*
+ ID_PRODUCT_FROM_DATABASE=ME-1000
+
+pci:v00001402d00001400*
+ ID_PRODUCT_FROM_DATABASE=ME-1400
+
+pci:v00001402d0000140A*
+ ID_PRODUCT_FROM_DATABASE=ME-1400A
+
+pci:v00001402d0000140B*
+ ID_PRODUCT_FROM_DATABASE=ME-1400B
+
+pci:v00001402d0000140C*
+ ID_PRODUCT_FROM_DATABASE=ME-1400C
+
+pci:v00001402d0000140D*
+ ID_PRODUCT_FROM_DATABASE=ME-1400D
+
+pci:v00001402d0000140E*
+ ID_PRODUCT_FROM_DATABASE=ME-1400E
+
+pci:v00001402d000014EA*
+ ID_PRODUCT_FROM_DATABASE=ME-1400EA
+
+pci:v00001402d000014EB*
+ ID_PRODUCT_FROM_DATABASE=ME-1400EB
+
+pci:v00001402d00001604*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/4U
+
+pci:v00001402d00001608*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/8U
+
+pci:v00001402d0000160C*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/12U
+
+pci:v00001402d0000160F*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/16U
+
+pci:v00001402d0000168F*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/16U8I
+
+pci:v00001402d00004610*
+ ID_PRODUCT_FROM_DATABASE=ME-4610
+
+pci:v00001402d00004650*
+ ID_PRODUCT_FROM_DATABASE=ME-4650
+
+pci:v00001402d00004660*
+ ID_PRODUCT_FROM_DATABASE=ME-4660
+
+pci:v00001402d00004661*
+ ID_PRODUCT_FROM_DATABASE=ME-4660I
+
+pci:v00001402d00004662*
+ ID_PRODUCT_FROM_DATABASE=ME-4660
+
+pci:v00001402d00004663*
+ ID_PRODUCT_FROM_DATABASE=ME-4660I
+
+pci:v00001402d00004670*
+ ID_PRODUCT_FROM_DATABASE=ME-4670
+
+pci:v00001402d00004671*
+ ID_PRODUCT_FROM_DATABASE=ME-4670I
+
+pci:v00001402d00004672*
+ ID_PRODUCT_FROM_DATABASE=ME-4670S
+
+pci:v00001402d00004673*
+ ID_PRODUCT_FROM_DATABASE=ME-4670IS
+
+pci:v00001402d00004680*
+ ID_PRODUCT_FROM_DATABASE=ME-4680
+
+pci:v00001402d00004681*
+ ID_PRODUCT_FROM_DATABASE=ME-4680I
+
+pci:v00001402d00004682*
+ ID_PRODUCT_FROM_DATABASE=ME-4680S
+
+pci:v00001402d00004683*
+ ID_PRODUCT_FROM_DATABASE=ME-4680IS
+
+pci:v00001402d00006004*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/4
+
+pci:v00001402d00006008*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/8
+
+pci:v00001402d0000600F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/16
+
+pci:v00001402d00006014*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/4
+
+pci:v00001402d00006018*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/8
+
+pci:v00001402d0000601F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/16
+
+pci:v00001402d00006034*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/4
+
+pci:v00001402d00006038*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/8
+
+pci:v00001402d0000603F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/16
+
+pci:v00001402d00006044*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/4/DIO
+
+pci:v00001402d00006048*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/8/DIO
+
+pci:v00001402d0000604F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/16/DIO
+
+pci:v00001402d00006054*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/4/DIO
+
+pci:v00001402d00006058*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/8/DIO
+
+pci:v00001402d0000605F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/16/DIO
+
+pci:v00001402d00006074*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/4/DIO
+
+pci:v00001402d00006078*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/8/DIO
+
+pci:v00001402d0000607F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/16/DIO
+
+pci:v00001402d00006104*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/4
+
+pci:v00001402d00006108*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/8
+
+pci:v00001402d0000610F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/16
+
+pci:v00001402d00006114*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/4
+
+pci:v00001402d00006118*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/8
+
+pci:v00001402d0000611F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/16
+
+pci:v00001402d00006134*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/4
+
+pci:v00001402d00006138*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/8
+
+pci:v00001402d0000613F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/16
+
+pci:v00001402d00006144*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/4/DIO
+
+pci:v00001402d00006148*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/8/DIO
+
+pci:v00001402d0000614F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/16/DIO
+
+pci:v00001402d00006154*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/4/DIO
+
+pci:v00001402d00006158*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/8/DIO
+
+pci:v00001402d0000615F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/16/DIO
+
+pci:v00001402d00006174*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/4/DIO
+
+pci:v00001402d00006178*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/8/DIO
+
+pci:v00001402d0000617F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/16/DIO
+
+pci:v00001402d00006259*
+ ID_PRODUCT_FROM_DATABASE=ME-6200I/9/DIO
+
+pci:v00001402d00006359*
+ ID_PRODUCT_FROM_DATABASE=ME-6300I/9/DIO
+
+pci:v00001402d0000810A*
+ ID_PRODUCT_FROM_DATABASE=ME-8100A
+
+pci:v00001402d0000810B*
+ ID_PRODUCT_FROM_DATABASE=ME-8100B
+
+pci:v00001402d0000820A*
+ ID_PRODUCT_FROM_DATABASE=ME-8200A
+
+pci:v00001402d0000820B*
+ ID_PRODUCT_FROM_DATABASE=ME-8200B
+
+pci:v00001403*
+ ID_VENDOR_FROM_DATABASE=Ascor Inc
+
+pci:v00001404*
+ ID_VENDOR_FROM_DATABASE=Fundamental Software Inc
+
+pci:v00001405*
+ ID_VENDOR_FROM_DATABASE=Excalibur Systems Inc
+
+pci:v00001406*
+ ID_VENDOR_FROM_DATABASE=Oce' Printing Systems GmbH
+
+pci:v00001407*
+ ID_VENDOR_FROM_DATABASE=Lava Computer mfg Inc
+
+pci:v00001407d00000100*
+ ID_PRODUCT_FROM_DATABASE=Lava Dual Serial
+
+pci:v00001407d00000101*
+ ID_PRODUCT_FROM_DATABASE=Lava Quatro A
+
+pci:v00001407d00000102*
+ ID_PRODUCT_FROM_DATABASE=Lava Quatro B
+
+pci:v00001407d00000110*
+ ID_PRODUCT_FROM_DATABASE=Lava DSerial-PCI Port A
+
+pci:v00001407d00000111*
+ ID_PRODUCT_FROM_DATABASE=Lava DSerial-PCI Port B
+
+pci:v00001407d00000120*
+ ID_PRODUCT_FROM_DATABASE=Quattro-PCI A
+
+pci:v00001407d00000121*
+ ID_PRODUCT_FROM_DATABASE=Quattro-PCI B
+
+pci:v00001407d00000180*
+ ID_PRODUCT_FROM_DATABASE=Lava Octo A
+
+pci:v00001407d00000181*
+ ID_PRODUCT_FROM_DATABASE=Lava Octo B
+
+pci:v00001407d00000200*
+ ID_PRODUCT_FROM_DATABASE=Lava Port Plus
+
+pci:v00001407d00000201*
+ ID_PRODUCT_FROM_DATABASE=Lava Quad A
+
+pci:v00001407d00000202*
+ ID_PRODUCT_FROM_DATABASE=Lava Quad B
+
+pci:v00001407d00000220*
+ ID_PRODUCT_FROM_DATABASE=Lava Quattro PCI Ports A/B
+
+pci:v00001407d00000221*
+ ID_PRODUCT_FROM_DATABASE=Lava Quattro PCI Ports C/D
+
+pci:v00001407d00000400*
+ ID_PRODUCT_FROM_DATABASE=Lava 8255-PIO-PCI
+
+pci:v00001407d00000500*
+ ID_PRODUCT_FROM_DATABASE=Lava Single Serial
+
+pci:v00001407d00000520*
+ ID_PRODUCT_FROM_DATABASE=Lava RS422-SS-PCI
+
+pci:v00001407d00000600*
+ ID_PRODUCT_FROM_DATABASE=Lava Port 650
+
+pci:v00001407d00008000*
+ ID_PRODUCT_FROM_DATABASE=Lava Parallel
+
+pci:v00001407d00008001*
+ ID_PRODUCT_FROM_DATABASE=Dual parallel port controller A
+
+pci:v00001407d00008002*
+ ID_PRODUCT_FROM_DATABASE=Lava Dual Parallel port A
+
+pci:v00001407d00008003*
+ ID_PRODUCT_FROM_DATABASE=Lava Dual Parallel port B
+
+pci:v00001407d00008800*
+ ID_PRODUCT_FROM_DATABASE=BOCA Research IOPPAR
+
+pci:v00001408*
+ ID_VENDOR_FROM_DATABASE=Aloka Co. Ltd
+
+pci:v00001409*
+ ID_VENDOR_FROM_DATABASE=Timedia Technology Co Ltd
+
+pci:v00001409d00007168*
+ ID_PRODUCT_FROM_DATABASE=PCI2S550 (Dual 16550 UART)
+
+pci:v00001409d00007168sv00001409sd00000002*
+ ID_PRODUCT_FROM_DATABASE=SER4036A3V (2x RS232 port)
+
+pci:v00001409d00007168sv00001409sd00004027*
+ ID_PRODUCT_FROM_DATABASE=SER4027A (1x RS232 port)
+
+pci:v00001409d00007168sv00001409sd00004037*
+ ID_PRODUCT_FROM_DATABASE=SER4037A (2x RS232 port)
+
+pci:v00001409d00007168sv00001409sd00004056*
+ ID_PRODUCT_FROM_DATABASE=SER4056A (4x RS232)
+
+pci:v00001409d00007168sv00001409sd00005027*
+ ID_PRODUCT_FROM_DATABASE=SER4027D
+
+pci:v00001409d00007168sv00001409sd00005037*
+ ID_PRODUCT_FROM_DATABASE=SER4037D (2x RS232 port)
+
+pci:v00001409d00007168sv00001409sd00005066*
+ ID_PRODUCT_FROM_DATABASE=SER4066R (8x RS232)
+
+pci:v00001409d00007168sv00001409sd00006056*
+ ID_PRODUCT_FROM_DATABASE=SER4056D (4x RS232 port)
+
+pci:v00001409d00007268*
+ ID_PRODUCT_FROM_DATABASE=SUN1888 (Dual IEEE1284 parallel port)
+
+pci:v00001409d00007268sv00001409sd00000103*
+ ID_PRODUCT_FROM_DATABASE=PAR4008A
+
+pci:v00001409d00007268sv00001409sd00000104*
+ ID_PRODUCT_FROM_DATABASE=PAR4018A
+
+pci:v0000140A*
+ ID_VENDOR_FROM_DATABASE=DSP Research Inc
+
+pci:v0000140B*
+ ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms
+
+pci:v0000140C*
+ ID_VENDOR_FROM_DATABASE=Elmic Systems Inc
+
+pci:v0000140D*
+ ID_VENDOR_FROM_DATABASE=Matsushita Electric Works Ltd
+
+pci:v0000140E*
+ ID_VENDOR_FROM_DATABASE=Goepel Electronic GmbH
+
+pci:v0000140F*
+ ID_VENDOR_FROM_DATABASE=Salient Systems Corp
+
+pci:v00001410*
+ ID_VENDOR_FROM_DATABASE=Midas lab Inc
+
+pci:v00001411*
+ ID_VENDOR_FROM_DATABASE=Ikos Systems Inc
+
+pci:v00001412*
+ ID_VENDOR_FROM_DATABASE=VIA Technologies Inc.
+
+pci:v00001412d00001712*
+ ID_PRODUCT_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller
+
+pci:v00001412d00001712sv00001412sd00001712*
+ ID_PRODUCT_FROM_DATABASE=Hoontech ST Audio DSP 24
+
+pci:v00001412d00001712sv00001412sd00003632*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta Audiophile 192
+
+pci:v00001412d00001712sv00001412sd0000D630*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta 1010
+
+pci:v00001412d00001712sv00001412sd0000D631*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta DiO
+
+pci:v00001412d00001712sv00001412sd0000D632*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta 66
+
+pci:v00001412d00001712sv00001412sd0000D633*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta 44
+
+pci:v00001412d00001712sv00001412sd0000D634*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta Audiophile 2496
+
+pci:v00001412d00001712sv00001412sd0000D635*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta TDIF
+
+pci:v00001412d00001712sv00001412sd0000D637*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta RBUS
+
+pci:v00001412d00001712sv00001412sd0000D638*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta 410
+
+pci:v00001412d00001712sv00001412sd0000D63B*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Delta 1010LT
+
+pci:v00001412d00001712sv00001412sd0000D63C*
+ ID_PRODUCT_FROM_DATABASE=Digigram VX442
+
+pci:v00001412d00001712sv00001416sd00001712*
+ ID_PRODUCT_FROM_DATABASE=Hoontech ST Audio DSP 24 Media 7.1
+
+pci:v00001412d00001712sv0000153Bsd00001115*
+ ID_PRODUCT_FROM_DATABASE=EWS88 MT
+
+pci:v00001412d00001712sv0000153Bsd00001125*
+ ID_PRODUCT_FROM_DATABASE=EWS88 MT (Master)
+
+pci:v00001412d00001712sv0000153Bsd0000112B*
+ ID_PRODUCT_FROM_DATABASE=EWS88 D
+
+pci:v00001412d00001712sv0000153Bsd0000112C*
+ ID_PRODUCT_FROM_DATABASE=EWS88 D (Master)
+
+pci:v00001412d00001712sv0000153Bsd00001130*
+ ID_PRODUCT_FROM_DATABASE=EWX 24/96
+
+pci:v00001412d00001712sv0000153Bsd00001138*
+ ID_PRODUCT_FROM_DATABASE=DMX 6fire 24/96
+
+pci:v00001412d00001712sv0000153Bsd00001151*
+ ID_PRODUCT_FROM_DATABASE=PHASE88
+
+pci:v00001412d00001712sv000016CEsd00001040*
+ ID_PRODUCT_FROM_DATABASE=Edirol DA-2496
+
+pci:v00001412d00001724*
+ ID_PRODUCT_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller
+
+pci:v00001412d00001724sv000010B0sd00000200*
+ ID_PRODUCT_FROM_DATABASE=Hollywood@Home 7.1
+
+pci:v00001412d00001724sv00001412sd00001724*
+ ID_PRODUCT_FROM_DATABASE=Albatron PX865PE 7.1
+
+pci:v00001412d00001724sv00001412sd00003630*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Revolution 7.1
+
+pci:v00001412d00001724sv00001412sd00003631*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Revolution 5.1
+
+pci:v00001412d00001724sv0000153Bsd00001145*
+ ID_PRODUCT_FROM_DATABASE=Aureon 7.1 Space
+
+pci:v00001412d00001724sv0000153Bsd00001147*
+ ID_PRODUCT_FROM_DATABASE=Aureon 5.1 Sky
+
+pci:v00001412d00001724sv0000153Bsd00001150*
+ ID_PRODUCT_FROM_DATABASE=PHASE 22
+
+pci:v00001412d00001724sv0000153Bsd00001153*
+ ID_PRODUCT_FROM_DATABASE=Aureon 7.1 Universe
+
+pci:v00001412d00001724sv000017ABsd00001906*
+ ID_PRODUCT_FROM_DATABASE=PSC 724 [Ultimate Edge]
+
+pci:v00001412d00001724sv0000270Fsd0000F641*
+ ID_PRODUCT_FROM_DATABASE=ZNF3-150
+
+pci:v00001412d00001724sv0000270Fsd0000F645*
+ ID_PRODUCT_FROM_DATABASE=ZNF3-250
+
+pci:v00001412d00001724sv00003130sd00004154*
+ ID_PRODUCT_FROM_DATABASE=MAYA 44 MKII
+
+pci:v00001413*
+ ID_VENDOR_FROM_DATABASE=Addonics
+
+pci:v00001414*
+ ID_VENDOR_FROM_DATABASE=Microsoft Corporation
+
+pci:v00001414d00000001*
+ ID_PRODUCT_FROM_DATABASE=MN-120 (ADMtek Centaur-C based)
+
+pci:v00001414d00000002*
+ ID_PRODUCT_FROM_DATABASE=MN-130 (ADMtek Centaur-P based)
+
+pci:v00001414d00005353*
+ ID_PRODUCT_FROM_DATABASE=Hyper-V virtual VGA
+
+pci:v00001414d00005801*
+ ID_PRODUCT_FROM_DATABASE=XMA Decoder (Xenon)
+
+pci:v00001414d00005802*
+ ID_PRODUCT_FROM_DATABASE=SATA Controller - CdRom (Xenon)
+
+pci:v00001414d00005803*
+ ID_PRODUCT_FROM_DATABASE=SATA Controller - Disk (Xenon)
+
+pci:v00001414d00005804*
+ ID_PRODUCT_FROM_DATABASE=OHCI Controller 0 (Xenon)
+
+pci:v00001414d00005805*
+ ID_PRODUCT_FROM_DATABASE=EHCI Controller 0 (Xenon)
+
+pci:v00001414d00005806*
+ ID_PRODUCT_FROM_DATABASE=OHCI Controller 1 (Xenon)
+
+pci:v00001414d00005807*
+ ID_PRODUCT_FROM_DATABASE=EHCI Controller 1 (Xenon)
+
+pci:v00001414d0000580A*
+ ID_PRODUCT_FROM_DATABASE=Fast Ethernet Adapter (Xenon)
+
+pci:v00001414d0000580B*
+ ID_PRODUCT_FROM_DATABASE=Secure Flash Controller (Xenon)
+
+pci:v00001414d0000580D*
+ ID_PRODUCT_FROM_DATABASE=System Management Controller (Xenon)
+
+pci:v00001414d00005811*
+ ID_PRODUCT_FROM_DATABASE=Xenos GPU (Xenon)
+
+pci:v00001415*
+ ID_VENDOR_FROM_DATABASE=Oxford Semiconductor Ltd
+
+pci:v00001415d00008401*
+ ID_PRODUCT_FROM_DATABASE=OX9162 Mode 1 (8-bit bus)
+
+pci:v00001415d00008403*
+ ID_PRODUCT_FROM_DATABASE=OX9162 Mode 0 (parallel port)
+
+pci:v00001415d00009500*
+ ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Disabled)
+
+pci:v00001415d00009501*
+ ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart)
+
+pci:v00001415d00009501sv000012C4sd00000201*
+ ID_PRODUCT_FROM_DATABASE=Titan/cPCI (2 port)
+
+pci:v00001415d00009501sv000012C4sd00000202*
+ ID_PRODUCT_FROM_DATABASE=Titan/cPCI (4 port)
+
+pci:v00001415d00009501sv000012C4sd00000203*
+ ID_PRODUCT_FROM_DATABASE=Titan/cPCI (8 port)
+
+pci:v00001415d00009501sv000012C4sd00000210*
+ ID_PRODUCT_FROM_DATABASE=Titan/104-Plus (8 port, p1-4)
+
+pci:v00001415d00009501sv0000131Fsd00002050*
+ ID_PRODUCT_FROM_DATABASE=CyberPro (4-port)
+
+pci:v00001415d00009501sv0000131Fsd00002051*
+ ID_PRODUCT_FROM_DATABASE=CyberSerial 4S Plus
+
+pci:v00001415d00009501sv000015EDsd00002000*
+ ID_PRODUCT_FROM_DATABASE=MCCR Serial p0-3 of 8
+
+pci:v00001415d00009501sv000015EDsd00002001*
+ ID_PRODUCT_FROM_DATABASE=MCCR Serial p0-3 of 16
+
+pci:v00001415d00009505*
+ ID_PRODUCT_FROM_DATABASE=OXuPCI952 (Dual 16C950 UART)
+
+pci:v00001415d0000950A*
+ ID_PRODUCT_FROM_DATABASE=EXSYS EX-41092 Dual 16950 Serial adapter
+
+pci:v00001415d0000950B*
+ ID_PRODUCT_FROM_DATABASE=OXCB950 Cardbus 16950 UART
+
+pci:v00001415d00009510*
+ ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (Disabled)
+
+pci:v00001415d00009510sv000012C4sd00000200*
+ ID_PRODUCT_FROM_DATABASE=Titan/cPCI (Unused)
+
+pci:v00001415d00009511*
+ ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (8bit bus)
+
+pci:v00001415d00009511sv000012C4sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Titan/104-Plus (8 port, p5-8)
+
+pci:v00001415d00009511sv000015EDsd00002000*
+ ID_PRODUCT_FROM_DATABASE=MCCR Serial p4-7 of 8
+
+pci:v00001415d00009511sv000015EDsd00002001*
+ ID_PRODUCT_FROM_DATABASE=MCCR Serial p4-15 of 16
+
+pci:v00001415d00009512*
+ ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (32bit bus)
+
+pci:v00001415d00009513*
+ ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (parallel port)
+
+pci:v00001415d00009521*
+ ID_PRODUCT_FROM_DATABASE=OX16PCI952 (Dual 16950 UART)
+
+pci:v00001415d00009523*
+ ID_PRODUCT_FROM_DATABASE=OX16PCI952 Integrated Parallel Port
+
+pci:v00001415d0000C158*
+ ID_PRODUCT_FROM_DATABASE=OXPCIe952 Dual 16C950 UART
+
+pci:v00001415d0000C158sv0000E4BFsd0000C504*
+ ID_PRODUCT_FROM_DATABASE=CP4-SCAT Wireless Technologies Carrier Board
+
+pci:v00001415d0000C158sv0000E4BFsd0000D551*
+ ID_PRODUCT_FROM_DATABASE=DU1-MUSTANG Dual-Port RS-485 Interface
+
+pci:v00001415d0000C308*
+ ID_PRODUCT_FROM_DATABASE=EX-44016 16-port serial
+
+pci:v00001416*
+ ID_VENDOR_FROM_DATABASE=Multiwave Innovation pte Ltd
+
+pci:v00001417*
+ ID_VENDOR_FROM_DATABASE=Convergenet Technologies Inc
+
+pci:v00001418*
+ ID_VENDOR_FROM_DATABASE=Kyushu electronics systems Inc
+
+pci:v00001419*
+ ID_VENDOR_FROM_DATABASE=Excel Switching Corp
+
+pci:v0000141A*
+ ID_VENDOR_FROM_DATABASE=Apache Micro Peripherals Inc
+
+pci:v0000141B*
+ ID_VENDOR_FROM_DATABASE=Zoom Telephonics Inc
+
+pci:v0000141D*
+ ID_VENDOR_FROM_DATABASE=Digitan Systems Inc
+
+pci:v0000141E*
+ ID_VENDOR_FROM_DATABASE=Fanuc Ltd
+
+pci:v0000141F*
+ ID_VENDOR_FROM_DATABASE=Visiontech Ltd
+
+pci:v00001420*
+ ID_VENDOR_FROM_DATABASE=Psion Dacom plc
+
+pci:v00001420d00008002*
+ ID_PRODUCT_FROM_DATABASE=Gold Card NetGlobal 56k+10/100Mb CardBus (Ethernet part)
+
+pci:v00001420d00008003*
+ ID_PRODUCT_FROM_DATABASE=Gold Card NetGlobal 56k+10/100Mb CardBus (Modem part)
+
+pci:v00001421*
+ ID_VENDOR_FROM_DATABASE=Ads Technologies Inc
+
+pci:v00001422*
+ ID_VENDOR_FROM_DATABASE=Ygrec Systems Co Ltd
+
+pci:v00001423*
+ ID_VENDOR_FROM_DATABASE=Custom Technology Corp.
+
+pci:v00001424*
+ ID_VENDOR_FROM_DATABASE=Videoserver Connections
+
+pci:v00001425*
+ ID_VENDOR_FROM_DATABASE=Chelsio Communications Inc
+
+pci:v00001425d0000000B*
+ ID_PRODUCT_FROM_DATABASE=T210 Protocol Engine
+
+pci:v00001425d0000000C*
+ ID_PRODUCT_FROM_DATABASE=T204 Protocol Engine
+
+pci:v00001425d00000022*
+ ID_PRODUCT_FROM_DATABASE=10GbE Ethernet Adapter
+
+pci:v00001425d00000030*
+ ID_PRODUCT_FROM_DATABASE=T310 10GbE Single Port Adapter
+
+pci:v00001425d00000030sv0000103Csd0000705E*
+ ID_PRODUCT_FROM_DATABASE=PCIe 10GBase-SR [AD386A]
+
+pci:v00001425d00000031*
+ ID_PRODUCT_FROM_DATABASE=T320 10GbE Dual Port Adapter
+
+pci:v00001425d00000032*
+ ID_PRODUCT_FROM_DATABASE=T302 1GbE Dual Port Adapter
+
+pci:v00001425d00000033*
+ ID_PRODUCT_FROM_DATABASE=T304 1GbE Quad Port Adapter
+
+pci:v00001425d00000034*
+ ID_PRODUCT_FROM_DATABASE=B320 10GbE Dual Port Adapter
+
+pci:v00001425d00000035*
+ ID_PRODUCT_FROM_DATABASE=S310-CR 10GbE Single Port Adapter
+
+pci:v00001425d00000036*
+ ID_PRODUCT_FROM_DATABASE=S320-LP-CR 10GbE Dual Port Adapter
+
+pci:v00001425d00000037*
+ ID_PRODUCT_FROM_DATABASE=N320-G2-CR 10GbE Dual Port Adapter
+
+pci:v00001425d00004001*
+ ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004002*
+ ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004003*
+ ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004004*
+ ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller
+
+pci:v00001425d00004005*
+ ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller
+
+pci:v00001425d00004006*
+ ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller
+
+pci:v00001425d00004007*
+ ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller
+
+pci:v00001425d00004008*
+ ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller
+
+pci:v00001425d00004009*
+ ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000400A*
+ ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000400B*
+ ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller
+
+pci:v00001425d0000400C*
+ ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000400D*
+ ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Ethernet Controller
+
+pci:v00001425d0000400E*
+ ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004401*
+ ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004402*
+ ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004403*
+ ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004404*
+ ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller
+
+pci:v00001425d00004405*
+ ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller
+
+pci:v00001425d00004406*
+ ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller
+
+pci:v00001425d00004407*
+ ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller
+
+pci:v00001425d00004408*
+ ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller
+
+pci:v00001425d00004409*
+ ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000440A*
+ ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000440B*
+ ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller
+
+pci:v00001425d0000440C*
+ ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000440D*
+ ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Ethernet Controller
+
+pci:v00001425d0000440E*
+ ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004501*
+ ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Storage Controller
+
+pci:v00001425d00004502*
+ ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Storage Controller
+
+pci:v00001425d00004503*
+ ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Storage Controller
+
+pci:v00001425d00004504*
+ ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Storage Controller
+
+pci:v00001425d00004505*
+ ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Storage Controller
+
+pci:v00001425d00004506*
+ ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Storage Controller
+
+pci:v00001425d00004507*
+ ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Storage Controller
+
+pci:v00001425d00004508*
+ ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Storage Controller
+
+pci:v00001425d00004509*
+ ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Storage Controller
+
+pci:v00001425d0000450A*
+ ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Storage Controller
+
+pci:v00001425d0000450B*
+ ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller
+
+pci:v00001425d0000450C*
+ ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000450D*
+ ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Storage Controller
+
+pci:v00001425d0000450E*
+ ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Storage Controller
+
+pci:v00001425d00004601*
+ ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Storage Controller
+
+pci:v00001425d00004602*
+ ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Storage Controller
+
+pci:v00001425d00004603*
+ ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Storage Controller
+
+pci:v00001425d00004604*
+ ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Storage Controller
+
+pci:v00001425d00004605*
+ ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Storage Controller
+
+pci:v00001425d00004606*
+ ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Storage Controller
+
+pci:v00001425d00004607*
+ ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Storage Controller
+
+pci:v00001425d00004608*
+ ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Storage Controller
+
+pci:v00001425d00004609*
+ ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Storage Controller
+
+pci:v00001425d0000460A*
+ ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Storage Controller
+
+pci:v00001425d0000460B*
+ ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller
+
+pci:v00001425d0000460C*
+ ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000460D*
+ ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Storage Controller
+
+pci:v00001425d0000460E*
+ ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Storage Controller
+
+pci:v00001425d00004701*
+ ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004702*
+ ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004703*
+ ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004704*
+ ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller
+
+pci:v00001425d00004705*
+ ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller
+
+pci:v00001425d00004706*
+ ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller
+
+pci:v00001425d00004707*
+ ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller
+
+pci:v00001425d00004708*
+ ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller
+
+pci:v00001425d00004709*
+ ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000470A*
+ ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000470B*
+ ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller
+
+pci:v00001425d0000470C*
+ ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000470D*
+ ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Ethernet Controller
+
+pci:v00001425d0000470E*
+ ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004801*
+ ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004802*
+ ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004803*
+ ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller
+
+pci:v00001425d00004804*
+ ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller
+
+pci:v00001425d00004805*
+ ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller
+
+pci:v00001425d00004806*
+ ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller
+
+pci:v00001425d00004807*
+ ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller
+
+pci:v00001425d00004808*
+ ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller
+
+pci:v00001425d00004809*
+ ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000480A*
+ ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000480B*
+ ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller
+
+pci:v00001425d0000480C*
+ ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller
+
+pci:v00001425d0000480D*
+ ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Ethernet Controller
+
+pci:v00001425d0000480E*
+ ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller
+
+pci:v00001425d0000A000*
+ ID_PRODUCT_FROM_DATABASE=PE10K Unified Wire Ethernet Controller
+
+pci:v00001426*
+ ID_VENDOR_FROM_DATABASE=Storage Technology Corp.
+
+pci:v00001427*
+ ID_VENDOR_FROM_DATABASE=Better On-Line Solutions
+
+pci:v00001428*
+ ID_VENDOR_FROM_DATABASE=Edec Co Ltd
+
+pci:v00001429*
+ ID_VENDOR_FROM_DATABASE=Unex Technology Corp.
+
+pci:v0000142A*
+ ID_VENDOR_FROM_DATABASE=Kingmax Technology Inc
+
+pci:v0000142B*
+ ID_VENDOR_FROM_DATABASE=Radiolan
+
+pci:v0000142C*
+ ID_VENDOR_FROM_DATABASE=Minton Optic Industry Co Ltd
+
+pci:v0000142D*
+ ID_VENDOR_FROM_DATABASE=Pix stream Inc
+
+pci:v0000142E*
+ ID_VENDOR_FROM_DATABASE=Vitec Multimedia
+
+pci:v0000142Ed00004020*
+ ID_PRODUCT_FROM_DATABASE=VM2-2 [Video Maker 2] MPEG1/2 Encoder
+
+pci:v0000142Ed00004337*
+ ID_PRODUCT_FROM_DATABASE=VM2-2-C7 [Video Maker 2 rev. C7] MPEG1/2 Encoder
+
+pci:v0000142F*
+ ID_VENDOR_FROM_DATABASE=Radicom Research Inc
+
+pci:v00001430*
+ ID_VENDOR_FROM_DATABASE=ITT Aerospace/Communications Division
+
+pci:v00001431*
+ ID_VENDOR_FROM_DATABASE=Gilat Satellite Networks
+
+pci:v00001432*
+ ID_VENDOR_FROM_DATABASE=Edimax Computer Co.
+
+pci:v00001432d00009130*
+ ID_PRODUCT_FROM_DATABASE=RTL81xx Fast Ethernet
+
+pci:v00001433*
+ ID_VENDOR_FROM_DATABASE=Eltec Elektronik GmbH
+
+pci:v00001435*
+ ID_VENDOR_FROM_DATABASE=RTD Embedded Technologies, Inc.
+
+pci:v00001435d00004520*
+ ID_PRODUCT_FROM_DATABASE=PCI4520
+
+pci:v00001435d00006020*
+ ID_PRODUCT_FROM_DATABASE=SPM6020
+
+pci:v00001435d00006030*
+ ID_PRODUCT_FROM_DATABASE=SPM6030
+
+pci:v00001435d00006420*
+ ID_PRODUCT_FROM_DATABASE=SPM186420
+
+pci:v00001435d00006430*
+ ID_PRODUCT_FROM_DATABASE=SPM176430
+
+pci:v00001435d00006431*
+ ID_PRODUCT_FROM_DATABASE=SPM176431
+
+pci:v00001435d00007520*
+ ID_PRODUCT_FROM_DATABASE=DM7520
+
+pci:v00001435d00007540*
+ ID_PRODUCT_FROM_DATABASE=SDM7540
+
+pci:v00001435d00007820*
+ ID_PRODUCT_FROM_DATABASE=DM7820
+
+pci:v00001436*
+ ID_VENDOR_FROM_DATABASE=CIS Technology Inc
+
+pci:v00001437*
+ ID_VENDOR_FROM_DATABASE=Nissin Inc Co
+
+pci:v00001438*
+ ID_VENDOR_FROM_DATABASE=Atmel-dream
+
+pci:v00001439*
+ ID_VENDOR_FROM_DATABASE=Outsource Engineering & Mfg. Inc
+
+pci:v0000143A*
+ ID_VENDOR_FROM_DATABASE=Stargate Solutions Inc
+
+pci:v0000143B*
+ ID_VENDOR_FROM_DATABASE=Canon Research Center, America
+
+pci:v0000143C*
+ ID_VENDOR_FROM_DATABASE=Amlogic Inc
+
+pci:v0000143D*
+ ID_VENDOR_FROM_DATABASE=Tamarack Microelectronics Inc
+
+pci:v0000143E*
+ ID_VENDOR_FROM_DATABASE=Jones Futurex Inc
+
+pci:v0000143F*
+ ID_VENDOR_FROM_DATABASE=Lightwell Co Ltd - Zax Division
+
+pci:v00001440*
+ ID_VENDOR_FROM_DATABASE=ALGOL Corp.
+
+pci:v00001441*
+ ID_VENDOR_FROM_DATABASE=AGIE Ltd
+
+pci:v00001442*
+ ID_VENDOR_FROM_DATABASE=Phoenix Contact GmbH & Co.
+
+pci:v00001443*
+ ID_VENDOR_FROM_DATABASE=Unibrain S.A.
+
+pci:v00001444*
+ ID_VENDOR_FROM_DATABASE=TRW
+
+pci:v00001445*
+ ID_VENDOR_FROM_DATABASE=Logical DO Ltd
+
+pci:v00001446*
+ ID_VENDOR_FROM_DATABASE=Graphin Co Ltd
+
+pci:v00001447*
+ ID_VENDOR_FROM_DATABASE=AIM GmBH
+
+pci:v00001448*
+ ID_VENDOR_FROM_DATABASE=Alesis Studio Electronics
+
+pci:v00001449*
+ ID_VENDOR_FROM_DATABASE=TUT Systems Inc
+
+pci:v0000144A*
+ ID_VENDOR_FROM_DATABASE=Adlink Technology
+
+pci:v0000144Ad00006208*
+ ID_PRODUCT_FROM_DATABASE=PCI-6208V
+
+pci:v0000144Ad00007250*
+ ID_PRODUCT_FROM_DATABASE=PCI-7250
+
+pci:v0000144Ad00007296*
+ ID_PRODUCT_FROM_DATABASE=PCI-7296
+
+pci:v0000144Ad00007432*
+ ID_PRODUCT_FROM_DATABASE=PCI-7432
+
+pci:v0000144Ad00007433*
+ ID_PRODUCT_FROM_DATABASE=PCI-7433
+
+pci:v0000144Ad00007434*
+ ID_PRODUCT_FROM_DATABASE=PCI-7434
+
+pci:v0000144Ad00007841*
+ ID_PRODUCT_FROM_DATABASE=PCI-7841
+
+pci:v0000144Ad00008133*
+ ID_PRODUCT_FROM_DATABASE=PCI-8133
+
+pci:v0000144Ad00008164*
+ ID_PRODUCT_FROM_DATABASE=PCI-8164
+
+pci:v0000144Ad00008554*
+ ID_PRODUCT_FROM_DATABASE=PCI-8554
+
+pci:v0000144Ad00009111*
+ ID_PRODUCT_FROM_DATABASE=PCI-9111
+
+pci:v0000144Ad00009113*
+ ID_PRODUCT_FROM_DATABASE=PCI-9113
+
+pci:v0000144Ad00009114*
+ ID_PRODUCT_FROM_DATABASE=PCI-9114
+
+pci:v0000144B*
+ ID_VENDOR_FROM_DATABASE=Verint Systems Inc.
+
+pci:v0000144C*
+ ID_VENDOR_FROM_DATABASE=Catalina Research Inc
+
+pci:v0000144D*
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics Co Ltd
+
+pci:v0000144Dd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P35 laptop
+
+pci:v0000144Dd0000C511*
+ ID_PRODUCT_FROM_DATABASE=R20 Laptop
+
+pci:v0000144E*
+ ID_VENDOR_FROM_DATABASE=OLITEC
+
+pci:v0000144F*
+ ID_VENDOR_FROM_DATABASE=Askey Computer Corp.
+
+pci:v00001450*
+ ID_VENDOR_FROM_DATABASE=Octave Communications Ind.
+
+pci:v00001451*
+ ID_VENDOR_FROM_DATABASE=SP3D Chip Design GmBH
+
+pci:v00001453*
+ ID_VENDOR_FROM_DATABASE=MYCOM Inc
+
+pci:v00001454*
+ ID_VENDOR_FROM_DATABASE=Altiga Networks
+
+pci:v00001455*
+ ID_VENDOR_FROM_DATABASE=Logic Plus Plus Inc
+
+pci:v00001456*
+ ID_VENDOR_FROM_DATABASE=Advanced Hardware Architectures
+
+pci:v00001457*
+ ID_VENDOR_FROM_DATABASE=Nuera Communications Inc
+
+pci:v00001458*
+ ID_VENDOR_FROM_DATABASE=Giga-byte Technology
+
+pci:v00001458d00009001*
+ ID_PRODUCT_FROM_DATABASE=GC-PTV-TAF Hybrid TV card
+
+pci:v00001458d0000E911*
+ ID_PRODUCT_FROM_DATABASE=GN-WIAG02
+
+pci:v00001459*
+ ID_VENDOR_FROM_DATABASE=DOOIN Electronics
+
+pci:v0000145A*
+ ID_VENDOR_FROM_DATABASE=Escalate Networks Inc
+
+pci:v0000145B*
+ ID_VENDOR_FROM_DATABASE=PRAIM SRL
+
+pci:v0000145C*
+ ID_VENDOR_FROM_DATABASE=Cryptek
+
+pci:v0000145D*
+ ID_VENDOR_FROM_DATABASE=Gallant Computer Inc
+
+pci:v0000145E*
+ ID_VENDOR_FROM_DATABASE=Aashima Technology B.V.
+
+pci:v0000145F*
+ ID_VENDOR_FROM_DATABASE=Baldor Electric Company
+
+pci:v0000145Fd00000001*
+ ID_PRODUCT_FROM_DATABASE=NextMove PCI
+
+pci:v00001460*
+ ID_VENDOR_FROM_DATABASE=DYNARC INC
+
+pci:v00001461*
+ ID_VENDOR_FROM_DATABASE=Avermedia Technologies Inc
+
+pci:v00001461d0000A3CE*
+ ID_PRODUCT_FROM_DATABASE=M179
+
+pci:v00001461d0000A3CF*
+ ID_PRODUCT_FROM_DATABASE=M179
+
+pci:v00001461d0000A836*
+ ID_PRODUCT_FROM_DATABASE=M115 DVB-T, PAL/SECAM/NTSC Tuner
+
+pci:v00001461d0000E836*
+ ID_PRODUCT_FROM_DATABASE=M115S Hybrid Analog/DVB PAL/SECAM/NTSC Tuner
+
+pci:v00001461d0000F436*
+ ID_PRODUCT_FROM_DATABASE=AVerTV Hybrid+FM
+
+pci:v00001462*
+ ID_VENDOR_FROM_DATABASE=Micro-Star International Co., Ltd.
+
+pci:v00001462d00005501*
+ ID_PRODUCT_FROM_DATABASE=nVidia NV15DDR [GeForce2 Ti]
+
+pci:v00001462d00006819*
+ ID_PRODUCT_FROM_DATABASE=Broadcom Corporation BCM4306 802.11b/g Wireless LAN Controller [MSI CB54G]
+
+pci:v00001462d00006825*
+ ID_PRODUCT_FROM_DATABASE=PCI Card wireless 11g [PC54G]
+
+pci:v00001462d00006834*
+ ID_PRODUCT_FROM_DATABASE=RaLink RT2500 802.11g [PC54G2]
+
+pci:v00001462d00007125*
+ ID_PRODUCT_FROM_DATABASE=MS-7125 [K8N Neo4 Platinum]
+
+pci:v00001462d00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v00001462d00007242*
+ ID_PRODUCT_FROM_DATABASE=K9AGM RS485 Motherboard
+
+pci:v00001462d00007250*
+ ID_PRODUCT_FROM_DATABASE=MS-7250 Motherboard [K9N Platinum SLI/non-SLI]
+
+pci:v00001462d00007327*
+ ID_PRODUCT_FROM_DATABASE=K9AGM2-FIH Motherboard
+
+pci:v00001462d00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00001462d00008725*
+ ID_PRODUCT_FROM_DATABASE=NVIDIA NV25 [GeForce4 Ti 4600] VGA Adapter
+
+pci:v00001462d00009000*
+ ID_PRODUCT_FROM_DATABASE=NVIDIA NV28 [GeForce4 Ti 4800] VGA Adapter
+
+pci:v00001462d00009110*
+ ID_PRODUCT_FROM_DATABASE=GeFORCE FX5200
+
+pci:v00001462d00009119*
+ ID_PRODUCT_FROM_DATABASE=NVIDIA NV31 [GeForce FX 5600XT] VGA Adapter
+
+pci:v00001462d00009123*
+ ID_PRODUCT_FROM_DATABASE=NVIDIA NV31 [GeForce FX 5600] FX5600-VTDR128 [MS-8912]
+
+pci:v00001462d00009510*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600XT
+
+pci:v00001462d00009511*
+ ID_PRODUCT_FROM_DATABASE=Radeon 9600XT
+
+pci:v00001462d00009591*
+ ID_PRODUCT_FROM_DATABASE=nVidia Corporation NV36 [GeForce FX 5700LE]
+
+pci:v00001462d0000B834*
+ ID_PRODUCT_FROM_DATABASE=Wireless 11g Turbo G PCI card [MSI PC60G]
+
+pci:v00001463*
+ ID_VENDOR_FROM_DATABASE=Fast Corporation
+
+pci:v00001464*
+ ID_VENDOR_FROM_DATABASE=Interactive Circuits & Systems Ltd
+
+pci:v00001465*
+ ID_VENDOR_FROM_DATABASE=GN NETTEST Telecom DIV.
+
+pci:v00001466*
+ ID_VENDOR_FROM_DATABASE=Designpro Inc.
+
+pci:v00001467*
+ ID_VENDOR_FROM_DATABASE=DIGICOM SPA
+
+pci:v00001468*
+ ID_VENDOR_FROM_DATABASE=AMBIT Microsystem Corp.
+
+pci:v00001469*
+ ID_VENDOR_FROM_DATABASE=Cleveland Motion Controls
+
+pci:v0000146A*
+ ID_VENDOR_FROM_DATABASE=IFR
+
+pci:v0000146B*
+ ID_VENDOR_FROM_DATABASE=Parascan Technologies Ltd
+
+pci:v0000146C*
+ ID_VENDOR_FROM_DATABASE=Ruby Tech Corp.
+
+pci:v0000146Cd00001430*
+ ID_PRODUCT_FROM_DATABASE=FE-1430TX Fast Ethernet PCI Adapter
+
+pci:v0000146D*
+ ID_VENDOR_FROM_DATABASE=Tachyon, INC.
+
+pci:v0000146E*
+ ID_VENDOR_FROM_DATABASE=Williams Electronics Games, Inc.
+
+pci:v0000146F*
+ ID_VENDOR_FROM_DATABASE=Multi Dimensional Consulting Inc
+
+pci:v00001470*
+ ID_VENDOR_FROM_DATABASE=Bay Networks
+
+pci:v00001471*
+ ID_VENDOR_FROM_DATABASE=Integrated Telecom Express Inc
+
+pci:v00001472*
+ ID_VENDOR_FROM_DATABASE=DAIKIN Industries, Ltd
+
+pci:v00001473*
+ ID_VENDOR_FROM_DATABASE=ZAPEX Technologies Inc
+
+pci:v00001474*
+ ID_VENDOR_FROM_DATABASE=Doug Carson & Associates
+
+pci:v00001475*
+ ID_VENDOR_FROM_DATABASE=PICAZO Communications
+
+pci:v00001476*
+ ID_VENDOR_FROM_DATABASE=MORTARA Instrument Inc
+
+pci:v00001477*
+ ID_VENDOR_FROM_DATABASE=Net Insight
+
+pci:v00001478*
+ ID_VENDOR_FROM_DATABASE=DIATREND Corporation
+
+pci:v00001479*
+ ID_VENDOR_FROM_DATABASE=TORAY Industries Inc
+
+pci:v0000147A*
+ ID_VENDOR_FROM_DATABASE=FORMOSA Industrial Computing
+
+pci:v0000147B*
+ ID_VENDOR_FROM_DATABASE=ABIT Computer Corp.
+
+pci:v0000147Bd00001084*
+ ID_PRODUCT_FROM_DATABASE=IP35 [Dark Raider]
+
+pci:v0000147C*
+ ID_VENDOR_FROM_DATABASE=AWARE, Inc.
+
+pci:v0000147D*
+ ID_VENDOR_FROM_DATABASE=Interworks Computer Products
+
+pci:v0000147E*
+ ID_VENDOR_FROM_DATABASE=Matsushita Graphic Communication Systems, Inc.
+
+pci:v0000147F*
+ ID_VENDOR_FROM_DATABASE=NIHON UNISYS, Ltd.
+
+pci:v00001480*
+ ID_VENDOR_FROM_DATABASE=SCII Telecom
+
+pci:v00001481*
+ ID_VENDOR_FROM_DATABASE=BIOPAC Systems Inc
+
+pci:v00001482*
+ ID_VENDOR_FROM_DATABASE=ISYTEC - Integrierte Systemtechnik GmBH
+
+pci:v00001482d00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI-16 Host Interface for ITC-16
+
+pci:v00001483*
+ ID_VENDOR_FROM_DATABASE=LABWAY Corporation
+
+pci:v00001484*
+ ID_VENDOR_FROM_DATABASE=Logic Corporation
+
+pci:v00001485*
+ ID_VENDOR_FROM_DATABASE=ERMA - Electronic GmBH
+
+pci:v00001486*
+ ID_VENDOR_FROM_DATABASE=L3 Communications Telemetry & Instrumentation
+
+pci:v00001487*
+ ID_VENDOR_FROM_DATABASE=MARQUETTE Medical Systems
+
+pci:v00001488*
+ ID_VENDOR_FROM_DATABASE=KONTRON Electronik GmBH
+
+pci:v00001489*
+ ID_VENDOR_FROM_DATABASE=KYE Systems Corporation
+
+pci:v0000148A*
+ ID_VENDOR_FROM_DATABASE=OPTO
+
+pci:v0000148B*
+ ID_VENDOR_FROM_DATABASE=INNOMEDIALOGIC Inc.
+
+pci:v0000148C*
+ ID_VENDOR_FROM_DATABASE=C.P. Technology Co. Ltd
+
+pci:v0000148D*
+ ID_VENDOR_FROM_DATABASE=DIGICOM Systems, Inc.
+
+pci:v0000148Dd00001003*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v0000148E*
+ ID_VENDOR_FROM_DATABASE=OSI Plus Corporation
+
+pci:v0000148F*
+ ID_VENDOR_FROM_DATABASE=Plant Equipment, Inc.
+
+pci:v00001490*
+ ID_VENDOR_FROM_DATABASE=Stone Microsystems PTY Ltd.
+
+pci:v00001491*
+ ID_VENDOR_FROM_DATABASE=ZEAL Corporation
+
+pci:v00001492*
+ ID_VENDOR_FROM_DATABASE=Time Logic Corporation
+
+pci:v00001493*
+ ID_VENDOR_FROM_DATABASE=MAKER Communications
+
+pci:v00001494*
+ ID_VENDOR_FROM_DATABASE=WINTOP Technology, Inc.
+
+pci:v00001495*
+ ID_VENDOR_FROM_DATABASE=TOKAI Communications Industry Co. Ltd
+
+pci:v00001496*
+ ID_VENDOR_FROM_DATABASE=JOYTECH Computer Co., Ltd.
+
+pci:v00001497*
+ ID_VENDOR_FROM_DATABASE=SMA Regelsysteme GmBH
+
+pci:v00001497d00001497*
+ ID_PRODUCT_FROM_DATABASE=SMA Technologie AG
+
+pci:v00001498*
+ ID_VENDOR_FROM_DATABASE=TEWS Technologies GmbH
+
+pci:v00001498d00000330*
+ ID_PRODUCT_FROM_DATABASE=TPMC816 2 Channel CAN bus controller.
+
+pci:v00001498d0000035D*
+ ID_PRODUCT_FROM_DATABASE=TPMC861 4-Channel Isolated Serial Interface RS422/RS485
+
+pci:v00001498d00000385*
+ ID_PRODUCT_FROM_DATABASE=TPMC901 Extended CAN bus with 2/4/6 CAN controller
+
+pci:v00001498d000021CC*
+ ID_PRODUCT_FROM_DATABASE=TCP460 CompactPCI 16 Channel Serial Interface RS232/RS422
+
+pci:v00001498d000021CD*
+ ID_PRODUCT_FROM_DATABASE=TCP461 CompactPCI 8 Channel Serial Interface RS232/RS422
+
+pci:v00001498d00003064*
+ ID_PRODUCT_FROM_DATABASE=TPCI100 (2 Slot IndustryPack PCI Carrier)
+
+pci:v00001498d000030C8*
+ ID_PRODUCT_FROM_DATABASE=TPCI200
+
+pci:v00001499*
+ ID_VENDOR_FROM_DATABASE=EMTEC CO., Ltd
+
+pci:v0000149A*
+ ID_VENDOR_FROM_DATABASE=ANDOR Technology Ltd
+
+pci:v0000149B*
+ ID_VENDOR_FROM_DATABASE=SEIKO Instruments Inc
+
+pci:v0000149C*
+ ID_VENDOR_FROM_DATABASE=OVISLINK Corp.
+
+pci:v0000149D*
+ ID_VENDOR_FROM_DATABASE=NEWTEK Inc
+
+pci:v0000149Dd00000001*
+ ID_PRODUCT_FROM_DATABASE=Video Toaster for PC
+
+pci:v0000149E*
+ ID_VENDOR_FROM_DATABASE=Mapletree Networks Inc.
+
+pci:v0000149F*
+ ID_VENDOR_FROM_DATABASE=LECTRON Co Ltd
+
+pci:v000014A0*
+ ID_VENDOR_FROM_DATABASE=SOFTING GmBH
+
+pci:v000014A1*
+ ID_VENDOR_FROM_DATABASE=Systembase Co Ltd
+
+pci:v000014A2*
+ ID_VENDOR_FROM_DATABASE=Millennium Engineering Inc
+
+pci:v000014A3*
+ ID_VENDOR_FROM_DATABASE=Maverick Networks
+
+pci:v000014A4*
+ ID_VENDOR_FROM_DATABASE=Broadcom Corporation (Wrong ID)
+
+pci:v000014A4d00004318*
+ ID_PRODUCT_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller
+
+pci:v000014A5*
+ ID_VENDOR_FROM_DATABASE=XIONICS Document Technologies Inc
+
+pci:v000014A6*
+ ID_VENDOR_FROM_DATABASE=INOVA Computers GmBH & Co KG
+
+pci:v000014A7*
+ ID_VENDOR_FROM_DATABASE=MYTHOS Systems Inc
+
+pci:v000014A8*
+ ID_VENDOR_FROM_DATABASE=FEATRON Technologies Corporation
+
+pci:v000014A9*
+ ID_VENDOR_FROM_DATABASE=HIVERTEC Inc
+
+pci:v000014AA*
+ ID_VENDOR_FROM_DATABASE=Advanced MOS Technology Inc
+
+pci:v000014AB*
+ ID_VENDOR_FROM_DATABASE=Mentor Graphics Corp.
+
+pci:v000014AC*
+ ID_VENDOR_FROM_DATABASE=Novaweb Technologies Inc
+
+pci:v000014AD*
+ ID_VENDOR_FROM_DATABASE=Time Space Radio AB
+
+pci:v000014AE*
+ ID_VENDOR_FROM_DATABASE=CTI, Inc
+
+pci:v000014AF*
+ ID_VENDOR_FROM_DATABASE=Guillemot Corporation
+
+pci:v000014AFd00007102*
+ ID_PRODUCT_FROM_DATABASE=3D Prophet II MX
+
+pci:v000014B0*
+ ID_VENDOR_FROM_DATABASE=BST Communication Technology Ltd
+
+pci:v000014B1*
+ ID_VENDOR_FROM_DATABASE=Nextcom K.K.
+
+pci:v000014B2*
+ ID_VENDOR_FROM_DATABASE=ENNOVATE Networks Inc
+
+pci:v000014B3*
+ ID_VENDOR_FROM_DATABASE=XPEED Inc
+
+pci:v000014B3d00000000*
+ ID_PRODUCT_FROM_DATABASE=DSL NIC
+
+pci:v000014B4*
+ ID_VENDOR_FROM_DATABASE=PHILIPS Business Electronics B.V.
+
+pci:v000014B5*
+ ID_VENDOR_FROM_DATABASE=Creamware GmBH
+
+pci:v000014B5d00000200*
+ ID_PRODUCT_FROM_DATABASE=Scope
+
+pci:v000014B5d00000300*
+ ID_PRODUCT_FROM_DATABASE=Pulsar
+
+pci:v000014B5d00000400*
+ ID_PRODUCT_FROM_DATABASE=PulsarSRB
+
+pci:v000014B5d00000600*
+ ID_PRODUCT_FROM_DATABASE=Pulsar2
+
+pci:v000014B5d00000800*
+ ID_PRODUCT_FROM_DATABASE=DSP-Board
+
+pci:v000014B5d00000900*
+ ID_PRODUCT_FROM_DATABASE=DSP-Board
+
+pci:v000014B5d00000A00*
+ ID_PRODUCT_FROM_DATABASE=DSP-Board
+
+pci:v000014B5d00000B00*
+ ID_PRODUCT_FROM_DATABASE=DSP-Board
+
+pci:v000014B6*
+ ID_VENDOR_FROM_DATABASE=Quantum Data Corp.
+
+pci:v000014B7*
+ ID_VENDOR_FROM_DATABASE=PROXIM Inc
+
+pci:v000014B7d00000001*
+ ID_PRODUCT_FROM_DATABASE=Symphony 4110
+
+pci:v000014B8*
+ ID_VENDOR_FROM_DATABASE=Techsoft Technology Co Ltd
+
+pci:v000014B9*
+ ID_VENDOR_FROM_DATABASE=Cisco Aironet Wireless Communications
+
+pci:v000014B9d00000001*
+ ID_PRODUCT_FROM_DATABASE=PC4800
+
+pci:v000014B9d00000340*
+ ID_PRODUCT_FROM_DATABASE=PC4800
+
+pci:v000014B9d00000350*
+ ID_PRODUCT_FROM_DATABASE=350 series 802.11b Wireless LAN Adapter
+
+pci:v000014B9d00004500*
+ ID_PRODUCT_FROM_DATABASE=PC4500
+
+pci:v000014B9d00004800*
+ ID_PRODUCT_FROM_DATABASE=Cisco Aironet 340 802.11b Wireless LAN Adapter/Aironet PC4800
+
+pci:v000014B9d0000A504*
+ ID_PRODUCT_FROM_DATABASE=Cisco Aironet Wireless 802.11b
+
+pci:v000014B9d0000A505*
+ ID_PRODUCT_FROM_DATABASE=Cisco Aironet CB20a 802.11a Wireless LAN Adapter
+
+pci:v000014B9d0000A506*
+ ID_PRODUCT_FROM_DATABASE=Cisco Aironet Mini PCI b/g
+
+pci:v000014BA*
+ ID_VENDOR_FROM_DATABASE=INTERNIX Inc.
+
+pci:v000014BAd00000600*
+ ID_PRODUCT_FROM_DATABASE=ARC-PCI/22
+
+pci:v000014BB*
+ ID_VENDOR_FROM_DATABASE=SEMTECH Corporation
+
+pci:v000014BC*
+ ID_VENDOR_FROM_DATABASE=Globespan Semiconductor Inc.
+
+pci:v000014BCd0000D002*
+ ID_PRODUCT_FROM_DATABASE=Pulsar [PCI ADSL Card]
+
+pci:v000014BCd0000D00F*
+ ID_PRODUCT_FROM_DATABASE=Pulsar [PCI ADSL Card]
+
+pci:v000014BD*
+ ID_VENDOR_FROM_DATABASE=CARDIO Control N.V.
+
+pci:v000014BE*
+ ID_VENDOR_FROM_DATABASE=L3 Communications
+
+pci:v000014BF*
+ ID_VENDOR_FROM_DATABASE=SPIDER Communications Inc.
+
+pci:v000014C0*
+ ID_VENDOR_FROM_DATABASE=COMPAL Electronics Inc
+
+pci:v000014C1*
+ ID_VENDOR_FROM_DATABASE=MYRICOM Inc.
+
+pci:v000014C1d00000008*
+ ID_PRODUCT_FROM_DATABASE=Myri-10G Dual-Protocol NIC
+
+pci:v000014C1d00000008sv000014C1sd00000008*
+ ID_PRODUCT_FROM_DATABASE=10G-PCIE-8A
+
+pci:v000014C1d00000008sv000014C1sd00000009*
+ ID_PRODUCT_FROM_DATABASE=10G-PCIE-8A (MSI-X firmware)
+
+pci:v000014C1d00000008sv000014C1sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=10G-PCIE-8B
+
+pci:v000014C1d00008043*
+ ID_PRODUCT_FROM_DATABASE=Myrinet 2000 Scalable Cluster Interconnect
+
+pci:v000014C1d00008043sv0000103Csd00001240*
+ ID_PRODUCT_FROM_DATABASE=Myrinet M2L-PCI64/2-3.0 LANai 7.4 (HP OEM)
+
+pci:v000014C2*
+ ID_VENDOR_FROM_DATABASE=DTK Computer
+
+pci:v000014C3*
+ ID_VENDOR_FROM_DATABASE=MEDIATEK Corp.
+
+pci:v000014C4*
+ ID_VENDOR_FROM_DATABASE=IWASAKI Information Systems Co Ltd
+
+pci:v000014C5*
+ ID_VENDOR_FROM_DATABASE=Automation Products AB
+
+pci:v000014C6*
+ ID_VENDOR_FROM_DATABASE=Data Race Inc
+
+pci:v000014C7*
+ ID_VENDOR_FROM_DATABASE=Modular Technology Holdings Ltd
+
+pci:v000014C8*
+ ID_VENDOR_FROM_DATABASE=Turbocomm Tech. Inc.
+
+pci:v000014C9*
+ ID_VENDOR_FROM_DATABASE=ODIN Telesystems Inc
+
+pci:v000014CA*
+ ID_VENDOR_FROM_DATABASE=PE Logic Corp.
+
+pci:v000014CB*
+ ID_VENDOR_FROM_DATABASE=Billionton Systems Inc
+
+pci:v000014CC*
+ ID_VENDOR_FROM_DATABASE=NAKAYO Telecommunications Inc
+
+pci:v000014CD*
+ ID_VENDOR_FROM_DATABASE=Universal Scientific Ind.
+
+pci:v000014CE*
+ ID_VENDOR_FROM_DATABASE=Whistle Communications
+
+pci:v000014CF*
+ ID_VENDOR_FROM_DATABASE=TEK Microsystems Inc.
+
+pci:v000014D0*
+ ID_VENDOR_FROM_DATABASE=Ericsson Axe R & D
+
+pci:v000014D1*
+ ID_VENDOR_FROM_DATABASE=Computer Hi-Tech Co Ltd
+
+pci:v000014D2*
+ ID_VENDOR_FROM_DATABASE=Titan Electronics Inc
+
+pci:v000014D2d00008001*
+ ID_PRODUCT_FROM_DATABASE=VScom 010L 1 port parallel adaptor
+
+pci:v000014D2d00008002*
+ ID_PRODUCT_FROM_DATABASE=VScom 020L 2 port parallel adaptor
+
+pci:v000014D2d00008010*
+ ID_PRODUCT_FROM_DATABASE=VScom 100L 1 port serial adaptor
+
+pci:v000014D2d00008011*
+ ID_PRODUCT_FROM_DATABASE=VScom 110L 1 port serial and 1 port parallel adaptor
+
+pci:v000014D2d00008020*
+ ID_PRODUCT_FROM_DATABASE=VScom 200L 1 or 2 port serial adaptor
+
+pci:v000014D2d00008021*
+ ID_PRODUCT_FROM_DATABASE=VScom 210L 2 port serial and 1 port parallel adaptor
+
+pci:v000014D2d00008028*
+ ID_PRODUCT_FROM_DATABASE=VScom 200I/200I-SI 2-port serial adapter
+
+pci:v000014D2d00008040*
+ ID_PRODUCT_FROM_DATABASE=VScom 400L 4 port serial adaptor
+
+pci:v000014D2d00008043*
+ ID_PRODUCT_FROM_DATABASE=VScom 430L 4-port serial and 3-port parallel adapter
+
+pci:v000014D2d00008048*
+ ID_PRODUCT_FROM_DATABASE=VScom 400I 4-port serial adapter
+
+pci:v000014D2d00008080*
+ ID_PRODUCT_FROM_DATABASE=VScom 800L 8 port serial adaptor
+
+pci:v000014D2d00008088*
+ ID_PRODUCT_FROM_DATABASE=VScom 800I 8-port serial adapter
+
+pci:v000014D2d0000A000*
+ ID_PRODUCT_FROM_DATABASE=VScom 010H 1 port parallel adaptor
+
+pci:v000014D2d0000A001*
+ ID_PRODUCT_FROM_DATABASE=VScom 100H 1 port serial adaptor
+
+pci:v000014D2d0000A003*
+ ID_PRODUCT_FROM_DATABASE=VScom 400H 4 port serial adaptor
+
+pci:v000014D2d0000A004*
+ ID_PRODUCT_FROM_DATABASE=VScom 400HF1 4 port serial adaptor
+
+pci:v000014D2d0000A005*
+ ID_PRODUCT_FROM_DATABASE=VScom 200H 2 port serial adaptor
+
+pci:v000014D2d0000A007*
+ ID_PRODUCT_FROM_DATABASE=VScom PCI800EH (PCIe) 8-port serial adapter Port 1-4
+
+pci:v000014D2d0000A008*
+ ID_PRODUCT_FROM_DATABASE=VScom PCI800EH (PCIe) 8-port serial adapter Port 5-8
+
+pci:v000014D2d0000A009*
+ ID_PRODUCT_FROM_DATABASE=VScom PCI400EH (PCIe) 4-port serial adapter
+
+pci:v000014D2d0000E001*
+ ID_PRODUCT_FROM_DATABASE=VScom 010HV2 1 port parallel adaptor
+
+pci:v000014D2d0000E010*
+ ID_PRODUCT_FROM_DATABASE=VScom 100HV2 1 port serial adaptor
+
+pci:v000014D2d0000E020*
+ ID_PRODUCT_FROM_DATABASE=VScom 200HV2 2 port serial adaptor
+
+pci:v000014D3*
+ ID_VENDOR_FROM_DATABASE=CIRTECH (UK) Ltd
+
+pci:v000014D4*
+ ID_VENDOR_FROM_DATABASE=Panacom Technology Corp
+
+pci:v000014D5*
+ ID_VENDOR_FROM_DATABASE=Nitsuko Corporation
+
+pci:v000014D6*
+ ID_VENDOR_FROM_DATABASE=Accusys Inc
+
+pci:v000014D6d00006101*
+ ID_PRODUCT_FROM_DATABASE=ACS-61xxx, PCIe to SAS/SATA RAID HBA
+
+pci:v000014D6d00006201*
+ ID_PRODUCT_FROM_DATABASE=ACS-62xxx, External PCIe to SAS/SATA RAID controller
+
+pci:v000014D7*
+ ID_VENDOR_FROM_DATABASE=Hirakawa Hewtech Corp
+
+pci:v000014D8*
+ ID_VENDOR_FROM_DATABASE=HOPF Elektronik GmBH
+
+pci:v000014D9*
+ ID_VENDOR_FROM_DATABASE=Alliance Semiconductor Corporation
+
+pci:v000014D9d00000010*
+ ID_PRODUCT_FROM_DATABASE=AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon]
+
+pci:v000014D9d00009000*
+ ID_PRODUCT_FROM_DATABASE=AS90L10204/10208 HyperTransport to PCI-X Bridge
+
+pci:v000014DA*
+ ID_VENDOR_FROM_DATABASE=National Aerospace Laboratories
+
+pci:v000014DB*
+ ID_VENDOR_FROM_DATABASE=AFAVLAB Technology Inc
+
+pci:v000014DBd00002120*
+ ID_PRODUCT_FROM_DATABASE=TK9902
+
+pci:v000014DBd00002182*
+ ID_PRODUCT_FROM_DATABASE=AFAVLAB Technology Inc. 8-port serial card
+
+pci:v000014DC*
+ ID_VENDOR_FROM_DATABASE=Amplicon Liveline Ltd
+
+pci:v000014DCd00000000*
+ ID_PRODUCT_FROM_DATABASE=PCI230
+
+pci:v000014DCd00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI242
+
+pci:v000014DCd00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI244
+
+pci:v000014DCd00000003*
+ ID_PRODUCT_FROM_DATABASE=PCI247
+
+pci:v000014DCd00000004*
+ ID_PRODUCT_FROM_DATABASE=PCI248
+
+pci:v000014DCd00000005*
+ ID_PRODUCT_FROM_DATABASE=PCI249
+
+pci:v000014DCd00000006*
+ ID_PRODUCT_FROM_DATABASE=PCI260
+
+pci:v000014DCd00000007*
+ ID_PRODUCT_FROM_DATABASE=PCI224
+
+pci:v000014DCd00000008*
+ ID_PRODUCT_FROM_DATABASE=PCI234
+
+pci:v000014DCd00000009*
+ ID_PRODUCT_FROM_DATABASE=PCI236
+
+pci:v000014DCd0000000A*
+ ID_PRODUCT_FROM_DATABASE=PCI272
+
+pci:v000014DCd0000000B*
+ ID_PRODUCT_FROM_DATABASE=PCI215
+
+pci:v000014DD*
+ ID_VENDOR_FROM_DATABASE=Boulder Design Labs Inc
+
+pci:v000014DE*
+ ID_VENDOR_FROM_DATABASE=Applied Integration Corporation
+
+pci:v000014DF*
+ ID_VENDOR_FROM_DATABASE=ASIC Communications Corp
+
+pci:v000014E1*
+ ID_VENDOR_FROM_DATABASE=INVERTEX
+
+pci:v000014E2*
+ ID_VENDOR_FROM_DATABASE=INFOLIBRIA
+
+pci:v000014E3*
+ ID_VENDOR_FROM_DATABASE=AMTELCO
+
+pci:v000014E4*
+ ID_VENDOR_FROM_DATABASE=Broadcom Corporation
+
+pci:v000014E4d00000576*
+ ID_PRODUCT_FROM_DATABASE=BCM43224 802.11a/b/g/n
+
+pci:v000014E4d00000800*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 Chipcommon I/O Controller
+
+pci:v000014E4d00000804*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 PCI Bridge
+
+pci:v000014E4d00000805*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 MIPS32 CPU
+
+pci:v000014E4d00000806*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 Ethernet Controller
+
+pci:v000014E4d0000080B*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 Crypto Accelerator
+
+pci:v000014E4d0000080F*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 DDR/SDR RAM Controller
+
+pci:v000014E4d00000811*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 External Interface Core
+
+pci:v000014E4d00000816*
+ ID_PRODUCT_FROM_DATABASE=BCM3302 Sentry5 MIPS32 CPU
+
+pci:v000014E4d00001600*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5752 Gigabit Ethernet PCI Express
+
+pci:v000014E4d00001600sv00001028sd000001C1*
+ ID_PRODUCT_FROM_DATABASE=Precision 490
+
+pci:v000014E4d00001600sv00001028sd000001C2*
+ ID_PRODUCT_FROM_DATABASE=Latitude D620
+
+pci:v000014E4d00001600sv0000103Csd00003015*
+ ID_PRODUCT_FROM_DATABASE=PCIe LAN on Motherboard
+
+pci:v000014E4d00001600sv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500 Onboard
+
+pci:v000014E4d00001600sv00001259sd00002705*
+ ID_PRODUCT_FROM_DATABASE=AT-2711FX
+
+pci:v000014E4d00001601*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5752M Gigabit Ethernet PCI Express
+
+pci:v000014E4d00001612*
+ ID_PRODUCT_FROM_DATABASE=BCM70012 Video Decoder [Crystal HD]
+
+pci:v000014E4d00001615*
+ ID_PRODUCT_FROM_DATABASE=BCM70015 Video Decoder [Crystal HD]
+
+pci:v000014E4d00001639*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet
+
+pci:v000014E4d00001639sv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 BCM5709 Gigabit Ethernet
+
+pci:v000014E4d00001639sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 BCM5709 Gigabit Ethernet
+
+pci:v000014E4d00001639sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 BCM5709 Gigabit Ethernet
+
+pci:v000014E4d00001639sv0000103Csd00007055*
+ ID_PRODUCT_FROM_DATABASE=NC382i Integrated Multi-port PCI Express Gigabit Server Adapter
+
+pci:v000014E4d00001639sv0000103Csd00007059*
+ ID_PRODUCT_FROM_DATABASE=NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter
+
+pci:v000014E4d00001639sv000010A9sd00008027*
+ ID_PRODUCT_FROM_DATABASE=Quad port Gigabit Ethernet Controller
+
+pci:v000014E4d0000163A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5709S Gigabit Ethernet
+
+pci:v000014E4d0000163Asv00001028sd0000027B*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M805 Broadcom NetXtreme II BCM5709S
+
+pci:v000014E4d0000163Asv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 BCM5709S Gigabit Ethernet
+
+pci:v000014E4d0000163Asv0000103Csd0000171D*
+ ID_PRODUCT_FROM_DATABASE=NC382m Dual Port 1GbE Multifunction BL-c Adapter
+
+pci:v000014E4d0000163Asv0000103Csd00007056*
+ ID_PRODUCT_FROM_DATABASE=NC382i Integrated Quad Port PCI Express Gigabit Server Adapter
+
+pci:v000014E4d0000163B*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5716 Gigabit Ethernet
+
+pci:v000014E4d0000163Bsv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 BCM5716 Gigabit Ethernet
+
+pci:v000014E4d0000163Bsv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 BCM5716 Gigabit Ethernet
+
+pci:v000014E4d0000163Bsv00001028sd000002F1*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R510 BCM5716 Gigabit Ethernet
+
+pci:v000014E4d0000163C*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5716S Gigabit Ethernet
+
+pci:v000014E4d0000163D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57811 10-Gigabit Ethernet
+
+pci:v000014E4d0000163E*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57811 10 Gigabit Ethernet Multi Function
+
+pci:v000014E4d0000163F*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57811 10-Gigabit Ethernet Virtual Function
+
+pci:v000014E4d00001641*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57787 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001642*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57764 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001643*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5725 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001644*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet
+
+pci:v000014E4d00001644sv00001014sd00000277*
+ ID_PRODUCT_FROM_DATABASE=Broadcom Vigil B5700 1000Base-T
+
+pci:v000014E4d00001644sv00001028sd000000D1*
+ ID_PRODUCT_FROM_DATABASE=Broadcom BCM5700
+
+pci:v000014E4d00001644sv00001028sd00000106*
+ ID_PRODUCT_FROM_DATABASE=Broadcom BCM5700
+
+pci:v000014E4d00001644sv00001028sd00000109*
+ ID_PRODUCT_FROM_DATABASE=Broadcom BCM5700 1000Base-T
+
+pci:v000014E4d00001644sv00001028sd0000010A*
+ ID_PRODUCT_FROM_DATABASE=Broadcom BCM5700 1000BaseTX
+
+pci:v000014E4d00001644sv000010B7sd00001000*
+ ID_PRODUCT_FROM_DATABASE=3C996-T 1000Base-T
+
+pci:v000014E4d00001644sv000010B7sd00001001*
+ ID_PRODUCT_FROM_DATABASE=3C996B-T 1000Base-T
+
+pci:v000014E4d00001644sv000010B7sd00001002*
+ ID_PRODUCT_FROM_DATABASE=3C996C-T 1000Base-T
+
+pci:v000014E4d00001644sv000010B7sd00001003*
+ ID_PRODUCT_FROM_DATABASE=3C997-T 1000Base-T Dual Port
+
+pci:v000014E4d00001644sv000010B7sd00001004*
+ ID_PRODUCT_FROM_DATABASE=3C996-SX 1000Base-SX
+
+pci:v000014E4d00001644sv000010B7sd00001005*
+ ID_PRODUCT_FROM_DATABASE=3C997-SX 1000Base-SX Dual Port
+
+pci:v000014E4d00001644sv000010B7sd00001008*
+ ID_PRODUCT_FROM_DATABASE=3C942 Gigabit LOM (31X31)
+
+pci:v000014E4d00001644sv000014E4sd00000002*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme 1000Base-SX
+
+pci:v000014E4d00001644sv000014E4sd00000003*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme 1000Base-SX
+
+pci:v000014E4d00001644sv000014E4sd00000004*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme 1000Base-T
+
+pci:v000014E4d00001644sv000014E4sd00001028*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme 1000BaseTX
+
+pci:v000014E4d00001644sv000014E4sd00001644*
+ ID_PRODUCT_FROM_DATABASE=BCM5700 1000Base-T
+
+pci:v000014E4d00001645*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet
+
+pci:v000014E4d00001645sv00000E11sd0000007C*
+ ID_PRODUCT_FROM_DATABASE=NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+
+pci:v000014E4d00001645sv00000E11sd0000007D*
+ ID_PRODUCT_FROM_DATABASE=NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
+
+pci:v000014E4d00001645sv00000E11sd00000085*
+ ID_PRODUCT_FROM_DATABASE=NC7780 Gigabit Server Adapter (embedded, WOL)
+
+pci:v000014E4d00001645sv00000E11sd00000099*
+ ID_PRODUCT_FROM_DATABASE=NC7780 Gigabit Server Adapter (embedded, WOL)
+
+pci:v000014E4d00001645sv00000E11sd0000009A*
+ ID_PRODUCT_FROM_DATABASE=NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+
+pci:v000014E4d00001645sv00000E11sd000000C1*
+ ID_PRODUCT_FROM_DATABASE=NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
+
+pci:v000014E4d00001645sv00001028sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Broadcom BCM5701 1000Base-T
+
+pci:v000014E4d00001645sv0000103Csd0000128A*
+ ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T (HP, OEM 3COM)
+
+pci:v000014E4d00001645sv0000103Csd0000128B*
+ ID_PRODUCT_FROM_DATABASE=1000Base-SX (PCI) [A7073A]
+
+pci:v000014E4d00001645sv0000103Csd000012A4*
+ ID_PRODUCT_FROM_DATABASE=Core Lan 1000Base-T
+
+pci:v000014E4d00001645sv0000103Csd000012C1*
+ ID_PRODUCT_FROM_DATABASE=IOX Core Lan 1000Base-T [A7109AX]
+
+pci:v000014E4d00001645sv0000103Csd00001300*
+ ID_PRODUCT_FROM_DATABASE=Core LAN/SCSI Combo [A6794A]
+
+pci:v000014E4d00001645sv000010A9sd00008010*
+ ID_PRODUCT_FROM_DATABASE=IO9/IO10 Gigabit Ethernet (Copper)
+
+pci:v000014E4d00001645sv000010A9sd00008011*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet (Copper)
+
+pci:v000014E4d00001645sv000010A9sd00008012*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet (Fiber)
+
+pci:v000014E4d00001645sv000010B7sd00001004*
+ ID_PRODUCT_FROM_DATABASE=3C996-SX 1000Base-SX
+
+pci:v000014E4d00001645sv000010B7sd00001006*
+ ID_PRODUCT_FROM_DATABASE=3C996B-T 1000Base-T
+
+pci:v000014E4d00001645sv000010B7sd00001007*
+ ID_PRODUCT_FROM_DATABASE=3C1000-T 1000Base-T
+
+pci:v000014E4d00001645sv000010B7sd00001008*
+ ID_PRODUCT_FROM_DATABASE=3C940-BR01 1000Base-T
+
+pci:v000014E4d00001645sv000014E4sd00000001*
+ ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T
+
+pci:v000014E4d00001645sv000014E4sd00000005*
+ ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T
+
+pci:v000014E4d00001645sv000014E4sd00000006*
+ ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T
+
+pci:v000014E4d00001645sv000014E4sd00000007*
+ ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-SX
+
+pci:v000014E4d00001645sv000014E4sd00000008*
+ ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T
+
+pci:v000014E4d00001645sv000014E4sd00001645*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet
+
+pci:v000014E4d00001645sv000014E4sd00008008*
+ ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T
+
+pci:v000014E4d00001646*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5702 Gigabit Ethernet
+
+pci:v000014E4d00001646sv00000E11sd000000BB*
+ ID_PRODUCT_FROM_DATABASE=NC7760 1000BaseTX
+
+pci:v000014E4d00001646sv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Broadcom BCM5702 1000BaseTX
+
+pci:v000014E4d00001646sv000014E4sd00008009*
+ ID_PRODUCT_FROM_DATABASE=BCM5702 1000BaseTX
+
+pci:v000014E4d00001647*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet
+
+pci:v000014E4d00001647sv00000E11sd00000099*
+ ID_PRODUCT_FROM_DATABASE=NC7780 1000BaseTX
+
+pci:v000014E4d00001647sv00000E11sd0000009A*
+ ID_PRODUCT_FROM_DATABASE=NC7770 1000BaseTX
+
+pci:v000014E4d00001647sv000010A9sd00008010*
+ ID_PRODUCT_FROM_DATABASE=SGI IO9 Gigabit Ethernet (Copper)
+
+pci:v000014E4d00001647sv000014E4sd00000009*
+ ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseTX
+
+pci:v000014E4d00001647sv000014E4sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseSX
+
+pci:v000014E4d00001647sv000014E4sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseTX
+
+pci:v000014E4d00001647sv000014E4sd00008009*
+ ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseTX
+
+pci:v000014E4d00001647sv000014E4sd0000800A*
+ ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseTX
+
+pci:v000014E4d00001648*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet
+
+pci:v000014E4d00001648sv00000E11sd000000CF*
+ ID_PRODUCT_FROM_DATABASE=NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+
+pci:v000014E4d00001648sv00000E11sd000000D0*
+ ID_PRODUCT_FROM_DATABASE=NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+
+pci:v000014E4d00001648sv00000E11sd000000D1*
+ ID_PRODUCT_FROM_DATABASE=NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+
+pci:v000014E4d00001648sv00001028sd0000014A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1750
+
+pci:v000014E4d00001648sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Broadcom NetXtreme BCM5704
+
+pci:v000014E4d00001648sv0000103Csd0000310F*
+ ID_PRODUCT_FROM_DATABASE=NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+
+pci:v000014E4d00001648sv000010A9sd00008013*
+ ID_PRODUCT_FROM_DATABASE=Dual Port Gigabit Ethernet (PCI-X,Copper)
+
+pci:v000014E4d00001648sv000010A9sd00008018*
+ ID_PRODUCT_FROM_DATABASE=Dual Port Gigabit Ethernet (A330)
+
+pci:v000014E4d00001648sv000010A9sd0000801A*
+ ID_PRODUCT_FROM_DATABASE=Dual Port Gigabit Ethernet (IA-blade)
+
+pci:v000014E4d00001648sv000010A9sd0000801B*
+ ID_PRODUCT_FROM_DATABASE=Quad Port Gigabit Ethernet (PCI-E,Copper)
+
+pci:v000014E4d00001648sv000010B7sd00002000*
+ ID_PRODUCT_FROM_DATABASE=3C998-T Dual Port 10/100/1000 PCI-X
+
+pci:v000014E4d00001648sv000010B7sd00003000*
+ ID_PRODUCT_FROM_DATABASE=3C999-T Quad Port 10/100/1000 PCI-X
+
+pci:v000014E4d00001648sv00001166sd00001648*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme CIOB-E 1000Base-T
+
+pci:v000014E4d00001648sv00001734sd0000100B*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard LAN
+
+pci:v000014E4d00001649*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5704S_2 Gigabit Ethernet
+
+pci:v000014E4d0000164A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5706 Gigabit Ethernet
+
+pci:v000014E4d0000164Asv0000103Csd00001709*
+ ID_PRODUCT_FROM_DATABASE=NC371i Integrated PCI-X Multifunction Gigabit Server Adapter
+
+pci:v000014E4d0000164Asv0000103Csd00003070*
+ ID_PRODUCT_FROM_DATABASE=NC380T PCI Express Dual Port Multifunction Gigabit Server Adapter
+
+pci:v000014E4d0000164Asv0000103Csd00003101*
+ ID_PRODUCT_FROM_DATABASE=NC370T MultifuNCtion Gigabit Server Adapter
+
+pci:v000014E4d0000164Asv0000103Csd00003106*
+ ID_PRODUCT_FROM_DATABASE=NC370i Multifunction Gigabit Server Adapter
+
+pci:v000014E4d0000164C*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet
+
+pci:v000014E4d0000164Csv00001028sd000001F0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R900 Broadcom NetXtreme II BCM5708
+
+pci:v000014E4d0000164Csv00001028sd00000205*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 Broadcom NetXtreme II BCM5708
+
+pci:v000014E4d0000164Csv00001028sd0000020B*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T605 Broadcom NetXtreme II BCM5708
+
+pci:v000014E4d0000164Csv00001028sd00000221*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805 Broadcom NetXtreme II BCM5708
+
+pci:v000014E4d0000164Csv00001028sd00000223*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R905 Broadcom NetXtreme II BCM5708
+
+pci:v000014E4d0000164Csv00001028sd00001F12*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R805/R905 Broadcom NetXtreme II BCM5708
+
+pci:v000014E4d0000164Csv0000103Csd00007037*
+ ID_PRODUCT_FROM_DATABASE=NC373T PCI Express Multifunction Gigabit Server Adapter
+
+pci:v000014E4d0000164Csv0000103Csd00007038*
+ ID_PRODUCT_FROM_DATABASE=NC373i Integrated Multifunction Gigabit Server Adapter
+
+pci:v000014E4d0000164Csv0000103Csd00007045*
+ ID_PRODUCT_FROM_DATABASE=NC374m PCI Express Dual Port Multifunction Gigabit Server Adapter
+
+pci:v000014E4d0000164D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5702FE Gigabit Ethernet
+
+pci:v000014E4d0000164E*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57710 10-Gigabit PCIe [Everest]
+
+pci:v000014E4d0000164Esv0000103Csd0000171C*
+ ID_PRODUCT_FROM_DATABASE=NC532m Dual Port 10GbE Multifunction BL-C Adapter
+
+pci:v000014E4d0000164Esv0000103Csd00007058*
+ ID_PRODUCT_FROM_DATABASE=NC532i Dual Port 10GbE Multifunction BL-C Adapter
+
+pci:v000014E4d0000164F*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57711 10-Gigabit PCIe
+
+pci:v000014E4d00001650*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57711E 10-Gigabit PCIe
+
+pci:v000014E4d00001650sv0000103Csd0000171C*
+ ID_PRODUCT_FROM_DATABASE=NC532m Dual Port 10GbE Multifunction BL-C Adapter
+
+pci:v000014E4d00001650sv0000103Csd00007058*
+ ID_PRODUCT_FROM_DATABASE=NC532i Dual Port 10GbE Multifunction BL-C Adapter
+
+pci:v000014E4d00001653*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5705 Gigabit Ethernet
+
+pci:v000014E4d00001653sv00000E11sd000000E3*
+ ID_PRODUCT_FROM_DATABASE=NC7761 Gigabit Server Adapter
+
+pci:v000014E4d00001654*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5705_2 Gigabit Ethernet
+
+pci:v000014E4d00001654sv00000E11sd000000E3*
+ ID_PRODUCT_FROM_DATABASE=NC7761 Gigabit Server Adapter
+
+pci:v000014E4d00001654sv0000103Csd00003100*
+ ID_PRODUCT_FROM_DATABASE=NC1020 ProLiant Gigabit Server Adapter 32 PCI
+
+pci:v000014E4d00001654sv0000103Csd00003226*
+ ID_PRODUCT_FROM_DATABASE=NC150T 4-port Gigabit Combo Switch & Adapter
+
+pci:v000014E4d00001655*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5717 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001656*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5718 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001657*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5719 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001659*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express
+
+pci:v000014E4d00001659sv00001014sd000002C6*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v000014E4d00001659sv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v000014E4d00001659sv00001028sd0000023C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R200 Broadcom NetXtreme BCM5721
+
+pci:v000014E4d00001659sv0000103Csd0000170B*
+ ID_PRODUCT_FROM_DATABASE=NC320m PCI Express Dual Port Gigabit Server Adapter
+
+pci:v000014E4d00001659sv0000103Csd00007031*
+ ID_PRODUCT_FROM_DATABASE=NC320T PCIe Gigabit Server Adapter
+
+pci:v000014E4d00001659sv0000103Csd00007032*
+ ID_PRODUCT_FROM_DATABASE=NC320i PCIe Gigabit Server Adapter
+
+pci:v000014E4d00001659sv00001734sd00001061*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard LAN
+
+pci:v000014E4d0000165A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express
+
+pci:v000014E4d0000165Asv00001014sd00000378*
+ ID_PRODUCT_FROM_DATABASE=IBM System x3350 (Machine type 4192)
+
+pci:v000014E4d0000165Asv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300 Broadcom NetXtreme 5722
+
+pci:v000014E4d0000165Asv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 Broadcom NetXtreme 5722
+
+pci:v000014E4d0000165Asv00001028sd00000225*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Broadcom NetXtreme 5722
+
+pci:v000014E4d0000165Asv0000103Csd00007051*
+ ID_PRODUCT_FROM_DATABASE=NC105i PCIe Gigabit Server Adapter
+
+pci:v000014E4d0000165Asv0000103Csd00007052*
+ ID_PRODUCT_FROM_DATABASE=NC105T PCIe Gigabit Server Adapter
+
+pci:v000014E4d0000165B*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5723 Gigabit Ethernet PCIe
+
+pci:v000014E4d0000165Bsv0000103Csd0000705D*
+ ID_PRODUCT_FROM_DATABASE=NC107i Integrated PCI Express Gigabit Server Adapter
+
+pci:v000014E4d0000165C*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5724 Gigabit Ethernet PCIe
+
+pci:v000014E4d0000165D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5705M Gigabit Ethernet
+
+pci:v000014E4d0000165Dsv00001028sd0000865D*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v000014E4d0000165Dsv000014E4sd0000165D*
+ ID_PRODUCT_FROM_DATABASE=Dell Latitude D600
+
+pci:v000014E4d0000165E*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5705M_2 Gigabit Ethernet
+
+pci:v000014E4d0000165Esv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v000014E4d0000165Esv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v000014E4d0000165Esv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v000014E4d0000165Esv000010CFsd00001279*
+ ID_PRODUCT_FROM_DATABASE=LifeBook E8010D
+
+pci:v000014E4d0000165F*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001662*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57712 10 Gigabit Ethernet
+
+pci:v000014E4d00001663*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57712 10 Gigabit Ethernet Multi Function
+
+pci:v000014E4d00001665*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5717 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001668*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5714 Gigabit Ethernet
+
+pci:v000014E4d00001668sv0000103Csd00007039*
+ ID_PRODUCT_FROM_DATABASE=NC324i PCIe Dual Port Gigabit Server Adapter
+
+pci:v000014E4d00001669*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme 5714S Gigabit Ethernet
+
+pci:v000014E4d0000166A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5780 Gigabit Ethernet
+
+pci:v000014E4d0000166Asv0000103Csd00007035*
+ ID_PRODUCT_FROM_DATABASE=NC325i Integrated Dual port PCIe Express Gigabit Server Adapter
+
+pci:v000014E4d0000166B*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5780S Gigabit Ethernet
+
+pci:v000014E4d0000166E*
+ ID_PRODUCT_FROM_DATABASE=570x 10/100 Integrated Controller
+
+pci:v000014E4d0000166F*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57712 10 Gigabit Ethernet Virtual Function
+
+pci:v000014E4d00001672*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5754M Gigabit Ethernet PCI Express
+
+pci:v000014E4d00001673*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5755M Gigabit Ethernet PCI Express
+
+pci:v000014E4d00001674*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5756ME Gigabit Ethernet PCI Express
+
+pci:v000014E4d00001677*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express
+
+pci:v000014E4d00001677sv00001028sd00000176*
+ ID_PRODUCT_FROM_DATABASE=Dimension XPS Gen 4
+
+pci:v000014E4d00001677sv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v000014E4d00001677sv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v000014E4d00001677sv00001028sd00000182*
+ ID_PRODUCT_FROM_DATABASE=Latitude D610
+
+pci:v000014E4d00001677sv00001028sd00000187*
+ ID_PRODUCT_FROM_DATABASE=Precision M70
+
+pci:v000014E4d00001677sv00001028sd000001A8*
+ ID_PRODUCT_FROM_DATABASE=Precision 380
+
+pci:v000014E4d00001677sv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v000014E4d00001677sv0000103Csd00003006*
+ ID_PRODUCT_FROM_DATABASE=DC7100 SFF(DX878AV)
+
+pci:v000014E4d00001677sv00001462sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v000014E4d00001677sv00001734sd0000105D*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v000014E4d00001678*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5715 Gigabit Ethernet
+
+pci:v000014E4d00001678sv0000103Csd0000703E*
+ ID_PRODUCT_FROM_DATABASE=NC326i PCIe Dual Port Gigabit Server Adapter
+
+pci:v000014E4d00001679*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5715S Gigabit Ethernet
+
+pci:v000014E4d00001679sv0000103Csd00001707*
+ ID_PRODUCT_FROM_DATABASE=NC326m PCIe Dual Port Adapter
+
+pci:v000014E4d00001679sv0000103Csd0000170C*
+ ID_PRODUCT_FROM_DATABASE=NC325m PCIe Quad Port Adapter
+
+pci:v000014E4d00001679sv0000103Csd0000703C*
+ ID_PRODUCT_FROM_DATABASE=NC326i PCIe Dual Port Gigabit Server Adapter
+
+pci:v000014E4d0000167A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5754 Gigabit Ethernet PCI Express
+
+pci:v000014E4d0000167Asv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v000014E4d0000167Asv00001028sd000001DE*
+ ID_PRODUCT_FROM_DATABASE=Precision 390
+
+pci:v000014E4d0000167Asv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v000014E4d0000167Asv00001028sd00000214*
+ ID_PRODUCT_FROM_DATABASE=Precision T3400
+
+pci:v000014E4d0000167Asv00001028sd0000021E*
+ ID_PRODUCT_FROM_DATABASE=Precision T5400
+
+pci:v000014E4d0000167B*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5755 Gigabit Ethernet PCI Express
+
+pci:v000014E4d0000167Bsv0000103Csd0000280A*
+ ID_PRODUCT_FROM_DATABASE=DC5750 Microtower
+
+pci:v000014E4d0000167D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express
+
+pci:v000014E4d0000167Dsv00001014sd00000577*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad Z60t
+
+pci:v000014E4d0000167Dsv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=HP nx8220
+
+pci:v000014E4d0000167Dsv0000103Csd00000940*
+ ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+
+pci:v000014E4d0000167Dsv000017AAsd00002081*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R60e
+
+pci:v000014E4d0000167E*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5751F Fast Ethernet PCI Express
+
+pci:v000014E4d0000167F*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5787F Fast Ethernet PCI Express
+
+pci:v000014E4d00001680*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5761e Gigabit Ethernet PCIe
+
+pci:v000014E4d00001681*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5761 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001682*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57762 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001683*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57767 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001684*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5764M Gigabit Ethernet PCIe
+
+pci:v000014E4d00001685*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57500S Gigabit Ethernet
+
+pci:v000014E4d00001686*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57766 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001687*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5762 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001688*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5761 10/100/1000BASE-T Ethernet
+
+pci:v000014E4d00001688sv00001259sd00002708*
+ ID_PRODUCT_FROM_DATABASE=AT-2712 FX
+
+pci:v000014E4d0000168A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet
+
+pci:v000014E4d0000168Asv00001028sd00001F5C*
+ ID_PRODUCT_FROM_DATABASE=BCM57800 10-Gigabit Ethernet
+
+pci:v000014E4d0000168Asv00001028sd00001F5D*
+ ID_PRODUCT_FROM_DATABASE=BCM57800 10-Gigabit Ethernet
+
+pci:v000014E4d0000168Asv00001028sd00001F67*
+ ID_PRODUCT_FROM_DATABASE=BCM57800 1-Gigabit Ethernet
+
+pci:v000014E4d0000168Asv00001028sd00001F68*
+ ID_PRODUCT_FROM_DATABASE=BCM57800 1-Gigabit Ethernet
+
+pci:v000014E4d0000168D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet
+
+pci:v000014E4d0000168E*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet
+
+pci:v000014E4d0000168Esv0000103Csd00001798*
+ ID_PRODUCT_FROM_DATABASE=Flex-10 10Gb 2-port 530FLB Adapter [Meru]
+
+pci:v000014E4d00001690*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57760 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001691*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM57788 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001691sv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v000014E4d00001692*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM57780 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001692sv00001025sd0000033D*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v000014E4d00001693*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express
+
+pci:v000014E4d00001693sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v000014E4d00001693sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=6710b
+
+pci:v000014E4d00001694*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM57790 Gigabit Ethernet PCIe
+
+pci:v000014E4d00001696*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5782 Gigabit Ethernet
+
+pci:v000014E4d00001696sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A)
+
+pci:v000014E4d00001696sv000014E4sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5782 1000Base-T
+
+pci:v000014E4d00001698*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5784M Gigabit Ethernet PCIe
+
+pci:v000014E4d00001699*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5785 Gigabit Ethernet
+
+pci:v000014E4d0000169A*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5786 Gigabit Ethernet PCI Express
+
+pci:v000014E4d0000169B*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5787 Gigabit Ethernet PCI Express
+
+pci:v000014E4d0000169C*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5788 Gigabit Ethernet
+
+pci:v000014E4d0000169Csv0000103Csd0000308B*
+ ID_PRODUCT_FROM_DATABASE=MX6125
+
+pci:v000014E4d0000169Csv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v000014E4d0000169Csv0000144Dsd0000C018*
+ ID_PRODUCT_FROM_DATABASE=X20
+
+pci:v000014E4d0000169Csv00001462sd0000590C*
+ ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+
+pci:v000014E4d0000169D*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5789 Gigabit Ethernet PCI Express
+
+pci:v000014E4d000016A0*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5785 Fast Ethernet
+
+pci:v000014E4d000016A1*
+ ID_PRODUCT_FROM_DATABASE=BCM57840 NetXtreme II 10 Gigabit Ethernet
+
+pci:v000014E4d000016A2*
+ ID_PRODUCT_FROM_DATABASE=BCM57840 NetXtreme II 10/20-Gigabit Ethernet
+
+pci:v000014E4d000016A4*
+ ID_PRODUCT_FROM_DATABASE=BCM57840 NetXtreme II Ethernet Multi Function
+
+pci:v000014E4d000016A5*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Multi Function
+
+pci:v000014E4d000016A5sv00001028sd00001F5C*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Multi Function
+
+pci:v000014E4d000016A5sv00001028sd00001F5D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Multi Function
+
+pci:v000014E4d000016A5sv00001028sd00001F67*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Multi Function
+
+pci:v000014E4d000016A5sv00001028sd00001F68*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Multi Function
+
+pci:v000014E4d000016A6*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5702X Gigabit Ethernet
+
+pci:v000014E4d000016A6sv00000E11sd000000BB*
+ ID_PRODUCT_FROM_DATABASE=NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+
+pci:v000014E4d000016A6sv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T
+
+pci:v000014E4d000016A6sv000014E4sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T
+
+pci:v000014E4d000016A6sv000014E4sd00008009*
+ ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T
+
+pci:v000014E4d000016A7*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet
+
+pci:v000014E4d000016A7sv00000E11sd000000CA*
+ ID_PRODUCT_FROM_DATABASE=NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+
+pci:v000014E4d000016A7sv00000E11sd000000CB*
+ ID_PRODUCT_FROM_DATABASE=NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+
+pci:v000014E4d000016A7sv00001014sd0000026F*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v000014E4d000016A7sv000014E4sd00000009*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-T
+
+pci:v000014E4d000016A7sv000014E4sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-SX
+
+pci:v000014E4d000016A7sv000014E4sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-T
+
+pci:v000014E4d000016A7sv000014E4sd0000800A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-T
+
+pci:v000014E4d000016A8*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5704S Gigabit Ethernet
+
+pci:v000014E4d000016A8sv0000103Csd0000132B*
+ ID_PRODUCT_FROM_DATABASE=PCI-X 1000Mbps Dual-port Built-in
+
+pci:v000014E4d000016A8sv000010A9sd00008014*
+ ID_PRODUCT_FROM_DATABASE=Dual Port Gigabit Ethernet (PCI-X,Fiber)
+
+pci:v000014E4d000016A8sv000010A9sd0000801C*
+ ID_PRODUCT_FROM_DATABASE=Quad Port Gigabit Ethernet (PCI-E,Fiber)
+
+pci:v000014E4d000016A8sv000010B7sd00002001*
+ ID_PRODUCT_FROM_DATABASE=3C998-SX Dual Port 1000-SX PCI-X
+
+pci:v000014E4d000016A9*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Virtual Function
+
+pci:v000014E4d000016A9sv00001028sd00001F5C*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Virtual Function
+
+pci:v000014E4d000016A9sv00001028sd00001F5D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Virtual Function
+
+pci:v000014E4d000016A9sv00001028sd00001F67*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Virtual Function
+
+pci:v000014E4d000016A9sv00001028sd00001F68*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Virtual Function
+
+pci:v000014E4d000016AA*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5706S Gigabit Ethernet
+
+pci:v000014E4d000016AAsv0000103Csd00003102*
+ ID_PRODUCT_FROM_DATABASE=NC370F MultifuNCtion Gigabit Server Adapter
+
+pci:v000014E4d000016AAsv0000103Csd0000310C*
+ ID_PRODUCT_FROM_DATABASE=NC370i Multifunction Gigabit Server Adapter
+
+pci:v000014E4d000016AB*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet Multi Function
+
+pci:v000014E4d000016AC*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet
+
+pci:v000014E4d000016ACsv00001014sd00000304*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet
+
+pci:v000014E4d000016ACsv00001028sd000001BB*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 Broadcom NetXtreme II BCM5708S
+
+pci:v000014E4d000016ACsv00001028sd0000020C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M605 Broadcom NetXtreme II BCM5708S
+
+pci:v000014E4d000016ACsv0000103Csd00001706*
+ ID_PRODUCT_FROM_DATABASE=NC373m Multifunction Gigabit Server Adapter
+
+pci:v000014E4d000016ACsv0000103Csd00007038*
+ ID_PRODUCT_FROM_DATABASE=NC373i PCI Express Multifunction Gigabit Server Adapter
+
+pci:v000014E4d000016ACsv0000103Csd0000703B*
+ ID_PRODUCT_FROM_DATABASE=NC373i Integrated Multifunction Gigabit Server Adapter
+
+pci:v000014E4d000016ACsv0000103Csd0000703D*
+ ID_PRODUCT_FROM_DATABASE=NC373F PCI Express Multifunction Gigabit Server Adapter
+
+pci:v000014E4d000016AD*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet Virtual Function
+
+pci:v000014E4d000016AE*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function
+
+pci:v000014E4d000016AF*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function
+
+pci:v000014E4d000016B0*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57761 Gigabit Ethernet PCIe
+
+pci:v000014E4d000016B1*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM57781 Gigabit Ethernet PCIe
+
+pci:v000014E4d000016B2*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM57791 Gigabit Ethernet PCIe
+
+pci:v000014E4d000016B3*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57786 Gigabit Ethernet PCIe
+
+pci:v000014E4d000016B4*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57765 Gigabit Ethernet PCIe
+
+pci:v000014E4d000016B5*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM57785 Gigabit Ethernet PCIe
+
+pci:v000014E4d000016B6*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM57795 Gigabit Ethernet PCIe
+
+pci:v000014E4d000016B7*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57782 Gigabit Ethernet PCIe
+
+pci:v000014E4d000016BC*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57765 Memory Card Reader
+
+pci:v000014E4d000016C6*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5702A3 Gigabit Ethernet
+
+pci:v000014E4d000016C6sv000010B7sd00001100*
+ ID_PRODUCT_FROM_DATABASE=3C1000B-T 10/100/1000 PCI
+
+pci:v000014E4d000016C6sv000014E4sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T
+
+pci:v000014E4d000016C6sv000014E4sd00008009*
+ ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T
+
+pci:v000014E4d000016C7*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet
+
+pci:v000014E4d000016C7sv00000E11sd000000CA*
+ ID_PRODUCT_FROM_DATABASE=NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+
+pci:v000014E4d000016C7sv00000E11sd000000CB*
+ ID_PRODUCT_FROM_DATABASE=NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+
+pci:v000014E4d000016C7sv0000103Csd000012C3*
+ ID_PRODUCT_FROM_DATABASE=Combo FC/GigE-SX [A9782A]
+
+pci:v000014E4d000016C7sv0000103Csd000012CA*
+ ID_PRODUCT_FROM_DATABASE=Combo FC/GigE-T [A9784A]
+
+pci:v000014E4d000016C7sv0000103Csd00001321*
+ ID_PRODUCT_FROM_DATABASE=Core I/O LAN/SCSI Combo [AB314A]
+
+pci:v000014E4d000016C7sv000014E4sd00000009*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-T
+
+pci:v000014E4d000016C7sv000014E4sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-SX
+
+pci:v000014E4d000016DD*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5781 Gigabit Ethernet PCI Express
+
+pci:v000014E4d000016F7*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5753 Gigabit Ethernet PCI Express
+
+pci:v000014E4d000016FD*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5753M Gigabit Ethernet PCI Express
+
+pci:v000014E4d000016FDsv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v000014E4d000016FDsv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v000014E4d000016FE*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5753F Fast Ethernet PCI Express
+
+pci:v000014E4d0000170C*
+ ID_PRODUCT_FROM_DATABASE=BCM4401-B0 100Base-TX
+
+pci:v000014E4d0000170Csv00001028sd00000188*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop
+
+pci:v000014E4d0000170Csv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v000014E4d0000170Csv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v000014E4d0000170Csv00001028sd000001AF*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 6400
+
+pci:v000014E4d0000170Csv00001028sd000001CD*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 9400 Laptop
+
+pci:v000014E4d0000170Csv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v000014E4d0000170Csv00001028sd000001D8*
+ ID_PRODUCT_FROM_DATABASE=Inspiron E1405
+
+pci:v000014E4d0000170Csv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v000014E4d0000170Csv0000103Csd000030A2*
+ ID_PRODUCT_FROM_DATABASE=NX7300 laptop
+
+pci:v000014E4d0000170Csv000014E4sd0000170C*
+ ID_PRODUCT_FROM_DATABASE=HP Compaq 6720t Mobile Thin Client
+
+pci:v000014E4d0000170D*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5901 100Base-TX
+
+pci:v000014E4d0000170Dsv00001014sd00000545*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40e
+
+pci:v000014E4d0000170E*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5901 100Base-TX
+
+pci:v000014E4d00001712*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5906 Fast Ethernet PCI Express
+
+pci:v000014E4d00001713*
+ ID_PRODUCT_FROM_DATABASE=NetLink BCM5906M Fast Ethernet PCI Express
+
+pci:v000014E4d00001713sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v000014E4d00001713sv00001028sd00000209*
+ ID_PRODUCT_FROM_DATABASE=XPS M1330
+
+pci:v000014E4d00001713sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v000014E4d00001713sv000017AAsd00003A23*
+ ID_PRODUCT_FROM_DATABASE=IdeaPad S10e
+
+pci:v000014E4d00003352*
+ ID_PRODUCT_FROM_DATABASE=BCM3352
+
+pci:v000014E4d00003360*
+ ID_PRODUCT_FROM_DATABASE=BCM3360
+
+pci:v000014E4d00004210*
+ ID_PRODUCT_FROM_DATABASE=BCM4210 iLine10 HomePNA 2.0
+
+pci:v000014E4d00004211*
+ ID_PRODUCT_FROM_DATABASE=BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem
+
+pci:v000014E4d00004212*
+ ID_PRODUCT_FROM_DATABASE=BCM4212 v.90 56k modem
+
+pci:v000014E4d00004220*
+ ID_PRODUCT_FROM_DATABASE=802-11b/g Wireless PCI controller, packaged as a Linksys WPC54G ver 1.2 PCMCIA card
+
+pci:v000014E4d00004222*
+ ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5753M Gigabit Ethernet PCI Express
+
+pci:v000014E4d00004301*
+ ID_PRODUCT_FROM_DATABASE=BCM4301 802.11b Wireless LAN Controller
+
+pci:v000014E4d00004301sv00001028sd00000407*
+ ID_PRODUCT_FROM_DATABASE=TrueMobile 1180 Onboard WLAN
+
+pci:v000014E4d00004301sv00001043sd00000120*
+ ID_PRODUCT_FROM_DATABASE=WL-103b Wireless LAN PC Card
+
+pci:v000014E4d00004301sv000016A5sd00001602*
+ ID_PRODUCT_FROM_DATABASE=B-300 802.11b Wireless CardBus Adapter
+
+pci:v000014E4d00004301sv00001737sd00004301*
+ ID_PRODUCT_FROM_DATABASE=WMP11 v2.7 802.11b Wireless-B PCI Adapter
+
+pci:v000014E4d00004305*
+ ID_PRODUCT_FROM_DATABASE=BCM4307 V.90 56k Modem
+
+pci:v000014E4d00004306*
+ ID_PRODUCT_FROM_DATABASE=BCM4306 802.11bg Wireless LAN controller
+
+pci:v000014E4d00004307*
+ ID_PRODUCT_FROM_DATABASE=BCM4306 802.11bg Wireless LAN Controller
+
+pci:v000014E4d00004310*
+ ID_PRODUCT_FROM_DATABASE=BCM4310 Chipcommon I/OController
+
+pci:v000014E4d00004311*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g WLAN
+
+pci:v000014E4d00004311sv00001028sd00000007*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1390 WLAN Mini-Card
+
+pci:v000014E4d00004311sv00001028sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1390 WLAN ExpressCard
+
+pci:v000014E4d00004311sv0000103Csd00001363*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004311sv0000103Csd00001364*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004311sv0000103Csd00001365*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004311sv0000103Csd00001374*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004311sv0000103Csd00001375*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004311sv0000103Csd00001376*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004311sv0000103Csd00001377*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004311sv0000103Csd0000137F*
+ ID_PRODUCT_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller
+
+pci:v000014E4d00004311sv0000103Csd00001380*
+ ID_PRODUCT_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller
+
+pci:v000014E4d00004311sv000014E4sd00004311*
+ ID_PRODUCT_FROM_DATABASE=BCM94311MCG
+
+pci:v000014E4d00004312*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11a/b/g
+
+pci:v000014E4d00004312sv00001028sd00000007*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1490 Dual Band WLAN Mini-Card
+
+pci:v000014E4d00004312sv00001028sd00000008*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1490 Dual Band WLAN ExpressCard
+
+pci:v000014E4d00004312sv0000103Csd0000135A*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd0000135F*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd00001360*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd00001361*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd00001362*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd00001370*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd00001371*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd00001372*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd00001373*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004312sv0000103Csd000030B5*
+ ID_PRODUCT_FROM_DATABASE=Presario V3242AU
+
+pci:v000014E4d00004312sv00001371sd0000103C*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11 Multiband-netwerkadapter(6715s)
+
+pci:v000014E4d00004313*
+ ID_PRODUCT_FROM_DATABASE=BCM4311 802.11a
+
+pci:v000014E4d00004315*
+ ID_PRODUCT_FROM_DATABASE=BCM4312 802.11b/g LP-PHY
+
+pci:v000014E4d00004315sv00001028sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1395 WLAN Mini-Card
+
+pci:v000014E4d00004315sv00001028sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1397 WLAN Mini-Card
+
+pci:v000014E4d00004315sv0000103Csd0000137C*
+ ID_PRODUCT_FROM_DATABASE=BCM4312 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004315sv0000103Csd0000137D*
+ ID_PRODUCT_FROM_DATABASE=BCM4312 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004315sv0000103Csd00001507*
+ ID_PRODUCT_FROM_DATABASE=U98Z049.00 Wireless Mini PCIe Card
+
+pci:v000014E4d00004315sv0000105Bsd0000E003*
+ ID_PRODUCT_FROM_DATABASE=T77H030.00 Wireless Mini PCIe Card
+
+pci:v000014E4d00004315sv0000105Bsd0000E01B*
+ ID_PRODUCT_FROM_DATABASE=T77H106.00 Wireless Half-size Mini PCIe Card
+
+pci:v000014E4d00004318*
+ ID_PRODUCT_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller
+
+pci:v000014E4d00004318sv00001028sd00000005*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1370 WLAN Mini-PCI Card
+
+pci:v000014E4d00004318sv00001028sd00000006*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1370 WLAN PC Card
+
+pci:v000014E4d00004318sv0000103Csd00001355*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN
+
+pci:v000014E4d00004318sv0000103Csd00001356*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN
+
+pci:v000014E4d00004318sv0000103Csd00001357*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN
+
+pci:v000014E4d00004318sv00001043sd0000100F*
+ ID_PRODUCT_FROM_DATABASE=WL-138G v2 / WL-138gE / WL-100gE
+
+pci:v000014E4d00004318sv00001043sd0000120F*
+ ID_PRODUCT_FROM_DATABASE=A6U notebook embedded card
+
+pci:v000014E4d00004318sv00001154sd00000355*
+ ID_PRODUCT_FROM_DATABASE=Buffalo WLI2-PCI-G54S High Speed Mode Wireless Adapter
+
+pci:v000014E4d00004318sv00001468sd00000311*
+ ID_PRODUCT_FROM_DATABASE=Aspire 3022WLMi, 5024WLMi, 5020
+
+pci:v000014E4d00004318sv00001468sd00000312*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 2410
+
+pci:v000014E4d00004318sv000014E4sd00000449*
+ ID_PRODUCT_FROM_DATABASE=Gateway 7510GX
+
+pci:v000014E4d00004318sv000016ECsd00000119*
+ ID_PRODUCT_FROM_DATABASE=U.S.Robotics Wireless MAXg PC Card
+
+pci:v000014E4d00004318sv00001737sd00000042*
+ ID_PRODUCT_FROM_DATABASE=WMP54GS v1.1 802.11g Wireless-G PCI Adapter with SpeedBooster
+
+pci:v000014E4d00004318sv00001737sd00000048*
+ ID_PRODUCT_FROM_DATABASE=WPC54G v3 802.11g Wireless-G Notebook Adapter
+
+pci:v000014E4d00004318sv00001737sd00000049*
+ ID_PRODUCT_FROM_DATABASE=WPC54GS v2 802.11g Wireless-G Notebook Adapter with SpeedBooster
+
+pci:v000014E4d00004318sv00001799sd00007000*
+ ID_PRODUCT_FROM_DATABASE=F5D7000 v4000 Wireless G Desktop Card
+
+pci:v000014E4d00004318sv00001799sd00007001*
+ ID_PRODUCT_FROM_DATABASE=F5D7001 v2000 Wireless G Plus Desktop Card
+
+pci:v000014E4d00004318sv00001799sd00007010*
+ ID_PRODUCT_FROM_DATABASE=F5D7010 v4000 Wireless G Notebook Card
+
+pci:v000014E4d00004318sv00001799sd00007011*
+ ID_PRODUCT_FROM_DATABASE=F5D7011 v2000 High-Speed Mode Wireless G Notebook Card
+
+pci:v000014E4d00004319*
+ ID_PRODUCT_FROM_DATABASE=BCM4318 [AirForce 54g] 802.11a/b/g PCI Express Transceiver
+
+pci:v000014E4d00004319sv00001028sd00000005*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1470 Dual Band WLAN Mini-PCI Card
+
+pci:v000014E4d00004319sv00001028sd00000006*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1470 Dual Band WLAN PC Card
+
+pci:v000014E4d00004319sv0000103Csd00001358*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004319sv0000103Csd00001359*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004319sv0000103Csd0000135A*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004320*
+ ID_PRODUCT_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller
+
+pci:v000014E4d00004320sv00001028sd00000001*
+ ID_PRODUCT_FROM_DATABASE=TrueMobile 1300 WLAN Mini-PCI Card
+
+pci:v000014E4d00004320sv00001028sd00000002*
+ ID_PRODUCT_FROM_DATABASE=TrueMobile 1300 WLAN PC Card
+
+pci:v000014E4d00004320sv00001028sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1350 WLAN Mini-PCI Card
+
+pci:v000014E4d00004320sv00001028sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1350 WLAN PC Card
+
+pci:v000014E4d00004320sv0000103Csd000012F4*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN
+
+pci:v000014E4d00004320sv0000103Csd000012F8*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN
+
+pci:v000014E4d00004320sv0000103Csd000012FA*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN
+
+pci:v000014E4d00004320sv0000103Csd000012FB*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN
+
+pci:v000014E4d00004320sv00001043sd0000100F*
+ ID_PRODUCT_FROM_DATABASE=WL-100G
+
+pci:v000014E4d00004320sv00001057sd00007025*
+ ID_PRODUCT_FROM_DATABASE=WN825G
+
+pci:v000014E4d00004320sv0000106Bsd0000004E*
+ ID_PRODUCT_FROM_DATABASE=AirPort Extreme
+
+pci:v000014E4d00004320sv00001154sd00000330*
+ ID_PRODUCT_FROM_DATABASE=Buffalo WLI2-PCI-G54S High Speed Mode Wireless Desktop Adapter
+
+pci:v000014E4d00004320sv0000144Fsd00007050*
+ ID_PRODUCT_FROM_DATABASE=eMachines M6805 802.11g Built-in Wireless
+
+pci:v000014E4d00004320sv0000144Fsd00007051*
+ ID_PRODUCT_FROM_DATABASE=Sonnet Aria Extreme PCI
+
+pci:v000014E4d00004320sv00001737sd00000013*
+ ID_PRODUCT_FROM_DATABASE=WMP54G v1 802.11g PCI Adapter
+
+pci:v000014E4d00004320sv00001737sd00000014*
+ ID_PRODUCT_FROM_DATABASE=WMP54G v2 802.11g PCI Adapter
+
+pci:v000014E4d00004320sv00001737sd00000015*
+ ID_PRODUCT_FROM_DATABASE=WMP54GS v1.0 802.11g Wireless-G PCI Adapter with SpeedBooster
+
+pci:v000014E4d00004320sv00001737sd00004320*
+ ID_PRODUCT_FROM_DATABASE=WPC54G v1 / WPC54GS v1 802.11g Wireless-G Notebook Adapter
+
+pci:v000014E4d00004320sv00001799sd00007000*
+ ID_PRODUCT_FROM_DATABASE=F5D7000 v1000 Wireless G Desktop Card
+
+pci:v000014E4d00004320sv00001799sd00007001*
+ ID_PRODUCT_FROM_DATABASE=F5D7001 v1000 Wireless G Plus Desktop Card
+
+pci:v000014E4d00004320sv00001799sd00007010*
+ ID_PRODUCT_FROM_DATABASE=F5D7010 v1000 Wireless G Notebook Card
+
+pci:v000014E4d00004320sv00001799sd00007011*
+ ID_PRODUCT_FROM_DATABASE=F5D7011 v1000 High-Speed Mode Wireless G Notebook Card
+
+pci:v000014E4d00004320sv0000185Fsd00001220*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290E WLAN Mini-PCI Card
+
+pci:v000014E4d00004321*
+ ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a Wireless Network Controller
+
+pci:v000014E4d00004322*
+ ID_PRODUCT_FROM_DATABASE=BCM4322 802.11bgn Wireless Network Controller
+
+pci:v000014E4d00004324*
+ ID_PRODUCT_FROM_DATABASE=BCM4306 802.11a/b/g
+
+pci:v000014E4d00004324sv00001028sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Truemobile 1400
+
+pci:v000014E4d00004324sv00001028sd00000002*
+ ID_PRODUCT_FROM_DATABASE=TrueMobile 1400 Dual Band WLAN PC Card
+
+pci:v000014E4d00004324sv00001028sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Truemobile 1450 MiniPCI
+
+pci:v000014E4d00004324sv00001028sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1450 Dual Band WLAN PC Card
+
+pci:v000014E4d00004324sv0000103Csd000012F9*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004324sv0000103Csd000012FC*
+ ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+
+pci:v000014E4d00004325*
+ ID_PRODUCT_FROM_DATABASE=BCM4306 802.11bg Wireless Network Controller
+
+pci:v000014E4d00004325sv00001414sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Wireless Notebook Adapter MN-720
+
+pci:v000014E4d00004325sv00001414sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Wireless PCI Adapter MN-730
+
+pci:v000014E4d00004326*
+ ID_PRODUCT_FROM_DATABASE=BCM4307 Chipcommon I/O Controller?
+
+pci:v000014E4d00004328*
+ ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n
+
+pci:v000014E4d00004328sv00001028sd00000009*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1500 Draft 802.11n WLAN Mini-Card
+
+pci:v000014E4d00004328sv00001028sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1500 Draft 802.11n WLAN Mini-card
+
+pci:v000014E4d00004328sv0000103Csd00001366*
+ ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller
+
+pci:v000014E4d00004328sv0000103Csd00001367*
+ ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller
+
+pci:v000014E4d00004328sv0000103Csd00001368*
+ ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller
+
+pci:v000014E4d00004328sv0000103Csd00001369*
+ ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller
+
+pci:v000014E4d00004328sv000014E4sd00004328*
+ ID_PRODUCT_FROM_DATABASE=BCM4328 802.11a/b/g/n
+
+pci:v000014E4d00004328sv00001737sd00000066*
+ ID_PRODUCT_FROM_DATABASE=WPC600N v1 802.11a/b/g/n Wireless-N CardBus Adapter
+
+pci:v000014E4d00004328sv00001737sd00000068*
+ ID_PRODUCT_FROM_DATABASE=WEC600N v1 802.11a/b/g/n Wireless-N ExpressCard
+
+pci:v000014E4d00004329*
+ ID_PRODUCT_FROM_DATABASE=BCM4321 802.11b/g/n
+
+pci:v000014E4d00004329sv00001385sd00007B00*
+ ID_PRODUCT_FROM_DATABASE=WN511B RangeMax NEXT Wireless Notebook Adapter
+
+pci:v000014E4d00004329sv00001385sd00007D00*
+ ID_PRODUCT_FROM_DATABASE=WN311B RangeMax Next 270 Mbps Wireless PCI Adapter
+
+pci:v000014E4d00004329sv00001737sd00000058*
+ ID_PRODUCT_FROM_DATABASE=WPC300N v1 Wireless-N Notebook Adapter
+
+pci:v000014E4d0000432A*
+ ID_PRODUCT_FROM_DATABASE=BCM4321 802.11an Wireless Network Controller
+
+pci:v000014E4d0000432B*
+ ID_PRODUCT_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller
+
+pci:v000014E4d0000432Bsv00001028sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1510 Wireless-N WLAN Mini-Card
+
+pci:v000014E4d0000432Bsv0000106Bsd0000008E*
+ ID_PRODUCT_FROM_DATABASE=AirPort Extreme
+
+pci:v000014E4d0000432C*
+ ID_PRODUCT_FROM_DATABASE=BCM4322 802.11b/g/n
+
+pci:v000014E4d0000432Csv00001799sd0000D311*
+ ID_PRODUCT_FROM_DATABASE=Dynex DX-NNBX 802.11n WLAN Cardbus Card
+
+pci:v000014E4d0000432D*
+ ID_PRODUCT_FROM_DATABASE=BCM4322 802.11an Wireless Network Controller
+
+pci:v000014E4d00004331*
+ ID_PRODUCT_FROM_DATABASE=BCM4331 802.11a/b/g/n
+
+pci:v000014E4d00004331sv0000106Bsd000000D6*
+ ID_PRODUCT_FROM_DATABASE=AirPort Extreme
+
+pci:v000014E4d00004333*
+ ID_PRODUCT_FROM_DATABASE=Serial (EDGE/GPRS modem part of Option GT Combo Edge)
+
+pci:v000014E4d00004344*
+ ID_PRODUCT_FROM_DATABASE=EDGE/GPRS data and 802.11b/g combo cardbus [GC89]
+
+pci:v000014E4d00004353*
+ ID_PRODUCT_FROM_DATABASE=BCM43224 802.11a/b/g/n
+
+pci:v000014E4d00004353sv00001028sd0000000E*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1520 Half-size Mini PCIe Card
+
+pci:v000014E4d00004353sv0000103Csd00001509*
+ ID_PRODUCT_FROM_DATABASE=WMIB-275N Half-size Mini PCIe Card
+
+pci:v000014E4d00004357*
+ ID_PRODUCT_FROM_DATABASE=BCM43225 802.11b/g/n
+
+pci:v000014E4d00004357sv0000105Bsd0000E021*
+ ID_PRODUCT_FROM_DATABASE=T77H103.00 Wireless Half-size Mini PCIe Card
+
+pci:v000014E4d00004358*
+ ID_PRODUCT_FROM_DATABASE=BCM43227 802.11b/g/n
+
+pci:v000014E4d00004359*
+ ID_PRODUCT_FROM_DATABASE=BCM43228 802.11a/b/g/n
+
+pci:v000014E4d00004359sv00001028sd00000011*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1530 Half-size Mini PCIe Card
+
+pci:v000014E4d00004359sv0000103Csd0000182C*
+ ID_PRODUCT_FROM_DATABASE=BCM943228HM4L 802.11a/b/g/n 2x2 Wi-Fi Adapter
+
+pci:v000014E4d00004365*
+ ID_PRODUCT_FROM_DATABASE=BCM43142 802.11b/g/n
+
+pci:v000014E4d00004365sv00001028sd00000016*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1704 802.11n + BT 4.0
+
+pci:v000014E4d00004401*
+ ID_PRODUCT_FROM_DATABASE=BCM4401 100Base-T
+
+pci:v000014E4d00004401sv00001025sd00000035*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 660
+
+pci:v000014E4d00004401sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v000014E4d00004401sv00001043sd000080A8*
+ ID_PRODUCT_FROM_DATABASE=A7V8X motherboard
+
+pci:v000014E4d00004402*
+ ID_PRODUCT_FROM_DATABASE=BCM4402 Integrated 10/100BaseT
+
+pci:v000014E4d00004403*
+ ID_PRODUCT_FROM_DATABASE=BCM4402 V.90 56k Modem
+
+pci:v000014E4d00004410*
+ ID_PRODUCT_FROM_DATABASE=BCM4413 iLine32 HomePNA 2.0
+
+pci:v000014E4d00004411*
+ ID_PRODUCT_FROM_DATABASE=BCM4413 V.90 56k modem
+
+pci:v000014E4d00004412*
+ ID_PRODUCT_FROM_DATABASE=BCM4412 10/100BaseT
+
+pci:v000014E4d00004430*
+ ID_PRODUCT_FROM_DATABASE=BCM44xx CardBus iLine32 HomePNA 2.0
+
+pci:v000014E4d00004432*
+ ID_PRODUCT_FROM_DATABASE=BCM4432 CardBus 10/100BaseT
+
+pci:v000014E4d00004610*
+ ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 PCI to SB Bridge
+
+pci:v000014E4d00004611*
+ ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 iLine32 HomePNA 1.0
+
+pci:v000014E4d00004612*
+ ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 V.90 56k Modem
+
+pci:v000014E4d00004613*
+ ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 Ethernet Controller
+
+pci:v000014E4d00004614*
+ ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 External Interface
+
+pci:v000014E4d00004615*
+ ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 USB Controller
+
+pci:v000014E4d00004704*
+ ID_PRODUCT_FROM_DATABASE=BCM4704 PCI to SB Bridge
+
+pci:v000014E4d00004705*
+ ID_PRODUCT_FROM_DATABASE=BCM4704 Sentry5 802.11b Wireless LAN Controller
+
+pci:v000014E4d00004706*
+ ID_PRODUCT_FROM_DATABASE=BCM4704 Sentry5 Ethernet Controller
+
+pci:v000014E4d00004707*
+ ID_PRODUCT_FROM_DATABASE=BCM4704 Sentry5 USB Controller
+
+pci:v000014E4d00004708*
+ ID_PRODUCT_FROM_DATABASE=BCM4704 Crypto Accelerator
+
+pci:v000014E4d00004710*
+ ID_PRODUCT_FROM_DATABASE=BCM4710 Sentry5 PCI to SB Bridge
+
+pci:v000014E4d00004711*
+ ID_PRODUCT_FROM_DATABASE=BCM47xx Sentry5 iLine32 HomePNA 2.0
+
+pci:v000014E4d00004712*
+ ID_PRODUCT_FROM_DATABASE=BCM47xx V.92 56k modem
+
+pci:v000014E4d00004713*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 Ethernet Controller
+
+pci:v000014E4d00004714*
+ ID_PRODUCT_FROM_DATABASE=BCM47xx Sentry5 External Interface
+
+pci:v000014E4d00004715*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 USB Controller
+
+pci:v000014E4d00004716*
+ ID_PRODUCT_FROM_DATABASE=BCM47xx Sentry5 USB Host Controller
+
+pci:v000014E4d00004717*
+ ID_PRODUCT_FROM_DATABASE=BCM47xx Sentry5 USB Device Controller
+
+pci:v000014E4d00004718*
+ ID_PRODUCT_FROM_DATABASE=Sentry5 Crypto Accelerator
+
+pci:v000014E4d00004719*
+ ID_PRODUCT_FROM_DATABASE=BCM47xx/53xx RoboSwitch Core
+
+pci:v000014E4d00004720*
+ ID_PRODUCT_FROM_DATABASE=BCM4712 MIPS CPU
+
+pci:v000014E4d00004727*
+ ID_PRODUCT_FROM_DATABASE=BCM4313 802.11b/g/n Wireless LAN Controller
+
+pci:v000014E4d00004727sv00001028sd00000010*
+ ID_PRODUCT_FROM_DATABASE=Inspiron M5010 / XPS 8300
+
+pci:v000014E4d00005365*
+ ID_PRODUCT_FROM_DATABASE=BCM5365P Sentry5 Host Bridge
+
+pci:v000014E4d00005600*
+ ID_PRODUCT_FROM_DATABASE=BCM5600 StrataSwitch 24+2 Ethernet Switch Controller
+
+pci:v000014E4d00005605*
+ ID_PRODUCT_FROM_DATABASE=BCM5605 StrataSwitch 24+2 Ethernet Switch Controller
+
+pci:v000014E4d00005615*
+ ID_PRODUCT_FROM_DATABASE=BCM5615 StrataSwitch 24+2 Ethernet Switch Controller
+
+pci:v000014E4d00005625*
+ ID_PRODUCT_FROM_DATABASE=BCM5625 StrataSwitch 24+2 Ethernet Switch Controller
+
+pci:v000014E4d00005645*
+ ID_PRODUCT_FROM_DATABASE=BCM5645 StrataSwitch 24+2 Ethernet Switch Controller
+
+pci:v000014E4d00005670*
+ ID_PRODUCT_FROM_DATABASE=BCM5670 8-Port 10GE Ethernet Switch Fabric
+
+pci:v000014E4d00005680*
+ ID_PRODUCT_FROM_DATABASE=BCM5680 G-Switch 8 Port Gigabit Ethernet Switch Controller
+
+pci:v000014E4d00005690*
+ ID_PRODUCT_FROM_DATABASE=BCM5690 12-port Multi-Layer Gigabit Ethernet Switch
+
+pci:v000014E4d00005691*
+ ID_PRODUCT_FROM_DATABASE=BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller
+
+pci:v000014E4d00005692*
+ ID_PRODUCT_FROM_DATABASE=BCM5692 12-port Multi-Layer Gigabit Ethernet Switch
+
+pci:v000014E4d00005695*
+ ID_PRODUCT_FROM_DATABASE=BCM5695 12-port + HiGig Multi-Layer Gigabit Ethernet Switch
+
+pci:v000014E4d00005698*
+ ID_PRODUCT_FROM_DATABASE=BCM5698 12-port Multi-Layer Gigabit Ethernet Switch
+
+pci:v000014E4d00005820*
+ ID_PRODUCT_FROM_DATABASE=BCM5820 Crypto Accelerator
+
+pci:v000014E4d00005821*
+ ID_PRODUCT_FROM_DATABASE=BCM5821 Crypto Accelerator
+
+pci:v000014E4d00005822*
+ ID_PRODUCT_FROM_DATABASE=BCM5822 Crypto Accelerator
+
+pci:v000014E4d00005823*
+ ID_PRODUCT_FROM_DATABASE=BCM5823 Crypto Accelerator
+
+pci:v000014E4d00005824*
+ ID_PRODUCT_FROM_DATABASE=BCM5824 Crypto Accelerator
+
+pci:v000014E4d00005840*
+ ID_PRODUCT_FROM_DATABASE=BCM5840 Crypto Accelerator
+
+pci:v000014E4d00005841*
+ ID_PRODUCT_FROM_DATABASE=BCM5841 Crypto Accelerator
+
+pci:v000014E4d00005850*
+ ID_PRODUCT_FROM_DATABASE=BCM5850 Crypto Accelerator
+
+pci:v000014E4d0000B800*
+ ID_PRODUCT_FROM_DATABASE=BCM56800 StrataXGS 10GE Switch Controller
+
+pci:v000014E5*
+ ID_VENDOR_FROM_DATABASE=Pixelfusion Ltd
+
+pci:v000014E6*
+ ID_VENDOR_FROM_DATABASE=SHINING Technology Inc
+
+pci:v000014E7*
+ ID_VENDOR_FROM_DATABASE=3CX
+
+pci:v000014E8*
+ ID_VENDOR_FROM_DATABASE=RAYCER Inc
+
+pci:v000014E9*
+ ID_VENDOR_FROM_DATABASE=GARNETS System CO Ltd
+
+pci:v000014EA*
+ ID_VENDOR_FROM_DATABASE=Planex Communications, Inc
+
+pci:v000014EAd0000AB06*
+ ID_PRODUCT_FROM_DATABASE=FNW-3603-TX CardBus Fast Ethernet
+
+pci:v000014EAd0000AB07*
+ ID_PRODUCT_FROM_DATABASE=RTL81xx RealTek Ethernet
+
+pci:v000014EAd0000AB08*
+ ID_PRODUCT_FROM_DATABASE=FNW-3602-TX CardBus Fast Ethernet
+
+pci:v000014EB*
+ ID_VENDOR_FROM_DATABASE=SEIKO EPSON Corp
+
+pci:v000014EC*
+ ID_VENDOR_FROM_DATABASE=Agilent Technologies
+
+pci:v000014ECd00000000*
+ ID_PRODUCT_FROM_DATABASE=Aciris Digitizer (malformed ID)
+
+pci:v000014ED*
+ ID_VENDOR_FROM_DATABASE=DATAKINETICS Ltd
+
+pci:v000014EE*
+ ID_VENDOR_FROM_DATABASE=MASPRO KENKOH Corp
+
+pci:v000014EF*
+ ID_VENDOR_FROM_DATABASE=CARRY Computer ENG. CO Ltd
+
+pci:v000014F0*
+ ID_VENDOR_FROM_DATABASE=CANON RESEACH CENTRE FRANCE
+
+pci:v000014F1*
+ ID_VENDOR_FROM_DATABASE=Conexant Systems, Inc.
+
+pci:v000014F1d00001002*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001003*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001004*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001005*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001006*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001022*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001023*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001024*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001025*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001026*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001032*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001033*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v000014F1d00001033sv00001033sd00008077*
+ ID_PRODUCT_FROM_DATABASE=NEC
+
+pci:v000014F1d00001033sv0000122Dsd00004027*
+ ID_PRODUCT_FROM_DATABASE=Dell Zeus - MDP3880-W(B) Data Fax Modem
+
+pci:v000014F1d00001033sv0000122Dsd00004030*
+ ID_PRODUCT_FROM_DATABASE=Dell Mercury - MDP3880-U(B) Data Fax Modem
+
+pci:v000014F1d00001033sv0000122Dsd00004034*
+ ID_PRODUCT_FROM_DATABASE=Dell Thor - MDP3880-W(U) Data Fax Modem
+
+pci:v000014F1d00001033sv000013E0sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Dell Copper
+
+pci:v000014F1d00001033sv000013E0sd0000020E*
+ ID_PRODUCT_FROM_DATABASE=Dell Silver
+
+pci:v000014F1d00001033sv000013E0sd00000261*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v000014F1d00001033sv000013E0sd00000290*
+ ID_PRODUCT_FROM_DATABASE=Compaq Goldwing
+
+pci:v000014F1d00001033sv000013E0sd000002A0*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v000014F1d00001033sv000013E0sd000002B0*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v000014F1d00001033sv000013E0sd000002C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq Scooter
+
+pci:v000014F1d00001033sv000013E0sd000002D0*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v000014F1d00001033sv0000144Fsd00001500*
+ ID_PRODUCT_FROM_DATABASE=IBM P85-DF (1)
+
+pci:v000014F1d00001033sv0000144Fsd00001501*
+ ID_PRODUCT_FROM_DATABASE=IBM P85-DF (2)
+
+pci:v000014F1d00001033sv0000144Fsd0000150A*
+ ID_PRODUCT_FROM_DATABASE=IBM P85-DF (3)
+
+pci:v000014F1d00001033sv0000144Fsd0000150B*
+ ID_PRODUCT_FROM_DATABASE=IBM P85-DF Low Profile (1)
+
+pci:v000014F1d00001033sv0000144Fsd00001510*
+ ID_PRODUCT_FROM_DATABASE=IBM P85-DF Low Profile (2)
+
+pci:v000014F1d00001034*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
+
+pci:v000014F1d00001035*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v000014F1d00001035sv000010CFsd00001098*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu P85-DFSV
+
+pci:v000014F1d00001036*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem
+
+pci:v000014F1d00001036sv0000104Dsd00008067*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001036sv0000122Dsd00004029*
+ ID_PRODUCT_FROM_DATABASE=MDP3880SP-W
+
+pci:v000014F1d00001036sv0000122Dsd00004031*
+ ID_PRODUCT_FROM_DATABASE=MDP3880SP-U
+
+pci:v000014F1d00001036sv000013E0sd00000209*
+ ID_PRODUCT_FROM_DATABASE=Dell Titanium
+
+pci:v000014F1d00001036sv000013E0sd0000020A*
+ ID_PRODUCT_FROM_DATABASE=Dell Graphite
+
+pci:v000014F1d00001036sv000013E0sd00000260*
+ ID_PRODUCT_FROM_DATABASE=Gateway Red Owl
+
+pci:v000014F1d00001036sv000013E0sd00000270*
+ ID_PRODUCT_FROM_DATABASE=Gateway White Horse
+
+pci:v000014F1d00001052*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem (Worldwide)
+
+pci:v000014F1d00001053*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem (Worldwide)
+
+pci:v000014F1d00001054*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem (Worldwide)
+
+pci:v000014F1d00001055*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
+
+pci:v000014F1d00001056*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+
+pci:v000014F1d00001057*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+
+pci:v000014F1d00001059*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem (Worldwide)
+
+pci:v000014F1d00001063*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v000014F1d00001064*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
+
+pci:v000014F1d00001065*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v000014F1d00001066*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem
+
+pci:v000014F1d00001066sv0000122Dsd00004033*
+ ID_PRODUCT_FROM_DATABASE=Dell Athena - MDP3900V-U
+
+pci:v000014F1d00001085*
+ ID_PRODUCT_FROM_DATABASE=HCF V90 56k Data/Fax/Voice/Spkp PCI Modem
+
+pci:v000014F1d000010B6*
+ ID_PRODUCT_FROM_DATABASE=CX06834-11 HCF V.92 56k Data/Fax/Voice/Spkp Modem
+
+pci:v000014F1d00001433*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v000014F1d00001434*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
+
+pci:v000014F1d00001435*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v000014F1d00001436*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v000014F1d00001453*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem
+
+pci:v000014F1d00001453sv000013E0sd00000240*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v000014F1d00001453sv000013E0sd00000250*
+ ID_PRODUCT_FROM_DATABASE=IBM
+
+pci:v000014F1d00001453sv0000144Fsd00001502*
+ ID_PRODUCT_FROM_DATABASE=IBM P95-DF (1)
+
+pci:v000014F1d00001453sv0000144Fsd00001503*
+ ID_PRODUCT_FROM_DATABASE=IBM P95-DF (2)
+
+pci:v000014F1d00001454*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
+
+pci:v000014F1d00001455*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v000014F1d00001456*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem
+
+pci:v000014F1d00001456sv0000122Dsd00004035*
+ ID_PRODUCT_FROM_DATABASE=Dell Europa - MDP3900V-W
+
+pci:v000014F1d00001456sv0000122Dsd00004302*
+ ID_PRODUCT_FROM_DATABASE=Dell MP3930V-W(C) MiniPCI
+
+pci:v000014F1d00001610*
+ ID_PRODUCT_FROM_DATABASE=ADSL AccessRunner PCI Arbitration Device
+
+pci:v000014F1d00001611*
+ ID_PRODUCT_FROM_DATABASE=AccessRunner PCI ADSL Interface Device
+
+pci:v000014F1d00001620*
+ ID_PRODUCT_FROM_DATABASE=AccessRunner V2 PCI ADSL Arbitration Device
+
+pci:v000014F1d00001621*
+ ID_PRODUCT_FROM_DATABASE=AccessRunner V2 PCI ADSL Interface Device
+
+pci:v000014F1d00001622*
+ ID_PRODUCT_FROM_DATABASE=AccessRunner V2 PCI ADSL Yukon WAN Adapter
+
+pci:v000014F1d00001803*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001803sv00000E11sd00000023*
+ ID_PRODUCT_FROM_DATABASE=623-LAN Grizzly
+
+pci:v000014F1d00001803sv00000E11sd00000043*
+ ID_PRODUCT_FROM_DATABASE=623-LAN Yogi
+
+pci:v000014F1d00001811*
+ ID_PRODUCT_FROM_DATABASE=MiniPCI Network Adapter
+
+pci:v000014F1d00001815*
+ ID_PRODUCT_FROM_DATABASE=HCF 56k Modem
+
+pci:v000014F1d00001815sv00000E11sd00000022*
+ ID_PRODUCT_FROM_DATABASE=Grizzly
+
+pci:v000014F1d00001815sv00000E11sd00000042*
+ ID_PRODUCT_FROM_DATABASE=Yogi
+
+pci:v000014F1d00002003*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem
+
+pci:v000014F1d00002004*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem
+
+pci:v000014F1d00002005*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v000014F1d00002006*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem
+
+pci:v000014F1d00002013*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem
+
+pci:v000014F1d00002013sv00000E11sd0000B195*
+ ID_PRODUCT_FROM_DATABASE=Bear
+
+pci:v000014F1d00002013sv00000E11sd0000B196*
+ ID_PRODUCT_FROM_DATABASE=Seminole 1
+
+pci:v000014F1d00002013sv00000E11sd0000B1BE*
+ ID_PRODUCT_FROM_DATABASE=Seminole 2
+
+pci:v000014F1d00002013sv00001025sd00008013*
+ ID_PRODUCT_FROM_DATABASE=Acer
+
+pci:v000014F1d00002013sv00001033sd0000809D*
+ ID_PRODUCT_FROM_DATABASE=NEC
+
+pci:v000014F1d00002013sv00001033sd000080BC*
+ ID_PRODUCT_FROM_DATABASE=NEC
+
+pci:v000014F1d00002013sv0000155Dsd00006793*
+ ID_PRODUCT_FROM_DATABASE=HP
+
+pci:v000014F1d00002013sv0000155Dsd00008850*
+ ID_PRODUCT_FROM_DATABASE=E Machines
+
+pci:v000014F1d00002014*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem
+
+pci:v000014F1d00002015*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+
+pci:v000014F1d00002016*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem
+
+pci:v000014F1d00002043*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem (WorldW SmartDAA)
+
+pci:v000014F1d00002044*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (WorldW SmartDAA)
+
+pci:v000014F1d00002045*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA)
+
+pci:v000014F1d00002045sv000014F1sd00002045*
+ ID_PRODUCT_FROM_DATABASE=Generic SoftK56
+
+pci:v000014F1d00002046*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA)
+
+pci:v000014F1d00002063*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem (SmartDAA)
+
+pci:v000014F1d00002064*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (SmartDAA)
+
+pci:v000014F1d00002065*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
+
+pci:v000014F1d00002066*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
+
+pci:v000014F1d00002093*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Modem
+
+pci:v000014F1d00002093sv0000155Dsd00002F07*
+ ID_PRODUCT_FROM_DATABASE=Legend
+
+pci:v000014F1d00002143*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002144*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Cell Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002145*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002146*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002163*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Cell Modem (Mob SmartDAA)
+
+pci:v000014F1d00002164*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Cell Modem (Mob SmartDAA)
+
+pci:v000014F1d00002165*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob SmartDAA)
+
+pci:v000014F1d00002166*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob SmartDAA)
+
+pci:v000014F1d00002343*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax CardBus Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002344*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice CardBus Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002345*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002346*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002363*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax CardBus Modem (Mob SmartDAA)
+
+pci:v000014F1d00002364*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice CardBus Modem (Mob SmartDAA)
+
+pci:v000014F1d00002365*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
+
+pci:v000014F1d00002366*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA)
+
+pci:v000014F1d00002443*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002443sv0000104Dsd00008075*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v000014F1d00002443sv0000104Dsd00008083*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v000014F1d00002443sv0000104Dsd00008097*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+pci:v000014F1d00002444*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002445*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002446*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA)
+
+pci:v000014F1d00002463*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem (Mob SmartDAA)
+
+pci:v000014F1d00002464*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (Mob SmartDAA)
+
+pci:v000014F1d00002465*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA)
+
+pci:v000014F1d00002466*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA)
+
+pci:v000014F1d00002BFA*
+ ID_PRODUCT_FROM_DATABASE=D110 HDAudio Soft Data Fax Modem with SmartCP
+
+pci:v000014F1d00002BFAsv00001025sd00000009*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5622WLMi
+
+pci:v000014F1d00002F00*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k HSFi Modem
+
+pci:v000014F1d00002F00sv000013E0sd00008D84*
+ ID_PRODUCT_FROM_DATABASE=IBM HSFi V.90
+
+pci:v000014F1d00002F00sv000013E0sd00008D85*
+ ID_PRODUCT_FROM_DATABASE=Compaq Stinger
+
+pci:v000014F1d00002F00sv000014F1sd00002004*
+ ID_PRODUCT_FROM_DATABASE=Dynalink 56PMi
+
+pci:v000014F1d00002F02*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k HSFi Data/Fax
+
+pci:v000014F1d00002F11*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k HSFi Modem
+
+pci:v000014F1d00002F20*
+ ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem
+
+pci:v000014F1d00002F20sv000014F1sd0000200C*
+ ID_PRODUCT_FROM_DATABASE=Soft Data Fax Modem with SmartCP
+
+pci:v000014F1d00002F20sv000014F1sd0000200F*
+ ID_PRODUCT_FROM_DATABASE=Dimension 3000
+
+pci:v000014F1d00002F30*
+ ID_PRODUCT_FROM_DATABASE=SoftV92 SpeakerPhone SoftRing Modem with SmartSP
+
+pci:v000014F1d00002F30sv000014F1sd00002014*
+ ID_PRODUCT_FROM_DATABASE=Devolo MikroLink 56K Modem PCI
+
+pci:v000014F1d00002F50*
+ ID_PRODUCT_FROM_DATABASE=Conexant SoftK56 Data/Fax Modem
+
+pci:v000014F1d00005045*
+ ID_PRODUCT_FROM_DATABASE=CX20549 (Venice)
+
+pci:v000014F1d00005047*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio [Waikiki]
+
+pci:v000014F1d00005051*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio (HERMOSA)
+
+pci:v000014F1d00005B7A*
+ ID_PRODUCT_FROM_DATABASE=CX23418 Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder
+
+pci:v000014F1d00005B7Asv00000070sd00007444*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-1600
+
+pci:v000014F1d00005B7Asv00005854sd00003343*
+ ID_PRODUCT_FROM_DATABASE=GoTView PCI DVD3 Hybrid
+
+pci:v000014F1d00008200*
+ ID_PRODUCT_FROM_DATABASE=CX25850
+
+pci:v000014F1d00008234*
+ ID_PRODUCT_FROM_DATABASE=RS8234 ATM SAR Controller [ServiceSAR Plus]
+
+pci:v000014F1d00008800*
+ ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder
+
+pci:v000014F1d00008800sv00000070sd00002801*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models
+
+pci:v000014F1d00008800sv00000070sd00003401*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 34xxx models
+
+pci:v000014F1d00008800sv00000070sd00006902*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-4000-HD
+
+pci:v000014F1d00008800sv00000070sd00007801*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-1800 MCE
+
+pci:v000014F1d00008800sv00000070sd00009001*
+ ID_PRODUCT_FROM_DATABASE=Nova-T DVB-T
+
+pci:v000014F1d00008800sv00000070sd00009200*
+ ID_PRODUCT_FROM_DATABASE=Nova-SE2 DVB-S
+
+pci:v000014F1d00008800sv00000070sd00009202*
+ ID_PRODUCT_FROM_DATABASE=Nova-S-Plus DVB-S
+
+pci:v000014F1d00008800sv00000070sd00009402*
+ ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid
+
+pci:v000014F1d00008800sv00000070sd00009600*
+ ID_PRODUCT_FROM_DATABASE=WinTV 88x Video
+
+pci:v000014F1d00008800sv00000070sd00009802*
+ ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid (Low Profile)
+
+pci:v000014F1d00008800sv00001002sd000000F8*
+ ID_PRODUCT_FROM_DATABASE=ATI TV Wonder Pro
+
+pci:v000014F1d00008800sv00001002sd0000A101*
+ ID_PRODUCT_FROM_DATABASE=HDTV Wonder
+
+pci:v000014F1d00008800sv00001043sd00004823*
+ ID_PRODUCT_FROM_DATABASE=ASUS PVR-416
+
+pci:v000014F1d00008800sv0000107Dsd00006611*
+ ID_PRODUCT_FROM_DATABASE=Winfast TV 2000XP Expert
+
+pci:v000014F1d00008800sv0000107Dsd00006613*
+ ID_PRODUCT_FROM_DATABASE=Leadtek Winfast 2000XP Expert
+
+pci:v000014F1d00008800sv0000107Dsd00006620*
+ ID_PRODUCT_FROM_DATABASE=Leadtek Winfast DV2000
+
+pci:v000014F1d00008800sv0000107Dsd0000663C*
+ ID_PRODUCT_FROM_DATABASE=Leadtek PVR 2000
+
+pci:v000014F1d00008800sv0000107Dsd0000665F*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV1000-T
+
+pci:v000014F1d00008800sv000010FCsd0000D003*
+ ID_PRODUCT_FROM_DATABASE=IODATA GV-VCP3/PCI
+
+pci:v000014F1d00008800sv000010FCsd0000D035*
+ ID_PRODUCT_FROM_DATABASE=IODATA GV/BCTV7E
+
+pci:v000014F1d00008800sv00001421sd00000334*
+ ID_PRODUCT_FROM_DATABASE=Instant TV DVB-T PCI
+
+pci:v000014F1d00008800sv00001461sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=AVerTV 303 (M126)
+
+pci:v000014F1d00008800sv00001461sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=AverTV Studio 303 (M126)
+
+pci:v000014F1d00008800sv00001461sd00008011*
+ ID_PRODUCT_FROM_DATABASE=UltraTV Media Center PCI 550
+
+pci:v000014F1d00008800sv00001462sd00008606*
+ ID_PRODUCT_FROM_DATABASE=MSI TV-@nywhere Master
+
+pci:v000014F1d00008800sv000014C7sd00000107*
+ ID_PRODUCT_FROM_DATABASE=GDI Black Gold
+
+pci:v000014F1d00008800sv000014F1sd00000187*
+ ID_PRODUCT_FROM_DATABASE=Conexant DVB-T reference design
+
+pci:v000014F1d00008800sv000014F1sd00000342*
+ ID_PRODUCT_FROM_DATABASE=Digital-Logic MICROSPACE Entertainment Center (MEC)
+
+pci:v000014F1d00008800sv0000153Bsd00001166*
+ ID_PRODUCT_FROM_DATABASE=Cinergy 1400 DVB-T
+
+pci:v000014F1d00008800sv00001540sd00002580*
+ ID_PRODUCT_FROM_DATABASE=Provideo PV259
+
+pci:v000014F1d00008800sv00001554sd00004811*
+ ID_PRODUCT_FROM_DATABASE=PixelView
+
+pci:v000014F1d00008800sv00001554sd00004813*
+ ID_PRODUCT_FROM_DATABASE=Club 3D  ZAP1000 MCE Edition
+
+pci:v000014F1d00008800sv000017DEsd000008A1*
+ ID_PRODUCT_FROM_DATABASE=KWorld/VStream XPert DVB-T with cx22702
+
+pci:v000014F1d00008800sv000017DEsd000008A6*
+ ID_PRODUCT_FROM_DATABASE=KWorld/VStream XPert DVB-T
+
+pci:v000014F1d00008800sv000017DEsd000008B2*
+ ID_PRODUCT_FROM_DATABASE=KWorld DVB-S 100
+
+pci:v000014F1d00008800sv000017DEsd0000A8A6*
+ ID_PRODUCT_FROM_DATABASE=digitalnow DNTV Live! DVB-T
+
+pci:v000014F1d00008800sv00001822sd00000025*
+ ID_PRODUCT_FROM_DATABASE=digitalnow DNTV Live! DVB-T Pro
+
+pci:v000014F1d00008800sv0000185Bsd0000E000*
+ ID_PRODUCT_FROM_DATABASE=VideoMate X500
+
+pci:v000014F1d00008800sv000018ACsd0000D500*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV 5 Gold
+
+pci:v000014F1d00008800sv000018ACsd0000D810*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold-Q
+
+pci:v000014F1d00008800sv000018ACsd0000D820*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold-T
+
+pci:v000014F1d00008800sv000018ACsd0000DB00*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T1
+
+pci:v000014F1d00008800sv000018ACsd0000DB11*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Plus
+
+pci:v000014F1d00008800sv000018ACsd0000DB50*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Dual Digital
+
+pci:v000014F1d00008800sv00005654sd00002388*
+ ID_PRODUCT_FROM_DATABASE=GoTView PCI Hybrid TV Tuner Card
+
+pci:v000014F1d00008800sv00007063sd00003000*
+ ID_PRODUCT_FROM_DATABASE=pcHDTV HD3000 HDTV
+
+pci:v000014F1d00008800sv00007063sd00005500*
+ ID_PRODUCT_FROM_DATABASE=pcHDTV HD-5500
+
+pci:v000014F1d00008801*
+ ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port]
+
+pci:v000014F1d00008801sv00000070sd00002801*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models
+
+pci:v000014F1d00008801sv0000185Bsd0000E000*
+ ID_PRODUCT_FROM_DATABASE=VideoMate X500
+
+pci:v000014F1d00008801sv00005654sd00002388*
+ ID_PRODUCT_FROM_DATABASE=GoTView PCI Hybrid Audio AVStream Device
+
+pci:v000014F1d00008801sv00007063sd00005500*
+ ID_PRODUCT_FROM_DATABASE=pcHDTV HD-5500
+
+pci:v000014F1d00008802*
+ ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port]
+
+pci:v000014F1d00008802sv00000070sd00002801*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models
+
+pci:v000014F1d00008802sv00000070sd00006902*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-4000-HD
+
+pci:v000014F1d00008802sv00000070sd00009002*
+ ID_PRODUCT_FROM_DATABASE=Nova-T DVB-T Model 909
+
+pci:v000014F1d00008802sv00000070sd00009402*
+ ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid
+
+pci:v000014F1d00008802sv00000070sd00009600*
+ ID_PRODUCT_FROM_DATABASE=WinTV 88x MPEG Encoder
+
+pci:v000014F1d00008802sv00001043sd00004823*
+ ID_PRODUCT_FROM_DATABASE=ASUS PVR-416
+
+pci:v000014F1d00008802sv0000107Dsd0000663C*
+ ID_PRODUCT_FROM_DATABASE=Leadtek PVR 2000
+
+pci:v000014F1d00008802sv0000107Dsd0000665F*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV1000-T
+
+pci:v000014F1d00008802sv000014F1sd00000187*
+ ID_PRODUCT_FROM_DATABASE=Conexant DVB-T reference design
+
+pci:v000014F1d00008802sv000017DEsd000008A1*
+ ID_PRODUCT_FROM_DATABASE=XPert DVB-T PCI BDA DVBT 23880 Transport Stream Capture
+
+pci:v000014F1d00008802sv000017DEsd000008A6*
+ ID_PRODUCT_FROM_DATABASE=KWorld/VStream XPert DVB-T
+
+pci:v000014F1d00008802sv000018ACsd0000D500*
+ ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV5 Gold
+
+pci:v000014F1d00008802sv000018ACsd0000D810*
+ ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV3 Gold-Q
+
+pci:v000014F1d00008802sv000018ACsd0000D820*
+ ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV3 Gold-T
+
+pci:v000014F1d00008802sv000018ACsd0000DB00*
+ ID_PRODUCT_FROM_DATABASE=DVICO FusionHDTV DVB-T1
+
+pci:v000014F1d00008802sv000018ACsd0000DB10*
+ ID_PRODUCT_FROM_DATABASE=DVICO FusionHDTV DVB-T Plus
+
+pci:v000014F1d00008802sv00005654sd00002388*
+ ID_PRODUCT_FROM_DATABASE=GoTView PCI Hybrid TS Capture Device
+
+pci:v000014F1d00008802sv00007063sd00003000*
+ ID_PRODUCT_FROM_DATABASE=pcHDTV HD3000 HDTV
+
+pci:v000014F1d00008802sv00007063sd00005500*
+ ID_PRODUCT_FROM_DATABASE=pcHDTV HD-5500
+
+pci:v000014F1d00008804*
+ ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [IR Port]
+
+pci:v000014F1d00008804sv00000070sd00006902*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-4000-HD
+
+pci:v000014F1d00008804sv00000070sd00009002*
+ ID_PRODUCT_FROM_DATABASE=Nova-T DVB-T Model 909
+
+pci:v000014F1d00008804sv00000070sd00009402*
+ ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid
+
+pci:v000014F1d00008804sv00007063sd00005500*
+ ID_PRODUCT_FROM_DATABASE=pcHDTV HD-5500
+
+pci:v000014F1d00008811*
+ ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port]
+
+pci:v000014F1d00008811sv00000070sd00003401*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 34xxx models
+
+pci:v000014F1d00008811sv00000070sd00006902*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-4000-HD
+
+pci:v000014F1d00008811sv00000070sd00009402*
+ ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid
+
+pci:v000014F1d00008811sv00000070sd00009600*
+ ID_PRODUCT_FROM_DATABASE=WinTV 88x Audio
+
+pci:v000014F1d00008811sv00001462sd00008606*
+ ID_PRODUCT_FROM_DATABASE=MSI TV-@nywhere Master
+
+pci:v000014F1d00008811sv000018ACsd0000D500*
+ ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV5 Gold
+
+pci:v000014F1d00008811sv000018ACsd0000D810*
+ ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV3 Gold-Q
+
+pci:v000014F1d00008811sv000018ACsd0000D820*
+ ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV3 Gold-T
+
+pci:v000014F1d00008811sv000018ACsd0000DB00*
+ ID_PRODUCT_FROM_DATABASE=DVICO FusionHDTV DVB-T1
+
+pci:v000014F1d00008811sv00005654sd00002388*
+ ID_PRODUCT_FROM_DATABASE=GoTView PCI Hybrid Audio Capture Device
+
+pci:v000014F1d00008852*
+ ID_PRODUCT_FROM_DATABASE=CX23885 PCI Video and Audio Decoder
+
+pci:v000014F1d00008852sv00000070sd00008010*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV HVR-1400 ExpressCard
+
+pci:v000014F1d00008852sv00001461sd0000C039*
+ ID_PRODUCT_FROM_DATABASE=AVerTV Hybrid Express (A577)
+
+pci:v000014F1d00008852sv0000153Bsd0000117E*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T PCIe Dual
+
+pci:v000014F1d00008852sv000018ACsd0000DB78*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Dual Express
+
+pci:v000014F1d00008880*
+ ID_PRODUCT_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb
+
+pci:v000014F1d00008880sv00000070sd0000C108*
+ ID_PRODUCT_FROM_DATABASE=WinTV-HVR-4400-HD model 1278
+
+pci:v000014F1d00008880sv00005654sd00002389*
+ ID_PRODUCT_FROM_DATABASE=GoTView X5 DVD Hybrid PCI-E
+
+pci:v000014F1d00008880sv00005654sd00002390*
+ ID_PRODUCT_FROM_DATABASE=GoTView X5 3D HYBRID PCI-E
+
+pci:v000014F2*
+ ID_VENDOR_FROM_DATABASE=MOBILITY Electronics
+
+pci:v000014F2d00000120*
+ ID_PRODUCT_FROM_DATABASE=EV1000 bridge
+
+pci:v000014F2d00000121*
+ ID_PRODUCT_FROM_DATABASE=EV1000 Parallel port
+
+pci:v000014F2d00000122*
+ ID_PRODUCT_FROM_DATABASE=EV1000 Serial port
+
+pci:v000014F2d00000123*
+ ID_PRODUCT_FROM_DATABASE=EV1000 Keyboard controller
+
+pci:v000014F2d00000124*
+ ID_PRODUCT_FROM_DATABASE=EV1000 Mouse controller
+
+pci:v000014F3*
+ ID_VENDOR_FROM_DATABASE=BroadLogic
+
+pci:v000014F3d00002030*
+ ID_PRODUCT_FROM_DATABASE=2030 DVB-S Satellite Receiver
+
+pci:v000014F3d00002035*
+ ID_PRODUCT_FROM_DATABASE=2035 DVB-S Satellite Receiver
+
+pci:v000014F3d00002050*
+ ID_PRODUCT_FROM_DATABASE=2050 DVB-T Terrestrial (Cable) Receiver
+
+pci:v000014F3d00002060*
+ ID_PRODUCT_FROM_DATABASE=2060 ATSC Terrestrial (Cable) Receiver
+
+pci:v000014F4*
+ ID_VENDOR_FROM_DATABASE=TOKYO Electronic Industry CO Ltd
+
+pci:v000014F5*
+ ID_VENDOR_FROM_DATABASE=SOPAC Ltd
+
+pci:v000014F6*
+ ID_VENDOR_FROM_DATABASE=COYOTE Technologies LLC
+
+pci:v000014F7*
+ ID_VENDOR_FROM_DATABASE=WOLF Technology Inc
+
+pci:v000014F8*
+ ID_VENDOR_FROM_DATABASE=AUDIOCODES Inc
+
+pci:v000014F8d00002077*
+ ID_PRODUCT_FROM_DATABASE=TP-240 dual span E1 VoIP PCI card
+
+pci:v000014F9*
+ ID_VENDOR_FROM_DATABASE=AG COMMUNICATIONS
+
+pci:v000014FA*
+ ID_VENDOR_FROM_DATABASE=WANDEL & GOLTERMANN
+
+pci:v000014FB*
+ ID_VENDOR_FROM_DATABASE=TRANSAS MARINE (UK) Ltd
+
+pci:v000014FC*
+ ID_VENDOR_FROM_DATABASE=Quadrics Ltd
+
+pci:v000014FCd00000000*
+ ID_PRODUCT_FROM_DATABASE=QsNet Elan3 Network Adapter
+
+pci:v000014FCd00000001*
+ ID_PRODUCT_FROM_DATABASE=QsNetII Elan4 Network Adapter
+
+pci:v000014FCd00000002*
+ ID_PRODUCT_FROM_DATABASE=QsNetIII Elan5 Network Adapter
+
+pci:v000014FD*
+ ID_VENDOR_FROM_DATABASE=JAPAN Computer Industry Inc
+
+pci:v000014FE*
+ ID_VENDOR_FROM_DATABASE=ARCHTEK TELECOM Corp
+
+pci:v000014FF*
+ ID_VENDOR_FROM_DATABASE=TWINHEAD INTERNATIONAL Corp
+
+pci:v00001500*
+ ID_VENDOR_FROM_DATABASE=DELTA Electronics, Inc
+
+pci:v00001500d00001360*
+ ID_PRODUCT_FROM_DATABASE=RTL81xx RealTek Ethernet
+
+pci:v00001501*
+ ID_VENDOR_FROM_DATABASE=BANKSOFT CANADA Ltd
+
+pci:v00001502*
+ ID_VENDOR_FROM_DATABASE=MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd
+
+pci:v00001503*
+ ID_VENDOR_FROM_DATABASE=KAWASAKI LSI USA Inc
+
+pci:v00001504*
+ ID_VENDOR_FROM_DATABASE=KAISER Electronics
+
+pci:v00001505*
+ ID_VENDOR_FROM_DATABASE=ITA INGENIEURBURO FUR TESTAUFGABEN GmbH
+
+pci:v00001506*
+ ID_VENDOR_FROM_DATABASE=CHAMELEON Systems Inc
+
+pci:v00001507*
+ ID_VENDOR_FROM_DATABASE=Motorola ?? / HTEC
+
+pci:v00001507d00000001*
+ ID_PRODUCT_FROM_DATABASE=MPC105 [Eagle]
+
+pci:v00001507d00000002*
+ ID_PRODUCT_FROM_DATABASE=MPC106 [Grackle]
+
+pci:v00001507d00000003*
+ ID_PRODUCT_FROM_DATABASE=MPC8240 [Kahlua]
+
+pci:v00001507d00000100*
+ ID_PRODUCT_FROM_DATABASE=MC145575 [HFC-PCI]
+
+pci:v00001507d00000431*
+ ID_PRODUCT_FROM_DATABASE=KTI829c 100VG
+
+pci:v00001507d00004801*
+ ID_PRODUCT_FROM_DATABASE=Raven
+
+pci:v00001507d00004802*
+ ID_PRODUCT_FROM_DATABASE=Falcon
+
+pci:v00001507d00004803*
+ ID_PRODUCT_FROM_DATABASE=Hawk
+
+pci:v00001507d00004806*
+ ID_PRODUCT_FROM_DATABASE=CPX8216
+
+pci:v00001508*
+ ID_VENDOR_FROM_DATABASE=HONDA CONNECTORS/MHOTRONICS Inc
+
+pci:v00001509*
+ ID_VENDOR_FROM_DATABASE=FIRST INTERNATIONAL Computer Inc
+
+pci:v0000150A*
+ ID_VENDOR_FROM_DATABASE=FORVUS RESEARCH Inc
+
+pci:v0000150B*
+ ID_VENDOR_FROM_DATABASE=YAMASHITA Systems Corp
+
+pci:v0000150C*
+ ID_VENDOR_FROM_DATABASE=KYOPAL CO Ltd
+
+pci:v0000150D*
+ ID_VENDOR_FROM_DATABASE=WARPSPPED Inc
+
+pci:v0000150E*
+ ID_VENDOR_FROM_DATABASE=C-PORT Corp
+
+pci:v0000150F*
+ ID_VENDOR_FROM_DATABASE=INTEC GmbH
+
+pci:v00001510*
+ ID_VENDOR_FROM_DATABASE=BEHAVIOR TECH Computer Corp
+
+pci:v00001511*
+ ID_VENDOR_FROM_DATABASE=CENTILLIUM Technology Corp
+
+pci:v00001512*
+ ID_VENDOR_FROM_DATABASE=ROSUN Technologies Inc
+
+pci:v00001513*
+ ID_VENDOR_FROM_DATABASE=Raychem
+
+pci:v00001514*
+ ID_VENDOR_FROM_DATABASE=TFL LAN Inc
+
+pci:v00001515*
+ ID_VENDOR_FROM_DATABASE=Advent design
+
+pci:v00001516*
+ ID_VENDOR_FROM_DATABASE=MYSON Technology Inc
+
+pci:v00001516d00000800*
+ ID_PRODUCT_FROM_DATABASE=MTD-8xx 100/10M Ethernet PCI Adapter
+
+pci:v00001516d00000803*
+ ID_PRODUCT_FROM_DATABASE=SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
+
+pci:v00001516d00000803sv00001320sd000010BD*
+ ID_PRODUCT_FROM_DATABASE=SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
+
+pci:v00001516d00000891*
+ ID_PRODUCT_FROM_DATABASE=MTD-8xx 100/10M Ethernet PCI Adapter
+
+pci:v00001517*
+ ID_VENDOR_FROM_DATABASE=ECHOTEK Corp
+
+pci:v00001518*
+ ID_VENDOR_FROM_DATABASE=Kontron Modular Computers GmbH
+
+pci:v00001519*
+ ID_VENDOR_FROM_DATABASE=TELEFON AKTIEBOLAGET LM Ericsson
+
+pci:v0000151A*
+ ID_VENDOR_FROM_DATABASE=Globetek
+
+pci:v0000151Ad00001002*
+ ID_PRODUCT_FROM_DATABASE=PCI-1002
+
+pci:v0000151Ad00001004*
+ ID_PRODUCT_FROM_DATABASE=PCI-1004
+
+pci:v0000151Ad00001008*
+ ID_PRODUCT_FROM_DATABASE=PCI-1008
+
+pci:v0000151B*
+ ID_VENDOR_FROM_DATABASE=COMBOX Ltd
+
+pci:v0000151C*
+ ID_VENDOR_FROM_DATABASE=DIGITAL AUDIO LABS Inc
+
+pci:v0000151Cd00000003*
+ ID_PRODUCT_FROM_DATABASE=Prodif T 2496
+
+pci:v0000151Cd00004000*
+ ID_PRODUCT_FROM_DATABASE=Prodif 88
+
+pci:v0000151D*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Computer Products Of America
+
+pci:v0000151E*
+ ID_VENDOR_FROM_DATABASE=MATRIX Corp
+
+pci:v0000151F*
+ ID_VENDOR_FROM_DATABASE=TOPIC SEMICONDUCTOR Corp
+
+pci:v0000151Fd00000000*
+ ID_PRODUCT_FROM_DATABASE=TP560 Data/Fax/Voice 56k modem
+
+pci:v00001520*
+ ID_VENDOR_FROM_DATABASE=CHAPLET System Inc
+
+pci:v00001521*
+ ID_VENDOR_FROM_DATABASE=BELL Corp
+
+pci:v00001522*
+ ID_VENDOR_FROM_DATABASE=MainPine Ltd
+
+pci:v00001522d00000100*
+ ID_PRODUCT_FROM_DATABASE=PCI <-> IOBus Bridge
+
+pci:v00001522d00000100sv00001522sd00000200*
+ ID_PRODUCT_FROM_DATABASE=RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem
+
+pci:v00001522d00000100sv00001522sd00000300*
+ ID_PRODUCT_FROM_DATABASE=RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
+
+pci:v00001522d00000100sv00001522sd00000400*
+ ID_PRODUCT_FROM_DATABASE=RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
+
+pci:v00001522d00000100sv00001522sd00000500*
+ ID_PRODUCT_FROM_DATABASE=RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem
+
+pci:v00001522d00000100sv00001522sd00000600*
+ ID_PRODUCT_FROM_DATABASE=RockForce+ 2 Port V.90 Data/Fax/Voice Modem
+
+pci:v00001522d00000100sv00001522sd00000700*
+ ID_PRODUCT_FROM_DATABASE=RockForce+ 4 Port V.90 Data/Fax/Voice Modem
+
+pci:v00001522d00000100sv00001522sd00000800*
+ ID_PRODUCT_FROM_DATABASE=RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem
+
+pci:v00001522d00000100sv00001522sd00000C00*
+ ID_PRODUCT_FROM_DATABASE=RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+
+pci:v00001522d00000100sv00001522sd00000D00*
+ ID_PRODUCT_FROM_DATABASE=RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+
+pci:v00001522d00000100sv00001522sd00001D00*
+ ID_PRODUCT_FROM_DATABASE=RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+
+pci:v00001522d00000100sv00001522sd00002000*
+ ID_PRODUCT_FROM_DATABASE=RockForceD1 1 Port V.90 Data Modem
+
+pci:v00001522d00000100sv00001522sd00002100*
+ ID_PRODUCT_FROM_DATABASE=RockForceF1 1 Port V.34 Super-G3 Fax Modem
+
+pci:v00001522d00000100sv00001522sd00002200*
+ ID_PRODUCT_FROM_DATABASE=RockForceD2 2 Port V.90 Data Modem
+
+pci:v00001522d00000100sv00001522sd00002300*
+ ID_PRODUCT_FROM_DATABASE=RockForceF2 2 Port V.34 Super-G3 Fax Modem
+
+pci:v00001522d00000100sv00001522sd00002400*
+ ID_PRODUCT_FROM_DATABASE=RockForceD4 4 Port V.90 Data Modem
+
+pci:v00001522d00000100sv00001522sd00002500*
+ ID_PRODUCT_FROM_DATABASE=RockForceF4 4 Port V.34 Super-G3 Fax Modem
+
+pci:v00001522d00000100sv00001522sd00002600*
+ ID_PRODUCT_FROM_DATABASE=RockForceD8 8 Port V.90 Data Modem
+
+pci:v00001522d00000100sv00001522sd00002700*
+ ID_PRODUCT_FROM_DATABASE=RockForceF8 8 Port V.34 Super-G3 Fax Modem
+
+pci:v00001522d00000100sv00001522sd00003000*
+ ID_PRODUCT_FROM_DATABASE=IQ Express D1 - 1 Port V.92 Data Modem
+
+pci:v00001522d00000100sv00001522sd00003100*
+ ID_PRODUCT_FROM_DATABASE=IQ Express F1 - 1 Port V.34 Super-G3 Fax Modem
+
+pci:v00001522d00000100sv00001522sd00003200*
+ ID_PRODUCT_FROM_DATABASE=IQ Express D2 - 2 Port V.92 Data Modem
+
+pci:v00001522d00000100sv00001522sd00003300*
+ ID_PRODUCT_FROM_DATABASE=IQ Express F2 - 2 Port V.34 Super-G3 Fax Modem
+
+pci:v00001522d00000100sv00001522sd00003400*
+ ID_PRODUCT_FROM_DATABASE=IQ Express D4 - 4 Port V.92 Data Modem
+
+pci:v00001522d00000100sv00001522sd00003500*
+ ID_PRODUCT_FROM_DATABASE=IQ Express F4 - 4 Port V.34 Super-G3 Fax Modem
+
+pci:v00001522d00000100sv00001522sd00003C00*
+ ID_PRODUCT_FROM_DATABASE=IQ Express D8 - 8 Port V.92 Data Modem
+
+pci:v00001522d00000100sv00001522sd00003D00*
+ ID_PRODUCT_FROM_DATABASE=IQ Express F8 - 8 Port V.34 Super-G3 Fax Modem
+
+pci:v00001522d00004000*
+ ID_PRODUCT_FROM_DATABASE=PCI Express UART
+
+pci:v00001522d00004000sv00001522sd00004001*
+ ID_PRODUCT_FROM_DATABASE=IQ Express 1-port V.34 Super-G3 Fax
+
+pci:v00001522d00004000sv00001522sd00004002*
+ ID_PRODUCT_FROM_DATABASE=IQ Express 2-port V.34 Super-G3 Fax
+
+pci:v00001522d00004000sv00001522sd00004004*
+ ID_PRODUCT_FROM_DATABASE=IQ Express 4-port V.34 Super-G3 Fax
+
+pci:v00001522d00004000sv00001522sd00004008*
+ ID_PRODUCT_FROM_DATABASE=IQ Express 8-port V.34 Super-G3 Fax
+
+pci:v00001522d00004000sv00001522sd00004100*
+ ID_PRODUCT_FROM_DATABASE=IQ Express SideBand
+
+pci:v00001523*
+ ID_VENDOR_FROM_DATABASE=MUSIC Semiconductors
+
+pci:v00001524*
+ ID_VENDOR_FROM_DATABASE=ENE Technology Inc
+
+pci:v00001524d00000510*
+ ID_PRODUCT_FROM_DATABASE=CB710 Memory Card Reader Controller
+
+pci:v00001524d00000510sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00001524d00000520*
+ ID_PRODUCT_FROM_DATABASE=FLASH memory: ENE Technology Inc:
+
+pci:v00001524d00000530*
+ ID_PRODUCT_FROM_DATABASE=ENE PCI Memory Stick Card Reader Controller
+
+pci:v00001524d00000550*
+ ID_PRODUCT_FROM_DATABASE=ENE PCI Secure Digital Card Reader Controller
+
+pci:v00001524d00000551*
+ ID_PRODUCT_FROM_DATABASE=SD/MMC Card Reader Controller
+
+pci:v00001524d00000610*
+ ID_PRODUCT_FROM_DATABASE=PCI Smart Card Reader Controller
+
+pci:v00001524d00000720*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Card Reader Controller
+
+pci:v00001524d00000730*
+ ID_PRODUCT_FROM_DATABASE=ENE PCI Memory Stick Card Reader Controller
+
+pci:v00001524d00000750*
+ ID_PRODUCT_FROM_DATABASE=ENE PCI SmartMedia / xD Card Reader Controller
+
+pci:v00001524d00000751*
+ ID_PRODUCT_FROM_DATABASE=ENE PCI Secure Digital / MMC Card Reader Controller
+
+pci:v00001524d00001211*
+ ID_PRODUCT_FROM_DATABASE=CB1211 Cardbus Controller
+
+pci:v00001524d00001225*
+ ID_PRODUCT_FROM_DATABASE=CB1225 Cardbus Controller
+
+pci:v00001524d00001410*
+ ID_PRODUCT_FROM_DATABASE=CB1410 Cardbus Controller
+
+pci:v00001524d00001410sv00001025sd0000003C*
+ ID_PRODUCT_FROM_DATABASE=CL50 motherboard
+
+pci:v00001524d00001410sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00001524d00001411*
+ ID_PRODUCT_FROM_DATABASE=CB-710/2/4 Cardbus Controller
+
+pci:v00001524d00001411sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00001524d00001412*
+ ID_PRODUCT_FROM_DATABASE=CB-712/4 Cardbus Controller
+
+pci:v00001524d00001420*
+ ID_PRODUCT_FROM_DATABASE=CB1420 Cardbus Controller
+
+pci:v00001524d00001421*
+ ID_PRODUCT_FROM_DATABASE=CB-720/2/4 Cardbus Controller
+
+pci:v00001524d00001422*
+ ID_PRODUCT_FROM_DATABASE=CB-722/4 Cardbus Controller
+
+pci:v00001525*
+ ID_VENDOR_FROM_DATABASE=IMPACT Technologies
+
+pci:v00001526*
+ ID_VENDOR_FROM_DATABASE=ISS, Inc
+
+pci:v00001527*
+ ID_VENDOR_FROM_DATABASE=SOLECTRON
+
+pci:v00001528*
+ ID_VENDOR_FROM_DATABASE=ACKSYS
+
+pci:v00001529*
+ ID_VENDOR_FROM_DATABASE=AMERICAN MICROSystems Inc
+
+pci:v0000152A*
+ ID_VENDOR_FROM_DATABASE=QUICKTURN DESIGN Systems
+
+pci:v0000152B*
+ ID_VENDOR_FROM_DATABASE=FLYTECH Technology CO Ltd
+
+pci:v0000152C*
+ ID_VENDOR_FROM_DATABASE=MACRAIGOR Systems LLC
+
+pci:v0000152D*
+ ID_VENDOR_FROM_DATABASE=QUANTA Computer Inc
+
+pci:v0000152E*
+ ID_VENDOR_FROM_DATABASE=MELEC Inc
+
+pci:v0000152F*
+ ID_VENDOR_FROM_DATABASE=PHILIPS - CRYPTO
+
+pci:v00001530*
+ ID_VENDOR_FROM_DATABASE=ACQIS Technology Inc
+
+pci:v00001531*
+ ID_VENDOR_FROM_DATABASE=CHRYON Corp
+
+pci:v00001532*
+ ID_VENDOR_FROM_DATABASE=ECHELON Corp
+
+pci:v00001532d00000020*
+ ID_PRODUCT_FROM_DATABASE=LonWorks PCLTA-20 PCI LonTalk Adapter
+
+pci:v00001533*
+ ID_VENDOR_FROM_DATABASE=BALTIMORE
+
+pci:v00001534*
+ ID_VENDOR_FROM_DATABASE=ROAD Corp
+
+pci:v00001535*
+ ID_VENDOR_FROM_DATABASE=EVERGREEN Technologies Inc
+
+pci:v00001536*
+ ID_VENDOR_FROM_DATABASE=ACTIS Computer
+
+pci:v00001537*
+ ID_VENDOR_FROM_DATABASE=DATALEX COMMUNCATIONS
+
+pci:v00001538*
+ ID_VENDOR_FROM_DATABASE=ARALION Inc
+
+pci:v00001538d00000303*
+ ID_PRODUCT_FROM_DATABASE=ARS106S Ultra ATA 133/100/66 Host Controller
+
+pci:v00001539*
+ ID_VENDOR_FROM_DATABASE=ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A.
+
+pci:v0000153A*
+ ID_VENDOR_FROM_DATABASE=ONO SOKKI
+
+pci:v0000153B*
+ ID_VENDOR_FROM_DATABASE=TERRATEC Electronic GmbH
+
+pci:v0000153Bd00001144*
+ ID_PRODUCT_FROM_DATABASE=Aureon 5.1
+
+pci:v0000153Bd00001147*
+ ID_PRODUCT_FROM_DATABASE=Aureon 5.1 Sky
+
+pci:v0000153Bd00001158*
+ ID_PRODUCT_FROM_DATABASE=Philips Semiconductors SAA7134 (rev 01) [Terratec Cinergy 600 TV]
+
+pci:v0000153C*
+ ID_VENDOR_FROM_DATABASE=ANTAL Electronic
+
+pci:v0000153D*
+ ID_VENDOR_FROM_DATABASE=FILANET Corp
+
+pci:v0000153E*
+ ID_VENDOR_FROM_DATABASE=TECHWELL Inc
+
+pci:v0000153F*
+ ID_VENDOR_FROM_DATABASE=MIPS Technologies, Inc.
+
+pci:v0000153Fd00000001*
+ ID_PRODUCT_FROM_DATABASE=SOC-it 101 System Controller
+
+pci:v00001540*
+ ID_VENDOR_FROM_DATABASE=PROVIDEO MULTIMEDIA Co Ltd
+
+pci:v00001541*
+ ID_VENDOR_FROM_DATABASE=MACHONE Communications
+
+pci:v00001542*
+ ID_VENDOR_FROM_DATABASE=Concurrent Computer Corporation
+
+pci:v00001542d00009260*
+ ID_PRODUCT_FROM_DATABASE=RCIM-II Real-Time Clock & Interrupt Module
+
+pci:v00001543*
+ ID_VENDOR_FROM_DATABASE=SILICON Laboratories
+
+pci:v00001543d00003052*
+ ID_PRODUCT_FROM_DATABASE=Intel 537 [Winmodem]
+
+pci:v00001543d00003155*
+ ID_PRODUCT_FROM_DATABASE=Motorola SM56 Speakerphone Modem
+
+pci:v00001543d00004C22*
+ ID_PRODUCT_FROM_DATABASE=Si3036 MC'97 DAA
+
+pci:v00001544*
+ ID_VENDOR_FROM_DATABASE=DCM DATA Systems
+
+pci:v00001545*
+ ID_VENDOR_FROM_DATABASE=VISIONTEK
+
+pci:v00001546*
+ ID_VENDOR_FROM_DATABASE=IOI Technology Corp
+
+pci:v00001547*
+ ID_VENDOR_FROM_DATABASE=MITUTOYO Corp
+
+pci:v00001548*
+ ID_VENDOR_FROM_DATABASE=JET PROPULSION Laboratory
+
+pci:v00001549*
+ ID_VENDOR_FROM_DATABASE=INTERCONNECT Systems Solutions
+
+pci:v0000154A*
+ ID_VENDOR_FROM_DATABASE=MAX Technologies Inc
+
+pci:v0000154B*
+ ID_VENDOR_FROM_DATABASE=COMPUTEX Co Ltd
+
+pci:v0000154C*
+ ID_VENDOR_FROM_DATABASE=VISUAL Technology Inc
+
+pci:v0000154D*
+ ID_VENDOR_FROM_DATABASE=PAN INTERNATIONAL Industrial Corp
+
+pci:v0000154E*
+ ID_VENDOR_FROM_DATABASE=SERVOTEST Ltd
+
+pci:v0000154F*
+ ID_VENDOR_FROM_DATABASE=STRATABEAM Technology
+
+pci:v00001550*
+ ID_VENDOR_FROM_DATABASE=OPEN NETWORK Co Ltd
+
+pci:v00001551*
+ ID_VENDOR_FROM_DATABASE=SMART Electronic DEVELOPMENT GmBH
+
+pci:v00001552*
+ ID_VENDOR_FROM_DATABASE=RACAL AIRTECH Ltd
+
+pci:v00001553*
+ ID_VENDOR_FROM_DATABASE=CHICONY Electronics Co Ltd
+
+pci:v00001554*
+ ID_VENDOR_FROM_DATABASE=PROLINK Microsystems Corp
+
+pci:v00001555*
+ ID_VENDOR_FROM_DATABASE=GESYTEC GmBH
+
+pci:v00001556*
+ ID_VENDOR_FROM_DATABASE=PLD APPLICATIONS
+
+pci:v00001557*
+ ID_VENDOR_FROM_DATABASE=MEDIASTAR Co Ltd
+
+pci:v00001558*
+ ID_VENDOR_FROM_DATABASE=CLEVO/KAPOK Computer
+
+pci:v00001559*
+ ID_VENDOR_FROM_DATABASE=SI LOGIC Ltd
+
+pci:v0000155A*
+ ID_VENDOR_FROM_DATABASE=INNOMEDIA Inc
+
+pci:v0000155B*
+ ID_VENDOR_FROM_DATABASE=PROTAC INTERNATIONAL Corp
+
+pci:v0000155C*
+ ID_VENDOR_FROM_DATABASE=Cemax-Icon Inc
+
+pci:v0000155D*
+ ID_VENDOR_FROM_DATABASE=Mac System Co Ltd
+
+pci:v0000155E*
+ ID_VENDOR_FROM_DATABASE=LP Elektronik GmbH
+
+pci:v0000155F*
+ ID_VENDOR_FROM_DATABASE=Perle Systems Ltd
+
+pci:v00001560*
+ ID_VENDOR_FROM_DATABASE=Terayon Communications Systems
+
+pci:v00001561*
+ ID_VENDOR_FROM_DATABASE=Viewgraphics Inc
+
+pci:v00001562*
+ ID_VENDOR_FROM_DATABASE=Symbol Technologies
+
+pci:v00001563*
+ ID_VENDOR_FROM_DATABASE=A-Trend Technology Co Ltd
+
+pci:v00001564*
+ ID_VENDOR_FROM_DATABASE=Yamakatsu Electronics Industry Co Ltd
+
+pci:v00001565*
+ ID_VENDOR_FROM_DATABASE=Biostar Microtech Int'l Corp
+
+pci:v00001566*
+ ID_VENDOR_FROM_DATABASE=Ardent Technologies Inc
+
+pci:v00001567*
+ ID_VENDOR_FROM_DATABASE=Jungsoft
+
+pci:v00001568*
+ ID_VENDOR_FROM_DATABASE=DDK Electronics Inc
+
+pci:v00001569*
+ ID_VENDOR_FROM_DATABASE=Palit Microsystems Inc.
+
+pci:v0000156A*
+ ID_VENDOR_FROM_DATABASE=Avtec Systems
+
+pci:v0000156B*
+ ID_VENDOR_FROM_DATABASE=2wire Inc
+
+pci:v0000156C*
+ ID_VENDOR_FROM_DATABASE=Vidac Electronics GmbH
+
+pci:v0000156D*
+ ID_VENDOR_FROM_DATABASE=Alpha-Top Corp
+
+pci:v0000156E*
+ ID_VENDOR_FROM_DATABASE=Alfa Inc
+
+pci:v0000156F*
+ ID_VENDOR_FROM_DATABASE=M-Systems Flash Disk Pioneers Ltd
+
+pci:v00001570*
+ ID_VENDOR_FROM_DATABASE=Lecroy Corp
+
+pci:v00001571*
+ ID_VENDOR_FROM_DATABASE=Contemporary Controls
+
+pci:v00001571d0000A001*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-485 ARCnet
+
+pci:v00001571d0000A002*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-485D ARCnet
+
+pci:v00001571d0000A003*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-485X ARCnet
+
+pci:v00001571d0000A004*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-CXB ARCnet
+
+pci:v00001571d0000A005*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-CXS ARCnet
+
+pci:v00001571d0000A006*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-FOG-SMA ARCnet
+
+pci:v00001571d0000A007*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-FOG-ST ARCnet
+
+pci:v00001571d0000A008*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-TB5 ARCnet
+
+pci:v00001571d0000A009*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-485 5Mbit ARCnet
+
+pci:v00001571d0000A00A*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-485D 5Mbit ARCnet
+
+pci:v00001571d0000A00B*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-485X 5Mbit ARCnet
+
+pci:v00001571d0000A00C*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-FOG-ST 5Mbit ARCnet
+
+pci:v00001571d0000A00D*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-FOG-SMA 5Mbit ARCnet
+
+pci:v00001571d0000A201*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI22-485 10Mbit ARCnet
+
+pci:v00001571d0000A202*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI22-485D 10Mbit ARCnet
+
+pci:v00001571d0000A203*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI22-485X 10Mbit ARCnet
+
+pci:v00001571d0000A204*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI22-CHB 10Mbit ARCnet
+
+pci:v00001571d0000A205*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI22-FOG_ST 10Mbit ARCnet
+
+pci:v00001571d0000A206*
+ ID_PRODUCT_FROM_DATABASE=CCSI PCI22-THB 10Mbit ARCnet
+
+pci:v00001572*
+ ID_VENDOR_FROM_DATABASE=Otis Elevator Company
+
+pci:v00001573*
+ ID_VENDOR_FROM_DATABASE=Lattice - Vantis
+
+pci:v00001574*
+ ID_VENDOR_FROM_DATABASE=Fairchild Semiconductor
+
+pci:v00001575*
+ ID_VENDOR_FROM_DATABASE=Voltaire Advanced Data Security Ltd
+
+pci:v00001576*
+ ID_VENDOR_FROM_DATABASE=Viewcast COM
+
+pci:v00001578*
+ ID_VENDOR_FROM_DATABASE=HITT
+
+pci:v00001578d00004D34*
+ ID_PRODUCT_FROM_DATABASE=VPMK4 [Video Processor Mk IV]
+
+pci:v00001578d00005615*
+ ID_PRODUCT_FROM_DATABASE=VPMK3 [Video Processor Mk III]
+
+pci:v00001579*
+ ID_VENDOR_FROM_DATABASE=Dual Technology Corp
+
+pci:v0000157A*
+ ID_VENDOR_FROM_DATABASE=Japan Elecronics Ind Inc
+
+pci:v0000157B*
+ ID_VENDOR_FROM_DATABASE=Star Multimedia Corp
+
+pci:v0000157C*
+ ID_VENDOR_FROM_DATABASE=Eurosoft (UK)
+
+pci:v0000157Cd00008001*
+ ID_PRODUCT_FROM_DATABASE=Fix2000 PCI Y2K Compliance Card
+
+pci:v0000157D*
+ ID_VENDOR_FROM_DATABASE=Gemflex Networks
+
+pci:v0000157E*
+ ID_VENDOR_FROM_DATABASE=Transition Networks
+
+pci:v0000157F*
+ ID_VENDOR_FROM_DATABASE=PX Instruments Technology Ltd
+
+pci:v00001580*
+ ID_VENDOR_FROM_DATABASE=Primex Aerospace Co
+
+pci:v00001581*
+ ID_VENDOR_FROM_DATABASE=SEH Computertechnik GmbH
+
+pci:v00001582*
+ ID_VENDOR_FROM_DATABASE=Cytec Corp
+
+pci:v00001583*
+ ID_VENDOR_FROM_DATABASE=Inet Technologies Inc
+
+pci:v00001584*
+ ID_VENDOR_FROM_DATABASE=Uniwill Computer Corp
+
+pci:v00001585*
+ ID_VENDOR_FROM_DATABASE=Logitron
+
+pci:v00001586*
+ ID_VENDOR_FROM_DATABASE=Lancast Inc
+
+pci:v00001587*
+ ID_VENDOR_FROM_DATABASE=Konica Corp
+
+pci:v00001588*
+ ID_VENDOR_FROM_DATABASE=Solidum Systems Corp
+
+pci:v00001589*
+ ID_VENDOR_FROM_DATABASE=Atlantek Microsystems Pty Ltd
+
+pci:v00001589d00000008*
+ ID_PRODUCT_FROM_DATABASE=Leutron Vision PicPortExpress CL
+
+pci:v00001589d00000009*
+ ID_PRODUCT_FROM_DATABASE=Leutron Vision PicPortExpress CL Stereo
+
+pci:v0000158A*
+ ID_VENDOR_FROM_DATABASE=Digalog Systems Inc
+
+pci:v0000158B*
+ ID_VENDOR_FROM_DATABASE=Allied Data Technologies
+
+pci:v0000158C*
+ ID_VENDOR_FROM_DATABASE=Hitachi Semiconductor & Devices Sales Co Ltd
+
+pci:v0000158D*
+ ID_VENDOR_FROM_DATABASE=Point Multimedia Systems
+
+pci:v0000158E*
+ ID_VENDOR_FROM_DATABASE=Lara Technology Inc
+
+pci:v0000158F*
+ ID_VENDOR_FROM_DATABASE=Ditect Coop
+
+pci:v00001590*
+ ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company
+
+pci:v00001590d00000001*
+ ID_PRODUCT_FROM_DATABASE=Eagle Cluster Manager
+
+pci:v00001590d00000002*
+ ID_PRODUCT_FROM_DATABASE=Osprey Cluster Manager
+
+pci:v00001590d00000003*
+ ID_PRODUCT_FROM_DATABASE=Harrier Cluster Manager
+
+pci:v00001590d0000A01D*
+ ID_PRODUCT_FROM_DATABASE=FC044X Fibre Channel HBA
+
+pci:v00001591*
+ ID_VENDOR_FROM_DATABASE=ARN
+
+pci:v00001592*
+ ID_VENDOR_FROM_DATABASE=Syba Tech Ltd
+
+pci:v00001592d00000781*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v00001592d00000782*
+ ID_PRODUCT_FROM_DATABASE=Parallel Port Card 2xEPP
+
+pci:v00001592d00000783*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v00001592d00000785*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v00001592d00000786*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v00001592d00000787*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v00001592d00000788*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v00001592d0000078A*
+ ID_PRODUCT_FROM_DATABASE=Multi-IO Card
+
+pci:v00001593*
+ ID_VENDOR_FROM_DATABASE=Bops Inc
+
+pci:v00001594*
+ ID_VENDOR_FROM_DATABASE=Netgame Ltd
+
+pci:v00001595*
+ ID_VENDOR_FROM_DATABASE=Diva Systems Corp
+
+pci:v00001596*
+ ID_VENDOR_FROM_DATABASE=Folsom Research Inc
+
+pci:v00001597*
+ ID_VENDOR_FROM_DATABASE=Memec Design Services
+
+pci:v00001598*
+ ID_VENDOR_FROM_DATABASE=Granite Microsystems
+
+pci:v00001599*
+ ID_VENDOR_FROM_DATABASE=Delta Electronics Inc
+
+pci:v0000159A*
+ ID_VENDOR_FROM_DATABASE=General Instrument
+
+pci:v0000159B*
+ ID_VENDOR_FROM_DATABASE=Faraday Technology Corp
+
+pci:v0000159C*
+ ID_VENDOR_FROM_DATABASE=Stratus Computer Systems
+
+pci:v0000159D*
+ ID_VENDOR_FROM_DATABASE=Ningbo Harrison Electronics Co Ltd
+
+pci:v0000159E*
+ ID_VENDOR_FROM_DATABASE=A-Max Technology Co Ltd
+
+pci:v0000159F*
+ ID_VENDOR_FROM_DATABASE=Galea Network Security
+
+pci:v000015A0*
+ ID_VENDOR_FROM_DATABASE=Compumaster SRL
+
+pci:v000015A1*
+ ID_VENDOR_FROM_DATABASE=Geocast Network Systems
+
+pci:v000015A2*
+ ID_VENDOR_FROM_DATABASE=Catalyst Enterprises Inc
+
+pci:v000015A2d00000001*
+ ID_PRODUCT_FROM_DATABASE=TA700 PCI Bus Analyzer/Exerciser
+
+pci:v000015A3*
+ ID_VENDOR_FROM_DATABASE=Italtel
+
+pci:v000015A4*
+ ID_VENDOR_FROM_DATABASE=X-Net OY
+
+pci:v000015A5*
+ ID_VENDOR_FROM_DATABASE=Toyota Macs Inc
+
+pci:v000015A6*
+ ID_VENDOR_FROM_DATABASE=Sunlight Ultrasound Technologies Ltd
+
+pci:v000015A7*
+ ID_VENDOR_FROM_DATABASE=SSE Telecom Inc
+
+pci:v000015A8*
+ ID_VENDOR_FROM_DATABASE=Shanghai Communications Technologies Center
+
+pci:v000015AA*
+ ID_VENDOR_FROM_DATABASE=Moreton Bay
+
+pci:v000015AB*
+ ID_VENDOR_FROM_DATABASE=Bluesteel Networks Inc
+
+pci:v000015AC*
+ ID_VENDOR_FROM_DATABASE=North Atlantic Instruments
+
+pci:v000015AD*
+ ID_VENDOR_FROM_DATABASE=VMware
+
+pci:v000015ADd00000405*
+ ID_PRODUCT_FROM_DATABASE=SVGA II Adapter
+
+pci:v000015ADd00000710*
+ ID_PRODUCT_FROM_DATABASE=SVGA Adapter
+
+pci:v000015ADd00000720*
+ ID_PRODUCT_FROM_DATABASE=VMXNET Ethernet Controller
+
+pci:v000015ADd00000740*
+ ID_PRODUCT_FROM_DATABASE=Virtual Machine Communication Interface
+
+pci:v000015ADd00000770*
+ ID_PRODUCT_FROM_DATABASE=USB2 EHCI Controller
+
+pci:v000015ADd00000774*
+ ID_PRODUCT_FROM_DATABASE=USB1.1 UHCI Controller
+
+pci:v000015ADd00000790*
+ ID_PRODUCT_FROM_DATABASE=PCI bridge
+
+pci:v000015ADd000007A0*
+ ID_PRODUCT_FROM_DATABASE=PCI Express Root Port
+
+pci:v000015ADd000007B0*
+ ID_PRODUCT_FROM_DATABASE=VMXNET3 Ethernet Controller
+
+pci:v000015ADd000007C0*
+ ID_PRODUCT_FROM_DATABASE=PVSCSI SCSI Controller
+
+pci:v000015ADd00000801*
+ ID_PRODUCT_FROM_DATABASE=Virtual Machine Interface
+
+pci:v000015ADd00000801sv000015ADsd00000800*
+ ID_PRODUCT_FROM_DATABASE=Hypervisor ROM Interface
+
+pci:v000015ADd00001977*
+ ID_PRODUCT_FROM_DATABASE=HD Audio Controller
+
+pci:v000015AE*
+ ID_VENDOR_FROM_DATABASE=Amersham Pharmacia Biotech
+
+pci:v000015B0*
+ ID_VENDOR_FROM_DATABASE=Zoltrix International Ltd
+
+pci:v000015B1*
+ ID_VENDOR_FROM_DATABASE=Source Technology Inc
+
+pci:v000015B2*
+ ID_VENDOR_FROM_DATABASE=Mosaid Technologies Inc
+
+pci:v000015B3*
+ ID_VENDOR_FROM_DATABASE=Mellanox Technologies
+
+pci:v000015B3d00000191*
+ ID_PRODUCT_FROM_DATABASE=MT25408 [ConnectX IB Flash Recovery]
+
+pci:v000015B3d000001F6*
+ ID_PRODUCT_FROM_DATABASE=MT27500 Family [ConnectX-3 Flash Recovery]
+
+pci:v000015B3d000001FF*
+ ID_PRODUCT_FROM_DATABASE=MT27600 Family [Connect-IB Flash Recovery]
+
+pci:v000015B3d00001002*
+ ID_PRODUCT_FROM_DATABASE=MT25400 Family [ConnectX-2 Virtual Function]
+
+pci:v000015B3d00001003*
+ ID_PRODUCT_FROM_DATABASE=MT27500 Family [ConnectX-3]
+
+pci:v000015B3d00001004*
+ ID_PRODUCT_FROM_DATABASE=MT27500 Family [ConnectX-3 Virtual Function]
+
+pci:v000015B3d00001005*
+ ID_PRODUCT_FROM_DATABASE=MT27510 Family
+
+pci:v000015B3d00001006*
+ ID_PRODUCT_FROM_DATABASE=MT27511 Family
+
+pci:v000015B3d00001007*
+ ID_PRODUCT_FROM_DATABASE=MT27520 Family
+
+pci:v000015B3d00001008*
+ ID_PRODUCT_FROM_DATABASE=MT27521 Family
+
+pci:v000015B3d00001009*
+ ID_PRODUCT_FROM_DATABASE=MT27530 Family
+
+pci:v000015B3d0000100A*
+ ID_PRODUCT_FROM_DATABASE=MT27531 Family
+
+pci:v000015B3d0000100B*
+ ID_PRODUCT_FROM_DATABASE=MT27540 Family
+
+pci:v000015B3d0000100C*
+ ID_PRODUCT_FROM_DATABASE=MT27541 Family
+
+pci:v000015B3d0000100D*
+ ID_PRODUCT_FROM_DATABASE=MT27550 Family
+
+pci:v000015B3d0000100E*
+ ID_PRODUCT_FROM_DATABASE=MT27551 Family
+
+pci:v000015B3d0000100F*
+ ID_PRODUCT_FROM_DATABASE=MT27560 Family
+
+pci:v000015B3d00001010*
+ ID_PRODUCT_FROM_DATABASE=MT27561 Family
+
+pci:v000015B3d00001011*
+ ID_PRODUCT_FROM_DATABASE=MT27600 [Connect-IB]
+
+pci:v000015B3d00001012*
+ ID_PRODUCT_FROM_DATABASE=MT27600 Family [Connect-IB Virtual Function]
+
+pci:v000015B3d00001013*
+ ID_PRODUCT_FROM_DATABASE=MT27620 Family
+
+pci:v000015B3d00001014*
+ ID_PRODUCT_FROM_DATABASE=MT27621 Family
+
+pci:v000015B3d00001015*
+ ID_PRODUCT_FROM_DATABASE=MT27630 Family
+
+pci:v000015B3d00001016*
+ ID_PRODUCT_FROM_DATABASE=MT27631 Family
+
+pci:v000015B3d00005274*
+ ID_PRODUCT_FROM_DATABASE=MT21108 InfiniBridge
+
+pci:v000015B3d00005A44*
+ ID_PRODUCT_FROM_DATABASE=MT23108 InfiniHost
+
+pci:v000015B3d00005A45*
+ ID_PRODUCT_FROM_DATABASE=MT23108 [Infinihost HCA Flash Recovery]
+
+pci:v000015B3d00005A46*
+ ID_PRODUCT_FROM_DATABASE=MT23108 PCI Bridge
+
+pci:v000015B3d00005E8C*
+ ID_PRODUCT_FROM_DATABASE=MT24204 [InfiniHost III Lx HCA]
+
+pci:v000015B3d00005E8D*
+ ID_PRODUCT_FROM_DATABASE=MT25204 [InfiniHost III Lx HCA Flash Recovery]
+
+pci:v000015B3d00006274*
+ ID_PRODUCT_FROM_DATABASE=MT25204 [InfiniHost III Lx HCA]
+
+pci:v000015B3d00006278*
+ ID_PRODUCT_FROM_DATABASE=MT25208 InfiniHost III Ex (Tavor compatibility mode)
+
+pci:v000015B3d00006279*
+ ID_PRODUCT_FROM_DATABASE=MT25208 [InfiniHost III Ex HCA Flash Recovery]
+
+pci:v000015B3d00006282*
+ ID_PRODUCT_FROM_DATABASE=MT25208 [InfiniHost III Ex]
+
+pci:v000015B3d00006340*
+ ID_PRODUCT_FROM_DATABASE=MT25408 [ConnectX VPI - IB SDR / 10GigE]
+
+pci:v000015B3d0000634A*
+ ID_PRODUCT_FROM_DATABASE=MT25418 [ConnectX VPI PCIe 2.0 2.5GT/s - IB DDR / 10GigE]
+
+pci:v000015B3d00006368*
+ ID_PRODUCT_FROM_DATABASE=MT25448 [ConnectX EN 10GigE, PCIe 2.0 2.5GT/s]
+
+pci:v000015B3d00006372*
+ ID_PRODUCT_FROM_DATABASE=MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe 2.0 2.5GT/s]
+
+pci:v000015B3d00006732*
+ ID_PRODUCT_FROM_DATABASE=MT26418 [ConnectX VPI PCIe 2.0 5GT/s - IB DDR / 10GigE]
+
+pci:v000015B3d0000673C*
+ ID_PRODUCT_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE]
+
+pci:v000015B3d00006746*
+ ID_PRODUCT_FROM_DATABASE=MT26438 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE Virtualization+]
+
+pci:v000015B3d00006746sv0000103Csd00001781*
+ ID_PRODUCT_FROM_DATABASE=NC543i 1-port 4x QDR IB/Flex-10 10Gb Adapter
+
+pci:v000015B3d00006746sv0000103Csd00003349*
+ ID_PRODUCT_FROM_DATABASE=NC543i 2-port 4xQDR IB/10Gb Adapter
+
+pci:v000015B3d00006750*
+ ID_PRODUCT_FROM_DATABASE=MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s]
+
+pci:v000015B3d0000675A*
+ ID_PRODUCT_FROM_DATABASE=MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe Gen2 5GT/s]
+
+pci:v000015B3d00006764*
+ ID_PRODUCT_FROM_DATABASE=MT26468 [ConnectX EN 10GigE, PCIe 2.0 5GT/s Virtualization+]
+
+pci:v000015B3d00006764sv0000103Csd00003313*
+ ID_PRODUCT_FROM_DATABASE=HP NC542m Dual Port Flex-10 10GbE BLc Adapter
+
+pci:v000015B3d0000676E*
+ ID_PRODUCT_FROM_DATABASE=MT26478 [ConnectX EN 40GigE, PCIe 2.0 5GT/s]
+
+pci:v000015B3d00006778*
+ ID_PRODUCT_FROM_DATABASE=MT26488 [ConnectX VPI PCIe 2.0 5GT/s - IB DDR / 10GigE Virtualization+]
+
+pci:v000015B4*
+ ID_VENDOR_FROM_DATABASE=CCI/TRIAD
+
+pci:v000015B5*
+ ID_VENDOR_FROM_DATABASE=Cimetrics Inc
+
+pci:v000015B6*
+ ID_VENDOR_FROM_DATABASE=Texas Memory Systems Inc
+
+pci:v000015B6d00000001*
+ ID_PRODUCT_FROM_DATABASE=XP15 DSP Accelerator
+
+pci:v000015B6d00000002*
+ ID_PRODUCT_FROM_DATABASE=XP30 DSP Accelerator
+
+pci:v000015B6d00000003*
+ ID_PRODUCT_FROM_DATABASE=XP00 Data Acquisition Device
+
+pci:v000015B6d00000004*
+ ID_PRODUCT_FROM_DATABASE=XP35 DSP Accelerator
+
+pci:v000015B6d00000007*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-T0]
+
+pci:v000015B6d00000008*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-T1]
+
+pci:v000015B6d00000009*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-E0]
+
+pci:v000015B6d0000000A*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-E1]
+
+pci:v000015B6d0000000E*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-0]
+
+pci:v000015B6d0000000F*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-1]
+
+pci:v000015B6d00000010*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-P0]
+
+pci:v000015B6d00000011*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-P1]
+
+pci:v000015B6d00000012*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-P2]
+
+pci:v000015B6d00000013*
+ ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-P3]
+
+pci:v000015B6d00000014*
+ ID_PRODUCT_FROM_DATABASE=RamSan Flash SSD
+
+pci:v000015B6d00000015*
+ ID_PRODUCT_FROM_DATABASE=ZBox
+
+pci:v000015B7*
+ ID_VENDOR_FROM_DATABASE=Sandisk Corp
+
+pci:v000015B8*
+ ID_VENDOR_FROM_DATABASE=ADDI-DATA GmbH
+
+pci:v000015B8d00001001*
+ ID_PRODUCT_FROM_DATABASE=APCI1516 SP controller (16 digi outputs)
+
+pci:v000015B8d00001003*
+ ID_PRODUCT_FROM_DATABASE=APCI1032 SP controller (32 digi inputs w/ opto coupler)
+
+pci:v000015B8d00001004*
+ ID_PRODUCT_FROM_DATABASE=APCI2032 SP controller (32 digi outputs)
+
+pci:v000015B8d00001005*
+ ID_PRODUCT_FROM_DATABASE=APCI2200 SP controller (8/16 digi outputs (relay))
+
+pci:v000015B8d00001006*
+ ID_PRODUCT_FROM_DATABASE=APCI1564 SP controller (32 digi ins, 32 digi outs)
+
+pci:v000015B8d0000100A*
+ ID_PRODUCT_FROM_DATABASE=APCI1696 SP controller (96 TTL I/Os)
+
+pci:v000015B8d00003001*
+ ID_PRODUCT_FROM_DATABASE=APCI3501 SP controller (analog output board)
+
+pci:v000015B8d0000300F*
+ ID_PRODUCT_FROM_DATABASE=APCI3600 Noise and vibration measurement board
+
+pci:v000015B8d00007001*
+ ID_PRODUCT_FROM_DATABASE=APCI7420 2-port Serial Controller
+
+pci:v000015B8d00007002*
+ ID_PRODUCT_FROM_DATABASE=APCI7300 Serial Controller
+
+pci:v000015B9*
+ ID_VENDOR_FROM_DATABASE=Maestro Digital Communications
+
+pci:v000015BA*
+ ID_VENDOR_FROM_DATABASE=Impacct Technology Corp
+
+pci:v000015BB*
+ ID_VENDOR_FROM_DATABASE=Portwell Inc
+
+pci:v000015BC*
+ ID_VENDOR_FROM_DATABASE=Agilent Technologies
+
+pci:v000015BCd00000100*
+ ID_PRODUCT_FROM_DATABASE=HPFC-5600 Tachyon DX2+ FC
+
+pci:v000015BCd00000103*
+ ID_PRODUCT_FROM_DATABASE=QX4 PCI Express quad 4-gigabit Fibre Channel controller
+
+pci:v000015BCd00000105*
+ ID_PRODUCT_FROM_DATABASE=Celerity FC-42XS Fibre Channel Adapter
+
+pci:v000015BCd00000105sv0000117Csd00000022*
+ ID_PRODUCT_FROM_DATABASE=Celerity FC-42XS Fibre Channel Adapter
+
+pci:v000015BCd00001100*
+ ID_PRODUCT_FROM_DATABASE=E8001-66442 PCI Express CIC
+
+pci:v000015BCd00002922*
+ ID_PRODUCT_FROM_DATABASE=64 Bit, 133MHz PCI-X Exerciser & Protocol Checker
+
+pci:v000015BCd00002928*
+ ID_PRODUCT_FROM_DATABASE=64 Bit, 66MHz PCI Exerciser & Analyzer
+
+pci:v000015BCd00002929*
+ ID_PRODUCT_FROM_DATABASE=64 Bit, 133MHz PCI-X Analyzer & Exerciser
+
+pci:v000015BD*
+ ID_VENDOR_FROM_DATABASE=DFI Inc
+
+pci:v000015BE*
+ ID_VENDOR_FROM_DATABASE=Sola Electronics
+
+pci:v000015BF*
+ ID_VENDOR_FROM_DATABASE=High Tech Computer Corp (HTC)
+
+pci:v000015C0*
+ ID_VENDOR_FROM_DATABASE=BVM Ltd
+
+pci:v000015C1*
+ ID_VENDOR_FROM_DATABASE=Quantel
+
+pci:v000015C2*
+ ID_VENDOR_FROM_DATABASE=Newer Technology Inc
+
+pci:v000015C3*
+ ID_VENDOR_FROM_DATABASE=Taiwan Mycomp Co Ltd
+
+pci:v000015C4*
+ ID_VENDOR_FROM_DATABASE=EVSX Inc
+
+pci:v000015C5*
+ ID_VENDOR_FROM_DATABASE=Procomp Informatics Ltd
+
+pci:v000015C5d00008010*
+ ID_PRODUCT_FROM_DATABASE=1394b - 1394 Firewire 3-Port Host Adapter Card
+
+pci:v000015C6*
+ ID_VENDOR_FROM_DATABASE=Technical University of Budapest
+
+pci:v000015C7*
+ ID_VENDOR_FROM_DATABASE=Tateyama System Laboratory Co Ltd
+
+pci:v000015C7d00000349*
+ ID_PRODUCT_FROM_DATABASE=Tateyama C-PCI PLC/NC card Rev.01A
+
+pci:v000015C8*
+ ID_VENDOR_FROM_DATABASE=Penta Media Co Ltd
+
+pci:v000015C9*
+ ID_VENDOR_FROM_DATABASE=Serome Technology Inc
+
+pci:v000015CA*
+ ID_VENDOR_FROM_DATABASE=Bitboys OY
+
+pci:v000015CB*
+ ID_VENDOR_FROM_DATABASE=AG Electronics Ltd
+
+pci:v000015CC*
+ ID_VENDOR_FROM_DATABASE=Hotrail Inc
+
+pci:v000015CD*
+ ID_VENDOR_FROM_DATABASE=Dreamtech Co Ltd
+
+pci:v000015CE*
+ ID_VENDOR_FROM_DATABASE=Genrad Inc
+
+pci:v000015CF*
+ ID_VENDOR_FROM_DATABASE=Hilscher GmbH
+
+pci:v000015D1*
+ ID_VENDOR_FROM_DATABASE=Infineon Technologies AG
+
+pci:v000015D2*
+ ID_VENDOR_FROM_DATABASE=FIC (First International Computer Inc)
+
+pci:v000015D3*
+ ID_VENDOR_FROM_DATABASE=NDS Technologies Israel Ltd
+
+pci:v000015D4*
+ ID_VENDOR_FROM_DATABASE=Iwill Corp
+
+pci:v000015D5*
+ ID_VENDOR_FROM_DATABASE=Tatung Co
+
+pci:v000015D6*
+ ID_VENDOR_FROM_DATABASE=Entridia Corp
+
+pci:v000015D7*
+ ID_VENDOR_FROM_DATABASE=Rockwell-Collins Inc
+
+pci:v000015D8*
+ ID_VENDOR_FROM_DATABASE=Cybernetics Technology Co Ltd
+
+pci:v000015D9*
+ ID_VENDOR_FROM_DATABASE=Super Micro Computer Inc
+
+pci:v000015DA*
+ ID_VENDOR_FROM_DATABASE=Cyberfirm Inc
+
+pci:v000015DB*
+ ID_VENDOR_FROM_DATABASE=Applied Computing Systems Inc
+
+pci:v000015DC*
+ ID_VENDOR_FROM_DATABASE=Litronic Inc
+
+pci:v000015DCd00000001*
+ ID_PRODUCT_FROM_DATABASE=Argus 300 PCI Cryptography Module
+
+pci:v000015DD*
+ ID_VENDOR_FROM_DATABASE=Sigmatel Inc
+
+pci:v000015DE*
+ ID_VENDOR_FROM_DATABASE=Malleable Technologies Inc
+
+pci:v000015DF*
+ ID_VENDOR_FROM_DATABASE=Infinilink Corp
+
+pci:v000015E0*
+ ID_VENDOR_FROM_DATABASE=Cacheflow Inc
+
+pci:v000015E1*
+ ID_VENDOR_FROM_DATABASE=Voice Technologies Group Inc
+
+pci:v000015E2*
+ ID_VENDOR_FROM_DATABASE=Quicknet Technologies Inc
+
+pci:v000015E2d00000500*
+ ID_PRODUCT_FROM_DATABASE=PhoneJack-PCI
+
+pci:v000015E3*
+ ID_VENDOR_FROM_DATABASE=Networth Technologies Inc
+
+pci:v000015E4*
+ ID_VENDOR_FROM_DATABASE=VSN Systemen BV
+
+pci:v000015E5*
+ ID_VENDOR_FROM_DATABASE=Valley technologies Inc
+
+pci:v000015E6*
+ ID_VENDOR_FROM_DATABASE=Agere Inc
+
+pci:v000015E7*
+ ID_VENDOR_FROM_DATABASE=Get Engineering Corp
+
+pci:v000015E8*
+ ID_VENDOR_FROM_DATABASE=National Datacomm Corp
+
+pci:v000015E8d00000130*
+ ID_PRODUCT_FROM_DATABASE=Wireless PCI Card
+
+pci:v000015E8d00000131*
+ ID_PRODUCT_FROM_DATABASE=NCP130A2 Wireless NIC
+
+pci:v000015E9*
+ ID_VENDOR_FROM_DATABASE=Pacific Digital Corp
+
+pci:v000015E9d00001841*
+ ID_PRODUCT_FROM_DATABASE=ADMA-100 DiscStaQ ATA Controller
+
+pci:v000015EA*
+ ID_VENDOR_FROM_DATABASE=Tokyo Denshi Sekei K.K.
+
+pci:v000015EB*
+ ID_VENDOR_FROM_DATABASE=DResearch Digital Media Systems GmbH
+
+pci:v000015EC*
+ ID_VENDOR_FROM_DATABASE=Beckhoff GmbH
+
+pci:v000015ECd00003101*
+ ID_PRODUCT_FROM_DATABASE=FC3101 Profibus DP 1 Channel PCI
+
+pci:v000015ECd00005102*
+ ID_PRODUCT_FROM_DATABASE=FC5102
+
+pci:v000015ED*
+ ID_VENDOR_FROM_DATABASE=Macrolink Inc
+
+pci:v000015EE*
+ ID_VENDOR_FROM_DATABASE=In Win Development Inc
+
+pci:v000015EF*
+ ID_VENDOR_FROM_DATABASE=Intelligent Paradigm Inc
+
+pci:v000015F0*
+ ID_VENDOR_FROM_DATABASE=B-Tree Systems Inc
+
+pci:v000015F1*
+ ID_VENDOR_FROM_DATABASE=Times N Systems Inc
+
+pci:v000015F2*
+ ID_VENDOR_FROM_DATABASE=Diagnostic Instruments Inc
+
+pci:v000015F3*
+ ID_VENDOR_FROM_DATABASE=Digitmedia Corp
+
+pci:v000015F4*
+ ID_VENDOR_FROM_DATABASE=Valuesoft
+
+pci:v000015F5*
+ ID_VENDOR_FROM_DATABASE=Power Micro Research
+
+pci:v000015F6*
+ ID_VENDOR_FROM_DATABASE=Extreme Packet Device Inc
+
+pci:v000015F7*
+ ID_VENDOR_FROM_DATABASE=Banctec
+
+pci:v000015F8*
+ ID_VENDOR_FROM_DATABASE=Koga Electronics Co
+
+pci:v000015F9*
+ ID_VENDOR_FROM_DATABASE=Zenith Electronics Corp
+
+pci:v000015FA*
+ ID_VENDOR_FROM_DATABASE=J.P. Axzam Corp
+
+pci:v000015FB*
+ ID_VENDOR_FROM_DATABASE=Zilog Inc
+
+pci:v000015FC*
+ ID_VENDOR_FROM_DATABASE=Techsan Electronics Co Ltd
+
+pci:v000015FD*
+ ID_VENDOR_FROM_DATABASE=N-CUBED.NET
+
+pci:v000015FE*
+ ID_VENDOR_FROM_DATABASE=Kinpo Electronics Inc
+
+pci:v000015FF*
+ ID_VENDOR_FROM_DATABASE=Fastpoint Technologies Inc
+
+pci:v00001600*
+ ID_VENDOR_FROM_DATABASE=Northrop Grumman - Canada Ltd
+
+pci:v00001601*
+ ID_VENDOR_FROM_DATABASE=Tenta Technology
+
+pci:v00001602*
+ ID_VENDOR_FROM_DATABASE=Prosys-tec Inc
+
+pci:v00001603*
+ ID_VENDOR_FROM_DATABASE=Nokia Wireless Communications
+
+pci:v00001604*
+ ID_VENDOR_FROM_DATABASE=Central System Research Co Ltd
+
+pci:v00001605*
+ ID_VENDOR_FROM_DATABASE=Pairgain Technologies
+
+pci:v00001606*
+ ID_VENDOR_FROM_DATABASE=Europop AG
+
+pci:v00001607*
+ ID_VENDOR_FROM_DATABASE=Lava Semiconductor Manufacturing Inc
+
+pci:v00001608*
+ ID_VENDOR_FROM_DATABASE=Automated Wagering International
+
+pci:v00001609*
+ ID_VENDOR_FROM_DATABASE=Scimetric Instruments Inc
+
+pci:v00001612*
+ ID_VENDOR_FROM_DATABASE=Telesynergy Research Inc.
+
+pci:v00001618*
+ ID_VENDOR_FROM_DATABASE=Stone Ridge Technology
+
+pci:v00001618d00000001*
+ ID_PRODUCT_FROM_DATABASE=RDX 11
+
+pci:v00001618d00000002*
+ ID_PRODUCT_FROM_DATABASE=HFT-01
+
+pci:v00001618d00000400*
+ ID_PRODUCT_FROM_DATABASE=FarSync T2P (2 port X.21/V.35/V.24)
+
+pci:v00001618d00000440*
+ ID_PRODUCT_FROM_DATABASE=FarSync T4P (4 port X.21/V.35/V.24)
+
+pci:v00001618d00000610*
+ ID_PRODUCT_FROM_DATABASE=FarSync T1U (1 port X.21/V.35/V.24)
+
+pci:v00001618d00000620*
+ ID_PRODUCT_FROM_DATABASE=FarSync T2U (2 port X.21/V.35/V.24)
+
+pci:v00001618d00000640*
+ ID_PRODUCT_FROM_DATABASE=FarSync T4U (4 port X.21/V.35/V.24)
+
+pci:v00001618d00001610*
+ ID_PRODUCT_FROM_DATABASE=FarSync TE1 (T1,E1)
+
+pci:v00001618d00002610*
+ ID_PRODUCT_FROM_DATABASE=FarSync DSL-S1 (SHDSL)
+
+pci:v00001618d00003640*
+ ID_PRODUCT_FROM_DATABASE=FarSync T4E (4-port X.21/V.35/V.24)
+
+pci:v00001618d00004620*
+ ID_PRODUCT_FROM_DATABASE=FarSync T2Ue PCI Express (2-port X.21/V.35/V.24)
+
+pci:v00001618d00004640*
+ ID_PRODUCT_FROM_DATABASE=FarSync T4Ue PCI Express (4-port X.21/V.35/V.24)
+
+pci:v00001619*
+ ID_VENDOR_FROM_DATABASE=FarSite Communications Ltd
+
+pci:v00001619d00000400*
+ ID_PRODUCT_FROM_DATABASE=FarSync T2P (2 port X.21/V.35/V.24)
+
+pci:v00001619d00000440*
+ ID_PRODUCT_FROM_DATABASE=FarSync T4P (4 port X.21/V.35/V.24)
+
+pci:v00001619d00000610*
+ ID_PRODUCT_FROM_DATABASE=FarSync T1U (1 port X.21/V.35/V.24)
+
+pci:v00001619d00000620*
+ ID_PRODUCT_FROM_DATABASE=FarSync T2U (2 port X.21/V.35/V.24)
+
+pci:v00001619d00000640*
+ ID_PRODUCT_FROM_DATABASE=FarSync T4U (4 port X.21/V.35/V.24)
+
+pci:v00001619d00001610*
+ ID_PRODUCT_FROM_DATABASE=FarSync TE1 (T1,E1)
+
+pci:v00001619d00002610*
+ ID_PRODUCT_FROM_DATABASE=FarSync DSL-S1 (SHDSL)
+
+pci:v00001619d00003640*
+ ID_PRODUCT_FROM_DATABASE=FarSync T4E (4-port X.21/V.35/V.24)
+
+pci:v00001619d00004620*
+ ID_PRODUCT_FROM_DATABASE=FarSync T2Ue PCI Express (2-port X.21/V.35/V.24)
+
+pci:v00001619d00004640*
+ ID_PRODUCT_FROM_DATABASE=FarSync T4Ue PCI Express (4-port X.21/V.35/V.24)
+
+pci:v0000161F*
+ ID_VENDOR_FROM_DATABASE=Rioworks
+
+pci:v00001626*
+ ID_VENDOR_FROM_DATABASE=TDK Semiconductor Corp.
+
+pci:v00001626d00008410*
+ ID_PRODUCT_FROM_DATABASE=RTL81xx Fast Ethernet
+
+pci:v00001629*
+ ID_VENDOR_FROM_DATABASE=Kongsberg Spacetec AS
+
+pci:v00001629d00001003*
+ ID_PRODUCT_FROM_DATABASE=Format synchronizer v3.0
+
+pci:v00001629d00001006*
+ ID_PRODUCT_FROM_DATABASE=Format synchronizer, model 10500
+
+pci:v00001629d00001007*
+ ID_PRODUCT_FROM_DATABASE=Format synchronizer, model 21000
+
+pci:v00001629d00002002*
+ ID_PRODUCT_FROM_DATABASE=Fast Universal Data Output
+
+pci:v00001631*
+ ID_VENDOR_FROM_DATABASE=Packard Bell B.V.
+
+pci:v00001638*
+ ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp [SMC]
+
+pci:v00001638d00001100*
+ ID_PRODUCT_FROM_DATABASE=SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000
+
+pci:v0000163C*
+ ID_VENDOR_FROM_DATABASE=Smart Link Ltd.
+
+pci:v0000163Cd00003052*
+ ID_PRODUCT_FROM_DATABASE=SmartLink SmartPCI562 56K Modem
+
+pci:v0000163Cd00005449*
+ ID_PRODUCT_FROM_DATABASE=SmartPCI561 Modem
+
+pci:v00001641*
+ ID_VENDOR_FROM_DATABASE=MKNet Corp.
+
+pci:v00001657*
+ ID_VENDOR_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+pci:v00001657d00000013*
+ ID_PRODUCT_FROM_DATABASE=425/825/42B/82B 4Gbps/8Gbps PCIe dual port FC HBA
+
+pci:v00001657d00000013sv0000103Csd00001742*
+ ID_PRODUCT_FROM_DATABASE=HP 82B 8Gbps dual port FC HBA
+
+pci:v00001657d00000013sv0000103Csd00001744*
+ ID_PRODUCT_FROM_DATABASE=HP 42B 4Gbps dual port FC HBA
+
+pci:v00001657d00000013sv00001657sd00000014*
+ ID_PRODUCT_FROM_DATABASE=425/825 4Gbps/8Gbps PCIe dual port FC HBA
+
+pci:v00001657d00000014*
+ ID_PRODUCT_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA
+
+pci:v00001657d00000014sv00001657sd00000014*
+ ID_PRODUCT_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA - FCOE
+
+pci:v00001657d00000014sv00001657sd00000015*
+ ID_PRODUCT_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA - LL
+
+pci:v00001657d00000017*
+ ID_PRODUCT_FROM_DATABASE=415/815/41B/81B 4Gbps/8Gbps PCIe single port FC HBA
+
+pci:v00001657d00000017sv0000103Csd00001741*
+ ID_PRODUCT_FROM_DATABASE=HP 41B 4Gbps single port FC HBA
+
+pci:v00001657d00000017sv0000103Csd00001743*
+ ID_PRODUCT_FROM_DATABASE=HP 81B 8Gbps single port FC HBA
+
+pci:v00001657d00000017sv00001657sd00000014*
+ ID_PRODUCT_FROM_DATABASE=415/815 4Gbps/8Gbps single port PCIe FC HBA
+
+pci:v00001657d00000021*
+ ID_PRODUCT_FROM_DATABASE=804 8Gbps FC HBA for HP Bladesystem c-class
+
+pci:v00001657d00000022*
+ ID_PRODUCT_FROM_DATABASE=1867/1860: 16Gbps/10Gbps Fabric Adapter
+
+pci:v00001657d00000022sv00001657sd00000022*
+ ID_PRODUCT_FROM_DATABASE=10Gbps CNA - FCOE
+
+pci:v00001657d00000022sv00001657sd00000023*
+ ID_PRODUCT_FROM_DATABASE=10Gbps CNA - LL
+
+pci:v00001657d00000022sv00001657sd00000024*
+ ID_PRODUCT_FROM_DATABASE=16Gbps FC HBA
+
+pci:v00001657d00000646*
+ ID_PRODUCT_FROM_DATABASE=400 4Gbps PCIe FC HBA
+
+pci:v0000165A*
+ ID_VENDOR_FROM_DATABASE=Epix Inc
+
+pci:v0000165Ad0000C100*
+ ID_PRODUCT_FROM_DATABASE=PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232]
+
+pci:v0000165Ad0000D200*
+ ID_PRODUCT_FROM_DATABASE=PIXCI(R) D2X Digital Video Capture Board [custom QL5232]
+
+pci:v0000165Ad0000D300*
+ ID_PRODUCT_FROM_DATABASE=PIXCI(R) D3X Digital Video Capture Board [custom QL5232]
+
+pci:v0000165D*
+ ID_VENDOR_FROM_DATABASE=Hsing Tech. Enterprise Co., Ltd.
+
+pci:v0000165F*
+ ID_VENDOR_FROM_DATABASE=Linux Media Labs, LLC
+
+pci:v0000165Fd00001020*
+ ID_PRODUCT_FROM_DATABASE=LMLM4 MPEG-4 encoder
+
+pci:v00001661*
+ ID_VENDOR_FROM_DATABASE=Worldspace Corp.
+
+pci:v00001668*
+ ID_VENDOR_FROM_DATABASE=Actiontec Electronics Inc
+
+pci:v00001668d00000100*
+ ID_PRODUCT_FROM_DATABASE=Mini-PCI bridge
+
+pci:v0000166D*
+ ID_VENDOR_FROM_DATABASE=Broadcom Corporation
+
+pci:v0000166Dd00000001*
+ ID_PRODUCT_FROM_DATABASE=SiByte BCM1125/1125H/1250 System-on-a-Chip PCI
+
+pci:v0000166Dd00000002*
+ ID_PRODUCT_FROM_DATABASE=SiByte BCM1125H/1250 System-on-a-Chip HyperTransport
+
+pci:v0000166Dd00000012*
+ ID_PRODUCT_FROM_DATABASE=SiByte BCM1280/BCM1480 System-on-a-Chip PCI-X
+
+pci:v0000166Dd00000014*
+ ID_PRODUCT_FROM_DATABASE=Sibyte BCM1280/BCM1480 System-on-a-Chip HyperTransport
+
+pci:v00001677*
+ ID_VENDOR_FROM_DATABASE=Bernecker + Rainer
+
+pci:v00001677d0000104E*
+ ID_PRODUCT_FROM_DATABASE=5LS172.6 B&R Dual CAN Interface Card
+
+pci:v00001677d000012D7*
+ ID_PRODUCT_FROM_DATABASE=5LS172.61 B&R Dual CAN Interface Card
+
+pci:v00001677d000020AD*
+ ID_PRODUCT_FROM_DATABASE=5ACPCI.MFIO-K01 Profibus DP / K-Feldbus / COM
+
+pci:v00001678*
+ ID_VENDOR_FROM_DATABASE=NetEffect
+
+pci:v00001678d00000100*
+ ID_PRODUCT_FROM_DATABASE=NE020 10Gb Accelerated Ethernet Adapter (iWARP RNIC)
+
+pci:v00001679*
+ ID_VENDOR_FROM_DATABASE=Tokyo Electron Device Ltd.
+
+pci:v00001679d00003000*
+ ID_PRODUCT_FROM_DATABASE=SD Standard host controller [Ellen]
+
+pci:v0000167B*
+ ID_VENDOR_FROM_DATABASE=ZyDAS Technology Corp.
+
+pci:v0000167Bd00002102*
+ ID_PRODUCT_FROM_DATABASE=ZyDAS ZD1202
+
+pci:v0000167Bd00002102sv0000187Esd00003406*
+ ID_PRODUCT_FROM_DATABASE=ZyAIR B-122 CardBus 11Mbs Wireless LAN Card
+
+pci:v0000167Bd00002102sv0000187Esd00003407*
+ ID_PRODUCT_FROM_DATABASE=ZyAIR B-320 802.11b Wireless PCI Adapter
+
+pci:v0000167Bd00002116*
+ ID_PRODUCT_FROM_DATABASE=ZD1212B Wireless Adapter
+
+pci:v0000167D*
+ ID_VENDOR_FROM_DATABASE=Samsung Electro-Mechanics Co., Ltd.
+
+pci:v0000167Dd0000A000*
+ ID_PRODUCT_FROM_DATABASE=MagicLAN SWL-2210P 802.11b [Intersil ISL3874]
+
+pci:v0000167E*
+ ID_VENDOR_FROM_DATABASE=ONNTO Corp.
+
+pci:v00001681*
+ ID_VENDOR_FROM_DATABASE=Hercules
+
+pci:v00001682*
+ ID_VENDOR_FROM_DATABASE=XFX Pine Group Inc.
+
+pci:v00001688*
+ ID_VENDOR_FROM_DATABASE=CastleNet Technology Inc.
+
+pci:v00001688d00001170*
+ ID_PRODUCT_FROM_DATABASE=WLAN 802.11b card
+
+pci:v0000168C*
+ ID_VENDOR_FROM_DATABASE=Atheros Communications Inc.
+
+pci:v0000168Cd00000007*
+ ID_PRODUCT_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a]
+
+pci:v0000168Cd00000007sv00001737sd00000007*
+ ID_PRODUCT_FROM_DATABASE=WPC54A Wireless PC Card
+
+pci:v0000168Cd00000007sv00001B47sd00000100*
+ ID_PRODUCT_FROM_DATABASE=Harmony 8450CN Wireless CardBus Module
+
+pci:v0000168Cd00000007sv00001B47sd00000110*
+ ID_PRODUCT_FROM_DATABASE=Skyline 4030 / Harmony 8450 802.11a Wireless CardBus Adapter
+
+pci:v0000168Cd00000007sv00008086sd00002501*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 5000 LAN PCI Adapter Module
+
+pci:v0000168Cd00000011*
+ ID_PRODUCT_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001A 802.11a]
+
+pci:v0000168Cd00000012*
+ ID_PRODUCT_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab]
+
+pci:v0000168Cd00000012sv0000126Csd00008031*
+ ID_PRODUCT_FROM_DATABASE=2201 Mobile Adapter
+
+pci:v0000168Cd00000012sv00001385sd00004400*
+ ID_PRODUCT_FROM_DATABASE=WAB501 802.11ab Wireless CardBus Card
+
+pci:v0000168Cd00000012sv00001B47sd0000AA00*
+ ID_PRODUCT_FROM_DATABASE=8460 802.11ab Wireless CardBus Adapter
+
+pci:v0000168Cd00000013*
+ ID_PRODUCT_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter
+
+pci:v0000168Cd00000013sv00000308sd00003402*
+ ID_PRODUCT_FROM_DATABASE=AG-100 802.11ag Wireless Cardbus Adapter
+
+pci:v0000168Cd00000013sv00000308sd00003405*
+ ID_PRODUCT_FROM_DATABASE=G-102 v2 802.11g Wireless Cardbus Adapter
+
+pci:v0000168Cd00000013sv00000308sd00003408*
+ ID_PRODUCT_FROM_DATABASE=G-170S 802.11g Wireless CardBus Adapter
+
+pci:v0000168Cd00000013sv00000E11sd000000E5*
+ ID_PRODUCT_FROM_DATABASE=NC6000/NC8000 laptop
+
+pci:v0000168Cd00000013sv000010B7sd00006002*
+ ID_PRODUCT_FROM_DATABASE=3CRWE154A72 802.11abg Cardbus Adapter
+
+pci:v0000168Cd00000013sv00001113sd0000D301*
+ ID_PRODUCT_FROM_DATABASE=Philips CPWNA100 Wireless CardBus adapter
+
+pci:v0000168Cd00000013sv00001113sd0000EE23*
+ ID_PRODUCT_FROM_DATABASE=SMCWPCIT-G 108Mbps Wireless PCI adapter
+
+pci:v0000168Cd00000013sv00001154sd0000033B*
+ ID_PRODUCT_FROM_DATABASE=Buffalo WLI-CB-AMG54
+
+pci:v0000168Cd00000013sv00001154sd0000034E*
+ ID_PRODUCT_FROM_DATABASE=Buffalo WLI-CB-AG108HP 802.11abg Cardbus Adapter
+
+pci:v0000168Cd00000013sv00001186sd00003202*
+ ID_PRODUCT_FROM_DATABASE=DWL-G650 (Rev B3,B5) Wireless cardbus adapter
+
+pci:v0000168Cd00000013sv00001186sd00003203*
+ ID_PRODUCT_FROM_DATABASE=AirPlus DWL-G520 Wireless PCI Adapter (rev. A)
+
+pci:v0000168Cd00000013sv00001186sd00003A12*
+ ID_PRODUCT_FROM_DATABASE=D-Link AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
+
+pci:v0000168Cd00000013sv00001186sd00003A13*
+ ID_PRODUCT_FROM_DATABASE=AirPlus DWL-G520 Wireless PCI Adapter (rev. B)
+
+pci:v0000168Cd00000013sv00001186sd00003A14*
+ ID_PRODUCT_FROM_DATABASE=AirPremier AG DWL-AG530 Wireless PCI Adapter (rev.A)
+
+pci:v0000168Cd00000013sv00001186sd00003A17*
+ ID_PRODUCT_FROM_DATABASE=D-Link AirPremier DWL-G680 Wireless Cardbus Adapter
+
+pci:v0000168Cd00000013sv00001186sd00003A18*
+ ID_PRODUCT_FROM_DATABASE=D-Link AirPremier DWL-G550 Wireless PCI Adapter
+
+pci:v0000168Cd00000013sv00001186sd00003A1A*
+ ID_PRODUCT_FROM_DATABASE=WNA-2330 802.11bg Wireless CardBus Adapter
+
+pci:v0000168Cd00000013sv00001186sd00003A63*
+ ID_PRODUCT_FROM_DATABASE=D-Link AirPremier DWL-AG660 Wireless Cardbus Adapter
+
+pci:v0000168Cd00000013sv00001186sd00003A93*
+ ID_PRODUCT_FROM_DATABASE=Conceptronic C54I Wireless 801.11g PCI card
+
+pci:v0000168Cd00000013sv00001186sd00003A94*
+ ID_PRODUCT_FROM_DATABASE=Conceptronic C54C 802.11g Wireless Cardbus Adapter
+
+pci:v0000168Cd00000013sv00001186sd00003AB0*
+ ID_PRODUCT_FROM_DATABASE=Allnet ALL0281 Wireless PCI Card
+
+pci:v0000168Cd00000013sv00001385sd00004900*
+ ID_PRODUCT_FROM_DATABASE=WG311v1 802.11g Wireless PCI Adapter
+
+pci:v0000168Cd00000013sv00001385sd00004B00*
+ ID_PRODUCT_FROM_DATABASE=WG511T 108 Mbps Wireless PC Card (rev.A/B)
+
+pci:v0000168Cd00000013sv00001385sd00004D00*
+ ID_PRODUCT_FROM_DATABASE=WG311T 108 Mbps Wireless PCI Adapter (rev.A2)
+
+pci:v0000168Cd00000013sv00001385sd00004F00*
+ ID_PRODUCT_FROM_DATABASE=WG511U Double 108 Mbps Wireless PC Card
+
+pci:v0000168Cd00000013sv00001385sd00005A00*
+ ID_PRODUCT_FROM_DATABASE=WG311T 108 Mbps Wireless PCI Adapter (rev.A3)
+
+pci:v0000168Cd00000013sv00001385sd00005B00*
+ ID_PRODUCT_FROM_DATABASE=WG511T 108 Mbps Wireless PC Card (rev.C)
+
+pci:v0000168Cd00000013sv00001385sd00005D00*
+ ID_PRODUCT_FROM_DATABASE=WPN511 RangeMax Wireless PC Card
+
+pci:v0000168Cd00000013sv00001458sd0000E911*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte GN-WIAG02
+
+pci:v0000168Cd00000013sv00001468sd00000403*
+ ID_PRODUCT_FROM_DATABASE=U10H014 802.11g Cardbus Adapter
+
+pci:v0000168Cd00000013sv00001468sd00000408*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 11b/g Wireless LAN Mini PCI Adapter
+
+pci:v0000168Cd00000013sv000014B7sd00000A10*
+ ID_PRODUCT_FROM_DATABASE=8480-WD 802.11abg Cardbus Adapter
+
+pci:v0000168Cd00000013sv000014B7sd00000A60*
+ ID_PRODUCT_FROM_DATABASE=8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter
+
+pci:v0000168Cd00000013sv000014B7sd0000AA30*
+ ID_PRODUCT_FROM_DATABASE=8800-FC 802.11bg Cardbus Adapter
+
+pci:v0000168Cd00000013sv000014B7sd0000AA40*
+ ID_PRODUCT_FROM_DATABASE=8470-WD 802.11bg Cardbus Adapter
+
+pci:v0000168Cd00000013sv000014B9sd0000CB21*
+ ID_PRODUCT_FROM_DATABASE=CB21 802.11a/b/g Cardbus Adapter
+
+pci:v0000168Cd00000013sv00001668sd00001026*
+ ID_PRODUCT_FROM_DATABASE=IBM HighRate 11 a/b/g Wireless CardBus Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00000013*
+ ID_PRODUCT_FROM_DATABASE=AirPlus XtremeG DWL-G650 Wireless PCMCIA Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00001025*
+ ID_PRODUCT_FROM_DATABASE=DWL-G650B2 Wireless CardBus Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00001027*
+ ID_PRODUCT_FROM_DATABASE=Engenius NL-3054CB ARIES b/g CardBus Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00001042*
+ ID_PRODUCT_FROM_DATABASE=Ubiquiti Networks SuperRange a/b/g Cardbus Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00001051*
+ ID_PRODUCT_FROM_DATABASE=EZ Connect g 802.11g 108Mbps Wireless PCI Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00002026*
+ ID_PRODUCT_FROM_DATABASE=Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00002027*
+ ID_PRODUCT_FROM_DATABASE=D-Link AirPlus DWL-G520 Wireless PCI Adapter (rev. A)
+
+pci:v0000168Cd00000013sv0000168Csd00002041*
+ ID_PRODUCT_FROM_DATABASE=Engenius 5354MP Plus ARIES2 b/g MiniPCI Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00002042*
+ ID_PRODUCT_FROM_DATABASE=Engenius 5354MP Plus ARIES2 a/b/g MiniPCI Adapter
+
+pci:v0000168Cd00000013sv0000168Csd00002051*
+ ID_PRODUCT_FROM_DATABASE=TRENDnet TEW-443PI Wireless PCI Adapter
+
+pci:v0000168Cd00000013sv000016A5sd0000160A*
+ ID_PRODUCT_FROM_DATABASE=BWP712 802.11bg Wireless CardBus Adapter
+
+pci:v0000168Cd00000013sv000016ABsd00007302*
+ ID_PRODUCT_FROM_DATABASE=Trust Speedshare Turbo Pro Wireless PCI Adapter
+
+pci:v0000168Cd00000013sv00001737sd00000017*
+ ID_PRODUCT_FROM_DATABASE=WPC55AG
+
+pci:v0000168Cd00000013sv00001737sd00000026*
+ ID_PRODUCT_FROM_DATABASE=WMP55AG v1.1
+
+pci:v0000168Cd00000013sv00001737sd00000035*
+ ID_PRODUCT_FROM_DATABASE=WPC55AG v1.2 802.11abg Cardbus Adapter
+
+pci:v0000168Cd00000013sv00001737sd00000036*
+ ID_PRODUCT_FROM_DATABASE=WMP55AG v1.2 802.11abg PCI Adapter
+
+pci:v0000168Cd00000013sv00001799sd00003000*
+ ID_PRODUCT_FROM_DATABASE=F6D3000 Dual-Band Wireless A+G Desktop Card
+
+pci:v0000168Cd00000013sv00001799sd00003010*
+ ID_PRODUCT_FROM_DATABASE=F6D3010 Dual-Band Wireless A+G Notebook Card
+
+pci:v0000168Cd00000013sv000017CFsd00000042*
+ ID_PRODUCT_FROM_DATABASE=Z-COMAX Highpower XG-622H (400mw) 802.11b/g mini-PCI Adapter
+
+pci:v0000168Cd00000013sv0000185Fsd00001012*
+ ID_PRODUCT_FROM_DATABASE=CM9 Wireless a/b/g MiniPCI Adapter
+
+pci:v0000168Cd00000013sv0000185Fsd00002012*
+ ID_PRODUCT_FROM_DATABASE=Wistron NeWeb WLAN a+b+g model CB9
+
+pci:v0000168Cd00000013sv0000A727sd00006801*
+ ID_PRODUCT_FROM_DATABASE=3CRXJK10075 OfficeConnect Wireless 108Mbps 11g XJACK PC Card
+
+pci:v0000168Cd0000001A*
+ ID_PRODUCT_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg]
+
+pci:v0000168Cd0000001Asv00001052sd0000168C*
+ ID_PRODUCT_FROM_DATABASE=Sweex Wireless Lan PC Card 54Mbps
+
+pci:v0000168Cd0000001Asv00001113sd0000EE20*
+ ID_PRODUCT_FROM_DATABASE=SMC Wireless CardBus Adapter 802.11g (SMCWCB-G EU)
+
+pci:v0000168Cd0000001Asv00001113sd0000EE24*
+ ID_PRODUCT_FROM_DATABASE=SMC Wireless PCI Card WPCI-G
+
+pci:v0000168Cd0000001Asv00001186sd00003A15*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.D1)
+
+pci:v0000168Cd0000001Asv00001186sd00003A16*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G510 Wireless PCI Adapter(rev.B)
+
+pci:v0000168Cd0000001Asv00001186sd00003A1C*
+ ID_PRODUCT_FROM_DATABASE=WNA-1330 Notebook Adapter
+
+pci:v0000168Cd0000001Asv00001186sd00003A1D*
+ ID_PRODUCT_FROM_DATABASE=WDA-1320 Desktop Adapter
+
+pci:v0000168Cd0000001Asv00001186sd00003A23*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G520+A Wireless PCI Adapter
+
+pci:v0000168Cd0000001Asv00001186sd00003A24*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G650+A Wireless Cardbus Adapter
+
+pci:v0000168Cd0000001Asv00001186sd00003B08*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.C1)
+
+pci:v0000168Cd0000001Asv0000168Csd0000001A*
+ ID_PRODUCT_FROM_DATABASE=Belkin FD7000
+
+pci:v0000168Cd0000001Asv0000168Csd00001052*
+ ID_PRODUCT_FROM_DATABASE=TP-Link TL-WN510G Wireless CardBus Adapter
+
+pci:v0000168Cd0000001Asv0000168Csd00002052*
+ ID_PRODUCT_FROM_DATABASE=Compex Wireless 802.11 b/g  MiniPCI Adapter, Rev A1 [WLM54G]
+
+pci:v0000168Cd0000001Asv000016ECsd00000122*
+ ID_PRODUCT_FROM_DATABASE=Wireless PCI Adapter Model 5418
+
+pci:v0000168Cd0000001Asv00001737sd00000053*
+ ID_PRODUCT_FROM_DATABASE=WPC54G v7 802.11g Wireless-G Notebook Adapter
+
+pci:v0000168Cd0000001Asv00001799sd0000700C*
+ ID_PRODUCT_FROM_DATABASE=F5D7000 v5000 Wireless G Desktop Card
+
+pci:v0000168Cd0000001Asv00001799sd0000701D*
+ ID_PRODUCT_FROM_DATABASE=F5D7010 v5000 Wireless G Notebook Card
+
+pci:v0000168Cd0000001Asv000017F9sd00000008*
+ ID_PRODUCT_FROM_DATABASE=DX-WGNBC 802.11bg Wireless CardBus Adapter
+
+pci:v0000168Cd0000001Asv000017F9sd00000018*
+ ID_PRODUCT_FROM_DATABASE=DX-WGDTC 802.11bg Wireless PCI Adapter
+
+pci:v0000168Cd0000001B*
+ ID_PRODUCT_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg]
+
+pci:v0000168Cd0000001Bsv00000777sd00003002*
+ ID_PRODUCT_FROM_DATABASE=XR2 802.11g Wireless Mini PCI Adapter
+
+pci:v0000168Cd0000001Bsv00000777sd00003005*
+ ID_PRODUCT_FROM_DATABASE=XR5 802.11a Wireless Mini PCI Adapter
+
+pci:v0000168Cd0000001Bsv00000777sd00003009*
+ ID_PRODUCT_FROM_DATABASE=XR9 900MHz Wireless Mini PCI Adapter
+
+pci:v0000168Cd0000001Bsv00001154sd0000034E*
+ ID_PRODUCT_FROM_DATABASE=WLI-CB-AG108HP 802.11abg Wireless CardBus Adapter
+
+pci:v0000168Cd0000001Bsv00001186sd00003A19*
+ ID_PRODUCT_FROM_DATABASE=D-Link AirPremier AG DWL-AG660 Wireless Cardbus Adapter
+
+pci:v0000168Cd0000001Bsv00001186sd00003A22*
+ ID_PRODUCT_FROM_DATABASE=AirPremier AG DWL-AG530 Wireless PCI Adapter (rev.B)
+
+pci:v0000168Cd0000001Bsv000011ADsd00005001*
+ ID_PRODUCT_FROM_DATABASE=WN5301A 802.11bg Wireless PCI Adapter
+
+pci:v0000168Cd0000001Bsv00001458sd0000E901*
+ ID_PRODUCT_FROM_DATABASE=GN-WI01HT Wireless a/b/g MiniPCI Adapter
+
+pci:v0000168Cd0000001Bsv0000168Csd0000001B*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN PCI LiteOn
+
+pci:v0000168Cd0000001Bsv0000168Csd00001062*
+ ID_PRODUCT_FROM_DATABASE=IPN-W100CB 802.11abg Wireless CardBus Adapter
+
+pci:v0000168Cd0000001Bsv0000168Csd00002062*
+ ID_PRODUCT_FROM_DATABASE=EnGenius EMP-8602 (400mw) or Compex WLM54AG (SuperAG)
+
+pci:v0000168Cd0000001Bsv0000168Csd00002063*
+ ID_PRODUCT_FROM_DATABASE=EnGenius EMP-8602 (400mw) or Compex WLM54AG
+
+pci:v0000168Cd0000001Bsv000017F9sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=WL-711A 802.11abg Wireless CardBus Adapter
+
+pci:v0000168Cd0000001Bsv000017F9sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=WPIA-112AG 802.11abg Wireless PCI Adapter
+
+pci:v0000168Cd0000001Bsv000017F9sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=PC-686X 802.11abg Wireless Mini PCI Adapter
+
+pci:v0000168Cd0000001Bsv0000185Fsd00001600*
+ ID_PRODUCT_FROM_DATABASE=DCMA-82 High Power WLAN 802.11a/b/g mini-PCI Module (Super A/G, eXtended Range, 400mW)
+
+pci:v0000168Cd0000001Bsv00001948sd00003ABA*
+ ID_PRODUCT_FROM_DATABASE=RBTBJ-AW 802.11abg Wireless Cardbus Adapter
+
+pci:v0000168Cd0000001Bsv0000A727sd00006804*
+ ID_PRODUCT_FROM_DATABASE=Wireless 11a/b/g PC Card with XJACK(r) Antenna
+
+pci:v0000168Cd0000001C*
+ ID_PRODUCT_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express)
+
+pci:v0000168Cd0000001Csv00000777sd00003006*
+ ID_PRODUCT_FROM_DATABASE=SRX 802.11abg Wireless ExpressCard Adapter
+
+pci:v0000168Cd0000001Csv0000103Csd0000137A*
+ ID_PRODUCT_FROM_DATABASE=AR5BXB63 (Foxconn) 802.11bg Mini PCIe NIC
+
+pci:v0000168Cd0000001Csv0000106Bsd00000086*
+ ID_PRODUCT_FROM_DATABASE=AR5BXB6 802.11abg Wireless Mini PCIe Card
+
+pci:v0000168Cd0000001Csv0000144Fsd00007106*
+ ID_PRODUCT_FROM_DATABASE=WLL3140 (Toshiba PA3501U-1MPC) 802.11bg Wireless Mini PCIe Card
+
+pci:v0000168Cd0000001Csv0000144Fsd00007128*
+ ID_PRODUCT_FROM_DATABASE=WLL3141 (Toshiba PA3613U-1MPC) 802.11bg Wireless Mini PCIe Card
+
+pci:v0000168Cd0000001Csv00001468sd00000428*
+ ID_PRODUCT_FROM_DATABASE=AR5BXB63 802.11bg NIC
+
+pci:v0000168Cd0000001Csv00001468sd0000042A*
+ ID_PRODUCT_FROM_DATABASE=AR5007EG 802.11bg NIC
+
+pci:v0000168Cd0000001Csv0000147Bsd00001033*
+ ID_PRODUCT_FROM_DATABASE=AirPace Wi-Fi
+
+pci:v0000168Cd0000001Csv0000168Csd0000001C*
+ ID_PRODUCT_FROM_DATABASE=AR242x 802.11abg NIC (PCI Express)
+
+pci:v0000168Cd0000001Csv0000168Csd00003061*
+ ID_PRODUCT_FROM_DATABASE=AR5006EGS 802.11bg NIC (2.4GHz, PCI Express)
+
+pci:v0000168Cd0000001Csv0000168Csd00003062*
+ ID_PRODUCT_FROM_DATABASE=AR5006EXS 802.11abg NIC (2.4/5.0GHz, PCI Express)
+
+pci:v0000168Cd0000001Csv0000168Csd00003063*
+ ID_PRODUCT_FROM_DATABASE=AR5006EX 802.11abg NIC (2.4/5.0GHz, PCI Express)
+
+pci:v0000168Cd0000001Csv0000168Csd00003065*
+ ID_PRODUCT_FROM_DATABASE=AR5006EG 802.11bg NIC (2.4GHz, PCI Express)
+
+pci:v0000168Cd0000001Csv0000168Csd00003067*
+ ID_PRODUCT_FROM_DATABASE=AR242x 802.11abg Wireless PCI Express Adapter (rev 01)
+
+pci:v0000168Cd0000001Csv00001A3Bsd00001026*
+ ID_PRODUCT_FROM_DATABASE=AW-GE780 802.11bg Wireless Mini PCIe Card
+
+pci:v0000168Cd0000001D*
+ ID_PRODUCT_FROM_DATABASE=AR2417 Wireless Network Adapter [AR5007G 802.11bg]
+
+pci:v0000168Cd0000001Dsv00001799sd0000720B*
+ ID_PRODUCT_FROM_DATABASE=F5D7000 v8000 Wireless G Desktop Card
+
+pci:v0000168Cd0000001Dsv00001799sd0000721B*
+ ID_PRODUCT_FROM_DATABASE=F5D7010 v8000 Wireless G Notebook Card
+
+pci:v0000168Cd00000020*
+ ID_PRODUCT_FROM_DATABASE=AR5513 802.11abg Wireless NIC
+
+pci:v0000168Cd00000020sv00000308sd00003407*
+ ID_PRODUCT_FROM_DATABASE=M-102 802.11g Wireless Cardbus Adapter
+
+pci:v0000168Cd00000020sv00001186sd00003A67*
+ ID_PRODUCT_FROM_DATABASE=DWL-G650M Super G MIMO Wireless Notebook Adapter
+
+pci:v0000168Cd00000020sv00001186sd00003A68*
+ ID_PRODUCT_FROM_DATABASE=DWL-G520M Wireless 108G MIMO Desktop Adapter
+
+pci:v0000168Cd00000020sv0000187Esd0000340E*
+ ID_PRODUCT_FROM_DATABASE=M-302 802.11g Wireless PCI Adapter
+
+pci:v0000168Cd00000020sv00001976sd00002003*
+ ID_PRODUCT_FROM_DATABASE=TEW-601PC 802.11g Wireless CardBus Adapter
+
+pci:v0000168Cd00000023*
+ ID_PRODUCT_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn]
+
+pci:v0000168Cd00000023sv00000308sd0000340B*
+ ID_PRODUCT_FROM_DATABASE=NWD-170N 802.11bgn Wireless CardBus Adapter
+
+pci:v0000168Cd00000023sv00001154sd00000365*
+ ID_PRODUCT_FROM_DATABASE=Buffalo WLP-CB-AG300 802.11abgn Cardbus Adapter
+
+pci:v0000168Cd00000023sv00001154sd00000367*
+ ID_PRODUCT_FROM_DATABASE=WLI-CB-AG301N 802.11abgn Wireless CardBus Adapter
+
+pci:v0000168Cd00000023sv00001186sd00003A6A*
+ ID_PRODUCT_FROM_DATABASE=DWA-642 802.11n RangeBooster N CardBus Adapter
+
+pci:v0000168Cd00000023sv00001186sd00003A6B*
+ ID_PRODUCT_FROM_DATABASE=DWA-547 802.11n RangeBooster N 650 DeskTop Adapter
+
+pci:v0000168Cd00000023sv00001186sd00003A6D*
+ ID_PRODUCT_FROM_DATABASE=DWA-552 802.11n Xtreme N Desktop Adapter (rev A1)
+
+pci:v0000168Cd00000023sv00001186sd00003A76*
+ ID_PRODUCT_FROM_DATABASE=DWA-645 802.11n RangeBooster N 650 Notebook Adapter (rev A1)
+
+pci:v0000168Cd00000023sv00001737sd00000059*
+ ID_PRODUCT_FROM_DATABASE=WPC300N v2 Wireless-N Notebook Adapter
+
+pci:v0000168Cd00000023sv00001737sd00000069*
+ ID_PRODUCT_FROM_DATABASE=WPC100 v1 802.11n RangePlus Wireless Notebook Adapter
+
+pci:v0000168Cd00000023sv00001737sd00000072*
+ ID_PRODUCT_FROM_DATABASE=WMP110 v1 802.11n RangePlus Wireless PCI Adapter
+
+pci:v0000168Cd00000023sv00001799sd00008011*
+ ID_PRODUCT_FROM_DATABASE=F5D8011 v1 802.11n N1 Wireless Notebook Card
+
+pci:v0000168Cd00000023sv0000187Esd00003411*
+ ID_PRODUCT_FROM_DATABASE=NWD-370N 802.11n Wireless PCI Adapter
+
+pci:v0000168Cd00000023sv00001976sd00002008*
+ ID_PRODUCT_FROM_DATABASE=TEW-621PC 802.11bgn Wireless CardBus Adapter
+
+pci:v0000168Cd00000024*
+ ID_PRODUCT_FROM_DATABASE=AR5418 Wireless Network Adapter [AR5008E 802.11(a)bgn] (PCI-Express)
+
+pci:v0000168Cd00000024sv0000106Bsd00000087*
+ ID_PRODUCT_FROM_DATABASE=AR5BXB72 802.11abgn Mini PCIe Card [AR5008E-3NX]
+
+pci:v0000168Cd00000027*
+ ID_PRODUCT_FROM_DATABASE=AR9160 Wireless Network Adapter [AR9001 802.11(a)bgn]
+
+pci:v0000168Cd00000027sv00000777sd00004082*
+ ID_PRODUCT_FROM_DATABASE=SR71-A 802.11abgn Wireless Mini PCI Adapter
+
+pci:v0000168Cd00000029*
+ ID_PRODUCT_FROM_DATABASE=AR922X Wireless Network Adapter
+
+pci:v0000168Cd00000029sv00000777sd00004005*
+ ID_PRODUCT_FROM_DATABASE=SR71-15 802.11an Mini PCI Adapter
+
+pci:v0000168Cd00000029sv00001186sd00003A7A*
+ ID_PRODUCT_FROM_DATABASE=DWA-552 802.11n Xtreme N Desktop Adapter (rev A2)
+
+pci:v0000168Cd0000002A*
+ ID_PRODUCT_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express)
+
+pci:v0000168Cd0000002Asv00000777sd00004F05*
+ ID_PRODUCT_FROM_DATABASE=SR71-X 802.11abgn Wireless ExpressCard Adapter [AR9280]
+
+pci:v0000168Cd0000002Asv0000103Csd00003041*
+ ID_PRODUCT_FROM_DATABASE=AR5BHB92-H 802.11abgn Wireless Half-size Mini PCIe Card [AR9280]
+
+pci:v0000168Cd0000002Asv0000105Bsd0000E006*
+ ID_PRODUCT_FROM_DATABASE=T77H053.00 802.11bgn Wireless Mini PCIe Card [AR9281]
+
+pci:v0000168Cd0000002Asv0000105Bsd0000E01F*
+ ID_PRODUCT_FROM_DATABASE=T77H047.31 802.11bgn Wireless Half-size Mini PCIe Card [AR9283]
+
+pci:v0000168Cd0000002Asv000011ADsd00006600*
+ ID_PRODUCT_FROM_DATABASE=WN6600A 802.11bgn Wireless Mini PCIe Card [AR9281]
+
+pci:v0000168Cd0000002Asv0000144Fsd00007141*
+ ID_PRODUCT_FROM_DATABASE=WLL6080 802.11bgn Wireless Mini PCIe Card [AR9281]
+
+pci:v0000168Cd0000002Asv0000168Csd00000203*
+ ID_PRODUCT_FROM_DATABASE=DW1525 802.11abgn WLAN PCIe Card [AR9280]
+
+pci:v0000168Cd0000002Asv00001A32sd00000303*
+ ID_PRODUCT_FROM_DATABASE=EM303 802.11bgn Wireless Mini PCIe Card [AR9281]
+
+pci:v0000168Cd0000002Asv00001A32sd00000306*
+ ID_PRODUCT_FROM_DATABASE=EM306 802.11bgn Wireless Half-size Mini PCIe Card [AR9283]
+
+pci:v0000168Cd0000002Asv00001A3Bsd00001067*
+ ID_PRODUCT_FROM_DATABASE=AW-NE771 802.11bgn Wireless Mini PCIe Card [AR9281]
+
+pci:v0000168Cd0000002Asv00001A3Bsd00001081*
+ ID_PRODUCT_FROM_DATABASE=AW-NE773 802.11abgn Wireless Half-size Mini PCIe Card [AR9280]
+
+pci:v0000168Cd0000002B*
+ ID_PRODUCT_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express)
+
+pci:v0000168Cd0000002Bsv00001028sd00000204*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1502 802.11bgn Half-size Mini PCIe Card
+
+pci:v0000168Cd0000002Bsv00001028sd00000205*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1702 802.11bgn Half-size Mini PCIe Card [AR9002WB-1NGCD]
+
+pci:v0000168Cd0000002Bsv0000103Csd0000303F*
+ ID_PRODUCT_FROM_DATABASE=U98Z062.10 802.11bgn Wireless Half-size Mini PCIe Card
+
+pci:v0000168Cd0000002Bsv0000103Csd00003040*
+ ID_PRODUCT_FROM_DATABASE=U98Z062.12 802.11bgn Wireless Half-size Mini PCIe Card
+
+pci:v0000168Cd0000002Bsv0000105Bsd0000E017*
+ ID_PRODUCT_FROM_DATABASE=T77H126.00 802.11bgn Wireless Half-size Mini PCIe Card
+
+pci:v0000168Cd0000002Bsv00001113sd0000E811*
+ ID_PRODUCT_FROM_DATABASE=WN7811A (Toshiba PA3722U-1MPC) 802.11bgn Wireless Half-size Mini PCIe Card
+
+pci:v0000168Cd0000002Bsv0000185Fsd000030AF*
+ ID_PRODUCT_FROM_DATABASE=DNXA-95 802.11bgn Wireless Half-size Mini PCIe Card
+
+pci:v0000168Cd0000002Bsv00001931sd00000023*
+ ID_PRODUCT_FROM_DATABASE=Option GTM67x PCIe WiFi Adapter
+
+pci:v0000168Cd0000002Bsv00001A3Bsd00001089*
+ ID_PRODUCT_FROM_DATABASE=AW-NE785 / AW-NE785H 802.11bgn Wireless Full or Half-size Mini PCIe Card
+
+pci:v0000168Cd0000002Bsv00001A3Bsd00002C37*
+ ID_PRODUCT_FROM_DATABASE=AW-NB037H 802.11bgn Wireless Half-size Mini PCIe Card [AR9002WB-1NGCD]
+
+pci:v0000168Cd0000002Bsv00001B9Asd00000401*
+ ID_PRODUCT_FROM_DATABASE=XW204E 802.11bgn Wireless Half-size Mini PCIe Card
+
+pci:v0000168Cd0000002Bsv00001B9Asd00000C03*
+ ID_PRODUCT_FROM_DATABASE=WB214E 802.11bgn Wireless Half-size Mini PCIe Card [AR9002WB-1NGCD]
+
+pci:v0000168Cd0000002C*
+ ID_PRODUCT_FROM_DATABASE=AR2427 802.11bg Wireless Network Adapter (PCI-Express)
+
+pci:v0000168Cd0000002D*
+ ID_PRODUCT_FROM_DATABASE=AR9227 Wireless Network Adapter
+
+pci:v0000168Cd0000002E*
+ ID_PRODUCT_FROM_DATABASE=AR9287 Wireless Network Adapter (PCI-Express)
+
+pci:v0000168Cd00000030*
+ ID_PRODUCT_FROM_DATABASE=AR9300 Wireless LAN adaptor
+
+pci:v0000168Cd00000030sv0000103Csd00001627*
+ ID_PRODUCT_FROM_DATABASE=AR9380/HB112 802.11abgn 3×3 Wi-Fi Adapter
+
+pci:v0000168Cd00000030sv00001A56sd00002000*
+ ID_PRODUCT_FROM_DATABASE=Killer Wireless-N 1102 Half-size Mini PCIe Card [AR9382]
+
+pci:v0000168Cd00000030sv00001A56sd00002001*
+ ID_PRODUCT_FROM_DATABASE=Killer Wireless-N 1103 Half-size Mini PCIe Card [AR9380]
+
+pci:v0000168Cd00000032*
+ ID_PRODUCT_FROM_DATABASE=AR9485 Wireless Network Adapter
+
+pci:v0000168Cd00000032sv0000103Csd00001838*
+ ID_PRODUCT_FROM_DATABASE=AR9485/HB125 802.11bgn 1×1 Wi-Fi Adapter
+
+pci:v0000168Cd00000033*
+ ID_PRODUCT_FROM_DATABASE=AR9580 Wireless Network Adapter
+
+pci:v0000168Cd00000034*
+ ID_PRODUCT_FROM_DATABASE=AR9462 Wireless Network Adapter
+
+pci:v0000168Cd00000036*
+ ID_PRODUCT_FROM_DATABASE=AR9565 Wireless Network Adapter
+
+pci:v0000168Cd00000207*
+ ID_PRODUCT_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a]
+
+pci:v0000168Cd00001014*
+ ID_PRODUCT_FROM_DATABASE=AR5212 802.11abg NIC
+
+pci:v0000168Cd00001014sv00001014sd0000058A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 11a/b/g Wireless LAN Mini Express Adapter (AR5BXB6)
+
+pci:v0000168Cd00009013*
+ ID_PRODUCT_FROM_DATABASE=AR5002X Wireless Network Adapter
+
+pci:v0000168Cd0000FF19*
+ ID_PRODUCT_FROM_DATABASE=AR5006X Wireless Network Adapter
+
+pci:v0000168Cd0000FF1C*
+ ID_PRODUCT_FROM_DATABASE=AR5008 Wireless Network Adapter
+
+pci:v0000168Cd0000FF1D*
+ ID_PRODUCT_FROM_DATABASE=AR5008 Wireless Network Adapter
+
+pci:v00001695*
+ ID_VENDOR_FROM_DATABASE=EPoX Computer Co., Ltd.
+
+pci:v0000169C*
+ ID_VENDOR_FROM_DATABASE=Netcell Corporation
+
+pci:v0000169Cd00000044*
+ ID_PRODUCT_FROM_DATABASE=Revolution Storage Processing Card
+
+pci:v0000169D*
+ ID_VENDOR_FROM_DATABASE=Club-3D VB (Wrong ID)
+
+pci:v000016A5*
+ ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd.
+
+pci:v000016AB*
+ ID_VENDOR_FROM_DATABASE=Global Sun Technology Inc
+
+pci:v000016ABd00001100*
+ ID_PRODUCT_FROM_DATABASE=GL24110P
+
+pci:v000016ABd00001101*
+ ID_PRODUCT_FROM_DATABASE=PLX9052 PCMCIA-to-PCI Wireless LAN
+
+pci:v000016ABd00001102*
+ ID_PRODUCT_FROM_DATABASE=PCMCIA-to-PCI Wireless Network Bridge
+
+pci:v000016ABd00008501*
+ ID_PRODUCT_FROM_DATABASE=WL-8305 Wireless LAN PCI Adapter
+
+pci:v000016AE*
+ ID_VENDOR_FROM_DATABASE=SafeNet Inc
+
+pci:v000016AEd00000001*
+ ID_PRODUCT_FROM_DATABASE=SafeXcel 1140
+
+pci:v000016AEd0000000A*
+ ID_PRODUCT_FROM_DATABASE=SafeXcel 1841
+
+pci:v000016AEd00001141*
+ ID_PRODUCT_FROM_DATABASE=SafeXcel 1141
+
+pci:v000016AEd00001841*
+ ID_PRODUCT_FROM_DATABASE=SafeXcel 1842
+
+pci:v000016AF*
+ ID_VENDOR_FROM_DATABASE=SparkLAN Communications, Inc.
+
+pci:v000016B4*
+ ID_VENDOR_FROM_DATABASE=Aspex Semiconductor Ltd
+
+pci:v000016B8*
+ ID_VENDOR_FROM_DATABASE=Sonnet Technologies, Inc.
+
+pci:v000016BE*
+ ID_VENDOR_FROM_DATABASE=Creatix Polymedia GmbH
+
+pci:v000016C6*
+ ID_VENDOR_FROM_DATABASE=Micrel-Kendin
+
+pci:v000016C6d00008695*
+ ID_PRODUCT_FROM_DATABASE=Centaur KS8695 ARM processor
+
+pci:v000016C6d00008842*
+ ID_PRODUCT_FROM_DATABASE=KSZ8842-PMQL 2-Port Ethernet Switch
+
+pci:v000016C8*
+ ID_VENDOR_FROM_DATABASE=Octasic Inc.
+
+pci:v000016C9*
+ ID_VENDOR_FROM_DATABASE=EONIC B.V. The Netherlands
+
+pci:v000016CA*
+ ID_VENDOR_FROM_DATABASE=CENATEK Inc
+
+pci:v000016CAd00000001*
+ ID_PRODUCT_FROM_DATABASE=Rocket Drive DL
+
+pci:v000016CD*
+ ID_VENDOR_FROM_DATABASE=Advantech Co. Ltd
+
+pci:v000016CDd00000101*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI SRAM for DPX-11x series
+
+pci:v000016CDd00000102*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI SRAM for DPX-S/C/E-series
+
+pci:v000016CDd00000103*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI ROM for DPX-11x series
+
+pci:v000016CDd00000104*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI ROM for DPX-S/C/E-series
+
+pci:v000016CDd00000105*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-114/DPX-115
+
+pci:v000016CDd00000106*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-116
+
+pci:v000016CDd00000107*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-116U
+
+pci:v000016CDd00000108*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-117
+
+pci:v000016CDd00000109*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-112
+
+pci:v000016CDd0000010A*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-C/E-series
+
+pci:v000016CDd0000010B*
+ ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-S series
+
+pci:v000016CE*
+ ID_VENDOR_FROM_DATABASE=Roland Corp.
+
+pci:v000016D5*
+ ID_VENDOR_FROM_DATABASE=Acromag, Inc.
+
+pci:v000016D5d00000504*
+ ID_PRODUCT_FROM_DATABASE=PMC-DX504 Reconfigurable FPGA with LVDS I/O
+
+pci:v000016D5d00000520*
+ ID_PRODUCT_FROM_DATABASE=PMC520 Serial Communication, 232 Octal
+
+pci:v000016D5d00000521*
+ ID_PRODUCT_FROM_DATABASE=PMC521 Serial Communication, 422/485 Octal
+
+pci:v000016D5d00001020*
+ ID_PRODUCT_FROM_DATABASE=PMC-AX1020 Reconfigurable FPGA with A/D & D/A
+
+pci:v000016D5d00001065*
+ ID_PRODUCT_FROM_DATABASE=PMC-AX1065 Reconfigurable FPGA with A/D & D/A
+
+pci:v000016D5d00002004*
+ ID_PRODUCT_FROM_DATABASE=PMC-DX2004 Reconfigurable FPGA with LVDS I/O
+
+pci:v000016D5d00002020*
+ ID_PRODUCT_FROM_DATABASE=PMC-AX2020 Reconfigurable FPGA with A/D & D/A
+
+pci:v000016D5d00002065*
+ ID_PRODUCT_FROM_DATABASE=PMC-AX2065 Reconfigurable FPGA with A/D & D/A
+
+pci:v000016D5d00003020*
+ ID_PRODUCT_FROM_DATABASE=PMC-AX3020 Reconfigurable FPGA with A/D & D/A
+
+pci:v000016D5d00003065*
+ ID_PRODUCT_FROM_DATABASE=PMC-AX3065 Reconfigurable FPGA with A/D & D/A
+
+pci:v000016D5d00004243*
+ ID_PRODUCT_FROM_DATABASE=PMC424, APC424, AcPC424 Digital I/O and Counter Timer Module
+
+pci:v000016D5d00004248*
+ ID_PRODUCT_FROM_DATABASE=PMC464, APC464, AcPC464 Digital I/O and Counter Timer Module
+
+pci:v000016D5d0000424B*
+ ID_PRODUCT_FROM_DATABASE=PMC-DX2002 Reconfigurable FPGA with Differential I/O
+
+pci:v000016D5d00004253*
+ ID_PRODUCT_FROM_DATABASE=PMC-DX503 Reconfigurable FPGA with TTL and Differential I/O
+
+pci:v000016D5d00004312*
+ ID_PRODUCT_FROM_DATABASE=PMC-CX1002 Reconfigurable Conduction-Cooled FPGA Virtex-II with Differential I/O
+
+pci:v000016D5d00004313*
+ ID_PRODUCT_FROM_DATABASE=PMC-CX1003 Reconfigurable Conduction-Cooled FPGA Virtex-II with CMOS and Differential I/O
+
+pci:v000016D5d00004322*
+ ID_PRODUCT_FROM_DATABASE=PMC-CX2002 Reconfigurable Conduction-Cooled FPGA Virtex-II with Differential I/O
+
+pci:v000016D5d00004323*
+ ID_PRODUCT_FROM_DATABASE=PMC-CX2003 Reconfigurable Conduction-Cooled FPGA Virtex-II with CMOS and Differential I/O
+
+pci:v000016D5d00004350*
+ ID_PRODUCT_FROM_DATABASE=PMC-DX501 Reconfigurable Digital I/O Module
+
+pci:v000016D5d00004353*
+ ID_PRODUCT_FROM_DATABASE=PMC-DX2003 Reconfigurable FPGA with TTL and Differential I/O
+
+pci:v000016D5d00004357*
+ ID_PRODUCT_FROM_DATABASE=PMC-DX502 Reconfigurable Differential I/O Module
+
+pci:v000016D5d00004457*
+ ID_PRODUCT_FROM_DATABASE=PMC730, APC730, AcPC730 Multifunction Module
+
+pci:v000016D5d0000464D*
+ ID_PRODUCT_FROM_DATABASE=PMC408 32-Channel Digital Input/Output Module
+
+pci:v000016D5d00004850*
+ ID_PRODUCT_FROM_DATABASE=PMC220-16 12-Bit Analog Output Module
+
+pci:v000016D5d00004A42*
+ ID_PRODUCT_FROM_DATABASE=PMC483, APC483, AcPC483 Counter Timer Module
+
+pci:v000016D5d00004A50*
+ ID_PRODUCT_FROM_DATABASE=PMC484, APC484, AcPC484 Counter Timer Module
+
+pci:v000016D5d00004A56*
+ ID_PRODUCT_FROM_DATABASE=PMC230 16-Bit Analog Output Module
+
+pci:v000016D5d00004B47*
+ ID_PRODUCT_FROM_DATABASE=PMC330, APC330, AcPC330 Analog Input Module, 16-bit A/D
+
+pci:v000016D5d00004C40*
+ ID_PRODUCT_FROM_DATABASE=PMC-LX40 Reconfigurable Virtex-4 FPGA with plug-in I/O
+
+pci:v000016D5d00004C60*
+ ID_PRODUCT_FROM_DATABASE=PMC-LX60 Reconfigurable Virtex-4 FPGA with plug-in I/O
+
+pci:v000016D5d00004D4D*
+ ID_PRODUCT_FROM_DATABASE=PMC341, APC341, AcPC341 Analog Input Module, Simultaneous Sample & Hold
+
+pci:v000016D5d00004D4E*
+ ID_PRODUCT_FROM_DATABASE=PMC482, APC482, AcPC482 Counter Timer Board
+
+pci:v000016D5d0000524D*
+ ID_PRODUCT_FROM_DATABASE=PMC-DX2001 Reconfigurable FPGA with TTL I/O
+
+pci:v000016D5d00005335*
+ ID_PRODUCT_FROM_DATABASE=PMC-SX35 Reconfigurable Virtex-4 FPGA with plug-in I/O
+
+pci:v000016D5d00005456*
+ ID_PRODUCT_FROM_DATABASE=PMC470 48-Channel Digital Input/Output Module
+
+pci:v000016D5d00005601*
+ ID_PRODUCT_FROM_DATABASE=PMC-VLX85 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005602*
+ ID_PRODUCT_FROM_DATABASE=PMC-VLX110 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005603*
+ ID_PRODUCT_FROM_DATABASE=PMC-VSX95 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005604*
+ ID_PRODUCT_FROM_DATABASE=PMC-VLX155 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005605*
+ ID_PRODUCT_FROM_DATABASE=PMC-VFX70 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005606*
+ ID_PRODUCT_FROM_DATABASE=PMC-VLX155-1M Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005701*
+ ID_PRODUCT_FROM_DATABASE=PMC-SLX150: Reconfigurable Spartan-6 FPGA with plug-in I/O
+
+pci:v000016D5d00005702*
+ ID_PRODUCT_FROM_DATABASE=PMC-SLX150-1M: Reconfigurable Spartan-6 FPGA with plug-in I/O
+
+pci:v000016D5d00005801*
+ ID_PRODUCT_FROM_DATABASE=XMC-VLX85 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005802*
+ ID_PRODUCT_FROM_DATABASE=XMC-VLX110 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005803*
+ ID_PRODUCT_FROM_DATABASE=XMC-VSX95 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005804*
+ ID_PRODUCT_FROM_DATABASE=XMC-VLX155 Reconfigurable Virtex-5 FPGA with plug-in I/O
+
+pci:v000016D5d00005807*
+ ID_PRODUCT_FROM_DATABASE=XMC-SLX150: Reconfigurable Spartan-6 FPGA with plug-in I/O
+
+pci:v000016D5d00005808*
+ ID_PRODUCT_FROM_DATABASE=XMC-SLX150-1M: Reconfigurable Spartan-6 FPGA with plug-in I/O
+
+pci:v000016D5d00005901*
+ ID_PRODUCT_FROM_DATABASE=APCe8650 PCI Express IndustryPack Carrier Card
+
+pci:v000016D5d00006301*
+ ID_PRODUCT_FROM_DATABASE=XMC Module with user-configurable Virtex-6 FPGA, 240k logic cells, SFP front I/O
+
+pci:v000016D5d00006302*
+ ID_PRODUCT_FROM_DATABASE=XMC Module with user-configurable Virtex-6 FPGA, 365k logic cells, SFP front I/O
+
+pci:v000016D5d00006303*
+ ID_PRODUCT_FROM_DATABASE=XMC Module with user-configurable Virtex-6 FPGA, 240k logic cells, no front I/O
+
+pci:v000016D5d00006304*
+ ID_PRODUCT_FROM_DATABASE=XMC Module with user-configurable Virtex-6 FPGA, 365k logic cells, no front I/O
+
+pci:v000016DA*
+ ID_VENDOR_FROM_DATABASE=Advantech Co., Ltd.
+
+pci:v000016DAd00000011*
+ ID_PRODUCT_FROM_DATABASE=INES GPIB-PCI
+
+pci:v000016DF*
+ ID_VENDOR_FROM_DATABASE=PIKA Technologies Inc.
+
+pci:v000016E2*
+ ID_VENDOR_FROM_DATABASE=Geotest-MTS
+
+pci:v000016E3*
+ ID_VENDOR_FROM_DATABASE=European Space Agency
+
+pci:v000016E3d00001E0F*
+ ID_PRODUCT_FROM_DATABASE=LEON2FT Processor
+
+pci:v000016E5*
+ ID_VENDOR_FROM_DATABASE=Intellon Corp.
+
+pci:v000016E5d00006000*
+ ID_PRODUCT_FROM_DATABASE=INT6000 Ethernet-to-Powerline Bridge [HomePlug AV]
+
+pci:v000016E5d00006300*
+ ID_PRODUCT_FROM_DATABASE=INT6300 Ethernet-to-Powerline Bridge [HomePlug AV]
+
+pci:v000016EC*
+ ID_VENDOR_FROM_DATABASE=U.S. Robotics
+
+pci:v000016ECd000000ED*
+ ID_PRODUCT_FROM_DATABASE=USR997900
+
+pci:v000016ECd00000116*
+ ID_PRODUCT_FROM_DATABASE=USR997902 10/100/1000 Mbps PCI Network Card
+
+pci:v000016ECd00002F00*
+ ID_PRODUCT_FROM_DATABASE=USR5660A (USR265660A, USR5660A-BP) 56K PCI Faxmodem
+
+pci:v000016ECd00003685*
+ ID_PRODUCT_FROM_DATABASE=Wireless Access PCI Adapter Model 022415
+
+pci:v000016ECd00004320*
+ ID_PRODUCT_FROM_DATABASE=USR997904 10/100/1000 64-bit NIC (Marvell Yukon)
+
+pci:v000016ECd0000AB06*
+ ID_PRODUCT_FROM_DATABASE=USR997901A 10/100 Cardbus NIC
+
+pci:v000016ED*
+ ID_VENDOR_FROM_DATABASE=Sycron N. V.
+
+pci:v000016EDd00001001*
+ ID_PRODUCT_FROM_DATABASE=UMIO communication card
+
+pci:v000016F3*
+ ID_VENDOR_FROM_DATABASE=Jetway Information Co., Ltd.
+
+pci:v000016F4*
+ ID_VENDOR_FROM_DATABASE=Vweb Corp
+
+pci:v000016F4d00008000*
+ ID_PRODUCT_FROM_DATABASE=VW2010
+
+pci:v000016F6*
+ ID_VENDOR_FROM_DATABASE=VideoTele.com, Inc.
+
+pci:v00001702*
+ ID_VENDOR_FROM_DATABASE=Internet Machines Corporation (IMC)
+
+pci:v00001705*
+ ID_VENDOR_FROM_DATABASE=Digital First, Inc.
+
+pci:v0000170B*
+ ID_VENDOR_FROM_DATABASE=NetOctave
+
+pci:v0000170Bd00000100*
+ ID_PRODUCT_FROM_DATABASE=NSP2000-SSL crypto accelerator
+
+pci:v0000170C*
+ ID_VENDOR_FROM_DATABASE=YottaYotta Inc.
+
+pci:v00001719*
+ ID_VENDOR_FROM_DATABASE=EZChip Technologies
+
+pci:v00001725*
+ ID_VENDOR_FROM_DATABASE=Vitesse Semiconductor
+
+pci:v00001725d00007174*
+ ID_PRODUCT_FROM_DATABASE=VSC7174 PCI/PCI-X Serial ATA Host Bus Controller
+
+pci:v0000172A*
+ ID_VENDOR_FROM_DATABASE=Accelerated Encryption
+
+pci:v0000172Ad000013C8*
+ ID_PRODUCT_FROM_DATABASE=AEP SureWare Runner 1000V3
+
+pci:v00001734*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Technology Solutions
+
+pci:v00001734d00001078*
+ ID_PRODUCT_FROM_DATABASE=Amilo Pro v2010
+
+pci:v00001734d00001085*
+ ID_PRODUCT_FROM_DATABASE=Celsius M450
+
+pci:v00001734d00001098*
+ ID_PRODUCT_FROM_DATABASE=Amilo L 1310G
+
+pci:v00001735*
+ ID_VENDOR_FROM_DATABASE=Aten International Co. Ltd.
+
+pci:v00001737*
+ ID_VENDOR_FROM_DATABASE=Linksys
+
+pci:v00001737d00000029*
+ ID_PRODUCT_FROM_DATABASE=WPG54G ver. 4 PCI Card
+
+pci:v00001737d00001032*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Network Adapter
+
+pci:v00001737d00001032sv00001737sd00000015*
+ ID_PRODUCT_FROM_DATABASE=EG1032 v2 Instant Gigabit Network Adapter
+
+pci:v00001737d00001032sv00001737sd00000024*
+ ID_PRODUCT_FROM_DATABASE=EG1032 v3 Instant Gigabit Network Adapter
+
+pci:v00001737d00001064*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Network Adapter
+
+pci:v00001737d00001064sv00001737sd00000016*
+ ID_PRODUCT_FROM_DATABASE=EG1064 v2 Instant Gigabit Network Adapter
+
+pci:v00001737d0000AB08*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v00001737d0000AB09*
+ ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
+
+pci:v0000173B*
+ ID_VENDOR_FROM_DATABASE=Altima (nee Broadcom)
+
+pci:v0000173Bd000003E8*
+ ID_PRODUCT_FROM_DATABASE=AC1000 Gigabit Ethernet
+
+pci:v0000173Bd000003E9*
+ ID_PRODUCT_FROM_DATABASE=AC1001 Gigabit Ethernet
+
+pci:v0000173Bd000003EA*
+ ID_PRODUCT_FROM_DATABASE=AC9100 Gigabit Ethernet
+
+pci:v0000173Bd000003EAsv0000173Bsd00000001*
+ ID_PRODUCT_FROM_DATABASE=AC1002
+
+pci:v0000173Bd000003EB*
+ ID_PRODUCT_FROM_DATABASE=AC1003 Gigabit Ethernet
+
+pci:v00001743*
+ ID_VENDOR_FROM_DATABASE=Peppercon AG
+
+pci:v00001743d00008139*
+ ID_PRODUCT_FROM_DATABASE=ROL/F-100 Fast Ethernet Adapter with ROL
+
+pci:v00001745*
+ ID_VENDOR_FROM_DATABASE=ViXS Systems, Inc.
+
+pci:v00001745d00002020*
+ ID_PRODUCT_FROM_DATABASE=XCode II Series
+
+pci:v00001745d00002100*
+ ID_PRODUCT_FROM_DATABASE=XCode 2100 Series
+
+pci:v00001749*
+ ID_VENDOR_FROM_DATABASE=RLX Technologies
+
+pci:v0000174B*
+ ID_VENDOR_FROM_DATABASE=PC Partner Limited
+
+pci:v0000174D*
+ ID_VENDOR_FROM_DATABASE=WellX Telecom SA
+
+pci:v0000175C*
+ ID_VENDOR_FROM_DATABASE=AudioScience Inc
+
+pci:v0000175E*
+ ID_VENDOR_FROM_DATABASE=Sanera Systems, Inc.
+
+pci:v00001760*
+ ID_VENDOR_FROM_DATABASE=TEDIA spol. s r. o.
+
+pci:v00001771*
+ ID_VENDOR_FROM_DATABASE=InnoVISION Multimedia Ltd.
+
+pci:v00001775*
+ ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms
+
+pci:v0000177D*
+ ID_VENDOR_FROM_DATABASE=Cavium Networks
+
+pci:v0000177Dd00000001*
+ ID_PRODUCT_FROM_DATABASE=Nitrox XL N1
+
+pci:v0000177Dd00000003*
+ ID_PRODUCT_FROM_DATABASE=Nitrox XL N1 Lite
+
+pci:v0000177Dd00000004*
+ ID_PRODUCT_FROM_DATABASE=Octeon (and older) FIPS
+
+pci:v0000177Dd00000005*
+ ID_PRODUCT_FROM_DATABASE=Octeon CN38XX Network Processor Pass 3.x
+
+pci:v0000177Dd00000006*
+ ID_PRODUCT_FROM_DATABASE=RoHS
+
+pci:v0000177Dd00000010*
+ ID_PRODUCT_FROM_DATABASE=Nitrox XL NPX
+
+pci:v0000177Dd00000020*
+ ID_PRODUCT_FROM_DATABASE=Octeon CN31XX Network Processor
+
+pci:v0000177Dd00000030*
+ ID_PRODUCT_FROM_DATABASE=Octeon CN30XX Network Processor
+
+pci:v0000177Dd00000040*
+ ID_PRODUCT_FROM_DATABASE=Octeon CN58XX Network Processor
+
+pci:v0000177Dd00000050*
+ ID_PRODUCT_FROM_DATABASE=Octeon CN57XX Network Processor (CN54XX/CN55XX/CN56XX)
+
+pci:v0000177Dd00000070*
+ ID_PRODUCT_FROM_DATABASE=Octeon CN50XX Network Processor
+
+pci:v0000177Dd00000080*
+ ID_PRODUCT_FROM_DATABASE=Octeon CN52XX Network Processor
+
+pci:v0000177Dd00000090*
+ ID_PRODUCT_FROM_DATABASE=Octeon II CN63XX Network Processor
+
+pci:v0000177Dd00000091*
+ ID_PRODUCT_FROM_DATABASE=Octeon II CN68XX Network Processor
+
+pci:v0000177Dd00000092*
+ ID_PRODUCT_FROM_DATABASE=Octeon II CN65XX Network Processor
+
+pci:v0000177Dd00000093*
+ ID_PRODUCT_FROM_DATABASE=Octeon II CN61XX Network Processor
+
+pci:v00001787*
+ ID_VENDOR_FROM_DATABASE=Hightech Information System Ltd.
+
+pci:v00001789*
+ ID_VENDOR_FROM_DATABASE=Ennyah Technologies Corp.
+
+pci:v00001796*
+ ID_VENDOR_FROM_DATABASE=Research Centre Juelich
+
+pci:v00001796d00000001*
+ ID_PRODUCT_FROM_DATABASE=SIS1100 [Gigabit link]
+
+pci:v00001796d00000002*
+ ID_PRODUCT_FROM_DATABASE=HOTlink
+
+pci:v00001796d00000003*
+ ID_PRODUCT_FROM_DATABASE=Counter Timer
+
+pci:v00001796d00000004*
+ ID_PRODUCT_FROM_DATABASE=CAMAC Controller
+
+pci:v00001796d00000005*
+ ID_PRODUCT_FROM_DATABASE=PROFIBUS
+
+pci:v00001796d00000006*
+ ID_PRODUCT_FROM_DATABASE=AMCC HOTlink
+
+pci:v00001796d0000000D*
+ ID_PRODUCT_FROM_DATABASE=Synchronisation Slave
+
+pci:v00001796d0000000E*
+ ID_PRODUCT_FROM_DATABASE=SIS1100-eCMC
+
+pci:v00001796d0000000F*
+ ID_PRODUCT_FROM_DATABASE=TDC (GPX)
+
+pci:v00001796d00000010*
+ ID_PRODUCT_FROM_DATABASE=PCIe Counter Timer
+
+pci:v00001796d00000011*
+ ID_PRODUCT_FROM_DATABASE=SIS1100-e single link
+
+pci:v00001796d00000012*
+ ID_PRODUCT_FROM_DATABASE=SIS1100-e quad link
+
+pci:v00001797*
+ ID_VENDOR_FROM_DATABASE=Techwell Inc.
+
+pci:v00001797d00006801*
+ ID_PRODUCT_FROM_DATABASE=TW6802 multimedia video card
+
+pci:v00001797d00006802*
+ ID_PRODUCT_FROM_DATABASE=TW6802 multimedia other device
+
+pci:v00001797d00006810*
+ ID_PRODUCT_FROM_DATABASE=TW6816 multimedia video controller
+
+pci:v00001797d00006811*
+ ID_PRODUCT_FROM_DATABASE=TW6816 multimedia video controller
+
+pci:v00001797d00006812*
+ ID_PRODUCT_FROM_DATABASE=TW6816 multimedia video controller
+
+pci:v00001797d00006813*
+ ID_PRODUCT_FROM_DATABASE=TW6816 multimedia video controller
+
+pci:v00001799*
+ ID_VENDOR_FROM_DATABASE=Belkin
+
+pci:v00001799d00006001*
+ ID_PRODUCT_FROM_DATABASE=F5D6001 Wireless PCI Card [Realtek RTL8180]
+
+pci:v00001799d00006020*
+ ID_PRODUCT_FROM_DATABASE=F5D6020 v3000 Wireless PCMCIA Card [Realtek RTL8180]
+
+pci:v00001799d00006060*
+ ID_PRODUCT_FROM_DATABASE=F5D6060 Wireless PDA Card
+
+pci:v00001799d0000700F*
+ ID_PRODUCT_FROM_DATABASE=F5D7000 v7000 Wireless G Desktop Card [Realtek RTL8185]
+
+pci:v00001799d0000701F*
+ ID_PRODUCT_FROM_DATABASE=F5D7010 v7000 Wireless G Notebook Card [Realtek RTL8185]
+
+pci:v0000179A*
+ ID_VENDOR_FROM_DATABASE=id Quantique
+
+pci:v0000179Ad00000001*
+ ID_PRODUCT_FROM_DATABASE=Quantis PCI 16Mbps
+
+pci:v0000179C*
+ ID_VENDOR_FROM_DATABASE=Data Patterns
+
+pci:v0000179Cd00000557*
+ ID_PRODUCT_FROM_DATABASE=DP-PCI-557 [PCI 1553B]
+
+pci:v0000179Cd00000566*
+ ID_PRODUCT_FROM_DATABASE=DP-PCI-566 [Intelligent PCI 1553B]
+
+pci:v0000179Cd00001152*
+ ID_PRODUCT_FROM_DATABASE=DP-cPCI-1152 (8-channel Isolated ADC Module)
+
+pci:v0000179Cd00005031*
+ ID_PRODUCT_FROM_DATABASE=DP-CPCI-5031-Synchro Module
+
+pci:v0000179Cd00005112*
+ ID_PRODUCT_FROM_DATABASE=DP-cPCI-5112 [MM-Carrier]
+
+pci:v0000179Cd00005121*
+ ID_PRODUCT_FROM_DATABASE=DP-CPCI-5121-IP Carrier
+
+pci:v0000179Cd00005211*
+ ID_PRODUCT_FROM_DATABASE=DP-CPCI-5211-IP Carrier
+
+pci:v0000179Cd00005679*
+ ID_PRODUCT_FROM_DATABASE=AGE Display Module
+
+pci:v000017A0*
+ ID_VENDOR_FROM_DATABASE=Genesys Logic, Inc
+
+pci:v000017A0d00007163*
+ ID_PRODUCT_FROM_DATABASE=GL9701 PCIe to PCI Bridge
+
+pci:v000017A0d00008083*
+ ID_PRODUCT_FROM_DATABASE=GL880 USB 1.1 UHCI controller
+
+pci:v000017A0d00008084*
+ ID_PRODUCT_FROM_DATABASE=GL880 USB 2.0 EHCI controller
+
+pci:v000017AA*
+ ID_VENDOR_FROM_DATABASE=Lenovo
+
+pci:v000017AB*
+ ID_VENDOR_FROM_DATABASE=Phillips Components
+
+pci:v000017AF*
+ ID_VENDOR_FROM_DATABASE=Hightech Information System Ltd.
+
+pci:v000017B3*
+ ID_VENDOR_FROM_DATABASE=Hawking Technologies
+
+pci:v000017B3d0000AB08*
+ ID_PRODUCT_FROM_DATABASE=PN672TX 10/100 Ethernet
+
+pci:v000017B4*
+ ID_VENDOR_FROM_DATABASE=Indra Networks, Inc.
+
+pci:v000017B4d00000011*
+ ID_PRODUCT_FROM_DATABASE=WebEnhance 100 GZIP Compression Card
+
+pci:v000017B4d00000012*
+ ID_PRODUCT_FROM_DATABASE=WebEnhance 200 GZIP Compression Card
+
+pci:v000017B4d00000015*
+ ID_PRODUCT_FROM_DATABASE=WebEnhance 300 GZIP Compression Card
+
+pci:v000017B4d00000016*
+ ID_PRODUCT_FROM_DATABASE=StorCompress 300 GZIP Compression Card
+
+pci:v000017B4d00000017*
+ ID_PRODUCT_FROM_DATABASE=StorSecure 300 GZIP Compression and AES Encryption Card
+
+pci:v000017C0*
+ ID_VENDOR_FROM_DATABASE=Wistron Corp.
+
+pci:v000017C2*
+ ID_VENDOR_FROM_DATABASE=Newisys, Inc.
+
+pci:v000017CB*
+ ID_VENDOR_FROM_DATABASE=Airgo Networks Inc
+
+pci:v000017CBd00000001*
+ ID_PRODUCT_FROM_DATABASE=AGN100 802.11 a/b/g True MIMO Wireless Card
+
+pci:v000017CBd00000001sv00001385sd00005C00*
+ ID_PRODUCT_FROM_DATABASE=WGM511 Pre-N 802.11g Wireless CardBus Adapter
+
+pci:v000017CBd00000001sv00001737sd00000045*
+ ID_PRODUCT_FROM_DATABASE=WMP54GX v1 802.11g Wireless-G PCI Adapter with SRX
+
+pci:v000017CBd00000002*
+ ID_PRODUCT_FROM_DATABASE=AGN300 802.11 a/b/g True MIMO Wireless Card
+
+pci:v000017CBd00000002sv00001385sd00006D00*
+ ID_PRODUCT_FROM_DATABASE=WPNT511 RangeMax 240 Mbps Wireless CardBus Adapter
+
+pci:v000017CBd00000002sv00001737sd00000054*
+ ID_PRODUCT_FROM_DATABASE=WPC54GX4 v1 802.11g Wireless-G Notebook Adapter with SRX400
+
+pci:v000017CC*
+ ID_VENDOR_FROM_DATABASE=NetChip Technology, Inc
+
+pci:v000017CCd00002280*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0
+
+pci:v000017CF*
+ ID_VENDOR_FROM_DATABASE=Z-Com, Inc.
+
+pci:v000017D3*
+ ID_VENDOR_FROM_DATABASE=Areca Technology Corp.
+
+pci:v000017D3d00001110*
+ ID_PRODUCT_FROM_DATABASE=ARC-1110 4-Port PCI-X to SATA RAID Controller
+
+pci:v000017D3d00001120*
+ ID_PRODUCT_FROM_DATABASE=ARC-1120 8-Port PCI-X to SATA RAID Controller
+
+pci:v000017D3d00001130*
+ ID_PRODUCT_FROM_DATABASE=ARC-1130 12-Port PCI-X to SATA RAID Controller
+
+pci:v000017D3d00001160*
+ ID_PRODUCT_FROM_DATABASE=ARC-1160 16-Port PCI-X to SATA RAID Controller
+
+pci:v000017D3d00001170*
+ ID_PRODUCT_FROM_DATABASE=ARC-1170 24-Port PCI-X to SATA RAID Controller
+
+pci:v000017D3d00001201*
+ ID_PRODUCT_FROM_DATABASE=ARC-1200 2-Port PCI-Express to SATA II RAID Controller
+
+pci:v000017D3d00001210*
+ ID_PRODUCT_FROM_DATABASE=ARC-1210 4-Port PCI-Express to SATA RAID Controller
+
+pci:v000017D3d00001220*
+ ID_PRODUCT_FROM_DATABASE=ARC-1220 8-Port PCI-Express to SATA RAID Controller
+
+pci:v000017D3d00001222*
+ ID_PRODUCT_FROM_DATABASE=ARC-1222 8-Port PCI-Express to SAS/SATA II RAID Controller
+
+pci:v000017D3d00001230*
+ ID_PRODUCT_FROM_DATABASE=ARC-1230 12-Port PCI-Express to SATA RAID Controller
+
+pci:v000017D3d00001260*
+ ID_PRODUCT_FROM_DATABASE=ARC-1260 16-Port PCI-Express to SATA RAID Controller
+
+pci:v000017D3d00001280*
+ ID_PRODUCT_FROM_DATABASE=ARC-1280/1280ML 24-Port PCI-Express to SATA II RAID Controller
+
+pci:v000017D3d00001280sv000017D3sd00001221*
+ ID_PRODUCT_FROM_DATABASE=ARC-1221 8-Port PCI-Express to SATA RAID Controller
+
+pci:v000017D3d00001300*
+ ID_PRODUCT_FROM_DATABASE=ARC-1300ix-16 16-Port PCI-Express to SAS Non-RAID Host Adapter
+
+pci:v000017D3d00001680*
+ ID_PRODUCT_FROM_DATABASE=ARC-1680 8 port PCIe/PCI-X to SAS/SATA II RAID Controller
+
+pci:v000017D3d00001680sv000017D3sd00001212*
+ ID_PRODUCT_FROM_DATABASE=ARC-1212 4-Port PCIe to SAS/SATA II RAID Controller
+
+pci:v000017D3d00001880*
+ ID_PRODUCT_FROM_DATABASE=ARC-1880 8/12 port PCIe/PCI-X to SAS/SATA II RAID Controller
+
+pci:v000017D5*
+ ID_VENDOR_FROM_DATABASE=Exar Corp.
+
+pci:v000017D5d00005731*
+ ID_PRODUCT_FROM_DATABASE=Xframe 10-Gigabit Ethernet PCI-X
+
+pci:v000017D5d00005732*
+ ID_PRODUCT_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0
+
+pci:v000017D5d00005831*
+ ID_PRODUCT_FROM_DATABASE=Xframe 10-Gigabit Ethernet PCI-X
+
+pci:v000017D5d00005831sv0000103Csd000012D5*
+ ID_PRODUCT_FROM_DATABASE=PCI-X 133MHz 10GbE SR Fiber
+
+pci:v000017D5d00005831sv000010A9sd00008020*
+ ID_PRODUCT_FROM_DATABASE=Single Port 10-Gigabit Ethernet (PCI-X, Fiber)
+
+pci:v000017D5d00005831sv000010A9sd00008024*
+ ID_PRODUCT_FROM_DATABASE=Single Port 10-Gigabit Ethernet (PCI-X, Fiber)
+
+pci:v000017D5d00005832*
+ ID_PRODUCT_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0
+
+pci:v000017D5d00005832sv0000103Csd00001337*
+ ID_PRODUCT_FROM_DATABASE=PCI-X 266MHz 10GigE SR [AD385A]
+
+pci:v000017D5d00005832sv000010A9sd00008021*
+ ID_PRODUCT_FROM_DATABASE=Single Port 10-Gigabit Ethernet II (PCI-X, Fiber)
+
+pci:v000017D5d00005832sv000017D5sd00006020*
+ ID_PRODUCT_FROM_DATABASE=Xframe II SR
+
+pci:v000017D5d00005832sv000017D5sd00006021*
+ ID_PRODUCT_FROM_DATABASE=Xframe II SR, Low Profile
+
+pci:v000017D5d00005832sv000017D5sd00006022*
+ ID_PRODUCT_FROM_DATABASE=Xframe E SR
+
+pci:v000017D5d00005832sv000017D5sd00006420*
+ ID_PRODUCT_FROM_DATABASE=Xframe II LR
+
+pci:v000017D5d00005832sv000017D5sd00006421*
+ ID_PRODUCT_FROM_DATABASE=Xframe II LR, Low Profile
+
+pci:v000017D5d00005832sv000017D5sd00006422*
+ ID_PRODUCT_FROM_DATABASE=Xframe E LR
+
+pci:v000017D5d00005832sv000017D5sd00006C20*
+ ID_PRODUCT_FROM_DATABASE=Xframe II CX4
+
+pci:v000017D5d00005832sv000017D5sd00006C21*
+ ID_PRODUCT_FROM_DATABASE=Xframe II CX4, Low Profile
+
+pci:v000017D5d00005832sv000017D5sd00006C22*
+ ID_PRODUCT_FROM_DATABASE=Xframe E CX4
+
+pci:v000017D5d00005833*
+ ID_PRODUCT_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe
+
+pci:v000017D5d00005833sv000017D5sd00006030*
+ ID_PRODUCT_FROM_DATABASE=X3110 Single Port SR
+
+pci:v000017D5d00005833sv000017D5sd00006031*
+ ID_PRODUCT_FROM_DATABASE=X3120 Dual Port SR
+
+pci:v000017D5d00005833sv000017D5sd00006430*
+ ID_PRODUCT_FROM_DATABASE=X3110 Single Port LR
+
+pci:v000017D5d00005833sv000017D5sd00006431*
+ ID_PRODUCT_FROM_DATABASE=X3120 Dual Port LR
+
+pci:v000017D5d00005833sv000017D5sd00007030*
+ ID_PRODUCT_FROM_DATABASE=X3110 Single Port LRM
+
+pci:v000017D5d00005833sv000017D5sd00007031*
+ ID_PRODUCT_FROM_DATABASE=X3120 Dual Port LRM
+
+pci:v000017D5d00005833sv000017D5sd00007430*
+ ID_PRODUCT_FROM_DATABASE=X3110 Single Port 10GBase-T
+
+pci:v000017D5d00005833sv000017D5sd00007431*
+ ID_PRODUCT_FROM_DATABASE=X3120 Dual Port 10GBase-T
+
+pci:v000017D5d00005833sv000017D5sd00007830*
+ ID_PRODUCT_FROM_DATABASE=X3110 Single Port 10GBase-CR
+
+pci:v000017D5d00005833sv000017D5sd00007831*
+ ID_PRODUCT_FROM_DATABASE=X3120 Dual Port 10GBase-CR
+
+pci:v000017DB*
+ ID_VENDOR_FROM_DATABASE=Cray Inc
+
+pci:v000017DBd00000101*
+ ID_PRODUCT_FROM_DATABASE=XT Series [Seastar] 3D Toroidal Router
+
+pci:v000017DE*
+ ID_VENDOR_FROM_DATABASE=KWorld Computer Co. Ltd.
+
+pci:v000017E4*
+ ID_VENDOR_FROM_DATABASE=Sectra AB
+
+pci:v000017E4d00000001*
+ ID_PRODUCT_FROM_DATABASE=KK671 Cardbus encryption board
+
+pci:v000017E4d00000002*
+ ID_PRODUCT_FROM_DATABASE=KK672 Cardbus encryption board
+
+pci:v000017E6*
+ ID_VENDOR_FROM_DATABASE=Entropic Communications Inc.
+
+pci:v000017E6d00000010*
+ ID_PRODUCT_FROM_DATABASE=EN2010 [c.Link] MoCA Network Controller (Coax, PCI interface)
+
+pci:v000017E6d00000011*
+ ID_PRODUCT_FROM_DATABASE=EN2010 [c.Link] MoCA Network Controller (Coax, MPEG interface)
+
+pci:v000017E6d00000021*
+ ID_PRODUCT_FROM_DATABASE=EN2210 [c.Link] MoCA Network Controller (Coax)
+
+pci:v000017E6d00000025*
+ ID_PRODUCT_FROM_DATABASE=EN2510 [c.Link] MoCA Network Controller (Coax, PCIe interface)
+
+pci:v000017E6d00000027*
+ ID_PRODUCT_FROM_DATABASE=EN2710 [c.Link] MoCA 2.0 Network Controller (Coax, PCIe interface)
+
+pci:v000017EE*
+ ID_VENDOR_FROM_DATABASE=Connect Components Ltd
+
+pci:v000017F2*
+ ID_VENDOR_FROM_DATABASE=Albatron Corp.
+
+pci:v000017F3*
+ ID_VENDOR_FROM_DATABASE=RDC Semiconductor, Inc.
+
+pci:v000017F3d00001010*
+ ID_PRODUCT_FROM_DATABASE=R1010 IDE Controller
+
+pci:v000017F3d00006020*
+ ID_PRODUCT_FROM_DATABASE=R6020 North Bridge
+
+pci:v000017F3d00006021*
+ ID_PRODUCT_FROM_DATABASE=R6021 Host Bridge
+
+pci:v000017F3d00006030*
+ ID_PRODUCT_FROM_DATABASE=R6030 ISA Bridge
+
+pci:v000017F3d00006031*
+ ID_PRODUCT_FROM_DATABASE=R6031 ISA Bridge
+
+pci:v000017F3d00006040*
+ ID_PRODUCT_FROM_DATABASE=R6040 MAC Controller
+
+pci:v000017F3d00006060*
+ ID_PRODUCT_FROM_DATABASE=R6060 USB 1.1 Controller
+
+pci:v000017F3d00006061*
+ ID_PRODUCT_FROM_DATABASE=R6061 USB 2.0 Controller
+
+pci:v000017F7*
+ ID_VENDOR_FROM_DATABASE=Topdek Semiconductor Inc.
+
+pci:v000017F9*
+ ID_VENDOR_FROM_DATABASE=Gemtek Technology Co., Ltd
+
+pci:v000017FC*
+ ID_VENDOR_FROM_DATABASE=IOGEAR, Inc.
+
+pci:v000017FE*
+ ID_VENDOR_FROM_DATABASE=InProComm Inc.
+
+pci:v000017FEd00002120*
+ ID_PRODUCT_FROM_DATABASE=IPN 2120 802.11b
+
+pci:v000017FEd00002120sv00001737sd00000020*
+ ID_PRODUCT_FROM_DATABASE=WMP11 v4 802.11b Wireless-B PCI Adapter
+
+pci:v000017FEd00002220*
+ ID_PRODUCT_FROM_DATABASE=IPN 2220 802.11g
+
+pci:v000017FEd00002220sv00001468sd00000305*
+ ID_PRODUCT_FROM_DATABASE=T60N871 802.11g Mini PCI Wireless Adapter
+
+pci:v000017FEd00002220sv00001737sd00000029*
+ ID_PRODUCT_FROM_DATABASE=WPC54G v4 802.11g Wireless-G Notebook Adapter
+
+pci:v000017FF*
+ ID_VENDOR_FROM_DATABASE=Benq Corporation
+
+pci:v00001803*
+ ID_VENDOR_FROM_DATABASE=ProdaSafe GmbH
+
+pci:v00001805*
+ ID_VENDOR_FROM_DATABASE=Euresys S.A.
+
+pci:v00001809*
+ ID_VENDOR_FROM_DATABASE=Lumanate, Inc.
+
+pci:v00001813*
+ ID_VENDOR_FROM_DATABASE=Ambient Technologies Inc
+
+pci:v00001813d00004000*
+ ID_PRODUCT_FROM_DATABASE=HaM controllerless modem
+
+pci:v00001813d00004000sv000016BEsd00000001*
+ ID_PRODUCT_FROM_DATABASE=V9x HAM Data Fax Modem
+
+pci:v00001813d00004100*
+ ID_PRODUCT_FROM_DATABASE=HaM plus Data Fax Modem
+
+pci:v00001813d00004100sv000016BEsd00000002*
+ ID_PRODUCT_FROM_DATABASE=V9x HAM 1394
+
+pci:v00001814*
+ ID_VENDOR_FROM_DATABASE=Ralink corp.
+
+pci:v00001814d00000101*
+ ID_PRODUCT_FROM_DATABASE=Wireless PCI Adapter RT2400 / RT2460
+
+pci:v00001814d00000101sv00001043sd00000127*
+ ID_PRODUCT_FROM_DATABASE=WiFi-b add-on Card
+
+pci:v00001814d00000101sv00001371sd00000010*
+ ID_PRODUCT_FROM_DATABASE=Minitar MNW2BPCI Wireless PCI Card
+
+pci:v00001814d00000101sv00001462sd00006828*
+ ID_PRODUCT_FROM_DATABASE=PC11B2 (MS-6828) Wireless 11b PCI Card
+
+pci:v00001814d00000200*
+ ID_PRODUCT_FROM_DATABASE=RT2500 802.11g PCI [PC54G2]
+
+pci:v00001814d00000201*
+ ID_PRODUCT_FROM_DATABASE=RT2500 Wireless 802.11bg
+
+pci:v00001814d00000201sv00001043sd0000130F*
+ ID_PRODUCT_FROM_DATABASE=WL-130g
+
+pci:v00001814d00000201sv00001186sd00003C00*
+ ID_PRODUCT_FROM_DATABASE=DWL-G650X Wireless 11g CardBus Adapter
+
+pci:v00001814d00000201sv00001371sd0000001E*
+ ID_PRODUCT_FROM_DATABASE=CWC-854 Wireless-G CardBus Adapter
+
+pci:v00001814d00000201sv00001371sd0000001F*
+ ID_PRODUCT_FROM_DATABASE=CWM-854 Wireless-G Mini PCI Adapter
+
+pci:v00001814d00000201sv00001371sd00000020*
+ ID_PRODUCT_FROM_DATABASE=CWP-854 Wireless-G PCI Adapter
+
+pci:v00001814d00000201sv00001458sd0000E381*
+ ID_PRODUCT_FROM_DATABASE=GN-WMKG 802.11b/g Wireless CardBus Adapter
+
+pci:v00001814d00000201sv00001458sd0000E931*
+ ID_PRODUCT_FROM_DATABASE=GN-WIKG 802.11b/g mini-PCI Adapter
+
+pci:v00001814d00000201sv00001462sd00006833*
+ ID_PRODUCT_FROM_DATABASE=Unknown 802.11g mini-PCI Adapter
+
+pci:v00001814d00000201sv00001462sd00006835*
+ ID_PRODUCT_FROM_DATABASE=Wireless 11G CardBus CB54G2
+
+pci:v00001814d00000201sv00001737sd00000032*
+ ID_PRODUCT_FROM_DATABASE=WMP54G v4.0 PCI Adapter
+
+pci:v00001814d00000201sv00001799sd0000700A*
+ ID_PRODUCT_FROM_DATABASE=F5D7000 v2000/v3000 Wireless G Desktop Card
+
+pci:v00001814d00000201sv00001799sd0000701A*
+ ID_PRODUCT_FROM_DATABASE=F5D7010 v2000/v3000 Wireless G Notebook Card
+
+pci:v00001814d00000201sv00001814sd00002560*
+ ID_PRODUCT_FROM_DATABASE=RT2500 Wireless 802.11bg
+
+pci:v00001814d00000201sv0000182Dsd00009073*
+ ID_PRODUCT_FROM_DATABASE=WL-115 Wireless Network PCI Adapter
+
+pci:v00001814d00000201sv0000185Fsd000022A0*
+ ID_PRODUCT_FROM_DATABASE=CN-WF513 Wireless Cardbus Adapter
+
+pci:v00001814d00000201sv000018EBsd00005312*
+ ID_PRODUCT_FROM_DATABASE=WL531P IEEE 802.11g PCI Card-EU
+
+pci:v00001814d00000201sv00001948sd00003C00*
+ ID_PRODUCT_FROM_DATABASE=C54RC v1 Wireless 11g CardBus Adapter
+
+pci:v00001814d00000201sv00001948sd00003C01*
+ ID_PRODUCT_FROM_DATABASE=C54Ri v1 Wireless 11g PCI Adapter
+
+pci:v00001814d00000300*
+ ID_PRODUCT_FROM_DATABASE=Wireless Adapter Canyon CN-WF511
+
+pci:v00001814d00000301*
+ ID_PRODUCT_FROM_DATABASE=RT2561/RT61 802.11g PCI
+
+pci:v00001814d00000301sv00001186sd00003C08*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.E1)
+
+pci:v00001814d00000301sv00001186sd00003C09*
+ ID_PRODUCT_FROM_DATABASE=DWL-G510 Rev C
+
+pci:v00001814d00000301sv000013D1sd0000ABE3*
+ ID_PRODUCT_FROM_DATABASE=miniPCI Pluscom 802.11 a/b/g
+
+pci:v00001814d00000301sv00001458sd0000E933*
+ ID_PRODUCT_FROM_DATABASE=GN-WI01GS
+
+pci:v00001814d00000301sv00001458sd0000E934*
+ ID_PRODUCT_FROM_DATABASE=GN-WP01GS
+
+pci:v00001814d00000301sv00001737sd00000055*
+ ID_PRODUCT_FROM_DATABASE=WMP54G v4.1
+
+pci:v00001814d00000301sv00001799sd0000700E*
+ ID_PRODUCT_FROM_DATABASE=F5D7000 v6000 Wireless G Desktop Card
+
+pci:v00001814d00000301sv00001799sd0000701E*
+ ID_PRODUCT_FROM_DATABASE=F5D7010 v6000 Wireless G Notebook Card
+
+pci:v00001814d00000301sv000017F9sd00000012*
+ ID_PRODUCT_FROM_DATABASE=AWLC3026T 802.11g Wireless CardBus Adapter
+
+pci:v00001814d00000301sv00001814sd00002561*
+ ID_PRODUCT_FROM_DATABASE=EW-7108PCg/EW-7128g
+
+pci:v00001814d00000302*
+ ID_PRODUCT_FROM_DATABASE=RT2561/RT61 rev B 802.11g
+
+pci:v00001814d00000302sv00001186sd00003A71*
+ ID_PRODUCT_FROM_DATABASE=DWA-510 Wireless G Desktop Adapter
+
+pci:v00001814d00000302sv00001186sd00003C08*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.E2)
+
+pci:v00001814d00000302sv00001186sd00003C09*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G510 Wireless Network Adapter (Rev.C)
+
+pci:v00001814d00000302sv00001462sd0000B834*
+ ID_PRODUCT_FROM_DATABASE=PC54G3 Wireless 11g PCI Card
+
+pci:v00001814d00000302sv00001948sd00003C23*
+ ID_PRODUCT_FROM_DATABASE=C54RC v2 Wireless 11g CardBus Adapter
+
+pci:v00001814d00000302sv00001948sd00003C24*
+ ID_PRODUCT_FROM_DATABASE=C54Ri v2 Wireless 11g PCI Adapter
+
+pci:v00001814d00000401*
+ ID_PRODUCT_FROM_DATABASE=RT2600 802.11 MIMO
+
+pci:v00001814d00000401sv00001737sd00000052*
+ ID_PRODUCT_FROM_DATABASE=WPC54GR v1 802.11g Wireless-G Notebook Adapter with RangeBooster
+
+pci:v00001814d00000401sv000017F9sd00000011*
+ ID_PRODUCT_FROM_DATABASE=WPCR-137G 802.11bg Wireless CardBus Adapter
+
+pci:v00001814d00000401sv000017F9sd00000016*
+ ID_PRODUCT_FROM_DATABASE=WPIR-119GH 802.11bg Wireless Desktop Adapter
+
+pci:v00001814d00000601*
+ ID_PRODUCT_FROM_DATABASE=RT2800 802.11n PCI
+
+pci:v00001814d00000601sv00001799sd0000801C*
+ ID_PRODUCT_FROM_DATABASE=F5D8011 v3 802.11n N1 Wireless Notebook Card
+
+pci:v00001814d00000601sv0000187Esd00003412*
+ ID_PRODUCT_FROM_DATABASE=NWD-310N 802.11n Wireless PCI Adapter
+
+pci:v00001814d00000681*
+ ID_PRODUCT_FROM_DATABASE=RT2890 Wireless 802.11n PCIe
+
+pci:v00001814d00000681sv00001458sd0000E939*
+ ID_PRODUCT_FROM_DATABASE=GN-WS30N-RH 802.11bgn Mini PCIe Card
+
+pci:v00001814d00000701*
+ ID_PRODUCT_FROM_DATABASE=RT2760 Wireless 802.11n 1T/2R
+
+pci:v00001814d00000701sv00001737sd00000074*
+ ID_PRODUCT_FROM_DATABASE=WMP110 v2 802.11n RangePlus Wireless PCI Adapter
+
+pci:v00001814d00000781*
+ ID_PRODUCT_FROM_DATABASE=RT2790 Wireless 802.11n 1T/2R PCIe
+
+pci:v00001814d00003060*
+ ID_PRODUCT_FROM_DATABASE=RT3060 Wireless 802.11n 1T/1R
+
+pci:v00001814d00003060sv00001186sd00003C04*
+ ID_PRODUCT_FROM_DATABASE=DWA-525 Wireless N 150 Desktop Adapter (rev.A1)
+
+pci:v00001814d00003062*
+ ID_PRODUCT_FROM_DATABASE=RT3062 Wireless 802.11n 2T/2R
+
+pci:v00001814d00003090*
+ ID_PRODUCT_FROM_DATABASE=RT3090 Wireless 802.11n 1T/1R PCIe
+
+pci:v00001814d00003090sv000013BDsd00001057*
+ ID_PRODUCT_FROM_DATABASE=GN-WS32L-RH Half-size Mini PCIe Card
+
+pci:v00001814d00003091*
+ ID_PRODUCT_FROM_DATABASE=RT3091 Wireless 802.11n 1T/2R PCIe
+
+pci:v00001814d00003092*
+ ID_PRODUCT_FROM_DATABASE=RT3092 Wireless 802.11n 2T/2R PCIe
+
+pci:v00001814d00003290*
+ ID_PRODUCT_FROM_DATABASE=RT3290 Wireless 802.11n 1T/1R PCIe
+
+pci:v00001814d00003298*
+ ID_PRODUCT_FROM_DATABASE=RT3290 Bluetooth
+
+pci:v00001814d00003592*
+ ID_PRODUCT_FROM_DATABASE=RT3592 Wireless 802.11abgn 2T/2R PCIe
+
+pci:v00001814d00005360*
+ ID_PRODUCT_FROM_DATABASE=RT5360 Wireless 802.11n 1T/1R
+
+pci:v00001814d00005360sv00001186sd00003C05*
+ ID_PRODUCT_FROM_DATABASE=DWA-525 Wireless N 150 Desktop Adapter (rev.A2)
+
+pci:v00001814d00005360sv000020F4sd0000703A*
+ ID_PRODUCT_FROM_DATABASE=TEW-703PI N150 Wireless PCI Adapter
+
+pci:v00001814d00005390*
+ ID_PRODUCT_FROM_DATABASE=RT5390 Wireless 802.11n 1T/1R PCIe
+
+pci:v00001814d00005390sv0000103Csd00001636*
+ ID_PRODUCT_FROM_DATABASE=U98Z077.00 Half-size Mini PCIe Card
+
+pci:v00001814d0000539F*
+ ID_PRODUCT_FROM_DATABASE=RT5390 [802.11 b/g/n 1T1R G-band PCI Express Single Chip]
+
+pci:v00001814d0000539Fsv0000103Csd00001637*
+ ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 PCIe wireless card
+
+pci:v00001814d0000E932*
+ ID_PRODUCT_FROM_DATABASE=RT2560F 802.11 b/g PCI
+
+pci:v00001815*
+ ID_VENDOR_FROM_DATABASE=Devolo AG
+
+pci:v00001820*
+ ID_VENDOR_FROM_DATABASE=InfiniCon Systems Inc.
+
+pci:v00001822*
+ ID_VENDOR_FROM_DATABASE=Twinhan Technology Co. Ltd
+
+pci:v00001822d00004E35*
+ ID_PRODUCT_FROM_DATABASE=Mantis DTV PCI Bridge Controller [Ver 1.0]
+
+pci:v0000182D*
+ ID_VENDOR_FROM_DATABASE=SiteCom Europe BV
+
+pci:v0000182Dd00003069*
+ ID_PRODUCT_FROM_DATABASE=ISDN PCI DC-105V2
+
+pci:v0000182Dd00009790*
+ ID_PRODUCT_FROM_DATABASE=WL-121 Wireless Network Adapter 100g+ [Ver.3]
+
+pci:v0000182E*
+ ID_VENDOR_FROM_DATABASE=Raza Microelectronics, Inc.
+
+pci:v0000182Ed00000008*
+ ID_PRODUCT_FROM_DATABASE=XLR516 Processor
+
+pci:v0000182F*
+ ID_VENDOR_FROM_DATABASE=Broadcom
+
+pci:v0000182Fd0000000B*
+ ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] SATA (RAID Mode)
+
+pci:v00001830*
+ ID_VENDOR_FROM_DATABASE=Credence Systems Corporation
+
+pci:v0000183B*
+ ID_VENDOR_FROM_DATABASE=MikroM GmbH
+
+pci:v0000183Bd000008A7*
+ ID_PRODUCT_FROM_DATABASE=MVC100 DVI
+
+pci:v0000183Bd000008A8*
+ ID_PRODUCT_FROM_DATABASE=MVC101 SDI
+
+pci:v0000183Bd000008A9*
+ ID_PRODUCT_FROM_DATABASE=MVC102 DVI+Audio
+
+pci:v0000183Bd000008B0*
+ ID_PRODUCT_FROM_DATABASE=MVC200-DC
+
+pci:v00001846*
+ ID_VENDOR_FROM_DATABASE=Alcatel-Lucent
+
+pci:v00001849*
+ ID_VENDOR_FROM_DATABASE=ASRock Incorporation
+
+pci:v0000184A*
+ ID_VENDOR_FROM_DATABASE=Thales Computers
+
+pci:v0000184Ad00001100*
+ ID_PRODUCT_FROM_DATABASE=MAX II cPLD
+
+pci:v00001851*
+ ID_VENDOR_FROM_DATABASE=Microtune, Inc.
+
+pci:v00001852*
+ ID_VENDOR_FROM_DATABASE=Anritsu Corp.
+
+pci:v00001853*
+ ID_VENDOR_FROM_DATABASE=SMSC Automotive Infotainment System Group
+
+pci:v00001854*
+ ID_VENDOR_FROM_DATABASE=LG Electronics, Inc.
+
+pci:v0000185B*
+ ID_VENDOR_FROM_DATABASE=Compro Technology, Inc.
+
+pci:v0000185Bd00001489*
+ ID_PRODUCT_FROM_DATABASE=VideoMate Vista T100
+
+pci:v0000185F*
+ ID_VENDOR_FROM_DATABASE=Wistron NeWeb Corp.
+
+pci:v00001864*
+ ID_VENDOR_FROM_DATABASE=SilverBack
+
+pci:v00001864d00002110*
+ ID_PRODUCT_FROM_DATABASE=ISNAP 2110
+
+pci:v00001867*
+ ID_VENDOR_FROM_DATABASE=Topspin Communications
+
+pci:v00001867d00005A44*
+ ID_PRODUCT_FROM_DATABASE=MT23108 InfiniHost HCA
+
+pci:v00001867d00005A45*
+ ID_PRODUCT_FROM_DATABASE=MT23108 InfiniHost HCA flash recovery
+
+pci:v00001867d00005A46*
+ ID_PRODUCT_FROM_DATABASE=MT23108 InfiniHost HCA bridge
+
+pci:v00001867d00006278*
+ ID_PRODUCT_FROM_DATABASE=MT25208 InfiniHost III Ex (Tavor compatibility mode)
+
+pci:v00001867d00006282*
+ ID_PRODUCT_FROM_DATABASE=MT25208 InfiniHost III Ex
+
+pci:v0000186C*
+ ID_VENDOR_FROM_DATABASE=Humusoft, s.r.o.
+
+pci:v0000186Cd00000612*
+ ID_PRODUCT_FROM_DATABASE=AD612 Data Acquisition Device
+
+pci:v0000186Cd00000614*
+ ID_PRODUCT_FROM_DATABASE=MF614 Multifunction I/O Card
+
+pci:v0000186Cd00000622*
+ ID_PRODUCT_FROM_DATABASE=AD622 Data Acquisition Device
+
+pci:v0000186Cd00000624*
+ ID_PRODUCT_FROM_DATABASE=MF624 Multifunction I/O Card
+
+pci:v0000186Cd00000625*
+ ID_PRODUCT_FROM_DATABASE=MF625 3-phase Motor Driver
+
+pci:v0000186F*
+ ID_VENDOR_FROM_DATABASE=WiNRADiO Communications
+
+pci:v00001876*
+ ID_VENDOR_FROM_DATABASE=L-3 Communications
+
+pci:v00001876d0000A101*
+ ID_PRODUCT_FROM_DATABASE=VigraWATCH PCI
+
+pci:v00001876d0000A102*
+ ID_PRODUCT_FROM_DATABASE=VigraWATCH PMC
+
+pci:v00001876d0000A103*
+ ID_PRODUCT_FROM_DATABASE=Vigra I/O
+
+pci:v0000187E*
+ ID_VENDOR_FROM_DATABASE=ZyXEL Communication Corporation
+
+pci:v0000187Ed00003403*
+ ID_PRODUCT_FROM_DATABASE=ZyAir G-110 802.11g
+
+pci:v0000187Ed0000340E*
+ ID_PRODUCT_FROM_DATABASE=M-302 802.11g XtremeMIMO
+
+pci:v00001885*
+ ID_VENDOR_FROM_DATABASE=Avvida Systems Inc.
+
+pci:v00001888*
+ ID_VENDOR_FROM_DATABASE=Varisys Ltd
+
+pci:v00001888d00000301*
+ ID_PRODUCT_FROM_DATABASE=VMFX1 FPGA PMC module
+
+pci:v00001888d00000601*
+ ID_PRODUCT_FROM_DATABASE=VSM2 dual PMC carrier
+
+pci:v00001888d00000710*
+ ID_PRODUCT_FROM_DATABASE=VS14x series PowerPC PCI board
+
+pci:v00001888d00000720*
+ ID_PRODUCT_FROM_DATABASE=VS24x series PowerPC PCI board
+
+pci:v0000188A*
+ ID_VENDOR_FROM_DATABASE=Ample Communications, Inc
+
+pci:v00001890*
+ ID_VENDOR_FROM_DATABASE=Egenera, Inc.
+
+pci:v00001894*
+ ID_VENDOR_FROM_DATABASE=KNC One
+
+pci:v00001896*
+ ID_VENDOR_FROM_DATABASE=B&B Electronics Manufacturing Company, Inc.
+
+pci:v00001896d00004202*
+ ID_PRODUCT_FROM_DATABASE=MIport 3PCIU2 2-port Serial
+
+pci:v00001896d00004204*
+ ID_PRODUCT_FROM_DATABASE=MIport 3PCIU4 4-port Serial
+
+pci:v00001896d00004208*
+ ID_PRODUCT_FROM_DATABASE=MIport 3PCIU8 8-port Serial
+
+pci:v00001896d00004211*
+ ID_PRODUCT_FROM_DATABASE=MIport 3PCIOU1 1-port Isolated Serial
+
+pci:v00001896d00004212*
+ ID_PRODUCT_FROM_DATABASE=MIport 3PCIOU2 2-port Isolated Serial
+
+pci:v00001896d00004214*
+ ID_PRODUCT_FROM_DATABASE=MIport 3PCIOU4 4-port Isolated Serial
+
+pci:v00001896d0000BB10*
+ ID_PRODUCT_FROM_DATABASE=3PCI2 2-Port Serial
+
+pci:v00001896d0000BB11*
+ ID_PRODUCT_FROM_DATABASE=3PCIO1 1-Port Isolated Serial
+
+pci:v00001897*
+ ID_VENDOR_FROM_DATABASE=AMtek
+
+pci:v000018A1*
+ ID_VENDOR_FROM_DATABASE=Astute Networks Inc.
+
+pci:v000018A2*
+ ID_VENDOR_FROM_DATABASE=Stretch Inc.
+
+pci:v000018A2d00000002*
+ ID_PRODUCT_FROM_DATABASE=VRC6016 16-Channel PCIe DVR Card
+
+pci:v000018A3*
+ ID_VENDOR_FROM_DATABASE=AT&T
+
+pci:v000018AC*
+ ID_VENDOR_FROM_DATABASE=DViCO Corporation
+
+pci:v000018ACd0000D500*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV 5
+
+pci:v000018ACd0000D800*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold
+
+pci:v000018ACd0000D810*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold-Q
+
+pci:v000018ACd0000D820*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold-T
+
+pci:v000018ACd0000DB30*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Pro
+
+pci:v000018ACd0000DB40*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Hybrid
+
+pci:v000018ACd0000DB78*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Dual Express
+
+pci:v000018B8*
+ ID_VENDOR_FROM_DATABASE=Ammasso
+
+pci:v000018B8d0000B001*
+ ID_PRODUCT_FROM_DATABASE=AMSO 1100 iWARP/RDMA Gigabit Ethernet Coprocessor
+
+pci:v000018BC*
+ ID_VENDOR_FROM_DATABASE=Info-Tek Corp.
+
+pci:v000018C3*
+ ID_VENDOR_FROM_DATABASE=Micronas Semiconductor Holding AG
+
+pci:v000018C3d00000720*
+ ID_PRODUCT_FROM_DATABASE=nGene PCI-Express Multimedia Controller
+
+pci:v000018C3d00000720sv000007CAsd0000032E*
+ ID_PRODUCT_FROM_DATABASE=Hybrid M779 PCI-E
+
+pci:v000018C8*
+ ID_VENDOR_FROM_DATABASE=Cray Inc
+
+pci:v000018C9*
+ ID_VENDOR_FROM_DATABASE=ARVOO Engineering BV
+
+pci:v000018CA*
+ ID_VENDOR_FROM_DATABASE=XGI Technology Inc. (eXtreme Graphics Innovation)
+
+pci:v000018CAd00000020*
+ ID_PRODUCT_FROM_DATABASE=Z7/Z9 (XG20 core)
+
+pci:v000018CAd00000021*
+ ID_PRODUCT_FROM_DATABASE=Z9s/Z9m (XG21 core)
+
+pci:v000018CAd00000027*
+ ID_PRODUCT_FROM_DATABASE=Z11/Z11M
+
+pci:v000018CAd00000040*
+ ID_PRODUCT_FROM_DATABASE=Volari V3XT/V5/V8
+
+pci:v000018CAd00000047*
+ ID_PRODUCT_FROM_DATABASE=Volari 8300 (chip: XP10, codename: XG47)
+
+pci:v000018D2*
+ ID_VENDOR_FROM_DATABASE=Sitecom Europe BV (Wrong ID)
+
+pci:v000018D2d00003069*
+ ID_PRODUCT_FROM_DATABASE=DC-105v2 ISDN controller
+
+pci:v000018D8*
+ ID_VENDOR_FROM_DATABASE=Dialogue Technology Corp.
+
+pci:v000018DD*
+ ID_VENDOR_FROM_DATABASE=Artimi Inc
+
+pci:v000018DDd00004C6F*
+ ID_PRODUCT_FROM_DATABASE=Artimi RTMI-100 UWB adapter
+
+pci:v000018E6*
+ ID_VENDOR_FROM_DATABASE=MPL AG
+
+pci:v000018E6d00000001*
+ ID_PRODUCT_FROM_DATABASE=OSCI [Octal Serial Communication Interface]
+
+pci:v000018EB*
+ ID_VENDOR_FROM_DATABASE=Advance Multimedia Internet Technology, Inc.
+
+pci:v000018EC*
+ ID_VENDOR_FROM_DATABASE=Cesnet, z.s.p.o.
+
+pci:v000018ECd00006D05*
+ ID_PRODUCT_FROM_DATABASE=ML555
+
+pci:v000018ECd00006D05sv000018ECsd00000100*
+ ID_PRODUCT_FROM_DATABASE=NIC (ethernet interfaces)
+
+pci:v000018ECd00006D05sv000018ECsd00000200*
+ ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 4x1G
+
+pci:v000018ECd00006D05sv000018ECsd00000201*
+ ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 2x10G
+
+pci:v000018ECd00006D05sv000018ECsd00000300*
+ ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 4x1G
+
+pci:v000018ECd00006D05sv000018ECsd00000302*
+ ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 2x10G
+
+pci:v000018ECd00006D05sv000018ECsd00004200*
+ ID_PRODUCT_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G
+
+pci:v000018ECd00006D05sv000018ECsd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Testing design
+
+pci:v000018ECd00006D05sv000018ECsd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=Boot design
+
+pci:v000018ECd0000C006*
+ ID_PRODUCT_FROM_DATABASE=COMBO6
+
+pci:v000018ECd0000C006sv000018ECsd0000D001*
+ ID_PRODUCT_FROM_DATABASE=COMBO-4MTX
+
+pci:v000018ECd0000C006sv000018ECsd0000D002*
+ ID_PRODUCT_FROM_DATABASE=COMBO-4SFP
+
+pci:v000018ECd0000C006sv000018ECsd0000D003*
+ ID_PRODUCT_FROM_DATABASE=COMBO-4SFPRO
+
+pci:v000018ECd0000C006sv000018ECsd0000D004*
+ ID_PRODUCT_FROM_DATABASE=COMBO-2XFP
+
+pci:v000018ECd0000C032*
+ ID_PRODUCT_FROM_DATABASE=COMBO-LXT110
+
+pci:v000018ECd0000C032sv000018ECsd00000100*
+ ID_PRODUCT_FROM_DATABASE=NIC (ethernet interfaces)
+
+pci:v000018ECd0000C032sv000018ECsd00000200*
+ ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 4x1G
+
+pci:v000018ECd0000C032sv000018ECsd00000201*
+ ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 2x10G
+
+pci:v000018ECd0000C032sv000018ECsd00000300*
+ ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 4x1G
+
+pci:v000018ECd0000C032sv000018ECsd00000302*
+ ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 2x10G
+
+pci:v000018ECd0000C032sv000018ECsd00004200*
+ ID_PRODUCT_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G
+
+pci:v000018ECd0000C032sv000018ECsd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Testing design
+
+pci:v000018ECd0000C032sv000018ECsd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=Boot design
+
+pci:v000018ECd0000C045*
+ ID_PRODUCT_FROM_DATABASE=COMBO6E
+
+pci:v000018ECd0000C050*
+ ID_PRODUCT_FROM_DATABASE=COMBO-PTM
+
+pci:v000018ECd0000C058*
+ ID_PRODUCT_FROM_DATABASE=COMBO6X
+
+pci:v000018ECd0000C058sv000018ECsd0000D001*
+ ID_PRODUCT_FROM_DATABASE=COMBO-4MTX
+
+pci:v000018ECd0000C058sv000018ECsd0000D002*
+ ID_PRODUCT_FROM_DATABASE=COMBO-4SFP
+
+pci:v000018ECd0000C058sv000018ECsd0000D003*
+ ID_PRODUCT_FROM_DATABASE=COMBO-4SFPRO
+
+pci:v000018ECd0000C058sv000018ECsd0000D004*
+ ID_PRODUCT_FROM_DATABASE=COMBO-2XFP
+
+pci:v000018ECd0000C132*
+ ID_PRODUCT_FROM_DATABASE=COMBO-LXT155
+
+pci:v000018ECd0000C132sv000018ECsd00000100*
+ ID_PRODUCT_FROM_DATABASE=NIC (ethernet interfaces)
+
+pci:v000018ECd0000C132sv000018ECsd00000200*
+ ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 4x1G
+
+pci:v000018ECd0000C132sv000018ECsd00000201*
+ ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 2x10G
+
+pci:v000018ECd0000C132sv000018ECsd00000300*
+ ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 4x1G
+
+pci:v000018ECd0000C132sv000018ECsd00000302*
+ ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 2x10G
+
+pci:v000018ECd0000C132sv000018ECsd00004200*
+ ID_PRODUCT_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G
+
+pci:v000018ECd0000C132sv000018ECsd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Testing design
+
+pci:v000018ECd0000C132sv000018ECsd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=Boot design
+
+pci:v000018ECd0000C232*
+ ID_PRODUCT_FROM_DATABASE=COMBO-FXT100
+
+pci:v000018ECd0000C232sv000018ECsd00000100*
+ ID_PRODUCT_FROM_DATABASE=NIC (ethernet interfaces)
+
+pci:v000018ECd0000C232sv000018ECsd00000200*
+ ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 4x1G
+
+pci:v000018ECd0000C232sv000018ECsd00000201*
+ ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 2x10G
+
+pci:v000018ECd0000C232sv000018ECsd00000300*
+ ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 4x1G
+
+pci:v000018ECd0000C232sv000018ECsd00000302*
+ ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 2x10G
+
+pci:v000018ECd0000C232sv000018ECsd00004200*
+ ID_PRODUCT_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G
+
+pci:v000018ECd0000C232sv000018ECsd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Testing design
+
+pci:v000018ECd0000C232sv000018ECsd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=Boot design
+
+pci:v000018EE*
+ ID_VENDOR_FROM_DATABASE=Chenming Mold Ind. Corp.
+
+pci:v000018F1*
+ ID_VENDOR_FROM_DATABASE=Spectrum GmbH
+
+pci:v000018F4*
+ ID_VENDOR_FROM_DATABASE=Napatech A/S
+
+pci:v000018F4d00000031*
+ ID_PRODUCT_FROM_DATABASE=NT20X Network Adapter
+
+pci:v000018F4d00000051*
+ ID_PRODUCT_FROM_DATABASE=NT20X Capture Card
+
+pci:v000018F4d00000061*
+ ID_PRODUCT_FROM_DATABASE=NT20E Capture Card
+
+pci:v000018F4d00000064*
+ ID_PRODUCT_FROM_DATABASE=NT20E Inline Card
+
+pci:v000018F4d00000071*
+ ID_PRODUCT_FROM_DATABASE=NT4E Capture Card
+
+pci:v000018F4d00000074*
+ ID_PRODUCT_FROM_DATABASE=NT4E Inline Card
+
+pci:v000018F4d00000081*
+ ID_PRODUCT_FROM_DATABASE=NT4E 4-port Expansion Card
+
+pci:v000018F4d00000091*
+ ID_PRODUCT_FROM_DATABASE=NT20X Capture Card [New Rev]
+
+pci:v000018F4d000000A1*
+ ID_PRODUCT_FROM_DATABASE=NT4E-STD Capture Card
+
+pci:v000018F4d000000A4*
+ ID_PRODUCT_FROM_DATABASE=NT4E-STD Inline Card
+
+pci:v000018F4d000000B1*
+ ID_PRODUCT_FROM_DATABASE=NTBPE Optical Bypass Adapter
+
+pci:v000018F4d000000C5*
+ ID_PRODUCT_FROM_DATABASE=NT20E2 Network Adapter 2x10Gb
+
+pci:v000018F4d000000D5*
+ ID_PRODUCT_FROM_DATABASE=NT40E2-4 Network Adapter 4x10Gb
+
+pci:v000018F4d000000E5*
+ ID_PRODUCT_FROM_DATABASE=NT40E2-1 Network Adapter 1x40Gb
+
+pci:v000018F4d000000F5*
+ ID_PRODUCT_FROM_DATABASE=NT4E2-4T-BP Network Adapter 4x1Gb with Electrical Bypass
+
+pci:v000018F6*
+ ID_VENDOR_FROM_DATABASE=NextIO
+
+pci:v000018F6d00001000*
+ ID_PRODUCT_FROM_DATABASE=[Nexsis] Switch Virtual P2P PCIe Bridge
+
+pci:v000018F6d00001050*
+ ID_PRODUCT_FROM_DATABASE=[Nexsis] Switch Virtual P2P PCI Bridge
+
+pci:v000018F6d00002000*
+ ID_PRODUCT_FROM_DATABASE=[Nexsis] Switch Integrated Mgmt. Endpoint
+
+pci:v000018F7*
+ ID_VENDOR_FROM_DATABASE=Commtech, Inc.
+
+pci:v000018F7d00000001*
+ ID_PRODUCT_FROM_DATABASE=ESCC-PCI-335 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000002*
+ ID_PRODUCT_FROM_DATABASE=422/4-PCI-335 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000003*
+ ID_PRODUCT_FROM_DATABASE=232/4-1M-PCI Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000004*
+ ID_PRODUCT_FROM_DATABASE=422/2-PCI-335 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000005*
+ ID_PRODUCT_FROM_DATABASE=IGESCC-PCI-ISO/1 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d0000000A*
+ ID_PRODUCT_FROM_DATABASE=232/4-PCI-335 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d0000000B*
+ ID_PRODUCT_FROM_DATABASE=232/8-PCI-335 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d0000000F*
+ ID_PRODUCT_FROM_DATABASE=FSCC Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000010*
+ ID_PRODUCT_FROM_DATABASE=GSCC Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000011*
+ ID_PRODUCT_FROM_DATABASE=QSSB Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000014*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000015*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC-104 Serial PCI/104+ Adapter [Fastcom]
+
+pci:v000018F7d00000016*
+ ID_PRODUCT_FROM_DATABASE=FSCC-232 RS-232 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000017*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC-104-NOUART Serial PCI/104+ Adapter [Fastcom]
+
+pci:v000018F7d00000018*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC/4 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000019*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d0000001A*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC-104-LVDS Serial PC/104+ Adapter [Fastcom]
+
+pci:v000018F7d0000001B*
+ ID_PRODUCT_FROM_DATABASE=FSCC/4 Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d0000001C*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC/4-LVDS Serial PCI Adapter [Fastcom]
+
+pci:v000018F7d00000020*
+ ID_PRODUCT_FROM_DATABASE=422/4-PCIe Serial PCIe Adapter [Fastcom]
+
+pci:v000018F7d00000021*
+ ID_PRODUCT_FROM_DATABASE=422/8-PCIe Serial PCIe Adapter [Fastcom]
+
+pci:v000018FB*
+ ID_VENDOR_FROM_DATABASE=Resilience Corporation
+
+pci:v00001904*
+ ID_VENDOR_FROM_DATABASE=Hangzhou Silan Microelectronics Co., Ltd.
+
+pci:v00001904d00002031*
+ ID_PRODUCT_FROM_DATABASE=SC92031 PCI Fast Ethernet Adapter
+
+pci:v00001904d00008139*
+ ID_PRODUCT_FROM_DATABASE=RTL8139D [Realtek] PCI 10/100BaseTX ethernet adaptor
+
+pci:v00001905*
+ ID_VENDOR_FROM_DATABASE=Micronas USA, Inc.
+
+pci:v00001912*
+ ID_VENDOR_FROM_DATABASE=Renesas Technology Corp.
+
+pci:v00001912d00000002*
+ ID_PRODUCT_FROM_DATABASE=SH7780 PCI Controller (PCIC)
+
+pci:v00001912d00000011*
+ ID_PRODUCT_FROM_DATABASE=SH7757 PCIe End-Point [PBI]
+
+pci:v00001912d00000012*
+ ID_PRODUCT_FROM_DATABASE=SH7757 PCIe-PCI Bridge [PPB]
+
+pci:v00001912d00000013*
+ ID_PRODUCT_FROM_DATABASE=SH7757 PCIe Switch [PS]
+
+pci:v00001912d00000014*
+ ID_PRODUCT_FROM_DATABASE=uPD720201 USB 3.0 Host Controller
+
+pci:v00001919*
+ ID_VENDOR_FROM_DATABASE=Soltek Computer Inc.
+
+pci:v00001923*
+ ID_VENDOR_FROM_DATABASE=Sangoma Technologies Corp.
+
+pci:v00001923d00000040*
+ ID_PRODUCT_FROM_DATABASE=A200/Remora FXO/FXS Analog AFT card
+
+pci:v00001923d00000100*
+ ID_PRODUCT_FROM_DATABASE=A104d QUAD T1/E1 AFT card
+
+pci:v00001923d00000300*
+ ID_PRODUCT_FROM_DATABASE=A101 single-port T1/E1
+
+pci:v00001923d00000400*
+ ID_PRODUCT_FROM_DATABASE=A104u Quad T1/E1 AFT
+
+pci:v00001924*
+ ID_VENDOR_FROM_DATABASE=Solarflare Communications
+
+pci:v00001924d00000703*
+ ID_PRODUCT_FROM_DATABASE=SFC4000 rev A net [Solarstorm]
+
+pci:v00001924d00000703sv000010B8sd00000102*
+ ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A2) [TigerCard]
+
+pci:v00001924d00000703sv000010B8sd00000103*
+ ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard]
+
+pci:v00001924d00000703sv000010B8sd00000201*
+ ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard]
+
+pci:v00001924d00000703sv00001924sd00000101*
+ ID_PRODUCT_FROM_DATABASE=SFE4001-A1
+
+pci:v00001924d00000703sv00001924sd00000102*
+ ID_PRODUCT_FROM_DATABASE=SFE4001-A2
+
+pci:v00001924d00000703sv00001924sd00000103*
+ ID_PRODUCT_FROM_DATABASE=SFE4001-A3
+
+pci:v00001924d00000703sv00001924sd00000201*
+ ID_PRODUCT_FROM_DATABASE=SFE4002-A1
+
+pci:v00001924d00000703sv00001924sd00000301*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A1
+
+pci:v00001924d00000703sv00001924sd00000302*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A2
+
+pci:v00001924d00000703sv00001924sd00000303*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A3
+
+pci:v00001924d00000703sv00001924sd00000304*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A4
+
+pci:v00001924d00000703sv00001924sd00000500*
+ ID_PRODUCT_FROM_DATABASE=SFE4005-A0
+
+pci:v00001924d00000710*
+ ID_PRODUCT_FROM_DATABASE=SFC4000 rev B [Solarstorm]
+
+pci:v00001924d00000710sv000010B8sd00000103*
+ ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard]
+
+pci:v00001924d00000710sv000010B8sd00000201*
+ ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard]
+
+pci:v00001924d00000710sv00001924sd00000102*
+ ID_PRODUCT_FROM_DATABASE=SFE4001-A2
+
+pci:v00001924d00000710sv00001924sd00000103*
+ ID_PRODUCT_FROM_DATABASE=SFE4001-A3
+
+pci:v00001924d00000710sv00001924sd00000201*
+ ID_PRODUCT_FROM_DATABASE=SFE4002-A1
+
+pci:v00001924d00000710sv00001924sd00000302*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A2
+
+pci:v00001924d00000710sv00001924sd00000303*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A3
+
+pci:v00001924d00000710sv00001924sd00000304*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A4
+
+pci:v00001924d00000710sv00001924sd00000500*
+ ID_PRODUCT_FROM_DATABASE=SFE4005-A0
+
+pci:v00001924d00000710sv00001924sd00005102*
+ ID_PRODUCT_FROM_DATABASE=SFN4111T-A2
+
+pci:v00001924d00000710sv00001924sd00005103*
+ ID_PRODUCT_FROM_DATABASE=SFN4111T-R3
+
+pci:v00001924d00000710sv00001924sd00005104*
+ ID_PRODUCT_FROM_DATABASE=SFN4111T-R4
+
+pci:v00001924d00000710sv00001924sd00005105*
+ ID_PRODUCT_FROM_DATABASE=SFN4111T-R5
+
+pci:v00001924d00000710sv00001924sd00005201*
+ ID_PRODUCT_FROM_DATABASE=SFN4112F-R1
+
+pci:v00001924d00000710sv00001924sd00005202*
+ ID_PRODUCT_FROM_DATABASE=SFN4112F-R2
+
+pci:v00001924d00000803*
+ ID_PRODUCT_FROM_DATABASE=SFC9020 [Solarstorm]
+
+pci:v00001924d00000803sv00001924sd00001201*
+ ID_PRODUCT_FROM_DATABASE=SFA6902F-R1 SFP+ AOE Adapter
+
+pci:v00001924d00000803sv00001924sd00006200*
+ ID_PRODUCT_FROM_DATABASE=SFN5122F-R0
+
+pci:v00001924d00000803sv00001924sd00006201*
+ ID_PRODUCT_FROM_DATABASE=SFN5122F-R1
+
+pci:v00001924d00000803sv00001924sd00006202*
+ ID_PRODUCT_FROM_DATABASE=SFN5122F-R2
+
+pci:v00001924d00000803sv00001924sd00006204*
+ ID_PRODUCT_FROM_DATABASE=SFN5122F-R4
+
+pci:v00001924d00000803sv00001924sd00006205*
+ ID_PRODUCT_FROM_DATABASE=SFN5122F-R5
+
+pci:v00001924d00000803sv00001924sd00006206*
+ ID_PRODUCT_FROM_DATABASE=SFN5122F-R6
+
+pci:v00001924d00000803sv00001924sd00006207*
+ ID_PRODUCT_FROM_DATABASE=SFN5122F-R7
+
+pci:v00001924d00000803sv00001924sd00006210*
+ ID_PRODUCT_FROM_DATABASE=SFN5322F-R0
+
+pci:v00001924d00000803sv00001924sd00006211*
+ ID_PRODUCT_FROM_DATABASE=SFN5322F-R1
+
+pci:v00001924d00000803sv00001924sd00006217*
+ ID_PRODUCT_FROM_DATABASE=SFN5322F-R7
+
+pci:v00001924d00000803sv00001924sd00006227*
+ ID_PRODUCT_FROM_DATABASE=SFN6122F-R7
+
+pci:v00001924d00000803sv00001924sd00006237*
+ ID_PRODUCT_FROM_DATABASE=SFN6322F-R7
+
+pci:v00001924d00000803sv00001924sd00006501*
+ ID_PRODUCT_FROM_DATABASE=SFN5802K-R1
+
+pci:v00001924d00000803sv00001924sd00006511*
+ ID_PRODUCT_FROM_DATABASE=SFN5814H-R1
+
+pci:v00001924d00000803sv00001924sd00006521*
+ ID_PRODUCT_FROM_DATABASE=SFN5812H-R1
+
+pci:v00001924d00000803sv00001924sd00006562*
+ ID_PRODUCT_FROM_DATABASE=SFN6832F-R2 SFP+ Mezzanine Adapter
+
+pci:v00001924d00000803sv00001924sd00006A05*
+ ID_PRODUCT_FROM_DATABASE=SFN5112F-R5
+
+pci:v00001924d00000803sv00001924sd00006A06*
+ ID_PRODUCT_FROM_DATABASE=SFN5112F-R6
+
+pci:v00001924d00000803sv00001924sd00007206*
+ ID_PRODUCT_FROM_DATABASE=SFN5162F-R6
+
+pci:v00001924d00000803sv00001924sd00007207*
+ ID_PRODUCT_FROM_DATABASE=SFN5162F-R7
+
+pci:v00001924d00000803sv00001924sd00007A06*
+ ID_PRODUCT_FROM_DATABASE=SFN5152F-R6
+
+pci:v00001924d00000803sv00001924sd00007A07*
+ ID_PRODUCT_FROM_DATABASE=SFN5152F-R7
+
+pci:v00001924d00000813*
+ ID_PRODUCT_FROM_DATABASE=SFL9021 [Solarstorm]
+
+pci:v00001924d00000813sv00001924sd00006100*
+ ID_PRODUCT_FROM_DATABASE=SFN5121T-R0
+
+pci:v00001924d00000813sv00001924sd00006102*
+ ID_PRODUCT_FROM_DATABASE=SFN5121T-R2
+
+pci:v00001924d00000813sv00001924sd00006103*
+ ID_PRODUCT_FROM_DATABASE=SFN5121T-R3
+
+pci:v00001924d00000813sv00001924sd00006104*
+ ID_PRODUCT_FROM_DATABASE=SFN5121T-R4
+
+pci:v00001924d00000813sv00001924sd00006902*
+ ID_PRODUCT_FROM_DATABASE=SFN5111T-R2
+
+pci:v00001924d00000813sv00001924sd00006904*
+ ID_PRODUCT_FROM_DATABASE=SFN5111T-R4
+
+pci:v00001924d00000813sv00001924sd00007104*
+ ID_PRODUCT_FROM_DATABASE=SFN5161T-R4
+
+pci:v00001924d00000813sv00001924sd00007904*
+ ID_PRODUCT_FROM_DATABASE=SFN5151T-R4
+
+pci:v00001924d00001803*
+ ID_PRODUCT_FROM_DATABASE=SFC9020 Virtual Function [Solarstorm]
+
+pci:v00001924d00001813*
+ ID_PRODUCT_FROM_DATABASE=SFL9021 Virtual Function [Solarstorm]
+
+pci:v00001924d00006703*
+ ID_PRODUCT_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm]
+
+pci:v00001924d00006703sv000010B8sd00000102*
+ ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A2) [TigerCard]
+
+pci:v00001924d00006703sv000010B8sd00000103*
+ ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard]
+
+pci:v00001924d00006703sv000010B8sd00000201*
+ ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard]
+
+pci:v00001924d00006703sv00001924sd00000101*
+ ID_PRODUCT_FROM_DATABASE=SFE4001-A1
+
+pci:v00001924d00006703sv00001924sd00000102*
+ ID_PRODUCT_FROM_DATABASE=SFE4001-A2
+
+pci:v00001924d00006703sv00001924sd00000103*
+ ID_PRODUCT_FROM_DATABASE=SFE4001-A3
+
+pci:v00001924d00006703sv00001924sd00000201*
+ ID_PRODUCT_FROM_DATABASE=SFE4002-A1
+
+pci:v00001924d00006703sv00001924sd00000301*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A1
+
+pci:v00001924d00006703sv00001924sd00000302*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A2
+
+pci:v00001924d00006703sv00001924sd00000303*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A3
+
+pci:v00001924d00006703sv00001924sd00000304*
+ ID_PRODUCT_FROM_DATABASE=SFE4003-A4
+
+pci:v00001924d00006703sv00001924sd00000500*
+ ID_PRODUCT_FROM_DATABASE=SFE4005-A0
+
+pci:v00001924d0000C101*
+ ID_PRODUCT_FROM_DATABASE=EF1-21022T [EtherFabric]
+
+pci:v0000192A*
+ ID_VENDOR_FROM_DATABASE=BiTMICRO Networks Inc.
+
+pci:v0000192E*
+ ID_VENDOR_FROM_DATABASE=TransDimension
+
+pci:v00001931*
+ ID_VENDOR_FROM_DATABASE=Option N.V.
+
+pci:v00001931d0000000C*
+ ID_PRODUCT_FROM_DATABASE=Qualcomm MSM6275 UMTS chip
+
+pci:v00001932*
+ ID_VENDOR_FROM_DATABASE=DiBcom
+
+pci:v0000193C*
+ ID_VENDOR_FROM_DATABASE=MAXIM Integrated Products
+
+pci:v0000193F*
+ ID_VENDOR_FROM_DATABASE=Comtech AHA Corp.
+
+pci:v0000193Fd00000001*
+ ID_PRODUCT_FROM_DATABASE=AHA36x-PCIX
+
+pci:v0000193Fd00000360*
+ ID_PRODUCT_FROM_DATABASE=AHA360-PCIe
+
+pci:v0000193Fd00000363*
+ ID_PRODUCT_FROM_DATABASE=AHA363-PCIe
+
+pci:v0000193Fd00000364*
+ ID_PRODUCT_FROM_DATABASE=AHA364-PCIe
+
+pci:v0000193Fd00000367*
+ ID_PRODUCT_FROM_DATABASE=AHA367-PCIe
+
+pci:v0000193Fd00000370*
+ ID_PRODUCT_FROM_DATABASE=AHA370-PCIe
+
+pci:v00001942*
+ ID_VENDOR_FROM_DATABASE=ClearSpeed Technology plc
+
+pci:v00001942d0000E511*
+ ID_PRODUCT_FROM_DATABASE=Advance X620 accelerator card
+
+pci:v00001942d0000E521*
+ ID_PRODUCT_FROM_DATABASE=Advance e620 accelerator card
+
+pci:v00001947*
+ ID_VENDOR_FROM_DATABASE=C-guys, Inc.
+
+pci:v00001947d00004743*
+ ID_PRODUCT_FROM_DATABASE=CG200 Dual SD/SDIO Host controller device
+
+pci:v00001948*
+ ID_VENDOR_FROM_DATABASE=Alpha Networks Inc.
+
+pci:v0000194A*
+ ID_VENDOR_FROM_DATABASE=DapTechnology B.V.
+
+pci:v0000194Ad00001111*
+ ID_PRODUCT_FROM_DATABASE=FireSpy3850
+
+pci:v0000194Ad00001112*
+ ID_PRODUCT_FROM_DATABASE=FireSpy450b
+
+pci:v0000194Ad00001113*
+ ID_PRODUCT_FROM_DATABASE=FireSpy450bT
+
+pci:v0000194Ad00001114*
+ ID_PRODUCT_FROM_DATABASE=FireSpy850
+
+pci:v0000194Ad00001115*
+ ID_PRODUCT_FROM_DATABASE=FireSpy850bT
+
+pci:v0000194Ad00001200*
+ ID_PRODUCT_FROM_DATABASE=FireTrac 3460bT
+
+pci:v0000194Ad00001201*
+ ID_PRODUCT_FROM_DATABASE=FireTrac 3460bT (fallback firmware)
+
+pci:v0000194Ad00001202*
+ ID_PRODUCT_FROM_DATABASE=FireTrac 3460bT
+
+pci:v0000194Ad00001203*
+ ID_PRODUCT_FROM_DATABASE=FireTrac 3460bT (fallback firmware)
+
+pci:v00001954*
+ ID_VENDOR_FROM_DATABASE=One Stop Systems, Inc.
+
+pci:v00001957*
+ ID_VENDOR_FROM_DATABASE=Freescale Semiconductor Inc
+
+pci:v00001957d00000012*
+ ID_PRODUCT_FROM_DATABASE=MPC8548E
+
+pci:v00001957d00000013*
+ ID_PRODUCT_FROM_DATABASE=MPC8548
+
+pci:v00001957d00000014*
+ ID_PRODUCT_FROM_DATABASE=MPC8543E
+
+pci:v00001957d00000015*
+ ID_PRODUCT_FROM_DATABASE=MPC8543
+
+pci:v00001957d00000018*
+ ID_PRODUCT_FROM_DATABASE=MPC8547E
+
+pci:v00001957d00000019*
+ ID_PRODUCT_FROM_DATABASE=MPC8545E
+
+pci:v00001957d0000001A*
+ ID_PRODUCT_FROM_DATABASE=MPC8545
+
+pci:v00001957d00000020*
+ ID_PRODUCT_FROM_DATABASE=MPC8568E
+
+pci:v00001957d00000021*
+ ID_PRODUCT_FROM_DATABASE=MPC8568
+
+pci:v00001957d00000022*
+ ID_PRODUCT_FROM_DATABASE=MPC8567E
+
+pci:v00001957d00000023*
+ ID_PRODUCT_FROM_DATABASE=MPC8567
+
+pci:v00001957d00000030*
+ ID_PRODUCT_FROM_DATABASE=MPC8533E
+
+pci:v00001957d00000031*
+ ID_PRODUCT_FROM_DATABASE=MPC8533
+
+pci:v00001957d00000032*
+ ID_PRODUCT_FROM_DATABASE=MPC8544E
+
+pci:v00001957d00000033*
+ ID_PRODUCT_FROM_DATABASE=MPC8544
+
+pci:v00001957d00000040*
+ ID_PRODUCT_FROM_DATABASE=MPC8572E
+
+pci:v00001957d00000041*
+ ID_PRODUCT_FROM_DATABASE=MPC8572
+
+pci:v00001957d00000050*
+ ID_PRODUCT_FROM_DATABASE=MPC8536E
+
+pci:v00001957d00000051*
+ ID_PRODUCT_FROM_DATABASE=MPC8536
+
+pci:v00001957d00000052*
+ ID_PRODUCT_FROM_DATABASE=MPC8535E
+
+pci:v00001957d00000053*
+ ID_PRODUCT_FROM_DATABASE=MPC8535
+
+pci:v00001957d00000060*
+ ID_PRODUCT_FROM_DATABASE=MPC8569
+
+pci:v00001957d00000061*
+ ID_PRODUCT_FROM_DATABASE=MPC8569E
+
+pci:v00001957d00000070*
+ ID_PRODUCT_FROM_DATABASE=P2020E
+
+pci:v00001957d00000071*
+ ID_PRODUCT_FROM_DATABASE=P2020
+
+pci:v00001957d00000078*
+ ID_PRODUCT_FROM_DATABASE=P2010E
+
+pci:v00001957d00000079*
+ ID_PRODUCT_FROM_DATABASE=P2010
+
+pci:v00001957d00000080*
+ ID_PRODUCT_FROM_DATABASE=MPC8349E
+
+pci:v00001957d00000081*
+ ID_PRODUCT_FROM_DATABASE=MPC8349
+
+pci:v00001957d00000082*
+ ID_PRODUCT_FROM_DATABASE=MPC8347E TBGA
+
+pci:v00001957d00000083*
+ ID_PRODUCT_FROM_DATABASE=MPC8347 TBGA
+
+pci:v00001957d00000084*
+ ID_PRODUCT_FROM_DATABASE=MPC8347E PBGA
+
+pci:v00001957d00000085*
+ ID_PRODUCT_FROM_DATABASE=MPC8347 PBGA
+
+pci:v00001957d00000086*
+ ID_PRODUCT_FROM_DATABASE=MPC8343E
+
+pci:v00001957d00000087*
+ ID_PRODUCT_FROM_DATABASE=MPC8343
+
+pci:v00001957d000000B4*
+ ID_PRODUCT_FROM_DATABASE=MPC8315E
+
+pci:v00001957d000000C2*
+ ID_PRODUCT_FROM_DATABASE=MPC8379E
+
+pci:v00001957d000000C3*
+ ID_PRODUCT_FROM_DATABASE=MPC8379
+
+pci:v00001957d000000C4*
+ ID_PRODUCT_FROM_DATABASE=MPC8378E
+
+pci:v00001957d000000C5*
+ ID_PRODUCT_FROM_DATABASE=MPC8378
+
+pci:v00001957d000000C6*
+ ID_PRODUCT_FROM_DATABASE=MPC8377E
+
+pci:v00001957d000000C7*
+ ID_PRODUCT_FROM_DATABASE=MPC8377
+
+pci:v00001957d00000100*
+ ID_PRODUCT_FROM_DATABASE=P1020E
+
+pci:v00001957d00000101*
+ ID_PRODUCT_FROM_DATABASE=P1020
+
+pci:v00001957d00000102*
+ ID_PRODUCT_FROM_DATABASE=P1021E
+
+pci:v00001957d00000103*
+ ID_PRODUCT_FROM_DATABASE=P1021
+
+pci:v00001957d00000108*
+ ID_PRODUCT_FROM_DATABASE=P1011E
+
+pci:v00001957d00000109*
+ ID_PRODUCT_FROM_DATABASE=P1011
+
+pci:v00001957d0000010A*
+ ID_PRODUCT_FROM_DATABASE=P1012E
+
+pci:v00001957d0000010B*
+ ID_PRODUCT_FROM_DATABASE=P1012
+
+pci:v00001957d00000110*
+ ID_PRODUCT_FROM_DATABASE=P1022E
+
+pci:v00001957d00000111*
+ ID_PRODUCT_FROM_DATABASE=P1022
+
+pci:v00001957d00000111sv00001C7Fsd00005200*
+ ID_PRODUCT_FROM_DATABASE=EB5200
+
+pci:v00001957d00000118*
+ ID_PRODUCT_FROM_DATABASE=P1013E
+
+pci:v00001957d00000119*
+ ID_PRODUCT_FROM_DATABASE=P1013
+
+pci:v00001957d00000128*
+ ID_PRODUCT_FROM_DATABASE=P1010
+
+pci:v00001957d00000400*
+ ID_PRODUCT_FROM_DATABASE=P4080E
+
+pci:v00001957d00000401*
+ ID_PRODUCT_FROM_DATABASE=P4080
+
+pci:v00001957d00000408*
+ ID_PRODUCT_FROM_DATABASE=P4040E
+
+pci:v00001957d00000409*
+ ID_PRODUCT_FROM_DATABASE=P4040
+
+pci:v00001957d0000580C*
+ ID_PRODUCT_FROM_DATABASE=MPC5121e
+
+pci:v00001957d00007010*
+ ID_PRODUCT_FROM_DATABASE=MPC8641 PCI Host Bridge
+
+pci:v00001957d00007011*
+ ID_PRODUCT_FROM_DATABASE=MPC8641D PCI Host Bridge
+
+pci:v00001957d00007018*
+ ID_PRODUCT_FROM_DATABASE=MPC8610
+
+pci:v00001958*
+ ID_VENDOR_FROM_DATABASE=Faster Technology, LLC.
+
+pci:v00001959*
+ ID_VENDOR_FROM_DATABASE=PA Semi, Inc
+
+pci:v00001959d0000A000*
+ ID_PRODUCT_FROM_DATABASE=PA6T Core
+
+pci:v00001959d0000A001*
+ ID_PRODUCT_FROM_DATABASE=PWRficient Host Bridge
+
+pci:v00001959d0000A002*
+ ID_PRODUCT_FROM_DATABASE=PWRficient PCI-Express Port
+
+pci:v00001959d0000A003*
+ ID_PRODUCT_FROM_DATABASE=PWRficient SMBus Controller
+
+pci:v00001959d0000A004*
+ ID_PRODUCT_FROM_DATABASE=PWRficient 16550 UART
+
+pci:v00001959d0000A005*
+ ID_PRODUCT_FROM_DATABASE=PWRficient Gigabit Ethernet
+
+pci:v00001959d0000A006*
+ ID_PRODUCT_FROM_DATABASE=PWRficient 10-Gigabit Ethernet
+
+pci:v00001959d0000A007*
+ ID_PRODUCT_FROM_DATABASE=PWRficient DMA Controller
+
+pci:v00001959d0000A008*
+ ID_PRODUCT_FROM_DATABASE=PWRficient LPC/Localbus Interface
+
+pci:v00001959d0000A009*
+ ID_PRODUCT_FROM_DATABASE=PWRficient L2 Cache
+
+pci:v00001959d0000A00A*
+ ID_PRODUCT_FROM_DATABASE=PWRficient DDR2 Memory Controller
+
+pci:v00001959d0000A00B*
+ ID_PRODUCT_FROM_DATABASE=PWRficient SERDES
+
+pci:v00001959d0000A00C*
+ ID_PRODUCT_FROM_DATABASE=PWRficient System/Debug Controller
+
+pci:v00001959d0000A00D*
+ ID_PRODUCT_FROM_DATABASE=PWRficient PCI-Express Internal Endpoint
+
+pci:v00001966*
+ ID_VENDOR_FROM_DATABASE=Orad Hi-Tec Systems
+
+pci:v00001966d00001975*
+ ID_PRODUCT_FROM_DATABASE=DVG64 family
+
+pci:v00001966d00001977*
+ ID_PRODUCT_FROM_DATABASE=DVG128 family
+
+pci:v00001969*
+ ID_VENDOR_FROM_DATABASE=Atheros Communications Inc.
+
+pci:v00001969d00001026*
+ ID_PRODUCT_FROM_DATABASE=AR8121/AR8113/AR8114 Gigabit or Fast Ethernet
+
+pci:v00001969d00001026sv00001043sd00008304*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-CM Motherboard
+
+pci:v00001969d00001048*
+ ID_PRODUCT_FROM_DATABASE=Attansic L1 Gigabit Ethernet
+
+pci:v00001969d00001048sv00001043sd00008226*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00001969d00001062*
+ ID_PRODUCT_FROM_DATABASE=AR8132 Fast Ethernet
+
+pci:v00001969d00001063*
+ ID_PRODUCT_FROM_DATABASE=AR8131 Gigabit Ethernet
+
+pci:v00001969d00001063sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=GA-G31M-ES2L Motherboard
+
+pci:v00001969d00001066*
+ ID_PRODUCT_FROM_DATABASE=Attansic L2c Gigabit Ethernet
+
+pci:v00001969d00001067*
+ ID_PRODUCT_FROM_DATABASE=Attansic L1c Gigabit Ethernet
+
+pci:v00001969d00001073*
+ ID_PRODUCT_FROM_DATABASE=AR8151 v1.0 Gigabit Ethernet
+
+pci:v00001969d00001083*
+ ID_PRODUCT_FROM_DATABASE=AR8151 v2.0 Gigabit Ethernet
+
+pci:v00001969d00001090*
+ ID_PRODUCT_FROM_DATABASE=AR8162 Fast Ethernet
+
+pci:v00001969d00001091*
+ ID_PRODUCT_FROM_DATABASE=AR8161 Gigabit Ethernet
+
+pci:v00001969d00001091sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00001969d00002048*
+ ID_PRODUCT_FROM_DATABASE=Attansic L2 Fast Ethernet
+
+pci:v00001969d00002060*
+ ID_PRODUCT_FROM_DATABASE=AR8152 v1.1 Fast Ethernet
+
+pci:v00001969d00002062*
+ ID_PRODUCT_FROM_DATABASE=AR8152 v2.0 Fast Ethernet
+
+pci:v0000196A*
+ ID_VENDOR_FROM_DATABASE=Sensory Networks Inc.
+
+pci:v0000196Ad00000101*
+ ID_PRODUCT_FROM_DATABASE=NodalCore C-1000 Content Classification Accelerator
+
+pci:v0000196Ad00000102*
+ ID_PRODUCT_FROM_DATABASE=NodalCore C-2000 Content Classification Accelerator
+
+pci:v0000196Ad00000105*
+ ID_PRODUCT_FROM_DATABASE=NodalCore C-3000 Content Classification Accelerator
+
+pci:v0000196D*
+ ID_VENDOR_FROM_DATABASE=Club-3D BV
+
+pci:v00001971*
+ ID_VENDOR_FROM_DATABASE=AGEIA Technologies, Inc.
+
+pci:v00001971d00001011*
+ ID_PRODUCT_FROM_DATABASE=Physics Processing Unit [PhysX]
+
+pci:v00001971d00001011sv00001043sd00000001*
+ ID_PRODUCT_FROM_DATABASE=PhysX P1
+
+pci:v00001974*
+ ID_VENDOR_FROM_DATABASE=Eberspaecher Electronics
+
+pci:v00001976*
+ ID_VENDOR_FROM_DATABASE=TRENDnet
+
+pci:v00001977*
+ ID_VENDOR_FROM_DATABASE=Parsec
+
+pci:v0000197B*
+ ID_VENDOR_FROM_DATABASE=JMicron Technology Corp.
+
+pci:v0000197Bd00000250*
+ ID_PRODUCT_FROM_DATABASE=JMC250 PCI Express Gigabit Ethernet Controller
+
+pci:v0000197Bd00000260*
+ ID_PRODUCT_FROM_DATABASE=JMC260 PCI Express Fast Ethernet Controller
+
+pci:v0000197Bd00000368*
+ ID_PRODUCT_FROM_DATABASE=JMB368 IDE controller
+
+pci:v0000197Bd00002360*
+ ID_PRODUCT_FROM_DATABASE=JMB360 AHCI Controller
+
+pci:v0000197Bd00002361*
+ ID_PRODUCT_FROM_DATABASE=JMB361 AHCI/IDE
+
+pci:v0000197Bd00002361sv00001462sd00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v0000197Bd00002362*
+ ID_PRODUCT_FROM_DATABASE=JMB362 SATA Controller
+
+pci:v0000197Bd00002362sv00001043sd00008460*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v0000197Bd00002363*
+ ID_PRODUCT_FROM_DATABASE=JMB363 SATA/IDE Controller
+
+pci:v0000197Bd00002363sv00001043sd000081E4*
+ ID_PRODUCT_FROM_DATABASE=P5B [JMB363]
+
+pci:v0000197Bd00002363sv00001458sd0000B000*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v0000197Bd00002363sv00001849sd00002363*
+ ID_PRODUCT_FROM_DATABASE=Motherboard (one of many)
+
+pci:v0000197Bd00002364*
+ ID_PRODUCT_FROM_DATABASE=JMB364 AHCI Controller
+
+pci:v0000197Bd00002365*
+ ID_PRODUCT_FROM_DATABASE=JMB365 AHCI/IDE
+
+pci:v0000197Bd00002366*
+ ID_PRODUCT_FROM_DATABASE=JMB366 AHCI/IDE
+
+pci:v0000197Bd00002368*
+ ID_PRODUCT_FROM_DATABASE=JMB368 IDE controller
+
+pci:v0000197Bd00002369*
+ ID_PRODUCT_FROM_DATABASE=JMB369 Serial ATA Controller
+
+pci:v0000197Bd00002380*
+ ID_PRODUCT_FROM_DATABASE=IEEE 1394 Host Controller
+
+pci:v0000197Bd00002381*
+ ID_PRODUCT_FROM_DATABASE=Standard SD Host Controller
+
+pci:v0000197Bd00002382*
+ ID_PRODUCT_FROM_DATABASE=SD/MMC Host Controller
+
+pci:v0000197Bd00002383*
+ ID_PRODUCT_FROM_DATABASE=MS Host Controller
+
+pci:v0000197Bd00002384*
+ ID_PRODUCT_FROM_DATABASE=xD Host Controller
+
+pci:v0000197Bd00002386*
+ ID_PRODUCT_FROM_DATABASE=Standard SD Host Controller
+
+pci:v0000197Bd00002387*
+ ID_PRODUCT_FROM_DATABASE=SD/MMC Host Controller
+
+pci:v0000197Bd00002388*
+ ID_PRODUCT_FROM_DATABASE=MS Host Controller
+
+pci:v0000197Bd00002389*
+ ID_PRODUCT_FROM_DATABASE=xD Host Controller
+
+pci:v0000197Bd00002391*
+ ID_PRODUCT_FROM_DATABASE=Standard SD Host Controller
+
+pci:v0000197Bd00002392*
+ ID_PRODUCT_FROM_DATABASE=SD/MMC Host Controller
+
+pci:v0000197Bd00002393*
+ ID_PRODUCT_FROM_DATABASE=MS Host Controller
+
+pci:v0000197Bd00002394*
+ ID_PRODUCT_FROM_DATABASE=xD Host Controller
+
+pci:v00001982*
+ ID_VENDOR_FROM_DATABASE=Distant Early Warning Communications Inc
+
+pci:v00001982d00001600*
+ ID_PRODUCT_FROM_DATABASE=OX16C954 HOST-A
+
+pci:v00001982d000016FF*
+ ID_PRODUCT_FROM_DATABASE=OX16C954 HOST-B
+
+pci:v00001989*
+ ID_VENDOR_FROM_DATABASE=Montilio Inc.
+
+pci:v00001989d00000001*
+ ID_PRODUCT_FROM_DATABASE=RapidFile Bridge
+
+pci:v00001989d00008001*
+ ID_PRODUCT_FROM_DATABASE=RapidFile
+
+pci:v0000198A*
+ ID_VENDOR_FROM_DATABASE=Nallatech Ltd.
+
+pci:v00001993*
+ ID_VENDOR_FROM_DATABASE=Innominate Security Technologies AG
+
+pci:v00001999*
+ ID_VENDOR_FROM_DATABASE=A-Logics
+
+pci:v00001999d0000A900*
+ ID_PRODUCT_FROM_DATABASE=AM-7209 Video Processor
+
+pci:v0000199A*
+ ID_VENDOR_FROM_DATABASE=Pulse-LINK, Inc.
+
+pci:v0000199D*
+ ID_VENDOR_FROM_DATABASE=Xsigo Systems
+
+pci:v0000199Dd00008209*
+ ID_PRODUCT_FROM_DATABASE=Virtual NIC Device
+
+pci:v0000199Dd0000890A*
+ ID_PRODUCT_FROM_DATABASE=Virtual HBA Device
+
+pci:v0000199F*
+ ID_VENDOR_FROM_DATABASE=Auvitek
+
+pci:v0000199Fd00008501*
+ ID_PRODUCT_FROM_DATABASE=AU85X1 PCI REV1.1
+
+pci:v0000199Fd00008521*
+ ID_PRODUCT_FROM_DATABASE=AU8521 TV card
+
+pci:v000019A2*
+ ID_VENDOR_FROM_DATABASE=Emulex Corporation
+
+pci:v000019A2d00000200*
+ ID_PRODUCT_FROM_DATABASE=BladeEngine 10Gb PCI-E iSCSI adapter
+
+pci:v000019A2d00000201*
+ ID_PRODUCT_FROM_DATABASE=BladeEngine 10Gb PCIe Network Adapter
+
+pci:v000019A2d00000211*
+ ID_PRODUCT_FROM_DATABASE=BladeEngine2 10Gb Gen2 PCIe Network Adapter
+
+pci:v000019A2d00000212*
+ ID_PRODUCT_FROM_DATABASE=BladeEngine2 10Gb Gen2 PCIe iSCSI Adapter
+
+pci:v000019A2d00000221*
+ ID_PRODUCT_FROM_DATABASE=BladeEngine3 10Gb Gen2 PCIe Network Adapter
+
+pci:v000019A2d00000222*
+ ID_PRODUCT_FROM_DATABASE=BladeEngine3 10Gb Gen2 PCIe iSCSI Adapter
+
+pci:v000019A2d00000700*
+ ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb NIC
+
+pci:v000019A2d00000700sv0000103Csd00001747*
+ ID_PRODUCT_FROM_DATABASE=NC550SFP DualPort 10GbE Server Adapter
+
+pci:v000019A2d00000700sv0000103Csd00001749*
+ ID_PRODUCT_FROM_DATABASE=NC550SFP Dual Port Server Adapter
+
+pci:v000019A2d00000700sv0000103Csd0000174A*
+ ID_PRODUCT_FROM_DATABASE=NC551m Dual Port FlexFabric 10Gb Adapter
+
+pci:v000019A2d00000700sv0000103Csd0000174B*
+ ID_PRODUCT_FROM_DATABASE=StorageWorks NC550 DualPort Converged Network Adapter
+
+pci:v000019A2d00000700sv0000103Csd00003314*
+ ID_PRODUCT_FROM_DATABASE=NC551i Dual Port FlexFabric 10Gb Adapter
+
+pci:v000019A2d00000702*
+ ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator
+
+pci:v000019A2d00000704*
+ ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb FCoE Initiator
+
+pci:v000019A2d00000710*
+ ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb NIC (be3)
+
+pci:v000019A2d00000710sv0000103Csd00003315*
+ ID_PRODUCT_FROM_DATABASE=NC553i 10Gb 2-port FlexFabric Converged Network Adapter
+
+pci:v000019A2d00000710sv0000103Csd00003340*
+ ID_PRODUCT_FROM_DATABASE=NC552SFP 2-port 10Gb Server Adapter
+
+pci:v000019A2d00000710sv0000103Csd00003341*
+ ID_PRODUCT_FROM_DATABASE=NC552m 10Gb 2-port FlexFabric Converged Network Adapter
+
+pci:v000019A2d00000710sv0000103Csd00003345*
+ ID_PRODUCT_FROM_DATABASE=NC553m 10Gb 2-port FlexFabric Converged Network Adapter
+
+pci:v000019A2d00000712*
+ ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator (be3)
+
+pci:v000019A2d00000714*
+ ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb FCoE Initiator (be3)
+
+pci:v000019A2d00000714sv0000103Csd00003315*
+ ID_PRODUCT_FROM_DATABASE=NC553i 10Gb 2-port FlexFabric Converged Network Adapter
+
+pci:v000019A8*
+ ID_VENDOR_FROM_DATABASE=DAQDATA GmbH
+
+pci:v000019AC*
+ ID_VENDOR_FROM_DATABASE=Kasten Chase Applied Research
+
+pci:v000019ACd00000001*
+ ID_PRODUCT_FROM_DATABASE=ACA2400 Crypto Accelerator
+
+pci:v000019AE*
+ ID_VENDOR_FROM_DATABASE=Progeny Systems Corporation
+
+pci:v000019AEd00000520*
+ ID_PRODUCT_FROM_DATABASE=4135 HFT Interface Controller
+
+pci:v000019AEd00000521*
+ ID_PRODUCT_FROM_DATABASE=Decimator
+
+pci:v000019C1*
+ ID_VENDOR_FROM_DATABASE=Exegy Inc.
+
+pci:v000019D1*
+ ID_VENDOR_FROM_DATABASE=Motorola Expedience
+
+pci:v000019D4*
+ ID_VENDOR_FROM_DATABASE=Quixant Limited
+
+pci:v000019DA*
+ ID_VENDOR_FROM_DATABASE=ZOTAC International (MCO) Ltd.
+
+pci:v000019DE*
+ ID_VENDOR_FROM_DATABASE=Pico Computing
+
+pci:v000019E2*
+ ID_VENDOR_FROM_DATABASE=Vector Informatik GmbH
+
+pci:v000019E3*
+ ID_VENDOR_FROM_DATABASE=DDRdrive LLC
+
+pci:v000019E3d00005801*
+ ID_PRODUCT_FROM_DATABASE=DDRdrive X1
+
+pci:v000019E3d00005808*
+ ID_PRODUCT_FROM_DATABASE=DDRdrive X8
+
+pci:v000019E3d0000DD52*
+ ID_PRODUCT_FROM_DATABASE=DDRdrive X1-30
+
+pci:v000019E7*
+ ID_VENDOR_FROM_DATABASE=NET (Network Equipment Technologies)
+
+pci:v000019E7d00001001*
+ ID_PRODUCT_FROM_DATABASE=STIX DSP Card
+
+pci:v000019E7d00001002*
+ ID_PRODUCT_FROM_DATABASE=STIX - 1 Port T1/E1 Card
+
+pci:v000019E7d00001003*
+ ID_PRODUCT_FROM_DATABASE=STIX - 2 Port T1/E1 Card
+
+pci:v000019E7d00001004*
+ ID_PRODUCT_FROM_DATABASE=STIX - 4 Port T1/E1 Card
+
+pci:v000019E7d00001005*
+ ID_PRODUCT_FROM_DATABASE=STIX - 4 Port FXS Card
+
+pci:v000019EE*
+ ID_VENDOR_FROM_DATABASE=Netronome Systems, Inc.
+
+pci:v000019F1*
+ ID_VENDOR_FROM_DATABASE=BFG Tech
+
+pci:v000019FF*
+ ID_VENDOR_FROM_DATABASE=Eclipse Electronic Systems, Inc.
+
+pci:v00001A03*
+ ID_VENDOR_FROM_DATABASE=ASPEED Technology, Inc.
+
+pci:v00001A03d00001150*
+ ID_PRODUCT_FROM_DATABASE=AST1150 PCI-to-PCI Bridge
+
+pci:v00001A03d00002000*
+ ID_PRODUCT_FROM_DATABASE=ASPEED Graphics Family
+
+pci:v00001A07*
+ ID_VENDOR_FROM_DATABASE=Kvaser AB
+
+pci:v00001A07d00000006*
+ ID_PRODUCT_FROM_DATABASE=CAN interface PC104+ HS/HS
+
+pci:v00001A07d00000007*
+ ID_PRODUCT_FROM_DATABASE=CAN interface PCIcanx II HS or HS/HS
+
+pci:v00001A07d00000008*
+ ID_PRODUCT_FROM_DATABASE=CAN interface PCIEcan HS or HS/HS
+
+pci:v00001A07d00000009*
+ ID_PRODUCT_FROM_DATABASE=CAN interface PCI104 HS/HS
+
+pci:v00001A08*
+ ID_VENDOR_FROM_DATABASE=Sierra semiconductor
+
+pci:v00001A08d00000000*
+ ID_PRODUCT_FROM_DATABASE=SC15064
+
+pci:v00001A0E*
+ ID_VENDOR_FROM_DATABASE=DekTec Digital Video B.V.
+
+pci:v00001A17*
+ ID_VENDOR_FROM_DATABASE=Force10 Networks, Inc.
+
+pci:v00001A17d00008002*
+ ID_PRODUCT_FROM_DATABASE=PB-10GE-2P 10GbE Security Card
+
+pci:v00001A1D*
+ ID_VENDOR_FROM_DATABASE=GFaI e.V.
+
+pci:v00001A1Dd00001A17*
+ ID_PRODUCT_FROM_DATABASE=Meta Networks MTP-1G IDPS NIC
+
+pci:v00001A1E*
+ ID_VENDOR_FROM_DATABASE=3Leaf Systems, Inc.
+
+pci:v00001A22*
+ ID_VENDOR_FROM_DATABASE=Ambric Inc.
+
+pci:v00001A29*
+ ID_VENDOR_FROM_DATABASE=Fortinet, Inc.
+
+pci:v00001A2B*
+ ID_VENDOR_FROM_DATABASE=Ascom AG
+
+pci:v00001A2Bd00000000*
+ ID_PRODUCT_FROM_DATABASE=GESP v1.2
+
+pci:v00001A2Bd00000001*
+ ID_PRODUCT_FROM_DATABASE=GESP v1.3
+
+pci:v00001A2Bd00000002*
+ ID_PRODUCT_FROM_DATABASE=ECOMP v1.3
+
+pci:v00001A2Bd00000005*
+ ID_PRODUCT_FROM_DATABASE=ETP v1.4
+
+pci:v00001A2Bd0000000A*
+ ID_PRODUCT_FROM_DATABASE=ETP-104 v1.1
+
+pci:v00001A2Bd0000000E*
+ ID_PRODUCT_FROM_DATABASE=DSLP-104 v1.1
+
+pci:v00001A32*
+ ID_VENDOR_FROM_DATABASE=Quanta Microsystems, Inc
+
+pci:v00001A3B*
+ ID_VENDOR_FROM_DATABASE=AzureWave
+
+pci:v00001A3Bd00001112*
+ ID_PRODUCT_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express)
+
+pci:v00001A41*
+ ID_VENDOR_FROM_DATABASE=Tilera Corp.
+
+pci:v00001A41d00000001*
+ ID_PRODUCT_FROM_DATABASE=TILE64 processor
+
+pci:v00001A41d00000002*
+ ID_PRODUCT_FROM_DATABASE=TILEPro processor
+
+pci:v00001A41d00000200*
+ ID_PRODUCT_FROM_DATABASE=TILE-Gx36 processor
+
+pci:v00001A4A*
+ ID_VENDOR_FROM_DATABASE=SLAC National Accelerator Lab PPA-REG
+
+pci:v00001A4Ad00001000*
+ ID_PRODUCT_FROM_DATABASE=MCOR Power Supply Controller
+
+pci:v00001A4Ad00001010*
+ ID_PRODUCT_FROM_DATABASE=AMC EVR - Stockholm Timing Board
+
+pci:v00001A4Ad00002000*
+ ID_PRODUCT_FROM_DATABASE=PGPCard - 4 Lane
+
+pci:v00001A4Ad00002010*
+ ID_PRODUCT_FROM_DATABASE=PCI-Express EVR
+
+pci:v00001A51*
+ ID_VENDOR_FROM_DATABASE=Hectronic AB
+
+pci:v00001A55*
+ ID_VENDOR_FROM_DATABASE=Rohde & Schwarz DVS GmbH
+
+pci:v00001A55d00000010*
+ ID_PRODUCT_FROM_DATABASE=SDStationOEM
+
+pci:v00001A55d00000011*
+ ID_PRODUCT_FROM_DATABASE=SDStationOEM II
+
+pci:v00001A55d00000020*
+ ID_PRODUCT_FROM_DATABASE=Centaurus
+
+pci:v00001A55d00000021*
+ ID_PRODUCT_FROM_DATABASE=Centaurus II
+
+pci:v00001A55d00000022*
+ ID_PRODUCT_FROM_DATABASE=Centaurus II LT
+
+pci:v00001A55d00000030*
+ ID_PRODUCT_FROM_DATABASE=CLIPSTER-VPU 1.x (Hugo)
+
+pci:v00001A55d00000040*
+ ID_PRODUCT_FROM_DATABASE=Hydra Cinema (JPEG)
+
+pci:v00001A55d00000050*
+ ID_PRODUCT_FROM_DATABASE=CLIPSTER-VPU 2.x (DigiLab)
+
+pci:v00001A55d00000060*
+ ID_PRODUCT_FROM_DATABASE=CLIPSTER-DCI 2.x (HydraX)
+
+pci:v00001A55d00000061*
+ ID_PRODUCT_FROM_DATABASE=Atomix
+
+pci:v00001A55d00000062*
+ ID_PRODUCT_FROM_DATABASE=Atomix LT
+
+pci:v00001A55d00000063*
+ ID_PRODUCT_FROM_DATABASE=Atomix HDMI
+
+pci:v00001A55d00000064*
+ ID_PRODUCT_FROM_DATABASE=Atomix STAN
+
+pci:v00001A55d00000065*
+ ID_PRODUCT_FROM_DATABASE=Atomix HDMI STAN
+
+pci:v00001A55d00000070*
+ ID_PRODUCT_FROM_DATABASE=RED Rocket
+
+pci:v00001A55d00000090*
+ ID_PRODUCT_FROM_DATABASE=CinePlay
+
+pci:v00001A56*
+ ID_VENDOR_FROM_DATABASE=Bigfoot Networks, Inc.
+
+pci:v00001A57*
+ ID_VENDOR_FROM_DATABASE=Highly Reliable Systems
+
+pci:v00001A58*
+ ID_VENDOR_FROM_DATABASE=Razer USA Ltd.
+
+pci:v00001A5D*
+ ID_VENDOR_FROM_DATABASE=Celoxica
+
+pci:v00001A5E*
+ ID_VENDOR_FROM_DATABASE=Aprius Inc.
+
+pci:v00001A5F*
+ ID_VENDOR_FROM_DATABASE=System TALKS Inc.
+
+pci:v00001A68*
+ ID_VENDOR_FROM_DATABASE=VirtenSys Limited
+
+pci:v00001A71*
+ ID_VENDOR_FROM_DATABASE=XenSource, Inc.
+
+pci:v00001A73*
+ ID_VENDOR_FROM_DATABASE=Violin Memory, Inc
+
+pci:v00001A73d00000001*
+ ID_PRODUCT_FROM_DATABASE=Mozart [Memory Appliance 1010]
+
+pci:v00001A76*
+ ID_VENDOR_FROM_DATABASE=Wavesat
+
+pci:v00001A77*
+ ID_VENDOR_FROM_DATABASE=Lightfleet Corporation
+
+pci:v00001A78*
+ ID_VENDOR_FROM_DATABASE=Virident Systems Inc.
+
+pci:v00001A78d00000031*
+ ID_PRODUCT_FROM_DATABASE=Virident FlashMAX Drive
+
+pci:v00001A78d00000031sv00001A78sd00000034*
+ ID_PRODUCT_FROM_DATABASE=FlashMAX PCIe SSD [rev 3]
+
+pci:v00001A78d00000031sv00001A78sd00000037*
+ ID_PRODUCT_FROM_DATABASE=FlashMAX PCIe SSD [rev 3D]
+
+pci:v00001A78d00000031sv00001A78sd00000038*
+ ID_PRODUCT_FROM_DATABASE=FlashMAX PCIe SSD [rev 4]
+
+pci:v00001A78d00000031sv00001A78sd00000039*
+ ID_PRODUCT_FROM_DATABASE=FlashMAX PCIe SSD [rev 4D]
+
+pci:v00001A78d00000040*
+ ID_PRODUCT_FROM_DATABASE=FlashMAX II
+
+pci:v00001A84*
+ ID_VENDOR_FROM_DATABASE=Commex Technologies
+
+pci:v00001A84d00000001*
+ ID_PRODUCT_FROM_DATABASE=Vulcan SP HT6210 10-Gigabit Ethernet (rev 02)
+
+pci:v00001A88*
+ ID_VENDOR_FROM_DATABASE=MEN Mikro Elektronik
+
+pci:v00001A88d00004D45*
+ ID_PRODUCT_FROM_DATABASE=Multifunction IP core
+
+pci:v00001A8C*
+ ID_VENDOR_FROM_DATABASE=Verigy Pte. Ltd.
+
+pci:v00001A8Cd00001100*
+ ID_PRODUCT_FROM_DATABASE=E8001-66443 PCI Express CIC
+
+pci:v00001A8E*
+ ID_VENDOR_FROM_DATABASE=DRS Technologies
+
+pci:v00001A8Ed00002090*
+ ID_PRODUCT_FROM_DATABASE=Model 2090 PCI Express
+
+pci:v00001AA8*
+ ID_VENDOR_FROM_DATABASE=Ciprico, Inc.
+
+pci:v00001AA8d00000009*
+ ID_PRODUCT_FROM_DATABASE=RAIDCore Controller
+
+pci:v00001AA8d0000000A*
+ ID_PRODUCT_FROM_DATABASE=RAIDCore Controller
+
+pci:v00001AAE*
+ ID_VENDOR_FROM_DATABASE=Global Velocity, Inc.
+
+pci:v00001AB6*
+ ID_VENDOR_FROM_DATABASE=CalDigit, Inc.
+
+pci:v00001AB6d00006201*
+ ID_PRODUCT_FROM_DATABASE=RAID Card
+
+pci:v00001AB8*
+ ID_VENDOR_FROM_DATABASE=Parallels, Inc.
+
+pci:v00001AB8d00004000*
+ ID_PRODUCT_FROM_DATABASE=Virtual Machine Communication Interface
+
+pci:v00001AB8d00004005*
+ ID_PRODUCT_FROM_DATABASE=Accelerated Virtual Video Adapter
+
+pci:v00001AB8d00004006*
+ ID_PRODUCT_FROM_DATABASE=Memory Ballooning Controller
+
+pci:v00001AB9*
+ ID_VENDOR_FROM_DATABASE=Espia Srl
+
+pci:v00001ACC*
+ ID_VENDOR_FROM_DATABASE=Point of View B.V
+
+pci:v00001AD7*
+ ID_VENDOR_FROM_DATABASE=Spectracom Corporation
+
+pci:v00001AD7d00008000*
+ ID_PRODUCT_FROM_DATABASE=TSync-PCIe Time Code Processor
+
+pci:v00001AD7d00009100*
+ ID_PRODUCT_FROM_DATABASE=TPRO-PCI-66U Timecode Reader/Generator
+
+pci:v00001ADE*
+ ID_VENDOR_FROM_DATABASE=Spin Master Ltd.
+
+pci:v00001ADEd00001501*
+ ID_PRODUCT_FROM_DATABASE=Swipetech barcode scanner
+
+pci:v00001AE0*
+ ID_VENDOR_FROM_DATABASE=Google, Inc.
+
+pci:v00001AE7*
+ ID_VENDOR_FROM_DATABASE=First Wise Media GmbH
+
+pci:v00001AE7d00000520*
+ ID_PRODUCT_FROM_DATABASE=HFC-S PCI A [X-TENSIONS XC-520]
+
+pci:v00001AE8*
+ ID_VENDOR_FROM_DATABASE=Silicon Software GmbH
+
+pci:v00001AE8d00000A40*
+ ID_PRODUCT_FROM_DATABASE=microEnable IV-BASE x1
+
+pci:v00001AE8d00000A41*
+ ID_PRODUCT_FROM_DATABASE=microEnable IV-FULL x1
+
+pci:v00001AE8d00000A44*
+ ID_PRODUCT_FROM_DATABASE=microEnable IV-FULL x4
+
+pci:v00001AE8d00000E44*
+ ID_PRODUCT_FROM_DATABASE=microEnable IV-GigE x4
+
+pci:v00001AEC*
+ ID_VENDOR_FROM_DATABASE=Wolfson Microelectronics
+
+pci:v00001AED*
+ ID_VENDOR_FROM_DATABASE=Fusion-io
+
+pci:v00001AEDd00001003*
+ ID_PRODUCT_FROM_DATABASE=ioDimm3 (v1.2)
+
+pci:v00001AEDd00001005*
+ ID_PRODUCT_FROM_DATABASE=ioDimm3
+
+pci:v00001AEDd00001005sv00001014sd000003C3*
+ ID_PRODUCT_FROM_DATABASE=High IOPS SSD PCIe Adapter
+
+pci:v00001AEDd00001005sv0000103Csd0000176F*
+ ID_PRODUCT_FROM_DATABASE=1.28TB MLC PCIe ioDrive Duo
+
+pci:v00001AEDd00001005sv0000103Csd00001770*
+ ID_PRODUCT_FROM_DATABASE=5.2TB MLC PCIe ioDrive Octal
+
+pci:v00001AEDd00001005sv0000103Csd0000178B*
+ ID_PRODUCT_FROM_DATABASE=160GB SLC PCIe ioDrive
+
+pci:v00001AEDd00001005sv0000103Csd0000178C*
+ ID_PRODUCT_FROM_DATABASE=320GB MLC PCIe ioDrive
+
+pci:v00001AEDd00001005sv0000103Csd0000178D*
+ ID_PRODUCT_FROM_DATABASE=320GB SLC PCIe ioDrive Duo
+
+pci:v00001AEDd00001005sv0000103Csd0000178E*
+ ID_PRODUCT_FROM_DATABASE=640GB MLC PCIe ioDrive Duo
+
+pci:v00001AEDd00001006*
+ ID_PRODUCT_FROM_DATABASE=ioXtreme
+
+pci:v00001AEDd00001007*
+ ID_PRODUCT_FROM_DATABASE=ioXtreme Pro
+
+pci:v00001AEDd00001008*
+ ID_PRODUCT_FROM_DATABASE=ioXtreme-2
+
+pci:v00001AEDd00002001*
+ ID_PRODUCT_FROM_DATABASE=ioDrive2
+
+pci:v00001AEE*
+ ID_VENDOR_FROM_DATABASE=Caustic Graphics Inc.
+
+pci:v00001AF4*
+ ID_VENDOR_FROM_DATABASE=Red Hat, Inc
+
+pci:v00001AF4d00001000*
+ ID_PRODUCT_FROM_DATABASE=Virtio network device
+
+pci:v00001AF4d00001001*
+ ID_PRODUCT_FROM_DATABASE=Virtio block device
+
+pci:v00001AF4d00001002*
+ ID_PRODUCT_FROM_DATABASE=Virtio memory balloon
+
+pci:v00001AF4d00001003*
+ ID_PRODUCT_FROM_DATABASE=Virtio console
+
+pci:v00001AF5*
+ ID_VENDOR_FROM_DATABASE=Netezza Corp.
+
+pci:v00001AFA*
+ ID_VENDOR_FROM_DATABASE=J & W Electronics Co., Ltd.
+
+pci:v00001B03*
+ ID_VENDOR_FROM_DATABASE=Magnum Semiconductor, Inc,
+
+pci:v00001B03d00006100*
+ ID_PRODUCT_FROM_DATABASE=DXT/DXTPro Multiformat Broadcast HD/SD Encoder/Decoder/Transcoder
+
+pci:v00001B08*
+ ID_VENDOR_FROM_DATABASE=MSC Vertriebs GmbH
+
+pci:v00001B13*
+ ID_VENDOR_FROM_DATABASE=Jaton Corp
+
+pci:v00001B1A*
+ ID_VENDOR_FROM_DATABASE=K&F Computing Research Co.
+
+pci:v00001B1Ad00000E70*
+ ID_PRODUCT_FROM_DATABASE=GRAPE
+
+pci:v00001B21*
+ ID_VENDOR_FROM_DATABASE=ASMedia Technology Inc.
+
+pci:v00001B21d00000611*
+ ID_PRODUCT_FROM_DATABASE=ASM1061 SATA IDE Controller
+
+pci:v00001B21d00000612*
+ ID_PRODUCT_FROM_DATABASE=ASM1062 Serial ATA Controller
+
+pci:v00001B21d00001042*
+ ID_PRODUCT_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller
+
+pci:v00001B21d00001080*
+ ID_PRODUCT_FROM_DATABASE=ASM1083/1085 PCIe to PCI Bridge
+
+pci:v00001B36*
+ ID_VENDOR_FROM_DATABASE=Red Hat, Inc.
+
+pci:v00001B37*
+ ID_VENDOR_FROM_DATABASE=Signal Processing Devices Sweden AB
+
+pci:v00001B37d00000014*
+ ID_PRODUCT_FROM_DATABASE=ADQ412
+
+pci:v00001B3A*
+ ID_VENDOR_FROM_DATABASE=Westar Display Technologies
+
+pci:v00001B3Ad00007589*
+ ID_PRODUCT_FROM_DATABASE=HRED J2000 - JPEG 2000 Video Codec Device
+
+pci:v00001B3E*
+ ID_VENDOR_FROM_DATABASE=Teradata Corp.
+
+pci:v00001B3Ed00001FA8*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC2SE/X
+
+pci:v00001B3Ed00001FA8sv00001B3Esd000000A3*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC2SX
+
+pci:v00001B3Ed00001FA8sv00001B3Esd000000C3*
+ ID_PRODUCT_FROM_DATABASE=BYNET BIC2SE
+
+pci:v00001B40*
+ ID_VENDOR_FROM_DATABASE=Schooner Information Technology, Inc.
+
+pci:v00001B47*
+ ID_VENDOR_FROM_DATABASE=Numascale AS
+
+pci:v00001B47d00000601*
+ ID_PRODUCT_FROM_DATABASE=NumaChip N601
+
+pci:v00001B47d00000602*
+ ID_PRODUCT_FROM_DATABASE=NumaChip N602
+
+pci:v00001B4B*
+ ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd.
+
+pci:v00001B4Bd00000640*
+ ID_PRODUCT_FROM_DATABASE=88SE9128 SATA III 6Gb/s RAID Controller
+
+pci:v00001B4Bd00009120*
+ ID_PRODUCT_FROM_DATABASE=88SE9120 SATA 6Gb/s Controller
+
+pci:v00001B4Bd00009123*
+ ID_PRODUCT_FROM_DATABASE=88SE9123 PCIe SATA 6.0 Gb/s controller
+
+pci:v00001B4Bd00009125*
+ ID_PRODUCT_FROM_DATABASE=88SE9125 PCIe SATA 6.0 Gb/s controller
+
+pci:v00001B4Bd00009128*
+ ID_PRODUCT_FROM_DATABASE=88SE9128 PCIe SATA 6 Gb/s RAID controller
+
+pci:v00001B4Bd00009130*
+ ID_PRODUCT_FROM_DATABASE=88SE9128 PCIe SATA 6 Gb/s RAID controller with HyperDuo
+
+pci:v00001B4Bd00009130sv00001043sd00008438*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00001B4Bd00009172*
+ ID_PRODUCT_FROM_DATABASE=88SE9172 SATA 6Gb/s Controller
+
+pci:v00001B4Bd0000917A*
+ ID_PRODUCT_FROM_DATABASE=88SE9172 SATA III 6Gb/s RAID Controller
+
+pci:v00001B4Bd00009192*
+ ID_PRODUCT_FROM_DATABASE=88SE9172 SATA III 6Gb/s RAID Controller
+
+pci:v00001B4Bd000091A0*
+ ID_PRODUCT_FROM_DATABASE=88SE91A0 SATA 6Gb/s Controller
+
+pci:v00001B4Bd000091A4*
+ ID_PRODUCT_FROM_DATABASE=88SE9128 IDE Controller
+
+pci:v00001B4Bd00009230*
+ ID_PRODUCT_FROM_DATABASE=88SE9230 PCIe SATA 6Gb/s Controller
+
+pci:v00001B4Bd00009480*
+ ID_PRODUCT_FROM_DATABASE=88SE9480 SAS/SATA 6Gb/s RAID controller
+
+pci:v00001B55*
+ ID_VENDOR_FROM_DATABASE=NetUP Inc.
+
+pci:v00001B55d00002A2C*
+ ID_PRODUCT_FROM_DATABASE=Dual DVB-S2-CI card
+
+pci:v00001B55d0000E2E4*
+ ID_PRODUCT_FROM_DATABASE=Dual DVB-T/C-CI RF card
+
+pci:v00001B55d0000E5F4*
+ ID_PRODUCT_FROM_DATABASE=MPEG2 and H264 Encoder-Transcoder
+
+pci:v00001B55d0000F1C4*
+ ID_PRODUCT_FROM_DATABASE=Dual ASI-RX/TX-CI card
+
+pci:v00001B6F*
+ ID_VENDOR_FROM_DATABASE=Etron Technology, Inc.
+
+pci:v00001B6Fd00007023*
+ ID_PRODUCT_FROM_DATABASE=EJ168 USB 3.0 Host Controller
+
+pci:v00001B6Fd00007052*
+ ID_PRODUCT_FROM_DATABASE=EJ188/EJ198 USB 3.0 Host Controller
+
+pci:v00001B73*
+ ID_VENDOR_FROM_DATABASE=Fresco Logic
+
+pci:v00001B73d00001000*
+ ID_PRODUCT_FROM_DATABASE=FL1000G USB 3.0 Host Controller
+
+pci:v00001B73d00001000sv00001D5Csd00001000*
+ ID_PRODUCT_FROM_DATABASE=Anker USB 3.0 Express Card
+
+pci:v00001B73d00001009*
+ ID_PRODUCT_FROM_DATABASE=FL1009 USB 3.0 Host Controller
+
+pci:v00001B74*
+ ID_VENDOR_FROM_DATABASE=OpenVox Communication Co. Ltd.
+
+pci:v00001B74d00000115*
+ ID_PRODUCT_FROM_DATABASE=D115P/D115E Single-port E1/T1 card
+
+pci:v00001B74d0000D130*
+ ID_PRODUCT_FROM_DATABASE=D130P/D130E Single-port E1/T1 card (3rd GEN)
+
+pci:v00001B74d0000D210*
+ ID_PRODUCT_FROM_DATABASE=D210P/D210E Dual-port E1/T1 card(2nd generation)
+
+pci:v00001B74d0000D230*
+ ID_PRODUCT_FROM_DATABASE=D230 Dual-port E1/T1 card (2nd generation)
+
+pci:v00001B74d0000D410*
+ ID_PRODUCT_FROM_DATABASE=D410/430 Quad-port E1/T1 card
+
+pci:v00001B74d0000D430*
+ ID_PRODUCT_FROM_DATABASE=D410/430 Quad-port E1/T1 card
+
+pci:v00001B85*
+ ID_VENDOR_FROM_DATABASE=OCZ Technology Group, Inc.
+
+pci:v00001B85d00001041*
+ ID_PRODUCT_FROM_DATABASE=RevoDrive 3 X2 PCI-Express SSD 240 GB (Marvell Controller)
+
+pci:v00001B96*
+ ID_VENDOR_FROM_DATABASE=Western Digital
+
+pci:v00001B9A*
+ ID_VENDOR_FROM_DATABASE=XAVi Technologies Corp.
+
+pci:v00001BAD*
+ ID_VENDOR_FROM_DATABASE=ReFLEX CES
+
+pci:v00001BB0*
+ ID_VENDOR_FROM_DATABASE=SimpliVity Corporation
+
+pci:v00001BB0d00000002*
+ ID_PRODUCT_FROM_DATABASE=OmniCube Accelerator OA-3000
+
+pci:v00001BB3*
+ ID_VENDOR_FROM_DATABASE=Bluecherry
+
+pci:v00001BB3d00004304*
+ ID_PRODUCT_FROM_DATABASE=BC-04120A MPEG4 4 port video encoder / decoder
+
+pci:v00001BB3d00004309*
+ ID_PRODUCT_FROM_DATABASE=BC-08240A MPEG4 4 port video encoder / decoder
+
+pci:v00001BB3d00004310*
+ ID_PRODUCT_FROM_DATABASE=BC-16480A MPEG4 16 port video encoder / decoder
+
+pci:v00001BB3d00004E04*
+ ID_PRODUCT_FROM_DATABASE=BC-04120A 4 port MPEG4 video encoder / decoder
+
+pci:v00001BB3d00004E09*
+ ID_PRODUCT_FROM_DATABASE=BC-08240A 8 port MPEG4 video encoder / decoder
+
+pci:v00001BB3d00004E10*
+ ID_PRODUCT_FROM_DATABASE=BC-16480A 16 port MPEG4 video encoder / decoder
+
+pci:v00001BB3d00005304*
+ ID_PRODUCT_FROM_DATABASE=BC-H04120A 4 port H.264 video and audio encoder / decoder
+
+pci:v00001BB3d00005308*
+ ID_PRODUCT_FROM_DATABASE=BC-H08240A 8 port H.264 video and audio encoder / decoder
+
+pci:v00001BB3d00005310*
+ ID_PRODUCT_FROM_DATABASE=BC-H16480A 16 port H.264 video and audio encoder / decoder
+
+pci:v00001BB5*
+ ID_VENDOR_FROM_DATABASE=Quantenna Communications, Inc.
+
+pci:v00001BBF*
+ ID_VENDOR_FROM_DATABASE=Maxeler Technologies Ltd.
+
+pci:v00001BBFd00000003*
+ ID_PRODUCT_FROM_DATABASE=MAX3
+
+pci:v00001BBFd00000004*
+ ID_PRODUCT_FROM_DATABASE=MAX4
+
+pci:v00001BF4*
+ ID_VENDOR_FROM_DATABASE=VTI Instruments Corporation
+
+pci:v00001C1C*
+ ID_VENDOR_FROM_DATABASE=Symphony
+
+pci:v00001C1Cd00000001*
+ ID_PRODUCT_FROM_DATABASE=82C101
+
+pci:v00001C2C*
+ ID_VENDOR_FROM_DATABASE=Fiberblaze
+
+pci:v00001C32*
+ ID_VENDOR_FROM_DATABASE=Highland Technology, Inc.
+
+pci:v00001C3B*
+ ID_VENDOR_FROM_DATABASE=Accensus, LLC
+
+pci:v00001C3Bd00000200*
+ ID_PRODUCT_FROM_DATABASE=Telas2
+
+pci:v00001C44*
+ ID_VENDOR_FROM_DATABASE=Enmotus Inc
+
+pci:v00001C44d00008000*
+ ID_PRODUCT_FROM_DATABASE=8000 Storage IO Controller
+
+pci:v00001C7F*
+ ID_VENDOR_FROM_DATABASE=Elektrobit Austria GmbH
+
+pci:v00001C7Fd00005100*
+ ID_PRODUCT_FROM_DATABASE=EB5100
+
+pci:v00001C8A*
+ ID_VENDOR_FROM_DATABASE=TSF5 Corporation
+
+pci:v00001D44*
+ ID_VENDOR_FROM_DATABASE=DPT
+
+pci:v00001D44d0000A400*
+ ID_PRODUCT_FROM_DATABASE=PM2x24/PM3224
+
+pci:v00001D5C*
+ ID_VENDOR_FROM_DATABASE=Fantasia Trading LLC
+
+pci:v00001DE1*
+ ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd.
+
+pci:v00001DE1d00000391*
+ ID_PRODUCT_FROM_DATABASE=TRM-S1040
+
+pci:v00001DE1d00002020*
+ ID_PRODUCT_FROM_DATABASE=DC-390
+
+pci:v00001DE1d0000690C*
+ ID_PRODUCT_FROM_DATABASE=690c
+
+pci:v00001DE1d0000DC29*
+ ID_PRODUCT_FROM_DATABASE=DC290
+
+pci:v00001FC0*
+ ID_VENDOR_FROM_DATABASE=Ascom (Finland) Oy
+
+pci:v00001FC0d00000300*
+ ID_PRODUCT_FROM_DATABASE=E2200 Dual E1/Rawpipe Card
+
+pci:v00001FC0d00000301*
+ ID_PRODUCT_FROM_DATABASE=C5400 SHDSL/E1 Card
+
+pci:v00001FC1*
+ ID_VENDOR_FROM_DATABASE=QLogic, Corp.
+
+pci:v00001FC1d0000000D*
+ ID_PRODUCT_FROM_DATABASE=IBA6110 InfiniBand HCA
+
+pci:v00001FC1d00000010*
+ ID_PRODUCT_FROM_DATABASE=IBA6120 InfiniBand HCA
+
+pci:v00001FC9*
+ ID_VENDOR_FROM_DATABASE=Tehuti Networks Ltd.
+
+pci:v00001FC9d00003009*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE SmartNIC
+
+pci:v00001FC9d00003010*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE SmartNIC
+
+pci:v00001FC9d00003010sv00000000sd00003002*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port XFP SmartNIC
+
+pci:v00001FC9d00003010sv00000000sd00003004*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC
+
+pci:v00001FC9d00003010sv00000000sd00003008*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port CX4 SmartNIC
+
+pci:v00001FC9d00003014*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE SmartNIC 2-Port
+
+pci:v00001FC9d00003014sv00000000sd00003003*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port XFP Low Profile SmartNIC
+
+pci:v00001FC9d00003014sv00000000sd00003005*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC
+
+pci:v00001FC9d00003014sv00000000sd00003014*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC
+
+pci:v00001FC9d00003110*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port SmartNIC
+
+pci:v00001FC9d00003110sv00000000sd00003004*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC
+
+pci:v00001FC9d00003114*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC
+
+pci:v00001FC9d00003114sv00000000sd00003005*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC
+
+pci:v00001FC9d00003114sv00000000sd00003011*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+/CX4 Low Profile SmartNIC
+
+pci:v00001FC9d00003114sv00000000sd00003012*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4/SFP+ Low Profile SmartNIC
+
+pci:v00001FC9d00003114sv00000000sd00003014*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC
+
+pci:v00001FC9d00003310*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE SFP+ Single Port SmartNIC
+
+pci:v00001FC9d00003310sv00000000sd00003004*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC
+
+pci:v00001FC9d00003314*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC
+
+pci:v00001FC9d00003314sv00000000sd00003005*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC
+
+pci:v00001FC9d00003314sv00000000sd00003011*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+/CX4 Low Profile SmartNIC
+
+pci:v00001FC9d00003314sv00000000sd00003012*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4/SFP+ Low Profile SmartNIC
+
+pci:v00001FC9d00003314sv00000000sd00003014*
+ ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC
+
+pci:v00001FCE*
+ ID_VENDOR_FROM_DATABASE=Cognio Inc.
+
+pci:v00001FCEd00000001*
+ ID_PRODUCT_FROM_DATABASE=Spectrum Analyzer PC Card (SAgE)
+
+pci:v00001FD4*
+ ID_VENDOR_FROM_DATABASE=SUNIX Co., Ltd.
+
+pci:v00001FD4d00000001*
+ ID_PRODUCT_FROM_DATABASE=Matrix multiport serial adapter
+
+pci:v00001FD4d00001999*
+ ID_PRODUCT_FROM_DATABASE=Multiport serial controller
+
+pci:v00002000*
+ ID_VENDOR_FROM_DATABASE=Smart Link Ltd.
+
+pci:v00002000d00002800*
+ ID_PRODUCT_FROM_DATABASE=SmartPCI2800 V.92 PCI Soft DFT
+
+pci:v00002001*
+ ID_VENDOR_FROM_DATABASE=Temporal Research Ltd
+
+pci:v00002003*
+ ID_VENDOR_FROM_DATABASE=Smart Link Ltd.
+
+pci:v00002003d00008800*
+ ID_PRODUCT_FROM_DATABASE=LM-I56N
+
+pci:v00002004*
+ ID_VENDOR_FROM_DATABASE=Smart Link Ltd.
+
+pci:v000020F4*
+ ID_VENDOR_FROM_DATABASE=TRENDnet
+
+pci:v00002116*
+ ID_VENDOR_FROM_DATABASE=ZyDAS Technology Corp.
+
+pci:v000021C3*
+ ID_VENDOR_FROM_DATABASE=21st Century Computer Corp.
+
+pci:v000022B8*
+ ID_VENDOR_FROM_DATABASE=Motorola, Inc.
+
+pci:v00002304*
+ ID_VENDOR_FROM_DATABASE=Colorgraphic Communications Corp.
+
+pci:v00002348*
+ ID_VENDOR_FROM_DATABASE=Racore
+
+pci:v00002348d00002010*
+ ID_PRODUCT_FROM_DATABASE=8142 100VG/AnyLAN
+
+pci:v00002646*
+ ID_VENDOR_FROM_DATABASE=Kingston Technologies
+
+pci:v0000270B*
+ ID_VENDOR_FROM_DATABASE=Xantel Corporation
+
+pci:v0000270F*
+ ID_VENDOR_FROM_DATABASE=Chaintech Computer Co. Ltd
+
+pci:v00002711*
+ ID_VENDOR_FROM_DATABASE=AVID Technology Inc.
+
+pci:v000029B4*
+ ID_VENDOR_FROM_DATABASE=82q35 Express MEI Controller
+
+pci:v00002A15*
+ ID_VENDOR_FROM_DATABASE=3D Vision(???)
+
+pci:v00003000*
+ ID_VENDOR_FROM_DATABASE=Hansol Electronics Inc.
+
+pci:v00003020*
+ ID_VENDOR_FROM_DATABASE=LSI SAS2 9211-8i
+
+pci:v00003080*
+ ID_VENDOR_FROM_DATABASE=LSI SAS2 9200-8e
+
+pci:v00003142*
+ ID_VENDOR_FROM_DATABASE=Post Impression Systems.
+
+pci:v00003388*
+ ID_VENDOR_FROM_DATABASE=Hint Corp
+
+pci:v00003388d00000013*
+ ID_PRODUCT_FROM_DATABASE=HiNT HC4 PCI to ISDN bridge, Multimedia audio controller
+
+pci:v00003388d00000014*
+ ID_PRODUCT_FROM_DATABASE=HiNT HC4 PCI to ISDN bridge, Network controller
+
+pci:v00003388d00000020*
+ ID_PRODUCT_FROM_DATABASE=HB6 Universal PCI-PCI bridge (transparent mode)
+
+pci:v00003388d00000021*
+ ID_PRODUCT_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode)
+
+pci:v00003388d00000021sv00001775sd0000C200*
+ ID_PRODUCT_FROM_DATABASE=C2K CompactPCI interface bridge
+
+pci:v00003388d00000021sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00003388d00000021sv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v00003388d00000021sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00003388d00000021sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 mainboard
+
+pci:v00003388d00000021sv00004C53sd000010A0*
+ ID_PRODUCT_FROM_DATABASE=CA3/CR3 mainboard
+
+pci:v00003388d00000021sv00004C53sd00003010*
+ ID_PRODUCT_FROM_DATABASE=PPCI mezzanine (32-bit PMC)
+
+pci:v00003388d00000021sv00004C53sd00003011*
+ ID_PRODUCT_FROM_DATABASE=PPCI mezzanine (64-bit PMC)
+
+pci:v00003388d00000021sv00004C53sd00004000*
+ ID_PRODUCT_FROM_DATABASE=PMCCARR1 carrier board
+
+pci:v00003388d00000022*
+ ID_PRODUCT_FROM_DATABASE=HiNT HB4 PCI-PCI Bridge (PCI6150)
+
+pci:v00003388d00000026*
+ ID_PRODUCT_FROM_DATABASE=HB2 PCI-PCI Bridge
+
+pci:v00003388d00001018*
+ ID_PRODUCT_FROM_DATABASE=Audiotrak INCA88
+
+pci:v00003388d00001019*
+ ID_PRODUCT_FROM_DATABASE=Miditrak 2120
+
+pci:v00003388d0000101A*
+ ID_PRODUCT_FROM_DATABASE=E.Band [AudioTrak Inca88]
+
+pci:v00003388d0000101B*
+ ID_PRODUCT_FROM_DATABASE=E.Band [AudioTrak Inca88]
+
+pci:v00003388d00008011*
+ ID_PRODUCT_FROM_DATABASE=VXPro II Chipset
+
+pci:v00003388d00008011sv00003388sd00008011*
+ ID_PRODUCT_FROM_DATABASE=VXPro II Chipset CPU to PCI Bridge
+
+pci:v00003388d00008012*
+ ID_PRODUCT_FROM_DATABASE=VXPro II Chipset
+
+pci:v00003388d00008012sv00003388sd00008012*
+ ID_PRODUCT_FROM_DATABASE=VXPro II Chipset PCI to ISA Bridge
+
+pci:v00003388d00008013*
+ ID_PRODUCT_FROM_DATABASE=VXPro II IDE
+
+pci:v00003388d00008013sv00003388sd00008013*
+ ID_PRODUCT_FROM_DATABASE=VXPro II Chipset EIDE Controller
+
+pci:v00003388d0000A103*
+ ID_PRODUCT_FROM_DATABASE=Blackmagic Design DeckLink HD Pro
+
+pci:v00003411*
+ ID_VENDOR_FROM_DATABASE=Quantum Designs (H.K.) Inc
+
+pci:v00003442*
+ ID_VENDOR_FROM_DATABASE=Bihl+Wiedemann GmbH
+
+pci:v00003442d00001783*
+ ID_PRODUCT_FROM_DATABASE=AS-i 3.0 cPCI Master
+
+pci:v00003442d00001922*
+ ID_PRODUCT_FROM_DATABASE=AS-i 3.0 PCI Master
+
+pci:v00003475*
+ ID_VENDOR_FROM_DATABASE=Arastra Inc.
+
+pci:v00003513*
+ ID_VENDOR_FROM_DATABASE=ARCOM Control Systems Ltd
+
+pci:v000037D9*
+ ID_VENDOR_FROM_DATABASE=ITD Firm ltd.
+
+pci:v000037D9d00001138*
+ ID_PRODUCT_FROM_DATABASE=SCHD-PH-8 Phase detector
+
+pci:v00003842*
+ ID_VENDOR_FROM_DATABASE=eVga.com. Corp.
+
+pci:v000038EF*
+ ID_VENDOR_FROM_DATABASE=4Links
+
+pci:v00003D3D*
+ ID_VENDOR_FROM_DATABASE=3DLabs
+
+pci:v00003D3Dd00000001*
+ ID_PRODUCT_FROM_DATABASE=GLINT 300SX
+
+pci:v00003D3Dd00000002*
+ ID_PRODUCT_FROM_DATABASE=GLINT 500TX
+
+pci:v00003D3Dd00000002sv00000000sd00000000*
+ ID_PRODUCT_FROM_DATABASE=GLoria L
+
+pci:v00003D3Dd00000003*
+ ID_PRODUCT_FROM_DATABASE=GLINT Delta
+
+pci:v00003D3Dd00000003sv00000000sd00000000*
+ ID_PRODUCT_FROM_DATABASE=GLoria XL
+
+pci:v00003D3Dd00000004*
+ ID_PRODUCT_FROM_DATABASE=Permedia
+
+pci:v00003D3Dd00000005*
+ ID_PRODUCT_FROM_DATABASE=Permedia
+
+pci:v00003D3Dd00000006*
+ ID_PRODUCT_FROM_DATABASE=GLINT MX
+
+pci:v00003D3Dd00000006sv00000000sd00000000*
+ ID_PRODUCT_FROM_DATABASE=GLoria XL
+
+pci:v00003D3Dd00000006sv00001048sd00000A42*
+ ID_PRODUCT_FROM_DATABASE=GLoria XXL
+
+pci:v00003D3Dd00000007*
+ ID_PRODUCT_FROM_DATABASE=3D Extreme
+
+pci:v00003D3Dd00000008*
+ ID_PRODUCT_FROM_DATABASE=GLINT Gamma G1
+
+pci:v00003D3Dd00000008sv00001048sd00000A42*
+ ID_PRODUCT_FROM_DATABASE=GLoria XXL
+
+pci:v00003D3Dd00000009*
+ ID_PRODUCT_FROM_DATABASE=Permedia II 2D+3D
+
+pci:v00003D3Dd00000009sv00001040sd00000011*
+ ID_PRODUCT_FROM_DATABASE=AccelStar II
+
+pci:v00003D3Dd00000009sv00001048sd00000A42*
+ ID_PRODUCT_FROM_DATABASE=GLoria XXL
+
+pci:v00003D3Dd00000009sv000013E9sd00001000*
+ ID_PRODUCT_FROM_DATABASE=6221L-4U
+
+pci:v00003D3Dd00000009sv00003D3Dsd00000100*
+ ID_PRODUCT_FROM_DATABASE=AccelStar II 3D Accelerator
+
+pci:v00003D3Dd00000009sv00003D3Dsd00000111*
+ ID_PRODUCT_FROM_DATABASE=Permedia 3:16
+
+pci:v00003D3Dd00000009sv00003D3Dsd00000114*
+ ID_PRODUCT_FROM_DATABASE=Santa Ana
+
+pci:v00003D3Dd00000009sv00003D3Dsd00000116*
+ ID_PRODUCT_FROM_DATABASE=Oxygen GVX1
+
+pci:v00003D3Dd00000009sv00003D3Dsd00000119*
+ ID_PRODUCT_FROM_DATABASE=Scirocco
+
+pci:v00003D3Dd00000009sv00003D3Dsd00000120*
+ ID_PRODUCT_FROM_DATABASE=Santa Ana PCL
+
+pci:v00003D3Dd00000009sv00003D3Dsd00000125*
+ ID_PRODUCT_FROM_DATABASE=Oxygen VX1
+
+pci:v00003D3Dd00000009sv00003D3Dsd00000127*
+ ID_PRODUCT_FROM_DATABASE=Permedia3 Create!
+
+pci:v00003D3Dd0000000A*
+ ID_PRODUCT_FROM_DATABASE=GLINT R3
+
+pci:v00003D3Dd0000000Asv00003D3Dsd00000121*
+ ID_PRODUCT_FROM_DATABASE=Oxygen VX1
+
+pci:v00003D3Dd0000000C*
+ ID_PRODUCT_FROM_DATABASE=GLINT R3 [Oxygen VX1]
+
+pci:v00003D3Dd0000000Csv00003D3Dsd00000144*
+ ID_PRODUCT_FROM_DATABASE=Oxygen VX1-4X AGP [Permedia 4]
+
+pci:v00003D3Dd0000000D*
+ ID_PRODUCT_FROM_DATABASE=GLint R4 rev A
+
+pci:v00003D3Dd0000000E*
+ ID_PRODUCT_FROM_DATABASE=GLINT Gamma G2
+
+pci:v00003D3Dd00000011*
+ ID_PRODUCT_FROM_DATABASE=GLint R4 rev B
+
+pci:v00003D3Dd00000012*
+ ID_PRODUCT_FROM_DATABASE=GLint R5 rev A
+
+pci:v00003D3Dd00000013*
+ ID_PRODUCT_FROM_DATABASE=GLint R5 rev B
+
+pci:v00003D3Dd00000020*
+ ID_PRODUCT_FROM_DATABASE=VP10 visual processor
+
+pci:v00003D3Dd00000022*
+ ID_PRODUCT_FROM_DATABASE=VP10 visual processor
+
+pci:v00003D3Dd00000024*
+ ID_PRODUCT_FROM_DATABASE=VP9 visual processor
+
+pci:v00003D3Dd0000002C*
+ ID_PRODUCT_FROM_DATABASE=Wildcat Realizm 100/200
+
+pci:v00003D3Dd00000030*
+ ID_PRODUCT_FROM_DATABASE=Wildcat Realizm 800
+
+pci:v00003D3Dd00000032*
+ ID_PRODUCT_FROM_DATABASE=Wildcat Realizm 500
+
+pci:v00003D3Dd00000100*
+ ID_PRODUCT_FROM_DATABASE=Permedia II 2D+3D
+
+pci:v00003D3Dd000007A1*
+ ID_PRODUCT_FROM_DATABASE=Wildcat III 6210
+
+pci:v00003D3Dd000007A2*
+ ID_PRODUCT_FROM_DATABASE=Sun XVR-500 Graphics Accelerator
+
+pci:v00003D3Dd000007A3*
+ ID_PRODUCT_FROM_DATABASE=Wildcat IV 7210
+
+pci:v00003D3Dd00001004*
+ ID_PRODUCT_FROM_DATABASE=Permedia
+
+pci:v00003D3Dd00003D04*
+ ID_PRODUCT_FROM_DATABASE=Permedia
+
+pci:v00003D3Dd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=Glint VGA
+
+pci:v00004005*
+ ID_VENDOR_FROM_DATABASE=Avance Logic Inc.
+
+pci:v00004005d00000300*
+ ID_PRODUCT_FROM_DATABASE=ALS300 PCI Audio Device
+
+pci:v00004005d00000308*
+ ID_PRODUCT_FROM_DATABASE=ALS300+ PCI Audio Device
+
+pci:v00004005d00000309*
+ ID_PRODUCT_FROM_DATABASE=PCI Input Controller
+
+pci:v00004005d00001064*
+ ID_PRODUCT_FROM_DATABASE=ALG-2064
+
+pci:v00004005d00002064*
+ ID_PRODUCT_FROM_DATABASE=ALG-2064i
+
+pci:v00004005d00002128*
+ ID_PRODUCT_FROM_DATABASE=ALG-2364A GUI Accelerator
+
+pci:v00004005d00002301*
+ ID_PRODUCT_FROM_DATABASE=ALG-2301
+
+pci:v00004005d00002302*
+ ID_PRODUCT_FROM_DATABASE=ALG-2302
+
+pci:v00004005d00002303*
+ ID_PRODUCT_FROM_DATABASE=AVG-2302 GUI Accelerator
+
+pci:v00004005d00002364*
+ ID_PRODUCT_FROM_DATABASE=ALG-2364A
+
+pci:v00004005d00002464*
+ ID_PRODUCT_FROM_DATABASE=ALG-2464
+
+pci:v00004005d00002501*
+ ID_PRODUCT_FROM_DATABASE=ALG-2564A/25128A
+
+pci:v00004005d00004000*
+ ID_PRODUCT_FROM_DATABASE=ALS4000 Audio Chipset
+
+pci:v00004005d00004000sv00004005sd00004000*
+ ID_PRODUCT_FROM_DATABASE=ALS4000 Audio Chipset
+
+pci:v00004005d00004710*
+ ID_PRODUCT_FROM_DATABASE=ALC200/200P
+
+pci:v00004033*
+ ID_VENDOR_FROM_DATABASE=Addtron Technology Co, Inc.
+
+pci:v00004033d00001360*
+ ID_PRODUCT_FROM_DATABASE=RTL8139 Ethernet
+
+pci:v00004040*
+ ID_VENDOR_FROM_DATABASE=NetXen Incorporated
+
+pci:v00004040d00000001*
+ ID_PRODUCT_FROM_DATABASE=NXB-10GXSR 10-Gigabit Ethernet PCIe Adapter with SR-XFP optical interface
+
+pci:v00004040d00000001sv0000103Csd00007047*
+ ID_PRODUCT_FROM_DATABASE=NC510F PCIe 10-Gigabit Server Adapter
+
+pci:v00004040d00000002*
+ ID_PRODUCT_FROM_DATABASE=NXB-10GCX4 10-Gigabit Ethernet PCIe Adapter with CX4 copper interface
+
+pci:v00004040d00000002sv0000103Csd00007048*
+ ID_PRODUCT_FROM_DATABASE=NC510c PCIe 10-Gigabit Server Adapter
+
+pci:v00004040d00000003*
+ ID_PRODUCT_FROM_DATABASE=NXB-4GCU Quad Gigabit Ethernet PCIe Adapter with 1000-BASE-T interface
+
+pci:v00004040d00000004*
+ ID_PRODUCT_FROM_DATABASE=BladeCenter-H 10-Gigabit Ethernet High Speed Daughter Card
+
+pci:v00004040d00000005*
+ ID_PRODUCT_FROM_DATABASE=NetXen Dual Port 10GbE Multifunction Adapter for c-Class
+
+pci:v00004040d00000005sv0000103Csd0000170E*
+ ID_PRODUCT_FROM_DATABASE=NC512m Dual Port 10GbE Multifunction BL-C Adapter
+
+pci:v00004040d00000024*
+ ID_PRODUCT_FROM_DATABASE=XG Mgmt
+
+pci:v00004040d00000025*
+ ID_PRODUCT_FROM_DATABASE=XG Mgmt
+
+pci:v00004040d00000100*
+ ID_PRODUCT_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter
+
+pci:v00004040d00000100sv0000103Csd0000171B*
+ ID_PRODUCT_FROM_DATABASE=NC522m Dual Port 10GbE Multifunction BL-c Adapter
+
+pci:v00004040d00000100sv0000103Csd00001740*
+ ID_PRODUCT_FROM_DATABASE=NC375T PCI Express Quad Port Gigabit Server Adapter
+
+pci:v00004040d00000100sv0000103Csd00003251*
+ ID_PRODUCT_FROM_DATABASE=NC375i 1G w/NC524SFP 10G Module
+
+pci:v00004040d00000100sv0000103Csd0000705A*
+ ID_PRODUCT_FROM_DATABASE=NC375i Integrated Quad Port Multifunction Gigabit Server Adapter
+
+pci:v00004040d00000100sv0000103Csd0000705B*
+ ID_PRODUCT_FROM_DATABASE=NC522SFP Dual Port 10GbE Server Adapter
+
+pci:v00004040d00000100sv0000152Dsd0000896B*
+ ID_PRODUCT_FROM_DATABASE=TG20 Dual Port 10GbE Server/Storage Adapter
+
+pci:v00004040d00000100sv00004040sd00000124*
+ ID_PRODUCT_FROM_DATABASE=NX3031 Quad Port Gigabit Server Adapter
+
+pci:v00004040d00000100sv00004040sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Dual Port SFP+ 10GbE Server Adapter
+
+pci:v00004143*
+ ID_VENDOR_FROM_DATABASE=Digital Equipment Corp
+
+pci:v00004144*
+ ID_VENDOR_FROM_DATABASE=Alpha Data
+
+pci:v00004144d00000044*
+ ID_PRODUCT_FROM_DATABASE=ADM-XRCIIPro
+
+pci:v00004150*
+ ID_VENDOR_FROM_DATABASE=ONA Electroerosion
+
+pci:v00004150d00000001*
+ ID_PRODUCT_FROM_DATABASE=PCI32TLITE FILSTRUP1 PCI to VME Bridge Controller
+
+pci:v00004150d00000006*
+ ID_PRODUCT_FROM_DATABASE=PCI32TLITE UART 16550 Opencores
+
+pci:v00004150d00000007*
+ ID_PRODUCT_FROM_DATABASE=PCI32TLITE CAN Controller Opencores
+
+pci:v0000415A*
+ ID_VENDOR_FROM_DATABASE=Auzentech, Inc.
+
+pci:v0000416C*
+ ID_VENDOR_FROM_DATABASE=Aladdin Knowledge Systems
+
+pci:v0000416Cd00000100*
+ ID_PRODUCT_FROM_DATABASE=AladdinCARD
+
+pci:v0000416Cd00000200*
+ ID_PRODUCT_FROM_DATABASE=CPC
+
+pci:v00004321*
+ ID_VENDOR_FROM_DATABASE=Tata Power Strategic Electronics Division
+
+pci:v0000434E*
+ ID_VENDOR_FROM_DATABASE=CAST Navigation LLC
+
+pci:v00004444*
+ ID_VENDOR_FROM_DATABASE=Internext Compression Inc
+
+pci:v00004444d00000016*
+ ID_PRODUCT_FROM_DATABASE=iTVC16 (CX23416) Video Decoder
+
+pci:v00004444d00000016sv00000070sd00000003*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 250
+
+pci:v00004444d00000016sv00000070sd00000009*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 150
+
+pci:v00004444d00000016sv00000070sd00000801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 150
+
+pci:v00004444d00000016sv00000070sd00000807*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 150
+
+pci:v00004444d00000016sv00000070sd00004001*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 250
+
+pci:v00004444d00000016sv00000070sd00004009*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 250
+
+pci:v00004444d00000016sv00000070sd00004801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 250
+
+pci:v00004444d00000016sv00000070sd00004803*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 250
+
+pci:v00004444d00000016sv00000070sd00008003*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 150
+
+pci:v00004444d00000016sv00000070sd00008801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 150
+
+pci:v00004444d00000016sv00000070sd0000C801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 150
+
+pci:v00004444d00000016sv00000070sd0000E807*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 500 (1st unit)
+
+pci:v00004444d00000016sv00000070sd0000E817*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 500 (2nd unit)
+
+pci:v00004444d00000016sv00000070sd0000FF92*
+ ID_PRODUCT_FROM_DATABASE=WiNTV PVR-550
+
+pci:v00004444d00000016sv00000270sd00000801*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR 150
+
+pci:v00004444d00000016sv0000104Dsd0000013D*
+ ID_PRODUCT_FROM_DATABASE=ENX-26 TV Encoder
+
+pci:v00004444d00000016sv000010FCsd0000D038*
+ ID_PRODUCT_FROM_DATABASE=GV-MVP/RX2W (1st unit)
+
+pci:v00004444d00000016sv000010FCsd0000D039*
+ ID_PRODUCT_FROM_DATABASE=GV-MVP/RX2W (2nd unit)
+
+pci:v00004444d00000016sv000012ABsd0000FFF3*
+ ID_PRODUCT_FROM_DATABASE=MPG600
+
+pci:v00004444d00000016sv000012ABsd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=MPG600
+
+pci:v00004444d00000016sv00001461sd0000C00A*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Philips FQ1216MK3 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C00B*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Philips FM1216MK3 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC, JAPAN version, Philips FI1286MK2 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C010*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC, Philips FI1236MK3 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C011*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC+FM, Philips FM1236MK3 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C018*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC, Philips FQ1236MK5 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C019*
+ ID_PRODUCT_FROM_DATABASE=UltraTV 1500 MCE, a.k.a. M113 PCI Analog TV (NTSC+FM, Philips FQ1236MK5 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C01A*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Philips FQ1216MK5 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C01B*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Philips FM1216MK5 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C030*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC-J, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C031*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC-J+FM, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C032*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C033*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C034*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C035*
+ ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC+FM, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C03F*
+ ID_PRODUCT_FROM_DATABASE=C115 PCI video capture card (no tuner)
+
+pci:v00004444d00000016sv00001461sd0000C136*
+ ID_PRODUCT_FROM_DATABASE=M104 mini-PCI Analog TV
+
+pci:v00004444d00000016sv00001461sd0000C20A*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Philips FQ1216MK3 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C218*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC, Philips FQ1236MK5 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C219*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC+FM, Philips FQ1236MK5 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C21A*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Philips FQ1216MK5 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C21B*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM+FM, Philips FM1216MK5 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C230*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC-J, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C231*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC-J+FM, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C232*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C233*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM+FM, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C234*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C235*
+ ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC+FM, Partsnic tuner)
+
+pci:v00004444d00000016sv00001461sd0000C337*
+ ID_PRODUCT_FROM_DATABASE=E106 AVerMedia AVerTV Video Capture
+
+pci:v00004444d00000016sv00001461sd0000C439*
+ ID_PRODUCT_FROM_DATABASE=M116 AVerMedia AVerTV MCE 116 Plus (NTSC/PAL/SECAM+FM+REMOTE, Xceive 2028 tuner)
+
+pci:v00004444d00000016sv00001461sd0000C5FF*
+ ID_PRODUCT_FROM_DATABASE=C755 AVerTV Video Capture card (no tuner)
+
+pci:v00004444d00000016sv00001461sd0000C6FF*
+ ID_PRODUCT_FROM_DATABASE=C115 PCI video capture card (no tuner)
+
+pci:v00004444d00000016sv00001461sd0000C739*
+ ID_PRODUCT_FROM_DATABASE=M785 AVerMedia PCI Analog TV (NTSC/PAL/SECAM+FM, Xceive 2028 tuner)
+
+pci:v00004444d00000016sv00009005sd00000092*
+ ID_PRODUCT_FROM_DATABASE=VideOh! AVC-2010
+
+pci:v00004444d00000016sv00009005sd00000093*
+ ID_PRODUCT_FROM_DATABASE=VideOh! AVC-2410
+
+pci:v00004444d00000803*
+ ID_PRODUCT_FROM_DATABASE=iTVC15 (CX23415) Video Decoder
+
+pci:v00004444d00000803sv00000070sd00004000*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-350
+
+pci:v00004444d00000803sv00000070sd00004001*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-250
+
+pci:v00004444d00000803sv00000070sd00004800*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR-350 (V1)
+
+pci:v00004444d00000803sv000012ABsd00000000*
+ ID_PRODUCT_FROM_DATABASE=MPG160
+
+pci:v00004444d00000803sv00001461sd0000A3CE*
+ ID_PRODUCT_FROM_DATABASE=M179
+
+pci:v00004444d00000803sv00001461sd0000A3CF*
+ ID_PRODUCT_FROM_DATABASE=M179
+
+pci:v00004468*
+ ID_VENDOR_FROM_DATABASE=Bridgeport machines
+
+pci:v00004594*
+ ID_VENDOR_FROM_DATABASE=Cogetec Informatique Inc
+
+pci:v000045FB*
+ ID_VENDOR_FROM_DATABASE=Baldor Electric Company
+
+pci:v00004624*
+ ID_VENDOR_FROM_DATABASE=Budker Institute of Nuclear Physics
+
+pci:v00004624d0000ADC1*
+ ID_PRODUCT_FROM_DATABASE=ADC200ME High speed ADC
+
+pci:v00004624d0000DE01*
+ ID_PRODUCT_FROM_DATABASE=DL200ME High resolution delay line PCI based card
+
+pci:v00004624d0000DE02*
+ ID_PRODUCT_FROM_DATABASE=DL200ME Middle resolution delay line PCI based card
+
+pci:v00004680*
+ ID_VENDOR_FROM_DATABASE=Umax Computer Corp
+
+pci:v00004843*
+ ID_VENDOR_FROM_DATABASE=Hercules Computer Technology Inc
+
+pci:v00004916*
+ ID_VENDOR_FROM_DATABASE=RedCreek Communications Inc
+
+pci:v00004916d00001960*
+ ID_PRODUCT_FROM_DATABASE=RedCreek PCI adapter
+
+pci:v00004943*
+ ID_VENDOR_FROM_DATABASE=Growth Networks
+
+pci:v0000494F*
+ ID_VENDOR_FROM_DATABASE=ACCES I/O Products, Inc.
+
+pci:v0000494Fd00000520*
+ ID_PRODUCT_FROM_DATABASE=PCI-IDO-48
+
+pci:v0000494Fd00000920*
+ ID_PRODUCT_FROM_DATABASE=PCI-IDI-48
+
+pci:v0000494Fd00000C50*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-24H
+
+pci:v0000494Fd00000C51*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-24D
+
+pci:v0000494Fd00000C60*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-48(H)
+
+pci:v0000494Fd00000C68*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-72
+
+pci:v0000494Fd00000C70*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-96
+
+pci:v0000494Fd00000C78*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-120
+
+pci:v0000494Fd00000DC8*
+ ID_PRODUCT_FROM_DATABASE=PCI-IDIO-16
+
+pci:v0000494Fd00000E50*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-24S
+
+pci:v0000494Fd00000E51*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-24H(C)
+
+pci:v0000494Fd00000E52*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-24D(C)
+
+pci:v0000494Fd00000E60*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-48S(H)
+
+pci:v0000494Fd00000E61*
+ ID_PRODUCT_FROM_DATABASE=P104-DIO-24S
+
+pci:v0000494Fd00000F00*
+ ID_PRODUCT_FROM_DATABASE=PCI-IIRO-8
+
+pci:v0000494Fd00000F01*
+ ID_PRODUCT_FROM_DATABASE=LPCI-IIRO-8
+
+pci:v0000494Fd00000F08*
+ ID_PRODUCT_FROM_DATABASE=PCI-IIRO-16
+
+pci:v0000494Fd00001050*
+ ID_PRODUCT_FROM_DATABASE=PCI-422/485-2
+
+pci:v0000494Fd00001058*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM422/4
+
+pci:v0000494Fd00001059*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM485/4
+
+pci:v0000494Fd00001068*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM422/8
+
+pci:v0000494Fd00001069*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM485/8
+
+pci:v0000494Fd00001088*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM232/1
+
+pci:v0000494Fd00001090*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM232/2
+
+pci:v0000494Fd000010A8*
+ ID_PRODUCT_FROM_DATABASE=P104-COM232-8
+
+pci:v0000494Fd000010C9*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM-1S
+
+pci:v0000494Fd000010D0*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM2S
+
+pci:v0000494Fd000010E8*
+ ID_PRODUCT_FROM_DATABASE=PCI-COM-8SM
+
+pci:v0000494Fd00001148*
+ ID_PRODUCT_FROM_DATABASE=PCI-ICM-1S
+
+pci:v0000494Fd00001150*
+ ID_PRODUCT_FROM_DATABASE=PCI-ICM-2S
+
+pci:v0000494Fd00001158*
+ ID_PRODUCT_FROM_DATABASE=PCI-ICM422/4
+
+pci:v0000494Fd00001159*
+ ID_PRODUCT_FROM_DATABASE=PCI-ICM485/4
+
+pci:v0000494Fd00001250*
+ ID_PRODUCT_FROM_DATABASE=PCI-WDG-2S
+
+pci:v0000494Fd000012D0*
+ ID_PRODUCT_FROM_DATABASE=PCI-WDG-IMPAC
+
+pci:v0000494Fd000022C0*
+ ID_PRODUCT_FROM_DATABASE=PCI-WDG-CSM
+
+pci:v0000494Fd00002C50*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-96CT
+
+pci:v0000494Fd00002C58*
+ ID_PRODUCT_FROM_DATABASE=PCI-DIO-96C3
+
+pci:v0000494Fd00005ED0*
+ ID_PRODUCT_FROM_DATABASE=PCI-DAC
+
+pci:v0000494Fd00006C90*
+ ID_PRODUCT_FROM_DATABASE=PCI-DA12-2
+
+pci:v0000494Fd00006C98*
+ ID_PRODUCT_FROM_DATABASE=PCI-DA12-4
+
+pci:v0000494Fd00006CA0*
+ ID_PRODUCT_FROM_DATABASE=PCI-DA12-6
+
+pci:v0000494Fd00006CA8*
+ ID_PRODUCT_FROM_DATABASE=PCI-DA12-8
+
+pci:v0000494Fd00006CA9*
+ ID_PRODUCT_FROM_DATABASE=PCI-DA12-8V
+
+pci:v0000494Fd00006CB0*
+ ID_PRODUCT_FROM_DATABASE=PCI-DA12-16
+
+pci:v0000494Fd00006CB1*
+ ID_PRODUCT_FROM_DATABASE=PCI-DA12-16V
+
+pci:v0000494Fd00008EF0*
+ ID_PRODUCT_FROM_DATABASE=P104-FAS16-16
+
+pci:v0000494Fd0000ACA8*
+ ID_PRODUCT_FROM_DATABASE=PCI-AI12-16
+
+pci:v0000494Fd0000ACA9*
+ ID_PRODUCT_FROM_DATABASE=PCI-AI12-16A
+
+pci:v0000494Fd0000ECA8*
+ ID_PRODUCT_FROM_DATABASE=PCI-AIO12-16
+
+pci:v0000494Fd0000ECA9*
+ ID_PRODUCT_FROM_DATABASE=PCI-A12-16
+
+pci:v0000494Fd0000ECAA*
+ ID_PRODUCT_FROM_DATABASE=PCI-A12-16A
+
+pci:v0000494Fd0000ECE8*
+ ID_PRODUCT_FROM_DATABASE=PCI-A16-16
+
+pci:v00004978*
+ ID_VENDOR_FROM_DATABASE=Axil Computer Inc
+
+pci:v00004A14*
+ ID_VENDOR_FROM_DATABASE=NetVin
+
+pci:v00004A14d00005000*
+ ID_PRODUCT_FROM_DATABASE=NV5000SC
+
+pci:v00004A14d00005000sv00004A14sd00005000*
+ ID_PRODUCT_FROM_DATABASE=RT8029-Based Ethernet Adapter
+
+pci:v00004B10*
+ ID_VENDOR_FROM_DATABASE=Buslogic Inc.
+
+pci:v00004C48*
+ ID_VENDOR_FROM_DATABASE=LUNG HWA Electronics
+
+pci:v00004C53*
+ ID_VENDOR_FROM_DATABASE=SBS Technologies
+
+pci:v00004C53d00000000*
+ ID_PRODUCT_FROM_DATABASE=PLUSTEST device
+
+pci:v00004C53d00000000sv00004C53sd00003000*
+ ID_PRODUCT_FROM_DATABASE=PLUSTEST card (PC104+)
+
+pci:v00004C53d00000000sv00004C53sd00003001*
+ ID_PRODUCT_FROM_DATABASE=PLUSTEST card (PMC)
+
+pci:v00004C53d00000001*
+ ID_PRODUCT_FROM_DATABASE=PLUSTEST-MM device
+
+pci:v00004C53d00000001sv00004C53sd00003002*
+ ID_PRODUCT_FROM_DATABASE=PLUSTEST-MM card (PMC)
+
+pci:v00004CA1*
+ ID_VENDOR_FROM_DATABASE=Seanix Technology Inc
+
+pci:v00004D51*
+ ID_VENDOR_FROM_DATABASE=MediaQ Inc.
+
+pci:v00004D51d00000200*
+ ID_PRODUCT_FROM_DATABASE=MQ-200
+
+pci:v00004D54*
+ ID_VENDOR_FROM_DATABASE=Microtechnica Co Ltd
+
+pci:v00004D56*
+ ID_VENDOR_FROM_DATABASE=MATRIX VISION GmbH
+
+pci:v00004D56d00000000*
+ ID_PRODUCT_FROM_DATABASE=[mvHYPERION-CLe/CLb] CameraLink PCI Express x1 Frame Grabber
+
+pci:v00004D56d00000001*
+ ID_PRODUCT_FROM_DATABASE=[mvHYPERION-CLf/CLm] CameraLink PCI Express x4 Frame Grabber
+
+pci:v00004D56d00000010*
+ ID_PRODUCT_FROM_DATABASE=[mvHYPERION-16R16/-32R16] 16 Video Channel PCI Express x4 Frame Grabber
+
+pci:v00004D56d00000020*
+ ID_PRODUCT_FROM_DATABASE=[mvHYPERION-HD-SDI] HD-SDI PCI Express x4 Frame Grabber
+
+pci:v00004D56d00000030*
+ ID_PRODUCT_FROM_DATABASE=[mvHYPERION-HD-SDI-Merger] HD-SDI PCI Express x4 Frame Grabber
+
+pci:v00004DDC*
+ ID_VENDOR_FROM_DATABASE=ILC Data Device Corp
+
+pci:v00004DDCd00000100*
+ ID_PRODUCT_FROM_DATABASE=DD-42924I5-300 (ARINC 429 Data Bus)
+
+pci:v00004DDCd00000801*
+ ID_PRODUCT_FROM_DATABASE=BU-65570I1 MIL-STD-1553 Test and Simulation
+
+pci:v00004DDCd00000802*
+ ID_PRODUCT_FROM_DATABASE=BU-65570I2 MIL-STD-1553 Test and Simulation
+
+pci:v00004DDCd00000811*
+ ID_PRODUCT_FROM_DATABASE=BU-65572I1 MIL-STD-1553 Test and Simulation
+
+pci:v00004DDCd00000812*
+ ID_PRODUCT_FROM_DATABASE=BU-65572I2 MIL-STD-1553 Test and Simulation
+
+pci:v00004DDCd00000881*
+ ID_PRODUCT_FROM_DATABASE=BU-65570T1 MIL-STD-1553 Test and Simulation
+
+pci:v00004DDCd00000882*
+ ID_PRODUCT_FROM_DATABASE=BU-65570T2 MIL-STD-1553 Test and Simulation
+
+pci:v00004DDCd00000891*
+ ID_PRODUCT_FROM_DATABASE=BU-65572T1 MIL-STD-1553 Test and Simulation
+
+pci:v00004DDCd00000892*
+ ID_PRODUCT_FROM_DATABASE=BU-65572T2 MIL-STD-1553 Test and Simulation
+
+pci:v00004DDCd00000901*
+ ID_PRODUCT_FROM_DATABASE=BU-65565C1 MIL-STD-1553 Data Bus
+
+pci:v00004DDCd00000902*
+ ID_PRODUCT_FROM_DATABASE=BU-65565C2 MIL-STD-1553 Data Bus
+
+pci:v00004DDCd00000903*
+ ID_PRODUCT_FROM_DATABASE=BU-65565C3 MIL-STD-1553 Data Bus
+
+pci:v00004DDCd00000904*
+ ID_PRODUCT_FROM_DATABASE=BU-65565C4 MIL-STD-1553 Data Bus
+
+pci:v00004DDCd00000B01*
+ ID_PRODUCT_FROM_DATABASE=BU-65569I1 MIL-STD-1553 Data Bus
+
+pci:v00004DDCd00000B02*
+ ID_PRODUCT_FROM_DATABASE=BU-65569I2 MIL-STD-1553 Data Bus
+
+pci:v00004DDCd00000B03*
+ ID_PRODUCT_FROM_DATABASE=BU-65569I3 MIL-STD-1553 Data Bus
+
+pci:v00004DDCd00000B04*
+ ID_PRODUCT_FROM_DATABASE=BU-65569I4 MIL-STD-1553 Data Bus
+
+pci:v00005045*
+ ID_VENDOR_FROM_DATABASE=University of Toronto
+
+pci:v00005045d00004243*
+ ID_PRODUCT_FROM_DATABASE=BLASTbus PCI Interface Card v1
+
+pci:v00005046*
+ ID_VENDOR_FROM_DATABASE=GemTek Technology Corporation
+
+pci:v00005046d00001001*
+ ID_PRODUCT_FROM_DATABASE=PCI Radio
+
+pci:v00005053*
+ ID_VENDOR_FROM_DATABASE=Voyetra Technologies
+
+pci:v00005053d00002010*
+ ID_PRODUCT_FROM_DATABASE=Daytona Audio Adapter
+
+pci:v000050B2*
+ ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH
+
+pci:v000050B2d00001111*
+ ID_PRODUCT_FROM_DATABASE=Terratec XLerate
+
+pci:v00005136*
+ ID_VENDOR_FROM_DATABASE=S S Technologies
+
+pci:v00005143*
+ ID_VENDOR_FROM_DATABASE=Qualcomm Inc
+
+pci:v00005145*
+ ID_VENDOR_FROM_DATABASE=Ensoniq (Old)
+
+pci:v00005145d00003031*
+ ID_PRODUCT_FROM_DATABASE=Concert AudioPCI
+
+pci:v00005168*
+ ID_VENDOR_FROM_DATABASE=Animation Technologies Inc.
+
+pci:v00005168d00000300*
+ ID_PRODUCT_FROM_DATABASE=FlyDVB-S
+
+pci:v00005168d00000301*
+ ID_PRODUCT_FROM_DATABASE=FlyDVB-T
+
+pci:v00005301*
+ ID_VENDOR_FROM_DATABASE=Alliance Semiconductor Corp.
+
+pci:v00005301d00000001*
+ ID_PRODUCT_FROM_DATABASE=ProMotion aT3D
+
+pci:v00005333*
+ ID_VENDOR_FROM_DATABASE=S3 Inc.
+
+pci:v00005333d00000551*
+ ID_PRODUCT_FROM_DATABASE=Plato/PX (system)
+
+pci:v00005333d00005631*
+ ID_PRODUCT_FROM_DATABASE=86c325 [ViRGE]
+
+pci:v00005333d00008800*
+ ID_PRODUCT_FROM_DATABASE=86c866 [Vision 866]
+
+pci:v00005333d00008801*
+ ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964]
+
+pci:v00005333d00008810*
+ ID_PRODUCT_FROM_DATABASE=86c764_0 [Trio 32 vers 0]
+
+pci:v00005333d00008811*
+ ID_PRODUCT_FROM_DATABASE=86c764/765 [Trio32/64/64V+]
+
+pci:v00005333d00008812*
+ ID_PRODUCT_FROM_DATABASE=86cM65 [Aurora64V+]
+
+pci:v00005333d00008813*
+ ID_PRODUCT_FROM_DATABASE=86c764_3 [Trio 32/64 vers 3]
+
+pci:v00005333d00008814*
+ ID_PRODUCT_FROM_DATABASE=86c767 [Trio 64UV+]
+
+pci:v00005333d00008815*
+ ID_PRODUCT_FROM_DATABASE=86cM65 [Aurora 128]
+
+pci:v00005333d0000883D*
+ ID_PRODUCT_FROM_DATABASE=86c988 [ViRGE/VX]
+
+pci:v00005333d00008870*
+ ID_PRODUCT_FROM_DATABASE=FireGL
+
+pci:v00005333d00008880*
+ ID_PRODUCT_FROM_DATABASE=86c868 [Vision 868 VRAM] vers 0
+
+pci:v00005333d00008881*
+ ID_PRODUCT_FROM_DATABASE=86c868 [Vision 868 VRAM] vers 1
+
+pci:v00005333d00008882*
+ ID_PRODUCT_FROM_DATABASE=86c868 [Vision 868 VRAM] vers 2
+
+pci:v00005333d00008883*
+ ID_PRODUCT_FROM_DATABASE=86c868 [Vision 868 VRAM] vers 3
+
+pci:v00005333d000088B0*
+ ID_PRODUCT_FROM_DATABASE=86c928 [Vision 928 VRAM] vers 0
+
+pci:v00005333d000088B1*
+ ID_PRODUCT_FROM_DATABASE=86c928 [Vision 928 VRAM] vers 1
+
+pci:v00005333d000088B2*
+ ID_PRODUCT_FROM_DATABASE=86c928 [Vision 928 VRAM] vers 2
+
+pci:v00005333d000088B3*
+ ID_PRODUCT_FROM_DATABASE=86c928 [Vision 928 VRAM] vers 3
+
+pci:v00005333d000088C0*
+ ID_PRODUCT_FROM_DATABASE=86c864 [Vision 864 DRAM] vers 0
+
+pci:v00005333d000088C1*
+ ID_PRODUCT_FROM_DATABASE=86c864 [Vision 864 DRAM] vers 1
+
+pci:v00005333d000088C2*
+ ID_PRODUCT_FROM_DATABASE=86c864 [Vision 864-P DRAM] vers 2
+
+pci:v00005333d000088C3*
+ ID_PRODUCT_FROM_DATABASE=86c864 [Vision 864-P DRAM] vers 3
+
+pci:v00005333d000088D0*
+ ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964 VRAM] vers 0
+
+pci:v00005333d000088D1*
+ ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964 VRAM] vers 1
+
+pci:v00005333d000088D2*
+ ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964-P VRAM] vers 2
+
+pci:v00005333d000088D3*
+ ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964-P VRAM] vers 3
+
+pci:v00005333d000088F0*
+ ID_PRODUCT_FROM_DATABASE=86c968 [Vision 968 VRAM] rev 0
+
+pci:v00005333d000088F1*
+ ID_PRODUCT_FROM_DATABASE=86c968 [Vision 968 VRAM] rev 1
+
+pci:v00005333d000088F2*
+ ID_PRODUCT_FROM_DATABASE=86c968 [Vision 968 VRAM] rev 2
+
+pci:v00005333d000088F3*
+ ID_PRODUCT_FROM_DATABASE=86c968 [Vision 968 VRAM] rev 3
+
+pci:v00005333d00008900*
+ ID_PRODUCT_FROM_DATABASE=86c755 [Trio 64V2/DX]
+
+pci:v00005333d00008900sv00005333sd00008900*
+ ID_PRODUCT_FROM_DATABASE=86C775 Trio64V2/DX
+
+pci:v00005333d00008901*
+ ID_PRODUCT_FROM_DATABASE=86c775/86c785 [Trio 64V2/DX or /GX]
+
+pci:v00005333d00008901sv00005333sd00008901*
+ ID_PRODUCT_FROM_DATABASE=86C775 Trio64V2/DX, 86C785 Trio64V2/GX
+
+pci:v00005333d00008902*
+ ID_PRODUCT_FROM_DATABASE=Plato/PX
+
+pci:v00005333d00008903*
+ ID_PRODUCT_FROM_DATABASE=Trio 3D business multimedia
+
+pci:v00005333d00008904*
+ ID_PRODUCT_FROM_DATABASE=86c365, 86c366 [Trio 3D]
+
+pci:v00005333d00008904sv00001014sd000000DB*
+ ID_PRODUCT_FROM_DATABASE=Integrated Trio3D
+
+pci:v00005333d00008904sv00004843sd0000314A*
+ ID_PRODUCT_FROM_DATABASE=Terminator 128/3D GLH
+
+pci:v00005333d00008904sv00005333sd00008904*
+ ID_PRODUCT_FROM_DATABASE=86C365 Trio3D AGP
+
+pci:v00005333d00008905*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d00008906*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d00008907*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d00008908*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d00008909*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d0000890A*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d0000890B*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d0000890C*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d0000890D*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d0000890E*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d0000890F*
+ ID_PRODUCT_FROM_DATABASE=Trio 64V+ family
+
+pci:v00005333d00008A01*
+ ID_PRODUCT_FROM_DATABASE=86c375 [ViRGE/DX] or 86c385 [ViRGE/GX]
+
+pci:v00005333d00008A01sv00000E11sd0000B032*
+ ID_PRODUCT_FROM_DATABASE=ViRGE/GX
+
+pci:v00005333d00008A01sv000010B4sd00001617*
+ ID_PRODUCT_FROM_DATABASE=Nitro 3D
+
+pci:v00005333d00008A01sv000010B4sd00001717*
+ ID_PRODUCT_FROM_DATABASE=Nitro 3D
+
+pci:v00005333d00008A01sv00005333sd00008A01*
+ ID_PRODUCT_FROM_DATABASE=ViRGE/DX
+
+pci:v00005333d00008A10*
+ ID_PRODUCT_FROM_DATABASE=ViRGE/GX2
+
+pci:v00005333d00008A10sv00001092sd00008A10*
+ ID_PRODUCT_FROM_DATABASE=Stealth 3D 4000
+
+pci:v00005333d00008A13*
+ ID_PRODUCT_FROM_DATABASE=86c360 [Trio 3D/1X], 86c362, 86c368 [Trio 3D/2X]
+
+pci:v00005333d00008A13sv00005333sd00008A13*
+ ID_PRODUCT_FROM_DATABASE=Trio3D/2X
+
+pci:v00005333d00008A20*
+ ID_PRODUCT_FROM_DATABASE=86c794 [Savage 3D]
+
+pci:v00005333d00008A20sv00005333sd00008A20*
+ ID_PRODUCT_FROM_DATABASE=86C391 Savage3D
+
+pci:v00005333d00008A21*
+ ID_PRODUCT_FROM_DATABASE=86c390 [Savage 3D/MV]
+
+pci:v00005333d00008A21sv00005333sd00008A21*
+ ID_PRODUCT_FROM_DATABASE=86C390 Savage3D/MV
+
+pci:v00005333d00008A22*
+ ID_PRODUCT_FROM_DATABASE=Savage 4
+
+pci:v00005333d00008A22sv00001033sd00008068*
+ ID_PRODUCT_FROM_DATABASE=Savage 4
+
+pci:v00005333d00008A22sv00001033sd00008069*
+ ID_PRODUCT_FROM_DATABASE=Savage 4
+
+pci:v00005333d00008A22sv00001033sd00008110*
+ ID_PRODUCT_FROM_DATABASE=Savage 4 LT
+
+pci:v00005333d00008A22sv0000105Dsd00000018*
+ ID_PRODUCT_FROM_DATABASE=SR9 8Mb SDRAM
+
+pci:v00005333d00008A22sv0000105Dsd0000002A*
+ ID_PRODUCT_FROM_DATABASE=SR9 Pro 16Mb SDRAM
+
+pci:v00005333d00008A22sv0000105Dsd0000003A*
+ ID_PRODUCT_FROM_DATABASE=SR9 Pro 32Mb SDRAM
+
+pci:v00005333d00008A22sv0000105Dsd0000092F*
+ ID_PRODUCT_FROM_DATABASE=SR9 Pro+ 16Mb SGRAM
+
+pci:v00005333d00008A22sv00001092sd00004207*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540
+
+pci:v00005333d00008A22sv00001092sd00004800*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540
+
+pci:v00005333d00008A22sv00001092sd00004807*
+ ID_PRODUCT_FROM_DATABASE=SpeedStar A90
+
+pci:v00005333d00008A22sv00001092sd00004808*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540
+
+pci:v00005333d00008A22sv00001092sd00004809*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540
+
+pci:v00005333d00008A22sv00001092sd0000480E*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540
+
+pci:v00005333d00008A22sv00001092sd00004904*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S520
+
+pci:v00005333d00008A22sv00001092sd00004905*
+ ID_PRODUCT_FROM_DATABASE=SpeedStar A200
+
+pci:v00005333d00008A22sv00001092sd00004A09*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540
+
+pci:v00005333d00008A22sv00001092sd00004A0B*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540 Xtreme
+
+pci:v00005333d00008A22sv00001092sd00004A0F*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540
+
+pci:v00005333d00008A22sv00001092sd00004E01*
+ ID_PRODUCT_FROM_DATABASE=Stealth III S540
+
+pci:v00005333d00008A22sv00001102sd0000101D*
+ ID_PRODUCT_FROM_DATABASE=3d Blaster Savage 4
+
+pci:v00005333d00008A22sv00001102sd0000101E*
+ ID_PRODUCT_FROM_DATABASE=3d Blaster Savage 4
+
+pci:v00005333d00008A22sv00005333sd00008100*
+ ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SDRAM 100
+
+pci:v00005333d00008A22sv00005333sd00008110*
+ ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SDRAM 110
+
+pci:v00005333d00008A22sv00005333sd00008125*
+ ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SDRAM 125
+
+pci:v00005333d00008A22sv00005333sd00008143*
+ ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SDRAM 143
+
+pci:v00005333d00008A22sv00005333sd00008A22*
+ ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4
+
+pci:v00005333d00008A22sv00005333sd00008A2E*
+ ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 32bit
+
+pci:v00005333d00008A22sv00005333sd00009125*
+ ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SGRAM 125
+
+pci:v00005333d00008A22sv00005333sd00009143*
+ ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SGRAM 143
+
+pci:v00005333d00008A23*
+ ID_PRODUCT_FROM_DATABASE=Savage 4
+
+pci:v00005333d00008A25*
+ ID_PRODUCT_FROM_DATABASE=ProSavage PM133
+
+pci:v00005333d00008A25sv00000303sd00000303*
+ ID_PRODUCT_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard]
+
+pci:v00005333d00008A26*
+ ID_PRODUCT_FROM_DATABASE=ProSavage KM133
+
+pci:v00005333d00008C00*
+ ID_PRODUCT_FROM_DATABASE=ViRGE/M3
+
+pci:v00005333d00008C01*
+ ID_PRODUCT_FROM_DATABASE=ViRGE/MX
+
+pci:v00005333d00008C01sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=ViRGE/MX
+
+pci:v00005333d00008C02*
+ ID_PRODUCT_FROM_DATABASE=ViRGE/MX+
+
+pci:v00005333d00008C03*
+ ID_PRODUCT_FROM_DATABASE=ViRGE/MX+MV
+
+pci:v00005333d00008C10*
+ ID_PRODUCT_FROM_DATABASE=86C270-294 Savage/MX-MV
+
+pci:v00005333d00008C11*
+ ID_PRODUCT_FROM_DATABASE=82C270-294 Savage/MX
+
+pci:v00005333d00008C12*
+ ID_PRODUCT_FROM_DATABASE=86C270-294 Savage/IX-MV
+
+pci:v00005333d00008C12sv00001014sd0000017F*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T20/T22
+
+pci:v00005333d00008C12sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=86C584 SuperSavage/IXC Toshiba
+
+pci:v00005333d00008C13*
+ ID_PRODUCT_FROM_DATABASE=86C270-294 Savage/IX
+
+pci:v00005333d00008C13sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Magnia Z310
+
+pci:v00005333d00008C22*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage MX/128
+
+pci:v00005333d00008C24*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage MX/64
+
+pci:v00005333d00008C26*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage MX/64C
+
+pci:v00005333d00008C2A*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage IX/128 SDR
+
+pci:v00005333d00008C2B*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage IX/128 DDR
+
+pci:v00005333d00008C2C*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage IX/64 SDR
+
+pci:v00005333d00008C2D*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage IX/64 DDR
+
+pci:v00005333d00008C2E*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage IX/C SDR
+
+pci:v00005333d00008C2Esv00001014sd000001FC*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T23
+
+pci:v00005333d00008C2F*
+ ID_PRODUCT_FROM_DATABASE=SuperSavage IX/C DDR
+
+pci:v00005333d00008D01*
+ ID_PRODUCT_FROM_DATABASE=86C380 [ProSavageDDR K4M266]
+
+pci:v00005333d00008D02*
+ ID_PRODUCT_FROM_DATABASE=VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK)
+
+pci:v00005333d00008D03*
+ ID_PRODUCT_FROM_DATABASE=VT8751 [ProSavageDDR P4M266]
+
+pci:v00005333d00008D04*
+ ID_PRODUCT_FROM_DATABASE=VT8375 [ProSavage8 KM266/KL266]
+
+pci:v00005333d00008E40*
+ ID_PRODUCT_FROM_DATABASE=2300E Graphics Processor
+
+pci:v00005333d00008E48*
+ ID_PRODUCT_FROM_DATABASE=Chrome S27 PCIE
+
+pci:v00005333d00008E48sv00005333sd00000130*
+ ID_PRODUCT_FROM_DATABASE=Chrome S27 256M DDR2
+
+pci:v00005333d00009102*
+ ID_PRODUCT_FROM_DATABASE=86C410 Savage 2000
+
+pci:v00005333d00009102sv00001092sd00005932*
+ ID_PRODUCT_FROM_DATABASE=Viper II Z200
+
+pci:v00005333d00009102sv00001092sd00005934*
+ ID_PRODUCT_FROM_DATABASE=Viper II Z200
+
+pci:v00005333d00009102sv00001092sd00005952*
+ ID_PRODUCT_FROM_DATABASE=Viper II Z200
+
+pci:v00005333d00009102sv00001092sd00005954*
+ ID_PRODUCT_FROM_DATABASE=Viper II Z200
+
+pci:v00005333d00009102sv00001092sd00005A35*
+ ID_PRODUCT_FROM_DATABASE=Viper II Z200
+
+pci:v00005333d00009102sv00001092sd00005A37*
+ ID_PRODUCT_FROM_DATABASE=Viper II Z200
+
+pci:v00005333d00009102sv00001092sd00005A55*
+ ID_PRODUCT_FROM_DATABASE=Viper II Z200
+
+pci:v00005333d00009102sv00001092sd00005A57*
+ ID_PRODUCT_FROM_DATABASE=Viper II Z200
+
+pci:v00005333d0000CA00*
+ ID_PRODUCT_FROM_DATABASE=SonicVibes
+
+pci:v00005431*
+ ID_VENDOR_FROM_DATABASE=AuzenTech, Inc.
+
+pci:v0000544C*
+ ID_VENDOR_FROM_DATABASE=Teralogic Inc
+
+pci:v0000544Cd00000350*
+ ID_PRODUCT_FROM_DATABASE=TL880-based HDTV/ATSC tuner
+
+pci:v00005452*
+ ID_VENDOR_FROM_DATABASE=SCANLAB AG
+
+pci:v00005452d00003443*
+ ID_PRODUCT_FROM_DATABASE=RTC4
+
+pci:v00005455*
+ ID_VENDOR_FROM_DATABASE=Technische University Berlin
+
+pci:v00005455d00004458*
+ ID_PRODUCT_FROM_DATABASE=S5933
+
+pci:v00005456*
+ ID_VENDOR_FROM_DATABASE=GoTView
+
+pci:v00005519*
+ ID_VENDOR_FROM_DATABASE=Cnet Technologies, Inc.
+
+pci:v00005544*
+ ID_VENDOR_FROM_DATABASE=Dunord Technologies
+
+pci:v00005544d00000001*
+ ID_PRODUCT_FROM_DATABASE=I-30xx Scanner Interface
+
+pci:v00005555*
+ ID_VENDOR_FROM_DATABASE=Genroco, Inc
+
+pci:v00005555d00000003*
+ ID_PRODUCT_FROM_DATABASE=TURBOstor HFP-832 [HiPPI NIC]
+
+pci:v00005646*
+ ID_VENDOR_FROM_DATABASE=Vector Fabrics BV
+
+pci:v00005654*
+ ID_VENDOR_FROM_DATABASE=VoiceTronix Pty Ltd
+
+pci:v00005700*
+ ID_VENDOR_FROM_DATABASE=Netpower
+
+pci:v0000584D*
+ ID_VENDOR_FROM_DATABASE=AuzenTech Co., Ltd.
+
+pci:v00005851*
+ ID_VENDOR_FROM_DATABASE=Exacq Technologies
+
+pci:v00005853*
+ ID_VENDOR_FROM_DATABASE=XenSource, Inc.
+
+pci:v00005853d00000001*
+ ID_PRODUCT_FROM_DATABASE=Xen Platform Device
+
+pci:v00005853d0000C110*
+ ID_PRODUCT_FROM_DATABASE=Virtualized HID
+
+pci:v00005853d0000C147*
+ ID_PRODUCT_FROM_DATABASE=Virtualized Graphics Device
+
+pci:v00005854*
+ ID_VENDOR_FROM_DATABASE=GoTView
+
+pci:v00005ACE*
+ ID_VENDOR_FROM_DATABASE=Beholder International Ltd.
+
+pci:v0000631C*
+ ID_VENDOR_FROM_DATABASE=SmartInfra Ltd
+
+pci:v0000631Cd00001652*
+ ID_PRODUCT_FROM_DATABASE=PXI-1652 Signal Generator
+
+pci:v0000631Cd00002504*
+ ID_PRODUCT_FROM_DATABASE=PXI-2504 Signal Interrogator
+
+pci:v00006356*
+ ID_VENDOR_FROM_DATABASE=UltraStor
+
+pci:v00006374*
+ ID_VENDOR_FROM_DATABASE=c't Magazin fuer Computertechnik
+
+pci:v00006374d00006773*
+ ID_PRODUCT_FROM_DATABASE=GPPCI
+
+pci:v00006409*
+ ID_VENDOR_FROM_DATABASE=Logitec Corp.
+
+pci:v00006549*
+ ID_VENDOR_FROM_DATABASE=Teradici Corp.
+
+pci:v00006549d00001200*
+ ID_PRODUCT_FROM_DATABASE=TERA1200 PC-over-IP Host
+
+pci:v00006666*
+ ID_VENDOR_FROM_DATABASE=Decision Computer International Co.
+
+pci:v00006666d00000001*
+ ID_PRODUCT_FROM_DATABASE=PCCOM4
+
+pci:v00006666d00000002*
+ ID_PRODUCT_FROM_DATABASE=PCCOM8
+
+pci:v00006666d00000004*
+ ID_PRODUCT_FROM_DATABASE=PCCOM2
+
+pci:v00006666d00000101*
+ ID_PRODUCT_FROM_DATABASE=PCI 8255/8254 I/O Card
+
+pci:v00006666d00000200*
+ ID_PRODUCT_FROM_DATABASE=12-bit AD/DA Card
+
+pci:v00006666d00000201*
+ ID_PRODUCT_FROM_DATABASE=14-bit AD/DA Card
+
+pci:v00006666d00001011*
+ ID_PRODUCT_FROM_DATABASE=Industrial Card
+
+pci:v00006666d00001021*
+ ID_PRODUCT_FROM_DATABASE=8 photo couple 8 relay Card
+
+pci:v00006666d00001022*
+ ID_PRODUCT_FROM_DATABASE=4 photo couple 4 relay Card
+
+pci:v00006666d00001025*
+ ID_PRODUCT_FROM_DATABASE=16 photo couple 16 relay Card
+
+pci:v00006666d00004000*
+ ID_PRODUCT_FROM_DATABASE=WatchDog Card
+
+pci:v00006900*
+ ID_VENDOR_FROM_DATABASE=Red Hat, Inc.
+
+pci:v00007063*
+ ID_VENDOR_FROM_DATABASE=pcHDTV
+
+pci:v00007063d00002000*
+ ID_PRODUCT_FROM_DATABASE=HD-2000
+
+pci:v00007063d00003000*
+ ID_PRODUCT_FROM_DATABASE=HD-3000
+
+pci:v00007063d00005500*
+ ID_PRODUCT_FROM_DATABASE=HD5500 HDTV
+
+pci:v00007284*
+ ID_VENDOR_FROM_DATABASE=HT OMEGA Inc.
+
+pci:v00007604*
+ ID_VENDOR_FROM_DATABASE=O.N. Electronic Co Ltd.
+
+pci:v00007BDE*
+ ID_VENDOR_FROM_DATABASE=MIDAC Corporation
+
+pci:v00007FED*
+ ID_VENDOR_FROM_DATABASE=PowerTV
+
+pci:v00008008*
+ ID_VENDOR_FROM_DATABASE=Quancom Electronic GmbH
+
+pci:v00008008d00000010*
+ ID_PRODUCT_FROM_DATABASE=WDOG1 [PCI-Watchdog 1]
+
+pci:v00008008d00000011*
+ ID_PRODUCT_FROM_DATABASE=PWDOG2 [PCI-Watchdog 2]
+
+pci:v00008008d00000015*
+ ID_PRODUCT_FROM_DATABASE=Clock77/PCI & Clock77/PCIe (DCF-77 receiver)
+
+pci:v0000807D*
+ ID_VENDOR_FROM_DATABASE=Asustek Computer, Inc.
+
+pci:v00008086*
+ ID_VENDOR_FROM_DATABASE=Intel Corporation
+
+pci:v00008086d00000007*
+ ID_PRODUCT_FROM_DATABASE=82379AB
+
+pci:v00008086d00000008*
+ ID_PRODUCT_FROM_DATABASE=Extended Express System Support Controller
+
+pci:v00008086d00000039*
+ ID_PRODUCT_FROM_DATABASE=21145 Fast Ethernet
+
+pci:v00008086d00000040*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DRAM Controller
+
+pci:v00008086d00000041*
+ ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express x16 Root Port
+
+pci:v00008086d00000042*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Graphics Controller
+
+pci:v00008086d00000043*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Secondary PCI Express Root Port
+
+pci:v00008086d00000044*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DRAM Controller
+
+pci:v00008086d00000044sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00000044sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00000045*
+ ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express x16 Root Port
+
+pci:v00008086d00000046*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Graphics Controller
+
+pci:v00008086d00000046sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00000047*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Secondary PCI Express Root Port
+
+pci:v00008086d00000048*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DRAM Controller
+
+pci:v00008086d00000049*
+ ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express x16 Root Port
+
+pci:v00008086d0000004A*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Graphics Controller
+
+pci:v00008086d0000004B*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Secondary PCI Express Root Port
+
+pci:v00008086d00000050*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Thermal Management Controller
+
+pci:v00008086d00000069*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DRAM Controller
+
+pci:v00008086d00000082*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak]
+
+pci:v00008086d00000082sv00008086sd00001301*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 AGN
+
+pci:v00008086d00000082sv00008086sd00001306*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 ABG
+
+pci:v00008086d00000082sv00008086sd00001307*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 BG
+
+pci:v00008086d00000082sv00008086sd00001321*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 AGN
+
+pci:v00008086d00000082sv00008086sd00001326*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 ABG
+
+pci:v00008086d00000083*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak]
+
+pci:v00008086d00000083sv00008086sd00001205*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+
+pci:v00008086d00000083sv00008086sd00001206*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG
+
+pci:v00008086d00000083sv00008086sd00001225*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+
+pci:v00008086d00000083sv00008086sd00001226*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG
+
+pci:v00008086d00000083sv00008086sd00001305*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+
+pci:v00008086d00000083sv00008086sd00001306*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG
+
+pci:v00008086d00000083sv00008086sd00001325*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+
+pci:v00008086d00000083sv00008086sd00001326*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG
+
+pci:v00008086d00000084*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak]
+
+pci:v00008086d00000084sv00008086sd00001215*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+
+pci:v00008086d00000084sv00008086sd00001216*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG
+
+pci:v00008086d00000084sv00008086sd00001315*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+
+pci:v00008086d00000084sv00008086sd00001316*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG
+
+pci:v00008086d00000085*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak]
+
+pci:v00008086d00000085sv00008086sd00001311*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 AGN
+
+pci:v00008086d00000085sv00008086sd00001316*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 ABG
+
+pci:v00008086d00000087*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak]
+
+pci:v00008086d00000087sv00008086sd00001301*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN
+
+pci:v00008086d00000087sv00008086sd00001306*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG
+
+pci:v00008086d00000087sv00008086sd00001321*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN
+
+pci:v00008086d00000087sv00008086sd00001326*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG
+
+pci:v00008086d00000089*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak]
+
+pci:v00008086d00000089sv00008086sd00001311*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN
+
+pci:v00008086d00000089sv00008086sd00001316*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG
+
+pci:v00008086d0000008A*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak]
+
+pci:v00008086d0000008Asv00008086sd00005305*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BGN
+
+pci:v00008086d0000008Asv00008086sd00005307*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BG
+
+pci:v00008086d0000008Asv00008086sd00005325*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BGN
+
+pci:v00008086d0000008Asv00008086sd00005327*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BG
+
+pci:v00008086d0000008B*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak]
+
+pci:v00008086d0000008Bsv00008086sd00005315*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BGN
+
+pci:v00008086d0000008Bsv00008086sd00005317*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BG
+
+pci:v00008086d00000090*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak]
+
+pci:v00008086d00000090sv00008086sd00005211*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 AGN
+
+pci:v00008086d00000090sv00008086sd00005215*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 BGN
+
+pci:v00008086d00000090sv00008086sd00005216*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 ABG
+
+pci:v00008086d00000091*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak]
+
+pci:v00008086d00000091sv00008086sd00005201*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 AGN
+
+pci:v00008086d00000091sv00008086sd00005205*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 BGN
+
+pci:v00008086d00000091sv00008086sd00005206*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 ABG
+
+pci:v00008086d00000091sv00008086sd00005207*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 BG
+
+pci:v00008086d00000091sv00008086sd00005221*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 AGN
+
+pci:v00008086d00000091sv00008086sd00005225*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 BGN
+
+pci:v00008086d00000091sv00008086sd00005226*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 ABG
+
+pci:v00008086d00000100*
+ ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller
+
+pci:v00008086d00000100sv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00008086d00000100sv00001043sd0000844D*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00000101*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
+
+pci:v00008086d00000101sv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00000101sv0000106Bsd000000DC*
+ ID_PRODUCT_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00000102*
+ ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
+
+pci:v00008086d00000104*
+ ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller
+
+pci:v00008086d00000104sv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00000104sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00000104sv0000106Bsd000000DC*
+ ID_PRODUCT_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00000105*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
+
+pci:v00008086d00000105sv0000106Bsd000000DC*
+ ID_PRODUCT_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00000106*
+ ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
+
+pci:v00008086d00000108*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 Processor Family DRAM Controller
+
+pci:v00008086d00000109*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
+
+pci:v00008086d0000010A*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 Processor Family Integrated Graphics Controller
+
+pci:v00008086d0000010B*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family Integrated Graphics Controller
+
+pci:v00008086d0000010C*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family DRAM Controller
+
+pci:v00008086d0000010D*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
+
+pci:v00008086d0000010E*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family Integrated Graphics Controller
+
+pci:v00008086d00000112*
+ ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
+
+pci:v00008086d00000116*
+ ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
+
+pci:v00008086d00000116sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00000122*
+ ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
+
+pci:v00008086d00000126*
+ ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
+
+pci:v00008086d00000126sv00001028sd000004CC*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00000150*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
+
+pci:v00008086d00000151*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
+
+pci:v00008086d00000151sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00000152*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
+
+pci:v00008086d00000153*
+ ID_PRODUCT_FROM_DATABASE=3rd Gen Core Processor Thermal Subsystem
+
+pci:v00008086d00000153sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00000154*
+ ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor DRAM Controller
+
+pci:v00008086d00000154sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00000154sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00000155*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
+
+pci:v00008086d00000156*
+ ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor Graphics Controller
+
+pci:v00008086d00000158*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge DRAM Controller
+
+pci:v00008086d00000159*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
+
+pci:v00008086d0000015A*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge Graphics Controller
+
+pci:v00008086d0000015C*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
+
+pci:v00008086d0000015D*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
+
+pci:v00008086d0000015E*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
+
+pci:v00008086d00000162*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
+
+pci:v00008086d00000166*
+ ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor Graphics Controller
+
+pci:v00008086d00000166sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00000166sv00001043sd00002103*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d0000016A*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
+
+pci:v00008086d00000172*
+ ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
+
+pci:v00008086d00000176*
+ ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor Graphics Controller
+
+pci:v00008086d00000309*
+ ID_PRODUCT_FROM_DATABASE=80303 I/O Processor PCI-to-PCI Bridge
+
+pci:v00008086d0000030D*
+ ID_PRODUCT_FROM_DATABASE=80312 I/O Companion Chip PCI-to-PCI Bridge
+
+pci:v00008086d00000326*
+ ID_PRODUCT_FROM_DATABASE=6700/6702PXH I/OxAPIC Interrupt Controller A
+
+pci:v00008086d00000326sv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00008086d00000326sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00000327*
+ ID_PRODUCT_FROM_DATABASE=6700PXH I/OxAPIC Interrupt Controller B
+
+pci:v00008086d00000327sv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00008086d00000327sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00000329*
+ ID_PRODUCT_FROM_DATABASE=6700PXH PCI Express-to-PCI Bridge A
+
+pci:v00008086d0000032A*
+ ID_PRODUCT_FROM_DATABASE=6700PXH PCI Express-to-PCI Bridge B
+
+pci:v00008086d0000032C*
+ ID_PRODUCT_FROM_DATABASE=6702PXH PCI Express-to-PCI Bridge A
+
+pci:v00008086d00000330*
+ ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (A-Segment Bridge)
+
+pci:v00008086d00000331*
+ ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (A-Segment IOAPIC)
+
+pci:v00008086d00000332*
+ ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (B-Segment Bridge)
+
+pci:v00008086d00000333*
+ ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (B-Segment IOAPIC)
+
+pci:v00008086d00000334*
+ ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (ATU)
+
+pci:v00008086d00000335*
+ ID_PRODUCT_FROM_DATABASE=80331 [Lindsay] I/O processor (PCI-X Bridge)
+
+pci:v00008086d00000336*
+ ID_PRODUCT_FROM_DATABASE=80331 [Lindsay] I/O processor (ATU)
+
+pci:v00008086d00000340*
+ ID_PRODUCT_FROM_DATABASE=41210 [Lanai] Serial to Parallel PCI Bridge (A-Segment Bridge)
+
+pci:v00008086d00000341*
+ ID_PRODUCT_FROM_DATABASE=41210 [Lanai] Serial to Parallel PCI Bridge (B-Segment Bridge)
+
+pci:v00008086d00000370*
+ ID_PRODUCT_FROM_DATABASE=80333 Segment-A PCI Express-to-PCI Express Bridge
+
+pci:v00008086d00000371*
+ ID_PRODUCT_FROM_DATABASE=80333 A-Bus IOAPIC
+
+pci:v00008086d00000372*
+ ID_PRODUCT_FROM_DATABASE=80333 Segment-B PCI Express-to-PCI Express Bridge
+
+pci:v00008086d00000373*
+ ID_PRODUCT_FROM_DATABASE=80333 B-Bus IOAPIC
+
+pci:v00008086d00000374*
+ ID_PRODUCT_FROM_DATABASE=80333 Address Translation Unit
+
+pci:v00008086d00000402*
+ ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller
+
+pci:v00008086d00000406*
+ ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller
+
+pci:v00008086d0000040A*
+ ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller
+
+pci:v00008086d00000412*
+ ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller
+
+pci:v00008086d00000416*
+ ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller
+
+pci:v00008086d0000041A*
+ ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller
+
+pci:v00008086d00000436*
+ ID_PRODUCT_FROM_DATABASE=DH8900CC Null Device
+
+pci:v00008086d00000438*
+ ID_PRODUCT_FROM_DATABASE=DH8900CC Series Gigabit Network Connection
+
+pci:v00008086d0000043A*
+ ID_PRODUCT_FROM_DATABASE=DH8900CC Series Gigabit Fiber Network Connection
+
+pci:v00008086d0000043C*
+ ID_PRODUCT_FROM_DATABASE=DH8900CC Series Gigabit Backplane Network Connection
+
+pci:v00008086d00000440*
+ ID_PRODUCT_FROM_DATABASE=DH8900CC Series Gigabit SFP Network Connection
+
+pci:v00008086d00000482*
+ ID_PRODUCT_FROM_DATABASE=82375EB/SB PCI to EISA Bridge
+
+pci:v00008086d00000483*
+ ID_PRODUCT_FROM_DATABASE=82424TX/ZX [Saturn] CPU to PCI bridge
+
+pci:v00008086d00000484*
+ ID_PRODUCT_FROM_DATABASE=82378ZB/IB, 82379AB (SIO, SIO.A) PCI to ISA Bridge
+
+pci:v00008086d00000486*
+ ID_PRODUCT_FROM_DATABASE=82425EX/ZX [Aries] PCIset with ISA bridge
+
+pci:v00008086d000004A3*
+ ID_PRODUCT_FROM_DATABASE=82434LX/NX [Mercury/Neptune] Processor to PCI bridge
+
+pci:v00008086d000004D0*
+ ID_PRODUCT_FROM_DATABASE=82437FX [Triton FX]
+
+pci:v00008086d00000500*
+ ID_PRODUCT_FROM_DATABASE=E8870 Processor bus control
+
+pci:v00008086d00000501*
+ ID_PRODUCT_FROM_DATABASE=E8870 Memory controller
+
+pci:v00008086d00000502*
+ ID_PRODUCT_FROM_DATABASE=E8870 Scalability Port 0
+
+pci:v00008086d00000503*
+ ID_PRODUCT_FROM_DATABASE=E8870 Scalability Port 1
+
+pci:v00008086d00000510*
+ ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 0 registers (8-bit compatibility port)
+
+pci:v00008086d00000511*
+ ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 1 registers
+
+pci:v00008086d00000512*
+ ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 2 registers
+
+pci:v00008086d00000513*
+ ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 3 registers
+
+pci:v00008086d00000514*
+ ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 4 registers
+
+pci:v00008086d00000515*
+ ID_PRODUCT_FROM_DATABASE=E8870IO General SIOH registers
+
+pci:v00008086d00000516*
+ ID_PRODUCT_FROM_DATABASE=E8870IO RAS registers
+
+pci:v00008086d00000530*
+ ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 0 registers
+
+pci:v00008086d00000531*
+ ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 1 registers
+
+pci:v00008086d00000532*
+ ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 2 registers
+
+pci:v00008086d00000533*
+ ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 3 registers
+
+pci:v00008086d00000534*
+ ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 4 registers
+
+pci:v00008086d00000535*
+ ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 5 registers
+
+pci:v00008086d00000536*
+ ID_PRODUCT_FROM_DATABASE=E8870SP Interleave registers 0 and 1
+
+pci:v00008086d00000537*
+ ID_PRODUCT_FROM_DATABASE=E8870SP Interleave registers 2 and 3
+
+pci:v00008086d00000600*
+ ID_PRODUCT_FROM_DATABASE=RAID Controller
+
+pci:v00008086d00000600sv00008086sd00000136*
+ ID_PRODUCT_FROM_DATABASE=SRCU31L
+
+pci:v00008086d00000600sv00008086sd000001AF*
+ ID_PRODUCT_FROM_DATABASE=SRCZCR
+
+pci:v00008086d00000600sv00008086sd000001C1*
+ ID_PRODUCT_FROM_DATABASE=ICP Vortex GDT8546RZ
+
+pci:v00008086d00000600sv00008086sd000001F7*
+ ID_PRODUCT_FROM_DATABASE=SCRU32
+
+pci:v00008086d0000061F*
+ ID_PRODUCT_FROM_DATABASE=80303 I/O Processor
+
+pci:v00008086d00000700*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor A/V Bridge
+
+pci:v00008086d00000701*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor NAND Flash Controller
+
+pci:v00008086d00000703*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Media Control Unit 1
+
+pci:v00008086d00000704*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Video Capture Interface
+
+pci:v00008086d00000707*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor SPI Slave
+
+pci:v00008086d00000708*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor 4100
+
+pci:v00008086d00000800*
+ ID_PRODUCT_FROM_DATABASE=Moorestown SPI Ctrl 0
+
+pci:v00008086d00000801*
+ ID_PRODUCT_FROM_DATABASE=Moorestown SPI Ctrl 1
+
+pci:v00008086d00000802*
+ ID_PRODUCT_FROM_DATABASE=Moorestown I2C 0
+
+pci:v00008086d00000803*
+ ID_PRODUCT_FROM_DATABASE=Moorestown I2C 1
+
+pci:v00008086d00000804*
+ ID_PRODUCT_FROM_DATABASE=Moorestown I2C 2
+
+pci:v00008086d00000805*
+ ID_PRODUCT_FROM_DATABASE=Moorestown Keyboard Ctrl
+
+pci:v00008086d00000806*
+ ID_PRODUCT_FROM_DATABASE=Moorestown USB Ctrl
+
+pci:v00008086d00000807*
+ ID_PRODUCT_FROM_DATABASE=Moorestown SD Host Ctrl 0
+
+pci:v00008086d00000808*
+ ID_PRODUCT_FROM_DATABASE=Moorestown SD Host Ctrl 1
+
+pci:v00008086d00000809*
+ ID_PRODUCT_FROM_DATABASE=Moorestown NAND Ctrl
+
+pci:v00008086d0000080A*
+ ID_PRODUCT_FROM_DATABASE=Moorestown Audio Ctrl
+
+pci:v00008086d0000080B*
+ ID_PRODUCT_FROM_DATABASE=Moorestown ISP
+
+pci:v00008086d0000080C*
+ ID_PRODUCT_FROM_DATABASE=Moorestown Security Controller
+
+pci:v00008086d0000080D*
+ ID_PRODUCT_FROM_DATABASE=Moorestown External Displays
+
+pci:v00008086d0000080E*
+ ID_PRODUCT_FROM_DATABASE=Moorestown SCU IPC
+
+pci:v00008086d0000080F*
+ ID_PRODUCT_FROM_DATABASE=Moorestown GPIO Controller
+
+pci:v00008086d00000810*
+ ID_PRODUCT_FROM_DATABASE=Moorestown Power Management Unit
+
+pci:v00008086d00000811*
+ ID_PRODUCT_FROM_DATABASE=Moorestown OTG Ctrl
+
+pci:v00008086d00000812*
+ ID_PRODUCT_FROM_DATABASE=Moorestown SPI Ctrl 2
+
+pci:v00008086d00000813*
+ ID_PRODUCT_FROM_DATABASE=Moorestown SC DMA
+
+pci:v00008086d00000814*
+ ID_PRODUCT_FROM_DATABASE=Moorestown LPE DMA
+
+pci:v00008086d00000815*
+ ID_PRODUCT_FROM_DATABASE=Moorestown SSP0
+
+pci:v00008086d00000885*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150
+
+pci:v00008086d00000885sv00008086sd00001305*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN
+
+pci:v00008086d00000885sv00008086sd00001307*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG
+
+pci:v00008086d00000885sv00008086sd00001325*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN
+
+pci:v00008086d00000885sv00008086sd00001327*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG
+
+pci:v00008086d00000886*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150
+
+pci:v00008086d00000886sv00008086sd00001315*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN
+
+pci:v00008086d00000886sv00008086sd00001317*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG
+
+pci:v00008086d00000887*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230
+
+pci:v00008086d00000887sv00008086sd00004062*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230 BGN
+
+pci:v00008086d00000887sv00008086sd00004462*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230 BGN
+
+pci:v00008086d00000888*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230
+
+pci:v00008086d00000888sv00008086sd00004262*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230 BGN
+
+pci:v00008086d0000088E*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235
+
+pci:v00008086d0000088Esv00008086sd00004060*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235 AGN
+
+pci:v00008086d0000088Esv00008086sd00004460*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235 AGN
+
+pci:v00008086d0000088F*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235
+
+pci:v00008086d0000088Fsv00008086sd00004260*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235 AGN
+
+pci:v00008086d00000890*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200
+
+pci:v00008086d00000890sv00008086sd00004022*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 BGN
+
+pci:v00008086d00000890sv00008086sd00004422*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 BGN
+
+pci:v00008086d00000890sv00008086sd00004822*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 BGN
+
+pci:v00008086d00000891*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200
+
+pci:v00008086d00000891sv00008086sd00004222*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 BGN
+
+pci:v00008086d00000892*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135
+
+pci:v00008086d00000892sv00008086sd00000062*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135 BGN
+
+pci:v00008086d00000892sv00008086sd00000462*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135 BGN
+
+pci:v00008086d00000893*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135
+
+pci:v00008086d00000893sv00008086sd00000262*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135 BGN
+
+pci:v00008086d00000894*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105
+
+pci:v00008086d00000894sv00008086sd00000022*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 BGN
+
+pci:v00008086d00000894sv00008086sd00000422*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 BGN
+
+pci:v00008086d00000894sv00008086sd00000822*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 BGN
+
+pci:v00008086d00000895*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105
+
+pci:v00008086d00000895sv00008086sd00000222*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 BGN
+
+pci:v00008086d00000896*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130
+
+pci:v00008086d00000896sv00008086sd00005005*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BGN
+
+pci:v00008086d00000896sv00008086sd00005007*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BG
+
+pci:v00008086d00000896sv00008086sd00005025*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BGN
+
+pci:v00008086d00000896sv00008086sd00005027*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BG
+
+pci:v00008086d00000897*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130
+
+pci:v00008086d00000897sv00008086sd00005015*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BGN
+
+pci:v00008086d00000897sv00008086sd00005017*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BG
+
+pci:v00008086d000008AE*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100
+
+pci:v00008086d000008AEsv00008086sd00001005*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BGN
+
+pci:v00008086d000008AEsv00008086sd00001007*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BG
+
+pci:v00008086d000008AEsv00008086sd00001025*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BGN
+
+pci:v00008086d000008AEsv00008086sd00001027*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BG
+
+pci:v00008086d000008AF*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100
+
+pci:v00008086d000008AFsv00008086sd00001015*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BGN
+
+pci:v00008086d000008AFsv00008086sd00001017*
+ ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BG
+
+pci:v00008086d00000960*
+ ID_PRODUCT_FROM_DATABASE=80960RP (i960RP) Microprocessor/Bridge
+
+pci:v00008086d00000962*
+ ID_PRODUCT_FROM_DATABASE=80960RM (i960RM) Bridge
+
+pci:v00008086d00000964*
+ ID_PRODUCT_FROM_DATABASE=80960RP (i960RP) Microprocessor/Bridge
+
+pci:v00008086d00000A04*
+ ID_PRODUCT_FROM_DATABASE=Haswell-ULT DRAM Controller
+
+pci:v00008086d00000A06*
+ ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
+
+pci:v00008086d00000A16*
+ ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
+
+pci:v00008086d00000A22*
+ ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
+
+pci:v00008086d00000A26*
+ ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
+
+pci:v00008086d00000A2A*
+ ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
+
+pci:v00008086d00000BE0*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE1*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE2*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE3*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE4*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE5*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE6*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE7*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE8*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BE9*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BEA*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BEB*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BEC*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BED*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BEE*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BEF*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
+
+pci:v00008086d00000BF0*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
+
+pci:v00008086d00000BF1*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
+
+pci:v00008086d00000BF2*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
+
+pci:v00008086d00000BF3*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
+
+pci:v00008086d00000BF4*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
+
+pci:v00008086d00000BF5*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
+
+pci:v00008086d00000BF6*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
+
+pci:v00008086d00000BF7*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
+
+pci:v00008086d00000C00*
+ ID_PRODUCT_FROM_DATABASE=Haswell DRAM Controller
+
+pci:v00008086d00000C01*
+ ID_PRODUCT_FROM_DATABASE=Haswell PCI Express x16 Controller
+
+pci:v00008086d00000C04*
+ ID_PRODUCT_FROM_DATABASE=Haswell DRAM Controller
+
+pci:v00008086d00000C05*
+ ID_PRODUCT_FROM_DATABASE=Haswell PCI Express x8 Controller
+
+pci:v00008086d00000C08*
+ ID_PRODUCT_FROM_DATABASE=Haswell DRAM Controller
+
+pci:v00008086d00000C09*
+ ID_PRODUCT_FROM_DATABASE=Haswell PCI Express x4 Controller
+
+pci:v00008086d00000C0C*
+ ID_PRODUCT_FROM_DATABASE=Haswell HD Audio Controller
+
+pci:v00008086d00000C46*
+ ID_PRODUCT_FROM_DATABASE=Centerton PCI Express Root Port 1
+
+pci:v00008086d00000C47*
+ ID_PRODUCT_FROM_DATABASE=Centerton PCI Express Root Port 2
+
+pci:v00008086d00000C48*
+ ID_PRODUCT_FROM_DATABASE=Centerton PCI Express Root Port 3
+
+pci:v00008086d00000C49*
+ ID_PRODUCT_FROM_DATABASE=Centerton PCI Express Root Port 4
+
+pci:v00008086d00000C4E*
+ ID_PRODUCT_FROM_DATABASE=Centerton NTB Primary
+
+pci:v00008086d00000C54*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Management
+
+pci:v00008086d00000C59*
+ ID_PRODUCT_FROM_DATABASE=Centerton SMBus 2.0 Controller 0
+
+pci:v00008086d00000C5A*
+ ID_PRODUCT_FROM_DATABASE=Centerton SMBus 2.0 Controller 1
+
+pci:v00008086d00000C5F*
+ ID_PRODUCT_FROM_DATABASE=Centerton UART
+
+pci:v00008086d00000C60*
+ ID_PRODUCT_FROM_DATABASE=Centerton Integrated Legacy Bus
+
+pci:v00008086d00000C70*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C71*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C72*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C73*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C74*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C75*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C76*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C77*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C78*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C79*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C7A*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C7B*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C7C*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C7D*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C7E*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000C7F*
+ ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric
+
+pci:v00008086d00000D00*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well DRAM Controller
+
+pci:v00008086d00000D01*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well PCI Express x16 Controller
+
+pci:v00008086d00000D04*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well DRAM Controller
+
+pci:v00008086d00000D05*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well PCI Express x8 Controller
+
+pci:v00008086d00000D09*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well PCI Express x4 Controller
+
+pci:v00008086d00000D0C*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well HD Audio Controller
+
+pci:v00008086d00000D16*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well Integrated Graphics Controller
+
+pci:v00008086d00000D26*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well Integrated Graphics Controller
+
+pci:v00008086d00000D36*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well Integrated Graphics Controller
+
+pci:v00008086d00000E00*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DMI2
+
+pci:v00008086d00000E01*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port in DMI2 Mode
+
+pci:v00008086d00000E02*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 1a
+
+pci:v00008086d00000E03*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 1b
+
+pci:v00008086d00000E04*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 2a
+
+pci:v00008086d00000E05*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 2b
+
+pci:v00008086d00000E06*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 2c
+
+pci:v00008086d00000E07*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 2d
+
+pci:v00008086d00000E08*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 3a
+
+pci:v00008086d00000E09*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 3b
+
+pci:v00008086d00000E0A*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 3c
+
+pci:v00008086d00000E0B*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 3d
+
+pci:v00008086d00000E1C*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Debug and Error Injection Related Registers
+
+pci:v00008086d00000E1D*
+ ID_PRODUCT_FROM_DATABASE=Ivytown R2PCIe
+
+pci:v00008086d00000E1E*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Semaphore and Scratchpad Configuration Registers
+
+pci:v00008086d00000E1F*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Semaphore and Scratchpad Configuration Registers
+
+pci:v00008086d00000E20*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 0
+
+pci:v00008086d00000E21*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 1
+
+pci:v00008086d00000E22*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 2
+
+pci:v00008086d00000E23*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 3
+
+pci:v00008086d00000E24*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 4
+
+pci:v00008086d00000E25*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 5
+
+pci:v00008086d00000E26*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 6
+
+pci:v00008086d00000E27*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 7
+
+pci:v00008086d00000E28*
+ ID_PRODUCT_FROM_DATABASE=Ivytown VTd/Memory Map/Misc
+
+pci:v00008086d00000E29*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Memory Hotplug
+
+pci:v00008086d00000E2A*
+ ID_PRODUCT_FROM_DATABASE=Ivytown IIO RAS
+
+pci:v00008086d00000E2C*
+ ID_PRODUCT_FROM_DATABASE=Ivytown IOAPIC
+
+pci:v00008086d00000E2E*
+ ID_PRODUCT_FROM_DATABASE=Ivytown CBDMA
+
+pci:v00008086d00000E2F*
+ ID_PRODUCT_FROM_DATABASE=Ivytown CBDMA
+
+pci:v00008086d00000E30*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Home Agent 0
+
+pci:v00008086d00000E32*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 0
+
+pci:v00008086d00000E33*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 1
+
+pci:v00008086d00000E34*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Ring Performance Monitoring
+
+pci:v00008086d00000E36*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring
+
+pci:v00008086d00000E37*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring
+
+pci:v00008086d00000E38*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Home Agent 1
+
+pci:v00008086d00000E3A*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 2
+
+pci:v00008086d00000E3E*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring
+
+pci:v00008086d00000E3F*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring
+
+pci:v00008086d00000E40*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 2
+
+pci:v00008086d00000E41*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Registers
+
+pci:v00008086d00000E43*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 2
+
+pci:v00008086d00000E44*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 2
+
+pci:v00008086d00000E60*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Home Agent 1
+
+pci:v00008086d00000E68*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Target Address/Thermal Registers
+
+pci:v00008086d00000E6A*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers
+
+pci:v00008086d00000E6B*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers
+
+pci:v00008086d00000E6C*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers
+
+pci:v00008086d00000E6D*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers
+
+pci:v00008086d00000E71*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 RAS Registers
+
+pci:v00008086d00000E79*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 RAS Registers
+
+pci:v00008086d00000E80*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 0
+
+pci:v00008086d00000E81*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Registers
+
+pci:v00008086d00000E83*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 0
+
+pci:v00008086d00000E84*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 0
+
+pci:v00008086d00000E90*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 1
+
+pci:v00008086d00000E93*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 1
+
+pci:v00008086d00000E94*
+ ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 1
+
+pci:v00008086d00000EA0*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Home Agent 0
+
+pci:v00008086d00000EA8*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Target Address/Thermal Registers
+
+pci:v00008086d00000EAA*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers
+
+pci:v00008086d00000EAB*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers
+
+pci:v00008086d00000EAC*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers
+
+pci:v00008086d00000EAD*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers
+
+pci:v00008086d00000EB0*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 0
+
+pci:v00008086d00000EB1*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 1
+
+pci:v00008086d00000EB2*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 0
+
+pci:v00008086d00000EB3*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 1
+
+pci:v00008086d00000EB4*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 2
+
+pci:v00008086d00000EB5*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 3
+
+pci:v00008086d00000EB7*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 2
+
+pci:v00008086d00000EC0*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 0
+
+pci:v00008086d00000EC1*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 1
+
+pci:v00008086d00000EC2*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 2
+
+pci:v00008086d00000EC3*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 3
+
+pci:v00008086d00000EC4*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 4
+
+pci:v00008086d00000EC8*
+ ID_PRODUCT_FROM_DATABASE=Ivytown System Address Decoder
+
+pci:v00008086d00000EC9*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Broadcast Registers
+
+pci:v00008086d00000ECA*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Broadcast Registers
+
+pci:v00008086d00000ED8*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000ED9*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EDC*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EDD*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EDE*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EDF*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EE0*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE1*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE2*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE3*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE4*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE5*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE6*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE7*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE8*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EE9*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EEA*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EEB*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EEC*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EED*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EEE*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers
+
+pci:v00008086d00000EF0*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 0
+
+pci:v00008086d00000EF1*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 1
+
+pci:v00008086d00000EF2*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 0
+
+pci:v00008086d00000EF3*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 2
+
+pci:v00008086d00000EF4*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 2
+
+pci:v00008086d00000EF5*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 3
+
+pci:v00008086d00000EF7*
+ ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 3
+
+pci:v00008086d00000EF8*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EF9*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EFA*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EFB*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EFC*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000EFD*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO
+
+pci:v00008086d00000F00*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SSA-CUnit
+
+pci:v00008086d00000F01*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SSA-CUnit
+
+pci:v00008086d00000F02*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SSA-CUnit
+
+pci:v00008086d00000F03*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SSA-CUnit
+
+pci:v00008086d00000F04*
+ ID_PRODUCT_FROM_DATABASE=ValleyView High Definition Audio Controller
+
+pci:v00008086d00000F05*
+ ID_PRODUCT_FROM_DATABASE=ValleyView High Definition Audio Controller
+
+pci:v00008086d00000F06*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 DMA Controller
+
+pci:v00008086d00000F07*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 DMA Controller
+
+pci:v00008086d00000F08*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 PWM Controller
+
+pci:v00008086d00000F09*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 PWM Controller
+
+pci:v00008086d00000F0A*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #1
+
+pci:v00008086d00000F0B*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #1
+
+pci:v00008086d00000F0C*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #2
+
+pci:v00008086d00000F0D*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #2
+
+pci:v00008086d00000F0E*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 SPI Controller
+
+pci:v00008086d00000F0F*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 SPI Controller
+
+pci:v00008086d00000F10*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 Controller
+
+pci:v00008086d00000F11*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 Controller
+
+pci:v00008086d00000F12*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SMBus Controller
+
+pci:v00008086d00000F13*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SMBus Controller
+
+pci:v00008086d00000F14*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SDIO Controller
+
+pci:v00008086d00000F15*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SDIO Controller
+
+pci:v00008086d00000F16*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SDIO Controller
+
+pci:v00008086d00000F17*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SDIO Controller
+
+pci:v00008086d00000F18*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SEC
+
+pci:v00008086d00000F19*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SEC
+
+pci:v00008086d00000F1A*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SEC
+
+pci:v00008086d00000F1B*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SEC
+
+pci:v00008086d00000F1C*
+ ID_PRODUCT_FROM_DATABASE=ValleyView Power Control Unit
+
+pci:v00008086d00000F1D*
+ ID_PRODUCT_FROM_DATABASE=ValleyView Power Control Unit
+
+pci:v00008086d00000F1E*
+ ID_PRODUCT_FROM_DATABASE=ValleyView Power Control Unit
+
+pci:v00008086d00000F1F*
+ ID_PRODUCT_FROM_DATABASE=ValleyView Power Control Unit
+
+pci:v00008086d00000F20*
+ ID_PRODUCT_FROM_DATABASE=ValleyView 4-Port SATA Storage Controller
+
+pci:v00008086d00000F21*
+ ID_PRODUCT_FROM_DATABASE=ValleyView 4-Port SATA Storage Controller
+
+pci:v00008086d00000F22*
+ ID_PRODUCT_FROM_DATABASE=ValleyView 6-Port SATA AHCI Controller
+
+pci:v00008086d00000F23*
+ ID_PRODUCT_FROM_DATABASE=ValleyView 6-Port SATA AHCI Controller
+
+pci:v00008086d00000F24*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SATA RAID Storage Controller
+
+pci:v00008086d00000F25*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SATA RAID Storage Controller
+
+pci:v00008086d00000F26*
+ ID_PRODUCT_FROM_DATABASE=ValleyView 2-Port SATA Storage Controller
+
+pci:v00008086d00000F27*
+ ID_PRODUCT_FROM_DATABASE=ValleyView 2-Port SATA Storage Controller
+
+pci:v00008086d00000F28*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPE Audio Controller
+
+pci:v00008086d00000F29*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPE Audio Controller
+
+pci:v00008086d00000F2A*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPE Audio Controller
+
+pci:v00008086d00000F2B*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPE Audio Controller
+
+pci:v00008086d00000F2E*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SATA RAID Storage Controller
+
+pci:v00008086d00000F2F*
+ ID_PRODUCT_FROM_DATABASE=ValleyView SATA RAID Storage Controller
+
+pci:v00008086d00000F30*
+ ID_PRODUCT_FROM_DATABASE=ValleyView Gen7
+
+pci:v00008086d00000F31*
+ ID_PRODUCT_FROM_DATABASE=ValleyView Gen7
+
+pci:v00008086d00000F32*
+ ID_PRODUCT_FROM_DATABASE=ValleyView Gen7
+
+pci:v00008086d00000F33*
+ ID_PRODUCT_FROM_DATABASE=ValleyView Gen7
+
+pci:v00008086d00000F34*
+ ID_PRODUCT_FROM_DATABASE=ValleyView USB Enhanced Host Controller
+
+pci:v00008086d00000F35*
+ ID_PRODUCT_FROM_DATABASE=ValleyView USB xHCI Host Controller
+
+pci:v00008086d00000F36*
+ ID_PRODUCT_FROM_DATABASE=ValleyView USB xHCI Host Controller
+
+pci:v00008086d00000F37*
+ ID_PRODUCT_FROM_DATABASE=ValleyView OTG
+
+pci:v00008086d00000F38*
+ ID_PRODUCT_FROM_DATABASE=ValleyView ISP
+
+pci:v00008086d00000F39*
+ ID_PRODUCT_FROM_DATABASE=ValleyView ISP
+
+pci:v00008086d00000F3A*
+ ID_PRODUCT_FROM_DATABASE=ValleyView ISP
+
+pci:v00008086d00000F3B*
+ ID_PRODUCT_FROM_DATABASE=ValleyView ISP
+
+pci:v00008086d00000F3C*
+ ID_PRODUCT_FROM_DATABASE=ValleyView ISP
+
+pci:v00008086d00000F3D*
+ ID_PRODUCT_FROM_DATABASE=ValleyView ISP
+
+pci:v00008086d00000F3E*
+ ID_PRODUCT_FROM_DATABASE=ValleyView ISP
+
+pci:v00008086d00000F3F*
+ ID_PRODUCT_FROM_DATABASE=ValleyView ISP
+
+pci:v00008086d00000F40*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 DMA Controller
+
+pci:v00008086d00000F41*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #1
+
+pci:v00008086d00000F42*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #2
+
+pci:v00008086d00000F43*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #3
+
+pci:v00008086d00000F44*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #4
+
+pci:v00008086d00000F45*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #5
+
+pci:v00008086d00000F46*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #6
+
+pci:v00008086d00000F47*
+ ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #7
+
+pci:v00008086d00000F48*
+ ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port
+
+pci:v00008086d00000F49*
+ ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port
+
+pci:v00008086d00000F4A*
+ ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port
+
+pci:v00008086d00000F4B*
+ ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port
+
+pci:v00008086d00000F4C*
+ ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port
+
+pci:v00008086d00000F4D*
+ ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port
+
+pci:v00008086d00000F4E*
+ ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port
+
+pci:v00008086d00000F4F*
+ ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port
+
+pci:v00008086d00000F50*
+ ID_PRODUCT_FROM_DATABASE=ValleyView MIPI-HSI Controller
+
+pci:v00008086d00001000*
+ ID_PRODUCT_FROM_DATABASE=82542 Gigabit Ethernet Controller (Fiber)
+
+pci:v00008086d00001000sv00000E11sd0000B0DF*
+ ID_PRODUCT_FROM_DATABASE=NC6132 Gigabit Ethernet Adapter (1000-SX)
+
+pci:v00008086d00001000sv00000E11sd0000B0E0*
+ ID_PRODUCT_FROM_DATABASE=NC6133 Gigabit Ethernet Adapter (1000-LX)
+
+pci:v00008086d00001000sv00000E11sd0000B123*
+ ID_PRODUCT_FROM_DATABASE=NC6134 Gigabit Ethernet Adapter (1000-LX)
+
+pci:v00008086d00001000sv00001014sd00000119*
+ ID_PRODUCT_FROM_DATABASE=Netfinity Gigabit Ethernet SX Adapter
+
+pci:v00008086d00001000sv00008086sd00001000*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 Gigabit Server Adapter
+
+pci:v00008086d00001001*
+ ID_PRODUCT_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Fiber)
+
+pci:v00008086d00001001sv00000E11sd0000004A*
+ ID_PRODUCT_FROM_DATABASE=NC6136 Gigabit Server Adapter
+
+pci:v00008086d00001001sv00001014sd000001EA*
+ ID_PRODUCT_FROM_DATABASE=Netfinity Gigabit Ethernet SX Adapter
+
+pci:v00008086d00001001sv00008086sd00001002*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 F Server Adapter
+
+pci:v00008086d00001001sv00008086sd00001003*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 F Server Adapter
+
+pci:v00008086d00001002*
+ ID_PRODUCT_FROM_DATABASE=Pro 100 LAN+Modem 56 Cardbus II
+
+pci:v00008086d00001002sv00008086sd0000200E*
+ ID_PRODUCT_FROM_DATABASE=Pro 100 LAN+Modem 56 Cardbus II
+
+pci:v00008086d00001002sv00008086sd00002013*
+ ID_PRODUCT_FROM_DATABASE=Pro 100 SR Mobile Combo Adapter
+
+pci:v00008086d00001002sv00008086sd00002017*
+ ID_PRODUCT_FROM_DATABASE=Pro 100 S Combo Mobile Adapter
+
+pci:v00008086d00001004*
+ ID_PRODUCT_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d00001004sv00000E11sd00000049*
+ ID_PRODUCT_FROM_DATABASE=NC7132 Gigabit Upgrade Module
+
+pci:v00008086d00001004sv00000E11sd0000B1A4*
+ ID_PRODUCT_FROM_DATABASE=NC7131 Gigabit Server Adapter
+
+pci:v00008086d00001004sv00001014sd000010F2*
+ ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet Server Adapter
+
+pci:v00008086d00001004sv00008086sd00001004*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 T Server Adapter
+
+pci:v00008086d00001004sv00008086sd00002004*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 T Server Adapter
+
+pci:v00008086d00001008*
+ ID_PRODUCT_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d00001008sv00001014sd00000269*
+ ID_PRODUCT_FROM_DATABASE=iSeries 1000/100/10 Ethernet Adapter
+
+pci:v00008086d00001008sv00001028sd0000011B*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1650/2550
+
+pci:v00008086d00001008sv00001028sd0000011C*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Network Connection
+
+pci:v00008086d00001008sv00008086sd00001107*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Server Adapter
+
+pci:v00008086d00001008sv00008086sd00002107*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Server Adapter
+
+pci:v00008086d00001008sv00008086sd00002110*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Desktop Adapter
+
+pci:v00008086d00001008sv00008086sd00003108*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Network Connection
+
+pci:v00008086d00001009*
+ ID_PRODUCT_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Fiber)
+
+pci:v00008086d00001009sv00001014sd00000268*
+ ID_PRODUCT_FROM_DATABASE=iSeries Gigabit Ethernet Adapter
+
+pci:v00008086d00001009sv00008086sd00001109*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 XF Server Adapter
+
+pci:v00008086d00001009sv00008086sd00002109*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 XF Server Adapter
+
+pci:v00008086d0000100A*
+ ID_PRODUCT_FROM_DATABASE=82540EM Gigabit Ethernet Controller
+
+pci:v00008086d0000100C*
+ ID_PRODUCT_FROM_DATABASE=82544GC Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d0000100Csv00008086sd00001112*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 T Desktop Adapter
+
+pci:v00008086d0000100Csv00008086sd00002112*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 T Desktop Adapter
+
+pci:v00008086d0000100D*
+ ID_PRODUCT_FROM_DATABASE=82544GC Gigabit Ethernet Controller (LOM)
+
+pci:v00008086d0000100Dsv00001028sd00000123*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Network Connection
+
+pci:v00008086d0000100Dsv00001079sd0000891F*
+ ID_PRODUCT_FROM_DATABASE=82544GC Based Network Connection
+
+pci:v00008086d0000100Dsv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00008086d0000100Dsv00008086sd0000110D*
+ ID_PRODUCT_FROM_DATABASE=82544GC Based Network Connection
+
+pci:v00008086d0000100E*
+ ID_PRODUCT_FROM_DATABASE=82540EM Gigabit Ethernet Controller
+
+pci:v00008086d0000100Esv00001014sd00000265*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d0000100Esv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d0000100Esv00001014sd0000026A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d0000100Esv00001028sd0000002E*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX260
+
+pci:v00008086d0000100Esv00001028sd00000134*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 600SC
+
+pci:v00008086d0000100Esv00001028sd00000151*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX270
+
+pci:v00008086d0000100Esv0000107Bsd00008920*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+
+pci:v00008086d0000100Esv00008086sd0000001E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+
+pci:v00008086d0000100Esv00008086sd0000002E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+
+pci:v00008086d0000100Esv00008086sd00001376*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Desktop Adapter
+
+pci:v00008086d0000100Esv00008086sd00001476*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Desktop Adapter
+
+pci:v00008086d0000100F*
+ ID_PRODUCT_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d0000100Fsv00001014sd00000269*
+ ID_PRODUCT_FROM_DATABASE=iSeries 1000/100/10 Ethernet Adapter
+
+pci:v00008086d0000100Fsv00001014sd0000028E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d0000100Fsv000015ADsd00000750*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Single Port Adapter
+
+pci:v00008086d0000100Fsv00008086sd00001000*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d0000100Fsv00008086sd00001001*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Adapter
+
+pci:v00008086d00001010*
+ ID_PRODUCT_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d00001010sv00000E11sd000000DB*
+ ID_PRODUCT_FROM_DATABASE=NC7170 Gigabit Server Adapter
+
+pci:v00008086d00001010sv00001014sd0000027C*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Network Adapter
+
+pci:v00008086d00001010sv000015ADsd00000760*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Adapter
+
+pci:v00008086d00001010sv000018FBsd00007872*
+ ID_PRODUCT_FROM_DATABASE=RESlink-X
+
+pci:v00008086d00001010sv00001FC1sd00000026*
+ ID_PRODUCT_FROM_DATABASE=Niagara 2260 Bypass Card
+
+pci:v00008086d00001010sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00008086d00001010sv00004C53sd000010A0*
+ ID_PRODUCT_FROM_DATABASE=CA3/CR3 mainboard
+
+pci:v00008086d00001010sv00008086sd00001011*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter
+
+pci:v00008086d00001010sv00008086sd00001012*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter
+
+pci:v00008086d00001010sv00008086sd0000101A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection
+
+pci:v00008086d00001010sv00008086sd00003424*
+ ID_PRODUCT_FROM_DATABASE=SE7501HG2 Mainboard
+
+pci:v00008086d00001011*
+ ID_PRODUCT_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Fiber)
+
+pci:v00008086d00001011sv00001014sd00000268*
+ ID_PRODUCT_FROM_DATABASE=iSeries Gigabit Ethernet Adapter
+
+pci:v00008086d00001011sv00008086sd00001002*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter
+
+pci:v00008086d00001011sv00008086sd00001003*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter (LX)
+
+pci:v00008086d00001012*
+ ID_PRODUCT_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Fiber)
+
+pci:v00008086d00001012sv00000E11sd000000DC*
+ ID_PRODUCT_FROM_DATABASE=NC6170 Gigabit Server Adapter
+
+pci:v00008086d00001012sv00008086sd00001012*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter
+
+pci:v00008086d00001013*
+ ID_PRODUCT_FROM_DATABASE=82541EI Gigabit Ethernet Controller
+
+pci:v00008086d00001013sv00008086sd00000013*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001013sv00008086sd00001013*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001013sv00008086sd00001113*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+
+pci:v00008086d00001014*
+ ID_PRODUCT_FROM_DATABASE=82541ER Gigabit Ethernet Controller
+
+pci:v00008086d00001014sv00008086sd00000014*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Connection
+
+pci:v00008086d00001014sv00008086sd00001014*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001015*
+ ID_PRODUCT_FROM_DATABASE=82540EM Gigabit Ethernet Controller (LOM)
+
+pci:v00008086d00001015sv00008086sd00001015*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001016*
+ ID_PRODUCT_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile)
+
+pci:v00008086d00001016sv00001014sd0000052C*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001016sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001016sv00008086sd00001016*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001017*
+ ID_PRODUCT_FROM_DATABASE=82540EP Gigabit Ethernet Controller
+
+pci:v00008086d00001017sv00008086sd00001017*
+ ID_PRODUCT_FROM_DATABASE=PR0/1000 MT Desktop Connection
+
+pci:v00008086d00001018*
+ ID_PRODUCT_FROM_DATABASE=82541EI Gigabit Ethernet Controller
+
+pci:v00008086d00001018sv00008086sd00001018*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001019*
+ ID_PRODUCT_FROM_DATABASE=82547EI Gigabit Ethernet Controller
+
+pci:v00008086d00001019sv00001458sd00001019*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d00001019sv00001458sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=Intel Gigabit Ethernet (Kenai II)
+
+pci:v00008086d00001019sv00008086sd00001019*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 CT Desktop Connection
+
+pci:v00008086d00001019sv00008086sd0000301F*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d00001019sv00008086sd00003025*
+ ID_PRODUCT_FROM_DATABASE=D875PBZ motherboard
+
+pci:v00008086d00001019sv00008086sd0000302C*
+ ID_PRODUCT_FROM_DATABASE=Intel 82865G Mainboard (D865GBF)
+
+pci:v00008086d00001019sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d0000101A*
+ ID_PRODUCT_FROM_DATABASE=82547EI Gigabit Ethernet Controller (Mobile)
+
+pci:v00008086d0000101Asv00008086sd0000101A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 CT Mobile Connection
+
+pci:v00008086d0000101D*
+ ID_PRODUCT_FROM_DATABASE=82546EB Gigabit Ethernet Controller
+
+pci:v00008086d0000101Dsv00008086sd00001000*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Quad Port Server Adapter
+
+pci:v00008086d0000101E*
+ ID_PRODUCT_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile)
+
+pci:v00008086d0000101Esv00001014sd00000549*
+ ID_PRODUCT_FROM_DATABASE=Thinkpad
+
+pci:v00008086d0000101Esv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d0000101Esv00008086sd0000101E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001026*
+ ID_PRODUCT_FROM_DATABASE=82545GM Gigabit Ethernet Controller
+
+pci:v00008086d00001026sv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d00001026sv00008086sd00001000*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Connection
+
+pci:v00008086d00001026sv00008086sd00001001*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Adapter
+
+pci:v00008086d00001026sv00008086sd00001002*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Adapter
+
+pci:v00008086d00001026sv00008086sd00001003*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Server Adapter
+
+pci:v00008086d00001026sv00008086sd00001026*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Connection
+
+pci:v00008086d00001027*
+ ID_PRODUCT_FROM_DATABASE=82545GM Gigabit Ethernet Controller
+
+pci:v00008086d00001027sv0000103Csd00003103*
+ ID_PRODUCT_FROM_DATABASE=NC310F PCI-X Gigabit Server Adapter
+
+pci:v00008086d00001027sv00008086sd00001001*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter(LX)
+
+pci:v00008086d00001027sv00008086sd00001002*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter(LX)
+
+pci:v00008086d00001027sv00008086sd00001003*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter(LX)
+
+pci:v00008086d00001027sv00008086sd00001027*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter
+
+pci:v00008086d00001028*
+ ID_PRODUCT_FROM_DATABASE=82545GM Gigabit Ethernet Controller
+
+pci:v00008086d00001028sv00008086sd00001028*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MB Server Connection
+
+pci:v00008086d00001029*
+ ID_PRODUCT_FROM_DATABASE=82559 Ethernet Controller
+
+pci:v00008086d00001030*
+ ID_PRODUCT_FROM_DATABASE=82559 InBusiness 10/100
+
+pci:v00008086d00001031*
+ ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller
+
+pci:v00008086d00001031sv00001014sd00000209*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00001031sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d00001031sv0000104Dsd0000813C*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-GRV616G
+
+pci:v00008086d00001031sv0000107Bsd00005350*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00001031sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00001031sv0000144Dsd0000C000*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00001031sv0000144Dsd0000C001*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00001031sv0000144Dsd0000C003*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00001031sv0000144Dsd0000C006*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4
+
+pci:v00008086d00001032*
+ ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE Ethernet Controller
+
+pci:v00008086d00001033*
+ ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller
+
+pci:v00008086d00001034*
+ ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VM Ethernet Controller
+
+pci:v00008086d00001035*
+ ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3)/82562EH (LOM) Ethernet Controller
+
+pci:v00008086d00001036*
+ ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) 82562EH Ethernet Controller
+
+pci:v00008086d00001037*
+ ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) Chipset Ethernet Controller
+
+pci:v00008086d00001038*
+ ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller
+
+pci:v00008086d00001038sv00000E11sd00000098*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v00008086d00001039*
+ ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VE (LOM) Ethernet Controller
+
+pci:v00008086d00001039sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d00001039sv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8 onboard ethernet ETH1
+
+pci:v00008086d0000103A*
+ ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VE (CNR) Ethernet Controller
+
+pci:v00008086d0000103B*
+ ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VM (LOM) Ethernet Controller
+
+pci:v00008086d0000103C*
+ ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VM (CNR) Ethernet Controller
+
+pci:v00008086d0000103D*
+ ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VE (MOB) Ethernet Controller
+
+pci:v00008086d0000103Dsv00001014sd00000522*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R40
+
+pci:v00008086d0000103Dsv00001028sd00002002*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00008086d0000103Dsv00008086sd0000103D*
+ ID_PRODUCT_FROM_DATABASE=82562EZ 10/100 Ethernet Controller
+
+pci:v00008086d0000103E*
+ ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VM (MOB) Ethernet Controller
+
+pci:v00008086d00001040*
+ ID_PRODUCT_FROM_DATABASE=536EP Data Fax Modem
+
+pci:v00008086d00001040sv000016BEsd00001040*
+ ID_PRODUCT_FROM_DATABASE=V.9X DSP Data Fax Modem
+
+pci:v00008086d00001043*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless LAN 2100 3B Mini PCI Adapter
+
+pci:v00008086d00001043sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d00001043sv00008086sd00002522*
+ ID_PRODUCT_FROM_DATABASE=Samsung X10/P30 integrated WLAN
+
+pci:v00008086d00001043sv00008086sd00002527*
+ ID_PRODUCT_FROM_DATABASE=MIM2000/Centrino
+
+pci:v00008086d00001043sv00008086sd00002561*
+ ID_PRODUCT_FROM_DATABASE=Dell Latitude D800
+
+pci:v00008086d00001043sv00008086sd00002581*
+ ID_PRODUCT_FROM_DATABASE=Toshiba Satellite M10
+
+pci:v00008086d00001048*
+ ID_PRODUCT_FROM_DATABASE=82597EX 10GbE Ethernet Controller
+
+pci:v00008086d00001048sv00008086sd0000A01F*
+ ID_PRODUCT_FROM_DATABASE=PRO/10GbE LR Server Adapter
+
+pci:v00008086d00001048sv00008086sd0000A11F*
+ ID_PRODUCT_FROM_DATABASE=PRO/10GbE LR Server Adapter
+
+pci:v00008086d00001049*
+ ID_PRODUCT_FROM_DATABASE=82566MM Gigabit Network Connection
+
+pci:v00008086d00001049sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00001049sv000017AAsd000020B9*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d0000104A*
+ ID_PRODUCT_FROM_DATABASE=82566DM Gigabit Network Connection
+
+pci:v00008086d0000104B*
+ ID_PRODUCT_FROM_DATABASE=82566DC Gigabit Network Connection
+
+pci:v00008086d0000104C*
+ ID_PRODUCT_FROM_DATABASE=82562V 10/100 Network Connection
+
+pci:v00008086d0000104D*
+ ID_PRODUCT_FROM_DATABASE=82566MC Gigabit Network Connection
+
+pci:v00008086d00001050*
+ ID_PRODUCT_FROM_DATABASE=82562EZ 10/100 Ethernet Controller
+
+pci:v00008086d00001050sv00001028sd0000019D*
+ ID_PRODUCT_FROM_DATABASE=Dimension 3000
+
+pci:v00008086d00001050sv00001462sd0000728C*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d00001050sv00001462sd0000758C*
+ ID_PRODUCT_FROM_DATABASE=MS-6758 (875P Neo)
+
+pci:v00008086d00001050sv00008086sd00003020*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d00001050sv00008086sd0000302F*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d00001050sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d00001051*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) integrated LAN Controller
+
+pci:v00008086d00001052*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection
+
+pci:v00008086d00001053*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection
+
+pci:v00008086d00001054*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection
+
+pci:v00008086d00001055*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection
+
+pci:v00008086d00001056*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection
+
+pci:v00008086d00001057*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection
+
+pci:v00008086d00001059*
+ ID_PRODUCT_FROM_DATABASE=82551QM Ethernet Controller
+
+pci:v00008086d0000105B*
+ ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d0000105E*
+ ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller
+
+pci:v00008086d0000105Esv0000103Csd00007044*
+ ID_PRODUCT_FROM_DATABASE=NC360T PCI Express Dual Port Gigabit Server Adapter
+
+pci:v00008086d0000105Esv0000103Csd0000704E*
+ ID_PRODUCT_FROM_DATABASE=Dual Port 1000Base-T (PCIe) [AD337A]
+
+pci:v00008086d0000105Esv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d0000105Esv00001775sd00006003*
+ ID_PRODUCT_FROM_DATABASE=Telum GE-QT
+
+pci:v00008086d0000105Esv00008086sd0000005E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Server Connection
+
+pci:v00008086d0000105Esv00008086sd0000105E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Network Connection
+
+pci:v00008086d0000105Esv00008086sd000010D5*
+ ID_PRODUCT_FROM_DATABASE=82571PT Gigabit PT Quad Port Server ExpressModule
+
+pci:v00008086d0000105Esv00008086sd0000115E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter
+
+pci:v00008086d0000105Esv00008086sd0000125E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter
+
+pci:v00008086d0000105Esv00008086sd0000135E*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter
+
+pci:v00008086d0000105F*
+ ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller
+
+pci:v00008086d0000105Fsv0000103Csd0000704F*
+ ID_PRODUCT_FROM_DATABASE=Dual Port 1000Base-SX (PCIe) [AD338A]
+
+pci:v00008086d0000105Fsv00008086sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter
+
+pci:v00008086d0000105Fsv00008086sd0000115F*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter
+
+pci:v00008086d0000105Fsv00008086sd0000125F*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter
+
+pci:v00008086d0000105Fsv00008086sd0000135F*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter
+
+pci:v00008086d00001060*
+ ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller
+
+pci:v00008086d00001060sv00008086sd00000060*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PB Dual Port Server Connection
+
+pci:v00008086d00001060sv00008086sd00001060*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PB Dual Port Server Connection
+
+pci:v00008086d00001064*
+ ID_PRODUCT_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller
+
+pci:v00008086d00001064sv00001043sd000080F8*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d00001065*
+ ID_PRODUCT_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller
+
+pci:v00008086d00001066*
+ ID_PRODUCT_FROM_DATABASE=82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller
+
+pci:v00008086d00001067*
+ ID_PRODUCT_FROM_DATABASE=82562 EM/EX/GX - PRO/100 VM Ethernet Controller
+
+pci:v00008086d00001068*
+ ID_PRODUCT_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile
+
+pci:v00008086d00001069*
+ ID_PRODUCT_FROM_DATABASE=82562EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile
+
+pci:v00008086d0000106A*
+ ID_PRODUCT_FROM_DATABASE=82562G - PRO/100 VE (LOM) Ethernet Controller
+
+pci:v00008086d0000106B*
+ ID_PRODUCT_FROM_DATABASE=82562G - PRO/100 VE Ethernet Controller Mobile
+
+pci:v00008086d00001075*
+ ID_PRODUCT_FROM_DATABASE=82547GI Gigabit Ethernet Controller
+
+pci:v00008086d00001075sv00001028sd00000165*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 750
+
+pci:v00008086d00001075sv00008086sd00000075*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 CT Network Connection
+
+pci:v00008086d00001075sv00008086sd00001075*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 CT Network Connection
+
+pci:v00008086d00001076*
+ ID_PRODUCT_FROM_DATABASE=82541GI Gigabit Ethernet Controller
+
+pci:v00008086d00001076sv00001028sd00000165*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001076sv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001076sv00001028sd0000019A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001076sv00001028sd0000106D*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001076sv00008086sd00000076*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001076sv00008086sd00001076*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection
+
+pci:v00008086d00001076sv00008086sd00001176*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+
+pci:v00008086d00001076sv00008086sd00001276*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Adapter
+
+pci:v00008086d00001077*
+ ID_PRODUCT_FROM_DATABASE=82541GI Gigabit Ethernet Controller
+
+pci:v00008086d00001077sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001077sv00008086sd00000077*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001077sv00008086sd00001077*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection
+
+pci:v00008086d00001078*
+ ID_PRODUCT_FROM_DATABASE=82541ER Gigabit Ethernet Controller
+
+pci:v00008086d00001078sv00008086sd00001078*
+ ID_PRODUCT_FROM_DATABASE=82541ER-based Network Connection
+
+pci:v00008086d00001079*
+ ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller
+
+pci:v00008086d00001079sv0000103Csd000012A6*
+ ID_PRODUCT_FROM_DATABASE=Dual Port 1000Base-T [A9900A]
+
+pci:v00008086d00001079sv0000103Csd000012CF*
+ ID_PRODUCT_FROM_DATABASE=Core Dual Port 1000Base-T [AB352A]
+
+pci:v00008086d00001079sv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer Gigabit Ethernet
+
+pci:v00008086d00001079sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d00001079sv00001FC1sd00000027*
+ ID_PRODUCT_FROM_DATABASE=Niagara 2261 Failover NIC
+
+pci:v00008086d00001079sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d00001079sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d00001079sv00008086sd00000079*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection
+
+pci:v00008086d00001079sv00008086sd00001079*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection
+
+pci:v00008086d00001079sv00008086sd00001179*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter
+
+pci:v00008086d00001079sv00008086sd0000117A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter
+
+pci:v00008086d0000107A*
+ ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller
+
+pci:v00008086d0000107Asv0000103Csd000012A8*
+ ID_PRODUCT_FROM_DATABASE=Dual Port 1000base-SX [A9899A]
+
+pci:v00008086d0000107Asv00008086sd0000107A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter
+
+pci:v00008086d0000107Asv00008086sd0000127A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter
+
+pci:v00008086d0000107B*
+ ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller
+
+pci:v00008086d0000107Bsv00008086sd0000007B*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MB Dual Port Server Connection
+
+pci:v00008086d0000107Bsv00008086sd0000107B*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MB Dual Port Server Connection
+
+pci:v00008086d0000107C*
+ ID_PRODUCT_FROM_DATABASE=82541PI Gigabit Ethernet Controller
+
+pci:v00008086d0000107Csv00008086sd00001376*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Desktop Adapter
+
+pci:v00008086d0000107Csv00008086sd00001476*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Desktop Adapter
+
+pci:v00008086d0000107D*
+ ID_PRODUCT_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d0000107Dsv00008086sd00001082*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Server Adapter
+
+pci:v00008086d0000107Dsv00008086sd00001084*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Server Adapter
+
+pci:v00008086d0000107Dsv00008086sd00001092*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Server Adapter
+
+pci:v00008086d0000107E*
+ ID_PRODUCT_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Fiber)
+
+pci:v00008086d0000107Esv00008086sd00001084*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Server Adapter
+
+pci:v00008086d0000107Esv00008086sd00001085*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Server Adapter
+
+pci:v00008086d0000107Esv00008086sd00001094*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Server Adapter
+
+pci:v00008086d0000107F*
+ ID_PRODUCT_FROM_DATABASE=82572EI Gigabit Ethernet Controller
+
+pci:v00008086d00001080*
+ ID_PRODUCT_FROM_DATABASE=FA82537EP 56K V.92 Data/Fax Modem PCI
+
+pci:v00008086d00001081*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB LAN Controller Copper
+
+pci:v00008086d00001082*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB LAN Controller fiber
+
+pci:v00008086d00001083*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB LAN Controller SERDES
+
+pci:v00008086d00001084*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB IDE Redirection
+
+pci:v00008086d00001085*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB Serial Port Redirection
+
+pci:v00008086d00001086*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB IPMI/KCS0
+
+pci:v00008086d00001087*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB UHCI Redirection
+
+pci:v00008086d00001089*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB BT
+
+pci:v00008086d0000108A*
+ ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller
+
+pci:v00008086d0000108Asv00008086sd0000108A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 P Dual Port Server Adapter
+
+pci:v00008086d0000108Asv00008086sd0000118A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 P Dual Port Server Adapter
+
+pci:v00008086d0000108B*
+ ID_PRODUCT_FROM_DATABASE=82573V Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d0000108Bsv00001462sd0000176C*
+ ID_PRODUCT_FROM_DATABASE=on board on MSI 945P - NEO (MS-7176)
+
+pci:v00008086d0000108C*
+ ID_PRODUCT_FROM_DATABASE=82573E Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d0000108E*
+ ID_PRODUCT_FROM_DATABASE=82573E KCS (Active Management)
+
+pci:v00008086d0000108F*
+ ID_PRODUCT_FROM_DATABASE=Active Management Technology - SOL
+
+pci:v00008086d00001091*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection
+
+pci:v00008086d00001092*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection
+
+pci:v00008086d00001093*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection
+
+pci:v00008086d00001094*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection
+
+pci:v00008086d00001095*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection
+
+pci:v00008086d00001096*
+ ID_PRODUCT_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d00001096sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d00001096sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d00001097*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB DPT LAN Controller (Fiber)
+
+pci:v00008086d00001098*
+ ID_PRODUCT_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Serdes)
+
+pci:v00008086d00001099*
+ ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d00001099sv00008086sd00001099*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter
+
+pci:v00008086d0000109A*
+ ID_PRODUCT_FROM_DATABASE=82573L Gigabit Ethernet Controller
+
+pci:v00008086d0000109Asv00001179sd0000FF10*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PL
+
+pci:v00008086d0000109Asv000017AAsd00002001*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60
+
+pci:v00008086d0000109Asv000017AAsd0000207E*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad X60s
+
+pci:v00008086d0000109Asv00008086sd0000109A*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PL Network Connection
+
+pci:v00008086d0000109Asv00008086sd0000309C*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D945GTP
+
+pci:v00008086d0000109Asv00008086sd000030A5*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D975XBX
+
+pci:v00008086d0000109B*
+ ID_PRODUCT_FROM_DATABASE=82546GB PRO/1000 GF Quad Port Server Adapter
+
+pci:v00008086d0000109E*
+ ID_PRODUCT_FROM_DATABASE=82597EX 10GbE Ethernet Controller
+
+pci:v00008086d0000109Esv00008086sd0000A01F*
+ ID_PRODUCT_FROM_DATABASE=PRO/10GbE CX4 Server Adapter
+
+pci:v00008086d0000109Esv00008086sd0000A11F*
+ ID_PRODUCT_FROM_DATABASE=PRO/10GbE CX4 Server Adapter
+
+pci:v00008086d000010A0*
+ ID_PRODUCT_FROM_DATABASE=82571EB PRO/1000 AT Quad Port Bypass Adapter
+
+pci:v00008086d000010A1*
+ ID_PRODUCT_FROM_DATABASE=82571EB PRO/1000 AF Quad Port Bypass Adapter
+
+pci:v00008086d000010A4*
+ ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller
+
+pci:v00008086d000010A4sv00008086sd000010A4*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Quad Port Server Adapter
+
+pci:v00008086d000010A4sv00008086sd000011A4*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Quad Port Server Adapter
+
+pci:v00008086d000010A5*
+ ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Fiber)
+
+pci:v00008086d000010A5sv00008086sd000010A5*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Quad Port Server Adapter
+
+pci:v00008086d000010A5sv00008086sd000010A6*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Quad Port Server Adapter
+
+pci:v00008086d000010A6*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit Dummy Function
+
+pci:v00008086d000010A7*
+ ID_PRODUCT_FROM_DATABASE=82575EB Gigabit Network Connection
+
+pci:v00008086d000010A7sv00008086sd000010A8*
+ ID_PRODUCT_FROM_DATABASE=82575EB Gigabit Riser Card
+
+pci:v00008086d000010A9*
+ ID_PRODUCT_FROM_DATABASE=82575EB Gigabit Backplane Connection
+
+pci:v00008086d000010B0*
+ ID_PRODUCT_FROM_DATABASE=82573L PRO/1000 PL Network Connection
+
+pci:v00008086d000010B2*
+ ID_PRODUCT_FROM_DATABASE=82573V PRO/1000 PM Network Connection
+
+pci:v00008086d000010B3*
+ ID_PRODUCT_FROM_DATABASE=82573E PRO/1000 PM Network Connection
+
+pci:v00008086d000010B4*
+ ID_PRODUCT_FROM_DATABASE=82573L PRO/1000 PL Network Connection
+
+pci:v00008086d000010B5*
+ ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d000010B5sv0000103Csd00003109*
+ ID_PRODUCT_FROM_DATABASE=NC340T PCI-X Quad-port Gigabit Server Adapter
+
+pci:v00008086d000010B5sv00008086sd00001099*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter
+
+pci:v00008086d000010B5sv00008086sd00001199*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter
+
+pci:v00008086d000010B6*
+ ID_PRODUCT_FROM_DATABASE=82598 10GbE PCI-Express Ethernet Controller
+
+pci:v00008086d000010B9*
+ ID_PRODUCT_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d000010B9sv0000103Csd0000704A*
+ ID_PRODUCT_FROM_DATABASE=HP 110T PCIe Gigabit Server Adapter
+
+pci:v00008086d000010B9sv00008086sd00001083*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Desktop Adapter
+
+pci:v00008086d000010B9sv00008086sd00001093*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Desktop Adapter
+
+pci:v00008086d000010BA*
+ ID_PRODUCT_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d000010BB*
+ ID_PRODUCT_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Serdes)
+
+pci:v00008086d000010BC*
+ ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper)
+
+pci:v00008086d000010BCsv0000103Csd0000704B*
+ ID_PRODUCT_FROM_DATABASE=NC364T PCI Express Quad Port Gigabit Server Adapter
+
+pci:v00008086d000010BCsv0000108Esd000011BC*
+ ID_PRODUCT_FROM_DATABASE=x4 PCI-Express Quad Gigabit Ethernet UTP Low Profile Adapter
+
+pci:v00008086d000010BCsv00008086sd000010BC*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Quad Port LP Server Adapter
+
+pci:v00008086d000010BCsv00008086sd000011BC*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Quad Port LP Server Adapter
+
+pci:v00008086d000010BD*
+ ID_PRODUCT_FROM_DATABASE=82566DM-2 Gigabit Network Connection
+
+pci:v00008086d000010BDsv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 755
+
+pci:v00008086d000010BF*
+ ID_PRODUCT_FROM_DATABASE=82567LF Gigabit Network Connection
+
+pci:v00008086d000010C0*
+ ID_PRODUCT_FROM_DATABASE=82562V-2 10/100 Network Connection
+
+pci:v00008086d000010C0sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d000010C2*
+ ID_PRODUCT_FROM_DATABASE=82562G-2 10/100 Network Connection
+
+pci:v00008086d000010C3*
+ ID_PRODUCT_FROM_DATABASE=82562GT-2 10/100 Network Connection
+
+pci:v00008086d000010C4*
+ ID_PRODUCT_FROM_DATABASE=82562GT 10/100 Network Connection
+
+pci:v00008086d000010C5*
+ ID_PRODUCT_FROM_DATABASE=82562G 10/100 Network Connection
+
+pci:v00008086d000010C6*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection
+
+pci:v00008086d000010C6sv00008086sd0000A05F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Dual Port Server Adapter
+
+pci:v00008086d000010C6sv00008086sd0000A15F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Dual Port Server Adapter
+
+pci:v00008086d000010C7*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection
+
+pci:v00008086d000010C7sv00001014sd0000037F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Server Adapter
+
+pci:v00008086d000010C7sv00001014sd00000380*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF LR Server Adapter
+
+pci:v00008086d000010C7sv00008086sd0000A05F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Server Adapter
+
+pci:v00008086d000010C7sv00008086sd0000A15F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Server Adapter
+
+pci:v00008086d000010C7sv00008086sd0000A16F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Server Adapter
+
+pci:v00008086d000010C8*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT Network Connection
+
+pci:v00008086d000010C8sv00008086sd0000A10C*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit AT Server Adapter
+
+pci:v00008086d000010C8sv00008086sd0000A11C*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit AT Server Adapter
+
+pci:v00008086d000010C8sv00008086sd0000A12C*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit AT Server Adapter
+
+pci:v00008086d000010C9*
+ ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection
+
+pci:v00008086d000010C9sv0000103Csd000031EF*
+ ID_PRODUCT_FROM_DATABASE=NC362i Integrated Dual port Gigabit Server Adapter
+
+pci:v00008086d000010C9sv0000103Csd0000323F*
+ ID_PRODUCT_FROM_DATABASE=NC362i Integrated Dual port Gigabit Server Adapter
+
+pci:v00008086d000010C9sv000010A9sd00008028*
+ ID_PRODUCT_FROM_DATABASE=UV-BaseIO dual-port GbE
+
+pci:v00008086d000010C9sv000013A3sd00000037*
+ ID_PRODUCT_FROM_DATABASE=DS4100 Secure Multi-Gigabit Server Adapter with Compression
+
+pci:v00008086d000010C9sv000015D9sd0000A811*
+ ID_PRODUCT_FROM_DATABASE=H8DGU
+
+pci:v00008086d000010C9sv00008086sd0000A01C*
+ ID_PRODUCT_FROM_DATABASE=Gigabit ET Dual Port Server Adapter
+
+pci:v00008086d000010C9sv00008086sd0000A03C*
+ ID_PRODUCT_FROM_DATABASE=Gigabit ET Dual Port Server Adapter
+
+pci:v00008086d000010C9sv00008086sd0000A04C*
+ ID_PRODUCT_FROM_DATABASE=Gigabit ET Dual Port Server Adapter
+
+pci:v00008086d000010CA*
+ ID_PRODUCT_FROM_DATABASE=82576 Virtual Function
+
+pci:v00008086d000010CB*
+ ID_PRODUCT_FROM_DATABASE=82567V Gigabit Network Connection
+
+pci:v00008086d000010CC*
+ ID_PRODUCT_FROM_DATABASE=82567LM-2 Gigabit Network Connection
+
+pci:v00008086d000010CD*
+ ID_PRODUCT_FROM_DATABASE=82567LF-2 Gigabit Network Connection
+
+pci:v00008086d000010CE*
+ ID_PRODUCT_FROM_DATABASE=82567V-2 Gigabit Network Connection
+
+pci:v00008086d000010D3*
+ ID_PRODUCT_FROM_DATABASE=82574L Gigabit Network Connection
+
+pci:v00008086d000010D3sv0000103Csd00003250*
+ ID_PRODUCT_FROM_DATABASE=NC112T PCI Express single Port Gigabit Server Adapter
+
+pci:v00008086d000010D3sv000010A9sd00008029*
+ ID_PRODUCT_FROM_DATABASE=Prism XL Single Port Gigabit Ethernet
+
+pci:v00008086d000010D3sv00008086sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Gigabit CT2 Desktop Adapter
+
+pci:v00008086d000010D3sv00008086sd0000A01F*
+ ID_PRODUCT_FROM_DATABASE=Gigabit CT Desktop Adapter
+
+pci:v00008086d000010D3sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d000010D3sv0000E4BFsd000050C2*
+ ID_PRODUCT_FROM_DATABASE=PC2-LIMBO
+
+pci:v00008086d000010D4*
+ ID_PRODUCT_FROM_DATABASE=Matrox Concord GE (customized Intel 82574)
+
+pci:v00008086d000010D5*
+ ID_PRODUCT_FROM_DATABASE=82571PT Gigabit PT Quad Port Server ExpressModule
+
+pci:v00008086d000010D6*
+ ID_PRODUCT_FROM_DATABASE=82575GB Gigabit Network Connection
+
+pci:v00008086d000010D6sv00008086sd000010D6*
+ ID_PRODUCT_FROM_DATABASE=Gigabit VT Quad Port Server Adapter
+
+pci:v00008086d000010D6sv00008086sd0000145A*
+ ID_PRODUCT_FROM_DATABASE=Gigabit VT Quad Port Server Adapter
+
+pci:v00008086d000010D6sv00008086sd0000147A*
+ ID_PRODUCT_FROM_DATABASE=Gigabit VT Quad Port Server Adapter
+
+pci:v00008086d000010D8*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit Unprogrammed
+
+pci:v00008086d000010D9*
+ ID_PRODUCT_FROM_DATABASE=82571EB Dual Port Gigabit Mezzanine Adapter
+
+pci:v00008086d000010D9sv0000103Csd00001716*
+ ID_PRODUCT_FROM_DATABASE=NC360m Dual Port 1GbE BL-c Adapter
+
+pci:v00008086d000010DA*
+ ID_PRODUCT_FROM_DATABASE=82571EB Quad Port Gigabit Mezzanine Adapter
+
+pci:v00008086d000010DAsv0000103Csd00001717*
+ ID_PRODUCT_FROM_DATABASE=NC364m Quad Port 1GbE BL-c Adapter
+
+pci:v00008086d000010DB*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit Dual Port Network Connection
+
+pci:v00008086d000010DD*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT CX4 Network Connection
+
+pci:v00008086d000010DE*
+ ID_PRODUCT_FROM_DATABASE=82567LM-3 Gigabit Network Connection
+
+pci:v00008086d000010DF*
+ ID_PRODUCT_FROM_DATABASE=82567LF-3 Gigabit Network Connection
+
+pci:v00008086d000010E1*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection
+
+pci:v00008086d000010E1sv00008086sd0000A15F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit SR Dual Port Express Module
+
+pci:v00008086d000010E2*
+ ID_PRODUCT_FROM_DATABASE=82575GB Gigabit Network Connection
+
+pci:v00008086d000010E2sv00008086sd000010E2*
+ ID_PRODUCT_FROM_DATABASE=Gigabit VT Quad Port Server Adapter
+
+pci:v00008086d000010E5*
+ ID_PRODUCT_FROM_DATABASE=82567LM-4 Gigabit Network Connection
+
+pci:v00008086d000010E6*
+ ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection
+
+pci:v00008086d000010E6sv00008086sd0000A01F*
+ ID_PRODUCT_FROM_DATABASE=Gigabit EF Dual Port Server Adapter
+
+pci:v00008086d000010E6sv00008086sd0000A02F*
+ ID_PRODUCT_FROM_DATABASE=Gigabit EF Dual Port Server Adapter
+
+pci:v00008086d000010E7*
+ ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection
+
+pci:v00008086d000010E7sv0000103Csd000031FF*
+ ID_PRODUCT_FROM_DATABASE=NC362i Integrated Dual Port BL-c Gigabit Server Adapter
+
+pci:v00008086d000010E8*
+ ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection
+
+pci:v00008086d000010E8sv00008086sd0000A02B*
+ ID_PRODUCT_FROM_DATABASE=Gigabit ET Quad Port Server Adapter
+
+pci:v00008086d000010E8sv00008086sd0000A02C*
+ ID_PRODUCT_FROM_DATABASE=Gigabit ET Quad Port Server Adapter
+
+pci:v00008086d000010EA*
+ ID_PRODUCT_FROM_DATABASE=82577LM Gigabit Network Connection
+
+pci:v00008086d000010EAsv00001028sd0000040A*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6410
+
+pci:v00008086d000010EAsv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d000010EAsv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d000010EB*
+ ID_PRODUCT_FROM_DATABASE=82577LC Gigabit Network Connection
+
+pci:v00008086d000010EC*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT CX4 Network Connection
+
+pci:v00008086d000010ECsv00008086sd0000A01F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit CX4 Dual Port Server Adapter
+
+pci:v00008086d000010ECsv00008086sd0000A11F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit CX4 Dual Port Server Adapter
+
+pci:v00008086d000010ED*
+ ID_PRODUCT_FROM_DATABASE=82599 Ethernet Controller Virtual Function
+
+pci:v00008086d000010EF*
+ ID_PRODUCT_FROM_DATABASE=82578DM Gigabit Network Connection
+
+pci:v00008086d000010EFsv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d000010F0*
+ ID_PRODUCT_FROM_DATABASE=82578DC Gigabit Network Connection
+
+pci:v00008086d000010F1*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection
+
+pci:v00008086d000010F1sv00008086sd0000A20F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit AF DA Dual Port Server Adapter
+
+pci:v00008086d000010F1sv00008086sd0000A21F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit AF DA Dual Port Server Adapter
+
+pci:v00008086d000010F4*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection
+
+pci:v00008086d000010F4sv00008086sd0000106F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF LR Server Adapter
+
+pci:v00008086d000010F4sv00008086sd0000A06F*
+ ID_PRODUCT_FROM_DATABASE=10-Gigabit XF LR Server Adapter
+
+pci:v00008086d000010F5*
+ ID_PRODUCT_FROM_DATABASE=82567LM Gigabit Network Connection
+
+pci:v00008086d000010F6*
+ ID_PRODUCT_FROM_DATABASE=82574L Gigabit Network Connection
+
+pci:v00008086d000010F7*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit KX4 Network Connection
+
+pci:v00008086d000010F7sv0000108Esd00007B12*
+ ID_PRODUCT_FROM_DATABASE=Sun Dual 10GbE PCIe 2.0 FEM
+
+pci:v00008086d000010F7sv00008086sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Mezzanine Adapter X520-KX4-2
+
+pci:v00008086d000010F8*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit Dual Port Backplane Connection
+
+pci:v00008086d000010F8sv00001028sd00001F63*
+ ID_PRODUCT_FROM_DATABASE=10GbE 2P X520k bNDC
+
+pci:v00008086d000010F8sv0000103Csd000017D2*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560M Adapter
+
+pci:v00008086d000010F8sv0000103Csd000018D0*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560FLB Adapter
+
+pci:v00008086d000010F8sv00008086sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=Ethernet X520 10GbE Dual Port KX4-KR Mezz
+
+pci:v00008086d000010F9*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit CX4 Dual Port Network Connection
+
+pci:v00008086d000010FB*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit SFI/SFP+ Network Connection
+
+pci:v00008086d000010FBsv00001028sd00001F72*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10G 4P X520/I350 rNDC
+
+pci:v00008086d000010FBsv0000103Csd000017D0*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560FLR-SFP+ Adapter
+
+pci:v00008086d000010FBsv0000103Csd000017D2*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560M Adapter
+
+pci:v00008086d000010FBsv0000103Csd000017D3*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560SFP+ Adapter
+
+pci:v00008086d000010FBsv0000108Esd00007B11*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2
+
+pci:v00008086d000010FBsv00001734sd000011A9*
+ ID_PRODUCT_FROM_DATABASE=10 Gigabit Dual Port Network Connection
+
+pci:v00008086d000010FBsv00008086sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-DA2
+
+pci:v00008086d000010FBsv00008086sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2
+
+pci:v00008086d000010FBsv00008086sd00000006*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-1
+
+pci:v00008086d000010FBsv00008086sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-1
+
+pci:v00008086d000010FBsv00008086sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2
+
+pci:v00008086d000010FBsv00008086sd00007A11*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2
+
+pci:v00008086d000010FBsv00008086sd00007A12*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2
+
+pci:v00008086d000010FC*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit XAUI/BX4 Network Connection
+
+pci:v00008086d000010FE*
+ ID_PRODUCT_FROM_DATABASE=82552 10/100 Network Connection
+
+pci:v00008086d00001107*
+ ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter (LX)
+
+pci:v00008086d00001130*
+ ID_PRODUCT_FROM_DATABASE=82815 815 Chipset Host Bridge and Memory Controller Hub
+
+pci:v00008086d00001130sv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX
+
+pci:v00008086d00001130sv00001043sd00008027*
+ ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard
+
+pci:v00008086d00001130sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00008086d00001130sv00008086sd00004532*
+ ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard
+
+pci:v00008086d00001130sv00008086sd00004557*
+ ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard
+
+pci:v00008086d00001131*
+ ID_PRODUCT_FROM_DATABASE=82815 815 Chipset AGP Bridge
+
+pci:v00008086d00001132*
+ ID_PRODUCT_FROM_DATABASE=82815 Chipset Graphics Controller (CGC)
+
+pci:v00008086d00001132sv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX
+
+pci:v00008086d00001132sv0000103Csd00002001*
+ ID_PRODUCT_FROM_DATABASE=e-pc 40
+
+pci:v00008086d00001132sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00008086d00001132sv00008086sd00004532*
+ ID_PRODUCT_FROM_DATABASE=D815EEA2 Mainboard
+
+pci:v00008086d00001132sv00008086sd00004541*
+ ID_PRODUCT_FROM_DATABASE=D815EEA Motherboard
+
+pci:v00008086d00001132sv00008086sd00004557*
+ ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard
+
+pci:v00008086d00001161*
+ ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub Advanced Programmable Interrupt Controller
+
+pci:v00008086d00001161sv00008086sd00001161*
+ ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub APIC
+
+pci:v00008086d00001162*
+ ID_PRODUCT_FROM_DATABASE=Xscale 80200 Big Endian Companion Chip
+
+pci:v00008086d00001200*
+ ID_PRODUCT_FROM_DATABASE=IXP1200 Network Processor
+
+pci:v00008086d00001200sv0000172Asd00000000*
+ ID_PRODUCT_FROM_DATABASE=AEP SSL Accelerator
+
+pci:v00008086d00001209*
+ ID_PRODUCT_FROM_DATABASE=8255xER/82551IT Fast Ethernet Controller
+
+pci:v00008086d00001209sv0000140Bsd00000610*
+ ID_PRODUCT_FROM_DATABASE=PMC610 quad Ethernet board
+
+pci:v00008086d00001209sv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v00008086d00001209sv00004C53sd00001051*
+ ID_PRODUCT_FROM_DATABASE=CE7 mainboard
+
+pci:v00008086d00001209sv00004C53sd00001070*
+ ID_PRODUCT_FROM_DATABASE=PC6 mainboard
+
+pci:v00008086d00001221*
+ ID_PRODUCT_FROM_DATABASE=82092AA PCI to PCMCIA Bridge
+
+pci:v00008086d00001222*
+ ID_PRODUCT_FROM_DATABASE=82092AA IDE Controller
+
+pci:v00008086d00001223*
+ ID_PRODUCT_FROM_DATABASE=SAA7116
+
+pci:v00008086d00001225*
+ ID_PRODUCT_FROM_DATABASE=82452KX/GX [Orion]
+
+pci:v00008086d00001226*
+ ID_PRODUCT_FROM_DATABASE=82596 PRO/10 PCI
+
+pci:v00008086d00001227*
+ ID_PRODUCT_FROM_DATABASE=82865 EtherExpress PRO/100A
+
+pci:v00008086d00001228*
+ ID_PRODUCT_FROM_DATABASE=82556 EtherExpress PRO/100 Smart
+
+pci:v00008086d00001229*
+ ID_PRODUCT_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100
+
+pci:v00008086d00001229sv00000E11sd00003001*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+
+pci:v00008086d00001229sv00000E11sd00003002*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+
+pci:v00008086d00001229sv00000E11sd00003003*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+
+pci:v00008086d00001229sv00000E11sd00003004*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+
+pci:v00008086d00001229sv00000E11sd00003005*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+
+pci:v00008086d00001229sv00000E11sd00003006*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+
+pci:v00008086d00001229sv00000E11sd00003007*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+
+pci:v00008086d00001229sv00000E11sd0000B01E*
+ ID_PRODUCT_FROM_DATABASE=NC3120 Fast Ethernet NIC
+
+pci:v00008086d00001229sv00000E11sd0000B01F*
+ ID_PRODUCT_FROM_DATABASE=NC3122 Fast Ethernet NIC (dual port)
+
+pci:v00008086d00001229sv00000E11sd0000B02F*
+ ID_PRODUCT_FROM_DATABASE=NC1120 Ethernet NIC
+
+pci:v00008086d00001229sv00000E11sd0000B04A*
+ ID_PRODUCT_FROM_DATABASE=Netelligent 10/100TX NIC with Wake on LAN
+
+pci:v00008086d00001229sv00000E11sd0000B0C6*
+ ID_PRODUCT_FROM_DATABASE=NC3161 Fast Ethernet NIC (embedded, WOL)
+
+pci:v00008086d00001229sv00000E11sd0000B0C7*
+ ID_PRODUCT_FROM_DATABASE=NC3160 Fast Ethernet NIC (embedded)
+
+pci:v00008086d00001229sv00000E11sd0000B0D7*
+ ID_PRODUCT_FROM_DATABASE=NC3121 Fast Ethernet NIC (WOL)
+
+pci:v00008086d00001229sv00000E11sd0000B0DD*
+ ID_PRODUCT_FROM_DATABASE=NC3131 Fast Ethernet NIC (dual port)
+
+pci:v00008086d00001229sv00000E11sd0000B0DE*
+ ID_PRODUCT_FROM_DATABASE=NC3132 Fast Ethernet Module (dual port)
+
+pci:v00008086d00001229sv00000E11sd0000B0E1*
+ ID_PRODUCT_FROM_DATABASE=NC3133 Fast Ethernet Module (100-FX)
+
+pci:v00008086d00001229sv00000E11sd0000B134*
+ ID_PRODUCT_FROM_DATABASE=NC3163 Fast Ethernet NIC (embedded, WOL)
+
+pci:v00008086d00001229sv00000E11sd0000B13C*
+ ID_PRODUCT_FROM_DATABASE=NC3162 Fast Ethernet NIC (embedded)
+
+pci:v00008086d00001229sv00000E11sd0000B144*
+ ID_PRODUCT_FROM_DATABASE=NC3123 Fast Ethernet NIC (WOL)
+
+pci:v00008086d00001229sv00000E11sd0000B163*
+ ID_PRODUCT_FROM_DATABASE=NC3134 Fast Ethernet NIC (dual port)
+
+pci:v00008086d00001229sv00000E11sd0000B164*
+ ID_PRODUCT_FROM_DATABASE=NC3135 Fast Ethernet Upgrade Module (dual port)
+
+pci:v00008086d00001229sv00000E11sd0000B1A4*
+ ID_PRODUCT_FROM_DATABASE=NC7131 Gigabit Server Adapter
+
+pci:v00008086d00001229sv00001014sd0000005C*
+ ID_PRODUCT_FROM_DATABASE=82558B Ethernet Pro 10/100
+
+pci:v00008086d00001229sv00001014sd000001BC*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LAN On Motherboard
+
+pci:v00008086d00001229sv00001014sd000001F1*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet Server Adapter
+
+pci:v00008086d00001229sv00001014sd000001F2*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet Server Adapter
+
+pci:v00008086d00001229sv00001014sd00000207*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Pro/100 S
+
+pci:v00008086d00001229sv00001014sd00000232*
+ ID_PRODUCT_FROM_DATABASE=10/100 Dual Port Server Adapter
+
+pci:v00008086d00001229sv00001014sd0000023A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R30
+
+pci:v00008086d00001229sv00001014sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Netfinity 10/100
+
+pci:v00008086d00001229sv00001014sd00002205*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A22p
+
+pci:v00008086d00001229sv00001014sd0000305C*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Management Adapter
+
+pci:v00008086d00001229sv00001014sd0000405C*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Adapter with Alert on LAN
+
+pci:v00008086d00001229sv00001014sd0000505C*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Secure Management Adapter
+
+pci:v00008086d00001229sv00001014sd0000605C*
+ ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Secure Management Adapter
+
+pci:v00008086d00001229sv00001014sd0000705C*
+ ID_PRODUCT_FROM_DATABASE=10/100 Netfinity 10/100 Ethernet Security Adapter
+
+pci:v00008086d00001229sv00001014sd0000805C*
+ ID_PRODUCT_FROM_DATABASE=10/100 Netfinity 10/100 Ethernet Security Adapter
+
+pci:v00008086d00001229sv00001028sd0000009B*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet Server Adapter
+
+pci:v00008086d00001229sv00001028sd000000CE*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet Server Adapter
+
+pci:v00008086d00001229sv00001033sd00008000*
+ ID_PRODUCT_FROM_DATABASE=PC-9821X-B06
+
+pci:v00008086d00001229sv00001033sd00008016*
+ ID_PRODUCT_FROM_DATABASE=PK-UG-X006
+
+pci:v00008086d00001229sv00001033sd0000801F*
+ ID_PRODUCT_FROM_DATABASE=PK-UG-X006
+
+pci:v00008086d00001229sv00001033sd00008026*
+ ID_PRODUCT_FROM_DATABASE=PK-UG-X006
+
+pci:v00008086d00001229sv00001033sd00008063*
+ ID_PRODUCT_FROM_DATABASE=82559-based Fast Ethernet Adapter
+
+pci:v00008086d00001229sv00001033sd00008064*
+ ID_PRODUCT_FROM_DATABASE=82559-based Fast Ethernet Adapter
+
+pci:v00008086d00001229sv0000103Csd000010C0*
+ ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX
+
+pci:v00008086d00001229sv0000103Csd000010C3*
+ ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX
+
+pci:v00008086d00001229sv0000103Csd000010CA*
+ ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX
+
+pci:v00008086d00001229sv0000103Csd000010CB*
+ ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX
+
+pci:v00008086d00001229sv0000103Csd000010E3*
+ ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX
+
+pci:v00008086d00001229sv0000103Csd000010E4*
+ ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX
+
+pci:v00008086d00001229sv0000103Csd00001200*
+ ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX
+
+pci:v00008086d00001229sv0000108Esd000010CF*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100(B)
+
+pci:v00008086d00001229sv000010C3sd00001100*
+ ID_PRODUCT_FROM_DATABASE=SmartEther100 SC1100
+
+pci:v00008086d00001229sv000010CFsd00001115*
+ ID_PRODUCT_FROM_DATABASE=8255x-based Ethernet Adapter (10/100)
+
+pci:v00008086d00001229sv000010CFsd00001143*
+ ID_PRODUCT_FROM_DATABASE=8255x-based Ethernet Adapter (10/100)
+
+pci:v00008086d00001229sv0000110Asd0000008B*
+ ID_PRODUCT_FROM_DATABASE=82551QM Fast Ethernet Multifuction PCI/CardBus Controller
+
+pci:v00008086d00001229sv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8 onboard ethernet ETH2
+
+pci:v00008086d00001229sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=8255x-based Ethernet Adapter (10/100)
+
+pci:v00008086d00001229sv00001179sd00000002*
+ ID_PRODUCT_FROM_DATABASE=PCI FastEther LAN on Docker
+
+pci:v00008086d00001229sv00001179sd00000003*
+ ID_PRODUCT_FROM_DATABASE=8255x-based Fast Ethernet
+
+pci:v00008086d00001229sv00001259sd00002560*
+ ID_PRODUCT_FROM_DATABASE=AT-2560 100
+
+pci:v00008086d00001229sv00001259sd00002561*
+ ID_PRODUCT_FROM_DATABASE=AT-2560 100 FX Ethernet Adapter
+
+pci:v00008086d00001229sv00001266sd00000001*
+ ID_PRODUCT_FROM_DATABASE=NE10/100 Adapter
+
+pci:v00008086d00001229sv000013E9sd00001000*
+ ID_PRODUCT_FROM_DATABASE=6221L-4U
+
+pci:v00008086d00001229sv0000144Dsd00002501*
+ ID_PRODUCT_FROM_DATABASE=SEM-2000 MiniPCI LAN Adapter
+
+pci:v00008086d00001229sv0000144Dsd00002502*
+ ID_PRODUCT_FROM_DATABASE=SEM-2100IL MiniPCI LAN Adapter
+
+pci:v00008086d00001229sv00001668sd00001100*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem)
+
+pci:v00008086d00001229sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00001229sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d00001229sv00004C53sd00001080*
+ ID_PRODUCT_FROM_DATABASE=CT8 mainboard
+
+pci:v00008086d00001229sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d00001229sv00008086sd00000001*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100B (TX)
+
+pci:v00008086d00001229sv00008086sd00000002*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100B (T4)
+
+pci:v00008086d00001229sv00008086sd00000003*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/10+
+
+pci:v00008086d00001229sv00008086sd00000004*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 WfM
+
+pci:v00008086d00001229sv00008086sd00000005*
+ ID_PRODUCT_FROM_DATABASE=82557 10/100
+
+pci:v00008086d00001229sv00008086sd00000006*
+ ID_PRODUCT_FROM_DATABASE=82557 10/100 with Wake on LAN
+
+pci:v00008086d00001229sv00008086sd00000007*
+ ID_PRODUCT_FROM_DATABASE=82558 10/100 Adapter
+
+pci:v00008086d00001229sv00008086sd00000008*
+ ID_PRODUCT_FROM_DATABASE=82558 10/100 with Wake on LAN
+
+pci:v00008086d00001229sv00008086sd00000009*
+ ID_PRODUCT_FROM_DATABASE=82558B PRO/100+ PCI (TP)
+
+pci:v00008086d00001229sv00008086sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter
+
+pci:v00008086d00001229sv00008086sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+
+
+pci:v00008086d00001229sv00008086sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter
+
+pci:v00008086d00001229sv00008086sd0000000D*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Alert On LAN II* Adapter
+
+pci:v00008086d00001229sv00008086sd0000000E*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter with Alert On LAN*
+
+pci:v00008086d00001229sv00008086sd0000000F*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter
+
+pci:v00008086d00001229sv00008086sd00000010*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Management Adapter
+
+pci:v00008086d00001229sv00008086sd00000011*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Management Adapter
+
+pci:v00008086d00001229sv00008086sd00000012*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Advanced Management Adapter (D)
+
+pci:v00008086d00001229sv00008086sd00000013*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Advanced Management Adapter (E)
+
+pci:v00008086d00001229sv00008086sd00000030*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100  Management Adapter with Alert On LAN* GC
+
+pci:v00008086d00001229sv00008086sd00000031*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter
+
+pci:v00008086d00001229sv00008086sd00000040*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter
+
+pci:v00008086d00001229sv00008086sd00000041*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter
+
+pci:v00008086d00001229sv00008086sd00000042*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter
+
+pci:v00008086d00001229sv00008086sd00000050*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter
+
+pci:v00008086d00001229sv00008086sd00001009*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Server Adapter
+
+pci:v00008086d00001229sv00008086sd0000100C*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Server Adapter (PILA8470B)
+
+pci:v00008086d00001229sv00008086sd00001012*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter (D)
+
+pci:v00008086d00001229sv00008086sd00001013*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter (E)
+
+pci:v00008086d00001229sv00008086sd00001015*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Dual Port Server Adapter
+
+pci:v00008086d00001229sv00008086sd00001017*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Dual Port Server Adapter
+
+pci:v00008086d00001229sv00008086sd00001030*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server
+
+pci:v00008086d00001229sv00008086sd00001040*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter
+
+pci:v00008086d00001229sv00008086sd00001041*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter
+
+pci:v00008086d00001229sv00008086sd00001042*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Server Adapter
+
+pci:v00008086d00001229sv00008086sd00001050*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter
+
+pci:v00008086d00001229sv00008086sd00001051*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Server Adapter
+
+pci:v00008086d00001229sv00008086sd00001052*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Server Adapter
+
+pci:v00008086d00001229sv00008086sd000010F0*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Dual Port Adapter
+
+pci:v00008086d00001229sv00008086sd00001229*
+ ID_PRODUCT_FROM_DATABASE=82557/8/9 [Ethernet Pro 100]
+
+pci:v00008086d00001229sv00008086sd00002009*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd0000200D*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Cardbus
+
+pci:v00008086d00001229sv00008086sd0000200E*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 LAN+V90 Cardbus Modem
+
+pci:v00008086d00001229sv00008086sd0000200F*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002010*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002013*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002016*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002017*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Combo Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002018*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002019*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SR Combo Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002101*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002102*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002103*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002104*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002105*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002106*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Adapter
+
+pci:v00008086d00001229sv00008086sd00002107*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Network Connection
+
+pci:v00008086d00001229sv00008086sd00002108*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Network Connection
+
+pci:v00008086d00001229sv00008086sd00002200*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002201*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002202*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002203*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002204*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002205*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002206*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002207*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002208*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter
+
+pci:v00008086d00001229sv00008086sd00002402*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002407*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002408*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002409*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd0000240F*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002410*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002411*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002412*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00002413*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+
+pci:v00008086d00001229sv00008086sd00003000*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LAN on Motherboard
+
+pci:v00008086d00001229sv00008086sd00003001*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Basic Alert on LAN*
+
+pci:v00008086d00001229sv00008086sd00003002*
+ ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN II*
+
+pci:v00008086d00001229sv00008086sd00003006*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Network Connection
+
+pci:v00008086d00001229sv00008086sd00003007*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Network Connection
+
+pci:v00008086d00001229sv00008086sd00003008*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Network Connection
+
+pci:v00008086d00001229sv00008086sd00003010*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Network Connection
+
+pci:v00008086d00001229sv00008086sd00003011*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Network Connection
+
+pci:v00008086d00001229sv00008086sd00003012*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Network Connection
+
+pci:v00008086d00001229sv00008086sd0000301A*
+ ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard
+
+pci:v00008086d00001229sv00008086sd00003411*
+ ID_PRODUCT_FROM_DATABASE=SDS2 Mainboard
+
+pci:v00008086d0000122D*
+ ID_PRODUCT_FROM_DATABASE=430FX - 82437FX TSC [Triton I]
+
+pci:v00008086d0000122E*
+ ID_PRODUCT_FROM_DATABASE=82371FB PIIX ISA [Triton I]
+
+pci:v00008086d00001230*
+ ID_PRODUCT_FROM_DATABASE=82371FB PIIX IDE [Triton I]
+
+pci:v00008086d00001231*
+ ID_PRODUCT_FROM_DATABASE=DSVD Modem
+
+pci:v00008086d00001234*
+ ID_PRODUCT_FROM_DATABASE=430MX - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX)
+
+pci:v00008086d00001235*
+ ID_PRODUCT_FROM_DATABASE=430MX - 82437MX Mob. System Ctrlr (MTSC) & 82438MX Data Path (MTDP)
+
+pci:v00008086d00001237*
+ ID_PRODUCT_FROM_DATABASE=440FX - 82441FX PMC [Natoma]
+
+pci:v00008086d00001237sv00001AF4sd00001100*
+ ID_PRODUCT_FROM_DATABASE=Qemu virtual machine
+
+pci:v00008086d00001239*
+ ID_PRODUCT_FROM_DATABASE=82371FB PIIX IDE Interface
+
+pci:v00008086d0000123B*
+ ID_PRODUCT_FROM_DATABASE=82380PB PCI to PCI Docking Bridge
+
+pci:v00008086d0000123C*
+ ID_PRODUCT_FROM_DATABASE=82380AB (MISA) Mobile PCI-to-ISA Bridge
+
+pci:v00008086d0000123D*
+ ID_PRODUCT_FROM_DATABASE=683053 Programmable Interrupt Device
+
+pci:v00008086d0000123E*
+ ID_PRODUCT_FROM_DATABASE=82466GX (IHPC) Integrated Hot-Plug Controller (hidden mode)
+
+pci:v00008086d0000123F*
+ ID_PRODUCT_FROM_DATABASE=82466GX Integrated Hot-Plug Controller (IHPC)
+
+pci:v00008086d00001240*
+ ID_PRODUCT_FROM_DATABASE=82752 (752) AGP Graphics Accelerator
+
+pci:v00008086d0000124B*
+ ID_PRODUCT_FROM_DATABASE=82380FB (MPCI2) Mobile Docking Controller
+
+pci:v00008086d00001250*
+ ID_PRODUCT_FROM_DATABASE=430HX - 82439HX TXC [Triton II]
+
+pci:v00008086d00001360*
+ ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub PCI Bridge
+
+pci:v00008086d00001361*
+ ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub Controller (HRes)
+
+pci:v00008086d00001361sv00008086sd00001361*
+ ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub Controller (HRes)
+
+pci:v00008086d00001361sv00008086sd00008000*
+ ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub Controller (HRes)
+
+pci:v00008086d00001460*
+ ID_PRODUCT_FROM_DATABASE=82870P2 P64H2 Hub PCI Bridge
+
+pci:v00008086d00001461*
+ ID_PRODUCT_FROM_DATABASE=82870P2 P64H2 I/OxAPIC
+
+pci:v00008086d00001461sv000015D9sd00003480*
+ ID_PRODUCT_FROM_DATABASE=P4DP6
+
+pci:v00008086d00001461sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9/Vx9 mainboard
+
+pci:v00008086d00001462*
+ ID_PRODUCT_FROM_DATABASE=82870P2 P64H2 Hot Plug Controller
+
+pci:v00008086d00001501*
+ ID_PRODUCT_FROM_DATABASE=82567V-3 Gigabit Network Connection
+
+pci:v00008086d00001502*
+ ID_PRODUCT_FROM_DATABASE=82579LM Gigabit Network Connection
+
+pci:v00008086d00001503*
+ ID_PRODUCT_FROM_DATABASE=82579V Gigabit Network Connection
+
+pci:v00008086d00001503sv00001043sd0000849C*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00001507*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit Network Connection
+
+pci:v00008086d00001508*
+ ID_PRODUCT_FROM_DATABASE=82598EB Gigabit BX Network Connection
+
+pci:v00008086d0000150A*
+ ID_PRODUCT_FROM_DATABASE=82576NS Gigabit Network Connection
+
+pci:v00008086d0000150B*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT2 Server Adapter
+
+pci:v00008086d0000150Bsv00008086sd0000A10C*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT2 Server Adapter
+
+pci:v00008086d0000150Bsv00008086sd0000A11C*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT2 Server Adapter
+
+pci:v00008086d0000150Bsv00008086sd0000A12C*
+ ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT2 Server Adapter
+
+pci:v00008086d0000150C*
+ ID_PRODUCT_FROM_DATABASE=82583V Gigabit Network Connection
+
+pci:v00008086d0000150D*
+ ID_PRODUCT_FROM_DATABASE=82576 Gigabit Backplane Connection
+
+pci:v00008086d0000150Dsv00008086sd0000A10C*
+ ID_PRODUCT_FROM_DATABASE=Gigabit ET Quad Port Mezzanine Card
+
+pci:v00008086d0000150E*
+ ID_PRODUCT_FROM_DATABASE=82580 Gigabit Network Connection
+
+pci:v00008086d0000150Esv0000103Csd00001780*
+ ID_PRODUCT_FROM_DATABASE=NC365T 4-port Ethernet Server Adapter
+
+pci:v00008086d0000150Esv00008086sd000012A1*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-T4
+
+pci:v00008086d0000150Esv00008086sd000012A2*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-T4
+
+pci:v00008086d0000150F*
+ ID_PRODUCT_FROM_DATABASE=82580 Gigabit Fiber Network Connection
+
+pci:v00008086d00001510*
+ ID_PRODUCT_FROM_DATABASE=82580 Gigabit Backplane Connection
+
+pci:v00008086d00001511*
+ ID_PRODUCT_FROM_DATABASE=82580 Gigabit SFP Connection
+
+pci:v00008086d00001514*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit KX4 Network Connection
+
+pci:v00008086d00001514sv00008086sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Ethernet X520 10GbE Dual Port KX4 Mezz
+
+pci:v00008086d00001515*
+ ID_PRODUCT_FROM_DATABASE=X540 Ethernet Controller Virtual Function
+
+pci:v00008086d00001516*
+ ID_PRODUCT_FROM_DATABASE=82580 Gigabit Network Connection
+
+pci:v00008086d00001516sv00008086sd000012B1*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-T2
+
+pci:v00008086d00001516sv00008086sd000012B2*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-T2
+
+pci:v00008086d00001517*
+ ID_PRODUCT_FROM_DATABASE=82599ES 10 Gigabit Network Connection
+
+pci:v00008086d00001517sv00001137sd0000006A*
+ ID_PRODUCT_FROM_DATABASE=UCS CNA M61KR-I Intel Converged Network Adapter
+
+pci:v00008086d00001518*
+ ID_PRODUCT_FROM_DATABASE=82576NS SerDes Gigabit Network Connection
+
+pci:v00008086d0000151C*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit TN Network Connection
+
+pci:v00008086d0000151Csv0000108Esd00007B13*
+ ID_PRODUCT_FROM_DATABASE=Dual 10GBASE-T LP
+
+pci:v00008086d00001520*
+ ID_PRODUCT_FROM_DATABASE=I350 Ethernet Controller Virtual Function
+
+pci:v00008086d00001521*
+ ID_PRODUCT_FROM_DATABASE=I350 Gigabit Network Connection
+
+pci:v00008086d00001521sv00001028sd00001F60*
+ ID_PRODUCT_FROM_DATABASE=Intel GbE 4P I350crNDC
+
+pci:v00008086d00001521sv00001028sd00001F62*
+ ID_PRODUCT_FROM_DATABASE=Intel GbE 2P I350crNDC
+
+pci:v00008086d00001521sv0000103Csd0000337F*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361i Adapter
+
+pci:v00008086d00001521sv0000103Csd00003380*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 4-port 366i Adapter
+
+pci:v00008086d00001521sv0000103Csd0000339E*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361T Adapter
+
+pci:v00008086d00001521sv0000108Esd00007B16*
+ ID_PRODUCT_FROM_DATABASE=Quad Port GbE PCIe 2.0 ExpressModule, UTP
+
+pci:v00008086d00001521sv0000108Esd00007B18*
+ ID_PRODUCT_FROM_DATABASE=Quad Port GbE PCIe 2.0 Low Profile Adapter, UTP
+
+pci:v00008086d00001521sv000010A9sd0000802A*
+ ID_PRODUCT_FROM_DATABASE=UV2-BaseIO dual-port GbE
+
+pci:v00008086d00001521sv00008086sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T4
+
+pci:v00008086d00001521sv00008086sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T2
+
+pci:v00008086d00001521sv00008086sd000000A1*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T4
+
+pci:v00008086d00001521sv00008086sd000000A2*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T2
+
+pci:v00008086d00001521sv00008086sd00005001*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T4
+
+pci:v00008086d00001521sv00008086sd00005002*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T2
+
+pci:v00008086d00001522*
+ ID_PRODUCT_FROM_DATABASE=I350 Gigabit Fiber Network Connection
+
+pci:v00008086d00001522sv0000108Esd00007B17*
+ ID_PRODUCT_FROM_DATABASE=Quad Port GbE PCIe 2.0 ExpressModule, MMF
+
+pci:v00008086d00001522sv0000108Esd00007B19*
+ ID_PRODUCT_FROM_DATABASE=Dual Port GbE PCIe 2.0 Low Profile Adapter, MMF
+
+pci:v00008086d00001522sv00008086sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T2
+
+pci:v00008086d00001522sv00008086sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-F4
+
+pci:v00008086d00001522sv00008086sd00000004*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-F2
+
+pci:v00008086d00001522sv00008086sd000000A3*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-F4
+
+pci:v00008086d00001522sv00008086sd000000A4*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-F2
+
+pci:v00008086d00001523*
+ ID_PRODUCT_FROM_DATABASE=I350 Gigabit Backplane Connection
+
+pci:v00008086d00001523sv0000103Csd00001784*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361FLB Adapter
+
+pci:v00008086d00001523sv0000103Csd000018D1*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361FLB Adapter
+
+pci:v00008086d00001523sv0000103Csd0000339F*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 4-port 366M Adapter
+
+pci:v00008086d00001523sv00008086sd00001F52*
+ ID_PRODUCT_FROM_DATABASE=1GbE 4P I350 Mezz
+
+pci:v00008086d00001524*
+ ID_PRODUCT_FROM_DATABASE=I350 Gigabit Connection
+
+pci:v00008086d00001525*
+ ID_PRODUCT_FROM_DATABASE=82567V-4 Gigabit Network Connection
+
+pci:v00008086d00001526*
+ ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection
+
+pci:v00008086d00001526sv00008086sd0000A05C*
+ ID_PRODUCT_FROM_DATABASE=Gigabit ET2 Quad Port Server Adapter
+
+pci:v00008086d00001526sv00008086sd0000A06C*
+ ID_PRODUCT_FROM_DATABASE=Gigabit ET2 Quad Port Server Adapter
+
+pci:v00008086d00001527*
+ ID_PRODUCT_FROM_DATABASE=82580 Gigabit Fiber Network Connection
+
+pci:v00008086d00001527sv00008086sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-F4
+
+pci:v00008086d00001527sv00008086sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-F4
+
+pci:v00008086d00001528*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2
+
+pci:v00008086d00001528sv00001028sd00001F61*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10G 4P X540/I350 rNDC
+
+pci:v00008086d00001528sv0000103Csd0000192D*
+ ID_PRODUCT_FROM_DATABASE=561FLR-T 2-port 10Gb Ethernet Adapter
+
+pci:v00008086d00001528sv0000108Esd00007B14*
+ ID_PRODUCT_FROM_DATABASE=Sun Dual Port 10 GbE PCIe 2.0 ExpressModule, Base-T
+
+pci:v00008086d00001528sv0000108Esd00007B15*
+ ID_PRODUCT_FROM_DATABASE=Sun Dual Port 10 GbE PCIe 2.0 Low Profile Adapter, Base-T
+
+pci:v00008086d00001528sv00001137sd000000BF*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2
+
+pci:v00008086d00001528sv00008086sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2
+
+pci:v00008086d00001528sv00008086sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T1
+
+pci:v00008086d00001528sv00008086sd0000001A*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2
+
+pci:v00008086d00001528sv00008086sd000000A2*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T1
+
+pci:v00008086d00001528sv00008086sd00001F61*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10G 4P X540/I350 rNDC
+
+pci:v00008086d00001528sv00008086sd00005003*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 10G 2P X540-t Adapter
+
+pci:v00008086d00001529*
+ ID_PRODUCT_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection with FCoE
+
+pci:v00008086d0000152A*
+ ID_PRODUCT_FROM_DATABASE=82599 10 Gigabit Dual port Network Connection with FCoE
+
+pci:v00008086d00001533*
+ ID_PRODUCT_FROM_DATABASE=I210 Gigabit Network Connection
+
+pci:v00008086d00001533sv0000103Csd00000003*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I210-T1
+
+pci:v00008086d00001533sv00008086sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I210-T1
+
+pci:v00008086d00001533sv00008086sd00000002*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I210-T1
+
+pci:v00008086d00001534*
+ ID_PRODUCT_FROM_DATABASE=I210 Gigabit Network Connection
+
+pci:v00008086d00001536*
+ ID_PRODUCT_FROM_DATABASE=I210 Gigabit Fiber Network Connection
+
+pci:v00008086d00001537*
+ ID_PRODUCT_FROM_DATABASE=I210 Gigabit Backplane Connection
+
+pci:v00008086d00001538*
+ ID_PRODUCT_FROM_DATABASE=I210 Gigabit Network Connection
+
+pci:v00008086d00001539*
+ ID_PRODUCT_FROM_DATABASE=I211 Gigabit Network Connection
+
+pci:v00008086d0000153A*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Connection I217-LM
+
+pci:v00008086d0000153B*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Connection I217-V
+
+pci:v00008086d00001547*
+ ID_PRODUCT_FROM_DATABASE=DSL3510 Thunderbolt Port [Cactus Ridge]
+
+pci:v00008086d00001549*
+ ID_PRODUCT_FROM_DATABASE=DSL3510 Thunderbolt Controller [Cactus Ridge]
+
+pci:v00008086d0000154A*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-4
+
+pci:v00008086d0000154Asv00008086sd0000011A*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X520-4
+
+pci:v00008086d0000154Asv00008086sd0000011B*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X520-4
+
+pci:v00008086d0000154Asv00008086sd0000011C*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X520-4
+
+pci:v00008086d0000154D*
+ ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit SFP+ Network Connection
+
+pci:v00008086d0000154Dsv00008086sd00007B11*
+ ID_PRODUCT_FROM_DATABASE=10GbE 2P X520 Adapter
+
+pci:v00008086d00001557*
+ ID_PRODUCT_FROM_DATABASE=82599 10 Gigabit Network Connection
+
+pci:v00008086d00001559*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Connection I218-V
+
+pci:v00008086d0000155A*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Connection I218-LM
+
+pci:v00008086d00001560*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Controller X540-AT1
+
+pci:v00008086d00001960*
+ ID_PRODUCT_FROM_DATABASE=80960RP (i960RP) Microprocessor
+
+pci:v00008086d00001960sv0000101Esd00000431*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 431 RAID Controller
+
+pci:v00008086d00001960sv0000101Esd00000438*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 438 Ultra2 LVD RAID Controller
+
+pci:v00008086d00001960sv0000101Esd00000466*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 466 Express Plus RAID Controller
+
+pci:v00008086d00001960sv0000101Esd00000467*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 467 Enterprise 1500 RAID Controller
+
+pci:v00008086d00001960sv0000101Esd00000490*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 490 Express 300 RAID Controller
+
+pci:v00008086d00001960sv0000101Esd00000762*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 762 Express RAID Controller
+
+pci:v00008086d00001960sv0000101Esd000009A0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC
+
+pci:v00008086d00001960sv00001028sd00000467*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/DC
+
+pci:v00008086d00001960sv00001028sd00001111*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC
+
+pci:v00008086d00001960sv0000103Csd000003A2*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID
+
+pci:v00008086d00001960sv0000103Csd000010C6*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 438, NetRAID-3Si
+
+pci:v00008086d00001960sv0000103Csd000010C7*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID T5, Integrated NetRAID
+
+pci:v00008086d00001960sv0000103Csd000010CC*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID, Integrated NetRAID
+
+pci:v00008086d00001960sv0000103Csd000010CD*
+ ID_PRODUCT_FROM_DATABASE=NetRAID-1Si
+
+pci:v00008086d00001960sv0000105Asd00000000*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak
+
+pci:v00008086d00001960sv0000105Asd00002168*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak Pro
+
+pci:v00008086d00001960sv0000105Asd00005168*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak66/100
+
+pci:v00008086d00001960sv00001111sd00001111*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC
+
+pci:v00008086d00001960sv00001111sd00001112*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC
+
+pci:v00008086d00001960sv0000113Csd000003A2*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID
+
+pci:v00008086d00001960sv0000E4BFsd00001010*
+ ID_PRODUCT_FROM_DATABASE=CG1-RADIO
+
+pci:v00008086d00001960sv0000E4BFsd00001020*
+ ID_PRODUCT_FROM_DATABASE=CU2-QUARTET
+
+pci:v00008086d00001960sv0000E4BFsd00001040*
+ ID_PRODUCT_FROM_DATABASE=CU1-CHORUS
+
+pci:v00008086d00001960sv0000E4BFsd00003100*
+ ID_PRODUCT_FROM_DATABASE=CX1-BAND
+
+pci:v00008086d00001962*
+ ID_PRODUCT_FROM_DATABASE=80960RM (i960RM) Microprocessor
+
+pci:v00008086d00001962sv0000105Asd00000000*
+ ID_PRODUCT_FROM_DATABASE=SuperTrak SX6000 I2O CPU
+
+pci:v00008086d00001A21*
+ ID_PRODUCT_FROM_DATABASE=82840 840 [Carmel] Chipset Host Bridge (Hub A)
+
+pci:v00008086d00001A23*
+ ID_PRODUCT_FROM_DATABASE=82840 840 [Carmel] Chipset AGP Bridge
+
+pci:v00008086d00001A24*
+ ID_PRODUCT_FROM_DATABASE=82840 840 [Carmel] Chipset PCI Bridge (Hub B)
+
+pci:v00008086d00001A30*
+ ID_PRODUCT_FROM_DATABASE=82845 845 [Brookdale] Chipset Host Bridge
+
+pci:v00008086d00001A30sv00001028sd0000010E*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX240
+
+pci:v00008086d00001A30sv000015D9sd00003280*
+ ID_PRODUCT_FROM_DATABASE=Supermicro P4SBE Mainboard
+
+pci:v00008086d00001A31*
+ ID_PRODUCT_FROM_DATABASE=82845 845 [Brookdale] Chipset AGP Bridge
+
+pci:v00008086d00001A38*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset DMA Engine
+
+pci:v00008086d00001A38sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d00001A38sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d00001A48*
+ ID_PRODUCT_FROM_DATABASE=82597EX 10GbE Ethernet Controller
+
+pci:v00008086d00001A48sv00008086sd0000A01F*
+ ID_PRODUCT_FROM_DATABASE=PRO/10GbE SR Server Adapter
+
+pci:v00008086d00001A48sv00008086sd0000A11F*
+ ID_PRODUCT_FROM_DATABASE=PRO/10GbE SR Server Adapter
+
+pci:v00008086d00001B48*
+ ID_PRODUCT_FROM_DATABASE=82597EX 10GbE Ethernet Controller
+
+pci:v00008086d00001B48sv00008086sd0000A01F*
+ ID_PRODUCT_FROM_DATABASE=PRO/10GbE LR Server Adapter
+
+pci:v00008086d00001B48sv00008086sd0000A11F*
+ ID_PRODUCT_FROM_DATABASE=PRO/10GbE LR Server Adapter
+
+pci:v00008086d00001C00*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller
+
+pci:v00008086d00001C01*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller
+
+pci:v00008086d00001C02*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller
+
+pci:v00008086d00001C02sv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00008086d00001C02sv00001043sd0000844D*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00001C03*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller
+
+pci:v00008086d00001C03sv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00001C03sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C03sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C04*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller
+
+pci:v00008086d00001C05*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller
+
+pci:v00008086d00001C08*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 2 port SATA IDE Controller
+
+pci:v00008086d00001C09*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 2 port SATA IDE Controller
+
+pci:v00008086d00001C10*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1
+
+pci:v00008086d00001C10sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C10sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C12*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2
+
+pci:v00008086d00001C12sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C14*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 3
+
+pci:v00008086d00001C14sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C14sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C16*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 4
+
+pci:v00008086d00001C18*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5
+
+pci:v00008086d00001C18sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C1A*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 6
+
+pci:v00008086d00001C1Asv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C1C*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 7
+
+pci:v00008086d00001C1E*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 8
+
+pci:v00008086d00001C20*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller
+
+pci:v00008086d00001C20sv00001028sd00000490*
+ ID_PRODUCT_FROM_DATABASE=Alienware M17x R3
+
+pci:v00008086d00001C20sv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00008086d00001C20sv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00001C20sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C20sv00001043sd00008418*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00001C20sv00008086sd00002008*
+ ID_PRODUCT_FROM_DATABASE=DQ67SW board
+
+pci:v00008086d00001C20sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C22*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller
+
+pci:v00008086d00001C22sv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00008086d00001C22sv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00001C22sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C22sv00001043sd0000844D*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00001C22sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C24*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family Thermal Management Controller
+
+pci:v00008086d00001C25*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family DMI to PCI Bridge
+
+pci:v00008086d00001C26*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1
+
+pci:v00008086d00001C26sv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00008086d00001C26sv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00001C26sv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C26sv00001043sd0000844D*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00001C26sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C27*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #1
+
+pci:v00008086d00001C27sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C2C*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #5
+
+pci:v00008086d00001C2Csv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C2D*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2
+
+pci:v00008086d00001C2Dsv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00008086d00001C2Dsv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00001C2Dsv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C2Dsv00001043sd0000844D*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00001C2Dsv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C33*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LAN Controller
+
+pci:v00008086d00001C35*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family VECI Controller
+
+pci:v00008086d00001C3A*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1
+
+pci:v00008086d00001C3Asv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00008086d00001C3Asv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00001C3Asv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C3Asv00001043sd0000844D*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00001C3Asv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C3B*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #2
+
+pci:v00008086d00001C3C*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family IDE-r Controller
+
+pci:v00008086d00001C3D*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family KT Controller
+
+pci:v00008086d00001C40*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C41*
+ ID_PRODUCT_FROM_DATABASE=Mobile SFF 6 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C42*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C43*
+ ID_PRODUCT_FROM_DATABASE=Mobile 6 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C44*
+ ID_PRODUCT_FROM_DATABASE=Z68 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C45*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C46*
+ ID_PRODUCT_FROM_DATABASE=P67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C46sv00001043sd0000844D*
+ ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard
+
+pci:v00008086d00001C47*
+ ID_PRODUCT_FROM_DATABASE=UM67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C48*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C49*
+ ID_PRODUCT_FROM_DATABASE=HM65 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C49sv00008086sd00007270*
+ ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+
+pci:v00008086d00001C4A*
+ ID_PRODUCT_FROM_DATABASE=H67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C4Asv00001028sd000004AA*
+ ID_PRODUCT_FROM_DATABASE=XPS 8300
+
+pci:v00008086d00001C4B*
+ ID_PRODUCT_FROM_DATABASE=HM67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C4Bsv00001028sd000004B2*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3350
+
+pci:v00008086d00001C4Bsv00001028sd000004DA*
+ ID_PRODUCT_FROM_DATABASE=Vostro 3750
+
+pci:v00008086d00001C4C*
+ ID_PRODUCT_FROM_DATABASE=Q65 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C4D*
+ ID_PRODUCT_FROM_DATABASE=QS67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C4E*
+ ID_PRODUCT_FROM_DATABASE=Q67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C4F*
+ ID_PRODUCT_FROM_DATABASE=QM67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C50*
+ ID_PRODUCT_FROM_DATABASE=B65 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C51*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C52*
+ ID_PRODUCT_FROM_DATABASE=C202 Chipset Family LPC Controller
+
+pci:v00008086d00001C53*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C54*
+ ID_PRODUCT_FROM_DATABASE=C204 Chipset Family LPC Controller
+
+pci:v00008086d00001C55*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C56*
+ ID_PRODUCT_FROM_DATABASE=C206 Chipset Family LPC Controller
+
+pci:v00008086d00001C57*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C58*
+ ID_PRODUCT_FROM_DATABASE=Upgraded B65 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C59*
+ ID_PRODUCT_FROM_DATABASE=Upgraded HM67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C5A*
+ ID_PRODUCT_FROM_DATABASE=Upgraded Q67 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C5B*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C5C*
+ ID_PRODUCT_FROM_DATABASE=H61 Express Chipset Family LPC Controller
+
+pci:v00008086d00001C5D*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C5E*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001C5F*
+ ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
+
+pci:v00008086d00001D00*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA IDE Controller
+
+pci:v00008086d00001D02*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 6-Port SATA AHCI Controller
+
+pci:v00008086d00001D04*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller
+
+pci:v00008086d00001D06*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SATA Premium RAID Controller
+
+pci:v00008086d00001D08*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 2-Port SATA IDE Controller
+
+pci:v00008086d00001D10*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 1
+
+pci:v00008086d00001D11*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 1
+
+pci:v00008086d00001D12*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 2
+
+pci:v00008086d00001D13*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 2
+
+pci:v00008086d00001D14*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 3
+
+pci:v00008086d00001D15*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 3
+
+pci:v00008086d00001D16*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 4
+
+pci:v00008086d00001D17*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 4
+
+pci:v00008086d00001D18*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 5
+
+pci:v00008086d00001D19*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 5
+
+pci:v00008086d00001D1A*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 6
+
+pci:v00008086d00001D1B*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 6
+
+pci:v00008086d00001D1C*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 7
+
+pci:v00008086d00001D1D*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 7
+
+pci:v00008086d00001D1E*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 8
+
+pci:v00008086d00001D1F*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 8
+
+pci:v00008086d00001D20*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset High Definition Audio Controller
+
+pci:v00008086d00001D22*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SMBus Host Controller
+
+pci:v00008086d00001D24*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Thermal Management Controller
+
+pci:v00008086d00001D25*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset DMI to PCI Bridge
+
+pci:v00008086d00001D26*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #1
+
+pci:v00008086d00001D2D*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #2
+
+pci:v00008086d00001D33*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset LAN Controller
+
+pci:v00008086d00001D35*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset VECI Controller
+
+pci:v00008086d00001D3A*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset MEI Controller #1
+
+pci:v00008086d00001D3B*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset MEI Controller #2
+
+pci:v00008086d00001D3C*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset IDE-r Controller
+
+pci:v00008086d00001D3D*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset KT Controller
+
+pci:v00008086d00001D3E*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Virtual Root Port
+
+pci:v00008086d00001D3F*
+ ID_PRODUCT_FROM_DATABASE=C608/C606/X79 series chipset PCI Express Virtual Switch Port
+
+pci:v00008086d00001D40*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset LPC Controller
+
+pci:v00008086d00001D41*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset LPC Controller
+
+pci:v00008086d00001D50*
+ ID_PRODUCT_FROM_DATABASE=C608 chipset Dual 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D54*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D55*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D58*
+ ID_PRODUCT_FROM_DATABASE=C606 chipset Dual 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D59*
+ ID_PRODUCT_FROM_DATABASE=C604/X79 series chipset 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D5A*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA Storage Control Unit
+
+pci:v00008086d00001D5B*
+ ID_PRODUCT_FROM_DATABASE=C602 chipset 4-Port SATA Storage Control Unit
+
+pci:v00008086d00001D5C*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D5D*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D5E*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA Storage Control Unit
+
+pci:v00008086d00001D5F*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA Storage Control Unit
+
+pci:v00008086d00001D60*
+ ID_PRODUCT_FROM_DATABASE=C608 chipset Dual 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D64*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D65*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D68*
+ ID_PRODUCT_FROM_DATABASE=C606 chipset Dual 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D69*
+ ID_PRODUCT_FROM_DATABASE=C604/X79 series chipset 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D6A*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA Storage Control Unit
+
+pci:v00008086d00001D6B*
+ ID_PRODUCT_FROM_DATABASE=C602 chipset 4-Port SATA Storage Control Unit
+
+pci:v00008086d00001D6C*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D6D*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA/SAS Storage Control Unit
+
+pci:v00008086d00001D6E*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA Storage Control Unit
+
+pci:v00008086d00001D6F*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA Storage Control Unit
+
+pci:v00008086d00001D70*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SMBus Controller 0
+
+pci:v00008086d00001D71*
+ ID_PRODUCT_FROM_DATABASE=C608/C606/X79 series chipset SMBus Controller 1
+
+pci:v00008086d00001D72*
+ ID_PRODUCT_FROM_DATABASE=C608 chipset SMBus Controller 2
+
+pci:v00008086d00001D74*
+ ID_PRODUCT_FROM_DATABASE=C608/C606/X79 series chipset PCI Express Upstream Port
+
+pci:v00008086d00001D76*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Multi-Function Glue
+
+pci:v00008086d00001E00*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family 4-port SATA Controller [IDE mode]
+
+pci:v00008086d00001E01*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family 4-port SATA Controller [IDE mode]
+
+pci:v00008086d00001E02*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family 6-port SATA Controller [AHCI mode]
+
+pci:v00008086d00001E03*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode]
+
+pci:v00008086d00001E03sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E03sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E04*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SATA Controller [RAID mode]
+
+pci:v00008086d00001E05*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset SATA Controller [RAID mode]
+
+pci:v00008086d00001E06*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SATA Controller [RAID mode]
+
+pci:v00008086d00001E07*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family SATA Controller [RAID mode]
+
+pci:v00008086d00001E08*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family 2-port SATA Controller [IDE mode]
+
+pci:v00008086d00001E09*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family 2-port SATA Controller [IDE mode]
+
+pci:v00008086d00001E0E*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SATA Controller [RAID mode]
+
+pci:v00008086d00001E10*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 1
+
+pci:v00008086d00001E10sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E10sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E12*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 2
+
+pci:v00008086d00001E12sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E12sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E14*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 3
+
+pci:v00008086d00001E16*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 4
+
+pci:v00008086d00001E16sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E18*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 5
+
+pci:v00008086d00001E1A*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 6
+
+pci:v00008086d00001E1C*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 7
+
+pci:v00008086d00001E1E*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 8
+
+pci:v00008086d00001E20*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller
+
+pci:v00008086d00001E20sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E20sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E22*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller
+
+pci:v00008086d00001E22sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E22sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E24*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family Thermal Management Controller
+
+pci:v00008086d00001E24sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E25*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family DMI to PCI Bridge
+
+pci:v00008086d00001E26*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1
+
+pci:v00008086d00001E26sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E26sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E2D*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2
+
+pci:v00008086d00001E2Dsv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E2Dsv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E31*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller
+
+pci:v00008086d00001E31sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E31sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E33*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family LAN Controller
+
+pci:v00008086d00001E3A*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #1
+
+pci:v00008086d00001E3Asv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E3Asv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E3B*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #2
+
+pci:v00008086d00001E3C*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family IDE-r Controller
+
+pci:v00008086d00001E3D*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family KT Controller
+
+pci:v00008086d00001E41*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E42*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E43*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E44*
+ ID_PRODUCT_FROM_DATABASE=Z77 Express Chipset LPC Controller
+
+pci:v00008086d00001E45*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E46*
+ ID_PRODUCT_FROM_DATABASE=Z75 Express Chipset LPC Controller
+
+pci:v00008086d00001E47*
+ ID_PRODUCT_FROM_DATABASE=Q77 Express Chipset LPC Controller
+
+pci:v00008086d00001E48*
+ ID_PRODUCT_FROM_DATABASE=Q75 Express Chipset LPC Controller
+
+pci:v00008086d00001E49*
+ ID_PRODUCT_FROM_DATABASE=B75 Express Chipset LPC Controller
+
+pci:v00008086d00001E4A*
+ ID_PRODUCT_FROM_DATABASE=H77 Express Chipset LPC Controller
+
+pci:v00008086d00001E4B*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E4C*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E4D*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E4E*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E4F*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E50*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E51*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E52*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E53*
+ ID_PRODUCT_FROM_DATABASE=C216 Series Chipset LPC Controller
+
+pci:v00008086d00001E54*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E55*
+ ID_PRODUCT_FROM_DATABASE=QM77 Express Chipset LPC Controller
+
+pci:v00008086d00001E56*
+ ID_PRODUCT_FROM_DATABASE=QS77 Express Chipset LPC Controller
+
+pci:v00008086d00001E57*
+ ID_PRODUCT_FROM_DATABASE=HM77 Express Chipset LPC Controller
+
+pci:v00008086d00001E58*
+ ID_PRODUCT_FROM_DATABASE=UM77 Express Chipset LPC Controller
+
+pci:v00008086d00001E59*
+ ID_PRODUCT_FROM_DATABASE=HM76 Express Chipset LPC Controller
+
+pci:v00008086d00001E59sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E59sv00001043sd00001517*
+ ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A
+
+pci:v00008086d00001E5A*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E5B*
+ ID_PRODUCT_FROM_DATABASE=UM77 Express Chipset LPC Controller
+
+pci:v00008086d00001E5C*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E5D*
+ ID_PRODUCT_FROM_DATABASE=HM75 Express Chipset LPC Controller
+
+pci:v00008086d00001E5E*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00001E5F*
+ ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller
+
+pci:v00008086d00002310*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC LPC Controller
+
+pci:v00008086d00002323*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC 4 Port SATA AHCI Controller
+
+pci:v00008086d00002330*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC SMBus Controller
+
+pci:v00008086d00002331*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC Chap Counter
+
+pci:v00008086d00002332*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC Thermal Subsystem
+
+pci:v00008086d00002334*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC USB2 Enhanced Host Controller #1
+
+pci:v00008086d00002335*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC USB2 Enhanced Host Controller #1
+
+pci:v00008086d00002342*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #1
+
+pci:v00008086d00002343*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #1
+
+pci:v00008086d00002344*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #2
+
+pci:v00008086d00002345*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #2
+
+pci:v00008086d00002346*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #3
+
+pci:v00008086d00002347*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #3
+
+pci:v00008086d00002348*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #4
+
+pci:v00008086d00002349*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #4
+
+pci:v00008086d00002360*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC Watchdog Timer
+
+pci:v00008086d00002364*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC MEI 0
+
+pci:v00008086d00002365*
+ ID_PRODUCT_FROM_DATABASE=DH89xxCC MEI 1
+
+pci:v00008086d00002410*
+ ID_PRODUCT_FROM_DATABASE=82801AA ISA Bridge (LPC)
+
+pci:v00008086d00002411*
+ ID_PRODUCT_FROM_DATABASE=82801AA IDE Controller
+
+pci:v00008086d00002412*
+ ID_PRODUCT_FROM_DATABASE=82801AA USB Controller
+
+pci:v00008086d00002413*
+ ID_PRODUCT_FROM_DATABASE=82801AA SMBus Controller
+
+pci:v00008086d00002415*
+ ID_PRODUCT_FROM_DATABASE=82801AA AC'97 Audio Controller
+
+pci:v00008086d00002415sv00001028sd00000095*
+ ID_PRODUCT_FROM_DATABASE=Precision Workstation 220 Integrated Digital Audio
+
+pci:v00008086d00002415sv00001028sd000000B4*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX110
+
+pci:v00008086d00002415sv0000110Asd00000051*
+ ID_PRODUCT_FROM_DATABASE=Activy 2xx
+
+pci:v00008086d00002415sv000011D4sd00000040*
+ ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio
+
+pci:v00008086d00002415sv000011D4sd00000048*
+ ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio
+
+pci:v00008086d00002415sv000011D4sd00005340*
+ ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio
+
+pci:v00008086d00002415sv00001734sd00001025*
+ ID_PRODUCT_FROM_DATABASE=Activy 3xx
+
+pci:v00008086d00002416*
+ ID_PRODUCT_FROM_DATABASE=82801AA AC'97 Modem Controller
+
+pci:v00008086d00002418*
+ ID_PRODUCT_FROM_DATABASE=82801AA PCI Bridge
+
+pci:v00008086d00002420*
+ ID_PRODUCT_FROM_DATABASE=82801AB ISA Bridge (LPC)
+
+pci:v00008086d00002421*
+ ID_PRODUCT_FROM_DATABASE=82801AB IDE Controller
+
+pci:v00008086d00002422*
+ ID_PRODUCT_FROM_DATABASE=82801AB USB Controller
+
+pci:v00008086d00002423*
+ ID_PRODUCT_FROM_DATABASE=82801AB SMBus Controller
+
+pci:v00008086d00002425*
+ ID_PRODUCT_FROM_DATABASE=82801AB AC'97 Audio Controller
+
+pci:v00008086d00002425sv000011D4sd00000040*
+ ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio
+
+pci:v00008086d00002425sv000011D4sd00000048*
+ ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio
+
+pci:v00008086d00002426*
+ ID_PRODUCT_FROM_DATABASE=82801AB AC'97 Modem Controller
+
+pci:v00008086d00002428*
+ ID_PRODUCT_FROM_DATABASE=82801AB PCI Bridge
+
+pci:v00008086d00002440*
+ ID_PRODUCT_FROM_DATABASE=82801BA ISA Bridge (LPC)
+
+pci:v00008086d00002440sv00008086sd00005744*
+ ID_PRODUCT_FROM_DATABASE=S845WD1-E
+
+pci:v00008086d00002442*
+ ID_PRODUCT_FROM_DATABASE=82801BA/BAM USB Controller #1
+
+pci:v00008086d00002442sv00001014sd000001C6*
+ ID_PRODUCT_FROM_DATABASE=Netvista A40/A40p
+
+pci:v00008086d00002442sv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX
+
+pci:v00008086d00002442sv00001028sd000000C7*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8100
+
+pci:v00008086d00002442sv00001028sd000000D8*
+ ID_PRODUCT_FROM_DATABASE=Precision 530
+
+pci:v00008086d00002442sv00001028sd0000010E*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX240
+
+pci:v00008086d00002442sv0000103Csd0000126F*
+ ID_PRODUCT_FROM_DATABASE=e-pc 40
+
+pci:v00008086d00002442sv00001043sd00008027*
+ ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard
+
+pci:v00008086d00002442sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00008086d00002442sv0000147Bsd00000507*
+ ID_PRODUCT_FROM_DATABASE=TH7II-RAID
+
+pci:v00008086d00002442sv00008086sd00004532*
+ ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard
+
+pci:v00008086d00002442sv00008086sd00004557*
+ ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard
+
+pci:v00008086d00002442sv00008086sd00005744*
+ ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard
+
+pci:v00008086d00002443*
+ ID_PRODUCT_FROM_DATABASE=82801BA/BAM SMBus Controller
+
+pci:v00008086d00002443sv00001014sd000001C6*
+ ID_PRODUCT_FROM_DATABASE=Netvista A40/A40p
+
+pci:v00008086d00002443sv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX
+
+pci:v00008086d00002443sv00001028sd000000C7*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8100
+
+pci:v00008086d00002443sv00001028sd000000D8*
+ ID_PRODUCT_FROM_DATABASE=Precision 530
+
+pci:v00008086d00002443sv00001028sd0000010E*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX240
+
+pci:v00008086d00002443sv0000103Csd0000126F*
+ ID_PRODUCT_FROM_DATABASE=e-pc 40
+
+pci:v00008086d00002443sv00001043sd00008027*
+ ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard
+
+pci:v00008086d00002443sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00008086d00002443sv0000147Bsd00000507*
+ ID_PRODUCT_FROM_DATABASE=TH7II-RAID
+
+pci:v00008086d00002443sv000015D9sd00003280*
+ ID_PRODUCT_FROM_DATABASE=Supermicro P4SBE Mainboard
+
+pci:v00008086d00002443sv00008086sd00004532*
+ ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard
+
+pci:v00008086d00002443sv00008086sd00004557*
+ ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard
+
+pci:v00008086d00002443sv00008086sd00005744*
+ ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard
+
+pci:v00008086d00002444*
+ ID_PRODUCT_FROM_DATABASE=82801BA/BAM USB Controller #1
+
+pci:v00008086d00002444sv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX
+
+pci:v00008086d00002444sv00001028sd000000C7*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8100
+
+pci:v00008086d00002444sv00001028sd000000D8*
+ ID_PRODUCT_FROM_DATABASE=Precision 530
+
+pci:v00008086d00002444sv00001028sd0000010E*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX240
+
+pci:v00008086d00002444sv0000103Csd0000126F*
+ ID_PRODUCT_FROM_DATABASE=e-pc 40
+
+pci:v00008086d00002444sv00001043sd00008027*
+ ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard
+
+pci:v00008086d00002444sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00008086d00002444sv0000147Bsd00000507*
+ ID_PRODUCT_FROM_DATABASE=TH7II-RAID
+
+pci:v00008086d00002444sv00008086sd00004532*
+ ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard
+
+pci:v00008086d00002444sv00008086sd00005744*
+ ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard
+
+pci:v00008086d00002445*
+ ID_PRODUCT_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller
+
+pci:v00008086d00002445sv00000E11sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Compaq Deskpro EN Audio
+
+pci:v00008086d00002445sv00000E11sd00000088*
+ ID_PRODUCT_FROM_DATABASE=Evo D500
+
+pci:v00008086d00002445sv00001014sd000001C6*
+ ID_PRODUCT_FROM_DATABASE=Netvista A40/A40p
+
+pci:v00008086d00002445sv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX
+
+pci:v00008086d00002445sv00001028sd000000D8*
+ ID_PRODUCT_FROM_DATABASE=Precision 530
+
+pci:v00008086d00002445sv0000103Csd0000126F*
+ ID_PRODUCT_FROM_DATABASE=e-pc 40
+
+pci:v00008086d00002445sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00008086d00002445sv00001462sd00003370*
+ ID_PRODUCT_FROM_DATABASE=STAC9721 AC
+
+pci:v00008086d00002445sv0000147Bsd00000507*
+ ID_PRODUCT_FROM_DATABASE=TH7II-RAID
+
+pci:v00008086d00002445sv00008086sd00004557*
+ ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard
+
+pci:v00008086d00002446*
+ ID_PRODUCT_FROM_DATABASE=82801BA/BAM AC'97 Modem Controller
+
+pci:v00008086d00002446sv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX
+
+pci:v00008086d00002446sv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00008086d00002448*
+ ID_PRODUCT_FROM_DATABASE=82801 Mobile PCI Bridge
+
+pci:v00008086d00002448sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00002448sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+
+pci:v00008086d00002448sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d00002448sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d00002448sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d00002448sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002448sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002448sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30 notebook
+
+pci:v00008086d00002448sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d00002448sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d00002448sv000017AAsd000020AE*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002448sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002449*
+ ID_PRODUCT_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller
+
+pci:v00008086d00002449sv00000E11sd00000012*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VM
+
+pci:v00008086d00002449sv00000E11sd00000091*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd000001CE*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd000001DC*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd000001EB*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd000001EC*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd00000202*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd00000205*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd00000217*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd00000234*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd0000023D*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd00000244*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd00000245*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001014sd00000265*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Desktop Connection
+
+pci:v00008086d00002449sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Desktop Connection
+
+pci:v00008086d00002449sv00001014sd0000026A*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Desktop Connection
+
+pci:v00008086d00002449sv0000109Fsd0000315D*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv0000109Fsd00003181*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00001179sd0000FF01*
+ ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection
+
+pci:v00008086d00002449sv00001186sd00007801*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv0000144Dsd00002602*
+ ID_PRODUCT_FROM_DATABASE=HomePNA 1M CNR
+
+pci:v00008086d00002449sv00008086sd00003010*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00008086sd00003011*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VM
+
+pci:v00008086d00002449sv00008086sd00003012*
+ ID_PRODUCT_FROM_DATABASE=82562EH based Phoneline
+
+pci:v00008086d00002449sv00008086sd00003013*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE
+
+pci:v00008086d00002449sv00008086sd00003014*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VM
+
+pci:v00008086d00002449sv00008086sd00003015*
+ ID_PRODUCT_FROM_DATABASE=82562EH based Phoneline
+
+pci:v00008086d00002449sv00008086sd00003016*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo
+
+pci:v00008086d00002449sv00008086sd00003017*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile
+
+pci:v00008086d00002449sv00008086sd00003018*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100
+
+pci:v00008086d0000244A*
+ ID_PRODUCT_FROM_DATABASE=82801BAM IDE U100 Controller
+
+pci:v00008086d0000244Asv00001025sd00001016*
+ ID_PRODUCT_FROM_DATABASE=Travelmate 612TX
+
+pci:v00008086d0000244Asv0000104Dsd000080DF*
+ ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403
+
+pci:v00008086d0000244B*
+ ID_PRODUCT_FROM_DATABASE=82801BA IDE U100 Controller
+
+pci:v00008086d0000244Bsv00001014sd000001C6*
+ ID_PRODUCT_FROM_DATABASE=Netvista A40/A40p
+
+pci:v00008086d0000244Bsv00001028sd000000C7*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8100
+
+pci:v00008086d0000244Bsv00001028sd000000D8*
+ ID_PRODUCT_FROM_DATABASE=Precision 530
+
+pci:v00008086d0000244Bsv00001028sd0000010E*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX240
+
+pci:v00008086d0000244Bsv0000103Csd0000126F*
+ ID_PRODUCT_FROM_DATABASE=e-pc 40
+
+pci:v00008086d0000244Bsv00001043sd00008027*
+ ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard
+
+pci:v00008086d0000244Bsv0000147Bsd00000507*
+ ID_PRODUCT_FROM_DATABASE=TH7II-RAID
+
+pci:v00008086d0000244Bsv000015D9sd00003280*
+ ID_PRODUCT_FROM_DATABASE=Supermicro P4SBE Mainboard
+
+pci:v00008086d0000244Bsv00008086sd00004532*
+ ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard
+
+pci:v00008086d0000244Bsv00008086sd00004557*
+ ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard
+
+pci:v00008086d0000244Bsv00008086sd00005744*
+ ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard
+
+pci:v00008086d0000244C*
+ ID_PRODUCT_FROM_DATABASE=82801BAM ISA Bridge (LPC)
+
+pci:v00008086d0000244E*
+ ID_PRODUCT_FROM_DATABASE=82801 PCI Bridge
+
+pci:v00008086d0000244Esv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d0000244Esv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d0000244Esv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d0000244Esv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d0000244Esv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d0000244Esv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d0000244Esv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d0000244Esv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d0000244Esv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d00002450*
+ ID_PRODUCT_FROM_DATABASE=82801E ISA Bridge (LPC)
+
+pci:v00008086d00002452*
+ ID_PRODUCT_FROM_DATABASE=82801E USB Controller
+
+pci:v00008086d00002453*
+ ID_PRODUCT_FROM_DATABASE=82801E SMBus Controller
+
+pci:v00008086d00002459*
+ ID_PRODUCT_FROM_DATABASE=82801E Ethernet Controller 0
+
+pci:v00008086d0000245B*
+ ID_PRODUCT_FROM_DATABASE=82801E IDE U100 Controller
+
+pci:v00008086d0000245D*
+ ID_PRODUCT_FROM_DATABASE=82801E Ethernet Controller 1
+
+pci:v00008086d0000245E*
+ ID_PRODUCT_FROM_DATABASE=82801E PCI Bridge
+
+pci:v00008086d00002480*
+ ID_PRODUCT_FROM_DATABASE=82801CA LPC Interface Controller
+
+pci:v00008086d00002482*
+ ID_PRODUCT_FROM_DATABASE=82801CA/CAM USB Controller #1
+
+pci:v00008086d00002482sv00000E11sd00000030*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v00008086d00002482sv00001014sd00000220*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00002482sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d00002482sv000015D9sd00003480*
+ ID_PRODUCT_FROM_DATABASE=P4DP6
+
+pci:v00008086d00002482sv00008086sd00001958*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4
+
+pci:v00008086d00002482sv00008086sd00003424*
+ ID_PRODUCT_FROM_DATABASE=SE7501HG2 Mainboard
+
+pci:v00008086d00002482sv00008086sd00004541*
+ ID_PRODUCT_FROM_DATABASE=Latitude C640
+
+pci:v00008086d00002483*
+ ID_PRODUCT_FROM_DATABASE=82801CA/CAM SMBus Controller
+
+pci:v00008086d00002483sv00001014sd00000220*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00002483sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d00002483sv000015D9sd00003480*
+ ID_PRODUCT_FROM_DATABASE=P4DP6
+
+pci:v00008086d00002483sv00008086sd00001958*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4
+
+pci:v00008086d00002484*
+ ID_PRODUCT_FROM_DATABASE=82801CA/CAM USB Controller #2
+
+pci:v00008086d00002484sv00000E11sd00000030*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v00008086d00002484sv00001014sd00000220*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00002484sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d00002484sv000015D9sd00003480*
+ ID_PRODUCT_FROM_DATABASE=P4DP6
+
+pci:v00008086d00002484sv00008086sd00001958*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4
+
+pci:v00008086d00002485*
+ ID_PRODUCT_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller
+
+pci:v00008086d00002485sv00001013sd00005959*
+ ID_PRODUCT_FROM_DATABASE=Crystal WMD Audio Codec
+
+pci:v00008086d00002485sv00001014sd00000222*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A30/A30p/T23
+
+pci:v00008086d00002485sv00001014sd00000508*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T30
+
+pci:v00008086d00002485sv00001014sd0000051C*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00002485sv00001043sd00001583*
+ ID_PRODUCT_FROM_DATABASE=L3C (SPDIF)
+
+pci:v00008086d00002485sv00001043sd00001623*
+ ID_PRODUCT_FROM_DATABASE=L2B (no SPDIF)
+
+pci:v00008086d00002485sv00001043sd00001643*
+ ID_PRODUCT_FROM_DATABASE=L3F
+
+pci:v00008086d00002485sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d00002485sv0000144Dsd0000C006*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4
+
+pci:v00008086d00002486*
+ ID_PRODUCT_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller
+
+pci:v00008086d00002486sv00001014sd00000223*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00002486sv00001014sd00000503*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R31
+
+pci:v00008086d00002486sv00001014sd0000051A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00002486sv0000101Fsd00001025*
+ ID_PRODUCT_FROM_DATABASE=620 Series
+
+pci:v00008086d00002486sv00001043sd00001496*
+ ID_PRODUCT_FROM_DATABASE=PCtel HSP56 MR
+
+pci:v00008086d00002486sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d00002486sv0000134Dsd00004C21*
+ ID_PRODUCT_FROM_DATABASE=Dell Inspiron 2100 internal modem
+
+pci:v00008086d00002486sv0000144Dsd00002115*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 internal modem
+
+pci:v00008086d00002486sv000014F1sd00005421*
+ ID_PRODUCT_FROM_DATABASE=MD56ORD V.92 MDC Modem
+
+pci:v00008086d00002487*
+ ID_PRODUCT_FROM_DATABASE=82801CA/CAM USB Controller #3
+
+pci:v00008086d00002487sv00000E11sd00000030*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v00008086d00002487sv00001014sd00000220*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00002487sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d00002487sv000015D9sd00003480*
+ ID_PRODUCT_FROM_DATABASE=P4DP6
+
+pci:v00008086d00002487sv00008086sd00001958*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4
+
+pci:v00008086d0000248A*
+ ID_PRODUCT_FROM_DATABASE=82801CAM IDE U100 Controller
+
+pci:v00008086d0000248Asv00000E11sd00000030*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v00008086d0000248Asv00001014sd00000220*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d0000248Asv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d0000248Asv00008086sd00001958*
+ ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4
+
+pci:v00008086d0000248Asv00008086sd00004541*
+ ID_PRODUCT_FROM_DATABASE=Latitude C640
+
+pci:v00008086d0000248B*
+ ID_PRODUCT_FROM_DATABASE=82801CA Ultra ATA Storage Controller
+
+pci:v00008086d0000248Bsv000015D9sd00003480*
+ ID_PRODUCT_FROM_DATABASE=P4DP6
+
+pci:v00008086d0000248C*
+ ID_PRODUCT_FROM_DATABASE=82801CAM ISA Bridge (LPC)
+
+pci:v00008086d000024C0*
+ ID_PRODUCT_FROM_DATABASE=82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge
+
+pci:v00008086d000024C0sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d000024C0sv00001462sd00005800*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d000024C1*
+ ID_PRODUCT_FROM_DATABASE=82801DBL (ICH4-L) IDE Controller
+
+pci:v00008086d000024C2*
+ ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
+
+pci:v00008086d000024C2sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d000024C2sv00001014sd0000052D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad
+
+pci:v00008086d000024C2sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d000024C2sv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX260
+
+pci:v00008086d000024C2sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d000024C2sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d000024C2sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d000024C2sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d000024C2sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d000024C2sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d000024C2sv00001043sd00008089*
+ ID_PRODUCT_FROM_DATABASE=P4B533
+
+pci:v00008086d000024C2sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v00008086d000024C2sv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8 onboard USB 1.x
+
+pci:v00008086d000024C2sv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00008086d000024C2sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d000024C2sv00001462sd00005800*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d000024C2sv00001509sd00002990*
+ ID_PRODUCT_FROM_DATABASE=Averatec 5110H laptop
+
+pci:v00008086d000024C2sv00001734sd00001004*
+ ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+
+pci:v00008086d000024C2sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d000024C2sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d000024C2sv00008086sd000024C2*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d000024C2sv00008086sd00004541*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400/D500
+
+pci:v00008086d000024C2sv0000E4BFsd00000CC9*
+ ID_PRODUCT_FROM_DATABASE=CC9-SAMBA
+
+pci:v00008086d000024C2sv0000E4BFsd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v00008086d000024C3*
+ ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller
+
+pci:v00008086d000024C3sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d000024C3sv00001014sd0000052D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad
+
+pci:v00008086d000024C3sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d000024C3sv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX260
+
+pci:v00008086d000024C3sv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d000024C3sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d000024C3sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d000024C3sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d000024C3sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d000024C3sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v00008086d000024C3sv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8 onboard SMbus
+
+pci:v00008086d000024C3sv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00008086d000024C3sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d000024C3sv00001458sd000024C2*
+ ID_PRODUCT_FROM_DATABASE=GA-8PE667 Ultra
+
+pci:v00008086d000024C3sv00001462sd00005800*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d000024C3sv00001734sd00001004*
+ ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+
+pci:v00008086d000024C3sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d000024C3sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d000024C3sv0000E4BFsd00000CC9*
+ ID_PRODUCT_FROM_DATABASE=CC9-SAMBA
+
+pci:v00008086d000024C3sv0000E4BFsd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v00008086d000024C4*
+ ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2
+
+pci:v00008086d000024C4sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d000024C4sv00001014sd0000052D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad
+
+pci:v00008086d000024C4sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d000024C4sv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX260
+
+pci:v00008086d000024C4sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d000024C4sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d000024C4sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d000024C4sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d000024C4sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d000024C4sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d000024C4sv00001043sd00008089*
+ ID_PRODUCT_FROM_DATABASE=P4B533
+
+pci:v00008086d000024C4sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v00008086d000024C4sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d000024C4sv00001462sd00005800*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d000024C4sv00001509sd00002990*
+ ID_PRODUCT_FROM_DATABASE=Averatec 5110H
+
+pci:v00008086d000024C4sv00001734sd00001004*
+ ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+
+pci:v00008086d000024C4sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d000024C4sv00008086sd000024C2*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d000024C4sv00008086sd00004541*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400/D500
+
+pci:v00008086d000024C4sv0000E4BFsd00000CC9*
+ ID_PRODUCT_FROM_DATABASE=CC9-SAMBA
+
+pci:v00008086d000024C4sv0000E4BFsd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v00008086d000024C5*
+ ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller
+
+pci:v00008086d000024C5sv00000E11sd000000B8*
+ ID_PRODUCT_FROM_DATABASE=Analog Devices Inc. codec [SoundMAX]
+
+pci:v00008086d000024C5sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d000024C5sv00001014sd00000537*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T41
+
+pci:v00008086d000024C5sv00001014sd0000055F*
+ ID_PRODUCT_FROM_DATABASE=Thinkpad R50e model 1634
+
+pci:v00008086d000024C5sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d000024C5sv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v00008086d000024C5sv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d000024C5sv00001028sd00000152*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00008086d000024C5sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d000024C5sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m [SigmaTel STAC9750,51]
+
+pci:v00008086d000024C5sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d000024C5sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d000024C5sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d000024C5sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d000024C5sv00001043sd00001713*
+ ID_PRODUCT_FROM_DATABASE=M6800N
+
+pci:v00008086d000024C5sv00001043sd000080B0*
+ ID_PRODUCT_FROM_DATABASE=P4B533
+
+pci:v00008086d000024C5sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v00008086d000024C5sv00001179sd00000201*
+ ID_PRODUCT_FROM_DATABASE=Toshiba Tecra M1
+
+pci:v00008086d000024C5sv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00008086d000024C5sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d000024C5sv00001458sd0000A002*
+ ID_PRODUCT_FROM_DATABASE=GA-8PE667 Ultra
+
+pci:v00008086d000024C5sv00001462sd00005800*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d000024C5sv00001734sd00001005*
+ ID_PRODUCT_FROM_DATABASE=D1451 (SCENIC N300, i845GV) Sigmatel STAC9750T
+
+pci:v00008086d000024C5sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d000024C5sv00008086sd000024C5*
+ ID_PRODUCT_FROM_DATABASE=Dell Dimension 2400
+
+pci:v00008086d000024C6*
+ ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller
+
+pci:v00008086d000024C6sv00001014sd00000524*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T41
+
+pci:v00008086d000024C6sv00001014sd00000525*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad
+
+pci:v00008086d000024C6sv00001014sd00000559*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R50e
+
+pci:v00008086d000024C6sv00001025sd0000003C*
+ ID_PRODUCT_FROM_DATABASE=Aspire 2001WLCi (Compal CL50 motherboard) implementation
+
+pci:v00008086d000024C6sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d000024C6sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d000024C6sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d000024C6sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d000024C6sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d000024C6sv00001043sd00001826*
+ ID_PRODUCT_FROM_DATABASE=M6800N
+
+pci:v00008086d000024C6sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v00008086d000024C6sv0000134Dsd00004C21*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00008086d000024C6sv0000144Dsd00002115*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00008086d000024C6sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d000024C6sv000014F1sd00005422*
+ ID_PRODUCT_FROM_DATABASE=D480 MDC V.9x Modem
+
+pci:v00008086d000024C7*
+ ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3
+
+pci:v00008086d000024C7sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d000024C7sv00001014sd0000052D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad
+
+pci:v00008086d000024C7sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d000024C7sv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX260
+
+pci:v00008086d000024C7sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d000024C7sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d000024C7sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d000024C7sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d000024C7sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d000024C7sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d000024C7sv00001043sd00008089*
+ ID_PRODUCT_FROM_DATABASE=P4B533
+
+pci:v00008086d000024C7sv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v00008086d000024C7sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d000024C7sv00001462sd00005800*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d000024C7sv00001509sd00002990*
+ ID_PRODUCT_FROM_DATABASE=Averatec 5110H
+
+pci:v00008086d000024C7sv00001734sd00001004*
+ ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+
+pci:v00008086d000024C7sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d000024C7sv00008086sd000024C2*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d000024C7sv00008086sd00004541*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400/D500
+
+pci:v00008086d000024C7sv0000E4BFsd00000CC9*
+ ID_PRODUCT_FROM_DATABASE=CC9-SAMBA
+
+pci:v00008086d000024C7sv0000E4BFsd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v00008086d000024CA*
+ ID_PRODUCT_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller
+
+pci:v00008086d000024CAsv00001014sd0000052D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad
+
+pci:v00008086d000024CAsv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d000024CAsv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d000024CAsv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d000024CAsv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d000024CAsv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d000024CAsv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d000024CAsv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d000024CAsv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d000024CAsv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v00008086d000024CAsv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00008086d000024CAsv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d000024CAsv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d000024CAsv00008086sd00004541*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400/D500
+
+pci:v00008086d000024CB*
+ ID_PRODUCT_FROM_DATABASE=82801DB (ICH4) IDE Controller
+
+pci:v00008086d000024CBsv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d000024CBsv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX260
+
+pci:v00008086d000024CBsv00001043sd00008089*
+ ID_PRODUCT_FROM_DATABASE=P4B533
+
+pci:v00008086d000024CBsv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8 onboard IDE
+
+pci:v00008086d000024CBsv00001458sd000024C2*
+ ID_PRODUCT_FROM_DATABASE=GA-8PE667 Ultra
+
+pci:v00008086d000024CBsv00001462sd00005800*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d000024CBsv00001734sd00001004*
+ ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+
+pci:v00008086d000024CBsv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d000024CBsv0000E4BFsd00000CC9*
+ ID_PRODUCT_FROM_DATABASE=CC9-SAMBA
+
+pci:v00008086d000024CBsv0000E4BFsd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v00008086d000024CC*
+ ID_PRODUCT_FROM_DATABASE=82801DBM (ICH4-M) LPC Interface Bridge
+
+pci:v00008086d000024CCsv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30 notebook
+
+pci:v00008086d000024CCsv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d000024CD*
+ ID_PRODUCT_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller
+
+pci:v00008086d000024CDsv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d000024CDsv00001014sd0000052E*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad
+
+pci:v00008086d000024CDsv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d000024CDsv00001028sd0000011D*
+ ID_PRODUCT_FROM_DATABASE=Latitude D600
+
+pci:v00008086d000024CDsv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX260
+
+pci:v00008086d000024CDsv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v00008086d000024CDsv00001028sd00000152*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00008086d000024CDsv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d000024CDsv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d000024CDsv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d000024CDsv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d000024CDsv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d000024CDsv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d000024CDsv00001043sd00008089*
+ ID_PRODUCT_FROM_DATABASE=P4B533
+
+pci:v00008086d000024CDsv00001071sd00008160*
+ ID_PRODUCT_FROM_DATABASE=MIM2000
+
+pci:v00008086d000024CDsv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8 onboard USB 2.0
+
+pci:v00008086d000024CDsv00001179sd0000FF00*
+ ID_PRODUCT_FROM_DATABASE=Satellite 2430
+
+pci:v00008086d000024CDsv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00008086d000024CDsv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d000024CDsv00001462sd00003981*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d000024CDsv00001509sd00001968*
+ ID_PRODUCT_FROM_DATABASE=Averatec 5110H
+
+pci:v00008086d000024CDsv00001734sd00001004*
+ ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+
+pci:v00008086d000024CDsv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d000024CDsv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d000024CDsv00008086sd000024C2*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d000024CDsv0000E4BFsd00000CC9*
+ ID_PRODUCT_FROM_DATABASE=CC9-SAMBA
+
+pci:v00008086d000024CDsv0000E4BFsd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v00008086d000024D0*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) LPC Interface Bridge
+
+pci:v00008086d000024D1*
+ ID_PRODUCT_FROM_DATABASE=82801EB (ICH5) SATA Controller
+
+pci:v00008086d000024D1sv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024D1sv00001028sd0000019A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425
+
+pci:v00008086d000024D1sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A)
+
+pci:v00008086d000024D1sv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00008086d000024D1sv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P4P800 series motherboard
+
+pci:v00008086d000024D1sv00001458sd000024D1*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d000024D1sv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024D1sv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d000024D1sv00001565sd00005200*
+ ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G)
+
+pci:v00008086d000024D1sv000015D9sd00004580*
+ ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard
+
+pci:v00008086d000024D1sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d000024D1sv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024D1sv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d000024D1sv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024D2*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1
+
+pci:v00008086d000024D2sv00001014sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024D2sv00001014sd000002ED*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024D2sv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024D2sv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 onboard UHCI
+
+pci:v00008086d000024D2sv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 onboard UHCI
+
+pci:v00008086d000024D2sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 onboard UHCI
+
+pci:v00008086d000024D2sv00001028sd00000183*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1800
+
+pci:v00008086d000024D2sv00001028sd0000019A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425
+
+pci:v00008086d000024D2sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00008086d000024D2sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A)
+
+pci:v00008086d000024D2sv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00008086d000024D2sv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard
+
+pci:v00008086d000024D2sv00001458sd000024D2*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000/8KNXP motherboard
+
+pci:v00008086d000024D2sv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024D2sv00001565sd00003101*
+ ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G)
+
+pci:v00008086d000024D2sv000015D9sd00004580*
+ ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard
+
+pci:v00008086d000024D2sv00001734sd0000101C*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard UHCI
+
+pci:v00008086d000024D2sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d000024D2sv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024D2sv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d000024D2sv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024D3*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller
+
+pci:v00008086d000024D3sv00001014sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024D3sv00001014sd000002ED*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024D3sv00001028sd00000156*
+ ID_PRODUCT_FROM_DATABASE=Precision 360
+
+pci:v00008086d000024D3sv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024D3sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d330 uT
+
+pci:v00008086d000024D3sv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00008086d000024D3sv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard
+
+pci:v00008086d000024D3sv00001458sd000024D2*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d000024D3sv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024D3sv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d000024D3sv00001565sd00003101*
+ ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G)
+
+pci:v00008086d000024D3sv000015D9sd00004580*
+ ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard
+
+pci:v00008086d000024D3sv00001734sd0000101C*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series SMBus
+
+pci:v00008086d000024D3sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d000024D3sv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024D3sv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d000024D3sv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024D4*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2
+
+pci:v00008086d000024D4sv00001014sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024D4sv00001014sd000002ED*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024D4sv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024D4sv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 onboard UHCI
+
+pci:v00008086d000024D4sv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 onboard UHCI
+
+pci:v00008086d000024D4sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 onboard UHCI
+
+pci:v00008086d000024D4sv00001028sd00000183*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1800
+
+pci:v00008086d000024D4sv00001028sd0000019A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425
+
+pci:v00008086d000024D4sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00008086d000024D4sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A)
+
+pci:v00008086d000024D4sv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00008086d000024D4sv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard
+
+pci:v00008086d000024D4sv00001458sd000024D2*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d000024D4sv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024D4sv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d000024D4sv00001565sd00003101*
+ ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G)
+
+pci:v00008086d000024D4sv000015D9sd00004580*
+ ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard
+
+pci:v00008086d000024D4sv00001734sd0000101C*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI
+
+pci:v00008086d000024D4sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d000024D4sv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024D4sv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d000024D4sv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024D5*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller
+
+pci:v00008086d000024D5sv0000100Asd0000147B*
+ ID_PRODUCT_FROM_DATABASE=Abit IS7-E motherboard
+
+pci:v00008086d000024D5sv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024D5sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00008086d000024D5sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d330 uT
+
+pci:v00008086d000024D5sv00001043sd000080F3*
+ ID_PRODUCT_FROM_DATABASE=P4P800 series motherboard
+
+pci:v00008086d000024D5sv00001043sd0000810F*
+ ID_PRODUCT_FROM_DATABASE=P5P800-MX Mainboard
+
+pci:v00008086d000024D5sv00001458sd0000A002*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000/8KNXP motherboard
+
+pci:v00008086d000024D5sv00001462sd00000080*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2-V (MS-6788) Mainboard
+
+pci:v00008086d000024D5sv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024D5sv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d000024D5sv00008086sd0000A000*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024D5sv00008086sd0000E000*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024D5sv00008086sd0000E001*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024D5sv00008086sd0000E002*
+ ID_PRODUCT_FROM_DATABASE=SoundMax Intergrated Digital Audio
+
+pci:v00008086d000024D6*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
+
+pci:v00008086d000024D6sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00008086d000024D7*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3
+
+pci:v00008086d000024D7sv00001014sd000002ED*
+ ID_PRODUCT_FROM_DATABASE=xSeries server mainboard
+
+pci:v00008086d000024D7sv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024D7sv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 onboard UHCI
+
+pci:v00008086d000024D7sv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 onboard UHCI
+
+pci:v00008086d000024D7sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 onboard UHCI
+
+pci:v00008086d000024D7sv00001028sd00000183*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1800
+
+pci:v00008086d000024D7sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00008086d000024D7sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A)
+
+pci:v00008086d000024D7sv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard
+
+pci:v00008086d000024D7sv00001458sd000024D2*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d000024D7sv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024D7sv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d000024D7sv00001565sd00003101*
+ ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G)
+
+pci:v00008086d000024D7sv000015D9sd00004580*
+ ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard
+
+pci:v00008086d000024D7sv00001734sd0000101C*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI
+
+pci:v00008086d000024D7sv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d000024D7sv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024D7sv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d000024D7sv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024DB*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller
+
+pci:v00008086d000024DBsv00001014sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024DBsv00001014sd000002ED*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024DBsv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024DBsv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 IDE Controller
+
+pci:v00008086d000024DBsv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 IDE Controller
+
+pci:v00008086d000024DBsv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 IDE Controller
+
+pci:v00008086d000024DBsv00001028sd0000019A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425
+
+pci:v00008086d000024DBsv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00008086d000024DBsv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A)
+
+pci:v00008086d000024DBsv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard
+
+pci:v00008086d000024DBsv00001458sd000024D2*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d000024DBsv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024DBsv00001462sd00007580*
+ ID_PRODUCT_FROM_DATABASE=MSI 875P
+
+pci:v00008086d000024DBsv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d000024DBsv00001565sd00003101*
+ ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G)
+
+pci:v00008086d000024DBsv000015D9sd00004580*
+ ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard
+
+pci:v00008086d000024DBsv00001734sd0000101C*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard IDE
+
+pci:v00008086d000024DBsv00008086sd000024DB*
+ ID_PRODUCT_FROM_DATABASE=P4C800 Mainboard
+
+pci:v00008086d000024DBsv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d000024DBsv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024DBsv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d000024DBsv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024DC*
+ ID_PRODUCT_FROM_DATABASE=82801EB (ICH5) LPC Interface Bridge
+
+pci:v00008086d000024DD*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller
+
+pci:v00008086d000024DDsv00001014sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024DDsv00001014sd000002ED*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d000024DDsv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024DDsv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 onboard EHCI
+
+pci:v00008086d000024DDsv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 onboard EHCI
+
+pci:v00008086d000024DDsv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 onboard EHCI
+
+pci:v00008086d000024DDsv00001028sd00000183*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1800
+
+pci:v00008086d000024DDsv00001028sd0000019A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425
+
+pci:v00008086d000024DDsv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00008086d000024DDsv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A)
+
+pci:v00008086d000024DDsv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00008086d000024DDsv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard
+
+pci:v00008086d000024DDsv00001458sd00005006*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d000024DDsv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024DDsv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d000024DDsv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d000024DDsv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024DDsv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d000024DDsv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024DE*
+ ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4
+
+pci:v00008086d000024DEsv00001014sd000002ED*
+ ID_PRODUCT_FROM_DATABASE=xSeries server mainboard
+
+pci:v00008086d000024DEsv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000024DEsv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard
+
+pci:v00008086d000024DEsv00001458sd000024D2*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d000024DEsv00001462sd00007280*
+ ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728)
+
+pci:v00008086d000024DEsv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d000024DEsv00001565sd00003101*
+ ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G)
+
+pci:v00008086d000024DEsv000015D9sd00004580*
+ ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard
+
+pci:v00008086d000024DEsv00001734sd0000101C*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI
+
+pci:v00008086d000024DEsv00008086sd00003427*
+ ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard
+
+pci:v00008086d000024DEsv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d000024DEsv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d000024DEsv00008086sd0000524C*
+ ID_PRODUCT_FROM_DATABASE=D865PERL mainboard
+
+pci:v00008086d000024DF*
+ ID_PRODUCT_FROM_DATABASE=82801ER (ICH5R) SATA Controller
+
+pci:v00008086d00002500*
+ ID_PRODUCT_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH)
+
+pci:v00008086d00002500sv00001028sd00000095*
+ ID_PRODUCT_FROM_DATABASE=Precision Workstation 220 Chipset
+
+pci:v00008086d00002500sv00001043sd0000801C*
+ ID_PRODUCT_FROM_DATABASE=P3C-2000 system chipset
+
+pci:v00008086d00002501*
+ ID_PRODUCT_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH)
+
+pci:v00008086d00002501sv00001043sd0000801C*
+ ID_PRODUCT_FROM_DATABASE=P3C-2000 system chipset
+
+pci:v00008086d0000250B*
+ ID_PRODUCT_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge
+
+pci:v00008086d0000250F*
+ ID_PRODUCT_FROM_DATABASE=82820 820 (Camino) Chipset AGP Bridge
+
+pci:v00008086d00002520*
+ ID_PRODUCT_FROM_DATABASE=82805AA MTH Memory Translator Hub
+
+pci:v00008086d00002521*
+ ID_PRODUCT_FROM_DATABASE=82804AA MRH-S Memory Repeater Hub for SDRAM
+
+pci:v00008086d00002530*
+ ID_PRODUCT_FROM_DATABASE=82850 850 (Tehama) Chipset Host Bridge (MCH)
+
+pci:v00008086d00002530sv00001028sd000000C7*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8100
+
+pci:v00008086d00002530sv0000147Bsd00000507*
+ ID_PRODUCT_FROM_DATABASE=TH7II-RAID
+
+pci:v00008086d00002531*
+ ID_PRODUCT_FROM_DATABASE=82860 860 (Wombat) Chipset Host Bridge (MCH)
+
+pci:v00008086d00002531sv00001028sd000000D8*
+ ID_PRODUCT_FROM_DATABASE=Precision 530
+
+pci:v00008086d00002532*
+ ID_PRODUCT_FROM_DATABASE=82850 850 (Tehama) Chipset AGP Bridge
+
+pci:v00008086d00002533*
+ ID_PRODUCT_FROM_DATABASE=82860 860 (Wombat) Chipset AGP Bridge
+
+pci:v00008086d00002534*
+ ID_PRODUCT_FROM_DATABASE=82860 860 (Wombat) Chipset PCI Bridge
+
+pci:v00008086d00002540*
+ ID_PRODUCT_FROM_DATABASE=E7500 Memory Controller Hub
+
+pci:v00008086d00002540sv000015D9sd00003480*
+ ID_PRODUCT_FROM_DATABASE=P4DP6
+
+pci:v00008086d00002541*
+ ID_PRODUCT_FROM_DATABASE=E7500/E7501 Host RASUM Controller
+
+pci:v00008086d00002541sv000015D9sd00003480*
+ ID_PRODUCT_FROM_DATABASE=P4DP6
+
+pci:v00008086d00002541sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d00002541sv00008086sd00003424*
+ ID_PRODUCT_FROM_DATABASE=SE7501HG2 Mainboard
+
+pci:v00008086d00002543*
+ ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface B PCI-to-PCI Bridge
+
+pci:v00008086d00002544*
+ ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface B RASUM Controller
+
+pci:v00008086d00002544sv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d00002545*
+ ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface C PCI-to-PCI Bridge
+
+pci:v00008086d00002546*
+ ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface C RASUM Controller
+
+pci:v00008086d00002547*
+ ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface D PCI-to-PCI Bridge
+
+pci:v00008086d00002548*
+ ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface D RASUM Controller
+
+pci:v00008086d0000254C*
+ ID_PRODUCT_FROM_DATABASE=E7501 Memory Controller Hub
+
+pci:v00008086d0000254Csv00004C53sd00001090*
+ ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard
+
+pci:v00008086d0000254Csv00008086sd00003424*
+ ID_PRODUCT_FROM_DATABASE=SE7501HG2 Mainboard
+
+pci:v00008086d00002550*
+ ID_PRODUCT_FROM_DATABASE=E7505 Memory Controller Hub
+
+pci:v00008086d00002551*
+ ID_PRODUCT_FROM_DATABASE=E7505/E7205 Series RAS Controller
+
+pci:v00008086d00002552*
+ ID_PRODUCT_FROM_DATABASE=E7505/E7205 PCI-to-AGP Bridge
+
+pci:v00008086d00002553*
+ ID_PRODUCT_FROM_DATABASE=E7505 Hub Interface B PCI-to-PCI Bridge
+
+pci:v00008086d00002554*
+ ID_PRODUCT_FROM_DATABASE=E7505 Hub Interface B PCI-to-PCI Bridge RAS Controller
+
+pci:v00008086d0000255D*
+ ID_PRODUCT_FROM_DATABASE=E7205 Memory Controller Hub
+
+pci:v00008086d00002560*
+ ID_PRODUCT_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface
+
+pci:v00008086d00002560sv00001028sd00000126*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX260
+
+pci:v00008086d00002560sv00001458sd00002560*
+ ID_PRODUCT_FROM_DATABASE=GA-8PE667 Ultra
+
+pci:v00008086d00002560sv00001462sd00005800*
+ ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580)
+
+pci:v00008086d00002561*
+ ID_PRODUCT_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge
+
+pci:v00008086d00002562*
+ ID_PRODUCT_FROM_DATABASE=82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device
+
+pci:v00008086d00002562sv00000E11sd000000B9*
+ ID_PRODUCT_FROM_DATABASE=Evo D510 SFF
+
+pci:v00008086d00002562sv00001014sd00000267*
+ ID_PRODUCT_FROM_DATABASE=NetVista A30p
+
+pci:v00008086d00002562sv00001734sd00001003*
+ ID_PRODUCT_FROM_DATABASE=D1521 Mainboard (Fujitsu-Siemens)
+
+pci:v00008086d00002562sv00001734sd00001004*
+ ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+
+pci:v00008086d00002570*
+ ID_PRODUCT_FROM_DATABASE=82865G/PE/P DRAM Controller/Host-Hub Interface
+
+pci:v00008086d00002570sv0000103Csd0000006A*
+ ID_PRODUCT_FROM_DATABASE=NX9500
+
+pci:v00008086d00002570sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=d330 uT
+
+pci:v00008086d00002570sv00001043sd000080F2*
+ ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard
+
+pci:v00008086d00002570sv00001458sd00002570*
+ ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+
+pci:v00008086d00002571*
+ ID_PRODUCT_FROM_DATABASE=82865G/PE/P AGP Bridge
+
+pci:v00008086d00002572*
+ ID_PRODUCT_FROM_DATABASE=82865G Integrated Graphics Controller
+
+pci:v00008086d00002572sv00001028sd0000019D*
+ ID_PRODUCT_FROM_DATABASE=Dimension 3000
+
+pci:v00008086d00002572sv0000103Csd000012BC*
+ ID_PRODUCT_FROM_DATABASE=D530 sff(dc578av)
+
+pci:v00008086d00002572sv00001043sd000080A5*
+ ID_PRODUCT_FROM_DATABASE=P5P800-MX Mainboard
+
+pci:v00008086d00002572sv00001462sd00007650*
+ ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+
+pci:v00008086d00002572sv00001734sd0000101B*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu-Siemens Scenic E300 i865GV
+
+pci:v00008086d00002572sv00008086sd00004246*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF
+
+pci:v00008086d00002572sv00008086sd00004C43*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC
+
+pci:v00008086d00002573*
+ ID_PRODUCT_FROM_DATABASE=82865G/PE/P PCI to CSA Bridge
+
+pci:v00008086d00002576*
+ ID_PRODUCT_FROM_DATABASE=82865G/PE/P Processor to I/O Memory Interface
+
+pci:v00008086d00002578*
+ ID_PRODUCT_FROM_DATABASE=82875P/E7210 Memory Controller Hub
+
+pci:v00008086d00002578sv00001458sd00002578*
+ ID_PRODUCT_FROM_DATABASE=GA-8KNXP motherboard (875P)
+
+pci:v00008086d00002578sv00001462sd00007580*
+ ID_PRODUCT_FROM_DATABASE=MS-6758 (875P Neo)
+
+pci:v00008086d00002578sv000015D9sd00004580*
+ ID_PRODUCT_FROM_DATABASE=P4SCE Motherboard
+
+pci:v00008086d00002579*
+ ID_PRODUCT_FROM_DATABASE=82875P Processor to AGP Controller
+
+pci:v00008086d0000257B*
+ ID_PRODUCT_FROM_DATABASE=82875P/E7210 Processor to PCI to CSA Bridge
+
+pci:v00008086d0000257E*
+ ID_PRODUCT_FROM_DATABASE=82875P/E7210 Processor to I/O Memory Interface
+
+pci:v00008086d00002580*
+ ID_PRODUCT_FROM_DATABASE=82915G/P/GV/GL/PL/910GL Memory Controller Hub
+
+pci:v00008086d00002580sv00001458sd00002580*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d00002580sv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d00002580sv00001734sd0000105B*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d00002581*
+ ID_PRODUCT_FROM_DATABASE=82915G/P/GV/GL/PL/910GL PCI Express Root Port
+
+pci:v00008086d00002582*
+ ID_PRODUCT_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller
+
+pci:v00008086d00002582sv00001028sd00001079*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d00002582sv0000103Csd00003006*
+ ID_PRODUCT_FROM_DATABASE=DC7100 SFF(DX878AV)
+
+pci:v00008086d00002582sv00001043sd00002582*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d00002582sv00001458sd00002582*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d00002582sv00001734sd0000105B*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d00002582sv00001849sd00002582*
+ ID_PRODUCT_FROM_DATABASE=ASRock P4Dual-915GL
+
+pci:v00008086d00002584*
+ ID_PRODUCT_FROM_DATABASE=82925X/XE Memory Controller Hub
+
+pci:v00008086d00002584sv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d00002585*
+ ID_PRODUCT_FROM_DATABASE=82925X/XE PCI Express Root Port
+
+pci:v00008086d00002588*
+ ID_PRODUCT_FROM_DATABASE=E7220/E7221 Memory Controller Hub
+
+pci:v00008086d00002589*
+ ID_PRODUCT_FROM_DATABASE=E7220/E7221 PCI Express Root Port
+
+pci:v00008086d0000258A*
+ ID_PRODUCT_FROM_DATABASE=E7221 Integrated Graphics Controller
+
+pci:v00008086d00002590*
+ ID_PRODUCT_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
+
+pci:v00008086d00002590sv00001014sd00000575*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad Z60t
+
+pci:v00008086d00002590sv00001028sd00000182*
+ ID_PRODUCT_FROM_DATABASE=Dell Latitude C610
+
+pci:v00008086d00002590sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d00002590sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d00002590sv0000104Dsd000081B7*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-S3XP
+
+pci:v00008086d00002590sv0000A304sd000081B7*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-S3XP
+
+pci:v00008086d00002590sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002590sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002590sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002591*
+ ID_PRODUCT_FROM_DATABASE=Mobile 915GM/PM Express PCI Express Root Port
+
+pci:v00008086d00002591sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+
+pci:v00008086d00002592*
+ ID_PRODUCT_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller
+
+pci:v00008086d00002592sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d00002592sv0000103Csd0000308A*
+ ID_PRODUCT_FROM_DATABASE=NC6220
+
+pci:v00008086d00002592sv00001043sd00001881*
+ ID_PRODUCT_FROM_DATABASE=GMA 900 915GM Integrated Graphics
+
+pci:v00008086d00002592sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002592sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002592sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d000025A1*
+ ID_PRODUCT_FROM_DATABASE=6300ESB LPC Interface Controller
+
+pci:v00008086d000025A2*
+ ID_PRODUCT_FROM_DATABASE=6300ESB PATA Storage Controller
+
+pci:v00008086d000025A2sv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer IDE
+
+pci:v00008086d000025A2sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025A2sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025A2sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025A2sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025A3*
+ ID_PRODUCT_FROM_DATABASE=6300ESB SATA Storage Controller
+
+pci:v00008086d000025A3sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025A3sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025A3sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025A3sv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d000025A3sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025A4*
+ ID_PRODUCT_FROM_DATABASE=6300ESB SMBus Controller
+
+pci:v00008086d000025A4sv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer
+
+pci:v00008086d000025A4sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025A4sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025A4sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025A4sv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d000025A4sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025A6*
+ ID_PRODUCT_FROM_DATABASE=6300ESB AC'97 Audio Controller
+
+pci:v00008086d000025A6sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025A6sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025A6sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025A7*
+ ID_PRODUCT_FROM_DATABASE=6300ESB AC'97 Modem Controller
+
+pci:v00008086d000025A9*
+ ID_PRODUCT_FROM_DATABASE=6300ESB USB Universal Host Controller
+
+pci:v00008086d000025A9sv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer USB
+
+pci:v00008086d000025A9sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025A9sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025A9sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025A9sv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d000025A9sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025AA*
+ ID_PRODUCT_FROM_DATABASE=6300ESB USB Universal Host Controller
+
+pci:v00008086d000025AAsv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025AAsv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025AAsv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025AAsv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d000025AAsv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025AB*
+ ID_PRODUCT_FROM_DATABASE=6300ESB Watchdog Timer
+
+pci:v00008086d000025ABsv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer
+
+pci:v00008086d000025ABsv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025ABsv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025ABsv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025ABsv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d000025ABsv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025AC*
+ ID_PRODUCT_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller
+
+pci:v00008086d000025ACsv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer
+
+pci:v00008086d000025ACsv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025ACsv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025ACsv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025ACsv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d000025ACsv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025AD*
+ ID_PRODUCT_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller
+
+pci:v00008086d000025ADsv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer USB 2.0
+
+pci:v00008086d000025ADsv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025ADsv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d000025ADsv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d000025ADsv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d000025ADsv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025AE*
+ ID_PRODUCT_FROM_DATABASE=6300ESB 64-bit PCI-X Bridge
+
+pci:v00008086d000025B0*
+ ID_PRODUCT_FROM_DATABASE=6300ESB SATA RAID Controller
+
+pci:v00008086d000025B0sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d000025B0sv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d000025B0sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d000025C0*
+ ID_PRODUCT_FROM_DATABASE=5000X Chipset Memory Controller Hub
+
+pci:v00008086d000025D0*
+ ID_PRODUCT_FROM_DATABASE=5000Z Chipset Memory Controller Hub
+
+pci:v00008086d000025D4*
+ ID_PRODUCT_FROM_DATABASE=5000V Chipset Memory Controller Hub
+
+pci:v00008086d000025D4sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d000025D8*
+ ID_PRODUCT_FROM_DATABASE=5000P Chipset Memory Controller Hub
+
+pci:v00008086d000025D8sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d000025E2*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 2
+
+pci:v00008086d000025E3*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 3
+
+pci:v00008086d000025E4*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 4
+
+pci:v00008086d000025E5*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 5
+
+pci:v00008086d000025E6*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 6
+
+pci:v00008086d000025E7*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 7
+
+pci:v00008086d000025F0*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset FSB Registers
+
+pci:v00008086d000025F0sv00001028sd000001BB*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 FSB Registers
+
+pci:v00008086d000025F0sv0000103Csd000031FD*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d000025F0sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d000025F0sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d000025F1*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset Reserved Registers
+
+pci:v00008086d000025F1sv0000103Csd000031FD*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d000025F1sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d000025F1sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d000025F3*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset Reserved Registers
+
+pci:v00008086d000025F3sv0000103Csd000031FD*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d000025F3sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d000025F3sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d000025F5*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset FBD Registers
+
+pci:v00008086d000025F5sv0000103Csd000031FD*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d000025F5sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d000025F5sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d000025F6*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset FBD Registers
+
+pci:v00008086d000025F6sv0000103Csd000031FD*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d000025F6sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d000025F6sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d000025F7*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x8 Port 2-3
+
+pci:v00008086d000025F8*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x8 Port 4-5
+
+pci:v00008086d000025F9*
+ ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x8 Port 6-7
+
+pci:v00008086d000025FA*
+ ID_PRODUCT_FROM_DATABASE=5000X Chipset PCI Express x16 Port 4-7
+
+pci:v00008086d00002600*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Hub Interface 1.5
+
+pci:v00008086d00002600sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Hub Interface
+
+pci:v00008086d00002601*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port D
+
+pci:v00008086d00002602*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port C0
+
+pci:v00008086d00002603*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port C1
+
+pci:v00008086d00002604*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port B0
+
+pci:v00008086d00002605*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port B1
+
+pci:v00008086d00002606*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port A0
+
+pci:v00008086d00002607*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port A1
+
+pci:v00008086d00002608*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x8 Port C
+
+pci:v00008086d00002609*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x8 Port B
+
+pci:v00008086d0000260A*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x8 Port A
+
+pci:v00008086d0000260C*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 IMI Registers
+
+pci:v00008086d00002610*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 FSB Registers
+
+pci:v00008086d00002611*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Address Mapping Registers
+
+pci:v00008086d00002612*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 RAS Registers
+
+pci:v00008086d00002613*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d00002614*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d00002615*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Miscellaneous Registers
+
+pci:v00008086d00002617*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d00002618*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d00002619*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d0000261A*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d0000261B*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d0000261C*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d0000261D*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d0000261E*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers
+
+pci:v00008086d00002620*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 eXternal Memory Bridge
+
+pci:v00008086d00002620sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Memory Bridge
+
+pci:v00008086d00002621*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Miscellaneous Registers
+
+pci:v00008086d00002621sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 XMB Registers
+
+pci:v00008086d00002622*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Memory Interleaving Registers
+
+pci:v00008086d00002622sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Memory Interleaving Registers
+
+pci:v00008086d00002623*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB DDR Initialization and Calibration
+
+pci:v00008086d00002623sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 DDR Initialization and Calibration
+
+pci:v00008086d00002624*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Reserved Registers
+
+pci:v00008086d00002624sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Reserved Registers
+
+pci:v00008086d00002625*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Reserved Registers
+
+pci:v00008086d00002625sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Reserved Registers
+
+pci:v00008086d00002626*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Reserved Registers
+
+pci:v00008086d00002626sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Reserved Registers
+
+pci:v00008086d00002627*
+ ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Reserved Registers
+
+pci:v00008086d00002627sv00001028sd00000170*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Reserved Registers
+
+pci:v00008086d00002640*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FR (ICH6/ICH6R) LPC Interface Bridge
+
+pci:v00008086d00002640sv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d00002640sv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d00002640sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002640sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002640sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002641*
+ ID_PRODUCT_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge
+
+pci:v00008086d00002641sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d00002641sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d00002642*
+ ID_PRODUCT_FROM_DATABASE=82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge
+
+pci:v00008086d00002651*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller
+
+pci:v00008086d00002651sv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d00002651sv00001043sd00002601*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d00002651sv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d00002651sv00008086sd00004147*
+ ID_PRODUCT_FROM_DATABASE=D915GAG Motherboard
+
+pci:v00008086d00002651sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002651sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002651sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002652*
+ ID_PRODUCT_FROM_DATABASE=82801FR/FRW (ICH6R/ICH6RW) SATA Controller
+
+pci:v00008086d00002652sv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d00002652sv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d00002653*
+ ID_PRODUCT_FROM_DATABASE=82801FBM (ICH6M) SATA Controller
+
+pci:v00008086d00002658*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1
+
+pci:v00008086d00002658sv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d00002658sv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d00002658sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d00002658sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d00002658sv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d00002658sv00001458sd00002558*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d00002658sv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d00002658sv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d00002658sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002658sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002658sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002659*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2
+
+pci:v00008086d00002659sv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d00002659sv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d00002659sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d00002659sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d00002659sv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d00002659sv00001458sd00002659*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d00002659sv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d00002659sv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d00002659sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002659sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002659sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d0000265A*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3
+
+pci:v00008086d0000265Asv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d0000265Asv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d0000265Asv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d0000265Asv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d0000265Asv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d0000265Asv00001458sd0000265A*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d0000265Asv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d0000265Asv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d0000265Asv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d0000265Asv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d0000265Asv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d0000265B*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4
+
+pci:v00008086d0000265Bsv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d0000265Bsv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d0000265Bsv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d0000265Bsv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d0000265Bsv00001458sd0000265A*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d0000265Bsv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d0000265Bsv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d0000265Bsv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d0000265Bsv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d0000265Bsv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d0000265C*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
+
+pci:v00008086d0000265Csv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d0000265Csv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d0000265Csv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d0000265Csv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d0000265Csv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d0000265Csv00001458sd00005006*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d0000265Csv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d0000265Csv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d0000265Csv00008086sd0000265C*
+ ID_PRODUCT_FROM_DATABASE=Dimension 3100
+
+pci:v00008086d0000265Csv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d0000265Csv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d0000265Csv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002660*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1
+
+pci:v00008086d00002660sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+
+pci:v00008086d00002660sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d00002660sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002660sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002660sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002662*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2
+
+pci:v00008086d00002662sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+
+pci:v00008086d00002662sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002662sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002662sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002664*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3
+
+pci:v00008086d00002664sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002664sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002664sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002666*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4
+
+pci:v00008086d00002666sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002666sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002666sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002668*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller
+
+pci:v00008086d00002668sv00001014sd000005B7*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad Z60t
+
+pci:v00008086d00002668sv0000103Csd00002A09*
+ ID_PRODUCT_FROM_DATABASE=PufferM-UL8E
+
+pci:v00008086d00002668sv00001043sd00001173*
+ ID_PRODUCT_FROM_DATABASE=Asus A6VC
+
+pci:v00008086d00002668sv00001043sd0000814E*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d00002668sv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d0000266A*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller
+
+pci:v00008086d0000266Asv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d0000266Asv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d0000266Asv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d0000266Asv00001458sd0000266A*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d0000266Asv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d0000266Asv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d0000266Asv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d0000266Asv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d0000266Asv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d0000266C*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller
+
+pci:v00008086d0000266D*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller
+
+pci:v00008086d0000266Dsv00001025sd0000006A*
+ ID_PRODUCT_FROM_DATABASE=Conexant AC'97 CoDec (in Acer TravelMate 2410 serie laptop)
+
+pci:v00008086d0000266Dsv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d0000266Dsv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d0000266E*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller
+
+pci:v00008086d0000266Esv00001025sd0000006A*
+ ID_PRODUCT_FROM_DATABASE=Realtek ALC 655 codec (in Acer TravelMate 2410 serie laptop)
+
+pci:v00008086d0000266Esv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d0000266Esv00001028sd00000179*
+ ID_PRODUCT_FROM_DATABASE=Optiplex GX280
+
+pci:v00008086d0000266Esv00001028sd00000182*
+ ID_PRODUCT_FROM_DATABASE=Latitude D610 Laptop
+
+pci:v00008086d0000266Esv00001028sd00000187*
+ ID_PRODUCT_FROM_DATABASE=Dell Precision M70 Laptop
+
+pci:v00008086d0000266Esv00001028sd00000188*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop
+
+pci:v00008086d0000266Esv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d0000266Esv0000103Csd00000944*
+ ID_PRODUCT_FROM_DATABASE=Compaq NC6220
+
+pci:v00008086d0000266Esv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d0000266Esv0000103Csd00003006*
+ ID_PRODUCT_FROM_DATABASE=DC7100 SFF(DX878AV)
+
+pci:v00008086d0000266Esv00001458sd0000A002*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d0000266Esv0000152Dsd00000745*
+ ID_PRODUCT_FROM_DATABASE=Packard Bell A8550 Laptop
+
+pci:v00008086d0000266Esv00001734sd0000105A*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d0000266F*
+ ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller
+
+pci:v00008086d0000266Fsv00001028sd00000177*
+ ID_PRODUCT_FROM_DATABASE=Dimension 8400
+
+pci:v00008086d0000266Fsv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d0000266Fsv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d0000266Fsv00001043sd000080A6*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d0000266Fsv00001458sd0000266F*
+ ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard
+
+pci:v00008086d0000266Fsv00001462sd00007028*
+ ID_PRODUCT_FROM_DATABASE=915P/G Neo2
+
+pci:v00008086d0000266Fsv00001734sd0000105C*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d0000266Fsv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d0000266Fsv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d0000266Fsv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d00002670*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller
+
+pci:v00008086d00002670sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d00002670sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d00002670sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d00002680*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset SATA IDE Controller
+
+pci:v00008086d00002681*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller
+
+pci:v00008086d00002681sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d00002681sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d00002681sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d00002682*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB SATA RAID Controller
+
+pci:v00008086d00002682sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=Adaptec Serial ATA HostRAID
+
+pci:v00008086d00002683*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB SATA RAID Controller
+
+pci:v00008086d00002688*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1
+
+pci:v00008086d00002688sv00001028sd000001BB*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 onboard USB
+
+pci:v00008086d00002688sv00001028sd000001F0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB
+
+pci:v00008086d00002688sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d00002688sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d00002688sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d00002689*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2
+
+pci:v00008086d00002689sv00001028sd000001BB*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 onboard USB
+
+pci:v00008086d00002689sv00001028sd000001F0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB
+
+pci:v00008086d00002689sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d00002689sv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d00002689sv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d0000268A*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3
+
+pci:v00008086d0000268Asv00001028sd000001F0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB
+
+pci:v00008086d0000268Asv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d0000268Asv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d0000268Asv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d0000268B*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4
+
+pci:v00008086d0000268Bsv00001028sd000001F0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB
+
+pci:v00008086d0000268Bsv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d0000268Bsv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d0000268C*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller
+
+pci:v00008086d0000268Csv00001028sd000001BB*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 onboard USB
+
+pci:v00008086d0000268Csv00001028sd000001F0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB
+
+pci:v00008086d0000268Csv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d0000268Csv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d0000268Csv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d00002690*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 1
+
+pci:v00008086d00002690sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d00002692*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 2
+
+pci:v00008086d00002692sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d00002694*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 3
+
+pci:v00008086d00002696*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 4
+
+pci:v00008086d00002698*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB AC '97 Audio Controller
+
+pci:v00008086d00002699*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB AC '97 Modem Controller
+
+pci:v00008086d0000269A*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB High Definition Audio Controller
+
+pci:v00008086d0000269B*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller
+
+pci:v00008086d0000269Bsv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d0000269Bsv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d0000269Bsv00008086sd00003476*
+ ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board
+
+pci:v00008086d0000269E*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB IDE Controller
+
+pci:v00008086d0000269Esv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d0000269Esv000015D9sd00008680*
+ ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard
+
+pci:v00008086d00002770*
+ ID_PRODUCT_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub
+
+pci:v00008086d00002770sv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d00002770sv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d00002770sv00001043sd0000817A*
+ ID_PRODUCT_FROM_DATABASE=P5LD2-VM Mainboard
+
+pci:v00008086d00002770sv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d00002770sv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d00002771*
+ ID_PRODUCT_FROM_DATABASE=82945G/GZ/P/PL PCI Express Root Port
+
+pci:v00008086d00002772*
+ ID_PRODUCT_FROM_DATABASE=82945G/GZ Integrated Graphics Controller
+
+pci:v00008086d00002772sv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d00002772sv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d00002772sv00008086sd0000D605*
+ ID_PRODUCT_FROM_DATABASE=Intel Desktop Board D945GCCR
+
+pci:v00008086d00002774*
+ ID_PRODUCT_FROM_DATABASE=82955X Memory Controller Hub
+
+pci:v00008086d00002775*
+ ID_PRODUCT_FROM_DATABASE=82955X PCI Express Root Port
+
+pci:v00008086d00002776*
+ ID_PRODUCT_FROM_DATABASE=82945G/GZ Integrated Graphics Controller
+
+pci:v00008086d00002778*
+ ID_PRODUCT_FROM_DATABASE=E7230/3000/3010 Memory Controller Hub
+
+pci:v00008086d00002778sv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d00002778sv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d00002779*
+ ID_PRODUCT_FROM_DATABASE=E7230/3000/3010 PCI Express Root Port
+
+pci:v00008086d0000277A*
+ ID_PRODUCT_FROM_DATABASE=82975X/3010 PCI Express Root Port
+
+pci:v00008086d0000277C*
+ ID_PRODUCT_FROM_DATABASE=82975X Memory Controller Hub
+
+pci:v00008086d0000277Csv00001043sd00008178*
+ ID_PRODUCT_FROM_DATABASE=P5WDG2 WS Professional motherboard
+
+pci:v00008086d0000277D*
+ ID_PRODUCT_FROM_DATABASE=82975X PCI Express Root Port
+
+pci:v00008086d00002782*
+ ID_PRODUCT_FROM_DATABASE=82915G Integrated Graphics Controller
+
+pci:v00008086d00002782sv00001043sd00002582*
+ ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard
+
+pci:v00008086d00002782sv00001734sd0000105B*
+ ID_PRODUCT_FROM_DATABASE=Scenic W620
+
+pci:v00008086d00002792*
+ ID_PRODUCT_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller
+
+pci:v00008086d00002792sv0000103Csd0000099C*
+ ID_PRODUCT_FROM_DATABASE=NX6110/NC6120
+
+pci:v00008086d00002792sv00001043sd00001881*
+ ID_PRODUCT_FROM_DATABASE=GMA 900 915GM Integrated Graphics
+
+pci:v00008086d00002792sv0000E4BFsd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v00008086d00002792sv0000E4BFsd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v00008086d00002792sv0000E4BFsd000058B1*
+ ID_PRODUCT_FROM_DATABASE=XB1
+
+pci:v00008086d000027A0*
+ ID_PRODUCT_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub
+
+pci:v00008086d000027A0sv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027A0sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027A0sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027A0sv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027A0sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027A0sv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00008086d000027A0sv000017AAsd00002015*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60
+
+pci:v00008086d000027A0sv000017AAsd00002017*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027A1*
+ ID_PRODUCT_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port
+
+pci:v00008086d000027A1sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027A1sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027A2*
+ ID_PRODUCT_FROM_DATABASE=Mobile 945GM/GMS, 943/940GML Express Integrated Graphics Controller
+
+pci:v00008086d000027A2sv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027A2sv000017AAsd0000201A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027A2sv00009902sd00001584*
+ ID_PRODUCT_FROM_DATABASE=CCE MPL-D10H120F
+
+pci:v00008086d000027A6*
+ ID_PRODUCT_FROM_DATABASE=Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller
+
+pci:v00008086d000027A6sv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027A6sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11 integrated graphics (secondary)
+
+pci:v00008086d000027A6sv000017AAsd0000201A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027AC*
+ ID_PRODUCT_FROM_DATABASE=Mobile 945GSE Express Memory Controller Hub
+
+pci:v00008086d000027ACsv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027AD*
+ ID_PRODUCT_FROM_DATABASE=Mobile 945GSE Express PCI Express Root Port
+
+pci:v00008086d000027AE*
+ ID_PRODUCT_FROM_DATABASE=Mobile 945GSE Express Integrated Graphics Controller
+
+pci:v00008086d000027AEsv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11 integrated graphics (primary)
+
+pci:v00008086d000027B0*
+ ID_PRODUCT_FROM_DATABASE=82801GH (ICH7DH) LPC Interface Bridge
+
+pci:v00008086d000027B0sv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027B0sv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027B8*
+ ID_PRODUCT_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge
+
+pci:v00008086d000027B8sv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d000027B8sv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00008086d000027B8sv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d000027B8sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027B8sv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027B9*
+ ID_PRODUCT_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge
+
+pci:v00008086d000027B9sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027B9sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027B9sv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027B9sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027B9sv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop
+
+pci:v00008086d000027B9sv000017AAsd00002009*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027BC*
+ ID_PRODUCT_FROM_DATABASE=NM10 Family LPC Controller
+
+pci:v00008086d000027BCsv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027BCsv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027BD*
+ ID_PRODUCT_FROM_DATABASE=82801GHM (ICH7-M DH) LPC Interface Bridge
+
+pci:v00008086d000027BDsv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027C0*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode]
+
+pci:v00008086d000027C0sv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d000027C0sv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027C0sv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d000027C0sv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00008086d000027C0sv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d000027C0sv00001462sd00002310*
+ ID_PRODUCT_FROM_DATABASE=MSI Hetis 945
+
+pci:v00008086d000027C0sv00001462sd00007236*
+ ID_PRODUCT_FROM_DATABASE=945P Neo3-F Rev. 2.2 motherboard
+
+pci:v00008086d000027C0sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027C0sv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027C1*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode]
+
+pci:v00008086d000027C1sv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027C1sv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027C1sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027C1sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027C1sv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027C1sv00008086sd00005842*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D975XBX
+
+pci:v00008086d000027C3*
+ ID_PRODUCT_FROM_DATABASE=82801GR/GDH (ICH7R/ICH7DH) SATA Controller [RAID mode]
+
+pci:v00008086d000027C3sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027C3sv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027C4*
+ ID_PRODUCT_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [IDE mode]
+
+pci:v00008086d000027C4sv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027C4sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027C4sv000017AAsd0000200E*
+ ID_PRODUCT_FROM_DATABASE=Thinkpad T60 model 2007
+
+pci:v00008086d000027C5*
+ ID_PRODUCT_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [AHCI mode]
+
+pci:v00008086d000027C5sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027C5sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027C5sv000017AAsd0000200D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027C6*
+ ID_PRODUCT_FROM_DATABASE=82801GHM (ICH7-M DH) SATA Controller [RAID mode]
+
+pci:v00008086d000027C8*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1
+
+pci:v00008086d000027C8sv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027C8sv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d000027C8sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027C8sv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027C8sv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d000027C8sv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027C8sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027C8sv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027C8sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027C8sv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00008086d000027C8sv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+
+pci:v00008086d000027C8sv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d000027C8sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027C8sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027C8sv000017AAsd0000200A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027C8sv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027C8sv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027C9*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2
+
+pci:v00008086d000027C9sv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027C9sv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d000027C9sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027C9sv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027C9sv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d000027C9sv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027C9sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027C9sv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027C9sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027C9sv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00008086d000027C9sv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+
+pci:v00008086d000027C9sv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d000027C9sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027C9sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027C9sv000017AAsd0000200A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027C9sv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027C9sv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027CA*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3
+
+pci:v00008086d000027CAsv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027CAsv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d000027CAsv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027CAsv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027CAsv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d000027CAsv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027CAsv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027CAsv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027CAsv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027CAsv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00008086d000027CAsv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+
+pci:v00008086d000027CAsv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d000027CAsv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027CAsv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027CAsv000017AAsd0000200A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027CAsv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027CAsv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027CB*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4
+
+pci:v00008086d000027CBsv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027CBsv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d000027CBsv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027CBsv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027CBsv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027CBsv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027CBsv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027CBsv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027CBsv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00008086d000027CBsv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+
+pci:v00008086d000027CBsv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d000027CBsv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027CBsv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027CBsv000017AAsd0000200A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027CBsv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027CBsv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027CC*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller
+
+pci:v00008086d000027CCsv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027CCsv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d000027CCsv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027CCsv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027CCsv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d000027CCsv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027CCsv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027CCsv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027CCsv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027CCsv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00008086d000027CCsv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+
+pci:v00008086d000027CCsv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027CCsv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027CCsv000017AAsd0000200B*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027CCsv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027CCsv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027D0*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1
+
+pci:v00008086d000027D0sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027D0sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027D0sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027D0sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027D2*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2
+
+pci:v00008086d000027D2sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027D2sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027D2sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027D2sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027D4*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 3
+
+pci:v00008086d000027D4sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027D4sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027D6*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4
+
+pci:v00008086d000027D6sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027D6sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027D6sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027D8*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller
+
+pci:v00008086d000027D8sv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027D8sv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027D8sv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027D8sv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027D8sv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027D8sv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027D8sv00001043sd00001123*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00008086d000027D8sv00001043sd000013C4*
+ ID_PRODUCT_FROM_DATABASE=Asus G2P
+
+pci:v00008086d000027D8sv00001043sd0000817F*
+ ID_PRODUCT_FROM_DATABASE=P5LD2-VM Mainboard (Realtek ALC 882 codec)
+
+pci:v00008086d000027D8sv00001043sd00008290*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00008086d000027D8sv00001043sd000082EA*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-CM Motherboard
+
+pci:v00008086d000027D8sv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d000027D8sv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop
+
+pci:v00008086d000027D8sv00001179sd0000FF10*
+ ID_PRODUCT_FROM_DATABASE=Toshiba Satellite A100-796 audio (Realtek ALC861)
+
+pci:v00008086d000027D8sv00001179sd0000FF31*
+ ID_PRODUCT_FROM_DATABASE=AC97 Data Fax SoftModem with SmartCP
+
+pci:v00008086d000027D8sv00001447sd00001043*
+ ID_PRODUCT_FROM_DATABASE=Asus A8JP (Analog Devices AD1986A)
+
+pci:v00008086d000027D8sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027D8sv00001458sd0000A102*
+ ID_PRODUCT_FROM_DATABASE=GA-8I945PG-RH Mainboard
+
+pci:v00008086d000027D8sv0000152Dsd00000753*
+ ID_PRODUCT_FROM_DATABASE=Softmodem
+
+pci:v00008086d000027D8sv00001734sd000010AD*
+ ID_PRODUCT_FROM_DATABASE=Conexant softmodem SmartCP
+
+pci:v00008086d000027D8sv000017AAsd00002010*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027D8sv000017AAsd00003802*
+ ID_PRODUCT_FROM_DATABASE=Lenovo 3000 C200 audio [Realtek ALC861VD]
+
+pci:v00008086d000027D8sv00008086sd00001112*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027D8sv00008086sd000027D8*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027D8sv00008086sd0000D618*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027D8sv00008384sd00007680*
+ ID_PRODUCT_FROM_DATABASE=STAC9221 HD Audio Codec
+
+pci:v00008086d000027DA*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family SMBus Controller
+
+pci:v00008086d000027DAsv00001025sd0000006C*
+ ID_PRODUCT_FROM_DATABASE=9814 WKMI
+
+pci:v00008086d000027DAsv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d000027DAsv00001028sd000001D7*
+ ID_PRODUCT_FROM_DATABASE=XPS M1210
+
+pci:v00008086d000027DAsv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027DAsv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d000027DAsv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027DAsv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00008086d000027DAsv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop
+
+pci:v00008086d000027DAsv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d000027DAsv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-8I945PG-RH Mainboard
+
+pci:v00008086d000027DAsv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027DAsv000017AAsd0000200F*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027DAsv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d000027DAsv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027DAsv00008086sd00005842*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D975XBX
+
+pci:v00008086d000027DC*
+ ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family LAN Controller
+
+pci:v00008086d000027DCsv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027DCsv00008086sd0000308D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027DD*
+ ID_PRODUCT_FROM_DATABASE=82801G (ICH7 Family) AC'97 Modem Controller
+
+pci:v00008086d000027DE*
+ ID_PRODUCT_FROM_DATABASE=82801G (ICH7 Family) AC'97 Audio Controller
+
+pci:v00008086d000027DEsv00001028sd000001AD*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX620
+
+pci:v00008086d000027DEsv00001462sd00007267*
+ ID_PRODUCT_FROM_DATABASE=Realtek ALC883 Audio Controller
+
+pci:v00008086d000027DEsv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11 integrated audio (AD1981BL codec)
+
+pci:v00008086d000027DF*
+ ID_PRODUCT_FROM_DATABASE=82801G (ICH7 Family) IDE Controller
+
+pci:v00008086d000027DFsv00001028sd000001DF*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC440
+
+pci:v00008086d000027DFsv00001028sd000001E6*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 860
+
+pci:v00008086d000027DFsv0000103Csd00002A3B*
+ ID_PRODUCT_FROM_DATABASE=Pavilion A1512X
+
+pci:v00008086d000027DFsv0000103Csd0000309F*
+ ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook
+
+pci:v00008086d000027DFsv0000103Csd000030A1*
+ ID_PRODUCT_FROM_DATABASE=NC2400
+
+pci:v00008086d000027DFsv0000103Csd000030A3*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8440
+
+pci:v00008086d000027DFsv00001043sd00001237*
+ ID_PRODUCT_FROM_DATABASE=A6J-Q008
+
+pci:v00008086d000027DFsv00001043sd00008179*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00008086d000027DFsv0000107Bsd00005048*
+ ID_PRODUCT_FROM_DATABASE=E4500
+
+pci:v00008086d000027DFsv000010F7sd00008338*
+ ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop
+
+pci:v00008086d000027DFsv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027DFsv000017AAsd0000200C*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series
+
+pci:v00008086d000027DFsv00008086sd0000544E*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP
+
+pci:v00008086d000027E0*
+ ID_PRODUCT_FROM_DATABASE=82801GR/GH/GHM (ICH7 Family) PCI Express Port 5
+
+pci:v00008086d000027E0sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d000027E2*
+ ID_PRODUCT_FROM_DATABASE=82801GR/GH/GHM (ICH7 Family) PCI Express Port 6
+
+pci:v00008086d000027E2sv00001775sd000011CC*
+ ID_PRODUCT_FROM_DATABASE=CC11/CL11
+
+pci:v00008086d00002802*
+ ID_PRODUCT_FROM_DATABASE=82GL40 [Cantiga] High Definition Audio HDMI Service
+
+pci:v00008086d00002810*
+ ID_PRODUCT_FROM_DATABASE=82801HB/HR (ICH8/R) LPC Interface Controller
+
+pci:v00008086d00002810sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002811*
+ ID_PRODUCT_FROM_DATABASE=82801HEM (ICH8M-E) LPC Interface Controller
+
+pci:v00008086d00002811sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002811sv000017AAsd000020B6*
+ ID_PRODUCT_FROM_DATABASE=T61
+
+pci:v00008086d00002811sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002812*
+ ID_PRODUCT_FROM_DATABASE=82801HH (ICH8DH) LPC Interface Controller
+
+pci:v00008086d00002814*
+ ID_PRODUCT_FROM_DATABASE=82801HO (ICH8DO) LPC Interface Controller
+
+pci:v00008086d00002815*
+ ID_PRODUCT_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller
+
+pci:v00008086d00002815sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d00002815sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002815sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002815sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002815sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002815sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002815sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002820*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) 4 port SATA Controller [IDE mode]
+
+pci:v00008086d00002820sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002820sv00001462sd00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v00008086d00002821*
+ ID_PRODUCT_FROM_DATABASE=82801HR/HO/HH (ICH8R/DO/DH) 6 port SATA Controller [AHCI mode]
+
+pci:v00008086d00002822*
+ ID_PRODUCT_FROM_DATABASE=82801 SATA Controller [RAID mode]
+
+pci:v00008086d00002822sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002823*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA RAID Controller
+
+pci:v00008086d00002824*
+ ID_PRODUCT_FROM_DATABASE=82801HB (ICH8) 4 port SATA Controller [AHCI mode]
+
+pci:v00008086d00002824sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002825*
+ ID_PRODUCT_FROM_DATABASE=82801HR/HO/HH (ICH8R/DO/DH) 2 port SATA Controller [IDE mode]
+
+pci:v00008086d00002825sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002825sv00001462sd00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v00008086d00002826*
+ ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller
+
+pci:v00008086d00002827*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA RAID Controller
+
+pci:v00008086d00002828*
+ ID_PRODUCT_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode]
+
+pci:v00008086d00002828sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002828sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002828sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002829*
+ ID_PRODUCT_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode]
+
+pci:v00008086d00002829sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d00002829sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002829sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002829sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002829sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002829sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002829sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002829sv000017AAsd000020A7*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002829sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d0000282A*
+ ID_PRODUCT_FROM_DATABASE=82801 Mobile SATA Controller [RAID mode]
+
+pci:v00008086d0000282Asv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d0000282Asv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00002830*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1
+
+pci:v00008086d00002830sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Acer Aspire 5920G
+
+pci:v00008086d00002830sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002830sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002830sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002830sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002830sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002830sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002830sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002830sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002830sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002830sv00001462sd00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v00008086d00002830sv000017AAsd000020AA*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002830sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002831*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2
+
+pci:v00008086d00002831sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d00002831sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002831sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002831sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002831sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002831sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002831sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002831sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002831sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002831sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002831sv00001462sd00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v00008086d00002831sv000017AAsd000020AA*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002831sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002832*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3
+
+pci:v00008086d00002832sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d00002832sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002832sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002832sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002832sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002832sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002832sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002832sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002832sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002832sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002832sv000017AAsd000020AA*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002832sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002833*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4
+
+pci:v00008086d00002833sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002834*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4
+
+pci:v00008086d00002834sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d00002834sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002834sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002834sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002834sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002834sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002834sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002834sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002834sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002834sv00001462sd00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v00008086d00002834sv000017AAsd000020AA*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002834sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002835*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5
+
+pci:v00008086d00002835sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Acer Aspire 5920G
+
+pci:v00008086d00002835sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002835sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002835sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002835sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002835sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002835sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002835sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002835sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002835sv000017AAsd000020AA*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T60
+
+pci:v00008086d00002835sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002836*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1
+
+pci:v00008086d00002836sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d00002836sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002836sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002836sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002836sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002836sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002836sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002836sv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d00002836sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002836sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002836sv00001462sd00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v00008086d00002836sv000017AAsd000020AB*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002836sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d0000283A*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2
+
+pci:v00008086d0000283Asv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Acer Aspire 5920G
+
+pci:v00008086d0000283Asv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d0000283Asv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d0000283Asv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d0000283Asv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d0000283Asv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d0000283Asv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d0000283Asv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d0000283Asv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d0000283Asv000017AAsd000020AB*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d0000283Asv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d0000283E*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller
+
+pci:v00008086d0000283Esv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d0000283Esv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d0000283Esv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d0000283Esv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d0000283Esv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d0000283Esv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d0000283Esv0000104Dsd00009008*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-SZ79SN_C
+
+pci:v00008086d0000283Esv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d0000283Esv00001462sd00007235*
+ ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard
+
+pci:v00008086d0000283Esv000017AAsd000020A9*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d0000283Esv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d0000283F*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1
+
+pci:v00008086d0000283Fsv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d0000283Fsv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d0000283Fsv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d0000283Fsv000017AAsd000020AD*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002841*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2
+
+pci:v00008086d00002841sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002841sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002841sv000017AAsd000020AD*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002843*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3
+
+pci:v00008086d00002843sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002843sv000017AAsd000020AD*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002845*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4
+
+pci:v00008086d00002845sv000017AAsd000020AD*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002847*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 5
+
+pci:v00008086d00002847sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002847sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002847sv000017AAsd000020AD*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002849*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 6
+
+pci:v00008086d0000284B*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller
+
+pci:v00008086d0000284Bsv00001025sd0000011F*
+ ID_PRODUCT_FROM_DATABASE=Realtek ALC268 audio codec
+
+pci:v00008086d0000284Bsv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d0000284Bsv00001025sd00000145*
+ ID_PRODUCT_FROM_DATABASE=Realtek ALC889 (Aspire 8920G w. Dolby Theather)
+
+pci:v00008086d0000284Bsv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d0000284Bsv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d0000284Bsv00001028sd000001F9*
+ ID_PRODUCT_FROM_DATABASE=Dell Latitude D630
+
+pci:v00008086d0000284Bsv00001028sd000001FF*
+ ID_PRODUCT_FROM_DATABASE=Dell Precision M4300
+
+pci:v00008086d0000284Bsv00001028sd00000256*
+ ID_PRODUCT_FROM_DATABASE=Studio 1735
+
+pci:v00008086d0000284Bsv0000103Csd00002802*
+ ID_PRODUCT_FROM_DATABASE=HP Compaq dc7700p
+
+pci:v00008086d0000284Bsv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d0000284Bsv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d0000284Bsv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d0000284Bsv00001043sd00001339*
+ ID_PRODUCT_FROM_DATABASE=Asus M51S series
+
+pci:v00008086d0000284Bsv00001043sd000081EC*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d0000284Bsv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d0000284Bsv0000104Dsd00009008*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-SZ79SN_C
+
+pci:v00008086d0000284Bsv0000104Dsd00009016*
+ ID_PRODUCT_FROM_DATABASE=Sony VAIO VGN-AR51M
+
+pci:v00008086d0000284Bsv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d0000284Bsv000014F1sd00005051*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d0000284Bsv000017AAsd000020AC*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d0000284Bsv00008384sd00007616*
+ ID_PRODUCT_FROM_DATABASE=Dell Vostro 1400
+
+pci:v00008086d0000284Bsv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d0000284F*
+ ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) Thermal Reporting Device
+
+pci:v00008086d00002850*
+ ID_PRODUCT_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller
+
+pci:v00008086d00002850sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Aspire 5920G
+
+pci:v00008086d00002850sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002850sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002850sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002850sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002850sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002850sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002850sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002850sv000017AAsd000020A6*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002850sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002912*
+ ID_PRODUCT_FROM_DATABASE=82801IH (ICH9DH) LPC Interface Controller
+
+pci:v00008086d00002914*
+ ID_PRODUCT_FROM_DATABASE=82801IO (ICH9DO) LPC Interface Controller
+
+pci:v00008086d00002914sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002916*
+ ID_PRODUCT_FROM_DATABASE=82801IR (ICH9R) LPC Interface Controller
+
+pci:v00008086d00002916sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002916sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002917*
+ ID_PRODUCT_FROM_DATABASE=ICH9M-E LPC Interface Controller
+
+pci:v00008086d00002917sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002918*
+ ID_PRODUCT_FROM_DATABASE=82801IB (ICH9) LPC Interface Controller
+
+pci:v00008086d00002918sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 82801IB (ICH9) LPC Interface Controller
+
+pci:v00008086d00002918sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002919*
+ ID_PRODUCT_FROM_DATABASE=ICH9M LPC Interface Controller
+
+pci:v00008086d00002920*
+ ID_PRODUCT_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode]
+
+pci:v00008086d00002920sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002920sv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard SATA Controller
+
+pci:v00008086d00002920sv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard SATA Controller
+
+pci:v00008086d00002920sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002920sv00001028sd0000023C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard SATA Controller
+
+pci:v00008086d00002921*
+ ID_PRODUCT_FROM_DATABASE=82801IB (ICH9) 2 port SATA Controller [IDE mode]
+
+pci:v00008086d00002921sv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 SATA IDE Controller
+
+pci:v00008086d00002921sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 SATA IDE Controller
+
+pci:v00008086d00002921sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 SATA IDE Controller
+
+pci:v00008086d00002921sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002922*
+ ID_PRODUCT_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode]
+
+pci:v00008086d00002922sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002923*
+ ID_PRODUCT_FROM_DATABASE=82801IB (ICH9) 4 port SATA Controller [AHCI mode]
+
+pci:v00008086d00002925*
+ ID_PRODUCT_FROM_DATABASE=82801IR/IO (ICH9R/DO) SATA Controller [RAID mode]
+
+pci:v00008086d00002925sv00001734sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=System Board D2542
+
+pci:v00008086d00002925sv00008086sd00002925*
+ ID_PRODUCT_FROM_DATABASE=System Board D2542
+
+pci:v00008086d00002926*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode]
+
+pci:v00008086d00002926sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002926sv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard SATA Controller
+
+pci:v00008086d00002926sv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard SATA Controller
+
+pci:v00008086d00002926sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002926sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002928*
+ ID_PRODUCT_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 2 port SATA Controller [IDE mode]
+
+pci:v00008086d00002929*
+ ID_PRODUCT_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode]
+
+pci:v00008086d00002929sv0000103Csd00003628*
+ ID_PRODUCT_FROM_DATABASE=dv6-1190en
+
+pci:v00008086d00002929sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d0000292C*
+ ID_PRODUCT_FROM_DATABASE=82801IEM (ICH9M-E) SATA Controller [RAID mode]
+
+pci:v00008086d0000292D*
+ ID_PRODUCT_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 2 port SATA Controller [IDE mode]
+
+pci:v00008086d0000292Dsv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002930*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller
+
+pci:v00008086d00002930sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002930sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002930sv0000103Csd00003628*
+ ID_PRODUCT_FROM_DATABASE=dv6-1190en
+
+pci:v00008086d00002930sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002930sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002930sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002932*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) Thermal Subsystem
+
+pci:v00008086d00002932sv0000103Csd00003628*
+ ID_PRODUCT_FROM_DATABASE=dv6-1190en
+
+pci:v00008086d00002934*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1
+
+pci:v00008086d00002934sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002934sv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard UHCI
+
+pci:v00008086d00002934sv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard UHCI
+
+pci:v00008086d00002934sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002934sv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB UHCI Controller
+
+pci:v00008086d00002934sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB UHCI Controller
+
+pci:v00008086d00002934sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+
+pci:v00008086d00002934sv00001028sd0000023C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard UHCI
+
+pci:v00008086d00002934sv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI
+
+pci:v00008086d00002934sv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+
+pci:v00008086d00002934sv00001028sd00002011*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002934sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002934sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002934sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002935*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2
+
+pci:v00008086d00002935sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002935sv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard UHCI
+
+pci:v00008086d00002935sv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard UHCI
+
+pci:v00008086d00002935sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002935sv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB UHCI Controller
+
+pci:v00008086d00002935sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB UHCI Controller
+
+pci:v00008086d00002935sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+
+pci:v00008086d00002935sv00001028sd0000023C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard UHCI
+
+pci:v00008086d00002935sv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI
+
+pci:v00008086d00002935sv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+
+pci:v00008086d00002935sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002935sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002935sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002936*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3
+
+pci:v00008086d00002936sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002936sv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard UHCI
+
+pci:v00008086d00002936sv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard UHCI
+
+pci:v00008086d00002936sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002936sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+
+pci:v00008086d00002936sv00001028sd0000023C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard UHCI
+
+pci:v00008086d00002936sv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI
+
+pci:v00008086d00002936sv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+
+pci:v00008086d00002936sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002936sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002936sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002937*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4
+
+pci:v00008086d00002937sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002937sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002937sv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB UHCI Controller
+
+pci:v00008086d00002937sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB UHCI Controller
+
+pci:v00008086d00002937sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+
+pci:v00008086d00002937sv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI
+
+pci:v00008086d00002937sv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+
+pci:v00008086d00002937sv00001028sd00002011*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002937sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002937sv00008086sd00002937*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002937sv00008086sd00002942*
+ ID_PRODUCT_FROM_DATABASE=828011 (ICH9 Family ) USB UHCI Controller
+
+pci:v00008086d00002937sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002937sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002938*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5
+
+pci:v00008086d00002938sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002938sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002938sv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB UHCI Controller
+
+pci:v00008086d00002938sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB UHCI Controller
+
+pci:v00008086d00002938sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+
+pci:v00008086d00002938sv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI
+
+pci:v00008086d00002938sv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+
+pci:v00008086d00002938sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002938sv00008086sd00002938*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002938sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002938sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002939*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6
+
+pci:v00008086d00002939sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002939sv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard UHCI
+
+pci:v00008086d00002939sv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+
+pci:v00008086d00002939sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d00002939sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d00002939sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d0000293A*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1
+
+pci:v00008086d0000293Asv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d0000293Asv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard EHCI
+
+pci:v00008086d0000293Asv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard EHCI
+
+pci:v00008086d0000293Asv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d0000293Asv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB EHCI Controller
+
+pci:v00008086d0000293Asv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB EHCI Controller
+
+pci:v00008086d0000293Asv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB EHCI Controller
+
+pci:v00008086d0000293Asv00001028sd0000023C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard EHCI
+
+pci:v00008086d0000293Asv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard EHCI
+
+pci:v00008086d0000293Asv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB EHCI Controller
+
+pci:v00008086d0000293Asv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d0000293Asv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d0000293Asv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d0000293C*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2
+
+pci:v00008086d0000293Csv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d0000293Csv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d0000293Csv00001028sd00000235*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB EHCI Controller
+
+pci:v00008086d0000293Csv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB EHCI Controller
+
+pci:v00008086d0000293Csv00001028sd00000237*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB EHCI Controller
+
+pci:v00008086d0000293Csv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard EHCI
+
+pci:v00008086d0000293Csv00001028sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB EHCI Controller
+
+pci:v00008086d0000293Csv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d0000293Csv00008086sd0000293C*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d0000293Csv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d0000293Csv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d0000293E*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller
+
+pci:v00008086d0000293Esv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d0000293Esv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d0000293Esv0000103Csd00003628*
+ ID_PRODUCT_FROM_DATABASE=dv6-1190en
+
+pci:v00008086d0000293Esv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d0000293Esv00008086sd0000293E*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d0000293Esv00008086sd00002940*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d0000293Esv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002940*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1
+
+pci:v00008086d00002940sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002940sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002940sv00008086sd00002940*
+ ID_PRODUCT_FROM_DATABASE=Optiplex 755
+
+pci:v00008086d00002942*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 2
+
+pci:v00008086d00002942sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002944*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 3
+
+pci:v00008086d00002944sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002946*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 4
+
+pci:v00008086d00002946sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d00002948*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 5
+
+pci:v00008086d00002948sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d0000294A*
+ ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6
+
+pci:v00008086d0000294Asv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d0000294C*
+ ID_PRODUCT_FROM_DATABASE=82566DC-2 Gigabit Network Connection
+
+pci:v00008086d0000294Csv000017AAsd0000302E*
+ ID_PRODUCT_FROM_DATABASE=82566DM-2 Gigabit Network Connection
+
+pci:v00008086d00002970*
+ ID_PRODUCT_FROM_DATABASE=82946GZ/PL/GL Memory Controller Hub
+
+pci:v00008086d00002971*
+ ID_PRODUCT_FROM_DATABASE=82946GZ/PL/GL PCI Express Root Port
+
+pci:v00008086d00002972*
+ ID_PRODUCT_FROM_DATABASE=82946GZ/GL Integrated Graphics Controller
+
+pci:v00008086d00002973*
+ ID_PRODUCT_FROM_DATABASE=82946GZ/GL Integrated Graphics Controller
+
+pci:v00008086d00002974*
+ ID_PRODUCT_FROM_DATABASE=82946GZ/GL HECI Controller
+
+pci:v00008086d00002975*
+ ID_PRODUCT_FROM_DATABASE=82946GZ/GL HECI Controller
+
+pci:v00008086d00002976*
+ ID_PRODUCT_FROM_DATABASE=82946GZ/GL PT IDER Controller
+
+pci:v00008086d00002977*
+ ID_PRODUCT_FROM_DATABASE=82946GZ/GL KT Controller
+
+pci:v00008086d00002980*
+ ID_PRODUCT_FROM_DATABASE=82G35 Express DRAM Controller
+
+pci:v00008086d00002981*
+ ID_PRODUCT_FROM_DATABASE=82G35 Express PCI Express Root Port
+
+pci:v00008086d00002982*
+ ID_PRODUCT_FROM_DATABASE=82G35 Express Integrated Graphics Controller
+
+pci:v00008086d00002983*
+ ID_PRODUCT_FROM_DATABASE=82G35 Express Integrated Graphics Controller
+
+pci:v00008086d00002984*
+ ID_PRODUCT_FROM_DATABASE=82G35 Express HECI Controller
+
+pci:v00008086d00002990*
+ ID_PRODUCT_FROM_DATABASE=82Q963/Q965 Memory Controller Hub
+
+pci:v00008086d00002990sv00001028sd000001DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 745
+
+pci:v00008086d00002991*
+ ID_PRODUCT_FROM_DATABASE=82Q963/Q965 PCI Express Root Port
+
+pci:v00008086d00002992*
+ ID_PRODUCT_FROM_DATABASE=82Q963/Q965 Integrated Graphics Controller
+
+pci:v00008086d00002993*
+ ID_PRODUCT_FROM_DATABASE=82Q963/Q965 Integrated Graphics Controller
+
+pci:v00008086d00002994*
+ ID_PRODUCT_FROM_DATABASE=82Q963/Q965 HECI Controller
+
+pci:v00008086d00002995*
+ ID_PRODUCT_FROM_DATABASE=82Q963/Q965 HECI Controller
+
+pci:v00008086d00002996*
+ ID_PRODUCT_FROM_DATABASE=82Q963/Q965 PT IDER Controller
+
+pci:v00008086d00002997*
+ ID_PRODUCT_FROM_DATABASE=82Q963/Q965 KT Controller
+
+pci:v00008086d000029A0*
+ ID_PRODUCT_FROM_DATABASE=82P965/G965 Memory Controller Hub
+
+pci:v00008086d000029A0sv00001043sd000081EA*
+ ID_PRODUCT_FROM_DATABASE=P5B
+
+pci:v00008086d000029A0sv00001462sd00007276*
+ ID_PRODUCT_FROM_DATABASE=MS-7276 [G965MDH]
+
+pci:v00008086d000029A1*
+ ID_PRODUCT_FROM_DATABASE=82P965/G965 PCI Express Root Port
+
+pci:v00008086d000029A2*
+ ID_PRODUCT_FROM_DATABASE=82G965 Integrated Graphics Controller
+
+pci:v00008086d000029A2sv00001462sd00007276*
+ ID_PRODUCT_FROM_DATABASE=MS-7276 [G965MDH]
+
+pci:v00008086d000029A3*
+ ID_PRODUCT_FROM_DATABASE=82G965 Integrated Graphics Controller
+
+pci:v00008086d000029A4*
+ ID_PRODUCT_FROM_DATABASE=82P965/G965 HECI Controller
+
+pci:v00008086d000029A5*
+ ID_PRODUCT_FROM_DATABASE=82P965/G965 HECI Controller
+
+pci:v00008086d000029A6*
+ ID_PRODUCT_FROM_DATABASE=82P965/G965 PT IDER Controller
+
+pci:v00008086d000029A7*
+ ID_PRODUCT_FROM_DATABASE=82P965/G965 KT Controller
+
+pci:v00008086d000029B0*
+ ID_PRODUCT_FROM_DATABASE=82Q35 Express DRAM Controller
+
+pci:v00008086d000029B0sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 755
+
+pci:v00008086d000029B1*
+ ID_PRODUCT_FROM_DATABASE=82Q35 Express PCI Express Root Port
+
+pci:v00008086d000029B1sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 755
+
+pci:v00008086d000029B2*
+ ID_PRODUCT_FROM_DATABASE=82Q35 Express Integrated Graphics Controller
+
+pci:v00008086d000029B2sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 755
+
+pci:v00008086d000029B3*
+ ID_PRODUCT_FROM_DATABASE=82Q35 Express Integrated Graphics Controller
+
+pci:v00008086d000029B3sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 755
+
+pci:v00008086d000029B4*
+ ID_PRODUCT_FROM_DATABASE=82Q35 Express MEI Controller
+
+pci:v00008086d000029B4sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 755
+
+pci:v00008086d000029B5*
+ ID_PRODUCT_FROM_DATABASE=82Q35 Express MEI Controller
+
+pci:v00008086d000029B6*
+ ID_PRODUCT_FROM_DATABASE=82Q35 Express PT IDER Controller
+
+pci:v00008086d000029B6sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 755
+
+pci:v00008086d000029B7*
+ ID_PRODUCT_FROM_DATABASE=82Q35 Express Serial KT Controller
+
+pci:v00008086d000029B7sv00001028sd00000211*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 755
+
+pci:v00008086d000029C0*
+ ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller
+
+pci:v00008086d000029C0sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d000029C0sv00001043sd000082B0*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00008086d000029C0sv00001462sd00007360*
+ ID_PRODUCT_FROM_DATABASE=G33/P35 Neo
+
+pci:v00008086d000029C0sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d000029C1*
+ ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express PCI Express Root Port
+
+pci:v00008086d000029C1sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d000029C2*
+ ID_PRODUCT_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller
+
+pci:v00008086d000029C2sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d000029C2sv00001043sd000082B0*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00008086d000029C3*
+ ID_PRODUCT_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller
+
+pci:v00008086d000029C3sv00001028sd0000020D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 530
+
+pci:v00008086d000029C3sv00001043sd000082B0*
+ ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard
+
+pci:v00008086d000029C4*
+ ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express MEI Controller
+
+pci:v00008086d000029C4sv00008086sd00005044*
+ ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP
+
+pci:v00008086d000029C5*
+ ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express MEI Controller
+
+pci:v00008086d000029C6*
+ ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express PT IDER Controller
+
+pci:v00008086d000029C7*
+ ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express Serial KT Controller
+
+pci:v00008086d000029CF*
+ ID_PRODUCT_FROM_DATABASE=Virtual HECI Controller
+
+pci:v00008086d000029D0*
+ ID_PRODUCT_FROM_DATABASE=82Q33 Express DRAM Controller
+
+pci:v00008086d000029D1*
+ ID_PRODUCT_FROM_DATABASE=82Q33 Express PCI Express Root Port
+
+pci:v00008086d000029D2*
+ ID_PRODUCT_FROM_DATABASE=82Q33 Express Integrated Graphics Controller
+
+pci:v00008086d000029D3*
+ ID_PRODUCT_FROM_DATABASE=82Q33 Express Integrated Graphics Controller
+
+pci:v00008086d000029D4*
+ ID_PRODUCT_FROM_DATABASE=82Q33 Express MEI Controller
+
+pci:v00008086d000029D5*
+ ID_PRODUCT_FROM_DATABASE=82Q33 Express MEI Controller
+
+pci:v00008086d000029D6*
+ ID_PRODUCT_FROM_DATABASE=82Q33 Express PT IDER Controller
+
+pci:v00008086d000029D7*
+ ID_PRODUCT_FROM_DATABASE=82Q33 Express Serial KT Controller
+
+pci:v00008086d000029E0*
+ ID_PRODUCT_FROM_DATABASE=82X38/X48 Express DRAM Controller
+
+pci:v00008086d000029E1*
+ ID_PRODUCT_FROM_DATABASE=82X38/X48 Express Host-Primary PCI Express Bridge
+
+pci:v00008086d000029E4*
+ ID_PRODUCT_FROM_DATABASE=82X38/X48 Express MEI Controller
+
+pci:v00008086d000029E5*
+ ID_PRODUCT_FROM_DATABASE=82X38/X48 Express MEI Controller
+
+pci:v00008086d000029E6*
+ ID_PRODUCT_FROM_DATABASE=82X38/X48 Express PT IDER Controller
+
+pci:v00008086d000029E7*
+ ID_PRODUCT_FROM_DATABASE=82X38/X48 Express Serial KT Controller
+
+pci:v00008086d000029E9*
+ ID_PRODUCT_FROM_DATABASE=82X38/X48 Express Host-Secondary PCI Express Bridge
+
+pci:v00008086d000029F0*
+ ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset DRAM Controller
+
+pci:v00008086d000029F1*
+ ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset Host-Primary PCI Express Bridge
+
+pci:v00008086d000029F4*
+ ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset MEI Controller
+
+pci:v00008086d000029F5*
+ ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset MEI Controller
+
+pci:v00008086d000029F6*
+ ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset PT IDER Controller
+
+pci:v00008086d000029F7*
+ ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset Serial KT Controller
+
+pci:v00008086d000029F9*
+ ID_PRODUCT_FROM_DATABASE=3210 Chipset Host-Secondary PCI Express Bridge
+
+pci:v00008086d00002A00*
+ ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub
+
+pci:v00008086d00002A00sv00001025sd00000121*
+ ID_PRODUCT_FROM_DATABASE=Acer Aspire 5920G
+
+pci:v00008086d00002A00sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002A00sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002A00sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002A00sv0000103Csd000030CC*
+ ID_PRODUCT_FROM_DATABASE=Pavilion dv6700
+
+pci:v00008086d00002A00sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002A00sv0000104Dsd00009005*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E
+
+pci:v00008086d00002A00sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002A00sv000017AAsd000020B1*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad T61
+
+pci:v00008086d00002A00sv000017AAsd000020B3*
+ ID_PRODUCT_FROM_DATABASE=T61
+
+pci:v00008086d00002A00sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002A01*
+ ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965/GL960 PCI Express Root Port
+
+pci:v00008086d00002A02*
+ ID_PRODUCT_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary)
+
+pci:v00008086d00002A02sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 1420
+
+pci:v00008086d00002A02sv00001028sd000001F9*
+ ID_PRODUCT_FROM_DATABASE=Latitude D630
+
+pci:v00008086d00002A02sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002A02sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002A02sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002A02sv000017AAsd000020B5*
+ ID_PRODUCT_FROM_DATABASE=T61
+
+pci:v00008086d00002A02sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002A03*
+ ID_PRODUCT_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary)
+
+pci:v00008086d00002A03sv00001028sd000001F3*
+ ID_PRODUCT_FROM_DATABASE=Dell Inspiron 1420
+
+pci:v00008086d00002A03sv0000103Csd000030C0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6710b
+
+pci:v00008086d00002A03sv0000103Csd000030D9*
+ ID_PRODUCT_FROM_DATABASE=Presario C700
+
+pci:v00008086d00002A03sv0000104Dsd0000902D*
+ ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E
+
+pci:v00008086d00002A03sv000017AAsd000020B5*
+ ID_PRODUCT_FROM_DATABASE=T61
+
+pci:v00008086d00002A03sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002A04*
+ ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965 MEI Controller
+
+pci:v00008086d00002A04sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002A05*
+ ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965 MEI Controller
+
+pci:v00008086d00002A06*
+ ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965 PT IDER Controller
+
+pci:v00008086d00002A06sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002A07*
+ ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965 KT Controller
+
+pci:v00008086d00002A07sv0000103Csd000030C1*
+ ID_PRODUCT_FROM_DATABASE=Compaq 6910p
+
+pci:v00008086d00002A10*
+ ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 Memory Controller Hub
+
+pci:v00008086d00002A10sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002A11*
+ ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 PCI Express Root Port
+
+pci:v00008086d00002A12*
+ ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 Integrated Graphics Controller
+
+pci:v00008086d00002A12sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002A13*
+ ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 Integrated Graphics Controller
+
+pci:v00008086d00002A13sv0000E4BFsd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v00008086d00002A14*
+ ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 MEI Controller
+
+pci:v00008086d00002A15*
+ ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 MEI Controller
+
+pci:v00008086d00002A16*
+ ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 PT IDER Controller
+
+pci:v00008086d00002A17*
+ ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 KT Controller
+
+pci:v00008086d00002A40*
+ ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset Memory Controller Hub
+
+pci:v00008086d00002A40sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002A41*
+ ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset PCI Express Graphics Port
+
+pci:v00008086d00002A41sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002A42*
+ ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002A42sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002A43*
+ ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002A43sv0000E4BFsd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v00008086d00002A44*
+ ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset MEI Controller
+
+pci:v00008086d00002A45*
+ ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset MEI Controller
+
+pci:v00008086d00002A46*
+ ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset PT IDER Controller
+
+pci:v00008086d00002A47*
+ ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset AMT SOL Redirection
+
+pci:v00008086d00002A50*
+ ID_PRODUCT_FROM_DATABASE=Cantiga MEI Controller
+
+pci:v00008086d00002A51*
+ ID_PRODUCT_FROM_DATABASE=Cantiga MEI Controller
+
+pci:v00008086d00002A52*
+ ID_PRODUCT_FROM_DATABASE=Cantiga PT IDER Controller
+
+pci:v00008086d00002A53*
+ ID_PRODUCT_FROM_DATABASE=Cantiga AMT SOL Redirection
+
+pci:v00008086d00002B00*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family System Configuration Controller 1
+
+pci:v00008086d00002B02*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family System Configuration Controller 2
+
+pci:v00008086d00002B04*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Power Controller
+
+pci:v00008086d00002B08*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Caching Agent 0
+
+pci:v00008086d00002B0C*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Caching Agent 1
+
+pci:v00008086d00002B10*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Home Agent 0
+
+pci:v00008086d00002B13*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 0c
+
+pci:v00008086d00002B14*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 0a
+
+pci:v00008086d00002B16*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 0b
+
+pci:v00008086d00002B18*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Home Agent 1
+
+pci:v00008086d00002B1B*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 1c
+
+pci:v00008086d00002B1C*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 1a
+
+pci:v00008086d00002B1E*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 1b
+
+pci:v00008086d00002B20*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 0
+
+pci:v00008086d00002B22*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family System Configuration Controller 3
+
+pci:v00008086d00002B24*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 1
+
+pci:v00008086d00002B28*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 2
+
+pci:v00008086d00002B2A*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family System Configuration Controller 4
+
+pci:v00008086d00002B2C*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 3
+
+pci:v00008086d00002B30*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 4
+
+pci:v00008086d00002B34*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 5
+
+pci:v00008086d00002B38*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 6
+
+pci:v00008086d00002B3C*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 7
+
+pci:v00008086d00002B40*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Router Port 0-1
+
+pci:v00008086d00002B42*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Router Port 2-3
+
+pci:v00008086d00002B44*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Router Port 4-5
+
+pci:v00008086d00002B46*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Router Port 6-7
+
+pci:v00008086d00002B48*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Test and Debug 0
+
+pci:v00008086d00002B4C*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Test and Debug 1
+
+pci:v00008086d00002B50*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 0: REUT control/status
+
+pci:v00008086d00002B52*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 0: Misc. control/status
+
+pci:v00008086d00002B54*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 1: REUT control/status
+
+pci:v00008086d00002B56*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 1: Misc. control/status
+
+pci:v00008086d00002B58*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 2: REUT control/status
+
+pci:v00008086d00002B5A*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 2: Misc. control/status
+
+pci:v00008086d00002B5C*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 3: REUT control/status
+
+pci:v00008086d00002B5E*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 3: Misc. control/status
+
+pci:v00008086d00002B60*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family SMI Physical Port 0: REUT control/status
+
+pci:v00008086d00002B62*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family SMI Physical Port 0: Misc control/status
+
+pci:v00008086d00002B64*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family SMI Physical Port 1: REUT control/status
+
+pci:v00008086d00002B66*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family SMI Physical Port 1: Misc control/status
+
+pci:v00008086d00002B68*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 8
+
+pci:v00008086d00002B6C*
+ ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 9
+
+pci:v00008086d00002C01*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QuickPath Architecture System Address Decoder
+
+pci:v00008086d00002C10*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QPI Link 0
+
+pci:v00008086d00002C11*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QPI Physical 0
+
+pci:v00008086d00002C14*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QPI Link 1
+
+pci:v00008086d00002C15*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QPI Physical 1
+
+pci:v00008086d00002C18*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller
+
+pci:v00008086d00002C19*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Target Address Decoder
+
+pci:v00008086d00002C1A*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller RAS Registers
+
+pci:v00008086d00002C1C*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Test Registers
+
+pci:v00008086d00002C20*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 0 Control Registers
+
+pci:v00008086d00002C21*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 0 Address Registers
+
+pci:v00008086d00002C22*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 0 Rank Registers
+
+pci:v00008086d00002C23*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 0 Thermal Control Registers
+
+pci:v00008086d00002C28*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 1 Control Registers
+
+pci:v00008086d00002C29*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 1 Address Registers
+
+pci:v00008086d00002C2A*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 1 Rank Registers
+
+pci:v00008086d00002C2B*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 1 Thermal Control Registers
+
+pci:v00008086d00002C30*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 2 Control Registers
+
+pci:v00008086d00002C31*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 2 Address Registers
+
+pci:v00008086d00002C32*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 2 Rank Registers
+
+pci:v00008086d00002C33*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 2 Thermal Control Registers
+
+pci:v00008086d00002C40*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C41*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C50*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C51*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C52*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C53*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C54*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C55*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C56*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C57*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers
+
+pci:v00008086d00002C58*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers
+
+pci:v00008086d00002C59*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers
+
+pci:v00008086d00002C5A*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers
+
+pci:v00008086d00002C5B*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers
+
+pci:v00008086d00002C5C*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers
+
+pci:v00008086d00002C5D*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers
+
+pci:v00008086d00002C5E*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers
+
+pci:v00008086d00002C5F*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers
+
+pci:v00008086d00002C61*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-core Registers
+
+pci:v00008086d00002C62*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-core Registers
+
+pci:v00008086d00002C70*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QuickPath Architecture Generic Non-core Registers
+
+pci:v00008086d00002C81*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture System Address Decoder
+
+pci:v00008086d00002C90*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QPI Link 0
+
+pci:v00008086d00002C91*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QPI Physical 0
+
+pci:v00008086d00002C98*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller
+
+pci:v00008086d00002C99*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Target Address Decoder
+
+pci:v00008086d00002C9A*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Test Registers
+
+pci:v00008086d00002C9C*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Test Registers
+
+pci:v00008086d00002CA0*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 0 Control Registers
+
+pci:v00008086d00002CA1*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 0 Address Registers
+
+pci:v00008086d00002CA2*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 0 Rank Registers
+
+pci:v00008086d00002CA3*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 0 Thermal Control Registers
+
+pci:v00008086d00002CA8*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 1 Control Registers
+
+pci:v00008086d00002CA9*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 1 Address Registers
+
+pci:v00008086d00002CAA*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 1 Rank Registers
+
+pci:v00008086d00002CAB*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 1 Thermal Control Registers
+
+pci:v00008086d00002CC1*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI System Address Decoder
+
+pci:v00008086d00002CD0*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Link 0
+
+pci:v00008086d00002CD1*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Physical 0
+
+pci:v00008086d00002CD4*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Link 1
+
+pci:v00008086d00002CD5*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Physical 1
+
+pci:v00008086d00002CD8*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Registers
+
+pci:v00008086d00002CD9*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Target Address Decoder
+
+pci:v00008086d00002CDA*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller RAS Registers
+
+pci:v00008086d00002CDC*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Test Registers
+
+pci:v00008086d00002CE0*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 0 Control
+
+pci:v00008086d00002CE1*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 0 Address
+
+pci:v00008086d00002CE2*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 0 Rank
+
+pci:v00008086d00002CE3*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 0 Thermal Control
+
+pci:v00008086d00002CE8*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 1 Control
+
+pci:v00008086d00002CE9*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 1 Address
+
+pci:v00008086d00002CEA*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 1 Rank
+
+pci:v00008086d00002CEB*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 1 Thermal Control
+
+pci:v00008086d00002CF0*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 2 Control
+
+pci:v00008086d00002CF1*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 2 Address
+
+pci:v00008086d00002CF2*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 2 Rank
+
+pci:v00008086d00002CF3*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 2 Thermal Control
+
+pci:v00008086d00002D01*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture System Address Decoder
+
+pci:v00008086d00002D10*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QPI Link 0
+
+pci:v00008086d00002D11*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QPI Physical 0
+
+pci:v00008086d00002D12*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Reserved
+
+pci:v00008086d00002D13*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Reserved
+
+pci:v00008086d00002D81*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QuickPath Architecture System Address Decoder
+
+pci:v00008086d00002D90*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QPI Link 0
+
+pci:v00008086d00002D91*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QPI Physical 0
+
+pci:v00008086d00002D92*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Mirror Port Link 0
+
+pci:v00008086d00002D93*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Mirror Port Link 1
+
+pci:v00008086d00002D94*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QPI Link 1
+
+pci:v00008086d00002D95*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QPI Physical 1
+
+pci:v00008086d00002D98*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Registers
+
+pci:v00008086d00002D99*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Target Address Decoder
+
+pci:v00008086d00002D9A*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller RAS Registers
+
+pci:v00008086d00002D9C*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Test Registers
+
+pci:v00008086d00002DA0*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 0 Control
+
+pci:v00008086d00002DA1*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 0 Address
+
+pci:v00008086d00002DA2*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 0 Rank
+
+pci:v00008086d00002DA3*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 0 Thermal Control
+
+pci:v00008086d00002DA8*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 1 Control
+
+pci:v00008086d00002DA9*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 1 Address
+
+pci:v00008086d00002DAA*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 1 Rank
+
+pci:v00008086d00002DAB*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 1 Thermal Control
+
+pci:v00008086d00002DB0*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 2 Control
+
+pci:v00008086d00002DB1*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 2 Address
+
+pci:v00008086d00002DB2*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 2 Rank
+
+pci:v00008086d00002DB3*
+ ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 2 Thermal Control
+
+pci:v00008086d00002E00*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller
+
+pci:v00008086d00002E01*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port
+
+pci:v00008086d00002E02*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E03*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E04*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E05*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E06*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller
+
+pci:v00008086d00002E07*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller
+
+pci:v00008086d00002E10*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller
+
+pci:v00008086d00002E11*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port
+
+pci:v00008086d00002E12*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E13*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E14*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E15*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E16*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller
+
+pci:v00008086d00002E17*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller
+
+pci:v00008086d00002E20*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller
+
+pci:v00008086d00002E20sv00001043sd000082D3*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00002E20sv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00002E21*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port
+
+pci:v00008086d00002E21sv00001043sd000082D3*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00002E21sv00001458sd00005000*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00002E22*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E22sv00001458sd0000D000*
+ ID_PRODUCT_FROM_DATABASE=GA-EG45M-DS2H Mainboard
+
+pci:v00008086d00002E23*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E23sv00001458sd0000D000*
+ ID_PRODUCT_FROM_DATABASE=GA-EG45M-DS2H Mainboard
+
+pci:v00008086d00002E24*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E25*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E26*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller
+
+pci:v00008086d00002E27*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller
+
+pci:v00008086d00002E29*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port
+
+pci:v00008086d00002E30*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller
+
+pci:v00008086d00002E31*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port
+
+pci:v00008086d00002E32*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E33*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E34*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E35*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E36*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller
+
+pci:v00008086d00002E37*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller
+
+pci:v00008086d00002E40*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller
+
+pci:v00008086d00002E41*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port
+
+pci:v00008086d00002E42*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E43*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E44*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E45*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E46*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller
+
+pci:v00008086d00002E47*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller
+
+pci:v00008086d00002E50*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor CE3100
+
+pci:v00008086d00002E52*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Clock and Reset Controller
+
+pci:v00008086d00002E58*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Interrupt Controller
+
+pci:v00008086d00002E5A*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor CE3100 A/V Bridge
+
+pci:v00008086d00002E5B*
+ ID_PRODUCT_FROM_DATABASE=Graphics Media Accelerator 500 Graphics
+
+pci:v00008086d00002E5C*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Video Decoder
+
+pci:v00008086d00002E5D*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Transport Stream Interface
+
+pci:v00008086d00002E5E*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Transport Stream Processor 0
+
+pci:v00008086d00002E5F*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Audio DSP
+
+pci:v00008086d00002E60*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Audio Interfaces
+
+pci:v00008086d00002E61*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Video Display Controller
+
+pci:v00008086d00002E62*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Video Processing Unit
+
+pci:v00008086d00002E63*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor HDMI Tx Interface
+
+pci:v00008086d00002E65*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Expansion Bus Interface
+
+pci:v00008086d00002E66*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor UART
+
+pci:v00008086d00002E67*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor General Purpose I/Os
+
+pci:v00008086d00002E68*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor I2C Interface
+
+pci:v00008086d00002E69*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Smart Card Interface
+
+pci:v00008086d00002E6A*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor SPI Master Interface
+
+pci:v00008086d00002E6E*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Gigabit Ethernet Controller
+
+pci:v00008086d00002E6F*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor Media Timing Unit
+
+pci:v00008086d00002E70*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor USB
+
+pci:v00008086d00002E71*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor SATA
+
+pci:v00008086d00002E73*
+ ID_PRODUCT_FROM_DATABASE=CE Media Processor CE3100 PCI Express
+
+pci:v00008086d00002E90*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller
+
+pci:v00008086d00002E91*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port
+
+pci:v00008086d00002E92*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E93*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
+
+pci:v00008086d00002E94*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E95*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller
+
+pci:v00008086d00002E96*
+ ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller
+
+pci:v00008086d00003200*
+ ID_PRODUCT_FROM_DATABASE=GD31244 PCI-X SATA HBA
+
+pci:v00008086d00003200sv00001775sd0000C200*
+ ID_PRODUCT_FROM_DATABASE=C2K onboard SATA host bus adapter
+
+pci:v00008086d00003310*
+ ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor
+
+pci:v00008086d00003310sv00001054sd00003030*
+ ID_PRODUCT_FROM_DATABASE=HRA380 Hitachi RAID Adapter to PCIe
+
+pci:v00008086d00003310sv00001054sd00003034*
+ ID_PRODUCT_FROM_DATABASE=HRA381 Hitachi RAID Adapter to PCIe
+
+pci:v00008086d00003313*
+ ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor (SL8e) in IOC Mode SAS/SATA
+
+pci:v00008086d0000331B*
+ ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor (SL8x) in IOC Mode SAS/SATA
+
+pci:v00008086d00003331*
+ ID_PRODUCT_FROM_DATABASE=IOC340 I/O Controller (VV8e) SAS/SATA
+
+pci:v00008086d00003339*
+ ID_PRODUCT_FROM_DATABASE=IOC340 I/O Controller (VV8x) SAS/SATA
+
+pci:v00008086d00003340*
+ ID_PRODUCT_FROM_DATABASE=82855PM Processor to I/O Controller
+
+pci:v00008086d00003340sv00001014sd00000529*
+ ID_PRODUCT_FROM_DATABASE=Thinkpad T40 series
+
+pci:v00008086d00003340sv00001025sd0000005A*
+ ID_PRODUCT_FROM_DATABASE=TravelMate 290
+
+pci:v00008086d00003340sv0000103Csd0000088C*
+ ID_PRODUCT_FROM_DATABASE=NC8000 laptop
+
+pci:v00008086d00003340sv0000103Csd00000890*
+ ID_PRODUCT_FROM_DATABASE=NC6000 laptop
+
+pci:v00008086d00003340sv0000103Csd000008B0*
+ ID_PRODUCT_FROM_DATABASE=tc1100 tablet
+
+pci:v00008086d00003340sv0000144Dsd0000C005*
+ ID_PRODUCT_FROM_DATABASE=X10 Laptop
+
+pci:v00008086d00003340sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30/P35 notebook
+
+pci:v00008086d00003341*
+ ID_PRODUCT_FROM_DATABASE=82855PM Processor to AGP Controller
+
+pci:v00008086d00003341sv0000144Dsd0000C00C*
+ ID_PRODUCT_FROM_DATABASE=P30 notebook
+
+pci:v00008086d00003363*
+ ID_PRODUCT_FROM_DATABASE=IOC340 I/O Controller in IOC Mode SAS/SATA
+
+pci:v00008086d00003382*
+ ID_PRODUCT_FROM_DATABASE=81342 [Chevelon] I/O Processor (ATUe)
+
+pci:v00008086d000033C3*
+ ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor (SL8De) in IOC Mode SAS/SATA
+
+pci:v00008086d000033CB*
+ ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor (SL8Dx) in IOC Mode SAS/SATA
+
+pci:v00008086d00003400*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port
+
+pci:v00008086d00003401*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port
+
+pci:v00008086d00003402*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port
+
+pci:v00008086d00003403*
+ ID_PRODUCT_FROM_DATABASE=5500 I/O Hub to ESI Port
+
+pci:v00008086d00003403sv00001028sd00000236*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R610 I/O Hub to ESI Port
+
+pci:v00008086d00003403sv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge M610 I/O Hub to ESI Port
+
+pci:v00008086d00003403sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 I/O Hub to ESI Port
+
+pci:v00008086d00003403sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 I/O Hub to ESI Port
+
+pci:v00008086d00003403sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d00003404*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port
+
+pci:v00008086d00003405*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port
+
+pci:v00008086d00003406*
+ ID_PRODUCT_FROM_DATABASE=5520 I/O Hub to ESI Port
+
+pci:v00008086d00003406sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003407*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port
+
+pci:v00008086d00003408*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 1
+
+pci:v00008086d00003408sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003409*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 2
+
+pci:v00008086d0000340A*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 3
+
+pci:v00008086d0000340Asv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d0000340B*
+ ID_PRODUCT_FROM_DATABASE=5520/X58 I/O Hub PCI Express Root Port 4
+
+pci:v00008086d0000340C*
+ ID_PRODUCT_FROM_DATABASE=5520/X58 I/O Hub PCI Express Root Port 5
+
+pci:v00008086d0000340D*
+ ID_PRODUCT_FROM_DATABASE=5520/X58 I/O Hub PCI Express Root Port 6
+
+pci:v00008086d0000340E*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 7
+
+pci:v00008086d0000340Esv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d0000340F*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 8
+
+pci:v00008086d00003410*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub PCI Express Root Port 9
+
+pci:v00008086d00003411*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub PCI Express Root Port 10
+
+pci:v00008086d00003418*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 Physical Layer Port 0
+
+pci:v00008086d00003419*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500 Physical Layer Port 1
+
+pci:v00008086d00003420*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub PCI Express Root Port 0
+
+pci:v00008086d00003421*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub PCI Express Root Port 0
+
+pci:v00008086d00003422*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub GPIO and Scratch Pad Registers
+
+pci:v00008086d00003422sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003423*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub Control Status and RAS Registers
+
+pci:v00008086d00003423sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003425*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 Physical and Link Layer Registers Port 0
+
+pci:v00008086d00003426*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 Routing and Protocol Layer Registers Port 0
+
+pci:v00008086d00003427*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500 Physical and Link Layer Registers Port 1
+
+pci:v00008086d00003428*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500 Routing & Protocol Layer Register Port 1
+
+pci:v00008086d00003429*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device
+
+pci:v00008086d0000342A*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device
+
+pci:v00008086d0000342B*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device
+
+pci:v00008086d0000342C*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device
+
+pci:v00008086d0000342D*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub I/OxAPIC Interrupt Controller
+
+pci:v00008086d0000342E*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub System Management Registers
+
+pci:v00008086d0000342Esv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d0000342F*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 Trusted Execution Technology Registers
+
+pci:v00008086d00003430*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device
+
+pci:v00008086d00003431*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device
+
+pci:v00008086d00003432*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device
+
+pci:v00008086d00003433*
+ ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device
+
+pci:v00008086d00003438*
+ ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub Throttle Registers
+
+pci:v00008086d00003500*
+ ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express Upstream Port
+
+pci:v00008086d00003500sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d00003501*
+ ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express Upstream Port
+
+pci:v00008086d00003504*
+ ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB I/OxAPIC Interrupt Controller
+
+pci:v00008086d00003505*
+ ID_PRODUCT_FROM_DATABASE=6310ESB I/OxAPIC Interrupt Controller
+
+pci:v00008086d0000350C*
+ ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express to PCI-X Bridge
+
+pci:v00008086d0000350Csv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d0000350D*
+ ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express to PCI-X Bridge
+
+pci:v00008086d00003510*
+ ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E1
+
+pci:v00008086d00003510sv0000103Csd000031FE*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3
+
+pci:v00008086d00003511*
+ ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express Downstream Port E1
+
+pci:v00008086d00003514*
+ ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E2
+
+pci:v00008086d00003515*
+ ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express Downstream Port E2
+
+pci:v00008086d00003518*
+ ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E3
+
+pci:v00008086d00003519*
+ ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express Downstream Port E3
+
+pci:v00008086d00003575*
+ ID_PRODUCT_FROM_DATABASE=82830M/MG/MP Host Bridge
+
+pci:v00008086d00003575sv00000E11sd00000030*
+ ID_PRODUCT_FROM_DATABASE=Evo N600c
+
+pci:v00008086d00003575sv00001014sd0000021D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00003575sv0000104Dsd000080E7*
+ ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+
+pci:v00008086d00003576*
+ ID_PRODUCT_FROM_DATABASE=82830M/MP AGP Bridge
+
+pci:v00008086d00003577*
+ ID_PRODUCT_FROM_DATABASE=82830M/MG Integrated Graphics Controller
+
+pci:v00008086d00003577sv00001014sd00000513*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series
+
+pci:v00008086d00003578*
+ ID_PRODUCT_FROM_DATABASE=82830M/MG/MP Host Bridge
+
+pci:v00008086d00003580*
+ ID_PRODUCT_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller
+
+pci:v00008086d00003580sv00001014sd0000055C*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R50e
+
+pci:v00008086d00003580sv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v00008086d00003580sv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d00003580sv00001028sd00000152*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00008086d00003580sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d00003580sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d00003580sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d00003580sv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8
+
+pci:v00008086d00003580sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d00003580sv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer
+
+pci:v00008086d00003580sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d00003580sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d00003580sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d00003580sv0000E4BFsd00000CC9*
+ ID_PRODUCT_FROM_DATABASE=CC9-SAMBA
+
+pci:v00008086d00003580sv0000E4BFsd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v00008086d00003581*
+ ID_PRODUCT_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to AGP Controller
+
+pci:v00008086d00003581sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d00003582*
+ ID_PRODUCT_FROM_DATABASE=82852/855GM Integrated Graphics Device
+
+pci:v00008086d00003582sv00001014sd00000562*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R50e
+
+pci:v00008086d00003582sv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v00008086d00003582sv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d00003582sv00001028sd00000152*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00008086d00003582sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d00003582sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d00003582sv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8 integrated graphics
+
+pci:v00008086d00003582sv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer VGA
+
+pci:v00008086d00003582sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d00003582sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d00003582sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d00003582sv0000E4BFsd00000CC9*
+ ID_PRODUCT_FROM_DATABASE=CC9-SAMBA
+
+pci:v00008086d00003582sv0000E4BFsd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v00008086d00003584*
+ ID_PRODUCT_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller
+
+pci:v00008086d00003584sv00001014sd0000055D*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R50e
+
+pci:v00008086d00003584sv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v00008086d00003584sv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d00003584sv00001028sd00000152*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00008086d00003584sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d00003584sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d00003584sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d00003584sv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8
+
+pci:v00008086d00003584sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d00003584sv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer
+
+pci:v00008086d00003584sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d00003584sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d00003584sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d00003585*
+ ID_PRODUCT_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller
+
+pci:v00008086d00003585sv00001014sd0000055E*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R50e
+
+pci:v00008086d00003585sv00001028sd00000139*
+ ID_PRODUCT_FROM_DATABASE=Latitude D400
+
+pci:v00008086d00003585sv00001028sd0000014F*
+ ID_PRODUCT_FROM_DATABASE=Latitude X300
+
+pci:v00008086d00003585sv00001028sd00000152*
+ ID_PRODUCT_FROM_DATABASE=Latitude D500
+
+pci:v00008086d00003585sv00001028sd00000163*
+ ID_PRODUCT_FROM_DATABASE=Latitude D505
+
+pci:v00008086d00003585sv00001028sd0000018D*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m
+
+pci:v00008086d00003585sv00001028sd00000196*
+ ID_PRODUCT_FROM_DATABASE=Inspiron 5160
+
+pci:v00008086d00003585sv0000114Asd00000582*
+ ID_PRODUCT_FROM_DATABASE=PC8
+
+pci:v00008086d00003585sv00001734sd00001055*
+ ID_PRODUCT_FROM_DATABASE=Amilo M1420
+
+pci:v00008086d00003585sv00001775sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer
+
+pci:v00008086d00003585sv00001775sd0000CE90*
+ ID_PRODUCT_FROM_DATABASE=CE9
+
+pci:v00008086d00003585sv00004C53sd000010B0*
+ ID_PRODUCT_FROM_DATABASE=CL9 mainboard
+
+pci:v00008086d00003585sv00004C53sd000010E0*
+ ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC
+
+pci:v00008086d0000358C*
+ ID_PRODUCT_FROM_DATABASE=82854 GMCH
+
+pci:v00008086d0000358E*
+ ID_PRODUCT_FROM_DATABASE=82854 GMCH Integrated Graphics Device
+
+pci:v00008086d00003590*
+ ID_PRODUCT_FROM_DATABASE=E7520 Memory Controller Hub
+
+pci:v00008086d00003590sv00001014sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d00003590sv00001028sd0000016C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 Memory Controller Hub
+
+pci:v00008086d00003590sv00001028sd0000016D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 Memory Controller Hub
+
+pci:v00008086d00003590sv00001028sd0000019A*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425
+
+pci:v00008086d00003590sv00001734sd0000103E*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series
+
+pci:v00008086d00003590sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00003590sv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d00003591*
+ ID_PRODUCT_FROM_DATABASE=E7525/E7520 Error Reporting Registers
+
+pci:v00008086d00003591sv00001014sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d00003591sv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d00003591sv0000103Csd00003208*
+ ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2
+
+pci:v00008086d00003591sv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d00003592*
+ ID_PRODUCT_FROM_DATABASE=E7320 Memory Controller Hub
+
+pci:v00008086d00003593*
+ ID_PRODUCT_FROM_DATABASE=E7320 Error Reporting Registers
+
+pci:v00008086d00003594*
+ ID_PRODUCT_FROM_DATABASE=E7520 DMA Controller
+
+pci:v00008086d00003594sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00003594sv00004C53sd000010D0*
+ ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC
+
+pci:v00008086d00003595*
+ ID_PRODUCT_FROM_DATABASE=E7525/E7520/E7320 PCI Express Port A
+
+pci:v00008086d00003595sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00003596*
+ ID_PRODUCT_FROM_DATABASE=E7525/E7520/E7320 PCI Express Port A1
+
+pci:v00008086d00003597*
+ ID_PRODUCT_FROM_DATABASE=E7525/E7520 PCI Express Port B
+
+pci:v00008086d00003597sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00003598*
+ ID_PRODUCT_FROM_DATABASE=E7520 PCI Express Port B1
+
+pci:v00008086d00003598sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00003599*
+ ID_PRODUCT_FROM_DATABASE=E7520 PCI Express Port C
+
+pci:v00008086d00003599sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d0000359A*
+ ID_PRODUCT_FROM_DATABASE=E7520 PCI Express Port C1
+
+pci:v00008086d0000359B*
+ ID_PRODUCT_FROM_DATABASE=E7525/E7520/E7320 Extended Configuration Registers
+
+pci:v00008086d0000359Bsv00001014sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard
+
+pci:v00008086d0000359E*
+ ID_PRODUCT_FROM_DATABASE=E7525 Memory Controller Hub
+
+pci:v00008086d0000359Esv00001028sd00000169*
+ ID_PRODUCT_FROM_DATABASE=Precision 470
+
+pci:v00008086d000035B0*
+ ID_PRODUCT_FROM_DATABASE=3100 Chipset Memory I/O Controller Hub
+
+pci:v00008086d000035B1*
+ ID_PRODUCT_FROM_DATABASE=3100 DRAM Controller Error Reporting Registers
+
+pci:v00008086d000035B5*
+ ID_PRODUCT_FROM_DATABASE=3100 Chipset Enhanced DMA Controller
+
+pci:v00008086d000035B6*
+ ID_PRODUCT_FROM_DATABASE=3100 Chipset PCI Express Port A
+
+pci:v00008086d000035B7*
+ ID_PRODUCT_FROM_DATABASE=3100 Chipset PCI Express Port A1
+
+pci:v00008086d000035C8*
+ ID_PRODUCT_FROM_DATABASE=3100 Extended Configuration Test Overflow Registers
+
+pci:v00008086d00003600*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset Memory Controller Hub
+
+pci:v00008086d00003604*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 1
+
+pci:v00008086d00003605*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 2
+
+pci:v00008086d00003606*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 3
+
+pci:v00008086d00003607*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 4
+
+pci:v00008086d00003608*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 5
+
+pci:v00008086d00003609*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 6
+
+pci:v00008086d0000360A*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 7
+
+pci:v00008086d0000360B*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset QuickData Technology Device
+
+pci:v00008086d0000360C*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset FSB Registers
+
+pci:v00008086d0000360Csv00001028sd000001F0*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R900 7300 Chipset FSB Registers
+
+pci:v00008086d0000360D*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset Snoop Filter Registers
+
+pci:v00008086d0000360E*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset Debug and Miscellaneous Registers
+
+pci:v00008086d0000360F*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset FBD Branch 0 Registers
+
+pci:v00008086d00003610*
+ ID_PRODUCT_FROM_DATABASE=7300 Chipset FBD Branch 1 Registers
+
+pci:v00008086d00003700*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003701*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003702*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003703*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003704*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003705*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003706*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003707*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003708*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003709*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d0000370A*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d0000370B*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d0000370C*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d0000370D*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d0000370E*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d0000370F*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI
+
+pci:v00008086d00003710*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003711*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003712*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003713*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003714*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003715*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003716*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003717*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003718*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d00003719*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA
+
+pci:v00008086d0000371A*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Link
+
+pci:v00008086d0000371B*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Routing and Protocol
+
+pci:v00008086d0000371D*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Routing and Protocol
+
+pci:v00008086d00003720*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 0
+
+pci:v00008086d00003721*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 1
+
+pci:v00008086d00003722*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 2
+
+pci:v00008086d00003723*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 3
+
+pci:v00008086d00003724*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 4
+
+pci:v00008086d00003725*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 NTB Primary
+
+pci:v00008086d00003726*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 NTB Primary
+
+pci:v00008086d00003727*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 NTB Secondary
+
+pci:v00008086d00003728*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Core
+
+pci:v00008086d00003729*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Core
+
+pci:v00008086d0000372A*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Core
+
+pci:v00008086d0000372B*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Core
+
+pci:v00008086d0000372C*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Reserved
+
+pci:v00008086d0000373F*
+ ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 IOxAPIC
+
+pci:v00008086d00003A00*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) 4-port SATA IDE Controller
+
+pci:v00008086d00003A02*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) SATA AHCI Controller
+
+pci:v00008086d00003A05*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) SATA RAID Controller
+
+pci:v00008086d00003A06*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) 2-port SATA IDE Controller
+
+pci:v00008086d00003A14*
+ ID_PRODUCT_FROM_DATABASE=82801JDO (ICH10DO) LPC Interface Controller
+
+pci:v00008086d00003A16*
+ ID_PRODUCT_FROM_DATABASE=82801JIR (ICH10R) LPC Interface Controller
+
+pci:v00008086d00003A16sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 LPC Interface Controller
+
+pci:v00008086d00003A16sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 LPC Interface Controller
+
+pci:v00008086d00003A16sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003A16sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A16sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00003A18*
+ ID_PRODUCT_FROM_DATABASE=82801JIB (ICH10) LPC Interface Controller
+
+pci:v00008086d00003A1A*
+ ID_PRODUCT_FROM_DATABASE=82801JD (ICH10D) LPC Interface Controller
+
+pci:v00008086d00003A20*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) 4 port SATA IDE Controller #1
+
+pci:v00008086d00003A20sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 SATA IDE Controller
+
+pci:v00008086d00003A20sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 SATA IDE Controller
+
+pci:v00008086d00003A22*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) SATA AHCI Controller
+
+pci:v00008086d00003A22sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003A22sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A22sv00001458sd0000B005*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00003A25*
+ ID_PRODUCT_FROM_DATABASE=82801JIR (ICH10R) SATA RAID Controller
+
+pci:v00008086d00003A25sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PERC S100 Controller (PE R410)
+
+pci:v00008086d00003A25sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PERC S100 Controller (PE T410)
+
+pci:v00008086d00003A25sv00001028sd000002F1*
+ ID_PRODUCT_FROM_DATABASE=PERC S100 Controller (PE R510)
+
+pci:v00008086d00003A26*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) 2 port SATA IDE Controller #2
+
+pci:v00008086d00003A26sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 SATA IDE Controller
+
+pci:v00008086d00003A26sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 SATA IDE Controller
+
+pci:v00008086d00003A30*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) SMBus Controller
+
+pci:v00008086d00003A30sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A30sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00003A32*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) Thermal Subsystem
+
+pci:v00008086d00003A34*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #1
+
+pci:v00008086d00003A34sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+
+pci:v00008086d00003A34sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+
+pci:v00008086d00003A34sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003A34sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A34sv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00003A35*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #2
+
+pci:v00008086d00003A35sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+
+pci:v00008086d00003A35sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+
+pci:v00008086d00003A35sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003A35sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A35sv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00003A36*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #3
+
+pci:v00008086d00003A36sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+
+pci:v00008086d00003A36sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+
+pci:v00008086d00003A36sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003A36sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A36sv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00003A37*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #4
+
+pci:v00008086d00003A37sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+
+pci:v00008086d00003A37sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+
+pci:v00008086d00003A37sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003A37sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A37sv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00003A38*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #5
+
+pci:v00008086d00003A38sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+
+pci:v00008086d00003A38sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+
+pci:v00008086d00003A38sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d00003A38sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A38sv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00003A39*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #6
+
+pci:v00008086d00003A39sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+
+pci:v00008086d00003A39sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+
+pci:v00008086d00003A39sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d00003A39sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A39sv00001458sd00005004*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00003A3A*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #1
+
+pci:v00008086d00003A3Asv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB EHCI Controller
+
+pci:v00008086d00003A3Asv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB EHCI Controller
+
+pci:v00008086d00003A3Asv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003A3Asv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A3Asv00001458sd00005006*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00003A3C*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #2
+
+pci:v00008086d00003A3Csv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB EHCI Controller
+
+pci:v00008086d00003A3Csv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB EHCI Controller
+
+pci:v00008086d00003A3Csv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant G6 series
+
+pci:v00008086d00003A3Csv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A3Csv00001458sd00005006*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00003A3E*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) HD Audio Controller
+
+pci:v00008086d00003A3Esv00001043sd00008311*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A3Esv00001458sd0000A002*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-UD3R Motherboard
+
+pci:v00008086d00003A3Esv00001458sd0000A102*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00003A40*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1
+
+pci:v00008086d00003A40sv00001028sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R410 PCI Express Port 1
+
+pci:v00008086d00003A40sv00001028sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T410 PCI Express Port 1
+
+pci:v00008086d00003A40sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d00003A40sv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A40sv00001043sd000082EA*
+ ID_PRODUCT_FROM_DATABASE=P6T DeLuxe Motherboard
+
+pci:v00008086d00003A40sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00003A42*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Port 2
+
+pci:v00008086d00003A44*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 3
+
+pci:v00008086d00003A44sv00001043sd000082EA*
+ ID_PRODUCT_FROM_DATABASE=P6T DeLuxe Motherboard
+
+pci:v00008086d00003A46*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 4
+
+pci:v00008086d00003A46sv00001043sd000082EA*
+ ID_PRODUCT_FROM_DATABASE=P6T DeLuxe Motherboard
+
+pci:v00008086d00003A46sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00003A48*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 5
+
+pci:v00008086d00003A48sv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d00003A48sv00001043sd000082EA*
+ ID_PRODUCT_FROM_DATABASE=P6T Deluxe Motherboard
+
+pci:v00008086d00003A48sv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard
+
+pci:v00008086d00003A4A*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 6
+
+pci:v00008086d00003A4Asv0000103Csd0000330B*
+ ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server
+
+pci:v00008086d00003A4Asv00001043sd000082D4*
+ ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard
+
+pci:v00008086d00003A4Asv00001043sd000082EA*
+ ID_PRODUCT_FROM_DATABASE=P6T DeLuxe Motherboard
+
+pci:v00008086d00003A4Asv00001458sd00005001*
+ ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+
+pci:v00008086d00003A4C*
+ ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) Gigabit Ethernet Controller
+
+pci:v00008086d00003A51*
+ ID_PRODUCT_FROM_DATABASE=82801JDO (ICH10DO) VECI Controller
+
+pci:v00008086d00003A55*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) Virtual SATA Controller
+
+pci:v00008086d00003A60*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) SMBus Controller
+
+pci:v00008086d00003A62*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) Thermal Subsystem
+
+pci:v00008086d00003A64*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #1
+
+pci:v00008086d00003A65*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #2
+
+pci:v00008086d00003A66*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #3
+
+pci:v00008086d00003A67*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #4
+
+pci:v00008086d00003A68*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #5
+
+pci:v00008086d00003A69*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #6
+
+pci:v00008086d00003A6A*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB2 EHCI Controller #1
+
+pci:v00008086d00003A6C*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB2 EHCI Controller #2
+
+pci:v00008086d00003A6E*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) HD Audio Controller
+
+pci:v00008086d00003A70*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 1
+
+pci:v00008086d00003A72*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 2
+
+pci:v00008086d00003A74*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 3
+
+pci:v00008086d00003A76*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 4
+
+pci:v00008086d00003A78*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 5
+
+pci:v00008086d00003A7A*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 6
+
+pci:v00008086d00003A7C*
+ ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) Gigabit Ethernet Controller
+
+pci:v00008086d00003B00*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B01*
+ ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B02*
+ ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B03*
+ ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B04*
+ ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B05*
+ ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B06*
+ ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B07*
+ ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B07sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B07sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B08*
+ ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B09*
+ ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B09sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00003B0A*
+ ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B0Asv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d00003B0B*
+ ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B0C*
+ ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B0D*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B0E*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B0F*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B10*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B11*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B12*
+ ID_PRODUCT_FROM_DATABASE=3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B13*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B14*
+ ID_PRODUCT_FROM_DATABASE=3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B15*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B16*
+ ID_PRODUCT_FROM_DATABASE=3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B17*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B18*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B19*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B1A*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B1B*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B1C*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B1D*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B1E*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B1F*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller
+
+pci:v00008086d00003B20*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller
+
+pci:v00008086d00003B21*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller
+
+pci:v00008086d00003B22*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller
+
+pci:v00008086d00003B22sv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d00003B23*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller
+
+pci:v00008086d00003B25*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset SATA RAID Controller
+
+pci:v00008086d00003B26*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller
+
+pci:v00008086d00003B28*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller
+
+pci:v00008086d00003B29*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller
+
+pci:v00008086d00003B29sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00003B2C*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset SATA RAID Controller
+
+pci:v00008086d00003B2D*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller
+
+pci:v00008086d00003B2Dsv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B2E*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller
+
+pci:v00008086d00003B2Esv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B2F*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller
+
+pci:v00008086d00003B2Fsv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B2Fsv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B30*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller
+
+pci:v00008086d00003B30sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00003B30sv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d00003B30sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B30sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B32*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset Thermal Subsystem
+
+pci:v00008086d00003B32sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00003B34*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller
+
+pci:v00008086d00003B34sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00003B34sv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d00003B34sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B34sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B36*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B37*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B38*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B39*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B3A*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B3B*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B3C*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller
+
+pci:v00008086d00003B3Csv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00003B3Csv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d00003B3Csv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B3Csv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B3E*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B3F*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B40*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
+
+pci:v00008086d00003B41*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LAN Controller
+
+pci:v00008086d00003B42*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1
+
+pci:v00008086d00003B42sv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d00003B42sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B44*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 2
+
+pci:v00008086d00003B44sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B46*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 3
+
+pci:v00008086d00003B46sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B48*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 4
+
+pci:v00008086d00003B48sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B4A*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 5
+
+pci:v00008086d00003B4Asv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d00003B4C*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 6
+
+pci:v00008086d00003B4E*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 7
+
+pci:v00008086d00003B50*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 8
+
+pci:v00008086d00003B53*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset VECI Controller
+
+pci:v00008086d00003B56*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio
+
+pci:v00008086d00003B56sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00003B56sv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d00003B56sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d00003B56sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B57*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio
+
+pci:v00008086d00003B64*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller
+
+pci:v00008086d00003B64sv00001025sd00000347*
+ ID_PRODUCT_FROM_DATABASE=Aspire 7740G
+
+pci:v00008086d00003B64sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003B65*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller
+
+pci:v00008086d00003B66*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PT IDER Controller
+
+pci:v00008086d00003B67*
+ ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset KT Controller
+
+pci:v00008086d00003B67sv0000E4BFsd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v00008086d00003C00*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMI2
+
+pci:v00008086d00003C01*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMI2 in PCI Express Mode
+
+pci:v00008086d00003C02*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 1a
+
+pci:v00008086d00003C03*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 1b
+
+pci:v00008086d00003C04*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 2a
+
+pci:v00008086d00003C05*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 2b
+
+pci:v00008086d00003C06*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 2c
+
+pci:v00008086d00003C07*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 2d
+
+pci:v00008086d00003C08*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 3a in PCI Express Mode
+
+pci:v00008086d00003C09*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 3b
+
+pci:v00008086d00003C0A*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 3c
+
+pci:v00008086d00003C0B*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 3d
+
+pci:v00008086d00003C0D*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Non-Transparent Bridge
+
+pci:v00008086d00003C0E*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Non-Transparent Bridge
+
+pci:v00008086d00003C0F*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Non-Transparent Bridge
+
+pci:v00008086d00003C20*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 0
+
+pci:v00008086d00003C21*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 1
+
+pci:v00008086d00003C22*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 2
+
+pci:v00008086d00003C23*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 3
+
+pci:v00008086d00003C24*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 4
+
+pci:v00008086d00003C25*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 5
+
+pci:v00008086d00003C26*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 6
+
+pci:v00008086d00003C27*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 7
+
+pci:v00008086d00003C28*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Address Map, VTd_Misc, System Management
+
+pci:v00008086d00003C2A*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Control Status and Global Errors
+
+pci:v00008086d00003C2C*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 I/O APIC
+
+pci:v00008086d00003C2E*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA
+
+pci:v00008086d00003C2F*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA
+
+pci:v00008086d00003C40*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO Switch and IRP Performance Monitor
+
+pci:v00008086d00003C43*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Ring to PCI Express Performance Monitor
+
+pci:v00008086d00003C44*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Ring to QuickPath Interconnect Link 0 Performance Monitor
+
+pci:v00008086d00003C45*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Ring to QuickPath Interconnect Link 1 Performance Monitor
+
+pci:v00008086d00003C46*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Processor Home Agent Performance Monitoring
+
+pci:v00008086d00003C71*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller RAS Registers
+
+pci:v00008086d00003C80*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link 0
+
+pci:v00008086d00003C83*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link Reut 0
+
+pci:v00008086d00003C84*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link Reut 0
+
+pci:v00008086d00003C90*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link 1
+
+pci:v00008086d00003C93*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link Reut 1
+
+pci:v00008086d00003C94*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link Reut 1
+
+pci:v00008086d00003CA0*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Processor Home Agent
+
+pci:v00008086d00003CA8*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Registers
+
+pci:v00008086d00003CAA*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 0
+
+pci:v00008086d00003CAB*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 1
+
+pci:v00008086d00003CAC*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 2
+
+pci:v00008086d00003CAD*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 3
+
+pci:v00008086d00003CAE*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 4
+
+pci:v00008086d00003CB0*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Channel 0-3 Thermal Control 0
+
+pci:v00008086d00003CB1*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Channel 0-3 Thermal Control 1
+
+pci:v00008086d00003CB2*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller ERROR Registers 0
+
+pci:v00008086d00003CB3*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller ERROR Registers 1
+
+pci:v00008086d00003CB4*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Channel 0-3 Thermal Control 2
+
+pci:v00008086d00003CB5*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Channel 0-3 Thermal Control 3
+
+pci:v00008086d00003CB6*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller ERROR Registers 2
+
+pci:v00008086d00003CB7*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller ERROR Registers 3
+
+pci:v00008086d00003CB8*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DDRIO
+
+pci:v00008086d00003CC0*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Power Control Unit 0
+
+pci:v00008086d00003CC1*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Power Control Unit 1
+
+pci:v00008086d00003CC2*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Power Control Unit 2
+
+pci:v00008086d00003CD0*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Power Control Unit 3
+
+pci:v00008086d00003CE0*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Interrupt Control Registers
+
+pci:v00008086d00003CE3*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Semaphore and Scratchpad Configuration Registers
+
+pci:v00008086d00003CE4*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 R2PCIe
+
+pci:v00008086d00003CE6*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QuickPath Interconnect Agent Ring Registers
+
+pci:v00008086d00003CE8*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 0
+
+pci:v00008086d00003CE9*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 5
+
+pci:v00008086d00003CEA*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 1
+
+pci:v00008086d00003CEB*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 6
+
+pci:v00008086d00003CEC*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 3
+
+pci:v00008086d00003CED*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 7
+
+pci:v00008086d00003CEE*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 4
+
+pci:v00008086d00003CEF*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 8
+
+pci:v00008086d00003CF4*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller System Address Decoder 0
+
+pci:v00008086d00003CF5*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller System Address Decoder 1
+
+pci:v00008086d00003CF6*
+ ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 System Address Decoder
+
+pci:v00008086d00004000*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset Memory Controller Hub
+
+pci:v00008086d00004001*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset Memory Controller Hub
+
+pci:v00008086d00004003*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset Memory Controller Hub
+
+pci:v00008086d00004021*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 1
+
+pci:v00008086d00004022*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 2
+
+pci:v00008086d00004023*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 3
+
+pci:v00008086d00004024*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 4
+
+pci:v00008086d00004025*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 5
+
+pci:v00008086d00004026*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 6
+
+pci:v00008086d00004027*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 7
+
+pci:v00008086d00004028*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 8
+
+pci:v00008086d00004029*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 9
+
+pci:v00008086d0000402D*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset IBIST Registers
+
+pci:v00008086d0000402E*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset IBIST Registers
+
+pci:v00008086d0000402F*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset QuickData Technology Device
+
+pci:v00008086d00004030*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset FSB Registers
+
+pci:v00008086d00004031*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset CE/SF Registers
+
+pci:v00008086d00004032*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset IOxAPIC
+
+pci:v00008086d00004035*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset FBD Registers
+
+pci:v00008086d00004036*
+ ID_PRODUCT_FROM_DATABASE=5400 Chipset FBD Registers
+
+pci:v00008086d00004100*
+ ID_PRODUCT_FROM_DATABASE=Moorestown Graphics and Video
+
+pci:v00008086d00004108*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d00004109*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d0000410A*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d0000410B*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d0000410C*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d0000410D*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d0000410E*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d0000410F*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d00004114*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #1
+
+pci:v00008086d00004115*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #2
+
+pci:v00008086d00004116*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #3
+
+pci:v00008086d00004117*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #4
+
+pci:v00008086d00004220*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection
+
+pci:v00008086d00004220sv0000103Csd00000934*
+ ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220
+
+pci:v00008086d00004220sv0000103Csd000012F6*
+ ID_PRODUCT_FROM_DATABASE=nc6120/nx8220/nw8240
+
+pci:v00008086d00004220sv00008086sd00002712*
+ ID_PRODUCT_FROM_DATABASE=IBM ThinkPad R50e
+
+pci:v00008086d00004220sv00008086sd00002721*
+ ID_PRODUCT_FROM_DATABASE=Dell B130 laptop integrated WLAN
+
+pci:v00008086d00004220sv00008086sd00002722*
+ ID_PRODUCT_FROM_DATABASE=Dell Latitude D600
+
+pci:v00008086d00004220sv00008086sd00002731*
+ ID_PRODUCT_FROM_DATABASE=Samsung P35 integrated WLAN
+
+pci:v00008086d00004222*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection
+
+pci:v00008086d00004222sv0000103Csd0000135C*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection
+
+pci:v00008086d00004222sv00008086sd00001000*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection
+
+pci:v00008086d00004222sv00008086sd00001001*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection
+
+pci:v00008086d00004222sv00008086sd00001005*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945BG Network Connection
+
+pci:v00008086d00004222sv00008086sd00001034*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945BG Network Connection
+
+pci:v00008086d00004222sv00008086sd00001044*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945BG Network Connection
+
+pci:v00008086d00004222sv00008086sd00001C00*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection
+
+pci:v00008086d00004223*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection
+
+pci:v00008086d00004223sv00001000sd00008086*
+ ID_PRODUCT_FROM_DATABASE=mPCI 3B Americas/Europe ZZA
+
+pci:v00008086d00004223sv00001001sd00008086*
+ ID_PRODUCT_FROM_DATABASE=mPCI 3B Europe ZZE
+
+pci:v00008086d00004223sv00001002sd00008086*
+ ID_PRODUCT_FROM_DATABASE=mPCI 3B Japan ZZJ
+
+pci:v00008086d00004223sv00001003sd00008086*
+ ID_PRODUCT_FROM_DATABASE=mPCI 3B High-Band ZZH
+
+pci:v00008086d00004223sv00001351sd0000103C*
+ ID_PRODUCT_FROM_DATABASE=Compaq NC6220
+
+pci:v00008086d00004224*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection
+
+pci:v00008086d00004227*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection
+
+pci:v00008086d00004227sv00008086sd00001011*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad R60e/X60s
+
+pci:v00008086d00004227sv00008086sd00001014*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945BG Network Connection
+
+pci:v00008086d00004229*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection
+
+pci:v00008086d00004229sv00008086sd00001100*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGN-SZ79SN_C
+
+pci:v00008086d00004229sv00008086sd00001101*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 4965 AG or AGN
+
+pci:v00008086d0000422B*
+ ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300
+
+pci:v00008086d0000422Bsv00008086sd00001101*
+ ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN
+
+pci:v00008086d0000422Bsv00008086sd00001121*
+ ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN
+
+pci:v00008086d0000422C*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200
+
+pci:v00008086d0000422Csv00008086sd00001301*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN
+
+pci:v00008086d0000422Csv00008086sd00001306*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG
+
+pci:v00008086d0000422Csv00008086sd00001307*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 BG
+
+pci:v00008086d0000422Csv00008086sd00001321*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN
+
+pci:v00008086d0000422Csv00008086sd00001326*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG
+
+pci:v00008086d00004230*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection
+
+pci:v00008086d00004230sv00008086sd00001110*
+ ID_PRODUCT_FROM_DATABASE=Lenovo ThinkPad T51
+
+pci:v00008086d00004230sv00008086sd00001111*
+ ID_PRODUCT_FROM_DATABASE=Lenovo ThinkPad T61
+
+pci:v00008086d00004232*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100
+
+pci:v00008086d00004232sv00008086sd00001201*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004232sv00008086sd00001204*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004232sv00008086sd00001205*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN
+
+pci:v00008086d00004232sv00008086sd00001206*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG
+
+pci:v00008086d00004232sv00008086sd00001221*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004232sv00008086sd00001224*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004232sv00008086sd00001225*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN
+
+pci:v00008086d00004232sv00008086sd00001226*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG
+
+pci:v00008086d00004232sv00008086sd00001301*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004232sv00008086sd00001304*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004232sv00008086sd00001305*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN
+
+pci:v00008086d00004232sv00008086sd00001306*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG
+
+pci:v00008086d00004232sv00008086sd00001321*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004232sv00008086sd00001324*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004232sv00008086sd00001325*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN
+
+pci:v00008086d00004232sv00008086sd00001326*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG
+
+pci:v00008086d00004235*
+ ID_PRODUCT_FROM_DATABASE=Ultimate N WiFi Link 5300
+
+pci:v00008086d00004236*
+ ID_PRODUCT_FROM_DATABASE=Ultimate N WiFi Link 5300
+
+pci:v00008086d00004237*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection
+
+pci:v00008086d00004237sv00008086sd00001211*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004237sv00008086sd00001214*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004237sv00008086sd00001215*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN
+
+pci:v00008086d00004237sv00008086sd00001216*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG
+
+pci:v00008086d00004237sv00008086sd00001311*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004237sv00008086sd00001314*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN
+
+pci:v00008086d00004237sv00008086sd00001315*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN
+
+pci:v00008086d00004237sv00008086sd00001316*
+ ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG
+
+pci:v00008086d00004238*
+ ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300
+
+pci:v00008086d00004238sv00008086sd00001111*
+ ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN
+
+pci:v00008086d00004239*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200
+
+pci:v00008086d00004239sv00008086sd00001311*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN
+
+pci:v00008086d00004239sv00008086sd00001316*
+ ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG
+
+pci:v00008086d0000423A*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 5350 AGN [Echo Peak] Network Connection
+
+pci:v00008086d0000423B*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 5350 AGN [Echo Peak] Network Connection
+
+pci:v00008086d0000423C*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150
+
+pci:v00008086d0000423Csv00008086sd00001201*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+
+pci:v00008086d0000423Csv00008086sd00001206*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG
+
+pci:v00008086d0000423Csv00008086sd00001221*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+
+pci:v00008086d0000423Csv00008086sd00001301*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+
+pci:v00008086d0000423Csv00008086sd00001306*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG
+
+pci:v00008086d0000423Csv00008086sd00001321*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+
+pci:v00008086d0000423D*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150
+
+pci:v00008086d0000423Dsv00008086sd00001211*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+
+pci:v00008086d0000423Dsv00008086sd00001216*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG
+
+pci:v00008086d0000423Dsv00008086sd00001311*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+
+pci:v00008086d0000423Dsv00008086sd00001316*
+ ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG
+
+pci:v00008086d0000444E*
+ ID_PRODUCT_FROM_DATABASE=Turbo Memory Controller
+
+pci:v00008086d00005001*
+ ID_PRODUCT_FROM_DATABASE=LE80578
+
+pci:v00008086d00005002*
+ ID_PRODUCT_FROM_DATABASE=LE80578 Graphics Processor Unit
+
+pci:v00008086d00005009*
+ ID_PRODUCT_FROM_DATABASE=LE80578 Video Display Controller
+
+pci:v00008086d0000500D*
+ ID_PRODUCT_FROM_DATABASE=LE80578 Expansion Bus
+
+pci:v00008086d0000500E*
+ ID_PRODUCT_FROM_DATABASE=LE80578 UART Controller
+
+pci:v00008086d0000500F*
+ ID_PRODUCT_FROM_DATABASE=LE80578 General Purpose IO
+
+pci:v00008086d00005010*
+ ID_PRODUCT_FROM_DATABASE=LE80578 I2C Controller
+
+pci:v00008086d00005012*
+ ID_PRODUCT_FROM_DATABASE=LE80578 Serial Peripheral Interface Bus
+
+pci:v00008086d00005020*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Memory Controller Hub
+
+pci:v00008086d00005021*
+ ID_PRODUCT_FROM_DATABASE=EP80579 DRAM Error Reporting Registers
+
+pci:v00008086d00005023*
+ ID_PRODUCT_FROM_DATABASE=EP80579 EDMA Controller
+
+pci:v00008086d00005024*
+ ID_PRODUCT_FROM_DATABASE=EP80579 PCI Express Port PEA0
+
+pci:v00008086d00005025*
+ ID_PRODUCT_FROM_DATABASE=EP80579 PCI Express Port PEA1
+
+pci:v00008086d00005028*
+ ID_PRODUCT_FROM_DATABASE=EP80579 S-ATA IDE
+
+pci:v00008086d00005029*
+ ID_PRODUCT_FROM_DATABASE=EP80579 S-ATA AHCI
+
+pci:v00008086d0000502A*
+ ID_PRODUCT_FROM_DATABASE=EP80579 S-ATA Reserved
+
+pci:v00008086d0000502B*
+ ID_PRODUCT_FROM_DATABASE=EP80579 S-ATA Reserved
+
+pci:v00008086d0000502C*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor ASU
+
+pci:v00008086d0000502D*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist ASU
+
+pci:v00008086d0000502E*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d0000502F*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d00005030*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d00005031*
+ ID_PRODUCT_FROM_DATABASE=EP80579 LPC Bus
+
+pci:v00008086d00005032*
+ ID_PRODUCT_FROM_DATABASE=EP80579 SMBus Controller
+
+pci:v00008086d00005033*
+ ID_PRODUCT_FROM_DATABASE=EP80579 USB 1.1 Controller
+
+pci:v00008086d00005035*
+ ID_PRODUCT_FROM_DATABASE=EP80579 USB 2.0 Controller
+
+pci:v00008086d00005037*
+ ID_PRODUCT_FROM_DATABASE=EP80579 PCI-PCI Bridge (transparent mode)
+
+pci:v00008086d00005039*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Controller Area Network (CAN) interface #1
+
+pci:v00008086d0000503A*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Controller Area Network (CAN) interface #2
+
+pci:v00008086d0000503B*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Synchronous Serial Port (SPP)
+
+pci:v00008086d0000503C*
+ ID_PRODUCT_FROM_DATABASE=EP80579 IEEE 1588 Hardware Assist
+
+pci:v00008086d0000503D*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Local Expansion Bus
+
+pci:v00008086d0000503E*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Global Control Unit (GCU)
+
+pci:v00008086d0000503F*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d00005040*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor Gigabit Ethernet MAC
+
+pci:v00008086d00005041*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist Gigabit Ethernet MAC
+
+pci:v00008086d00005042*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d00005043*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d00005044*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor Gigabit Ethernet MAC
+
+pci:v00008086d00005045*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist Gigabit Ethernet MAC
+
+pci:v00008086d00005046*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d00005047*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d00005048*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor Gigabit Ethernet MAC
+
+pci:v00008086d00005049*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist Gigabit Ethernet MAC
+
+pci:v00008086d0000504A*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d0000504B*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Reserved
+
+pci:v00008086d0000504C*
+ ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist TDM
+
+pci:v00008086d00005200*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server
+
+pci:v00008086d00005201*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server
+
+pci:v00008086d00005201sv00008086sd00000001*
+ ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Server Ethernet Adapter
+
+pci:v00008086d0000530D*
+ ID_PRODUCT_FROM_DATABASE=80310 (IOP) IO Processor
+
+pci:v00008086d000065C0*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset Memory Controller Hub
+
+pci:v00008086d000065E2*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 2
+
+pci:v00008086d000065E3*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 3
+
+pci:v00008086d000065E4*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 4
+
+pci:v00008086d000065E5*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 5
+
+pci:v00008086d000065E6*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 6
+
+pci:v00008086d000065E7*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 7
+
+pci:v00008086d000065F0*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset FSB Registers
+
+pci:v00008086d000065F0sv00001028sd0000020F*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge R300
+
+pci:v00008086d000065F0sv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300
+
+pci:v00008086d000065F1*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset Reserved Registers
+
+pci:v00008086d000065F1sv00001028sd00000210*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge T300
+
+pci:v00008086d000065F3*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset Reserved Registers
+
+pci:v00008086d000065F5*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset DDR Channel 0 Registers
+
+pci:v00008086d000065F6*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset DDR Channel 1 Registers
+
+pci:v00008086d000065F7*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x8 Port 2-3
+
+pci:v00008086d000065F8*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x8 Port 4-5
+
+pci:v00008086d000065F9*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x8 Port 6-7
+
+pci:v00008086d000065FA*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x16 Port 4-7
+
+pci:v00008086d000065FF*
+ ID_PRODUCT_FROM_DATABASE=5100 Chipset DMA Engine
+
+pci:v00008086d00007000*
+ ID_PRODUCT_FROM_DATABASE=82371SB PIIX3 ISA [Natoma/Triton II]
+
+pci:v00008086d00007000sv00001AF4sd00001100*
+ ID_PRODUCT_FROM_DATABASE=Qemu virtual machine
+
+pci:v00008086d00007010*
+ ID_PRODUCT_FROM_DATABASE=82371SB PIIX3 IDE [Natoma/Triton II]
+
+pci:v00008086d00007010sv00001AF4sd00001100*
+ ID_PRODUCT_FROM_DATABASE=Qemu virtual machine
+
+pci:v00008086d00007020*
+ ID_PRODUCT_FROM_DATABASE=82371SB PIIX3 USB [Natoma/Triton II]
+
+pci:v00008086d00007020sv00001AF4sd00001100*
+ ID_PRODUCT_FROM_DATABASE=Qemu virtual machine
+
+pci:v00008086d00007030*
+ ID_PRODUCT_FROM_DATABASE=430VX - 82437VX TVX [Triton VX]
+
+pci:v00008086d00007050*
+ ID_PRODUCT_FROM_DATABASE=Intercast Video Capture Card
+
+pci:v00008086d00007051*
+ ID_PRODUCT_FROM_DATABASE=PB 642365-003 (Business Video Conferencing Card)
+
+pci:v00008086d00007100*
+ ID_PRODUCT_FROM_DATABASE=430TX - 82439TX MTXC
+
+pci:v00008086d00007110*
+ ID_PRODUCT_FROM_DATABASE=82371AB/EB/MB PIIX4 ISA
+
+pci:v00008086d00007110sv000015ADsd00001976*
+ ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset
+
+pci:v00008086d00007111*
+ ID_PRODUCT_FROM_DATABASE=82371AB/EB/MB PIIX4 IDE
+
+pci:v00008086d00007111sv000015ADsd00001976*
+ ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset
+
+pci:v00008086d00007112*
+ ID_PRODUCT_FROM_DATABASE=82371AB/EB/MB PIIX4 USB
+
+pci:v00008086d00007112sv000015ADsd00001976*
+ ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset
+
+pci:v00008086d00007113*
+ ID_PRODUCT_FROM_DATABASE=82371AB/EB/MB PIIX4 ACPI
+
+pci:v00008086d00007113sv000015ADsd00001976*
+ ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset
+
+pci:v00008086d00007113sv00001AF4sd00001100*
+ ID_PRODUCT_FROM_DATABASE=Qemu virtual machine
+
+pci:v00008086d00007120*
+ ID_PRODUCT_FROM_DATABASE=82810 GMCH (Graphics Memory Controller Hub)
+
+pci:v00008086d00007120sv00004C53sd00001040*
+ ID_PRODUCT_FROM_DATABASE=CL7 mainboard
+
+pci:v00008086d00007120sv00004C53sd00001060*
+ ID_PRODUCT_FROM_DATABASE=PC7 mainboard
+
+pci:v00008086d00007121*
+ ID_PRODUCT_FROM_DATABASE=82810 (CGC) Chipset Graphics Controller
+
+pci:v00008086d00007121sv00004C53sd00001040*
+ ID_PRODUCT_FROM_DATABASE=CL7 mainboard
+
+pci:v00008086d00007121sv00004C53sd00001060*
+ ID_PRODUCT_FROM_DATABASE=PC7 mainboard
+
+pci:v00008086d00007121sv00008086sd00004341*
+ ID_PRODUCT_FROM_DATABASE=Cayman (CA810) Mainboard
+
+pci:v00008086d00007122*
+ ID_PRODUCT_FROM_DATABASE=82810 DC-100 (GMCH) Graphics Memory Controller Hub
+
+pci:v00008086d00007123*
+ ID_PRODUCT_FROM_DATABASE=82810 DC-100 (CGC) Chipset Graphics Controller
+
+pci:v00008086d00007124*
+ ID_PRODUCT_FROM_DATABASE=82810E DC-133 (GMCH) Graphics Memory Controller Hub
+
+pci:v00008086d00007124sv00001028sd000000B4*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX110
+
+pci:v00008086d00007125*
+ ID_PRODUCT_FROM_DATABASE=82810E DC-133 (CGC) Chipset Graphics Controller
+
+pci:v00008086d00007125sv00001028sd000000B4*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex GX110
+
+pci:v00008086d00007126*
+ ID_PRODUCT_FROM_DATABASE=82810 DC-133 System and Graphics Controller
+
+pci:v00008086d00007128*
+ ID_PRODUCT_FROM_DATABASE=82810-M DC-100 System and Graphics Controller
+
+pci:v00008086d0000712A*
+ ID_PRODUCT_FROM_DATABASE=82810-M DC-133 System and Graphics Controller
+
+pci:v00008086d00007180*
+ ID_PRODUCT_FROM_DATABASE=440LX/EX - 82443LX/EX Host bridge
+
+pci:v00008086d00007181*
+ ID_PRODUCT_FROM_DATABASE=440LX/EX - 82443LX/EX AGP bridge
+
+pci:v00008086d00007190*
+ ID_PRODUCT_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge
+
+pci:v00008086d00007190sv00000E11sd00000500*
+ ID_PRODUCT_FROM_DATABASE=Armada 1750 Laptop System Chipset
+
+pci:v00008086d00007190sv00000E11sd0000B110*
+ ID_PRODUCT_FROM_DATABASE=Armada M700/E500
+
+pci:v00008086d00007190sv00001028sd0000008E*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1300 mainboard
+
+pci:v00008086d00007190sv00001043sd0000803B*
+ ID_PRODUCT_FROM_DATABASE=CUBX-L/E Mainboard
+
+pci:v00008086d00007190sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Toshiba Tecra 8100 Laptop System Chipset
+
+pci:v00008086d00007190sv000015ADsd00001976*
+ ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset
+
+pci:v00008086d00007190sv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v00008086d00007190sv00004C53sd00001051*
+ ID_PRODUCT_FROM_DATABASE=CE7 mainboard
+
+pci:v00008086d00007191*
+ ID_PRODUCT_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
+
+pci:v00008086d00007191sv00001028sd0000008E*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1300 mainboard
+
+pci:v00008086d00007192*
+ ID_PRODUCT_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
+
+pci:v00008086d00007192sv00000E11sd00000460*
+ ID_PRODUCT_FROM_DATABASE=Armada 1700 Laptop System Chipset
+
+pci:v00008086d00007192sv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Satellite 4010
+
+pci:v00008086d00007192sv00004C53sd00001000*
+ ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+
+pci:v00008086d00007192sv00008086sd00007190*
+ ID_PRODUCT_FROM_DATABASE=Dell PowerEdge 350
+
+pci:v00008086d00007194*
+ ID_PRODUCT_FROM_DATABASE=82440MX Host Bridge
+
+pci:v00008086d00007194sv00001033sd00000000*
+ ID_PRODUCT_FROM_DATABASE=Versa Note Vxi
+
+pci:v00008086d00007194sv00004C53sd000010A0*
+ ID_PRODUCT_FROM_DATABASE=CA3/CR3 mainboard
+
+pci:v00008086d00007195*
+ ID_PRODUCT_FROM_DATABASE=82440MX AC'97 Audio Controller
+
+pci:v00008086d00007195sv00001033sd000080CC*
+ ID_PRODUCT_FROM_DATABASE=Versa Note VXi
+
+pci:v00008086d00007195sv000010CFsd00001099*
+ ID_PRODUCT_FROM_DATABASE=QSound_SigmaTel Stac97 PCI Audio
+
+pci:v00008086d00007195sv000011D4sd00000040*
+ ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio
+
+pci:v00008086d00007195sv000011D4sd00000048*
+ ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio
+
+pci:v00008086d00007196*
+ ID_PRODUCT_FROM_DATABASE=82440MX AC'97 Modem Controller
+
+pci:v00008086d00007198*
+ ID_PRODUCT_FROM_DATABASE=82440MX ISA Bridge
+
+pci:v00008086d00007199*
+ ID_PRODUCT_FROM_DATABASE=82440MX EIDE Controller
+
+pci:v00008086d0000719A*
+ ID_PRODUCT_FROM_DATABASE=82440MX USB Universal Host Controller
+
+pci:v00008086d0000719B*
+ ID_PRODUCT_FROM_DATABASE=82440MX Power Management Controller
+
+pci:v00008086d000071A0*
+ ID_PRODUCT_FROM_DATABASE=440GX - 82443GX Host bridge
+
+pci:v00008086d000071A0sv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v00008086d000071A0sv00004C53sd00001051*
+ ID_PRODUCT_FROM_DATABASE=CE7 mainboard
+
+pci:v00008086d000071A1*
+ ID_PRODUCT_FROM_DATABASE=440GX - 82443GX AGP bridge
+
+pci:v00008086d000071A2*
+ ID_PRODUCT_FROM_DATABASE=440GX - 82443GX Host bridge (AGP disabled)
+
+pci:v00008086d000071A2sv00004C53sd00001000*
+ ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+
+pci:v00008086d00007600*
+ ID_PRODUCT_FROM_DATABASE=82372FB PIIX5 ISA
+
+pci:v00008086d00007601*
+ ID_PRODUCT_FROM_DATABASE=82372FB PIIX5 IDE
+
+pci:v00008086d00007602*
+ ID_PRODUCT_FROM_DATABASE=82372FB PIIX5 USB
+
+pci:v00008086d00007603*
+ ID_PRODUCT_FROM_DATABASE=82372FB PIIX5 SMBus
+
+pci:v00008086d00007800*
+ ID_PRODUCT_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator
+
+pci:v00008086d00007800sv0000003Dsd00000008*
+ ID_PRODUCT_FROM_DATABASE=Starfighter AGP
+
+pci:v00008086d00007800sv0000003Dsd0000000B*
+ ID_PRODUCT_FROM_DATABASE=Starfighter AGP
+
+pci:v00008086d00007800sv00001092sd00000100*
+ ID_PRODUCT_FROM_DATABASE=Stealth II G460
+
+pci:v00008086d00007800sv000010B4sd0000201A*
+ ID_PRODUCT_FROM_DATABASE=Lightspeed 740
+
+pci:v00008086d00007800sv000010B4sd0000202F*
+ ID_PRODUCT_FROM_DATABASE=Lightspeed 740
+
+pci:v00008086d00007800sv00008086sd00000000*
+ ID_PRODUCT_FROM_DATABASE=Terminator 2x/i
+
+pci:v00008086d00007800sv00008086sd00000100*
+ ID_PRODUCT_FROM_DATABASE=Intel740 Graphics Accelerator
+
+pci:v00008086d00008002*
+ ID_PRODUCT_FROM_DATABASE=Trusted Execution Technology Registers
+
+pci:v00008086d00008003*
+ ID_PRODUCT_FROM_DATABASE=Trusted Execution Technology Registers
+
+pci:v00008086d00008100*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo)
+
+pci:v00008086d00008108*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) Graphics Controller
+
+pci:v00008086d00008110*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) PCI Express Port 1
+
+pci:v00008086d00008112*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) PCI Express Port 2
+
+pci:v00008086d00008114*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #1
+
+pci:v00008086d00008115*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #2
+
+pci:v00008086d00008116*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #3
+
+pci:v00008086d00008117*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB EHCI #1
+
+pci:v00008086d00008118*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB Client Controller
+
+pci:v00008086d00008119*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) LPC Bridge
+
+pci:v00008086d0000811A*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) IDE Controller
+
+pci:v00008086d0000811B*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) HD Audio Controller
+
+pci:v00008086d0000811C*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #1
+
+pci:v00008086d0000811D*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #2
+
+pci:v00008086d0000811E*
+ ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #3
+
+pci:v00008086d00008180*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Express Port 3
+
+pci:v00008086d00008181*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Express Port 4
+
+pci:v00008086d00008182*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller
+
+pci:v00008086d00008183*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Configuration Unit
+
+pci:v00008086d00008184*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Express Port 1
+
+pci:v00008086d00008185*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Express Port 2
+
+pci:v00008086d00008186*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx LPC Bridge
+
+pci:v00008086d0000821C*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #7
+
+pci:v00008086d0000821D*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #7
+
+pci:v00008086d000084C4*
+ ID_PRODUCT_FROM_DATABASE=450KX/GX [Orion] - 82454KX/GX PCI bridge
+
+pci:v00008086d000084C5*
+ ID_PRODUCT_FROM_DATABASE=450KX/GX [Orion] - 82453KX/GX Memory controller
+
+pci:v00008086d000084CA*
+ ID_PRODUCT_FROM_DATABASE=450NX - 82451NX Memory & I/O Controller
+
+pci:v00008086d000084CB*
+ ID_PRODUCT_FROM_DATABASE=450NX - 82454NX/84460GX PCI Expander Bridge
+
+pci:v00008086d000084E0*
+ ID_PRODUCT_FROM_DATABASE=460GX - 84460GX System Address Controller (SAC)
+
+pci:v00008086d000084E1*
+ ID_PRODUCT_FROM_DATABASE=460GX - 84460GX System Data Controller (SDC)
+
+pci:v00008086d000084E2*
+ ID_PRODUCT_FROM_DATABASE=460GX - 84460GX AGP Bridge (GXB function 2)
+
+pci:v00008086d000084E3*
+ ID_PRODUCT_FROM_DATABASE=460GX - 84460GX Memory Address Controller (MAC)
+
+pci:v00008086d000084E4*
+ ID_PRODUCT_FROM_DATABASE=460GX - 84460GX Memory Data Controller (MDC)
+
+pci:v00008086d000084E6*
+ ID_PRODUCT_FROM_DATABASE=460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB)
+
+pci:v00008086d000084EA*
+ ID_PRODUCT_FROM_DATABASE=460GX - 84460GX AGP Bridge (GXB function 1)
+
+pci:v00008086d00008500*
+ ID_PRODUCT_FROM_DATABASE=IXP4XX Network Processor (IXP420/421/422/425/IXC1100)
+
+pci:v00008086d00008500sv00001993sd00000DED*
+ ID_PRODUCT_FROM_DATABASE=mGuard-PCI AV#2
+
+pci:v00008086d00008500sv00001993sd00000DEE*
+ ID_PRODUCT_FROM_DATABASE=mGuard-PCI AV#1
+
+pci:v00008086d00008500sv00001993sd00000DEF*
+ ID_PRODUCT_FROM_DATABASE=mGuard-PCI AV#0
+
+pci:v00008086d00008800*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T PCI Express Port
+
+pci:v00008086d00008801*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T Packet Hub
+
+pci:v00008086d00008802*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T Gigabit Ethernet Controller
+
+pci:v00008086d00008803*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T General Purpose IO Controller
+
+pci:v00008086d00008804*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #4
+
+pci:v00008086d00008805*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #5
+
+pci:v00008086d00008806*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #6
+
+pci:v00008086d00008807*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB2 EHCI Controller #2
+
+pci:v00008086d00008808*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB Client Controller
+
+pci:v00008086d00008809*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T SDIO Controller #1
+
+pci:v00008086d0000880A*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T SDIO Controller #2
+
+pci:v00008086d0000880B*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T SATA AHCI Controller
+
+pci:v00008086d0000880C*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #1
+
+pci:v00008086d0000880D*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #2
+
+pci:v00008086d0000880E*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #3
+
+pci:v00008086d0000880F*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB2 EHCI Controller #1
+
+pci:v00008086d00008810*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T DMA Controller #1
+
+pci:v00008086d00008811*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T UART Controller 0
+
+pci:v00008086d00008812*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T UART Controller 1
+
+pci:v00008086d00008813*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T UART Controller 2
+
+pci:v00008086d00008814*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T UART Controller 3
+
+pci:v00008086d00008815*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T DMA Controller #2
+
+pci:v00008086d00008816*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T Serial Peripheral Interface Bus
+
+pci:v00008086d00008817*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T I2C Controller
+
+pci:v00008086d00008818*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T Controller Area Network (CAN) Controller
+
+pci:v00008086d00008819*
+ ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T IEEE 1588 Hardware Assist
+
+pci:v00008086d00008C00*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point 4-port SATA Controller 1 [IDE mode]
+
+pci:v00008086d00008C01*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point 4-port SATA Controller 1 [IDE mode]
+
+pci:v00008086d00008C02*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point 6-port SATA Controller 1 [AHCI mode]
+
+pci:v00008086d00008C03*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point 6-port SATA Controller 1 [AHCI mode]
+
+pci:v00008086d00008C04*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode]
+
+pci:v00008086d00008C05*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode]
+
+pci:v00008086d00008C06*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode]
+
+pci:v00008086d00008C07*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode]
+
+pci:v00008086d00008C08*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point 2-port SATA Controller 2 [IDE mode]
+
+pci:v00008086d00008C09*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point 2-port SATA Controller 2 [IDE mode]
+
+pci:v00008086d00008C0E*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode]
+
+pci:v00008086d00008C0F*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode]
+
+pci:v00008086d00008C10*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #1
+
+pci:v00008086d00008C11*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #1
+
+pci:v00008086d00008C12*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #2
+
+pci:v00008086d00008C13*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #2
+
+pci:v00008086d00008C14*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #3
+
+pci:v00008086d00008C15*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #3
+
+pci:v00008086d00008C16*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #4
+
+pci:v00008086d00008C17*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #4
+
+pci:v00008086d00008C18*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #5
+
+pci:v00008086d00008C19*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #5
+
+pci:v00008086d00008C1A*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #6
+
+pci:v00008086d00008C1B*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #6
+
+pci:v00008086d00008C1C*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #7
+
+pci:v00008086d00008C1D*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #7
+
+pci:v00008086d00008C1E*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #8
+
+pci:v00008086d00008C1F*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #8
+
+pci:v00008086d00008C20*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point High Definition Audio Controller
+
+pci:v00008086d00008C21*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point High Definition Audio Controller
+
+pci:v00008086d00008C22*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point SMBus Controller
+
+pci:v00008086d00008C23*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point CHAP Counters
+
+pci:v00008086d00008C24*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point Thermal Management Controller
+
+pci:v00008086d00008C26*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point USB Enhanced Host Controller #1
+
+pci:v00008086d00008C2D*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point USB Enhanced Host Controller #2
+
+pci:v00008086d00008C31*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point USB xHCI Host Controller
+
+pci:v00008086d00008C33*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LAN Controller
+
+pci:v00008086d00008C34*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point NAND Controller
+
+pci:v00008086d00008C3A*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point MEI Controller #1
+
+pci:v00008086d00008C3B*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point MEI Controller #2
+
+pci:v00008086d00008C3C*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point IDE-r Controller
+
+pci:v00008086d00008C3D*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point KT Controller
+
+pci:v00008086d00008C40*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C41*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C42*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C43*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C44*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C45*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C46*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C47*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C48*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C49*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C4A*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C4B*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C4C*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C4D*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C4E*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C4F*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C50*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C51*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C52*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C53*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C54*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C55*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C56*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C57*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C58*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C59*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C5A*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C5B*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C5C*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C5D*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C5E*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008C5F*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller
+
+pci:v00008086d00008D00*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg 4-port SATA Controller [IDE mode]
+
+pci:v00008086d00008D02*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg 6-Port SATA Controller [AHCI mode]
+
+pci:v00008086d00008D04*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg SATA Controller [RAID mode]
+
+pci:v00008086d00008D06*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg SATA Controller [RAID mode]
+
+pci:v00008086d00008D08*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg 2-port SATA Controller [IDE mode]
+
+pci:v00008086d00008D0E*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg SATA Controller [RAID mode]
+
+pci:v00008086d00008D10*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #1
+
+pci:v00008086d00008D11*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #1
+
+pci:v00008086d00008D12*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #2
+
+pci:v00008086d00008D13*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #2
+
+pci:v00008086d00008D14*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #3
+
+pci:v00008086d00008D15*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #3
+
+pci:v00008086d00008D16*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #4
+
+pci:v00008086d00008D17*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #4
+
+pci:v00008086d00008D18*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #5
+
+pci:v00008086d00008D19*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #5
+
+pci:v00008086d00008D1A*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #6
+
+pci:v00008086d00008D1E*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #8
+
+pci:v00008086d00008D1F*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #8
+
+pci:v00008086d00008D20*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg HD Audio Controller
+
+pci:v00008086d00008D21*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg HD Audio Controller
+
+pci:v00008086d00008D22*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg SMBus Controller
+
+pci:v00008086d00008D24*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg Thermal Subsystem
+
+pci:v00008086d00008D26*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg USB Enhanced Host Controller #1
+
+pci:v00008086d00008D2D*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg USB Enhanced Host Controller #2
+
+pci:v00008086d00008D31*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg USB xHCI Host Controller
+
+pci:v00008086d00008D33*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LAN Controller
+
+pci:v00008086d00008D34*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg NAND Controller
+
+pci:v00008086d00008D3A*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg MEI Controller #1
+
+pci:v00008086d00008D3B*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg MEI Controller #2
+
+pci:v00008086d00008D3C*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg IDE-r Controller
+
+pci:v00008086d00008D3D*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg KT Controller
+
+pci:v00008086d00008D40*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D41*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D42*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D43*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D44*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D45*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D46*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D47*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D48*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D49*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D4A*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D4B*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D4C*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D4D*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D4E*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D4F*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller
+
+pci:v00008086d00008D60*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [IDE mode]
+
+pci:v00008086d00008D62*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [AHCI mode]
+
+pci:v00008086d00008D64*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [RAID mode]
+
+pci:v00008086d00008D66*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [RAID mode]
+
+pci:v00008086d00008D68*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [IDE mode]
+
+pci:v00008086d00008D6E*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [RAID mode]
+
+pci:v00008086d00008D7C*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg SPSR
+
+pci:v00008086d00008D7D*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg MS SMBus 0
+
+pci:v00008086d00008D7E*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg MS SMBus 1
+
+pci:v00008086d00008D7F*
+ ID_PRODUCT_FROM_DATABASE=Wellsburg MS SMBus 2
+
+pci:v00008086d00009000*
+ ID_PRODUCT_FROM_DATABASE=IXP2000 Family Network Processor
+
+pci:v00008086d00009001*
+ ID_PRODUCT_FROM_DATABASE=IXP2400 Network Processor
+
+pci:v00008086d00009002*
+ ID_PRODUCT_FROM_DATABASE=IXP2300 Network Processor
+
+pci:v00008086d00009004*
+ ID_PRODUCT_FROM_DATABASE=IXP2800 Network Processor
+
+pci:v00008086d00009621*
+ ID_PRODUCT_FROM_DATABASE=Integrated RAID
+
+pci:v00008086d00009622*
+ ID_PRODUCT_FROM_DATABASE=Integrated RAID
+
+pci:v00008086d00009641*
+ ID_PRODUCT_FROM_DATABASE=Integrated RAID
+
+pci:v00008086d000096A1*
+ ID_PRODUCT_FROM_DATABASE=Integrated RAID
+
+pci:v00008086d00009C00*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [IDE mode]
+
+pci:v00008086d00009C01*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [IDE mode]
+
+pci:v00008086d00009C02*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [AHCI mode]
+
+pci:v00008086d00009C03*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [AHCI mode]
+
+pci:v00008086d00009C04*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+
+pci:v00008086d00009C05*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+
+pci:v00008086d00009C06*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+
+pci:v00008086d00009C07*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+
+pci:v00008086d00009C08*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 2 [IDE mode]
+
+pci:v00008086d00009C09*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 2 [IDE mode]
+
+pci:v00008086d00009C0A*
+ ID_PRODUCT_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved]
+
+pci:v00008086d00009C0B*
+ ID_PRODUCT_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved]
+
+pci:v00008086d00009C0C*
+ ID_PRODUCT_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved]
+
+pci:v00008086d00009C0D*
+ ID_PRODUCT_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved]
+
+pci:v00008086d00009C0E*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+
+pci:v00008086d00009C0F*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+
+pci:v00008086d00009C10*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 1
+
+pci:v00008086d00009C11*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 1
+
+pci:v00008086d00009C12*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 2
+
+pci:v00008086d00009C13*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 2
+
+pci:v00008086d00009C14*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 3
+
+pci:v00008086d00009C15*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 3
+
+pci:v00008086d00009C16*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 4
+
+pci:v00008086d00009C17*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 4
+
+pci:v00008086d00009C18*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 5
+
+pci:v00008086d00009C19*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 5
+
+pci:v00008086d00009C1A*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 6
+
+pci:v00008086d00009C1B*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 6
+
+pci:v00008086d00009C20*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HD Audio Controller
+
+pci:v00008086d00009C21*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HD Audio Controller
+
+pci:v00008086d00009C22*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SMBus Controller
+
+pci:v00008086d00009C23*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP CHAP Counters
+
+pci:v00008086d00009C24*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP Thermal
+
+pci:v00008086d00009C26*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP USB EHCI #1
+
+pci:v00008086d00009C31*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP USB xHCI HC
+
+pci:v00008086d00009C35*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SDIO Controller
+
+pci:v00008086d00009C36*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP Audio DSP Controller
+
+pci:v00008086d00009C3A*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HECI #0
+
+pci:v00008086d00009C3B*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HECI #1
+
+pci:v00008086d00009C3C*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HECI IDER
+
+pci:v00008086d00009C3D*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HECI KT
+
+pci:v00008086d00009C40*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller
+
+pci:v00008086d00009C41*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller
+
+pci:v00008086d00009C42*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller
+
+pci:v00008086d00009C43*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller
+
+pci:v00008086d00009C44*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller
+
+pci:v00008086d00009C45*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller
+
+pci:v00008086d00009C46*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller
+
+pci:v00008086d00009C47*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller
+
+pci:v00008086d00009C60*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP Low Power Sub-System DMA
+
+pci:v00008086d00009C61*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP I2C Controller #0
+
+pci:v00008086d00009C62*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP I2C Controller #1
+
+pci:v00008086d00009C63*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP UART Controller #0
+
+pci:v00008086d00009C64*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP UART Controller #1
+
+pci:v00008086d00009C65*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SPI Controller #0
+
+pci:v00008086d00009C66*
+ ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SPI Controller #1
+
+pci:v00008086d0000A000*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge
+
+pci:v00008086d0000A000sv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d0000A001*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
+
+pci:v00008086d0000A001sv00008086sd00004F4D*
+ ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO
+
+pci:v00008086d0000A002*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
+
+pci:v00008086d0000A003*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx CHAPS counter
+
+pci:v00008086d0000A010*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge
+
+pci:v00008086d0000A010sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d0000A011*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
+
+pci:v00008086d0000A011sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d0000A012*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
+
+pci:v00008086d0000A012sv0000144Dsd0000C072*
+ ID_PRODUCT_FROM_DATABASE=Notebook N150P
+
+pci:v00008086d0000A013*
+ ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx CHAPS counter
+
+pci:v00008086d0000A620*
+ ID_PRODUCT_FROM_DATABASE=6400/6402 Advanced Memory Buffer (AMB)
+
+pci:v00008086d0000B152*
+ ID_PRODUCT_FROM_DATABASE=21152 PCI-to-PCI Bridge
+
+pci:v00008086d0000B152sv00008086sd0000B152*
+ ID_PRODUCT_FROM_DATABASE=21152 PCI-to-PCI Bridge
+
+pci:v00008086d0000B154*
+ ID_PRODUCT_FROM_DATABASE=21154 PCI-to-PCI Bridge
+
+pci:v00008086d0000B555*
+ ID_PRODUCT_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge
+
+pci:v00008086d0000B555sv000012C7sd00005005*
+ ID_PRODUCT_FROM_DATABASE=SS7HD PCI Adaptor Card
+
+pci:v00008086d0000B555sv000012C7sd00005006*
+ ID_PRODUCT_FROM_DATABASE=SS7HDC cPCI Adaptor Card
+
+pci:v00008086d0000B555sv000012D9sd0000000A*
+ ID_PRODUCT_FROM_DATABASE=PCI VoIP Gateway
+
+pci:v00008086d0000B555sv00004C53sd00001050*
+ ID_PRODUCT_FROM_DATABASE=CT7 mainboard
+
+pci:v00008086d0000B555sv00004C53sd00001051*
+ ID_PRODUCT_FROM_DATABASE=CE7 mainboard
+
+pci:v00008086d0000B555sv0000E4BFsd00001000*
+ ID_PRODUCT_FROM_DATABASE=CC8-1-BLUES
+
+pci:v00008086d0000D130*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DMI
+
+pci:v00008086d0000D131*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DMI
+
+pci:v00008086d0000D131sv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d0000D132*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DMI
+
+pci:v00008086d0000D132sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d0000D133*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DMI
+
+pci:v00008086d0000D134*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DMI
+
+pci:v00008086d0000D135*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DMI
+
+pci:v00008086d0000D136*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DMI
+
+pci:v00008086d0000D137*
+ ID_PRODUCT_FROM_DATABASE=Core Processor DMI
+
+pci:v00008086d0000D138*
+ ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express Root Port 1
+
+pci:v00008086d0000D138sv00001028sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=OptiPlex 980
+
+pci:v00008086d0000D138sv00001028sd0000040B*
+ ID_PRODUCT_FROM_DATABASE=Latitude E6510
+
+pci:v00008086d0000D139*
+ ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express Root Port 2
+
+pci:v00008086d0000D13A*
+ ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express Root Port 3
+
+pci:v00008086d0000D13B*
+ ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express Root Port 4
+
+pci:v00008086d0000D150*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QPI Link
+
+pci:v00008086d0000D151*
+ ID_PRODUCT_FROM_DATABASE=Core Processor QPI Routing and Protocol Registers
+
+pci:v00008086d0000D155*
+ ID_PRODUCT_FROM_DATABASE=Core Processor System Management Registers
+
+pci:v00008086d0000D156*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Semaphore and Scratchpad Registers
+
+pci:v00008086d0000D157*
+ ID_PRODUCT_FROM_DATABASE=Core Processor System Control and Status Registers
+
+pci:v00008086d0000D158*
+ ID_PRODUCT_FROM_DATABASE=Core Processor Miscellaneous Registers
+
+pci:v000080EE*
+ ID_VENDOR_FROM_DATABASE=InnoTek Systemberatung GmbH
+
+pci:v000080EEd0000BEEF*
+ ID_PRODUCT_FROM_DATABASE=VirtualBox Graphics Adapter
+
+pci:v000080EEd0000CAFE*
+ ID_PRODUCT_FROM_DATABASE=VirtualBox Guest Service
+
+pci:v00008322*
+ ID_VENDOR_FROM_DATABASE=Sodick America Corp.
+
+pci:v00008384*
+ ID_VENDOR_FROM_DATABASE=SigmaTel
+
+pci:v00008384d00007618*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio Codec
+
+pci:v00008384d00007634*
+ ID_PRODUCT_FROM_DATABASE=9250 HD Audio Codec
+
+pci:v00008384d00007662*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio Codec
+
+pci:v00008384d00007662sv0000104Dsd00001E00*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio Codec [STAC9872AK]
+
+pci:v00008384d00007664*
+ ID_PRODUCT_FROM_DATABASE=High Definition Audio Codec
+
+pci:v00008384d00007670*
+ ID_PRODUCT_FROM_DATABASE=9770 High Definition Audio
+
+pci:v00008384d00007672*
+ ID_PRODUCT_FROM_DATABASE=9772 High Definition Audio
+
+pci:v00008384d00007682*
+ ID_PRODUCT_FROM_DATABASE=IDT High Definition Audio Codec
+
+pci:v00008384d00007690*
+ ID_PRODUCT_FROM_DATABASE=9200 HD Audio Codec
+
+pci:v00008384d00007690sv00001028sd000001C1*
+ ID_PRODUCT_FROM_DATABASE=Precision 490
+
+pci:v00008401*
+ ID_VENDOR_FROM_DATABASE=TRENDware International Inc.
+
+pci:v00008686*
+ ID_VENDOR_FROM_DATABASE=ScaleMP
+
+pci:v00008686d00001010*
+ ID_PRODUCT_FROM_DATABASE=vSMPowered system controller [vSMP CTL]
+
+pci:v00008800*
+ ID_VENDOR_FROM_DATABASE=Trigem Computer Inc.
+
+pci:v00008800d00002008*
+ ID_PRODUCT_FROM_DATABASE=Video assistent component
+
+pci:v00008866*
+ ID_VENDOR_FROM_DATABASE=T-Square Design Inc.
+
+pci:v00008888*
+ ID_VENDOR_FROM_DATABASE=Silicon Magic
+
+pci:v00008912*
+ ID_VENDOR_FROM_DATABASE=TRX
+
+pci:v00008C4A*
+ ID_VENDOR_FROM_DATABASE=Winbond
+
+pci:v00008C4Ad00001980*
+ ID_PRODUCT_FROM_DATABASE=W89C940 misprogrammed [ne2k]
+
+pci:v00008E0E*
+ ID_VENDOR_FROM_DATABASE=Computone Corporation
+
+pci:v00008E2E*
+ ID_VENDOR_FROM_DATABASE=KTI
+
+pci:v00008E2Ed00003000*
+ ID_PRODUCT_FROM_DATABASE=ET32P2
+
+pci:v00009004*
+ ID_VENDOR_FROM_DATABASE=Adaptec
+
+pci:v00009004d00000078*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U_CN
+
+pci:v00009004d00001078*
+ ID_PRODUCT_FROM_DATABASE=AIC-7810
+
+pci:v00009004d00001160*
+ ID_PRODUCT_FROM_DATABASE=AIC-1160 [Family Fibre Channel Adapter]
+
+pci:v00009004d00002178*
+ ID_PRODUCT_FROM_DATABASE=AIC-7821
+
+pci:v00009004d00003860*
+ ID_PRODUCT_FROM_DATABASE=AHA-2930CU
+
+pci:v00009004d00003B78*
+ ID_PRODUCT_FROM_DATABASE=AHA-4844W/4844UW
+
+pci:v00009004d00005075*
+ ID_PRODUCT_FROM_DATABASE=AIC-755x
+
+pci:v00009004d00005078*
+ ID_PRODUCT_FROM_DATABASE=AIC-7850
+
+pci:v00009004d00005078sv00009004sd00007850*
+ ID_PRODUCT_FROM_DATABASE=AHA-2904/Integrated AIC-7850
+
+pci:v00009004d00005175*
+ ID_PRODUCT_FROM_DATABASE=AIC-755x
+
+pci:v00009004d00005178*
+ ID_PRODUCT_FROM_DATABASE=AIC-7851
+
+pci:v00009004d00005275*
+ ID_PRODUCT_FROM_DATABASE=AIC-755x
+
+pci:v00009004d00005278*
+ ID_PRODUCT_FROM_DATABASE=AIC-7852
+
+pci:v00009004d00005375*
+ ID_PRODUCT_FROM_DATABASE=AIC-755x
+
+pci:v00009004d00005378*
+ ID_PRODUCT_FROM_DATABASE=AIC-7850
+
+pci:v00009004d00005475*
+ ID_PRODUCT_FROM_DATABASE=AIC-755x
+
+pci:v00009004d00005478*
+ ID_PRODUCT_FROM_DATABASE=AIC-7850
+
+pci:v00009004d00005575*
+ ID_PRODUCT_FROM_DATABASE=AVA-2930
+
+pci:v00009004d00005578*
+ ID_PRODUCT_FROM_DATABASE=AIC-7855
+
+pci:v00009004d00005647*
+ ID_PRODUCT_FROM_DATABASE=ANA-7711 TCP Offload Engine
+
+pci:v00009004d00005647sv00009004sd00007710*
+ ID_PRODUCT_FROM_DATABASE=ANA-7711F TCP Offload Engine - Optical
+
+pci:v00009004d00005647sv00009004sd00007711*
+ ID_PRODUCT_FROM_DATABASE=ANA-7711LP TCP Offload Engine - Copper
+
+pci:v00009004d00005675*
+ ID_PRODUCT_FROM_DATABASE=AIC-755x
+
+pci:v00009004d00005678*
+ ID_PRODUCT_FROM_DATABASE=AIC-7856
+
+pci:v00009004d00005775*
+ ID_PRODUCT_FROM_DATABASE=AIC-755x
+
+pci:v00009004d00005778*
+ ID_PRODUCT_FROM_DATABASE=AIC-7850
+
+pci:v00009004d00005800*
+ ID_PRODUCT_FROM_DATABASE=AIC-5800
+
+pci:v00009004d00005900*
+ ID_PRODUCT_FROM_DATABASE=ANA-5910/5930/5940 ATM155 & 25 LAN Adapter
+
+pci:v00009004d00005905*
+ ID_PRODUCT_FROM_DATABASE=ANA-5910A/5930A/5940A ATM Adapter
+
+pci:v00009004d00006038*
+ ID_PRODUCT_FROM_DATABASE=AIC-3860
+
+pci:v00009004d00006075*
+ ID_PRODUCT_FROM_DATABASE=AIC-1480 / APA-1480
+
+pci:v00009004d00006075sv00009004sd00007560*
+ ID_PRODUCT_FROM_DATABASE=AIC-1480 / APA-1480 Cardbus
+
+pci:v00009004d00006078*
+ ID_PRODUCT_FROM_DATABASE=AIC-7860
+
+pci:v00009004d00006178*
+ ID_PRODUCT_FROM_DATABASE=AIC-7861
+
+pci:v00009004d00006178sv00009004sd00007861*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940AU Single
+
+pci:v00009004d00006278*
+ ID_PRODUCT_FROM_DATABASE=AIC-7860
+
+pci:v00009004d00006378*
+ ID_PRODUCT_FROM_DATABASE=AIC-7860
+
+pci:v00009004d00006478*
+ ID_PRODUCT_FROM_DATABASE=AIC-786x
+
+pci:v00009004d00006578*
+ ID_PRODUCT_FROM_DATABASE=AIC-786x
+
+pci:v00009004d00006678*
+ ID_PRODUCT_FROM_DATABASE=AIC-786x
+
+pci:v00009004d00006778*
+ ID_PRODUCT_FROM_DATABASE=AIC-786x
+
+pci:v00009004d00006915*
+ ID_PRODUCT_FROM_DATABASE=ANA620xx/ANA69011A
+
+pci:v00009004d00006915sv00009004sd00000008*
+ ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 10/100
+
+pci:v00009004d00006915sv00009004sd00000009*
+ ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 10/100
+
+pci:v00009004d00006915sv00009004sd00000010*
+ ID_PRODUCT_FROM_DATABASE=ANA62022 2-port 10/100
+
+pci:v00009004d00006915sv00009004sd00000018*
+ ID_PRODUCT_FROM_DATABASE=ANA62044 4-port 10/100
+
+pci:v00009004d00006915sv00009004sd00000019*
+ ID_PRODUCT_FROM_DATABASE=ANA62044 4-port 10/100
+
+pci:v00009004d00006915sv00009004sd00000020*
+ ID_PRODUCT_FROM_DATABASE=ANA62022 2-port 10/100
+
+pci:v00009004d00006915sv00009004sd00000028*
+ ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 10/100
+
+pci:v00009004d00006915sv00009004sd00008008*
+ ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 64 bit 10/100
+
+pci:v00009004d00006915sv00009004sd00008009*
+ ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 64 bit 10/100
+
+pci:v00009004d00006915sv00009004sd00008010*
+ ID_PRODUCT_FROM_DATABASE=ANA62022 2-port 64 bit 10/100
+
+pci:v00009004d00006915sv00009004sd00008018*
+ ID_PRODUCT_FROM_DATABASE=ANA62044 4-port 64 bit 10/100
+
+pci:v00009004d00006915sv00009004sd00008019*
+ ID_PRODUCT_FROM_DATABASE=ANA62044 4-port 64 bit 10/100
+
+pci:v00009004d00006915sv00009004sd00008020*
+ ID_PRODUCT_FROM_DATABASE=ANA62022 2-port 64 bit 10/100
+
+pci:v00009004d00006915sv00009004sd00008028*
+ ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 64 bit 10/100
+
+pci:v00009004d00007078*
+ ID_PRODUCT_FROM_DATABASE=AHA-294x / AIC-7870
+
+pci:v00009004d00007178*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940/2940W / AIC-7871
+
+pci:v00009004d00007278*
+ ID_PRODUCT_FROM_DATABASE=AHA-3940/3940W / AIC-7872
+
+pci:v00009004d00007378*
+ ID_PRODUCT_FROM_DATABASE=AHA-3985 / AIC-7873
+
+pci:v00009004d00007478*
+ ID_PRODUCT_FROM_DATABASE=AHA-2944/2944W / AIC-7874
+
+pci:v00009004d00007578*
+ ID_PRODUCT_FROM_DATABASE=AHA-3944/3944W / AIC-7875
+
+pci:v00009004d00007678*
+ ID_PRODUCT_FROM_DATABASE=AHA-4944W/UW / AIC-7876
+
+pci:v00009004d00007710*
+ ID_PRODUCT_FROM_DATABASE=ANA-7711F Network Accelerator Card (NAC) - Optical
+
+pci:v00009004d00007711*
+ ID_PRODUCT_FROM_DATABASE=ANA-7711C Network Accelerator Card (NAC) - Copper
+
+pci:v00009004d00007778*
+ ID_PRODUCT_FROM_DATABASE=AIC-787x
+
+pci:v00009004d00007810*
+ ID_PRODUCT_FROM_DATABASE=AIC-7810
+
+pci:v00009004d00007815*
+ ID_PRODUCT_FROM_DATABASE=AIC-7815 RAID+Memory Controller IC
+
+pci:v00009004d00007815sv00009004sd00007815*
+ ID_PRODUCT_FROM_DATABASE=ARO-1130U2 RAID Controller
+
+pci:v00009004d00007815sv00009004sd00007840*
+ ID_PRODUCT_FROM_DATABASE=AIC-7815 RAID+Memory Controller IC
+
+pci:v00009004d00007850*
+ ID_PRODUCT_FROM_DATABASE=AIC-7850
+
+pci:v00009004d00007855*
+ ID_PRODUCT_FROM_DATABASE=AHA-2930
+
+pci:v00009004d00007860*
+ ID_PRODUCT_FROM_DATABASE=AIC-7860
+
+pci:v00009004d00007870*
+ ID_PRODUCT_FROM_DATABASE=AIC-7870
+
+pci:v00009004d00007871*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940
+
+pci:v00009004d00007872*
+ ID_PRODUCT_FROM_DATABASE=AHA-3940
+
+pci:v00009004d00007873*
+ ID_PRODUCT_FROM_DATABASE=AHA-3980
+
+pci:v00009004d00007874*
+ ID_PRODUCT_FROM_DATABASE=AHA-2944
+
+pci:v00009004d00007880*
+ ID_PRODUCT_FROM_DATABASE=AIC-7880P
+
+pci:v00009004d00007890*
+ ID_PRODUCT_FROM_DATABASE=AIC-7890
+
+pci:v00009004d00007891*
+ ID_PRODUCT_FROM_DATABASE=AIC-789x
+
+pci:v00009004d00007892*
+ ID_PRODUCT_FROM_DATABASE=AIC-789x
+
+pci:v00009004d00007893*
+ ID_PRODUCT_FROM_DATABASE=AIC-789x
+
+pci:v00009004d00007894*
+ ID_PRODUCT_FROM_DATABASE=AIC-789x
+
+pci:v00009004d00007895*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895
+
+pci:v00009004d00007895sv00009004sd00007890*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+
+pci:v00009004d00007895sv00009004sd00007891*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual
+
+pci:v00009004d00007895sv00009004sd00007892*
+ ID_PRODUCT_FROM_DATABASE=AHA-3940AU/AUW/AUWD/UWD
+
+pci:v00009004d00007895sv00009004sd00007894*
+ ID_PRODUCT_FROM_DATABASE=AHA-3944AUWD
+
+pci:v00009004d00007895sv00009004sd00007895*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+
+pci:v00009004d00007895sv00009004sd00007896*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+
+pci:v00009004d00007895sv00009004sd00007897*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+
+pci:v00009004d00007896*
+ ID_PRODUCT_FROM_DATABASE=AIC-789x
+
+pci:v00009004d00007897*
+ ID_PRODUCT_FROM_DATABASE=AIC-789x
+
+pci:v00009004d00008078*
+ ID_PRODUCT_FROM_DATABASE=AIC-7880U
+
+pci:v00009004d00008078sv00009004sd00007880*
+ ID_PRODUCT_FROM_DATABASE=AIC-7880P Ultra/Ultra Wide SCSI Chipset
+
+pci:v00009004d00008178*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U/UW/D / AIC-7881U
+
+pci:v00009004d00008178sv00009004sd00007881*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940UW SCSI Host Adapter
+
+pci:v00009004d00008278*
+ ID_PRODUCT_FROM_DATABASE=AHA-3940U/UW/UWD / AIC-7882U
+
+pci:v00009004d00008378*
+ ID_PRODUCT_FROM_DATABASE=AHA-3940U/UW / AIC-7883U
+
+pci:v00009004d00008478*
+ ID_PRODUCT_FROM_DATABASE=AHA-2944UW / AIC-7884U
+
+pci:v00009004d00008578*
+ ID_PRODUCT_FROM_DATABASE=AHA-3944U/UWD / AIC-7885
+
+pci:v00009004d00008678*
+ ID_PRODUCT_FROM_DATABASE=AHA-4944UW / AIC-7886
+
+pci:v00009004d00008778*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940UW Pro / AIC-788x
+
+pci:v00009004d00008778sv00009004sd00007887*
+ ID_PRODUCT_FROM_DATABASE=2940UW Pro Ultra-Wide SCSI Controller
+
+pci:v00009004d00008878*
+ ID_PRODUCT_FROM_DATABASE=AHA-2930UW / AIC-7888
+
+pci:v00009004d00008878sv00009004sd00007888*
+ ID_PRODUCT_FROM_DATABASE=AHA-2930UW SCSI Controller
+
+pci:v00009004d00008B78*
+ ID_PRODUCT_FROM_DATABASE=ABA-1030
+
+pci:v00009004d0000EC78*
+ ID_PRODUCT_FROM_DATABASE=AHA-4944W/UW
+
+pci:v00009005*
+ ID_VENDOR_FROM_DATABASE=Adaptec
+
+pci:v00009005d00000010*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U2/U2W
+
+pci:v00009005d00000010sv00009005sd00002180*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U2 SCSI Controller
+
+pci:v00009005d00000010sv00009005sd00008100*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U2B SCSI Controller
+
+pci:v00009005d00000010sv00009005sd0000A100*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U2B SCSI Controller
+
+pci:v00009005d00000010sv00009005sd0000A180*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U2W SCSI Controller
+
+pci:v00009005d00000010sv00009005sd0000E100*
+ ID_PRODUCT_FROM_DATABASE=AHA-2950U2B SCSI Controller
+
+pci:v00009005d00000011*
+ ID_PRODUCT_FROM_DATABASE=AHA-2930U2
+
+pci:v00009005d00000013*
+ ID_PRODUCT_FROM_DATABASE=78902
+
+pci:v00009005d00000013sv00009005sd00000003*
+ ID_PRODUCT_FROM_DATABASE=AAA-131U2 Array1000 1 Channel RAID Controller
+
+pci:v00009005d00000013sv00009005sd0000000F*
+ ID_PRODUCT_FROM_DATABASE=AIC7890_ARO
+
+pci:v00009005d0000001F*
+ ID_PRODUCT_FROM_DATABASE=AHA-2940U2/U2W / 7890/7891
+
+pci:v00009005d0000001Fsv00009005sd0000000F*
+ ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller
+
+pci:v00009005d0000001Fsv00009005sd0000A180*
+ ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller
+
+pci:v00009005d00000020*
+ ID_PRODUCT_FROM_DATABASE=AIC-7890
+
+pci:v00009005d0000002F*
+ ID_PRODUCT_FROM_DATABASE=AIC-7890
+
+pci:v00009005d00000030*
+ ID_PRODUCT_FROM_DATABASE=AIC-7890
+
+pci:v00009005d0000003F*
+ ID_PRODUCT_FROM_DATABASE=AIC-7890
+
+pci:v00009005d00000050*
+ ID_PRODUCT_FROM_DATABASE=AHA-3940U2x/395U2x
+
+pci:v00009005d00000050sv00009005sd0000F500*
+ ID_PRODUCT_FROM_DATABASE=AHA-3950U2B
+
+pci:v00009005d00000050sv00009005sd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=AHA-3950U2B
+
+pci:v00009005d00000051*
+ ID_PRODUCT_FROM_DATABASE=AHA-3950U2D
+
+pci:v00009005d00000051sv00009005sd0000B500*
+ ID_PRODUCT_FROM_DATABASE=AHA-3950U2D
+
+pci:v00009005d00000053*
+ ID_PRODUCT_FROM_DATABASE=AIC-7896 SCSI Controller
+
+pci:v00009005d00000053sv00009005sd0000FFFF*
+ ID_PRODUCT_FROM_DATABASE=AIC-7896 SCSI Controller mainboard implementation
+
+pci:v00009005d0000005F*
+ ID_PRODUCT_FROM_DATABASE=AIC-7896U2/7897U2
+
+pci:v00009005d00000080*
+ ID_PRODUCT_FROM_DATABASE=AIC-7892A U160/m
+
+pci:v00009005d00000080sv00000E11sd0000E2A0*
+ ID_PRODUCT_FROM_DATABASE=Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter
+
+pci:v00009005d00000080sv00009005sd00006220*
+ ID_PRODUCT_FROM_DATABASE=AHA-29160C
+
+pci:v00009005d00000080sv00009005sd000062A0*
+ ID_PRODUCT_FROM_DATABASE=29160N Ultra160 SCSI Controller
+
+pci:v00009005d00000080sv00009005sd0000E220*
+ ID_PRODUCT_FROM_DATABASE=29160LP Low Profile Ultra160 SCSI Controller
+
+pci:v00009005d00000080sv00009005sd0000E2A0*
+ ID_PRODUCT_FROM_DATABASE=29160 Ultra160 SCSI Controller
+
+pci:v00009005d00000081*
+ ID_PRODUCT_FROM_DATABASE=AIC-7892B U160/m
+
+pci:v00009005d00000081sv00009005sd000062A1*
+ ID_PRODUCT_FROM_DATABASE=19160 Ultra160 SCSI Controller
+
+pci:v00009005d00000083*
+ ID_PRODUCT_FROM_DATABASE=AIC-7892D U160/m
+
+pci:v00009005d0000008F*
+ ID_PRODUCT_FROM_DATABASE=AIC-7892P U160/m
+
+pci:v00009005d0000008Fsv00001179sd00000001*
+ ID_PRODUCT_FROM_DATABASE=Magnia Z310
+
+pci:v00009005d0000008Fsv000015D9sd00009005*
+ ID_PRODUCT_FROM_DATABASE=Onboard SCSI Host Adapter
+
+pci:v00009005d00000092*
+ ID_PRODUCT_FROM_DATABASE=AVC-2010 [VideoH!]
+
+pci:v00009005d00000093*
+ ID_PRODUCT_FROM_DATABASE=AVC-2410 [VideoH!]
+
+pci:v00009005d000000C0*
+ ID_PRODUCT_FROM_DATABASE=AHA-3960D / AIC-7899A U160/m
+
+pci:v00009005d000000C0sv00000E11sd0000F620*
+ ID_PRODUCT_FROM_DATABASE=Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
+
+pci:v00009005d000000C0sv00009005sd0000F620*
+ ID_PRODUCT_FROM_DATABASE=AHA-3960D U160/m
+
+pci:v00009005d000000C1*
+ ID_PRODUCT_FROM_DATABASE=AIC-7899B U160/m
+
+pci:v00009005d000000C3*
+ ID_PRODUCT_FROM_DATABASE=AIC-7899D U160/m
+
+pci:v00009005d000000C5*
+ ID_PRODUCT_FROM_DATABASE=RAID subsystem HBA
+
+pci:v00009005d000000C5sv00001028sd000000C5*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2400,2500,2550,4400
+
+pci:v00009005d000000CF*
+ ID_PRODUCT_FROM_DATABASE=AIC-7899P U160/m
+
+pci:v00009005d000000CFsv00001028sd000000CE*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 1400
+
+pci:v00009005d000000CFsv00001028sd000000D1*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2550
+
+pci:v00009005d000000CFsv00001028sd000000D9*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge 2500
+
+pci:v00009005d000000CFsv000010F1sd00002462*
+ ID_PRODUCT_FROM_DATABASE=Thunder K7 S2462
+
+pci:v00009005d000000CFsv000015D9sd00009005*
+ ID_PRODUCT_FROM_DATABASE=Onboard SCSI Host Adapter
+
+pci:v00009005d000000CFsv00008086sd00003411*
+ ID_PRODUCT_FROM_DATABASE=SDS2 Mainboard
+
+pci:v00009005d00000241*
+ ID_PRODUCT_FROM_DATABASE=Serial ATA II RAID 1420SA
+
+pci:v00009005d00000242*
+ ID_PRODUCT_FROM_DATABASE=Serial ATA II RAID 1220SA
+
+pci:v00009005d00000243*
+ ID_PRODUCT_FROM_DATABASE=Serial ATA II RAID 1430SA
+
+pci:v00009005d00000244*
+ ID_PRODUCT_FROM_DATABASE=eSATA II RAID 1225SA
+
+pci:v00009005d00000250*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID Controller
+
+pci:v00009005d00000250sv00001014sd00000279*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 6M
+
+pci:v00009005d00000250sv00001014sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 6i/6i+
+
+pci:v00009005d00000250sv00001014sd0000028E*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 7k
+
+pci:v00009005d00000279*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 6M
+
+pci:v00009005d00000283*
+ ID_PRODUCT_FROM_DATABASE=AAC-RAID
+
+pci:v00009005d00000283sv00009005sd00000283*
+ ID_PRODUCT_FROM_DATABASE=Catapult
+
+pci:v00009005d00000284*
+ ID_PRODUCT_FROM_DATABASE=AAC-RAID
+
+pci:v00009005d00000284sv00009005sd00000284*
+ ID_PRODUCT_FROM_DATABASE=Tomcat
+
+pci:v00009005d00000285*
+ ID_PRODUCT_FROM_DATABASE=AAC-RAID
+
+pci:v00009005d00000285sv00000E11sd00000295*
+ ID_PRODUCT_FROM_DATABASE=SATA 6Ch (Bearcat)
+
+pci:v00009005d00000285sv00001014sd000002F2*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 8i
+
+pci:v00009005d00000285sv00001028sd00000287*
+ ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 320/DC
+
+pci:v00009005d00000285sv00001028sd00000291*
+ ID_PRODUCT_FROM_DATABASE=CERC SATA RAID 2 PCI SATA 6ch (DellCorsair)
+
+pci:v00009005d00000285sv0000103Csd00003227*
+ ID_PRODUCT_FROM_DATABASE=AAR-2610SA
+
+pci:v00009005d00000285sv0000108Esd00000286*
+ ID_PRODUCT_FROM_DATABASE=STK RAID INT
+
+pci:v00009005d00000285sv0000108Esd00000287*
+ ID_PRODUCT_FROM_DATABASE=STK RAID EXT
+
+pci:v00009005d00000285sv0000108Esd00007AAC*
+ ID_PRODUCT_FROM_DATABASE=STK RAID REM
+
+pci:v00009005d00000285sv0000108Esd00007AAE*
+ ID_PRODUCT_FROM_DATABASE=STK RAID EX
+
+pci:v00009005d00000285sv000015D9sd000002B5*
+ ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S4i
+
+pci:v00009005d00000285sv000015D9sd000002B6*
+ ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S8i
+
+pci:v00009005d00000285sv000015D9sd000002C9*
+ ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S4iR
+
+pci:v00009005d00000285sv000015D9sd000002CA*
+ ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S8iR
+
+pci:v00009005d00000285sv000015D9sd000002D2*
+ ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S8i-LP
+
+pci:v00009005d00000285sv000015D9sd000002D3*
+ ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S8iR-LP
+
+pci:v00009005d00000285sv000017AAsd00000286*
+ ID_PRODUCT_FROM_DATABASE=Legend S220 (Legend Crusader)
+
+pci:v00009005d00000285sv000017AAsd00000287*
+ ID_PRODUCT_FROM_DATABASE=Legend S230 (Legend Vulcan)
+
+pci:v00009005d00000285sv00009005sd00000285*
+ ID_PRODUCT_FROM_DATABASE=2200S (Vulcan)
+
+pci:v00009005d00000285sv00009005sd00000286*
+ ID_PRODUCT_FROM_DATABASE=2120S (Crusader)
+
+pci:v00009005d00000285sv00009005sd00000287*
+ ID_PRODUCT_FROM_DATABASE=2200S (Vulcan-2m)
+
+pci:v00009005d00000285sv00009005sd00000288*
+ ID_PRODUCT_FROM_DATABASE=3230S (Harrier)
+
+pci:v00009005d00000285sv00009005sd00000289*
+ ID_PRODUCT_FROM_DATABASE=3240S (Tornado)
+
+pci:v00009005d00000285sv00009005sd0000028A*
+ ID_PRODUCT_FROM_DATABASE=ASR-2020ZCR
+
+pci:v00009005d00000285sv00009005sd0000028B*
+ ID_PRODUCT_FROM_DATABASE=ASR-2025ZCR (Terminator)
+
+pci:v00009005d00000285sv00009005sd0000028E*
+ ID_PRODUCT_FROM_DATABASE=ASR-2020SA (Skyhawk)
+
+pci:v00009005d00000285sv00009005sd0000028F*
+ ID_PRODUCT_FROM_DATABASE=ASR-2025SA
+
+pci:v00009005d00000285sv00009005sd00000290*
+ ID_PRODUCT_FROM_DATABASE=AAR-2410SA PCI SATA 4ch (Jaguar II)
+
+pci:v00009005d00000285sv00009005sd00000292*
+ ID_PRODUCT_FROM_DATABASE=AAR-2810SA PCI SATA 8ch (Corsair-8)
+
+pci:v00009005d00000285sv00009005sd00000293*
+ ID_PRODUCT_FROM_DATABASE=AAR-21610SA PCI SATA 16ch (Corsair-16)
+
+pci:v00009005d00000285sv00009005sd00000294*
+ ID_PRODUCT_FROM_DATABASE=ESD SO-DIMM PCI-X SATA ZCR (Prowler)
+
+pci:v00009005d00000285sv00009005sd00000296*
+ ID_PRODUCT_FROM_DATABASE=ASR-2240S
+
+pci:v00009005d00000285sv00009005sd00000297*
+ ID_PRODUCT_FROM_DATABASE=ASR-4005SAS
+
+pci:v00009005d00000285sv00009005sd00000298*
+ ID_PRODUCT_FROM_DATABASE=ASR-4000
+
+pci:v00009005d00000285sv00009005sd00000299*
+ ID_PRODUCT_FROM_DATABASE=ASR-4800SAS
+
+pci:v00009005d00000285sv00009005sd0000029A*
+ ID_PRODUCT_FROM_DATABASE=4805SAS
+
+pci:v00009005d00000285sv00009005sd000002A4*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP9085LI
+
+pci:v00009005d00000285sv00009005sd000002A5*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5085BR
+
+pci:v00009005d00000285sv00009005sd000002B5*
+ ID_PRODUCT_FROM_DATABASE=ASR5800
+
+pci:v00009005d00000285sv00009005sd000002B6*
+ ID_PRODUCT_FROM_DATABASE=ASR5805
+
+pci:v00009005d00000285sv00009005sd000002B7*
+ ID_PRODUCT_FROM_DATABASE=ASR5808
+
+pci:v00009005d00000285sv00009005sd000002B8*
+ ID_PRODUCT_FROM_DATABASE=ICP5445SL
+
+pci:v00009005d00000285sv00009005sd000002B9*
+ ID_PRODUCT_FROM_DATABASE=ICP5085SL
+
+pci:v00009005d00000285sv00009005sd000002BA*
+ ID_PRODUCT_FROM_DATABASE=ICP5805SL
+
+pci:v00009005d00000285sv00009005sd000002BB*
+ ID_PRODUCT_FROM_DATABASE=3405
+
+pci:v00009005d00000285sv00009005sd000002BC*
+ ID_PRODUCT_FROM_DATABASE=3805
+
+pci:v00009005d00000285sv00009005sd000002BD*
+ ID_PRODUCT_FROM_DATABASE=31205
+
+pci:v00009005d00000285sv00009005sd000002BE*
+ ID_PRODUCT_FROM_DATABASE=31605
+
+pci:v00009005d00000285sv00009005sd000002BF*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5045BL
+
+pci:v00009005d00000285sv00009005sd000002C0*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5085BL
+
+pci:v00009005d00000285sv00009005sd000002C1*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5125BR
+
+pci:v00009005d00000285sv00009005sd000002C2*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5165BR
+
+pci:v00009005d00000285sv00009005sd000002C3*
+ ID_PRODUCT_FROM_DATABASE=51205
+
+pci:v00009005d00000285sv00009005sd000002C4*
+ ID_PRODUCT_FROM_DATABASE=51605
+
+pci:v00009005d00000285sv00009005sd000002C5*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5125SL
+
+pci:v00009005d00000285sv00009005sd000002C6*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5165SL
+
+pci:v00009005d00000285sv00009005sd000002C7*
+ ID_PRODUCT_FROM_DATABASE=3085
+
+pci:v00009005d00000285sv00009005sd000002C8*
+ ID_PRODUCT_FROM_DATABASE=ICP5805BL
+
+pci:v00009005d00000285sv00009005sd000002CE*
+ ID_PRODUCT_FROM_DATABASE=51245
+
+pci:v00009005d00000285sv00009005sd000002CF*
+ ID_PRODUCT_FROM_DATABASE=51645
+
+pci:v00009005d00000285sv00009005sd000002D0*
+ ID_PRODUCT_FROM_DATABASE=52445
+
+pci:v00009005d00000285sv00009005sd000002D1*
+ ID_PRODUCT_FROM_DATABASE=5405
+
+pci:v00009005d00000285sv00009005sd000002D4*
+ ID_PRODUCT_FROM_DATABASE=ASR-2045
+
+pci:v00009005d00000285sv00009005sd000002D5*
+ ID_PRODUCT_FROM_DATABASE=ASR-2405
+
+pci:v00009005d00000285sv00009005sd000002D6*
+ ID_PRODUCT_FROM_DATABASE=ASR-2445
+
+pci:v00009005d00000285sv00009005sd000002D7*
+ ID_PRODUCT_FROM_DATABASE=ASR-2805
+
+pci:v00009005d00000285sv00009005sd000002D8*
+ ID_PRODUCT_FROM_DATABASE=5405G
+
+pci:v00009005d00000285sv00009005sd000002D9*
+ ID_PRODUCT_FROM_DATABASE=5445G
+
+pci:v00009005d00000285sv00009005sd000002DA*
+ ID_PRODUCT_FROM_DATABASE=5805G
+
+pci:v00009005d00000285sv00009005sd000002DB*
+ ID_PRODUCT_FROM_DATABASE=5085G
+
+pci:v00009005d00000285sv00009005sd000002DC*
+ ID_PRODUCT_FROM_DATABASE=51245G
+
+pci:v00009005d00000285sv00009005sd000002DD*
+ ID_PRODUCT_FROM_DATABASE=51645G
+
+pci:v00009005d00000285sv00009005sd000002DE*
+ ID_PRODUCT_FROM_DATABASE=52445G
+
+pci:v00009005d00000285sv00009005sd000002DF*
+ ID_PRODUCT_FROM_DATABASE=ASR-2045G
+
+pci:v00009005d00000285sv00009005sd000002E0*
+ ID_PRODUCT_FROM_DATABASE=ASR-2405G
+
+pci:v00009005d00000285sv00009005sd000002E1*
+ ID_PRODUCT_FROM_DATABASE=ASR-2445G
+
+pci:v00009005d00000285sv00009005sd000002E2*
+ ID_PRODUCT_FROM_DATABASE=ASR-2805G
+
+pci:v00009005d00000286*
+ ID_PRODUCT_FROM_DATABASE=AAC-RAID (Rocket)
+
+pci:v00009005d00000286sv00001014sd0000034D*
+ ID_PRODUCT_FROM_DATABASE=8s
+
+pci:v00009005d00000286sv00001014sd00009540*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 8k/8k-l4
+
+pci:v00009005d00000286sv00001014sd00009580*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 8k/8k-l8
+
+pci:v00009005d00000286sv00009005sd0000028C*
+ ID_PRODUCT_FROM_DATABASE=ASR-2230S + ASR-2230SLP PCI-X (Lancer)
+
+pci:v00009005d00000286sv00009005sd0000028D*
+ ID_PRODUCT_FROM_DATABASE=ASR-2130S
+
+pci:v00009005d00000286sv00009005sd0000029B*
+ ID_PRODUCT_FROM_DATABASE=ASR-2820SA
+
+pci:v00009005d00000286sv00009005sd0000029C*
+ ID_PRODUCT_FROM_DATABASE=ASR-2620SA
+
+pci:v00009005d00000286sv00009005sd0000029D*
+ ID_PRODUCT_FROM_DATABASE=ASR-2420SA
+
+pci:v00009005d00000286sv00009005sd0000029E*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP9024R0
+
+pci:v00009005d00000286sv00009005sd0000029F*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP9014R0
+
+pci:v00009005d00000286sv00009005sd000002A0*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP9047MA
+
+pci:v00009005d00000286sv00009005sd000002A1*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP9087MA
+
+pci:v00009005d00000286sv00009005sd000002A2*
+ ID_PRODUCT_FROM_DATABASE=3800
+
+pci:v00009005d00000286sv00009005sd000002A3*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5445AU
+
+pci:v00009005d00000286sv00009005sd000002A4*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP9085LI
+
+pci:v00009005d00000286sv00009005sd000002A5*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5085BR
+
+pci:v00009005d00000286sv00009005sd000002A6*
+ ID_PRODUCT_FROM_DATABASE=ICP9067MA
+
+pci:v00009005d00000286sv00009005sd000002A7*
+ ID_PRODUCT_FROM_DATABASE=3805
+
+pci:v00009005d00000286sv00009005sd000002A8*
+ ID_PRODUCT_FROM_DATABASE=3400
+
+pci:v00009005d00000286sv00009005sd000002A9*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5085AU
+
+pci:v00009005d00000286sv00009005sd000002AA*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5045AU
+
+pci:v00009005d00000286sv00009005sd000002AC*
+ ID_PRODUCT_FROM_DATABASE=1800
+
+pci:v00009005d00000286sv00009005sd000002B3*
+ ID_PRODUCT_FROM_DATABASE=2400
+
+pci:v00009005d00000286sv00009005sd000002B4*
+ ID_PRODUCT_FROM_DATABASE=ICP ICP5045AL
+
+pci:v00009005d00000286sv00009005sd00000800*
+ ID_PRODUCT_FROM_DATABASE=Callisto
+
+pci:v00009005d0000028B*
+ ID_PRODUCT_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2
+
+pci:v00009005d0000028Bsv00009005sd00000200*
+ ID_PRODUCT_FROM_DATABASE=Series 6 Entry Level - ASR-6405E - 4 internal 6G SAS ports
+
+pci:v00009005d0000028Bsv00009005sd00000201*
+ ID_PRODUCT_FROM_DATABASE=Series 6 Entry Level - ASR-6805E - 8 internal 6G SAS ports
+
+pci:v00009005d0000028Bsv00009005sd00000300*
+ ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-6405 - 4 internal 6G SAS ports
+
+pci:v00009005d0000028Bsv00009005sd00000301*
+ ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-6805 - 8 internal 6G SAS ports
+
+pci:v00009005d0000028Bsv00009005sd00000302*
+ ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-6445 - 4 internal and 4 external 6G SAS ports
+
+pci:v00009005d0000028Bsv00009005sd00000310*
+ ID_PRODUCT_FROM_DATABASE=Series 6 Connectors on Top - ASR-6405T - 4 internal 6G SAS ports
+
+pci:v00009005d0000028Bsv00009005sd00000311*
+ ID_PRODUCT_FROM_DATABASE=Series 6 Connectors on Top - ASR-6805T - 8 internal 6G SAS
+
+pci:v00009005d0000028Bsv00009005sd00000400*
+ ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-61205 - 12 internal 6G SAS ports
+
+pci:v00009005d0000028Bsv00009005sd00000401*
+ ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-61605 - 16 internal 6G SAS ports
+
+pci:v00009005d0000028Bsv00009005sd00000403*
+ ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-62405 - 24 internal 6G SAS ports
+
+pci:v00009005d0000028C*
+ ID_PRODUCT_FROM_DATABASE=Series 7 6G SAS/PCIe 3
+
+pci:v00009005d0000028Csv00009005sd00000500*
+ ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-7805 - 8 internal 6G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Csv00009005sd00000501*
+ ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-71605 - 16 internal 6G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Csv00009005sd00000502*
+ ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-71685 - 16 internal 8 external 6G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Csv00009005sd00000503*
+ ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-72405 - 24 internal 0 external 6G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Csv00009005sd00000504*
+ ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-7885 - 8 internal 8 external 6G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Csv00009005sd00000505*
+ ID_PRODUCT_FROM_DATABASE=Series 7 Entry Level - ASR-71685E - 16 internal 8 external 6G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Csv00009005sd00000506*
+ ID_PRODUCT_FROM_DATABASE=Series 7 Entry Level - ASR-72405E - 24 internal 0 external 6G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028D*
+ ID_PRODUCT_FROM_DATABASE=Series 8 12G SAS/PCIe 3
+
+pci:v00009005d0000028Dsv00009005sd00000550*
+ ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-82405 - 24 internal 0 external 12G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Dsv00009005sd00000551*
+ ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-81605 - 16 internal 0 external 12G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Dsv00009005sd00000552*
+ ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-8805 - 8 internal 0 external 12G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Dsv00009005sd00000553*
+ ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-8085 - 0 internal 8 external 12G SAS Port/PCIe 3.0
+
+pci:v00009005d0000028Dsv00009005sd00000554*
+ ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-8885 - 8 internal 8 external 12G SAS Port/PCIe 3.0
+
+pci:v00009005d00000410*
+ ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID)
+
+pci:v00009005d00000410sv00009005sd00000410*
+ ID_PRODUCT_FROM_DATABASE=ASC-48300(Spirit RAID)
+
+pci:v00009005d00000410sv00009005sd00000411*
+ ID_PRODUCT_FROM_DATABASE=ASC-58300 (Oakmont RAID)
+
+pci:v00009005d00000412*
+ ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor HBA non-RAID)
+
+pci:v00009005d00000412sv00009005sd00000412*
+ ID_PRODUCT_FROM_DATABASE=ASC-48300 (Spirit non-RAID)
+
+pci:v00009005d00000412sv00009005sd00000413*
+ ID_PRODUCT_FROM_DATABASE=ASC-58300 (Oakmont non-RAID)
+
+pci:v00009005d00000415*
+ ID_PRODUCT_FROM_DATABASE=ASC-58300 SAS (Razor-External HBA RAID)
+
+pci:v00009005d00000416*
+ ID_PRODUCT_FROM_DATABASE=ASC-58300 SAS (Razor-External HBA non-RAID)
+
+pci:v00009005d0000041E*
+ ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor ASIC non-RAID)
+
+pci:v00009005d0000041F*
+ ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor ASIC RAID)
+
+pci:v00009005d0000041Fsv00009005sd0000041F*
+ ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor ASIC RAID)
+
+pci:v00009005d0000042F*
+ ID_PRODUCT_FROM_DATABASE=VSC7250/7251 SAS (Aurora ASIC non-RAID)
+
+pci:v00009005d00000430*
+ ID_PRODUCT_FROM_DATABASE=AIC-9405W SAS (Razor-Lite HBA RAID)
+
+pci:v00009005d00000430sv00009005sd00000430*
+ ID_PRODUCT_FROM_DATABASE=ASC-44300 (Spirit-Lite RAID)
+
+pci:v00009005d00000432*
+ ID_PRODUCT_FROM_DATABASE=AIC-9405W SAS (Razor-Lite HBA non-RAID)
+
+pci:v00009005d00000432sv00009005sd00000432*
+ ID_PRODUCT_FROM_DATABASE=ASC-44300 (Spirit-Lite non-RAID)
+
+pci:v00009005d0000043E*
+ ID_PRODUCT_FROM_DATABASE=AIC-9405W SAS (Razor-Lite ASIC non-RAID)
+
+pci:v00009005d0000043F*
+ ID_PRODUCT_FROM_DATABASE=AIC-9405W SAS (Razor-Lite ASIC RAID)
+
+pci:v00009005d00000450*
+ ID_PRODUCT_FROM_DATABASE=ASC-1405 Unified Serial HBA
+
+pci:v00009005d00000500*
+ ID_PRODUCT_FROM_DATABASE=Obsidian chipset SCSI controller
+
+pci:v00009005d00000500sv00001014sd000002C1*
+ ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS Adapter (572A/572C)
+
+pci:v00009005d00000500sv00001014sd000002C2*
+ ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572B/572D)
+
+pci:v00009005d00000503*
+ ID_PRODUCT_FROM_DATABASE=Scamp chipset SCSI controller
+
+pci:v00009005d00000503sv00001014sd000002BF*
+ ID_PRODUCT_FROM_DATABASE=Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E)
+
+pci:v00009005d00000503sv00001014sd000002C3*
+ ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572F)
+
+pci:v00009005d00000503sv00001014sd000002D5*
+ ID_PRODUCT_FROM_DATABASE=Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571F)
+
+pci:v00009005d00000910*
+ ID_PRODUCT_FROM_DATABASE=AUA-3100B
+
+pci:v00009005d0000091E*
+ ID_PRODUCT_FROM_DATABASE=AUA-3100B
+
+pci:v00009005d00008000*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320A U320
+
+pci:v00009005d0000800F*
+ ID_PRODUCT_FROM_DATABASE=AIC-7901 U320
+
+pci:v00009005d00008010*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320 U320
+
+pci:v00009005d00008011*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320D
+
+pci:v00009005d00008011sv00000E11sd000000AC*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320D U320
+
+pci:v00009005d00008011sv00009005sd00000041*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320D U320
+
+pci:v00009005d00008012*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320 U320
+
+pci:v00009005d00008013*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320B U320
+
+pci:v00009005d00008014*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320LP U320
+
+pci:v00009005d00008015*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320B U320
+
+pci:v00009005d00008016*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320A U320
+
+pci:v00009005d00008017*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320ALP U320
+
+pci:v00009005d00008017sv00009005sd00000044*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320ALP PCIx U320
+
+pci:v00009005d00008017sv00009005sd00000045*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320LPE PCIe U320
+
+pci:v00009005d0000801C*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320D U320
+
+pci:v00009005d0000801D*
+ ID_PRODUCT_FROM_DATABASE=AIC-7902B U320
+
+pci:v00009005d0000801Dsv00001014sd000002CC*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 7e
+
+pci:v00009005d0000801E*
+ ID_PRODUCT_FROM_DATABASE=AIC-7901A U320
+
+pci:v00009005d0000801F*
+ ID_PRODUCT_FROM_DATABASE=AIC-7902 U320
+
+pci:v00009005d0000801Fsv00001734sd00001011*
+ ID_PRODUCT_FROM_DATABASE=PRIMERGY RX300 onboard SCSI
+
+pci:v00009005d00008080*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320A U320 w/HostRAID
+
+pci:v00009005d0000808F*
+ ID_PRODUCT_FROM_DATABASE=AIC-7901 U320 w/HostRAID
+
+pci:v00009005d00008090*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320 U320 w/HostRAID
+
+pci:v00009005d00008091*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320D U320 w/HostRAID
+
+pci:v00009005d00008092*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320 U320 w/HostRAID
+
+pci:v00009005d00008093*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320B U320 w/HostRAID
+
+pci:v00009005d00008094*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320LP U320 w/HostRAID
+
+pci:v00009005d00008095*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320(B) U320 w/HostRAID
+
+pci:v00009005d00008096*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320A U320 w/HostRAID
+
+pci:v00009005d00008097*
+ ID_PRODUCT_FROM_DATABASE=ASC-29320ALP U320 w/HostRAID
+
+pci:v00009005d0000809C*
+ ID_PRODUCT_FROM_DATABASE=ASC-39320D(B) U320 w/HostRAID
+
+pci:v00009005d0000809D*
+ ID_PRODUCT_FROM_DATABASE=AIC-7902(B) U320 w/HostRAID
+
+pci:v00009005d0000809Dsv00001014sd000002CC*
+ ID_PRODUCT_FROM_DATABASE=ServeRAID 7e
+
+pci:v00009005d0000809E*
+ ID_PRODUCT_FROM_DATABASE=AIC-7901A U320 w/HostRAID
+
+pci:v00009005d0000809F*
+ ID_PRODUCT_FROM_DATABASE=AIC-7902 U320 w/HostRAID
+
+pci:v0000907F*
+ ID_VENDOR_FROM_DATABASE=Atronics
+
+pci:v0000907Fd00002015*
+ ID_PRODUCT_FROM_DATABASE=IDE-2015PL
+
+pci:v0000919A*
+ ID_VENDOR_FROM_DATABASE=Gigapixel Corp
+
+pci:v00009412*
+ ID_VENDOR_FROM_DATABASE=Holtek
+
+pci:v00009412d00006565*
+ ID_PRODUCT_FROM_DATABASE=6565
+
+pci:v00009618*
+ ID_VENDOR_FROM_DATABASE=JusonTech Corporation
+
+pci:v00009618d00000001*
+ ID_PRODUCT_FROM_DATABASE=JusonTech Gigabit Ethernet Controller
+
+pci:v00009699*
+ ID_VENDOR_FROM_DATABASE=Omni Media Technology Inc
+
+pci:v00009699d00006565*
+ ID_PRODUCT_FROM_DATABASE=6565
+
+pci:v00009710*
+ ID_VENDOR_FROM_DATABASE=NetMos Technology
+
+pci:v00009710d00009250*
+ ID_PRODUCT_FROM_DATABASE=PCI-to-PCI bridge [MCS9250]
+
+pci:v00009710d00009805*
+ ID_PRODUCT_FROM_DATABASE=PCI 1 port parallel adapter
+
+pci:v00009710d00009815*
+ ID_PRODUCT_FROM_DATABASE=PCI 9815 Multi-I/O Controller
+
+pci:v00009710d00009815sv00001000sd00000020*
+ ID_PRODUCT_FROM_DATABASE=2P0S (2 port parallel adaptor)
+
+pci:v00009710d00009820*
+ ID_PRODUCT_FROM_DATABASE=PCI 9820 Multi-I/O Controller
+
+pci:v00009710d00009835*
+ ID_PRODUCT_FROM_DATABASE=PCI 9835 Multi-I/O Controller
+
+pci:v00009710d00009835sv00001000sd00000002*
+ ID_PRODUCT_FROM_DATABASE=2S (16C550 UART)
+
+pci:v00009710d00009835sv00001000sd00000012*
+ ID_PRODUCT_FROM_DATABASE=1P2S
+
+pci:v00009710d00009845*
+ ID_PRODUCT_FROM_DATABASE=PCI 9845 Multi-I/O Controller
+
+pci:v00009710d00009845sv00001000sd00000004*
+ ID_PRODUCT_FROM_DATABASE=0P4S (4 port 16550A serial card)
+
+pci:v00009710d00009845sv00001000sd00000006*
+ ID_PRODUCT_FROM_DATABASE=0P6S (6 port 16550a serial card)
+
+pci:v00009710d00009845sv00001000sd00000014*
+ ID_PRODUCT_FROM_DATABASE=1P4S (1 Parallel / 4 16550A Serial Port Adapter)
+
+pci:v00009710d00009855*
+ ID_PRODUCT_FROM_DATABASE=PCI 9855 Multi-I/O Controller
+
+pci:v00009710d00009855sv00001000sd00000014*
+ ID_PRODUCT_FROM_DATABASE=1P4S
+
+pci:v00009710d00009855sv00001000sd00000022*
+ ID_PRODUCT_FROM_DATABASE=2P2S (2 Parallel / 2 16550A Serial Port Adapter)
+
+pci:v00009710d00009865*
+ ID_PRODUCT_FROM_DATABASE=PCI 9865 Multi-I/O Controller
+
+pci:v00009710d00009901*
+ ID_PRODUCT_FROM_DATABASE=PCIe 9901 Multi-I/O Controller
+
+pci:v00009710d00009904*
+ ID_PRODUCT_FROM_DATABASE=4-Port PCIe Serial Adapter
+
+pci:v00009710d00009912*
+ ID_PRODUCT_FROM_DATABASE=PCIe 9912 Multi-I/O Controller
+
+pci:v00009710d00009922*
+ ID_PRODUCT_FROM_DATABASE=PCIe 9922 Multi-I/O Controller
+
+pci:v00009710d00009990*
+ ID_PRODUCT_FROM_DATABASE=MCS9990 PCIe to 4‐Port USB 2.0 Host Controller
+
+pci:v00009902*
+ ID_VENDOR_FROM_DATABASE=Stargen Inc.
+
+pci:v00009902d00000001*
+ ID_PRODUCT_FROM_DATABASE=SG2010 PCI over Starfabric Bridge
+
+pci:v00009902d00000002*
+ ID_PRODUCT_FROM_DATABASE=SG2010 PCI to Starfabric Gateway
+
+pci:v00009902d00000003*
+ ID_PRODUCT_FROM_DATABASE=SG1010 Starfabric Switch and PCI Bridge
+
+pci:v0000A0A0*
+ ID_VENDOR_FROM_DATABASE=AOPEN Inc.
+
+pci:v0000A0F1*
+ ID_VENDOR_FROM_DATABASE=UNISYS Corporation
+
+pci:v0000A200*
+ ID_VENDOR_FROM_DATABASE=NEC Corporation
+
+pci:v0000A259*
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard
+
+pci:v0000A25B*
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard GmbH PL24-MKT
+
+pci:v0000A304*
+ ID_VENDOR_FROM_DATABASE=Sony
+
+pci:v0000A727*
+ ID_VENDOR_FROM_DATABASE=3Com Corporation
+
+pci:v0000A727d00000013*
+ ID_PRODUCT_FROM_DATABASE=3CRPAG175 Wireless PC Card
+
+pci:v0000A727d00006803*
+ ID_PRODUCT_FROM_DATABASE=3CRDAG675B Wireless 11a/b/g Adapter
+
+pci:v0000AA42*
+ ID_VENDOR_FROM_DATABASE=Scitex Digital Video
+
+pci:v0000AA55*
+ ID_VENDOR_FROM_DATABASE=Ncomputing X300 PCI-Engine
+
+pci:v0000AAAA*
+ ID_VENDOR_FROM_DATABASE=Adnaco Technology Inc.
+
+pci:v0000AAAAd00000001*
+ ID_PRODUCT_FROM_DATABASE=H1 PCIe over fiber optic host controller
+
+pci:v0000AAAAd00000002*
+ ID_PRODUCT_FROM_DATABASE=R1BP1 PCIe over fiber optic expansion chassis
+
+pci:v0000ABCD*
+ ID_VENDOR_FROM_DATABASE=Vadatech Inc.
+
+pci:v0000AC1E*
+ ID_VENDOR_FROM_DATABASE=Digital Receiver Technology Inc
+
+pci:v0000AC3D*
+ ID_VENDOR_FROM_DATABASE=Actuality Systems
+
+pci:v0000AD00*
+ ID_VENDOR_FROM_DATABASE=Alta Data Technologies LLC
+
+pci:v0000AECB*
+ ID_VENDOR_FROM_DATABASE=Adrienne Electronics Corporation
+
+pci:v0000AECBd00006250*
+ ID_PRODUCT_FROM_DATABASE=VITC/LTC Timecode Reader card [PCI-VLTC/RDR]
+
+pci:v0000AFFE*
+ ID_VENDOR_FROM_DATABASE=Sirrix AG security technologies
+
+pci:v0000AFFEd000001E1*
+ ID_PRODUCT_FROM_DATABASE=PCI1E1 1-port ISDN E1 interface
+
+pci:v0000AFFEd000002E1*
+ ID_PRODUCT_FROM_DATABASE=PCI2E1 2-port ISDN E1 interface
+
+pci:v0000AFFEd0000450E*
+ ID_PRODUCT_FROM_DATABASE=PCI4S0EC 4-port ISDN S0 interface
+
+pci:v0000AFFEd0000DEAD*
+ ID_PRODUCT_FROM_DATABASE=Sirrix.PCI4S0 4-port ISDN S0 interface
+
+pci:v0000B100*
+ ID_VENDOR_FROM_DATABASE=OpenVox Communication Co. Ltd.
+
+pci:v0000B10B*
+ ID_VENDOR_FROM_DATABASE=Uakron PCI Project
+
+pci:v0000B1B3*
+ ID_VENDOR_FROM_DATABASE=Shiva Europe Limited
+
+pci:v0000B1D9*
+ ID_VENDOR_FROM_DATABASE=ATCOM Technology co., LTD.
+
+pci:v0000BD11*
+ ID_VENDOR_FROM_DATABASE=Pinnacle Systems, Inc. (Wrong ID)
+
+pci:v0000BDBD*
+ ID_VENDOR_FROM_DATABASE=Blackmagic Design
+
+pci:v0000BDBDd0000A11B*
+ ID_PRODUCT_FROM_DATABASE=DeckLink SDI
+
+pci:v0000C001*
+ ID_VENDOR_FROM_DATABASE=TSI Telsys
+
+pci:v0000C0A9*
+ ID_VENDOR_FROM_DATABASE=Micron/Crucial Technology
+
+pci:v0000C0DE*
+ ID_VENDOR_FROM_DATABASE=Motorola
+
+pci:v0000C0FE*
+ ID_VENDOR_FROM_DATABASE=Motion Engineering, Inc.
+
+pci:v0000CA50*
+ ID_VENDOR_FROM_DATABASE=Varian Australia Pty Ltd
+
+pci:v0000CACE*
+ ID_VENDOR_FROM_DATABASE=CACE Technologies, Inc.
+
+pci:v0000CACEd00000001*
+ ID_PRODUCT_FROM_DATABASE=TurboCap Port A
+
+pci:v0000CACEd00000002*
+ ID_PRODUCT_FROM_DATABASE=TurboCap Port B
+
+pci:v0000CACEd00000023*
+ ID_PRODUCT_FROM_DATABASE=AirPcap N
+
+pci:v0000CAFE*
+ ID_VENDOR_FROM_DATABASE=Chrysalis-ITS
+
+pci:v0000CAFEd00000003*
+ ID_PRODUCT_FROM_DATABASE=Luna K3 Hardware Security Module
+
+pci:v0000CAFEd00000006*
+ ID_PRODUCT_FROM_DATABASE=Luna PCI-e 3000 Hardware Security Module
+
+pci:v0000CCCC*
+ ID_VENDOR_FROM_DATABASE=Catapult Communications
+
+pci:v0000CCEC*
+ ID_VENDOR_FROM_DATABASE=Curtiss-Wright Controls Embedded Computing
+
+pci:v0000CDDD*
+ ID_VENDOR_FROM_DATABASE=Tyzx, Inc.
+
+pci:v0000CDDDd00000101*
+ ID_PRODUCT_FROM_DATABASE=DeepSea 1 High Speed Stereo Vision Frame Grabber
+
+pci:v0000CDDDd00000200*
+ ID_PRODUCT_FROM_DATABASE=DeepSea 2 High Speed Stereo Vision Frame Grabber
+
+pci:v0000CEBA*
+ ID_VENDOR_FROM_DATABASE=KEBA AG
+
+pci:v0000D161*
+ ID_VENDOR_FROM_DATABASE=Digium, Inc.
+
+pci:v0000D161d00000120*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE120P single-span T1/E1/J1 card
+
+pci:v0000D161d00000205*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE205P/TE207P dual-span T1/E1/J1 card 5.0V
+
+pci:v0000D161d00000210*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE210P/TE212P dual-span T1/E1/J1 card 3.3V
+
+pci:v0000D161d00000220*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE220 dual-span T1/E1/J1 card 3.3V (PCI-Express)
+
+pci:v0000D161d00000405*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE405P/TE407P quad-span T1/E1/J1 card 5.0V
+
+pci:v0000D161d00000410*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE410P/TE412P quad-span T1/E1/J1 card 3.3V
+
+pci:v0000D161d00000420*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE420P quad-span T1/E1/J1 card 3.3V (PCI-Express)
+
+pci:v0000D161d00000800*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TDM800P 8-port analog card
+
+pci:v0000D161d00001205*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE205P/TE207P dual-span T1/E1/J1 card 5.0V (u1)
+
+pci:v0000D161d00001220*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE220 dual-span T1/E1/J1 card 3.3V (PCI-Express) (5th gen)
+
+pci:v0000D161d00001405*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE405P/TE407P quad-span T1/E1/J1 card 5.0V (u1)
+
+pci:v0000D161d00001420*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE420 quad-span T1/E1/J1 card 3.3V (PCI-Express) (5th gen)
+
+pci:v0000D161d00002400*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TDM2400P 24-port analog card
+
+pci:v0000D161d00003400*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TC400P transcoder base card
+
+pci:v0000D161d00008000*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE121 single-span T1/E1/J1 card (PCI-Express)
+
+pci:v0000D161d00008001*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TE122 single-span T1/E1/J1 card
+
+pci:v0000D161d00008002*
+ ID_PRODUCT_FROM_DATABASE=Wildcard AEX800 8-port analog card (PCI-Express)
+
+pci:v0000D161d00008003*
+ ID_PRODUCT_FROM_DATABASE=Wildcard AEX2400 24-port analog card (PCI-Express)
+
+pci:v0000D161d00008004*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TCE400P transcoder base card
+
+pci:v0000D161d00008005*
+ ID_PRODUCT_FROM_DATABASE=Wildcard TDM410 4-port analog card
+
+pci:v0000D161d00008006*
+ ID_PRODUCT_FROM_DATABASE=Wildcard AEX410 4-port analog card (PCI-Express)
+
+pci:v0000D161d00008007*
+ ID_PRODUCT_FROM_DATABASE=Hx8 Series 8-port Base Card
+
+pci:v0000D161d00008008*
+ ID_PRODUCT_FROM_DATABASE=Hx8 Series 8-port Base Card (PCI-Express)
+
+pci:v0000D161d0000B410*
+ ID_PRODUCT_FROM_DATABASE=Wildcard B410 quad-BRI card
+
+pci:v0000D4D4*
+ ID_VENDOR_FROM_DATABASE=Dy4 Systems Inc
+
+pci:v0000D4D4d00000601*
+ ID_PRODUCT_FROM_DATABASE=PCI Mezzanine Card
+
+pci:v0000D531*
+ ID_VENDOR_FROM_DATABASE=I+ME ACTIA GmbH
+
+pci:v0000D84D*
+ ID_VENDOR_FROM_DATABASE=Exsys
+
+pci:v0000DADA*
+ ID_VENDOR_FROM_DATABASE=Datapath Limited
+
+pci:v0000DB10*
+ ID_VENDOR_FROM_DATABASE=Diablo Technologies
+
+pci:v0000DCBA*
+ ID_VENDOR_FROM_DATABASE=Dynamic Engineering
+
+pci:v0000DCBAd00000046*
+ ID_PRODUCT_FROM_DATABASE=PCIeAlteraCycloneIV
+
+pci:v0000DCBAd00000047*
+ ID_PRODUCT_FROM_DATABASE=VPX-RCB
+
+pci:v0000DCBAd00000048*
+ ID_PRODUCT_FROM_DATABASE=PMC-Biserial-III-BAE9
+
+pci:v0000DD01*
+ ID_VENDOR_FROM_DATABASE=Digital Devices GmbH
+
+pci:v0000DD01d00000003*
+ ID_PRODUCT_FROM_DATABASE=Octopus LE DVB adapter
+
+pci:v0000DEAD*
+ ID_VENDOR_FROM_DATABASE=Indigita Corporation
+
+pci:v0000DEAF*
+ ID_VENDOR_FROM_DATABASE=Middle Digital Inc.
+
+pci:v0000DEAFd00009050*
+ ID_PRODUCT_FROM_DATABASE=PC Weasel Virtual VGA
+
+pci:v0000DEAFd00009051*
+ ID_PRODUCT_FROM_DATABASE=PC Weasel Serial Port
+
+pci:v0000DEAFd00009052*
+ ID_PRODUCT_FROM_DATABASE=PC Weasel Watchdog Timer
+
+pci:v0000DEDA*
+ ID_VENDOR_FROM_DATABASE=SoftHard Technology Ltd.
+
+pci:v0000E000*
+ ID_VENDOR_FROM_DATABASE=Winbond
+
+pci:v0000E000d0000E000*
+ ID_PRODUCT_FROM_DATABASE=W89C940
+
+pci:v0000E159*
+ ID_VENDOR_FROM_DATABASE=Tiger Jet Network Inc.
+
+pci:v0000E159d00000001*
+ ID_PRODUCT_FROM_DATABASE=Tiger3XX Modem/ISDN interface
+
+pci:v0000E159d00000001sv00000059sd00000001*
+ ID_PRODUCT_FROM_DATABASE=128k ISDN-S/T Adapter
+
+pci:v0000E159d00000001sv00000059sd00000003*
+ ID_PRODUCT_FROM_DATABASE=128k ISDN-U Adapter
+
+pci:v0000E159d00000001sv000000A7sd00000001*
+ ID_PRODUCT_FROM_DATABASE=TELES.S0/PCI 2.x ISDN Adapter
+
+pci:v0000E159d00000001sv00008086sd00000003*
+ ID_PRODUCT_FROM_DATABASE=Digium X100P/X101P analogue PSTN FXO interface
+
+pci:v0000E159d00000001sv0000B100sd00000003*
+ ID_PRODUCT_FROM_DATABASE=OpenVox A400P 4-port analog card
+
+pci:v0000E159d00000001sv0000B1D9sd00000003*
+ ID_PRODUCT_FROM_DATABASE=AX400P 4-port analog card
+
+pci:v0000E159d00000002*
+ ID_PRODUCT_FROM_DATABASE=Tiger100APC ISDN chipset
+
+pci:v0000E1C5*
+ ID_VENDOR_FROM_DATABASE=Elcus
+
+pci:v0000E4BF*
+ ID_VENDOR_FROM_DATABASE=EKF Elektronik GmbH
+
+pci:v0000E4BFd00000CCD*
+ ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO
+
+pci:v0000E4BFd00000CD1*
+ ID_PRODUCT_FROM_DATABASE=CD1-OPERA
+
+pci:v0000E4BFd00000CD2*
+ ID_PRODUCT_FROM_DATABASE=CD2-BEBOP
+
+pci:v0000E4BFd00000CD3*
+ ID_PRODUCT_FROM_DATABASE=CD3-JIVE
+
+pci:v0000E4BFd000050C1*
+ ID_PRODUCT_FROM_DATABASE=PC1-GROOVE
+
+pci:v0000E4BFd000050C2*
+ ID_PRODUCT_FROM_DATABASE=PC2-LIMBO
+
+pci:v0000E4BFd000053C1*
+ ID_PRODUCT_FROM_DATABASE=SC1-ALLEGRO
+
+pci:v0000E4BFd0000CC47*
+ ID_PRODUCT_FROM_DATABASE=CCG-RUMBA
+
+pci:v0000E4BFd0000CC4D*
+ ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE
+
+pci:v0000E55E*
+ ID_VENDOR_FROM_DATABASE=Essence Technology, Inc.
+
+pci:v0000EA01*
+ ID_VENDOR_FROM_DATABASE=Eagle Technology
+
+pci:v0000EA01d0000000A*
+ ID_PRODUCT_FROM_DATABASE=PCI-773 Temperature Card
+
+pci:v0000EA01d00000032*
+ ID_PRODUCT_FROM_DATABASE=PCI-730 & PC104P-30 Card
+
+pci:v0000EA01d0000003E*
+ ID_PRODUCT_FROM_DATABASE=PCI-762 Opto-Isolator Card
+
+pci:v0000EA01d00000041*
+ ID_PRODUCT_FROM_DATABASE=PCI-763 Reed Relay Card
+
+pci:v0000EA01d00000043*
+ ID_PRODUCT_FROM_DATABASE=PCI-769 Opto-Isolator Reed Relay Combo Card
+
+pci:v0000EA01d00000046*
+ ID_PRODUCT_FROM_DATABASE=PCI-766 Analog Output Card
+
+pci:v0000EA01d00000052*
+ ID_PRODUCT_FROM_DATABASE=PCI-703 Analog I/O Card
+
+pci:v0000EA01d00000800*
+ ID_PRODUCT_FROM_DATABASE=PCI-800 Digital I/O Card
+
+pci:v0000EA60*
+ ID_VENDOR_FROM_DATABASE=RME
+
+pci:v0000EA60d00009896*
+ ID_PRODUCT_FROM_DATABASE=Digi32
+
+pci:v0000EA60d00009897*
+ ID_PRODUCT_FROM_DATABASE=Digi32 Pro
+
+pci:v0000EA60d00009898*
+ ID_PRODUCT_FROM_DATABASE=Digi32/8
+
+pci:v0000EABB*
+ ID_VENDOR_FROM_DATABASE=Aashima Technology B.V.
+
+pci:v0000EACE*
+ ID_VENDOR_FROM_DATABASE=Endace Measurement Systems, Ltd
+
+pci:v0000EACEd00003100*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.10 OC-3/OC-12
+
+pci:v0000EACEd00003200*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.2x OC-3/OC-12
+
+pci:v0000EACEd0000320E*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.2E Fast Ethernet
+
+pci:v0000EACEd0000340E*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.4E Fast Ethernet
+
+pci:v0000EACEd0000341E*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.41E Fast Ethernet
+
+pci:v0000EACEd00003500*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.5 OC-3/OC-12
+
+pci:v0000EACEd0000351C*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.5ECM Fast Ethernet
+
+pci:v0000EACEd0000360D*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.6D DS3
+
+pci:v0000EACEd0000360E*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.6E Fast Ethernet
+
+pci:v0000EACEd0000368E*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.6E Gig Ethernet
+
+pci:v0000EACEd00003707*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.7T T1/E1/J1
+
+pci:v0000EACEd0000370D*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.7D DS3/E3
+
+pci:v0000EACEd0000378E*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.7G Gig Ethernet
+
+pci:v0000EACEd00003800*
+ ID_PRODUCT_FROM_DATABASE=DAG 3.8S OC-3/OC-12
+
+pci:v0000EACEd00004100*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.10 OC-48
+
+pci:v0000EACEd00004110*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.11 OC-48
+
+pci:v0000EACEd00004220*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.2 OC-48
+
+pci:v0000EACEd0000422E*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.2GE Gig Ethernet
+
+pci:v0000EACEd00004230*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.2S OC-48
+
+pci:v0000EACEd0000423E*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.2GE Gig Ethernet
+
+pci:v0000EACEd00004300*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.3S OC-48
+
+pci:v0000EACEd0000430E*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.3GE Gig Ethernet
+
+pci:v0000EACEd0000452E*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.5G2 Gig Ethernet
+
+pci:v0000EACEd0000454E*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.5G4 Gig Ethernet
+
+pci:v0000EACEd000045B8*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.5Z8 Gig Ethernet
+
+pci:v0000EACEd000045BE*
+ ID_PRODUCT_FROM_DATABASE=DAG 4.5Z2 Gig Ethernet
+
+pci:v0000EACEd0000520E*
+ ID_PRODUCT_FROM_DATABASE=DAG 5.2X 10G Ethernet
+
+pci:v0000EACEd0000521A*
+ ID_PRODUCT_FROM_DATABASE=DAG 5.2SXA 10G Ethernet/OC-192
+
+pci:v0000EACEd00005400*
+ ID_PRODUCT_FROM_DATABASE=DAG 5.4S-12 OC-3/OC-12
+
+pci:v0000EACEd00005401*
+ ID_PRODUCT_FROM_DATABASE=DAG 5.4SG-48 Gig Ethernet/OC-3/OC-12/OC-48
+
+pci:v0000EACEd0000540A*
+ ID_PRODUCT_FROM_DATABASE=DAG 5.4GA Gig Ethernet
+
+pci:v0000EACEd0000541A*
+ ID_PRODUCT_FROM_DATABASE=DAG 5.4SA-12 OC-3/OC-12
+
+pci:v0000EACEd0000542A*
+ ID_PRODUCT_FROM_DATABASE=DAG 5.4SGA-48 Gig Ethernet/OC-3/OC-12/OC-48
+
+pci:v0000EACEd00006000*
+ ID_PRODUCT_FROM_DATABASE=DAG 6.0SE 10G Ethernet/OC-192
+
+pci:v0000EACEd00006100*
+ ID_PRODUCT_FROM_DATABASE=DAG 6.1SE 10G Ethernet/OC-192
+
+pci:v0000EACEd00006200*
+ ID_PRODUCT_FROM_DATABASE=DAG 6.2SE 10G Ethernet/OC-192
+
+pci:v0000EACEd00007100*
+ ID_PRODUCT_FROM_DATABASE=DAG 7.1S OC-3/OC-12
+
+pci:v0000EACEd00007400*
+ ID_PRODUCT_FROM_DATABASE=DAG 7.4S OC-3/OC-12
+
+pci:v0000EACEd00007401*
+ ID_PRODUCT_FROM_DATABASE=DAG 7.4S48 OC-48
+
+pci:v0000EACEd0000752E*
+ ID_PRODUCT_FROM_DATABASE=DAG 7.5G2 Gig Ethernet
+
+pci:v0000EACEd0000754E*
+ ID_PRODUCT_FROM_DATABASE=DAG 7.5G4 Gig Ethernet
+
+pci:v0000EACEd00008100*
+ ID_PRODUCT_FROM_DATABASE=DAG 8.1X 10G Ethernet
+
+pci:v0000EACEd00008101*
+ ID_PRODUCT_FROM_DATABASE=DAG 8.1SX 10G Ethernet/OC-192
+
+pci:v0000EACEd00008102*
+ ID_PRODUCT_FROM_DATABASE=DAG 8.1X 10G Ethernet
+
+pci:v0000EACEd0000820E*
+ ID_PRODUCT_FROM_DATABASE=DAG 8.2X 10G Ethernet
+
+pci:v0000EACEd0000820F*
+ ID_PRODUCT_FROM_DATABASE=DAG 8.2X 10G Ethernet (2nd bus)
+
+pci:v0000EACEd00008400*
+ ID_PRODUCT_FROM_DATABASE=DAG 8.4I Infiniband x4 SDR
+
+pci:v0000EACEd00008500*
+ ID_PRODUCT_FROM_DATABASE=DAG 8.5I Infiniband x4 DDR
+
+pci:v0000EACEd0000920E*
+ ID_PRODUCT_FROM_DATABASE=DAG 9.2X2 10G Ethernet
+
+pci:v0000EC80*
+ ID_VENDOR_FROM_DATABASE=Belkin Corporation
+
+pci:v0000EC80d0000EC00*
+ ID_PRODUCT_FROM_DATABASE=F5D6000
+
+pci:v0000ECC0*
+ ID_VENDOR_FROM_DATABASE=Echo Digital Audio Corporation
+
+pci:v0000EDD8*
+ ID_VENDOR_FROM_DATABASE=ARK Logic Inc
+
+pci:v0000EDD8d0000A091*
+ ID_PRODUCT_FROM_DATABASE=1000PV [Stingray]
+
+pci:v0000EDD8d0000A099*
+ ID_PRODUCT_FROM_DATABASE=2000PV [Stingray]
+
+pci:v0000EDD8d0000A0A1*
+ ID_PRODUCT_FROM_DATABASE=2000MT
+
+pci:v0000EDD8d0000A0A9*
+ ID_PRODUCT_FROM_DATABASE=2000MI
+
+pci:v0000F043*
+ ID_VENDOR_FROM_DATABASE=ASUSTeK Computer Inc. (Wrong ID)
+
+pci:v0000F05B*
+ ID_VENDOR_FROM_DATABASE=Foxconn International, Inc. (Wrong ID)
+
+pci:v0000F1D0*
+ ID_VENDOR_FROM_DATABASE=AJA Video
+
+pci:v0000F1D0d0000C0FE*
+ ID_PRODUCT_FROM_DATABASE=Xena HS/HD-R
+
+pci:v0000F1D0d0000C0FF*
+ ID_PRODUCT_FROM_DATABASE=Kona/Xena 2
+
+pci:v0000F1D0d0000CAFE*
+ ID_PRODUCT_FROM_DATABASE=Kona SD
+
+pci:v0000F1D0d0000CFEE*
+ ID_PRODUCT_FROM_DATABASE=Xena LS/SD-22-DA/SD-DA
+
+pci:v0000F1D0d0000DCAF*
+ ID_PRODUCT_FROM_DATABASE=Kona HD
+
+pci:v0000F1D0d0000DFEE*
+ ID_PRODUCT_FROM_DATABASE=Xena HD-DA
+
+pci:v0000F1D0d0000EFAC*
+ ID_PRODUCT_FROM_DATABASE=Xena SD-MM/SD-22-MM
+
+pci:v0000F1D0d0000FACD*
+ ID_PRODUCT_FROM_DATABASE=Xena HD-MM
+
+pci:v0000F5F5*
+ ID_VENDOR_FROM_DATABASE=F5 Networks, Inc.
+
+pci:v0000F849*
+ ID_VENDOR_FROM_DATABASE=ASRock Incorporation (Wrong ID)
+
+pci:v0000FA57*
+ ID_VENDOR_FROM_DATABASE=Interagon AS
+
+pci:v0000FA57d00000001*
+ ID_PRODUCT_FROM_DATABASE=PMC [Pattern Matching Chip]
+
+pci:v0000FAB7*
+ ID_VENDOR_FROM_DATABASE=Fabric7 Systems, Inc.
+
+pci:v0000FEBD*
+ ID_VENDOR_FROM_DATABASE=Ultraview Corp.
+
+pci:v0000FEDA*
+ ID_VENDOR_FROM_DATABASE=Broadcom Inc
+
+pci:v0000FEDAd0000A0FA*
+ ID_PRODUCT_FROM_DATABASE=BCM4210 iLine10 HomePNA 2.0
+
+pci:v0000FEDAd0000A10E*
+ ID_PRODUCT_FROM_DATABASE=BCM4230 iLine10 HomePNA 2.0
+
+pci:v0000FEDE*
+ ID_VENDOR_FROM_DATABASE=Fedetec Inc.
+
+pci:v0000FEDEd00000003*
+ ID_PRODUCT_FROM_DATABASE=TABIC PCI v3
+
+pci:v0000FFEE*
+ ID_VENDOR_FROM_DATABASE=FNK Tech
+
+pci:v0000FFFD*
+ ID_VENDOR_FROM_DATABASE=XenSource, Inc.
+
+pci:v0000FFFDd00000101*
+ ID_PRODUCT_FROM_DATABASE=PCI Event Channel Controller
+
+pci:v0000FFFE*
+ ID_VENDOR_FROM_DATABASE=VMWare Inc (temporary ID)
+
+pci:v0000FFFEd00000710*
+ ID_PRODUCT_FROM_DATABASE=Virtual SVGA
+
+pci:v0000FFFF*
+ ID_VENDOR_FROM_DATABASE=Illegal Vendor ID
diff --git a/hwdb/20-usb-classes.hwdb b/hwdb/20-usb-classes.hwdb
new file mode 100644 (file)
index 0000000..3294d8a
--- /dev/null
@@ -0,0 +1,339 @@
+# This file is part of systemd.
+#
+# Data imported from: http://www.linux-usb.org/usb.ids
+
+usb:v*p*d*dc01*
+ ID_USB_CLASS_FROM_DATABASE=Audio
+
+usb:v*p*d*dc01dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Control Device
+
+usb:v*p*d*dc01dsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=Streaming
+
+usb:v*p*d*dc01dsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=MIDI Streaming
+
+usb:v*p*d*dc02*
+ ID_USB_CLASS_FROM_DATABASE=Communications
+
+usb:v*p*d*dc02dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Direct Line
+
+usb:v*p*d*dc02dsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=Abstract (modem)
+
+usb:v*p*d*dc02dsc02dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (v.25ter)
+
+usb:v*p*d*dc02dsc02dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (PCCA101)
+
+usb:v*p*d*dc02dsc02dp03*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (PCCA101 + wakeup)
+
+usb:v*p*d*dc02dsc02dp04*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (GSM)
+
+usb:v*p*d*dc02dsc02dp05*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (3G)
+
+usb:v*p*d*dc02dsc02dp06*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (CDMA)
+
+usb:v*p*d*dc02dsc02dpFE*
+ ID_USB_PROTOCOL_FROM_DATABASE=Defined by command set descriptor
+
+usb:v*p*d*dc02dsc02dpFF*
+ ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific (MSFT RNDIS?)
+
+usb:v*p*d*dc02dsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=Telephone
+
+usb:v*p*d*dc02dsc04*
+ ID_USB_SUBCLASS_FROM_DATABASE=Multi-Channel
+
+usb:v*p*d*dc02dsc05*
+ ID_USB_SUBCLASS_FROM_DATABASE=CAPI Control
+
+usb:v*p*d*dc02dsc06*
+ ID_USB_SUBCLASS_FROM_DATABASE=Ethernet Networking
+
+usb:v*p*d*dc02dsc07*
+ ID_USB_SUBCLASS_FROM_DATABASE=ATM Networking
+
+usb:v*p*d*dc02dsc08*
+ ID_USB_SUBCLASS_FROM_DATABASE=Wireless Handset Control
+
+usb:v*p*d*dc02dsc09*
+ ID_USB_SUBCLASS_FROM_DATABASE=Device Management
+
+usb:v*p*d*dc02dsc0A*
+ ID_USB_SUBCLASS_FROM_DATABASE=Mobile Direct Line
+
+usb:v*p*d*dc02dsc0B*
+ ID_USB_SUBCLASS_FROM_DATABASE=OBEX
+
+usb:v*p*d*dc02dsc0C*
+ ID_USB_SUBCLASS_FROM_DATABASE=Ethernet Emulation
+
+usb:v*p*d*dc02dsc0Cdp07*
+ ID_USB_PROTOCOL_FROM_DATABASE=Ethernet Emulation (EEM)
+
+usb:v*p*d*dc03*
+ ID_USB_CLASS_FROM_DATABASE=Human Interface Device
+
+usb:v*p*d*dc03dsc00dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Keyboard
+
+usb:v*p*d*dc03dsc00dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Mouse
+
+usb:v*p*d*dc03dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Boot Interface Subclass
+
+usb:v*p*d*dc03dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Keyboard
+
+usb:v*p*d*dc03dsc01dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Mouse
+
+usb:v*p*d*dc05*
+ ID_USB_CLASS_FROM_DATABASE=Physical Interface Device
+
+usb:v*p*d*dc06*
+ ID_USB_CLASS_FROM_DATABASE=Imaging
+
+usb:v*p*d*dc06dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Still Image Capture
+
+usb:v*p*d*dc06dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Picture Transfer Protocol (PIMA 15470)
+
+usb:v*p*d*dc07*
+ ID_USB_CLASS_FROM_DATABASE=Printer
+
+usb:v*p*d*dc07dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Printer
+
+usb:v*p*d*dc07dsc01dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Reserved/Undefined
+
+usb:v*p*d*dc07dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Unidirectional
+
+usb:v*p*d*dc07dsc01dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bidirectional
+
+usb:v*p*d*dc07dsc01dp03*
+ ID_USB_PROTOCOL_FROM_DATABASE=IEEE 1284.4 compatible bidirectional
+
+usb:v*p*d*dc07dsc01dpFF*
+ ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific
+
+usb:v*p*d*dc08*
+ ID_USB_CLASS_FROM_DATABASE=Mass Storage
+
+usb:v*p*d*dc08dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=RBC (typically Flash)
+
+usb:v*p*d*dc08dsc01dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt
+
+usb:v*p*d*dc08dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk
+
+usb:v*p*d*dc08dsc01dp50*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only
+
+usb:v*p*d*dc08dsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=SFF-8020i, MMC-2 (ATAPI)
+
+usb:v*p*d*dc08dsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=QIC-157
+
+usb:v*p*d*dc08dsc04*
+ ID_USB_SUBCLASS_FROM_DATABASE=Floppy (UFI)
+
+usb:v*p*d*dc08dsc04dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt
+
+usb:v*p*d*dc08dsc04dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk
+
+usb:v*p*d*dc08dsc04dp50*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only
+
+usb:v*p*d*dc08dsc05*
+ ID_USB_SUBCLASS_FROM_DATABASE=SFF-8070i
+
+usb:v*p*d*dc08dsc06*
+ ID_USB_SUBCLASS_FROM_DATABASE=SCSI
+
+usb:v*p*d*dc08dsc06dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt
+
+usb:v*p*d*dc08dsc06dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk
+
+usb:v*p*d*dc08dsc06dp50*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only
+
+usb:v*p*d*dc09*
+ ID_USB_CLASS_FROM_DATABASE=Hub
+
+usb:v*p*d*dc09dsc00dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Full speed (or root) hub
+
+usb:v*p*d*dc09dsc00dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Single TT
+
+usb:v*p*d*dc09dsc00dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=TT per port
+
+usb:v*p*d*dc0A*
+ ID_USB_CLASS_FROM_DATABASE=CDC Data
+
+usb:v*p*d*dc0Adsc00dp30*
+ ID_USB_PROTOCOL_FROM_DATABASE=I.430 ISDN BRI
+
+usb:v*p*d*dc0Adsc00dp31*
+ ID_USB_PROTOCOL_FROM_DATABASE=HDLC
+
+usb:v*p*d*dc0Adsc00dp32*
+ ID_USB_PROTOCOL_FROM_DATABASE=Transparent
+
+usb:v*p*d*dc0Adsc00dp50*
+ ID_USB_PROTOCOL_FROM_DATABASE=Q.921M
+
+usb:v*p*d*dc0Adsc00dp51*
+ ID_USB_PROTOCOL_FROM_DATABASE=Q.921
+
+usb:v*p*d*dc0Adsc00dp52*
+ ID_USB_PROTOCOL_FROM_DATABASE=Q.921TM
+
+usb:v*p*d*dc0Adsc00dp90*
+ ID_USB_PROTOCOL_FROM_DATABASE=V.42bis
+
+usb:v*p*d*dc0Adsc00dp91*
+ ID_USB_PROTOCOL_FROM_DATABASE=Q.932 EuroISDN
+
+usb:v*p*d*dc0Adsc00dp92*
+ ID_USB_PROTOCOL_FROM_DATABASE=V.120 V.24 rate ISDN
+
+usb:v*p*d*dc0Adsc00dp93*
+ ID_USB_PROTOCOL_FROM_DATABASE=CAPI 2.0
+
+usb:v*p*d*dc0Adsc00dpFD*
+ ID_USB_PROTOCOL_FROM_DATABASE=Host Based Driver
+
+usb:v*p*d*dc0Adsc00dpFE*
+ ID_USB_PROTOCOL_FROM_DATABASE=CDC PUF
+
+usb:v*p*d*dc0Adsc00dpFF*
+ ID_USB_PROTOCOL_FROM_DATABASE=Vendor specific
+
+usb:v*p*d*dc0B*
+ ID_USB_CLASS_FROM_DATABASE=Chip/SmartCard
+
+usb:v*p*d*dc0D*
+ ID_USB_CLASS_FROM_DATABASE=Content Security
+
+usb:v*p*d*dc0E*
+ ID_USB_CLASS_FROM_DATABASE=Video
+
+usb:v*p*d*dc0Edsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Video Control
+
+usb:v*p*d*dc0Edsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=Video Streaming
+
+usb:v*p*d*dc0Edsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=Video Interface Collection
+
+usb:v*p*d*dc58*
+ ID_USB_CLASS_FROM_DATABASE=Xbox
+
+usb:v*p*d*dc58dsc42*
+ ID_USB_SUBCLASS_FROM_DATABASE=Controller
+
+usb:v*p*d*dcDC*
+ ID_USB_CLASS_FROM_DATABASE=Diagnostic
+
+usb:v*p*d*dcDCdsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Reprogrammable Diagnostics
+
+usb:v*p*d*dcDCdsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=USB2 Compliance
+
+usb:v*p*d*dcE0*
+ ID_USB_CLASS_FROM_DATABASE=Wireless
+
+usb:v*p*d*dcE0dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Radio Frequency
+
+usb:v*p*d*dcE0dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bluetooth
+
+usb:v*p*d*dcE0dsc01dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Ultra WideBand Radio Control
+
+usb:v*p*d*dcE0dsc01dp03*
+ ID_USB_PROTOCOL_FROM_DATABASE=RNDIS
+
+usb:v*p*d*dcE0dsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=Wireless USB Wire Adapter
+
+usb:v*p*d*dcE0dsc02dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Host Wire Adapter Control/Data Streaming
+
+usb:v*p*d*dcE0dsc02dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Device Wire Adapter Control/Data Streaming
+
+usb:v*p*d*dcE0dsc02dp03*
+ ID_USB_PROTOCOL_FROM_DATABASE=Device Wire Adapter Isochronous Streaming
+
+usb:v*p*d*dcEF*
+ ID_USB_CLASS_FROM_DATABASE=Miscellaneous Device
+
+usb:v*p*d*dcEFdsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Microsoft ActiveSync
+
+usb:v*p*d*dcEFdsc01dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Palm Sync
+
+usb:v*p*d*dcEFdsc02dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Interface Association
+
+usb:v*p*d*dcEFdsc02dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Wire Adapter Multifunction Peripheral
+
+usb:v*p*d*dcEFdsc03dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Cable Based Association
+
+usb:v*p*d*dcFE*
+ ID_USB_CLASS_FROM_DATABASE=Application Specific Interface
+
+usb:v*p*d*dcFEdsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Device Firmware Update
+
+usb:v*p*d*dcFEdsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=IRDA Bridge
+
+usb:v*p*d*dcFEdsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=Test and Measurement
+
+usb:v*p*d*dcFEdsc03dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=TMC
+
+usb:v*p*d*dcFEdsc03dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=USB488
+
+usb:v*p*d*dcFF*
+ ID_USB_CLASS_FROM_DATABASE=Vendor Specific Class
+
+usb:v*p*d*dcFFdscFF*
+ ID_USB_SUBCLASS_FROM_DATABASE=Vendor Specific Subclass
+
+usb:v*p*d*dcFFdscFFdpFF*
+ ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific Protocol
diff --git a/hwdb/20-usb-vendor-product.hwdb b/hwdb/20-usb-vendor-product.hwdb
new file mode 100644 (file)
index 0000000..a9b5a7e
--- /dev/null
@@ -0,0 +1,48138 @@
+# This file is part of systemd.
+#
+# Data imported from: http://www.linux-usb.org/usb.ids
+
+usb:v0001*
+ ID_VENDOR_FROM_DATABASE=Fry's Electronics
+
+usb:v0001p142B*
+ ID_PRODUCT_FROM_DATABASE=Arbiter Systems, Inc.
+
+usb:v0001p7778*
+ ID_PRODUCT_FROM_DATABASE=Counterfeit flash drive [Kingston]
+
+usb:v0002*
+ ID_VENDOR_FROM_DATABASE=Ingram
+
+usb:v0003*
+ ID_VENDOR_FROM_DATABASE=Club Mac
+
+usb:v0004*
+ ID_VENDOR_FROM_DATABASE=Nebraska Furniture Mart
+
+usb:v0053*
+ ID_VENDOR_FROM_DATABASE=Planex
+
+usb:v0053p5301*
+ ID_PRODUCT_FROM_DATABASE=GW-US54ZGL 802.11bg
+
+usb:v0079*
+ ID_VENDOR_FROM_DATABASE=DragonRise Inc.
+
+usb:v0079p0006*
+ ID_PRODUCT_FROM_DATABASE=Generic USB Joystick
+
+usb:v0079p0011*
+ ID_PRODUCT_FROM_DATABASE=Gamepad
+
+usb:v0105*
+ ID_VENDOR_FROM_DATABASE=Trust International B.V.
+
+usb:v0105p145F*
+ ID_PRODUCT_FROM_DATABASE=NW-3100 802.11b/g 54Mbps Wireless Network Adapter [zd1211]
+
+usb:v0145*
+ ID_VENDOR_FROM_DATABASE=Unknown
+
+usb:v0145p0112*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v0204*
+ ID_VENDOR_FROM_DATABASE=Chipsbank Microelectronics Co., Ltd
+
+usb:v0204p6025*
+ ID_PRODUCT_FROM_DATABASE=CBM2080 Flash drive controller
+
+usb:v0204p6026*
+ ID_PRODUCT_FROM_DATABASE=CBM1180 Flash drive controller
+
+usb:v0218*
+ ID_VENDOR_FROM_DATABASE=Hangzhou Worlde
+
+usb:v0218p0301*
+ ID_PRODUCT_FROM_DATABASE=MIDI Port
+
+usb:v02AD*
+ ID_VENDOR_FROM_DATABASE=HUMAX Co., Ltd.
+
+usb:v02ADp138C*
+ ID_PRODUCT_FROM_DATABASE=PVR Mass Storage
+
+usb:v0300*
+ ID_VENDOR_FROM_DATABASE=MM300 eBook Reader
+
+usb:v0324*
+ ID_VENDOR_FROM_DATABASE=OCZ Technology Inc
+
+usb:v0324pBC06*
+ ID_PRODUCT_FROM_DATABASE=OCZ ATV USB 2.0 Flash Drive
+
+usb:v0324pBC08*
+ ID_PRODUCT_FROM_DATABASE=OCZ Rally2/ATV USB 2.0 Flash Drive
+
+usb:v0325*
+ ID_VENDOR_FROM_DATABASE=OCZ Technology Inc
+
+usb:v0325pAC02*
+ ID_PRODUCT_FROM_DATABASE=ATV Turbo / Rally2 Dual Channel USB 2.0 Flash Drive
+
+usb:v0386*
+ ID_VENDOR_FROM_DATABASE=LTS
+
+usb:v0386p0001*
+ ID_PRODUCT_FROM_DATABASE=PSX for USB Converter
+
+usb:v03DA*
+ ID_VENDOR_FROM_DATABASE=Bernd Walter Computer Technology
+
+usb:v03DAp0002*
+ ID_PRODUCT_FROM_DATABASE=HD44780 LCD interface
+
+usb:v03E8*
+ ID_VENDOR_FROM_DATABASE=EndPoints, Inc.
+
+usb:v03E8p0004*
+ ID_PRODUCT_FROM_DATABASE=SE401 Webcam
+
+usb:v03E8p0008*
+ ID_PRODUCT_FROM_DATABASE=101 Ethernet [klsi]
+
+usb:v03E8p0015*
+ ID_PRODUCT_FROM_DATABASE=ATAPI Enclosure
+
+usb:v03E8p2123*
+ ID_PRODUCT_FROM_DATABASE=SiPix StyleCam Deluxe
+
+usb:v03E8p8004*
+ ID_PRODUCT_FROM_DATABASE=Aox 99001
+
+usb:v03E9*
+ ID_VENDOR_FROM_DATABASE=Thesys Microelectronics
+
+usb:v03EA*
+ ID_VENDOR_FROM_DATABASE=Data Broadcasting Corp.
+
+usb:v03EB*
+ ID_VENDOR_FROM_DATABASE=Atmel Corp.
+
+usb:v03EBp0902*
+ ID_PRODUCT_FROM_DATABASE=4-Port Hub
+
+usb:v03EBp2002*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v03EBp2015*
+ ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (HID keyboard)
+
+usb:v03EBp2018*
+ ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (CDC ACM)
+
+usb:v03EBp2019*
+ ID_PRODUCT_FROM_DATABASE=stk525 sample firmware (microphone)
+
+usb:v03EBp201C*
+ ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (HID mouse)
+
+usb:v03EBp201D*
+ ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (HID generic)
+
+usb:v03EBp2022*
+ ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (composite device)
+
+usb:v03EBp2040*
+ ID_PRODUCT_FROM_DATABASE=LUFA Test PID
+
+usb:v03EBp2041*
+ ID_PRODUCT_FROM_DATABASE=LUFA Mouse Demo Application
+
+usb:v03EBp2042*
+ ID_PRODUCT_FROM_DATABASE=LUFA Keyboard Demo Application
+
+usb:v03EBp2043*
+ ID_PRODUCT_FROM_DATABASE=LUFA Joystick Demo Application
+
+usb:v03EBp2044*
+ ID_PRODUCT_FROM_DATABASE=LUFA CDC Demo Application
+
+usb:v03EBp2045*
+ ID_PRODUCT_FROM_DATABASE=LUFA Mass Storage Demo Application
+
+usb:v03EBp2046*
+ ID_PRODUCT_FROM_DATABASE=LUFA Audio Output Demo Application
+
+usb:v03EBp2047*
+ ID_PRODUCT_FROM_DATABASE=LUFA Audio Input Demo Application
+
+usb:v03EBp2048*
+ ID_PRODUCT_FROM_DATABASE=LUFA MIDI Demo Application
+
+usb:v03EBp2049*
+ ID_PRODUCT_FROM_DATABASE=Stripe Snoop Magnetic Stripe Reader
+
+usb:v03EBp204A*
+ ID_PRODUCT_FROM_DATABASE=LUFA CDC Class Bootloader
+
+usb:v03EBp204B*
+ ID_PRODUCT_FROM_DATABASE=LUFA USB to Serial Adapter Project
+
+usb:v03EBp204C*
+ ID_PRODUCT_FROM_DATABASE=LUFA RNDIS Demo Application
+
+usb:v03EBp204D*
+ ID_PRODUCT_FROM_DATABASE=LUFA Combined Mouse and Keyboard Demo Application
+
+usb:v03EBp204E*
+ ID_PRODUCT_FROM_DATABASE=LUFA Dual CDC Demo Application
+
+usb:v03EBp204F*
+ ID_PRODUCT_FROM_DATABASE=LUFA Generic HID Demo Application
+
+usb:v03EBp2060*
+ ID_PRODUCT_FROM_DATABASE=Benito Programmer Project
+
+usb:v03EBp2061*
+ ID_PRODUCT_FROM_DATABASE=LUFA Combined Mass Storage and Keyboard Demo Application
+
+usb:v03EBp2062*
+ ID_PRODUCT_FROM_DATABASE=LUFA Combined CDC and Mouse Demo Application
+
+usb:v03EBp2063*
+ ID_PRODUCT_FROM_DATABASE=LUFA Datalogger Device
+
+usb:v03EBp2064*
+ ID_PRODUCT_FROM_DATABASE=Interfaceless Control-Only LUFA Devices
+
+usb:v03EBp2065*
+ ID_PRODUCT_FROM_DATABASE=LUFA Test and Measurement Demo Application
+
+usb:v03EBp2066*
+ ID_PRODUCT_FROM_DATABASE=LUFA Multiple Report HID Demo
+
+usb:v03EBp2068*
+ ID_PRODUCT_FROM_DATABASE=LUFA Virtual Serial/Mass Storage Demo
+
+usb:v03EBp2069*
+ ID_PRODUCT_FROM_DATABASE=LUFA Webserver Project
+
+usb:v03EBp2103*
+ ID_PRODUCT_FROM_DATABASE=JTAG ICE mkII
+
+usb:v03EBp2104*
+ ID_PRODUCT_FROM_DATABASE=AVR ISP mkII
+
+usb:v03EBp2105*
+ ID_PRODUCT_FROM_DATABASE=AVRONE!
+
+usb:v03EBp2106*
+ ID_PRODUCT_FROM_DATABASE=STK600 development board
+
+usb:v03EBp2107*
+ ID_PRODUCT_FROM_DATABASE=AVR Dragon
+
+usb:v03EBp2109*
+ ID_PRODUCT_FROM_DATABASE=STK541 ZigBee Development Board
+
+usb:v03EBp210D*
+ ID_PRODUCT_FROM_DATABASE=XPLAIN evaluation kit (CDC ACM)
+
+usb:v03EBp2122*
+ ID_PRODUCT_FROM_DATABASE=XMEGA-A1 Explained evaluation kit
+
+usb:v03EBp2310*
+ ID_PRODUCT_FROM_DATABASE=EVK11xx evaluation board
+
+usb:v03EBp2FE4*
+ ID_PRODUCT_FROM_DATABASE=ATxmega32A4U DFU bootloader
+
+usb:v03EBp2FFB*
+ ID_PRODUCT_FROM_DATABASE=at90usb AVR DFU bootloader
+
+usb:v03EBp2FFD*
+ ID_PRODUCT_FROM_DATABASE=at89c5130/c5131 DFU bootloader
+
+usb:v03EBp2FFF*
+ ID_PRODUCT_FROM_DATABASE=at89c5132/c51snd1c DFU bootloader
+
+usb:v03EBp3301*
+ ID_PRODUCT_FROM_DATABASE=at43301 4-Port Hub
+
+usb:v03EBp3312*
+ ID_PRODUCT_FROM_DATABASE=4-Port Hub
+
+usb:v03EBp4102*
+ ID_PRODUCT_FROM_DATABASE=AirVast W-Buddie WN210
+
+usb:v03EBp5601*
+ ID_PRODUCT_FROM_DATABASE=at76c510 Prism-II 802.11b Access Point
+
+usb:v03EBp5603*
+ ID_PRODUCT_FROM_DATABASE=Cisco 7920 WiFi IP Phone
+
+usb:v03EBp6119*
+ ID_PRODUCT_FROM_DATABASE=AT91SAM CDC Demo Application
+
+usb:v03EBp6124*
+ ID_PRODUCT_FROM_DATABASE=at91sam SAMBA bootloader
+
+usb:v03EBp6127*
+ ID_PRODUCT_FROM_DATABASE=AT91SAM HID Keyboard Demo Application
+
+usb:v03EBp6129*
+ ID_PRODUCT_FROM_DATABASE=AT91SAM Mass Storage Demo Application
+
+usb:v03EBp6200*
+ ID_PRODUCT_FROM_DATABASE=AT91SAM HID Mouse Demo Application
+
+usb:v03EBp7603*
+ ID_PRODUCT_FROM_DATABASE=D-Link DWL-120 802.11b Wireless Adapter [Atmel at76c503a]
+
+usb:v03EBp7604*
+ ID_PRODUCT_FROM_DATABASE=at76c503a 802.11b Adapter
+
+usb:v03EBp7605*
+ ID_PRODUCT_FROM_DATABASE=at76c503a 802.11b Adapter
+
+usb:v03EBp7606*
+ ID_PRODUCT_FROM_DATABASE=at76c505 802.11b Adapter
+
+usb:v03EBp7611*
+ ID_PRODUCT_FROM_DATABASE=at76c510 rfmd2948 802.11b Access Point
+
+usb:v03EBp7613*
+ ID_PRODUCT_FROM_DATABASE=WL-1130 USB
+
+usb:v03EBp7614*
+ ID_PRODUCT_FROM_DATABASE=AT76c505a Wireless Adapter
+
+usb:v03EBp7615*
+ ID_PRODUCT_FROM_DATABASE=AT76C505AMX Wireless Adapter
+
+usb:v03EBp7617*
+ ID_PRODUCT_FROM_DATABASE=AT76C505AS Wireless Adapter
+
+usb:v03EBp7800*
+ ID_PRODUCT_FROM_DATABASE=Mini Album
+
+usb:v03EBpFF07*
+ ID_PRODUCT_FROM_DATABASE=Tux Droid fish dongle
+
+usb:v03EC*
+ ID_VENDOR_FROM_DATABASE=Iwatsu America, Inc.
+
+usb:v03ED*
+ ID_VENDOR_FROM_DATABASE=Mitel Corp.
+
+usb:v03EE*
+ ID_VENDOR_FROM_DATABASE=Mitsumi
+
+usb:v03EEp0000*
+ ID_PRODUCT_FROM_DATABASE=CD-R/RW Drive
+
+usb:v03EEp2501*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v03EEp2502*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v03EEp5609*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard
+
+usb:v03EEp641F*
+ ID_PRODUCT_FROM_DATABASE=WIF-0402C Bluetooth Adapter
+
+usb:v03EEp6438*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v03EEp6440*
+ ID_PRODUCT_FROM_DATABASE=WML-C52APR Bluetooth Adapter
+
+usb:v03EEp6901*
+ ID_PRODUCT_FROM_DATABASE=SmartDisk FDD
+
+usb:v03EEp6902*
+ ID_PRODUCT_FROM_DATABASE=Floppy Disk Drive
+
+usb:v03EEp7500*
+ ID_PRODUCT_FROM_DATABASE=CD-R/RW
+
+usb:v03EEpFFFF*
+ ID_PRODUCT_FROM_DATABASE=Dongle with BlueCore in DFU mode
+
+usb:v03F0*
+ ID_VENDOR_FROM_DATABASE=Hewlett-Packard
+
+usb:v03F0p0004*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 895c
+
+usb:v03F0p0011*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet G55
+
+usb:v03F0p0012*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 1125C Printer Port
+
+usb:v03F0p0024*
+ ID_PRODUCT_FROM_DATABASE=KU-0316 Keyboard
+
+usb:v03F0p002A*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P1102
+
+usb:v03F0p0101*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4100c
+
+usb:v03F0p0102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart S20
+
+usb:v03F0p0104*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 880c/970c
+
+usb:v03F0p0105*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4200c
+
+usb:v03F0p0107*
+ ID_PRODUCT_FROM_DATABASE=CD-Writer Plus
+
+usb:v03F0p010C*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard Hub
+
+usb:v03F0p0111*
+ ID_PRODUCT_FROM_DATABASE=G55xi Printer/Scanner/Copier
+
+usb:v03F0p0117*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3200
+
+usb:v03F0p011C*
+ ID_PRODUCT_FROM_DATABASE=hn210w 802.11b Adapter
+
+usb:v03F0p011D*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 1.2 Interface [Broadcom BCM2035]
+
+usb:v03F0p0121*
+ ID_PRODUCT_FROM_DATABASE=HP49g+ Calculator
+
+usb:v03F0p0122*
+ ID_PRODUCT_FROM_DATABASE=HID Internet Keyboard
+
+usb:v03F0p0201*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 6200c
+
+usb:v03F0p0202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart S20
+
+usb:v03F0p0204*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 815c
+
+usb:v03F0p0205*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 3300c
+
+usb:v03F0p0207*
+ ID_PRODUCT_FROM_DATABASE=CD-Writer Plus 8200e
+
+usb:v03F0p020C*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard
+
+usb:v03F0p0211*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet G85
+
+usb:v03F0p0212*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 1220C
+
+usb:v03F0p0217*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 2200
+
+usb:v03F0p0218*
+ ID_PRODUCT_FROM_DATABASE=APOLLO P2500/2600
+
+usb:v03F0p0304*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 810c/812c
+
+usb:v03F0p0305*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4300c
+
+usb:v03F0p0307*
+ ID_PRODUCT_FROM_DATABASE=CD-Writer+ CD-4e
+
+usb:v03F0p0311*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet G85xi
+
+usb:v03F0p0312*
+ ID_PRODUCT_FROM_DATABASE=Color Inkjet CP1700
+
+usb:v03F0p0314*
+ ID_PRODUCT_FROM_DATABASE=designjet 30/130 series
+
+usb:v03F0p0317*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1200
+
+usb:v03F0p0324*
+ ID_PRODUCT_FROM_DATABASE=SK-2885 keyboard
+
+usb:v03F0p0401*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 5200c
+
+usb:v03F0p0404*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 830c/832c
+
+usb:v03F0p0405*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 3400cse
+
+usb:v03F0p0411*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet G95
+
+usb:v03F0p0412*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p0417*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1200 series
+
+usb:v03F0p0423*
+ ID_PRODUCT_FROM_DATABASE=HS-COMBO Cardreader
+
+usb:v03F0p0504*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 885c
+
+usb:v03F0p0505*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 2100c
+
+usb:v03F0p0507*
+ ID_PRODUCT_FROM_DATABASE=DVD+RW
+
+usb:v03F0p050C*
+ ID_PRODUCT_FROM_DATABASE=5219 Wireless Keyboard
+
+usb:v03F0p0511*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet K60
+
+usb:v03F0p0512*
+ ID_PRODUCT_FROM_DATABASE=DeckJet 450
+
+usb:v03F0p0517*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1000
+
+usb:v03F0p051D*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Interface
+
+usb:v03F0p0601*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 6300c
+
+usb:v03F0p0604*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 840c
+
+usb:v03F0p0605*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 2200c
+
+usb:v03F0p0611*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet K60xi
+
+usb:v03F0p0612*
+ ID_PRODUCT_FROM_DATABASE=business inkjet 3000
+
+usb:v03F0p0624*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v03F0p0701*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 5300c/5370c
+
+usb:v03F0p0704*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 825c
+
+usb:v03F0p0705*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4400c
+
+usb:v03F0p0711*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet K80
+
+usb:v03F0p0712*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 1180c
+
+usb:v03F0p0714*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p0801*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 7400c
+
+usb:v03F0p0804*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 816c
+
+usb:v03F0p0805*
+ ID_PRODUCT_FROM_DATABASE=HP4470C
+
+usb:v03F0p0811*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet K80xi
+
+usb:v03F0p0817*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3300
+
+usb:v03F0p0901*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 2300c
+
+usb:v03F0p0904*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 845c
+
+usb:v03F0p0912*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p0917*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3330
+
+usb:v03F0p0924*
+ ID_PRODUCT_FROM_DATABASE=Modular Smartcard Keyboard
+
+usb:v03F0p0A01*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 2400c
+
+usb:v03F0p0A17*
+ ID_PRODUCT_FROM_DATABASE=color LaserJet 3700
+
+usb:v03F0p0B01*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 82x0C
+
+usb:v03F0p0B0C*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Optical Mouse receiver
+
+usb:v03F0p0B17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 2300d
+
+usb:v03F0p0C17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1010
+
+usb:v03F0p0C24*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v03F0p0D12*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 9100 series
+
+usb:v03F0p0D17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1012
+
+usb:v03F0p0E17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1015
+
+usb:v03F0p0F0C*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Optical Mouse receiver
+
+usb:v03F0p0F11*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet V40
+
+usb:v03F0p0F12*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p0F17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1150
+
+usb:v03F0p1001*
+ ID_PRODUCT_FROM_DATABASE=Photo Scanner 1000
+
+usb:v03F0p1002*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 140 series
+
+usb:v03F0p1004*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 970c/970cse
+
+usb:v03F0p1005*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 5400c
+
+usb:v03F0p1011*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet V40xi
+
+usb:v03F0p1016*
+ ID_PRODUCT_FROM_DATABASE=Jornada 548 / iPAQ HW6515 Pocket PC
+
+usb:v03F0p1017*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1300
+
+usb:v03F0p1024*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Keyboard
+
+usb:v03F0p1027*
+ ID_PRODUCT_FROM_DATABASE=Virtual keyboard and mouse
+
+usb:v03F0p1102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 240 series
+
+usb:v03F0p1104*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 959c
+
+usb:v03F0p1105*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 5470c/5490c
+
+usb:v03F0p1111*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet v60
+
+usb:v03F0p1116*
+ ID_PRODUCT_FROM_DATABASE=Jornada 568 Pocket PC
+
+usb:v03F0p1117*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1300n
+
+usb:v03F0p1151*
+ ID_PRODUCT_FROM_DATABASE=PSC-750xi Printer/Scanner/Copier
+
+usb:v03F0p1202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 320 series
+
+usb:v03F0p1204*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 930c
+
+usb:v03F0p1205*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4500C/5550C
+
+usb:v03F0p1211*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet v60xi
+
+usb:v03F0p1217*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 2300L
+
+usb:v03F0p1302*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 370 series
+
+usb:v03F0p1305*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4570c
+
+usb:v03F0p1311*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet V30
+
+usb:v03F0p1312*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 460
+
+usb:v03F0p1317*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1005
+
+usb:v03F0p1327*
+ ID_PRODUCT_FROM_DATABASE=iLO Virtual Hub
+
+usb:v03F0p1405*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 3670
+
+usb:v03F0p1411*
+ ID_PRODUCT_FROM_DATABASE=PSC 750
+
+usb:v03F0p1424*
+ ID_PRODUCT_FROM_DATABASE=f2105 Monitor Hub
+
+usb:v03F0p1502*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 420 series
+
+usb:v03F0p1504*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 920c
+
+usb:v03F0p150C*
+ ID_PRODUCT_FROM_DATABASE=Mood Lighting (Microchip Technology Inc.)
+
+usb:v03F0p1511*
+ ID_PRODUCT_FROM_DATABASE=PSC 750xi
+
+usb:v03F0p1512*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p1517*
+ ID_PRODUCT_FROM_DATABASE=color LaserJet 3500
+
+usb:v03F0p1524*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Keyboard - KR
+
+usb:v03F0p1602*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 330 series
+
+usb:v03F0p1604*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 940c
+
+usb:v03F0p1605*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 5530C PhotoSmart
+
+usb:v03F0p1611*
+ ID_PRODUCT_FROM_DATABASE=psc 780
+
+usb:v03F0p1617*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3015
+
+usb:v03F0p161D*
+ ID_PRODUCT_FROM_DATABASE=Wireless Rechargeable Optical Mouse (HID)
+
+usb:v03F0p1624*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Keyboard - JP
+
+usb:v03F0p1702*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 380 series
+
+usb:v03F0p1704*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 948C
+
+usb:v03F0p1705*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 5590
+
+usb:v03F0p1711*
+ ID_PRODUCT_FROM_DATABASE=psc 780xi
+
+usb:v03F0p1712*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p1717*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3020
+
+usb:v03F0p171D*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Interface [Broadcom BCM2045]
+
+usb:v03F0p1801*
+ ID_PRODUCT_FROM_DATABASE=Inkjet P-2000U
+
+usb:v03F0p1802*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 470 series
+
+usb:v03F0p1804*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 916C
+
+usb:v03F0p1805*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 7650
+
+usb:v03F0p1811*
+ ID_PRODUCT_FROM_DATABASE=PSC 720
+
+usb:v03F0p1812*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet Pro K550
+
+usb:v03F0p1817*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3030
+
+usb:v03F0p181D*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Interface
+
+usb:v03F0p1902*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A430 series
+
+usb:v03F0p1904*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 3820
+
+usb:v03F0p1911*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet V45
+
+usb:v03F0p1917*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3380
+
+usb:v03F0p1A02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A510 series
+
+usb:v03F0p1A11*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 5100 series
+
+usb:v03F0p1A17*
+ ID_PRODUCT_FROM_DATABASE=color LaserJet 4650
+
+usb:v03F0p1B02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A610 series
+
+usb:v03F0p1B04*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 3810
+
+usb:v03F0p1B05*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4850C/4890C
+
+usb:v03F0p1B07*
+ ID_PRODUCT_FROM_DATABASE=Premium Starter Webcam
+
+usb:v03F0p1C02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A710 series
+
+usb:v03F0p1C17*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 2550l
+
+usb:v03F0p1D02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A310 series
+
+usb:v03F0p1D17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1320
+
+usb:v03F0p1E02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A320 Printer series
+
+usb:v03F0p1E11*
+ ID_PRODUCT_FROM_DATABASE=PSC-950
+
+usb:v03F0p1E17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1160 series
+
+usb:v03F0p1F02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A440 Printer series
+
+usb:v03F0p1F11*
+ ID_PRODUCT_FROM_DATABASE=PSC 920
+
+usb:v03F0p1F12*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet Pro K5300
+
+usb:v03F0p1F17*
+ ID_PRODUCT_FROM_DATABASE=color LaserJet 5550
+
+usb:v03F0p1F1D*
+ ID_PRODUCT_FROM_DATABASE=un2400 Gobi Wireless Modem
+
+usb:v03F0p2001*
+ ID_PRODUCT_FROM_DATABASE=Floppy
+
+usb:v03F0p2002*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v03F0p2004*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 640c
+
+usb:v03F0p2005*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 3570c
+
+usb:v03F0p2012*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet Pro K5400
+
+usb:v03F0p201D*
+ ID_PRODUCT_FROM_DATABASE=un2400 Gobi Wireless Modem (QDL mode)
+
+usb:v03F0p2102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7345
+
+usb:v03F0p2104*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 630c
+
+usb:v03F0p2112*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet Pro L7500
+
+usb:v03F0p211D*
+ ID_PRODUCT_FROM_DATABASE=Sierra MC5725 [ev2210]
+
+usb:v03F0p2202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7600 series
+
+usb:v03F0p2205*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 3500c
+
+usb:v03F0p2212*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet Pro L7600
+
+usb:v03F0p2217*
+ ID_PRODUCT_FROM_DATABASE=color LaserJet 9500 MFP
+
+usb:v03F0p2302*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7600 series
+
+usb:v03F0p2304*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 656c
+
+usb:v03F0p2305*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 3970c
+
+usb:v03F0p2311*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet d series
+
+usb:v03F0p2312*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet Pro L7700
+
+usb:v03F0p2317*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 4350
+
+usb:v03F0p231D*
+ ID_PRODUCT_FROM_DATABASE=4 GB Flash Drive
+
+usb:v03F0p2402*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7700 series
+
+usb:v03F0p2404*
+ ID_PRODUCT_FROM_DATABASE=Deskjet F2280 series
+
+usb:v03F0p2405*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4070 PhotoSmart
+
+usb:v03F0p2417*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 4250
+
+usb:v03F0p241D*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v03F0p2424*
+ ID_PRODUCT_FROM_DATABASE=LP1965 19" Monitor Hub
+
+usb:v03F0p2502*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7700 series
+
+usb:v03F0p2504*
+ ID_PRODUCT_FROM_DATABASE=DeskJet F4200 series
+
+usb:v03F0p2505*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 3770
+
+usb:v03F0p2512*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet Pro L7300
+
+usb:v03F0p2517*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 2410
+
+usb:v03F0p251D*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v03F0p2524*
+ ID_PRODUCT_FROM_DATABASE=LP3065 30" Monitor Hub
+
+usb:v03F0p2602*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A520 series
+
+usb:v03F0p2605*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 3800c
+
+usb:v03F0p2611*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 7100 series
+
+usb:v03F0p2617*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 2820 series
+
+usb:v03F0p2624*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (HP522 2 x 20 Line Display)
+
+usb:v03F0p2702*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A620 series
+
+usb:v03F0p2704*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 915
+
+usb:v03F0p2717*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 2830
+
+usb:v03F0p2811*
+ ID_PRODUCT_FROM_DATABASE=PSC-2100
+
+usb:v03F0p2817*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 2840
+
+usb:v03F0p2902*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart A820 series
+
+usb:v03F0p2911*
+ ID_PRODUCT_FROM_DATABASE=PSC 2200
+
+usb:v03F0p2917*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 2420
+
+usb:v03F0p2A11*
+ ID_PRODUCT_FROM_DATABASE=PSC 2150 series
+
+usb:v03F0p2A17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 2430
+
+usb:v03F0p2B11*
+ ID_PRODUCT_FROM_DATABASE=PSC 2170 series
+
+usb:v03F0p2B17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1020
+
+usb:v03F0p2C12*
+ ID_PRODUCT_FROM_DATABASE=Officejet J4680
+
+usb:v03F0p2C17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1022
+
+usb:v03F0p2C24*
+ ID_PRODUCT_FROM_DATABASE=Logitech M-UAL-96 Mouse
+
+usb:v03F0p2D05*
+ ID_PRODUCT_FROM_DATABASE=Scanjet 7000
+
+usb:v03F0p2D11*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 6110
+
+usb:v03F0p2D17*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p2E11*
+ ID_PRODUCT_FROM_DATABASE=PSC 1000
+
+usb:v03F0p2E17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 2600n
+
+usb:v03F0p2E24*
+ ID_PRODUCT_FROM_DATABASE=LP2275w Monitor Hub
+
+usb:v03F0p2F11*
+ ID_PRODUCT_FROM_DATABASE=PSC 1200
+
+usb:v03F0p2F17*
+ ID_PRODUCT_FROM_DATABASE=EWS 2605dn
+
+usb:v03F0p2F24*
+ ID_PRODUCT_FROM_DATABASE=LP2475w Monitor Hub
+
+usb:v03F0p3002*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart P1000
+
+usb:v03F0p3004*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 980c
+
+usb:v03F0p3005*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4670v
+
+usb:v03F0p3011*
+ ID_PRODUCT_FROM_DATABASE=PSC 1100 series
+
+usb:v03F0p3017*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p3102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart P1100 Printer w/ Card Reader
+
+usb:v03F0p3104*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 960c
+
+usb:v03F0p3111*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 4100 series
+
+usb:v03F0p3117*
+ ID_PRODUCT_FROM_DATABASE=EWS 2605dtn
+
+usb:v03F0p311D*
+ ID_PRODUCT_FROM_DATABASE=Atheros AR9285 Malbec Bluetooth Adapter
+
+usb:v03F0p3202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 1215
+
+usb:v03F0p3207*
+ ID_PRODUCT_FROM_DATABASE=4 GB flash drive
+
+usb:v03F0p3211*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 4105 series
+
+usb:v03F0p3217*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3050
+
+usb:v03F0p3302*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 1218
+
+usb:v03F0p3304*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 990c
+
+usb:v03F0p3312*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet J6410
+
+usb:v03F0p3317*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3052
+
+usb:v03F0p3402*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 1115
+
+usb:v03F0p3404*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 6122
+
+usb:v03F0p3417*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3055
+
+usb:v03F0p3502*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 230
+
+usb:v03F0p3504*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 6127c
+
+usb:v03F0p3511*
+ ID_PRODUCT_FROM_DATABASE=PSC 2300
+
+usb:v03F0p3517*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 3390
+
+usb:v03F0p3602*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 1315
+
+usb:v03F0p3611*
+ ID_PRODUCT_FROM_DATABASE=PSC 2410 PhotoSmart
+
+usb:v03F0p3617*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 2605
+
+usb:v03F0p3711*
+ ID_PRODUCT_FROM_DATABASE=PSC 2500
+
+usb:v03F0p3717*
+ ID_PRODUCT_FROM_DATABASE=EWS UPD
+
+usb:v03F0p3724*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v03F0p3802*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 100
+
+usb:v03F0p3807*
+ ID_PRODUCT_FROM_DATABASE=c485w Flash Drive
+
+usb:v03F0p3817*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P2015 series
+
+usb:v03F0p3902*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 130
+
+usb:v03F0p3A02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7150
+
+usb:v03F0p3A11*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 5500 series
+
+usb:v03F0p3A17*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p3B02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7150~
+
+usb:v03F0p3B11*
+ ID_PRODUCT_FROM_DATABASE=PSC 1300 series
+
+usb:v03F0p3B17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M1005 MFP
+
+usb:v03F0p3C02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7350
+
+usb:v03F0p3C11*
+ ID_PRODUCT_FROM_DATABASE=PSC 1358
+
+usb:v03F0p3C17*
+ ID_PRODUCT_FROM_DATABASE=EWS UPD
+
+usb:v03F0p3D02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7350~
+
+usb:v03F0p3D11*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 4215
+
+usb:v03F0p3D17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P1005
+
+usb:v03F0p3E02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7550
+
+usb:v03F0p3E17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P1006
+
+usb:v03F0p3F02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7550~
+
+usb:v03F0p3F11*
+ ID_PRODUCT_FROM_DATABASE=PSC-1315/PSC-1317
+
+usb:v03F0p4002*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 635/715/720/735/935 (storage)
+
+usb:v03F0p4004*
+ ID_PRODUCT_FROM_DATABASE=cp1160
+
+usb:v03F0p4102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 618
+
+usb:v03F0p4105*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4370
+
+usb:v03F0p4111*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 7200 series
+
+usb:v03F0p4117*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 1018
+
+usb:v03F0p4202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 812
+
+usb:v03F0p4205*
+ ID_PRODUCT_FROM_DATABASE=ScanJet G3010
+
+usb:v03F0p4211*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 7300 series
+
+usb:v03F0p4217*
+ ID_PRODUCT_FROM_DATABASE=EWS CM1015
+
+usb:v03F0p4302*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 850 (ptp)
+
+usb:v03F0p4305*
+ ID_PRODUCT_FROM_DATABASE=ScanJet G3110
+
+usb:v03F0p4311*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 7400 series
+
+usb:v03F0p4317*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet CM1017
+
+usb:v03F0p4402*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 935 (ptp)
+
+usb:v03F0p4417*
+ ID_PRODUCT_FROM_DATABASE=EWS UPD
+
+usb:v03F0p4502*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 945 (PTP mode)
+
+usb:v03F0p4505*
+ ID_PRODUCT_FROM_DATABASE=ScanJet G4010
+
+usb:v03F0p4511*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 2600
+
+usb:v03F0p4512*
+ ID_PRODUCT_FROM_DATABASE=E709n [Officejet 6500 Wireless]
+
+usb:v03F0p4517*
+ ID_PRODUCT_FROM_DATABASE=EWS UPD
+
+usb:v03F0p4605*
+ ID_PRODUCT_FROM_DATABASE=ScanJet G4050
+
+usb:v03F0p4611*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 2700
+
+usb:v03F0p4717*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet CP1215
+
+usb:v03F0p4811*
+ ID_PRODUCT_FROM_DATABASE=PSC 1600
+
+usb:v03F0p4911*
+ ID_PRODUCT_FROM_DATABASE=PSC 2350
+
+usb:v03F0p4B11*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 6200
+
+usb:v03F0p4C11*
+ ID_PRODUCT_FROM_DATABASE=PSC 1500 series
+
+usb:v03F0p4C17*
+ ID_PRODUCT_FROM_DATABASE=EWS UPD
+
+usb:v03F0p4D11*
+ ID_PRODUCT_FROM_DATABASE=PSC 1400
+
+usb:v03F0p4D17*
+ ID_PRODUCT_FROM_DATABASE=EWS UPD
+
+usb:v03F0p4E11*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 2570 series
+
+usb:v03F0p4F11*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 5600 (USBHUB)
+
+usb:v03F0p4F17*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet CM1312 MFP
+
+usb:v03F0p5004*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 995c
+
+usb:v03F0p5011*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 3100 series
+
+usb:v03F0p5017*
+ ID_PRODUCT_FROM_DATABASE=EWS UPD
+
+usb:v03F0p5111*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 3200 series
+
+usb:v03F0p5211*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 3300 series
+
+usb:v03F0p5311*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 6300
+
+usb:v03F0p5312*
+ ID_PRODUCT_FROM_DATABASE=Officejet Pro 8500A
+
+usb:v03F0p5411*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet 4300
+
+usb:v03F0p5511*
+ ID_PRODUCT_FROM_DATABASE=DeskJet F300 series
+
+usb:v03F0p5611*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C3180
+
+usb:v03F0p5617*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M1120 MFP
+
+usb:v03F0p5711*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C4100 series
+
+usb:v03F0p5717*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M1120n MFP
+
+usb:v03F0p5811*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C5100 series
+
+usb:v03F0p5817*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M1319f MFP
+
+usb:v03F0p5911*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C6180
+
+usb:v03F0p5A11*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C7100 series
+
+usb:v03F0p5B11*
+ ID_PRODUCT_FROM_DATABASE=OfficeJet J2100 series
+
+usb:v03F0p5C11*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C4200 Printer series
+
+usb:v03F0p5C17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P2055 series
+
+usb:v03F0p5D11*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C5200 series
+
+usb:v03F0p5E11*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart D7400 series
+
+usb:v03F0p6004*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 5550
+
+usb:v03F0p6102*
+ ID_PRODUCT_FROM_DATABASE=Hewlett Packard Digital Camera
+
+usb:v03F0p6104*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 5650c
+
+usb:v03F0p6117*
+ ID_PRODUCT_FROM_DATABASE=color LaserJet 3550
+
+usb:v03F0p6202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 215
+
+usb:v03F0p6204*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 5150c
+
+usb:v03F0p6217*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 4700
+
+usb:v03F0p6302*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 318/612
+
+usb:v03F0p6317*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 4730mfp
+
+usb:v03F0p6402*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 715 (ptp)
+
+usb:v03F0p6411*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C8100 series
+
+usb:v03F0p6417*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 5200
+
+usb:v03F0p6502*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 120 (ptp)
+
+usb:v03F0p6511*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C7200 series
+
+usb:v03F0p6602*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 320
+
+usb:v03F0p6611*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C4380 series
+
+usb:v03F0p6617*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 5200L
+
+usb:v03F0p6702*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 720 (ptp)
+
+usb:v03F0p6717*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 3000
+
+usb:v03F0p6802*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 620 (ptp)
+
+usb:v03F0p6811*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart D5300 series
+
+usb:v03F0p6817*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 3800
+
+usb:v03F0p6911*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart D7200 series
+
+usb:v03F0p6917*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 3600
+
+usb:v03F0p6A02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 735 (ptp)
+
+usb:v03F0p6A11*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C6200 series
+
+usb:v03F0p6A17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet 4240
+
+usb:v03F0p6B02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart R707 (PTP mode)
+
+usb:v03F0p6B11*
+ ID_PRODUCT_FROM_DATABASE=Photosmart C4500 series
+
+usb:v03F0p6C17*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet 4610
+
+usb:v03F0p6F17*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet CP6015 series
+
+usb:v03F0p7004*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 3320c
+
+usb:v03F0p7102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 635 (PTP mode)
+
+usb:v03F0p7104*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 3420c
+
+usb:v03F0p7117*
+ ID_PRODUCT_FROM_DATABASE=CM8060 Color MFP with Edgeline Technology
+
+usb:v03F0p7202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 43x (ptp)
+
+usb:v03F0p7204*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 36xx
+
+usb:v03F0p7217*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M5035 MFP
+
+usb:v03F0p7302*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M307 (PTP mode)
+
+usb:v03F0p7304*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 35xx
+
+usb:v03F0p7311*
+ ID_PRODUCT_FROM_DATABASE=Photosmart Premium C309
+
+usb:v03F0p7317*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P3005
+
+usb:v03F0p7404*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p7417*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M4345 MFP
+
+usb:v03F0p7504*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p7517*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M3035 MFP
+
+usb:v03F0p7604*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 3940
+
+usb:v03F0p7611*
+ ID_PRODUCT_FROM_DATABASE=DeskJet F2492 All-in-One
+
+usb:v03F0p7617*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P3004
+
+usb:v03F0p7702*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart R817 (PTP mode)
+
+usb:v03F0p7704*
+ ID_PRODUCT_FROM_DATABASE=DeskJet D4100
+
+usb:v03F0p7717*
+ ID_PRODUCT_FROM_DATABASE=CM8050 Color MFP with Edgeline Technology
+
+usb:v03F0p7804*
+ ID_PRODUCT_FROM_DATABASE=DeskJet D1360
+
+usb:v03F0p7817*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet CP3505
+
+usb:v03F0p7917*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M5025 MFP
+
+usb:v03F0p7A02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M415 (PTP mode)
+
+usb:v03F0p7A04*
+ ID_PRODUCT_FROM_DATABASE=DeskJet D2460
+
+usb:v03F0p7A17*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M3027 MFP
+
+usb:v03F0p7B02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M23 (PTP mode)
+
+usb:v03F0p7B17*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet CP4005
+
+usb:v03F0p7C17*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet CM6040 series
+
+usb:v03F0p7D04*
+ ID_PRODUCT_FROM_DATABASE=DeskJet F2100 Printer series
+
+usb:v03F0p7D17*
+ ID_PRODUCT_FROM_DATABASE=Color LaserJet CM4730 MFP
+
+usb:v03F0p7E04*
+ ID_PRODUCT_FROM_DATABASE=DeskJet F4100 Printer series
+
+usb:v03F0p8017*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P4515
+
+usb:v03F0p8104*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p8117*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P4015
+
+usb:v03F0p811C*
+ ID_PRODUCT_FROM_DATABASE=Ethernet HN210E
+
+usb:v03F0p8204*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v03F0p8207*
+ ID_PRODUCT_FROM_DATABASE=FHA-3510 2.4GHz Wireless Optical Mobile Mouse
+
+usb:v03F0p8217*
+ ID_PRODUCT_FROM_DATABASE=LaserJet P4014
+
+usb:v03F0p8317*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M9050 MFP
+
+usb:v03F0p8404*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 6800 series
+
+usb:v03F0p8417*
+ ID_PRODUCT_FROM_DATABASE=LaserJet M9040 MFP
+
+usb:v03F0p8504*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 6600 series
+
+usb:v03F0p8604*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 5440
+
+usb:v03F0p8704*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 5940
+
+usb:v03F0p8711*
+ ID_PRODUCT_FROM_DATABASE=Deskjet 2050 J510
+
+usb:v03F0p8804*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 6980 series
+
+usb:v03F0p8904*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 6940 series
+
+usb:v03F0p8C07*
+ ID_PRODUCT_FROM_DATABASE=Digital Stereo Headset
+
+usb:v03F0p8C11*
+ ID_PRODUCT_FROM_DATABASE=Deskjet F4500 series
+
+usb:v03F0p9002*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M437
+
+usb:v03F0p9102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M537
+
+usb:v03F0p9302*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart R930 series
+
+usb:v03F0p9402*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart R837
+
+usb:v03F0p9502*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart R840 series
+
+usb:v03F0p9602*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M730 series
+
+usb:v03F0p9702*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart R740 series
+
+usb:v03F0p9802*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart Mz60 series
+
+usb:v03F0p9902*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M630 series
+
+usb:v03F0p9A02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart E330 series
+
+usb:v03F0p9B02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M540 series
+
+usb:v03F0p9C02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart M440 series
+
+usb:v03F0pA004*
+ ID_PRODUCT_FROM_DATABASE=DeskJet 5850c
+
+usb:v03F0pA011*
+ ID_PRODUCT_FROM_DATABASE=Deskjet 3050A
+
+usb:v03F0pB002*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7200 series
+
+usb:v03F0pB102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7200 series
+
+usb:v03F0pB107*
+ ID_PRODUCT_FROM_DATABASE=v255w/c310w Flash Drive
+
+usb:v03F0pB116*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v03F0pB202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7600 series
+
+usb:v03F0pB302*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7600 series
+
+usb:v03F0pB402*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7700 series
+
+usb:v03F0pB502*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7700 series
+
+usb:v03F0pB602*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7900 series
+
+usb:v03F0pB702*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7900 series
+
+usb:v03F0pB802*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7400 series
+
+usb:v03F0pB902*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7800 series
+
+usb:v03F0pBA02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 8100 series
+
+usb:v03F0pBB02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 8400 series
+
+usb:v03F0pBC02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 8700 series
+
+usb:v03F0pBD02*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart Pro B9100 series
+
+usb:v03F0pBEF4*
+ ID_PRODUCT_FROM_DATABASE=NEC Picty760
+
+usb:v03F0pC002*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 7800 series
+
+usb:v03F0pC102*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 8000 series
+
+usb:v03F0pC202*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart 8200 series
+
+usb:v03F0pC302*
+ ID_PRODUCT_FROM_DATABASE=DeskJet D2300
+
+usb:v03F0pC402*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart D5100 series
+
+usb:v03F0pC502*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart D6100 series
+
+usb:v03F0pC602*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart D7100 series
+
+usb:v03F0pC702*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart D7300 series
+
+usb:v03F0pC802*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart D5060 Printer
+
+usb:v03F0pD104*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v03F0pEFBE*
+ ID_PRODUCT_FROM_DATABASE=NEC Picty900
+
+usb:v03F0pF0BE*
+ ID_PRODUCT_FROM_DATABASE=NEC Picty920
+
+usb:v03F0pF1BE*
+ ID_PRODUCT_FROM_DATABASE=NEC Picty800
+
+usb:v03F1*
+ ID_VENDOR_FROM_DATABASE=Genoa Technology
+
+usb:v03F2*
+ ID_VENDOR_FROM_DATABASE=Oak Technology, Inc.
+
+usb:v03F3*
+ ID_VENDOR_FROM_DATABASE=Adaptec, Inc.
+
+usb:v03F3p0020*
+ ID_PRODUCT_FROM_DATABASE=AWN-8020 WLAN [Intersil PRISM 2.5]
+
+usb:v03F3p0080*
+ ID_PRODUCT_FROM_DATABASE=AVC-1100 Audio Capture
+
+usb:v03F3p0083*
+ ID_PRODUCT_FROM_DATABASE=AVC-2200 Device
+
+usb:v03F3p0087*
+ ID_PRODUCT_FROM_DATABASE=AVC-2210 Loader
+
+usb:v03F3p0088*
+ ID_PRODUCT_FROM_DATABASE=AVC-2210 Device
+
+usb:v03F3p008B*
+ ID_PRODUCT_FROM_DATABASE=AVC-2310 Loader
+
+usb:v03F3p008C*
+ ID_PRODUCT_FROM_DATABASE=AVC-2310 Device
+
+usb:v03F3p0094*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v03F3p009B*
+ ID_PRODUCT_FROM_DATABASE=AVC-1410 GameBridge TV NTSC
+
+usb:v03F3p2000*
+ ID_PRODUCT_FROM_DATABASE=USBXchange
+
+usb:v03F3p2001*
+ ID_PRODUCT_FROM_DATABASE=USBXchange Adapter
+
+usb:v03F3p2002*
+ ID_PRODUCT_FROM_DATABASE=USB2-Xchange
+
+usb:v03F3p2003*
+ ID_PRODUCT_FROM_DATABASE=USB2-Xchange Adapter
+
+usb:v03F3p4000*
+ ID_PRODUCT_FROM_DATABASE=4-port hub
+
+usb:v03F3pADCC*
+ ID_PRODUCT_FROM_DATABASE=Composite Device Support
+
+usb:v03F4*
+ ID_VENDOR_FROM_DATABASE=Diebold, Inc.
+
+usb:v03F5*
+ ID_VENDOR_FROM_DATABASE=Siemens Electromechanical
+
+usb:v03F8*
+ ID_VENDOR_FROM_DATABASE=Epson Imaging Technology Center
+
+usb:v03F9*
+ ID_VENDOR_FROM_DATABASE=KeyTronic Corp.
+
+usb:v03F9p0100*
+ ID_PRODUCT_FROM_DATABASE=KT-2001 Keyboard
+
+usb:v03F9p0101*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v03F9p0102*
+ ID_PRODUCT_FROM_DATABASE=Keyboard Mouse
+
+usb:v03FB*
+ ID_VENDOR_FROM_DATABASE=OPTi, Inc.
+
+usb:v03FC*
+ ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems
+
+usb:v03FD*
+ ID_VENDOR_FROM_DATABASE=Xilinx, Inc.
+
+usb:v03FE*
+ ID_VENDOR_FROM_DATABASE=Farallon Comunications
+
+usb:v0400*
+ ID_VENDOR_FROM_DATABASE=National Semiconductor Corp.
+
+usb:v0400p05DC*
+ ID_PRODUCT_FROM_DATABASE=Rigol Technologies DS1000USB Oscilloscope
+
+usb:v0400p0807*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v0400p080A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0400p09C4*
+ ID_PRODUCT_FROM_DATABASE=Rigol Technologies DG1022 Arbitrary Waveform Generator
+
+usb:v0400p1000*
+ ID_PRODUCT_FROM_DATABASE=Mustek BearPaw 1200 Scanner
+
+usb:v0400p1001*
+ ID_PRODUCT_FROM_DATABASE=Mustek BearPaw 2400 Scanner
+
+usb:v0400p1237*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0400pA000*
+ ID_PRODUCT_FROM_DATABASE=Smart Display Reference Device
+
+usb:v0400pC359*
+ ID_PRODUCT_FROM_DATABASE=Logitech Harmony (Boot loader mode)
+
+usb:v0400pC35B*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v0400pC55D*
+ ID_PRODUCT_FROM_DATABASE=Rigol Technologies DS5000USB Oscilloscope
+
+usb:v0401*
+ ID_VENDOR_FROM_DATABASE=National Registry, Inc.
+
+usb:v0402*
+ ID_VENDOR_FROM_DATABASE=ALi Corp.
+
+usb:v0402p5462*
+ ID_PRODUCT_FROM_DATABASE=M5462 IDE Controller
+
+usb:v0402p5602*
+ ID_PRODUCT_FROM_DATABASE=M5602 Video Camera Controller
+
+usb:v0402p5603*
+ ID_PRODUCT_FROM_DATABASE=M5603 Video Camera Controller
+
+usb:v0402p5606*
+ ID_PRODUCT_FROM_DATABASE=M5606 Video Camera Controller [UVC]
+
+usb:v0402p5621*
+ ID_PRODUCT_FROM_DATABASE=M5621 High-Speed IDE Controller
+
+usb:v0402p5623*
+ ID_PRODUCT_FROM_DATABASE=M5623 Scanner Controller
+
+usb:v0402p5627*
+ ID_PRODUCT_FROM_DATABASE=Welland ME-740PS USB2 3.5" Power Saving Enclosure
+
+usb:v0402p5632*
+ ID_PRODUCT_FROM_DATABASE=M5632 Host-to-Host Link
+
+usb:v0402p5635*
+ ID_PRODUCT_FROM_DATABASE=M5635 Flash Card Reader
+
+usb:v0402p5636*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Storage Device
+
+usb:v0402p5637*
+ ID_PRODUCT_FROM_DATABASE=M5637 IDE Controller
+
+usb:v0402p5661*
+ ID_PRODUCT_FROM_DATABASE=M5661 MP3 player
+
+usb:v0402p5667*
+ ID_PRODUCT_FROM_DATABASE=M5667 MP3 player
+
+usb:v0402p9665*
+ ID_PRODUCT_FROM_DATABASE=Gateway Webcam
+
+usb:v0403*
+ ID_VENDOR_FROM_DATABASE=Future Technology Devices International, Ltd
+
+usb:v0403p0000*
+ ID_PRODUCT_FROM_DATABASE=H4SMK 7 Port Hub
+
+usb:v0403p0232*
+ ID_PRODUCT_FROM_DATABASE=Serial Converter
+
+usb:v0403p1060*
+ ID_PRODUCT_FROM_DATABASE=JTAG adapter
+
+usb:v0403p6001*
+ ID_PRODUCT_FROM_DATABASE=FT232 USB-Serial (UART) IC
+
+usb:v0403p6002*
+ ID_PRODUCT_FROM_DATABASE=Lumel PD12
+
+usb:v0403p6007*
+ ID_PRODUCT_FROM_DATABASE=Serial Converter
+
+usb:v0403p6008*
+ ID_PRODUCT_FROM_DATABASE=Serial Converter
+
+usb:v0403p6009*
+ ID_PRODUCT_FROM_DATABASE=Serial Converter
+
+usb:v0403p6010*
+ ID_PRODUCT_FROM_DATABASE=FT2232C Dual USB-UART/FIFO IC
+
+usb:v0403p6011*
+ ID_PRODUCT_FROM_DATABASE=FT4232H Quad HS USB-UART/FIFO IC
+
+usb:v0403p6014*
+ ID_PRODUCT_FROM_DATABASE=FT232H Single HS USB-UART/FIFO IC
+
+usb:v0403p6015*
+ ID_PRODUCT_FROM_DATABASE=Bridge(I2C/SPI/UART/FIFO)
+
+usb:v0403p8040*
+ ID_PRODUCT_FROM_DATABASE=4 Port Hub
+
+usb:v0403p8070*
+ ID_PRODUCT_FROM_DATABASE=7 Port Hub
+
+usb:v0403p8370*
+ ID_PRODUCT_FROM_DATABASE=7 Port Hub
+
+usb:v0403p8371*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard And Mouse
+
+usb:v0403p8372*
+ ID_PRODUCT_FROM_DATABASE=FT8U100AX Serial Port
+
+usb:v0403p8A28*
+ ID_PRODUCT_FROM_DATABASE=Rainforest Automation ZigBee Controller
+
+usb:v0403p8A98*
+ ID_PRODUCT_FROM_DATABASE=TIAO Multi-Protocol Adapter
+
+usb:v0403p9E90*
+ ID_PRODUCT_FROM_DATABASE=Marvell OpenRD Base/Client
+
+usb:v0403p9F80*
+ ID_PRODUCT_FROM_DATABASE=Ewert Energy Systems CANdapter
+
+usb:v0403pA6D0*
+ ID_PRODUCT_FROM_DATABASE=Texas Instruments XDS100v2 JTAG / BeagleBone A3
+
+usb:v0403pA951*
+ ID_PRODUCT_FROM_DATABASE=HCP HIT GSM/GPRS modem [Cinterion MC55i]
+
+usb:v0403pABB8*
+ ID_PRODUCT_FROM_DATABASE=Lego Mindstorms NXTCam
+
+usb:v0403pB810*
+ ID_PRODUCT_FROM_DATABASE=US Interface Navigator (CAT and 2nd PTT lines)
+
+usb:v0403pB811*
+ ID_PRODUCT_FROM_DATABASE=US Interface Navigator (WKEY and FSK lines)
+
+usb:v0403pB812*
+ ID_PRODUCT_FROM_DATABASE=US Interface Navigator (RS232 and CONFIG lines)
+
+usb:v0403pB9B0*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu SK-16FX-100PMC V1.1
+
+usb:v0403pBAF8*
+ ID_PRODUCT_FROM_DATABASE=Amontec JTAGkey - Open On-Chip Debugger
+
+usb:v0403pBCD8*
+ ID_PRODUCT_FROM_DATABASE=Stellaris Development Board
+
+usb:v0403pBCD9*
+ ID_PRODUCT_FROM_DATABASE=Stellaris Evaluation Board
+
+usb:v0403pBCDA*
+ ID_PRODUCT_FROM_DATABASE=Stellaris ICDI Board
+
+usb:v0403pBDC8*
+ ID_PRODUCT_FROM_DATABASE=Egnite GmbH - JTAG/RS-232 adapter
+
+usb:v0403pBFD8*
+ ID_PRODUCT_FROM_DATABASE=OpenDCC
+
+usb:v0403pBFD9*
+ ID_PRODUCT_FROM_DATABASE=OpenDCC (Sniffer)
+
+usb:v0403pBFDA*
+ ID_PRODUCT_FROM_DATABASE=OpenDCC (Throttle)
+
+usb:v0403pBFDB*
+ ID_PRODUCT_FROM_DATABASE=OpenDCC (Gateway)
+
+usb:v0403pBFDC*
+ ID_PRODUCT_FROM_DATABASE=OpenDCC (GBM)
+
+usb:v0403pC630*
+ ID_PRODUCT_FROM_DATABASE=lcd2usb interface
+
+usb:v0403pC631*
+ ID_PRODUCT_FROM_DATABASE=i2c-tiny-usb interface
+
+usb:v0403pC632*
+ ID_PRODUCT_FROM_DATABASE=xu1541 c64 floppy drive interface
+
+usb:v0403pC633*
+ ID_PRODUCT_FROM_DATABASE=TinyCrypt dongle
+
+usb:v0403pC634*
+ ID_PRODUCT_FROM_DATABASE=glcd2usb interface
+
+usb:v0403pC7D0*
+ ID_PRODUCT_FROM_DATABASE=RR-CirKits LocoBuffer-USB
+
+usb:v0403pC8B8*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte MTD TCU
+
+usb:v0403pC8B9*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte MTD TCU 1HE
+
+usb:v0403pC8BA*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium H1
+
+usb:v0403pC8BB*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium H3
+
+usb:v0403pC8BC*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium S1
+
+usb:v0403pC8BD*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium T1
+
+usb:v0403pC8BE*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium D1
+
+usb:v0403pCC48*
+ ID_PRODUCT_FROM_DATABASE=Tactrix OpenPort 1.3 Mitsubishi
+
+usb:v0403pCC49*
+ ID_PRODUCT_FROM_DATABASE=Tactrix OpenPort 1.3 Subaru
+
+usb:v0403pCC4A*
+ ID_PRODUCT_FROM_DATABASE=Tactrix OpenPort 1.3 Universal
+
+usb:v0403pCFF8*
+ ID_PRODUCT_FROM_DATABASE=Distortec JTAG-lock-pick
+
+usb:v0403pD010*
+ ID_PRODUCT_FROM_DATABASE=SCS PTC-IIusb
+
+usb:v0403pD011*
+ ID_PRODUCT_FROM_DATABASE=SCS Position-Tracker/TNC
+
+usb:v0403pD012*
+ ID_PRODUCT_FROM_DATABASE=SCS DRAGON 1
+
+usb:v0403pD013*
+ ID_PRODUCT_FROM_DATABASE=SCS DRAGON 1
+
+usb:v0403pD578*
+ ID_PRODUCT_FROM_DATABASE=Accesio USB-COM-4SM
+
+usb:v0403pD6F8*
+ ID_PRODUCT_FROM_DATABASE=UNI Black BOX
+
+usb:v0403pD738*
+ ID_PRODUCT_FROM_DATABASE=Propox JTAGcable II
+
+usb:v0403pD739*
+ ID_PRODUCT_FROM_DATABASE=Propox ISPcable III
+
+usb:v0403pD9A9*
+ ID_PRODUCT_FROM_DATABASE=Actisense USG-1 NMEA Serial Gateway
+
+usb:v0403pD9AA*
+ ID_PRODUCT_FROM_DATABASE=Actisense NGT-1 NMEA2000 PC Interface
+
+usb:v0403pE0D0*
+ ID_PRODUCT_FROM_DATABASE=Total Phase Aardvark I2C/SPI Host Adapter
+
+usb:v0403pE521*
+ ID_PRODUCT_FROM_DATABASE=EVER Sinline XL Series UPS
+
+usb:v0403pE6C8*
+ ID_PRODUCT_FROM_DATABASE=PYRAMID Computer GmbH LCD
+
+usb:v0403pE700*
+ ID_PRODUCT_FROM_DATABASE=Elster Unicom III Optical Probe
+
+usb:v0403pE729*
+ ID_PRODUCT_FROM_DATABASE=Segway Robotic Mobility Platforms 200
+
+usb:v0403pE888*
+ ID_PRODUCT_FROM_DATABASE=Expert ISDN Control USB
+
+usb:v0403pE889*
+ ID_PRODUCT_FROM_DATABASE=USB-RS232 OptoBridge
+
+usb:v0403pE88A*
+ ID_PRODUCT_FROM_DATABASE=Expert mouseCLOCK USB II
+
+usb:v0403pE88B*
+ ID_PRODUCT_FROM_DATABASE=Precision Clock MSF USB
+
+usb:v0403pE88C*
+ ID_PRODUCT_FROM_DATABASE=Expert mouseCLOCK USB II HBG
+
+usb:v0403pEA90*
+ ID_PRODUCT_FROM_DATABASE=Eclo 1-Wire Adapter
+
+usb:v0403pED71*
+ ID_PRODUCT_FROM_DATABASE=HAMEG HO870 Serial Port
+
+usb:v0403pED72*
+ ID_PRODUCT_FROM_DATABASE=HAMEG HO720 Serial Port
+
+usb:v0403pED73*
+ ID_PRODUCT_FROM_DATABASE=HAMEG HO730 Serial Port
+
+usb:v0403pED74*
+ ID_PRODUCT_FROM_DATABASE=HAMEG HO820 Serial Port
+
+usb:v0403pEF10*
+ ID_PRODUCT_FROM_DATABASE=FT1245BL
+
+usb:v0403pF070*
+ ID_PRODUCT_FROM_DATABASE=Serial Converter 422/485 [Vardaan VEUSB422R3]
+
+usb:v0403pF1A0*
+ ID_PRODUCT_FROM_DATABASE=Asix PRESTO Programmer
+
+usb:v0403pF208*
+ ID_PRODUCT_FROM_DATABASE=Papenmeier Braille-Display
+
+usb:v0403pF3C0*
+ ID_PRODUCT_FROM_DATABASE=4N-GALAXY Serial Converter
+
+usb:v0403pF608*
+ ID_PRODUCT_FROM_DATABASE=CTI USB-485-Mini
+
+usb:v0403pF60B*
+ ID_PRODUCT_FROM_DATABASE=CTI USB-Nano-485
+
+usb:v0403pF680*
+ ID_PRODUCT_FROM_DATABASE=Suunto Sports Instrument
+
+usb:v0403pF758*
+ ID_PRODUCT_FROM_DATABASE=GW Instek GDS-8x0 Oscilloscope
+
+usb:v0403pF7C0*
+ ID_PRODUCT_FROM_DATABASE=ZeitControl Cardsystems TagTracer MIFARE
+
+usb:v0403pF850*
+ ID_PRODUCT_FROM_DATABASE=USB-UIRT (Universal Infrared Receiver+Transmitter)
+
+usb:v0403pF918*
+ ID_PRODUCT_FROM_DATABASE=Ant8 Logic Probe
+
+usb:v0403pFA00*
+ ID_PRODUCT_FROM_DATABASE=Matrix Orbital USB Serial
+
+usb:v0403pFA01*
+ ID_PRODUCT_FROM_DATABASE=Matrix Orbital MX2 or MX3
+
+usb:v0403pFA02*
+ ID_PRODUCT_FROM_DATABASE=Matrix Orbital MX4 or MX5
+
+usb:v0403pFA03*
+ ID_PRODUCT_FROM_DATABASE=Matrix Orbital VK/LK202 Family
+
+usb:v0403pFA04*
+ ID_PRODUCT_FROM_DATABASE=Matrix Orbital VK/LK204 Family
+
+usb:v0403pFC08*
+ ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-632 USB LCD
+
+usb:v0403pFC09*
+ ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-634 USB LCD
+
+usb:v0403pFC0B*
+ ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-633 USB LCD
+
+usb:v0403pFC0C*
+ ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-631 USB LCD
+
+usb:v0403pFC0D*
+ ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-635 USB LCD
+
+usb:v0403pFC82*
+ ID_PRODUCT_FROM_DATABASE=SEMC DSS-20/DSS-25 SyncStation
+
+usb:v0403pFD48*
+ ID_PRODUCT_FROM_DATABASE=ShipModul MiniPlex-4xUSB NMEA Multiplexer
+
+usb:v0403pFD49*
+ ID_PRODUCT_FROM_DATABASE=ShipModul MiniPlex-4xUSB-AIS NMEA Multiplexer
+
+usb:v0403pFF08*
+ ID_PRODUCT_FROM_DATABASE=ToolHouse LoopBack Adapter
+
+usb:v0403pFF18*
+ ID_PRODUCT_FROM_DATABASE=ScienceScope Logbook ML
+
+usb:v0403pFF19*
+ ID_PRODUCT_FROM_DATABASE=Logbook Bus
+
+usb:v0403pFF1A*
+ ID_PRODUCT_FROM_DATABASE=Logbook Bus
+
+usb:v0403pFF1B*
+ ID_PRODUCT_FROM_DATABASE=Logbook Bus
+
+usb:v0403pFF1C*
+ ID_PRODUCT_FROM_DATABASE=ScienceScope Logbook LS
+
+usb:v0403pFF1D*
+ ID_PRODUCT_FROM_DATABASE=ScienceScope Logbook HS
+
+usb:v0403pFF1E*
+ ID_PRODUCT_FROM_DATABASE=Logbook Bus
+
+usb:v0403pFF1F*
+ ID_PRODUCT_FROM_DATABASE=Logbook Bus
+
+usb:v0404*
+ ID_VENDOR_FROM_DATABASE=NCR Corp.
+
+usb:v0404p0202*
+ ID_PRODUCT_FROM_DATABASE=78XX Scanner
+
+usb:v0404p0203*
+ ID_PRODUCT_FROM_DATABASE=78XX Scanner - Embedded System
+
+usb:v0404p0310*
+ ID_PRODUCT_FROM_DATABASE=K590 Printer, Self-Service
+
+usb:v0404p0311*
+ ID_PRODUCT_FROM_DATABASE=7167 Printer, Receipt/Slip
+
+usb:v0404p0312*
+ ID_PRODUCT_FROM_DATABASE=7197 Printer Receipt
+
+usb:v0404p0320*
+ ID_PRODUCT_FROM_DATABASE=5932-USB Keyboard
+
+usb:v0404p0321*
+ ID_PRODUCT_FROM_DATABASE=5953-USB Dynakey
+
+usb:v0404p0322*
+ ID_PRODUCT_FROM_DATABASE=5932-USB Enhanced Keyboard
+
+usb:v0404p0323*
+ ID_PRODUCT_FROM_DATABASE=5932-USB Enhanced Keyboard, Flash-Recovery/Download
+
+usb:v0404p0324*
+ ID_PRODUCT_FROM_DATABASE=5953-USB Enhanced Dynakey
+
+usb:v0404p0325*
+ ID_PRODUCT_FROM_DATABASE=5953-USB Enhanced Dynakey Flash-Recovery/Download
+
+usb:v0404p0328*
+ ID_PRODUCT_FROM_DATABASE=K016: USB-MSR ISO 3-track MSR: POS Standard (See HID pages)
+
+usb:v0404p0329*
+ ID_PRODUCT_FROM_DATABASE=K018: USB-MSR JIS 2-Track MSR: POS Standard
+
+usb:v0404p032A*
+ ID_PRODUCT_FROM_DATABASE=K016: USB-MSR ISO 3-Track MSR: HID Keyboard Mode
+
+usb:v0404p032B*
+ ID_PRODUCT_FROM_DATABASE=K016/K018: USB-MSR Flash-Recovery/Download
+
+usb:v0405*
+ ID_VENDOR_FROM_DATABASE=Synopsys, Inc.
+
+usb:v0406*
+ ID_VENDOR_FROM_DATABASE=Fujitsu-ICL Computers
+
+usb:v0407*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Personal Systems, Inc.
+
+usb:v0408*
+ ID_VENDOR_FROM_DATABASE=Quanta Computer, Inc.
+
+usb:v0408p0103*
+ ID_PRODUCT_FROM_DATABASE=FV TouchCam N1 (Audio)
+
+usb:v0408p030C*
+ ID_PRODUCT_FROM_DATABASE=HP Webcam
+
+usb:v0408p03B2*
+ ID_PRODUCT_FROM_DATABASE=HP Webcam
+
+usb:v0408p1030*
+ ID_PRODUCT_FROM_DATABASE=FV TouchCam N1 (Video)
+
+usb:v0408p3000*
+ ID_PRODUCT_FROM_DATABASE=Optical dual-touch panel
+
+usb:v0408p3001*
+ ID_PRODUCT_FROM_DATABASE=Optical Touch Screen
+
+usb:v0409*
+ ID_VENDOR_FROM_DATABASE=NEC Corp.
+
+usb:v0409p0011*
+ ID_PRODUCT_FROM_DATABASE=PC98 Series Layout Keyboard Mouse
+
+usb:v0409p0012*
+ ID_PRODUCT_FROM_DATABASE=ATerm IT75DSU ISDN TA
+
+usb:v0409p0014*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard
+
+usb:v0409p0019*
+ ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard with Bus-Powered Hub
+
+usb:v0409p001A*
+ ID_PRODUCT_FROM_DATABASE=PC98 Series Layout Keyboard with Bus-Powered Hub
+
+usb:v0409p0025*
+ ID_PRODUCT_FROM_DATABASE=Mini Keyboard with Bus-Powered Hub
+
+usb:v0409p0027*
+ ID_PRODUCT_FROM_DATABASE=MultiSync Monitor
+
+usb:v0409p002C*
+ ID_PRODUCT_FROM_DATABASE=Clik!-USB Drive
+
+usb:v0409p0034*
+ ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard with One-touch start buttons
+
+usb:v0409p003F*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard with One-touch start buttons
+
+usb:v0409p0040*
+ ID_PRODUCT_FROM_DATABASE=Floppy
+
+usb:v0409p004E*
+ ID_PRODUCT_FROM_DATABASE=SuperScript 1400 Series
+
+usb:v0409p004F*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard with One-touch start buttons
+
+usb:v0409p0050*
+ ID_PRODUCT_FROM_DATABASE=7-port hub
+
+usb:v0409p0058*
+ ID_PRODUCT_FROM_DATABASE=HighSpeed Hub
+
+usb:v0409p0059*
+ ID_PRODUCT_FROM_DATABASE=HighSpeed Hub
+
+usb:v0409p005A*
+ ID_PRODUCT_FROM_DATABASE=HighSpeed Hub
+
+usb:v0409p006A*
+ ID_PRODUCT_FROM_DATABASE=Conceptronic USB Harddisk Box
+
+usb:v0409p007D*
+ ID_PRODUCT_FROM_DATABASE=MINICUBE2
+
+usb:v0409p007E*
+ ID_PRODUCT_FROM_DATABASE=PG-FP5 Flash Memory Programmer
+
+usb:v0409p0081*
+ ID_PRODUCT_FROM_DATABASE=SuperScript 1400 Series
+
+usb:v0409p0082*
+ ID_PRODUCT_FROM_DATABASE=SuperScript 1400 Series
+
+usb:v0409p0094*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard with One-touch start buttons
+
+usb:v0409p0095*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard
+
+usb:v0409p00A9*
+ ID_PRODUCT_FROM_DATABASE=AtermIT21L 128K Support Standard
+
+usb:v0409p00AA*
+ ID_PRODUCT_FROM_DATABASE=AtermITX72 128K Support Standard
+
+usb:v0409p00AB*
+ ID_PRODUCT_FROM_DATABASE=AtermITX62 128K Support Standard
+
+usb:v0409p00AC*
+ ID_PRODUCT_FROM_DATABASE=AtermIT42 128K Support Standard
+
+usb:v0409p00AE*
+ ID_PRODUCT_FROM_DATABASE=INSMATEV70G-MAX Standard
+
+usb:v0409p00AF*
+ ID_PRODUCT_FROM_DATABASE=AtermITX70 128K Support Standard
+
+usb:v0409p00B0*
+ ID_PRODUCT_FROM_DATABASE=AtermITX80 128K Support Standard
+
+usb:v0409p00B2*
+ ID_PRODUCT_FROM_DATABASE=AtermITX80D 128K Support Standard
+
+usb:v0409p00C0*
+ ID_PRODUCT_FROM_DATABASE=Wireless Remocon
+
+usb:v0409p00F7*
+ ID_PRODUCT_FROM_DATABASE=Smart Display PK-SD10
+
+usb:v0409p011D*
+ ID_PRODUCT_FROM_DATABASE=e228 Mobile Phone
+
+usb:v0409p0203*
+ ID_PRODUCT_FROM_DATABASE=HID Audio Controls
+
+usb:v0409p021D*
+ ID_PRODUCT_FROM_DATABASE=Aterm WL54SU2 802.11g Wireless Adapter [Atheros AR5523]
+
+usb:v0409p0248*
+ ID_PRODUCT_FROM_DATABASE=Aterm PA-WL54GU
+
+usb:v0409p0249*
+ ID_PRODUCT_FROM_DATABASE=Aterm WL300NU-G
+
+usb:v0409p02B4*
+ ID_PRODUCT_FROM_DATABASE=Aterm WL300NU-AG
+
+usb:v0409p02B6*
+ ID_PRODUCT_FROM_DATABASE=Aterm WL300NU-GS 802.11n Wireless Adapter
+
+usb:v0409p0300*
+ ID_PRODUCT_FROM_DATABASE=LifeTouch Note
+
+usb:v0409p0301*
+ ID_PRODUCT_FROM_DATABASE=LifeTouch Note (debug mode)
+
+usb:v0409p55AA*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0409p55AB*
+ ID_PRODUCT_FROM_DATABASE=Hub [iMac/iTouch kbd]
+
+usb:v0409p8010*
+ ID_PRODUCT_FROM_DATABASE=Intellibase Hub
+
+usb:v0409p8011*
+ ID_PRODUCT_FROM_DATABASE=Intellibase Hub
+
+usb:v0409pEFBE*
+ ID_PRODUCT_FROM_DATABASE=P!cty 900 [HP DJ]
+
+usb:v0409pF0BE*
+ ID_PRODUCT_FROM_DATABASE=P!cty 920 [HP DJ 812c]
+
+usb:v040A*
+ ID_VENDOR_FROM_DATABASE=Kodak Co.
+
+usb:v040Ap0001*
+ ID_PRODUCT_FROM_DATABASE=DVC-323
+
+usb:v040Ap0002*
+ ID_PRODUCT_FROM_DATABASE=DVC-325
+
+usb:v040Ap0100*
+ ID_PRODUCT_FROM_DATABASE=DC-220
+
+usb:v040Ap0110*
+ ID_PRODUCT_FROM_DATABASE=DC-260
+
+usb:v040Ap0111*
+ ID_PRODUCT_FROM_DATABASE=DC-265
+
+usb:v040Ap0112*
+ ID_PRODUCT_FROM_DATABASE=DC-290
+
+usb:v040Ap0120*
+ ID_PRODUCT_FROM_DATABASE=DC-240
+
+usb:v040Ap0121*
+ ID_PRODUCT_FROM_DATABASE=DC-240 (PTP firmware)
+
+usb:v040Ap0130*
+ ID_PRODUCT_FROM_DATABASE=DC-280
+
+usb:v040Ap0131*
+ ID_PRODUCT_FROM_DATABASE=DC-5000
+
+usb:v040Ap0132*
+ ID_PRODUCT_FROM_DATABASE=DC-3400
+
+usb:v040Ap0140*
+ ID_PRODUCT_FROM_DATABASE=DC-4800
+
+usb:v040Ap0160*
+ ID_PRODUCT_FROM_DATABASE=DC4800
+
+usb:v040Ap0170*
+ ID_PRODUCT_FROM_DATABASE=DX3900
+
+usb:v040Ap0200*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0300*
+ ID_PRODUCT_FROM_DATABASE=EZ-200
+
+usb:v040Ap0400*
+ ID_PRODUCT_FROM_DATABASE=MC3
+
+usb:v040Ap0402*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0403*
+ ID_PRODUCT_FROM_DATABASE=Z7590
+
+usb:v040Ap0500*
+ ID_PRODUCT_FROM_DATABASE=DX3500
+
+usb:v040Ap0510*
+ ID_PRODUCT_FROM_DATABASE=DX3600
+
+usb:v040Ap0525*
+ ID_PRODUCT_FROM_DATABASE=DX3215
+
+usb:v040Ap0530*
+ ID_PRODUCT_FROM_DATABASE=DX3700
+
+usb:v040Ap0535*
+ ID_PRODUCT_FROM_DATABASE=EasyShare CX4230 Camera
+
+usb:v040Ap0540*
+ ID_PRODUCT_FROM_DATABASE=LS420
+
+usb:v040Ap0550*
+ ID_PRODUCT_FROM_DATABASE=DX4900
+
+usb:v040Ap0555*
+ ID_PRODUCT_FROM_DATABASE=DX4330
+
+usb:v040Ap0560*
+ ID_PRODUCT_FROM_DATABASE=CX4200
+
+usb:v040Ap0565*
+ ID_PRODUCT_FROM_DATABASE=CX4210
+
+usb:v040Ap0566*
+ ID_PRODUCT_FROM_DATABASE=CX4300
+
+usb:v040Ap0567*
+ ID_PRODUCT_FROM_DATABASE=LS753
+
+usb:v040Ap0568*
+ ID_PRODUCT_FROM_DATABASE=LS443
+
+usb:v040Ap0569*
+ ID_PRODUCT_FROM_DATABASE=LS663
+
+usb:v040Ap0570*
+ ID_PRODUCT_FROM_DATABASE=DX6340
+
+usb:v040Ap0571*
+ ID_PRODUCT_FROM_DATABASE=CX6330
+
+usb:v040Ap0572*
+ ID_PRODUCT_FROM_DATABASE=DX6440
+
+usb:v040Ap0573*
+ ID_PRODUCT_FROM_DATABASE=CX6230
+
+usb:v040Ap0574*
+ ID_PRODUCT_FROM_DATABASE=CX6200
+
+usb:v040Ap0575*
+ ID_PRODUCT_FROM_DATABASE=DX6490
+
+usb:v040Ap0576*
+ ID_PRODUCT_FROM_DATABASE=DX4530
+
+usb:v040Ap0577*
+ ID_PRODUCT_FROM_DATABASE=DX7630
+
+usb:v040Ap0578*
+ ID_PRODUCT_FROM_DATABASE=CX7300/CX7310
+
+usb:v040Ap0579*
+ ID_PRODUCT_FROM_DATABASE=CX7220
+
+usb:v040Ap057A*
+ ID_PRODUCT_FROM_DATABASE=CX7330
+
+usb:v040Ap057B*
+ ID_PRODUCT_FROM_DATABASE=CX7430
+
+usb:v040Ap057C*
+ ID_PRODUCT_FROM_DATABASE=CX7530
+
+usb:v040Ap057D*
+ ID_PRODUCT_FROM_DATABASE=DX7440
+
+usb:v040Ap057E*
+ ID_PRODUCT_FROM_DATABASE=C300
+
+usb:v040Ap057F*
+ ID_PRODUCT_FROM_DATABASE=DX7590
+
+usb:v040Ap0580*
+ ID_PRODUCT_FROM_DATABASE=Z730
+
+usb:v040Ap0581*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0582*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0583*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0584*
+ ID_PRODUCT_FROM_DATABASE=CX6445
+
+usb:v040Ap0585*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0586*
+ ID_PRODUCT_FROM_DATABASE=CX7525
+
+usb:v040Ap0587*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0588*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0589*
+ ID_PRODUCT_FROM_DATABASE=EasyShare C360
+
+usb:v040Ap058A*
+ ID_PRODUCT_FROM_DATABASE=C310
+
+usb:v040Ap058B*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap058C*
+ ID_PRODUCT_FROM_DATABASE=C330
+
+usb:v040Ap058D*
+ ID_PRODUCT_FROM_DATABASE=C340
+
+usb:v040Ap058E*
+ ID_PRODUCT_FROM_DATABASE=V530
+
+usb:v040Ap058F*
+ ID_PRODUCT_FROM_DATABASE=V550
+
+usb:v040Ap0590*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0591*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0592*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0593*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0594*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0595*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0596*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0597*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap0598*
+ ID_PRODUCT_FROM_DATABASE=EASYSHARE M1033 digital camera
+
+usb:v040Ap0599*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap059A*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap059B*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap059C*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap059D*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap059E*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap059F*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A0*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A1*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A2*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A3*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A4*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A5*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A6*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A7*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A8*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05A9*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05AA*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05AB*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05AC*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05AD*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05AE*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05AF*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B0*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B1*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B2*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B3*
+ ID_PRODUCT_FROM_DATABASE=EasyShare Z710 Camera
+
+usb:v040Ap05B4*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B5*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B6*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B7*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B8*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05B9*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05BA*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05BB*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05BC*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05BD*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05BE*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05BF*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05C0*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05C1*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05C2*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05C3*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05C4*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05C5*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v040Ap05C8*
+ ID_PRODUCT_FROM_DATABASE=EASYSHARE Z1485 IS Digital Camera
+
+usb:v040Ap05D3*
+ ID_PRODUCT_FROM_DATABASE=EasyShare M320 Camera
+
+usb:v040Ap05D4*
+ ID_PRODUCT_FROM_DATABASE=EasyShare C180 Digital Camera
+
+usb:v040Ap1001*
+ ID_PRODUCT_FROM_DATABASE=EasyShare SV811 Digital Picture Frame
+
+usb:v040Ap4000*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v040Ap4056*
+ ID_PRODUCT_FROM_DATABASE=ESP 7200 Series AiO
+
+usb:v040Ap4109*
+ ID_PRODUCT_FROM_DATABASE=EasyShare Printer Dock Series 3
+
+usb:v040Ap410D*
+ ID_PRODUCT_FROM_DATABASE=EasyShare G600 Printer Dock
+
+usb:v040Ap5010*
+ ID_PRODUCT_FROM_DATABASE=Wireless Adapter
+
+usb:v040Ap5012*
+ ID_PRODUCT_FROM_DATABASE=DBT-220 Bluetooth Adapter
+
+usb:v040Ap6001*
+ ID_PRODUCT_FROM_DATABASE=i30
+
+usb:v040Ap6002*
+ ID_PRODUCT_FROM_DATABASE=i40
+
+usb:v040Ap6003*
+ ID_PRODUCT_FROM_DATABASE=i50
+
+usb:v040Ap6004*
+ ID_PRODUCT_FROM_DATABASE=i60
+
+usb:v040Ap6005*
+ ID_PRODUCT_FROM_DATABASE=i80
+
+usb:v040B*
+ ID_VENDOR_FROM_DATABASE=Weltrend Semiconductor
+
+usb:v040Bp6510*
+ ID_PRODUCT_FROM_DATABASE=Weltrend Bar Code Reader
+
+usb:v040Bp6520*
+ ID_PRODUCT_FROM_DATABASE=XBOX Xploder
+
+usb:v040Bp6533*
+ ID_PRODUCT_FROM_DATABASE=Speed-Link Competition Pro
+
+usb:v040Bp6543*
+ ID_PRODUCT_FROM_DATABASE=Manhattan Magnetic Card Strip Reader
+
+usb:v040C*
+ ID_VENDOR_FROM_DATABASE=VTech Computers, Ltd
+
+usb:v040D*
+ ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc.
+
+usb:v040Dp3184*
+ ID_PRODUCT_FROM_DATABASE=VNT VT6656 USB-802.11 Wireless LAN Adapter
+
+usb:v040Dp6205*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader
+
+usb:v040E*
+ ID_VENDOR_FROM_DATABASE=MCCI
+
+usb:v040F*
+ ID_VENDOR_FROM_DATABASE=Echo Speech Corp.
+
+usb:v0411*
+ ID_VENDOR_FROM_DATABASE=BUFFALO INC. (formerly MelCo., Inc.)
+
+usb:v0411p0001*
+ ID_PRODUCT_FROM_DATABASE=LUA-TX Ethernet [pegasus]
+
+usb:v0411p0005*
+ ID_PRODUCT_FROM_DATABASE=LUA-TX Ethernet
+
+usb:v0411p0006*
+ ID_PRODUCT_FROM_DATABASE=WLI-USB-L11 Wireless LAN Adapter
+
+usb:v0411p0009*
+ ID_PRODUCT_FROM_DATABASE=LUA2-TX Ethernet
+
+usb:v0411p000B*
+ ID_PRODUCT_FROM_DATABASE=WLI-USB-L11G-WR Wireless LAN Adapter
+
+usb:v0411p000D*
+ ID_PRODUCT_FROM_DATABASE=WLI-USB-L11G Wireless LAN Adapter
+
+usb:v0411p0012*
+ ID_PRODUCT_FROM_DATABASE=LUA-KTX Ethernet
+
+usb:v0411p0013*
+ ID_PRODUCT_FROM_DATABASE=USB2-IDE Adapter
+
+usb:v0411p0016*
+ ID_PRODUCT_FROM_DATABASE=WLI-USB-S11 802.11b Adapter
+
+usb:v0411p0018*
+ ID_PRODUCT_FROM_DATABASE=USB2-IDE Adapter
+
+usb:v0411p001C*
+ ID_PRODUCT_FROM_DATABASE=USB-IDE Bridge: DUB-PxxG
+
+usb:v0411p0027*
+ ID_PRODUCT_FROM_DATABASE=WLI-USB-KS11G 802.11b Adapter
+
+usb:v0411p002A*
+ ID_PRODUCT_FROM_DATABASE=SMSC USB97C202 "HD-HB300V2-EU"
+
+usb:v0411p003D*
+ ID_PRODUCT_FROM_DATABASE=LUA-U2-KTX Ethernet
+
+usb:v0411p0044*
+ ID_PRODUCT_FROM_DATABASE=WLI-USB-KB11 Wireless LAN Adapter
+
+usb:v0411p004B*
+ ID_PRODUCT_FROM_DATABASE=WLI-USB-G54 802.11g Adapter [Broadcom 4320 USB]
+
+usb:v0411p004D*
+ ID_PRODUCT_FROM_DATABASE=WLI-USB-B11 Wireless LAN Adapter
+
+usb:v0411p0050*
+ ID_PRODUCT_FROM_DATABASE=WLI2-USB2-G54 Wireless LAN Adapter
+
+usb:v0411p005E*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54-YB WLAN
+
+usb:v0411p0065*
+ ID_PRODUCT_FROM_DATABASE=Python2 WDM Encoder
+
+usb:v0411p0066*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54 WLAN
+
+usb:v0411p0067*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54-AI WLAN
+
+usb:v0411p006E*
+ ID_PRODUCT_FROM_DATABASE=LUA-U2-GT 10/100/1000 Ethernet Adapter
+
+usb:v0411p0089*
+ ID_PRODUCT_FROM_DATABASE=RUF-C/U2 Flash Drive
+
+usb:v0411p008B*
+ ID_PRODUCT_FROM_DATABASE=Nintendo Wi-Fi
+
+usb:v0411p0091*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-KAMG54 Wireless LAN Adapter
+
+usb:v0411p0092*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-KAMG54 Bootloader
+
+usb:v0411p0097*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54-BB
+
+usb:v0411p00A9*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-AMG54HP Wireless LAN Adapter
+
+usb:v0411p00AA*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-AMG54HP Bootloader
+
+usb:v0411p00B3*
+ ID_PRODUCT_FROM_DATABASE=PC-OP-RS1 RemoteStation
+
+usb:v0411p00BC*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-KG125S 802.11g Adapter [Broadcom 4320 USB]
+
+usb:v0411p00CA*
+ ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter
+
+usb:v0411p00CB*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-G300N 802.11n Adapter
+
+usb:v0411p00D8*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-SG54HP
+
+usb:v0411p00D9*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-G54HP
+
+usb:v0411p00DA*
+ ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54L 802.11bg [ZyDAS ZD1211B]
+
+usb:v0411p00DB*
+ ID_PRODUCT_FROM_DATABASE=External Hard Drive HD-PF32OU2 [Buffalo Ministation]
+
+usb:v0411p00E8*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-G300N Wireless LAN Adapter [Ralink RT2870]
+
+usb:v0411p012E*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-AG300N Wireless LAN Adapter
+
+usb:v0411p0148*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-G300HP Wireless LAN Adapter
+
+usb:v0411p0150*
+ ID_PRODUCT_FROM_DATABASE=WLP-UC-AG300 Wireless LAN Adapter
+
+usb:v0411p0157*
+ ID_PRODUCT_FROM_DATABASE=External Hard Drive HD-PEU2
+
+usb:v0411p0158*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-GNHP Wireless LAN Adapter
+
+usb:v0411p015D*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-GN Wireless LAN Adapter [Ralink RT3070]
+
+usb:v0411p016F*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-G301N Wireless LAN Adapter [Ralink RT3072]
+
+usb:v0411p017F*
+ ID_PRODUCT_FROM_DATABASE=Sony UWA-BR100 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]
+
+usb:v0411p019E*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-GNP Wireless LAN Adapter
+
+usb:v0411p01A1*
+ ID_PRODUCT_FROM_DATABASE=MiniStation Metro
+
+usb:v0411p01A2*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070]
+
+usb:v0411p01DC*
+ ID_PRODUCT_FROM_DATABASE=Ultra-Slim Portable DVD Writer (DVSM-PC58U2V)
+
+usb:v0411p01DE*
+ ID_PRODUCT_FROM_DATABASE=External Hard Drive HD-PCTU3 [Buffalo MiniStation]
+
+usb:v0411p01EE*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-GNM2 Wireless LAN Adapter [Ralink RT3070]
+
+usb:v0411p01F1*
+ ID_PRODUCT_FROM_DATABASE=SATA Adapter [HD-LBU3]
+
+usb:v0411p01FD*
+ ID_PRODUCT_FROM_DATABASE=WLI-UC-G450 Wireless LAN Adapter
+
+usb:v0412*
+ ID_VENDOR_FROM_DATABASE=Award Software International
+
+usb:v0413*
+ ID_VENDOR_FROM_DATABASE=Leadtek Research, Inc.
+
+usb:v0413p1310*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC + FM
+
+usb:v0413p1311*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC + MTS + FM
+
+usb:v0413p1312*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL BG + FM
+
+usb:v0413p1313*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL BG+TXT + FM
+
+usb:v0413p1314*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL I
+
+usb:v0413p1315*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL I+TXT
+
+usb:v0413p1316*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL DK
+
+usb:v0413p1317*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL DK+TXT
+
+usb:v0413p1318*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL I/DK + FM
+
+usb:v0413p1319*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL N + FM
+
+usb:v0413p131A*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM LL
+
+usb:v0413p131B*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM LL+TXT
+
+usb:v0413p131C*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM DK
+
+usb:v0413p131D*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - SECAM DK + TXT + FM
+
+usb:v0413p131E*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC Japan + FM
+
+usb:v0413p1320*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC
+
+usb:v0413p1321*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC + MTS
+
+usb:v0413p1322*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL BG
+
+usb:v0413p1323*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL BG+TXT
+
+usb:v0413p1324*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL I
+
+usb:v0413p1325*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL I+TXT
+
+usb:v0413p1326*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL DK
+
+usb:v0413p1327*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL DK+TXT
+
+usb:v0413p1328*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL I/DK
+
+usb:v0413p1329*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL N
+
+usb:v0413p132A*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM LL
+
+usb:v0413p132B*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM LL+TXT
+
+usb:v0413p132C*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM DK
+
+usb:v0413p132D*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - SECAM DK + TXT
+
+usb:v0413p132E*
+ ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC Japan
+
+usb:v0413p6023*
+ ID_PRODUCT_FROM_DATABASE=EMP Audio Device
+
+usb:v0413p6024*
+ ID_PRODUCT_FROM_DATABASE=WinFast PalmTop/Novo TV Video
+
+usb:v0413p6025*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle (cold state)
+
+usb:v0413p6026*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle (warm state)
+
+usb:v0413p6029*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle Gold
+
+usb:v0413p6125*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle
+
+usb:v0413p6126*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle BDA Driver
+
+usb:v0413p6A03*
+ ID_PRODUCT_FROM_DATABASE=RTL2832 [WinFast DTV Dongle Mini]
+
+usb:v0413p6F00*
+ ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle (STK7700P based)
+
+usb:v0414*
+ ID_VENDOR_FROM_DATABASE=Giga-Byte Technology Co., Ltd
+
+usb:v0416*
+ ID_VENDOR_FROM_DATABASE=Winbond Electronics Corp.
+
+usb:v0416p0035*
+ ID_PRODUCT_FROM_DATABASE=W89C35 802.11bg WLAN Adapter
+
+usb:v0416p0101*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0416p0961*
+ ID_PRODUCT_FROM_DATABASE=AVL Flash Card Reader
+
+usb:v0416p3810*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Controller
+
+usb:v0416p3811*
+ ID_PRODUCT_FROM_DATABASE=Generic Controller - Single interface
+
+usb:v0416p3812*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Controller_2Interface
+
+usb:v0416p3813*
+ ID_PRODUCT_FROM_DATABASE=Panel Display
+
+usb:v0416p5518*
+ ID_PRODUCT_FROM_DATABASE=4-Port Hub
+
+usb:v0416p551A*
+ ID_PRODUCT_FROM_DATABASE=PC Sync Keypad
+
+usb:v0416p551B*
+ ID_PRODUCT_FROM_DATABASE=PC Async Keypad
+
+usb:v0416p551C*
+ ID_PRODUCT_FROM_DATABASE=Sync Tenkey
+
+usb:v0416p551D*
+ ID_PRODUCT_FROM_DATABASE=Async Tenkey
+
+usb:v0416p551E*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0416p551F*
+ ID_PRODUCT_FROM_DATABASE=Keyboard w/ Sys and Media
+
+usb:v0416p5521*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0416p6481*
+ ID_PRODUCT_FROM_DATABASE=16-bit Scanner
+
+usb:v0416p7721*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v0416p7722*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v0416p7723*
+ ID_PRODUCT_FROM_DATABASE=SD Card Reader
+
+usb:v0417*
+ ID_VENDOR_FROM_DATABASE=Symbios Logic
+
+usb:v0418*
+ ID_VENDOR_FROM_DATABASE=AST Research
+
+usb:v0419*
+ ID_VENDOR_FROM_DATABASE=Samsung Info. Systems America, Inc.
+
+usb:v0419p0001*
+ ID_PRODUCT_FROM_DATABASE=IrDA Remote Controller / Creative Cordless Mouse
+
+usb:v0419p0600*
+ ID_PRODUCT_FROM_DATABASE=Desktop Wireless 6000
+
+usb:v0419p3001*
+ ID_PRODUCT_FROM_DATABASE=Xerox P1202 Laser Printer
+
+usb:v0419p3003*
+ ID_PRODUCT_FROM_DATABASE=Olivetti PG L12L
+
+usb:v0419p3201*
+ ID_PRODUCT_FROM_DATABASE=Docuprint P8ex
+
+usb:v0419p3404*
+ ID_PRODUCT_FROM_DATABASE=SCX-5x12 series
+
+usb:v0419p3406*
+ ID_PRODUCT_FROM_DATABASE=MFP 830 series
+
+usb:v0419p3407*
+ ID_PRODUCT_FROM_DATABASE=ML-912
+
+usb:v0419p3601*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v0419p3602*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v0419p4602*
+ ID_PRODUCT_FROM_DATABASE=Remote NDIS Network Device
+
+usb:v0419p8001*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0419p8002*
+ ID_PRODUCT_FROM_DATABASE=SyncMaster HID Monitor Control
+
+usb:v0419pAA03*
+ ID_PRODUCT_FROM_DATABASE=SDAS-3 MP3 Player
+
+usb:v041A*
+ ID_VENDOR_FROM_DATABASE=Phoenix Technologies, Ltd
+
+usb:v041B*
+ ID_VENDOR_FROM_DATABASE=d'TV
+
+usb:v041D*
+ ID_VENDOR_FROM_DATABASE=S3, Inc.
+
+usb:v041E*
+ ID_VENDOR_FROM_DATABASE=Creative Technology, Ltd
+
+usb:v041Ep1002*
+ ID_PRODUCT_FROM_DATABASE=Nomad II
+
+usb:v041Ep1003*
+ ID_PRODUCT_FROM_DATABASE=Blaster GamePad Cobra
+
+usb:v041Ep1050*
+ ID_PRODUCT_FROM_DATABASE=GamePad Cobra
+
+usb:v041Ep1053*
+ ID_PRODUCT_FROM_DATABASE=Mouse Gamer HD7600L
+
+usb:v041Ep200C*
+ ID_PRODUCT_FROM_DATABASE=MuVo V100
+
+usb:v041Ep2020*
+ ID_PRODUCT_FROM_DATABASE=Zen X-Fi 2
+
+usb:v041Ep2029*
+ ID_PRODUCT_FROM_DATABASE=ZiiO
+
+usb:v041Ep2801*
+ ID_PRODUCT_FROM_DATABASE=Prodikeys PC-MIDI multifunction keyboard
+
+usb:v041Ep3000*
+ ID_PRODUCT_FROM_DATABASE=SoundBlaster Extigy
+
+usb:v041Ep3002*
+ ID_PRODUCT_FROM_DATABASE=SB External Composite Device
+
+usb:v041Ep3010*
+ ID_PRODUCT_FROM_DATABASE=SoundBlaster MP3+
+
+usb:v041Ep3014*
+ ID_PRODUCT_FROM_DATABASE=SB External Composite Device
+
+usb:v041Ep3015*
+ ID_PRODUCT_FROM_DATABASE=Sound Blaster Digital Music LX
+
+usb:v041Ep3020*
+ ID_PRODUCT_FROM_DATABASE=SoundBlaster Audigy 2 NX
+
+usb:v041Ep3030*
+ ID_PRODUCT_FROM_DATABASE=SB External Composite Device
+
+usb:v041Ep3040*
+ ID_PRODUCT_FROM_DATABASE=SoundBlaster Live! 24-bit External SB0490
+
+usb:v041Ep3060*
+ ID_PRODUCT_FROM_DATABASE=Sound Blaster Audigy 2 ZS External
+
+usb:v041Ep3061*
+ ID_PRODUCT_FROM_DATABASE=SoundBlaster Audigy 2 ZS Video Editor
+
+usb:v041Ep3090*
+ ID_PRODUCT_FROM_DATABASE=Sound Blaster Digital Music SX
+
+usb:v041Ep30D3*
+ ID_PRODUCT_FROM_DATABASE=Sound Blaster Play!
+
+usb:v041Ep3121*
+ ID_PRODUCT_FROM_DATABASE=WoW tap chat
+
+usb:v041Ep3F00*
+ ID_PRODUCT_FROM_DATABASE=E-Mu Xboard 25 MIDI Controller
+
+usb:v041Ep3F02*
+ ID_PRODUCT_FROM_DATABASE=E-Mu 0202
+
+usb:v041Ep3F04*
+ ID_PRODUCT_FROM_DATABASE=E-Mu 0404
+
+usb:v041Ep3F07*
+ ID_PRODUCT_FROM_DATABASE=E-Mu Xmidi 1x1
+
+usb:v041Ep4003*
+ ID_PRODUCT_FROM_DATABASE=VideoBlaster Webcam Go Plus [W9967CF]
+
+usb:v041Ep4004*
+ ID_PRODUCT_FROM_DATABASE=Nomad II MG
+
+usb:v041Ep4005*
+ ID_PRODUCT_FROM_DATABASE=Webcam Blaster Go ES
+
+usb:v041Ep4007*
+ ID_PRODUCT_FROM_DATABASE=Go Mini
+
+usb:v041Ep400A*
+ ID_PRODUCT_FROM_DATABASE=PC-Cam 300
+
+usb:v041Ep400B*
+ ID_PRODUCT_FROM_DATABASE=PC-Cam 600
+
+usb:v041Ep400C*
+ ID_PRODUCT_FROM_DATABASE=Webcam 5 [pwc]
+
+usb:v041Ep400D*
+ ID_PRODUCT_FROM_DATABASE=Webcam PD1001
+
+usb:v041Ep400F*
+ ID_PRODUCT_FROM_DATABASE=PC-CAM 550 (Composite)
+
+usb:v041Ep4011*
+ ID_PRODUCT_FROM_DATABASE=Webcam PRO eX
+
+usb:v041Ep4012*
+ ID_PRODUCT_FROM_DATABASE=PC-CAM350
+
+usb:v041Ep4013*
+ ID_PRODUCT_FROM_DATABASE=PC-Cam 750
+
+usb:v041Ep4015*
+ ID_PRODUCT_FROM_DATABASE=CardCam Value
+
+usb:v041Ep4016*
+ ID_PRODUCT_FROM_DATABASE=CardCam
+
+usb:v041Ep4017*
+ ID_PRODUCT_FROM_DATABASE=Webcam Mobile [PD1090]
+
+usb:v041Ep4018*
+ ID_PRODUCT_FROM_DATABASE=Webcam Vista [PD1100]
+
+usb:v041Ep4019*
+ ID_PRODUCT_FROM_DATABASE=Audio Device
+
+usb:v041Ep401A*
+ ID_PRODUCT_FROM_DATABASE=Webcam Vista [PD1100]
+
+usb:v041Ep401C*
+ ID_PRODUCT_FROM_DATABASE=Webcam NX [PD1110]
+
+usb:v041Ep401D*
+ ID_PRODUCT_FROM_DATABASE=Webcam NX Ultra
+
+usb:v041Ep401E*
+ ID_PRODUCT_FROM_DATABASE=Webcam NX Pro
+
+usb:v041Ep401F*
+ ID_PRODUCT_FROM_DATABASE=Webcam Notebook [PD1171]
+
+usb:v041Ep4020*
+ ID_PRODUCT_FROM_DATABASE=Webcam NX
+
+usb:v041Ep4021*
+ ID_PRODUCT_FROM_DATABASE=Webcam NX Ultra
+
+usb:v041Ep4022*
+ ID_PRODUCT_FROM_DATABASE=Webcam NX Pro
+
+usb:v041Ep4028*
+ ID_PRODUCT_FROM_DATABASE=Vista Plus cam [VF0090]
+
+usb:v041Ep4029*
+ ID_PRODUCT_FROM_DATABASE=Webcam Live!
+
+usb:v041Ep402F*
+ ID_PRODUCT_FROM_DATABASE=DC-CAM 3000Z
+
+usb:v041Ep4034*
+ ID_PRODUCT_FROM_DATABASE=Webcam Instant
+
+usb:v041Ep4035*
+ ID_PRODUCT_FROM_DATABASE=Webcam Instant
+
+usb:v041Ep4036*
+ ID_PRODUCT_FROM_DATABASE=Webcam Live!/Live! Pro
+
+usb:v041Ep4037*
+ ID_PRODUCT_FROM_DATABASE=Webcam Live!
+
+usb:v041Ep4038*
+ ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam [PC370R]
+
+usb:v041Ep4039*
+ ID_PRODUCT_FROM_DATABASE=Webcam Live! Effects
+
+usb:v041Ep403A*
+ ID_PRODUCT_FROM_DATABASE=Webcam NX Pro 2
+
+usb:v041Ep403B*
+ ID_PRODUCT_FROM_DATABASE=Creative Webcam Vista [VF0010]
+
+usb:v041Ep403C*
+ ID_PRODUCT_FROM_DATABASE=Webcam Live! Ultra
+
+usb:v041Ep403D*
+ ID_PRODUCT_FROM_DATABASE=Webcam Notebook Ultra
+
+usb:v041Ep403E*
+ ID_PRODUCT_FROM_DATABASE=Webcam Vista Plus
+
+usb:v041Ep4041*
+ ID_PRODUCT_FROM_DATABASE=Webcam Live! Motion
+
+usb:v041Ep4043*
+ ID_PRODUCT_FROM_DATABASE=Vibra Plus Webcam
+
+usb:v041Ep4045*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Voice
+
+usb:v041Ep4049*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Voice
+
+usb:v041Ep4051*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Notebook Pro [VF0250]
+
+usb:v041Ep4052*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Vista IM
+
+usb:v041Ep4053*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM
+
+usb:v041Ep4054*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM
+
+usb:v041Ep4055*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM Pro
+
+usb:v041Ep4056*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM Pro
+
+usb:v041Ep4057*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Optia
+
+usb:v041Ep4058*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Optia AF
+
+usb:v041Ep4061*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Notebook Pro [VF0400]
+
+usb:v041Ep4063*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM Pro
+
+usb:v041Ep4068*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Notebook [VF0470]
+
+usb:v041Ep406C*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Sync [VF0520]
+
+usb:v041Ep4083*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Socialize [VF0640]
+
+usb:v041Ep4087*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Socialize HD 1080 [VF0680]
+
+usb:v041Ep4088*
+ ID_PRODUCT_FROM_DATABASE=Live! Cam Chat HD [VF0700]
+
+usb:v041Ep4100*
+ ID_PRODUCT_FROM_DATABASE=Nomad Jukebox 2
+
+usb:v041Ep4101*
+ ID_PRODUCT_FROM_DATABASE=Nomad Jukebox 3
+
+usb:v041Ep4102*
+ ID_PRODUCT_FROM_DATABASE=NOMAD MuVo^2
+
+usb:v041Ep4106*
+ ID_PRODUCT_FROM_DATABASE=Nomad MuVo
+
+usb:v041Ep4107*
+ ID_PRODUCT_FROM_DATABASE=NOMAD MuVo
+
+usb:v041Ep4108*
+ ID_PRODUCT_FROM_DATABASE=Nomad Jukebox Zen
+
+usb:v041Ep4109*
+ ID_PRODUCT_FROM_DATABASE=Nomad Jukebox Zen NX
+
+usb:v041Ep410B*
+ ID_PRODUCT_FROM_DATABASE=Nomad Jukebox Zen USB 2.0
+
+usb:v041Ep410C*
+ ID_PRODUCT_FROM_DATABASE=Nomad MuVo NX
+
+usb:v041Ep410F*
+ ID_PRODUCT_FROM_DATABASE=NOMAD MuVo^2 (Flash)
+
+usb:v041Ep4110*
+ ID_PRODUCT_FROM_DATABASE=Nomad Jukebox Zen Xtra
+
+usb:v041Ep4111*
+ ID_PRODUCT_FROM_DATABASE=Dell Digital Jukebox
+
+usb:v041Ep4116*
+ ID_PRODUCT_FROM_DATABASE=MuVo^2
+
+usb:v041Ep4117*
+ ID_PRODUCT_FROM_DATABASE=Nomad MuVo TX
+
+usb:v041Ep411B*
+ ID_PRODUCT_FROM_DATABASE=Zen Touch
+
+usb:v041Ep411C*
+ ID_PRODUCT_FROM_DATABASE=Nomad MuVo USB 2.0
+
+usb:v041Ep411D*
+ ID_PRODUCT_FROM_DATABASE=Zen
+
+usb:v041Ep411E*
+ ID_PRODUCT_FROM_DATABASE=Zen Micro
+
+usb:v041Ep4120*
+ ID_PRODUCT_FROM_DATABASE=Nomad MuVo TX FM
+
+usb:v041Ep4123*
+ ID_PRODUCT_FROM_DATABASE=Zen Portable Media Center
+
+usb:v041Ep4124*
+ ID_PRODUCT_FROM_DATABASE=MuVo^2 FM (uHDD)
+
+usb:v041Ep4126*
+ ID_PRODUCT_FROM_DATABASE=Dell DJ (2nd gen)
+
+usb:v041Ep4127*
+ ID_PRODUCT_FROM_DATABASE=Dell DJ
+
+usb:v041Ep4128*
+ ID_PRODUCT_FROM_DATABASE=NOMAD Jukebox Zen Xtra (mtp)
+
+usb:v041Ep412B*
+ ID_PRODUCT_FROM_DATABASE=MuVo N200 with FM radio
+
+usb:v041Ep412F*
+ ID_PRODUCT_FROM_DATABASE=Dell Digital Jukebox 2.Gen
+
+usb:v041Ep4130*
+ ID_PRODUCT_FROM_DATABASE=Zen Micro (mtp)
+
+usb:v041Ep4131*
+ ID_PRODUCT_FROM_DATABASE=Zen Touch (mtp)
+
+usb:v041Ep4133*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v041Ep4134*
+ ID_PRODUCT_FROM_DATABASE=Zen Neeon
+
+usb:v041Ep4136*
+ ID_PRODUCT_FROM_DATABASE=Zen Sleek
+
+usb:v041Ep4137*
+ ID_PRODUCT_FROM_DATABASE=Zen Sleek (mtp)
+
+usb:v041Ep4139*
+ ID_PRODUCT_FROM_DATABASE=Zen Nano Plus
+
+usb:v041Ep413C*
+ ID_PRODUCT_FROM_DATABASE=Zen MicroPhoto
+
+usb:v041Ep4150*
+ ID_PRODUCT_FROM_DATABASE=Zen V (MTP)
+
+usb:v041Ep4151*
+ ID_PRODUCT_FROM_DATABASE=Zen Vision:M (mtp)
+
+usb:v041Ep4152*
+ ID_PRODUCT_FROM_DATABASE=Zen V Plus
+
+usb:v041Ep4153*
+ ID_PRODUCT_FROM_DATABASE=Zen Vision W
+
+usb:v041Ep4154*
+ ID_PRODUCT_FROM_DATABASE=Zen Stone
+
+usb:v041Ep4155*
+ ID_PRODUCT_FROM_DATABASE=Zen Stone plus
+
+usb:v041Ep4157*
+ ID_PRODUCT_FROM_DATABASE=Zen (MTP)
+
+usb:v041Ep500F*
+ ID_PRODUCT_FROM_DATABASE=Broadband Blaster 8012U-V
+
+usb:v041Ep5015*
+ ID_PRODUCT_FROM_DATABASE=TECOM Bluetooth Device
+
+usb:v041EpFFFF*
+ ID_PRODUCT_FROM_DATABASE=Webcam Live! Ultra
+
+usb:v041F*
+ ID_VENDOR_FROM_DATABASE=LCS Telegraphics
+
+usb:v0420*
+ ID_VENDOR_FROM_DATABASE=Chips and Technologies
+
+usb:v0420p1307*
+ ID_PRODUCT_FROM_DATABASE=Celly SIM Card Reader
+
+usb:v0421*
+ ID_VENDOR_FROM_DATABASE=Nokia Mobile Phones
+
+usb:v0421p0001*
+ ID_PRODUCT_FROM_DATABASE=E61i (PC Suite mode)
+
+usb:v0421p0018*
+ ID_PRODUCT_FROM_DATABASE=6288 GSM Smartphone
+
+usb:v0421p0019*
+ ID_PRODUCT_FROM_DATABASE=6288 GSM Smartphone (imaging mode)
+
+usb:v0421p001A*
+ ID_PRODUCT_FROM_DATABASE=6288 GSM Smartphone (file transfer mode)
+
+usb:v0421p0024*
+ ID_PRODUCT_FROM_DATABASE=5610 XpressMusic (Storage mode)
+
+usb:v0421p0025*
+ ID_PRODUCT_FROM_DATABASE=5610 XpressMusic (PC Suite mode)
+
+usb:v0421p0028*
+ ID_PRODUCT_FROM_DATABASE=5610 XpressMusic (Imaging mode)
+
+usb:v0421p002D*
+ ID_PRODUCT_FROM_DATABASE=6120 Phone (Mass storage mode)
+
+usb:v0421p002E*
+ ID_PRODUCT_FROM_DATABASE=6120 Phone (Media-Player mode)
+
+usb:v0421p002F*
+ ID_PRODUCT_FROM_DATABASE=6120 Phone (PC-Suite mode)
+
+usb:v0421p0042*
+ ID_PRODUCT_FROM_DATABASE=E51 (PC Suite mode)
+
+usb:v0421p0064*
+ ID_PRODUCT_FROM_DATABASE=3109c GSM Phone
+
+usb:v0421p006B*
+ ID_PRODUCT_FROM_DATABASE=5310 Xpress Music (PC Suite mode)
+
+usb:v0421p006C*
+ ID_PRODUCT_FROM_DATABASE=5310 Xpress music (Storage mode)
+
+usb:v0421p006D*
+ ID_PRODUCT_FROM_DATABASE=N95 (Storage mode)
+
+usb:v0421p006E*
+ ID_PRODUCT_FROM_DATABASE=N95 (Multimedia mode)
+
+usb:v0421p006F*
+ ID_PRODUCT_FROM_DATABASE=N95 (Printing mode)
+
+usb:v0421p0070*
+ ID_PRODUCT_FROM_DATABASE=N95 (PC Suite mode)
+
+usb:v0421p0096*
+ ID_PRODUCT_FROM_DATABASE=N810 Internet Tablet
+
+usb:v0421p00AA*
+ ID_PRODUCT_FROM_DATABASE=E71 (Mass storage mode)
+
+usb:v0421p00AB*
+ ID_PRODUCT_FROM_DATABASE=E71 (PC Suite mode)
+
+usb:v0421p00E4*
+ ID_PRODUCT_FROM_DATABASE=E71 (Media transfer mode)
+
+usb:v0421p0103*
+ ID_PRODUCT_FROM_DATABASE=ADL Flashing Engine AVALON Parent
+
+usb:v0421p0104*
+ ID_PRODUCT_FROM_DATABASE=ADL Re-Flashing Engine Parent
+
+usb:v0421p0105*
+ ID_PRODUCT_FROM_DATABASE=Nokia Firmware Upgrade Mode
+
+usb:v0421p0106*
+ ID_PRODUCT_FROM_DATABASE=ROM Parent
+
+usb:v0421p0154*
+ ID_PRODUCT_FROM_DATABASE=5800 XpressMusic (PC Suite mode)
+
+usb:v0421p0155*
+ ID_PRODUCT_FROM_DATABASE=5800 XpressMusic (Multimedia mode)
+
+usb:v0421p0156*
+ ID_PRODUCT_FROM_DATABASE=5800 XpressMusic (Storage mode)
+
+usb:v0421p0157*
+ ID_PRODUCT_FROM_DATABASE=5800 XpressMusic (Imaging mode)
+
+usb:v0421p0199*
+ ID_PRODUCT_FROM_DATABASE=6700 Classic (msc)
+
+usb:v0421p019A*
+ ID_PRODUCT_FROM_DATABASE=6700 Classic (PC Suite)
+
+usb:v0421p019B*
+ ID_PRODUCT_FROM_DATABASE=6700 Classic (mtp)
+
+usb:v0421p01B0*
+ ID_PRODUCT_FROM_DATABASE=6303 classic Phone (PC Suite mode)
+
+usb:v0421p01B1*
+ ID_PRODUCT_FROM_DATABASE=6303 classic Phone (Mass storage mode)
+
+usb:v0421p01B2*
+ ID_PRODUCT_FROM_DATABASE=6303 classic Phone (Printing and media mode)
+
+usb:v0421p01C7*
+ ID_PRODUCT_FROM_DATABASE=N900 (Storage Mode)
+
+usb:v0421p01C8*
+ ID_PRODUCT_FROM_DATABASE=N900 (PC-Suite Mode)
+
+usb:v0421p0228*
+ ID_PRODUCT_FROM_DATABASE=5530 XpressMusic
+
+usb:v0421p023A*
+ ID_PRODUCT_FROM_DATABASE=6730 Classic
+
+usb:v0421p026A*
+ ID_PRODUCT_FROM_DATABASE=N97 (mass storage)
+
+usb:v0421p026B*
+ ID_PRODUCT_FROM_DATABASE=N97 (Multimedia)
+
+usb:v0421p026C*
+ ID_PRODUCT_FROM_DATABASE=N97 (PC Suite)
+
+usb:v0421p026D*
+ ID_PRODUCT_FROM_DATABASE=N97 (Pictures)
+
+usb:v0421p0295*
+ ID_PRODUCT_FROM_DATABASE=660i/6600i Slide Phone (Mass Storage)
+
+usb:v0421p0297*
+ ID_PRODUCT_FROM_DATABASE=660i/6600i Slide Phone (Still Image)
+
+usb:v0421p02E1*
+ ID_PRODUCT_FROM_DATABASE=5230 (Storage mode)
+
+usb:v0421p02E2*
+ ID_PRODUCT_FROM_DATABASE=5230 (Multimedia mode)
+
+usb:v0421p02E3*
+ ID_PRODUCT_FROM_DATABASE=5230 (PC-Suite mode)
+
+usb:v0421p02E4*
+ ID_PRODUCT_FROM_DATABASE=5230 (Imaging mode)
+
+usb:v0421p0360*
+ ID_PRODUCT_FROM_DATABASE=C1-01 Ovi Suite Mode
+
+usb:v0421p03A4*
+ ID_PRODUCT_FROM_DATABASE=C5 (Storage mode)
+
+usb:v0421p03C0*
+ ID_PRODUCT_FROM_DATABASE=C7-00
+
+usb:v0421p03D1*
+ ID_PRODUCT_FROM_DATABASE=N950
+
+usb:v0421p0400*
+ ID_PRODUCT_FROM_DATABASE=7600 Phone Parent
+
+usb:v0421p0401*
+ ID_PRODUCT_FROM_DATABASE=6650 GSM Phone
+
+usb:v0421p0402*
+ ID_PRODUCT_FROM_DATABASE=6255 Phone Parent
+
+usb:v0421p0404*
+ ID_PRODUCT_FROM_DATABASE=5510
+
+usb:v0421p0405*
+ ID_PRODUCT_FROM_DATABASE=9500 GSM Communicator
+
+usb:v0421p0407*
+ ID_PRODUCT_FROM_DATABASE=Music Player HDR-1(tm)
+
+usb:v0421p040B*
+ ID_PRODUCT_FROM_DATABASE=N-Gage GSM Phone
+
+usb:v0421p040D*
+ ID_PRODUCT_FROM_DATABASE=6620 Phone Parent
+
+usb:v0421p040E*
+ ID_PRODUCT_FROM_DATABASE=6651 Phone Parent
+
+usb:v0421p040F*
+ ID_PRODUCT_FROM_DATABASE=6230 GSM Phone
+
+usb:v0421p0410*
+ ID_PRODUCT_FROM_DATABASE=6630 Imaging Smartphone
+
+usb:v0421p0411*
+ ID_PRODUCT_FROM_DATABASE=7610 Phone Parent
+
+usb:v0421p0413*
+ ID_PRODUCT_FROM_DATABASE=6260 Phone Parent
+
+usb:v0421p0414*
+ ID_PRODUCT_FROM_DATABASE=7370
+
+usb:v0421p0415*
+ ID_PRODUCT_FROM_DATABASE=9300 GSM Smartphone
+
+usb:v0421p0416*
+ ID_PRODUCT_FROM_DATABASE=6170 Phone Parent
+
+usb:v0421p0417*
+ ID_PRODUCT_FROM_DATABASE=7270 Phone Parent
+
+usb:v0421p0418*
+ ID_PRODUCT_FROM_DATABASE=E70 (PC Suite mode)
+
+usb:v0421p0419*
+ ID_PRODUCT_FROM_DATABASE=E60 (PC Suite mode)
+
+usb:v0421p041A*
+ ID_PRODUCT_FROM_DATABASE=9500 GSM Communicator (RNDIS)
+
+usb:v0421p041B*
+ ID_PRODUCT_FROM_DATABASE=9300 GSM Smartphone (RNDIS)
+
+usb:v0421p041C*
+ ID_PRODUCT_FROM_DATABASE=7710 Phone Parent
+
+usb:v0421p041D*
+ ID_PRODUCT_FROM_DATABASE=6670 Phone Parent
+
+usb:v0421p041E*
+ ID_PRODUCT_FROM_DATABASE=6680
+
+usb:v0421p041F*
+ ID_PRODUCT_FROM_DATABASE=6235 Phone Parent
+
+usb:v0421p0421*
+ ID_PRODUCT_FROM_DATABASE=3230 Phone Parent
+
+usb:v0421p0422*
+ ID_PRODUCT_FROM_DATABASE=6681 Phone Parent
+
+usb:v0421p0423*
+ ID_PRODUCT_FROM_DATABASE=6682 Phone Parent
+
+usb:v0421p0428*
+ ID_PRODUCT_FROM_DATABASE=6230i Modem
+
+usb:v0421p0429*
+ ID_PRODUCT_FROM_DATABASE=6230i MultiMedia Card
+
+usb:v0421p0431*
+ ID_PRODUCT_FROM_DATABASE=770 Internet Tablet
+
+usb:v0421p0432*
+ ID_PRODUCT_FROM_DATABASE=N90 Phone Parent
+
+usb:v0421p0435*
+ ID_PRODUCT_FROM_DATABASE=E70 (IP Passthrough/RNDIS mode)
+
+usb:v0421p0436*
+ ID_PRODUCT_FROM_DATABASE=E60 (IP Passthrough/RNDIS mode)
+
+usb:v0421p0437*
+ ID_PRODUCT_FROM_DATABASE=6265 Phone Parent
+
+usb:v0421p043A*
+ ID_PRODUCT_FROM_DATABASE=N70 USB Phone Parent
+
+usb:v0421p043B*
+ ID_PRODUCT_FROM_DATABASE=3155 Phone Parent
+
+usb:v0421p043C*
+ ID_PRODUCT_FROM_DATABASE=6155 Phone Parent
+
+usb:v0421p043D*
+ ID_PRODUCT_FROM_DATABASE=6270 Phone Parent
+
+usb:v0421p0443*
+ ID_PRODUCT_FROM_DATABASE=N70 Phone Parent
+
+usb:v0421p0444*
+ ID_PRODUCT_FROM_DATABASE=N91
+
+usb:v0421p044C*
+ ID_PRODUCT_FROM_DATABASE=NM850iG Phone Parent
+
+usb:v0421p044D*
+ ID_PRODUCT_FROM_DATABASE=E61 (PC Suite mode)
+
+usb:v0421p044E*
+ ID_PRODUCT_FROM_DATABASE=E61 (Data Exchange mode)
+
+usb:v0421p044F*
+ ID_PRODUCT_FROM_DATABASE=E61 (IP Passthrough/RNDIS mode)
+
+usb:v0421p0453*
+ ID_PRODUCT_FROM_DATABASE=9300 Phone Parent
+
+usb:v0421p0456*
+ ID_PRODUCT_FROM_DATABASE=6111 Phone Parent
+
+usb:v0421p0457*
+ ID_PRODUCT_FROM_DATABASE=6111 Phone (Printing mode)
+
+usb:v0421p045A*
+ ID_PRODUCT_FROM_DATABASE=6280 Phone Parent
+
+usb:v0421p045D*
+ ID_PRODUCT_FROM_DATABASE=6282 Phone Parent
+
+usb:v0421p046E*
+ ID_PRODUCT_FROM_DATABASE=6110 Navigator
+
+usb:v0421p0471*
+ ID_PRODUCT_FROM_DATABASE=6110 Navigator
+
+usb:v0421p0485*
+ ID_PRODUCT_FROM_DATABASE=MTP Device
+
+usb:v0421p04B9*
+ ID_PRODUCT_FROM_DATABASE=5300
+
+usb:v0421p04C3*
+ ID_PRODUCT_FROM_DATABASE=N800 Internet Tablet
+
+usb:v0421p04CE*
+ ID_PRODUCT_FROM_DATABASE=E90 Communicator (PC Suite mode)
+
+usb:v0421p04CF*
+ ID_PRODUCT_FROM_DATABASE=E90 Communicator (Storage mode)
+
+usb:v0421p04F0*
+ ID_PRODUCT_FROM_DATABASE=Nokia N95 (PC Suite mode)
+
+usb:v0421p04F9*
+ ID_PRODUCT_FROM_DATABASE=6300 (PC Suite mode)
+
+usb:v0421p0508*
+ ID_PRODUCT_FROM_DATABASE=E65 (PC Suite mode)
+
+usb:v0421p0509*
+ ID_PRODUCT_FROM_DATABASE=E65 (Storage mode)
+
+usb:v0421p0518*
+ ID_PRODUCT_FROM_DATABASE=N9 Phone
+
+usb:v0421p0600*
+ ID_PRODUCT_FROM_DATABASE=Digital Pen SU-1B
+
+usb:v0421p0610*
+ ID_PRODUCT_FROM_DATABASE=CS-15 (Internet Stick 3G modem)
+
+usb:v0421p0800*
+ ID_PRODUCT_FROM_DATABASE=Connectivity Cable DKU-5
+
+usb:v0421p0801*
+ ID_PRODUCT_FROM_DATABASE=Data Cable DKU-6
+
+usb:v0421p0802*
+ ID_PRODUCT_FROM_DATABASE=CA-42 Phone Parent
+
+usb:v0422*
+ ID_VENDOR_FROM_DATABASE=ADI Systems, Inc.
+
+usb:v0423*
+ ID_VENDOR_FROM_DATABASE=Computer Access Technology Corp.
+
+usb:v0423p000A*
+ ID_PRODUCT_FROM_DATABASE=NetMate Ethernet
+
+usb:v0423p000C*
+ ID_PRODUCT_FROM_DATABASE=NetMate2 Ethernet
+
+usb:v0423p000D*
+ ID_PRODUCT_FROM_DATABASE=USB Chief Analyzer
+
+usb:v0423p0100*
+ ID_PRODUCT_FROM_DATABASE=Generic Universal Protocol Analyzer
+
+usb:v0423p0101*
+ ID_PRODUCT_FROM_DATABASE=UPA USBTracer
+
+usb:v0423p0200*
+ ID_PRODUCT_FROM_DATABASE=Generic 10K Universal Protocol Analyzer
+
+usb:v0423p020A*
+ ID_PRODUCT_FROM_DATABASE=PETracer ML
+
+usb:v0423p0300*
+ ID_PRODUCT_FROM_DATABASE=Generic Universal Protocol Analyzer
+
+usb:v0423p0301*
+ ID_PRODUCT_FROM_DATABASE=2500H Tracer Trainer
+
+usb:v0423p030A*
+ ID_PRODUCT_FROM_DATABASE=PETracer x1
+
+usb:v0423p1237*
+ ID_PRODUCT_FROM_DATABASE=Andromeda Hub
+
+usb:v0424*
+ ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp.
+
+usb:v0424p0001*
+ ID_PRODUCT_FROM_DATABASE=Integrated Hub
+
+usb:v0424p0ACD*
+ ID_PRODUCT_FROM_DATABASE=Sitecom Internal Multi Memory reader/writer MD-005
+
+usb:v0424p0FDC*
+ ID_PRODUCT_FROM_DATABASE=Floppy
+
+usb:v0424p10CD*
+ ID_PRODUCT_FROM_DATABASE=Sitecom Internal Multi Memory reader/writer MD-005
+
+usb:v0424p2020*
+ ID_PRODUCT_FROM_DATABASE=USB Hub
+
+usb:v0424p20CD*
+ ID_PRODUCT_FROM_DATABASE=Sitecom Internal Multi Memory reader/writer MD-005
+
+usb:v0424p20FC*
+ ID_PRODUCT_FROM_DATABASE=6-in-1 Card Reader
+
+usb:v0424p2228*
+ ID_PRODUCT_FROM_DATABASE=9-in-2 Card Reader
+
+usb:v0424p223A*
+ ID_PRODUCT_FROM_DATABASE=8-in-1 Card Reader
+
+usb:v0424p2503*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v0424p2504*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v0424p2512*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v0424p2513*
+ ID_PRODUCT_FROM_DATABASE=2.0 Hub
+
+usb:v0424p2514*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v0424p2517*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0424p2524*
+ ID_PRODUCT_FROM_DATABASE=USB MultiSwitch Hub
+
+usb:v0424p2602*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v0424p2640*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v0424p4060*
+ ID_PRODUCT_FROM_DATABASE=Ultra Fast Media Reader
+
+usb:v0424p4064*
+ ID_PRODUCT_FROM_DATABASE=Ultra Fast Media Reader
+
+usb:v0424p9512*
+ ID_PRODUCT_FROM_DATABASE=LAN9500 Ethernet 10/100 Adapter
+
+usb:v0424pA700*
+ ID_PRODUCT_FROM_DATABASE=2 Port Hub
+
+usb:v0425*
+ ID_VENDOR_FROM_DATABASE=Motorola Semiconductors HK, Ltd
+
+usb:v0425p0101*
+ ID_PRODUCT_FROM_DATABASE=G-Tech Wireless Mouse & Keyboard
+
+usb:v0425pF102*
+ ID_PRODUCT_FROM_DATABASE=G-Tech U+P Wireless Mouse
+
+usb:v0426*
+ ID_VENDOR_FROM_DATABASE=Integrated Device Technology, Inc.
+
+usb:v0426p0426*
+ ID_PRODUCT_FROM_DATABASE=WDM Driver
+
+usb:v0427*
+ ID_VENDOR_FROM_DATABASE=Motorola Electronics Taiwan, Ltd
+
+usb:v0428*
+ ID_VENDOR_FROM_DATABASE=Advanced Gravis Computer Tech, Ltd
+
+usb:v0428p4001*
+ ID_PRODUCT_FROM_DATABASE=GamePad Pro
+
+usb:v0429*
+ ID_VENDOR_FROM_DATABASE=Cirrus Logic
+
+usb:v042A*
+ ID_VENDOR_FROM_DATABASE=Ericsson Austrian, AG
+
+usb:v042B*
+ ID_VENDOR_FROM_DATABASE=Intel Corp.
+
+usb:v042Bp9316*
+ ID_PRODUCT_FROM_DATABASE=8x931Hx Customer Hub
+
+usb:v042C*
+ ID_VENDOR_FROM_DATABASE=Innovative Semiconductors, Inc.
+
+usb:v042D*
+ ID_VENDOR_FROM_DATABASE=Micronics
+
+usb:v042E*
+ ID_VENDOR_FROM_DATABASE=Acer, Inc.
+
+usb:v042Ep0380*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v042F*
+ ID_VENDOR_FROM_DATABASE=Molex, Inc.
+
+usb:v0430*
+ ID_VENDOR_FROM_DATABASE=Sun Microsystems, Inc.
+
+usb:v0430p0002*
+ ID_PRODUCT_FROM_DATABASE=109 Keyboard
+
+usb:v0430p0005*
+ ID_PRODUCT_FROM_DATABASE=Type 6 Keyboard
+
+usb:v0430p000A*
+ ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard
+
+usb:v0430p000B*
+ ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard
+
+usb:v0430p0082*
+ ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard
+
+usb:v0430p0083*
+ ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard
+
+usb:v0430p00A2*
+ ID_PRODUCT_FROM_DATABASE=Type 7 Keyboard
+
+usb:v0430p0100*
+ ID_PRODUCT_FROM_DATABASE=3-button Mouse
+
+usb:v0430p100E*
+ ID_PRODUCT_FROM_DATABASE=24.1" LCD Monitor v4 / FID-638 Mouse
+
+usb:v0430p36BA*
+ ID_PRODUCT_FROM_DATABASE=Bus Powered Hub
+
+usb:v0430pA101*
+ ID_PRODUCT_FROM_DATABASE=remote key/mouse for P3 chip
+
+usb:v0430pA102*
+ ID_PRODUCT_FROM_DATABASE=remote key/mouse/storage for P3 chip
+
+usb:v0430pA103*
+ ID_PRODUCT_FROM_DATABASE=remote storage for P3 chip
+
+usb:v0430pA4A2*
+ ID_PRODUCT_FROM_DATABASE=Ethernet (RNDIS and CDC ethernet)
+
+usb:v0430pCDAB*
+ ID_PRODUCT_FROM_DATABASE=Raritan KVM dongle
+
+usb:v0431*
+ ID_VENDOR_FROM_DATABASE=Itac Systems, Inc.
+
+usb:v0431p0100*
+ ID_PRODUCT_FROM_DATABASE=Mouse-Trak 3-button Track Ball
+
+usb:v0432*
+ ID_VENDOR_FROM_DATABASE=Unisys Corp.
+
+usb:v0433*
+ ID_VENDOR_FROM_DATABASE=Alps Electric, Inc.
+
+usb:v0433p1101*
+ ID_PRODUCT_FROM_DATABASE=IBM Game Controller
+
+usb:v0433pABAB*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0434*
+ ID_VENDOR_FROM_DATABASE=Samsung Info. Systems America, Inc.
+
+usb:v0435*
+ ID_VENDOR_FROM_DATABASE=Hyundai Electronics America
+
+usb:v0436*
+ ID_VENDOR_FROM_DATABASE=Taugagreining HF
+
+usb:v0436p0005*
+ ID_PRODUCT_FROM_DATABASE=CameraMate (DPCM_USB)
+
+usb:v0437*
+ ID_VENDOR_FROM_DATABASE=Framatome Connectors USA
+
+usb:v0438*
+ ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc.
+
+usb:v0439*
+ ID_VENDOR_FROM_DATABASE=Voice Technologies Group
+
+usb:v043D*
+ ID_VENDOR_FROM_DATABASE=Lexmark International, Inc.
+
+usb:v043Dp0001*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0002*
+ ID_PRODUCT_FROM_DATABASE=Optra E310 Printer
+
+usb:v043Dp0003*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0004*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0005*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0006*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0007*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0008*
+ ID_PRODUCT_FROM_DATABASE=Inkjet Color Printer
+
+usb:v043Dp0009*
+ ID_PRODUCT_FROM_DATABASE=Optra S2450 Printer
+
+usb:v043Dp000A*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp000B*
+ ID_PRODUCT_FROM_DATABASE=Inkjet Color Printer
+
+usb:v043Dp000C*
+ ID_PRODUCT_FROM_DATABASE=Optra E312 Printer
+
+usb:v043Dp000D*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp000E*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp000F*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0010*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0011*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0012*
+ ID_PRODUCT_FROM_DATABASE=Inkjet Color Printer
+
+usb:v043Dp0013*
+ ID_PRODUCT_FROM_DATABASE=Inkjet Color Printer
+
+usb:v043Dp0014*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0015*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0016*
+ ID_PRODUCT_FROM_DATABASE=Z12 Color Jetprinter
+
+usb:v043Dp0017*
+ ID_PRODUCT_FROM_DATABASE=Z32 printer
+
+usb:v043Dp0018*
+ ID_PRODUCT_FROM_DATABASE=Z52 Printer
+
+usb:v043Dp0019*
+ ID_PRODUCT_FROM_DATABASE=Forms Printer
+
+usb:v043Dp001A*
+ ID_PRODUCT_FROM_DATABASE=Z65 Printer
+
+usb:v043Dp001B*
+ ID_PRODUCT_FROM_DATABASE=InkJet Photo Printer
+
+usb:v043Dp001C*
+ ID_PRODUCT_FROM_DATABASE=Kodak Personal Picture Maker 200 Printer
+
+usb:v043Dp001D*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp001E*
+ ID_PRODUCT_FROM_DATABASE=InkJet Photo Printer
+
+usb:v043Dp001F*
+ ID_PRODUCT_FROM_DATABASE=Kodak Personal Picture Maker 200 Card Reader
+
+usb:v043Dp0020*
+ ID_PRODUCT_FROM_DATABASE=Z51 Printer
+
+usb:v043Dp0021*
+ ID_PRODUCT_FROM_DATABASE=Z33 Printer
+
+usb:v043Dp0022*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0023*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0024*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0025*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0026*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0027*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0028*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0029*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp002A*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp002B*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp002C*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp002D*
+ ID_PRODUCT_FROM_DATABASE=X70/X73 Scan/Print/Copy
+
+usb:v043Dp002E*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp002F*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0030*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0031*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0032*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0033*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0034*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0035*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0036*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0037*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0038*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0039*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp003A*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp003B*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp003C*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp003D*
+ ID_PRODUCT_FROM_DATABASE=X83 Scan/Print/Copy
+
+usb:v043Dp003E*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp003F*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0040*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0041*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0042*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0043*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0044*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0045*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0046*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0047*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0048*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp0049*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp004A*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp004B*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp004C*
+ ID_PRODUCT_FROM_DATABASE=Scan Print Copy
+
+usb:v043Dp004D*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp004E*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp004F*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0050*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0051*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0052*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp0053*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0054*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0057*
+ ID_PRODUCT_FROM_DATABASE=Z35 Printer
+
+usb:v043Dp0058*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v043Dp005A*
+ ID_PRODUCT_FROM_DATABASE=X63
+
+usb:v043Dp005C*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0060*
+ ID_PRODUCT_FROM_DATABASE=X74/X75 Scanner
+
+usb:v043Dp0061*
+ ID_PRODUCT_FROM_DATABASE=X74 Hub
+
+usb:v043Dp0065*
+ ID_PRODUCT_FROM_DATABASE=X5130
+
+usb:v043Dp0069*
+ ID_PRODUCT_FROM_DATABASE=X74/X75 Printer
+
+usb:v043Dp006D*
+ ID_PRODUCT_FROM_DATABASE=X125
+
+usb:v043Dp006E*
+ ID_PRODUCT_FROM_DATABASE=C510
+
+usb:v043Dp0072*
+ ID_PRODUCT_FROM_DATABASE=X6170 Printer
+
+usb:v043Dp0073*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0078*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp0079*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp007A*
+ ID_PRODUCT_FROM_DATABASE=Generic Hub
+
+usb:v043Dp007B*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp007C*
+ ID_PRODUCT_FROM_DATABASE=X1110/X1130/X1140/X1150/X1170/X1180/X1185
+
+usb:v043Dp007D*
+ ID_PRODUCT_FROM_DATABASE=Photo 3150
+
+usb:v043Dp008A*
+ ID_PRODUCT_FROM_DATABASE=4200 series
+
+usb:v043Dp008B*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp008C*
+ ID_PRODUCT_FROM_DATABASE=to CF/SM/SD/MS Card Reader
+
+usb:v043Dp008E*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp008F*
+ ID_PRODUCT_FROM_DATABASE=X422
+
+usb:v043Dp0093*
+ ID_PRODUCT_FROM_DATABASE=X5250
+
+usb:v043Dp0095*
+ ID_PRODUCT_FROM_DATABASE=E220 Printer
+
+usb:v043Dp0096*
+ ID_PRODUCT_FROM_DATABASE=2200 series
+
+usb:v043Dp0097*
+ ID_PRODUCT_FROM_DATABASE=P6250
+
+usb:v043Dp0098*
+ ID_PRODUCT_FROM_DATABASE=7100 series
+
+usb:v043Dp009E*
+ ID_PRODUCT_FROM_DATABASE=P910 series Human Interface Device
+
+usb:v043Dp009F*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp00A9*
+ ID_PRODUCT_FROM_DATABASE=IBM Infoprint 1410 MFP
+
+usb:v043Dp00AB*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp00B2*
+ ID_PRODUCT_FROM_DATABASE=3300 series
+
+usb:v043Dp00B8*
+ ID_PRODUCT_FROM_DATABASE=7300 series
+
+usb:v043Dp00B9*
+ ID_PRODUCT_FROM_DATABASE=8300 series
+
+usb:v043Dp00BA*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp00BB*
+ ID_PRODUCT_FROM_DATABASE=2300 series
+
+usb:v043Dp00BD*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v043Dp00BE*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v043Dp00BF*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v043Dp00C0*
+ ID_PRODUCT_FROM_DATABASE=6300 series
+
+usb:v043Dp00C1*
+ ID_PRODUCT_FROM_DATABASE=4300 series
+
+usb:v043Dp00C7*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v043Dp00C8*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v043Dp00C9*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v043Dp00CB*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v043Dp00CC*
+ ID_PRODUCT_FROM_DATABASE=E120(n)
+
+usb:v043Dp00D0*
+ ID_PRODUCT_FROM_DATABASE=9300 series
+
+usb:v043Dp00D3*
+ ID_PRODUCT_FROM_DATABASE=X340 Scanner
+
+usb:v043Dp00D4*
+ ID_PRODUCT_FROM_DATABASE=X342n Scanner
+
+usb:v043Dp00D5*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v043Dp00D6*
+ ID_PRODUCT_FROM_DATABASE=X340 Scanner
+
+usb:v043Dp00E8*
+ ID_PRODUCT_FROM_DATABASE=X642e
+
+usb:v043Dp00E9*
+ ID_PRODUCT_FROM_DATABASE=2400 series
+
+usb:v043Dp00F6*
+ ID_PRODUCT_FROM_DATABASE=3400 series
+
+usb:v043Dp00F7*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp00FF*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v043Dp010B*
+ ID_PRODUCT_FROM_DATABASE=2500 series
+
+usb:v043Dp010D*
+ ID_PRODUCT_FROM_DATABASE=3500-4500 series
+
+usb:v043Dp010F*
+ ID_PRODUCT_FROM_DATABASE=6500 series
+
+usb:v043Dp0142*
+ ID_PRODUCT_FROM_DATABASE=X3650 (Printer, Scanner, Copier)
+
+usb:v043Dp4303*
+ ID_PRODUCT_FROM_DATABASE=Xerox WorkCentre Pro 412
+
+usb:v043E*
+ ID_VENDOR_FROM_DATABASE=LG Electronics USA, Inc.
+
+usb:v043Ep3001*
+ ID_PRODUCT_FROM_DATABASE=AN-WF100 802.11abgn Wireless Adapter [Broadcom BCM4323]
+
+usb:v043Ep42BD*
+ ID_PRODUCT_FROM_DATABASE=Flatron 795FT Plus Monitor
+
+usb:v043Ep4A4D*
+ ID_PRODUCT_FROM_DATABASE=Flatron 915FT Plus Monitor
+
+usb:v043Ep7001*
+ ID_PRODUCT_FROM_DATABASE=MF-PD100 Soul Digital MP3 Player
+
+usb:v043Ep7013*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v043Ep8484*
+ ID_PRODUCT_FROM_DATABASE=LPC-U30 Webcam II
+
+usb:v043Ep8585*
+ ID_PRODUCT_FROM_DATABASE=LPC-UC35 Webcam
+
+usb:v043Ep8888*
+ ID_PRODUCT_FROM_DATABASE=Electronics VCS Camera II(LPC-U20)
+
+usb:v043Ep9800*
+ ID_PRODUCT_FROM_DATABASE=Remote Control Receiver_iMON
+
+usb:v043Ep9803*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v043Ep9804*
+ ID_PRODUCT_FROM_DATABASE=DMB Receiver Control
+
+usb:v043Ep9C01*
+ ID_PRODUCT_FROM_DATABASE=LGE Sync
+
+usb:v043F*
+ ID_VENDOR_FROM_DATABASE=RadiSys Corp.
+
+usb:v0440*
+ ID_VENDOR_FROM_DATABASE=Eizo Nanao Corp.
+
+usb:v0441*
+ ID_VENDOR_FROM_DATABASE=Winbond Systems Lab.
+
+usb:v0441p1456*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0442*
+ ID_VENDOR_FROM_DATABASE=Ericsson, Inc.
+
+usb:v0442pABBA*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0443*
+ ID_VENDOR_FROM_DATABASE=Gateway, Inc.
+
+usb:v0443p000E*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard
+
+usb:v0443p002E*
+ ID_PRODUCT_FROM_DATABASE=Millennium Keyboard
+
+usb:v0445*
+ ID_VENDOR_FROM_DATABASE=Lucent Technologies, Inc.
+
+usb:v0446*
+ ID_VENDOR_FROM_DATABASE=NMB Technologies Corp.
+
+usb:v0446p6781*
+ ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Mouse Port
+
+usb:v0446p6782*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0447*
+ ID_VENDOR_FROM_DATABASE=Momentum Microsystems
+
+usb:v044A*
+ ID_VENDOR_FROM_DATABASE=Shamrock Tech. Co., Ltd
+
+usb:v044B*
+ ID_VENDOR_FROM_DATABASE=WSI
+
+usb:v044C*
+ ID_VENDOR_FROM_DATABASE=CCL/ITRI
+
+usb:v044D*
+ ID_VENDOR_FROM_DATABASE=Siemens Nixdorf AG
+
+usb:v044E*
+ ID_VENDOR_FROM_DATABASE=Alps Electric Co., Ltd
+
+usb:v044Ep1104*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard
+
+usb:v044Ep2002*
+ ID_PRODUCT_FROM_DATABASE=MD-5500 Printer
+
+usb:v044Ep2014*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v044Ep3001*
+ ID_PRODUCT_FROM_DATABASE=UGTZ4 Bluetooth
+
+usb:v044Ep3002*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v044Ep3003*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v044Ep3004*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter
+
+usb:v044Ep3005*
+ ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth Device
+
+usb:v044Ep3006*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter
+
+usb:v044Ep3007*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller (ALPS/UGX)
+
+usb:v044Ep300C*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller (ALPS/UGPZ6)
+
+usb:v044Ep300D*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller (ALPS/UGPZ6)
+
+usb:v044Ep3010*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter
+
+usb:v044Ep3017*
+ ID_PRODUCT_FROM_DATABASE=BCM2046 Bluetooth Device
+
+usb:v044EpFFFF*
+ ID_PRODUCT_FROM_DATABASE=Compaq Bluetooth Multiport Module
+
+usb:v044F*
+ ID_VENDOR_FROM_DATABASE=ThrustMaster, Inc.
+
+usb:v044Fp0400*
+ ID_PRODUCT_FROM_DATABASE=HOTAS Cougar
+
+usb:v044FpA003*
+ ID_PRODUCT_FROM_DATABASE=Rage 3D Game Pad
+
+usb:v044FpA01B*
+ ID_PRODUCT_FROM_DATABASE=PK-GP301 Driving Wheel
+
+usb:v044FpA0A0*
+ ID_PRODUCT_FROM_DATABASE=Top Gun Joystick
+
+usb:v044FpA0A1*
+ ID_PRODUCT_FROM_DATABASE=Top Gun Joystick (rev2)
+
+usb:v044FpA0A3*
+ ID_PRODUCT_FROM_DATABASE=Fusion Digital GamePad
+
+usb:v044FpA201*
+ ID_PRODUCT_FROM_DATABASE=PK-GP201 PlayStick
+
+usb:v044FpB10A*
+ ID_PRODUCT_FROM_DATABASE=T.16000M Joystick
+
+usb:v044FpB203*
+ ID_PRODUCT_FROM_DATABASE=360 Modena Pro Wheel
+
+usb:v044FpB300*
+ ID_PRODUCT_FROM_DATABASE=Firestorm Dual Power
+
+usb:v044FpB304*
+ ID_PRODUCT_FROM_DATABASE=Firestorm Dual Power
+
+usb:v044FpB307*
+ ID_PRODUCT_FROM_DATABASE=vibrating Upad
+
+usb:v044FpB30B*
+ ID_PRODUCT_FROM_DATABASE=Wireless VibrationPad
+
+usb:v044FpB315*
+ ID_PRODUCT_FROM_DATABASE=Firestorm Dual Analog 3
+
+usb:v044FpB323*
+ ID_PRODUCT_FROM_DATABASE=Dual Trigger 3-in-1 (PC Mode)
+
+usb:v044FpB324*
+ ID_PRODUCT_FROM_DATABASE=Dual Trigger 3-in-1 (PS3 Mode)
+
+usb:v044FpB603*
+ ID_PRODUCT_FROM_DATABASE=force feedback Wheel
+
+usb:v044FpB605*
+ ID_PRODUCT_FROM_DATABASE=force feedback Racing Wheel
+
+usb:v044FpB651*
+ ID_PRODUCT_FROM_DATABASE=Ferrari GT Rumble Force Wheel
+
+usb:v044FpB653*
+ ID_PRODUCT_FROM_DATABASE=RGT Force Feedback Clutch Racing Wheel
+
+usb:v044FpB654*
+ ID_PRODUCT_FROM_DATABASE=Ferrari GT Force Feedback Wheel
+
+usb:v044FpB700*
+ ID_PRODUCT_FROM_DATABASE=Tacticalboard
+
+usb:v0450*
+ ID_VENDOR_FROM_DATABASE=DFI, Inc.
+
+usb:v0451*
+ ID_VENDOR_FROM_DATABASE=Texas Instruments, Inc.
+
+usb:v0451p1234*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0451p1428*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0451p1446*
+ ID_PRODUCT_FROM_DATABASE=TUSB2040/2070 Hub
+
+usb:v0451p16A6*
+ ID_PRODUCT_FROM_DATABASE=BM-USBD1 BlueRobin RF heart rate sensor receiver
+
+usb:v0451p2036*
+ ID_PRODUCT_FROM_DATABASE=TUSB2036 Hub
+
+usb:v0451p2046*
+ ID_PRODUCT_FROM_DATABASE=TUSB2046 Hub
+
+usb:v0451p2077*
+ ID_PRODUCT_FROM_DATABASE=TUSB2077 Hub
+
+usb:v0451p3410*
+ ID_PRODUCT_FROM_DATABASE=TUSB3410 Microcontroller
+
+usb:v0451p3F00*
+ ID_PRODUCT_FROM_DATABASE=OMAP1610
+
+usb:v0451p3F02*
+ ID_PRODUCT_FROM_DATABASE=SMC WSKP100 Wi-Fi Phone
+
+usb:v0451p5409*
+ ID_PRODUCT_FROM_DATABASE=Frontier Labs NEX IA+ Digital Audio Player
+
+usb:v0451p6000*
+ ID_PRODUCT_FROM_DATABASE=AU5 ADSL Modem (pre-reenum)
+
+usb:v0451p6001*
+ ID_PRODUCT_FROM_DATABASE=AU5 ADSL Modem
+
+usb:v0451p6060*
+ ID_PRODUCT_FROM_DATABASE=RNDIS/BeWAN ADSL2+
+
+usb:v0451p6070*
+ ID_PRODUCT_FROM_DATABASE=RNDIS/BeWAN ADSL2+
+
+usb:v0451p625F*
+ ID_PRODUCT_FROM_DATABASE=TUSB6250 ATA Bridge
+
+usb:v0451p8042*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0451pDBC0*
+ ID_PRODUCT_FROM_DATABASE=Device Bay Controller
+
+usb:v0451pE001*
+ ID_PRODUCT_FROM_DATABASE=GraphLink
+
+usb:v0451pE003*
+ ID_PRODUCT_FROM_DATABASE=TI-84 Plus Calculator
+
+usb:v0451pE004*
+ ID_PRODUCT_FROM_DATABASE=TI-89 Titanium Calculator
+
+usb:v0451pE008*
+ ID_PRODUCT_FROM_DATABASE=TI-84 Plus Silver Calculator
+
+usb:v0451pF430*
+ ID_PRODUCT_FROM_DATABASE=MSP-FET430UIF JTAG Tool
+
+usb:v0451pF432*
+ ID_PRODUCT_FROM_DATABASE=eZ430 Development Tool
+
+usb:v0451pFFFF*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0452*
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Electronics America, Inc.
+
+usb:v0452p0021*
+ ID_PRODUCT_FROM_DATABASE=HID Monitor Controls
+
+usb:v0452p0050*
+ ID_PRODUCT_FROM_DATABASE=Diamond Pro 900u CRT Monitor
+
+usb:v0452p0051*
+ ID_PRODUCT_FROM_DATABASE=Integrated Hub
+
+usb:v0453*
+ ID_VENDOR_FROM_DATABASE=CMD Technology
+
+usb:v0453p6781*
+ ID_PRODUCT_FROM_DATABASE=NMB Keyboard
+
+usb:v0453p6783*
+ ID_PRODUCT_FROM_DATABASE=Chicony Composite Keyboard
+
+usb:v0454*
+ ID_VENDOR_FROM_DATABASE=Vobis Microcomputer AG
+
+usb:v0455*
+ ID_VENDOR_FROM_DATABASE=Telematics International, Inc.
+
+usb:v0456*
+ ID_VENDOR_FROM_DATABASE=Analog Devices, Inc.
+
+usb:v0456pF000*
+ ID_PRODUCT_FROM_DATABASE=FT2232 JTAG ICE [gnICE]
+
+usb:v0456pF001*
+ ID_PRODUCT_FROM_DATABASE=FT2232H Hi-Speed JTAG ICE [gnICE+]
+
+usb:v0457*
+ ID_VENDOR_FROM_DATABASE=Silicon Integrated Systems Corp.
+
+usb:v0457p0150*
+ ID_PRODUCT_FROM_DATABASE=Super Talent 1GB Flash Drive
+
+usb:v0457p0151*
+ ID_PRODUCT_FROM_DATABASE=Super Flash 1GB / GXT  64MB Flash Drive
+
+usb:v0457p0162*
+ ID_PRODUCT_FROM_DATABASE=SiS162 usb Wireless LAN Adapter
+
+usb:v0457p0163*
+ ID_PRODUCT_FROM_DATABASE=802.11 Wireless LAN Adapter
+
+usb:v0457p5401*
+ ID_PRODUCT_FROM_DATABASE=Wireless Adapter RO80211GS-USB
+
+usb:v0458*
+ ID_VENDOR_FROM_DATABASE=KYE Systems Corp. (Mouse Systems)
+
+usb:v0458p0001*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v0458p0002*
+ ID_PRODUCT_FROM_DATABASE=Genius NetMouse Pro
+
+usb:v0458p0003*
+ ID_PRODUCT_FROM_DATABASE=Genius NetScroll+
+
+usb:v0458p0006*
+ ID_PRODUCT_FROM_DATABASE=Easy Mouse+
+
+usb:v0458p000B*
+ ID_PRODUCT_FROM_DATABASE=NetMouse Wheel(P+U)
+
+usb:v0458p000C*
+ ID_PRODUCT_FROM_DATABASE=TACOMA Fingerprint V1.06.01
+
+usb:v0458p000E*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Web
+
+usb:v0458p0013*
+ ID_PRODUCT_FROM_DATABASE=TACOMA Fingerprint Mouse V1.06.01
+
+usb:v0458p001A*
+ ID_PRODUCT_FROM_DATABASE=Genius WebScroll+
+
+usb:v0458p0036*
+ ID_PRODUCT_FROM_DATABASE=Pocket Mouse LE
+
+usb:v0458p0039*
+ ID_PRODUCT_FROM_DATABASE=NetScroll+ Superior
+
+usb:v0458p003A*
+ ID_PRODUCT_FROM_DATABASE=NetScroll+ Mini Traveler / Genius NetScroll 120
+
+usb:v0458p004C*
+ ID_PRODUCT_FROM_DATABASE=Slimstar Pro Keyboard
+
+usb:v0458p0056*
+ ID_PRODUCT_FROM_DATABASE=Ergo 300 Mouse
+
+usb:v0458p0057*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Gaming Device
+
+usb:v0458p0059*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Laser Device
+
+usb:v0458p005A*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Device
+
+usb:v0458p005B*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Device
+
+usb:v0458p005C*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Laser Gaming Device
+
+usb:v0458p005D*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Device
+
+usb:v0458p0061*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v0458p0066*
+ ID_PRODUCT_FROM_DATABASE=Genius Traveler 1000 Wireless Mouse
+
+usb:v0458p0072*
+ ID_PRODUCT_FROM_DATABASE=Navigator 335
+
+usb:v0458p0083*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v0458p0087*
+ ID_PRODUCT_FROM_DATABASE=Ergo 525V Laser Mouse
+
+usb:v0458p0100*
+ ID_PRODUCT_FROM_DATABASE=EasyPen Tablet
+
+usb:v0458p0101*
+ ID_PRODUCT_FROM_DATABASE=CueCat
+
+usb:v0458p011B*
+ ID_PRODUCT_FROM_DATABASE=NetScroll T220
+
+usb:v0458p1001*
+ ID_PRODUCT_FROM_DATABASE=Joystick
+
+usb:v0458p1002*
+ ID_PRODUCT_FROM_DATABASE=Game Pad
+
+usb:v0458p1003*
+ ID_PRODUCT_FROM_DATABASE=Genius VideoCam
+
+usb:v0458p1004*
+ ID_PRODUCT_FROM_DATABASE=Flight2000 F-23 Joystick
+
+usb:v0458p100A*
+ ID_PRODUCT_FROM_DATABASE=Aashima Technology Trust Sight Fighter Vibration Feedback Joystick
+
+usb:v0458p2001*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid Pro Scanner
+
+usb:v0458p2004*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR6 V1 Scanner
+
+usb:v0458p2005*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR6/Vivid3
+
+usb:v0458p2007*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR6 V2 Scanner
+
+usb:v0458p2008*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR6 V2 Scanner
+
+usb:v0458p2009*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR6A Scanner
+
+usb:v0458p2011*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid3x Scanner
+
+usb:v0458p2012*
+ ID_PRODUCT_FROM_DATABASE=Plustek Scanner
+
+usb:v0458p2013*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR7 Scanner
+
+usb:v0458p2014*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid4
+
+usb:v0458p2015*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR7LE Scanner
+
+usb:v0458p2016*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR6X Scanner
+
+usb:v0458p2017*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid3xe
+
+usb:v0458p2018*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR7X
+
+usb:v0458p2019*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR6X Slim
+
+usb:v0458p201A*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid4xe
+
+usb:v0458p201B*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid4x
+
+usb:v0458p201C*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-HR8
+
+usb:v0458p201D*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid 1200 X
+
+usb:v0458p201E*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Slim 1200
+
+usb:v0458p201F*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid 1200 XE
+
+usb:v0458p2020*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-Slim 1200 USB2
+
+usb:v0458p2021*
+ ID_PRODUCT_FROM_DATABASE=ColorPage-SF600
+
+usb:v0458p3017*
+ ID_PRODUCT_FROM_DATABASE=SPEED WHEEL 3 Vibration
+
+usb:v0458p3018*
+ ID_PRODUCT_FROM_DATABASE=Wireless 2.4Ghz Game Pad
+
+usb:v0458p3019*
+ ID_PRODUCT_FROM_DATABASE=10-Button USB Joystick with Vibration
+
+usb:v0458p301A*
+ ID_PRODUCT_FROM_DATABASE=MaxFire G-12U Vibration
+
+usb:v0458p301D*
+ ID_PRODUCT_FROM_DATABASE=Genius MaxFire MiniPad
+
+usb:v0458p400F*
+ ID_PRODUCT_FROM_DATABASE=Genius TVGo DVB-T02Q MCE
+
+usb:v0458p4012*
+ ID_PRODUCT_FROM_DATABASE=TVGo DVB-T03 [AF9015]
+
+usb:v0458p5003*
+ ID_PRODUCT_FROM_DATABASE=G-pen 560 Tablet
+
+usb:v0458p5004*
+ ID_PRODUCT_FROM_DATABASE=G-pen Tablet
+
+usb:v0458p6001*
+ ID_PRODUCT_FROM_DATABASE=GF3000F Ethernet Adapter
+
+usb:v0458p7004*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Express V2
+
+usb:v0458p7006*
+ ID_PRODUCT_FROM_DATABASE=Dsc 1.3 Smart Camera Device
+
+usb:v0458p7007*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Web
+
+usb:v0458p7009*
+ ID_PRODUCT_FROM_DATABASE=G-Shot G312 Still Camera Device
+
+usb:v0458p700C*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Web V3
+
+usb:v0458p700D*
+ ID_PRODUCT_FROM_DATABASE=G-Shot G511 Composite Device
+
+usb:v0458p700F*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Web
+
+usb:v0458p7012*
+ ID_PRODUCT_FROM_DATABASE=WebCAM USB2.0
+
+usb:v0458p7014*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Live V3
+
+usb:v0458p701C*
+ ID_PRODUCT_FROM_DATABASE=G-Shot G512 Still Camera
+
+usb:v0458p7020*
+ ID_PRODUCT_FROM_DATABASE=Sim 321C
+
+usb:v0458p7025*
+ ID_PRODUCT_FROM_DATABASE=Eye 311Q Camera
+
+usb:v0458p7029*
+ ID_PRODUCT_FROM_DATABASE=Genius Look 320s (SN9C201 + HV7131R)
+
+usb:v0458p702F*
+ ID_PRODUCT_FROM_DATABASE=Genius Slim 322
+
+usb:v0458p7035*
+ ID_PRODUCT_FROM_DATABASE=i-Look 325T Camera
+
+usb:v0458p7045*
+ ID_PRODUCT_FROM_DATABASE=Genius Look 1320 V2
+
+usb:v0458p704C*
+ ID_PRODUCT_FROM_DATABASE=Genius i-Look 1321
+
+usb:v0458p704D*
+ ID_PRODUCT_FROM_DATABASE=Slim 1322AF
+
+usb:v0458p7055*
+ ID_PRODUCT_FROM_DATABASE=Slim 2020AF camera
+
+usb:v0458p705A*
+ ID_PRODUCT_FROM_DATABASE=Asus USB2.0 Webcam
+
+usb:v0458p705C*
+ ID_PRODUCT_FROM_DATABASE=Genius iSlim 1300AF
+
+usb:v0458p7079*
+ ID_PRODUCT_FROM_DATABASE=FaceCam 2025R
+
+usb:v0458p707F*
+ ID_PRODUCT_FROM_DATABASE=TVGo DVB-T03 [RTL2832]
+
+usb:v0459*
+ ID_VENDOR_FROM_DATABASE=Adobe Systems, Inc.
+
+usb:v045A*
+ ID_VENDOR_FROM_DATABASE=SONICblue, Inc.
+
+usb:v045Ap07DA*
+ ID_PRODUCT_FROM_DATABASE=Supra Express 56K modem
+
+usb:v045Ap0B4A*
+ ID_PRODUCT_FROM_DATABASE=SupraMax 2890 56K Modem [Lucent Atlas]
+
+usb:v045Ap0B68*
+ ID_PRODUCT_FROM_DATABASE=SupraMax 56K Modem
+
+usb:v045Ap5001*
+ ID_PRODUCT_FROM_DATABASE=Rio 600 MP3 Player
+
+usb:v045Ap5002*
+ ID_PRODUCT_FROM_DATABASE=Rio 800 MP3 Player
+
+usb:v045Ap5003*
+ ID_PRODUCT_FROM_DATABASE=Nike Psa/Play MP3 Player
+
+usb:v045Ap5005*
+ ID_PRODUCT_FROM_DATABASE=Rio S10 MP3 Player
+
+usb:v045Ap5006*
+ ID_PRODUCT_FROM_DATABASE=Rio S50 MP3 Player
+
+usb:v045Ap5007*
+ ID_PRODUCT_FROM_DATABASE=Rio S35 MP3 Player
+
+usb:v045Ap5008*
+ ID_PRODUCT_FROM_DATABASE=Rio 900 MP3 Player
+
+usb:v045Ap5009*
+ ID_PRODUCT_FROM_DATABASE=Rio S30 MP3 Player
+
+usb:v045Ap500D*
+ ID_PRODUCT_FROM_DATABASE=Fuse MP3 Player
+
+usb:v045Ap500E*
+ ID_PRODUCT_FROM_DATABASE=Chiba MP3 Player
+
+usb:v045Ap500F*
+ ID_PRODUCT_FROM_DATABASE=Cali MP3 Player
+
+usb:v045Ap5010*
+ ID_PRODUCT_FROM_DATABASE=Rio S11 MP3 Player
+
+usb:v045Ap501C*
+ ID_PRODUCT_FROM_DATABASE=Virgin MPF-1000
+
+usb:v045Ap501D*
+ ID_PRODUCT_FROM_DATABASE=Rio Fuse
+
+usb:v045Ap501E*
+ ID_PRODUCT_FROM_DATABASE=Rio Chiba
+
+usb:v045Ap501F*
+ ID_PRODUCT_FROM_DATABASE=Rio Cali
+
+usb:v045Ap503F*
+ ID_PRODUCT_FROM_DATABASE=Cali256 MP3 Player
+
+usb:v045Ap5202*
+ ID_PRODUCT_FROM_DATABASE=Rio Riot MP3 Player
+
+usb:v045Ap5210*
+ ID_PRODUCT_FROM_DATABASE=Rio Karma Music Player
+
+usb:v045Ap5220*
+ ID_PRODUCT_FROM_DATABASE=Rio Nitrus MP3 Player
+
+usb:v045Ap5221*
+ ID_PRODUCT_FROM_DATABASE=Rio Eigen
+
+usb:v045B*
+ ID_VENDOR_FROM_DATABASE=Hitachi, Ltd
+
+usb:v045Bp0053*
+ ID_PRODUCT_FROM_DATABASE=RX610 RX-Stick
+
+usb:v045D*
+ ID_VENDOR_FROM_DATABASE=Nortel Networks, Ltd
+
+usb:v045E*
+ ID_VENDOR_FROM_DATABASE=Microsoft Corp.
+
+usb:v045Ep0007*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Game Pad
+
+usb:v045Ep0008*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Precision Pro
+
+usb:v045Ep0009*
+ ID_PRODUCT_FROM_DATABASE=IntelliMouse
+
+usb:v045Ep000B*
+ ID_PRODUCT_FROM_DATABASE=Natural Keyboard Elite
+
+usb:v045Ep000E*
+ ID_PRODUCT_FROM_DATABASE=SideWinder® Freestyle Pro
+
+usb:v045Ep0014*
+ ID_PRODUCT_FROM_DATABASE=Digital Sound System 80
+
+usb:v045Ep001A*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Precision Racing Wheel
+
+usb:v045Ep001B*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Force Feedback 2 Joystick
+
+usb:v045Ep001C*
+ ID_PRODUCT_FROM_DATABASE=Internet Keyboard Pro
+
+usb:v045Ep001D*
+ ID_PRODUCT_FROM_DATABASE=Natural Keyboard Pro
+
+usb:v045Ep001E*
+ ID_PRODUCT_FROM_DATABASE=IntelliMouse Explorer
+
+usb:v045Ep0023*
+ ID_PRODUCT_FROM_DATABASE=Trackball Optical
+
+usb:v045Ep0024*
+ ID_PRODUCT_FROM_DATABASE=Trackball Explorer
+
+usb:v045Ep0025*
+ ID_PRODUCT_FROM_DATABASE=IntelliEye Mouse
+
+usb:v045Ep0026*
+ ID_PRODUCT_FROM_DATABASE=SideWinder GamePad Pro
+
+usb:v045Ep0027*
+ ID_PRODUCT_FROM_DATABASE=SideWinder PnP GamePad
+
+usb:v045Ep0028*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Dual Strike
+
+usb:v045Ep0029*
+ ID_PRODUCT_FROM_DATABASE=IntelliMouse Optical
+
+usb:v045Ep002B*
+ ID_PRODUCT_FROM_DATABASE=Internet Keyboard Pro
+
+usb:v045Ep002D*
+ ID_PRODUCT_FROM_DATABASE=Internet Keyboard
+
+usb:v045Ep002F*
+ ID_PRODUCT_FROM_DATABASE=Integrated Hub
+
+usb:v045Ep0033*
+ ID_PRODUCT_FROM_DATABASE=Sidewinder Strategic Commander
+
+usb:v045Ep0034*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Force Feedback Wheel
+
+usb:v045Ep0038*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Precision 2
+
+usb:v045Ep0039*
+ ID_PRODUCT_FROM_DATABASE=IntelliMouse Optical
+
+usb:v045Ep003B*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Game Voice
+
+usb:v045Ep003C*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Joystick
+
+usb:v045Ep0040*
+ ID_PRODUCT_FROM_DATABASE=Wheel Mouse Optical
+
+usb:v045Ep0047*
+ ID_PRODUCT_FROM_DATABASE=IntelliMouse Explorer 3.0
+
+usb:v045Ep0048*
+ ID_PRODUCT_FROM_DATABASE=Office Keyboard 1.0A
+
+usb:v045Ep0053*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v045Ep0059*
+ ID_PRODUCT_FROM_DATABASE=Wireless IntelliMouse Explorer
+
+usb:v045Ep005C*
+ ID_PRODUCT_FROM_DATABASE=Office Keyboard (106/109)
+
+usb:v045Ep005F*
+ ID_PRODUCT_FROM_DATABASE=Wireless MultiMedia Keyboard
+
+usb:v045Ep0061*
+ ID_PRODUCT_FROM_DATABASE=Wireless MultiMedia Keyboard (106/109)
+
+usb:v045Ep0063*
+ ID_PRODUCT_FROM_DATABASE=Wireless Natural MultiMedia Keyboard
+
+usb:v045Ep0065*
+ ID_PRODUCT_FROM_DATABASE=Wireless Natural MultiMedia Keyboard (106/109)
+
+usb:v045Ep006A*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse (IntelliPoint)
+
+usb:v045Ep006D*
+ ID_PRODUCT_FROM_DATABASE=eHome Remote Control Keyboard keys
+
+usb:v045Ep006E*
+ ID_PRODUCT_FROM_DATABASE=MN-510 802.11b Wireless Adapter [Intersil ISL3873B]
+
+usb:v045Ep006F*
+ ID_PRODUCT_FROM_DATABASE=Smart Display Reference Device
+
+usb:v045Ep0070*
+ ID_PRODUCT_FROM_DATABASE=Wireless MultiMedia Keyboard
+
+usb:v045Ep0071*
+ ID_PRODUCT_FROM_DATABASE=Wireless MultiMedia Keyboard (106/109)
+
+usb:v045Ep0072*
+ ID_PRODUCT_FROM_DATABASE=Wireless Natural MultiMedia Keyboard
+
+usb:v045Ep0073*
+ ID_PRODUCT_FROM_DATABASE=Wireless Natural MultiMedia Keyboard (106/109)
+
+usb:v045Ep0079*
+ ID_PRODUCT_FROM_DATABASE=IXI Ogo CT-17 handheld device
+
+usb:v045Ep007A*
+ ID_PRODUCT_FROM_DATABASE=10/100 USB NIC
+
+usb:v045Ep007D*
+ ID_PRODUCT_FROM_DATABASE=Notebook Optical Mouse
+
+usb:v045Ep007E*
+ ID_PRODUCT_FROM_DATABASE=Wireless Transceiver for Bluetooth
+
+usb:v045Ep0080*
+ ID_PRODUCT_FROM_DATABASE=Digital Media Pro Keyboard
+
+usb:v045Ep0083*
+ ID_PRODUCT_FROM_DATABASE=Basic Optical Mouse
+
+usb:v045Ep0084*
+ ID_PRODUCT_FROM_DATABASE=Basic Optical Mouse
+
+usb:v045Ep008A*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Mouse
+
+usb:v045Ep008B*
+ ID_PRODUCT_FROM_DATABASE=Dual Receiver Wireless Mouse (IntelliPoint)
+
+usb:v045Ep008C*
+ ID_PRODUCT_FROM_DATABASE=Wireless Intellimouse Explorer 2.0
+
+usb:v045Ep0095*
+ ID_PRODUCT_FROM_DATABASE=IntelliMouse Explorer 4.0 (IntelliPoint)
+
+usb:v045Ep009C*
+ ID_PRODUCT_FROM_DATABASE=Wireless Transceiver for Bluetooth 2.0
+
+usb:v045Ep009D*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Desktop 3.0
+
+usb:v045Ep00A0*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v045Ep00A4*
+ ID_PRODUCT_FROM_DATABASE=Compact Optical Mouse, model 1016
+
+usb:v045Ep00B0*
+ ID_PRODUCT_FROM_DATABASE=Digital Media Pro Keyboard
+
+usb:v045Ep00B4*
+ ID_PRODUCT_FROM_DATABASE=Digital Media Keyboard 1.0A
+
+usb:v045Ep00B9*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse 3.0
+
+usb:v045Ep00BB*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v045Ep00BC*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v045Ep00BD*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v045Ep00C2*
+ ID_PRODUCT_FROM_DATABASE=MN-710 802.11g Wireless Adapter [Intersil ISL3886]
+
+usb:v045Ep00C9*
+ ID_PRODUCT_FROM_DATABASE=MTP Device
+
+usb:v045Ep00CA*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v045Ep00CB*
+ ID_PRODUCT_FROM_DATABASE=Basic Optical Mouse v2.0
+
+usb:v045Ep00CE*
+ ID_PRODUCT_FROM_DATABASE=Generic PPC Flash device
+
+usb:v045Ep00D1*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse with Tilt Wheel
+
+usb:v045Ep00DA*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v045Ep00DB*
+ ID_PRODUCT_FROM_DATABASE=Natural Ergonomic Keyboard 4000 V1.0
+
+usb:v045Ep00DD*
+ ID_PRODUCT_FROM_DATABASE=Comfort Curve Keyboard 2000 V1.0
+
+usb:v045Ep00E1*
+ ID_PRODUCT_FROM_DATABASE=Wireless Laser Mouse 6000 Reciever
+
+usb:v045Ep00F4*
+ ID_PRODUCT_FROM_DATABASE=LifeCam VX-6000 (SN9C20x + OV9650)
+
+usb:v045Ep00F5*
+ ID_PRODUCT_FROM_DATABASE=LifeCam VX-3000
+
+usb:v045Ep00F6*
+ ID_PRODUCT_FROM_DATABASE=Comfort Optical Mouse 1000
+
+usb:v045Ep00F7*
+ ID_PRODUCT_FROM_DATABASE=LifeCam VX-1000
+
+usb:v045Ep00F8*
+ ID_PRODUCT_FROM_DATABASE=LifeCam NX-6000
+
+usb:v045Ep00F9*
+ ID_PRODUCT_FROM_DATABASE=Wireless Desktop Receiver 3.1
+
+usb:v045Ep0202*
+ ID_PRODUCT_FROM_DATABASE=Xbox Controller
+
+usb:v045Ep0280*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v045Ep0283*
+ ID_PRODUCT_FROM_DATABASE=Xbox Communicator
+
+usb:v045Ep0284*
+ ID_PRODUCT_FROM_DATABASE=Xbox DVD Playback Kit
+
+usb:v045Ep0285*
+ ID_PRODUCT_FROM_DATABASE=Xbox Controller S
+
+usb:v045Ep0288*
+ ID_PRODUCT_FROM_DATABASE=Xbox Controller S Hub
+
+usb:v045Ep0289*
+ ID_PRODUCT_FROM_DATABASE=Xbox Controller S
+
+usb:v045Ep028B*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 DVD Emulator
+
+usb:v045Ep028D*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 Memory Unit 64MB
+
+usb:v045Ep028E*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 Controller
+
+usb:v045Ep028F*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 Wireless Controller
+
+usb:v045Ep0290*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 Performance Pipe (PIX)
+
+usb:v045Ep0291*
+ ID_PRODUCT_FROM_DATABASE=Xbox 360 Wireless Receiver for Windows
+
+usb:v045Ep0292*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 Wireless Networking Adapter
+
+usb:v045Ep029C*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 HD-DVD Drive
+
+usb:v045Ep029D*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 HD-DVD Drive
+
+usb:v045Ep029E*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 HD-DVD Memory Unit
+
+usb:v045Ep02A0*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 Big Button IR
+
+usb:v045Ep02A8*
+ ID_PRODUCT_FROM_DATABASE=Xbox360 Wireless N Networking Adapter [Atheros AR7010+AR9280]
+
+usb:v045Ep02AD*
+ ID_PRODUCT_FROM_DATABASE=Xbox NUI Audio
+
+usb:v045Ep02AE*
+ ID_PRODUCT_FROM_DATABASE=Xbox NUI Camera
+
+usb:v045Ep02B0*
+ ID_PRODUCT_FROM_DATABASE=Xbox NUI Motor
+
+usb:v045Ep0400*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0401*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0402*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0403*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0404*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0405*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0406*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0407*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0408*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0409*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep040A*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep040B*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep040C*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep040D*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep040E*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep040F*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0410*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0411*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0412*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0413*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0414*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0415*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0416*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0417*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002
+
+usb:v045Ep0432*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0433*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0434*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0435*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0436*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0437*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0438*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0439*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep043A*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep043B*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep043C*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep043D*
+ ID_PRODUCT_FROM_DATABASE=Becker Traffic Assist Highspeed 7934
+
+usb:v045Ep043E*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep043F*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0440*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0441*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0442*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0443*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0444*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0445*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0446*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0447*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0448*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0449*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep044A*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep044B*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep044C*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep044D*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep044E*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep044F*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0450*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0451*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0452*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0453*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0454*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0455*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0456*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0457*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0458*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0459*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep045A*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep045B*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep045C*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep045D*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep045E*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep045F*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0460*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0461*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0462*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0463*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0464*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0465*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0466*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0467*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0468*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0469*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep046A*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep046B*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep046C*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep046D*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep046E*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep046F*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0470*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0471*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0472*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0473*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0474*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0475*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0476*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0477*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0478*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep0479*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep047A*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep047B*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003
+
+usb:v045Ep04C8*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002
+
+usb:v045Ep04C9*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002
+
+usb:v045Ep04CA*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002
+
+usb:v045Ep04CB*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002
+
+usb:v045Ep04CC*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002
+
+usb:v045Ep04CD*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002
+
+usb:v045Ep04CE*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002
+
+usb:v045Ep04D7*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04D8*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04D9*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04DA*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04DB*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04DC*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04DD*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04DE*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04DF*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E0*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E1*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E2*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E3*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E4*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E5*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E6*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E7*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E8*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04E9*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04EA*
+ ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003
+
+usb:v045Ep04EC*
+ ID_PRODUCT_FROM_DATABASE=Windows Phone (Zune)
+
+usb:v045Ep063E*
+ ID_PRODUCT_FROM_DATABASE=Zune HD Media Player
+
+usb:v045Ep0640*
+ ID_PRODUCT_FROM_DATABASE=KIN Phone
+
+usb:v045Ep0641*
+ ID_PRODUCT_FROM_DATABASE=KIN Phone
+
+usb:v045Ep0642*
+ ID_PRODUCT_FROM_DATABASE=KIN Phone
+
+usb:v045Ep0707*
+ ID_PRODUCT_FROM_DATABASE=Wireless Laser Mouse 8000
+
+usb:v045Ep0708*
+ ID_PRODUCT_FROM_DATABASE=Transceiver v 3.0 for Bluetooth
+
+usb:v045Ep070A*
+ ID_PRODUCT_FROM_DATABASE=Charon Bluetooth Dongle (DFU)
+
+usb:v045Ep0710*
+ ID_PRODUCT_FROM_DATABASE=Zune Media Player
+
+usb:v045Ep0713*
+ ID_PRODUCT_FROM_DATABASE=Wireless Presenter Mouse 8000
+
+usb:v045Ep0719*
+ ID_PRODUCT_FROM_DATABASE=Xbox 360 Wireless Adapter
+
+usb:v045Ep071F*
+ ID_PRODUCT_FROM_DATABASE=Mouse/Keyboard 2.4GHz Transceiver V2.0
+
+usb:v045Ep0721*
+ ID_PRODUCT_FROM_DATABASE=LifeCam NX-3000 (UVC-compliant)
+
+usb:v045Ep0723*
+ ID_PRODUCT_FROM_DATABASE=LifeCam VX-7000 (UVC-compliant)
+
+usb:v045Ep0724*
+ ID_PRODUCT_FROM_DATABASE=SideWinder Mouse
+
+usb:v045Ep0730*
+ ID_PRODUCT_FROM_DATABASE=Digital Media Keyboard 3000
+
+usb:v045Ep0734*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Desktop 700
+
+usb:v045Ep0736*
+ ID_PRODUCT_FROM_DATABASE=Sidewinder X5 Mouse
+
+usb:v045Ep0737*
+ ID_PRODUCT_FROM_DATABASE=Compact Optical Mouse 500
+
+usb:v045Ep0745*
+ ID_PRODUCT_FROM_DATABASE=Nano Transceiver v1.0 for Bluetooth
+
+usb:v045Ep0750*
+ ID_PRODUCT_FROM_DATABASE=Wired Keyboard 600
+
+usb:v045Ep0752*
+ ID_PRODUCT_FROM_DATABASE=Wired Keyboard 400
+
+usb:v045Ep075D*
+ ID_PRODUCT_FROM_DATABASE=LifeCam Cinema
+
+usb:v045Ep0766*
+ ID_PRODUCT_FROM_DATABASE=LifeCam VX-800
+
+usb:v045Ep0768*
+ ID_PRODUCT_FROM_DATABASE=Sidewinder X4
+
+usb:v045Ep076D*
+ ID_PRODUCT_FROM_DATABASE=LifeCam HD-5000
+
+usb:v045Ep0772*
+ ID_PRODUCT_FROM_DATABASE=LifeCam Studio
+
+usb:v045Ep0779*
+ ID_PRODUCT_FROM_DATABASE=LifeCam HD-3000
+
+usb:v045Ep930A*
+ ID_PRODUCT_FROM_DATABASE=ISOUSB.SYS Intel 82930 Isochronous IO Test Board
+
+usb:v045EpFFF8*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v045EpFFFF*
+ ID_PRODUCT_FROM_DATABASE=Windows CE Mass Storage
+
+usb:v0460*
+ ID_VENDOR_FROM_DATABASE=Ace Cad Enterprise Co., Ltd
+
+usb:v0460p0004*
+ ID_PRODUCT_FROM_DATABASE=Tablet (5x3.75)
+
+usb:v0460p0006*
+ ID_PRODUCT_FROM_DATABASE=LCD Tablet (12x9)
+
+usb:v0460p0008*
+ ID_PRODUCT_FROM_DATABASE=Tablet (3x2.25)
+
+usb:v0461*
+ ID_VENDOR_FROM_DATABASE=Primax Electronics, Ltd
+
+usb:v0461p0010*
+ ID_PRODUCT_FROM_DATABASE=HP Keyboard
+
+usb:v0461p0300*
+ ID_PRODUCT_FROM_DATABASE=G2-300 Scanner
+
+usb:v0461p0301*
+ ID_PRODUCT_FROM_DATABASE=G2E-300 Scanner
+
+usb:v0461p0302*
+ ID_PRODUCT_FROM_DATABASE=G2-300 #2 Scanner
+
+usb:v0461p0303*
+ ID_PRODUCT_FROM_DATABASE=G2E-300 #2 Scanner
+
+usb:v0461p0340*
+ ID_PRODUCT_FROM_DATABASE=Colorado 9600 Scanner
+
+usb:v0461p0341*
+ ID_PRODUCT_FROM_DATABASE=Colorado 600u Scanner
+
+usb:v0461p0345*
+ ID_PRODUCT_FROM_DATABASE=Visioneer 6200 Scanner
+
+usb:v0461p0346*
+ ID_PRODUCT_FROM_DATABASE=Memorex Maxx 6136u Scanner
+
+usb:v0461p0347*
+ ID_PRODUCT_FROM_DATABASE=Primascan Colorado 2600u/Visioneer 4400 Scanner
+
+usb:v0461p0360*
+ ID_PRODUCT_FROM_DATABASE=Colorado 19200 Scanner
+
+usb:v0461p0361*
+ ID_PRODUCT_FROM_DATABASE=Colorado 1200u Scanner
+
+usb:v0461p0363*
+ ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG)
+
+usb:v0461p0364*
+ ID_PRODUCT_FROM_DATABASE=LG Electronics Scanworks 600U Scanner
+
+usb:v0461p0365*
+ ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG)
+
+usb:v0461p0366*
+ ID_PRODUCT_FROM_DATABASE=6400
+
+usb:v0461p0367*
+ ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG)
+
+usb:v0461p0371*
+ ID_PRODUCT_FROM_DATABASE=Visioneer Onetouch 8920 Scanner
+
+usb:v0461p0374*
+ ID_PRODUCT_FROM_DATABASE=UMAX Astra 2500
+
+usb:v0461p0375*
+ ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG)
+
+usb:v0461p0377*
+ ID_PRODUCT_FROM_DATABASE=Medion MD 5345 Scanner
+
+usb:v0461p0378*
+ ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG)
+
+usb:v0461p037B*
+ ID_PRODUCT_FROM_DATABASE=Medion MD 6190 Scanner
+
+usb:v0461p037C*
+ ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG)
+
+usb:v0461p0380*
+ ID_PRODUCT_FROM_DATABASE=G2-600 Scanner
+
+usb:v0461p0381*
+ ID_PRODUCT_FROM_DATABASE=ReadyScan 636i Scanner
+
+usb:v0461p0382*
+ ID_PRODUCT_FROM_DATABASE=G2-600 #2 Scanner
+
+usb:v0461p0383*
+ ID_PRODUCT_FROM_DATABASE=G2E-600 Scanner
+
+usb:v0461p038A*
+ ID_PRODUCT_FROM_DATABASE=UMAX Astra 3000/3600
+
+usb:v0461p038B*
+ ID_PRODUCT_FROM_DATABASE=Xerox 2400 Onetouch
+
+usb:v0461p038C*
+ ID_PRODUCT_FROM_DATABASE=UMAX Astra 4100
+
+usb:v0461p0392*
+ ID_PRODUCT_FROM_DATABASE=Medion/Lifetec/Tevion/Cytron MD 6190
+
+usb:v0461p03A8*
+ ID_PRODUCT_FROM_DATABASE=9420M
+
+usb:v0461p0813*
+ ID_PRODUCT_FROM_DATABASE=IBM UltraPort Camera
+
+usb:v0461p0815*
+ ID_PRODUCT_FROM_DATABASE=Micro Innovations IC200 Webcam
+
+usb:v0461p0819*
+ ID_PRODUCT_FROM_DATABASE=Fujifilm IX-30 Camera [webcam mode]
+
+usb:v0461p081A*
+ ID_PRODUCT_FROM_DATABASE=Fujifilm IX-30 Camera [storage mode]
+
+usb:v0461p081C*
+ ID_PRODUCT_FROM_DATABASE=Elitegroup ECS-C11 Camera
+
+usb:v0461p081D*
+ ID_PRODUCT_FROM_DATABASE=Elitegroup ECS-C11 Storage
+
+usb:v0461p0A00*
+ ID_PRODUCT_FROM_DATABASE=Micro Innovations Web Cam 320
+
+usb:v0461p4D01*
+ ID_PRODUCT_FROM_DATABASE=Comfort Keyboard
+
+usb:v0461p4D02*
+ ID_PRODUCT_FROM_DATABASE=Mouse-in-a-Box
+
+usb:v0461p4D03*
+ ID_PRODUCT_FROM_DATABASE=Kensington Mouse-in-a-box
+
+usb:v0461p4D04*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v0461p4D06*
+ ID_PRODUCT_FROM_DATABASE=Balless Mouse (HID)
+
+usb:v0461p4D0F*
+ ID_PRODUCT_FROM_DATABASE=HP Optical Mouse
+
+usb:v0461p4D15*
+ ID_PRODUCT_FROM_DATABASE=Dell Optical Mouse
+
+usb:v0461p4D17*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v0461p4D20*
+ ID_PRODUCT_FROM_DATABASE=HP Optical Mouse
+
+usb:v0461p4D2A*
+ ID_PRODUCT_FROM_DATABASE=PoPo Elixir Mouse (HID)
+
+usb:v0461p4D2B*
+ ID_PRODUCT_FROM_DATABASE=Wireless Laser Mini Mouse (HID)
+
+usb:v0461p4D2C*
+ ID_PRODUCT_FROM_DATABASE=PoPo Mini Pointer Mouse (HID)
+
+usb:v0461p4D2E*
+ ID_PRODUCT_FROM_DATABASE=Optical Mobile Mouse (HID)
+
+usb:v0461p4D51*
+ ID_PRODUCT_FROM_DATABASE=0Y357C PMX-MMOCZUL (B) [Dell Laser Mouse]
+
+usb:v0461p4D75*
+ ID_PRODUCT_FROM_DATABASE=Rocketfish RF-FLBTAD Bluetooth Adapter
+
+usb:v0461p4D81*
+ ID_PRODUCT_FROM_DATABASE=Dell N889 Optical Mouse
+
+usb:v0461p4DE7*
+ ID_PRODUCT_FROM_DATABASE=webcam
+
+usb:v0463*
+ ID_VENDOR_FROM_DATABASE=MGE UPS Systems
+
+usb:v0463p0001*
+ ID_PRODUCT_FROM_DATABASE=UPS
+
+usb:v0463pFFFF*
+ ID_PRODUCT_FROM_DATABASE=UPS
+
+usb:v0464*
+ ID_VENDOR_FROM_DATABASE=AMP/Tycoelectronics Corp.
+
+usb:v0467*
+ ID_VENDOR_FROM_DATABASE=AT&T Paradyne
+
+usb:v0468*
+ ID_VENDOR_FROM_DATABASE=Wieson Technologies Co., Ltd
+
+usb:v046A*
+ ID_VENDOR_FROM_DATABASE=Cherry GmbH
+
+usb:v046Ap0001*
+ ID_PRODUCT_FROM_DATABASE=My3000 Keyboard
+
+usb:v046Ap0003*
+ ID_PRODUCT_FROM_DATABASE=My3000 Hub
+
+usb:v046Ap0004*
+ ID_PRODUCT_FROM_DATABASE=CyBoard Keyboard
+
+usb:v046Ap0005*
+ ID_PRODUCT_FROM_DATABASE=XX33 SmartCard Reader Keyboard
+
+usb:v046Ap0008*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Mouse
+
+usb:v046Ap0010*
+ ID_PRODUCT_FROM_DATABASE=SmartBoard XX44
+
+usb:v046Ap0011*
+ ID_PRODUCT_FROM_DATABASE=G83 (RS 6000) Keyboard
+
+usb:v046Ap0021*
+ ID_PRODUCT_FROM_DATABASE=CyMotion Expert Combo
+
+usb:v046Ap0023*
+ ID_PRODUCT_FROM_DATABASE=CyMotion Master Linux Keyboard G230
+
+usb:v046Ap0027*
+ ID_PRODUCT_FROM_DATABASE=CyMotion Master Solar Keyboard
+
+usb:v046Ap002A*
+ ID_PRODUCT_FROM_DATABASE=Wireless Mouse & Keyboard
+
+usb:v046Ap002D*
+ ID_PRODUCT_FROM_DATABASE=SmartTerminal XX44
+
+usb:v046Ap003E*
+ ID_PRODUCT_FROM_DATABASE=SmartTerminal ST-2xxx
+
+usb:v046Ap0080*
+ ID_PRODUCT_FROM_DATABASE=eHealth Terminal ST 1503
+
+usb:v046Ap0081*
+ ID_PRODUCT_FROM_DATABASE=eHealth Keyboard G87 1504
+
+usb:v046Ap0106*
+ ID_PRODUCT_FROM_DATABASE=R-300 Wireless Mouse Receiver
+
+usb:v046B*
+ ID_VENDOR_FROM_DATABASE=American Megatrends, Inc.
+
+usb:v046Bp0001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v046Bp0101*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard, Mouse & Joystick Ports
+
+usb:v046Bp0301*
+ ID_PRODUCT_FROM_DATABASE=USB 1.0 Hub
+
+usb:v046Bp0500*
+ ID_PRODUCT_FROM_DATABASE=Serial & Parallel Ports
+
+usb:v046BpFF10*
+ ID_PRODUCT_FROM_DATABASE=Virtual Keyboard and Mouse
+
+usb:v046C*
+ ID_VENDOR_FROM_DATABASE=Toshiba Corp., Digital Media Equipment
+
+usb:v046D*
+ ID_VENDOR_FROM_DATABASE=Logitech, Inc.
+
+usb:v046Dp0082*
+ ID_PRODUCT_FROM_DATABASE=Acer Aspire 5672 Webcam
+
+usb:v046Dp0200*
+ ID_PRODUCT_FROM_DATABASE=WingMan Extreme Joystick
+
+usb:v046Dp0203*
+ ID_PRODUCT_FROM_DATABASE=M2452 Keyboard
+
+usb:v046Dp0301*
+ ID_PRODUCT_FROM_DATABASE=M4848 Mouse
+
+usb:v046Dp0401*
+ ID_PRODUCT_FROM_DATABASE=HP PageScan
+
+usb:v046Dp0402*
+ ID_PRODUCT_FROM_DATABASE=NEC PageScan
+
+usb:v046Dp040F*
+ ID_PRODUCT_FROM_DATABASE=Logitech/Storm PageScan
+
+usb:v046Dp0430*
+ ID_PRODUCT_FROM_DATABASE=Mic (Cordless)
+
+usb:v046Dp0801*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Home
+
+usb:v046Dp0802*
+ ID_PRODUCT_FROM_DATABASE=Webcam C200
+
+usb:v046Dp0804*
+ ID_PRODUCT_FROM_DATABASE=Webcam C250
+
+usb:v046Dp0805*
+ ID_PRODUCT_FROM_DATABASE=Webcam C300
+
+usb:v046Dp0807*
+ ID_PRODUCT_FROM_DATABASE=Webcam B500
+
+usb:v046Dp0808*
+ ID_PRODUCT_FROM_DATABASE=Webcam C600
+
+usb:v046Dp0809*
+ ID_PRODUCT_FROM_DATABASE=Webcam Pro 9000
+
+usb:v046Dp080A*
+ ID_PRODUCT_FROM_DATABASE=Portable Webcam C905
+
+usb:v046Dp080F*
+ ID_PRODUCT_FROM_DATABASE=Webcam C120
+
+usb:v046Dp0810*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro
+
+usb:v046Dp0819*
+ ID_PRODUCT_FROM_DATABASE=Webcam C210
+
+usb:v046Dp081B*
+ ID_PRODUCT_FROM_DATABASE=Webcam C310
+
+usb:v046Dp081D*
+ ID_PRODUCT_FROM_DATABASE=HD Webcam C510
+
+usb:v046Dp0820*
+ ID_PRODUCT_FROM_DATABASE=QuickCam VC
+
+usb:v046Dp0821*
+ ID_PRODUCT_FROM_DATABASE=HD Webcam C910
+
+usb:v046Dp0825*
+ ID_PRODUCT_FROM_DATABASE=Webcam C270
+
+usb:v046Dp0828*
+ ID_PRODUCT_FROM_DATABASE=HD Webcam B990
+
+usb:v046Dp082D*
+ ID_PRODUCT_FROM_DATABASE=HD Pro Webcam C920
+
+usb:v046Dp0830*
+ ID_PRODUCT_FROM_DATABASE=QuickClip
+
+usb:v046Dp0840*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express
+
+usb:v046Dp0850*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Web
+
+usb:v046Dp0870*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express
+
+usb:v046Dp0890*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Traveler
+
+usb:v046Dp0892*
+ ID_PRODUCT_FROM_DATABASE=OrbiCam
+
+usb:v046Dp0894*
+ ID_PRODUCT_FROM_DATABASE=CrystalCam
+
+usb:v046Dp0895*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for Dell Notebooks
+
+usb:v046Dp0896*
+ ID_PRODUCT_FROM_DATABASE=OrbiCam
+
+usb:v046Dp0897*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for Dell Notebooks
+
+usb:v046Dp0899*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for Dell Notebooks
+
+usb:v046Dp089D*
+ ID_PRODUCT_FROM_DATABASE=QuickCam E2500 series
+
+usb:v046Dp08A0*
+ ID_PRODUCT_FROM_DATABASE=QuickCam IM
+
+usb:v046Dp08A1*
+ ID_PRODUCT_FROM_DATABASE=QuickCam IM with sound
+
+usb:v046Dp08A2*
+ ID_PRODUCT_FROM_DATABASE=Labtec Webcam Pro
+
+usb:v046Dp08A3*
+ ID_PRODUCT_FROM_DATABASE=QuickCam QuickCam Chat
+
+usb:v046Dp08A6*
+ ID_PRODUCT_FROM_DATABASE=QuickCam IM
+
+usb:v046Dp08A7*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Image
+
+usb:v046Dp08A9*
+ ID_PRODUCT_FROM_DATABASE=Notebook Deluxe
+
+usb:v046Dp08AA*
+ ID_PRODUCT_FROM_DATABASE=Labtec Notebooks
+
+usb:v046Dp08AC*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Cool
+
+usb:v046Dp08AD*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Communicate STX
+
+usb:v046Dp08AE*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for Notebooks
+
+usb:v046Dp08AF*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Easy/Cool
+
+usb:v046Dp08B0*
+ ID_PRODUCT_FROM_DATABASE=QuickCam 3000 Pro [pwc]
+
+usb:v046Dp08B1*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Notebook Pro
+
+usb:v046Dp08B2*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro 4000
+
+usb:v046Dp08B3*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Zoom
+
+usb:v046Dp08B4*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Zoom
+
+usb:v046Dp08B5*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Sphere
+
+usb:v046Dp08B9*
+ ID_PRODUCT_FROM_DATABASE=QuickCam IM
+
+usb:v046Dp08BD*
+ ID_PRODUCT_FROM_DATABASE=Microphone (Pro 4000)
+
+usb:v046Dp08C0*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro 3000
+
+usb:v046Dp08C1*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Fusion
+
+usb:v046Dp08C2*
+ ID_PRODUCT_FROM_DATABASE=QuickCam PTZ
+
+usb:v046Dp08C3*
+ ID_PRODUCT_FROM_DATABASE=Camera (Notebooks Pro)
+
+usb:v046Dp08C5*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro 5000
+
+usb:v046Dp08C6*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for DELL Notebooks
+
+usb:v046Dp08C7*
+ ID_PRODUCT_FROM_DATABASE=QuickCam OEM Cisco VT Camera II
+
+usb:v046Dp08C9*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Ultra Vision
+
+usb:v046Dp08CA*
+ ID_PRODUCT_FROM_DATABASE=Mic (Fusion)
+
+usb:v046Dp08CB*
+ ID_PRODUCT_FROM_DATABASE=Mic (Notebooks Pro)
+
+usb:v046Dp08CC*
+ ID_PRODUCT_FROM_DATABASE=Mic (PTZ)
+
+usb:v046Dp08CE*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro 5000
+
+usb:v046Dp08CF*
+ ID_PRODUCT_FROM_DATABASE=QuickCam UpdateMe
+
+usb:v046Dp08D0*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express
+
+usb:v046Dp08D7*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Communicate STX
+
+usb:v046Dp08D8*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for Notebook Deluxe
+
+usb:v046Dp08D9*
+ ID_PRODUCT_FROM_DATABASE=QuickCam IM/Connect
+
+usb:v046Dp08DA*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Messanger
+
+usb:v046Dp08DD*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for Notebooks
+
+usb:v046Dp08E0*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express
+
+usb:v046Dp08E1*
+ ID_PRODUCT_FROM_DATABASE=Labtec Webcam
+
+usb:v046Dp08F0*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Messenger
+
+usb:v046Dp08F1*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express
+
+usb:v046Dp08F2*
+ ID_PRODUCT_FROM_DATABASE=Microphone (Messenger)
+
+usb:v046Dp08F3*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express
+
+usb:v046Dp08F4*
+ ID_PRODUCT_FROM_DATABASE=Labtec Webcam
+
+usb:v046Dp08F5*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Messenger Communicate
+
+usb:v046Dp08F6*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Messenger Plus
+
+usb:v046Dp0900*
+ ID_PRODUCT_FROM_DATABASE=ClickSmart 310
+
+usb:v046Dp0901*
+ ID_PRODUCT_FROM_DATABASE=ClickSmart 510
+
+usb:v046Dp0903*
+ ID_PRODUCT_FROM_DATABASE=ClickSmart 820
+
+usb:v046Dp0905*
+ ID_PRODUCT_FROM_DATABASE=ClickSmart 820
+
+usb:v046Dp0910*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Cordless
+
+usb:v046Dp0920*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express
+
+usb:v046Dp0921*
+ ID_PRODUCT_FROM_DATABASE=Labtec Webcam
+
+usb:v046Dp0922*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Live
+
+usb:v046Dp0928*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express
+
+usb:v046Dp0929*
+ ID_PRODUCT_FROM_DATABASE=Labtec Webcam Pro
+
+usb:v046Dp092A*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for Notebooks
+
+usb:v046Dp092B*
+ ID_PRODUCT_FROM_DATABASE=Labtec Webcam Plus
+
+usb:v046Dp092C*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Chat
+
+usb:v046Dp092D*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express / Go
+
+usb:v046Dp092E*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Chat
+
+usb:v046Dp092F*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Express Plus
+
+usb:v046Dp0950*
+ ID_PRODUCT_FROM_DATABASE=Pocket Camera
+
+usb:v046Dp0960*
+ ID_PRODUCT_FROM_DATABASE=ClickSmart 420
+
+usb:v046Dp0970*
+ ID_PRODUCT_FROM_DATABASE=Pocket750
+
+usb:v046Dp0990*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro 9000
+
+usb:v046Dp0991*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro for Notebooks
+
+usb:v046Dp0992*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Communicate Deluxe
+
+usb:v046Dp0994*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Orbit/Sphere AF
+
+usb:v046Dp09A1*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Communicate MP/S5500
+
+usb:v046Dp09A2*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Communicate Deluxe/S7500
+
+usb:v046Dp09A4*
+ ID_PRODUCT_FROM_DATABASE=QuickCam E 3500
+
+usb:v046Dp09A5*
+ ID_PRODUCT_FROM_DATABASE=Quickcam 3000 For Business
+
+usb:v046Dp09A6*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Vision Pro
+
+usb:v046Dp09B0*
+ ID_PRODUCT_FROM_DATABASE=Acer OrbiCam
+
+usb:v046Dp09B2*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu Webcam
+
+usb:v046Dp09C0*
+ ID_PRODUCT_FROM_DATABASE=QuickCam for Dell Notebooks Mic
+
+usb:v046Dp09C1*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Deluxe for Notebooks
+
+usb:v046Dp0A01*
+ ID_PRODUCT_FROM_DATABASE=USB Headset
+
+usb:v046Dp0A02*
+ ID_PRODUCT_FROM_DATABASE=Premium Stereo USB Headset 350
+
+usb:v046Dp0A03*
+ ID_PRODUCT_FROM_DATABASE=Logitech USB Microphone
+
+usb:v046Dp0A04*
+ ID_PRODUCT_FROM_DATABASE=V20 portable speakers (USB powered)
+
+usb:v046Dp0A07*
+ ID_PRODUCT_FROM_DATABASE=Z-10 Speakers
+
+usb:v046Dp0A0B*
+ ID_PRODUCT_FROM_DATABASE=ClearChat Pro USB
+
+usb:v046Dp0A0C*
+ ID_PRODUCT_FROM_DATABASE=Clear Chat Comfort USB Headset
+
+usb:v046Dp0A13*
+ ID_PRODUCT_FROM_DATABASE=Z-5 Speakers
+
+usb:v046Dp0A17*
+ ID_PRODUCT_FROM_DATABASE=G330 Headset
+
+usb:v046Dp0B02*
+ ID_PRODUCT_FROM_DATABASE=C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode)
+
+usb:v046Dp8801*
+ ID_PRODUCT_FROM_DATABASE=Video Camera
+
+usb:v046DpB305*
+ ID_PRODUCT_FROM_DATABASE=BT Mini-Receiver
+
+usb:v046DpBFE4*
+ ID_PRODUCT_FROM_DATABASE=Premium Optical Wheel Mouse
+
+usb:v046DpC000*
+ ID_PRODUCT_FROM_DATABASE=N43 [Pilot Mouse]
+
+usb:v046DpC001*
+ ID_PRODUCT_FROM_DATABASE=N48/M-BB48 [FirstMouse Plus]
+
+usb:v046DpC002*
+ ID_PRODUCT_FROM_DATABASE=M-BA47 [MouseMan Plus]
+
+usb:v046DpC003*
+ ID_PRODUCT_FROM_DATABASE=MouseMan
+
+usb:v046DpC004*
+ ID_PRODUCT_FROM_DATABASE=WingMan Gaming Mouse
+
+usb:v046DpC005*
+ ID_PRODUCT_FROM_DATABASE=WingMan Gaming Wheel Mouse
+
+usb:v046DpC00B*
+ ID_PRODUCT_FROM_DATABASE=MouseMan Wheel
+
+usb:v046DpC00C*
+ ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse
+
+usb:v046DpC00D*
+ ID_PRODUCT_FROM_DATABASE=MouseMan Wheel+
+
+usb:v046DpC00E*
+ ID_PRODUCT_FROM_DATABASE=M-BJ58/M-BJ69 Optical Wheel Mouse
+
+usb:v046DpC00F*
+ ID_PRODUCT_FROM_DATABASE=MouseMan Traveler/Mobile
+
+usb:v046DpC011*
+ ID_PRODUCT_FROM_DATABASE=Optical MouseMan
+
+usb:v046DpC012*
+ ID_PRODUCT_FROM_DATABASE=Mouseman Dual Optical
+
+usb:v046DpC014*
+ ID_PRODUCT_FROM_DATABASE=Corded Workstation Mouse
+
+usb:v046DpC015*
+ ID_PRODUCT_FROM_DATABASE=Corded Workstation Mouse
+
+usb:v046DpC016*
+ ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse
+
+usb:v046DpC018*
+ ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse
+
+usb:v046DpC019*
+ ID_PRODUCT_FROM_DATABASE=Optical Tilt Wheel Mouse
+
+usb:v046DpC01A*
+ ID_PRODUCT_FROM_DATABASE=M-BQ85 Optical Wheel Mouse
+
+usb:v046DpC01B*
+ ID_PRODUCT_FROM_DATABASE=MX310 Optical Mouse
+
+usb:v046DpC01C*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v046DpC01D*
+ ID_PRODUCT_FROM_DATABASE=MX510 Optical Mouse
+
+usb:v046DpC01E*
+ ID_PRODUCT_FROM_DATABASE=MX518 Optical Mouse
+
+usb:v046DpC024*
+ ID_PRODUCT_FROM_DATABASE=MX300 Optical Mouse
+
+usb:v046DpC025*
+ ID_PRODUCT_FROM_DATABASE=MX500 Optical Mouse
+
+usb:v046DpC030*
+ ID_PRODUCT_FROM_DATABASE=iFeel Mouse
+
+usb:v046DpC031*
+ ID_PRODUCT_FROM_DATABASE=iFeel Mouse+
+
+usb:v046DpC032*
+ ID_PRODUCT_FROM_DATABASE=MouseMan iFeel
+
+usb:v046DpC033*
+ ID_PRODUCT_FROM_DATABASE=iFeel MouseMan+
+
+usb:v046DpC034*
+ ID_PRODUCT_FROM_DATABASE=MouseMan Optical
+
+usb:v046DpC035*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v046DpC036*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v046DpC037*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v046DpC038*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v046DpC03D*
+ ID_PRODUCT_FROM_DATABASE=M-BT96a Pilot Optical Mouse
+
+usb:v046DpC03E*
+ ID_PRODUCT_FROM_DATABASE=Premium Optical Wheel Mouse (M-BT58)
+
+usb:v046DpC03F*
+ ID_PRODUCT_FROM_DATABASE=M-BT85 [UltraX Optical Mouse]
+
+usb:v046DpC040*
+ ID_PRODUCT_FROM_DATABASE=Corded Tilt-Wheel Mouse
+
+usb:v046DpC041*
+ ID_PRODUCT_FROM_DATABASE=G5 Laser Mouse
+
+usb:v046DpC042*
+ ID_PRODUCT_FROM_DATABASE=G3 Laser Mouse
+
+usb:v046DpC043*
+ ID_PRODUCT_FROM_DATABASE=MX320/MX400 Laser Mouse
+
+usb:v046DpC044*
+ ID_PRODUCT_FROM_DATABASE=LX3 Optical Mouse
+
+usb:v046DpC045*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v046DpC046*
+ ID_PRODUCT_FROM_DATABASE=RX1000 Laser Mouse
+
+usb:v046DpC047*
+ ID_PRODUCT_FROM_DATABASE=Laser Mouse M-UAL120
+
+usb:v046DpC048*
+ ID_PRODUCT_FROM_DATABASE=G9 Laser Mouse
+
+usb:v046DpC049*
+ ID_PRODUCT_FROM_DATABASE=G5 Laser Mouse
+
+usb:v046DpC050*
+ ID_PRODUCT_FROM_DATABASE=RX 250 Optical Mouse
+
+usb:v046DpC051*
+ ID_PRODUCT_FROM_DATABASE=G3 (MX518) Optical Mouse
+
+usb:v046DpC053*
+ ID_PRODUCT_FROM_DATABASE=Laser Mouse
+
+usb:v046DpC054*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth mini-receiver
+
+usb:v046DpC058*
+ ID_PRODUCT_FROM_DATABASE=M115 Mouse
+
+usb:v046DpC05A*
+ ID_PRODUCT_FROM_DATABASE=M90/M100 Optical Mouse
+
+usb:v046DpC05B*
+ ID_PRODUCT_FROM_DATABASE=M-U0004 810-001317 [B110 Optical USB Mouse]
+
+usb:v046DpC05D*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v046DpC05F*
+ ID_PRODUCT_FROM_DATABASE=M115 Optical Mouse
+
+usb:v046DpC061*
+ ID_PRODUCT_FROM_DATABASE=RX1500 Laser Mouse
+
+usb:v046DpC062*
+ ID_PRODUCT_FROM_DATABASE=M-UAS144 [LS1 Laser Mouse]
+
+usb:v046DpC063*
+ ID_PRODUCT_FROM_DATABASE=DELL Laser Mouse
+
+usb:v046DpC068*
+ ID_PRODUCT_FROM_DATABASE=G500 Laser Mouse
+
+usb:v046DpC069*
+ ID_PRODUCT_FROM_DATABASE=M500 Laser Mouse
+
+usb:v046DpC06A*
+ ID_PRODUCT_FROM_DATABASE=USB Optical Mouse
+
+usb:v046DpC06B*
+ ID_PRODUCT_FROM_DATABASE=G700 Wireless Gaming Mouse
+
+usb:v046DpC06C*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v046DpC101*
+ ID_PRODUCT_FROM_DATABASE=UltraX Media Remote
+
+usb:v046DpC110*
+ ID_PRODUCT_FROM_DATABASE=Harmony 885 Remote
+
+usb:v046DpC111*
+ ID_PRODUCT_FROM_DATABASE=Harmony 525 Remote
+
+usb:v046DpC11F*
+ ID_PRODUCT_FROM_DATABASE=Harmony 900 Remote
+
+usb:v046DpC122*
+ ID_PRODUCT_FROM_DATABASE=Harmony 700 Remote
+
+usb:v046DpC201*
+ ID_PRODUCT_FROM_DATABASE=WingMan Extreme Joystick with Throttle
+
+usb:v046DpC202*
+ ID_PRODUCT_FROM_DATABASE=WingMan Formula
+
+usb:v046DpC207*
+ ID_PRODUCT_FROM_DATABASE=WingMan Extreme Digital 3D
+
+usb:v046DpC208*
+ ID_PRODUCT_FROM_DATABASE=WingMan Gamepad Extreme
+
+usb:v046DpC209*
+ ID_PRODUCT_FROM_DATABASE=WingMan Gamepad
+
+usb:v046DpC20A*
+ ID_PRODUCT_FROM_DATABASE=WingMan RumblePad
+
+usb:v046DpC20B*
+ ID_PRODUCT_FROM_DATABASE=WingMan Action Pad
+
+usb:v046DpC20C*
+ ID_PRODUCT_FROM_DATABASE=WingMan Precision
+
+usb:v046DpC20D*
+ ID_PRODUCT_FROM_DATABASE=WingMan Attack 2
+
+usb:v046DpC20E*
+ ID_PRODUCT_FROM_DATABASE=WingMan Formula GP
+
+usb:v046DpC211*
+ ID_PRODUCT_FROM_DATABASE=iTouch Cordless Reciever
+
+usb:v046DpC212*
+ ID_PRODUCT_FROM_DATABASE=WingMan Extreme Digital 3D
+
+usb:v046DpC213*
+ ID_PRODUCT_FROM_DATABASE=J-UH16 (Freedom 2.4 Cordless Joystick)
+
+usb:v046DpC214*
+ ID_PRODUCT_FROM_DATABASE=ATK3 (Attack III Joystick)
+
+usb:v046DpC215*
+ ID_PRODUCT_FROM_DATABASE=Extreme 3D Pro
+
+usb:v046DpC216*
+ ID_PRODUCT_FROM_DATABASE=Dual Action Gamepad
+
+usb:v046DpC218*
+ ID_PRODUCT_FROM_DATABASE=Logitech RumblePad 2 USB
+
+usb:v046DpC219*
+ ID_PRODUCT_FROM_DATABASE=Cordless RumblePad 2
+
+usb:v046DpC21A*
+ ID_PRODUCT_FROM_DATABASE=Precision Gamepad
+
+usb:v046DpC21C*
+ ID_PRODUCT_FROM_DATABASE=G13 Advanced Gameboard
+
+usb:v046DpC21D*
+ ID_PRODUCT_FROM_DATABASE=F310 Gamepad [XInput Mode]
+
+usb:v046DpC21E*
+ ID_PRODUCT_FROM_DATABASE=F510 Gamepad [XInput Mode]
+
+usb:v046DpC21F*
+ ID_PRODUCT_FROM_DATABASE=F710 Wireless Gamepad [XInput Mode]
+
+usb:v046DpC221*
+ ID_PRODUCT_FROM_DATABASE=G11/G15 Keyboard / Keyboard
+
+usb:v046DpC222*
+ ID_PRODUCT_FROM_DATABASE=G15 Keyboard / LCD
+
+usb:v046DpC223*
+ ID_PRODUCT_FROM_DATABASE=G11/G15 Keyboard / USB Hub
+
+usb:v046DpC225*
+ ID_PRODUCT_FROM_DATABASE=G11/G15 Keyboard / G keys
+
+usb:v046DpC226*
+ ID_PRODUCT_FROM_DATABASE=G15 Refresh Keyboard
+
+usb:v046DpC227*
+ ID_PRODUCT_FROM_DATABASE=G15 Refresh Keyboard
+
+usb:v046DpC22A*
+ ID_PRODUCT_FROM_DATABASE=Gaming Keyboard G110
+
+usb:v046DpC22B*
+ ID_PRODUCT_FROM_DATABASE=Gaming Keyboard G110 G-keys
+
+usb:v046DpC22D*
+ ID_PRODUCT_FROM_DATABASE=G510 Gaming Keyboard
+
+usb:v046DpC22E*
+ ID_PRODUCT_FROM_DATABASE=G510 Gaming Keyboard onboard audio
+
+usb:v046DpC246*
+ ID_PRODUCT_FROM_DATABASE=Gaming Mouse G300
+
+usb:v046DpC281*
+ ID_PRODUCT_FROM_DATABASE=WingMan Force
+
+usb:v046DpC283*
+ ID_PRODUCT_FROM_DATABASE=WingMan Force 3D
+
+usb:v046DpC285*
+ ID_PRODUCT_FROM_DATABASE=WingMan Strike Force 3D
+
+usb:v046DpC286*
+ ID_PRODUCT_FROM_DATABASE=Force 3D Pro
+
+usb:v046DpC287*
+ ID_PRODUCT_FROM_DATABASE=Flight System G940
+
+usb:v046DpC291*
+ ID_PRODUCT_FROM_DATABASE=WingMan Formula Force
+
+usb:v046DpC293*
+ ID_PRODUCT_FROM_DATABASE=WingMan Formula Force GP
+
+usb:v046DpC294*
+ ID_PRODUCT_FROM_DATABASE=Driving Force
+
+usb:v046DpC295*
+ ID_PRODUCT_FROM_DATABASE=Momo Force Steering Wheel
+
+usb:v046DpC298*
+ ID_PRODUCT_FROM_DATABASE=Driving Force Pro
+
+usb:v046DpC299*
+ ID_PRODUCT_FROM_DATABASE=G25 Racing Wheel
+
+usb:v046DpC29B*
+ ID_PRODUCT_FROM_DATABASE=G27 Racing Wheel
+
+usb:v046DpC29C*
+ ID_PRODUCT_FROM_DATABASE=Speed Force Wireless Wheel for Wii
+
+usb:v046DpC2A0*
+ ID_PRODUCT_FROM_DATABASE=Wingman Force Feedback Mouse
+
+usb:v046DpC2A1*
+ ID_PRODUCT_FROM_DATABASE=WingMan Force Feedback Mouse
+
+usb:v046DpC301*
+ ID_PRODUCT_FROM_DATABASE=iTouch Keyboard
+
+usb:v046DpC302*
+ ID_PRODUCT_FROM_DATABASE=iTouch Pro Keyboard
+
+usb:v046DpC303*
+ ID_PRODUCT_FROM_DATABASE=iTouch Keyboard
+
+usb:v046DpC305*
+ ID_PRODUCT_FROM_DATABASE=Internet Keyboard
+
+usb:v046DpC307*
+ ID_PRODUCT_FROM_DATABASE=Internet Keyboard
+
+usb:v046DpC308*
+ ID_PRODUCT_FROM_DATABASE=Internet Navigator Keyboard
+
+usb:v046DpC309*
+ ID_PRODUCT_FROM_DATABASE=Internet Keyboard
+
+usb:v046DpC30A*
+ ID_PRODUCT_FROM_DATABASE=iTouch Composite
+
+usb:v046DpC30B*
+ ID_PRODUCT_FROM_DATABASE=NetPlay Keyboard
+
+usb:v046DpC30C*
+ ID_PRODUCT_FROM_DATABASE=Internet Keys (X)
+
+usb:v046DpC30D*
+ ID_PRODUCT_FROM_DATABASE=Internet Keys
+
+usb:v046DpC30E*
+ ID_PRODUCT_FROM_DATABASE=UltraX Keyboard (Y-BL49)
+
+usb:v046DpC30F*
+ ID_PRODUCT_FROM_DATABASE=Logicool HID-Compliant Keyboard (106 key)
+
+usb:v046DpC311*
+ ID_PRODUCT_FROM_DATABASE=Y-UF49 [Internet Pro Keyboard]
+
+usb:v046DpC312*
+ ID_PRODUCT_FROM_DATABASE=DeLuxe 250 Keyboard
+
+usb:v046DpC313*
+ ID_PRODUCT_FROM_DATABASE=Internet 350 Keyboard
+
+usb:v046DpC315*
+ ID_PRODUCT_FROM_DATABASE=Classic New Touch Keyboard
+
+usb:v046DpC316*
+ ID_PRODUCT_FROM_DATABASE=HID-Compliant Keyboard
+
+usb:v046DpC317*
+ ID_PRODUCT_FROM_DATABASE=Wave Corded Keyboard
+
+usb:v046DpC318*
+ ID_PRODUCT_FROM_DATABASE=Illuminated Keyboard
+
+usb:v046DpC31A*
+ ID_PRODUCT_FROM_DATABASE=Comfort Wave 450
+
+usb:v046DpC31B*
+ ID_PRODUCT_FROM_DATABASE=Compact Keyboard K300
+
+usb:v046DpC31C*
+ ID_PRODUCT_FROM_DATABASE=Keyboard K120 for Business
+
+usb:v046DpC31D*
+ ID_PRODUCT_FROM_DATABASE=Media Keyboard K200
+
+usb:v046DpC401*
+ ID_PRODUCT_FROM_DATABASE=TrackMan Marble Wheel
+
+usb:v046DpC402*
+ ID_PRODUCT_FROM_DATABASE=Marble Mouse (2-button)
+
+usb:v046DpC403*
+ ID_PRODUCT_FROM_DATABASE=Turbo TrackMan Marble FX
+
+usb:v046DpC404*
+ ID_PRODUCT_FROM_DATABASE=TrackMan Wheel
+
+usb:v046DpC408*
+ ID_PRODUCT_FROM_DATABASE=Marble Mouse (4-button)
+
+usb:v046DpC501*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse Receiver
+
+usb:v046DpC502*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse & iTouch Keys
+
+usb:v046DpC503*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse+Keyboard Receiver
+
+usb:v046DpC504*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse+Keyboard Receiver
+
+usb:v046DpC505*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse+Keyboard Receiver
+
+usb:v046DpC506*
+ ID_PRODUCT_FROM_DATABASE=MX700 Cordless Mouse Receiver
+
+usb:v046DpC508*
+ ID_PRODUCT_FROM_DATABASE=Cordless Trackball
+
+usb:v046DpC509*
+ ID_PRODUCT_FROM_DATABASE=Cordless Keyboard & Mouse
+
+usb:v046DpC50A*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse
+
+usb:v046DpC50B*
+ ID_PRODUCT_FROM_DATABASE=Cordless Desktop Optical
+
+usb:v046DpC50C*
+ ID_PRODUCT_FROM_DATABASE=Cordless Desktop S510
+
+usb:v046DpC50D*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse
+
+usb:v046DpC50E*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse Receiver
+
+usb:v046DpC510*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse
+
+usb:v046DpC512*
+ ID_PRODUCT_FROM_DATABASE=LX-700 Cordless Desktop Receiver
+
+usb:v046DpC513*
+ ID_PRODUCT_FROM_DATABASE=MX3000 Cordless Desktop Receiver
+
+usb:v046DpC514*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse
+
+usb:v046DpC515*
+ ID_PRODUCT_FROM_DATABASE=Cordless 2.4 GHz Presenter Presentation remote control
+
+usb:v046DpC517*
+ ID_PRODUCT_FROM_DATABASE=LX710 Cordless Desktop Laser
+
+usb:v046DpC518*
+ ID_PRODUCT_FROM_DATABASE=MX610 Laser Cordless Mouse
+
+usb:v046DpC51A*
+ ID_PRODUCT_FROM_DATABASE=MX Revolution/G7 Cordless Mouse
+
+usb:v046DpC51B*
+ ID_PRODUCT_FROM_DATABASE=V220 Cordless Optical Mouse for Notebooks
+
+usb:v046DpC521*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse Receiver
+
+usb:v046DpC525*
+ ID_PRODUCT_FROM_DATABASE=MX Revolution Cordless Mouse
+
+usb:v046DpC526*
+ ID_PRODUCT_FROM_DATABASE=Nano Receiver
+
+usb:v046DpC529*
+ ID_PRODUCT_FROM_DATABASE=diNovo Keyboard for notebooks
+
+usb:v046DpC52B*
+ ID_PRODUCT_FROM_DATABASE=Unifying Receiver
+
+usb:v046DpC52F*
+ ID_PRODUCT_FROM_DATABASE=Wireless Mouse M305
+
+usb:v046DpC623*
+ ID_PRODUCT_FROM_DATABASE=3Dconnexion Space Traveller 3D Mouse
+
+usb:v046DpC625*
+ ID_PRODUCT_FROM_DATABASE=3Dconnexion Space Pilot 3D Mouse
+
+usb:v046DpC626*
+ ID_PRODUCT_FROM_DATABASE=3Dconnexion Space Navigator 3D Mouse
+
+usb:v046DpC627*
+ ID_PRODUCT_FROM_DATABASE=3Dconnexion Space Explorer 3D Mouse
+
+usb:v046DpC702*
+ ID_PRODUCT_FROM_DATABASE=Cordless Presenter
+
+usb:v046DpC703*
+ ID_PRODUCT_FROM_DATABASE=Elite Keyboard Y-RP20 + Mouse MX900 (Bluetooth)
+
+usb:v046DpC704*
+ ID_PRODUCT_FROM_DATABASE=diNovo Wireless Desktop
+
+usb:v046DpC705*
+ ID_PRODUCT_FROM_DATABASE=MX900 Bluetooth Wireless Hub (C-UJ16A)
+
+usb:v046DpC707*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpC708*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpC709*
+ ID_PRODUCT_FROM_DATABASE=BT Mini-Receiver (HCI mode)
+
+usb:v046DpC70A*
+ ID_PRODUCT_FROM_DATABASE=MX5000 Cordless Desktop
+
+usb:v046DpC70B*
+ ID_PRODUCT_FROM_DATABASE=BT Mini-Receiver (HID proxy mode)
+
+usb:v046DpC70C*
+ ID_PRODUCT_FROM_DATABASE=BT Mini-Receiver (HID proxy mode)
+
+usb:v046DpC70D*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpC70E*
+ ID_PRODUCT_FROM_DATABASE=MX1000 Bluetooth Laser Mouse
+
+usb:v046DpC70F*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpC712*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpC714*
+ ID_PRODUCT_FROM_DATABASE=diNovo Edge Keyboard
+
+usb:v046DpC715*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpC71A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpC71D*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpC71F*
+ ID_PRODUCT_FROM_DATABASE=diNovo Mini Wireless Keyboard
+
+usb:v046DpC720*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub
+
+usb:v046DpCA03*
+ ID_PRODUCT_FROM_DATABASE=MOMO Racing
+
+usb:v046DpCA04*
+ ID_PRODUCT_FROM_DATABASE=Formula Vibration Feedback Wheel
+
+usb:v046DpCAB1*
+ ID_PRODUCT_FROM_DATABASE=Cordless Keyboard for Wii HID Receiver
+
+usb:v046DpD001*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro
+
+usb:v046E*
+ ID_VENDOR_FROM_DATABASE=Behavior Tech. Computer Corp.
+
+usb:v046Ep0100*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v046Ep3001*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v046Ep3002*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v046Ep3003*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v046Ep3005*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v046Ep3008*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v046Ep5250*
+ ID_PRODUCT_FROM_DATABASE=KeyMaestro Multimedia Keyboard
+
+usb:v046Ep5273*
+ ID_PRODUCT_FROM_DATABASE=KeyMaestro Multimedia Keyboard
+
+usb:v046Ep52E6*
+ ID_PRODUCT_FROM_DATABASE=Cordless Mouse
+
+usb:v046Ep5308*
+ ID_PRODUCT_FROM_DATABASE=KeyMaestro Keyboard
+
+usb:v046Ep5408*
+ ID_PRODUCT_FROM_DATABASE=KeyMaestro Multimedia Keyboard/Hub
+
+usb:v046Ep5500*
+ ID_PRODUCT_FROM_DATABASE=Portable Keyboard 86+9 keys (Model 6100C US)
+
+usb:v046Ep5720*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Reader
+
+usb:v046Ep6782*
+ ID_PRODUCT_FROM_DATABASE=BTC 7932 mouse+keyboard
+
+usb:v046F*
+ ID_VENDOR_FROM_DATABASE=Crystal Semiconductor
+
+usb:v0471*
+ ID_VENDOR_FROM_DATABASE=Philips (or NXP)
+
+usb:v0471p0101*
+ ID_PRODUCT_FROM_DATABASE=DSS350 Digital Speaker System
+
+usb:v0471p0104*
+ ID_PRODUCT_FROM_DATABASE=DSS330 Digital Speaker System [uda1321]
+
+usb:v0471p0105*
+ ID_PRODUCT_FROM_DATABASE=UDA1321
+
+usb:v0471p014F*
+ ID_PRODUCT_FROM_DATABASE=GoGear SA9200
+
+usb:v0471p0160*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0471p0161*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0471p0163*
+ ID_PRODUCT_FROM_DATABASE=GoGear SA1100
+
+usb:v0471p0164*
+ ID_PRODUCT_FROM_DATABASE=GoGear SA1110/02
+
+usb:v0471p0165*
+ ID_PRODUCT_FROM_DATABASE=GoGear SA1330
+
+usb:v0471p0201*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0471p0222*
+ ID_PRODUCT_FROM_DATABASE=Creative Nomad Jukebox
+
+usb:v0471p0302*
+ ID_PRODUCT_FROM_DATABASE=PCA645VC Webcam [pwc]
+
+usb:v0471p0303*
+ ID_PRODUCT_FROM_DATABASE=PCA646VC Webcam [pwc]
+
+usb:v0471p0304*
+ ID_PRODUCT_FROM_DATABASE=Askey VC010 Webcam [pwc]
+
+usb:v0471p0307*
+ ID_PRODUCT_FROM_DATABASE=PCVC675K Webcam [pwc]
+
+usb:v0471p0308*
+ ID_PRODUCT_FROM_DATABASE=PCVC680K Webcam [pwc]
+
+usb:v0471p030B*
+ ID_PRODUCT_FROM_DATABASE=PC VGA Camera (Vesta Fun)
+
+usb:v0471p030C*
+ ID_PRODUCT_FROM_DATABASE=PCVC690K Webcam [pwc]
+
+usb:v0471p0310*
+ ID_PRODUCT_FROM_DATABASE=PCVC730K Webcam [pwc]
+
+usb:v0471p0311*
+ ID_PRODUCT_FROM_DATABASE=PCVC740K ToUcam Pro [pwc]
+
+usb:v0471p0312*
+ ID_PRODUCT_FROM_DATABASE=PCVC750K Webcam [pwc]
+
+usb:v0471p0314*
+ ID_PRODUCT_FROM_DATABASE=DMVC 1000K
+
+usb:v0471p0316*
+ ID_PRODUCT_FROM_DATABASE=DMVC 2000K Video Capture
+
+usb:v0471p0321*
+ ID_PRODUCT_FROM_DATABASE=FunCam
+
+usb:v0471p0322*
+ ID_PRODUCT_FROM_DATABASE=DMVC1300K PC Camera
+
+usb:v0471p0325*
+ ID_PRODUCT_FROM_DATABASE=SPC 200NC PC Camera
+
+usb:v0471p0326*
+ ID_PRODUCT_FROM_DATABASE=SPC 300NC PC Camera
+
+usb:v0471p0327*
+ ID_PRODUCT_FROM_DATABASE=Webcam SPC 6000 NC (Webcam w/ mic)
+
+usb:v0471p0328*
+ ID_PRODUCT_FROM_DATABASE=SPC 700NC PC Camera
+
+usb:v0471p0329*
+ ID_PRODUCT_FROM_DATABASE=SPC 900NC PC Camera / ORITE CCD Webcam(PC370R)
+
+usb:v0471p032D*
+ ID_PRODUCT_FROM_DATABASE=SPC 210NC PC Camera
+
+usb:v0471p032E*
+ ID_PRODUCT_FROM_DATABASE=SPC 315NC PC Camera
+
+usb:v0471p0330*
+ ID_PRODUCT_FROM_DATABASE=SPC 710NC PC Camera
+
+usb:v0471p0331*
+ ID_PRODUCT_FROM_DATABASE=SPC 1300NC PC Camera
+
+usb:v0471p0332*
+ ID_PRODUCT_FROM_DATABASE=SPC 1000NC PC Camera
+
+usb:v0471p0333*
+ ID_PRODUCT_FROM_DATABASE=SPC 620NC PC Camera
+
+usb:v0471p0334*
+ ID_PRODUCT_FROM_DATABASE=SPC 520/525NC PC Camera
+
+usb:v0471p0401*
+ ID_PRODUCT_FROM_DATABASE=Semiconductors CICT Keyboard
+
+usb:v0471p0402*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Mouse on Semiconductors CICT Keyboard
+
+usb:v0471p0406*
+ ID_PRODUCT_FROM_DATABASE=15 inch Detachable Monitor
+
+usb:v0471p0407*
+ ID_PRODUCT_FROM_DATABASE=10 inch Mobile Monitor
+
+usb:v0471p0408*
+ ID_PRODUCT_FROM_DATABASE=SG3WA1/74 802.11b WLAN Adapter [Atmel AT76C503A]
+
+usb:v0471p0471*
+ ID_PRODUCT_FROM_DATABASE=Digital Speaker System
+
+usb:v0471p0601*
+ ID_PRODUCT_FROM_DATABASE=OVU1020 IR Dongle (Kbd+Mouse)
+
+usb:v0471p0602*
+ ID_PRODUCT_FROM_DATABASE=ATI Remote Wonder II Input Device
+
+usb:v0471p0603*
+ ID_PRODUCT_FROM_DATABASE=ATI Remote Wonder II Controller
+
+usb:v0471p0608*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0471p060A*
+ ID_PRODUCT_FROM_DATABASE=TSU9600 Remote Control
+
+usb:v0471p060C*
+ ID_PRODUCT_FROM_DATABASE=Consumer Infrared Transceiver (HP)
+
+usb:v0471p060D*
+ ID_PRODUCT_FROM_DATABASE=Consumer Infrared Transceiver (SRM5100)
+
+usb:v0471p060E*
+ ID_PRODUCT_FROM_DATABASE=RF Dongle
+
+usb:v0471p060F*
+ ID_PRODUCT_FROM_DATABASE=Consumer Infrared Transceiver
+
+usb:v0471p0613*
+ ID_PRODUCT_FROM_DATABASE=Infrared Transceiver
+
+usb:v0471p0617*
+ ID_PRODUCT_FROM_DATABASE=IEEE802.15.4 RF Dongle
+
+usb:v0471p0619*
+ ID_PRODUCT_FROM_DATABASE=TSU9400 Remote Control
+
+usb:v0471p0666*
+ ID_PRODUCT_FROM_DATABASE=Hantek DDS-3005 Arbitrary Waveform Generator
+
+usb:v0471p0700*
+ ID_PRODUCT_FROM_DATABASE=Semiconductors CICT Hub
+
+usb:v0471p0701*
+ ID_PRODUCT_FROM_DATABASE=150P1 TFT Display
+
+usb:v0471p0809*
+ ID_PRODUCT_FROM_DATABASE=AVNET Bluetooth Device
+
+usb:v0471p0811*
+ ID_PRODUCT_FROM_DATABASE=JR24 CDRW
+
+usb:v0471p0814*
+ ID_PRODUCT_FROM_DATABASE=DCCX38/P data cable
+
+usb:v0471p0815*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0471p0844*
+ ID_PRODUCT_FROM_DATABASE=SA2111/02 1GB Flash Audio Player
+
+usb:v0471p084A*
+ ID_PRODUCT_FROM_DATABASE=GoGear SA3125
+
+usb:v0471p084E*
+ ID_PRODUCT_FROM_DATABASE=GoGear SA60xx (mtp)
+
+usb:v0471p0888*
+ ID_PRODUCT_FROM_DATABASE=Hantek DDS-3005 Arbitrary Waveform Generator
+
+usb:v0471p1103*
+ ID_PRODUCT_FROM_DATABASE=Digital Speaker System
+
+usb:v0471p1120*
+ ID_PRODUCT_FROM_DATABASE=Creative Rhomba MP3 player
+
+usb:v0471p1125*
+ ID_PRODUCT_FROM_DATABASE=Nike psa[128max Player
+
+usb:v0471p1137*
+ ID_PRODUCT_FROM_DATABASE=HDD065 MP3 player
+
+usb:v0471p1201*
+ ID_PRODUCT_FROM_DATABASE=Arima Bluetooth Device
+
+usb:v0471p1230*
+ ID_PRODUCT_FROM_DATABASE=Wireless Adapter 11g
+
+usb:v0471p1232*
+ ID_PRODUCT_FROM_DATABASE=SNU6500 Wireless Adapter
+
+usb:v0471p1233*
+ ID_PRODUCT_FROM_DATABASE=Wireless Adapter Bootloader Download
+
+usb:v0471p1236*
+ ID_PRODUCT_FROM_DATABASE=SNU5600 802.11bg
+
+usb:v0471p1237*
+ ID_PRODUCT_FROM_DATABASE=TalkTalk SNU5630NS/05 802.11bg
+
+usb:v0471p1552*
+ ID_PRODUCT_FROM_DATABASE=ISP 1581 Hi-Speed USB MPEG2 Encoder Reference Kit
+
+usb:v0471p1801*
+ ID_PRODUCT_FROM_DATABASE=Diva MP3 player
+
+usb:v0471p200A*
+ ID_PRODUCT_FROM_DATABASE=Wireless Network Adapter
+
+usb:v0471p200F*
+ ID_PRODUCT_FROM_DATABASE=802.11n Wireless Adapter
+
+usb:v0471p2021*
+ ID_PRODUCT_FROM_DATABASE=SDE3273FC/97 2.5" SATA HDD Enclosure [INIC-1608L]
+
+usb:v0471p2022*
+ ID_PRODUCT_FROM_DATABASE=GoGear SA52XX
+
+usb:v0471p2034*
+ ID_PRODUCT_FROM_DATABASE=Webcam SPC530NC
+
+usb:v0471p2036*
+ ID_PRODUCT_FROM_DATABASE=Webcam SPC1030NC
+
+usb:v0471p203F*
+ ID_PRODUCT_FROM_DATABASE=TSU9200 Remote Control
+
+usb:v0471p2046*
+ ID_PRODUCT_FROM_DATABASE=TSU9800 Remote Control
+
+usb:v0471p204E*
+ ID_PRODUCT_FROM_DATABASE=GoGear RaGa (SA1942/02)
+
+usb:v0471p205E*
+ ID_PRODUCT_FROM_DATABASE=TSU9300 Remote Control
+
+usb:v0471p206C*
+ ID_PRODUCT_FROM_DATABASE=MCE IR Receiver - Spinel plusf0r ASUS
+
+usb:v0471p2070*
+ ID_PRODUCT_FROM_DATABASE=GoGear Mix
+
+usb:v0471p2076*
+ ID_PRODUCT_FROM_DATABASE=GoGear Aria
+
+usb:v0471p2079*
+ ID_PRODUCT_FROM_DATABASE=GoGear Opus
+
+usb:v0471p2088*
+ ID_PRODUCT_FROM_DATABASE=MCE IR Receiver with ALS- Spinel plus for ASUS
+
+usb:v0471p209E*
+ ID_PRODUCT_FROM_DATABASE=PTA01 Wireless Adapter
+
+usb:v0471p20B6*
+ ID_PRODUCT_FROM_DATABASE=GoGear Vibe
+
+usb:v0471p20D0*
+ ID_PRODUCT_FROM_DATABASE=SPZ2000 Webcam [PixArt PAC7332]
+
+usb:v0471p20E3*
+ ID_PRODUCT_FROM_DATABASE=GoGear Raga
+
+usb:v0471p262C*
+ ID_PRODUCT_FROM_DATABASE=SPC230NC Webcam
+
+usb:v0471p485D*
+ ID_PRODUCT_FROM_DATABASE=Senselock SenseIV v2.x
+
+usb:v0471pDF55*
+ ID_PRODUCT_FROM_DATABASE=LPCXpresso LPC-Link
+
+usb:v0472*
+ ID_VENDOR_FROM_DATABASE=Chicony Electronics Co., Ltd
+
+usb:v0472p0065*
+ ID_PRODUCT_FROM_DATABASE=PFU-65 Keyboard [Chicony]
+
+usb:v0472pB086*
+ ID_PRODUCT_FROM_DATABASE=Asus USB2.0 Webcam
+
+usb:v0472pB091*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v0473*
+ ID_VENDOR_FROM_DATABASE=Sanyo Information Business Co., Ltd
+
+usb:v0474*
+ ID_VENDOR_FROM_DATABASE=Sanyo Electric Co., Ltd
+
+usb:v0474p0110*
+ ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder R200
+
+usb:v0474p0217*
+ ID_PRODUCT_FROM_DATABASE=Xacti J2
+
+usb:v0474p022F*
+ ID_PRODUCT_FROM_DATABASE=C5 Digital Media Camera (mass storage mode)
+
+usb:v0474p0230*
+ ID_PRODUCT_FROM_DATABASE=C5 Digital Media Camera (PictBridge mode)
+
+usb:v0474p0231*
+ ID_PRODUCT_FROM_DATABASE=C5 Digital Media Camera (PC control mode)
+
+usb:v0474p0401*
+ ID_PRODUCT_FROM_DATABASE=Optical Drive
+
+usb:v0474p0701*
+ ID_PRODUCT_FROM_DATABASE=SCP-4900 Cellphone
+
+usb:v0474p071F*
+ ID_PRODUCT_FROM_DATABASE=Usb Com Port Enumerator
+
+usb:v0474p0722*
+ ID_PRODUCT_FROM_DATABASE=W33SA Camera
+
+usb:v0475*
+ ID_VENDOR_FROM_DATABASE=Relisys/Teco Information System
+
+usb:v0475p0100*
+ ID_PRODUCT_FROM_DATABASE=NEC Petiscan
+
+usb:v0475p0103*
+ ID_PRODUCT_FROM_DATABASE=Eclipse 1200U/Episode
+
+usb:v0475p0210*
+ ID_PRODUCT_FROM_DATABASE=Scorpio Ultra 3
+
+usb:v0476*
+ ID_VENDOR_FROM_DATABASE=AESP
+
+usb:v0477*
+ ID_VENDOR_FROM_DATABASE=Seagate Technology, Inc.
+
+usb:v0478*
+ ID_VENDOR_FROM_DATABASE=Connectix Corp.
+
+usb:v0478p0001*
+ ID_PRODUCT_FROM_DATABASE=QuickCam
+
+usb:v0478p0002*
+ ID_PRODUCT_FROM_DATABASE=QuickClip
+
+usb:v0478p0003*
+ ID_PRODUCT_FROM_DATABASE=QuickCam Pro
+
+usb:v0479*
+ ID_VENDOR_FROM_DATABASE=Advanced Peripheral Laboratories
+
+usb:v047A*
+ ID_VENDOR_FROM_DATABASE=Semtech Corp.
+
+usb:v047Ap0004*
+ ID_PRODUCT_FROM_DATABASE=ScreenCoder UR7HCTS2-USB
+
+usb:v047B*
+ ID_VENDOR_FROM_DATABASE=Silitek Corp.
+
+usb:v047Bp0001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v047Bp0002*
+ ID_PRODUCT_FROM_DATABASE=Keyboard and Mouse
+
+usb:v047Bp0011*
+ ID_PRODUCT_FROM_DATABASE=SK-1688U Keyboard
+
+usb:v047Bp00F9*
+ ID_PRODUCT_FROM_DATABASE=SK-1789u Keyboard
+
+usb:v047Bp0101*
+ ID_PRODUCT_FROM_DATABASE=BlueTooth Keyboard and Mouse
+
+usb:v047Bp020B*
+ ID_PRODUCT_FROM_DATABASE=SK-3105 SmartCard Reader
+
+usb:v047Bp050E*
+ ID_PRODUCT_FROM_DATABASE=Internet Compact Keyboard
+
+usb:v047Bp1000*
+ ID_PRODUCT_FROM_DATABASE=Trust Office Scan USB 19200
+
+usb:v047Bp1002*
+ ID_PRODUCT_FROM_DATABASE=HP ScanJet 4300c Parallel Port
+
+usb:v047C*
+ ID_VENDOR_FROM_DATABASE=Dell Computer Corp.
+
+usb:v047D*
+ ID_VENDOR_FROM_DATABASE=Kensington
+
+usb:v047Dp1001*
+ ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box
+
+usb:v047Dp1002*
+ ID_PRODUCT_FROM_DATABASE=Expert Mouse Pro
+
+usb:v047Dp1003*
+ ID_PRODUCT_FROM_DATABASE=Orbit TrackBall
+
+usb:v047Dp1004*
+ ID_PRODUCT_FROM_DATABASE=MouseWorks
+
+usb:v047Dp1005*
+ ID_PRODUCT_FROM_DATABASE=TurboBall
+
+usb:v047Dp1006*
+ ID_PRODUCT_FROM_DATABASE=TurboRing
+
+usb:v047Dp1009*
+ ID_PRODUCT_FROM_DATABASE=Orbit TrackBall for Mac
+
+usb:v047Dp1012*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse
+
+usb:v047Dp1013*
+ ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical Pro
+
+usb:v047Dp1014*
+ ID_PRODUCT_FROM_DATABASE=Expert Mouse Pro Wireless
+
+usb:v047Dp1015*
+ ID_PRODUCT_FROM_DATABASE=Expert Mouse
+
+usb:v047Dp1016*
+ ID_PRODUCT_FROM_DATABASE=ADB/USB Orbit
+
+usb:v047Dp1018*
+ ID_PRODUCT_FROM_DATABASE=Studio Mouse
+
+usb:v047Dp101D*
+ ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical Pro
+
+usb:v047Dp101E*
+ ID_PRODUCT_FROM_DATABASE=Studio Mouse Wireless
+
+usb:v047Dp101F*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse Pro
+
+usb:v047Dp1020*
+ ID_PRODUCT_FROM_DATABASE=Expert Mouse Trackball
+
+usb:v047Dp1021*
+ ID_PRODUCT_FROM_DATABASE=Expert Mouse Wireless
+
+usb:v047Dp1022*
+ ID_PRODUCT_FROM_DATABASE=Orbit Optical
+
+usb:v047Dp1023*
+ ID_PRODUCT_FROM_DATABASE=Pocket Mouse Pro Wireless
+
+usb:v047Dp1024*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse
+
+usb:v047Dp1025*
+ ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical Elite Wireless
+
+usb:v047Dp1026*
+ ID_PRODUCT_FROM_DATABASE=Pocket Mouse Pro
+
+usb:v047Dp1027*
+ ID_PRODUCT_FROM_DATABASE=StudioMouse
+
+usb:v047Dp1028*
+ ID_PRODUCT_FROM_DATABASE=StudioMouse Wireless
+
+usb:v047Dp1029*
+ ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical Elite
+
+usb:v047Dp102A*
+ ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical
+
+usb:v047Dp102B*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse
+
+usb:v047Dp102C*
+ ID_PRODUCT_FROM_DATABASE=Iridio
+
+usb:v047Dp102D*
+ ID_PRODUCT_FROM_DATABASE=Pilot Optical
+
+usb:v047Dp102E*
+ ID_PRODUCT_FROM_DATABASE=Pilot Optical Pro
+
+usb:v047Dp102F*
+ ID_PRODUCT_FROM_DATABASE=Pilot Optical Pro Wireless
+
+usb:v047Dp1042*
+ ID_PRODUCT_FROM_DATABASE=Ci25m Notebook Optical Mouse [Diamond Eye Precision]
+
+usb:v047Dp1043*
+ ID_PRODUCT_FROM_DATABASE=Ci65m Wireless Notebook Optical Mouse
+
+usb:v047Dp104A*
+ ID_PRODUCT_FROM_DATABASE=PilotMouse Mini Retractable
+
+usb:v047Dp105D*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse Bluetooth
+
+usb:v047Dp105E*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Dongle
+
+usb:v047Dp1061*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse Grip
+
+usb:v047Dp1062*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse Max
+
+usb:v047Dp1063*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse Max Wireless
+
+usb:v047Dp1064*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse 2.0 Wireless
+
+usb:v047Dp1065*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse 2.0
+
+usb:v047Dp1066*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse Max Glow
+
+usb:v047Dp1067*
+ ID_PRODUCT_FROM_DATABASE=ValueMouse
+
+usb:v047Dp1068*
+ ID_PRODUCT_FROM_DATABASE=ValueOpt White
+
+usb:v047Dp1069*
+ ID_PRODUCT_FROM_DATABASE=ValueOpt Black
+
+usb:v047Dp106A*
+ ID_PRODUCT_FROM_DATABASE=PilotMouse Laser Wireless Mini
+
+usb:v047Dp106B*
+ ID_PRODUCT_FROM_DATABASE=PilotMouse Laser - 3 Button
+
+usb:v047Dp106C*
+ ID_PRODUCT_FROM_DATABASE=PilotMouse Laser - Gaming
+
+usb:v047Dp106D*
+ ID_PRODUCT_FROM_DATABASE=PilotMouse Laser - Wired
+
+usb:v047Dp106E*
+ ID_PRODUCT_FROM_DATABASE=PilotMouse Micro Laser
+
+usb:v047Dp1070*
+ ID_PRODUCT_FROM_DATABASE=ValueOpt Travel
+
+usb:v047Dp1071*
+ ID_PRODUCT_FROM_DATABASE=ValueOpt RF TX
+
+usb:v047Dp1072*
+ ID_PRODUCT_FROM_DATABASE=PocketMouse Colour
+
+usb:v047Dp1073*
+ ID_PRODUCT_FROM_DATABASE=PilotMouse Laser - 6 Button
+
+usb:v047Dp1074*
+ ID_PRODUCT_FROM_DATABASE=PilotMouse Laser Wireless Mini
+
+usb:v047Dp1075*
+ ID_PRODUCT_FROM_DATABASE=SlimBlade Presenter Media Mouse
+
+usb:v047Dp1076*
+ ID_PRODUCT_FROM_DATABASE=SlimBlade Media Mouse
+
+usb:v047Dp1077*
+ ID_PRODUCT_FROM_DATABASE=SlimBlade Presenter Mouse
+
+usb:v047Dp1152*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Dongle
+
+usb:v047Dp2002*
+ ID_PRODUCT_FROM_DATABASE=Optical Elite Wireless
+
+usb:v047Dp2010*
+ ID_PRODUCT_FROM_DATABASE=Wireless Presentation Remote
+
+usb:v047Dp2012*
+ ID_PRODUCT_FROM_DATABASE=Wireless Presenter with Laser Pointer
+
+usb:v047Dp2021*
+ ID_PRODUCT_FROM_DATABASE=PilotBoard Wireless
+
+usb:v047Dp2030*
+ ID_PRODUCT_FROM_DATABASE=PilotBoard Wireless
+
+usb:v047Dp2034*
+ ID_PRODUCT_FROM_DATABASE=SlimBlade Media Notebook Set
+
+usb:v047Dp2041*
+ ID_PRODUCT_FROM_DATABASE=SlimBlade Trackball
+
+usb:v047Dp2048*
+ ID_PRODUCT_FROM_DATABASE=Orbit Trackball with Scroll Ring
+
+usb:v047Dp4003*
+ ID_PRODUCT_FROM_DATABASE=Gravis Xterminator Digital Gamepad
+
+usb:v047Dp4005*
+ ID_PRODUCT_FROM_DATABASE=Gravis Eliminator GamePad Pro
+
+usb:v047Dp4006*
+ ID_PRODUCT_FROM_DATABASE=Gravis Eliminator AfterShock
+
+usb:v047Dp4007*
+ ID_PRODUCT_FROM_DATABASE=Gravis Xterminator Force
+
+usb:v047Dp4008*
+ ID_PRODUCT_FROM_DATABASE=Gravis Destroyer TiltPad
+
+usb:v047Dp5001*
+ ID_PRODUCT_FROM_DATABASE=Cabo I Camera
+
+usb:v047Dp5002*
+ ID_PRODUCT_FROM_DATABASE=VideoCam CABO II
+
+usb:v047Dp5003*
+ ID_PRODUCT_FROM_DATABASE=VideoCam
+
+usb:v047E*
+ ID_VENDOR_FROM_DATABASE=Agere Systems, Inc. (Lucent)
+
+usb:v047Ep0300*
+ ID_PRODUCT_FROM_DATABASE=ORiNOCO Card
+
+usb:v047Ep1001*
+ ID_PRODUCT_FROM_DATABASE=USS720 Parallel Port
+
+usb:v047Ep2892*
+ ID_PRODUCT_FROM_DATABASE=Systems Soft Modem
+
+usb:v047EpBAD1*
+ ID_PRODUCT_FROM_DATABASE=Lucent 56k Modem
+
+usb:v047EpF101*
+ ID_PRODUCT_FROM_DATABASE=Atlas Modem
+
+usb:v047F*
+ ID_VENDOR_FROM_DATABASE=Plantronics, Inc.
+
+usb:v047Fp0101*
+ ID_PRODUCT_FROM_DATABASE=Bulk Driver
+
+usb:v047Fp0301*
+ ID_PRODUCT_FROM_DATABASE=Bulk Driver
+
+usb:v047Fp0411*
+ ID_PRODUCT_FROM_DATABASE=Savi Office Base Station
+
+usb:v047Fp0CA1*
+ ID_PRODUCT_FROM_DATABASE=USB DSP v4 Audio Interface
+
+usb:v047Fp4254*
+ ID_PRODUCT_FROM_DATABASE=BUA-100 Bluetooth Adapter
+
+usb:v047FpAC01*
+ ID_PRODUCT_FROM_DATABASE=Savi 7xx
+
+usb:v047FpAD01*
+ ID_PRODUCT_FROM_DATABASE=GameCom 777 5.1 Headset
+
+usb:v0480*
+ ID_VENDOR_FROM_DATABASE=Toshiba America Info. Systems, Inc.
+
+usb:v0480p0001*
+ ID_PRODUCT_FROM_DATABASE=InTouch Module
+
+usb:v0480p0004*
+ ID_PRODUCT_FROM_DATABASE=InTouch Module
+
+usb:v0480p0011*
+ ID_PRODUCT_FROM_DATABASE=InTouch Module
+
+usb:v0480p0014*
+ ID_PRODUCT_FROM_DATABASE=InTouch Module
+
+usb:v0480pA007*
+ ID_PRODUCT_FROM_DATABASE=External Disk USB 3.0
+
+usb:v0481*
+ ID_VENDOR_FROM_DATABASE=Zenith Data Systems
+
+usb:v0482*
+ ID_VENDOR_FROM_DATABASE=Kyocera Corp.
+
+usb:v0482p000E*
+ ID_PRODUCT_FROM_DATABASE=FS-1020D Printer
+
+usb:v0482p0100*
+ ID_PRODUCT_FROM_DATABASE=Finecam S3x
+
+usb:v0482p0101*
+ ID_PRODUCT_FROM_DATABASE=Finecam S4
+
+usb:v0482p0103*
+ ID_PRODUCT_FROM_DATABASE=Finecam S5
+
+usb:v0482p0105*
+ ID_PRODUCT_FROM_DATABASE=Finecam L3
+
+usb:v0482p0106*
+ ID_PRODUCT_FROM_DATABASE=Finecam
+
+usb:v0482p0107*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera Device
+
+usb:v0482p0108*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera Device
+
+usb:v0482p0203*
+ ID_PRODUCT_FROM_DATABASE=AH-K3001V
+
+usb:v0482p0204*
+ ID_PRODUCT_FROM_DATABASE=iBurst Terminal
+
+usb:v0483*
+ ID_VENDOR_FROM_DATABASE=SGS Thomson Microelectronics
+
+usb:v0483p0137*
+ ID_PRODUCT_FROM_DATABASE=BeWAN ADSL USB ST (blue or green)
+
+usb:v0483p0138*
+ ID_PRODUCT_FROM_DATABASE=Unicorn II (ST70138B + MTC-20174TQ chipset)
+
+usb:v0483p1307*
+ ID_PRODUCT_FROM_DATABASE=Cytronix 6in1 Card Reader
+
+usb:v0483p163D*
+ ID_PRODUCT_FROM_DATABASE=Cool Icam Digi-MP3
+
+usb:v0483p2015*
+ ID_PRODUCT_FROM_DATABASE=TouchChip® Fingerprint Reader
+
+usb:v0483p2016*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v0483p2017*
+ ID_PRODUCT_FROM_DATABASE=Biometric Smart Card Reader
+
+usb:v0483p2018*
+ ID_PRODUCT_FROM_DATABASE=BioSimKey
+
+usb:v0483p2302*
+ ID_PRODUCT_FROM_DATABASE=Portable Flash Device (PFD)
+
+usb:v0483p3744*
+ ID_PRODUCT_FROM_DATABASE=STLINK Pseudo disk
+
+usb:v0483p3747*
+ ID_PRODUCT_FROM_DATABASE=ST Micro Connect Lite
+
+usb:v0483p3748*
+ ID_PRODUCT_FROM_DATABASE=ST-LINK/V2
+
+usb:v0483p4810*
+ ID_PRODUCT_FROM_DATABASE=ISDN adapter
+
+usb:v0483p481D*
+ ID_PRODUCT_FROM_DATABASE=BT Digital Access adapter
+
+usb:v0483p5000*
+ ID_PRODUCT_FROM_DATABASE=ST Micro/Ergenic ERG BT-002 Bluetooth Adapter
+
+usb:v0483p5001*
+ ID_PRODUCT_FROM_DATABASE=ST Micro Bluetooth Device
+
+usb:v0483p5710*
+ ID_PRODUCT_FROM_DATABASE=Joystick in FS Mode
+
+usb:v0483p5721*
+ ID_PRODUCT_FROM_DATABASE=Hantek DDS-3X25 Arbitrary Waveform Generator
+
+usb:v0483p7270*
+ ID_PRODUCT_FROM_DATABASE=ST Micro Serial Bridge
+
+usb:v0483p7554*
+ ID_PRODUCT_FROM_DATABASE=56k SoftModem
+
+usb:v0483pDF11*
+ ID_PRODUCT_FROM_DATABASE=STM Device in DFU Mode
+
+usb:v0483pFF10*
+ ID_PRODUCT_FROM_DATABASE=Swann ST56 Modem
+
+usb:v0484*
+ ID_VENDOR_FROM_DATABASE=Specialix
+
+usb:v0485*
+ ID_VENDOR_FROM_DATABASE=Nokia Monitors
+
+usb:v0486*
+ ID_VENDOR_FROM_DATABASE=ASUS Computers, Inc.
+
+usb:v0486p0185*
+ ID_PRODUCT_FROM_DATABASE=EeePC T91MT HID Touch Panel
+
+usb:v0487*
+ ID_VENDOR_FROM_DATABASE=Stewart Connector
+
+usb:v0488*
+ ID_VENDOR_FROM_DATABASE=Cirque Corp.
+
+usb:v0489*
+ ID_VENDOR_FROM_DATABASE=Foxconn / Hon Hai
+
+usb:v0489p0502*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia Card Reader Firmware Loader
+
+usb:v0489p0503*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia Card Reader
+
+usb:v0489pD00C*
+ ID_PRODUCT_FROM_DATABASE=Rollei Compactline (Storage Mode)
+
+usb:v0489pD00E*
+ ID_PRODUCT_FROM_DATABASE=Rollei Compactline (Video Mode)
+
+usb:v0489pE000*
+ ID_PRODUCT_FROM_DATABASE=T-Com TC 300
+
+usb:v0489pE003*
+ ID_PRODUCT_FROM_DATABASE=Pirelli DP-L10
+
+usb:v0489pE00D*
+ ID_PRODUCT_FROM_DATABASE=Broadcom Bluetooth 2.1 Device
+
+usb:v0489pE00F*
+ ID_PRODUCT_FROM_DATABASE=Foxconn T77H114 BCM2070 [Single-Chip Bluetooth 2.1 + EDR Adapter]
+
+usb:v0489pE016*
+ ID_PRODUCT_FROM_DATABASE=Ubee PXU1900 WiMAX Adapter [Beceem BCSM250]
+
+usb:v0489pE02C*
+ ID_PRODUCT_FROM_DATABASE=Atheros AR5BBU12 Bluetooth Device
+
+usb:v048A*
+ ID_VENDOR_FROM_DATABASE=S-MOS Systems, Inc.
+
+usb:v048C*
+ ID_VENDOR_FROM_DATABASE=Alps Electric Ireland, Ltd
+
+usb:v048D*
+ ID_VENDOR_FROM_DATABASE=Integrated Technology Express, Inc.
+
+usb:v048Dp1165*
+ ID_PRODUCT_FROM_DATABASE=IT1165 Flash Controller
+
+usb:v048Dp1336*
+ ID_PRODUCT_FROM_DATABASE=SD/MMC Cardreader
+
+usb:v048Dp1345*
+ ID_PRODUCT_FROM_DATABASE=Multi Cardreader
+
+usb:v048Dp9006*
+ ID_PRODUCT_FROM_DATABASE=IT9135 BDA Afatech DVB-T HDTV Dongle
+
+usb:v048Dp9009*
+ ID_PRODUCT_FROM_DATABASE=Zolid HD DVD Maker
+
+usb:v048Dp9135*
+ ID_PRODUCT_FROM_DATABASE=Zolid Mini DVB-T Stick
+
+usb:v048F*
+ ID_VENDOR_FROM_DATABASE=Eicon Tech.
+
+usb:v0490*
+ ID_VENDOR_FROM_DATABASE=United Microelectronics Corp.
+
+usb:v0491*
+ ID_VENDOR_FROM_DATABASE=Capetronic
+
+usb:v0491p0003*
+ ID_PRODUCT_FROM_DATABASE=Taxan Monitor Control
+
+usb:v0492*
+ ID_VENDOR_FROM_DATABASE=Samsung SemiConductor, Inc.
+
+usb:v0492p0140*
+ ID_PRODUCT_FROM_DATABASE=MP3 player
+
+usb:v0492p0141*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0493*
+ ID_VENDOR_FROM_DATABASE=MAG Technology Co., Ltd
+
+usb:v0495*
+ ID_VENDOR_FROM_DATABASE=ESS Technology, Inc.
+
+usb:v0496*
+ ID_VENDOR_FROM_DATABASE=Micron Electronics
+
+usb:v0497*
+ ID_VENDOR_FROM_DATABASE=Smile International
+
+usb:v0497pC001*
+ ID_PRODUCT_FROM_DATABASE=Camera Device
+
+usb:v0498*
+ ID_VENDOR_FROM_DATABASE=Capetronic (Kaohsiung) Corp.
+
+usb:v0499*
+ ID_VENDOR_FROM_DATABASE=Yamaha Corp.
+
+usb:v0499p1000*
+ ID_PRODUCT_FROM_DATABASE=UX256 MIDI I/F
+
+usb:v0499p1001*
+ ID_PRODUCT_FROM_DATABASE=MU1000
+
+usb:v0499p1002*
+ ID_PRODUCT_FROM_DATABASE=MU2000
+
+usb:v0499p1003*
+ ID_PRODUCT_FROM_DATABASE=MU500
+
+usb:v0499p1004*
+ ID_PRODUCT_FROM_DATABASE=UW500
+
+usb:v0499p1005*
+ ID_PRODUCT_FROM_DATABASE=MOTIF6
+
+usb:v0499p1006*
+ ID_PRODUCT_FROM_DATABASE=MOTIF7
+
+usb:v0499p1007*
+ ID_PRODUCT_FROM_DATABASE=MOTIF8
+
+usb:v0499p1008*
+ ID_PRODUCT_FROM_DATABASE=UX96 MIDI I/F
+
+usb:v0499p1009*
+ ID_PRODUCT_FROM_DATABASE=UX16 MIDI I/F
+
+usb:v0499p100A*
+ ID_PRODUCT_FROM_DATABASE=EOS BX
+
+usb:v0499p100C*
+ ID_PRODUCT_FROM_DATABASE=UC-MX
+
+usb:v0499p100D*
+ ID_PRODUCT_FROM_DATABASE=UC-KX
+
+usb:v0499p100E*
+ ID_PRODUCT_FROM_DATABASE=S08
+
+usb:v0499p100F*
+ ID_PRODUCT_FROM_DATABASE=CLP-150
+
+usb:v0499p1010*
+ ID_PRODUCT_FROM_DATABASE=CLP-170
+
+usb:v0499p1011*
+ ID_PRODUCT_FROM_DATABASE=P-250
+
+usb:v0499p1012*
+ ID_PRODUCT_FROM_DATABASE=TYROS
+
+usb:v0499p1013*
+ ID_PRODUCT_FROM_DATABASE=PF-500
+
+usb:v0499p1014*
+ ID_PRODUCT_FROM_DATABASE=S90
+
+usb:v0499p1015*
+ ID_PRODUCT_FROM_DATABASE=MOTIF-R
+
+usb:v0499p1016*
+ ID_PRODUCT_FROM_DATABASE=MDP-5
+
+usb:v0499p1017*
+ ID_PRODUCT_FROM_DATABASE=CVP-204
+
+usb:v0499p1018*
+ ID_PRODUCT_FROM_DATABASE=CVP-206
+
+usb:v0499p1019*
+ ID_PRODUCT_FROM_DATABASE=CVP-208
+
+usb:v0499p101A*
+ ID_PRODUCT_FROM_DATABASE=CVP-210
+
+usb:v0499p101B*
+ ID_PRODUCT_FROM_DATABASE=PSR-1100
+
+usb:v0499p101C*
+ ID_PRODUCT_FROM_DATABASE=PSR-2100
+
+usb:v0499p101D*
+ ID_PRODUCT_FROM_DATABASE=CLP-175
+
+usb:v0499p101E*
+ ID_PRODUCT_FROM_DATABASE=PSR-K1
+
+usb:v0499p101F*
+ ID_PRODUCT_FROM_DATABASE=EZ-J24
+
+usb:v0499p1020*
+ ID_PRODUCT_FROM_DATABASE=EZ-250i
+
+usb:v0499p1021*
+ ID_PRODUCT_FROM_DATABASE=MOTIF ES 6
+
+usb:v0499p1022*
+ ID_PRODUCT_FROM_DATABASE=MOTIF ES 7
+
+usb:v0499p1023*
+ ID_PRODUCT_FROM_DATABASE=MOTIF ES 8
+
+usb:v0499p1024*
+ ID_PRODUCT_FROM_DATABASE=CVP-301
+
+usb:v0499p1025*
+ ID_PRODUCT_FROM_DATABASE=CVP-303
+
+usb:v0499p1026*
+ ID_PRODUCT_FROM_DATABASE=CVP-305
+
+usb:v0499p1027*
+ ID_PRODUCT_FROM_DATABASE=CVP-307
+
+usb:v0499p1028*
+ ID_PRODUCT_FROM_DATABASE=CVP-309
+
+usb:v0499p1029*
+ ID_PRODUCT_FROM_DATABASE=CVP-309GP
+
+usb:v0499p102A*
+ ID_PRODUCT_FROM_DATABASE=PSR-1500
+
+usb:v0499p102B*
+ ID_PRODUCT_FROM_DATABASE=PSR-3000
+
+usb:v0499p102E*
+ ID_PRODUCT_FROM_DATABASE=ELS-01/01C
+
+usb:v0499p1030*
+ ID_PRODUCT_FROM_DATABASE=PSR-295/293
+
+usb:v0499p1031*
+ ID_PRODUCT_FROM_DATABASE=DGX-205/203
+
+usb:v0499p1032*
+ ID_PRODUCT_FROM_DATABASE=DGX-305
+
+usb:v0499p1033*
+ ID_PRODUCT_FROM_DATABASE=DGX-505
+
+usb:v0499p1037*
+ ID_PRODUCT_FROM_DATABASE=PSR-E403
+
+usb:v0499p103C*
+ ID_PRODUCT_FROM_DATABASE=MOTIF-RACK ES
+
+usb:v0499p1054*
+ ID_PRODUCT_FROM_DATABASE=S90XS Keyboard/Music Synthesizer
+
+usb:v0499p2000*
+ ID_PRODUCT_FROM_DATABASE=DGP-7
+
+usb:v0499p2001*
+ ID_PRODUCT_FROM_DATABASE=DGP-5
+
+usb:v0499p3001*
+ ID_PRODUCT_FROM_DATABASE=YST-MS55D USB Speaker
+
+usb:v0499p3003*
+ ID_PRODUCT_FROM_DATABASE=YST-M45D USB Speaker
+
+usb:v0499p4000*
+ ID_PRODUCT_FROM_DATABASE=NetVolante RTA54i Broadband&ISDN Router
+
+usb:v0499p4001*
+ ID_PRODUCT_FROM_DATABASE=NetVolante RTW65b Broadband Wireless Router
+
+usb:v0499p4002*
+ ID_PRODUCT_FROM_DATABASE=NetVolante RTW65i Broadband&ISDN Wireless Router
+
+usb:v0499p4004*
+ ID_PRODUCT_FROM_DATABASE=NetVolante RTA55i Broadband VoIP Router
+
+usb:v0499p5000*
+ ID_PRODUCT_FROM_DATABASE=CS1D
+
+usb:v0499p5001*
+ ID_PRODUCT_FROM_DATABASE=DSP1D
+
+usb:v0499p5002*
+ ID_PRODUCT_FROM_DATABASE=DME32
+
+usb:v0499p5003*
+ ID_PRODUCT_FROM_DATABASE=DM2000
+
+usb:v0499p5004*
+ ID_PRODUCT_FROM_DATABASE=02R96
+
+usb:v0499p5005*
+ ID_PRODUCT_FROM_DATABASE=ACU16-C
+
+usb:v0499p5006*
+ ID_PRODUCT_FROM_DATABASE=NHB32-C
+
+usb:v0499p5007*
+ ID_PRODUCT_FROM_DATABASE=DM1000
+
+usb:v0499p5008*
+ ID_PRODUCT_FROM_DATABASE=01V96
+
+usb:v0499p5009*
+ ID_PRODUCT_FROM_DATABASE=SPX2000
+
+usb:v0499p500A*
+ ID_PRODUCT_FROM_DATABASE=PM5D
+
+usb:v0499p500B*
+ ID_PRODUCT_FROM_DATABASE=DME64N
+
+usb:v0499p500C*
+ ID_PRODUCT_FROM_DATABASE=DME24N
+
+usb:v0499p6001*
+ ID_PRODUCT_FROM_DATABASE=CRW2200UX Lightspeed 2 External CD-RW Drive
+
+usb:v0499p7000*
+ ID_PRODUCT_FROM_DATABASE=DTX
+
+usb:v0499p7010*
+ ID_PRODUCT_FROM_DATABASE=UB99
+
+usb:v049A*
+ ID_VENDOR_FROM_DATABASE=Gandalf Technologies, Ltd
+
+usb:v049B*
+ ID_VENDOR_FROM_DATABASE=Curtis Computer Products
+
+usb:v049C*
+ ID_VENDOR_FROM_DATABASE=Acer Advanced Labs, Inc.
+
+usb:v049Cp0002*
+ ID_PRODUCT_FROM_DATABASE=Keyboard (???)
+
+usb:v049D*
+ ID_VENDOR_FROM_DATABASE=VLSI Technology
+
+usb:v049F*
+ ID_VENDOR_FROM_DATABASE=Compaq Computer Corp.
+
+usb:v049Fp0002*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v049Fp0003*
+ ID_PRODUCT_FROM_DATABASE=iPAQ PocketPC
+
+usb:v049Fp000E*
+ ID_PRODUCT_FROM_DATABASE=Internet Keyboard
+
+usb:v049Fp0012*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v049Fp0018*
+ ID_PRODUCT_FROM_DATABASE=PA-1/PA-2 MP3 Player
+
+usb:v049Fp0019*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v049Fp001A*
+ ID_PRODUCT_FROM_DATABASE=S4 100 Scanner
+
+usb:v049Fp001E*
+ ID_PRODUCT_FROM_DATABASE=IJ650 Inkjet Printer
+
+usb:v049Fp001F*
+ ID_PRODUCT_FROM_DATABASE=WL215 Adapter
+
+usb:v049Fp0021*
+ ID_PRODUCT_FROM_DATABASE=S200 Scanner
+
+usb:v049Fp0027*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Multiport Module by Compaq
+
+usb:v049Fp002A*
+ ID_PRODUCT_FROM_DATABASE=1400P Inkjet Printer
+
+usb:v049Fp002B*
+ ID_PRODUCT_FROM_DATABASE=A3000
+
+usb:v049Fp002C*
+ ID_PRODUCT_FROM_DATABASE=Lexmark X125
+
+usb:v049Fp0032*
+ ID_PRODUCT_FROM_DATABASE=802.11b Adapter [ipaq h5400]
+
+usb:v049Fp0033*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN MultiPort W100 [Intersil PRISM 2.5]
+
+usb:v049Fp0036*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Multiport Module
+
+usb:v049Fp0051*
+ ID_PRODUCT_FROM_DATABASE=KU-0133 Easy Access Interner Keyboard
+
+usb:v049Fp0076*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN MultiPort W200
+
+usb:v049Fp0080*
+ ID_PRODUCT_FROM_DATABASE=GPRS Multiport
+
+usb:v049Fp0086*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v049Fp504A*
+ ID_PRODUCT_FROM_DATABASE=Personal Jukebox PJB100
+
+usb:v049Fp505A*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB "CDC Subset" Device, or Itsy (experimental)
+
+usb:v049Fp8511*
+ ID_PRODUCT_FROM_DATABASE=iPAQ Networking 10/100 Ethernet [pegasus2]
+
+usb:v04A0*
+ ID_VENDOR_FROM_DATABASE=Digital Equipment Corp.
+
+usb:v04A1*
+ ID_VENDOR_FROM_DATABASE=SystemSoft Corp.
+
+usb:v04A1pFFF0*
+ ID_PRODUCT_FROM_DATABASE=Telex Composite Device
+
+usb:v04A2*
+ ID_VENDOR_FROM_DATABASE=FirePower Systems
+
+usb:v04A3*
+ ID_VENDOR_FROM_DATABASE=Trident Microsystems, Inc.
+
+usb:v04A4*
+ ID_VENDOR_FROM_DATABASE=Hitachi, Ltd
+
+usb:v04A4p0004*
+ ID_PRODUCT_FROM_DATABASE=DVD-CAM DZ-MV100A Camcorder
+
+usb:v04A4p001E*
+ ID_PRODUCT_FROM_DATABASE=DVDCAM USB HS Interface
+
+usb:v04A5*
+ ID_VENDOR_FROM_DATABASE=Acer Peripherals Inc. (now BenQ Corp.)
+
+usb:v04A5p0001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v04A5p0002*
+ ID_PRODUCT_FROM_DATABASE=API Ergo K/B
+
+usb:v04A5p0003*
+ ID_PRODUCT_FROM_DATABASE=API Generic K/B Mouse
+
+usb:v04A5p12A6*
+ ID_PRODUCT_FROM_DATABASE=AcerScan C310U
+
+usb:v04A5p1A20*
+ ID_PRODUCT_FROM_DATABASE=Prisa 310U
+
+usb:v04A5p1A2A*
+ ID_PRODUCT_FROM_DATABASE=Prisa 620U
+
+usb:v04A5p2022*
+ ID_PRODUCT_FROM_DATABASE=Prisa 320U/340U
+
+usb:v04A5p2040*
+ ID_PRODUCT_FROM_DATABASE=Prisa 620UT
+
+usb:v04A5p205E*
+ ID_PRODUCT_FROM_DATABASE=ScanPrisa 640BU
+
+usb:v04A5p2060*
+ ID_PRODUCT_FROM_DATABASE=Prisa 620U+/640U
+
+usb:v04A5p207E*
+ ID_PRODUCT_FROM_DATABASE=Prisa 640BU
+
+usb:v04A5p209E*
+ ID_PRODUCT_FROM_DATABASE=ScanPrisa 640BT
+
+usb:v04A5p20AE*
+ ID_PRODUCT_FROM_DATABASE=S2W 3000U
+
+usb:v04A5p20B0*
+ ID_PRODUCT_FROM_DATABASE=S2W 3300U/4300U
+
+usb:v04A5p20BE*
+ ID_PRODUCT_FROM_DATABASE=Prisa 640BT
+
+usb:v04A5p20C0*
+ ID_PRODUCT_FROM_DATABASE=Prisa 1240UT
+
+usb:v04A5p20DE*
+ ID_PRODUCT_FROM_DATABASE=S2W 4300U+
+
+usb:v04A5p20F8*
+ ID_PRODUCT_FROM_DATABASE=Benq 5000
+
+usb:v04A5p20FC*
+ ID_PRODUCT_FROM_DATABASE=Benq 5000
+
+usb:v04A5p20FE*
+ ID_PRODUCT_FROM_DATABASE=SW2 5300U
+
+usb:v04A5p2137*
+ ID_PRODUCT_FROM_DATABASE=Benq 5150/5250
+
+usb:v04A5p2202*
+ ID_PRODUCT_FROM_DATABASE=Benq 7400UT
+
+usb:v04A5p2311*
+ ID_PRODUCT_FROM_DATABASE=Benq 5560
+
+usb:v04A5p3003*
+ ID_PRODUCT_FROM_DATABASE=Benq Webcam
+
+usb:v04A5p3008*
+ ID_PRODUCT_FROM_DATABASE=Benq 1500
+
+usb:v04A5p300A*
+ ID_PRODUCT_FROM_DATABASE=Benq 3410
+
+usb:v04A5p300C*
+ ID_PRODUCT_FROM_DATABASE=Benq 1016
+
+usb:v04A5p3019*
+ ID_PRODUCT_FROM_DATABASE=Benq DC C40
+
+usb:v04A5p4000*
+ ID_PRODUCT_FROM_DATABASE=P30 Composite Device
+
+usb:v04A5p4013*
+ ID_PRODUCT_FROM_DATABASE=BenQ-Siemens EF82/SL91
+
+usb:v04A5p4044*
+ ID_PRODUCT_FROM_DATABASE=BenQ-Siemens SF71
+
+usb:v04A5p4045*
+ ID_PRODUCT_FROM_DATABASE=BenQ-Siemens E81
+
+usb:v04A5p4048*
+ ID_PRODUCT_FROM_DATABASE=BenQ M7
+
+usb:v04A5p6001*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6002*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6003*
+ ID_PRODUCT_FROM_DATABASE=ATA/ATAPI Adapter
+
+usb:v04A5p6004*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6005*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6006*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6007*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6008*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6009*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p600A*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p600B*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p600C*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p600D*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p600E*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p600F*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6010*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6011*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6012*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6013*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6014*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6015*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v04A5p6125*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v04A5p6180*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v04A5p6200*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v04A5p7500*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device
+
+usb:v04A5p9000*
+ ID_PRODUCT_FROM_DATABASE=AWL300 Wireless Adapter
+
+usb:v04A5p9001*
+ ID_PRODUCT_FROM_DATABASE=AWL400 Wireless Adapter
+
+usb:v04A5p9213*
+ ID_PRODUCT_FROM_DATABASE=Kbd Hub
+
+usb:v04A6*
+ ID_VENDOR_FROM_DATABASE=Nokia Display Products
+
+usb:v04A6p00B9*
+ ID_PRODUCT_FROM_DATABASE=Audio
+
+usb:v04A6p0180*
+ ID_PRODUCT_FROM_DATABASE=Hub Type P
+
+usb:v04A6p0181*
+ ID_PRODUCT_FROM_DATABASE=HID Monitor Controls
+
+usb:v04A7*
+ ID_VENDOR_FROM_DATABASE=Visioneer
+
+usb:v04A7p0100*
+ ID_PRODUCT_FROM_DATABASE=StrobePro
+
+usb:v04A7p0101*
+ ID_PRODUCT_FROM_DATABASE=Strobe Pro Scanner (1.01)
+
+usb:v04A7p0102*
+ ID_PRODUCT_FROM_DATABASE=StrobePro Scanner
+
+usb:v04A7p0211*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 7600 Scanner
+
+usb:v04A7p0221*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 5300 Scanner
+
+usb:v04A7p0223*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 8200
+
+usb:v04A7p0224*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 4800 USB/Microtek Scanport 3000
+
+usb:v04A7p0225*
+ ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG)
+
+usb:v04A7p0226*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 5300 USB
+
+usb:v04A7p0229*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 7100
+
+usb:v04A7p022A*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 6600
+
+usb:v04A7p022C*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 9000/9020
+
+usb:v04A7p0231*
+ ID_PRODUCT_FROM_DATABASE=6100 Scanner
+
+usb:v04A7p0311*
+ ID_PRODUCT_FROM_DATABASE=6200 EPP/USB Scanner
+
+usb:v04A7p0321*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 8100 EPP/USB Scanner
+
+usb:v04A7p0331*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 8600 EPP/USB Scanner
+
+usb:v04A7p0341*
+ ID_PRODUCT_FROM_DATABASE=6400
+
+usb:v04A7p0361*
+ ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG)
+
+usb:v04A7p0362*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 9320
+
+usb:v04A7p0371*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 8700/8920
+
+usb:v04A7p0380*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 7700
+
+usb:v04A7p0382*
+ ID_PRODUCT_FROM_DATABASE=Photo Port 7700
+
+usb:v04A7p0390*
+ ID_PRODUCT_FROM_DATABASE=9650
+
+usb:v04A7p03A0*
+ ID_PRODUCT_FROM_DATABASE=Xerox 4800 One Touch
+
+usb:v04A7p0410*
+ ID_PRODUCT_FROM_DATABASE=OneTouch Pro 8800/8820
+
+usb:v04A7p0421*
+ ID_PRODUCT_FROM_DATABASE=9450 USB
+
+usb:v04A7p0423*
+ ID_PRODUCT_FROM_DATABASE=9750 Scanner
+
+usb:v04A7p0424*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 450
+
+usb:v04A7p0425*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 100
+
+usb:v04A7p0426*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 200
+
+usb:v04A7p0427*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 100
+
+usb:v04A7p0444*
+ ID_PRODUCT_FROM_DATABASE=OneTouch 7300
+
+usb:v04A7p0445*
+ ID_PRODUCT_FROM_DATABASE=CardReader 100
+
+usb:v04A7p0446*
+ ID_PRODUCT_FROM_DATABASE=Xerox DocuMate 510
+
+usb:v04A7p0447*
+ ID_PRODUCT_FROM_DATABASE=XEROX DocuMate 520
+
+usb:v04A7p0448*
+ ID_PRODUCT_FROM_DATABASE=XEROX DocuMate 250
+
+usb:v04A7p0449*
+ ID_PRODUCT_FROM_DATABASE=Xerox DocuMate 252
+
+usb:v04A7p044A*
+ ID_PRODUCT_FROM_DATABASE=Xerox 6400
+
+usb:v04A7p044C*
+ ID_PRODUCT_FROM_DATABASE=Xerox DocuMate 262
+
+usb:v04A7p0474*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 300
+
+usb:v04A7p0475*
+ ID_PRODUCT_FROM_DATABASE=Xerox DocuMate 272
+
+usb:v04A7p0478*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 220
+
+usb:v04A7p0479*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 470
+
+usb:v04A7p047A*
+ ID_PRODUCT_FROM_DATABASE=9450
+
+usb:v04A7p047B*
+ ID_PRODUCT_FROM_DATABASE=9650
+
+usb:v04A7p047D*
+ ID_PRODUCT_FROM_DATABASE=9420
+
+usb:v04A7p0480*
+ ID_PRODUCT_FROM_DATABASE=9520
+
+usb:v04A7p048F*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 470
+
+usb:v04A7p0491*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 450
+
+usb:v04A7p0493*
+ ID_PRODUCT_FROM_DATABASE=9750
+
+usb:v04A7p0494*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 120
+
+usb:v04A7p0497*
+ ID_PRODUCT_FROM_DATABASE=Patriot 430
+
+usb:v04A7p0498*
+ ID_PRODUCT_FROM_DATABASE=Patriot 680
+
+usb:v04A7p0499*
+ ID_PRODUCT_FROM_DATABASE=Patriot 780
+
+usb:v04A7p049B*
+ ID_PRODUCT_FROM_DATABASE=Strobe XP 100
+
+usb:v04A7p04A0*
+ ID_PRODUCT_FROM_DATABASE=7400
+
+usb:v04A7p04AC*
+ ID_PRODUCT_FROM_DATABASE=Xerox Travel Scanner 100
+
+usb:v04A8*
+ ID_VENDOR_FROM_DATABASE=Multivideo Labs, Inc.
+
+usb:v04A8p0101*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v04A8p0303*
+ ID_PRODUCT_FROM_DATABASE=Peripheral Switch
+
+usb:v04A8p0404*
+ ID_PRODUCT_FROM_DATABASE=Peripheral Switch
+
+usb:v04A9*
+ ID_VENDOR_FROM_DATABASE=Canon, Inc.
+
+usb:v04A9p1005*
+ ID_PRODUCT_FROM_DATABASE=BJ Printer Hub
+
+usb:v04A9p1035*
+ ID_PRODUCT_FROM_DATABASE=PD Printer Storage
+
+usb:v04A9p1050*
+ ID_PRODUCT_FROM_DATABASE=BJC-8200
+
+usb:v04A9p1051*
+ ID_PRODUCT_FROM_DATABASE=BJC-3000 Color Printer
+
+usb:v04A9p1052*
+ ID_PRODUCT_FROM_DATABASE=BJC-6100
+
+usb:v04A9p1053*
+ ID_PRODUCT_FROM_DATABASE=BJC-6200
+
+usb:v04A9p1054*
+ ID_PRODUCT_FROM_DATABASE=BJC-6500
+
+usb:v04A9p1055*
+ ID_PRODUCT_FROM_DATABASE=BJC-85
+
+usb:v04A9p1056*
+ ID_PRODUCT_FROM_DATABASE=BJC-2110 Color Printer
+
+usb:v04A9p1057*
+ ID_PRODUCT_FROM_DATABASE=LR1
+
+usb:v04A9p105A*
+ ID_PRODUCT_FROM_DATABASE=BJC-55
+
+usb:v04A9p105B*
+ ID_PRODUCT_FROM_DATABASE=S600 Printer
+
+usb:v04A9p105C*
+ ID_PRODUCT_FROM_DATABASE=S400
+
+usb:v04A9p105D*
+ ID_PRODUCT_FROM_DATABASE=S450 Printer
+
+usb:v04A9p105E*
+ ID_PRODUCT_FROM_DATABASE=S800
+
+usb:v04A9p1062*
+ ID_PRODUCT_FROM_DATABASE=S500 Printer
+
+usb:v04A9p1063*
+ ID_PRODUCT_FROM_DATABASE=S4500
+
+usb:v04A9p1064*
+ ID_PRODUCT_FROM_DATABASE=S300 Printer
+
+usb:v04A9p1065*
+ ID_PRODUCT_FROM_DATABASE=S100
+
+usb:v04A9p1066*
+ ID_PRODUCT_FROM_DATABASE=S630
+
+usb:v04A9p1067*
+ ID_PRODUCT_FROM_DATABASE=S900
+
+usb:v04A9p1068*
+ ID_PRODUCT_FROM_DATABASE=S9000
+
+usb:v04A9p1069*
+ ID_PRODUCT_FROM_DATABASE=S820
+
+usb:v04A9p106A*
+ ID_PRODUCT_FROM_DATABASE=S200 Printer
+
+usb:v04A9p106B*
+ ID_PRODUCT_FROM_DATABASE=S520 Printer
+
+usb:v04A9p106D*
+ ID_PRODUCT_FROM_DATABASE=S750 Printer
+
+usb:v04A9p106E*
+ ID_PRODUCT_FROM_DATABASE=S820D
+
+usb:v04A9p1070*
+ ID_PRODUCT_FROM_DATABASE=S530D
+
+usb:v04A9p1072*
+ ID_PRODUCT_FROM_DATABASE=I850 Printer
+
+usb:v04A9p1073*
+ ID_PRODUCT_FROM_DATABASE=I550 Printer
+
+usb:v04A9p1074*
+ ID_PRODUCT_FROM_DATABASE=S330 Printer
+
+usb:v04A9p1076*
+ ID_PRODUCT_FROM_DATABASE=i70
+
+usb:v04A9p1077*
+ ID_PRODUCT_FROM_DATABASE=i950
+
+usb:v04A9p107A*
+ ID_PRODUCT_FROM_DATABASE=S830D
+
+usb:v04A9p107B*
+ ID_PRODUCT_FROM_DATABASE=i320
+
+usb:v04A9p107C*
+ ID_PRODUCT_FROM_DATABASE=i470D
+
+usb:v04A9p107D*
+ ID_PRODUCT_FROM_DATABASE=i9100
+
+usb:v04A9p107E*
+ ID_PRODUCT_FROM_DATABASE=i450
+
+usb:v04A9p107F*
+ ID_PRODUCT_FROM_DATABASE=i860
+
+usb:v04A9p1082*
+ ID_PRODUCT_FROM_DATABASE=i350
+
+usb:v04A9p1084*
+ ID_PRODUCT_FROM_DATABASE=i250
+
+usb:v04A9p1085*
+ ID_PRODUCT_FROM_DATABASE=i255
+
+usb:v04A9p1086*
+ ID_PRODUCT_FROM_DATABASE=i560
+
+usb:v04A9p1088*
+ ID_PRODUCT_FROM_DATABASE=i965
+
+usb:v04A9p108A*
+ ID_PRODUCT_FROM_DATABASE=i455
+
+usb:v04A9p108B*
+ ID_PRODUCT_FROM_DATABASE=i900D
+
+usb:v04A9p108C*
+ ID_PRODUCT_FROM_DATABASE=i475D
+
+usb:v04A9p108D*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP2000
+
+usb:v04A9p108F*
+ ID_PRODUCT_FROM_DATABASE=i80
+
+usb:v04A9p1090*
+ ID_PRODUCT_FROM_DATABASE=i9900 Photo Printer
+
+usb:v04A9p1091*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP1500
+
+usb:v04A9p1093*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP4000
+
+usb:v04A9p1094*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP3000x Printer
+
+usb:v04A9p1095*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP6000D
+
+usb:v04A9p1097*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP5000
+
+usb:v04A9p1098*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP1000
+
+usb:v04A9p1099*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP8500
+
+usb:v04A9p109C*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP4000R
+
+usb:v04A9p109D*
+ ID_PRODUCT_FROM_DATABASE=iP90
+
+usb:v04A9p10A0*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP1600 Printer
+
+usb:v04A9p10A2*
+ ID_PRODUCT_FROM_DATABASE=iP4200
+
+usb:v04A9p10A4*
+ ID_PRODUCT_FROM_DATABASE=iP5200R
+
+usb:v04A9p10A5*
+ ID_PRODUCT_FROM_DATABASE=iP5200
+
+usb:v04A9p10A7*
+ ID_PRODUCT_FROM_DATABASE=iP6210D
+
+usb:v04A9p10A8*
+ ID_PRODUCT_FROM_DATABASE=iP6220D
+
+usb:v04A9p10A9*
+ ID_PRODUCT_FROM_DATABASE=iP6600D
+
+usb:v04A9p10B6*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP4300 Printer
+
+usb:v04A9p10C2*
+ ID_PRODUCT_FROM_DATABASE=PIXMA iP1800 Printer
+
+usb:v04A9p10C4*
+ ID_PRODUCT_FROM_DATABASE=Pixma iP4500 Printer
+
+usb:v04A9p1404*
+ ID_PRODUCT_FROM_DATABASE=W6400PG
+
+usb:v04A9p1405*
+ ID_PRODUCT_FROM_DATABASE=W8400PG
+
+usb:v04A9p150F*
+ ID_PRODUCT_FROM_DATABASE=BIJ2350 PCL
+
+usb:v04A9p1510*
+ ID_PRODUCT_FROM_DATABASE=BIJ1350 PCL
+
+usb:v04A9p1512*
+ ID_PRODUCT_FROM_DATABASE=BIJ1350D PCL
+
+usb:v04A9p1601*
+ ID_PRODUCT_FROM_DATABASE=DR-2080C Scanner
+
+usb:v04A9p1607*
+ ID_PRODUCT_FROM_DATABASE=DR-6080 Scanner
+
+usb:v04A9p1700*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP110 Scanner
+
+usb:v04A9p1701*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP130 Scanner
+
+usb:v04A9p1702*
+ ID_PRODUCT_FROM_DATABASE=MP410 Composite
+
+usb:v04A9p1703*
+ ID_PRODUCT_FROM_DATABASE=MP430 Composite
+
+usb:v04A9p1704*
+ ID_PRODUCT_FROM_DATABASE=MP330 Composite
+
+usb:v04A9p1706*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP750 Scanner
+
+usb:v04A9p1707*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP780 Scanner
+
+usb:v04A9p1708*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP760 Scanner
+
+usb:v04A9p1709*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP150 Scanner
+
+usb:v04A9p170A*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP170 Scanner
+
+usb:v04A9p170B*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP450 Scanner
+
+usb:v04A9p170C*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP500 Scanner
+
+usb:v04A9p170D*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP800 Scanner
+
+usb:v04A9p170E*
+ ID_PRODUCT_FROM_DATABASE=MP800R
+
+usb:v04A9p1710*
+ ID_PRODUCT_FROM_DATABASE=MP950
+
+usb:v04A9p1712*
+ ID_PRODUCT_FROM_DATABASE=MP530
+
+usb:v04A9p1713*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP830 Scanner
+
+usb:v04A9p1714*
+ ID_PRODUCT_FROM_DATABASE=MP160
+
+usb:v04A9p1715*
+ ID_PRODUCT_FROM_DATABASE=MP180 Storage
+
+usb:v04A9p1716*
+ ID_PRODUCT_FROM_DATABASE=MP460 Composite
+
+usb:v04A9p1717*
+ ID_PRODUCT_FROM_DATABASE=MP510
+
+usb:v04A9p1718*
+ ID_PRODUCT_FROM_DATABASE=MP600 Storage
+
+usb:v04A9p171A*
+ ID_PRODUCT_FROM_DATABASE=MP810 Storage
+
+usb:v04A9p171B*
+ ID_PRODUCT_FROM_DATABASE=MP960
+
+usb:v04A9p1721*
+ ID_PRODUCT_FROM_DATABASE=MP210 ser
+
+usb:v04A9p1723*
+ ID_PRODUCT_FROM_DATABASE=MP470 ser
+
+usb:v04A9p1725*
+ ID_PRODUCT_FROM_DATABASE=MP610 ser
+
+usb:v04A9p1726*
+ ID_PRODUCT_FROM_DATABASE=MP970 ser
+
+usb:v04A9p1727*
+ ID_PRODUCT_FROM_DATABASE=MX300 ser
+
+usb:v04A9p1728*
+ ID_PRODUCT_FROM_DATABASE=MX310 ser
+
+usb:v04A9p1729*
+ ID_PRODUCT_FROM_DATABASE=MX700 ser
+
+usb:v04A9p172B*
+ ID_PRODUCT_FROM_DATABASE=MP140 ser
+
+usb:v04A9p173E*
+ ID_PRODUCT_FROM_DATABASE=MP560
+
+usb:v04A9p173F*
+ ID_PRODUCT_FROM_DATABASE=Pixma MP640 Multifunction device
+
+usb:v04A9p1748*
+ ID_PRODUCT_FROM_DATABASE=Pixma MG5150
+
+usb:v04A9p174D*
+ ID_PRODUCT_FROM_DATABASE=MX360 ser
+
+usb:v04A9p1900*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 90
+
+usb:v04A9p1901*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 8800F
+
+usb:v04A9p1904*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 100
+
+usb:v04A9p1905*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 200
+
+usb:v04A9p1906*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 5600F
+
+usb:v04A9p1907*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 700F
+
+usb:v04A9p1909*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 110
+
+usb:v04A9p190A*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 210
+
+usb:v04A9p2200*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 25
+
+usb:v04A9p2201*
+ ID_PRODUCT_FROM_DATABASE=CanoScan FB320U
+
+usb:v04A9p2202*
+ ID_PRODUCT_FROM_DATABASE=CanoScan FB620U
+
+usb:v04A9p2204*
+ ID_PRODUCT_FROM_DATABASE=CanoScan FB630U
+
+usb:v04A9p2205*
+ ID_PRODUCT_FROM_DATABASE=CanoScan FB1210U
+
+usb:v04A9p2206*
+ ID_PRODUCT_FROM_DATABASE=CanoScan N650U/N656U
+
+usb:v04A9p2207*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 1220U
+
+usb:v04A9p2208*
+ ID_PRODUCT_FROM_DATABASE=CanoScan D660U
+
+usb:v04A9p220A*
+ ID_PRODUCT_FROM_DATABASE=CanoScan D2400UF
+
+usb:v04A9p220B*
+ ID_PRODUCT_FROM_DATABASE=CanoScan D646U
+
+usb:v04A9p220C*
+ ID_PRODUCT_FROM_DATABASE=CanoScan D1250U2
+
+usb:v04A9p220D*
+ ID_PRODUCT_FROM_DATABASE=CanoScan N670U/N676U/LiDE 20
+
+usb:v04A9p220E*
+ ID_PRODUCT_FROM_DATABASE=CanoScan N1240U/LiDE 30
+
+usb:v04A9p220F*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 8000F
+
+usb:v04A9p2210*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 9900F
+
+usb:v04A9p2212*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 5000F
+
+usb:v04A9p2213*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 50/LiDE 35/LiDE 40
+
+usb:v04A9p2214*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 80
+
+usb:v04A9p2215*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 3000/3000F/3000ex
+
+usb:v04A9p2216*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 3200F
+
+usb:v04A9p2217*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 5200F
+
+usb:v04A9p2219*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 9950F
+
+usb:v04A9p221B*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 4200F
+
+usb:v04A9p221C*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 60
+
+usb:v04A9p221E*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 8400F
+
+usb:v04A9p221F*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 500F
+
+usb:v04A9p2220*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LIDE 25
+
+usb:v04A9p2224*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 600F
+
+usb:v04A9p2225*
+ ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 70
+
+usb:v04A9p2228*
+ ID_PRODUCT_FROM_DATABASE=CanoScan 4400F
+
+usb:v04A9p2602*
+ ID_PRODUCT_FROM_DATABASE=MultiPASS C555
+
+usb:v04A9p2603*
+ ID_PRODUCT_FROM_DATABASE=MultiPASS C755
+
+usb:v04A9p260A*
+ ID_PRODUCT_FROM_DATABASE=CAPT Printer
+
+usb:v04A9p260E*
+ ID_PRODUCT_FROM_DATABASE=LBP-2000
+
+usb:v04A9p2610*
+ ID_PRODUCT_FROM_DATABASE=MPC600F
+
+usb:v04A9p2611*
+ ID_PRODUCT_FROM_DATABASE=SmartBase MPC400
+
+usb:v04A9p2612*
+ ID_PRODUCT_FROM_DATABASE=MultiPASS C855
+
+usb:v04A9p2617*
+ ID_PRODUCT_FROM_DATABASE=CAPT Printer
+
+usb:v04A9p261A*
+ ID_PRODUCT_FROM_DATABASE=iR1600
+
+usb:v04A9p261B*
+ ID_PRODUCT_FROM_DATABASE=iR1610
+
+usb:v04A9p261C*
+ ID_PRODUCT_FROM_DATABASE=iC2300
+
+usb:v04A9p261F*
+ ID_PRODUCT_FROM_DATABASE=MPC200 Printer
+
+usb:v04A9p2621*
+ ID_PRODUCT_FROM_DATABASE=iR2000
+
+usb:v04A9p2622*
+ ID_PRODUCT_FROM_DATABASE=iR2010
+
+usb:v04A9p2623*
+ ID_PRODUCT_FROM_DATABASE=FAX-B180C
+
+usb:v04A9p2629*
+ ID_PRODUCT_FROM_DATABASE=FAXPHONE L75
+
+usb:v04A9p262B*
+ ID_PRODUCT_FROM_DATABASE=LaserShot LBP-1120 Printer
+
+usb:v04A9p262D*
+ ID_PRODUCT_FROM_DATABASE=iR C3200
+
+usb:v04A9p262F*
+ ID_PRODUCT_FROM_DATABASE=MultiPASS MP730
+
+usb:v04A9p2630*
+ ID_PRODUCT_FROM_DATABASE=MultiPASS MP700
+
+usb:v04A9p2631*
+ ID_PRODUCT_FROM_DATABASE=LASER CLASS 700
+
+usb:v04A9p2632*
+ ID_PRODUCT_FROM_DATABASE=FAX-L2000
+
+usb:v04A9p2635*
+ ID_PRODUCT_FROM_DATABASE=MPC190
+
+usb:v04A9p2637*
+ ID_PRODUCT_FROM_DATABASE=iR C6800
+
+usb:v04A9p2638*
+ ID_PRODUCT_FROM_DATABASE=iR C3100
+
+usb:v04A9p263C*
+ ID_PRODUCT_FROM_DATABASE=Smartbase MP360
+
+usb:v04A9p263D*
+ ID_PRODUCT_FROM_DATABASE=MP370
+
+usb:v04A9p263E*
+ ID_PRODUCT_FROM_DATABASE=MP390 FAX
+
+usb:v04A9p263F*
+ ID_PRODUCT_FROM_DATABASE=MP375
+
+usb:v04A9p2646*
+ ID_PRODUCT_FROM_DATABASE=MF5530 Scanner Device V1.9.1
+
+usb:v04A9p2647*
+ ID_PRODUCT_FROM_DATABASE=MF5550 Composite
+
+usb:v04A9p264D*
+ ID_PRODUCT_FROM_DATABASE=PIXMA MP710
+
+usb:v04A9p264E*
+ ID_PRODUCT_FROM_DATABASE=MF5630
+
+usb:v04A9p264F*
+ ID_PRODUCT_FROM_DATABASE=MF5650 (FAX)
+
+usb:v04A9p2650*
+ ID_PRODUCT_FROM_DATABASE=iR 6800C EUR
+
+usb:v04A9p2651*
+ ID_PRODUCT_FROM_DATABASE=iR 3100C EUR
+
+usb:v04A9p2655*
+ ID_PRODUCT_FROM_DATABASE=FP-L170/MF350/L380/L398
+
+usb:v04A9p2659*
+ ID_PRODUCT_FROM_DATABASE=MF8100
+
+usb:v04A9p265B*
+ ID_PRODUCT_FROM_DATABASE=CAPT Printer
+
+usb:v04A9p265C*
+ ID_PRODUCT_FROM_DATABASE=iR C3220
+
+usb:v04A9p265D*
+ ID_PRODUCT_FROM_DATABASE=MF5730
+
+usb:v04A9p265E*
+ ID_PRODUCT_FROM_DATABASE=MF5750
+
+usb:v04A9p265F*
+ ID_PRODUCT_FROM_DATABASE=MF5770
+
+usb:v04A9p2660*
+ ID_PRODUCT_FROM_DATABASE=MF3110
+
+usb:v04A9p2663*
+ ID_PRODUCT_FROM_DATABASE=iR3570/iR4570
+
+usb:v04A9p2664*
+ ID_PRODUCT_FROM_DATABASE=iR2270/iR2870
+
+usb:v04A9p2665*
+ ID_PRODUCT_FROM_DATABASE=iR C2620
+
+usb:v04A9p2666*
+ ID_PRODUCT_FROM_DATABASE=iR C5800
+
+usb:v04A9p2667*
+ ID_PRODUCT_FROM_DATABASE=iR85PLUS
+
+usb:v04A9p2669*
+ ID_PRODUCT_FROM_DATABASE=iR105PLUS
+
+usb:v04A9p266A*
+ ID_PRODUCT_FROM_DATABASE=CAPT Device
+
+usb:v04A9p266B*
+ ID_PRODUCT_FROM_DATABASE=iR8070
+
+usb:v04A9p266C*
+ ID_PRODUCT_FROM_DATABASE=iR9070
+
+usb:v04A9p266D*
+ ID_PRODUCT_FROM_DATABASE=iR 5800C EUR
+
+usb:v04A9p266E*
+ ID_PRODUCT_FROM_DATABASE=CAPT Device
+
+usb:v04A9p266F*
+ ID_PRODUCT_FROM_DATABASE=iR2230
+
+usb:v04A9p2670*
+ ID_PRODUCT_FROM_DATABASE=iR3530
+
+usb:v04A9p2671*
+ ID_PRODUCT_FROM_DATABASE=iR5570/iR6570
+
+usb:v04A9p2672*
+ ID_PRODUCT_FROM_DATABASE=iR C3170
+
+usb:v04A9p2673*
+ ID_PRODUCT_FROM_DATABASE=iR 3170C EUR
+
+usb:v04A9p2674*
+ ID_PRODUCT_FROM_DATABASE=L120
+
+usb:v04A9p2675*
+ ID_PRODUCT_FROM_DATABASE=iR2830
+
+usb:v04A9p2676*
+ ID_PRODUCT_FROM_DATABASE=CAPT Device
+
+usb:v04A9p2677*
+ ID_PRODUCT_FROM_DATABASE=iR C2570
+
+usb:v04A9p2678*
+ ID_PRODUCT_FROM_DATABASE=iR 2570C EUR
+
+usb:v04A9p2679*
+ ID_PRODUCT_FROM_DATABASE=CAPT Device
+
+usb:v04A9p267A*
+ ID_PRODUCT_FROM_DATABASE=iR2016
+
+usb:v04A9p267B*
+ ID_PRODUCT_FROM_DATABASE=iR2020
+
+usb:v04A9p267D*
+ ID_PRODUCT_FROM_DATABASE=MF7100 series
+
+usb:v04A9p2684*
+ ID_PRODUCT_FROM_DATABASE=MF3200 series
+
+usb:v04A9p2686*
+ ID_PRODUCT_FROM_DATABASE=MF6500 series
+
+usb:v04A9p2687*
+ ID_PRODUCT_FROM_DATABASE=iR4530
+
+usb:v04A9p2688*
+ ID_PRODUCT_FROM_DATABASE=LBP3460
+
+usb:v04A9p268C*
+ ID_PRODUCT_FROM_DATABASE=iR C6870
+
+usb:v04A9p268D*
+ ID_PRODUCT_FROM_DATABASE=iR 6870C EUR
+
+usb:v04A9p268E*
+ ID_PRODUCT_FROM_DATABASE=iR C5870
+
+usb:v04A9p268F*
+ ID_PRODUCT_FROM_DATABASE=iR 5870C EUR
+
+usb:v04A9p2691*
+ ID_PRODUCT_FROM_DATABASE=iR7105
+
+usb:v04A9p26A3*
+ ID_PRODUCT_FROM_DATABASE=MF4100 series
+
+usb:v04A9p26B0*
+ ID_PRODUCT_FROM_DATABASE=MF4600 series
+
+usb:v04A9p26B4*
+ ID_PRODUCT_FROM_DATABASE=MF4010 series
+
+usb:v04A9p26B5*
+ ID_PRODUCT_FROM_DATABASE=MF4200 series
+
+usb:v04A9p2737*
+ ID_PRODUCT_FROM_DATABASE=MF4410
+
+usb:v04A9p3041*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S10
+
+usb:v04A9p3042*
+ ID_PRODUCT_FROM_DATABASE=CanoScan FS4000US Film Scanner
+
+usb:v04A9p3043*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S20
+
+usb:v04A9p3044*
+ ID_PRODUCT_FROM_DATABASE=EOS D30
+
+usb:v04A9p3045*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S100
+
+usb:v04A9p3046*
+ ID_PRODUCT_FROM_DATABASE=IXY Digital
+
+usb:v04A9p3047*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS
+
+usb:v04A9p3048*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G1
+
+usb:v04A9p3049*
+ ID_PRODUCT_FROM_DATABASE=PowerShot Pro90 IS
+
+usb:v04A9p304A*
+ ID_PRODUCT_FROM_DATABASE=CP-10
+
+usb:v04A9p304B*
+ ID_PRODUCT_FROM_DATABASE=IXY Digital 300
+
+usb:v04A9p304C*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S300
+
+usb:v04A9p304D*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 300
+
+usb:v04A9p304E*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A20
+
+usb:v04A9p304F*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A10
+
+usb:v04A9p3050*
+ ID_PRODUCT_FROM_DATABASE=PowerShot unknown 1
+
+usb:v04A9p3051*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S110
+
+usb:v04A9p3052*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS V
+
+usb:v04A9p3055*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G2
+
+usb:v04A9p3056*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S40
+
+usb:v04A9p3057*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S30
+
+usb:v04A9p3058*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A40
+
+usb:v04A9p3059*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A30
+
+usb:v04A9p305B*
+ ID_PRODUCT_FROM_DATABASE=ZR45MC Digital Camcorder
+
+usb:v04A9p305C*
+ ID_PRODUCT_FROM_DATABASE=PowerShot unknown 2
+
+usb:v04A9p3060*
+ ID_PRODUCT_FROM_DATABASE=EOS D60
+
+usb:v04A9p3061*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A100
+
+usb:v04A9p3062*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A200
+
+usb:v04A9p3063*
+ ID_PRODUCT_FROM_DATABASE=CP-100
+
+usb:v04A9p3065*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S200
+
+usb:v04A9p3066*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 330
+
+usb:v04A9p3067*
+ ID_PRODUCT_FROM_DATABASE=MV550i Digital Video Camera
+
+usb:v04A9p3069*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G3
+
+usb:v04A9p306A*
+ ID_PRODUCT_FROM_DATABASE=Digital unknown 3
+
+usb:v04A9p306B*
+ ID_PRODUCT_FROM_DATABASE=MVX2i Digital Video Camera
+
+usb:v04A9p306C*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S45
+
+usb:v04A9p306D*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S45 PtP Mode
+
+usb:v04A9p306E*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G3 (normal mode)
+
+usb:v04A9p306F*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G3 (ptp)
+
+usb:v04A9p3070*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S230
+
+usb:v04A9p3071*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S230 (ptp)
+
+usb:v04A9p3072*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SD100 / Digital IXUS II (ptp)
+
+usb:v04A9p3073*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A70 (ptp)
+
+usb:v04A9p3074*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A60 (ptp)
+
+usb:v04A9p3075*
+ ID_PRODUCT_FROM_DATABASE=IXUS 400 Camera
+
+usb:v04A9p3076*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A300
+
+usb:v04A9p3077*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S50
+
+usb:v04A9p3078*
+ ID_PRODUCT_FROM_DATABASE=ZR70MC Digital Camcorder
+
+usb:v04A9p307A*
+ ID_PRODUCT_FROM_DATABASE=MV650i (normal mode)
+
+usb:v04A9p307B*
+ ID_PRODUCT_FROM_DATABASE=MV630i Digital Video Camera
+
+usb:v04A9p307C*
+ ID_PRODUCT_FROM_DATABASE=MV630i (normal mode)
+
+usb:v04A9p307D*
+ ID_PRODUCT_FROM_DATABASE=CP-300
+
+usb:v04A9p307F*
+ ID_PRODUCT_FROM_DATABASE=Optura 20
+
+usb:v04A9p3080*
+ ID_PRODUCT_FROM_DATABASE=MVX150i (normal mode) / Optura 20 (normal mode)
+
+usb:v04A9p3081*
+ ID_PRODUCT_FROM_DATABASE=Optura 10
+
+usb:v04A9p3082*
+ ID_PRODUCT_FROM_DATABASE=MVX100i / Optura 10
+
+usb:v04A9p3083*
+ ID_PRODUCT_FROM_DATABASE=EOS 10D
+
+usb:v04A9p3084*
+ ID_PRODUCT_FROM_DATABASE=EOS 300D / EOS Digital Rebel
+
+usb:v04A9p3085*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G5
+
+usb:v04A9p3087*
+ ID_PRODUCT_FROM_DATABASE=Elura 50 (PTP mode)
+
+usb:v04A9p3088*
+ ID_PRODUCT_FROM_DATABASE=Elura 50 (normal mode)
+
+usb:v04A9p308D*
+ ID_PRODUCT_FROM_DATABASE=MVX3i
+
+usb:v04A9p308E*
+ ID_PRODUCT_FROM_DATABASE=FV M1 (normal mode) / MVX 3i (normal mode) / Optura Xi (normal mode)
+
+usb:v04A9p3093*
+ ID_PRODUCT_FROM_DATABASE=Optura 300
+
+usb:v04A9p3096*
+ ID_PRODUCT_FROM_DATABASE=IXY DV M2 (normal mode) / MVX 10i (normal mode)
+
+usb:v04A9p3099*
+ ID_PRODUCT_FROM_DATABASE=EOS 300D (ptp)
+
+usb:v04A9p309A*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A80
+
+usb:v04A9p309B*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS (ptp)
+
+usb:v04A9p309C*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S1 IS
+
+usb:v04A9p309D*
+ ID_PRODUCT_FROM_DATABASE=Powershot Pro 1
+
+usb:v04A9p309F*
+ ID_PRODUCT_FROM_DATABASE=Camera
+
+usb:v04A9p30A0*
+ ID_PRODUCT_FROM_DATABASE=Camera
+
+usb:v04A9p30A1*
+ ID_PRODUCT_FROM_DATABASE=Camera
+
+usb:v04A9p30A2*
+ ID_PRODUCT_FROM_DATABASE=Camera
+
+usb:v04A9p30A8*
+ ID_PRODUCT_FROM_DATABASE=Elura 60E/Optura 40 (ptp)
+
+usb:v04A9p30A9*
+ ID_PRODUCT_FROM_DATABASE=MVX25i (normal mode) / Optura 40 (normal mode)
+
+usb:v04A9p30B1*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S70 (normal mode) / PowerShot S70 (PTP mode)
+
+usb:v04A9p30B2*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S60 (normal mode) / PowerShot S60 (PTP mode)
+
+usb:v04A9p30B3*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G6 (normal mode) / PowerShot G6 (PTP mode)
+
+usb:v04A9p30B4*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S500
+
+usb:v04A9p30B5*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A75
+
+usb:v04A9p30B6*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS II2  / Digital IXUS II2 (PTP mode) / PowerShot SD110 (PTP mode) / PowerShot SD110 Digital ELPH
+
+usb:v04A9p30B7*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A400 / PowerShot A400 (PTP mode)
+
+usb:v04A9p30B8*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A310 / PowerShot A310 (PTP mode)
+
+usb:v04A9p30B9*
+ ID_PRODUCT_FROM_DATABASE=Powershot A85
+
+usb:v04A9p30BA*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S410 Digital Elph
+
+usb:v04A9p30BB*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A95
+
+usb:v04A9p30BD*
+ ID_PRODUCT_FROM_DATABASE=CP-220
+
+usb:v04A9p30BE*
+ ID_PRODUCT_FROM_DATABASE=CP-330
+
+usb:v04A9p30BF*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 40
+
+usb:v04A9p30C0*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 30 (PTP mode) / PowerShot SD200 (PTP mode)
+
+usb:v04A9p30C1*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 50 (normal mode) / IXY Digital 55 (normal mode) / PowerShot A520 (PTP mode) / PowerShot SD400 (normal mode)
+
+usb:v04A9p30C2*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A510 (normal mode) / PowerShot A510 (PTP mode)
+
+usb:v04A9p30C4*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS i5 (normal mode) / IXY Digital L2 (normal mode) / PowerShot SD20 (normal mode)
+
+usb:v04A9p30EA*
+ ID_PRODUCT_FROM_DATABASE=EOS 1D Mark II (PTP mode)
+
+usb:v04A9p30EB*
+ ID_PRODUCT_FROM_DATABASE=EOS 20D
+
+usb:v04A9p30EC*
+ ID_PRODUCT_FROM_DATABASE=EOS 20D (ptp)
+
+usb:v04A9p30EE*
+ ID_PRODUCT_FROM_DATABASE=EOS 350D
+
+usb:v04A9p30EF*
+ ID_PRODUCT_FROM_DATABASE=EOS 350D (ptp)
+
+usb:v04A9p30F0*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S2 IS (PTP mode)
+
+usb:v04A9p30F2*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 700 (normal mode) / Digital IXUS 700 (PTP mode) / IXY Digital 600 (normal mode) / PowerShot SD500 (normal mode) / PowerShot SD500 (PTP mode)
+
+usb:v04A9p30F4*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SD30 / Ixus iZoom / IXY DIGITAL L3
+
+usb:v04A9p30F5*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP500
+
+usb:v04A9p30F6*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP400
+
+usb:v04A9p30F8*
+ ID_PRODUCT_FROM_DATABASE=Powershot A430
+
+usb:v04A9p30F9*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A410 (PTP mode)
+
+usb:v04A9p30FA*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S80
+
+usb:v04A9p30FC*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A620 (PTP mode)
+
+usb:v04A9p30FD*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A610 (normal mode)/PowerShot A610 (PTP mode)
+
+usb:v04A9p30FE*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 65 (PTP mode)/PowerShot SD630 (PTP mode)
+
+usb:v04A9p30FF*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 55 (PTP mode)/PowerShot SD450 (PTP mode)
+
+usb:v04A9p3100*
+ ID_PRODUCT_FROM_DATABASE=PowerShot TX1
+
+usb:v04A9p310B*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP600
+
+usb:v04A9p310E*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 50 (PTP mode)
+
+usb:v04A9p3110*
+ ID_PRODUCT_FROM_DATABASE=EOS Digital Rebel XTi
+
+usb:v04A9p3116*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 750 / PowerShot SD550 (PTP mode)
+
+usb:v04A9p3117*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A700
+
+usb:v04A9p3119*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS
+
+usb:v04A9p311B*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A540
+
+usb:v04A9p3127*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP710
+
+usb:v04A9p3128*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP510
+
+usb:v04A9p312D*
+ ID_PRODUCT_FROM_DATABASE=Elura 100
+
+usb:v04A9p3138*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A710 IS
+
+usb:v04A9p3141*
+ ID_PRODUCT_FROM_DATABASE=SELPHY ES1
+
+usb:v04A9p3142*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP730
+
+usb:v04A9p3143*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP720
+
+usb:v04A9p3147*
+ ID_PRODUCT_FROM_DATABASE=EOS 1Ds Mark III
+
+usb:v04A9p314F*
+ ID_PRODUCT_FROM_DATABASE=Powershot SD1000
+
+usb:v04A9p3155*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A450
+
+usb:v04A9p315A*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G9
+
+usb:v04A9p315D*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A720
+
+usb:v04A9p3160*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 860 IS
+
+usb:v04A9p3170*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP750
+
+usb:v04A9p3171*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP740
+
+usb:v04A9p3175*
+ ID_PRODUCT_FROM_DATABASE=IXY Digital 25 IS
+
+usb:v04A9p3176*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A590
+
+usb:v04A9p317A*
+ ID_PRODUCT_FROM_DATABASE=PC1267 [Powershot A470]
+
+usb:v04A9p3184*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 80 IS (PTP mode)
+
+usb:v04A9p3185*
+ ID_PRODUCT_FROM_DATABASE=SELPHY ES2
+
+usb:v04A9p3192*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX110 IS
+
+usb:v04A9p319A*
+ ID_PRODUCT_FROM_DATABASE=EOS 7D
+
+usb:v04A9p31AA*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP770
+
+usb:v04A9p31AB*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP760
+
+usb:v04A9p31AD*
+ ID_PRODUCT_FROM_DATABASE=PowerShot E1
+
+usb:v04A9p31B0*
+ ID_PRODUCT_FROM_DATABASE=SELPHY ES30
+
+usb:v04A9p31BC*
+ ID_PRODUCT_FROM_DATABASE=PowerShot D10
+
+usb:v04A9p31BF*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A480
+
+usb:v04A9p31C0*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX200 IS
+
+usb:v04A9p31DD*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP780
+
+usb:v04A9p31E5*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 200 IS
+
+usb:v04A9p31EE*
+ ID_PRODUCT_FROM_DATABASE=SELPHY ES40
+
+usb:v04A9p31EF*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A495
+
+usb:v04A9p31F1*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A3100 IS / PowerShot A3150 IS
+
+usb:v04A9p31F2*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A3000 IS
+
+usb:v04A9p31F3*
+ ID_PRODUCT_FROM_DATABASE=PowerShot Digital ELPH SD1400 IS
+
+usb:v04A9p31F4*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SD1300 IS / IXUS 105
+
+usb:v04A9p31F5*
+ ID_PRODUCT_FROM_DATABASE=Powershot SD3500 IS / IXUS 210 IS
+
+usb:v04A9p31F6*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX210 IS
+
+usb:v04A9p31F7*
+ ID_PRODUCT_FROM_DATABASE=Powershot SD4000 IS / IXUS 300 HS / IXY 30S
+
+usb:v04A9p31F8*
+ ID_PRODUCT_FROM_DATABASE=Powershot SD4500 IS / IXUS 1000 HS / IXY 50S
+
+usb:v04A9p31FF*
+ ID_PRODUCT_FROM_DATABASE=Digital IXUS 55
+
+usb:v04A9p3209*
+ ID_PRODUCT_FROM_DATABASE=Vixia HF S21 A
+
+usb:v04A9p3210*
+ ID_PRODUCT_FROM_DATABASE=Powershot SX30 IS
+
+usb:v04A9p3211*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX130 IS
+
+usb:v04A9p3212*
+ ID_PRODUCT_FROM_DATABASE=Powershot S95
+
+usb:v04A9p3214*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP800
+
+usb:v04A9p3218*
+ ID_PRODUCT_FROM_DATABASE=EOS 600D / Rebel T3i (ptp)
+
+usb:v04A9p3223*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A3300 IS
+
+usb:v04A9p3224*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A3200 IS
+
+usb:v04A9p3226*
+ ID_PRODUCT_FROM_DATABASE=PowerShow A800
+
+usb:v04A9p3228*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX230 HS
+
+usb:v04A9p3229*
+ ID_PRODUCT_FROM_DATABASE=IXUS 220 HS
+
+usb:v04A9p322A*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A2200
+
+usb:v04A9p322B*
+ ID_PRODUCT_FROM_DATABASE=Powershot A1200
+
+usb:v04A9p3233*
+ ID_PRODUCT_FROM_DATABASE=PowerShot G1 X
+
+usb:v04A9p3234*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX150 IS
+
+usb:v04A9p3236*
+ ID_PRODUCT_FROM_DATABASE=PowerShot S100
+
+usb:v04A9p3238*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX40 HS
+
+usb:v04A9p323F*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A810
+
+usb:v04A9p3243*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A4000 IS
+
+usb:v04A9p3244*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX260 HS
+
+usb:v04A9p3245*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX240 HS
+
+usb:v04A9p3247*
+ ID_PRODUCT_FROM_DATABASE=PowerShot ELPH 520 HS
+
+usb:v04A9p3248*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A3400 IS
+
+usb:v04A9p3249*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A2400 IS
+
+usb:v04A9p324A*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A2300
+
+usb:v04A9p3255*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP900
+
+usb:v04A9p3256*
+ ID_PRODUCT_FROM_DATABASE=SELPHY CP810
+
+usb:v04A9p3259*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX50 HS
+
+usb:v04A9p325A*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX160 IS
+
+usb:v04AA*
+ ID_VENDOR_FROM_DATABASE=DaeWoo Telecom, Ltd
+
+usb:v04AB*
+ ID_VENDOR_FROM_DATABASE=Chromatic Research
+
+usb:v04AC*
+ ID_VENDOR_FROM_DATABASE=Micro Audiometrics Corp.
+
+usb:v04AD*
+ ID_VENDOR_FROM_DATABASE=Dooin Electronics
+
+usb:v04ADp2501*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v04AF*
+ ID_VENDOR_FROM_DATABASE=Winnov L.P.
+
+usb:v04B0*
+ ID_VENDOR_FROM_DATABASE=Nikon Corp.
+
+usb:v04B0p0102*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 990
+
+usb:v04B0p0103*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 880
+
+usb:v04B0p0104*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 995
+
+usb:v04B0p0106*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 775
+
+usb:v04B0p0107*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 5000
+
+usb:v04B0p0108*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 2500
+
+usb:v04B0p0109*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 2500 (ptp)
+
+usb:v04B0p010A*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4500
+
+usb:v04B0p010B*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4500 (ptp)
+
+usb:v04B0p010D*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 5700 (ptp)
+
+usb:v04B0p010E*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4300 (storage)
+
+usb:v04B0p010F*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4300 (ptp)
+
+usb:v04B0p0110*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 3500 (Sierra Mode)
+
+usb:v04B0p0111*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 3500 (ptp)
+
+usb:v04B0p0112*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 885 (ptp)
+
+usb:v04B0p0113*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 5000 (ptp)
+
+usb:v04B0p0114*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 3100 (storage)
+
+usb:v04B0p0115*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 3100 (ptp)
+
+usb:v04B0p0117*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 2100 (ptp)
+
+usb:v04B0p0119*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 5400 (ptp)
+
+usb:v04B0p011D*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 3700 (ptp)
+
+usb:v04B0p0121*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 3200 (ptp)
+
+usb:v04B0p0122*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 2200 (ptp)
+
+usb:v04B0p0124*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 8400 (mass storage mode)
+
+usb:v04B0p0125*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 8400 (ptp)
+
+usb:v04B0p0126*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 8800
+
+usb:v04B0p0129*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4800 (ptp)
+
+usb:v04B0p012C*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4100 (storage)
+
+usb:v04B0p012D*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4100 (ptp)
+
+usb:v04B0p012E*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 5600 (ptp)
+
+usb:v04B0p0130*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4600 (ptp)
+
+usb:v04B0p0135*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 5900 (ptp)
+
+usb:v04B0p0136*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 7900 (storage)
+
+usb:v04B0p0137*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 7900 (ptp)
+
+usb:v04B0p013A*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 100 (storage)
+
+usb:v04B0p013B*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 100 (ptp)
+
+usb:v04B0p0141*
+ ID_PRODUCT_FROM_DATABASE=Coolpix P2 (storage)
+
+usb:v04B0p0142*
+ ID_PRODUCT_FROM_DATABASE=Coolpix P2 (ptp)
+
+usb:v04B0p0163*
+ ID_PRODUCT_FROM_DATABASE=Coolpix P5100 (ptp)
+
+usb:v04B0p0169*
+ ID_PRODUCT_FROM_DATABASE=Coolpix P50 (ptp)
+
+usb:v04B0p0202*
+ ID_PRODUCT_FROM_DATABASE=Coolpix SQ (ptp)
+
+usb:v04B0p0203*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4200 (mass storage mode)
+
+usb:v04B0p0204*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 4200 (ptp)
+
+usb:v04B0p0205*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 5200 (storage)
+
+usb:v04B0p0206*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 5200 (ptp)
+
+usb:v04B0p0301*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 2000 (storage)
+
+usb:v04B0p0302*
+ ID_PRODUCT_FROM_DATABASE=Coolpix 2000 (ptp)
+
+usb:v04B0p0317*
+ ID_PRODUCT_FROM_DATABASE=Coolpix L20 (ptp)
+
+usb:v04B0p0402*
+ ID_PRODUCT_FROM_DATABASE=DSC D100 (ptp)
+
+usb:v04B0p0403*
+ ID_PRODUCT_FROM_DATABASE=D2H (mass storage mode)
+
+usb:v04B0p0404*
+ ID_PRODUCT_FROM_DATABASE=D2H SLR (ptp)
+
+usb:v04B0p0405*
+ ID_PRODUCT_FROM_DATABASE=D70 (mass storage mode)
+
+usb:v04B0p0406*
+ ID_PRODUCT_FROM_DATABASE=DSC D70 (ptp)
+
+usb:v04B0p0408*
+ ID_PRODUCT_FROM_DATABASE=D2X SLR (ptp)
+
+usb:v04B0p0409*
+ ID_PRODUCT_FROM_DATABASE=D50 digital camera
+
+usb:v04B0p040A*
+ ID_PRODUCT_FROM_DATABASE=D50 (ptp)
+
+usb:v04B0p040C*
+ ID_PRODUCT_FROM_DATABASE=D2Hs
+
+usb:v04B0p040E*
+ ID_PRODUCT_FROM_DATABASE=DSC D70s (ptp)
+
+usb:v04B0p040F*
+ ID_PRODUCT_FROM_DATABASE=D200 (mass storage mode)
+
+usb:v04B0p0410*
+ ID_PRODUCT_FROM_DATABASE=D200 (ptp)
+
+usb:v04B0p0413*
+ ID_PRODUCT_FROM_DATABASE=D40 (mass storage mode)
+
+usb:v04B0p041E*
+ ID_PRODUCT_FROM_DATABASE=D60 digital camera (mass storage mode)
+
+usb:v04B0p0422*
+ ID_PRODUCT_FROM_DATABASE=D700 (ptp)
+
+usb:v04B0p0425*
+ ID_PRODUCT_FROM_DATABASE=D300S
+
+usb:v04B0p042A*
+ ID_PRODUCT_FROM_DATABASE=D800 (ptp)
+
+usb:v04B0p0F03*
+ ID_PRODUCT_FROM_DATABASE=PD-10 Wireless Printer Adapter
+
+usb:v04B0p4000*
+ ID_PRODUCT_FROM_DATABASE=Coolscan LS 40 ED
+
+usb:v04B0p4001*
+ ID_PRODUCT_FROM_DATABASE=LS 50 ED/Coolscan V ED
+
+usb:v04B0p4002*
+ ID_PRODUCT_FROM_DATABASE=Super Coolscan LS-5000 ED
+
+usb:v04B1*
+ ID_VENDOR_FROM_DATABASE=Pan International
+
+usb:v04B3*
+ ID_VENDOR_FROM_DATABASE=IBM Corp.
+
+usb:v04B3p3003*
+ ID_PRODUCT_FROM_DATABASE=Rapid Access III Keyboard
+
+usb:v04B3p3004*
+ ID_PRODUCT_FROM_DATABASE=Media Access Pro Keyboard
+
+usb:v04B3p300A*
+ ID_PRODUCT_FROM_DATABASE=Rapid Access IIIe Keyboard
+
+usb:v04B3p3016*
+ ID_PRODUCT_FROM_DATABASE=UltraNav Keyboard Hub
+
+usb:v04B3p3018*
+ ID_PRODUCT_FROM_DATABASE=UltraNav Keyboard
+
+usb:v04B3p301B*
+ ID_PRODUCT_FROM_DATABASE=SK-8815 Keyboard
+
+usb:v04B3p301C*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Performance Keyboard
+
+usb:v04B3p3020*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Performance Keyboard
+
+usb:v04B3p3025*
+ ID_PRODUCT_FROM_DATABASE=NetVista Full Width Keyboard
+
+usb:v04B3p3100*
+ ID_PRODUCT_FROM_DATABASE=NetVista Mouse
+
+usb:v04B3p3103*
+ ID_PRODUCT_FROM_DATABASE=ScrollPoint Pro Mouse
+
+usb:v04B3p3104*
+ ID_PRODUCT_FROM_DATABASE=ScrollPoint Wireless Mouse
+
+usb:v04B3p3105*
+ ID_PRODUCT_FROM_DATABASE=ScrollPoint Optical (HID)
+
+usb:v04B3p3107*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad 800dpi Optical Travel Mouse
+
+usb:v04B3p3108*
+ ID_PRODUCT_FROM_DATABASE=800dpi Optical Mouse w/ Scroll Point
+
+usb:v04B3p3109*
+ ID_PRODUCT_FROM_DATABASE=Optical ScrollPoint Pro Mouse
+
+usb:v04B3p310B*
+ ID_PRODUCT_FROM_DATABASE=Red Wheel Mouse
+
+usb:v04B3p310C*
+ ID_PRODUCT_FROM_DATABASE=Wheel Mouse
+
+usb:v04B3p4427*
+ ID_PRODUCT_FROM_DATABASE=Portable CD ROM
+
+usb:v04B3p4482*
+ ID_PRODUCT_FROM_DATABASE=Serial Converter
+
+usb:v04B3p4485*
+ ID_PRODUCT_FROM_DATABASE=Serial Converter
+
+usb:v04B3p4525*
+ ID_PRODUCT_FROM_DATABASE=Double sided CRT
+
+usb:v04B3p4535*
+ ID_PRODUCT_FROM_DATABASE=4610 Suremark Printer
+
+usb:v04B3p4550*
+ ID_PRODUCT_FROM_DATABASE=NVRAM (128 KB)
+
+usb:v04B3p4554*
+ ID_PRODUCT_FROM_DATABASE=Cash Drawer
+
+usb:v04B3p4580*
+ ID_PRODUCT_FROM_DATABASE=Hub w/ NVRAM
+
+usb:v04B3p4581*
+ ID_PRODUCT_FROM_DATABASE=4800-2xx Hub w/ Cash Drawer
+
+usb:v04B3p4604*
+ ID_PRODUCT_FROM_DATABASE=Keyboard w/ Card Reader
+
+usb:v04B3p4671*
+ ID_PRODUCT_FROM_DATABASE=4820 LCD w/ MSR/KB
+
+usb:v04B4*
+ ID_VENDOR_FROM_DATABASE=Cypress Semiconductor Corp.
+
+usb:v04B4p0001*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v04B4p0002*
+ ID_PRODUCT_FROM_DATABASE=CY7C63x0x Thermometer
+
+usb:v04B4p0033*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v04B4p0100*
+ ID_PRODUCT_FROM_DATABASE=Cino FuzzyScan F760-B
+
+usb:v04B4p0101*
+ ID_PRODUCT_FROM_DATABASE=Keyboard/Hub
+
+usb:v04B4p0102*
+ ID_PRODUCT_FROM_DATABASE=Keyboard with APM
+
+usb:v04B4p0130*
+ ID_PRODUCT_FROM_DATABASE=MyIRC Remote Receiver
+
+usb:v04B4p0306*
+ ID_PRODUCT_FROM_DATABASE=Telephone Receiver
+
+usb:v04B4p0407*
+ ID_PRODUCT_FROM_DATABASE=Optical Skype Mouse
+
+usb:v04B4p0BAD*
+ ID_PRODUCT_FROM_DATABASE=MetaGeek Wi-Spy
+
+usb:v04B4p1002*
+ ID_PRODUCT_FROM_DATABASE=CY7C63001 R100 FM Radio
+
+usb:v04B4p1006*
+ ID_PRODUCT_FROM_DATABASE=Human Interface Device
+
+usb:v04B4p2050*
+ ID_PRODUCT_FROM_DATABASE=hub
+
+usb:v04B4p2830*
+ ID_PRODUCT_FROM_DATABASE=Opera1 DVB-S (cold state)
+
+usb:v04B4p4381*
+ ID_PRODUCT_FROM_DATABASE=SCAPS USC-1 Scanner Controller
+
+usb:v04B4p4611*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter FX2 (CY)
+
+usb:v04B4p4616*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk (TPP)
+
+usb:v04B4p5201*
+ ID_PRODUCT_FROM_DATABASE=Combi Keyboard-Hub (Hub)
+
+usb:v04B4p5202*
+ ID_PRODUCT_FROM_DATABASE=Combi Keyboard-Hub (Keyboard)
+
+usb:v04B4p5500*
+ ID_PRODUCT_FROM_DATABASE=HID->COM RS232 Adapter
+
+usb:v04B4p5A9B*
+ ID_PRODUCT_FROM_DATABASE=Dacal CD/DVD Library D-101/DC-300/DC-016RW
+
+usb:v04B4p6370*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v04B4p6560*
+ ID_PRODUCT_FROM_DATABASE=CY7C65640 USB-2.0 "TetraHub"
+
+usb:v04B4p6830*
+ ID_PRODUCT_FROM_DATABASE=CY7C68300A EZ-USB AT2 USB 2.0 to ATA/ATAPI
+
+usb:v04B4p6831*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter ISD-300LP (CY)
+
+usb:v04B4p7417*
+ ID_PRODUCT_FROM_DATABASE=Wireless PC Lock/Ultra Mouse
+
+usb:v04B4p8329*
+ ID_PRODUCT_FROM_DATABASE=USB To keyboard/Mouse Converter
+
+usb:v04B4p8613*
+ ID_PRODUCT_FROM_DATABASE=CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
+
+usb:v04B4p8614*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+
+usb:v04B4p861F*
+ ID_PRODUCT_FROM_DATABASE=Anysee E30 USB 2.0 DVB-T Receiver
+
+usb:v04B4pBCA1*
+ ID_PRODUCT_FROM_DATABASE=Barcode Reader
+
+usb:v04B4pCC04*
+ ID_PRODUCT_FROM_DATABASE=Centor USB RACIA-ALVAR USB PORT
+
+usb:v04B4pCC06*
+ ID_PRODUCT_FROM_DATABASE=Centor-P RACIA-ALVAR USB PORT
+
+usb:v04B4pD5D5*
+ ID_PRODUCT_FROM_DATABASE=CY7C63x0x Zoltrix Z-Boxer GamePad
+
+usb:v04B4pDE61*
+ ID_PRODUCT_FROM_DATABASE=Barcode Reader
+
+usb:v04B4pDE64*
+ ID_PRODUCT_FROM_DATABASE=Barcode Reader
+
+usb:v04B4pF000*
+ ID_PRODUCT_FROM_DATABASE=CY30700 Licorice evaluation board
+
+usb:v04B4pF111*
+ ID_PRODUCT_FROM_DATABASE=CY8CKIT-002 PSoC MiniProg3 Rev A Program and debug kit
+
+usb:v04B4pF115*
+ ID_PRODUCT_FROM_DATABASE=PSoC FirstTouch Programmer
+
+usb:v04B5*
+ ID_VENDOR_FROM_DATABASE=ROHM LSI Systems USA, LLC
+
+usb:v04B5p3064*
+ ID_PRODUCT_FROM_DATABASE=Hantek DSO-3064
+
+usb:v04B6*
+ ID_VENDOR_FROM_DATABASE=Hint Corp.
+
+usb:v04B7*
+ ID_VENDOR_FROM_DATABASE=Compal Electronics, Inc.
+
+usb:v04B8*
+ ID_VENDOR_FROM_DATABASE=Seiko Epson Corp.
+
+usb:v04B8p0001*
+ ID_PRODUCT_FROM_DATABASE=Stylus Color 740 / Photo 750
+
+usb:v04B8p0002*
+ ID_PRODUCT_FROM_DATABASE=ISD Smart Cable for Mac
+
+usb:v04B8p0003*
+ ID_PRODUCT_FROM_DATABASE=ISD Smart Cable
+
+usb:v04B8p0004*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04B8p0005*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04B8p0006*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04B8p0007*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04B8p0101*
+ ID_PRODUCT_FROM_DATABASE=GT-7000U [Perfection 636]
+
+usb:v04B8p0102*
+ ID_PRODUCT_FROM_DATABASE=GT-2200
+
+usb:v04B8p0103*
+ ID_PRODUCT_FROM_DATABASE=GT-6600U [Perfection 610]
+
+usb:v04B8p0104*
+ ID_PRODUCT_FROM_DATABASE=GT-7600UF [Perfection 1200U/1200U Photo]
+
+usb:v04B8p0105*
+ ID_PRODUCT_FROM_DATABASE=Stylus Scan 2000
+
+usb:v04B8p0106*
+ ID_PRODUCT_FROM_DATABASE=Stylus Scan 2500
+
+usb:v04B8p0107*
+ ID_PRODUCT_FROM_DATABASE=ES-2000 [Expression 1600U]
+
+usb:v04B8p0108*
+ ID_PRODUCT_FROM_DATABASE=CC-700
+
+usb:v04B8p0109*
+ ID_PRODUCT_FROM_DATABASE=ES-8500 [Expression 1640 XL]
+
+usb:v04B8p010A*
+ ID_PRODUCT_FROM_DATABASE=GT-8700/GT-8700F [Perfection 1640SU/1640SU PHOTO]
+
+usb:v04B8p010B*
+ ID_PRODUCT_FROM_DATABASE=GT-7700U [Perfection 1240U]
+
+usb:v04B8p010C*
+ ID_PRODUCT_FROM_DATABASE=GT-6700U [Perfection 640]
+
+usb:v04B8p010D*
+ ID_PRODUCT_FROM_DATABASE=CC-500L
+
+usb:v04B8p010E*
+ ID_PRODUCT_FROM_DATABASE=ES-2200 [Perfection 1680]
+
+usb:v04B8p010F*
+ ID_PRODUCT_FROM_DATABASE=GT-7200U [Perfection 1250/1250 PHOTO]
+
+usb:v04B8p0110*
+ ID_PRODUCT_FROM_DATABASE=GT-8200U/GT-8200UF [Perfection 1650/1650 PHOTO]
+
+usb:v04B8p0112*
+ ID_PRODUCT_FROM_DATABASE=GT-9700F [Perfection 2450 PHOTO]
+
+usb:v04B8p0114*
+ ID_PRODUCT_FROM_DATABASE=Perfection 660
+
+usb:v04B8p0116*
+ ID_PRODUCT_FROM_DATABASE=GT-9400UF [Perfection 3170]
+
+usb:v04B8p0118*
+ ID_PRODUCT_FROM_DATABASE=GT-F600 [Perfection 4180]
+
+usb:v04B8p0119*
+ ID_PRODUCT_FROM_DATABASE=GT-X750 [Perfection 4490 Photo]
+
+usb:v04B8p011A*
+ ID_PRODUCT_FROM_DATABASE=CC-550L [1000 ICS]
+
+usb:v04B8p011B*
+ ID_PRODUCT_FROM_DATABASE=GT-9300UF [Perfection 2400 PHOTO]
+
+usb:v04B8p011C*
+ ID_PRODUCT_FROM_DATABASE=GT-9800F [Perfection 3200]
+
+usb:v04B8p011D*
+ ID_PRODUCT_FROM_DATABASE=GT-7300U [Perfection 1260/1260 PHOTO]
+
+usb:v04B8p011E*
+ ID_PRODUCT_FROM_DATABASE=GT-8300UF [Perfection 1660 PHOTO]
+
+usb:v04B8p011F*
+ ID_PRODUCT_FROM_DATABASE=GT-8400UF [Perfection 1670/1670 PHOTO]
+
+usb:v04B8p0120*
+ ID_PRODUCT_FROM_DATABASE=GT-7400U [Perfection 1270]
+
+usb:v04B8p0121*
+ ID_PRODUCT_FROM_DATABASE=GT-F500/GT-F550 [Perfection 2480/2580 PHOTO]
+
+usb:v04B8p0122*
+ ID_PRODUCT_FROM_DATABASE=GT-F520/GT-F570 [Perfection 3590 PHOTO]
+
+usb:v04B8p0126*
+ ID_PRODUCT_FROM_DATABASE=ES-7000H [GT-15000]
+
+usb:v04B8p0128*
+ ID_PRODUCT_FROM_DATABASE=GT-X700 [Perfection 4870]
+
+usb:v04B8p0129*
+ ID_PRODUCT_FROM_DATABASE=ES-10000G [Expression 10000XL]
+
+usb:v04B8p012A*
+ ID_PRODUCT_FROM_DATABASE=GT-X800 [Perfection 4990 PHOTO]
+
+usb:v04B8p012B*
+ ID_PRODUCT_FROM_DATABASE=ES-H300 [GT-2500]
+
+usb:v04B8p012C*
+ ID_PRODUCT_FROM_DATABASE=GT-X900 [Perfection V700/V750 Photo]
+
+usb:v04B8p012D*
+ ID_PRODUCT_FROM_DATABASE=GT-F650 [GT-S600/Perfection V10/V100]
+
+usb:v04B8p012E*
+ ID_PRODUCT_FROM_DATABASE=GT-F670 [Perfection V200 Photo]
+
+usb:v04B8p012F*
+ ID_PRODUCT_FROM_DATABASE=GT-F700 [Perfection V350]
+
+usb:v04B8p0130*
+ ID_PRODUCT_FROM_DATABASE=GT-X770 [Perfection V500]
+
+usb:v04B8p0131*
+ ID_PRODUCT_FROM_DATABASE=GT-F720 [GT-S620/Perfection V30/V300 Photo]
+
+usb:v04B8p0133*
+ ID_PRODUCT_FROM_DATABASE=GT-1500 [GT-D1000]
+
+usb:v04B8p0135*
+ ID_PRODUCT_FROM_DATABASE=GT-X970
+
+usb:v04B8p0136*
+ ID_PRODUCT_FROM_DATABASE=ES-D400 [GT-S80]
+
+usb:v04B8p0137*
+ ID_PRODUCT_FROM_DATABASE=ES-D200 [GT-S50]
+
+usb:v04B8p0138*
+ ID_PRODUCT_FROM_DATABASE=ES-H7200 [GT-20000]
+
+usb:v04B8p013A*
+ ID_PRODUCT_FROM_DATABASE=GT-X820 [Perfection V600 Photo]
+
+usb:v04B8p0142*
+ ID_PRODUCT_FROM_DATABASE=GT-F730 [GT-S630/Perfection V33/V330 Photo]
+
+usb:v04B8p0143*
+ ID_PRODUCT_FROM_DATABASE=GT-S55
+
+usb:v04B8p0144*
+ ID_PRODUCT_FROM_DATABASE=GT-S85
+
+usb:v04B8p0202*
+ ID_PRODUCT_FROM_DATABASE=Receipt Printer M129C
+
+usb:v04B8p0401*
+ ID_PRODUCT_FROM_DATABASE=CP 800 Digital Camera
+
+usb:v04B8p0402*
+ ID_PRODUCT_FROM_DATABASE=PhotoPC 850z
+
+usb:v04B8p0403*
+ ID_PRODUCT_FROM_DATABASE=PhotoPC 3000z
+
+usb:v04B8p0509*
+ ID_PRODUCT_FROM_DATABASE=JVC PIX-MC10
+
+usb:v04B8p0601*
+ ID_PRODUCT_FROM_DATABASE=Stylus Photo 875DC Card Reader
+
+usb:v04B8p0602*
+ ID_PRODUCT_FROM_DATABASE=Stylus Photo 895 Card Reader
+
+usb:v04B8p0801*
+ ID_PRODUCT_FROM_DATABASE=CC-600PX [Stylus CX5200/CX5400/CX6600]
+
+usb:v04B8p0802*
+ ID_PRODUCT_FROM_DATABASE=CC-570L [Stylus CX3100/CX3200]
+
+usb:v04B8p0803*
+ ID_PRODUCT_FROM_DATABASE=Printer (Composite Device)
+
+usb:v04B8p0804*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v04B8p0805*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX6300/CX6400
+
+usb:v04B8p0806*
+ ID_PRODUCT_FROM_DATABASE=PM-A850 [Stylus Photo RX600/610]
+
+usb:v04B8p0807*
+ ID_PRODUCT_FROM_DATABASE=Stylus Photo RX500/510
+
+usb:v04B8p0808*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX5200/CX5300/CX5400
+
+usb:v04B8p0809*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v04B8p080A*
+ ID_PRODUCT_FROM_DATABASE=F-3200
+
+usb:v04B8p080C*
+ ID_PRODUCT_FROM_DATABASE=ME100 [Stylus CX1500]
+
+usb:v04B8p080D*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX4500/4600
+
+usb:v04B8p080E*
+ ID_PRODUCT_FROM_DATABASE=PX-A550 [CX-3500/3600/3650 MFP]
+
+usb:v04B8p080F*
+ ID_PRODUCT_FROM_DATABASE=Stylus Photo RX420/RX425/RX430
+
+usb:v04B8p0810*
+ ID_PRODUCT_FROM_DATABASE=PM-A900 [Stylus Photo RX700]
+
+usb:v04B8p0811*
+ ID_PRODUCT_FROM_DATABASE=PM-A870 [Stylus Photo RX620/RX630]
+
+usb:v04B8p0812*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p0813*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX6500/6600
+
+usb:v04B8p0814*
+ ID_PRODUCT_FROM_DATABASE=PM-A700
+
+usb:v04B8p0815*
+ ID_PRODUCT_FROM_DATABASE=LP-A500 [AcuLaser CX1]
+
+usb:v04B8p0816*
+ ID_PRODUCT_FROM_DATABASE=Printer (Composite Device)
+
+usb:v04B8p0817*
+ ID_PRODUCT_FROM_DATABASE=LP-M5500/LP-M5500F
+
+usb:v04B8p0818*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX3700/CX3800/DX3800
+
+usb:v04B8p0819*
+ ID_PRODUCT_FROM_DATABASE=PX-A650 [Stylus CX4700/CX4800/DX4800/DX4850]
+
+usb:v04B8p081A*
+ ID_PRODUCT_FROM_DATABASE=PM-A750 [Stylus Photo RX520/RX530]
+
+usb:v04B8p081B*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p081C*
+ ID_PRODUCT_FROM_DATABASE=PM-A890 [Stylus Photo RX640/RX650]
+
+usb:v04B8p081D*
+ ID_PRODUCT_FROM_DATABASE=PM-A950
+
+usb:v04B8p081E*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p081F*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX7700/7800
+
+usb:v04B8p0820*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX4100/CX4200/DX4200
+
+usb:v04B8p0821*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX5700F/CX5800F
+
+usb:v04B8p0822*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v04B8p0823*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p0824*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v04B8p0825*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p0826*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v04B8p0827*
+ ID_PRODUCT_FROM_DATABASE=PM-A820 [Stylus Photo RX560/RX580/RX585/RX590]
+
+usb:v04B8p0828*
+ ID_PRODUCT_FROM_DATABASE=PM-A970
+
+usb:v04B8p0829*
+ ID_PRODUCT_FROM_DATABASE=PM-T990
+
+usb:v04B8p082A*
+ ID_PRODUCT_FROM_DATABASE=PM-A920
+
+usb:v04B8p082B*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX5900/CX5000/DX5000/DX5050
+
+usb:v04B8p082C*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v04B8p082D*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v04B8p082E*
+ ID_PRODUCT_FROM_DATABASE=PX-A720 [Stylus CX5900/CX6000/DX6000]
+
+usb:v04B8p082F*
+ ID_PRODUCT_FROM_DATABASE=PX-A620 [Stylus CX3900/DX4000/DX4050]
+
+usb:v04B8p0830*
+ ID_PRODUCT_FROM_DATABASE=ME 200 [Stylus CX2800/CX2900]
+
+usb:v04B8p0831*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX6900F/CX7000F/DX7000F
+
+usb:v04B8p0832*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p0833*
+ ID_PRODUCT_FROM_DATABASE=LP-M5600
+
+usb:v04B8p0834*
+ ID_PRODUCT_FROM_DATABASE=LP-M6000
+
+usb:v04B8p0835*
+ ID_PRODUCT_FROM_DATABASE=AcuLaser CX21
+
+usb:v04B8p0836*
+ ID_PRODUCT_FROM_DATABASE=PM-T960
+
+usb:v04B8p0837*
+ ID_PRODUCT_FROM_DATABASE=PM-A940 [Stylus Photo RX680/RX685/RX690]
+
+usb:v04B8p0838*
+ ID_PRODUCT_FROM_DATABASE=PX-A640 [CX7300/CX7400/DX7400]
+
+usb:v04B8p0839*
+ ID_PRODUCT_FROM_DATABASE=PX-A740 [CX8300/CX8400/DX8400]
+
+usb:v04B8p083A*
+ ID_PRODUCT_FROM_DATABASE=PX-FA700 [CX9300F/CX9400Fax/DX9400F]
+
+usb:v04B8p083B*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p083C*
+ ID_PRODUCT_FROM_DATABASE=PM-A840S [Stylus Photo RX595/RX610]
+
+usb:v04B8p083D*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p083E*
+ ID_PRODUCT_FROM_DATABASE=MFP Composite Device
+
+usb:v04B8p083F*
+ ID_PRODUCT_FROM_DATABASE=Stylus CX4300/CX4400/CX5500/CX5600/DX4400/DX4450
+
+usb:v04B8p0841*
+ ID_PRODUCT_FROM_DATABASE=PX-401A [ME 300/Stylus NX100]
+
+usb:v04B8p0843*
+ ID_PRODUCT_FROM_DATABASE=LP-M5000
+
+usb:v04B8p0844*
+ ID_PRODUCT_FROM_DATABASE=EP-901A/EP-901F [Artisan 800/Stylus Photo PX800FW]
+
+usb:v04B8p0846*
+ ID_PRODUCT_FROM_DATABASE=EP-801A [Artisan 700/Stylus Photo PX700W/TX700W]
+
+usb:v04B8p0847*
+ ID_PRODUCT_FROM_DATABASE=PX-601F [ME Office 700FW/Stylus Office BX600FW/TX600FW]
+
+usb:v04B8p0848*
+ ID_PRODUCT_FROM_DATABASE=ME Office 600F/Stylus Office BX300F/TX300F
+
+usb:v04B8p0849*
+ ID_PRODUCT_FROM_DATABASE=Stylus SX205
+
+usb:v04B8p084A*
+ ID_PRODUCT_FROM_DATABASE=PX-501A [Stylus NX400]
+
+usb:v04B8p084D*
+ ID_PRODUCT_FROM_DATABASE=PX-402A [Stylus SX115/Stylus NX110 Series]
+
+usb:v04B8p084F*
+ ID_PRODUCT_FROM_DATABASE=ME OFFICE 510
+
+usb:v04B8p0850*
+ ID_PRODUCT_FROM_DATABASE=EP-702A [Stylus Photo PX650/TX650 Series]
+
+usb:v04B8p0851*
+ ID_PRODUCT_FROM_DATABASE=Stylus SX410
+
+usb:v04B8p0852*
+ ID_PRODUCT_FROM_DATABASE=EP-802A [Artisan 710 Series/Stylus Photo PX710W/TX720W Series]
+
+usb:v04B8p0853*
+ ID_PRODUCT_FROM_DATABASE=EP-902A [Artisan 810 Series/Stylus Photo PX810FW Series]
+
+usb:v04B8p0854*
+ ID_PRODUCT_FROM_DATABASE=ME OFFICE 650FN Series/Stylus Office BX310FN/TX520FN Series
+
+usb:v04B8p0855*
+ ID_PRODUCT_FROM_DATABASE=PX-602F [Stylus Office BX610FW/TX620FW Series]
+
+usb:v04B8p0856*
+ ID_PRODUCT_FROM_DATABASE=PX-502A [Stylus SX515W]
+
+usb:v04B8p085C*
+ ID_PRODUCT_FROM_DATABASE=ME 320/330 Series [Stylus SX125]
+
+usb:v04B8p085D*
+ ID_PRODUCT_FROM_DATABASE=PX-603F [ME OFFICE 960FWD Series/Stylus Office BX625FWD/TX620FWD Series]
+
+usb:v04B8p085E*
+ ID_PRODUCT_FROM_DATABASE=PX-503A [ME OFFICE 900WD Series/Stylus Office BX525WD]
+
+usb:v04B8p085F*
+ ID_PRODUCT_FROM_DATABASE=Stylus Office BX320FW/TX525FW Series
+
+usb:v04B8p0860*
+ ID_PRODUCT_FROM_DATABASE=EP-903A/EP-903F [Artisan 835/Stylus Photo PX820FWD Series]
+
+usb:v04B8p0861*
+ ID_PRODUCT_FROM_DATABASE=EP-803A/EP-803AW [Artisan 725/Stylus Photo PX720WD/TX720WD Series]
+
+usb:v04B8p0862*
+ ID_PRODUCT_FROM_DATABASE=EP-703A [Stylus Photo PX660 Series]
+
+usb:v04B8p0863*
+ ID_PRODUCT_FROM_DATABASE=ME OFFICE 620F Series/Stylus Office BX305F/BX305FW/TX320F
+
+usb:v04B8p0864*
+ ID_PRODUCT_FROM_DATABASE=ME OFFICE 560W Series
+
+usb:v04B8p0865*
+ ID_PRODUCT_FROM_DATABASE=ME OFFICE 520 Series
+
+usb:v04B8p0866*
+ ID_PRODUCT_FROM_DATABASE=AcuLaser MX20DN/MX20DNF/MX21DNF
+
+usb:v04B8p0869*
+ ID_PRODUCT_FROM_DATABASE=PX-1600F
+
+usb:v04B8p086A*
+ ID_PRODUCT_FROM_DATABASE=PX-673F [Stylus Office BX925FWD]
+
+usb:v04B8p0870*
+ ID_PRODUCT_FROM_DATABASE=Stylus Office BX305FW Plus
+
+usb:v04B8p0871*
+ ID_PRODUCT_FROM_DATABASE=K200 Series
+
+usb:v04B8p0872*
+ ID_PRODUCT_FROM_DATABASE=K300 Series
+
+usb:v04B8p0873*
+ ID_PRODUCT_FROM_DATABASE=L200 Series
+
+usb:v04B8p0878*
+ ID_PRODUCT_FROM_DATABASE=EP-704A
+
+usb:v04B8p0879*
+ ID_PRODUCT_FROM_DATABASE=EP-904A/EP-904F [Artisan 837/Stylus Photo PX830FWD Series]
+
+usb:v04B8p087B*
+ ID_PRODUCT_FROM_DATABASE=EP-804A/EP-804AR/EP-804AW [Stylus Photo PX730WD/Artisan 730 Series]
+
+usb:v04B8p087C*
+ ID_PRODUCT_FROM_DATABASE=PX-1700F
+
+usb:v04B8p087D*
+ ID_PRODUCT_FROM_DATABASE=PX-B750F
+
+usb:v04B8p087F*
+ ID_PRODUCT_FROM_DATABASE=PX-403A
+
+usb:v04B8p0880*
+ ID_PRODUCT_FROM_DATABASE=PX-434A [Stylus NX330 Series]
+
+usb:v04B8p0881*
+ ID_PRODUCT_FROM_DATABASE=PX-404A [ME OFFICE 535]
+
+usb:v04B8p0883*
+ ID_PRODUCT_FROM_DATABASE=ME 340 Series/Stylus NX130 Series
+
+usb:v04B8p0884*
+ ID_PRODUCT_FROM_DATABASE=Stylus NX430W Series
+
+usb:v04B8p0885*
+ ID_PRODUCT_FROM_DATABASE=Stylus NX230 Series
+
+usb:v04B8p088F*
+ ID_PRODUCT_FROM_DATABASE=Stylus Office BX635FWD
+
+usb:v04B8p0890*
+ ID_PRODUCT_FROM_DATABASE=ME OFFICE 940FW Series/Stylus Office BX630FW Series
+
+usb:v04B8p0891*
+ ID_PRODUCT_FROM_DATABASE=Stylus Office BX535WD
+
+usb:v04B8p0892*
+ ID_PRODUCT_FROM_DATABASE=Stylus Office BX935FWD
+
+usb:v04B8p0893*
+ ID_PRODUCT_FROM_DATABASE=EP-774A
+
+usb:v04B9*
+ ID_VENDOR_FROM_DATABASE=Rainbow Technologies, Inc.
+
+usb:v04B9p0300*
+ ID_PRODUCT_FROM_DATABASE=SafeNet USB SuperPro/UltraPro
+
+usb:v04B9p1000*
+ ID_PRODUCT_FROM_DATABASE=iKey 1000 Token
+
+usb:v04B9p1001*
+ ID_PRODUCT_FROM_DATABASE=iKey 1200 Token
+
+usb:v04B9p1002*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1003*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1004*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1005*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1006*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1200*
+ ID_PRODUCT_FROM_DATABASE=iKey 2000 Token
+
+usb:v04B9p1201*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1202*
+ ID_PRODUCT_FROM_DATABASE=iKey 2032 Token
+
+usb:v04B9p1203*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1204*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1205*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1206*
+ ID_PRODUCT_FROM_DATABASE=iKey 4000 Token
+
+usb:v04B9p1300*
+ ID_PRODUCT_FROM_DATABASE=iKey 3000 Token
+
+usb:v04B9p1301*
+ ID_PRODUCT_FROM_DATABASE=iKey 3000
+
+usb:v04B9p1302*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1303*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1304*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1305*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04B9p1306*
+ ID_PRODUCT_FROM_DATABASE=iKey Token
+
+usb:v04BA*
+ ID_VENDOR_FROM_DATABASE=Toucan Systems, Ltd
+
+usb:v04BB*
+ ID_VENDOR_FROM_DATABASE=I-O Data Device, Inc.
+
+usb:v04BBp0101*
+ ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter
+
+usb:v04BBp0201*
+ ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter
+
+usb:v04BBp0204*
+ ID_PRODUCT_FROM_DATABASE=DVD Multi-plus unit iU-CD2
+
+usb:v04BBp0206*
+ ID_PRODUCT_FROM_DATABASE=DVD Multi-plus unit DVR-UEH8
+
+usb:v04BBp0301*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v04BBp0314*
+ ID_PRODUCT_FROM_DATABASE=USB-SSMRW SD-card
+
+usb:v04BBp0319*
+ ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter
+
+usb:v04BBp031A*
+ ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter
+
+usb:v04BBp031B*
+ ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter
+
+usb:v04BBp031E*
+ ID_PRODUCT_FROM_DATABASE=USB-SDRW SD-card
+
+usb:v04BBp0502*
+ ID_PRODUCT_FROM_DATABASE=Nogatech Live! (BT)
+
+usb:v04BBp0528*
+ ID_PRODUCT_FROM_DATABASE=GV-USB Video Capture
+
+usb:v04BBp0901*
+ ID_PRODUCT_FROM_DATABASE=USB ETT
+
+usb:v04BBp0904*
+ ID_PRODUCT_FROM_DATABASE=ET/TX Ethernet [pegasus]
+
+usb:v04BBp0913*
+ ID_PRODUCT_FROM_DATABASE=ET/TX-S Ethernet [pegasus2]
+
+usb:v04BBp0919*
+ ID_PRODUCT_FROM_DATABASE=USB WN-B11
+
+usb:v04BBp0922*
+ ID_PRODUCT_FROM_DATABASE=IOData AirPort WN-B11/USBS 802.11b
+
+usb:v04BBp0930*
+ ID_PRODUCT_FROM_DATABASE=ETG-US2
+
+usb:v04BBp0937*
+ ID_PRODUCT_FROM_DATABASE=WN-WAG/USL Wireless LAN Adapter
+
+usb:v04BBp0938*
+ ID_PRODUCT_FROM_DATABASE=WN-G54/USL Wireless LAN Adapter
+
+usb:v04BBp093B*
+ ID_PRODUCT_FROM_DATABASE=WN-GDN/USB
+
+usb:v04BBp093F*
+ ID_PRODUCT_FROM_DATABASE=WNGDNUS2 802.11n
+
+usb:v04BBp0944*
+ ID_PRODUCT_FROM_DATABASE=WHG-AGDN/US Wireless LAN Adapter
+
+usb:v04BBp0945*
+ ID_PRODUCT_FROM_DATABASE=WN-GDN/US3 Wireless LAN Adapter
+
+usb:v04BBp0947*
+ ID_PRODUCT_FROM_DATABASE=WN-G150U Wireless LAN Adapter
+
+usb:v04BBp0948*
+ ID_PRODUCT_FROM_DATABASE=WN-G300U Wireless LAN Adapter
+
+usb:v04BBp0A03*
+ ID_PRODUCT_FROM_DATABASE=Serial USB-RSAQ1
+
+usb:v04BBp0A07*
+ ID_PRODUCT_FROM_DATABASE=USB2-iCN Adapter
+
+usb:v04BBp0A08*
+ ID_PRODUCT_FROM_DATABASE=USB2-iCN Adapter
+
+usb:v04BBp0C01*
+ ID_PRODUCT_FROM_DATABASE=FM-10 Pro Disk
+
+usb:v04BD*
+ ID_VENDOR_FROM_DATABASE=Toshiba Electronics Taiwan Corp.
+
+usb:v04BE*
+ ID_VENDOR_FROM_DATABASE=Telia Research AB
+
+usb:v04BF*
+ ID_VENDOR_FROM_DATABASE=TDK Corp.
+
+usb:v04BFp0100*
+ ID_PRODUCT_FROM_DATABASE=MediaReader CF
+
+usb:v04BFp0115*
+ ID_PRODUCT_FROM_DATABASE=USB-PDC Adapter UPA9664
+
+usb:v04BFp0116*
+ ID_PRODUCT_FROM_DATABASE=USB-cdmaOne Adapter UCA1464
+
+usb:v04BFp0117*
+ ID_PRODUCT_FROM_DATABASE=USB-PHS Adapter UHA6400
+
+usb:v04BFp0118*
+ ID_PRODUCT_FROM_DATABASE=USB-PHS Adapter UPA6400
+
+usb:v04BFp0135*
+ ID_PRODUCT_FROM_DATABASE=MediaReader Dual
+
+usb:v04BFp0202*
+ ID_PRODUCT_FROM_DATABASE=73S1121F Smart Card Reader-
+
+usb:v04BFp0309*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth USB dongle
+
+usb:v04BFp030A*
+ ID_PRODUCT_FROM_DATABASE=IBM Bluetooth Ultraport Module
+
+usb:v04BFp030B*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v04BFp030C*
+ ID_PRODUCT_FROM_DATABASE=Ultraport Bluetooth Device
+
+usb:v04BFp0310*
+ ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth
+
+usb:v04BFp0311*
+ ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth Device
+
+usb:v04BFp0317*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth UltraPort Module from IBM
+
+usb:v04BFp0318*
+ ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth
+
+usb:v04BFp0319*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter
+
+usb:v04BFp0320*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter
+
+usb:v04BFp0321*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v04BFp0A28*
+ ID_PRODUCT_FROM_DATABASE=INDI AV-IN Device
+
+usb:v04C1*
+ ID_VENDOR_FROM_DATABASE=U.S. Robotics (3Com)
+
+usb:v04C1p0020*
+ ID_PRODUCT_FROM_DATABASE=56K Voice Pro
+
+usb:v04C1p0022*
+ ID_PRODUCT_FROM_DATABASE=56K Voice Pro
+
+usb:v04C1p007E*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA
+
+usb:v04C1p0082*
+ ID_PRODUCT_FROM_DATABASE=OfficeConnect Analog Modem
+
+usb:v04C1p008F*
+ ID_PRODUCT_FROM_DATABASE=Pro ISDN TA
+
+usb:v04C1p0097*
+ ID_PRODUCT_FROM_DATABASE=OfficeConnect Analog
+
+usb:v04C1p009D*
+ ID_PRODUCT_FROM_DATABASE=HomeConnect Webcam [vicam]
+
+usb:v04C1p00A9*
+ ID_PRODUCT_FROM_DATABASE=ISDN Pro TA-U
+
+usb:v04C1p00B9*
+ ID_PRODUCT_FROM_DATABASE=HomeConnect IDSL Modem
+
+usb:v04C1p3021*
+ ID_PRODUCT_FROM_DATABASE=56k Voice FaxModem Pro
+
+usb:v04C2*
+ ID_VENDOR_FROM_DATABASE=Methode Electronics Far East PTE, Ltd
+
+usb:v04C3*
+ ID_VENDOR_FROM_DATABASE=Maxi Switch, Inc.
+
+usb:v04C3p1102*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v04C3p2102*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v04C4*
+ ID_VENDOR_FROM_DATABASE=Lockheed Martin Energy Research
+
+usb:v04C5*
+ ID_VENDOR_FROM_DATABASE=Fujitsu, Ltd
+
+usb:v04C5p1029*
+ ID_PRODUCT_FROM_DATABASE=fi-4010c Scanner
+
+usb:v04C5p1033*
+ ID_PRODUCT_FROM_DATABASE=fi-4110CU
+
+usb:v04C5p1041*
+ ID_PRODUCT_FROM_DATABASE=fi-4120c Scanner
+
+usb:v04C5p1042*
+ ID_PRODUCT_FROM_DATABASE=fi-4220c Scanner
+
+usb:v04C5p105B*
+ ID_PRODUCT_FROM_DATABASE=AH-F401U Air H device
+
+usb:v04C5p1096*
+ ID_PRODUCT_FROM_DATABASE=fi-5110EOX
+
+usb:v04C5p1097*
+ ID_PRODUCT_FROM_DATABASE=fi-5110C
+
+usb:v04C5p10AE*
+ ID_PRODUCT_FROM_DATABASE=fi-4120C2
+
+usb:v04C5p10AF*
+ ID_PRODUCT_FROM_DATABASE=fi-4220C2
+
+usb:v04C5p10E0*
+ ID_PRODUCT_FROM_DATABASE=fi-5120c Scanner
+
+usb:v04C5p10E1*
+ ID_PRODUCT_FROM_DATABASE=fi-5220C
+
+usb:v04C5p10E7*
+ ID_PRODUCT_FROM_DATABASE=fi-5900C
+
+usb:v04C5p10FE*
+ ID_PRODUCT_FROM_DATABASE=S500
+
+usb:v04C5p1150*
+ ID_PRODUCT_FROM_DATABASE=fi-6230
+
+usb:v04C6*
+ ID_VENDOR_FROM_DATABASE=Toshiba America Electronic Components
+
+usb:v04C7*
+ ID_VENDOR_FROM_DATABASE=Micro Macro Technologies
+
+usb:v04C8*
+ ID_VENDOR_FROM_DATABASE=Konica Corp.
+
+usb:v04C8p0720*
+ ID_PRODUCT_FROM_DATABASE=Digital Color Camera
+
+usb:v04C8p0721*
+ ID_PRODUCT_FROM_DATABASE=e-miniD Camera
+
+usb:v04C8p0722*
+ ID_PRODUCT_FROM_DATABASE=e-mini
+
+usb:v04C8p0723*
+ ID_PRODUCT_FROM_DATABASE=KD-200Z Camera
+
+usb:v04C8p0726*
+ ID_PRODUCT_FROM_DATABASE=KD-310Z Camera
+
+usb:v04C8p0728*
+ ID_PRODUCT_FROM_DATABASE=Revio C2 Mass Storage Device
+
+usb:v04C8p0729*
+ ID_PRODUCT_FROM_DATABASE=Revio C2 Digital Camera
+
+usb:v04C8p072C*
+ ID_PRODUCT_FROM_DATABASE=Revio KD20M
+
+usb:v04C8p072D*
+ ID_PRODUCT_FROM_DATABASE=Revio KD410Z
+
+usb:v04CA*
+ ID_VENDOR_FROM_DATABASE=Lite-On Technology Corp.
+
+usb:v04CAp1766*
+ ID_PRODUCT_FROM_DATABASE=HID Monitor Controls
+
+usb:v04CAp9304*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v04CApF01C*
+ ID_PRODUCT_FROM_DATABASE=TT1280DA DVB-T TV Tuner
+
+usb:v04CB*
+ ID_VENDOR_FROM_DATABASE=Fuji Photo Film Co., Ltd
+
+usb:v04CBp0100*
+ ID_PRODUCT_FROM_DATABASE=FinePix 30i/40i/50i, A101/201, 1300/2200, 1400/2400/2600/2800/4500/4700/4800/4900/6800/6900 Zoom
+
+usb:v04CBp0103*
+ ID_PRODUCT_FROM_DATABASE=FinePix NX-500/NX-700 printer
+
+usb:v04CBp0104*
+ ID_PRODUCT_FROM_DATABASE=FinePix A101, 2600/2800/4800/6800 Zoom (PC CAM)
+
+usb:v04CBp0108*
+ ID_PRODUCT_FROM_DATABASE=FinePix F601 Zoom (DSC)
+
+usb:v04CBp0109*
+ ID_PRODUCT_FROM_DATABASE=FinePix F601 Zoom (PC CAM)
+
+usb:v04CBp010A*
+ ID_PRODUCT_FROM_DATABASE=FinePix S602 (Pro) Zoom (DSC)
+
+usb:v04CBp010B*
+ ID_PRODUCT_FROM_DATABASE=FinePix S602 (Pro) Zoom (PC CAM)
+
+usb:v04CBp010D*
+ ID_PRODUCT_FROM_DATABASE=FinePix Digital Camera 020531
+
+usb:v04CBp010E*
+ ID_PRODUCT_FROM_DATABASE=FinePix F402 Zoom (DSC)
+
+usb:v04CBp010F*
+ ID_PRODUCT_FROM_DATABASE=FinePix F402 Zoom (PC CAM)
+
+usb:v04CBp0110*
+ ID_PRODUCT_FROM_DATABASE=FinePix M603 Zoom (DSC)
+
+usb:v04CBp0111*
+ ID_PRODUCT_FROM_DATABASE=FinePix M603 Zoom (PC CAM)
+
+usb:v04CBp0112*
+ ID_PRODUCT_FROM_DATABASE=FinePix A202, A200 Zoom (DSC)
+
+usb:v04CBp0113*
+ ID_PRODUCT_FROM_DATABASE=FinePix A202, A200 Zoom (PC CAM)
+
+usb:v04CBp0114*
+ ID_PRODUCT_FROM_DATABASE=FinePix F401 Zoom (DSC)
+
+usb:v04CBp0115*
+ ID_PRODUCT_FROM_DATABASE=FinePix F401 Zoom (PC CAM)
+
+usb:v04CBp0116*
+ ID_PRODUCT_FROM_DATABASE=FinePix A203 Zoom (DSC)
+
+usb:v04CBp0117*
+ ID_PRODUCT_FROM_DATABASE=FinePix A203 Zoom (PC CAM)
+
+usb:v04CBp0118*
+ ID_PRODUCT_FROM_DATABASE=FinePix A303 Zoom (DSC)
+
+usb:v04CBp0119*
+ ID_PRODUCT_FROM_DATABASE=FinePix A303 Zoom (PC CAM)
+
+usb:v04CBp011A*
+ ID_PRODUCT_FROM_DATABASE=FinePix S304/3800 Zoom (DSC)
+
+usb:v04CBp011B*
+ ID_PRODUCT_FROM_DATABASE=FinePix S304/3800 Zoom (PC CAM)
+
+usb:v04CBp011C*
+ ID_PRODUCT_FROM_DATABASE=FinePix A204/2650 Zoom (DSC)
+
+usb:v04CBp011D*
+ ID_PRODUCT_FROM_DATABASE=FinePix A204/2650 Zoom (PC CAM)
+
+usb:v04CBp0120*
+ ID_PRODUCT_FROM_DATABASE=FinePix F700 Zoom (DSC)
+
+usb:v04CBp0121*
+ ID_PRODUCT_FROM_DATABASE=FinePix F700 Zoom (PC CAM)
+
+usb:v04CBp0122*
+ ID_PRODUCT_FROM_DATABASE=FinePix F410 Zoom (DSC)
+
+usb:v04CBp0123*
+ ID_PRODUCT_FROM_DATABASE=FinePix F410 Zoom (PC CAM)
+
+usb:v04CBp0124*
+ ID_PRODUCT_FROM_DATABASE=FinePix A310 Zoom (DSC)
+
+usb:v04CBp0125*
+ ID_PRODUCT_FROM_DATABASE=FinePix A310 Zoom (PC CAM)
+
+usb:v04CBp0126*
+ ID_PRODUCT_FROM_DATABASE=FinePix A210 Zoom (DSC)
+
+usb:v04CBp0127*
+ ID_PRODUCT_FROM_DATABASE=FinePix A210 Zoom (PC CAM)
+
+usb:v04CBp0128*
+ ID_PRODUCT_FROM_DATABASE=FinePix A205(S) Zoom (DSC)
+
+usb:v04CBp0129*
+ ID_PRODUCT_FROM_DATABASE=FinePix A205(S) Zoom (PC CAM)
+
+usb:v04CBp012A*
+ ID_PRODUCT_FROM_DATABASE=FinePix F610 Zoom (DSC)
+
+usb:v04CBp012B*
+ ID_PRODUCT_FROM_DATABASE=FinePix Digital Camera 030513
+
+usb:v04CBp012C*
+ ID_PRODUCT_FROM_DATABASE=FinePix S7000 Zoom (DSC)
+
+usb:v04CBp012D*
+ ID_PRODUCT_FROM_DATABASE=FinePix S7000 Zoom (PC CAM)
+
+usb:v04CBp012F*
+ ID_PRODUCT_FROM_DATABASE=FinePix Digital Camera 030731
+
+usb:v04CBp0130*
+ ID_PRODUCT_FROM_DATABASE=FinePix S5000 Zoom (DSC)
+
+usb:v04CBp0131*
+ ID_PRODUCT_FROM_DATABASE=FinePix S5000 Zoom (PC CAM)
+
+usb:v04CBp013B*
+ ID_PRODUCT_FROM_DATABASE=FinePix Digital Camera 030722
+
+usb:v04CBp013C*
+ ID_PRODUCT_FROM_DATABASE=FinePix S3000 Zoom (DSC)
+
+usb:v04CBp013D*
+ ID_PRODUCT_FROM_DATABASE=FinePix S3000 Zoom (PC CAM)
+
+usb:v04CBp013E*
+ ID_PRODUCT_FROM_DATABASE=FinePix F420 Zoom (DSC)
+
+usb:v04CBp013F*
+ ID_PRODUCT_FROM_DATABASE=FinePix F420 Zoom (PC CAM)
+
+usb:v04CBp0142*
+ ID_PRODUCT_FROM_DATABASE=FinePix S7000 Zoom (PTP)
+
+usb:v04CBp0148*
+ ID_PRODUCT_FROM_DATABASE=FinePix A330 Zoom (DSC)
+
+usb:v04CBp0149*
+ ID_PRODUCT_FROM_DATABASE=FinePix A330 Zoom (UVC)
+
+usb:v04CBp014A*
+ ID_PRODUCT_FROM_DATABASE=FinePix A330 Zoom (PTP)
+
+usb:v04CBp014B*
+ ID_PRODUCT_FROM_DATABASE=FinePix A340 Zoom (DSC)
+
+usb:v04CBp014C*
+ ID_PRODUCT_FROM_DATABASE=FinePix A340 Zoom (UVC)
+
+usb:v04CBp0159*
+ ID_PRODUCT_FROM_DATABASE=FinePix F710 Zoom (DSC)
+
+usb:v04CBp0165*
+ ID_PRODUCT_FROM_DATABASE=FinePix S3500 Zoom (DSC)
+
+usb:v04CBp0168*
+ ID_PRODUCT_FROM_DATABASE=FinePix E500 Zoom (DSC)
+
+usb:v04CBp0169*
+ ID_PRODUCT_FROM_DATABASE=FinePix E500 Zoom (UVC)
+
+usb:v04CBp016B*
+ ID_PRODUCT_FROM_DATABASE=FinePix E510 Zoom (DSC)
+
+usb:v04CBp016C*
+ ID_PRODUCT_FROM_DATABASE=FinePix E510 Zoom (PC CAM)
+
+usb:v04CBp016E*
+ ID_PRODUCT_FROM_DATABASE=FinePix S5500 Zoom (DSC)
+
+usb:v04CBp016F*
+ ID_PRODUCT_FROM_DATABASE=FinePix S5500 Zoom (UVC)
+
+usb:v04CBp0171*
+ ID_PRODUCT_FROM_DATABASE=FinePix E550 Zoom (DSC)
+
+usb:v04CBp0172*
+ ID_PRODUCT_FROM_DATABASE=FinePix E550 Zoom (UVC)
+
+usb:v04CBp0177*
+ ID_PRODUCT_FROM_DATABASE=FinePix F10 (DSC)
+
+usb:v04CBp0179*
+ ID_PRODUCT_FROM_DATABASE=Finepix F10 (PTP)
+
+usb:v04CBp0186*
+ ID_PRODUCT_FROM_DATABASE=FinePix S5200/S5600 Zoom (DSC)
+
+usb:v04CBp0188*
+ ID_PRODUCT_FROM_DATABASE=FinePix S5200/S5600 Zoom (PTP)
+
+usb:v04CBp018E*
+ ID_PRODUCT_FROM_DATABASE=FinePix S9500 Zoom (DSC)
+
+usb:v04CBp018F*
+ ID_PRODUCT_FROM_DATABASE=FinePix S9500 Zoom (PTP)
+
+usb:v04CBp0192*
+ ID_PRODUCT_FROM_DATABASE=FinePix E900 Zoom (DSC)
+
+usb:v04CBp0193*
+ ID_PRODUCT_FROM_DATABASE=FinePix E900 Zoom (PTP)
+
+usb:v04CBp019B*
+ ID_PRODUCT_FROM_DATABASE=FinePix F30 (PTP)
+
+usb:v04CBp01AF*
+ ID_PRODUCT_FROM_DATABASE=FinePix A700 (PTP)
+
+usb:v04CBp01BF*
+ ID_PRODUCT_FROM_DATABASE=FinePix F6000fd/S6500fd Zoom (PTP)
+
+usb:v04CBp01C0*
+ ID_PRODUCT_FROM_DATABASE=FinePix F20 (PTP)
+
+usb:v04CBp01C1*
+ ID_PRODUCT_FROM_DATABASE=FinePix F31fd (PTP)
+
+usb:v04CBp01C4*
+ ID_PRODUCT_FROM_DATABASE=FinePix S5700 Zoom (PTP)
+
+usb:v04CBp01C5*
+ ID_PRODUCT_FROM_DATABASE=FinePix F40fd (PTP)
+
+usb:v04CBp01C6*
+ ID_PRODUCT_FROM_DATABASE=FinePix A820 Zoom (PTP)
+
+usb:v04CBp01D2*
+ ID_PRODUCT_FROM_DATABASE=FinePix A800 Zoom (PTP)
+
+usb:v04CBp01D3*
+ ID_PRODUCT_FROM_DATABASE=FinePix A920 (PTP)
+
+usb:v04CBp01D4*
+ ID_PRODUCT_FROM_DATABASE=FinePix F50fd (PTP)
+
+usb:v04CBp01D5*
+ ID_PRODUCT_FROM_DATABASE=FinePix F47 (PTP)
+
+usb:v04CBp01F7*
+ ID_PRODUCT_FROM_DATABASE=FinePix J250 (PTP)
+
+usb:v04CBp01FD*
+ ID_PRODUCT_FROM_DATABASE=A160
+
+usb:v04CBp023E*
+ ID_PRODUCT_FROM_DATABASE=FinePix AX300
+
+usb:v04CBp0240*
+ ID_PRODUCT_FROM_DATABASE=FinePix S2950 Digital Camera
+
+usb:v04CBp0241*
+ ID_PRODUCT_FROM_DATABASE=FinePix S3200 Digital Camera
+
+usb:v04CC*
+ ID_VENDOR_FROM_DATABASE=ST-Ericsson
+
+usb:v04CCp1122*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v04CCp1520*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub (Avocent KVM)
+
+usb:v04CCp1521*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v04CCp1A62*
+ ID_PRODUCT_FROM_DATABASE=GW Instek GSP-830 Spectrum Analyzer (HID)
+
+usb:v04CCp2323*
+ ID_PRODUCT_FROM_DATABASE=Ux500 serial debug port
+
+usb:v04CCp2533*
+ ID_PRODUCT_FROM_DATABASE=NFC device (PN533)
+
+usb:v04CCp8116*
+ ID_PRODUCT_FROM_DATABASE=Camera
+
+usb:v04CD*
+ ID_VENDOR_FROM_DATABASE=Tatung Co. Of America
+
+usb:v04CE*
+ ID_VENDOR_FROM_DATABASE=ScanLogic Corp.
+
+usb:v04CEp0002*
+ ID_PRODUCT_FROM_DATABASE=SL11R-IDE IDE Bridge
+
+usb:v04CEp0100*
+ ID_PRODUCT_FROM_DATABASE=USB2PRN Printer Class
+
+usb:v04CEp0300*
+ ID_PRODUCT_FROM_DATABASE=Phantom 336CX - C3 scanner
+
+usb:v04CEp04CE*
+ ID_PRODUCT_FROM_DATABASE=SL11DEMO, VID: 0x4ce, PID: 0x4ce
+
+usb:v04CEp07D1*
+ ID_PRODUCT_FROM_DATABASE=SL11R, VID: 0x4ce, PID: 0x07D1
+
+usb:v04CF*
+ ID_VENDOR_FROM_DATABASE=Myson Century, Inc.
+
+usb:v04CFp0022*
+ ID_PRODUCT_FROM_DATABASE=OCZ Alchemy Series Elixir II Keyboard
+
+usb:v04CFp0800*
+ ID_PRODUCT_FROM_DATABASE=MTP800 Mass Storage Device
+
+usb:v04CFp8810*
+ ID_PRODUCT_FROM_DATABASE=CS8810 Mass Storage Device
+
+usb:v04CFp8811*
+ ID_PRODUCT_FROM_DATABASE=CS8811 Mass Storage Device
+
+usb:v04CFp8813*
+ ID_PRODUCT_FROM_DATABASE=CS8813 Mass Storage Device
+
+usb:v04CFp8818*
+ ID_PRODUCT_FROM_DATABASE=USB2.0 to ATAPI Bridge Controller
+
+usb:v04CFp8819*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 SD/MMC Reader
+
+usb:v04CFp9920*
+ ID_PRODUCT_FROM_DATABASE=CS8819A2-114 Mass Storage Device
+
+usb:v04D0*
+ ID_VENDOR_FROM_DATABASE=Digi International
+
+usb:v04D1*
+ ID_VENDOR_FROM_DATABASE=ITT Canon
+
+usb:v04D2*
+ ID_VENDOR_FROM_DATABASE=Altec Lansing Technologies
+
+usb:v04D2p0070*
+ ID_PRODUCT_FROM_DATABASE=ADA70 Speakers
+
+usb:v04D2p0305*
+ ID_PRODUCT_FROM_DATABASE=Non-Compliant Audio Device
+
+usb:v04D2p0311*
+ ID_PRODUCT_FROM_DATABASE=ADA-310 Speakers
+
+usb:v04D2p2060*
+ ID_PRODUCT_FROM_DATABASE=Claritel-i750 - vp
+
+usb:v04D2pFF05*
+ ID_PRODUCT_FROM_DATABASE=ADA-305 Speakers
+
+usb:v04D2pFF47*
+ ID_PRODUCT_FROM_DATABASE=Lansing HID Audio Controls
+
+usb:v04D2pFF49*
+ ID_PRODUCT_FROM_DATABASE=Lansing HID Audio Controls
+
+usb:v04D3*
+ ID_VENDOR_FROM_DATABASE=VidUS, Inc.
+
+usb:v04D4*
+ ID_VENDOR_FROM_DATABASE=LSI Logic, Inc.
+
+usb:v04D5*
+ ID_VENDOR_FROM_DATABASE=Forte Technologies, Inc.
+
+usb:v04D6*
+ ID_VENDOR_FROM_DATABASE=Mentor Graphics
+
+usb:v04D7*
+ ID_VENDOR_FROM_DATABASE=Oki Semiconductor
+
+usb:v04D7p1BE4*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v04D8*
+ ID_VENDOR_FROM_DATABASE=Microchip Technology, Inc.
+
+usb:v04D8p0002*
+ ID_PRODUCT_FROM_DATABASE=PicoLCD 20x2
+
+usb:v04D8p0003*
+ ID_PRODUCT_FROM_DATABASE=PICkit 2 Microcontroller Programmer
+
+usb:v04D8p000A*
+ ID_PRODUCT_FROM_DATABASE=CDC RS-232 Emulation Demo
+
+usb:v04D8p000B*
+ ID_PRODUCT_FROM_DATABASE=PIC18F2550 (32K Flashable 10 Channel, 10 Bit A/D USB Microcontroller)
+
+usb:v04D8p0032*
+ ID_PRODUCT_FROM_DATABASE=PICkit1
+
+usb:v04D8p0033*
+ ID_PRODUCT_FROM_DATABASE=PICkit2
+
+usb:v04D8p0036*
+ ID_PRODUCT_FROM_DATABASE=PICkit Serial Analyzer
+
+usb:v04D8p00E0*
+ ID_PRODUCT_FROM_DATABASE=PIC32 Starter Board
+
+usb:v04D8p0A04*
+ ID_PRODUCT_FROM_DATABASE=AGP LIN Serial Analyzer
+
+usb:v04D8p8000*
+ ID_PRODUCT_FROM_DATABASE=In-Circuit Debugger
+
+usb:v04D8p8001*
+ ID_PRODUCT_FROM_DATABASE=ICD2 in-circuit debugger
+
+usb:v04D8p8101*
+ ID_PRODUCT_FROM_DATABASE=PIC24F Starter Kit
+
+usb:v04D8p8107*
+ ID_PRODUCT_FROM_DATABASE=Microstick II
+
+usb:v04D8p900A*
+ ID_PRODUCT_FROM_DATABASE=PICkit3
+
+usb:v04D8pC001*
+ ID_PRODUCT_FROM_DATABASE=PicoLCD 20x4
+
+usb:v04D8pF8DA*
+ ID_PRODUCT_FROM_DATABASE=Hughski Ltd. ColorHug
+
+usb:v04D8pFBBA*
+ ID_PRODUCT_FROM_DATABASE=DiscFerret Magnetic Disc Analyser (bootloader mode)
+
+usb:v04D8pFBBB*
+ ID_PRODUCT_FROM_DATABASE=DiscFerret Magnetic Disc Analyser (active mode)
+
+usb:v04D8pFC92*
+ ID_PRODUCT_FROM_DATABASE=Open Bench Logic Sniffer
+
+usb:v04D8pFFEF*
+ ID_PRODUCT_FROM_DATABASE=PICoPLC [APStech]
+
+usb:v04D9*
+ ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc.
+
+usb:v04D9p0022*
+ ID_PRODUCT_FROM_DATABASE=Portable Keyboard
+
+usb:v04D9p048E*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v04D9p0499*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v04D9p1203*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v04D9p1400*
+ ID_PRODUCT_FROM_DATABASE=PS/2 keyboard + mouse controller
+
+usb:v04D9p1503*
+ ID_PRODUCT_FROM_DATABASE=Shortboard Lefty
+
+usb:v04D9p1603*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v04D9p2013*
+ ID_PRODUCT_FROM_DATABASE=Keyboard [Das Keyboard]
+
+usb:v04D9p2221*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v04D9pA055*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v04DA*
+ ID_VENDOR_FROM_DATABASE=Panasonic (Matsushita)
+
+usb:v04DAp0901*
+ ID_PRODUCT_FROM_DATABASE=LS-120 Camera
+
+usb:v04DAp0912*
+ ID_PRODUCT_FROM_DATABASE=SDR-S10
+
+usb:v04DAp0B01*
+ ID_PRODUCT_FROM_DATABASE=CD-R/RW Drive
+
+usb:v04DAp0B03*
+ ID_PRODUCT_FROM_DATABASE=SuperDisk 240MB
+
+usb:v04DAp0D01*
+ ID_PRODUCT_FROM_DATABASE=CD-R Drive KXL-840AN
+
+usb:v04DAp0D09*
+ ID_PRODUCT_FROM_DATABASE=CD-R Drive KXL-RW32AN
+
+usb:v04DAp0D0A*
+ ID_PRODUCT_FROM_DATABASE=CD-R Drive KXL-CB20AN
+
+usb:v04DAp0D0D*
+ ID_PRODUCT_FROM_DATABASE=CDRCB03
+
+usb:v04DAp0D0E*
+ ID_PRODUCT_FROM_DATABASE=DVD-ROM & CD-R/RW
+
+usb:v04DAp0F40*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04DAp104D*
+ ID_PRODUCT_FROM_DATABASE=Elite Panaboard UB-T880 (HID)
+
+usb:v04DAp104E*
+ ID_PRODUCT_FROM_DATABASE=Elite Panaboard Pen Adaptor (HID)
+
+usb:v04DAp1500*
+ ID_PRODUCT_FROM_DATABASE=MFSUSB Driver
+
+usb:v04DAp1800*
+ ID_PRODUCT_FROM_DATABASE=DY-WL10 802.11abgn Adapter [Broadcom BCM4323]
+
+usb:v04DAp1B00*
+ ID_PRODUCT_FROM_DATABASE=MultiMediaCard
+
+usb:v04DAp2121*
+ ID_PRODUCT_FROM_DATABASE=EB-VS6
+
+usb:v04DAp2316*
+ ID_PRODUCT_FROM_DATABASE=DVC Mass Storage Device
+
+usb:v04DAp2317*
+ ID_PRODUCT_FROM_DATABASE=DVC USB-SERIAL Driver for WinXP
+
+usb:v04DAp2318*
+ ID_PRODUCT_FROM_DATABASE=NV-GS11/230/250 (webcam mode)
+
+usb:v04DAp2319*
+ ID_PRODUCT_FROM_DATABASE=NV-GS15 (webcam mode)
+
+usb:v04DAp231A*
+ ID_PRODUCT_FROM_DATABASE=NV-GS11/230/250 (DV mode)
+
+usb:v04DAp231D*
+ ID_PRODUCT_FROM_DATABASE=DVC Web Camera Device
+
+usb:v04DAp231E*
+ ID_PRODUCT_FROM_DATABASE=DVC DV Stream Device
+
+usb:v04DAp2372*
+ ID_PRODUCT_FROM_DATABASE=Lumix Camera
+
+usb:v04DAp2374*
+ ID_PRODUCT_FROM_DATABASE=DMC-FZ18/FZ20
+
+usb:v04DAp2451*
+ ID_PRODUCT_FROM_DATABASE=HDC-SD9
+
+usb:v04DAp2497*
+ ID_PRODUCT_FROM_DATABASE=HDC-TM700
+
+usb:v04DAp250C*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v04DAp250D*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v04DAp3904*
+ ID_PRODUCT_FROM_DATABASE=N5HBZ0000055 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]
+
+usb:v04DAp3C04*
+ ID_PRODUCT_FROM_DATABASE=JT-P100MR-20 [ePassport Reader]
+
+usb:v04DB*
+ ID_VENDOR_FROM_DATABASE=Hypertec Pty, Ltd
+
+usb:v04DC*
+ ID_VENDOR_FROM_DATABASE=Huan Hsin Holdings, Ltd
+
+usb:v04DD*
+ ID_VENDOR_FROM_DATABASE=Sharp Corp.
+
+usb:v04DDp13A6*
+ ID_PRODUCT_FROM_DATABASE=MFC2000
+
+usb:v04DDp6006*
+ ID_PRODUCT_FROM_DATABASE=AL-1216
+
+usb:v04DDp6007*
+ ID_PRODUCT_FROM_DATABASE=AL-1045
+
+usb:v04DDp6008*
+ ID_PRODUCT_FROM_DATABASE=AL-1255
+
+usb:v04DDp6009*
+ ID_PRODUCT_FROM_DATABASE=AL-1530CS
+
+usb:v04DDp600A*
+ ID_PRODUCT_FROM_DATABASE=AL-1540CS
+
+usb:v04DDp600B*
+ ID_PRODUCT_FROM_DATABASE=AL-1456
+
+usb:v04DDp600C*
+ ID_PRODUCT_FROM_DATABASE=AL-1555
+
+usb:v04DDp600D*
+ ID_PRODUCT_FROM_DATABASE=AL-1225
+
+usb:v04DDp600E*
+ ID_PRODUCT_FROM_DATABASE=AL-1551CS
+
+usb:v04DDp600F*
+ ID_PRODUCT_FROM_DATABASE=AR-122E
+
+usb:v04DDp6010*
+ ID_PRODUCT_FROM_DATABASE=AR-152E
+
+usb:v04DDp6011*
+ ID_PRODUCT_FROM_DATABASE=AR-157E
+
+usb:v04DDp6012*
+ ID_PRODUCT_FROM_DATABASE=SN-1045
+
+usb:v04DDp6013*
+ ID_PRODUCT_FROM_DATABASE=SN-1255
+
+usb:v04DDp6014*
+ ID_PRODUCT_FROM_DATABASE=SN-1456
+
+usb:v04DDp6015*
+ ID_PRODUCT_FROM_DATABASE=SN-1555
+
+usb:v04DDp6016*
+ ID_PRODUCT_FROM_DATABASE=AR-153E
+
+usb:v04DDp6017*
+ ID_PRODUCT_FROM_DATABASE=AR-122E N
+
+usb:v04DDp6018*
+ ID_PRODUCT_FROM_DATABASE=AR-153E N
+
+usb:v04DDp6019*
+ ID_PRODUCT_FROM_DATABASE=AR-152E N
+
+usb:v04DDp601A*
+ ID_PRODUCT_FROM_DATABASE=AR-157E N
+
+usb:v04DDp601B*
+ ID_PRODUCT_FROM_DATABASE=AL-1217
+
+usb:v04DDp601C*
+ ID_PRODUCT_FROM_DATABASE=AL-1226
+
+usb:v04DDp601D*
+ ID_PRODUCT_FROM_DATABASE=AR-123E
+
+usb:v04DDp6021*
+ ID_PRODUCT_FROM_DATABASE=IS01
+
+usb:v04DDp7002*
+ ID_PRODUCT_FROM_DATABASE=DVC Ver.1.0
+
+usb:v04DDp7004*
+ ID_PRODUCT_FROM_DATABASE=VE-CG40U Digital Still Camera
+
+usb:v04DDp7005*
+ ID_PRODUCT_FROM_DATABASE=VE-CG30 Digital Still Camera
+
+usb:v04DDp7007*
+ ID_PRODUCT_FROM_DATABASE=VL-Z7S Digital Camcorder
+
+usb:v04DDp8004*
+ ID_PRODUCT_FROM_DATABASE=Zaurus SL-5000D/SL-5500 PDA
+
+usb:v04DDp8005*
+ ID_PRODUCT_FROM_DATABASE=Zaurus A-300
+
+usb:v04DDp8006*
+ ID_PRODUCT_FROM_DATABASE=Zaurus SL-B500/SL-5600 PDA
+
+usb:v04DDp8007*
+ ID_PRODUCT_FROM_DATABASE=Zaurus C-700 PDA
+
+usb:v04DDp9009*
+ ID_PRODUCT_FROM_DATABASE=AR-M160
+
+usb:v04DDp9014*
+ ID_PRODUCT_FROM_DATABASE=IM-DR80 Portable NetMD Player
+
+usb:v04DDp9031*
+ ID_PRODUCT_FROM_DATABASE=Zaurus C-750/C-760/C-860/SL-C3000 PDA
+
+usb:v04DDp9032*
+ ID_PRODUCT_FROM_DATABASE=Zaurus SL-6000
+
+usb:v04DDp903A*
+ ID_PRODUCT_FROM_DATABASE=GSM GPRS
+
+usb:v04DDp9050*
+ ID_PRODUCT_FROM_DATABASE=Zaurus C-860 PDA
+
+usb:v04DDp9056*
+ ID_PRODUCT_FROM_DATABASE=Viewcam Z
+
+usb:v04DDp9073*
+ ID_PRODUCT_FROM_DATABASE=AM-900
+
+usb:v04DDp9074*
+ ID_PRODUCT_FROM_DATABASE=GSM GPRS
+
+usb:v04DDp90A9*
+ ID_PRODUCT_FROM_DATABASE=Sharp Composite
+
+usb:v04DDp90D0*
+ ID_PRODUCT_FROM_DATABASE=USB-to-Serial Comm. Port
+
+usb:v04DDp90F2*
+ ID_PRODUCT_FROM_DATABASE=Sharp 3G GSM USB Control
+
+usb:v04DDp9120*
+ ID_PRODUCT_FROM_DATABASE=WS004SH
+
+usb:v04DDp9122*
+ ID_PRODUCT_FROM_DATABASE=WS007SH
+
+usb:v04DDp9123*
+ ID_PRODUCT_FROM_DATABASE=W-ZERO3 ES Smartphone
+
+usb:v04DDp91A3*
+ ID_PRODUCT_FROM_DATABASE=922SH Internet Machine
+
+usb:v04DDp939A*
+ ID_PRODUCT_FROM_DATABASE=IS03
+
+usb:v04DE*
+ ID_VENDOR_FROM_DATABASE=MindShare, Inc.
+
+usb:v04DF*
+ ID_VENDOR_FROM_DATABASE=Interlink Electronics
+
+usb:v04E1*
+ ID_VENDOR_FROM_DATABASE=Iiyama North America, Inc.
+
+usb:v04E1p0201*
+ ID_PRODUCT_FROM_DATABASE=Monitor Hub
+
+usb:v04E2*
+ ID_VENDOR_FROM_DATABASE=Exar Corp.
+
+usb:v04E3*
+ ID_VENDOR_FROM_DATABASE=Zilog, Inc.
+
+usb:v04E4*
+ ID_VENDOR_FROM_DATABASE=ACC Microelectronics
+
+usb:v04E5*
+ ID_VENDOR_FROM_DATABASE=Promise Technology
+
+usb:v04E6*
+ ID_VENDOR_FROM_DATABASE=SCM Microsystems, Inc.
+
+usb:v04E6p0001*
+ ID_PRODUCT_FROM_DATABASE=E-USB ATA Bridge
+
+usb:v04E6p0002*
+ ID_PRODUCT_FROM_DATABASE=eUSCSI SCSI Bridge
+
+usb:v04E6p0003*
+ ID_PRODUCT_FROM_DATABASE=eUSB SmartMedia Card Reader
+
+usb:v04E6p0005*
+ ID_PRODUCT_FROM_DATABASE=eUSB SmartMedia/CompactFlash Card Reader
+
+usb:v04E6p0006*
+ ID_PRODUCT_FROM_DATABASE=eUSB SmartMedia Card Reader
+
+usb:v04E6p0007*
+ ID_PRODUCT_FROM_DATABASE=Hifd
+
+usb:v04E6p0009*
+ ID_PRODUCT_FROM_DATABASE=eUSB ATA/ATAPI Adapter
+
+usb:v04E6p000A*
+ ID_PRODUCT_FROM_DATABASE=eUSB CompactFlash Adapter
+
+usb:v04E6p000B*
+ ID_PRODUCT_FROM_DATABASE=eUSCSI Bridge
+
+usb:v04E6p000C*
+ ID_PRODUCT_FROM_DATABASE=eUSCSI Bridge
+
+usb:v04E6p000D*
+ ID_PRODUCT_FROM_DATABASE=Dazzle MS
+
+usb:v04E6p0012*
+ ID_PRODUCT_FROM_DATABASE=Dazzle SD/MMC
+
+usb:v04E6p0101*
+ ID_PRODUCT_FROM_DATABASE=eUSB ATA Bridge (Sony Spressa USB CDRW)
+
+usb:v04E6p0311*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DM-CF
+
+usb:v04E6p0312*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DM-SD/MMC
+
+usb:v04E6p0313*
+ ID_PRODUCT_FROM_DATABASE=Dazzle SM
+
+usb:v04E6p0314*
+ ID_PRODUCT_FROM_DATABASE=Dazzle MS
+
+usb:v04E6p0322*
+ ID_PRODUCT_FROM_DATABASE=e-Film Reader-5
+
+usb:v04E6p0325*
+ ID_PRODUCT_FROM_DATABASE=eUSB ORCA Quad Reader
+
+usb:v04E6p0327*
+ ID_PRODUCT_FROM_DATABASE=Digital Media Reader
+
+usb:v04E6p03FE*
+ ID_PRODUCT_FROM_DATABASE=DMHS2 DFU Adapter
+
+usb:v04E6p0406*
+ ID_PRODUCT_FROM_DATABASE=eUSB SmartDM Reader
+
+usb:v04E6p04E6*
+ ID_PRODUCT_FROM_DATABASE=eUSB DFU Adapter
+
+usb:v04E6p04E7*
+ ID_PRODUCT_FROM_DATABASE=STCII DFU Adapter
+
+usb:v04E6p04E8*
+ ID_PRODUCT_FROM_DATABASE=eUSBDM DFU Adapter
+
+usb:v04E6p04E9*
+ ID_PRODUCT_FROM_DATABASE=DM-E DFU Adapter
+
+usb:v04E6p0500*
+ ID_PRODUCT_FROM_DATABASE=Veridicom 5thSense Fingerprint Sensor and eUSB SmartCard
+
+usb:v04E6p0701*
+ ID_PRODUCT_FROM_DATABASE=DCS200 Loader Device
+
+usb:v04E6p0702*
+ ID_PRODUCT_FROM_DATABASE=DVD Creation Station 200
+
+usb:v04E6p0703*
+ ID_PRODUCT_FROM_DATABASE=DVC100 Loader Device
+
+usb:v04E6p0704*
+ ID_PRODUCT_FROM_DATABASE=Digital Video Creator 100
+
+usb:v04E6p1001*
+ ID_PRODUCT_FROM_DATABASE=SCR300 Smart Card Reader
+
+usb:v04E6p1010*
+ ID_PRODUCT_FROM_DATABASE=USBAT-2 CompactFlash Card Reader
+
+usb:v04E6p1014*
+ ID_PRODUCT_FROM_DATABASE=e-Film Reader-3
+
+usb:v04E6p1020*
+ ID_PRODUCT_FROM_DATABASE=USBAT ATA/ATAPI Adapter
+
+usb:v04E6p2007*
+ ID_PRODUCT_FROM_DATABASE=RSA SecurID ComboReader
+
+usb:v04E6p2009*
+ ID_PRODUCT_FROM_DATABASE=Citibank Smart Card Reader
+
+usb:v04E6p200A*
+ ID_PRODUCT_FROM_DATABASE=Reflex v.2 Smart Card Reader
+
+usb:v04E6p200D*
+ ID_PRODUCT_FROM_DATABASE=STR391 Reader
+
+usb:v04E6p5111*
+ ID_PRODUCT_FROM_DATABASE=SCR331-DI SmartCard Reader
+
+usb:v04E6p5113*
+ ID_PRODUCT_FROM_DATABASE=SCR333 SmartCard Reader
+
+usb:v04E6p5114*
+ ID_PRODUCT_FROM_DATABASE=SCR331-DI SmartCard Reader
+
+usb:v04E6p5115*
+ ID_PRODUCT_FROM_DATABASE=SCR335 SmartCard Reader
+
+usb:v04E6p5116*
+ ID_PRODUCT_FROM_DATABASE=SCR331-LC1 / SCR3310 SmartCard Reader
+
+usb:v04E6p5117*
+ ID_PRODUCT_FROM_DATABASE=SCR3320 - Smart Card Reader
+
+usb:v04E6p5118*
+ ID_PRODUCT_FROM_DATABASE=Expresscard SIM Card Reader
+
+usb:v04E6p5119*
+ ID_PRODUCT_FROM_DATABASE=SCR3340 - ExpressCard54 Smart Card Reader
+
+usb:v04E6p511B*
+ ID_PRODUCT_FROM_DATABASE=SmartCard Reader
+
+usb:v04E6p511D*
+ ID_PRODUCT_FROM_DATABASE=SCR3311 Smart Card Reader
+
+usb:v04E6p5120*
+ ID_PRODUCT_FROM_DATABASE=SCR331-DI SmartCard Reader
+
+usb:v04E6p5121*
+ ID_PRODUCT_FROM_DATABASE=SDI010 Smart Card Reader
+
+usb:v04E6p5151*
+ ID_PRODUCT_FROM_DATABASE=SCR338 Keyboard Smart Card Reader
+
+usb:v04E6p5292*
+ ID_PRODUCT_FROM_DATABASE=SCL011 RFID reader
+
+usb:v04E6p5410*
+ ID_PRODUCT_FROM_DATABASE=SCR35xx Smart Card Reader
+
+usb:v04E6pE000*
+ ID_PRODUCT_FROM_DATABASE=SCRx31 Reader
+
+usb:v04E6pE001*
+ ID_PRODUCT_FROM_DATABASE=SCR331 SmartCard Reader
+
+usb:v04E6pE003*
+ ID_PRODUCT_FROM_DATABASE=SPR532 PinPad SmartCard Reader
+
+usb:v04E7*
+ ID_VENDOR_FROM_DATABASE=Elo TouchSystems
+
+usb:v04E7p0001*
+ ID_PRODUCT_FROM_DATABASE=TouchScreen
+
+usb:v04E7p0002*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface 2600 Rev 2
+
+usb:v04E7p0004*
+ ID_PRODUCT_FROM_DATABASE=4000U CarrollTouch® Touchmonitor Interface
+
+usb:v04E7p0007*
+ ID_PRODUCT_FROM_DATABASE=2500U IntelliTouch® Touchmonitor Interface
+
+usb:v04E7p0008*
+ ID_PRODUCT_FROM_DATABASE=3000U AccuTouch® Touchmonitor Interface
+
+usb:v04E7p0009*
+ ID_PRODUCT_FROM_DATABASE=4000U CarrollTouch® Touchmonitor Interface
+
+usb:v04E7p0020*
+ ID_PRODUCT_FROM_DATABASE=Touchscreen Interface (2700)
+
+usb:v04E7p0021*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E7p0030*
+ ID_PRODUCT_FROM_DATABASE=4500U CarrollTouch® Touchmonitor Interface
+
+usb:v04E7p0032*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E7p0033*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E7p0041*
+ ID_PRODUCT_FROM_DATABASE=5010 Surface Capacitive Touchmonitor Interface
+
+usb:v04E7p0042*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E7p0050*
+ ID_PRODUCT_FROM_DATABASE=2216 AccuTouch® Touchmonitor Interface
+
+usb:v04E7p0071*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E7p0072*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E7p0081*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E7p0082*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E7p00FF*
+ ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface
+
+usb:v04E8*
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics Co., Ltd
+
+usb:v04E8p0100*
+ ID_PRODUCT_FROM_DATABASE=Kingston Flash Drive (128MB)
+
+usb:v04E8p0110*
+ ID_PRODUCT_FROM_DATABASE=Connect3D Flash Drive
+
+usb:v04E8p0111*
+ ID_PRODUCT_FROM_DATABASE=Connect3D Flash Drive
+
+usb:v04E8p1003*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player and Recorder
+
+usb:v04E8p1006*
+ ID_PRODUCT_FROM_DATABASE=SDC-200Z
+
+usb:v04E8p130C*
+ ID_PRODUCT_FROM_DATABASE=NX100
+
+usb:v04E8p1F06*
+ ID_PRODUCT_FROM_DATABASE=HX-MU064DA portable harddisk
+
+usb:v04E8p2018*
+ ID_PRODUCT_FROM_DATABASE=WIS09ABGN LinkStick Wireless LAN Adapter
+
+usb:v04E8p2035*
+ ID_PRODUCT_FROM_DATABASE=Digital Photo Frame Mass Storage
+
+usb:v04E8p2036*
+ ID_PRODUCT_FROM_DATABASE=Digital Photo Frame Mini Monitor
+
+usb:v04E8p3004*
+ ID_PRODUCT_FROM_DATABASE=ML-4600
+
+usb:v04E8p3005*
+ ID_PRODUCT_FROM_DATABASE=Docuprint P1210
+
+usb:v04E8p3008*
+ ID_PRODUCT_FROM_DATABASE=ML-6060 laser printer
+
+usb:v04E8p300C*
+ ID_PRODUCT_FROM_DATABASE=ML-1210 Printer
+
+usb:v04E8p300E*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p3104*
+ ID_PRODUCT_FROM_DATABASE=ML-3550N
+
+usb:v04E8p3210*
+ ID_PRODUCT_FROM_DATABASE=ML-5200A Laser Printer
+
+usb:v04E8p3226*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p3228*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p322A*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p322C*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p3230*
+ ID_PRODUCT_FROM_DATABASE=ML-1440
+
+usb:v04E8p3232*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p3236*
+ ID_PRODUCT_FROM_DATABASE=ML-1450
+
+usb:v04E8p3238*
+ ID_PRODUCT_FROM_DATABASE=ML-1430
+
+usb:v04E8p323A*
+ ID_PRODUCT_FROM_DATABASE=ML-1710 Printer
+
+usb:v04E8p323B*
+ ID_PRODUCT_FROM_DATABASE=Phaser 3130
+
+usb:v04E8p323C*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p323D*
+ ID_PRODUCT_FROM_DATABASE=Phaser 3120
+
+usb:v04E8p323E*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p3240*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p3242*
+ ID_PRODUCT_FROM_DATABASE=ML-1510 Laser Printer
+
+usb:v04E8p3248*
+ ID_PRODUCT_FROM_DATABASE=Color Laser Printer
+
+usb:v04E8p324A*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v04E8p324C*
+ ID_PRODUCT_FROM_DATABASE=ML-1740 Printer
+
+usb:v04E8p324D*
+ ID_PRODUCT_FROM_DATABASE=Phaser 3121
+
+usb:v04E8p3256*
+ ID_PRODUCT_FROM_DATABASE=ML-1520 Laser Printer
+
+usb:v04E8p325B*
+ ID_PRODUCT_FROM_DATABASE=Xerox Phaser 3117 Laser Printer
+
+usb:v04E8p325F*
+ ID_PRODUCT_FROM_DATABASE=Phaser 3425 Laser Printer
+
+usb:v04E8p3260*
+ ID_PRODUCT_FROM_DATABASE=CLP-510 Color Laser Printer
+
+usb:v04E8p3268*
+ ID_PRODUCT_FROM_DATABASE=ML-1610 Mono Laser Printer
+
+usb:v04E8p326C*
+ ID_PRODUCT_FROM_DATABASE=ML-2010P Mono Laser Printer
+
+usb:v04E8p3276*
+ ID_PRODUCT_FROM_DATABASE=ML-3050/ML-3051 Laser Printer
+
+usb:v04E8p328E*
+ ID_PRODUCT_FROM_DATABASE=CLP-310 Color Laser Printer
+
+usb:v04E8p3292*
+ ID_PRODUCT_FROM_DATABASE=ML-1640 Series Laser Printer
+
+usb:v04E8p3296*
+ ID_PRODUCT_FROM_DATABASE=ML-2580N Mono Laser Printer
+
+usb:v04E8p3297*
+ ID_PRODUCT_FROM_DATABASE=ML-191x/ML-252x Laser Printer
+
+usb:v04E8p330C*
+ ID_PRODUCT_FROM_DATABASE=ML-1865
+
+usb:v04E8p3310*
+ ID_PRODUCT_FROM_DATABASE=ML-331x Series Laser Printer
+
+usb:v04E8p3315*
+ ID_PRODUCT_FROM_DATABASE=ML-2540 Series Laser Printer
+
+usb:v04E8p3409*
+ ID_PRODUCT_FROM_DATABASE=SCX-4216F Scanner
+
+usb:v04E8p340C*
+ ID_PRODUCT_FROM_DATABASE=SCX-5x15 series
+
+usb:v04E8p340D*
+ ID_PRODUCT_FROM_DATABASE=SCX-6x20 series
+
+usb:v04E8p340E*
+ ID_PRODUCT_FROM_DATABASE=MFP 560 series
+
+usb:v04E8p340F*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v04E8p3412*
+ ID_PRODUCT_FROM_DATABASE=SCX-4x20 series
+
+usb:v04E8p3413*
+ ID_PRODUCT_FROM_DATABASE=SCX-4100 Scanner
+
+usb:v04E8p3415*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04E8p3419*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04E8p341A*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v04E8p341B*
+ ID_PRODUCT_FROM_DATABASE=SCX-4200 series
+
+usb:v04E8p341C*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04E8p341D*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04E8p341F*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04E8p3420*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04E8p3426*
+ ID_PRODUCT_FROM_DATABASE=SCX-4500 Laser Printer
+
+usb:v04E8p3605*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v04E8p3606*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v04E8p3609*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v04E8p3902*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v04E8p3903*
+ ID_PRODUCT_FROM_DATABASE=Xerox WorkCentre XK50cx
+
+usb:v04E8p390F*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v04E8p3911*
+ ID_PRODUCT_FROM_DATABASE=SCX-1020 series
+
+usb:v04E8p4005*
+ ID_PRODUCT_FROM_DATABASE=GT-S8000 Jet (msc)
+
+usb:v04E8p4F1F*
+ ID_PRODUCT_FROM_DATABASE=GT-S8000 Jet (mtp)
+
+usb:v04E8p5000*
+ ID_PRODUCT_FROM_DATABASE=YP-MF series
+
+usb:v04E8p5001*
+ ID_PRODUCT_FROM_DATABASE=YP-100
+
+usb:v04E8p5002*
+ ID_PRODUCT_FROM_DATABASE=YP-30
+
+usb:v04E8p5003*
+ ID_PRODUCT_FROM_DATABASE=YP-700
+
+usb:v04E8p5004*
+ ID_PRODUCT_FROM_DATABASE=YP-30
+
+usb:v04E8p5005*
+ ID_PRODUCT_FROM_DATABASE=YP-300
+
+usb:v04E8p5006*
+ ID_PRODUCT_FROM_DATABASE=YP-750
+
+usb:v04E8p500D*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v04E8p5010*
+ ID_PRODUCT_FROM_DATABASE=Yepp YP-35
+
+usb:v04E8p5011*
+ ID_PRODUCT_FROM_DATABASE=YP-780
+
+usb:v04E8p5013*
+ ID_PRODUCT_FROM_DATABASE=YP-60
+
+usb:v04E8p5015*
+ ID_PRODUCT_FROM_DATABASE=yepp upgrade
+
+usb:v04E8p501B*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v04E8p5021*
+ ID_PRODUCT_FROM_DATABASE=Yepp YP-ST5
+
+usb:v04E8p5026*
+ ID_PRODUCT_FROM_DATABASE=YP-MT6V
+
+usb:v04E8p5027*
+ ID_PRODUCT_FROM_DATABASE=YP-T7
+
+usb:v04E8p502B*
+ ID_PRODUCT_FROM_DATABASE=YP-F1
+
+usb:v04E8p5032*
+ ID_PRODUCT_FROM_DATABASE=YP-J70
+
+usb:v04E8p503B*
+ ID_PRODUCT_FROM_DATABASE=YP-U1 MP3 Player
+
+usb:v04E8p503D*
+ ID_PRODUCT_FROM_DATABASE=YP-T7F
+
+usb:v04E8p5041*
+ ID_PRODUCT_FROM_DATABASE=YP-Z5
+
+usb:v04E8p5050*
+ ID_PRODUCT_FROM_DATABASE=YP-U2 MP3 Player
+
+usb:v04E8p5051*
+ ID_PRODUCT_FROM_DATABASE=YP-F2R
+
+usb:v04E8p5055*
+ ID_PRODUCT_FROM_DATABASE=YP-T9
+
+usb:v04E8p507D*
+ ID_PRODUCT_FROM_DATABASE=YP-U3 (mtp)
+
+usb:v04E8p507F*
+ ID_PRODUCT_FROM_DATABASE=YP-T9J
+
+usb:v04E8p5080*
+ ID_PRODUCT_FROM_DATABASE=Yepp YP-K3 (msc)
+
+usb:v04E8p5081*
+ ID_PRODUCT_FROM_DATABASE=Yepp YP-K3 (mtp)
+
+usb:v04E8p5082*
+ ID_PRODUCT_FROM_DATABASE=YP-P2 (msc)
+
+usb:v04E8p5083*
+ ID_PRODUCT_FROM_DATABASE=YP-P2 (mtp)
+
+usb:v04E8p508A*
+ ID_PRODUCT_FROM_DATABASE=YP-T10
+
+usb:v04E8p508B*
+ ID_PRODUCT_FROM_DATABASE=YP-S5 MP3 Player
+
+usb:v04E8p508C*
+ ID_PRODUCT_FROM_DATABASE=YP-S5
+
+usb:v04E8p5090*
+ ID_PRODUCT_FROM_DATABASE=YP-S3 (msc)
+
+usb:v04E8p5091*
+ ID_PRODUCT_FROM_DATABASE=YP-S3 (mtp)
+
+usb:v04E8p5092*
+ ID_PRODUCT_FROM_DATABASE=YP-U4 (msc)
+
+usb:v04E8p5093*
+ ID_PRODUCT_FROM_DATABASE=YP-U4 (mtp)
+
+usb:v04E8p5095*
+ ID_PRODUCT_FROM_DATABASE=YP-S2
+
+usb:v04E8p510F*
+ ID_PRODUCT_FROM_DATABASE=YP-R1
+
+usb:v04E8p5119*
+ ID_PRODUCT_FROM_DATABASE=Yepp YP-P3
+
+usb:v04E8p511C*
+ ID_PRODUCT_FROM_DATABASE=YP-Q2
+
+usb:v04E8p5121*
+ ID_PRODUCT_FROM_DATABASE=YP-U5
+
+usb:v04E8p5123*
+ ID_PRODUCT_FROM_DATABASE=Yepp YP-M1
+
+usb:v04E8p5A00*
+ ID_PRODUCT_FROM_DATABASE=YP-NEU
+
+usb:v04E8p5A01*
+ ID_PRODUCT_FROM_DATABASE=YP-NDU
+
+usb:v04E8p5A03*
+ ID_PRODUCT_FROM_DATABASE=Yepp MP3 Player
+
+usb:v04E8p5A04*
+ ID_PRODUCT_FROM_DATABASE=YP-800
+
+usb:v04E8p5A08*
+ ID_PRODUCT_FROM_DATABASE=YP-90
+
+usb:v04E8p5A0F*
+ ID_PRODUCT_FROM_DATABASE=Meizu M6 MiniPlayer
+
+usb:v04E8p5B01*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v04E8p5B02*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v04E8p5B03*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v04E8p5B04*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v04E8p5B05*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v04E8p5B11*
+ ID_PRODUCT_FROM_DATABASE=SEW-2001u Card
+
+usb:v04E8p5F00*
+ ID_PRODUCT_FROM_DATABASE=NEXiO Sync
+
+usb:v04E8p5F01*
+ ID_PRODUCT_FROM_DATABASE=NEXiO Sync
+
+usb:v04E8p5F02*
+ ID_PRODUCT_FROM_DATABASE=NEXiO Sync
+
+usb:v04E8p5F03*
+ ID_PRODUCT_FROM_DATABASE=NEXiO Sync
+
+usb:v04E8p5F04*
+ ID_PRODUCT_FROM_DATABASE=NEXiO Sync
+
+usb:v04E8p5F05*
+ ID_PRODUCT_FROM_DATABASE=STORY Station 1TB
+
+usb:v04E8p6032*
+ ID_PRODUCT_FROM_DATABASE=G2 Portable hard drive
+
+usb:v04E8p60B3*
+ ID_PRODUCT_FROM_DATABASE=M2 Portable Hard Drive
+
+usb:v04E8p60C4*
+ ID_PRODUCT_FROM_DATABASE=M2 Portable Hard Drive USB 3.0
+
+usb:v04E8p6601*
+ ID_PRODUCT_FROM_DATABASE=Mobile Phone
+
+usb:v04E8p6602*
+ ID_PRODUCT_FROM_DATABASE=Galaxy
+
+usb:v04E8p6603*
+ ID_PRODUCT_FROM_DATABASE=Galaxy
+
+usb:v04E8p6611*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p6613*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p6615*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p6617*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p6619*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p661B*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p661E*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v04E8p6620*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v04E8p6622*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v04E8p6624*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v04E8p662E*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p6630*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p6632*
+ ID_PRODUCT_FROM_DATABASE=MITs Sync
+
+usb:v04E8p663E*
+ ID_PRODUCT_FROM_DATABASE=D900e Phone
+
+usb:v04E8p663F*
+ ID_PRODUCT_FROM_DATABASE=SGH-E720/SGH-E840
+
+usb:v04E8p6640*
+ ID_PRODUCT_FROM_DATABASE=Usb Modem Enumerator
+
+usb:v04E8p6702*
+ ID_PRODUCT_FROM_DATABASE=X830
+
+usb:v04E8p6708*
+ ID_PRODUCT_FROM_DATABASE=U600 Phone
+
+usb:v04E8p6709*
+ ID_PRODUCT_FROM_DATABASE=U600
+
+usb:v04E8p6734*
+ ID_PRODUCT_FROM_DATABASE=Juke
+
+usb:v04E8p6759*
+ ID_PRODUCT_FROM_DATABASE=D900e Media Player
+
+usb:v04E8p675A*
+ ID_PRODUCT_FROM_DATABASE=D900e Mass Storage
+
+usb:v04E8p675B*
+ ID_PRODUCT_FROM_DATABASE=D900e Camera
+
+usb:v04E8p6772*
+ ID_PRODUCT_FROM_DATABASE=Standalone LTE device (Trial)
+
+usb:v04E8p6795*
+ ID_PRODUCT_FROM_DATABASE=S5230
+
+usb:v04E8p6802*
+ ID_PRODUCT_FROM_DATABASE=Standalone HSPA device
+
+usb:v04E8p6806*
+ ID_PRODUCT_FROM_DATABASE=Composite LTE device (Trial)
+
+usb:v04E8p6807*
+ ID_PRODUCT_FROM_DATABASE=Composite HSPA device
+
+usb:v04E8p681C*
+ ID_PRODUCT_FROM_DATABASE=Galaxy Portal/Spica/S
+
+usb:v04E8p681D*
+ ID_PRODUCT_FROM_DATABASE=Galaxy Portal/Spica Android Phone
+
+usb:v04E8p684E*
+ ID_PRODUCT_FROM_DATABASE=Wave (GT-S8500)
+
+usb:v04E8p685B*
+ ID_PRODUCT_FROM_DATABASE=GT-I9100 Phone [Galaxy S II] (mass storage mode)
+
+usb:v04E8p685C*
+ ID_PRODUCT_FROM_DATABASE=GT-I9250 Phone [Galaxy Nexus]
+
+usb:v04E8p685E*
+ ID_PRODUCT_FROM_DATABASE=GT-I9100 Phone [Galaxy S II] (USB Debugging mode)
+
+usb:v04E8p6860*
+ ID_PRODUCT_FROM_DATABASE=GT-I9100 Phone [Galaxy S II], GT-I9300 Phone [Galaxy S III], GT-P7500 [Galaxy Tab 10.1]
+
+usb:v04E8p6865*
+ ID_PRODUCT_FROM_DATABASE=GT-I9300 Phone [Galaxy S III] (PTP mode)
+
+usb:v04E8p6866*
+ ID_PRODUCT_FROM_DATABASE=GT-I9300 Phone [Galaxy S III] (debugging mode)
+
+usb:v04E8p6875*
+ ID_PRODUCT_FROM_DATABASE=GT-B3710 Standalone LTE device (Commercial)
+
+usb:v04E8p6876*
+ ID_PRODUCT_FROM_DATABASE=GT-B3710 LTE Modem
+
+usb:v04E8p6877*
+ ID_PRODUCT_FROM_DATABASE=Galaxy S
+
+usb:v04E8p6888*
+ ID_PRODUCT_FROM_DATABASE=GT-B3730 Composite LTE device (Commercial)
+
+usb:v04E8p6889*
+ ID_PRODUCT_FROM_DATABASE=GT-B3730 Composite LTE device (Commercial)
+
+usb:v04E8p689A*
+ ID_PRODUCT_FROM_DATABASE=LTE Storage Driver [CMC2xx]
+
+usb:v04E8p689E*
+ ID_PRODUCT_FROM_DATABASE=GT-S5670 [Galaxy Fit]
+
+usb:v04E8p68AA*
+ ID_PRODUCT_FROM_DATABASE=Reality
+
+usb:v04E8p7011*
+ ID_PRODUCT_FROM_DATABASE=SEW-2003U Card
+
+usb:v04E8p7021*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v04E8p7061*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v04E8p7080*
+ ID_PRODUCT_FROM_DATABASE=Anycall SCH-W580
+
+usb:v04E8p7081*
+ ID_PRODUCT_FROM_DATABASE=Human Interface Device
+
+usb:v04E8p8001*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v04E8pE020*
+ ID_PRODUCT_FROM_DATABASE=SERI E02 SCOM 6200 UMTS Phone
+
+usb:v04E8pE021*
+ ID_PRODUCT_FROM_DATABASE=SERI E02 SCOM 6200 Virtual UARTs
+
+usb:v04E8pE022*
+ ID_PRODUCT_FROM_DATABASE=SERI E02 SCOM 6200 Flash Load Disk
+
+usb:v04E8pFF30*
+ ID_PRODUCT_FROM_DATABASE=SG_iMON
+
+usb:v04E9*
+ ID_VENDOR_FROM_DATABASE=PC-Tel, Inc.
+
+usb:v04EA*
+ ID_VENDOR_FROM_DATABASE=Brooktree Corp.
+
+usb:v04EB*
+ ID_VENDOR_FROM_DATABASE=Northstar Systems, Inc.
+
+usb:v04EBpE004*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v04EC*
+ ID_VENDOR_FROM_DATABASE=Tokyo Electron Device, Ltd
+
+usb:v04ED*
+ ID_VENDOR_FROM_DATABASE=Annabooks
+
+usb:v04EF*
+ ID_VENDOR_FROM_DATABASE=Pacific Electronic International, Inc.
+
+usb:v04F0*
+ ID_VENDOR_FROM_DATABASE=Daewoo Electronics Co., Ltd
+
+usb:v04F1*
+ ID_VENDOR_FROM_DATABASE=Victor Company of Japan, Ltd
+
+usb:v04F1p0001*
+ ID_PRODUCT_FROM_DATABASE=GC-QX3 Digital Still Camera
+
+usb:v04F1p0004*
+ ID_PRODUCT_FROM_DATABASE=GR-DVL815U Digital Video Camera
+
+usb:v04F1p0006*
+ ID_PRODUCT_FROM_DATABASE=DV Camera Storage
+
+usb:v04F1p0008*
+ ID_PRODUCT_FROM_DATABASE=GZ-MG30AA/MC500E Digital Video Camera
+
+usb:v04F1p0009*
+ ID_PRODUCT_FROM_DATABASE=GR-DX25EK Digital Video Camera
+
+usb:v04F1p000A*
+ ID_PRODUCT_FROM_DATABASE=GR-D72 Digital Video Camera
+
+usb:v04F1p1001*
+ ID_PRODUCT_FROM_DATABASE=GC-A50 Camera Device
+
+usb:v04F1p3008*
+ ID_PRODUCT_FROM_DATABASE=MP-PRX1 Ethernet
+
+usb:v04F1p3009*
+ ID_PRODUCT_FROM_DATABASE=MP-XP7250 WLAN Adapter
+
+usb:v04F2*
+ ID_VENDOR_FROM_DATABASE=Chicony Electronics Co., Ltd
+
+usb:v04F2p0001*
+ ID_PRODUCT_FROM_DATABASE=KU-8933 Keyboard
+
+usb:v04F2p0002*
+ ID_PRODUCT_FROM_DATABASE=NT68P81 Keyboard
+
+usb:v04F2p0110*
+ ID_PRODUCT_FROM_DATABASE=KU-2971 Keyboard
+
+usb:v04F2p0111*
+ ID_PRODUCT_FROM_DATABASE=KU-9908 Keyboard
+
+usb:v04F2p0112*
+ ID_PRODUCT_FROM_DATABASE=KU-8933 Keyboard with PS/2 Mouse port
+
+usb:v04F2p0116*
+ ID_PRODUCT_FROM_DATABASE=KU-2971/KU-0325 Keyboard
+
+usb:v04F2p0200*
+ ID_PRODUCT_FROM_DATABASE=KBR-0108
+
+usb:v04F2p0201*
+ ID_PRODUCT_FROM_DATABASE=Gaming Keyboard KPD0250
+
+usb:v04F2p0220*
+ ID_PRODUCT_FROM_DATABASE=Wireless HID Receiver
+
+usb:v04F2p0402*
+ ID_PRODUCT_FROM_DATABASE=Genius LuxeMate i200 Keyboard
+
+usb:v04F2p0403*
+ ID_PRODUCT_FROM_DATABASE=KU-0420 keyboard
+
+usb:v04F2p0418*
+ ID_PRODUCT_FROM_DATABASE=KU-0418 Tactical Pad
+
+usb:v04F2p0760*
+ ID_PRODUCT_FROM_DATABASE=Acer KU-0760 Keyboard
+
+usb:v04F2p0841*
+ ID_PRODUCT_FROM_DATABASE=HP Multimedia Keyboard
+
+usb:v04F2p0860*
+ ID_PRODUCT_FROM_DATABASE=2.4G Multimedia Wireless Kit
+
+usb:v04F2pA001*
+ ID_PRODUCT_FROM_DATABASE=E-Video DC-100 Camera
+
+usb:v04F2pA120*
+ ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R)
+
+usb:v04F2pA121*
+ ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R)
+
+usb:v04F2pA122*
+ ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R)
+
+usb:v04F2pA123*
+ ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R)
+
+usb:v04F2pA124*
+ ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R)
+
+usb:v04F2pA128*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C202 + OV7663 + EEPROM)
+
+usb:v04F2pA133*
+ ID_PRODUCT_FROM_DATABASE=Gateway Webcam
+
+usb:v04F2pA136*
+ ID_PRODUCT_FROM_DATABASE=LabTec Webcam 5500
+
+usb:v04F2pA204*
+ ID_PRODUCT_FROM_DATABASE=DSC WIA Device (1300)
+
+usb:v04F2pA208*
+ ID_PRODUCT_FROM_DATABASE=DSC WIA Device (2320)
+
+usb:v04F2pA209*
+ ID_PRODUCT_FROM_DATABASE=Labtec DC-2320
+
+usb:v04F2pA20A*
+ ID_PRODUCT_FROM_DATABASE=DSC WIA Device (3310)
+
+usb:v04F2pA20C*
+ ID_PRODUCT_FROM_DATABASE=DSC WIA Device (3320)
+
+usb:v04F2pA210*
+ ID_PRODUCT_FROM_DATABASE=Audio Device
+
+usb:v04F2pB008*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Camera
+
+usb:v04F2pB009*
+ ID_PRODUCT_FROM_DATABASE=Integrated Camera
+
+usb:v04F2pB010*
+ ID_PRODUCT_FROM_DATABASE=Integrated Camera
+
+usb:v04F2pB012*
+ ID_PRODUCT_FROM_DATABASE=1.3 MPixel UVC Webcam
+
+usb:v04F2pB013*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Camera
+
+usb:v04F2pB015*
+ ID_PRODUCT_FROM_DATABASE=VGA 24fps UVC Webcam
+
+usb:v04F2pB016*
+ ID_PRODUCT_FROM_DATABASE=VGA 30fps UVC Webcam
+
+usb:v04F2pB018*
+ ID_PRODUCT_FROM_DATABASE=2M UVC Webcam
+
+usb:v04F2pB021*
+ ID_PRODUCT_FROM_DATABASE=ViewSonic 1.3M, USB2.0 Webcam
+
+usb:v04F2pB022*
+ ID_PRODUCT_FROM_DATABASE=Gateway USB 2.0 Webcam
+
+usb:v04F2pB023*
+ ID_PRODUCT_FROM_DATABASE=Gateway USB 2.0 Webcam
+
+usb:v04F2pB024*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Webcam
+
+usb:v04F2pB025*
+ ID_PRODUCT_FROM_DATABASE=Camera
+
+usb:v04F2pB027*
+ ID_PRODUCT_FROM_DATABASE=Gateway USB 2.0 Webcam
+
+usb:v04F2pB028*
+ ID_PRODUCT_FROM_DATABASE=VGA UVC Webcam
+
+usb:v04F2pB029*
+ ID_PRODUCT_FROM_DATABASE=1.3M UVC Webcam
+
+usb:v04F2pB036*
+ ID_PRODUCT_FROM_DATABASE=Asus Integrated 0.3M UVC Webcam
+
+usb:v04F2pB044*
+ ID_PRODUCT_FROM_DATABASE=Acer CrystalEye Webcam
+
+usb:v04F2pB057*
+ ID_PRODUCT_FROM_DATABASE=integrated USB webcam
+
+usb:v04F2pB059*
+ ID_PRODUCT_FROM_DATABASE=CKF7037 HP webcam
+
+usb:v04F2pB071*
+ ID_PRODUCT_FROM_DATABASE=2.0M UVC Webcam / CNF7129
+
+usb:v04F2pB091*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v04F2pB104*
+ ID_PRODUCT_FROM_DATABASE=CNF7069 Webcam
+
+usb:v04F2pB107*
+ ID_PRODUCT_FROM_DATABASE=CNF7070 Webcam
+
+usb:v04F2pB14C*
+ ID_PRODUCT_FROM_DATABASE=CNF8050 Webcam
+
+usb:v04F2pB175*
+ ID_PRODUCT_FROM_DATABASE=4-Port Hub
+
+usb:v04F2pB1AA*
+ ID_PRODUCT_FROM_DATABASE=Webcam-101
+
+usb:v04F2pB1B4*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera
+
+usb:v04F2pB1B9*
+ ID_PRODUCT_FROM_DATABASE=Asus Integrated Webcam
+
+usb:v04F2pB1CF*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera
+
+usb:v04F2pB1D6*
+ ID_PRODUCT_FROM_DATABASE=CNF9055 Toshiba Webcam
+
+usb:v04F2pB217*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera (0.3MP)
+
+usb:v04F2pB221*
+ ID_PRODUCT_FROM_DATABASE=integrated camera
+
+usb:v04F2pB230*
+ ID_PRODUCT_FROM_DATABASE=Integrated HP HD Webcam
+
+usb:v04F2pB257*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera
+
+usb:v04F2pB26B*
+ ID_PRODUCT_FROM_DATABASE=Sony Visual Communication Camera
+
+usb:v04F2pB272*
+ ID_PRODUCT_FROM_DATABASE=Lenovo EasyCamera
+
+usb:v04F2pB2B0*
+ ID_PRODUCT_FROM_DATABASE=Camera
+
+usb:v04F2pB2B9*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera UVC
+
+usb:v04F2pB2EA*
+ ID_PRODUCT_FROM_DATABASE=Integrated Camera [ThinkPad]
+
+usb:v04F2pB330*
+ ID_PRODUCT_FROM_DATABASE=Asus 720p CMOS webcam
+
+usb:v04F3*
+ ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp.
+
+usb:v04F3p0103*
+ ID_PRODUCT_FROM_DATABASE=ActiveJet K-2024 Multimedia Keyboard
+
+usb:v04F3p01A4*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard
+
+usb:v04F3p0210*
+ ID_PRODUCT_FROM_DATABASE=AM-400 Hama Optical Mouse
+
+usb:v04F3p0212*
+ ID_PRODUCT_FROM_DATABASE=Laser Mouse
+
+usb:v04F3p0214*
+ ID_PRODUCT_FROM_DATABASE=Lynx M9 Optical Mouse
+
+usb:v04F3p0230*
+ ID_PRODUCT_FROM_DATABASE=3D Optical Mouse
+
+usb:v04F3p0232*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v04F3p02F4*
+ ID_PRODUCT_FROM_DATABASE=2.4G Cordless Mouse
+
+usb:v04F3p04A0*
+ ID_PRODUCT_FROM_DATABASE=Dream Cheeky Stress/Panic Button
+
+usb:v04F4*
+ ID_VENDOR_FROM_DATABASE=Harting Elektronik, Inc.
+
+usb:v04F5*
+ ID_VENDOR_FROM_DATABASE=Fujitsu-ICL Systems, Inc.
+
+usb:v04F6*
+ ID_VENDOR_FROM_DATABASE=Norand Corp.
+
+usb:v04F7*
+ ID_VENDOR_FROM_DATABASE=Newnex Technology Corp.
+
+usb:v04F8*
+ ID_VENDOR_FROM_DATABASE=FuturePlus Systems
+
+usb:v04F9*
+ ID_VENDOR_FROM_DATABASE=Brother Industries, Ltd
+
+usb:v04F9p0002*
+ ID_PRODUCT_FROM_DATABASE=HL-1050 Laser Printer
+
+usb:v04F9p0005*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0006*
+ ID_PRODUCT_FROM_DATABASE=HL-1240 Laser Printer
+
+usb:v04F9p0007*
+ ID_PRODUCT_FROM_DATABASE=HL-1250 Laser Printer
+
+usb:v04F9p0008*
+ ID_PRODUCT_FROM_DATABASE=HL-1270 Laser Printer
+
+usb:v04F9p0009*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p000A*
+ ID_PRODUCT_FROM_DATABASE=P2500 series
+
+usb:v04F9p000B*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p000C*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p000D*
+ ID_PRODUCT_FROM_DATABASE=HL-1440 Laser Printer
+
+usb:v04F9p000E*
+ ID_PRODUCT_FROM_DATABASE=HL-1450 series
+
+usb:v04F9p000F*
+ ID_PRODUCT_FROM_DATABASE=HL-1470N series
+
+usb:v04F9p0010*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0011*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0012*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0013*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0014*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0015*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0016*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0017*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0018*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p001A*
+ ID_PRODUCT_FROM_DATABASE=HL-1430 Laser Printer
+
+usb:v04F9p001C*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p001E*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0020*
+ ID_PRODUCT_FROM_DATABASE=HL-5130 series
+
+usb:v04F9p0021*
+ ID_PRODUCT_FROM_DATABASE=HL-5140 series
+
+usb:v04F9p0022*
+ ID_PRODUCT_FROM_DATABASE=HL-5150D series
+
+usb:v04F9p0023*
+ ID_PRODUCT_FROM_DATABASE=HL-5170DN series
+
+usb:v04F9p0024*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0025*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0027*
+ ID_PRODUCT_FROM_DATABASE=HL-2030 Laser Printer
+
+usb:v04F9p0028*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0029*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p002A*
+ ID_PRODUCT_FROM_DATABASE=HL-52x0 series
+
+usb:v04F9p002B*
+ ID_PRODUCT_FROM_DATABASE=HL-5250DN Printer
+
+usb:v04F9p002C*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p002D*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p0039*
+ ID_PRODUCT_FROM_DATABASE=HL-5340 series
+
+usb:v04F9p0100*
+ ID_PRODUCT_FROM_DATABASE=MFC8600/9650 series
+
+usb:v04F9p0101*
+ ID_PRODUCT_FROM_DATABASE=MFC9600/9870 series
+
+usb:v04F9p0102*
+ ID_PRODUCT_FROM_DATABASE=MFC9750/1200 series
+
+usb:v04F9p0104*
+ ID_PRODUCT_FROM_DATABASE=MFC-8300J
+
+usb:v04F9p0105*
+ ID_PRODUCT_FROM_DATABASE=MFC-9600J
+
+usb:v04F9p0106*
+ ID_PRODUCT_FROM_DATABASE=MFC-7300C
+
+usb:v04F9p0107*
+ ID_PRODUCT_FROM_DATABASE=MFC-7400C
+
+usb:v04F9p0108*
+ ID_PRODUCT_FROM_DATABASE=MFC-9200C
+
+usb:v04F9p0109*
+ ID_PRODUCT_FROM_DATABASE=MFC-830
+
+usb:v04F9p010A*
+ ID_PRODUCT_FROM_DATABASE=MFC-840
+
+usb:v04F9p010B*
+ ID_PRODUCT_FROM_DATABASE=MFC-860
+
+usb:v04F9p010C*
+ ID_PRODUCT_FROM_DATABASE=MFC-7400J
+
+usb:v04F9p010D*
+ ID_PRODUCT_FROM_DATABASE=MFC-9200J
+
+usb:v04F9p010E*
+ ID_PRODUCT_FROM_DATABASE=MFC3100C Scanner
+
+usb:v04F9p010F*
+ ID_PRODUCT_FROM_DATABASE=MFC 5100C
+
+usb:v04F9p0110*
+ ID_PRODUCT_FROM_DATABASE=MFC4800 Scanner
+
+usb:v04F9p0111*
+ ID_PRODUCT_FROM_DATABASE=MFC 6800
+
+usb:v04F9p0112*
+ ID_PRODUCT_FROM_DATABASE=DCP1000 Port(FaxModem)
+
+usb:v04F9p0113*
+ ID_PRODUCT_FROM_DATABASE=MFC-8500
+
+usb:v04F9p0114*
+ ID_PRODUCT_FROM_DATABASE=MFC9700 Port(FaxModem)
+
+usb:v04F9p0115*
+ ID_PRODUCT_FROM_DATABASE=MFC9800 Scanner
+
+usb:v04F9p0116*
+ ID_PRODUCT_FROM_DATABASE=DCP1400 Scanner
+
+usb:v04F9p0119*
+ ID_PRODUCT_FROM_DATABASE=MFC-9660
+
+usb:v04F9p011B*
+ ID_PRODUCT_FROM_DATABASE=MFC-9880
+
+usb:v04F9p011C*
+ ID_PRODUCT_FROM_DATABASE=MFC-9760
+
+usb:v04F9p011D*
+ ID_PRODUCT_FROM_DATABASE=MFC-9070
+
+usb:v04F9p011E*
+ ID_PRODUCT_FROM_DATABASE=MFC-9180
+
+usb:v04F9p011F*
+ ID_PRODUCT_FROM_DATABASE=MFC-9160
+
+usb:v04F9p0120*
+ ID_PRODUCT_FROM_DATABASE=MFC580 Port(FaxModem)
+
+usb:v04F9p0121*
+ ID_PRODUCT_FROM_DATABASE=MFC-590
+
+usb:v04F9p0122*
+ ID_PRODUCT_FROM_DATABASE=MFC-5100J
+
+usb:v04F9p0129*
+ ID_PRODUCT_FROM_DATABASE=Imagistics 2500 (MFC-8640D clone)
+
+usb:v04F9p012F*
+ ID_PRODUCT_FROM_DATABASE=FAX-4750e
+
+usb:v04F9p0132*
+ ID_PRODUCT_FROM_DATABASE=MFC-5200C RemovableDisk
+
+usb:v04F9p0135*
+ ID_PRODUCT_FROM_DATABASE=MFC-100 Scanner
+
+usb:v04F9p0136*
+ ID_PRODUCT_FROM_DATABASE=MFC-150CL Scanner
+
+usb:v04F9p013C*
+ ID_PRODUCT_FROM_DATABASE=MFC-890 Port
+
+usb:v04F9p013D*
+ ID_PRODUCT_FROM_DATABASE=MFC-5200J Printer
+
+usb:v04F9p013E*
+ ID_PRODUCT_FROM_DATABASE=MFC-4420C RemovableDisk
+
+usb:v04F9p013F*
+ ID_PRODUCT_FROM_DATABASE=MFC-4820C RemovableDisk
+
+usb:v04F9p0140*
+ ID_PRODUCT_FROM_DATABASE=DCP-8020
+
+usb:v04F9p0141*
+ ID_PRODUCT_FROM_DATABASE=DCP-8025D
+
+usb:v04F9p0142*
+ ID_PRODUCT_FROM_DATABASE=MFC-8420
+
+usb:v04F9p0143*
+ ID_PRODUCT_FROM_DATABASE=MFC-8820D
+
+usb:v04F9p0144*
+ ID_PRODUCT_FROM_DATABASE=DCP-4020C RemovableDisk
+
+usb:v04F9p0146*
+ ID_PRODUCT_FROM_DATABASE=MFC-3220C
+
+usb:v04F9p0147*
+ ID_PRODUCT_FROM_DATABASE=FAX-1820C Printer
+
+usb:v04F9p0148*
+ ID_PRODUCT_FROM_DATABASE=MFC-3320CN Printer
+
+usb:v04F9p0149*
+ ID_PRODUCT_FROM_DATABASE=FAX-1920CN Printer
+
+usb:v04F9p014A*
+ ID_PRODUCT_FROM_DATABASE=MFC-3420C
+
+usb:v04F9p014B*
+ ID_PRODUCT_FROM_DATABASE=MFC-3820CN
+
+usb:v04F9p014D*
+ ID_PRODUCT_FROM_DATABASE=FAX-1815C Printer
+
+usb:v04F9p014E*
+ ID_PRODUCT_FROM_DATABASE=MFC-8820J
+
+usb:v04F9p0150*
+ ID_PRODUCT_FROM_DATABASE=MFC-8220 Port(FaxModem)
+
+usb:v04F9p0151*
+ ID_PRODUCT_FROM_DATABASE=MFC-8210J
+
+usb:v04F9p0157*
+ ID_PRODUCT_FROM_DATABASE=MFC-3420J Printer
+
+usb:v04F9p0158*
+ ID_PRODUCT_FROM_DATABASE=MFC-3820JN Port(FaxModem)
+
+usb:v04F9p015D*
+ ID_PRODUCT_FROM_DATABASE=MFC Composite Device
+
+usb:v04F9p015E*
+ ID_PRODUCT_FROM_DATABASE=DCP-8045D
+
+usb:v04F9p015F*
+ ID_PRODUCT_FROM_DATABASE=MFC-8440
+
+usb:v04F9p0160*
+ ID_PRODUCT_FROM_DATABASE=MFC-8840D
+
+usb:v04F9p0161*
+ ID_PRODUCT_FROM_DATABASE=MFC-210C
+
+usb:v04F9p0162*
+ ID_PRODUCT_FROM_DATABASE=MFC-420CN Remote Setup Port
+
+usb:v04F9p0163*
+ ID_PRODUCT_FROM_DATABASE=MFC-410CN RemovableDisk
+
+usb:v04F9p0165*
+ ID_PRODUCT_FROM_DATABASE=MFC-620CN
+
+usb:v04F9p0166*
+ ID_PRODUCT_FROM_DATABASE=MFC-610CLN RemovableDisk
+
+usb:v04F9p0168*
+ ID_PRODUCT_FROM_DATABASE=MFC-620CLN
+
+usb:v04F9p0169*
+ ID_PRODUCT_FROM_DATABASE=DCP-110C RemovableDisk
+
+usb:v04F9p016B*
+ ID_PRODUCT_FROM_DATABASE=DCP-310CN RemovableDisk
+
+usb:v04F9p016C*
+ ID_PRODUCT_FROM_DATABASE=FAX-2440C Printer
+
+usb:v04F9p016D*
+ ID_PRODUCT_FROM_DATABASE=MFC-5440CN
+
+usb:v04F9p016E*
+ ID_PRODUCT_FROM_DATABASE=MFC-5840CN Remote Setup Port
+
+usb:v04F9p0170*
+ ID_PRODUCT_FROM_DATABASE=FAX-1840C Printer
+
+usb:v04F9p0171*
+ ID_PRODUCT_FROM_DATABASE=FAX-1835C Printer
+
+usb:v04F9p0172*
+ ID_PRODUCT_FROM_DATABASE=FAX-1940CN Printer
+
+usb:v04F9p0173*
+ ID_PRODUCT_FROM_DATABASE=MFC-3240C Remote Setup Port
+
+usb:v04F9p0174*
+ ID_PRODUCT_FROM_DATABASE=MFC-3340CN RemovableDisk
+
+usb:v04F9p017B*
+ ID_PRODUCT_FROM_DATABASE=Imagistics sx2100
+
+usb:v04F9p0180*
+ ID_PRODUCT_FROM_DATABASE=MFC-7420
+
+usb:v04F9p0181*
+ ID_PRODUCT_FROM_DATABASE=MFC-7820N Port(FaxModem)
+
+usb:v04F9p0182*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04F9p0183*
+ ID_PRODUCT_FROM_DATABASE=DCP-7020
+
+usb:v04F9p0184*
+ ID_PRODUCT_FROM_DATABASE=DCP-7025 Printer
+
+usb:v04F9p0185*
+ ID_PRODUCT_FROM_DATABASE=MFC-7220 Printer
+
+usb:v04F9p0186*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04F9p0187*
+ ID_PRODUCT_FROM_DATABASE=FAX-2820 Printer
+
+usb:v04F9p0188*
+ ID_PRODUCT_FROM_DATABASE=FAX-2920 Printer
+
+usb:v04F9p018A*
+ ID_PRODUCT_FROM_DATABASE=MFC-9420CN
+
+usb:v04F9p018C*
+ ID_PRODUCT_FROM_DATABASE=DCP-115C
+
+usb:v04F9p018D*
+ ID_PRODUCT_FROM_DATABASE=DCP-116C
+
+usb:v04F9p018E*
+ ID_PRODUCT_FROM_DATABASE=DCP-117C
+
+usb:v04F9p018F*
+ ID_PRODUCT_FROM_DATABASE=DCP-118C
+
+usb:v04F9p0190*
+ ID_PRODUCT_FROM_DATABASE=DCP-120C
+
+usb:v04F9p0191*
+ ID_PRODUCT_FROM_DATABASE=DCP-315CN
+
+usb:v04F9p0192*
+ ID_PRODUCT_FROM_DATABASE=DCP-340CW
+
+usb:v04F9p0193*
+ ID_PRODUCT_FROM_DATABASE=MFC-215C
+
+usb:v04F9p0194*
+ ID_PRODUCT_FROM_DATABASE=MFC-425CN
+
+usb:v04F9p0195*
+ ID_PRODUCT_FROM_DATABASE=MFC-820CW Remote Setup Port
+
+usb:v04F9p0196*
+ ID_PRODUCT_FROM_DATABASE=MFC-820CN Remote Setup Port
+
+usb:v04F9p0197*
+ ID_PRODUCT_FROM_DATABASE=MFC-640CW
+
+usb:v04F9p019A*
+ ID_PRODUCT_FROM_DATABASE=MFC-840CLN Remote Setup Port
+
+usb:v04F9p01A2*
+ ID_PRODUCT_FROM_DATABASE=MFC-8640D
+
+usb:v04F9p01A3*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v04F9p01A4*
+ ID_PRODUCT_FROM_DATABASE=DCP-8065DN Printer
+
+usb:v04F9p01A5*
+ ID_PRODUCT_FROM_DATABASE=MFC-8460N Port(FaxModem)
+
+usb:v04F9p01A6*
+ ID_PRODUCT_FROM_DATABASE=MFC-8860DN Port(FaxModem)
+
+usb:v04F9p01A7*
+ ID_PRODUCT_FROM_DATABASE=MFC-8870DW Printer
+
+usb:v04F9p01A8*
+ ID_PRODUCT_FROM_DATABASE=DCP-130C
+
+usb:v04F9p01A9*
+ ID_PRODUCT_FROM_DATABASE=DCP-330C
+
+usb:v04F9p01AA*
+ ID_PRODUCT_FROM_DATABASE=DCP-540CN
+
+usb:v04F9p01AB*
+ ID_PRODUCT_FROM_DATABASE=MFC-240C
+
+usb:v04F9p01AE*
+ ID_PRODUCT_FROM_DATABASE=DCP-750CW RemovableDisk
+
+usb:v04F9p01AF*
+ ID_PRODUCT_FROM_DATABASE=MFC-440CN
+
+usb:v04F9p01B0*
+ ID_PRODUCT_FROM_DATABASE=MFC-660CN
+
+usb:v04F9p01B1*
+ ID_PRODUCT_FROM_DATABASE=MFC-665CW Remote Setup Port
+
+usb:v04F9p01B2*
+ ID_PRODUCT_FROM_DATABASE=MFC-845CW Remote Setup Port
+
+usb:v04F9p01B4*
+ ID_PRODUCT_FROM_DATABASE=MFC-460CN Remote Setup Port
+
+usb:v04F9p01B5*
+ ID_PRODUCT_FROM_DATABASE=MFC-630CD
+
+usb:v04F9p01B6*
+ ID_PRODUCT_FROM_DATABASE=MFC-850CDN
+
+usb:v04F9p01B7*
+ ID_PRODUCT_FROM_DATABASE=MFC-5460CN Remote Setup Port
+
+usb:v04F9p01B8*
+ ID_PRODUCT_FROM_DATABASE=MFC-5860CN
+
+usb:v04F9p01BA*
+ ID_PRODUCT_FROM_DATABASE=MFC-3360C
+
+usb:v04F9p01BD*
+ ID_PRODUCT_FROM_DATABASE=MFC-8660DN
+
+usb:v04F9p01BE*
+ ID_PRODUCT_FROM_DATABASE=DCP-750CN RemovableDisk
+
+usb:v04F9p01BF*
+ ID_PRODUCT_FROM_DATABASE=MFC-860CDN Remote Setup Port
+
+usb:v04F9p01C0*
+ ID_PRODUCT_FROM_DATABASE=DCP-128C
+
+usb:v04F9p01C1*
+ ID_PRODUCT_FROM_DATABASE=DCP-129C
+
+usb:v04F9p01C2*
+ ID_PRODUCT_FROM_DATABASE=DCP-131C
+
+usb:v04F9p01C3*
+ ID_PRODUCT_FROM_DATABASE=DCP-329C
+
+usb:v04F9p01C4*
+ ID_PRODUCT_FROM_DATABASE=DCP-331C
+
+usb:v04F9p01C5*
+ ID_PRODUCT_FROM_DATABASE=MFC-239C
+
+usb:v04F9p01CA*
+ ID_PRODUCT_FROM_DATABASE=MFC-9440CN Remote Setup Port
+
+usb:v04F9p01CE*
+ ID_PRODUCT_FROM_DATABASE=DCP-135C
+
+usb:v04F9p01CF*
+ ID_PRODUCT_FROM_DATABASE=DCP-150C
+
+usb:v04F9p01D0*
+ ID_PRODUCT_FROM_DATABASE=DCP-350C
+
+usb:v04F9p01D1*
+ ID_PRODUCT_FROM_DATABASE=DCP-560CN
+
+usb:v04F9p01D4*
+ ID_PRODUCT_FROM_DATABASE=MFC-230C
+
+usb:v04F9p01D5*
+ ID_PRODUCT_FROM_DATABASE=MFC-235C
+
+usb:v04F9p01D6*
+ ID_PRODUCT_FROM_DATABASE=MFC-260C
+
+usb:v04F9p01DF*
+ ID_PRODUCT_FROM_DATABASE=DCP-155C
+
+usb:v04F9p01E0*
+ ID_PRODUCT_FROM_DATABASE=MFC-265C
+
+usb:v04F9p01E1*
+ ID_PRODUCT_FROM_DATABASE=DCP-153C
+
+usb:v04F9p01E2*
+ ID_PRODUCT_FROM_DATABASE=DCP-157C
+
+usb:v04F9p01E3*
+ ID_PRODUCT_FROM_DATABASE=DCP-353C
+
+usb:v04F9p01E4*
+ ID_PRODUCT_FROM_DATABASE=DCP-357C
+
+usb:v04F9p01E7*
+ ID_PRODUCT_FROM_DATABASE=MFC-7340
+
+usb:v04F9p01E9*
+ ID_PRODUCT_FROM_DATABASE=DCP-7040
+
+usb:v04F9p01EA*
+ ID_PRODUCT_FROM_DATABASE=DCP-7030
+
+usb:v04F9p01EB*
+ ID_PRODUCT_FROM_DATABASE=MFC-7320
+
+usb:v04F9p01F4*
+ ID_PRODUCT_FROM_DATABASE=MFC-5890CN
+
+usb:v04F9p0223*
+ ID_PRODUCT_FROM_DATABASE=DCP-365CN
+
+usb:v04F9p0248*
+ ID_PRODUCT_FROM_DATABASE=DCP-7055 scanner/printer
+
+usb:v04F9p1000*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p1002*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v04F9p2002*
+ ID_PRODUCT_FROM_DATABASE=PTUSB Printing
+
+usb:v04F9p2004*
+ ID_PRODUCT_FROM_DATABASE=PT-2300/2310 p-Touch Laber Printer
+
+usb:v04F9p2015*
+ ID_PRODUCT_FROM_DATABASE=QL-500 P-touch label printer
+
+usb:v04F9p2016*
+ ID_PRODUCT_FROM_DATABASE=QL-550 P-touch label printer
+
+usb:v04F9p201A*
+ ID_PRODUCT_FROM_DATABASE=PT-18R P-touch label printer
+
+usb:v04F9p201B*
+ ID_PRODUCT_FROM_DATABASE=QL-650TD P-Touch Label Printer
+
+usb:v04F9p2027*
+ ID_PRODUCT_FROM_DATABASE=QL-560 P-Touch Label Printer
+
+usb:v04F9p2100*
+ ID_PRODUCT_FROM_DATABASE=Card Reader Writer
+
+usb:v04FA*
+ ID_VENDOR_FROM_DATABASE=Dallas Semiconductor
+
+usb:v04FAp2490*
+ ID_PRODUCT_FROM_DATABASE=DS1490F 2-in-1 Fob, 1-Wire adapter
+
+usb:v04FAp4201*
+ ID_PRODUCT_FROM_DATABASE=DS4201 Audio DAC
+
+usb:v04FB*
+ ID_VENDOR_FROM_DATABASE=Biostar Microtech International Corp.
+
+usb:v04FC*
+ ID_VENDOR_FROM_DATABASE=Sunplus Technology Co., Ltd
+
+usb:v04FCp0003*
+ ID_PRODUCT_FROM_DATABASE=CM1092 / Wintech CM-5098 Optical Mouse
+
+usb:v04FCp0005*
+ ID_PRODUCT_FROM_DATABASE=USB OpticalWheel Mouse
+
+usb:v04FCp0013*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v04FCp0015*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v04FCp00D3*
+ ID_PRODUCT_FROM_DATABASE=00052486 / Laser Mouse M1052 [hama]
+
+usb:v04FCp0171*
+ ID_PRODUCT_FROM_DATABASE=SPCA1527A/SPCA1528 SD card camera (Mass Storage mode)
+
+usb:v04FCp0232*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint
+
+usb:v04FCp0538*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse 2.4G [Bright]
+
+usb:v04FCp0561*
+ ID_PRODUCT_FROM_DATABASE=Flexcam 100
+
+usb:v04FCp05D8*
+ ID_PRODUCT_FROM_DATABASE=Wireless keyboard/mouse
+
+usb:v04FCp0C15*
+ ID_PRODUCT_FROM_DATABASE=SPIF215A SATA bridge
+
+usb:v04FCp0C25*
+ ID_PRODUCT_FROM_DATABASE=SATALink SPIF225A
+
+usb:v04FCp1528*
+ ID_PRODUCT_FROM_DATABASE=SPCA1527A/SPCA1528 SD card camera (webcam mode)
+
+usb:v04FCp1533*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage
+
+usb:v04FCp2080*
+ ID_PRODUCT_FROM_DATABASE=ASUS Webcam
+
+usb:v04FCp500C*
+ ID_PRODUCT_FROM_DATABASE=CA500C Digital Camera
+
+usb:v04FCp504A*
+ ID_PRODUCT_FROM_DATABASE=Aiptek Mini PenCam 1.3
+
+usb:v04FCp504B*
+ ID_PRODUCT_FROM_DATABASE=Aiptek Mega PockerCam 1.3/Maxell MaxPocket LE 1.3
+
+usb:v04FCp5330*
+ ID_PRODUCT_FROM_DATABASE=Digitrex 2110
+
+usb:v04FCp5331*
+ ID_PRODUCT_FROM_DATABASE=Vivitar Vivicam 10
+
+usb:v04FCp5360*
+ ID_PRODUCT_FROM_DATABASE=Sunplus Generic Digital Camera
+
+usb:v04FCp5720*
+ ID_PRODUCT_FROM_DATABASE=Card Reader Driver
+
+usb:v04FCp7333*
+ ID_PRODUCT_FROM_DATABASE=Finet Technology Palmpix DC-85
+
+usb:v04FCp757A*
+ ID_PRODUCT_FROM_DATABASE=Aiptek, MP315 MP3 Player
+
+usb:v04FCpFFFF*
+ ID_PRODUCT_FROM_DATABASE=PureDigital Ritz Disposable
+
+usb:v04FD*
+ ID_VENDOR_FROM_DATABASE=Soliton Systems, K.K.
+
+usb:v04FDp0003*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Reader II
+
+usb:v04FE*
+ ID_VENDOR_FROM_DATABASE=PFU, Ltd
+
+usb:v04FF*
+ ID_VENDOR_FROM_DATABASE=E-CMOS Corp.
+
+usb:v0500*
+ ID_VENDOR_FROM_DATABASE=Siam United Hi-Tech
+
+usb:v0500p0001*
+ ID_PRODUCT_FROM_DATABASE=DART Keyboard Mouse
+
+usb:v0500p0002*
+ ID_PRODUCT_FROM_DATABASE=DART-2 Keyboard
+
+usb:v0501*
+ ID_VENDOR_FROM_DATABASE=Fujikura DDK, Ltd
+
+usb:v0502*
+ ID_VENDOR_FROM_DATABASE=Acer, Inc.
+
+usb:v0502p0001*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0502p0736*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0502p15B1*
+ ID_PRODUCT_FROM_DATABASE=PDA n311
+
+usb:v0502p1631*
+ ID_PRODUCT_FROM_DATABASE=c10 Series
+
+usb:v0502p1632*
+ ID_PRODUCT_FROM_DATABASE=c20 Series
+
+usb:v0502p16E1*
+ ID_PRODUCT_FROM_DATABASE=n10 Handheld Sync
+
+usb:v0502p16E2*
+ ID_PRODUCT_FROM_DATABASE=n20 Pocket PC Sync
+
+usb:v0502p16E3*
+ ID_PRODUCT_FROM_DATABASE=n30 Handheld Sync
+
+usb:v0502p3202*
+ ID_PRODUCT_FROM_DATABASE=Liquid
+
+usb:v0502p3203*
+ ID_PRODUCT_FROM_DATABASE=Liquid (Debug mode)
+
+usb:v0502p3317*
+ ID_PRODUCT_FROM_DATABASE=Liquid
+
+usb:v0502p3325*
+ ID_PRODUCT_FROM_DATABASE=Iconia tablet A500
+
+usb:v0502p3341*
+ ID_PRODUCT_FROM_DATABASE=Iconia tablet A500
+
+usb:v0502pD001*
+ ID_PRODUCT_FROM_DATABASE=Divio NW801/DVC-V6+ Digital Camera
+
+usb:v0503*
+ ID_VENDOR_FROM_DATABASE=Hitachi America, Ltd
+
+usb:v0504*
+ ID_VENDOR_FROM_DATABASE=Hayes Microcomputer Products
+
+usb:v0506*
+ ID_VENDOR_FROM_DATABASE=3Com Corp.
+
+usb:v0506p009D*
+ ID_PRODUCT_FROM_DATABASE=HomeConnect Camera
+
+usb:v0506p00A0*
+ ID_PRODUCT_FROM_DATABASE=3CREB96 Bluetooth Adapter
+
+usb:v0506p00A1*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0506p00A2*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0506p00DF*
+ ID_PRODUCT_FROM_DATABASE=3Com Home Connect lite
+
+usb:v0506p0100*
+ ID_PRODUCT_FROM_DATABASE=HomeConnect ADSL Modem Driver
+
+usb:v0506p03E8*
+ ID_PRODUCT_FROM_DATABASE=3C19250 Ethernet [klsi]
+
+usb:v0506p0A01*
+ ID_PRODUCT_FROM_DATABASE=3CRSHEW696 Wireless Adapter
+
+usb:v0506p0A11*
+ ID_PRODUCT_FROM_DATABASE=3CRWE254G72 802.11g Adapter
+
+usb:v0506p11F8*
+ ID_PRODUCT_FROM_DATABASE=HomeConnect 3C460
+
+usb:v0506p2922*
+ ID_PRODUCT_FROM_DATABASE=HomeConnect Cable Modem External with
+
+usb:v0506p3021*
+ ID_PRODUCT_FROM_DATABASE=U.S.Robotics 56000 Voice FaxModem Pro
+
+usb:v0506p4601*
+ ID_PRODUCT_FROM_DATABASE=3C460B 10/100 Ethernet Adapter
+
+usb:v0506pF002*
+ ID_PRODUCT_FROM_DATABASE=3CP4218 ADSL Modem (pre-init)
+
+usb:v0506pF003*
+ ID_PRODUCT_FROM_DATABASE=3CP4218 ADSL Modem
+
+usb:v0506pF100*
+ ID_PRODUCT_FROM_DATABASE=3CP4218 ADSL Modem (pre-init)
+
+usb:v0507*
+ ID_VENDOR_FROM_DATABASE=Hosiden Corp.
+
+usb:v0507p0011*
+ ID_PRODUCT_FROM_DATABASE=Konami ParaParaParadise Controller
+
+usb:v0508*
+ ID_VENDOR_FROM_DATABASE=Clarion Co., Ltd
+
+usb:v0509*
+ ID_VENDOR_FROM_DATABASE=Aztech Systems, Ltd
+
+usb:v0509p0801*
+ ID_PRODUCT_FROM_DATABASE=ADSL Modem
+
+usb:v0509p0802*
+ ID_PRODUCT_FROM_DATABASE=ADSL Modem (RFC1483)
+
+usb:v0509p0806*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0509p080F*
+ ID_PRODUCT_FROM_DATABASE=Binatone ADSL500 Modem Network Interface
+
+usb:v0509p0812*
+ ID_PRODUCT_FROM_DATABASE=Pirelli ADSL Modem Network Interface
+
+usb:v050A*
+ ID_VENDOR_FROM_DATABASE=Cinch Connectors
+
+usb:v050B*
+ ID_VENDOR_FROM_DATABASE=Cable System International
+
+usb:v050C*
+ ID_VENDOR_FROM_DATABASE=InnoMedia, Inc.
+
+usb:v050D*
+ ID_VENDOR_FROM_DATABASE=Belkin Components
+
+usb:v050Dp0004*
+ ID_PRODUCT_FROM_DATABASE=Direct Connect
+
+usb:v050Dp0012*
+ ID_PRODUCT_FROM_DATABASE=F8T012 Bluetooth Adapter
+
+usb:v050Dp0013*
+ ID_PRODUCT_FROM_DATABASE=F8T013 Bluetooth Adapter
+
+usb:v050Dp0017*
+ ID_PRODUCT_FROM_DATABASE=B8T017 Bluetooth+EDR 2.1
+
+usb:v050Dp003A*
+ ID_PRODUCT_FROM_DATABASE=Universal Media Reader
+
+usb:v050Dp0050*
+ ID_PRODUCT_FROM_DATABASE=F5D6050 802.11b Wireless Adapter v2000 [Atmel at76c503a]
+
+usb:v050Dp0081*
+ ID_PRODUCT_FROM_DATABASE=F8T001v2 Bluetooth
+
+usb:v050Dp0083*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v050Dp0084*
+ ID_PRODUCT_FROM_DATABASE=F8T003v2 Bluetooth
+
+usb:v050Dp0102*
+ ID_PRODUCT_FROM_DATABASE=Flip KVM
+
+usb:v050Dp0103*
+ ID_PRODUCT_FROM_DATABASE=F5U103 Serial Adapter [etek]
+
+usb:v050Dp0106*
+ ID_PRODUCT_FROM_DATABASE=VideoBus II Adapter, Video
+
+usb:v050Dp0108*
+ ID_PRODUCT_FROM_DATABASE=F1DE108B KVM
+
+usb:v050Dp0109*
+ ID_PRODUCT_FROM_DATABASE=F5U109/F5U409 PDA Adapter
+
+usb:v050Dp0115*
+ ID_PRODUCT_FROM_DATABASE=SCSI Adapter
+
+usb:v050Dp0119*
+ ID_PRODUCT_FROM_DATABASE=F5U120-PC Dual PS/2 Ports / F5U118-UNV ADB Adapter
+
+usb:v050Dp0121*
+ ID_PRODUCT_FROM_DATABASE=F5D5050 100Mbps Ethernet
+
+usb:v050Dp0122*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Adapter
+
+usb:v050Dp0131*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device with trace filter
+
+usb:v050Dp016A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Mini Dongle
+
+usb:v050Dp0200*
+ ID_PRODUCT_FROM_DATABASE=Nostromo SpeedPad n52te Gaming Keyboard
+
+usb:v050Dp0201*
+ ID_PRODUCT_FROM_DATABASE=Peripheral Switch
+
+usb:v050Dp0208*
+ ID_PRODUCT_FROM_DATABASE=USBView II Video Adapter [nt1004]
+
+usb:v050Dp0210*
+ ID_PRODUCT_FROM_DATABASE=F5U228 Hi-Speed USB 2.0 DVD Creator
+
+usb:v050Dp0211*
+ ID_PRODUCT_FROM_DATABASE=F5U211 USB 2.0 15-in-1 Media Reader & Writer
+
+usb:v050Dp0224*
+ ID_PRODUCT_FROM_DATABASE=F5U224 USB 2.0 4-Port Hub
+
+usb:v050Dp0234*
+ ID_PRODUCT_FROM_DATABASE=F5U234 USB 2.0 4-Port Hub
+
+usb:v050Dp0237*
+ ID_PRODUCT_FROM_DATABASE=F5U237 USB 2.0 7-Port Hub
+
+usb:v050Dp0240*
+ ID_PRODUCT_FROM_DATABASE=F5U240 USB 2.0 CF Card Reader
+
+usb:v050Dp0249*
+ ID_PRODUCT_FROM_DATABASE=USB 2 Flash Media Device
+
+usb:v050Dp0257*
+ ID_PRODUCT_FROM_DATABASE=F5U257 Serial
+
+usb:v050Dp0304*
+ ID_PRODUCT_FROM_DATABASE=FSU304 USB 2.0 - 4 Ports Hub
+
+usb:v050Dp0307*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 - 7 ports Hub [FSU307]
+
+usb:v050Dp0409*
+ ID_PRODUCT_FROM_DATABASE=F5U409 Serial
+
+usb:v050Dp0551*
+ ID_PRODUCT_FROM_DATABASE=F6C550-AVR UPS
+
+usb:v050Dp0706*
+ ID_PRODUCT_FROM_DATABASE=2-N-1 USB 2.0 7-Port Hub (Lower half)
+
+usb:v050Dp0802*
+ ID_PRODUCT_FROM_DATABASE=Nostromo n40 Gamepad
+
+usb:v050Dp0803*
+ ID_PRODUCT_FROM_DATABASE=Nostromo 1745 GamePad
+
+usb:v050Dp0805*
+ ID_PRODUCT_FROM_DATABASE=Nostromo N50 GamePad
+
+usb:v050Dp0815*
+ ID_PRODUCT_FROM_DATABASE=Nostromo n52 HID SpeedPad Mouse Wheel
+
+usb:v050Dp0826*
+ ID_PRODUCT_FROM_DATABASE=ErgoFit Wireless Optical Mouse (HID)
+
+usb:v050Dp0980*
+ ID_PRODUCT_FROM_DATABASE=HID UPS Battery
+
+usb:v050Dp1004*
+ ID_PRODUCT_FROM_DATABASE=F9L1004 802.11n Surf N300 XR Wireless Adapter [Realtek RTL8192CU]
+
+usb:v050Dp1102*
+ ID_PRODUCT_FROM_DATABASE=F7D1102 N150/Surf Micro Wireless Adapter v1000 [Realtek RTL8188CUS]
+
+usb:v050Dp1103*
+ ID_PRODUCT_FROM_DATABASE=F9L1103 N750 DB 802.11abgn 2x3:3 [Ralink RT3573]
+
+usb:v050Dp11F2*
+ ID_PRODUCT_FROM_DATABASE=ISY Wireless Micro Adapter IWL 2000 [RTL8188CUS]
+
+usb:v050Dp1202*
+ ID_PRODUCT_FROM_DATABASE=F5U120-PC Parallel Printer Port
+
+usb:v050Dp1203*
+ ID_PRODUCT_FROM_DATABASE=F5U120-PC Serial Port
+
+usb:v050Dp2103*
+ ID_PRODUCT_FROM_DATABASE=F7D2102 802.11n N300 Micro Wireless Adapter v3000 [Realtek RTL8192CU]
+
+usb:v050Dp258A*
+ ID_PRODUCT_FROM_DATABASE=F5U258 Host to Host cable
+
+usb:v050Dp3101*
+ ID_PRODUCT_FROM_DATABASE=F1DF102U/F1DG102U Flip Hub
+
+usb:v050Dp3201*
+ ID_PRODUCT_FROM_DATABASE=F1DF102U/F1DG102U Flip KVM
+
+usb:v050Dp4050*
+ ID_PRODUCT_FROM_DATABASE=ZD1211B
+
+usb:v050Dp5055*
+ ID_PRODUCT_FROM_DATABASE=F5D5055 Gigabit Network Adapter [AX88xxx]
+
+usb:v050Dp6050*
+ ID_PRODUCT_FROM_DATABASE=F6D6050 802.11abgn Wireless Adapter [Broadcom BCM4323]
+
+usb:v050Dp6051*
+ ID_PRODUCT_FROM_DATABASE=F5D6051 802.11b Wireless Network Adapter [ZyDAS ZD1201]
+
+usb:v050Dp615A*
+ ID_PRODUCT_FROM_DATABASE=F7D4101 / F9L1101 802.11abgn Wireless Adapter [Broadcom BCM4323]
+
+usb:v050Dp7050*
+ ID_PRODUCT_FROM_DATABASE=F5D7050 Wireless G Adapter v1000/v2000 [Intersil ISL3887]
+
+usb:v050Dp7051*
+ ID_PRODUCT_FROM_DATABASE=F5D7051 802.11g Adapter v1000 [Broadcom 4320 USB]
+
+usb:v050Dp705A*
+ ID_PRODUCT_FROM_DATABASE=F5D7050 Wireless G Adapter v3000 [Ralink RT2571W]
+
+usb:v050Dp705B*
+ ID_PRODUCT_FROM_DATABASE=Wireless G Adapter
+
+usb:v050Dp705C*
+ ID_PRODUCT_FROM_DATABASE=F5D7050 Wireless G Adapter v4000 [Zydas ZD1211B]
+
+usb:v050Dp705E*
+ ID_PRODUCT_FROM_DATABASE=F5D7050 Wireless G Adapter v5000 [Realtek RTL8187B]
+
+usb:v050Dp706A*
+ ID_PRODUCT_FROM_DATABASE=2-N-1 7-Port Hub (Upper half)
+
+usb:v050Dp8053*
+ ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless USB Adapter v1000/v4000 [Ralink RT2870]
+
+usb:v050Dp805C*
+ ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless Adapter v3000 [Ralink RT2870]
+
+usb:v050Dp805E*
+ ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless USB Adapter v5000 [Realtek RTL8192U]
+
+usb:v050Dp815C*
+ ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless USB Adapter v3000 [Ralink RT2870]
+
+usb:v050Dp815F*
+ ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless USB Adapter v6000 [Realtek RTL8192SU]
+
+usb:v050Dp825A*
+ ID_PRODUCT_FROM_DATABASE=F5D8055 N+ Wireless Adapter v1000 [Ralink RT2870]
+
+usb:v050Dp825B*
+ ID_PRODUCT_FROM_DATABASE=F5D8055 N+ Wireless Adapter v2000 [Ralink RT3072]
+
+usb:v050Dp845A*
+ ID_PRODUCT_FROM_DATABASE=F7D2101 802.11n Surf & Share Wireless Adapter v1000 [Realtek RTL8192SU]
+
+usb:v050Dp905B*
+ ID_PRODUCT_FROM_DATABASE=F5D9050 Wireless G+ MIMO Network Adapter v3000 [Ralink RT2573]
+
+usb:v050Dp905C*
+ ID_PRODUCT_FROM_DATABASE=F5D9050 Wireless G+ MIMO Network Adapter v4000 [Ralink RT2573]
+
+usb:v050Dp935A*
+ ID_PRODUCT_FROM_DATABASE=F6D4050 N150 Enhanced Wireless Network Adapter v1000 [Ralink RT3070]
+
+usb:v050Dp935B*
+ ID_PRODUCT_FROM_DATABASE=F6D4050 N150 Enhanced Wireless Network Adapter v2000 [Ralink RT3070]
+
+usb:v050Dp945A*
+ ID_PRODUCT_FROM_DATABASE=F7D1101 v1 Basic Wireless Adapter [Realtek RTL8188SU]
+
+usb:v050Dp945B*
+ ID_PRODUCT_FROM_DATABASE=F7D1101 v2 Basic Wireless Adapter [Ralink RT3370]
+
+usb:v050DpD321*
+ ID_PRODUCT_FROM_DATABASE=Dynex DX-NUSB 802.11bgn Wireless Adapter [Broadcom BCM43231]
+
+usb:v050E*
+ ID_VENDOR_FROM_DATABASE=Neon Technology, Inc.
+
+usb:v050F*
+ ID_VENDOR_FROM_DATABASE=KC Technology, Inc.
+
+usb:v050Fp0001*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v050Fp0003*
+ ID_PRODUCT_FROM_DATABASE=KC82C160S Hub
+
+usb:v050Fp0180*
+ ID_PRODUCT_FROM_DATABASE=KC-180 IrDA Dongle
+
+usb:v050Fp0190*
+ ID_PRODUCT_FROM_DATABASE=KC2190 USB Host-to-Host cable
+
+usb:v0510*
+ ID_VENDOR_FROM_DATABASE=Sejin Electron, Inc.
+
+usb:v0510p0001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0510p1000*
+ ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Mouse Port
+
+usb:v0510pE001*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v0511*
+ ID_VENDOR_FROM_DATABASE=N'Able (DataBook) Technologies, Inc.
+
+usb:v0511p002B*
+ ID_PRODUCT_FROM_DATABASE=AOC DVB
+
+usb:v0512*
+ ID_VENDOR_FROM_DATABASE=Hualon Microelectronics Corp.
+
+usb:v0513*
+ ID_VENDOR_FROM_DATABASE=digital-X, Inc.
+
+usb:v0514*
+ ID_VENDOR_FROM_DATABASE=FCI Electronics
+
+usb:v0515*
+ ID_VENDOR_FROM_DATABASE=ACTC
+
+usb:v0516*
+ ID_VENDOR_FROM_DATABASE=Longwell Electronics
+
+usb:v0517*
+ ID_VENDOR_FROM_DATABASE=Butterfly Communications
+
+usb:v0518*
+ ID_VENDOR_FROM_DATABASE=EzKEY Corp.
+
+usb:v0518p0001*
+ ID_PRODUCT_FROM_DATABASE=USB to PS2 Adaptor v1.09
+
+usb:v0518p0002*
+ ID_PRODUCT_FROM_DATABASE=EZ-9900C Keyboard
+
+usb:v0519*
+ ID_VENDOR_FROM_DATABASE=Star Micronics Co., Ltd
+
+usb:v0519p0003*
+ ID_PRODUCT_FROM_DATABASE=TSP100ECO/TSP100II
+
+usb:v0519pC002*
+ ID_PRODUCT_FROM_DATABASE=Xlive Bluetooth XBM-100S MP3 Player
+
+usb:v051A*
+ ID_VENDOR_FROM_DATABASE=WYSE Technology
+
+usb:v051ApA005*
+ ID_PRODUCT_FROM_DATABASE=Smart Display Version 9973
+
+usb:v051B*
+ ID_VENDOR_FROM_DATABASE=Silicon Graphics
+
+usb:v051C*
+ ID_VENDOR_FROM_DATABASE=Shuttle, Inc.
+
+usb:v051Cp0005*
+ ID_PRODUCT_FROM_DATABASE=VFD Module
+
+usb:v051CpC001*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v051CpC002*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v051D*
+ ID_VENDOR_FROM_DATABASE=American Power Conversion
+
+usb:v051Dp0001*
+ ID_PRODUCT_FROM_DATABASE=UPS
+
+usb:v051Dp0002*
+ ID_PRODUCT_FROM_DATABASE=Uninterruptible Power Supply
+
+usb:v051Dp0003*
+ ID_PRODUCT_FROM_DATABASE=UPS
+
+usb:v051E*
+ ID_VENDOR_FROM_DATABASE=Scientific Atlanta, Inc.
+
+usb:v051F*
+ ID_VENDOR_FROM_DATABASE=IO Systems (Elite Electronics), Inc.
+
+usb:v0520*
+ ID_VENDOR_FROM_DATABASE=Taiwan Semiconductor Manufacturing Co.
+
+usb:v0521*
+ ID_VENDOR_FROM_DATABASE=Airborn Connectors
+
+usb:v0522*
+ ID_VENDOR_FROM_DATABASE=Advanced Connectek, Inc.
+
+usb:v0523*
+ ID_VENDOR_FROM_DATABASE=ATEN GmbH
+
+usb:v0524*
+ ID_VENDOR_FROM_DATABASE=Sola Electronics
+
+usb:v0525*
+ ID_VENDOR_FROM_DATABASE=Netchip Technology, Inc.
+
+usb:v0525p100D*
+ ID_PRODUCT_FROM_DATABASE=RFMD Bluetooth Device
+
+usb:v0525p1080*
+ ID_PRODUCT_FROM_DATABASE=NET1080 USB-USB Bridge
+
+usb:v0525p1200*
+ ID_PRODUCT_FROM_DATABASE=SSDC Adapter II
+
+usb:v0525p1265*
+ ID_PRODUCT_FROM_DATABASE=File-backed Storage Gadget
+
+usb:v0525pA0F0*
+ ID_PRODUCT_FROM_DATABASE=Cambridge Electronic Devices Power1401 mk 2
+
+usb:v0525pA140*
+ ID_PRODUCT_FROM_DATABASE=USB Clik! 40
+
+usb:v0525pA141*
+ ID_PRODUCT_FROM_DATABASE=(OME) PocketZip 40 MP3 Player Driver
+
+usb:v0525pA220*
+ ID_PRODUCT_FROM_DATABASE=GVC Bluetooth Wireless Adapter
+
+usb:v0525pA4A0*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB "Gadget Zero"
+
+usb:v0525pA4A1*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB Ethernet Gadget
+
+usb:v0525pA4A2*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB Ethernet/RNDIS Gadget
+
+usb:v0525pA4A3*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB user-mode isochronous source/sink
+
+usb:v0525pA4A4*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB user-mode bulk source/sink
+
+usb:v0525pA4A5*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB File Storage Gadget
+
+usb:v0525pA4A6*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB Serial Gadget
+
+usb:v0525pA4A7*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB Serial Gadget (CDC ACM mode)
+
+usb:v0525pA4A8*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB Printer Gadget
+
+usb:v0525pA4A9*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB OBEX Gadget
+
+usb:v0525pA4AA*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB CDC Composite Gadge (Ethernet and ACM)
+
+usb:v0526*
+ ID_VENDOR_FROM_DATABASE=Temic MHS S.A.
+
+usb:v0527*
+ ID_VENDOR_FROM_DATABASE=ALTRA
+
+usb:v0528*
+ ID_VENDOR_FROM_DATABASE=ATI Technologies, Inc.
+
+usb:v0528p7561*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder
+
+usb:v0528p7562*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FN5)
+
+usb:v0528p7563*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FI)
+
+usb:v0528p7564*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FQ)
+
+usb:v0528p7565*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (NTSC+)
+
+usb:v0528p7566*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FN5)
+
+usb:v0528p7567*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FI)
+
+usb:v0528p7568*
+ ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FQ)
+
+usb:v0528p7569*
+ ID_PRODUCT_FROM_DATABASE=Live! Pro (A)
+
+usb:v0528p756A*
+ ID_PRODUCT_FROM_DATABASE=Live! Pro Audio (O)
+
+usb:v0529*
+ ID_VENDOR_FROM_DATABASE=Aladdin Knowledge Systems
+
+usb:v0529p0001*
+ ID_PRODUCT_FROM_DATABASE=HASP v0.06
+
+usb:v0529p030B*
+ ID_PRODUCT_FROM_DATABASE=eToken R1 v3.1.3.x
+
+usb:v0529p0313*
+ ID_PRODUCT_FROM_DATABASE=eToken R1 v3.2.3.x
+
+usb:v0529p031B*
+ ID_PRODUCT_FROM_DATABASE=eToken R1 v3.3.3.x
+
+usb:v0529p0323*
+ ID_PRODUCT_FROM_DATABASE=eToken R1 v3.4.3.x
+
+usb:v0529p0412*
+ ID_PRODUCT_FROM_DATABASE=eToken R2 v2.2.4.x
+
+usb:v0529p041A*
+ ID_PRODUCT_FROM_DATABASE=eToken R2 v2.2.4.x
+
+usb:v0529p0422*
+ ID_PRODUCT_FROM_DATABASE=eToken R2 v2.4.4.x
+
+usb:v0529p042A*
+ ID_PRODUCT_FROM_DATABASE=eToken R2 v2.5.4.x
+
+usb:v0529p050C*
+ ID_PRODUCT_FROM_DATABASE=eToken Pro v4.1.5.x
+
+usb:v0529p0514*
+ ID_PRODUCT_FROM_DATABASE=eToken Pro v4.2.5.4
+
+usb:v0529p0600*
+ ID_PRODUCT_FROM_DATABASE=eToken Pro 64k (4.2)
+
+usb:v0529p0620*
+ ID_PRODUCT_FROM_DATABASE=Token JC
+
+usb:v052A*
+ ID_VENDOR_FROM_DATABASE=Crescent Heart Software
+
+usb:v052B*
+ ID_VENDOR_FROM_DATABASE=Tekom Technologies, Inc.
+
+usb:v052Bp0102*
+ ID_PRODUCT_FROM_DATABASE=Ca508A HP1020 Camera v.1.3.1.6
+
+usb:v052Bp0801*
+ ID_PRODUCT_FROM_DATABASE=Yakumo MegaImage 37
+
+usb:v052Bp1512*
+ ID_PRODUCT_FROM_DATABASE=Yakumo MegaImage IV
+
+usb:v052Bp1513*
+ ID_PRODUCT_FROM_DATABASE=Aosta CX100 Webcam
+
+usb:v052Bp1514*
+ ID_PRODUCT_FROM_DATABASE=Aosta CX100 Webcam Storage
+
+usb:v052Bp1905*
+ ID_PRODUCT_FROM_DATABASE=Yakumo MegaImage 47
+
+usb:v052Bp1911*
+ ID_PRODUCT_FROM_DATABASE=Yakumo MegaImage 47 SL
+
+usb:v052Bp2202*
+ ID_PRODUCT_FROM_DATABASE=WDM Still Image Capture
+
+usb:v052Bp2203*
+ ID_PRODUCT_FROM_DATABASE=Sound Vision Stream Driver
+
+usb:v052Bp3A06*
+ ID_PRODUCT_FROM_DATABASE=DigiLife DDV-5120A
+
+usb:v052BpD001*
+ ID_PRODUCT_FROM_DATABASE=P35U Camera Capture
+
+usb:v052C*
+ ID_VENDOR_FROM_DATABASE=Canon Information Systems, Inc.
+
+usb:v052D*
+ ID_VENDOR_FROM_DATABASE=Avid Electronics Corp.
+
+usb:v052E*
+ ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp.
+
+usb:v052F*
+ ID_VENDOR_FROM_DATABASE=Unicore Software, Inc.
+
+usb:v0530*
+ ID_VENDOR_FROM_DATABASE=American Microsystems, Inc.
+
+usb:v0531*
+ ID_VENDOR_FROM_DATABASE=Wacom Technology Corp.
+
+usb:v0532*
+ ID_VENDOR_FROM_DATABASE=Systech Corp.
+
+usb:v0533*
+ ID_VENDOR_FROM_DATABASE=Alcatel Mobile Phones
+
+usb:v0534*
+ ID_VENDOR_FROM_DATABASE=Motorola, Inc.
+
+usb:v0535*
+ ID_VENDOR_FROM_DATABASE=LIH TZU Electric Co., Ltd
+
+usb:v0536*
+ ID_VENDOR_FROM_DATABASE=Hand Held Products (Welch Allyn, Inc.)
+
+usb:v0536p01A0*
+ ID_PRODUCT_FROM_DATABASE=PDT
+
+usb:v0537*
+ ID_VENDOR_FROM_DATABASE=Inventec Corp.
+
+usb:v0538*
+ ID_VENDOR_FROM_DATABASE=Caldera International, Inc. (SCO)
+
+usb:v0539*
+ ID_VENDOR_FROM_DATABASE=Shyh Shiun Terminals Co., Ltd
+
+usb:v053A*
+ ID_VENDOR_FROM_DATABASE=PrehKeyTec GmbH
+
+usb:v053Ap0B00*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v053B*
+ ID_VENDOR_FROM_DATABASE=Global Village Communication
+
+usb:v053C*
+ ID_VENDOR_FROM_DATABASE=Institut of Microelectronic & Mechatronic Systems
+
+usb:v053D*
+ ID_VENDOR_FROM_DATABASE=Silicon Architect
+
+usb:v053E*
+ ID_VENDOR_FROM_DATABASE=Mobility Electronics
+
+usb:v053F*
+ ID_VENDOR_FROM_DATABASE=Synopsys, Inc.
+
+usb:v0540*
+ ID_VENDOR_FROM_DATABASE=UniAccess AB
+
+usb:v0540p0101*
+ ID_PRODUCT_FROM_DATABASE=Panache Surf ISDN TA
+
+usb:v0541*
+ ID_VENDOR_FROM_DATABASE=Sirf Technology, Inc.
+
+usb:v0543*
+ ID_VENDOR_FROM_DATABASE=ViewSonic Corp.
+
+usb:v0543p00FE*
+ ID_PRODUCT_FROM_DATABASE=G773 Monitor Hub
+
+usb:v0543p00FF*
+ ID_PRODUCT_FROM_DATABASE=P815 Monitor Hub
+
+usb:v0543p0BF2*
+ ID_PRODUCT_FROM_DATABASE=airpanel V150 Wireless Smart Display
+
+usb:v0543p0BF3*
+ ID_PRODUCT_FROM_DATABASE=airpanel V110 Wireless Smart Display
+
+usb:v0543p0ED9*
+ ID_PRODUCT_FROM_DATABASE=Color Pocket PC V35
+
+usb:v0543p0F01*
+ ID_PRODUCT_FROM_DATABASE=airsync Wi-Fi Wireless Adapter
+
+usb:v0543p1527*
+ ID_PRODUCT_FROM_DATABASE=Color Pocket PC V36
+
+usb:v0543p1529*
+ ID_PRODUCT_FROM_DATABASE=Color Pocket PC V37
+
+usb:v0543p152B*
+ ID_PRODUCT_FROM_DATABASE=Color Pocket PC V38
+
+usb:v0543p152E*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC
+
+usb:v0543p1921*
+ ID_PRODUCT_FROM_DATABASE=Communicator Pocket PC
+
+usb:v0543p1922*
+ ID_PRODUCT_FROM_DATABASE=Smartphone
+
+usb:v0543p1923*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC V30
+
+usb:v0543p1A11*
+ ID_PRODUCT_FROM_DATABASE=Wireless 802.11g Adapter
+
+usb:v0543p1E60*
+ ID_PRODUCT_FROM_DATABASE=TA310 - ATSC/NTSC/PAL Driver(PCM4)
+
+usb:v0543p4153*
+ ID_PRODUCT_FROM_DATABASE=ViewSonic G773 Control (?)
+
+usb:v0544*
+ ID_VENDOR_FROM_DATABASE=Cristie Electronics, Ltd
+
+usb:v0545*
+ ID_VENDOR_FROM_DATABASE=Xirlink, Inc.
+
+usb:v0545p7333*
+ ID_PRODUCT_FROM_DATABASE=Trution Web Camera
+
+usb:v0545p8002*
+ ID_PRODUCT_FROM_DATABASE=IBM NetCamera
+
+usb:v0545p8009*
+ ID_PRODUCT_FROM_DATABASE=Veo PC Camera
+
+usb:v0545p800C*
+ ID_PRODUCT_FROM_DATABASE=Veo Stingray
+
+usb:v0545p800D*
+ ID_PRODUCT_FROM_DATABASE=Veo PC Camera
+
+usb:v0545p8080*
+ ID_PRODUCT_FROM_DATABASE=IBM C-It Webcam
+
+usb:v0545p808A*
+ ID_PRODUCT_FROM_DATABASE=Veo PC Camera
+
+usb:v0545p808B*
+ ID_PRODUCT_FROM_DATABASE=Veo Stingray
+
+usb:v0545p808D*
+ ID_PRODUCT_FROM_DATABASE=Veo PC Camera
+
+usb:v0545p810A*
+ ID_PRODUCT_FROM_DATABASE=Veo Advanced Connect Webcam
+
+usb:v0545p810B*
+ ID_PRODUCT_FROM_DATABASE=Veo PC Camera
+
+usb:v0545p810C*
+ ID_PRODUCT_FROM_DATABASE=Veo PC Camera
+
+usb:v0545p8135*
+ ID_PRODUCT_FROM_DATABASE=Veo Mobile/Advanced Web Camera
+
+usb:v0545p813A*
+ ID_PRODUCT_FROM_DATABASE=Veo PC Camera
+
+usb:v0545p813B*
+ ID_PRODUCT_FROM_DATABASE=Veo PC Camera
+
+usb:v0545p813C*
+ ID_PRODUCT_FROM_DATABASE=Veo Mobile/Advanced Web Camera
+
+usb:v0545p8333*
+ ID_PRODUCT_FROM_DATABASE=Veo Stingray/Connect Web Camera
+
+usb:v0545p888C*
+ ID_PRODUCT_FROM_DATABASE=eVision 123 digital camera
+
+usb:v0545p888D*
+ ID_PRODUCT_FROM_DATABASE=eVision 123 digital camera
+
+usb:v0546*
+ ID_VENDOR_FROM_DATABASE=Polaroid Corp.
+
+usb:v0546p0DAF*
+ ID_PRODUCT_FROM_DATABASE=PDC 2300Z
+
+usb:v0546p1BED*
+ ID_PRODUCT_FROM_DATABASE=PDC 1320 Camera
+
+usb:v0546p3097*
+ ID_PRODUCT_FROM_DATABASE=PDC 310
+
+usb:v0546p3155*
+ ID_PRODUCT_FROM_DATABASE=PDC 3070 Camera
+
+usb:v0546p3187*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0546p3191*
+ ID_PRODUCT_FROM_DATABASE=Ion 80 Camera
+
+usb:v0546p3273*
+ ID_PRODUCT_FROM_DATABASE=PDC 2030 Camera
+
+usb:v0546p3304*
+ ID_PRODUCT_FROM_DATABASE=a500 Digital Camera
+
+usb:v0546pDCCF*
+ ID_PRODUCT_FROM_DATABASE=Sound Vision Stream Driver
+
+usb:v0547*
+ ID_VENDOR_FROM_DATABASE=Anchor Chips, Inc.
+
+usb:v0547p0001*
+ ID_PRODUCT_FROM_DATABASE=ICSI Bluetooth Device
+
+usb:v0547p1002*
+ ID_PRODUCT_FROM_DATABASE=Python2 WDM Encoder
+
+usb:v0547p1006*
+ ID_PRODUCT_FROM_DATABASE=Hantek DSO-2100 UF
+
+usb:v0547p2131*
+ ID_PRODUCT_FROM_DATABASE=AN2131 EZUSB Microcontroller
+
+usb:v0547p2235*
+ ID_PRODUCT_FROM_DATABASE=AN2235 EZUSB-FX Microcontroller
+
+usb:v0547p2710*
+ ID_PRODUCT_FROM_DATABASE=EZ-Link Loader (EZLNKLDR.SYS)
+
+usb:v0547p2720*
+ ID_PRODUCT_FROM_DATABASE=AN2720 USB-USB Bridge
+
+usb:v0547p2727*
+ ID_PRODUCT_FROM_DATABASE=Xircom PGUNET USB-USB Bridge
+
+usb:v0547p2750*
+ ID_PRODUCT_FROM_DATABASE=EZ-Link (EZLNKUSB.SYS)
+
+usb:v0547p2810*
+ ID_PRODUCT_FROM_DATABASE=Cypress ATAPI Bridge
+
+usb:v0547p7777*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0547p9999*
+ ID_PRODUCT_FROM_DATABASE=AN2131 uninitialized (?)
+
+usb:v0548*
+ ID_VENDOR_FROM_DATABASE=Tyan Computer Corp.
+
+usb:v0548p1005*
+ ID_PRODUCT_FROM_DATABASE=EZ Cart II GameBoy Flash Programmer
+
+usb:v0549*
+ ID_VENDOR_FROM_DATABASE=Pixera Corp.
+
+usb:v054A*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Microelectronics, Inc.
+
+usb:v054B*
+ ID_VENDOR_FROM_DATABASE=New Media Corp.
+
+usb:v054C*
+ ID_VENDOR_FROM_DATABASE=Sony Corp.
+
+usb:v054Cp0001*
+ ID_PRODUCT_FROM_DATABASE=HUB
+
+usb:v054Cp0002*
+ ID_PRODUCT_FROM_DATABASE=Standard HUB
+
+usb:v054Cp0010*
+ ID_PRODUCT_FROM_DATABASE=DSC-S30/S70/S75/F505V/F505/FD92/W1 Cybershot/Mavica Digital Camera
+
+usb:v054Cp0014*
+ ID_PRODUCT_FROM_DATABASE=Nogatech USBVision (SY)
+
+usb:v054Cp0022*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 (TPP)
+
+usb:v054Cp0023*
+ ID_PRODUCT_FROM_DATABASE=CD Writer
+
+usb:v054Cp0024*
+ ID_PRODUCT_FROM_DATABASE=Mavica CD-1000 Camera
+
+usb:v054Cp0025*
+ ID_PRODUCT_FROM_DATABASE=NW-MS7 Walkman MemoryStick Reader
+
+usb:v054Cp002B*
+ ID_PRODUCT_FROM_DATABASE=Portable USB Harddrive V2
+
+usb:v054Cp002C*
+ ID_PRODUCT_FROM_DATABASE=USB Floppy Disk Drive
+
+usb:v054Cp002D*
+ ID_PRODUCT_FROM_DATABASE=MSAC-US1 MemoryStick Reader
+
+usb:v054Cp002E*
+ ID_PRODUCT_FROM_DATABASE=HandyCam MemoryStick Reader
+
+usb:v054Cp0030*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 (TPP)
+
+usb:v054Cp0032*
+ ID_PRODUCT_FROM_DATABASE=MemoryStick MSC-U01 Reader
+
+usb:v054Cp0035*
+ ID_PRODUCT_FROM_DATABASE=Network Walkman (E)
+
+usb:v054Cp0036*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0037*
+ ID_PRODUCT_FROM_DATABASE=MG Memory Stick Reader/Writer
+
+usb:v054Cp0038*
+ ID_PRODUCT_FROM_DATABASE=Clie PEG-S300/D PalmOS PDA
+
+usb:v054Cp0039*
+ ID_PRODUCT_FROM_DATABASE=Network Walkman (MS)
+
+usb:v054Cp003C*
+ ID_PRODUCT_FROM_DATABASE=VAIO-MX LCD Control
+
+usb:v054Cp0045*
+ ID_PRODUCT_FROM_DATABASE=Digital Imaging Video
+
+usb:v054Cp0046*
+ ID_PRODUCT_FROM_DATABASE=Network Walkman
+
+usb:v054Cp004A*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Hi-Fi System
+
+usb:v054Cp004B*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v054Cp004E*
+ ID_PRODUCT_FROM_DATABASE=DSC-xxx (ptp)
+
+usb:v054Cp0056*
+ ID_PRODUCT_FROM_DATABASE=MG Memory Stick Reader/Writer
+
+usb:v054Cp0058*
+ ID_PRODUCT_FROM_DATABASE=Clie PEG-N7x0C PalmOS PDA Mass Storage
+
+usb:v054Cp0066*
+ ID_PRODUCT_FROM_DATABASE=Clie PEG-N7x0C/PEG-T425 PalmOS PDA Serial
+
+usb:v054Cp0067*
+ ID_PRODUCT_FROM_DATABASE=CMR-PC3 Webcam
+
+usb:v054Cp0069*
+ ID_PRODUCT_FROM_DATABASE=Memorystick MSC-U03 Reader
+
+usb:v054Cp006C*
+ ID_PRODUCT_FROM_DATABASE=FeliCa S310 [PaSoRi]
+
+usb:v054Cp006D*
+ ID_PRODUCT_FROM_DATABASE=Clie PEG-T425 PDA Mass Storage
+
+usb:v054Cp006F*
+ ID_PRODUCT_FROM_DATABASE=Network Walkman (EV)
+
+usb:v054Cp0073*
+ ID_PRODUCT_FROM_DATABASE=Storage CRX1750U
+
+usb:v054Cp0075*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0076*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter ACR-U20
+
+usb:v054Cp007C*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp007F*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (MS)
+
+usb:v054Cp0080*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0081*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0084*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0085*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0086*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp008B*
+ ID_PRODUCT_FROM_DATABASE=Micro Vault 64M Mass Storage
+
+usb:v054Cp0095*
+ ID_PRODUCT_FROM_DATABASE=Clie s360
+
+usb:v054Cp0099*
+ ID_PRODUCT_FROM_DATABASE=Clie NR70 PDA Mass Storage
+
+usb:v054Cp009A*
+ ID_PRODUCT_FROM_DATABASE=Clie NR70 PDA Serial
+
+usb:v054Cp00AB*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera (PCGA-UVC10)
+
+usb:v054Cp00AF*
+ ID_PRODUCT_FROM_DATABASE=DPP-EX Series Digital Photo Printer
+
+usb:v054Cp00BF*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (S)
+
+usb:v054Cp00C0*
+ ID_PRODUCT_FROM_DATABASE=Handycam DCR-30
+
+usb:v054Cp00C6*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp00C7*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp00C8*
+ ID_PRODUCT_FROM_DATABASE=MZ-N710 Minidisc Walkman
+
+usb:v054Cp00C9*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp00CA*
+ ID_PRODUCT_FROM_DATABASE=MZ-DN430 Minidisc Walkman
+
+usb:v054Cp00CB*
+ ID_PRODUCT_FROM_DATABASE=MSAC-US20 Memory Stick Reader
+
+usb:v054Cp00DA*
+ ID_PRODUCT_FROM_DATABASE=Clie nx60
+
+usb:v054Cp00E8*
+ ID_PRODUCT_FROM_DATABASE=Network Walkman (MS)
+
+usb:v054Cp00E9*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v054Cp00EB*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0101*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0103*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (ST)
+
+usb:v054Cp0105*
+ ID_PRODUCT_FROM_DATABASE=Micro Vault Hub
+
+usb:v054Cp0107*
+ ID_PRODUCT_FROM_DATABASE=VCC-U01 Visual Communication Camera
+
+usb:v054Cp0110*
+ ID_PRODUCT_FROM_DATABASE=Digital Imaging Video
+
+usb:v054Cp0113*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0116*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (P)
+
+usb:v054Cp0144*
+ ID_PRODUCT_FROM_DATABASE=Clie PEG-TH55 PDA
+
+usb:v054Cp0147*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera (PCGA-UVC11)
+
+usb:v054Cp014C*
+ ID_PRODUCT_FROM_DATABASE=Aiwa AM-NX9 Net MD Music Recorder MDLP
+
+usb:v054Cp014D*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer
+
+usb:v054Cp0154*
+ ID_PRODUCT_FROM_DATABASE=Eyetoy Audio Device
+
+usb:v054Cp015F*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (BM)
+
+usb:v054Cp0169*
+ ID_PRODUCT_FROM_DATABASE=Clie PEG-TJ35 PDA Serial
+
+usb:v054Cp016A*
+ ID_PRODUCT_FROM_DATABASE=Clie PEG-TJ35 PDA Mass Storage
+
+usb:v054Cp016B*
+ ID_PRODUCT_FROM_DATABASE=Mobile HDD
+
+usb:v054Cp016D*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (SX)
+
+usb:v054Cp016E*
+ ID_PRODUCT_FROM_DATABASE=DPP-EX50 Digital Photo Printer
+
+usb:v054Cp0171*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Sensor 3500
+
+usb:v054Cp017E*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp017F*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp0180*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0181*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp0182*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0183*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp0184*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0185*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp0186*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0187*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD MZ-NH600 WALKMAN
+
+usb:v054Cp0188*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp018A*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp018B*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD SOUND GATE
+
+usb:v054Cp019E*
+ ID_PRODUCT_FROM_DATABASE=Micro Vault 1.0G Mass Storage
+
+usb:v054Cp01AD*
+ ID_PRODUCT_FROM_DATABASE=ATRAC HDD PA
+
+usb:v054Cp01BB*
+ ID_PRODUCT_FROM_DATABASE=FeliCa S320 [PaSoRi]
+
+usb:v054Cp01BD*
+ ID_PRODUCT_FROM_DATABASE=MRW62E Multi-Card Reader/Writer
+
+usb:v054Cp01C3*
+ ID_PRODUCT_FROM_DATABASE=NW-E55 Network Walkman
+
+usb:v054Cp01C6*
+ ID_PRODUCT_FROM_DATABASE=MEMORY P-AUDIO
+
+usb:v054Cp01C7*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v054Cp01C8*
+ ID_PRODUCT_FROM_DATABASE=PSP Type A
+
+usb:v054Cp01C9*
+ ID_PRODUCT_FROM_DATABASE=PSP Type B
+
+usb:v054Cp01D0*
+ ID_PRODUCT_FROM_DATABASE=DVD+RW External Drive DRU-700A
+
+usb:v054Cp01D5*
+ ID_PRODUCT_FROM_DATABASE=IC RECORDER
+
+usb:v054Cp01DE*
+ ID_PRODUCT_FROM_DATABASE=VRD-VC10 [Video Capture]
+
+usb:v054Cp01E9*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp01EA*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp01EE*
+ ID_PRODUCT_FROM_DATABASE=IC RECORDER
+
+usb:v054Cp01FA*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (P)
+
+usb:v054Cp01FB*
+ ID_PRODUCT_FROM_DATABASE=NW-E405 Network Walkman
+
+usb:v054Cp020F*
+ ID_PRODUCT_FROM_DATABASE=Device
+
+usb:v054Cp0210*
+ ID_PRODUCT_FROM_DATABASE=ATRAC HDD PA
+
+usb:v054Cp0219*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp021A*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp021B*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp021C*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp021D*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0227*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v054Cp022C*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp022D*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD AUDIO
+
+usb:v054Cp0233*
+ ID_PRODUCT_FROM_DATABASE=ATRAC HDD PA
+
+usb:v054Cp0236*
+ ID_PRODUCT_FROM_DATABASE=Mobile HDD
+
+usb:v054Cp023B*
+ ID_PRODUCT_FROM_DATABASE=DVD+RW External Drive DRU-800UL
+
+usb:v054Cp023C*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp023D*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp0243*
+ ID_PRODUCT_FROM_DATABASE=MicroVault Flash Drive
+
+usb:v054Cp024B*
+ ID_PRODUCT_FROM_DATABASE=Vaio VGX Mouse
+
+usb:v054Cp0257*
+ ID_PRODUCT_FROM_DATABASE=IFU-WLM2 USB Wireless LAN Module (Wireless Mode)
+
+usb:v054Cp0258*
+ ID_PRODUCT_FROM_DATABASE=IFU-WLM2 USB Wireless LAN Module (Memory Mode)
+
+usb:v054Cp0259*
+ ID_PRODUCT_FROM_DATABASE=IC RECORDER
+
+usb:v054Cp0267*
+ ID_PRODUCT_FROM_DATABASE=Tachikoma Device
+
+usb:v054Cp0268*
+ ID_PRODUCT_FROM_DATABASE=Batoh Device / PlayStation 3 Controller
+
+usb:v054Cp0269*
+ ID_PRODUCT_FROM_DATABASE=HDD WALKMAN
+
+usb:v054Cp026A*
+ ID_PRODUCT_FROM_DATABASE=HDD WALKMAN
+
+usb:v054Cp0271*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (P)
+
+usb:v054Cp027C*
+ ID_PRODUCT_FROM_DATABASE=NETWORK WALKMAN
+
+usb:v054Cp027E*
+ ID_PRODUCT_FROM_DATABASE=SONY Communicator
+
+usb:v054Cp027F*
+ ID_PRODUCT_FROM_DATABASE=IC RECORDER
+
+usb:v054Cp0286*
+ ID_PRODUCT_FROM_DATABASE=Net MD
+
+usb:v054Cp0287*
+ ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN
+
+usb:v054Cp0290*
+ ID_PRODUCT_FROM_DATABASE=VGP-UVC100 Visual Communication Camera
+
+usb:v054Cp029B*
+ ID_PRODUCT_FROM_DATABASE=PRS-500 eBook reader
+
+usb:v054Cp02A5*
+ ID_PRODUCT_FROM_DATABASE=MicroVault Flash Drive
+
+usb:v054Cp02AF*
+ ID_PRODUCT_FROM_DATABASE=Handycam DCR-DVD306E
+
+usb:v054Cp02C4*
+ ID_PRODUCT_FROM_DATABASE=Device
+
+usb:v054Cp02D1*
+ ID_PRODUCT_FROM_DATABASE=DVD RW
+
+usb:v054Cp02D2*
+ ID_PRODUCT_FROM_DATABASE=PSP Slim
+
+usb:v054Cp02E1*
+ ID_PRODUCT_FROM_DATABASE=FeliCa S330 [PaSoRi]
+
+usb:v054Cp02EA*
+ ID_PRODUCT_FROM_DATABASE=PlayStation 3 Memory Card Adaptor
+
+usb:v054Cp02F9*
+ ID_PRODUCT_FROM_DATABASE=DSC-H9
+
+usb:v054Cp0317*
+ ID_PRODUCT_FROM_DATABASE=WALKMAN
+
+usb:v054Cp031A*
+ ID_PRODUCT_FROM_DATABASE=Walkman NWD-B103F
+
+usb:v054Cp031E*
+ ID_PRODUCT_FROM_DATABASE=PRS-300/PRS-505 eBook reader
+
+usb:v054Cp0325*
+ ID_PRODUCT_FROM_DATABASE=NWZ-A818
+
+usb:v054Cp033E*
+ ID_PRODUCT_FROM_DATABASE=DSC-W120/W290
+
+usb:v054Cp0346*
+ ID_PRODUCT_FROM_DATABASE=Handycam DCR-SR55E
+
+usb:v054Cp0348*
+ ID_PRODUCT_FROM_DATABASE=HandyCam HDR-TG3E
+
+usb:v054Cp035B*
+ ID_PRODUCT_FROM_DATABASE=Walkman NWZ-A828
+
+usb:v054Cp035C*
+ ID_PRODUCT_FROM_DATABASE=NWZ-A726/A728/A729
+
+usb:v054Cp0382*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick PRO-HG Duo Adaptor (MSAC-UAH1)
+
+usb:v054Cp0385*
+ ID_PRODUCT_FROM_DATABASE=Walkman NWZ-E436F
+
+usb:v054Cp0387*
+ ID_PRODUCT_FROM_DATABASE=IC Recorder (P)
+
+usb:v054Cp03BC*
+ ID_PRODUCT_FROM_DATABASE=Webbie HD - MHS-CM1
+
+usb:v054Cp03D3*
+ ID_PRODUCT_FROM_DATABASE=DR-BT100CX
+
+usb:v054Cp03D5*
+ ID_PRODUCT_FROM_DATABASE=PlayStation Move motion controller
+
+usb:v054Cp03FC*
+ ID_PRODUCT_FROM_DATABASE=WALKMAN [NWZ-E345]
+
+usb:v054Cp03FD*
+ ID_PRODUCT_FROM_DATABASE=Walkman NWZ-E443
+
+usb:v054Cp042F*
+ ID_PRODUCT_FROM_DATABASE=PlayStation Move navigation controller
+
+usb:v054Cp0440*
+ ID_PRODUCT_FROM_DATABASE=DSC-H55
+
+usb:v054Cp0485*
+ ID_PRODUCT_FROM_DATABASE=MHS-PM5 HD camcorder
+
+usb:v054Cp04CB*
+ ID_PRODUCT_FROM_DATABASE=WALKMAN NWZ-E354
+
+usb:v054Cp1000*
+ ID_PRODUCT_FROM_DATABASE=Wireless Buzz! Receiver
+
+usb:v054D*
+ ID_VENDOR_FROM_DATABASE=Try Corp.
+
+usb:v054E*
+ ID_VENDOR_FROM_DATABASE=Proside Corp.
+
+usb:v054F*
+ ID_VENDOR_FROM_DATABASE=WYSE Technology Taiwan
+
+usb:v0550*
+ ID_VENDOR_FROM_DATABASE=Fuji Xerox Co., Ltd
+
+usb:v0550p0002*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v0550p0004*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v0550p0005*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v0551*
+ ID_VENDOR_FROM_DATABASE=CompuTrend Systems, Inc.
+
+usb:v0552*
+ ID_VENDOR_FROM_DATABASE=Philips Monitors
+
+usb:v0553*
+ ID_VENDOR_FROM_DATABASE=STMicroelectronics Imaging Division (VLSI Vision)
+
+usb:v0553p0001*
+ ID_PRODUCT_FROM_DATABASE=TerraCAM
+
+usb:v0553p0002*
+ ID_PRODUCT_FROM_DATABASE=CPiA Webcam
+
+usb:v0553p0100*
+ ID_PRODUCT_FROM_DATABASE=STV0672 Camera
+
+usb:v0553p0140*
+ ID_PRODUCT_FROM_DATABASE=Video Camera
+
+usb:v0553p0150*
+ ID_PRODUCT_FROM_DATABASE=CDE CAM 100
+
+usb:v0553p0151*
+ ID_PRODUCT_FROM_DATABASE=Digital Blue QX5 Microscope
+
+usb:v0553p0200*
+ ID_PRODUCT_FROM_DATABASE=Dual-mode Camera0
+
+usb:v0553p0201*
+ ID_PRODUCT_FROM_DATABASE=Dual-mode Camera1
+
+usb:v0553p0202*
+ ID_PRODUCT_FROM_DATABASE=Aiptek PenCam 1
+
+usb:v0553p0674*
+ ID_PRODUCT_FROM_DATABASE=Multi-mode Camera
+
+usb:v0553p0679*
+ ID_PRODUCT_FROM_DATABASE=NMS Video Camera (Webcam)
+
+usb:v0553p1002*
+ ID_PRODUCT_FROM_DATABASE=Che-ez! Splash
+
+usb:v0554*
+ ID_VENDOR_FROM_DATABASE=Dictaphone Corp.
+
+usb:v0555*
+ ID_VENDOR_FROM_DATABASE=ANAM S&T Co., Ltd
+
+usb:v0556*
+ ID_VENDOR_FROM_DATABASE=Asahi Kasei Microsystems Co., Ltd
+
+usb:v0556p0001*
+ ID_PRODUCT_FROM_DATABASE=AK5370 I/F A/D Converter
+
+usb:v0557*
+ ID_VENDOR_FROM_DATABASE=ATEN International Co., Ltd
+
+usb:v0557p2001*
+ ID_PRODUCT_FROM_DATABASE=UC-1284 Printer Port
+
+usb:v0557p2002*
+ ID_PRODUCT_FROM_DATABASE=10Mbps Ethernet [klsi]
+
+usb:v0557p2004*
+ ID_PRODUCT_FROM_DATABASE=UC-100KM PS/2 Mouse and Keyboard adapter
+
+usb:v0557p2006*
+ ID_PRODUCT_FROM_DATABASE=UC-1284B Printer Port
+
+usb:v0557p2007*
+ ID_PRODUCT_FROM_DATABASE=UC-110T 100Mbps Ethernet [pegasus]
+
+usb:v0557p2008*
+ ID_PRODUCT_FROM_DATABASE=UC-232A Serial Port [pl2303]
+
+usb:v0557p2009*
+ ID_PRODUCT_FROM_DATABASE=UC-210T Ethernet
+
+usb:v0557p2011*
+ ID_PRODUCT_FROM_DATABASE=UC-2324 4xSerial Ports [mos7840]
+
+usb:v0557p2202*
+ ID_PRODUCT_FROM_DATABASE=CS124U Miniview II KVM Switch
+
+usb:v0557p2213*
+ ID_PRODUCT_FROM_DATABASE=CS682 2-Port USB 2.0 DVI KVM Switch
+
+usb:v0557p2221*
+ ID_PRODUCT_FROM_DATABASE=Winbond Hermon
+
+usb:v0557p2404*
+ ID_PRODUCT_FROM_DATABASE=4-port switch
+
+usb:v0557p2600*
+ ID_PRODUCT_FROM_DATABASE=IDE Bridge
+
+usb:v0557p2701*
+ ID_PRODUCT_FROM_DATABASE=CE700A KVM Extender
+
+usb:v0557p4000*
+ ID_PRODUCT_FROM_DATABASE=DSB-650 10Mbps Ethernet [klsi]
+
+usb:v0557p7000*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0557p7820*
+ ID_PRODUCT_FROM_DATABASE=UC-2322 2xSerial Ports [mos7820]
+
+usb:v0558*
+ ID_VENDOR_FROM_DATABASE=Truevision, Inc.
+
+usb:v0558p1009*
+ ID_PRODUCT_FROM_DATABASE=GW Instek GDS-1000 Oscilloscope
+
+usb:v0558p100A*
+ ID_PRODUCT_FROM_DATABASE=GW Instek GDS-1000A Oscilloscope
+
+usb:v0558p2009*
+ ID_PRODUCT_FROM_DATABASE=GW Instek GDS-2000 Oscilloscope
+
+usb:v0559*
+ ID_VENDOR_FROM_DATABASE=Cadence Design Systems, Inc.
+
+usb:v055A*
+ ID_VENDOR_FROM_DATABASE=Kenwood USA
+
+usb:v055B*
+ ID_VENDOR_FROM_DATABASE=KnowledgeTek, Inc.
+
+usb:v055C*
+ ID_VENDOR_FROM_DATABASE=Proton Electronic Ind.
+
+usb:v055D*
+ ID_VENDOR_FROM_DATABASE=Samsung Electro-Mechanics Co.
+
+usb:v055Dp0001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v055Dp0BB1*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v055Dp1030*
+ ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse (OMS3CB/OMGB30)
+
+usb:v055Dp1031*
+ ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse (OMA3CB/OMGI30)
+
+usb:v055Dp1040*
+ ID_PRODUCT_FROM_DATABASE=Mouse HID Device
+
+usb:v055Dp1050*
+ ID_PRODUCT_FROM_DATABASE=E-Mail Optical Wheel Mouse (OMS3CE)
+
+usb:v055Dp1080*
+ ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse (OMS3CH)
+
+usb:v055Dp2020*
+ ID_PRODUCT_FROM_DATABASE=Floppy Disk Drive
+
+usb:v055Dp6780*
+ ID_PRODUCT_FROM_DATABASE=Keyboard V1
+
+usb:v055Dp6781*
+ ID_PRODUCT_FROM_DATABASE=Keyboard Mouse
+
+usb:v055Dp8001*
+ ID_PRODUCT_FROM_DATABASE=E.M. Hub
+
+usb:v055Dp9000*
+ ID_PRODUCT_FROM_DATABASE=AnyCam [pwc]
+
+usb:v055Dp9001*
+ ID_PRODUCT_FROM_DATABASE=MPC-C30 AnyCam Premium for Notebooks [pwc]
+
+usb:v055DpA000*
+ ID_PRODUCT_FROM_DATABASE=SWL-2100U
+
+usb:v055DpA010*
+ ID_PRODUCT_FROM_DATABASE=WLAN Adapter(SWL-2300)
+
+usb:v055DpA011*
+ ID_PRODUCT_FROM_DATABASE=Boot Device
+
+usb:v055DpA012*
+ ID_PRODUCT_FROM_DATABASE=WLAN Adapter(SWL-2300)
+
+usb:v055DpA013*
+ ID_PRODUCT_FROM_DATABASE=WLAN Adapter(SWL-2350)
+
+usb:v055DpA230*
+ ID_PRODUCT_FROM_DATABASE=Boot Device
+
+usb:v055DpB000*
+ ID_PRODUCT_FROM_DATABASE=11Mbps WLAN Mini Adapter
+
+usb:v055DpB230*
+ ID_PRODUCT_FROM_DATABASE=Netopia 802.11b WLAN Adapter
+
+usb:v055DpB231*
+ ID_PRODUCT_FROM_DATABASE=LG Wireless LAN 11b Adapter
+
+usb:v055E*
+ ID_VENDOR_FROM_DATABASE=CTX Opto-Electronics Corp.
+
+usb:v055F*
+ ID_VENDOR_FROM_DATABASE=Mustek Systems, Inc.
+
+usb:v055Fp0001*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 CU
+
+usb:v055Fp0002*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress 600 CU
+
+usb:v055Fp0003*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 USB
+
+usb:v055Fp0006*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 UB
+
+usb:v055Fp0007*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 USB Plus
+
+usb:v055Fp0008*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 CU Plus
+
+usb:v055Fp0010*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 1200F
+
+usb:v055Fp0210*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress A3 USB
+
+usb:v055Fp0218*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 2400 TA
+
+usb:v055Fp0219*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 2400 TA Plus
+
+usb:v055Fp021A*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 2448 TA Plus
+
+usb:v055Fp021B*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 1200 CU Plus
+
+usb:v055Fp021C*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 1200 CU Plus
+
+usb:v055Fp021D*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 2400 CU Plus
+
+usb:v055Fp021E*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 1200 TA/CS
+
+usb:v055Fp021F*
+ ID_PRODUCT_FROM_DATABASE=SNAPSCAN e22
+
+usb:v055Fp0400*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 2400 TA Pro
+
+usb:v055Fp0401*
+ ID_PRODUCT_FROM_DATABASE=P 3600 A3 Pro
+
+usb:v055Fp0408*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 2448 CU Pro
+
+usb:v055Fp0409*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 2448 TA Pro
+
+usb:v055Fp040B*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress A3 USB 1200 PRO
+
+usb:v055Fp0873*
+ ID_PRODUCT_FROM_DATABASE=ScanExpress 600 USB
+
+usb:v055Fp1000*
+ ID_PRODUCT_FROM_DATABASE=BearPaw 4800 TA Pro
+
+usb:v055FpA350*
+ ID_PRODUCT_FROM_DATABASE=gSmart 350 Camera
+
+usb:v055FpA800*
+ ID_PRODUCT_FROM_DATABASE=MDC 800 Camera
+
+usb:v055FpB500*
+ ID_PRODUCT_FROM_DATABASE=MDC 3000 Camera
+
+usb:v055FpC005*
+ ID_PRODUCT_FROM_DATABASE=PC CAM 300A
+
+usb:v055FpC200*
+ ID_PRODUCT_FROM_DATABASE=gSmart 300
+
+usb:v055FpC211*
+ ID_PRODUCT_FROM_DATABASE=Kowa Bs888e Microcamera
+
+usb:v055FpC220*
+ ID_PRODUCT_FROM_DATABASE=gSmart mini
+
+usb:v055FpC230*
+ ID_PRODUCT_FROM_DATABASE=Digicam 330K
+
+usb:v055FpC232*
+ ID_PRODUCT_FROM_DATABASE=MDC3500 Camera
+
+usb:v055FpC360*
+ ID_PRODUCT_FROM_DATABASE=DV 4000 Camera
+
+usb:v055FpC420*
+ ID_PRODUCT_FROM_DATABASE=gSmart mini 2 Camera
+
+usb:v055FpC430*
+ ID_PRODUCT_FROM_DATABASE=gSmart LCD 2 Camera
+
+usb:v055FpC440*
+ ID_PRODUCT_FROM_DATABASE=DV 3000 Camera
+
+usb:v055FpC520*
+ ID_PRODUCT_FROM_DATABASE=gSmart mini 3 Camera
+
+usb:v055FpC530*
+ ID_PRODUCT_FROM_DATABASE=gSmart LCD 2 Camera
+
+usb:v055FpC540*
+ ID_PRODUCT_FROM_DATABASE=gSmart D30 Camera
+
+usb:v055FpC630*
+ ID_PRODUCT_FROM_DATABASE=MDC 4000 Camera
+
+usb:v055FpC631*
+ ID_PRODUCT_FROM_DATABASE=MDC 4000 Camera
+
+usb:v055FpC650*
+ ID_PRODUCT_FROM_DATABASE=MDC 5500Z Camera
+
+usb:v055FpD001*
+ ID_PRODUCT_FROM_DATABASE=WCam 300
+
+usb:v055FpD003*
+ ID_PRODUCT_FROM_DATABASE=WCam 300A
+
+usb:v055FpD004*
+ ID_PRODUCT_FROM_DATABASE=WCam 300AN
+
+usb:v0560*
+ ID_VENDOR_FROM_DATABASE=Interface Corp.
+
+usb:v0561*
+ ID_VENDOR_FROM_DATABASE=Oasis Design, Inc.
+
+usb:v0562*
+ ID_VENDOR_FROM_DATABASE=Telex Communications, Inc.
+
+usb:v0562p0001*
+ ID_PRODUCT_FROM_DATABASE=Enhanced Microphone
+
+usb:v0562p0002*
+ ID_PRODUCT_FROM_DATABASE=Telex Microphone
+
+usb:v0563*
+ ID_VENDOR_FROM_DATABASE=Immersion Corp.
+
+usb:v0564*
+ ID_VENDOR_FROM_DATABASE=Kodak Digital Product Center, Japan Ltd. (formerly Chinon Industries Inc.)
+
+usb:v0565*
+ ID_VENDOR_FROM_DATABASE=Peracom Networks, Inc.
+
+usb:v0565p0001*
+ ID_PRODUCT_FROM_DATABASE=Serial Port [etek]
+
+usb:v0565p0002*
+ ID_PRODUCT_FROM_DATABASE=Enet Ethernet [klsi]
+
+usb:v0565p0003*
+ ID_PRODUCT_FROM_DATABASE=@Home Networks Ethernet [klsi]
+
+usb:v0565p0005*
+ ID_PRODUCT_FROM_DATABASE=Enet2 Ethernet [klsi]
+
+usb:v0565p0041*
+ ID_PRODUCT_FROM_DATABASE=Peracom Remote NDIS Ethernet Adapter
+
+usb:v0566*
+ ID_VENDOR_FROM_DATABASE=Monterey International Corp.
+
+usb:v0566p0110*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v0566p1001*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v0566p1002*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v0566p1003*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v0566p1004*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v0566p1005*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v0566p1006*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v0566p1007*
+ ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201
+
+usb:v0566p2800*
+ ID_PRODUCT_FROM_DATABASE=MIC K/B
+
+usb:v0566p2801*
+ ID_PRODUCT_FROM_DATABASE=MIC K/B Mouse
+
+usb:v0566p2802*
+ ID_PRODUCT_FROM_DATABASE=Kbd Hub
+
+usb:v0566p3004*
+ ID_PRODUCT_FROM_DATABASE=Genius KB-29E
+
+usb:v0566p3107*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0567*
+ ID_VENDOR_FROM_DATABASE=Xyratex International, Ltd
+
+usb:v0568*
+ ID_VENDOR_FROM_DATABASE=Quartz Ingenierie
+
+usb:v0569*
+ ID_VENDOR_FROM_DATABASE=SegaSoft
+
+usb:v056A*
+ ID_VENDOR_FROM_DATABASE=Wacom Co., Ltd
+
+usb:v056Ap0000*
+ ID_PRODUCT_FROM_DATABASE=PenPartner
+
+usb:v056Ap0001*
+ ID_PRODUCT_FROM_DATABASE=PenPartner 4x5
+
+usb:v056Ap0002*
+ ID_PRODUCT_FROM_DATABASE=PenPartner 6x8
+
+usb:v056Ap0003*
+ ID_PRODUCT_FROM_DATABASE=Cintiq Partner
+
+usb:v056Ap0010*
+ ID_PRODUCT_FROM_DATABASE=Graphire
+
+usb:v056Ap0011*
+ ID_PRODUCT_FROM_DATABASE=Graphire 2 4x5
+
+usb:v056Ap0012*
+ ID_PRODUCT_FROM_DATABASE=Graphire 2 5x7
+
+usb:v056Ap0013*
+ ID_PRODUCT_FROM_DATABASE=Graphire 3 4x5
+
+usb:v056Ap0014*
+ ID_PRODUCT_FROM_DATABASE=Graphire 3 6x8
+
+usb:v056Ap0015*
+ ID_PRODUCT_FROM_DATABASE=Graphire 4 4x5
+
+usb:v056Ap0016*
+ ID_PRODUCT_FROM_DATABASE=Graphire 4 6x8
+
+usb:v056Ap0017*
+ ID_PRODUCT_FROM_DATABASE=CTE-450 [Bamboo Fun]
+
+usb:v056Ap0018*
+ ID_PRODUCT_FROM_DATABASE=Bamboo Fun 6x8
+
+usb:v056Ap0019*
+ ID_PRODUCT_FROM_DATABASE=Bamboo One Medium
+
+usb:v056Ap0020*
+ ID_PRODUCT_FROM_DATABASE=Intuos 4x5
+
+usb:v056Ap0021*
+ ID_PRODUCT_FROM_DATABASE=Intuos 6x8
+
+usb:v056Ap0022*
+ ID_PRODUCT_FROM_DATABASE=Intuos 9x12
+
+usb:v056Ap0023*
+ ID_PRODUCT_FROM_DATABASE=Intuos 12x12
+
+usb:v056Ap0024*
+ ID_PRODUCT_FROM_DATABASE=Intuos 12x18
+
+usb:v056Ap0026*
+ ID_PRODUCT_FROM_DATABASE=Intuos5 touch S
+
+usb:v056Ap0027*
+ ID_PRODUCT_FROM_DATABASE=Intuos5 touch M
+
+usb:v056Ap0028*
+ ID_PRODUCT_FROM_DATABASE=Intuos5 touch L
+
+usb:v056Ap0029*
+ ID_PRODUCT_FROM_DATABASE=Intuos5 S
+
+usb:v056Ap002A*
+ ID_PRODUCT_FROM_DATABASE=Intuos5 M
+
+usb:v056Ap0030*
+ ID_PRODUCT_FROM_DATABASE=PL400
+
+usb:v056Ap0031*
+ ID_PRODUCT_FROM_DATABASE=PL500
+
+usb:v056Ap0032*
+ ID_PRODUCT_FROM_DATABASE=PL600
+
+usb:v056Ap0033*
+ ID_PRODUCT_FROM_DATABASE=PL600SX
+
+usb:v056Ap0034*
+ ID_PRODUCT_FROM_DATABASE=PL550
+
+usb:v056Ap0035*
+ ID_PRODUCT_FROM_DATABASE=PL800
+
+usb:v056Ap0037*
+ ID_PRODUCT_FROM_DATABASE=PL700
+
+usb:v056Ap0038*
+ ID_PRODUCT_FROM_DATABASE=PL510
+
+usb:v056Ap0039*
+ ID_PRODUCT_FROM_DATABASE=DTU-710
+
+usb:v056Ap003F*
+ ID_PRODUCT_FROM_DATABASE=Cintiq 21UX (DTZ-2100)
+
+usb:v056Ap0041*
+ ID_PRODUCT_FROM_DATABASE=Intuos2 4x5
+
+usb:v056Ap0042*
+ ID_PRODUCT_FROM_DATABASE=Intuos2 6x8
+
+usb:v056Ap0043*
+ ID_PRODUCT_FROM_DATABASE=Intuos2 9x12
+
+usb:v056Ap0044*
+ ID_PRODUCT_FROM_DATABASE=Intuos2 12x12
+
+usb:v056Ap0045*
+ ID_PRODUCT_FROM_DATABASE=Intuos2 12x18
+
+usb:v056Ap0047*
+ ID_PRODUCT_FROM_DATABASE=Intuos2 6x8
+
+usb:v056Ap0060*
+ ID_PRODUCT_FROM_DATABASE=Volito
+
+usb:v056Ap0061*
+ ID_PRODUCT_FROM_DATABASE=PenStation2
+
+usb:v056Ap0062*
+ ID_PRODUCT_FROM_DATABASE=Volito2 4x5
+
+usb:v056Ap0063*
+ ID_PRODUCT_FROM_DATABASE=Volito2 2x3
+
+usb:v056Ap0064*
+ ID_PRODUCT_FROM_DATABASE=PenPartner2
+
+usb:v056Ap0065*
+ ID_PRODUCT_FROM_DATABASE=Bamboo
+
+usb:v056Ap0069*
+ ID_PRODUCT_FROM_DATABASE=Bamboo One
+
+usb:v056Ap0081*
+ ID_PRODUCT_FROM_DATABASE=Graphire Wireless 6x8
+
+usb:v056Ap0090*
+ ID_PRODUCT_FROM_DATABASE=TPC90
+
+usb:v056Ap0093*
+ ID_PRODUCT_FROM_DATABASE=TPC93
+
+usb:v056Ap009A*
+ ID_PRODUCT_FROM_DATABASE=TPC9A
+
+usb:v056Ap00B0*
+ ID_PRODUCT_FROM_DATABASE=Intuos3 4x5
+
+usb:v056Ap00B1*
+ ID_PRODUCT_FROM_DATABASE=Intuos3 6x18
+
+usb:v056Ap00B2*
+ ID_PRODUCT_FROM_DATABASE=Intuos3 9x12
+
+usb:v056Ap00B3*
+ ID_PRODUCT_FROM_DATABASE=Intuos3 12x12
+
+usb:v056Ap00B4*
+ ID_PRODUCT_FROM_DATABASE=Intuos3 12x19
+
+usb:v056Ap00B5*
+ ID_PRODUCT_FROM_DATABASE=Intuos3 6x11 (PTZ-631W)
+
+usb:v056Ap00B7*
+ ID_PRODUCT_FROM_DATABASE=Intuos3 4x6
+
+usb:v056Ap00B8*
+ ID_PRODUCT_FROM_DATABASE=Intuos4 4x6
+
+usb:v056Ap00B9*
+ ID_PRODUCT_FROM_DATABASE=Intuos4 6x9
+
+usb:v056Ap00BA*
+ ID_PRODUCT_FROM_DATABASE=Intuos4 8x13
+
+usb:v056Ap00BB*
+ ID_PRODUCT_FROM_DATABASE=Intuos4 12x19
+
+usb:v056Ap00C0*
+ ID_PRODUCT_FROM_DATABASE=DTF-521
+
+usb:v056Ap00C4*
+ ID_PRODUCT_FROM_DATABASE=DTF-720
+
+usb:v056Ap00C5*
+ ID_PRODUCT_FROM_DATABASE=Cintiq 20WSX
+
+usb:v056Ap00C6*
+ ID_PRODUCT_FROM_DATABASE=Cintiq 12WX
+
+usb:v056Ap00C7*
+ ID_PRODUCT_FROM_DATABASE=DTU-1931
+
+usb:v056Ap00CC*
+ ID_PRODUCT_FROM_DATABASE=Cintiq 21UX (DTK-2100)
+
+usb:v056Ap00D1*
+ ID_PRODUCT_FROM_DATABASE=Bamboo Pen & Touch (CTH-460-DE)
+
+usb:v056Ap00D3*
+ ID_PRODUCT_FROM_DATABASE=Bamboo Fun (CTH-661)
+
+usb:v056Ap00D6*
+ ID_PRODUCT_FROM_DATABASE=Bamboo Pen & Touch (CTH-460)
+
+usb:v056Ap00DB*
+ ID_PRODUCT_FROM_DATABASE=Bamboo Fun (CTH-661SE-NL)
+
+usb:v056Ap00DD*
+ ID_PRODUCT_FROM_DATABASE=Bamboo Pen (CTL-470)
+
+usb:v056Ap00F6*
+ ID_PRODUCT_FROM_DATABASE=Cintiq 24HD touch (DTH-2400) touchscreen
+
+usb:v056Ap00F8*
+ ID_PRODUCT_FROM_DATABASE=Cintiq 24HD touch (DTH-2400) tablet
+
+usb:v056Ap0400*
+ ID_PRODUCT_FROM_DATABASE=PenPartner 4x5
+
+usb:v056Ap4850*
+ ID_PRODUCT_FROM_DATABASE=PenPartner 6x8
+
+usb:v056B*
+ ID_VENDOR_FROM_DATABASE=Decicon, Inc.
+
+usb:v056C*
+ ID_VENDOR_FROM_DATABASE=eTEK Labs
+
+usb:v056Cp0006*
+ ID_PRODUCT_FROM_DATABASE=KwikLink Host-Host Connector
+
+usb:v056Cp8007*
+ ID_PRODUCT_FROM_DATABASE=Kwik232 Serial Port
+
+usb:v056Cp8100*
+ ID_PRODUCT_FROM_DATABASE=KwikLink Host-Host Connector
+
+usb:v056Cp8101*
+ ID_PRODUCT_FROM_DATABASE=KwikLink USB-USB Bridge
+
+usb:v056D*
+ ID_VENDOR_FROM_DATABASE=EIZO Corp.
+
+usb:v056Dp0000*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v056Dp0001*
+ ID_PRODUCT_FROM_DATABASE=Monitor
+
+usb:v056Dp0002*
+ ID_PRODUCT_FROM_DATABASE=HID Monitor Controls
+
+usb:v056Dp0003*
+ ID_PRODUCT_FROM_DATABASE=Device Bay Controller
+
+usb:v056E*
+ ID_VENDOR_FROM_DATABASE=Elecom Co., Ltd
+
+usb:v056Ep0002*
+ ID_PRODUCT_FROM_DATABASE=29UO Mouse
+
+usb:v056Ep0072*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v056Ep200C*
+ ID_PRODUCT_FROM_DATABASE=LD-USB/TX
+
+usb:v056Ep4002*
+ ID_PRODUCT_FROM_DATABASE=Laneed 100Mbps Ethernet LD-USB/TX [pegasus]
+
+usb:v056Ep4005*
+ ID_PRODUCT_FROM_DATABASE=LD-USBL/TX
+
+usb:v056Ep400B*
+ ID_PRODUCT_FROM_DATABASE=LD-USB/TX
+
+usb:v056Ep4010*
+ ID_PRODUCT_FROM_DATABASE=LD-USB20
+
+usb:v056Ep5003*
+ ID_PRODUCT_FROM_DATABASE=UC-SGT
+
+usb:v056Ep5004*
+ ID_PRODUCT_FROM_DATABASE=UC-SGT
+
+usb:v056Ep6008*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk
+
+usb:v056EpABC1*
+ ID_PRODUCT_FROM_DATABASE=LD-USB/TX
+
+usb:v056F*
+ ID_VENDOR_FROM_DATABASE=Korea Data Systems Co., Ltd
+
+usb:v056FpCD00*
+ ID_PRODUCT_FROM_DATABASE=CDM-751 CD organizer
+
+usb:v0570*
+ ID_VENDOR_FROM_DATABASE=Epson America
+
+usb:v0571*
+ ID_VENDOR_FROM_DATABASE=Interex, Inc.
+
+usb:v0571p0002*
+ ID_PRODUCT_FROM_DATABASE=echoFX InterView Lite
+
+usb:v0572*
+ ID_VENDOR_FROM_DATABASE=Conexant Systems (Rockwell), Inc.
+
+usb:v0572p0001*
+ ID_PRODUCT_FROM_DATABASE=Ezcam II Webcam
+
+usb:v0572p0002*
+ ID_PRODUCT_FROM_DATABASE=Ezcam II Webcam
+
+usb:v0572p0040*
+ ID_PRODUCT_FROM_DATABASE=Wondereye CP-115 Webcam
+
+usb:v0572p0041*
+ ID_PRODUCT_FROM_DATABASE=Webcam Notebook
+
+usb:v0572p0042*
+ ID_PRODUCT_FROM_DATABASE=Webcam Notebook
+
+usb:v0572p1232*
+ ID_PRODUCT_FROM_DATABASE=V.90 modem
+
+usb:v0572p1234*
+ ID_PRODUCT_FROM_DATABASE=Typhoon Redfun Modem V90 56k
+
+usb:v0572p1252*
+ ID_PRODUCT_FROM_DATABASE=HCF V90 Data Fax Voice Modem
+
+usb:v0572p1253*
+ ID_PRODUCT_FROM_DATABASE=Zoom V.92 Faxmodem
+
+usb:v0572p1300*
+ ID_PRODUCT_FROM_DATABASE=SoftK56 Data Fax Voice CARP
+
+usb:v0572p1301*
+ ID_PRODUCT_FROM_DATABASE=Modem Enumerator
+
+usb:v0572p1328*
+ ID_PRODUCT_FROM_DATABASE=TrendNet TFM-561 modem
+
+usb:v0572p2000*
+ ID_PRODUCT_FROM_DATABASE=SoftGate 802.11 Adapter
+
+usb:v0572p2002*
+ ID_PRODUCT_FROM_DATABASE=SoftGate 802.11 Adapter
+
+usb:v0572p262A*
+ ID_PRODUCT_FROM_DATABASE=tm5600 Video & Audio Grabber Capture
+
+usb:v0572p8390*
+ ID_PRODUCT_FROM_DATABASE=WinFast PalmTop/Novo TV Video
+
+usb:v0572p8392*
+ ID_PRODUCT_FROM_DATABASE=WinFast PalmTop/Novo TV Video
+
+usb:v0572pCAFE*
+ ID_PRODUCT_FROM_DATABASE=AccessRunner ADSL Modem
+
+usb:v0572pCB00*
+ ID_PRODUCT_FROM_DATABASE=ADSL Modem
+
+usb:v0572pCB01*
+ ID_PRODUCT_FROM_DATABASE=ADSL Modem
+
+usb:v0572pCB06*
+ ID_PRODUCT_FROM_DATABASE=StarModem Network Interface
+
+usb:v0573*
+ ID_VENDOR_FROM_DATABASE=Zoran Co. Personal Media Division (Nogatech)
+
+usb:v0573p0003*
+ ID_PRODUCT_FROM_DATABASE=USBGear USBG-V1
+
+usb:v0573p0400*
+ ID_PRODUCT_FROM_DATABASE=D-Link V100
+
+usb:v0573p0600*
+ ID_PRODUCT_FROM_DATABASE=Dazzle USBVision (1006)
+
+usb:v0573p1300*
+ ID_PRODUCT_FROM_DATABASE=leadtek USBVision (1006)
+
+usb:v0573p2000*
+ ID_PRODUCT_FROM_DATABASE=X10 va10a Wireless Camera
+
+usb:v0573p2001*
+ ID_PRODUCT_FROM_DATABASE=Dazzle EmMe (2001)
+
+usb:v0573p2101*
+ ID_PRODUCT_FROM_DATABASE=Zoran Co. PMD (Nogatech) AV-grabber Manhattan
+
+usb:v0573p2D00*
+ ID_PRODUCT_FROM_DATABASE=Osprey 50
+
+usb:v0573p2D01*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge USB-Live Model 600
+
+usb:v0573p3000*
+ ID_PRODUCT_FROM_DATABASE=Dazzle MicroCam (NTSC)
+
+usb:v0573p3001*
+ ID_PRODUCT_FROM_DATABASE=Dazzle MicroCam (PAL)
+
+usb:v0573p4000*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! (NTSC)
+
+usb:v0573p4001*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! (PAL)
+
+usb:v0573p4002*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! (PAL-I-)
+
+usb:v0573p4003*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! (MF-)
+
+usb:v0573p4008*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! (NTSC) (T)
+
+usb:v0573p4009*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! (PAL) (T)
+
+usb:v0573p4010*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! (NTSC) (A)
+
+usb:v0573p4100*
+ ID_PRODUCT_FROM_DATABASE=USB-TV FM (NTSC)
+
+usb:v0573p4110*
+ ID_PRODUCT_FROM_DATABASE=PNY USB-TV (NTSC) FM
+
+usb:v0573p4400*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (NTSC)
+
+usb:v0573p4401*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (PAL)
+
+usb:v0573p4450*
+ ID_PRODUCT_FROM_DATABASE=PixelView PlayTv-USB PRO (PAL) FM
+
+usb:v0573p4451*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (PAL+)
+
+usb:v0573p4452*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (PAL-I+)
+
+usb:v0573p4500*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (NTSC)
+
+usb:v0573p4501*
+ ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (PAL)
+
+usb:v0573p4550*
+ ID_PRODUCT_FROM_DATABASE=ZTV ZT-721 2.4GHz A/V Receiver
+
+usb:v0573p4551*
+ ID_PRODUCT_FROM_DATABASE=Dazzle TV! Pro Audio (P+)
+
+usb:v0573p4D00*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB USA
+
+usb:v0573p4D01*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB
+
+usb:v0573p4D02*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB UK
+
+usb:v0573p4D03*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB France
+
+usb:v0573p4D04*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV (PAL D/K)
+
+usb:v0573p4D10*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB with FM USA radio
+
+usb:v0573p4D11*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB (PAL) with FM radio
+
+usb:v0573p4D12*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB UK with FM Radio
+
+usb:v0573p4D14*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV (PAL D/K FM)
+
+usb:v0573p4D20*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB II (PAL) with FM radio
+
+usb:v0573p4D21*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB II (PAL)
+
+usb:v0573p4D22*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB II (PAL) Model 566
+
+usb:v0573p4D23*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB France 4D23
+
+usb:v0573p4D24*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (PAL D/K)
+
+usb:v0573p4D25*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40209 rev B234
+
+usb:v0573p4D26*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40209 rev B243
+
+usb:v0573p4D27*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40204 Rev B281
+
+usb:v0573p4D28*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40204 rev B283
+
+usb:v0573p4D29*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40205 rev B298
+
+usb:v0573p4D2A*
+ ID_PRODUCT_FROM_DATABASE=Hauppague WinTV-USB Model 602 Rev B285
+
+usb:v0573p4D2B*
+ ID_PRODUCT_FROM_DATABASE=Hauppague WinTV-USB Model 602 Rev B282
+
+usb:v0573p4D2C*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (PAL/SECAM)
+
+usb:v0573p4D30*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB FM Model 40211 Rev B123
+
+usb:v0573p4D31*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB III (PAL) with FM radio Model 568
+
+usb:v0573p4D32*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB III (PAL) FM Model 573
+
+usb:v0573p4D34*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (PAL D/K FM)
+
+usb:v0573p4D35*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB III (PAL) FM Model 597
+
+usb:v0573p4D36*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (PAL B/G FM)
+
+usb:v0573p4D37*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40219 rev E189
+
+usb:v0573p4D38*
+ ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (NTSC FM)
+
+usb:v0574*
+ ID_VENDOR_FROM_DATABASE=City University of Hong Kong
+
+usb:v0575*
+ ID_VENDOR_FROM_DATABASE=Philips Creative Display Solutions
+
+usb:v0576*
+ ID_VENDOR_FROM_DATABASE=BAFO/Quality Computer Accessories
+
+usb:v0577*
+ ID_VENDOR_FROM_DATABASE=ELSA
+
+usb:v0578*
+ ID_VENDOR_FROM_DATABASE=Intrinsix Corp.
+
+usb:v0579*
+ ID_VENDOR_FROM_DATABASE=GVC Corp.
+
+usb:v057A*
+ ID_VENDOR_FROM_DATABASE=Samsung Electronics America
+
+usb:v057B*
+ ID_VENDOR_FROM_DATABASE=Y-E Data, Inc.
+
+usb:v057Bp0000*
+ ID_PRODUCT_FROM_DATABASE=FlashBuster-U Floppy
+
+usb:v057Bp0001*
+ ID_PRODUCT_FROM_DATABASE=Tri-Media Reader Floppy
+
+usb:v057Bp0006*
+ ID_PRODUCT_FROM_DATABASE=Tri-Media Reader Card Reader
+
+usb:v057Bp0010*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader Writer
+
+usb:v057Bp0020*
+ ID_PRODUCT_FROM_DATABASE=HEXA Media Drive 6-in-1 Card Reader Writer
+
+usb:v057Bp0030*
+ ID_PRODUCT_FROM_DATABASE=Memory Card Viewer (TV)
+
+usb:v057C*
+ ID_VENDOR_FROM_DATABASE=AVM GmbH
+
+usb:v057Cp0B00*
+ ID_PRODUCT_FROM_DATABASE=ISDN-Controller B1 Family
+
+usb:v057Cp0C00*
+ ID_PRODUCT_FROM_DATABASE=ISDN-Controller FRITZ!Card
+
+usb:v057Cp1000*
+ ID_PRODUCT_FROM_DATABASE=ISDN-Controller FRITZ!Card v2.0
+
+usb:v057Cp1900*
+ ID_PRODUCT_FROM_DATABASE=ISDN-Controller FRITZ!Card v2.1
+
+usb:v057Cp2000*
+ ID_PRODUCT_FROM_DATABASE=ISDN-Connector FRITZ!X
+
+usb:v057Cp2200*
+ ID_PRODUCT_FROM_DATABASE=BlueFRITZ!
+
+usb:v057Cp2300*
+ ID_PRODUCT_FROM_DATABASE=Teledat X130 DSL
+
+usb:v057Cp2800*
+ ID_PRODUCT_FROM_DATABASE=ISDN-Connector TA
+
+usb:v057Cp3200*
+ ID_PRODUCT_FROM_DATABASE=Teledat X130 DSL
+
+usb:v057Cp3500*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Card DSL SL
+
+usb:v057Cp3701*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Box SL
+
+usb:v057Cp3702*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Box
+
+usb:v057Cp3800*
+ ID_PRODUCT_FROM_DATABASE=BlueFRITZ! Bluetooth Stick
+
+usb:v057Cp3A00*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Box Fon
+
+usb:v057Cp3C00*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Box WLAN
+
+usb:v057Cp3D00*
+ ID_PRODUCT_FROM_DATABASE=Fritz!Box
+
+usb:v057Cp3E01*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Box (Annex A)
+
+usb:v057Cp4001*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Box Fon (Annex A)
+
+usb:v057Cp4101*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Box WLAN (Annex A)
+
+usb:v057Cp4201*
+ ID_PRODUCT_FROM_DATABASE=FRITZ!Box Fon WLAN (Annex A)
+
+usb:v057Cp4601*
+ ID_PRODUCT_FROM_DATABASE=Eumex 5520PC (WinXP/2000)
+
+usb:v057Cp4602*
+ ID_PRODUCT_FROM_DATABASE=Eumex 400 (WinXP/2000)
+
+usb:v057Cp4701*
+ ID_PRODUCT_FROM_DATABASE=AVM FRITZ!Box Fon ata
+
+usb:v057Cp5401*
+ ID_PRODUCT_FROM_DATABASE=Eumex 300 IP
+
+usb:v057Cp5601*
+ ID_PRODUCT_FROM_DATABASE=AVM Fritz!WLAN [Texas Instruments TNETW1450]
+
+usb:v057Cp6201*
+ ID_PRODUCT_FROM_DATABASE=AVM Fritz!WLAN v1.1 [Texas Instruments TNETW1450]
+
+usb:v057Cp62FF*
+ ID_PRODUCT_FROM_DATABASE=AVM Fritz!WLAN USB (in CD-ROM-mode)
+
+usb:v057Cp8401*
+ ID_PRODUCT_FROM_DATABASE=Fritz!WLAN N [Atheros AR9001U]
+
+usb:v057Cp8402*
+ ID_PRODUCT_FROM_DATABASE=Fritz!WLAN N 2.4 [Atheros AR9001U]
+
+usb:v057Cp8403*
+ ID_PRODUCT_FROM_DATABASE=Fritz!WLAN N v2 [Atheros AR9271]
+
+usb:v057Cp84FF*
+ ID_PRODUCT_FROM_DATABASE=AVM Fritz!WLAN USB N (in CD-ROM-mode)
+
+usb:v057D*
+ ID_VENDOR_FROM_DATABASE=Shark Multimedia, Inc.
+
+usb:v057E*
+ ID_VENDOR_FROM_DATABASE=Nintendo Co., Ltd
+
+usb:v057Ep0305*
+ ID_PRODUCT_FROM_DATABASE=Broadcom BCM2045A Bluetooth Radio [Nintendo Wii]
+
+usb:v057Ep0306*
+ ID_PRODUCT_FROM_DATABASE=Wii Remote Controller RVL-003
+
+usb:v057F*
+ ID_VENDOR_FROM_DATABASE=QuickShot, Ltd
+
+usb:v057Fp6238*
+ ID_PRODUCT_FROM_DATABASE=USB StrikePad
+
+usb:v0580*
+ ID_VENDOR_FROM_DATABASE=Denron, Inc.
+
+usb:v0581*
+ ID_VENDOR_FROM_DATABASE=Racal Data Group
+
+usb:v0582*
+ ID_VENDOR_FROM_DATABASE=Roland Corp.
+
+usb:v0582p0000*
+ ID_PRODUCT_FROM_DATABASE=UA-100
+
+usb:v0582p0002*
+ ID_PRODUCT_FROM_DATABASE=UM-4/MPU-64 MIDI Interface
+
+usb:v0582p0003*
+ ID_PRODUCT_FROM_DATABASE=SoundCanvas SC-8850
+
+usb:v0582p0004*
+ ID_PRODUCT_FROM_DATABASE=U-8
+
+usb:v0582p0005*
+ ID_PRODUCT_FROM_DATABASE=Edirol UM-2 MIDI Adapter
+
+usb:v0582p0007*
+ ID_PRODUCT_FROM_DATABASE=SoundCanvas SC-8820
+
+usb:v0582p0008*
+ ID_PRODUCT_FROM_DATABASE=PC-300
+
+usb:v0582p0009*
+ ID_PRODUCT_FROM_DATABASE=Edirol UM-1SX MIDI Adapter
+
+usb:v0582p000B*
+ ID_PRODUCT_FROM_DATABASE=SK-500
+
+usb:v0582p000C*
+ ID_PRODUCT_FROM_DATABASE=SC-D70
+
+usb:v0582p0010*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-5
+
+usb:v0582p0011*
+ ID_PRODUCT_FROM_DATABASE=Edirol UA-5 Sound Capture
+
+usb:v0582p0012*
+ ID_PRODUCT_FROM_DATABASE=XV-5050
+
+usb:v0582p0013*
+ ID_PRODUCT_FROM_DATABASE=XV-5050
+
+usb:v0582p0014*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UM-880 MIDI I/F (native)
+
+usb:v0582p0015*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UM-880 MIDI I/F (generic)
+
+usb:v0582p0016*
+ ID_PRODUCT_FROM_DATABASE=EDIROL SD-90
+
+usb:v0582p0017*
+ ID_PRODUCT_FROM_DATABASE=EDIROL SD-90
+
+usb:v0582p0018*
+ ID_PRODUCT_FROM_DATABASE=UA-1A
+
+usb:v0582p001B*
+ ID_PRODUCT_FROM_DATABASE=MMP-2
+
+usb:v0582p001C*
+ ID_PRODUCT_FROM_DATABASE=MMP-2
+
+usb:v0582p001D*
+ ID_PRODUCT_FROM_DATABASE=V-SYNTH
+
+usb:v0582p001E*
+ ID_PRODUCT_FROM_DATABASE=V-SYNTH
+
+usb:v0582p0023*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UM-550
+
+usb:v0582p0024*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UM-550
+
+usb:v0582p0025*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-20
+
+usb:v0582p0026*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-20
+
+usb:v0582p0027*
+ ID_PRODUCT_FROM_DATABASE=EDIROL SD-20
+
+usb:v0582p0028*
+ ID_PRODUCT_FROM_DATABASE=EDIROL SD-20
+
+usb:v0582p0029*
+ ID_PRODUCT_FROM_DATABASE=EDIROL SD-80
+
+usb:v0582p002A*
+ ID_PRODUCT_FROM_DATABASE=EDIROL SD-80
+
+usb:v0582p002B*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-700
+
+usb:v0582p002C*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-700
+
+usb:v0582p002D*
+ ID_PRODUCT_FROM_DATABASE=XV-2020 Synthesizer
+
+usb:v0582p002E*
+ ID_PRODUCT_FROM_DATABASE=XV-2020 Synthesizer
+
+usb:v0582p002F*
+ ID_PRODUCT_FROM_DATABASE=VariOS
+
+usb:v0582p0030*
+ ID_PRODUCT_FROM_DATABASE=VariOS
+
+usb:v0582p0033*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR
+
+usb:v0582p0034*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR
+
+usb:v0582p0037*
+ ID_PRODUCT_FROM_DATABASE=Digital Piano
+
+usb:v0582p0038*
+ ID_PRODUCT_FROM_DATABASE=Digital Piano
+
+usb:v0582p003B*
+ ID_PRODUCT_FROM_DATABASE=BOSS GS-10
+
+usb:v0582p003C*
+ ID_PRODUCT_FROM_DATABASE=BOSS GS-10
+
+usb:v0582p0040*
+ ID_PRODUCT_FROM_DATABASE=GI-20
+
+usb:v0582p0041*
+ ID_PRODUCT_FROM_DATABASE=GI-20
+
+usb:v0582p0042*
+ ID_PRODUCT_FROM_DATABASE=RS-70
+
+usb:v0582p0043*
+ ID_PRODUCT_FROM_DATABASE=RS-70
+
+usb:v0582p0044*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-1000
+
+usb:v0582p0047*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UR-80 WAVE
+
+usb:v0582p0048*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UR-80 MIDI
+
+usb:v0582p0049*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UR-80 WAVE
+
+usb:v0582p004A*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UR-80 MIDI
+
+usb:v0582p004B*
+ ID_PRODUCT_FROM_DATABASE=EDIROL M-100FX
+
+usb:v0582p004C*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR-A WAVE
+
+usb:v0582p004D*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR-A MIDI
+
+usb:v0582p004E*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR-A WAVE
+
+usb:v0582p004F*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR-A MIDI
+
+usb:v0582p0050*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-3FX
+
+usb:v0582p0052*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UM-1SX
+
+usb:v0582p0054*
+ ID_PRODUCT_FROM_DATABASE=Digital Piano
+
+usb:v0582p0060*
+ ID_PRODUCT_FROM_DATABASE=EXR Series
+
+usb:v0582p0064*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR-1 WAVE
+
+usb:v0582p0065*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR-1 MIDI
+
+usb:v0582p0066*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR-1 WAVE
+
+usb:v0582p0067*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PCR-1 MIDI
+
+usb:v0582p006A*
+ ID_PRODUCT_FROM_DATABASE=SP-606
+
+usb:v0582p006B*
+ ID_PRODUCT_FROM_DATABASE=SP-606
+
+usb:v0582p006D*
+ ID_PRODUCT_FROM_DATABASE=FANTOM-X
+
+usb:v0582p006E*
+ ID_PRODUCT_FROM_DATABASE=FANTOM-X
+
+usb:v0582p0073*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-25
+
+usb:v0582p0074*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-25
+
+usb:v0582p0075*
+ ID_PRODUCT_FROM_DATABASE=BOSS DR-880
+
+usb:v0582p0076*
+ ID_PRODUCT_FROM_DATABASE=BOSS DR-880
+
+usb:v0582p007A*
+ ID_PRODUCT_FROM_DATABASE=RD
+
+usb:v0582p007B*
+ ID_PRODUCT_FROM_DATABASE=RD
+
+usb:v0582p007D*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-101
+
+usb:v0582p0080*
+ ID_PRODUCT_FROM_DATABASE=G-70
+
+usb:v0582p0081*
+ ID_PRODUCT_FROM_DATABASE=G-70
+
+usb:v0582p008B*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PC-50
+
+usb:v0582p008C*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PC-50
+
+usb:v0582p008D*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-101 USB1
+
+usb:v0582p0092*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PC-80 WAVE
+
+usb:v0582p0093*
+ ID_PRODUCT_FROM_DATABASE=EDIROL PC-80 MIDI
+
+usb:v0582p0096*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-1EX
+
+usb:v0582p009A*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UM-3EX
+
+usb:v0582p009D*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UM-1
+
+usb:v0582p00A2*
+ ID_PRODUCT_FROM_DATABASE=Digital Piano
+
+usb:v0582p00A3*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-4FX
+
+usb:v0582p00A6*
+ ID_PRODUCT_FROM_DATABASE=Juno-G
+
+usb:v0582p00AD*
+ ID_PRODUCT_FROM_DATABASE=SH-201
+
+usb:v0582p00B2*
+ ID_PRODUCT_FROM_DATABASE=VG-99
+
+usb:v0582p00B3*
+ ID_PRODUCT_FROM_DATABASE=VG-99
+
+usb:v0582p00C4*
+ ID_PRODUCT_FROM_DATABASE=EDIROL M-16DX
+
+usb:v0582p00DB*
+ ID_PRODUCT_FROM_DATABASE=BOSS GT-10 Guitar Effects Processor
+
+usb:v0582p00DE*
+ ID_PRODUCT_FROM_DATABASE=Fantom-G7
+
+usb:v0582p00E6*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-25EX (Advanced mode)
+
+usb:v0582p00E7*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-25EX
+
+usb:v0582p010F*
+ ID_PRODUCT_FROM_DATABASE=A-PRO
+
+usb:v0582p0110*
+ ID_PRODUCT_FROM_DATABASE=A-PRO
+
+usb:v0582p0505*
+ ID_PRODUCT_FROM_DATABASE=EDIROL UA-101
+
+usb:v0583*
+ ID_VENDOR_FROM_DATABASE=Padix Co., Ltd (Rockfire)
+
+usb:v0583p0001*
+ ID_PRODUCT_FROM_DATABASE=4 Axis 12 button +POV
+
+usb:v0583p0002*
+ ID_PRODUCT_FROM_DATABASE=4 Axis 12 button +POV
+
+usb:v0583p2030*
+ ID_PRODUCT_FROM_DATABASE=RM-203 USB Nest [mode 1]
+
+usb:v0583p2031*
+ ID_PRODUCT_FROM_DATABASE=RM-203 USB Nest [mode 2]
+
+usb:v0583p2032*
+ ID_PRODUCT_FROM_DATABASE=RM-203 USB Nest [mode 3]
+
+usb:v0583p2033*
+ ID_PRODUCT_FROM_DATABASE=RM-203 USB Nest [mode 4]
+
+usb:v0583p2050*
+ ID_PRODUCT_FROM_DATABASE=PX-205 PSX Bridge
+
+usb:v0583p205F*
+ ID_PRODUCT_FROM_DATABASE=PSX/USB converter
+
+usb:v0583p206F*
+ ID_PRODUCT_FROM_DATABASE=USB, 2-axis 8-button gamepad
+
+usb:v0583p3050*
+ ID_PRODUCT_FROM_DATABASE=QF-305u Gamepad
+
+usb:v0583p3379*
+ ID_PRODUCT_FROM_DATABASE=Rockfire X-Force
+
+usb:v0583p337F*
+ ID_PRODUCT_FROM_DATABASE=Rockfire USB RacingStar Vibra
+
+usb:v0583p509F*
+ ID_PRODUCT_FROM_DATABASE=USB,4-Axis,12-Button with POV
+
+usb:v0583p5259*
+ ID_PRODUCT_FROM_DATABASE=Rockfire USB SkyShuttle Vibra
+
+usb:v0583p525F*
+ ID_PRODUCT_FROM_DATABASE=USB Vibration Pad
+
+usb:v0583p5308*
+ ID_PRODUCT_FROM_DATABASE=USB Wireless VibrationPad
+
+usb:v0583p5359*
+ ID_PRODUCT_FROM_DATABASE=Rockfire USB SkyShuttle Pro
+
+usb:v0583p535F*
+ ID_PRODUCT_FROM_DATABASE=USB,real VibrationPad
+
+usb:v0583p5659*
+ ID_PRODUCT_FROM_DATABASE=Rockfire USB SkyShuttle Vibra
+
+usb:v0583p565F*
+ ID_PRODUCT_FROM_DATABASE=USB VibrationPad
+
+usb:v0583p6009*
+ ID_PRODUCT_FROM_DATABASE=Revenger
+
+usb:v0583p600F*
+ ID_PRODUCT_FROM_DATABASE=USB,GameBoard II
+
+usb:v0583p6258*
+ ID_PRODUCT_FROM_DATABASE=USB, 4-axis, 6-button joystick w/view finder
+
+usb:v0583p6889*
+ ID_PRODUCT_FROM_DATABASE=Windstorm Pro
+
+usb:v0583p688F*
+ ID_PRODUCT_FROM_DATABASE=QF-688uv Windstorm Pro Joystick
+
+usb:v0583p7070*
+ ID_PRODUCT_FROM_DATABASE=QF-707u Bazooka Joystick
+
+usb:v0583pA000*
+ ID_PRODUCT_FROM_DATABASE=MaxFire G-08XU Gamepad
+
+usb:v0583pA015*
+ ID_PRODUCT_FROM_DATABASE=4-Axis,16-Button with POV
+
+usb:v0583pA019*
+ ID_PRODUCT_FROM_DATABASE=USB, Vibration ,4-axis, 8-button joystick w/view finder
+
+usb:v0583pA020*
+ ID_PRODUCT_FROM_DATABASE=USB,4-Axis,10-Button with POV
+
+usb:v0583pA021*
+ ID_PRODUCT_FROM_DATABASE=USB,4-Axis,12-Button with POV
+
+usb:v0583pA022*
+ ID_PRODUCT_FROM_DATABASE=USB,4-Axis,14-Button with POV
+
+usb:v0583pA023*
+ ID_PRODUCT_FROM_DATABASE=USB,4-Axis,16-Button with POV
+
+usb:v0583pA024*
+ ID_PRODUCT_FROM_DATABASE=4axis,12button vibrition audio gamepad
+
+usb:v0583pA025*
+ ID_PRODUCT_FROM_DATABASE=4axis,12button vibrition audio gamepad
+
+usb:v0583pA130*
+ ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Gamepad
+
+usb:v0583pA131*
+ ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Joystick
+
+usb:v0583pA132*
+ ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Wheelpad
+
+usb:v0583pA133*
+ ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Wheel&Gamepad
+
+usb:v0583pA202*
+ ID_PRODUCT_FROM_DATABASE=ForceFeedbackWheel
+
+usb:v0583pA209*
+ ID_PRODUCT_FROM_DATABASE=MetalStrike FF
+
+usb:v0583pB000*
+ ID_PRODUCT_FROM_DATABASE=USB,4-Axis,12-Button with POV
+
+usb:v0583pB001*
+ ID_PRODUCT_FROM_DATABASE=USB,4-Axis,12-Button with POV
+
+usb:v0583pB002*
+ ID_PRODUCT_FROM_DATABASE=Vibration,12-Button USB Wheel
+
+usb:v0583pB005*
+ ID_PRODUCT_FROM_DATABASE=USB,12-Button Wheel
+
+usb:v0583pB008*
+ ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Wheel
+
+usb:v0583pB009*
+ ID_PRODUCT_FROM_DATABASE=USB,12-Button  Wheel
+
+usb:v0583pB00A*
+ ID_PRODUCT_FROM_DATABASE=PSX/USB converter
+
+usb:v0583pB00B*
+ ID_PRODUCT_FROM_DATABASE=PSX/USB converter
+
+usb:v0583pB00C*
+ ID_PRODUCT_FROM_DATABASE=PSX/USB converter
+
+usb:v0583pB00D*
+ ID_PRODUCT_FROM_DATABASE=PSX/USB converter
+
+usb:v0583pB00E*
+ ID_PRODUCT_FROM_DATABASE=4-Axis,12-Button with POV
+
+usb:v0583pB00F*
+ ID_PRODUCT_FROM_DATABASE=USB,5-Axis,10-Button with POV
+
+usb:v0583pB010*
+ ID_PRODUCT_FROM_DATABASE=MetalStrike Pro
+
+usb:v0583pB012*
+ ID_PRODUCT_FROM_DATABASE=Wireless MetalStrike
+
+usb:v0583pB013*
+ ID_PRODUCT_FROM_DATABASE=USB,Wiress  2.4GHZ Joystick
+
+usb:v0583pB016*
+ ID_PRODUCT_FROM_DATABASE=USB,5-Axis,10-Button with POV
+
+usb:v0583pB018*
+ ID_PRODUCT_FROM_DATABASE=TW6 Wheel
+
+usb:v0583pFF60*
+ ID_PRODUCT_FROM_DATABASE=USB Wireless VibrationPad
+
+usb:v0584*
+ ID_VENDOR_FROM_DATABASE=RATOC System, Inc.
+
+usb:v0584p0008*
+ ID_PRODUCT_FROM_DATABASE=Fujifilm MemoryCard ReaderWriter
+
+usb:v0584p0220*
+ ID_PRODUCT_FROM_DATABASE=U2SCX SCSI Converter
+
+usb:v0584pB000*
+ ID_PRODUCT_FROM_DATABASE=REX-USB60
+
+usb:v0584pB020*
+ ID_PRODUCT_FROM_DATABASE=REX-USB60F
+
+usb:v0585*
+ ID_VENDOR_FROM_DATABASE=FlashPoint Technology, Inc.
+
+usb:v0585p0001*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p0002*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p0003*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p0004*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p0005*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p0006*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p0007*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p0008*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p0009*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p000A*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p000B*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p000C*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p000D*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p000E*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0585p000F*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera
+
+usb:v0586*
+ ID_VENDOR_FROM_DATABASE=ZyXEL Communications Corp.
+
+usb:v0586p0025*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g/n USB Wireless Network Adapter
+
+usb:v0586p0102*
+ ID_PRODUCT_FROM_DATABASE=omni.net II ISDN TA
+
+usb:v0586p1000*
+ ID_PRODUCT_FROM_DATABASE=Omni NET Modem / ISDN TA
+
+usb:v0586p1500*
+ ID_PRODUCT_FROM_DATABASE=Omni 56K Plus
+
+usb:v0586p2011*
+ ID_PRODUCT_FROM_DATABASE=Scorpion-980N keyboard
+
+usb:v0586p3304*
+ ID_PRODUCT_FROM_DATABASE=LAN Modem
+
+usb:v0586p3309*
+ ID_PRODUCT_FROM_DATABASE=ADSL Modem Prestige 600 series
+
+usb:v0586p330A*
+ ID_PRODUCT_FROM_DATABASE=ADSL Modem Interface
+
+usb:v0586p330E*
+ ID_PRODUCT_FROM_DATABASE=USB Broadband ADSL Modem Rev 1.10
+
+usb:v0586p3400*
+ ID_PRODUCT_FROM_DATABASE=ZyAIR B-220 IEEE 802.11b Adapter
+
+usb:v0586p3401*
+ ID_PRODUCT_FROM_DATABASE=ZyAIR G-220 802.11bg
+
+usb:v0586p3402*
+ ID_PRODUCT_FROM_DATABASE=ZyAIR G-220F 802.11bg
+
+usb:v0586p3403*
+ ID_PRODUCT_FROM_DATABASE=AG-200 802.11abg Wireless Adapter [Atheros AR5523]
+
+usb:v0586p3407*
+ ID_PRODUCT_FROM_DATABASE=G-200 v2 802.11bg
+
+usb:v0586p3408*
+ ID_PRODUCT_FROM_DATABASE=G-260 802.11bg
+
+usb:v0586p3409*
+ ID_PRODUCT_FROM_DATABASE=AG-225H 802.11bg
+
+usb:v0586p340A*
+ ID_PRODUCT_FROM_DATABASE=M-202 802.11bg
+
+usb:v0586p340C*
+ ID_PRODUCT_FROM_DATABASE=G-270S 802.11bg Wireless Adapter [Atheros AR5523]
+
+usb:v0586p340F*
+ ID_PRODUCT_FROM_DATABASE=G-220 v2 802.11bg
+
+usb:v0586p3410*
+ ID_PRODUCT_FROM_DATABASE=ZyAIR G-202 802.11bg
+
+usb:v0586p3412*
+ ID_PRODUCT_FROM_DATABASE=802.11bg
+
+usb:v0586p3413*
+ ID_PRODUCT_FROM_DATABASE=ZyAIR AG-225H v2 802.11bg
+
+usb:v0586p3415*
+ ID_PRODUCT_FROM_DATABASE=G-210H 802.11g Wireless Adapter
+
+usb:v0586p3416*
+ ID_PRODUCT_FROM_DATABASE=NWD-210N 802.11b/g/n-draft wireless adapter
+
+usb:v0586p3417*
+ ID_PRODUCT_FROM_DATABASE=NWD271N 802.11n Wireless Adapter [Atheros AR9001U-(2)NG]
+
+usb:v0586p3418*
+ ID_PRODUCT_FROM_DATABASE=NWD211AN 802.11abgn Wireless Adapter [Ralink RT2870]
+
+usb:v0586p3419*
+ ID_PRODUCT_FROM_DATABASE=G-220 v3 802.11bg Wireless Adapter [ZyDAS ZD1211B]
+
+usb:v0586p341A*
+ ID_PRODUCT_FROM_DATABASE=NWD-270N Wireless N-lite USB Adapter
+
+usb:v0586p341E*
+ ID_PRODUCT_FROM_DATABASE=NWD2105 802.11bgn Wireless Adapter [Ralink RT3070]
+
+usb:v0586p341F*
+ ID_PRODUCT_FROM_DATABASE=NWD2205 802.11n Wireless N Adapter [Realtek RTL8192CU]
+
+usb:v0586p343E*
+ ID_PRODUCT_FROM_DATABASE=N220 802.11bgn Wireless Adapter
+
+usb:v0587*
+ ID_VENDOR_FROM_DATABASE=America Kotobuki Electronics Industries, Inc.
+
+usb:v0588*
+ ID_VENDOR_FROM_DATABASE=Sapien Design
+
+usb:v0589*
+ ID_VENDOR_FROM_DATABASE=Victron
+
+usb:v058A*
+ ID_VENDOR_FROM_DATABASE=Nohau Corp.
+
+usb:v058B*
+ ID_VENDOR_FROM_DATABASE=Infineon Technologies
+
+usb:v058Bp001C*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v058C*
+ ID_VENDOR_FROM_DATABASE=In Focus Systems
+
+usb:v058Cp0007*
+ ID_PRODUCT_FROM_DATABASE=Flash
+
+usb:v058Cp0008*
+ ID_PRODUCT_FROM_DATABASE=LP130
+
+usb:v058Cp000A*
+ ID_PRODUCT_FROM_DATABASE=LP530
+
+usb:v058Cp0010*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0011*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0012*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0013*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0014*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0015*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0016*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0017*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0018*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp0019*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp001A*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp001B*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp001C*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp001D*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp001E*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058Cp001F*
+ ID_PRODUCT_FROM_DATABASE=Projector
+
+usb:v058CpFFE5*
+ ID_PRODUCT_FROM_DATABASE=IN34 Projector
+
+usb:v058D*
+ ID_VENDOR_FROM_DATABASE=Micrel Semiconductor
+
+usb:v058E*
+ ID_VENDOR_FROM_DATABASE=Tripath Technology, Inc.
+
+usb:v058F*
+ ID_VENDOR_FROM_DATABASE=Alcor Micro Corp.
+
+usb:v058Fp1234*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v058Fp2412*
+ ID_PRODUCT_FROM_DATABASE=SCard R/W CSR-145
+
+usb:v058Fp2802*
+ ID_PRODUCT_FROM_DATABASE=Monterey Keyboard
+
+usb:v058Fp5492*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v058Fp6232*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed 16-in-1 Flash Card Reader/Writer
+
+usb:v058Fp6254*
+ ID_PRODUCT_FROM_DATABASE=USB Hub
+
+usb:v058Fp6331*
+ ID_PRODUCT_FROM_DATABASE=SD/MMC/MS Card Reader
+
+usb:v058Fp6332*
+ ID_PRODUCT_FROM_DATABASE=Multi-Function Card Reader
+
+usb:v058Fp6335*
+ ID_PRODUCT_FROM_DATABASE=SD/MMC Card Reader
+
+usb:v058Fp6360*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader
+
+usb:v058Fp6361*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader
+
+usb:v058Fp6362*
+ ID_PRODUCT_FROM_DATABASE=Flash Card Reader/Writer
+
+usb:v058Fp6364*
+ ID_PRODUCT_FROM_DATABASE=AU6477 Card Reader Controller
+
+usb:v058Fp6366*
+ ID_PRODUCT_FROM_DATABASE=Multi Flash Reader
+
+usb:v058Fp6377*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader
+
+usb:v058Fp6386*
+ ID_PRODUCT_FROM_DATABASE=Memory Card
+
+usb:v058Fp6387*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v058Fp6390*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0-IDE bridge
+
+usb:v058Fp9213*
+ ID_PRODUCT_FROM_DATABASE=MacAlly Kbd Hub
+
+usb:v058Fp9215*
+ ID_PRODUCT_FROM_DATABASE=AU9814 Hub
+
+usb:v058Fp9254*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v058Fp9310*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UID4/5A & UID7A)
+
+usb:v058Fp9320*
+ ID_PRODUCT_FROM_DATABASE=Micro Storage Driver for Win98
+
+usb:v058Fp9321*
+ ID_PRODUCT_FROM_DATABASE=Micro Storage Driver for Win98
+
+usb:v058Fp9330*
+ ID_PRODUCT_FROM_DATABASE=SD Reader
+
+usb:v058Fp9331*
+ ID_PRODUCT_FROM_DATABASE=Micro Storage Driver for Win98
+
+usb:v058Fp9340*
+ ID_PRODUCT_FROM_DATABASE=Delkin eFilm Reader-32
+
+usb:v058Fp9350*
+ ID_PRODUCT_FROM_DATABASE=Delkin eFilm Reader-32
+
+usb:v058Fp9360*
+ ID_PRODUCT_FROM_DATABASE=8-in-1 Media Card Reader
+
+usb:v058Fp9361*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader
+
+usb:v058Fp9368*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader
+
+usb:v058Fp9380*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v058Fp9382*
+ ID_PRODUCT_FROM_DATABASE=Acer/Sweex Flash drive
+
+usb:v058Fp9384*
+ ID_PRODUCT_FROM_DATABASE=qdi U2Disk T209M
+
+usb:v058Fp9410*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v058Fp9472*
+ ID_PRODUCT_FROM_DATABASE=Keyboard Hub
+
+usb:v058Fp9510*
+ ID_PRODUCT_FROM_DATABASE=ChunghwaTL USB02 Smartcard Reader
+
+usb:v058Fp9520*
+ ID_PRODUCT_FROM_DATABASE=EMV Certified Smart Card Reader
+
+usb:v058Fp9720*
+ ID_PRODUCT_FROM_DATABASE=USB-Serial Adapter
+
+usb:v058FpA014*
+ ID_PRODUCT_FROM_DATABASE=Asus Integrated Webcam
+
+usb:v0590*
+ ID_VENDOR_FROM_DATABASE=Omron Corp.
+
+usb:v0590p0004*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v0590p000B*
+ ID_PRODUCT_FROM_DATABASE=MR56SVS
+
+usb:v0590p0028*
+ ID_PRODUCT_FROM_DATABASE=HJ-720IT Pedometer / Blood Pressure Monitor HEM-7080IT-E
+
+usb:v0591*
+ ID_VENDOR_FROM_DATABASE=Questra Consulting
+
+usb:v0592*
+ ID_VENDOR_FROM_DATABASE=Powerware Corp.
+
+usb:v0592p0002*
+ ID_PRODUCT_FROM_DATABASE=UPS (X-Slot)
+
+usb:v0593*
+ ID_VENDOR_FROM_DATABASE=Incite
+
+usb:v0594*
+ ID_VENDOR_FROM_DATABASE=Princeton Graphic Systems
+
+usb:v0595*
+ ID_VENDOR_FROM_DATABASE=Zoran Microelectronics, Ltd
+
+usb:v0595p1001*
+ ID_PRODUCT_FROM_DATABASE=Digitrex DSC-1300/DSC-2100 (mass storage mode)
+
+usb:v0595p2002*
+ ID_PRODUCT_FROM_DATABASE=DIGITAL STILL CAMERA 6M 4X
+
+usb:v0595p4343*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera EX-20 DSC
+
+usb:v0596*
+ ID_VENDOR_FROM_DATABASE=MicroTouch Systems, Inc.
+
+usb:v0596p0001*
+ ID_PRODUCT_FROM_DATABASE=Touchscreen
+
+usb:v0596p0002*
+ ID_PRODUCT_FROM_DATABASE=Touch Screen Controller
+
+usb:v0596p0500*
+ ID_PRODUCT_FROM_DATABASE=PCT Multitouch HID Controller
+
+usb:v0597*
+ ID_VENDOR_FROM_DATABASE=Trisignal Communications
+
+usb:v0598*
+ ID_VENDOR_FROM_DATABASE=Niigata Canotec Co., Inc.
+
+usb:v0599*
+ ID_VENDOR_FROM_DATABASE=Brilliance Semiconductor, Inc.
+
+usb:v059A*
+ ID_VENDOR_FROM_DATABASE=Spectrum Signal Processing, Inc.
+
+usb:v059B*
+ ID_VENDOR_FROM_DATABASE=Iomega Corp.
+
+usb:v059Bp0001*
+ ID_PRODUCT_FROM_DATABASE=Zip 100 (Type 1)
+
+usb:v059Bp000B*
+ ID_PRODUCT_FROM_DATABASE=Zip 100 (Type 2)
+
+usb:v059Bp0021*
+ ID_PRODUCT_FROM_DATABASE=Win98 Disk Controller
+
+usb:v059Bp0030*
+ ID_PRODUCT_FROM_DATABASE=Zip 250 (Ver 1)
+
+usb:v059Bp0031*
+ ID_PRODUCT_FROM_DATABASE=Zip 100 (Type 3)
+
+usb:v059Bp0032*
+ ID_PRODUCT_FROM_DATABASE=Zip 250 (Ver 2)
+
+usb:v059Bp0034*
+ ID_PRODUCT_FROM_DATABASE=Zip 100 Driver
+
+usb:v059Bp0037*
+ ID_PRODUCT_FROM_DATABASE=Zip 750 MB
+
+usb:v059Bp0040*
+ ID_PRODUCT_FROM_DATABASE=SCSI Bridge
+
+usb:v059Bp0042*
+ ID_PRODUCT_FROM_DATABASE=Rev 70 GB
+
+usb:v059Bp0050*
+ ID_PRODUCT_FROM_DATABASE=Zip CD 650 Writer
+
+usb:v059Bp0053*
+ ID_PRODUCT_FROM_DATABASE=CDRW55292EXT CD-RW External Drive
+
+usb:v059Bp0056*
+ ID_PRODUCT_FROM_DATABASE=External CD-RW Drive Enclosure
+
+usb:v059Bp0057*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v059Bp005D*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v059Bp005F*
+ ID_PRODUCT_FROM_DATABASE=CDRW64892EXT3-C CD-RW 52x24x52x External Drive
+
+usb:v059Bp0060*
+ ID_PRODUCT_FROM_DATABASE=PCMCIA PocketZip Dock
+
+usb:v059Bp0061*
+ ID_PRODUCT_FROM_DATABASE=Varo PocketZip 40 MP3 Player
+
+usb:v059Bp006D*
+ ID_PRODUCT_FROM_DATABASE=HipZip MP3 Player
+
+usb:v059Bp007C*
+ ID_PRODUCT_FROM_DATABASE=Ultra Max USB/1394
+
+usb:v059Bp007D*
+ ID_PRODUCT_FROM_DATABASE=HTC42606 0G9AT00 [Iomega HDD]
+
+usb:v059Bp007E*
+ ID_PRODUCT_FROM_DATABASE=Mini 256MB/512MB Flash Drive [IOM2D5]
+
+usb:v059Bp00DB*
+ ID_PRODUCT_FROM_DATABASE=FotoShow Zip 250 Driver
+
+usb:v059Bp0150*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v059Bp015D*
+ ID_PRODUCT_FROM_DATABASE=Super DVD Writer
+
+usb:v059Bp0173*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v059Bp0174*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v059Bp0176*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v059Bp0177*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v059Bp0178*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v059Bp0179*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v059Bp017A*
+ ID_PRODUCT_FROM_DATABASE=HDD
+
+usb:v059Bp017B*
+ ID_PRODUCT_FROM_DATABASE=HDD/1394A
+
+usb:v059Bp017C*
+ ID_PRODUCT_FROM_DATABASE=HDD/1394B
+
+usb:v059Bp0251*
+ ID_PRODUCT_FROM_DATABASE=Optical
+
+usb:v059Bp0252*
+ ID_PRODUCT_FROM_DATABASE=Optical
+
+usb:v059Bp0278*
+ ID_PRODUCT_FROM_DATABASE=LDHD-UPS [Professional Desktop Hard Drive eSATA / USB2.0]
+
+usb:v059Bp027A*
+ ID_PRODUCT_FROM_DATABASE=LPHD250-U [Portable Hard Drive Silver Series 250 Go]
+
+usb:v059Bp0470*
+ ID_PRODUCT_FROM_DATABASE=Prestige Portable Hard Drive
+
+usb:v059Bp047A*
+ ID_PRODUCT_FROM_DATABASE=Select Portable Hard Drive
+
+usb:v059Bp0571*
+ ID_PRODUCT_FROM_DATABASE=Prestige Portable Hard Drive
+
+usb:v059Bp0579*
+ ID_PRODUCT_FROM_DATABASE=eGo Portable Hard Drive
+
+usb:v059Bp1052*
+ ID_PRODUCT_FROM_DATABASE=DVD+RW External Drive
+
+usb:v059C*
+ ID_VENDOR_FROM_DATABASE=A-Trend Technology Co., Ltd
+
+usb:v059D*
+ ID_VENDOR_FROM_DATABASE=Advanced Input Devices
+
+usb:v059E*
+ ID_VENDOR_FROM_DATABASE=Intelligent Instrumentation
+
+usb:v059F*
+ ID_VENDOR_FROM_DATABASE=LaCie, Ltd
+
+usb:v059Fp0201*
+ ID_PRODUCT_FROM_DATABASE=StudioDrive USB2
+
+usb:v059Fp0202*
+ ID_PRODUCT_FROM_DATABASE=StudioDrive USB2
+
+usb:v059Fp0203*
+ ID_PRODUCT_FROM_DATABASE=StudioDrive USB2
+
+usb:v059Fp0211*
+ ID_PRODUCT_FROM_DATABASE=PocketDrive
+
+usb:v059Fp0212*
+ ID_PRODUCT_FROM_DATABASE=PocketDrive
+
+usb:v059Fp0213*
+ ID_PRODUCT_FROM_DATABASE=PocketDrive USB2
+
+usb:v059Fp0323*
+ ID_PRODUCT_FROM_DATABASE=LaCie d2 Drive USB2
+
+usb:v059Fp0421*
+ ID_PRODUCT_FROM_DATABASE=Big Disk G465
+
+usb:v059Fp0641*
+ ID_PRODUCT_FROM_DATABASE=Mobile Hard Drive
+
+usb:v059Fp1010*
+ ID_PRODUCT_FROM_DATABASE=Desktop Hard Drive
+
+usb:v059Fp1019*
+ ID_PRODUCT_FROM_DATABASE=Desktop Hard Drive
+
+usb:v059Fp1021*
+ ID_PRODUCT_FROM_DATABASE=Little Disk
+
+usb:v059Fp1027*
+ ID_PRODUCT_FROM_DATABASE=iamaKey V2
+
+usb:v059Fp102A*
+ ID_PRODUCT_FROM_DATABASE=Rikiki Hard Drive
+
+usb:v059Fp1049*
+ ID_PRODUCT_FROM_DATABASE=rikiki Harddrive
+
+usb:v059Fp1052*
+ ID_PRODUCT_FROM_DATABASE=P'9220 Mobile Drive
+
+usb:v059FpA601*
+ ID_PRODUCT_FROM_DATABASE=HardDrive
+
+usb:v059FpA602*
+ ID_PRODUCT_FROM_DATABASE=CD R/W
+
+usb:v05A0*
+ ID_VENDOR_FROM_DATABASE=Vetronix Corp.
+
+usb:v05A1*
+ ID_VENDOR_FROM_DATABASE=USC Corp.
+
+usb:v05A2*
+ ID_VENDOR_FROM_DATABASE=Fuji Film Microdevices Co., Ltd
+
+usb:v05A3*
+ ID_VENDOR_FROM_DATABASE=ARC International
+
+usb:v05A3p8388*
+ ID_PRODUCT_FROM_DATABASE=Marvell 88W8388 802.11a/b/g WLAN
+
+usb:v05A4*
+ ID_VENDOR_FROM_DATABASE=Ortek Technology, Inc.
+
+usb:v05A4p1000*
+ ID_PRODUCT_FROM_DATABASE=WKB-1000S Wireless Ergo Keyboard with Touchpad
+
+usb:v05A4p2000*
+ ID_PRODUCT_FROM_DATABASE=WKB-2000 Wireless Keyboard with Touchpad
+
+usb:v05A4p9720*
+ ID_PRODUCT_FROM_DATABASE=Keyboard Mouse
+
+usb:v05A4p9722*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v05A4p9731*
+ ID_PRODUCT_FROM_DATABASE=MCK-600W/MCK-800USB Keyboard
+
+usb:v05A4p9783*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keypad
+
+usb:v05A5*
+ ID_VENDOR_FROM_DATABASE=Sampo Technology Corp.
+
+usb:v05A6*
+ ID_VENDOR_FROM_DATABASE=Cisco Systems, Inc.
+
+usb:v05A6p0001*
+ ID_PRODUCT_FROM_DATABASE=CVA124 Cable Voice Adapter (WDM)
+
+usb:v05A6p0002*
+ ID_PRODUCT_FROM_DATABASE=CVA122 Cable Voice Adapter (WDM)
+
+usb:v05A6p0003*
+ ID_PRODUCT_FROM_DATABASE=CVA124E Cable Voice Adapter (WDM)
+
+usb:v05A6p0004*
+ ID_PRODUCT_FROM_DATABASE=CVA122E Cable Voice Adapter (WDM)
+
+usb:v05A7*
+ ID_VENDOR_FROM_DATABASE=Bose Corp.
+
+usb:v05A8*
+ ID_VENDOR_FROM_DATABASE=Spacetec IMC Corp.
+
+usb:v05A9*
+ ID_VENDOR_FROM_DATABASE=OmniVision Technologies, Inc.
+
+usb:v05A9p0511*
+ ID_PRODUCT_FROM_DATABASE=OV511 Webcam
+
+usb:v05A9p0518*
+ ID_PRODUCT_FROM_DATABASE=OV518 Webcam
+
+usb:v05A9p0519*
+ ID_PRODUCT_FROM_DATABASE=OV519 Microphone
+
+usb:v05A9p1550*
+ ID_PRODUCT_FROM_DATABASE=VEHO Filmscanner
+
+usb:v05A9p2640*
+ ID_PRODUCT_FROM_DATABASE=OV2640 Webcam
+
+usb:v05A9p2643*
+ ID_PRODUCT_FROM_DATABASE=Monitor Webcam
+
+usb:v05A9p264B*
+ ID_PRODUCT_FROM_DATABASE=Monitor Webcam
+
+usb:v05A9p2800*
+ ID_PRODUCT_FROM_DATABASE=SuperCAM
+
+usb:v05A9p4519*
+ ID_PRODUCT_FROM_DATABASE=Webcam Classic
+
+usb:v05A9p7670*
+ ID_PRODUCT_FROM_DATABASE=OV7670 Webcam
+
+usb:v05A9p8519*
+ ID_PRODUCT_FROM_DATABASE=OV519 Webcam
+
+usb:v05A9pA511*
+ ID_PRODUCT_FROM_DATABASE=OV511+ Webcam
+
+usb:v05A9pA518*
+ ID_PRODUCT_FROM_DATABASE=D-Link DSB-C310 Webcam
+
+usb:v05AA*
+ ID_VENDOR_FROM_DATABASE=Utilux South China, Ltd
+
+usb:v05AB*
+ ID_VENDOR_FROM_DATABASE=In-System Design
+
+usb:v05ABp0002*
+ ID_PRODUCT_FROM_DATABASE=Parallel Port
+
+usb:v05ABp0030*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 (TPP)
+
+usb:v05ABp0031*
+ ID_PRODUCT_FROM_DATABASE=ATA Bridge
+
+usb:v05ABp0060*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 ATA Bridge
+
+usb:v05ABp0061*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V3 (TPP-I)
+
+usb:v05ABp0101*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter (TPP)
+
+usb:v05ABp0130*
+ ID_PRODUCT_FROM_DATABASE=Compact Flash and Microdrive Reader (TPP)
+
+usb:v05ABp0200*
+ ID_PRODUCT_FROM_DATABASE=USS725 ATA Bridge
+
+usb:v05ABp0201*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter (TPP)
+
+usb:v05ABp0202*
+ ID_PRODUCT_FROM_DATABASE=ATA Bridge
+
+usb:v05ABp0300*
+ ID_PRODUCT_FROM_DATABASE=Portable Hard Drive (TPP)
+
+usb:v05ABp0301*
+ ID_PRODUCT_FROM_DATABASE=Portable Hard Drive V2
+
+usb:v05ABp0350*
+ ID_PRODUCT_FROM_DATABASE=Portable Hard Drive (TPP)
+
+usb:v05ABp0351*
+ ID_PRODUCT_FROM_DATABASE=Portable Hard Drive V2
+
+usb:v05ABp081A*
+ ID_PRODUCT_FROM_DATABASE=ATA Bridge
+
+usb:v05ABp0CDA*
+ ID_PRODUCT_FROM_DATABASE=ATA Bridge for CD-R/RW
+
+usb:v05ABp1001*
+ ID_PRODUCT_FROM_DATABASE=BAYI Printer Class Support
+
+usb:v05ABp5700*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 (TPP)
+
+usb:v05ABp5701*
+ ID_PRODUCT_FROM_DATABASE=USB Storage Adapter V2
+
+usb:v05ABp5901*
+ ID_PRODUCT_FROM_DATABASE=Smart Board (TPP)
+
+usb:v05ABp5A01*
+ ID_PRODUCT_FROM_DATABASE=ATI Storage Adapter (TPP)
+
+usb:v05ABp5D01*
+ ID_PRODUCT_FROM_DATABASE=DataBook Adapter (TPP)
+
+usb:v05AC*
+ ID_VENDOR_FROM_DATABASE=Apple, Inc.
+
+usb:v05ACp0201*
+ ID_PRODUCT_FROM_DATABASE=USB Keyboard [Alps or Logitech, M2452]
+
+usb:v05ACp0202*
+ ID_PRODUCT_FROM_DATABASE=Keyboard [ALPS]
+
+usb:v05ACp0205*
+ ID_PRODUCT_FROM_DATABASE=Extended Keyboard [Mitsumi]
+
+usb:v05ACp0206*
+ ID_PRODUCT_FROM_DATABASE=Extended Keyboard [Mitsumi]
+
+usb:v05ACp020B*
+ ID_PRODUCT_FROM_DATABASE=Pro Keyboard [Mitsumi, A1048/US layout]
+
+usb:v05ACp020C*
+ ID_PRODUCT_FROM_DATABASE=Extended Keyboard [Mitsumi]
+
+usb:v05ACp020D*
+ ID_PRODUCT_FROM_DATABASE=Pro Keyboard [Mitsumi, A1048/JIS layout]
+
+usb:v05ACp020E*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp020F*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0214*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp0215*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0216*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp0217*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp0218*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0219*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp021A*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp021B*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp021C*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp021D*
+ ID_PRODUCT_FROM_DATABASE=Aluminum Mini Keyboard (ANSI)
+
+usb:v05ACp021E*
+ ID_PRODUCT_FROM_DATABASE=Aluminum Mini Keyboard (ISO)
+
+usb:v05ACp021F*
+ ID_PRODUCT_FROM_DATABASE=Aluminum Mini Keyboard (JIS)
+
+usb:v05ACp0220*
+ ID_PRODUCT_FROM_DATABASE=Aluminum Keyboard (ANSI)
+
+usb:v05ACp0221*
+ ID_PRODUCT_FROM_DATABASE=Aluminum Keyboard (ISO)
+
+usb:v05ACp0222*
+ ID_PRODUCT_FROM_DATABASE=Aluminum Keyboard (JIS)
+
+usb:v05ACp0223*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp0224*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0225*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp0229*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro) (ANSI)
+
+usb:v05ACp022A*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro) (ISO)
+
+usb:v05ACp022B*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro) (JIS)
+
+usb:v05ACp0230*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro 4,1) (ANSI)
+
+usb:v05ACp0231*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro 4,1) (ISO)
+
+usb:v05ACp0232*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro 4,1) (JIS)
+
+usb:v05ACp0236*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp0237*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0238*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp023F*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp0240*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0241*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp0242*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp0243*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0244*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp0245*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp0246*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0247*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp024D*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Air) (ISO)
+
+usb:v05ACp0250*
+ ID_PRODUCT_FROM_DATABASE=Aluminium Keyboard (ISO)
+
+usb:v05ACp0252*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
+
+usb:v05ACp0253*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO)
+
+usb:v05ACp0254*
+ ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
+
+usb:v05ACp0301*
+ ID_PRODUCT_FROM_DATABASE=USB Mouse [Mitsumi, M4848]
+
+usb:v05ACp0302*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse [Fujitsu]
+
+usb:v05ACp0304*
+ ID_PRODUCT_FROM_DATABASE=Optical USB Mouse [Mitsumi]
+
+usb:v05ACp0306*
+ ID_PRODUCT_FROM_DATABASE=Optical USB Mouse [Fujitsu]
+
+usb:v05ACp030A*
+ ID_PRODUCT_FROM_DATABASE=Internal Trackpad
+
+usb:v05ACp030B*
+ ID_PRODUCT_FROM_DATABASE=Internal Trackpad
+
+usb:v05ACp030D*
+ ID_PRODUCT_FROM_DATABASE=Magic Mouse
+
+usb:v05ACp030E*
+ ID_PRODUCT_FROM_DATABASE=MC380Z/A [Magic Trackpad]
+
+usb:v05ACp1000*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth HCI MacBookPro (HID mode)
+
+usb:v05ACp1001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard Hub [ALPS]
+
+usb:v05ACp1002*
+ ID_PRODUCT_FROM_DATABASE=Extended Keyboard Hub [Mitsumi]
+
+usb:v05ACp1003*
+ ID_PRODUCT_FROM_DATABASE=Hub in Pro Keyboard [Mitsumi, A1048]
+
+usb:v05ACp1006*
+ ID_PRODUCT_FROM_DATABASE=Hub in Aluminum Keyboard
+
+usb:v05ACp1101*
+ ID_PRODUCT_FROM_DATABASE=Speakers
+
+usb:v05ACp1105*
+ ID_PRODUCT_FROM_DATABASE=Audio in LED Cinema Display
+
+usb:v05ACp1107*
+ ID_PRODUCT_FROM_DATABASE=Thunderbolt Display Audio
+
+usb:v05ACp1201*
+ ID_PRODUCT_FROM_DATABASE=3G iPod
+
+usb:v05ACp1202*
+ ID_PRODUCT_FROM_DATABASE=iPod 2G
+
+usb:v05ACp1203*
+ ID_PRODUCT_FROM_DATABASE=iPod 4.Gen Grayscale 40G
+
+usb:v05ACp1204*
+ ID_PRODUCT_FROM_DATABASE=iPod [Photo]
+
+usb:v05ACp1205*
+ ID_PRODUCT_FROM_DATABASE=iPod Mini 1.Gen/2.Gen
+
+usb:v05ACp1206*
+ ID_PRODUCT_FROM_DATABASE=iPod '06'
+
+usb:v05ACp1207*
+ ID_PRODUCT_FROM_DATABASE=iPod '07'
+
+usb:v05ACp1208*
+ ID_PRODUCT_FROM_DATABASE=iPod '08'
+
+usb:v05ACp1209*
+ ID_PRODUCT_FROM_DATABASE=iPod Video
+
+usb:v05ACp120A*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano
+
+usb:v05ACp1223*
+ ID_PRODUCT_FROM_DATABASE=iPod Classic/Nano 3.Gen (DFU mode)
+
+usb:v05ACp1224*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 3.Gen (DFU mode)
+
+usb:v05ACp1225*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 4.Gen (DFU mode)
+
+usb:v05ACp1227*
+ ID_PRODUCT_FROM_DATABASE=Mobile Device (DFU Mode)
+
+usb:v05ACp1231*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 5.Gen (DFU mode)
+
+usb:v05ACp1240*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 2.Gen (DFU mode)
+
+usb:v05ACp1242*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 3.Gen (WTF mode)
+
+usb:v05ACp1243*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 4.Gen (WTF mode)
+
+usb:v05ACp1245*
+ ID_PRODUCT_FROM_DATABASE=iPod Classic 3.Gen (WTF mode)
+
+usb:v05ACp1246*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 5.Gen (WTF mode)
+
+usb:v05ACp1255*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 4.Gen (DFU mode)
+
+usb:v05ACp1260*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 2.Gen
+
+usb:v05ACp1261*
+ ID_PRODUCT_FROM_DATABASE=iPod Classic
+
+usb:v05ACp1262*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 3.Gen
+
+usb:v05ACp1263*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 4.Gen
+
+usb:v05ACp1265*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 5.Gen
+
+usb:v05ACp1266*
+ ID_PRODUCT_FROM_DATABASE=iPod Nano 6.Gen
+
+usb:v05ACp1281*
+ ID_PRODUCT_FROM_DATABASE=Apple Mobile Device [Recovery Mode]
+
+usb:v05ACp1290*
+ ID_PRODUCT_FROM_DATABASE=iPhone
+
+usb:v05ACp1291*
+ ID_PRODUCT_FROM_DATABASE=iPod Touch 1.Gen
+
+usb:v05ACp1292*
+ ID_PRODUCT_FROM_DATABASE=iPhone 3G
+
+usb:v05ACp1293*
+ ID_PRODUCT_FROM_DATABASE=iPod Touch 2.Gen
+
+usb:v05ACp1294*
+ ID_PRODUCT_FROM_DATABASE=iPhone 3GS
+
+usb:v05ACp1296*
+ ID_PRODUCT_FROM_DATABASE=iPod Touch 3.Gen (8GB)
+
+usb:v05ACp1297*
+ ID_PRODUCT_FROM_DATABASE=iPhone 4
+
+usb:v05ACp1299*
+ ID_PRODUCT_FROM_DATABASE=iPod Touch 3.Gen
+
+usb:v05ACp129A*
+ ID_PRODUCT_FROM_DATABASE=iPad
+
+usb:v05ACp129E*
+ ID_PRODUCT_FROM_DATABASE=iPod Touch 4.Gen
+
+usb:v05ACp129F*
+ ID_PRODUCT_FROM_DATABASE=iPad 2
+
+usb:v05ACp12A0*
+ ID_PRODUCT_FROM_DATABASE=iPhone 4S
+
+usb:v05ACp12A2*
+ ID_PRODUCT_FROM_DATABASE=iPad 2 (3G; 64GB)
+
+usb:v05ACp12A9*
+ ID_PRODUCT_FROM_DATABASE=iPad 2
+
+usb:v05ACp12AA*
+ ID_PRODUCT_FROM_DATABASE=iPod Touch 5.Gen [A1421]
+
+usb:v05ACp1300*
+ ID_PRODUCT_FROM_DATABASE=iPod Shuffle
+
+usb:v05ACp1301*
+ ID_PRODUCT_FROM_DATABASE=iPod Shuffle 2.Gen
+
+usb:v05ACp1302*
+ ID_PRODUCT_FROM_DATABASE=iPod Shuffle 3.Gen
+
+usb:v05ACp1303*
+ ID_PRODUCT_FROM_DATABASE=iPod Shuffle 4.Gen
+
+usb:v05ACp1401*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+usb:v05ACp1402*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Adapter [A1277]
+
+usb:v05ACp8202*
+ ID_PRODUCT_FROM_DATABASE=HCF V.90 Data/Fax Modem
+
+usb:v05ACp8203*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth HCI
+
+usb:v05ACp8204*
+ ID_PRODUCT_FROM_DATABASE=Built-in Bluetooth 2.0+EDR HCI
+
+usb:v05ACp8205*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth HCI
+
+usb:v05ACp8206*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth HCI
+
+usb:v05ACp820A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth HID Keyboard
+
+usb:v05ACp820B*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth HID Mouse
+
+usb:v05ACp820F*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth HCI
+
+usb:v05ACp8213*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Host Controller
+
+usb:v05ACp8215*
+ ID_PRODUCT_FROM_DATABASE=Built-in Bluetooth 2.0+EDR HCI
+
+usb:v05ACp8216*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth USB Host Controller
+
+usb:v05ACp8217*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth USB Host Controller
+
+usb:v05ACp8218*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Host Controller
+
+usb:v05ACp821A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Host Controller
+
+usb:v05ACp821F*
+ ID_PRODUCT_FROM_DATABASE=Built-in Bluetooth 2.0+EDR HCI
+
+usb:v05ACp8240*
+ ID_PRODUCT_FROM_DATABASE=Built-in IR Receiver
+
+usb:v05ACp8241*
+ ID_PRODUCT_FROM_DATABASE=Built-in IR Receiver
+
+usb:v05ACp8242*
+ ID_PRODUCT_FROM_DATABASE=Built-in IR Receiver
+
+usb:v05ACp8300*
+ ID_PRODUCT_FROM_DATABASE=Built-in iSight (no firmware loaded)
+
+usb:v05ACp8403*
+ ID_PRODUCT_FROM_DATABASE=Internal Memory Card Reader
+
+usb:v05ACp8404*
+ ID_PRODUCT_FROM_DATABASE=Internal Memory Card Reader
+
+usb:v05ACp8501*
+ ID_PRODUCT_FROM_DATABASE=Built-in iSight [Micron]
+
+usb:v05ACp8502*
+ ID_PRODUCT_FROM_DATABASE=Built-in iSight
+
+usb:v05ACp8505*
+ ID_PRODUCT_FROM_DATABASE=Built-in iSight
+
+usb:v05ACp8507*
+ ID_PRODUCT_FROM_DATABASE=Built-in iSight
+
+usb:v05ACp8508*
+ ID_PRODUCT_FROM_DATABASE=iSight in LED Cinema Display
+
+usb:v05ACp8509*
+ ID_PRODUCT_FROM_DATABASE=FaceTime HD Camera
+
+usb:v05ACp850A*
+ ID_PRODUCT_FROM_DATABASE=FaceTime Camera
+
+usb:v05ACp911C*
+ ID_PRODUCT_FROM_DATABASE=Hub in A1082 [Cinema HD Display 23"]
+
+usb:v05ACp912F*
+ ID_PRODUCT_FROM_DATABASE=Hub in 30" Cinema Display
+
+usb:v05ACp9215*
+ ID_PRODUCT_FROM_DATABASE=Studio Display 15"
+
+usb:v05ACp9217*
+ ID_PRODUCT_FROM_DATABASE=Studio Display 17"
+
+usb:v05ACp9218*
+ ID_PRODUCT_FROM_DATABASE=Cinema Display 23"
+
+usb:v05ACp9219*
+ ID_PRODUCT_FROM_DATABASE=Cinema Display 20"
+
+usb:v05ACp921C*
+ ID_PRODUCT_FROM_DATABASE=A1082 [Cinema HD Display 23"]
+
+usb:v05ACp921E*
+ ID_PRODUCT_FROM_DATABASE=Cinema Display 24"
+
+usb:v05ACp9221*
+ ID_PRODUCT_FROM_DATABASE=30" Cinema Display
+
+usb:v05ACp9226*
+ ID_PRODUCT_FROM_DATABASE=LED Cinema Display
+
+usb:v05ACp9227*
+ ID_PRODUCT_FROM_DATABASE=Thunderbolt Display
+
+usb:v05ACp9232*
+ ID_PRODUCT_FROM_DATABASE=Cinema HD Display 30"
+
+usb:v05ACpFFFF*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth in DFU mode - Driver
+
+usb:v05AD*
+ ID_VENDOR_FROM_DATABASE=Y.C. Cable U.S.A., Inc.
+
+usb:v05AE*
+ ID_VENDOR_FROM_DATABASE=Synopsys, Inc.
+
+usb:v05AF*
+ ID_VENDOR_FROM_DATABASE=Jing-Mold Enterprise Co., Ltd
+
+usb:v05AFp0806*
+ ID_PRODUCT_FROM_DATABASE=HP SK806A Keyboard
+
+usb:v05AFp0809*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Mouse
+
+usb:v05AFp0821*
+ ID_PRODUCT_FROM_DATABASE=IDE to
+
+usb:v05AFp3062*
+ ID_PRODUCT_FROM_DATABASE=Cordless Keyboard
+
+usb:v05AFp9167*
+ ID_PRODUCT_FROM_DATABASE=KB 9151B - 678
+
+usb:v05AFp9267*
+ ID_PRODUCT_FROM_DATABASE=KB 9251B - 678 Mouse
+
+usb:v05B0*
+ ID_VENDOR_FROM_DATABASE=Fountain Technologies, Inc.
+
+usb:v05B1*
+ ID_VENDOR_FROM_DATABASE=First International Computer, Inc.
+
+usb:v05B1p1389*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Wireless Adapter
+
+usb:v05B4*
+ ID_VENDOR_FROM_DATABASE=LG Semicon Co., Ltd
+
+usb:v05B4p4857*
+ ID_PRODUCT_FROM_DATABASE=M-Any DAH-210
+
+usb:v05B4p6001*
+ ID_PRODUCT_FROM_DATABASE=Digisette DUO-MP3 AR-100
+
+usb:v05B5*
+ ID_VENDOR_FROM_DATABASE=Dialogic Corp.
+
+usb:v05B6*
+ ID_VENDOR_FROM_DATABASE=Proxima Corp.
+
+usb:v05B7*
+ ID_VENDOR_FROM_DATABASE=Medianix Semiconductor, Inc.
+
+usb:v05B8*
+ ID_VENDOR_FROM_DATABASE=Agiler, Inc.
+
+usb:v05B8p3002*
+ ID_PRODUCT_FROM_DATABASE=Scroll Mouse
+
+usb:v05B9*
+ ID_VENDOR_FROM_DATABASE=Philips Research Laboratories
+
+usb:v05BA*
+ ID_VENDOR_FROM_DATABASE=DigitalPersona, Inc.
+
+usb:v05BAp0007*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v05BAp0008*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v05BAp000A*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v05BB*
+ ID_VENDOR_FROM_DATABASE=Grey Cell Systems
+
+usb:v05BC*
+ ID_VENDOR_FROM_DATABASE=3G Green Green Globe Co., Ltd
+
+usb:v05BCp0004*
+ ID_PRODUCT_FROM_DATABASE=Trackball
+
+usb:v05BD*
+ ID_VENDOR_FROM_DATABASE=RAFI GmbH & Co. KG
+
+usb:v05BE*
+ ID_VENDOR_FROM_DATABASE=Tyco Electronics (Raychem)
+
+usb:v05BF*
+ ID_VENDOR_FROM_DATABASE=S & S Research
+
+usb:v05C0*
+ ID_VENDOR_FROM_DATABASE=Keil Software
+
+usb:v05C1*
+ ID_VENDOR_FROM_DATABASE=Kawasaki Microelectronics, Inc.
+
+usb:v05C2*
+ ID_VENDOR_FROM_DATABASE=Media Phonics (Suisse) S.A.
+
+usb:v05C5*
+ ID_VENDOR_FROM_DATABASE=Digi International, Inc.
+
+usb:v05C5p0002*
+ ID_PRODUCT_FROM_DATABASE=AccelePort USB 2
+
+usb:v05C5p0004*
+ ID_PRODUCT_FROM_DATABASE=AccelePort USB 4
+
+usb:v05C5p0008*
+ ID_PRODUCT_FROM_DATABASE=AccelePort USB 8
+
+usb:v05C6*
+ ID_VENDOR_FROM_DATABASE=Qualcomm, Inc.
+
+usb:v05C6p0114*
+ ID_PRODUCT_FROM_DATABASE=Select RW-200 CDMA Wireless Modem
+
+usb:v05C6p1000*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v05C6p3100*
+ ID_PRODUCT_FROM_DATABASE=CDMA Wireless Modem/Phone
+
+usb:v05C6p3196*
+ ID_PRODUCT_FROM_DATABASE=CDMA Wireless Modem
+
+usb:v05C6p3197*
+ ID_PRODUCT_FROM_DATABASE=CDMA Wireless Modem/Phone
+
+usb:v05C6p6000*
+ ID_PRODUCT_FROM_DATABASE=Siemens SG75
+
+usb:v05C6p6503*
+ ID_PRODUCT_FROM_DATABASE=AnyData APE-540H
+
+usb:v05C6p6613*
+ ID_PRODUCT_FROM_DATABASE=Onda H600/N501HS ZTE MF330
+
+usb:v05C6p9000*
+ ID_PRODUCT_FROM_DATABASE=SIMCom SIM5218 modem
+
+usb:v05C6p9001*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v05C6p9002*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v05C6p9008*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v05C6p9018*
+ ID_PRODUCT_FROM_DATABASE=Qualcomm HSUSB Device
+
+usb:v05C6p9025*
+ ID_PRODUCT_FROM_DATABASE=Qualcomm HSUSB Device
+
+usb:v05C6p9201*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v05C6p9202*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v05C6p9203*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v05C6p9211*
+ ID_PRODUCT_FROM_DATABASE=Acer Gobi Wireless Modem (QDL mode)
+
+usb:v05C6p9212*
+ ID_PRODUCT_FROM_DATABASE=Acer Gobi Wireless Modem
+
+usb:v05C6p9214*
+ ID_PRODUCT_FROM_DATABASE=Acer Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v05C6p9215*
+ ID_PRODUCT_FROM_DATABASE=Acer Gobi 2000 Wireless Modem
+
+usb:v05C6p9221*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v05C6p9222*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v05C6p9224*
+ ID_PRODUCT_FROM_DATABASE=Sony Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v05C6p9225*
+ ID_PRODUCT_FROM_DATABASE=Sony Gobi 2000 Wireless Modem
+
+usb:v05C6p9231*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v05C6p9234*
+ ID_PRODUCT_FROM_DATABASE=Top Global Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v05C6p9235*
+ ID_PRODUCT_FROM_DATABASE=Top Global Gobi 2000 Wireless Modem
+
+usb:v05C6p9244*
+ ID_PRODUCT_FROM_DATABASE=Samsung Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v05C6p9245*
+ ID_PRODUCT_FROM_DATABASE=Samsung Gobi 2000 Wireless Modem
+
+usb:v05C6p9264*
+ ID_PRODUCT_FROM_DATABASE=Asus Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v05C6p9265*
+ ID_PRODUCT_FROM_DATABASE=Asus Gobi 2000 Wireless Modem
+
+usb:v05C6p9274*
+ ID_PRODUCT_FROM_DATABASE=iRex Technologies Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v05C6p9275*
+ ID_PRODUCT_FROM_DATABASE=iRex Technologies Gobi 2000 Wireless Modem
+
+usb:v05C7*
+ ID_VENDOR_FROM_DATABASE=Qtronix Corp.
+
+usb:v05C7p0113*
+ ID_PRODUCT_FROM_DATABASE=PC Line Mouse
+
+usb:v05C7p1001*
+ ID_PRODUCT_FROM_DATABASE=Lynx Mouse
+
+usb:v05C7p2001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v05C7p2011*
+ ID_PRODUCT_FROM_DATABASE=SCorpius Keyboard
+
+usb:v05C7p6001*
+ ID_PRODUCT_FROM_DATABASE=Ten-Keypad
+
+usb:v05C8*
+ ID_VENDOR_FROM_DATABASE=Cheng Uei Precision Industry Co., Ltd (Foxlink)
+
+usb:v05C8p0103*
+ ID_PRODUCT_FROM_DATABASE=FO13FF-65 PC-CAM
+
+usb:v05C8p021A*
+ ID_PRODUCT_FROM_DATABASE=HP Webcam
+
+usb:v05C8p0318*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v05C8p0403*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v05C9*
+ ID_VENDOR_FROM_DATABASE=Semtech Corp.
+
+usb:v05CA*
+ ID_VENDOR_FROM_DATABASE=Ricoh Co., Ltd
+
+usb:v05CAp0101*
+ ID_PRODUCT_FROM_DATABASE=RDC-5300 Camera
+
+usb:v05CAp0325*
+ ID_PRODUCT_FROM_DATABASE=Caplio GX (ptp)
+
+usb:v05CAp032D*
+ ID_PRODUCT_FROM_DATABASE=Caplio GX 8 (ptp)
+
+usb:v05CAp032F*
+ ID_PRODUCT_FROM_DATABASE=Caplio R3 (ptp)
+
+usb:v05CAp03A1*
+ ID_PRODUCT_FROM_DATABASE=IS200e
+
+usb:v05CAp0403*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v05CAp0405*
+ ID_PRODUCT_FROM_DATABASE=Type 101
+
+usb:v05CAp0406*
+ ID_PRODUCT_FROM_DATABASE=Type 102
+
+usb:v05CAp1803*
+ ID_PRODUCT_FROM_DATABASE=V5 camera [R5U870]
+
+usb:v05CAp1810*
+ ID_PRODUCT_FROM_DATABASE=Pavilion Webcam [R5U870]
+
+usb:v05CAp1812*
+ ID_PRODUCT_FROM_DATABASE=Pavilion Webcam
+
+usb:v05CAp1814*
+ ID_PRODUCT_FROM_DATABASE=HD Webcam
+
+usb:v05CAp1820*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v05CAp1830*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC2 [R5U870]
+
+usb:v05CAp1832*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC3 [R5U870]
+
+usb:v05CAp1833*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC2 [R5U870]
+
+usb:v05CAp1834*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC2 [R5U870]
+
+usb:v05CAp1835*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC5 [R5U870]
+
+usb:v05CAp1836*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC4 [R5U870]
+
+usb:v05CAp1837*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC4 [R5U870]
+
+usb:v05CAp1839*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC6 [R5U870]
+
+usb:v05CAp183A*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC7 [R5U870]
+
+usb:v05CAp183B*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC8 [R5U870]
+
+usb:v05CAp183D*
+ ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam
+
+usb:v05CAp183E*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC9 [R5U870]
+
+usb:v05CAp1841*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu F01/ Lifebook U810 [R5U870]
+
+usb:v05CAp1870*
+ ID_PRODUCT_FROM_DATABASE=Webcam 1000
+
+usb:v05CAp18B0*
+ ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam
+
+usb:v05CAp18B1*
+ ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam
+
+usb:v05CAp18B3*
+ ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam
+
+usb:v05CAp18B5*
+ ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam
+
+usb:v05CAp2201*
+ ID_PRODUCT_FROM_DATABASE=RDC-7 Camera
+
+usb:v05CAp2202*
+ ID_PRODUCT_FROM_DATABASE=Caplio RR30
+
+usb:v05CAp2203*
+ ID_PRODUCT_FROM_DATABASE=Caplio 300G
+
+usb:v05CAp2204*
+ ID_PRODUCT_FROM_DATABASE=Caplio G3
+
+usb:v05CAp2205*
+ ID_PRODUCT_FROM_DATABASE=Caplio RR30 / Medion MD 6126 Camera
+
+usb:v05CAp2206*
+ ID_PRODUCT_FROM_DATABASE=Konica DG-3Z
+
+usb:v05CAp2207*
+ ID_PRODUCT_FROM_DATABASE=Caplio Pro G3
+
+usb:v05CAp2208*
+ ID_PRODUCT_FROM_DATABASE=Caplio G4
+
+usb:v05CAp2209*
+ ID_PRODUCT_FROM_DATABASE=Caplio 400G wide
+
+usb:v05CAp220A*
+ ID_PRODUCT_FROM_DATABASE=KONICA MINOLTA DG-4Wide
+
+usb:v05CAp220B*
+ ID_PRODUCT_FROM_DATABASE=Caplio RX
+
+usb:v05CAp220C*
+ ID_PRODUCT_FROM_DATABASE=Caplio GX
+
+usb:v05CAp220D*
+ ID_PRODUCT_FROM_DATABASE=Caplio R1/RZ1
+
+usb:v05CAp220E*
+ ID_PRODUCT_FROM_DATABASE=Sea & Sea 5000G
+
+usb:v05CAp220F*
+ ID_PRODUCT_FROM_DATABASE=Rollei dr5 / Rollei dr5 (PTP mode)
+
+usb:v05CAp2211*
+ ID_PRODUCT_FROM_DATABASE=Caplio R1S
+
+usb:v05CAp2212*
+ ID_PRODUCT_FROM_DATABASE=Caplio R1v Camera
+
+usb:v05CAp2213*
+ ID_PRODUCT_FROM_DATABASE=Caplio R2
+
+usb:v05CAp2214*
+ ID_PRODUCT_FROM_DATABASE=Caplio GX 8
+
+usb:v05CAp2215*
+ ID_PRODUCT_FROM_DATABASE=DSC 725
+
+usb:v05CAp2216*
+ ID_PRODUCT_FROM_DATABASE=Caplio R3
+
+usb:v05CAp2222*
+ ID_PRODUCT_FROM_DATABASE=RDC-i500
+
+usb:v05CB*
+ ID_VENDOR_FROM_DATABASE=PowerVision Technologies, Inc.
+
+usb:v05CBp1483*
+ ID_PRODUCT_FROM_DATABASE=PV8630 interface (scanners, webcams)
+
+usb:v05CC*
+ ID_VENDOR_FROM_DATABASE=ELSA AG
+
+usb:v05CCp2100*
+ ID_PRODUCT_FROM_DATABASE=MicroLink ISDN Office
+
+usb:v05CCp2219*
+ ID_PRODUCT_FROM_DATABASE=MicroLink ISDN
+
+usb:v05CCp2265*
+ ID_PRODUCT_FROM_DATABASE=MicroLink 56k
+
+usb:v05CCp2267*
+ ID_PRODUCT_FROM_DATABASE=MicroLink 56k (V.250)
+
+usb:v05CCp2280*
+ ID_PRODUCT_FROM_DATABASE=MicroLink 56k Fun
+
+usb:v05CCp3000*
+ ID_PRODUCT_FROM_DATABASE=Micolink USB2Ethernet [pegasus]
+
+usb:v05CCp3100*
+ ID_PRODUCT_FROM_DATABASE=AirLancer USB-11
+
+usb:v05CCp3363*
+ ID_PRODUCT_FROM_DATABASE=MicroLink ADSL Fun
+
+usb:v05CD*
+ ID_VENDOR_FROM_DATABASE=Silicom, Ltd
+
+usb:v05CE*
+ ID_VENDOR_FROM_DATABASE=sci-worx GmbH
+
+usb:v05CF*
+ ID_VENDOR_FROM_DATABASE=Sung Forn Co., Ltd
+
+usb:v05D0*
+ ID_VENDOR_FROM_DATABASE=GE Medical Systems Lunar
+
+usb:v05D1*
+ ID_VENDOR_FROM_DATABASE=Brainboxes, Ltd
+
+usb:v05D1p0003*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter BL-554
+
+usb:v05D2*
+ ID_VENDOR_FROM_DATABASE=Wave Systems Corp.
+
+usb:v05D3*
+ ID_VENDOR_FROM_DATABASE=Tohoku Ricoh Co., Ltd
+
+usb:v05D5*
+ ID_VENDOR_FROM_DATABASE=Super Gate Technology Co., Ltd
+
+usb:v05D6*
+ ID_VENDOR_FROM_DATABASE=Philips Semiconductors, CICT
+
+usb:v05D7*
+ ID_VENDOR_FROM_DATABASE=Thomas & Betts Corp.
+
+usb:v05D7p0099*
+ ID_PRODUCT_FROM_DATABASE=10Mbps Ethernet [klsi]
+
+usb:v05D8*
+ ID_VENDOR_FROM_DATABASE=Ultima Electronics Corp.
+
+usb:v05D8p4001*
+ ID_PRODUCT_FROM_DATABASE=Artec Ultima 2000
+
+usb:v05D8p4002*
+ ID_PRODUCT_FROM_DATABASE=Artec Ultima 2000 (GT6801 based)/Lifetec LT9385/ScanMagic 1200 UB Plus Scanner
+
+usb:v05D8p4003*
+ ID_PRODUCT_FROM_DATABASE=Artec E+ 48U
+
+usb:v05D8p4004*
+ ID_PRODUCT_FROM_DATABASE=Artec E+ Pro
+
+usb:v05D8p4005*
+ ID_PRODUCT_FROM_DATABASE=MEM48U
+
+usb:v05D8p4006*
+ ID_PRODUCT_FROM_DATABASE=TRUST EASY WEBSCAN 19200
+
+usb:v05D8p4007*
+ ID_PRODUCT_FROM_DATABASE=TRUST 240H EASY WEBSCAN GOLD
+
+usb:v05D8p4008*
+ ID_PRODUCT_FROM_DATABASE=Trust Easy Webscan 19200
+
+usb:v05D8p4009*
+ ID_PRODUCT_FROM_DATABASE=Umax Astraslim
+
+usb:v05D8p4013*
+ ID_PRODUCT_FROM_DATABASE=IT Scan 1200
+
+usb:v05D8p8105*
+ ID_PRODUCT_FROM_DATABASE=Artec T1 USB TVBOX (cold)
+
+usb:v05D8p8106*
+ ID_PRODUCT_FROM_DATABASE=Artec T1 USB TVBOX (warm)
+
+usb:v05D8p8107*
+ ID_PRODUCT_FROM_DATABASE=Artec T1 USB TVBOX with AN2235 (cold)
+
+usb:v05D8p8108*
+ ID_PRODUCT_FROM_DATABASE=Artec T1 USB TVBOX with AN2235 (warm)
+
+usb:v05D8p8109*
+ ID_PRODUCT_FROM_DATABASE=Artec T1 USB2.0 TVBOX (cold
+
+usb:v05D9*
+ ID_VENDOR_FROM_DATABASE=Axiohm Transaction Solutions
+
+usb:v05D9pA225*
+ ID_PRODUCT_FROM_DATABASE=A225 Printer
+
+usb:v05D9pA758*
+ ID_PRODUCT_FROM_DATABASE=A758 Printer
+
+usb:v05D9pA794*
+ ID_PRODUCT_FROM_DATABASE=A794 Printer
+
+usb:v05DA*
+ ID_VENDOR_FROM_DATABASE=Microtek International, Inc.
+
+usb:v05DAp0091*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker X6u
+
+usb:v05DAp0093*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker V6USL
+
+usb:v05DAp0094*
+ ID_PRODUCT_FROM_DATABASE=Phantom 336CX/C3
+
+usb:v05DAp0099*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker X6/X6U
+
+usb:v05DAp009A*
+ ID_PRODUCT_FROM_DATABASE=Phantom C6
+
+usb:v05DAp00A0*
+ ID_PRODUCT_FROM_DATABASE=Phantom 336CX/C3 (#2)
+
+usb:v05DAp00A3*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker V6USL
+
+usb:v05DAp00AC*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker V6UL
+
+usb:v05DAp00B6*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker V6UPL
+
+usb:v05DAp00EF*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker V6UPL
+
+usb:v05DAp1006*
+ ID_PRODUCT_FROM_DATABASE=Jenoptik JD350 entrance
+
+usb:v05DAp1011*
+ ID_PRODUCT_FROM_DATABASE=NHJ Che-ez! Kiss Digital Camera
+
+usb:v05DAp1018*
+ ID_PRODUCT_FROM_DATABASE=Digital Dream Enigma 1.3
+
+usb:v05DAp1020*
+ ID_PRODUCT_FROM_DATABASE=Digital Dream l'espion xtra
+
+usb:v05DAp1025*
+ ID_PRODUCT_FROM_DATABASE=Take-it Still Camera Device
+
+usb:v05DAp1026*
+ ID_PRODUCT_FROM_DATABASE=Take-it
+
+usb:v05DAp1043*
+ ID_PRODUCT_FROM_DATABASE=Take-It 1300 DSC Bulk Driver
+
+usb:v05DAp1045*
+ ID_PRODUCT_FROM_DATABASE=Take-it D1
+
+usb:v05DAp1047*
+ ID_PRODUCT_FROM_DATABASE=Take-it Camera Composite Device
+
+usb:v05DAp1048*
+ ID_PRODUCT_FROM_DATABASE=Take-it Q3
+
+usb:v05DAp1049*
+ ID_PRODUCT_FROM_DATABASE=3M Still Camera Device
+
+usb:v05DAp1051*
+ ID_PRODUCT_FROM_DATABASE=Camcorder Series
+
+usb:v05DAp1052*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v05DAp1053*
+ ID_PRODUCT_FROM_DATABASE=Take-it DV Composite Device
+
+usb:v05DAp1054*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v05DAp1055*
+ ID_PRODUCT_FROM_DATABASE=Digital Camera Series(536)
+
+usb:v05DAp1056*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v05DAp1057*
+ ID_PRODUCT_FROM_DATABASE=Take-it DSC Camera Device(536)
+
+usb:v05DAp1058*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v05DAp1059*
+ ID_PRODUCT_FROM_DATABASE=Camcorder DSC Series
+
+usb:v05DAp1060*
+ ID_PRODUCT_FROM_DATABASE=Microtek Take-it MV500
+
+usb:v05DAp2007*
+ ID_PRODUCT_FROM_DATABASE=ArtixScan DI 1210
+
+usb:v05DAp200C*
+ ID_PRODUCT_FROM_DATABASE=1394_USB2 Scanner
+
+usb:v05DAp200E*
+ ID_PRODUCT_FROM_DATABASE=ArtixScan DI 810
+
+usb:v05DAp2017*
+ ID_PRODUCT_FROM_DATABASE=UF ICE Scanner
+
+usb:v05DAp201C*
+ ID_PRODUCT_FROM_DATABASE=4800 Scanner
+
+usb:v05DAp201D*
+ ID_PRODUCT_FROM_DATABASE=ArtixScan DI 1610
+
+usb:v05DAp201F*
+ ID_PRODUCT_FROM_DATABASE=4800 Scanner-ICE
+
+usb:v05DAp202E*
+ ID_PRODUCT_FROM_DATABASE=ArtixScan DI 2020
+
+usb:v05DAp208B*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 6800
+
+usb:v05DAp208F*
+ ID_PRODUCT_FROM_DATABASE=ArtixScan DI 2010
+
+usb:v05DAp209E*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 4700LP
+
+usb:v05DAp20A7*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 5600
+
+usb:v05DAp20B0*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker X12USL
+
+usb:v05DAp20B1*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 8700
+
+usb:v05DAp20B4*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 4700
+
+usb:v05DAp20BD*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 5700
+
+usb:v05DAp20C9*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 6700
+
+usb:v05DAp20D2*
+ ID_PRODUCT_FROM_DATABASE=Microtek ArtixScan 1800f
+
+usb:v05DAp20D6*
+ ID_PRODUCT_FROM_DATABASE=PS4000
+
+usb:v05DAp20DE*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 9800XL
+
+usb:v05DAp20E0*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 9700XL
+
+usb:v05DAp20ED*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 4700
+
+usb:v05DAp20EE*
+ ID_PRODUCT_FROM_DATABASE=Micortek ScanMaker X12USL
+
+usb:v05DAp3008*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v05DAp300A*
+ ID_PRODUCT_FROM_DATABASE=4800 ICE Scanner
+
+usb:v05DAp300B*
+ ID_PRODUCT_FROM_DATABASE=4800 Scanner
+
+usb:v05DAp300F*
+ ID_PRODUCT_FROM_DATABASE=MiniScan C5
+
+usb:v05DAp3020*
+ ID_PRODUCT_FROM_DATABASE=4800dpi Scanner
+
+usb:v05DAp3021*
+ ID_PRODUCT_FROM_DATABASE=1200dpi Scanner
+
+usb:v05DAp3022*
+ ID_PRODUCT_FROM_DATABASE=Scanner 4800dpi
+
+usb:v05DAp3023*
+ ID_PRODUCT_FROM_DATABASE=USB1200II Scanner
+
+usb:v05DAp30C1*
+ ID_PRODUCT_FROM_DATABASE=USB600 Scanner
+
+usb:v05DAp30CE*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 3800
+
+usb:v05DAp30CF*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 4800
+
+usb:v05DAp30D4*
+ ID_PRODUCT_FROM_DATABASE=USB1200 Scanner
+
+usb:v05DAp30D8*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v05DAp30D9*
+ ID_PRODUCT_FROM_DATABASE=USB2400 Scanner
+
+usb:v05DAp30E4*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 4100
+
+usb:v05DAp30E5*
+ ID_PRODUCT_FROM_DATABASE=USB3200 Scanner
+
+usb:v05DAp30E6*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker i320
+
+usb:v05DAp40B3*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 3600
+
+usb:v05DAp40B8*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 3700
+
+usb:v05DAp40C7*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 4600
+
+usb:v05DAp40CA*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 3600
+
+usb:v05DAp40CB*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 3700
+
+usb:v05DAp40DD*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 3750i
+
+usb:v05DAp40FF*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 3600
+
+usb:v05DAp5003*
+ ID_PRODUCT_FROM_DATABASE=Goya
+
+usb:v05DAp5013*
+ ID_PRODUCT_FROM_DATABASE=3200 Scanner
+
+usb:v05DAp80A3*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker V6USL (#2)
+
+usb:v05DAp80AC*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker V6UL/SpicyU
+
+usb:v05DB*
+ ID_VENDOR_FROM_DATABASE=Sun Corp. (Suntac?)
+
+usb:v05DBp0003*
+ ID_PRODUCT_FROM_DATABASE=SUNTAC U-Cable type D2
+
+usb:v05DBp0005*
+ ID_PRODUCT_FROM_DATABASE=SUNTAC U-Cable type P1
+
+usb:v05DBp0009*
+ ID_PRODUCT_FROM_DATABASE=SUNTAC Slipper U
+
+usb:v05DBp000A*
+ ID_PRODUCT_FROM_DATABASE=SUNTAC Ir-Trinity
+
+usb:v05DBp000B*
+ ID_PRODUCT_FROM_DATABASE=SUNTAC U-Cable type A3
+
+usb:v05DBp0011*
+ ID_PRODUCT_FROM_DATABASE=SUNTAC U-Cable type A4
+
+usb:v05DC*
+ ID_VENDOR_FROM_DATABASE=Lexar Media, Inc.
+
+usb:v05DCp0001*
+ ID_PRODUCT_FROM_DATABASE=jumpSHOT CompactFlash Reader
+
+usb:v05DCp0002*
+ ID_PRODUCT_FROM_DATABASE=JumpShot
+
+usb:v05DCp0003*
+ ID_PRODUCT_FROM_DATABASE=JumpShot
+
+usb:v05DCp0080*
+ ID_PRODUCT_FROM_DATABASE=Jumpdrive Secure 64MB
+
+usb:v05DCp0081*
+ ID_PRODUCT_FROM_DATABASE=RBC Compact Flash Drive
+
+usb:v05DCp00A7*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Impact
+
+usb:v05DCp0100*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive PRO
+
+usb:v05DCp0200*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive 2.0 Pro
+
+usb:v05DCp0300*
+ ID_PRODUCT_FROM_DATABASE=Jumpdrive Geysr
+
+usb:v05DCp0301*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Classic
+
+usb:v05DCp0302*
+ ID_PRODUCT_FROM_DATABASE=JD Micro
+
+usb:v05DCp0303*
+ ID_PRODUCT_FROM_DATABASE=JD Micro Pro
+
+usb:v05DCp0304*
+ ID_PRODUCT_FROM_DATABASE=JD Secure II
+
+usb:v05DCp0310*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive
+
+usb:v05DCp0311*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Classic
+
+usb:v05DCp0312*
+ ID_PRODUCT_FROM_DATABASE=JD Micro
+
+usb:v05DCp0313*
+ ID_PRODUCT_FROM_DATABASE=JD Micro Pro
+
+usb:v05DCp0320*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive
+
+usb:v05DCp0321*
+ ID_PRODUCT_FROM_DATABASE=JD Micro
+
+usb:v05DCp0322*
+ ID_PRODUCT_FROM_DATABASE=JD Micro Pro
+
+usb:v05DCp0323*
+ ID_PRODUCT_FROM_DATABASE=UFC
+
+usb:v05DCp0330*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Expression
+
+usb:v05DCp0340*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive TAD
+
+usb:v05DCp0350*
+ ID_PRODUCT_FROM_DATABASE=Express Card
+
+usb:v05DCp0400*
+ ID_PRODUCT_FROM_DATABASE=UFDC
+
+usb:v05DCp0401*
+ ID_PRODUCT_FROM_DATABASE=UFDC
+
+usb:v05DCp0403*
+ ID_PRODUCT_FROM_DATABASE=Locked B Device
+
+usb:v05DCp0405*
+ ID_PRODUCT_FROM_DATABASE=Locked C Device
+
+usb:v05DCp0407*
+ ID_PRODUCT_FROM_DATABASE=Locked D Device
+
+usb:v05DCp0409*
+ ID_PRODUCT_FROM_DATABASE=Locked E Device
+
+usb:v05DCp040B*
+ ID_PRODUCT_FROM_DATABASE=Locked F Device
+
+usb:v05DCp040D*
+ ID_PRODUCT_FROM_DATABASE=Locked G Device
+
+usb:v05DCp040F*
+ ID_PRODUCT_FROM_DATABASE=Locked H Device
+
+usb:v05DCp0410*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive
+
+usb:v05DCp0411*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive
+
+usb:v05DCp0413*
+ ID_PRODUCT_FROM_DATABASE=Locked J Device
+
+usb:v05DCp0415*
+ ID_PRODUCT_FROM_DATABASE=Locked K Device
+
+usb:v05DCp0417*
+ ID_PRODUCT_FROM_DATABASE=Locked L Device
+
+usb:v05DCp0419*
+ ID_PRODUCT_FROM_DATABASE=Locked M Device
+
+usb:v05DCp041B*
+ ID_PRODUCT_FROM_DATABASE=Locked N Device
+
+usb:v05DCp041D*
+ ID_PRODUCT_FROM_DATABASE=Locked O Device
+
+usb:v05DCp041F*
+ ID_PRODUCT_FROM_DATABASE=Locked P Device
+
+usb:v05DCp0420*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive
+
+usb:v05DCp0421*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive
+
+usb:v05DCp0423*
+ ID_PRODUCT_FROM_DATABASE=Locked R Device
+
+usb:v05DCp0425*
+ ID_PRODUCT_FROM_DATABASE=Locked S Device
+
+usb:v05DCp0427*
+ ID_PRODUCT_FROM_DATABASE=Locked T Device
+
+usb:v05DCp0429*
+ ID_PRODUCT_FROM_DATABASE=Locked U Device
+
+usb:v05DCp042B*
+ ID_PRODUCT_FROM_DATABASE=Locked V Device
+
+usb:v05DCp042D*
+ ID_PRODUCT_FROM_DATABASE=Locked W Device
+
+usb:v05DCp042F*
+ ID_PRODUCT_FROM_DATABASE=Locked X Device
+
+usb:v05DCp0431*
+ ID_PRODUCT_FROM_DATABASE=Locked Y Device
+
+usb:v05DCp0433*
+ ID_PRODUCT_FROM_DATABASE=Locked Z Device
+
+usb:v05DCp4D02*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v05DCp4D12*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v05DCp4D30*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v05DCpA300*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive2
+
+usb:v05DCpA400*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive trade; Pro 40-501
+
+usb:v05DCpA410*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive 128MB/256MB
+
+usb:v05DCpA411*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Traveler
+
+usb:v05DCpA420*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Pro
+
+usb:v05DCpA421*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Pro II
+
+usb:v05DCpA422*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Micro Pro
+
+usb:v05DCpA430*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Secure
+
+usb:v05DCpA431*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Secure II
+
+usb:v05DCpA432*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Classic
+
+usb:v05DCpA440*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Lightning
+
+usb:v05DCpA450*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive TouchGuard
+
+usb:v05DCpA460*
+ ID_PRODUCT_FROM_DATABASE=JD Mercury
+
+usb:v05DCpA501*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Classic
+
+usb:v05DCpA510*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Sport
+
+usb:v05DCpA530*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Expression
+
+usb:v05DCpA531*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive Secure II
+
+usb:v05DCpA560*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive FireFly
+
+usb:v05DCpA701*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive FireFly
+
+usb:v05DCpA731*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive FireFly
+
+usb:v05DCpA790*
+ ID_PRODUCT_FROM_DATABASE=JumpDrive 2GB
+
+usb:v05DCpA811*
+ ID_PRODUCT_FROM_DATABASE=16GB Gizmo!
+
+usb:v05DCpA813*
+ ID_PRODUCT_FROM_DATABASE=16gB flash thumb drive
+
+usb:v05DCpB002*
+ ID_PRODUCT_FROM_DATABASE=USB CF Reader
+
+usb:v05DCpB018*
+ ID_PRODUCT_FROM_DATABASE=Multi-Card Reader
+
+usb:v05DCpB047*
+ ID_PRODUCT_FROM_DATABASE=SDHC Reader [RW047-7000]
+
+usb:v05DD*
+ ID_VENDOR_FROM_DATABASE=Delta Electronics, Inc.
+
+usb:v05DDpFF31*
+ ID_PRODUCT_FROM_DATABASE=AWU-120
+
+usb:v05DDpFF32*
+ ID_PRODUCT_FROM_DATABASE=FriendlyNET AeroLAN AL2011
+
+usb:v05DDpFF35*
+ ID_PRODUCT_FROM_DATABASE=PCW 100 - Wireless 802.11b Adapter
+
+usb:v05DDpFF91*
+ ID_PRODUCT_FROM_DATABASE=2Wire PC Port Phoneline 10Mbps Adapter
+
+usb:v05DF*
+ ID_VENDOR_FROM_DATABASE=Silicon Vision, Inc.
+
+usb:v05E0*
+ ID_VENDOR_FROM_DATABASE=Symbol Technologies
+
+usb:v05E0p0700*
+ ID_PRODUCT_FROM_DATABASE=Bar Code Scanner (CS1504)
+
+usb:v05E0p0800*
+ ID_PRODUCT_FROM_DATABASE=Spectrum24 Wireless LAN Adapter
+
+usb:v05E0p1200*
+ ID_PRODUCT_FROM_DATABASE=Bar Code Scanner
+
+usb:v05E0p1900*
+ ID_PRODUCT_FROM_DATABASE=SNAPI Imaging Device
+
+usb:v05E0p2000*
+ ID_PRODUCT_FROM_DATABASE=MC3090 Rugged Mobile Computer
+
+usb:v05E0p200D*
+ ID_PRODUCT_FROM_DATABASE=MC70 Rugged Mobile Computer
+
+usb:v05E1*
+ ID_VENDOR_FROM_DATABASE=Syntek Semiconductor Co., Ltd
+
+usb:v05E1p0100*
+ ID_PRODUCT_FROM_DATABASE=802.11g + Bluetooth Wireless Adapter
+
+usb:v05E1p0408*
+ ID_PRODUCT_FROM_DATABASE=STK1160 Video Capture Device
+
+usb:v05E1p0500*
+ ID_PRODUCT_FROM_DATABASE=DC-112X Webcam
+
+usb:v05E1p0501*
+ ID_PRODUCT_FROM_DATABASE=DC-1125 Webcam
+
+usb:v05E1p0890*
+ ID_PRODUCT_FROM_DATABASE=STK011 Camera
+
+usb:v05E1p0892*
+ ID_PRODUCT_FROM_DATABASE=STK013 Camera
+
+usb:v05E1p0895*
+ ID_PRODUCT_FROM_DATABASE=STK016 Camera
+
+usb:v05E1p0896*
+ ID_PRODUCT_FROM_DATABASE=STK017 Camera
+
+usb:v05E2*
+ ID_VENDOR_FROM_DATABASE=ElecVision, Inc.
+
+usb:v05E3*
+ ID_VENDOR_FROM_DATABASE=Genesys Logic, Inc.
+
+usb:v05E3p000A*
+ ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Port
+
+usb:v05E3p000B*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v05E3p0100*
+ ID_PRODUCT_FROM_DATABASE=Nintendo Game Boy Advance SP
+
+usb:v05E3p0120*
+ ID_PRODUCT_FROM_DATABASE=Pacific Image Electronics PrimeFilm 1800u slide/negative scanner
+
+usb:v05E3p0131*
+ ID_PRODUCT_FROM_DATABASE=CF/SM Reader/Writer
+
+usb:v05E3p0142*
+ ID_PRODUCT_FROM_DATABASE=Multiple Slides Scanner-3600
+
+usb:v05E3p0143*
+ ID_PRODUCT_FROM_DATABASE=Multiple Frames Film Scanner-36series
+
+usb:v05E3p0180*
+ ID_PRODUCT_FROM_DATABASE=Plustek Scanner
+
+usb:v05E3p0182*
+ ID_PRODUCT_FROM_DATABASE=Wize Media 1000
+
+usb:v05E3p0189*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4600 series
+
+usb:v05E3p018A*
+ ID_PRODUCT_FROM_DATABASE=Xerox 6400
+
+usb:v05E3p0300*
+ ID_PRODUCT_FROM_DATABASE=GLUSB98PT Parallel Port
+
+usb:v05E3p0301*
+ ID_PRODUCT_FROM_DATABASE=USB2LPT Cable Release2
+
+usb:v05E3p0406*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v05E3p0501*
+ ID_PRODUCT_FROM_DATABASE=GL620USB Host-Host interface
+
+usb:v05E3p0502*
+ ID_PRODUCT_FROM_DATABASE=GL620USB-A GeneLink USB-USB Bridge
+
+usb:v05E3p0503*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v05E3p0504*
+ ID_PRODUCT_FROM_DATABASE=HID Keyboard Filter
+
+usb:v05E3p0604*
+ ID_PRODUCT_FROM_DATABASE=USB 1.1 Hub
+
+usb:v05E3p0605*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v05E3p0606*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub / D-Link DUB-H4 USB 2.0 Hub
+
+usb:v05E3p0607*
+ ID_PRODUCT_FROM_DATABASE=Logitech G110 Hub
+
+usb:v05E3p0608*
+ ID_PRODUCT_FROM_DATABASE=USB-2.0 4-Port HUB
+
+usb:v05E3p0610*
+ ID_PRODUCT_FROM_DATABASE=4-port hub
+
+usb:v05E3p0660*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub
+
+usb:v05E3p0700*
+ ID_PRODUCT_FROM_DATABASE=SIIG US2256 CompactFlash Card Reader
+
+usb:v05E3p0701*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 IDE Adapter
+
+usb:v05E3p0702*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 IDE Adapter [GL811E]
+
+usb:v05E3p0703*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p0704*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p0705*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p0706*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p0707*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p0708*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p0709*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p070A*
+ ID_PRODUCT_FROM_DATABASE=Pen Flash
+
+usb:v05E3p070B*
+ ID_PRODUCT_FROM_DATABASE=DMHS1B Rev 3 DFU Adapter
+
+usb:v05E3p070E*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader
+
+usb:v05E3p070F*
+ ID_PRODUCT_FROM_DATABASE=Pen Flash
+
+usb:v05E3p0710*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 33-in-1 Card Reader
+
+usb:v05E3p0711*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p0712*
+ ID_PRODUCT_FROM_DATABASE=Delkin Mass Storage Device
+
+usb:v05E3p0715*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 microSD Reader
+
+usb:v05E3p0716*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Multislot Card Reader/Writer
+
+usb:v05E3p0717*
+ ID_PRODUCT_FROM_DATABASE=All-in-1 Card Reader
+
+usb:v05E3p0718*
+ ID_PRODUCT_FROM_DATABASE=IDE/SATA Adapter
+
+usb:v05E3p0719*
+ ID_PRODUCT_FROM_DATABASE=SATA adapter
+
+usb:v05E3p0723*
+ ID_PRODUCT_FROM_DATABASE=GL827L SD/MMC/MS Flash Card Reader
+
+usb:v05E3p0726*
+ ID_PRODUCT_FROM_DATABASE=SD Card Reader
+
+usb:v05E3p0727*
+ ID_PRODUCT_FROM_DATABASE=microSD Reader/Writer
+
+usb:v05E3p0736*
+ ID_PRODUCT_FROM_DATABASE=microSD Reader/Writer
+
+usb:v05E3p0760*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader/Writer
+
+usb:v05E3p0761*
+ ID_PRODUCT_FROM_DATABASE=Genesys Mass Storage Device
+
+usb:v05E3p0780*
+ ID_PRODUCT_FROM_DATABASE=USBFS DFU Adapter
+
+usb:v05E3p07A0*
+ ID_PRODUCT_FROM_DATABASE=Pen Flash
+
+usb:v05E3p0880*
+ ID_PRODUCT_FROM_DATABASE=Wasp (SL-6612)
+
+usb:v05E3p0927*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v05E3p1205*
+ ID_PRODUCT_FROM_DATABASE=Afilias Optical Mouse H3003 / Trust Optical USB MultiColour Mouse MI-2330
+
+usb:v05E3pA700*
+ ID_PRODUCT_FROM_DATABASE=Pen Flash
+
+usb:v05E3pF102*
+ ID_PRODUCT_FROM_DATABASE=VX7012 TV Box
+
+usb:v05E3pF103*
+ ID_PRODUCT_FROM_DATABASE=VX7012 TV Box
+
+usb:v05E3pF104*
+ ID_PRODUCT_FROM_DATABASE=VX7012 TV Box
+
+usb:v05E3pFD21*
+ ID_PRODUCT_FROM_DATABASE=3M TL20 Temperature Logger
+
+usb:v05E3pFE00*
+ ID_PRODUCT_FROM_DATABASE=Razer Mouse
+
+usb:v05E4*
+ ID_VENDOR_FROM_DATABASE=Red Wing Corp.
+
+usb:v05E5*
+ ID_VENDOR_FROM_DATABASE=Fuji Electric Co., Ltd
+
+usb:v05E6*
+ ID_VENDOR_FROM_DATABASE=Keithley Instruments
+
+usb:v05E8*
+ ID_VENDOR_FROM_DATABASE=ICC, Inc.
+
+usb:v05E9*
+ ID_VENDOR_FROM_DATABASE=Kawasaki LSI
+
+usb:v05E9p0008*
+ ID_PRODUCT_FROM_DATABASE=KL5KUSB101B Ethernet [klsi]
+
+usb:v05E9p0009*
+ ID_PRODUCT_FROM_DATABASE=Sony 10Mbps Ethernet [pegasus]
+
+usb:v05E9p000C*
+ ID_PRODUCT_FROM_DATABASE=USB-to-RS-232
+
+usb:v05E9p000D*
+ ID_PRODUCT_FROM_DATABASE=USB-to-RS-232
+
+usb:v05E9p0014*
+ ID_PRODUCT_FROM_DATABASE=RS-232 J104
+
+usb:v05E9p0040*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Adapter
+
+usb:v05E9p2008*
+ ID_PRODUCT_FROM_DATABASE=Ethernet Adapter
+
+usb:v05EB*
+ ID_VENDOR_FROM_DATABASE=FFC, Ltd
+
+usb:v05EC*
+ ID_VENDOR_FROM_DATABASE=COM21, Inc.
+
+usb:v05EE*
+ ID_VENDOR_FROM_DATABASE=Cytechinfo Inc.
+
+usb:v05EF*
+ ID_VENDOR_FROM_DATABASE=AVB, Inc. [anko?]
+
+usb:v05EFp020A*
+ ID_PRODUCT_FROM_DATABASE=Top Shot Pegasus Joystick
+
+usb:v05EFp8884*
+ ID_PRODUCT_FROM_DATABASE=Mag Turbo Force Wheel
+
+usb:v05EFp8888*
+ ID_PRODUCT_FROM_DATABASE=Top Shot Force Feedback Racing Wheel
+
+usb:v05F0*
+ ID_VENDOR_FROM_DATABASE=Canopus Co., Ltd
+
+usb:v05F0p0101*
+ ID_PRODUCT_FROM_DATABASE=DA-Port DAC
+
+usb:v05F1*
+ ID_VENDOR_FROM_DATABASE=Compass Communications
+
+usb:v05F2*
+ ID_VENDOR_FROM_DATABASE=Dexin Corp., Ltd
+
+usb:v05F2p0010*
+ ID_PRODUCT_FROM_DATABASE=AQ Mouse
+
+usb:v05F3*
+ ID_VENDOR_FROM_DATABASE=PI Engineering, Inc.
+
+usb:v05F3p0007*
+ ID_PRODUCT_FROM_DATABASE=Kinesis Advantage PRO MPC/USB Keyboard
+
+usb:v05F3p0081*
+ ID_PRODUCT_FROM_DATABASE=Kinesis Integrated Hub
+
+usb:v05F3p00FF*
+ ID_PRODUCT_FROM_DATABASE=VEC Footpedal
+
+usb:v05F3p020B*
+ ID_PRODUCT_FROM_DATABASE=PS2 Adapter
+
+usb:v05F3p0232*
+ ID_PRODUCT_FROM_DATABASE=X-Keys Switch Interface, Programming Mode
+
+usb:v05F3p0261*
+ ID_PRODUCT_FROM_DATABASE=X-Keys Switch Interface, SPLAT Mode
+
+usb:v05F3p0264*
+ ID_PRODUCT_FROM_DATABASE=X-Keys Switch Interface, Composite Mode
+
+usb:v05F5*
+ ID_VENDOR_FROM_DATABASE=Unixtar Technology, Inc.
+
+usb:v05F6*
+ ID_VENDOR_FROM_DATABASE=AOC International
+
+usb:v05F7*
+ ID_VENDOR_FROM_DATABASE=RFC Distribution(s) PTE, Ltd
+
+usb:v05F9*
+ ID_VENDOR_FROM_DATABASE=PSC Scanning, Inc.
+
+usb:v05F9p1104*
+ ID_PRODUCT_FROM_DATABASE=Magellan 2200VS
+
+usb:v05F9p2206*
+ ID_PRODUCT_FROM_DATABASE=Gryphon Barcode Scanner
+
+usb:v05F9p2602*
+ ID_PRODUCT_FROM_DATABASE=Datalogic Magellan 1100i Barcode Scanner
+
+usb:v05FA*
+ ID_VENDOR_FROM_DATABASE=Siemens Telecommunications Systems, Ltd
+
+usb:v05FAp3301*
+ ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Mouse Port
+
+usb:v05FAp3302*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v05FAp3303*
+ ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Mouse Port
+
+usb:v05FC*
+ ID_VENDOR_FROM_DATABASE=Harman Multimedia
+
+usb:v05FCp7849*
+ ID_PRODUCT_FROM_DATABASE=Harman/Kardon SoundSticks
+
+usb:v05FD*
+ ID_VENDOR_FROM_DATABASE=InterAct, Inc.
+
+usb:v05FDp0239*
+ ID_PRODUCT_FROM_DATABASE=SV-239 HammerHead Digital
+
+usb:v05FDp0251*
+ ID_PRODUCT_FROM_DATABASE=Raider Pro
+
+usb:v05FDp0253*
+ ID_PRODUCT_FROM_DATABASE=ProPad 8 Digital
+
+usb:v05FDp0286*
+ ID_PRODUCT_FROM_DATABASE=SV-286 Cyclone Digital
+
+usb:v05FDp107A*
+ ID_PRODUCT_FROM_DATABASE=PowerPad Pro X-Box pad
+
+usb:v05FDp262A*
+ ID_PRODUCT_FROM_DATABASE=3dfx HammerHead FX
+
+usb:v05FDp262F*
+ ID_PRODUCT_FROM_DATABASE=HammerHead Fx
+
+usb:v05FDpDAAE*
+ ID_PRODUCT_FROM_DATABASE=Game Shark
+
+usb:v05FE*
+ ID_VENDOR_FROM_DATABASE=Chic Technology Corp.
+
+usb:v05FEp0001*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v05FEp0003*
+ ID_PRODUCT_FROM_DATABASE=Cypress USB Mouse
+
+usb:v05FEp0005*
+ ID_PRODUCT_FROM_DATABASE=Viewmaster 4D Browser Mouse
+
+usb:v05FEp0007*
+ ID_PRODUCT_FROM_DATABASE=Twinhead Mouse
+
+usb:v05FEp0009*
+ ID_PRODUCT_FROM_DATABASE=Inland Pro 4500/5000 Mouse
+
+usb:v05FEp0011*
+ ID_PRODUCT_FROM_DATABASE=Browser Mouse
+
+usb:v05FEp0014*
+ ID_PRODUCT_FROM_DATABASE=Gamepad
+
+usb:v05FEp1010*
+ ID_PRODUCT_FROM_DATABASE=Optical Wireless
+
+usb:v05FF*
+ ID_VENDOR_FROM_DATABASE=LeCroy Corp.
+
+usb:v0600*
+ ID_VENDOR_FROM_DATABASE=Barco Display Systems
+
+usb:v0601*
+ ID_VENDOR_FROM_DATABASE=Jazz Hipster Corp.
+
+usb:v0601p0003*
+ ID_PRODUCT_FROM_DATABASE=Internet Security Co., Ltd. SecureKey
+
+usb:v0602*
+ ID_VENDOR_FROM_DATABASE=Vista Imaging, Inc.
+
+usb:v0602p1001*
+ ID_PRODUCT_FROM_DATABASE=ViCam Webcam
+
+usb:v0603*
+ ID_VENDOR_FROM_DATABASE=Novatek Microelectronics Corp.
+
+usb:v0603p00F1*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0603p6871*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v0604*
+ ID_VENDOR_FROM_DATABASE=Jean Co., Ltd
+
+usb:v0605*
+ ID_VENDOR_FROM_DATABASE=Anchor C&C Co., Ltd
+
+usb:v0606*
+ ID_VENDOR_FROM_DATABASE=Royal Information Electronics Co., Ltd
+
+usb:v0607*
+ ID_VENDOR_FROM_DATABASE=Bridge Information Co., Ltd
+
+usb:v0608*
+ ID_VENDOR_FROM_DATABASE=Genrad Ads
+
+usb:v0609*
+ ID_VENDOR_FROM_DATABASE=SMK Manufacturing, Inc.
+
+usb:v0609p031D*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0609p0322*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0609p0334*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0609pFF12*
+ ID_PRODUCT_FROM_DATABASE=SMK Bluetooth Device
+
+usb:v060A*
+ ID_VENDOR_FROM_DATABASE=Worthington Data Solutions, Inc.
+
+usb:v060B*
+ ID_VENDOR_FROM_DATABASE=Solid Year
+
+usb:v060Bp0001*
+ ID_PRODUCT_FROM_DATABASE=MacAlly Keyboard
+
+usb:v060Bp0230*
+ ID_PRODUCT_FROM_DATABASE=KSK-8003 UX Keyboard
+
+usb:v060Bp1006*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard - 260U
+
+usb:v060Bp2101*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v060Bp2231*
+ ID_PRODUCT_FROM_DATABASE=KSK-6001 UELX Keyboard
+
+usb:v060Bp2270*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte K8100 Aivia Gaming Keyboard
+
+usb:v060Bp5811*
+ ID_PRODUCT_FROM_DATABASE=ACK-571U Wireless Keyboard
+
+usb:v060Bp5903*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard - 595U
+
+usb:v060Bp6001*
+ ID_PRODUCT_FROM_DATABASE=SolidTek USB 2p HUB
+
+usb:v060Bp6002*
+ ID_PRODUCT_FROM_DATABASE=SolidTek USB Keyboard
+
+usb:v060Bp6003*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard - 600HM
+
+usb:v060Bp6231*
+ ID_PRODUCT_FROM_DATABASE=Thermaltake eSPORTS Meka Keyboard
+
+usb:v060Bp8007*
+ ID_PRODUCT_FROM_DATABASE=P-W1G1F12 VER:1 [Macally MegaCam]
+
+usb:v060BpA001*
+ ID_PRODUCT_FROM_DATABASE=Maxwell Compact Pc PM3
+
+usb:v060C*
+ ID_VENDOR_FROM_DATABASE=EEH Datalink GmbH
+
+usb:v060D*
+ ID_VENDOR_FROM_DATABASE=Auctor Corp.
+
+usb:v060E*
+ ID_VENDOR_FROM_DATABASE=Transmonde Technologies, Inc.
+
+usb:v060F*
+ ID_VENDOR_FROM_DATABASE=Joinsoon Electronics Mfg. Co., Ltd
+
+usb:v0610*
+ ID_VENDOR_FROM_DATABASE=Costar Electronics, Inc.
+
+usb:v0611*
+ ID_VENDOR_FROM_DATABASE=Totoku Electric Co., Ltd
+
+usb:v0613*
+ ID_VENDOR_FROM_DATABASE=TransAct Technologies, Inc.
+
+usb:v0614*
+ ID_VENDOR_FROM_DATABASE=Bio-Rad Laboratories
+
+usb:v0615*
+ ID_VENDOR_FROM_DATABASE=Quabbin Wire & Cable Co., Inc.
+
+usb:v0616*
+ ID_VENDOR_FROM_DATABASE=Future Techno Designs PVT, Ltd
+
+usb:v0617*
+ ID_VENDOR_FROM_DATABASE=Swiss Federal Insitute of Technology
+
+usb:v0618*
+ ID_VENDOR_FROM_DATABASE=MacAlly
+
+usb:v0618p0101*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v0619*
+ ID_VENDOR_FROM_DATABASE=Seiko Instruments, Inc.
+
+usb:v0619p0101*
+ ID_PRODUCT_FROM_DATABASE=SLP-100 Driver
+
+usb:v0619p0102*
+ ID_PRODUCT_FROM_DATABASE=SLP-200 Driver
+
+usb:v0619p0103*
+ ID_PRODUCT_FROM_DATABASE=SLP-100N Driver
+
+usb:v0619p0104*
+ ID_PRODUCT_FROM_DATABASE=SLP-200N Driver
+
+usb:v0619p0105*
+ ID_PRODUCT_FROM_DATABASE=SLP-240 Driver
+
+usb:v0619p0501*
+ ID_PRODUCT_FROM_DATABASE=SLP-440 Driver
+
+usb:v0619p0502*
+ ID_PRODUCT_FROM_DATABASE=SLP-450 Driver
+
+usb:v061A*
+ ID_VENDOR_FROM_DATABASE=Veridicom International, Inc.
+
+usb:v061Ap0110*
+ ID_PRODUCT_FROM_DATABASE=5thSense Fingerprint Sensor
+
+usb:v061Ap0200*
+ ID_PRODUCT_FROM_DATABASE=FPS200 Fingerprint Sensor
+
+usb:v061Ap8200*
+ ID_PRODUCT_FROM_DATABASE=VKI-A Fingerprint Sensor/Flash Storage (dumb)
+
+usb:v061Ap9200*
+ ID_PRODUCT_FROM_DATABASE=VKI-B Fingerprint Sensor/Flash Storage (smart)
+
+usb:v061B*
+ ID_VENDOR_FROM_DATABASE=Promptus Communications, Inc.
+
+usb:v061C*
+ ID_VENDOR_FROM_DATABASE=Act Labs, Ltd
+
+usb:v061D*
+ ID_VENDOR_FROM_DATABASE=Quatech, Inc.
+
+usb:v061DpC020*
+ ID_PRODUCT_FROM_DATABASE=SSU-100
+
+usb:v061E*
+ ID_VENDOR_FROM_DATABASE=Nissei Electric Co.
+
+usb:v061Ep0001*
+ ID_PRODUCT_FROM_DATABASE=nissei 128DE-USB -
+
+usb:v061Ep0010*
+ ID_PRODUCT_FROM_DATABASE=nissei 128DE-PNA -
+
+usb:v0620*
+ ID_VENDOR_FROM_DATABASE=Alaris, Inc.
+
+usb:v0620p0004*
+ ID_PRODUCT_FROM_DATABASE=QuickVideo weeCam
+
+usb:v0620p0007*
+ ID_PRODUCT_FROM_DATABASE=QuickVideo weeCam
+
+usb:v0620p000A*
+ ID_PRODUCT_FROM_DATABASE=QuickVideo weeCam
+
+usb:v0620p000B*
+ ID_PRODUCT_FROM_DATABASE=QuickVideo weeCam
+
+usb:v0621*
+ ID_VENDOR_FROM_DATABASE=ODU-Steckverbindungssysteme GmbH & Co. KG
+
+usb:v0622*
+ ID_VENDOR_FROM_DATABASE=Iotech, Inc.
+
+usb:v0623*
+ ID_VENDOR_FROM_DATABASE=Littelfuse, Inc.
+
+usb:v0624*
+ ID_VENDOR_FROM_DATABASE=Avocent Corp.
+
+usb:v0624p0294*
+ ID_PRODUCT_FROM_DATABASE=Dell 03R874 KVM dongle
+
+usb:v0624p0402*
+ ID_PRODUCT_FROM_DATABASE=Cisco Virtual Keyboard and Mouse
+
+usb:v0624p0403*
+ ID_PRODUCT_FROM_DATABASE=Cisco Virtual Mass Storage
+
+usb:v0625*
+ ID_VENDOR_FROM_DATABASE=TiMedia Technology Co., Ltd
+
+usb:v0626*
+ ID_VENDOR_FROM_DATABASE=Nippon Systems Development Co., Ltd
+
+usb:v0627*
+ ID_VENDOR_FROM_DATABASE=Adomax Technology Co., Ltd
+
+usb:v0628*
+ ID_VENDOR_FROM_DATABASE=Tasking Software, Inc.
+
+usb:v0629*
+ ID_VENDOR_FROM_DATABASE=Zida Technologies, Ltd
+
+usb:v062A*
+ ID_VENDOR_FROM_DATABASE=Creative Labs
+
+usb:v062Ap0000*
+ ID_PRODUCT_FROM_DATABASE=Optical mouse
+
+usb:v062Ap0001*
+ ID_PRODUCT_FROM_DATABASE=Notebook Optical Mouse
+
+usb:v062Ap0102*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard/Mouse Combo [MK1152WC]
+
+usb:v062Ap0201*
+ ID_PRODUCT_FROM_DATABASE=Defender Office Keyboard (K7310) S Zodiak KM-9010
+
+usb:v062Ap0252*
+ ID_PRODUCT_FROM_DATABASE=Emerge Uni-retractable Laser Mouse
+
+usb:v062Ap3286*
+ ID_PRODUCT_FROM_DATABASE=Nano Receiver [Sandstrom Laser Mouse SMWLL11]
+
+usb:v062Ap6301*
+ ID_PRODUCT_FROM_DATABASE=Trust Wireless Optical Mouse MI-4150K
+
+usb:v062Ap9003*
+ ID_PRODUCT_FROM_DATABASE=VoIP Conference Hub (A16GH)
+
+usb:v062Ap9004*
+ ID_PRODUCT_FROM_DATABASE=USR9602 USB Internet Mini Phone
+
+usb:v062B*
+ ID_VENDOR_FROM_DATABASE=Greatlink Electronics Taiwan, Ltd
+
+usb:v062C*
+ ID_VENDOR_FROM_DATABASE=Institute for Information Industry
+
+usb:v062D*
+ ID_VENDOR_FROM_DATABASE=Taiwan Tai-Hao Enterprises Co., Ltd
+
+usb:v062E*
+ ID_VENDOR_FROM_DATABASE=Mainsuper Enterprises Co., Ltd
+
+usb:v062F*
+ ID_VENDOR_FROM_DATABASE=Sin Sheng Terminal & Machine, Inc.
+
+usb:v0631*
+ ID_VENDOR_FROM_DATABASE=JUJO Electronics Corp.
+
+usb:v0633*
+ ID_VENDOR_FROM_DATABASE=Cyrix Corp.
+
+usb:v0634*
+ ID_VENDOR_FROM_DATABASE=Micron Technology, Inc.
+
+usb:v0634p0655*
+ ID_PRODUCT_FROM_DATABASE=Embedded Mass Storage Drive [RealSSD]
+
+usb:v0635*
+ ID_VENDOR_FROM_DATABASE=Methode Electronics, Inc.
+
+usb:v0636*
+ ID_VENDOR_FROM_DATABASE=Sierra Imaging, Inc.
+
+usb:v0636p0003*
+ ID_PRODUCT_FROM_DATABASE=Vivicam 35Xx
+
+usb:v0638*
+ ID_VENDOR_FROM_DATABASE=Avision, Inc.
+
+usb:v0638p0268*
+ ID_PRODUCT_FROM_DATABASE=iVina 1200U Scanner
+
+usb:v0638p026A*
+ ID_PRODUCT_FROM_DATABASE=Minolta Dimage Scan Dual II AF-2820U (2886)
+
+usb:v0638p0A10*
+ ID_PRODUCT_FROM_DATABASE=iVina FB1600/UMAX Astra 4500
+
+usb:v0638p0A13*
+ ID_PRODUCT_FROM_DATABASE=AV600U
+
+usb:v0638p0A15*
+ ID_PRODUCT_FROM_DATABASE=Konica Minolta SC-110
+
+usb:v0638p0A16*
+ ID_PRODUCT_FROM_DATABASE=Konica Minolta SC-215
+
+usb:v0638p0A30*
+ ID_PRODUCT_FROM_DATABASE=UMAX Astra 6700 Scanner
+
+usb:v0638p0A41*
+ ID_PRODUCT_FROM_DATABASE=Avision AM3000/MF3000 Series
+
+usb:v0638p0F01*
+ ID_PRODUCT_FROM_DATABASE=fi-4010CU
+
+usb:v0638p4004*
+ ID_PRODUCT_FROM_DATABASE=Minolta Dimage Scan Elite II AF-2920 (2888)
+
+usb:v0639*
+ ID_VENDOR_FROM_DATABASE=Chrontel, Inc.
+
+usb:v063A*
+ ID_VENDOR_FROM_DATABASE=Techwin Corp.
+
+usb:v063B*
+ ID_VENDOR_FROM_DATABASE=Taugagreining HF
+
+usb:v063C*
+ ID_VENDOR_FROM_DATABASE=Yamaichi Electronics Co., Ltd (Sakura)
+
+usb:v063D*
+ ID_VENDOR_FROM_DATABASE=Fong Kai Industrial Co., Ltd
+
+usb:v063E*
+ ID_VENDOR_FROM_DATABASE=RealMedia Technology, Inc.
+
+usb:v063F*
+ ID_VENDOR_FROM_DATABASE=New Technology Cable, Ltd
+
+usb:v0640*
+ ID_VENDOR_FROM_DATABASE=Hitex Development Tools
+
+usb:v0640p0026*
+ ID_PRODUCT_FROM_DATABASE=LPC-Stick
+
+usb:v0641*
+ ID_VENDOR_FROM_DATABASE=Woods Industries, Inc.
+
+usb:v0642*
+ ID_VENDOR_FROM_DATABASE=VIA Medical Corp.
+
+usb:v0644*
+ ID_VENDOR_FROM_DATABASE=TEAC Corp.
+
+usb:v0644p0000*
+ ID_PRODUCT_FROM_DATABASE=Floppy
+
+usb:v0644p0200*
+ ID_PRODUCT_FROM_DATABASE=All-In-One Multi-Card Reader CA200/B/S
+
+usb:v0644p1000*
+ ID_PRODUCT_FROM_DATABASE=CD-ROM Drive
+
+usb:v0644p800D*
+ ID_PRODUCT_FROM_DATABASE=TASCAM Portastudio DP-01FX
+
+usb:v0644p800E*
+ ID_PRODUCT_FROM_DATABASE=TASCAM US-122L
+
+usb:v0644p8021*
+ ID_PRODUCT_FROM_DATABASE=TASCAM US-122mkII
+
+usb:v0644pD001*
+ ID_PRODUCT_FROM_DATABASE=CD-R/RW Unit
+
+usb:v0644pD002*
+ ID_PRODUCT_FROM_DATABASE=CD-R/RW Unit
+
+usb:v0644pD010*
+ ID_PRODUCT_FROM_DATABASE=CD-RW/DVD Unit
+
+usb:v0645*
+ ID_VENDOR_FROM_DATABASE=Who? Vision Systems, Inc.
+
+usb:v0646*
+ ID_VENDOR_FROM_DATABASE=UMAX
+
+usb:v0647*
+ ID_VENDOR_FROM_DATABASE=Acton Research Corp.
+
+usb:v0647p0100*
+ ID_PRODUCT_FROM_DATABASE=ARC SpectraPro UV/VIS/IR Monochromator/Spectrograph
+
+usb:v0647p0101*
+ ID_PRODUCT_FROM_DATABASE=ARC AM-VM Mono Airpath/Vacuum Monochromator/Spectrograph
+
+usb:v0647p0102*
+ ID_PRODUCT_FROM_DATABASE=ARC Inspectrum Mono
+
+usb:v0647p0103*
+ ID_PRODUCT_FROM_DATABASE=ARC Filterwheel
+
+usb:v0647p03E9*
+ ID_PRODUCT_FROM_DATABASE=Inspectrum 128x1024 F VIS Spectrograph
+
+usb:v0647p03EA*
+ ID_PRODUCT_FROM_DATABASE=Inspectrum 256x1024 F VIS Spectrograph
+
+usb:v0647p03EB*
+ ID_PRODUCT_FROM_DATABASE=Inspectrum 128x1024 B VIS Spectrograph
+
+usb:v0647p03EC*
+ ID_PRODUCT_FROM_DATABASE=Inspectrum 256x1024 B VIS Spectrograph
+
+usb:v0648*
+ ID_VENDOR_FROM_DATABASE=Inside Out Networks
+
+usb:v0649*
+ ID_VENDOR_FROM_DATABASE=Weli Science Co., Ltd
+
+usb:v064B*
+ ID_VENDOR_FROM_DATABASE=Analog Devices, Inc. (White Mountain DSP)
+
+usb:v064Bp0165*
+ ID_PRODUCT_FROM_DATABASE=Blackfin 535 [ADZS HPUSB ICE]
+
+usb:v064C*
+ ID_VENDOR_FROM_DATABASE=Ji-Haw Industrial Co., Ltd
+
+usb:v064D*
+ ID_VENDOR_FROM_DATABASE=TriTech Microelectronics, Ltd
+
+usb:v064E*
+ ID_VENDOR_FROM_DATABASE=Suyin Corp.
+
+usb:v064EpA100*
+ ID_PRODUCT_FROM_DATABASE=Acer OrbiCam
+
+usb:v064EpA101*
+ ID_PRODUCT_FROM_DATABASE=Acer CrystalEye Webcam
+
+usb:v064EpA102*
+ ID_PRODUCT_FROM_DATABASE=Acer/Lenovo Webcam [CN0316]
+
+usb:v064EpA103*
+ ID_PRODUCT_FROM_DATABASE=Acer/HP Integrated Webcam [CN0314]
+
+usb:v064EpA110*
+ ID_PRODUCT_FROM_DATABASE=HP Webcam
+
+usb:v064EpA114*
+ ID_PRODUCT_FROM_DATABASE=Lemote Webcam
+
+usb:v064EpA136*
+ ID_PRODUCT_FROM_DATABASE=Asus Integrated Webcam [CN031B]
+
+usb:v064EpA219*
+ ID_PRODUCT_FROM_DATABASE=1.3M WebCam (notebook emachines E730, Acer sub-brand)
+
+usb:v064EpC107*
+ ID_PRODUCT_FROM_DATABASE=HP webcam [dv6-1190en]
+
+usb:v064EpD101*
+ ID_PRODUCT_FROM_DATABASE=Acer CrystalEye Webcam
+
+usb:v064EpE201*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam
+
+usb:v064EpE203*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam
+
+usb:v064EpF102*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam [R5U877]
+
+usb:v064EpF103*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam [R5U877]
+
+usb:v064F*
+ ID_VENDOR_FROM_DATABASE=WIBU-Systems AG
+
+usb:v064Fp03E9*
+ ID_PRODUCT_FROM_DATABASE=CmStick (article no. 1001)
+
+usb:v064Fp03F2*
+ ID_PRODUCT_FROM_DATABASE=CmStick/M (article no. 1010)
+
+usb:v064Fp03F3*
+ ID_PRODUCT_FROM_DATABASE=CmStick/M (article no. 1011)
+
+usb:v064Fp0BD7*
+ ID_PRODUCT_FROM_DATABASE=BOX/U
+
+usb:v064Fp0BD8*
+ ID_PRODUCT_FROM_DATABASE=BOX/RU
+
+usb:v0650*
+ ID_VENDOR_FROM_DATABASE=Dynapro Systems
+
+usb:v0651*
+ ID_VENDOR_FROM_DATABASE=Likom Technology Sdn. Bhd.
+
+usb:v0652*
+ ID_VENDOR_FROM_DATABASE=Stargate Solutions, Inc.
+
+usb:v0653*
+ ID_VENDOR_FROM_DATABASE=CNF, Inc.
+
+usb:v0654*
+ ID_VENDOR_FROM_DATABASE=Granite Microsystems, Inc.
+
+usb:v0654p0005*
+ ID_PRODUCT_FROM_DATABASE=Device Bay Controller
+
+usb:v0654p0006*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0654p0007*
+ ID_PRODUCT_FROM_DATABASE=Device Bay Controller
+
+usb:v0654p0016*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0655*
+ ID_VENDOR_FROM_DATABASE=Space Shuttle Hi-Tech Co., Ltd
+
+usb:v0656*
+ ID_VENDOR_FROM_DATABASE=Glory Mark Electronic, Ltd
+
+usb:v0657*
+ ID_VENDOR_FROM_DATABASE=Tekcon Electronics Corp.
+
+usb:v0658*
+ ID_VENDOR_FROM_DATABASE=Sigma Designs, Inc.
+
+usb:v0659*
+ ID_VENDOR_FROM_DATABASE=Aethra
+
+usb:v065A*
+ ID_VENDOR_FROM_DATABASE=Optoelectronics Co., Ltd
+
+usb:v065Ap0001*
+ ID_PRODUCT_FROM_DATABASE=Barcode scanner
+
+usb:v065B*
+ ID_VENDOR_FROM_DATABASE=Tracewell Systems
+
+usb:v065E*
+ ID_VENDOR_FROM_DATABASE=Silicon Graphics
+
+usb:v065F*
+ ID_VENDOR_FROM_DATABASE=Good Way Technology Co., Ltd & GWC technology Inc.
+
+usb:v0660*
+ ID_VENDOR_FROM_DATABASE=TSAY-E (BVI) International, Inc.
+
+usb:v0661*
+ ID_VENDOR_FROM_DATABASE=Hamamatsu Photonics K.K.
+
+usb:v0662*
+ ID_VENDOR_FROM_DATABASE=Kansai Electric Co., Ltd
+
+usb:v0663*
+ ID_VENDOR_FROM_DATABASE=Topmax Electronic Co., Ltd
+
+usb:v0663p0103*
+ ID_PRODUCT_FROM_DATABASE=CobraPad
+
+usb:v0664*
+ ID_VENDOR_FROM_DATABASE=ET&T Technology Co., Ltd.
+
+usb:v0664p0301*
+ ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen
+
+usb:v0664p0302*
+ ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen
+
+usb:v0664p0303*
+ ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen
+
+usb:v0664p0304*
+ ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen
+
+usb:v0664p0305*
+ ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen
+
+usb:v0664p0306*
+ ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen
+
+usb:v0664p0307*
+ ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen
+
+usb:v0664p0309*
+ ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen
+
+usb:v0665*
+ ID_VENDOR_FROM_DATABASE=Cypress Semiconductor
+
+usb:v0665p5161*
+ ID_PRODUCT_FROM_DATABASE=USB to Serial
+
+usb:v0667*
+ ID_VENDOR_FROM_DATABASE=Aiwa Co., Ltd
+
+usb:v0667p0FA1*
+ ID_PRODUCT_FROM_DATABASE=TD-U8000 Tape Drive
+
+usb:v0668*
+ ID_VENDOR_FROM_DATABASE=WordWand
+
+usb:v0669*
+ ID_VENDOR_FROM_DATABASE=Oce' Printing Systems GmbH
+
+usb:v066A*
+ ID_VENDOR_FROM_DATABASE=Total Technologies, Ltd
+
+usb:v066B*
+ ID_VENDOR_FROM_DATABASE=Linksys, Inc.
+
+usb:v066Bp0105*
+ ID_PRODUCT_FROM_DATABASE=SCM eUSB SmartMedia Card Reader
+
+usb:v066Bp010A*
+ ID_PRODUCT_FROM_DATABASE=Melco MCR-U2 SmartMedia / CompactFlash Reader
+
+usb:v066Bp200C*
+ ID_PRODUCT_FROM_DATABASE=USB10TX
+
+usb:v066Bp2202*
+ ID_PRODUCT_FROM_DATABASE=USB10TX Ethernet [pegasus]
+
+usb:v066Bp2203*
+ ID_PRODUCT_FROM_DATABASE=USB100TX Ethernet [pegasus]
+
+usb:v066Bp2204*
+ ID_PRODUCT_FROM_DATABASE=USB100TX HomePNA Ethernet [pegasus]
+
+usb:v066Bp2206*
+ ID_PRODUCT_FROM_DATABASE=USB Ethernet [pegasus]
+
+usb:v066Bp2207*
+ ID_PRODUCT_FROM_DATABASE=HomeLink Phoneline 10M Network Adapter
+
+usb:v066Bp2211*
+ ID_PRODUCT_FROM_DATABASE=WUSB11 802.11b Adapter
+
+usb:v066Bp2212*
+ ID_PRODUCT_FROM_DATABASE=WUSB11v2.5 802.11b Adapter
+
+usb:v066Bp2213*
+ ID_PRODUCT_FROM_DATABASE=WUSB12v1.1 802.11b Adapter
+
+usb:v066Bp2219*
+ ID_PRODUCT_FROM_DATABASE=Instant Wireless Network Adapter
+
+usb:v066Bp400B*
+ ID_PRODUCT_FROM_DATABASE=USB10TX
+
+usb:v066D*
+ ID_VENDOR_FROM_DATABASE=Entrega, Inc.
+
+usb:v066E*
+ ID_VENDOR_FROM_DATABASE=Acer Semiconductor America, Inc.
+
+usb:v066F*
+ ID_VENDOR_FROM_DATABASE=SigmaTel, Inc.
+
+usb:v066Fp003B*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp003E*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp003F*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp0040*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp0041*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp0042*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp0043*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp004B*
+ ID_PRODUCT_FROM_DATABASE=A-Max PA11 MP3 Player
+
+usb:v066Fp3400*
+ ID_PRODUCT_FROM_DATABASE=STMP3400 D-Major MP3 Player
+
+usb:v066Fp3410*
+ ID_PRODUCT_FROM_DATABASE=STMP3410 D-Major MP3 Player
+
+usb:v066Fp3500*
+ ID_PRODUCT_FROM_DATABASE=Player Recovery Device
+
+usb:v066Fp3780*
+ ID_PRODUCT_FROM_DATABASE=STMP3780/i.MX23 SystemOnChip in RecoveryMode
+
+usb:v066Fp4200*
+ ID_PRODUCT_FROM_DATABASE=STIr4200 IrDA Bridge
+
+usb:v066Fp4210*
+ ID_PRODUCT_FROM_DATABASE=STIr4210 IrDA Bridge
+
+usb:v066Fp8000*
+ ID_PRODUCT_FROM_DATABASE=MSCN MP3 Player
+
+usb:v066Fp8001*
+ ID_PRODUCT_FROM_DATABASE=SigmaTel MSCN Audio Player
+
+usb:v066Fp8004*
+ ID_PRODUCT_FROM_DATABASE=MSCNMMC MP3 Player
+
+usb:v066Fp8008*
+ ID_PRODUCT_FROM_DATABASE=i-Bead 100 MP3 Player
+
+usb:v066Fp8020*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8034*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8036*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8038*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8056*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8060*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8066*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp807E*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8092*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8096*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp809A*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80AA*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80AC*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80B8*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80BA*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80BC*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80BF*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80C5*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80C8*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80CA*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp80CC*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8104*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8106*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8108*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp810A*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp810C*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8122*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8124*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8126*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8128*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8134*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8136*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8138*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp813A*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp813E*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8140*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8142*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8144*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8146*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8148*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp814C*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8201*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8202*
+ ID_PRODUCT_FROM_DATABASE=Jens of Sweden / I-BEAD 150M/150H MP3 player
+
+usb:v066Fp8203*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8204*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8205*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8206*
+ ID_PRODUCT_FROM_DATABASE=Digital MP3 Music Player
+
+usb:v066Fp8207*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8208*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8209*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp820A*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp820B*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp820C*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp820D*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp820E*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp820F*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8210*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8211*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8212*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8213*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8214*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8215*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8216*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8217*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8218*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8219*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp821A*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp821B*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp821C*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp821D*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp821E*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp821F*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8220*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8221*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8222*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8223*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8224*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8225*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8226*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8227*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8228*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8229*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8230*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp829C*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp82E0*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp8320*
+ ID_PRODUCT_FROM_DATABASE=TrekStor i.Beat fun
+
+usb:v066Fp835D*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp9000*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp9001*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v066Fp9002*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0670*
+ ID_VENDOR_FROM_DATABASE=Sequel Imaging
+
+usb:v0670p0001*
+ ID_PRODUCT_FROM_DATABASE=Calibrator
+
+usb:v0670p0005*
+ ID_PRODUCT_FROM_DATABASE=Enable Cable
+
+usb:v0672*
+ ID_VENDOR_FROM_DATABASE=Labtec, Inc.
+
+usb:v0672p1041*
+ ID_PRODUCT_FROM_DATABASE=LCS1040 Speaker System
+
+usb:v0672p5000*
+ ID_PRODUCT_FROM_DATABASE=SpaceBall 4000 FLX
+
+usb:v0673*
+ ID_VENDOR_FROM_DATABASE=HCL
+
+usb:v0673p5000*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0674*
+ ID_VENDOR_FROM_DATABASE=Key Mouse Electronic Enterprise Co., Ltd
+
+usb:v0675*
+ ID_VENDOR_FROM_DATABASE=DrayTek Corp.
+
+usb:v0675p0110*
+ ID_PRODUCT_FROM_DATABASE=Vigor 128 ISDN TA
+
+usb:v0675p0530*
+ ID_PRODUCT_FROM_DATABASE=Vigor530 IEEE 802.11G Adapter (ISL3880+NET2280)
+
+usb:v0675p0550*
+ ID_PRODUCT_FROM_DATABASE=Vigor550
+
+usb:v0675p1688*
+ ID_PRODUCT_FROM_DATABASE=miniVigor 128 ISDN TA
+
+usb:v0675p6694*
+ ID_PRODUCT_FROM_DATABASE=USB ISDN TA
+
+usb:v0676*
+ ID_VENDOR_FROM_DATABASE=Teles AG
+
+usb:v0677*
+ ID_VENDOR_FROM_DATABASE=Aiwa Co., Ltd
+
+usb:v0677p07D5*
+ ID_PRODUCT_FROM_DATABASE=TM-ED1285(USB)
+
+usb:v0677p0FA1*
+ ID_PRODUCT_FROM_DATABASE=TD-U8000 Tape Drive
+
+usb:v0678*
+ ID_VENDOR_FROM_DATABASE=ACard Technology Corp.
+
+usb:v067B*
+ ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc.
+
+usb:v067Bp0000*
+ ID_PRODUCT_FROM_DATABASE=PL2301 USB-USB Bridge
+
+usb:v067Bp0001*
+ ID_PRODUCT_FROM_DATABASE=PL2302 USB-USB Bridge
+
+usb:v067Bp0307*
+ ID_PRODUCT_FROM_DATABASE=Motorola Serial Adapter
+
+usb:v067Bp04BB*
+ ID_PRODUCT_FROM_DATABASE=PL2303 Serial (IODATA USB-RSAQ2)
+
+usb:v067Bp0610*
+ ID_PRODUCT_FROM_DATABASE=Onext EG210U MODEM
+
+usb:v067Bp0611*
+ ID_PRODUCT_FROM_DATABASE=AlDiga AL-11U Quad-band GSM/GPRS/EDGE modem
+
+usb:v067Bp2303*
+ ID_PRODUCT_FROM_DATABASE=PL2303 Serial Port
+
+usb:v067Bp2305*
+ ID_PRODUCT_FROM_DATABASE=PL2305 Parallel Port
+
+usb:v067Bp2306*
+ ID_PRODUCT_FROM_DATABASE=Raylink Bridge Controller
+
+usb:v067Bp2307*
+ ID_PRODUCT_FROM_DATABASE=PL2307 USB-ATAPI4 Bridge
+
+usb:v067Bp2313*
+ ID_PRODUCT_FROM_DATABASE=FITEL PHS U Cable Adaptor
+
+usb:v067Bp2315*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk Embedded Hub
+
+usb:v067Bp2316*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk Security Device
+
+usb:v067Bp2317*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v067Bp2501*
+ ID_PRODUCT_FROM_DATABASE=PL2501 USB-USB Bridge (USB 2.0)
+
+usb:v067Bp2506*
+ ID_PRODUCT_FROM_DATABASE=Kaser 8gB micro hard drive
+
+usb:v067Bp2507*
+ ID_PRODUCT_FROM_DATABASE=PL2507 Hi-speed USB to IDE bridge controller
+
+usb:v067Bp2515*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk Embedded Hub
+
+usb:v067Bp2517*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk Mass Storage Device
+
+usb:v067Bp2528*
+ ID_PRODUCT_FROM_DATABASE=Storage device (8gB thumb drive)
+
+usb:v067Bp25A1*
+ ID_PRODUCT_FROM_DATABASE=PL25A1 Host-Host Bridge
+
+usb:v067Bp3400*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed Flash Disk with TruePrint AES3400
+
+usb:v067Bp3500*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed Flash Disk with TruePrint AES3500
+
+usb:v067Bp3507*
+ ID_PRODUCT_FROM_DATABASE=PL3507 ATAPI6 Bridge
+
+usb:v067BpAAA0*
+ ID_PRODUCT_FROM_DATABASE=Prolific Pharos
+
+usb:v067BpAAA2*
+ ID_PRODUCT_FROM_DATABASE=PL2303 Serial Adapter (IODATA USB-RSAQ3)
+
+usb:v067C*
+ ID_VENDOR_FROM_DATABASE=Efficient Networks, Inc.
+
+usb:v067Cp1001*
+ ID_PRODUCT_FROM_DATABASE=Siemens SpeedStream 100MBps Ethernet
+
+usb:v067Cp1022*
+ ID_PRODUCT_FROM_DATABASE=Siemens SpeedStream 1022 802.11b Adapter
+
+usb:v067Cp1023*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream Wireless
+
+usb:v067Cp4020*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 4020 ATM/ADSL Installer
+
+usb:v067Cp4031*
+ ID_PRODUCT_FROM_DATABASE=Efficient ADSL Modem
+
+usb:v067Cp4032*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer
+
+usb:v067Cp4033*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer
+
+usb:v067Cp4060*
+ ID_PRODUCT_FROM_DATABASE=Alcatel Speedstream 4060 ADSL Modem
+
+usb:v067Cp4062*
+ ID_PRODUCT_FROM_DATABASE=Efficient Networks 4060 Loader
+
+usb:v067Cp5667*
+ ID_PRODUCT_FROM_DATABASE=Efficient Networks Virtual Bus for ADSL Modem
+
+usb:v067CpC031*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer
+
+usb:v067CpC032*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer
+
+usb:v067CpC033*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer
+
+usb:v067CpC060*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 4060 Miniport ATM/ADSL Adapter
+
+usb:v067CpD667*
+ ID_PRODUCT_FROM_DATABASE=Efficient Networks Virtual Bus for ADSL Modem
+
+usb:v067CpE240*
+ ID_PRODUCT_FROM_DATABASE=Speedstream Ethernet Adapter E240
+
+usb:v067CpE540*
+ ID_PRODUCT_FROM_DATABASE=Speedstream Ethernet Adapter E240
+
+usb:v067D*
+ ID_VENDOR_FROM_DATABASE=Hohner Corp.
+
+usb:v067E*
+ ID_VENDOR_FROM_DATABASE=Intermec Technologies Corp.
+
+usb:v067Ep0801*
+ ID_PRODUCT_FROM_DATABASE=HID Keyboard, Barcode scanner
+
+usb:v067Ep0803*
+ ID_PRODUCT_FROM_DATABASE=VCP, Barcode scanner
+
+usb:v067Ep0805*
+ ID_PRODUCT_FROM_DATABASE=VCP + UVC, Barcode scanner
+
+usb:v067Ep1001*
+ ID_PRODUCT_FROM_DATABASE=Mobile Computer
+
+usb:v067F*
+ ID_VENDOR_FROM_DATABASE=Virata, Ltd
+
+usb:v067Fp4552*
+ ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL Modem
+
+usb:v067Fp6542*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v067Fp6549*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v067Fp7541*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0680*
+ ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp., CPP Div. (Avance Logic)
+
+usb:v0680p0002*
+ ID_PRODUCT_FROM_DATABASE=Arowana Optical Wheel Mouse MSOP-01
+
+usb:v0681*
+ ID_VENDOR_FROM_DATABASE=Siemens Information and Communication Products
+
+usb:v0681p0001*
+ ID_PRODUCT_FROM_DATABASE=Dect Base
+
+usb:v0681p0002*
+ ID_PRODUCT_FROM_DATABASE=Gigaset 3075 Passive ISDN
+
+usb:v0681p0005*
+ ID_PRODUCT_FROM_DATABASE=ID-Mouse with Fingerprint Reader
+
+usb:v0681p0012*
+ ID_PRODUCT_FROM_DATABASE=I-Gate 802.11b Adapter
+
+usb:v0681p001B*
+ ID_PRODUCT_FROM_DATABASE=WLL013
+
+usb:v0681p001D*
+ ID_PRODUCT_FROM_DATABASE=Hipath 1000
+
+usb:v0681p0022*
+ ID_PRODUCT_FROM_DATABASE=Gigaset SX353 ISDN
+
+usb:v0681p0026*
+ ID_PRODUCT_FROM_DATABASE=DECT Data - Gigaset M34
+
+usb:v0681p002B*
+ ID_PRODUCT_FROM_DATABASE=A-100-I ADSL Modem
+
+usb:v0681p002E*
+ ID_PRODUCT_FROM_DATABASE=ADSL Router_S-141
+
+usb:v0681p0034*
+ ID_PRODUCT_FROM_DATABASE=GSM module MC35/ES75 USB Modem
+
+usb:v0681p3C06*
+ ID_PRODUCT_FROM_DATABASE=54g USB Network Adapter
+
+usb:v0682*
+ ID_VENDOR_FROM_DATABASE=Victor Company of Japan, Ltd
+
+usb:v0684*
+ ID_VENDOR_FROM_DATABASE=Actiontec Electronics, Inc.
+
+usb:v0685*
+ ID_VENDOR_FROM_DATABASE=ZD Incorporated
+
+usb:v0685p7000*
+ ID_PRODUCT_FROM_DATABASE=HSDPA Modem
+
+usb:v0686*
+ ID_VENDOR_FROM_DATABASE=Minolta Co., Ltd
+
+usb:v0686p2001*
+ ID_PRODUCT_FROM_DATABASE=PagePro 4110W
+
+usb:v0686p2004*
+ ID_PRODUCT_FROM_DATABASE=PagePro 1200W
+
+usb:v0686p2005*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2300 DL
+
+usb:v0686p3001*
+ ID_PRODUCT_FROM_DATABASE=PagePro 4100
+
+usb:v0686p3005*
+ ID_PRODUCT_FROM_DATABASE=PagePro 1250E
+
+usb:v0686p3006*
+ ID_PRODUCT_FROM_DATABASE=PagePro 1250W
+
+usb:v0686p3009*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2300W
+
+usb:v0686p300B*
+ ID_PRODUCT_FROM_DATABASE=PagePro 1350W
+
+usb:v0686p300C*
+ ID_PRODUCT_FROM_DATABASE=PagePro 1300W
+
+usb:v0686p302E*
+ ID_PRODUCT_FROM_DATABASE=Develop D 1650iD PCL
+
+usb:v0686p3034*
+ ID_PRODUCT_FROM_DATABASE=Develop D 2050iD PCL
+
+usb:v0686p4001*
+ ID_PRODUCT_FROM_DATABASE=Dimage 2300
+
+usb:v0686p4003*
+ ID_PRODUCT_FROM_DATABASE=Dimage 2330 Zoom Camera
+
+usb:v0686p4004*
+ ID_PRODUCT_FROM_DATABASE=Dimage Scan Elite II AF-2920 (2888)
+
+usb:v0686p4005*
+ ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE E201 Mass Storage Device
+
+usb:v0686p4006*
+ ID_PRODUCT_FROM_DATABASE=Dimage 7 Camera
+
+usb:v0686p4007*
+ ID_PRODUCT_FROM_DATABASE=Dimage S304 Camera
+
+usb:v0686p4008*
+ ID_PRODUCT_FROM_DATABASE=Dimage 5 Camera
+
+usb:v0686p4009*
+ ID_PRODUCT_FROM_DATABASE=Dimage X Camera
+
+usb:v0686p400A*
+ ID_PRODUCT_FROM_DATABASE=Dimage S404 Camera
+
+usb:v0686p400B*
+ ID_PRODUCT_FROM_DATABASE=Dimage 7i Camera
+
+usb:v0686p400C*
+ ID_PRODUCT_FROM_DATABASE=Dimage F100 Camera
+
+usb:v0686p400D*
+ ID_PRODUCT_FROM_DATABASE=Dimage Scan Dual III AF-2840 (2889)
+
+usb:v0686p400E*
+ ID_PRODUCT_FROM_DATABASE=Dimage Scan Elite 5400 (2890)
+
+usb:v0686p400F*
+ ID_PRODUCT_FROM_DATABASE=Dimage 7Hi Camera
+
+usb:v0686p4010*
+ ID_PRODUCT_FROM_DATABASE=Dimage Xi Camera
+
+usb:v0686p4011*
+ ID_PRODUCT_FROM_DATABASE=Dimage F300 Camera
+
+usb:v0686p4012*
+ ID_PRODUCT_FROM_DATABASE=Dimage F200 Camera
+
+usb:v0686p4014*
+ ID_PRODUCT_FROM_DATABASE=Dimage S414 Camera
+
+usb:v0686p4015*
+ ID_PRODUCT_FROM_DATABASE=Dimage XT Camera [storage]
+
+usb:v0686p4016*
+ ID_PRODUCT_FROM_DATABASE=Dimage XT Camera [remote mode]
+
+usb:v0686p4017*
+ ID_PRODUCT_FROM_DATABASE=Dimage E223
+
+usb:v0686p4018*
+ ID_PRODUCT_FROM_DATABASE=Dimage Z1  Camera
+
+usb:v0686p4019*
+ ID_PRODUCT_FROM_DATABASE=Dimage A1 Camera [remote mode]
+
+usb:v0686p401A*
+ ID_PRODUCT_FROM_DATABASE=Dimage A1 Camera [storage]
+
+usb:v0686p401C*
+ ID_PRODUCT_FROM_DATABASE=Dimage X20 Camera
+
+usb:v0686p401E*
+ ID_PRODUCT_FROM_DATABASE=Dimage E323 Camera
+
+usb:v068A*
+ ID_VENDOR_FROM_DATABASE=Pertech, Inc.
+
+usb:v068B*
+ ID_VENDOR_FROM_DATABASE=Potrans International, Inc.
+
+usb:v068E*
+ ID_VENDOR_FROM_DATABASE=CH Products, Inc.
+
+usb:v068Ep00D3*
+ ID_PRODUCT_FROM_DATABASE=OEM 3 axis 5 button joystick
+
+usb:v068Ep00E2*
+ ID_PRODUCT_FROM_DATABASE=HFX OEM Joystick
+
+usb:v068Ep00F1*
+ ID_PRODUCT_FROM_DATABASE=Pro Throttle
+
+usb:v068Ep00F2*
+ ID_PRODUCT_FROM_DATABASE=Flight Sim Pedals
+
+usb:v068Ep00F3*
+ ID_PRODUCT_FROM_DATABASE=Fighterstick
+
+usb:v068Ep00F4*
+ ID_PRODUCT_FROM_DATABASE=Combatstick
+
+usb:v068Ep00FA*
+ ID_PRODUCT_FROM_DATABASE=Flight Sim Pedals
+
+usb:v068Ep00FF*
+ ID_PRODUCT_FROM_DATABASE=Flight Sim Yoke
+
+usb:v068Ep0500*
+ ID_PRODUCT_FROM_DATABASE=GameStick 3D
+
+usb:v068Ep0501*
+ ID_PRODUCT_FROM_DATABASE=CH Pro Pedals
+
+usb:v068Ep0504*
+ ID_PRODUCT_FROM_DATABASE=F-16 Combat Stick
+
+usb:v0690*
+ ID_VENDOR_FROM_DATABASE=Golden Bridge Electech, Inc.
+
+usb:v0693*
+ ID_VENDOR_FROM_DATABASE=Hagiwara Sys-Com Co., Ltd
+
+usb:v0693p0002*
+ ID_PRODUCT_FROM_DATABASE=FlashGate SmartMedia Card Reader
+
+usb:v0693p0003*
+ ID_PRODUCT_FROM_DATABASE=FlashGate CompactFlash Card Reader
+
+usb:v0693p0005*
+ ID_PRODUCT_FROM_DATABASE=FlashGate
+
+usb:v0693p0006*
+ ID_PRODUCT_FROM_DATABASE=SM PCCard R/W and SPD
+
+usb:v0693p0007*
+ ID_PRODUCT_FROM_DATABASE=FlashGate ME (Authenticated)
+
+usb:v0693p000A*
+ ID_PRODUCT_FROM_DATABASE=SDCard/MMC Reader/Writer
+
+usb:v0694*
+ ID_VENDOR_FROM_DATABASE=Lego Group
+
+usb:v0694p0001*
+ ID_PRODUCT_FROM_DATABASE=Mindstorms Tower
+
+usb:v0694p0002*
+ ID_PRODUCT_FROM_DATABASE=Mindstorms NXT
+
+usb:v0698*
+ ID_VENDOR_FROM_DATABASE=Chuntex (CTX)
+
+usb:v0698p1786*
+ ID_PRODUCT_FROM_DATABASE=1300ex Monitor
+
+usb:v0698p2003*
+ ID_PRODUCT_FROM_DATABASE=CTX M730V built in Camera
+
+usb:v0698p9999*
+ ID_PRODUCT_FROM_DATABASE=VLxxxx Monitor+Hub
+
+usb:v0699*
+ ID_VENDOR_FROM_DATABASE=Tektronix, Inc.
+
+usb:v069A*
+ ID_VENDOR_FROM_DATABASE=Askey Computer Corp.
+
+usb:v069Ap0001*
+ ID_PRODUCT_FROM_DATABASE=VC010 Webcam [pwc]
+
+usb:v069Ap0303*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v069Ap0311*
+ ID_PRODUCT_FROM_DATABASE=ADSL Router Remote NDIS Device
+
+usb:v069Ap0318*
+ ID_PRODUCT_FROM_DATABASE=Remote NDIS Device
+
+usb:v069Ap0319*
+ ID_PRODUCT_FROM_DATABASE=220V Remote NDIS Device
+
+usb:v069Ap0320*
+ ID_PRODUCT_FROM_DATABASE=IEEE 802.11b Wireless LAN Card
+
+usb:v069Ap0321*
+ ID_PRODUCT_FROM_DATABASE=Dynalink WLL013 / Compex WLU11A 802.11b Adapter
+
+usb:v069Ap0402*
+ ID_PRODUCT_FROM_DATABASE=Scientific Atlanta WebSTAR 100 & 200 series Cable Modem
+
+usb:v069Ap0811*
+ ID_PRODUCT_FROM_DATABASE=BT Virtual Bus for Helium
+
+usb:v069Ap0821*
+ ID_PRODUCT_FROM_DATABASE=BT Voyager 1010 802.11b Adapter
+
+usb:v069Ap4402*
+ ID_PRODUCT_FROM_DATABASE=Scientific Atlanta WebSTAR 2000 series Cable Modem
+
+usb:v069Ap4403*
+ ID_PRODUCT_FROM_DATABASE=Scientific Atlanta WebSTAR 300 series Cable Modem
+
+usb:v069Ap4501*
+ ID_PRODUCT_FROM_DATABASE=Scientific-Atlanta WebSTAR 2000 series Cable Modem
+
+usb:v069B*
+ ID_VENDOR_FROM_DATABASE=Thomson, Inc.
+
+usb:v069Bp0704*
+ ID_PRODUCT_FROM_DATABASE=DCM245 Cable Modem
+
+usb:v069Bp0705*
+ ID_PRODUCT_FROM_DATABASE=THG540K Cable Modem
+
+usb:v069Bp0709*
+ ID_PRODUCT_FROM_DATABASE=Lyra PDP2424
+
+usb:v069Bp070C*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v069Bp070D*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v069Bp070E*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v069Bp070F*
+ ID_PRODUCT_FROM_DATABASE=RCA Lyra RD1071 MP3 Player
+
+usb:v069Bp0731*
+ ID_PRODUCT_FROM_DATABASE=Lyra M200E256
+
+usb:v069Bp0761*
+ ID_PRODUCT_FROM_DATABASE=RCA H100A
+
+usb:v069Bp0778*
+ ID_PRODUCT_FROM_DATABASE=PEARL USB Device
+
+usb:v069Bp2220*
+ ID_PRODUCT_FROM_DATABASE=RCA Kazoo RD1000 MP3 Player
+
+usb:v069Bp300A*
+ ID_PRODUCT_FROM_DATABASE=RCA Lyra MP3 Player
+
+usb:v069Bp3012*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v069Bp3013*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v069Bp5557*
+ ID_PRODUCT_FROM_DATABASE=RCA CDS6300
+
+usb:v069D*
+ ID_VENDOR_FROM_DATABASE=Hughes Network Systems (HNS)
+
+usb:v069Dp0001*
+ ID_PRODUCT_FROM_DATABASE=Satellite Receiver Device
+
+usb:v069Dp0002*
+ ID_PRODUCT_FROM_DATABASE=Satellite Device
+
+usb:v069E*
+ ID_VENDOR_FROM_DATABASE=Welcat Inc.
+
+usb:v069Ep0005*
+ ID_PRODUCT_FROM_DATABASE=Marx CryptoBox v1.2
+
+usb:v069F*
+ ID_VENDOR_FROM_DATABASE=Allied Data Technologies BV
+
+usb:v069Fp0010*
+ ID_PRODUCT_FROM_DATABASE=Tornado Speakerphone FaxModem 56.0
+
+usb:v069Fp0011*
+ ID_PRODUCT_FROM_DATABASE=Tornado Speakerphone FaxModem 56.0
+
+usb:v069Fp1000*
+ ID_PRODUCT_FROM_DATABASE=ADT VvBus for CopperJet
+
+usb:v069Fp1004*
+ ID_PRODUCT_FROM_DATABASE=CopperJet 821 RouterPlus
+
+usb:v06A2*
+ ID_VENDOR_FROM_DATABASE=Topro Technology, Inc.
+
+usb:v06A2p0033*
+ ID_PRODUCT_FROM_DATABASE=USB Mouse
+
+usb:v06A3*
+ ID_VENDOR_FROM_DATABASE=Saitek PLC
+
+usb:v06A3p0006*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Gold Joystick
+
+usb:v06A3p0109*
+ ID_PRODUCT_FROM_DATABASE=P880 Pad
+
+usb:v06A3p0160*
+ ID_PRODUCT_FROM_DATABASE=ST290 Pro
+
+usb:v06A3p0200*
+ ID_PRODUCT_FROM_DATABASE=Xbox Adrenalin Hub
+
+usb:v06A3p0241*
+ ID_PRODUCT_FROM_DATABASE=Xbox Adrenalin Gamepad
+
+usb:v06A3p0255*
+ ID_PRODUCT_FROM_DATABASE=X52 Flight Controller
+
+usb:v06A3p040B*
+ ID_PRODUCT_FROM_DATABASE=P990 Dual Analog Pad
+
+usb:v06A3p040C*
+ ID_PRODUCT_FROM_DATABASE=P2900 Wireless Pad
+
+usb:v06A3p0422*
+ ID_PRODUCT_FROM_DATABASE=ST90 Joystick
+
+usb:v06A3p0460*
+ ID_PRODUCT_FROM_DATABASE=ST290 Pro Flight Stick
+
+usb:v06A3p0463*
+ ID_PRODUCT_FROM_DATABASE=ST290
+
+usb:v06A3p0464*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Evo
+
+usb:v06A3p0471*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Graphite Stick
+
+usb:v06A3p0501*
+ ID_PRODUCT_FROM_DATABASE=R100 Sports Wheel
+
+usb:v06A3p0502*
+ ID_PRODUCT_FROM_DATABASE=ST200 Stick
+
+usb:v06A3p0506*
+ ID_PRODUCT_FROM_DATABASE=R220 Digital Wheel
+
+usb:v06A3p051E*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Digital II Stick
+
+usb:v06A3p052D*
+ ID_PRODUCT_FROM_DATABASE=P750 Gamepad
+
+usb:v06A3p053C*
+ ID_PRODUCT_FROM_DATABASE=X45 Flight Controller
+
+usb:v06A3p053F*
+ ID_PRODUCT_FROM_DATABASE=X36F Flightstick
+
+usb:v06A3p056C*
+ ID_PRODUCT_FROM_DATABASE=P2000 Tilt Pad
+
+usb:v06A3p056F*
+ ID_PRODUCT_FROM_DATABASE=P2000 Tilt Pad
+
+usb:v06A3p05D2*
+ ID_PRODUCT_FROM_DATABASE=PC Dash 2
+
+usb:v06A3p075C*
+ ID_PRODUCT_FROM_DATABASE=X52 Flight Controller
+
+usb:v06A3p0762*
+ ID_PRODUCT_FROM_DATABASE=Saitek X52 Pro Flight Control System
+
+usb:v06A3p0763*
+ ID_PRODUCT_FROM_DATABASE=Pro Flight Rudder Pedals
+
+usb:v06A3p0764*
+ ID_PRODUCT_FROM_DATABASE=Flight Pro Combat Rudder
+
+usb:v06A3p0805*
+ ID_PRODUCT_FROM_DATABASE=R440 Force Wheel
+
+usb:v06A3p0B4E*
+ ID_PRODUCT_FROM_DATABASE=Pro Flight Backlit Information Panel
+
+usb:v06A3p0BAC*
+ ID_PRODUCT_FROM_DATABASE=Pro Flight Yoke
+
+usb:v06A3p0C2D*
+ ID_PRODUCT_FROM_DATABASE=Pro Flight Quadrant
+
+usb:v06A3p0D05*
+ ID_PRODUCT_FROM_DATABASE=Pro Flight Radio Panel
+
+usb:v06A3p0D06*
+ ID_PRODUCT_FROM_DATABASE=Flight Pro Multi Panel
+
+usb:v06A3p0D67*
+ ID_PRODUCT_FROM_DATABASE=Pro Flight Switch Panel
+
+usb:v06A3p1003*
+ ID_PRODUCT_FROM_DATABASE=GM2 Action Pad
+
+usb:v06A3p1009*
+ ID_PRODUCT_FROM_DATABASE=Action Pad
+
+usb:v06A3p100A*
+ ID_PRODUCT_FROM_DATABASE=SP550 Pad and Joystick Combo
+
+usb:v06A3p100B*
+ ID_PRODUCT_FROM_DATABASE=SP550 Pad
+
+usb:v06A3p1509*
+ ID_PRODUCT_FROM_DATABASE=P3000 Wireless Pad
+
+usb:v06A3p1589*
+ ID_PRODUCT_FROM_DATABASE=P3000 Wireless Pad
+
+usb:v06A3p2541*
+ ID_PRODUCT_FROM_DATABASE=X45 Flight Controller
+
+usb:v06A3p3509*
+ ID_PRODUCT_FROM_DATABASE=P3000 RF GamePad
+
+usb:v06A3p353E*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Evo Wireless
+
+usb:v06A3p3589*
+ ID_PRODUCT_FROM_DATABASE=P3000 Wireless Pad
+
+usb:v06A3p35BE*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Evo
+
+usb:v06A3p5509*
+ ID_PRODUCT_FROM_DATABASE=P3000 Wireless Pad
+
+usb:v06A3p712C*
+ ID_PRODUCT_FROM_DATABASE=Pro Flight Yoke integrated hub
+
+usb:v06A3p8000*
+ ID_PRODUCT_FROM_DATABASE=Gamers' Keyboard
+
+usb:v06A3p801E*
+ ID_PRODUCT_FROM_DATABASE=Cyborg 3D Digital Stick II
+
+usb:v06A3p8020*
+ ID_PRODUCT_FROM_DATABASE=Eclipse Keyboard
+
+usb:v06A3p8021*
+ ID_PRODUCT_FROM_DATABASE=Eclipse II Keyboard
+
+usb:v06A3p802D*
+ ID_PRODUCT_FROM_DATABASE=P750 Pad
+
+usb:v06A3p803F*
+ ID_PRODUCT_FROM_DATABASE=X36 Flight Controller
+
+usb:v06A3p806F*
+ ID_PRODUCT_FROM_DATABASE=P2000 Tilt Pad
+
+usb:v06A3p80C0*
+ ID_PRODUCT_FROM_DATABASE=Pro Gamer Command Unit
+
+usb:v06A3p80C1*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Command Pad Unit
+
+usb:v06A3pA2AE*
+ ID_PRODUCT_FROM_DATABASE=Pro Flight Instrument Panel
+
+usb:v06A3pA502*
+ ID_PRODUCT_FROM_DATABASE=Gaming Mouse
+
+usb:v06A3pF518*
+ ID_PRODUCT_FROM_DATABASE=P3200 Rumble Force Game Pad
+
+usb:v06A3pFF04*
+ ID_PRODUCT_FROM_DATABASE=R440 Force Wheel
+
+usb:v06A3pFF0C*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Force Rumble Pad
+
+usb:v06A3pFF0D*
+ ID_PRODUCT_FROM_DATABASE=P2600 Rumble Force Pad
+
+usb:v06A3pFF12*
+ ID_PRODUCT_FROM_DATABASE=Cyborg 3D Force Stick
+
+usb:v06A3pFF17*
+ ID_PRODUCT_FROM_DATABASE=ST 330 Rumble Force Stick
+
+usb:v06A3pFF52*
+ ID_PRODUCT_FROM_DATABASE=Cyborg 3D Rumble Force Joystick
+
+usb:v06A3pFFB5*
+ ID_PRODUCT_FROM_DATABASE=Cyborg Evo Force Joystick
+
+usb:v06A4*
+ ID_VENDOR_FROM_DATABASE=Xiamen Doowell Electron Co., Ltd
+
+usb:v06A5*
+ ID_VENDOR_FROM_DATABASE=Divio
+
+usb:v06A5p0000*
+ ID_PRODUCT_FROM_DATABASE=Typhoon Webcam 100k [nw8000]
+
+usb:v06A5pD001*
+ ID_PRODUCT_FROM_DATABASE=ProLink DS3303u Webcam
+
+usb:v06A5pD800*
+ ID_PRODUCT_FROM_DATABASE=Chicony TwinkleCam
+
+usb:v06A5pD820*
+ ID_PRODUCT_FROM_DATABASE=Wize Media 1000
+
+usb:v06A7*
+ ID_VENDOR_FROM_DATABASE=MicroStore, Inc.
+
+usb:v06A8*
+ ID_VENDOR_FROM_DATABASE=Topaz Systems, Inc.
+
+usb:v06A8p0042*
+ ID_PRODUCT_FROM_DATABASE=SignatureGem 1X5 Pad
+
+usb:v06A8p0043*
+ ID_PRODUCT_FROM_DATABASE=SignatureGem 1X5-HID Pad
+
+usb:v06A9*
+ ID_VENDOR_FROM_DATABASE=Westell
+
+usb:v06A9p0005*
+ ID_PRODUCT_FROM_DATABASE=WireSpeed Dual Connect Modem
+
+usb:v06A9p0006*
+ ID_PRODUCT_FROM_DATABASE=WireSpeed Dual Connect Modem
+
+usb:v06A9p000A*
+ ID_PRODUCT_FROM_DATABASE=WireSpeed Dual Connect Modem
+
+usb:v06A9p000B*
+ ID_PRODUCT_FROM_DATABASE=WireSpeed Dual Connect Modem
+
+usb:v06A9p000E*
+ ID_PRODUCT_FROM_DATABASE=A90-211WG-01 802.11g Adapter [Intersil ISL3887]
+
+usb:v06AA*
+ ID_VENDOR_FROM_DATABASE=Sysgration, Ltd
+
+usb:v06AC*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Laboratories of America, Inc.
+
+usb:v06AD*
+ ID_VENDOR_FROM_DATABASE=Greatland Electronics Taiwan, Ltd
+
+usb:v06AE*
+ ID_VENDOR_FROM_DATABASE=Professional Multimedia Testing Centre
+
+usb:v06AF*
+ ID_VENDOR_FROM_DATABASE=Harting, Inc. of North America
+
+usb:v06B8*
+ ID_VENDOR_FROM_DATABASE=Pixela Corp.
+
+usb:v06B9*
+ ID_VENDOR_FROM_DATABASE=Alcatel Telecom
+
+usb:v06B9p0120*
+ ID_PRODUCT_FROM_DATABASE=SpeedTouch 120g 802.11g Wireless Adapter [Intersil ISL3886]
+
+usb:v06B9p0121*
+ ID_PRODUCT_FROM_DATABASE=SpeedTouch 121g Wireless Dongle
+
+usb:v06B9p2001*
+ ID_PRODUCT_FROM_DATABASE=SPEED TOUCH Card
+
+usb:v06B9p4061*
+ ID_PRODUCT_FROM_DATABASE=SpeedTouch ISDN or ADSL Modem
+
+usb:v06B9p4062*
+ ID_PRODUCT_FROM_DATABASE=SpeedTouch ISDN or ADSL router
+
+usb:v06B9pA5A5*
+ ID_PRODUCT_FROM_DATABASE=DynaMiTe Modem
+
+usb:v06BA*
+ ID_VENDOR_FROM_DATABASE=Smooth Cord & Connector Co., Ltd
+
+usb:v06BB*
+ ID_VENDOR_FROM_DATABASE=EDA, Inc.
+
+usb:v06BC*
+ ID_VENDOR_FROM_DATABASE=Oki Data Corp.
+
+usb:v06BCp000B*
+ ID_PRODUCT_FROM_DATABASE=Okipage 14ex Printer
+
+usb:v06BCp0027*
+ ID_PRODUCT_FROM_DATABASE=Okipage 14e
+
+usb:v06BCp0A91*
+ ID_PRODUCT_FROM_DATABASE=B2500MFP (printer+scanner)
+
+usb:v06BCp3801*
+ ID_PRODUCT_FROM_DATABASE=B6100 Laser Printer
+
+usb:v06BD*
+ ID_VENDOR_FROM_DATABASE=AGFA-Gevaert NV
+
+usb:v06BDp0001*
+ ID_PRODUCT_FROM_DATABASE=SnapScan 1212U
+
+usb:v06BDp0002*
+ ID_PRODUCT_FROM_DATABASE=SnapScan 1236U
+
+usb:v06BDp0100*
+ ID_PRODUCT_FROM_DATABASE=SnapScan Touch
+
+usb:v06BDp0101*
+ ID_PRODUCT_FROM_DATABASE=SNAPSCAN ELITE
+
+usb:v06BDp0200*
+ ID_PRODUCT_FROM_DATABASE=ScanMaker 8700
+
+usb:v06BDp02BF*
+ ID_PRODUCT_FROM_DATABASE=DUOSCAN f40
+
+usb:v06BDp0400*
+ ID_PRODUCT_FROM_DATABASE=CL30
+
+usb:v06BDp0401*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage
+
+usb:v06BDp0403*
+ ID_PRODUCT_FROM_DATABASE=ePhoto CL18 Camera
+
+usb:v06BDp0404*
+ ID_PRODUCT_FROM_DATABASE=ePhoto CL20 Camera
+
+usb:v06BDp2061*
+ ID_PRODUCT_FROM_DATABASE=SnapScan 1212U (?)
+
+usb:v06BDp208D*
+ ID_PRODUCT_FROM_DATABASE=Snapscan e40
+
+usb:v06BDp208F*
+ ID_PRODUCT_FROM_DATABASE=SnapScan e50
+
+usb:v06BDp2091*
+ ID_PRODUCT_FROM_DATABASE=SnapScan e20
+
+usb:v06BDp2093*
+ ID_PRODUCT_FROM_DATABASE=SnapScan e10
+
+usb:v06BDp2095*
+ ID_PRODUCT_FROM_DATABASE=SnapScan e25
+
+usb:v06BDp2097*
+ ID_PRODUCT_FROM_DATABASE=SnapScan e26
+
+usb:v06BDp20FD*
+ ID_PRODUCT_FROM_DATABASE=SnapScan e52
+
+usb:v06BDp20FF*
+ ID_PRODUCT_FROM_DATABASE=SnapScan e42
+
+usb:v06BE*
+ ID_VENDOR_FROM_DATABASE=AME Optimedia Technology Co., Ltd
+
+usb:v06BEp0800*
+ ID_PRODUCT_FROM_DATABASE=Optimedia Camera
+
+usb:v06BEp1005*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DPVM! (1005)
+
+usb:v06BEpD001*
+ ID_PRODUCT_FROM_DATABASE=P35U Camera Capture
+
+usb:v06BF*
+ ID_VENDOR_FROM_DATABASE=Leoco Corp.
+
+usb:v06C2*
+ ID_VENDOR_FROM_DATABASE=Phidgets Inc. (formerly GLAB)
+
+usb:v06C2p0030*
+ ID_PRODUCT_FROM_DATABASE=PhidgetRFID
+
+usb:v06C2p0038*
+ ID_PRODUCT_FROM_DATABASE=4-Motor PhidgetServo v3.0
+
+usb:v06C2p0039*
+ ID_PRODUCT_FROM_DATABASE=1-Motor PhidgetServo v3.0
+
+usb:v06C2p003A*
+ ID_PRODUCT_FROM_DATABASE=8-Motor PhidgetAvancedServo
+
+usb:v06C2p0040*
+ ID_PRODUCT_FROM_DATABASE=PhidgetInterface Kit 0-0-4
+
+usb:v06C2p0044*
+ ID_PRODUCT_FROM_DATABASE=PhidgetInterface Kit 0-16-16
+
+usb:v06C2p0045*
+ ID_PRODUCT_FROM_DATABASE=PhidgetInterface Kit 8-8-8
+
+usb:v06C2p0048*
+ ID_PRODUCT_FROM_DATABASE=PhidgetStepper (Under Development)
+
+usb:v06C2p0049*
+ ID_PRODUCT_FROM_DATABASE=PhidgetTextLED Ver 1.0
+
+usb:v06C2p004A*
+ ID_PRODUCT_FROM_DATABASE=PhidgetLED Ver 1.0
+
+usb:v06C2p004B*
+ ID_PRODUCT_FROM_DATABASE=PhidgetEncoder Ver 1.0
+
+usb:v06C2p0051*
+ ID_PRODUCT_FROM_DATABASE=PhidgetInterface Kit 0-5-7 (Custom)
+
+usb:v06C2p0052*
+ ID_PRODUCT_FROM_DATABASE=PhidgetTextLCD
+
+usb:v06C2p0053*
+ ID_PRODUCT_FROM_DATABASE=PhidgetInterfaceKit 0-8-8
+
+usb:v06C2p0058*
+ ID_PRODUCT_FROM_DATABASE=PhidgetMotorControl Ver 1.0
+
+usb:v06C2p0070*
+ ID_PRODUCT_FROM_DATABASE=PhidgetTemperatureSensor Ver 1.0
+
+usb:v06C2p0071*
+ ID_PRODUCT_FROM_DATABASE=PhidgetAccelerometer Ver 1.0
+
+usb:v06C2p0072*
+ ID_PRODUCT_FROM_DATABASE=PhidgetWeightSensor Ver 1.0
+
+usb:v06C2p0073*
+ ID_PRODUCT_FROM_DATABASE=PhidgetHumiditySensor
+
+usb:v06C2p0074*
+ ID_PRODUCT_FROM_DATABASE=PhidgetPHSensor
+
+usb:v06C2p0075*
+ ID_PRODUCT_FROM_DATABASE=PhidgetGyroscope
+
+usb:v06C4*
+ ID_VENDOR_FROM_DATABASE=Bizlink International Corp.
+
+usb:v06C5*
+ ID_VENDOR_FROM_DATABASE=Hagenuk, GmbH
+
+usb:v06C6*
+ ID_VENDOR_FROM_DATABASE=Infowave Software, Inc.
+
+usb:v06C8*
+ ID_VENDOR_FROM_DATABASE=SIIG, Inc.
+
+usb:v06C9*
+ ID_VENDOR_FROM_DATABASE=Taxan (Europe), Ltd
+
+usb:v06C9p0005*
+ ID_PRODUCT_FROM_DATABASE=Monitor Control
+
+usb:v06C9p0007*
+ ID_PRODUCT_FROM_DATABASE=Monitor Control
+
+usb:v06C9p0009*
+ ID_PRODUCT_FROM_DATABASE=Monitor Control
+
+usb:v06CA*
+ ID_VENDOR_FROM_DATABASE=Newer Technology, Inc.
+
+usb:v06CB*
+ ID_VENDOR_FROM_DATABASE=Synaptics, Inc.
+
+usb:v06CBp0001*
+ ID_PRODUCT_FROM_DATABASE=TouchPad
+
+usb:v06CBp0002*
+ ID_PRODUCT_FROM_DATABASE=Integrated TouchPad
+
+usb:v06CBp0003*
+ ID_PRODUCT_FROM_DATABASE=cPad
+
+usb:v06CBp0005*
+ ID_PRODUCT_FROM_DATABASE=Touchpad/FPS
+
+usb:v06CBp0006*
+ ID_PRODUCT_FROM_DATABASE=TouchScreen
+
+usb:v06CBp0007*
+ ID_PRODUCT_FROM_DATABASE=USB Styk
+
+usb:v06CBp0008*
+ ID_PRODUCT_FROM_DATABASE=WheelPad
+
+usb:v06CBp0009*
+ ID_PRODUCT_FROM_DATABASE=Composite TouchPad and TrackPoint
+
+usb:v06CBp000E*
+ ID_PRODUCT_FROM_DATABASE=HID Device
+
+usb:v06CBp0010*
+ ID_PRODUCT_FROM_DATABASE=Wireless TouchPad
+
+usb:v06CBp0013*
+ ID_PRODUCT_FROM_DATABASE=DisplayPad
+
+usb:v06CC*
+ ID_VENDOR_FROM_DATABASE=Terayon Communication Systems
+
+usb:v06CCp0101*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v06CCp0102*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v06CCp0103*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v06CCp0104*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v06CCp0304*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v06CD*
+ ID_VENDOR_FROM_DATABASE=Keyspan
+
+usb:v06CDp0101*
+ ID_PRODUCT_FROM_DATABASE=USA-28 PDA [no firmware]
+
+usb:v06CDp0102*
+ ID_PRODUCT_FROM_DATABASE=USA-28X PDA [no firmware]
+
+usb:v06CDp0103*
+ ID_PRODUCT_FROM_DATABASE=USA-19 PDA [no firmware]
+
+usb:v06CDp0104*
+ ID_PRODUCT_FROM_DATABASE=PDA [prerenum]
+
+usb:v06CDp0105*
+ ID_PRODUCT_FROM_DATABASE=USA-18X PDA [no firmware]
+
+usb:v06CDp0106*
+ ID_PRODUCT_FROM_DATABASE=USA-19W PDA [no firmware]
+
+usb:v06CDp0107*
+ ID_PRODUCT_FROM_DATABASE=USA-19 PDA
+
+usb:v06CDp0108*
+ ID_PRODUCT_FROM_DATABASE=USA-19W PDA
+
+usb:v06CDp0109*
+ ID_PRODUCT_FROM_DATABASE=USA-49W serial adapter [no firmware]
+
+usb:v06CDp010A*
+ ID_PRODUCT_FROM_DATABASE=USA-49W serial adapter
+
+usb:v06CDp010B*
+ ID_PRODUCT_FROM_DATABASE=USA-19Qi serial adapter [no firmware]
+
+usb:v06CDp010C*
+ ID_PRODUCT_FROM_DATABASE=USA-19Qi serial adapter
+
+usb:v06CDp010D*
+ ID_PRODUCT_FROM_DATABASE=USA-19Q serial Adapter (no firmware)
+
+usb:v06CDp010E*
+ ID_PRODUCT_FROM_DATABASE=USA-19Q serial Adapter
+
+usb:v06CDp010F*
+ ID_PRODUCT_FROM_DATABASE=USA-28 PDA
+
+usb:v06CDp0110*
+ ID_PRODUCT_FROM_DATABASE=USA-28Xb PDA
+
+usb:v06CDp0111*
+ ID_PRODUCT_FROM_DATABASE=USA-18 serial Adapter
+
+usb:v06CDp0112*
+ ID_PRODUCT_FROM_DATABASE=USA-18X PDA
+
+usb:v06CDp0113*
+ ID_PRODUCT_FROM_DATABASE=USA-28Xb PDA [no firmware]
+
+usb:v06CDp0114*
+ ID_PRODUCT_FROM_DATABASE=USA-28Xa PDA [no firmware]
+
+usb:v06CDp0115*
+ ID_PRODUCT_FROM_DATABASE=USA-28Xa PDA
+
+usb:v06CDp0116*
+ ID_PRODUCT_FROM_DATABASE=USA-18XA serial Adapter (no firmware)
+
+usb:v06CDp0117*
+ ID_PRODUCT_FROM_DATABASE=USA-18XA serial Adapter
+
+usb:v06CDp0118*
+ ID_PRODUCT_FROM_DATABASE=USA-19QW PDA [no firmware]
+
+usb:v06CDp0119*
+ ID_PRODUCT_FROM_DATABASE=USA-19QW PDA
+
+usb:v06CDp011A*
+ ID_PRODUCT_FROM_DATABASE=USA-49Wlc serial adapter [no firmware]
+
+usb:v06CDp011B*
+ ID_PRODUCT_FROM_DATABASE=MPR Serial Preloader (MPRQI)
+
+usb:v06CDp011C*
+ ID_PRODUCT_FROM_DATABASE=MPR Serial (MPRQI)
+
+usb:v06CDp011D*
+ ID_PRODUCT_FROM_DATABASE=MPR Serial Preloader (MPRQ)
+
+usb:v06CDp011E*
+ ID_PRODUCT_FROM_DATABASE=MPR Serial (MPRQ)
+
+usb:v06CDp0121*
+ ID_PRODUCT_FROM_DATABASE=USA-19hs serial adapter
+
+usb:v06CDp012A*
+ ID_PRODUCT_FROM_DATABASE=USA-49Wlc serial adapter
+
+usb:v06CDp0201*
+ ID_PRODUCT_FROM_DATABASE=UIA-10 Digital Media Remote [Cypress AN2131SC]
+
+usb:v06CDp0202*
+ ID_PRODUCT_FROM_DATABASE=UIA-11 Digital Media Remote
+
+usb:v06CE*
+ ID_VENDOR_FROM_DATABASE=Contec
+
+usb:v06CEp8311*
+ ID_PRODUCT_FROM_DATABASE=COM-1(USB)H
+
+usb:v06CF*
+ ID_VENDOR_FROM_DATABASE=SpheronVR AG
+
+usb:v06CFp1010*
+ ID_PRODUCT_FROM_DATABASE=PanoCam 10
+
+usb:v06CFp1012*
+ ID_PRODUCT_FROM_DATABASE=PanoCam 12/12X
+
+usb:v06D0*
+ ID_VENDOR_FROM_DATABASE=LapLink, Inc.
+
+usb:v06D0p0622*
+ ID_PRODUCT_FROM_DATABASE=LapLink Gold USB-USB Bridge [net1080]
+
+usb:v06D1*
+ ID_VENDOR_FROM_DATABASE=Daewoo Electronics Co., Ltd
+
+usb:v06D3*
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corp.
+
+usb:v06D3p0380*
+ ID_PRODUCT_FROM_DATABASE=CP8000D Port
+
+usb:v06D3p0381*
+ ID_PRODUCT_FROM_DATABASE=CP770D Port
+
+usb:v06D3p0385*
+ ID_PRODUCT_FROM_DATABASE=CP900D Port
+
+usb:v06D3p0387*
+ ID_PRODUCT_FROM_DATABASE=CP980D Port
+
+usb:v06D3p038B*
+ ID_PRODUCT_FROM_DATABASE=CP3020D Port
+
+usb:v06D3p038C*
+ ID_PRODUCT_FROM_DATABASE=CP900DW(ID) Port
+
+usb:v06D3p0393*
+ ID_PRODUCT_FROM_DATABASE=CP9500D/DW Port
+
+usb:v06D3p0394*
+ ID_PRODUCT_FROM_DATABASE=CP9000D/DW Port
+
+usb:v06D3p03A1*
+ ID_PRODUCT_FROM_DATABASE=CP9550D/DW Port
+
+usb:v06D4*
+ ID_VENDOR_FROM_DATABASE=Cisco Systems
+
+usb:v06D5*
+ ID_VENDOR_FROM_DATABASE=Toshiba
+
+usb:v06D5p4000*
+ ID_PRODUCT_FROM_DATABASE=Japanese Keyboard
+
+usb:v06D6*
+ ID_VENDOR_FROM_DATABASE=Aashima Technology B.V.
+
+usb:v06D6p0025*
+ ID_PRODUCT_FROM_DATABASE=Gamepad
+
+usb:v06D6p0026*
+ ID_PRODUCT_FROM_DATABASE=Predator TH 400 Gamepad
+
+usb:v06D6p002D*
+ ID_PRODUCT_FROM_DATABASE=Trust PowerC@m 350FT
+
+usb:v06D6p002E*
+ ID_PRODUCT_FROM_DATABASE=Trust PowerC@m 350FS
+
+usb:v06D6p0030*
+ ID_PRODUCT_FROM_DATABASE=Trust 710 LCD POWERC@M ZOOM - MSD
+
+usb:v06D6p0031*
+ ID_PRODUCT_FROM_DATABASE=Trust 610/710 LCD POWERC@M ZOOM
+
+usb:v06D6p003A*
+ ID_PRODUCT_FROM_DATABASE=Trust PowerC@m 770Z (mass storage mode)
+
+usb:v06D6p003B*
+ ID_PRODUCT_FROM_DATABASE=Trust PowerC@m 770Z (webcam mode)
+
+usb:v06D6p003C*
+ ID_PRODUCT_FROM_DATABASE=Trust 910z PowerC@m
+
+usb:v06D6p003F*
+ ID_PRODUCT_FROM_DATABASE=Trust 735S POWERC@M ZOOM, WDM DSC Bulk Driver
+
+usb:v06D6p0050*
+ ID_PRODUCT_FROM_DATABASE=Trust 738AV LCD PV Digital Camera
+
+usb:v06D6p0062*
+ ID_PRODUCT_FROM_DATABASE=TRUST 782AV LCD P. V. Video Capture
+
+usb:v06D6p0066*
+ ID_PRODUCT_FROM_DATABASE=TRUST Digital PCTV and Movie Editor
+
+usb:v06D6p0067*
+ ID_PRODUCT_FROM_DATABASE=Trust 350FS POWERC@M FLASH
+
+usb:v06D6p006B*
+ ID_PRODUCT_FROM_DATABASE=TRUST AUDIO VIDEO EDITOR
+
+usb:v06D7*
+ ID_VENDOR_FROM_DATABASE=Network Computing Devices (NCD)
+
+usb:v06D8*
+ ID_VENDOR_FROM_DATABASE=Technical Marketing Research, Inc.
+
+usb:v06DA*
+ ID_VENDOR_FROM_DATABASE=Phoenixtec Power Co., Ltd
+
+usb:v06DAp0002*
+ ID_PRODUCT_FROM_DATABASE=UPS
+
+usb:v06DAp0003*
+ ID_PRODUCT_FROM_DATABASE=1300VA UPS
+
+usb:v06DB*
+ ID_VENDOR_FROM_DATABASE=Paradyne
+
+usb:v06DC*
+ ID_VENDOR_FROM_DATABASE=Foxlink Image Technology Co., Ltd
+
+usb:v06DCp0012*
+ ID_PRODUCT_FROM_DATABASE=Scan 1200c Scanner
+
+usb:v06DCp0014*
+ ID_PRODUCT_FROM_DATABASE=Prolink Winscan Pro 2448U
+
+usb:v06DE*
+ ID_VENDOR_FROM_DATABASE=Heisei Electronics Co., Ltd
+
+usb:v06E0*
+ ID_VENDOR_FROM_DATABASE=Multi-Tech Systems, Inc.
+
+usb:v06E0pF101*
+ ID_PRODUCT_FROM_DATABASE=MT5634ZBA-USB MultiModemUSB (old firmware)
+
+usb:v06E0pF103*
+ ID_PRODUCT_FROM_DATABASE=MT5634MU MultiMobileUSB
+
+usb:v06E0pF104*
+ ID_PRODUCT_FROM_DATABASE=MT5634ZBA-USB MultiModemUSB (new firmware)
+
+usb:v06E0pF107*
+ ID_PRODUCT_FROM_DATABASE=MT5634ZBA-USB-V92 MultiModemUSB
+
+usb:v06E1*
+ ID_VENDOR_FROM_DATABASE=ADS Technologies, Inc.
+
+usb:v06E1p0008*
+ ID_PRODUCT_FROM_DATABASE=UBS-10BT Ethernet [klsi]
+
+usb:v06E1p0009*
+ ID_PRODUCT_FROM_DATABASE=UBS-10BT Ethernet
+
+usb:v06E1p0833*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v06E1pA155*
+ ID_PRODUCT_FROM_DATABASE=FM Radio Receiver/Instant FM Music (RDX-155-EF)
+
+usb:v06E1pA160*
+ ID_PRODUCT_FROM_DATABASE=Instant Video-To-Go RDX-160 (no firmware)
+
+usb:v06E1pA161*
+ ID_PRODUCT_FROM_DATABASE=Instant Video-To-Go RDX-160
+
+usb:v06E1pA190*
+ ID_PRODUCT_FROM_DATABASE=Instand VCD Capture
+
+usb:v06E1pA191*
+ ID_PRODUCT_FROM_DATABASE=Instant VideoXpress
+
+usb:v06E1pA337*
+ ID_PRODUCT_FROM_DATABASE=Mini DigitalTV
+
+usb:v06E1pA701*
+ ID_PRODUCT_FROM_DATABASE=DVD Xpress
+
+usb:v06E1pA708*
+ ID_PRODUCT_FROM_DATABASE=saa7114H video input card (Instant VideoMPX)
+
+usb:v06E1pB337*
+ ID_PRODUCT_FROM_DATABASE=Mini DigitalTV
+
+usb:v06E1pB701*
+ ID_PRODUCT_FROM_DATABASE=DVD Xpress B
+
+usb:v06E4*
+ ID_VENDOR_FROM_DATABASE=Alcatel Microelectronics
+
+usb:v06E6*
+ ID_VENDOR_FROM_DATABASE=Tiger Jet Network, Inc.
+
+usb:v06E6p0200*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p0201*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p0202*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p0203*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p0210*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p0211*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p0212*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p031C*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p031D*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p031E*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p3200*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p3201*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p3202*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p3203*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p7200*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p7210*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p7250*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p825C*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p831C*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6p831D*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6p831E*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pB200*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pB201*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pB202*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pB210*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pB211*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pB212*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pB250*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pB251*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pB252*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pC200*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pC201*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pC202*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pC203*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pC210*
+ ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway
+
+usb:v06E6pC211*
+ ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway
+
+usb:v06E6pC212*
+ ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway
+
+usb:v06E6pC213*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pC25C*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pC290*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pC291*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pC292*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pC293*
+ ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway
+
+usb:v06E6pC31C*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pC39C*
+ ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway
+
+usb:v06E6pC39D*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pC39E*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pC39F*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pC700*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pC701*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pC702*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pC703*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pC710*
+ ID_PRODUCT_FROM_DATABASE=VoIP Combo Device
+
+usb:v06E6pC711*
+ ID_PRODUCT_FROM_DATABASE=VoIP Combo
+
+usb:v06E6pC712*
+ ID_PRODUCT_FROM_DATABASE=VoIP Combo Device
+
+usb:v06E6pC713*
+ ID_PRODUCT_FROM_DATABASE=VoIP Combo Device
+
+usb:v06E6pCF00*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pCF01*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pCF02*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pCF03*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pD210*
+ ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway
+
+usb:v06E6pD211*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pD212*
+ ID_PRODUCT_FROM_DATABASE=PPG Device
+
+usb:v06E6pD213*
+ ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway
+
+usb:v06E6pD700*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pD701*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pD702*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pD703*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pD710*
+ ID_PRODUCT_FROM_DATABASE=VoIP Combo
+
+usb:v06E6pD711*
+ ID_PRODUCT_FROM_DATABASE=VoIP Combo Device
+
+usb:v06E6pD712*
+ ID_PRODUCT_FROM_DATABASE=VoIP Combo
+
+usb:v06E6pD713*
+ ID_PRODUCT_FROM_DATABASE=VoIP Combo
+
+usb:v06E6pDF00*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pDF01*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pDF02*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pDF03*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pF200*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pF201*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pF202*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pF203*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pF210*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pF250*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06E6pF252*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pF310*
+ ID_PRODUCT_FROM_DATABASE=Internet Phone
+
+usb:v06E6pF350*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v06EA*
+ ID_VENDOR_FROM_DATABASE=Sirius Technologies
+
+usb:v06EAp0001*
+ ID_PRODUCT_FROM_DATABASE=NetCom Roadster II 56k
+
+usb:v06EAp0002*
+ ID_PRODUCT_FROM_DATABASE=Roadster II 56k
+
+usb:v06EB*
+ ID_VENDOR_FROM_DATABASE=PC Expert Tech. Co., Ltd
+
+usb:v06EF*
+ ID_VENDOR_FROM_DATABASE=I.A.C. Geometrische Ingenieurs B.V.
+
+usb:v06F0*
+ ID_VENDOR_FROM_DATABASE=T.N.C Industrial Co., Ltd
+
+usb:v06F0pDE01*
+ ID_PRODUCT_FROM_DATABASE=DualCam Video Camera
+
+usb:v06F0pDE02*
+ ID_PRODUCT_FROM_DATABASE=DualCam Still Camera
+
+usb:v06F1*
+ ID_VENDOR_FROM_DATABASE=Opcode Systems, Inc.
+
+usb:v06F1pA011*
+ ID_PRODUCT_FROM_DATABASE=SonicPort
+
+usb:v06F1pA021*
+ ID_PRODUCT_FROM_DATABASE=SonicPort Optical
+
+usb:v06F2*
+ ID_VENDOR_FROM_DATABASE=Emine Technology Co.
+
+usb:v06F2p0011*
+ ID_PRODUCT_FROM_DATABASE=KVM Switch Keyboard
+
+usb:v06F6*
+ ID_VENDOR_FROM_DATABASE=Wintrend Technology Co., Ltd
+
+usb:v06F7*
+ ID_VENDOR_FROM_DATABASE=Wailly Technology Ltd
+
+usb:v06F7p0003*
+ ID_PRODUCT_FROM_DATABASE=USB->Din 4 Adaptor
+
+usb:v06F8*
+ ID_VENDOR_FROM_DATABASE=Guillemot Corp.
+
+usb:v06F8p3002*
+ ID_PRODUCT_FROM_DATABASE=Hercules Blog Webcam
+
+usb:v06F8p3004*
+ ID_PRODUCT_FROM_DATABASE=Hercules Classic Silver
+
+usb:v06F8p3005*
+ ID_PRODUCT_FROM_DATABASE=Hercules Dualpix Exchange
+
+usb:v06F8p3007*
+ ID_PRODUCT_FROM_DATABASE=Hercules Dualpix Chat and Show
+
+usb:v06F8p3020*
+ ID_PRODUCT_FROM_DATABASE=Hercules Webcam EC300
+
+usb:v06F8pA300*
+ ID_PRODUCT_FROM_DATABASE=Dual Analog Leader GamePad
+
+usb:v06F8pB000*
+ ID_PRODUCT_FROM_DATABASE=Hercules DJ Console
+
+usb:v06F8pC000*
+ ID_PRODUCT_FROM_DATABASE=Hercules Muse Pocket
+
+usb:v06F8pD002*
+ ID_PRODUCT_FROM_DATABASE=Hercules DJ Console
+
+usb:v06F8pE000*
+ ID_PRODUCT_FROM_DATABASE=HWGUSB2-54 WLAN
+
+usb:v06F8pE010*
+ ID_PRODUCT_FROM_DATABASE=HWGUSB2-54-LB
+
+usb:v06F8pE020*
+ ID_PRODUCT_FROM_DATABASE=HWGUSB2-54V2-AP
+
+usb:v06F8pE031*
+ ID_PRODUCT_FROM_DATABASE=Hercules HWNUm-300 Wireless N mini [Realtek RTL8191SU]
+
+usb:v06F8pE032*
+ ID_PRODUCT_FROM_DATABASE=HWGUm-54 [Hercules Wireless G Ultra Mini Key]
+
+usb:v06F8pE033*
+ ID_PRODUCT_FROM_DATABASE=Hercules HWNUp-150 802.11n Wireless N Pico [Realtek RTL8188CUS]
+
+usb:v06F9*
+ ID_VENDOR_FROM_DATABASE=ASYST electronic d.o.o.
+
+usb:v06FA*
+ ID_VENDOR_FROM_DATABASE=HSD S.r.L
+
+usb:v06FC*
+ ID_VENDOR_FROM_DATABASE=Motorola Semiconductor Products Sector
+
+usb:v06FD*
+ ID_VENDOR_FROM_DATABASE=Boston Acoustics
+
+usb:v06FDp0101*
+ ID_PRODUCT_FROM_DATABASE=Audio Device
+
+usb:v06FDp0102*
+ ID_PRODUCT_FROM_DATABASE=Audio Device
+
+usb:v06FDp0201*
+ ID_PRODUCT_FROM_DATABASE=2-piece Audio Device
+
+usb:v06FE*
+ ID_VENDOR_FROM_DATABASE=Gallant Computer, Inc.
+
+usb:v0701*
+ ID_VENDOR_FROM_DATABASE=Supercomal Wire & Cable SDN. BHD.
+
+usb:v0703*
+ ID_VENDOR_FROM_DATABASE=Bvtech Industry, Inc.
+
+usb:v0705*
+ ID_VENDOR_FROM_DATABASE=NKK Corp.
+
+usb:v0706*
+ ID_VENDOR_FROM_DATABASE=Ariel Corp.
+
+usb:v0707*
+ ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp.
+
+usb:v0707p0100*
+ ID_PRODUCT_FROM_DATABASE=2202 Ethernet [klsi]
+
+usb:v0707p0200*
+ ID_PRODUCT_FROM_DATABASE=2202 Ethernet [pegasus]
+
+usb:v0707p0201*
+ ID_PRODUCT_FROM_DATABASE=EZ Connect USB Ethernet
+
+usb:v0707pEE04*
+ ID_PRODUCT_FROM_DATABASE=SMCWUSB32 802.11b Wireless LAN Card
+
+usb:v0707pEE06*
+ ID_PRODUCT_FROM_DATABASE=SMC2862W-G v1 EZ Connect 802.11g Adapter [Intersil ISL3886]
+
+usb:v0707pEE13*
+ ID_PRODUCT_FROM_DATABASE=SMC2862W-G v2 EZ Connect 802.11g Adapter [Intersil ISL3887]
+
+usb:v0708*
+ ID_VENDOR_FROM_DATABASE=Putercom Co., Ltd
+
+usb:v0708p047E*
+ ID_PRODUCT_FROM_DATABASE=USB-1284 BRIDGE
+
+usb:v0709*
+ ID_VENDOR_FROM_DATABASE=Silicon Systems, Ltd (SSL)
+
+usb:v070A*
+ ID_VENDOR_FROM_DATABASE=Oki Electric Industry Co., Ltd
+
+usb:v070Ap4002*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v070Ap4003*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v070D*
+ ID_VENDOR_FROM_DATABASE=Comoss Electronic Co., Ltd
+
+usb:v070E*
+ ID_VENDOR_FROM_DATABASE=Excel Cell Electronic Co., Ltd
+
+usb:v0710*
+ ID_VENDOR_FROM_DATABASE=Connect Tech, Inc.
+
+usb:v0710p0001*
+ ID_PRODUCT_FROM_DATABASE=WhiteHeat (fake ID)
+
+usb:v0710p8001*
+ ID_PRODUCT_FROM_DATABASE=WhiteHeat
+
+usb:v0711*
+ ID_VENDOR_FROM_DATABASE=Magic Control Technology Corp.
+
+usb:v0711p0100*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v0711p0180*
+ ID_PRODUCT_FROM_DATABASE=IRXpress Infrared Device
+
+usb:v0711p0181*
+ ID_PRODUCT_FROM_DATABASE=IRXpress Infrared Device
+
+usb:v0711p0200*
+ ID_PRODUCT_FROM_DATABASE=BAY-3U1S1P Serial Port
+
+usb:v0711p0210*
+ ID_PRODUCT_FROM_DATABASE=MCT1S Serial Port
+
+usb:v0711p0230*
+ ID_PRODUCT_FROM_DATABASE=MCT-232 Serial Port
+
+usb:v0711p0231*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Mouse Port
+
+usb:v0711p0232*
+ ID_PRODUCT_FROM_DATABASE=Serial On Port
+
+usb:v0711p0240*
+ ID_PRODUCT_FROM_DATABASE=PS/2 to USB Converter
+
+usb:v0711p0300*
+ ID_PRODUCT_FROM_DATABASE=BAY-3U1S1P Parallel Port
+
+usb:v0711p0302*
+ ID_PRODUCT_FROM_DATABASE=Parallel Port
+
+usb:v0711p0900*
+ ID_PRODUCT_FROM_DATABASE=SVGA Adapter
+
+usb:v0711p5001*
+ ID_PRODUCT_FROM_DATABASE=Trigger UV-002BD[Startech USBVGAE]
+
+usb:v0711p5100*
+ ID_PRODUCT_FROM_DATABASE=Magic Control Technology Corp. (USB2VGA dongle)
+
+usb:v0713*
+ ID_VENDOR_FROM_DATABASE=Interval Research Corp.
+
+usb:v0714*
+ ID_VENDOR_FROM_DATABASE=NewMotion, Inc.
+
+usb:v0714p0003*
+ ID_PRODUCT_FROM_DATABASE=ADB to USB convertor
+
+usb:v0717*
+ ID_VENDOR_FROM_DATABASE=ZNK Corp.
+
+usb:v0718*
+ ID_VENDOR_FROM_DATABASE=Imation Corp.
+
+usb:v0718p0002*
+ ID_PRODUCT_FROM_DATABASE=SuperDisk 120MB
+
+usb:v0718p0003*
+ ID_PRODUCT_FROM_DATABASE=SuperDisk 120MB (Authenticated)
+
+usb:v0718p0060*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v0718p0061*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v0718p0062*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v0718p0063*
+ ID_PRODUCT_FROM_DATABASE=Swivel Flash Drive
+
+usb:v0718p0064*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v0718p0065*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v0718p0066*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v0718p0067*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v0718p0068*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v0718p0084*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive Mini
+
+usb:v0718p043C*
+ ID_PRODUCT_FROM_DATABASE=Flash drive 16GB [Nano Pro]
+
+usb:v0718p0582*
+ ID_PRODUCT_FROM_DATABASE=Revo Flash Drive
+
+usb:v0718p1120*
+ ID_PRODUCT_FROM_DATABASE=RDX External dock (redbud)
+
+usb:v0718pD000*
+ ID_PRODUCT_FROM_DATABASE=Disc Stakka CD/DVD Manager
+
+usb:v0719*
+ ID_VENDOR_FROM_DATABASE=Tremon Enterprises Co., Ltd
+
+usb:v071B*
+ ID_VENDOR_FROM_DATABASE=Domain Technologies, Inc.
+
+usb:v071Bp0002*
+ ID_PRODUCT_FROM_DATABASE=DTI-56362-USB Digital Interface Unit
+
+usb:v071Bp0101*
+ ID_PRODUCT_FROM_DATABASE=Audio4-USB DSP Data Acquisition Unit
+
+usb:v071Bp0201*
+ ID_PRODUCT_FROM_DATABASE=Audio4-5410 DSP Data Acquisition Unit
+
+usb:v071Bp0301*
+ ID_PRODUCT_FROM_DATABASE=SB-USB JTAG Emulator
+
+usb:v071Bp3203*
+ ID_PRODUCT_FROM_DATABASE=Rockchip Media Player
+
+usb:v071Bp32BB*
+ ID_PRODUCT_FROM_DATABASE=Music Mediatouch
+
+usb:v071C*
+ ID_VENDOR_FROM_DATABASE=Xionics Document Technologies, Inc.
+
+usb:v071D*
+ ID_VENDOR_FROM_DATABASE=Eicon Networks Corp.
+
+usb:v071Dp1000*
+ ID_PRODUCT_FROM_DATABASE=Diva ISDN TA
+
+usb:v071Dp1003*
+ ID_PRODUCT_FROM_DATABASE=Diva
+
+usb:v071Dp2000*
+ ID_PRODUCT_FROM_DATABASE=Teledat Surf
+
+usb:v071E*
+ ID_VENDOR_FROM_DATABASE=Ariston Technologies
+
+usb:v0723*
+ ID_VENDOR_FROM_DATABASE=Centillium Communications Corp.
+
+usb:v0723p0002*
+ ID_PRODUCT_FROM_DATABASE=Palladia 300/400 Adsl Modem
+
+usb:v0726*
+ ID_VENDOR_FROM_DATABASE=Vanguard International Semiconductor-America
+
+usb:v0729*
+ ID_VENDOR_FROM_DATABASE=Amitm
+
+usb:v0729p1000*
+ ID_PRODUCT_FROM_DATABASE=USC-1000 Serial Port
+
+usb:v072E*
+ ID_VENDOR_FROM_DATABASE=Sunix Co., Ltd
+
+usb:v072F*
+ ID_VENDOR_FROM_DATABASE=Advanced Card Systems, Ltd
+
+usb:v072Fp0001*
+ ID_PRODUCT_FROM_DATABASE=AC1030-based SmartCard Reader
+
+usb:v072Fp0008*
+ ID_PRODUCT_FROM_DATABASE=ACR 80 Smart Card Reader
+
+usb:v072Fp1000*
+ ID_PRODUCT_FROM_DATABASE=PLDT Drive
+
+usb:v072Fp1001*
+ ID_PRODUCT_FROM_DATABASE=PLDT Drive
+
+usb:v072Fp8002*
+ ID_PRODUCT_FROM_DATABASE=AET63 BioTRUSTKey
+
+usb:v072Fp8003*
+ ID_PRODUCT_FROM_DATABASE=ACR120
+
+usb:v072Fp8103*
+ ID_PRODUCT_FROM_DATABASE=ACR120
+
+usb:v072Fp9000*
+ ID_PRODUCT_FROM_DATABASE=ACR38 AC1038-based Smart Card Reader
+
+usb:v072Fp90CC*
+ ID_PRODUCT_FROM_DATABASE=ACR38 SmartCard Reader
+
+usb:v072Fp90CF*
+ ID_PRODUCT_FROM_DATABASE=ACR38 SAM Smart Card Reader
+
+usb:v072Fp90D0*
+ ID_PRODUCT_FROM_DATABASE=PertoSmart EMV - Card Reader
+
+usb:v0731*
+ ID_VENDOR_FROM_DATABASE=Susteen, Inc.
+
+usb:v0731p0528*
+ ID_PRODUCT_FROM_DATABASE=SonyEricsson DCU-11 Cable
+
+usb:v0732*
+ ID_VENDOR_FROM_DATABASE=Goldfull Electronics & Telecommunications Corp.
+
+usb:v0733*
+ ID_VENDOR_FROM_DATABASE=ViewQuest Technologies, Inc.
+
+usb:v0733p0101*
+ ID_PRODUCT_FROM_DATABASE=Digital Video Camera
+
+usb:v0733p0110*
+ ID_PRODUCT_FROM_DATABASE=VQ110 Video Camera
+
+usb:v0733p0401*
+ ID_PRODUCT_FROM_DATABASE=CS330 Webcam
+
+usb:v0733p0402*
+ ID_PRODUCT_FROM_DATABASE=M-318B Webcam
+
+usb:v0733p0430*
+ ID_PRODUCT_FROM_DATABASE=Intel Pro Share Webcam
+
+usb:v0733p0630*
+ ID_PRODUCT_FROM_DATABASE=VQ630 Dual Mode Digital Camera(Bulk)
+
+usb:v0733p0631*
+ ID_PRODUCT_FROM_DATABASE=Hercules Dualpix
+
+usb:v0733p0780*
+ ID_PRODUCT_FROM_DATABASE=Smart Cam Deluxe(composite)
+
+usb:v0733p1310*
+ ID_PRODUCT_FROM_DATABASE=Epsilon 1.3/Jenoptik JD C1.3/UMAX AstraPix 470
+
+usb:v0733p1311*
+ ID_PRODUCT_FROM_DATABASE=Digital Dream Epsilon 1.3
+
+usb:v0733p1314*
+ ID_PRODUCT_FROM_DATABASE=Mercury 2.1MEG Deluxe Classic Cam
+
+usb:v0733p2211*
+ ID_PRODUCT_FROM_DATABASE=Jenoptik jdc 21 LCD Camera
+
+usb:v0733p2221*
+ ID_PRODUCT_FROM_DATABASE=Mercury Digital Pro 3.1p
+
+usb:v0733p3261*
+ ID_PRODUCT_FROM_DATABASE=Concord 3045 spca536a Camera
+
+usb:v0733p3281*
+ ID_PRODUCT_FROM_DATABASE=Cyberpix S550V
+
+usb:v0734*
+ ID_VENDOR_FROM_DATABASE=Lasat Communications A/S
+
+usb:v0734p0001*
+ ID_PRODUCT_FROM_DATABASE=560V Modem
+
+usb:v0734p0002*
+ ID_PRODUCT_FROM_DATABASE=Lasat 560V Modem
+
+usb:v0734p043A*
+ ID_PRODUCT_FROM_DATABASE=DVS Audio
+
+usb:v0734p043B*
+ ID_PRODUCT_FROM_DATABASE=3DeMon USB Capture
+
+usb:v0735*
+ ID_VENDOR_FROM_DATABASE=Asuscom Network
+
+usb:v0735p2100*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter
+
+usb:v0735p2101*
+ ID_PRODUCT_FROM_DATABASE=ISDN Adapter
+
+usb:v0735p6694*
+ ID_PRODUCT_FROM_DATABASE=ISDNlink 128K
+
+usb:v0735pC541*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA 280
+
+usb:v0736*
+ ID_VENDOR_FROM_DATABASE=Lorom Industrial Co., Ltd
+
+usb:v0738*
+ ID_VENDOR_FROM_DATABASE=Mad Catz, Inc.
+
+usb:v0738p4507*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4516*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4520*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4526*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4536*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4540*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4556*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4566*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4576*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4586*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p4588*
+ ID_PRODUCT_FROM_DATABASE=XBox Device
+
+usb:v0738p8818*
+ ID_PRODUCT_FROM_DATABASE=Street Fighter IV Arcade FightStick (PS3)
+
+usb:v073A*
+ ID_VENDOR_FROM_DATABASE=Chaplet Systems, Inc.
+
+usb:v073Ap2230*
+ ID_PRODUCT_FROM_DATABASE=infrared dongle for remote
+
+usb:v073B*
+ ID_VENDOR_FROM_DATABASE=Suncom Technologies
+
+usb:v073C*
+ ID_VENDOR_FROM_DATABASE=Industrial Electronic Engineers, Inc.
+
+usb:v073Cp0305*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (PC305-3415  2 x 20 Line Display)
+
+usb:v073Cp0322*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (PC322-3415  2 x 20 Line Display)
+
+usb:v073Cp0324*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (LB324-USB   4 x 20 Line Display)
+
+usb:v073Cp0330*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (P330-3415   2 x 20 Line Display)
+
+usb:v073Cp0424*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (SP324-4415  4 x 20 Line Display)
+
+usb:v073Cp0450*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (L450-USB   Graphic Line Display)
+
+usb:v073Cp0505*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (SPC505-3415 2 x 20 Line Display)
+
+usb:v073Cp0522*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (SPC522-3415 2 x 20 Line Display)
+
+usb:v073Cp0624*
+ ID_PRODUCT_FROM_DATABASE=Pole Display (SP324-3415  4 x 20 Line Display)
+
+usb:v073D*
+ ID_VENDOR_FROM_DATABASE=Eutron S.p.a.
+
+usb:v073Dp0005*
+ ID_PRODUCT_FROM_DATABASE=Crypto Token
+
+usb:v073Dp0007*
+ ID_PRODUCT_FROM_DATABASE=CryptoIdentity CCID
+
+usb:v073Dp0025*
+ ID_PRODUCT_FROM_DATABASE=SmartKey 3
+
+usb:v073Dp0C00*
+ ID_PRODUCT_FROM_DATABASE=Pocket Reader
+
+usb:v073Dp0D00*
+ ID_PRODUCT_FROM_DATABASE=StarSign Bio Token 3.0 EU
+
+usb:v073E*
+ ID_VENDOR_FROM_DATABASE=NEC, Inc.
+
+usb:v073Ep0301*
+ ID_PRODUCT_FROM_DATABASE=Game Pad
+
+usb:v0745*
+ ID_VENDOR_FROM_DATABASE=Syntech Information Co., Ltd
+
+usb:v0746*
+ ID_VENDOR_FROM_DATABASE=Onkyo Corp.
+
+usb:v0746p5500*
+ ID_PRODUCT_FROM_DATABASE=SE-U55 Audio Device
+
+usb:v0747*
+ ID_VENDOR_FROM_DATABASE=Labway Corp.
+
+usb:v0748*
+ ID_VENDOR_FROM_DATABASE=Strong Man Enterprise Co., Ltd
+
+usb:v0749*
+ ID_VENDOR_FROM_DATABASE=EVer Electronics Corp.
+
+usb:v074A*
+ ID_VENDOR_FROM_DATABASE=Ming Fortune Industry Co., Ltd
+
+usb:v074B*
+ ID_VENDOR_FROM_DATABASE=Polestar Tech. Corp.
+
+usb:v074C*
+ ID_VENDOR_FROM_DATABASE=C-C-C Group PLC
+
+usb:v074D*
+ ID_VENDOR_FROM_DATABASE=Micronas GmbH
+
+usb:v074Dp3553*
+ ID_PRODUCT_FROM_DATABASE=Composite USB-Device
+
+usb:v074Dp3554*
+ ID_PRODUCT_FROM_DATABASE=Composite USB-Device
+
+usb:v074Dp3556*
+ ID_PRODUCT_FROM_DATABASE=Composite USB-Device
+
+usb:v074E*
+ ID_VENDOR_FROM_DATABASE=Digital Stream Corp.
+
+usb:v074Ep0001*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Adapter
+
+usb:v074Ep0002*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Adapter
+
+usb:v0755*
+ ID_VENDOR_FROM_DATABASE=Aureal Semiconductor
+
+usb:v0757*
+ ID_VENDOR_FROM_DATABASE=Network Technologies, Inc.
+
+usb:v075B*
+ ID_VENDOR_FROM_DATABASE=Sophisticated Circuits, Inc.
+
+usb:v075Bp0001*
+ ID_PRODUCT_FROM_DATABASE=Kick-off! Watchdog
+
+usb:v0763*
+ ID_VENDOR_FROM_DATABASE=Midiman
+
+usb:v0763p0115*
+ ID_PRODUCT_FROM_DATABASE=O2 / KeyRig 25
+
+usb:v0763p0117*
+ ID_PRODUCT_FROM_DATABASE=Trigger Finger
+
+usb:v0763p0119*
+ ID_PRODUCT_FROM_DATABASE=MidAir
+
+usb:v0763p0150*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Uno
+
+usb:v0763p0160*
+ ID_PRODUCT_FROM_DATABASE=M-Audio 1x1
+
+usb:v0763p0192*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Keystation 88es
+
+usb:v0763p0193*
+ ID_PRODUCT_FROM_DATABASE=ProKeys 88
+
+usb:v0763p0194*
+ ID_PRODUCT_FROM_DATABASE=ProKeys 88sx
+
+usb:v0763p0195*
+ ID_PRODUCT_FROM_DATABASE=Oxygen 8 v2
+
+usb:v0763p0196*
+ ID_PRODUCT_FROM_DATABASE=Oxygen 49
+
+usb:v0763p0197*
+ ID_PRODUCT_FROM_DATABASE=Oxygen 61
+
+usb:v0763p0198*
+ ID_PRODUCT_FROM_DATABASE=Axiom 25
+
+usb:v0763p0199*
+ ID_PRODUCT_FROM_DATABASE=Axiom 49
+
+usb:v0763p019A*
+ ID_PRODUCT_FROM_DATABASE=Axiom 61
+
+usb:v0763p019B*
+ ID_PRODUCT_FROM_DATABASE=KeyRig 49
+
+usb:v0763p019C*
+ ID_PRODUCT_FROM_DATABASE=KeyStudio
+
+usb:v0763p1001*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 2x2
+
+usb:v0763p1002*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 2x2
+
+usb:v0763p1003*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 2x2
+
+usb:v0763p1010*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 1x1
+
+usb:v0763p1011*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 1x1
+
+usb:v0763p1014*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Keystation Loader
+
+usb:v0763p1015*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Keystation
+
+usb:v0763p1020*
+ ID_PRODUCT_FROM_DATABASE=Midisport 4x4
+
+usb:v0763p1021*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 4x4
+
+usb:v0763p1030*
+ ID_PRODUCT_FROM_DATABASE=Midisport 8x8
+
+usb:v0763p1031*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 8x8/s Loader
+
+usb:v0763p1033*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 8x8/s
+
+usb:v0763p1040*
+ ID_PRODUCT_FROM_DATABASE=M-Audio MidiSport 2x4 Loader
+
+usb:v0763p1041*
+ ID_PRODUCT_FROM_DATABASE=M-Audio MidiSport 2x4
+
+usb:v0763p1110*
+ ID_PRODUCT_FROM_DATABASE=MidiSport 1x1
+
+usb:v0763p2001*
+ ID_PRODUCT_FROM_DATABASE=M Audio Quattro
+
+usb:v0763p2002*
+ ID_PRODUCT_FROM_DATABASE=M Audio Duo
+
+usb:v0763p2003*
+ ID_PRODUCT_FROM_DATABASE=M Audio AudioPhile
+
+usb:v0763p2004*
+ ID_PRODUCT_FROM_DATABASE=M-Audio MobilePre
+
+usb:v0763p2006*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Transit
+
+usb:v0763p2007*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Sonica Theater
+
+usb:v0763p2008*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Ozone
+
+usb:v0763p200D*
+ ID_PRODUCT_FROM_DATABASE=M-Audio OmniStudio
+
+usb:v0763p200F*
+ ID_PRODUCT_FROM_DATABASE=M-Audio MobilePre
+
+usb:v0763p2010*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Fast Track
+
+usb:v0763p2012*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Fast Track Pro
+
+usb:v0763p2013*
+ ID_PRODUCT_FROM_DATABASE=M-Audio JamLab
+
+usb:v0763p2015*
+ ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU
+
+usb:v0763p2016*
+ ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU
+
+usb:v0763p2019*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Ozone Academic
+
+usb:v0763p201A*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Micro
+
+usb:v0763p201B*
+ ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU
+
+usb:v0763p201D*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Producer
+
+usb:v0763p2024*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Fast Track MKII
+
+usb:v0763p2080*
+ ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU
+
+usb:v0763p2081*
+ ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU / Fast Track Ultra 8R
+
+usb:v0763p2803*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Audiophile DFU
+
+usb:v0763p2804*
+ ID_PRODUCT_FROM_DATABASE=M-Audio MobilePre DFU
+
+usb:v0763p2806*
+ ID_PRODUCT_FROM_DATABASE=M-Audio Transit DFU
+
+usb:v0763p2815*
+ ID_PRODUCT_FROM_DATABASE=M-Audio DFU
+
+usb:v0763p2816*
+ ID_PRODUCT_FROM_DATABASE=M-Audio DFU
+
+usb:v0763p281B*
+ ID_PRODUCT_FROM_DATABASE=M-Audio DFU
+
+usb:v0763p2880*
+ ID_PRODUCT_FROM_DATABASE=M-Audio DFU
+
+usb:v0763p2881*
+ ID_PRODUCT_FROM_DATABASE=M-Audio DFU
+
+usb:v0764*
+ ID_VENDOR_FROM_DATABASE=Cyber Power System, Inc.
+
+usb:v0764p0005*
+ ID_PRODUCT_FROM_DATABASE=Cyber Power UPS
+
+usb:v0764p0501*
+ ID_PRODUCT_FROM_DATABASE=CP1500 AVR UPS
+
+usb:v0765*
+ ID_VENDOR_FROM_DATABASE=X-Rite, Inc.
+
+usb:v0765p5001*
+ ID_PRODUCT_FROM_DATABASE=Huey PRO Colorimeter
+
+usb:v0765pD094*
+ ID_PRODUCT_FROM_DATABASE=X-Rite DTP94 [Quato Silver Haze Pro]
+
+usb:v0766*
+ ID_VENDOR_FROM_DATABASE=Jess-Link Products Co., Ltd
+
+usb:v0766p001B*
+ ID_PRODUCT_FROM_DATABASE=Packard Bell Go
+
+usb:v0766p0204*
+ ID_PRODUCT_FROM_DATABASE=TopSpeed Cyberlink Remote Control
+
+usb:v0767*
+ ID_VENDOR_FROM_DATABASE=Tokheim Corp.
+
+usb:v0768*
+ ID_VENDOR_FROM_DATABASE=Camtel Technology Corp.
+
+usb:v0768p0006*
+ ID_PRODUCT_FROM_DATABASE=Camtel Technology USB TV Genie Pro FM Model TVB330
+
+usb:v0768p0023*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0769*
+ ID_VENDOR_FROM_DATABASE=Surecom Technology Corp.
+
+usb:v0769p11F2*
+ ID_PRODUCT_FROM_DATABASE=EP-9001-g 802.11g 54M WLAN Adapter
+
+usb:v0769p11F3*
+ ID_PRODUCT_FROM_DATABASE=RT2570
+
+usb:v0769p11F7*
+ ID_PRODUCT_FROM_DATABASE=802.11g 54M WLAN Adapter
+
+usb:v0769p31F3*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v076A*
+ ID_VENDOR_FROM_DATABASE=Smart Technology Enablers, Inc.
+
+usb:v076B*
+ ID_VENDOR_FROM_DATABASE=OmniKey AG
+
+usb:v076Bp0596*
+ ID_PRODUCT_FROM_DATABASE=CardMan 2020
+
+usb:v076Bp1021*
+ ID_PRODUCT_FROM_DATABASE=CardMan 1021
+
+usb:v076Bp1221*
+ ID_PRODUCT_FROM_DATABASE=CardMan 1221
+
+usb:v076Bp1784*
+ ID_PRODUCT_FROM_DATABASE=CardMan 6020
+
+usb:v076Bp3021*
+ ID_PRODUCT_FROM_DATABASE=CardMan 3121
+
+usb:v076Bp3610*
+ ID_PRODUCT_FROM_DATABASE=CardMan 3620
+
+usb:v076Bp3621*
+ ID_PRODUCT_FROM_DATABASE=CardMan 3621
+
+usb:v076Bp3821*
+ ID_PRODUCT_FROM_DATABASE=CardMan 3821
+
+usb:v076Bp4321*
+ ID_PRODUCT_FROM_DATABASE=CardMan 4321
+
+usb:v076Bp5121*
+ ID_PRODUCT_FROM_DATABASE=CardMan 5121
+
+usb:v076Bp5125*
+ ID_PRODUCT_FROM_DATABASE=CardMan 5125
+
+usb:v076Bp6622*
+ ID_PRODUCT_FROM_DATABASE=CardMan 6121
+
+usb:v076BpA011*
+ ID_PRODUCT_FROM_DATABASE=CCID Smart Card Reader Keyboard
+
+usb:v076BpA021*
+ ID_PRODUCT_FROM_DATABASE=CCID Smart Card Reader
+
+usb:v076BpA022*
+ ID_PRODUCT_FROM_DATABASE=CardMan Smart@Link
+
+usb:v076BpC000*
+ ID_PRODUCT_FROM_DATABASE=CardMan 3x21 CS
+
+usb:v076BpC001*
+ ID_PRODUCT_FROM_DATABASE=CardMan 5121 CS
+
+usb:v076C*
+ ID_VENDOR_FROM_DATABASE=Partner Tech
+
+usb:v076D*
+ ID_VENDOR_FROM_DATABASE=Denso Corp.
+
+usb:v076E*
+ ID_VENDOR_FROM_DATABASE=Kuan Tech Enterprise Co., Ltd
+
+usb:v076F*
+ ID_VENDOR_FROM_DATABASE=Jhen Vei Electronic Co., Ltd
+
+usb:v0770*
+ ID_VENDOR_FROM_DATABASE=Welch Allyn, Inc - Medical Division
+
+usb:v0771*
+ ID_VENDOR_FROM_DATABASE=Observator Instruments BV
+
+usb:v0771p4455*
+ ID_PRODUCT_FROM_DATABASE=OMC45III
+
+usb:v0771pAE0F*
+ ID_PRODUCT_FROM_DATABASE=OMC45III
+
+usb:v0772*
+ ID_VENDOR_FROM_DATABASE=Your data Our Care
+
+usb:v0774*
+ ID_VENDOR_FROM_DATABASE=AmTRAN Technology Co., Ltd
+
+usb:v0775*
+ ID_VENDOR_FROM_DATABASE=Longshine Electronics Corp.
+
+usb:v0776*
+ ID_VENDOR_FROM_DATABASE=Inalways Corp.
+
+usb:v0777*
+ ID_VENDOR_FROM_DATABASE=Comda Enterprise Corp.
+
+usb:v0778*
+ ID_VENDOR_FROM_DATABASE=Volex, Inc.
+
+usb:v0779*
+ ID_VENDOR_FROM_DATABASE=Fairchild Semiconductor
+
+usb:v077A*
+ ID_VENDOR_FROM_DATABASE=Sankyo Seiki Mfg. Co., Ltd
+
+usb:v077B*
+ ID_VENDOR_FROM_DATABASE=Linksys
+
+usb:v077Bp08BE*
+ ID_PRODUCT_FROM_DATABASE=BEFCMU10 v4 Cable Modem
+
+usb:v077Bp2219*
+ ID_PRODUCT_FROM_DATABASE=WUSB11 V2.6 802.11b Adapter
+
+usb:v077Bp2226*
+ ID_PRODUCT_FROM_DATABASE=USB200M 100baseTX Adapter
+
+usb:v077Bp2227*
+ ID_PRODUCT_FROM_DATABASE=Network Everywhere NWU11B
+
+usb:v077C*
+ ID_VENDOR_FROM_DATABASE=Forward Electronics Co., Ltd
+
+usb:v077Cp0005*
+ ID_PRODUCT_FROM_DATABASE=NEC Keyboard
+
+usb:v077D*
+ ID_VENDOR_FROM_DATABASE=Griffin Technology
+
+usb:v077Dp0223*
+ ID_PRODUCT_FROM_DATABASE=IMic Audio In/Out
+
+usb:v077Dp0405*
+ ID_PRODUCT_FROM_DATABASE=iMate, ADB Adapter
+
+usb:v077Dp0410*
+ ID_PRODUCT_FROM_DATABASE=PowerMate
+
+usb:v077Dp041A*
+ ID_PRODUCT_FROM_DATABASE=PowerWave
+
+usb:v077Dp04AA*
+ ID_PRODUCT_FROM_DATABASE=SoundKnob
+
+usb:v077Dp07AF*
+ ID_PRODUCT_FROM_DATABASE=iMic
+
+usb:v077Dp1016*
+ ID_PRODUCT_FROM_DATABASE=AirClick
+
+usb:v077Dp627A*
+ ID_PRODUCT_FROM_DATABASE=Radio SHARK
+
+usb:v077F*
+ ID_VENDOR_FROM_DATABASE=Well Excellent & Most Corp.
+
+usb:v0780*
+ ID_VENDOR_FROM_DATABASE=Sagem Monetel GmbH
+
+usb:v0780p1202*
+ ID_PRODUCT_FROM_DATABASE=ORGA 900 Smart Card Terminal Virtual Com Port
+
+usb:v0780p1302*
+ ID_PRODUCT_FROM_DATABASE=ORGA 6000 Smart Card Terminal Virtual Com Port
+
+usb:v0780p1303*
+ ID_PRODUCT_FROM_DATABASE=ORGA 6000 Smart Card Terminal USB RNDIS
+
+usb:v0780pDF55*
+ ID_PRODUCT_FROM_DATABASE=ORGA 900/6000 Smart Card Terminal DFU
+
+usb:v0781*
+ ID_VENDOR_FROM_DATABASE=SanDisk Corp.
+
+usb:v0781p0001*
+ ID_PRODUCT_FROM_DATABASE=SDDR-05a ImageMate CompactFlash Reader
+
+usb:v0781p0002*
+ ID_PRODUCT_FROM_DATABASE=SDDR-31 ImageMate II CompactFlash Reader
+
+usb:v0781p0005*
+ ID_PRODUCT_FROM_DATABASE=SDDR-05b (CF II) ImageMate CompactFlash Reader
+
+usb:v0781p0100*
+ ID_PRODUCT_FROM_DATABASE=ImageMate SDDR-12
+
+usb:v0781p0200*
+ ID_PRODUCT_FROM_DATABASE=SDDR-09 (SSFDC) ImageMate SmartMedia Reader [eusb]
+
+usb:v0781p0400*
+ ID_PRODUCT_FROM_DATABASE=SecureMate SD/MMC Reader
+
+usb:v0781p0621*
+ ID_PRODUCT_FROM_DATABASE=SDDR-86 Imagemate 6-in-1 Reader
+
+usb:v0781p0720*
+ ID_PRODUCT_FROM_DATABASE=Sansa C200 series in recovery mode
+
+usb:v0781p0729*
+ ID_PRODUCT_FROM_DATABASE=Sansa E200 series in recovery mode
+
+usb:v0781p0810*
+ ID_PRODUCT_FROM_DATABASE=SDDR-75 ImageMate CF-SM Reader
+
+usb:v0781p0830*
+ ID_PRODUCT_FROM_DATABASE=ImageMate CF/MMC/SD Reader
+
+usb:v0781p1234*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Mini Flash Drive
+
+usb:v0781p5150*
+ ID_PRODUCT_FROM_DATABASE=SDCZ2 Cruzer Mini Flash Drive (thin)
+
+usb:v0781p5151*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Micro Flash Drive
+
+usb:v0781p5153*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Flash Drive
+
+usb:v0781p5204*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Crossfire
+
+usb:v0781p5402*
+ ID_PRODUCT_FROM_DATABASE=U3 Cruzer Micro
+
+usb:v0781p5406*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Micro U3
+
+usb:v0781p5408*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Titanium U3
+
+usb:v0781p540E*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Contour Flash Drive
+
+usb:v0781p5530*
+ ID_PRODUCT_FROM_DATABASE=Cruzer
+
+usb:v0781p5567*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Blade
+
+usb:v0781p5571*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Fit
+
+usb:v0781p5E10*
+ ID_PRODUCT_FROM_DATABASE=Encrypted
+
+usb:v0781p6100*
+ ID_PRODUCT_FROM_DATABASE=Ultra II SD Plus 2GB
+
+usb:v0781p7100*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Mini
+
+usb:v0781p7101*
+ ID_PRODUCT_FROM_DATABASE=Pen Flash
+
+usb:v0781p7102*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Mini
+
+usb:v0781p7103*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Mini
+
+usb:v0781p7104*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Micro Mini 256MB Flash Drive
+
+usb:v0781p7105*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Mini
+
+usb:v0781p7106*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Mini
+
+usb:v0781p7112*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Micro 128MB Flash Drive
+
+usb:v0781p7113*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Micro 256MB Flash Drive
+
+usb:v0781p7114*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Mini
+
+usb:v0781p7115*
+ ID_PRODUCT_FROM_DATABASE=Cruzer Mini
+
+usb:v0781p7301*
+ ID_PRODUCT_FROM_DATABASE=Sansa e100 series (mtp)
+
+usb:v0781p7302*
+ ID_PRODUCT_FROM_DATABASE=Sansa e100 series (msc)
+
+usb:v0781p7400*
+ ID_PRODUCT_FROM_DATABASE=Sansa M200 series (mtp)
+
+usb:v0781p7401*
+ ID_PRODUCT_FROM_DATABASE=Sansa M200 series (msc)
+
+usb:v0781p7420*
+ ID_PRODUCT_FROM_DATABASE=Sansa E200 series (mtp)
+
+usb:v0781p7421*
+ ID_PRODUCT_FROM_DATABASE=Sansa E200 Series (msc)
+
+usb:v0781p7422*
+ ID_PRODUCT_FROM_DATABASE=Sansa E200 series v2 (mtp)
+
+usb:v0781p7423*
+ ID_PRODUCT_FROM_DATABASE=Sansa E200 series v2 (msc)
+
+usb:v0781p7430*
+ ID_PRODUCT_FROM_DATABASE=Sansa M200 series
+
+usb:v0781p7431*
+ ID_PRODUCT_FROM_DATABASE=Sansa M200 series V4 (msc)
+
+usb:v0781p7432*
+ ID_PRODUCT_FROM_DATABASE=Sansa Clip (mtp)
+
+usb:v0781p7433*
+ ID_PRODUCT_FROM_DATABASE=Sansa Clip (msc)
+
+usb:v0781p7434*
+ ID_PRODUCT_FROM_DATABASE=Sansa Clip V2 (mtp)
+
+usb:v0781p7435*
+ ID_PRODUCT_FROM_DATABASE=Sansa Clip V2 (msc)
+
+usb:v0781p7450*
+ ID_PRODUCT_FROM_DATABASE=Sansa C250
+
+usb:v0781p7451*
+ ID_PRODUCT_FROM_DATABASE=Sansa C240
+
+usb:v0781p7460*
+ ID_PRODUCT_FROM_DATABASE=Sansa Express
+
+usb:v0781p7480*
+ ID_PRODUCT_FROM_DATABASE=Sansa Connect
+
+usb:v0781p7481*
+ ID_PRODUCT_FROM_DATABASE=Sansa Connect (in recovery mode)
+
+usb:v0781p74B0*
+ ID_PRODUCT_FROM_DATABASE=Sansa View (msc)
+
+usb:v0781p74B1*
+ ID_PRODUCT_FROM_DATABASE=Sansa View (mtp)
+
+usb:v0781p74C0*
+ ID_PRODUCT_FROM_DATABASE=Sansa Fuze (mtp)
+
+usb:v0781p74C1*
+ ID_PRODUCT_FROM_DATABASE=Sansa Fuze (msc)
+
+usb:v0781p74C2*
+ ID_PRODUCT_FROM_DATABASE=Sansa Fuze V2 (mtp)
+
+usb:v0781p74C3*
+ ID_PRODUCT_FROM_DATABASE=Sansa Fuze V2 (msc)
+
+usb:v0781p74D0*
+ ID_PRODUCT_FROM_DATABASE=Sansa Clip+ (mtp)
+
+usb:v0781p74D1*
+ ID_PRODUCT_FROM_DATABASE=Sansa Clip+ (msc)
+
+usb:v0781p8181*
+ ID_PRODUCT_FROM_DATABASE=Pen Flash
+
+usb:v0781p8183*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device
+
+usb:v0781p8185*
+ ID_PRODUCT_FROM_DATABASE=SDCZ2 Cruzer Mini Flash Drive (older, thick)
+
+usb:v0781p8888*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v0781p8889*
+ ID_PRODUCT_FROM_DATABASE=SDDR-88 Imagemate 8-in-1 Reader
+
+usb:v0781p8919*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v0781p8989*
+ ID_PRODUCT_FROM_DATABASE=ImageMate 12-in-1 Reader
+
+usb:v0781p9191*
+ ID_PRODUCT_FROM_DATABASE=ImageMate CF
+
+usb:v0781p9219*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v0781p9292*
+ ID_PRODUCT_FROM_DATABASE=ImageMate CF Reader/Writer
+
+usb:v0781p9393*
+ ID_PRODUCT_FROM_DATABASE=ImageMate SD-MMC
+
+usb:v0781p9595*
+ ID_PRODUCT_FROM_DATABASE=ImageMate xD-SM
+
+usb:v0781p9797*
+ ID_PRODUCT_FROM_DATABASE=ImageMate MS-PRO
+
+usb:v0781p9919*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v0781p9999*
+ ID_PRODUCT_FROM_DATABASE=SDDR-99 5-in-1 Reader
+
+usb:v0781pA7C1*
+ ID_PRODUCT_FROM_DATABASE=Storage device (SD card reader)
+
+usb:v0781pA7E8*
+ ID_PRODUCT_FROM_DATABASE=SDDR-113 MicroMate SDHC Reader
+
+usb:v0781pB2B3*
+ ID_PRODUCT_FROM_DATABASE=SDDR-103 MobileMate SD+ Reader
+
+usb:v0781pB4B5*
+ ID_PRODUCT_FROM_DATABASE=SDDR-89 V4 ImageMate 12-in-1 Reader
+
+usb:v0782*
+ ID_VENDOR_FROM_DATABASE=Trackerball
+
+usb:v0783*
+ ID_VENDOR_FROM_DATABASE=C3PO
+
+usb:v0783p0003*
+ ID_PRODUCT_FROM_DATABASE=LTC31 SmartCard Reader
+
+usb:v0783p0006*
+ ID_PRODUCT_FROM_DATABASE=LTC31v2
+
+usb:v0783p0009*
+ ID_PRODUCT_FROM_DATABASE=KBR36
+
+usb:v0783p0010*
+ ID_PRODUCT_FROM_DATABASE=LTC32
+
+usb:v0784*
+ ID_VENDOR_FROM_DATABASE=Vivitar, Inc.
+
+usb:v0784p0100*
+ ID_PRODUCT_FROM_DATABASE=Vivicam 2655
+
+usb:v0784p1310*
+ ID_PRODUCT_FROM_DATABASE=Vivicam 3305
+
+usb:v0784p1688*
+ ID_PRODUCT_FROM_DATABASE=Vivicam 3665
+
+usb:v0784p1689*
+ ID_PRODUCT_FROM_DATABASE=Gateway DC-M42/Labtec DC-505/Vivitar Vivicam 3705
+
+usb:v0784p2620*
+ ID_PRODUCT_FROM_DATABASE=AOL Photocam Plus
+
+usb:v0784p2888*
+ ID_PRODUCT_FROM_DATABASE=Polaroid DC700
+
+usb:v0784p3330*
+ ID_PRODUCT_FROM_DATABASE=Nytec ND-3200 Camera
+
+usb:v0784p4300*
+ ID_PRODUCT_FROM_DATABASE=Traveler D1
+
+usb:v0784p5260*
+ ID_PRODUCT_FROM_DATABASE=Werlisa Sport PX 100 / JVC GC-A33 Camera
+
+usb:v0784p5300*
+ ID_PRODUCT_FROM_DATABASE=Pretec dc530
+
+usb:v0785*
+ ID_VENDOR_FROM_DATABASE=NTT-ME
+
+usb:v0785p0001*
+ ID_PRODUCT_FROM_DATABASE=MN128mini-V ISDN TA
+
+usb:v0785p0003*
+ ID_PRODUCT_FROM_DATABASE=MN128mini-J ISDN TA
+
+usb:v0789*
+ ID_VENDOR_FROM_DATABASE=Logitec Corp.
+
+usb:v0789p0026*
+ ID_PRODUCT_FROM_DATABASE=LHD Device
+
+usb:v0789p0033*
+ ID_PRODUCT_FROM_DATABASE=DVD Multi-plus unit LDR-H443SU2
+
+usb:v0789p0063*
+ ID_PRODUCT_FROM_DATABASE=LDR Device
+
+usb:v0789p0064*
+ ID_PRODUCT_FROM_DATABASE=LDR-R Device
+
+usb:v0789p00B3*
+ ID_PRODUCT_FROM_DATABASE=DVD Multi-plus unit LDR-H443U2
+
+usb:v0789p0105*
+ ID_PRODUCT_FROM_DATABASE=LAN-TX/U1H2 10/100 Ethernet Adapter [pegasus II]
+
+usb:v0789p010C*
+ ID_PRODUCT_FROM_DATABASE=Realtek RTL8187 Wireless 802.11g 54Mbps Network Adapter
+
+usb:v0789p0160*
+ ID_PRODUCT_FROM_DATABASE=LAN-GTJ/U2A
+
+usb:v0789p0162*
+ ID_PRODUCT_FROM_DATABASE=LAN-WN22/U2 Wireless LAN Adapter
+
+usb:v0789p0163*
+ ID_PRODUCT_FROM_DATABASE=LAN-WN12/U2 Wireless LAN Adapter
+
+usb:v0789p0164*
+ ID_PRODUCT_FROM_DATABASE=LAN-W150/U2M Wireless LAN Adapter
+
+usb:v0789p0166*
+ ID_PRODUCT_FROM_DATABASE=LAN-W300N/U2 Wireless LAN Adapter
+
+usb:v0789p0168*
+ ID_PRODUCT_FROM_DATABASE=LAN-W150N/U2 Wireless LAN Adapter
+
+usb:v0789p0170*
+ ID_PRODUCT_FROM_DATABASE=LAN-W300AN/U2 Wireless LAN Adapter
+
+usb:v078B*
+ ID_VENDOR_FROM_DATABASE=Happ Controls, Inc.
+
+usb:v078Bp0010*
+ ID_PRODUCT_FROM_DATABASE=Driving UGCI
+
+usb:v078Bp0020*
+ ID_PRODUCT_FROM_DATABASE=Flying UGCI
+
+usb:v078Bp0030*
+ ID_PRODUCT_FROM_DATABASE=Fighting UGCI
+
+usb:v078C*
+ ID_VENDOR_FROM_DATABASE=GTCO/CalComp
+
+usb:v078Cp0090*
+ ID_PRODUCT_FROM_DATABASE=Tablet Adapter
+
+usb:v078Cp0100*
+ ID_PRODUCT_FROM_DATABASE=Tablet Adapter
+
+usb:v078Cp0200*
+ ID_PRODUCT_FROM_DATABASE=Tablet Adapter
+
+usb:v078Cp0300*
+ ID_PRODUCT_FROM_DATABASE=Tablet Adapter
+
+usb:v078Cp0400*
+ ID_PRODUCT_FROM_DATABASE=Digitizer (Whiteboard)
+
+usb:v078E*
+ ID_VENDOR_FROM_DATABASE=Brincom, Inc.
+
+usb:v0790*
+ ID_VENDOR_FROM_DATABASE=Pro-Image Manufacturing Co., Ltd
+
+usb:v0791*
+ ID_VENDOR_FROM_DATABASE=Copartner Wire and Cable Mfg. Corp.
+
+usb:v0792*
+ ID_VENDOR_FROM_DATABASE=Axis Communications AB
+
+usb:v0793*
+ ID_VENDOR_FROM_DATABASE=Wha Yu Industrial Co., Ltd
+
+usb:v0794*
+ ID_VENDOR_FROM_DATABASE=ABL Electronics Corp.
+
+usb:v0795*
+ ID_VENDOR_FROM_DATABASE=RealChip, Inc.
+
+usb:v0796*
+ ID_VENDOR_FROM_DATABASE=Certicom Corp.
+
+usb:v0797*
+ ID_VENDOR_FROM_DATABASE=Grandtech Semiconductor Corp.
+
+usb:v0797p6801*
+ ID_PRODUCT_FROM_DATABASE=Flatbed Scanner
+
+usb:v0797p6802*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v0797p8001*
+ ID_PRODUCT_FROM_DATABASE=SmartCam
+
+usb:v0797p801A*
+ ID_PRODUCT_FROM_DATABASE=Typhoon StyloCam
+
+usb:v0797p801C*
+ ID_PRODUCT_FROM_DATABASE=Meade Binoculars/Camera
+
+usb:v0797p8901*
+ ID_PRODUCT_FROM_DATABASE=ScanHex SX-35a
+
+usb:v0797p8909*
+ ID_PRODUCT_FROM_DATABASE=ScanHex SX-35b
+
+usb:v0797p8911*
+ ID_PRODUCT_FROM_DATABASE=ScanHex SX-35c
+
+usb:v0798*
+ ID_VENDOR_FROM_DATABASE=Optelec
+
+usb:v0798p0001*
+ ID_PRODUCT_FROM_DATABASE=Braille Voyager
+
+usb:v0799*
+ ID_VENDOR_FROM_DATABASE=Altera
+
+usb:v0799p7651*
+ ID_PRODUCT_FROM_DATABASE=Programming Unit
+
+usb:v079B*
+ ID_VENDOR_FROM_DATABASE=Sagem
+
+usb:v079Bp0027*
+ ID_PRODUCT_FROM_DATABASE=USB-Serial Controller
+
+usb:v079Bp002F*
+ ID_PRODUCT_FROM_DATABASE=Mobile
+
+usb:v079Bp0030*
+ ID_PRODUCT_FROM_DATABASE=Mobile Communication Device
+
+usb:v079Bp0042*
+ ID_PRODUCT_FROM_DATABASE=Mobile
+
+usb:v079Bp004A*
+ ID_PRODUCT_FROM_DATABASE=XG-760A 802.11bg
+
+usb:v079Bp004B*
+ ID_PRODUCT_FROM_DATABASE=Wi-Fi 11g adapter
+
+usb:v079Bp0056*
+ ID_PRODUCT_FROM_DATABASE=Agfa AP1100 Photo Printer
+
+usb:v079Bp005D*
+ ID_PRODUCT_FROM_DATABASE=Mobile Mass Storage
+
+usb:v079Bp0062*
+ ID_PRODUCT_FROM_DATABASE=XG-76NA 802.11bg
+
+usb:v079Bp0078*
+ ID_PRODUCT_FROM_DATABASE=Laser Pro Monochrome MFP
+
+usb:v079D*
+ ID_VENDOR_FROM_DATABASE=Alfadata Computer Corp.
+
+usb:v079Dp0201*
+ ID_PRODUCT_FROM_DATABASE=GamePort Adapter
+
+usb:v07A1*
+ ID_VENDOR_FROM_DATABASE=Digicom S.p.A.
+
+usb:v07A1pD952*
+ ID_PRODUCT_FROM_DATABASE=Palladio USB V.92 Modem
+
+usb:v07A2*
+ ID_VENDOR_FROM_DATABASE=National Technical Systems
+
+usb:v07A3*
+ ID_VENDOR_FROM_DATABASE=Onnto Corp.
+
+usb:v07A4*
+ ID_VENDOR_FROM_DATABASE=Be, Inc.
+
+usb:v07A6*
+ ID_VENDOR_FROM_DATABASE=ADMtek, Inc.
+
+usb:v07A6p07C2*
+ ID_PRODUCT_FROM_DATABASE=AN986A Ethernet
+
+usb:v07A6p0986*
+ ID_PRODUCT_FROM_DATABASE=AN986 Pegasus Ethernet
+
+usb:v07A6p8266*
+ ID_PRODUCT_FROM_DATABASE=Infineon WildCard-USB Wireless LAN Adapter
+
+usb:v07A6p8511*
+ ID_PRODUCT_FROM_DATABASE=ADM8511 Pegasus II Ethernet
+
+usb:v07A6p8513*
+ ID_PRODUCT_FROM_DATABASE=AN8513 Ethernet
+
+usb:v07A6p8515*
+ ID_PRODUCT_FROM_DATABASE=AN8515 Ethernet
+
+usb:v07AA*
+ ID_VENDOR_FROM_DATABASE=Corega K.K.
+
+usb:v07AAp0001*
+ ID_PRODUCT_FROM_DATABASE=Ether USB-T Ethernet [klsi]
+
+usb:v07AAp0004*
+ ID_PRODUCT_FROM_DATABASE=FEther USB-TX Ethernet [pegasus]
+
+usb:v07AAp000C*
+ ID_PRODUCT_FROM_DATABASE=WirelessLAN USB-11
+
+usb:v07AAp000D*
+ ID_PRODUCT_FROM_DATABASE=FEther USB-TXS
+
+usb:v07AAp0011*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN USB-11 mini
+
+usb:v07AAp0012*
+ ID_PRODUCT_FROM_DATABASE=Stick-11 802.11b Adapter
+
+usb:v07AAp0017*
+ ID_PRODUCT_FROM_DATABASE=FEther USB2-TX
+
+usb:v07AAp0018*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN USB-11 mini 2
+
+usb:v07AAp001A*
+ ID_PRODUCT_FROM_DATABASE=ULUSB-11 Key
+
+usb:v07AAp001C*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GTST 802.11g Wireless Adapter [Intersil ISL3887]
+
+usb:v07AAp002E*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GPX [Ralink RT2571W]
+
+usb:v07AAp002F*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GNL
+
+usb:v07AAp0031*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GS 802.11bg [Atheros AR5523]
+
+usb:v07AAp003C*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GNL
+
+usb:v07AAp003F*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB300AGN
+
+usb:v07AAp0041*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB300GNS
+
+usb:v07AAp0042*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB300GNM
+
+usb:v07AAp0043*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB300N rev A2 [Realtek RTL8192U]
+
+usb:v07AAp0047*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSBNM
+
+usb:v07AAp0051*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB300NM
+
+usb:v07AAp7613*
+ ID_PRODUCT_FROM_DATABASE=Stick-11 V2 802.11b Adapter
+
+usb:v07AAp9601*
+ ID_PRODUCT_FROM_DATABASE=FEther USB-TXC
+
+usb:v07AB*
+ ID_VENDOR_FROM_DATABASE=Freecom Technologies
+
+usb:v07ABpFC01*
+ ID_PRODUCT_FROM_DATABASE=IDE bridge
+
+usb:v07ABpFC02*
+ ID_PRODUCT_FROM_DATABASE=Cable II USB-2
+
+usb:v07ABpFC03*
+ ID_PRODUCT_FROM_DATABASE=USB2-IDE IDE bridge
+
+usb:v07ABpFCD6*
+ ID_PRODUCT_FROM_DATABASE=Freecom HD Classic
+
+usb:v07ABpFCF6*
+ ID_PRODUCT_FROM_DATABASE=DataBar 512 MB
+
+usb:v07ABpFCF8*
+ ID_PRODUCT_FROM_DATABASE=Freecom Classic SL Network Drive
+
+usb:v07ABpFCFE*
+ ID_PRODUCT_FROM_DATABASE=Hard Drive 80GB
+
+usb:v07AF*
+ ID_VENDOR_FROM_DATABASE=Microtech
+
+usb:v07AFp0004*
+ ID_PRODUCT_FROM_DATABASE=SCSI-DB25 SCSI Bridge [shuttle]
+
+usb:v07AFp0005*
+ ID_PRODUCT_FROM_DATABASE=SCSI-HD50 SCSI Bridge [shuttle]
+
+usb:v07AFp0006*
+ ID_PRODUCT_FROM_DATABASE=CameraMate SmartMedia and CompactFlash Card Reader [eusb/shuttle]
+
+usb:v07AFpFC01*
+ ID_PRODUCT_FROM_DATABASE=Freecom USB-IDE
+
+usb:v07B0*
+ ID_VENDOR_FROM_DATABASE=Trust Technologies
+
+usb:v07B0p0001*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA
+
+usb:v07B0p0002*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA128 Plus
+
+usb:v07B0p0003*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA128 Deluxe
+
+usb:v07B0p0005*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA128 SE
+
+usb:v07B0p0006*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA128 CE
+
+usb:v07B0p0007*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA
+
+usb:v07B0p0008*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA
+
+usb:v07B1*
+ ID_VENDOR_FROM_DATABASE=IMP, Inc.
+
+usb:v07B2*
+ ID_VENDOR_FROM_DATABASE=Motorola BCS, Inc.
+
+usb:v07B2p0100*
+ ID_PRODUCT_FROM_DATABASE=SURFboard Voice over IP Cable Modem
+
+usb:v07B2p0900*
+ ID_PRODUCT_FROM_DATABASE=SURFboard Gateway
+
+usb:v07B2p0950*
+ ID_PRODUCT_FROM_DATABASE=SURFboard SBG950 Gateway
+
+usb:v07B2p1000*
+ ID_PRODUCT_FROM_DATABASE=SURFboard SBG1000 Gateway
+
+usb:v07B2p4100*
+ ID_PRODUCT_FROM_DATABASE=SurfBoard SB4100 Cable Modem
+
+usb:v07B2p4200*
+ ID_PRODUCT_FROM_DATABASE=SurfBoard SB4200 Cable Modem
+
+usb:v07B2p4210*
+ ID_PRODUCT_FROM_DATABASE=SurfBoard 4210 Cable Modem
+
+usb:v07B2p4220*
+ ID_PRODUCT_FROM_DATABASE=SURFboard SB4220 Cable Modem
+
+usb:v07B2p4500*
+ ID_PRODUCT_FROM_DATABASE=CG4500 Communications Gateway
+
+usb:v07B2p450B*
+ ID_PRODUCT_FROM_DATABASE=CG4501 Communications Gateway
+
+usb:v07B2p450E*
+ ID_PRODUCT_FROM_DATABASE=CG4500E Communications Gateway
+
+usb:v07B2p5100*
+ ID_PRODUCT_FROM_DATABASE=SurfBoard SB5100 Cable Modem
+
+usb:v07B2p5101*
+ ID_PRODUCT_FROM_DATABASE=SurfBoard SB5101 Cable Modem
+
+usb:v07B2p5120*
+ ID_PRODUCT_FROM_DATABASE=SurfBoard SB5120 Cable Modem (RNDIS)
+
+usb:v07B2p5121*
+ ID_PRODUCT_FROM_DATABASE=Surfboard 5121 Cable Modem
+
+usb:v07B2p7030*
+ ID_PRODUCT_FROM_DATABASE=WU830G 802.11bg Wireless Adapter [Envara WiND512]
+
+usb:v07B3*
+ ID_VENDOR_FROM_DATABASE=Plustek, Inc.
+
+usb:v07B3p0001*
+ ID_PRODUCT_FROM_DATABASE=OpticPro 1212U Scanner
+
+usb:v07B3p0003*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v07B3p0010*
+ ID_PRODUCT_FROM_DATABASE=OpticPro U12 Scanner
+
+usb:v07B3p0011*
+ ID_PRODUCT_FROM_DATABASE=OpticPro U24 Scanner
+
+usb:v07B3p0013*
+ ID_PRODUCT_FROM_DATABASE=OpticPro UT12 Scanner
+
+usb:v07B3p0014*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v07B3p0015*
+ ID_PRODUCT_FROM_DATABASE=OpticPro U24 Scanner
+
+usb:v07B3p0017*
+ ID_PRODUCT_FROM_DATABASE=OpticPro UT12/16/24 Scanner
+
+usb:v07B3p0204*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v07B3p0400*
+ ID_PRODUCT_FROM_DATABASE=OpticPro 1248U Scanner
+
+usb:v07B3p0401*
+ ID_PRODUCT_FROM_DATABASE=OpticPro 1248U Scanner #2
+
+usb:v07B3p0403*
+ ID_PRODUCT_FROM_DATABASE=OpticPro U16B Scanner
+
+usb:v07B3p0404*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v07B3p0405*
+ ID_PRODUCT_FROM_DATABASE=A8 Namecard-s Controller
+
+usb:v07B3p0406*
+ ID_PRODUCT_FROM_DATABASE=A8 Namecard-D Controller
+
+usb:v07B3p0410*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v07B3p0412*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v07B3p0413*
+ ID_PRODUCT_FROM_DATABASE=OpticSlim 1200 Scanner
+
+usb:v07B3p0601*
+ ID_PRODUCT_FROM_DATABASE=OpticPro ST24 Scanner
+
+usb:v07B3p0800*
+ ID_PRODUCT_FROM_DATABASE=OpticPro ST48 Scanner
+
+usb:v07B3p0906*
+ ID_PRODUCT_FROM_DATABASE=OpticBook 3600 Scanner
+
+usb:v07B3p0A06*
+ ID_PRODUCT_FROM_DATABASE=TVcam VD100
+
+usb:v07B3p0B00*
+ ID_PRODUCT_FROM_DATABASE=SmartPhoto F50
+
+usb:v07B3p0C03*
+ ID_PRODUCT_FROM_DATABASE=OpticPro ST64+ Scanner
+
+usb:v07B3p0C04*
+ ID_PRODUCT_FROM_DATABASE=Optic Film 7200i scanner
+
+usb:v07B3p0C0C*
+ ID_PRODUCT_FROM_DATABASE=PL806 Scanner
+
+usb:v07B3p0C26*
+ ID_PRODUCT_FROM_DATABASE=OpticBook 4600 Scanner
+
+usb:v07B3p0C2B*
+ ID_PRODUCT_FROM_DATABASE=Mobile Office D428 Scanner
+
+usb:v07B4*
+ ID_VENDOR_FROM_DATABASE=Olympus Optical Co., Ltd
+
+usb:v07B4p0100*
+ ID_PRODUCT_FROM_DATABASE=Camedia C-2100/C-3000 Ultra Zoom Camera
+
+usb:v07B4p0102*
+ ID_PRODUCT_FROM_DATABASE=Camedia E-10/C-220/C-50 Camera
+
+usb:v07B4p0105*
+ ID_PRODUCT_FROM_DATABASE=Camedia C-310Z/C-700/C-750UZ/C-755/C-765UZ/C-3040/C-4000/C-5050Z/D-560/C-3020Z Zoom Camera
+
+usb:v07B4p0109*
+ ID_PRODUCT_FROM_DATABASE=C-370Z/C-500Z/D-535Z/X-450
+
+usb:v07B4p010A*
+ ID_PRODUCT_FROM_DATABASE=MAUSB-10 xD and SmartMedia Card Reader
+
+usb:v07B4p0112*
+ ID_PRODUCT_FROM_DATABASE=MAUSB-100 xD Card Reader
+
+usb:v07B4p0113*
+ ID_PRODUCT_FROM_DATABASE=Mju 500
+
+usb:v07B4p0114*
+ ID_PRODUCT_FROM_DATABASE=C-350Z Camera
+
+usb:v07B4p0118*
+ ID_PRODUCT_FROM_DATABASE=Mju Mini Digital/Mju Digital 500 Camera / Stylus 850 SW
+
+usb:v07B4p0184*
+ ID_PRODUCT_FROM_DATABASE=P-S100 port
+
+usb:v07B4p0203*
+ ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder DW-90
+
+usb:v07B4p0206*
+ ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder DS-330
+
+usb:v07B4p0207*
+ ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder & Camera W-10
+
+usb:v07B4p0209*
+ ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder DM-20
+
+usb:v07B4p020D*
+ ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder VN-240PC
+
+usb:v07B4p0244*
+ ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder VN-8500PC
+
+usb:v07B4p0280*
+ ID_PRODUCT_FROM_DATABASE=m:robe 100
+
+usb:v07B5*
+ ID_VENDOR_FROM_DATABASE=Mega World International, Ltd
+
+usb:v07B5p0017*
+ ID_PRODUCT_FROM_DATABASE=Joystick
+
+usb:v07B5p0213*
+ ID_PRODUCT_FROM_DATABASE=Thrustmaster Firestorm Digital 3 Gamepad
+
+usb:v07B5p0312*
+ ID_PRODUCT_FROM_DATABASE=Gamepad
+
+usb:v07B5p9902*
+ ID_PRODUCT_FROM_DATABASE=GamePad
+
+usb:v07B6*
+ ID_VENDOR_FROM_DATABASE=Marubun Corp.
+
+usb:v07B7*
+ ID_VENDOR_FROM_DATABASE=TIME Interconnect, Ltd
+
+usb:v07B8*
+ ID_VENDOR_FROM_DATABASE=AboCom Systems Inc
+
+usb:v07B8p110C*
+ ID_PRODUCT_FROM_DATABASE=XX1
+
+usb:v07B8p1201*
+ ID_PRODUCT_FROM_DATABASE=IEEE 802.11b Adapter
+
+usb:v07B8p200C*
+ ID_PRODUCT_FROM_DATABASE=XX2
+
+usb:v07B8p2573*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN Card
+
+usb:v07B8p2770*
+ ID_PRODUCT_FROM_DATABASE=802.11n/b/g Mini Wireless LAN USB2.0 Adapter
+
+usb:v07B8p2870*
+ ID_PRODUCT_FROM_DATABASE=802.11n/b/g Wireless LAN USB2.0 Adapter
+
+usb:v07B8p3070*
+ ID_PRODUCT_FROM_DATABASE=802.11n/b/g Mini Wireless LAN USB2.0 Adapter
+
+usb:v07B8p3071*
+ ID_PRODUCT_FROM_DATABASE=802.11n/b/g Mini Wireless LAN USB2.0 Adapter
+
+usb:v07B8p3072*
+ ID_PRODUCT_FROM_DATABASE=802.11n/b/g Mini Wireless LAN USB2.0 Adapter
+
+usb:v07B8p4000*
+ ID_PRODUCT_FROM_DATABASE=DU-E10 Ethernet [klsi]
+
+usb:v07B8p4002*
+ ID_PRODUCT_FROM_DATABASE=DU-E100 Ethernet [pegasus]
+
+usb:v07B8p4003*
+ ID_PRODUCT_FROM_DATABASE=1/10/100 Ethernet Adapter
+
+usb:v07B8p4004*
+ ID_PRODUCT_FROM_DATABASE=XX4
+
+usb:v07B8p4007*
+ ID_PRODUCT_FROM_DATABASE=XX5
+
+usb:v07B8p400B*
+ ID_PRODUCT_FROM_DATABASE=XX6
+
+usb:v07B8p400C*
+ ID_PRODUCT_FROM_DATABASE=XX7
+
+usb:v07B8p401A*
+ ID_PRODUCT_FROM_DATABASE=RTL8151
+
+usb:v07B8p4102*
+ ID_PRODUCT_FROM_DATABASE=USB 1.1 10/100M Fast Ethernet Adapter
+
+usb:v07B8p4104*
+ ID_PRODUCT_FROM_DATABASE=XX9
+
+usb:v07B8p420A*
+ ID_PRODUCT_FROM_DATABASE=UF200 Ethernet
+
+usb:v07B8p5301*
+ ID_PRODUCT_FROM_DATABASE=GW-US54ZGL 802.11bg
+
+usb:v07B8p6001*
+ ID_PRODUCT_FROM_DATABASE=802.11bg
+
+usb:v07B8pA001*
+ ID_PRODUCT_FROM_DATABASE=WUG2200 802.11g Wireless Adapter [Envara WiND512]
+
+usb:v07B8pABC1*
+ ID_PRODUCT_FROM_DATABASE=DU-E10 Ethernet [pegasus]
+
+usb:v07B8pB000*
+ ID_PRODUCT_FROM_DATABASE=BWU613
+
+usb:v07B8pB02A*
+ ID_PRODUCT_FROM_DATABASE=AboCom Bluetooth Device
+
+usb:v07B8pB02B*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth dongle
+
+usb:v07B8pB02C*
+ ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter
+
+usb:v07B8pB02D*
+ ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter
+
+usb:v07B8pB02E*
+ ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter
+
+usb:v07B8pB030*
+ ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter
+
+usb:v07B8pB031*
+ ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter
+
+usb:v07B8pB032*
+ ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter
+
+usb:v07B8pB033*
+ ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter
+
+usb:v07B8pB21A*
+ ID_PRODUCT_FROM_DATABASE=WUG2400 802.11g Wireless Adapter [Texas Instruments TNETW1450]
+
+usb:v07B8pB21B*
+ ID_PRODUCT_FROM_DATABASE=HWU54DM
+
+usb:v07B8pB21C*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v07B8pB21D*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v07B8pB21E*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v07B8pB21F*
+ ID_PRODUCT_FROM_DATABASE=WUG2700
+
+usb:v07B8pD011*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v07B8pE001*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE002*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE003*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE004*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE005*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE006*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE007*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE008*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE009*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE00A*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07B8pE4F0*
+ ID_PRODUCT_FROM_DATABASE=Card Reader Driver
+
+usb:v07B8pF101*
+ ID_PRODUCT_FROM_DATABASE=DSB-560 Modem [atlas]
+
+usb:v07BC*
+ ID_VENDOR_FROM_DATABASE=Canon Computer Systems, Inc.
+
+usb:v07BD*
+ ID_VENDOR_FROM_DATABASE=Webgear, Inc.
+
+usb:v07BE*
+ ID_VENDOR_FROM_DATABASE=Veridicom
+
+usb:v07C0*
+ ID_VENDOR_FROM_DATABASE=Code Mercenaries Hard- und Software GmbH
+
+usb:v07C0p1113*
+ ID_PRODUCT_FROM_DATABASE=JoyWarrior24F8
+
+usb:v07C0p1116*
+ ID_PRODUCT_FROM_DATABASE=JoyWarrior24F14
+
+usb:v07C0p1121*
+ ID_PRODUCT_FROM_DATABASE=The Claw
+
+usb:v07C0p1500*
+ ID_PRODUCT_FROM_DATABASE=IO-Warrior 40
+
+usb:v07C0p1501*
+ ID_PRODUCT_FROM_DATABASE=IO-Warrior 24
+
+usb:v07C0p1502*
+ ID_PRODUCT_FROM_DATABASE=IO-Warrior 48
+
+usb:v07C0p1503*
+ ID_PRODUCT_FROM_DATABASE=IO-Warrior 28
+
+usb:v07C0p1511*
+ ID_PRODUCT_FROM_DATABASE=IO-Warrior 24 Power Vampire
+
+usb:v07C0p1512*
+ ID_PRODUCT_FROM_DATABASE=IO-Warrior 24 Power Vampire
+
+usb:v07C1*
+ ID_VENDOR_FROM_DATABASE=Keisokugiken
+
+usb:v07C1p0068*
+ ID_PRODUCT_FROM_DATABASE=HKS-0200 USBDAQ
+
+usb:v07C4*
+ ID_VENDOR_FROM_DATABASE=Datafab Systems, Inc.
+
+usb:v07C4p0102*
+ ID_PRODUCT_FROM_DATABASE=USB to LS120
+
+usb:v07C4p0103*
+ ID_PRODUCT_FROM_DATABASE=USB to IDE
+
+usb:v07C4p1234*
+ ID_PRODUCT_FROM_DATABASE=USB to ATAPI
+
+usb:v07C4pA000*
+ ID_PRODUCT_FROM_DATABASE=CompactFlash Card Reader
+
+usb:v07C4pA001*
+ ID_PRODUCT_FROM_DATABASE=CompactFlash & SmartMedia Card Reader [eusb]
+
+usb:v07C4pA002*
+ ID_PRODUCT_FROM_DATABASE=Disk Drive
+
+usb:v07C4pA003*
+ ID_PRODUCT_FROM_DATABASE=Datafab-based Reader
+
+usb:v07C4pA004*
+ ID_PRODUCT_FROM_DATABASE=USB to MMC Class Drive
+
+usb:v07C4pA005*
+ ID_PRODUCT_FROM_DATABASE=CompactFlash & SmartMedia Card Reader
+
+usb:v07C4pA006*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia Card Reader
+
+usb:v07C4pA007*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Class Drive
+
+usb:v07C4pA103*
+ ID_PRODUCT_FROM_DATABASE=MDSM-B reader
+
+usb:v07C4pA107*
+ ID_PRODUCT_FROM_DATABASE=USB to Memory Stick (LC1) Drive
+
+usb:v07C4pA109*
+ ID_PRODUCT_FROM_DATABASE=LC1 CompactFlash & SmartMedia Card Reader
+
+usb:v07C4pA10B*
+ ID_PRODUCT_FROM_DATABASE=USB to CF+MS(LC1)
+
+usb:v07C4pA200*
+ ID_PRODUCT_FROM_DATABASE=DF-UT-06 Hama MMC/SD Reader
+
+usb:v07C4pA400*
+ ID_PRODUCT_FROM_DATABASE=CompactFlash & Microdrive Reader
+
+usb:v07C4pA600*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v07C4pAD01*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07C4pAE01*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07C4pAF01*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v07C4pB000*
+ ID_PRODUCT_FROM_DATABASE=USB to CF(LC1)
+
+usb:v07C4pB001*
+ ID_PRODUCT_FROM_DATABASE=USB to CF+PCMCIA
+
+usb:v07C4pB004*
+ ID_PRODUCT_FROM_DATABASE=MMC/SD Reader
+
+usb:v07C4pB006*
+ ID_PRODUCT_FROM_DATABASE=USB to PCMCIA
+
+usb:v07C4pB00A*
+ ID_PRODUCT_FROM_DATABASE=USB to CF+SD Drive(LC1)
+
+usb:v07C4pB00B*
+ ID_PRODUCT_FROM_DATABASE=USB to Memory Stick(LC1)
+
+usb:v07C5*
+ ID_VENDOR_FROM_DATABASE=APG Cash Drawer
+
+usb:v07C6*
+ ID_VENDOR_FROM_DATABASE=ShareWave, Inc.
+
+usb:v07C6p0002*
+ ID_PRODUCT_FROM_DATABASE=Bodega Wireless Access Point
+
+usb:v07C6p0003*
+ ID_PRODUCT_FROM_DATABASE=Bodega Wireless Network Adapter
+
+usb:v07C7*
+ ID_VENDOR_FROM_DATABASE=Powertech Industrial Co., Ltd
+
+usb:v07C8*
+ ID_VENDOR_FROM_DATABASE=B.U.G., Inc.
+
+usb:v07C8p0202*
+ ID_PRODUCT_FROM_DATABASE=MN128-SOHO PAL
+
+usb:v07C9*
+ ID_VENDOR_FROM_DATABASE=Allied Telesyn International
+
+usb:v07C9pB100*
+ ID_PRODUCT_FROM_DATABASE=AT-USB100
+
+usb:v07CA*
+ ID_VENDOR_FROM_DATABASE=AVerMedia Technologies, Inc.
+
+usb:v07CAp0002*
+ ID_PRODUCT_FROM_DATABASE=AVerTV PVR USB/EZMaker Pro Device
+
+usb:v07CAp0026*
+ ID_PRODUCT_FROM_DATABASE=AVerTV
+
+usb:v07CAp0337*
+ ID_PRODUCT_FROM_DATABASE=A867 DVB-T dongle
+
+usb:v07CAp0837*
+ ID_PRODUCT_FROM_DATABASE=H837 Hybrid ATSC/QAM
+
+usb:v07CAp1228*
+ ID_PRODUCT_FROM_DATABASE=MPEG-2 Capture Device (M038)
+
+usb:v07CAp1830*
+ ID_PRODUCT_FROM_DATABASE=AVerTV Volar Video Capture (H830)
+
+usb:v07CAp3835*
+ ID_PRODUCT_FROM_DATABASE=AVerTV Volar Green HD (A835B)
+
+usb:v07CAp850A*
+ ID_PRODUCT_FROM_DATABASE=AverTV Volar Black HD (A850)
+
+usb:v07CAp850B*
+ ID_PRODUCT_FROM_DATABASE=AverTV Red HD+ (A850T)
+
+usb:v07CApA309*
+ ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T (A309)
+
+usb:v07CApA801*
+ ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T (A800)
+
+usb:v07CApA815*
+ ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T Volar X (A815)
+
+usb:v07CApA867*
+ ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T (A867)
+
+usb:v07CApB800*
+ ID_PRODUCT_FROM_DATABASE=MR800 FM Radio
+
+usb:v07CApE880*
+ ID_PRODUCT_FROM_DATABASE=MPEG-2 Capture Device (E880)
+
+usb:v07CApE882*
+ ID_PRODUCT_FROM_DATABASE=MPEG-2 Capture Device (E882)
+
+usb:v07CB*
+ ID_VENDOR_FROM_DATABASE=Kingmax Technology, Inc.
+
+usb:v07CC*
+ ID_VENDOR_FROM_DATABASE=Carry Computer Eng., Co., Ltd
+
+usb:v07CCp0000*
+ ID_PRODUCT_FROM_DATABASE=CF Card Reader
+
+usb:v07CCp0001*
+ ID_PRODUCT_FROM_DATABASE=Reader (UICSE)
+
+usb:v07CCp0002*
+ ID_PRODUCT_FROM_DATABASE=Reader (UIS)
+
+usb:v07CCp0003*
+ ID_PRODUCT_FROM_DATABASE=SM Card Reader
+
+usb:v07CCp0004*
+ ID_PRODUCT_FROM_DATABASE=SM/CF/PCMCIA Card Reader
+
+usb:v07CCp0005*
+ ID_PRODUCT_FROM_DATABASE=Reader (UISA2SE)
+
+usb:v07CCp0006*
+ ID_PRODUCT_FROM_DATABASE=SM/CF/PCMCIA Card Reader
+
+usb:v07CCp0007*
+ ID_PRODUCT_FROM_DATABASE=Reader (UISA6SE)
+
+usb:v07CCp000C*
+ ID_PRODUCT_FROM_DATABASE=SM/CF Card Reader
+
+usb:v07CCp000D*
+ ID_PRODUCT_FROM_DATABASE=SM/CF Card Reader
+
+usb:v07CCp000E*
+ ID_PRODUCT_FROM_DATABASE=Reader (UISDA)
+
+usb:v07CCp000F*
+ ID_PRODUCT_FROM_DATABASE=Reader (UICLIK)
+
+usb:v07CCp0010*
+ ID_PRODUCT_FROM_DATABASE=Reader (UISMA)
+
+usb:v07CCp0012*
+ ID_PRODUCT_FROM_DATABASE=Reader (UISC6SE-FLASH)
+
+usb:v07CCp0014*
+ ID_PRODUCT_FROM_DATABASE=Litronic Fortezza Reader
+
+usb:v07CCp0030*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC12S)
+
+usb:v07CCp0040*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC13S)
+
+usb:v07CCp0100*
+ ID_PRODUCT_FROM_DATABASE=Reader (UID)
+
+usb:v07CCp0101*
+ ID_PRODUCT_FROM_DATABASE=Reader (UIM)
+
+usb:v07CCp0102*
+ ID_PRODUCT_FROM_DATABASE=Reader (UISDMA)
+
+usb:v07CCp0103*
+ ID_PRODUCT_FROM_DATABASE=Reader (UISDMC)
+
+usb:v07CCp0104*
+ ID_PRODUCT_FROM_DATABASE=Reader (UISDM)
+
+usb:v07CCp0200*
+ ID_PRODUCT_FROM_DATABASE=6-in-1 Card Reader
+
+usb:v07CCp0201*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC1S & UISDMC3S)
+
+usb:v07CCp0202*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC5S)
+
+usb:v07CCp0203*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISMC5S)
+
+usb:v07CCp0204*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UIM4/5S & UIM7S)
+
+usb:v07CCp0205*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UIS4/5S & UIS7S)
+
+usb:v07CCp0206*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC10S & UISDMC11S)
+
+usb:v07CCp0207*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UPIDMA)
+
+usb:v07CCp0208*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UCFC II)
+
+usb:v07CCp0210*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UPIXXA)
+
+usb:v07CCp0213*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UPIDA)
+
+usb:v07CCp0214*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UPIMA)
+
+usb:v07CCp0215*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UPISA)
+
+usb:v07CCp0217*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UPISDMA)
+
+usb:v07CCp0223*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UCIDA)
+
+usb:v07CCp0224*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UCIMA)
+
+usb:v07CCp0225*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UIS7S)
+
+usb:v07CCp0227*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UCIDMA)
+
+usb:v07CCp0234*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UIM7S)
+
+usb:v07CCp0235*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UIS4S-S)
+
+usb:v07CCp0237*
+ ID_PRODUCT_FROM_DATABASE=Velper (UISDMC4S)
+
+usb:v07CCp0300*
+ ID_PRODUCT_FROM_DATABASE=6-in-1 Card Reader
+
+usb:v07CCp0301*
+ ID_PRODUCT_FROM_DATABASE=6-in-1 Card Reader
+
+usb:v07CCp0303*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UID10W)
+
+usb:v07CCp0304*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UIM10W)
+
+usb:v07CCp0305*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UIS10W)
+
+usb:v07CCp0308*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UIC10W)
+
+usb:v07CCp0309*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISC3W)
+
+usb:v07CCp0310*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMA2W)
+
+usb:v07CCp0311*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC14W)
+
+usb:v07CCp0320*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC4W)
+
+usb:v07CCp0321*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC37W)
+
+usb:v07CCp0330*
+ ID_PRODUCT_FROM_DATABASE=WINTERREADER Reader
+
+usb:v07CCp0350*
+ ID_PRODUCT_FROM_DATABASE=9-in-1 Card Reader
+
+usb:v07CCp0500*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage
+
+usb:v07CCp0501*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage
+
+usb:v07CD*
+ ID_VENDOR_FROM_DATABASE=Elektor
+
+usb:v07CDp0001*
+ ID_PRODUCT_FROM_DATABASE=USBuart Serial Port
+
+usb:v07CF*
+ ID_VENDOR_FROM_DATABASE=Casio Computer Co., Ltd
+
+usb:v07CFp1001*
+ ID_PRODUCT_FROM_DATABASE=QV-8000SX/5700/3000EX Digicam; Exilim EX-M20
+
+usb:v07CFp1003*
+ ID_PRODUCT_FROM_DATABASE=Exilim EX-S500
+
+usb:v07CFp1004*
+ ID_PRODUCT_FROM_DATABASE=Exilim EX-Z120
+
+usb:v07CFp1011*
+ ID_PRODUCT_FROM_DATABASE=USB-CASIO PC CAMERA
+
+usb:v07CFp1116*
+ ID_PRODUCT_FROM_DATABASE=EXILIM EX-Z19
+
+usb:v07CFp1125*
+ ID_PRODUCT_FROM_DATABASE=Exilim EX-H10 Digital Camera (mass storage mode)
+
+usb:v07CFp1133*
+ ID_PRODUCT_FROM_DATABASE=Exilim EX-Z350 Digital Camera (mass storage mode)
+
+usb:v07CFp1225*
+ ID_PRODUCT_FROM_DATABASE=Exilim EX-H10 Digital Camera (PictBridge mode)
+
+usb:v07CFp1233*
+ ID_PRODUCT_FROM_DATABASE=Exilim EX-Z350 Digital Camera (PictBridge mode)
+
+usb:v07CFp2002*
+ ID_PRODUCT_FROM_DATABASE=E-125 Cassiopeia Pocket PC
+
+usb:v07CFp3801*
+ ID_PRODUCT_FROM_DATABASE=WMP-1 MP3-Watch
+
+usb:v07CFp4001*
+ ID_PRODUCT_FROM_DATABASE=Label Printer KL-P1000
+
+usb:v07CFp4007*
+ ID_PRODUCT_FROM_DATABASE=CW50 Device
+
+usb:v07CFp4104*
+ ID_PRODUCT_FROM_DATABASE=Cw75 Device
+
+usb:v07CFp4107*
+ ID_PRODUCT_FROM_DATABASE=CW-L300 Device
+
+usb:v07CFp4500*
+ ID_PRODUCT_FROM_DATABASE=LV-20 Digital Camera
+
+usb:v07CFp6801*
+ ID_PRODUCT_FROM_DATABASE=PL-40R
+
+usb:v07CFp6802*
+ ID_PRODUCT_FROM_DATABASE=MIDI Keyboard
+
+usb:v07D0*
+ ID_VENDOR_FROM_DATABASE=Dazzle
+
+usb:v07D0p0001*
+ ID_PRODUCT_FROM_DATABASE=Digital Video Creator I
+
+usb:v07D0p0002*
+ ID_PRODUCT_FROM_DATABASE=Global Village VideoFX Grabber
+
+usb:v07D0p0003*
+ ID_PRODUCT_FROM_DATABASE=Fusion Model DVC-50 Rev 1 (NTSC)
+
+usb:v07D0p0004*
+ ID_PRODUCT_FROM_DATABASE=DVC-800 (PAL) Grabber
+
+usb:v07D0p0005*
+ ID_PRODUCT_FROM_DATABASE=Fusion Video and Audio Ports
+
+usb:v07D0p0006*
+ ID_PRODUCT_FROM_DATABASE=DVC 150 Loader Device
+
+usb:v07D0p0007*
+ ID_PRODUCT_FROM_DATABASE=DVC 150
+
+usb:v07D0p0327*
+ ID_PRODUCT_FROM_DATABASE=Fusion Digital Media Reader
+
+usb:v07D0p1001*
+ ID_PRODUCT_FROM_DATABASE=DM-FLEX DFU Adapter
+
+usb:v07D0p1002*
+ ID_PRODUCT_FROM_DATABASE=DMHS2 DFU Adapter
+
+usb:v07D0p1102*
+ ID_PRODUCT_FROM_DATABASE=CF Reader/Writer
+
+usb:v07D0p1103*
+ ID_PRODUCT_FROM_DATABASE=SD Reader/Writer
+
+usb:v07D0p1104*
+ ID_PRODUCT_FROM_DATABASE=SM Reader/Writer
+
+usb:v07D0p1105*
+ ID_PRODUCT_FROM_DATABASE=MS Reader/Writer
+
+usb:v07D0p1106*
+ ID_PRODUCT_FROM_DATABASE=xD/SM Reader/Writer
+
+usb:v07D0p1202*
+ ID_PRODUCT_FROM_DATABASE=MultiSlot Reader/Writer
+
+usb:v07D0p2000*
+ ID_PRODUCT_FROM_DATABASE=FX2 DFU Adapter
+
+usb:v07D0p2001*
+ ID_PRODUCT_FROM_DATABASE=eUSB CompactFlash Reader
+
+usb:v07D0p4100*
+ ID_PRODUCT_FROM_DATABASE=Kingsun SF-620 Infrared Adapter
+
+usb:v07D0p4101*
+ ID_PRODUCT_FROM_DATABASE=Connectivity Cable (CA-42 clone)
+
+usb:v07D0p4959*
+ ID_PRODUCT_FROM_DATABASE=Kingsun KS-959 Infrared Adapter
+
+usb:v07D1*
+ ID_VENDOR_FROM_DATABASE=D-Link System
+
+usb:v07D1p13EC*
+ ID_PRODUCT_FROM_DATABASE=VvBus for Helium 2xx
+
+usb:v07D1p13ED*
+ ID_PRODUCT_FROM_DATABASE=VvBus for Helium 2xx
+
+usb:v07D1p13F1*
+ ID_PRODUCT_FROM_DATABASE=DSL-302G Modem
+
+usb:v07D1p13F2*
+ ID_PRODUCT_FROM_DATABASE=DSL-502G Router
+
+usb:v07D1p3300*
+ ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.E) [Realtek RTL8191SU]
+
+usb:v07D1p3302*
+ ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.C2) [Realtek RTL8191SU]
+
+usb:v07D1p3303*
+ ID_PRODUCT_FROM_DATABASE=DWA-131 802.11n Wireless N Nano Adapter(rev.A1) [Realtek RTL8192SU]
+
+usb:v07D1p3304*
+ ID_PRODUCT_FROM_DATABASE=FR-300USB 802.11bgn Wireless Adapter
+
+usb:v07D1p3A07*
+ ID_PRODUCT_FROM_DATABASE=WUA-2340 RangeBooster G Adapter(rev.A) [Atheros AR5523]
+
+usb:v07D1p3A08*
+ ID_PRODUCT_FROM_DATABASE=WUA-2340 RangeBooster G Adapter(rev.A) (no firmware) [Atheros AR5523]
+
+usb:v07D1p3A09*
+ ID_PRODUCT_FROM_DATABASE=DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.A2) [Atheros AR9170+AR9104]
+
+usb:v07D1p3A0D*
+ ID_PRODUCT_FROM_DATABASE=DWA-120 802.11g Wireless 108G Adapter [Atheros AR5523]
+
+usb:v07D1p3A0F*
+ ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.D) [Atheros AR9170+AR9102]
+
+usb:v07D1p3A10*
+ ID_PRODUCT_FROM_DATABASE=DWA-126 802.11n Wireless Adapter [Atheros AR9271]
+
+usb:v07D1p3B01*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.D) [Marvell 88W8338+88W8010]
+
+usb:v07D1p3B10*
+ ID_PRODUCT_FROM_DATABASE=DWA-142 RangeBooster N Adapter [Marvell 88W8362+88W8060]
+
+usb:v07D1p3B11*
+ ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.A1) [Marvell 88W8362+88W8060]
+
+usb:v07D1p3C03*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.C1) [Ralink RT2571W]
+
+usb:v07D1p3C04*
+ ID_PRODUCT_FROM_DATABASE=WUA-1340
+
+usb:v07D1p3C05*
+ ID_PRODUCT_FROM_DATABASE=EH103 Wireless G Adapter
+
+usb:v07D1p3C06*
+ ID_PRODUCT_FROM_DATABASE=DWA-111 802.11bg Wireless Adapter [Ralink RT2571W]
+
+usb:v07D1p3C07*
+ ID_PRODUCT_FROM_DATABASE=DWA-110 Wireless G Adapter(rev.A1) [Ralink RT2571W]
+
+usb:v07D1p3C09*
+ ID_PRODUCT_FROM_DATABASE=DWA-140 RangeBooster N Adapter(rev.B1) [Ralink RT2870]
+
+usb:v07D1p3C0A*
+ ID_PRODUCT_FROM_DATABASE=DWA-140 RangeBooster N Adapter(rev.B2) [Ralink RT3072]
+
+usb:v07D1p3C0B*
+ ID_PRODUCT_FROM_DATABASE=DWA-110 Wireless G Adapter(rev.B) [Ralink RT2870]
+
+usb:v07D1p3C0D*
+ ID_PRODUCT_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.A1) [Ralink RT3070]
+
+usb:v07D1p3C0E*
+ ID_PRODUCT_FROM_DATABASE=WUA-2340 RangeBooster G Adapter(rev.B) [Ralink RT2070]
+
+usb:v07D1p3C0F*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.E1) [Ralink RT2070]
+
+usb:v07D1p3C10*
+ ID_PRODUCT_FROM_DATABASE=DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.A1) [Atheros AR9170+AR9104]
+
+usb:v07D1p3C11*
+ ID_PRODUCT_FROM_DATABASE=DWA-160 Xtreme N Dual Band USB Adapter(rev.B) [Ralink RT2870]
+
+usb:v07D1p3C13*
+ ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.B) [Ralink RT2870]
+
+usb:v07D1p3C15*
+ ID_PRODUCT_FROM_DATABASE=DWA-140 RangeBooster N Adapter(rev.B3) [Ralink RT2870]
+
+usb:v07D1p3C16*
+ ID_PRODUCT_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.A2) [Ralink RT3070]
+
+usb:v07D1p3E02*
+ ID_PRODUCT_FROM_DATABASE=DWM-156 3.75G HSUPA Adapter
+
+usb:v07D1p5100*
+ ID_PRODUCT_FROM_DATABASE=Remote NDIS Device
+
+usb:v07D1pA800*
+ ID_PRODUCT_FROM_DATABASE=DWM-152 3.75G HSUPA Adapter
+
+usb:v07D1pF101*
+ ID_PRODUCT_FROM_DATABASE=DBT-122 Bluetooth
+
+usb:v07D1pFC01*
+ ID_PRODUCT_FROM_DATABASE=DBT-120 Bluetooth Adapter
+
+usb:v07D2*
+ ID_VENDOR_FROM_DATABASE=Aptio Products, Inc.
+
+usb:v07D3*
+ ID_VENDOR_FROM_DATABASE=Cyberdata Corp.
+
+usb:v07D5*
+ ID_VENDOR_FROM_DATABASE=Radiant Systems
+
+usb:v07D7*
+ ID_VENDOR_FROM_DATABASE=GCC Technologies, Inc.
+
+usb:v07DA*
+ ID_VENDOR_FROM_DATABASE=Arasan Chip Systems
+
+usb:v07DE*
+ ID_VENDOR_FROM_DATABASE=Diamond Multimedia
+
+usb:v07DEp2820*
+ ID_PRODUCT_FROM_DATABASE=VC500 Video Capture Dongle
+
+usb:v07DF*
+ ID_VENDOR_FROM_DATABASE=David Electronics Co., Ltd
+
+usb:v07E1*
+ ID_VENDOR_FROM_DATABASE=Ambient Technologies, Inc.
+
+usb:v07E1p5201*
+ ID_PRODUCT_FROM_DATABASE=V.90 Modem
+
+usb:v07E2*
+ ID_VENDOR_FROM_DATABASE=Elmeg GmbH & Co., Ltd
+
+usb:v07E3*
+ ID_VENDOR_FROM_DATABASE=Planex Communications, Inc.
+
+usb:v07E4*
+ ID_VENDOR_FROM_DATABASE=Movado Enterprise Co., Ltd
+
+usb:v07E4p0967*
+ ID_PRODUCT_FROM_DATABASE=SCard R/W CSR-145
+
+usb:v07E4p0968*
+ ID_PRODUCT_FROM_DATABASE=SCard R/W CSR-145
+
+usb:v07E5*
+ ID_VENDOR_FROM_DATABASE=QPS, Inc.
+
+usb:v07E5p05C2*
+ ID_PRODUCT_FROM_DATABASE=IDE-to-USB2.0 PCA
+
+usb:v07E5p5C01*
+ ID_PRODUCT_FROM_DATABASE=Que! CDRW
+
+usb:v07E6*
+ ID_VENDOR_FROM_DATABASE=Allied Cable Corp.
+
+usb:v07E7*
+ ID_VENDOR_FROM_DATABASE=Mirvo Toys, Inc.
+
+usb:v07E8*
+ ID_VENDOR_FROM_DATABASE=Labsystems
+
+usb:v07EA*
+ ID_VENDOR_FROM_DATABASE=Iwatsu Electric Co., Ltd
+
+usb:v07EB*
+ ID_VENDOR_FROM_DATABASE=Double-H Technology Co., Ltd
+
+usb:v07EC*
+ ID_VENDOR_FROM_DATABASE=Taiyo Electric Wire & Cable Co., Ltd
+
+usb:v07EE*
+ ID_VENDOR_FROM_DATABASE=Torex Retail (formerly Logware)
+
+usb:v07EEp0002*
+ ID_PRODUCT_FROM_DATABASE=Cash Drawer I/F
+
+usb:v07EF*
+ ID_VENDOR_FROM_DATABASE=STSN
+
+usb:v07EFp0001*
+ ID_PRODUCT_FROM_DATABASE=Internet Access Device
+
+usb:v07F2*
+ ID_VENDOR_FROM_DATABASE=Microcomputer Applications, Inc.
+
+usb:v07F2p0001*
+ ID_PRODUCT_FROM_DATABASE=KEYLOK II
+
+usb:v07F6*
+ ID_VENDOR_FROM_DATABASE=Circuit Assembly Corp.
+
+usb:v07F7*
+ ID_VENDOR_FROM_DATABASE=Century Corp.
+
+usb:v07F7p0005*
+ ID_PRODUCT_FROM_DATABASE=ScanLogic/Century Corporation uATA
+
+usb:v07F7p011E*
+ ID_PRODUCT_FROM_DATABASE=Century USB Disk Enclosure
+
+usb:v07F9*
+ ID_VENDOR_FROM_DATABASE=Dotop Technology, Inc.
+
+usb:v07FA*
+ ID_VENDOR_FROM_DATABASE=DrayTek Corp.
+
+usb:v07FAp0778*
+ ID_PRODUCT_FROM_DATABASE=miniVigor 128 ISDN TA
+
+usb:v07FAp1012*
+ ID_PRODUCT_FROM_DATABASE=BeWAN ADSL USB ST (grey)
+
+usb:v07FAp1196*
+ ID_PRODUCT_FROM_DATABASE=BWIFI-USB54AR 802.11bg
+
+usb:v07FApA904*
+ ID_PRODUCT_FROM_DATABASE=BeWAN ADSL
+
+usb:v07FApA905*
+ ID_PRODUCT_FROM_DATABASE=BeWAN ADSL ST
+
+usb:v07FD*
+ ID_VENDOR_FROM_DATABASE=Mark of the Unicorn
+
+usb:v07FDp0000*
+ ID_PRODUCT_FROM_DATABASE=FastLane MIDI Interface
+
+usb:v07FDp0001*
+ ID_PRODUCT_FROM_DATABASE=FastLane Quad MIDI Interface
+
+usb:v07FDp0002*
+ ID_PRODUCT_FROM_DATABASE=MOTU Audio for 64 bit
+
+usb:v07FF*
+ ID_VENDOR_FROM_DATABASE=Unknown
+
+usb:v07FFp00FF*
+ ID_PRODUCT_FROM_DATABASE=Portable Hard Drive
+
+usb:v0801*
+ ID_VENDOR_FROM_DATABASE=MagTek
+
+usb:v0801p0001*
+ ID_PRODUCT_FROM_DATABASE=Mini Swipe Reader (Keyboard Emulation)
+
+usb:v0801p0002*
+ ID_PRODUCT_FROM_DATABASE=Mini Swipe Reader
+
+usb:v0801p0003*
+ ID_PRODUCT_FROM_DATABASE=Magstripe Insert Reader
+
+usb:v0802*
+ ID_VENDOR_FROM_DATABASE=Mako Technologies, LLC
+
+usb:v0803*
+ ID_VENDOR_FROM_DATABASE=Zoom Telephonics, Inc.
+
+usb:v0803p1300*
+ ID_PRODUCT_FROM_DATABASE=V92 Faxmodem
+
+usb:v0803p4310*
+ ID_PRODUCT_FROM_DATABASE=4410a Wireless-G Adapter [Intersil ISL3887]
+
+usb:v0803p4410*
+ ID_PRODUCT_FROM_DATABASE=4410b Wireless-G Adapter [ZyDAS ZD1211B]
+
+usb:v0803p5241*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v0803p5551*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0803p9700*
+ ID_PRODUCT_FROM_DATABASE=2986L FaxModem
+
+usb:v0803p9800*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v0803pA312*
+ ID_PRODUCT_FROM_DATABASE=Wireless-G
+
+usb:v0809*
+ ID_VENDOR_FROM_DATABASE=Genicom Technology, Inc.
+
+usb:v080A*
+ ID_VENDOR_FROM_DATABASE=Evermuch Technology Co., Ltd
+
+usb:v080B*
+ ID_VENDOR_FROM_DATABASE=Cross Match Technologies
+
+usb:v080Bp0002*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Scanner (After ReNumeration)
+
+usb:v080Bp0010*
+ ID_PRODUCT_FROM_DATABASE=300LC Series Fingerprint Scanner (Before ReNumeration)
+
+usb:v080C*
+ ID_VENDOR_FROM_DATABASE=Datalogic S.p.A.
+
+usb:v080Cp0300*
+ ID_PRODUCT_FROM_DATABASE=Gryphon D120 Barcode Scanner
+
+usb:v080Cp0400*
+ ID_PRODUCT_FROM_DATABASE=Gryphon D120 Barcode Scanner
+
+usb:v080Cp0500*
+ ID_PRODUCT_FROM_DATABASE=Gryphon D120 Barcode Scanner
+
+usb:v080Cp0600*
+ ID_PRODUCT_FROM_DATABASE=Gryphon M100 Barcode Scanner
+
+usb:v080D*
+ ID_VENDOR_FROM_DATABASE=Teco Image Systems Co., Ltd
+
+usb:v080Dp0102*
+ ID_PRODUCT_FROM_DATABASE=Hercules Scan@home 48
+
+usb:v080Dp0104*
+ ID_PRODUCT_FROM_DATABASE=3.2Slim
+
+usb:v080Dp0110*
+ ID_PRODUCT_FROM_DATABASE=UMAX AstraSlim 1200 Scanner
+
+usb:v0810*
+ ID_VENDOR_FROM_DATABASE=Personal Communication Systems, Inc.
+
+usb:v0810p0001*
+ ID_PRODUCT_FROM_DATABASE=Dual PSX Adaptor
+
+usb:v0810p0002*
+ ID_PRODUCT_FROM_DATABASE=Dual PCS Adaptor
+
+usb:v0810p0003*
+ ID_PRODUCT_FROM_DATABASE=PlayStation Gamepad
+
+usb:v0813*
+ ID_VENDOR_FROM_DATABASE=Mattel, Inc.
+
+usb:v0813p0001*
+ ID_PRODUCT_FROM_DATABASE=Intel Play QX3 Microscope
+
+usb:v0813p0002*
+ ID_PRODUCT_FROM_DATABASE=Dual Mode Camera Plus
+
+usb:v0819*
+ ID_VENDOR_FROM_DATABASE=eLicenser
+
+usb:v0819p0101*
+ ID_PRODUCT_FROM_DATABASE=License Management and Copy Protection
+
+usb:v081A*
+ ID_VENDOR_FROM_DATABASE=MG Logic
+
+usb:v081Ap1000*
+ ID_PRODUCT_FROM_DATABASE=Duo Pen Tablet
+
+usb:v081B*
+ ID_VENDOR_FROM_DATABASE=Indigita Corp.
+
+usb:v081Bp0600*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter
+
+usb:v081Bp0601*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter
+
+usb:v081C*
+ ID_VENDOR_FROM_DATABASE=Mipsys
+
+usb:v081E*
+ ID_VENDOR_FROM_DATABASE=AlphaSmart, Inc.
+
+usb:v081EpDF00*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0822*
+ ID_VENDOR_FROM_DATABASE=Reudo Corp.
+
+usb:v0822p2001*
+ ID_PRODUCT_FROM_DATABASE=IRXpress Infrared Device
+
+usb:v0825*
+ ID_VENDOR_FROM_DATABASE=GC Protronics
+
+usb:v0826*
+ ID_VENDOR_FROM_DATABASE=Data Transit
+
+usb:v0827*
+ ID_VENDOR_FROM_DATABASE=BroadLogic, Inc.
+
+usb:v0828*
+ ID_VENDOR_FROM_DATABASE=Sato Corp.
+
+usb:v0829*
+ ID_VENDOR_FROM_DATABASE=DirecTV Broadband, Inc. (Telocity)
+
+usb:v082D*
+ ID_VENDOR_FROM_DATABASE=Handspring
+
+usb:v082Dp0100*
+ ID_PRODUCT_FROM_DATABASE=Visor
+
+usb:v082Dp0200*
+ ID_PRODUCT_FROM_DATABASE=Treo
+
+usb:v082Dp0300*
+ ID_PRODUCT_FROM_DATABASE=Treo 600
+
+usb:v082Dp0400*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v082Dp0500*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v082Dp0600*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830*
+ ID_VENDOR_FROM_DATABASE=Palm, Inc.
+
+usb:v0830p0001*
+ ID_PRODUCT_FROM_DATABASE=m500
+
+usb:v0830p0002*
+ ID_PRODUCT_FROM_DATABASE=m505
+
+usb:v0830p0003*
+ ID_PRODUCT_FROM_DATABASE=m515
+
+usb:v0830p0004*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0005*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0006*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0010*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0011*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0012*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0013*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0014*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0020*
+ ID_PRODUCT_FROM_DATABASE=i705
+
+usb:v0830p0021*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0022*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0023*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0024*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0030*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0031*
+ ID_PRODUCT_FROM_DATABASE=Tungsten W
+
+usb:v0830p0032*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0033*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0034*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0040*
+ ID_PRODUCT_FROM_DATABASE=m125
+
+usb:v0830p0041*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0042*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0043*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0044*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0050*
+ ID_PRODUCT_FROM_DATABASE=m130
+
+usb:v0830p0051*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0052*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0053*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0054*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0060*
+ ID_PRODUCT_FROM_DATABASE=Tungsten C/E/T/T2/T3 / Zire 71
+
+usb:v0830p0061*
+ ID_PRODUCT_FROM_DATABASE=Lifedrive / Treo 650/680 / Tunsten E2/T5/TX / Centro / Zire 21/31/72 / Z22
+
+usb:v0830p0062*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0063*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0064*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0070*
+ ID_PRODUCT_FROM_DATABASE=Zire
+
+usb:v0830p0071*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0072*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0080*
+ ID_PRODUCT_FROM_DATABASE=Serial Adapter [for Palm III]
+
+usb:v0830p0081*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p0082*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0830p00A0*
+ ID_PRODUCT_FROM_DATABASE=Treo 800w
+
+usb:v0830p0101*
+ ID_PRODUCT_FROM_DATABASE=Pre
+
+usb:v0832*
+ ID_VENDOR_FROM_DATABASE=Kouwell Electronics Corp.
+
+usb:v0832p5850*
+ ID_PRODUCT_FROM_DATABASE=Cable
+
+usb:v0833*
+ ID_VENDOR_FROM_DATABASE=Sourcenext Corp.
+
+usb:v0833p012E*
+ ID_PRODUCT_FROM_DATABASE=KeikaiDenwa 8 with charger
+
+usb:v0833p039F*
+ ID_PRODUCT_FROM_DATABASE=KeikaiDenwa 8
+
+usb:v0835*
+ ID_VENDOR_FROM_DATABASE=Action Star Enterprise Co., Ltd
+
+usb:v0836*
+ ID_VENDOR_FROM_DATABASE=TrekStor
+
+usb:v0836p2836*
+ ID_PRODUCT_FROM_DATABASE=i.Beat mood
+
+usb:v0839*
+ ID_VENDOR_FROM_DATABASE=Samsung Techwin Co., Ltd
+
+usb:v0839p0005*
+ ID_PRODUCT_FROM_DATABASE=Digimax Camera
+
+usb:v0839p0008*
+ ID_PRODUCT_FROM_DATABASE=Digimax 230 Camera
+
+usb:v0839p0009*
+ ID_PRODUCT_FROM_DATABASE=Digimax 340
+
+usb:v0839p000A*
+ ID_PRODUCT_FROM_DATABASE=Digimax 410
+
+usb:v0839p000E*
+ ID_PRODUCT_FROM_DATABASE=Digimax 360
+
+usb:v0839p0010*
+ ID_PRODUCT_FROM_DATABASE=Digimax 300
+
+usb:v0839p1003*
+ ID_PRODUCT_FROM_DATABASE=Digimax 210SE
+
+usb:v0839p1005*
+ ID_PRODUCT_FROM_DATABASE=Digimax 220
+
+usb:v0839p1009*
+ ID_PRODUCT_FROM_DATABASE=Digimax V4
+
+usb:v0839p1012*
+ ID_PRODUCT_FROM_DATABASE=6500 Document Camera
+
+usb:v0839p1058*
+ ID_PRODUCT_FROM_DATABASE=S730 Camera
+
+usb:v0839p1064*
+ ID_PRODUCT_FROM_DATABASE=Digimax D830 Camera
+
+usb:v0839p1542*
+ ID_PRODUCT_FROM_DATABASE=Digimax 50 Duo
+
+usb:v0839p3000*
+ ID_PRODUCT_FROM_DATABASE=Digimax 35 MP3
+
+usb:v083A*
+ ID_VENDOR_FROM_DATABASE=Accton Technology Corp.
+
+usb:v083Ap1046*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet [pegasus]
+
+usb:v083Ap1060*
+ ID_PRODUCT_FROM_DATABASE=HomeLine Adapter
+
+usb:v083Ap1F4D*
+ ID_PRODUCT_FROM_DATABASE=SMC8013WG Broadband Remote NDIS Device
+
+usb:v083Ap3046*
+ ID_PRODUCT_FROM_DATABASE=10/100 Series Adapter
+
+usb:v083Ap3060*
+ ID_PRODUCT_FROM_DATABASE=1/10/100 Adapter
+
+usb:v083Ap3501*
+ ID_PRODUCT_FROM_DATABASE=2664W
+
+usb:v083Ap3502*
+ ID_PRODUCT_FROM_DATABASE=WN3501D Wireless Adapter
+
+usb:v083Ap3503*
+ ID_PRODUCT_FROM_DATABASE=T-Sinus 111 Wireless Adapter
+
+usb:v083Ap4501*
+ ID_PRODUCT_FROM_DATABASE=T-Sinus 154data
+
+usb:v083Ap4502*
+ ID_PRODUCT_FROM_DATABASE=Siemens S30853-S1016-R107 802.11g Wireless Adapter [Intersil ISL3886]
+
+usb:v083Ap4505*
+ ID_PRODUCT_FROM_DATABASE=SMCWUSB-G 802.11bg
+
+usb:v083Ap4507*
+ ID_PRODUCT_FROM_DATABASE=SMCWUSBT-G2 802.11g Wireless Adapter [Atheros AR5523]
+
+usb:v083Ap4521*
+ ID_PRODUCT_FROM_DATABASE=Siemens S30863-S1016-R107-2 802.11g Wireless Adapter [Intersil ISL3887]
+
+usb:v083Ap5046*
+ ID_PRODUCT_FROM_DATABASE=SpeedStream 10/100 Ethernet [pegasus]
+
+usb:v083Ap5501*
+ ID_PRODUCT_FROM_DATABASE=Wireless Adapter 11g
+
+usb:v083Ap6500*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v083Ap6618*
+ ID_PRODUCT_FROM_DATABASE=802.11n Wireless Adapter
+
+usb:v083Ap7511*
+ ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter
+
+usb:v083Ap7512*
+ ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter
+
+usb:v083Ap7522*
+ ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter
+
+usb:v083Ap8522*
+ ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter
+
+usb:v083Ap8541*
+ ID_PRODUCT_FROM_DATABASE=WN4501F 802.11g Wireless Adapter [Intersil ISL3887]
+
+usb:v083ApA512*
+ ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter
+
+usb:v083ApA618*
+ ID_PRODUCT_FROM_DATABASE=SMCWUSBS-N EZ Connect N Draft 11n Wireless Adapter [Ralink RT2870]
+
+usb:v083ApA701*
+ ID_PRODUCT_FROM_DATABASE=SMCWUSBS-N3 EZ Connect N Wireless Adapter [Ralink RT3070]
+
+usb:v083ApB004*
+ ID_PRODUCT_FROM_DATABASE=CPWUE001 USB/Ethernet Adapter
+
+usb:v083ApB522*
+ ID_PRODUCT_FROM_DATABASE=SMCWUSBS-N2 EZ Connect N Wireless Adapter [Ralink RT2870]
+
+usb:v083ApBB01*
+ ID_PRODUCT_FROM_DATABASE=BlueExpert Bluetooth Device
+
+usb:v083ApC003*
+ ID_PRODUCT_FROM_DATABASE=802.11b Wireless Adapter
+
+usb:v083ApC501*
+ ID_PRODUCT_FROM_DATABASE=Zoom 4410 Wireless-G [Intersil ISL3887]
+
+usb:v083ApC561*
+ ID_PRODUCT_FROM_DATABASE=802.11a/g Wireless Adapter
+
+usb:v083ApD522*
+ ID_PRODUCT_FROM_DATABASE=Speedport W 102 Stick IEEE 802.11n USB 2.0 Adapter
+
+usb:v083ApE501*
+ ID_PRODUCT_FROM_DATABASE=ZD1211B
+
+usb:v083ApE503*
+ ID_PRODUCT_FROM_DATABASE=Arcadyan WN4501 802.11b/g
+
+usb:v083ApE506*
+ ID_PRODUCT_FROM_DATABASE=WUS-201 802.11bg
+
+usb:v083ApF501*
+ ID_PRODUCT_FROM_DATABASE=802.11g Wireless Adapter
+
+usb:v083ApF502*
+ ID_PRODUCT_FROM_DATABASE=802.11g Wireless Adapter
+
+usb:v083ApF522*
+ ID_PRODUCT_FROM_DATABASE=Arcadyan WN7512 802.11n
+
+usb:v083F*
+ ID_VENDOR_FROM_DATABASE=Global Village
+
+usb:v083FpB100*
+ ID_PRODUCT_FROM_DATABASE=TelePort V.90 Fax/Modem
+
+usb:v0840*
+ ID_VENDOR_FROM_DATABASE=Argosy Research, Inc.
+
+usb:v0840p0060*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter Bridge Module
+
+usb:v0841*
+ ID_VENDOR_FROM_DATABASE=Rioport.com, Inc.
+
+usb:v0841p0001*
+ ID_PRODUCT_FROM_DATABASE=Rio 500
+
+usb:v0844*
+ ID_VENDOR_FROM_DATABASE=Welland Industrial Co., Ltd
+
+usb:v0846*
+ ID_VENDOR_FROM_DATABASE=NetGear, Inc.
+
+usb:v0846p1001*
+ ID_PRODUCT_FROM_DATABASE=EA101 10 Mbps 10BASE-T Ethernet [Kawasaki LSI KL5KLUSB101B]
+
+usb:v0846p1002*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v0846p1020*
+ ID_PRODUCT_FROM_DATABASE=FA101 Fast Ethernet USB 1.1
+
+usb:v0846p1040*
+ ID_PRODUCT_FROM_DATABASE=FA120 Fast Ethernet USB 2.0 [Asix AX88172 / AX8817x]
+
+usb:v0846p4110*
+ ID_PRODUCT_FROM_DATABASE=MA111(v1) 802.11b Wireless [Intersil Prism 3.0]
+
+usb:v0846p4200*
+ ID_PRODUCT_FROM_DATABASE=WG121(v1) 54 Mbps Wireless [Intersil ISL3886]
+
+usb:v0846p4210*
+ ID_PRODUCT_FROM_DATABASE=WG121(v2) 54 Mbps Wireless [Intersil ISL3886]
+
+usb:v0846p4220*
+ ID_PRODUCT_FROM_DATABASE=WG111(v1) 54 Mbps Wireless [Intersil ISL3886]
+
+usb:v0846p4230*
+ ID_PRODUCT_FROM_DATABASE=MA111(v2) 802.11b Wireless [SIS SIS 162]
+
+usb:v0846p4240*
+ ID_PRODUCT_FROM_DATABASE=WG111(v1) rev 2 54 Mbps Wireless [Intersil ISL3887]
+
+usb:v0846p4260*
+ ID_PRODUCT_FROM_DATABASE=WG111v3 54 Mbps Wireless [realtek RTL8187B]
+
+usb:v0846p4300*
+ ID_PRODUCT_FROM_DATABASE=WG111U Double 108 Mbps Wireless [Atheros AR5004X / AR5005UX]
+
+usb:v0846p4301*
+ ID_PRODUCT_FROM_DATABASE=WG111U (no firmware) Double 108 Mbps Wireless [Atheros AR5004X / AR5005UX]
+
+usb:v0846p5F00*
+ ID_PRODUCT_FROM_DATABASE=WPN111 802.11g Wireless Adapter [Atheros AR5523]
+
+usb:v0846p6A00*
+ ID_PRODUCT_FROM_DATABASE=WG111v2 54 Mbps Wireless [RealTek RTL8187L]
+
+usb:v0846p7100*
+ ID_PRODUCT_FROM_DATABASE=WN121T RangeMax Next Wireless-N [Marvell TopDog]
+
+usb:v0846p9000*
+ ID_PRODUCT_FROM_DATABASE=WN111(v1) RangeMax Next Wireless [Marvell 88W8362+88W8060]
+
+usb:v0846p9001*
+ ID_PRODUCT_FROM_DATABASE=WN111(v2) RangeMax Next Wireless [Atheros AR9170+AR9101]
+
+usb:v0846p9010*
+ ID_PRODUCT_FROM_DATABASE=WNDA3100v1 802.11abgn [Atheros AR9170+AR9104]
+
+usb:v0846p9011*
+ ID_PRODUCT_FROM_DATABASE=WNDA3100v2 802.11abgn [Broadcom BCM4323]
+
+usb:v0846p9012*
+ ID_PRODUCT_FROM_DATABASE=WNDA4100 802.11abgn 3x3:3 [Ralink RT3573]
+
+usb:v0846p9018*
+ ID_PRODUCT_FROM_DATABASE=WNDA3200 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]
+
+usb:v0846p9020*
+ ID_PRODUCT_FROM_DATABASE=WNA3100(v1) Wireless-N 300 [Broadcom BCM43231]
+
+usb:v0846p9030*
+ ID_PRODUCT_FROM_DATABASE=WNA1100 Wireless-N 150 [Atheros AR9271]
+
+usb:v0846p9040*
+ ID_PRODUCT_FROM_DATABASE=WNA1000 Wireless-N 150 [Atheros AR9170+AR9101]
+
+usb:v0846p9041*
+ ID_PRODUCT_FROM_DATABASE=WNA1000M 802.11bgn [Realtek RTL8188CUS]
+
+usb:v0846pA001*
+ ID_PRODUCT_FROM_DATABASE=PA101 10 Mbps HPNA Home Phoneline RJ-1
+
+usb:v084D*
+ ID_VENDOR_FROM_DATABASE=Minton Optic Industry Co., Inc.
+
+usb:v084Dp0001*
+ ID_PRODUCT_FROM_DATABASE=Jenoptik JD800i
+
+usb:v084Dp0003*
+ ID_PRODUCT_FROM_DATABASE=S-Cam F5/D-Link DSC-350 Digital Camera
+
+usb:v084Dp0011*
+ ID_PRODUCT_FROM_DATABASE=Argus DC3500 Digital Camera
+
+usb:v084Dp0014*
+ ID_PRODUCT_FROM_DATABASE=Praktica DC 32
+
+usb:v084Dp0019*
+ ID_PRODUCT_FROM_DATABASE=Praktica DPix3000
+
+usb:v084Dp0025*
+ ID_PRODUCT_FROM_DATABASE=Praktica DC 60
+
+usb:v084Dp1001*
+ ID_PRODUCT_FROM_DATABASE=ScanHex SX-35d
+
+usb:v084E*
+ ID_VENDOR_FROM_DATABASE=KB Gear
+
+usb:v084Ep0001*
+ ID_PRODUCT_FROM_DATABASE=JamCam Camera
+
+usb:v084Ep1001*
+ ID_PRODUCT_FROM_DATABASE=Jam Studio Tablet
+
+usb:v084Ep1002*
+ ID_PRODUCT_FROM_DATABASE=Pablo Tablet
+
+usb:v084F*
+ ID_VENDOR_FROM_DATABASE=Empeg
+
+usb:v084Fp0001*
+ ID_PRODUCT_FROM_DATABASE=Empeg-Car Mark I/II Player
+
+usb:v0850*
+ ID_VENDOR_FROM_DATABASE=Fast Point Technologies, Inc.
+
+usb:v0851*
+ ID_VENDOR_FROM_DATABASE=Macronix International Co., Ltd
+
+usb:v0851p1542*
+ ID_PRODUCT_FROM_DATABASE=SiPix Blink
+
+usb:v0851p1543*
+ ID_PRODUCT_FROM_DATABASE=Maxell WS30 Slim Digital Camera, or Pandigital PI8004W01 digital photo frame
+
+usb:v0851pA168*
+ ID_PRODUCT_FROM_DATABASE=MXIC
+
+usb:v0852*
+ ID_VENDOR_FROM_DATABASE=CSEM
+
+usb:v0853*
+ ID_VENDOR_FROM_DATABASE=Topre Corporation
+
+usb:v0853p0100*
+ ID_PRODUCT_FROM_DATABASE=HHKB Professional
+
+usb:v0854*
+ ID_VENDOR_FROM_DATABASE=ActiveWire, Inc.
+
+usb:v0854p0100*
+ ID_PRODUCT_FROM_DATABASE=I/O Board
+
+usb:v0854p0101*
+ ID_PRODUCT_FROM_DATABASE=I/O Board, rev1
+
+usb:v0856*
+ ID_VENDOR_FROM_DATABASE=B&B Electronics
+
+usb:v0856pAC01*
+ ID_PRODUCT_FROM_DATABASE=uLinks USOTL4 RS422/485 Adapter
+
+usb:v0858*
+ ID_VENDOR_FROM_DATABASE=Hitachi Maxell, Ltd
+
+usb:v0858p3102*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0858pFFFF*
+ ID_PRODUCT_FROM_DATABASE=Maxell module with BlueCore in DFU mode
+
+usb:v0859*
+ ID_VENDOR_FROM_DATABASE=Minolta Systems Laboratory, Inc.
+
+usb:v085A*
+ ID_VENDOR_FROM_DATABASE=Xircom
+
+usb:v085Ap0001*
+ ID_PRODUCT_FROM_DATABASE=Portstation Dual Serial Port
+
+usb:v085Ap0003*
+ ID_PRODUCT_FROM_DATABASE=Portstation Paraller Port
+
+usb:v085Ap0008*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v085Ap0009*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v085Ap000B*
+ ID_PRODUCT_FROM_DATABASE=Portstation Dual PS/2 Port
+
+usb:v085Ap0021*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial Converter
+
+usb:v085Ap0022*
+ ID_PRODUCT_FROM_DATABASE=Parallel Port
+
+usb:v085Ap0023*
+ ID_PRODUCT_FROM_DATABASE=2 port to Serial Converter
+
+usb:v085Ap0024*
+ ID_PRODUCT_FROM_DATABASE=Parallel Port
+
+usb:v085Ap0027*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial Converter
+
+usb:v085Ap0028*
+ ID_PRODUCT_FROM_DATABASE=PortGear to SCSI Converter
+
+usb:v085Ap0032*
+ ID_PRODUCT_FROM_DATABASE=PortStation SCSI Module
+
+usb:v085Ap003C*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter
+
+usb:v085Ap0299*
+ ID_PRODUCT_FROM_DATABASE=Colorvision, Inc. Monitor Spyder
+
+usb:v085Ap8021*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial
+
+usb:v085Ap8023*
+ ID_PRODUCT_FROM_DATABASE=2 port to Serial
+
+usb:v085Ap8027*
+ ID_PRODUCT_FROM_DATABASE=PGSDB9 Serial Port
+
+usb:v085C*
+ ID_VENDOR_FROM_DATABASE=ColorVision, Inc.
+
+usb:v085Cp0200*
+ ID_PRODUCT_FROM_DATABASE=Monitor Spyder
+
+usb:v0862*
+ ID_VENDOR_FROM_DATABASE=Teletrol Systems, Inc.
+
+usb:v0863*
+ ID_VENDOR_FROM_DATABASE=Filanet Corp.
+
+usb:v0864*
+ ID_VENDOR_FROM_DATABASE=NetGear, Inc.
+
+usb:v0864p4100*
+ ID_PRODUCT_FROM_DATABASE=MA101 802.11b Adapter
+
+usb:v0864p4102*
+ ID_PRODUCT_FROM_DATABASE=MA101 802.11b Adapter
+
+usb:v0867*
+ ID_VENDOR_FROM_DATABASE=Data Translation, Inc.
+
+usb:v0867p9812*
+ ID_PRODUCT_FROM_DATABASE=ECON Data acquisition unit
+
+usb:v0867p9816*
+ ID_PRODUCT_FROM_DATABASE=DT9816 ECON data acquisition module
+
+usb:v0867p9836*
+ ID_PRODUCT_FROM_DATABASE=DT9836 data acquisition card
+
+usb:v086A*
+ ID_VENDOR_FROM_DATABASE=Emagic Soft- und Hardware GmbH
+
+usb:v086Ap0001*
+ ID_PRODUCT_FROM_DATABASE=Unitor8
+
+usb:v086Ap0002*
+ ID_PRODUCT_FROM_DATABASE=AMT8
+
+usb:v086Ap0003*
+ ID_PRODUCT_FROM_DATABASE=MT4
+
+usb:v086C*
+ ID_VENDOR_FROM_DATABASE=DeTeWe - Deutsche Telephonwerke AG & Co.
+
+usb:v086Cp1001*
+ ID_PRODUCT_FROM_DATABASE=Eumex 504PC ISDN TA
+
+usb:v086Cp1002*
+ ID_PRODUCT_FROM_DATABASE=Eumex 504PC (FlashLoad)
+
+usb:v086Cp1003*
+ ID_PRODUCT_FROM_DATABASE=TA33 ISDN TA
+
+usb:v086Cp1004*
+ ID_PRODUCT_FROM_DATABASE=TA33 (FlashLoad)
+
+usb:v086Cp1005*
+ ID_PRODUCT_FROM_DATABASE=Eumex 604PC HomeNet
+
+usb:v086Cp1006*
+ ID_PRODUCT_FROM_DATABASE=Eumex 604PC HomeNet (FlashLoad)
+
+usb:v086Cp1007*
+ ID_PRODUCT_FROM_DATABASE=Eumex 704PC DSL
+
+usb:v086Cp1008*
+ ID_PRODUCT_FROM_DATABASE=Eumex 704PC DSL (FlashLoad)
+
+usb:v086Cp1009*
+ ID_PRODUCT_FROM_DATABASE=Eumex 724PC DSL
+
+usb:v086Cp100A*
+ ID_PRODUCT_FROM_DATABASE=Eumex 724PC DSL (FlashLoad)
+
+usb:v086Cp100B*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 30
+
+usb:v086Cp100C*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 30 (FlashLoad)
+
+usb:v086Cp100D*
+ ID_PRODUCT_FROM_DATABASE=BeeTel Home 100
+
+usb:v086Cp100E*
+ ID_PRODUCT_FROM_DATABASE=BeeTel Home 100 (FlashLoad)
+
+usb:v086Cp1011*
+ ID_PRODUCT_FROM_DATABASE=USB2DECT
+
+usb:v086Cp1012*
+ ID_PRODUCT_FROM_DATABASE=USB2DECT (FlashLoad)
+
+usb:v086Cp1013*
+ ID_PRODUCT_FROM_DATABASE=Eumex 704PC LAN
+
+usb:v086Cp1014*
+ ID_PRODUCT_FROM_DATABASE=Eumex 704PC LAN (FlashLoad)
+
+usb:v086Cp1019*
+ ID_PRODUCT_FROM_DATABASE=Eumex 504 SE
+
+usb:v086Cp101A*
+ ID_PRODUCT_FROM_DATABASE=Eumex 504 SE (Flash-Mode)
+
+usb:v086Cp1021*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 40
+
+usb:v086Cp1022*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 40 (FlashLoad)
+
+usb:v086Cp1023*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 45
+
+usb:v086Cp1024*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 45 (FlashLoad)
+
+usb:v086Cp1025*
+ ID_PRODUCT_FROM_DATABASE=Sinus 61 data
+
+usb:v086Cp1029*
+ ID_PRODUCT_FROM_DATABASE=dect BOX
+
+usb:v086Cp102C*
+ ID_PRODUCT_FROM_DATABASE=Eumex 604PC HomeNet [FlashLoad]
+
+usb:v086Cp1030*
+ ID_PRODUCT_FROM_DATABASE=Eumex 704PC DSL [FlashLoad]
+
+usb:v086Cp1032*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 40 [FlashLoad]
+
+usb:v086Cp1033*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 30 plus
+
+usb:v086Cp1034*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 30 plus (FlashLoad)
+
+usb:v086Cp1041*
+ ID_PRODUCT_FROM_DATABASE=Eumex 220PC
+
+usb:v086Cp1042*
+ ID_PRODUCT_FROM_DATABASE=Eumex 220PC (FlashMode)
+
+usb:v086Cp1055*
+ ID_PRODUCT_FROM_DATABASE=Eumex 220 Version 2 ISDN TA
+
+usb:v086Cp1056*
+ ID_PRODUCT_FROM_DATABASE=Eumex 220 Version 2 ISDN TA (Flash-Mode)
+
+usb:v086Cp2000*
+ ID_PRODUCT_FROM_DATABASE=OpenCom 1000
+
+usb:v086E*
+ ID_VENDOR_FROM_DATABASE=System TALKS, Inc.
+
+usb:v086Ep1920*
+ ID_PRODUCT_FROM_DATABASE=SGC-X2UL
+
+usb:v086F*
+ ID_VENDOR_FROM_DATABASE=MEC IMEX, Inc.
+
+usb:v0870*
+ ID_VENDOR_FROM_DATABASE=Metricom
+
+usb:v0870p0001*
+ ID_PRODUCT_FROM_DATABASE=Ricochet GS
+
+usb:v0871*
+ ID_VENDOR_FROM_DATABASE=SanDisk, Inc.
+
+usb:v0871p0001*
+ ID_PRODUCT_FROM_DATABASE=SDDR-01 Compact Flash Reader
+
+usb:v0871p0002*
+ ID_PRODUCT_FROM_DATABASE=SDDR-31 Compact Flash Reader
+
+usb:v0871p0005*
+ ID_PRODUCT_FROM_DATABASE=SDDR-05 Compact Flash Reader
+
+usb:v0873*
+ ID_VENDOR_FROM_DATABASE=Xpeed, Inc.
+
+usb:v0874*
+ ID_VENDOR_FROM_DATABASE=A-Tec Subsystem, Inc.
+
+usb:v0879*
+ ID_VENDOR_FROM_DATABASE=Comtrol Corp.
+
+usb:v087C*
+ ID_VENDOR_FROM_DATABASE=Adesso/Kbtek America, Inc.
+
+usb:v087D*
+ ID_VENDOR_FROM_DATABASE=Jaton Corp.
+
+usb:v087Dp5704*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v087E*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Computer Products of America
+
+usb:v087F*
+ ID_VENDOR_FROM_DATABASE=Virtual IP Group, Inc.
+
+usb:v0880*
+ ID_VENDOR_FROM_DATABASE=APT Technologies, Inc.
+
+usb:v0883*
+ ID_VENDOR_FROM_DATABASE=Recording Industry Association of America (RIAA)
+
+usb:v0885*
+ ID_VENDOR_FROM_DATABASE=Boca Research, Inc.
+
+usb:v0886*
+ ID_VENDOR_FROM_DATABASE=XAC Automation Corp.
+
+usb:v0886p0630*
+ ID_PRODUCT_FROM_DATABASE=Intel PC Camera CS630
+
+usb:v0887*
+ ID_VENDOR_FROM_DATABASE=Hannstar Electronics Corp.
+
+usb:v088B*
+ ID_VENDOR_FROM_DATABASE=MassWorks, Inc.
+
+usb:v088Bp4944*
+ ID_PRODUCT_FROM_DATABASE=MassWorks ID-75 TouchScreen
+
+usb:v088C*
+ ID_VENDOR_FROM_DATABASE=Swecoin AB
+
+usb:v088Cp2030*
+ ID_PRODUCT_FROM_DATABASE=Ticket Printer TTP 2030
+
+usb:v088E*
+ ID_VENDOR_FROM_DATABASE=iLok
+
+usb:v088Ep5036*
+ ID_PRODUCT_FROM_DATABASE=Portable secure storage for software licenses
+
+usb:v0892*
+ ID_VENDOR_FROM_DATABASE=DioGraphy, Inc.
+
+usb:v0892p0101*
+ ID_PRODUCT_FROM_DATABASE=Smartdio Reader/Writer
+
+usb:v0897*
+ ID_VENDOR_FROM_DATABASE=Lauterbach
+
+usb:v0897p0002*
+ ID_PRODUCT_FROM_DATABASE=Power Debug/Power Debug II
+
+usb:v089C*
+ ID_VENDOR_FROM_DATABASE=United Technologies Research Cntr.
+
+usb:v089D*
+ ID_VENDOR_FROM_DATABASE=Icron Technologies Corp.
+
+usb:v089E*
+ ID_VENDOR_FROM_DATABASE=NST Co., Ltd
+
+usb:v089F*
+ ID_VENDOR_FROM_DATABASE=Primex Aerospace Co.
+
+usb:v08A5*
+ ID_VENDOR_FROM_DATABASE=e9, Inc.
+
+usb:v08A8*
+ ID_VENDOR_FROM_DATABASE=Andrea Electronics
+
+usb:v08A9*
+ ID_VENDOR_FROM_DATABASE=CWAV Inc.
+
+usb:v08A9p0005*
+ ID_PRODUCT_FROM_DATABASE=USBee ZX
+
+usb:v08A9p0009*
+ ID_PRODUCT_FROM_DATABASE=USBee SX
+
+usb:v08A9p0012*
+ ID_PRODUCT_FROM_DATABASE=USBee AX-Standard
+
+usb:v08A9p0013*
+ ID_PRODUCT_FROM_DATABASE=USBee AX-Plus
+
+usb:v08A9p0014*
+ ID_PRODUCT_FROM_DATABASE=USBee AX-Pro
+
+usb:v08A9p0015*
+ ID_PRODUCT_FROM_DATABASE=USBee DX
+
+usb:v08AE*
+ ID_VENDOR_FROM_DATABASE=Macally (Mace Group, Inc.)
+
+usb:v08B4*
+ ID_VENDOR_FROM_DATABASE=Sorenson Vision, Inc.
+
+usb:v08B7*
+ ID_VENDOR_FROM_DATABASE=NATSU
+
+usb:v08B7p0001*
+ ID_PRODUCT_FROM_DATABASE=Playstation adapter
+
+usb:v08B8*
+ ID_VENDOR_FROM_DATABASE=J. Gordon Electronic Design, Inc.
+
+usb:v08B8p01F4*
+ ID_PRODUCT_FROM_DATABASE=USBSIMM1
+
+usb:v08B9*
+ ID_VENDOR_FROM_DATABASE=RadioShack Corp. (Tandy)
+
+usb:v08BB*
+ ID_VENDOR_FROM_DATABASE=Texas Instruments Japan
+
+usb:v08BBp2702*
+ ID_PRODUCT_FROM_DATABASE=Speakers
+
+usb:v08BBp2704*
+ ID_PRODUCT_FROM_DATABASE=Audio Codec
+
+usb:v08BBp2900*
+ ID_PRODUCT_FROM_DATABASE=PCM2900 Audio Codec
+
+usb:v08BBp2901*
+ ID_PRODUCT_FROM_DATABASE=PCM2901 Audio Codec
+
+usb:v08BBp2902*
+ ID_PRODUCT_FROM_DATABASE=PCM2902 Audio Codec
+
+usb:v08BBp2904*
+ ID_PRODUCT_FROM_DATABASE=PCM2904 Audio Codec
+
+usb:v08BBp2910*
+ ID_PRODUCT_FROM_DATABASE=PCM2912 Audio Codec
+
+usb:v08BBp29B0*
+ ID_PRODUCT_FROM_DATABASE=PCM2900B Audio CODEC
+
+usb:v08BBp29B2*
+ ID_PRODUCT_FROM_DATABASE=PCM2902 Audio CODEC
+
+usb:v08BBp29B3*
+ ID_PRODUCT_FROM_DATABASE=PCM2903B Audio CODEC
+
+usb:v08BBp29B6*
+ ID_PRODUCT_FROM_DATABASE=PCM2906B Audio CODEC
+
+usb:v08BBp29C0*
+ ID_PRODUCT_FROM_DATABASE=PCM2900C Audio CODEC
+
+usb:v08BBp29C2*
+ ID_PRODUCT_FROM_DATABASE=PCM2902C Audio CODEC
+
+usb:v08BBp29C3*
+ ID_PRODUCT_FROM_DATABASE=PCM2903C Audio CODEC
+
+usb:v08BBp29C6*
+ ID_PRODUCT_FROM_DATABASE=PCM2906C Audio CODEC
+
+usb:v08BD*
+ ID_VENDOR_FROM_DATABASE=Citizen Watch Co., Ltd
+
+usb:v08BDp0208*
+ ID_PRODUCT_FROM_DATABASE=CLP-521 Label Printer
+
+usb:v08BDp1100*
+ ID_PRODUCT_FROM_DATABASE=X1-USB Floppy
+
+usb:v08C3*
+ ID_VENDOR_FROM_DATABASE=Precise Biometrics
+
+usb:v08C3p0001*
+ ID_PRODUCT_FROM_DATABASE=100 SC
+
+usb:v08C3p0002*
+ ID_PRODUCT_FROM_DATABASE=100 A
+
+usb:v08C3p0003*
+ ID_PRODUCT_FROM_DATABASE=100 SC BioKeyboard
+
+usb:v08C3p0006*
+ ID_PRODUCT_FROM_DATABASE=100 A BioKeyboard
+
+usb:v08C3p0100*
+ ID_PRODUCT_FROM_DATABASE=100 MC ISP
+
+usb:v08C3p0101*
+ ID_PRODUCT_FROM_DATABASE=100 MC FingerPrint and SmartCard Reader
+
+usb:v08C3p0300*
+ ID_PRODUCT_FROM_DATABASE=100 AX
+
+usb:v08C3p0400*
+ ID_PRODUCT_FROM_DATABASE=100 SC
+
+usb:v08C3p0401*
+ ID_PRODUCT_FROM_DATABASE=150 MC
+
+usb:v08C3p0402*
+ ID_PRODUCT_FROM_DATABASE=200 MC FingerPrint and SmartCard Reader
+
+usb:v08C3p0404*
+ ID_PRODUCT_FROM_DATABASE=100 SC Upgrade
+
+usb:v08C3p0405*
+ ID_PRODUCT_FROM_DATABASE=150 MC Upgrade
+
+usb:v08C3p0406*
+ ID_PRODUCT_FROM_DATABASE=100 MC Upgrade
+
+usb:v08C4*
+ ID_VENDOR_FROM_DATABASE=Proxim, Inc.
+
+usb:v08C4p0100*
+ ID_PRODUCT_FROM_DATABASE=Skyline 802.11b Wireless Adapter
+
+usb:v08C4p02F2*
+ ID_PRODUCT_FROM_DATABASE=Farallon Home Phoneline Adapter
+
+usb:v08C7*
+ ID_VENDOR_FROM_DATABASE=Key Nice Enterprise Co., Ltd
+
+usb:v08C8*
+ ID_VENDOR_FROM_DATABASE=2Wire, Inc.
+
+usb:v08C9*
+ ID_VENDOR_FROM_DATABASE=Nippon Telegraph and Telephone Corp.
+
+usb:v08CA*
+ ID_VENDOR_FROM_DATABASE=Aiptek International, Inc.
+
+usb:v08CAp0001*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v08CAp0010*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v08CAp0020*
+ ID_PRODUCT_FROM_DATABASE=APT-6000U Tablet
+
+usb:v08CAp0021*
+ ID_PRODUCT_FROM_DATABASE=APT-2 Tablet
+
+usb:v08CAp0022*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v08CAp0023*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v08CAp0024*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v08CAp0100*
+ ID_PRODUCT_FROM_DATABASE=Pen Drive
+
+usb:v08CAp0102*
+ ID_PRODUCT_FROM_DATABASE=DualCam
+
+usb:v08CAp0103*
+ ID_PRODUCT_FROM_DATABASE=Pocket DV Digital Camera
+
+usb:v08CAp0104*
+ ID_PRODUCT_FROM_DATABASE=Pocket DVII
+
+usb:v08CAp0105*
+ ID_PRODUCT_FROM_DATABASE=Mega DV(Disk)
+
+usb:v08CAp0106*
+ ID_PRODUCT_FROM_DATABASE=Pocket DV3100+
+
+usb:v08CAp0107*
+ ID_PRODUCT_FROM_DATABASE=Pocket DV3100
+
+usb:v08CAp0109*
+ ID_PRODUCT_FROM_DATABASE=Nisis DV4 Digital Camera
+
+usb:v08CAp010A*
+ ID_PRODUCT_FROM_DATABASE=Trust 738AV LCD PV Mass Storage
+
+usb:v08CAp0111*
+ ID_PRODUCT_FROM_DATABASE=PenCam VGA Plus
+
+usb:v08CAp2008*
+ ID_PRODUCT_FROM_DATABASE=Mini PenCam 2
+
+usb:v08CAp2010*
+ ID_PRODUCT_FROM_DATABASE=Pocket CAM 3 Mega (webcam)
+
+usb:v08CAp2011*
+ ID_PRODUCT_FROM_DATABASE=Pocket CAM 3 Mega (storage)
+
+usb:v08CAp2016*
+ ID_PRODUCT_FROM_DATABASE=PocketCam 2 Mega
+
+usb:v08CAp2018*
+ ID_PRODUCT_FROM_DATABASE=Pencam SD 2M
+
+usb:v08CAp2020*
+ ID_PRODUCT_FROM_DATABASE=Slim 3000F
+
+usb:v08CAp2022*
+ ID_PRODUCT_FROM_DATABASE=Slim 3200
+
+usb:v08CAp2024*
+ ID_PRODUCT_FROM_DATABASE=Pocket DV3500
+
+usb:v08CAp2028*
+ ID_PRODUCT_FROM_DATABASE=Pocket Cam4M
+
+usb:v08CAp2040*
+ ID_PRODUCT_FROM_DATABASE=Pocket DV4100M
+
+usb:v08CAp2042*
+ ID_PRODUCT_FROM_DATABASE=Pocket DV5100M Composite Device
+
+usb:v08CAp2043*
+ ID_PRODUCT_FROM_DATABASE=Pocket DV5100M (Disk)
+
+usb:v08CAp2060*
+ ID_PRODUCT_FROM_DATABASE=Pocket DV5300
+
+usb:v08CD*
+ ID_VENDOR_FROM_DATABASE=Jue Hsun Ind. Corp.
+
+usb:v08CE*
+ ID_VENDOR_FROM_DATABASE=Long Well Electronics Corp.
+
+usb:v08CF*
+ ID_VENDOR_FROM_DATABASE=Productivity Enhancement Products
+
+usb:v08D1*
+ ID_VENDOR_FROM_DATABASE=smartBridges, Inc.
+
+usb:v08D1p0001*
+ ID_PRODUCT_FROM_DATABASE=smartNIC Ethernet [catc]
+
+usb:v08D1p0003*
+ ID_PRODUCT_FROM_DATABASE=smartNIC 2 PnP Ethernet
+
+usb:v08D3*
+ ID_VENDOR_FROM_DATABASE=Virtual Ink
+
+usb:v08D4*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Siemens Computers
+
+usb:v08D4p0009*
+ ID_PRODUCT_FROM_DATABASE=SCR SmartCard Reader
+
+usb:v08D8*
+ ID_VENDOR_FROM_DATABASE=IXXAT Automation GmbH
+
+usb:v08D8p0002*
+ ID_PRODUCT_FROM_DATABASE=USB-to-CAN compact
+
+usb:v08D8p0003*
+ ID_PRODUCT_FROM_DATABASE=USB-to-CAN II
+
+usb:v08D8p0100*
+ ID_PRODUCT_FROM_DATABASE=USB-to-CAN
+
+usb:v08D9*
+ ID_VENDOR_FROM_DATABASE=Increment P Corp.
+
+usb:v08DD*
+ ID_VENDOR_FROM_DATABASE=Billionton Systems, Inc.
+
+usb:v08DDp0112*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN Adapter
+
+usb:v08DDp0113*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN Adapter
+
+usb:v08DDp0986*
+ ID_PRODUCT_FROM_DATABASE=USB-100N Ethernet [pegasus]
+
+usb:v08DDp0987*
+ ID_PRODUCT_FROM_DATABASE=USBLP-100 HomePNA Ethernet [pegasus]
+
+usb:v08DDp0988*
+ ID_PRODUCT_FROM_DATABASE=USBEL-100 Ethernet [pegasus]
+
+usb:v08DDp1986*
+ ID_PRODUCT_FROM_DATABASE=10/100 LAN Adapter
+
+usb:v08DDp2103*
+ ID_PRODUCT_FROM_DATABASE=DVB-T TV-Tuner Card-R
+
+usb:v08DDp8511*
+ ID_PRODUCT_FROM_DATABASE=USBE-100 Ethernet [pegasus2]
+
+usb:v08DDp90FF*
+ ID_PRODUCT_FROM_DATABASE=USB2AR Ethernet
+
+usb:v08DE*
+ ID_VENDOR_FROM_DATABASE=???
+
+usb:v08DEp7A01*
+ ID_PRODUCT_FROM_DATABASE=802.11b Adapter
+
+usb:v08DF*
+ ID_VENDOR_FROM_DATABASE=Spyrus, Inc.
+
+usb:v08DFp0001*
+ ID_PRODUCT_FROM_DATABASE=Rosetta Token V1
+
+usb:v08DFp0002*
+ ID_PRODUCT_FROM_DATABASE=Rosetta Token V2
+
+usb:v08DFp0003*
+ ID_PRODUCT_FROM_DATABASE=Rosetta Token V3
+
+usb:v08DFp0A00*
+ ID_PRODUCT_FROM_DATABASE=Lynks Interface
+
+usb:v08E3*
+ ID_VENDOR_FROM_DATABASE=Olitec, Inc.
+
+usb:v08E3p0002*
+ ID_PRODUCT_FROM_DATABASE=USB-RS232 Bridge
+
+usb:v08E3p0100*
+ ID_PRODUCT_FROM_DATABASE=Interface ADSL
+
+usb:v08E3p0101*
+ ID_PRODUCT_FROM_DATABASE=Interface ADSL
+
+usb:v08E3p0102*
+ ID_PRODUCT_FROM_DATABASE=ADSL
+
+usb:v08E3p0301*
+ ID_PRODUCT_FROM_DATABASE=RNIS
+
+usb:v08E4*
+ ID_VENDOR_FROM_DATABASE=Pioneer Corp.
+
+usb:v08E5*
+ ID_VENDOR_FROM_DATABASE=Litronic
+
+usb:v08E6*
+ ID_VENDOR_FROM_DATABASE=Gemplus
+
+usb:v08E6p0001*
+ ID_PRODUCT_FROM_DATABASE=GemPC-Touch 430
+
+usb:v08E6p0430*
+ ID_PRODUCT_FROM_DATABASE=GemPC430 SmartCard Reader
+
+usb:v08E6p0432*
+ ID_PRODUCT_FROM_DATABASE=GemPC432 SmartCard Reader
+
+usb:v08E6p0435*
+ ID_PRODUCT_FROM_DATABASE=GemPC435 SmartCard Reader
+
+usb:v08E6p0437*
+ ID_PRODUCT_FROM_DATABASE=GemPC433 SL SmartCard Reader
+
+usb:v08E6p1359*
+ ID_PRODUCT_FROM_DATABASE=UA SECURE STORAGE TOKEN
+
+usb:v08E6p2202*
+ ID_PRODUCT_FROM_DATABASE=Gem e-Seal Pro Token
+
+usb:v08E6p3437*
+ ID_PRODUCT_FROM_DATABASE=GemPC Twin SmartCard Reader
+
+usb:v08E6p3438*
+ ID_PRODUCT_FROM_DATABASE=GemPC Key SmartCard Reader
+
+usb:v08E6p3478*
+ ID_PRODUCT_FROM_DATABASE=PinPad Smart Card Reader
+
+usb:v08E6p4433*
+ ID_PRODUCT_FROM_DATABASE=GemPC433-Swap
+
+usb:v08E6p5501*
+ ID_PRODUCT_FROM_DATABASE=GemProx-PU Contactless Smart Card Reader
+
+usb:v08E6pACE0*
+ ID_PRODUCT_FROM_DATABASE=UA HYBRID TOKEN
+
+usb:v08E7*
+ ID_VENDOR_FROM_DATABASE=Pan-International Wire & Cable
+
+usb:v08E8*
+ ID_VENDOR_FROM_DATABASE=Integrated Memory Logic
+
+usb:v08E9*
+ ID_VENDOR_FROM_DATABASE=Extended Systems, Inc.
+
+usb:v08E9p0100*
+ ID_PRODUCT_FROM_DATABASE=XTNDAccess IrDA Dongle
+
+usb:v08EA*
+ ID_VENDOR_FROM_DATABASE=Ericsson, Inc., Blue Ridge Labs
+
+usb:v08EAp00C9*
+ ID_PRODUCT_FROM_DATABASE=ADSL Modem HM120dp Loader
+
+usb:v08EAp00CA*
+ ID_PRODUCT_FROM_DATABASE=ADSL WAN Modem HM120dp
+
+usb:v08EAp00CE*
+ ID_PRODUCT_FROM_DATABASE=HM230d Virtual Bus for Helium
+
+usb:v08EApABBA*
+ ID_PRODUCT_FROM_DATABASE=USB Driver for Bluetooth Wireless Technology
+
+usb:v08EApABBB*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device in DFU State
+
+usb:v08EC*
+ ID_VENDOR_FROM_DATABASE=M-Systems Flash Disk Pioneers
+
+usb:v08ECp0001*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp0002*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp0005*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp0008*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp0010*
+ ID_PRODUCT_FROM_DATABASE=DiskOnKey
+
+usb:v08ECp0011*
+ ID_PRODUCT_FROM_DATABASE=DiskOnKey
+
+usb:v08ECp0012*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp0014*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp0015*
+ ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler ELITE
+
+usb:v08ECp0016*
+ ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler U3
+
+usb:v08ECp0020*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0021*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0022*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0023*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0024*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0025*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0026*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0027*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0028*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0029*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0030*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp0822*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp0832*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device
+
+usb:v08ECp0834*
+ ID_PRODUCT_FROM_DATABASE=M-Disk 220
+
+usb:v08ECp0998*
+ ID_PRODUCT_FROM_DATABASE=Kingston Data Traveler2.0 Disk Driver
+
+usb:v08ECp0999*
+ ID_PRODUCT_FROM_DATABASE=Kingston Data Traveler2.0 Disk Driver
+
+usb:v08ECp1000*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp2000*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v08ECp2038*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp2039*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp204A*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ECp204B*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v08ED*
+ ID_VENDOR_FROM_DATABASE=MediaTek Inc.
+
+usb:v08EDp0002*
+ ID_PRODUCT_FROM_DATABASE=CECT M800 memory card
+
+usb:v08EE*
+ ID_VENDOR_FROM_DATABASE=CCSI/Hesso
+
+usb:v08F0*
+ ID_VENDOR_FROM_DATABASE=Corex Technologies
+
+usb:v08F1*
+ ID_VENDOR_FROM_DATABASE=CTI Electronics Corp.
+
+usb:v08F2*
+ ID_VENDOR_FROM_DATABASE=Gotop Information Inc.
+
+usb:v08F2p007F*
+ ID_PRODUCT_FROM_DATABASE=Super Q2 Tablet
+
+usb:v08F5*
+ ID_VENDOR_FROM_DATABASE=SysTec Co., Ltd
+
+usb:v08F6*
+ ID_VENDOR_FROM_DATABASE=Logic 3 International, Ltd
+
+usb:v08F7*
+ ID_VENDOR_FROM_DATABASE=Vernier
+
+usb:v08F7p0001*
+ ID_PRODUCT_FROM_DATABASE=LabPro
+
+usb:v08F7p0002*
+ ID_PRODUCT_FROM_DATABASE=EasyTemp/Go!Temp
+
+usb:v08F7p0003*
+ ID_PRODUCT_FROM_DATABASE=Go!Link
+
+usb:v08F7p0004*
+ ID_PRODUCT_FROM_DATABASE=Go!Motion
+
+usb:v08F8*
+ ID_VENDOR_FROM_DATABASE=Keen Top International Enterprise Co., Ltd
+
+usb:v08F9*
+ ID_VENDOR_FROM_DATABASE=Wipro Technologies
+
+usb:v08FA*
+ ID_VENDOR_FROM_DATABASE=Caere
+
+usb:v08FB*
+ ID_VENDOR_FROM_DATABASE=Socket Communications
+
+usb:v08FC*
+ ID_VENDOR_FROM_DATABASE=Sicon Cable Technology Co., Ltd
+
+usb:v08FD*
+ ID_VENDOR_FROM_DATABASE=Digianswer A/S
+
+usb:v08FDp0001*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v08FF*
+ ID_VENDOR_FROM_DATABASE=AuthenTec, Inc.
+
+usb:v08FFp1600*
+ ID_PRODUCT_FROM_DATABASE=AES1600
+
+usb:v08FFp1610*
+ ID_PRODUCT_FROM_DATABASE=AES1600
+
+usb:v08FFp1660*
+ ID_PRODUCT_FROM_DATABASE=AES1660 Fingerprint Sensor
+
+usb:v08FFp1680*
+ ID_PRODUCT_FROM_DATABASE=AES1660 Fingerprint Sensor
+
+usb:v08FFp168F*
+ ID_PRODUCT_FROM_DATABASE=AES1660 Fingerprint Sensor
+
+usb:v08FFp2500*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2501*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2502*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2503*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2504*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2505*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2506*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2507*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2508*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2509*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp250A*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp250B*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp250C*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp250D*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp250E*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp250F*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2510*
+ ID_PRODUCT_FROM_DATABASE=AES2510
+
+usb:v08FFp2550*
+ ID_PRODUCT_FROM_DATABASE=AES2550 Fingerprint Sensor
+
+usb:v08FFp2580*
+ ID_PRODUCT_FROM_DATABASE=AES2501 Fingerprint Sensor
+
+usb:v08FFp2588*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2589*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp258A*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp258B*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp258C*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp258D*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp258E*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp258F*
+ ID_PRODUCT_FROM_DATABASE=AES2501
+
+usb:v08FFp2660*
+ ID_PRODUCT_FROM_DATABASE=AES2660 Fingerprint Sensor
+
+usb:v08FFp2680*
+ ID_PRODUCT_FROM_DATABASE=AES2660 Fingerprint Sensor
+
+usb:v08FFp268F*
+ ID_PRODUCT_FROM_DATABASE=AES2660 Fingerprint Sensor
+
+usb:v08FFp2810*
+ ID_PRODUCT_FROM_DATABASE=AES2810
+
+usb:v08FFp3400*
+ ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor
+
+usb:v08FFp3401*
+ ID_PRODUCT_FROM_DATABASE=AES3400 Sensor
+
+usb:v08FFp3402*
+ ID_PRODUCT_FROM_DATABASE=AES3400 Sensor
+
+usb:v08FFp3403*
+ ID_PRODUCT_FROM_DATABASE=AES3400 Sensor
+
+usb:v08FFp3404*
+ ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor
+
+usb:v08FFp3405*
+ ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor
+
+usb:v08FFp3406*
+ ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor
+
+usb:v08FFp3407*
+ ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor
+
+usb:v08FFp4902*
+ ID_PRODUCT_FROM_DATABASE=BioMV with TruePrint AES3500
+
+usb:v08FFp4903*
+ ID_PRODUCT_FROM_DATABASE=BioMV with TruePrint AES3400
+
+usb:v08FFp5500*
+ ID_PRODUCT_FROM_DATABASE=AES4000
+
+usb:v08FFp5501*
+ ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor
+
+usb:v08FFp5503*
+ ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor
+
+usb:v08FFp5505*
+ ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor
+
+usb:v08FFp5507*
+ ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor
+
+usb:v08FFp55FF*
+ ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor.
+
+usb:v08FFp5700*
+ ID_PRODUCT_FROM_DATABASE=AES3500 Fingerprint Reader
+
+usb:v08FFp5701*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5702*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5703*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5704*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5705*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5706*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5707*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5710*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5711*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5712*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5713*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5714*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5715*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5716*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5717*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5730*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5731*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5732*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5733*
+ ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor
+
+usb:v08FFp5734*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5735*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5736*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFp5737*
+ ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor
+
+usb:v08FFpAFE3*
+ ID_PRODUCT_FROM_DATABASE=FingerLoc Sensor Module (Anchor)
+
+usb:v08FFpAFE4*
+ ID_PRODUCT_FROM_DATABASE=FingerLoc Sensor Module (Anchor)
+
+usb:v08FFpAFE5*
+ ID_PRODUCT_FROM_DATABASE=FingerLoc Sensor Module (Anchor)
+
+usb:v08FFpAFE6*
+ ID_PRODUCT_FROM_DATABASE=FingerLoc Sensor Module (Anchor)
+
+usb:v08FFpFFFD*
+ ID_PRODUCT_FROM_DATABASE=AES2510 Sensor (USB Emulator)
+
+usb:v08FFpFFFF*
+ ID_PRODUCT_FROM_DATABASE=Sensor (Emulator)
+
+usb:v0900*
+ ID_VENDOR_FROM_DATABASE=Pinnacle Systems, Inc.
+
+usb:v0901*
+ ID_VENDOR_FROM_DATABASE=VST Technologies
+
+usb:v0901p0001*
+ ID_PRODUCT_FROM_DATABASE=Hard Drive Adapter (TPP)
+
+usb:v0901p0002*
+ ID_PRODUCT_FROM_DATABASE=SigmaDrive Adapter (TPP)
+
+usb:v0906*
+ ID_VENDOR_FROM_DATABASE=Faraday Technology Corp.
+
+usb:v0908*
+ ID_VENDOR_FROM_DATABASE=ShenZhen SANZHAI Technology Co.,Ltd
+
+usb:v0908p2701*
+ ID_PRODUCT_FROM_DATABASE=Spy Pen VGA
+
+usb:v0909*
+ ID_VENDOR_FROM_DATABASE=Audio-Technica Corp.
+
+usb:v090A*
+ ID_VENDOR_FROM_DATABASE=Trumpion Microelectronics, Inc.
+
+usb:v090Ap1001*
+ ID_PRODUCT_FROM_DATABASE=T33520 Flash Card Controller
+
+usb:v090Ap1100*
+ ID_PRODUCT_FROM_DATABASE=Comotron C3310 MP3 player
+
+usb:v090Ap1200*
+ ID_PRODUCT_FROM_DATABASE=MP3 player
+
+usb:v090Ap1540*
+ ID_PRODUCT_FROM_DATABASE=Digitex Container Flash Disk
+
+usb:v090B*
+ ID_VENDOR_FROM_DATABASE=Neurosmith
+
+usb:v090C*
+ ID_VENDOR_FROM_DATABASE=Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.)
+
+usb:v090Cp0371*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion SM371 Camera
+
+usb:v090Cp0373*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090Cp037A*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090Cp037B*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090Cp1000*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v090Cp1132*
+ ID_PRODUCT_FROM_DATABASE=5-in-1 Card Reader
+
+usb:v090Cp337B*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090Cp3710*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090Cp3720*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090Cp37BC*
+ ID_PRODUCT_FROM_DATABASE=HP Webcam-101 Integrated Camera
+
+usb:v090Cp37C0*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090Cp6000*
+ ID_PRODUCT_FROM_DATABASE=SD/SDHC Card Reader (SG365 / FlexiDrive XC+)
+
+usb:v090Cp6200*
+ ID_PRODUCT_FROM_DATABASE=microSD card reader
+
+usb:v090Cp71B3*
+ ID_PRODUCT_FROM_DATABASE=SM731 Camera
+
+usb:v090Cp837B*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090Cp937B*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera
+
+usb:v090CpB370*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion SM370 Camera
+
+usb:v090CpB371*
+ ID_PRODUCT_FROM_DATABASE=Silicon Motion SM371 Camera
+
+usb:v090D*
+ ID_VENDOR_FROM_DATABASE=Multiport Computer Vertriebs GmbH
+
+usb:v090E*
+ ID_VENDOR_FROM_DATABASE=Shining Technology, Inc.
+
+usb:v090F*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Devices, Inc.
+
+usb:v0910*
+ ID_VENDOR_FROM_DATABASE=Alation Systems, Inc.
+
+usb:v0911*
+ ID_VENDOR_FROM_DATABASE=Philips Speech Processing
+
+usb:v0911p149A*
+ ID_PRODUCT_FROM_DATABASE=SpeechMike II Pro Plus LFH5276
+
+usb:v0911p2512*
+ ID_PRODUCT_FROM_DATABASE=SpeechMike Pro
+
+usb:v0912*
+ ID_VENDOR_FROM_DATABASE=Voquette, Inc.
+
+usb:v0915*
+ ID_VENDOR_FROM_DATABASE=GlobeSpan, Inc.
+
+usb:v0915p0001*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0915p0002*
+ ID_PRODUCT_FROM_DATABASE=ADSL ATM Modem
+
+usb:v0915p0005*
+ ID_PRODUCT_FROM_DATABASE=LAN Modem
+
+usb:v0915p2000*
+ ID_PRODUCT_FROM_DATABASE=802.11 Adapter
+
+usb:v0915p2002*
+ ID_PRODUCT_FROM_DATABASE=802.11 Adapter
+
+usb:v0915p8000*
+ ID_PRODUCT_FROM_DATABASE=ADSL LAN Modem
+
+usb:v0915p8005*
+ ID_PRODUCT_FROM_DATABASE=DSL-302G Modem
+
+usb:v0915p8101*
+ ID_PRODUCT_FROM_DATABASE=ADSL WAN Modem
+
+usb:v0915p8102*
+ ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL Modem
+
+usb:v0915p8103*
+ ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL Modem
+
+usb:v0915p8104*
+ ID_PRODUCT_FROM_DATABASE=DSL-200 Modem
+
+usb:v0915p8400*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0915p8401*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0915p8402*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0915p8500*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0915p8501*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v0917*
+ ID_VENDOR_FROM_DATABASE=SmartDisk Corp.
+
+usb:v0917p0001*
+ ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 SM/CF
+
+usb:v0917p0002*
+ ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 SM
+
+usb:v0917p0003*
+ ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 CF
+
+usb:v0917p0200*
+ ID_PRODUCT_FROM_DATABASE=FireFly
+
+usb:v0917p0201*
+ ID_PRODUCT_FROM_DATABASE=FireLite
+
+usb:v0917p0202*
+ ID_PRODUCT_FROM_DATABASE=STORAGE ADAPTER (FirePower)
+
+usb:v0917p0204*
+ ID_PRODUCT_FROM_DATABASE=FlashTrax Storage
+
+usb:v0917p0205*
+ ID_PRODUCT_FROM_DATABASE=STORAGE ADAPTER (CrossFire)
+
+usb:v0917p0206*
+ ID_PRODUCT_FROM_DATABASE=FireFly 20G HDD
+
+usb:v0917p0207*
+ ID_PRODUCT_FROM_DATABASE=FireLite
+
+usb:v0917p020F*
+ ID_PRODUCT_FROM_DATABASE=STORAGE ADAPTER (FireLite)
+
+usb:v0917pDA01*
+ ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 Test
+
+usb:v0917pFFFF*
+ ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 (Class/PDR)
+
+usb:v0919*
+ ID_VENDOR_FROM_DATABASE=Tiger Electronics
+
+usb:v0919p0100*
+ ID_PRODUCT_FROM_DATABASE=Fast Flicks Digital Camera
+
+usb:v091E*
+ ID_VENDOR_FROM_DATABASE=Garmin International
+
+usb:v091Ep0003*
+ ID_PRODUCT_FROM_DATABASE=GPS (various models)
+
+usb:v091Ep0004*
+ ID_PRODUCT_FROM_DATABASE=iQue 3600
+
+usb:v091Ep0200*
+ ID_PRODUCT_FROM_DATABASE=Data Card Programmer (install)
+
+usb:v091Ep1200*
+ ID_PRODUCT_FROM_DATABASE=Data Card Programmer
+
+usb:v091Ep21A5*
+ ID_PRODUCT_FROM_DATABASE=etrex Cx (msc)
+
+usb:v091Ep2236*
+ ID_PRODUCT_FROM_DATABASE=nuvi 360
+
+usb:v091Ep2271*
+ ID_PRODUCT_FROM_DATABASE=Edge 605/705
+
+usb:v091Ep2295*
+ ID_PRODUCT_FROM_DATABASE=Colorado 300
+
+usb:v091Ep22B6*
+ ID_PRODUCT_FROM_DATABASE=eTrex Vista HCx (Mass Storage mode)
+
+usb:v091Ep231B*
+ ID_PRODUCT_FROM_DATABASE=Oregon 400t
+
+usb:v091Ep2353*
+ ID_PRODUCT_FROM_DATABASE=Nüvi 205T
+
+usb:v091Ep2380*
+ ID_PRODUCT_FROM_DATABASE=Oregon series
+
+usb:v091Ep23CC*
+ ID_PRODUCT_FROM_DATABASE=nüvi 1350
+
+usb:v091Ep2459*
+ ID_PRODUCT_FROM_DATABASE=GPSmap 62/78 series
+
+usb:v091Ep2519*
+ ID_PRODUCT_FROM_DATABASE=eTrex 30
+
+usb:v091Ep2535*
+ ID_PRODUCT_FROM_DATABASE=Edge 800
+
+usb:v091Ep255B*
+ ID_PRODUCT_FROM_DATABASE=Nuvi 2505LM
+
+usb:v0920*
+ ID_VENDOR_FROM_DATABASE=Echelon Co.
+
+usb:v0920p7500*
+ ID_PRODUCT_FROM_DATABASE=Network Interface
+
+usb:v0921*
+ ID_VENDOR_FROM_DATABASE=GoHubs, Inc.
+
+usb:v0921p1001*
+ ID_PRODUCT_FROM_DATABASE=GoCOM232 Serial
+
+usb:v0922*
+ ID_VENDOR_FROM_DATABASE=Dymo-CoStar Corp.
+
+usb:v0922p0007*
+ ID_PRODUCT_FROM_DATABASE=LabelWriter 330
+
+usb:v0922p0009*
+ ID_PRODUCT_FROM_DATABASE=LabelWriter 310
+
+usb:v0922p001A*
+ ID_PRODUCT_FROM_DATABASE=LabelWriter 400 Turbo
+
+usb:v0922p0020*
+ ID_PRODUCT_FROM_DATABASE=LabelWriter 450
+
+usb:v0923*
+ ID_VENDOR_FROM_DATABASE=IC Media Corp.
+
+usb:v0923p010F*
+ ID_PRODUCT_FROM_DATABASE=SIIG MobileCam
+
+usb:v0924*
+ ID_VENDOR_FROM_DATABASE=Xerox
+
+usb:v0924p23DD*
+ ID_PRODUCT_FROM_DATABASE=DocuPrint M760 (X760_USB)
+
+usb:v0924p3CE8*
+ ID_PRODUCT_FROM_DATABASE=Phaser 3428 Printer
+
+usb:v0924p3D5B*
+ ID_PRODUCT_FROM_DATABASE=Phaser 6115MFP TWAIN Scanner
+
+usb:v0924p420F*
+ ID_PRODUCT_FROM_DATABASE=WorkCentre PE220 Series
+
+usb:v0924p421F*
+ ID_PRODUCT_FROM_DATABASE=M20 Scanner
+
+usb:v0924p423B*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v0924p4274*
+ ID_PRODUCT_FROM_DATABASE=Xerox Phaser 3635MFPX
+
+usb:v0924pFFEF*
+ ID_PRODUCT_FROM_DATABASE=WorkCenter M15
+
+usb:v0924pFFFB*
+ ID_PRODUCT_FROM_DATABASE=DocuPrint M750 (X750_USB)
+
+usb:v0925*
+ ID_VENDOR_FROM_DATABASE=Lakeview Research
+
+usb:v0925p0005*
+ ID_PRODUCT_FROM_DATABASE=Gamtec.,Ltd SmartJoy PLUS Adapter
+
+usb:v0925p3881*
+ ID_PRODUCT_FROM_DATABASE=Saleae Logic
+
+usb:v0925p8101*
+ ID_PRODUCT_FROM_DATABASE=Phidgets, Inc., 1-Motor PhidgetServo v2.0
+
+usb:v0925p8104*
+ ID_PRODUCT_FROM_DATABASE=Phidgets, Inc., 4-Motor PhidgetServo v2.0
+
+usb:v0925p8800*
+ ID_PRODUCT_FROM_DATABASE=WiseGroup Ltd, MP-8800 Quad Joypad
+
+usb:v0925p8866*
+ ID_PRODUCT_FROM_DATABASE=WiseGroup Ltd, MP-8866 Dual Joypad
+
+usb:v0927*
+ ID_VENDOR_FROM_DATABASE=Summus, Ltd
+
+usb:v0928*
+ ID_VENDOR_FROM_DATABASE=PLX Technology, Inc. (formerly Oxford Semiconductor, Ltd)
+
+usb:v0928p8000*
+ ID_PRODUCT_FROM_DATABASE=Firmware uploader
+
+usb:v0929*
+ ID_VENDOR_FROM_DATABASE=American Biometric Co.
+
+usb:v092A*
+ ID_VENDOR_FROM_DATABASE=Toshiba Information & Industrial Sys. And Services
+
+usb:v092B*
+ ID_VENDOR_FROM_DATABASE=Sena Technologies, Inc.
+
+usb:v092F*
+ ID_VENDOR_FROM_DATABASE=Northern Embedded Science/CAVNEX
+
+usb:v092Fp0004*
+ ID_PRODUCT_FROM_DATABASE=JTAG-4
+
+usb:v092Fp0005*
+ ID_PRODUCT_FROM_DATABASE=JTAG-5
+
+usb:v0930*
+ ID_VENDOR_FROM_DATABASE=Toshiba Corp.
+
+usb:v0930p0009*
+ ID_PRODUCT_FROM_DATABASE=Gigabeat F/X (HDD audio player)
+
+usb:v0930p000C*
+ ID_PRODUCT_FROM_DATABASE=Gigabeat F (mtp)
+
+usb:v0930p0010*
+ ID_PRODUCT_FROM_DATABASE=Gigabeat S (mtp)
+
+usb:v0930p0301*
+ ID_PRODUCT_FROM_DATABASE=PCX1100U Cable Modem (WDM)
+
+usb:v0930p0302*
+ ID_PRODUCT_FROM_DATABASE=PCX2000 Cable Modem (WDM)
+
+usb:v0930p0305*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem PCX3000
+
+usb:v0930p0307*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem PCX2500
+
+usb:v0930p0308*
+ ID_PRODUCT_FROM_DATABASE=PCX2200 Cable Modem (WDM)
+
+usb:v0930p0309*
+ ID_PRODUCT_FROM_DATABASE=PCX5000 Cable Modem (WDM)
+
+usb:v0930p030B*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem PCX2600
+
+usb:v0930p0501*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller
+
+usb:v0930p0502*
+ ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth
+
+usb:v0930p0503*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller
+
+usb:v0930p0505*
+ ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth
+
+usb:v0930p0506*
+ ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth
+
+usb:v0930p0507*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter
+
+usb:v0930p0508*
+ ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth HCI
+
+usb:v0930p0509*
+ ID_PRODUCT_FROM_DATABASE=BT EDR Dongle
+
+usb:v0930p0706*
+ ID_PRODUCT_FROM_DATABASE=PocketPC e740
+
+usb:v0930p0707*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC e330 Series
+
+usb:v0930p0708*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC e350 Series
+
+usb:v0930p0709*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC e750 Series
+
+usb:v0930p070A*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC e400 Series
+
+usb:v0930p070B*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC e800 Series
+
+usb:v0930p0A07*
+ ID_PRODUCT_FROM_DATABASE=WLM-10U1 802.11abgn Wireless Adapter [Ralink RT3572]
+
+usb:v0930p0B05*
+ ID_PRODUCT_FROM_DATABASE=PX1220E-1G25 External hard drive
+
+usb:v0930p0B09*
+ ID_PRODUCT_FROM_DATABASE=PX1396E-3T01 External hard drive
+
+usb:v0930p1300*
+ ID_PRODUCT_FROM_DATABASE=Wireless Broadband (CDMA EV-DO) SM-Bus Minicard Status Port
+
+usb:v0930p1301*
+ ID_PRODUCT_FROM_DATABASE=Wireless Broadband (CDMA EV-DO) Minicard Status Port
+
+usb:v0930p1302*
+ ID_PRODUCT_FROM_DATABASE=Wireless Broadband (3G HSDPA) SM-Bus Minicard Status Port
+
+usb:v0930p1303*
+ ID_PRODUCT_FROM_DATABASE=Wireless Broadband (3G HSDPA) Minicard Status Port
+
+usb:v0930p1308*
+ ID_PRODUCT_FROM_DATABASE=Broadband (3G HSDPA) SM-Bus Minicard Diagnostics Port
+
+usb:v0930p130B*
+ ID_PRODUCT_FROM_DATABASE=F3507g Mobile Broadband Module
+
+usb:v0930p130C*
+ ID_PRODUCT_FROM_DATABASE=F3607gw Mobile Broadband Module
+
+usb:v0930p1311*
+ ID_PRODUCT_FROM_DATABASE=F3607gw v2 Mobile Broadband Module
+
+usb:v0930p1400*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick 2GB
+
+usb:v0930p642F*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6506*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6507*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6508*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6509*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6510*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6517*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6518*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6519*
+ ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 2.0 USB Stick
+
+usb:v0930p651A*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p651B*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p651C*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p651D*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p651E*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p651F*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6520*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6521*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6522*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2C
+
+usb:v0930p6523*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6524*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6525*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6526*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6527*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6528*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6529*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p652A*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p652B*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p652C*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p652D*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p652F*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6530*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6531*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p6532*
+ ID_PRODUCT_FROM_DATABASE=256M Stick
+
+usb:v0930p6533*
+ ID_PRODUCT_FROM_DATABASE=512M Stick
+
+usb:v0930p6534*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive
+
+usb:v0930p653C*
+ ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 2.0 Stick (512M)
+
+usb:v0930p653D*
+ ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 2.0 Stick (1GB)
+
+usb:v0930p653E*
+ ID_PRODUCT_FROM_DATABASE=Flash Memory
+
+usb:v0930p6540*
+ ID_PRODUCT_FROM_DATABASE=TransMemory Flash Memory
+
+usb:v0930p6544*
+ ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 2.0 Stick (2GB)
+
+usb:v0930p6545*
+ ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 102 Flash Drive / HEMA Flash Drive 2 GB / PNY Attache 4GB Stick
+
+usb:v0931*
+ ID_VENDOR_FROM_DATABASE=Harmonic Data Systems, Ltd
+
+usb:v0932*
+ ID_VENDOR_FROM_DATABASE=Crescentec Corp.
+
+usb:v0932p0300*
+ ID_PRODUCT_FROM_DATABASE=VideoAdvantage
+
+usb:v0932p0302*
+ ID_PRODUCT_FROM_DATABASE=Syntek DC-112X
+
+usb:v0932p0320*
+ ID_PRODUCT_FROM_DATABASE=VideoAdvantage
+
+usb:v0932p0482*
+ ID_PRODUCT_FROM_DATABASE=USB2.0 TVBOX
+
+usb:v0932p1100*
+ ID_PRODUCT_FROM_DATABASE=DC-1100 Video Enhamcement Device
+
+usb:v0932p1112*
+ ID_PRODUCT_FROM_DATABASE=Veo Web Camera
+
+usb:v0932pA311*
+ ID_PRODUCT_FROM_DATABASE=Video Enhancement Device
+
+usb:v0933*
+ ID_VENDOR_FROM_DATABASE=Quantum Corp.
+
+usb:v0934*
+ ID_VENDOR_FROM_DATABASE=Spirent Communications
+
+usb:v0936*
+ ID_VENDOR_FROM_DATABASE=NuTesla
+
+usb:v0936p0030*
+ ID_PRODUCT_FROM_DATABASE=Composite Device, Mass Storage Device (Flash Drive) amd HID
+
+usb:v0936p003C*
+ ID_PRODUCT_FROM_DATABASE=Rhythmedics HID Bootloader
+
+usb:v0939*
+ ID_VENDOR_FROM_DATABASE=Lumberg, Inc.
+
+usb:v0939p0B15*
+ ID_PRODUCT_FROM_DATABASE=Toshiba Stor.E Alu 2 1TB (PX1710E-1HJ0)
+
+usb:v093A*
+ ID_VENDOR_FROM_DATABASE=Pixart Imaging, Inc.
+
+usb:v093Ap0007*
+ ID_PRODUCT_FROM_DATABASE=CMOS 100K-R Rev. 1.90
+
+usb:v093Ap010E*
+ ID_PRODUCT_FROM_DATABASE=Digital camera, CD302N/Elta Medi@ digi-cam/HE-501A
+
+usb:v093Ap010F*
+ ID_PRODUCT_FROM_DATABASE=Argus DC-1610/DC-1620/Emprex PCD3600/Philips P44417B keychain camera/Precision Mini,Model HA513A/Vivitar Vivicam 55
+
+usb:v093Ap020F*
+ ID_PRODUCT_FROM_DATABASE=Bullet Line Photo Viewer
+
+usb:v093Ap050F*
+ ID_PRODUCT_FROM_DATABASE=Mars-Semi Pc-Camera
+
+usb:v093Ap2460*
+ ID_PRODUCT_FROM_DATABASE=Q-TEC WEBCAM 100
+
+usb:v093Ap2468*
+ ID_PRODUCT_FROM_DATABASE=SoC PC-Camera
+
+usb:v093Ap2470*
+ ID_PRODUCT_FROM_DATABASE=SoC PC-Camera
+
+usb:v093Ap2471*
+ ID_PRODUCT_FROM_DATABASE=SoC PC-Camera
+
+usb:v093Ap2500*
+ ID_PRODUCT_FROM_DATABASE=USB Optical Mouse
+
+usb:v093Ap2510*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v093Ap2600*
+ ID_PRODUCT_FROM_DATABASE=Typhoon Easycam USB 330K (newer)/Typhoon Easycam USB 2.0 VGA 1.3M/Sansun SN-508
+
+usb:v093Ap2601*
+ ID_PRODUCT_FROM_DATABASE=SPC 610NC Laptop Camera
+
+usb:v093Ap2603*
+ ID_PRODUCT_FROM_DATABASE=PAC7312 Camera
+
+usb:v093Ap2608*
+ ID_PRODUCT_FROM_DATABASE=PAC7311 Trust WB-3300p
+
+usb:v093Ap260E*
+ ID_PRODUCT_FROM_DATABASE=PAC7311 Gigaware VGA PC Camera:Trust WB-3350p:SIGMA cam 2350
+
+usb:v093Ap260F*
+ ID_PRODUCT_FROM_DATABASE=PAC7311 SnakeCam
+
+usb:v093Ap2621*
+ ID_PRODUCT_FROM_DATABASE=PAC731x Trust Webcam
+
+usb:v093Ap2624*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v093B*
+ ID_VENDOR_FROM_DATABASE=Plextor Corp.
+
+usb:v093Bp0010*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter
+
+usb:v093Bp0011*
+ ID_PRODUCT_FROM_DATABASE=PlexWriter 40/12/40U
+
+usb:v093Bp0041*
+ ID_PRODUCT_FROM_DATABASE=PX-708A DVD RW
+
+usb:v093Bp0042*
+ ID_PRODUCT_FROM_DATABASE=PX-712UF DVD RW
+
+usb:v093BpA002*
+ ID_PRODUCT_FROM_DATABASE=ConvertX M402U XLOADER
+
+usb:v093BpA003*
+ ID_PRODUCT_FROM_DATABASE=ConvertX AV100U A/V Capture Audio
+
+usb:v093BpA004*
+ ID_PRODUCT_FROM_DATABASE=ConvertX TV402U XLOADER
+
+usb:v093BpA005*
+ ID_PRODUCT_FROM_DATABASE=ConvertX TV100U A/V Capture
+
+usb:v093BpA102*
+ ID_PRODUCT_FROM_DATABASE=ConvertX M402U A/V Capture
+
+usb:v093BpA104*
+ ID_PRODUCT_FROM_DATABASE=ConvertX PX-TV402U/NA
+
+usb:v093C*
+ ID_VENDOR_FROM_DATABASE=Intrepid Control Systems, Inc.
+
+usb:v093Cp0601*
+ ID_PRODUCT_FROM_DATABASE=ValueCAN
+
+usb:v093Cp0701*
+ ID_PRODUCT_FROM_DATABASE=NeoVI Blue vehicle bus interface
+
+usb:v093D*
+ ID_VENDOR_FROM_DATABASE=InnoSync, Inc.
+
+usb:v093E*
+ ID_VENDOR_FROM_DATABASE=J.S.T. Mfg. Co., Ltd
+
+usb:v093F*
+ ID_VENDOR_FROM_DATABASE=Olympia Telecom Vertriebs GmbH
+
+usb:v0940*
+ ID_VENDOR_FROM_DATABASE=Japan Storage Battery Co., Ltd
+
+usb:v0941*
+ ID_VENDOR_FROM_DATABASE=Photobit Corp.
+
+usb:v0942*
+ ID_VENDOR_FROM_DATABASE=i2Go.com, LLC
+
+usb:v0943*
+ ID_VENDOR_FROM_DATABASE=HCL Technologies India Private, Ltd
+
+usb:v0944*
+ ID_VENDOR_FROM_DATABASE=KORG, Inc.
+
+usb:v0944p0001*
+ ID_PRODUCT_FROM_DATABASE=PXR4 4-Track Digital Recorder
+
+usb:v0944p0020*
+ ID_PRODUCT_FROM_DATABASE=KAOSS Pad KP3 Dynamic Effect/Sampler
+
+usb:v0944p0023*
+ ID_PRODUCT_FROM_DATABASE=KAOSSILATOR PRO Dynamic Phrase Synthesizer
+
+usb:v0944p010D*
+ ID_PRODUCT_FROM_DATABASE=nanoKEY MIDI keyboard
+
+usb:v0944p010E*
+ ID_PRODUCT_FROM_DATABASE=nanoPAD pad controller
+
+usb:v0944p010F*
+ ID_PRODUCT_FROM_DATABASE=nanoKONTROL studio controller
+
+usb:v0944p0117*
+ ID_PRODUCT_FROM_DATABASE=nanoKONTROL2 MIDI Controller
+
+usb:v0944p0F03*
+ ID_PRODUCT_FROM_DATABASE=K-Series K61P MIDI studio controller
+
+usb:v0945*
+ ID_VENDOR_FROM_DATABASE=Pasco Scientific
+
+usb:v0948*
+ ID_VENDOR_FROM_DATABASE=Kronauer music in digital
+
+usb:v0948p0301*
+ ID_PRODUCT_FROM_DATABASE=USB Pro (24/48)
+
+usb:v0948p0302*
+ ID_PRODUCT_FROM_DATABASE=USB Pro (24/96 playback)
+
+usb:v0948p0303*
+ ID_PRODUCT_FROM_DATABASE=USB Pro (24/96 record)
+
+usb:v0948p0304*
+ ID_PRODUCT_FROM_DATABASE=USB Pro (16/48)
+
+usb:v0948p1105*
+ ID_PRODUCT_FROM_DATABASE=USB One
+
+usb:v094B*
+ ID_VENDOR_FROM_DATABASE=Linkup Systems Corp.
+
+usb:v094Bp0001*
+ ID_PRODUCT_FROM_DATABASE=neonode N2
+
+usb:v094D*
+ ID_VENDOR_FROM_DATABASE=Cable Television Laboratories
+
+usb:v094F*
+ ID_VENDOR_FROM_DATABASE=Yano
+
+usb:v094Fp0101*
+ ID_PRODUCT_FROM_DATABASE=U640MO-03
+
+usb:v094Fp05FC*
+ ID_PRODUCT_FROM_DATABASE=METALWEAR-HDD
+
+usb:v0951*
+ ID_VENDOR_FROM_DATABASE=Kingston Technology
+
+usb:v0951p0008*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v0951p000A*
+ ID_PRODUCT_FROM_DATABASE=KNU101TX 100baseTX Ethernet
+
+usb:v0951p1600*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler II Pen Drive
+
+usb:v0951p1601*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler II+ Pen Drive
+
+usb:v0951p1602*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler Mini
+
+usb:v0951p1603*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 1GB/2GB Pen Drive
+
+usb:v0951p1606*
+ ID_PRODUCT_FROM_DATABASE=Eee PC 701 SD Card Reader [ENE UB6225]
+
+usb:v0951p1607*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 100
+
+usb:v0951p160D*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler Vault Privacy
+
+usb:v0951p1613*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler DT101C Flash Drive
+
+usb:v0951p1616*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler Locker 4GB
+
+usb:v0951p1621*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 150 (32GB)
+
+usb:v0951p1624*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler G2 4GB Pen Drive
+
+usb:v0951p1625*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 101 II
+
+usb:v0951p162A*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 112 4GB Pen Drive
+
+usb:v0951p162D*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 102
+
+usb:v0951p1630*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 200 (32GB)
+
+usb:v0951p1642*
+ ID_PRODUCT_FROM_DATABASE=DT101 G2
+
+usb:v0951p1643*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler G3 4GB
+
+usb:v0951p1653*
+ ID_PRODUCT_FROM_DATABASE=Data Traveler 100 G2 8 GiB
+
+usb:v0951p1656*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler Ultimate G2
+
+usb:v0954*
+ ID_VENDOR_FROM_DATABASE=RPM Systems Corp.
+
+usb:v0955*
+ ID_VENDOR_FROM_DATABASE=NVidia Corp.
+
+usb:v0955p7030*
+ ID_PRODUCT_FROM_DATABASE=Tegra 3 (recovery mode)
+
+usb:v0955p7100*
+ ID_PRODUCT_FROM_DATABASE=Notion Ink Adam
+
+usb:v0956*
+ ID_VENDOR_FROM_DATABASE=BSquare Corp.
+
+usb:v0957*
+ ID_VENDOR_FROM_DATABASE=Agilent Technologies, Inc.
+
+usb:v0957p0200*
+ ID_PRODUCT_FROM_DATABASE=E-Video DC-350 Camera
+
+usb:v0957p0202*
+ ID_PRODUCT_FROM_DATABASE=E-Video DC-350 Camera
+
+usb:v0957p0518*
+ ID_PRODUCT_FROM_DATABASE=82357B GPIB Interface
+
+usb:v0957p1745*
+ ID_PRODUCT_FROM_DATABASE=Test and Measurement Device (IVI)
+
+usb:v0957p2918*
+ ID_PRODUCT_FROM_DATABASE=U2702A oscilloscope
+
+usb:v0958*
+ ID_VENDOR_FROM_DATABASE=CompuLink Research, Inc.
+
+usb:v0959*
+ ID_VENDOR_FROM_DATABASE=Cologne Chip AG
+
+usb:v0959p2BD0*
+ ID_PRODUCT_FROM_DATABASE=Intelligent ISDN (Ver. 3.60.04)
+
+usb:v095A*
+ ID_VENDOR_FROM_DATABASE=Portsmith
+
+usb:v095Ap3003*
+ ID_PRODUCT_FROM_DATABASE=Express Ethernet
+
+usb:v095B*
+ ID_VENDOR_FROM_DATABASE=Medialogic Corp.
+
+usb:v095C*
+ ID_VENDOR_FROM_DATABASE=K-Tec Electronics
+
+usb:v095D*
+ ID_VENDOR_FROM_DATABASE=Polycom, Inc.
+
+usb:v095Dp0001*
+ ID_PRODUCT_FROM_DATABASE=Polycom ViaVideo
+
+usb:v0967*
+ ID_VENDOR_FROM_DATABASE=Acer (??)
+
+usb:v0967p0204*
+ ID_PRODUCT_FROM_DATABASE=WarpLink 802.11b Adapter
+
+usb:v0968*
+ ID_VENDOR_FROM_DATABASE=Catalyst Enterprises, Inc.
+
+usb:v096E*
+ ID_VENDOR_FROM_DATABASE=Feitian Technologies, Inc.
+
+usb:v096Ep0120*
+ ID_PRODUCT_FROM_DATABASE=Microcosm Ltd Dinkey
+
+usb:v096Ep0802*
+ ID_PRODUCT_FROM_DATABASE=ePass2000 (G&D STARCOS SPK 2.4)
+
+usb:v096Ep0807*
+ ID_PRODUCT_FROM_DATABASE=ePass2003
+
+usb:v0971*
+ ID_VENDOR_FROM_DATABASE=Gretag-Macbeth AG
+
+usb:v0971p2003*
+ ID_PRODUCT_FROM_DATABASE=Eye-One display
+
+usb:v0971p2005*
+ ID_PRODUCT_FROM_DATABASE=Huey
+
+usb:v0971p2007*
+ ID_PRODUCT_FROM_DATABASE=ColorMunki
+
+usb:v0973*
+ ID_VENDOR_FROM_DATABASE=Schlumberger
+
+usb:v0973p0001*
+ ID_PRODUCT_FROM_DATABASE=e-gate Smart Card
+
+usb:v0974*
+ ID_VENDOR_FROM_DATABASE=Datagraphix, a business unit of Anacomp
+
+usb:v0975*
+ ID_VENDOR_FROM_DATABASE=OL'E Communications, Inc.
+
+usb:v0976*
+ ID_VENDOR_FROM_DATABASE=Adirondack Wire & Cable
+
+usb:v0977*
+ ID_VENDOR_FROM_DATABASE=Lightsurf Technologies
+
+usb:v0978*
+ ID_VENDOR_FROM_DATABASE=Beckhoff GmbH
+
+usb:v0979*
+ ID_VENDOR_FROM_DATABASE=Jeilin Technology Corp., Ltd
+
+usb:v0979p0224*
+ ID_PRODUCT_FROM_DATABASE=JL2005A Toy Camera
+
+usb:v0979p0226*
+ ID_PRODUCT_FROM_DATABASE=JL2005A Toy Camera
+
+usb:v0979p0227*
+ ID_PRODUCT_FROM_DATABASE=JL2005B/C/D Toy Camera
+
+usb:v097A*
+ ID_VENDOR_FROM_DATABASE=Minds At Work LLC
+
+usb:v097Ap0001*
+ ID_PRODUCT_FROM_DATABASE=Digital Wallet
+
+usb:v097B*
+ ID_VENDOR_FROM_DATABASE=Knudsen Engineering, Ltd
+
+usb:v097C*
+ ID_VENDOR_FROM_DATABASE=Marunix Co., Ltd
+
+usb:v097D*
+ ID_VENDOR_FROM_DATABASE=Rosun Technologies, Inc.
+
+usb:v097E*
+ ID_VENDOR_FROM_DATABASE=Biopac Systems Inc.
+
+usb:v097Ep0035*
+ ID_PRODUCT_FROM_DATABASE=MP35 v1.0
+
+usb:v097F*
+ ID_VENDOR_FROM_DATABASE=Barun Electronics Co., Ltd
+
+usb:v0981*
+ ID_VENDOR_FROM_DATABASE=Oak Technology, Ltd
+
+usb:v0984*
+ ID_VENDOR_FROM_DATABASE=Apricorn
+
+usb:v0984p0200*
+ ID_PRODUCT_FROM_DATABASE=Hard Drive Storage (TPP)
+
+usb:v0985*
+ ID_VENDOR_FROM_DATABASE=cab Produkttechnik GmbH & Co KG
+
+usb:v0985p0045*
+ ID_PRODUCT_FROM_DATABASE=Mach4/200 Label Printer
+
+usb:v0985p00A3*
+ ID_PRODUCT_FROM_DATABASE=A3/200 or A3/300 Label Printer
+
+usb:v0986*
+ ID_VENDOR_FROM_DATABASE=Matsushita Electric Works, Ltd.
+
+usb:v098C*
+ ID_VENDOR_FROM_DATABASE=Vitana Corp.
+
+usb:v098D*
+ ID_VENDOR_FROM_DATABASE=INDesign
+
+usb:v098E*
+ ID_VENDOR_FROM_DATABASE=Integrated Intellectual Property, Inc.
+
+usb:v098F*
+ ID_VENDOR_FROM_DATABASE=Kenwood TMI Corp.
+
+usb:v0993*
+ ID_VENDOR_FROM_DATABASE=Gemstar eBook Group, Ltd
+
+usb:v0993p0001*
+ ID_PRODUCT_FROM_DATABASE=REB1100 eBook Reader
+
+usb:v0993p0002*
+ ID_PRODUCT_FROM_DATABASE=eBook
+
+usb:v0996*
+ ID_VENDOR_FROM_DATABASE=Integrated Telecom Express, Inc.
+
+usb:v099A*
+ ID_VENDOR_FROM_DATABASE=Zippy Technology Corp.
+
+usb:v099Ap0638*
+ ID_PRODUCT_FROM_DATABASE=Sanwa Supply Inc. Small Keyboard
+
+usb:v099Ap610C*
+ ID_PRODUCT_FROM_DATABASE=EL-610 Super Mini Electron luminescent Keyboard
+
+usb:v099Ap7160*
+ ID_PRODUCT_FROM_DATABASE=Hyper Slim Keyboard
+
+usb:v09A3*
+ ID_VENDOR_FROM_DATABASE=PairGain Technologies
+
+usb:v09A4*
+ ID_VENDOR_FROM_DATABASE=Contech Research, Inc.
+
+usb:v09A5*
+ ID_VENDOR_FROM_DATABASE=VCON Telecommunications
+
+usb:v09A6*
+ ID_VENDOR_FROM_DATABASE=Poinchips
+
+usb:v09A6p8001*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v09A7*
+ ID_VENDOR_FROM_DATABASE=Data Transmission Network Corp.
+
+usb:v09A8*
+ ID_VENDOR_FROM_DATABASE=Lin Shiung Enterprise Co., Ltd
+
+usb:v09A9*
+ ID_VENDOR_FROM_DATABASE=Smart Card Technologies Co., Ltd
+
+usb:v09AA*
+ ID_VENDOR_FROM_DATABASE=Intersil Corp.
+
+usb:v09AAp1000*
+ ID_PRODUCT_FROM_DATABASE=Prism GT 802.11b/g Adapter
+
+usb:v09AAp3642*
+ ID_PRODUCT_FROM_DATABASE=Prism 2.x 802.11b Adapter
+
+usb:v09AB*
+ ID_VENDOR_FROM_DATABASE=Japan Cash Machine Co., Ltd.
+
+usb:v09AE*
+ ID_VENDOR_FROM_DATABASE=Tripp Lite
+
+usb:v09B2*
+ ID_VENDOR_FROM_DATABASE=Franklin Electronic Publishers, Inc.
+
+usb:v09B2p0001*
+ ID_PRODUCT_FROM_DATABASE=eBookman Palm Computer
+
+usb:v09B3*
+ ID_VENDOR_FROM_DATABASE=Altius Solutions, Inc.
+
+usb:v09B4*
+ ID_VENDOR_FROM_DATABASE=MDS Telephone Systems
+
+usb:v09B5*
+ ID_VENDOR_FROM_DATABASE=Celltrix Technology Co., Ltd
+
+usb:v09BC*
+ ID_VENDOR_FROM_DATABASE=Grundig
+
+usb:v09BCp0002*
+ ID_PRODUCT_FROM_DATABASE=MPaxx MP150 MP3 Player
+
+usb:v09BE*
+ ID_VENDOR_FROM_DATABASE=MySmart.Com
+
+usb:v09BEp0001*
+ ID_PRODUCT_FROM_DATABASE=MySmartPad
+
+usb:v09BF*
+ ID_VENDOR_FROM_DATABASE=Auerswald GmbH & Co. KG
+
+usb:v09BFp00C0*
+ ID_PRODUCT_FROM_DATABASE=COMpact 2104 ISDN PBX
+
+usb:v09BFp00DB*
+ ID_PRODUCT_FROM_DATABASE=COMpact 4410/2206 ISDN
+
+usb:v09BFp00DC*
+ ID_PRODUCT_FROM_DATABASE=COMpact 4406 DSL (PBX)
+
+usb:v09BFp00DD*
+ ID_PRODUCT_FROM_DATABASE=COMpact 2204 (PBX)
+
+usb:v09BFp00DE*
+ ID_PRODUCT_FROM_DATABASE=COMpact 2104 (Rev.2 PBX)
+
+usb:v09BFp00E0*
+ ID_PRODUCT_FROM_DATABASE=COMmander Business (PBX)
+
+usb:v09BFp00E2*
+ ID_PRODUCT_FROM_DATABASE=COMmander Basic.2 (PBX)
+
+usb:v09BFp00F1*
+ ID_PRODUCT_FROM_DATABASE=COMfort 2000 (System telephone)
+
+usb:v09BFp00F2*
+ ID_PRODUCT_FROM_DATABASE=COMfort 1200 (System telephone)
+
+usb:v09BFp00F5*
+ ID_PRODUCT_FROM_DATABASE=COMfortel 2500 (System telephone)
+
+usb:v09BFp8000*
+ ID_PRODUCT_FROM_DATABASE=COMpact 2104 DSL (DSL modem)
+
+usb:v09BFp8001*
+ ID_PRODUCT_FROM_DATABASE=COMpact 4406 DSL (DSL modem)
+
+usb:v09BFp8002*
+ ID_PRODUCT_FROM_DATABASE=Analog/ISDN Converter (Line converter)
+
+usb:v09BFp8005*
+ ID_PRODUCT_FROM_DATABASE=WG-640 (Automatic event dialer)
+
+usb:v09C0*
+ ID_VENDOR_FROM_DATABASE=Genpix Electronics, LLC
+
+usb:v09C0p0136*
+ ID_PRODUCT_FROM_DATABASE=Axon CNS, MultiClamp 700B
+
+usb:v09C0p0202*
+ ID_PRODUCT_FROM_DATABASE=8PSK DVB-S tuner
+
+usb:v09C0p0203*
+ ID_PRODUCT_FROM_DATABASE=Skywalker-1 DVB-S tuner
+
+usb:v09C0p0204*
+ ID_PRODUCT_FROM_DATABASE=Skywalker-CW3K DVB-S tuner
+
+usb:v09C0p0205*
+ ID_PRODUCT_FROM_DATABASE=Skywalker-CW3K DVB-S tuner
+
+usb:v09C0p0206*
+ ID_PRODUCT_FROM_DATABASE=Skywalker-2 DVB-S tuner
+
+usb:v09C1*
+ ID_VENDOR_FROM_DATABASE=Arris Interactive LLC
+
+usb:v09C1p1337*
+ ID_PRODUCT_FROM_DATABASE=TOUCHSTONE DEVICE
+
+usb:v09C2*
+ ID_VENDOR_FROM_DATABASE=Nisca Corp.
+
+usb:v09C3*
+ ID_VENDOR_FROM_DATABASE=ActivCard, Inc.
+
+usb:v09C3p0007*
+ ID_PRODUCT_FROM_DATABASE=Reader V2
+
+usb:v09C3p0008*
+ ID_PRODUCT_FROM_DATABASE=ZFG-9800-AC SmartCard Reader
+
+usb:v09C3p0014*
+ ID_PRODUCT_FROM_DATABASE=ActivIdentity ActivKey SIM USB Token
+
+usb:v09C4*
+ ID_VENDOR_FROM_DATABASE=ACTiSYS Corp.
+
+usb:v09C4p0011*
+ ID_PRODUCT_FROM_DATABASE=ACT-IR2000U IrDA Dongle
+
+usb:v09C5*
+ ID_VENDOR_FROM_DATABASE=Memory Corp.
+
+usb:v09CC*
+ ID_VENDOR_FROM_DATABASE=Workbit Corp.
+
+usb:v09CCp0404*
+ ID_PRODUCT_FROM_DATABASE=BAFO USB-ATA/ATAPI Bridge Controller
+
+usb:v09CD*
+ ID_VENDOR_FROM_DATABASE=Psion Dacom Home Networks, Ltd
+
+usb:v09CDp2001*
+ ID_PRODUCT_FROM_DATABASE=Psion WaveFinder DAB radio receiver
+
+usb:v09CE*
+ ID_VENDOR_FROM_DATABASE=City Electronics, Ltd
+
+usb:v09CF*
+ ID_VENDOR_FROM_DATABASE=Electronics Testing Center, Taiwan
+
+usb:v09D1*
+ ID_VENDOR_FROM_DATABASE=NeoMagic, Inc.
+
+usb:v09D2*
+ ID_VENDOR_FROM_DATABASE=Vreelin Engineering, Inc.
+
+usb:v09D3*
+ ID_VENDOR_FROM_DATABASE=Com One
+
+usb:v09D3p0001*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA
+
+usb:v09D7*
+ ID_VENDOR_FROM_DATABASE=Novatel Wireless
+
+usb:v09D7p0100*
+ ID_PRODUCT_FROM_DATABASE=NovAtel FlexPack GPS receiver
+
+usb:v09D9*
+ ID_VENDOR_FROM_DATABASE=KRF Tech, Ltd
+
+usb:v09DA*
+ ID_VENDOR_FROM_DATABASE=A4 Tech Co., Ltd
+
+usb:v09DAp0006*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse WOP-35 / Trust 450L Optical Mouse
+
+usb:v09DAp000A*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse Opto 510D
+
+usb:v09DAp000E*
+ ID_PRODUCT_FROM_DATABASE=X-F710F Optical Mouse 3xFire Gaming Mouse
+
+usb:v09DAp0018*
+ ID_PRODUCT_FROM_DATABASE=Trust Human Interface Device
+
+usb:v09DAp001A*
+ ID_PRODUCT_FROM_DATABASE=Wireless Mouse & RXM-15 Receiver
+
+usb:v09DAp002A*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse NB-30
+
+usb:v09DAp022B*
+ ID_PRODUCT_FROM_DATABASE=Wireless Mouse (Battery Free)
+
+usb:v09DAp024F*
+ ID_PRODUCT_FROM_DATABASE=RF Receiver and G6-20D Wireless Optical Mouse
+
+usb:v09DAp0260*
+ ID_PRODUCT_FROM_DATABASE=KV-300H Isolation Keyboard
+
+usb:v09DAp032B*
+ ID_PRODUCT_FROM_DATABASE=Wireless Mouse (Battery Free)
+
+usb:v09DAp8090*
+ ID_PRODUCT_FROM_DATABASE=X-718BK Oscar Optical Gaming Mouse
+
+usb:v09DAp9090*
+ ID_PRODUCT_FROM_DATABASE=XL-750BK Laser Mouse
+
+usb:v09DB*
+ ID_VENDOR_FROM_DATABASE=Measurement Computing Corp.
+
+usb:v09DBp0075*
+ ID_PRODUCT_FROM_DATABASE=MiniLab 1008
+
+usb:v09DBp0076*
+ ID_PRODUCT_FROM_DATABASE=PMD-1024
+
+usb:v09DBp007A*
+ ID_PRODUCT_FROM_DATABASE=PMD-1208LS
+
+usb:v09DBp0081*
+ ID_PRODUCT_FROM_DATABASE=USB-1616FS
+
+usb:v09DBp0082*
+ ID_PRODUCT_FROM_DATABASE=USB-1208FS
+
+usb:v09DBp0088*
+ ID_PRODUCT_FROM_DATABASE=USB-1616FS internal hub
+
+usb:v09DC*
+ ID_VENDOR_FROM_DATABASE=Aimex Corp.
+
+usb:v09DD*
+ ID_VENDOR_FROM_DATABASE=Fellowes, Inc.
+
+usb:v09DF*
+ ID_VENDOR_FROM_DATABASE=Addonics Technologies Corp.
+
+usb:v09E1*
+ ID_VENDOR_FROM_DATABASE=Intellon Corp.
+
+usb:v09E1p5121*
+ ID_PRODUCT_FROM_DATABASE=MicroLink dLAN
+
+usb:v09E5*
+ ID_VENDOR_FROM_DATABASE=Jo-Dan International, Inc.
+
+usb:v09E6*
+ ID_VENDOR_FROM_DATABASE=Silutia, Inc.
+
+usb:v09E7*
+ ID_VENDOR_FROM_DATABASE=Real 3D, Inc.
+
+usb:v09E8*
+ ID_VENDOR_FROM_DATABASE=AKAI  Professional M.I. Corp.
+
+usb:v09E8p0062*
+ ID_PRODUCT_FROM_DATABASE=MPD16 MIDI Pad Controller Unit
+
+usb:v09E8p006D*
+ ID_PRODUCT_FROM_DATABASE=EWI electronic wind instrument
+
+usb:v09E8p0071*
+ ID_PRODUCT_FROM_DATABASE=MPK25 MIDI Keyboard
+
+usb:v09E8p0076*
+ ID_PRODUCT_FROM_DATABASE=LPK25 MIDI Keyboard
+
+usb:v09E9*
+ ID_VENDOR_FROM_DATABASE=Chen-Source, Inc.
+
+usb:v09EB*
+ ID_VENDOR_FROM_DATABASE=IM Networks, Inc.
+
+usb:v09EBp4331*
+ ID_PRODUCT_FROM_DATABASE=iRhythm Tuner Remote
+
+usb:v09EF*
+ ID_VENDOR_FROM_DATABASE=Xitel
+
+usb:v09EFp0101*
+ ID_PRODUCT_FROM_DATABASE=MD-Port DG2 MiniDisc Interface
+
+usb:v09F3*
+ ID_VENDOR_FROM_DATABASE=GoFlight, Inc.
+
+usb:v09F3p0018*
+ ID_PRODUCT_FROM_DATABASE=GF-46 Multi-Mode Display Module
+
+usb:v09F3p0028*
+ ID_PRODUCT_FROM_DATABASE=RP-48 Combination Pushbutton-Rotary Module
+
+usb:v09F3p0048*
+ ID_PRODUCT_FROM_DATABASE=LGTII - Landing Gear and Trim Control Module
+
+usb:v09F3p0064*
+ ID_PRODUCT_FROM_DATABASE=MCPPro - Airliner Mode Control Panel (Autopilot)
+
+usb:v09F3p0300*
+ ID_PRODUCT_FROM_DATABASE=EFIS - Electronic Flight Information System
+
+usb:v09F5*
+ ID_VENDOR_FROM_DATABASE=AresCom
+
+usb:v09F5p0168*
+ ID_PRODUCT_FROM_DATABASE=Network Adapter
+
+usb:v09F5p0188*
+ ID_PRODUCT_FROM_DATABASE=LAN Adapter
+
+usb:v09F5p0850*
+ ID_PRODUCT_FROM_DATABASE=Adapter
+
+usb:v09F6*
+ ID_VENDOR_FROM_DATABASE=RocketChips, Inc.
+
+usb:v09F7*
+ ID_VENDOR_FROM_DATABASE=Edu-Science (H.K.), Ltd
+
+usb:v09F8*
+ ID_VENDOR_FROM_DATABASE=SoftConnex Technologies, Inc.
+
+usb:v09F9*
+ ID_VENDOR_FROM_DATABASE=Bay Associates
+
+usb:v09FA*
+ ID_VENDOR_FROM_DATABASE=Mtek Vision
+
+usb:v09FB*
+ ID_VENDOR_FROM_DATABASE=Altera
+
+usb:v09FBp6001*
+ ID_PRODUCT_FROM_DATABASE=Blaster
+
+usb:v09FF*
+ ID_VENDOR_FROM_DATABASE=Gain Technology Corp.
+
+usb:v0A00*
+ ID_VENDOR_FROM_DATABASE=Liquid Audio
+
+usb:v0A01*
+ ID_VENDOR_FROM_DATABASE=ViA, Inc.
+
+usb:v0A07*
+ ID_VENDOR_FROM_DATABASE=Ontrak Control Systems Inc.
+
+usb:v0A07p0064*
+ ID_PRODUCT_FROM_DATABASE=ADU100 Data Acquisition Interface
+
+usb:v0A07p0078*
+ ID_PRODUCT_FROM_DATABASE=ADU120 Data Acquisition Interface
+
+usb:v0A07p0082*
+ ID_PRODUCT_FROM_DATABASE=ADU130 Data Acquisition Interface
+
+usb:v0A07p00C8*
+ ID_PRODUCT_FROM_DATABASE=ADU200 Relay I/O Interface
+
+usb:v0A07p00D0*
+ ID_PRODUCT_FROM_DATABASE=ADU208 Relay I/O Interface
+
+usb:v0A07p00DA*
+ ID_PRODUCT_FROM_DATABASE=ADU218 Solid-State Relay I/O Interface
+
+usb:v0A0B*
+ ID_VENDOR_FROM_DATABASE=Cybex Computer Products Co.
+
+usb:v0A11*
+ ID_VENDOR_FROM_DATABASE=Xentec, Inc.
+
+usb:v0A12*
+ ID_VENDOR_FROM_DATABASE=Cambridge Silicon Radio, Ltd
+
+usb:v0A12p0001*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle (HCI mode)
+
+usb:v0A12p0002*
+ ID_PRODUCT_FROM_DATABASE=Frontline Test Equipment Bluetooth Device
+
+usb:v0A12p0003*
+ ID_PRODUCT_FROM_DATABASE=Nanosira
+
+usb:v0A12p0004*
+ ID_PRODUCT_FROM_DATABASE=Nanosira WHQL Reference Radio
+
+usb:v0A12p0005*
+ ID_PRODUCT_FROM_DATABASE=Nanosira-Multimedia
+
+usb:v0A12p0006*
+ ID_PRODUCT_FROM_DATABASE=Nanosira-Multimedia WHQL Reference Radio
+
+usb:v0A12p0007*
+ ID_PRODUCT_FROM_DATABASE=Nanosira3-ROM
+
+usb:v0A12p0008*
+ ID_PRODUCT_FROM_DATABASE=Nanosira3-ROM
+
+usb:v0A12p0009*
+ ID_PRODUCT_FROM_DATABASE=Nanosira4-EDR WHQL Reference Radio
+
+usb:v0A12p000A*
+ ID_PRODUCT_FROM_DATABASE=Nanosira4-EDR-ROM
+
+usb:v0A12p000B*
+ ID_PRODUCT_FROM_DATABASE=Nanosira5-ROM
+
+usb:v0A12p0043*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A12p0100*
+ ID_PRODUCT_FROM_DATABASE=Casira with BlueCore2-External Module
+
+usb:v0A12p0101*
+ ID_PRODUCT_FROM_DATABASE=Casira with BlueCore2-Flash Module
+
+usb:v0A12p0102*
+ ID_PRODUCT_FROM_DATABASE=Casira with BlueCore3-Multimedia Module
+
+usb:v0A12p0103*
+ ID_PRODUCT_FROM_DATABASE=Casira with BlueCore3-Flash Module
+
+usb:v0A12p0104*
+ ID_PRODUCT_FROM_DATABASE=Casira with BlueCore4-External Module
+
+usb:v0A12p0105*
+ ID_PRODUCT_FROM_DATABASE=Casira with BlueCore4-Multimedia Module
+
+usb:v0A12p1000*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle (HID proxy mode)
+
+usb:v0A12p1010*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A12p1011*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A12p1012*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A12pFFFF*
+ ID_PRODUCT_FROM_DATABASE=USB Bluetooth Device in DFU State
+
+usb:v0A13*
+ ID_VENDOR_FROM_DATABASE=Telebyte, Inc.
+
+usb:v0A14*
+ ID_VENDOR_FROM_DATABASE=Spacelabs Medical, Inc.
+
+usb:v0A15*
+ ID_VENDOR_FROM_DATABASE=Scalar Corp.
+
+usb:v0A16*
+ ID_VENDOR_FROM_DATABASE=Trek Technology (S) PTE, Ltd
+
+usb:v0A16p1111*
+ ID_PRODUCT_FROM_DATABASE=ThumbDrive
+
+usb:v0A16p8888*
+ ID_PRODUCT_FROM_DATABASE=IBM USB Memory Key
+
+usb:v0A16p9988*
+ ID_PRODUCT_FROM_DATABASE=Trek2000 TD-G2
+
+usb:v0A17*
+ ID_VENDOR_FROM_DATABASE=Pentax Corp.
+
+usb:v0A17p0004*
+ ID_PRODUCT_FROM_DATABASE=Optio 330
+
+usb:v0A17p0006*
+ ID_PRODUCT_FROM_DATABASE=Optio S
+
+usb:v0A17p0007*
+ ID_PRODUCT_FROM_DATABASE=Optio 550
+
+usb:v0A17p0009*
+ ID_PRODUCT_FROM_DATABASE=Optio 33WR
+
+usb:v0A17p000A*
+ ID_PRODUCT_FROM_DATABASE=Optio 555
+
+usb:v0A17p000C*
+ ID_PRODUCT_FROM_DATABASE=Optio 43WR (mass storage mode)
+
+usb:v0A17p000D*
+ ID_PRODUCT_FROM_DATABASE=Optio 43WR
+
+usb:v0A17p0015*
+ ID_PRODUCT_FROM_DATABASE=Optio S40/S5i
+
+usb:v0A17p003B*
+ ID_PRODUCT_FROM_DATABASE=Optio 50 (mass storage mode)
+
+usb:v0A17p003D*
+ ID_PRODUCT_FROM_DATABASE=Optio S55
+
+usb:v0A17p0043*
+ ID_PRODUCT_FROM_DATABASE=*ist DL
+
+usb:v0A17p0047*
+ ID_PRODUCT_FROM_DATABASE=Optio S60
+
+usb:v0A17p0052*
+ ID_PRODUCT_FROM_DATABASE=Optio 60 Digital Camera
+
+usb:v0A17p006E*
+ ID_PRODUCT_FROM_DATABASE=K10D
+
+usb:v0A17p0070*
+ ID_PRODUCT_FROM_DATABASE=K100D
+
+usb:v0A17p0093*
+ ID_PRODUCT_FROM_DATABASE=K200D
+
+usb:v0A17p00A7*
+ ID_PRODUCT_FROM_DATABASE=Optio E50
+
+usb:v0A17p1001*
+ ID_PRODUCT_FROM_DATABASE=EI2000 Camera powered by Digita!
+
+usb:v0A18*
+ ID_VENDOR_FROM_DATABASE=Heidelberger Druckmaschinen AG
+
+usb:v0A19*
+ ID_VENDOR_FROM_DATABASE=Hua Geng Technologies, Inc.
+
+usb:v0A21*
+ ID_VENDOR_FROM_DATABASE=Medtronic Physio Control Corp.
+
+usb:v0A21p8001*
+ ID_PRODUCT_FROM_DATABASE=MMT-7305WW [Medtronic Minimed CareLink]
+
+usb:v0A22*
+ ID_VENDOR_FROM_DATABASE=Century Semiconductor USA, Inc.
+
+usb:v0A27*
+ ID_VENDOR_FROM_DATABASE=Datacard Group
+
+usb:v0A27p0102*
+ ID_PRODUCT_FROM_DATABASE=SP35
+
+usb:v0A2C*
+ ID_VENDOR_FROM_DATABASE=AK-Modul-Bus Computer GmbH
+
+usb:v0A2Cp0008*
+ ID_PRODUCT_FROM_DATABASE=GPIO Ports
+
+usb:v0A34*
+ ID_VENDOR_FROM_DATABASE=TG3 Electronics, Inc.
+
+usb:v0A34p0101*
+ ID_PRODUCT_FROM_DATABASE=TG82tp
+
+usb:v0A34p0110*
+ ID_PRODUCT_FROM_DATABASE=Deck 82-key backlit keyboard
+
+usb:v0A35*
+ ID_VENDOR_FROM_DATABASE=Radikal Technologies
+
+usb:v0A35p002A*
+ ID_PRODUCT_FROM_DATABASE=SAC - Software Assigned Controller
+
+usb:v0A35p008A*
+ ID_PRODUCT_FROM_DATABASE=SAC Hub
+
+usb:v0A39*
+ ID_VENDOR_FROM_DATABASE=Gilat Satellite Networks, Ltd
+
+usb:v0A3A*
+ ID_VENDOR_FROM_DATABASE=PentaMedia Co., Ltd
+
+usb:v0A3Ap0163*
+ ID_PRODUCT_FROM_DATABASE=KN-W510U 1.0 Wireless LAN Adapter
+
+usb:v0A3C*
+ ID_VENDOR_FROM_DATABASE=NTT DoCoMo, Inc.
+
+usb:v0A3D*
+ ID_VENDOR_FROM_DATABASE=Varo Vision
+
+usb:v0A3F*
+ ID_VENDOR_FROM_DATABASE=Swissonic AG
+
+usb:v0A43*
+ ID_VENDOR_FROM_DATABASE=Boca Systems, Inc.
+
+usb:v0A46*
+ ID_VENDOR_FROM_DATABASE=Davicom Semiconductor, Inc.
+
+usb:v0A46p0268*
+ ID_PRODUCT_FROM_DATABASE=ST268
+
+usb:v0A46p6688*
+ ID_PRODUCT_FROM_DATABASE=ZT6688 Fast Ethernet Adapter
+
+usb:v0A46p8515*
+ ID_PRODUCT_FROM_DATABASE=ADMtek ADM8515 NIC
+
+usb:v0A46p9000*
+ ID_PRODUCT_FROM_DATABASE=DM9000E Fast Ethernet Adapter
+
+usb:v0A46p9601*
+ ID_PRODUCT_FROM_DATABASE=DM9601 Fast Ethernet Adapter
+
+usb:v0A47*
+ ID_VENDOR_FROM_DATABASE=Hirose Electric
+
+usb:v0A48*
+ ID_VENDOR_FROM_DATABASE=I/O Interconnect
+
+usb:v0A48p3233*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader
+
+usb:v0A48p3239*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader
+
+usb:v0A48p3258*
+ ID_PRODUCT_FROM_DATABASE=Dane Elec zMate SD Reader
+
+usb:v0A48p3259*
+ ID_PRODUCT_FROM_DATABASE=Dane Elec zMate CF Reader
+
+usb:v0A48p5000*
+ ID_PRODUCT_FROM_DATABASE=MediaGear xD-SM
+
+usb:v0A48p500A*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p500F*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5010*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5011*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5014*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5020*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5021*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5022*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5023*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5024*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A48p5025*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0A4B*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Media Devices, Ltd
+
+usb:v0A4C*
+ ID_VENDOR_FROM_DATABASE=Computex Co., Ltd
+
+usb:v0A4Cp15D9*
+ ID_PRODUCT_FROM_DATABASE=OPTICAL MOUSE
+
+usb:v0A4D*
+ ID_VENDOR_FROM_DATABASE=Evolution Electronics, Ltd
+
+usb:v0A4Dp0064*
+ ID_PRODUCT_FROM_DATABASE=MK-225 Driver
+
+usb:v0A4Dp0065*
+ ID_PRODUCT_FROM_DATABASE=MK-225C Driver
+
+usb:v0A4Dp0066*
+ ID_PRODUCT_FROM_DATABASE=MK-225C Driver
+
+usb:v0A4Dp0067*
+ ID_PRODUCT_FROM_DATABASE=MK-425C Driver
+
+usb:v0A4Dp0078*
+ ID_PRODUCT_FROM_DATABASE=MK-37 Driver
+
+usb:v0A4Dp0079*
+ ID_PRODUCT_FROM_DATABASE=MK-37C Driver
+
+usb:v0A4Dp007A*
+ ID_PRODUCT_FROM_DATABASE=MK-37C Driver
+
+usb:v0A4Dp008C*
+ ID_PRODUCT_FROM_DATABASE=TerraTec MIDI MASTER
+
+usb:v0A4Dp008D*
+ ID_PRODUCT_FROM_DATABASE=MK-249C Driver
+
+usb:v0A4Dp008E*
+ ID_PRODUCT_FROM_DATABASE=MK-249C MIDI Keyboard
+
+usb:v0A4Dp008F*
+ ID_PRODUCT_FROM_DATABASE=MK-449C Driver
+
+usb:v0A4Dp0090*
+ ID_PRODUCT_FROM_DATABASE=Keystation 49e Driver
+
+usb:v0A4Dp0091*
+ ID_PRODUCT_FROM_DATABASE=Keystation 61es Driver
+
+usb:v0A4Dp00A0*
+ ID_PRODUCT_FROM_DATABASE=MK-361 Driver
+
+usb:v0A4Dp00A1*
+ ID_PRODUCT_FROM_DATABASE=MK-361C Driver
+
+usb:v0A4Dp00A2*
+ ID_PRODUCT_FROM_DATABASE=MK-361C Driver
+
+usb:v0A4Dp00A3*
+ ID_PRODUCT_FROM_DATABASE=MK-461C MIDI Keyboard
+
+usb:v0A4Dp00B5*
+ ID_PRODUCT_FROM_DATABASE=Keystation Pro 88 Driver
+
+usb:v0A4Dp00D2*
+ ID_PRODUCT_FROM_DATABASE=E-Keys Driver
+
+usb:v0A4Dp00F0*
+ ID_PRODUCT_FROM_DATABASE=UC-16 Driver
+
+usb:v0A4Dp00F1*
+ ID_PRODUCT_FROM_DATABASE=X-Session Driver
+
+usb:v0A4Dp00F5*
+ ID_PRODUCT_FROM_DATABASE=UC-33e MIDI Controller
+
+usb:v0A4E*
+ ID_VENDOR_FROM_DATABASE=Steinberg Soft-und Hardware GmbH
+
+usb:v0A4F*
+ ID_VENDOR_FROM_DATABASE=Litton Systems, Inc.
+
+usb:v0A50*
+ ID_VENDOR_FROM_DATABASE=Mimaki Engineering Co., Ltd
+
+usb:v0A51*
+ ID_VENDOR_FROM_DATABASE=Sony Electronics, Inc.
+
+usb:v0A52*
+ ID_VENDOR_FROM_DATABASE=Jebsee Electronics Co., Ltd
+
+usb:v0A53*
+ ID_VENDOR_FROM_DATABASE=Portable Peripheral Co., Ltd
+
+usb:v0A53p1000*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v0A53p2000*
+ ID_PRODUCT_FROM_DATABASE=Q-Scan A6 Scanner
+
+usb:v0A53p2001*
+ ID_PRODUCT_FROM_DATABASE=Q-Scan A6 Scanner
+
+usb:v0A53p2013*
+ ID_PRODUCT_FROM_DATABASE=Media Drive A6 Scanner
+
+usb:v0A53p2014*
+ ID_PRODUCT_FROM_DATABASE=Media Drive A6 Scanner
+
+usb:v0A53p2015*
+ ID_PRODUCT_FROM_DATABASE=BizCardReader 600C
+
+usb:v0A53p2016*
+ ID_PRODUCT_FROM_DATABASE=BizCardReader 600C
+
+usb:v0A53p202A*
+ ID_PRODUCT_FROM_DATABASE=Scanshell-CSSN
+
+usb:v0A53p3000*
+ ID_PRODUCT_FROM_DATABASE=Q-Scan A8 Scanner
+
+usb:v0A53p3002*
+ ID_PRODUCT_FROM_DATABASE=Q-Scan A8 Reader
+
+usb:v0A53p3015*
+ ID_PRODUCT_FROM_DATABASE=BizCardReader 300G
+
+usb:v0A53p302A*
+ ID_PRODUCT_FROM_DATABASE=LM9832 - PA570 Mini Business Card Scanner [Targus]
+
+usb:v0A53p5001*
+ ID_PRODUCT_FROM_DATABASE=BizCardReader 900C
+
+usb:v0A5A*
+ ID_VENDOR_FROM_DATABASE=Electronics For Imaging, Inc.
+
+usb:v0A5B*
+ ID_VENDOR_FROM_DATABASE=EAsics NV
+
+usb:v0A5C*
+ ID_VENDOR_FROM_DATABASE=Broadcom Corp.
+
+usb:v0A5Cp0201*
+ ID_PRODUCT_FROM_DATABASE=iLine10(tm) Network Adapter
+
+usb:v0A5Cp2000*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A5Cp2001*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A5Cp2009*
+ ID_PRODUCT_FROM_DATABASE=BCM2035 Bluetooth
+
+usb:v0A5Cp200A*
+ ID_PRODUCT_FROM_DATABASE=BCM2035 Bluetooth dongle
+
+usb:v0A5Cp200F*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller
+
+usb:v0A5Cp201D*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A5Cp201E*
+ ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth IV
+
+usb:v0A5Cp2020*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth dongle
+
+usb:v0A5Cp2021*
+ ID_PRODUCT_FROM_DATABASE=BCM2035B3 Bluetooth Adapter
+
+usb:v0A5Cp2033*
+ ID_PRODUCT_FROM_DATABASE=BCM2033 Bluetooth
+
+usb:v0A5Cp2035*
+ ID_PRODUCT_FROM_DATABASE=BCM2035 Bluetooth
+
+usb:v0A5Cp2038*
+ ID_PRODUCT_FROM_DATABASE=Blutonium Device
+
+usb:v0A5Cp2039*
+ ID_PRODUCT_FROM_DATABASE=BCM2045 Bluetooth
+
+usb:v0A5Cp2045*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller
+
+usb:v0A5Cp2046*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A5Cp2047*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A5Cp205E*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0A5Cp2100*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0+eDR dongle
+
+usb:v0A5Cp2101*
+ ID_PRODUCT_FROM_DATABASE=BCM2045 Bluetooth
+
+usb:v0A5Cp2102*
+ ID_PRODUCT_FROM_DATABASE=ANYCOM Blue USB-200/250
+
+usb:v0A5Cp2110*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller
+
+usb:v0A5Cp2111*
+ ID_PRODUCT_FROM_DATABASE=ANYCOM Blue USB-UHE 200/250
+
+usb:v0A5Cp2120*
+ ID_PRODUCT_FROM_DATABASE=2045 Bluetooth 2.0 USB-UHE Device with trace filter
+
+usb:v0A5Cp2121*
+ ID_PRODUCT_FROM_DATABASE=BCM2210 Bluetooth
+
+usb:v0A5Cp2122*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0+EDR dongle
+
+usb:v0A5Cp2123*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth dongle
+
+usb:v0A5Cp2130*
+ ID_PRODUCT_FROM_DATABASE=2045 Bluetooth 2.0 USB-UHE Device with trace filter
+
+usb:v0A5Cp2131*
+ ID_PRODUCT_FROM_DATABASE=2045 Bluetooth 2.0 Device with trace filter
+
+usb:v0A5Cp2145*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth with Enhanced Data Rate II
+
+usb:v0A5Cp2148*
+ ID_PRODUCT_FROM_DATABASE=BCM92046DG-CL1ROM Bluetooth 2.1 Adapter
+
+usb:v0A5Cp2150*
+ ID_PRODUCT_FROM_DATABASE=BCM2046 Bluetooth Device
+
+usb:v0A5Cp2151*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth
+
+usb:v0A5Cp217D*
+ ID_PRODUCT_FROM_DATABASE=HP Bluethunder
+
+usb:v0A5Cp217F*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller
+
+usb:v0A5Cp2198*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 3.0 Device
+
+usb:v0A5Cp219B*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.1 Device
+
+usb:v0A5Cp21B1*
+ ID_PRODUCT_FROM_DATABASE=HP Bluetooth Module
+
+usb:v0A5Cp21B4*
+ ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR
+
+usb:v0A5Cp21B9*
+ ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR
+
+usb:v0A5Cp21BA*
+ ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR
+
+usb:v0A5Cp21BB*
+ ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR
+
+usb:v0A5Cp21BC*
+ ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR
+
+usb:v0A5Cp21BD*
+ ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR
+
+usb:v0A5Cp21D7*
+ ID_PRODUCT_FROM_DATABASE=BCM43142 Bluetooth 4.0
+
+usb:v0A5Cp21E1*
+ ID_PRODUCT_FROM_DATABASE=HP Portable SoftSailing
+
+usb:v0A5Cp21E3*
+ ID_PRODUCT_FROM_DATABASE=HP Portable Valentine
+
+usb:v0A5Cp21E6*
+ ID_PRODUCT_FROM_DATABASE=BCM20702 Bluetooth 4.0 [ThinkPad]
+
+usb:v0A5Cp21E8*
+ ID_PRODUCT_FROM_DATABASE=BCM20702A0 Bluetooth 4.0
+
+usb:v0A5Cp21F1*
+ ID_PRODUCT_FROM_DATABASE=HP Portable Bumble Bee
+
+usb:v0A5Cp22BE*
+ ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 3.0 + HS
+
+usb:v0A5Cp4500*
+ ID_PRODUCT_FROM_DATABASE=BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth)
+
+usb:v0A5Cp4502*
+ ID_PRODUCT_FROM_DATABASE=Keyboard (Boot Interface Subclass)
+
+usb:v0A5Cp4503*
+ ID_PRODUCT_FROM_DATABASE=Mouse (Boot Interface Subclass)
+
+usb:v0A5Cp5800*
+ ID_PRODUCT_FROM_DATABASE=BCM5880 Secure Applications Processor
+
+usb:v0A5Cp5801*
+ ID_PRODUCT_FROM_DATABASE=BCM5880 Secure Applications Processor with fingerprint swipe sensor
+
+usb:v0A5Cp5802*
+ ID_PRODUCT_FROM_DATABASE=BCM5880 Secure Applications Processor with fingerprint touch sensor
+
+usb:v0A5Cp5803*
+ ID_PRODUCT_FROM_DATABASE=BCM5880 Secure Applications Processor with secure keyboard
+
+usb:v0A5Cp6300*
+ ID_PRODUCT_FROM_DATABASE=Pirelli Remote NDIS Device
+
+usb:v0A5CpBD11*
+ ID_PRODUCT_FROM_DATABASE=TiVo AG0100 802.11bg Wireless Adapter [Broadcom BCM4320]
+
+usb:v0A5CpBD13*
+ ID_PRODUCT_FROM_DATABASE=BCM4323 802.11abgn Wireless Adapter
+
+usb:v0A5CpBD17*
+ ID_PRODUCT_FROM_DATABASE=BCM43236 802.11abgn Wireless Adapter
+
+usb:v0A5CpD11B*
+ ID_PRODUCT_FROM_DATABASE=Eminent EM4045 [Broadcom 4320 USB]
+
+usb:v0A5D*
+ ID_VENDOR_FROM_DATABASE=Diatrend Corp.
+
+usb:v0A5F*
+ ID_VENDOR_FROM_DATABASE=Zebra
+
+usb:v0A5Fp0009*
+ ID_PRODUCT_FROM_DATABASE=LP2844 Printer
+
+usb:v0A5Fp0081*
+ ID_PRODUCT_FROM_DATABASE=GK420t Label Printer
+
+usb:v0A5Fp008B*
+ ID_PRODUCT_FROM_DATABASE=HC100 wristbands Printer
+
+usb:v0A5Fp930A*
+ ID_PRODUCT_FROM_DATABASE=Printer
+
+usb:v0A62*
+ ID_VENDOR_FROM_DATABASE=MPMan
+
+usb:v0A62p0010*
+ ID_PRODUCT_FROM_DATABASE=MPMan MP-F40 MP3 Player
+
+usb:v0A66*
+ ID_VENDOR_FROM_DATABASE=ClearCube Technology
+
+usb:v0A67*
+ ID_VENDOR_FROM_DATABASE=Medeli Electronics Co., Ltd
+
+usb:v0A68*
+ ID_VENDOR_FROM_DATABASE=Comaide Corp.
+
+usb:v0A69*
+ ID_VENDOR_FROM_DATABASE=Chroma ate, Inc.
+
+usb:v0A6B*
+ ID_VENDOR_FROM_DATABASE=Green House Co., Ltd
+
+usb:v0A6Bp0001*
+ ID_PRODUCT_FROM_DATABASE=Compact Flash R/W with MP3 player
+
+usb:v0A6Bp000F*
+ ID_PRODUCT_FROM_DATABASE=FlashDisk
+
+usb:v0A6C*
+ ID_VENDOR_FROM_DATABASE=Integrated Circuit Systems, Inc.
+
+usb:v0A6D*
+ ID_VENDOR_FROM_DATABASE=UPS Manufacturing
+
+usb:v0A6E*
+ ID_VENDOR_FROM_DATABASE=Benwin
+
+usb:v0A6F*
+ ID_VENDOR_FROM_DATABASE=Core Technology, Inc.
+
+usb:v0A6Fp0400*
+ ID_PRODUCT_FROM_DATABASE=Xanboo
+
+usb:v0A70*
+ ID_VENDOR_FROM_DATABASE=International Game Technology
+
+usb:v0A71*
+ ID_VENDOR_FROM_DATABASE=VIPColor Technologies USA, Inc.
+
+usb:v0A71p0001*
+ ID_PRODUCT_FROM_DATABASE=VP485 Printer
+
+usb:v0A72*
+ ID_VENDOR_FROM_DATABASE=Sanwa Denshi
+
+usb:v0A73*
+ ID_VENDOR_FROM_DATABASE=Mackie Designs
+
+usb:v0A73p0002*
+ ID_PRODUCT_FROM_DATABASE=XD-2 [Spike]
+
+usb:v0A7D*
+ ID_VENDOR_FROM_DATABASE=NSTL, Inc.
+
+usb:v0A7E*
+ ID_VENDOR_FROM_DATABASE=Octagon Systems Corp.
+
+usb:v0A80*
+ ID_VENDOR_FROM_DATABASE=Rexon Technology Corp., Ltd
+
+usb:v0A81*
+ ID_VENDOR_FROM_DATABASE=Chesen Electronics Corp.
+
+usb:v0A81p0101*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0A81p0103*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0A81p0203*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v0A81p0205*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard+Mouse Adapter
+
+usb:v0A81p0701*
+ ID_PRODUCT_FROM_DATABASE=USB Missile Launcher
+
+usb:v0A81pFF01*
+ ID_PRODUCT_FROM_DATABASE=Wireless Missile Launcher
+
+usb:v0A82*
+ ID_VENDOR_FROM_DATABASE=Syscan
+
+usb:v0A82p4600*
+ ID_PRODUCT_FROM_DATABASE=TravelScan 460/464
+
+usb:v0A83*
+ ID_VENDOR_FROM_DATABASE=NextComm, Inc.
+
+usb:v0A84*
+ ID_VENDOR_FROM_DATABASE=Maui Innovative Peripherals
+
+usb:v0A85*
+ ID_VENDOR_FROM_DATABASE=Idexx Labs
+
+usb:v0A86*
+ ID_VENDOR_FROM_DATABASE=NITGen Co., Ltd
+
+usb:v0A8D*
+ ID_VENDOR_FROM_DATABASE=Picturetel
+
+usb:v0A8E*
+ ID_VENDOR_FROM_DATABASE=Japan Aviation Electronics Industry, Ltd
+
+usb:v0A8Ep2011*
+ ID_PRODUCT_FROM_DATABASE=Filter Driver For JAE XMC R/W
+
+usb:v0A90*
+ ID_VENDOR_FROM_DATABASE=Candy Technology Co., Ltd
+
+usb:v0A91*
+ ID_VENDOR_FROM_DATABASE=Globlink Technology, Inc.
+
+usb:v0A91p3801*
+ ID_PRODUCT_FROM_DATABASE=Targus PAKP003 Mouse
+
+usb:v0A92*
+ ID_VENDOR_FROM_DATABASE=EGO SYStems, Inc.
+
+usb:v0A92p0011*
+ ID_PRODUCT_FROM_DATABASE=SYS WaveTerminal U2A
+
+usb:v0A92p0021*
+ ID_PRODUCT_FROM_DATABASE=GIGAPort
+
+usb:v0A92p0031*
+ ID_PRODUCT_FROM_DATABASE=GIGAPortAG
+
+usb:v0A92p0053*
+ ID_PRODUCT_FROM_DATABASE=AudioTrak Optoplay
+
+usb:v0A92p0061*
+ ID_PRODUCT_FROM_DATABASE=Waveterminal U24
+
+usb:v0A92p0071*
+ ID_PRODUCT_FROM_DATABASE=MAYA EX7
+
+usb:v0A92p0091*
+ ID_PRODUCT_FROM_DATABASE=Maya 44
+
+usb:v0A92p00B1*
+ ID_PRODUCT_FROM_DATABASE=MAYA EX5
+
+usb:v0A92p1000*
+ ID_PRODUCT_FROM_DATABASE=MIDI Mate
+
+usb:v0A92p1010*
+ ID_PRODUCT_FROM_DATABASE=RoMI/O
+
+usb:v0A92p1020*
+ ID_PRODUCT_FROM_DATABASE=M4U
+
+usb:v0A92p1030*
+ ID_PRODUCT_FROM_DATABASE=M8U
+
+usb:v0A92p1090*
+ ID_PRODUCT_FROM_DATABASE=KeyControl49
+
+usb:v0A92p10A0*
+ ID_PRODUCT_FROM_DATABASE=KeyControl25
+
+usb:v0A93*
+ ID_VENDOR_FROM_DATABASE=C Technologies AB
+
+usb:v0A93p0002*
+ ID_PRODUCT_FROM_DATABASE=C-Pen 10
+
+usb:v0A93p0005*
+ ID_PRODUCT_FROM_DATABASE=MyPen Light
+
+usb:v0A93p000D*
+ ID_PRODUCT_FROM_DATABASE=Input Pen
+
+usb:v0A93p0010*
+ ID_PRODUCT_FROM_DATABASE=C-Pen 20
+
+usb:v0A93p0A93*
+ ID_PRODUCT_FROM_DATABASE=PayPen
+
+usb:v0A94*
+ ID_VENDOR_FROM_DATABASE=Intersense
+
+usb:v0AA3*
+ ID_VENDOR_FROM_DATABASE=Lava Computer Mfg., Inc.
+
+usb:v0AA4*
+ ID_VENDOR_FROM_DATABASE=Develco Elektronik
+
+usb:v0AA5*
+ ID_VENDOR_FROM_DATABASE=First International Digital
+
+usb:v0AA5p0002*
+ ID_PRODUCT_FROM_DATABASE=irock! 500 Series
+
+usb:v0AA5p0801*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0AA6*
+ ID_VENDOR_FROM_DATABASE=Perception Digital, Ltd
+
+usb:v0AA6p0101*
+ ID_PRODUCT_FROM_DATABASE=Hercules Jukebox
+
+usb:v0AA6p1501*
+ ID_PRODUCT_FROM_DATABASE=Store 'n' Go HD Drive
+
+usb:v0AA7*
+ ID_VENDOR_FROM_DATABASE=Wincor Nixdorf International GmbH
+
+usb:v0AA7p0100*
+ ID_PRODUCT_FROM_DATABASE=POS Keyboard, TA58P-USB
+
+usb:v0AA7p0101*
+ ID_PRODUCT_FROM_DATABASE=POS Keyboard, TA85P-USB
+
+usb:v0AA7p0102*
+ ID_PRODUCT_FROM_DATABASE=POS Keyboard, TA59-USB
+
+usb:v0AA7p0103*
+ ID_PRODUCT_FROM_DATABASE=POS Keyboard, TA60-USB
+
+usb:v0AA7p0104*
+ ID_PRODUCT_FROM_DATABASE=SNIkey Keyboard, SNIKey-KB-USB
+
+usb:v0AA7p0200*
+ ID_PRODUCT_FROM_DATABASE=Operator Display, BA63-USB
+
+usb:v0AA7p0201*
+ ID_PRODUCT_FROM_DATABASE=Operator Display, BA66-USB
+
+usb:v0AA7p0202*
+ ID_PRODUCT_FROM_DATABASE=Operator Display & Scanner, XiCheck-BA63
+
+usb:v0AA7p0203*
+ ID_PRODUCT_FROM_DATABASE=Operator Display & Scanner, XiCheck-BA66
+
+usb:v0AA7p0204*
+ ID_PRODUCT_FROM_DATABASE=Graphics Operator Display, BA63GV
+
+usb:v0AA7p0300*
+ ID_PRODUCT_FROM_DATABASE=POS Printer (printer class mode), TH210
+
+usb:v0AA7p0301*
+ ID_PRODUCT_FROM_DATABASE=POS Printer (native mode), TH210
+
+usb:v0AA7p0302*
+ ID_PRODUCT_FROM_DATABASE=POS Printer (printer class mode), TH220
+
+usb:v0AA7p0303*
+ ID_PRODUCT_FROM_DATABASE=POS Printer (native mode), TH220
+
+usb:v0AA7p0304*
+ ID_PRODUCT_FROM_DATABASE=POS Printer, TH230
+
+usb:v0AA7p0305*
+ ID_PRODUCT_FROM_DATABASE=Lottery Printer, XiPrintPlus
+
+usb:v0AA7p0306*
+ ID_PRODUCT_FROM_DATABASE=POS Printer (printer class mode), TH320
+
+usb:v0AA7p0307*
+ ID_PRODUCT_FROM_DATABASE=POS Printer (native mode), TH320
+
+usb:v0AA7p0308*
+ ID_PRODUCT_FROM_DATABASE=POS Printer (printer class mode), TH420
+
+usb:v0AA7p0309*
+ ID_PRODUCT_FROM_DATABASE=POS Printer (native mode), TH420
+
+usb:v0AA7p030A*
+ ID_PRODUCT_FROM_DATABASE=POS Printer, TH200B
+
+usb:v0AA7p0400*
+ ID_PRODUCT_FROM_DATABASE=Lottery Scanner, Xiscan S
+
+usb:v0AA7p0401*
+ ID_PRODUCT_FROM_DATABASE=Lottery Scanner, Xiscan 3
+
+usb:v0AA7p0402*
+ ID_PRODUCT_FROM_DATABASE=Programmable Magnetic Swipe Card Reader, MSRP-USB
+
+usb:v0AA7p0500*
+ ID_PRODUCT_FROM_DATABASE=IDE Adapter
+
+usb:v0AA7p0501*
+ ID_PRODUCT_FROM_DATABASE=Hub Printer Interface
+
+usb:v0AA7p0502*
+ ID_PRODUCT_FROM_DATABASE=Hub SNIKey Keyboard
+
+usb:v0AA7p4304*
+ ID_PRODUCT_FROM_DATABASE=Banking Printer TP07
+
+usb:v0AA7p4305*
+ ID_PRODUCT_FROM_DATABASE=Banking Printer TP07c
+
+usb:v0AA7p4500*
+ ID_PRODUCT_FROM_DATABASE=WN Central Special Electronics
+
+usb:v0AA8*
+ ID_VENDOR_FROM_DATABASE=TriGem Computer, Inc.
+
+usb:v0AA8p0060*
+ ID_PRODUCT_FROM_DATABASE=TG 11Mbps WLAN Mini Adapter
+
+usb:v0AA8p1001*
+ ID_PRODUCT_FROM_DATABASE=DreamComboM4100
+
+usb:v0AA8p3002*
+ ID_PRODUCT_FROM_DATABASE=InkJet Color Printer
+
+usb:v0AA8p8001*
+ ID_PRODUCT_FROM_DATABASE=TG_iMON
+
+usb:v0AA8p8002*
+ ID_PRODUCT_FROM_DATABASE=TG_KLOSS
+
+usb:v0AA8pA001*
+ ID_PRODUCT_FROM_DATABASE=TG_X2
+
+usb:v0AA8pA002*
+ ID_PRODUCT_FROM_DATABASE=TGVFD_KLOSS
+
+usb:v0AA8pFFDA*
+ ID_PRODUCT_FROM_DATABASE=iMON_VFD
+
+usb:v0AA9*
+ ID_VENDOR_FROM_DATABASE=Baromtec Co.
+
+usb:v0AA9pF01B*
+ ID_PRODUCT_FROM_DATABASE=Medion MD 6242 MP3 Player
+
+usb:v0AAA*
+ ID_VENDOR_FROM_DATABASE=Japan CBM Corp.
+
+usb:v0AAB*
+ ID_VENDOR_FROM_DATABASE=Vision Shape Europe SA
+
+usb:v0AAC*
+ ID_VENDOR_FROM_DATABASE=iCompression, Inc.
+
+usb:v0AAD*
+ ID_VENDOR_FROM_DATABASE=Rohde & Schwarz GmbH & Co. KG
+
+usb:v0AADp0003*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z21
+
+usb:v0AADp000C*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z11
+
+usb:v0AADp0013*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z22
+
+usb:v0AADp0014*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z23
+
+usb:v0AADp0015*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z24
+
+usb:v0AADp0016*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z51
+
+usb:v0AADp0017*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z52
+
+usb:v0AADp0018*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z55
+
+usb:v0AADp0019*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z56
+
+usb:v0AADp0021*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z91
+
+usb:v0AADp0023*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z81
+
+usb:v0AADp002C*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z31
+
+usb:v0AADp002D*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z37
+
+usb:v0AADp002F*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z27
+
+usb:v0AADp0051*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z28
+
+usb:v0AADp0052*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z98
+
+usb:v0AADp0062*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z92
+
+usb:v0AADp0070*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z57
+
+usb:v0AADp0083*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z85
+
+usb:v0AADp0095*
+ ID_PRODUCT_FROM_DATABASE=NRP-Z86
+
+usb:v0AAE*
+ ID_VENDOR_FROM_DATABASE=NEC infrontia Corp. (Nitsuko)
+
+usb:v0AAF*
+ ID_VENDOR_FROM_DATABASE=Digitalway Co., Ltd
+
+usb:v0AB0*
+ ID_VENDOR_FROM_DATABASE=Arrow Strong Electronics Co., Ltd
+
+usb:v0AB1*
+ ID_VENDOR_FROM_DATABASE=FEIG ELECTRONIC GmbH
+
+usb:v0AB1p0002*
+ ID_PRODUCT_FROM_DATABASE=OBID RFID-Reader
+
+usb:v0ABA*
+ ID_VENDOR_FROM_DATABASE=Ellisys
+
+usb:v0ABAp8001*
+ ID_PRODUCT_FROM_DATABASE=Tracker 110 Protocol Analyzer
+
+usb:v0ABAp8002*
+ ID_PRODUCT_FROM_DATABASE=Explorer 200 Protocol Analyzer
+
+usb:v0ABE*
+ ID_VENDOR_FROM_DATABASE=Stereo-Link
+
+usb:v0ABEp0101*
+ ID_PRODUCT_FROM_DATABASE=SL1200 DAC
+
+usb:v0ABF*
+ ID_VENDOR_FROM_DATABASE=Diolan
+
+usb:v0ABFp3370*
+ ID_PRODUCT_FROM_DATABASE=I2C/SPI Adapter - U2C-12
+
+usb:v0AC3*
+ ID_VENDOR_FROM_DATABASE=Sanyo Semiconductor Company Micro
+
+usb:v0AC4*
+ ID_VENDOR_FROM_DATABASE=Leco Corp.
+
+usb:v0AC5*
+ ID_VENDOR_FROM_DATABASE=I & C Corp.
+
+usb:v0AC6*
+ ID_VENDOR_FROM_DATABASE=Singing Electrons, Inc.
+
+usb:v0AC7*
+ ID_VENDOR_FROM_DATABASE=Panwest Corp.
+
+usb:v0AC8*
+ ID_VENDOR_FROM_DATABASE=Z-Star Microelectronics Corp.
+
+usb:v0AC8p0301*
+ ID_PRODUCT_FROM_DATABASE=Web Camera
+
+usb:v0AC8p0302*
+ ID_PRODUCT_FROM_DATABASE=ZC0302 Webcam
+
+usb:v0AC8p0321*
+ ID_PRODUCT_FROM_DATABASE=Vimicro generic vc0321 Camera
+
+usb:v0AC8p0323*
+ ID_PRODUCT_FROM_DATABASE=Luxya WC-1200 USB 2.0 Webcam
+
+usb:v0AC8p0328*
+ ID_PRODUCT_FROM_DATABASE=A4Tech PK-130MG
+
+usb:v0AC8p0336*
+ ID_PRODUCT_FROM_DATABASE=Elecom UCAM-DLQ30
+
+usb:v0AC8p301B*
+ ID_PRODUCT_FROM_DATABASE=ZC0301 Webcam
+
+usb:v0AC8p303B*
+ ID_PRODUCT_FROM_DATABASE=ZC0303 Webcam
+
+usb:v0AC8p305B*
+ ID_PRODUCT_FROM_DATABASE=ZC0305 Webcam
+
+usb:v0AC8p307B*
+ ID_PRODUCT_FROM_DATABASE=USB 1.1 Webcam
+
+usb:v0AC8p332D*
+ ID_PRODUCT_FROM_DATABASE=Vega USB 2.0 Camera
+
+usb:v0AC8p3343*
+ ID_PRODUCT_FROM_DATABASE=Sirius USB 2.0 Camera
+
+usb:v0AC8p3370*
+ ID_PRODUCT_FROM_DATABASE=Traveler TV 6500 SF Dia-scanner
+
+usb:v0AC8p3420*
+ ID_PRODUCT_FROM_DATABASE=Venus USB2.0 Camera
+
+usb:v0AC8pC001*
+ ID_PRODUCT_FROM_DATABASE=Sony embedded vimicro Camera
+
+usb:v0AC8pC002*
+ ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC1
+
+usb:v0AC8pC302*
+ ID_PRODUCT_FROM_DATABASE=Vega USB 2.0 Camera
+
+usb:v0AC8pC303*
+ ID_PRODUCT_FROM_DATABASE=Saturn USB 2.0 Camera
+
+usb:v0AC8pC326*
+ ID_PRODUCT_FROM_DATABASE=Namuga 1.3M Webcam
+
+usb:v0AC8pC33F*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v0AC9*
+ ID_VENDOR_FROM_DATABASE=Micro Solutions, Inc.
+
+usb:v0AC9p0000*
+ ID_PRODUCT_FROM_DATABASE=Backpack CD-ReWriter
+
+usb:v0AC9p0001*
+ ID_PRODUCT_FROM_DATABASE=BACKPACK  2 Cable
+
+usb:v0AC9p0010*
+ ID_PRODUCT_FROM_DATABASE=BACKPACK
+
+usb:v0AC9p0011*
+ ID_PRODUCT_FROM_DATABASE=Backpack 40GB Hard Drive
+
+usb:v0AC9p0110*
+ ID_PRODUCT_FROM_DATABASE=BACKPACK
+
+usb:v0AC9p0111*
+ ID_PRODUCT_FROM_DATABASE=BackPack
+
+usb:v0AC9p1234*
+ ID_PRODUCT_FROM_DATABASE=BACKPACK
+
+usb:v0ACA*
+ ID_VENDOR_FROM_DATABASE=OPEN Networks Ltd
+
+usb:v0ACAp1060*
+ ID_PRODUCT_FROM_DATABASE=OPEN NT1 Plus II
+
+usb:v0ACC*
+ ID_VENDOR_FROM_DATABASE=Koga Electronics Co.
+
+usb:v0ACD*
+ ID_VENDOR_FROM_DATABASE=ID Tech
+
+usb:v0ACDp0300*
+ ID_PRODUCT_FROM_DATABASE=IDT1221U RS-232 Adapter
+
+usb:v0ACDp0401*
+ ID_PRODUCT_FROM_DATABASE=Spectrum III Hybrid Smartcard Reader
+
+usb:v0ACDp0630*
+ ID_PRODUCT_FROM_DATABASE=Spectrum III Mag-Only Insert Reader (SPT3-355 Series) USB-CDC
+
+usb:v0ACE*
+ ID_VENDOR_FROM_DATABASE=ZyDAS
+
+usb:v0ACEp1201*
+ ID_PRODUCT_FROM_DATABASE=ZD1201 802.11b
+
+usb:v0ACEp1211*
+ ID_PRODUCT_FROM_DATABASE=ZD1211 802.11g
+
+usb:v0ACEp1215*
+ ID_PRODUCT_FROM_DATABASE=ZD1211B 802.11g
+
+usb:v0ACEp1221*
+ ID_PRODUCT_FROM_DATABASE=ZD1221 802.11n
+
+usb:v0ACEp1602*
+ ID_PRODUCT_FROM_DATABASE=ZyXEL Omni FaxModem 56K
+
+usb:v0ACEp1608*
+ ID_PRODUCT_FROM_DATABASE=ZyXEL Omni FaxModem 56K UNO
+
+usb:v0ACEp1611*
+ ID_PRODUCT_FROM_DATABASE=ZyXEL Omni FaxModem 56K Plus
+
+usb:v0ACEp2011*
+ ID_PRODUCT_FROM_DATABASE=Virtual media for 802.11bg
+
+usb:v0ACEp20FF*
+ ID_PRODUCT_FROM_DATABASE=Virtual media for 802.11bg
+
+usb:v0ACEpA211*
+ ID_PRODUCT_FROM_DATABASE=ZD1211 802.11b/g Wireless Adapter
+
+usb:v0ACEpB215*
+ ID_PRODUCT_FROM_DATABASE=802.11bg
+
+usb:v0ACF*
+ ID_VENDOR_FROM_DATABASE=Intoto, Inc.
+
+usb:v0AD0*
+ ID_VENDOR_FROM_DATABASE=Intellix Corp.
+
+usb:v0AD1*
+ ID_VENDOR_FROM_DATABASE=Remotec Technology, Ltd
+
+usb:v0AD2*
+ ID_VENDOR_FROM_DATABASE=Service & Quality Technology Co., Ltd
+
+usb:v0ADA*
+ ID_VENDOR_FROM_DATABASE=Data Encryption Systems Ltd.
+
+usb:v0ADAp0005*
+ ID_PRODUCT_FROM_DATABASE=DK2
+
+usb:v0AE3*
+ ID_VENDOR_FROM_DATABASE=Allion Computer, Inc.
+
+usb:v0AE4*
+ ID_VENDOR_FROM_DATABASE=Taito Corp.
+
+usb:v0AE7*
+ ID_VENDOR_FROM_DATABASE=Neodym Systems, Inc.
+
+usb:v0AE8*
+ ID_VENDOR_FROM_DATABASE=System Support Co., Ltd
+
+usb:v0AE9*
+ ID_VENDOR_FROM_DATABASE=North Shore Circuit Design L.L.P.
+
+usb:v0AEA*
+ ID_VENDOR_FROM_DATABASE=SciEssence, LLC
+
+usb:v0AEB*
+ ID_VENDOR_FROM_DATABASE=TTP Communications, Ltd
+
+usb:v0AEC*
+ ID_VENDOR_FROM_DATABASE=Neodio Technologies Corp.
+
+usb:v0AECp2101*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia Card Reader
+
+usb:v0AECp2102*
+ ID_PRODUCT_FROM_DATABASE=CompactFlash Card Reader
+
+usb:v0AECp2103*
+ ID_PRODUCT_FROM_DATABASE=MMC/SD Card Reader
+
+usb:v0AECp2104*
+ ID_PRODUCT_FROM_DATABASE=MemoryStick Card Reader
+
+usb:v0AECp2201*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia+CompactFlash Card Reader
+
+usb:v0AECp2202*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia+MMC/SD Card Reader
+
+usb:v0AECp2203*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia+MemoryStick Card Reader
+
+usb:v0AECp2204*
+ ID_PRODUCT_FROM_DATABASE=CompactFlash+MMC/SD Card Reader
+
+usb:v0AECp2205*
+ ID_PRODUCT_FROM_DATABASE=CompactFlash+MemoryStick Card Reader
+
+usb:v0AECp2206*
+ ID_PRODUCT_FROM_DATABASE=MMC/SD+MemoryStick Card Reader
+
+usb:v0AECp2301*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia+CompactFlash+MMC/SD Card Reader
+
+usb:v0AECp2302*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia+CompactFlash+MemoryStick Card Reader
+
+usb:v0AECp2303*
+ ID_PRODUCT_FROM_DATABASE=SmartMedia+MMC/SD+MemoryStick Card Reader
+
+usb:v0AECp2304*
+ ID_PRODUCT_FROM_DATABASE=CompactFlash+MMC/SD+MemoryStick Card Reader
+
+usb:v0AECp3016*
+ ID_PRODUCT_FROM_DATABASE=MMC/SD+Memory Stick Card Reader
+
+usb:v0AECp3050*
+ ID_PRODUCT_FROM_DATABASE=ND3050 8-in-1 Card Reader
+
+usb:v0AECp3060*
+ ID_PRODUCT_FROM_DATABASE=1.1 FS Card Reader
+
+usb:v0AECp3101*
+ ID_PRODUCT_FROM_DATABASE=MMC/SD Card Reader
+
+usb:v0AECp3102*
+ ID_PRODUCT_FROM_DATABASE=MemoryStick Card Reader
+
+usb:v0AECp3201*
+ ID_PRODUCT_FROM_DATABASE=MMC/SD+MemoryStick Card Reader
+
+usb:v0AECp3216*
+ ID_PRODUCT_FROM_DATABASE=HS Card Reader
+
+usb:v0AECp3260*
+ ID_PRODUCT_FROM_DATABASE=7-in-1 Card Reader
+
+usb:v0AECp5010*
+ ID_PRODUCT_FROM_DATABASE=ND5010 Card Reader
+
+usb:v0AF0*
+ ID_VENDOR_FROM_DATABASE=Option
+
+usb:v0AF0p5000*
+ ID_PRODUCT_FROM_DATABASE=UMTS Card
+
+usb:v0AF0p6000*
+ ID_PRODUCT_FROM_DATABASE=GlobeTrotter 3G datacard
+
+usb:v0AF0p6300*
+ ID_PRODUCT_FROM_DATABASE=GT 3G Quad UMTS/GPRS Card
+
+usb:v0AF0p6600*
+ ID_PRODUCT_FROM_DATABASE=GlobeTrotter 3G+ datacard
+
+usb:v0AF0p6711*
+ ID_PRODUCT_FROM_DATABASE=GlobeTrotter Express 7.2 v2
+
+usb:v0AF0p6971*
+ ID_PRODUCT_FROM_DATABASE=Globetrotter HSDPA Modem
+
+usb:v0AF0p7251*
+ ID_PRODUCT_FROM_DATABASE=Globetrotter HSUPA Modem (aka iCON HSUPA E)
+
+usb:v0AF0p7501*
+ ID_PRODUCT_FROM_DATABASE=Globetrotter HSUPA Modem (icon 411 aka "Vodafone K3760")
+
+usb:v0AF0p7601*
+ ID_PRODUCT_FROM_DATABASE=Globetrotter MO40x 3G Modem (GTM 382)
+
+usb:v0AF0p7701*
+ ID_PRODUCT_FROM_DATABASE=Globetrotter HSUPA Modem (aka icon 451)
+
+usb:v0AF0pD055*
+ ID_PRODUCT_FROM_DATABASE=Globetrotter GI0505 [iCON 505]
+
+usb:v0AF6*
+ ID_VENDOR_FROM_DATABASE=Silver I Co., Ltd
+
+usb:v0AF7*
+ ID_VENDOR_FROM_DATABASE=B2C2, Inc.
+
+usb:v0AF7p0101*
+ ID_PRODUCT_FROM_DATABASE=Digital TV USB Receiver (DVB-S/T/C / ATSC)
+
+usb:v0AF9*
+ ID_VENDOR_FROM_DATABASE=Hama, Inc.
+
+usb:v0AF9p0010*
+ ID_PRODUCT_FROM_DATABASE=USB SightCam 100
+
+usb:v0AF9p0011*
+ ID_PRODUCT_FROM_DATABASE=Micro Innovations IC50C Webcam
+
+usb:v0AFC*
+ ID_VENDOR_FROM_DATABASE=Zaptronix Ltd
+
+usb:v0AFD*
+ ID_VENDOR_FROM_DATABASE=Tateno Dennou, Inc.
+
+usb:v0AFE*
+ ID_VENDOR_FROM_DATABASE=Cummins Engine Co.
+
+usb:v0AFF*
+ ID_VENDOR_FROM_DATABASE=Jump Zone Network Products, Inc.
+
+usb:v0B00*
+ ID_VENDOR_FROM_DATABASE=INGENICO
+
+usb:v0B05*
+ ID_VENDOR_FROM_DATABASE=ASUSTek Computer, Inc.
+
+usb:v0B05p1101*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC4S)
+
+usb:v0B05p1706*
+ ID_PRODUCT_FROM_DATABASE=WL-167G v1 802.11g Adapter [Ralink RT2571]
+
+usb:v0B05p1707*
+ ID_PRODUCT_FROM_DATABASE=WL-167G v1 802.11g Adapter [Ralink RT2571]
+
+usb:v0B05p1708*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0B05p170B*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0B05p170C*
+ ID_PRODUCT_FROM_DATABASE=WL-159g 802.11bg
+
+usb:v0B05p170D*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g Wireless Network Adapter
+
+usb:v0B05p1712*
+ ID_PRODUCT_FROM_DATABASE=BT-183 Bluetooth 2.0+EDR adapter
+
+usb:v0B05p1715*
+ ID_PRODUCT_FROM_DATABASE=2045 Bluetooth 2.0 Device with trace filter
+
+usb:v0B05p1716*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0B05p1717*
+ ID_PRODUCT_FROM_DATABASE=WL169gE 802.11g Adapter [Broadcom 4320 USB]
+
+usb:v0B05p171B*
+ ID_PRODUCT_FROM_DATABASE=A9T wireless 802.11bg
+
+usb:v0B05p171C*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g Wireless Network Adapter
+
+usb:v0B05p171F*
+ ID_PRODUCT_FROM_DATABASE=My Cinema U3000 Mini [DiBcom DiB7700P]
+
+usb:v0B05p1723*
+ ID_PRODUCT_FROM_DATABASE=WL-167G v2 802.11g Adapter [Ralink RT2571W]
+
+usb:v0B05p1724*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v0B05p1726*
+ ID_PRODUCT_FROM_DATABASE=Laptop OLED Display
+
+usb:v0B05p172A*
+ ID_PRODUCT_FROM_DATABASE=ASUS 802.11n Network Adapter
+
+usb:v0B05p172B*
+ ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter
+
+usb:v0B05p1731*
+ ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter
+
+usb:v0B05p1732*
+ ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter
+
+usb:v0B05p1734*
+ ID_PRODUCT_FROM_DATABASE=ASUS AF-200
+
+usb:v0B05p173C*
+ ID_PRODUCT_FROM_DATABASE=BT-183 Bluetooth 2.0
+
+usb:v0B05p173F*
+ ID_PRODUCT_FROM_DATABASE=My Cinema U3100 Mini
+
+usb:v0B05p1742*
+ ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter
+
+usb:v0B05p1743*
+ ID_PRODUCT_FROM_DATABASE=Xonar U1 Audio Station
+
+usb:v0B05p1751*
+ ID_PRODUCT_FROM_DATABASE=BT-253 Bluetooth Adapter
+
+usb:v0B05p175B*
+ ID_PRODUCT_FROM_DATABASE=Laptop OLED Display
+
+usb:v0B05p1760*
+ ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter
+
+usb:v0B05p1761*
+ ID_PRODUCT_FROM_DATABASE=USB-N11 802.11n Network Adapter [Ralink RT2870]
+
+usb:v0B05p1774*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v0B05p1776*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v0B05p1779*
+ ID_PRODUCT_FROM_DATABASE=My Cinema U3100 Mini Plus [AF9035A]
+
+usb:v0B05p1784*
+ ID_PRODUCT_FROM_DATABASE=USB-N13 802.11n Network Adapter (rev. A1) [Ralink RT3072]
+
+usb:v0B05p1786*
+ ID_PRODUCT_FROM_DATABASE=USB-N10 802.11n Network Adapter [Realtek RTL8188SU]
+
+usb:v0B05p1791*
+ ID_PRODUCT_FROM_DATABASE=WL-167G v3 802.11n Adapter [Realtek RTL8188SU]
+
+usb:v0B05p179D*
+ ID_PRODUCT_FROM_DATABASE=USB-N53 802.11abgn Network Adapter [Ralink RT3572]
+
+usb:v0B05p179E*
+ ID_PRODUCT_FROM_DATABASE=Eee Note EA800 (network mode)
+
+usb:v0B05p179F*
+ ID_PRODUCT_FROM_DATABASE=Eee Note EA800 (tablet mode)
+
+usb:v0B05p17A1*
+ ID_PRODUCT_FROM_DATABASE=Eee Note EA800 (mass storage mode)
+
+usb:v0B05p17AB*
+ ID_PRODUCT_FROM_DATABASE=USB-N13 802.11n Network Adapter (rev. B1) [Realtek RTL8192CU]
+
+usb:v0B05p4C80*
+ ID_PRODUCT_FROM_DATABASE=Transformer Pad TF300TG
+
+usb:v0B05p4C90*
+ ID_PRODUCT_FROM_DATABASE=Transformer Pad Infinity TF700
+
+usb:v0B05p4C91*
+ ID_PRODUCT_FROM_DATABASE=Transformer Pad Infinity TF700 (Debug mode)
+
+usb:v0B05p4D00*
+ ID_PRODUCT_FROM_DATABASE=Transformer Prime TF201
+
+usb:v0B05p4D01*
+ ID_PRODUCT_FROM_DATABASE=Transformer Prime TF201 (debug mode)
+
+usb:v0B05p4DAF*
+ ID_PRODUCT_FROM_DATABASE=Transformer Pad Infinity TF700 (Fastboot)
+
+usb:v0B05p6101*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v0B05p620A*
+ ID_PRODUCT_FROM_DATABASE=Remote NDIS Device
+
+usb:v0B05pB700*
+ ID_PRODUCT_FROM_DATABASE=Broadcom Bluetooth 2.1
+
+usb:v0B0B*
+ ID_VENDOR_FROM_DATABASE=Datamax-O'Neil
+
+usb:v0B0Bp106E*
+ ID_PRODUCT_FROM_DATABASE=Datamax E-4304
+
+usb:v0B0C*
+ ID_VENDOR_FROM_DATABASE=Todos AB
+
+usb:v0B0Cp0009*
+ ID_PRODUCT_FROM_DATABASE=Todos Argos Mini II Smart Card Reader
+
+usb:v0B0Cp001E*
+ ID_PRODUCT_FROM_DATABASE=e.dentifier2 (ABN AMRO electronic banking card reader NL)
+
+usb:v0B0Cp002E*
+ ID_PRODUCT_FROM_DATABASE=C200 smartcard controller (Nordea card reader)
+
+usb:v0B0Cp003F*
+ ID_PRODUCT_FROM_DATABASE=Todos C400 smartcard controller (Handelsbanken card reader)
+
+usb:v0B0Cp0050*
+ ID_PRODUCT_FROM_DATABASE=Argos Mini II Smart Card Reader (CCID)
+
+usb:v0B0D*
+ ID_VENDOR_FROM_DATABASE=ProjectLab
+
+usb:v0B0Dp0000*
+ ID_PRODUCT_FROM_DATABASE=CenturyCD
+
+usb:v0B0E*
+ ID_VENDOR_FROM_DATABASE=GN Netcom
+
+usb:v0B0Ep1022*
+ ID_PRODUCT_FROM_DATABASE=Jabra PRO 9450, Type 9400BS (DECT Headset)
+
+usb:v0B0F*
+ ID_VENDOR_FROM_DATABASE=AVID Technology
+
+usb:v0B10*
+ ID_VENDOR_FROM_DATABASE=Pcally
+
+usb:v0B11*
+ ID_VENDOR_FROM_DATABASE=I Tech Solutions Co., Ltd
+
+usb:v0B1E*
+ ID_VENDOR_FROM_DATABASE=Electronic Warfare Assoc., Inc. (EWA)
+
+usb:v0B1Ep8007*
+ ID_PRODUCT_FROM_DATABASE=Blackhawk USB560-BP JTAG Emulator
+
+usb:v0B1F*
+ ID_VENDOR_FROM_DATABASE=Insyde Software Corp.
+
+usb:v0B20*
+ ID_VENDOR_FROM_DATABASE=TransDimension, Inc.
+
+usb:v0B21*
+ ID_VENDOR_FROM_DATABASE=Yokogawa Electric Corp.
+
+usb:v0B22*
+ ID_VENDOR_FROM_DATABASE=Japan System Development Co., Ltd
+
+usb:v0B23*
+ ID_VENDOR_FROM_DATABASE=Pan-Asia Electronics Co., Ltd
+
+usb:v0B24*
+ ID_VENDOR_FROM_DATABASE=Link Evolution Corp.
+
+usb:v0B27*
+ ID_VENDOR_FROM_DATABASE=Ritek Corp.
+
+usb:v0B28*
+ ID_VENDOR_FROM_DATABASE=Kenwood Corp.
+
+usb:v0B2C*
+ ID_VENDOR_FROM_DATABASE=Village Center, Inc.
+
+usb:v0B30*
+ ID_VENDOR_FROM_DATABASE=PNY Technologies, Inc.
+
+usb:v0B30p0006*
+ ID_PRODUCT_FROM_DATABASE=SM Media-Shuttle Card Reader
+
+usb:v0B33*
+ ID_VENDOR_FROM_DATABASE=Contour Design, Inc.
+
+usb:v0B33p0020*
+ ID_PRODUCT_FROM_DATABASE=ShuttleXpress
+
+usb:v0B37*
+ ID_VENDOR_FROM_DATABASE=Hitachi ULSI Systems Co., Ltd
+
+usb:v0B38*
+ ID_VENDOR_FROM_DATABASE=Gear Head
+
+usb:v0B38p0003*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0B38p0010*
+ ID_PRODUCT_FROM_DATABASE=107-Key Keyboard
+
+usb:v0B39*
+ ID_VENDOR_FROM_DATABASE=Omnidirectional Control Technology, Inc.
+
+usb:v0B39p0001*
+ ID_PRODUCT_FROM_DATABASE=Composite USB PS2 Converter
+
+usb:v0B39p0109*
+ ID_PRODUCT_FROM_DATABASE=USB TO Ethernet
+
+usb:v0B39p0421*
+ ID_PRODUCT_FROM_DATABASE=Serial
+
+usb:v0B39p0801*
+ ID_PRODUCT_FROM_DATABASE=USB-Parallel Bridge
+
+usb:v0B39p0901*
+ ID_PRODUCT_FROM_DATABASE=OCT To Fast Ethernet Converter
+
+usb:v0B39p0C03*
+ ID_PRODUCT_FROM_DATABASE=LAN DOCK Serial Converter
+
+usb:v0B3A*
+ ID_VENDOR_FROM_DATABASE=IPaxess
+
+usb:v0B3B*
+ ID_VENDOR_FROM_DATABASE=Tekram Technology Co., Ltd
+
+usb:v0B3Bp0163*
+ ID_PRODUCT_FROM_DATABASE=TL-WN320G 1.0 WLAN Adapter
+
+usb:v0B3Bp1601*
+ ID_PRODUCT_FROM_DATABASE=Allnet 0193 802.11b Adapter
+
+usb:v0B3Bp1602*
+ ID_PRODUCT_FROM_DATABASE=ZyXEL ZyAIR B200 802.11b Adapter
+
+usb:v0B3Bp1612*
+ ID_PRODUCT_FROM_DATABASE=AIR.Mate 2@net 802.11b Adapter
+
+usb:v0B3Bp1613*
+ ID_PRODUCT_FROM_DATABASE=802.11b Wireless LAN Adapter
+
+usb:v0B3Bp1620*
+ ID_PRODUCT_FROM_DATABASE=Allnet Wireless Network Adapter [Envara WiND512]
+
+usb:v0B3Bp1630*
+ ID_PRODUCT_FROM_DATABASE=QuickWLAN 802.11bg
+
+usb:v0B3Bp5630*
+ ID_PRODUCT_FROM_DATABASE=802.11bg
+
+usb:v0B3Bp6630*
+ ID_PRODUCT_FROM_DATABASE=ZD1211
+
+usb:v0B3C*
+ ID_VENDOR_FROM_DATABASE=Olivetti Techcenter
+
+usb:v0B3CpA010*
+ ID_PRODUCT_FROM_DATABASE=Simple_Way Printer/Scanner/Copier
+
+usb:v0B3CpC000*
+ ID_PRODUCT_FROM_DATABASE=Olicard 100
+
+usb:v0B3CpC700*
+ ID_PRODUCT_FROM_DATABASE=Olicard 100 (Mass Storage mode)
+
+usb:v0B3E*
+ ID_VENDOR_FROM_DATABASE=Kikusui Electronics Corp.
+
+usb:v0B41*
+ ID_VENDOR_FROM_DATABASE=Hal Corp.
+
+usb:v0B41p0011*
+ ID_PRODUCT_FROM_DATABASE=Crossam2+USB IR commander
+
+usb:v0B43*
+ ID_VENDOR_FROM_DATABASE=Play.com, Inc.
+
+usb:v0B43p0003*
+ ID_PRODUCT_FROM_DATABASE=PS2 Controller Converter
+
+usb:v0B43p0005*
+ ID_PRODUCT_FROM_DATABASE=GameCube Adaptor
+
+usb:v0B47*
+ ID_VENDOR_FROM_DATABASE=Sportbug.com, Inc.
+
+usb:v0B48*
+ ID_VENDOR_FROM_DATABASE=TechnoTrend AG
+
+usb:v0B48p1003*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge USB-Nova
+
+usb:v0B48p1004*
+ ID_PRODUCT_FROM_DATABASE=TT-PCline
+
+usb:v0B48p1005*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge USB-Nova
+
+usb:v0B48p1006*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DEC3000-s
+
+usb:v0B48p1007*
+ ID_PRODUCT_FROM_DATABASE=TT-micro plus Device
+
+usb:v0B48p1008*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DEC2000-t
+
+usb:v0B48p1009*
+ ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DEC2540-t
+
+usb:v0B48p3001*
+ ID_PRODUCT_FROM_DATABASE=DVB-S receiver
+
+usb:v0B48p3002*
+ ID_PRODUCT_FROM_DATABASE=DVB-C receiver
+
+usb:v0B48p3003*
+ ID_PRODUCT_FROM_DATABASE=DVB-T receiver
+
+usb:v0B48p3004*
+ ID_PRODUCT_FROM_DATABASE=TT TV-Stick
+
+usb:v0B48p3005*
+ ID_PRODUCT_FROM_DATABASE=TT TV-Stick (8kB EEPROM)
+
+usb:v0B48p3006*
+ ID_PRODUCT_FROM_DATABASE=TT-connect S-2400 DVB-S receiver
+
+usb:v0B48p3007*
+ ID_PRODUCT_FROM_DATABASE=TT-connect S2-3600
+
+usb:v0B48p3008*
+ ID_PRODUCT_FROM_DATABASE=TT-connect
+
+usb:v0B48p3009*
+ ID_PRODUCT_FROM_DATABASE=TT-connect S-2400 DVB-S receiver (8kB EEPROM)
+
+usb:v0B48p300A*
+ ID_PRODUCT_FROM_DATABASE=TT-connect S2-3650 CI
+
+usb:v0B48p300B*
+ ID_PRODUCT_FROM_DATABASE=TT-connect C-3650 CI
+
+usb:v0B48p300C*
+ ID_PRODUCT_FROM_DATABASE=TT-connect T-3650 CI
+
+usb:v0B48p300D*
+ ID_PRODUCT_FROM_DATABASE=TT-connect CT-3650 CI
+
+usb:v0B48p300E*
+ ID_PRODUCT_FROM_DATABASE=TT-connect C-2400
+
+usb:v0B49*
+ ID_VENDOR_FROM_DATABASE=ASCII Corp.
+
+usb:v0B49p064F*
+ ID_PRODUCT_FROM_DATABASE=Trance Vibrator
+
+usb:v0B4B*
+ ID_VENDOR_FROM_DATABASE=Pine Corp. Ltd.
+
+usb:v0B4Bp0100*
+ ID_PRODUCT_FROM_DATABASE=D'music MP3 Player
+
+usb:v0B4D*
+ ID_VENDOR_FROM_DATABASE=Graphtec America, Inc.
+
+usb:v0B4Dp110A*
+ ID_PRODUCT_FROM_DATABASE=Graphtec CC200-20
+
+usb:v0B4E*
+ ID_VENDOR_FROM_DATABASE=Musical Electronics, Ltd
+
+usb:v0B4Ep6500*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0B4Ep8028*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0B4Ep8920*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0B50*
+ ID_VENDOR_FROM_DATABASE=Dumpries Co., Ltd
+
+usb:v0B51*
+ ID_VENDOR_FROM_DATABASE=Comfort Keyboard Co.
+
+usb:v0B51p0020*
+ ID_PRODUCT_FROM_DATABASE=Comfort Keyboard
+
+usb:v0B52*
+ ID_VENDOR_FROM_DATABASE=Colorado MicroDisplay, Inc.
+
+usb:v0B54*
+ ID_VENDOR_FROM_DATABASE=Sinbon Electronics Co., Ltd
+
+usb:v0B56*
+ ID_VENDOR_FROM_DATABASE=TYI Systems, Ltd
+
+usb:v0B57*
+ ID_VENDOR_FROM_DATABASE=Beijing HanwangTechnology Co., Ltd
+
+usb:v0B59*
+ ID_VENDOR_FROM_DATABASE=Lake Communications, Ltd
+
+usb:v0B5A*
+ ID_VENDOR_FROM_DATABASE=Corel Corp.
+
+usb:v0B5F*
+ ID_VENDOR_FROM_DATABASE=Green Electronics Co., Ltd
+
+usb:v0B60*
+ ID_VENDOR_FROM_DATABASE=Nsine, Ltd
+
+usb:v0B61*
+ ID_VENDOR_FROM_DATABASE=NEC Viewtechnology, Ltd
+
+usb:v0B62*
+ ID_VENDOR_FROM_DATABASE=Orange Micro, Inc.
+
+usb:v0B62p000B*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0B62p0059*
+ ID_PRODUCT_FROM_DATABASE=iBOT2 Webcam
+
+usb:v0B63*
+ ID_VENDOR_FROM_DATABASE=ADLink Technology, Inc.
+
+usb:v0B64*
+ ID_VENDOR_FROM_DATABASE=Wonderful Wire Cable Co., Ltd
+
+usb:v0B65*
+ ID_VENDOR_FROM_DATABASE=Expert Magnetics Corp.
+
+usb:v0B69*
+ ID_VENDOR_FROM_DATABASE=CacheVision
+
+usb:v0B6A*
+ ID_VENDOR_FROM_DATABASE=Maxim Integrated Products
+
+usb:v0B6F*
+ ID_VENDOR_FROM_DATABASE=Nagano Japan Radio Co., Ltd
+
+usb:v0B70*
+ ID_VENDOR_FROM_DATABASE=PortalPlayer, Inc.
+
+usb:v0B70p00BA*
+ ID_PRODUCT_FROM_DATABASE=iRiver H10 20GB
+
+usb:v0B71*
+ ID_VENDOR_FROM_DATABASE=SHIN-EI Sangyo Co., Ltd
+
+usb:v0B72*
+ ID_VENDOR_FROM_DATABASE=Embedded Wireless Technology Co., Ltd
+
+usb:v0B73*
+ ID_VENDOR_FROM_DATABASE=Computone Corp.
+
+usb:v0B75*
+ ID_VENDOR_FROM_DATABASE=Roland DG Corp.
+
+usb:v0B79*
+ ID_VENDOR_FROM_DATABASE=Sunrise Telecom, Inc.
+
+usb:v0B7A*
+ ID_VENDOR_FROM_DATABASE=Zeevo, Inc.
+
+usb:v0B7Ap07D0*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v0B7B*
+ ID_VENDOR_FROM_DATABASE=Taiko Denki Co., Ltd
+
+usb:v0B7C*
+ ID_VENDOR_FROM_DATABASE=ITRAN Communications, Ltd
+
+usb:v0B7D*
+ ID_VENDOR_FROM_DATABASE=Astrodesign, Inc.
+
+usb:v0B81*
+ ID_VENDOR_FROM_DATABASE=id3 Semiconductors
+
+usb:v0B81p0001*
+ ID_PRODUCT_FROM_DATABASE=Biothentic II smartcard reader with fingerprint sensor
+
+usb:v0B81p0002*
+ ID_PRODUCT_FROM_DATABASE=DFU-Enabled Devices (DFU)
+
+usb:v0B81p0012*
+ ID_PRODUCT_FROM_DATABASE=BioPAD biometric module (DFU + CDC)
+
+usb:v0B81p0102*
+ ID_PRODUCT_FROM_DATABASE=Certis V1 fingerprint reader
+
+usb:v0B81p0103*
+ ID_PRODUCT_FROM_DATABASE=Certis V2 fingerprint reader
+
+usb:v0B81p0200*
+ ID_PRODUCT_FROM_DATABASE=CL1356T / CL1356T5 / CL1356A smartcard readers (CCID)
+
+usb:v0B81p0201*
+ ID_PRODUCT_FROM_DATABASE=CL1356T / CL1356T5 / CL1356A smartcard readers (DFU + CCID)
+
+usb:v0B81p0220*
+ ID_PRODUCT_FROM_DATABASE=CL1356A FFPJP smartcard reader (CCID + HID)
+
+usb:v0B81p0221*
+ ID_PRODUCT_FROM_DATABASE=CL1356A smartcard reader (DFU + CCID + HID)
+
+usb:v0B84*
+ ID_VENDOR_FROM_DATABASE=Rextron Technology, Inc.
+
+usb:v0B85*
+ ID_VENDOR_FROM_DATABASE=Elkat Electronics, Sdn., Bhd.
+
+usb:v0B86*
+ ID_VENDOR_FROM_DATABASE=Exputer Systems, Inc.
+
+usb:v0B86p5100*
+ ID_PRODUCT_FROM_DATABASE=XMC5100 Zippy Drive
+
+usb:v0B86p5110*
+ ID_PRODUCT_FROM_DATABASE=XMC5110 Flash Drive
+
+usb:v0B86p5200*
+ ID_PRODUCT_FROM_DATABASE=XMC5200 Zippy Drive
+
+usb:v0B86p5201*
+ ID_PRODUCT_FROM_DATABASE=XMC5200 Zippy Drive
+
+usb:v0B86p5202*
+ ID_PRODUCT_FROM_DATABASE=XMC5200 Zippy Drive
+
+usb:v0B86p5280*
+ ID_PRODUCT_FROM_DATABASE=XMC5280 Storage Drive
+
+usb:v0B86pFFF0*
+ ID_PRODUCT_FROM_DATABASE=ISP5200 Debugger
+
+usb:v0B87*
+ ID_VENDOR_FROM_DATABASE=Plus-One I & T, Inc.
+
+usb:v0B88*
+ ID_VENDOR_FROM_DATABASE=Sigma Koki Co., Ltd, Technology Center
+
+usb:v0B89*
+ ID_VENDOR_FROM_DATABASE=Advanced Digital Broadcast, Ltd
+
+usb:v0B8C*
+ ID_VENDOR_FROM_DATABASE=SMART Technologies Inc.
+
+usb:v0B8Cp0001*
+ ID_PRODUCT_FROM_DATABASE=Interactive Whiteboard Controller (SB6) (HID)
+
+usb:v0B8Cp00C3*
+ ID_PRODUCT_FROM_DATABASE=Sympodium ID350
+
+usb:v0B95*
+ ID_VENDOR_FROM_DATABASE=ASIX Electronics Corp.
+
+usb:v0B95p1720*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet
+
+usb:v0B95p1780*
+ ID_PRODUCT_FROM_DATABASE=AX88178
+
+usb:v0B95p7720*
+ ID_PRODUCT_FROM_DATABASE=AX88772
+
+usb:v0B95p772A*
+ ID_PRODUCT_FROM_DATABASE=AX88772A Fast Ethernet
+
+usb:v0B95p772B*
+ ID_PRODUCT_FROM_DATABASE=AX88772B
+
+usb:v0B95p7E2B*
+ ID_PRODUCT_FROM_DATABASE=AX88772B
+
+usb:v0B96*
+ ID_VENDOR_FROM_DATABASE=Sewon Telecom
+
+usb:v0B97*
+ ID_VENDOR_FROM_DATABASE=O2 Micro, Inc.
+
+usb:v0B97p7732*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Reader
+
+usb:v0B97p7761*
+ ID_PRODUCT_FROM_DATABASE=Oz776 1.1 Hub
+
+usb:v0B97p7762*
+ ID_PRODUCT_FROM_DATABASE=Oz776 SmartCard Reader
+
+usb:v0B97p7772*
+ ID_PRODUCT_FROM_DATABASE=OZ776 CCID Smartcard Reader
+
+usb:v0B98*
+ ID_VENDOR_FROM_DATABASE=Playmates Toys, Inc.
+
+usb:v0B99*
+ ID_VENDOR_FROM_DATABASE=Audio International, Inc.
+
+usb:v0B9B*
+ ID_VENDOR_FROM_DATABASE=Dipl.-Ing. Stefan Kunde
+
+usb:v0B9Bp4012*
+ ID_PRODUCT_FROM_DATABASE=Reflex RC-controller Interface
+
+usb:v0B9D*
+ ID_VENDOR_FROM_DATABASE=Softprotec Co.
+
+usb:v0B9F*
+ ID_VENDOR_FROM_DATABASE=Chippo Technologies
+
+usb:v0BAF*
+ ID_VENDOR_FROM_DATABASE=U.S. Robotics
+
+usb:v0BAFp00E5*
+ ID_PRODUCT_FROM_DATABASE=USR6000
+
+usb:v0BAFp00EB*
+ ID_PRODUCT_FROM_DATABASE=USR1120 802.11b Adapter
+
+usb:v0BAFp00EC*
+ ID_PRODUCT_FROM_DATABASE=56K Faxmodem
+
+usb:v0BAFp00F1*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL ATM Adapter
+
+usb:v0BAFp00F2*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Loader
+
+usb:v0BAFp00F5*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL ATM Adapter
+
+usb:v0BAFp00F6*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Loader
+
+usb:v0BAFp00F7*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL ATM Adapter
+
+usb:v0BAFp00F8*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Loader
+
+usb:v0BAFp00F9*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL ATM Adapter
+
+usb:v0BAFp00FA*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Loader
+
+usb:v0BAFp00FB*
+ ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Ethernet/USB Router
+
+usb:v0BAFp0111*
+ ID_PRODUCT_FROM_DATABASE=USR5420 802.11g Adapter [Broadcom 4320 USB]
+
+usb:v0BAFp0118*
+ ID_PRODUCT_FROM_DATABASE=U5 802.11g Adapter
+
+usb:v0BAFp011B*
+ ID_PRODUCT_FROM_DATABASE=Wireless MAXg Adapter [Broadcom 4320]
+
+usb:v0BAFp0121*
+ ID_PRODUCT_FROM_DATABASE=USR5423 802.11bg Wireless Adapter [ZyDAS ZD1211B]
+
+usb:v0BAFp6112*
+ ID_PRODUCT_FROM_DATABASE=FaxModem Model 5633
+
+usb:v0BB0*
+ ID_VENDOR_FROM_DATABASE=Concord Camera Corp.
+
+usb:v0BB0p0100*
+ ID_PRODUCT_FROM_DATABASE=Sound Vision Stream
+
+usb:v0BB0p5007*
+ ID_PRODUCT_FROM_DATABASE=3340z/Rollei DC3100
+
+usb:v0BB1*
+ ID_VENDOR_FROM_DATABASE=Infinilink Corp.
+
+usb:v0BB2*
+ ID_VENDOR_FROM_DATABASE=Ambit Microsystems Corp.
+
+usb:v0BB2p0302*
+ ID_PRODUCT_FROM_DATABASE=U10H010 802.11b Wireless Adapter [Intersil PRISM 3]
+
+usb:v0BB2p6098*
+ ID_PRODUCT_FROM_DATABASE=USB Cable Modem
+
+usb:v0BB3*
+ ID_VENDOR_FROM_DATABASE=Ofuji Technology
+
+usb:v0BB4*
+ ID_VENDOR_FROM_DATABASE=HTC (High Tech Computer Corp.)
+
+usb:v0BB4p00CE*
+ ID_PRODUCT_FROM_DATABASE=mmO2 XDA GSM/GPRS Pocket PC
+
+usb:v0BB4p00CF*
+ ID_PRODUCT_FROM_DATABASE=SPV C500 Smart Phone
+
+usb:v0BB4p0A01*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A02*
+ ID_PRODUCT_FROM_DATABASE=Himalaya GSM/GPRS Pocket PC
+
+usb:v0BB4p0A03*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A04*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A05*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A06*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A07*
+ ID_PRODUCT_FROM_DATABASE=Magician PocketPC SmartPhone / O2 XDA
+
+usb:v0BB4p0A08*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A09*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A0A*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A0B*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A0C*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A0D*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A0E*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A0F*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A10*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A11*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A12*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A13*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A14*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A15*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A16*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A17*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A18*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A19*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A1A*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A1B*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A1C*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A1D*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A1E*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A1F*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A20*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A21*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A22*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A23*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A24*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A25*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A26*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A27*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A28*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A29*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A2A*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A2B*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A2C*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A2D*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A2E*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A2F*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A30*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A31*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A32*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A33*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A34*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A35*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A36*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A37*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A38*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A39*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A3A*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A3B*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A3C*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A3D*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A3E*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A3F*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A40*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A41*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A42*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A43*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A44*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A45*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A46*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A47*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A48*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A49*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A4A*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A4B*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A4C*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A4D*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A4E*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A4F*
+ ID_PRODUCT_FROM_DATABASE=PocketPC Sync
+
+usb:v0BB4p0A50*
+ ID_PRODUCT_FROM_DATABASE=HTC SmartPhone Sync
+
+usb:v0BB4p0A51*
+ ID_PRODUCT_FROM_DATABASE=SPV C400 / T-Mobile SDA GSM/GPRS Pocket PC
+
+usb:v0BB4p0A52*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A53*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A54*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A55*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A56*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A57*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A58*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A59*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A5A*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A5B*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A5C*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A5D*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A5E*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A5F*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A60*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A61*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A62*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A63*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A64*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A65*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A66*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A67*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A68*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A69*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A6A*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A6B*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A6C*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A6D*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A6E*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A6F*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A70*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A71*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A72*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A73*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A74*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A75*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A76*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A77*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A78*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A79*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A7A*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A7B*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A7C*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A7D*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A7E*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A7F*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A80*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A81*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A82*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A83*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A84*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A85*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A86*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A87*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A88*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A89*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A8A*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A8B*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A8C*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A8D*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A8E*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A8F*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A90*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A91*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A92*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A93*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A94*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A95*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A96*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A97*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A98*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A99*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A9A*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A9B*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A9C*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A9D*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A9E*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0A9F*
+ ID_PRODUCT_FROM_DATABASE=SmartPhone Sync
+
+usb:v0BB4p0B03*
+ ID_PRODUCT_FROM_DATABASE=Ozone Mobile Broadband
+
+usb:v0BB4p0B04*
+ ID_PRODUCT_FROM_DATABASE=Hermes / TyTN / T-Mobile MDA Vario II / O2 Xda Trion
+
+usb:v0BB4p0B05*
+ ID_PRODUCT_FROM_DATABASE=P3600
+
+usb:v0BB4p0B06*
+ ID_PRODUCT_FROM_DATABASE=Athena / Advantage x7500 / Dopod U1000 / T-Mobile AMEO
+
+usb:v0BB4p0B0C*
+ ID_PRODUCT_FROM_DATABASE=Elf / Touch / P3450 / T-Mobile MDA Touch / O2 Xda Nova / Dopod S1
+
+usb:v0BB4p0B1F*
+ ID_PRODUCT_FROM_DATABASE=Sony Ericsson XPERIA X1
+
+usb:v0BB4p0B2F*
+ ID_PRODUCT_FROM_DATABASE=Rhodium
+
+usb:v0BB4p0B51*
+ ID_PRODUCT_FROM_DATABASE=Qtek 8310 mobile phone [Tornado Noble]
+
+usb:v0BB4p0BCE*
+ ID_PRODUCT_FROM_DATABASE=Vario MDA
+
+usb:v0BB4p0C01*
+ ID_PRODUCT_FROM_DATABASE=Dream / ADP1 / G1 / Magic / Tattoo
+
+usb:v0BB4p0C02*
+ ID_PRODUCT_FROM_DATABASE=Dream / ADP1 / G1 / Magic / Tattoo (Debug)
+
+usb:v0BB4p0C13*
+ ID_PRODUCT_FROM_DATABASE=Diamond
+
+usb:v0BB4p0C1F*
+ ID_PRODUCT_FROM_DATABASE=Sony Ericsson XPERIA X1
+
+usb:v0BB4p0C5F*
+ ID_PRODUCT_FROM_DATABASE=Snap
+
+usb:v0BB4p0C86*
+ ID_PRODUCT_FROM_DATABASE=Sensation
+
+usb:v0BB4p0C87*
+ ID_PRODUCT_FROM_DATABASE=Desire (debug)
+
+usb:v0BB4p0C8D*
+ ID_PRODUCT_FROM_DATABASE=EVO 4G (debug)
+
+usb:v0BB4p0C91*
+ ID_PRODUCT_FROM_DATABASE=Vision
+
+usb:v0BB4p0C94*
+ ID_PRODUCT_FROM_DATABASE=Vision
+
+usb:v0BB4p0C97*
+ ID_PRODUCT_FROM_DATABASE=Legend
+
+usb:v0BB4p0C99*
+ ID_PRODUCT_FROM_DATABASE=Desire (debug)
+
+usb:v0BB4p0C9E*
+ ID_PRODUCT_FROM_DATABASE=Incredible
+
+usb:v0BB4p0CA2*
+ ID_PRODUCT_FROM_DATABASE=Desire HD (debug mode)
+
+usb:v0BB4p0CA5*
+ ID_PRODUCT_FROM_DATABASE=Android Phone [Evo Shift 4G]
+
+usb:v0BB4p0FF8*
+ ID_PRODUCT_FROM_DATABASE=Desire HD (Tethering Mode)
+
+usb:v0BB4p0FF9*
+ ID_PRODUCT_FROM_DATABASE=Desire / Desire HD / Hero (Charge Mode)
+
+usb:v0BB4p0FFE*
+ ID_PRODUCT_FROM_DATABASE=Desire HD (modem mode)
+
+usb:v0BB4p0FFF*
+ ID_PRODUCT_FROM_DATABASE=Android Fastboot Bootloader
+
+usb:v0BB5*
+ ID_VENDOR_FROM_DATABASE=Murata Manufacturing Co., Ltd
+
+usb:v0BB6*
+ ID_VENDOR_FROM_DATABASE=Network Alchemy
+
+usb:v0BB7*
+ ID_VENDOR_FROM_DATABASE=Joytech Computer Co., Ltd
+
+usb:v0BB8*
+ ID_VENDOR_FROM_DATABASE=Hitachi Semiconductor and Devices Sales Co., Ltd
+
+usb:v0BB9*
+ ID_VENDOR_FROM_DATABASE=Eiger M&C Co., Ltd
+
+usb:v0BBA*
+ ID_VENDOR_FROM_DATABASE=ZAccess Systems
+
+usb:v0BBB*
+ ID_VENDOR_FROM_DATABASE=General Meters Corp.
+
+usb:v0BBC*
+ ID_VENDOR_FROM_DATABASE=Assistive Technology, Inc.
+
+usb:v0BBD*
+ ID_VENDOR_FROM_DATABASE=System Connection, Inc.
+
+usb:v0BC0*
+ ID_VENDOR_FROM_DATABASE=Knilink Technology, Inc.
+
+usb:v0BC1*
+ ID_VENDOR_FROM_DATABASE=Fuw Yng Electronics Co., Ltd
+
+usb:v0BC2*
+ ID_VENDOR_FROM_DATABASE=Seagate RSS LLC
+
+usb:v0BC2p0502*
+ ID_PRODUCT_FROM_DATABASE=ST3300601CB-RK 300 GB External Hard Drive
+
+usb:v0BC2p0503*
+ ID_PRODUCT_FROM_DATABASE=ST3250824A [Barracuda 7200.9]
+
+usb:v0BC2p2000*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V3 (TPP)
+
+usb:v0BC2p2200*
+ ID_PRODUCT_FROM_DATABASE=FreeAgent Go FW
+
+usb:v0BC2p2300*
+ ID_PRODUCT_FROM_DATABASE=Expansion Portable
+
+usb:v0BC2p2320*
+ ID_PRODUCT_FROM_DATABASE=USB 3.0 bridge [Portable Expansion Drive]
+
+usb:v0BC2p3332*
+ ID_PRODUCT_FROM_DATABASE=Expansion
+
+usb:v0BC2p5021*
+ ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex USB 2.0
+
+usb:v0BC2p5031*
+ ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex USB 3.0
+
+usb:v0BC2p50A5*
+ ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex Desk USB 3.0
+
+usb:v0BC2p5121*
+ ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex
+
+usb:v0BC2p5161*
+ ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex dock
+
+usb:v0BC3*
+ ID_VENDOR_FROM_DATABASE=IPWireless, Inc.
+
+usb:v0BC3p0001*
+ ID_PRODUCT_FROM_DATABASE=UMTS-TDD (TD-CDMA) modem
+
+usb:v0BC4*
+ ID_VENDOR_FROM_DATABASE=Microcube Corp.
+
+usb:v0BC5*
+ ID_VENDOR_FROM_DATABASE=JCN Co., Ltd
+
+usb:v0BC6*
+ ID_VENDOR_FROM_DATABASE=ExWAY, Inc.
+
+usb:v0BC7*
+ ID_VENDOR_FROM_DATABASE=X10 Wireless Technology, Inc.
+
+usb:v0BC7p0001*
+ ID_PRODUCT_FROM_DATABASE=ActiveHome (ACPI-compliant)
+
+usb:v0BC7p0002*
+ ID_PRODUCT_FROM_DATABASE=Firecracker Interface (ACPI-compliant)
+
+usb:v0BC7p0003*
+ ID_PRODUCT_FROM_DATABASE=VGA Video Sender (ACPI-compliant)
+
+usb:v0BC7p0004*
+ ID_PRODUCT_FROM_DATABASE=X10 Receiver
+
+usb:v0BC7p0005*
+ ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant)
+
+usb:v0BC7p0006*
+ ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant)
+
+usb:v0BC7p0007*
+ ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant)
+
+usb:v0BC7p0008*
+ ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant)
+
+usb:v0BC7p0009*
+ ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant)
+
+usb:v0BC7p000A*
+ ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant)
+
+usb:v0BC7p000B*
+ ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant)
+
+usb:v0BC7p000C*
+ ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant)
+
+usb:v0BC7p000D*
+ ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant)
+
+usb:v0BC7p000E*
+ ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant)
+
+usb:v0BC7p000F*
+ ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant)
+
+usb:v0BC8*
+ ID_VENDOR_FROM_DATABASE=Telmax Communications
+
+usb:v0BC9*
+ ID_VENDOR_FROM_DATABASE=ECI Telecom, Ltd
+
+usb:v0BCA*
+ ID_VENDOR_FROM_DATABASE=Startek Engineering, Inc.
+
+usb:v0BCB*
+ ID_VENDOR_FROM_DATABASE=Perfect Technic Enterprise Co., Ltd
+
+usb:v0BD7*
+ ID_VENDOR_FROM_DATABASE=Andrew Pargeter & Associates
+
+usb:v0BD7pA021*
+ ID_PRODUCT_FROM_DATABASE=Amptek DP4 multichannel signal analyzer
+
+usb:v0BDA*
+ ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp.
+
+usb:v0BDAp0103*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader
+
+usb:v0BDAp0104*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0106*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0107*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0108*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0111*
+ ID_PRODUCT_FROM_DATABASE=RTS5111 Card Reader Controller
+
+usb:v0BDAp0113*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0115*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device (Multicard Reader)
+
+usb:v0BDAp0116*
+ ID_PRODUCT_FROM_DATABASE=RTS5116 Card Reader Controller
+
+usb:v0BDAp0117*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0118*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0119*
+ ID_PRODUCT_FROM_DATABASE=Storage Device (SD card reader)
+
+usb:v0BDAp0129*
+ ID_PRODUCT_FROM_DATABASE=RTS5129 Card Reader Controller
+
+usb:v0BDAp0138*
+ ID_PRODUCT_FROM_DATABASE=RTS5138 Card Reader Controller
+
+usb:v0BDAp0139*
+ ID_PRODUCT_FROM_DATABASE=RTS5139 Card Reader Controller
+
+usb:v0BDAp0151*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device (Multicard Reader)
+
+usb:v0BDAp0152*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0153*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0156*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0157*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0158*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 multicard reader
+
+usb:v0BDAp0159*
+ ID_PRODUCT_FROM_DATABASE=RTS5159 Card Reader Controller
+
+usb:v0BDAp0161*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0168*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0169*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0171*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0176*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0178*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0BDAp0186*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v0BDAp2831*
+ ID_PRODUCT_FROM_DATABASE=RTL2831U DVB-T
+
+usb:v0BDAp2832*
+ ID_PRODUCT_FROM_DATABASE=RTL2832U DVB-T
+
+usb:v0BDAp2838*
+ ID_PRODUCT_FROM_DATABASE=RTL2838 DVB-T
+
+usb:v0BDAp8150*
+ ID_PRODUCT_FROM_DATABASE=RTL8150 Fast Ethernet Adapter
+
+usb:v0BDAp8151*
+ ID_PRODUCT_FROM_DATABASE=RTL8151 Adapteon Business Mobile Networks BV
+
+usb:v0BDAp8171*
+ ID_PRODUCT_FROM_DATABASE=RTL8188SU 802.11n WLAN Adapter
+
+usb:v0BDAp8172*
+ ID_PRODUCT_FROM_DATABASE=RTL8191SU 802.11n WLAN Adapter
+
+usb:v0BDAp8174*
+ ID_PRODUCT_FROM_DATABASE=RTL8192SU 802.11n WLAN Adapter
+
+usb:v0BDAp8176*
+ ID_PRODUCT_FROM_DATABASE=RTL8188CUS 802.11n WLAN Adapter
+
+usb:v0BDAp8178*
+ ID_PRODUCT_FROM_DATABASE=RTL8192CU 802.11n WLAN Adapter
+
+usb:v0BDAp817F*
+ ID_PRODUCT_FROM_DATABASE=RTL8188RU 802.11n WLAN Adapter
+
+usb:v0BDAp8187*
+ ID_PRODUCT_FROM_DATABASE=RTL8187 Wireless Adapter
+
+usb:v0BDAp8189*
+ ID_PRODUCT_FROM_DATABASE=RTL8187B Wireless 802.11g 54Mbps Network Adapter
+
+usb:v0BDAp8192*
+ ID_PRODUCT_FROM_DATABASE=RTL8191SU 802.11n Wireless Adapter
+
+usb:v0BDAp8193*
+ ID_PRODUCT_FROM_DATABASE=RTL8192DU 802.11an WLAN Adapter
+
+usb:v0BDAp8197*
+ ID_PRODUCT_FROM_DATABASE=RTL8187B Wireless Adapter
+
+usb:v0BDAp8198*
+ ID_PRODUCT_FROM_DATABASE=RTL8187B Wireless Adapter
+
+usb:v0BDB*
+ ID_VENDOR_FROM_DATABASE=Ericsson Business Mobile Networks BV
+
+usb:v0BDBp1000*
+ ID_PRODUCT_FROM_DATABASE=BV Bluetooth Device
+
+usb:v0BDBp1002*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device 1.2
+
+usb:v0BDBp1049*
+ ID_PRODUCT_FROM_DATABASE=C3607w Mobile Broadband Module
+
+usb:v0BDBp1900*
+ ID_PRODUCT_FROM_DATABASE=F3507g Mobile Broadband Module
+
+usb:v0BDBp1902*
+ ID_PRODUCT_FROM_DATABASE=F3507g v2 Mobile Broadband Module
+
+usb:v0BDBp1904*
+ ID_PRODUCT_FROM_DATABASE=F3607gw Mobile Broadband Module
+
+usb:v0BDBp1905*
+ ID_PRODUCT_FROM_DATABASE=F3607gw v2 Mobile Broadband Module
+
+usb:v0BDBp1906*
+ ID_PRODUCT_FROM_DATABASE=F3607gw v3 Mobile Broadband Module
+
+usb:v0BDBp1909*
+ ID_PRODUCT_FROM_DATABASE=F3307 v2 Mobile Broadband Module
+
+usb:v0BDBp190A*
+ ID_PRODUCT_FROM_DATABASE=F3307 Mobile Broadband Module
+
+usb:v0BDBp190B*
+ ID_PRODUCT_FROM_DATABASE=C3607w v2 Mobile Broadband Module
+
+usb:v0BDC*
+ ID_VENDOR_FROM_DATABASE=Y Media Corp.
+
+usb:v0BDD*
+ ID_VENDOR_FROM_DATABASE=Orange PCS
+
+usb:v0BE2*
+ ID_VENDOR_FROM_DATABASE=Kanda Tsushin Kogyo Co., Ltd
+
+usb:v0BE3*
+ ID_VENDOR_FROM_DATABASE=TOYO Corp.
+
+usb:v0BE4*
+ ID_VENDOR_FROM_DATABASE=Elka International, Ltd
+
+usb:v0BE5*
+ ID_VENDOR_FROM_DATABASE=DOME imaging systems, Inc.
+
+usb:v0BE6*
+ ID_VENDOR_FROM_DATABASE=Dong Guan Humen Wonderful Wire Cable Factory
+
+usb:v0BED*
+ ID_VENDOR_FROM_DATABASE=Silicon Labs
+
+usb:v0BEDp1100*
+ ID_PRODUCT_FROM_DATABASE=MEI CASHFLOW SC
+
+usb:v0BEDp1101*
+ ID_PRODUCT_FROM_DATABASE=Series 2000 Combo Acceptor
+
+usb:v0BEE*
+ ID_VENDOR_FROM_DATABASE=LTK Industries, Ltd
+
+usb:v0BEF*
+ ID_VENDOR_FROM_DATABASE=Way2Call Communications
+
+usb:v0BF0*
+ ID_VENDOR_FROM_DATABASE=Pace Micro Technology PLC
+
+usb:v0BF1*
+ ID_VENDOR_FROM_DATABASE=Intracom S.A.
+
+usb:v0BF1p0001*
+ ID_PRODUCT_FROM_DATABASE=netMod Driver Ver 2.4.17 (CAPI)
+
+usb:v0BF1p0002*
+ ID_PRODUCT_FROM_DATABASE=netMod Driver Ver 2.4 (CAPI)
+
+usb:v0BF1p0003*
+ ID_PRODUCT_FROM_DATABASE=netMod Driver Ver 2.4 (CAPI)
+
+usb:v0BF2*
+ ID_VENDOR_FROM_DATABASE=Konexx
+
+usb:v0BF6*
+ ID_VENDOR_FROM_DATABASE=Addonics Technologies, Inc.
+
+usb:v0BF6p0103*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v0BF6p1234*
+ ID_PRODUCT_FROM_DATABASE=Storage Device
+
+usb:v0BF6pA000*
+ ID_PRODUCT_FROM_DATABASE=Cable 205 (TPP)
+
+usb:v0BF6pA001*
+ ID_PRODUCT_FROM_DATABASE=Cable 205
+
+usb:v0BF6pA002*
+ ID_PRODUCT_FROM_DATABASE=IDE Bridge
+
+usb:v0BF7*
+ ID_VENDOR_FROM_DATABASE=Sunny Giken, Inc.
+
+usb:v0BF8*
+ ID_VENDOR_FROM_DATABASE=Fujitsu Siemens Computers
+
+usb:v0BF8p1001*
+ ID_PRODUCT_FROM_DATABASE=Fujitsu Pocket Loox 600 PDA
+
+usb:v0BF8p1006*
+ ID_PRODUCT_FROM_DATABASE=SmartCard Reader 2A
+
+usb:v0BF8p1007*
+ ID_PRODUCT_FROM_DATABASE=Connect2Air E-5400 802.11g Wireless Adapter
+
+usb:v0BF8p1009*
+ ID_PRODUCT_FROM_DATABASE=Connect2Air E-5400 D1700 802.11g Wireless Adapter [Intersil ISL3887]
+
+usb:v0BF8p100C*
+ ID_PRODUCT_FROM_DATABASE=Keyboard FSC KBPC PX
+
+usb:v0BF8p100F*
+ ID_PRODUCT_FROM_DATABASE=miniCard D2301 802.11bg Wireless Module [SiS 163U]
+
+usb:v0BFD*
+ ID_VENDOR_FROM_DATABASE=Kvaser AB
+
+usb:v0BFDp0004*
+ ID_PRODUCT_FROM_DATABASE=USBcan II
+
+usb:v0BFDp000B*
+ ID_PRODUCT_FROM_DATABASE=Leaf Light HS
+
+usb:v0BFDp000E*
+ ID_PRODUCT_FROM_DATABASE=Leaf SemiPro HS
+
+usb:v0C04*
+ ID_VENDOR_FROM_DATABASE=MOTO Development Group, Inc.
+
+usb:v0C05*
+ ID_VENDOR_FROM_DATABASE=Appian Graphics
+
+usb:v0C06*
+ ID_VENDOR_FROM_DATABASE=Hasbro Games, Inc.
+
+usb:v0C07*
+ ID_VENDOR_FROM_DATABASE=Infinite Data Storage, Ltd
+
+usb:v0C08*
+ ID_VENDOR_FROM_DATABASE=Agate
+
+usb:v0C08p0378*
+ ID_PRODUCT_FROM_DATABASE=Q 16MB Storage Device
+
+usb:v0C09*
+ ID_VENDOR_FROM_DATABASE=Comjet Information System
+
+usb:v0C09pA5A5*
+ ID_PRODUCT_FROM_DATABASE=Litto Version USB2.0
+
+usb:v0C0A*
+ ID_VENDOR_FROM_DATABASE=Highpoint Technologies, Inc.
+
+usb:v0C0B*
+ ID_VENDOR_FROM_DATABASE=Dura Micro, Inc. (Acomdata)
+
+usb:v0C0Bp27CB*
+ ID_PRODUCT_FROM_DATABASE=6-in-1 Flash Reader and Writer
+
+usb:v0C0Bp27D7*
+ ID_PRODUCT_FROM_DATABASE=Multi Memory reader/writer MD-005
+
+usb:v0C0Bp27DA*
+ ID_PRODUCT_FROM_DATABASE=Multi Memory reader/writer MD-005
+
+usb:v0C0Bp27DC*
+ ID_PRODUCT_FROM_DATABASE=Multi Memory reader/writer MD-005
+
+usb:v0C0Bp27E7*
+ ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231
+
+usb:v0C0Bp27EE*
+ ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231
+
+usb:v0C0Bp2814*
+ ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231
+
+usb:v0C0Bp2815*
+ ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231
+
+usb:v0C0Bp281D*
+ ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231
+
+usb:v0C0Bp5FAB*
+ ID_PRODUCT_FROM_DATABASE=Storage Adaptor
+
+usb:v0C0BpA109*
+ ID_PRODUCT_FROM_DATABASE=CF/SM Reader and Writer
+
+usb:v0C0BpA10C*
+ ID_PRODUCT_FROM_DATABASE=SD/MS Reader and Writer
+
+usb:v0C0BpB001*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Mass Storage IDE adapter
+
+usb:v0C0BpB004*
+ ID_PRODUCT_FROM_DATABASE=MMC/SD Reader and Writer
+
+usb:v0C12*
+ ID_VENDOR_FROM_DATABASE=Zeroplus
+
+usb:v0C12p0005*
+ ID_PRODUCT_FROM_DATABASE=PSX Vibration Feedback Converter
+
+usb:v0C12p0030*
+ ID_PRODUCT_FROM_DATABASE=PSX Vibration Feedback Converter
+
+usb:v0C12p700E*
+ ID_PRODUCT_FROM_DATABASE=Logic Analyzer (LAP-C-16032)
+
+usb:v0C12p8801*
+ ID_PRODUCT_FROM_DATABASE=Xbox Controller
+
+usb:v0C12p8802*
+ ID_PRODUCT_FROM_DATABASE=Xbox Controller
+
+usb:v0C12p8809*
+ ID_PRODUCT_FROM_DATABASE=Red Octane Ignition Xbox DDR Pad
+
+usb:v0C12p880A*
+ ID_PRODUCT_FROM_DATABASE=Pelican Eclipse PL-2023
+
+usb:v0C12p8810*
+ ID_PRODUCT_FROM_DATABASE=Xbox Controller
+
+usb:v0C12p9902*
+ ID_PRODUCT_FROM_DATABASE=VibraX
+
+usb:v0C15*
+ ID_VENDOR_FROM_DATABASE=Iris Graphics
+
+usb:v0C16*
+ ID_VENDOR_FROM_DATABASE=Gyration, Inc.
+
+usb:v0C16p0002*
+ ID_PRODUCT_FROM_DATABASE=RF Technology Receiver
+
+usb:v0C16p0003*
+ ID_PRODUCT_FROM_DATABASE=RF Technology Receiver
+
+usb:v0C16p0008*
+ ID_PRODUCT_FROM_DATABASE=RF Technology Receiver
+
+usb:v0C16p0080*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0C16p0081*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0C17*
+ ID_VENDOR_FROM_DATABASE=Cyberboard A/S
+
+usb:v0C18*
+ ID_VENDOR_FROM_DATABASE=SynerTek Korea, Inc.
+
+usb:v0C19*
+ ID_VENDOR_FROM_DATABASE=cyberPIXIE, Inc.
+
+usb:v0C1A*
+ ID_VENDOR_FROM_DATABASE=Silicon Motion, Inc.
+
+usb:v0C1B*
+ ID_VENDOR_FROM_DATABASE=MIPS Technologies
+
+usb:v0C1C*
+ ID_VENDOR_FROM_DATABASE=Hang Zhou Silan Electronics Co., Ltd
+
+usb:v0C22*
+ ID_VENDOR_FROM_DATABASE=Tally Printer Corp.
+
+usb:v0C23*
+ ID_VENDOR_FROM_DATABASE=Lernout + Hauspie
+
+usb:v0C24*
+ ID_VENDOR_FROM_DATABASE=Taiyo Yuden
+
+usb:v0C24p0001*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adaptor
+
+usb:v0C24p0002*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device2
+
+usb:v0C24p0005*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External)
+
+usb:v0C24p000B*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External)
+
+usb:v0C24p000C*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adaptor
+
+usb:v0C24p000E*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External)
+
+usb:v0C24p000F*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device (V2.0+EDR)
+
+usb:v0C24p0010*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External)
+
+usb:v0C24p0012*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External)
+
+usb:v0C24p0018*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External)
+
+usb:v0C24p0019*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0C24p0021*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0C24p0C24*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device(SAMPLE)
+
+usb:v0C24pFFFF*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth module with BlueCore in DFU mode
+
+usb:v0C25*
+ ID_VENDOR_FROM_DATABASE=Sampo Corp.
+
+usb:v0C25p0310*
+ ID_PRODUCT_FROM_DATABASE=Scream Cam
+
+usb:v0C26*
+ ID_VENDOR_FROM_DATABASE=Prolific Technology Inc.
+
+usb:v0C26p0018*
+ ID_PRODUCT_FROM_DATABASE=USB-Serial Controller [Icom Inc. OPC-478UC]
+
+usb:v0C27*
+ ID_VENDOR_FROM_DATABASE=RFIDeas, Inc
+
+usb:v0C27p3BFA*
+ ID_PRODUCT_FROM_DATABASE=pcProx Card Reader
+
+usb:v0C2E*
+ ID_VENDOR_FROM_DATABASE=Metrologic Instruments
+
+usb:v0C2Ep0007*
+ ID_PRODUCT_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (IBM SurePOS mode)
+
+usb:v0C2Ep0200*
+ ID_PRODUCT_FROM_DATABASE=Metrologic Scanner
+
+usb:v0C2Ep0204*
+ ID_PRODUCT_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (keyboard mode)
+
+usb:v0C2Ep0700*
+ ID_PRODUCT_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (uni-directional serial mode)
+
+usb:v0C2Ep0720*
+ ID_PRODUCT_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (bi-directional serial mode)
+
+usb:v0C2Ep0B61*
+ ID_PRODUCT_FROM_DATABASE=Vuquest 3310g
+
+usb:v0C2Ep0B6A*
+ ID_PRODUCT_FROM_DATABASE=Vuquest 3310 Area-Imaging Scanner
+
+usb:v0C35*
+ ID_VENDOR_FROM_DATABASE=Eagletron, Inc.
+
+usb:v0C36*
+ ID_VENDOR_FROM_DATABASE=E Ink Corp.
+
+usb:v0C37*
+ ID_VENDOR_FROM_DATABASE=e.Digital
+
+usb:v0C38*
+ ID_VENDOR_FROM_DATABASE=Der An Electric Wire & Cable Co., Ltd
+
+usb:v0C39*
+ ID_VENDOR_FROM_DATABASE=IFR
+
+usb:v0C3A*
+ ID_VENDOR_FROM_DATABASE=Furui Precise Component (Kunshan) Co., Ltd
+
+usb:v0C3B*
+ ID_VENDOR_FROM_DATABASE=Komatsu, Ltd
+
+usb:v0C3C*
+ ID_VENDOR_FROM_DATABASE=Radius Co., Ltd
+
+usb:v0C3D*
+ ID_VENDOR_FROM_DATABASE=Innocom, Inc.
+
+usb:v0C3E*
+ ID_VENDOR_FROM_DATABASE=Nextcell, Inc.
+
+usb:v0C44*
+ ID_VENDOR_FROM_DATABASE=Motorola iDEN
+
+usb:v0C44p0021*
+ ID_PRODUCT_FROM_DATABASE=iDEN P2k0 Device
+
+usb:v0C44p0022*
+ ID_PRODUCT_FROM_DATABASE=iDEN P2k1 Device
+
+usb:v0C44p03A2*
+ ID_PRODUCT_FROM_DATABASE=iDEN Smartphone
+
+usb:v0C44p41D9*
+ ID_PRODUCT_FROM_DATABASE=i1 phone
+
+usb:v0C45*
+ ID_VENDOR_FROM_DATABASE=Microdia
+
+usb:v0C45p0011*
+ ID_PRODUCT_FROM_DATABASE=EBUDDY
+
+usb:v0C45p1020*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1028*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1030*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1031*
+ ID_PRODUCT_FROM_DATABASE=Sonix Mass Storage Device
+
+usb:v0C45p1032*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1033*
+ ID_PRODUCT_FROM_DATABASE=Sonix Mass Storage Device
+
+usb:v0C45p1034*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1035*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1036*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1037*
+ ID_PRODUCT_FROM_DATABASE=Sonix Mass Storage Device
+
+usb:v0C45p1050*
+ ID_PRODUCT_FROM_DATABASE=CF Card Reader
+
+usb:v0C45p1058*
+ ID_PRODUCT_FROM_DATABASE=HDD Reader
+
+usb:v0C45p1060*
+ ID_PRODUCT_FROM_DATABASE=iFlash SM-Direct Card Reader
+
+usb:v0C45p1061*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1062*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1063*
+ ID_PRODUCT_FROM_DATABASE=Sonix Mass Storage Device
+
+usb:v0C45p1064*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1065*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1066*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1067*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Reader
+
+usb:v0C45p1158*
+ ID_PRODUCT_FROM_DATABASE=A56AK
+
+usb:v0C45p184C*
+ ID_PRODUCT_FROM_DATABASE=VoIP Phone
+
+usb:v0C45p6001*
+ ID_PRODUCT_FROM_DATABASE=Genius VideoCAM NB
+
+usb:v0C45p6005*
+ ID_PRODUCT_FROM_DATABASE=Sweex Mini Webcam
+
+usb:v0C45p6007*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Eye
+
+usb:v0C45p6009*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII
+
+usb:v0C45p600D*
+ ID_PRODUCT_FROM_DATABASE=TwinkleCam USB camera
+
+usb:v0C45p6011*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C102)
+
+usb:v0C45p6019*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C102)
+
+usb:v0C45p6024*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII
+
+usb:v0C45p6025*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII
+
+usb:v0C45p6028*
+ ID_PRODUCT_FROM_DATABASE=Typhoon Easycam USB 330K (older)
+
+usb:v0C45p6029*
+ ID_PRODUCT_FROM_DATABASE=Triplex i-mini PC Camera
+
+usb:v0C45p602A*
+ ID_PRODUCT_FROM_DATABASE=Meade ETX-105EC Camera
+
+usb:v0C45p602B*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM NB 300
+
+usb:v0C45p602C*
+ ID_PRODUCT_FROM_DATABASE=Clas Ohlson TWC-30XOP Webcam
+
+usb:v0C45p602D*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII
+
+usb:v0C45p602E*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Messenger
+
+usb:v0C45p6030*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII
+
+usb:v0C45p603F*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII
+
+usb:v0C45p6040*
+ ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A)
+
+usb:v0C45p606A*
+ ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A)
+
+usb:v0C45p607A*
+ ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A)
+
+usb:v0C45p607B*
+ ID_PRODUCT_FROM_DATABASE=Win2 PC Camera
+
+usb:v0C45p607C*
+ ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A)
+
+usb:v0C45p607E*
+ ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A)
+
+usb:v0C45p6080*
+ ID_PRODUCT_FROM_DATABASE=Audio (Microphone)
+
+usb:v0C45p6082*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Look
+
+usb:v0C45p6083*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Look
+
+usb:v0C45p608C*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Look
+
+usb:v0C45p608E*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Look
+
+usb:v0C45p608F*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C103 + OV7630)
+
+usb:v0C45p60A8*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Look
+
+usb:v0C45p60AA*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Look
+
+usb:v0C45p60AB*
+ ID_PRODUCT_FROM_DATABASE=PC Camera
+
+usb:v0C45p60AF*
+ ID_PRODUCT_FROM_DATABASE=VideoCAM Look
+
+usb:v0C45p60B0*
+ ID_PRODUCT_FROM_DATABASE=Genius VideoCam Look
+
+usb:v0C45p60C0*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105)
+
+usb:v0C45p60C8*
+ ID_PRODUCT_FROM_DATABASE=Win2 PC Camera
+
+usb:v0C45p60CC*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105)
+
+usb:v0C45p60EC*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105)
+
+usb:v0C45p60EF*
+ ID_PRODUCT_FROM_DATABASE=Win2 PC Camera
+
+usb:v0C45p60FA*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105)
+
+usb:v0C45p60FB*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v0C45p60FC*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105)
+
+usb:v0C45p60FE*
+ ID_PRODUCT_FROM_DATABASE=Audio (Microphone)
+
+usb:v0C45p6108*
+ ID_PRODUCT_FROM_DATABASE=Win2 PC Camera
+
+usb:v0C45p6122*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110)
+
+usb:v0C45p6123*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110)
+
+usb:v0C45p6128*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C325 + OM6802)
+
+usb:v0C45p612A*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C325)
+
+usb:v0C45p612C*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110)
+
+usb:v0C45p612E*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110)
+
+usb:v0C45p612F*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110)
+
+usb:v0C45p6130*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120)
+
+usb:v0C45p6138*
+ ID_PRODUCT_FROM_DATABASE=Win2 PC Camera
+
+usb:v0C45p613A*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120)
+
+usb:v0C45p613B*
+ ID_PRODUCT_FROM_DATABASE=Win2 PC Camera
+
+usb:v0C45p613C*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120)
+
+usb:v0C45p613E*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120)
+
+usb:v0C45p6143*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120 + SP80708)
+
+usb:v0C45p6240*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + MI1300)
+
+usb:v0C45p6242*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + MI1310)
+
+usb:v0C45p6243*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + S5K4AAFX)
+
+usb:v0C45p6248*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV9655)
+
+usb:v0C45p624B*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + CX1332)
+
+usb:v0C45p624C*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + MI1320)
+
+usb:v0C45p624E*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + SOI968)
+
+usb:v0C45p624F*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV9650)
+
+usb:v0C45p6251*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV9650)
+
+usb:v0C45p6253*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV9650)
+
+usb:v0C45p6260*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV7670ISP)
+
+usb:v0C45p6262*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OM6802)
+
+usb:v0C45p6270*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + MI0360/MT9V011 or MI0360SOC/MT9V111) U-CAM PC Camera NE878, Whitcom WHC017, ...
+
+usb:v0C45p627A*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + S5K53BEB)
+
+usb:v0C45p627B*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV7660)
+
+usb:v0C45p627C*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + HV7131R)
+
+usb:v0C45p627F*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV965x + EEPROM)
+
+usb:v0C45p6280*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + MI1300)
+
+usb:v0C45p6282*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + MI1310)
+
+usb:v0C45p6283*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + S5K4AAFX)
+
+usb:v0C45p6288*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV9655)
+
+usb:v0C45p628A*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + ICM107)
+
+usb:v0C45p628B*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + CX1332)
+
+usb:v0C45p628C*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + MI1320)
+
+usb:v0C45p628E*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + SOI968)
+
+usb:v0C45p628F*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV9650)
+
+usb:v0C45p62A0*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV7670ISP)
+
+usb:v0C45p62A2*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OM6802)
+
+usb:v0C45p62B0*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + MI0360/MT9V011 or MI0360SOC/MT9V111)
+
+usb:v0C45p62B3*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV9655)
+
+usb:v0C45p62BA*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + S5K53BEB)
+
+usb:v0C45p62BB*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV7660)
+
+usb:v0C45p62BC*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + HV7131R)
+
+usb:v0C45p62BE*
+ ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV7663)
+
+usb:v0C45p62C0*
+ ID_PRODUCT_FROM_DATABASE=Sonix USB 2.0 Camera
+
+usb:v0C45p62E0*
+ ID_PRODUCT_FROM_DATABASE=MSI Starcam Racer
+
+usb:v0C45p6310*
+ ID_PRODUCT_FROM_DATABASE=Sonix USB 2.0 Camera
+
+usb:v0C45p63E0*
+ ID_PRODUCT_FROM_DATABASE=Sonix Integrated Webcam
+
+usb:v0C45p63F1*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v0C45p63F8*
+ ID_PRODUCT_FROM_DATABASE=Sonix Integrated Webcam
+
+usb:v0C45p6409*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v0C45p6413*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v0C45p6417*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v0C45p641D*
+ ID_PRODUCT_FROM_DATABASE=1.3 MPixel Integrated Webcam
+
+usb:v0C45p6480*
+ ID_PRODUCT_FROM_DATABASE=Sonix 1.3 MP Laptop Integrated Webcam
+
+usb:v0C45p648B*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v0C45p64BD*
+ ID_PRODUCT_FROM_DATABASE=Sony Visual Communication Camera
+
+usb:v0C45p7402*
+ ID_PRODUCT_FROM_DATABASE=TEMPerHUM Temperature & Humidity Sensor
+
+usb:v0C45p7403*
+ ID_PRODUCT_FROM_DATABASE=Foot Switch
+
+usb:v0C45p8000*
+ ID_PRODUCT_FROM_DATABASE=DC31VC
+
+usb:v0C45p8006*
+ ID_PRODUCT_FROM_DATABASE=Dual Mode Camera (8006 VGA)
+
+usb:v0C45p800A*
+ ID_PRODUCT_FROM_DATABASE=Vivitar Vivicam3350B
+
+usb:v0C46*
+ ID_VENDOR_FROM_DATABASE=WaveRider Communications, Inc.
+
+usb:v0C4A*
+ ID_VENDOR_FROM_DATABASE=ALGE-TIMING GmbH
+
+usb:v0C4Ap0889*
+ ID_PRODUCT_FROM_DATABASE=Timy
+
+usb:v0C4Ap088A*
+ ID_PRODUCT_FROM_DATABASE=Timy 2
+
+usb:v0C4B*
+ ID_VENDOR_FROM_DATABASE=Reiner SCT Kartensysteme GmbH
+
+usb:v0C4Bp0100*
+ ID_PRODUCT_FROM_DATABASE=cyberJack e-com/pinpad
+
+usb:v0C4Bp0300*
+ ID_PRODUCT_FROM_DATABASE=cyberJack pinpad(a)
+
+usb:v0C4Bp9102*
+ ID_PRODUCT_FROM_DATABASE=cyberJack RFID basis contactless smartcard reader
+
+usb:v0C4C*
+ ID_VENDOR_FROM_DATABASE=Needham's Electronics
+
+usb:v0C4Cp0021*
+ ID_PRODUCT_FROM_DATABASE=EMP-21 Universal Programmer
+
+usb:v0C52*
+ ID_VENDOR_FROM_DATABASE=Sealevel Systems, Inc.
+
+usb:v0C52p2101*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+232
+
+usb:v0C52p2102*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+485
+
+usb:v0C52p2103*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+232I
+
+usb:v0C52p2104*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+485I
+
+usb:v0C52p2211*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+2/232 (Port 1)
+
+usb:v0C52p2212*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+2/485 (Port 1)
+
+usb:v0C52p2213*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+2 (Port 1)
+
+usb:v0C52p2221*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+2/232 (Port 2)
+
+usb:v0C52p2222*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+2/485 (Port 2)
+
+usb:v0C52p2223*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+2 (Port 2)
+
+usb:v0C52p2411*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4/232 (Port 1)
+
+usb:v0C52p2412*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4/485 (Port 1)
+
+usb:v0C52p2413*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4 (Port 1)
+
+usb:v0C52p2421*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4/232 (Port 2)
+
+usb:v0C52p2422*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4/485 (Port 2)
+
+usb:v0C52p2423*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4 (Port 2)
+
+usb:v0C52p2431*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4/232 (Port 3)
+
+usb:v0C52p2432*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4/485 (Port 3)
+
+usb:v0C52p2433*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4 (Port 3)
+
+usb:v0C52p2441*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4/232 (Port 4)
+
+usb:v0C52p2442*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4/485 (Port 4)
+
+usb:v0C52p2443*
+ ID_PRODUCT_FROM_DATABASE=SeaPORT+4 (Port 4)
+
+usb:v0C52p2811*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 1)
+
+usb:v0C52p2812*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 1)
+
+usb:v0C52p2813*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 1)
+
+usb:v0C52p2821*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 2)
+
+usb:v0C52p2822*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 2)
+
+usb:v0C52p2823*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 2)
+
+usb:v0C52p2831*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 3)
+
+usb:v0C52p2832*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 3)
+
+usb:v0C52p2833*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 3)
+
+usb:v0C52p2841*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 4)
+
+usb:v0C52p2842*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 4)
+
+usb:v0C52p2843*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 4)
+
+usb:v0C52p2851*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 5)
+
+usb:v0C52p2852*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 5)
+
+usb:v0C52p2853*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 5)
+
+usb:v0C52p2861*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 6)
+
+usb:v0C52p2862*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 6)
+
+usb:v0C52p2863*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 6)
+
+usb:v0C52p2871*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 7)
+
+usb:v0C52p2872*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 7)
+
+usb:v0C52p2873*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 7)
+
+usb:v0C52p2881*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 8)
+
+usb:v0C52p2882*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 8)
+
+usb:v0C52p2883*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 8)
+
+usb:v0C52p9020*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+422
+
+usb:v0C52pA02A*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 1+2)
+
+usb:v0C52pA02B*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 3+4)
+
+usb:v0C52pA02C*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 5+6)
+
+usb:v0C52pA02D*
+ ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 7+8)
+
+usb:v0C53*
+ ID_VENDOR_FROM_DATABASE=ViewPLUS, Inc.
+
+usb:v0C54*
+ ID_VENDOR_FROM_DATABASE=Glory, Ltd
+
+usb:v0C55*
+ ID_VENDOR_FROM_DATABASE=Spectrum Digital, Inc.
+
+usb:v0C55p0510*
+ ID_PRODUCT_FROM_DATABASE=Spectrum Digital XDS510 JTAG Debugger
+
+usb:v0C55p0540*
+ ID_PRODUCT_FROM_DATABASE=SPI540
+
+usb:v0C55p5416*
+ ID_PRODUCT_FROM_DATABASE=TMS320C5416 DSK
+
+usb:v0C55p6416*
+ ID_PRODUCT_FROM_DATABASE=TMS320C6416 DDB
+
+usb:v0C56*
+ ID_VENDOR_FROM_DATABASE=Billion Bright, Ltd
+
+usb:v0C57*
+ ID_VENDOR_FROM_DATABASE=Imaginative Design Operation Co., Ltd
+
+usb:v0C58*
+ ID_VENDOR_FROM_DATABASE=Vidar Systems Corp.
+
+usb:v0C59*
+ ID_VENDOR_FROM_DATABASE=Dong Guan Shinko Wire Co., Ltd
+
+usb:v0C5A*
+ ID_VENDOR_FROM_DATABASE=TRS International Mfg., Inc.
+
+usb:v0C5E*
+ ID_VENDOR_FROM_DATABASE=Xytronix Research & Design
+
+usb:v0C60*
+ ID_VENDOR_FROM_DATABASE=Apogee Electronics Corp.
+
+usb:v0C62*
+ ID_VENDOR_FROM_DATABASE=Chant Sincere Co., Ltd
+
+usb:v0C63*
+ ID_VENDOR_FROM_DATABASE=Toko, Inc.
+
+usb:v0C64*
+ ID_VENDOR_FROM_DATABASE=Signality System Engineering Co., Ltd
+
+usb:v0C65*
+ ID_VENDOR_FROM_DATABASE=Eminence Enterprise Co., Ltd
+
+usb:v0C66*
+ ID_VENDOR_FROM_DATABASE=Rexon Electronics Corp.
+
+usb:v0C67*
+ ID_VENDOR_FROM_DATABASE=Concept Telecom, Ltd
+
+usb:v0C6A*
+ ID_VENDOR_FROM_DATABASE=ACS
+
+usb:v0C6Ap0005*
+ ID_PRODUCT_FROM_DATABASE=Color 320 x 240 LCD Display Terminal with Touchscreen
+
+usb:v0C6C*
+ ID_VENDOR_FROM_DATABASE=JETI Technische Instrumente GmbH
+
+usb:v0C6Cp04B2*
+ ID_PRODUCT_FROM_DATABASE=Specbos 1201
+
+usb:v0C70*
+ ID_VENDOR_FROM_DATABASE=MCT Elektronikladen
+
+usb:v0C70p0000*
+ ID_PRODUCT_FROM_DATABASE=USB08 Development board
+
+usb:v0C70p0747*
+ ID_PRODUCT_FROM_DATABASE=Eye Movement Recorder [Visagraph]/[ReadAlyzer]
+
+usb:v0C72*
+ ID_VENDOR_FROM_DATABASE=PEAK System
+
+usb:v0C72p000C*
+ ID_PRODUCT_FROM_DATABASE=PCAN-USB
+
+usb:v0C72p000D*
+ ID_PRODUCT_FROM_DATABASE=PCAN Pro
+
+usb:v0C74*
+ ID_VENDOR_FROM_DATABASE=Optronic Laboratories Inc.
+
+usb:v0C74p0002*
+ ID_PRODUCT_FROM_DATABASE=OL 700-30 Goniometer
+
+usb:v0C76*
+ ID_VENDOR_FROM_DATABASE=JMTek, LLC.
+
+usb:v0C76p0001*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Controller
+
+usb:v0C76p0002*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Controller
+
+usb:v0C76p0003*
+ ID_PRODUCT_FROM_DATABASE=USBdisk
+
+usb:v0C76p0004*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Controller
+
+usb:v0C76p0005*
+ ID_PRODUCT_FROM_DATABASE=Transcend Flash disk
+
+usb:v0C76p0006*
+ ID_PRODUCT_FROM_DATABASE=Transcend JetFlash
+
+usb:v0C76p0007*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0C76p1600*
+ ID_PRODUCT_FROM_DATABASE=Ion Quick Play LP turntable
+
+usb:v0C76p1605*
+ ID_PRODUCT_FROM_DATABASE=SSS Headphone Set
+
+usb:v0C76p1607*
+ ID_PRODUCT_FROM_DATABASE=audio controller
+
+usb:v0C77*
+ ID_VENDOR_FROM_DATABASE=Sipix Group, Ltd
+
+usb:v0C77p1001*
+ ID_PRODUCT_FROM_DATABASE=SiPix Web2
+
+usb:v0C77p1002*
+ ID_PRODUCT_FROM_DATABASE=SiPix SC2100
+
+usb:v0C77p1010*
+ ID_PRODUCT_FROM_DATABASE=SiPix Snap
+
+usb:v0C77p1011*
+ ID_PRODUCT_FROM_DATABASE=SiPix Blink 2
+
+usb:v0C77p1015*
+ ID_PRODUCT_FROM_DATABASE=SiPix CAMeleon
+
+usb:v0C78*
+ ID_VENDOR_FROM_DATABASE=Detto Corp.
+
+usb:v0C79*
+ ID_VENDOR_FROM_DATABASE=NuConnex Technologies Pte., Ltd
+
+usb:v0C7A*
+ ID_VENDOR_FROM_DATABASE=Wing-Span Enterprise Co., Ltd
+
+usb:v0C86*
+ ID_VENDOR_FROM_DATABASE=NDA Technologies, Inc.
+
+usb:v0C88*
+ ID_VENDOR_FROM_DATABASE=Kyocera Wireless Corp.
+
+usb:v0C88p0021*
+ ID_PRODUCT_FROM_DATABASE=Handheld
+
+usb:v0C88p17DA*
+ ID_PRODUCT_FROM_DATABASE=Qualcomm Kyocera CDMA Technologies MSM
+
+usb:v0C89*
+ ID_VENDOR_FROM_DATABASE=Honda Tsushin Kogyo Co., Ltd
+
+usb:v0C8A*
+ ID_VENDOR_FROM_DATABASE=Pathway Connectivity, Inc.
+
+usb:v0C8B*
+ ID_VENDOR_FROM_DATABASE=Wavefly Corp.
+
+usb:v0C8C*
+ ID_VENDOR_FROM_DATABASE=Coactive Networks
+
+usb:v0C8D*
+ ID_VENDOR_FROM_DATABASE=Tempo
+
+usb:v0C8E*
+ ID_VENDOR_FROM_DATABASE=Cesscom Co., Ltd
+
+usb:v0C8Ep6000*
+ ID_PRODUCT_FROM_DATABASE=Luxian Series
+
+usb:v0C8F*
+ ID_VENDOR_FROM_DATABASE=Applied Microsystems
+
+usb:v0C94*
+ ID_VENDOR_FROM_DATABASE=Cryptera
+
+usb:v0C94pA000*
+ ID_PRODUCT_FROM_DATABASE=EPP 1217
+
+usb:v0C98*
+ ID_VENDOR_FROM_DATABASE=Berkshire Products, Inc.
+
+usb:v0C98p1140*
+ ID_PRODUCT_FROM_DATABASE=USB PC Watchdog
+
+usb:v0C99*
+ ID_VENDOR_FROM_DATABASE=Innochips Co., Ltd
+
+usb:v0C9A*
+ ID_VENDOR_FROM_DATABASE=Hanwool Robotics Corp.
+
+usb:v0C9B*
+ ID_VENDOR_FROM_DATABASE=Jobin Yvon, Inc.
+
+usb:v0C9D*
+ ID_VENDOR_FROM_DATABASE=SemTek
+
+usb:v0C9Dp0170*
+ ID_PRODUCT_FROM_DATABASE=3873 Manual Insert card reader
+
+usb:v0CA2*
+ ID_VENDOR_FROM_DATABASE=Zyfer
+
+usb:v0CA3*
+ ID_VENDOR_FROM_DATABASE=Sega Corp.
+
+usb:v0CA4*
+ ID_VENDOR_FROM_DATABASE=ST&T Instrument Corp.
+
+usb:v0CA5*
+ ID_VENDOR_FROM_DATABASE=BAE Systems Canada, Inc.
+
+usb:v0CA6*
+ ID_VENDOR_FROM_DATABASE=Castles Technology Co., Ltd
+
+usb:v0CA6p0010*
+ ID_PRODUCT_FROM_DATABASE=EZUSB PC/SC Smart Card Reader
+
+usb:v0CA6p0050*
+ ID_PRODUCT_FROM_DATABASE=EZ220PU Reader Controller
+
+usb:v0CA6p1077*
+ ID_PRODUCT_FROM_DATABASE=Bludrive Family Smart Card Reader
+
+usb:v0CA6p107E*
+ ID_PRODUCT_FROM_DATABASE=Reader Controller
+
+usb:v0CA6p2010*
+ ID_PRODUCT_FROM_DATABASE=myPad110 PC/SC Smart Card Reader
+
+usb:v0CA6p3050*
+ ID_PRODUCT_FROM_DATABASE=EZ710 Smart Card Reader
+
+usb:v0CA7*
+ ID_VENDOR_FROM_DATABASE=Information Systems Laboratories
+
+usb:v0CAD*
+ ID_VENDOR_FROM_DATABASE=Motorola CGISS
+
+usb:v0CADp9001*
+ ID_PRODUCT_FROM_DATABASE=PowerPad Pocket PC Device
+
+usb:v0CAE*
+ ID_VENDOR_FROM_DATABASE=Ascom Business Systems, Ltd
+
+usb:v0CAF*
+ ID_VENDOR_FROM_DATABASE=Buslink
+
+usb:v0CAFp2507*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v0CAFp2515*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk Embedded Hub
+
+usb:v0CAFp2516*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk Security Device
+
+usb:v0CAFp2517*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk Mass Storage Device
+
+usb:v0CAFp25C7*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v0CAFp3A00*
+ ID_PRODUCT_FROM_DATABASE=Hard Drive
+
+usb:v0CAFp3A20*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0CAFp3ACD*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0CB0*
+ ID_VENDOR_FROM_DATABASE=Flying Pig Systems
+
+usb:v0CB1*
+ ID_VENDOR_FROM_DATABASE=Innovonics, Inc.
+
+usb:v0CB6*
+ ID_VENDOR_FROM_DATABASE=Celestix Networks, Pte., Ltd
+
+usb:v0CB7*
+ ID_VENDOR_FROM_DATABASE=Singatron Enterprise Co., Ltd
+
+usb:v0CB8*
+ ID_VENDOR_FROM_DATABASE=Opticis Co., Ltd
+
+usb:v0CBA*
+ ID_VENDOR_FROM_DATABASE=Trust Electronic (Shanghai) Co., Ltd
+
+usb:v0CBB*
+ ID_VENDOR_FROM_DATABASE=Shanghai Darong Electronics Co., Ltd
+
+usb:v0CBC*
+ ID_VENDOR_FROM_DATABASE=Palmax Technology Co., Ltd
+
+usb:v0CBCp0101*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC P6C
+
+usb:v0CBCp0201*
+ ID_PRODUCT_FROM_DATABASE=Personal Digital Assistant
+
+usb:v0CBCp0301*
+ ID_PRODUCT_FROM_DATABASE=Personal Digital Assistant P6M+
+
+usb:v0CBCp0401*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC
+
+usb:v0CBD*
+ ID_VENDOR_FROM_DATABASE=Pentel Co., Ltd (Electronics Equipment Div.)
+
+usb:v0CBE*
+ ID_VENDOR_FROM_DATABASE=Keryx Technologies, Inc.
+
+usb:v0CBF*
+ ID_VENDOR_FROM_DATABASE=Union Genius Computer Co., Ltd
+
+usb:v0CC0*
+ ID_VENDOR_FROM_DATABASE=Kuon Yi Industrial Corp.
+
+usb:v0CC1*
+ ID_VENDOR_FROM_DATABASE=Given Imaging, Ltd
+
+usb:v0CC2*
+ ID_VENDOR_FROM_DATABASE=Timex Corp.
+
+usb:v0CC3*
+ ID_VENDOR_FROM_DATABASE=Rimage Corp.
+
+usb:v0CC4*
+ ID_VENDOR_FROM_DATABASE=emsys GmbH
+
+usb:v0CC5*
+ ID_VENDOR_FROM_DATABASE=Sendo
+
+usb:v0CC6*
+ ID_VENDOR_FROM_DATABASE=Intermagic Corp.
+
+usb:v0CC7*
+ ID_VENDOR_FROM_DATABASE=Kontron Medical AG
+
+usb:v0CC8*
+ ID_VENDOR_FROM_DATABASE=Technotools Corp.
+
+usb:v0CC9*
+ ID_VENDOR_FROM_DATABASE=BroadMAX Technologies, Inc.
+
+usb:v0CCA*
+ ID_VENDOR_FROM_DATABASE=Amphenol
+
+usb:v0CCB*
+ ID_VENDOR_FROM_DATABASE=SKNet Co., Ltd
+
+usb:v0CCC*
+ ID_VENDOR_FROM_DATABASE=Domex Technology Corp.
+
+usb:v0CCD*
+ ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH
+
+usb:v0CCDp0012*
+ ID_PRODUCT_FROM_DATABASE=PHASE 26
+
+usb:v0CCDp0013*
+ ID_PRODUCT_FROM_DATABASE=PHASE 26
+
+usb:v0CCDp0014*
+ ID_PRODUCT_FROM_DATABASE=PHASE 26
+
+usb:v0CCDp0015*
+ ID_PRODUCT_FROM_DATABASE=Flash Update for TerraTec PHASE 26
+
+usb:v0CCDp0021*
+ ID_PRODUCT_FROM_DATABASE=Cameo Grabster 200
+
+usb:v0CCDp0023*
+ ID_PRODUCT_FROM_DATABASE=Mystify Claw
+
+usb:v0CCDp0028*
+ ID_PRODUCT_FROM_DATABASE=Aureon 5.1 MkII
+
+usb:v0CCDp0032*
+ ID_PRODUCT_FROM_DATABASE=MIDI HUBBLE
+
+usb:v0CCDp0035*
+ ID_PRODUCT_FROM_DATABASE=Miditech Play'n Roll
+
+usb:v0CCDp0036*
+ ID_PRODUCT_FROM_DATABASE=Cinergy 250 Audio
+
+usb:v0CCDp0037*
+ ID_PRODUCT_FROM_DATABASE=Cinergy 250 Audio
+
+usb:v0CCDp0038*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T² DVB-T Receiver
+
+usb:v0CCDp0039*
+ ID_PRODUCT_FROM_DATABASE=Grabster AV 400
+
+usb:v0CCDp003B*
+ ID_PRODUCT_FROM_DATABASE=Cinergy 400
+
+usb:v0CCDp003C*
+ ID_PRODUCT_FROM_DATABASE=Grabster AV 250
+
+usb:v0CCDp0042*
+ ID_PRODUCT_FROM_DATABASE=Cinergy Hybrid T XS
+
+usb:v0CCDp0043*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T XS
+
+usb:v0CCDp004E*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T XS
+
+usb:v0CCDp004F*
+ ID_PRODUCT_FROM_DATABASE=Cinergy Analog XS
+
+usb:v0CCDp0055*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T XE (Version 1, AF9005)
+
+usb:v0CCDp005C*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T²
+
+usb:v0CCDp0069*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T XE (Version 2, AF9015)
+
+usb:v0CCDp006B*
+ ID_PRODUCT_FROM_DATABASE=Cinergy HT PVR (EU)
+
+usb:v0CCDp0072*
+ ID_PRODUCT_FROM_DATABASE=Cinergy Hybrid T
+
+usb:v0CCDp0077*
+ ID_PRODUCT_FROM_DATABASE=Aureon Dual USB
+
+usb:v0CCDp0078*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T XXS
+
+usb:v0CCDp0086*
+ ID_PRODUCT_FROM_DATABASE=Cinergy Hybrid XE
+
+usb:v0CCDp008E*
+ ID_PRODUCT_FROM_DATABASE=Cinergy HTC XS
+
+usb:v0CCDp0097*
+ ID_PRODUCT_FROM_DATABASE=Cinergy T RC MKII
+
+usb:v0CCDp0099*
+ ID_PRODUCT_FROM_DATABASE=AfaTech 9015 [Cinergy T Stick Dual]
+
+usb:v0CCDp00A5*
+ ID_PRODUCT_FROM_DATABASE=Cinergy Hybrid Stick
+
+usb:v0CCDp00A9*
+ ID_PRODUCT_FROM_DATABASE=RTL2838 DVB-T COFDM Demodulator [TerraTec Cinergy T Stick Black]
+
+usb:v0CCDp00B3*
+ ID_PRODUCT_FROM_DATABASE=NOXON DAB/DAB+ Stick
+
+usb:v0CCDp10A7*
+ ID_PRODUCT_FROM_DATABASE=TerraTec G3
+
+usb:v0CD4*
+ ID_VENDOR_FROM_DATABASE=Bang Olufsen
+
+usb:v0CD4p0101*
+ ID_PRODUCT_FROM_DATABASE=BeolinkPC2
+
+usb:v0CD5*
+ ID_VENDOR_FROM_DATABASE=LabJack Corporation
+
+usb:v0CD5p0003*
+ ID_PRODUCT_FROM_DATABASE=U3
+
+usb:v0CD5p0009*
+ ID_PRODUCT_FROM_DATABASE=UE9
+
+usb:v0CD7*
+ ID_VENDOR_FROM_DATABASE=NewChip S.r.l.
+
+usb:v0CD8*
+ ID_VENDOR_FROM_DATABASE=JS Digitech, Inc.
+
+usb:v0CD8p2007*
+ ID_PRODUCT_FROM_DATABASE=Smart Card Reader/JSTU-9700
+
+usb:v0CD9*
+ ID_VENDOR_FROM_DATABASE=Hitachi Shin Din Cable, Ltd
+
+usb:v0CDE*
+ ID_VENDOR_FROM_DATABASE=Z-Com
+
+usb:v0CDEp0001*
+ ID_PRODUCT_FROM_DATABASE=XI-750 802.11b Wireless Adapter [Atmel AT76C503A]
+
+usb:v0CDEp0002*
+ ID_PRODUCT_FROM_DATABASE=XI-725/726 Prism2.5 802.11b Adapter
+
+usb:v0CDEp0003*
+ ID_PRODUCT_FROM_DATABASE=Sagem 802.11b Dongle
+
+usb:v0CDEp0004*
+ ID_PRODUCT_FROM_DATABASE=Sagem 802.11b Dongle
+
+usb:v0CDEp0005*
+ ID_PRODUCT_FROM_DATABASE=XI-735 Prism3 802.11b Adapter
+
+usb:v0CDEp0006*
+ ID_PRODUCT_FROM_DATABASE=XG-300 802.11b Adapter
+
+usb:v0CDEp0008*
+ ID_PRODUCT_FROM_DATABASE=XG-703A 802.11g Wireless Adapter [Intersil ISL3887]
+
+usb:v0CDEp0009*
+ ID_PRODUCT_FROM_DATABASE=(ZD1211)IEEE 802.11b+g Adapter
+
+usb:v0CDEp0011*
+ ID_PRODUCT_FROM_DATABASE=ZD1211
+
+usb:v0CDEp0012*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v0CDEp0013*
+ ID_PRODUCT_FROM_DATABASE=AR5523 driver (no firmware)
+
+usb:v0CDEp0014*
+ ID_PRODUCT_FROM_DATABASE=NB 802.11g Wireless LAN Adapter(3887A)
+
+usb:v0CDEp0015*
+ ID_PRODUCT_FROM_DATABASE=XG-705A 802.11g Wireless Adapter [Intersil ISL3887]
+
+usb:v0CDEp0016*
+ ID_PRODUCT_FROM_DATABASE=NB 802.11g Wireless LAN Adapter(3887A)
+
+usb:v0CDEp0018*
+ ID_PRODUCT_FROM_DATABASE=NB 802.11a/b/g Wireless LAN Adapter(3887A)
+
+usb:v0CDEp001A*
+ ID_PRODUCT_FROM_DATABASE=802.11bg
+
+usb:v0CDEp001C*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g Wireless Network Adapter
+
+usb:v0CDEp0020*
+ ID_PRODUCT_FROM_DATABASE=AG-760A 802.11abg Wireless Adapter [ZyDAS ZD1211B]
+
+usb:v0CDEp0022*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g/n Wireless Network Adapter
+
+usb:v0CDEp0023*
+ ID_PRODUCT_FROM_DATABASE=UB81 802.11bgn
+
+usb:v0CDEp0025*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g/n USB Wireless Network Adapter
+
+usb:v0CDEp0026*
+ ID_PRODUCT_FROM_DATABASE=UB82 802.11abgn
+
+usb:v0CDEp0027*
+ ID_PRODUCT_FROM_DATABASE=Sphairon Homelink 1202 802.11n Wireless Adapter [Atheros AR9170]
+
+usb:v0CE5*
+ ID_VENDOR_FROM_DATABASE=Validation Technologies International
+
+usb:v0CE5p0003*
+ ID_PRODUCT_FROM_DATABASE=Matrix
+
+usb:v0CE9*
+ ID_VENDOR_FROM_DATABASE=pico Technology
+
+usb:v0CE9p1001*
+ ID_PRODUCT_FROM_DATABASE=PicoScope3204
+
+usb:v0CF1*
+ ID_VENDOR_FROM_DATABASE=e-Conn Electronic Co., Ltd
+
+usb:v0CF2*
+ ID_VENDOR_FROM_DATABASE=ENE Technology, Inc.
+
+usb:v0CF2p6220*
+ ID_PRODUCT_FROM_DATABASE=SD Card Reader (SG361)
+
+usb:v0CF2p6225*
+ ID_PRODUCT_FROM_DATABASE=SD card reader (UB6225)
+
+usb:v0CF2p6250*
+ ID_PRODUCT_FROM_DATABASE=SD card reader (UB6250)
+
+usb:v0CF3*
+ ID_VENDOR_FROM_DATABASE=Atheros Communications, Inc.
+
+usb:v0CF3p0001*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v0CF3p0002*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v0CF3p0003*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v0CF3p0004*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v0CF3p0005*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v0CF3p0006*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v0CF3p1001*
+ ID_PRODUCT_FROM_DATABASE=Thomson TG121N [Atheros AR9001U-(2)NG]
+
+usb:v0CF3p1002*
+ ID_PRODUCT_FROM_DATABASE=TP-Link TL-WN821N v2 802.11n [Atheros AR9170]
+
+usb:v0CF3p1006*
+ ID_PRODUCT_FROM_DATABASE=TP-Link TL-WN322G v3 / TL-WN422G v2 802.11g [Atheros AR9271]
+
+usb:v0CF3p1010*
+ ID_PRODUCT_FROM_DATABASE=3Com 3CRUSBN275 802.11abgn Wireless Adapter [Atheros AR9170]
+
+usb:v0CF3p20FF*
+ ID_PRODUCT_FROM_DATABASE=AR7010 (no firmware)
+
+usb:v0CF3p3000*
+ ID_PRODUCT_FROM_DATABASE=AR3011 Bluetooth (no firmware)
+
+usb:v0CF3p3002*
+ ID_PRODUCT_FROM_DATABASE=AR3011 Bluetooth
+
+usb:v0CF3p3005*
+ ID_PRODUCT_FROM_DATABASE=AR3011 Bluetooth
+
+usb:v0CF3p7015*
+ ID_PRODUCT_FROM_DATABASE=TP-Link TL-WN821N v3 802.11n [Atheros AR7010+AR9287]
+
+usb:v0CF3p9170*
+ ID_PRODUCT_FROM_DATABASE=AR9170 802.11n
+
+usb:v0CF3p9271*
+ ID_PRODUCT_FROM_DATABASE=AR9271 802.11n
+
+usb:v0CF3pB002*
+ ID_PRODUCT_FROM_DATABASE=Ubiquiti WiFiStation 802.11n [Atheros AR9271]
+
+usb:v0CF3pB003*
+ ID_PRODUCT_FROM_DATABASE=Ubiquiti WiFiStationEXT 802.11n [Atheros AR9271]
+
+usb:v0CF4*
+ ID_VENDOR_FROM_DATABASE=Fomtex Corp.
+
+usb:v0CF5*
+ ID_VENDOR_FROM_DATABASE=Cellink Co., Ltd
+
+usb:v0CF6*
+ ID_VENDOR_FROM_DATABASE=Compucable Corp.
+
+usb:v0CF7*
+ ID_VENDOR_FROM_DATABASE=ishoni Networks
+
+usb:v0CF8*
+ ID_VENDOR_FROM_DATABASE=Clarisys, Inc.
+
+usb:v0CF8p0750*
+ ID_PRODUCT_FROM_DATABASE=Claritel-i750 - vp
+
+usb:v0CF9*
+ ID_VENDOR_FROM_DATABASE=Central System Research Co., Ltd
+
+usb:v0CFA*
+ ID_VENDOR_FROM_DATABASE=Inviso, Inc.
+
+usb:v0CFC*
+ ID_VENDOR_FROM_DATABASE=Minolta-QMS, Inc.
+
+usb:v0CFCp2301*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2300 DL
+
+usb:v0CFCp2350*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2350EN/3300
+
+usb:v0CFCp3100*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 3100
+
+usb:v0CFCp7300*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 5450/5550
+
+usb:v0CFF*
+ ID_VENDOR_FROM_DATABASE=SAFA MEDIA Co., Ltd.
+
+usb:v0CFFp0320*
+ ID_PRODUCT_FROM_DATABASE=SR-380N
+
+usb:v0D06*
+ ID_VENDOR_FROM_DATABASE=telos EDV Systementwicklung GmbH
+
+usb:v0D08*
+ ID_VENDOR_FROM_DATABASE=UTStarcom
+
+usb:v0D08p0602*
+ ID_PRODUCT_FROM_DATABASE=DV007 [serial]
+
+usb:v0D08p0603*
+ ID_PRODUCT_FROM_DATABASE=DV007 [storage]
+
+usb:v0D0B*
+ ID_VENDOR_FROM_DATABASE=Contemporary Controls
+
+usb:v0D0C*
+ ID_VENDOR_FROM_DATABASE=Astron Electronics Co., Ltd
+
+usb:v0D0D*
+ ID_VENDOR_FROM_DATABASE=MKNet Corp.
+
+usb:v0D0E*
+ ID_VENDOR_FROM_DATABASE=Hybrid Networks, Inc.
+
+usb:v0D0F*
+ ID_VENDOR_FROM_DATABASE=Feng Shin Cable Co., Ltd
+
+usb:v0D10*
+ ID_VENDOR_FROM_DATABASE=Elastic Networks
+
+usb:v0D10p0001*
+ ID_PRODUCT_FROM_DATABASE=StormPort (WDM)
+
+usb:v0D11*
+ ID_VENDOR_FROM_DATABASE=Maspro Denkoh Corp.
+
+usb:v0D12*
+ ID_VENDOR_FROM_DATABASE=Hansol Electronics, Inc.
+
+usb:v0D13*
+ ID_VENDOR_FROM_DATABASE=BMF Corp.
+
+usb:v0D14*
+ ID_VENDOR_FROM_DATABASE=Array Comm, Inc.
+
+usb:v0D15*
+ ID_VENDOR_FROM_DATABASE=OnStream b.v.
+
+usb:v0D16*
+ ID_VENDOR_FROM_DATABASE=Hi-Touch Imaging Technologies Co., Ltd
+
+usb:v0D16p0001*
+ ID_PRODUCT_FROM_DATABASE=PhotoShuttle
+
+usb:v0D16p0002*
+ ID_PRODUCT_FROM_DATABASE=Photo Printer 730 series
+
+usb:v0D16p0004*
+ ID_PRODUCT_FROM_DATABASE=Photo Printer 63xPL/PS
+
+usb:v0D16p0100*
+ ID_PRODUCT_FROM_DATABASE=Photo Printer 63xPL/PS
+
+usb:v0D16p0102*
+ ID_PRODUCT_FROM_DATABASE=Photo Printer 64xPS
+
+usb:v0D16p0103*
+ ID_PRODUCT_FROM_DATABASE=Photo Printer 730 series
+
+usb:v0D16p0104*
+ ID_PRODUCT_FROM_DATABASE=Photo Printer 63xPL/PS
+
+usb:v0D16p0105*
+ ID_PRODUCT_FROM_DATABASE=Photo Printer 64xPS
+
+usb:v0D16p0200*
+ ID_PRODUCT_FROM_DATABASE=Photo Printer 64xDL
+
+usb:v0D17*
+ ID_VENDOR_FROM_DATABASE=NALTEC, Inc.
+
+usb:v0D18*
+ ID_VENDOR_FROM_DATABASE=coaXmedia
+
+usb:v0D19*
+ ID_VENDOR_FROM_DATABASE=Hank Connection Industrial Co., Ltd
+
+usb:v0D28*
+ ID_VENDOR_FROM_DATABASE=NXP
+
+usb:v0D28p0204*
+ ID_PRODUCT_FROM_DATABASE=LPC1768
+
+usb:v0D32*
+ ID_VENDOR_FROM_DATABASE=Leo Hui Electric Wire & Cable Co., Ltd
+
+usb:v0D33*
+ ID_VENDOR_FROM_DATABASE=AirSpeak, Inc.
+
+usb:v0D34*
+ ID_VENDOR_FROM_DATABASE=Rearden Steel Technologies
+
+usb:v0D35*
+ ID_VENDOR_FROM_DATABASE=Dah Kun Co., Ltd
+
+usb:v0D3A*
+ ID_VENDOR_FROM_DATABASE=Posiflex Technologies, Inc.
+
+usb:v0D3C*
+ ID_VENDOR_FROM_DATABASE=Sri Cable Technology, Ltd
+
+usb:v0D3D*
+ ID_VENDOR_FROM_DATABASE=Tangtop Technology Co., Ltd
+
+usb:v0D3Dp0001*
+ ID_PRODUCT_FROM_DATABASE=HID Keyboard
+
+usb:v0D3E*
+ ID_VENDOR_FROM_DATABASE=Fitcom, inc.
+
+usb:v0D3F*
+ ID_VENDOR_FROM_DATABASE=MTS Systems Corp.
+
+usb:v0D40*
+ ID_VENDOR_FROM_DATABASE=Ascor, Inc.
+
+usb:v0D41*
+ ID_VENDOR_FROM_DATABASE=Ta Yun Terminals Industrial Co., Ltd
+
+usb:v0D42*
+ ID_VENDOR_FROM_DATABASE=Full Der Co., Ltd
+
+usb:v0D46*
+ ID_VENDOR_FROM_DATABASE=Kobil Systems GmbH
+
+usb:v0D46p2012*
+ ID_PRODUCT_FROM_DATABASE=KAAN Standard Plus (Smartcard reader)
+
+usb:v0D46p3003*
+ ID_PRODUCT_FROM_DATABASE=mIDentity Light / KAAN SIM III
+
+usb:v0D46p4000*
+ ID_PRODUCT_FROM_DATABASE=mIDentity (mass storage)
+
+usb:v0D46p4001*
+ ID_PRODUCT_FROM_DATABASE=mIDentity Basic/Classic (composite device)
+
+usb:v0D46p4081*
+ ID_PRODUCT_FROM_DATABASE=mIDentity Basic/Classic (installationless)
+
+usb:v0D48*
+ ID_VENDOR_FROM_DATABASE=Promethean Limited
+
+usb:v0D48p0001*
+ ID_PRODUCT_FROM_DATABASE=ACTIVboard
+
+usb:v0D48p0004*
+ ID_PRODUCT_FROM_DATABASE=ACTIVboard
+
+usb:v0D48p0100*
+ ID_PRODUCT_FROM_DATABASE=Audio
+
+usb:v0D49*
+ ID_VENDOR_FROM_DATABASE=Maxtor
+
+usb:v0D49p3000*
+ ID_PRODUCT_FROM_DATABASE=Drive
+
+usb:v0D49p3010*
+ ID_PRODUCT_FROM_DATABASE=3000LE Drive
+
+usb:v0D49p3100*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-IDE Bridge Controller
+
+usb:v0D49p3200*
+ ID_PRODUCT_FROM_DATABASE=Personal Storage 3200
+
+usb:v0D49p5000*
+ ID_PRODUCT_FROM_DATABASE=5000XT Drive
+
+usb:v0D49p5010*
+ ID_PRODUCT_FROM_DATABASE=5000LE Drive
+
+usb:v0D49p5020*
+ ID_PRODUCT_FROM_DATABASE=Mobile Hard Disk Drive
+
+usb:v0D49p7000*
+ ID_PRODUCT_FROM_DATABASE=OneTouch
+
+usb:v0D49p7010*
+ ID_PRODUCT_FROM_DATABASE=OneTouch
+
+usb:v0D49p7100*
+ ID_PRODUCT_FROM_DATABASE=OneTouch II 300GB External Hard Disk
+
+usb:v0D49p7410*
+ ID_PRODUCT_FROM_DATABASE=Mobile Hard Disk Drive (1TB)
+
+usb:v0D49p7450*
+ ID_PRODUCT_FROM_DATABASE=Basics Portable USB Device
+
+usb:v0D4A*
+ ID_VENDOR_FROM_DATABASE=NF Corp.
+
+usb:v0D4B*
+ ID_VENDOR_FROM_DATABASE=Grape Systems, Inc.
+
+usb:v0D4C*
+ ID_VENDOR_FROM_DATABASE=Tedas AG
+
+usb:v0D4D*
+ ID_VENDOR_FROM_DATABASE=Coherent, Inc.
+
+usb:v0D4E*
+ ID_VENDOR_FROM_DATABASE=Agere Systems Netherland BV
+
+usb:v0D4Ep047A*
+ ID_PRODUCT_FROM_DATABASE=WLAN Card
+
+usb:v0D4Ep1000*
+ ID_PRODUCT_FROM_DATABASE=Wireless Card Model 0801
+
+usb:v0D4Ep1001*
+ ID_PRODUCT_FROM_DATABASE=Wireless Card Model 0802
+
+usb:v0D4F*
+ ID_VENDOR_FROM_DATABASE=EADS Airbus France
+
+usb:v0D50*
+ ID_VENDOR_FROM_DATABASE=Cleware GmbH
+
+usb:v0D50p0011*
+ ID_PRODUCT_FROM_DATABASE=USB-Temp2 Thermometer
+
+usb:v0D51*
+ ID_VENDOR_FROM_DATABASE=Volex (Asia) Pte., Ltd
+
+usb:v0D53*
+ ID_VENDOR_FROM_DATABASE=HMI Co., Ltd
+
+usb:v0D54*
+ ID_VENDOR_FROM_DATABASE=Holon Corp.
+
+usb:v0D55*
+ ID_VENDOR_FROM_DATABASE=ASKA Technologies, Inc.
+
+usb:v0D56*
+ ID_VENDOR_FROM_DATABASE=AVLAB Technology, Inc.
+
+usb:v0D57*
+ ID_VENDOR_FROM_DATABASE=Solomon Microtech, Ltd
+
+usb:v0D5C*
+ ID_VENDOR_FROM_DATABASE=SMC Networks, Inc.
+
+usb:v0D5CpA001*
+ ID_PRODUCT_FROM_DATABASE=SMC2662W (v1) EZ Connect 802.11b Wireless Adapter [Atmel AT76C503A]
+
+usb:v0D5CpA002*
+ ID_PRODUCT_FROM_DATABASE=SMC2662W v2 / SMC2662W-AR / Belkin F5D6050 [Atmel at76c503a]
+
+usb:v0D5E*
+ ID_VENDOR_FROM_DATABASE=Myacom, Ltd
+
+usb:v0D5Ep2346*
+ ID_PRODUCT_FROM_DATABASE=BT Digital Access adapter
+
+usb:v0D5F*
+ ID_VENDOR_FROM_DATABASE=CSI, Inc.
+
+usb:v0D60*
+ ID_VENDOR_FROM_DATABASE=IVL Technologies, Ltd
+
+usb:v0D61*
+ ID_VENDOR_FROM_DATABASE=Meilu Electronics (Shenzhen) Co., Ltd
+
+usb:v0D62*
+ ID_VENDOR_FROM_DATABASE=Darfon Electronics Corp.
+
+usb:v0D62p0003*
+ ID_PRODUCT_FROM_DATABASE=Smartcard Reader
+
+usb:v0D62p0004*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v0D62p001C*
+ ID_PRODUCT_FROM_DATABASE=Benq X120 Internet Keyboard Pro
+
+usb:v0D62p0306*
+ ID_PRODUCT_FROM_DATABASE=M530 Mouse
+
+usb:v0D62p0800*
+ ID_PRODUCT_FROM_DATABASE=Magic Wheel
+
+usb:v0D62p2021*
+ ID_PRODUCT_FROM_DATABASE=AM805 Keyboard
+
+usb:v0D62p2026*
+ ID_PRODUCT_FROM_DATABASE=TECOM Bluetooth Device
+
+usb:v0D62p2050*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v0D62p2106*
+ ID_PRODUCT_FROM_DATABASE=Dell L20U Multimedia Keyboard
+
+usb:v0D62pA100*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v0D63*
+ ID_VENDOR_FROM_DATABASE=Fritz Gegauf AG
+
+usb:v0D64*
+ ID_VENDOR_FROM_DATABASE=DXG Technology Corp.
+
+usb:v0D64p0105*
+ ID_PRODUCT_FROM_DATABASE=Dual Mode Digital Camera 1.3M
+
+usb:v0D64p0107*
+ ID_PRODUCT_FROM_DATABASE=Horus MT-409 Camera
+
+usb:v0D64p0108*
+ ID_PRODUCT_FROM_DATABASE=Dual Mode Digital Camera
+
+usb:v0D64p0202*
+ ID_PRODUCT_FROM_DATABASE=Dual Mode Video Camera Device
+
+usb:v0D64p0303*
+ ID_PRODUCT_FROM_DATABASE=DXG-305V Camera
+
+usb:v0D64p1001*
+ ID_PRODUCT_FROM_DATABASE=SiPix Stylecam/UMAX AstraPix 320s
+
+usb:v0D64p1002*
+ ID_PRODUCT_FROM_DATABASE=Fashion Cam 01 Dual-Mode DSC (Video Camera)
+
+usb:v0D64p1003*
+ ID_PRODUCT_FROM_DATABASE=Fashion Cam Dual-Mode DSC (Controller)
+
+usb:v0D64p1021*
+ ID_PRODUCT_FROM_DATABASE=D-Link DSC 350F
+
+usb:v0D64p1208*
+ ID_PRODUCT_FROM_DATABASE=Dual Mode Still Camera Device
+
+usb:v0D64p2208*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage
+
+usb:v0D64p3105*
+ ID_PRODUCT_FROM_DATABASE=Dual Mode Digital Camera Disk
+
+usb:v0D64p3108*
+ ID_PRODUCT_FROM_DATABASE=Digicam Mass Storage Device
+
+usb:v0D65*
+ ID_VENDOR_FROM_DATABASE=KMJP Co., Ltd
+
+usb:v0D66*
+ ID_VENDOR_FROM_DATABASE=TMT
+
+usb:v0D67*
+ ID_VENDOR_FROM_DATABASE=Advanet, Inc.
+
+usb:v0D68*
+ ID_VENDOR_FROM_DATABASE=Super Link Electronics Co., Ltd
+
+usb:v0D69*
+ ID_VENDOR_FROM_DATABASE=NSI
+
+usb:v0D6A*
+ ID_VENDOR_FROM_DATABASE=Megapower International Corp.
+
+usb:v0D6B*
+ ID_VENDOR_FROM_DATABASE=And-Or Logic
+
+usb:v0D70*
+ ID_VENDOR_FROM_DATABASE=Try Computer Co., Ltd
+
+usb:v0D71*
+ ID_VENDOR_FROM_DATABASE=Hirakawa Hewtech Corp.
+
+usb:v0D72*
+ ID_VENDOR_FROM_DATABASE=Winmate Communication, Inc.
+
+usb:v0D73*
+ ID_VENDOR_FROM_DATABASE=Hit's Communications, Inc.
+
+usb:v0D76*
+ ID_VENDOR_FROM_DATABASE=MFP Korea, Inc.
+
+usb:v0D77*
+ ID_VENDOR_FROM_DATABASE=Power Sentry/Newpoint
+
+usb:v0D78*
+ ID_VENDOR_FROM_DATABASE=Japan Distributor Corp.
+
+usb:v0D7A*
+ ID_VENDOR_FROM_DATABASE=MARX Datentechnik GmbH
+
+usb:v0D7B*
+ ID_VENDOR_FROM_DATABASE=Wellco Technology Co., Ltd
+
+usb:v0D7C*
+ ID_VENDOR_FROM_DATABASE=Taiwan Line Tek Electronic Co., Ltd
+
+usb:v0D7D*
+ ID_VENDOR_FROM_DATABASE=Phison Electronics Corp.
+
+usb:v0D7Dp0100*
+ ID_PRODUCT_FROM_DATABASE=PS1001/1011/1006/1026 Flash Disk
+
+usb:v0D7Dp0110*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte FlexDrive
+
+usb:v0D7Dp0120*
+ ID_PRODUCT_FROM_DATABASE=Disk Pro 64MB
+
+usb:v0D7Dp0124*
+ ID_PRODUCT_FROM_DATABASE=GIGABYTE Disk
+
+usb:v0D7Dp0240*
+ ID_PRODUCT_FROM_DATABASE=I/O-Magic/Transcend 6-in-1 Card Reader
+
+usb:v0D7Dp110E*
+ ID_PRODUCT_FROM_DATABASE=NEC uPD720121/130 USB-ATA/ATAPI Bridge
+
+usb:v0D7Dp1240*
+ ID_PRODUCT_FROM_DATABASE=Apacer 6-in-1 Card Reader 2.0
+
+usb:v0D7Dp1270*
+ ID_PRODUCT_FROM_DATABASE=Wolverine SixPac 6000
+
+usb:v0D7Dp1300*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk
+
+usb:v0D7Dp1320*
+ ID_PRODUCT_FROM_DATABASE=PS2031 Flash Disk
+
+usb:v0D7Dp1400*
+ ID_PRODUCT_FROM_DATABASE=Attache 256MB USB 2.0 Flash Drive
+
+usb:v0D7Dp1420*
+ ID_PRODUCT_FROM_DATABASE=PS2044 Pen Drive
+
+usb:v0D7Dp1470*
+ ID_PRODUCT_FROM_DATABASE=Vosonic X's-Drive II+ VP2160
+
+usb:v0D7Dp1620*
+ ID_PRODUCT_FROM_DATABASE=USB Disk Pro
+
+usb:v0D7Dp1900*
+ ID_PRODUCT_FROM_DATABASE=USB Thumb Drive
+
+usb:v0D7E*
+ ID_VENDOR_FROM_DATABASE=American Computer & Digital Components
+
+usb:v0D7Ep2507*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v0D7Ep2517*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device
+
+usb:v0D7Ep25C7*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller
+
+usb:v0D7F*
+ ID_VENDOR_FROM_DATABASE=Essential Reality LLC
+
+usb:v0D7Fp0100*
+ ID_PRODUCT_FROM_DATABASE=P5 Glove glove controller
+
+usb:v0D80*
+ ID_VENDOR_FROM_DATABASE=H.R. Silvine Electronics, Inc.
+
+usb:v0D81*
+ ID_VENDOR_FROM_DATABASE=TechnoVision
+
+usb:v0D83*
+ ID_VENDOR_FROM_DATABASE=Think Outside, Inc.
+
+usb:v0D87*
+ ID_VENDOR_FROM_DATABASE=Dolby Laboratories Inc.
+
+usb:v0D89*
+ ID_VENDOR_FROM_DATABASE=Oz Software
+
+usb:v0D8A*
+ ID_VENDOR_FROM_DATABASE=King Jim Co., Ltd
+
+usb:v0D8Ap0101*
+ ID_PRODUCT_FROM_DATABASE=TEPRA PRO
+
+usb:v0D8B*
+ ID_VENDOR_FROM_DATABASE=Ascom Telecommunications, Ltd
+
+usb:v0D8C*
+ ID_VENDOR_FROM_DATABASE=C-Media Electronics, Inc.
+
+usb:v0D8Cp0001*
+ ID_PRODUCT_FROM_DATABASE=Audio Device
+
+usb:v0D8Cp0002*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v0D8Cp0003*
+ ID_PRODUCT_FROM_DATABASE=Sound Device
+
+usb:v0D8Cp0006*
+ ID_PRODUCT_FROM_DATABASE=Storm HP-USB500 5.1 Headset
+
+usb:v0D8Cp000C*
+ ID_PRODUCT_FROM_DATABASE=Audio Adapter
+
+usb:v0D8Cp000D*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v0D8Cp000E*
+ ID_PRODUCT_FROM_DATABASE=Audio Adapter (Planet UP-100, Genius G-Talk)
+
+usb:v0D8Cp001F*
+ ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller
+
+usb:v0D8Cp0102*
+ ID_PRODUCT_FROM_DATABASE=CM106 Like Sound Device
+
+usb:v0D8Cp0103*
+ ID_PRODUCT_FROM_DATABASE=CM102-A+/102S+ Audio Controller
+
+usb:v0D8Cp0104*
+ ID_PRODUCT_FROM_DATABASE=CM103+ Audio Controller
+
+usb:v0D8Cp0105*
+ ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller
+
+usb:v0D8Cp0107*
+ ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller
+
+usb:v0D8Cp010F*
+ ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller
+
+usb:v0D8Cp0115*
+ ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller
+
+usb:v0D8Cp013C*
+ ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller
+
+usb:v0D8Cp0201*
+ ID_PRODUCT_FROM_DATABASE=CM6501
+
+usb:v0D8Cp5000*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Controller
+
+usb:v0D8Cp5200*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Controller(0D8C,5200)
+
+usb:v0D8CpB213*
+ ID_PRODUCT_FROM_DATABASE=USB Phone CM109 (aka CT2000,VPT1000)
+
+usb:v0D8D*
+ ID_VENDOR_FROM_DATABASE=Promotion & Display Technology, Ltd
+
+usb:v0D8Dp0234*
+ ID_PRODUCT_FROM_DATABASE=V-234 Composite Device
+
+usb:v0D8Dp0550*
+ ID_PRODUCT_FROM_DATABASE=V-550 Composite Device
+
+usb:v0D8Dp0551*
+ ID_PRODUCT_FROM_DATABASE=V-551 Composite Device
+
+usb:v0D8Dp0552*
+ ID_PRODUCT_FROM_DATABASE=V-552 Composite Device
+
+usb:v0D8Dp0651*
+ ID_PRODUCT_FROM_DATABASE=V-651 Composite Device
+
+usb:v0D8Dp0652*
+ ID_PRODUCT_FROM_DATABASE=V-652 Composite Device
+
+usb:v0D8Dp0653*
+ ID_PRODUCT_FROM_DATABASE=V-653 Composite Device
+
+usb:v0D8Dp0654*
+ ID_PRODUCT_FROM_DATABASE=V-654 Composite Device
+
+usb:v0D8Dp0655*
+ ID_PRODUCT_FROM_DATABASE=V-655 Composite Device
+
+usb:v0D8Dp0656*
+ ID_PRODUCT_FROM_DATABASE=V-656 Composite Device
+
+usb:v0D8Dp0657*
+ ID_PRODUCT_FROM_DATABASE=V-657 Composite Device
+
+usb:v0D8Dp0658*
+ ID_PRODUCT_FROM_DATABASE=V-658 Composite Device
+
+usb:v0D8Dp0659*
+ ID_PRODUCT_FROM_DATABASE=V-659 Composite Device
+
+usb:v0D8Dp0660*
+ ID_PRODUCT_FROM_DATABASE=V-660 Composite Device
+
+usb:v0D8Dp0661*
+ ID_PRODUCT_FROM_DATABASE=V-661 Composite Device
+
+usb:v0D8Dp0662*
+ ID_PRODUCT_FROM_DATABASE=V-662 Composite Device
+
+usb:v0D8Dp0850*
+ ID_PRODUCT_FROM_DATABASE=V-850 Composite Device
+
+usb:v0D8Dp0851*
+ ID_PRODUCT_FROM_DATABASE=V-851 Composite Device
+
+usb:v0D8Dp0852*
+ ID_PRODUCT_FROM_DATABASE=V-852 Composite Device
+
+usb:v0D8Dp0901*
+ ID_PRODUCT_FROM_DATABASE=V-901 Composite Device
+
+usb:v0D8Dp0902*
+ ID_PRODUCT_FROM_DATABASE=V-902 Composite Device
+
+usb:v0D8Dp0903*
+ ID_PRODUCT_FROM_DATABASE=V-903 Composite Device
+
+usb:v0D8Dp4754*
+ ID_PRODUCT_FROM_DATABASE=Voyager DMP Composite Device
+
+usb:v0D8DpBB00*
+ ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device
+
+usb:v0D8DpBB01*
+ ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device
+
+usb:v0D8DpBB02*
+ ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device
+
+usb:v0D8DpBB03*
+ ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device
+
+usb:v0D8DpBB04*
+ ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device
+
+usb:v0D8DpBB05*
+ ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device
+
+usb:v0D8DpFFFE*
+ ID_PRODUCT_FROM_DATABASE=Global Tuner Composite Device
+
+usb:v0D8DpFFFF*
+ ID_PRODUCT_FROM_DATABASE=Voyager DMP Composite Device
+
+usb:v0D8E*
+ ID_VENDOR_FROM_DATABASE=Global Sun Technology, Inc.
+
+usb:v0D8Ep0163*
+ ID_PRODUCT_FROM_DATABASE=802.11g 54 Mbps Wireless Dongle
+
+usb:v0D8Ep1621*
+ ID_PRODUCT_FROM_DATABASE=802.11b Wireless Adapter
+
+usb:v0D8Ep3762*
+ ID_PRODUCT_FROM_DATABASE=Cohiba 802.11g Wireless Mini adapter [Intersil ISL3887]
+
+usb:v0D8Ep3763*
+ ID_PRODUCT_FROM_DATABASE=802.11g Wireless dongle
+
+usb:v0D8Ep7100*
+ ID_PRODUCT_FROM_DATABASE=802.11b Adapter
+
+usb:v0D8Ep7110*
+ ID_PRODUCT_FROM_DATABASE=WL-210 / WU210P 802.11b Wireless Adapter [Atmel AT76C503A]
+
+usb:v0D8Ep7605*
+ ID_PRODUCT_FROM_DATABASE=TRENDnet TEW-224UB 802.11b Wireless Adapter [Atmel AT76C503A]
+
+usb:v0D8Ep7801*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v0D8Ep7802*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v0D8Ep7811*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v0D8Ep7812*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v0D8Ep7A01*
+ ID_PRODUCT_FROM_DATABASE=PRISM25 802.11b Adapter
+
+usb:v0D8F*
+ ID_VENDOR_FROM_DATABASE=Pitney Bowes
+
+usb:v0D90*
+ ID_VENDOR_FROM_DATABASE=Sure-Fire Electrical Corp.
+
+usb:v0D96*
+ ID_VENDOR_FROM_DATABASE=Skanhex Technology, Inc.
+
+usb:v0D96p0000*
+ ID_PRODUCT_FROM_DATABASE=Jenoptik JD350 video
+
+usb:v0D96p3300*
+ ID_PRODUCT_FROM_DATABASE=SX330z Camera
+
+usb:v0D96p4100*
+ ID_PRODUCT_FROM_DATABASE=SX410z Camera
+
+usb:v0D96p4102*
+ ID_PRODUCT_FROM_DATABASE=MD 9700 Camera
+
+usb:v0D96p4104*
+ ID_PRODUCT_FROM_DATABASE=Jenoptik JD-4100z3s
+
+usb:v0D96p410A*
+ ID_PRODUCT_FROM_DATABASE=Medion 9801/Novatech SX-410z
+
+usb:v0D96p5200*
+ ID_PRODUCT_FROM_DATABASE=SX-520z Camera
+
+usb:v0D97*
+ ID_VENDOR_FROM_DATABASE=Santa Barbara Instrument Group
+
+usb:v0D97p0001*
+ ID_PRODUCT_FROM_DATABASE=SBIG Astronomy Camera (without firmware)
+
+usb:v0D97p0101*
+ ID_PRODUCT_FROM_DATABASE=SBIG Astronomy Camera (with firmware)
+
+usb:v0D98*
+ ID_VENDOR_FROM_DATABASE=Mars Semiconductor Corp.
+
+usb:v0D98p0300*
+ ID_PRODUCT_FROM_DATABASE=Avaya Wireless Card
+
+usb:v0D98p1007*
+ ID_PRODUCT_FROM_DATABASE=Discovery Kids Digital Camera
+
+usb:v0D99*
+ ID_VENDOR_FROM_DATABASE=Trazer Technologies, Inc.
+
+usb:v0D9A*
+ ID_VENDOR_FROM_DATABASE=RTX Telecom AS
+
+usb:v0D9Ap0001*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0D9B*
+ ID_VENDOR_FROM_DATABASE=Tat Shing Electrical Co.
+
+usb:v0D9C*
+ ID_VENDOR_FROM_DATABASE=Chee Chen Hi-Technology Co., Ltd
+
+usb:v0D9D*
+ ID_VENDOR_FROM_DATABASE=Sanwa Supply, Inc.
+
+usb:v0D9E*
+ ID_VENDOR_FROM_DATABASE=Avaya
+
+usb:v0D9Ep0300*
+ ID_PRODUCT_FROM_DATABASE=Wireless Card
+
+usb:v0D9F*
+ ID_VENDOR_FROM_DATABASE=Powercom Co., Ltd
+
+usb:v0D9Fp0001*
+ ID_PRODUCT_FROM_DATABASE=Uninterruptible Power Supply
+
+usb:v0D9Fp0002*
+ ID_PRODUCT_FROM_DATABASE=Black Knight PRO / WOW Uninterruptible Power Supply (Cypress HID->COM RS232)
+
+usb:v0D9Fp00A2*
+ ID_PRODUCT_FROM_DATABASE=Imperial Uninterruptible Power Supply (HID PDC)
+
+usb:v0D9Fp00A3*
+ ID_PRODUCT_FROM_DATABASE=Smart King PRO Uninterruptible Power Supply (HID PDC)
+
+usb:v0D9Fp00A4*
+ ID_PRODUCT_FROM_DATABASE=WOW Uninterruptible Power Supply (HID PDC)
+
+usb:v0D9Fp00A5*
+ ID_PRODUCT_FROM_DATABASE=Vanguard Uninterruptible Power Supply (HID PDC)
+
+usb:v0D9Fp00A6*
+ ID_PRODUCT_FROM_DATABASE=Black Knight PRO Uninterruptible Power Supply (HID PDC)
+
+usb:v0DA0*
+ ID_VENDOR_FROM_DATABASE=Danger Research
+
+usb:v0DA1*
+ ID_VENDOR_FROM_DATABASE=Suzhou Peter's Precise Industrial Co., Ltd
+
+usb:v0DA2*
+ ID_VENDOR_FROM_DATABASE=Land Instruments International, Ltd
+
+usb:v0DA3*
+ ID_VENDOR_FROM_DATABASE=Nippon Electro-Sensory Devices Corp.
+
+usb:v0DA4*
+ ID_VENDOR_FROM_DATABASE=Polar Electro OY
+
+usb:v0DA4p0001*
+ ID_PRODUCT_FROM_DATABASE=Interface
+
+usb:v0DA7*
+ ID_VENDOR_FROM_DATABASE=IOGear, Inc.
+
+usb:v0DA8*
+ ID_VENDOR_FROM_DATABASE=softDSP Co., Ltd
+
+usb:v0DA8p0001*
+ ID_PRODUCT_FROM_DATABASE=SDS 200A Oscilloscope
+
+usb:v0DAB*
+ ID_VENDOR_FROM_DATABASE=Cubig Group
+
+usb:v0DABp0100*
+ ID_PRODUCT_FROM_DATABASE=DVR/CVR-M140 MP3 Player
+
+usb:v0DAD*
+ ID_VENDOR_FROM_DATABASE=Westover Scientific
+
+usb:v0DB0*
+ ID_VENDOR_FROM_DATABASE=Micro Star International
+
+usb:v0DB0p1020*
+ ID_PRODUCT_FROM_DATABASE=PC2PC WLAN Card
+
+usb:v0DB0p1967*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v0DB0p3801*
+ ID_PRODUCT_FROM_DATABASE=Motorola Bluetooth 2.1+EDR Device
+
+usb:v0DB0p4011*
+ ID_PRODUCT_FROM_DATABASE=Medion Flash XL V2.0 Card Reader
+
+usb:v0DB0p4023*
+ ID_PRODUCT_FROM_DATABASE=Lexar Mobile Card Reader
+
+usb:v0DB0p4600*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g Turbo Wireless Adapter
+
+usb:v0DB0p5501*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0DB0p5502*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0DB0p5513*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0DB0p5515*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0DB0p5516*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0DB0p5580*
+ ID_PRODUCT_FROM_DATABASE=Mega Sky 580 DVB-T Tuner [M902x]
+
+usb:v0DB0p5581*
+ ID_PRODUCT_FROM_DATABASE=Mega Sky 580 DVB-T Tuner [GL861]
+
+usb:v0DB0p6823*
+ ID_PRODUCT_FROM_DATABASE=UB11B/MS-6823 802.11b Wi-Fi adapter
+
+usb:v0DB0p6826*
+ ID_PRODUCT_FROM_DATABASE=IEEE 802.11g Wireless Network Adapter
+
+usb:v0DB0p6855*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0DB0p6861*
+ ID_PRODUCT_FROM_DATABASE=MSI-6861 802.11g WiFi adapter
+
+usb:v0DB0p6865*
+ ID_PRODUCT_FROM_DATABASE=RT2570
+
+usb:v0DB0p6869*
+ ID_PRODUCT_FROM_DATABASE=RT2570
+
+usb:v0DB0p6874*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v0DB0p6877*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v0DB0p6881*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Class I EDR Device
+
+usb:v0DB0p688A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Class I EDR Device
+
+usb:v0DB0p6899*
+ ID_PRODUCT_FROM_DATABASE=802.11bgn 1T1R Mini Card Wireless Adapter
+
+usb:v0DB0p6970*
+ ID_PRODUCT_FROM_DATABASE=MS-6970 BToes Bluetooth adapter
+
+usb:v0DB0p697A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v0DB0p6982*
+ ID_PRODUCT_FROM_DATABASE=Medion Flash XL Card Reader
+
+usb:v0DB0pA861*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v0DB0pA874*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v0DB0pA970*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth dongle
+
+usb:v0DB0pA97A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Device
+
+usb:v0DB0pB970*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Device
+
+usb:v0DB0pB97A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Device
+
+usb:v0DB1*
+ ID_VENDOR_FROM_DATABASE=Wen Te Electronics Co., Ltd
+
+usb:v0DB2*
+ ID_VENDOR_FROM_DATABASE=Shian Hwi Plug Parts, Plastic Factory
+
+usb:v0DB3*
+ ID_VENDOR_FROM_DATABASE=Tekram Technology Co., Ltd
+
+usb:v0DB4*
+ ID_VENDOR_FROM_DATABASE=Chung Fu Chen Yeh Enterprise Corp.
+
+usb:v0DB7*
+ ID_VENDOR_FROM_DATABASE=ELCON Systemtechnik
+
+usb:v0DB7p0002*
+ ID_PRODUCT_FROM_DATABASE=Goldpfeil P-LAN
+
+usb:v0DBC*
+ ID_VENDOR_FROM_DATABASE=A&D Medical
+
+usb:v0DBCp0003*
+ ID_PRODUCT_FROM_DATABASE=AND Serial Cable [AND Smart Cable]
+
+usb:v0DBE*
+ ID_VENDOR_FROM_DATABASE=Jiuh Shiuh Precision Industry Co., Ltd
+
+usb:v0DBF*
+ ID_VENDOR_FROM_DATABASE=Jess-Link International
+
+usb:v0DBFp0002*
+ ID_PRODUCT_FROM_DATABASE=SmartDongle Security Key
+
+usb:v0DBFp0200*
+ ID_PRODUCT_FROM_DATABASE=HDD Storage Solution
+
+usb:v0DBFp021B*
+ ID_PRODUCT_FROM_DATABASE=USB-2.0 IDE Adapter
+
+usb:v0DBFp0300*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter
+
+usb:v0DBFp0333*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter
+
+usb:v0DBFp0707*
+ ID_PRODUCT_FROM_DATABASE=ZIV Drive
+
+usb:v0DC0*
+ ID_VENDOR_FROM_DATABASE=G7 Solutions (formerly Great Notions)
+
+usb:v0DC1*
+ ID_VENDOR_FROM_DATABASE=Tamagawa Seiki Co., Ltd
+
+usb:v0DC3*
+ ID_VENDOR_FROM_DATABASE=Athena Smartcard Solutions, Inc.
+
+usb:v0DC3p0801*
+ ID_PRODUCT_FROM_DATABASE=ASEDrive III
+
+usb:v0DC3p0802*
+ ID_PRODUCT_FROM_DATABASE=ASEDrive IIIe
+
+usb:v0DC3p1104*
+ ID_PRODUCT_FROM_DATABASE=ASEDrive IIIe KB
+
+usb:v0DC3p1701*
+ ID_PRODUCT_FROM_DATABASE=ASEKey
+
+usb:v0DC3p1702*
+ ID_PRODUCT_FROM_DATABASE=ASEKey
+
+usb:v0DC4*
+ ID_VENDOR_FROM_DATABASE=Macpower Peripherals, Ltd
+
+usb:v0DC4p0040*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0DC4p0041*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0DC4p0042*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Device
+
+usb:v0DC4p0101*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device
+
+usb:v0DC4p020A*
+ ID_PRODUCT_FROM_DATABASE=Oyen Digital MiniPro 2.5" hard drive enclosure
+
+usb:v0DC5*
+ ID_VENDOR_FROM_DATABASE=SDK Co., Ltd
+
+usb:v0DC6*
+ ID_VENDOR_FROM_DATABASE=Precision Squared Technology Corp.
+
+usb:v0DC6p2301*
+ ID_PRODUCT_FROM_DATABASE=Wireless Touchpad Keyboard
+
+usb:v0DC7*
+ ID_VENDOR_FROM_DATABASE=First Cable Line, Inc.
+
+usb:v0DCD*
+ ID_VENDOR_FROM_DATABASE=NetworkFab Corp.
+
+usb:v0DCDp0001*
+ ID_PRODUCT_FROM_DATABASE=Remote Interface Adapter
+
+usb:v0DCDp0002*
+ ID_PRODUCT_FROM_DATABASE=High Bandwidth Codec
+
+usb:v0DD0*
+ ID_VENDOR_FROM_DATABASE=Access Solutions
+
+usb:v0DD0p1002*
+ ID_PRODUCT_FROM_DATABASE=Triple Talk Speech Synthesizer
+
+usb:v0DD1*
+ ID_VENDOR_FROM_DATABASE=Contek Electronics Co., Ltd
+
+usb:v0DD2*
+ ID_VENDOR_FROM_DATABASE=Power Quotient International Co., Ltd
+
+usb:v0DD2p0003*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage (P)
+
+usb:v0DD3*
+ ID_VENDOR_FROM_DATABASE=MediaQ
+
+usb:v0DD4*
+ ID_VENDOR_FROM_DATABASE=Custom Engineering SPA
+
+usb:v0DD5*
+ ID_VENDOR_FROM_DATABASE=California Micro Devices
+
+usb:v0DD7*
+ ID_VENDOR_FROM_DATABASE=Kocom Co., Ltd
+
+usb:v0DD8*
+ ID_VENDOR_FROM_DATABASE=Netac Technology Co., Ltd
+
+usb:v0DD8p1060*
+ ID_PRODUCT_FROM_DATABASE=USB-CF-Card
+
+usb:v0DD8pE007*
+ ID_PRODUCT_FROM_DATABASE=OnlyDisk U222 Pendrive
+
+usb:v0DD8pF607*
+ ID_PRODUCT_FROM_DATABASE=OnlyDisk U208 1G flash drive [U-SAFE]
+
+usb:v0DD9*
+ ID_VENDOR_FROM_DATABASE=HighSpeed Surfing
+
+usb:v0DDA*
+ ID_VENDOR_FROM_DATABASE=Integrated Circuit Solution, Inc.
+
+usb:v0DDAp0001*
+ ID_PRODUCT_FROM_DATABASE=Multi-Card Reader 6in1
+
+usb:v0DDAp0002*
+ ID_PRODUCT_FROM_DATABASE=Multi-Card Reader 7in1
+
+usb:v0DDAp0003*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk
+
+usb:v0DDAp0005*
+ ID_PRODUCT_FROM_DATABASE=Internal Multi-Card Reader 6in1
+
+usb:v0DDAp0008*
+ ID_PRODUCT_FROM_DATABASE=SD single card reader
+
+usb:v0DDAp0009*
+ ID_PRODUCT_FROM_DATABASE=MS single card reader
+
+usb:v0DDAp000A*
+ ID_PRODUCT_FROM_DATABASE=MS+SD Dual Card Reader
+
+usb:v0DDAp000B*
+ ID_PRODUCT_FROM_DATABASE=SM single card reader
+
+usb:v0DDAp0101*
+ ID_PRODUCT_FROM_DATABASE=All-In-One Card Reader
+
+usb:v0DDAp0102*
+ ID_PRODUCT_FROM_DATABASE=All-In-One Card Reader
+
+usb:v0DDAp0301*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0DDAp0302*
+ ID_PRODUCT_FROM_DATABASE=Multi-Card MP3 Player
+
+usb:v0DDAp1001*
+ ID_PRODUCT_FROM_DATABASE=Multi-Flash Disk
+
+usb:v0DDAp2001*
+ ID_PRODUCT_FROM_DATABASE=Multi-Card Reader
+
+usb:v0DDAp2002*
+ ID_PRODUCT_FROM_DATABASE=Q018 default PID
+
+usb:v0DDAp2003*
+ ID_PRODUCT_FROM_DATABASE=Multi-Card Reader
+
+usb:v0DDAp2005*
+ ID_PRODUCT_FROM_DATABASE=Datalux DLX-1611 16in1 Card Reader
+
+usb:v0DDAp2006*
+ ID_PRODUCT_FROM_DATABASE=All-In-One Card Reader
+
+usb:v0DDAp2007*
+ ID_PRODUCT_FROM_DATABASE=USB to ATAPI bridge
+
+usb:v0DDAp2008*
+ ID_PRODUCT_FROM_DATABASE=All-In-One Card Reader
+
+usb:v0DDAp2013*
+ ID_PRODUCT_FROM_DATABASE=SD/MS Combo Card Reader
+
+usb:v0DDAp2014*
+ ID_PRODUCT_FROM_DATABASE=SD/MS Single Card Reader
+
+usb:v0DDAp2023*
+ ID_PRODUCT_FROM_DATABASE=card reader SD/MS DEMO board with ICSI brand name (MaskROM version)
+
+usb:v0DDAp2024*
+ ID_PRODUCT_FROM_DATABASE=card reader SD/MS DEMO board with Generic brand name (MaskROM version)
+
+usb:v0DDAp2026*
+ ID_PRODUCT_FROM_DATABASE=USB2.0 Card Reader
+
+usb:v0DDAp2027*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader
+
+usb:v0DDAp2315*
+ ID_PRODUCT_FROM_DATABASE=UFD MP3 player (model 2)
+
+usb:v0DDAp2318*
+ ID_PRODUCT_FROM_DATABASE=UFD MP3 player (model 1)
+
+usb:v0DDAp2321*
+ ID_PRODUCT_FROM_DATABASE=UFD MP3 player
+
+usb:v0DDB*
+ ID_VENDOR_FROM_DATABASE=Tamarack, Inc.
+
+usb:v0DDD*
+ ID_VENDOR_FROM_DATABASE=Datelink Technology Co., Ltd
+
+usb:v0DDE*
+ ID_VENDOR_FROM_DATABASE=Ubicom, Inc.
+
+usb:v0DE0*
+ ID_VENDOR_FROM_DATABASE=BD Consumer Healthcare
+
+usb:v0DE7*
+ ID_VENDOR_FROM_DATABASE=USBmicro
+
+usb:v0DE7p0191*
+ ID_PRODUCT_FROM_DATABASE=U401 Interface card
+
+usb:v0DE7p01A5*
+ ID_PRODUCT_FROM_DATABASE=U421 interface card
+
+usb:v0DE7p01C3*
+ ID_PRODUCT_FROM_DATABASE=U451 relay interface card
+
+usb:v0DEA*
+ ID_VENDOR_FROM_DATABASE=UTECH Electronic (D.G.) Co., Ltd.
+
+usb:v0DED*
+ ID_VENDOR_FROM_DATABASE=Novasonics
+
+usb:v0DEE*
+ ID_VENDOR_FROM_DATABASE=Lifetime Memory Products
+
+usb:v0DEEp4010*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter
+
+usb:v0DEF*
+ ID_VENDOR_FROM_DATABASE=Full Rise Electronic Co., Ltd
+
+usb:v0DF4*
+ ID_VENDOR_FROM_DATABASE=NET&SYS
+
+usb:v0DF4p0201*
+ ID_PRODUCT_FROM_DATABASE=MNG-2005
+
+usb:v0DF6*
+ ID_VENDOR_FROM_DATABASE=Sitecom Europe B.V.
+
+usb:v0DF6p0001*
+ ID_PRODUCT_FROM_DATABASE=C-Media VOIP Device
+
+usb:v0DF6p0004*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Adapter 100m
+
+usb:v0DF6p0007*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Adapter 10m
+
+usb:v0DF6p000B*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Adapter DFU
+
+usb:v0DF6p000D*
+ ID_PRODUCT_FROM_DATABASE=WL-168 Wireless Network Adapter 54g
+
+usb:v0DF6p0017*
+ ID_PRODUCT_FROM_DATABASE=WL-182 Wireless-N Network USB Card
+
+usb:v0DF6p0019*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 adapter 10m CN-512v2 001
+
+usb:v0DF6p001A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 adapter 100m CN-521v2 001
+
+usb:v0DF6p002B*
+ ID_PRODUCT_FROM_DATABASE=WL-188 Wireless Network 300N USB Adapter
+
+usb:v0DF6p002C*
+ ID_PRODUCT_FROM_DATABASE=WL-301 Wireless Network 300N USB Adapter
+
+usb:v0DF6p002D*
+ ID_PRODUCT_FROM_DATABASE=WL-302 Wireless Network 300N USB dongle
+
+usb:v0DF6p0036*
+ ID_PRODUCT_FROM_DATABASE=WL-603 Wireless Adapter
+
+usb:v0DF6p0039*
+ ID_PRODUCT_FROM_DATABASE=WL-315 Wireless-N USB Adapter
+
+usb:v0DF6p003B*
+ ID_PRODUCT_FROM_DATABASE=WL-321 Wireless USB Gaming Adapter 300N
+
+usb:v0DF6p003C*
+ ID_PRODUCT_FROM_DATABASE=WL-323 Wireless-N USB Adapter
+
+usb:v0DF6p003D*
+ ID_PRODUCT_FROM_DATABASE=WL-324 Wireless USB Adapter 300N
+
+usb:v0DF6p003E*
+ ID_PRODUCT_FROM_DATABASE=WL-343 Wireless USB Adapter 150N X1
+
+usb:v0DF6p003F*
+ ID_PRODUCT_FROM_DATABASE=WL-608 Wireless USB Adapter 54g
+
+usb:v0DF6p0040*
+ ID_PRODUCT_FROM_DATABASE=WL-344 Wireless Adapter 300N X2 [Ralink RT3071]
+
+usb:v0DF6p0041*
+ ID_PRODUCT_FROM_DATABASE=WL-329 Wireless Dualband USB adapter 300N
+
+usb:v0DF6p0042*
+ ID_PRODUCT_FROM_DATABASE=WL-345 Wireless USB adapter 300N X3
+
+usb:v0DF6p0045*
+ ID_PRODUCT_FROM_DATABASE=WL-353 Wireless USB Adapter 150N Nano
+
+usb:v0DF6p0047*
+ ID_PRODUCT_FROM_DATABASE=WL-352v1 Wireless USB Adapter 300N 002
+
+usb:v0DF6p0048*
+ ID_PRODUCT_FROM_DATABASE=WL-349v1 Wireless Adapter 150N 002 [Ralink RT3070]
+
+usb:v0DF6p0049*
+ ID_PRODUCT_FROM_DATABASE=WL-356 Wireless Adapter 300N
+
+usb:v0DF6p004A*
+ ID_PRODUCT_FROM_DATABASE=WL-358v1 Wireless Micro USB Adapter 300N X3 002
+
+usb:v0DF6p004B*
+ ID_PRODUCT_FROM_DATABASE=WL-349v3 Wireless Micro Adapter 150N X1 [Realtek RTL8192SU]
+
+usb:v0DF6p004C*
+ ID_PRODUCT_FROM_DATABASE=WL-352 802.11n Adapter [Realtek RTL8191SU]
+
+usb:v0DF6p0050*
+ ID_PRODUCT_FROM_DATABASE=WL-349v4 Wireless Micro Adapter 150N X1 [Ralink RT3370]
+
+usb:v0DF6p0056*
+ ID_PRODUCT_FROM_DATABASE=LN-031 10/100/1000 Ethernet Adapter
+
+usb:v0DF6p005D*
+ ID_PRODUCT_FROM_DATABASE=WLA-2000 v1.001 WLAN [RTL8191SU]
+
+usb:v0DF6p0060*
+ ID_PRODUCT_FROM_DATABASE=WLA-4000 802.11bgn [Ralink RT3072]
+
+usb:v0DF6p0062*
+ ID_PRODUCT_FROM_DATABASE=WLA-5000 802.11abgn [Ralink RT3572]
+
+usb:v0DF6p061C*
+ ID_PRODUCT_FROM_DATABASE=LN-028 Network USB 2.0 Adapter
+
+usb:v0DF6p21F4*
+ ID_PRODUCT_FROM_DATABASE=44 St Bluetooth Device
+
+usb:v0DF6p2200*
+ ID_PRODUCT_FROM_DATABASE=Sitecom bluetooth2.0 class 2 dongle CN-512
+
+usb:v0DF6p2208*
+ ID_PRODUCT_FROM_DATABASE=Sitecom bluetooth2.0 class 2 dongle CN-520
+
+usb:v0DF6p2209*
+ ID_PRODUCT_FROM_DATABASE=Sitecom bluetooth2.0 class 1 dongle CN-521
+
+usb:v0DF6p9071*
+ ID_PRODUCT_FROM_DATABASE=WL-113 rev 1 Wireless Network USB Adapter
+
+usb:v0DF6p9075*
+ ID_PRODUCT_FROM_DATABASE=WL-117 Hi-Speed USB Adapter
+
+usb:v0DF6p90AC*
+ ID_PRODUCT_FROM_DATABASE=WL-172 Wireless Network USB Adapter 54g Turbo
+
+usb:v0DF6p9712*
+ ID_PRODUCT_FROM_DATABASE=WL-113 rev 2 Wireless Network USB Adapter
+
+usb:v0DF7*
+ ID_VENDOR_FROM_DATABASE=Mobile Action Technology, Inc.
+
+usb:v0DF7p0620*
+ ID_PRODUCT_FROM_DATABASE=MA-620 Infrared Adapter
+
+usb:v0DF7p0700*
+ ID_PRODUCT_FROM_DATABASE=MA-700 Bluetooth Adapter
+
+usb:v0DF7p0720*
+ ID_PRODUCT_FROM_DATABASE=MA-720 Bluetooth Adapter
+
+usb:v0DF7p0722*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v0DF7p0730*
+ ID_PRODUCT_FROM_DATABASE=MA-730/MA-730G Bluetooth Adapter
+
+usb:v0DF7p0800*
+ ID_PRODUCT_FROM_DATABASE=Data Cable
+
+usb:v0DF7p0820*
+ ID_PRODUCT_FROM_DATABASE=Data Cable
+
+usb:v0DF7p0900*
+ ID_PRODUCT_FROM_DATABASE=MA i-gotU Travel Logger GPS
+
+usb:v0DF7p1800*
+ ID_PRODUCT_FROM_DATABASE=Generic Card Reader
+
+usb:v0DF7p1802*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v0DFA*
+ ID_VENDOR_FROM_DATABASE=Toyo Communication Equipment Co., Ltd
+
+usb:v0DFC*
+ ID_VENDOR_FROM_DATABASE=GeneralTouch Technology Co., Ltd
+
+usb:v0DFCp0001*
+ ID_PRODUCT_FROM_DATABASE=Touchscreen
+
+usb:v0E03*
+ ID_VENDOR_FROM_DATABASE=Nippon Systemware Co., Ltd
+
+usb:v0E08*
+ ID_VENDOR_FROM_DATABASE=Winbest Technology Co., Ltd
+
+usb:v0E0B*
+ ID_VENDOR_FROM_DATABASE=Amigo Technology Inc.
+
+usb:v0E0Bp9031*
+ ID_PRODUCT_FROM_DATABASE=802.11n Wireless USB Card
+
+usb:v0E0Bp9041*
+ ID_PRODUCT_FROM_DATABASE=802.11n Wireless USB Card
+
+usb:v0E0C*
+ ID_VENDOR_FROM_DATABASE=Gesytec
+
+usb:v0E0Cp0101*
+ ID_PRODUCT_FROM_DATABASE=LonUSB LonTalk Network Adapter
+
+usb:v0E0F*
+ ID_VENDOR_FROM_DATABASE=VMware, Inc.
+
+usb:v0E0Fp0001*
+ ID_PRODUCT_FROM_DATABASE=Device
+
+usb:v0E0Fp0002*
+ ID_PRODUCT_FROM_DATABASE=Virtual USB Hub
+
+usb:v0E0Fp0003*
+ ID_PRODUCT_FROM_DATABASE=Virtual Mouse
+
+usb:v0E0Fp0004*
+ ID_PRODUCT_FROM_DATABASE=Virtual CCID
+
+usb:v0E0Fp0005*
+ ID_PRODUCT_FROM_DATABASE=Virtual Mass Storage
+
+usb:v0E0Fp0006*
+ ID_PRODUCT_FROM_DATABASE=Virtual Keyboard
+
+usb:v0E0FpF80A*
+ ID_PRODUCT_FROM_DATABASE=Smoker FX2
+
+usb:v0E16*
+ ID_VENDOR_FROM_DATABASE=JMTek, LLC
+
+usb:v0E17*
+ ID_VENDOR_FROM_DATABASE=Walex Electronic, Ltd
+
+usb:v0E1A*
+ ID_VENDOR_FROM_DATABASE=Unisys
+
+usb:v0E1B*
+ ID_VENDOR_FROM_DATABASE=Crewave
+
+usb:v0E20*
+ ID_VENDOR_FROM_DATABASE=Pegasus Technologies Ltd.
+
+usb:v0E20p0101*
+ ID_PRODUCT_FROM_DATABASE=NoteTaker
+
+usb:v0E21*
+ ID_VENDOR_FROM_DATABASE=Cowon Systems, Inc.
+
+usb:v0E21p0300*
+ ID_PRODUCT_FROM_DATABASE=iAudio CW200
+
+usb:v0E21p0400*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0E21p0500*
+ ID_PRODUCT_FROM_DATABASE=iAudio M3
+
+usb:v0E21p0510*
+ ID_PRODUCT_FROM_DATABASE=iAudio X5, subpack USB port
+
+usb:v0E21p0513*
+ ID_PRODUCT_FROM_DATABASE=iAudio X5, side USB port
+
+usb:v0E21p0520*
+ ID_PRODUCT_FROM_DATABASE=iAudio M5, side USB port
+
+usb:v0E21p0601*
+ ID_PRODUCT_FROM_DATABASE=iAudio G3
+
+usb:v0E21p0681*
+ ID_PRODUCT_FROM_DATABASE=iAUDIO E2
+
+usb:v0E21p0700*
+ ID_PRODUCT_FROM_DATABASE=iAudio U3
+
+usb:v0E21p0751*
+ ID_PRODUCT_FROM_DATABASE=iAudio 7
+
+usb:v0E21p0760*
+ ID_PRODUCT_FROM_DATABASE=iAUDIO U5 / iAUDIO G2
+
+usb:v0E21p0800*
+ ID_PRODUCT_FROM_DATABASE=Cowon D2 (UMS mode)
+
+usb:v0E21p0801*
+ ID_PRODUCT_FROM_DATABASE=Cowon D2 (MTP mode)
+
+usb:v0E21p0910*
+ ID_PRODUCT_FROM_DATABASE=iAUDIO 9
+
+usb:v0E21p0920*
+ ID_PRODUCT_FROM_DATABASE=J3
+
+usb:v0E22*
+ ID_VENDOR_FROM_DATABASE=Symbian Ltd.
+
+usb:v0E23*
+ ID_VENDOR_FROM_DATABASE=Liou Yuane Enterprise Co., Ltd
+
+usb:v0E25*
+ ID_VENDOR_FROM_DATABASE=VinChip Systems, Inc.
+
+usb:v0E26*
+ ID_VENDOR_FROM_DATABASE=J-Phone East Co., Ltd
+
+usb:v0E30*
+ ID_VENDOR_FROM_DATABASE=HeartMath LLC
+
+usb:v0E34*
+ ID_VENDOR_FROM_DATABASE=Micro Computer Control Corp.
+
+usb:v0E35*
+ ID_VENDOR_FROM_DATABASE=3Pea Technologies, Inc.
+
+usb:v0E36*
+ ID_VENDOR_FROM_DATABASE=TiePie engineering
+
+usb:v0E36p0008*
+ ID_PRODUCT_FROM_DATABASE=Handyscope HS3
+
+usb:v0E36p0009*
+ ID_PRODUCT_FROM_DATABASE=Handyscope HS3 (br)
+
+usb:v0E36p000A*
+ ID_PRODUCT_FROM_DATABASE=Handyscope HS4
+
+usb:v0E36p000B*
+ ID_PRODUCT_FROM_DATABASE=Handyscope HS4 (br)
+
+usb:v0E36p000E*
+ ID_PRODUCT_FROM_DATABASE=Handyscope HS4-DIFF
+
+usb:v0E36p000F*
+ ID_PRODUCT_FROM_DATABASE=Handyscope HS4-DIFF (br)
+
+usb:v0E36p0010*
+ ID_PRODUCT_FROM_DATABASE=Handyscope HS2
+
+usb:v0E36p0011*
+ ID_PRODUCT_FROM_DATABASE=TiePieSCOPE HS805 (br)
+
+usb:v0E36p0012*
+ ID_PRODUCT_FROM_DATABASE=TiePieSCOPE HS805
+
+usb:v0E36p0013*
+ ID_PRODUCT_FROM_DATABASE=Handyprobe HP3
+
+usb:v0E36p0014*
+ ID_PRODUCT_FROM_DATABASE=Handyprobe HP3
+
+usb:v0E36p0018*
+ ID_PRODUCT_FROM_DATABASE=Handyprobe HP2
+
+usb:v0E36p001B*
+ ID_PRODUCT_FROM_DATABASE=Handyscope HS5
+
+usb:v0E36p0042*
+ ID_PRODUCT_FROM_DATABASE=TiePieSCOPE HS801
+
+usb:v0E36p00FD*
+ ID_PRODUCT_FROM_DATABASE=USB To Parallel adapter
+
+usb:v0E36p00FE*
+ ID_PRODUCT_FROM_DATABASE=USB To Parallel adapter
+
+usb:v0E38*
+ ID_VENDOR_FROM_DATABASE=Stratitec, Inc.
+
+usb:v0E39*
+ ID_VENDOR_FROM_DATABASE=Smart Modular Technologies, Inc.
+
+usb:v0E39p0137*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v0E3A*
+ ID_VENDOR_FROM_DATABASE=Neostar Technology Co., Ltd
+
+usb:v0E3Ap1100*
+ ID_PRODUCT_FROM_DATABASE=CW-1100 Wireless Network Adapter
+
+usb:v0E3B*
+ ID_VENDOR_FROM_DATABASE=Mansella, Ltd
+
+usb:v0E41*
+ ID_VENDOR_FROM_DATABASE=Line6, Inc.
+
+usb:v0E41p4147*
+ ID_PRODUCT_FROM_DATABASE=TonePort GX
+
+usb:v0E41p4156*
+ ID_PRODUCT_FROM_DATABASE=POD HD Desktop
+
+usb:v0E41p4250*
+ ID_PRODUCT_FROM_DATABASE=BassPODxt
+
+usb:v0E41p4252*
+ ID_PRODUCT_FROM_DATABASE=BassPODxt Pro
+
+usb:v0E41p4642*
+ ID_PRODUCT_FROM_DATABASE=BassPODxt Live
+
+usb:v0E41p4650*
+ ID_PRODUCT_FROM_DATABASE=PODxt Live
+
+usb:v0E41p4750*
+ ID_PRODUCT_FROM_DATABASE=GuitarPort
+
+usb:v0E41p5044*
+ ID_PRODUCT_FROM_DATABASE=PODxt
+
+usb:v0E41p5050*
+ ID_PRODUCT_FROM_DATABASE=PODxt Pro
+
+usb:v0E41p534D*
+ ID_PRODUCT_FROM_DATABASE=SeaMonkey
+
+usb:v0E44*
+ ID_VENDOR_FROM_DATABASE=Sun-Riseful Technology Co., Ltd.
+
+usb:v0E48*
+ ID_VENDOR_FROM_DATABASE=Julia Corp., Ltd
+
+usb:v0E48p0100*
+ ID_PRODUCT_FROM_DATABASE=CardPro SmartCard Reader
+
+usb:v0E4A*
+ ID_VENDOR_FROM_DATABASE=Shenzhen Bao Hing Electric Wire & Cable Mfr. Co.
+
+usb:v0E4C*
+ ID_VENDOR_FROM_DATABASE=Radica Games, Ltd
+
+usb:v0E4Cp1097*
+ ID_PRODUCT_FROM_DATABASE=Gamester Controller
+
+usb:v0E4Cp2390*
+ ID_PRODUCT_FROM_DATABASE=Games Jtech Controller
+
+usb:v0E4Cp7288*
+ ID_PRODUCT_FROM_DATABASE=funkey reader
+
+usb:v0E50*
+ ID_VENDOR_FROM_DATABASE=TechnoData Interware
+
+usb:v0E50p0002*
+ ID_PRODUCT_FROM_DATABASE=Matrixlock Dongle (HID)
+
+usb:v0E55*
+ ID_VENDOR_FROM_DATABASE=Speed Dragon Multimedia, Ltd
+
+usb:v0E55p110A*
+ ID_PRODUCT_FROM_DATABASE=Tanic S110-SG1 + ISSC IS1002N [Slow Infra-Red (SIR) & Bluetooth 1.2 (Class 2) Adapter]
+
+usb:v0E55p110B*
+ ID_PRODUCT_FROM_DATABASE=MS3303H USB-to-Serial Bridge
+
+usb:v0E56*
+ ID_VENDOR_FROM_DATABASE=Kingston Technology Company, Inc.
+
+usb:v0E56p6021*
+ ID_PRODUCT_FROM_DATABASE=K-PEX 100
+
+usb:v0E5A*
+ ID_VENDOR_FROM_DATABASE=Active Co., Ltd
+
+usb:v0E5B*
+ ID_VENDOR_FROM_DATABASE=Union Power Information Industrial Co., Ltd
+
+usb:v0E5C*
+ ID_VENDOR_FROM_DATABASE=Bitland Information Technology Co., Ltd
+
+usb:v0E5Cp6118*
+ ID_PRODUCT_FROM_DATABASE=LCD Device
+
+usb:v0E5Cp6119*
+ ID_PRODUCT_FROM_DATABASE=remote receive and control device
+
+usb:v0E5Cp6441*
+ ID_PRODUCT_FROM_DATABASE=C-Media Sound Device
+
+usb:v0E5D*
+ ID_VENDOR_FROM_DATABASE=Neltron Industrial Co., Ltd
+
+usb:v0E5E*
+ ID_VENDOR_FROM_DATABASE=Conwise Technology Co., Ltd.
+
+usb:v0E5Ep6622*
+ ID_PRODUCT_FROM_DATABASE=CW6622
+
+usb:v0E66*
+ ID_VENDOR_FROM_DATABASE=Hawking Technologies
+
+usb:v0E66p0001*
+ ID_PRODUCT_FROM_DATABASE=HWUN1 Hi-Gain Wireless-300N Adapter w/ Upgradable Antenna [Ralink RT2870]
+
+usb:v0E66p0003*
+ ID_PRODUCT_FROM_DATABASE=HWDN1 Hi-Gain Wireless-300N Dish Adapter [Ralink RT2870]
+
+usb:v0E66p0009*
+ ID_PRODUCT_FROM_DATABASE=HWUN2 Hi-Gain Wireless-150N Adapter w/ Upgradable Antenna [Ralink RT2770]
+
+usb:v0E66p000B*
+ ID_PRODUCT_FROM_DATABASE=HWDN2 Hi-Gain Wireless-150N Dish Adapter [Ralink RT2770]
+
+usb:v0E66p0013*
+ ID_PRODUCT_FROM_DATABASE=HWUN3 Hi-Gain Wireless-N Adapter [Ralink RT3070]
+
+usb:v0E66p0015*
+ ID_PRODUCT_FROM_DATABASE=HWDN2 Rev. E Hi-Gain Wireless-150N Dish Adapter [Realtek RTL8191SU]
+
+usb:v0E66p0017*
+ ID_PRODUCT_FROM_DATABASE=HAWNU1 Hi-Gain Wireless-150N Network Adapter with Range Amplifier [Ralink RT3070]
+
+usb:v0E66p0018*
+ ID_PRODUCT_FROM_DATABASE=Wireless-N Network Adapter [Ralink RT2870]
+
+usb:v0E66p400B*
+ ID_PRODUCT_FROM_DATABASE=UF100 10/100 Network Adapter
+
+usb:v0E66p400C*
+ ID_PRODUCT_FROM_DATABASE=UF100 Ethernet [pegasus2]
+
+usb:v0E67*
+ ID_VENDOR_FROM_DATABASE=Fossil, Inc.
+
+usb:v0E67p0002*
+ ID_PRODUCT_FROM_DATABASE=Wrist PDA
+
+usb:v0E6A*
+ ID_VENDOR_FROM_DATABASE=Megawin Technology Co., Ltd
+
+usb:v0E6Ap0101*
+ ID_PRODUCT_FROM_DATABASE=MA100 [USB-UART Bridge IC]
+
+usb:v0E6Ap6001*
+ ID_PRODUCT_FROM_DATABASE=GEMBIRD Flexible keyboard KB-109F-B-DE
+
+usb:v0E6F*
+ ID_VENDOR_FROM_DATABASE=Logic3
+
+usb:v0E6Fp0003*
+ ID_PRODUCT_FROM_DATABASE=Freebird wireless Controller
+
+usb:v0E6Fp0005*
+ ID_PRODUCT_FROM_DATABASE=Eclipse wireless Controller
+
+usb:v0E6Fp0006*
+ ID_PRODUCT_FROM_DATABASE=Edge wireless Controller
+
+usb:v0E70*
+ ID_VENDOR_FROM_DATABASE=Tokyo Electronic Industry Co., Ltd
+
+usb:v0E72*
+ ID_VENDOR_FROM_DATABASE=Hsi-Chin Electronics Co., Ltd
+
+usb:v0E75*
+ ID_VENDOR_FROM_DATABASE=TVS Electronics, Ltd
+
+usb:v0E79*
+ ID_VENDOR_FROM_DATABASE=Archos, Inc.
+
+usb:v0E79p1106*
+ ID_PRODUCT_FROM_DATABASE=Pocket Media Assistant - PMA400
+
+usb:v0E79p1204*
+ ID_PRODUCT_FROM_DATABASE=Gmini XS 200
+
+usb:v0E79p1306*
+ ID_PRODUCT_FROM_DATABASE=504 Portable Multimedia Player
+
+usb:v0E79p1330*
+ ID_PRODUCT_FROM_DATABASE=5 Tablet
+
+usb:v0E79p1332*
+ ID_PRODUCT_FROM_DATABASE=5 IMT
+
+usb:v0E79p1416*
+ ID_PRODUCT_FROM_DATABASE=32 IT
+
+usb:v0E79p1417*
+ ID_PRODUCT_FROM_DATABASE=A43 IT
+
+usb:v0E7B*
+ ID_VENDOR_FROM_DATABASE=On-Tech Industry Co., Ltd
+
+usb:v0E7E*
+ ID_VENDOR_FROM_DATABASE=Gmate, Inc.
+
+usb:v0E7Ep0001*
+ ID_PRODUCT_FROM_DATABASE=Yopy 3000 PDA
+
+usb:v0E7Ep1001*
+ ID_PRODUCT_FROM_DATABASE=YP3X00 PDA
+
+usb:v0E82*
+ ID_VENDOR_FROM_DATABASE=Ching Tai Electric Wire & Cable Co., Ltd
+
+usb:v0E83*
+ ID_VENDOR_FROM_DATABASE=Shin An Wire & Cable Co.
+
+usb:v0E8C*
+ ID_VENDOR_FROM_DATABASE=Well Force Electronic Co., Ltd
+
+usb:v0E8D*
+ ID_VENDOR_FROM_DATABASE=MediaTek Inc.
+
+usb:v0E8Dp0003*
+ ID_PRODUCT_FROM_DATABASE=MT6227 phone
+
+usb:v0E8Dp0004*
+ ID_PRODUCT_FROM_DATABASE=MT6227 phone
+
+usb:v0E8Dp1806*
+ ID_PRODUCT_FROM_DATABASE=Samsung SE-208AB Slim Portable DVD Writer
+
+usb:v0E8Dp1836*
+ ID_PRODUCT_FROM_DATABASE=Samsung SE-S084 Super WriteMaster Slim External DVD writer
+
+usb:v0E8F*
+ ID_VENDOR_FROM_DATABASE=GreenAsia Inc.
+
+usb:v0E8Fp0003*
+ ID_PRODUCT_FROM_DATABASE=MaxFire Blaze2
+
+usb:v0E8Fp0012*
+ ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Gamepad
+
+usb:v0E8Fp0016*
+ ID_PRODUCT_FROM_DATABASE=4 port USB 1.1 hub UH-174
+
+usb:v0E8Fp0020*
+ ID_PRODUCT_FROM_DATABASE=USB to PS/2 Adapter
+
+usb:v0E8Fp0021*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard Controller
+
+usb:v0E8Fp0201*
+ ID_PRODUCT_FROM_DATABASE=SmartJoy Frag Xpad/PS2 adaptor
+
+usb:v0E90*
+ ID_VENDOR_FROM_DATABASE=WiebeTech, LLC
+
+usb:v0E90p0100*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V1
+
+usb:v0E91*
+ ID_VENDOR_FROM_DATABASE=VTech Engineering Canada, Ltd
+
+usb:v0E92*
+ ID_VENDOR_FROM_DATABASE=C's Glory Enterprise Co., Ltd
+
+usb:v0E93*
+ ID_VENDOR_FROM_DATABASE=eM Technics Co., Ltd
+
+usb:v0E95*
+ ID_VENDOR_FROM_DATABASE=Future Technology Co., Ltd
+
+usb:v0E96*
+ ID_VENDOR_FROM_DATABASE=Aplux Communications, Ltd
+
+usb:v0E96pC001*
+ ID_PRODUCT_FROM_DATABASE=TRUST 380 USB2 SPACEC@M
+
+usb:v0E97*
+ ID_VENDOR_FROM_DATABASE=Fingerworks, Inc.
+
+usb:v0E97p0908*
+ ID_PRODUCT_FROM_DATABASE=Composite HID (Keyboard and Mouse)
+
+usb:v0E98*
+ ID_VENDOR_FROM_DATABASE=Advanced Analogic Technologies, Inc.
+
+usb:v0E99*
+ ID_VENDOR_FROM_DATABASE=Parallel Dice Co., Ltd
+
+usb:v0E9A*
+ ID_VENDOR_FROM_DATABASE=TA HSING Industries, Ltd
+
+usb:v0E9B*
+ ID_VENDOR_FROM_DATABASE=ADTEC Corp.
+
+usb:v0E9C*
+ ID_VENDOR_FROM_DATABASE=Streamzap, Inc.
+
+usb:v0E9Cp0000*
+ ID_PRODUCT_FROM_DATABASE=Streamzap Remote Control
+
+usb:v0E9F*
+ ID_VENDOR_FROM_DATABASE=Tamura Corp.
+
+usb:v0EA0*
+ ID_VENDOR_FROM_DATABASE=Ours Technology, Inc.
+
+usb:v0EA0p2126*
+ ID_PRODUCT_FROM_DATABASE=7-in-1 Card Reader
+
+usb:v0EA0p2153*
+ ID_PRODUCT_FROM_DATABASE=SD Card Reader Key
+
+usb:v0EA0p2168*
+ ID_PRODUCT_FROM_DATABASE=Transcend JetFlash 2.0 / Astone USB Drive
+
+usb:v0EA0p6803*
+ ID_PRODUCT_FROM_DATABASE=OTI-6803 Flash Disk
+
+usb:v0EA0p6808*
+ ID_PRODUCT_FROM_DATABASE=OTI-6808 Flash Disk
+
+usb:v0EA0p6828*
+ ID_PRODUCT_FROM_DATABASE=OTI-6828 Flash Disk
+
+usb:v0EA0p6858*
+ ID_PRODUCT_FROM_DATABASE=OTi-6858 serial adapter
+
+usb:v0EA6*
+ ID_VENDOR_FROM_DATABASE=Nihon Computer Co., Ltd
+
+usb:v0EA7*
+ ID_VENDOR_FROM_DATABASE=MSL Enterprises Corp.
+
+usb:v0EA8*
+ ID_VENDOR_FROM_DATABASE=CenDyne, Inc.
+
+usb:v0EAD*
+ ID_VENDOR_FROM_DATABASE=Humax Co., Ltd
+
+usb:v0EB0*
+ ID_VENDOR_FROM_DATABASE=NovaTech
+
+usb:v0EB0p9020*
+ ID_PRODUCT_FROM_DATABASE=NovaTech NV-902W
+
+usb:v0EB0p9021*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v0EB1*
+ ID_VENDOR_FROM_DATABASE=WIS Technologies, Inc.
+
+usb:v0EB1p6666*
+ ID_PRODUCT_FROM_DATABASE=WinFast WalkieTV TV Loader
+
+usb:v0EB1p6668*
+ ID_PRODUCT_FROM_DATABASE=WinFast WalkieTV TV Loader
+
+usb:v0EB1p7007*
+ ID_PRODUCT_FROM_DATABASE=WinFast WalkieTV WDM Capture
+
+usb:v0EB2*
+ ID_VENDOR_FROM_DATABASE=Y-S Electronic Co., Ltd
+
+usb:v0EB3*
+ ID_VENDOR_FROM_DATABASE=Saint Technology Corp.
+
+usb:v0EB7*
+ ID_VENDOR_FROM_DATABASE=Endor AG
+
+usb:v0EBE*
+ ID_VENDOR_FROM_DATABASE=VWeb Corp.
+
+usb:v0EBF*
+ ID_VENDOR_FROM_DATABASE=Omega Technology of Taiwan, Inc.
+
+usb:v0EC0*
+ ID_VENDOR_FROM_DATABASE=LHI Technology (China) Co., Ltd
+
+usb:v0EC1*
+ ID_VENDOR_FROM_DATABASE=Abit Computer Corp.
+
+usb:v0EC2*
+ ID_VENDOR_FROM_DATABASE=Sweetray Industrial, Ltd
+
+usb:v0EC3*
+ ID_VENDOR_FROM_DATABASE=Axell Co., Ltd
+
+usb:v0EC4*
+ ID_VENDOR_FROM_DATABASE=Ballracing Developments, Ltd
+
+usb:v0EC5*
+ ID_VENDOR_FROM_DATABASE=GT Information System Co., Ltd
+
+usb:v0EC6*
+ ID_VENDOR_FROM_DATABASE=InnoVISION Multimedia, Ltd
+
+usb:v0EC7*
+ ID_VENDOR_FROM_DATABASE=Theta Link Corp.
+
+usb:v0EC7p1008*
+ ID_PRODUCT_FROM_DATABASE=So., Show 301 Digital Camera
+
+usb:v0ECD*
+ ID_VENDOR_FROM_DATABASE=Lite-On IT Corp.
+
+usb:v0ECDp1400*
+ ID_PRODUCT_FROM_DATABASE=CD\RW 40X
+
+usb:v0ECDpA100*
+ ID_PRODUCT_FROM_DATABASE=LDW-411SX DVD/CD Rewritable Drive
+
+usb:v0ECE*
+ ID_VENDOR_FROM_DATABASE=TaiSol Electronics Co., Ltd
+
+usb:v0ECF*
+ ID_VENDOR_FROM_DATABASE=Phogenix Imaging, LLC
+
+usb:v0ED1*
+ ID_VENDOR_FROM_DATABASE=WinMaxGroup
+
+usb:v0ED1p6660*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk 64M-C
+
+usb:v0ED1p6680*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk 64M-B
+
+usb:v0ED1p7634*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v0ED2*
+ ID_VENDOR_FROM_DATABASE=Kyoto Micro Computer Co., Ltd
+
+usb:v0ED3*
+ ID_VENDOR_FROM_DATABASE=Wing-Tech Enterprise Co., Ltd
+
+usb:v0ED5*
+ ID_VENDOR_FROM_DATABASE=Fiberbyte
+
+usb:v0ED5pE000*
+ ID_PRODUCT_FROM_DATABASE=USB-inSync Device
+
+usb:v0ED5pF000*
+ ID_PRODUCT_FROM_DATABASE=Fiberbyte USB-inSync Device
+
+usb:v0ED5pF201*
+ ID_PRODUCT_FROM_DATABASE=Fiberbyte USB-inSync DAQ-2500X
+
+usb:v0EDA*
+ ID_VENDOR_FROM_DATABASE=Noriake Itron Corp.
+
+usb:v0EDF*
+ ID_VENDOR_FROM_DATABASE=e-MDT Co., Ltd
+
+usb:v0EDFp2060*
+ ID_PRODUCT_FROM_DATABASE=FID irock! 100 Series
+
+usb:v0EE0*
+ ID_VENDOR_FROM_DATABASE=Shima Seiki Mfg., Ltd
+
+usb:v0EE1*
+ ID_VENDOR_FROM_DATABASE=Sarotech Co., Ltd
+
+usb:v0EE2*
+ ID_VENDOR_FROM_DATABASE=AMI Semiconductor, Inc.
+
+usb:v0EE3*
+ ID_VENDOR_FROM_DATABASE=ComTrue Technology Corp.
+
+usb:v0EE3p1000*
+ ID_PRODUCT_FROM_DATABASE=Image Tank 1.5
+
+usb:v0EE4*
+ ID_VENDOR_FROM_DATABASE=Sunrich Technology, Ltd
+
+usb:v0EEE*
+ ID_VENDOR_FROM_DATABASE=Digital Stream Technology, Inc.
+
+usb:v0EEEp8810*
+ ID_PRODUCT_FROM_DATABASE=Mass Storage Drive
+
+usb:v0EEF*
+ ID_VENDOR_FROM_DATABASE=D-WAV Scientific Co., Ltd
+
+usb:v0EEFp0001*
+ ID_PRODUCT_FROM_DATABASE=eGalax TouchScreen
+
+usb:v0EEFp0002*
+ ID_PRODUCT_FROM_DATABASE=Touchscreen Controller(Professional)
+
+usb:v0EF0*
+ ID_VENDOR_FROM_DATABASE=Hitachi Cable, Ltd
+
+usb:v0EF1*
+ ID_VENDOR_FROM_DATABASE=Aichi Micro Intelligent Corp.
+
+usb:v0EF2*
+ ID_VENDOR_FROM_DATABASE=I/O Magic Corp.
+
+usb:v0EF3*
+ ID_VENDOR_FROM_DATABASE=Lynn Products, Inc.
+
+usb:v0EF4*
+ ID_VENDOR_FROM_DATABASE=DSI Datotech
+
+usb:v0EF5*
+ ID_VENDOR_FROM_DATABASE=PointChips
+
+usb:v0EF5p2202*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk
+
+usb:v0EF5p2366*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk
+
+usb:v0EF6*
+ ID_VENDOR_FROM_DATABASE=Yield Microelectronics Corp.
+
+usb:v0EF7*
+ ID_VENDOR_FROM_DATABASE=SM Tech Co., Ltd (Tulip)
+
+usb:v0EFD*
+ ID_VENDOR_FROM_DATABASE=Oasis Semiconductor
+
+usb:v0EFE*
+ ID_VENDOR_FROM_DATABASE=Wem Technology, Inc.
+
+usb:v0F03*
+ ID_VENDOR_FROM_DATABASE=Unitek UPS Systems
+
+usb:v0F03p0001*
+ ID_PRODUCT_FROM_DATABASE=Alpha 1200Sx
+
+usb:v0F06*
+ ID_VENDOR_FROM_DATABASE=Visual Frontier Enterprise Co., Ltd
+
+usb:v0F08*
+ ID_VENDOR_FROM_DATABASE=CSL Wire & Plug (Shen Zhen) Co.
+
+usb:v0F0C*
+ ID_VENDOR_FROM_DATABASE=CAS Corp.
+
+usb:v0F0D*
+ ID_VENDOR_FROM_DATABASE=Hori Co., Ltd
+
+usb:v0F0Dp0011*
+ ID_PRODUCT_FROM_DATABASE=Real Arcade Pro 3
+
+usb:v0F0E*
+ ID_VENDOR_FROM_DATABASE=Energy Full Corp.
+
+usb:v0F11*
+ ID_VENDOR_FROM_DATABASE=LD Didactic GmbH
+
+usb:v0F11p1000*
+ ID_PRODUCT_FROM_DATABASE=CASSY-S
+
+usb:v0F11p1010*
+ ID_PRODUCT_FROM_DATABASE=Pocket-CASSY
+
+usb:v0F11p1020*
+ ID_PRODUCT_FROM_DATABASE=Mobile-CASSY
+
+usb:v0F11p1080*
+ ID_PRODUCT_FROM_DATABASE=Joule and Wattmeter
+
+usb:v0F11p1081*
+ ID_PRODUCT_FROM_DATABASE=Digital Multimeter P
+
+usb:v0F11p1090*
+ ID_PRODUCT_FROM_DATABASE=UMI P
+
+usb:v0F11p1100*
+ ID_PRODUCT_FROM_DATABASE=X-Ray Apparatus
+
+usb:v0F11p1101*
+ ID_PRODUCT_FROM_DATABASE=X-Ray Apparatus
+
+usb:v0F11p1200*
+ ID_PRODUCT_FROM_DATABASE=VideoCom
+
+usb:v0F11p2000*
+ ID_PRODUCT_FROM_DATABASE=COM3LAB
+
+usb:v0F11p2010*
+ ID_PRODUCT_FROM_DATABASE=Terminal Adapter
+
+usb:v0F11p2020*
+ ID_PRODUCT_FROM_DATABASE=Network Analyser
+
+usb:v0F11p2030*
+ ID_PRODUCT_FROM_DATABASE=Converter Control Unit
+
+usb:v0F11p2040*
+ ID_PRODUCT_FROM_DATABASE=Machine Test System
+
+usb:v0F12*
+ ID_VENDOR_FROM_DATABASE=Mars Engineering Corp.
+
+usb:v0F13*
+ ID_VENDOR_FROM_DATABASE=Acetek Technology Co., Ltd
+
+usb:v0F18*
+ ID_VENDOR_FROM_DATABASE=Finger Lakes Instrumentation
+
+usb:v0F18p0002*
+ ID_PRODUCT_FROM_DATABASE=CCD
+
+usb:v0F18p0006*
+ ID_PRODUCT_FROM_DATABASE=Focuser
+
+usb:v0F18p0007*
+ ID_PRODUCT_FROM_DATABASE=Filter Wheel
+
+usb:v0F18p000A*
+ ID_PRODUCT_FROM_DATABASE=ProLine CCD
+
+usb:v0F18p000B*
+ ID_PRODUCT_FROM_DATABASE=Color Filter Wheel 4
+
+usb:v0F18p000C*
+ ID_PRODUCT_FROM_DATABASE=PDF2
+
+usb:v0F18p000D*
+ ID_PRODUCT_FROM_DATABASE=Guider
+
+usb:v0F19*
+ ID_VENDOR_FROM_DATABASE=Oracom Co., Ltd
+
+usb:v0F1B*
+ ID_VENDOR_FROM_DATABASE=Onset Computer Corp.
+
+usb:v0F1C*
+ ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd
+
+usb:v0F1D*
+ ID_VENDOR_FROM_DATABASE=Iwill Corp.
+
+usb:v0F21*
+ ID_VENDOR_FROM_DATABASE=IOI Technology Corp.
+
+usb:v0F22*
+ ID_VENDOR_FROM_DATABASE=Senior Industries, Inc.
+
+usb:v0F23*
+ ID_VENDOR_FROM_DATABASE=Leader Tech Manufacturer Co., Ltd
+
+usb:v0F24*
+ ID_VENDOR_FROM_DATABASE=Flex-P Industries, Snd., Bhd.
+
+usb:v0F2D*
+ ID_VENDOR_FROM_DATABASE=ViPower, Inc.
+
+usb:v0F2E*
+ ID_VENDOR_FROM_DATABASE=Geniality Maple Technology Co., Ltd
+
+usb:v0F2F*
+ ID_VENDOR_FROM_DATABASE=Priva Design Services
+
+usb:v0F30*
+ ID_VENDOR_FROM_DATABASE=Jess Technology Co., Ltd
+
+usb:v0F30p001C*
+ ID_PRODUCT_FROM_DATABASE=PS3 Guitar Controller Dongle
+
+usb:v0F30p0110*
+ ID_PRODUCT_FROM_DATABASE=Dual Analog Rumble Pad
+
+usb:v0F30p0111*
+ ID_PRODUCT_FROM_DATABASE=Colour Rumble Pad
+
+usb:v0F30p0208*
+ ID_PRODUCT_FROM_DATABASE=Xbox & PC Gamepad
+
+usb:v0F31*
+ ID_VENDOR_FROM_DATABASE=Chrysalis Development
+
+usb:v0F32*
+ ID_VENDOR_FROM_DATABASE=YFC-BonEagle Electric Co., Ltd
+
+usb:v0F37*
+ ID_VENDOR_FROM_DATABASE=Kokuyo Co., Ltd
+
+usb:v0F38*
+ ID_VENDOR_FROM_DATABASE=Nien-Yi Industrial Corp.
+
+usb:v0F3D*
+ ID_VENDOR_FROM_DATABASE=Airprime, Incorporated
+
+usb:v0F3Dp0112*
+ ID_PRODUCT_FROM_DATABASE=CDMA 1xEVDO PC Card, PC 5220
+
+usb:v0F41*
+ ID_VENDOR_FROM_DATABASE=RDC Semiconductor Co., Ltd
+
+usb:v0F42*
+ ID_VENDOR_FROM_DATABASE=Nital Consulting Services, Inc.
+
+usb:v0F44*
+ ID_VENDOR_FROM_DATABASE=Polhemus
+
+usb:v0F44pEF11*
+ ID_PRODUCT_FROM_DATABASE=Patriot (firmware not loaded)
+
+usb:v0F44pEF12*
+ ID_PRODUCT_FROM_DATABASE=Patriot
+
+usb:v0F44pFF11*
+ ID_PRODUCT_FROM_DATABASE=Liberty (firmware not loaded)
+
+usb:v0F44pFF12*
+ ID_PRODUCT_FROM_DATABASE=Liberty
+
+usb:v0F4B*
+ ID_VENDOR_FROM_DATABASE=St. John Technology Co., Ltd
+
+usb:v0F4C*
+ ID_VENDOR_FROM_DATABASE=WorldWide Cable Opto Corp.
+
+usb:v0F4D*
+ ID_VENDOR_FROM_DATABASE=Microtune, Inc.
+
+usb:v0F4Dp1000*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v0F4E*
+ ID_VENDOR_FROM_DATABASE=Freedom Scientific
+
+usb:v0F52*
+ ID_VENDOR_FROM_DATABASE=Wing Key Electrical Co., Ltd
+
+usb:v0F53*
+ ID_VENDOR_FROM_DATABASE=Dongguan White Horse Cable Factory, Ltd
+
+usb:v0F54*
+ ID_VENDOR_FROM_DATABASE=Kawai Musical Instruments Mfg. Co., Ltd
+
+usb:v0F55*
+ ID_VENDOR_FROM_DATABASE=AmbiCom, Inc.
+
+usb:v0F5C*
+ ID_VENDOR_FROM_DATABASE=Prairiecomm, Inc.
+
+usb:v0F5D*
+ ID_VENDOR_FROM_DATABASE=NewAge International, LLC
+
+usb:v0F5Dp9455*
+ ID_PRODUCT_FROM_DATABASE=Compact Drive
+
+usb:v0F5F*
+ ID_VENDOR_FROM_DATABASE=Key Technology Corp.
+
+usb:v0F60*
+ ID_VENDOR_FROM_DATABASE=NTK, Ltd
+
+usb:v0F61*
+ ID_VENDOR_FROM_DATABASE=Varian, Inc.
+
+usb:v0F62*
+ ID_VENDOR_FROM_DATABASE=Acrox Technologies Co., Ltd
+
+usb:v0F62p1001*
+ ID_PRODUCT_FROM_DATABASE=Targus Mini Trackball Optical Mouse
+
+usb:v0F63*
+ ID_VENDOR_FROM_DATABASE=LeapFrog Enterprises
+
+usb:v0F63p0010*
+ ID_PRODUCT_FROM_DATABASE=Leapster Explorer
+
+usb:v0F63p0500*
+ ID_PRODUCT_FROM_DATABASE=Fly Fusion
+
+usb:v0F63p0600*
+ ID_PRODUCT_FROM_DATABASE=Leap Port Turbo
+
+usb:v0F63p0700*
+ ID_PRODUCT_FROM_DATABASE=POGO
+
+usb:v0F63p0800*
+ ID_PRODUCT_FROM_DATABASE=Didj
+
+usb:v0F63p0900*
+ ID_PRODUCT_FROM_DATABASE=TAGSchool
+
+usb:v0F63p0A00*
+ ID_PRODUCT_FROM_DATABASE=Leapster 2
+
+usb:v0F63p0B00*
+ ID_PRODUCT_FROM_DATABASE=Crammer
+
+usb:v0F63p0C00*
+ ID_PRODUCT_FROM_DATABASE=Tag Jr
+
+usb:v0F63p0D00*
+ ID_PRODUCT_FROM_DATABASE=My Pal Scout
+
+usb:v0F63p0E00*
+ ID_PRODUCT_FROM_DATABASE=Tag32
+
+usb:v0F63p0F00*
+ ID_PRODUCT_FROM_DATABASE=Tag64
+
+usb:v0F63p1000*
+ ID_PRODUCT_FROM_DATABASE=Kiwi16
+
+usb:v0F63p1100*
+ ID_PRODUCT_FROM_DATABASE=Leapster L2x
+
+usb:v0F63p1111*
+ ID_PRODUCT_FROM_DATABASE=Fly Fusion
+
+usb:v0F63p1300*
+ ID_PRODUCT_FROM_DATABASE=Didj UK/France (Leapster Advance)
+
+usb:v0F68*
+ ID_VENDOR_FROM_DATABASE=Kobe Steel, Ltd
+
+usb:v0F69*
+ ID_VENDOR_FROM_DATABASE=Dionex Corp.
+
+usb:v0F6A*
+ ID_VENDOR_FROM_DATABASE=Vibren Technologies, Inc.
+
+usb:v0F6E*
+ ID_VENDOR_FROM_DATABASE=INTELLIGENT SYSTEMS
+
+usb:v0F6Ep0100*
+ ID_PRODUCT_FROM_DATABASE=GameBoy Color Emulator
+
+usb:v0F6Ep0201*
+ ID_PRODUCT_FROM_DATABASE=GameBoy Advance Flash Gang Writer
+
+usb:v0F6Ep0202*
+ ID_PRODUCT_FROM_DATABASE=GameBoy Advance Capture
+
+usb:v0F6Ep0300*
+ ID_PRODUCT_FROM_DATABASE=Gamecube DOL Viewer
+
+usb:v0F6Ep0400*
+ ID_PRODUCT_FROM_DATABASE=NDS Emulator
+
+usb:v0F6Ep0401*
+ ID_PRODUCT_FROM_DATABASE=NDS UIC
+
+usb:v0F6Ep0402*
+ ID_PRODUCT_FROM_DATABASE=NDS Writer
+
+usb:v0F6Ep0403*
+ ID_PRODUCT_FROM_DATABASE=NDS Capture
+
+usb:v0F6Ep0404*
+ ID_PRODUCT_FROM_DATABASE=NDS Emulator (Lite)
+
+usb:v0F73*
+ ID_VENDOR_FROM_DATABASE=DFI
+
+usb:v0F7C*
+ ID_VENDOR_FROM_DATABASE=DQ Technology, Inc.
+
+usb:v0F7D*
+ ID_VENDOR_FROM_DATABASE=NetBotz, Inc.
+
+usb:v0F7E*
+ ID_VENDOR_FROM_DATABASE=Fluke Corp.
+
+usb:v0F88*
+ ID_VENDOR_FROM_DATABASE=VTech Holdings, Ltd
+
+usb:v0F88p3012*
+ ID_PRODUCT_FROM_DATABASE=RT2570
+
+usb:v0F88p3014*
+ ID_PRODUCT_FROM_DATABASE=ZD1211B
+
+usb:v0F8B*
+ ID_VENDOR_FROM_DATABASE=Yazaki Corp.
+
+usb:v0F8C*
+ ID_VENDOR_FROM_DATABASE=Young Generation International Corp.
+
+usb:v0F8D*
+ ID_VENDOR_FROM_DATABASE=Uniwill Computer Corp.
+
+usb:v0F8E*
+ ID_VENDOR_FROM_DATABASE=Kingnet Technology Co., Ltd
+
+usb:v0F8F*
+ ID_VENDOR_FROM_DATABASE=Soma Networks
+
+usb:v0F97*
+ ID_VENDOR_FROM_DATABASE=CviLux Corp.
+
+usb:v0F98*
+ ID_VENDOR_FROM_DATABASE=CyberBank Corp.
+
+usb:v0F9C*
+ ID_VENDOR_FROM_DATABASE=Hyun Won, Inc.
+
+usb:v0F9Cp0301*
+ ID_PRODUCT_FROM_DATABASE=M-Any Premium DAH-610 MP3/WMA Player
+
+usb:v0F9Cp0332*
+ ID_PRODUCT_FROM_DATABASE=mobiBLU DAH-1200 MP3/Ogg Player
+
+usb:v0F9E*
+ ID_VENDOR_FROM_DATABASE=Lucent Technologies
+
+usb:v0FA3*
+ ID_VENDOR_FROM_DATABASE=Starconn Electronic Co., Ltd
+
+usb:v0FA4*
+ ID_VENDOR_FROM_DATABASE=ATL Technology
+
+usb:v0FA5*
+ ID_VENDOR_FROM_DATABASE=Sotec Co., Ltd
+
+usb:v0FA7*
+ ID_VENDOR_FROM_DATABASE=Epox Computer Co., Ltd
+
+usb:v0FA8*
+ ID_VENDOR_FROM_DATABASE=Logic Controls, Inc.
+
+usb:v0FAF*
+ ID_VENDOR_FROM_DATABASE=Winpoint Electronic Corp.
+
+usb:v0FB0*
+ ID_VENDOR_FROM_DATABASE=Haurtian Wire & Cable Co., Ltd
+
+usb:v0FB1*
+ ID_VENDOR_FROM_DATABASE=Inclose Design, Inc.
+
+usb:v0FB2*
+ ID_VENDOR_FROM_DATABASE=Juan-Chern Industrial Co., Ltd
+
+usb:v0FB6*
+ ID_VENDOR_FROM_DATABASE=Heber Ltd
+
+usb:v0FB6p3FC3*
+ ID_PRODUCT_FROM_DATABASE=Firefly X10i I/O Board (with firmware)
+
+usb:v0FB6p3FC4*
+ ID_PRODUCT_FROM_DATABASE=Firefly X10i I/O Board (without firmware)
+
+usb:v0FB8*
+ ID_VENDOR_FROM_DATABASE=Wistron Corp.
+
+usb:v0FB8p0002*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v0FB9*
+ ID_VENDOR_FROM_DATABASE=AACom Corp.
+
+usb:v0FBA*
+ ID_VENDOR_FROM_DATABASE=San Shing Electronics Co., Ltd
+
+usb:v0FBB*
+ ID_VENDOR_FROM_DATABASE=Bitwise Systems, Inc.
+
+usb:v0FC1*
+ ID_VENDOR_FROM_DATABASE=Mitac Internatinal Corp.
+
+usb:v0FC2*
+ ID_VENDOR_FROM_DATABASE=Plug and Jack Industrial, Inc.
+
+usb:v0FC5*
+ ID_VENDOR_FROM_DATABASE=Delcom Engineering
+
+usb:v0FC5p1222*
+ ID_PRODUCT_FROM_DATABASE=I/O Development Board
+
+usb:v0FC6*
+ ID_VENDOR_FROM_DATABASE=Dataplus Supplies, Inc.
+
+usb:v0FCA*
+ ID_VENDOR_FROM_DATABASE=Research In Motion, Ltd.
+
+usb:v0FCAp0001*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Handheld
+
+usb:v0FCAp0004*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Handheld
+
+usb:v0FCAp0006*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Pearl
+
+usb:v0FCAp0008*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Pearl
+
+usb:v0FCAp8001*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Handheld
+
+usb:v0FCAp8004*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Handheld
+
+usb:v0FCAp8007*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Handheld
+
+usb:v0FCAp8010*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Playbook (Connect to Windows mode)
+
+usb:v0FCAp8011*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Playbook (Connect to Mac mode)
+
+usb:v0FCAp8020*
+ ID_PRODUCT_FROM_DATABASE=Blackberry Playbook (CD-Rom mode)
+
+usb:v0FCE*
+ ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+
+usb:v0FCEp0076*
+ ID_PRODUCT_FROM_DATABASE=W910i (Multimedia mode)
+
+usb:v0FCEp00AF*
+ ID_PRODUCT_FROM_DATABASE=V640i Phone [PTP Camera]
+
+usb:v0FCEp00D4*
+ ID_PRODUCT_FROM_DATABASE=C902 [MTP]
+
+usb:v0FCEp00D9*
+ ID_PRODUCT_FROM_DATABASE=C702 Phone
+
+usb:v0FCEp0112*
+ ID_PRODUCT_FROM_DATABASE=W995 Walkman Phone
+
+usb:v0FCEp0166*
+ ID_PRODUCT_FROM_DATABASE=Xperia Mini Pro
+
+usb:v0FCEp0169*
+ ID_PRODUCT_FROM_DATABASE=Xperia S
+
+usb:v0FCEp0172*
+ ID_PRODUCT_FROM_DATABASE=Xperia P
+
+usb:v0FCEp1010*
+ ID_PRODUCT_FROM_DATABASE=WMC Modem
+
+usb:v0FCEp10AF*
+ ID_PRODUCT_FROM_DATABASE=V640i Phone [PictBridge]
+
+usb:v0FCEp10D4*
+ ID_PRODUCT_FROM_DATABASE=C902 Phone [PictBridge]
+
+usb:v0FCEp2105*
+ ID_PRODUCT_FROM_DATABASE=W715 Phone
+
+usb:v0FCEp2137*
+ ID_PRODUCT_FROM_DATABASE=Xperia X10 mini (USB debug)
+
+usb:v0FCEp2138*
+ ID_PRODUCT_FROM_DATABASE=Xperia X10 mini pro (Debug)
+
+usb:v0FCEp2149*
+ ID_PRODUCT_FROM_DATABASE=Xperia X8 (debug)
+
+usb:v0FCEp3137*
+ ID_PRODUCT_FROM_DATABASE=Xperia X10 mini
+
+usb:v0FCEp3138*
+ ID_PRODUCT_FROM_DATABASE=Xperia X10 mini pro
+
+usb:v0FCEp3149*
+ ID_PRODUCT_FROM_DATABASE=Xperia X8
+
+usb:v0FCEp614F*
+ ID_PRODUCT_FROM_DATABASE=Xperia X12 (debug mode)
+
+usb:v0FCEp6166*
+ ID_PRODUCT_FROM_DATABASE=Xperia Mini Pro
+
+usb:v0FCEp8004*
+ ID_PRODUCT_FROM_DATABASE=9000 Phone [Mass Storage]
+
+usb:v0FCEpADDE*
+ ID_PRODUCT_FROM_DATABASE=Boot loader
+
+usb:v0FCEpD008*
+ ID_PRODUCT_FROM_DATABASE=V800-Vodafone 802SE Phone
+
+usb:v0FCEpD016*
+ ID_PRODUCT_FROM_DATABASE=K750i Phone
+
+usb:v0FCEpD017*
+ ID_PRODUCT_FROM_DATABASE=K608i Phone
+
+usb:v0FCEpD019*
+ ID_PRODUCT_FROM_DATABASE=VDC EGPRS Modem
+
+usb:v0FCEpD025*
+ ID_PRODUCT_FROM_DATABASE=520 WMC Data Modem
+
+usb:v0FCEpD028*
+ ID_PRODUCT_FROM_DATABASE=W800i
+
+usb:v0FCEpD038*
+ ID_PRODUCT_FROM_DATABASE=W850i Phone
+
+usb:v0FCEpD039*
+ ID_PRODUCT_FROM_DATABASE=K800i (phone mode)
+
+usb:v0FCEpD041*
+ ID_PRODUCT_FROM_DATABASE=K510i Phone
+
+usb:v0FCEpD042*
+ ID_PRODUCT_FROM_DATABASE=W810i Phone
+
+usb:v0FCEpD043*
+ ID_PRODUCT_FROM_DATABASE=V630i Phone
+
+usb:v0FCEpD046*
+ ID_PRODUCT_FROM_DATABASE=K610i Phone
+
+usb:v0FCEpD065*
+ ID_PRODUCT_FROM_DATABASE=W960i Phone (PC Suite)
+
+usb:v0FCEpD076*
+ ID_PRODUCT_FROM_DATABASE=W910i (Phone mode)
+
+usb:v0FCEpD089*
+ ID_PRODUCT_FROM_DATABASE=W580i Phone (mass storage)
+
+usb:v0FCEpD0A1*
+ ID_PRODUCT_FROM_DATABASE=K810
+
+usb:v0FCEpD0AF*
+ ID_PRODUCT_FROM_DATABASE=V640i Phone
+
+usb:v0FCEpD0CF*
+ ID_PRODUCT_FROM_DATABASE=MD300 Mobile Broadband Modem
+
+usb:v0FCEpD0D4*
+ ID_PRODUCT_FROM_DATABASE=C902 Phone [Modem]
+
+usb:v0FCEpD0E1*
+ ID_PRODUCT_FROM_DATABASE=MD400 Mobile Broadband Modem
+
+usb:v0FCEpD12E*
+ ID_PRODUCT_FROM_DATABASE=Xperia X10
+
+usb:v0FCEpE000*
+ ID_PRODUCT_FROM_DATABASE=K810 (PictBridge mode)
+
+usb:v0FCEpE039*
+ ID_PRODUCT_FROM_DATABASE=K800i (msc mode)
+
+usb:v0FCEpE042*
+ ID_PRODUCT_FROM_DATABASE=W810i Phone
+
+usb:v0FCEpE043*
+ ID_PRODUCT_FROM_DATABASE=V630i Phone [Mass Storage]
+
+usb:v0FCEpE075*
+ ID_PRODUCT_FROM_DATABASE=K850i
+
+usb:v0FCEpE076*
+ ID_PRODUCT_FROM_DATABASE=W910i (Mass storage)
+
+usb:v0FCEpE089*
+ ID_PRODUCT_FROM_DATABASE=W580i Phone
+
+usb:v0FCEpE090*
+ ID_PRODUCT_FROM_DATABASE=W200 Phone (Mass Storage)
+
+usb:v0FCEpE0A1*
+ ID_PRODUCT_FROM_DATABASE=K810 (Mass Storage mode)
+
+usb:v0FCEpE0A3*
+ ID_PRODUCT_FROM_DATABASE=W660i
+
+usb:v0FCEpE0AF*
+ ID_PRODUCT_FROM_DATABASE=V640i Phone [Mass Storage]
+
+usb:v0FCEpE0D4*
+ ID_PRODUCT_FROM_DATABASE=C902 Phone [Mass Storage]
+
+usb:v0FCEpE0EF*
+ ID_PRODUCT_FROM_DATABASE=C905 Phone [Mass Storage]
+
+usb:v0FCEpE0F3*
+ ID_PRODUCT_FROM_DATABASE=W595
+
+usb:v0FCEpE105*
+ ID_PRODUCT_FROM_DATABASE=W705
+
+usb:v0FCEpE112*
+ ID_PRODUCT_FROM_DATABASE=W995 Phone (Mass Storage)
+
+usb:v0FCEpE12E*
+ ID_PRODUCT_FROM_DATABASE=X10i Phone
+
+usb:v0FCEpE133*
+ ID_PRODUCT_FROM_DATABASE=Vivaz
+
+usb:v0FCEpE14F*
+ ID_PRODUCT_FROM_DATABASE=Xperia Arc/X12
+
+usb:v0FCEpE161*
+ ID_PRODUCT_FROM_DATABASE=Xperia Ray
+
+usb:v0FCEpE166*
+ ID_PRODUCT_FROM_DATABASE=Xperia Mini Pro
+
+usb:v0FCEpE167*
+ ID_PRODUCT_FROM_DATABASE=XPERIA mini
+
+usb:v0FCF*
+ ID_VENDOR_FROM_DATABASE=Dynastream Innovations, Inc.
+
+usb:v0FCFp1003*
+ ID_PRODUCT_FROM_DATABASE=ANT Development Board
+
+usb:v0FCFp1004*
+ ID_PRODUCT_FROM_DATABASE=ANT2USB
+
+usb:v0FCFp1006*
+ ID_PRODUCT_FROM_DATABASE=ANT Development Board
+
+usb:v0FCFp1008*
+ ID_PRODUCT_FROM_DATABASE=Mini stick Suunto
+
+usb:v0FD0*
+ ID_VENDOR_FROM_DATABASE=Tulip Computers B.V.
+
+usb:v0FD1*
+ ID_VENDOR_FROM_DATABASE=Giant Electronics Ltd.
+
+usb:v0FD4*
+ ID_VENDOR_FROM_DATABASE=Tenovis GmbH & Co., KG
+
+usb:v0FD5*
+ ID_VENDOR_FROM_DATABASE=Direct Access Technology, Inc.
+
+usb:v0FD9*
+ ID_VENDOR_FROM_DATABASE=Elgato Systems GmbH
+
+usb:v0FD9p0011*
+ ID_PRODUCT_FROM_DATABASE=EyeTV Diversity
+
+usb:v0FD9p0018*
+ ID_PRODUCT_FROM_DATABASE=EyeTV Hybrid
+
+usb:v0FD9p0020*
+ ID_PRODUCT_FROM_DATABASE=EyeTV DTT Deluxe
+
+usb:v0FD9p0021*
+ ID_PRODUCT_FROM_DATABASE=EyeTV DTT
+
+usb:v0FD9p002A*
+ ID_PRODUCT_FROM_DATABASE=EyeTV Sat
+
+usb:v0FD9p002C*
+ ID_PRODUCT_FROM_DATABASE=EyeTV DTT Deluxe v2
+
+usb:v0FD9p0033*
+ ID_PRODUCT_FROM_DATABASE=Video Capture
+
+usb:v0FD9p0037*
+ ID_PRODUCT_FROM_DATABASE=Video Capture v2
+
+usb:v0FDC*
+ ID_VENDOR_FROM_DATABASE=Micro Plus
+
+usb:v0FE0*
+ ID_VENDOR_FROM_DATABASE=Osterhout Design Group
+
+usb:v0FE0p0100*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Mouse
+
+usb:v0FE0p0101*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth IMU
+
+usb:v0FE0p0200*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Keypad
+
+usb:v0FE4*
+ ID_VENDOR_FROM_DATABASE=IN-Tech Electronics, Ltd
+
+usb:v0FE5*
+ ID_VENDOR_FROM_DATABASE=Greenconn (U.S.A.), Inc.
+
+usb:v0FE6*
+ ID_VENDOR_FROM_DATABASE=Kontron (Industrial Computer Source / ICS Advent)
+
+usb:v0FE6p8101*
+ ID_PRODUCT_FROM_DATABASE=DM9601 Fast Ethernet Adapter
+
+usb:v0FE6p811E*
+ ID_PRODUCT_FROM_DATABASE=Parallel Adapter
+
+usb:v0FE6p9700*
+ ID_PRODUCT_FROM_DATABASE=DM9601 Fast Ethernet Adapter
+
+usb:v0FE9*
+ ID_VENDOR_FROM_DATABASE=DVICO
+
+usb:v0FE9p4020*
+ ID_PRODUCT_FROM_DATABASE=TViX M-6500
+
+usb:v0FE9pDB00*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T (MT352+LgZ201) (uninitialized)
+
+usb:v0FE9pDB01*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T (MT352+LgZ201) (initialized)
+
+usb:v0FE9pDB10*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T (MT352+Thomson7579) (uninitialized)
+
+usb:v0FE9pDB11*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T (MT352+Thomson7579) (initialized)
+
+usb:v0FE9pDB78*
+ ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Dual Digital 4 (ZL10353+xc2028/xc3028) (initialized)
+
+usb:v0FEA*
+ ID_VENDOR_FROM_DATABASE=United Computer Accessories
+
+usb:v0FEB*
+ ID_VENDOR_FROM_DATABASE=CRS Electronic Co., Ltd
+
+usb:v0FEC*
+ ID_VENDOR_FROM_DATABASE=UMC Electronics Co., Ltd
+
+usb:v0FED*
+ ID_VENDOR_FROM_DATABASE=Access Co., Ltd
+
+usb:v0FEE*
+ ID_VENDOR_FROM_DATABASE=Xsido Corp.
+
+usb:v0FEF*
+ ID_VENDOR_FROM_DATABASE=MJ Research, Inc.
+
+usb:v0FF6*
+ ID_VENDOR_FROM_DATABASE=Core Valley Co., Ltd
+
+usb:v0FF7*
+ ID_VENDOR_FROM_DATABASE=CHI SHING Computer Accessories Co., Ltd
+
+usb:v0FFC*
+ ID_VENDOR_FROM_DATABASE=Clavia DMI AB
+
+usb:v0FFCp0021*
+ ID_PRODUCT_FROM_DATABASE=Nord Stage 2
+
+usb:v0FFF*
+ ID_VENDOR_FROM_DATABASE=Aopen, Inc.
+
+usb:v1000*
+ ID_VENDOR_FROM_DATABASE=Speed Tech Corp.
+
+usb:v1001*
+ ID_VENDOR_FROM_DATABASE=Ritronics Components (S) Pte., Ltd
+
+usb:v1003*
+ ID_VENDOR_FROM_DATABASE=Sigma Corp.
+
+usb:v1003p0003*
+ ID_PRODUCT_FROM_DATABASE=SD14
+
+usb:v1003p0100*
+ ID_PRODUCT_FROM_DATABASE=SD9/SD10
+
+usb:v1004*
+ ID_VENDOR_FROM_DATABASE=LG Electronics, Inc.
+
+usb:v1004p1FAE*
+ ID_PRODUCT_FROM_DATABASE=U8120 3G Cellphone
+
+usb:v1004p6000*
+ ID_PRODUCT_FROM_DATABASE=KU330/KU990/VX4400/VX6000
+
+usb:v1004p6005*
+ ID_PRODUCT_FROM_DATABASE=T5100
+
+usb:v1004p6018*
+ ID_PRODUCT_FROM_DATABASE=GM360/GD510/GW520/KP501
+
+usb:v1004p618E*
+ ID_PRODUCT_FROM_DATABASE=Ally/Optimus One/Vortex (debug mode)
+
+usb:v1004p618F*
+ ID_PRODUCT_FROM_DATABASE=Ally/Optimus One
+
+usb:v1004p61C6*
+ ID_PRODUCT_FROM_DATABASE=Vortex (msc)
+
+usb:v1004p61CC*
+ ID_PRODUCT_FROM_DATABASE=Optimus S
+
+usb:v1004p61FC*
+ ID_PRODUCT_FROM_DATABASE=Optimus 3
+
+usb:v1004p6800*
+ ID_PRODUCT_FROM_DATABASE=CDMA Modem
+
+usb:v1004p7000*
+ ID_PRODUCT_FROM_DATABASE=LG LDP-7024D(LD)USB
+
+usb:v1004pA400*
+ ID_PRODUCT_FROM_DATABASE=Renoir (KC910)
+
+usb:v1005*
+ ID_VENDOR_FROM_DATABASE=Apacer Technology, Inc.
+
+usb:v1005p1001*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v1005p1004*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v1005p1006*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v1005pB113*
+ ID_PRODUCT_FROM_DATABASE=Handy Steno 2.0/HT203
+
+usb:v1005pB223*
+ ID_PRODUCT_FROM_DATABASE=CD-RW + 6in1 Card Reader Digital Storage / Converter
+
+usb:v1006*
+ ID_VENDOR_FROM_DATABASE=iRiver, Ltd.
+
+usb:v1006p3001*
+ ID_PRODUCT_FROM_DATABASE=iHP-100
+
+usb:v1006p3002*
+ ID_PRODUCT_FROM_DATABASE=iHP-120/140 MP3 Player
+
+usb:v1006p3003*
+ ID_PRODUCT_FROM_DATABASE=H320/H340
+
+usb:v1006p3004*
+ ID_PRODUCT_FROM_DATABASE=H340 (mtp)
+
+usb:v1009*
+ ID_VENDOR_FROM_DATABASE=Emuzed, Inc.
+
+usb:v1009p000E*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v1009p0013*
+ ID_PRODUCT_FROM_DATABASE=Angel MPEG Device
+
+usb:v1009p0015*
+ ID_PRODUCT_FROM_DATABASE=Lumanate Wave PAL SECAM DVBT Device
+
+usb:v1009p0016*
+ ID_PRODUCT_FROM_DATABASE=Lumanate Wave NTSC/ATSC Combo Device
+
+usb:v100A*
+ ID_VENDOR_FROM_DATABASE=AV Chaseway, Ltd
+
+usb:v100Ap2402*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v100Ap2404*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v100Ap2405*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v100Ap2406*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v100ApA0C0*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v100B*
+ ID_VENDOR_FROM_DATABASE=Chou Chin Industrial Co., Ltd
+
+usb:v100D*
+ ID_VENDOR_FROM_DATABASE=Netopia, Inc.
+
+usb:v100Dp3342*
+ ID_PRODUCT_FROM_DATABASE=Cayman 3352 DSL Modem
+
+usb:v100Dp3382*
+ ID_PRODUCT_FROM_DATABASE=3380 Series Network Interface
+
+usb:v100Dp6072*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v100Dp9031*
+ ID_PRODUCT_FROM_DATABASE=Motorola 802.11n Dualband USB Wireless Adapter
+
+usb:v100Dp9032*
+ ID_PRODUCT_FROM_DATABASE=Motorola 802.11n 5G USB Wireless Adapter
+
+usb:v100DpCB01*
+ ID_PRODUCT_FROM_DATABASE=Cayman 3341 Ethernet DSL Router
+
+usb:v1010*
+ ID_VENDOR_FROM_DATABASE=Fukuda Denshi Co., Ltd
+
+usb:v1011*
+ ID_VENDOR_FROM_DATABASE=Mobile Media Tech.
+
+usb:v1011p0001*
+ ID_PRODUCT_FROM_DATABASE=AccFast Mp3
+
+usb:v1012*
+ ID_VENDOR_FROM_DATABASE=SDKM Fibres, Wires & Cables Berhad
+
+usb:v1013*
+ ID_VENDOR_FROM_DATABASE=TST-Touchless Sensor Technology AG
+
+usb:v1014*
+ ID_VENDOR_FROM_DATABASE=Densitron Technologies PLC
+
+usb:v1015*
+ ID_VENDOR_FROM_DATABASE=Softronics Pty., Ltd
+
+usb:v1016*
+ ID_VENDOR_FROM_DATABASE=Xiamen Hung's Enterprise Co., Ltd
+
+usb:v1017*
+ ID_VENDOR_FROM_DATABASE=Speedy Industrial Supplies, Pte., Ltd
+
+usb:v1019*
+ ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems (ECS)
+
+usb:v1019p0C55*
+ ID_PRODUCT_FROM_DATABASE=Flash Reader, Desknote UCR-61S2B
+
+usb:v1019p0F38*
+ ID_PRODUCT_FROM_DATABASE=Infrared Receiver
+
+usb:v1020*
+ ID_VENDOR_FROM_DATABASE=Labtec
+
+usb:v1020p0006*
+ ID_PRODUCT_FROM_DATABASE=Wireless Keyboard
+
+usb:v1020p000A*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse
+
+usb:v1020p0106*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse
+
+usb:v1022*
+ ID_VENDOR_FROM_DATABASE=Shinko Shoji Co., Ltd
+
+usb:v1025*
+ ID_VENDOR_FROM_DATABASE=Hyper-Paltek
+
+usb:v1025p005E*
+ ID_PRODUCT_FROM_DATABASE=USB DVB-T device
+
+usb:v1025p005F*
+ ID_PRODUCT_FROM_DATABASE=USB DVB-T device
+
+usb:v1025p0300*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v1025p0350*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v1026*
+ ID_VENDOR_FROM_DATABASE=Newly Corp.
+
+usb:v1027*
+ ID_VENDOR_FROM_DATABASE=Time Domain
+
+usb:v1028*
+ ID_VENDOR_FROM_DATABASE=Inovys Corp.
+
+usb:v1029*
+ ID_VENDOR_FROM_DATABASE=Atlantic Coast Telesys
+
+usb:v102A*
+ ID_VENDOR_FROM_DATABASE=Ramos Technology Co., Ltd
+
+usb:v102B*
+ ID_VENDOR_FROM_DATABASE=Infotronic America, Inc.
+
+usb:v102C*
+ ID_VENDOR_FROM_DATABASE=Etoms Electronics Corp.
+
+usb:v102Cp6151*
+ ID_PRODUCT_FROM_DATABASE=Q-Cam Sangha CIF
+
+usb:v102Cp6251*
+ ID_PRODUCT_FROM_DATABASE=Q-Cam VGA
+
+usb:v102D*
+ ID_VENDOR_FROM_DATABASE=Winic Corp.
+
+usb:v1031*
+ ID_VENDOR_FROM_DATABASE=Comax Technology, Inc.
+
+usb:v1032*
+ ID_VENDOR_FROM_DATABASE=C-One Technology Corp.
+
+usb:v1033*
+ ID_VENDOR_FROM_DATABASE=Nucam Corp.
+
+usb:v1033p0068*
+ ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231
+
+usb:v1038*
+ ID_VENDOR_FROM_DATABASE=Ideazon, Inc.
+
+usb:v1038p0100*
+ ID_PRODUCT_FROM_DATABASE=Zboard
+
+usb:v1039*
+ ID_VENDOR_FROM_DATABASE=devolo AG
+
+usb:v1039p0824*
+ ID_PRODUCT_FROM_DATABASE=1866 802.11bg [Texas Instruments TNETW1450]
+
+usb:v1039p2140*
+ ID_PRODUCT_FROM_DATABASE=dsl+ 1100 duo
+
+usb:v103D*
+ ID_VENDOR_FROM_DATABASE=Stanton
+
+usb:v103Dp0100*
+ ID_PRODUCT_FROM_DATABASE=ScratchAmp
+
+usb:v103Dp0101*
+ ID_PRODUCT_FROM_DATABASE=ScratchAmp
+
+usb:v1043*
+ ID_VENDOR_FROM_DATABASE=iCreate Technologies Corp.
+
+usb:v1043p160F*
+ ID_PRODUCT_FROM_DATABASE=Wireless Network Adapter
+
+usb:v1043p4901*
+ ID_PRODUCT_FROM_DATABASE=AV-836 Video Capture Device
+
+usb:v1043p8006*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk 32-256 MB
+
+usb:v1043p8012*
+ ID_PRODUCT_FROM_DATABASE=Flash Disk 256 MB
+
+usb:v1044*
+ ID_VENDOR_FROM_DATABASE=Chu Yuen Enterprise Co., Ltd
+
+usb:v1044p7001*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte U7000 DVB-T tuner
+
+usb:v1044p7002*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte U8000 DVB-T tuner
+
+usb:v1044p7004*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte U7100 DVB-T tuner
+
+usb:v1044p7005*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte U7200 DVB-T tuner [AF9035]
+
+usb:v1044p7006*
+ ID_PRODUCT_FROM_DATABASE=Gigabyte U6000 DVB-T tuner [em2863]
+
+usb:v1044p8001*
+ ID_PRODUCT_FROM_DATABASE=GN-54G
+
+usb:v1044p8002*
+ ID_PRODUCT_FROM_DATABASE=GN-BR402W
+
+usb:v1044p8003*
+ ID_PRODUCT_FROM_DATABASE=GN-WLBM101
+
+usb:v1044p8004*
+ ID_PRODUCT_FROM_DATABASE=GN-WLBZ101 802.11b Adapter
+
+usb:v1044p8005*
+ ID_PRODUCT_FROM_DATABASE=GN-WLBZ201 802.11b Adapter
+
+usb:v1044p8006*
+ ID_PRODUCT_FROM_DATABASE=GN-WBZB-M 802.11b Adapter
+
+usb:v1044p8007*
+ ID_PRODUCT_FROM_DATABASE=GN-WBKG
+
+usb:v1044p8008*
+ ID_PRODUCT_FROM_DATABASE=GN-WB01GS
+
+usb:v1044p800A*
+ ID_PRODUCT_FROM_DATABASE=GN-WI05GS
+
+usb:v1044p800B*
+ ID_PRODUCT_FROM_DATABASE=GN-WB30N 802.11n WLAN Card
+
+usb:v1044p800C*
+ ID_PRODUCT_FROM_DATABASE=GN-WB31N 802.11n USB WLAN Card
+
+usb:v1044p800D*
+ ID_PRODUCT_FROM_DATABASE=GN-WB32L 802.11n USB WLAN Card
+
+usb:v1046*
+ ID_VENDOR_FROM_DATABASE=Winbond Electronics Corp. [hex]
+
+usb:v1046p6694*
+ ID_PRODUCT_FROM_DATABASE=Generic W6694 USB
+
+usb:v1046p8901*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v1046p9967*
+ ID_PRODUCT_FROM_DATABASE=W9967CF/W9968CF Webcam IC
+
+usb:v1048*
+ ID_VENDOR_FROM_DATABASE=Targus Group International
+
+usb:v104B*
+ ID_VENDOR_FROM_DATABASE=Mylex / Buslogic
+
+usb:v104C*
+ ID_VENDOR_FROM_DATABASE=AMCO TEC International, Inc.
+
+usb:v104D*
+ ID_VENDOR_FROM_DATABASE=Newport Corporation
+
+usb:v104Dp1003*
+ ID_PRODUCT_FROM_DATABASE=Model-52 LED Light Source Power Supply and Driver
+
+usb:v104F*
+ ID_VENDOR_FROM_DATABASE=WB Electronics
+
+usb:v104Fp0001*
+ ID_PRODUCT_FROM_DATABASE=Infinity Phoenix
+
+usb:v104Fp0002*
+ ID_PRODUCT_FROM_DATABASE=Smartmouse
+
+usb:v104Fp0003*
+ ID_PRODUCT_FROM_DATABASE=FunProgrammer
+
+usb:v104Fp0004*
+ ID_PRODUCT_FROM_DATABASE=Infinity Unlimited
+
+usb:v104Fp0006*
+ ID_PRODUCT_FROM_DATABASE=Infinity Smart
+
+usb:v104Fp0007*
+ ID_PRODUCT_FROM_DATABASE=Infinity Smart module
+
+usb:v104Fp0008*
+ ID_PRODUCT_FROM_DATABASE=Infinity CryptoKey
+
+usb:v104Fp0009*
+ ID_PRODUCT_FROM_DATABASE=RE-BL PlayStation 3 IR-to-Bluetooth converter
+
+usb:v1050*
+ ID_VENDOR_FROM_DATABASE=Yubico.com
+
+usb:v1050p0010*
+ ID_PRODUCT_FROM_DATABASE=Yubikey
+
+usb:v1053*
+ ID_VENDOR_FROM_DATABASE=Immanuel Electronics Co., Ltd
+
+usb:v1054*
+ ID_VENDOR_FROM_DATABASE=BMS International Beheer N.V.
+
+usb:v1054p5004*
+ ID_PRODUCT_FROM_DATABASE=DSL 7420 Loader
+
+usb:v1054p5005*
+ ID_PRODUCT_FROM_DATABASE=DSL 7420 LAN Modem
+
+usb:v1055*
+ ID_VENDOR_FROM_DATABASE=Complex Micro Interconnection Co., Ltd
+
+usb:v1056*
+ ID_VENDOR_FROM_DATABASE=Hsin Chen Ent Co., Ltd
+
+usb:v1057*
+ ID_VENDOR_FROM_DATABASE=ON Semiconductor
+
+usb:v1058*
+ ID_VENDOR_FROM_DATABASE=Western Digital Technologies, Inc.
+
+usb:v1058p0200*
+ ID_PRODUCT_FROM_DATABASE=Firewire USB Combo
+
+usb:v1058p0400*
+ ID_PRODUCT_FROM_DATABASE=External HDD
+
+usb:v1058p0500*
+ ID_PRODUCT_FROM_DATABASE=hub
+
+usb:v1058p0702*
+ ID_PRODUCT_FROM_DATABASE=Passport External HDD
+
+usb:v1058p0704*
+ ID_PRODUCT_FROM_DATABASE=Passport External HDD
+
+usb:v1058p070A*
+ ID_PRODUCT_FROM_DATABASE=My Passport Essential SE
+
+usb:v1058p071A*
+ ID_PRODUCT_FROM_DATABASE=My Passport 1TB
+
+usb:v1058p0740*
+ ID_PRODUCT_FROM_DATABASE=My Passport 1TB
+
+usb:v1058p0742*
+ ID_PRODUCT_FROM_DATABASE=My Passport Essential SE
+
+usb:v1058p0748*
+ ID_PRODUCT_FROM_DATABASE=My Passport 1TB USB 3.0
+
+usb:v1058p0900*
+ ID_PRODUCT_FROM_DATABASE=MyBook Essential External HDD
+
+usb:v1058p0901*
+ ID_PRODUCT_FROM_DATABASE=MyBook External HDD
+
+usb:v1058p0903*
+ ID_PRODUCT_FROM_DATABASE=My Book Premium Edition
+
+usb:v1058p0910*
+ ID_PRODUCT_FROM_DATABASE=MyBook Essential External HDD
+
+usb:v1058p1001*
+ ID_PRODUCT_FROM_DATABASE=External Hard Disk [Elements]
+
+usb:v1058p1003*
+ ID_PRODUCT_FROM_DATABASE=Elements 1000 GB
+
+usb:v1058p1010*
+ ID_PRODUCT_FROM_DATABASE=Elements External HDD
+
+usb:v1058p1021*
+ ID_PRODUCT_FROM_DATABASE=Elements 2TB
+
+usb:v1058p1023*
+ ID_PRODUCT_FROM_DATABASE=Elements SE
+
+usb:v1058p1103*
+ ID_PRODUCT_FROM_DATABASE=My Book Studio
+
+usb:v1058p1104*
+ ID_PRODUCT_FROM_DATABASE=MyBook Mirror Edition External HDD
+
+usb:v1058p1105*
+ ID_PRODUCT_FROM_DATABASE=My Book Studio II
+
+usb:v1058p1123*
+ ID_PRODUCT_FROM_DATABASE=My Book 3.0
+
+usb:v1058p1140*
+ ID_PRODUCT_FROM_DATABASE=My Book Essential USB3.0
+
+usb:v1059*
+ ID_VENDOR_FROM_DATABASE=Giesecke & Devrient GmbH
+
+usb:v1059p000B*
+ ID_PRODUCT_FROM_DATABASE=StarSign Bio Token 3.0
+
+usb:v105C*
+ ID_VENDOR_FROM_DATABASE=Hong Ji Electric Wire & Cable (Dongguan) Co., Ltd
+
+usb:v105D*
+ ID_VENDOR_FROM_DATABASE=Delkin Devices, Inc.
+
+usb:v105E*
+ ID_VENDOR_FROM_DATABASE=Valence Semiconductor Design, Ltd
+
+usb:v105F*
+ ID_VENDOR_FROM_DATABASE=Chin Shong Enterprise Co., Ltd
+
+usb:v1060*
+ ID_VENDOR_FROM_DATABASE=Easthome Industrial Co., Ltd
+
+usb:v1063*
+ ID_VENDOR_FROM_DATABASE=Motorola Electronics Taiwan, Ltd [hex]
+
+usb:v1063p1555*
+ ID_PRODUCT_FROM_DATABASE=MC141555 Hub
+
+usb:v1063p4100*
+ ID_PRODUCT_FROM_DATABASE=SB4100 USB Cable Modem
+
+usb:v1065*
+ ID_VENDOR_FROM_DATABASE=CCYU Technology
+
+usb:v1065p0020*
+ ID_PRODUCT_FROM_DATABASE=USB-DVR2 Dev Board
+
+usb:v1065p2136*
+ ID_PRODUCT_FROM_DATABASE=EasyDisk ED1064
+
+usb:v106A*
+ ID_VENDOR_FROM_DATABASE=Loyal Legend, Ltd
+
+usb:v106C*
+ ID_VENDOR_FROM_DATABASE=Curitel Communications, Inc.
+
+usb:v106Cp1101*
+ ID_PRODUCT_FROM_DATABASE=CDMA 2000 1xRTT USB modem (HX-550C)
+
+usb:v106Cp1102*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp1103*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp1104*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp1105*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v106Cp1106*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp1301*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v106Cp1302*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp1303*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp1304*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp1401*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v106Cp1402*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp1403*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp1501*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp1502*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp1503*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp1601*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp1602*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp1603*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp2101*
+ ID_PRODUCT_FROM_DATABASE=AudioVox 8900 Cell Phone
+
+usb:v106Cp2102*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp2103*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp2301*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp2302*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp2303*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp2401*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp2402*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp2403*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp2501*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp2502*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp2503*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp2601*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp2602*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp2603*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp3701*
+ ID_PRODUCT_FROM_DATABASE=Broadband Wireless modem
+
+usb:v106Cp3702*
+ ID_PRODUCT_FROM_DATABASE=Pantech PX-500
+
+usb:v106Cp3714*
+ ID_PRODUCT_FROM_DATABASE=PANTECH USB MODEM [UM175]
+
+usb:v106Cp3716*
+ ID_PRODUCT_FROM_DATABASE=UMW190 Modem
+
+usb:v106Cp3721*
+ ID_PRODUCT_FROM_DATABASE=Option Beemo (GI0801) LTE surfstick
+
+usb:v106Cp3B14*
+ ID_PRODUCT_FROM_DATABASE=Option Beemo (GI0801) LTE surfstick
+
+usb:v106Cp3EB4*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp4101*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp4102*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp4301*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v106Cp4302*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp4401*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v106Cp4402*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp4501*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp4502*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp4601*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v106Cp4602*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp5101*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp5102*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp5301*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp5302*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp5401*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp5402*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp5501*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp5502*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp5601*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106Cp5602*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106Cp7101*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v106Cp7102*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106CpA000*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106CpA001*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106CpC100*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106CpC200*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106CpC500*
+ ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM)
+
+usb:v106CpE200*
+ ID_PRODUCT_FROM_DATABASE=Packet Service
+
+usb:v106D*
+ ID_VENDOR_FROM_DATABASE=San Chieh Manufacturing, Ltd
+
+usb:v106E*
+ ID_VENDOR_FROM_DATABASE=ConectL
+
+usb:v106F*
+ ID_VENDOR_FROM_DATABASE=Money Controls
+
+usb:v106Fp0009*
+ ID_PRODUCT_FROM_DATABASE=CT10x Coin Transaction
+
+usb:v106Fp000A*
+ ID_PRODUCT_FROM_DATABASE=CR10x Coin Recycler
+
+usb:v1076*
+ ID_VENDOR_FROM_DATABASE=GCT Semiconductor, Inc.
+
+usb:v1076p0031*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v1076p0032*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v107B*
+ ID_VENDOR_FROM_DATABASE=Gateway, Inc.
+
+usb:v107Bp3009*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v107Bp55B2*
+ ID_PRODUCT_FROM_DATABASE=WBU-110 802.11b Wireless Adapter [Intersil PRISM 3]
+
+usb:v107Bp55F2*
+ ID_PRODUCT_FROM_DATABASE=WGU-210 802.11g Adapter [Intersil ISL3886]
+
+usb:v107D*
+ ID_VENDOR_FROM_DATABASE=Arlec Australia, Ltd
+
+usb:v107E*
+ ID_VENDOR_FROM_DATABASE=Midoriya Electric Co., Ltd
+
+usb:v107F*
+ ID_VENDOR_FROM_DATABASE=KidzMouse, Inc.
+
+usb:v1082*
+ ID_VENDOR_FROM_DATABASE=Shin-Etsukaken Co., Ltd
+
+usb:v1083*
+ ID_VENDOR_FROM_DATABASE=Canon Electronics, Inc.
+
+usb:v1083p162C*
+ ID_PRODUCT_FROM_DATABASE=P-150 Scanner
+
+usb:v1084*
+ ID_VENDOR_FROM_DATABASE=Pantech Co., Ltd
+
+usb:v108A*
+ ID_VENDOR_FROM_DATABASE=Chloride Power Protection
+
+usb:v108B*
+ ID_VENDOR_FROM_DATABASE=Grand-tek Technology Co., Ltd
+
+usb:v108C*
+ ID_VENDOR_FROM_DATABASE=Robert Bosch GmbH
+
+usb:v108E*
+ ID_VENDOR_FROM_DATABASE=Lotes Co., Ltd.
+
+usb:v1099*
+ ID_VENDOR_FROM_DATABASE=Surface Optics Corp.
+
+usb:v109A*
+ ID_VENDOR_FROM_DATABASE=DATASOFT Systems GmbH
+
+usb:v109F*
+ ID_VENDOR_FROM_DATABASE=eSOL Co., Ltd
+
+usb:v109Fp3163*
+ ID_PRODUCT_FROM_DATABASE=Trigem Mobile SmartDisplay84
+
+usb:v109Fp3164*
+ ID_PRODUCT_FROM_DATABASE=Trigem Mobile SmartDisplay121
+
+usb:v10A0*
+ ID_VENDOR_FROM_DATABASE=Hirotech, Inc.
+
+usb:v10A3*
+ ID_VENDOR_FROM_DATABASE=Mitsubishi Materials Corp.
+
+usb:v10A9*
+ ID_VENDOR_FROM_DATABASE=SK Teletech Co., Ltd
+
+usb:v10A9p1102*
+ ID_PRODUCT_FROM_DATABASE=Sky Love Actually IM-U460K
+
+usb:v10A9p1104*
+ ID_PRODUCT_FROM_DATABASE=Sky Vega IM-A650S
+
+usb:v10A9p6021*
+ ID_PRODUCT_FROM_DATABASE=SIRIUS alpha
+
+usb:v10AA*
+ ID_VENDOR_FROM_DATABASE=Cables To Go
+
+usb:v10AB*
+ ID_VENDOR_FROM_DATABASE=USI Co., Ltd
+
+usb:v10ABp1002*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v10ABp1003*
+ ID_PRODUCT_FROM_DATABASE=BC02-EXT in DFU
+
+usb:v10ABp1005*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adptr
+
+usb:v10ABp1006*
+ ID_PRODUCT_FROM_DATABASE=BC04-EXT in DFU
+
+usb:v10ABp10C5*
+ ID_PRODUCT_FROM_DATABASE=Sony-Ericsson / Samsung DataCable
+
+usb:v10AC*
+ ID_VENDOR_FROM_DATABASE=Honeywell, Inc.
+
+usb:v10AE*
+ ID_VENDOR_FROM_DATABASE=Princeton Technology Corp.
+
+usb:v10AF*
+ ID_VENDOR_FROM_DATABASE=Liebert Corp.
+
+usb:v10AFp0000*
+ ID_PRODUCT_FROM_DATABASE=UPS
+
+usb:v10AFp0001*
+ ID_PRODUCT_FROM_DATABASE=PowerSure PSA UPS
+
+usb:v10AFp0002*
+ ID_PRODUCT_FROM_DATABASE=PowerSure PST UPS
+
+usb:v10AFp0003*
+ ID_PRODUCT_FROM_DATABASE=PowerSure PSP UPS
+
+usb:v10AFp0004*
+ ID_PRODUCT_FROM_DATABASE=PowerSure PSI UPS
+
+usb:v10AFp0005*
+ ID_PRODUCT_FROM_DATABASE=UPStation GXT 2U UPS
+
+usb:v10AFp0006*
+ ID_PRODUCT_FROM_DATABASE=UPStation GXT UPS
+
+usb:v10AFp0007*
+ ID_PRODUCT_FROM_DATABASE=Nfinity Power Systems UPS
+
+usb:v10AFp0008*
+ ID_PRODUCT_FROM_DATABASE=PowerSure Interactive UPS
+
+usb:v10B5*
+ ID_VENDOR_FROM_DATABASE=Comodo (PLX?)
+
+usb:v10B5p9060*
+ ID_PRODUCT_FROM_DATABASE=Test Board
+
+usb:v10B8*
+ ID_VENDOR_FROM_DATABASE=DiBcom
+
+usb:v10B8p0BB8*
+ ID_PRODUCT_FROM_DATABASE=DiBcom USB DVB-T reference design (MOD300) (cold)
+
+usb:v10B8p0BB9*
+ ID_PRODUCT_FROM_DATABASE=DiBcom USB DVB-T reference design (MOD300) (warm)
+
+usb:v10B8p0BC6*
+ ID_PRODUCT_FROM_DATABASE=DiBcom USB2.0 DVB-T reference design (MOD3000P) (cold)
+
+usb:v10B8p0BC7*
+ ID_PRODUCT_FROM_DATABASE=DiBcom USB2.0 DVB-T reference design (MOD3000P) (warm)
+
+usb:v10BB*
+ ID_VENDOR_FROM_DATABASE=TM Technology, Inc.
+
+usb:v10BC*
+ ID_VENDOR_FROM_DATABASE=Dinging Technology Co., Ltd
+
+usb:v10BD*
+ ID_VENDOR_FROM_DATABASE=TMT Technology, Inc.
+
+usb:v10BDp1427*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v10BF*
+ ID_VENDOR_FROM_DATABASE=SmartHome
+
+usb:v10BFp0001*
+ ID_PRODUCT_FROM_DATABASE=SmartHome PowerLinc
+
+usb:v10C4*
+ ID_VENDOR_FROM_DATABASE=Cygnal Integrated Products, Inc.
+
+usb:v10C4p0002*
+ ID_PRODUCT_FROM_DATABASE=F32x USBXpress Device
+
+usb:v10C4p0003*
+ ID_PRODUCT_FROM_DATABASE=CommandIR
+
+usb:v10C4p8030*
+ ID_PRODUCT_FROM_DATABASE=K4JRG Ham Radio devices
+
+usb:v10C4p8044*
+ ID_PRODUCT_FROM_DATABASE=USB Debug Adapter
+
+usb:v10C4p804E*
+ ID_PRODUCT_FROM_DATABASE=Software Bisque Paramount ME
+
+usb:v10C4p80A9*
+ ID_PRODUCT_FROM_DATABASE=CP210x to UART Bridge Controller
+
+usb:v10C4p80CA*
+ ID_PRODUCT_FROM_DATABASE=ATM2400 Sensor Device
+
+usb:v10C4p813F*
+ ID_PRODUCT_FROM_DATABASE=tams EasyControl
+
+usb:v10C4p8149*
+ ID_PRODUCT_FROM_DATABASE=West Mountain Radio Computerized Battery Analyzer
+
+usb:v10C4p814A*
+ ID_PRODUCT_FROM_DATABASE=West Mountain Radio RIGblaster P&P
+
+usb:v10C4p814B*
+ ID_PRODUCT_FROM_DATABASE=West Mountain Radio RIGtalk
+
+usb:v10C4p818A*
+ ID_PRODUCT_FROM_DATABASE=Silicon Labs FM Radio Reference Design
+
+usb:v10C4p81E8*
+ ID_PRODUCT_FROM_DATABASE=Zephyr BioHarness
+
+usb:v10C4p8460*
+ ID_PRODUCT_FROM_DATABASE=Sangoma Wanpipe VoiceTime
+
+usb:v10C4p8461*
+ ID_PRODUCT_FROM_DATABASE=Sangoma U100
+
+usb:v10C4p8477*
+ ID_PRODUCT_FROM_DATABASE=Balluff RFID Reader
+
+usb:v10C4p8605*
+ ID_PRODUCT_FROM_DATABASE=dilitronics ESoLUX solar lighting controller
+
+usb:v10C4p86BC*
+ ID_PRODUCT_FROM_DATABASE=C8051F34x AudioDelay [AD-340]
+
+usb:v10C4p8789*
+ ID_PRODUCT_FROM_DATABASE=C8051F34x Extender & EDID MGR [EMX-DVI]
+
+usb:v10C4p87BE*
+ ID_PRODUCT_FROM_DATABASE=C8051F34x HDMI Audio Extractor [EMX-HD-AUD]
+
+usb:v10C4pEA60*
+ ID_PRODUCT_FROM_DATABASE=CP210x UART Bridge / myAVR mySmartUSB light
+
+usb:v10C4pEA61*
+ ID_PRODUCT_FROM_DATABASE=CP210x UART Bridge
+
+usb:v10C4pEA70*
+ ID_PRODUCT_FROM_DATABASE=CP210x UART Bridge
+
+usb:v10C4pEA80*
+ ID_PRODUCT_FROM_DATABASE=CP210x UART Bridge
+
+usb:v10C5*
+ ID_VENDOR_FROM_DATABASE=Sanei Electric, Inc.
+
+usb:v10C5p819A*
+ ID_PRODUCT_FROM_DATABASE=FM Radio
+
+usb:v10C6*
+ ID_VENDOR_FROM_DATABASE=Intec, Inc.
+
+usb:v10CB*
+ ID_VENDOR_FROM_DATABASE=Eratech
+
+usb:v10CC*
+ ID_VENDOR_FROM_DATABASE=GBM Connector Co., Ltd
+
+usb:v10CCp1101*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v10CD*
+ ID_VENDOR_FROM_DATABASE=Kycon, Inc.
+
+usb:v10CE*
+ ID_VENDOR_FROM_DATABASE=Silicon Labs
+
+usb:v10CEpEA6A*
+ ID_PRODUCT_FROM_DATABASE=MobiData EDGE USB Modem
+
+usb:v10CF*
+ ID_VENDOR_FROM_DATABASE=Velleman Components, Inc.
+
+usb:v10CFp2011*
+ ID_PRODUCT_FROM_DATABASE=R-Engine MPEG2 encoder/decoder
+
+usb:v10CFp5500*
+ ID_PRODUCT_FROM_DATABASE=8055 Experiment Interface Board (address=0)
+
+usb:v10CFp5501*
+ ID_PRODUCT_FROM_DATABASE=8055 Experiment Interface Board (address=1)
+
+usb:v10CFp5502*
+ ID_PRODUCT_FROM_DATABASE=8055 Experiment Interface Board (address=2)
+
+usb:v10CFp5503*
+ ID_PRODUCT_FROM_DATABASE=8055 Experiment Interface Board (address=3)
+
+usb:v10D1*
+ ID_VENDOR_FROM_DATABASE=Hottinger Baldwin Measurement
+
+usb:v10D1p0101*
+ ID_PRODUCT_FROM_DATABASE=USB-Module for Spider8, CP32
+
+usb:v10D1p0202*
+ ID_PRODUCT_FROM_DATABASE=CP22 - Communication Processor
+
+usb:v10D1p0301*
+ ID_PRODUCT_FROM_DATABASE=CP42 - Communication Processor
+
+usb:v10D4*
+ ID_VENDOR_FROM_DATABASE=Man Boon Manufactory, Ltd
+
+usb:v10D5*
+ ID_VENDOR_FROM_DATABASE=Uni Class Technology Co., Ltd
+
+usb:v10D5p5552*
+ ID_PRODUCT_FROM_DATABASE=KVM Human Interface Composite Device (Keyboard/Mouse ports)
+
+usb:v10D5p55A2*
+ ID_PRODUCT_FROM_DATABASE=2Port KVMSwitcher
+
+usb:v10D6*
+ ID_VENDOR_FROM_DATABASE=Actions Semiconductor Co., Ltd
+
+usb:v10D6p1000*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v10D6p1100*
+ ID_PRODUCT_FROM_DATABASE=MPMan MP-Ki 128 MP3 Player/Recorder
+
+usb:v10D6p1101*
+ ID_PRODUCT_FROM_DATABASE=D-Wave 2GB MP4 Player / AK1025 MP3/MP4 Player
+
+usb:v10D6p2200*
+ ID_PRODUCT_FROM_DATABASE=Acer MP-120 MP3 player
+
+usb:v10D6p8888*
+ ID_PRODUCT_FROM_DATABASE=ADFU Device
+
+usb:v10D6pFF51*
+ ID_PRODUCT_FROM_DATABASE=ADFU Device
+
+usb:v10D6pFF61*
+ ID_PRODUCT_FROM_DATABASE=MP4 Player
+
+usb:v10D6pFF66*
+ ID_PRODUCT_FROM_DATABASE=Craig 2GB MP3/Video Player
+
+usb:v10DE*
+ ID_VENDOR_FROM_DATABASE=Authenex, Inc.
+
+usb:v10DF*
+ ID_VENDOR_FROM_DATABASE=In-Win Development, Inc.
+
+usb:v10DFp0500*
+ ID_PRODUCT_FROM_DATABASE=iAPP CR-e500 Card reader
+
+usb:v10E0*
+ ID_VENDOR_FROM_DATABASE=Post-Op Video, Inc.
+
+usb:v10E1*
+ ID_VENDOR_FROM_DATABASE=CablePlus, Ltd
+
+usb:v10E2*
+ ID_VENDOR_FROM_DATABASE=Nada Electronics, Ltd
+
+usb:v10EC*
+ ID_VENDOR_FROM_DATABASE=Vast Technologies, Inc.
+
+usb:v10F0*
+ ID_VENDOR_FROM_DATABASE=Nexio Co., Ltd
+
+usb:v10F0p2002*
+ ID_PRODUCT_FROM_DATABASE=iNexio Touchscreen controller
+
+usb:v10F1*
+ ID_VENDOR_FROM_DATABASE=Importek
+
+usb:v10F1p1A08*
+ ID_PRODUCT_FROM_DATABASE=Internal Webcam
+
+usb:v10F1p1A1E*
+ ID_PRODUCT_FROM_DATABASE=Laptop Integrated Webcam 1.3M
+
+usb:v10F1p1A2A*
+ ID_PRODUCT_FROM_DATABASE=Laptop Integrated Webcam
+
+usb:v10F5*
+ ID_VENDOR_FROM_DATABASE=Turtle Beach
+
+usb:v10F5p0200*
+ ID_PRODUCT_FROM_DATABASE=Audio Advantage Roadie
+
+usb:v10FB*
+ ID_VENDOR_FROM_DATABASE=Pictos Technologies, Inc.
+
+usb:v10FD*
+ ID_VENDOR_FROM_DATABASE=Anubis Electronics, Ltd
+
+usb:v10FDp7E50*
+ ID_PRODUCT_FROM_DATABASE=FlyCam Usb 100
+
+usb:v10FDp804D*
+ ID_PRODUCT_FROM_DATABASE=Typhoon Webshot II Webcam [zc0301]
+
+usb:v10FDp8050*
+ ID_PRODUCT_FROM_DATABASE=FlyCAM-USB 300 XP2
+
+usb:v10FDpDE00*
+ ID_PRODUCT_FROM_DATABASE=WinFast WalkieTV WDM Capture Driver.
+
+usb:v10FE*
+ ID_VENDOR_FROM_DATABASE=Thrane & Thrane
+
+usb:v10FEp000C*
+ ID_PRODUCT_FROM_DATABASE=TT-3750 BGAN-XL Radio Module
+
+usb:v1100*
+ ID_VENDOR_FROM_DATABASE=VirTouch, Ltd
+
+usb:v1100p0001*
+ ID_PRODUCT_FROM_DATABASE=VTPlayer VTP-1 Braille Mouse
+
+usb:v1101*
+ ID_VENDOR_FROM_DATABASE=EasyPass Industrial Co., Ltd
+
+usb:v1101p0001*
+ ID_PRODUCT_FROM_DATABASE=FSK Electronics Super GSM Reader
+
+usb:v1108*
+ ID_VENDOR_FROM_DATABASE=Brightcom Technologies, Ltd
+
+usb:v110A*
+ ID_VENDOR_FROM_DATABASE=Moxa Technologies Co., Ltd.
+
+usb:v110Ap1250*
+ ID_PRODUCT_FROM_DATABASE=UPort 1250 2-Port RS-232/422/485
+
+usb:v110Ap1251*
+ ID_PRODUCT_FROM_DATABASE=UPort 1250I 2-Port RS-232/422/485 with Isolation
+
+usb:v110Ap1410*
+ ID_PRODUCT_FROM_DATABASE=UPort 1410 4-Port RS-232
+
+usb:v110Ap1450*
+ ID_PRODUCT_FROM_DATABASE=UPort 1450 4-Port RS-232/422/485
+
+usb:v110Ap1451*
+ ID_PRODUCT_FROM_DATABASE=UPort 1450I 4-Port RS-232/422/485 with Isolation
+
+usb:v110Ap1613*
+ ID_PRODUCT_FROM_DATABASE=UPort 1610-16 16-Port RS-232
+
+usb:v110Ap1618*
+ ID_PRODUCT_FROM_DATABASE=UPort 1610-8 8-Port RS-232
+
+usb:v110Ap1653*
+ ID_PRODUCT_FROM_DATABASE=UPort 1650-16 16-Port RS-232/422/485
+
+usb:v110Ap1658*
+ ID_PRODUCT_FROM_DATABASE=UPort 1650-8 8-Port RS-232/422/485
+
+usb:v1110*
+ ID_VENDOR_FROM_DATABASE=Analog Devices Canada, Ltd (Allied Telesyn)
+
+usb:v1110p5C01*
+ ID_PRODUCT_FROM_DATABASE=Huawei MT-882 Remote NDIS Network Device
+
+usb:v1110p6489*
+ ID_PRODUCT_FROM_DATABASE=ADSL ETH/USB RTR
+
+usb:v1110p9000*
+ ID_PRODUCT_FROM_DATABASE=ADSL LAN Adapter
+
+usb:v1110p9001*
+ ID_PRODUCT_FROM_DATABASE=ADSL Loader
+
+usb:v1110p900F*
+ ID_PRODUCT_FROM_DATABASE=AT-AR215 DSL Modem
+
+usb:v1110p9010*
+ ID_PRODUCT_FROM_DATABASE=AT-AR215 DSL Modem
+
+usb:v1110p9021*
+ ID_PRODUCT_FROM_DATABASE=ADSL WAN Adapter
+
+usb:v1110p9022*
+ ID_PRODUCT_FROM_DATABASE=ADSL Loader
+
+usb:v1110p9023*
+ ID_PRODUCT_FROM_DATABASE=ADSL WAN Adapter
+
+usb:v1110p9024*
+ ID_PRODUCT_FROM_DATABASE=ADSL Loader
+
+usb:v1110p9031*
+ ID_PRODUCT_FROM_DATABASE=ADSL LAN Adapter
+
+usb:v1110p9032*
+ ID_PRODUCT_FROM_DATABASE=ADSL Loader
+
+usb:v1111*
+ ID_VENDOR_FROM_DATABASE=Pandora International Ltd.
+
+usb:v1111p8888*
+ ID_PRODUCT_FROM_DATABASE=Evolution Device
+
+usb:v1112*
+ ID_VENDOR_FROM_DATABASE=YM ELECTRIC CO., Ltd
+
+usb:v1113*
+ ID_VENDOR_FROM_DATABASE=Medion AG
+
+usb:v1113pA0A2*
+ ID_PRODUCT_FROM_DATABASE=Active Sync device
+
+usb:v111E*
+ ID_VENDOR_FROM_DATABASE=VSO Electric Co., Ltd
+
+usb:v112A*
+ ID_VENDOR_FROM_DATABASE=RedRat
+
+usb:v112Ap0001*
+ ID_PRODUCT_FROM_DATABASE=RedRat3 IR Transceiver
+
+usb:v112Ap0005*
+ ID_PRODUCT_FROM_DATABASE=RedRat3II IR Transceiver
+
+usb:v112E*
+ ID_VENDOR_FROM_DATABASE=Master Hill Electric Wire and Cable Co., Ltd
+
+usb:v112F*
+ ID_VENDOR_FROM_DATABASE=Cellon International, Inc.
+
+usb:v1130*
+ ID_VENDOR_FROM_DATABASE=Tenx Technology, Inc.
+
+usb:v1130p0002*
+ ID_PRODUCT_FROM_DATABASE=iBuddy
+
+usb:v1130p0202*
+ ID_PRODUCT_FROM_DATABASE=Rocket Launcher
+
+usb:v1130p6604*
+ ID_PRODUCT_FROM_DATABASE=MCE IR-Receiver
+
+usb:v1130p660C*
+ ID_PRODUCT_FROM_DATABASE=Foot Pedal/Thermometer
+
+usb:v1130p6806*
+ ID_PRODUCT_FROM_DATABASE=Keychain photo frame
+
+usb:v1130pF211*
+ ID_PRODUCT_FROM_DATABASE=TP6911 Audio Headset
+
+usb:v1131*
+ ID_VENDOR_FROM_DATABASE=Integrated System Solution Corp.
+
+usb:v1131p1001*
+ ID_PRODUCT_FROM_DATABASE=KY-BT100 Bluetooth Adapter
+
+usb:v1131p1002*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v1131p1003*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v1131p1004*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v1132*
+ ID_VENDOR_FROM_DATABASE=Toshiba Corp., Digital Media Equipment [hex]
+
+usb:v1132p4331*
+ ID_PRODUCT_FROM_DATABASE=PDR-M4/M5/M70 Digital Camera
+
+usb:v1132p4332*
+ ID_PRODUCT_FROM_DATABASE=PDR-M60 Digital Camera
+
+usb:v1132p4333*
+ ID_PRODUCT_FROM_DATABASE=PDR-M2300/PDR-M700
+
+usb:v1132p4334*
+ ID_PRODUCT_FROM_DATABASE=PDR-M65
+
+usb:v1132p4335*
+ ID_PRODUCT_FROM_DATABASE=PDR-M61
+
+usb:v1132p4337*
+ ID_PRODUCT_FROM_DATABASE=PDR-M11
+
+usb:v1132p4338*
+ ID_PRODUCT_FROM_DATABASE=PDR-M25
+
+usb:v1136*
+ ID_VENDOR_FROM_DATABASE=CTS Electronincs
+
+usb:v1136p3131*
+ ID_PRODUCT_FROM_DATABASE=CTS LS515
+
+usb:v113C*
+ ID_VENDOR_FROM_DATABASE=Arin Tech Co., Ltd
+
+usb:v113D*
+ ID_VENDOR_FROM_DATABASE=Mapower Electronics Co., Ltd
+
+usb:v1141*
+ ID_VENDOR_FROM_DATABASE=V One Multimedia, Pte., Ltd
+
+usb:v1142*
+ ID_VENDOR_FROM_DATABASE=CyberScan Technologies, Inc.
+
+usb:v1145*
+ ID_VENDOR_FROM_DATABASE=Japan Radio Company
+
+usb:v1145p0001*
+ ID_PRODUCT_FROM_DATABASE=AirH PHONE AH-J3001V/J3002V
+
+usb:v1146*
+ ID_VENDOR_FROM_DATABASE=Shimane SANYO Electric Co., Ltd.
+
+usb:v1147*
+ ID_VENDOR_FROM_DATABASE=Ever Great Electric Wire and Cable Co., Ltd
+
+usb:v114B*
+ ID_VENDOR_FROM_DATABASE=Sphairon Access Systems GmbH
+
+usb:v114Bp0110*
+ ID_PRODUCT_FROM_DATABASE=Turbolink UB801R WLAN Adapter
+
+usb:v114Bp0150*
+ ID_PRODUCT_FROM_DATABASE=Turbolink UB801RE Wireless 802.11g 54Mbps Network Adapter [RTL8187]
+
+usb:v114C*
+ ID_VENDOR_FROM_DATABASE=Tinius Olsen Testing Machine Co., Inc.
+
+usb:v114D*
+ ID_VENDOR_FROM_DATABASE=Alpha Imaging Technology Corp.
+
+usb:v114F*
+ ID_VENDOR_FROM_DATABASE=Wavecom
+
+usb:v115B*
+ ID_VENDOR_FROM_DATABASE=Salix Technology Co., Ltd.
+
+usb:v1162*
+ ID_VENDOR_FROM_DATABASE=Secugen Corp.
+
+usb:v1163*
+ ID_VENDOR_FROM_DATABASE=DeLorme Publishing, Inc.
+
+usb:v1163p0100*
+ ID_PRODUCT_FROM_DATABASE=Earthmate GPS (orig)
+
+usb:v1163p0200*
+ ID_PRODUCT_FROM_DATABASE=Earthmate GPS (LT-20, LT-40)
+
+usb:v1163p2020*
+ ID_PRODUCT_FROM_DATABASE=Earthmate GPS (PN-40)
+
+usb:v1164*
+ ID_VENDOR_FROM_DATABASE=YUAN High-Tech Development Co., Ltd
+
+usb:v1164p0300*
+ ID_PRODUCT_FROM_DATABASE=ELSAVISION 460D
+
+usb:v1164p0601*
+ ID_PRODUCT_FROM_DATABASE=Analog TV Tuner
+
+usb:v1164p0900*
+ ID_PRODUCT_FROM_DATABASE=TigerBird BMP837 USB2.0 WDM Encoder
+
+usb:v1164p0BC7*
+ ID_PRODUCT_FROM_DATABASE=Digital TV Tuner
+
+usb:v1164p521B*
+ ID_PRODUCT_FROM_DATABASE=MC521A mini Card ATSC Tuner
+
+usb:v1164p6601*
+ ID_PRODUCT_FROM_DATABASE=Digital TV Tuner Card [RTL2832U]
+
+usb:v1165*
+ ID_VENDOR_FROM_DATABASE=Telson Electronics Co., Ltd
+
+usb:v1166*
+ ID_VENDOR_FROM_DATABASE=Bantam Interactive Technologies
+
+usb:v1167*
+ ID_VENDOR_FROM_DATABASE=Salient Systems Corp.
+
+usb:v1168*
+ ID_VENDOR_FROM_DATABASE=BizConn International Corp.
+
+usb:v116E*
+ ID_VENDOR_FROM_DATABASE=Gigastorage Corp.
+
+usb:v116F*
+ ID_VENDOR_FROM_DATABASE=Silicon 10 Technology Corp.
+
+usb:v116Fp0005*
+ ID_PRODUCT_FROM_DATABASE=Flash Card Reader
+
+usb:v116FpC108*
+ ID_PRODUCT_FROM_DATABASE=Flash Card Reader
+
+usb:v116FpC109*
+ ID_PRODUCT_FROM_DATABASE=Flash Card Reader
+
+usb:v1175*
+ ID_VENDOR_FROM_DATABASE=Shengyih Steel Mold Co., Ltd
+
+usb:v117D*
+ ID_VENDOR_FROM_DATABASE=Santa Electronic, Inc.
+
+usb:v117E*
+ ID_VENDOR_FROM_DATABASE=JNC, Inc.
+
+usb:v1182*
+ ID_VENDOR_FROM_DATABASE=Venture Corp., Ltd
+
+usb:v1183*
+ ID_VENDOR_FROM_DATABASE=Compaq Computer Corp. [hex] (Digital Dream ??)
+
+usb:v1183p0001*
+ ID_PRODUCT_FROM_DATABASE=DigitalDream l'espion XS
+
+usb:v1183p19C7*
+ ID_PRODUCT_FROM_DATABASE=ISDN TA
+
+usb:v1183p4008*
+ ID_PRODUCT_FROM_DATABASE=56k FaxModem
+
+usb:v1183p504A*
+ ID_PRODUCT_FROM_DATABASE=PJB-100 Personal Jukebox
+
+usb:v1184*
+ ID_VENDOR_FROM_DATABASE=Kyocera Elco Corp.
+
+usb:v1188*
+ ID_VENDOR_FROM_DATABASE=Bloomberg L.P.
+
+usb:v1189*
+ ID_VENDOR_FROM_DATABASE=Acer Communications & Multimedia
+
+usb:v1189p0893*
+ ID_PRODUCT_FROM_DATABASE=EP-1427X-2 Ethernet Adapter [Acer]
+
+usb:v118F*
+ ID_VENDOR_FROM_DATABASE=You Yang Technology Co., Ltd
+
+usb:v1190*
+ ID_VENDOR_FROM_DATABASE=Tripace
+
+usb:v1191*
+ ID_VENDOR_FROM_DATABASE=Loyalty Founder Enterprise Co., Ltd
+
+usb:v1196*
+ ID_VENDOR_FROM_DATABASE=Yankee Robotics, LLC
+
+usb:v1196p0010*
+ ID_PRODUCT_FROM_DATABASE=Trifid Camera without code
+
+usb:v1196p0011*
+ ID_PRODUCT_FROM_DATABASE=Trifid Camera
+
+usb:v1197*
+ ID_VENDOR_FROM_DATABASE=Technoimagia Co., Ltd
+
+usb:v1198*
+ ID_VENDOR_FROM_DATABASE=StarShine Technology Corp.
+
+usb:v1199*
+ ID_VENDOR_FROM_DATABASE=Sierra Wireless, Inc.
+
+usb:v1199p0019*
+ ID_PRODUCT_FROM_DATABASE=AC595U
+
+usb:v1199p0021*
+ ID_PRODUCT_FROM_DATABASE=AC597E
+
+usb:v1199p0024*
+ ID_PRODUCT_FROM_DATABASE=MC5727 CDMA modem
+
+usb:v1199p0110*
+ ID_PRODUCT_FROM_DATABASE=Composite Device
+
+usb:v1199p0112*
+ ID_PRODUCT_FROM_DATABASE=CDMA 1xEVDO PC Card, AirCard 580
+
+usb:v1199p0120*
+ ID_PRODUCT_FROM_DATABASE=AC595U
+
+usb:v1199p0218*
+ ID_PRODUCT_FROM_DATABASE=MC5720 Wireless Modem
+
+usb:v1199p6467*
+ ID_PRODUCT_FROM_DATABASE=MP Series Network Adapter
+
+usb:v1199p6468*
+ ID_PRODUCT_FROM_DATABASE=MP Series Network Adapter
+
+usb:v1199p6469*
+ ID_PRODUCT_FROM_DATABASE=MP Series Network Adapter
+
+usb:v1199p6802*
+ ID_PRODUCT_FROM_DATABASE=MC8755 Device
+
+usb:v1199p6803*
+ ID_PRODUCT_FROM_DATABASE=MC8765 Device
+
+usb:v1199p6804*
+ ID_PRODUCT_FROM_DATABASE=MC8755 Device
+
+usb:v1199p6805*
+ ID_PRODUCT_FROM_DATABASE=MC8765 Device
+
+usb:v1199p6812*
+ ID_PRODUCT_FROM_DATABASE=MC8775 Device
+
+usb:v1199p6820*
+ ID_PRODUCT_FROM_DATABASE=AC875 Device
+
+usb:v1199p6832*
+ ID_PRODUCT_FROM_DATABASE=MC8780 Device
+
+usb:v1199p6833*
+ ID_PRODUCT_FROM_DATABASE=MC8781 Device
+
+usb:v1199p683A*
+ ID_PRODUCT_FROM_DATABASE=MC8785 Device
+
+usb:v1199p683C*
+ ID_PRODUCT_FROM_DATABASE=MC8790 Device
+
+usb:v1199p6850*
+ ID_PRODUCT_FROM_DATABASE=AirCard 880 Device
+
+usb:v1199p6851*
+ ID_PRODUCT_FROM_DATABASE=AirCard 881 Device
+
+usb:v1199p6852*
+ ID_PRODUCT_FROM_DATABASE=AirCard 880E Device
+
+usb:v1199p6853*
+ ID_PRODUCT_FROM_DATABASE=AirCard 881E Device
+
+usb:v1199p6854*
+ ID_PRODUCT_FROM_DATABASE=AirCard 885 Device
+
+usb:v1199p6856*
+ ID_PRODUCT_FROM_DATABASE=ATT "USB Connect 881"
+
+usb:v1199p6870*
+ ID_PRODUCT_FROM_DATABASE=MC8780 Device
+
+usb:v1199p6871*
+ ID_PRODUCT_FROM_DATABASE=MC8781 Device
+
+usb:v1199p6893*
+ ID_PRODUCT_FROM_DATABASE=MC8777 Device
+
+usb:v1199p68A3*
+ ID_PRODUCT_FROM_DATABASE=MC8700 Modem
+
+usb:v1199p68AA*
+ ID_PRODUCT_FROM_DATABASE=4G LTE adapter
+
+usb:v1199p9000*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v1199p9001*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p9002*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p9003*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p9004*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p9005*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p9006*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p9007*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p9008*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p9009*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v1199p900A*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v119A*
+ ID_VENDOR_FROM_DATABASE=ZHAN QI Technology Co., Ltd
+
+usb:v119B*
+ ID_VENDOR_FROM_DATABASE=ruwido austria GmbH
+
+usb:v119Bp0400*
+ ID_PRODUCT_FROM_DATABASE=Infrared Keyboard V2.01
+
+usb:v11A0*
+ ID_VENDOR_FROM_DATABASE=Chipcon AS
+
+usb:v11A0pEB11*
+ ID_PRODUCT_FROM_DATABASE=CC2400EB 2.0 ZigBee Sniffer
+
+usb:v11A3*
+ ID_VENDOR_FROM_DATABASE=Technovas Co., Ltd
+
+usb:v11A3p8031*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v11A3p8032*
+ ID_PRODUCT_FROM_DATABASE=MP3 Player
+
+usb:v11AA*
+ ID_VENDOR_FROM_DATABASE=GlobalMedia Group, LLC
+
+usb:v11AAp1518*
+ ID_PRODUCT_FROM_DATABASE=iREZ K2
+
+usb:v11AB*
+ ID_VENDOR_FROM_DATABASE=Exito Electronics Co., Ltd
+
+usb:v11B0*
+ ID_VENDOR_FROM_DATABASE=ATECH FLASH TECHNOLOGY
+
+usb:v11C5*
+ ID_VENDOR_FROM_DATABASE=Inmax
+
+usb:v11C5p0521*
+ ID_PRODUCT_FROM_DATABASE=IMT-0521 Smartcard Reader
+
+usb:v11DB*
+ ID_VENDOR_FROM_DATABASE=Topfield Co., Ltd.
+
+usb:v11DBp1000*
+ ID_PRODUCT_FROM_DATABASE=PVR
+
+usb:v11DBp1100*
+ ID_PRODUCT_FROM_DATABASE=PVR
+
+usb:v11E6*
+ ID_VENDOR_FROM_DATABASE=K.I. Technology Co. Ltd.
+
+usb:v11F5*
+ ID_VENDOR_FROM_DATABASE=Siemens AG
+
+usb:v11F5p0001*
+ ID_PRODUCT_FROM_DATABASE=SX1
+
+usb:v11F5p0003*
+ ID_PRODUCT_FROM_DATABASE=Mobile phone USB cable
+
+usb:v11F5p0004*
+ ID_PRODUCT_FROM_DATABASE=X75
+
+usb:v11F5p0005*
+ ID_PRODUCT_FROM_DATABASE=SXG75/EF81
+
+usb:v11F5p0008*
+ ID_PRODUCT_FROM_DATABASE=UMTS/HSDPA Data Card
+
+usb:v11F6*
+ ID_VENDOR_FROM_DATABASE=Prolific
+
+usb:v11F6p2001*
+ ID_PRODUCT_FROM_DATABASE=Willcom WSIM
+
+usb:v11F7*
+ ID_VENDOR_FROM_DATABASE=Alcatel (?)
+
+usb:v11F7p02DF*
+ ID_PRODUCT_FROM_DATABASE=TD10 Mobile phone USB cable
+
+usb:v1203*
+ ID_VENDOR_FROM_DATABASE=TSC Auto ID Technology Co., Ltd
+
+usb:v1203p0140*
+ ID_PRODUCT_FROM_DATABASE=TTP-245C
+
+usb:v1209*
+ ID_VENDOR_FROM_DATABASE=InterBiometrics
+
+usb:v1209p1001*
+ ID_PRODUCT_FROM_DATABASE=USB Hub
+
+usb:v1209p1002*
+ ID_PRODUCT_FROM_DATABASE=USB Relais
+
+usb:v1209p1003*
+ ID_PRODUCT_FROM_DATABASE=IBSecureCam-P
+
+usb:v1209p1004*
+ ID_PRODUCT_FROM_DATABASE=IBSecureCam-O
+
+usb:v1209p1005*
+ ID_PRODUCT_FROM_DATABASE=IBSecureCam-N
+
+usb:v120E*
+ ID_VENDOR_FROM_DATABASE=Hudson Soft Co., Ltd
+
+usb:v120F*
+ ID_VENDOR_FROM_DATABASE=Magellan
+
+usb:v120Fp524E*
+ ID_PRODUCT_FROM_DATABASE=RoadMate 1475T
+
+usb:v120Fp5260*
+ ID_PRODUCT_FROM_DATABASE=Triton Handheld GPS Receiver (300/400/500/1500/2000)
+
+usb:v1210*
+ ID_VENDOR_FROM_DATABASE=DigiTech
+
+usb:v1210p001B*
+ ID_PRODUCT_FROM_DATABASE=RP155 Guitar Multi-Effects Processor
+
+usb:v1210p001C*
+ ID_PRODUCT_FROM_DATABASE=RP255 Guitar Multi-Effects Processor
+
+usb:v121E*
+ ID_VENDOR_FROM_DATABASE=Jungsoft Co., Ltd
+
+usb:v121Ep3403*
+ ID_PRODUCT_FROM_DATABASE=Muzio JM250 Audio Player
+
+usb:v1223*
+ ID_VENDOR_FROM_DATABASE=SKYCABLE ENTERPRISE. CO., LTD.
+
+usb:v1230*
+ ID_VENDOR_FROM_DATABASE=Chipidea-Microelectronica, S.A.
+
+usb:v1233*
+ ID_VENDOR_FROM_DATABASE=Denver Electronics
+
+usb:v1233p5677*
+ ID_PRODUCT_FROM_DATABASE=FUSB200 mp3 player
+
+usb:v1234*
+ ID_VENDOR_FROM_DATABASE=Brain Actuated Technologies
+
+usb:v1234p0000*
+ ID_PRODUCT_FROM_DATABASE=Neural Impulse Actuator Prototype 1.0 [NIA]
+
+usb:v1234p4321*
+ ID_PRODUCT_FROM_DATABASE=Human Interface Device
+
+usb:v1234pED02*
+ ID_PRODUCT_FROM_DATABASE=Emotiv EPOC Developer Headset Wireless Dongle
+
+usb:v1235*
+ ID_VENDOR_FROM_DATABASE=Novation EMS
+
+usb:v1235p0001*
+ ID_PRODUCT_FROM_DATABASE=ReMOTE Audio/XStation
+
+usb:v1235p0002*
+ ID_PRODUCT_FROM_DATABASE=Speedio
+
+usb:v1235p0003*
+ ID_PRODUCT_FROM_DATABASE=ReMOTE ZeRO SL
+
+usb:v1235p4661*
+ ID_PRODUCT_FROM_DATABASE=ReMOTE25
+
+usb:v1235p8006*
+ ID_PRODUCT_FROM_DATABASE=Focusrite Scarlett 2i2
+
+usb:v1241*
+ ID_VENDOR_FROM_DATABASE=Belkin
+
+usb:v1241p1111*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v1241p1122*
+ ID_PRODUCT_FROM_DATABASE=Typhoon Stream Optical Mouse USB+PS/2
+
+usb:v1241p1155*
+ ID_PRODUCT_FROM_DATABASE=PS2/USB Browser Combo Mouse
+
+usb:v1241p1166*
+ ID_PRODUCT_FROM_DATABASE=MI-2150 Trust Mouse
+
+usb:v1241p1177*
+ ID_PRODUCT_FROM_DATABASE=F8E842-DL Mouse
+
+usb:v1241p1503*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v1241p1603*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v124A*
+ ID_VENDOR_FROM_DATABASE=AirVast
+
+usb:v124Ap168B*
+ ID_PRODUCT_FROM_DATABASE=PRISM3 WLAN Adapter
+
+usb:v124Ap4017*
+ ID_PRODUCT_FROM_DATABASE=PC-Chips 802.11b Adapter
+
+usb:v124Ap4023*
+ ID_PRODUCT_FROM_DATABASE=WM168g 802.11bg Wireless Adapter [Intersil ISL3886]
+
+usb:v124Ap4025*
+ ID_PRODUCT_FROM_DATABASE=IOGear GWU513 v2 802.11bg Wireless Adapter [Intersil ISL3887]
+
+usb:v124B*
+ ID_VENDOR_FROM_DATABASE=Nyko (Honey Bee)
+
+usb:v124Bp4D01*
+ ID_PRODUCT_FROM_DATABASE=Airflo EX Joystick
+
+usb:v124C*
+ ID_VENDOR_FROM_DATABASE=MXI - Memory Experts International, Inc.
+
+usb:v124Cp3200*
+ ID_PRODUCT_FROM_DATABASE=Stealth MXP 1GB
+
+usb:v125C*
+ ID_VENDOR_FROM_DATABASE=Apogee Inc.
+
+usb:v125Cp0010*
+ ID_PRODUCT_FROM_DATABASE=Alta series CCD
+
+usb:v125F*
+ ID_VENDOR_FROM_DATABASE=A-DATA Technology Co., Ltd.
+
+usb:v125Fp312A*
+ ID_PRODUCT_FROM_DATABASE=Superior S102
+
+usb:v125Fp312B*
+ ID_PRODUCT_FROM_DATABASE=Superior S102 Pro
+
+usb:v125FpA91A*
+ ID_PRODUCT_FROM_DATABASE=Portable HDD CH91
+
+usb:v125FpC08A*
+ ID_PRODUCT_FROM_DATABASE=C008 Flash Drive
+
+usb:v125FpC81A*
+ ID_PRODUCT_FROM_DATABASE=Flash drive
+
+usb:v125FpC93A*
+ ID_PRODUCT_FROM_DATABASE=4GB Pen Drive
+
+usb:v125FpC96A*
+ ID_PRODUCT_FROM_DATABASE=C906 Flash Drive
+
+usb:v1260*
+ ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp.
+
+usb:v1260pEE22*
+ ID_PRODUCT_FROM_DATABASE=SMC2862W-G v3 EZ Connect 802.11g Adapter [Intersil ISL3887]
+
+usb:v1264*
+ ID_VENDOR_FROM_DATABASE=Covidien Energy-based Devices
+
+usb:v1266*
+ ID_VENDOR_FROM_DATABASE=Pirelli Broadband Solutions
+
+usb:v1266p6302*
+ ID_PRODUCT_FROM_DATABASE=Fastweb DRG A226M ADSL Router
+
+usb:v1267*
+ ID_VENDOR_FROM_DATABASE=Logic3 / SpectraVideo plc
+
+usb:v1267p0103*
+ ID_PRODUCT_FROM_DATABASE=G-720 Keyboard
+
+usb:v1267p0201*
+ ID_PRODUCT_FROM_DATABASE=A4Tech SWOP-3 Mouse
+
+usb:v1267p0210*
+ ID_PRODUCT_FROM_DATABASE=LG Optical Mouse 3D-310
+
+usb:v1267pA001*
+ ID_PRODUCT_FROM_DATABASE=JP260 PC Game Pad
+
+usb:v1267pC002*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse
+
+usb:v126C*
+ ID_VENDOR_FROM_DATABASE=Aristocrat Technologies
+
+usb:v126D*
+ ID_VENDOR_FROM_DATABASE=Bel Stewart
+
+usb:v126E*
+ ID_VENDOR_FROM_DATABASE=Strobe Data, Inc.
+
+usb:v126F*
+ ID_VENDOR_FROM_DATABASE=TwinMOS
+
+usb:v126Fp0163*
+ ID_PRODUCT_FROM_DATABASE=Storage device (2gB thumb drive)
+
+usb:v126Fp1325*
+ ID_PRODUCT_FROM_DATABASE=Mobile Disk
+
+usb:v126Fp2168*
+ ID_PRODUCT_FROM_DATABASE=Mobile Disk III
+
+usb:v126FpA006*
+ ID_PRODUCT_FROM_DATABASE=G240 802.11bg
+
+usb:v1274*
+ ID_VENDOR_FROM_DATABASE=Ensoniq
+
+usb:v1275*
+ ID_VENDOR_FROM_DATABASE=Xaxero Marine Software Engineering, Ltd.
+
+usb:v1275p0002*
+ ID_PRODUCT_FROM_DATABASE=WeatherFax 2000 Demodulator
+
+usb:v1275p0080*
+ ID_PRODUCT_FROM_DATABASE=SkyEye Weather Satellite Receiver
+
+usb:v1278*
+ ID_VENDOR_FROM_DATABASE=Starlight Xpress
+
+usb:v1278p0105*
+ ID_PRODUCT_FROM_DATABASE=SXV-M5
+
+usb:v1278p0107*
+ ID_PRODUCT_FROM_DATABASE=SXV-M7
+
+usb:v1278p0109*
+ ID_PRODUCT_FROM_DATABASE=SXV-M9
+
+usb:v1278p0110*
+ ID_PRODUCT_FROM_DATABASE=SXVF-H16
+
+usb:v1278p0115*
+ ID_PRODUCT_FROM_DATABASE=SXVF-H5
+
+usb:v1278p0119*
+ ID_PRODUCT_FROM_DATABASE=SXV-H9
+
+usb:v1278p0135*
+ ID_PRODUCT_FROM_DATABASE=SXVF-H35
+
+usb:v1278p0136*
+ ID_PRODUCT_FROM_DATABASE=SXVF-H36
+
+usb:v1278p0200*
+ ID_PRODUCT_FROM_DATABASE=SXV interface for paraller MX cameras
+
+usb:v1278p0305*
+ ID_PRODUCT_FROM_DATABASE=SXV-M5C
+
+usb:v1278p0307*
+ ID_PRODUCT_FROM_DATABASE=SXV-M7C
+
+usb:v1278p0319*
+ ID_PRODUCT_FROM_DATABASE=SXV-H9C
+
+usb:v1278p0325*
+ ID_PRODUCT_FROM_DATABASE=SXV-M25C
+
+usb:v1278p0326*
+ ID_PRODUCT_FROM_DATABASE=SXVR-M26C
+
+usb:v1278p0507*
+ ID_PRODUCT_FROM_DATABASE=Lodestar autoguider
+
+usb:v1278p0517*
+ ID_PRODUCT_FROM_DATABASE=CoStar
+
+usb:v1283*
+ ID_VENDOR_FROM_DATABASE=zebris Medical GmbH
+
+usb:v1283p0100*
+ ID_PRODUCT_FROM_DATABASE=USB-RS232 Adaptor
+
+usb:v1283p0110*
+ ID_PRODUCT_FROM_DATABASE=CMS20
+
+usb:v1283p0111*
+ ID_PRODUCT_FROM_DATABASE=CMS 10
+
+usb:v1283p0112*
+ ID_PRODUCT_FROM_DATABASE=CMS 05
+
+usb:v1283p0114*
+ ID_PRODUCT_FROM_DATABASE=ARCUS digma PC-Interface
+
+usb:v1283p0115*
+ ID_PRODUCT_FROM_DATABASE=SAM Axioquick recorder
+
+usb:v1283p0116*
+ ID_PRODUCT_FROM_DATABASE=SAM Axioquick recorder
+
+usb:v1283p0120*
+ ID_PRODUCT_FROM_DATABASE=emed-X
+
+usb:v1283p0121*
+ ID_PRODUCT_FROM_DATABASE=emed-AT
+
+usb:v1283p0130*
+ ID_PRODUCT_FROM_DATABASE=PDM
+
+usb:v1283p0150*
+ ID_PRODUCT_FROM_DATABASE=CMS10GI (Golf)
+
+usb:v1286*
+ ID_VENDOR_FROM_DATABASE=Marvell Semiconductor, Inc.
+
+usb:v1286p1FAB*
+ ID_PRODUCT_FROM_DATABASE=88W8338 [Libertas] 802.11g
+
+usb:v1286p2001*
+ ID_PRODUCT_FROM_DATABASE=88W8388 802.11a/b/g WLAN
+
+usb:v1286p2006*
+ ID_PRODUCT_FROM_DATABASE=88W8362 802.11n WLAN
+
+usb:v1286p8001*
+ ID_PRODUCT_FROM_DATABASE=BLOB boot loader firmware
+
+usb:v1291*
+ ID_VENDOR_FROM_DATABASE=Qualcomm Flarion Technologies, Inc. / Leadtek Research, Inc.
+
+usb:v1291p0010*
+ ID_PRODUCT_FROM_DATABASE=FDM 2xxx Flash-OFDM modem
+
+usb:v1291p0011*
+ ID_PRODUCT_FROM_DATABASE=LR7F06/LR7F14 Flash-OFDM modem
+
+usb:v1292*
+ ID_VENDOR_FROM_DATABASE=Innomedia
+
+usb:v1292p0258*
+ ID_PRODUCT_FROM_DATABASE=Creative Labs VoIP Blaster
+
+usb:v1293*
+ ID_VENDOR_FROM_DATABASE=Belkin Components [hex]
+
+usb:v1293p0002*
+ ID_PRODUCT_FROM_DATABASE=F5U002 Parallel Port [uss720]
+
+usb:v1293p2101*
+ ID_PRODUCT_FROM_DATABASE=104-key keyboard
+
+usb:v1294*
+ ID_VENDOR_FROM_DATABASE=RISO KAGAKU CORP.
+
+usb:v129B*
+ ID_VENDOR_FROM_DATABASE=CyberTAN Technology
+
+usb:v129Bp160B*
+ ID_PRODUCT_FROM_DATABASE=Siemens S30853-S1031-R351 802.11g Wireless Adapter [Atheros AR5523]
+
+usb:v129Bp160C*
+ ID_PRODUCT_FROM_DATABASE=Siemens S30853-S1038-R351 802.11g Wireless Adapter [Atheros AR5523]
+
+usb:v129Bp1666*
+ ID_PRODUCT_FROM_DATABASE=TG54USB 802.11bg
+
+usb:v129Bp1667*
+ ID_PRODUCT_FROM_DATABASE=802.11bg
+
+usb:v129Bp1828*
+ ID_PRODUCT_FROM_DATABASE=Gigaset USB Adapter 300
+
+usb:v12A7*
+ ID_VENDOR_FROM_DATABASE=Trendchip Technologies Corp.
+
+usb:v12AB*
+ ID_VENDOR_FROM_DATABASE=Honey Bee Electronic International Ltd.
+
+usb:v12B8*
+ ID_VENDOR_FROM_DATABASE=Zhejiang Xinya Electronic Technology Co., Ltd.
+
+usb:v12BA*
+ ID_VENDOR_FROM_DATABASE=Licensed by Sony Computer Entertainment America
+
+usb:v12BAp0100*
+ ID_PRODUCT_FROM_DATABASE=RedOctane Guitar for PlayStation(R)3
+
+usb:v12BAp0120*
+ ID_PRODUCT_FROM_DATABASE=RedOctane Drum Kit for PlayStation(R)3
+
+usb:v12BAp0200*
+ ID_PRODUCT_FROM_DATABASE=Harmonix Guitar for PlayStation(R)3
+
+usb:v12BAp0210*
+ ID_PRODUCT_FROM_DATABASE=Harmonix Drum Kit for PlayStation(R)3
+
+usb:v12C4*
+ ID_VENDOR_FROM_DATABASE=Autocue Group Ltd
+
+usb:v12C4p0006*
+ ID_PRODUCT_FROM_DATABASE=Teleprompter Two-button Hand Control (v1)
+
+usb:v12C4p0008*
+ ID_PRODUCT_FROM_DATABASE=Teleprompter Foot Control (v1)
+
+usb:v12D1*
+ ID_VENDOR_FROM_DATABASE=Huawei Technologies Co., Ltd.
+
+usb:v12D1p1001*
+ ID_PRODUCT_FROM_DATABASE=E169/E620/E800 HSDPA Modem
+
+usb:v12D1p1003*
+ ID_PRODUCT_FROM_DATABASE=E220 HSDPA Modem / E230/E270/E870 HSDPA/HSUPA Modem
+
+usb:v12D1p1004*
+ ID_PRODUCT_FROM_DATABASE=E220 (bis)
+
+usb:v12D1p1009*
+ ID_PRODUCT_FROM_DATABASE=U120
+
+usb:v12D1p1010*
+ ID_PRODUCT_FROM_DATABASE=ETS2252+ CDMA Fixed Wireless Terminal
+
+usb:v12D1p1021*
+ ID_PRODUCT_FROM_DATABASE=U8520
+
+usb:v12D1p1035*
+ ID_PRODUCT_FROM_DATABASE=U8120
+
+usb:v12D1p1037*
+ ID_PRODUCT_FROM_DATABASE=Ideos
+
+usb:v12D1p1038*
+ ID_PRODUCT_FROM_DATABASE=Ideos (debug mode)
+
+usb:v12D1p1039*
+ ID_PRODUCT_FROM_DATABASE=Ideos (tethering mode)
+
+usb:v12D1p1406*
+ ID_PRODUCT_FROM_DATABASE=E1750
+
+usb:v12D1p140B*
+ ID_PRODUCT_FROM_DATABASE=EC1260 Wireless Data Modem HSD USB Card
+
+usb:v12D1p1436*
+ ID_PRODUCT_FROM_DATABASE=E173 3G Modem (modem-mode)
+
+usb:v12D1p1446*
+ ID_PRODUCT_FROM_DATABASE=E1552/E1800/E173 (HSPA modem)
+
+usb:v12D1p1465*
+ ID_PRODUCT_FROM_DATABASE=K3765 HSPA
+
+usb:v12D1p14C3*
+ ID_PRODUCT_FROM_DATABASE=K5005 Vodafone LTE/UMTS/GSM Modem/Networkcard
+
+usb:v12D1p14C8*
+ ID_PRODUCT_FROM_DATABASE=K5005 Vodafone LTE/UMTS/GSM MOdem/Networkcard
+
+usb:v12D1p14C9*
+ ID_PRODUCT_FROM_DATABASE=K3770 3G Modem
+
+usb:v12D1p14D1*
+ ID_PRODUCT_FROM_DATABASE=K3770 3G Modem (Mass Storage Mode)
+
+usb:v12D1p14F1*
+ ID_PRODUCT_FROM_DATABASE=Gobi 3000 HSPA+ Modem
+
+usb:v12D1p1501*
+ ID_PRODUCT_FROM_DATABASE=Pulse
+
+usb:v12D1p1505*
+ ID_PRODUCT_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard
+
+usb:v12D1p1506*
+ ID_PRODUCT_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard
+
+usb:v12D1p150A*
+ ID_PRODUCT_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard
+
+usb:v12D1p1520*
+ ID_PRODUCT_FROM_DATABASE=K3765 HSPA
+
+usb:v12D1p1521*
+ ID_PRODUCT_FROM_DATABASE=K4505 HSPA+
+
+usb:v12D1p1805*
+ ID_PRODUCT_FROM_DATABASE=AT&T Go Phone U2800A phone
+
+usb:v12D1p1C05*
+ ID_PRODUCT_FROM_DATABASE=E173s 3G broadband stick (modem on)
+
+usb:v12D1p1C0B*
+ ID_PRODUCT_FROM_DATABASE=E173s 3G broadband stick (modem off)
+
+usb:v12D1p1D50*
+ ID_PRODUCT_FROM_DATABASE=ET302s TD-SCDMA/TD-HSDPA Mobile Broadband
+
+usb:v12D1p380B*
+ ID_PRODUCT_FROM_DATABASE=WiMAX USB modem(s)
+
+usb:v12D2*
+ ID_VENDOR_FROM_DATABASE=LINE TECH INDUSTRIAL CO., LTD.
+
+usb:v12D6*
+ ID_VENDOR_FROM_DATABASE=EMS Dr. Thomas Wuensche
+
+usb:v12D6p0444*
+ ID_PRODUCT_FROM_DATABASE=CPC-USB/ARM7
+
+usb:v12D6p0888*
+ ID_PRODUCT_FROM_DATABASE=CPC-USB/M16C
+
+usb:v12D7*
+ ID_VENDOR_FROM_DATABASE=BETTER WIRE FACTORY CO., LTD.
+
+usb:v12E6*
+ ID_VENDOR_FROM_DATABASE=Waldorf Music GmbH
+
+usb:v12E6p0013*
+ ID_PRODUCT_FROM_DATABASE=Blofeld
+
+usb:v12EF*
+ ID_VENDOR_FROM_DATABASE=Tapwave, Inc.
+
+usb:v12EFp0100*
+ ID_PRODUCT_FROM_DATABASE=Tapwave Handheld [Tapwave Zodiac]
+
+usb:v12F5*
+ ID_VENDOR_FROM_DATABASE=Dynamic System Electronics Corp.
+
+usb:v12F7*
+ ID_VENDOR_FROM_DATABASE=Memorex Products, Inc.
+
+usb:v12F7p1A00*
+ ID_PRODUCT_FROM_DATABASE=TD Classic 003B
+
+usb:v12F7p1E23*
+ ID_PRODUCT_FROM_DATABASE=TravelDrive 2007 Flash Drive
+
+usb:v12FD*
+ ID_VENDOR_FROM_DATABASE=AIN Comm. Technology Co., Ltd
+
+usb:v12FDp1001*
+ ID_PRODUCT_FROM_DATABASE=AWU2000b 802.11b Stick
+
+usb:v12FF*
+ ID_VENDOR_FROM_DATABASE=Fascinating Electronics, Inc.
+
+usb:v12FFp0101*
+ ID_PRODUCT_FROM_DATABASE=Advanced RC Servo Controller
+
+usb:v1307*
+ ID_VENDOR_FROM_DATABASE=Transcend Information, Inc.
+
+usb:v1307p0163*
+ ID_PRODUCT_FROM_DATABASE=256MB/512MB/1GB Flash Drive
+
+usb:v1307p0165*
+ ID_PRODUCT_FROM_DATABASE=2GB/4GB Flash Drive
+
+usb:v1307p0190*
+ ID_PRODUCT_FROM_DATABASE=Ut190 8 GB Flash Drive with MicroSD reader
+
+usb:v1307p0310*
+ ID_PRODUCT_FROM_DATABASE=SD/MicroSD CardReader [hama]
+
+usb:v1307p0330*
+ ID_PRODUCT_FROM_DATABASE=63-in-1 Multi-Card Reader/Writer
+
+usb:v1307p0361*
+ ID_PRODUCT_FROM_DATABASE=CR-75: 51-in-1 Card Reader/Writer [Sakar]
+
+usb:v1307p1169*
+ ID_PRODUCT_FROM_DATABASE=TS2GJF210 JetFlash 210 2GB
+
+usb:v1307p1171*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v1308*
+ ID_VENDOR_FROM_DATABASE=Shuttle, Inc.
+
+usb:v1308p0003*
+ ID_PRODUCT_FROM_DATABASE=VFD Module
+
+usb:v1308pC001*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v1310*
+ ID_VENDOR_FROM_DATABASE=Roper
+
+usb:v1310p0001*
+ ID_PRODUCT_FROM_DATABASE=Class 1 Bluetooth Dongle
+
+usb:v1312*
+ ID_VENDOR_FROM_DATABASE=ICS Electronics
+
+usb:v131D*
+ ID_VENDOR_FROM_DATABASE=Natural Point
+
+usb:v131Dp0155*
+ ID_PRODUCT_FROM_DATABASE=TrackIR 3 Pro Head Tracker
+
+usb:v131Dp0156*
+ ID_PRODUCT_FROM_DATABASE=TrackIR 4 Pro Head Tracker
+
+usb:v132A*
+ ID_VENDOR_FROM_DATABASE=Envara Inc.
+
+usb:v132Ap1502*
+ ID_PRODUCT_FROM_DATABASE=WiND 802.11abg / 802.11bg WLAN
+
+usb:v132B*
+ ID_VENDOR_FROM_DATABASE=Konica Minolta
+
+usb:v132Bp0000*
+ ID_PRODUCT_FROM_DATABASE=Dimage A2 Camera
+
+usb:v132Bp0001*
+ ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE A2 (ptp)
+
+usb:v132Bp0003*
+ ID_PRODUCT_FROM_DATABASE=Dimage Xg Camera
+
+usb:v132Bp0006*
+ ID_PRODUCT_FROM_DATABASE=Dimage Z2 Camera
+
+usb:v132Bp0007*
+ ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE Z2 (PictBridge mode)
+
+usb:v132Bp0008*
+ ID_PRODUCT_FROM_DATABASE=Dimage X21 Camera
+
+usb:v132Bp000A*
+ ID_PRODUCT_FROM_DATABASE=Dimage Scan Dual IV AF-3200 (2891)
+
+usb:v132Bp000B*
+ ID_PRODUCT_FROM_DATABASE=Dimage Z10 Camera
+
+usb:v132Bp000D*
+ ID_PRODUCT_FROM_DATABASE=Dimage X50 Camera [storage?]
+
+usb:v132Bp000F*
+ ID_PRODUCT_FROM_DATABASE=Dimage X50 Camera [p2p?]
+
+usb:v132Bp0010*
+ ID_PRODUCT_FROM_DATABASE=Dimage G600 Camera
+
+usb:v132Bp0012*
+ ID_PRODUCT_FROM_DATABASE=Dimage Scan Elite 5400 II (2892)
+
+usb:v132Bp0013*
+ ID_PRODUCT_FROM_DATABASE=Dimage X31 Camera
+
+usb:v132Bp0015*
+ ID_PRODUCT_FROM_DATABASE=Dimage G530 Camera
+
+usb:v132Bp0017*
+ ID_PRODUCT_FROM_DATABASE=Dimage Z3 Camera
+
+usb:v132Bp0018*
+ ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE Z3 (PictBridge mode)
+
+usb:v132Bp0019*
+ ID_PRODUCT_FROM_DATABASE=Dimage A200 Camera
+
+usb:v132Bp0021*
+ ID_PRODUCT_FROM_DATABASE=Dimage Z5 Camera
+
+usb:v132Bp0022*
+ ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE Z5 (PictBridge mode)
+
+usb:v132Bp002C*
+ ID_PRODUCT_FROM_DATABASE=Dynax 5D camera
+
+usb:v132Bp2001*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2400w
+
+usb:v132Bp2004*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 5430DL
+
+usb:v132Bp2005*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2430 DL
+
+usb:v132Bp2029*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 5440DL
+
+usb:v132Bp2030*
+ ID_PRODUCT_FROM_DATABASE=PagePro 1350E(N)
+
+usb:v132Bp2033*
+ ID_PRODUCT_FROM_DATABASE=PagePro 1400W
+
+usb:v132Bp2043*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2530DL
+
+usb:v132Bp2045*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2500W
+
+usb:v132Bp2049*
+ ID_PRODUCT_FROM_DATABASE=Magicolor 2490MF
+
+usb:v1342*
+ ID_VENDOR_FROM_DATABASE=Mobility
+
+usb:v1342p0200*
+ ID_PRODUCT_FROM_DATABASE=EasiDock 200 Hub
+
+usb:v1342p0201*
+ ID_PRODUCT_FROM_DATABASE=EasiDock 200 Keyboard and Mouse Port
+
+usb:v1342p0202*
+ ID_PRODUCT_FROM_DATABASE=EasiDock 200 Serial Port
+
+usb:v1342p0203*
+ ID_PRODUCT_FROM_DATABASE=EasiDock 200 Printer Port
+
+usb:v1342p0204*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v1342p0304*
+ ID_PRODUCT_FROM_DATABASE=EasiDock Ethernet
+
+usb:v1345*
+ ID_VENDOR_FROM_DATABASE=Sino Lite Technology Corp.
+
+usb:v1345p001C*
+ ID_PRODUCT_FROM_DATABASE=Xbox Controller Hub
+
+usb:v1347*
+ ID_VENDOR_FROM_DATABASE=Moravian Instruments
+
+usb:v1347p0400*
+ ID_PRODUCT_FROM_DATABASE=G2CCD USB 1.1 obsolete
+
+usb:v1347p0401*
+ ID_PRODUCT_FROM_DATABASE=G2CCD-S with Sony ICX285 CCD
+
+usb:v1347p0402*
+ ID_PRODUCT_FROM_DATABASE=G2CCD2
+
+usb:v1347p0403*
+ ID_PRODUCT_FROM_DATABASE=G2/G3CCD-I KAI CCD
+
+usb:v1347p0404*
+ ID_PRODUCT_FROM_DATABASE=G2/G3/G4 CCD-F KAF CCD
+
+usb:v1347p0410*
+ ID_PRODUCT_FROM_DATABASE=G1-0400 CCD
+
+usb:v1347p0411*
+ ID_PRODUCT_FROM_DATABASE=G1-0800 CCD
+
+usb:v1347p0412*
+ ID_PRODUCT_FROM_DATABASE=G1-0300 CCD
+
+usb:v1347p0413*
+ ID_PRODUCT_FROM_DATABASE=G1-2000 CCD
+
+usb:v1347p0414*
+ ID_PRODUCT_FROM_DATABASE=G1-1400 CCD
+
+usb:v1348*
+ ID_VENDOR_FROM_DATABASE=Katsuragawa Electric Co., Ltd.
+
+usb:v134C*
+ ID_VENDOR_FROM_DATABASE=PanJit International Inc.
+
+usb:v134Cp0001*
+ ID_PRODUCT_FROM_DATABASE=Touch Panel Controller
+
+usb:v134Cp0002*
+ ID_PRODUCT_FROM_DATABASE=Touch Panel Controller
+
+usb:v134Cp0003*
+ ID_PRODUCT_FROM_DATABASE=Touch Panel Controller
+
+usb:v134Cp0004*
+ ID_PRODUCT_FROM_DATABASE=Touch Panel Controller
+
+usb:v134E*
+ ID_VENDOR_FROM_DATABASE=Digby's Bitpile, Inc. DBA D Bit
+
+usb:v1357*
+ ID_VENDOR_FROM_DATABASE=P&E Microcomputer Systems
+
+usb:v1357p0503*
+ ID_PRODUCT_FROM_DATABASE=USB-ML-12 HCS08/HCS12 Multilink
+
+usb:v1357p0504*
+ ID_PRODUCT_FROM_DATABASE=DEMOJM
+
+usb:v1366*
+ ID_VENDOR_FROM_DATABASE=SEGGER
+
+usb:v1366p0101*
+ ID_PRODUCT_FROM_DATABASE=J-Link ARM
+
+usb:v136B*
+ ID_VENDOR_FROM_DATABASE=STEC
+
+usb:v1370*
+ ID_VENDOR_FROM_DATABASE=Swissbit
+
+usb:v1370p0323*
+ ID_PRODUCT_FROM_DATABASE=Swissmemory cirrusWHITE
+
+usb:v1370p6828*
+ ID_PRODUCT_FROM_DATABASE=Victorinox Flash Drive
+
+usb:v1371*
+ ID_VENDOR_FROM_DATABASE=CNet Technology Inc.
+
+usb:v1371p0001*
+ ID_PRODUCT_FROM_DATABASE=CNUSB-611AR Wireless Adapter-G [AT76C503]
+
+usb:v1371p0002*
+ ID_PRODUCT_FROM_DATABASE=CNUSB-611AR Wireless Adapter-G [AT76C503] (FiberLine WL-240U)
+
+usb:v1371p0013*
+ ID_PRODUCT_FROM_DATABASE=CNUSB-611 Wireless Adapter [AT76C505]
+
+usb:v1371p0014*
+ ID_PRODUCT_FROM_DATABASE=CNUSB-611 Wireless Adapter [AT76C505] (FiberLine WL-240U)
+
+usb:v1371p5743*
+ ID_PRODUCT_FROM_DATABASE=CNUSB-611 (D) Wireless Adapter [AT76C503]
+
+usb:v1371p9022*
+ ID_PRODUCT_FROM_DATABASE=CWD-854 [RT2573]
+
+usb:v1371p9032*
+ ID_PRODUCT_FROM_DATABASE=CWD-854 rev F
+
+usb:v1371p9401*
+ ID_PRODUCT_FROM_DATABASE=CWD-854 Wireless 802.11g 54Mbps Network Adapter [RTL8187]
+
+usb:v1376*
+ ID_VENDOR_FROM_DATABASE=Vimtron Electronics Co., Ltd.
+
+usb:v137B*
+ ID_VENDOR_FROM_DATABASE=SCAPS GmbH
+
+usb:v137Bp0002*
+ ID_PRODUCT_FROM_DATABASE=SCAPS USC-2 Scanner Controller
+
+usb:v1385*
+ ID_VENDOR_FROM_DATABASE=Netgear, Inc
+
+usb:v1385p4250*
+ ID_PRODUCT_FROM_DATABASE=WG111T
+
+usb:v1385p4251*
+ ID_PRODUCT_FROM_DATABASE=WG111T (no firmware)
+
+usb:v1385p5F00*
+ ID_PRODUCT_FROM_DATABASE=WPN111 RangeMax(TM) Wireless USB 2.0 Adapter
+
+usb:v1385p5F01*
+ ID_PRODUCT_FROM_DATABASE=WPN111 (no firmware)
+
+usb:v1385p5F02*
+ ID_PRODUCT_FROM_DATABASE=WPN111 (no firmware)
+
+usb:v1385p6E00*
+ ID_PRODUCT_FROM_DATABASE=WPNT121 802.11g 240Mbps Wireless Adapter [Airgo AGN300]
+
+usb:v138A*
+ ID_VENDOR_FROM_DATABASE=Validity Sensors, Inc.
+
+usb:v138Ap0001*
+ ID_PRODUCT_FROM_DATABASE=VFS101 Fingerprint Reader
+
+usb:v138Ap0005*
+ ID_PRODUCT_FROM_DATABASE=VFS301 Fingerprint Reader
+
+usb:v138Ap0007*
+ ID_PRODUCT_FROM_DATABASE=VFS451 Fingerprint Reader
+
+usb:v138Ap0008*
+ ID_PRODUCT_FROM_DATABASE=VFS300 Fingerprint Reader
+
+usb:v138Ap0011*
+ ID_PRODUCT_FROM_DATABASE=VFS5011 Fingerprint Reader
+
+usb:v138Ap003C*
+ ID_PRODUCT_FROM_DATABASE=VFS471 Fingerprint Reader
+
+usb:v138E*
+ ID_VENDOR_FROM_DATABASE=Jungo LTD
+
+usb:v138Ep9000*
+ ID_PRODUCT_FROM_DATABASE=Raisonance S.A. STM32 ARM evaluation board
+
+usb:v1390*
+ ID_VENDOR_FROM_DATABASE=TOMTOM B.V.
+
+usb:v1390p0001*
+ ID_PRODUCT_FROM_DATABASE=GO 520 T/GO 630/ONE XL (v9)
+
+usb:v1391*
+ ID_VENDOR_FROM_DATABASE=IdealTEK, Inc.
+
+usb:v1391p1000*
+ ID_PRODUCT_FROM_DATABASE=URTC-1000
+
+usb:v1395*
+ ID_VENDOR_FROM_DATABASE=Sennheiser Communications
+
+usb:v1395p3556*
+ ID_PRODUCT_FROM_DATABASE=USB Headset
+
+usb:v1397*
+ ID_VENDOR_FROM_DATABASE=BEHRINGER International GmbH
+
+usb:v1397p00BC*
+ ID_PRODUCT_FROM_DATABASE=BCF2000
+
+usb:v1398*
+ ID_VENDOR_FROM_DATABASE=Q-tec
+
+usb:v1398p2103*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Storage Device
+
+usb:v13AD*
+ ID_VENDOR_FROM_DATABASE=Baltech
+
+usb:v13ADp9999*
+ ID_PRODUCT_FROM_DATABASE=Card reader
+
+usb:v13B0*
+ ID_VENDOR_FROM_DATABASE=PerkinElmer Optoelectronics
+
+usb:v13B0p000A*
+ ID_PRODUCT_FROM_DATABASE=Alesis Photon X25 MIDI Controller
+
+usb:v13B1*
+ ID_VENDOR_FROM_DATABASE=Linksys
+
+usb:v13B1p000A*
+ ID_PRODUCT_FROM_DATABASE=WUSB54G v2 802.11g Adapter [Intersil ISL3887]
+
+usb:v13B1p000B*
+ ID_PRODUCT_FROM_DATABASE=WUSB11 v4.0 802.11b Adapter [ALi M4301]
+
+usb:v13B1p000C*
+ ID_PRODUCT_FROM_DATABASE=WUSB54AG 802.11a/g Adapter [Intersil ISL3887]
+
+usb:v13B1p000D*
+ ID_PRODUCT_FROM_DATABASE=WUSB54G v4 802.11g Adapter [Ralink RT2500USB]
+
+usb:v13B1p000E*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GS v1 802.11g Adapter [Broadcom 4320 USB]
+
+usb:v13B1p0011*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GP v4.0 802.11g Adapter [Ralink RT2500USB]
+
+usb:v13B1p0014*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GS v2 802.11g Adapter [Broadcom 4320 USB]
+
+usb:v13B1p0018*
+ ID_PRODUCT_FROM_DATABASE=USB200M 10/100 Ethernet Adapter
+
+usb:v13B1p001A*
+ ID_PRODUCT_FROM_DATABASE=HU200TS Wireless Adapter
+
+usb:v13B1p001E*
+ ID_PRODUCT_FROM_DATABASE=WUSBF54G 802.11bg
+
+usb:v13B1p0020*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GC v1 802.11g Adapter [Ralink RT73]
+
+usb:v13B1p0022*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GX4 802.11g 240Mbps Wireless Adapter [Airgo AGN300]
+
+usb:v13B1p0023*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GR
+
+usb:v13B1p0024*
+ ID_PRODUCT_FROM_DATABASE=WUSBF54G v1.1 802.11bg
+
+usb:v13B1p0026*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GSC v1 802.11g Adapter [Broadcom 4320 USB]
+
+usb:v13B1p0028*
+ ID_PRODUCT_FROM_DATABASE=WUSB200 802.11g Adapter [Ralink RT2671]
+
+usb:v13B1p0029*
+ ID_PRODUCT_FROM_DATABASE=WUSB300N 802.11bgn Wireless Adapter [Marvell 88W8362+88W8060]
+
+usb:v13B1p002F*
+ ID_PRODUCT_FROM_DATABASE=AE1000 v1 802.11n [Ralink RT3572]
+
+usb:v13B1p0031*
+ ID_PRODUCT_FROM_DATABASE=AM10 v1 802.11n [Ralink RT3072]
+
+usb:v13B1p0039*
+ ID_PRODUCT_FROM_DATABASE=AE1200 802.11bgn Wireless Adapter [Broadcom BCM43235]
+
+usb:v13B1p003A*
+ ID_PRODUCT_FROM_DATABASE=AE2500 802.11abgn Wireless Adapter [Broadcom BCM43236]
+
+usb:v13B1p13B1*
+ ID_PRODUCT_FROM_DATABASE=WUSB200: Wireless-G Business Network Adapter with Rangebooster
+
+usb:v13B2*
+ ID_VENDOR_FROM_DATABASE=Alesis
+
+usb:v13B2p0030*
+ ID_PRODUCT_FROM_DATABASE=Multimix 8
+
+usb:v13B3*
+ ID_VENDOR_FROM_DATABASE=Nippon Dics Co., Ltd.
+
+usb:v13BA*
+ ID_VENDOR_FROM_DATABASE=PCPlay
+
+usb:v13BAp0017*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard+Mouse Adapter
+
+usb:v13BAp0018*
+ ID_PRODUCT_FROM_DATABASE=Barcode PCP-BCG4209
+
+usb:v13BE*
+ ID_VENDOR_FROM_DATABASE=Ricoh Printing Systems, Ltd.
+
+usb:v13CA*
+ ID_VENDOR_FROM_DATABASE=JyeTai Precision Industrial Co., Ltd.
+
+usb:v13CF*
+ ID_VENDOR_FROM_DATABASE=Wisair Ltd.
+
+usb:v13CFp1200*
+ ID_PRODUCT_FROM_DATABASE=Olidata Wireless Multimedia Adapter
+
+usb:v13D0*
+ ID_VENDOR_FROM_DATABASE=Techsan Electronics Co., Ltd.
+
+usb:v13D0p2282*
+ ID_PRODUCT_FROM_DATABASE=TechniSat DVB-PC TV Star 2
+
+usb:v13D1*
+ ID_VENDOR_FROM_DATABASE=A-Max Technology Macao Commercial Offshore Co. Ltd.
+
+usb:v13D1p7019*
+ ID_PRODUCT_FROM_DATABASE=MD 82288
+
+usb:v13D1pABE6*
+ ID_PRODUCT_FROM_DATABASE=Wireless 802.11g 54Mbps Network Adapter [RTL8187]
+
+usb:v13D2*
+ ID_VENDOR_FROM_DATABASE=Shark Multimedia
+
+usb:v13D2p0400*
+ ID_PRODUCT_FROM_DATABASE=Pocket Ethernet [klsi]
+
+usb:v13D3*
+ ID_VENDOR_FROM_DATABASE=IMC Networks
+
+usb:v13D3p3201*
+ ID_PRODUCT_FROM_DATABASE=VisionDTV USB-Ter/HAMA USB DVB-T device cold
+
+usb:v13D3p3202*
+ ID_PRODUCT_FROM_DATABASE=VisionDTV USB-Ter/HAMA USB DVB-T device warm
+
+usb:v13D3p3203*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+
+usb:v13D3p3204*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+
+usb:v13D3p3205*
+ ID_PRODUCT_FROM_DATABASE=DNTV Live! Tiny USB2 BDA (No Remote)
+
+usb:v13D3p3206*
+ ID_PRODUCT_FROM_DATABASE=DNTV Live! Tiny USB2 BDA (No Remote)
+
+usb:v13D3p3207*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+
+usb:v13D3p3208*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+
+usb:v13D3p3209*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7022BDA DVB-S Box(Without HID)
+
+usb:v13D3p3211*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB Hybrid Analog/Capture / Pinnacle PCTV 310e
+
+usb:v13D3p3212*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT704C - DVBT/NTSC/PAL Driver(PCM4)
+
+usb:v13D3p3213*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT704D - DVBT/NTSC/PAL Driver (PCM4)
+
+usb:v13D3p3214*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT704F -(MiniCard) DVBT/NTSC/PAL Driver(Without HID)
+
+usb:v13D3p3215*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDAT7240 - ATSC/NTSC/PAL Driver(PCM4)
+
+usb:v13D3p3216*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 7047-USB 2.0 DVB-T Driver
+
+usb:v13D3p3217*
+ ID_PRODUCT_FROM_DATABASE=Digital-TV Receiver.
+
+usb:v13D3p3219*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT7049 - DVB-T Driver(Without HID)
+
+usb:v13D3p3220*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 7047M-USB 2.0 DVB-T Driver
+
+usb:v13D3p3223*
+ ID_PRODUCT_FROM_DATABASE=DNTV Live! Tiny USB2 BDA (No Remote)
+
+usb:v13D3p3224*
+ ID_PRODUCT_FROM_DATABASE=DNTV Live! Tiny USB2 BDA (No Remote)
+
+usb:v13D3p3226*
+ ID_PRODUCT_FROM_DATABASE=DigitalNow TinyTwin DVB-T Receiver
+
+usb:v13D3p3234*
+ ID_PRODUCT_FROM_DATABASE=DVB-T FTA Half Minicard [RTL2832U]
+
+usb:v13D3p3236*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 7047A-USB 2.0 DVB-T Driver
+
+usb:v13D3p3237*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 704J - dual DVB-T Driver
+
+usb:v13D3p3239*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT704D - DVBT/NTSC/PAL Driver(Without HID)
+
+usb:v13D3p3240*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDXTTM6010 - A/D Driver(Without HID)
+
+usb:v13D3p3241*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDXTTM6010 - A/D Driver(Without HID)
+
+usb:v13D3p3242*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDAT7240LP - ATSC/NTSC/PAL Driver(Without HID)
+
+usb:v13D3p3243*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDXTTM6010 - A/D Driver(Without HID)
+
+usb:v13D3p3244*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 7047Z-USB 2.0 DVB-T Driver
+
+usb:v13D3p3247*
+ ID_PRODUCT_FROM_DATABASE=802.11 n/g/b Wireless LAN Adapter
+
+usb:v13D3p3249*
+ ID_PRODUCT_FROM_DATABASE=Internal Bluetooth
+
+usb:v13D3p3262*
+ ID_PRODUCT_FROM_DATABASE=802.11 n/g/b Wireless LAN USB Adapter
+
+usb:v13D3p3273*
+ ID_PRODUCT_FROM_DATABASE=802.11 n/g/b Wireless LAN USB Mini-Card
+
+usb:v13D3p3274*
+ ID_PRODUCT_FROM_DATABASE=DVB-T Dongle [RTL2832U]
+
+usb:v13D3p3282*
+ ID_PRODUCT_FROM_DATABASE=DVB-T + GPS Minicard [RTL2832U]
+
+usb:v13D3p3284*
+ ID_PRODUCT_FROM_DATABASE=Wireless LAN USB Mini-Card
+
+usb:v13D3p3304*
+ ID_PRODUCT_FROM_DATABASE=Asus Integrated Bluetooth module [AR3011]
+
+usb:v13D3p3306*
+ ID_PRODUCT_FROM_DATABASE=Mediao 802.11n WLAN [Realtek RTL8191SU]
+
+usb:v13D3p3315*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth module
+
+usb:v13D3p5070*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v13D3p5111*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v13D3p5115*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v13D3p5116*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v13D3p5126*
+ ID_PRODUCT_FROM_DATABASE=PC Cam
+
+usb:v13D3p5702*
+ ID_PRODUCT_FROM_DATABASE=UVC VGA Webcam
+
+usb:v13D3p5716*
+ ID_PRODUCT_FROM_DATABASE=UVC VGA Webcam
+
+usb:v13D3p7020*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+
+usb:v13D3p7022*
+ ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7022BDA DVB-S Box(Without HID)
+
+usb:v13DC*
+ ID_VENDOR_FROM_DATABASE=ALEREON, INC.
+
+usb:v13DD*
+ ID_VENDOR_FROM_DATABASE=i.Tech Dynamic Limited
+
+usb:v13E1*
+ ID_VENDOR_FROM_DATABASE=Kaibo Wire & Cable (Shenzhen) Co., Ltd.
+
+usb:v13E5*
+ ID_VENDOR_FROM_DATABASE=Rane
+
+usb:v13E5p0001*
+ ID_PRODUCT_FROM_DATABASE=SL-1
+
+usb:v13E5p0003*
+ ID_PRODUCT_FROM_DATABASE=TTM 57SL
+
+usb:v13E6*
+ ID_VENDOR_FROM_DATABASE=TechnoScope Co., Ltd.
+
+usb:v13EA*
+ ID_VENDOR_FROM_DATABASE=Hengstler
+
+usb:v13EAp0001*
+ ID_PRODUCT_FROM_DATABASE=C-56 Thermal Printer
+
+usb:v13EC*
+ ID_VENDOR_FROM_DATABASE=Zydacron
+
+usb:v13ECp0006*
+ ID_PRODUCT_FROM_DATABASE=HID Remote Control
+
+usb:v13EE*
+ ID_VENDOR_FROM_DATABASE=MosArt
+
+usb:v13EEp0003*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v13FD*
+ ID_VENDOR_FROM_DATABASE=Initio Corporation
+
+usb:v13FDp0840*
+ ID_PRODUCT_FROM_DATABASE=INIC-1618L SATA
+
+usb:v13FDp0841*
+ ID_PRODUCT_FROM_DATABASE=Samsung SE-T084M DVD-RW
+
+usb:v13FDp1340*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed USB to SATA Bridge
+
+usb:v13FDp160F*
+ ID_PRODUCT_FROM_DATABASE=RocketFish SATA Bridge [INIC-1611]
+
+usb:v13FDp1640*
+ ID_PRODUCT_FROM_DATABASE=ASUS SDRW-08D1S-U DVD-RW
+
+usb:v13FDp1840*
+ ID_PRODUCT_FROM_DATABASE=INIC-1608 SATA bridge
+
+usb:v13FE*
+ ID_VENDOR_FROM_DATABASE=Kingston Technology Company Inc.
+
+usb:v13FEp1A00*
+ ID_PRODUCT_FROM_DATABASE=512MB/1GB Flash Drive
+
+usb:v13FEp1A23*
+ ID_PRODUCT_FROM_DATABASE=512MB Flash Drive
+
+usb:v13FEp1D00*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 2.0 1GB/4GB Flash Drive / Patriot Xporter 4GB Flash Drive
+
+usb:v13FEp1E00*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive 2 GB [ICIDU 2 GB]
+
+usb:v13FEp1E50*
+ ID_PRODUCT_FROM_DATABASE=U3 Smart Drive
+
+usb:v13FEp1F00*
+ ID_PRODUCT_FROM_DATABASE=DataTraveler 2.0 4GB Flash Drive / Patriot Xporter 32GB (PEF32GUSB) Flash Drive
+
+usb:v13FEp2240*
+ ID_PRODUCT_FROM_DATABASE=microSD card reader
+
+usb:v13FEp3100*
+ ID_PRODUCT_FROM_DATABASE=2/4 GB stick
+
+usb:v13FEp3800*
+ ID_PRODUCT_FROM_DATABASE=Rage XT Flash Drive
+
+usb:v13FEp3E00*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v13FEp5100*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v1400*
+ ID_VENDOR_FROM_DATABASE=Axxion Group Corp.
+
+usb:v1402*
+ ID_VENDOR_FROM_DATABASE=Bowe Bell & Howell
+
+usb:v1403*
+ ID_VENDOR_FROM_DATABASE=Sitronix
+
+usb:v1403p0001*
+ ID_PRODUCT_FROM_DATABASE=Digital Photo Frame
+
+usb:v140E*
+ ID_VENDOR_FROM_DATABASE=Telechips, Inc.
+
+usb:v140EpB011*
+ ID_PRODUCT_FROM_DATABASE=TCC780X-based player (USB Boot mode)
+
+usb:v140EpB021*
+ ID_PRODUCT_FROM_DATABASE=TCC77X-based players (USB Boot mode)
+
+usb:v1410*
+ ID_VENDOR_FROM_DATABASE=Novatel Wireless
+
+usb:v1410p1110*
+ ID_PRODUCT_FROM_DATABASE=Merlin S620
+
+usb:v1410p1120*
+ ID_PRODUCT_FROM_DATABASE=Merlin EX720
+
+usb:v1410p1130*
+ ID_PRODUCT_FROM_DATABASE=Merlin S720
+
+usb:v1410p1400*
+ ID_PRODUCT_FROM_DATABASE=Merlin U730/U740 (Vodafone)
+
+usb:v1410p1410*
+ ID_PRODUCT_FROM_DATABASE=Merlin U740 (non-Vodafone)
+
+usb:v1410p1430*
+ ID_PRODUCT_FROM_DATABASE=Merlin XU870
+
+usb:v1410p1450*
+ ID_PRODUCT_FROM_DATABASE=Merlin X950D
+
+usb:v1410p2110*
+ ID_PRODUCT_FROM_DATABASE=Ovation U720/MCD3000
+
+usb:v1410p2410*
+ ID_PRODUCT_FROM_DATABASE=Expedite EU740
+
+usb:v1410p2420*
+ ID_PRODUCT_FROM_DATABASE=Expedite EU850D/EU860D/EU870D
+
+usb:v1410p4100*
+ ID_PRODUCT_FROM_DATABASE=U727
+
+usb:v1410p4400*
+ ID_PRODUCT_FROM_DATABASE=Ovation MC930D/MC950D
+
+usb:v1410pA001*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v1410pA008*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v1415*
+ ID_VENDOR_FROM_DATABASE=Nam Tai E&E Products Ltd. or OmniVision Technologies, Inc.
+
+usb:v1415p0000*
+ ID_PRODUCT_FROM_DATABASE=Sony SingStar USBMIC
+
+usb:v1415p0020*
+ ID_PRODUCT_FROM_DATABASE=Sony Wireless SingStar
+
+usb:v1415p2000*
+ ID_PRODUCT_FROM_DATABASE=Sony Playstation Eye
+
+usb:v1419*
+ ID_VENDOR_FROM_DATABASE=ABILITY ENTERPRISE CO., LTD.
+
+usb:v1429*
+ ID_VENDOR_FROM_DATABASE=Vega Technologies Industrial (Austria) Co.
+
+usb:v142A*
+ ID_VENDOR_FROM_DATABASE=Thales E-Transactions
+
+usb:v142Ap0003*
+ ID_PRODUCT_FROM_DATABASE=Artema Hybrid
+
+usb:v142Ap0005*
+ ID_PRODUCT_FROM_DATABASE=Artema Modular
+
+usb:v142Ap0043*
+ ID_PRODUCT_FROM_DATABASE=medCompact
+
+usb:v142B*
+ ID_VENDOR_FROM_DATABASE=Arbiter Systems, Inc.
+
+usb:v142Bp03A5*
+ ID_PRODUCT_FROM_DATABASE=933A Portable Power Sentinel
+
+usb:v1430*
+ ID_VENDOR_FROM_DATABASE=RedOctane
+
+usb:v1430p0150*
+ ID_PRODUCT_FROM_DATABASE=wireless receiver for skylanders wii
+
+usb:v1430p4734*
+ ID_PRODUCT_FROM_DATABASE=Guitar Hero4 hub
+
+usb:v1430p474B*
+ ID_PRODUCT_FROM_DATABASE=Guitar Hero MIDI interface
+
+usb:v1431*
+ ID_VENDOR_FROM_DATABASE=Pertech Resources, Inc.
+
+usb:v1435*
+ ID_VENDOR_FROM_DATABASE=Wistron NeWeb
+
+usb:v1435p0427*
+ ID_PRODUCT_FROM_DATABASE=UR054g 802.11g Wireless Adapter [Intersil ISL3887]
+
+usb:v1435p0711*
+ ID_PRODUCT_FROM_DATABASE=UR055G 802.11bg
+
+usb:v1435p0804*
+ ID_PRODUCT_FROM_DATABASE=AR9170+AR9104 802.11abgn Wireless Adapter
+
+usb:v1435p0826*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v1435p0827*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v1435p0828*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v1435p0829*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v1436*
+ ID_VENDOR_FROM_DATABASE=Denali Software, Inc.
+
+usb:v143C*
+ ID_VENDOR_FROM_DATABASE=Altek Corporation
+
+usb:v1443*
+ ID_VENDOR_FROM_DATABASE=Digilent
+
+usb:v1443p0007*
+ ID_PRODUCT_FROM_DATABASE=CoolRunner-II CPLD Starter Kit
+
+usb:v1446*
+ ID_VENDOR_FROM_DATABASE=X.J.GROUP
+
+usb:v1446p6A73*
+ ID_PRODUCT_FROM_DATABASE=Stamps.com Model 510 5LB Scale
+
+usb:v1453*
+ ID_VENDOR_FROM_DATABASE=Radio Shack
+
+usb:v1453p4026*
+ ID_PRODUCT_FROM_DATABASE=26-183 Serial Cable
+
+usb:v1456*
+ ID_VENDOR_FROM_DATABASE=Extending Wire & Cable Co., Ltd.
+
+usb:v1457*
+ ID_VENDOR_FROM_DATABASE=First International Computer, Inc.
+
+usb:v1457p5117*
+ ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 kernel usbnet (g_ether, CDC Ethernet) mode
+
+usb:v1457p5118*
+ ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 Debug board (V2+)
+
+usb:v1457p5119*
+ ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 u-boot cdc_acm serial port
+
+usb:v1457p5120*
+ ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 u-boot usbtty generic serial
+
+usb:v1457p5121*
+ ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 kernel mass storage (g_storage) mode
+
+usb:v1457p5122*
+ ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 / Neo Freerunner kernel cdc_ether USB network
+
+usb:v1457p5123*
+ ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 internal USB CSR4 module
+
+usb:v1457p5124*
+ ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 Bluetooth Device ID service
+
+usb:v145F*
+ ID_VENDOR_FROM_DATABASE=Trust
+
+usb:v145Fp0106*
+ ID_PRODUCT_FROM_DATABASE=Trust K56 V92 USB Modem
+
+usb:v145Fp013D*
+ ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV7660)
+
+usb:v145Fp013F*
+ ID_PRODUCT_FROM_DATABASE=Megapixel Auto Focus Webcam
+
+usb:v145Fp0142*
+ ID_PRODUCT_FROM_DATABASE=WB-6250X Webcam
+
+usb:v145Fp015A*
+ ID_PRODUCT_FROM_DATABASE=WB-8300X 2MP Webcam
+
+usb:v145Fp0161*
+ ID_PRODUCT_FROM_DATABASE=15901 802.11bg Wireless Adapter [Realtek RTL8187L]
+
+usb:v145Fp0167*
+ ID_PRODUCT_FROM_DATABASE=Widescreen 3MP Webcam
+
+usb:v145Fp0176*
+ ID_PRODUCT_FROM_DATABASE=Isla Keyboard
+
+usb:v1460*
+ ID_VENDOR_FROM_DATABASE=Tatung Co.
+
+usb:v1460p9150*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v1461*
+ ID_VENDOR_FROM_DATABASE=Staccato Communications
+
+usb:v1462*
+ ID_VENDOR_FROM_DATABASE=Micro Star International
+
+usb:v1462p5512*
+ ID_PRODUCT_FROM_DATABASE=MegaStick-1 Flash Stick
+
+usb:v1462p8807*
+ ID_PRODUCT_FROM_DATABASE=DIGIVOX mini III [af9015]
+
+usb:v1472*
+ ID_VENDOR_FROM_DATABASE=Huawei-3Com
+
+usb:v1472p0007*
+ ID_PRODUCT_FROM_DATABASE=Aolynk WUB300g [ZyDAS ZD1211]
+
+usb:v1472p0009*
+ ID_PRODUCT_FROM_DATABASE=Aolynk WUB320g
+
+usb:v147A*
+ ID_VENDOR_FROM_DATABASE=Formosa Industrial Computing, Inc.
+
+usb:v147ApE015*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v147ApE016*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v147ApE017*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v147ApE018*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v147ApE02C*
+ ID_PRODUCT_FROM_DATABASE=Infrared Receiver
+
+usb:v147ApE03A*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v147ApE03C*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v147ApE03E*
+ ID_PRODUCT_FROM_DATABASE=Infrared Receiver [IR605A/Q]
+
+usb:v147E*
+ ID_VENDOR_FROM_DATABASE=Upek
+
+usb:v147Ep1000*
+ ID_PRODUCT_FROM_DATABASE=Biometric Touchchip/Touchstrip Fingerprint Sensor
+
+usb:v147Ep1001*
+ ID_PRODUCT_FROM_DATABASE=TCS5B Fingerprint sensor
+
+usb:v147Ep2016*
+ ID_PRODUCT_FROM_DATABASE=Biometric Touchchip/Touchstrip Fingerprint Sensor
+
+usb:v147Ep2020*
+ ID_PRODUCT_FROM_DATABASE=TouchChip Fingerprint Coprocessor (WBF advanced mode)
+
+usb:v147Ep3000*
+ ID_PRODUCT_FROM_DATABASE=TCS1C EIM/Cypress Fingerprint sensor
+
+usb:v147Ep3001*
+ ID_PRODUCT_FROM_DATABASE=TCS1C EIM/STM32 Fingerprint sensor
+
+usb:v147F*
+ ID_VENDOR_FROM_DATABASE=Hama GmbH & Co., KG
+
+usb:v1482*
+ ID_VENDOR_FROM_DATABASE=Vaillant
+
+usb:v1482p1005*
+ ID_PRODUCT_FROM_DATABASE=VRD PC-Interface
+
+usb:v1484*
+ ID_VENDOR_FROM_DATABASE=Elsa AG [hex]
+
+usb:v1484p1746*
+ ID_PRODUCT_FROM_DATABASE=Ecomo 19H99 Monitor
+
+usb:v1484p7616*
+ ID_PRODUCT_FROM_DATABASE=Elsa Hub
+
+usb:v1485*
+ ID_VENDOR_FROM_DATABASE=Silicom
+
+usb:v1485p0001*
+ ID_PRODUCT_FROM_DATABASE=U2E
+
+usb:v1485p0002*
+ ID_PRODUCT_FROM_DATABASE=Psion Gold Port Ethernet
+
+usb:v1487*
+ ID_VENDOR_FROM_DATABASE=DSP Group, Ltd.
+
+usb:v148E*
+ ID_VENDOR_FROM_DATABASE=EVATRONIX SA
+
+usb:v148F*
+ ID_VENDOR_FROM_DATABASE=Ralink Technology, Corp.
+
+usb:v148Fp1706*
+ ID_PRODUCT_FROM_DATABASE=RT2500USB Wireless Adapter
+
+usb:v148Fp2070*
+ ID_PRODUCT_FROM_DATABASE=RT2070 Wireless Adapter
+
+usb:v148Fp2570*
+ ID_PRODUCT_FROM_DATABASE=RT2570 Wireless Adapter
+
+usb:v148Fp2573*
+ ID_PRODUCT_FROM_DATABASE=RT2501/RT2573 Wireless Adapter
+
+usb:v148Fp2671*
+ ID_PRODUCT_FROM_DATABASE=RT2601/RT2671 Wireless Adapter
+
+usb:v148Fp2770*
+ ID_PRODUCT_FROM_DATABASE=RT2770 Wireless Adapter
+
+usb:v148Fp2870*
+ ID_PRODUCT_FROM_DATABASE=RT2870 Wireless Adapter
+
+usb:v148Fp3070*
+ ID_PRODUCT_FROM_DATABASE=RT2870/RT3070 Wireless Adapter
+
+usb:v148Fp3071*
+ ID_PRODUCT_FROM_DATABASE=RT3071 Wireless Adapter
+
+usb:v148Fp3072*
+ ID_PRODUCT_FROM_DATABASE=RT3072 Wireless Adapter
+
+usb:v148Fp3370*
+ ID_PRODUCT_FROM_DATABASE=RT3370 Wireless Adapter
+
+usb:v148Fp3572*
+ ID_PRODUCT_FROM_DATABASE=RT3572 Wireless Adapter
+
+usb:v148Fp3573*
+ ID_PRODUCT_FROM_DATABASE=TEW-684UB / RT3573 Wireless Adapter
+
+usb:v148Fp5370*
+ ID_PRODUCT_FROM_DATABASE=RT5370 Wireless Adapter
+
+usb:v148Fp5372*
+ ID_PRODUCT_FROM_DATABASE=RT5372 Wireless Adapter
+
+usb:v148Fp5572*
+ ID_PRODUCT_FROM_DATABASE=RT5572 Wireless Adapter
+
+usb:v148Fp9020*
+ ID_PRODUCT_FROM_DATABASE=RT2500USB Wireless Adapter
+
+usb:v148Fp9021*
+ ID_PRODUCT_FROM_DATABASE=RT2501USB Wireless Adapter
+
+usb:v1491*
+ ID_VENDOR_FROM_DATABASE=Futronic Technology Co. Ltd.
+
+usb:v1491p0020*
+ ID_PRODUCT_FROM_DATABASE=FS81 Fingerprint Scanner Module
+
+usb:v1493*
+ ID_VENDOR_FROM_DATABASE=Suunto
+
+usb:v1497*
+ ID_VENDOR_FROM_DATABASE=Panstrong Company Ltd.
+
+usb:v1498*
+ ID_VENDOR_FROM_DATABASE=Microtek International Inc.
+
+usb:v1498pA090*
+ ID_PRODUCT_FROM_DATABASE=DVB-T Tuner
+
+usb:v149A*
+ ID_VENDOR_FROM_DATABASE=Imagination Technologies
+
+usb:v149Ap2107*
+ ID_PRODUCT_FROM_DATABASE=DBX1 DSP core
+
+usb:v14AA*
+ ID_VENDOR_FROM_DATABASE=WideView Technology Inc.
+
+usb:v14AAp0001*
+ ID_PRODUCT_FROM_DATABASE=Avermedia AverTV DVBT USB1.1 (cold)
+
+usb:v14AAp0002*
+ ID_PRODUCT_FROM_DATABASE=Avermedia AverTV DVBT USB1.1 (warm)
+
+usb:v14AAp0201*
+ ID_PRODUCT_FROM_DATABASE=AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (cold)
+
+usb:v14AAp0221*
+ ID_PRODUCT_FROM_DATABASE=WT-220U DVB-T dongle
+
+usb:v14AAp022B*
+ ID_PRODUCT_FROM_DATABASE=WT-220U DVB-T dongle
+
+usb:v14AAp0301*
+ ID_PRODUCT_FROM_DATABASE=AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (warm)
+
+usb:v14AD*
+ ID_VENDOR_FROM_DATABASE=CTK Corporation
+
+usb:v14AE*
+ ID_VENDOR_FROM_DATABASE=Printronix Inc.
+
+usb:v14AF*
+ ID_VENDOR_FROM_DATABASE=ATP Electronics Inc.
+
+usb:v14B0*
+ ID_VENDOR_FROM_DATABASE=StarTech.com Ltd.
+
+usb:v14B2*
+ ID_VENDOR_FROM_DATABASE=Ralink Technology, Corp.
+
+usb:v14B2p3A93*
+ ID_PRODUCT_FROM_DATABASE=Topcom 802.11bg Wireless Adapter [Atheros AR5523]
+
+usb:v14B2p3A95*
+ ID_PRODUCT_FROM_DATABASE=Toshiba WUS-G06G-JT 802.11bg Wireless Adapter [Atheros AR5523]
+
+usb:v14B2p3A98*
+ ID_PRODUCT_FROM_DATABASE=Airlink101 AWLL4130 802.11bg Wireless Adapter [Atheros AR5523]
+
+usb:v14B2p3C02*
+ ID_PRODUCT_FROM_DATABASE=Conceptronic C54RU v2 802.11bg Wireless Adapter [Ralink RT2571]
+
+usb:v14B2p3C05*
+ ID_PRODUCT_FROM_DATABASE=rt2570 802.11g WLAN
+
+usb:v14B2p3C06*
+ ID_PRODUCT_FROM_DATABASE=Conceptronic C300RU v1 802.11bgn Wireless Adapter [Ralink RT2870]
+
+usb:v14B2p3C07*
+ ID_PRODUCT_FROM_DATABASE=802.11n adapter
+
+usb:v14B2p3C09*
+ ID_PRODUCT_FROM_DATABASE=802.11n adapter
+
+usb:v14B2p3C22*
+ ID_PRODUCT_FROM_DATABASE=Conceptronic C54RU v3 802.11bg Wireless Adapter [Ralink RT2571W]
+
+usb:v14B2p3C23*
+ ID_PRODUCT_FROM_DATABASE=Airlink101 AWLL6080 802.11bgn Wireless Adapter [Ralink RT2870]
+
+usb:v14B2p3C24*
+ ID_PRODUCT_FROM_DATABASE=NEC NP01LM 802.11abg Wireless Adapter [Ralink RT2571W]
+
+usb:v14B2p3C25*
+ ID_PRODUCT_FROM_DATABASE=DrayTek Vigor N61 802.11bgn Wireless Adapter [Ralink RT2870]
+
+usb:v14B2p3C27*
+ ID_PRODUCT_FROM_DATABASE=Airlink101 AWLL6070 802.11bgn Wireless Adapter [Ralink RT2770]
+
+usb:v14B2p3C28*
+ ID_PRODUCT_FROM_DATABASE=Conceptronic C300RU v2 802.11bgn Wireless Adapter [Ralink RT2770]
+
+usb:v14B2p3C2B*
+ ID_PRODUCT_FROM_DATABASE=NEC NP02LM 802.11bgn Wireless Adapter [Ralink RT3070]
+
+usb:v14B2p3C2C*
+ ID_PRODUCT_FROM_DATABASE=Keebox W150NU 802.11bgn Wireless Adapter [Ralink RT3070]
+
+usb:v14C0*
+ ID_VENDOR_FROM_DATABASE=Rockwell Automation, Inc.
+
+usb:v14C2*
+ ID_VENDOR_FROM_DATABASE=Gemlight Computer, Ltd
+
+usb:v14C2p0250*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V2
+
+usb:v14C2p0350*
+ ID_PRODUCT_FROM_DATABASE=Storage Adapter V2
+
+usb:v14C8*
+ ID_VENDOR_FROM_DATABASE=Zytronic
+
+usb:v14CD*
+ ID_VENDOR_FROM_DATABASE=Super Top
+
+usb:v14CDp121C*
+ ID_PRODUCT_FROM_DATABASE=microSD card reader
+
+usb:v14CDp123A*
+ ID_PRODUCT_FROM_DATABASE=SD/MMC/RS-MMC Card Reader
+
+usb:v14CDp125C*
+ ID_PRODUCT_FROM_DATABASE=SD card reader
+
+usb:v14CDp127B*
+ ID_PRODUCT_FROM_DATABASE=SDXC Reader
+
+usb:v14CDp6116*
+ ID_PRODUCT_FROM_DATABASE=M6116 SATA Bridge
+
+usb:v14CDp6600*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 IDE DEVICE
+
+usb:v14CDp6700*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v14CDp6900*
+ ID_PRODUCT_FROM_DATABASE=Card Reader
+
+usb:v14CDp8123*
+ ID_PRODUCT_FROM_DATABASE=SD MMC Reader
+
+usb:v14CDp8125*
+ ID_PRODUCT_FROM_DATABASE=SD MMC Reader
+
+usb:v14D8*
+ ID_VENDOR_FROM_DATABASE=JAMER INDUSTRIES CO., LTD.
+
+usb:v14DD*
+ ID_VENDOR_FROM_DATABASE=Raritan Computer, Inc.
+
+usb:v14DDp1007*
+ ID_PRODUCT_FROM_DATABASE=D2CIM-VUSB KVM connector
+
+usb:v14E1*
+ ID_VENDOR_FROM_DATABASE=Dialogue Technology Corp.
+
+usb:v14E1p5000*
+ ID_PRODUCT_FROM_DATABASE=PenMount 5000 Touch Controller
+
+usb:v14E5*
+ ID_VENDOR_FROM_DATABASE=SAIN Information & Communications Co., Ltd.
+
+usb:v14EA*
+ ID_VENDOR_FROM_DATABASE=Planex Communications
+
+usb:v14EApAB10*
+ ID_PRODUCT_FROM_DATABASE=GW-US54GZ
+
+usb:v14EApAB11*
+ ID_PRODUCT_FROM_DATABASE=GU-1000T
+
+usb:v14EApAB13*
+ ID_PRODUCT_FROM_DATABASE=GW-US54Mini 802.11bg
+
+usb:v14ED*
+ ID_VENDOR_FROM_DATABASE=Shure Inc.
+
+usb:v14EDp29B6*
+ ID_PRODUCT_FROM_DATABASE=X2u Adapter
+
+usb:v14F7*
+ ID_VENDOR_FROM_DATABASE=TechniSat Digital GmbH
+
+usb:v14F7p0001*
+ ID_PRODUCT_FROM_DATABASE=SkyStar 2 HD CI
+
+usb:v14F7p0002*
+ ID_PRODUCT_FROM_DATABASE=SkyStar 2 HD CI
+
+usb:v14F7p0003*
+ ID_PRODUCT_FROM_DATABASE=CableStar Combo HD CI
+
+usb:v14F7p0004*
+ ID_PRODUCT_FROM_DATABASE=AirStar TeleStick 2
+
+usb:v14F7p0500*
+ ID_PRODUCT_FROM_DATABASE=DVB-PC TV Star HD
+
+usb:v1500*
+ ID_VENDOR_FROM_DATABASE=Ellisys
+
+usb:v1501*
+ ID_VENDOR_FROM_DATABASE=Pine-Tum Enterprise Co., Ltd.
+
+usb:v1509*
+ ID_VENDOR_FROM_DATABASE=First International Computer, Inc.
+
+usb:v1509p9242*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v1513*
+ ID_VENDOR_FROM_DATABASE=medMobile
+
+usb:v1513p0444*
+ ID_PRODUCT_FROM_DATABASE=medMobile
+
+usb:v1514*
+ ID_VENDOR_FROM_DATABASE=Actel
+
+usb:v1514p2003*
+ ID_PRODUCT_FROM_DATABASE=FlashPro3 Programmer
+
+usb:v1514p2004*
+ ID_PRODUCT_FROM_DATABASE=FlashPro3 Programmer
+
+usb:v1514p2005*
+ ID_PRODUCT_FROM_DATABASE=FlashPro3 Programmer
+
+usb:v1516*
+ ID_VENDOR_FROM_DATABASE=CompUSA
+
+usb:v1516p1603*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive
+
+usb:v1516p8628*
+ ID_PRODUCT_FROM_DATABASE=Pen Drive
+
+usb:v1518*
+ ID_VENDOR_FROM_DATABASE=Cheshire Engineering Corp.
+
+usb:v1518p0001*
+ ID_PRODUCT_FROM_DATABASE=HDReye High Dynamic Range Camera
+
+usb:v1518p0002*
+ ID_PRODUCT_FROM_DATABASE=HDReye (before firmware loads)
+
+usb:v1520*
+ ID_VENDOR_FROM_DATABASE=Bitwire Corp.
+
+usb:v1524*
+ ID_VENDOR_FROM_DATABASE=ENE Technology Inc
+
+usb:v1524p6680*
+ ID_PRODUCT_FROM_DATABASE=UTS 6680
+
+usb:v1527*
+ ID_VENDOR_FROM_DATABASE=Silicon Portals
+
+usb:v1527p0200*
+ ID_PRODUCT_FROM_DATABASE=YAP Phone (no firmware)
+
+usb:v1527p0201*
+ ID_PRODUCT_FROM_DATABASE=YAP Phone
+
+usb:v1529*
+ ID_VENDOR_FROM_DATABASE=UBIQUAM Co., Ltd.
+
+usb:v1529p3100*
+ ID_PRODUCT_FROM_DATABASE=CDMA 1xRTT USB Modem (U-100/105/200/300/520)
+
+usb:v152A*
+ ID_VENDOR_FROM_DATABASE=Thesycon Systemsoftware & Consulting GmbH
+
+usb:v152D*
+ ID_VENDOR_FROM_DATABASE=JMicron Technology Corp. / JMicron USA Technology Corp.
+
+usb:v152Dp2329*
+ ID_PRODUCT_FROM_DATABASE=JM20329 SATA Bridge
+
+usb:v152Dp2335*
+ ID_PRODUCT_FROM_DATABASE=ATA/ATAPI Bridge
+
+usb:v152Dp2336*
+ ID_PRODUCT_FROM_DATABASE=Hard Disk Drive
+
+usb:v152Dp2337*
+ ID_PRODUCT_FROM_DATABASE=ATA/ATAPI Bridge
+
+usb:v152Dp2338*
+ ID_PRODUCT_FROM_DATABASE=JM20337 Hi-Speed USB to SATA & PATA Combo Bridge
+
+usb:v152Dp2339*
+ ID_PRODUCT_FROM_DATABASE=JM20339 SATA Bridge
+
+usb:v152Dp2352*
+ ID_PRODUCT_FROM_DATABASE=ATA/ATAPI Bridge
+
+usb:v152Dp2509*
+ ID_PRODUCT_FROM_DATABASE=JMS539 SuperSpeed SATA II 3.0G Bridge
+
+usb:v152E*
+ ID_VENDOR_FROM_DATABASE=LG (HLDS)
+
+usb:v152Ep2507*
+ ID_PRODUCT_FROM_DATABASE=PL-2507 IDE Controller
+
+usb:v152EpE001*
+ ID_PRODUCT_FROM_DATABASE=GSA-5120D DVD-RW
+
+usb:v1532*
+ ID_VENDOR_FROM_DATABASE=Razer USA, Ltd
+
+usb:v1532p0001*
+ ID_PRODUCT_FROM_DATABASE=RZ01-020300 Optical Mouse [Diamondback]
+
+usb:v1532p0003*
+ ID_PRODUCT_FROM_DATABASE=Krait Mouse
+
+usb:v1532p0007*
+ ID_PRODUCT_FROM_DATABASE=DeathAdder Mouse
+
+usb:v1532p0013*
+ ID_PRODUCT_FROM_DATABASE=Orochi mouse
+
+usb:v1532p0016*
+ ID_PRODUCT_FROM_DATABASE=DeathAdder Mouse
+
+usb:v1532p0017*
+ ID_PRODUCT_FROM_DATABASE=Imperator Mouse
+
+usb:v1532p001C*
+ ID_PRODUCT_FROM_DATABASE=RZ01-0036 Optical Gaming Mouse [Abyssus]
+
+usb:v1532p0024*
+ ID_PRODUCT_FROM_DATABASE=Razer Mamba
+
+usb:v1532p0101*
+ ID_PRODUCT_FROM_DATABASE=Copperhead Mouse
+
+usb:v1532p0102*
+ ID_PRODUCT_FROM_DATABASE=Tarantula Keyboard
+
+usb:v1532p0109*
+ ID_PRODUCT_FROM_DATABASE=Lycosa Keyboard
+
+usb:v1546*
+ ID_VENDOR_FROM_DATABASE=U-Blox AG
+
+usb:v1547*
+ ID_VENDOR_FROM_DATABASE=SG Intec Ltd & Co KG
+
+usb:v1547p1000*
+ ID_PRODUCT_FROM_DATABASE=SG-Lock[U2]
+
+usb:v154A*
+ ID_VENDOR_FROM_DATABASE=Celectronic GmbH
+
+usb:v154Ap8180*
+ ID_PRODUCT_FROM_DATABASE=CARD STAR/medic2
+
+usb:v154B*
+ ID_VENDOR_FROM_DATABASE=PNY
+
+usb:v154Bp0010*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Flash Drive
+
+usb:v154Bp004D*
+ ID_PRODUCT_FROM_DATABASE=8 GB Flash Drive
+
+usb:v154Bp6545*
+ ID_PRODUCT_FROM_DATABASE=FD Device
+
+usb:v154D*
+ ID_VENDOR_FROM_DATABASE=ConnectCounty Holdings Berhad
+
+usb:v154E*
+ ID_VENDOR_FROM_DATABASE=D&M Holdings, Inc. (Denon/Marantz)
+
+usb:v154Ep3000*
+ ID_PRODUCT_FROM_DATABASE=Marantz RC9001 Remote Control
+
+usb:v154F*
+ ID_VENDOR_FROM_DATABASE=SNBC CO., Ltd
+
+usb:v1554*
+ ID_VENDOR_FROM_DATABASE=Prolink Microsystems Corp.
+
+usb:v1554p5010*
+ ID_PRODUCT_FROM_DATABASE=PV-D231U(RN)-F [PixelView PlayTV SBTVD Full-Seg]
+
+usb:v1557*
+ ID_VENDOR_FROM_DATABASE=OQO
+
+usb:v1557p0002*
+ ID_PRODUCT_FROM_DATABASE=model 01 WiFi interface
+
+usb:v1557p0003*
+ ID_PRODUCT_FROM_DATABASE=model 01 Bluetooth interface
+
+usb:v1557p0A80*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v1557p7720*
+ ID_PRODUCT_FROM_DATABASE=model 01+ Ethernet
+
+usb:v1557p8150*
+ ID_PRODUCT_FROM_DATABASE=model 01 Ethernet interface
+
+usb:v1568*
+ ID_VENDOR_FROM_DATABASE=Sunf Pu Technology Co., Ltd
+
+usb:v156F*
+ ID_VENDOR_FROM_DATABASE=Quantum Corporation
+
+usb:v1570*
+ ID_VENDOR_FROM_DATABASE=ALLTOP TECHNOLOGY CO., LTD.
+
+usb:v157B*
+ ID_VENDOR_FROM_DATABASE=Ketron SRL
+
+usb:v157E*
+ ID_VENDOR_FROM_DATABASE=TRENDnet
+
+usb:v157Ep3006*
+ ID_PRODUCT_FROM_DATABASE=TEW-444UB EU [TRENDnet]
+
+usb:v157Ep3007*
+ ID_PRODUCT_FROM_DATABASE=TEW-444UB EU (no firmware)
+
+usb:v157Ep300A*
+ ID_PRODUCT_FROM_DATABASE=TEW-429UB 802.11bg
+
+usb:v157Ep300B*
+ ID_PRODUCT_FROM_DATABASE=TEW-429UB 802.11bg
+
+usb:v157Ep300C*
+ ID_PRODUCT_FROM_DATABASE=TEW-429UF A1 802.11bg Wireless Adapter [ZyDAS ZD1211B]
+
+usb:v157Ep300D*
+ ID_PRODUCT_FROM_DATABASE=TEW-429UB C1 802.11bg
+
+usb:v157Ep300E*
+ ID_PRODUCT_FROM_DATABASE=SMC SMCWUSB-N 802.11bgn 2x2:2 Wireless Adapter [Ralink RT2870]
+
+usb:v157Ep3012*
+ ID_PRODUCT_FROM_DATABASE=TEW-604UB 802.11bg Wireless Adapter [Atheros AR5523]
+
+usb:v157Ep3013*
+ ID_PRODUCT_FROM_DATABASE=TEW-645UB 802.11bgn 1x2:2 Wireless Adapter [Ralink RT2770]
+
+usb:v157Ep3204*
+ ID_PRODUCT_FROM_DATABASE=Allnet ALL0298 v2 802.11bg
+
+usb:v157Ep3205*
+ ID_PRODUCT_FROM_DATABASE=Allnet ALL0283 [AR5523]
+
+usb:v157Ep3206*
+ ID_PRODUCT_FROM_DATABASE=Allnet ALL0283 [AR5523](no firmware)
+
+usb:v157Ep3207*
+ ID_PRODUCT_FROM_DATABASE=TEW-509UB A1 802.11abg Wireless Adapter [ZyDAS ZD1211]
+
+usb:v157Ep3208*
+ ID_PRODUCT_FROM_DATABASE=TEW-509UB 1.1R 802.11abg Wireless Adapter
+
+usb:v1582*
+ ID_VENDOR_FROM_DATABASE=Fiberline
+
+usb:v1582p6003*
+ ID_PRODUCT_FROM_DATABASE=WL-430U 802.11bg
+
+usb:v1587*
+ ID_VENDOR_FROM_DATABASE=SMA Technologie AG
+
+usb:v158D*
+ ID_VENDOR_FROM_DATABASE=Oakley Inc.
+
+usb:v158E*
+ ID_VENDOR_FROM_DATABASE=JDS Uniphase Corporation (JDSU)
+
+usb:v158Ep0820*
+ ID_PRODUCT_FROM_DATABASE=SmartPocket Class Device
+
+usb:v1598*
+ ID_VENDOR_FROM_DATABASE=Kunshan Guoji Electronics Co., Ltd.
+
+usb:v15A2*
+ ID_VENDOR_FROM_DATABASE=Freescale Semiconductor, Inc.
+
+usb:v15A2p003B*
+ ID_PRODUCT_FROM_DATABASE=USB2CAN Application for ColdFire DEMOJM board
+
+usb:v15A2p0042*
+ ID_PRODUCT_FROM_DATABASE=OSBDM - Debug Port
+
+usb:v15A2p004F*
+ ID_PRODUCT_FROM_DATABASE=i.MX28 SystemOnChip in RecoveryMode
+
+usb:v15A2p0052*
+ ID_PRODUCT_FROM_DATABASE=i.MX50 SystemOnChip in RecoveryMode
+
+usb:v15A2p0054*
+ ID_PRODUCT_FROM_DATABASE=i.MX6Q SystemOnChip in RecoveryMode
+
+usb:v15A4*
+ ID_VENDOR_FROM_DATABASE=Afatech Technologies, Inc.
+
+usb:v15A4p1000*
+ ID_PRODUCT_FROM_DATABASE=AF9015/AF9035 DVB-T stick
+
+usb:v15A4p1001*
+ ID_PRODUCT_FROM_DATABASE=AF9015/AF9035 DVB-T stick
+
+usb:v15A4p1336*
+ ID_PRODUCT_FROM_DATABASE=SDHC/MicroSD/MMC/MS/M2/CF/XD Flash Card Reader
+
+usb:v15A4p9015*
+ ID_PRODUCT_FROM_DATABASE=AF9015 DVB-T USB2.0 stick
+
+usb:v15A4p9016*
+ ID_PRODUCT_FROM_DATABASE=AF9015 DVB-T USB2.0 stick
+
+usb:v15A8*
+ ID_VENDOR_FROM_DATABASE=Teams Power Limited
+
+usb:v15A9*
+ ID_VENDOR_FROM_DATABASE=Gemtek
+
+usb:v15A9p0002*
+ ID_PRODUCT_FROM_DATABASE=SparkLAN WL-682 802.11bg Wireless Adapter [Intersil ISL3887]
+
+usb:v15A9p0004*
+ ID_PRODUCT_FROM_DATABASE=WUBR-177G [Ralink RT2571W]
+
+usb:v15A9p0006*
+ ID_PRODUCT_FROM_DATABASE=Wireless 11n USB Adapter
+
+usb:v15A9p0010*
+ ID_PRODUCT_FROM_DATABASE=802.11n USB Wireless Card
+
+usb:v15A9p0012*
+ ID_PRODUCT_FROM_DATABASE=WUBR-208N 802.11abgn Wireless Adapter [Ralink RT2870]
+
+usb:v15AA*
+ ID_VENDOR_FROM_DATABASE=Gearway Electronics (Dong Guan) Co., Ltd.
+
+usb:v15AD*
+ ID_VENDOR_FROM_DATABASE=VMware Inc.
+
+usb:v15BA*
+ ID_VENDOR_FROM_DATABASE=Olimex Ltd.
+
+usb:v15BAp0003*
+ ID_PRODUCT_FROM_DATABASE=OpenOCD JTAG
+
+usb:v15BAp0004*
+ ID_PRODUCT_FROM_DATABASE=OpenOCD JTAG TINY
+
+usb:v15BAp002A*
+ ID_PRODUCT_FROM_DATABASE=ARM-USB-TINY-H JTAG interface
+
+usb:v15C0*
+ ID_VENDOR_FROM_DATABASE=XL Imaging
+
+usb:v15C0p0001*
+ ID_PRODUCT_FROM_DATABASE=2M pixel Microscope Camera
+
+usb:v15C0p0002*
+ ID_PRODUCT_FROM_DATABASE=3M pixel Microscope Camera
+
+usb:v15C0p0003*
+ ID_PRODUCT_FROM_DATABASE=1.3M pixel Microscope Camera (mono)
+
+usb:v15C0p0004*
+ ID_PRODUCT_FROM_DATABASE=1.3M pixel Microscope Camera (colour)
+
+usb:v15C0p0005*
+ ID_PRODUCT_FROM_DATABASE=3M pixel Microscope Camera (Mk 2)
+
+usb:v15C0p0006*
+ ID_PRODUCT_FROM_DATABASE=2M pixel Microscope Camera (with capture button)
+
+usb:v15C0p0007*
+ ID_PRODUCT_FROM_DATABASE=3M pixel Microscope Camera (with capture button)
+
+usb:v15C0p0008*
+ ID_PRODUCT_FROM_DATABASE=1.3M pixel Microscope Camera (colour, with capture button)
+
+usb:v15C0p0009*
+ ID_PRODUCT_FROM_DATABASE=1.3M pixel Microscope Camera (colour, with capture button)
+
+usb:v15C0p000A*
+ ID_PRODUCT_FROM_DATABASE=2M pixel Microscope Camera (Mk 2)
+
+usb:v15C0p0010*
+ ID_PRODUCT_FROM_DATABASE=1.3M pixel "Tinycam"
+
+usb:v15C0p0101*
+ ID_PRODUCT_FROM_DATABASE=3M pixel Microscope Camera
+
+usb:v15C2*
+ ID_VENDOR_FROM_DATABASE=SoundGraph Inc.
+
+usb:v15C2p0036*
+ ID_PRODUCT_FROM_DATABASE=LC16M VFD Display/IR Receiver
+
+usb:v15C2p0038*
+ ID_PRODUCT_FROM_DATABASE=GD01 MX LCD Display/IR Receiver
+
+usb:v15C2pFFDA*
+ ID_PRODUCT_FROM_DATABASE=iMON PAD Remote Controller
+
+usb:v15C2pFFDC*
+ ID_PRODUCT_FROM_DATABASE=iMON PAD Remote Controller
+
+usb:v15C5*
+ ID_VENDOR_FROM_DATABASE=Advance Multimedia Internet Technology Inc. (AMIT)
+
+usb:v15C5p0008*
+ ID_PRODUCT_FROM_DATABASE=WL532U 802.11g Adapter
+
+usb:v15C6*
+ ID_VENDOR_FROM_DATABASE=Laboratoires MXM
+
+usb:v15C6p1000*
+ ID_PRODUCT_FROM_DATABASE=DigistimSP (cold)
+
+usb:v15C6p1001*
+ ID_PRODUCT_FROM_DATABASE=DigistimSP (warm)
+
+usb:v15C6p1002*
+ ID_PRODUCT_FROM_DATABASE=DigimapSP USB (cold)
+
+usb:v15C6p1003*
+ ID_PRODUCT_FROM_DATABASE=DigimapSP USB (warm)
+
+usb:v15C6p1004*
+ ID_PRODUCT_FROM_DATABASE=DigistimSP (cold)
+
+usb:v15C6p1005*
+ ID_PRODUCT_FROM_DATABASE=DigistimSP (warm)
+
+usb:v15C6p1100*
+ ID_PRODUCT_FROM_DATABASE=Odyssee (cold)
+
+usb:v15C6p1101*
+ ID_PRODUCT_FROM_DATABASE=Odyssee (warm)
+
+usb:v15C6p1200*
+ ID_PRODUCT_FROM_DATABASE=Digispy
+
+usb:v15C8*
+ ID_VENDOR_FROM_DATABASE=KTF Technologies
+
+usb:v15C8p3201*
+ ID_PRODUCT_FROM_DATABASE=EVER EV-W100/EV-W250
+
+usb:v15C9*
+ ID_VENDOR_FROM_DATABASE=D-Box Technologies
+
+usb:v15CA*
+ ID_VENDOR_FROM_DATABASE=Textech International Ltd.
+
+usb:v15CAp00C3*
+ ID_PRODUCT_FROM_DATABASE=Mini Optical Mouse
+
+usb:v15CAp0101*
+ ID_PRODUCT_FROM_DATABASE=MIDI Interface cable
+
+usb:v15CAp1806*
+ ID_PRODUCT_FROM_DATABASE=MIDI Interface cable
+
+usb:v15D5*
+ ID_VENDOR_FROM_DATABASE=Coulomb Electronics Ltd.
+
+usb:v15D9*
+ ID_VENDOR_FROM_DATABASE=Trust International B.V.
+
+usb:v15D9p0A33*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v15D9p0A37*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v15D9p0A41*
+ ID_PRODUCT_FROM_DATABASE=MI-2540D [Optical mouse]
+
+usb:v15D9p0A4C*
+ ID_PRODUCT_FROM_DATABASE=USB+PS/2 Optical Mouse
+
+usb:v15D9p0A4D*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v15DC*
+ ID_VENDOR_FROM_DATABASE=Hynix Semiconductor Inc.
+
+usb:v15E0*
+ ID_VENDOR_FROM_DATABASE=Seong Ji Industrial Co., Ltd.
+
+usb:v15E1*
+ ID_VENDOR_FROM_DATABASE=RSA
+
+usb:v15E1p2007*
+ ID_PRODUCT_FROM_DATABASE=RSA SecurID (R) Authenticator
+
+usb:v15E4*
+ ID_VENDOR_FROM_DATABASE=Numark
+
+usb:v15E4p0024*
+ ID_PRODUCT_FROM_DATABASE=Mixtrack
+
+usb:v15E8*
+ ID_VENDOR_FROM_DATABASE=SohoWare
+
+usb:v15E8p9100*
+ ID_PRODUCT_FROM_DATABASE=NUB100 Ethernet [pegasus]
+
+usb:v15E8p9110*
+ ID_PRODUCT_FROM_DATABASE=10/100 USB Ethernet
+
+usb:v15E9*
+ ID_VENDOR_FROM_DATABASE=Pacific Digital Corp.
+
+usb:v15E9p04CE*
+ ID_PRODUCT_FROM_DATABASE=MemoryFrame MF-570
+
+usb:v15E9p1968*
+ ID_PRODUCT_FROM_DATABASE=MemoryFrame MF-570
+
+usb:v15E9p1969*
+ ID_PRODUCT_FROM_DATABASE=Digital Frame
+
+usb:v15EC*
+ ID_VENDOR_FROM_DATABASE=Belcarra Technologies Corp.
+
+usb:v15F4*
+ ID_VENDOR_FROM_DATABASE=HanfTek
+
+usb:v15F4p0001*
+ ID_PRODUCT_FROM_DATABASE=HanfTek UMT-010 USB2.0 DVB-T (cold)
+
+usb:v15F4p0025*
+ ID_PRODUCT_FROM_DATABASE=HanfTek UMT-010 USB2.0 DVB-T (warm)
+
+usb:v1604*
+ ID_VENDOR_FROM_DATABASE=Tascam
+
+usb:v1604p8000*
+ ID_PRODUCT_FROM_DATABASE=US-428 Audio/Midi Controller (without fw)
+
+usb:v1604p8001*
+ ID_PRODUCT_FROM_DATABASE=US-428 Audio/Midi Controller
+
+usb:v1604p8004*
+ ID_PRODUCT_FROM_DATABASE=US-224 Audio/Midi Controller (without fw)
+
+usb:v1604p8005*
+ ID_PRODUCT_FROM_DATABASE=US-224 Audio/Midi Controller
+
+usb:v1604p8006*
+ ID_PRODUCT_FROM_DATABASE=US-122 Audio/Midi Interface (without fw)
+
+usb:v1604p8007*
+ ID_PRODUCT_FROM_DATABASE=US-122 Audio/Midi Interface
+
+usb:v1606*
+ ID_VENDOR_FROM_DATABASE=Umax
+
+usb:v1606p0002*
+ ID_PRODUCT_FROM_DATABASE=Astra 1236U Scanner
+
+usb:v1606p0010*
+ ID_PRODUCT_FROM_DATABASE=Astra 1220U
+
+usb:v1606p0030*
+ ID_PRODUCT_FROM_DATABASE=Astra 1600U/2000U
+
+usb:v1606p0050*
+ ID_PRODUCT_FROM_DATABASE=Scanner
+
+usb:v1606p0060*
+ ID_PRODUCT_FROM_DATABASE=Astra 3400/3450
+
+usb:v1606p0070*
+ ID_PRODUCT_FROM_DATABASE=Astra 4400/4450
+
+usb:v1606p0130*
+ ID_PRODUCT_FROM_DATABASE=Astra 2100U
+
+usb:v1606p0160*
+ ID_PRODUCT_FROM_DATABASE=Astra 5400U
+
+usb:v1606p0170*
+ ID_PRODUCT_FROM_DATABASE=Uniscan D50
+
+usb:v1606p0230*
+ ID_PRODUCT_FROM_DATABASE=Astra 2200/2200SU
+
+usb:v1606p0350*
+ ID_PRODUCT_FROM_DATABASE=Astra 4800/4850 Scanner
+
+usb:v1606p1030*
+ ID_PRODUCT_FROM_DATABASE=Astra 4000U
+
+usb:v1606p1220*
+ ID_PRODUCT_FROM_DATABASE=Genesys Logic Scanner Controller NT5.0
+
+usb:v1606p2010*
+ ID_PRODUCT_FROM_DATABASE=AstraCam Digital Camera
+
+usb:v1606p2020*
+ ID_PRODUCT_FROM_DATABASE=AstraCam 1000
+
+usb:v1606p2030*
+ ID_PRODUCT_FROM_DATABASE=AstraCam 1800 Digital Camera
+
+usb:v1608*
+ ID_VENDOR_FROM_DATABASE=Inside Out Networks [hex]
+
+usb:v1608p0001*
+ ID_PRODUCT_FROM_DATABASE=EdgePort/4 Serial Port
+
+usb:v1608p0002*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8
+
+usb:v1608p0003*
+ ID_PRODUCT_FROM_DATABASE=Rapidport/4
+
+usb:v1608p0004*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p0005*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2
+
+usb:v1608p0006*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4i
+
+usb:v1608p0007*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2i
+
+usb:v1608p0008*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8
+
+usb:v1608p000C*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/421
+
+usb:v1608p000D*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/21
+
+usb:v1608p000E*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p000F*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8
+
+usb:v1608p0010*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2
+
+usb:v1608p0011*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p0012*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/416
+
+usb:v1608p0014*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8i
+
+usb:v1608p0018*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/412
+
+usb:v1608p0019*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/412
+
+usb:v1608p001A*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2+2i
+
+usb:v1608p0101*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p0105*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2
+
+usb:v1608p0106*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4i
+
+usb:v1608p0107*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2i
+
+usb:v1608p010C*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/421
+
+usb:v1608p010D*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/21
+
+usb:v1608p0110*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2
+
+usb:v1608p0111*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p0112*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/416
+
+usb:v1608p0114*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8i
+
+usb:v1608p0201*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p0203*
+ ID_PRODUCT_FROM_DATABASE=Rapidport/4
+
+usb:v1608p0204*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p0205*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2
+
+usb:v1608p0206*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4i
+
+usb:v1608p0207*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2i
+
+usb:v1608p020C*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/421
+
+usb:v1608p020D*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/21
+
+usb:v1608p020E*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p020F*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8
+
+usb:v1608p0210*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2
+
+usb:v1608p0211*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4
+
+usb:v1608p0212*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/416
+
+usb:v1608p0214*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8i
+
+usb:v1608p0215*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/1
+
+usb:v1608p0216*
+ ID_PRODUCT_FROM_DATABASE=EPOS/44
+
+usb:v1608p0217*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/42
+
+usb:v1608p021A*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2+2i
+
+usb:v1608p021B*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/2c
+
+usb:v1608p021C*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/221c
+
+usb:v1608p021D*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/22c
+
+usb:v1608p021E*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/21c
+
+usb:v1608p021F*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/62
+
+usb:v1608p0240*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/1
+
+usb:v1608p0241*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/1i
+
+usb:v1608p0242*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/4s
+
+usb:v1608p0243*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8s
+
+usb:v1608p0244*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/8
+
+usb:v1608p0245*
+ ID_PRODUCT_FROM_DATABASE=Edgeport/22c
+
+usb:v1608p0301*
+ ID_PRODUCT_FROM_DATABASE=Watchport/P
+
+usb:v1608p0302*
+ ID_PRODUCT_FROM_DATABASE=Watchport/M
+
+usb:v1608p0303*
+ ID_PRODUCT_FROM_DATABASE=Watchport/W
+
+usb:v1608p0304*
+ ID_PRODUCT_FROM_DATABASE=Watchport/T
+
+usb:v1608p0305*
+ ID_PRODUCT_FROM_DATABASE=Watchport/H
+
+usb:v1608p0306*
+ ID_PRODUCT_FROM_DATABASE=Watchport/E
+
+usb:v1608p0307*
+ ID_PRODUCT_FROM_DATABASE=Watchport/L
+
+usb:v1608p0308*
+ ID_PRODUCT_FROM_DATABASE=Watchport/R
+
+usb:v1608p0309*
+ ID_PRODUCT_FROM_DATABASE=Watchport/A
+
+usb:v1608p030A*
+ ID_PRODUCT_FROM_DATABASE=Watchport/D
+
+usb:v1608p030B*
+ ID_PRODUCT_FROM_DATABASE=Watchport/D
+
+usb:v1608p030C*
+ ID_PRODUCT_FROM_DATABASE=Power Management Port
+
+usb:v1608p030E*
+ ID_PRODUCT_FROM_DATABASE=Power Management Port
+
+usb:v1608p030F*
+ ID_PRODUCT_FROM_DATABASE=Watchport/G
+
+usb:v1608p0310*
+ ID_PRODUCT_FROM_DATABASE=Watchport/Tc
+
+usb:v1608p0311*
+ ID_PRODUCT_FROM_DATABASE=Watchport/Hc
+
+usb:v1608p1403*
+ ID_PRODUCT_FROM_DATABASE=MultiTech Systems MT4X56 Modem
+
+usb:v1608p1A17*
+ ID_PRODUCT_FROM_DATABASE=Agilent Technologies (E6473)
+
+usb:v160A*
+ ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc.
+
+usb:v160Ap3184*
+ ID_PRODUCT_FROM_DATABASE=VIA VNT-6656 [WiFi 802.11b/g USB Dongle]
+
+usb:v160E*
+ ID_VENDOR_FROM_DATABASE=INRO
+
+usb:v160Ep0001*
+ ID_PRODUCT_FROM_DATABASE=E2USBKey
+
+usb:v1614*
+ ID_VENDOR_FROM_DATABASE=Amoi Electronics
+
+usb:v1614p0404*
+ ID_PRODUCT_FROM_DATABASE=WMA9109 UMTS Phone
+
+usb:v1614p0600*
+ ID_PRODUCT_FROM_DATABASE=Vodafone VDA GPS / Toschiba Protege G710
+
+usb:v1614p0804*
+ ID_PRODUCT_FROM_DATABASE=WP-S1 Phone
+
+usb:v1619*
+ ID_VENDOR_FROM_DATABASE=L & K Precision Technology Co., Ltd.
+
+usb:v1621*
+ ID_VENDOR_FROM_DATABASE=Wionics Research
+
+usb:v1628*
+ ID_VENDOR_FROM_DATABASE=Stonestreet One, Inc.
+
+usb:v162A*
+ ID_VENDOR_FROM_DATABASE=Airgo Networks Inc.
+
+usb:v162F*
+ ID_VENDOR_FROM_DATABASE=WiQuest Communications, Inc.
+
+usb:v1630*
+ ID_VENDOR_FROM_DATABASE=2Wire, Inc.
+
+usb:v1630p0005*
+ ID_PRODUCT_FROM_DATABASE=802.11g Wireless Adapter [Intersil ISL3886]
+
+usb:v1630p0011*
+ ID_PRODUCT_FROM_DATABASE=PC Port 10 Mps Adapter
+
+usb:v1630pFF81*
+ ID_PRODUCT_FROM_DATABASE=802.11b Wireless Adapter [Lucent/Agere Hermes I]
+
+usb:v1631*
+ ID_VENDOR_FROM_DATABASE=Good Way Technology
+
+usb:v1631p6200*
+ ID_PRODUCT_FROM_DATABASE=GWUSB2E
+
+usb:v1631pC019*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v1645*
+ ID_VENDOR_FROM_DATABASE=Cross Match Technologies GmbH
+
+usb:v1645p0001*
+ ID_PRODUCT_FROM_DATABASE=1S Serial Port
+
+usb:v1645p0002*
+ ID_PRODUCT_FROM_DATABASE=2S Serial Port
+
+usb:v1645p0003*
+ ID_PRODUCT_FROM_DATABASE=1S25 Serial Port
+
+usb:v1645p0004*
+ ID_PRODUCT_FROM_DATABASE=4S Serial Port
+
+usb:v1645p0005*
+ ID_PRODUCT_FROM_DATABASE=E45 Ethernet [klsi]
+
+usb:v1645p0006*
+ ID_PRODUCT_FROM_DATABASE=Parallel Port
+
+usb:v1645p0007*
+ ID_PRODUCT_FROM_DATABASE=U1-SC25 SCSI
+
+usb:v1645p0008*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v1645p0016*
+ ID_PRODUCT_FROM_DATABASE=Bi-directional to Parallel Printer Converter
+
+usb:v1645p0080*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial Converter
+
+usb:v1645p0081*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial Converter
+
+usb:v1645p0093*
+ ID_PRODUCT_FROM_DATABASE=1S9 Serial Port
+
+usb:v1645p8000*
+ ID_PRODUCT_FROM_DATABASE=EZ-USB
+
+usb:v1645p8001*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial
+
+usb:v1645p8002*
+ ID_PRODUCT_FROM_DATABASE=2x Serial Port
+
+usb:v1645p8003*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial
+
+usb:v1645p8004*
+ ID_PRODUCT_FROM_DATABASE=2U4S serial/usb hub
+
+usb:v1645p8005*
+ ID_PRODUCT_FROM_DATABASE=Ethernet
+
+usb:v1645p8080*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial
+
+usb:v1645p8081*
+ ID_PRODUCT_FROM_DATABASE=1 port to Serial
+
+usb:v1645p8093*
+ ID_PRODUCT_FROM_DATABASE=PortGear Serial Port
+
+usb:v1649*
+ ID_VENDOR_FROM_DATABASE=SofTec Microsystems
+
+usb:v1649p0102*
+ ID_PRODUCT_FROM_DATABASE=uDART In-Circuit Debugger
+
+usb:v1649p0200*
+ ID_PRODUCT_FROM_DATABASE=SpYder USBSPYDER08
+
+usb:v164A*
+ ID_VENDOR_FROM_DATABASE=ChipX
+
+usb:v164C*
+ ID_VENDOR_FROM_DATABASE=Matrix Vision GmbH
+
+usb:v164Cp0101*
+ ID_PRODUCT_FROM_DATABASE=mvBlueFOX camera (no firmware)
+
+usb:v164Cp0103*
+ ID_PRODUCT_FROM_DATABASE=mvBlueFOX camera
+
+usb:v164Cp0201*
+ ID_PRODUCT_FROM_DATABASE=mvBlueLYNX-X intelligent camera (bootloader)
+
+usb:v164Cp0203*
+ ID_PRODUCT_FROM_DATABASE=mvBlueLYNX-X intelligent camera
+
+usb:v1657*
+ ID_VENDOR_FROM_DATABASE=Struck Innovative Systeme GmbH
+
+usb:v1657p3150*
+ ID_PRODUCT_FROM_DATABASE=SIS3150 USB2.0 to VME interface
+
+usb:v165B*
+ ID_VENDOR_FROM_DATABASE=Frontier Design Group
+
+usb:v165Bp8101*
+ ID_PRODUCT_FROM_DATABASE=Tranzport Control Surface
+
+usb:v165BpFAD1*
+ ID_PRODUCT_FROM_DATABASE=Alphatrack Control Surface
+
+usb:v165C*
+ ID_VENDOR_FROM_DATABASE=Kondo Kagaku
+
+usb:v165Cp0002*
+ ID_PRODUCT_FROM_DATABASE=Serial Adapter
+
+usb:v1660*
+ ID_VENDOR_FROM_DATABASE=Creatix Polymedia GmbH
+
+usb:v1668*
+ ID_VENDOR_FROM_DATABASE=Actiontec Electronics, Inc. [hex]
+
+usb:v1668p0009*
+ ID_PRODUCT_FROM_DATABASE=Gateway
+
+usb:v1668p0333*
+ ID_PRODUCT_FROM_DATABASE=Modem
+
+usb:v1668p0358*
+ ID_PRODUCT_FROM_DATABASE=InternetPhoneWizard
+
+usb:v1668p0405*
+ ID_PRODUCT_FROM_DATABASE=Gateway
+
+usb:v1668p0408*
+ ID_PRODUCT_FROM_DATABASE=Prism2.5 802.11b Adapter
+
+usb:v1668p0413*
+ ID_PRODUCT_FROM_DATABASE=Gateway
+
+usb:v1668p0421*
+ ID_PRODUCT_FROM_DATABASE=Prism2.5 802.11b Adapter
+
+usb:v1668p0441*
+ ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth II
+
+usb:v1668p0500*
+ ID_PRODUCT_FROM_DATABASE=BTM200B BlueTooth Adapter
+
+usb:v1668p1050*
+ ID_PRODUCT_FROM_DATABASE=802UIG-1 802.11g Wireless Mini Adapter [Intersil ISL3887]
+
+usb:v1668p1200*
+ ID_PRODUCT_FROM_DATABASE=802AIN Wireless N Network Adapter [Atheros AR9170+AR9101]
+
+usb:v1668p1441*
+ ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth II
+
+usb:v1668p2441*
+ ID_PRODUCT_FROM_DATABASE=BMDC-2 IBM Bluetooth III w.56k
+
+usb:v1668p3441*
+ ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth III
+
+usb:v1668p6010*
+ ID_PRODUCT_FROM_DATABASE=Gateway
+
+usb:v1668p6097*
+ ID_PRODUCT_FROM_DATABASE=802.11b Wireless Adapter
+
+usb:v1668p6106*
+ ID_PRODUCT_FROM_DATABASE=802UI3(B) 802.11b Wireless Adapter [Intersil PRISM 3]
+
+usb:v1668p7605*
+ ID_PRODUCT_FROM_DATABASE=UAT1 Wireless Ethernet Adapter
+
+usb:v1669*
+ ID_VENDOR_FROM_DATABASE=PiKRON Ltd. [hex]
+
+usb:v1669p1001*
+ ID_PRODUCT_FROM_DATABASE=uLan2USB Converter - PS1 protocol
+
+usb:v1677*
+ ID_VENDOR_FROM_DATABASE=China Huada Integrated Circuit Design (Group) Co., Ltd. (CIDC Group)
+
+usb:v1677p0103*
+ ID_PRODUCT_FROM_DATABASE=Token
+
+usb:v1679*
+ ID_VENDOR_FROM_DATABASE=Total Phase
+
+usb:v1679p2001*
+ ID_PRODUCT_FROM_DATABASE=Beagle Protocol Analyzer
+
+usb:v1679p2002*
+ ID_PRODUCT_FROM_DATABASE=Cheetah SPI Host Adapter
+
+usb:v1680*
+ ID_VENDOR_FROM_DATABASE=Golden Bridge Electech Inc.
+
+usb:v1680pA332*
+ ID_PRODUCT_FROM_DATABASE=DVB-T Dongle [RTL2832U]
+
+usb:v1681*
+ ID_VENDOR_FROM_DATABASE=Prevo Technologies, Inc.
+
+usb:v1681p0001*
+ ID_PRODUCT_FROM_DATABASE=Tuner's Dashboard
+
+usb:v1681p0002*
+ ID_PRODUCT_FROM_DATABASE=Tubachron
+
+usb:v1682*
+ ID_VENDOR_FROM_DATABASE=Maxwise Production Enterprise Ltd.
+
+usb:v1684*
+ ID_VENDOR_FROM_DATABASE=Godspeed Computer Corp.
+
+usb:v1685*
+ ID_VENDOR_FROM_DATABASE=Delock
+
+usb:v1685p0200*
+ ID_PRODUCT_FROM_DATABASE=Infrared adapter
+
+usb:v1686*
+ ID_VENDOR_FROM_DATABASE=ZOOM Corporation
+
+usb:v1686p0045*
+ ID_PRODUCT_FROM_DATABASE=H4 Digital Recorder
+
+usb:v1687*
+ ID_VENDOR_FROM_DATABASE=Kingmax Digital Inc.
+
+usb:v1687p5289*
+ ID_PRODUCT_FROM_DATABASE=FlashDisk
+
+usb:v1687p6211*
+ ID_PRODUCT_FROM_DATABASE=FlashDisk
+
+usb:v1688*
+ ID_VENDOR_FROM_DATABASE=Saab AB
+
+usb:v1689*
+ ID_VENDOR_FROM_DATABASE=Razer USA, Ltd
+
+usb:v1689pFD00*
+ ID_PRODUCT_FROM_DATABASE=Onza Tournament Edition controller
+
+usb:v168C*
+ ID_VENDOR_FROM_DATABASE=Atheros Communications
+
+usb:v168Cp0001*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v168Cp0002*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v1690*
+ ID_VENDOR_FROM_DATABASE=Askey Computer Corp. [hex]
+
+usb:v1690p0101*
+ ID_PRODUCT_FROM_DATABASE=Creative Modem Blaster DE5670
+
+usb:v1690p0102*
+ ID_PRODUCT_FROM_DATABASE=V1456 VQE-R2 Modem [conexant]
+
+usb:v1690p0103*
+ ID_PRODUCT_FROM_DATABASE=1456 VQE-R3 Modem [conexant]
+
+usb:v1690p0104*
+ ID_PRODUCT_FROM_DATABASE=HCF V90 Data Fax RTAD Modem
+
+usb:v1690p0107*
+ ID_PRODUCT_FROM_DATABASE=HCF V.90 Data,Fax,RTAD Modem
+
+usb:v1690p0109*
+ ID_PRODUCT_FROM_DATABASE=MagicXpress V.90 Pocket Modem [conexant]
+
+usb:v1690p0203*
+ ID_PRODUCT_FROM_DATABASE=Voyager ADSL Modem Loader
+
+usb:v1690p0204*
+ ID_PRODUCT_FROM_DATABASE=Voyager ADSL Modem
+
+usb:v1690p0205*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v1690p0206*
+ ID_PRODUCT_FROM_DATABASE=GlobeSpan ADSL WAN Modem
+
+usb:v1690p0208*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v1690p0209*
+ ID_PRODUCT_FROM_DATABASE=Voyager 100 ADSL Modem
+
+usb:v1690p0211*
+ ID_PRODUCT_FROM_DATABASE=Globespan Virata ADSL LAN Modem
+
+usb:v1690p0212*
+ ID_PRODUCT_FROM_DATABASE=DSL Modem
+
+usb:v1690p0213*
+ ID_PRODUCT_FROM_DATABASE=HM121d DSL Modem
+
+usb:v1690p0214*
+ ID_PRODUCT_FROM_DATABASE=HM121d DSL Modem
+
+usb:v1690p0215*
+ ID_PRODUCT_FROM_DATABASE=Voyager 105 ADSL Modem
+
+usb:v1690p0701*
+ ID_PRODUCT_FROM_DATABASE=WLAN
+
+usb:v1690p0710*
+ ID_PRODUCT_FROM_DATABASE=SMCWUSBT-G
+
+usb:v1690p0711*
+ ID_PRODUCT_FROM_DATABASE=SMCWUSBT-G (no firmware)
+
+usb:v1690p0712*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v1690p0713*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v1690p0715*
+ ID_PRODUCT_FROM_DATABASE=Name: Voyager 1055 Laptop 802.11g Adapter [Broadcom 4320]
+
+usb:v1690p0722*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v1690p0726*
+ ID_PRODUCT_FROM_DATABASE=Wi-Fi Wireless LAN Adapter
+
+usb:v1690p0740*
+ ID_PRODUCT_FROM_DATABASE=802.11n Wireless LAN Card
+
+usb:v1690p0901*
+ ID_PRODUCT_FROM_DATABASE=Voyager 205 ADSL Router
+
+usb:v1696*
+ ID_VENDOR_FROM_DATABASE=Hitachi Video and Information System, Inc.
+
+usb:v1697*
+ ID_VENDOR_FROM_DATABASE=VTec Test, Inc.
+
+usb:v16A5*
+ ID_VENDOR_FROM_DATABASE=Shenzhen Zhengerya Cable Co., Ltd.
+
+usb:v16A6*
+ ID_VENDOR_FROM_DATABASE=Unigraf
+
+usb:v16A6p3000*
+ ID_PRODUCT_FROM_DATABASE=VTG-3xxx Video Test Generator family
+
+usb:v16A6p4000*
+ ID_PRODUCT_FROM_DATABASE=VTG-4xxx Video Test Generator family
+
+usb:v16A6p5000*
+ ID_PRODUCT_FROM_DATABASE=VTG-5xxx Video Test Generator family
+
+usb:v16A6p5001*
+ ID_PRODUCT_FROM_DATABASE=VTG-5xxx Special (update) mode of VTG-5xxx family
+
+usb:v16AB*
+ ID_VENDOR_FROM_DATABASE=Global Sun Technology
+
+usb:v16ABp7801*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v16ABp7802*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v16ABp7811*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:v16ABp7812*
+ ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware)
+
+usb:v16AC*
+ ID_VENDOR_FROM_DATABASE=Dongguan ChingLung Wire & Cable Co., Ltd.
+
+usb:v16B4*
+ ID_VENDOR_FROM_DATABASE=iStation
+
+usb:v16B4p0801*
+ ID_PRODUCT_FROM_DATABASE=U43
+
+usb:v16B5*
+ ID_VENDOR_FROM_DATABASE=Persentec, Inc.
+
+usb:v16B5p0002*
+ ID_PRODUCT_FROM_DATABASE=Otto driving companion
+
+usb:v16C0*
+ ID_VENDOR_FROM_DATABASE=Van Ooijen Technische Informatica
+
+usb:v16C0p03E8*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1000
+
+usb:v16C0p03E9*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1001
+
+usb:v16C0p03EA*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1002
+
+usb:v16C0p03EB*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1003
+
+usb:v16C0p03EC*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1004
+
+usb:v16C0p03ED*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1005
+
+usb:v16C0p03EE*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1006
+
+usb:v16C0p03EF*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1007
+
+usb:v16C0p03F0*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1008
+
+usb:v16C0p03F1*
+ ID_PRODUCT_FROM_DATABASE=free for internal lab use 1009
+
+usb:v16C0p0477*
+ ID_PRODUCT_FROM_DATABASE=Teensy Rebootor
+
+usb:v16C0p0478*
+ ID_PRODUCT_FROM_DATABASE=Teensy Halfkay Bootloader
+
+usb:v16C0p0479*
+ ID_PRODUCT_FROM_DATABASE=Teensy Debug
+
+usb:v16C0p047A*
+ ID_PRODUCT_FROM_DATABASE=Teensy Serial
+
+usb:v16C0p047B*
+ ID_PRODUCT_FROM_DATABASE=Teensy Serial+Debug
+
+usb:v16C0p047C*
+ ID_PRODUCT_FROM_DATABASE=Teensy Keyboard
+
+usb:v16C0p047D*
+ ID_PRODUCT_FROM_DATABASE=Teensy Keyboard+Debug
+
+usb:v16C0p047E*
+ ID_PRODUCT_FROM_DATABASE=Teensy Mouse
+
+usb:v16C0p047F*
+ ID_PRODUCT_FROM_DATABASE=Teensy Mouse+Debug
+
+usb:v16C0p0480*
+ ID_PRODUCT_FROM_DATABASE=Teensy RawHID
+
+usb:v16C0p0481*
+ ID_PRODUCT_FROM_DATABASE=Teensy RawHID+Debug
+
+usb:v16C0p0482*
+ ID_PRODUCT_FROM_DATABASE=Teensyduino Keyboard+Mouse+Joystick
+
+usb:v16C0p0483*
+ ID_PRODUCT_FROM_DATABASE=Teensyduino Serial
+
+usb:v16C0p0484*
+ ID_PRODUCT_FROM_DATABASE=Teensyduino Disk
+
+usb:v16C0p0485*
+ ID_PRODUCT_FROM_DATABASE=Teensyduino MIDI
+
+usb:v16C0p0486*
+ ID_PRODUCT_FROM_DATABASE=Teensyduino RawHID
+
+usb:v16C0p0487*
+ ID_PRODUCT_FROM_DATABASE=Teensyduino Serial+Keyboard+Mouse+Joystick
+
+usb:v16C0p0488*
+ ID_PRODUCT_FROM_DATABASE=Teensyduino Flight Sim Controls
+
+usb:v16C0p05DC*
+ ID_PRODUCT_FROM_DATABASE=shared ID for use with libusb
+
+usb:v16C0p05DD*
+ ID_PRODUCT_FROM_DATABASE=BlackcatUSB2
+
+usb:v16C0p05DF*
+ ID_PRODUCT_FROM_DATABASE=Masterkit MA901 radio
+
+usb:v16C0p05E1*
+ ID_PRODUCT_FROM_DATABASE=CDC-ACM class devices (modems)
+
+usb:v16C0p05E4*
+ ID_PRODUCT_FROM_DATABASE=MIDI class devices
+
+usb:v16C0p076B*
+ ID_PRODUCT_FROM_DATABASE=OpenPCD 13.56MHz RFID Reader
+
+usb:v16C0p076C*
+ ID_PRODUCT_FROM_DATABASE=OpenPICC 13.56MHz RFID Simulator (native)
+
+usb:v16C0p08AC*
+ ID_PRODUCT_FROM_DATABASE=OpenBeacon USB stick
+
+usb:v16C0p08CA*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Universal Display
+
+usb:v16C0p08CB*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Studio Clock
+
+usb:v16C0p08CC*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte SAM7S MT Boot Loader
+
+usb:v16C0p08CD*
+ ID_PRODUCT_FROM_DATABASE=Alpermann+Velte SAM7X MT Boot Loader
+
+usb:v16C0p0A32*
+ ID_PRODUCT_FROM_DATABASE=jbmedia Light-Manager Pro
+
+usb:v16C0p27DA*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v16C0p27DB*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v16C0p27DC*
+ ID_PRODUCT_FROM_DATABASE=Joystick
+
+usb:v16C0p27DD*
+ ID_PRODUCT_FROM_DATABASE=CDC-ACM class devices (modems)
+
+usb:v16C0p27DE*
+ ID_PRODUCT_FROM_DATABASE=MIDI class devices
+
+usb:v16C0p294A*
+ ID_PRODUCT_FROM_DATABASE=Eye Movement Recorder [Visagraph]
+
+usb:v16C0p294B*
+ ID_PRODUCT_FROM_DATABASE=Eye Movement Recorder [ReadAlyzer]
+
+usb:v16CA*
+ ID_VENDOR_FROM_DATABASE=Wireless Cables, Inc.
+
+usb:v16CAp1502*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle
+
+usb:v16CC*
+ ID_VENDOR_FROM_DATABASE=silex technology, Inc.
+
+usb:v16D0*
+ ID_VENDOR_FROM_DATABASE=MCS
+
+usb:v16D0p0498*
+ ID_PRODUCT_FROM_DATABASE=Braintechnology USB-LPS
+
+usb:v16D0p0504*
+ ID_PRODUCT_FROM_DATABASE=RETRO Innovations ZoomFloppy
+
+usb:v16D0p054B*
+ ID_PRODUCT_FROM_DATABASE=GrauTec ReelBox OLED Display (external)
+
+usb:v16D0p05BE*
+ ID_PRODUCT_FROM_DATABASE=EasyLogic Board
+
+usb:v16D3*
+ ID_VENDOR_FROM_DATABASE=Frontline Test Equipment, Inc.
+
+usb:v16D5*
+ ID_VENDOR_FROM_DATABASE=AnyDATA Corporation
+
+usb:v16D5p6202*
+ ID_PRODUCT_FROM_DATABASE=CDMA/UMTS/GPRS modem
+
+usb:v16D5p6501*
+ ID_PRODUCT_FROM_DATABASE=CDMA 2000 1xRTT/EV-DO Modem
+
+usb:v16D5p6502*
+ ID_PRODUCT_FROM_DATABASE=CDMA/UMTS/GPRS modem
+
+usb:v16D6*
+ ID_VENDOR_FROM_DATABASE=JABLOCOM s.r.o.
+
+usb:v16D6p8000*
+ ID_PRODUCT_FROM_DATABASE=GDP-04 desktop phone
+
+usb:v16D6p8001*
+ ID_PRODUCT_FROM_DATABASE=EYE-02
+
+usb:v16D6p8003*
+ ID_PRODUCT_FROM_DATABASE=GDP-04 modem
+
+usb:v16D6p8004*
+ ID_PRODUCT_FROM_DATABASE=Bootloader
+
+usb:v16D6p8005*
+ ID_PRODUCT_FROM_DATABASE=GDP-04i
+
+usb:v16D6p8007*
+ ID_PRODUCT_FROM_DATABASE=BTP-06 modem
+
+usb:v16D8*
+ ID_VENDOR_FROM_DATABASE=CMOTECH Co., Ltd.
+
+usb:v16D8p5141*
+ ID_PRODUCT_FROM_DATABASE=CMOTECH CDMA Technologies modem
+
+usb:v16D8p5533*
+ ID_PRODUCT_FROM_DATABASE=CCU-550 CDMA EV-DO modem
+
+usb:v16D8p5543*
+ ID_PRODUCT_FROM_DATABASE=CDMA 2000 1xRTT/1xEVDO modem
+
+usb:v16D8p6280*
+ ID_PRODUCT_FROM_DATABASE=CMOTECH CDMA Technologies modem
+
+usb:v16D8p6803*
+ ID_PRODUCT_FROM_DATABASE=CNU-680 CDMA EV-DO modem
+
+usb:v16D8p8001*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v16D8p8002*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v16DC*
+ ID_VENDOR_FROM_DATABASE=Wiener, Plein & Baus
+
+usb:v16DCp0001*
+ ID_PRODUCT_FROM_DATABASE=CC
+
+usb:v16DCp000B*
+ ID_PRODUCT_FROM_DATABASE=VM
+
+usb:v16DCp0010*
+ ID_PRODUCT_FROM_DATABASE=PL512 Power Supply System
+
+usb:v16DCp0011*
+ ID_PRODUCT_FROM_DATABASE=MARATON Power Supply System
+
+usb:v16DCp0012*
+ ID_PRODUCT_FROM_DATABASE=MPOD Multi Channel Power Supply System
+
+usb:v16DCp0015*
+ ID_PRODUCT_FROM_DATABASE=CML Control, Measurement and Data Logging System
+
+usb:v16DF*
+ ID_VENDOR_FROM_DATABASE=King Billion Electronics Co., Ltd.
+
+usb:v16F0*
+ ID_VENDOR_FROM_DATABASE=GN ReSound A/S
+
+usb:v16F0p0001*
+ ID_PRODUCT_FROM_DATABASE=Speedlink Programming Interface
+
+usb:v16F0p0003*
+ ID_PRODUCT_FROM_DATABASE=Airlink Wireless Programming Interface
+
+usb:v16F5*
+ ID_VENDOR_FROM_DATABASE=Futurelogic Inc.
+
+usb:v1706*
+ ID_VENDOR_FROM_DATABASE=BlueView Technologies, Inc.
+
+usb:v1707*
+ ID_VENDOR_FROM_DATABASE=ARTIMI
+
+usb:v170B*
+ ID_VENDOR_FROM_DATABASE=Swissonic
+
+usb:v170Bp0011*
+ ID_PRODUCT_FROM_DATABASE=MIDI-USB 1x1
+
+usb:v170D*
+ ID_VENDOR_FROM_DATABASE=Avnera
+
+usb:v1725*
+ ID_VENDOR_FROM_DATABASE=Vitesse Semiconductor
+
+usb:v1726*
+ ID_VENDOR_FROM_DATABASE=Axesstel, Inc.
+
+usb:v1726p1000*
+ ID_PRODUCT_FROM_DATABASE=wireless modem
+
+usb:v1726p2000*
+ ID_PRODUCT_FROM_DATABASE=wireless modem
+
+usb:v1726p3000*
+ ID_PRODUCT_FROM_DATABASE=wireless modem
+
+usb:v172F*
+ ID_VENDOR_FROM_DATABASE=Waltop International Corp.
+
+usb:v172Fp0022*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v172Fp0024*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v172Fp0025*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v172Fp0026*
+ ID_PRODUCT_FROM_DATABASE=Tablet
+
+usb:v172Fp0031*
+ ID_PRODUCT_FROM_DATABASE=Slim Tablet 12.1"
+
+usb:v172Fp0032*
+ ID_PRODUCT_FROM_DATABASE=Slim Tablet 5.8"
+
+usb:v172Fp0034*
+ ID_PRODUCT_FROM_DATABASE=Slim Tablet 12.1"
+
+usb:v172Fp0038*
+ ID_PRODUCT_FROM_DATABASE=Genius G-Pen F509
+
+usb:v172Fp0500*
+ ID_PRODUCT_FROM_DATABASE=Media Tablet 14.1"
+
+usb:v172Fp0501*
+ ID_PRODUCT_FROM_DATABASE=Media Tablet 10.6"
+
+usb:v172Fp0502*
+ ID_PRODUCT_FROM_DATABASE=Sirius Battery Free Tablet
+
+usb:v1733*
+ ID_VENDOR_FROM_DATABASE=Cellink Technology Co., Ltd
+
+usb:v1733p0101*
+ ID_PRODUCT_FROM_DATABASE=RF Wireless Optical Mouse OP-701
+
+usb:v1736*
+ ID_VENDOR_FROM_DATABASE=CANON IMAGING SYSTEM TECHNOLOGIES INC.
+
+usb:v1737*
+ ID_VENDOR_FROM_DATABASE=Linksys
+
+usb:v1737p0039*
+ ID_PRODUCT_FROM_DATABASE=USB1000 Gigabit Notebook Adapter
+
+usb:v1737p0070*
+ ID_PRODUCT_FROM_DATABASE=WUSB100 v1 RangePlus Wireless Network Adapter [Ralink RT2870]
+
+usb:v1737p0071*
+ ID_PRODUCT_FROM_DATABASE=WUSB600N v1 Dual-Band Wireless-N Network Adapter [Ralink RT2870]
+
+usb:v1737p0073*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GC v2 802.11g Adapter [Realtek RTL8187B]
+
+usb:v1737p0075*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GSC v2 802.11g Adapter [Broadcom 4326U]
+
+usb:v1737p0077*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GC v3 802.11g Adapter [Ralink RT2070L]
+
+usb:v1737p0078*
+ ID_PRODUCT_FROM_DATABASE=WUSB100 v2 RangePlus Wireless Network Adapter [Ralink RT3070]
+
+usb:v1737p0079*
+ ID_PRODUCT_FROM_DATABASE=WUSB600N v2 Dual-Band Wireless-N Network Adapter [Ralink RT3572]
+
+usb:v1740*
+ ID_VENDOR_FROM_DATABASE=Senao
+
+usb:v1740p0605*
+ ID_PRODUCT_FROM_DATABASE=LevelOne WUA-0605 N_Max Wireless USB Adapter
+
+usb:v1740p0615*
+ ID_PRODUCT_FROM_DATABASE=LevelOne WUA-0615 N_Max Wireless USB Adapter
+
+usb:v1740p1000*
+ ID_PRODUCT_FROM_DATABASE=NUB-350 802.11g Wireless Adapter [Intersil ISL3887]
+
+usb:v1740p2000*
+ ID_PRODUCT_FROM_DATABASE=NUB-8301 802.11bg
+
+usb:v1740p3701*
+ ID_PRODUCT_FROM_DATABASE=EUB-3701 EXT 802.11g Wireless Adapter [Ralink RT2571W]
+
+usb:v1740p9603*
+ ID_PRODUCT_FROM_DATABASE=RTL8188S WLAN Adapter
+
+usb:v1740p9701*
+ ID_PRODUCT_FROM_DATABASE=EnGenius 802.11n Wireless USB Adapter
+
+usb:v1740p9702*
+ ID_PRODUCT_FROM_DATABASE=EnGenius 802.11n Wireless USB Adapter
+
+usb:v1740p9703*
+ ID_PRODUCT_FROM_DATABASE=EnGenius 802.11n Wireless USB Adapter
+
+usb:v1740p9705*
+ ID_PRODUCT_FROM_DATABASE=EnGenius 802.11n Wireless USB Adapter
+
+usb:v1740p9706*
+ ID_PRODUCT_FROM_DATABASE=EUB9706 802.11n Wireless Adapter [Ralink RT3072]
+
+usb:v1740p9801*
+ ID_PRODUCT_FROM_DATABASE=EUB9801 802.11abgn Wireless Adapter [Ralink RT3572]
+
+usb:v1743*
+ ID_VENDOR_FROM_DATABASE=General Atomics
+
+usb:v174C*
+ ID_VENDOR_FROM_DATABASE=ASMedia Technology Inc.
+
+usb:v174Cp5106*
+ ID_PRODUCT_FROM_DATABASE=Transcend StoreJet 25M3
+
+usb:v174Cp55AA*
+ ID_PRODUCT_FROM_DATABASE=ASMedia 2105 SATA bridge
+
+usb:v174F*
+ ID_VENDOR_FROM_DATABASE=Syntek
+
+usb:v174Fp1105*
+ ID_PRODUCT_FROM_DATABASE=SM-MS/Pro-MMC-XD Card Reader
+
+usb:v174Fp110B*
+ ID_PRODUCT_FROM_DATABASE=HP Webcam
+
+usb:v174Fp1403*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v174Fp1404*
+ ID_PRODUCT_FROM_DATABASE=USB Camera device, 1.3 MPixel Web Cam
+
+usb:v174Fp5212*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 UVC PC Camera
+
+usb:v174Fp5A11*
+ ID_PRODUCT_FROM_DATABASE=PC Camera
+
+usb:v174Fp5A31*
+ ID_PRODUCT_FROM_DATABASE=Sonix USB 2.0 Camera
+
+usb:v174Fp5A35*
+ ID_PRODUCT_FROM_DATABASE=Sonix 1.3MPixel USB 2.0 Camera
+
+usb:v174Fp6A31*
+ ID_PRODUCT_FROM_DATABASE=Web Cam - Asus A8J, F3S, F5R, VX2S, V1S
+
+usb:v174Fp6A33*
+ ID_PRODUCT_FROM_DATABASE=Web Cam - Asus F3SA, F9J, F9S
+
+usb:v174Fp6A51*
+ ID_PRODUCT_FROM_DATABASE=2.0MPixel Web Cam - Asus Z96J, Z96S, S96S
+
+usb:v174Fp6A54*
+ ID_PRODUCT_FROM_DATABASE=Web Cam
+
+usb:v174Fp6D51*
+ ID_PRODUCT_FROM_DATABASE=2.0Mpixel Web Cam - Eurocom D900C
+
+usb:v174Fp8A12*
+ ID_PRODUCT_FROM_DATABASE=Syntek 0.3MPixel USB 2.0 UVC PC Camera
+
+usb:v174Fp8A33*
+ ID_PRODUCT_FROM_DATABASE=Syntek USB 2.0 UVC PC Camera
+
+usb:v174FpA311*
+ ID_PRODUCT_FROM_DATABASE=1.3MPixel Web Cam - Asus A3A, A6J, A6K, A6M, A6R, A6T, A6V, A7T, A7sv, A7U
+
+usb:v174FpA312*
+ ID_PRODUCT_FROM_DATABASE=1.3MPixel Web Cam
+
+usb:v174FpA821*
+ ID_PRODUCT_FROM_DATABASE=Web Cam - Packard Bell BU45, PB Easynote MX66-208W
+
+usb:v174FpAA11*
+ ID_PRODUCT_FROM_DATABASE=Web Cam
+
+usb:v1753*
+ ID_VENDOR_FROM_DATABASE=GERTEC Telecomunicacoes Ltda.
+
+usb:v1753pC901*
+ ID_PRODUCT_FROM_DATABASE=PPC900 Pinpad Terminal
+
+usb:v1759*
+ ID_VENDOR_FROM_DATABASE=LucidPort Technology, Inc.
+
+usb:v1761*
+ ID_VENDOR_FROM_DATABASE=ASUSTek Computer, Inc. (wrong ID)
+
+usb:v1761p0B05*
+ ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter (wrong ID - swapped vendor and device)
+
+usb:v1772*
+ ID_VENDOR_FROM_DATABASE=System Level Solutions, Inc.
+
+usb:v1776*
+ ID_VENDOR_FROM_DATABASE=Arowana
+
+usb:v1776p501C*
+ ID_PRODUCT_FROM_DATABASE=300K CMOS Camera
+
+usb:v177F*
+ ID_VENDOR_FROM_DATABASE=Sweex
+
+usb:v177Fp0004*
+ ID_PRODUCT_FROM_DATABASE=MM004V5 Photo Key Chain (Digital Photo Frame) 1.5"
+
+usb:v177Fp0153*
+ ID_PRODUCT_FROM_DATABASE=LW153 802.11n Adapter [ralink rt3070]
+
+usb:v177Fp0154*
+ ID_PRODUCT_FROM_DATABASE=LW154 802.11bgn (1x1:1) Wireless Adapter [Realtek RTL8188SU]
+
+usb:v177Fp0313*
+ ID_PRODUCT_FROM_DATABASE=LW313 802.11n Adapter [ralink rt2770 + rt2720]
+
+usb:v1781*
+ ID_VENDOR_FROM_DATABASE=Multiple Vendors
+
+usb:v1781p083E*
+ ID_PRODUCT_FROM_DATABASE=MetaGeek Wi-Spy
+
+usb:v1781p083F*
+ ID_PRODUCT_FROM_DATABASE=MetaGeek Wi-Spy 2.4x
+
+usb:v1781p0938*
+ ID_PRODUCT_FROM_DATABASE=Iguanaworks USB IR Transceiver
+
+usb:v1781p0C30*
+ ID_PRODUCT_FROM_DATABASE=Telldus TellStick
+
+usb:v1781p0C31*
+ ID_PRODUCT_FROM_DATABASE=Telldus TellStick Duo
+
+usb:v1781p0C9F*
+ ID_PRODUCT_FROM_DATABASE=USBtiny
+
+usb:v1782*
+ ID_VENDOR_FROM_DATABASE=Spreadtrum Communications Inc.
+
+usb:v1784*
+ ID_VENDOR_FROM_DATABASE=TopSeed Technology Corp.
+
+usb:v1784p0001*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v1784p0004*
+ ID_PRODUCT_FROM_DATABASE=RF Combo Device
+
+usb:v1784p0006*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v1784p0007*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v1784p0008*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v1784p000A*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver
+
+usb:v1787*
+ ID_VENDOR_FROM_DATABASE=ATI AIB
+
+usb:v1788*
+ ID_VENDOR_FROM_DATABASE=ShenZhen Litkconn Technology Co., Ltd.
+
+usb:v1796*
+ ID_VENDOR_FROM_DATABASE=Printrex, Inc.
+
+usb:v1797*
+ ID_VENDOR_FROM_DATABASE=JALCO CO., LTD.
+
+usb:v1799*
+ ID_VENDOR_FROM_DATABASE=Belkin Components
+
+usb:v1799p7051*
+ ID_PRODUCT_FROM_DATABASE=F5D7051 802.11g Adapter v1000 [Broadcom 4320]
+
+usb:v1799p8051*
+ ID_PRODUCT_FROM_DATABASE=F5D8051 v2 802.11bgn Wireless Adapter [Marvell 88W8362]
+
+usb:v179D*
+ ID_VENDOR_FROM_DATABASE=Ricavision International, Inc.
+
+usb:v179Dp0010*
+ ID_PRODUCT_FROM_DATABASE=Internal Infrared Transceiver
+
+usb:v17A0*
+ ID_VENDOR_FROM_DATABASE=Samson Technologies Corp.
+
+usb:v17A0p0001*
+ ID_PRODUCT_FROM_DATABASE=C01U condenser microphone
+
+usb:v17A0p0002*
+ ID_PRODUCT_FROM_DATABASE=Q1U dynamic microphone
+
+usb:v17A0p0100*
+ ID_PRODUCT_FROM_DATABASE=C03U multi-pattern microphone
+
+usb:v17A0p0101*
+ ID_PRODUCT_FROM_DATABASE=UB1 boundary microphone
+
+usb:v17A0p0200*
+ ID_PRODUCT_FROM_DATABASE=StudioDock monitors (internal hub)
+
+usb:v17A0p0201*
+ ID_PRODUCT_FROM_DATABASE=StudioDock monitors (audio)
+
+usb:v17A0p0301*
+ ID_PRODUCT_FROM_DATABASE=Q2U handheld microphone with XLR
+
+usb:v17A0p0302*
+ ID_PRODUCT_FROM_DATABASE=GoMic compact condenser microphone
+
+usb:v17A0p0310*
+ ID_PRODUCT_FROM_DATABASE=Meteor condenser microphone
+
+usb:v17A4*
+ ID_VENDOR_FROM_DATABASE=Concept2
+
+usb:v17A4p0001*
+ ID_PRODUCT_FROM_DATABASE=Performance Monitor 3
+
+usb:v17A4p0002*
+ ID_PRODUCT_FROM_DATABASE=Performance Monitor 4
+
+usb:v17A5*
+ ID_VENDOR_FROM_DATABASE=Advanced Connection Technology Inc.
+
+usb:v17A7*
+ ID_VENDOR_FROM_DATABASE=MICOMSOFT CO., LTD.
+
+usb:v17A8*
+ ID_VENDOR_FROM_DATABASE=Kamstrup A/S
+
+usb:v17A8p0001*
+ ID_PRODUCT_FROM_DATABASE=Optical Eye/3-wire
+
+usb:v17A8p0005*
+ ID_PRODUCT_FROM_DATABASE=M-Bus Master MultiPort 250D
+
+usb:v17B3*
+ ID_VENDOR_FROM_DATABASE=Grey Innovation
+
+usb:v17B3p0004*
+ ID_PRODUCT_FROM_DATABASE=Linux-USB Midi Gadget
+
+usb:v17BA*
+ ID_VENDOR_FROM_DATABASE=SAURIS GmbH
+
+usb:v17BAp0001*
+ ID_PRODUCT_FROM_DATABASE=SAU510-USB [no firmware]
+
+usb:v17BAp0510*
+ ID_PRODUCT_FROM_DATABASE=SAU510-USB and SAU510-USB plus JTAG Emulators
+
+usb:v17BAp0511*
+ ID_PRODUCT_FROM_DATABASE=SAU510-USB Iso Plus JTAG Emulator
+
+usb:v17BAp0520*
+ ID_PRODUCT_FROM_DATABASE=SAU510-USB Nano JTAG Emulator
+
+usb:v17BAp1511*
+ ID_PRODUCT_FROM_DATABASE=Onboard Emulator on SAUModule development kit
+
+usb:v17C3*
+ ID_VENDOR_FROM_DATABASE=Singim International Corp.
+
+usb:v17CC*
+ ID_VENDOR_FROM_DATABASE=Native Instruments
+
+usb:v17CCp041C*
+ ID_PRODUCT_FROM_DATABASE=Audio 2 DJ
+
+usb:v17CCp0808*
+ ID_PRODUCT_FROM_DATABASE=Maschine Controller
+
+usb:v17CCp0815*
+ ID_PRODUCT_FROM_DATABASE=Audio Kontrol 1
+
+usb:v17CCp0839*
+ ID_PRODUCT_FROM_DATABASE=Audio 4 DJ
+
+usb:v17CCp0D8D*
+ ID_PRODUCT_FROM_DATABASE=Guitarrig Mobile
+
+usb:v17CCp1915*
+ ID_PRODUCT_FROM_DATABASE=Session I/O
+
+usb:v17CCp1940*
+ ID_PRODUCT_FROM_DATABASE=RigKontrol3
+
+usb:v17CCp1969*
+ ID_PRODUCT_FROM_DATABASE=RigKontrol2
+
+usb:v17CCp1978*
+ ID_PRODUCT_FROM_DATABASE=Audio 8 DJ
+
+usb:v17CCp2280*
+ ID_PRODUCT_FROM_DATABASE=Medion MDPNA1500 in card reader mode
+
+usb:v17CCp2305*
+ ID_PRODUCT_FROM_DATABASE=Traktor Kontrol X1
+
+usb:v17CCp4711*
+ ID_PRODUCT_FROM_DATABASE=Kore Controller
+
+usb:v17CCp4712*
+ ID_PRODUCT_FROM_DATABASE=Kore Controller 2
+
+usb:v17CCpBAFF*
+ ID_PRODUCT_FROM_DATABASE=Traktor Kontrol S4
+
+usb:v17CF*
+ ID_VENDOR_FROM_DATABASE=Hip Hing Cable & Plug Mfy. Ltd.
+
+usb:v17D0*
+ ID_VENDOR_FROM_DATABASE=Sanford L.P.
+
+usb:v17D3*
+ ID_VENDOR_FROM_DATABASE=Korea Techtron Co., Ltd.
+
+usb:v17E9*
+ ID_VENDOR_FROM_DATABASE=DisplayLink
+
+usb:v17E9p0051*
+ ID_PRODUCT_FROM_DATABASE=USB VGA Adaptor
+
+usb:v17E9p0377*
+ ID_PRODUCT_FROM_DATABASE=Plugable UD-160-A (M)
+
+usb:v17E9p0378*
+ ID_PRODUCT_FROM_DATABASE=Plugable UGA-2K-A
+
+usb:v17E9p0379*
+ ID_PRODUCT_FROM_DATABASE=Plugable UGA-125
+
+usb:v17E9p037A*
+ ID_PRODUCT_FROM_DATABASE=Plugable UGA-165
+
+usb:v17E9p037B*
+ ID_PRODUCT_FROM_DATABASE=Plugable USB-VGA-165
+
+usb:v17E9p037C*
+ ID_PRODUCT_FROM_DATABASE=Plugable DC-125
+
+usb:v17E9p037D*
+ ID_PRODUCT_FROM_DATABASE=Plugable USB2-HDMI-165
+
+usb:v17E9p430A*
+ ID_PRODUCT_FROM_DATABASE=HP Port Replicator (Composite Device)
+
+usb:v17EB*
+ ID_VENDOR_FROM_DATABASE=Cornice, Inc.
+
+usb:v17EF*
+ ID_VENDOR_FROM_DATABASE=Lenovo
+
+usb:v17EFp1003*
+ ID_PRODUCT_FROM_DATABASE=Integrated Smart Card Reader
+
+usb:v17EFp1004*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v17EFp100A*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad Mini Dock Plus Series 3
+
+usb:v17EFp3815*
+ ID_PRODUCT_FROM_DATABASE=ChipsBnk 2GB USB Stick
+
+usb:v17EFp4802*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Vc0323+MI1310_SOC Camera
+
+usb:v17EFp4807*
+ ID_PRODUCT_FROM_DATABASE=UVC Camera
+
+usb:v17EFp480C*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v17EFp480D*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp480E*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp480F*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp4810*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp4811*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp4812*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp4813*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp4814*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp4815*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877]
+
+usb:v17EFp481C*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v17EFp481D*
+ ID_PRODUCT_FROM_DATABASE=Integrated Webcam
+
+usb:v17EFp6007*
+ ID_PRODUCT_FROM_DATABASE=Smartcard Keyboard
+
+usb:v17EFp6009*
+ ID_PRODUCT_FROM_DATABASE=ThinkPad Keyboard with TrackPoint
+
+usb:v17EFp6014*
+ ID_PRODUCT_FROM_DATABASE=Mini Wireless Keyboard N5901
+
+usb:v17EFp7423*
+ ID_PRODUCT_FROM_DATABASE=IdeaPad A1 Tablet
+
+usb:v17F4*
+ ID_VENDOR_FROM_DATABASE=WaveSense
+
+usb:v17F4pAAAA*
+ ID_PRODUCT_FROM_DATABASE=Jazz Blood Glucose Meter
+
+usb:v17F5*
+ ID_VENDOR_FROM_DATABASE=K.K. Rocky
+
+usb:v17F6*
+ ID_VENDOR_FROM_DATABASE=Unicomp, Inc
+
+usb:v17F6p0709*
+ ID_PRODUCT_FROM_DATABASE=Model M Keyboard
+
+usb:v1809*
+ ID_VENDOR_FROM_DATABASE=Advantech
+
+usb:v1809p4604*
+ ID_PRODUCT_FROM_DATABASE=USB-4604
+
+usb:v1809p4761*
+ ID_PRODUCT_FROM_DATABASE=USB-4761 Portable Data Acquisition Module
+
+usb:v1822*
+ ID_VENDOR_FROM_DATABASE=Twinhan
+
+usb:v1822p3201*
+ ID_PRODUCT_FROM_DATABASE=VisionDTV USB-Ter/HAMA USB DVB-T device cold
+
+usb:v1822p3202*
+ ID_PRODUCT_FROM_DATABASE=VisionDTV USB-Ter/HAMA USB DVB-T device warm
+
+usb:v1831*
+ ID_VENDOR_FROM_DATABASE=Gwo Jinn Industries Co., Ltd.
+
+usb:v1832*
+ ID_VENDOR_FROM_DATABASE=Huizhou Shenghua Industrial Co., Ltd.
+
+usb:v183D*
+ ID_VENDOR_FROM_DATABASE=VIVOphone
+
+usb:v183Dp0010*
+ ID_PRODUCT_FROM_DATABASE=VoiceKey
+
+usb:v1843*
+ ID_VENDOR_FROM_DATABASE=Vaisala
+
+usb:v1849*
+ ID_VENDOR_FROM_DATABASE=ASRock Incorporation
+
+usb:v1852*
+ ID_VENDOR_FROM_DATABASE=GYROCOM C&C Co., LTD
+
+usb:v1852p7922*
+ ID_PRODUCT_FROM_DATABASE=Audiotrak DR.DAC2 DX [GYROCOM C&C]
+
+usb:v1854*
+ ID_VENDOR_FROM_DATABASE=Memory Devices Ltd.
+
+usb:v185B*
+ ID_VENDOR_FROM_DATABASE=Compro
+
+usb:v185Bp3020*
+ ID_PRODUCT_FROM_DATABASE=K100 Infrared Receiver
+
+usb:v185Bp3082*
+ ID_PRODUCT_FROM_DATABASE=K100 Infrared Receiver v2
+
+usb:v185BpD000*
+ ID_PRODUCT_FROM_DATABASE=Compro Videomate DVB-U2000 - DVB-T USB cold
+
+usb:v185BpD001*
+ ID_PRODUCT_FROM_DATABASE=Compro Videomate DVB-U2000 - DVB-T USB warm
+
+usb:v1861*
+ ID_VENDOR_FROM_DATABASE=Tech Technology Industrial Company
+
+usb:v1862*
+ ID_VENDOR_FROM_DATABASE=Teridian Semiconductor Corp.
+
+usb:v1870*
+ ID_VENDOR_FROM_DATABASE=Nexio Co., Ltd
+
+usb:v1870p0001*
+ ID_PRODUCT_FROM_DATABASE=iNexio Touchscreen controller
+
+usb:v1871*
+ ID_VENDOR_FROM_DATABASE=Aveo Technology Corp.
+
+usb:v1871p0101*
+ ID_PRODUCT_FROM_DATABASE=UVC camera (Bresser microscope)
+
+usb:v1871p0D01*
+ ID_PRODUCT_FROM_DATABASE=USB2.0 Camera
+
+usb:v1873*
+ ID_VENDOR_FROM_DATABASE=Navilock
+
+usb:v1873pEE93*
+ ID_PRODUCT_FROM_DATABASE=EasyLogger
+
+usb:v187C*
+ ID_VENDOR_FROM_DATABASE=Alienware Corporation
+
+usb:v187Cp0600*
+ ID_PRODUCT_FROM_DATABASE=Dual Compatible Game Pad
+
+usb:v187F*
+ ID_VENDOR_FROM_DATABASE=Siano Mobile Silicon
+
+usb:v187Fp0010*
+ ID_PRODUCT_FROM_DATABASE=Stallar Board
+
+usb:v187Fp0100*
+ ID_PRODUCT_FROM_DATABASE=Stallar Board
+
+usb:v187Fp0200*
+ ID_PRODUCT_FROM_DATABASE=Nova A
+
+usb:v187Fp0201*
+ ID_PRODUCT_FROM_DATABASE=Nova B
+
+usb:v187Fp0202*
+ ID_PRODUCT_FROM_DATABASE=Nice
+
+usb:v187Fp0300*
+ ID_PRODUCT_FROM_DATABASE=Vega
+
+usb:v187Fp0301*
+ ID_PRODUCT_FROM_DATABASE=VeNice
+
+usb:v1892*
+ ID_VENDOR_FROM_DATABASE=Vast Technologies, Inc.
+
+usb:v1894*
+ ID_VENDOR_FROM_DATABASE=Topseed
+
+usb:v1894p5632*
+ ID_PRODUCT_FROM_DATABASE=Atek Tote Remote
+
+usb:v1894p5641*
+ ID_PRODUCT_FROM_DATABASE=TSAM-004 Presentation Remote
+
+usb:v1897*
+ ID_VENDOR_FROM_DATABASE=Evertop Wire Cable Co.
+
+usb:v189F*
+ ID_VENDOR_FROM_DATABASE=3Shape A/S
+
+usb:v189Fp0002*
+ ID_PRODUCT_FROM_DATABASE=Legato2 3D Scanner
+
+usb:v18A4*
+ ID_VENDOR_FROM_DATABASE=CSSN
+
+usb:v18A4p0001*
+ ID_PRODUCT_FROM_DATABASE=Snapshell IDR
+
+usb:v18A5*
+ ID_VENDOR_FROM_DATABASE=Verbatim, Ltd
+
+usb:v18A5p0214*
+ ID_PRODUCT_FROM_DATABASE=Portable Hard Drive
+
+usb:v18A5p0216*
+ ID_PRODUCT_FROM_DATABASE=External Hard Drive
+
+usb:v18A5p0218*
+ ID_PRODUCT_FROM_DATABASE=External Hard Drive
+
+usb:v18A5p0227*
+ ID_PRODUCT_FROM_DATABASE=Pocket Hard Drive
+
+usb:v18A5p022B*
+ ID_PRODUCT_FROM_DATABASE=Portable Hard Drive (Store'n'Go)
+
+usb:v18A5p0237*
+ ID_PRODUCT_FROM_DATABASE=Portable Harddrive (500 GB)
+
+usb:v18B1*
+ ID_VENDOR_FROM_DATABASE=Petalynx
+
+usb:v18B1p0037*
+ ID_PRODUCT_FROM_DATABASE=Maxter Remote Control
+
+usb:v18B4*
+ ID_VENDOR_FROM_DATABASE=e3C Technologies
+
+usb:v18B4p1001*
+ ID_PRODUCT_FROM_DATABASE=DUTV007
+
+usb:v18B4p1002*
+ ID_PRODUCT_FROM_DATABASE=EC168 (v5) based USB DVB-T receiver
+
+usb:v18B4p1689*
+ ID_PRODUCT_FROM_DATABASE=DUTV009
+
+usb:v18B4pFFFA*
+ ID_PRODUCT_FROM_DATABASE=EC168 (v2) based USB DVB-T receiver
+
+usb:v18B4pFFFB*
+ ID_PRODUCT_FROM_DATABASE=EC168 (v3) based USB DVB-T receiver
+
+usb:v18B6*
+ ID_VENDOR_FROM_DATABASE=Mikkon Technology Limited
+
+usb:v18B7*
+ ID_VENDOR_FROM_DATABASE=Zotek Electronic Co., Ltd.
+
+usb:v18C5*
+ ID_VENDOR_FROM_DATABASE=AMIT Technology, Inc.
+
+usb:v18C5p0002*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GO
+
+usb:v18C5p0008*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GNR Corega Wireless USB Adapter
+
+usb:v18C5p0012*
+ ID_PRODUCT_FROM_DATABASE=CG-WLUSB10 Corega Wireless USB Adapter
+
+usb:v18CD*
+ ID_VENDOR_FROM_DATABASE=Ecamm
+
+usb:v18CDpCAFE*
+ ID_PRODUCT_FROM_DATABASE=Pico iMage
+
+usb:v18D1*
+ ID_VENDOR_FROM_DATABASE=Google Inc.
+
+usb:v18D1p0D02*
+ ID_PRODUCT_FROM_DATABASE=Celkon A88
+
+usb:v18D1p4E11*
+ ID_PRODUCT_FROM_DATABASE=Nexus One
+
+usb:v18D1p4E12*
+ ID_PRODUCT_FROM_DATABASE=Nexus One (debug)
+
+usb:v18D1p4E13*
+ ID_PRODUCT_FROM_DATABASE=Nexus One (tether)
+
+usb:v18D1p4E20*
+ ID_PRODUCT_FROM_DATABASE=Nexus S (fastboot)
+
+usb:v18D1p4E21*
+ ID_PRODUCT_FROM_DATABASE=Nexus S
+
+usb:v18D1p4E22*
+ ID_PRODUCT_FROM_DATABASE=Nexus S (debug)
+
+usb:v18D1p4E24*
+ ID_PRODUCT_FROM_DATABASE=Nexus S (tether)
+
+usb:v18D1p7102*
+ ID_PRODUCT_FROM_DATABASE=Toshiba Thrive tablet
+
+usb:v18D1pB004*
+ ID_PRODUCT_FROM_DATABASE=Pandigital / B&N Novel 9" tablet
+
+usb:v18D5*
+ ID_VENDOR_FROM_DATABASE=Starline International Group Limited
+
+usb:v18D9*
+ ID_VENDOR_FROM_DATABASE=Kaba
+
+usb:v18D9p01A0*
+ ID_PRODUCT_FROM_DATABASE=B-Net 91 07
+
+usb:v18DC*
+ ID_VENDOR_FROM_DATABASE=LKC Technologies, Inc.
+
+usb:v18DD*
+ ID_VENDOR_FROM_DATABASE=Planon System Solutions Inc.
+
+usb:v18DDp1000*
+ ID_PRODUCT_FROM_DATABASE=DocuPen RC800
+
+usb:v18E3*
+ ID_VENDOR_FROM_DATABASE=Fitipower Integrated Technology Inc
+
+usb:v18E3p7102*
+ ID_PRODUCT_FROM_DATABASE=Multi Card Reader (Internal)
+
+usb:v18E3p9101*
+ ID_PRODUCT_FROM_DATABASE=All-in-1 Card Reader
+
+usb:v18E3p9102*
+ ID_PRODUCT_FROM_DATABASE=Multi Card Reader
+
+usb:v18E3p9512*
+ ID_PRODUCT_FROM_DATABASE=Webcam
+
+usb:v18E8*
+ ID_VENDOR_FROM_DATABASE=Qcom
+
+usb:v18E8p6144*
+ ID_PRODUCT_FROM_DATABASE=LR802UA 802.11b Wireless Adapter [ALi M4301AU]
+
+usb:v18E8p6196*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v18E8p6229*
+ ID_PRODUCT_FROM_DATABASE=RT2573
+
+usb:v18E8p6232*
+ ID_PRODUCT_FROM_DATABASE=Wireless 802.11g 54Mbps Network Adapter [RTL8187]
+
+usb:v18EA*
+ ID_VENDOR_FROM_DATABASE=Matrox Graphics, Inc.
+
+usb:v18EAp0002*
+ ID_PRODUCT_FROM_DATABASE=DualHead2Go [Analog Edition]
+
+usb:v18EAp0004*
+ ID_PRODUCT_FROM_DATABASE=TripleHead2Go [Digital Edition]
+
+usb:v18EC*
+ ID_VENDOR_FROM_DATABASE=Arkmicro Technologies Inc.
+
+usb:v18ECp3118*
+ ID_PRODUCT_FROM_DATABASE=USB to IrDA adapter [ARK3116T]
+
+usb:v18ECp3188*
+ ID_PRODUCT_FROM_DATABASE=ARK3188 UVC Webcam
+
+usb:v18FD*
+ ID_VENDOR_FROM_DATABASE=FineArch Inc.
+
+usb:v1908*
+ ID_VENDOR_FROM_DATABASE=GEMBIRD
+
+usb:v1908p1320*
+ ID_PRODUCT_FROM_DATABASE=PhotoFrame PF-15-1
+
+usb:v190D*
+ ID_VENDOR_FROM_DATABASE=Motorola GSG
+
+usb:v1914*
+ ID_VENDOR_FROM_DATABASE=Alco Digital Devices Limited
+
+usb:v1915*
+ ID_VENDOR_FROM_DATABASE=Nordic Semiconductor ASA
+
+usb:v1915p2233*
+ ID_PRODUCT_FROM_DATABASE=Linksys WUSB11 v2.8 802.11b Adapter [Atmel AT76C505]
+
+usb:v1915p2234*
+ ID_PRODUCT_FROM_DATABASE=Linksys WUSB54G v1 OEM 802.11g Adapter [Intersil ISL3886]
+
+usb:v1915p2235*
+ ID_PRODUCT_FROM_DATABASE=Linksys WUSB54GP v1 OEM 802.11g Adapter [Intersil ISL3886]
+
+usb:v1915p2236*
+ ID_PRODUCT_FROM_DATABASE=Linksys WUSB11 v3.0 802.11b Adapter [Intersil PRISM 3]
+
+usb:v1926*
+ ID_VENDOR_FROM_DATABASE=NextWindow
+
+usb:v1926p0003*
+ ID_PRODUCT_FROM_DATABASE=1900 HID Touchscreen
+
+usb:v1926p0006*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0064*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0065*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0066*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0067*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0068*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0069*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0071*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0072*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0073*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0074*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0075*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0076*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0077*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0078*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0079*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p007A*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p007E*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p007F*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0080*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0081*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0082*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0083*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0084*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0085*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0086*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v1926p0087*
+ ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen
+
+usb:v192F*
+ ID_VENDOR_FROM_DATABASE=Avago Technologies, Pte.
+
+usb:v192Fp0000*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v192Fp0416*
+ ID_PRODUCT_FROM_DATABASE=ADNS-5700 Optical Mouse Controller (3-button)
+
+usb:v192Fp0616*
+ ID_PRODUCT_FROM_DATABASE=ADNS-5700 Optical Mouse Controller (5-button)
+
+usb:v1930*
+ ID_VENDOR_FROM_DATABASE=Shenzhen Xianhe Technology Co., Ltd.
+
+usb:v1931*
+ ID_VENDOR_FROM_DATABASE=Ningbo Broad Telecommunication Co., Ltd.
+
+usb:v1934*
+ ID_VENDOR_FROM_DATABASE=Feature Integration Technology Inc. (Fintek)
+
+usb:v1934p0602*
+ ID_PRODUCT_FROM_DATABASE=F71610 or F71612 Consumer Infrared Receiver/Transceiver
+
+usb:v1934p0702*
+ ID_PRODUCT_FROM_DATABASE=Integrated Consumer Infrared Receiver/Transceiver
+
+usb:v1934p5168*
+ ID_PRODUCT_FROM_DATABASE=F71610A or F71612A Consumer Infrared Receiver/Transceiver
+
+usb:v1941*
+ ID_VENDOR_FROM_DATABASE=Dream Link
+
+usb:v1941p8021*
+ ID_PRODUCT_FROM_DATABASE=WH1080 Weather Station / USB Missile Launcher
+
+usb:v1943*
+ ID_VENDOR_FROM_DATABASE=Sensoray Co., Inc.
+
+usb:v1943p2250*
+ ID_PRODUCT_FROM_DATABASE=Model 2250 MPEG and JPEG Capture Card
+
+usb:v1943p2253*
+ ID_PRODUCT_FROM_DATABASE=Model 2253 Audio/Video Codec Card
+
+usb:v1943p2255*
+ ID_PRODUCT_FROM_DATABASE=Model 2255 4 Channel Capture Card
+
+usb:v1943p2257*
+ ID_PRODUCT_FROM_DATABASE=Model 2257 4 Channel Capture Card
+
+usb:v1943pA250*
+ ID_PRODUCT_FROM_DATABASE=Model 2250 MPEG and JPEG Capture Card (cold)
+
+usb:v1943pA253*
+ ID_PRODUCT_FROM_DATABASE=Model 2253 Audio/Video Codec Card (cold)
+
+usb:v1949*
+ ID_VENDOR_FROM_DATABASE=Lab126, Inc.
+
+usb:v1949p0002*
+ ID_PRODUCT_FROM_DATABASE=Amazon Kindle
+
+usb:v1949p0004*
+ ID_PRODUCT_FROM_DATABASE=Amazon Kindle 3/4
+
+usb:v1949p0006*
+ ID_PRODUCT_FROM_DATABASE=Kindle Fire
+
+usb:v194F*
+ ID_VENDOR_FROM_DATABASE=PreSonus Audio Electronics, Inc.
+
+usb:v194Fp0101*
+ ID_PRODUCT_FROM_DATABASE=AudioBox 22 VSL
+
+usb:v194Fp0102*
+ ID_PRODUCT_FROM_DATABASE=AudioBox 44 VSL
+
+usb:v194Fp0103*
+ ID_PRODUCT_FROM_DATABASE=AudioBox 1818 VSL
+
+usb:v194Fp0301*
+ ID_PRODUCT_FROM_DATABASE=AudioBox
+
+usb:v1951*
+ ID_VENDOR_FROM_DATABASE=Hyperstone AG
+
+usb:v1953*
+ ID_VENDOR_FROM_DATABASE=Ironkey Inc.
+
+usb:v1954*
+ ID_VENDOR_FROM_DATABASE=Radiient Technologies
+
+usb:v195D*
+ ID_VENDOR_FROM_DATABASE=Itron Technology iONE
+
+usb:v195Dp7002*
+ ID_PRODUCT_FROM_DATABASE=Libra-Q11 IR remote
+
+usb:v195Dp7006*
+ ID_PRODUCT_FROM_DATABASE=Libra-Q26 / 1.0 Remote
+
+usb:v195Dp7777*
+ ID_PRODUCT_FROM_DATABASE=Scorpius wireless keyboard
+
+usb:v195Dp7779*
+ ID_PRODUCT_FROM_DATABASE=Scorpius-P20MT
+
+usb:v1967*
+ ID_VENDOR_FROM_DATABASE=CASIO HITACHI Mobile Communications Co., Ltd.
+
+usb:v196B*
+ ID_VENDOR_FROM_DATABASE=Wispro Technology Inc.
+
+usb:v1970*
+ ID_VENDOR_FROM_DATABASE=Dane-Elec Corp. USA
+
+usb:v1975*
+ ID_VENDOR_FROM_DATABASE=Dongguan Guneetal Wire & Cable Co., Ltd.
+
+usb:v1976*
+ ID_VENDOR_FROM_DATABASE=Chipsbrand Microelectronics (HK) Co., Ltd.
+
+usb:v1976p6025*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive 512 MB
+
+usb:v1977*
+ ID_VENDOR_FROM_DATABASE=T-Logic
+
+usb:v1977p0111*
+ ID_PRODUCT_FROM_DATABASE=TL203 MP3 Player and Voice Recorder
+
+usb:v197D*
+ ID_VENDOR_FROM_DATABASE=Leuze electronic
+
+usb:v197Dp0222*
+ ID_PRODUCT_FROM_DATABASE=BCL 508i
+
+usb:v1989*
+ ID_VENDOR_FROM_DATABASE=Nuconn Technology Corp.
+
+usb:v198F*
+ ID_VENDOR_FROM_DATABASE=Beceem Communications Inc.
+
+usb:v198Fp0210*
+ ID_PRODUCT_FROM_DATABASE=BCS200 WiMAX Adapter
+
+usb:v198Fp0220*
+ ID_PRODUCT_FROM_DATABASE=BCSM250 WiMAX Adapter
+
+usb:v1990*
+ ID_VENDOR_FROM_DATABASE=Acron Precision Industrial Co., Ltd.
+
+usb:v1995*
+ ID_VENDOR_FROM_DATABASE=Trillium Technology Pty. Ltd.
+
+usb:v1995p3202*
+ ID_PRODUCT_FROM_DATABASE=REC-ADPT-USB (recorder)
+
+usb:v1995p3203*
+ ID_PRODUCT_FROM_DATABASE=REC-A-ADPT-USB (recorder)
+
+usb:v199B*
+ ID_VENDOR_FROM_DATABASE=MicroStrain, Inc.
+
+usb:v199Bp3065*
+ ID_PRODUCT_FROM_DATABASE=3DM-GX3-25 Orientation Sensor
+
+usb:v199E*
+ ID_VENDOR_FROM_DATABASE=The Imaging Source Europe GmbH
+
+usb:v199Ep8101*
+ ID_PRODUCT_FROM_DATABASE=DFx 21BU04 Camera
+
+usb:v199F*
+ ID_VENDOR_FROM_DATABASE=Benica Corporation
+
+usb:v19A8*
+ ID_VENDOR_FROM_DATABASE=Biforst Technology Inc.
+
+usb:v19AB*
+ ID_VENDOR_FROM_DATABASE=Bodelin
+
+usb:v19ABp1000*
+ ID_PRODUCT_FROM_DATABASE=ProScope HR
+
+usb:v19AF*
+ ID_VENDOR_FROM_DATABASE=S Life
+
+usb:v19AFp6611*
+ ID_PRODUCT_FROM_DATABASE=Celestia VoIP Phone
+
+usb:v19B2*
+ ID_VENDOR_FROM_DATABASE=Batronix
+
+usb:v19B2p0010*
+ ID_PRODUCT_FROM_DATABASE=BX32 Batupo
+
+usb:v19B2p0011*
+ ID_PRODUCT_FROM_DATABASE=BX32P Barlino
+
+usb:v19B2p0012*
+ ID_PRODUCT_FROM_DATABASE=BX40 Bagero
+
+usb:v19B2p0013*
+ ID_PRODUCT_FROM_DATABASE=BX48 Batego
+
+usb:v19B4*
+ ID_VENDOR_FROM_DATABASE=Celestron
+
+usb:v19B4p0002*
+ ID_PRODUCT_FROM_DATABASE=SkyScout Personal Planetarium
+
+usb:v19B4p0101*
+ ID_PRODUCT_FROM_DATABASE=Handheld Digital Microscope 44302
+
+usb:v19B5*
+ ID_VENDOR_FROM_DATABASE=B & W Group
+
+usb:v19B6*
+ ID_VENDOR_FROM_DATABASE=Infotech Logistic, LLC
+
+usb:v19B9*
+ ID_VENDOR_FROM_DATABASE=Data Robotics
+
+usb:v19B9p8D20*
+ ID_PRODUCT_FROM_DATABASE=Drobo Elite
+
+usb:v19C2*
+ ID_VENDOR_FROM_DATABASE=Futuba
+
+usb:v19C2p6A11*
+ ID_PRODUCT_FROM_DATABASE=MDM166A Fluorescent Display
+
+usb:v19CA*
+ ID_VENDOR_FROM_DATABASE=Mindtribe
+
+usb:v19CAp0001*
+ ID_PRODUCT_FROM_DATABASE=Sandio 3D HID Mouse
+
+usb:v19CF*
+ ID_VENDOR_FROM_DATABASE=Parrot SA
+
+usb:v19D2*
+ ID_VENDOR_FROM_DATABASE=ZTE WCDMA Technologies MSM
+
+usb:v19D2p0001*
+ ID_PRODUCT_FROM_DATABASE=CDMA Wireless Modem
+
+usb:v19D2p0002*
+ ID_PRODUCT_FROM_DATABASE=MF632/ONDA ET502HS/MT505UP
+
+usb:v19D2p0007*
+ ID_PRODUCT_FROM_DATABASE=TU25 WiMAX Adapter [Beceem BCS200]
+
+usb:v19D2p0031*
+ ID_PRODUCT_FROM_DATABASE=MF110/MF627/MF636
+
+usb:v19D2p0063*
+ ID_PRODUCT_FROM_DATABASE=K3565-Z HSDPA
+
+usb:v19D2p0064*
+ ID_PRODUCT_FROM_DATABASE=MF627 AU
+
+usb:v19D2p0083*
+ ID_PRODUCT_FROM_DATABASE=MF190
+
+usb:v19D2p0103*
+ ID_PRODUCT_FROM_DATABASE=MF112
+
+usb:v19D2p0104*
+ ID_PRODUCT_FROM_DATABASE=K4505-Z
+
+usb:v19D2p0167*
+ ID_PRODUCT_FROM_DATABASE=MF820 4G LTE
+
+usb:v19D2p0172*
+ ID_PRODUCT_FROM_DATABASE=AX226 WIMAX MODEM (After Modeswitch)
+
+usb:v19D2p0325*
+ ID_PRODUCT_FROM_DATABASE=LTE4G O2 ZTE MF821D LTE/UMTS/GSM Modem/Networkcard
+
+usb:v19D2p0326*
+ ID_PRODUCT_FROM_DATABASE=LTE4G O2 ZTE MF821D LTE/UMTS/GSM Modem/Networkcard
+
+usb:v19D2p1008*
+ ID_PRODUCT_FROM_DATABASE=K3570-Z
+
+usb:v19D2p1010*
+ ID_PRODUCT_FROM_DATABASE=K3571-Z
+
+usb:v19D2p1017*
+ ID_PRODUCT_FROM_DATABASE=K5006-Z vodafone LTE/UMTS/GSM Modem/Networkcard
+
+usb:v19D2p1018*
+ ID_PRODUCT_FROM_DATABASE=K5006-Z vodafone LTE/UMTS/GSM Modem/Networkcard
+
+usb:v19D2p1203*
+ ID_PRODUCT_FROM_DATABASE=MF691 [ T-Mobile webConnect Rocket 2.0]
+
+usb:v19D2p1217*
+ ID_PRODUCT_FROM_DATABASE=MF652
+
+usb:v19D2p1218*
+ ID_PRODUCT_FROM_DATABASE=MF652
+
+usb:v19D2p2000*
+ ID_PRODUCT_FROM_DATABASE=MF627/MF628/MF628+/MF636+ HSDPA/HSUPA
+
+usb:v19D2pFFF2*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v19D2pFFF3*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v19E1*
+ ID_VENDOR_FROM_DATABASE=WeiDuan Electronic Accessory (S.Z.) Co., Ltd.
+
+usb:v19E8*
+ ID_VENDOR_FROM_DATABASE=Industrial Technology Research Institute
+
+usb:v19EF*
+ ID_VENDOR_FROM_DATABASE=Pak Heng Technology (Shenzhen) Co., Ltd.
+
+usb:v19F7*
+ ID_VENDOR_FROM_DATABASE=RODE Microphones
+
+usb:v19F7p0001*
+ ID_PRODUCT_FROM_DATABASE=Podcaster
+
+usb:v19FA*
+ ID_VENDOR_FROM_DATABASE=Gampaq Co.Ltd
+
+usb:v19FAp0703*
+ ID_PRODUCT_FROM_DATABASE=Steering Wheel
+
+usb:v19FF*
+ ID_VENDOR_FROM_DATABASE=Dynex
+
+usb:v19FFp0102*
+ ID_PRODUCT_FROM_DATABASE=1.3MP Webcam
+
+usb:v19FFp0201*
+ ID_PRODUCT_FROM_DATABASE=Rocketfish Wireless 2.4G Laser Mouse
+
+usb:v1A08*
+ ID_VENDOR_FROM_DATABASE=Bellwood International, Inc.
+
+usb:v1A0A*
+ ID_VENDOR_FROM_DATABASE=USB-IF non-workshop
+
+usb:v1A0ApBADD*
+ ID_PRODUCT_FROM_DATABASE=USB OTG Compliance test device
+
+usb:v1A12*
+ ID_VENDOR_FROM_DATABASE=KES Co., Ltd.
+
+usb:v1A1D*
+ ID_VENDOR_FROM_DATABASE=Veho
+
+usb:v1A1Dp0407*
+ ID_PRODUCT_FROM_DATABASE=Mimi WiFi speakers
+
+usb:v1A25*
+ ID_VENDOR_FROM_DATABASE=Amphenol East Asia Ltd.
+
+usb:v1A2A*
+ ID_VENDOR_FROM_DATABASE=Seagate Branded Solutions
+
+usb:v1A2C*
+ ID_VENDOR_FROM_DATABASE=China Resource Semico Co., Ltd
+
+usb:v1A2Cp0021*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v1A2Cp0024*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard
+
+usb:v1A32*
+ ID_VENDOR_FROM_DATABASE=Quanta Microsystems, Inc.
+
+usb:v1A32p0304*
+ ID_PRODUCT_FROM_DATABASE=802.11n Wireless LAN Card
+
+usb:v1A34*
+ ID_VENDOR_FROM_DATABASE=ACRUX
+
+usb:v1A34p0802*
+ ID_PRODUCT_FROM_DATABASE=Gamepad
+
+usb:v1A36*
+ ID_VENDOR_FROM_DATABASE=Biwin Technology Ltd.
+
+usb:v1A40*
+ ID_VENDOR_FROM_DATABASE=Terminus Technology Inc.
+
+usb:v1A40p0101*
+ ID_PRODUCT_FROM_DATABASE=4-Port HUB
+
+usb:v1A40p0201*
+ ID_PRODUCT_FROM_DATABASE=FE 2.1 7-port Hub
+
+usb:v1A41*
+ ID_VENDOR_FROM_DATABASE=Action Electronics Co., Ltd.
+
+usb:v1A44*
+ ID_VENDOR_FROM_DATABASE=VASCO Data Security International
+
+usb:v1A44p0001*
+ ID_PRODUCT_FROM_DATABASE=Digipass 905 SmartCard Reader
+
+usb:v1A4A*
+ ID_VENDOR_FROM_DATABASE=Silicon Image
+
+usb:v1A4B*
+ ID_VENDOR_FROM_DATABASE=SafeBoot International B.V.
+
+usb:v1A5A*
+ ID_VENDOR_FROM_DATABASE=Tandberg Data
+
+usb:v1A61*
+ ID_VENDOR_FROM_DATABASE=Abbott Diabetes Care
+
+usb:v1A61p3410*
+ ID_PRODUCT_FROM_DATABASE=CoPilot System Cable
+
+usb:v1A6A*
+ ID_VENDOR_FROM_DATABASE=Spansion Inc.
+
+usb:v1A6D*
+ ID_VENDOR_FROM_DATABASE=SamYoung Electronics Co., Ltd
+
+usb:v1A6E*
+ ID_VENDOR_FROM_DATABASE=Global Unichip Corp.
+
+usb:v1A6F*
+ ID_VENDOR_FROM_DATABASE=Sagem Orga GmbH
+
+usb:v1A72*
+ ID_VENDOR_FROM_DATABASE=Physik Instrumente
+
+usb:v1A72p1008*
+ ID_PRODUCT_FROM_DATABASE=E-861 PiezoWalk NEXACT Controller
+
+usb:v1A79*
+ ID_VENDOR_FROM_DATABASE=Bayer Health Care LLC
+
+usb:v1A7B*
+ ID_VENDOR_FROM_DATABASE=Lumberg Connect  GmbH & Co. KG
+
+usb:v1A7C*
+ ID_VENDOR_FROM_DATABASE=Evoluent
+
+usb:v1A7Cp0068*
+ ID_PRODUCT_FROM_DATABASE=VerticalMouse 3
+
+usb:v1A7Cp0168*
+ ID_PRODUCT_FROM_DATABASE=VerticalMouse 3 Wireless
+
+usb:v1A7Cp0191*
+ ID_PRODUCT_FROM_DATABASE=VerticalMouse 4
+
+usb:v1A81*
+ ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc.
+
+usb:v1A81p2203*
+ ID_PRODUCT_FROM_DATABASE=Laser Gaming mouse
+
+usb:v1A81p2204*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v1A81p2205*
+ ID_PRODUCT_FROM_DATABASE=Laser Mouse
+
+usb:v1A86*
+ ID_VENDOR_FROM_DATABASE=QinHeng Electronics
+
+usb:v1A86p5523*
+ ID_PRODUCT_FROM_DATABASE=CH341 in serial mode, usb to serial port converter
+
+usb:v1A86p5584*
+ ID_PRODUCT_FROM_DATABASE=CH341 in parallel mode, usb to printer port converter
+
+usb:v1A86p7523*
+ ID_PRODUCT_FROM_DATABASE=HL-340 USB-Serial adapter
+
+usb:v1A86p752D*
+ ID_PRODUCT_FROM_DATABASE=CH345 MIDI adapter
+
+usb:v1A86p7584*
+ ID_PRODUCT_FROM_DATABASE=CH340S
+
+usb:v1A86pE008*
+ ID_PRODUCT_FROM_DATABASE=HID-based serial adapater
+
+usb:v1A89*
+ ID_VENDOR_FROM_DATABASE=Dynalith Systems Co., Ltd.
+
+usb:v1A8B*
+ ID_VENDOR_FROM_DATABASE=SGS Taiwan Ltd.
+
+usb:v1A8D*
+ ID_VENDOR_FROM_DATABASE=BandRich, Inc.
+
+usb:v1A8Dp1002*
+ ID_PRODUCT_FROM_DATABASE=BandLuxe 3.5G HSDPA Adapter
+
+usb:v1A8Dp1009*
+ ID_PRODUCT_FROM_DATABASE=BandLuxe 3.5G HSPA Adapter
+
+usb:v1A8Dp100D*
+ ID_PRODUCT_FROM_DATABASE=4G LTE adapter
+
+usb:v1A98*
+ ID_VENDOR_FROM_DATABASE=Leica Camera AG
+
+usb:v1AA4*
+ ID_VENDOR_FROM_DATABASE=Data Drive Thru, Inc.
+
+usb:v1AA5*
+ ID_VENDOR_FROM_DATABASE=UBeacon Technologies, Inc.
+
+usb:v1AA6*
+ ID_VENDOR_FROM_DATABASE=eFortune Technology Corp.
+
+usb:v1AAD*
+ ID_VENDOR_FROM_DATABASE=KeeTouch
+
+usb:v1AADp0001*
+ ID_PRODUCT_FROM_DATABASE=Touchscreen
+
+usb:v1AB1*
+ ID_VENDOR_FROM_DATABASE=Rigol Technologies
+
+usb:v1AB1p0588*
+ ID_PRODUCT_FROM_DATABASE=DS1000 SERIES
+
+usb:v1ACB*
+ ID_VENDOR_FROM_DATABASE=Salcomp Plc
+
+usb:v1AD1*
+ ID_VENDOR_FROM_DATABASE=Desay Wire Co., Ltd.
+
+usb:v1AD4*
+ ID_VENDOR_FROM_DATABASE=APS
+
+usb:v1AD4p0002*
+ ID_PRODUCT_FROM_DATABASE=KM290-HRS
+
+usb:v1ADB*
+ ID_VENDOR_FROM_DATABASE=SEL C662 Serial Cable
+
+usb:v1AE4*
+ ID_VENDOR_FROM_DATABASE=ic-design Reinhard Gottinger GmbH
+
+usb:v1AE7*
+ ID_VENDOR_FROM_DATABASE=X-TENSIONS
+
+usb:v1AE7p0381*
+ ID_PRODUCT_FROM_DATABASE=VS-DVB-T 380U (af9015 based)
+
+usb:v1AE7p2001*
+ ID_PRODUCT_FROM_DATABASE=SpeedLink SL-6825
+
+usb:v1AED*
+ ID_VENDOR_FROM_DATABASE=High Top Precision Electronic Co., Ltd.
+
+usb:v1AEF*
+ ID_VENDOR_FROM_DATABASE=Conntech Electronic (Suzhou) Corporation
+
+usb:v1AF1*
+ ID_VENDOR_FROM_DATABASE=Connect One Ltd.
+
+usb:v1AFE*
+ ID_VENDOR_FROM_DATABASE=A. Eberle GmbH & Co. KG
+
+usb:v1AFEp0001*
+ ID_PRODUCT_FROM_DATABASE=PQ Box 100
+
+usb:v1B04*
+ ID_VENDOR_FROM_DATABASE=Meilhaus Electronic GmbH
+
+usb:v1B04p0630*
+ ID_PRODUCT_FROM_DATABASE=ME-630
+
+usb:v1B04p0940*
+ ID_PRODUCT_FROM_DATABASE=ME-94
+
+usb:v1B04p0950*
+ ID_PRODUCT_FROM_DATABASE=ME-95
+
+usb:v1B04p0960*
+ ID_PRODUCT_FROM_DATABASE=ME-96
+
+usb:v1B04p1000*
+ ID_PRODUCT_FROM_DATABASE=ME-1000
+
+usb:v1B04p100A*
+ ID_PRODUCT_FROM_DATABASE=ME-1000
+
+usb:v1B04p100B*
+ ID_PRODUCT_FROM_DATABASE=ME-1000
+
+usb:v1B04p1400*
+ ID_PRODUCT_FROM_DATABASE=ME-1400
+
+usb:v1B04p140A*
+ ID_PRODUCT_FROM_DATABASE=ME-1400A
+
+usb:v1B04p140B*
+ ID_PRODUCT_FROM_DATABASE=ME-1400B
+
+usb:v1B04p140C*
+ ID_PRODUCT_FROM_DATABASE=ME-1400C
+
+usb:v1B04p140D*
+ ID_PRODUCT_FROM_DATABASE=ME-1400D
+
+usb:v1B04p140E*
+ ID_PRODUCT_FROM_DATABASE=ME-1400E
+
+usb:v1B04p14EA*
+ ID_PRODUCT_FROM_DATABASE=ME-1400EA
+
+usb:v1B04p14EB*
+ ID_PRODUCT_FROM_DATABASE=ME-1400EB
+
+usb:v1B04p1604*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/4U
+
+usb:v1B04p1608*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/8U
+
+usb:v1B04p160C*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/12U
+
+usb:v1B04p160F*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/16U
+
+usb:v1B04p168F*
+ ID_PRODUCT_FROM_DATABASE=ME-1600/16U8I
+
+usb:v1B04p4610*
+ ID_PRODUCT_FROM_DATABASE=ME-4610
+
+usb:v1B04p4650*
+ ID_PRODUCT_FROM_DATABASE=ME-4650
+
+usb:v1B04p4660*
+ ID_PRODUCT_FROM_DATABASE=ME-4660
+
+usb:v1B04p4661*
+ ID_PRODUCT_FROM_DATABASE=ME-4660I
+
+usb:v1B04p4662*
+ ID_PRODUCT_FROM_DATABASE=ME-4660
+
+usb:v1B04p4663*
+ ID_PRODUCT_FROM_DATABASE=ME-4660I
+
+usb:v1B04p4670*
+ ID_PRODUCT_FROM_DATABASE=ME-4670
+
+usb:v1B04p4671*
+ ID_PRODUCT_FROM_DATABASE=ME-4670I
+
+usb:v1B04p4672*
+ ID_PRODUCT_FROM_DATABASE=ME-4670S
+
+usb:v1B04p4673*
+ ID_PRODUCT_FROM_DATABASE=ME-4670IS
+
+usb:v1B04p4680*
+ ID_PRODUCT_FROM_DATABASE=ME-4680
+
+usb:v1B04p4681*
+ ID_PRODUCT_FROM_DATABASE=ME-4680I
+
+usb:v1B04p4682*
+ ID_PRODUCT_FROM_DATABASE=ME-4680S
+
+usb:v1B04p4683*
+ ID_PRODUCT_FROM_DATABASE=ME-4680IS
+
+usb:v1B04p6004*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/4
+
+usb:v1B04p6008*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/8
+
+usb:v1B04p600F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/16
+
+usb:v1B04p6014*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/4
+
+usb:v1B04p6018*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/8
+
+usb:v1B04p601F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/16
+
+usb:v1B04p6034*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/4
+
+usb:v1B04p6038*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/8
+
+usb:v1B04p603F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/16
+
+usb:v1B04p6044*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/4/DIO
+
+usb:v1B04p6048*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/8/DIO
+
+usb:v1B04p604F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000/16/DIO
+
+usb:v1B04p6054*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/4/DIO
+
+usb:v1B04p6058*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/8/DIO
+
+usb:v1B04p605F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000I/16/DIO
+
+usb:v1B04p6074*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/4/DIO
+
+usb:v1B04p6078*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/8/DIO
+
+usb:v1B04p607F*
+ ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/16/DIO
+
+usb:v1B04p6104*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/4
+
+usb:v1B04p6108*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/8
+
+usb:v1B04p610F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/16
+
+usb:v1B04p6114*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/4
+
+usb:v1B04p6118*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/8
+
+usb:v1B04p611F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/16
+
+usb:v1B04p6134*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/4
+
+usb:v1B04p6138*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/8
+
+usb:v1B04p613F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/16
+
+usb:v1B04p6144*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/4/DIO
+
+usb:v1B04p6148*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/8/DIO
+
+usb:v1B04p614F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100/16/DIO
+
+usb:v1B04p6154*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/4/DIO
+
+usb:v1B04p6158*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/8/DIO
+
+usb:v1B04p615F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100I/16/DIO
+
+usb:v1B04p6174*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/4/DIO
+
+usb:v1B04p6178*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/8/DIO
+
+usb:v1B04p617F*
+ ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/16/DIO
+
+usb:v1B04p6259*
+ ID_PRODUCT_FROM_DATABASE=ME-6200I/9/DIO
+
+usb:v1B04p6359*
+ ID_PRODUCT_FROM_DATABASE=ME-6300I/9/DIO
+
+usb:v1B04p810A*
+ ID_PRODUCT_FROM_DATABASE=ME-8100A
+
+usb:v1B04p810B*
+ ID_PRODUCT_FROM_DATABASE=ME-8100B
+
+usb:v1B04p820A*
+ ID_PRODUCT_FROM_DATABASE=ME-8200A
+
+usb:v1B04p820B*
+ ID_PRODUCT_FROM_DATABASE=ME-8200B
+
+usb:v1B0E*
+ ID_VENDOR_FROM_DATABASE=BLUTRONICS S.r.l.
+
+usb:v1B0Ep1078*
+ ID_PRODUCT_FROM_DATABASE=BLUDRIVE II CCID
+
+usb:v1B0Ep1079*
+ ID_PRODUCT_FROM_DATABASE=BLUDRIVE II CCID
+
+usb:v1B0Ep1080*
+ ID_PRODUCT_FROM_DATABASE=WRITECHIP II CCID
+
+usb:v1B1C*
+ ID_VENDOR_FROM_DATABASE=Corsair
+
+usb:v1B1Cp0890*
+ ID_PRODUCT_FROM_DATABASE=Flash Padlock
+
+usb:v1B1Cp0A00*
+ ID_PRODUCT_FROM_DATABASE=SP2500 Speakers
+
+usb:v1B1Cp0A60*
+ ID_PRODUCT_FROM_DATABASE=Vengeance K60 Keyboard
+
+usb:v1B1Cp1A01*
+ ID_PRODUCT_FROM_DATABASE=Flash Voyager GT
+
+usb:v1B1Cp1A0A*
+ ID_PRODUCT_FROM_DATABASE=Survivor Stealth Flash Drive
+
+usb:v1B1Cp1A90*
+ ID_PRODUCT_FROM_DATABASE=Flash Voyager GT
+
+usb:v1B20*
+ ID_VENDOR_FROM_DATABASE=MStar Semiconductor, Inc.
+
+usb:v1B22*
+ ID_VENDOR_FROM_DATABASE=WiLinx Corp.
+
+usb:v1B26*
+ ID_VENDOR_FROM_DATABASE=Cellex Power Products, Inc.
+
+usb:v1B27*
+ ID_VENDOR_FROM_DATABASE=Current Electronics Inc.
+
+usb:v1B28*
+ ID_VENDOR_FROM_DATABASE=NAVIsis Inc.
+
+usb:v1B32*
+ ID_VENDOR_FROM_DATABASE=Ugobe Life Forms, Inc.
+
+usb:v1B32p0064*
+ ID_PRODUCT_FROM_DATABASE=Pleo robotic dinosaur
+
+usb:v1B36*
+ ID_VENDOR_FROM_DATABASE=ViXS Systems, Inc.
+
+usb:v1B3B*
+ ID_VENDOR_FROM_DATABASE=iPassion Technology Inc.
+
+usb:v1B3Bp2933*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2935*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2936*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2937*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2938*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2939*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2950*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2951*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2952*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2953*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2955*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2956*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2957*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2958*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2959*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2960*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2961*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2962*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2963*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2965*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2966*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2967*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2968*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3Bp2969*
+ ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller
+
+usb:v1B3F*
+ ID_VENDOR_FROM_DATABASE=Generalplus Technology Inc.
+
+usb:v1B3Fp0C52*
+ ID_PRODUCT_FROM_DATABASE=808 Camera #9 (mass storage mode)
+
+usb:v1B3Fp2002*
+ ID_PRODUCT_FROM_DATABASE=808 Camera #9 (web-cam mode)
+
+usb:v1B47*
+ ID_VENDOR_FROM_DATABASE=Energizer Holdings, Inc.
+
+usb:v1B47p0001*
+ ID_PRODUCT_FROM_DATABASE=CHUSB Duo Charger (NiMH AA/AAA USB smart charger)
+
+usb:v1B48*
+ ID_VENDOR_FROM_DATABASE=Plastron Precision Co., Ltd.
+
+usb:v1B59*
+ ID_VENDOR_FROM_DATABASE=K.S. Terminals Inc.
+
+usb:v1B5A*
+ ID_VENDOR_FROM_DATABASE=Chao Zhou Kai Yuan Electric Co., Ltd.
+
+usb:v1B65*
+ ID_VENDOR_FROM_DATABASE=The Hong Kong Standards and Testing Centre Ltd.
+
+usb:v1B72*
+ ID_VENDOR_FROM_DATABASE=ATERGI TECHNOLOGY CO., LTD.
+
+usb:v1B73*
+ ID_VENDOR_FROM_DATABASE=Fresco Logic
+
+usb:v1B73p1000*
+ ID_PRODUCT_FROM_DATABASE=xHC1 Controller
+
+usb:v1B75*
+ ID_VENDOR_FROM_DATABASE=Ovislink Corp.
+
+usb:v1B75p3072*
+ ID_PRODUCT_FROM_DATABASE=AirLive WN-360USB adapter
+
+usb:v1B75p8171*
+ ID_PRODUCT_FROM_DATABASE=WN-370USB 802.11bgn Wireless Adapter [Realtek RTL8188SU]
+
+usb:v1B75p8187*
+ ID_PRODUCT_FROM_DATABASE=AirLive WL-1600USB 802.11g Adapter [Realtek RTL8187L]
+
+usb:v1B75p9170*
+ ID_PRODUCT_FROM_DATABASE=AirLive X.USB 802.11abgn [Atheros AR9170+AR9104]
+
+usb:v1B75pA200*
+ ID_PRODUCT_FROM_DATABASE=AirLive WN-200USB wireless 11b/g/n dongle
+
+usb:v1B76*
+ ID_VENDOR_FROM_DATABASE=Legend Silicon Corp.
+
+usb:v1B80*
+ ID_VENDOR_FROM_DATABASE=Afatech
+
+usb:v1B80pC810*
+ ID_PRODUCT_FROM_DATABASE=MC810 [af9015]
+
+usb:v1B80pD393*
+ ID_PRODUCT_FROM_DATABASE=DVB-T receiver [RTL2832U]
+
+usb:v1B80pD396*
+ ID_PRODUCT_FROM_DATABASE=UB396-T [RTL2832U]
+
+usb:v1B80pD397*
+ ID_PRODUCT_FROM_DATABASE=DVB-T receiver [RTL2832U]
+
+usb:v1B80pD398*
+ ID_PRODUCT_FROM_DATABASE=DVB-T receiver [RTL2832U]
+
+usb:v1B80pD700*
+ ID_PRODUCT_FROM_DATABASE=FM Radio SnapMusic Mobile 700 (FM700)
+
+usb:v1B80pE297*
+ ID_PRODUCT_FROM_DATABASE=Conceptronic DVB-T CTVDIGRCU V3.0
+
+usb:v1B80pE383*
+ ID_PRODUCT_FROM_DATABASE=DVB-T UB383-T [af9015]
+
+usb:v1B80pE385*
+ ID_PRODUCT_FROM_DATABASE=DVB-T UB385-T [af9015]
+
+usb:v1B80pE386*
+ ID_PRODUCT_FROM_DATABASE=DVB-T UB385-T [af9015]
+
+usb:v1B80pE399*
+ ID_PRODUCT_FROM_DATABASE=DVB-T KWorld PlusTV 399U [af9015]
+
+usb:v1B80pE39A*
+ ID_PRODUCT_FROM_DATABASE=DVB-T395U [af9015]
+
+usb:v1B80pE39B*
+ ID_PRODUCT_FROM_DATABASE=DVB-T395U [af9015]
+
+usb:v1B80pE401*
+ ID_PRODUCT_FROM_DATABASE=Sveon STV22 DVB-T [af9015]
+
+usb:v1B80pE409*
+ ID_PRODUCT_FROM_DATABASE=IT9137FN Dual DVB-T [KWorld UB499-2T]
+
+usb:v1B86*
+ ID_VENDOR_FROM_DATABASE=Dongguan Guanshang Electronics Co., Ltd.
+
+usb:v1B88*
+ ID_VENDOR_FROM_DATABASE=ShenMing Electron (Dong Guan) Co., Ltd.
+
+usb:v1B8C*
+ ID_VENDOR_FROM_DATABASE=Altium Limited
+
+usb:v1B8D*
+ ID_VENDOR_FROM_DATABASE=e-MOVE Technology Co., Ltd.
+
+usb:v1B8E*
+ ID_VENDOR_FROM_DATABASE=Amlogic, Inc.
+
+usb:v1B8F*
+ ID_VENDOR_FROM_DATABASE=MA LABS, Inc.
+
+usb:v1B96*
+ ID_VENDOR_FROM_DATABASE=N-Trig
+
+usb:v1B96p0001*
+ ID_PRODUCT_FROM_DATABASE=Duosense Transparent Electromagnetic Digitizer
+
+usb:v1B98*
+ ID_VENDOR_FROM_DATABASE=YMax Communications Corp.
+
+usb:v1B99*
+ ID_VENDOR_FROM_DATABASE=Shenzhen Yuanchuan Electronic
+
+usb:v1BA1*
+ ID_VENDOR_FROM_DATABASE=JINQ CHERN ENTERPRISE CO., LTD.
+
+usb:v1BA2*
+ ID_VENDOR_FROM_DATABASE=Lite Metals & Plastic (Shenzhen) Co., Ltd.
+
+usb:v1BA4*
+ ID_VENDOR_FROM_DATABASE=Ember Corporation
+
+usb:v1BA4p0001*
+ ID_PRODUCT_FROM_DATABASE=InSight USB Link
+
+usb:v1BA6*
+ ID_VENDOR_FROM_DATABASE=Abilis Systems
+
+usb:v1BA8*
+ ID_VENDOR_FROM_DATABASE=China Telecommunication Technology Labs
+
+usb:v1BAD*
+ ID_VENDOR_FROM_DATABASE=Harmonix Music
+
+usb:v1BADp0002*
+ ID_PRODUCT_FROM_DATABASE=Guitar for Xbox 360
+
+usb:v1BADp0003*
+ ID_PRODUCT_FROM_DATABASE=Drum Kit for Xbox 360
+
+usb:v1BAE*
+ ID_VENDOR_FROM_DATABASE=Vuzix Corporation
+
+usb:v1BAEp0002*
+ ID_PRODUCT_FROM_DATABASE=VR920 Immersive Eyewear
+
+usb:v1BBB*
+ ID_VENDOR_FROM_DATABASE=T & A Mobile Phones
+
+usb:v1BC4*
+ ID_VENDOR_FROM_DATABASE=Ford Motor Co.
+
+usb:v1BC5*
+ ID_VENDOR_FROM_DATABASE=AVIXE Technology (China) Ltd.
+
+usb:v1BC7*
+ ID_VENDOR_FROM_DATABASE=Telit
+
+usb:v1BC7p0020*
+ ID_PRODUCT_FROM_DATABASE=HE863
+
+usb:v1BC7p1003*
+ ID_PRODUCT_FROM_DATABASE=UC864-E
+
+usb:v1BC7p1004*
+ ID_PRODUCT_FROM_DATABASE=UC864-G
+
+usb:v1BC7p1005*
+ ID_PRODUCT_FROM_DATABASE=CC864-DUAL
+
+usb:v1BC7p1006*
+ ID_PRODUCT_FROM_DATABASE=CC864-SINGLE
+
+usb:v1BC7p1010*
+ ID_PRODUCT_FROM_DATABASE=DE910-DUAL
+
+usb:v1BCE*
+ ID_VENDOR_FROM_DATABASE=Contac Cable Industrial Limited
+
+usb:v1BCF*
+ ID_VENDOR_FROM_DATABASE=Sunplus Innovation Technology Inc.
+
+usb:v1BCFp0007*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v1BCFp053A*
+ ID_PRODUCT_FROM_DATABASE=Targa Silvercrest OMC807-C optische Funkmaus
+
+usb:v1BCFp05C5*
+ ID_PRODUCT_FROM_DATABASE=SPRF2413A [2.4GHz Wireless Keyboard/Mouse Receiver]
+
+usb:v1BCFp05CF*
+ ID_PRODUCT_FROM_DATABASE=Micro keyboard & mouse receiver
+
+usb:v1BCFp0C31*
+ ID_PRODUCT_FROM_DATABASE=SPIF30x Serial-ATA bridge
+
+usb:v1BCFp2888*
+ ID_PRODUCT_FROM_DATABASE=HP Universal Camera
+
+usb:v1BD0*
+ ID_VENDOR_FROM_DATABASE=Hangzhou Riyue Electronic Co., Ltd.
+
+usb:v1BD5*
+ ID_VENDOR_FROM_DATABASE=BG Systems, Inc.
+
+usb:v1BDE*
+ ID_VENDOR_FROM_DATABASE=P-TWO INDUSTRIES, INC.
+
+usb:v1BEF*
+ ID_VENDOR_FROM_DATABASE=Shenzhen Tongyuan Network-Communication Cables Co., Ltd
+
+usb:v1BF0*
+ ID_VENDOR_FROM_DATABASE=RealVision Inc.
+
+usb:v1BF5*
+ ID_VENDOR_FROM_DATABASE=Extranet Systems Inc.
+
+usb:v1BF6*
+ ID_VENDOR_FROM_DATABASE=Orient Semiconductor Electronics, Ltd.
+
+usb:v1BFD*
+ ID_VENDOR_FROM_DATABASE=TouchPack
+
+usb:v1BFDp1268*
+ ID_PRODUCT_FROM_DATABASE=Touch Screen
+
+usb:v1BFDp1368*
+ ID_PRODUCT_FROM_DATABASE=Touch Screen
+
+usb:v1BFDp1568*
+ ID_PRODUCT_FROM_DATABASE=Capacitive Touch Screen
+
+usb:v1BFDp1668*
+ ID_PRODUCT_FROM_DATABASE=IR Touch Screen
+
+usb:v1BFDp1688*
+ ID_PRODUCT_FROM_DATABASE=Resistive Touch Screen
+
+usb:v1BFDp2968*
+ ID_PRODUCT_FROM_DATABASE=Touch Screen
+
+usb:v1BFDp5968*
+ ID_PRODUCT_FROM_DATABASE=Touch Screen
+
+usb:v1BFDp6968*
+ ID_PRODUCT_FROM_DATABASE=Touch Screen
+
+usb:v1C02*
+ ID_VENDOR_FROM_DATABASE=Kreton Corporation
+
+usb:v1C04*
+ ID_VENDOR_FROM_DATABASE=QNAP System Inc.
+
+usb:v1C0C*
+ ID_VENDOR_FROM_DATABASE=Ionics EMS, Inc.
+
+usb:v1C0Cp0102*
+ ID_PRODUCT_FROM_DATABASE=Plug Computer
+
+usb:v1C0D*
+ ID_VENDOR_FROM_DATABASE=Relm Wireless
+
+usb:v1C10*
+ ID_VENDOR_FROM_DATABASE=Lanterra Industrial Co., Ltd.
+
+usb:v1C13*
+ ID_VENDOR_FROM_DATABASE=ALECTRONIC LIMITED
+
+usb:v1C1A*
+ ID_VENDOR_FROM_DATABASE=Datel Electronics Ltd.
+
+usb:v1C1B*
+ ID_VENDOR_FROM_DATABASE=Volkswagen of America, Inc.
+
+usb:v1C1F*
+ ID_VENDOR_FROM_DATABASE=Goldvish S.A.
+
+usb:v1C20*
+ ID_VENDOR_FROM_DATABASE=Fuji Electric Device Technology Co., Ltd.
+
+usb:v1C21*
+ ID_VENDOR_FROM_DATABASE=ADDMM LLC
+
+usb:v1C22*
+ ID_VENDOR_FROM_DATABASE=ZHONGSHAN CHIANG YU ELECTRIC CO., LTD.
+
+usb:v1C26*
+ ID_VENDOR_FROM_DATABASE=Shanghai Haiying Electronics Co., Ltd.
+
+usb:v1C27*
+ ID_VENDOR_FROM_DATABASE=HuiYang D & S Cable Co., Ltd.
+
+usb:v1C31*
+ ID_VENDOR_FROM_DATABASE=LS Cable Ltd.
+
+usb:v1C34*
+ ID_VENDOR_FROM_DATABASE=SpringCard
+
+usb:v1C34p7241*
+ ID_PRODUCT_FROM_DATABASE=Prox'N'Roll RFID Scanner
+
+usb:v1C37*
+ ID_VENDOR_FROM_DATABASE=Authorizer Technologies, Inc.
+
+usb:v1C3D*
+ ID_VENDOR_FROM_DATABASE=NONIN MEDICAL INC.
+
+usb:v1C3E*
+ ID_VENDOR_FROM_DATABASE=Wep Peripherals
+
+usb:v1C40*
+ ID_VENDOR_FROM_DATABASE=EZPrototypes
+
+usb:v1C40p0533*
+ ID_PRODUCT_FROM_DATABASE=TiltStick
+
+usb:v1C40p0534*
+ ID_PRODUCT_FROM_DATABASE=i2c-tiny-usb interface
+
+usb:v1C40p0535*
+ ID_PRODUCT_FROM_DATABASE=glcd2usb interface
+
+usb:v1C40p0536*
+ ID_PRODUCT_FROM_DATABASE=Swiss ColorPAL
+
+usb:v1C49*
+ ID_VENDOR_FROM_DATABASE=Cherng Weei Technology Corp.
+
+usb:v1C4F*
+ ID_VENDOR_FROM_DATABASE=SiGma Micro
+
+usb:v1C4Fp0002*
+ ID_PRODUCT_FROM_DATABASE=Keyboard TRACER Gamma Ivory
+
+usb:v1C4Fp0003*
+ ID_PRODUCT_FROM_DATABASE=HID controller
+
+usb:v1C4Fp000E*
+ ID_PRODUCT_FROM_DATABASE=Genius KB-120 Keyboard
+
+usb:v1C4Fp3000*
+ ID_PRODUCT_FROM_DATABASE=Micro USB Web Camera
+
+usb:v1C6B*
+ ID_VENDOR_FROM_DATABASE=Philips & Lite-ON Digital Solutions Corporation
+
+usb:v1C6BpA222*
+ ID_PRODUCT_FROM_DATABASE=DVD Writer Slimtype eTAU108
+
+usb:v1C6C*
+ ID_VENDOR_FROM_DATABASE=Skydigital Inc.
+
+usb:v1C73*
+ ID_VENDOR_FROM_DATABASE=AMT
+
+usb:v1C73p861F*
+ ID_PRODUCT_FROM_DATABASE=Anysee E30 USB 2.0 DVB-T Receiver
+
+usb:v1C77*
+ ID_VENDOR_FROM_DATABASE=Kaetat Industrial Co., Ltd.
+
+usb:v1C78*
+ ID_VENDOR_FROM_DATABASE=Datascope Corp.
+
+usb:v1C79*
+ ID_VENDOR_FROM_DATABASE=Unigen Corporation
+
+usb:v1C7A*
+ ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc.
+
+usb:v1C7Ap0801*
+ ID_PRODUCT_FROM_DATABASE=Fingerprint Reader
+
+usb:v1C7B*
+ ID_VENDOR_FROM_DATABASE=LUXSHARE PRECISION INDUSTRY (SHENZHEN) CO., LTD.
+
+usb:v1C87*
+ ID_VENDOR_FROM_DATABASE=2N TELEKOMUNIKACE a.s.
+
+usb:v1C88*
+ ID_VENDOR_FROM_DATABASE=Somagic, Inc.
+
+usb:v1C88p0007*
+ ID_PRODUCT_FROM_DATABASE=SMI Grabber (EasyCAP DC60+ clone) (no firmware) [SMI-2021CBE]
+
+usb:v1C88p003C*
+ ID_PRODUCT_FROM_DATABASE=SMI Grabber (EasyCAP DC60+ clone) [SMI-2021CBE]
+
+usb:v1C89*
+ ID_VENDOR_FROM_DATABASE=HONGKONG WEIDIDA ELECTRON LIMITED
+
+usb:v1C8E*
+ ID_VENDOR_FROM_DATABASE=ASTRON INTERNATIONAL CORP.
+
+usb:v1C98*
+ ID_VENDOR_FROM_DATABASE=ALPINE ELECTRONICS, INC.
+
+usb:v1C9E*
+ ID_VENDOR_FROM_DATABASE=OMEGA TECHNOLOGY
+
+usb:v1C9Ep6061*
+ ID_PRODUCT_FROM_DATABASE=WL-72B 3.5G MODEM
+
+usb:v1CA0*
+ ID_VENDOR_FROM_DATABASE=ACCARIO Inc.
+
+usb:v1CA1*
+ ID_VENDOR_FROM_DATABASE=Symwave
+
+usb:v1CA1p18AB*
+ ID_PRODUCT_FROM_DATABASE=SATA bridge
+
+usb:v1CAC*
+ ID_VENDOR_FROM_DATABASE=Kinstone
+
+usb:v1CACpA332*
+ ID_PRODUCT_FROM_DATABASE=C8 Webcam
+
+usb:v1CACpB288*
+ ID_PRODUCT_FROM_DATABASE=C18 Webcam
+
+usb:v1CB3*
+ ID_VENDOR_FROM_DATABASE=Aces Electronic Co., Ltd.
+
+usb:v1CB4*
+ ID_VENDOR_FROM_DATABASE=OPEX CORPORATION
+
+usb:v1CBE*
+ ID_VENDOR_FROM_DATABASE=Luminary Micro Inc.
+
+usb:v1CBEp00FD*
+ ID_PRODUCT_FROM_DATABASE=In-Circuit Debug Interface
+
+usb:v1CBEp00FF*
+ ID_PRODUCT_FROM_DATABASE=Stellaris ROM DFU Bootloader
+
+usb:v1CBF*
+ ID_VENDOR_FROM_DATABASE=FORTAT SKYMARK INDUSTRIAL COMPANY
+
+usb:v1CC0*
+ ID_VENDOR_FROM_DATABASE=PlantSense
+
+usb:v1CCA*
+ ID_VENDOR_FROM_DATABASE=NextWave Broadband Inc.
+
+usb:v1CCD*
+ ID_VENDOR_FROM_DATABASE=Bodatong Technology (Shenzhen) Co., Ltd.
+
+usb:v1CD4*
+ ID_VENDOR_FROM_DATABASE=adp corporation
+
+usb:v1CD5*
+ ID_VENDOR_FROM_DATABASE=Firecomms Ltd.
+
+usb:v1CD6*
+ ID_VENDOR_FROM_DATABASE=Antonio Precise Products Manufactory Ltd.
+
+usb:v1CDE*
+ ID_VENDOR_FROM_DATABASE=Telecommunications Technology Association (TTA)
+
+usb:v1CDF*
+ ID_VENDOR_FROM_DATABASE=WonTen Technology Co., Ltd.
+
+usb:v1CE0*
+ ID_VENDOR_FROM_DATABASE=EDIMAX TECHNOLOGY CO., LTD.
+
+usb:v1CE1*
+ ID_VENDOR_FROM_DATABASE=Amphenol KAE
+
+usb:v1CF1*
+ ID_VENDOR_FROM_DATABASE=Dresden Elektronik
+
+usb:v1CF1p0001*
+ ID_PRODUCT_FROM_DATABASE=Sensor Terminal Board
+
+usb:v1CF1p0004*
+ ID_PRODUCT_FROM_DATABASE=Wireless Handheld Terminal
+
+usb:v1CF1p0017*
+ ID_PRODUCT_FROM_DATABASE=deRFusbSniffer 2.4 GHz
+
+usb:v1CF1p0018*
+ ID_PRODUCT_FROM_DATABASE=deRFusb24E001
+
+usb:v1CF1p0019*
+ ID_PRODUCT_FROM_DATABASE=deRFusb14E001
+
+usb:v1CF1p001A*
+ ID_PRODUCT_FROM_DATABASE=deRFusb23E00
+
+usb:v1CF1p001B*
+ ID_PRODUCT_FROM_DATABASE=deRFusb13E00
+
+usb:v1CF1p001C*
+ ID_PRODUCT_FROM_DATABASE=deRFnode
+
+usb:v1CF1p001D*
+ ID_PRODUCT_FROM_DATABASE=deRFnode / gateway
+
+usb:v1CF1p0022*
+ ID_PRODUCT_FROM_DATABASE=deUSB level shifter
+
+usb:v1CF1p0023*
+ ID_PRODUCT_FROM_DATABASE=deRFusbSniffer Sub-GHz
+
+usb:v1CF1p0025*
+ ID_PRODUCT_FROM_DATABASE=deRFusb23E06
+
+usb:v1CF1p0027*
+ ID_PRODUCT_FROM_DATABASE=deRFusb13E06
+
+usb:v1CFC*
+ ID_VENDOR_FROM_DATABASE=ANDES TECHNOLOGY CORPORATION
+
+usb:v1CFD*
+ ID_VENDOR_FROM_DATABASE=Flextronics Digital Design Japan, LTD.
+
+usb:v1D03*
+ ID_VENDOR_FROM_DATABASE=iCON
+
+usb:v1D03p0028*
+ ID_PRODUCT_FROM_DATABASE=iCreativ MIDI Controller
+
+usb:v1D07*
+ ID_VENDOR_FROM_DATABASE=Solid-Motion
+
+usb:v1D08*
+ ID_VENDOR_FROM_DATABASE=NINGBO HENTEK DRAGON ELECTRONICS CO., LTD.
+
+usb:v1D09*
+ ID_VENDOR_FROM_DATABASE=TechFaith Wireless Technology Limited
+
+usb:v1D09p1026*
+ ID_PRODUCT_FROM_DATABASE=HSUPA Modem FLYING-LARK46-VER0.07 [Flying Angel]
+
+usb:v1D0A*
+ ID_VENDOR_FROM_DATABASE=Johnson Controls, Inc. The Automotive Business Unit
+
+usb:v1D0B*
+ ID_VENDOR_FROM_DATABASE=HAN HUA CABLE & WIRE TECHNOLOGY (J.X.) CO., LTD.
+
+usb:v1D0F*
+ ID_VENDOR_FROM_DATABASE=Sonix Technology Co., Ltd.
+
+usb:v1D14*
+ ID_VENDOR_FROM_DATABASE=ALPHA-SAT TECHNOLOGY LIMITED
+
+usb:v1D17*
+ ID_VENDOR_FROM_DATABASE=C-Thru Music Ltd.
+
+usb:v1D17p0001*
+ ID_PRODUCT_FROM_DATABASE=AXiS-49 Harmonic Table MIDI Keyboard
+
+usb:v1D19*
+ ID_VENDOR_FROM_DATABASE=Dexatek Technology Ltd.
+
+usb:v1D19p1101*
+ ID_PRODUCT_FROM_DATABASE=DK DVB-T Dongle
+
+usb:v1D19p1102*
+ ID_PRODUCT_FROM_DATABASE=DK mini DVB-T Dongle
+
+usb:v1D19p1103*
+ ID_PRODUCT_FROM_DATABASE=DK 5217 DVB-T Dongle
+
+usb:v1D19p6105*
+ ID_PRODUCT_FROM_DATABASE=Video grabber
+
+usb:v1D19p8202*
+ ID_PRODUCT_FROM_DATABASE=DK DVBC/T DONGLE
+
+usb:v1D1F*
+ ID_VENDOR_FROM_DATABASE=Diostech Co., Ltd.
+
+usb:v1D20*
+ ID_VENDOR_FROM_DATABASE=SAMTACK INC.
+
+usb:v1D34*
+ ID_VENDOR_FROM_DATABASE=Dream Cheeky
+
+usb:v1D34p0001*
+ ID_PRODUCT_FROM_DATABASE=Dream Cheeky Fidget
+
+usb:v1D34p0004*
+ ID_PRODUCT_FROM_DATABASE=Dream Cheeky Webmail Notifier
+
+usb:v1D34p0008*
+ ID_PRODUCT_FROM_DATABASE=Dream Cheeky button
+
+usb:v1D34p000A*
+ ID_PRODUCT_FROM_DATABASE=Dream Cheeky Mailbox Friends Alert
+
+usb:v1D34p000D*
+ ID_PRODUCT_FROM_DATABASE=Dream Cheeky Big Red Button
+
+usb:v1D34p0013*
+ ID_PRODUCT_FROM_DATABASE=Dream Cheeky LED Message Board
+
+usb:v1D4D*
+ ID_VENDOR_FROM_DATABASE=PEGATRON CORPORATION
+
+usb:v1D4Dp0002*
+ ID_PRODUCT_FROM_DATABASE=Ralink RT2770/2720 802.11b/g/n Wireless LAN Mini-USB Device
+
+usb:v1D4Dp000C*
+ ID_PRODUCT_FROM_DATABASE=Ralink RT3070 802.11b/g/n Wireless Lan USB Device
+
+usb:v1D4Dp000E*
+ ID_PRODUCT_FROM_DATABASE=Ralink RT3070 802.11b/g/n Wireless Lan USB Device
+
+usb:v1D50*
+ ID_VENDOR_FROM_DATABASE=OpenMoko, Inc.
+
+usb:v1D50p5119*
+ ID_PRODUCT_FROM_DATABASE=GTA01/GTA02 U-Boot Bootloader
+
+usb:v1D57*
+ ID_VENDOR_FROM_DATABASE=Xenta
+
+usb:v1D57p0005*
+ ID_PRODUCT_FROM_DATABASE=Wireless Receiver (Keyboard and Mouse)
+
+usb:v1D57p0006*
+ ID_PRODUCT_FROM_DATABASE=Wireless Receiver (RC Laser Pointer)
+
+usb:v1D57p000C*
+ ID_PRODUCT_FROM_DATABASE=Optical Mouse
+
+usb:v1D57p2400*
+ ID_PRODUCT_FROM_DATABASE=Wireless Mouse Receiver
+
+usb:v1D57p32DA*
+ ID_PRODUCT_FROM_DATABASE=2.4GHz Receiver (Keyboard and Mouse)
+
+usb:v1D57p83D0*
+ ID_PRODUCT_FROM_DATABASE=Click-mouse!
+
+usb:v1D57pAC01*
+ ID_PRODUCT_FROM_DATABASE=Wireless Receiver (Keyboard and Mouse)
+
+usb:v1D57pAF01*
+ ID_PRODUCT_FROM_DATABASE=AUVIO Universal Remote Receiver for PlayStation 3
+
+usb:v1D5B*
+ ID_VENDOR_FROM_DATABASE=Smartronix, Inc.
+
+usb:v1D6B*
+ ID_VENDOR_FROM_DATABASE=Linux Foundation
+
+usb:v1D6Bp0001*
+ ID_PRODUCT_FROM_DATABASE=1.1 root hub
+
+usb:v1D6Bp0002*
+ ID_PRODUCT_FROM_DATABASE=2.0 root hub
+
+usb:v1D6Bp0003*
+ ID_PRODUCT_FROM_DATABASE=3.0 root hub
+
+usb:v1D6Bp0100*
+ ID_PRODUCT_FROM_DATABASE=PTP Gadget
+
+usb:v1D6Bp0101*
+ ID_PRODUCT_FROM_DATABASE=Audio Gadget
+
+usb:v1D6Bp0102*
+ ID_PRODUCT_FROM_DATABASE=EEM Gadget
+
+usb:v1D6Bp0103*
+ ID_PRODUCT_FROM_DATABASE=NCM (Ethernet) Gadget
+
+usb:v1D6Bp0104*
+ ID_PRODUCT_FROM_DATABASE=Multifunction Composite Gadget
+
+usb:v1D6Bp0105*
+ ID_PRODUCT_FROM_DATABASE=FunctionFS Gadget
+
+usb:v1D6Bp0200*
+ ID_PRODUCT_FROM_DATABASE=Qemu Audio Device
+
+usb:v1DE1*
+ ID_VENDOR_FROM_DATABASE=Actions Microelectronics Co.
+
+usb:v1DE1p1101*
+ ID_PRODUCT_FROM_DATABASE=Generic Display Device (Mass storage mode)
+
+usb:v1DE1pC101*
+ ID_PRODUCT_FROM_DATABASE=Generic Display Device
+
+usb:v1E0E*
+ ID_VENDOR_FROM_DATABASE=Qualcomm / Option
+
+usb:v1E0EpF000*
+ ID_PRODUCT_FROM_DATABASE=iCON 210 UMTS Surfstick
+
+usb:v1E10*
+ ID_VENDOR_FROM_DATABASE=Point Grey Research, Inc.
+
+usb:v1E10p2004*
+ ID_PRODUCT_FROM_DATABASE=Sony 1.3MP 1/3" ICX445 IIDC video camera [Chameleon]
+
+usb:v1E17*
+ ID_VENDOR_FROM_DATABASE=Mirion Technologies Dosimetry Services Division
+
+usb:v1E17p0001*
+ ID_PRODUCT_FROM_DATABASE=instadose dosimeter
+
+usb:v1E1D*
+ ID_VENDOR_FROM_DATABASE=Lumension Security
+
+usb:v1E1Dp0165*
+ ID_PRODUCT_FROM_DATABASE=Secure Pen drive
+
+usb:v1E1F*
+ ID_VENDOR_FROM_DATABASE=INVIA
+
+usb:v1E29*
+ ID_VENDOR_FROM_DATABASE=Festo AG & Co. KG
+
+usb:v1E29p0101*
+ ID_PRODUCT_FROM_DATABASE=CPX Adapter
+
+usb:v1E29p0102*
+ ID_PRODUCT_FROM_DATABASE=CPX Adapter >=HW10.09 [CP2102]
+
+usb:v1E29p0401*
+ ID_PRODUCT_FROM_DATABASE=iL3-TP [AT90USB646]
+
+usb:v1E29p0402*
+ ID_PRODUCT_FROM_DATABASE=FTDI232 [EasyPort]
+
+usb:v1E29p0403*
+ ID_PRODUCT_FROM_DATABASE=FTDI232 [EasyPort Mini]
+
+usb:v1E29p0404*
+ ID_PRODUCT_FROM_DATABASE=FTDI232 [Netzteil-GL]
+
+usb:v1E29p0405*
+ ID_PRODUCT_FROM_DATABASE=FTDI232 [MotorPrüfstand]
+
+usb:v1E29p0406*
+ ID_PRODUCT_FROM_DATABASE=STM32F103 [EasyKit]
+
+usb:v1E29p0407*
+ ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino]
+
+usb:v1E29p0408*
+ ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino-Arm]
+
+usb:v1E29p0409*
+ ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino-Arm Bootloader]
+
+usb:v1E29p040A*
+ ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino Bootloader]
+
+usb:v1E29p040B*
+ ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino XT]
+
+usb:v1E29p040C*
+ ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino XT Bootloader]
+
+usb:v1E29p040D*
+ ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino 3]
+
+usb:v1E29p040E*
+ ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino 3 Bootloader]
+
+usb:v1E29p0501*
+ ID_PRODUCT_FROM_DATABASE=CP2102 [CMSP]
+
+usb:v1E29p0601*
+ ID_PRODUCT_FROM_DATABASE=CMMP-AS
+
+usb:v1E3D*
+ ID_VENDOR_FROM_DATABASE=Chipsbank Microelectronics Co., Ltd
+
+usb:v1E3Dp2093*
+ ID_PRODUCT_FROM_DATABASE=CBM209x Flash Drive (OEM)
+
+usb:v1E3Dp4082*
+ ID_PRODUCT_FROM_DATABASE=CBM4082 SD Card Reader
+
+usb:v1E41*
+ ID_VENDOR_FROM_DATABASE=Cleverscope
+
+usb:v1E41p0001*
+ ID_PRODUCT_FROM_DATABASE=CS328A PC Oscilloscope
+
+usb:v1E4E*
+ ID_VENDOR_FROM_DATABASE=Cubeternet
+
+usb:v1E4Ep0100*
+ ID_PRODUCT_FROM_DATABASE=WebCam
+
+usb:v1E4Ep0102*
+ ID_PRODUCT_FROM_DATABASE=GL-UPC822 UVC WebCam
+
+usb:v1E54*
+ ID_VENDOR_FROM_DATABASE=TypeMatrix
+
+usb:v1E54p2030*
+ ID_PRODUCT_FROM_DATABASE=2030 USB Keyboard
+
+usb:v1E68*
+ ID_VENDOR_FROM_DATABASE=TrekStor GmbH & Co. KG
+
+usb:v1E68p001B*
+ ID_PRODUCT_FROM_DATABASE=DataStation maxi g.u
+
+usb:v1E71*
+ ID_VENDOR_FROM_DATABASE=NZXT
+
+usb:v1E71p0001*
+ ID_PRODUCT_FROM_DATABASE=Avatar Optical Mouse
+
+usb:v1E74*
+ ID_VENDOR_FROM_DATABASE=Coby Electronics Corporation
+
+usb:v1E74p2211*
+ ID_PRODUCT_FROM_DATABASE=MP300
+
+usb:v1E74p2647*
+ ID_PRODUCT_FROM_DATABASE=2 GB 2 Go Video MP3 Player [MP601-2G]
+
+usb:v1E74p2659*
+ ID_PRODUCT_FROM_DATABASE=Coby 4GB Go Video MP3 Player [MP620-4G]
+
+usb:v1E74p4641*
+ ID_PRODUCT_FROM_DATABASE=A8705 MP3/Video Player
+
+usb:v1E74p6511*
+ ID_PRODUCT_FROM_DATABASE=MP705-8G MP3 player
+
+usb:v1E74p6512*
+ ID_PRODUCT_FROM_DATABASE=MP705-4G
+
+usb:v1E74p7111*
+ ID_PRODUCT_FROM_DATABASE=MP957 Music and Video Player
+
+usb:v1E7D*
+ ID_VENDOR_FROM_DATABASE=ROCCAT
+
+usb:v1E7Dp2C24*
+ ID_PRODUCT_FROM_DATABASE=Pyra Mouse (wired)
+
+usb:v1E7Dp2CED*
+ ID_PRODUCT_FROM_DATABASE=Kone Mouse
+
+usb:v1E7Dp2CF6*
+ ID_PRODUCT_FROM_DATABASE=Pyra Mouse (wireless)
+
+usb:v1E7Dp2D50*
+ ID_PRODUCT_FROM_DATABASE=Kova+ Mouse
+
+usb:v1E7Dp2D51*
+ ID_PRODUCT_FROM_DATABASE=Kone+ Mouse
+
+usb:v1E7Dp30D4*
+ ID_PRODUCT_FROM_DATABASE=Arvo Keyboard
+
+usb:v1EBB*
+ ID_VENDOR_FROM_DATABASE=NuCORE Technology, Inc.
+
+usb:v1EDA*
+ ID_VENDOR_FROM_DATABASE=AirTies Wireless Networks
+
+usb:v1EDAp2012*
+ ID_PRODUCT_FROM_DATABASE=Air2210 54 Mbps Wireless Adapter
+
+usb:v1EDAp2210*
+ ID_PRODUCT_FROM_DATABASE=Air2210 54 Mbps Wireless Adapter
+
+usb:v1EDAp2310*
+ ID_PRODUCT_FROM_DATABASE=Air2310 150 Mbps Wireless Adapter
+
+usb:v1EDAp2410*
+ ID_PRODUCT_FROM_DATABASE=Air2410 300 Mbps Wireless Adapter
+
+usb:v1EDB*
+ ID_VENDOR_FROM_DATABASE=Blackmagic design
+
+usb:v1EDBpBD3B*
+ ID_PRODUCT_FROM_DATABASE=Intensity Shuttle
+
+usb:v1EE8*
+ ID_VENDOR_FROM_DATABASE=ONDA COMMUNICATION S.p.a.
+
+usb:v1EE8p0014*
+ ID_PRODUCT_FROM_DATABASE=MT833UP
+
+usb:v1EF6*
+ ID_VENDOR_FROM_DATABASE=EADS Deutschland GmbH
+
+usb:v1EF6p5064*
+ ID_PRODUCT_FROM_DATABASE=FDR Interface
+
+usb:v1EF6p5648*
+ ID_PRODUCT_FROM_DATABASE=RIU CSMU/BSD
+
+usb:v1EF6p564A*
+ ID_PRODUCT_FROM_DATABASE=Cassidian RIU CSMU/BSD Simulator
+
+usb:v1F28*
+ ID_VENDOR_FROM_DATABASE=Cal-Comp
+
+usb:v1F28p0020*
+ ID_PRODUCT_FROM_DATABASE=CDMA USB Modem A600
+
+usb:v1F28p0021*
+ ID_PRODUCT_FROM_DATABASE=CD INSTALLER USB Device
+
+usb:v1F44*
+ ID_VENDOR_FROM_DATABASE=The Neat Company
+
+usb:v1F44p0001*
+ ID_PRODUCT_FROM_DATABASE=NM-1000 scanner
+
+usb:v1F48*
+ ID_VENDOR_FROM_DATABASE=H-TRONIC GmbH
+
+usb:v1F48p0627*
+ ID_PRODUCT_FROM_DATABASE=Data capturing system
+
+usb:v1F48p0628*
+ ID_PRODUCT_FROM_DATABASE=Data capturing and control module
+
+usb:v1F4D*
+ ID_VENDOR_FROM_DATABASE=G-Tek Electronics Group
+
+usb:v1F4DpB803*
+ ID_PRODUCT_FROM_DATABASE=Lifeview LV5TDLX DVB-T [RTL2832U]
+
+usb:v1F6F*
+ ID_VENDOR_FROM_DATABASE=Aliph
+
+usb:v1F6Fp0023*
+ ID_PRODUCT_FROM_DATABASE=Jawbone Jambox
+
+usb:v1F6Fp8000*
+ ID_PRODUCT_FROM_DATABASE=Jawbone Jambox - Updating
+
+usb:v1F75*
+ ID_VENDOR_FROM_DATABASE=Innostor Technology Corporation
+
+usb:v1F75p0888*
+ ID_PRODUCT_FROM_DATABASE=IS888 SATA Storage Controller
+
+usb:v1F75p0902*
+ ID_PRODUCT_FROM_DATABASE=IS902 UFD controller
+
+usb:v1F82*
+ ID_VENDOR_FROM_DATABASE=TANDBERG
+
+usb:v1F82p0001*
+ ID_PRODUCT_FROM_DATABASE=PrecisionHD Camera
+
+usb:v1F84*
+ ID_VENDOR_FROM_DATABASE=Alere, Inc.
+
+usb:v1F87*
+ ID_VENDOR_FROM_DATABASE=Stantum
+
+usb:v1F87p0002*
+ ID_PRODUCT_FROM_DATABASE=Multi-touch HID Controller
+
+usb:v1F9B*
+ ID_VENDOR_FROM_DATABASE=Ubiquiti Networks, Inc.
+
+usb:v1F9Bp0241*
+ ID_PRODUCT_FROM_DATABASE=AirView2-EXT
+
+usb:v1FAB*
+ ID_VENDOR_FROM_DATABASE=Samsung Opto-Electroncs Co., Ltd.
+
+usb:v1FABp104D*
+ ID_PRODUCT_FROM_DATABASE=ES65
+
+usb:v1FBD*
+ ID_VENDOR_FROM_DATABASE=Delphin Technology AG
+
+usb:v1FBDp0001*
+ ID_PRODUCT_FROM_DATABASE=Expert Key - Data aquisition system
+
+usb:v1FC9*
+ ID_VENDOR_FROM_DATABASE=NXP Semiconductors
+
+usb:v1FC9p010B*
+ ID_PRODUCT_FROM_DATABASE=PR533
+
+usb:v1FDE*
+ ID_VENDOR_FROM_DATABASE=ILX Lightwave Corporation
+
+usb:v1FDEp0001*
+ ID_PRODUCT_FROM_DATABASE=UART Bridge
+
+usb:v1FE7*
+ ID_VENDOR_FROM_DATABASE=Vertex Wireless Co., Ltd.
+
+usb:v1FE7p1000*
+ ID_PRODUCT_FROM_DATABASE=VW100 series CDMA EV-DO Rev.A modem
+
+usb:v1FF7*
+ ID_VENDOR_FROM_DATABASE=CVT Electronics.Co.,Ltd
+
+usb:v1FF7p0013*
+ ID_PRODUCT_FROM_DATABASE=CVTouch Screen (HID)
+
+usb:v1FF7p001A*
+ ID_PRODUCT_FROM_DATABASE=Human Interface Device
+
+usb:v1FFF*
+ ID_VENDOR_FROM_DATABASE=Ideofy Inc.
+
+usb:v2001*
+ ID_VENDOR_FROM_DATABASE=D-Link Corp.
+
+usb:v2001p0001*
+ ID_PRODUCT_FROM_DATABASE=DWL-120 WIRELESS ADAPTER
+
+usb:v2001p0201*
+ ID_PRODUCT_FROM_DATABASE=DHN-120 10Mb Home Phoneline Adapter
+
+usb:v2001p1A00*
+ ID_PRODUCT_FROM_DATABASE=DUB-E100 10/100 Ethernet
+
+usb:v2001p1A02*
+ ID_PRODUCT_FROM_DATABASE=DUB-E100 Ethernet Adapter
+
+usb:v2001p200C*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet
+
+usb:v2001p3200*
+ ID_PRODUCT_FROM_DATABASE=DWL-120 802.11b Wireless Adapter(rev.E1) [Atmel at76c503a]
+
+usb:v2001p3301*
+ ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.C1) [Realtek RTL8192U]
+
+usb:v2001p3306*
+ ID_PRODUCT_FROM_DATABASE=DWL-G122 Wireless Adapter(rev.F1) [Realtek RTL8188SU]
+
+usb:v2001p3308*
+ ID_PRODUCT_FROM_DATABASE=DWA-121 802.11n Wireless N 150 Pico Adapter [Realtek RTL8188CUS]
+
+usb:v2001p3309*
+ ID_PRODUCT_FROM_DATABASE=DWA-135 802.11n Wireless N Adapter(rev.A1) [Realtek RTL8192CU]
+
+usb:v2001p330A*
+ ID_PRODUCT_FROM_DATABASE=DWA-133 802.11n Wireless N Adapter [Realtek RTL8192CU]
+
+usb:v2001p3500*
+ ID_PRODUCT_FROM_DATABASE=Elitegroup Computer Systems WLAN card WL-162
+
+usb:v2001p3700*
+ ID_PRODUCT_FROM_DATABASE=DWL-122 802.11b [Intersil Prism 3]
+
+usb:v2001p3701*
+ ID_PRODUCT_FROM_DATABASE=DWL-G120 Spinnaker 802.11g [Intersil ISL3886]
+
+usb:v2001p3702*
+ ID_PRODUCT_FROM_DATABASE=DWL-120 802.11b Wireless Adapter(rev.F) [Intersil ISL3871]
+
+usb:v2001p3703*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.A1) [Intersil ISL3880]
+
+usb:v2001p3704*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.A2) [Intersil ISL3887]
+
+usb:v2001p3705*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G120 Wireless Adapter(rev.C) [Intersil ISL3887]
+
+usb:v2001p3761*
+ ID_PRODUCT_FROM_DATABASE=IEEE 802.11g USB2.0 Wireless Network Adapter-PN
+
+usb:v2001p3A00*
+ ID_PRODUCT_FROM_DATABASE=DWL-AG132 [Atheros AR5523]
+
+usb:v2001p3A01*
+ ID_PRODUCT_FROM_DATABASE=DWL-AG132 (no firmware) [Atheros AR5523]
+
+usb:v2001p3A02*
+ ID_PRODUCT_FROM_DATABASE=DWL-G132 [Atheros AR5523]
+
+usb:v2001p3A03*
+ ID_PRODUCT_FROM_DATABASE=DWL-G132 (no firmware) [Atheros AR5523]
+
+usb:v2001p3A04*
+ ID_PRODUCT_FROM_DATABASE=DWL-AG122 [Atheros AR5523]
+
+usb:v2001p3A05*
+ ID_PRODUCT_FROM_DATABASE=DWL-AG122 (no firmware) [Atheros AR5523]
+
+usb:v2001p3A80*
+ ID_PRODUCT_FROM_DATABASE=AirPlus Xtreme G DWL-G132 Wireless Adapter
+
+usb:v2001p3A81*
+ ID_PRODUCT_FROM_DATABASE=predator Bootloader Download
+
+usb:v2001p3A82*
+ ID_PRODUCT_FROM_DATABASE=AirPremier AG DWL-AG132 Wireless Adapter
+
+usb:v2001p3A83*
+ ID_PRODUCT_FROM_DATABASE=predator Bootloader Download
+
+usb:v2001p3B00*
+ ID_PRODUCT_FROM_DATABASE=AirPlus DWL-120+ Wireless Adapter [Texas Instruments ACX100USB]
+
+usb:v2001p3B01*
+ ID_PRODUCT_FROM_DATABASE=WLAN Boot Device
+
+usb:v2001p3C00*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.B1) [Ralink RT2571]
+
+usb:v2001p3C01*
+ ID_PRODUCT_FROM_DATABASE=AirPlus AG DWL-AG122 Wireless Adapter
+
+usb:v2001p3C02*
+ ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter
+
+usb:v2001p3C05*
+ ID_PRODUCT_FROM_DATABASE=DUB-E100 Fast Ethernet [asix]
+
+usb:v2001p3C15*
+ ID_PRODUCT_FROM_DATABASE=DWA-140 RangeBooster N Adapter(rev.B3) [Ralink RT5372]
+
+usb:v2001p3C17*
+ ID_PRODUCT_FROM_DATABASE=DWA-123 Wireless N 150 Adapter(rev.A1) [Ralink RT3370]
+
+usb:v2001p3C19*
+ ID_PRODUCT_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.A3) [Ralink RT5370]
+
+usb:v2001p3C1A*
+ ID_PRODUCT_FROM_DATABASE=DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.B2) [Ralink RT5572]
+
+usb:v2001p3C1B*
+ ID_PRODUCT_FROM_DATABASE=DWA-127 Wireless N 150 High-Gain Adapter(rev.A1) [Ralink RT3070]
+
+usb:v2001p4000*
+ ID_PRODUCT_FROM_DATABASE=DSB-650C Ethernet [klsi]
+
+usb:v2001p4001*
+ ID_PRODUCT_FROM_DATABASE=DSB-650TX Ethernet [pegasus]
+
+usb:v2001p4002*
+ ID_PRODUCT_FROM_DATABASE=DSB-650TX Ethernet [pegasus]
+
+usb:v2001p4003*
+ ID_PRODUCT_FROM_DATABASE=DSB-650TX-PNA Ethernet [pegasus]
+
+usb:v2001p400B*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet
+
+usb:v2001p4102*
+ ID_PRODUCT_FROM_DATABASE=10/100 Ethernet
+
+usb:v2001p5100*
+ ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL ATM Modem
+
+usb:v2001p5102*
+ ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL Loader
+
+usb:v2001p5B00*
+ ID_PRODUCT_FROM_DATABASE=Remote NDIS Network Device
+
+usb:v2001p9414*
+ ID_PRODUCT_FROM_DATABASE=Cable Modem
+
+usb:v2001p9B00*
+ ID_PRODUCT_FROM_DATABASE=Broadband Cable Modem Remote NDIS Device
+
+usb:v2001pABC1*
+ ID_PRODUCT_FROM_DATABASE=DSB-650 Ethernet [pegasus]
+
+usb:v2001pF013*
+ ID_PRODUCT_FROM_DATABASE=DLink 7 port USB2.0 Hub
+
+usb:v2001pF103*
+ ID_PRODUCT_FROM_DATABASE=DUB-H7 7-port USB 2.0 hub
+
+usb:v2001pF10D*
+ ID_PRODUCT_FROM_DATABASE=Accent Communications Modem
+
+usb:v2001pF110*
+ ID_PRODUCT_FROM_DATABASE=DUB-AV300 A/V Capture
+
+usb:v2001pF111*
+ ID_PRODUCT_FROM_DATABASE=DBT-122 Bluetooth adapter
+
+usb:v2001pF112*
+ ID_PRODUCT_FROM_DATABASE=DUB-T210 Audio Device
+
+usb:v2001pF116*
+ ID_PRODUCT_FROM_DATABASE=Formosa 2
+
+usb:v2001pF117*
+ ID_PRODUCT_FROM_DATABASE=Formosa 3
+
+usb:v2001pF118*
+ ID_PRODUCT_FROM_DATABASE=Formosa 4
+
+usb:v2002*
+ ID_VENDOR_FROM_DATABASE=DAP Technologies
+
+usb:v200C*
+ ID_VENDOR_FROM_DATABASE=Reloop
+
+usb:v200Cp100B*
+ ID_PRODUCT_FROM_DATABASE=Play audio soundcard
+
+usb:v2013*
+ ID_VENDOR_FROM_DATABASE=PCTV Systems
+
+usb:v2013p0245*
+ ID_PRODUCT_FROM_DATABASE=PCTV 73ESE
+
+usb:v2013p0246*
+ ID_PRODUCT_FROM_DATABASE=PCTV 74E
+
+usb:v2013p0248*
+ ID_PRODUCT_FROM_DATABASE=PCTV 282E
+
+usb:v2013p024F*
+ ID_PRODUCT_FROM_DATABASE=nanoStick T2 290e
+
+usb:v2019*
+ ID_VENDOR_FROM_DATABASE=PLANEX
+
+usb:v2019p3220*
+ ID_PRODUCT_FROM_DATABASE=GW-US11S WLAN [Atmel AT76C503A]
+
+usb:v2019p4901*
+ ID_PRODUCT_FROM_DATABASE=GW-USSuper300 802.11bgn Wireless Adapter [Realtek RTL8191SU]
+
+usb:v2019p4903*
+ ID_PRODUCT_FROM_DATABASE=GW-USFang300 802.11abgn Wireless Adapter [Realtek RTL8192DU]
+
+usb:v2019p4904*
+ ID_PRODUCT_FROM_DATABASE=GW-USUltra300 802.11abgn Wireless Adapter [Realtek RTL8192DU]
+
+usb:v2019p5303*
+ ID_PRODUCT_FROM_DATABASE=GW-US54GXS 802.11bg
+
+usb:v2019p5304*
+ ID_PRODUCT_FROM_DATABASE=GWUS300 802.11n
+
+usb:v2019pAB01*
+ ID_PRODUCT_FROM_DATABASE=GW-US54HP
+
+usb:v2019pAB24*
+ ID_PRODUCT_FROM_DATABASE=GW-US300MiniS
+
+usb:v2019pAB25*
+ ID_PRODUCT_FROM_DATABASE=GW-USMini2N 802.11n Wireless Adapter [Ralink RT2870]
+
+usb:v2019pAB28*
+ ID_PRODUCT_FROM_DATABASE=GW-USNano
+
+usb:v2019pAB29*
+ ID_PRODUCT_FROM_DATABASE=GW-USMicro300
+
+usb:v2019pAB2A*
+ ID_PRODUCT_FROM_DATABASE=GW-USNano2 802.11n Wireless Adapter [Realtek RTL8188CUS]
+
+usb:v2019pAB2B*
+ ID_PRODUCT_FROM_DATABASE=GW-USEco300 802.11bgn Wireless Adapter [Realtek RTL8192CU]
+
+usb:v2019pAB2C*
+ ID_PRODUCT_FROM_DATABASE=GW-USDual300 802.11abgn Wireless Adapter [Realtek RTL8192DU]
+
+usb:v2019pAB50*
+ ID_PRODUCT_FROM_DATABASE=GW-US54Mini2
+
+usb:v2019pC002*
+ ID_PRODUCT_FROM_DATABASE=GW-US54SG
+
+usb:v2019pC007*
+ ID_PRODUCT_FROM_DATABASE=GW-US54GZL
+
+usb:v2019pED02*
+ ID_PRODUCT_FROM_DATABASE=GW-USMM
+
+usb:v2019pED06*
+ ID_PRODUCT_FROM_DATABASE=GW-US300MiniW 802.11bgn Wireless Adapter
+
+usb:v2019pED10*
+ ID_PRODUCT_FROM_DATABASE=GW-US300Mini2
+
+usb:v2019pED14*
+ ID_PRODUCT_FROM_DATABASE=GW-USMicroN
+
+usb:v2019pED16*
+ ID_PRODUCT_FROM_DATABASE=GW-USMicroN2W 802.11bgn Wireless Adapter [Realtek RTL8188SU]
+
+usb:v2019pED17*
+ ID_PRODUCT_FROM_DATABASE=GW-USValue-EZ 802.11n Wireless Adapter [Realtek RTL8188CUS]
+
+usb:v2019pED18*
+ ID_PRODUCT_FROM_DATABASE=GW-USHyper300 / GW-USH300N 802.11bgn Wireless Adapter [Realtek RTL8191SU]
+
+usb:v2040*
+ ID_VENDOR_FROM_DATABASE=Hauppauge
+
+usb:v2040p0C80*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040p0C90*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040p1700*
+ ID_PRODUCT_FROM_DATABASE=CataMount
+
+usb:v2040p1800*
+ ID_PRODUCT_FROM_DATABASE=Okemo A
+
+usb:v2040p1801*
+ ID_PRODUCT_FROM_DATABASE=Okemo B
+
+usb:v2040p2000*
+ ID_PRODUCT_FROM_DATABASE=Tiger Minicard
+
+usb:v2040p2009*
+ ID_PRODUCT_FROM_DATABASE=Tiger Minicard R2
+
+usb:v2040p200A*
+ ID_PRODUCT_FROM_DATABASE=Tiger Minicard
+
+usb:v2040p2010*
+ ID_PRODUCT_FROM_DATABASE=Tiger Minicard
+
+usb:v2040p2011*
+ ID_PRODUCT_FROM_DATABASE=WinTV MiniCard [Dell Digital TV Receiver]
+
+usb:v2040p2019*
+ ID_PRODUCT_FROM_DATABASE=Tiger Minicard
+
+usb:v2040p2400*
+ ID_PRODUCT_FROM_DATABASE=WinTV PVR USB2 (Model 24019)
+
+usb:v2040p4700*
+ ID_PRODUCT_FROM_DATABASE=WinTV Nova-S-USB2
+
+usb:v2040p4902*
+ ID_PRODUCT_FROM_DATABASE=HD PVR
+
+usb:v2040p4903*
+ ID_PRODUCT_FROM_DATABASE=HS PVR
+
+usb:v2040p4982*
+ ID_PRODUCT_FROM_DATABASE=HD PVR
+
+usb:v2040p5500*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040p5510*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040p5520*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040p5530*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040p5580*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040p5590*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040p6500*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-900
+
+usb:v2040p6502*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-900
+
+usb:v2040p6503*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-930
+
+usb:v2040p6513*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-980
+
+usb:v2040p7050*
+ ID_PRODUCT_FROM_DATABASE=Nova-T Stick
+
+usb:v2040p7060*
+ ID_PRODUCT_FROM_DATABASE=Nova-T Stick 2
+
+usb:v2040p7070*
+ ID_PRODUCT_FROM_DATABASE=Nova-T Stick 3
+
+usb:v2040p7240*
+ ID_PRODUCT_FROM_DATABASE=WinTV HVR-850
+
+usb:v2040p8400*
+ ID_PRODUCT_FROM_DATABASE=WinTV Nova-T-500
+
+usb:v2040p9300*
+ ID_PRODUCT_FROM_DATABASE=WinTV NOVA-T USB2 (cold)
+
+usb:v2040p9301*
+ ID_PRODUCT_FROM_DATABASE=WinTV NOVA-T USB2 (warm)
+
+usb:v2040p9941*
+ ID_PRODUCT_FROM_DATABASE=WinTV Nova-T-500
+
+usb:v2040p9950*
+ ID_PRODUCT_FROM_DATABASE=WinTV Nova-T-500
+
+usb:v2040pB910*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040pB980*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040pB990*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040pC000*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2040pC010*
+ ID_PRODUCT_FROM_DATABASE=Windham
+
+usb:v2047*
+ ID_VENDOR_FROM_DATABASE=Texas Instruments
+
+usb:v2047p0200*
+ ID_PRODUCT_FROM_DATABASE=MSP430 USB HID Bootstrap Loader
+
+usb:v2080*
+ ID_VENDOR_FROM_DATABASE=Barnes & Noble
+
+usb:v2080p0001*
+ ID_PRODUCT_FROM_DATABASE=nook
+
+usb:v2080p0002*
+ ID_PRODUCT_FROM_DATABASE=NOOKcolor
+
+usb:v2080p0003*
+ ID_PRODUCT_FROM_DATABASE=NOOK Simple Touch
+
+usb:v2080p0004*
+ ID_PRODUCT_FROM_DATABASE=NOOK Tablet
+
+usb:v2087*
+ ID_VENDOR_FROM_DATABASE=Cando
+
+usb:v2087p0A01*
+ ID_PRODUCT_FROM_DATABASE=Multi Touch Panel
+
+usb:v2087p0A02*
+ ID_PRODUCT_FROM_DATABASE=Multi Touch Panel
+
+usb:v2087p0B03*
+ ID_PRODUCT_FROM_DATABASE=Multi Touch Panel
+
+usb:v20A0*
+ ID_VENDOR_FROM_DATABASE=Clay Logic
+
+usb:v20A0p4123*
+ ID_PRODUCT_FROM_DATABASE=IKALOGIC SCANALOGIC 2
+
+usb:v20A0p414A*
+ ID_PRODUCT_FROM_DATABASE=MDE SPI Interface
+
+usb:v20A0p415A*
+ ID_PRODUCT_FROM_DATABASE=OpenPilot
+
+usb:v20A0p415B*
+ ID_PRODUCT_FROM_DATABASE=CopterControl
+
+usb:v20A0p415C*
+ ID_PRODUCT_FROM_DATABASE=PipXtreme
+
+usb:v20B1*
+ ID_VENDOR_FROM_DATABASE=XMOS Ltd
+
+usb:v20B1p10AD*
+ ID_PRODUCT_FROM_DATABASE=XUSB Loader
+
+usb:v20B1pF7D1*
+ ID_PRODUCT_FROM_DATABASE=XTAG2 - JTAG Adapter
+
+usb:v20B3*
+ ID_VENDOR_FROM_DATABASE=Hanvon
+
+usb:v20B3p0A18*
+ ID_PRODUCT_FROM_DATABASE=10.1 Touch screen overlay
+
+usb:v20B7*
+ ID_VENDOR_FROM_DATABASE=Qi Hardware
+
+usb:v20B7p0713*
+ ID_PRODUCT_FROM_DATABASE=Milkymist JTAG/serial
+
+usb:v20B7p1540*
+ ID_PRODUCT_FROM_DATABASE=ben-wpan, AT86RF230-based
+
+usb:v20B7p1DB5*
+ ID_PRODUCT_FROM_DATABASE=IDBG in DFU mode
+
+usb:v20B7p1DB6*
+ ID_PRODUCT_FROM_DATABASE=IDBG in normal mode
+
+usb:v20B7pC25B*
+ ID_PRODUCT_FROM_DATABASE=C2 Dongle
+
+usb:v20B7pCB72*
+ ID_PRODUCT_FROM_DATABASE=ben-wpan, cntr
+
+usb:v20DF*
+ ID_VENDOR_FROM_DATABASE=Simtec Electronics
+
+usb:v20DFp0001*
+ ID_PRODUCT_FROM_DATABASE=Entropy Key [UDEKEY01]
+
+usb:v20F4*
+ ID_VENDOR_FROM_DATABASE=TRENDnet
+
+usb:v20F4p648B*
+ ID_PRODUCT_FROM_DATABASE=TEW-648UBM 802.11n 150Mbps Micro Wireless N Adapter [Realtek RTL8188CUS]
+
+usb:v2101*
+ ID_VENDOR_FROM_DATABASE=ActionStar
+
+usb:v2101p0201*
+ ID_PRODUCT_FROM_DATABASE=SIIG 4-to-2 Printer Switch
+
+usb:v2162*
+ ID_VENDOR_FROM_DATABASE=Creative (?)
+
+usb:v2162p2031*
+ ID_PRODUCT_FROM_DATABASE=Network Blaster Wireless Adapter
+
+usb:v2162p500C*
+ ID_PRODUCT_FROM_DATABASE=DE5771 Modem Blaster
+
+usb:v2162p8001*
+ ID_PRODUCT_FROM_DATABASE=Broadxent BritePort DSL Bridge 8010U
+
+usb:v2184*
+ ID_VENDOR_FROM_DATABASE=GW Instek
+
+usb:v2184p0005*
+ ID_PRODUCT_FROM_DATABASE=GDS-3000 Oscilloscope
+
+usb:v2184p0006*
+ ID_PRODUCT_FROM_DATABASE=GDS-3000 Oscilloscope
+
+usb:v2184p0011*
+ ID_PRODUCT_FROM_DATABASE=AFG Function Generator (CDC)
+
+usb:v21A1*
+ ID_VENDOR_FROM_DATABASE=Emotiv Systems Pty. Ltd.
+
+usb:v21A1p0001*
+ ID_PRODUCT_FROM_DATABASE=EPOC Consumer Headset Wireless Dongle
+
+usb:v21D6*
+ ID_VENDOR_FROM_DATABASE=Agecodagis SARL
+
+usb:v21D6p0002*
+ ID_PRODUCT_FROM_DATABASE=Seismic recorder [Tellus]
+
+usb:v2222*
+ ID_VENDOR_FROM_DATABASE=MacAlly
+
+usb:v2222p0004*
+ ID_PRODUCT_FROM_DATABASE=iWebKey Keyboard
+
+usb:v2222p2520*
+ ID_PRODUCT_FROM_DATABASE=Mini Tablet
+
+usb:v2222p4050*
+ ID_PRODUCT_FROM_DATABASE=AirStick joystick
+
+usb:v2227*
+ ID_VENDOR_FROM_DATABASE=SAMWOO Enterprise
+
+usb:v2227p3105*
+ ID_PRODUCT_FROM_DATABASE=SKYDATA SKD-U100
+
+usb:v2233*
+ ID_VENDOR_FROM_DATABASE=RadioShack Corporation
+
+usb:v2233p6323*
+ ID_PRODUCT_FROM_DATABASE=USB Electronic Scale
+
+usb:v2237*
+ ID_VENDOR_FROM_DATABASE=Kobo Inc.
+
+usb:v2237p4161*
+ ID_PRODUCT_FROM_DATABASE=eReader White
+
+usb:v22A6*
+ ID_VENDOR_FROM_DATABASE=Pie Digital, Inc.
+
+usb:v22A6pFFFF*
+ ID_PRODUCT_FROM_DATABASE=PieKey "beta" 4GB model 4E4F41482E4F5247 (SM3251Q BB)
+
+usb:v22B8*
+ ID_VENDOR_FROM_DATABASE=Motorola PCS
+
+usb:v22B8p0001*
+ ID_PRODUCT_FROM_DATABASE=Wally 2.2 chipset
+
+usb:v22B8p0002*
+ ID_PRODUCT_FROM_DATABASE=Wally 2.4 chipset
+
+usb:v22B8p0005*
+ ID_PRODUCT_FROM_DATABASE=V.60c/V.60i GSM Phone
+
+usb:v22B8p0830*
+ ID_PRODUCT_FROM_DATABASE=2386C-HT820
+
+usb:v22B8p0833*
+ ID_PRODUCT_FROM_DATABASE=2386C-HT820 [Flash Mode]
+
+usb:v22B8p0850*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v22B8p1001*
+ ID_PRODUCT_FROM_DATABASE=Patriot 1.0 (GSM) chipset
+
+usb:v22B8p1002*
+ ID_PRODUCT_FROM_DATABASE=Patriot 2.0 chipset
+
+usb:v22B8p1005*
+ ID_PRODUCT_FROM_DATABASE=T280e GSM/GPRS Phone
+
+usb:v22B8p1101*
+ ID_PRODUCT_FROM_DATABASE=Patriot 1.0 (TDMA) chipset
+
+usb:v22B8p1801*
+ ID_PRODUCT_FROM_DATABASE=Rainbow chipset flash
+
+usb:v22B8p2035*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Device
+
+usb:v22B8p2805*
+ ID_PRODUCT_FROM_DATABASE=GSM Modem
+
+usb:v22B8p2821*
+ ID_PRODUCT_FROM_DATABASE=T720 GSM Phone
+
+usb:v22B8p2822*
+ ID_PRODUCT_FROM_DATABASE=V.120e GSM Phone
+
+usb:v22B8p2823*
+ ID_PRODUCT_FROM_DATABASE=Flash Interface
+
+usb:v22B8p2A01*
+ ID_PRODUCT_FROM_DATABASE=MSM6050 chipset
+
+usb:v22B8p2A02*
+ ID_PRODUCT_FROM_DATABASE=CDMA modem
+
+usb:v22B8p2A03*
+ ID_PRODUCT_FROM_DATABASE=MSM6050 chipset flash
+
+usb:v22B8p2A21*
+ ID_PRODUCT_FROM_DATABASE=V710 GSM Phone (P2K)
+
+usb:v22B8p2A22*
+ ID_PRODUCT_FROM_DATABASE=V710 GSM Phone (AT)
+
+usb:v22B8p2A23*
+ ID_PRODUCT_FROM_DATABASE=MSM6100 chipset flash
+
+usb:v22B8p2A41*
+ ID_PRODUCT_FROM_DATABASE=MSM6300 chipset
+
+usb:v22B8p2A42*
+ ID_PRODUCT_FROM_DATABASE=Usb Modem
+
+usb:v22B8p2A43*
+ ID_PRODUCT_FROM_DATABASE=MSM6300 chipset flash
+
+usb:v22B8p2A61*
+ ID_PRODUCT_FROM_DATABASE=E815 GSM Phone (P2K)
+
+usb:v22B8p2A62*
+ ID_PRODUCT_FROM_DATABASE=E815 GSM Phone (AT)
+
+usb:v22B8p2A63*
+ ID_PRODUCT_FROM_DATABASE=MSM6500 chipset flash
+
+usb:v22B8p2A81*
+ ID_PRODUCT_FROM_DATABASE=MSM6025 chipset
+
+usb:v22B8p2A83*
+ ID_PRODUCT_FROM_DATABASE=MSM6025 chipset flash
+
+usb:v22B8p2AC1*
+ ID_PRODUCT_FROM_DATABASE=MSM6100 chipset
+
+usb:v22B8p2AC3*
+ ID_PRODUCT_FROM_DATABASE=MSM6100 chipset flash
+
+usb:v22B8p2D78*
+ ID_PRODUCT_FROM_DATABASE=XT300[SPICE]
+
+usb:v22B8p3001*
+ ID_PRODUCT_FROM_DATABASE=A835/E1000 GSM Phone (P2K)
+
+usb:v22B8p3002*
+ ID_PRODUCT_FROM_DATABASE=A835/E1000 GSM Phone (AT)
+
+usb:v22B8p3801*
+ ID_PRODUCT_FROM_DATABASE=C350L/C450 (P2K)
+
+usb:v22B8p3802*
+ ID_PRODUCT_FROM_DATABASE=C330/C350L/C450/EZX GSM Phone (AT)
+
+usb:v22B8p3803*
+ ID_PRODUCT_FROM_DATABASE=Neptune LT chipset flash
+
+usb:v22B8p4001*
+ ID_PRODUCT_FROM_DATABASE=OMAP 1.0 chipset
+
+usb:v22B8p4002*
+ ID_PRODUCT_FROM_DATABASE=A920/A925 UMTS Phone
+
+usb:v22B8p4003*
+ ID_PRODUCT_FROM_DATABASE=OMAP 1.0 chipset flash
+
+usb:v22B8p4008*
+ ID_PRODUCT_FROM_DATABASE=OMAP 1.0 chipset RDL
+
+usb:v22B8p41D6*
+ ID_PRODUCT_FROM_DATABASE=Droid X (Windows media mode)
+
+usb:v22B8p41D9*
+ ID_PRODUCT_FROM_DATABASE=Droid/Milestone
+
+usb:v22B8p41DB*
+ ID_PRODUCT_FROM_DATABASE=Droid/Milestone (Debug mode)
+
+usb:v22B8p41DE*
+ ID_PRODUCT_FROM_DATABASE=Droid X (PC mode)
+
+usb:v22B8p4204*
+ ID_PRODUCT_FROM_DATABASE=MPx200 Smartphone
+
+usb:v22B8p4214*
+ ID_PRODUCT_FROM_DATABASE=MPc GSM
+
+usb:v22B8p4224*
+ ID_PRODUCT_FROM_DATABASE=MPx220 Smartphone
+
+usb:v22B8p4234*
+ ID_PRODUCT_FROM_DATABASE=MPc CDMA
+
+usb:v22B8p4244*
+ ID_PRODUCT_FROM_DATABASE=MPx100 Smartphone
+
+usb:v22B8p4285*
+ ID_PRODUCT_FROM_DATABASE=Droid X (Mass storage)
+
+usb:v22B8p4801*
+ ID_PRODUCT_FROM_DATABASE=Neptune LTS chipset
+
+usb:v22B8p4803*
+ ID_PRODUCT_FROM_DATABASE=Neptune LTS chipset flash
+
+usb:v22B8p4810*
+ ID_PRODUCT_FROM_DATABASE=Triplet GSM Phone (storage)
+
+usb:v22B8p4901*
+ ID_PRODUCT_FROM_DATABASE=Triplet GSM Phone (P2K)
+
+usb:v22B8p4902*
+ ID_PRODUCT_FROM_DATABASE=Triplet GSM Phone (AT)
+
+usb:v22B8p4903*
+ ID_PRODUCT_FROM_DATABASE=Neptune LTE chipset flash
+
+usb:v22B8p4A01*
+ ID_PRODUCT_FROM_DATABASE=Neptune LTX chipset
+
+usb:v22B8p4A03*
+ ID_PRODUCT_FROM_DATABASE=Neptune LTX chipset flash
+
+usb:v22B8p4A32*
+ ID_PRODUCT_FROM_DATABASE=L6-imode Phone
+
+usb:v22B8p5801*
+ ID_PRODUCT_FROM_DATABASE=Neptune ULS chipset
+
+usb:v22B8p5803*
+ ID_PRODUCT_FROM_DATABASE=Neptune ULS chipset flash
+
+usb:v22B8p5901*
+ ID_PRODUCT_FROM_DATABASE=Neptune VLT chipset
+
+usb:v22B8p5903*
+ ID_PRODUCT_FROM_DATABASE=Neptune VLT chipset flash
+
+usb:v22B8p6001*
+ ID_PRODUCT_FROM_DATABASE=Dalhart EZX
+
+usb:v22B8p6003*
+ ID_PRODUCT_FROM_DATABASE=Dalhart flash
+
+usb:v22B8p6004*
+ ID_PRODUCT_FROM_DATABASE=EZX GSM Phone (CDC Net)
+
+usb:v22B8p6006*
+ ID_PRODUCT_FROM_DATABASE=MOTOROKR E6
+
+usb:v22B8p6008*
+ ID_PRODUCT_FROM_DATABASE=Dalhart RDL
+
+usb:v22B8p6009*
+ ID_PRODUCT_FROM_DATABASE=EZX GSM Phone (P2K)
+
+usb:v22B8p600A*
+ ID_PRODUCT_FROM_DATABASE=Dalhart EZX config 17
+
+usb:v22B8p600B*
+ ID_PRODUCT_FROM_DATABASE=Dalhart EZX config 18
+
+usb:v22B8p600C*
+ ID_PRODUCT_FROM_DATABASE=EZX GSM Phone (USBLAN)
+
+usb:v22B8p6021*
+ ID_PRODUCT_FROM_DATABASE=JUIX chipset
+
+usb:v22B8p6023*
+ ID_PRODUCT_FROM_DATABASE=JUIX chipset flash
+
+usb:v22B8p6026*
+ ID_PRODUCT_FROM_DATABASE=Flash RAM Downloader/miniOS
+
+usb:v22B8p6027*
+ ID_PRODUCT_FROM_DATABASE=USBLAN
+
+usb:v22B8p604C*
+ ID_PRODUCT_FROM_DATABASE=EZX GSM Phone (Storage)
+
+usb:v22B8p6101*
+ ID_PRODUCT_FROM_DATABASE=Talon integrated chipset
+
+usb:v22B8p6401*
+ ID_PRODUCT_FROM_DATABASE=Argon chipset
+
+usb:v22B8p6403*
+ ID_PRODUCT_FROM_DATABASE=Argon chipset flash
+
+usb:v22B8p6415*
+ ID_PRODUCT_FROM_DATABASE=ROKR Z6 (MTP mode)
+
+usb:v22B8p6604*
+ ID_PRODUCT_FROM_DATABASE=Washington CDMA Phone
+
+usb:v22B8p6631*
+ ID_PRODUCT_FROM_DATABASE=CDC Modem
+
+usb:v22B8p7001*
+ ID_PRODUCT_FROM_DATABASE=Q Smartphone
+
+usb:v22B8pFE01*
+ ID_PRODUCT_FROM_DATABASE=StarTAC III MS900
+
+usb:v22B9*
+ ID_VENDOR_FROM_DATABASE=eTurboTouch Technology, Inc.
+
+usb:v22B9p0006*
+ ID_PRODUCT_FROM_DATABASE=Touch Screen
+
+usb:v22BA*
+ ID_VENDOR_FROM_DATABASE=Technology Innovation Holdings, Ltd
+
+usb:v2304*
+ ID_VENDOR_FROM_DATABASE=Pinnacle Systems, Inc.
+
+usb:v2304p0109*
+ ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (SECAM)
+
+usb:v2304p0110*
+ ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (PAL)
+
+usb:v2304p0111*
+ ID_PRODUCT_FROM_DATABASE=Miro PCTV USB
+
+usb:v2304p0112*
+ ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (NTSC) with FM radio
+
+usb:v2304p0201*
+ ID_PRODUCT_FROM_DATABASE=Systems MovieBox Device
+
+usb:v2304p0204*
+ ID_PRODUCT_FROM_DATABASE=MovieBox USB_B
+
+usb:v2304p0205*
+ ID_PRODUCT_FROM_DATABASE=DVC 150B
+
+usb:v2304p0206*
+ ID_PRODUCT_FROM_DATABASE=Systems MovieBox Deluxe Device
+
+usb:v2304p0207*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DVC90 Video Device
+
+usb:v2304p0208*
+ ID_PRODUCT_FROM_DATABASE=Studio PCTV USB2
+
+usb:v2304p020E*
+ ID_PRODUCT_FROM_DATABASE=PCTV 200e
+
+usb:v2304p020F*
+ ID_PRODUCT_FROM_DATABASE=PCTV 400e BDA Device
+
+usb:v2304p0210*
+ ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (PAL) with FM radio
+
+usb:v2304p0212*
+ ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (NTSC)
+
+usb:v2304p0213*
+ ID_PRODUCT_FROM_DATABASE=500-USB Device
+
+usb:v2304p0214*
+ ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (PAL) with FM radio
+
+usb:v2304p0216*
+ ID_PRODUCT_FROM_DATABASE=PCTV 60e
+
+usb:v2304p0219*
+ ID_PRODUCT_FROM_DATABASE=PCTV 260e
+
+usb:v2304p021A*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DVC100 Audio Device
+
+usb:v2304p021B*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DVC130/DVC170
+
+usb:v2304p021D*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DVC130
+
+usb:v2304p021E*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DVC170
+
+usb:v2304p021F*
+ ID_PRODUCT_FROM_DATABASE=PCTV Sat HDTV Pro BDA Device
+
+usb:v2304p0222*
+ ID_PRODUCT_FROM_DATABASE=PCTV Sat Pro BDA Device
+
+usb:v2304p0223*
+ ID_PRODUCT_FROM_DATABASE=DazzleTV Sat BDA Device
+
+usb:v2304p0225*
+ ID_PRODUCT_FROM_DATABASE=Remote Kit Infrared Transceiver
+
+usb:v2304p0226*
+ ID_PRODUCT_FROM_DATABASE=PCTV 330e
+
+usb:v2304p0227*
+ ID_PRODUCT_FROM_DATABASE=PCTV for Mac, HD Stick
+
+usb:v2304p0228*
+ ID_PRODUCT_FROM_DATABASE=PCTV DVB-T Flash Stick
+
+usb:v2304p0229*
+ ID_PRODUCT_FROM_DATABASE=PCTV Dual DVB-T 2001e
+
+usb:v2304p022A*
+ ID_PRODUCT_FROM_DATABASE=PCTV 160e
+
+usb:v2304p022B*
+ ID_PRODUCT_FROM_DATABASE=PCTV 71e [Afatech AF9015]
+
+usb:v2304p0232*
+ ID_PRODUCT_FROM_DATABASE=PCTV 170e
+
+usb:v2304p0236*
+ ID_PRODUCT_FROM_DATABASE=PCTV 72e [DiBcom DiB7000PC]
+
+usb:v2304p0237*
+ ID_PRODUCT_FROM_DATABASE=PCTV 73e [DiBcom DiB7000PC]
+
+usb:v2304p023A*
+ ID_PRODUCT_FROM_DATABASE=PCTV 801e
+
+usb:v2304p023B*
+ ID_PRODUCT_FROM_DATABASE=PCTV 801e SE
+
+usb:v2304p023D*
+ ID_PRODUCT_FROM_DATABASE=PCTV 340e
+
+usb:v2304p023E*
+ ID_PRODUCT_FROM_DATABASE=PCTV 340e SE
+
+usb:v2304p0300*
+ ID_PRODUCT_FROM_DATABASE=Studio Linx Video input cable (NTSC)
+
+usb:v2304p0301*
+ ID_PRODUCT_FROM_DATABASE=Studio Linx Video input cable (PAL)
+
+usb:v2304p0302*
+ ID_PRODUCT_FROM_DATABASE=Dazzle DVC120
+
+usb:v2304p0419*
+ ID_PRODUCT_FROM_DATABASE=PCTV Bungee USB (PAL) with FM radio
+
+usb:v2304p061D*
+ ID_PRODUCT_FROM_DATABASE=PCTV Deluxe (NTSC) Device
+
+usb:v2304p061E*
+ ID_PRODUCT_FROM_DATABASE=PCTV Deluxe (PAL) Device
+
+usb:v2318*
+ ID_VENDOR_FROM_DATABASE=Shining Technologies, Inc. [hex]
+
+usb:v2318p0011*
+ ID_PRODUCT_FROM_DATABASE=CitiDISK Jr. IDE Enclosure
+
+usb:v2341*
+ ID_VENDOR_FROM_DATABASE=Arduino SA
+
+usb:v2341p0001*
+ ID_PRODUCT_FROM_DATABASE=Uno (CDC ACM)
+
+usb:v2341p0010*
+ ID_PRODUCT_FROM_DATABASE=Mega 2560 (CDC ACM)
+
+usb:v2341p003B*
+ ID_PRODUCT_FROM_DATABASE=Serial Adapter (CDC ACM)
+
+usb:v2341p003F*
+ ID_PRODUCT_FROM_DATABASE=Mega ADK (CDC ACM)
+
+usb:v2341p0042*
+ ID_PRODUCT_FROM_DATABASE=Mega 2560 R3 (CDC ACM)
+
+usb:v2341p0043*
+ ID_PRODUCT_FROM_DATABASE=Uno R3 (CDC ACM)
+
+usb:v2341p0044*
+ ID_PRODUCT_FROM_DATABASE=Mega ADK R3 (CDC ACM)
+
+usb:v2341p0045*
+ ID_PRODUCT_FROM_DATABASE=Serial R3 (CDC ACM)
+
+usb:v2341p8036*
+ ID_PRODUCT_FROM_DATABASE=Leonardo (CDC ACM, HID)
+
+usb:v2373*
+ ID_VENDOR_FROM_DATABASE=Pumatronix Ltda
+
+usb:v2373p0001*
+ ID_PRODUCT_FROM_DATABASE=5 MegaPixel Digital Still Camera [DSC5M]
+
+usb:v2375*
+ ID_VENDOR_FROM_DATABASE=Digit@lway, Inc.
+
+usb:v2375p0001*
+ ID_PRODUCT_FROM_DATABASE=Digital Audio Player
+
+usb:v2406*
+ ID_VENDOR_FROM_DATABASE=SANHO Digital Electronics Co., Ltd.
+
+usb:v2406p6688*
+ ID_PRODUCT_FROM_DATABASE=PD7X Portable Storage
+
+usb:v2478*
+ ID_VENDOR_FROM_DATABASE=Tripp-Lite
+
+usb:v2478p2008*
+ ID_PRODUCT_FROM_DATABASE=U209-000-R Serial Port
+
+usb:v2632*
+ ID_VENDOR_FROM_DATABASE=TwinMOS
+
+usb:v2632p3209*
+ ID_PRODUCT_FROM_DATABASE=7-in-1 Card Reader
+
+usb:v2650*
+ ID_VENDOR_FROM_DATABASE=Electronics For Imaging, Inc. [hex]
+
+usb:v2659*
+ ID_VENDOR_FROM_DATABASE=Sundtek
+
+usb:v2659p1101*
+ ID_PRODUCT_FROM_DATABASE=TNT DVB-T/DAB/DAB+/FM
+
+usb:v2659p1201*
+ ID_PRODUCT_FROM_DATABASE=FM Transmitter/Receiver
+
+usb:v2659p1202*
+ ID_PRODUCT_FROM_DATABASE=MediaTV Analog/FM/DVB-T
+
+usb:v2659p1203*
+ ID_PRODUCT_FROM_DATABASE=MediaTV Analog/FM/DVB-T MiniPCIe
+
+usb:v2659p1204*
+ ID_PRODUCT_FROM_DATABASE=MediaTV Analog/FM/ATSC
+
+usb:v2659p1205*
+ ID_PRODUCT_FROM_DATABASE=SkyTV Ultimate V
+
+usb:v2659p1206*
+ ID_PRODUCT_FROM_DATABASE=MediaTV DVB-T MiniPCIe
+
+usb:v2659p1207*
+ ID_PRODUCT_FROM_DATABASE=Sundtek HD Capture
+
+usb:v2659p1208*
+ ID_PRODUCT_FROM_DATABASE=Sundtek SkyTV Ultimate III
+
+usb:v2730*
+ ID_VENDOR_FROM_DATABASE=Citizen
+
+usb:v2730p200F*
+ ID_PRODUCT_FROM_DATABASE=CT-S310 Label printer
+
+usb:v2735*
+ ID_VENDOR_FROM_DATABASE=DigitalWay
+
+usb:v2735p0003*
+ ID_PRODUCT_FROM_DATABASE=MPIO HS100
+
+usb:v2735p1001*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY200
+
+usb:v2735p1002*
+ ID_PRODUCT_FROM_DATABASE=MPIO FL100
+
+usb:v2735p1003*
+ ID_PRODUCT_FROM_DATABASE=MPIO FD100
+
+usb:v2735p1004*
+ ID_PRODUCT_FROM_DATABASE=MPIO HD200
+
+usb:v2735p1005*
+ ID_PRODUCT_FROM_DATABASE=MPIO HD300
+
+usb:v2735p1006*
+ ID_PRODUCT_FROM_DATABASE=MPIO FG100
+
+usb:v2735p1007*
+ ID_PRODUCT_FROM_DATABASE=MPIO FG130
+
+usb:v2735p1008*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY300
+
+usb:v2735p1009*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY400
+
+usb:v2735p100A*
+ ID_PRODUCT_FROM_DATABASE=MPIO FL300
+
+usb:v2735p100B*
+ ID_PRODUCT_FROM_DATABASE=MPIO HS200
+
+usb:v2735p100C*
+ ID_PRODUCT_FROM_DATABASE=MPIO FL350
+
+usb:v2735p100D*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY500
+
+usb:v2735p100E*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY500
+
+usb:v2735p100F*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY600
+
+usb:v2735p1012*
+ ID_PRODUCT_FROM_DATABASE=MPIO FL400
+
+usb:v2735p1013*
+ ID_PRODUCT_FROM_DATABASE=MPIO HD400
+
+usb:v2735p1014*
+ ID_PRODUCT_FROM_DATABASE=MPIO HD400
+
+usb:v2735p1016*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY700
+
+usb:v2735p1017*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY700
+
+usb:v2735p1018*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY800
+
+usb:v2735p1019*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY800
+
+usb:v2735p101A*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY900
+
+usb:v2735p101B*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY900
+
+usb:v2735p102B*
+ ID_PRODUCT_FROM_DATABASE=MPIO FL500
+
+usb:v2735p102C*
+ ID_PRODUCT_FROM_DATABASE=MPIO FL500
+
+usb:v2735p103F*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY570
+
+usb:v2735p1040*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY570
+
+usb:v2735p1041*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY670
+
+usb:v2735p1042*
+ ID_PRODUCT_FROM_DATABASE=MPIO FY670
+
+usb:v2735p1043*
+ ID_PRODUCT_FROM_DATABASE=HCT HMD-180A
+
+usb:v2735p1044*
+ ID_PRODUCT_FROM_DATABASE=HCT HMD-180A
+
+usb:v2770*
+ ID_VENDOR_FROM_DATABASE=NHJ, Ltd
+
+usb:v2770p0A01*
+ ID_PRODUCT_FROM_DATABASE=ScanJet 4600 series
+
+usb:v2770p905C*
+ ID_PRODUCT_FROM_DATABASE=Che-Ez Snap SNAP-U/Digigr8/Soundstar TDC-35
+
+usb:v2770p9060*
+ ID_PRODUCT_FROM_DATABASE=A130
+
+usb:v2770p9120*
+ ID_PRODUCT_FROM_DATABASE=Che-ez! Snap / iClick Tiny VGA Digital Camera
+
+usb:v2770p9130*
+ ID_PRODUCT_FROM_DATABASE=TCG 501
+
+usb:v2770p913C*
+ ID_PRODUCT_FROM_DATABASE=Argus DC-1730
+
+usb:v2770p9150*
+ ID_PRODUCT_FROM_DATABASE=Mini Cam
+
+usb:v2770p9153*
+ ID_PRODUCT_FROM_DATABASE=iClick 5X
+
+usb:v2770p915D*
+ ID_PRODUCT_FROM_DATABASE=Cyberpix S-210S / Little Tikes My Real Digital Camera
+
+usb:v2770p930B*
+ ID_PRODUCT_FROM_DATABASE=CCD Webcam(PC370R)
+
+usb:v2770p930C*
+ ID_PRODUCT_FROM_DATABASE=CCD Webcam(PC370R)
+
+usb:v2821*
+ ID_VENDOR_FROM_DATABASE=ASUSTek Computer Inc.
+
+usb:v2821p0161*
+ ID_PRODUCT_FROM_DATABASE=WL-161 802.11b Wireless Adapter [SiS 162U]
+
+usb:v2821p160F*
+ ID_PRODUCT_FROM_DATABASE=WL-160g 802.11g Wireless Adapter [Envara WiND512]
+
+usb:v2821p3300*
+ ID_PRODUCT_FROM_DATABASE=WL-140 / Hawking HWU36D 802.11b Wireless Adapter [Intersil PRISM 3]
+
+usb:v2899*
+ ID_VENDOR_FROM_DATABASE=Toptronic Industrial Co., Ltd
+
+usb:v2899p012C*
+ ID_PRODUCT_FROM_DATABASE=Camera Device
+
+usb:v2C02*
+ ID_VENDOR_FROM_DATABASE=Planex Communications
+
+usb:v2C02p14EA*
+ ID_PRODUCT_FROM_DATABASE=GW-US11H WLAN
+
+usb:v2C1A*
+ ID_VENDOR_FROM_DATABASE=Dolphin Peripherals
+
+usb:v2C1Ap0000*
+ ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse
+
+usb:v2FB2*
+ ID_VENDOR_FROM_DATABASE=Fujitsu, Ltd
+
+usb:v3125*
+ ID_VENDOR_FROM_DATABASE=Eagletron
+
+usb:v3125p0001*
+ ID_PRODUCT_FROM_DATABASE=TrackerPod Camera Stand
+
+usb:v3176*
+ ID_VENDOR_FROM_DATABASE=Whanam Electronics Co., Ltd
+
+usb:v3275*
+ ID_VENDOR_FROM_DATABASE=VidzMedia Pte Ltd
+
+usb:v3275p4FB1*
+ ID_PRODUCT_FROM_DATABASE=MonsterTV P2H
+
+usb:v3334*
+ ID_VENDOR_FROM_DATABASE=AEI
+
+usb:v3334p1701*
+ ID_PRODUCT_FROM_DATABASE=Fast Ethernet
+
+usb:v3340*
+ ID_VENDOR_FROM_DATABASE=Yakumo
+
+usb:v3340p043A*
+ ID_PRODUCT_FROM_DATABASE=Mio A701 DigiWalker PPCPhone
+
+usb:v3340p0E3A*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC 300 GPS SL / Typhoon MyGuide 3500
+
+usb:v3340pA0A3*
+ ID_PRODUCT_FROM_DATABASE=deltaX 5 BT (D) PDA
+
+usb:v3504*
+ ID_VENDOR_FROM_DATABASE=Micro Star
+
+usb:v3504pF110*
+ ID_PRODUCT_FROM_DATABASE=Security Key
+
+usb:v3538*
+ ID_VENDOR_FROM_DATABASE=Power Quotient International Co., Ltd
+
+usb:v3538p0001*
+ ID_PRODUCT_FROM_DATABASE=Travel Flash
+
+usb:v3538p0015*
+ ID_PRODUCT_FROM_DATABASE=Mass Storge Device
+
+usb:v3538p0022*
+ ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device
+
+usb:v3538p0042*
+ ID_PRODUCT_FROM_DATABASE=Cool Drive U339 Flash Disk
+
+usb:v3538p0054*
+ ID_PRODUCT_FROM_DATABASE=Flash Drive (2GB)
+
+usb:v3579*
+ ID_VENDOR_FROM_DATABASE=DIVA
+
+usb:v3579p6901*
+ ID_PRODUCT_FROM_DATABASE=Media Reader
+
+usb:v3636*
+ ID_VENDOR_FROM_DATABASE=InVibro
+
+usb:v3838*
+ ID_VENDOR_FROM_DATABASE=WEM
+
+usb:v3838p0001*
+ ID_PRODUCT_FROM_DATABASE=5-in-1 Card Reader
+
+usb:v3923*
+ ID_VENDOR_FROM_DATABASE=National Instruments Corp.
+
+usb:v3923p12C0*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6020E
+
+usb:v3923p12D0*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6507
+
+usb:v3923p12E0*
+ ID_PRODUCT_FROM_DATABASE=NI 4350
+
+usb:v3923p12F0*
+ ID_PRODUCT_FROM_DATABASE=NI 5102
+
+usb:v3923p1750*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6508
+
+usb:v3923p17B0*
+ ID_PRODUCT_FROM_DATABASE=USB-ISA-Bridge
+
+usb:v3923p1820*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6020E (68 pin I/O)
+
+usb:v3923p1830*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6020E (BNC)
+
+usb:v3923p1F00*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6024E
+
+usb:v3923p1F10*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6024E
+
+usb:v3923p1F20*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6025E
+
+usb:v3923p1F30*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6025E
+
+usb:v3923p1F40*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6036E
+
+usb:v3923p1F50*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6036E
+
+usb:v3923p2F80*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6052E
+
+usb:v3923p2F90*
+ ID_PRODUCT_FROM_DATABASE=DAQPad-6052E
+
+usb:v3923p702B*
+ ID_PRODUCT_FROM_DATABASE=GPIB-USB-B
+
+usb:v3923p703C*
+ ID_PRODUCT_FROM_DATABASE=USB-485 RS485 Cable
+
+usb:v3923p709B*
+ ID_PRODUCT_FROM_DATABASE=GPIB-USB-HS
+
+usb:v3923p7254*
+ ID_PRODUCT_FROM_DATABASE=NI MIO (data acquisition card) firmware updater
+
+usb:v3923p729E*
+ ID_PRODUCT_FROM_DATABASE=USB-6251 (OEM) data acquisition card
+
+usb:v40BB*
+ ID_VENDOR_FROM_DATABASE=I-O Data
+
+usb:v40BBp0A09*
+ ID_PRODUCT_FROM_DATABASE=USB2.0-SCSI Bridge USB2-SC
+
+usb:v4101*
+ ID_VENDOR_FROM_DATABASE=i-rocks
+
+usb:v4101p1301*
+ ID_PRODUCT_FROM_DATABASE=IR-2510 usb phone
+
+usb:v4102*
+ ID_VENDOR_FROM_DATABASE=iRiver, Ltd.
+
+usb:v4102p1001*
+ ID_PRODUCT_FROM_DATABASE=iFP-100 series mp3 player
+
+usb:v4102p1003*
+ ID_PRODUCT_FROM_DATABASE=iFP-300 series mp3 player
+
+usb:v4102p1005*
+ ID_PRODUCT_FROM_DATABASE=iFP-500 series mp3 player
+
+usb:v4102p1007*
+ ID_PRODUCT_FROM_DATABASE=iFP-700 series mp3/ogg vorbis player
+
+usb:v4102p1008*
+ ID_PRODUCT_FROM_DATABASE=iFP-800 series mp3/ogg vorbis player
+
+usb:v4102p100A*
+ ID_PRODUCT_FROM_DATABASE=iFP-1000 series mp3/ogg vorbis player
+
+usb:v4102p1014*
+ ID_PRODUCT_FROM_DATABASE=T20 series mp3/ogg vorbis player (ums firmware)
+
+usb:v4102p1019*
+ ID_PRODUCT_FROM_DATABASE=T30
+
+usb:v4102p1034*
+ ID_PRODUCT_FROM_DATABASE=T60
+
+usb:v4102p1040*
+ ID_PRODUCT_FROM_DATABASE=M1Player
+
+usb:v4102p1041*
+ ID_PRODUCT_FROM_DATABASE=E100 (ums)
+
+usb:v4102p1101*
+ ID_PRODUCT_FROM_DATABASE=iFP-100 series mp3 player (ums firmware)
+
+usb:v4102p1103*
+ ID_PRODUCT_FROM_DATABASE=iFP-300 series mp3 player (ums firmware)
+
+usb:v4102p1105*
+ ID_PRODUCT_FROM_DATABASE=iFP-500 series mp3 player (ums firmware)
+
+usb:v4102p1113*
+ ID_PRODUCT_FROM_DATABASE=T10 (alternate)
+
+usb:v4102p1117*
+ ID_PRODUCT_FROM_DATABASE=T10
+
+usb:v4102p1119*
+ ID_PRODUCT_FROM_DATABASE=T30 series mp3/ogg/wma player
+
+usb:v4102p1141*
+ ID_PRODUCT_FROM_DATABASE=E100 (mtp)
+
+usb:v4102p2002*
+ ID_PRODUCT_FROM_DATABASE=H10 6GB
+
+usb:v4102p2101*
+ ID_PRODUCT_FROM_DATABASE=H10 20GB (mtp)
+
+usb:v4102p2102*
+ ID_PRODUCT_FROM_DATABASE=H10 5GB (mtp)
+
+usb:v4102p2105*
+ ID_PRODUCT_FROM_DATABASE=H10 5/6GB (mtp)
+
+usb:v413C*
+ ID_VENDOR_FROM_DATABASE=Dell Computer Corp.
+
+usb:v413Cp0000*
+ ID_PRODUCT_FROM_DATABASE=DRAC 5 Virtual Keyboard and Mouse
+
+usb:v413Cp0001*
+ ID_PRODUCT_FROM_DATABASE=DRAC 5 Virtual Media
+
+usb:v413Cp0058*
+ ID_PRODUCT_FROM_DATABASE=Port Replicator
+
+usb:v413Cp1001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard Hub
+
+usb:v413Cp1002*
+ ID_PRODUCT_FROM_DATABASE=Keyboard Hub
+
+usb:v413Cp1003*
+ ID_PRODUCT_FROM_DATABASE=Keyboard Hub
+
+usb:v413Cp1005*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Pro Keyboard Hub
+
+usb:v413Cp2001*
+ ID_PRODUCT_FROM_DATABASE=Keyboard HID Support
+
+usb:v413Cp2002*
+ ID_PRODUCT_FROM_DATABASE=SK-8125 Keyboard
+
+usb:v413Cp2003*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v413Cp2005*
+ ID_PRODUCT_FROM_DATABASE=RT7D50 Keyboard
+
+usb:v413Cp2010*
+ ID_PRODUCT_FROM_DATABASE=Keyboard
+
+usb:v413Cp2011*
+ ID_PRODUCT_FROM_DATABASE=Multimedia Pro Keyboard
+
+usb:v413Cp2100*
+ ID_PRODUCT_FROM_DATABASE=SK-3106 Keyboard
+
+usb:v413Cp2101*
+ ID_PRODUCT_FROM_DATABASE=SmartCard Reader Keyboard
+
+usb:v413Cp2105*
+ ID_PRODUCT_FROM_DATABASE=Model L100 Keyboard
+
+usb:v413Cp2106*
+ ID_PRODUCT_FROM_DATABASE=Dell QuietKey Keyboard
+
+usb:v413Cp2500*
+ ID_PRODUCT_FROM_DATABASE=DRAC4 Remote Access Card
+
+usb:v413Cp2513*
+ ID_PRODUCT_FROM_DATABASE=internal USB Hub of E-Port Replicator
+
+usb:v413Cp3010*
+ ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse
+
+usb:v413Cp3012*
+ ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse
+
+usb:v413Cp3016*
+ ID_PRODUCT_FROM_DATABASE=Optical 5-Button Wheel Mouse
+
+usb:v413Cp3200*
+ ID_PRODUCT_FROM_DATABASE=Mouse
+
+usb:v413Cp4001*
+ ID_PRODUCT_FROM_DATABASE=Axim X5
+
+usb:v413Cp4002*
+ ID_PRODUCT_FROM_DATABASE=Axim X3
+
+usb:v413Cp4003*
+ ID_PRODUCT_FROM_DATABASE=Axim X30
+
+usb:v413Cp4004*
+ ID_PRODUCT_FROM_DATABASE=Axim Sync
+
+usb:v413Cp4005*
+ ID_PRODUCT_FROM_DATABASE=Axim Sync
+
+usb:v413Cp4006*
+ ID_PRODUCT_FROM_DATABASE=Axim Sync
+
+usb:v413Cp4007*
+ ID_PRODUCT_FROM_DATABASE=Axim Sync
+
+usb:v413Cp4008*
+ ID_PRODUCT_FROM_DATABASE=Axim Sync
+
+usb:v413Cp4009*
+ ID_PRODUCT_FROM_DATABASE=Axim Sync
+
+usb:v413Cp4011*
+ ID_PRODUCT_FROM_DATABASE=Axim X51v
+
+usb:v413Cp5103*
+ ID_PRODUCT_FROM_DATABASE=AIO Printer A940
+
+usb:v413Cp5105*
+ ID_PRODUCT_FROM_DATABASE=AIO Printer A920
+
+usb:v413Cp5107*
+ ID_PRODUCT_FROM_DATABASE=AIO Printer A960
+
+usb:v413Cp5109*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 922
+
+usb:v413Cp5110*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 962
+
+usb:v413Cp5111*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 942
+
+usb:v413Cp5112*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 924
+
+usb:v413Cp5113*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 944
+
+usb:v413Cp5114*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 964
+
+usb:v413Cp5115*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 926
+
+usb:v413Cp5116*
+ ID_PRODUCT_FROM_DATABASE=AIO Printer 946
+
+usb:v413Cp5117*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 966
+
+usb:v413Cp5118*
+ ID_PRODUCT_FROM_DATABASE=AIO 810
+
+usb:v413Cp5124*
+ ID_PRODUCT_FROM_DATABASE=Laser MFP 1815
+
+usb:v413Cp5128*
+ ID_PRODUCT_FROM_DATABASE=Photo AIO 928
+
+usb:v413Cp5200*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v413Cp5202*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v413Cp5203*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v413Cp5210*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v413Cp5211*
+ ID_PRODUCT_FROM_DATABASE=1110 Laser Printer
+
+usb:v413Cp5220*
+ ID_PRODUCT_FROM_DATABASE=Laser MFP 1600n
+
+usb:v413Cp5225*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v413Cp5226*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v413Cp5300*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v413Cp5400*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v413Cp5401*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer
+
+usb:v413Cp5513*
+ ID_PRODUCT_FROM_DATABASE=WLA3310 Wireless Adapter [Intersil ISL3887]
+
+usb:v413Cp5601*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer 3100cn
+
+usb:v413Cp5602*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer 3000cn
+
+usb:v413Cp5631*
+ ID_PRODUCT_FROM_DATABASE=Laser Printer 5100cn
+
+usb:v413Cp5905*
+ ID_PRODUCT_FROM_DATABASE=Printing Support
+
+usb:v413Cp8000*
+ ID_PRODUCT_FROM_DATABASE=BC02 Bluetooth Adapter
+
+usb:v413Cp8010*
+ ID_PRODUCT_FROM_DATABASE=TrueMobile Bluetooth Module in
+
+usb:v413Cp8100*
+ ID_PRODUCT_FROM_DATABASE=TrueMobile 1180 802.11b Adapter [Intersil PRISM 3]
+
+usb:v413Cp8102*
+ ID_PRODUCT_FROM_DATABASE=TrueMobile 1300 802.11g Wireless Adapter [Intersil ISL3880]
+
+usb:v413Cp8103*
+ ID_PRODUCT_FROM_DATABASE=Wireless 350 Bluetooth
+
+usb:v413Cp8104*
+ ID_PRODUCT_FROM_DATABASE=Wireless 1450 Dual-band (802.11a/b/g) Adapter [Intersil ISL3887]
+
+usb:v413Cp8105*
+ ID_PRODUCT_FROM_DATABASE=U2 in HID - Driver
+
+usb:v413Cp8106*
+ ID_PRODUCT_FROM_DATABASE=Wireless 350 Bluetooth Internal Card in
+
+usb:v413Cp8110*
+ ID_PRODUCT_FROM_DATABASE=Wireless 3xx Bluetooth Internal Card
+
+usb:v413Cp8111*
+ ID_PRODUCT_FROM_DATABASE=Wireless 3xx Bluetooth Internal Card in
+
+usb:v413Cp8114*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5700 Mobile Broadband (CDMA EV-DO) Minicard Modem
+
+usb:v413Cp8115*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5500 Mobile Broadband (3G HSDPA) Minicard Modem
+
+usb:v413Cp8116*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5505 Mobile Broadband (3G HSDPA) Minicard Modem
+
+usb:v413Cp8117*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5700 Mobile Broadband (CDMA EV-DO) Expresscard Modem
+
+usb:v413Cp8118*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5510 Mobile Broadband (3G HSDPA) Expresscard Status Port
+
+usb:v413Cp8120*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth adapter
+
+usb:v413Cp8121*
+ ID_PRODUCT_FROM_DATABASE=Eastfold in HID
+
+usb:v413Cp8122*
+ ID_PRODUCT_FROM_DATABASE=Eastfold in DFU
+
+usb:v413Cp8123*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v413Cp8124*
+ ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver
+
+usb:v413Cp8126*
+ ID_PRODUCT_FROM_DATABASE=Wireless 355 Bluetooth
+
+usb:v413Cp8127*
+ ID_PRODUCT_FROM_DATABASE=Wireless 355 Module with Bluetooth 2.0 + EDR Technology.
+
+usb:v413Cp8128*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5700-Sprint Mobile Broadband (CDMA EV-DO) Mini-Card Status Port
+
+usb:v413Cp8129*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5700-Telus Mobile Broadband (CDMA EV-DO) Mini-Card Status Port
+
+usb:v413Cp8131*
+ ID_PRODUCT_FROM_DATABASE=Wireless 360 Bluetooth 2.0 + EDR module.
+
+usb:v413Cp8133*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port
+
+usb:v413Cp8134*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5720 Sprint Mobile Broadband (EVDO Rev-A) Minicard Status Port
+
+usb:v413Cp8135*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5720 TELUS Mobile Broadband (EVDO Rev-A) Minicard Diagnostics Port
+
+usb:v413Cp8136*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5520 Cingular Mobile Broadband (3G HSDPA) Minicard Diagnostics Port
+
+usb:v413Cp8137*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5520 Voda L Mobile Broadband (3G HSDPA) Minicard Status Port
+
+usb:v413Cp8138*
+ ID_PRODUCT_FROM_DATABASE=Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard EAP-SIM Port
+
+usb:v413Cp8140*
+ ID_PRODUCT_FROM_DATABASE=Wireless 360 Bluetooth
+
+usb:v413Cp8142*
+ ID_PRODUCT_FROM_DATABASE=Mobile 360 in DFU
+
+usb:v413Cp8147*
+ ID_PRODUCT_FROM_DATABASE=F3507g Mobile Broadband Module
+
+usb:v413Cp8156*
+ ID_PRODUCT_FROM_DATABASE=Wireless 370 Bluetooth Mini-card
+
+usb:v413Cp8157*
+ ID_PRODUCT_FROM_DATABASE=Integrated Keyboard
+
+usb:v413Cp8158*
+ ID_PRODUCT_FROM_DATABASE=Integrated Touchpad / Trackstick
+
+usb:v413Cp8160*
+ ID_PRODUCT_FROM_DATABASE=Wireless 365 Bluetooth
+
+usb:v413Cp8161*
+ ID_PRODUCT_FROM_DATABASE=Integrated Keyboard
+
+usb:v413Cp8162*
+ ID_PRODUCT_FROM_DATABASE=Integrated Touchpad [Synaptics]
+
+usb:v413Cp8171*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode)
+
+usb:v413Cp8172*
+ ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem
+
+usb:v413Cp8183*
+ ID_PRODUCT_FROM_DATABASE=F3607gw Mobile Broadband Module
+
+usb:v413Cp8184*
+ ID_PRODUCT_FROM_DATABASE=F3607gw v2 Mobile Broadband Module
+
+usb:v413Cp8185*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem (QDL mode)
+
+usb:v413Cp8186*
+ ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem
+
+usb:v413Cp8187*
+ ID_PRODUCT_FROM_DATABASE=DW375 Bluetooth Module
+
+usb:v413Cp8501*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter
+
+usb:v413Cp9500*
+ ID_PRODUCT_FROM_DATABASE=USB CP210x UART Bridge Controller [DW700]
+
+usb:v413CpA001*
+ ID_PRODUCT_FROM_DATABASE=Hub
+
+usb:v413CpA005*
+ ID_PRODUCT_FROM_DATABASE=Internal 2.0 Hub
+
+usb:v413CpA700*
+ ID_PRODUCT_FROM_DATABASE=Hub (in 1905FP LCD Monitor)
+
+usb:v4146*
+ ID_VENDOR_FROM_DATABASE=USBest Technology
+
+usb:v4146p9281*
+ ID_PRODUCT_FROM_DATABASE=Iomega Micro Mini 128MB Flash Drive
+
+usb:v4146pBA01*
+ ID_PRODUCT_FROM_DATABASE=Intuix Flash Drive
+
+usb:v4242*
+ ID_VENDOR_FROM_DATABASE=USB Design by Example
+
+usb:v4242p4201*
+ ID_PRODUCT_FROM_DATABASE=Buttons and Lights HID device
+
+usb:v4242p4220*
+ ID_PRODUCT_FROM_DATABASE=Echo 1 Camera
+
+usb:v4317*
+ ID_VENDOR_FROM_DATABASE=Broadcom Corp.
+
+usb:v4317p0700*
+ ID_PRODUCT_FROM_DATABASE=U.S. Robotics USR5426 802.11g Adapter
+
+usb:v4317p0701*
+ ID_PRODUCT_FROM_DATABASE=U.S. Robotics USR5425 Wireless MAXg Adapter
+
+usb:v4317p0711*
+ ID_PRODUCT_FROM_DATABASE=Belkin F5D7051 v3000 802.11g
+
+usb:v4317p0720*
+ ID_PRODUCT_FROM_DATABASE=Dynex DX-BUSB
+
+usb:v4348*
+ ID_VENDOR_FROM_DATABASE=WinChipHead
+
+usb:v4348p5523*
+ ID_PRODUCT_FROM_DATABASE=USB->RS 232 adapter with Prolifec PL 2303 chipset
+
+usb:v4348p5537*
+ ID_PRODUCT_FROM_DATABASE=13.56Mhz RFID Card Reader and Writer
+
+usb:v4348p5584*
+ ID_PRODUCT_FROM_DATABASE=CH34x printer adapter cable
+
+usb:v4572*
+ ID_VENDOR_FROM_DATABASE=Shuttle, Inc.
+
+usb:v4572p4572*
+ ID_PRODUCT_FROM_DATABASE=Shuttle PN31 Remote
+
+usb:v4586*
+ ID_VENDOR_FROM_DATABASE=Panram
+
+usb:v4586p1026*
+ ID_PRODUCT_FROM_DATABASE=Crystal Bar Flash Drive
+
+usb:v4670*
+ ID_VENDOR_FROM_DATABASE=EMS Production
+
+usb:v4670p9394*
+ ID_PRODUCT_FROM_DATABASE=Game Cube USB Memory Adaptor 64M
+
+usb:v4752*
+ ID_VENDOR_FROM_DATABASE=Miditech
+
+usb:v4752p0011*
+ ID_PRODUCT_FROM_DATABASE=Midistart-2
+
+usb:v4757*
+ ID_VENDOR_FROM_DATABASE=GW Instek
+
+usb:v4757p2009*
+ ID_PRODUCT_FROM_DATABASE=PEL-2000 Series Electronic Load (CDC)
+
+usb:v4757p2010*
+ ID_PRODUCT_FROM_DATABASE=PEL-2000 Series Electronic Load (CDC)
+
+usb:v4766*
+ ID_VENDOR_FROM_DATABASE=Aceeca
+
+usb:v4766p0001*
+ ID_PRODUCT_FROM_DATABASE=MEZ1000 RDA
+
+usb:v4855*
+ ID_VENDOR_FROM_DATABASE=Memorex
+
+usb:v4855p7288*
+ ID_PRODUCT_FROM_DATABASE=Ultra Traveldrive 160G 2.5" HDD
+
+usb:v4971*
+ ID_VENDOR_FROM_DATABASE=SimpleTech
+
+usb:v4971pCB01*
+ ID_PRODUCT_FROM_DATABASE=SP-U25/120G
+
+usb:v4971pCE17*
+ ID_PRODUCT_FROM_DATABASE=1TB SimpleDrive II USB External Hard Drive
+
+usb:v4D46*
+ ID_VENDOR_FROM_DATABASE=Musical Fidelity
+
+usb:v4D46p0001*
+ ID_PRODUCT_FROM_DATABASE=V-Link
+
+usb:v4D46p0002*
+ ID_PRODUCT_FROM_DATABASE=V-DAC II
+
+usb:v5032*
+ ID_VENDOR_FROM_DATABASE=Grandtec
+
+usb:v5032p0BB8*
+ ID_PRODUCT_FROM_DATABASE=Grandtec USB1.1 DVB-T (cold)
+
+usb:v5032p0BB9*
+ ID_PRODUCT_FROM_DATABASE=Grandtec USB1.1 DVB-T (warm)
+
+usb:v5032p0FA0*
+ ID_PRODUCT_FROM_DATABASE=Grandtec USB1.1 DVB-T (cold)
+
+usb:v5032p0FA1*
+ ID_PRODUCT_FROM_DATABASE=Grandtec USB1.1 DVB-T (warm)
+
+usb:v5041*
+ ID_VENDOR_FROM_DATABASE=Linksys (?)
+
+usb:v5041p2234*
+ ID_PRODUCT_FROM_DATABASE=WUSB54G v1 802.11g Adapter [Intersil ISL3886]
+
+usb:v5041p2235*
+ ID_PRODUCT_FROM_DATABASE=WUSB54GP v1 802.11g Adapter [Intersil ISL3886]
+
+usb:v50C2*
+ ID_VENDOR_FROM_DATABASE=Averatec (?)
+
+usb:v50C2p4013*
+ ID_PRODUCT_FROM_DATABASE=WLAN Adapter
+
+usb:v5173*
+ ID_VENDOR_FROM_DATABASE=Sweex
+
+usb:v5173p1809*
+ ID_PRODUCT_FROM_DATABASE=ZD1211
+
+usb:v5219*
+ ID_VENDOR_FROM_DATABASE=I-Tetra
+
+usb:v5219p1001*
+ ID_PRODUCT_FROM_DATABASE=Cetus CDC Device
+
+usb:v5345*
+ ID_VENDOR_FROM_DATABASE=Owon
+
+usb:v5345p1234*
+ ID_PRODUCT_FROM_DATABASE=PDS6062T Oscilloscope
+
+usb:v544D*
+ ID_VENDOR_FROM_DATABASE=Transmeta Corp.
+
+usb:v5543*
+ ID_VENDOR_FROM_DATABASE=UC-Logic Technology Corp.
+
+usb:v5543p0002*
+ ID_PRODUCT_FROM_DATABASE=SuperPen WP3325U Tablet
+
+usb:v5543p0003*
+ ID_PRODUCT_FROM_DATABASE=Tablet WP4030U
+
+usb:v5543p0004*
+ ID_PRODUCT_FROM_DATABASE=Tablet WP5540U
+
+usb:v5543p0005*
+ ID_PRODUCT_FROM_DATABASE=Tablet WP8060U
+
+usb:v5543p0041*
+ ID_PRODUCT_FROM_DATABASE=Genius PenSketch 6x8 Tablet
+
+usb:v5543p0042*
+ ID_PRODUCT_FROM_DATABASE=Tablet PF1209
+
+usb:v5543p0064*
+ ID_PRODUCT_FROM_DATABASE=Aiptek HyperPen 10000U
+
+usb:v5555*
+ ID_VENDOR_FROM_DATABASE=Epiphan Systems Inc.
+
+usb:v5555p1110*
+ ID_PRODUCT_FROM_DATABASE=VGA2USB
+
+usb:v5555p1120*
+ ID_PRODUCT_FROM_DATABASE=KVM2USB
+
+usb:v5555p2222*
+ ID_PRODUCT_FROM_DATABASE=DVI2USB
+
+usb:v5555p3333*
+ ID_PRODUCT_FROM_DATABASE=VGA2USB Pro
+
+usb:v5555p3337*
+ ID_PRODUCT_FROM_DATABASE=KVM2USB Pro
+
+usb:v5555p3340*
+ ID_PRODUCT_FROM_DATABASE=VGA2USB LR
+
+usb:v5555p3344*
+ ID_PRODUCT_FROM_DATABASE=KVM2USB LR
+
+usb:v5555p3411*
+ ID_PRODUCT_FROM_DATABASE=DVI2USB Solo
+
+usb:v5555p3422*
+ ID_PRODUCT_FROM_DATABASE=DVI2USB Duo
+
+usb:v55AA*
+ ID_VENDOR_FROM_DATABASE=OnSpec Electronic, Inc.
+
+usb:v55AAp0015*
+ ID_PRODUCT_FROM_DATABASE=Hard Drive
+
+usb:v55AAp0102*
+ ID_PRODUCT_FROM_DATABASE=SuperDisk
+
+usb:v55AAp0103*
+ ID_PRODUCT_FROM_DATABASE=IDE Hard Drive
+
+usb:v55AAp0201*
+ ID_PRODUCT_FROM_DATABASE=DDI to Reader-19
+
+usb:v55AAp1234*
+ ID_PRODUCT_FROM_DATABASE=ATAPI Bridge
+
+usb:v55AApA103*
+ ID_PRODUCT_FROM_DATABASE=Sandisk SDDR-55 SmartMedia Card Reader
+
+usb:v55AApB000*
+ ID_PRODUCT_FROM_DATABASE=USB to CompactFlash Card Reader
+
+usb:v55AApB004*
+ ID_PRODUCT_FROM_DATABASE=OnSpec MMC/SD Reader/Writer
+
+usb:v55AApB00B*
+ ID_PRODUCT_FROM_DATABASE=USB to Memory Stick Card Reader
+
+usb:v55AApB00C*
+ ID_PRODUCT_FROM_DATABASE=USB to SmartMedia Card Reader
+
+usb:v55AApB012*
+ ID_PRODUCT_FROM_DATABASE=Mitsumi FA402M 8-in-2 Card Reader
+
+usb:v55AApB200*
+ ID_PRODUCT_FROM_DATABASE=Compact Flash Reader
+
+usb:v55AApB204*
+ ID_PRODUCT_FROM_DATABASE=MMC/ SD Reader
+
+usb:v55AApB207*
+ ID_PRODUCT_FROM_DATABASE=Memory Stick Reader
+
+usb:v5656*
+ ID_VENDOR_FROM_DATABASE=Uni-Trend Group Limited
+
+usb:v5656p0832*
+ ID_PRODUCT_FROM_DATABASE=UT2000/UT3000 Digital Storage Oscilloscope
+
+usb:v595A*
+ ID_VENDOR_FROM_DATABASE=IRTOUCHSYSTEMS Co. Ltd.
+
+usb:v595Ap0001*
+ ID_PRODUCT_FROM_DATABASE=Touchscreen
+
+usb:v5986*
+ ID_VENDOR_FROM_DATABASE=Acer, Inc
+
+usb:v5986p0100*
+ ID_PRODUCT_FROM_DATABASE=Orbicam
+
+usb:v5986p0101*
+ ID_PRODUCT_FROM_DATABASE=USB2.0 Camera
+
+usb:v5986p0102*
+ ID_PRODUCT_FROM_DATABASE=Crystal Eye Webcam
+
+usb:v5986p01A6*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam
+
+usb:v5986p01A7*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam
+
+usb:v5986p01A9*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam
+
+usb:v5986p0200*
+ ID_PRODUCT_FROM_DATABASE=OrbiCam
+
+usb:v5986p0203*
+ ID_PRODUCT_FROM_DATABASE=BisonCam NB Pro 1300
+
+usb:v5986p0241*
+ ID_PRODUCT_FROM_DATABASE=BisonCam, NB Pro
+
+usb:v5986p02D0*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam [R5U877]
+
+usb:v5986p03D0*
+ ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam [R5U877]
+
+usb:v5A57*
+ ID_VENDOR_FROM_DATABASE=Zinwell
+
+usb:v5A57p0260*
+ ID_PRODUCT_FROM_DATABASE=RT2570
+
+usb:v5A57p0280*
+ ID_PRODUCT_FROM_DATABASE=802.11a/b/g/n USB Wireless LAN Card
+
+usb:v5A57p0282*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g/n USB Wireless LAN Card
+
+usb:v5A57p0283*
+ ID_PRODUCT_FROM_DATABASE=802.11b/g/n USB Wireless LAN Card
+
+usb:v5A57p0284*
+ ID_PRODUCT_FROM_DATABASE=802.11a/b/g/n USB Wireless LAN Card
+
+usb:v5A57p0290*
+ ID_PRODUCT_FROM_DATABASE=ZW-N290 802.11n [Realtek RTL8192SU]
+
+usb:v5A57p5257*
+ ID_PRODUCT_FROM_DATABASE=Metronic 495257 wifi 802.11ng
+
+usb:v6000*
+ ID_VENDOR_FROM_DATABASE=Beholder International Ltd.
+
+usb:v6000pDEC0*
+ ID_PRODUCT_FROM_DATABASE=TV Wander
+
+usb:v6000pDEC1*
+ ID_PRODUCT_FROM_DATABASE=TV Voyage
+
+usb:v601A*
+ ID_VENDOR_FROM_DATABASE=Ingenic Semiconductor Ltd.
+
+usb:v601Ap4740*
+ ID_PRODUCT_FROM_DATABASE=XBurst Jz4740 boot mode
+
+usb:v6189*
+ ID_VENDOR_FROM_DATABASE=Sitecom
+
+usb:v6189p182D*
+ ID_PRODUCT_FROM_DATABASE=USB 2.0 Ethernet
+
+usb:v6189p2068*
+ ID_PRODUCT_FROM_DATABASE=USB to serial cable (v2)
+
+usb:v6253*
+ ID_VENDOR_FROM_DATABASE=TwinHan Technology Co., Ltd
+
+usb:v6253p0100*
+ ID_PRODUCT_FROM_DATABASE=Ir reciver f. remote control
+
+usb:v636C*
+ ID_VENDOR_FROM_DATABASE=CoreLogic, Inc.
+
+usb:v6472*
+ ID_VENDOR_FROM_DATABASE=Unknown (Sony?)
+
+usb:v6472p01C8*
+ ID_PRODUCT_FROM_DATABASE=PlayStation Portable [Mass Storage]
+
+usb:v6547*
+ ID_VENDOR_FROM_DATABASE=Arkmicro Technologies Inc.
+
+usb:v6547p0232*
+ ID_PRODUCT_FROM_DATABASE=ARK3116 Serial
+
+usb:v6615*
+ ID_VENDOR_FROM_DATABASE=IRTOUCHSYSTEMS Co. Ltd.
+
+usb:v6615p0001*
+ ID_PRODUCT_FROM_DATABASE=Touchscreen
+
+usb:v6666*
+ ID_VENDOR_FROM_DATABASE=Prototype product Vendor ID
+
+usb:v6666p0667*
+ ID_PRODUCT_FROM_DATABASE=WiseGroup Smart Joy PSX, PS-PC Smart JoyPad
+
+usb:v6666p2667*
+ ID_PRODUCT_FROM_DATABASE=JCOP BlueZ Smartcard reader
+
+usb:v6666p8802*
+ ID_PRODUCT_FROM_DATABASE=SmartJoy Dual Plus PS2 converter
+
+usb:v6666p8804*
+ ID_PRODUCT_FROM_DATABASE=WiseGroup SuperJoy Box 5
+
+usb:v6677*
+ ID_VENDOR_FROM_DATABASE=WiseGroup, Ltd.
+
+usb:v6677p8802*
+ ID_PRODUCT_FROM_DATABASE=SmartJoy Dual Plus PS2 converter
+
+usb:v6677p8811*
+ ID_PRODUCT_FROM_DATABASE=Deluxe Dance Mat
+
+usb:v6891*
+ ID_VENDOR_FROM_DATABASE=3Com
+
+usb:v6891pA727*
+ ID_PRODUCT_FROM_DATABASE=3CRUSB10075 802.11bg [ZyDAS ZD1211]
+
+usb:v695C*
+ ID_VENDOR_FROM_DATABASE=Opera1
+
+usb:v695Cp3829*
+ ID_PRODUCT_FROM_DATABASE=Opera1 DVB-S (warm state)
+
+usb:v6993*
+ ID_VENDOR_FROM_DATABASE=Yealink Network Technology Co., Ltd.
+
+usb:v6993pB001*
+ ID_PRODUCT_FROM_DATABASE=VoIP Phone
+
+usb:v6A75*
+ ID_VENDOR_FROM_DATABASE=Shanghai Jujo Electronics Co., Ltd
+
+usb:v7104*
+ ID_VENDOR_FROM_DATABASE=CME (Central Music Co.)
+
+usb:v7104p2202*
+ ID_PRODUCT_FROM_DATABASE=UF5/UF6/UF7/UF8 MIDI Master Keyboard
+
+usb:v726C*
+ ID_VENDOR_FROM_DATABASE=StackFoundry LLC
+
+usb:v726Cp2149*
+ ID_PRODUCT_FROM_DATABASE=EntropyKing Random Number Generator
+
+usb:v734C*
+ ID_VENDOR_FROM_DATABASE=TBS Technologies China
+
+usb:v734Cp5920*
+ ID_PRODUCT_FROM_DATABASE=Q-Box II DVB-S2 HD
+
+usb:v734Cp5928*
+ ID_PRODUCT_FROM_DATABASE=Q-Box II DVB-S2 HD
+
+usb:v7392*
+ ID_VENDOR_FROM_DATABASE=Edimax Technology Co., Ltd
+
+usb:v7392p7711*
+ ID_PRODUCT_FROM_DATABASE=EW-7711UTn nLite Wireless Adapter [Ralink RT2870]
+
+usb:v7392p7717*
+ ID_PRODUCT_FROM_DATABASE=EW-7717UN 802.11n Wireless Adapter [Ralink RT2870]
+
+usb:v7392p7718*
+ ID_PRODUCT_FROM_DATABASE=EW-7718UN 802.11n Wireless Adapter [Ralink RT2870]
+
+usb:v7392p7722*
+ ID_PRODUCT_FROM_DATABASE=EW-7722UTn 802.11n Wireless Adapter [Ralink RT307x]
+
+usb:v7392p7811*
+ ID_PRODUCT_FROM_DATABASE=EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS]
+
+usb:v8086*
+ ID_VENDOR_FROM_DATABASE=Intel Corp.
+
+usb:v8086p0001*
+ ID_PRODUCT_FROM_DATABASE=AnyPoint (TM) Home Network 1.6 Mbps Wireless Adapter
+
+usb:v8086p0044*
+ ID_PRODUCT_FROM_DATABASE=CPU DRAM Controller
+
+usb:v8086p0046*
+ ID_PRODUCT_FROM_DATABASE=HD Graphics
+
+usb:v8086p0100*
+ ID_PRODUCT_FROM_DATABASE=Personal Audio Player 3000
+
+usb:v8086p0101*
+ ID_PRODUCT_FROM_DATABASE=Personal Audio Player 3000
+
+usb:v8086p0110*
+ ID_PRODUCT_FROM_DATABASE=Easy PC Camera
+
+usb:v8086p0120*
+ ID_PRODUCT_FROM_DATABASE=PC Camera CS120
+
+usb:v8086p0180*
+ ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m
+
+usb:v8086p0181*
+ ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m
+
+usb:v8086p0182*
+ ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m
+
+usb:v8086p0186*
+ ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m
+
+usb:v8086p0188*
+ ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m
+
+usb:v8086p0200*
+ ID_PRODUCT_FROM_DATABASE=AnyPoint(TM) Wireless II Network 11Mbps Adapter [Atmel AT76C503A]
+
+usb:v8086p0431*
+ ID_PRODUCT_FROM_DATABASE=Intel Pro Video PC Camera
+
+usb:v8086p0510*
+ ID_PRODUCT_FROM_DATABASE=Digital Movie Creator
+
+usb:v8086p0630*
+ ID_PRODUCT_FROM_DATABASE=Pocket PC Camera
+
+usb:v8086p0780*
+ ID_PRODUCT_FROM_DATABASE=CS780 Microphone Input
+
+usb:v8086p07D3*
+ ID_PRODUCT_FROM_DATABASE=BLOB boot loader firmware
+
+usb:v8086p0DAD*
+ ID_PRODUCT_FROM_DATABASE=Cherry MiniatureCard Keyboard
+
+usb:v8086p1010*
+ ID_PRODUCT_FROM_DATABASE=AnyPoint(TM) Home Network 10 Mbps Phoneline Adapter
+
+usb:v8086p110A*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller from (Ericsson P4A)
+
+usb:v8086p110B*
+ ID_PRODUCT_FROM_DATABASE=Bluetooth Controller from (Intel/CSR)
+
+usb:v8086p1110*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless LAN Module
+
+usb:v8086p1111*
+ ID_PRODUCT_FROM_DATABASE=PRO/Wireless 2011B 802.11b Adapter [Intersil PRISM 2.5]
+
+usb:v8086p1134*
+ ID_PRODUCT_FROM_DATABASE=Hollister Mobile Monitor
+
+usb:v8086p1139*
+ ID_PRODUCT_FROM_DATABASE=In-Target Probe (ITP)
+
+usb:v8086p1234*
+ ID_PRODUCT_FROM_DATABASE=Prototype Reader/Writer
+
+usb:v8086p1403*
+ ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m
+
+usb:v8086p1405*
+ ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m
+
+usb:v8086p1406*
+ ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m
+
+usb:v8086p2448*
+ ID_PRODUCT_FROM_DATABASE=82801 PCI Bridge
+
+usb:v8086p3100*
+ ID_PRODUCT_FROM_DATABASE=PRO/DSL 3220 Modem - WAN
+
+usb:v8086p3101*
+ ID_PRODUCT_FROM_DATABASE=PRO/DSL 3220 Modem
+
+usb:v8086p3240*
+ ID_PRODUCT_FROM_DATABASE=AnyPoint® 3240 Modem - WAN
+
+usb:v8086p3241*
+ ID_PRODUCT_FROM_DATABASE=AnyPoint® 3240 Modem
+
+usb:v8086p8602*
+ ID_PRODUCT_FROM_DATABASE=Miniature Card Slot
+
+usb:v8086p9303*
+ ID_PRODUCT_FROM_DATABASE=Intel 8x930Hx Hub
+
+usb:v8086p9500*
+ ID_PRODUCT_FROM_DATABASE=CE 9500 DVB-T
+
+usb:v8086p9890*
+ ID_PRODUCT_FROM_DATABASE=82930 Test Board
+
+usb:v8086pBEEF*
+ ID_PRODUCT_FROM_DATABASE=SCM Miniature Card Reader/Writer
+
+usb:v8086pC013*
+ ID_PRODUCT_FROM_DATABASE=Wireless HID Station
+
+usb:v8086pF001*
+ ID_PRODUCT_FROM_DATABASE=XScale PXA27x Bulverde flash
+
+usb:v8086pF1A5*
+ ID_PRODUCT_FROM_DATABASE=Z-U130 [Value Solid State Drive]
+
+usb:v8087*
+ ID_VENDOR_FROM_DATABASE=Intel Corp.
+
+usb:v8087p0020*
+ ID_PRODUCT_FROM_DATABASE=Integrated Rate Matching Hub
+
+usb:v8087p0024*
+ ID_PRODUCT_FROM_DATABASE=Integrated Rate Matching Hub
+
+usb:v80EE*
+ ID_VENDOR_FROM_DATABASE=VirtualBox
+
+usb:v80EEp0021*
+ ID_PRODUCT_FROM_DATABASE=USB Tablet
+
+usb:v8282*
+ ID_VENDOR_FROM_DATABASE=Keio
+
+usb:v8282p3201*
+ ID_PRODUCT_FROM_DATABASE=Retro Adapter
+
+usb:v8282p3301*
+ ID_PRODUCT_FROM_DATABASE=Retro Adapter Mouse
+
+usb:v8341*
+ ID_VENDOR_FROM_DATABASE=EGO Systems, Inc.
+
+usb:v8341p2000*
+ ID_PRODUCT_FROM_DATABASE=Flashdisk
+
+usb:v9016*
+ ID_VENDOR_FROM_DATABASE=Sitecom
+
+usb:v9016p182D*
+ ID_PRODUCT_FROM_DATABASE=WL-022 802.11b Adapter
+
+usb:v9022*
+ ID_VENDOR_FROM_DATABASE=TeVii Technology Ltd.
+
+usb:v9022pD630*
+ ID_PRODUCT_FROM_DATABASE=DVB-S S630
+
+usb:v9022pD650*
+ ID_PRODUCT_FROM_DATABASE=DVB-S2 S650
+
+usb:v9022pD660*
+ ID_PRODUCT_FROM_DATABASE=DVB-S2 S660
+
+usb:v9148*
+ ID_VENDOR_FROM_DATABASE=GeoLab, Ltd
+
+usb:v9148p0004*
+ ID_PRODUCT_FROM_DATABASE=R3 Compatible Device
+
+usb:v9710*
+ ID_VENDOR_FROM_DATABASE=MosChip Semiconductor
+
+usb:v9710p7703*
+ ID_PRODUCT_FROM_DATABASE=MCS7703 Serial Port Adapter
+
+usb:v9710p7705*
+ ID_PRODUCT_FROM_DATABASE=MCS7705 Parallel port adapter
+
+usb:v9710p7715*
+ ID_PRODUCT_FROM_DATABASE=MCS7715 Parallel and serial port adapter
+
+usb:v9710p7717*
+ ID_PRODUCT_FROM_DATABASE=MCS7717 3-port hub with serial and parallel adapter
+
+usb:v9710p7720*
+ ID_PRODUCT_FROM_DATABASE=MCS7720 Dual serial port adapter
+
+usb:v9710p7730*
+ ID_PRODUCT_FROM_DATABASE=MCS7730 10/100 Mbps Ethernet adapter
+
+usb:v9710p7780*
+ ID_PRODUCT_FROM_DATABASE=MCS7780 4Mbps Fast IrDA Adapter
+
+usb:v9710p7830*
+ ID_PRODUCT_FROM_DATABASE=MCS7830 10/100 Mbps Ethernet adapter
+
+usb:v9710p7832*
+ ID_PRODUCT_FROM_DATABASE=MCS7832 10/100 Mbps Ethernet adapter
+
+usb:v9710p7840*
+ ID_PRODUCT_FROM_DATABASE=MCS7820/MCS7840 2/4 port serial adapter
+
+usb:v99FA*
+ ID_VENDOR_FROM_DATABASE=Grandtec
+
+usb:v99FAp8988*
+ ID_PRODUCT_FROM_DATABASE=V.cap Camera Device
+
+usb:v9AC4*
+ ID_VENDOR_FROM_DATABASE=J. Westhues
+
+usb:v9AC4p4B8F*
+ ID_PRODUCT_FROM_DATABASE=ProxMark-3 RFID Instrument
+
+usb:vA128*
+ ID_VENDOR_FROM_DATABASE=AnMo Electronics Corp. / Dino-Lite (?)
+
+usb:vA128p0610*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + HV7131R)
+
+usb:vA128p0611*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + HV7131R)
+
+usb:vA128p0612*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C120 + HV7131R)
+
+usb:vA128p0613*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + HV7131R)
+
+usb:vA128p0614*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + MI1310/MT9M111)
+
+usb:vA128p0615*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + MI1310/MT9M111)
+
+usb:vA128p0616*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C120 + HV7131R)
+
+usb:vA128p0617*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + MI1310/MT9M111)
+
+usb:vA128p0618*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + HV7131R)
+
+usb:vA168*
+ ID_VENDOR_FROM_DATABASE=AnMo Electronics Corporation
+
+usb:vA168p0610*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope
+
+usb:vA168p0611*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope
+
+usb:vA168p0613*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope
+
+usb:vA168p0614*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Pro Digital Microscope
+
+usb:vA168p0615*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Pro Digital Microscope
+
+usb:vA168p0617*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Pro Digital Microscope
+
+usb:vA168p0618*
+ ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope
+
+usb:vA600*
+ ID_VENDOR_FROM_DATABASE=Asix
+
+usb:vA600pE110*
+ ID_PRODUCT_FROM_DATABASE=OK1ZIA Davac 4.x
+
+usb:vA727*
+ ID_VENDOR_FROM_DATABASE=3Com
+
+usb:vA727p6893*
+ ID_PRODUCT_FROM_DATABASE=3CRUSB20075 OfficeConnect Wireless 108Mbps 11g Adapter [Atheros AR5523]
+
+usb:vA727p6895*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:vA727p6897*
+ ID_PRODUCT_FROM_DATABASE=AR5523
+
+usb:vABCD*
+ ID_VENDOR_FROM_DATABASE=Unknown
+
+usb:vABCDpCDEE*
+ ID_PRODUCT_FROM_DATABASE=Petcam
+
+usb:vC251*
+ ID_VENDOR_FROM_DATABASE=Keil Software, Inc.
+
+usb:vC251p2710*
+ ID_PRODUCT_FROM_DATABASE=ULink
+
+usb:vCACE*
+ ID_VENDOR_FROM_DATABASE=CACE Technologies Inc.
+
+usb:vCACEp0002*
+ ID_PRODUCT_FROM_DATABASE=AirPCAP Classic 802.11 packet capture adapter
+
+usb:vCACEp0300*
+ ID_PRODUCT_FROM_DATABASE=AirPcap NX [Atheros AR9001U-(2)NG]
+
+usb:vD209*
+ ID_VENDOR_FROM_DATABASE=Ultimarc
+
+usb:vD209p0301*
+ ID_PRODUCT_FROM_DATABASE=I-PAC Arcade Control Interface
+
+usb:vD209p0501*
+ ID_PRODUCT_FROM_DATABASE=Ultra-Stik Ultimarc Ultra-Stik Player 1
+
+usb:vE4E4*
+ ID_VENDOR_FROM_DATABASE=Xorcom Ltd.
+
+usb:vE4E4p1130*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1131*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1132*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1140*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1141*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1142*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1150*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1151*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1152*
+ ID_PRODUCT_FROM_DATABASE=Astribank series
+
+usb:vE4E4p1160*
+ ID_PRODUCT_FROM_DATABASE=Astribank 2 series
+
+usb:vE4E4p1161*
+ ID_PRODUCT_FROM_DATABASE=Astribank 2 series
+
+usb:vE4E4p1162*
+ ID_PRODUCT_FROM_DATABASE=Astribank 2 series
+
+usb:vEB03*
+ ID_VENDOR_FROM_DATABASE=MakingThings
+
+usb:vEB03p0920*
+ ID_PRODUCT_FROM_DATABASE=Make Controller Kit
+
+usb:vEB1A*
+ ID_VENDOR_FROM_DATABASE=eMPIA Technology, Inc.
+
+usb:vEB1Ap17DE*
+ ID_PRODUCT_FROM_DATABASE=KWorld V-Stream XPERT DTV - DVB-T USB cold
+
+usb:vEB1Ap17DF*
+ ID_PRODUCT_FROM_DATABASE=KWorld V-Stream XPERT DTV - DVB-T USB warm
+
+usb:vEB1Ap2571*
+ ID_PRODUCT_FROM_DATABASE=M035 Compact Web Cam
+
+usb:vEB1Ap2710*
+ ID_PRODUCT_FROM_DATABASE=SilverCrest Webcam
+
+usb:vEB1Ap2750*
+ ID_PRODUCT_FROM_DATABASE=ECS Elitegroup G220 integrated Webcam
+
+usb:vEB1Ap2761*
+ ID_PRODUCT_FROM_DATABASE=EeePC 701 integrated Webcam
+
+usb:vEB1Ap2776*
+ ID_PRODUCT_FROM_DATABASE=Combined audio and video input device
+
+usb:vEB1Ap2800*
+ ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 200
+
+usb:vEB1Ap2801*
+ ID_PRODUCT_FROM_DATABASE=GrabBeeX+ Video Encoder
+
+usb:vEB1Ap2863*
+ ID_PRODUCT_FROM_DATABASE=Video Grabber
+
+usb:vEB1Ap2870*
+ ID_PRODUCT_FROM_DATABASE=Pinnacle PCTV Stick
+
+usb:vEB1Ap2881*
+ ID_PRODUCT_FROM_DATABASE=EM2881 Video Controller
+
+usb:vEB1Ap50A3*
+ ID_PRODUCT_FROM_DATABASE=Gadmei UTV380 TV Box
+
+usb:vEB1Ap50A6*
+ ID_PRODUCT_FROM_DATABASE=Gadmei UTV330 TV Box
+
+usb:vEB1ApE355*
+ ID_PRODUCT_FROM_DATABASE=KWorld DVB-T 355U Digital TV Dongle
+
+usb:vEB2A*
+ ID_VENDOR_FROM_DATABASE=KWorld
+
+usb:vF003*
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard
+
+usb:vF003p6002*
+ ID_PRODUCT_FROM_DATABASE=PhotoSmart C500
+
+usb:vF4EC*
+ ID_VENDOR_FROM_DATABASE=Atten Electronics / Siglent Technologies
+
+usb:vF4ECpEE38*
+ ID_PRODUCT_FROM_DATABASE=Digital Storage Oscilloscope
diff --git a/hwdb/ids-update.pl b/hwdb/ids-update.pl
new file mode 100755 (executable)
index 0000000..13596b8
--- /dev/null
@@ -0,0 +1,268 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+sub usb_vendor {
+        my $vendor;
+
+        open(IN, "<", "usb.ids");
+        open(OUT, ">", "20-usb-vendor-product.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported from: http://www.linux-usb.org/usb.ids\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+                $line =~ m/^([0-9a-f]{4})\s*(.+)$/;
+                if (defined $1) {
+                        $vendor = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "usb:v" . $vendor . "*\n");
+                        print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t([0-9a-f]{4})\s*(.+)$/;
+                if (defined $1) {
+                        my $product = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "usb:v" . $vendor . "p" . $product . "*\n");
+                        print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(IN);
+        close(OUT);
+}
+
+sub usb_classes {
+        my $class;
+        my $subclass;
+        my $protocol;
+
+        open(IN, "<", "usb.ids");
+        open(OUT, ">", "20-usb-classes.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported from: http://www.linux-usb.org/usb.ids\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+
+                $line =~ m/^C\ ([0-9a-f]{2})\s*(.+)$/;
+                if (defined $1) {
+                        $class = uc $1;
+                        if ($class =~ m/^00$/) {
+                                next;
+                        }
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "usb:v*p*d*dc" . $class . "*\n");
+                        print(OUT " ID_USB_CLASS_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                if (not defined $class) {
+                        next;
+                } elsif ($line =~ m/^$/) {
+                        last;
+                }
+
+                $line =~ m/^\t([0-9a-f]{2})\s*(.+)$/;
+                if (defined $1) {
+                        $subclass = uc $1;
+                        if ($subclass =~ m/^00$/) {
+                                next;
+                        }
+                        my $text = $2;
+                        if ($text =~ m/^(\?|None|Unused)$/) {
+                                next;
+                        }
+                        print(OUT "\n");
+                        print(OUT "usb:v*p*d*dc" . $class . "dsc" . $subclass . "*\n");
+                        print(OUT " ID_USB_SUBCLASS_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t\t([0-9a-f]{2})\s*(.+)$/;
+                if (defined $1) {
+                        $protocol = uc $1;
+                        my $text = $2;
+                        if ($text =~ m/^(\?|None|Unused)$/) {
+                                next;
+                        }
+                        print(OUT "\n");
+                        print(OUT "usb:v*p*d*dc" .  $class . "dsc" . $subclass . "dp" . $protocol . "*\n");
+                        print(OUT " ID_USB_PROTOCOL_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(IN);
+        close(OUT);
+}
+
+sub pci_vendor {
+        my $vendor;
+        my $device;
+
+        open(IN, "<", "pci.ids");
+        open(OUT, ">", "20-pci-vendor-product.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+                $line =~ m/^([0-9a-f]{4})\s*(.+)$/;
+
+                if (defined $1) {
+                        $vendor = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v0000" . $vendor . "*\n");
+                        print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t([0-9a-f]{4})\s*(.+)$/;
+                if (defined $1) {
+                        $device = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v0000" . $vendor . "d0000" . $device . "*\n");
+                        print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t\t([0-9a-f]{4})\s*([0-9a-f]{4})\s*(.*)$/;
+                if (defined $1) {
+                        my $sub_vendor = uc $1;
+                        my $sub_device = uc $2;
+                        my $text = $3;
+                        print(OUT "\n");
+                        print(OUT "pci:v0000" . $vendor . "d0000" . $device . "sv0000" . $sub_vendor . "sd0000" . $sub_device . "*\n");
+                        print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(IN);
+        close(OUT);
+}
+
+sub pci_classes {
+        my $class;
+        my $subclass;
+        my $interface;
+
+        open(IN, "<", "pci.ids");
+        open(OUT, ">", "20-pci-classes.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+
+                $line =~ m/^C\ ([0-9a-f]{2})\s*(.+)$/;
+                if (defined $1) {
+                        $class = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v*d*sv*sd*bc" . $class . "*\n");
+                        print(OUT " ID_PCI_CLASS_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                if (not defined $class) {
+                        next;
+                } elsif ($line =~ m/^$/) {
+                        last;
+                }
+
+                $line =~ m/^\t([0-9a-f]{2})\s*(.+)$/;
+                if (defined $1) {
+                        $subclass = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v*d*sv*sd*bc" . $class . "sc" . $subclass . "*\n");
+                        print(OUT " ID_PCI_SUBCLASS_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t\t([0-9a-f]{2})\s*(.+)$/;
+                if (defined $1) {
+                        $interface = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v*d*sv*sd*bc" .  $class . "sc" . $subclass . "i" . $interface . "*\n");
+                        print(OUT " ID_PCI_INTERFACE_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(IN);
+        close(OUT);
+}
+
+sub oui {
+        my $iab_prefix;
+        my %iab_prefixes = ();
+
+        open(OUT, ">", "20-OUI.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported from:\n" .
+                  "#   http://standards.ieee.org/develop/regauth/oui/oui.txt\n" .
+                  "#   http://standards.ieee.org/develop/regauth/iab/iab.txt\n");
+
+        open(IN, "<", "iab.txt");
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+                $line =~ m/^([0-9A-F]{2})-([0-9A-F]{2})-([0-9A-F]{2})\s*\(hex\)\s*.+$/;
+                if (defined $1) {
+                        $iab_prefix = $1 . $2 . $3;
+                        $iab_prefixes{ $iab_prefix } = 1;
+                        next;
+                }
+
+                $line =~ m/^([0-9A-F]{3})000-\g1FFF\s*\(base 16\)\s*(.+)$/;
+                if (defined $1) {
+                        my $vendor = uc $1;
+                        my $text = $2;
+
+                        print(OUT "\n");
+                        print(OUT "OUI:" . $iab_prefix . $vendor . "*\n");
+                        print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+        close(IN);
+
+        open(IN, "<", "oui.txt");
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+                $line =~ m/^([0-9A-F]{6})\s*\(base 16\)\s*(.+)$/;
+                if (defined $1) {
+                        my $vendor = uc $1;
+                        my $text = $2;
+
+                        # skip the IAB prefixes
+                        if (! exists $iab_prefixes{ $vendor }) {
+                                print(OUT "\n");
+                                print(OUT "OUI:" . $vendor . "*\n");
+                                print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n");
+                        }
+                }
+        }
+        close(IN);
+        close(OUT);
+}
+
+usb_vendor();
+usb_classes();
+
+pci_vendor();
+pci_classes();
+
+oui();
diff --git a/introspect.awk b/introspect.awk
new file mode 100644 (file)
index 0000000..5931913
--- /dev/null
@@ -0,0 +1,13 @@
+BEGIN {
+       print "<!DOCTYPE node PUBLIC DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER"
+       print "DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER>"
+       print "<node>"
+}
+
+// {
+       print
+}
+
+END {
+       print "</node>"
+}
diff --git a/keymaps-force-release/common-volume-keys b/keymaps-force-release/common-volume-keys
new file mode 100644 (file)
index 0000000..3a7654d
--- /dev/null
@@ -0,0 +1,3 @@
+0xa0 #mute
+0xae #volume down
+0xb0 #volume up
diff --git a/keymaps-force-release/dell-touchpad b/keymaps-force-release/dell-touchpad
new file mode 100644 (file)
index 0000000..18e9bde
--- /dev/null
@@ -0,0 +1 @@
+0x9E
diff --git a/keymaps-force-release/dell-xps b/keymaps-force-release/dell-xps
new file mode 100644 (file)
index 0000000..69f7899
--- /dev/null
@@ -0,0 +1 @@
+0x8C
diff --git a/keymaps-force-release/hp-other b/keymaps-force-release/hp-other
new file mode 100644 (file)
index 0000000..6621370
--- /dev/null
@@ -0,0 +1,3 @@
+# list of scancodes (hex or decimal), optional comment
+0xd8 # Touchpad off
+0xd9 # Touchpad on
diff --git a/keymaps-force-release/samsung-other b/keymaps-force-release/samsung-other
new file mode 100644 (file)
index 0000000..c51123a
--- /dev/null
@@ -0,0 +1,10 @@
+# list of scancodes (hex or decimal), optional comment
+0x82 # Fn+F4 CRT/LCD
+0x83 # Fn+F2 battery
+0x84 # Fn+F5 backlight on/off
+0x86 # Fn+F9 WLAN
+0x88 # Fn-Up brightness up
+0x89 # Fn-Down brightness down
+0xB3 # Fn+F8 switch power mode (battery/dynamic/performance)
+0xF7 # Fn+F10 Touchpad on
+0xF9 # Fn+F10 Touchpad off
diff --git a/keymaps-force-release/samsung-series-9 b/keymaps-force-release/samsung-series-9
new file mode 100644 (file)
index 0000000..65707ef
--- /dev/null
@@ -0,0 +1,6 @@
+# list of scancodes (hex or decimal), optional comment
+0xCE # Fn+F8 keyboard backlit up
+0x8D # Fn+F7 keyboard backlit down
+0x97 # Fn+F12 wifi on/off
+0x96 # Fn+F1 performance mode (?)
+0xD5 # Fn+F6 battery life extender
diff --git a/keymaps/acer b/keymaps/acer
new file mode 100644 (file)
index 0000000..4e7c297
--- /dev/null
@@ -0,0 +1,22 @@
+0xA5 help # Fn+F1
+0xA6 setup # Fn+F2 Acer eSettings
+0xA7 battery # Fn+F3 Power Management
+0xA9 switchvideomode # Fn+F5
+0xB3 euro
+0xB4 dollar
+0xCE brightnessup # Fn+Right
+0xD4 bluetooth # (toggle) off-to-on
+0xD5 wlan # (toggle) on-to-off
+0xD6 wlan # (toggle) off-to-on
+0xD7 bluetooth # (toggle) on-to-off
+0xD8 bluetooth # (toggle) off-to-on
+0xD9 brightnessup # Fn+Right
+0xEE brightnessup # Fn+Right
+0xEF brightnessdown # Fn+Left
+0xF1 f22 # Fn+F7 Touchpad toggle (off-to-on)
+0xF2 f23 # Fn+F7 Touchpad toggle (on-to-off)
+0xF3 prog2 # "P2" programmable button
+0xF4 prog1 # "P1" programmable button
+0xF5 presentation
+0xF8 fn
+0xF9 f23 # Launch NTI shadow
diff --git a/keymaps/acer-aspire_5720 b/keymaps/acer-aspire_5720
new file mode 100644 (file)
index 0000000..3ff9de3
--- /dev/null
@@ -0,0 +1,5 @@
+0x84 bluetooth  # sent when bluetooth module missing, and key pressed
+0x92 media      # acer arcade
+0xD4 bluetooth  # bluetooth on
+0xD9 bluetooth  # bluetooth off
+0xF4 prog3      # e-key
diff --git a/keymaps/acer-aspire_5920g b/keymaps/acer-aspire_5920g
new file mode 100644 (file)
index 0000000..633c4e8
--- /dev/null
@@ -0,0 +1,5 @@
+0x8A media
+0x92 media
+0xA6 setup
+0xB2 www
+0xD9 bluetooth # (toggle) on-to-off
diff --git a/keymaps/acer-aspire_6920 b/keymaps/acer-aspire_6920
new file mode 100644 (file)
index 0000000..699c954
--- /dev/null
@@ -0,0 +1,5 @@
+0xD9 bluetooth # (toggle) on-to-off
+0x92 media
+0x9E back
+0x83 rewind
+0x89 fastforward
diff --git a/keymaps/acer-aspire_8930 b/keymaps/acer-aspire_8930
new file mode 100644 (file)
index 0000000..fb27bfb
--- /dev/null
@@ -0,0 +1,5 @@
+0xCA prog3        # key 'HOLD' on cine dash media console
+0x83 rewind
+0x89 fastforward
+0x92 media        # key 'ARCADE' on cine dash media console
+0x9E back
diff --git a/keymaps/acer-travelmate_c300 b/keymaps/acer-travelmate_c300
new file mode 100644 (file)
index 0000000..bfef4cf
--- /dev/null
@@ -0,0 +1,5 @@
+0x67 f24 # FIXME: rotate screen
+0x68 up
+0x69 down
+0x6B fn
+0x6C screenlock # FIXME: lock tablet device/buttons
diff --git a/keymaps/asus b/keymaps/asus
new file mode 100644 (file)
index 0000000..2a5995f
--- /dev/null
@@ -0,0 +1,3 @@
+0xED volumeup
+0xEE volumedown
+0xEF mute
diff --git a/keymaps/compaq-e_evo b/keymaps/compaq-e_evo
new file mode 100644 (file)
index 0000000..5fbc573
--- /dev/null
@@ -0,0 +1,4 @@
+0xA3 www # I key
+0x9A search
+0x9E email
+0x9F homepage
diff --git a/keymaps/dell b/keymaps/dell
new file mode 100644 (file)
index 0000000..4f907b3
--- /dev/null
@@ -0,0 +1,29 @@
+0x81 playpause # Play/Pause
+0x82 stopcd # Stop
+0x83 previoussong # Previous song
+0x84 nextsong # Next song
+0x85 brightnessdown # Fn+Down arrow Brightness Down
+0x86 brightnessup # Fn+Up arrow Brightness Up
+0x87 battery # Fn+F3 battery icon
+0x88 unknown # Fn+F2 Turn On/Off Wireless - handled in hardware
+0x89 ejectclosecd # Fn+F10 Eject CD
+0x8A suspend # Fn+F1 hibernate
+0x8B switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle")
+0x8C f23 # Fn+Right arrow Auto Brightness
+0x8F switchvideomode # Fn+F7 aspect ratio
+0x90 previoussong # Front panel previous song
+0x91 prog1 # Wifi Catcher (DELL Specific)
+0x92 media # MediaDirect button (house icon)
+0x93 f23 # FIXME Fn+Left arrow Auto Brightness
+0x95 camera # Shutter button Takes a picture if optional camera available
+0x97 email # Tablet email button
+0x98 f21 # FIXME: Tablet screen rotatation
+0x99 nextsong # Front panel next song
+0x9A setup # Tablet tools button
+0x9B switchvideomode # Display Toggle button
+0x9E f21 #touchpad toggle
+0xA2 playpause # Front panel play/pause
+0xA4 stopcd # Front panel stop
+0xED media # MediaDirect button
+0xD8 screenlock # FIXME: Tablet lock button
+0xD9 f21 # touchpad toggle
diff --git a/keymaps/dell-latitude-xt2 b/keymaps/dell-latitude-xt2
new file mode 100644 (file)
index 0000000..39872f5
--- /dev/null
@@ -0,0 +1,4 @@
+0x9B up # tablet rocker up
+0x9E enter # tablet rocker press
+0x9F back # tablet back
+0xA3 down # tablet rocker down
diff --git a/keymaps/everex-xt5000 b/keymaps/everex-xt5000
new file mode 100644 (file)
index 0000000..4823a83
--- /dev/null
@@ -0,0 +1,7 @@
+0x5C media
+0x65 f21 # Fn+F5 Touchpad toggle
+0x67 prog3 # Fan Speed Control button
+0x6F brightnessup
+0x7F brightnessdown
+0xB2 www
+0xEC mail
diff --git a/keymaps/fujitsu-amilo_li_2732 b/keymaps/fujitsu-amilo_li_2732
new file mode 100644 (file)
index 0000000..9b8b36a
--- /dev/null
@@ -0,0 +1,3 @@
+0xD9 brightnessdown # Fn+F8 brightness down
+0xEF brightnessup # Fn+F9 brightness up
+0xA9 switchvideomode # Fn+F10 Cycle between available video outputs
diff --git a/keymaps/fujitsu-amilo_pa_2548 b/keymaps/fujitsu-amilo_pa_2548
new file mode 100644 (file)
index 0000000..f7b0c52
--- /dev/null
@@ -0,0 +1,3 @@
+0xE0 volumedown
+0xE1 volumeup
+0xE5 prog1
diff --git a/keymaps/fujitsu-amilo_pro_edition_v3505 b/keymaps/fujitsu-amilo_pro_edition_v3505
new file mode 100644 (file)
index 0000000..d2e38cb
--- /dev/null
@@ -0,0 +1,4 @@
+0xA5 help # Fn-F1
+0xA9 switchvideomode # Fn-F3
+0xD9 brightnessdown # Fn-F8
+0xE0 brightnessup # Fn-F9
diff --git a/keymaps/fujitsu-amilo_pro_v3205 b/keymaps/fujitsu-amilo_pro_v3205
new file mode 100644 (file)
index 0000000..43e3199
--- /dev/null
@@ -0,0 +1,2 @@
+0xF4 f21 # FIXME: silent-mode decrease CPU/GPU clock
+0xF7 switchvideomode # Fn+F3
diff --git a/keymaps/fujitsu-amilo_si_1520 b/keymaps/fujitsu-amilo_si_1520
new file mode 100644 (file)
index 0000000..1419bd9
--- /dev/null
@@ -0,0 +1,6 @@
+0xE1 wlan
+0xF3 wlan
+0xEE brightnessdown
+0xE0 brightnessup
+0xE2 bluetooth
+0xF7 video
diff --git a/keymaps/fujitsu-esprimo_mobile_v5 b/keymaps/fujitsu-esprimo_mobile_v5
new file mode 100644 (file)
index 0000000..d3d056b
--- /dev/null
@@ -0,0 +1,4 @@
+0xA9 switchvideomode
+0xD9 brightnessdown
+0xDF sleep
+0xEF brightnessup
diff --git a/keymaps/fujitsu-esprimo_mobile_v6 b/keymaps/fujitsu-esprimo_mobile_v6
new file mode 100644 (file)
index 0000000..52c70c5
--- /dev/null
@@ -0,0 +1,2 @@
+0xCE brightnessup
+0xEF brightnessdown
diff --git a/keymaps/genius-slimstar-320 b/keymaps/genius-slimstar-320
new file mode 100644 (file)
index 0000000..d0a3656
--- /dev/null
@@ -0,0 +1,35 @@
+# Genius SlimStar 320
+#
+# Only buttons which are not properly mapped yet are configured below
+
+# "Scroll wheel", a circular up/down/left/right button. Aimed for scolling,
+# but since there are no scrollleft/scrollright, let's map to back/forward.
+0x900f0 scrollup
+0x900f1 scrolldown
+0x900f3 back
+0x900f2 forward
+
+# Multimedia buttons, left side (from left to right)
+# [W]
+0x900f5 wordprocessor
+# [Ex]
+0x900f6 spreadsheet
+# [P]
+0x900f4 presentation
+# Other five (calculator, playpause, stop, mute and eject) are OK
+
+# Right side, from left to right
+# [e]
+0xc0223 www
+# "man"
+0x900f7 chat
+# "Y"
+0x900fb prog1
+# [X]
+0x900f8 close
+# "picture"
+0x900f9 graphicseditor
+# "two windows"
+0x900fd scale
+# "lock"
+0x900fc screenlock
diff --git a/keymaps/hewlett-packard b/keymaps/hewlett-packard
new file mode 100644 (file)
index 0000000..4461fa2
--- /dev/null
@@ -0,0 +1,12 @@
+0x81 fn_esc
+0x89 battery # FnF8
+0x8A screenlock # FnF6
+0x8B camera
+0x8C media # music
+0x8E dvd
+0xB1 help
+0xB3 f23 # FIXME: Auto brightness
+0xD7 wlan
+0x92 brightnessdown # FnF7 (FnF9 on 6730b)
+0x97 brightnessup # FnF8 (FnF10 on 6730b)
+0xEE switchvideomode # FnF4
diff --git a/keymaps/hewlett-packard-2510p_2530p b/keymaps/hewlett-packard-2510p_2530p
new file mode 100644 (file)
index 0000000..41ad2e9
--- /dev/null
@@ -0,0 +1,2 @@
+0xD8 f23 # touchpad off
+0xD9 f22 # touchpad on
diff --git a/keymaps/hewlett-packard-compaq_elitebook b/keymaps/hewlett-packard-compaq_elitebook
new file mode 100644 (file)
index 0000000..42007c5
--- /dev/null
@@ -0,0 +1,2 @@
+0x88 presentation
+0xD9 help # I key (high keycode: "info")
diff --git a/keymaps/hewlett-packard-pavilion b/keymaps/hewlett-packard-pavilion
new file mode 100644 (file)
index 0000000..3d3cefc
--- /dev/null
@@ -0,0 +1,3 @@
+0x88 media # FIXME: quick play
+0xD8 f23 # touchpad off
+0xD9 f22 # touchpad on
diff --git a/keymaps/hewlett-packard-presario-2100 b/keymaps/hewlett-packard-presario-2100
new file mode 100644 (file)
index 0000000..1df39dc
--- /dev/null
@@ -0,0 +1,3 @@
+0xF0 help
+0xF1 screenlock
+0xF3 search
diff --git a/keymaps/hewlett-packard-tablet b/keymaps/hewlett-packard-tablet
new file mode 100644 (file)
index 0000000..d19005a
--- /dev/null
@@ -0,0 +1,6 @@
+0x82 prog2 # Funny Key
+0x83 prog1 # Q
+0x84 tab
+0x85 esc
+0x86 pageup
+0x87 pagedown
diff --git a/keymaps/hewlett-packard-tx2 b/keymaps/hewlett-packard-tx2
new file mode 100644 (file)
index 0000000..36a690f
--- /dev/null
@@ -0,0 +1,3 @@
+0xC2 media
+0xD8 f23 # Toggle touchpad button on tx2 (OFF)
+0xD9 f22 # Toggle touchpad button on tx2 (ON)
diff --git a/keymaps/hewlett-packard_elitebook-8440p b/keymaps/hewlett-packard_elitebook-8440p
new file mode 100644 (file)
index 0000000..e0c2a1a
--- /dev/null
@@ -0,0 +1,5 @@
+0x88 www
+0xA0 mute
+0xAE volumedown
+0xB0 volumeup
+0xEC mail
diff --git a/keymaps/ibm-thinkpad-usb-keyboard-trackpoint b/keymaps/ibm-thinkpad-usb-keyboard-trackpoint
new file mode 100644 (file)
index 0000000..027e50b
--- /dev/null
@@ -0,0 +1,7 @@
+0x900f0 screenlock
+0x900f1 wlan
+0x900f2 switchvideomode
+0x900f3 suspend
+0x900f4 brightnessup
+0x900f5 brightnessdown
+0x900f8 zoom
diff --git a/keymaps/inventec-symphony_6.0_7.0 b/keymaps/inventec-symphony_6.0_7.0
new file mode 100644 (file)
index 0000000..4a8b4ba
--- /dev/null
@@ -0,0 +1,2 @@
+0xF3 prog2
+0xF4 prog1
diff --git a/keymaps/lenovo-3000 b/keymaps/lenovo-3000
new file mode 100644 (file)
index 0000000..5bd1656
--- /dev/null
@@ -0,0 +1,5 @@
+0x8B switchvideomode # Fn+F7 video
+0x96 wlan # Fn+F5 wireless
+0x97 sleep # Fn+F4 suspend
+0x98 suspend # Fn+F12 hibernate
+0xB4 prog1 # Lenovo Care
diff --git a/keymaps/lenovo-ideapad b/keymaps/lenovo-ideapad
new file mode 100644 (file)
index 0000000..fc33983
--- /dev/null
@@ -0,0 +1,8 @@
+# Key codes observed on S10-3, assumed valid on other IdeaPad models
+0x81 rfkill             # does nothing in BIOS
+0x83 display_off        # BIOS toggles screen state
+0xB9 brightnessup       # does nothing in BIOS
+0xBA brightnessdown     # does nothing in BIOS
+0xF1 camera             # BIOS toggles camera power
+0xf2 f21                # touchpad toggle (key alternately emits f2 and f3)
+0xf3 f21
diff --git a/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint
new file mode 100644 (file)
index 0000000..47e8846
--- /dev/null
@@ -0,0 +1,13 @@
+0x90012 screenlock # Fn+F2
+0x90013 battery # Fn+F3
+0x90014 wlan # Fn+F5
+0x90016 switchvideomode # Fn+F7
+0x90017 f21 # Fn+F8  touchpadtoggle
+0x90019 suspend # Fn+F12
+0x9001A brightnessup # Fn+Home
+0x9001B brightnessdown # Fn+End
+0x9001D zoom # Fn+Space
+0x90011 prog1 # Thinkvantage button
+
+0x90015 camera # Fn+F6 headset/camera VoIP key  ??
+0x90010 micmute # Microphone mute button
diff --git a/keymaps/lenovo-thinkpad_x200_tablet b/keymaps/lenovo-thinkpad_x200_tablet
new file mode 100644 (file)
index 0000000..31ea3b2
--- /dev/null
@@ -0,0 +1,6 @@
+0x5D menu
+0x63 fn
+0x66 screenlock
+0x67 cyclewindows # bezel circular arrow
+0x68 setup # bezel setup / menu
+0x6c direction # rotate screen
diff --git a/keymaps/lenovo-thinkpad_x6_tablet b/keymaps/lenovo-thinkpad_x6_tablet
new file mode 100644 (file)
index 0000000..6fd16b5
--- /dev/null
@@ -0,0 +1,8 @@
+0x6C f21 # rotate
+0x68 screenlock # screenlock
+0x6B esc # escape
+0x6D right # right on d-pad
+0x6E left # left on d-pad
+0x71 up # up on d-pad
+0x6F down # down on d-pad
+0x69 enter # enter on d-pad
diff --git a/keymaps/lg-x110 b/keymaps/lg-x110
new file mode 100644 (file)
index 0000000..ba08cba
--- /dev/null
@@ -0,0 +1,12 @@
+0xA0 mute # Fn-F9
+0xAE volumedown # Fn-Left
+0xAF search # Fn-F3
+0xB0 volumeup # Fn-Right
+0xB1 battery # Fn-F10 Info
+0xB3 suspend # Fn-F12
+0xDF sleep # Fn-F4
+# 0xE2 bluetooth # satellite dish2
+0xE4 f21 # Fn-F5   Touchpad disable
+0xF6 wlan # Fn-F6
+0xF7 reserved # brightnessdown # Fn-Down
+0xF8 reserved # brightnessup # Fn-Up
diff --git a/keymaps/logitech-wave b/keymaps/logitech-wave
new file mode 100644 (file)
index 0000000..caa5d5d
--- /dev/null
@@ -0,0 +1,16 @@
+0x9001C scale #expo
+0x9001F zoomout #zoom out
+0x90020 zoomin #zoom in
+0x9003D prog1 #gadget
+0x90005 camera #camera
+0x90018 media #media center
+0x90041 wordprocessor #fn+f1 (word)
+0x90042 spreadsheet #fn+f2 (excel)
+0x90043 calendar #fn+f3 (calendar)
+0x90044 prog2 #fn+f4 (program a)
+0x90045 prog3 #fn+f5 (program b)
+0x90046 prog4 #fn+f6 (program c)
+0x90048 messenger #fn+f8 (msn messenger)
+0x9002D find #fn+f10 (search www)
+0x9004B search #fn+f11 (search pc)
+0x9004C ejectclosecd #fn+f12 (eject)
diff --git a/keymaps/logitech-wave-cordless b/keymaps/logitech-wave-cordless
new file mode 100644 (file)
index 0000000..a10dad5
--- /dev/null
@@ -0,0 +1,15 @@
+0xD4 zoomin
+0xCC zoomout
+0xC0183 media
+0xC1005 camera
+0xC101F zoomout
+0xC1020 zoomin
+0xC1041 wordprocessor
+0xC1042 spreadsheet
+0xC1043 calendar
+0xC1044 prog2 #fn+f4 (program a)
+0xC1045 prog3 #fn+f5 (program b)
+0xC1046 prog4 #fn+f6 (program c)
+0xC1048 messenger
+0xC104A find #fn+f10 (search www)
+0xC104C ejectclosecd
diff --git a/keymaps/logitech-wave-pro-cordless b/keymaps/logitech-wave-pro-cordless
new file mode 100644 (file)
index 0000000..e7aa022
--- /dev/null
@@ -0,0 +1,12 @@
+0xC01B6 camera
+0xC0183 media
+0xC0184 wordprocessor
+0xC0186 spreadsheet
+0xC018E calendar
+0xC0223 homepage
+0xC01BC messenger
+0xC018A mail
+0xC0221 search
+0xC00B8 ejectcd
+0xC022D zoomin
+0xC022E zoomout
diff --git a/keymaps/maxdata-pro_7000 b/keymaps/maxdata-pro_7000
new file mode 100644 (file)
index 0000000..c0e4f77
--- /dev/null
@@ -0,0 +1,9 @@
+0x97 prog2
+0x9F prog1
+0xA0 mute # Fn-F5
+0x82 www
+0xEC email
+0xAE volumedown # Fn-Down
+0xB0 volumeup # Fn-Up
+0xDF suspend # Fn+F2
+0xF5 help
diff --git a/keymaps/medion-fid2060 b/keymaps/medion-fid2060
new file mode 100644 (file)
index 0000000..5a76c76
--- /dev/null
@@ -0,0 +1,2 @@
+0x6B channeldown # Thottle Down
+0x6D channelup # Thottle Up
diff --git a/keymaps/medionnb-a555 b/keymaps/medionnb-a555
new file mode 100644 (file)
index 0000000..c3b5dfa
--- /dev/null
@@ -0,0 +1,4 @@
+0x63 www # N button
+0x66 prog1 # link 1 button
+0x67 email # envelope button
+0x69 prog2 # link 2 button
diff --git a/keymaps/micro-star b/keymaps/micro-star
new file mode 100644 (file)
index 0000000..4a43869
--- /dev/null
@@ -0,0 +1,13 @@
+0xA0 mute # Fn-F9
+0xAE volumedown # Fn-F7
+0xB0 volumeup # Fn-F8
+0xB2 www # e button
+0xDF sleep # Fn-F12
+0xE2 bluetooth # satellite dish2
+0xE4 f21 # Fn-F3   Touchpad disable
+0xEC email # envelope button
+0xEE camera # Fn-F6 camera disable
+0xF6 wlan # satellite dish1
+0xF7 brightnessdown # Fn-F4
+0xF8 brightnessup # Fn-F5
+0xF9 search
diff --git a/keymaps/module-asus-w3j b/keymaps/module-asus-w3j
new file mode 100644 (file)
index 0000000..773e0b3
--- /dev/null
@@ -0,0 +1,11 @@
+0x41 nextsong
+0x45 playpause
+0x43 stopcd
+0x40 previoussong
+0x4C ejectclosecd
+0x32 mute
+0x31 volumedown
+0x30 volumeup
+0x5D wlan
+0x7E bluetooth
+0x8A media # high keycode: "tv"
diff --git a/keymaps/module-ibm b/keymaps/module-ibm
new file mode 100644 (file)
index 0000000..a92dfa2
--- /dev/null
@@ -0,0 +1,16 @@
+0x01 battery # Fn+F2
+0x02 screenlock # Fn+F3
+0x03 sleep # Fn+F4
+0x04 wlan # Fn+F5
+0x06 switchvideomode # Fn+F7
+0x07 zoom # Fn+F8 screen expand
+0x08 f24 # Fn+F9 undock
+0x0B suspend # Fn+F12
+0x0F brightnessup # Fn+Home
+0x10 brightnessdown # Fn+End
+0x11 kbdillumtoggle # Fn+PgUp - ThinkLight
+0x13 zoom # Fn+Space
+0x14 volumeup
+0x15 volumedown
+0x16 mute
+0x17 prog1 # ThinkPad/ThinkVantage button  (high keycode: "vendor")
diff --git a/keymaps/module-lenovo b/keymaps/module-lenovo
new file mode 100644 (file)
index 0000000..8e38883
--- /dev/null
@@ -0,0 +1,17 @@
+0x1 screenlock # Fn+F2
+0x2 battery # Fn+F3
+0x3 sleep # Fn+F4
+0x4 wlan # Fn+F5
+0x6 switchvideomode # Fn+F7
+0x7 f21 # Fn+F8 touchpadtoggle
+0x8 f24 # Fn+F9 undock
+0xB suspend # Fn+F12
+0xF brightnessup # Fn+Home
+0x10 brightnessdown # Fn+End
+0x11 kbdillumtoggle # Fn+PgUp - ThinkLight
+0x13 zoom # Fn+Space
+0x14 volumeup
+0x15 volumedown
+0x16 mute
+0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor")
+0x1A micmute # Microphone mute
diff --git a/keymaps/module-sony b/keymaps/module-sony
new file mode 100644 (file)
index 0000000..7c00013
--- /dev/null
@@ -0,0 +1,8 @@
+0x06 mute # Fn+F2
+0x07 volumedown # Fn+F3
+0x08 volumeup # Fn+F4
+0x09 brightnessdown # Fn+F5
+0x0A brightnessup # Fn+F6
+0x0B switchvideomode # Fn+F7
+0x0E zoom # Fn+F10
+0x10 suspend # Fn+F12
diff --git a/keymaps/module-sony-old b/keymaps/module-sony-old
new file mode 100644 (file)
index 0000000..596a342
--- /dev/null
@@ -0,0 +1,2 @@
+0x06 battery
+0x07 mute
diff --git a/keymaps/module-sony-vgn b/keymaps/module-sony-vgn
new file mode 100644 (file)
index 0000000..c8ba001
--- /dev/null
@@ -0,0 +1,8 @@
+0x00 brightnessdown # Fn+F5
+0x10 brightnessup # Fn+F6
+0x11 switchvideomode # Fn+F7
+0x12 zoomout
+0x14 zoomin
+0x15 suspend # Fn+F12
+0x17 prog1
+0x20 media
diff --git a/keymaps/module-sony-vpc b/keymaps/module-sony-vpc
new file mode 100644 (file)
index 0000000..681082c
--- /dev/null
@@ -0,0 +1,4 @@
+# 0x05 touchpad_toggle # fn_f1 -> KEY_TOUCHPAD_TOGGLE
+0x05 f21 # fn_f1 -> KEY_F21 (The actual touchpad toggle)
+0x0d zoomout # fn_f9
+0x0e zoomin # fn_f10
diff --git a/keymaps/olpc-xo b/keymaps/olpc-xo
new file mode 100644 (file)
index 0000000..34434a1
--- /dev/null
@@ -0,0 +1,74 @@
+0x59 fn
+0x81 fn_esc
+0xF9 camera
+0xF8 sound # Fn-CAMERA = Mic
+
+
+# Function key mappings, as per
+#    http://dev.laptop.org/ticket/10213#comment:20
+#
+# Unmodified F1-F8 produce F1-F8, so no remap necessary.
+# Unmodified F9-F12 control brightness and volume.
+0x43 brightnessdown
+0x44 brightnessup
+0x57 volumedown
+0x58 volumeup
+
+# fn-modified fkeys all produce the unmodified version of the key.
+0xBB f1
+0xBC f2
+0xBD f3
+0xBE f4
+0xBF f5
+0xC0 f6
+0xC1 f7
+0xC2 f8
+0xC3 f9
+0xC4 f10
+0xD7 f11
+0xD8 f12
+
+
+# Using F13-F21 for the .5 F keys right now.
+0xF7 f13
+0xF6 f14
+0xF5 f15
+0xF4 f16
+0xF3 f17
+0xF2 f18
+0xF1 f19
+0xF0 f20
+0xEF f21
+
+0xEE chat
+0xE4 chat # Just mapping Fn-Chat to Chat for now
+0xDD menu # Frame
+0xDA prog1 # Fn-Frame
+
+# The FN of some keys is other keys
+0xD3 delete
+0xD2 insert
+0xC9 pageup
+0xD1 pagedown
+0xC7 home
+0xCF end
+
+# Language key - don't ask what they are doing as KEY_HP
+0x73 hp
+0x7E hp
+
+0xDB leftmeta # left grab
+0xDC rightmeta # right grab
+0x85 rightmeta # Right grab releases on a different scancode
+0xD6 kbdillumtoggle # Fn-space
+0x69 switchvideomode # Brightness key
+
+# Game keys
+0x65 kp8 # up
+0x66 kp2 # down
+0x67 kp4 # left
+0x68 kp6 # right
+0xE5 kp9 # pgup
+0xE6 kp3 # pgdn
+0xE7 kp7 # home
+0xE8 kp1 # end
diff --git a/keymaps/onkyo b/keymaps/onkyo
new file mode 100644 (file)
index 0000000..ee864ad
--- /dev/null
@@ -0,0 +1,14 @@
+0xA0 mute # Fn+D
+0xAE volumedown # Fn+F
+0xB0 volumeup # Fn+G
+0xDF sleep # Fn+W
+0xE0 bluetooth # Fn+H
+0xE2 cyclewindows # Fn+Esc
+0xEE battery # Fn+Q
+0xF0 media # Fn+R
+0xF5 switchvideomode # Fn+E
+0xF6 camera # Fn+T
+0xF7 f21 # Fn+Y (touchpad toggle)
+0xF8 brightnessup # Fn+S
+0xF9 brightnessdown # Fn+A
+0xFB wlan # Fn+J
diff --git a/keymaps/oqo-model2 b/keymaps/oqo-model2
new file mode 100644 (file)
index 0000000..b7f4851
--- /dev/null
@@ -0,0 +1,5 @@
+0x8E wlan
+0xF0 switchvideomode
+0xF1 mute
+0xF2 volumedown
+0xF3 volumeup
diff --git a/keymaps/samsung-other b/keymaps/samsung-other
new file mode 100644 (file)
index 0000000..3ac0c2f
--- /dev/null
@@ -0,0 +1,14 @@
+0x74 prog1 # User key
+0x75 www
+0x78 mail
+0x82 switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle")
+0x83 battery # Fn+F2
+0x84 prog1 # Fn+F5 backlight on/off
+0x86 wlan # Fn+F9
+0x88 brightnessup # Fn-Up
+0x89 brightnessdown # Fn-Down
+0xB1 prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice)
+0xB3 prog3 # Fn+F8 switch power mode (battery/dynamic/performance)
+0xB4 wlan # Fn+F9 (X60P)
+0xF7 f22 # Fn+F10 Touchpad on
+0xF9 f23 # Fn+F10 Touchpad off
diff --git a/keymaps/samsung-series-9 b/keymaps/samsung-series-9
new file mode 100644 (file)
index 0000000..3b65735
--- /dev/null
@@ -0,0 +1,5 @@
+0x96 kbdillumup         # Fn+F8 keyboard backlit up
+0x97 kbdillumdown       # Fn+F7 keyboard backlit down
+0xD5 wlan               # Fn+F12 wifi on/off
+0xCE prog1              # Fn+F1 performance mode
+0x8D prog2              # Fn+F6 battery life extender
diff --git a/keymaps/samsung-sq1us b/keymaps/samsung-sq1us
new file mode 100644 (file)
index 0000000..ea2141e
--- /dev/null
@@ -0,0 +1,7 @@
+0xD4 menu
+0xD8 f1
+0xD9 f10
+0xD6 f3
+0xD7 f9
+0xE4 f5
+0xEE f11
diff --git a/keymaps/samsung-sx20s b/keymaps/samsung-sx20s
new file mode 100644 (file)
index 0000000..9d954ee
--- /dev/null
@@ -0,0 +1,4 @@
+0x74 mute
+0x75 mute
+0x77 f22 # Touchpad on
+0x79 f23 # Touchpad off
diff --git a/keymaps/toshiba-satellite_a100 b/keymaps/toshiba-satellite_a100
new file mode 100644 (file)
index 0000000..22007be
--- /dev/null
@@ -0,0 +1,2 @@
+0xA4 stopcd
+0xB2 www
diff --git a/keymaps/toshiba-satellite_a110 b/keymaps/toshiba-satellite_a110
new file mode 100644 (file)
index 0000000..1429409
--- /dev/null
@@ -0,0 +1,10 @@
+0x92 stop
+0x93 www
+0x94 media
+0x9E f22 # Touchpad on
+0x9F f23 # Touchpad off
+0xB9 nextsong
+0xD9 brightnessup
+0xEE screenlock
+0xF4 previoussong
+0xF7 playpause
diff --git a/keymaps/toshiba-satellite_m30x b/keymaps/toshiba-satellite_m30x
new file mode 100644 (file)
index 0000000..ae8e349
--- /dev/null
@@ -0,0 +1,6 @@
+0xef brightnessdown
+0xd9 brightnessup
+0xee screenlock
+0x93 media
+0x9e f22 #touchpad_enable
+0x9f f23 #touchpad_disable
diff --git a/keymaps/zepto-znote b/keymaps/zepto-znote
new file mode 100644 (file)
index 0000000..cf72fda
--- /dev/null
@@ -0,0 +1,11 @@
+0x93 switchvideomode    # Fn+F3 Toggle Video Output
+0x95 brightnessdown     # Fn+F4 Brightness Down
+0x91 brightnessup       # Fn+F5 Brightness Up
+0xA5 f23                # Fn+F6 Disable Touchpad
+0xA6 f22                # Fn+F6 Enable Touchpad
+0xA7 bluetooth          # Fn+F10 Enable Bluetooth
+0XA9 bluetooth          # Fn+F10 Disable Bluetooth
+0xF1 wlan               # RF Switch Off
+0xF2 wlan               # RF Switch On
+0xF4 prog1              # P1 Button
+0xF3 prog2              # P2 Button
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644 (file)
index 0000000..cf35a86
--- /dev/null
@@ -0,0 +1,7 @@
+intltool.m4
+libtool.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+lt~obsolete.m4
+gtk-doc.m4
diff --git a/m4/acx_libwrap.m4 b/m4/acx_libwrap.m4
new file mode 100644 (file)
index 0000000..ccf8afc
--- /dev/null
@@ -0,0 +1,19 @@
+AC_DEFUN([ACX_LIBWRAP], [
+LIBWRAP_LIBS=
+saved_LIBS="$LIBS"
+LIBS="$LIBS -lwrap"
+AC_MSG_CHECKING([for tcpwrap library and headers])
+AC_LINK_IFELSE(
+[AC_LANG_PROGRAM(
+[#include <tcpd.h>
+#include <syslog.h>
+int allow_severity = LOG_INFO;
+int deny_severity = LOG_WARNING;],
+[struct request_info *req;
+return hosts_access (req);])],
+[AC_DEFINE(HAVE_LIBWRAP, [], [Have tcpwrap?])
+LIBWRAP_LIBS="-lwrap"
+AC_MSG_RESULT(yes)],
+[AC_MSG_RESULT(no)])
+LIBS="$saved_LIBS"
+])
diff --git a/m4/attributes.m4 b/m4/attributes.m4
new file mode 100644 (file)
index 0000000..f0bcf24
--- /dev/null
@@ -0,0 +1,288 @@
+dnl Macros to check the presence of generic (non-typed) symbols.
+dnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes@gmail.com>
+dnl Copyright (c) 2006-2008 xine project
+dnl Copyright (c) 2012 Lucas De Marchi <lucas.de.marchi@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2, or (at your option)
+dnl any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+dnl 02110-1301, USA.
+dnl
+dnl As a special exception, the copyright owners of the
+dnl macro gives unlimited permission to copy, distribute and modify the
+dnl configure scripts that are the output of Autoconf when processing the
+dnl Macro. You need not follow the terms of the GNU General Public
+dnl License when using or distributing such scripts, even though portions
+dnl of the text of the Macro appear in them. The GNU General Public
+dnl License (GPL) does govern all other use of the material that
+dnl constitutes the Autoconf Macro.
+dnl
+dnl This special exception to the GPL applies to versions of the
+dnl Autoconf Macro released by this project. When you make and
+dnl distribute a modified version of the Autoconf Macro, you may extend
+dnl this special exception to the GPL to apply to your modified version as
+dnl well.
+
+dnl Check if FLAG in ENV-VAR is supported by compiler and append it
+dnl to WHERE-TO-APPEND variable
+dnl CC_CHECK_FLAG_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG])
+
+AC_DEFUN([CC_CHECK_FLAG_APPEND], [
+  AC_CACHE_CHECK([if $CC supports flag $3 in envvar $2],
+                 AS_TR_SH([cc_cv_$2_$3]),
+                [eval "AS_TR_SH([cc_save_$2])='${$2}'"
+                 eval "AS_TR_SH([$2])='-Werror $3'"
+                 AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])],
+                                    [eval "AS_TR_SH([cc_cv_$2_$3])='yes'"],
+                                    [eval "AS_TR_SH([cc_cv_$2_$3])='no'"])
+                 eval "AS_TR_SH([$2])='$cc_save_$2'"])
+
+  AS_IF([eval test x$]AS_TR_SH([cc_cv_$2_$3])[ = xyes],
+        [eval "$1='${$1} $3'"])
+])
+
+dnl CC_CHECK_FLAGS_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG1 FLAG2])
+AC_DEFUN([CC_CHECK_FLAGS_APPEND], [
+  for flag in $3; do
+    CC_CHECK_FLAG_APPEND($1, $2, $flag)
+  done
+])
+
+dnl Check if the flag is supported by linker (cacheable)
+dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+
+AC_DEFUN([CC_CHECK_LDFLAGS], [
+  AC_CACHE_CHECK([if $CC supports $1 flag],
+    AS_TR_SH([cc_cv_ldflags_$1]),
+    [ac_save_LDFLAGS="$LDFLAGS"
+     LDFLAGS="$LDFLAGS $1"
+     AC_LINK_IFELSE([int main() { return 1; }],
+       [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
+       [eval "AS_TR_SH([cc_cv_ldflags_$1])="])
+     LDFLAGS="$ac_save_LDFLAGS"
+    ])
+
+  AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
+    [$2], [$3])
+])
+
+dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
+dnl the current linker to avoid undefined references in a shared object.
+AC_DEFUN([CC_NOUNDEFINED], [
+  dnl We check $host for which systems to enable this for.
+  AC_REQUIRE([AC_CANONICAL_HOST])
+
+  case $host in
+     dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads
+     dnl are requested, as different implementations are present; to avoid problems
+     dnl use -Wl,-z,defs only for those platform not behaving this way.
+     *-freebsd* | *-openbsd*) ;;
+     *)
+        dnl First of all check for the --no-undefined variant of GNU ld. This allows
+        dnl for a much more readable commandline, so that people can understand what
+        dnl it does without going to look for what the heck -z defs does.
+        for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do
+          CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"])
+         break
+        done
+       ;;
+  esac
+
+  AC_SUBST([LDFLAGS_NOUNDEFINED])
+])
+
+dnl Check for a -Werror flag or equivalent. -Werror is the GCC
+dnl and ICC flag that tells the compiler to treat all the warnings
+dnl as fatal. We usually need this option to make sure that some
+dnl constructs (like attributes) are not simply ignored.
+dnl
+dnl Other compilers don't support -Werror per se, but they support
+dnl an equivalent flag:
+dnl  - Sun Studio compiler supports -errwarn=%all
+AC_DEFUN([CC_CHECK_WERROR], [
+  AC_CACHE_CHECK(
+    [for $CC way to treat warnings as errors],
+    [cc_cv_werror],
+    [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
+      [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
+    ])
+])
+
+AC_DEFUN([CC_CHECK_ATTRIBUTE], [
+  AC_REQUIRE([CC_CHECK_WERROR])
+  AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],
+    AS_TR_SH([cc_cv_attribute_$1]),
+    [ac_save_CFLAGS="$CFLAGS"
+     CFLAGS="$CFLAGS $cc_cv_werror"
+     AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])],
+       [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"],
+       [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"])
+     CFLAGS="$ac_save_CFLAGS"
+    ])
+
+  AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],
+    [AC_DEFINE(
+       AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,
+         [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]
+         )
+     $4],
+    [$5])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
+  CC_CHECK_ATTRIBUTE(
+    [constructor],,
+    [void __attribute__((constructor)) ctor() { int a; }],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
+  CC_CHECK_ATTRIBUTE(
+    [format], [format(printf, n, n)],
+    [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [
+  CC_CHECK_ATTRIBUTE(
+    [format_arg], [format_arg(printf)],
+    [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
+  CC_CHECK_ATTRIBUTE(
+    [visibility_$1], [visibility("$1")],
+    [void __attribute__((visibility("$1"))) $1_function() { }],
+    [$2], [$3])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
+  CC_CHECK_ATTRIBUTE(
+    [nonnull], [nonnull()],
+    [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
+  CC_CHECK_ATTRIBUTE(
+    [unused], ,
+    [void some_function(void *foo, __attribute__((unused)) void *bar);],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [
+  CC_CHECK_ATTRIBUTE(
+    [sentinel], ,
+    [void some_function(void *foo, ...) __attribute__((sentinel));],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [
+  CC_CHECK_ATTRIBUTE(
+    [deprecated], ,
+    [void some_function(void *foo, ...) __attribute__((deprecated));],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_ALIAS], [
+  CC_CHECK_ATTRIBUTE(
+    [alias], [weak, alias],
+    [void other_function(void *foo) { }
+     void some_function(void *foo) __attribute__((weak, alias("other_function")));],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_MALLOC], [
+  CC_CHECK_ATTRIBUTE(
+    [malloc], ,
+    [void * __attribute__((malloc)) my_alloc(int n);],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_PACKED], [
+  CC_CHECK_ATTRIBUTE(
+    [packed], ,
+    [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_CONST], [
+  CC_CHECK_ATTRIBUTE(
+    [const], ,
+    [int __attribute__((const)) twopow(int n) { return 1 << n; } ],
+    [$1], [$2])
+])
+
+AC_DEFUN([CC_FLAG_VISIBILITY], [
+  AC_REQUIRE([CC_CHECK_WERROR])
+  AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
+    [cc_cv_flag_visibility],
+    [cc_flag_visibility_save_CFLAGS="$CFLAGS"
+     CFLAGS="$CFLAGS $cc_cv_werror"
+     CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
+       cc_cv_flag_visibility='yes',
+       cc_cv_flag_visibility='no')
+     CFLAGS="$cc_flag_visibility_save_CFLAGS"])
+
+  AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
+    [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
+       [Define this if the compiler supports the -fvisibility flag])
+     $1],
+    [$2])
+])
+
+AC_DEFUN([CC_FUNC_EXPECT], [
+  AC_REQUIRE([CC_CHECK_WERROR])
+  AC_CACHE_CHECK([if compiler has __builtin_expect function],
+    [cc_cv_func_expect],
+    [ac_save_CFLAGS="$CFLAGS"
+     CFLAGS="$CFLAGS $cc_cv_werror"
+     AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+       [int some_function() {
+        int a = 3;
+        return (int)__builtin_expect(a, 3);
+       }])],
+       [cc_cv_func_expect=yes],
+       [cc_cv_func_expect=no])
+     CFLAGS="$ac_save_CFLAGS"
+    ])
+
+  AS_IF([test "x$cc_cv_func_expect" = "xyes"],
+    [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,
+     [Define this if the compiler supports __builtin_expect() function])
+     $1],
+    [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
+  AC_REQUIRE([CC_CHECK_WERROR])
+  AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],
+    [cc_cv_attribute_aligned],
+    [ac_save_CFLAGS="$CFLAGS"
+     CFLAGS="$CFLAGS $cc_cv_werror"
+     for cc_attribute_align_try in 64 32 16 8 4 2; do
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+          int main() {
+            static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;
+            return c;
+          }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])
+     done
+     CFLAGS="$ac_save_CFLAGS"
+  ])
+
+  if test "x$cc_cv_attribute_aligned" != "x"; then
+     AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
+       [Define the highest alignment supported])
+  fi
+])
diff --git a/make-directive-index.py b/make-directive-index.py
new file mode 100755 (executable)
index 0000000..eaf7019
--- /dev/null
@@ -0,0 +1,149 @@
+#  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+#
+#  This file is part of systemd.
+#
+#  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import collections
+import xml.etree.ElementTree as tree
+
+TEMPLATE = '''\
+<refentry id="systemd.directives">
+
+        <refentryinfo>
+                <title>systemd.directives</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Zbigniew</firstname>
+                                <surname>Jędrzejewski-Szmek</surname>
+                                <email>zbyszek@in.waw.pl</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.directives</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.directives</refname>
+                <refpurpose>Index of configuration directives</refpurpose>
+        </refnamediv>
+
+        <refsect1>
+                <title>Unit directives</title>
+
+                <para>Directives for configuring units, used in unit
+                files.</para>
+
+                <variablelist id='unit-directives' />
+        </refsect1>
+
+        <refsect1>
+                <title>System manager directives</title>
+
+                <para>Directives for configuring the behaviour of the
+                systemd process.</para>
+
+                <variablelist id='systemd-directives' />
+        </refsect1>
+
+        <refsect1>
+                <title>UDEV directives</title>
+
+                <para>Directives for configuring systemd units through the
+                udev database.</para>
+
+                <variablelist id='udev-directives' />
+        </refsect1>
+
+        <refsect1>
+                <title>Journal directives</title>
+
+                <para>Directives for configuring the behaviour of the
+                journald process.</para>
+
+                <variablelist id='journal-directives' />
+        </refsect1>
+</refentry>
+'''
+
+def _extract_directives(directive_groups, page):
+    t = tree.parse(page)
+    section = t.find('./refmeta/manvolnum').text
+    pagename = t.find('./refmeta/refentrytitle').text
+    for variablelist in t.iterfind('.//variablelist'):
+        klass = variablelist.attrib.get('class') or 'unit-directives'
+        stor = directive_groups[klass]
+        for varname in variablelist.iterfind('./varlistentry/term/varname'):
+            text = ''.join(varname.text.partition('=')[:2])
+            stor[text].append((pagename, section))
+
+def _make_section(refentry, name, directives):
+    varlist = refentry.find(".//*[@id='{}']".format(name))
+    for varname, manpages in sorted(directives.items()):
+        entry = tree.SubElement(varlist, 'varlistentry')
+        a = tree.SubElement(tree.SubElement(entry, 'term'), 'varname')
+        a.text = varname
+        para = tree.SubElement(tree.SubElement(entry, 'listitem'), 'para')
+
+        b = None
+        for manpage, manvolume in sorted(manpages):
+                if b is not None:
+                        b.tail = ', '
+                b = tree.SubElement(para, 'citerefentry')
+                c = tree.SubElement(b, 'refentrytitle')
+                c.text = manpage
+                d = tree.SubElement(b, 'manvolnum')
+                d.text = manvolume
+        entry.tail = '\n\n'
+
+def _make_page(directive_groups):
+    """Create an XML tree from directive_groups.
+
+    directive_groups = {
+       'class': {'variable': [('manpage', 'manvolume'), ...],
+                 'variable2': ...},
+       ...
+    }
+    """
+    refentry = tree.fromstring(TEMPLATE)
+
+    for name, directives in directive_groups.items():
+            _make_section(refentry, name, directives)
+
+    return refentry
+
+def make_page(xml_files):
+    "Extract directives from xml_files and return XML index tree."
+    directive_groups = {name:collections.defaultdict(list)
+                        for name in ['unit-directives',
+                                     'udev-directives',
+                                     'systemd-directives',
+                                     'journal-directives',
+                                     ]}
+    for page in xml_files:
+        _extract_directives(directive_groups, page)
+
+    return _make_page(directive_groups)
+
+if __name__ == '__main__':
+    tree.dump(make_page(sys.argv[1:]))
diff --git a/make-man-index.py b/make-man-index.py
new file mode 100755 (executable)
index 0000000..b40c963
--- /dev/null
@@ -0,0 +1,95 @@
+#  -*- Mode: python; indent-tabs-mode: nil -*- */
+#
+#  This file is part of systemd.
+#
+#  Copyright 2012 Lennart Poettering
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+from xml.etree.ElementTree import parse, Element, SubElement, tostring
+from sys import argv, stdout
+
+index = {}
+
+def prettify(elem, indent = 0):
+        s = "\n" + indent * "  "
+        if len(elem):
+                if not elem.text or not elem.text.strip():
+                        elem.text = s + "  "
+                for e in elem:
+                        prettify(e, indent + 1)
+                        if not e.tail or not e.tail.strip():
+                                e.tail = s + "  "
+                if not e.tail or not e.tail.strip():
+                        e.tail = s
+        else:
+                if indent and (not elem.tail or not elem.tail.strip()):
+                        elem.tail = s
+
+for p in argv[1:]:
+        t = parse(p)
+        section = t.find('./refmeta/manvolnum').text
+        purpose = ' '.join(t.find('./refnamediv/refpurpose').text.split())
+        for f in t.findall('./refnamediv/refname'):
+                index[f.text] = (p, section, purpose)
+
+html = Element('html')
+
+head = SubElement(html, 'head')
+title = SubElement(head, 'title')
+title.text = 'Manual Page Index'
+
+body = SubElement(html, 'body')
+h1 = SubElement(body, 'h1')
+h1.text = 'Manual Page Index'
+
+letter = None
+for n in sorted(index.keys(), key = str.lower):
+        path, section, purpose = index[n]
+
+        if path.endswith('.xml'):
+                path = path[:-4] + ".html"
+
+        c = path.rfind('/')
+        if c >= 0:
+                path = path[c+1:]
+
+        if letter is None or n[0].upper() != letter:
+                letter = n[0].upper()
+
+                h2 = SubElement(body, 'h2')
+                h2.text = letter
+
+                ul = SubElement(body, 'ul')
+                ul.set('style', 'list-style-type:none')
+
+        li = SubElement(ul, 'li')
+
+        a = SubElement(li, 'a')
+        a.set('href', path)
+        a.text = n + '(' + section + ')'
+        a.tail = ' -- '
+
+        i = SubElement(li, 'i')
+        i.text = purpose
+
+hr = SubElement(body, 'hr')
+
+p = SubElement(body, 'p')
+p.text = "This index contains %s entries, referring to %i individual manual pages." % (len(index), len(argv)-1)
+
+if hasattr(stdout, "buffer"):
+       stdout = stdout.buffer
+prettify(html)
+stdout.write(tostring(html))
diff --git a/man/.gitignore b/man/.gitignore
new file mode 100644 (file)
index 0000000..e97cda7
--- /dev/null
@@ -0,0 +1,2 @@
+/systemd.directives.xml
+/*.[13578]
diff --git a/man/Makefile b/man/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml
new file mode 100644 (file)
index 0000000..07ae0ac
--- /dev/null
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="binfmt.d">
+
+        <refentryinfo>
+                <title>binfmt.d</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>binfmt.d</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>binfmt.d</refname>
+                <refpurpose>Configure additional binary formats for
+                executables at boot</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/binfmt.d/*.conf</filename></para>
+                <para><filename>/run/binfmt.d/*.conf</filename></para>
+                <para><filename>/usr/lib/binfmt.d/*.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>At boot,
+                <citerefentry><refentrytitle>systemd-binfmt.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                reads configuration files from the above directories
+                to register in the kernel additional binary
+                formats for executables.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Configuration Format</title>
+
+                <para>Each file contains a list of binfmt_misc kernel
+                binary format rules. Consult <ulink
+                url="http://www.kernel.org/doc/Documentation/binfmt_misc.txt">binfmt_misc.txt</ulink>
+                for more information on registration of additional
+                binary formats and how to write rules.</para>
+
+                <para>Empty lines and lines beginning with ; and # are
+                ignored. Note that this means you may not use ; and #
+                as delimiter in binary format rules.</para>
+
+                <para>Each configuration file shall be named in the
+                style of <filename>&lt;program&gt;.conf</filename>.
+                Files in <filename>/etc/</filename> override files
+                with the same name in <filename>/usr/lib/</filename>
+                and <filename>/run/</filename>. Files in
+                <filename>/run/</filename> override files with the
+                same name in <filename>/usr/lib/</filename>. Packages
+                should install their configuration files in
+                <filename>/usr/lib/</filename>, files in
+                <filename>/etc/</filename> are reserved for the local
+                administrator, who may use this logic to override the
+                configuration files installed from vendor
+                packages. All files are sorted by their filename in
+                alphabetical order, regardless in which of the
+                directories they reside, to guarantee that a specific
+                configuration file takes precedence over another file
+                with an alphabetically later name.</para>
+
+                <para>If the administrator wants to disable a
+                configuration file supplied by the vendor the
+                recommended way is to place a symlink to
+                <filename>/dev/null</filename> in
+                <filename>/etc/binfmt.d/</filename> bearing the
+                same file name.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+                <example>
+                        <title>/etc/binfmt.d/wine.conf example:</title>
+
+                        <programlisting># Start WINE on Windows executables
+:DOSWin:M::MZ::/usr/bin/wine:</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-binfmt.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wine</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/bootup.xml b/man/bootup.xml
new file mode 100644 (file)
index 0000000..4cc4baf
--- /dev/null
@@ -0,0 +1,226 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="bootup">
+
+        <refentryinfo>
+                <title>bootup</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>bootup</refentrytitle>
+                <manvolnum>7</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>bootup</refname>
+                <refpurpose>System bootup process</refpurpose>
+        </refnamediv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A number of different components are involved in the
+                system boot. Immediately after power-up, the system
+                BIOS will do minimal hardware initialization, and hand
+                control over to a boot loader stored on a persistent
+                storage device. This boot loader will then invoke an
+                OS kernel from disk (or the network). In the Linux
+                case this kernel now (optionally) extracts and
+                executes an initial RAM disk image (initrd) such as
+                <citerefentry><refentrytitle>dracut</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                which looks for the root file system. After the root
+                file system is found and mounted the initrd hands over
+                control to the system manager (such as
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>)
+                stored on the OS image which is then responsible for
+                probing all remaining hardware, mounting all necessary
+                file systems and spawning all configured
+                services.</para>
+
+                <para>On shutdown the system manager stops all
+                services, unmounts all file systems (detaching the
+                storage technologies backing them), and then
+                (optionally) jumps back into the initrd code which
+                unmounts/detaches the root file system and the storage
+                it resides on. As last step the system is powered down.</para>
+
+                <para>Additional information about the system boot
+                process may be found in
+                <citerefentry><refentrytitle>boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>System Manager Bootup</title>
+
+                <para>At boot, the system manager on the OS image is
+                responsible for initializing the required file
+                systems, services and drivers that are necessary for
+                operation of the system. On
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                systems this process is split up in various discrete
+                steps which are exposed as target units. (See
+                <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for detailed information about target units.) The
+                boot-up process is highly parallelized so that the
+                order in which specific target units are reached is not
+                deterministic, but still adheres to a limited amount
+                of ordering structure.</para>
+
+                <para>When systemd starts up the system it will
+                activate all units that are dependencies of
+                <filename>default.target</filename> (as well as
+                recursively all dependencies of these
+                dependencies). Usually
+                <filename>default.target</filename> is simply an alias
+                of <filename>graphical.target</filename> or
+                <filename>multi-user.target</filename> depending on
+                whether the system is configured for a graphical UI or
+                only for a text console. To enforce minimal ordering
+                between the units pulled in a number of well-known
+                target units are available, as listed on
+                <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+
+                <para>The following chart is a structural overview of
+                these well-known units and their position in the
+                boot-up logic. The arrows describe which units are
+                pulled in and ordered before which other units. Units
+                near the top are started before units nearer to the
+                bottom of the chart.</para>
+
+<programlisting>local-fs-pre.target
+         |
+         v
+(various mounts and   (various swap   (various cryptsetup
+ fsck services...)     devices...)        devices...)       (various low-level   (various low-level
+         |                  |                  |             services: udevd,     API VFS mounts:
+         v                  v                  v             tmpfiles, random     mqueue, configfs,
+  local-fs.target      swap.target     cryptsetup.target    seed, sysctl, ...)      debugfs, ...)
+         |                  |                  |                    |                    |
+         \__________________|_________________ | ___________________|____________________/
+                                              \|/
+                                               v
+                                        sysinit.target
+                                               |
+                             _________________/|\___________________
+                            /                  |                    \
+                            |                  |                    |
+                            v                  |                    v
+                        (various               |              rescue.service
+                       sockets...)             |                    |
+                            |                  |                    v
+                            v                  |              <emphasis>rescue.target</emphasis>
+                     sockets.target            |
+                            |                  |
+                            \_________________ |
+                                              \|
+                                               v
+                                         basic.target
+                                               |
+            __________________________________/|                                 emergency.service
+           /                |                  |                                         |
+           |                |                  |                                         v
+           v                v                  v                                 <emphasis>emergency.target</emphasis>
+       display-      (various system    (various system
+   manager.service       services           services)
+           |           required for            |
+           |          graphical UIs)           v
+           |                |           <emphasis>multi-user.target</emphasis>
+           |                |                  |
+           \_______________ | _________________/
+                           \|/
+                            v
+                    <emphasis>graphical.target</emphasis></programlisting>
+
+                <para>Target units that are commonly used as boot
+                targets are <emphasis>emphasized</emphasis>. These
+                units are good choices as goal targets, for
+                example by passing them to the
+                <varname>systemd.unit=</varname> kernel command line
+                option (see
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>)
+                or by symlinking <filename>default.target</filename>
+                to them.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>System Manager Shutdown</title>
+
+                <para>System shutdown also consists of various target
+                units with some minimal ordering structure
+                applied:</para>
+
+
+
+
+<programlisting>                                  (conflicts with  (conflicts with
+                                    all system     all file system
+                                     services)     mounts, swaps,
+                                         |           cryptsetup
+                                         |          devices, ...)
+                                         |                |
+                                         v                v
+                                  shutdown.target    umount.target
+                                         |                |
+                                         \_______   ______/
+                                                 \ /
+                                                  v
+                                         (various low-level
+                                              services)
+                                                  |
+                                                  v
+                                            final.target
+                                                  |
+            _____________________________________/ \_________________________________
+           /                         |                        |                      \
+           |                         |                        |                      |
+           v                         v                        v                      v
+systemd-reboot.service   systemd-poweroff.service   systemd-halt.service   systemd-kexec.service
+           |                         |                        |                      |
+           v                         v                        v                      v
+    <emphasis>reboot.target</emphasis>             <emphasis>poweroff.target</emphasis>            <emphasis>halt.target</emphasis>           <emphasis>kexec.target</emphasis></programlisting>
+
+                <para>Commonly used system shutdown targets are <emphasis>emphasized</emphasis>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/crypttab.xml b/man/crypttab.xml
new file mode 100644 (file)
index 0000000..2a83994
--- /dev/null
@@ -0,0 +1,313 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+  This is based on crypttab(5) from Fedora's initscripts package, which in
+  turn is based on Debian's version.
+
+  The Red Hat version has been written by Miloslav Trmac <mitr@redhat.com>.
+
+-->
+<refentry id="crypttab">
+
+        <refentryinfo>
+                <title>crypttab</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Documentation</contrib>
+                                <firstname>Miloslav</firstname>
+                                <surname>Trmac</surname>
+                                <email>mitr@redhat.com</email>
+                        </author>
+                        <author>
+                                <contrib>Documentation</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>crypttab</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>crypttab</refname>
+                <refpurpose>Configuration for encrypted block devices</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/crypttab</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The <filename>/etc/crypttab</filename> file
+                describes encrypted block devices that are set up
+                during system boot.</para>
+
+                <para>Empty lines and lines starting with the #
+                character are ignored.  Each of the remaining lines
+                describes one encrypted block device, fields on the
+                line are delimited by white space.  The first two
+                fields are mandatory, the remaining two are
+                optional.</para>
+
+                <para>The first field contains the name of the
+                resulting encrypted block device; the device is set up
+                within <filename>/dev/mapper/</filename>.</para>
+
+                <para>The second field contains a path to the
+                underlying block device, or a specification of a block
+                device via <literal>UUID=</literal> followed by the
+                UUID.  If the block device contains a LUKS signature,
+                it is opened as a LUKS encrypted partition; otherwise
+                it is assumed to be a raw dm-crypt partition.</para>
+
+                <para>The third field specifies the encryption
+                password.  If the field is not present or the password
+                is set to none, the password has to be manually
+                entered during system boot.  Otherwise the field is
+                interpreted as a path to a file containing the
+                encryption password.  For swap encryption
+                <filename>/dev/urandom</filename> or the hardware
+                device <filename>/dev/hw_random</filename> can be used
+                as the password file; using
+                <filename>/dev/random</filename> may prevent boot
+                completion if the system does not have enough entropy
+                to generate a truly random encryption key.</para>
+
+                <para>The fourth field, if present, is a
+                comma-delimited list of options.  The following
+                options are recognized:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>cipher=</varname></term>
+
+                                <listitem><para>Specifies the cipher
+                                to use; see
+                                <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for possible values and the default
+                                value of this option.  A cipher with
+                                unpredictable IV values, such as
+                                <literal>aes-cbc-essiv:sha256</literal>,
+                                is recommended. </para></listitem>
+                        </varlistentry>
+
+
+                        <varlistentry>
+                                <term><varname>size=</varname></term>
+
+                                <listitem><para>Specifies the key size
+                                in bits; see
+                                <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for possible values and the default
+                                value of this
+                                option. </para></listitem>
+                        </varlistentry>
+
+
+                        <varlistentry>
+                                <term><varname>keyfile-size=</varname></term>
+
+                                <listitem><para>Specifies the maximum number
+                                of bytes to read from the keyfile; see
+                                <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for possible values and the default
+                                value of this option. This option is ignored
+                                in plain encryption mode, as the keyfile-size is then given by the key size.</para></listitem>
+                        </varlistentry>
+
+
+                        <varlistentry>
+                                <term><varname>keyfile-offset=</varname></term>
+
+                                <listitem><para>Specifies the number
+                                of bytes to skip at the start of
+                                the keyfile; see
+                                <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for possible values and the default
+                                value of this option.</para></listitem>
+                        </varlistentry>
+
+
+                        <varlistentry>
+                                <term><varname>hash=</varname></term>
+
+                                <listitem><para>Specifies the hash to
+                                use for password hashing; see
+                                <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry> for possible values and
+                                the default value of this
+                                option. </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>tries=</varname></term>
+
+                                <listitem><para>Specifies the maximum
+                                number of times the user is queried
+                                for a password.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>verify</varname></term>
+
+                                <listitem><para> If the encryption
+                                password is read from console, it has
+                                to be entered twice (to prevent
+                                typos). </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>read-only</varname></term>
+
+                                <listitem><para>Set up the encrypted
+                                block device in read-only
+                                mode.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>allow-discards</varname></term>
+
+                                <listitem><para>Allow discard requests
+                                to be passed through the encrypted
+                                block device. This improves
+                                performance on SSD storage but has
+                                security
+                                implications.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>luks</varname></term>
+
+                                <listitem><para>Force LUKS mode.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>plain</varname></term>
+
+                                <listitem><para>Force plain encryption
+                                mode.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>timeout=</varname></term>
+
+                                <listitem><para>Specify the timeout
+                                for querying for a password. If no
+                                unit is specified seconds is used.
+                                Supported units are s, ms,
+                                us, min, h, d.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>noauto</varname></term>
+
+                                <listitem><para> This device will not
+                                be automatically unlocked on
+                                boot. </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>nofail</varname></term>
+
+                                <listitem><para>The system will not
+                                wait for the device to show up and be
+                                unlocked at boot, and not fail the
+                                boot if it doesn't show
+                                up.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>swap</varname></term>
+
+                                <listitem><para> The encrypted block
+                                device will be used as a swap
+                                partition, and will be formatted as a
+                                swap partition after setting up the
+                                encrypted block device, with
+                                <citerefentry><refentrytitle>mkswap</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+                                <para>WARNING: Using the
+                                <varname>swap</varname> option will
+                                destroy the contents of the named
+                                partition during every boot, so make
+                                sure the underlying block device is
+                                specified
+                                correctly. </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>tmp</varname></term>
+
+                                <listitem><para>The encrypted block
+                                device will be prepared for using it
+                                as <filename>/tmp</filename>
+                                partition: it will be formatted using
+                                <citerefentry><refentrytitle>mke2fs</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+                                <para>WARNING: Using the
+                                <varname>tmp</varname> option will
+                                destroy the contents of the named
+                                partition during every boot, so make
+                                sure the underlying block device is
+                                specified
+                                correctly. </para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>At early boot and when the system manager
+                configuration is reloaded this file is translated into
+                native systemd units
+                by <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+                <example>
+                        <title>/etc/crypttab example</title>
+                        <para>Set up two encrypted block devices with
+                        LUKS: one normal one for storage, and another
+                        one for usage as swap device.</para>
+
+                        <programlisting>luks-2505567a-9e27-4efe-a4d5-15ad146c258b UUID=2505567a-9e27-4efe-a4d5-15ad146c258b - timeout=0
+swap /dev/sda7 /dev/urandom swap</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>mkswap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>mke2fs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/custom-html.xsl b/man/custom-html.xsl
new file mode 100644 (file)
index 0000000..906ddc5
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
+
+<!-- translate man page references to links to html pages -->
+<xsl:template match="citerefentry">
+  <a>
+    <xsl:attribute name="href">
+      <xsl:value-of select="refentrytitle"/><xsl:text>.html</xsl:text>
+    </xsl:attribute>
+    <xsl:call-template name="inline.charseq"/>
+  </a>
+</xsl:template>
+
+<!-- add Index link at top of page -->
+<xsl:template name="user.header.content">
+  <a>
+    <xsl:attribute name="href">
+      <xsl:text>index.html</xsl:text>
+    </xsl:attribute>
+    <xsl:text>Index </xsl:text>
+  </a>
+  <hr/>
+</xsl:template>
+
+<!-- Switch things to UTF-8, ISO-8859-1 is soo yesteryear -->
+<xsl:output method="html" encoding="UTF-8" indent="no"/>
+
+</xsl:stylesheet>
diff --git a/man/daemon.xml b/man/daemon.xml
new file mode 100644 (file)
index 0000000..0d29e7a
--- /dev/null
@@ -0,0 +1,949 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="daemon">
+
+        <refentryinfo>
+                <title>daemon</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>daemon</refentrytitle>
+                <manvolnum>7</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>daemon</refname>
+                <refpurpose>Writing and packaging system daemons</refpurpose>
+        </refnamediv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A daemon is a service process that runs in the
+                background and supervises the system or provides
+                functionality to other processes. Traditionally,
+                daemons are implemented following a scheme originating
+                in SysV Unix. Modern daemons should follow a simpler
+                yet more powerful scheme (here called "new-style"
+                daemons), as implemented by
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>. This
+                manual page covers both schemes, and in
+                particular includes recommendations for daemons that
+                shall be included in the systemd init system.</para>
+
+                <refsect2>
+                        <title>SysV Daemons</title>
+
+                        <para>When a traditional SysV daemon
+                        starts, it should execute the following steps
+                        as part of the initialization. Note that these
+                        steps are unnecessary for new-style daemons (see below),
+                        and should only be implemented if compatibility
+                        with SysV is essential.</para>
+
+                        <orderedlist>
+                                <listitem><para>Close all open file
+                                descriptors except STDIN, STDOUT,
+                                STDERR (i.e. the first three file
+                                descriptors 0, 1, 2). This ensures
+                                that no accidentally passed file
+                                descriptor stays around in the daemon
+                                process. On Linux this is best
+                                implemented by iterating through
+                                <filename>/proc/self/fd</filename>,
+                                with a fallback of iterating from file
+                                descriptor 3 to the value returned by
+                                <function>getrlimit()</function> for
+                                RLIMIT_NOFILE.</para></listitem>
+
+                                <listitem><para>Reset all signal
+                                handlers to their default. This is
+                                best done by iterating through the
+                                available signals up to the limit of
+                                _NSIG and resetting them to
+                                SIG_DFL.</para></listitem>
+
+                                <listitem><para>Reset the signal mask
+                                using
+                                <function>sigprocmask()</function>.</para></listitem>
+
+                                <listitem><para>Sanitize the
+                                environment block, removing or
+                                resetting environment variables that
+                                might negatively impact daemon
+                                runtime.</para></listitem>
+
+                                <listitem><para>Call <function>fork()</function>,
+                                to create a background
+                                process.</para></listitem>
+
+                                <listitem><para>In the child, call
+                                <function>setsid()</function> to
+                                detach from any terminal and create an
+                                independent session.</para></listitem>
+
+                                <listitem><para>In the child, call
+                                <function>fork()</function> again, to
+                                ensure the daemon can never re-acquire
+                                a terminal again.</para></listitem>
+
+                                <listitem><para>Call <function>exit()</function> in the
+                                first child, so that only the second
+                                child (the actual daemon process)
+                                stays around. This ensures that the
+                                daemon process is re-parented to
+                                init/PID 1, as all daemons should
+                                be.</para></listitem>
+
+                                <listitem><para>In the daemon process,
+                                connect <filename>/dev/null</filename>
+                                to STDIN, STDOUT,
+                                STDERR.</para></listitem>
+
+                                <listitem><para>In the daemon process,
+                                reset the umask to 0, so that the file
+                                modes passed to <function>open()</function>, <function>mkdir()</function> and
+                                suchlike directly control the access
+                                mode of the created files and
+                                directories.</para></listitem>
+
+                                <listitem><para>In the daemon process,
+                                change the current directory to the
+                                root directory (/), in order to avoid
+                                that the daemon involuntarily
+                                blocks mount points from being
+                                unmounted.</para></listitem>
+
+                                <listitem><para>In the daemon process,
+                                write the daemon PID (as returned by
+                                <function>getpid()</function>) to a
+                                PID file, for example
+                                <filename>/var/run/foobar.pid</filename>
+                                (for a hypothetical daemon "foobar"),
+                                to ensure that the daemon cannot be
+                                started more than once. This must be
+                                implemented in race-free fashion so
+                                that the PID file is only updated when
+                                at the same time it is verified that
+                                the PID previously stored in the PID
+                                file no longer exists or belongs to a
+                                foreign process. Commonly some kind of
+                                file locking is employed to implement
+                                this logic.</para></listitem>
+
+                                <listitem><para>In the daemon process,
+                                drop privileges, if possible and
+                                applicable.</para></listitem>
+
+                                <listitem><para>From the daemon
+                                process notify the original process
+                                started that initialization is
+                                complete. This can be implemented via
+                                an unnamed pipe or similar
+                                communication channel that is created
+                                before the first
+                                <function>fork()</function> and hence
+                                available in both the original and the
+                                daemon process.</para></listitem>
+
+                                <listitem><para>Call
+                                <function>exit()</function> in the
+                                original process. The process that
+                                invoked the daemon must be able to
+                                rely on that this
+                                <function>exit()</function> happens
+                                after initialization is complete and
+                                all external communication channels
+                                are established and
+                                accessible.</para></listitem>
+                        </orderedlist>
+
+                        <para>The BSD <function>daemon()</function> function should not be
+                        used, as it implements only a subset of these steps.</para>
+
+                        <para>A daemon that needs to provide
+                        compatibility with SysV systems should
+                        implement the scheme pointed out
+                        above. However, it is recommended to make this
+                        behavior optional and configurable via a
+                        command line argument, to ease debugging as
+                        well as to simplify integration into systems
+                        using systemd.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>New-Style Daemons</title>
+
+                        <para>Modern services for Linux should be
+                        implemented as new-style daemons. This makes it
+                        easier to supervise and control them at
+                        runtime and simplifies their
+                        implementation.</para>
+
+                        <para>For developing a new-style daemon none
+                        of the initialization steps recommended for
+                        SysV daemons need to be implemented. New-style
+                        init systems such as systemd make all of them
+                        redundant. Moreover, since some of these steps
+                        interfere with process monitoring, file
+                        descriptor passing and other functionality of
+                        the init system it is recommended not to
+                        execute them when run as new-style
+                        service.</para>
+
+                        <para>Note that new-style init systems
+                        guarantee execution of daemon processes in
+                        clean process contexts: it is guaranteed that
+                        the environment block is sanitized, that the
+                        signal handlers and mask is reset and that no
+                        left-over file descriptors are passed. Daemons
+                        will be executed in their own session, and
+                        STDIN/STDOUT/STDERR connected to
+                        <filename>/dev/null</filename> unless
+                        otherwise configured. The umask is reset.</para>
+
+                        <para>It is recommended for new-style daemons
+                        to implement the following:</para>
+
+                        <orderedlist>
+                                <listitem><para>If SIGTERM is
+                                received, shut down the daemon and
+                                exit cleanly.</para></listitem>
+
+                                <listitem><para>If SIGHUP is received,
+                                reload the configuration files, if
+                                this applies.</para></listitem>
+
+                                <listitem><para>Provide a correct exit
+                                code from the main daemon process, as
+                                this is used by the init system to
+                                detect service errors and problems. It
+                                is recommended to follow the exit code
+                                scheme as defined in the <ulink
+                                url="http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB
+                                recommendations for SysV init
+                                scripts</ulink>.</para></listitem>
+
+                                <listitem><para>If possible and
+                                applicable expose the daemon's control
+                                interface via the D-Bus IPC system and
+                                grab a bus name as last step of
+                                initialization.</para></listitem>
+
+                                <listitem><para>For integration in
+                                systemd, provide a
+                                <filename>.service</filename> unit
+                                file that carries information about
+                                starting, stopping and otherwise
+                                maintaining the daemon. See
+                                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details.</para></listitem>
+
+                                <listitem><para>As much as possible,
+                                rely on the init system's
+                                functionality to limit the access of
+                                the daemon to files, services and
+                                other resources. i.e. in the case of
+                                systemd, rely on systemd's resource
+                                limit control instead of implementing
+                                your own, rely on systemd's privilege
+                                dropping code instead of implementing
+                                it in the daemon, and similar. See
+                                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for the available
+                                controls.</para></listitem>
+
+                                <listitem><para>If D-Bus is used, make
+                                your daemon bus-activatable, via
+                                supplying a D-Bus service activation
+                                configuration file. This has multiple
+                                advantages: your daemon may be started
+                                lazily on-demand; it may be started in
+                                parallel to other daemons requiring it
+                                -- which maximizes parallelization and
+                                boot-up speed; your daemon can be
+                                restarted on failure, without losing
+                                any bus requests, as the bus queues
+                                requests for activatable services. See
+                                below for details.</para></listitem>
+
+                                <listitem><para>If your daemon
+                                provides services to other local
+                                processes or remote clients via a
+                                socket, it should be made
+                                socket-activatable following the
+                                scheme pointed out below. Like D-Bus
+                                activation this enables on-demand
+                                starting of services as well as it
+                                allows improved parallelization of
+                                service start-up. Also, for state-less
+                                protocols (such as syslog, DNS) a
+                                daemon implementing socket-based
+                                activation can be restarted without
+                                losing a single request. See below for
+                                details.</para></listitem>
+
+                                <listitem><para>If applicable a daemon
+                                should notify the init system about
+                                startup completion or status updates
+                                via the
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                interface.</para></listitem>
+
+                                <listitem><para>Instead of using the
+                                <function>syslog()</function> call to log directly to the
+                                system syslog service, a new-style daemon may
+                                choose to simply log to STDERR via
+                                <function>fprintf()</function>, which is then forwarded to
+                                syslog by the init system. If log
+                                priorities are necessary these can be
+                                encoded by prefixing individual log
+                                lines with strings like "&lt;4&gt;"
+                                (for log priority 4 "WARNING" in the
+                                syslog priority scheme), following a
+                                similar style as the Linux kernel's
+                                <function>printk()</function> priority system. In fact,
+                                using this style of logging also
+                                enables the init system to optionally
+                                direct all application logging to the
+                                kernel log buffer (kmsg), as
+                                accessible via
+                                <citerefentry><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>. This
+                                kind of logging may be enabled by
+                                setting
+                                <varname>StandardError=syslog</varname>
+                                in the service unit file. For details
+                                see
+                                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                and
+                                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        </orderedlist>
+
+                        <para>These recommendations are similar but
+                        not identical to the <ulink
+                        url="http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html#//apple_ref/doc/uid/TP40001762-104738">Apple
+                        MacOS X Daemon Requirements</ulink>.</para>
+                </refsect2>
+
+        </refsect1>
+        <refsect1>
+                <title>Activation</title>
+
+                <para>New-style init systems provide multiple
+                additional mechanisms to activate services, as
+                detailed below. It is common that services are
+                configured to be activated via more than one mechanism
+                at the same time. An example for systemd:
+                <filename>bluetoothd.service</filename> might get
+                activated either when Bluetooth hardware is plugged
+                in, or when an application accesses its programming
+                interfaces via D-Bus. Or, a print server daemon might
+                get activated when traffic arrives at an IPP port, or
+                when a printer is plugged in, or when a file is queued
+                in the printer spool directory. Even for services that
+                are intended to be started on system bootup
+                unconditionally it is a good idea to implement some of
+                the various activation schemes outlined below, in
+                order to maximize parallelization: if a daemon
+                implements a D-Bus service or listening socket,
+                implementing the full bus and socket activation scheme
+                allows starting of the daemon with its clients in
+                parallel (which speeds up boot-up), since all its
+                communication channels are established already, and no
+                request is lost because client requests will be queued
+                by the bus system (in case of D-Bus) or the kernel (in
+                case of sockets), until the activation is
+                completed.</para>
+
+                <refsect2>
+                        <title>Activation on Boot</title>
+
+                        <para>Old-style daemons are usually activated
+                        exclusively on boot (and manually by the
+                        administrator) via SysV init scripts, as
+                        detailed in the <ulink
+                        url="http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB
+                        Linux Standard Base Core
+                        Specification</ulink>. This method of
+                        activation is supported ubiquitously on Linux
+                        init systems, both old-style and new-style
+                        systems. Among other issues SysV init scripts
+                        have the disadvantage of involving shell
+                        scripts in the boot process. New-style init
+                        systems generally employ updated versions of
+                        activation, both during boot-up and during
+                        runtime and using more minimal service
+                        description files.</para>
+
+                        <para>In systemd, if the developer or
+                        administrator wants to make sure a service or
+                        other unit is activated automatically on boot
+                        it is recommended to place a symlink to the
+                        unit file in the <filename>.wants/</filename>
+                        directory of either
+                        <filename>multi-user.target</filename> or
+                        <filename>graphical.target</filename>, which
+                        are normally used as boot targets at system
+                        startup. See
+                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                        for details about the
+                        <filename>.wants/</filename> directories, and
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                        for details about the two boot targets.</para>
+
+                </refsect2>
+
+                <refsect2>
+                        <title>Socket-Based Activation</title>
+
+                        <para>In order to maximize the possible
+                        parallelization and robustness and simplify
+                        configuration and development, it is
+                        recommended for all new-style daemons that
+                        communicate via listening sockets to employ
+                        socket-based activation. In a socket-based
+                        activation scheme the creation and binding of
+                        the listening socket as primary communication
+                        channel of daemons to local (and sometimes
+                        remote) clients is moved out of the daemon
+                        code and into the init system. Based on
+                        per-daemon configuration the init system
+                        installs the sockets and then hands them off
+                        to the spawned process as soon as the
+                        respective daemon is to be started.
+                        Optionally activation of the service can be
+                        delayed until the first inbound traffic
+                        arrives at the socket, to implement on-demand
+                        activation of daemons. However, the primary
+                        advantage of this scheme is that all providers
+                        and all consumers of the sockets can be
+                        started in parallel as soon as all sockets
+                        are established. In addition to that daemons
+                        can be restarted with losing only a minimal
+                        number of client transactions or even any
+                        client request at all (the latter is
+                        particularly true for state-less protocols,
+                        such as DNS or syslog), because the socket
+                        stays bound and accessible during the restart,
+                        and all requests are queued while the daemon
+                        cannot process them.</para>
+
+                        <para>New-style daemons which support socket
+                        activation must be able to receive their
+                        sockets from the init system, instead of
+                        creating and binding them themselves. For
+                        details about the programming interfaces for
+                        this scheme provided by systemd see
+                        <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                        and
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>. For
+                        details about porting existing daemons to
+                        socket-based activation see below. With
+                        minimal effort it is possible to implement
+                        socket-based activation in addition to
+                        traditional internal socket creation in the
+                        same codebase in order to support both
+                        new-style and old-style init systems from the
+                        same daemon binary.</para>
+
+                        <para>systemd implements socket-based
+                        activation via <filename>.socket</filename>
+                        units, which are described in
+                        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>. When
+                        configuring socket units for socket-based
+                        activation it is essential that all listening
+                        sockets are pulled in by the special target
+                        unit <filename>sockets.target</filename>. It
+                        is recommended to place a
+                        <varname>WantedBy=sockets.target</varname>
+                        directive in the <literal>[Install]</literal>
+                        section, to automatically add such a
+                        dependency on installation of a socket
+                        unit. Unless
+                        <varname>DefaultDependencies=no</varname> is
+                        set the necessary ordering dependencies are
+                        implicitly created for all socket units. For
+                        more information about
+                        <filename>sockets.target</filename> see
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>. It
+                        is not necessary or recommended to place any
+                        additional dependencies on socket units (for
+                        example from
+                        <filename>multi-user.target</filename> or
+                        suchlike) when one is installed in
+                        <filename>sockets.target</filename>.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>Bus-Based Activation</title>
+
+                        <para>When the D-Bus IPC system is used for
+                        communication with clients, new-style daemons
+                        should employ bus activation so that they are
+                        automatically activated when a client
+                        application accesses their IPC
+                        interfaces. This is configured in D-Bus
+                        service files (not to be confused with systemd
+                        service unit files!). To ensure that D-Bus
+                        uses systemd to start-up and maintain the
+                        daemon use the
+                        <varname>SystemdService=</varname> directive
+                        in these service files, to configure the
+                        matching systemd service for a D-Bus
+                        service. e.g.: for a D-Bus service whose D-Bus
+                        activation file is named
+                        <filename>org.freedesktop.RealtimeKit.service</filename>,
+                        make sure to set
+                        <varname>SystemdService=rtkit-daemon.service</varname>
+                        in that file, to bind it to the systemd
+                        service
+                        <filename>rtkit-daemon.service</filename>. This
+                        is needed to make sure that the daemon is
+                        started in a race-free fashion when activated
+                        via multiple mechanisms simultaneously.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>Device-Based Activation</title>
+
+                        <para>Often, daemons that manage a particular
+                        type of hardware should be activated only when
+                        the hardware of the respective kind is plugged
+                        in or otherwise becomes available. In a
+                        new-style init system it is possible to bind
+                        activation to hardware plug/unplug events. In
+                        systemd, kernel devices appearing in the
+                        sysfs/udev device tree can be exposed as units
+                        if they are tagged with the string
+                        "<literal>systemd</literal>". Like any other
+                        kind of unit they may then pull in other units
+                        when activated (i.e. Plugged in) and thus
+                        implement device-based activation. Systemd
+                        dependencies may be encoded in the udev
+                        database via the
+                        <varname>SYSTEMD_WANTS=</varname>
+                        property. See
+                        <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                        for details. Often it is nicer to pull in
+                        services from devices only indirectly via
+                        dedicated targets. Example: instead of pulling
+                        in <filename>bluetoothd.service</filename>
+                        from all the various bluetooth dongles and
+                        other hardware available, pull in
+                        bluetooth.target from them and
+                        <filename>bluetoothd.service</filename> from
+                        that target. This provides for nicer
+                        abstraction and gives administrators the
+                        option to enable
+                        <filename>bluetoothd.service</filename> via
+                        controlling a
+                        <filename>bluetooth.target.wants/</filename>
+                        symlink uniformly with a command like
+                        <command>enable</command> of
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        instead of manipulating the udev
+                        ruleset.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>Path-Based Activation</title>
+
+                        <para>Often, runtime of daemons processing
+                        spool files or directories (such as a printing
+                        system) can be delayed until these file system
+                        objects change state, or become
+                        non-empty. New-style init systems provide a
+                        way to bind service activation to file system
+                        changes. systemd implements this scheme via
+                        path-based activation configured in
+                        <filename>.path</filename> units, as outlined
+                        in
+                        <citerefentry><refentrytitle>systemd.path</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>Timer-Based Activation</title>
+
+                        <para>Some daemons that implement clean-up
+                        jobs that are intended to be executed in
+                        regular intervals benefit from timer-based
+                        activation. In systemd, this is implemented
+                        via <filename>.timer</filename> units, as
+                        described in
+                        <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>Other Forms of Activation</title>
+
+                        <para>Other forms of activation have been
+                        suggested and implemented in some
+                        systems. However, often there are simpler or
+                        better alternatives, or they can be put
+                        together of combinations of the schemes
+                        above. Example: sometimes it appears useful to
+                        start daemons or <filename>.socket</filename>
+                        units when a specific IP address is configured
+                        on a network interface, because network
+                        sockets shall be bound to the
+                        address. However, an alternative to implement
+                        this is by utilizing the Linux IP_FREEBIND
+                        socket option, as accessible via
+                        <varname>FreeBind=yes</varname> in systemd
+                        socket files (see
+                        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                        for details). This option, when enabled,
+                        allows sockets to be bound to a non-local, not
+                        configured IP address, and hence allows
+                        bindings to a particular IP address before it
+                        actually becomes available, making such an
+                        explicit dependency to the configured address
+                        redundant. Another often suggested trigger for
+                        service activation is low system
+                        load. However, here too, a more convincing
+                        approach might be to make proper use of
+                        features of the operating system: in
+                        particular, the CPU or IO scheduler of
+                        Linux. Instead of scheduling jobs from
+                        userspace based on monitoring the OS
+                        scheduler, it is advisable to leave the
+                        scheduling of processes to the OS scheduler
+                        itself. systemd provides fine-grained access
+                        to the CPU and IO schedulers. If a process
+                        executed by the init system shall not
+                        negatively impact the amount of CPU or IO
+                        bandwidth available to other processes, it
+                        should be configured with
+                        <varname>CPUSchedulingPolicy=idle</varname>
+                        and/or
+                        <varname>IOSchedulingClass=idle</varname>. Optionally,
+                        this may be combined with timer-based
+                        activation to schedule background jobs during
+                        runtime and with minimal impact on the system,
+                        and remove it from the boot phase
+                        itself.</para>
+                </refsect2>
+
+        </refsect1>
+        <refsect1>
+                <title>Integration with Systemd</title>
+
+                <refsect2>
+                        <title>Writing Systemd Unit Files</title>
+
+                        <para>When writing systemd unit files, it is
+                        recommended to consider the following
+                        suggestions:</para>
+
+                        <orderedlist>
+                                <listitem><para>If possible do not use
+                                the <varname>Type=forking</varname>
+                                setting in service files. But if you
+                                do, make sure to set the PID file path
+                                using <varname>PIDFile=</varname>. See
+                                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details.</para></listitem>
+
+                                <listitem><para>If your daemon
+                                registers a D-Bus name on the bus,
+                                make sure to use
+                                <varname>Type=dbus</varname> in the
+                                service file if
+                                possible.</para></listitem>
+
+                                <listitem><para>Make sure to set a
+                                good human-readable description string
+                                with
+                                <varname>Description=</varname>.</para></listitem>
+
+                                <listitem><para>Do not disable
+                                <varname>DefaultDependencies=</varname>,
+                                unless you really know what you do and
+                                your unit is involved in early boot or
+                                late system shutdown.</para></listitem>
+
+                                <listitem><para>Normally, little if
+                                any dependencies should need to
+                                be defined explicitly. However, if you
+                                do configure explicit dependencies, only refer to
+                                unit names listed on
+                                <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                or names introduced by your own
+                                package to keep the unit file
+                                operating
+                                system-independent.</para></listitem>
+
+                                <listitem><para>Make sure to include
+                                an <literal>[Install]</literal>
+                                section including installation
+                                information for the unit file. See
+                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details. To activate your service
+                                on boot make sure to add a
+                                <varname>WantedBy=multi-user.target</varname>
+                                or
+                                <varname>WantedBy=graphical.target</varname>
+                                directive. To activate your socket on
+                                boot, make sure to add
+                                <varname>WantedBy=sockets.target</varname>. Usually
+                                you also want to make sure that when
+                                your service is installed your socket
+                                is installed too, hence add
+                                <varname>Also=foo.socket</varname> in
+                                your service file
+                                <filename>foo.service</filename>, for
+                                a hypothetical program
+                                <filename>foo</filename>.</para></listitem>
+
+                        </orderedlist>
+                </refsect2>
+
+                <refsect2>
+                        <title>Installing Systemd Service Files</title>
+
+                        <para>At the build installation time
+                        (e.g. <command>make install</command> during
+                        package build) packages are recommended to
+                        install their systemd unit files in the
+                        directory returned by <command>pkg-config
+                        systemd
+                        --variable=systemdsystemunitdir</command> (for
+                        system services) or <command>pkg-config
+                        systemd
+                        --variable=systemduserunitdir</command>
+                        (for user services). This will make the
+                        services available in the system on explicit
+                        request but not activate them automatically
+                        during boot. Optionally, during package
+                        installation (e.g. <command>rpm -i</command>
+                        by the administrator) symlinks should be
+                        created in the systemd configuration
+                        directories via the <command>enable</command>
+                        command of the
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        tool, to activate them automatically on
+                        boot.</para>
+
+                        <para>Packages using
+                        <citerefentry><refentrytitle>autoconf</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        are recommended to use a configure script
+                        excerpt like the following to determine the
+                        unit installation path during source
+                        configuration:</para>
+
+                        <programlisting>PKG_PROG_PKG_CONFIG
+AC_ARG_WITH([systemdsystemunitdir],
+        AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
+        [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
+if test "x$with_systemdsystemunitdir" != xno; then
+        AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+fi
+AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])</programlisting>
+
+                        <para>This snippet allows automatic
+                        installation of the unit files on systemd
+                        machines, and optionally allows their
+                        installation even on machines lacking
+                        systemd. (Modification of this snippet for the
+                        user unit directory is left as an exercise for the
+                        reader.)</para>
+
+                        <para>Additionally, to ensure that
+                        <command>make distcheck</command> continues to
+                        work, it is recommended to add the following
+                        to the top-level <filename>Makefile.am</filename>
+                        file in
+                        <citerefentry><refentrytitle>automake</refentrytitle><manvolnum>1</manvolnum></citerefentry>-based
+                        projects:</para>
+
+                        <programlisting>DISTCHECK_CONFIGURE_FLAGS = \
+        --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)</programlisting>
+
+                        <para>Finally, unit files should be installed in the system with an automake excerpt like the following:</para>
+
+                        <programlisting>if HAVE_SYSTEMD
+systemdsystemunit_DATA = \
+        foobar.socket \
+        foobar.service
+endif</programlisting>
+
+                        <para>In the
+                        <citerefentry><refentrytitle>rpm</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <filename>.spec</filename> file use snippets
+                        like the following to enable/disable the
+                        service during
+                        installation/deinstallation. This makes use of
+                        the RPM macros shipped along systemd. Consult
+                        the packaging guidelines of your distribution
+                        for details and the equivalent for other
+                        package managers.</para>
+
+                        <para>At the top of the file:</para>
+
+                        <programlisting>BuildRequires: systemd
+%{?systemd_requires}</programlisting>
+
+                        <para>And as scriptlets, further down:</para>
+
+                        <programlisting>%post
+%systemd_post foobar.service foobar.socket
+
+%preun
+%systemd_preun foobar.service foobar.socket
+
+%postun
+%systemd_postun</programlisting>
+
+                        <para>If the service shall be restarted during
+                        upgrades replace the
+                        <literal>%postun</literal> scriptlet above
+                        with the following:</para>
+
+                        <programlisting>%postun
+%systemd_postun_with_restart foobar.service</programlisting>
+
+                        <para>Note that
+                        <literal>%systemd_post</literal> and
+                        <literal>%systemd_preun</literal> expect the
+                        names of all units that are installed/removed
+                        as arguments, separated by
+                        spaces. <literal>%systemd_postun</literal>
+                        expects no
+                        arguments. <literal>%systemd_postun_with_restart</literal>
+                        expects the units to restart as
+                        arguments.</para>
+
+                        <para>To facilitate upgrades from a package
+                        version that shipped only SysV init scripts to
+                        a package version that ships both a SysV init
+                        script and a native systemd service file, use
+                        a fragment like the following:</para>
+
+                        <programlisting>%triggerun -- foobar &lt; 0.47.11-1
+if /sbin/chkconfig --level 5 foobar ; then
+        /bin/systemctl --no-reload enable foobar.service foobar.socket >/dev/null 2>&amp;1 || :
+fi</programlisting>
+
+                        <para>Where 0.47.11-1 is the first package
+                        version that includes the native unit
+                        file. This fragment will ensure that the first
+                        time the unit file is installed it will be
+                        enabled if and only if the SysV init script is
+                        enabled, thus making sure that the enable
+                        status is not changed. Note that
+                        <command>chkconfig</command> is a command
+                        specific to Fedora which can be used to check
+                        whether a SysV init script is enabled. Other
+                        operating systems will have to use different
+                        commands here.</para>
+                </refsect2>
+        </refsect1>
+
+        <refsect1>
+                <title>Porting Existing Daemons</title>
+
+                <para>Since new-style init systems such as systemd are
+                compatible with traditional SysV init systems it is
+                not strictly necessary to port existing daemons to the
+                new style. However doing so offers additional
+                functionality to the daemons as well as simplifying
+                integration into new-style init systems.</para>
+
+                <para>To port an existing SysV compatible daemon the
+                following steps are recommended:</para>
+
+                <orderedlist>
+                        <listitem><para>If not already implemented,
+                        add an optional command line switch to the
+                        daemon to disable daemonization. This is
+                        useful not only for using the daemon in
+                        new-style init systems, but also to ease
+                        debugging.</para></listitem>
+
+                        <listitem><para>If the daemon offers
+                        interfaces to other software running on the
+                        local system via local AF_UNIX sockets,
+                        consider implementing socket-based activation
+                        (see above). Usually a minimal patch is
+                        sufficient to implement this: Extend the
+                        socket creation in the daemon code so that
+                        <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                        is checked for already passed sockets
+                        first. If sockets are passed (i.e. when
+                        <function>sd_listen_fds()</function> returns a
+                        positive value), skip the socket creation step
+                        and use the passed sockets. Secondly, ensure
+                        that the file-system socket nodes for local
+                        AF_UNIX sockets used in the socket-based
+                        activation are not removed when the daemon
+                        shuts down, if sockets have been
+                        passed. Third, if the daemon normally closes
+                        all remaining open file descriptors as part of
+                        its initialization, the sockets passed from
+                        the init system must be spared. Since
+                        new-style init systems guarantee that no
+                        left-over file descriptors are passed to
+                        executed processes, it might be a good choice
+                        to simply skip the closing of all remaining
+                        open file descriptors if sockets are
+                        passed.</para></listitem>
+
+                        <listitem><para>Write and install a systemd
+                        unit file for the service (and the sockets if
+                        socket-based activation is used, as well as a
+                        path unit file, if the daemon processes a
+                        spool directory), see above for
+                        details.</para></listitem>
+
+                        <listitem><para>If the daemon exposes
+                        interfaces via D-Bus, write and install a
+                        D-Bus activation file for the service, see
+                        above for details.</para></listitem>
+                </orderedlist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/halt.xml b/man/halt.xml
new file mode 100644 (file)
index 0000000..8473965
--- /dev/null
@@ -0,0 +1,172 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="halt">
+
+        <refentryinfo>
+                <title>halt</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>halt</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>halt</refname>
+                <refname>poweroff</refname>
+                <refname>reboot</refname>
+                <refpurpose>Halt, power-off or reboot the machine</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>halt <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+                </cmdsynopsis>
+                <cmdsynopsis>
+                        <command>poweroff <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+                </cmdsynopsis>
+                <cmdsynopsis>
+                        <command>reboot <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>halt</command>,
+                <command>poweroff</command>, <command>reboot</command>
+                may be used to halt, power-off or reboot the
+                machine.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--halt</option></term>
+
+                                <listitem><para>Halt the machine,
+                                regardless of which one of the three
+                                commands is invoked.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-p</option></term>
+                                <term><option>--poweroff</option></term>
+
+                                <listitem><para>Power-off the machine,
+                                regardless of which one of the three
+                                commands is invoked.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--reboot</option></term>
+
+                                <listitem><para>Reboot the machine,
+                                regardless of which one of the three
+                                commands is invoked.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-f</option></term>
+                                <term><option>--force</option></term>
+
+                                <listitem><para>Force immediate halt,
+                                power-off, reboot. Don't contact the
+                                init system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-w</option></term>
+                                <term><option>--wtmp-only</option></term>
+
+                                <listitem><para>Only write wtmp
+                                shutdown entry, don't actually halt,
+                                power-off, reboot.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-d</option></term>
+                                <term><option>--no-wtmp</option></term>
+
+                                <listitem><para>Don't write wtmp
+                                shutdown entry.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-wall</option></term>
+
+                                <listitem><para>Don't send wall
+                                message before
+                                halt, power-off, reboot.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>These are legacy commands available for
+                compatibility only.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>shutdown</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/hostname.xml b/man/hostname.xml
new file mode 100644 (file)
index 0000000..84a2961
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="hostname">
+        <refentryinfo>
+                <title>/etc/hostname</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>hostname</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>hostname</refname>
+                <refpurpose>Local host name configuration file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/hostname</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The <filename>/etc/hostname</filename> file
+                configures the name of the local system that is set
+                during boot, with the
+                <citerefentry><refentrytitle>sethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                system call. It should contain a single
+                newline-terminated host name string. The
+                host name may be a free-form string up to 64 characters
+                in length, however it is recommended that it consists
+                only of 7bit ASCII lower-case characters and no spaces or dots,
+                and limits itself to the format allowed for DNS domain
+                name labels, even though this is not a
+                strict requirement.</para>
+
+                <para>Depending on the operating system other
+                configuration files might be checked for configuration
+                of the host name as well, however only as fallback.</para>
+
+                <para>You may use
+                <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to change the value of this file from the command
+                line.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>History</title>
+
+                <para>The simple configuration file format of
+                <filename>/etc/hostname</filename> originates from
+                Debian GNU/Linux.</para>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>sethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml
new file mode 100644 (file)
index 0000000..a29d2f5
--- /dev/null
@@ -0,0 +1,254 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="hostnamectl">
+
+        <refentryinfo>
+                <title>hostnamectl</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>hostnamectl</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>hostnamectl</refname>
+                <refpurpose>Control the system hostname</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>hostnamectl <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>hostnamectl</command> may be used to
+                query and change the system hostname and related
+                settings.</para>
+
+                <para>This tool distinguishes three different host
+                names: the high-level "pretty" hostname which might
+                include all kinds of special characters
+                (e.g. "Lennart's Laptop"), the static hostname which
+                is used to initialize the kernel hostname at boot
+                (e.g. "lennarts-laptop"), and the transient hostname
+                which might be assigned temporarily due to network
+                configuration and might revert back to the static
+                hostname if network connectivity is lost and is only
+                temporarily written to the kernel hostname
+                (e.g. "dhcp-47-11").</para>
+
+                <para>Note that the pretty hostname has little
+                restrictions on the characters used, while the static
+                and transient hostnames are limited to the usually
+                accepted characters of internet domain names.</para>
+
+                <para>The static host name is stored in
+                <filename>/etc/hostname</filename>, see
+                <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more information. The pretty host name, chassis
+                type and icon name are stored in
+                <filename>/etc/machine-info</filename>, see
+                <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-ask-password</option></term>
+
+                                <listitem><para>Don't query the user
+                                for authentication for privileged
+                                operations.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-H</option></term>
+                                <term><option>--host</option></term>
+
+                                <listitem><para>Execute the operation
+                                remotely. Specify a hostname, or
+                                username and hostname separated by @,
+                                to connect to. This will use SSH to
+                                talk to a remote
+                                system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--static</option></term>
+                                <term><option>--transient</option></term>
+                                <term><option>--pretty</option></term>
+
+                                <listitem><para>If
+                                <command>set-hostname</command> is
+                                invoked and one or more of these
+                                options are passed only the selected
+                                hostnames is
+                                updated.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>The following commands are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><command>status</command></term>
+
+                                <listitem><para>Show current system
+                                hostname and related
+                                information.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-hostname [NAME]</command></term>
+
+                                <listitem><para>Set the system
+                                hostname. By default this will alter
+                                the pretty, the static, and the
+                                transient hostname alike, however if
+                                one or more of
+                                <option>--static</option>,
+                                <option>--transient</option>,
+                                <option>--pretty</option> are used
+                                only the selected hostnames are
+                                changed. If the pretty hostname is
+                                being set, and static or transient are
+                                being set as well the specified host
+                                name will be simplified in regards to
+                                the character set used before the
+                                latter are updated. This is done by
+                                replacing spaces by "-" and removing
+                                special characters. This ensures that
+                                the pretty and the static hostname
+                                are always closely related while still
+                                following the validity rules of the
+                                specific name. This simplification of
+                                the hostname string is not done if
+                                only the transient and/or static host
+                                names are set, and the pretty host
+                                name is left untouched. Pass the empty
+                                string "" as hostname to reset the
+                                selected hostnames to their default
+                                (usually
+                                "localhost").</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-icon-name [NAME]</command></term>
+
+                                <listitem><para>Set the system icon
+                                name. The icon name is used by some
+                                graphical applications to visualize
+                                this host. The icon name should follow
+                                the <ulink
+                                url="http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html">Icon
+                                Naming Specification</ulink>. Pass an
+                                empty string to this operation to
+                                reset the icon name to the default
+                                value which is determined from chassis
+                                type (see below) and possibly other
+                                parameters.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-chassis [TYPE]</command></term>
+
+                                <listitem><para>Set the chassis
+                                type. The chassis type is used by some
+                                graphical applications to visualize
+                                the host or alter user
+                                interaction. Currently, the following
+                                chassis types are defined:
+                                <literal>desktop</literal>,
+                                <literal>laptop</literal>,
+                                <literal>server</literal>,
+                                <literal>tablet</literal>,
+                                <literal>handset</literal>, as well as
+                                the special chassis types
+                                <literal>vm</literal> and
+                                <literal>container</literal> for
+                                virtualized systems that lack an
+                                immediate physical chassis. Pass an
+                                empty string to this operation to
+                                reset the chassis type to the default
+                                value which is determined from the
+                                firmware and possibly other
+                                parameters.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/journalctl.xml b/man/journalctl.xml
new file mode 100644 (file)
index 0000000..959ae1e
--- /dev/null
@@ -0,0 +1,584 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="journalctl">
+
+        <refentryinfo>
+                <title>journalctl</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>journalctl</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>journalctl</refname>
+                <refpurpose>Query the systemd journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>journalctl <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">MATCHES</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>journalctl</command> may be used to
+                query the contents of the
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                journal as written by
+                <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+                <para>If called without parameter it will show the full
+                contents of the journal, starting with the oldest
+                entry collected.</para>
+
+                <para>If one or more match arguments are passed the
+                output is filtered accordingly. A match is in the
+                format <literal>FIELD=VALUE</literal>,
+                e.g. <literal>_SYSTEMD_UNIT=httpd.service</literal>,
+                referring to the components of a structured journal
+                entry. See
+                <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                for a list of well-known fields. If multiple matches
+                are specified matching different fields the log
+                entries are filtered by both, i.e. the resulting output
+                will show only entries matching all the specified
+                matches of this kind. If two matches apply to the same
+                field, then they are automatically matched as
+                alternatives, i.e. the resulting output will show
+                entries matching any of the specified matches for the
+                same field. Finally, if the character
+                "<literal>+</literal>" appears as separate word on the
+                command line all matches before and after are combined
+                in a disjunction (i.e. logical OR).</para>
+
+                <para>As shortcuts for a few types of field/value
+                matches file paths may be specified. If a file path
+                refers to an executable file, this is equivalent to an
+                <literal>_EXE=</literal> match for the canonicalized
+                binary path. Similar, if a path refers to a device
+                node, this is equivalent to a
+                <literal>_KERNEL_DEVICE=</literal> match for the
+                device.</para>
+
+                <para>Output is interleaved from all accessible
+                journal files, whether they are rotated or currently
+                being written, and regardless whether they belong to the
+                system itself or are accessible user journals.</para>
+
+                <para>All users are granted access to their private
+                per-user journals. However, by default only root and
+                users who are members of the <literal>adm</literal>
+                group get access to the system journal and the
+                journals of other users.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+                                <listitem><para>Do not pipe output into a
+                                pager.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--full</option></term>
+
+                                <listitem><para>Show all (printable) fields in
+                                full.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--all</option></term>
+                                <term><option>-a</option></term>
+
+                                <listitem><para>Show all fields in
+                                full, even if they include unprintable
+                                characters or are very
+                                long.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--follow</option></term>
+                                <term><option>-f</option></term>
+
+                                <listitem><para>Show only the most recent
+                                journal entries, and continuously print
+                                new entries as they are appended to
+                                the journal.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--lines=</option></term>
+                                <term><option>-n</option></term>
+
+                                <listitem><para>Show the most recent
+                                journal events and limit the number of
+                                events shown. If
+                                <option>--follow</option> is used,
+                                this option is implied. The argument,
+                                a positive integer, is optional, and
+                                defaults to 10. </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-tail</option></term>
+
+                                <listitem><para>Show all stored output
+                                lines, even in follow mode. Undoes the
+                                effect of
+                                <option>--lines=</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--output=</option></term>
+                                <term><option>-o</option></term>
+
+                                <listitem><para>Controls the
+                                formatting of the journal entries that
+                                are shown. Takes one of
+                                <literal>short</literal>,
+                                <literal>short-monotonic</literal>,
+                                <literal>verbose</literal>,
+                                <literal>export</literal>,
+                                <literal>json</literal>,
+                                <literal>json-pretty</literal>,
+                                <literal>json-sse</literal>,
+                                <literal>cat</literal>. <literal>short</literal>
+                                is the default and generates an output
+                                that is mostly identical to the
+                                formatting of classic syslog log
+                                files, showing one line per journal
+                                entry. <literal>short-monotonic</literal>
+                                is very similar but shows monotonic
+                                timestamps instead of wallclock
+                                timestamps. <literal>verbose</literal>
+                                shows the full structured entry items
+                                with all
+                                fields. <literal>export</literal>
+                                serializes the journal into a binary
+                                (but mostly text-based) stream
+                                suitable for backups and network
+                                transfer (see <ulink
+                                url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+                                Export Format</ulink> for more
+                                information). <literal>json</literal>
+                                formats entries as JSON data
+                                structures, one per
+                                line (see <ulink
+                                url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal
+                                JSON Format</ulink> for more
+                                information). <literal>json-pretty</literal>
+                                also formats entries as JSON data
+                                structures, but formats them in
+                                multiple lines in order to make them
+                                more readable for
+                                humans. <literal>json-sse</literal>
+                                also formats entries as JSON data
+                                structures, but wraps them in a format
+                                suitable for <ulink
+                                url="https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events">Server-Sent
+                                Events</ulink>. <literal>cat</literal>
+                                generates a very terse output only
+                                showing the actual message of each
+                                journal entry with no meta data, not
+                                even a timestamp.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--catalog</option></term>
+                                <term><option>-x</option></term>
+
+                                <listitem><para>Augment log lines with
+                                explanation texts from the message
+                                catalog. This will add explanatory
+                                help texts to log messages in the
+                                output where this is available. These
+                                short help texts will explain the
+                                context of an error or log event,
+                                possible solutions, as well as
+                                pointers to support forums, developer
+                                documentation and any other relevant
+                                manuals. Note that help texts are not
+                                available for all messages, but only
+                                for selected ones. For more
+                                information on the message catalog
+                                please refer to the <ulink
+                                url="http://www.freedesktop.org/wiki/Software/systemd/catalog">Message
+                                Catalog Developer
+                                Documentation</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--quiet</option></term>
+                                <term><option>-q</option></term>
+
+                                <listitem><para>Suppresses any warning
+                                message regarding inaccessible system
+                                journals when run as normal
+                                user.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--merge</option></term>
+                                <term><option>-m</option></term>
+
+                                <listitem><para>Show entries
+                                interleaved from all available
+                                journals, including remote
+                                ones.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--this-boot</option></term>
+                                <term><option>-b</option></term>
+
+                                <listitem><para>Show data only from
+                                current boot. This will add a match
+                                for <literal>_BOOT_ID=</literal> for
+                                the current boot ID of the
+                                kernel.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--unit=</option></term>
+                                <term><option>-u</option></term>
+
+                                <listitem><para>Show data only of the
+                                specified unit. This will add a match
+                                for <literal>_SYSTEMD_UNIT=</literal>
+                                for the specified
+                                unit.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-p</option></term>
+                                <term><option>--priority=</option></term>
+
+                                <listitem><para>Filter output by
+                                message priorities or priority
+                                ranges. Takes either a single numeric
+                                or textual log level (i.e. between
+                                0/<literal>emerg</literal> and
+                                7/<literal>debug</literal>), or a
+                                range of numeric/text log levels in
+                                the form FROM..TO. The log levels are
+                                the usual syslog log levels as
+                                documented in
+                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                                i.e. <literal>emerg</literal> (0),
+                                <literal>alert</literal> (1),
+                                <literal>crit</literal> (2),
+                                <literal>err</literal> (3),
+                                <literal>warning</literal> (4),
+                                <literal>notice</literal> (5),
+                                <literal>info</literal> (6),
+                                <literal>debug</literal> (7). If a
+                                single log level is specified all
+                                messages with this log level or a
+                                lower (hence more important) log level
+                                are shown. If a range is specified all
+                                messages within the range are shown,
+                                including both the start and the end
+                                value of the range. This will add
+                                <literal>PRIORITY=</literal> matches
+                                for the specified
+                                priorities.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--cursor=</option></term>
+                                <term><option>-c</option></term>
+
+                                <listitem><para>Start showing entries
+                                from the location in the journal
+                                specified by the passed
+                                cursor.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--since=</option></term>
+                                <term><option>--until=</option></term>
+
+                                <listitem><para>Start showing entries
+                                on or newer than the specified date,
+                                or on or older than the specified
+                                date, respectively. Date specifications should be of
+                                the format "2012-10-30 18:17:16". If
+                                the time part is omitted, 00:00:00 is
+                                assumed. If only the seconds component
+                                is omitted, :00 is assumed. If the
+                                date component is omitted, the
+                                current day is assumed. Alternatively
+                                the strings
+                                <literal>yesterday</literal>,
+                                <literal>today</literal>,
+                                <literal>tomorrow</literal> are
+                                understood, which refer to 00:00:00 of
+                                the day before the current day, the
+                                current day, or the day after the
+                                current day, respectively. <literal>now</literal>
+                                refers to the current time. Finally,
+                                relative times may be specified,
+                                prefixed with <literal>-</literal> or
+                                <literal>+</literal>, referring to
+                                times before or after the current
+                                time, respectively.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--field=</option></term>
+                                <term><option>-F</option></term>
+
+                                <listitem><para>Print all possible
+                                data values the specified field can
+                                take in all entries of the
+                                journal.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--directory=</option></term>
+                                <term><option>-D</option></term>
+
+                                <listitem><para>Takes an absolute
+                                directory path as argument. If
+                                specified journalctl will operate on the
+                                specified journal directory instead of
+                                the default runtime and system journal
+                                paths.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--new-id128</option></term>
+
+                                <listitem><para>Instead of showing
+                                journal contents generate a new 128
+                                bit ID suitable for identifying
+                                messages. This is intended for usage
+                                by developers who need a new
+                                identifier for a new message they
+                                introduce and want to make
+                                recognizable. Will print the new ID in
+                                three different formats which can be
+                                copied into source code or
+                                similar.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--header</option></term>
+
+                                <listitem><para>Instead of showing
+                                journal contents show internal header
+                                information of the journal fields
+                                accessed.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--disk-usage</option></term>
+
+                                <listitem><para>Shows the current disk
+                                usage of all
+                                journal files.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--list-catalog</option></term>
+
+                                <listitem><para>List the contents of
+                                the message catalog, as table of
+                                message IDs plus their short
+                                description strings.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--update-catalog</option></term>
+
+                                <listitem><para>Update the message
+                                catalog index. This command needs to
+                                be executed each time new catalog
+                                files are installed, removed or
+                                updated to rebuild the binary catalog
+                                index.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--setup-keys</option></term>
+
+                                <listitem><para>Instead of showing
+                                journal contents generate a new key
+                                pair for Forward Secure Sealing
+                                (FSS). This will generate a sealing
+                                key and a verification key. The
+                                sealing key is stored in the journal
+                                data directory and shall remain on the
+                                host. The verification key should be
+                                stored externally.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--interval=</option></term>
+
+                                <listitem><para>Specifies the change
+                                interval for the sealing key, when
+                                generating an FSS key pair with
+                                <option>--setup-keys</option>. Shorter
+                                intervals increase CPU consumption but
+                                shorten the time range of
+                                undetectable journal
+                                alterations. Defaults to
+                                15min.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--verify</option></term>
+
+                                <listitem><para>Check the journal file
+                                for internal consistency. If the
+                                file has been generated with FSS
+                                enabled, and the FSS verification key
+                                has been specified with
+                                <option>--verify-key=</option>
+                                authenticity of the journal file is
+                                verified.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--verify-key=</option></term>
+
+                                <listitem><para>Specifies the FSS
+                                verification key to use for the
+                                <option>--verify</option>
+                                operation.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_PAGER</varname></term>
+                                <listitem><para>Pager to use when
+                                <option>--no-pager</option> is not given;
+                                overrides <varname>$PAGER</varname>.  Setting
+                                this to an empty string or the value
+                                <literal>cat</literal> is equivalent to passing
+                                <option>--no-pager</option>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <para>Without arguments all collected logs are shown
+                unfiltered:</para>
+
+                <programlisting>journalctl</programlisting>
+
+                <para>With one match specified all entries with a field matching the expression are shown:</para>
+
+                <programlisting>journalctl _SYSTEMD_UNIT=avahi-daemon.service</programlisting>
+
+                <para>If two different fields are matched only entries matching both expressions at the same time are shown:</para>
+
+                <programlisting>journalctl _SYSTEMD_UNIT=avahi-daemon.service _PID=28097</programlisting>
+
+                <para>If two matches refer to the same field all entries matching either expression are shown:</para>
+
+                <programlisting>journalctl _SYSTEMD_UNIT=avahi-daemon.service _SYSTEMD_UNIT=dbus.service</programlisting>
+
+                <para>If the separator "<literal>+</literal>" is used
+                two expressions may be combined in a logical OR. The
+                following will show all messages from the Avahi
+                service process with the PID 28097 plus all messages
+                from the D-Bus service (from any of its
+                processes):</para>
+
+                <programlisting>journalctl _SYSTEMD_UNIT=avahi-daemon.service _PID=28097 + _SYSTEMD_UNIT=dbus.service</programlisting>
+
+                <para>Show all logs generated by the D-Bus executable:</para>
+
+                <programlisting>journalctl /usr/bin/dbus-daemon</programlisting>
+
+                <para>Show all logs of the kernel device node <filename>/dev/sda</filename>:</para>
+
+                <programlisting>journalctl /dev/sda</programlisting>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
new file mode 100644 (file)
index 0000000..30523c5
--- /dev/null
@@ -0,0 +1,411 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="journald.conf">
+        <refentryinfo>
+                <title>journald.conf</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>journald.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>journald.conf</refname>
+                <refpurpose>Journal service configuration file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/systemd/journald.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>This files configures various parameters of the
+                systemd journal service
+                <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>All options are configured in the
+                <literal>[Journal]</literal> section:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>Storage=</varname></term>
+
+                                <listitem><para>Controls where to
+                                store journal data. One of
+                                <literal>volatile</literal>,
+                                <literal>persistent</literal>,
+                                <literal>auto</literal> and
+                                <literal>none</literal>. If
+                                <literal>volatile</literal> journal
+                                log data will be stored only in
+                                memory, i.e. below the
+                                <filename>/run/log/journal</filename>
+                                hierarchy (which is created if
+                                needed). If
+                                <literal>persistent</literal> data will
+                                be stored preferably on disk,
+                                i.e. below the
+                                <filename>/var/log/journal</filename>
+                                hierarchy (which is created if
+                                needed), with a fallback to
+                                <filename>/run/log/journal</filename>
+                                (which is created if needed), during
+                                early boot and if the disk is not
+                                writable. <literal>auto</literal> is
+                                similar to
+                                <literal>persistent</literal> but the
+                                directory
+                                <filename>/var/log/journal</filename>
+                                is not created if needed, so that its
+                                existence controls where log data
+                                goes. <literal>none</literal> turns
+                                off all storage, all log data received
+                                will be dropped. Forwarding to other
+                                targets, such as the console, the
+                                kernel log buffer or a syslog daemon
+                                will still work however.  Defaults to
+                                <literal>auto</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Compress=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                value. If enabled (the default) data
+                                objects that shall be stored in the
+                                journal and are larger than a certain
+                                threshold are compressed with the XZ
+                                compression algorithm before they are
+                                written to the file
+                                system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Seal=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                value. If enabled (the default) and a
+                                sealing key is available (as created
+                                by
+                                <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+                                <option>--setup-keys</option>
+                                command), forward secure sealing (FSS) for
+                                all persistent journal files is
+                                enabled.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SplitMode=</varname></term>
+
+                                <listitem><para>Controls whether to
+                                split up journal files per user. One
+                                of <literal>login</literal>,
+                                <literal>uid</literal> and
+                                <literal>none</literal>. If
+                                <literal>login</literal> each logged
+                                in user will get his own journal
+                                files, but systemd user IDs will log
+                                into the system journal. If
+                                <literal>uid</literal> any user ID
+                                will get his own journal files
+                                regardless whether it belongs to a
+                                system service or refers to a real
+                                logged in user. If
+                                <literal>none</literal> journal files
+                                are not split up per-user and all
+                                messages are stored in the single
+                                system journal. Note that splitting
+                                up journal files per-user is only
+                                available of journals are stored
+                                persistently. If journals are stored
+                                on volatile storage (see above) only a
+                                single journal file for all user IDs
+                                is kept. Defaults to
+                                <literal>login</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RateLimitInterval=</varname></term>
+                                <term><varname>RateLimitBurst=</varname></term>
+
+                                <listitem><para>Configures the rate
+                                limiting that is applied to all
+                                messages generated on the system. If
+                                in the time interval defined by
+                                <varname>RateLimitInterval=</varname>
+                                more messages than specified in
+                                <varname>RateLimitBurst=</varname> are
+                                logged by a service all further
+                                messages within the interval are
+                                dropped, until the interval is over. A
+                                message about the number of dropped
+                                messages is generated. This rate
+                                limiting is applied per-service, so
+                                that two services which log do not
+                                interfere with each others'
+                                limits. Defaults to 200 messages in
+                                10s. The time specification for
+                                <varname>RateLimitInterval=</varname>
+                                may be specified in the following
+                                units: <literal>s</literal>,
+                                <literal>min</literal>,
+                                <literal>h</literal>,
+                                <literal>ms</literal>,
+                                <literal>us</literal>. To turn off any
+                                kind of rate limiting, set either
+                                value to 0.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SystemMaxUse=</varname></term>
+                                <term><varname>SystemKeepFree=</varname></term>
+                                <term><varname>SystemMaxFileSize=</varname></term>
+                                <term><varname>RuntimeMaxUse=</varname></term>
+                                <term><varname>RuntimeKeepFree=</varname></term>
+                                <term><varname>RuntimeMaxFileSize=</varname></term>
+
+                                <listitem><para>Enforce size limits on
+                                the journal files stored. The options
+                                prefixed with
+                                <literal>System</literal> apply to the
+                                journal files when stored on a
+                                persistent file system, more
+                                specifically
+                                <filename>/var/log/journal</filename>. The
+                                options prefixed with
+                                <literal>Runtime</literal> apply to
+                                the journal files when stored on a
+                                volatile in-memory file system, more
+                                specifically
+                                <filename>/run/log/journal</filename>. The
+                                former is used only when
+                                <filename>/var</filename> is mounted,
+                                writable and the directory
+                                <filename>/var/log/journal</filename>
+                                exists. Otherwise only the latter
+                                applies. Note that this means that
+                                during early boot and if the
+                                administrator disabled persistent
+                                logging only the latter options apply,
+                                while the former apply if persistent
+                                logging is enabled and the system is
+                                fully booted
+                                up. <varname>SystemMaxUse=</varname>
+                                and <varname>RuntimeMaxUse=</varname>
+                                control how much disk space the
+                                journal may use up at
+                                maximum. Defaults to 10% of the size
+                                of the respective file
+                                system. <varname>SystemKeepFree=</varname>
+                                and
+                                <varname>RuntimeKeepFree=</varname>
+                                control how much disk space the
+                                journal shall always leave free for
+                                other uses if less than the disk space
+                                configured in
+                                <varname>SystemMaxUse=</varname> and
+                                <varname>RuntimeMaxUse=</varname> is
+                                available. Defaults to 5% of the size
+                                of the respective file
+                                system. <varname>SystemMaxFileSize=</varname>
+                                and
+                                <varname>RuntimeMaxFileSize=</varname>
+                                control how large individual journal
+                                files may grow at maximum. This
+                                influences the granularity in which
+                                disk space is made available through
+                                rotation, i.e. deletion of historic
+                                data. Defaults to one eighth of the
+                                values configured with
+                                <varname>SystemMaxUse=</varname> and
+                                <varname>RuntimeMaxUse=</varname>, so
+                                that usually seven rotated journal
+                                files are kept as history. Specify
+                                values in bytes or use K, M, G, T, P,
+                                E as units for the specified
+                                sizes. Note that size limits are
+                                enforced synchronously to journal
+                                files as they are extended, and need
+                                no explicit rotation step triggered by
+                                time.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>MaxFileSec=</varname></term>
+
+                                <listitem><para>The maximum time to
+                                store entries in a single journal
+                                file, before rotating to the next
+                                one. Normally time-based rotation
+                                should not be required as size-based
+                                rotation with options such as
+                                <varname>SystemMaxFileSize=</varname>
+                                should be sufficient to ensure that
+                                journal files don't grow without
+                                bounds. However, to ensure that not
+                                too much data is lost at once when old
+                                journal files are deleted it might
+                                make sense to change this value from
+                                the default of one month. Set to 0 to
+                                turn off this feature. This setting
+                                takes time values which may be
+                                suffixed with the units year, month,
+                                week, day, h, m to override the
+                                default time unit of
+                                seconds.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>MaxRetentionSec=</varname></term>
+
+                                <listitem><para>The maximum time to
+                                store journal entries. This
+                                controls whether journal files
+                                containing entries older then the
+                                specified time span are
+                                deleted. Normally time-based deletion
+                                of old journal files should not be
+                                required as size-based deletion with
+                                options such as
+                                <varname>SystemMaxUse=</varname>
+                                should be sufficient to ensure that
+                                journal files don't grow without
+                                bounds. However, to enforce data
+                                retention policies it might make sense
+                                to change this value from the
+                                default of 0 (which turns off this
+                                feature). This setting also takes
+                                time values which may be suffixed with
+                                the units year, month, week, day, h, m
+                                to override the default time unit of
+                                seconds. </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ForwardToSyslog=</varname></term>
+                                <term><varname>ForwardToKMsg=</varname></term>
+                                <term><varname>ForwardToConsole=</varname></term>
+
+                                <listitem><para>Control whether log
+                                messages received by the journal
+                                daemon shall be forwarded to a
+                                traditional syslog daemon, to the
+                                kernel log buffer (kmsg), or to the
+                                system console. These options take
+                                boolean arguments. If forwarding to
+                                syslog is enabled but no syslog daemon
+                                is running the respective option has
+                                no effect. By default only forwarding
+                                to syslog is enabled. These settings
+                                may be overridden at boot time with
+                                the kernel command line options
+                                <literal>systemd.journald.forward_to_syslog=</literal>,
+                                <literal>systemd.journald.forward_to_kmsg=</literal>
+                                and
+                                <literal>systemd.journald.forward_to_console=</literal>.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>MaxLevelStore=</varname></term>
+                                <term><varname>MaxLevelSyslog=</varname></term>
+                                <term><varname>MaxLevelKMsg=</varname></term>
+                                <term><varname>MaxLevelConsole=</varname></term>
+
+                                <listitem><para>Controls the maximum
+                                log level of messages that are stored
+                                on disk, forwarded to syslog, kmsg or
+                                the console (if that is enabled, see
+                                above). As argument, takes one of
+                                <literal>emerg</literal>,
+                                <literal>alert</literal>,
+                                <literal>crit</literal>,
+                                <literal>err</literal>,
+                                <literal>warning</literal>,
+                                <literal>notice</literal>,
+                                <literal>info</literal>,
+                                <literal>debug</literal> or integer
+                                values in the range of 0..7 (corresponding
+                                to the same levels). Messages equal or below
+                                the log level specified are
+                                stored/forwarded, messages above are
+                                dropped. Defaults to
+                                <literal>debug</literal> for
+                                <varname>MaxLevelStore=</varname> and
+                                <varname>MaxLevelSyslog=</varname>, to
+                                ensure that the all messages are
+                                written to disk and forwarded to
+                                syslog. Defaults to
+                                <literal>notice</literal> for
+                                <varname>MaxLevelKMsg=</varname> and
+                                <literal>info</literal> for
+                                <varname>MaxLevelConsole=</varname>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TTYPath=</varname></term>
+
+                                <listitem><para>Change the console TTY
+                                to use if
+                                <varname>ForwardToConsole=yes</varname>
+                                is used. Defaults to
+                                <filename>/dev/console</filename>.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
new file mode 100644 (file)
index 0000000..154d399
--- /dev/null
@@ -0,0 +1,295 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="kernel-command-line">
+
+        <refentryinfo>
+                <title>kernel-command-line</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>kernel-command-line</refentrytitle>
+                <manvolnum>7</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>kernel-command-line</refname>
+                <refpurpose>Kernel command line parameters</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/proc/cmdline</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The kernel, the initial RAM disk (initrd) and
+                basic userspace functionality may be configured at boot via
+                kernel command line arguments.</para>
+
+                <para>For command line parameters understood by the
+                kernel please see <ulink
+                url="https://www.kernel.org/doc/Documentation/kernel-parameters.txt"><filename>kernel-parameters.txt</filename></ulink>
+                and
+                <citerefentry><refentrytitle>bootparam</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+
+                <para>For command line parameters understood by the
+                initial RAM disk, please see
+                <citerefentry><refentrytitle>dracut.cmdline</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                or the documentation of the specific initrd
+                implementation of your installation.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Core OS Command Line Arguments</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>systemd.unit=</varname></term>
+                                <term><varname>rd.systemd.unit=</varname></term>
+                                <term><varname>systemd.dump_core=</varname></term>
+                                <term><varname>systemd.crash_shell=</varname></term>
+                                <term><varname>systemd.crash_chvt=</varname></term>
+                                <term><varname>systemd.confirm_spawn=</varname></term>
+                                <term><varname>systemd.show_status=</varname></term>
+                                <term><varname>systemd.log_target=</varname></term>
+                                <term><varname>systemd.log_level=</varname></term>
+                                <term><varname>systemd.log_color=</varname></term>
+                                <term><varname>systemd.log_location=</varname></term>
+                                <term><varname>systemd.default_standard_output=</varname></term>
+                                <term><varname>systemd.default_standard_error=</varname></term>
+                                <term><varname>systemd.setenv=</varname></term>
+                                <listitem>
+                                        <para>Parameters understood by
+                                        the system and service manager
+                                        to control system behavior. For details see
+                                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>quiet</varname></term>
+                                <listitem>
+                                        <para>Parameter understood by
+                                        both the kernel and the system
+                                        and service manager to control
+                                        console log verbosity. For
+                                        details see
+                                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>emergency</varname></term>
+                                <term><varname>single</varname></term>
+                                <term><varname>s</varname></term>
+                                <term><varname>S</varname></term>
+                                <term><varname>1</varname></term>
+                                <term><varname>2</varname></term>
+                                <term><varname>3</varname></term>
+                                <term><varname>4</varname></term>
+                                <term><varname>5</varname></term>
+                                <listitem>
+                                        <para>Parameters understood by
+                                        the system and service
+                                        manager, as compatibility
+                                        options. For details see
+                                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>locale.LANG=</varname></term>
+                                <term><varname>locale.LANGUAGE=</varname></term>
+                                <term><varname>locale.LC_CTYPE=</varname></term>
+                                <term><varname>locale.LC_NUMERIC=</varname></term>
+                                <term><varname>locale.LC_TIME=</varname></term>
+                                <term><varname>locale.LC_COLLATE=</varname></term>
+                                <term><varname>locale.LC_MONETARY=</varname></term>
+                                <term><varname>locale.LC_MESSAGES=</varname></term>
+                                <term><varname>locale.LC_PAPER=</varname></term>
+                                <term><varname>locale.LC_NAME=</varname></term>
+                                <term><varname>locale.LC_ADDRESS=</varname></term>
+                                <term><varname>locale.LC_TELEPHONE=</varname></term>
+                                <term><varname>locale.LC_MEASUREMENT=</varname></term>
+                                <term><varname>locale.LC_IDENTIFICATION=</varname></term>
+                                <listitem>
+                                        <para>Parameters understood by
+                                        the system and service manager
+                                        to control locale and language
+                                        settings. For details see
+                                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>fsck.mode=</varname></term>
+
+                                <listitem>
+                                        <para>Parameter understood by
+                                        the file system checker
+                                        services. For details see
+                                        <citerefentry><refentrytitle>systemd-fsck@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>quotacheck.mode=</varname></term>
+
+                                <listitem>
+                                        <para>Parameter understood by
+                                        the file quota checker
+                                        service. For details see
+                                        <citerefentry><refentrytitle>systemd-quotacheck.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.journald.forward_to_syslog=</varname></term>
+                                <term><varname>systemd.journald.forward_to_kmsg=</varname></term>
+                                <term><varname>systemd.journald.forward_to_console=</varname></term>
+
+                                <listitem>
+                                        <para>Parameters understood by
+                                        the journal service. For
+                                        details see
+                                        <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>vconsole.keymap=</varname></term>
+                                <term><varname>vconsole.keymap.toggle=</varname></term>
+                                <term><varname>vconsole.font=</varname></term>
+                                <term><varname>vconsole.font.map=</varname></term>
+                                <term><varname>vconsole.font.unimap=</varname></term>
+
+                                <listitem>
+                                        <para>Parameters understood by
+                                        the virtual console setup logic. For
+                                        details see
+                                        <citerefentry><refentrytitle>systemd-vconsole-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>udev.log-priority=</varname></term>
+                                <term><varname>rd.udev.log-priority=</varname></term>
+                                <term><varname>udev.children-max=</varname></term>
+                                <term><varname>rd.udev.children-max=</varname></term>
+                                <term><varname>udev.exec-delay=</varname></term>
+                                <term><varname>rd.udev.exec-delay=</varname></term>
+
+                                <listitem>
+                                        <para>Parameters understood by
+                                        the device event managing daemon. For
+                                        details see
+                                        <citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>plymouth.enable=</varname></term>
+
+                                <listitem>
+                                        <para>May be used to disable
+                                        the Plymouth boot splash. For
+                                        details see
+                                        <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>luks=</varname></term>
+                                <term><varname>rd.luks=</varname></term>
+                                <term><varname>luks.crypttab=</varname></term>
+                                <term><varname>rd.luks.crypttab=</varname></term>
+                                <term><varname>luks.uuid=</varname></term>
+                                <term><varname>rd.luks.uuid=</varname></term>
+
+                                <listitem>
+                                        <para>Configures the LUKS
+                                        full-disk encryption logic at
+                                        boot. For details see
+                                        <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>fstab=</varname></term>
+                                <term><varname>rd.fstab=</varname></term>
+
+                                <listitem>
+                                        <para>Configures the
+                                        <filename>/etc/fstab</filename>
+                                        logic at boot. For details see
+                                        <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>modules-load=</varname></term>
+                                <term><varname>rd.modules-load=</varname></term>
+
+                                <listitem>
+                                        <para>Load a specific kernel
+                                        module early at boot. For
+                                        details see
+                                        <citerefentry><refentrytitle>systemd-modules-load.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>bootparam</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>dracut.cmdline</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-fsck@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-quotacheck.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-vconsole-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-modules-load.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/locale.conf.xml b/man/locale.conf.xml
new file mode 100644 (file)
index 0000000..06c0af0
--- /dev/null
@@ -0,0 +1,149 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="locale.conf">
+        <refentryinfo>
+                <title>locale.conf</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>locale.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>locale.conf</refname>
+                <refpurpose>Configuration file for locale settings</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/locale.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The <filename>/etc/locale.conf</filename> file
+                configures system-wide locale settings. It is read at
+                early-boot by
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+
+                <para>The basic file format of
+                <filename>locale.conf</filename> is a
+                newline-separated list of environment-like
+                shell-compatible variable assignments. It is possible
+                to source the configuration from shell scripts,
+                however, beyond mere variable assignments no shell
+                features are supported, allowing applications to read
+                the file without implementing a shell compatible
+                execution engine.</para>
+
+                <para>Note that the kernel command line options
+                <varname>locale.LANG=</varname>,
+                <varname>locale.LANGUAGE=</varname>,
+                <varname>locale.LC_CTYPE=</varname>,
+                <varname>locale.LC_NUMERIC=</varname>,
+                <varname>locale.LC_TIME=</varname>,
+                <varname>locale.LC_COLLATE=</varname>,
+                <varname>locale.LC_MONETARY=</varname>,
+                <varname>locale.LC_MESSAGES=</varname>,
+                <varname>locale.LC_PAPER=</varname>,
+                <varname>locale.LC_NAME=</varname>,
+                <varname>locale.LC_ADDRESS=</varname>,
+                <varname>locale.LC_TELEPHONE=</varname>,
+                <varname>locale.LC_MEASUREMENT=</varname>,
+                <varname>locale.LC_IDENTIFICATION=</varname> may be
+                used to override the locale settings at boot.</para>
+
+                <para>The locale settings configured in
+                <filename>/etc/locale.conf</filename> are system-wide
+                and are inherited by every service or user, unless
+                overridden or unset by individual programs or
+                individual users.</para>
+
+                <para>Depending on the operating system other
+                configuration files might be checked for locale
+                configuration as well, however only as
+                fallback.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following locale settings may be set using
+                <filename>/etc/locale.conf</filename>:
+                <varname>LANG=</varname>,
+                <varname>LANGUAGE=</varname>,
+                <varname>LC_CTYPE=</varname>,
+                <varname>LC_NUMERIC=</varname>,
+                <varname>LC_TIME=</varname>,
+                <varname>LC_COLLATE=</varname>,
+                <varname>LC_MONETARY=</varname>,
+                <varname>LC_MESSAGES=</varname>,
+                <varname>LC_PAPER=</varname>,
+                <varname>LC_NAME=</varname>,
+                <varname>LC_ADDRESS=</varname>,
+                <varname>LC_TELEPHONE=</varname>,
+                <varname>LC_MEASUREMENT=</varname>,
+                <varname>LC_IDENTIFICATION=</varname>. Note that
+                <varname>LC_ALL</varname> may not be configured in
+                this file. For details about the meaning and semantics
+                of these settings, refer to
+                <citerefentry><refentrytitle>locale</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+
+                <example>
+                        <title>German locale with English messages</title>
+
+                        <para><filename>/etc/locale.conf:</filename></para>
+
+                        <programlisting>LANG=de_DE.UTF-8
+LC_MESSAGES=C</programlisting>
+                </example>
+
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>locale</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/localectl.xml b/man/localectl.xml
new file mode 100644 (file)
index 0000000..33508cf
--- /dev/null
@@ -0,0 +1,259 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="localectl">
+
+        <refentryinfo>
+                <title>localectl</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>localectl</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>localectl</refname>
+                <refpurpose>Control the system locale and keyboard layout settings</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>localectl <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>localectl</command> may be used to
+                query and change the system locale and keyboard layout
+                settings.</para>
+
+                <para>The system locale controls the language settings
+                of system services and of the UI before the user logs
+                in, such as the display manager, as well as the
+                default for users after login.</para>
+
+                <para>The keyboard settings control the keyboard
+                layout used on the text console and of the graphical
+                UI before the user logs in, such as the display
+                manager, as well as the default for users after
+                login.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+                                <listitem><para>Do not pipe output into a
+                                pager.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-ask-password</option></term>
+
+                                <listitem><para>Don't query the user
+                                for authentication for privileged
+                                operations.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-H</option></term>
+                                <term><option>--host</option></term>
+
+                                <listitem><para>Execute the operation
+                                remotely. Specify a hostname, or
+                                username and hostname separated by @,
+                                to connect to. This will use SSH to
+                                talk to a remote
+                                system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-convert</option></term>
+
+                                <listitem><para>If
+                                <command>set-keymap</command> or
+                                <command>set-x11-keymap</command> is
+                                invoked and this option is passed then
+                                the keymap will not be converted from
+                                the console to X11, or X11 to console,
+                                respectively.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>The following commands are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><command>status</command></term>
+
+                                <listitem><para>Show current settings
+                                of the system locale and keyboard
+                                mapping.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-locale LOCALE...</command></term>
+
+                                <listitem><para>Set the system
+                                locale. This takes one or more
+                                assignments such as "LANG=de_DE.utf8",
+                                "LC_MESSAGES=en_GB.utf8", and so
+                                on. See
+                                <citerefentry><refentrytitle>locale</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details on the available settings
+                                and their meanings. Use
+                                <command>list-locales</command> for a
+                                list of available locales (see below).
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>list-locales</command></term>
+
+                                <listitem><para>List available locales
+                                useful for configuration with
+                                <command>set-locale</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-keymap MAP [TOGGLEMAP]</command></term>
+
+                                <listitem><para>Set the system
+                                keyboard mapping for the console. This
+                                takes a keyboard mapping name (such as
+                                "de" or "us"), and possibly a second
+                                one to define a toggle keyboard
+                                mapping. Unless
+                                <option>--no-convert</option> is
+                                passed the selected setting is also
+                                applied to the default keyboard
+                                mapping of X11, after converting it to
+                                the closest matching X11 keyboard
+                                mapping. Use
+                                <command>list-locales</command> for a
+                                list of available keyboard mappings
+                                (see below).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>list-keymaps</command></term>
+
+                                <listitem><para>List available
+                                keyboard mappings for the console,
+                                useful for configuration with
+                                <command>set-keyboard</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-x11-keymap LAYOUT [MODEL] [VARIANT] [OPTIONS]</command></term>
+
+                                <listitem><para>Set the system default
+                                keyboard mapping for X11. This takes a
+                                keyboard mapping name (such as "de" or
+                                "us"), and possibly a model, variant
+                                and options, see
+                                <citerefentry><refentrytitle>kbd</refentrytitle><manvolnum>4</manvolnum></citerefentry>
+                                for details. Unless
+                                <option>--no-convert</option> is
+                                passed the selected setting is also
+                                applied to the system console keyboard
+                                mapping, after converting it to the
+                                closest matching console keyboard
+                                mapping.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_PAGER</varname></term>
+                                <listitem><para>Pager to use when
+                                <option>--no-pager</option> is not given;
+                                overrides <varname>$PAGER</varname>.  Setting
+                                this to an empty string or the value
+                                <literal>cat</literal> is equivalent to passing
+                                <option>--no-pager</option>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>locale</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>kbd</refentrytitle><manvolnum>4</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/localtime.xml b/man/localtime.xml
new file mode 100644 (file)
index 0000000..88c84a3
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright 2012 Shawn Landden
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="localtime">
+        <refentryinfo>
+                <title>/etc/localtime</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Shawn</firstname>
+                                <surname>Landden</surname>
+                                <email>shawnlandden@gmail.com</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>localtime</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>localtime</refname>
+                <refpurpose>Local time zone configuration file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/localtime</filename> -> <filename>../usr/share/zoneinfo/…</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The <filename>/etc/localtime</filename> file
+                configures the system-wide time zone of the local
+                system that is used by applications for presentation
+                to the user. It should be an absolute or relative
+                symbolic link pointing to
+                <filename>/usr/share/zoneinfo/</filename>, followed by
+                a time zone identifier such as
+                <literal>Europe/Berlin</literal> or
+                <literal>Etc/UTC</literal>.  The resulting link should
+                lead to the corresponding binary
+                <citerefentry><refentrytitle>tzfile</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                time zone data for the configured time zone.</para>
+
+                <para>As the time zone identifier is extracted from
+                the symlink target name of
+                <filename>/etc/localtime</filename> this file may not
+                be a normal file or hardlink.</para>
+
+                <para>The time zone may be overridden for individual
+                programs by using the TZ environment variable. See
+                <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+
+                <para>You may use
+                <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to change the settings of this file from the command
+                line.</para>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>tzset</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-timedated.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/loginctl.xml b/man/loginctl.xml
new file mode 100644 (file)
index 0000000..5dbc1f6
--- /dev/null
@@ -0,0 +1,474 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="loginctl">
+
+        <refentryinfo>
+                <title>loginctl</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>loginctl</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>loginctl</refname>
+                <refpurpose>Control the systemd login manager</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>loginctl <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg> <arg choice="opt" rep="repeat">NAME</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>loginctl</command> may be used to
+                introspect and control the state of the
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                login manager <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--property=</option></term>
+                                <term><option>-p</option></term>
+
+                                <listitem><para>When showing
+                                session/user properties, limit
+                                display to certain properties as
+                                specified as argument. If not
+                                specified all set properties are
+                                shown. The argument should be a
+                                property name, such as
+                                <literal>Sessions</literal>. If
+                                specified more than once all
+                                properties with the specified names
+                                are shown.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--all</option></term>
+                                <term><option>-a</option></term>
+
+                                <listitem><para>When showing
+                                unit/job/manager properties, show all
+                                properties regardless whether they are
+                                set or not.</para></listitem>
+                        </varlistentry>
+
+
+                        <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+                                <listitem><para>Do not pipe output into a
+                                pager.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-ask-password</option></term>
+
+                                <listitem><para>Don't query the user
+                                for authentication for privileged
+                                operations.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--kill-who=</option></term>
+
+                                <listitem><para>When used with
+                                <command>kill-session</command>,
+                                choose which processes to kill. Must
+                                be one of <option>leader</option>, or
+                                <option>all</option> to select whether
+                                to kill only the leader process of the
+                                session or all processes of the
+                                session. If omitted defaults to
+                                <option>all</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--signal=</option></term>
+                                <term><option>-s</option></term>
+
+                                <listitem><para>When used with
+                                <command>kill-session</command> or
+                                <command>kill-user</command>, choose
+                                which signal to send to selected
+                                processes. Must be one of the well
+                                known signal specifiers such as
+                                SIGTERM, SIGINT or SIGSTOP. If omitted
+                                defaults to
+                                <option>SIGTERM</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-H</option></term>
+                                <term><option>--host</option></term>
+
+                                <listitem><para>Execute operation
+                                remotely. Specify a hostname, or
+                                username and hostname separated by @,
+                                to connect to. This will use SSH to
+                                talk to the remote login manager
+                                instance.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-P</option></term>
+                                <term><option>--privileged</option></term>
+
+                                <listitem><para>Acquire privileges via
+                                PolicyKit before executing the
+                                operation.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>The following commands are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><command>list-sessions</command></term>
+
+                                <listitem><para>List current sessions.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>session-status [ID...]</command></term>
+
+                                <listitem><para>Show terse runtime
+                                status information about one or more
+                                sessions. This function is intended to
+                                generate human-readable output. If you
+                                are looking for computer-parsable
+                                output, use
+                                <command>show-session</command>
+                                instead.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>show-session [ID...]</command></term>
+
+                                <listitem><para>Show properties of one
+                                or more sessions or the manager
+                                itself. If no argument is specified
+                                properties of the manager will be
+                                shown. If a session ID is specified
+                                properties of the session is shown. By
+                                default, empty properties are
+                                suppressed. Use <option>--all</option>
+                                to show those too. To select specific
+                                properties to show use
+                                <option>--property=</option>. This
+                                command is intended to be used
+                                whenever computer-parsable output is
+                                required. Use
+                                <command>session-status</command> if
+                                you are looking for formatted
+                                human-readable
+                                output.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>activate [ID...]</command></term>
+
+                                <listitem><para>Activate one or more
+                                sessions. This brings one or more
+                                sessions into the foreground, if
+                                another session is currently in the
+                                foreground on the respective
+                                seat.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>lock-session [ID...]</command></term>
+                                <term><command>unlock-session [ID...]</command></term>
+
+                                <listitem><para>Activates/deactivates
+                                the screen lock on one or more
+                                sessions, if the session supports it.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>lock-sessions</command></term>
+
+                                <listitem><para>Activate the screen
+                                lock on all current sessions
+                                supporting it.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>terminate-session [ID...]</command></term>
+
+                                <listitem><para>Terminates a
+                                session. This kills all processes of
+                                the session and deallocates all
+                                resources attached to the
+                                session.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>kill-session [ID...]</command></term>
+
+                                <listitem><para>Send a signal to one
+                                or more processes of the session. Use
+                                <option>--kill-who=</option> to select
+                                which process to kill. Use
+                                <option>--signal=</option> to select
+                                the signal to send.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>list-users</command></term>
+
+                                <listitem><para>List currently logged
+                                in users.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>user-status [USER...]</command></term>
+
+                                <listitem><para>Show terse runtime
+                                status information about one or more
+                                logged in users. This function is
+                                intended to generate human-readable
+                                output. If you are looking for
+                                computer-parsable output, use
+                                <command>show-user</command>
+                                instead. Users may be specified by
+                                their usernames or numeric user
+                                IDs.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>show-user [USER...]</command></term>
+
+                                <listitem><para>Show properties of one
+                                or more users or the manager
+                                itself. If no argument is specified
+                                properties of the manager will be
+                                shown. If a user is specified
+                                properties of the user is shown. By
+                                default, empty properties are
+                                suppressed. Use <option>--all</option>
+                                to show those too. To select specific
+                                properties to show use
+                                <option>--property=</option>. This
+                                command is intended to be used
+                                whenever computer-parsable output is
+                                required. Use
+                                <command>user-status</command> if
+                                you are looking for formatted
+                                human-readable
+                                output.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>enable-linger [USER...]</command></term>
+                                <term><command>disable-linger [USER...]</command></term>
+
+                                <listitem><para>Enable/disable user
+                                lingering for one or more users. If
+                                enabled for a specific user a user
+                                manager is spawned for him/her at
+                                boot, and kept around after
+                                logouts. This allows users who aren't
+                                logged in to run long-running
+                                services.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>terminate-user [USER...]</command></term>
+
+                                <listitem><para>Terminates all
+                                sessions of a user. This kills all
+                                processes of all sessions of the user
+                                and deallocates all runtime resources
+                                attached to the
+                                user.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>kill-user [USER...]</command></term>
+
+                                <listitem><para>Send a signal to all
+                                processes of a user. Use
+                                <option>--signal=</option> to select
+                                the signal to send.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>list-seats</command></term>
+
+                                <listitem><para>List currently
+                                available seats on the local
+                                system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>seat-status [NAME...]</command></term>
+
+                                <listitem><para>Show terse runtime
+                                status information about one or more
+                                seats. This function is
+                                intended to generate human-readable
+                                output. If you are looking for
+                                computer-parsable output, use
+                                <command>show-seat</command>
+                                instead.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>show-seat [NAME...]</command></term>
+
+                                <listitem><para>Show properties of one
+                                or more seats or the manager
+                                itself. If no argument is specified
+                                properties of the manager will be
+                                shown. If a seat is specified
+                                properties of the seat are shown. By
+                                default, empty properties are
+                                suppressed. Use <option>--all</option>
+                                to show those too. To select specific
+                                properties to show use
+                                <option>--property=</option>. This
+                                command is intended to be used
+                                whenever computer-parsable output is
+                                required. Use
+                                <command>seat-status</command> if you
+                                are looking for formatted
+                                human-readable
+                                output.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>attach [NAME] [DEVICE...]</command></term>
+
+                                <listitem><para>Persistently attach
+                                one or more devices to a seat. The
+                                devices should be specified via device
+                                paths in the <filename>/sys</filename>
+                                file system. To create a new seat
+                                attach at least one graphics card to a
+                                previously unused seat name. Seat
+                                names may consist only of a-z, A-Z,
+                                0-9, "-" and "_" and must be prefixed
+                                with "seat". To drop assignment of a
+                                device to a specific seat just
+                                reassign it to a different seat, or
+                                use
+                                <command>flush-devices</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>flush-devices</command></term>
+
+                                <listitem><para>Removes all device
+                                assignments previously created with
+                                <command>attach</command>. After this
+                                call only automatically generated
+                                seats will remain and all seat
+                                hardware is assigned to
+                                them.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>terminate-seat [NAME...]</command></term>
+
+                                <listitem><para>Terminates all
+                                sessions on a seat. This kills all
+                                processes of all sessions on a seat and
+                                deallocates all runtime resources
+                                attached to them.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_PAGER</varname></term>
+                                <listitem><para>Pager to use when
+                                <option>--no-pager</option> is not given;
+                                overrides <varname>$PAGER</varname>.  Setting
+                                this to an empty string or the value
+                                <literal>cat</literal> is equivalent to passing
+                                <option>--no-pager</option>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
new file mode 100644 (file)
index 0000000..df15d51
--- /dev/null
@@ -0,0 +1,298 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="logind.conf">
+        <refentryinfo>
+                <title>logind.conf</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>logind.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>logind.conf</refname>
+                <refpurpose>Login manager configuration file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/systemd/logind.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>This file configures various parameters of the systemd login manager <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>All options are configured in the
+                <literal>[Login]</literal> section:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>NAutoVTs=</varname></term>
+
+                                <listitem><para>Takes a positive
+                                integer. Configures how many virtual
+                                terminals (VTs) to allocate by default
+                                that -- when switched to and
+                                previously unused --
+                                <literal>autovt</literal> services are
+                                automatically spawned on. These
+                                services are instantiated from the
+                                template unit
+                                <filename>autovt@.service</filename>
+                                for the respective VT TTY name,
+                                e.g. <filename>autovt@tty4.service</filename>. By
+                                default
+                                <filename>autovt@.service</filename>
+                                is linked to
+                                <filename>getty@.service</filename>,
+                                i.e. login prompts are started
+                                dynamically as the user switches to
+                                unused virtual terminals. Hence, this
+                                parameter controls how many login
+                                <literal>gettys</literal> are
+                                available on the VTs. If a VT is
+                                already used by some other subsystem
+                                (for example a graphical login) this
+                                kind of activation will not be
+                                attempted. Note that the VT configured
+                                in <varname>ReserveVT=</varname> is
+                                always subject to this kind of
+                                activation, even if it is not one of
+                                VTs configured with the
+                                <varname>NAutoVTs=</varname>
+                                directive. Defaults to 6. When set to
+                                0, automatic spawning of
+                                <literal>autovt</literal> services is
+                                disabled. </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ReserveVT=</varname></term>
+
+                                <listitem><para>Takes a positive
+                                integer. Configures the number of one
+                                virtual terminal that shall
+                                unconditionally be reserved for
+                                <filename>autovt@.service</filename>
+                                activation (see above). The VT
+                                selected with this option will be
+                                marked busy unconditionally so that no
+                                other subsystem will allocate it. This
+                                functionality is useful to ensure that
+                                regardless how many VTs are allocated
+                                by other subsystems one login
+                                <literal>getty</literal> is always
+                                available. Defaults to 6 (with other
+                                words: there'll always be a
+                                <literal>getty</literal> available on
+                                Alt-F6.). When set to 0, VT
+                                reservation is
+                                disabled.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>KillUserProcesses=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. Configures whether the
+                                processes of a user should be killed
+                                when she or he completely logs out (i.e. after
+                                her/his last session ended). Defaults to
+                                <literal>no</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>KillOnlyUsers=</varname></term>
+                                <term><varname>KillExcludeUsers=</varname></term>
+
+                                <listitem><para>These settings take
+                                space separated lists of user names
+                                that influence the effect of
+                                <varname>KillUserProcesses=</varname>. If
+                                not empty only processes of users
+                                listed in
+                                <varname>KillOnlyUsers</varname> will
+                                be killed when they log out
+                                entirely. Processes of users listed in
+                                <varname>KillExcludeUsers=</varname>
+                                are excluded from being
+                                killed. <varname>KillExcludeUsers=</varname>
+                                defaults to <literal>root</literal>
+                                and takes precedence over
+                                <varname>KillOnlyUsers=</varname>
+                                which defaults to the empty list.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Controllers=</varname></term>
+                                <term><varname>ResetControllers=</varname></term>
+
+                                <listitem><para>These settings control
+                                the default control group hierarchies
+                                users logging in are added to. When
+                                logging in users will get private
+                                control groups in all hierarchies
+                                listed in
+                                <varname>Controllers=</varname> and be
+                                reset to the root control group in all
+                                hierarchies listed in
+                                <varname>ResetControllers=</varname>. <varname>Controllers=</varname>
+                                defaults to the empty list,
+                                <varname>ResetControllers=</varname>
+                                defaults to
+                                <literal>cpu</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>InhibitDelayMaxSec=</varname></term>
+
+                                <listitem><para>Specifies the maximum
+                                time a system shutdown or sleep
+                                request is delayed due to an inhibitor
+                                lock of type <literal>delay</literal>
+                                being active -- before it is ignored
+                                and the operation executed
+                                anyway. Defaults to
+                                5s.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>HandlePowerKey=</varname></term>
+                                <term><varname>HandleSuspendKey=</varname></term>
+                                <term><varname>HandleHibernateKey=</varname></term>
+                                <term><varname>HandleLidSwitch=</varname></term>
+
+                                <listitem><para>Controls whether
+                                logind shall handle the system power
+                                and sleep keys and the lid switch to
+                                trigger actions such as system
+                                power-off or suspend. Can be one of
+                                <literal>ignore</literal>,
+                                <literal>poweroff</literal>,
+                                <literal>reboot</literal>,
+                                <literal>halt</literal>,
+                                <literal>kexec</literal>,
+                                <literal>suspend</literal>,
+                                <literal>hibernate</literal>,
+                                <literal>hybrid-sleep</literal> and
+                                <literal>lock</literal>. If
+                                <literal>ignore</literal> logind will
+                                never handle these keys. If
+                                <literal>lock</literal> all running
+                                sessions will be screen
+                                locked. Otherwise the specified action
+                                will be taken in the respective
+                                event. Only input devices with the
+                                <literal>power-switch</literal> udev
+                                tag will be watched for key/lid switch
+                                events. <varname>HandlePowerKey=</varname>
+                                defaults to
+                                <literal>poweroff</literal>.
+                                <varname>HandleSuspendKey=</varname>
+                                and
+                                <varname>HandleLidSwitch=</varname>
+                                default to <literal>suspend</literal>.
+                                <varname>HandleHibernateKey=</varname>
+                                defaults to
+                                <literal>hibernate</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PowerKeyIgnoreInhibited=</varname></term>
+                                <term><varname>SuspendKeyIgnoreInhibited=</varname></term>
+                                <term><varname>HibernateKeyIgnoreInhibited=</varname></term>
+                                <term><varname>LidSwitchIgnoreInhibited=</varname></term>
+
+                                <listitem><para>Controls whether
+                                actions triggered by the power and
+                                sleep keys and the lid switch are
+                                subject to inhibitor locks. These
+                                settings take boolean arguments. If
+                                <literal>off</literal> the inhibitor
+                                locks taken by applications in order
+                                to block the requested operation are
+                                respected, if <literal>on</literal>
+                                the requested operation is executed in
+                                any
+                                case. <varname>PowerKeyIgnoreInhibited=</varname>,
+                                <varname>SuspendKeyIgnoreInhibited=</varname>
+                                and
+                                <varname>HibernateKeyIgnoreInhibited=</varname>
+                                defaults to <literal>off</literal>,
+                                <varname>LidSwitchIgnoreInhibited=</varname>
+                                defaults to
+                                <literal>yes</literal>. This means
+                                that the lid switch does not respect
+                                suspend blockers by default, but the
+                                power and sleep keys do.
+                                </para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+                <para>Note that setting
+                <varname>KillUserProcesses=1</varname> will break tools
+                like
+                <citerefentry><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+
+                <para>Note that <varname>KillUserProcesses=1</varname>
+                is a weaker version of
+                <varname>kill-session-processes=1</varname> which may
+                be configured per-service for
+                <citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>. The
+                latter kills processes of a session as soon as it
+                ends, the former kills processes as soon as the last
+                session of the user ends.</para>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/machine-id.xml b/man/machine-id.xml
new file mode 100644 (file)
index 0000000..7d424b7
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="machine-id">
+        <refentryinfo>
+                <title>/etc/machine-id</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>machine-id</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>machine-id</refname>
+                <refpurpose>Local machine ID configuration file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/machine-id</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The <filename>/etc/machine-id</filename> file
+                contains the unique machine id of the local system
+                that is set during installation. The machine ID is a
+                single newline-terminated, hexadecimal, lowercase 32
+                character machine ID string. (When decoded from
+                hexadecimal this corresponds with a 16 byte/128 bit
+                string.)</para>
+
+                <para>The machine ID is usually generated from a
+                random source during system installation and stays
+                constant for all subsequent boots. Optionally, for
+                stateless systems it is generated during runtime at
+                boot if it is found to be empty.</para>
+
+                <para>The machine ID does not change based on user
+                configuration, or when hardware is replaced.</para>
+
+                <para>This machine ID adheres to the same format and
+                logic as the D-Bus machine ID.</para>
+
+                <para>Programs may use this ID to identify the host
+                with a globally unique ID in the network, that does
+                not change even if the local network configuration
+                changes. Due to this and its greater length it is
+                a more useful replacement for the
+                <citerefentry><refentrytitle>gethostid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call POSIX specifies.</para>
+
+                <para>The
+                <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                tool may be used by installer tools to initialize the
+                machine ID at install time.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Relation to OSF UUIDs</title>
+
+                <para>Note that the machine ID historically is not an
+                OSF UUID as defined by <ulink
+                url="http://tools.ietf.org/html/rfc4122">RFC
+                4122</ulink>, nor a Microsoft GUID. Starting with
+                systemd v30 newly generated machine IDs however do
+                qualify as v4 UUIDs.</para>
+
+                <para>In order to maintain compatibility with existing
+                installations, an application requiring a UUID should
+                decode the machine ID, and then apply the following
+                operations to turn it into a valid OSF v4 UUID. With
+                <literal>id</literal> being an unsigned character
+                array:</para>
+
+                <programlisting>/* Set UUID version to 4 --- truly random generation */
+id[6] = (id[6] &amp; 0x0F) | 0x40;
+/* Set the UUID variant to DCE */
+id[8] = (id[8] &amp; 0x3F) | 0x80;</programlisting>
+
+                <para>(This code is inspired by
+                <literal>generate_random_uuid()</literal> of
+                <filename>drivers/char/random.c</filename> from the
+                kernel sources.)</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>History</title>
+
+                <para>The simple configuration file format of
+                <filename>/etc/machine-id</filename> originates in the
+                <filename>/var/lib/dbus/machine-id</filename> file
+                introduced by D-Bus. In fact this latter file might be a
+                symlink to
+                <varname>/etc/machine-id</varname>.</para>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>gethostid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/machine-info.xml b/man/machine-info.xml
new file mode 100644 (file)
index 0000000..1c3a21c
--- /dev/null
@@ -0,0 +1,183 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="machine-info">
+        <refentryinfo>
+                <title>machine-info</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>machine-info</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>machine-info</refname>
+                <refpurpose>Local machine information file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/machine-info</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The <filename>/etc/machine-info</filename> file
+                contains machine meta data.</para>
+
+                <para>The basic file format of
+                <filename>machine-info</filename> is a
+                newline-separated list of environment-like
+                shell-compatible variable assignments. It is possible
+                to source the configuration from shell scripts,
+                however, beyond mere variable assignments no shell
+                features are supported, allowing applications to read
+                the file without implementing a shell compatible
+                execution engine.</para>
+
+                <para><filename>/etc/machine-info</filename> contains
+                meta data about the machine that is set by the user or
+                administrator.</para>
+
+                <para>Depending on the operating system other
+                configuration files might be checked for machine
+                information as well, however only as fallback.</para>
+
+                <para>You may use
+                <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to change the settings of this file from the command
+                line.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following machine meta data parameters may
+                be set using
+                <filename>/etc/machine-info</filename>:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>PRETTY_HOSTNAME=</varname></term>
+
+                                <listitem><para>A pretty
+                                human-readable UTF8 machine identifier
+                                string. This should contain a name
+                                like <literal>Lennart's
+                                Laptop</literal> which is useful to
+                                present to the user and does not
+                                suffer by the syntax limitations of
+                                internet domain names. If possible the
+                                internet host name as configured in
+                                <filename>/etc/hostname</filename>
+                                should be kept similar to this
+                                one. Example: if this value is
+                                <literal>Lennart's Computer</literal>
+                                an Internet host name of
+                                <literal>lennarts-computer</literal>
+                                might be a good choice. If this
+                                parameter is not set an application
+                                should fall back to the Internet host
+                                name for presentation
+                                purposes.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ICON_NAME=</varname></term>
+
+                                <listitem><para>An icon identifying
+                                this machine according to the <ulink
+                                url="http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html">XDG
+                                Icon Naming Specification</ulink>. If
+                                this parameter is not set an
+                                application should fall back to
+                                <literal>computer</literal> or a
+                                similar icon name.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CHASSIS=</varname></term>
+
+                                <listitem><para>The chassis
+                                type. Currently, the following chassis
+                                types are defined:
+                                <literal>desktop</literal>,
+                                <literal>laptop</literal>,
+                                <literal>server</literal>,
+                                <literal>tablet</literal>,
+                                <literal>handset</literal>, as well as
+                                the special chassis types
+                                <literal>vm</literal> and
+                                <literal>container</literal> for
+                                virtualized systems that lack an
+                                immediate physical chassis. Note that
+                                many systems allow detection of the
+                                chassis type automatically (based on
+                                firmware information or
+                                suchlike). This setting (if set) shall
+                                take precedence over automatically
+                                detected information and is useful to
+                                override misdetected configuration or
+                                to manually configure the chassis type
+                                where automatic detection is not
+                                available.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+
+                <programlisting>PRETTY_HOSTNAME="Lennart's Tablet"
+ICON_NAME=computer-tablet
+CHASSIS=tablet</programlisting>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/modules-load.d.xml b/man/modules-load.d.xml
new file mode 100644 (file)
index 0000000..bcc4d12
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="modules-load.d">
+
+        <refentryinfo>
+                <title>modules-load.d</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>modules-load.d</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>modules-load.d</refname>
+                <refpurpose>Configure kernel modules to load at boot</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/modules-load.d/*.conf</filename></para>
+                <para><filename>/run/modules-load.d/*.conf</filename></para>
+                <para><filename>/usr/lib/modules-load.d/*.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><citerefentry><refentrytitle>systemd-modules-load.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                reads files from the above directories which contain
+                kernel modules to load during boot in a static list.
+                Each configuration file is named in the style of
+                <filename>/etc/modules-load.d/&lt;program&gt;.conf</filename>. Note
+                that it is usually a better idea to rely on the
+                automatic module loading by PCI IDs, USB IDs, DMI IDs
+                or similar triggers encoded in the kernel modules
+                themselves instead of static configuration like
+                this. In fact, most modern kernel modules are prepared
+                for automatic loading already.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Configuration Format</title>
+
+                <para>The configuration files should simply contain a
+                list of kernel module names to load, separated by
+                newlines. Empty lines and lines whose first
+                non-whitespace character is # or ; are ignored.</para>
+
+                <para>Each configuration file shall be named in the
+                style of <filename>&lt;program&gt;.conf</filename>.
+                Files in <filename>/etc/</filename> override files
+                with the same name in <filename>/usr/lib/</filename>
+                and <filename>/run/</filename>. Files in
+                <filename>/run/</filename> override files with the
+                same name in <filename>/usr/lib/</filename>. Packages
+                should install their configuration files in
+                <filename>/usr/lib/</filename>, files in
+                <filename>/etc/</filename> are reserved for the local
+                administrator, who may use this logic to override the
+                configuration files installed from vendor
+                packages.</para>
+
+                <para>If the administrator wants to disable a
+                configuration file supplied by the vendor the
+                recommended way is to place a symlink to
+                <filename>/dev/null</filename> in
+                <filename>/etc/modules-load.d/</filename> bearing the
+                same file name.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+                <example>
+                        <title>/etc/modules-load.d/virtio-net.conf example:</title>
+
+                        <programlisting># Load virtio-net.ko at boot
+virtio-net</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-modules-load.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>modprobe</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/os-release.xml b/man/os-release.xml
new file mode 100644 (file)
index 0000000..98320ef
--- /dev/null
@@ -0,0 +1,350 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="os-release">
+        <refentryinfo>
+                <title>os-release</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>os-release</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>os-release</refname>
+                <refpurpose>Operating system identification</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/os-release</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The <filename>/etc/os-release</filename> file
+                contains operating system identification data.</para>
+
+                <para>The basic file format of
+                <filename>os-release</filename> is a newline-separated
+                list of environment-like shell-compatible variable
+                assignments. It is possible to source the
+                configuration from shell scripts, however, beyond mere
+                variable assignments no shell features are supported
+                (this means variable expansion is explicitly not
+                supported), allowing applications to read the file
+                without implementing a shell compatible execution
+                engine. Variable assignment values should be enclosed
+                in double or single quotes if they include spaces,
+                semicolons or other special characters outside of A-Z,
+                a-z, 0-9. All strings should be in UTF-8 format, and
+                non-printable characters should not be used. If double
+                or single quotes or backslashes are to be used within
+                variable assignments they should be escaped with
+                backslashes, following shell style. It is not
+                supported to concatenate multiple individually quoted
+                strings. Lines beginning with "#" shall be ignored as
+                comments.</para>
+
+                <para><filename>/etc/os-release</filename> contains
+                data that is defined by the operating system vendor
+                and should not be changed by the administrator.</para>
+
+                <para>As this file only encodes names and identifiers
+                it should not be localized.</para>
+
+                <para>The file <filename>/etc/os-release</filename> might
+                be a symlink to another file, but it is important that
+                the file is available from earliest boot on, and hence
+                must be located on the root file system.</para>
+
+                <para>For a longer rationale for
+                <filename>/etc/os-release</filename> please refer to
+                the <ulink
+                url="http://0pointer.de/blog/projects/os-release">Announcement of <filename>/etc/os-release</filename></ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following OS identifications parameters may be set using
+                <filename>/etc/os-release</filename>:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>NAME=</varname></term>
+
+                                <listitem><para>A string identifying
+                                the operating system, without a
+                                version component, and suitable for
+                                presentation to the user. If not set
+                                defaults to
+                                <literal>NAME=Linux</literal>. Example:
+                                <literal>NAME=Fedora</literal> or
+                                <literal>NAME="Debian
+                                GNU/Linux"</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>VERSION=</varname></term>
+
+                                <listitem><para>A string identifying
+                                the operating system version,
+                                excluding any OS name information,
+                                possibly including a release code
+                                name, and suitable for presentation to
+                                the user. This field is
+                                optional. Example:
+                                <literal>VERSION=17</literal> or
+                                <literal>VERSION="17 (Beefy
+                                Miracle)"</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ID=</varname></term>
+
+                                <listitem><para>A lower-case string
+                                (no spaces or other characters outside
+                                of 0-9, a-z, ".", "_" and "-")
+                                identifying the operating system,
+                                excluding any version information and
+                                suitable for processing by scripts or
+                                usage in generated file names. If not
+                                set defaults to
+                                <literal>ID=linux</literal>. Example:
+                                <literal>ID=fedora</literal> or
+                                <literal>ID=debian</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ID_LIKE=</varname></term>
+
+                                <listitem><para>A space-separated list
+                                of operating system identifiers in the
+                                same syntax as the
+                                <varname>ID=</varname> setting. Should
+                                list identifiers of operating systems
+                                that are closely related to the local
+                                operating system in regards to
+                                packaging and programming interfaces,
+                                for example listing one or more
+                                OS identifiers the local
+                                OS is a derivative from. An
+                                OS should generally only list other OS
+                                identifiers it itself is a derivative
+                                from, and not any OSes that
+                                are derived from it, but symmetric
+                                relationships are possible. Build
+                                scripts and similar should check this
+                                variable if they need to identify the
+                                local operating system and the value
+                                of <varname>ID=</varname> is not
+                                recognized. Operating systems should
+                                be listed in order of how closely the
+                                local operating system relates to the
+                                listed ones, starting with the
+                                closest. This field is
+                                optional. Example: for an operating
+                                system with
+                                <literal>ID=centos</literal> an
+                                assignment of <literal>ID_LIKE="rhel
+                                fedora"</literal> would be
+                                appropriate. For an operating system
+                                with <literal>ID=ubuntu</literal> an
+                                assignment of
+                                <literal>ID_LIKE=debian</literal> is
+                                appropriate.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>VERSION_ID=</varname></term>
+
+                                <listitem><para>A lower-case string
+                                (mostly numeric, no spaces or other
+                                characters outside of 0-9, a-z, ".",
+                                "_" and "-") identifying the operating
+                                system version, excluding any OS name
+                                information or release code name, and
+                                suitable for processing by scripts or
+                                usage in generated file names. This
+                                field is optional. Example:
+                                <literal>VERSION_ID=17</literal> or
+                                <literal>VERSION_ID=11.04</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PRETTY_NAME=</varname></term>
+
+                                <listitem><para>A pretty operating
+                                system name in a format suitable for
+                                presentation to the user. May or may
+                                not contain a release code name or OS
+                                version of some kind, as suitable. If
+                                not set defaults to
+                                <literal>PRETTY_NAME="Linux"</literal>. Example:
+                                <literal>PRETTY_NAME="Fedora 17 (Beefy
+                                Miracle)"</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ANSI_COLOR=</varname></term>
+
+                                <listitem><para>A suggested
+                                presentation color when showing the
+                                OS name on the console. This
+                                should be specified as string suitable
+                                for inclusion in the ESC [ m
+                                ANSI/ECMA-48 escape code for setting
+                                graphical rendition. This field is
+                                optional. Example:
+                                <literal>ANSI_COLOR="0;31"</literal>
+                                for red, or
+                                <literal>ANSI_COLOR="1;34"</literal>
+                                for light blue.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CPE_NAME=</varname></term>
+
+                                <listitem><para>A CPE name for the
+                                operating system, following the <ulink
+                                url="http://cpe.mitre.org/specification/">Common
+                                Platform Enumeration
+                                Specification</ulink> as proposed by
+                                the MITRE Corporation. This field
+                                is optional. Example:
+                                <literal>CPE_NAME="cpe:/o:fedoraproject:fedora:17"</literal>
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>HOME_URL=</varname></term>
+                                <term><varname>SUPPORT_URL=</varname></term>
+                                <term><varname>BUG_REPORT_URL=</varname></term>
+
+                                <listitem><para>Links to resources on
+                                the Internet related the operating
+                                system. <varname>HOME_URL=</varname>
+                                should refer to the homepage of the
+                                operating system, or alternatively
+                                some homepage of the specific version
+                                of the operating
+                                system. <varname>SUPPORT_URL=</varname>
+                                should refer to the main support page
+                                for the operating system, if there is
+                                any. This is primarily intended for
+                                operating systems which vendors
+                                provide support
+                                for. <varname>BUG_REPORT_URL=</varname>
+                                should refer to the main bug reporting
+                                page for the operating system, if
+                                there is any. This is primarily
+                                intended for operating systems that
+                                rely on community QA. These settings
+                                are optional, and providing only some
+                                of these settings is common. These
+                                URLs are intended to be exposed in
+                                "About this system" UIs behind links
+                                with captions such as "About this
+                                Operating System", "Obtain Support",
+                                and "Report a Bug". The values should
+                                be in <ulink
+                                url="https://tools.ietf.org/html/rfc3986">RFC3986
+                                format</ulink>, and should be
+                                <literal>http:</literal> or
+                                <literal>https:</literal> URLs, and
+                                possibly <literal>mailto:</literal> or
+                                <literal>tel:</literal>. Only one URL
+                                shall be listed in each setting. If
+                                multiple resources need to be
+                                referenced it is recommended to
+                                provide an online landing page linking
+                                all available resources. Examples:
+                                <literal>HOME_URL="https://fedoraproject.org/"</literal>
+                                and
+                                <literal>BUG_REPORT_URL="https://bugzilla.redhat.com/"</literal></para></listitem>
+                        </varlistentry>
+
+
+                </variablelist>
+
+                <para>If you are reading this file from C code or a
+                shell script to determine the OS or a specific version
+                of it, use the ID and VERSION_ID fields, possibly with
+                ID_LIKE as fallback for ID. When looking for an OS
+                identification string for presentation to the user use
+                the PRETTY_NAME field.</para>
+
+                <para>Note that operating system vendors may choose
+                not to provide version information, for example to
+                accommodate for rolling releases. In this case VERSION
+                and VERSION_ID may be unset. Applications should not
+                rely on these fields to be set.</para>
+
+                <para>Operating system vendors may extend the file
+                format and introduce new fields. It is highly
+                recommended to prefix new fields with an OS specific
+                name in order to avoid name clashes. Applications
+                reading this file must ignore unknown fields. Example:
+                <literal>DEBIAN_BTS="debbugs://bugs.debian.org/"</literal></para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+
+                <programlisting>NAME=Fedora
+VERSION="17 (Beefy Miracle)"
+ID=fedora
+VERSION_ID=17
+PRETTY_NAME="Fedora 17 (Beefy Miracle)"
+ANSI_COLOR="0;34"
+CPE_NAME="cpe:/o:fedoraproject:fedora:17"
+HOME_URL="https://fedoraproject.org/"
+BUG_REPORT_URL="https://bugzilla.redhat.com/"</programlisting>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>lsb_release</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml
new file mode 100644 (file)
index 0000000..600bfd7
--- /dev/null
@@ -0,0 +1,328 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="pam_systemd">
+
+        <refentryinfo>
+                <title>pam_systemd</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>pam_systemd</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>pam_systemd</refname>
+                <refpurpose>Register user sessions in the systemd login manager</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>pam_systemd.so</command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>pam_systemd</command> registers user
+                sessions in the systemd login manager
+                <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                and hence the systemd control group hierarchy.</para>
+
+                <para>On login, this module ensures the following:</para>
+
+                <orderedlist>
+                        <listitem><para>If it does not exist yet, the
+                        user runtime directory
+                        <filename>/run/user/$USER</filename> is
+                        created and its ownership changed to the user
+                        that is logging in.</para></listitem>
+
+                        <listitem><para>The
+                        <varname>$XDG_SESSION_ID</varname> environment
+                        variable is initialized. If auditing is
+                        available and
+                        <command>pam_loginuid.so</command> run before
+                        this module (which is highly recommended), the
+                        variable is initialized from the auditing
+                        session id
+                        (<filename>/proc/self/sessionid</filename>). Otherwise
+                        an independent session counter is
+                        used.</para></listitem>
+
+                        <listitem><para>A new control group
+                        <filename>/user/$USER/$XDG_SESSION_ID</filename>
+                        is created and the login process moved into
+                        it.</para></listitem>
+                </orderedlist>
+
+                <para>On logout, this module ensures the following:</para>
+
+                <orderedlist>
+                        <listitem><para>If
+                        <varname>$XDG_SESSION_ID</varname> is set and
+                        <option>kill-session-processes=1</option> specified, all
+                        remaining processes in the
+                        <filename>/user/$USER/$XDG_SESSION_ID</filename>
+                        control group are killed and the control group
+                        is removed.</para></listitem>
+
+                        <listitem><para>If the last subgroup of the
+                        <filename>/user/$USER</filename> control group
+                        was removed the
+                        <varname>$XDG_RUNTIME_DIR</varname> directory
+                        and all its contents are
+                        removed, too.</para></listitem>
+                </orderedlist>
+
+                <para>If the system was not booted up with systemd as
+                init system, this module does nothing and immediately
+                returns PAM_SUCCESS.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>kill-session-processes=</option></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true, all processes
+                                created by the user during his session
+                                and from his session will be
+                                terminated when he logs out from his
+                                session.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>kill-only-users=</option></term>
+
+                                <listitem><para>Takes a comma
+                                separated list of user names or
+                                numeric user ids as argument. If this
+                                option is used the effect of the
+                                <option>kill-session-processes=</option> options
+                                will apply only to the listed
+                                users. If this option is not used the
+                                option applies to all local
+                                users. Note that
+                                <option>kill-exclude-users=</option>
+                                takes precedence over this list and is
+                                hence subtracted from the list
+                                specified here.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>kill-exclude-users=</option></term>
+
+                                <listitem><para>Takes a comma
+                                separated list of user names or
+                                numeric user ids as argument. Users
+                                listed in this argument will not be
+                                subject to the effect of
+                                <option>kill-session-processes=</option>.  Note
+                                that this option takes precedence
+                                over
+                                <option>kill-only-users=</option>, and
+                                hence whatever is listed for
+                                <option>kill-exclude-users=</option>
+                                is guaranteed to never be killed by
+                                this PAM module, independent of any
+                                other configuration
+                                setting.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>controllers=</option></term>
+
+                                <listitem><para>Takes a comma
+                                separated list of control group
+                                controllers in which hierarchies a
+                                user/session control group will be
+                                created by default for each user
+                                logging in, in addition to the control
+                                group in the named 'name=systemd'
+                                hierarchy. If omitted, defaults to an
+                                empty list.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>reset-controllers=</option></term>
+
+                                <listitem><para>Takes a comma
+                                separated list of control group
+                                controllers in which hierarchies the
+                                logged in processes will be reset to
+                                the root control
+                                group.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>class=</option></term>
+
+                                <listitem><para>Takes a string
+                                argument which sets the session class.
+                                The XDG_SESSION_CLASS environmental variable
+                                takes precedence.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>debug=</option></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If yes, the module will log
+                                debugging information as it
+                                operates.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>Note that setting
+                <varname>kill-session-processes=1</varname> will break tools
+                like
+                <citerefentry><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+
+                <para>Note that
+                <varname>kill-session-processes=1</varname> is a
+                stricter version of
+                <varname>KillUserProcesses=1</varname> which may be
+                configured system-wide in
+                <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
+                former kills processes of a session as soon as it
+                ends, the latter kills processes as soon as the last
+                session of the user ends.</para>
+
+                <para>If the options are omitted they default to
+                <option>kill-session-processes=0</option>,
+                <option>kill-only-users=</option>,
+                <option>kill-exclude-users=</option>,
+                <option>controllers=</option>,
+                <option>reset-controllers=</option>,
+                <option>debug=no</option>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Module Types Provided</title>
+
+                <para>Only <option>session</option> is provided.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <para>The following environment variables are set for the processes of the user's session:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$XDG_SESSION_ID</varname></term>
+
+                                <listitem><para>A session identifier,
+                                suitable to be used in file names. The
+                                string itself should be considered
+                                opaque, although often it is just the
+                                audit session ID as reported by
+                                <filename>/proc/self/sessionid</filename>. Each
+                                ID will be assigned only once during
+                                machine uptime. It may hence be used
+                                to uniquely label files or other
+                                resources of this
+                                session.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$XDG_RUNTIME_DIR</varname></term>
+
+                                <listitem><para>Path to a user-private
+                                user-writable directory that is bound
+                                to the user login time on the
+                                machine. It is automatically created
+                                the first time a user logs in and
+                                removed on his final logout. If a user
+                                logs in twice at the same time, both
+                                sessions will see the same
+                                <varname>$XDG_RUNTIME_DIR</varname>
+                                and the same contents. If a user logs
+                                in once, then logs out again, and logs
+                                in again, the directory contents will
+                                have been lost in between, but
+                                applications should not rely on this
+                                behavior and must be able to deal with
+                                stale files. To store session-private
+                                data in this directory the user should
+                                include the value of <varname>$XDG_SESSION_ID</varname>
+                                in the filename. This directory shall
+                                be used for runtime file system
+                                objects such as AF_UNIX sockets,
+                                FIFOs, PID files and similar. It is
+                                guaranteed that this directory is
+                                local and offers the greatest possible
+                                file system feature set the
+                                operating system
+                                provides.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+
+                <programlisting>#%PAM-1.0
+auth       required     pam_unix.so
+auth       required     pam_nologin.so
+account    required     pam_unix.so
+password   required     pam_unix.so
+session    required     pam_unix.so
+session    required     pam_loginuid.so
+session    required     pam_systemd.so kill-session-processes=1</programlisting>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pam_loginuid</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/runlevel.xml b/man/runlevel.xml
new file mode 100644 (file)
index 0000000..02d5371
--- /dev/null
@@ -0,0 +1,154 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="runlevel">
+
+        <refentryinfo>
+                <title>runlevel</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>runlevel</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>runlevel</refname>
+                <refpurpose>Print previous and current SysV runlevel</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>runlevel <arg choice="opt" rep="repeat">options</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>runlevel</command> prints the previous
+                and current SysV runlevel if they are known.</para>
+
+                <para>The two runlevel characters are separated by a
+                single space character. If a runlevel cannot be
+                determined, N is printed instead. If neither can be
+                determined, the word "unknown" is printed.</para>
+
+                <para>Unless overridden in the environment, this will
+                check the utmp database for recent runlevel
+                changes.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following option is understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>If one or both runlevels could be determined, 0
+                is returned, a non-zero failure code otherwise.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$RUNLEVEL</varname></term>
+
+                                <listitem><para>If
+                                <varname>$RUNLEVEL</varname> is set,
+                                <command>runlevel</command> will print
+                                this value as current runlevel and
+                                ignore utmp.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$PREVLEVEL</varname></term>
+
+                                <listitem><para>If
+                                <varname>$PREVLEVEL</varname> is set
+                                <command>runlevel</command> will print
+                                this value as previous runlevel and
+                                ignore utmp.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Files</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>/var/run/utmp</varname></term>
+
+                                <listitem><para>The utmp database
+                                <command>runlevel</command> reads the
+                                previous and current runlevel
+                                from.</para></listitem>
+
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>This is a legacy command available for compatibility
+                only. It should not be used anymore, as the concept of
+                runlevels is obsolete.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml
new file mode 100644 (file)
index 0000000..a3bf662
--- /dev/null
@@ -0,0 +1,180 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd-daemon">
+
+        <refentryinfo>
+                <title>sd-daemon</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd-daemon</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd-daemon</refname>
+                <refname>SD_EMERG</refname>
+                <refname>SD_ALERT</refname>
+                <refname>SD_CRIT</refname>
+                <refname>SD_ERR</refname>
+                <refname>SD_WARNING</refname>
+                <refname>SD_NOTICE</refname>
+                <refname>SD_INFO</refname>
+                <refname>SD_DEBUG</refname>
+                <refpurpose>Reference implementation of APIs for
+                new-style daemons</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+                </funcsynopsis>
+
+                <cmdsynopsis>
+                        <command>pkg-config --cflags --libs libsystemd-daemon</command>
+                </cmdsynopsis>
+
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>sd-daemon.c</filename> and
+                <filename>sd-daemon.h</filename> provide a reference
+                implementation of various APIs for new-style daemons,
+                as implemented by the
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                init system.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_is_fifo</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information about the functions
+                implemented. In addition to these functions a couple
+                of logging prefixes are defined as macros:</para>
+
+                <programlisting>#define SD_EMERG   "&lt;0&gt;"  /* system is unusable */
+#define SD_ALERT   "&lt;1&gt;"  /* action must be taken immediately */
+#define SD_CRIT    "&lt;2&gt;"  /* critical conditions */
+#define SD_ERR     "&lt;3&gt;"  /* error conditions */
+#define SD_WARNING "&lt;4&gt;"  /* warning conditions */
+#define SD_NOTICE  "&lt;5&gt;"  /* normal but significant condition */
+#define SD_INFO    "&lt;6&gt;"  /* informational */
+#define SD_DEBUG   "&lt;7&gt;"  /* debug-level messages */</programlisting>
+
+                <para>These prefixes are intended to be used in
+                conjunction with STDERR-based logging as implemented
+                by systemd. If a systemd service definition file is
+                configured with <varname>StandardError=syslog</varname>
+                or <varname>StandardError=kmsg</varname> these
+                prefixes can be used to encode a log level in lines
+                printed. This is similar to the kernel
+                <function>printk()</function>-style logging. See
+                <citerefentry><refentrytitle>klogctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                for more information.</para>
+
+                <para>The log levels are identical to
+                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s
+                log level system. To use these prefixes simply prefix
+                every line with one of these strings. A line that is
+                not prefixed will be logged at the default log level
+                SD_INFO.</para>
+
+                <example>
+                        <title>Hello World</title>
+
+                        <para>A daemon may log with the log level
+                        NOTICE by issuing this call:</para>
+
+                        <programlisting>fprintf(stderr, SD_NOTICE "Hello World!\n");</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>These interfaces are provided by the reference
+                implementation of APIs for new-style daemons and
+                distributed with the systemd package. The algorithms
+                they implement are simple, and can easily be
+                reimplemented in daemons if it is important to support
+                this interface without using the reference
+                implementation. See the respective function man pages
+                for details.</para>
+
+                <para>In addition, for details about the algorithms
+                check the liberally licensed reference implementation
+                sources:
+                <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c"/>
+                and <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h"/></para>
+
+                <para>These APIs are implemented in the reference
+                implementation's <filename>sd-daemon.c</filename> and
+                <filename>sd-daemon.h</filename> files. These
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-daemon</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file. Alternatively, applications consuming these APIs
+                may copy the implementation into their source tree,
+                either verbatim or in excerpts.</para>
+
+                <para>The functions directly related to new-style
+                daemons become NOPs when -DDISABLE_SYSTEMD is set
+                during compilation and the reference implementation is
+                used as drop-in files. In addition, if
+                <filename>sd-daemon.c</filename> is compiled on
+                non-Linux systems they become NOPs.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_is_fifo</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd-id128.xml b/man/sd-id128.xml
new file mode 100644 (file)
index 0000000..ac2000e
--- /dev/null
@@ -0,0 +1,181 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd-id128">
+
+        <refentryinfo>
+                <title>sd-id128</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd-id128</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd-id128</refname>
+                <refname>sd_id128_t</refname>
+                <refname>SD_ID128_MAKE</refname>
+                <refname>SD_ID128_CONST_STR</refname>
+                <refname>SD_ID128_FORMAT_STR</refname>
+                <refname>SD_ID128_FORMAT_VAL</refname>
+                <refname>sd_id128_equal</refname>
+                <refpurpose>APIs for processing 128 bit IDs</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-id128.h&gt;</funcsynopsisinfo>
+                </funcsynopsis>
+
+                <cmdsynopsis>
+                        <command>pkg-config --cflags --libs libsystemd-id128</command>
+                </cmdsynopsis>
+
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>sd-id128.h</filename> provides APIs to
+                process and generate 128 bit ID values. The 128 bit ID
+                values processed and generated by these APIs are a
+                generalization of OSF UUIDs as defined by <ulink
+                url="http://tools.ietf.org/html/rfc4122">RFC
+                4122</ulink>, though use a simpler string
+                formatting. These functions impose no structure on the
+                used IDs, much unlike OSF UUIDs or Microsoft GUIDs,
+                but are fully compatible with those types of IDs.
+                </para>
+
+                <para>See
+                <citerefentry><refentrytitle>sd_id128_to_string</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_id128_randomize</refentrytitle><manvolnum>3</manvolnum></citerefentry> and
+                <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information about the implemented
+                functions.</para>
+
+                <para>A 128 bit ID is implemented as the following
+                union type:</para>
+
+                <programlisting>typedef union sd_id128 {
+        uint8_t bytes[16];
+        uint64_t qwords[2];
+} sd_id128_t;</programlisting>
+
+                <para>This union type allows accessing the 128 bit ID
+                as 16 separate bytes or two 64 bit words. It is generally
+                safer to access the ID components by their 8 bit array
+                to avoid endianness issues. This union is intended to
+                be passed call-by-value (as opposed to
+                call-by-reference) and may be directly manipulated by
+                clients.</para>
+
+                <para>A couple of macros are defined to denote and
+                decode 128 bit IDs:</para>
+
+                <para><function>SD_ID128_MAKE()</function> may be used
+                to denote a constant 128 bit ID in source code. A
+                commonly used idiom is to assign a name to a 128 bit
+                ID using this macro:</para>
+
+                <programlisting>#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)</programlisting>
+
+                <para><function>SD_ID128_CONST_STR()</function> may be
+                used to convert constant 128bit IDs into constant
+                strings for output. The following example code will
+                output the string
+                "fc2e22bc6ee647b6b90729ab34a250b1":</para>
+                <programlisting>int main(int argc, char *argv[]) {
+        puts(SD_ID128_CONST_STR(SD_MESSAGE_COREDUMP));
+}</programlisting>
+
+                <para><function>SD_ID128_FORMAT_STR</function> and
+                <function>SD_ID128_FORMAT_VAL()</function> may be used
+                to format a 128 bit ID in a
+                <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                format string, as shown in the following
+                example:</para>
+
+                <programlisting>int main(int argc, char *argv[]) {
+        sd_id128_t id;
+        id = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07);
+        printf("The ID encoded in this C file is " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(id));
+        return 0;
+}</programlisting>
+
+                <para>Use <function>sd_id128_equal()</function> to compare two 128 bit IDs:</para>
+
+                <programlisting>int main(int argc, char *argv[]) {
+        sd_id128_t a, b, c;
+        a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07);
+        b = SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e);
+        c = a;
+        assert(sd_id128_equal(a, c));
+        assert(!sd_id128_equal(a, b));
+        return 0;
+}</programlisting>
+
+                <para>Note that new, randomized IDs may be generated
+                with
+                <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+                <literal>--new-id</literal> option.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>These APIs are implemented as a shared library,
+                which can be compiled and linked to with the
+                <literal>libsystemd-id128</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_id128_to_string</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_id128_randomize</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd-journal.xml b/man/sd-journal.xml
new file mode 100644 (file)
index 0000000..a7220ec
--- /dev/null
@@ -0,0 +1,132 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd-journal">
+
+        <refentryinfo>
+                <title>sd-journal</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd-journal</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd-journal</refname>
+                <refpurpose>APIs for submitting and querying log entries to and from the journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+                </funcsynopsis>
+
+                <cmdsynopsis>
+                        <command>pkg-config --cflags --libs libsystemd-journal</command>
+                </cmdsynopsis>
+
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>sd-journal.h</filename> provides APIs
+                to submit and query log entries. The APIs exposed act
+                both as client for the
+                <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                journal service and as parser for the journal files
+                on disk.
+                </para>
+
+                <para>See
+                <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_stream_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_get_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_seek_head</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_get_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_cutoff_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_get_usage</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_get_catalog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>sd_journal_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information about the functions
+                implemented.</para>
+
+                <para>Command line access for submitting entries to
+                the journal is available with the
+                <citerefentry><refentrytitle>systemd-cat</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                tool. Command line access for querying entries from
+                the journal is available with the
+                <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                tool.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>These APIs are implemented as shared library,
+                which can be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_stream_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_seek_head</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_cutoff_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_usage</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_query_unique</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_catalog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd-login.xml b/man/sd-login.xml
new file mode 100644 (file)
index 0000000..c02ad0c
--- /dev/null
@@ -0,0 +1,146 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd-login">
+
+        <refentryinfo>
+                <title>sd-login</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd-login</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd-login</refname>
+                <refpurpose>APIs for
+                tracking logins</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+                </funcsynopsis>
+
+                <cmdsynopsis>
+                        <command>pkg-config --cflags --libs libsystemd-login</command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>sd-login.h</filename> provides APIs to
+                introspect and monitor seat, login session and user
+                status information on the local system. </para>
+
+                <para>See <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
+                on Linux</ulink> for an introduction into multi-seat
+                support on Linux, the background for this set of APIs.</para>
+
+                <para>Note that these APIs only allow purely passive access
+                and monitoring of seats, sessions and users. To
+                actively make changes to the seat configuration,
+                terminate login sessions, or switch session on a seat
+                you need to utilize the D-Bus API of
+                systemd-logind, instead.</para>
+
+                <para>These functions synchronously access data in
+                <filename>/proc</filename>,
+                <filename>/sys/fs/cgroup</filename> and
+                <filename>/run</filename>. All of these are virtual
+                file systems, hence the runtime cost of the accesses
+                is relatively cheap.</para>
+
+                <para>It is possible (and often a very good choice) to
+                mix calls to the synchronous interface of
+                <filename>sd-login.h</filename> with the asynchronous
+                D-Bus interface of systemd-logind. However, if this is
+                done you need to think a bit about possible races
+                since the stream of events from D-Bus and from
+                <filename>sd-login.h</filename> interfaces such as the
+                login monitor are asynchronous and not ordered against
+                each other.</para>
+
+                <para>If the functions return string arrays, these are
+                generally NULL terminated and need to be freed by the
+                caller with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use, including the strings referenced
+                therein. Similar, individual strings returned need to
+                be freed, as well.</para>
+
+                <para>As a special exception, instead of an empty
+                string array NULL may be returned, which should be
+                treated equivalent to an empty string array.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_uid_get_state</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_seat_get_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information about the functions
+                implemented.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>These APIs are implemented as shared library,
+                which can be compiled and linked to with the
+                <literal>libsystemd-login</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_uid_get_state</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_seat_get_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd-readahead.xml b/man/sd-readahead.xml
new file mode 100644 (file)
index 0000000..cebaa5d
--- /dev/null
@@ -0,0 +1,117 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd-daemon">
+
+        <refentryinfo>
+                <title>sd-readahead</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd-readahead</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd-readahead</refname>
+                <refpurpose>Reference implementation of APIs for
+                controlling boot-time read-ahead</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include "sd-readahead.h"</funcsynopsisinfo>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>sd-readahead.c</filename> and
+                <filename>sd-readahead.h</filename> provide a
+                reference implementation for APIs for controlling boot-time
+                read-ahead, as implemented by the read-ahead subsystem
+                of the
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                init system.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>sd_readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information about the function
+                implemented.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>This interface is provided by the reference
+                implementation of APIs for controlling boot-time
+                read-ahead and distributed with the systemd
+                package. The algorithms it implements are simple, and
+                can easily be reimplemented in daemons if it is
+                important to support this interface without using the
+                reference implementation. See the respective function
+                man pages for details.</para>
+
+                <para>In addition, for details about the algorithms
+                check the liberally licensed reference implementation
+                sources:
+                <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c"/>
+                and <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h"/></para>
+
+                <para>These APIs are implemented in the reference
+                implementation's drop-in
+                <filename>sd-readahead.c</filename> and
+                <filename>sd-readahead.h</filename> files. It is
+                recommended that applications consuming these APIs copy
+                the implementation into their source tree, either
+                verbatim or in excerpts. These interfaces are
+                currently not available in a dynamic library.</para>
+
+                <para>The functions provided by this interface become
+                NOPs when -DDISABLE_SYSTEMD is set during
+                compilation. In addition, if
+                <filename>sd-readhead.c</filename> is compiled on
+                non-Linux systems it becomes NOPs.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_booted.xml b/man/sd_booted.xml
new file mode 100644 (file)
index 0000000..34f2cbf
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_booted">
+
+        <refentryinfo>
+                <title>sd_booted</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_booted</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_booted</refname>
+                <refpurpose>Test whether the system is running the systemd init system</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_booted</function></funcdef>
+                                <paramdef>void</paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+                <para><function>sd_booted()</function> checks whether
+                the system was booted up using the systemd init system.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On failure, this call returns a negative
+                errno-style error code. If the system was booted up
+                with systemd as init system, this call returns a
+                positive return value, zero otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>This function is provided by the reference
+                implementation of APIs for new-style daemons and
+                distributed with the systemd package. The algorithm it
+                implements is simple, and can easily be reimplemented
+                in daemons if it is important to support this
+                interface without using the reference
+                implementation.</para>
+
+                <para>Internally, this function checks whether the
+                <filename>/sys/fs/cgroup/systemd</filename> virtual file
+                system is mounted, by comparing the st_dev value of
+                the <function>stat()</function> data of
+                <filename>/sys/fs/cgroup</filename> and
+                <filename>/sys/fs/cgroup/systemd</filename>.</para>
+
+                <para>For details about the algorithm check the
+                liberally licensed reference implementation sources:
+                <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c"/>
+                and <ulink
+                url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h"/></para>
+
+                <para><function>sd_booted()</function> is implemented
+                in the reference implementation's
+                <filename>sd-daemon.c</filename> and
+                <filename>sd-daemon.h</filename> files. These
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-daemon</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file. Alternatively, applications consuming these APIs
+                may copy the implementation into their source
+                tree. For more details about the reference
+                implementation see
+                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>If the reference implementation is used as
+                drop-in files and -DDISABLE_SYSTEMD is set during
+                compilation this function will always return 0 and
+                otherwise become a NOP.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml
new file mode 100644 (file)
index 0000000..17adcef
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_get_seats">
+
+        <refentryinfo>
+                <title>sd_get_seats</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_get_seats</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_get_seats</refname>
+                <refname>sd_get_sessions</refname>
+                <refname>sd_get_uids</refname>
+                <refpurpose>Determine available seats, sessions and logged in users</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_get_seats</function></funcdef>
+                                <paramdef>char*** <parameter>seats</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_get_sessions</function></funcdef>
+                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_get_uids</function></funcdef>
+                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_get_seats()</function> may be used
+                to determine all currently available local
+                seats. Returns a NULL terminated array of seat
+                identifiers. The returned array and all strings it
+                references need to be freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use. Note that instead of an empty array
+                NULL may be returned and should be considered
+                equivalent to an empty array.</para>
+
+                <para>Similar, <function>sd_get_sessions()</function> may
+                be used to determine all current login sessions.</para>
+
+                <para>Similar, <function>sd_get_uids()</function> may
+                be used to determine all Unix users who currently have login sessions.</para>
+
+                <para>Note that the returned lists are not sorted and in an undefined order.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On success <function>sd_get_seats()</function>,
+                <function>sd_get_sessions()</function> and
+                <function>sd_get_uids()</function> return the number
+                of entries in the arrays. On failure, these calls
+                return a negative errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_get_seats()</function>,
+                <function>sd_get_sessions()</function> and
+                <function>sd_get_uids()</function> interfaces
+                are available as shared library, which can be compiled
+                and linked to with the
+                <literal>libsystemd-login</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
new file mode 100644 (file)
index 0000000..039c1dd
--- /dev/null
@@ -0,0 +1,138 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_id128_get_machine">
+
+        <refentryinfo>
+                <title>sd_id128_get_machine</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_id128_get_machine</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_id128_get_machine</refname>
+                <refname>sd_id128_get_boot</refname>
+                <refpurpose>Retrieve 128 bit IDs</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-id128.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_id128_get_machine</function></funcdef>
+                                <paramdef>sd_id128_t* <parameter>ret</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_id128_get_boot</function></funcdef>
+                                <paramdef>sd_id128_t* <parameter>ret</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_id128_get_machine()</function>
+                returns the machine ID of the executing host. This
+                reads and parses the
+                <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                file. This function caches the machine ID internally
+                to make retrieving the machine ID a cheap
+                operation.</para>
+
+                <para><function>sd_id128_get_boot()</function> returns
+                the boot ID of the executing kernel. This reads and
+                parses the
+                <filename>/proc/sys/kernel/random/boot_id</filename>
+                file exposed by the kernel. It is randomly generated
+                early at boot and is unique for every running kernel
+                instance. See
+                <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>
+                for more information. This function also internally
+                caches the returned ID to make this call a cheap
+                operation.</para>
+
+                <para>Note that
+                <function>sd_id128_get_boot()</function> always returns
+                a UUID v4 compatible
+                ID. <function>sd_id128_get_machine()</function> will
+                also return a UUID v4 compatible ID on new
+                installations, but might not on older. It is possible
+                to convert the machine ID into an UUID v4 compatible
+                one. For more information see
+                <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+                <para>For more information about the
+                <literal>sd_id128_t</literal> type see
+                <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>The two calls return 0 on success (in which
+                case <parameter>ret</parameter> is filled in), or a
+                negative errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_id128_get_machine()</function>
+                and <function>sd_id128_get_boot()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-id128</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_id128_randomize</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_id128_randomize.xml b/man/sd_id128_randomize.xml
new file mode 100644 (file)
index 0000000..be74937
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_id128_randomize">
+
+        <refentryinfo>
+                <title>sd_id128_randomize</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_id128_randomize</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_id128_randomize</refname>
+                <refpurpose>Generate 128 bit IDs</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-id128.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_id128_randomize</function></funcdef>
+                                <paramdef>sd_id128_t* <parameter>ret</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_id128_randomize()</function>
+                generates a new randomized 128 bit ID and returns it
+                in <parameter>ret</parameter>. Every invocation
+                returns a new randomly generated ID. This uses the
+                <filename>/dev/urandom</filename> kernel random number
+                generator.</para>
+
+                <para>Note that
+                <function>sd_id128_randomize()</function> always returns
+                a UUID v4 compatible
+                ID.</para>
+
+                <para>For more information about the
+                <literal>sd_id128_t</literal> type see
+                <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para><citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+                <literal>--new-id</literal> command may be used as
+                command line front-end for
+                <function>sd_id128_randomize()</function>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>The call returns 0 on success (in which
+                case <parameter>ret</parameter> is filled in), or a
+                negative errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_id128_randomize()</function> interface
+                is available as shared library, which can be compiled
+                and linked to with the
+                <literal>libsystemd-id128</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_id128_to_string.xml b/man/sd_id128_to_string.xml
new file mode 100644 (file)
index 0000000..ec8b263
--- /dev/null
@@ -0,0 +1,131 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_id128_to_string">
+
+        <refentryinfo>
+                <title>sd_id128_to_string</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_id128_to_string</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_id128_to_string</refname>
+                <refname>sd_id128_from_string</refname>
+                <refpurpose>Format or parse 128 bit IDs as strings</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-id128.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>char* <function>sd_id128_to_string</function></funcdef>
+                                <paramdef>sd_id128_t <parameter>id</parameter>, char <parameter>s</parameter>[33]</paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_id128_from_string</function></funcdef>
+                                <paramdef>const char <parameter>s</parameter>[33], sd_id128_t* <parameter>ret</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_id128_to_string()</function>
+                formats a 128 bit ID as character string. It expects
+                the ID and a string array capable of storing 33
+                characters. The ID will be formatted as 32 lowercase
+                hexadecimal digits and be terminated by a NUL
+                byte.</para>
+
+                <para><function>sd_id128_from_string()</function>
+                implements the reverse operation: it takes a 33
+                character array with 32 hexadecimal digits
+                (terminated by NUL) and parses them back into an
+                128 bit ID returned in
+                <parameter>ret</parameter>.</para>
+
+                <para>For more information about the
+                <literal>sd_id128_t</literal> type see
+                <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>When formatting a 128 bit ID into a string it is
+                often easier to use a format string for
+                <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This
+                is easily done using the
+                <function>SD_ID128_FORMAT_STR</function> and
+                <function>SD_ID128_FORMAT_VAL()</function> macros. For
+                more information see
+                <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_id128_to_string()</function> always
+                succeeds and returns a pointer to the string array
+                passed in.  <function>sd_id128_from_string</function>
+                returns 0 on success (in which case
+                <parameter>ret</parameter> is filled in), or a negative
+                errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_id128_to_string()</function>
+                and <function>sd_id128_from_string()</function> interfaces are
+                available as shared library, which can be compiled and
+                linked to with the <literal>libsystemd-id128</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml
new file mode 100644 (file)
index 0000000..595c8f1
--- /dev/null
@@ -0,0 +1,217 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_is_fifo">
+
+        <refentryinfo>
+                <title>sd_is_fifo</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_is_fifo</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_is_fifo</refname>
+                <refname>sd_is_socket</refname>
+                <refname>sd_is_socket_inet</refname>
+                <refname>sd_is_socket_unix</refname>
+                <refname>sd_is_mq</refname>
+                <refpurpose>Check the type of a file descriptor</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_is_fifo</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>const char *<parameter>path</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_is_socket</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>int <parameter>family</parameter></paramdef>
+                                <paramdef>int <parameter>type</parameter></paramdef>
+                                <paramdef>int <parameter>listening</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_is_socket_inet</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>int <parameter>family</parameter></paramdef>
+                                <paramdef>int <parameter>type</parameter></paramdef>
+                                <paramdef>int <parameter>listening</parameter></paramdef>
+                                <paramdef>uint16_t <parameter>port</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_is_socket_unix</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>int <parameter>type</parameter></paramdef>
+                                <paramdef>int <parameter>listening</parameter></paramdef>
+                                <paramdef>const char* <parameter>path</parameter></paramdef>
+                                <paramdef>size_t <parameter>length</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_is_mq</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>const char *<parameter>path</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_is_fifo()</function> may be called
+                to check whether the specified file descriptor refers
+                to a FIFO or pipe. If the <parameter>path</parameter>
+                parameter is not NULL, it is checked whether the FIFO
+                is bound to the specified file system path.</para>
+
+                <para><function>sd_is_socket()</function> may be
+                called to check whether the specified file descriptor
+                refers to a socket. If the
+                <parameter>family</parameter> parameter is not
+                AF_UNSPEC it is checked whether the socket is of the
+                specified family (AF_UNIX, AF_INET, ...). If the
+                <parameter>type</parameter> parameter is not 0 it is
+                checked whether the socket is of the specified type
+                (SOCK_STREAM, SOCK_DGRAM, ...). If the
+                <parameter>listening</parameter> parameter is positive
+                it is checked whether the socket is in accepting mode,
+                i.e. <function>listen()</function> has been called for
+                it. If <parameter>listening</parameter> is 0, it is
+                checked whether the socket is not in this mode. If the
+                parameter is negative, no such check is made. The
+                <parameter>listening</parameter> parameter should only
+                be used for stream sockets and should be set to a
+                negative value otherwise.</para>
+
+                <para><function>sd_is_socket_inet()</function> is
+                similar to <function>sd_is_socket()</function>, but
+                optionally checks the IPv4 or IPv6 port number the
+                socket is bound to, unless <parameter>port</parameter>
+                is zero. For this call <parameter>family</parameter>
+                must be passed as either AF_UNSPEC, AF_INET, or
+                AF_INET6.</para>
+
+                <para><function>sd_is_socket_unix()</function> is
+                similar to <function>sd_is_socket()</function>, but
+                optionally checks the AF_UNIX path the socket is bound
+                to, unless the <parameter>path</parameter> parameter
+                is NULL. For normal file system AF_UNIX sockets set
+                the <parameter>length</parameter> parameter to 0. For
+                Linux abstract namespace sockets set the
+                <parameter>length</parameter> to the size of the
+                address, including the initial 0 byte and set
+                <parameter>path</parameter> to the initial 0 byte of
+                the socket address.</para>
+
+                <para><function>sd_is_mq()</function> may be called to
+                check whether the specified file descriptor refers to
+                a POSIX message queue. If the
+                <parameter>path</parameter> parameter is not NULL, it
+                is checked whether the message queue is bound to the
+                specified name.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On failure, these calls return a negative
+                errno-style error code. If the file descriptor is of
+                the specified type and bound to the specified address
+                a positive return value is returned, otherwise
+                zero.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>These functions are provided by the reference
+                implementation of APIs for new-style daemons and
+                distributed with the systemd package. The algorithms
+                they implement are simple, and can easily be
+                reimplemented in daemons if it is important to support
+                this interface without using the reference
+                implementation.</para>
+
+                <para>Internally, these function use a combination of
+                <filename>fstat()</filename> and
+                <filename>getsockname()</filename> to check the file
+                descriptor type and where it is bound to.</para>
+
+                <para>For details about the algorithms check the
+                liberally licensed reference implementation sources:
+                <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c"/>
+                and <ulink
+                url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h"/></para>
+
+                <para><function>sd_is_fifo()</function> and the
+                related functions are implemented in the reference
+                implementation's <filename>sd-daemon.c</filename> and
+                <filename>sd-daemon.h</filename> files. These
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-daemon</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file. Alternatively, applications consuming these APIs
+                may copy the implementation into their source
+                tree. For more details about the reference
+                implementation see
+                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>These functions continue to work as described,
+                even if -DDISABLE_SYSTEMD is set during
+                compilation.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_add_match.xml b/man/sd_journal_add_match.xml
new file mode 100644 (file)
index 0000000..ad2486d
--- /dev/null
@@ -0,0 +1,189 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_add_match">
+
+        <refentryinfo>
+                <title>sd_journal_add_match</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_add_match</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_add_match</refname>
+                <refname>sd_journal_add_disjunction</refname>
+                <refname>sd_journal_flush_matches</refname>
+                <refpurpose>Add or remove entry matches</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_add_match</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const void* <parameter>data</parameter></paramdef>
+                                <paramdef>size_t <parameter>size</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_add_disjunction</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_flush_matches</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_add_match()</function> adds
+                a match by which to filter the entries of the journal
+                file. Matches applied with this call will filter what
+                can be iterated through and read from the journal file
+                via calls like
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>. Matches
+                are of the form <literal>FIELD=value</literal>, where
+                the field part is a short uppercase string consisting
+                only of 0-9, A-Z and the underscore. It may not begin
+                with two underscores or be the empty string. The value
+                part may be any value, including binary. If a match is
+                applied only entries with this field set will be
+                iterated. Multiple matches may be active at the same
+                time: if they apply to different fields only entries
+                with both fields set like this will be iterated, if
+                they apply to the same fields only entries where the
+                field takes one of the specified values will be
+                iterated. Well known fields are documented in
+                <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Whenever
+                a new match is added the current entry position is
+                reset, and
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry> (or a similar call)
+                needs to be called before entries can be read
+                again.</para>
+
+                <para><function>sd_journal_add_disjunction()</function>
+                may be used to insert a disjunction (i.e. logical OR)
+                in the match list. If this call is invoked all
+                previously added matches are combined in an OR with
+                all matches added afterwards, until
+                <function>sd_journal_add_disjunction()</function> is
+                invoked again to begin the next OR term. The
+                combination of
+                <function>sd_journal_add_match()</function> and
+                <function>sd_journal_add_disjunction()</function> may
+                be used to build complex search terms, even though
+                full logical expressions are not available.</para>
+
+                <para><function>sd_journal_flush_matches()</function>
+                may be used to flush all matches and disjunction terms
+                again. After this call all filtering is removed and
+                all entries in the journal will be iterated
+                again.</para>
+
+                <para>Note that filtering via matches only applies to
+                the way the journal is read, it has no effect on storage
+                on disk.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_add_match()</function> and
+                <function>sd_journal_add_disjunction()</function>
+                return 0 on success or a negative errno-style error
+                code. <function>sd_journal_flush_matches()</function>
+                returns nothing.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_add_match()</function>,
+                <function>sd_journal_add_disjunction()</function> and
+                <function>sd_journal_flush_matches()</function> interfaces are
+                available as shared library, which can be compiled and
+                linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <para>The following example adds matches to a journal
+                context object to iterate only through messages
+                generated by the Avahi service at the four error log
+                levels, plus all messages of the message ID
+                03bb1dab98ab4ecfbf6fff2738bdd964 coming from any
+                service (this example lacks the necessary error
+                checking):</para>
+
+                <programlisting>...
+int add_matches(sd_journal *j) {
+        sd_journal_add_match(j, "_SYSTEMD_UNIT=avahi-daemon.service", 0);
+        sd_journal_add_match(j, "PRIORITY=0", 0);
+        sd_journal_add_match(j, "PRIORITY=1", 0);
+        sd_journal_add_match(j, "PRIORITY=2", 0);
+        sd_journal_add_match(j, "PRIORITY=3", 0);
+        sd_journal_add_disjunction(j);
+        sd_journal_add_match(j, "MESSAGE_ID=03bb1dab98ab4ecfbf6fff2738bdd964", 0);
+}</programlisting>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml
new file mode 100644 (file)
index 0000000..fa9bbc9
--- /dev/null
@@ -0,0 +1,136 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_get_catalog">
+
+        <refentryinfo>
+                <title>sd_journal_get_catalog</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_get_catalog</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_get_catalog</refname>
+                <refname>sd_journal_get_catalog_for_message_id</refname>
+                <refpurpose>Retrieve message catalog entry</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_catalog</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const char** <parameter>ret</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_catalog_for_message_id</function></funcdef>
+                                <paramdef>sd_id128_t <parameter>id</parameter></paramdef>
+                                <paramdef>const char** <parameter>ret</parameter></paramdef>
+                        </funcprototype>
+
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_get_catalog()</function>
+                retrieves a message catalog entry for the current
+                journal entry. This will look up an entry in the
+                message catalog by using the
+                <literal>MESSAGE_ID=</literal> field of the current
+                journal entry. Before returning the entry all journal
+                field names in the catalog entry text enclosed in "@"
+                will be replaced by the respective field values of the
+                current entry. If a field name referenced in the
+                message catalog entry does not exist it the current
+                journal entry the "@" will be removed but the field
+                name otherwise left untouched.</para>
+
+                <para><function>sd_journal_get_catalog_for_message_id()</function>
+                works similar to
+                <function>sd_journal_get_catalog()</function> but the
+                entry is looked up by the specified message ID (no
+                open journal context is necessary for this), and no
+                field substitution is done.</para>
+
+                <para>For more information about the journal message
+                catalog please refer to the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/catalog">Journal
+                Message Catalogs</ulink> documentation page.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_get_catalog()</function>
+                and
+                <function>sd_journal_get_catalog_for_message_id()</function>
+                returns 0 on success or a negative errno-style error
+                code. If no matching message catalog entry is found
+                -ENOENT is returned.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_get_catalog()</function> and
+                <function>sd_journal_get_catalog_for_message_id()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_get_cursor.xml b/man/sd_journal_get_cursor.xml
new file mode 100644 (file)
index 0000000..354168b
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_get_cursor">
+
+        <refentryinfo>
+                <title>sd_journal_get_cursor</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_get_cursor</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_get_cursor</refname>
+                <refname>sd_journal_test_cursor</refname>
+                <refpurpose>Get cursor string for or test cursor string against the current journal entry</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_cursor</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>char ** <parameter>cursor</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_test_cursor</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const char * <parameter>cursor</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_get_cursor()</function>
+                returns a cursor string for the current journal
+                entry. A cursor is a serialization of the current
+                journal position formatted as text. The string only
+                contains printable characters and can be passed around
+                in text form. The cursor identifies a journal entry
+                globally and in a stable way and may be used to later
+                seek to it via
+                <citerefentry><refentrytitle>sd_journal_seek_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>. The
+                cursor string should be considered opaque and not be
+                parsed by clients. Seeking to a cursor position
+                without the specific entry being available locally
+                will seek to the next closest (in terms of time)
+                available entry. The call takes two arguments: a
+                journal context object and a pointer to a string
+                pointer where the cursor string will be placed. The
+                string is allocated via libc
+                <citerefentry><refentrytitle>malloc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and should be freed after use with
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>Note that
+                <function>sd_journal_get_cursor()</function> will not
+                work before
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                (or related call) has been called at least once, in
+                order to position the read pointer at a valid
+                entry.</para>
+
+                <para><function>sd_journal_test_cursor()</function>
+                may be used to check whether the current position in
+                the journal matches the specified cursor. This is
+                useful since cursor strings do not uniquely identify
+                an entry: the same entry might be referred to by
+                multiple different cursor strings, and hence string
+                comparing cursors is not possible. Use this call to
+                verify after an invocation of
+                <citerefentry><refentrytitle>sd_journal_seek_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                whether the entry being seeked to was actually found
+                in the journal or the next closest entry was used
+                instead.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_get_cursor()</function>
+                returns 0 on success or a negative errno-style error
+                code. <function>sd_journal_test_cursor()</function>
+                returns positive if the current entry matches the
+                specified cursor, 0 if it doesn't match the specified
+                cursor or a negative errno-style error code on
+                failure.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_get_cursor()</function>
+                and <function>sd_journal_test_cursor()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_seek_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_get_cutoff_realtime_usec.xml b/man/sd_journal_get_cutoff_realtime_usec.xml
new file mode 100644 (file)
index 0000000..ed014cb
--- /dev/null
@@ -0,0 +1,142 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_get_cutoff_realtime_usec">
+
+        <refentryinfo>
+                <title>sd_journal_get_cutoff_realtime_usec</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_get_cutoff_realtime_usec</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_get_cutoff_realtime_usec</refname>
+                <refname>sd_journal_get_cutoff_monotonic_usec</refname>
+                <refpurpose>Read cut-off timestamps from the current journal entry</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_cutoff_realtime_usec</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t* <parameter>from</parameter></paramdef>
+                                <paramdef>uint64_t* <parameter>to</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_cutoff_monotonic_usec</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>sd_id128_t <parameter>boot_id</parameter></paramdef>
+                                <paramdef>uint64_t* <parameter>from</parameter></paramdef>
+                                <paramdef>uint64_t* <parameter>to</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_get_cutoff_realtime_usec()</function>
+                gets the realtime (wallclock) timestamps of the first
+                and last entries accessible in the journal.  It takes
+                three arguments: the journal context object and two
+                pointers to 64 Bit unsigned integers to store the
+                timestamps in. The timestamps are in microseconds
+                since the epoch, i.e. CLOCK_REALTIME. Either one of
+                the two timestamp arguments may be passed as NULL in
+                case the timestamp is not needed, but not both.</para>
+
+                <para><function>sd_journal_get_cutoff_monotonic_usec()</function>
+                gets the monotonic timestamps of the first and last
+                entries accessible in the journal. It takes three
+                arguments: the journal context object, a 128 Bit
+                identifier for the boot, and two pointers to 64 Bit
+                unsigned integers to store the timestamps. The
+                timestamps are in microseconds since boot-up of the
+                specific boot, i.e. CLOCK_MONOTONIC. Since the
+                monotonic clock begins new with every reboot it only
+                defines a well-defined point in time when used
+                together with an identifier identifying the boot, see
+                <citerefentry><refentrytitle>sd_id128_get_boot</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information. The function will return the
+                timestamps for the boot identified by the passed boot
+                ID. Either one of the two timestamp arguments may be
+                passed as NULL in case the timestamp is not needed,
+                but not both.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_get_cutoff_realtime_usec()</function>
+                and
+                <function>sd_journal_get_cutoff_monotonic_usec()</function>
+                return 1 on success, 0 if not suitable entries are in
+                the journal or a negative errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The
+                <function>sd_journal_get_cutoff_realtime_usec()</function>
+                and
+                <function>sd_journal_get_cutoff_monotonic_usec()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_id128_get_boot</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_get_data.xml b/man/sd_journal_get_data.xml
new file mode 100644 (file)
index 0000000..1259b0c
--- /dev/null
@@ -0,0 +1,251 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_get_data">
+
+        <refentryinfo>
+                <title>sd_journal_get_data</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_get_data</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_get_data</refname>
+                <refname>sd_journal_enumerate_data</refname>
+                <refname>sd_journal_restart_data</refname>
+                <refname>SD_JOURNAL_FOREACH_DATA</refname>
+                <refname>sd_journal_set_data_threshold</refname>
+                <refname>sd_journal_get_data_threshold</refname>
+                <refpurpose>Read data fields from the current journal entry</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_data</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const char* <parameter>field</parameter></paramdef>
+                                <paramdef>const void** <parameter>data</parameter></paramdef>
+                                <paramdef>size_t* <parameter>length</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_enumerate_data</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const void** <parameter>data</parameter></paramdef>
+                                <paramdef>size_t* <parameter>length</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>void <function>sd_journal_restart_data</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef><function>SD_JOURNAL_FOREACH_DATA</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const void* <parameter>data</parameter></paramdef>
+                                <paramdef>size_t <parameter>length</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_set_data_threshold</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>size_t <parameter>sz</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_data_threshold</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>size_t* <parameter>sz</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_get_data()</function> gets
+                the data object associated with a specific field from
+                the current journal entry. It takes four arguments:
+                the journal context object, a string with the field
+                name to request, plus a pair of pointers to
+                pointer/size variables where the data object and its
+                size shall be stored in. The field name should be an
+                entry field name. Well-known field names are listed in
+                <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The
+                returned data is in a read-only memory map and is only
+                valid until the next invocation of
+                <function>sd_journal_get_data()</function> or
+                <function>sd_journal_enumerate_data()</function>, or
+                the read pointer is altered. Note that the data
+                returned will be prefixed with the field name and
+                '='. Also note that by default data fields larger than
+                64K might get truncated to 64K. This threshold may be
+                changed and turned off with
+                <function>sd_journal_set_data_threshold()</function> (see
+                below).</para>
+
+                <para><function>sd_journal_enumerate_data()</function>
+                may be used to iterate through all fields of the
+                current entry. On each invocation the data for the
+                next field is returned. The order of these fields is
+                not defined. The data returned is in the same format
+                as with <function>sd_journal_get_data()</function> and
+                also follows the same life-time semantics.</para>
+
+                <para><function>sd_journal_restart_data()</function>
+                resets the data enumeration index to the beginning of
+                the entry. The next invocation of
+                <function>sd_journal_enumerate_data()</function> will return the first
+                field of the entry again.</para>
+
+                <para>Note that the
+                <function>SD_JOURNAL_FOREACH_DATA()</function> macro
+                may be used as a handy wrapper around
+                <function>sd_journal_restart_data()</function> and
+                <function>sd_journal_enumerate_data()</function>.</para>
+
+                <para>Note that these functions will not work before
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                (or related call) has been called at least
+                once, in order to position the read pointer at a valid entry.</para>
+
+                <para><function>sd_journal_set_data_threshold()</function>
+                may be used to change the data field size threshold
+                for data returned by
+                <function>sd_journal_get_data()</function>,
+                <function>sd_journal_enumerate_data()</function> and
+                <function>sd_journal_enumerate_unique()</function>. This
+                threshold is a hint only: it indicates that the client
+                program is interested only in the initial parts of the
+                data fields, up to the threshold in size -- but the
+                library might still return larger data objects. That
+                means applications should not rely exclusively on this
+                setting to limit the size of the data fields returned,
+                but need to apply a explicit size limit on the
+                returned data as well. This threshold defaults to 64K
+                by default. To retrieve the complete data fields this
+                threshold should be turned off by setting it to 0, so
+                that the library always returns the complete data
+                objects. It is recommended to set this threshold as
+                low as possible since this relieves the library from
+                having to decompress large compressed data objects in
+                full.</para>
+
+                <para><function>sd_journal_get_data_threshold()</function>
+                returns the currently configured data field size
+                threshold.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_get_data()</function>
+                returns 0 on success or a negative errno-style error
+                code. If the current entry does not include the
+                specified field -ENOENT is returned. If
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                has not been called at least once -EADDRNOTAVAIL is
+                returned. <function>sd_journal_enumerate_data()</function>
+                returns a positive integer if the next field has been
+                read, 0 when no more fields are known, or a negative
+                errno-style error
+                code. <function>sd_journal_restart_data()</function>
+                returns
+                nothing. <function>sd_journal_set_data_threshold()</function>
+                and <function>sd_journal_get_threshold()</function>
+                return 0 on success or a negative errno-style error
+                code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_get_data()</function>,
+                <function>sd_journal_enumerate_data()</function>,
+                <function>sd_journal_restart_data()</function>,
+                <function>sd_journal_set_data_threshold()</function>
+                and
+                <function>sd_journal_get_data_threshold()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <para>See
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for a complete example how to use
+                <function>sd_journal_get_data()</function>.</para>
+
+                <para>Use the
+                <function>SD_JOURNAL_FOREACH_DATA</function> macro to
+                iterate through all fields of the current journal
+                entry:</para>
+
+                <programlisting>...
+int print_fields(sd_journal *j) {
+        const void *data;
+        size_t l;
+        SD_JOURNAL_FOREACH_DATA(j, data, length)
+                printf("%.*s\n", (int) length, data);
+}
+...</programlisting>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_query_unique</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml
new file mode 100644 (file)
index 0000000..189d213
--- /dev/null
@@ -0,0 +1,272 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_get_fd">
+
+        <refentryinfo>
+                <title>sd_journal_get_fd</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_get_fd</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_get_fd</refname>
+                <refname>sd_journal_reliable_fd</refname>
+                <refname>sd_journal_process</refname>
+                <refname>sd_journal_wait</refname>
+                <refname>SD_JOURNAL_NOP</refname>
+                <refname>SD_JOURNAL_APPEND</refname>
+                <refname>SD_JOURNAL_INVALIDATE</refname>
+                <refpurpose>Journal change notification
+                interface</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_fd</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_reliable_fd</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_process</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_wait</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t <parameter>timeout_usec</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_get_fd()</function> returns
+                a file descriptor that may be asynchronously polled in
+                an external event loop and is signaled readable as
+                soon as the journal changes, because new entries or
+                files were added, rotation took place, or files have
+                been deleted, and similar. The file descriptor is
+                suitable for usage in
+                <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                where it will yield POLLIN on changes. The call takes
+                one argument: the journal context object. Note that
+                not all file systems are capable of generating the
+                necessary events for wakeups from this file descriptor
+                to be enirely reliable. In particular network files
+                systems do not generate suitable file change events in
+                all cases. In such a case an application should not
+                rely alone on wake-ups from this file descriptor but
+                wake up and recheck the journal in regular time
+                intervals, for example every 2s. To detect
+                cases where this is necessary, use
+                <function>sd_journal_reliable_fd()</function>,
+                below.</para>
+
+                <para><function>sd_journal_reliable_fd()</function>
+                may be used to check whether the wakeup events from
+                the file descriptor returned by
+                <function>sd_journal_get_fd</function> are sufficient
+                to track changes to the journal. If this call returns
+                0, it is necessary to regularly recheck for journal
+                changes (suggestion: every 2s). If this call returns a
+                positive integer this is not necessary, and wakeups
+                from the file descriptor returned by
+                <function>sd_journal_get_fd()</function> are
+                sufficient as only source for wake-ups.</para>
+
+                <para>After each POLLIN wake-up
+                <function>sd_journal_process()</function> needs to be
+                called to process events and reset the readable state
+                of the file descriptor. This call will also indicate
+                what kind of change has been detected (see below; note
+                that spurious wake-ups are possible).</para>
+
+                <para>A synchronous alternative for using
+                <function>sd_journal_get_fd()</function>,
+                <function>sd_journal_reliable_fd()</function> and
+                <function>sd_journal_process()</function> is
+                <function>sd_journal_wait()</function>. It will
+                synchronously wait until the journal gets changed,
+                possibly using a 2s time-out if this is necessary (see
+                above). In either way the maximum time this call
+                sleeps may be controlled with the
+                <parameter>timeout_usec</parameter> parameter. Pass
+                <literal>(uint64_t) -1</literal> to wait
+                indefinitely. Internally this call simply combines
+                <function>sd_journal_get_fd()</function>,
+                <function>sd_journal_reliable_fd()</function>,
+                <function>poll()</function> and
+                <function>sd_journal_process()</function> into
+                one.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_get_fd()</function> returns a valid file descriptor on success or a negative errno-style error
+                code.</para>
+
+                <para><function>sd_journal_reliable_fd()</function>
+                returns a positive integer if the file descriptor
+                returned by <function>sd_journal_get_fd()</function>
+                is sufficient as sole wake-up source for journal
+                change events. Returns 0 if it is not sufficient and
+                the journal needs to be checked manually in regular
+                time intervals for changes. Returns a negative
+                errno-style error code on failure.</para>
+
+                <para><function>sd_journal_process()</function> and
+                <function>sd_journal_wait()</function> return one of
+                <literal>SD_JOURNAL_NOP</literal>,
+                <literal>SD_JOURNAL_APPEND</literal> or
+                <literal>SD_JOURNAL_INVALIDATE</literal> on success or
+                a negative errno-style error code. If
+                <literal>SD_JOURNAL_NOP</literal> is returned the
+                journal didn't change since the last invocation. If
+                <literal>SD_JOURNAL_APPEND</literal> is returned new
+                entries have been appended to the end of the
+                journal. If <literal>SD_JOURNAL_INVALIDATE</literal>
+                journal files were added or removed (possibly due to
+                rotation). In the latter event live-view UIs should
+                probably refresh their entire display while in the
+                case of <literal>SD_JOURNAL_APPEND</literal> it is
+                sufficient to simply continue reading at the previous
+                end of the journal.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_get_fd()</function>,
+                <function>sd_journal_reliable_fd()</function>,
+                <function>sd_journal_process()</function> and
+                <function>sd_journal_wait()</function> interfaces are
+                available as shared library, which can be compiled and
+                linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <para>Iterating through the journal, in a live view tracking all changes:</para>
+
+                <programlisting>#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;systemd/sd-journal.h&gt;
+
+int main(int argc, char *argv[]) {
+        int r;
+        sd_journal *j;
+        r = sd_journal_open(&amp;j, SD_JOURNAL_LOCAL_ONLY);
+        if (r &lt; 0) {
+                fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
+                return 1;
+        }
+        for (;;)  {
+                const char *d;
+                size_t l;
+                r = sd_journal_next(j);
+                if (r &lt; 0) {
+                        fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
+                        break;
+                }
+                if (r == 0) {
+                        /* Reached the end, let's wait for changes, and try again */
+                        r = sd_journal_wait(j, (uint64_t) -1);
+                        if (r &lt; 0) {
+                                fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
+                                break;
+                        }
+                        continue;
+                }
+                r = sd_journal_get_data(j, "MESSAGE", &amp;d, &amp;l);
+                if (r &lt; 0) {
+                        fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
+                        continue;
+                }
+                printf("%.*s\n", (int) l, d);
+        }
+        sd_journal_close(j);
+        return 0;
+}</programlisting>
+
+                <para>Waiting with <function>poll()</function> (this
+                example lacks all error checking for the sake of
+                simplicity):</para>
+
+                <programlisting>#include &lt;sys/poll.h&gt;
+#include &lt;systemd/sd-journal.h&gt;
+
+int wait_for_changes(sd_journal *j) {
+        struct pollfd pollfd;
+        pollfd.fd = sd_journal_get_fd();
+        pollfd.events = POLLIN;
+        poll(&amp;pollfd, 1, sd_journal_reliable_fd() &gt; 0 ? -1 : 2000);
+        return sd_journal_process(j);
+}
+                </programlisting>
+        </refsect1>
+
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_get_realtime_usec.xml b/man/sd_journal_get_realtime_usec.xml
new file mode 100644 (file)
index 0000000..515932c
--- /dev/null
@@ -0,0 +1,146 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_get_realtime_usec">
+
+        <refentryinfo>
+                <title>sd_journal_get_realtime_usec</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_get_realtime_usec</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_get_realtime_usec</refname>
+                <refname>sd_journal_get_monotonic_usec</refname>
+                <refpurpose>Read timestamps from the current journal entry</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_realtime_usec</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t* <parameter>usec</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_monotonic_usec</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t* <parameter>usec</parameter></paramdef>
+                                <paramdef>sd_id128_t* <parameter>boot_id</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_get_realtime_usec()</function>
+                gets the realtime (wallclock) timestamp of the
+                current journal entry.  It takes two arguments: the
+                journal context object and a pointer to a 64 Bit
+                unsigned integer to store the timestamp in. The
+                timestamp is in microseconds since the epoch,
+                i.e. CLOCK_REALTIME.</para>
+
+                <para><function>sd_journal_get_monotonic_usec()</function>
+                gets the monotonic timestamp of the current
+                journal entry.  It takes three arguments: the journal
+                context object, a pointer to a 64 Bit unsigned integer
+                to store the timestamp in as well as a 128 Bit ID
+                buffer to store the boot ID of the monotonic timestamp
+                in. The timestamp is in microseconds since boot-up of
+                the specific boot, i.e. CLOCK_MONOTONIC. Since the
+                monotonic clock begins new with every reboot it only
+                defines a well-defined point in time when used
+                together with an identifier identifying the boot, see
+                <citerefentry><refentrytitle>sd_id128_get_boot</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information. If the boot ID parameter is
+                passed NULL the function will fail if the monotonic
+                timestamp of the current entry is not of the current
+                system boot.</para>
+
+                <para>Note that these functions will not work before
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                (or related call) has been called at least
+                once, in order to position the read pointer at a valid entry.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_get_realtime_usec()</function>
+                and
+                <function>sd_journal_get_monotonic_usec()</function>
+                returns 0 on success or a negative errno-style error
+                code. If the boot ID parameter was passed NULL and the
+                monotonic timestamp of the current journal entry is
+                not of the current system boot, -ESTALE is returned by <function>sd_journal_get_monotonic_usec()</function>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The
+                <function>sd_journal_get_realtime_usec()</function>
+                and
+                <function>sd_journal_get_monotonic_usec()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_id128_get_boot</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_cutoff_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_get_usage.xml b/man/sd_journal_get_usage.xml
new file mode 100644 (file)
index 0000000..14eb1e2
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_get_usage">
+
+        <refentryinfo>
+                <title>sd_journal_get_usage</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_get_usage</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_get_usage</refname>
+                <refpurpose>Journal disk usage</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_get_usage</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t* <parameter>bytes</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_get_usage()</function>
+                determines the total disk space currently used up by
+                journal files. If
+                <literal>SD_JOURNAL_LOCAL_ONLY</literal> has been
+                passed when opening the journal files this value will
+                only reflect the size of journal files of the local
+                host, otherwise of all hosts.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_get_usage()</function>
+                returns 0 on success or a negative errno-style error
+                code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_get_usage()</function>
+                interface is available as shared library, which can be
+                compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_next.xml b/man/sd_journal_next.xml
new file mode 100644 (file)
index 0000000..9b1cb1f
--- /dev/null
@@ -0,0 +1,214 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_next">
+
+        <refentryinfo>
+                <title>sd_journal_next</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_next</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_next</refname>
+                <refname>sd_journal_previous</refname>
+                <refname>sd_journal_next_skip</refname>
+                <refname>sd_journal_previous_skip</refname>
+                <refname>SD_JOURNAL_FOREACH</refname>
+                <refname>SD_JOURNAL_FOREACH_BACKWARDS</refname>
+                <refpurpose>Advance or set back the read pointer in the journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_next</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_previous</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_next_skip</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t <parameter>skip</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_previous_skip</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t <parameter>skip</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef><function>SD_JOURNAL_FOREACH</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef><function>SD_JOURNAL_FOREACH_BACKWARDS</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_next()</function> advances
+                the read pointer into the journal by one entry. The
+                only argument taken is a journal context object as
+                allocated via
+                <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>. After
+                successful invocation the entry may be read with
+                functions such as
+                <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>Similar, <function>sd_journal_previous()</function> sets
+                the read pointer back one entry.</para>
+
+                <para><function>sd_journal_next_skip()</function> and
+                <function>sd_journal_previous_skip()</function>
+                advance/set back the read pointer by multiple entries
+                at once, as specified in the <varname>skip</varname>
+                parameter.</para>
+
+                <para>The journal is strictly ordered by reception
+                time, and hence advancing to the next entry guarantees
+                that the entry then pointing to is later in time than
+                then previous one, or has the same timestamp.</para>
+
+                <para>Note that
+                <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and related calls will fail unless
+                <function>sd_journal_next()</function> has been
+                invoked at least once in order to position the read
+                pointer on a journal entry.</para>
+
+                <para>Note that the
+                <function>SD_JOURNAL_FOREACH()</function> macro may be used
+                as a wrapper around
+                <citerefentry><refentrytitle>sd_journal_seek_head</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and <function>sd_journal_next()</function> in order to
+                make iterating through the journal easier. See below
+                for an example. Similar,
+                <function>SD_JOURNAL_FOREACH_BACKWARDS()</function>
+                may be used for iterating the journal in reverse
+                order.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>The four calls return the number of entries
+                advanced/set back on success or a negative errno-style
+                error code. When the end or beginning of the journal
+                is reached, a number smaller than requested is
+                returned. More specifically, if
+                <function>sd_journal_next()</function> or
+                <function>sd_journal_previous()</function> reach the
+                end/beginning of the journal they will return 0,
+                instead of 1 when they are successful. This should be
+                considered an EOF marker.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_next()</function>, <function>sd_journal_previous()</function>,
+                <function>sd_journal_next_skip()</function> and
+                <function>sd_journal_previous_skip()</function> interfaces are
+                available as shared library, which can be compiled and
+                linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <para>Iterating through the journal:</para>
+
+                <programlisting>#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;systemd/sd-journal.h&gt;
+
+int main(int argc, char *argv[]) {
+        int r;
+        sd_journal *j;
+        r = sd_journal_open(&amp;j, SD_JOURNAL_LOCAL_ONLY);
+        if (r &lt; 0) {
+                fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
+                return 1;
+        }
+        SD_JOURNAL_FOREACH(j) {
+                const char *d;
+                size_t l;
+
+                r = sd_journal_get_data(j, "MESSAGE", &amp;d, &amp;l);
+                if (r &lt; 0) {
+                        fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
+                        continue;
+                }
+
+                printf("%.*s\n", (int) l, d);
+        }
+        sd_journal_close(j);
+        return 0;
+}</programlisting>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml
new file mode 100644 (file)
index 0000000..76b857b
--- /dev/null
@@ -0,0 +1,184 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_open">
+
+        <refentryinfo>
+                <title>sd_journal_open</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_open</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_open</refname>
+                <refname>sd_journal_open_directory</refname>
+                <refname>sd_journal_close</refname>
+                <refname>sd_journal</refname>
+                <refname>SD_JOURNAL_LOCAL_ONLY</refname>
+                <refname>SD_JOURNAL_RUNTIME_ONLY</refname>
+                <refname>SD_JOURNAL_SYSTEM_ONLY</refname>
+                <refpurpose>Open the system journal for reading</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_open</function></funcdef>
+                                <paramdef>sd_journal** <parameter>ret</parameter></paramdef>
+                                <paramdef>int <parameter>flags</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_open_directory</function></funcdef>
+                                <paramdef>sd_journal** <parameter>ret</parameter></paramdef>
+                                <paramdef>const char* <parameter>path</parameter></paramdef>
+                                <paramdef>int <parameter>flags</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>void <function>sd_journal_close</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_open()</function> opens
+                the log journal for reading. It will find all journal
+                files automatically and interleave them automatically
+                when reading. As first argument it takes a pointer to
+                a <literal>sd_journal</literal> pointer, which on
+                success will contain journal context object afterwards. The
+                second argument is a flags field, which may consist of
+                the following flags ORed together:
+                <literal>SD_JOURNAL_LOCAL_ONLY</literal> makes sure
+                only journal files generated on the local machine will
+                be opened. <literal>SD_JOURNAL_RUNTIME_ONLY</literal>
+                makes sure only volatile journal files will be opened,
+                excluding those which are stored on persistent
+                storage. <literal>SD_JOURNAL_SYSTEM_ONLY</literal>
+                will ensure that only journal files of system services
+                and the kernel (in opposition to user session processes) will
+                be opened.</para>
+
+                <para><function>sd_journal_open_directory()</function>
+                is similar to <function>sd_journal_open()</function>
+                but takes an absolute directory path as argument. All
+                journal files in this directory will be opened and
+                interleaved automatically. This call also takes a
+                flags argument, but it must be passed as 0 as no flags
+                are currently understood for this call.</para>
+
+                <para><function>sd_journal_close()</function> will
+                close the journal context allocated with
+                <function>sd_journal_open()</function> or
+                <function>sd_journal_open_directory()</function> and
+                free its resources.</para>
+
+                <para>When opening the journal only journal files
+                accessible to the calling user will be opened. If
+                journal files are not accessible to the caller this
+                will be silently ignored.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for an example how to iterate through the journal
+                after opening it with
+                <function>sd_journal_open()</function>.</para>
+
+                <para>A journal context object returned by
+                <function>sd_journal_open()</function> references a
+                specific journal entry as <emphasis>current</emphasis> entry,
+                similar to a file seek index in a classic file system
+                file, but without absolute positions. It may be
+                altered with
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>sd_journal_seek_head</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and related calls. The current entry position may be
+                exported in <emphasis>cursor</emphasis> strings, as accessible
+                via
+                <citerefentry><refentrytitle>sd_journal_get_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>. Cursor
+                strings may be used to globally identify a specific
+                journal entry in a stable way and then later to seek
+                to it (or if the specific entry is not available
+                locally, to its closest entry in time)
+                <citerefentry><refentrytitle>sd_journal_seek_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>Notification of journal changes is available via
+                <function>sd_journal_get_fd()</function> and related
+                calls.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>The <function>sd_journal_open()</function> and
+                <function>sd_journal_open_directory()</function> calls
+                return 0 on success or a negative errno-style error
+                code. <function>sd_journal_close()</function> returns
+                nothing.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_open()</function>,
+                <function>sd_journal_open_directory()</function> and
+                <function>sd_journal_close()</function> interfaces are
+                available as shared library, which can be compiled and
+                linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml
new file mode 100644 (file)
index 0000000..7742268
--- /dev/null
@@ -0,0 +1,251 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_print">
+
+        <refentryinfo>
+                <title>sd_journal_print</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_print</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_print</refname>
+                <refname>sd_journal_printv</refname>
+                <refname>sd_journal_send</refname>
+                <refname>sd_journal_sendv</refname>
+                <refname>sd_journal_perror</refname>
+                <refname>SD_JOURNAL_SUPPRESS_LOCATION</refname>
+                <refpurpose>Submit log entries to the journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_print</function></funcdef>
+                                <paramdef>int <parameter>priority</parameter></paramdef>
+                                <paramdef>const char* <parameter>format</parameter></paramdef>
+                                <paramdef>...</paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_printv</function></funcdef>
+                                <paramdef>int <parameter>priority</parameter></paramdef>
+                                <paramdef>const char* <parameter>format</parameter></paramdef>
+                                <paramdef>va_list <parameter>ap</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_send</function></funcdef>
+                                <paramdef>const char* <parameter>format</parameter></paramdef>
+                                <paramdef>...</paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_sendv</function></funcdef>
+                                <paramdef>const struct iovec *<parameter>iov</parameter></paramdef>
+                                <paramdef>int <parameter>n</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_perror</function></funcdef>
+                                <paramdef>const char* <parameter>message</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_print()</function> may be
+                used to submit simple, plain text log entries to the
+                system journal. The first argument is a priority
+                value. This is followed by a format string and its
+                parameters, similar to
+                <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                or
+                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. The
+                priority value is one of
+                <literal>LOG_EMERG</literal>,
+                <literal>LOG_ALERT</literal>,
+                <literal>LOG_CRIT</literal>,
+                <literal>LOG_ERR</literal>,
+                <literal>LOG_WARNING</literal>,
+                <literal>LOG_NOTICE</literal>,
+                <literal>LOG_INFO</literal>,
+                <literal>LOG_DEBUG</literal>, as defined in
+                <filename>syslog.h</filename>, see
+                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for details. It is recommended to use this call to
+                submit log messages in the application locale or system
+                locale and in UTF-8 format, but no such restrictions
+                are enforced.</para>
+
+                <para><function>sd_journal_printv()</function> is
+                similar to <function>sd_journal_print()</function> but
+                takes a variable argument list encapsulated in an
+                object of type <literal>va_list</literal> (see
+                <citerefentry><refentrytitle>stdarg</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information) instead of the format string. It
+                is otherwise equivalent in behavior.</para>
+
+                <para><function>sd_journal_send()</function> may be
+                used to submit structured log entries to the system
+                journal. It takes a series of format strings, each
+                immediately followed by their associated parameters,
+                terminated by NULL. The strings passed should be of
+                the format <literal>VARIABLE=value</literal>. The
+                variable name must be in uppercase and consist only of
+                characters, numbers and underscores, and may not begin
+                with an underscore. (All assignments that do not
+                follow this syntax will be ignored.) The value can be
+                of any size and format. It is highly recommended to
+                submit text strings formatted in the UTF-8 character
+                encoding only, and submit binary fields only when
+                formatting in UTf-8 strings is not sensible. A number
+                of well known fields are defined, see
+                <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                for details, but additional application defined fields
+                may be used. A variable may be assigned more than one
+                value per entry.</para>
+
+                <para><function>sd_journal_sendv()</function> is
+                similar to <function>sd_journal_send()</function> but
+                takes an array of <literal>struct iovec</literal> (as
+                defined in <filename>uio.h</filename>, see
+                <citerefentry><refentrytitle>readv</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for details) instead of the format string. Each
+                structure should reference one field of the entry to
+                submit. The second argument specifies the number of
+                structures in the
+                array. <function>sd_journal_sendv()</function> is
+                particularly useful to submit binary objects to the
+                journal where that is necessary.</para>
+
+                <para><function>sd_journal_perror()</function> is a
+                similar to
+                <citerefentry><refentrytitle>perror</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and writes a message to the journal that consists of
+                the passed string, suffixed with ": " and a human
+                readable representation of the current error code
+                stored in
+                <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
+                the message string is passed as NULL or empty string
+                only the error string representation will be written,
+                prefixed with nothing. An additional journal field
+                ERRNO= is included in the entry containing the numeric
+                error code formatted as decimal string. The log
+                priority used is <literal>LOG_ERR</literal> (3).</para>
+
+                <para>Note that <function>sd_journal_send()</function>
+                is a wrapper around
+                <function>sd_journal_sendv()</function> to make it
+                easier to use when only text strings shall be
+                submitted. Also, the following two calls are
+                mostly equivalent:</para>
+
+                <programlisting>sd_journal_print(LOG_INFO, "Hello World, this is PID %lu!", (unsigned long) getpid());
+
+sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(),
+                "PRIORITY=%i", LOG_INFO,
+                NULL);</programlisting>
+
+                <para>Note that these calls implicitly add fields for
+                the source file, function name and code line where
+                invoked. This is implemented with macros. If this is
+                not desired it can be turned off by defining
+                SD_JOURNAL_SUPPRESS_LOCATION before including
+                <filename>sd-journal.h</filename>.</para>
+
+                <para><citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                and <function>sd_journal_print()</function> may
+                largely be used interchangeably
+                functionality-wise. However, note that log messages
+                logged via the former take a different path to the
+                journal server than the later, and hence global
+                chronological ordering between the two streams cannot
+                be guaranteed. Using
+                <function>sd_journal_print()</function> has the
+                benefit of logging source code line, file names, and
+                functions as meta data along all entries, and
+                guaranteeing chronological ordering with structured
+                log entries that are generated via
+                <function>sd_journal_send()</function>. Using
+                <function>syslog()</function> has the benefit of being
+                more portable.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>The four calls return 0 on success or a negative
+                errno-style error code. The
+                <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                variable itself is not altered.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_print()</function>,
+                <function>sd_journal_printv()</function>,
+                <function>sd_journal_send()</function> and
+                <function>sd_journal_sendv()</function> interfaces
+                are available as shared library, which can be compiled
+                and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_stream_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>perror</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_query_unique.xml b/man/sd_journal_query_unique.xml
new file mode 100644 (file)
index 0000000..502a7e0
--- /dev/null
@@ -0,0 +1,216 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_query_unique">
+
+        <refentryinfo>
+                <title>sd_journal_query_unique</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_query_unique</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_query_unique</refname>
+                <refname>sd_journal_enumerate_unique</refname>
+                <refname>sd_journal_restart_unique</refname>
+                <refname>SD_JOURNAL_FOREACH_UNIQUE</refname>
+                <refpurpose>Read unique data fields from the journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_query_unique</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const char* <parameter>field</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_enumerate_unique</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const void** <parameter>data</parameter></paramdef>
+                                <paramdef>size_t* <parameter>length</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>void <function>sd_journal_restart_unique</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef><function>SD_JOURNAL_FOREACH_UNIQUE</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const void* <parameter>data</parameter></paramdef>
+                                <paramdef>size_t <parameter>length</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_query_unique()</function>
+                queries the journal for all unique values the
+                specified field can take. It takes two arguments: the
+                journal to query and the field name to look
+                for. Well-known field names are listed on
+                <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Field
+                names must be specified without a trailing '='. After
+                this function has been executed successfully the field
+                values may be queried using
+                <function>sd_journal_enumerate_unique()</function>. Invoking
+                this call a second time will change the field name
+                being queried and reset the enumeration index to the
+                first field value that matches.</para>
+
+                <para><function>sd_journal_enumerate_unique()</function>
+                may be used to iterate through all data fields which
+                match the previously selected field name as set with
+                <function>sd_journal_query_unique()</function>. On
+                each invocation the next field data matching the field
+                name is returned. The order of the returned data
+                fields is not defined. It takes three arguments: the
+                journal context object, plus a pair of pointers to
+                pointer/size variables where the data object and its
+                size shall be stored in. The returned data is in a
+                read-only memory map and is only valid until the next
+                invocation of
+                <function>sd_journal_enumerate_unique()</function>. Note
+                that the data returned will be prefixed with the field
+                name and '='. Note that this call is subject to the
+                data field size threshold as controlled by
+                <function>sd_journal_set_data_threshold()</function>.</para>
+
+                <para><function>sd_journal_restart_unique()</function>
+                resets the data enumeration index to the beginning of
+                the list. The next invocation of
+                <function>sd_journal_enumerate_unique()</function>
+                will return the first field data matching the field
+                name again.</para>
+
+                <para>Note that the
+                <function>SD_JOURNAL_FOREACH_UNIQUE()</function> macro
+                may be used as a handy wrapper around
+                <function>sd_journal_restart_unique()</function> and
+                <function>sd_journal_enumerate_unique()</function>.</para>
+
+                <para>Note that these functions currently are not
+                influenced by matches set with
+                <function>sd_journal_add_match()</function> but this
+                might change in a later version of this
+                software.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para><function>sd_journal_query_unique()</function>
+                returns 0 on success or a negative errno-style error
+                code. <function>sd_journal_enumerate_unique()</function>
+                returns a positive integer if the next field data has
+                been read, 0 when no more fields are known, or a
+                negative errno-style error
+                code. <function>sd_journal_restart_unique()</function>
+                returns nothing.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_query_unique()</function>,
+                <function>sd_journal_enumerate_unique()</function> and
+                <function>sd_journal_restart_unique()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <para>Use the
+                <function>SD_JOURNAL_FOREACH_UNIQUE</function> macro
+                to iterate through all values a field of the journal
+                can take. The following example lists all unit names
+                referenced in the journal:</para>
+
+                <programlisting>#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;systemd/sd-journal.h&gt;
+
+int main(int argc, char *argv[]) {
+        sd_journal *j;
+        const void *d;
+        size_t l;
+        int r;
+
+        r = sd_journal_open(&amp;j, SD_JOURNAL_LOCAL_ONLY);
+        if (r &lt; 0) {
+                fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
+                return 1;
+        }
+        r = sd_journal_query_unique(j, "_SYSTEMD_UNIT");
+        if (r &lt; 0) {
+                fprintf(stderr, "Failed to query journal: %s\n", strerror(-r));
+                return 1;
+        }
+        SD_JOURNAL_FOREACH_UNIQUE(j, d, l)
+                printf("%.*s\n", (int) l, (const char*) d);
+        sd_journal_close(j);
+        return 0;
+}</programlisting>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_seek_head.xml b/man/sd_journal_seek_head.xml
new file mode 100644 (file)
index 0000000..3716c5d
--- /dev/null
@@ -0,0 +1,178 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_seek_head">
+
+        <refentryinfo>
+                <title>sd_journal_seek_head</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_seek_head</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_seek_head</refname>
+                <refname>sd_journal_seek_tail</refname>
+                <refname>sd_journal_seek_monotonic_usec</refname>
+                <refname>sd_journal_seek_realtime_usec</refname>
+                <refname>sd_journal_seek_cursor</refname>
+                <refpurpose>Seek to a position in the
+                journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_seek_head</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_seek_tail</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_seek_monotonic_usec</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>sd_id128_t <parameter>boot_id</parameter></paramdef>
+                                <paramdef>uint64_t <parameter>usec</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_seek_realtime_usec</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t <parameter>usec</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_seek_cursor</function></funcdef>
+                                <paramdef>sd_journal* <parameter>j</parameter></paramdef>
+                                <paramdef>const char * <parameter>cursor</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_seek_head()</function>
+                seeks to the beginning of the journal, i.e. the oldest
+                available entry.</para>
+
+                <para>Similar,
+                <function>sd_journal_seek_tail()</function> may be
+                used to seek to the end of the journal, i.e. the most
+                recent available entry.</para>
+
+                <para><function>sd_journal_seek_monotonic_usec()</function>
+                seeks to the entry with the specified monotonic
+                timestamp, i.e. CLOCK_MONOOTONIC. Since monotonic time
+                restarts on every reboot a boot ID needs to be
+                specified as well.</para>
+
+                <para><function>sd_journal_seek_realtime_usec()</function>
+                seeks to the entry with the specified realtime
+                (wallclock) timestamp, i.e. CLOCK_REALTIME. Note that
+                the realtime clock is not necessarily monotonic. If a
+                realtime timestamp is ambiguous it is not defined
+                which position is sought to.</para>
+
+                <para><function>sd_journal_seek_cursor()</function>
+                seeks to the entry located at the specified cursor
+                string. For details on cursors see
+                <citerefentry><refentrytitle>sd_journal_get_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
+                no entry matching the specified cursor is found the
+                call will seek to the next closest entry (in terms of
+                time) instead. To verify whether the newly selected
+                entry actually matches the cursor use
+                <citerefentry><refentrytitle>sd_journal_test_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>Note that these calls do not actually make any
+                entry the new current entry, this needs to be done in
+                a separate step with a subsequent
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                invocation (or a similar call). Only then entry data
+                may be retrieved via
+                <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
+                no entry exists that matches exactly the specified
+                seek address the next closest is sought to. If
+                <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                is used the closest following entry will be sought to,
+                if
+                <citerefentry><refentrytitle>sd_journal_previous</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                is used the closest preceding entry is sought
+                to.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>The functions return 0 on success or a negative
+                errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_seek_head()</function>,
+                <function>sd_journal_seek_tail()</function>,
+                <function>sd_journal_seek_monotonic_usec()</function>,
+                <function>sd_journal_seek_realtime_usec()</function>,
+                and <function>sd_journal_seek_cursor()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_journal_stream_fd.xml b/man/sd_journal_stream_fd.xml
new file mode 100644 (file)
index 0000000..4407296
--- /dev/null
@@ -0,0 +1,171 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_journal_stream_fd">
+
+        <refentryinfo>
+                <title>sd_journal_stream_fd</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_journal_stream_fd</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_journal_stream_fd</refname>
+                <refpurpose>Create log stream file descriptor to the journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-journal.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_journal_stream_fd</function></funcdef>
+                                <paramdef>const char* <parameter>identifier</parameter></paramdef>
+                                <paramdef>int <parameter>priority</parameter></paramdef>
+                                <paramdef>int <parameter>level_prefix</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_journal_stream_fd()</function> may
+                be used to create a log stream file descriptor. Log
+                messages written to this file descriptor as simple
+                newline separated text strings are written to the
+                journal. This file descriptor can be used internally
+                by applications or be made STDOUT/STDERR of other
+                processes executed.</para>
+
+                <para><function>sd_journal_stream_fd()</function>
+                takes a short program identifier string as first
+                argument, which will be written to the journal as
+                _SYSLOG_IDENTIFIER= field for each log entry (see
+                <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                for more information). The second argument shall be
+                the default priority level for all messages. The
+                priority level is one of <literal>LOG_EMERG</literal>,
+                <literal>LOG_ALERT</literal>,
+                <literal>LOG_CRIT</literal>,
+                <literal>LOG_ERR</literal>,
+                <literal>LOG_WARNING</literal>,
+                <literal>LOG_NOTICE</literal>,
+                <literal>LOG_INFO</literal>,
+                <literal>LOG_DEBUG</literal>, as defined in
+                <filename>syslog.h</filename>, see
+                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for details. The third argument is a boolean: if true
+                kernel-style log priority level prefixes (such as
+                <literal>SD_WARNING</literal>) are interpreted, see
+                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for more information.</para>
+
+                <para>It is recommended that applications log UTF-8
+                messages only with this API, but this is not
+                enforced.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>The call returns a valid write-only file descriptor on success or a
+                negative errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_journal_stream_fd()</function>
+                interface is available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-journal</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <para>Creating a log stream suitable for
+                <citerefentry><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>:</para>
+
+                <programlisting>#include &lt;syslog.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;systemd/sd-journal.h&gt;
+#include &lt;systemd/sd-daemon.h&gt;
+
+int main(int argc, char *argv[]) {
+        int fd;
+        FILE *log;
+        fd = sd_journal_stream_fd("test", LOG_INFO, 1);
+        if (fd &lt; 0) {
+                fprintf(stderr, "Failed to create stream fd: %s\n", strerror(-fd));
+                return 1;
+        }
+        log = fdopen(fd, "w");
+        if (!log) {
+                fprintf(stderr, "Failed to create file object: %m\n");
+                close(fd);
+                return 1;
+        }
+        fprintf(log, "Hello World!\n");
+        fprintf(log, SD_WARNING "This is a warning!\n");
+        fclose(log);
+        return 0;
+}</programlisting>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml
new file mode 100644 (file)
index 0000000..b891b6b
--- /dev/null
@@ -0,0 +1,204 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_listen_fds">
+
+        <refentryinfo>
+                <title>sd_listen_fds</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_listen_fds</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_listen_fds</refname>
+                <refname>SD_LISTEN_FDS_START</refname>
+                <refpurpose>Check for file descriptors passed by the system manager</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+
+                        <funcsynopsisinfo>#define SD_LISTEN_FDS_START 3</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_listen_fds</function></funcdef>
+                                <paramdef>int <parameter>unset_environment</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_listen_fds()</function> shall be
+                called by a daemon to check for file descriptors
+                passed by the init system as part of the socket-based
+                activation logic.</para>
+
+                <para>If the <parameter>unset_environment</parameter>
+                parameter is non-zero
+                <function>sd_listen_fds()</function> will unset the
+                <varname>$LISTEN_FDS</varname>/<varname>$LISTEN_PID</varname>
+                environment variables before returning (regardless
+                whether the function call itself succeeded or
+                not). Further calls to
+                <function>sd_listen_fds()</function> will then fail,
+                but the variables are no longer inherited by child
+                processes.</para>
+
+                <para>If a daemon receives more than one file
+                descriptor, they will be passed in the same order as
+                configured in the systemd socket definition
+                file. Nonetheless it is recommended to verify the
+                correct socket types before using them. To simplify
+                this checking the functions
+                <citerefentry><refentrytitle>sd_is_fifo</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_is_socket</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_is_socket_inet</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_is_socket_unix</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                are provided. In order to maximize flexibility it is
+                recommended to make these checks as loose as possible
+                without allowing incorrect setups. i.e. often the
+                actual port number a socket is bound to matters little
+                for the service to work, hence it should not be
+                verified. On the other hand, whether a socket is a
+                datagram or stream socket matters a lot for the most
+                common program logics and should be checked.</para>
+
+                <para>This function call will set the FD_CLOEXEC flag
+                for all passed file descriptors to avoid further
+                inheritance to children of the calling process.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On failure, this call returns a negative
+                errno-style error code. If
+                <varname>$LISTEN_FDS</varname>/<varname>$LISTEN_PID</varname>
+                was not set or was not correctly set for this daemon and
+                hence no file descriptors were received, 0 is
+                returned. Otherwise the number of file descriptors
+                passed is returned. The application may find them
+                starting with file descriptor SD_LISTEN_FDS_START,
+                i.e. file descriptor 3.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>This function is provided by the reference
+                implementation of APIs for new-style daemons and
+                distributed with the systemd package. The algorithm it
+                implements is simple, and can easily be reimplemented
+                in daemons if it is important to support this
+                interface without using the reference
+                implementation.</para>
+
+                <para>Internally, this function checks whether the
+                <varname>$LISTEN_PID</varname> environment variable
+                equals the daemon PID. If not, it returns
+                immediately. Otherwise it parses the number passed in
+                the <varname>$LISTEN_FDS</varname> environment
+                variable, then sets the FD_CLOEXEC flag for the parsed
+                number of file descriptors starting from
+                SD_LISTEN_FDS_START. Finally it returns the parsed
+                number.</para>
+
+                <para>For details about the algorithm check the
+                liberally licensed reference implementation sources:
+                <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c"/>
+                and <ulink
+                url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h"/></para>
+
+                <para><function>sd_listen_fds()</function> is
+                implemented in the reference implementation's
+                <filename>sd-daemon.c</filename> and
+                <filename>sd-daemon.h</filename> files. These
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-daemon</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file. Alternatively, applications consuming these APIs
+                may copy the implementation into their source
+                tree. For more details about the reference
+                implementation see
+                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>If the reference implementation is used as
+                drop-in files and -DDISABLE_SYSTEMD is set during
+                compilation this function will always return 0 and
+                otherwise become a NOP.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$LISTEN_PID</varname></term>
+                                <term><varname>$LISTEN_FDS</varname></term>
+
+                                <listitem><para>Set by the init system
+                                for supervised processes that use
+                                socket-based activation. This
+                                environment variable specifies the
+                                data
+                                <function>sd_listen_fds()</function>
+                                parses. See above for
+                                details.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_is_fifo</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_is_socket</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_is_socket_inet</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_is_socket_unix</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
new file mode 100644 (file)
index 0000000..35cb6b3
--- /dev/null
@@ -0,0 +1,173 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_login_monitor_new">
+
+        <refentryinfo>
+                <title>sd_login_monitor_new</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_login_monitor_new</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_login_monitor_new</refname>
+                <refname>sd_login_monitor_unref</refname>
+                <refname>sd_login_monitor_flush</refname>
+                <refname>sd_login_monitor_get_fd</refname>
+                <refname>sd_login_monitor</refname>
+                <refpurpose>Monitor login sessions, seats and users</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_login_monitor_new</function></funcdef>
+                                <paramdef>const char* <parameter>category</parameter></paramdef>
+                                <paramdef>sd_login_monitor** <parameter>ret</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>sd_login_monitor* <function>sd_login_monitor_unref</function></funcdef>
+                                <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_login_monitor_flush</function></funcdef>
+                                <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_login_monitor_get_fd</function></funcdef>
+                                <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
+                        </funcprototype>
+
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_login_monitor_new()</function> may
+                be used to monitor login sessions, users and seats. Via
+                a monitor object a file descriptor can be integrated
+                into an application defined event loop which is woken
+                up each time a user logs in, logs out or a seat is
+                added or removed, or a session, user, or seat changes
+                state otherwise. The first parameter takes a string
+                which can be <literal>seat</literal> (to get
+                only notifications about seats being added, removed or
+                changed), <literal>session</literal> (to get only
+                notifications about sessions being created or removed
+                or changed) or <literal>uid</literal> (to get only
+                notifications when a user changes state in respect to
+                logins). If notifications shall be generated in all
+                these conditions, NULL may be passed. Note that in the
+                future additional categories may be defined. The
+                second parameter returns a monitor object and needs to
+                be freed with the
+                <function>sd_login_monitor_unref()</function> call
+                after use.</para>
+
+                <para><function>sd_login_monitor_unref()</function>
+                may be used to destroy a monitor object. Note that
+                this will invalidate any file descriptor returned by
+                <function>sd_login_monitor_get_fd()</function>.</para>
+
+                <para><function>sd_login_monitor_flush()</function>
+                may be used to reset the wakeup state of the monitor
+                object. Whenever an event causes the monitor to wake
+                up the event loop via the file descriptor this
+                function needs to be called to reset the wake-up
+                state. If this call is not invoked the file descriptor
+                will immediately wake up the event loop again.</para>
+
+                <para><function>sd_login_monitor_get_fd()</function>
+                may be used to retrieve the file descriptor of the
+                monitor object that may be integrated in an
+                application defined event loop, based around
+                <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                or a similar interface. The application should include
+                the returned file descriptor as wake up source for
+                POLLIN events. Whenever a wake-up is triggered the
+                file descriptor needs to be reset via
+                <function>sd_login_monitor_flush()</function>. An
+                application needs to reread the login state with a
+                function like
+                <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                or similar to determine what changed.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On success
+                <function>sd_login_monitor_new()</function> and
+                <function>sd_login_monitor_flush()</function> return 0
+                or a positive integer. On success
+                <function>sd_login_monitor_get_fd()</function> returns
+                a Unix file descriptor. On failure, these calls return
+                a negative errno-style error code.</para>
+
+                <para><function>sd_login_monitor_unref()</function>
+                always returns NULL.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_login_monitor_new()</function>,
+                <function>sd_login_monitor_unref()</function>, <function>sd_login_monitor_flush()</function> and
+                <function>sd_login_monitor_get_fd()</function> interfaces
+                are available as shared library, which can be compiled
+                and linked to with the
+                <literal>libsystemd-login</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
new file mode 100644 (file)
index 0000000..75edeea
--- /dev/null
@@ -0,0 +1,319 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_notify">
+
+        <refentryinfo>
+                <title>sd_notify</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_notify</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_notify</refname>
+                <refname>sd_notifyf</refname>
+                <refpurpose>Notify service manager about start-up completion and other daemon status changes</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_notify</function></funcdef>
+                                <paramdef>int <parameter>unset_environment</parameter></paramdef>
+                                <paramdef>const char *<parameter>state</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_notifyf</function></funcdef>
+                                <paramdef>int <parameter>unset_environment</parameter></paramdef>
+                                <paramdef>const char *<parameter>format</parameter></paramdef>
+                                <paramdef>...</paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+                <para><function>sd_notify()</function> shall be called
+                by a daemon to notify the init system about status
+                changes. It can be used to send arbitrary information,
+                encoded in an environment-block-like string. Most
+                importantly it can be used for start-up completion
+                notification.</para>
+
+                <para>If the <parameter>unset_environment</parameter>
+                parameter is non-zero <function>sd_notify()</function>
+                will unset the <varname>$NOTIFY_SOCKET</varname>
+                environment variable before returning (regardless
+                whether the function call itself succeeded or
+                not). Further calls to
+                <function>sd_notify()</function> will then fail, but
+                the variable is no longer inherited by child
+                processes.</para>
+
+                <para>The <parameter>state</parameter> parameter
+                should contain a newline-separated list of variable
+                assignments, similar in style to an environment
+                block. A trailing newline is implied if none is
+                specified. The string may contain any kind of variable
+                assignments, but the following shall be considered
+                well-known:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>READY=1</term>
+
+                                <listitem><para>Tells the init system
+                                that daemon startup is finished. This
+                                is only used by systemd if the service
+                                definition file has Type=notify
+                                set. The passed argument is a boolean
+                                "1" or "0". Since there is little
+                                value in signaling non-readiness, the
+                                only value daemons should send is
+                                "READY=1".</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>STATUS=...</term>
+
+                                <listitem><para>Passes a single-line
+                                status string back to the init system
+                                that describes the daemon state. This
+                                is free-form and can be used for
+                                various purposes: general state
+                                feedback, fsck-like programs could
+                                pass completion percentages and
+                                failing programs could pass a human
+                                readable error message. Example:
+                                "STATUS=Completed 66% of file system
+                                check..."</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>ERRNO=...</term>
+
+                                <listitem><para>If a daemon fails, the
+                                errno-style error code, formatted as
+                                string. Example: "ERRNO=2" for
+                                ENOENT.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>BUSERROR=...</term>
+
+                                <listitem><para>If a daemon fails, the
+                                D-Bus error-style error code. Example:
+                                "BUSERROR=org.freedesktop.DBus.Error.TimedOut"</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>MAINPID=...</term>
+
+                                <listitem><para>The main pid of the
+                                daemon, in case the init system did
+                                not fork off the process
+                                itself. Example:
+                                "MAINPID=4711"</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>WATCHDOG=1</term>
+
+                                <listitem><para>Tells systemd to
+                                update the watchdog timestamp. This is
+                                the keep-alive ping that services need
+                                to issue in regular intervals if
+                                <varname>WatchdogSec=</varname> is
+                                enabled for it. See
+                                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details. It is recommended to send
+                                this message if the
+                                <varname>WATCHDOG_USEC=</varname>
+                                environment variable has been set for
+                                the service process, in every half the
+                                time interval that is specified in the
+                                variable.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>It is recommended to prefix variable names that
+                are not shown in the list above with
+                <varname>X_</varname> to avoid namespace
+                clashes.</para>
+
+                <para>Note that systemd will accept status data sent
+                from a daemon only if the
+                <varname>NotifyAccess=</varname> option is correctly
+                set in the service definition file. See
+                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details.</para>
+
+                <para><function>sd_notifyf()</function> is similar to
+                <function>sd_notify()</function> but takes a
+                <function>printf()</function>-like format string plus
+                arguments.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On failure, these calls return a negative
+                errno-style error code. If
+                <varname>$NOTIFY_SOCKET</varname> was not set and
+                hence no status data could be sent, 0 is returned. If
+                the status was sent these functions return with a
+                positive return value. In order to support both, init
+                systems that implement this scheme and those which
+                don't, it is generally recommended to ignore the return
+                value of this call.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>These functions are provided by the reference
+                implementation of APIs for new-style daemons and
+                distributed with the systemd package. The algorithms
+                they implement are simple, and can easily be
+                reimplemented in daemons if it is important to support
+                this interface without using the reference
+                implementation.</para>
+
+                <para>Internally, these functions send a single
+                datagram with the state string as payload to the
+                AF_UNIX socket referenced in the
+                <varname>$NOTIFY_SOCKET</varname> environment
+                variable. If the first character of
+                <varname>$NOTIFY_SOCKET</varname> is @ the string is
+                understood as Linux abstract namespace socket. The
+                datagram is accompanied by the process credentials of
+                the sending daemon, using SCM_CREDENTIALS.</para>
+
+                <para>For details about the algorithms check the
+                liberally licensed reference implementation sources:
+                <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c"/>
+                and <ulink
+                url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h"/></para>
+
+                <para><function>sd_notify()</function> and
+                <function>sd_notifyf()</function> are implemented in
+                the reference implementation's
+                <filename>sd-daemon.c</filename> and
+                <filename>sd-daemon.h</filename> files. These
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
+                <literal>libsystemd-daemon</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file. Alternatively, applications consuming these APIs
+                may copy the implementation into their source tree. For
+                more details about the reference implementation see
+                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>If the reference implementation is used as
+                drop-in files and -DDISABLE_SYSTEMD is set during
+                compilation these functions will always return 0 and
+                otherwise become a NOP.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$NOTIFY_SOCKET</varname></term>
+
+                                <listitem><para>Set by the init system
+                                for supervised processes for status
+                                and start-up completion
+                                notification. This environment variable
+                                specifies the socket
+                                <function>sd_notify()</function> talks
+                                to. See above for details.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <example>
+                        <title>Start-up Notification</title>
+
+                        <para>When a daemon finished starting up, it
+                        might issue the following call to notify
+                        the init system:</para>
+
+                        <programlisting>sd_notify(0, "READY=1");</programlisting>
+                </example>
+
+                <example>
+                        <title>Extended Start-up Notification</title>
+
+                        <para>A daemon could send the following after
+                        completing initialization:</para>
+
+                        <programlisting>sd_notifyf(0, "READY=1\n"
+              "STATUS=Processing requests...\n"
+              "MAINPID=%lu",
+              (unsigned long) getpid());</programlisting>
+                </example>
+
+                <example>
+                        <title>Error Cause Notification</title>
+
+                        <para>A daemon could send the following shortly before exiting, on failure</para>
+
+                        <programlisting>sd_notifyf(0, "STATUS=Failed to start up: %s\n"
+              "ERRNO=%i",
+              strerror(errno),
+              errno);</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml
new file mode 100644 (file)
index 0000000..9517795
--- /dev/null
@@ -0,0 +1,160 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_pid_get_session">
+
+        <refentryinfo>
+                <title>sd_pid_get_session</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_pid_get_session</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_pid_get_session</refname>
+                <refname>sd_pid_get_unit</refname>
+                <refname>sd_pid_get_owner_uid</refname>
+                <refpurpose>Determine session, service or owner of a session of a specific PID</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_pid_get_session</function></funcdef>
+                                <paramdef>pid_t <parameter>pid</parameter></paramdef>
+                                <paramdef>char** <parameter>session</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_pid_get_unit</function></funcdef>
+                                <paramdef>pid_t <parameter>pid</parameter></paramdef>
+                                <paramdef>char** <parameter>unit</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
+                                <paramdef>pid_t <parameter>pid</parameter></paramdef>
+                                <paramdef>uid_t* <parameter>uid</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_pid_get_session()</function> may be
+                used to determine the login session identifier of a
+                process identified by the specified process
+                identifier. The session identifier is a short string,
+                suitable for usage in file system paths. Note that not
+                all processes are part of a login session (e.g. system
+                service processes, user processes that are shared
+                between multiple sessions of the same user, or kernel
+                threads). For processes not being part of a login
+                session this function will fail. The returned string
+                needs to be freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_pid_get_unit()</function> may be
+                used to determine the systemd unit (i.e. system
+                service) identifier of a process identified by the
+                specified process identifier. The unit name is a short
+                string, suitable for usage in file system paths. Note
+                that not all processes are part of a unit/service
+                (e.g. user processes, or kernel threads). For
+                processes not being part of a systemd unit/system
+                service this function will fail. The returned string
+                needs to be freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_pid_get_owner_uid()</function> may
+                be used to determine the Unix user identifier of the
+                owner of the session of a process identified the
+                specified PID. Note that this function will succeed
+                for user processes which are shared between multiple
+                login sessions of the same user, where
+                <function>sd_pid_get_session()</function> will
+                fail. For processes not being part of a login session
+                and not being a shared process of a user this function
+                will fail.</para>
+
+                <para>If the <literal>pid</literal> parameter of any
+                of these functions is passed as 0 the operation is
+                executed for the calling process.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On success these calls return 0 or a positive
+                integer. On failure, these calls return a negative
+                errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_pid_get_session()</function>,
+                <function>sd_pid_get_pid()</function>, and
+                <function>sd_pid_get_owner_uid()</function> interfaces
+                are available as shared library, which can be compiled
+                and linked to with the
+                <literal>libsystemd-login</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+
+                <para>Note that the login session identifier as
+                returned by <function>sd_pid_get_session()</function>
+                is completely unrelated to the process session
+                identifier as returned by
+                <citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml
new file mode 100644 (file)
index 0000000..a1fc6f1
--- /dev/null
@@ -0,0 +1,178 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_notify">
+
+        <refentryinfo>
+                <title>sd_readahead</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_readahead</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_readahead</refname>
+                <refpurpose>Control ongoing disk boot-time read-ahead operations</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include "sd-readahead.h"</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_readahead</function></funcdef>
+                                <paramdef>const char *<parameter>action</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+                <para><function>sd_readahead()</function> may be
+                called by programs involved with early boot-up to
+                control ongoing boot-time disk read-ahead operations. It may be
+                used to terminate read-ahead operations in case an
+                uncommon disk access pattern is to be expected and
+                hence read-ahead replay or collection is unlikely to
+                have the desired speed-up effect on the current or
+                future boot-ups.</para>
+
+                <para>The <parameter>action</parameter> should be one
+                of the following strings:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>cancel</term>
+
+                                <listitem><para>Terminates read-ahead
+                                data collection, and drops all
+                                read-ahead data collected during this
+                                boot-up.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>done</term>
+
+                                <listitem><para>Terminates read-ahead
+                                data collection, but keeps all
+                                read-ahead data collected during this
+                                boot-up around for use during
+                                subsequent boot-ups.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>noreplay</term>
+
+                                <listitem><para>Terminates read-ahead
+                                replay.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On failure, these calls return a negative
+                errno-style error code. It is generally recommended to
+                ignore the return value of this call.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>This function is provided by the reference
+                implementation of APIs for controlling boot-time
+                read-ahead and distributed with the systemd
+                package. The algorithm it implements is simple, and
+                can easily be reimplemented in daemons if it is
+                important to support this interface without using the
+                reference implementation.</para>
+
+                <para>Internally, this function creates a file in
+                <filename>/run/systemd/readahead/</filename> which is
+                then used as flag file to notify the read-ahead
+                subsystem.</para>
+
+                <para>For details about the algorithm check the
+                liberally licensed reference implementation sources:
+                <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c"/>
+                and <ulink
+                url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h"/></para>
+
+                <para><function>sd_readahead()</function> is
+                implemented in the reference implementation's drop-in
+                <filename>sd-readahead.c</filename> and
+                <filename>sd-readahead.h</filename> files. It is
+                recommended that applications consuming this API copy
+                the implementation into their source tree. For more
+                details about the reference implementation see
+                <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry></para>
+
+                <para>If -DDISABLE_SYSTEMD is set during compilation
+                this function will always return 0 and otherwise
+                become a NOP.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <example>
+                        <title>Cancelling all read-ahead operations</title>
+
+                        <para>During boots where SELinux has to
+                        relabel the file system hierarchy, it will
+                        create a large amount of disk accesses that
+                        are not necessary during normal boots. Hence
+                        it is a good idea to disable both read-ahead replay and read-ahead collection.
+                        </para>
+
+                        <programlisting>sd_readahead("cancel");
+sd_readahead("noreplay");</programlisting>
+                </example>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
new file mode 100644 (file)
index 0000000..b1d6d20
--- /dev/null
@@ -0,0 +1,180 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_seat_get_active">
+
+        <refentryinfo>
+                <title>sd_seat_get_active</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_seat_get_active</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_seat_get_active</refname>
+                <refname>sd_seat_get_sessions</refname>
+                <refname>sd_seat_can_multi_session</refname>
+                <refpurpose>Determine state of a specific seat</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_seat_get_active</function></funcdef>
+                                <paramdef>const char* <parameter>seat</parameter></paramdef>
+                                <paramdef>char** <parameter>session</parameter></paramdef>
+                                <paramdef>uid_t* <parameter>uid</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_seat_get_sessions</function></funcdef>
+                                <paramdef>const char* <parameter>seat</parameter></paramdef>
+                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
+                                <paramdef>uid_t** <parameter>uid</parameter></paramdef>
+                                <paramdef>unsigned* <parameter>n_uids</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_seat_can_multi_session</function></funcdef>
+                                <paramdef>const char* <parameter>seat</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_seat_can_tty</function></funcdef>
+                                <paramdef>const char* <parameter>seat</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_seat_can_graphical</function></funcdef>
+                                <paramdef>const char* <parameter>seat</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_seat_get_active()</function> may be
+                used to determine which session is currently active on
+                a seat, if there is any. Returns the session
+                identifier and the user identifier of the Unix user
+                the session is belonging to. Either the session or the
+                user identifier parameter can be passed NULL, in
+                case only one of the parameters shall be queried. The
+                returned string needs to be freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_seat_get_sessions()</function> may
+                be used to determine all sessions on the specified
+                seat. Returns two arrays, one (NULL terminated) with
+                the session identifiers of the sessions and one with
+                the user identifiers of the Unix users the sessions
+                belong to. An additional parameter may be used to
+                return the number of entries in the latter array. The
+                two arrays and the latter parameter may be passed as
+                NULL in case these values need not to be
+                determined. The arrays and the strings referenced by
+                them need to be freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use. Note that instead of an empty array
+                NULL may be returned and should be considered
+                equivalent to an empty array.</para>
+
+                <para><function>sd_seat_can_multi_session()</function>
+                may be used to determine whether a specific seat is
+                capable of multi-session, i.e. allows multiple login
+                sessions in parallel (with only one being active at a
+                time).</para>
+
+                <para><function>sd_seat_can_tty()</function> may be
+                used to determine whether a specific seat provides TTY
+                functionality, i.e. is useful as a text console.</para>
+
+                <para><function>sd_seat_can_graphical()</function> may
+                be used to determine whether a specific seat provides
+                graphics functionality, i.e. is useful as a graphics
+                display.</para>
+
+                <para>If the <literal>seat</literal> parameter of any
+                of these functions is passed as NULL the operation is
+                executed for the seat of the session of the calling
+                process, if there is any.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para> On success
+                <function>sd_seat_get_active()</function>
+                returns 0 or a positive integer. On success
+                <function>sd_seat_get_sessions()</function> returns
+                the number of entries in the session identifier
+                array. If the test succeeds
+                <function>sd_seat_can_multi_session</function>,
+                <function>sd_seat_can_tty</function> and
+                <function>sd_seat_can_graphical</function> return a
+                positive integer, if it fails 0. On failure, these
+                calls return a negative errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_seat_get_active()</function>,
+                <function>sd_seat_get_sessions()</function>,
+                <function>sd_seat_can_multi_session()</function>,
+                <function>sd_seat_can_tty()</function> and
+                <function>sd_seat_can_grapical()</function> interfaces
+                are available as shared library, which can be compiled
+                and linked to with the
+                <literal>libsystemd-login</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
new file mode 100644 (file)
index 0000000..a9107cb
--- /dev/null
@@ -0,0 +1,240 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_session_is_active">
+
+        <refentryinfo>
+                <title>sd_session_is_active</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_session_is_active</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_session_is_active</refname>
+                <refname>sd_session_get_state</refname>
+                <refname>sd_session_get_uid</refname>
+                <refname>sd_session_get_seat</refname>
+                <refname>sd_session_get_service</refname>
+                <refname>sd_session_get_type</refname>
+                <refname>sd_session_get_class</refname>
+                <refname>sd_session_get_display</refname>
+                <refpurpose>Determine state of a specific session</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_session_is_active</function></funcdef>
+                                <paramdef>const char* <parameter>session</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_session_get_state</function></funcdef>
+                                <paramdef>const char* <parameter>session</parameter></paramdef>
+                                <paramdef>char** <parameter>state</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_session_get_uid</function></funcdef>
+                                <paramdef>const char* <parameter>session</parameter></paramdef>
+                                <paramdef>uid_t* <parameter>uid</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_session_get_seat</function></funcdef>
+                                <paramdef>const char* <parameter>session</parameter></paramdef>
+                                <paramdef>char** <parameter>seat</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_session_get_service</function></funcdef>
+                                <paramdef>const char* <parameter>session</parameter></paramdef>
+                                <paramdef>char** <parameter>service</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_session_get_type</function></funcdef>
+                                <paramdef>const char* <parameter>session</parameter></paramdef>
+                                <paramdef>char** <parameter>type</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_session_get_class</function></funcdef>
+                                <paramdef>const char* <parameter>session</parameter></paramdef>
+                                <paramdef>char** <parameter>class</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_session_get_display</function></funcdef>
+                                <paramdef>const char* <parameter>session</parameter></paramdef>
+                                <paramdef>char** <parameter>display</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_session_is_active()</function> may
+                be used to determine whether the session identified by
+                the specified session identifier is currently active
+                (i.e. currently in the foreground and available for
+                user input) or not.</para>
+
+                <para><function>sd_session_get_state()</function> may
+                be used to determine the state of the session
+                identified by the specified session identifier. The
+                following states are currently known:
+                <literal>online</literal> (session logged in, but
+                session not active, i.e. not in the foreground),
+                <literal>active</literal> (session logged in and
+                active, i.e. in the foreground),
+                <literal>closing</literal> (session nominally logged
+                out, but some processes belonging to it are still
+                around). In the future additional states might be
+                defined, client code should be written to be robust in
+                regards to additional state strings being
+                returned. This function is a more generic version of
+                <function>sd_session_is_active()</function>. The returned
+                string needs to be freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_session_get_uid()</function> may be
+                used to determine the user identifier of the Unix user the session
+                identified by the specified session identifier belongs
+                to.</para>
+
+                <para><function>sd_session_get_seat()</function> may
+                be used to determine the seat identifier of the seat
+                the session identified by the specified session
+                identifier belongs to. Note that not all sessions are
+                attached to a seat, this call will fail for them. The
+                returned string needs to be freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_session_get_service()</function>
+                may be used to determine the name of the service (as
+                passed during PAM session setup) that registered the
+                session identified by the specified session
+                identifier. The returned string needs to be freed with
+                the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_session_get_type()</function> may
+                be used to determine the type of the session
+                identified by the specified session identifier. The
+                returned string is one of <literal>x11</literal>,
+                <literal>tty</literal> or
+                <literal>unspecified</literal> and needs to be freed
+                with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_session_get_class()</function> may
+                be used to determine the class of the session
+                identified by the specified session identifier. The
+                returned string is one of <literal>user</literal>,
+                <literal>greeter</literal> or
+                <literal>lock-screen</literal> and needs to be freed
+                with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_session_get_display()</function>
+                may be used to determine the X11 display of the
+                session identified by the specified session
+                identifier. The returned string is one of needs to be
+                freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para>If the <literal>session</literal> parameter of
+                any of these functions is passed as NULL the operation
+                is executed for the session the calling process is a
+                member of, if there is any.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>If the test succeeds
+                <function>sd_session_is_active()</function> returns a
+                positive integer, if it fails 0.  On success
+                <function>sd_session_get_state()</function>,
+                <function>sd_session_get_uid()</function>,
+                <function>sd_session_get_seat()</function>,
+                <function>sd_session_get_service()</function>,
+                <function>sd_session_get_type()</function>,
+                <function>sd_session_get_class()</function> and
+                <function>sd_session_get_display()</function> return 0 or
+                a positive integer. On failure, these calls return a
+                negative errno-style error code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_session_is_active()</function>,
+                <function>sd_session_get_state()</function>,
+                <function>sd_session_get_uid()</function>,
+                <function>sd_session_get_seat()</function>,
+                <function>sd_session_get_service()</function>,
+                <function>sd_session_get_type()</function>,
+                <function>sd_session_get_class()</function> and
+                <function>sd_session_get_display()</function> interfaces
+                are available as shared library, which can be compiled
+                and linked to with the
+                <literal>libsystemd-login</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml
new file mode 100644 (file)
index 0000000..b7bc944
--- /dev/null
@@ -0,0 +1,190 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_uid_get_state">
+
+        <refentryinfo>
+                <title>sd_uid_get_state</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sd_uid_get_state</refentrytitle>
+                <manvolnum>3</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sd_uid_get_state</refname>
+                <refname>sd_uid_is_on_seat</refname>
+                <refname>sd_uid_get_sessions</refname>
+                <refname>sd_uid_get_seats</refname>
+                <refpurpose>Determine login state of a specific Unix user ID</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <funcsynopsis>
+                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_uid_get_state</function></funcdef>
+                                <paramdef>uid_t <parameter>uid</parameter></paramdef>
+                                <paramdef>char** <parameter>state</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_uid_is_on_seat</function></funcdef>
+                                <paramdef>uid_t <parameter>uid</parameter></paramdef>
+                                <paramdef>int <parameter>require_active</parameter></paramdef>
+                                <paramdef>const char* <parameter>seat</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_uid_get_sessions</function></funcdef>
+                                <paramdef>uid_t <parameter>uid</parameter></paramdef>
+                                <paramdef>int <parameter>require_active</parameter></paramdef>
+                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_uid_get_seats</function></funcdef>
+                                <paramdef>uid_t <parameter>uid</parameter></paramdef>
+                                <paramdef>int <parameter>require_active</parameter></paramdef>
+                                <paramdef>char*** <parameter>seats</parameter></paramdef>
+                        </funcprototype>
+                </funcsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><function>sd_uid_get_state()</function> may be
+                used to determine the login state of a specific Unix
+                user identifier. The following states are currently
+                known: <literal>offline</literal> (user not logged in
+                at all), <literal>lingering</literal> (user not logged
+                in, but some user services running),
+                <literal>online</literal> (user logged in, but not
+                active, i.e. has no session in the foreground),
+                <literal>active</literal> (user logged in, and has at
+                least one active session, i.e. one session in the
+                foreground), <literal>closing</literal> (user not
+                logged in, and not lingering, but some processes are
+                still around). In the future additional states might
+                be defined, client code should be written to be robust
+                in regards to additional state strings being
+                returned. The returned string needs to be freed with
+                the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
+                <para><function>sd_uid_is_on_seat()</function> may be
+                used to determine whether a specific user is logged in
+                or active on a specific seat. Accepts a Unix user
+                identifier and a seat identifier string as
+                parameters. The <parameter>require_active</parameter>
+                parameter is a boolean value. If non-zero (true) this
+                function will test if the user is active (i.e. has a
+                session that is in the foreground and accepting user
+                input) on the specified seat, otherwise (false) only
+                if the user is logged in (and possibly inactive) on
+                the specified seat.</para>
+
+                <para><function>sd_uid_get_sessions()</function> may
+                be used to determine the current sessions of the
+                specified user. Accepts a Unix user identifier as
+                parameter. The <parameter>require_active</parameter>
+                parameter controls whether the returned list shall
+                consist of only those sessions where the user is
+                currently active (&gt; 0), where the user is currently
+                online but possibly inactive (= 0), or
+                logged in at all but possibly closing the session (&lt; 0). The call returns a
+                NULL terminated string array of session identifiers in
+                <parameter>sessions</parameter> which needs to be
+                freed by the caller with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use, including all the strings
+                referenced. If the string array parameter is passed as
+                NULL the array will not be filled in, but the return
+                code still indicates the number of current
+                sessions. Note that instead of an empty array NULL may
+                be returned and should be considered equivalent to an
+                empty array.</para>
+
+                <para>Similar, <function>sd_uid_get_seats()</function>
+                may be used to determine the list of seats on which
+                the user currently has sessions. Similar semantics
+                apply, however note that the user may have
+                multiple sessions on the same seat as well as sessions
+                with no attached seat and hence the number of entries
+                in the returned array may differ from the one returned
+                by <function>sd_uid_get_sessions()</function>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Return Value</title>
+
+                <para>On success
+                <function>sd_uid_get_state()</function> returns 0 or a
+                positive integer. If the test succeeds
+                <function>sd_uid_is_on_seat()</function> returns a
+                positive integer, if it fails
+                0. <function>sd_uid_get_sessions()</function> and
+                <function>sd_uid_get_seats()</function> return the
+                number of entries in the returned arrays. On failure,
+                these calls return a negative errno-style error
+                code.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>The <function>sd_uid_get_state()</function>,
+                <function>sd_uid_is_on_seat()</function>,
+                <function>sd_uid_get_sessions()</function>, and
+                <function>sd_uid_get_seats()</function> interfaces are
+                available as shared library, which can be compiled and
+                linked to with the <literal>libsystemd-login</literal>
+                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/shutdown.xml b/man/shutdown.xml
new file mode 100644 (file)
index 0000000..d54fcb2
--- /dev/null
@@ -0,0 +1,188 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="shutdown">
+
+        <refentryinfo>
+                <title>shutdown</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>shutdown</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>shutdown</refname>
+                <refpurpose>Halt, power-off or reboot the machine</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>shutdown <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">TIME</arg> <arg choice="opt" rep="repeat">WALL</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>shutdown</command> may be used to halt,
+                power-off or reboot the machine.</para>
+
+                <para>The first argument may be a time string (which
+                is usually <literal>now</literal>). Optionally, this
+                may be followed by a wall message to be sent to all
+                logged-in users before going down.</para>
+
+                <para>The time string may either be in the format
+                <literal>hh:mm</literal> for hour/minutes specifying
+                the time to execute the shutdown at, specified in 24h
+                clock format. Alternatively it may be in the syntax
+                <literal>+m</literal> referring to the specified
+                number of minutes m from now. <literal>now</literal>
+                is an alias for <literal>+0</literal>, i.e. for
+                triggering an immediate shutdown. If no time argument
+                is specified, <literal>+1</literal> is
+                implied.</para>
+
+                <para>Note that to specify a wall message you must
+                specify a time argument, too.</para>
+
+                <para>If the time argument is used, 5 minutes
+                before the system goes down the
+                <filename>/etc/nologin</filename> file is created to
+                ensure that further logins shall not be
+                allowed.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-H</option></term>
+                                <term><option>--halt</option></term>
+
+                                <listitem><para>Halt the machine.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-P</option></term>
+                                <term><option>--poweroff</option></term>
+
+                                <listitem><para>Power-off the
+                                machine (the default).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-r</option></term>
+                                <term><option>--reboot</option></term>
+
+                                <listitem><para>Reboot the
+                                machine.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Equivalent to
+                                <option>--poweroff</option>, unless
+                                <option>--halt</option> is
+                                specified.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-k</option></term>
+
+                                <listitem><para>Don't halt, power-off,
+                                reboot, just write wall
+                                message.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-wall</option></term>
+
+                                <listitem><para>Don't send wall
+                                message before
+                                halt, power-off, reboot.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-c</option></term>
+
+                                <listitem><para>Cancel a pending
+                                shutdown. This may be used cancel the
+                                effect of an invocation of
+                                <command>shutdown</command> with a
+                                time argument that is not
+                                <literal>+0</literal> or
+                                <literal>now</literal>.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>This is a legacy command available for
+                compatibility only.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>halt</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml
new file mode 100644 (file)
index 0000000..69aac8c
--- /dev/null
@@ -0,0 +1,127 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="sysctl.d">
+
+        <refentryinfo>
+                <title>sysctl.d</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sysctl.d</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sysctl.d</refname>
+                <refpurpose>Configure kernel parameters at boot</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/sysctl.d/*.conf</filename></para>
+                <para><filename>/run/sysctl.d/*.conf</filename></para>
+                <para><filename>/usr/lib/sysctl.d/*.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>At boot,
+                <citerefentry><refentrytitle>systemd-sysctl.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                reads configuration files from the above directories
+                to configure
+                <citerefentry><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                kernel parameters.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Configuration Format</title>
+
+                <para>The configuration files contain a list of
+                variable assignments, separated by newlines. Empty
+                lines and lines whose first non-whitespace character
+                is # or ; are ignored.</para>
+
+                <para>Note that both / and . are accepted as label
+                separators within sysctl variable
+                names. <literal>kernel.domainname=foo</literal> and
+                <literal>kernel/domainname=foo</literal> hence are
+                entirely equivalent.</para>
+
+                <para>Each configuration file shall be named in the
+                style of <filename>&lt;program&gt;.conf</filename>.
+                Files in <filename>/etc/</filename> override files
+                with the same name in <filename>/usr/lib/</filename>
+                and <filename>/run/</filename>.  Files in
+                <filename>/run/</filename> override files with the same
+                name in <filename>/usr/lib/</filename>. Packages
+                should install their configuration files in
+                <filename>/usr/lib/</filename>. Files in
+                <filename>/etc/</filename> are reserved for the local
+                administrator, who may use this logic to override the
+                configuration files installed by vendor packages. All
+                configuration files are sorted by their filename in
+                alphabetical order, regardless in which of the
+                directories they reside, to guarantee that a specific
+                configuration file takes precedence over another file
+                with an alphabetically earlier name, if both files
+                contain the same variable setting.</para>
+
+                <para>If the administrator wants to disable a
+                configuration file supplied by the vendor the
+                recommended way is to place a symlink to
+                <filename>/dev/null</filename> in
+                <filename>/etc/sysctl.d/</filename> bearing the
+                same file name.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+                <example>
+                        <title>/etc/sysctl.d/domain-name.conf example:</title>
+
+                        <programlisting># Set kernel YP domain name
+kernel.domainname=example.com</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-sysctl.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sysctl.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemctl.xml b/man/systemctl.xml
new file mode 100644 (file)
index 0000000..f86952c
--- /dev/null
@@ -0,0 +1,1286 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemctl">
+
+        <refentryinfo>
+                <title>systemctl</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemctl</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemctl</refname>
+                <refpurpose>Control the systemd system and service manager</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemctl <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg> <arg choice="opt" rep="repeat">NAME</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemctl</command> may be used to
+                introspect and control the state of the
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                system and service manager.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--type=</option></term>
+                                <term><option>-t</option></term>
+
+                                <listitem><para>The argument should
+                                be a unit type name such as
+                                <option>service</option> and
+                                <option>socket</option>,
+                                or a unit load state such as
+                                <option>loaded</option> and
+                                <option>masked</option>.
+                                </para>
+
+                                <para>If the argument is a unit type,
+                                when listing units, limit display to
+                                certain unit types. If not specified
+                                units of all types will be shown.</para>
+
+                                <para>If the argument is a unit load state,
+                                when listing units, limit display to
+                                certain unit types. If not specified
+                                units of in all load states will be
+                                shown.</para>
+
+                                <para>As a special case, if the argument
+                                is <option>help</option>, a list of
+                                allowed values will be printed and the
+                                program will exit.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--property=</option></term>
+                                <term><option>-p</option></term>
+
+                                <listitem><para>When showing
+                                unit/job/manager properties, limit
+                                display to certain properties as
+                                specified as argument. If not
+                                specified all set properties are
+                                shown. The argument should be a
+                                property name, such as
+                                <literal>MainPID</literal>. If
+                                specified more than once all
+                                properties with the specified names
+                                are shown.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--all</option></term>
+                                <term><option>-a</option></term>
+
+                                <listitem><para>When listing units,
+                                show all units, regardless of their
+                                state, including inactive units. When
+                                showing unit/job/manager properties,
+                                show all properties regardless whether
+                                they are set or not.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--failed</option></term>
+
+                                <listitem><para>When listing units,
+                                show only failed units. Do not confuse
+                                with
+                                <option>--fail</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--full</option></term>
+
+                                <listitem><para>Do not ellipsize unit
+                                names and truncate unit descriptions
+                                in the output of
+                                <command>list-units</command> and
+                                <command>list-jobs</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--fail</option></term>
+
+                                <listitem><para>If the requested
+                                operation conflicts with a pending
+                                unfinished job, fail the command. If
+                                this is not specified the requested
+                                operation will replace the pending job,
+                                if necessary. Do not confuse
+                                with
+                                <option>--failed</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--ignore-dependencies</option></term>
+
+                                <listitem><para>When enqueuing a new
+                                job ignore all its dependencies and
+                                execute it immediately. If passed no
+                                required units of the unit passed will
+                                be pulled in, and no ordering
+                                dependencies will be honored. This is
+                                mostly a debugging and rescue tool for
+                                the administrator and should not be
+                                used by
+                                applications.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--quiet</option></term>
+                                <term><option>-q</option></term>
+
+                                <listitem><para>Suppress output to
+                                STDOUT in
+                                <command>snapshot</command>,
+                                <command>is-active</command>,
+                                <command>is-failed</command>,
+                                <command>enable</command> and
+                                <command>disable</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-block</option></term>
+
+                                <listitem><para>Do not synchronously wait for
+                                the requested operation to finish. If this is
+                                not specified the job will be verified,
+                                enqueued and <command>systemctl</command> will
+                                wait until it is completed. By passing this
+                                argument it is only verified and
+                                enqueued.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-legend</option></term>
+
+                                <listitem><para>Do not print a legend, i.e.
+                                the column headers and the footer with hints.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+                                <listitem><para>Do not pipe output into a
+                                pager.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--system</option></term>
+
+                                <listitem><para>Talk to the systemd
+                                system manager. (Default)</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--user</option></term>
+
+                                <listitem><para>Talk to the systemd
+                                manager of the calling user.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--order</option></term>
+                                <term><option>--require</option></term>
+
+                                <listitem><para>When used in
+                                conjunction with the
+                                <command>dot</command> command (see
+                                below), selects which dependencies are
+                                shown in the dependency graph. If
+                                <option>--order</option> is passed
+                                only dependencies of type
+                                <varname>After=</varname> or
+                                <varname>Before=</varname> are
+                                shown. If <option>--require</option>
+                                is passed only dependencies of type
+                                <varname>Requires=</varname>,
+                                <varname>RequiresOverridable=</varname>,
+                                <varname>Requisite=</varname>,
+                                <varname>RequisiteOverridable=</varname>,
+                                <varname>Wants=</varname> and
+                                <varname>Conflicts=</varname> are
+                                shown. If neither is passed, shows
+                                dependencies of all these
+                                types.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-wall</option></term>
+
+                                <listitem><para>Don't send wall
+                                message before
+                                halt, power-off, reboot.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--global</option></term>
+
+                                <listitem><para>When used with
+                                <command>enable</command> and
+                                <command>disable</command>, operate on the
+                                global user configuration
+                                directory, thus enabling or disabling
+                                a unit file globally for all future
+                                logins of all users.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-reload</option></term>
+
+                                <listitem><para>When used with
+                                <command>enable</command> and
+                                <command>disable</command>, do not
+                                implicitly reload daemon configuration
+                                after executing the
+                                changes.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-ask-password</option></term>
+
+                                <listitem><para>When used with
+                                <command>start</command> and related
+                                commands, disables asking for
+                                passwords. Background services may
+                                require input of a password or
+                                passphrase string, for example to
+                                unlock system hard disks or
+                                cryptographic certificates. Unless
+                                this option is specified and the
+                                command is invoked from a terminal
+                                <command>systemctl</command> will
+                                query the user on the terminal for the
+                                necessary secrets. Use this option to
+                                switch this behavior off. In this case
+                                the password must be supplied by some
+                                other means (for example graphical
+                                password agents) or the service might
+                                fail. This also disables querying the
+                                user for authentication for privileged
+                                operations.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--kill-who=</option></term>
+
+                                <listitem><para>When used with
+                                <command>kill</command>, choose which
+                                processes to kill. Must be one of
+                                <option>main</option>,
+                                <option>control</option> or
+                                <option>all</option> to select whether
+                                to kill only the main process of the
+                                unit, the control process or all
+                                processes of the unit. If omitted
+                                defaults to
+                                <option>all</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--signal=</option></term>
+                                <term><option>-s</option></term>
+
+                                <listitem><para>When used with
+                                <command>kill</command>, choose which
+                                signal to send to selected
+                                processes. Must be one of the well
+                                known signal specifiers such as
+                                SIGTERM, SIGINT or SIGSTOP. If
+                                omitted defaults to
+                                <option>SIGTERM</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--force</option></term>
+                                <term><option>-f</option></term>
+
+                                <listitem><para>When used with
+                                <command>enable</command>, overwrite any
+                                existing conflicting
+                                symlinks.</para></listitem>
+
+                                <listitem><para>When used with
+                                <command>halt</command>,
+                                <command>poweroff</command>,
+                                <command>reboot</command> or
+                                <command>kexec</command> execute the
+                                selected operation without shutting
+                                down all units. However, all processes
+                                will be killed forcibly and all file
+                                systems are unmounted or remounted
+                                read-only. This is hence a drastic but
+                                relatively safe option to request an
+                                immediate reboot. If
+                                <option>--force</option> is specified
+                                twice for these operations, they will
+                                be executed immediately without
+                                terminating any processes or umounting
+                                any file systems. Warning: specifying
+                                <option>--force</option> twice with
+                                any of these operations might result
+                                in data loss.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--root=</option></term>
+
+                                <listitem><para>When used with
+                                <command>enable</command>/<command>disable</command>/<command>is-enabled</command> (and
+                                related commands), use alternative
+                                root path when looking for unit
+                                files.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--runtime</option></term>
+
+                                <listitem><para>When used with
+                                <command>enable</command>/<command>disable</command>/<command>is-enabled</command> (and related commands), make
+                                changes only temporarily, so that they
+                                are dropped on the next reboot. This
+                                will have the effect that changes are
+                                not made in subdirectories of
+                                <filename>/etc</filename> but in
+                                <filename>/run</filename>, with
+                                identical immediate effects, however,
+                                since the latter is lost on reboot,
+                                the changes are lost
+                                too.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-H</option></term>
+                                <term><option>--host</option></term>
+
+                                <listitem><para>Execute operation
+                                remotely. Specify a hostname, or
+                                username and hostname separated by @,
+                                to connect to. This will use SSH to
+                                talk to the remote systemd
+                                instance.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-P</option></term>
+                                <term><option>--privileged</option></term>
+
+                                <listitem><para>Acquire privileges via
+                                PolicyKit before executing the
+                                operation.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--lines=</option></term>
+                                <term><option>-n</option></term>
+
+                                <listitem><para>When used with
+                                <command>status</command> controls the
+                                number of journal lines to show,
+                                counting from the most recent
+                                ones. Takes a positive integer
+                                argument. Defaults to
+                                10.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--output=</option></term>
+                                <term><option>-o</option></term>
+
+                                <listitem><para>When used with
+                                <command>status</command> controls the
+                                formatting of the journal entries that
+                                are shown. For the available choices
+                                see
+                                <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. Defaults
+                                to
+                                <literal>short</literal>.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+                <para>The following commands are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><command>list-units</command></term>
+
+                                <listitem><para>List known units.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>start [NAME...]</command></term>
+
+                                <listitem><para>Start (activate) one
+                                or more units specified on the command
+                                line.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>stop [NAME...]</command></term>
+
+                                <listitem><para>Stop (deactivate) one
+                                or more units specified on the command
+                                line.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>reload [NAME...]</command></term>
+
+                                <listitem><para>Asks all units listed
+                                on the command line to reload their
+                                configuration. Note that this will
+                                reload the service-specific
+                                configuration, not the unit
+                                configuration file of systemd. If you
+                                want systemd to reload the
+                                configuration file of a unit use the
+                                <command>daemon-reload</command>
+                                command. In other words: for the
+                                example case of Apache, this will
+                                reload Apache's
+                                <filename>httpd.conf</filename> in the
+                                web server, not the
+                                <filename>apache.service</filename>
+                                systemd unit file. </para>
+
+                                <para>This command should not be
+                                confused with the
+                                <command>daemon-reload</command> or
+                                <command>load</command>
+                                commands.</para></listitem>
+
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>restart [NAME...]</command></term>
+
+                                <listitem><para>Restart one or more
+                                units specified on the command
+                                line. If the units are not running yet
+                                they will be
+                                started.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>try-restart [NAME...]</command></term>
+
+                                <listitem><para>Restart one or more
+                                units specified on the command
+                                line if the units are running. Do
+                                nothing if units are not running.
+                                Note that for compatibility
+                                with Red Hat init scripts
+                                <command>condrestart</command> is
+                                equivalent to this command.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>reload-or-restart [NAME...]</command></term>
+
+                                <listitem><para>Reload one or more
+                                units if they support it. If not,
+                                restart them instead. If the units
+                                are not running yet they will be
+                                started.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>reload-or-try-restart [NAME...]</command></term>
+
+                                <listitem><para>Reload one or more
+                                units if they support it. If not,
+                                restart them instead. Do nothing if
+                                the units are not running. Note that
+                                for compatibility with SysV init
+                                scripts
+                                <command>force-reload</command> is
+                                equivalent to this
+                                command.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>isolate [NAME]</command></term>
+
+                                <listitem><para>Start the unit
+                                specified on the command line and its
+                                dependencies and stop all others.</para>
+
+                                <para>This is similar to changing the
+                                runlevel in a traditional init system. The
+                                <command>isolate</command> command will
+                                immediately stop processes that are not
+                                enabled in the new unit, possibly including
+                                the graphical environment or terminal you
+                                are currently using.</para>
+
+                                <para>Note that this works only on units
+                                where <option>AllowIsolate=</option> is
+                                enabled. See
+                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>kill [NAME...]</command></term>
+
+                                <listitem><para>Send a signal to one
+                                or more processes of the unit. Use
+                                <option>--kill-who=</option> to select
+                                which process to kill. Use
+                                <option>--kill-mode=</option> to
+                                select the kill mode and
+                                <option>--signal=</option> to select
+                                the signal to send.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>is-active [NAME...]</command></term>
+
+                                <listitem><para>Check whether any of
+                                the specified units are active
+                                (i.e. running). Returns an exit code
+                                0 if at least one is active, non-zero
+                                otherwise. Unless
+                                <option>--quiet</option> is specified
+                                this will also print the current unit
+                                state to STDOUT.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>is-failed [NAME...]</command></term>
+
+                                <listitem><para>Check whether any of
+                                the specified units are failed.
+                                Returns an exit code
+                                0 if at least one is failed, non-zero
+                                otherwise. Unless
+                                <option>--quiet</option> is specified
+                                this will also print the current unit
+                                state to STDOUT.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>status [NAME...|PID...]</command></term>
+
+                                <listitem><para>Show terse runtime
+                                status information about one or more
+                                units, followed by its most recent log
+                                data from the journal. This function
+                                is intended to generate human-readable
+                                output. If you are looking for
+                                computer-parsable output, use
+                                <command>show</command> instead. If a
+                                PID is passed information about the
+                                unit the process of the PID belongs to
+                                is shown.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>show [NAME...|JOB...]</command></term>
+
+                                <listitem><para>Show properties of one
+                                or more units, jobs or the manager
+                                itself. If no argument is specified
+                                properties of the manager will be
+                                shown. If a unit name is specified
+                                properties of the unit is shown, and
+                                if a job id is specified properties of
+                                the job is shown. By default, empty
+                                properties are suppressed. Use
+                                <option>--all</option> to show those
+                                too. To select specific properties to
+                                show use
+                                <option>--property=</option>. This
+                                command is intended to be used
+                                whenever computer-parsable output is
+                                required. Use
+                                <command>status</command> if you are
+                                looking for formatted human-readable
+                                output.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>help [NAME...|PID...]</command></term>
+
+                                <listitem><para>Show manual pages for
+                                one or more units, if available. If a
+                                PID is passed the manual pages for the
+                                unit the process of the PID belongs to
+                                is shown.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>reset-failed [NAME...]</command></term>
+
+                                <listitem><para>Reset the
+                                '<literal>failed</literal>' state of the
+                                specified units, or if no unit name is
+                                passed of all units. When a unit fails
+                                in some way (i.e. process exiting with
+                                non-zero error code, terminating
+                                abnormally or timing out) it will
+                                automatically enter the
+                                '<literal>failed</literal>' state and
+                                its exit code and status is recorded
+                                for introspection by the administrator
+                                until the service is restarted or
+                                reset with this
+                                command.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>list-unit-files</command></term>
+
+                                <listitem><para>List installed unit files.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>enable [NAME...]</command></term>
+
+                                <listitem><para>Enable one or
+                                more unit files or unit file
+                                instances, as specified on the
+                                command line. This will create a
+                                number of symlinks as encoded in
+                                the <literal>[Install]</literal>
+                                sections of the unit files. After
+                                the symlinks have been created the
+                                systemd configuration is reloaded
+                                (in a way that is equivalent to
+                                <command>daemon-reload</command>)
+                                to ensure the changes are taken into
+                                account immediately. Note that this
+                                does not have the effect that any of
+                                the units enabled are also started at
+                                the same time.  If this is desired
+                                a separate <command>start</command>
+                                command must be invoked for the unit.
+                                Also note that in case of instance
+                                enablement, symlinks named same as
+                                instances are created in install
+                                location, however they all point to
+                                the same template unit file.</para>
+
+                                <para>This command will
+                                print the actions executed. This
+                                output may be suppressed by passing
+                                <option>--quiet</option>.</para>
+
+                                <para>Note that this operation creates
+                                only the suggested symlinks for the
+                                units. While this command is the
+                                recommended way to manipulate the unit
+                                configuration directory, the
+                                administrator is free to make
+                                additional changes manually, by
+                                placing or removing symlinks in the
+                                directory. This is particularly useful
+                                to create configurations that deviate
+                                from the suggested default
+                                installation. In this case the
+                                administrator must make sure to invoke
+                                <command>daemon-reload</command>
+                                manually as necessary, to ensure his
+                                changes are taken into account.</para>
+
+                                <para>Enabling units should not be
+                                confused with starting (activating)
+                                units, as done by the
+                                <command>start</command>
+                                command. Enabling and starting units
+                                is orthogonal: units may be enabled
+                                without being started and started
+                                without being enabled. Enabling simply
+                                hooks the unit into various suggested
+                                places (for example, so that the unit
+                                is automatically started on boot or
+                                when a particular kind of hardware is
+                                plugged in). Starting actually spawns
+                                the daemon process (in case of service
+                                units), or binds the socket (in case
+                                of socket units), and so
+                                on.</para>
+
+                                <para>Depending on whether
+                                <option>--system</option>,
+                                <option>--user</option> or
+                                <option>--global</option> is specified
+                                this enables the unit for the system,
+                                for the calling user only
+                                or for all future logins of all
+                                users. Note that in the latter case no
+                                systemd daemon configuration is
+                                reloaded.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>disable [NAME...]</command></term>
+
+                                <listitem><para>Disables one or more
+                                units. This removes all symlinks to
+                                the specified unit files from the unit
+                                configuration directory, and hence
+                                undoes the changes made by
+                                <command>enable</command>. Note
+                                however that this removes
+                                all symlinks to the unit files
+                                (i.e. including manual additions), not
+                                just those actually created by
+                                <command>enable</command>. This call
+                                implicitly reloads the systemd daemon
+                                configuration after completing the
+                                disabling of the units. Note that this
+                                command does not implicitly stop the
+                                units that are being disabled. If this
+                                is desired an additional
+                                <command>stop</command> command should
+                                be executed afterwards.</para>
+
+                                <para>This command will print the
+                                actions executed. This output may be
+                                suppressed by passing
+                                <option>--quiet</option>.</para>
+                                </listitem>
+
+                                <para>This command honors
+                                <option>--system</option>,
+                                <option>--user</option>,
+                                <option>--global</option> in a similar
+                                way as
+                                <command>enable</command>.</para>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>is-enabled [NAME...]</command></term>
+
+                                <listitem><para>Checks whether any of
+                                the specified unit files are enabled
+                                (as with
+                                <command>enable</command>). Returns an
+                                exit code of 0 if at least one is
+                                enabled, non-zero otherwise. Prints
+                                the current enable status. To suppress
+                                this output use
+                                <option>--quiet</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>reenable [NAME...]</command></term>
+
+                                <listitem><para>Reenable one or more
+                                unit files, as specified on the
+                                command line. This is a combination of
+                                <command>disable</command> and
+                                <command>enable</command> and is
+                                useful to reset the symlinks a unit is
+                                enabled with to the defaults
+                                configured in the
+                                <literal>[Install]</literal> section
+                                of the unit file.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>preset [NAME...]</command></term>
+
+                                <listitem><para>Reset one or more unit
+                                files, as specified on the command
+                                line, to the defaults configured in
+                                the preset policy files. This has the
+                                same effect as
+                                <command>disable</command> or
+                                <command>enable</command>, depending
+                                how the unit is listed in the preset
+                                files. For more information on preset
+                                policy format see
+                                <citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>. For
+                                more information on the concept of
+                                presets please consult the <ulink
+                                url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
+                                document.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>mask [NAME...]</command></term>
+
+                                <listitem><para>Mask one or more unit
+                                files, as specified on the command
+                                line. This will link these units to
+                                <filename>/dev/null</filename>, making
+                                it impossible to start them. This is a stronger version
+                                of <command>disable</command>, since
+                                it prohibits all kinds of activation
+                                of the unit, including manual
+                                activation. Use this option with
+                                care.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>unmask [NAME...]</command></term>
+
+                                <listitem><para>Unmask one or more
+                                unit files, as specified on the
+                                command line. This will undo the
+                                effect of
+                                <command>mask</command>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>link [NAME...]</command></term>
+
+                                <listitem><para>Link a unit file that
+                                is not in the unit file search paths
+                                into the unit file search path. This
+                                requires an absolute path to a unit
+                                file. The effect of this can be undone
+                                with <command>disable</command>. The
+                                effect of this command is that a unit
+                                file is available for
+                                <command>start</command> and other
+                                commands although it isn't installed
+                                directly in the unit search
+                                path.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>load [NAME...]</command></term>
+
+                                <listitem><para>Load one or more units
+                                specified on the command line. This
+                                will simply load their configuration
+                                from disk, but not start them. To
+                                start them you need to use the
+                                <command>start</command> command which
+                                will implicitly load a unit that has
+                                not been loaded yet. Note that systemd
+                                garbage collects loaded units that are
+                                not active or referenced by an active
+                                unit. This means that units loaded
+                                this way will usually not stay loaded
+                                for long. Also note that this command
+                                cannot be used to reload unit
+                                configuration. Use the
+                                <command>daemon-reload</command>
+                                command for that. All in all, this
+                                command is of little use except for
+                                debugging.</para>
+                                <para>This command should not be
+                                confused with the
+                                <command>daemon-reload</command> or
+                                <command>reload</command>
+                                commands.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>list-jobs</command></term>
+
+                                <listitem><para>List jobs that are in progress.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>cancel [JOB...]</command></term>
+
+                                <listitem><para>Cancel one or more
+                                jobs specified on the command line by
+                                their numeric job
+                                IDs. If no job id is specified, cancel all pending jobs.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>dump</command></term>
+
+                                <listitem><para>Dump server
+                                status. This will output a (usually
+                                very long) human readable manager
+                                status dump. Its format is subject to
+                                change without notice and should not
+                                be parsed by
+                                applications.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>dot</command></term>
+
+                                <listitem><para>Generate textual
+                                dependency graph description in dot
+                                format for further processing with the
+                                GraphViz
+                                <citerefentry><refentrytitle>dot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                tool. Use a command line like
+                                <command>systemctl dot | dot -Tsvg >
+                                systemd.svg</command> to generate a
+                                graphical dependency tree. Unless
+                                <option>--order</option> or
+                                <option>--require</option> is passed
+                                the generated graph will show both
+                                ordering and requirement
+                                dependencies.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>snapshot [NAME]</command></term>
+
+                                <listitem><para>Create a snapshot. If
+                                a snapshot name is specified, the new
+                                snapshot will be named after it. If
+                                none is specified an automatic
+                                snapshot name is generated. In either
+                                case, the snapshot name used is
+                                printed to STDOUT, unless
+                                <option>--quiet</option> is
+                                specified.</para>
+
+                                <para>A snapshot refers to a saved
+                                state of the systemd manager. It is
+                                implemented itself as a unit that is
+                                generated dynamically with this
+                                command and has dependencies on all
+                                units active at the time. At a later
+                                time the user may return to this state
+                                by using the
+                                <command>isolate</command> command on
+                                the snapshot unit.</para></listitem>
+
+                                <para>Snapshots are only useful for
+                                saving and restoring which units are
+                                running or are stopped, they do not
+                                save/restore any other
+                                state. Snapshots are dynamic and lost
+                                on reboot.</para>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>delete [NAME...]</command></term>
+
+                                <listitem><para>Remove a snapshot
+                                previously created with
+                                <command>snapshot</command>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>daemon-reload</command></term>
+
+                                <listitem><para>Reload systemd manager
+                                configuration. This will reload all
+                                unit files and recreate the entire
+                                dependency tree. While the daemon is
+                                reloaded, all sockets systemd listens
+                                on on behalf of user configuration will
+                                stay accessible.</para> <para>This
+                                command should not be confused with
+                                the <command>load</command> or
+                                <command>reload</command>
+                                commands.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>daemon-reexec</command></term>
+
+                                <listitem><para>Reexecute the systemd
+                                manager. This will serialize the
+                                manager state, reexecute the process
+                                and deserialize the state again. This
+                                command is of little use except for
+                                debugging and package
+                                upgrades. Sometimes it might be
+                                helpful as a heavy-weight
+                                <command>daemon-reload</command>. While
+                                the daemon is reexecuted all sockets
+                                systemd listens on on behalf of user
+                                configuration will stay
+                                accessible.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>show-environment</command></term>
+
+                                <listitem><para>Dump the systemd
+                                manager environment block. The
+                                environment block will be dumped in
+                                straight-forward form suitable for
+                                sourcing into a shell script. This
+                                environment block will be passed to
+                                all processes the manager
+                                spawns.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>set-environment [NAME=VALUE...]</command></term>
+
+                                <listitem><para>Set one or more
+                                systemd manager environment variables,
+                                as specified on the command
+                                line.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>unset-environment [NAME...]</command></term>
+
+                                <listitem><para>Unset one or more
+                                systemd manager environment
+                                variables. If only a variable name is
+                                specified it will be removed
+                                regardless of its value. If a variable
+                                and a value are specified the variable
+                                is only removed if it has the
+                                specified value.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>default</command></term>
+
+                                <listitem><para>Enter default
+                                mode. This is mostly equivalent to
+                                <command>start
+                                default.target</command>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>rescue</command></term>
+
+                                <listitem><para>Enter rescue
+                                mode. This is mostly equivalent to
+                                <command>isolate
+                                rescue.target</command> but also
+                                prints a wall message to all
+                                users.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>emergency</command></term>
+
+                                <listitem><para>Enter emergency
+                                mode. This is mostly equivalent to
+                                <command>isolate
+                                emergency.target</command> but also
+                                prints a wall message to all
+                                users.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>halt</command></term>
+
+                                <listitem><para>Shut down and halt the
+                                system. This is mostly equivalent to
+                                <command>start halt.target</command>
+                                but also prints a wall message to all
+                                users.  If combined with
+                                <option>--force</option> shutdown of
+                                all running services is skipped,
+                                however all processes are killed and
+                                all file systems are unmounted or
+                                mounted read-only, immediately
+                                followed by the system halt.  If
+                                <option>--force</option> is specified
+                                twice the operation is immediately
+                                executed without terminating any
+                                processes or unmounting any file
+                                systems. This may result in data
+                                loss.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>poweroff</command></term>
+
+                                <listitem><para>Shut down and
+                                power-off the system. This is mostly
+                                equivalent to <command>start
+                                poweroff.target</command> but also
+                                prints a wall message to all users. If
+                                combined with <option>--force</option>
+                                shutdown of all running services is
+                                skipped, however all processes are
+                                killed and all file systems are
+                                unmounted or mounted read-only,
+                                immediately followed by the powering
+                                off. If <option>--force</option> is
+                                specified twice the operation is
+                                immediately executed without
+                                terminating any processes or
+                                unmounting any file systems. This may
+                                result in data loss.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>reboot</command></term>
+
+                                <listitem><para>Shut down and reboot
+                                the system. This is mostly equivalent
+                                to <command>start
+                                reboot.target</command> but also
+                                prints a wall message to all users. If
+                                combined with <option>--force</option>
+                                shutdown of all running services is
+                                skipped, however all processes are
+                                killed and all file systems are
+                                unmounted or mounted read-only,
+                                immediately followed by the reboot. If
+                                <option>--force</option> is specified
+                                twice the operation is immediately
+                                executed without terminating any
+                                processes or unmounting any file
+                                systems. This may result in data
+                                loss.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>kexec</command></term>
+
+                                <listitem><para>Shut down and reboot
+                                the system via kexec. This is mostly
+                                equivalent to <command>start
+                                kexec.target</command> but also prints
+                                a wall message to all users. If
+                                combined with <option>--force</option>
+                                shutdown of all running services is
+                                skipped, however all processes are killed
+                                and all file systems are unmounted or
+                                mounted read-only, immediately
+                                followed by the
+                                reboot.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>exit</command></term>
+
+                                <listitem><para>Ask the systemd
+                                manager to quit. This is only
+                                supported for user service managers
+                                (i.e. in conjunction with the
+                                <option>--user</option> option) and
+                                will fail otherwise.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>suspend</command></term>
+
+                                <listitem><para>Suspend the
+                                system. This will trigger activation
+                                of the special
+                                <filename>suspend.target</filename>
+                                target.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>hibernate</command></term>
+
+                                <listitem><para>Hibernate the
+                                system. This will trigger activation
+                                of the special
+                                <filename>hibernate.target</filename>
+                                target.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>hybrid-sleep</command></term>
+
+                                <listitem><para>Hibernate and suspend
+                                the system. This will trigger
+                                activation of the special
+                                <filename>hybrid-sleep.target</filename>
+                                target.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>switch-root [ROOT] [INIT]</command></term>
+
+                                <listitem><para>Switches to a
+                                different root directory and executes
+                                a new system manager process below
+                                it. This is intended for usage in
+                                initial RAM disks ("initrd"), and will
+                                transition from the initrd's system
+                                manager process (a.k.a "init" process)
+                                to the main system manager
+                                process. Takes two arguments: the
+                                directory to make the new root
+                                directory, and the path to the new
+                                system manager binary below it to
+                                execute as PID 1. If the latter is
+                                omitted or the empty string, a
+                                systemd binary will automatically be
+                                searched for and used as init. If the
+                                system manager path is omitted or
+                                equal the empty string the state of
+                                the initrd's system manager process is
+                                passed to the main system manager,
+                                which allows later introspection of the
+                                state of the services involved in the
+                                initrd boot.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_PAGER</varname></term>
+                                <listitem><para>Pager to use when
+                                <option>--no-pager</option> is not given;
+                                overrides <varname>$PAGER</varname>.  Setting
+                                this to an empty string or the value
+                                <literal>cat</literal> is equivalent to passing
+                                <option>--no-pager</option>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemadm</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
new file mode 100644 (file)
index 0000000..c2ff9cc
--- /dev/null
@@ -0,0 +1,138 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-analyze">
+
+        <refentryinfo>
+                <title>systemd-analyze</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-analyze</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-analyze</refname>
+                <refpurpose>Analyze system boot-up performance</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-analyze <arg choice="opt" rep="repeat">OPTIONS</arg> time</command>
+                </cmdsynopsis>
+                <cmdsynopsis>
+                        <command>systemd-analyze <arg choice="opt" rep="repeat">OPTIONS</arg> blame </command>
+                </cmdsynopsis>
+                <cmdsynopsis>
+                        <command>systemd-analyze <arg choice="opt" rep="repeat">OPTIONS</arg> plot <arg choice="opt">&gt; file.svg</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-analyze</command> may be used
+                to determine system boot-up performance of the current
+                boot.</para>
+
+                <para><command>systemd-analyze time</command>
+                prints the time spent in the kernel before
+                userspace has been reached, the time spent in the
+                initial RAM disk (initrd) before normal system
+                userspace has been reached and the time normal system
+                userspace took to initialize. Note that these
+                measurements simply measure the time passed up to the
+                point where all system services have been spawned, but
+                not necessarily until they fully finished
+                initialization or the disk is idle.</para>
+
+                <para><command>systemd-analyze blame</command> prints
+                a list of all running units, ordered by the time they
+                took to initialize. This information may be used to
+                optimize boot-up times. Note that the output might be
+                misleading as the initialization of one service might
+                be slow simply because it waits for the initialization
+                of another service to complete.</para>
+
+                <para><command>systemd-analyze plot</command> prints
+                an SVG graphic detailing which system services have
+                been started at what time, highlighting the time they
+                spent on initialization.</para>
+
+                <para>If no command is passed <command>systemd-analyze
+                time</command> is implied.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--user</option></term>
+
+                                <listitem><para>Shows performance data
+                                of user sessions instead of the system
+                                manager.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-ask-password-console.service.xml b/man/systemd-ask-password-console.service.xml
new file mode 100644 (file)
index 0000000..6c87feb
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-ask-password-console.service">
+
+        <refentryinfo>
+                <title>systemd-ask-password-console.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-ask-password-console.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-ask-password-console.service</refname>
+                <refname>systemd-ask-password-console.path</refname>
+                <refname>systemd-ask-password-wall.service</refname>
+                <refname>systemd-ask-password-wall.path</refname>
+                <refpurpose>Query the user for system passwords on the
+                console and via wall</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-ask-password-console.service</filename></para>
+                <para><filename>systemd-ask-password-console.path</filename></para>
+                <para><filename>systemd-ask-password-wall.service</filename></para>
+                <para><filename>systemd-ask-password-wall.path</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-ask-password-console.service</filename>
+                is a system service that queries the user for system
+                passwords (such as hard disk encryption keys and SSL
+                certificate passphrases) on the console. It is
+                intended to be used during boot to ensure proper
+                handling of passwords necessary for
+                boot. <filename>systemd-ask-password-wall.service</filename>
+                is a system service that informs all logged in users
+                for system passwords via
+                <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>. It
+                is intended to be used after boot to ensure that users
+                are properly notified.</para>
+
+                <para>See the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
+                developer documentation</ulink> for more information
+                about the system password logic.</para>
+
+                <para>Note that these services invoke
+                <citerefentry><refentrytitle>systemd-tty-ask-password-agent</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                with either the <command>--watch --console</command>
+                or <command>--watch --wall</command> command line
+                parameters.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-tty-ask-password-agent</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml
new file mode 100644 (file)
index 0000000..7b0b9ab
--- /dev/null
@@ -0,0 +1,183 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-ask-password">
+
+        <refentryinfo>
+                <title>systemd-ask-password</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-ask-password</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-ask-password</refname>
+                <refpurpose>Query the user for a system password</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-ask-password <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">MESSAGE</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-ask-password</command> may be
+                used to query a system password or passphrase from the
+                user, using a question message specified on the
+                command line. When run from a TTY it will query a
+                password on the TTY and print it to STDOUT. When run
+                with no TTY or with <option>--no-tty</option> it will
+                query the password system-wide and allow active users
+                to respond via several agents. The latter is
+                only available to privileged processes.</para>
+
+                <para>The purpose of this tool is to query system-wide
+                passwords -- that is passwords not attached to a
+                specific user account. Examples include: unlocking
+                encrypted hard disks when they are plugged in or at
+                boot, entering an SSL certificate passphrase for web
+                and VPN servers.</para>
+
+                <para>Existing agents are: a boot-time password agent
+                asking the user for passwords using Plymouth; a
+                boot-time password agent querying the user directly on
+                the console; an agent requesting password input via a
+                <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                message; an agent suitable for running in a GNOME
+                session; a command line agent which can be started
+                temporarily to process queued password requests; a TTY
+                agent that is temporarily spawned during
+                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                invocations.</para>
+
+                <para>Additional password agents may be implemented
+                according to the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">systemd
+                Password Agent Specification</ulink>.</para>
+
+                <para>If a password is queried on a TTY the user may
+                press TAB to hide the asterisks normally shown for
+                each character typed. Pressing Backspace as first key
+                achieves the same effect.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--icon=</option></term>
+
+                                <listitem><para>Specify an icon name
+                                alongside the password query, which may
+                                be used in all agents supporting
+                                graphical display. The icon name
+                                should follow the <ulink
+                                url="http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html">XDG
+                                Icon Naming
+                                Specification</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--timeout=</option></term>
+
+                                <listitem><para>Specify the query
+                                timeout in seconds. Defaults to
+                                90s.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-tty</option></term>
+
+                                <listitem><para>Never ask for password
+                                on current TTY even if one is
+                                available. Always use agent
+                                system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--accept-cached</option></term>
+
+                                <listitem><para>If passed accept
+                                cached passwords, i.e. passwords
+                                previously typed in.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--multiple</option></term>
+
+                                <listitem><para>When used in
+                                conjunction with
+                                <option>--accept-cached</option>
+                                accept multiple passwords. This will
+                                output one password per
+                                line.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-binfmt.service.xml b/man/systemd-binfmt.service.xml
new file mode 100644 (file)
index 0000000..1db735a
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-binfmt.service">
+
+        <refentryinfo>
+                <title>systemd-binfmt.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-binfmt.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-binfmt.service</refname>
+                <refname>systemd-binfmt</refname>
+                <refpurpose>Configure additional binary formats for executables at boot</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-binfmt.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-binfmt</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-binfmt.service</filename> is
+                an early-boot service that registers additional binary
+                formats for executables in the kernel.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>binfmt.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for information about the configuration of this
+                service.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>binfmt.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wine</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-cat.xml b/man/systemd-cat.xml
new file mode 100644 (file)
index 0000000..cac275b
--- /dev/null
@@ -0,0 +1,205 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-cat">
+
+        <refentryinfo>
+                <title>systemd-cat</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-cat</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-cat</refname>
+                <refpurpose>Connect a pipeline or program's output with the journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-cat <arg choice="opt" rep="repeat">OPTIONS</arg> <arg>COMMAND</arg> <arg choice="opt" rep="repeat">ARGUMENTS</arg></command>
+                </cmdsynopsis>
+                <cmdsynopsis>
+                        <command>systemd-cat <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-cat</command> may be used to
+                connect STDOUT and STDERR of a process with the
+                journal, or as a filter tool in a shell pipeline to
+                pass the output the previous pipeline element
+                generates to the journal.</para>
+
+                <para>If no parameter is passed
+                <command>systemd-cat</command> will write
+                everything it reads from standard input (STDIN) to the journal.</para>
+
+                <para>If parameters are passed they are executed as
+                command line with standard output (STDOUT) and standard
+                error output (STDERR) connected to the journal, so
+                that all it writes is stored in the journal.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-t</option></term>
+                                <term><option>--identifier=</option></term>
+
+                                <listitem><para>Specify a short string
+                                that is used to identify the logging
+                                tool. If not specified no identifying
+                                string is written to the journal.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-p</option></term>
+                                <term><option>--priority=</option></term>
+
+                                <listitem><para>Specify the default
+                                priority level for the logged
+                                messages. Pass one of
+                                <literal>emerg</literal>,
+                                <literal>alert</literal>,
+                                <literal>crit</literal>,
+                                <literal>err</literal>,
+                                <literal>warning</literal>,
+                                <literal>notice</literal>,
+                                <literal>info</literal>,
+                                <literal>debug</literal>, or a
+                                value between 0 and 7 (corresponding
+                                to the same named levels). These
+                                priority values are the same as
+                                defined by
+                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. Defaults
+                                to <literal>info</literal>. Note that
+                                this simply controls the default,
+                                individual lines may be logged with
+                                different levels if they are prefixed
+                                accordingly. For details see
+                                <option>--level-prefix=</option>
+                                below.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--level-prefix=</option></term>
+
+                                <listitem><para>Controls whether lines
+                                read are parsed for syslog priority
+                                level prefixes. If enabled (the
+                                default) a line prefixed with a
+                                priority prefix such as
+                                <literal>&lt;5&gt;</literal> is logged
+                                at priority 5
+                                (<literal>notice</literal>), and
+                                similar for the other priority
+                                levels. Takes a boolean
+                                argument.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <example>
+                        <title>Invoke a program</title>
+
+                        <para>This calls <filename>/bin/ls</filename>
+                        with STDOUT/STDERR connected to the
+                        journal:</para>
+
+                        <programlisting># systemd-cat ls</programlisting>
+                </example>
+
+                <example>
+                        <title>Usage in a shell pipeline</title>
+
+                        <para>This builds a shell pipeline also
+                        invoking <filename>/bin/ls</filename> and
+                        writes the output it generates to the
+                        journal:</para>
+
+                        <programlisting># ls | systemd-cat</programlisting>
+                </example>
+
+                <para>Even though the two examples have very similar
+                effects the first is preferable since only one process
+                is running at a time, and both STDOUT and STDERR are
+                captured while in the second example only STDOUT is
+                captured.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>logger</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml
new file mode 100644 (file)
index 0000000..4b6ee93
--- /dev/null
@@ -0,0 +1,141 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-cgls">
+
+        <refentryinfo>
+                <title>systemd-cgls</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-cgls</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-cgls</refname>
+                <refpurpose>Recursively show control group contents</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-cgls <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">CGROUP</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-cgls</command> recursively
+                shows the contents of the selected Linux control group
+                hierarchy in a tree. If arguments are specified shows
+                all member processes of the specified control groups
+                plus all their subgroups and their members. The
+                control groups may either be specified by their full
+                file paths or are assumed in the systemd control group
+                hierarchy. If no argument is specified and the current
+                working directory is beneath the control group mount
+                point <filename>/sys/fs/cgroup</filename> shows the contents
+                of the control group the working directory refers
+                to. Otherwise the full systemd control group hierarchy
+                is shown.</para>
+
+                <para>By default empty control groups are not
+                shown.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+                                <listitem><para>Do not pipe output into a
+                                pager.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--all</option></term>
+
+                                <listitem><para>Don't hide empty
+                                control groups in the
+                                output.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-k</option></term>
+
+                                <listitem><para>Include kernel
+                                threads in output.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-cgtop</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml
new file mode 100644 (file)
index 0000000..7a34512
--- /dev/null
@@ -0,0 +1,276 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-cgtop">
+
+        <refentryinfo>
+                <title>systemd-cgtop</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-cgtop</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-cgtop</refname>
+                <refpurpose>Show top control groups by their resource usage</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-cgtop <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-cgtop</command> shows the top
+                control groups of the local Linux control group
+                hierarchy, ordered by their CPU, memory and disk I/O load. The
+                display is refreshed in regular intervals (by default
+                every 1s), similar in style to
+                <citerefentry><refentrytitle>top</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+
+                <para>Resource usage is only accounted for control
+                groups in the relevant hierarchy, i.e. CPU usage is
+                only accounted for control groups in the
+                <literal>cpuacct</literal> hierarchy, memory usage
+                only for those in <literal>memory</literal> and disk
+                I/O usage for those in
+                <literal>blkio</literal>. <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                by default places all services in their own control
+                group in the <literal>cpuacct</literal> hierarchy, but
+                not in <literal>memory</literal> nor
+                <literal>blkio</literal>. If resource monitoring for
+                these resources is required it is recommended to add
+                <literal>blkio</literal> and <literal>memory</literal>
+                to the <varname>DefaultControllers=</varname> setting
+                in <filename>/etc/systemd/system.conf</filename> (see
+                <citerefentry><refentrytitle>systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details). Alternatively, it is possible to enable
+                resource accounting individually for services, by
+                making use of the <varname>ControlGroup=</varname>
+                option in the unit files (See
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details).</para>
+
+                <para>To emphasize this: unless
+                <literal>blkio</literal> and <literal>memory</literal>
+                are enabled for the services in question with either
+                of the options suggested above no resource accounting
+                will be available for system services and the data shown
+                by <command>systemd-cgtop</command> will be
+                incomplete.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a version string and
+                                exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-p</option></term>
+
+                                <listitem><para>Order by control group
+                                path name.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-t</option></term>
+
+                                <listitem><para>Order by number of
+                                tasks in control
+                                group (i.e. threads and processes).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-c</option></term>
+
+                                <listitem><para>Order by CPU load.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-m</option></term>
+
+                                <listitem><para>Order by memory usage.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-i</option></term>
+
+                                <listitem><para>Order by disk I/O load.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-b</option></term>
+                                <term><option>--batch</option></term>
+
+                                <listitem><para>Run in "batch" mode:
+                                do not accept input and run until the
+                                iteration limit set with
+                                <option>--iterations</option> is
+                                exhausted or until killed. This mode
+                                could be useful for sending output
+                                from <command>systemd-cgtop</command>
+                                to other programs or to a
+                                file.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-n</option></term>
+                                <term><option>--iterations=</option></term>
+
+                                <listitem><para>Perform only this many
+                                iterations.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-d</option></term>
+                                <term><option>--delay=</option></term>
+
+                                <listitem><para>Specify refresh delay
+                                in seconds (or if one of
+                                <literal>ms</literal>,
+                                <literal>us</literal>,
+                                <literal>min</literal> is specified as
+                                unit in this time
+                                unit).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--depth=</option></term>
+
+                                <listitem><para>Maximum control group
+                                tree traversal depth. Specifies how
+                                deep <command>systemd-cgtop</command>
+                                shall traverse the control group
+                                hierarchies. If 0 is specified only
+                                the root group is monitored, for 1
+                                only the first level of control groups
+                                is monitored, and so on. Defaults to
+                                3.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+
+        <refsect1>
+                <title>Keys</title>
+
+                <para><command>systemd-cgtop</command> is an
+                interactive tool and may be controlled via user input
+                using the following keys:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>h</term>
+
+                                <listitem><para>Shows a short help text.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SPACE</term>
+
+                                <listitem><para>Immediately refresh output.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>q</term>
+
+                                <listitem><para>Terminate the program.</para></listitem>
+                        </varlistentry>
+
+
+                        <varlistentry>
+                                <term>p</term>
+                                <term>t</term>
+                                <term>c</term>
+                                <term>m</term>
+                                <term>i</term>
+
+                                <listitem><para>Sort the control groups
+                                by path, number of tasks, CPU load,
+                                memory usage, or IO
+                                load, respectively.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>+</term>
+                                <term>-</term>
+
+                                <listitem><para>Increase
+                                or decrease refresh
+                                delay, respectively.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-cgls</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>top</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-coredumpctl.xml b/man/systemd-coredumpctl.xml
new file mode 100644 (file)
index 0000000..53b82ed
--- /dev/null
@@ -0,0 +1,217 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-coredumpctl">
+
+        <refentryinfo>
+                <title>systemd-coredumpctl</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Zbigniew</firstname>
+                                <surname>Jędrzejewski-Szmek</surname>
+                                <email>zbyszek@in.waw.pl</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-coredumpctl</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-coredumpctl</refname>
+                <refpurpose>Retrieve coredumps from the journal</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-coredumpctl</command>
+                        <arg choice="opt" rep="repeat">OPTIONS</arg>
+                        <arg choice="req">COMMAND</arg>
+                        <arg choice="opt" rep="repeat">PID|COMM|EXE|MATCH</arg>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-coredumpctl</command> may be used to
+                retrieve coredumps from
+                <citerefentry><refentrytitle>systemd-journald</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Print a short help
+                                text and exit.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Print a short version
+                                string and exit.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--field=</option></term>
+                                <term><option>-F</option></term>
+
+                                <listitem><para>Print all possible
+                                data values the specified field
+                                takes in matching coredump entries of the
+                                journal.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--output=FILE</option></term>
+                                <term><option>-o FILE</option></term>
+
+                                <listitem><para>Write the core to
+                                <option>FILE</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+                                <listitem><para>Do not pipe output of
+                                <command>list</command> into a
+                                pager.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-legend</option></term>
+
+                                <listitem><para>Do not print the column headers.
+                                </para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+                <para>The following commands are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><command>list</command></term>
+
+                                <listitem><para>List coredumps captured in the journal
+                                matching specified characteristics.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>dump</command></term>
+
+                                <listitem><para>Extract the last coredump
+                                matching specified characteristics.
+                                Coredump will be written on stdout, unless
+                                an output file is specified with
+                                <option>-o/--output</option>.
+                                </para></listitem>
+                        </varlistentry>
+
+
+                        <varlistentry>
+                                <term><command>gdb</command></term>
+
+                                <listitem><para>Invoke the GNU
+                                debugger on the last coredump matching
+                                specified characteristics.
+                                </para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Matching</title>
+
+                <para>Match can be:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>PID</option></term>
+
+                                <listitem><para>Process ID of the
+                                process that dumped
+                                core. An integer.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>COMM</option></term>
+
+                                <listitem><para>Name of the executable
+                                (matches <option>COREDUMP_COMM=</option>).
+                                Must not contain slashes.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>EXE</option></term>
+
+                                <listitem><para>Path to the executable
+                                (matches <option>COREDUMP_EXE=</option>).
+                                Must contain at least one slash.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>MATCH</option></term>
+
+                                <listitem><para>General journalctl predicates
+                                (see <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
+                                Must contain an equals sign.
+                                </para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise. Not finding any matching coredumps is treated
+               as failure.
+               </para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>gdb</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml
new file mode 100644 (file)
index 0000000..49d4d55
--- /dev/null
@@ -0,0 +1,147 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-cryptsetup-generator">
+
+        <refentryinfo>
+                <title>systemd-cryptsetup-generator</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-cryptsetup-generator</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-cryptsetup-generator</refname>
+                <refpurpose>Unit generator for <filename>/etc/crypttab</filename></refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/usr/lib/systemd/system-generators/systemd-cryptsetup-generator</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-cryptsetup-generator</filename>
+                is a generator that translates
+                <filename>/etc/crypttab</filename> into native systemd
+                units early at boot and when configuration of the
+                system manager is reloaded. This will create
+                <citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                units as necessary.</para>
+
+                <para><filename>systemd-cryptsetup-generator</filename>
+                implements the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/Generators">generator
+                specification</ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Command Line</title>
+
+                <para><filename>systemd-cryptsetup-generator</filename> understands
+                the following kernel command line parameters:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>luks=</varname></term>
+                                <term><varname>rd.luks=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. Defaults to
+                                <literal>yes</literal>. If
+                                <literal>no</literal> disables the
+                                generator
+                                entirely. <varname>rd.luks=</varname>
+                                is honored only by initial RAM disk
+                                (initrd) while
+                                <varname>luks=</varname> is honored
+                                by both the main system and the
+                                initrd.  </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>luks.crypttab=</varname></term>
+                                <term><varname>rd.luks.crypttab=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. Defaults to
+                                <literal>yes</literal>. If
+                                <literal>no</literal> causes the
+                                generator to ignore any devices
+                                configured in
+                                <filename>/etc/crypttab</filename>
+                                (<varname>luks.uuid=</varname> will
+                                still work
+                                however). <varname>rd.luks.crypttab=</varname>
+                                is honored only by initial RAM disk
+                                (initrd) while
+                                <varname>luks.crypttab=</varname> is
+                                honored by both the main system and
+                                the initrd.  </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>luks.uuid=</varname></term>
+                                <term><varname>rd.luks.uuid=</varname></term>
+
+                                <listitem><para>Takes a LUKS super
+                                block UUID as argument. This will
+                                activate the specified device as part
+                                of the boot process as if it was
+                                listed in
+                                <filename>/etc/fstab</filename>. This
+                                option may be specified more than once
+                                in order to set up multiple
+                                devices. <varname>rd.luks.uuid=</varname>
+                                is honored only by initial RAM disk
+                                (initrd) while
+                                <varname>luks.uuid=</varname> is
+                                honored by both the main system and
+                                the initrd.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-cryptsetup@.service.xml b/man/systemd-cryptsetup@.service.xml
new file mode 100644 (file)
index 0000000..abbb9d7
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-cryptsetup@.service">
+
+        <refentryinfo>
+                <title>systemd-cryptsetup@.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-cryptsetup@.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-cryptsetup@.service</refname>
+                <refname>systemd-cryptsetup</refname>
+                <refpurpose>Full disk decryption logic</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-cryptsetup@.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-cryptsetup</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-cryptsetup@.service</filename>
+                is a service responsible for setting up encrypted
+                block devices. It is instantiated for each device that
+                requires decryption for access.</para>
+
+                <para><filename>systemd-cryptsetup@.service</filename>
+                will ask for hard disk passwords via the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
+                password agent logic</ulink>, in order to query the
+                user for the password using the right mechanism at
+                boot and during runtime.</para>
+
+                <para>At early boot and when the system manager
+                configuration is reloaded this
+                <filename>/etc/crypttab</filename> is translated into
+                <filename>systemd-cryptsetup@.service</filename> units
+                by
+                <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                 </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-delta.xml b/man/systemd-delta.xml
new file mode 100644 (file)
index 0000000..072f55f
--- /dev/null
@@ -0,0 +1,181 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-delta">
+
+        <refentryinfo>
+                <title>systemd-delta</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-delta</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-delta</refname>
+                <refpurpose>Find overridden configuration files</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-delta <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">SUFFIX</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-delta</command> may be used to
+                identify and compare configuration files in
+                <filename>/etc</filename> that override default
+                counterparts in <filename>/usr</filename>. The command
+                line argument can be one or more name of a subdirectories of
+                <filename>/etc</filename> or
+                <filename>/usr/lib</filename> to compare, such as
+                <filename>tmpfiles.d</filename>, <filename>sysctl.d</filename> or
+                <filename>systemd/system</filename>.</para>
+
+                <para>When no argument is specified a number of
+                well-known subdirectories are searched for overridden
+                files.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+                                <listitem><para>Do not pipe output into a
+                                pager.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--type=</option></term>
+                                <term><option>-t</option></term>
+
+                                <listitem><para>When listing the
+                                differences, only list those that are
+                                asked for. The list itself is a
+                                comma-separated list of desired
+                                difference types.</para>
+
+                                <para>Recognized types are:
+
+                                        <variablelist>
+                                                <varlistentry>
+                                                        <term><varname>masked</varname></term>
+
+                                                        <listitem><para>Show masked files</para></listitem>
+                                                </varlistentry>
+
+                                                <varlistentry>
+                                                        <term><varname>equivalent</varname></term>
+
+                                                        <listitem><para>Show overridden
+                                                        files that while overridden, do
+                                                        not differ in content.</para></listitem>
+                                                </varlistentry>
+
+                                                <varlistentry>
+                                                        <term><varname>redirected</varname></term>
+
+                                                        <listitem><para>Show files that
+                                                        are redirected to another.</para></listitem>
+                                                </varlistentry>
+
+                                                <varlistentry>
+                                                        <term><varname>overridden</varname></term>
+
+                                                        <listitem><para>Show overridden,
+                                                        and changed files.</para></listitem>
+                                                </varlistentry>
+
+                                                <varlistentry>
+                                                        <term><varname>unchanged</varname></term>
+
+                                                        <listitem><para>Show unmodified
+                                                        files too.</para></listitem>
+                                                </varlistentry>
+                                        </variablelist>
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--diff=</option></term>
+
+                                <listitem><para>When showing modified
+                                files, when a file is overridden show a
+                                diff as well. This option takes a
+                                boolean argument. If omitted it defaults
+                                to <option>true</option>.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml
new file mode 100644 (file)
index 0000000..762b6ab
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-detect-virt">
+
+        <refentryinfo>
+                <title>systemd-detect-virt</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-detect-virt</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-detect-virt</refname>
+                <refpurpose>Detect execution in a virtualized environment</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-detect-virt <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-detect-virt</command> detects
+                execution in a virtualized environment. It identifies
+                the virtualization technology and can distinguish full
+                VM virtualization from container
+                virtualization.</para>
+
+                <para>When executed without <option>--quiet</option>
+                will print a short identifier for the detected
+                virtualization technology. The following technologies
+                are currently identified: <varname>qemu</varname>,
+                <varname>kvm</varname>, <varname>vmware</varname>,
+                <varname>microsoft</varname>,
+                <varname>oracle</varname>, <varname>xen</varname>,
+                <varname>bochs</varname>, <varname>chroot</varname>,
+                <varname>openvz</varname>, <varname>lxc</varname>,
+                <varname>lxc-libvirt</varname>,
+                <varname>systemd-nspawn</varname>.</para>
+
+                <para>If multiple virtualization solutions are used
+                only the "innermost" is detected and identified. That
+                means if both VM virtualization and container
+                virtualization are used in conjunction only the latter
+                will be identified (unless <option>--vm</option> is
+                passed).</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-c</option></term>
+                                <term><option>--container</option></term>
+
+                                <listitem><para>Only detects container
+                                virtualization (i.e. shared kernel
+                                virtualization).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-v</option></term>
+                                <term><option>--vm</option></term>
+
+                                <listitem><para>Only detects VM
+                                virtualization (i.e. full hardware
+                                virtualization).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-q</option></term>
+                                <term><option>--quiet</option></term>
+
+                                <listitem><para>Suppress output of the
+                                virtualization technology
+                                identifier.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>If a virtualization technology is detected 0 is
+                returned, a non-zero code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-fsck@.service.xml b/man/systemd-fsck@.service.xml
new file mode 100644 (file)
index 0000000..62f6311
--- /dev/null
@@ -0,0 +1,110 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-fsck@.service">
+
+        <refentryinfo>
+                <title>systemd-fsck@.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-fsck@.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-fsck@.service</refname>
+                <refname>systemd-fsck-root.service</refname>
+                <refname>systemd-fsck</refname>
+                <refpurpose>File system checker logic</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-fsck@.service</filename></para>
+                <para><filename>systemd-fsck-root.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-fsck</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-fsck@.service</filename> is a
+                service responsible for file system checks. It is
+                instantiated for each device that requires a file
+                system
+                check. <filename>systemd-fsck-root.service</filename> is
+                responsible for file system checks on the root
+                file system.</para>
+
+                <para><filename>systemd-fsck</filename> will
+                forward file system checking progress to the
+                console. If a file system check fails emergency mode
+                is activated, by isolating to
+                <filename>emergency.target</filename>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Command Line</title>
+
+                <para><filename>systemd-fsck</filename> understands
+                one kernel command line parameter:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>fsck.mode=</varname></term>
+
+                                <listitem><para>One of
+                                <literal>auto</literal>,
+                                <literal>force</literal>,
+                                <literal>skip</literal>. Controls the
+                                mode of operation. The default is
+                                <literal>auto</literal>, and ensures
+                                that file system checks are done when
+                                the file system checker deems them
+                                necessary. <literal>force</literal>
+                                unconditionally results in full file
+                                system checks. <literal>skip</literal>
+                                skips any file system
+                                checks.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-quotacheck.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml
new file mode 100644 (file)
index 0000000..b265b6c
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-fstab-generator">
+
+        <refentryinfo>
+                <title>systemd-fstab-generator</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-fstab-generator</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-fstab-generator</refname>
+                <refpurpose>Unit generator for /etc/fstab</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/usr/lib/systemd/system-generators/systemd-fstab-generator</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-fstab-generator</filename> is
+                a generator that translates
+                <filename>/etc/fstab</filename> (see
+                <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details) into native systemd units early at boot
+                and when configuration of the system manager is
+                reloaded. This will instantiate mount and swap units
+                as necessary.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more information about special
+                <filename>/etc/fstab</filename> mount options this
+                generator understands.</para>
+
+                <para><filename>systemd-fstab-generator</filename>
+                implements the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/Generators">generator
+                specification</ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Command Line</title>
+
+                <para><filename>systemd-fstab-generator</filename> understands
+                the following kernel command line parameters:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>fstab=</varname></term>
+                                <term><varname>rd.fstab=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. Defaults to
+                                <literal>yes</literal>. If
+                                <literal>no</literal> causes the
+                                generator to ignore any mounts or swaps
+                                configured in
+                                <filename>/etc/fstab</filename>. <varname>rd.fstab=</varname>
+                                is honored only by initial RAM disk
+                                (initrd) while
+                                <varname>fstab=</varname> is
+                                honored by both the main system and
+                                the initrd.  </para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-getty-generator.xml b/man/systemd-getty-generator.xml
new file mode 100644 (file)
index 0000000..da88e72
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-getty-generator">
+
+        <refentryinfo>
+                <title>systemd-getty-generator</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-getty-generator</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-getty-generator</refname>
+                <refpurpose>Generator for enabling getty instances on
+                the console</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/usr/lib/systemd/system-generators/systemd-getty-generator</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-getty-generator</filename> is
+                a generator that automatically instantiates
+                <filename>serial-getty@.service</filename> on the
+                kernel console <filename>/dev/console</filename> if
+                that is not directed to the virtual console
+                subsystem. It will also instantiate
+                <filename>serial-getty@.service</filename> instances
+                for virtualizer consoles, if execution in a
+                virtualized environment is detected. This should
+                ensure that the user is shown a login prompt at the
+                right place, regardless in which environment the
+                system is started. For example, it is sufficient to
+                redirect the kernel console with a kernel command line
+                argument such as <varname>console=</varname> to get
+                both kernel messages and a getty prompt on a serial
+                TTY. See <ulink
+                url="https://www.kernel.org/doc/Documentation/kernel-parameters.txt"><filename>kernel-parameters.txt</filename></ulink>
+                for more information on the
+                <varname>console=</varname> kernel parameter.</para>
+
+                <para><filename>systemd-getty-generator</filename>
+                implements the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/Generators">generator
+                specification</ulink>.</para>
+
+                <para>Further information about configuration of
+                gettys you may find in <ulink
+                url="http://0pointer.de/blog/projects/serial-console.html">systemd
+                for Administrators, Part XVI: Gettys on Serial
+                Consoles (and Elsewhere)</ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>agetty</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-halt.service.xml b/man/systemd-halt.service.xml
new file mode 100644 (file)
index 0000000..6a6bfdc
--- /dev/null
@@ -0,0 +1,119 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-halt.service">
+
+        <refentryinfo>
+                <title>systemd-halt.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-halt.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-halt.service</refname>
+                <refname>systemd-poweroff.service</refname>
+                <refname>systemd-reboot.service</refname>
+                <refname>systemd-kexec.service</refname>
+                <refname>systemd-shutdown</refname>
+                <refpurpose>System shutdown logic</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-halt.service</filename></para>
+                <para><filename>systemd-poweroff.service</filename></para>
+                <para><filename>systemd-reboot.service</filename></para>
+                <para><filename>systemd-kexec.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-shutdown</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-halt.service</filename> is a
+                system service that is pulled in by
+                <filename>halt.target</filename> and is responsible
+                for the actual system halt. Similar,
+                <filename>systemd-poweroff.service</filename> is
+                pulled in by <filename>poweroff.target</filename>,
+                <filename>systemd-reboot.service</filename> by
+                <filename>reboot.target</filename> and
+                <filename>systemd-kexec.service</filename> by
+                <filename>kexec.target</filename> to execute the
+                respective actions.</para>
+
+                <para>When these services are run they ensure that PID
+                1 is replaced by the
+                <filename>/usr/lib/systemd/systemd-shutdown</filename>
+                tool which is then responsible for the actual
+                shutdown. Before shutting down this binary will try to
+                unmount all remaining file systems, disable all
+                remaining swap devices, detach all remaining storage
+                devices and kill all remaining processes.</para>
+
+                <para>Immediately before executing the actual system
+                halt/poweroff/reboot/kexec
+                <filename>systemd-shutdown</filename> will run all
+                executables in
+                <filename>/usr/lib/systemd/system-shutdown/</filename>
+                and pass one arguments to them: either
+                "<literal>halt</literal>",
+                "<literal>poweroff</literal>",
+                "<literal>reboot</literal>" or
+                "<literal>kexec</literal>", depending on the chosen
+                action. All executables in this directory are executed
+                in parallel, and execution of the action is not
+                continued before all executables finished.</para>
+
+                <para>Note that
+                <filename>systemd-halt.service</filename> (and the
+                related units) should never be executed
+                directly. Instead, trigger system shutdown with a
+                command such as "<literal>systemctl halt</literal>" or
+                suchlike.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-suspend.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-hostnamed.service.xml b/man/systemd-hostnamed.service.xml
new file mode 100644 (file)
index 0000000..d9c1911
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-hostnamed.service">
+
+        <refentryinfo>
+                <title>systemd-hostnamed.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-hostnamed.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-hostnamed.service</refname>
+                <refname>systemd-hostnamed</refname>
+                <refpurpose>Hostname bus mechanism</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-hostnamed.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-hostnamed</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-hostnamed</filename> is a system
+                service that may be used as mechanism to change the
+                system hostname. <filename>systemd-hostnamed</filename> is
+                automatically activated on request and terminates
+                itself when it is unused.</para>
+
+                <para>The tool
+                <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                is a command line client to this service.</para>
+
+                <para>See the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/hostnamed">
+                developer documentation</ulink> for information about
+                the APIs <filename>systemd-hostnamed</filename>
+                provides.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-inhibit.xml b/man/systemd-inhibit.xml
new file mode 100644 (file)
index 0000000..6f63c8c
--- /dev/null
@@ -0,0 +1,205 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-inhibit">
+
+        <refentryinfo>
+                <title>systemd-inhibit</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-inhibit</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-inhibit</refname>
+                <refpurpose>Execute a program with an inhibition lock taken</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-inhibit <arg choice="opt" rep="repeat">OPTIONS</arg> <arg>COMMAND</arg> <arg choice="opt" rep="repeat">ARGUMENTS</arg></command>
+                </cmdsynopsis>
+                <cmdsynopsis>
+                        <command>systemd-inhibit <arg choice="opt" rep="repeat">OPTIONS</arg> --list</command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-inhibit</command> may be used
+                to execute a program with a shutdown, sleep or idle
+                inhibitor lock taken. The lock will be acquired before
+                the specified command line is executed and released
+                afterwards.</para>
+
+                <para>Inhibitor locks may be used to block or delay
+                system sleep and shutdown requests from the user, as well
+                as automatic idle handling of the OS. This is useful
+                to avoid system suspends while an optical disc is
+                being recorded, or similar operations that should not
+                be interrupted.</para>
+
+                <para>For more information see the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
+                Lock Developer Documentation</ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--what=</option></term>
+
+                                <listitem><para>Takes a colon
+                                separated list of one or more
+                                operations to inhibit:
+                                <literal>shutdown</literal>,
+                                <literal>sleep</literal>,
+                                <literal>idle</literal>,
+                                <literal>handle-power-key</literal>,
+                                <literal>handle-suspend-key</literal>,
+                                <literal>handle-hibernate-key</literal>,
+                                <literal>handle-lid-switch</literal>,
+                                for inhibiting
+                                reboot/power-off/halt/kexec,
+                                suspending/hibernating, the automatic
+                                idle detection, or the low-level
+                                handling of the power/sleep key and
+                                the lid switch, respectively. If omitted,
+                                defaults to
+                                <literal>idle:sleep:shutdown</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--who=</option></term>
+
+                                <listitem><para>Takes a short human
+                                readable descriptive string for the
+                                program taking the lock. If not passed
+                                defaults to the command line
+                                string.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--why=</option></term>
+
+                                <listitem><para>Takes a short human
+                                readable descriptive string for the
+                                reason for taking the lock. Defaults
+                                to "Unknown reason".</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--mode=</option></term>
+
+                                <listitem><para>Takes either
+                                <literal>block</literal> or
+                                <literal>delay</literal> and describes
+                                how the lock is applied. If
+                                <literal>block</literal> is used (the
+                                default), the lock prohibits any of
+                                the requested operations without time
+                                limit, and only privileged users may
+                                override it. If
+                                <literal>delay</literal> is used, the
+                                lock can only delay the requested
+                                operations for a limited time. If the
+                                time elapses the lock is ignored and
+                                the operation executed. The time limit
+                                may be specified in
+                                <citerefentry><refentrytitle>systemd-logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Note
+                                that <literal>delay</literal> is only
+                                available for <literal>sleep</literal>
+                                and
+                                <literal>shutdown</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--list</option></term>
+
+                                <listitem><para>Lists all active
+                                inhibition locks instead of acquiring
+                                one.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>Returns the exit status of the executed program.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+
+                <programlisting># systemd-inhibit wodim foobar.iso</programlisting>
+
+                <para>This burns the ISO image
+                <filename>foobar.iso</filename> on a CD using
+                <citerefentry><refentrytitle>wodim</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                and inhibits system sleeping, shutdown and idle while
+                doing so.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-initctl.service.xml b/man/systemd-initctl.service.xml
new file mode 100644 (file)
index 0000000..eda6459
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-initctl.service">
+
+        <refentryinfo>
+                <title>systemd-initctl.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-initctl.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-initctl.service</refname>
+                <refname>systemd-initctl.socket</refname>
+                <refname>systemd-initctl</refname>
+                <refpurpose>/dev/initctl compatibility</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-initctl.service</filename></para>
+                <para><filename>systemd-initctl.socket</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-initctl</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-initctl</filename> is a system
+                service that implements compatibility with the
+                <filename>/dev/initctl</filename> FIFO file system
+                object, as implemented by the SysV init system. <filename>systemd-initctl</filename> is
+                automatically activated on request and terminates
+                itself when it is unused.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml
new file mode 100644 (file)
index 0000000..562d221
--- /dev/null
@@ -0,0 +1,274 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-journal-gatewayd.service">
+
+  <refentryinfo>
+    <title>systemd-journal-gatewayd.service</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-journal-gatewayd.service</refentrytitle>
+    <manvolnum>8</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-journal-gatewayd.service</refname>
+    <refname>systemd-journal-gatewayd.socket</refname>
+    <refname>systemd-journal-gatewayd</refname>
+    <refpurpose>HTTP server for journal events</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>systemd-journal-gatewayd.service</filename></para>
+    <para><filename>systemd-journal-gatewayd.socket</filename></para>
+    <cmdsynopsis><command>/usr/lib/systemd/systemd-journal-gatewayd</command>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><command>systemd-journal-gatewayd</command> serves journal
+    events over the network. Clients must connect using
+    HTTP. The server listens on port 19531 by default.</para>
+
+    <para>The program is started by
+    <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    and expects to receive a single socket. Use
+    <command>systemctl start systemd-journal-gatewayd.socket</command> to start
+    the service, and <command>systemctl enable systemd-journal-gatewayd.socket</command>
+    to have it started on boot.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Supported URLs</title>
+
+    <para>The following URLs are recognized:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>/browse</option></term>
+
+        <listitem><para>Interactive browsing.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>/entries[?option1&amp;option2=value...]</option></term>
+
+        <listitem><para>Retrieval of events in various formats.</para>
+
+        <para>The <option>Accept:</option> part of the HTTP header
+        determines the format. Supported values are described below.
+        </para>
+
+        <para>The <option>Range:</option> part of the HTTP header
+        determines the range of events returned. Supported values are
+        described below.
+        </para>
+
+        <para>GET parameters can be used to modify what events are
+        returned. Supported parameters are described below.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>/machine</option></term>
+
+        <listitem><para>Return a JSON structure describing the machine.</para>
+
+        <para>Example:
+        <programlisting>
+{ "machine_id" : "8cf7ed9d451ea194b77a9f118f3dc446",
+  "boot_id" : "3d3c9efaf556496a9b04259ee35df7f7",
+  "hostname" : "fedora",
+  "os_pretty_name" : "Fedora 19 (Rawhide)",
+  "virtualization" : "kvm",
+  ...}
+        </programlisting>
+        </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>/fields/</option><replaceable>FIELD_NAME</replaceable></term>
+
+        <listitem><para>Return a list of values of this field present in the logs.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Accept header</title>
+
+    <para>
+      <option>Accept: </option><replaceable>format</replaceable>
+    </para>
+
+    <para>Recognized formats:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>text/plain</option></term>
+
+        <listitem><para>The default. Plaintext syslog-like output,
+        one line per journal entry
+        (like <command>journalctl --output short</command>).</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>application/json</option></term>
+
+        <listitem><para>Entries are formatted as JSON data structures,
+        one per line
+        (like <command>journalctl --output json</command>).
+        See <ulink
+        url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal
+        JSON Format</ulink> for more information.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>application/event-stream</option></term>
+
+        <listitem><para>Entries are formatted as JSON data structures,
+        wrapped in a format suitable for <ulink
+        url="https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events">
+        Server-Sent Events</ulink>
+        (like <command>journalctl --output json-sse</command>).
+        </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>application/vnd.fdo.journal</option></term>
+
+        <listitem><para>Entries are serialized into a binary (but
+        mostly text-based) stream suitable for backups and network
+        transfer
+        (like <command>journalctl --output export</command>).
+        See <ulink
+        url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+        Export Format</ulink> for more information.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Range header</title>
+
+    <para>
+      <option>Range: entries=&lt;cursor&gt;[[:&lt;num_skip&gt;]:&lt;num_entries&gt;]</option>
+    </para>
+
+    <para>where
+      <option>cursor</option> is a cursor string,
+      <option>num_skip</option> is an integer,
+      <option>num_entries</option> is an unsigned integer.
+    </para>
+
+    <para>Range defaults to all available events.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>URL GET parameters</title>
+
+    <para>Following parameters can be used as part of the URL:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>follow</option></term>
+
+        <listitem><para>wait for new events
+        (like <command>journalctl --follow</command>, except that
+        the number of events returned is not limited).</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>discrete</option></term>
+
+        <listitem><para>Test that the specified cursor refers to an
+        entry in the journal. Returns just this entry.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>boot</option></term>
+
+        <listitem><para>Limit events to the current boot of the system
+        (like <command>journalctl --this--boot</command>).</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>&lt;KEY&gt;=&lt;match&gt;</option></term>
+
+        <listitem><para>Match journal fields. See
+        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+    <para>Retrieve events from this boot from local journal
+    in <ulink
+    url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+    Export Format</ulink>:
+    <programlisting>
+curl --silent -H'Accept: application/vnd.fdo.journal' \
+       'http://localhost:19531/entries?boot'
+    </programlisting>
+    </para>
+
+    <para>Listen for core dumps:
+    <programlisting>
+curl 'http://localhost:19531/entries?follow&amp;MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1'
+    </programlisting></para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+    </para>
+  </refsect1>
+
+</refentry>
diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml
new file mode 100644 (file)
index 0000000..abc03df
--- /dev/null
@@ -0,0 +1,173 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-journald.service">
+
+        <refentryinfo>
+                <title>systemd-journald.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-journald.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-journald.service</refname>
+                <refname>systemd-journald.socket</refname>
+                <refname>systemd-journald</refname>
+                <refpurpose>Journal service</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-journald.service</filename></para>
+                <para><filename>systemd-journald.socket</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-journald</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-journald</filename> is a
+                system service that collects and stores logging
+                data. It creates and maintains structured, indexed
+                journals based on logging information that is received
+                from the kernel, from user processes via the libc
+                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call, from STDOUT/STDERR of system services or via its
+                native API. It will implicitly collect numerous meta
+                data fields for each log messages in a secure and
+                unfakeable way. See
+                <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                for more information about the collected meta data.
+                </para>
+
+                <para>Log data collected by the journal is primarily
+                text based but can also include binary data where
+                necessary. All objects stored in the journal can be up
+                to 2^64-1 bytes in size.</para>
+
+                <para>By default the journal stores log data in
+                <filename>/run/log/journal/</filename>. Since
+                <filename>/run/</filename> is volatile log data is
+                lost at reboot. To make the data persistent it
+                is sufficient to create
+                <filename>/var/log/journal/</filename> where
+                <filename>systemd-journald</filename> will then store
+                the data.</para>
+
+                <para><filename>systemd-journald</filename> will
+                forward all received log messages to the AF_UNIX
+                SOCK_DGRAM socket
+                <filename>/run/systemd/journal/syslog</filename> (if it exists) which
+                may be used by UNIX syslog daemons to process the data
+                further.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for information about the configuration of this
+                service.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Signals</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>SIGUSR1</term>
+
+                                <listitem><para>Request that journal
+                                data from <filename>/run/</filename>
+                                is flushed to
+                                <filename>/var/</filename> in order to
+                                make it persistent (if this is
+                                enabled). This may be used after
+                                <filename>/var/</filename> is mounted,
+                                but is generally not required since
+                                the first journal write when
+                                <filename>/var/</filename> becomes
+                                writable triggers the flushing
+                                anyway.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGUSR2</term>
+
+                                <listitem><para>Request immediate
+                                rotation of the journal
+                                files.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Command Line</title>
+
+                <para>A few configuration parameters from
+                <filename>journald.conf</filename> may be overridden on
+                the kernel command line:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>systemd.journald.forward_to_syslog=</varname></term>
+                                <term><varname>systemd.journald.forward_to_kmsg=</varname></term>
+                                <term><varname>systemd.journald.forward_to_console=</varname></term>
+
+                                <listitem><para>Enables/disables
+                                forwarding of collected log messages
+                                to syslog, the kernel log buffer or
+                                the system console.
+                                </para>
+
+                                <para>See
+                                <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for information about these settings.</para>
+                                </listitem>
+
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-localed.service.xml b/man/systemd-localed.service.xml
new file mode 100644 (file)
index 0000000..6cefc42
--- /dev/null
@@ -0,0 +1,89 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-localed.service">
+
+        <refentryinfo>
+                <title>systemd-localed.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-localed.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-localed.service</refname>
+                <refname>systemd-localed</refname>
+                <refpurpose>Locale bus mechanism</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-localed.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-localed</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-localed</filename> is a system
+                service that may be used as mechanism to change the
+                system locale settings, as well as the console key
+                mapping and default X11 key
+                mapping. <filename>systemd-localed</filename> is
+                automatically activated on request and terminates
+                itself when it is unused.</para>
+
+                <para>The tool
+                <citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                is a command line client to this service.</para>
+
+                <para>See the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/localed">
+                developer documentation</ulink> for information about
+                the APIs <filename>systemd-localed</filename>
+                provides.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml
new file mode 100644 (file)
index 0000000..00f3405
--- /dev/null
@@ -0,0 +1,133 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-logind.service">
+
+        <refentryinfo>
+                <title>systemd-logind.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-logind.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-logind.service</refname>
+                <refname>systemd-logind</refname>
+                <refpurpose>Login manager</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-logind.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-logind</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-logind</filename> is a system
+                service that manages user logins. It is responsible
+                for:</para>
+
+                <itemizedlist>
+                        <listitem><para>Keeping track of users and sessions, their
+                        processes and their idle state</para></listitem>
+
+                        <listitem><para>Creating control groups for
+                        user processes</para></listitem>
+
+                        <listitem><para>Providing PolicyKit-based access
+                        for users to operations such as system
+                        shutdown or sleep</para></listitem>
+
+                        <listitem><para>Implementing a shutdown/sleep
+                        inhibition logic for
+                        applications</para></listitem>
+
+                        <listitem><para>Handling of power/sleep
+                        hardware keys</para></listitem>
+
+                        <listitem><para>Multi-seat
+                        management</para></listitem>
+
+                        <listitem><para>Session
+                        switch management</para></listitem>
+
+                        <listitem><para>Device access management for
+                        users</para></listitem>
+
+                        <listitem><para>Automatic spawning of text
+                        logins (gettys) on virtual console activation
+                        and user runtime directory
+                        management</para></listitem>
+                </itemizedlist>
+
+                <para>User sessions are registered in logind via the
+                <citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                PAM module.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for information about the configuration of this
+                service.</para>
+
+                <para>See <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
+                on Linux</ulink> for an introduction into basic
+                concepts of logind such as users, sessions and seats.</para>
+
+                <para>See the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/logind">
+                logind D-Bus API Documentation</ulink> for information about
+                the APIs <filename>systemd-logind</filename>
+                provides.</para>
+
+                <para>For more information on the inhibition logic see
+                the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
+                Lock Developer Documentation</ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-user-sessions.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-machine-id-setup.xml b/man/systemd-machine-id-setup.xml
new file mode 100644 (file)
index 0000000..25fb63a
--- /dev/null
@@ -0,0 +1,132 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-machine-id-setup">
+
+        <refentryinfo>
+                <title>systemd-machine-id-setup</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-machine-id-setup</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-machine-id-setup</refname>
+                <refpurpose>Initialize the machine ID in /etc/machine-id</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-machine-id-setup</command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-machine-id-setup</command> may
+                be used by system installer tools to initialize the
+                machine ID stored in
+                <filename>/etc/machine-id</filename> at install time
+                with a randomly generated ID. See
+                <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more information about this file.</para>
+
+                <para>This tool will execute no operation if
+                <filename>/etc/machine-id</filename> is already
+                initialized.</para>
+
+                <para>If a valid D-Bus machine ID is already
+                configured for the system the D-Bus machine ID is
+                copied and used to initialize the machine ID in
+                <filename>/etc/machine-id</filename>.</para>
+
+                <para>If run inside a KVM virtual machine and a UUID
+                is passed via the <option>-uuid</option> option this
+                UUID is used to initialize the machine ID instead of a
+                randomly generated one. The caller must ensure that the
+                UUID passed is sufficiently unique and is different
+                for every booted instanced of the VM.</para>
+
+                <para>Similar, if run inside a Linux container
+                environment and a UUID is set for the container this
+                is used to initialize the machine ID. For details see
+                the documentation of the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
+                Interface</ulink>.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>dbus-uuidgen</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-modules-load.service.xml b/man/systemd-modules-load.service.xml
new file mode 100644 (file)
index 0000000..e5f10a7
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-modules-load.service">
+
+        <refentryinfo>
+                <title>systemd-modules-load.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-modules-load.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-modules-load.service</refname>
+                <refname>systemd-modules-load</refname>
+                <refpurpose>Configure kernel modules to load at boot</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-modules-load.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-modules-load</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-modules-load.service</filename>
+                is an early-boot service that loads kernel modules
+                from static configuration.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>modules-load.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for information about the configuration of this
+                service.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Command Line</title>
+
+                <para><filename>systemd-modules-load.service</filename> understands
+                the following kernel command line parameters:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>modules-load=</varname></term>
+                                <term><varname>rd.modules-load=</varname></term>
+
+                                <listitem><para>Takes a comma
+                                separated list of kernel modules to
+                                statically load during early boot. The
+                                option prefixed with
+                                <literal>rd.</literal> is read by the
+                                initial RAM disk
+                                only.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>modules-load.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wine</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml
new file mode 100644 (file)
index 0000000..b03492c
--- /dev/null
@@ -0,0 +1,218 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-notify">
+
+        <refentryinfo>
+                <title>systemd-notify</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-notify</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-notify</refname>
+                <refpurpose>Notify service manager about start-up completion and other daemon status changes</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-notify <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">VARIABLE=VALUE</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-notify</command> may be
+                called by daemon scripts to notify the init system
+                about status changes. It can be used to send arbitrary
+                information, encoded in an environment-block-like list
+                of strings. Most importantly it can be used for
+                start-up completion notification.</para>
+
+                <para>This is mostly just a wrapper around
+                <function>sd_notify()</function> and makes this
+                functionality available to shell scripts. For details
+                see
+                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+                <para>The command line may carry a list of
+                environment variables to send as part of the status
+                update.</para>
+
+                <para>Note that systemd will refuse reception of
+                status updates from this command unless
+                <varname>NotifyAccess=all</varname> is set for the
+                service unit this command is called from.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--ready</option></term>
+
+                                <listitem><para>Inform the init system
+                                about service start-up
+                                completion. This is equivalent to
+                                <command>systemd-notify
+                                READY=1</command>. For details about
+                                the semantics of this option see
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--pid=</option></term>
+
+                                <listitem><para>Inform the init system
+                                about the main PID of the
+                                daemon. Takes a PID as argument. If
+                                the argument is omitted the PID of the
+                                process that invoked
+                                <command>systemd-notify</command> is
+                                used. This is equivalent to
+                                <command>systemd-notify
+                                MAINPID=$PID</command>. For details
+                                about the semantics of this option see
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--status=</option></term>
+
+                                <listitem><para>Send a free-form
+                                status string for the daemon to the
+                                init systemd. This option takes the
+                                status string as argument. This is
+                                equivalent to <command>systemd-notify
+                                STATUS=...</command>. For details
+                                about the semantics of this option see
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--booted</option></term>
+
+                                <listitem><para>Returns 0 if the
+                                system was booted up with systemd,
+                                non-zero otherwise. If this option is
+                                passed no message is sent. This option
+                                is hence unrelated to the other
+                                options. For details about the
+                                semantics of this option see
+                                <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--readahead=</option></term>
+
+                                <listitem><para>Controls disk
+                                read-ahead operations. The argument
+                                must be a string, and either "cancel",
+                                "done" or "noreplay". For details
+                                about the semantics of this option see
+                                <citerefentry><refentrytitle>sd_readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+
+                <example>
+                        <title>Start-up Notification and Status Updates</title>
+
+                        <para>A simple shell daemon that sends
+                        start-up notifications after having set up its
+                        communication channel. During runtime it sends
+                        further status updates to the init
+                        system:</para>
+
+                        <programlisting>#!/bin/bash
+
+mkfifo /tmp/waldo
+systemd-notify --ready --status="Waiting for data..."
+
+while : ; do
+        read a &lt; /tmp/waldo
+        systemd-notify --status="Processing $a"
+
+        # Do something with $a ...
+
+        systemd-notify --status="Waiting for data..."
+done</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
new file mode 100644 (file)
index 0000000..fef5c2c
--- /dev/null
@@ -0,0 +1,331 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-nspawn">
+
+        <refentryinfo>
+                <title>systemd-nspawn</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-nspawn</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-nspawn</refname>
+                <refpurpose>Spawn a namespace container for debugging, testing and building</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-nspawn <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">COMMAND</arg> <arg choice="opt" rep="repeat">ARGS</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-nspawn</command> may be used to
+                run a command or OS in a light-weight namespace
+                container. In many ways it is similar to
+                <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                but more powerful since it fully virtualizes the file
+                system hierarchy, as well as the process tree, the
+                various IPC subsystems and the host and domain
+                name.</para>
+
+                <para><command>systemd-nspawn</command> limits access
+                to various kernel interfaces in the container to
+                read-only, such as <filename>/sys</filename>,
+                <filename>/proc/sys</filename> or
+                <filename>/sys/fs/selinux</filename>. Network
+                interfaces and the system clock may not be changed
+                from within the container. Device nodes may not be
+                created. The host system cannot be rebooted and kernel
+                modules may not be loaded from within the
+                container.</para>
+
+                <para>Note that even though these security precautions
+                are taken <command>systemd-nspawn</command> is not
+                suitable for secure container setups. Many of the
+                security features may be circumvented and are hence
+                primarily useful to avoid accidental changes to the
+                host system from the container. The intended use of
+                this program is debugging and testing as well as
+                building of packages, distributions and software
+                involved with boot and systems management.</para>
+
+                <para>In contrast to
+                <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <command>systemd-nspawn</command> may be used to boot
+                full Linux-based operating systems in a
+                container.</para>
+
+                <para>Use a tool like
+                <citerefentry><refentrytitle>yum</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                or
+                <citerefentry><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                to set up an OS directory tree suitable as file system
+                hierarchy for <command>systemd-nspawn</command>
+                containers.</para>
+
+                <para>Note that <command>systemd-nspawn</command> will
+                mount file systems private to the container to
+                <filename>/dev</filename>,
+                <filename>/run</filename> and similar. These will
+                not be visible outside of the container, and their
+                contents will be lost when the container exits.</para>
+
+                <para>Note that running two
+                <command>systemd-nspawn</command> containers from the
+                same directory tree will not make processes in them
+                see each other. The PID namespace separation of the
+                two containers is complete and the containers will
+                share very few runtime objects except for the
+                underlying file system.</para>
+
+                <para><command>systemd-nspawn</command> implements the
+                <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
+                Interface</ulink> specification.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>If no arguments are passed the container is set
+                up and a shell started in it, otherwise the passed
+                command and arguments are executed in it. The
+                following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--directory=</option></term>
+                                <term><option>-D</option></term>
+
+                                <listitem><para>Directory to use as
+                                file system root for the namespace
+                                container. If omitted the current
+                                directory will be
+                                used.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--boot</option></term>
+                                <term><option>-b</option></term>
+
+                                <listitem><para>Automatically search
+                                for an init binary and invoke it
+                                instead of a shell or a user supplied
+                                program.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--user=</option></term>
+                                <term><option>-u</option></term>
+
+                                <listitem><para>Run the command
+                                under specified user, create home
+                                directory and cd into it. As rest
+                                of systemd-nspawn, this is not
+                                the security feature and limits
+                                against accidental changes only.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--uuid=</option></term>
+
+                                <listitem><para>Set the specified uuid
+                                for the container. The init system
+                                will initialize
+                                <filename>/etc/machine-id</filename>
+                                from this if this file is not set yet.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--controllers=</option></term>
+                                <term><option>-C</option></term>
+
+                                <listitem><para>Makes the container appear in
+                                other hierarchies than the name=systemd:/ one.
+                                Takes a comma-separated list of controllers.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--private-network</option></term>
+
+                                <listitem><para>Turn off networking in
+                                the container. This makes all network
+                                interfaces unavailable in the
+                                container, with the exception of the
+                                loopback device.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--read-only</option></term>
+
+                                <listitem><para>Mount the root file
+                                system read only for the
+                                container.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--capability=</option></term>
+
+                                <listitem><para>List one or more
+                                additional capabilities to grant the
+                                container. Takes a comma separated
+                                list of capability names, see
+                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for more information. Note that the
+                                following capabilities will be
+                                granted in any way: CAP_CHOWN,
+                                CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH,
+                                CAP_FOWNER, CAP_FSETID, CAP_IPC_OWNER,
+                                CAP_KILL, CAP_LEASE,
+                                CAP_LINUX_IMMUTABLE,
+                                CAP_NET_BIND_SERVICE,
+                                CAP_NET_BROADCAST, CAP_NET_RAW,
+                                CAP_SETGID, CAP_SETFCAP, CAP_SETPCAP,
+                                CAP_SETUID, CAP_SYS_ADMIN,
+                                CAP_SYS_CHROOT, CAP_SYS_NICE,
+                                CAP_SYS_PTRACE, CAP_SYS_TTY_CONFIG,
+                                CAP_SYS_RESOURCE, CAP_SYS_BOOT.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--link-journal=</option></term>
+
+                                <listitem><para>Control whether the
+                                container's journal shall be made
+                                visible to the host system. If enabled
+                                allows viewing the container's journal
+                                files from the host (but not vice
+                                versa). Takes one of
+                                <literal>no</literal>,
+                                <literal>host</literal>,
+                                <literal>guest</literal>,
+                                <literal>auto</literal>. If
+                                <literal>no</literal>, the journal is
+                                not linked. If <literal>host</literal>,
+                                the journal files are stored on the
+                                host file system (beneath
+                                <filename>/var/log/journal/&lt;machine-id&gt;</filename>)
+                                and the subdirectory is bind-mounted
+                                into the container at the same
+                                location. If <literal>guest</literal>,
+                                the journal files are stored on the
+                                guest file system (beneath
+                                <filename>/var/log/journal/&lt;machine-id&gt;</filename>)
+                                and the subdirectory is symlinked into the host
+                                at the same location. If
+                                <literal>auto</literal> (the default),
+                                and the right subdirectory of
+                                <filename>/var/log/journal</filename>
+                                exists, it will be bind mounted
+                                into the container. If the
+                                subdirectory doesn't exist, no
+                                linking is performed. Effectively,
+                                booting a container once with
+                                <literal>guest</literal> or
+                                <literal>host</literal> will link the
+                                journal persistently if further on
+                                the default of <literal>auto</literal>
+                                is used.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-j</option></term>
+
+                                <listitem><para>Equivalent to
+                                <option>--link-journal=guest</option>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Example 1</title>
+
+                <programlisting># yum --releasever=17 --nogpgcheck --installroot ~/fedora-tree/ install yum passwd vim-minimal rootfiles systemd
+# systemd-nspawn -D ~/fedora-tree /usr/lib/systemd/systemd</programlisting>
+
+                <para>This installs a minimal Fedora distribution into
+                the directory <filename>~/fedora-tree/</filename>
+                and then boots an OS in a namespace container in it,
+                with systemd as init system.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example 2</title>
+
+                <programlisting># debootstrap --arch=amd64 unstable ~/debian-tree/
+# systemd-nspawn -D ~/debian-tree/</programlisting>
+
+                <para>This installs a minimal Debian unstable
+                distribution into the directory
+                <filename>~/debian-tree/</filename> and then spawns a
+                shell in a namespace container in it.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>The exit code of the program executed in the
+                container is returned.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>yum</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-quotacheck.service.xml b/man/systemd-quotacheck.service.xml
new file mode 100644 (file)
index 0000000..4d0218b
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-quotacheck.service">
+
+        <refentryinfo>
+                <title>systemd-quotacheck.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-quotacheck.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-quotacheck.service</refname>
+                <refname>systemd-quotacheck</refname>
+                <refpurpose>File system quota checker logic</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-quotacheck.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-quotacheck</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-quotacheck.service</filename>
+                is a service responsible for file system quota
+                checks. It is run once at boot after all necessary
+                file systems are mounted. It is pulled in only if at
+                least one file system has quotas enabled.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Command Line</title>
+
+                <para><filename>systemd-quotacheck</filename> understands
+                one kernel command line parameter:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>quotacheck.mode=</varname></term>
+
+                                <listitem><para>One of
+                                <literal>auto</literal>,
+                                <literal>force</literal>,
+                                <literal>skip</literal>. Controls the
+                                mode of operation. The default is
+                                <literal>auto</literal>, and ensures
+                                that file system quota checks are done
+                                when the file system quota checker
+                                deems them
+                                necessary. <literal>force</literal>
+                                unconditionally results in full file
+                                system quota
+                                checks. <literal>skip</literal> skips
+                                any file system quota
+                                checks.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>quotacheck</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-fsck@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-random-seed-load.service.xml b/man/systemd-random-seed-load.service.xml
new file mode 100644 (file)
index 0000000..87f563e
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-random-seed-load.service">
+
+        <refentryinfo>
+                <title>systemd-random-seed-load.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-random-seed-load.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-random-seed-load.service</refname>
+                <refname>systemd-random-seed-save.service</refname>
+                <refname>systemd-random-seed</refname>
+                <refpurpose>Load and save the system random seed at boot and shutdown</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-random-seed-load.service</filename></para>
+                <para><filename>systemd-random-seed-save.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-random-seed</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-random-seed-load.service</filename>
+                is an early-boot service that restores the random seed
+                of the
+                system. <filename>systemd-random-seed-save.service</filename>
+                is a late-shutdown service that saves the random seed
+                of the system. See
+                <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>
+                for details. Saving/restoring the random seed across
+                boots increases the amount of available entropy early
+                at boot. On disk the random seed is stored in
+                <filename>/var/lib/random-seed</filename>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-readahead-replay.service.xml b/man/systemd-readahead-replay.service.xml
new file mode 100644 (file)
index 0000000..66d2534
--- /dev/null
@@ -0,0 +1,113 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-readahead-replay.service">
+
+        <refentryinfo>
+                <title>systemd-readahead-replay.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-readahead-replay.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-readahead-replay.service</refname>
+                <refname>systemd-readahead-collect.service</refname>
+                <refname>systemd-readahead-done.service</refname>
+                <refname>systemd-readahead-done.timer</refname>
+                <refname>systemd-readahead</refname>
+                <refpurpose>Disk read ahead logic</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-readahead-replay.service</filename></para>
+                <para><filename>systemd-readahead-collect.service</filename></para>
+                <para><filename>systemd-readahead-done.service</filename></para>
+                <para><filename>systemd-readahead-done.timer</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-readahead</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-readahead-collect.service</filename>
+                is a service that collects disk usage patterns at boot
+                time. <filename>systemd-readahead-replay.service</filename>
+                is a service that replays this access data collected
+                at the subsequent boot. Since disks tend to be
+                magnitudes slower than RAM this is intended to improve
+                boot speeds by pre-loading early at boot all data on
+                disk that is known to be read for the complete boot
+                process.</para>
+
+                <para><filename>systemd-readahead-done.service</filename>
+                is executed a short while after boot completed and signals
+                <filename>systemd-readahead-collect.service</filename>
+                to end data collection. On this signal this service
+                will then sort the collected disk accesses and store
+                information about them disk in
+                <filename>/.readahead</filename>.</para>
+
+                <para>Normally, both
+                <filename>systemd-readahead-collect.service</filename>
+                and
+                <filename>systemd-readahead-replay.service</filename>
+                are activated at boot so that access patterns from the
+                preceding boot are replayed and new data collected
+                for the subsequent boot. However, on read-only media
+                where the collected data cannot be stored it might
+                be a good idea to disable
+                <filename>systemd-readahead-collect.service</filename>.</para>
+
+                <para>On rotating media, when replaying disk accesses
+                at early boot
+                <filename>systemd-readahead-replay.service</filename>
+                will order read requests by their location on disk. On
+                non-rotating media, they will be ordered by their
+                original access timestamp. If the file system supports
+                it
+                <filename>systemd-readahead-collect.service</filename>
+                will also defragment and rearrange files on disk to
+                optimize subsequent boot times.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-remount-fs.service.xml b/man/systemd-remount-fs.service.xml
new file mode 100644 (file)
index 0000000..d920c0c
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-remount-fs.service">
+
+        <refentryinfo>
+                <title>systemd-remount-fs.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-remount-fs.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-remount-fs.service</refname>
+                <refname>systemd-remount-fs</refname>
+                <refpurpose>Remount root and kernel file systems</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-remount-fs.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-remount-fs</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-remount-fs.service</filename>
+                is an early-boot service that applies mount options
+                listed in
+                <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                to the root file system, the <filename>/usr</filename>
+                file system and the kernel API virtual file
+                systems. This is required so that the mount options of
+                these file systems -- which are pre-mounted by the
+                kernel, the initial RAM disk, container environments
+                or system manager code -- are updated to those listed
+                in <filename>/etc/fstab</filename>. This service
+                ignores normal file systems and only changes the root
+                file system (i.e. <filename>/</filename>),
+                <filename>/usr</filename> and the virtual kernel API
+                file systems such as <filename>/proc</filename>,
+                <filename>/sys</filename> or
+                <filename>/dev/</filename>. This service executes no
+                operation if <filename>/etc/fstab</filename> does not
+                exist or lists no entries for the mentioned file systems.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-shutdownd.service.xml b/man/systemd-shutdownd.service.xml
new file mode 100644 (file)
index 0000000..c1b8ef7
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-shutdownd.service">
+
+        <refentryinfo>
+                <title>systemd-shutdownd.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-shutdownd.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-shutdownd.service</refname>
+                <refname>systemd-shutdownd.socket</refname>
+                <refname>systemd-shutdownd</refname>
+                <refpurpose>Scheduled shutdown service</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-shutdownd.service</filename></para>
+                <para><filename>systemd-shutdownd.socket</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-shutdownd</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-shutdownd.service</filename> is a
+                system service that implements scheduled shutdowns, as
+                exposed by
+                <citerefentry><refentrytitle>shutdown</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+                <filename>systemd-shutdownd.service</filename> is automatically activated on request and terminates
+                itself when it is unused.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>shutdown</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-suspend.service.xml b/man/systemd-suspend.service.xml
new file mode 100644 (file)
index 0000000..9b8bad4
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-suspend.service">
+
+        <refentryinfo>
+                <title>systemd-suspend.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-suspend.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-suspend.service</refname>
+                <refname>systemd-hibernate.service</refname>
+                <refname>systemd-hybrid-sleep.service</refname>
+                <refname>systemd-sleep</refname>
+                <refpurpose>System sleep state logic</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-suspend.service</filename></para>
+                <para><filename>systemd-hibernate.service</filename></para>
+                <para><filename>systemd-hybrid-sleep.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-sleep</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-suspend.service</filename> is
+                a system service that is pulled in by
+                <filename>suspend.target</filename> and is responsible
+                for the actual system suspend. Similar,
+                <filename>systemd-hibernate.service</filename> is
+                pulled in by <filename>hibernate.target</filename> to
+                execute the actual hibernation. Finally,
+                <filename>systemd-hybrid-sleep.service</filename> is
+                pulled in by <filename>hybrid-sleep.target</filename>
+                to execute hybrid hibernation with system
+                suspend.</para>
+
+                <para>Immediately before entering system suspend
+                and/or hibernation
+                <filename>systemd-suspend.service</filename> (and the
+                other mentioned units, respectively) will run all
+                executables in
+                <filename>/usr/lib/systemd/system-sleep/</filename>
+                and pass two arguments to them. The first argument
+                will be "<literal>pre</literal>", the second either
+                "<literal>suspend</literal>",
+                "<literal>hibernate</literal>", or
+                "<literal>hybrid-sleep</literal>" depending on the
+                chosen action. Immediately after leaving system
+                suspend and/or hibernation the same executables are run,
+                but the first argument is now
+                "<literal>post</literal>". All executables in this
+                directory are executed in parallel, and execution of
+                the action is not continued before all executables
+                finished.</para>
+
+                <para>Note that scripts or binaries dropped in
+                <filename>/usr/lib/systemd/system-sleep/</filename>
+                are intended for local use only and should be
+                considered hacks. If applications want to be notified
+                of system suspend/hibernation and resume there are
+                much nicer interfaces available.</para>
+
+                <para>Note that
+                <filename>systemd-suspend.service</filename>,
+                <filename>systemd-hibernate.service</filename> and
+                <filename>systemd-hybrid-sleep.service</filename>
+                should never be executed directly. Instead, trigger
+                system sleep states with a command such as
+                "<literal>systemctl suspend</literal>" or
+                similar.</para>
+
+                <para>Internally, this service will echo a string like
+                <literal>mem</literal> into
+                <filename>/sys/power/state</filename>, to trigger the
+                actual system suspend.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-halt.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-sysctl.service.xml b/man/systemd-sysctl.service.xml
new file mode 100644 (file)
index 0000000..72a102c
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-sysctl.service">
+
+        <refentryinfo>
+                <title>systemd-sysctl.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-sysctl.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-sysctl.service</refname>
+                <refname>systemd-sysctl</refname>
+                <refpurpose>Configure kernel parameters at boot</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-sysctl.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-sysctl</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-sysctl.service</filename> is
+                an early-boot service that configures
+                <citerefentry><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                kernel parameters.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for information about the configuration of this
+                service.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wine</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-system-update-generator.xml b/man/systemd-system-update-generator.xml
new file mode 100644 (file)
index 0000000..18a23ed
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-system-update-generator">
+
+        <refentryinfo>
+                <title>systemd-system-update-generator</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-system-update-generator</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-system-update-generator</refname>
+                <refpurpose>Generator for redirecting boot to offline update mode</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/usr/lib/systemd/system-generators/systemd-system-update-generator</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-system-update-generator</filename>
+                is a generator that automatically redirects the boot
+                process to <filename>system-update.target</filename>
+                if <filename>/system-update</filename> exists. This is
+                required to implement the logic explained in the
+                <ulink
+                url="http://freedesktop.org/wiki/Software/systemd/SystemUpdates">System
+                Updates Specification</ulink>.
+                </para>
+
+                <para><filename>systemd-system-update-generator</filename>
+                implements the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/Generators">generator
+                specification</ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-timedated.service.xml b/man/systemd-timedated.service.xml
new file mode 100644 (file)
index 0000000..ea2abc5
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-timedated.service">
+
+        <refentryinfo>
+                <title>systemd-timedated.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-timedated.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-timedated.service</refname>
+                <refname>systemd-timedated</refname>
+                <refpurpose>Time and date bus mechanism</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-timedated.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-timedated</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-timedated</filename> is a
+                system service that may be used as mechanism to change
+                the system clock and timezone, as well as to
+                enable/disable NTP time
+                synchronization. <filename>systemd-timedated</filename>
+                is automatically activated on request and terminates
+                itself when it is unused.</para>
+
+                <para>The tool
+                <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                is a command line client to this service.</para>
+
+                <para>See the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/timedated">
+                developer documentation</ulink> for information about
+                the APIs <filename>systemd-timedated</filename>
+                provides.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
new file mode 100644 (file)
index 0000000..22744c7
--- /dev/null
@@ -0,0 +1,162 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-tmpfiles">
+
+        <refentryinfo>
+                <title>systemd-tmpfiles</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-tmpfiles</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-tmpfiles</refname>
+                <refname>systemd-tmpfiles-setup.service</refname>
+                <refname>systemd-tmpfiles-clean.service</refname>
+                <refname>systemd-tmpfiles-clean.timer</refname>
+                <refpurpose>Creates, deletes and cleans up volatile
+                and temporary files and directories</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-tmpfiles <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">CONFIGURATION FILE</arg></command>
+                </cmdsynopsis>
+
+                <para><filename>systemd-tmpfiles-setup.service</filename></para>
+                <para><filename>systemd-tmpfiles-clean.service</filename></para>
+                <para><filename>systemd-tmpfiles-clean.timer</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-tmpfiles</command> creates,
+                deletes and cleans up volatile and temporary files and
+                directories, based on the configuration file format and
+                location specified in <citerefentry>
+                        <refentrytitle>tmpfiles.d</refentrytitle>
+                        <manvolnum>5</manvolnum>
+                </citerefentry>.</para>
+
+                <para>If invoked with no arguments, it applies all
+                directives from all configuration files. If one or
+                more file names are passed on the command line, only
+                the directives in these files are applied. If only
+                the basename of a configuration file is specified,
+                all configuration directories as specified in <citerefentry>
+                        <refentrytitle>tmpfiles.d</refentrytitle>
+                        <manvolnum>5</manvolnum>
+                </citerefentry> are searched for a matching file.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><option>--create</option></term>
+                                <listitem><para>If this option is passed all
+                                files and directories marked with f,
+                                F, d, D in the configuration files are
+                                created. Files and directories marked with z,
+                                Z have their ownership, access mode and security
+                                labels set.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--clean</option></term>
+                                <listitem><para>If this option is
+                                passed all files and directories with
+                                an age parameter configured will be
+                                cleaned up.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--remove</option></term>
+                                <listitem><para>If this option is
+                                passed all files and directories marked
+                                with r, R in the configuration files
+                                are removed.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--prefix=PATH</option></term>
+                                <listitem><para>Only apply rules that
+                                apply to paths with the specified
+                                prefix.</para></listitem>
+                        </varlistentry>
+
+
+                        <varlistentry>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+                <para>It is possible to combine
+                <option>--create</option>, <option>--clean</option>,
+                and <option>--remove</option> in one invocation. For
+                example, during boot the following command line is
+                executed to ensure that all temporary and volatile
+                directories are removed and created according to the
+                configuration file:</para>
+
+                <programlisting>systemd-tmpfiles --remove --create</programlisting>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-tty-ask-password-agent.xml b/man/systemd-tty-ask-password-agent.xml
new file mode 100644 (file)
index 0000000..31a18ba
--- /dev/null
@@ -0,0 +1,166 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-tty-ask-password-agent">
+
+        <refentryinfo>
+                <title>systemd-tty-ask-password-agent</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-tty-ask-password-agent</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-tty-ask-password-agent</refname>
+                <refpurpose>List or process pending systemd password requests</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-tty-ask-password-agent <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">VARIABLE=VALUE</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-tty-ask-password-agent</command>
+                is a password agent that handles password
+                requests of the system, for example for hard disk
+                encryption passwords or SSL certificate passwords that
+                need to be queried at boot-time or during
+                runtime.</para>
+
+                <para><command>systemd-tty-ask-password-agent</command>
+                implements the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">Password
+                Agents Specification</ulink>.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--list</option></term>
+
+                                <listitem><para>Lists all currently pending system password requests.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--query</option></term>
+
+                                <listitem><para>Process all currently
+                                pending system password requests by
+                                querying the user on the calling
+                                TTY.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--watch</option></term>
+
+                                <listitem><para>Continuously process
+                                password requests.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--wall</option></term>
+
+                                <listitem><para>Forward password
+                                requests to
+                                <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                instead of querying the user on the
+                                calling TTY.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--plymouth</option></term>
+
+                                <listitem><para>Ask question with
+                                <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                instead of querying the user on the
+                                calling TTY.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--console</option></term>
+
+                                <listitem><para>Ask question on
+                                <filename>/dev/console</filename>
+                                instead of querying the user on the
+                                calling TTY.  </para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-ask-password-console.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml
new file mode 100644 (file)
index 0000000..92fb38f
--- /dev/null
@@ -0,0 +1,168 @@
+<?xml version='1.0'?>
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="systemd-udevd.service">
+  <refentryinfo>
+    <title>systemd-udevd.service</title>
+    <productname>systemd</productname>
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Kay</firstname>
+        <surname>Sievers</surname>
+        <email>kay@vrfy.org</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-udevd.service</refentrytitle>
+    <manvolnum>8</manvolnum>
+    <refmiscinfo class="version"></refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-udevd.service</refname>
+    <refname>systemd-udevd-control.socket</refname>
+    <refname>systemd-udevd-kernel.socket</refname>
+    <refname>systemd-udevd</refname>
+    <refpurpose>Device event managing daemon</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>systemd-udevd.service</filename></para>
+    <para><filename>systemd-udevd-control.socket</filename></para>
+    <para><filename>systemd-udevd-kernel.socket</filename></para>
+
+    <cmdsynopsis>
+      <command>/usr/lib/systemd/systemd-udevd</command>
+      <arg><option>--daemon</option></arg>
+      <arg><option>--debug</option></arg>
+      <arg><option>--children-max=</option></arg>
+      <arg><option>--exec-delay=</option></arg>
+      <arg><option>--resolve-names=early|late|never</option></arg>
+      <arg><option>--version</option></arg>
+      <arg><option>--help</option></arg>
+    </cmdsynopsis>
+
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+    <para><command>systemd-udevd</command> listens to kernel uevents.
+      For every event, systemd-udevd executes matching instructions
+      specified in udev rules. See <citerefentry>
+      <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum>
+      </citerefentry>.</para>
+    <para>The behavior of the running daemon can be changed with
+    <command>udevadm control</command>.</para>
+  </refsect1>
+
+  <refsect1><title>Options</title>
+    <variablelist>
+      <varlistentry>
+        <term><option>--daemon</option></term>
+        <listitem>
+          <para>Detach and run in the background.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--debug</option></term>
+        <listitem>
+          <para>Print debug messages to stderr.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--children-max=</option></term>
+        <listitem>
+          <para>Limit the number of events executed in parallel.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--exec-delay=</option></term>
+        <listitem>
+
+          <para>Delay the execution of RUN instruction by the given
+          number of seconds. This option might be useful when
+          debugging system crashes during coldplug caused by loading
+          non-working kernel modules.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--resolve-names=</option></term>
+        <listitem>
+          <para>Specify when systemd-udevd should resolve names of users and groups.
+          When set to <option>early</option> (the default) names will be
+          resolved when the rules are parsed.  When set to
+          <option>late</option> names will be resolved for every event.
+          When set to <option>never</option> names will never be resolved
+          and all devices will be owned by root.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--version</option></term>
+        <listitem>
+          <para>Print version number.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--help</option></term>
+        <listitem>
+          <para>Print help text.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1><title>Environment</title>
+    <variablelist>
+      <varlistentry>
+        <term><varname>UDEV_LOG=</varname></term>
+        <listitem>
+          <para>Set the logging priority.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+ </refsect1>
+
+  <refsect1><title>Kernel command line</title>
+    <variablelist>
+      <para>Parameters starting with "rd." will be read when
+      <command>systemd-udevd</command> is used in an initrd.</para>
+      <varlistentry>
+        <term><varname>udev.log-priority=</varname></term>
+        <term><varname>rd.udev.log-priority=</varname></term>
+        <listitem>
+          <para>Set the logging priority.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>udev.children-max=</varname></term>
+        <term><varname>rd.udev.children-max=</varname></term>
+        <listitem>
+          <para>Limit the number of events executed in parallel.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>udev.exec-delay=</varname></term>
+        <term><varname>rd.udev.exec-delay=</varname></term>
+        <listitem>
+          <para>Delay the execution of RUN instruction by the given
+          number of seconds. This option might be useful when
+          debugging system crashes during coldplug caused by loading
+          non-working kernel modules.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+ </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para><citerefentry>
+        <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum>
+    </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/man/systemd-update-utmp-runlevel.service.xml b/man/systemd-update-utmp-runlevel.service.xml
new file mode 100644 (file)
index 0000000..0e19581
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-user-sessions.service">
+
+        <refentryinfo>
+                <title>systemd-update-utmp-runlevel.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-update-utmp-runlevel.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-update-utmp-runlevel.service</refname>
+                <refname>systemd-update-utmp-shutdown.service</refname>
+                <refname>systemd-update-utmp</refname>
+                <refpurpose>Write audit and utmp updates at runlevel
+                changes and shutdown</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-update-utmp-runlevel.service</filename></para>
+                <para><filename>systemd-update-utmp-shutdown.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-update-utmp</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-update-utmp-runlevel.service</filename>
+                is a service that writes SysV runlevel changes to utmp
+                and wtmp, as well as the audit logs, as they
+                occur. <filename>systemd-update-utmp-shutdown.service</filename>
+                does the same for shut-down requests.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>utmp</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>auditd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-user-sessions.service.xml b/man/systemd-user-sessions.service.xml
new file mode 100644 (file)
index 0000000..9214ec9
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-user-sessions.service">
+
+        <refentryinfo>
+                <title>systemd-user-sessions.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-user-sessions.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-user-sessions.service</refname>
+                <refname>systemd-user-sessions</refname>
+                <refpurpose>Permit user logins after boot, prohibit user logins at shutdown</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-user-sessions.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-user-sessions</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-user-sessions.service</filename>
+                is a service that controls user logins. After basic
+                system initialization is complete it removes
+                <filename>/run/nologin</filename>, thus permitting
+                logins. Before system shutdown it creates
+                <filename>/run/nologin</filename>, thus prohibiting
+                further logins. At the same time it also kills all
+                user processes, so that system shutdown may proceed
+                without any remaining user processes around.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pam_nologin</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-vconsole-setup.service.xml b/man/systemd-vconsole-setup.service.xml
new file mode 100644 (file)
index 0000000..c1ef80d
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-vconsole-setup.service">
+
+        <refentryinfo>
+                <title>systemd-vconsole-setup.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-vconsole-setup.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-vconsole-setup.service</refname>
+                <refname>systemd-vconsole-setup</refname>
+                <refpurpose>Configure the virtual console at boot</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-vconsole-setup.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-vconsole-setup</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-vconsole-setup.service</filename>
+                is an early-boot service that configures the virtual
+                console font and console keymap. Internally it calls
+                <citerefentry><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+                <para>See
+                <citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for information about the configuration files understood by this
+                service.</para>
+
+
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Command Line</title>
+
+                <para>A few configuration parameters from
+                <filename>vconsole.conf</filename> may be overridden on
+                the kernel command line:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>vconsole.keymap=</varname></term>
+                                <term><varname>vconsole.keymap.toggle=</varname></term>
+
+                                <listitem><para>Overrides the key
+                                mapping table for the keyboard and the
+                                second toggle keymap.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+
+                                <term><varname>vconsole.font=</varname></term>
+                                <term><varname>vconsole.font.map=</varname></term>
+                                <term><varname>vconsole.font.unimap=</varname></term>
+
+                                <listitem><para>Configures the console
+                                font, the console map, and the unicode
+                                font map.</para></listitem>
+
+
+                        </varlistentry>
+                </variablelist>
+
+                <para>See
+                <citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for information about these settings.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml
new file mode 100644 (file)
index 0000000..fe559e1
--- /dev/null
@@ -0,0 +1,167 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.automount">
+        <refentryinfo>
+                <title>systemd.automount</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.automount</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.automount</refname>
+                <refpurpose>Automount unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.automount</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.automount</filename> encodes information
+                about a file system automount point controlled and
+                supervised by systemd.</para>
+
+                <para>This man page lists the configuration options
+                specific to this unit type. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic [Unit] and [Install] sections. The
+                automount specific configuration options are configured
+                in the [Automount] section.</para>
+
+                <para>Automount units must be named after the
+                automount directories they control. Example: the
+                automount point <filename>/home/lennart</filename>
+                must be configured in a unit file
+                <filename>home-lennart.automount</filename>. For
+                details about the escaping logic used to convert a
+                file system path to a unit name see
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+                <para>For each automount unit file a matching mount
+                unit file (see
+                <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details) must exist which is activated when the
+                automount path is accessed. Example: if an automount
+                unit <filename>home-lennart.automount</filename> is
+                active and the user accesses
+                <filename>/home/lennart</filename> the mount unit
+                <filename>home-lennart.mount</filename> will be
+                activated.</para>
+
+                <para>Automount units may be used to implement
+                on-demand mounting as well as parallelized mounting of
+                file systems.</para>
+
+                <para>If an automount point is beneath another mount
+                point in the file system hierarchy a dependency
+                between both units is created automatically.</para>
+        </refsect1>
+
+        <refsect1>
+                <title><filename>fstab</filename></title>
+
+                <para>Automount units may either be configured via unit
+                files, or via <filename>/etc/fstab</filename> (see
+                <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details).</para>
+
+                <para>For details how systemd parses
+                <filename>/etc/fstab</filename> see
+                <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+                <para>If an automount point is configured in both
+                <filename>/etc/fstab</filename> and a unit file the
+                configuration in the latter takes precedence.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>Automount files must include an [Automount]
+                section, which carries information about the file
+                system automount points it supervises. The options
+                specific to the [Automount] section of automount units
+                are the following:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>Where=</varname></term>
+                                <listitem><para>Takes an absolute path
+                                of a directory of the automount
+                                point. If the automount point is not
+                                existing at time that the automount
+                                point is installed it is created. This
+                                string must be reflected in the unit
+                                file name. (See above.) This option is
+                                mandatory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>DirectoryMode=</varname></term>
+                                <listitem><para>Directories of
+                                automount points (and any parent
+                                directories) are automatically created
+                                if needed. This option specifies the
+                                file system access mode used when
+                                creating these directories. Takes an
+                                access mode in octal
+                                notation. Defaults to
+                                0755.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>automount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.conf.xml b/man/systemd.conf.xml
new file mode 100644 (file)
index 0000000..a6be932
--- /dev/null
@@ -0,0 +1,284 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.conf">
+        <refentryinfo>
+                <title>systemd.conf</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.conf</refname>
+                <refpurpose>System and service manager configuration file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/systemd/system.conf</filename></para>
+                <para><filename>/etc/systemd/user.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>When run as system instance systemd reads the
+                configuration file <filename>system.conf</filename>,
+                otherwise <filename>user.conf</filename>. These
+                configuration files contain a few settings controlling
+                basic manager operations.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>All options are configured in the
+                <literal>[Manager]</literal> section:</para>
+
+                <variablelist class='systemd-directives'>
+
+                        <varlistentry>
+                                <term><varname>LogLevel=</varname></term>
+                                <term><varname>LogTarget=</varname></term>
+                                <term><varname>LogColor=</varname></term>
+                                <term><varname>LogLocation=</varname></term>
+                                <term><varname>DumpCore=yes</varname></term>
+                                <term><varname>CrashShell=no</varname></term>
+                                <term><varname>ShowStatus=yes</varname></term>
+                                <term><varname>CrashChVT=1</varname></term>
+                                <term><varname>DefaultStandardOutput=journal</varname></term>
+                                <term><varname>DefaultStandardError=inherit</varname></term>
+
+                                <listitem><para>Configures various
+                                parameters of basic manager
+                                operation. These options may be
+                                overridden by the respective command
+                                line arguments. See
+                                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                for details about these command line
+                                arguments.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CPUAffinity=</varname></term>
+
+                                <listitem><para>Configures the initial
+                                CPU affinity for the init
+                                process. Takes a space-separated list
+                                of CPU indexes.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>DefaultControllers=cpu</varname></term>
+
+                                <listitem><para>Configures in which
+                                cgroup controller hierarchies to
+                                create per-service cgroups
+                                automatically, in addition to the
+                                name=systemd named hierarchy. Defaults
+                                to 'cpu'. Takes a space separated list
+                                of controller names. Pass an empty
+                                string to ensure that systemd does not
+                                touch any hierarchies but its
+                                own.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>JoinControllers=cpu,cpuacct,cpuset net_cls,netprio</varname></term>
+
+                                <listitem><para>Configures controllers
+                                that shall be mounted in a single
+                                hierarchy. By default systemd will
+                                mount all controllers which are
+                                enabled in the kernel in individual
+                                hierarchies, with the exception of
+                                those listed in this setting. Takes a
+                                space separated list of comma
+                                separated controller names, in order
+                                to allow multiple joined
+                                hierarchies. Defaults to
+                                'cpu,cpuacct'. Pass an empty string to
+                                ensure that systemd mounts all
+                                controllers in separate
+                                hierarchies.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RuntimeWatchdogSec=</varname></term>
+                                <term><varname>ShutdownWatchdogSec=</varname></term>
+
+                                <listitem><para>Configure the hardware
+                                watchdog at runtime and at
+                                reboot. Takes a timeout value in
+                                seconds (or in other time units if
+                                suffixed with <literal>ms</literal>,
+                                <literal>min</literal>,
+                                <literal>h</literal>,
+                                <literal>d</literal>,
+                                <literal>w</literal>). If
+                                <varname>RuntimeWatchdogSec=</varname>
+                                is set to a non-zero value the
+                                watchdog hardware
+                                (<filename>/dev/watchdog</filename>)
+                                will be programmed to automatically
+                                reboot the system if it is not
+                                contacted within the specified timeout
+                                interval. The system manager will
+                                ensure to contact it at least once in
+                                half the specified timeout
+                                interval. This feature requires a
+                                hardware watchdog device to be
+                                present, as it is commonly the case in
+                                embedded and server systems. Not all
+                                hardware watchdogs allow configuration
+                                of the reboot timeout, in which case
+                                the closest available timeout is
+                                picked. <varname>ShutdownWatchdogSec=</varname>
+                                may be used to configure the hardware
+                                watchdog when the system is asked to
+                                reboot. It works as a safety net to
+                                ensure that the reboot takes place
+                                even if a clean reboot attempt times
+                                out. By default
+                                <varname>RuntimeWatchdogSec=</varname>
+                                defaults to 0 (off), and
+                                <varname>ShutdownWatchdogSec=</varname>
+                                to 10min. These settings have no
+                                effect if a hardware watchdog is not
+                                available.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CapabilityBoundingSet=</varname></term>
+
+                                <listitem><para>Controls which
+                                capabilities to include in the
+                                capability bounding set for PID 1 and
+                                its children. See
+                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details. Takes a whitespace
+                                separated list of capability names as
+                                read by
+                                <citerefentry><refentrytitle>cap_from_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                                Capabilities listed will be included
+                                in the bounding set, all others are
+                                removed. If the list of capabilities
+                                is prefixed with ~ all but the listed
+                                capabilities will be included, the
+                                effect of the assignment
+                                inverted. Note that this option also
+                                affects the respective capabilities in
+                                the effective, permitted and
+                                inheritable capability sets. The
+                                capability bounding set may also be
+                                individually configured for units
+                                using the
+                                <varname>CapabilityBoundingSet=</varname>
+                                directive for units, but note that
+                                capabilities dropped for PID 1 cannot
+                                be regained in individual units, they
+                                are lost for good.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimerSlackNSec=</varname></term>
+
+                                <listitem><para>Sets the timer slack
+                                in nanoseconds for PID 1 which is then
+                                inherited to all executed processes,
+                                unless overridden individually, for
+                                example with the
+                                <varname>TimerSlackNSec=</varname>
+                                setting in service units (for details
+                                see
+                                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>). The
+                                timer slack controls the accuracy of
+                                wake-ups triggered by timers. See
+                                <citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for more information. Note that in
+                                contrast to most other time span
+                                definitions this parameter takes an
+                                integer value in nano-seconds if no
+                                unit is specified. The usual time
+                                units are understood
+                                too.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>DefaultLimitCPU=</varname></term>
+                                <term><varname>DefaultLimitFSIZE=</varname></term>
+                                <term><varname>DefaultLimitDATA=</varname></term>
+                                <term><varname>DefaultLimitSTACK=</varname></term>
+                                <term><varname>DefaultLimitCORE=</varname></term>
+                                <term><varname>DefaultLimitRSS=</varname></term>
+                                <term><varname>DefaultLimitNOFILE=</varname></term>
+                                <term><varname>DefaultLimitAS=</varname></term>
+                                <term><varname>DefaultLimitNPROC=</varname></term>
+                                <term><varname>DefaultLimitMEMLOCK=</varname></term>
+                                <term><varname>DefaultLimitLOCKS=</varname></term>
+                                <term><varname>DefaultLimitSIGPENDING=</varname></term>
+                                <term><varname>DefaultLimitMSGQUEUE=</varname></term>
+                                <term><varname>DefaultLimitNICE=</varname></term>
+                                <term><varname>DefaultLimitRTPRIO=</varname></term>
+                                <term><varname>DefaultLimitRTTIME=</varname></term>
+
+                                <listitem><para>These settings control
+                                various default resource limits for
+                                units. See
+                                <citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details. Use the string
+                                <varname>infinity</varname> to
+                                configure no limit on a specific
+                                resource. These settings may be
+                                overridden in individual units
+                                using the corresponding LimitXXX=
+                                directives. Note that these resource
+                                limits are only defaults for units,
+                                they are not applied to PID 1
+                                itself.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.device.xml b/man/systemd.device.xml
new file mode 100644 (file)
index 0000000..141d72e
--- /dev/null
@@ -0,0 +1,168 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.device">
+        <refentryinfo>
+                <title>systemd.device</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.device</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.device</refname>
+                <refpurpose>Device unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.device</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.device</filename> encodes information about
+                a device unit as exposed in the
+                sysfs/<citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                device tree.</para>
+
+                <para>This unit type has no specific options. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic <literal>[Unit]</literal> and
+                <literal>[Install]</literal> sections. A separate
+                <literal>[Device]</literal> section does not exist,
+                since no device-specific options may be
+                configured.</para>
+
+                <para>systemd will automatically create dynamic device
+                units for all kernel devices that are marked with the
+                "systemd" udev tag (by default all block and network
+                devices, and a few others). This may be used to define
+                dependencies between devices and other
+                units.</para>
+
+                <para>Device units are named after the
+                <filename>/sys</filename> and
+                <filename>/dev</filename> paths they control. Example:
+                the device <filename>/dev/sda5</filename> is exposed
+                in systemd as <filename>dev-sda5.device</filename>. For
+                details about the escaping logic used to convert a
+                file system path to a unit name see
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>The udev Database</title>
+
+                <para>The settings of device units may either be
+                configured via unit files, or directly from the udev
+                database (which is recommended). The following udev
+                properties are understood by systemd:</para>
+
+                <variablelist class='udev-directives'>
+                        <varlistentry>
+                                <term><varname>SYSTEMD_WANTS=</varname></term>
+                                <listitem><para>Adds dependencies of
+                                type <varname>Wants</varname> from
+                                this unit to all listed units. This
+                                may be used to activate arbitrary
+                                units, when a specific device becomes
+                                available. Note that this and the
+                                other tags are not taken into account
+                                unless the device is tagged with the
+                                "<literal>systemd</literal>" string in
+                                the udev database, because otherwise
+                                the device is not exposed as systemd
+                                unit.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SYSTEMD_ALIAS=</varname></term>
+                                <listitem><para>Adds an additional
+                                alias name to the device unit. This
+                                must be an absolute path that is
+                                automatically transformed into a unit
+                                name. (See above.)</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SYSTEMD_READY=</varname></term>
+                                <listitem><para>If set to 0 systemd
+                                will consider this device unplugged
+                                even if it shows up in the udev
+                                tree. If this property is unset or set
+                                to 1 the device will be considered
+                                plugged the moment it shows up in the
+                                udev tree. This property has no
+                                influence on the behavior when a
+                                device disappears from the udev
+                                tree. This option is useful to support
+                                devices that initially show up in an
+                                uninitialized state in the tree, and for
+                                which a changed event is generated the
+                                moment they are fully set
+                                up.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ID_MODEL_FROM_DATABASE=</varname></term>
+                                <term><varname>ID_MODEL=</varname></term>
+
+                                <listitem><para>If set, this property is
+                                used as description string for the
+                                device unit.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
new file mode 100644 (file)
index 0000000..302ac43
--- /dev/null
@@ -0,0 +1,1156 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.exec">
+        <refentryinfo>
+                <title>systemd.exec</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.exec</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.exec</refname>
+                <refpurpose>Execution environment configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.service</filename>,
+                <filename>systemd.socket</filename>,
+                <filename>systemd.mount</filename>,
+                <filename>systemd.swap</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>Unit configuration files for services, sockets,
+                mount points and swap devices share a subset of
+                configuration options which define the execution
+                environment of spawned processes.</para>
+
+                <para>This man page lists the configuration options
+                shared by these four unit types. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files, and
+                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more information on the specific unit
+                configuration files. The execution specific
+                configuration options are configured in the [Service],
+                [Socket], [Mount], or [Swap] sections, depending on the unit
+                type.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>WorkingDirectory=</varname></term>
+
+                                <listitem><para>Takes an absolute
+                                directory path. Sets the working
+                                directory for executed processes. If
+                                not set defaults to the root directory
+                                when systemd is running as a system
+                                instance and the respective user's
+                                home directory if run as
+                                user.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RootDirectory=</varname></term>
+
+                                <listitem><para>Takes an absolute
+                                directory path. Sets the root
+                                directory for executed processes, with
+                                the
+                                <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                system call. If this is used it must
+                                be ensured that the process and all
+                                its auxiliary files are available in
+                                the <function>chroot()</function>
+                                jail.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>User=</varname></term>
+                                <term><varname>Group=</varname></term>
+
+                                <listitem><para>Sets the Unix user
+                                or group that the processes are executed
+                                as, respectively. Takes a single user or group
+                                name or ID as argument. If no group is
+                                set, the default group of the user is
+                                chosen.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SupplementaryGroups=</varname></term>
+
+                                <listitem><para>Sets the supplementary
+                                Unix groups the processes are executed
+                                as. This takes a space separated list
+                                of group names or IDs. This option may
+                                be specified more than once in which
+                                case all listed groups are set as
+                                supplementary groups. This option does
+                                not override but extends the list of
+                                supplementary groups configured in the
+                                system group database for the
+                                user.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Nice=</varname></term>
+
+                                <listitem><para>Sets the default nice
+                                level (scheduling priority) for
+                                executed processes. Takes an integer
+                                between -20 (highest priority) and 19
+                                (lowest priority). See
+                                <citerefentry><refentrytitle>setpriority</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>OOMScoreAdjust=</varname></term>
+
+                                <listitem><para>Sets the adjustment
+                                level for the Out-Of-Memory killer for
+                                executed processes. Takes an integer
+                                between -1000 (to disable OOM killing
+                                for this process) and 1000 (to make
+                                killing of this process under memory
+                                pressure very likely). See <ulink
+                                url="http://www.kernel.org/doc/Documentation/filesystems/proc.txt">proc.txt</ulink>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>IOSchedulingClass=</varname></term>
+
+                                <listitem><para>Sets the IO scheduling
+                                class for executed processes. Takes an
+                                integer between 0 and 3 or one of the
+                                strings <option>none</option>,
+                                <option>realtime</option>,
+                                <option>best-effort</option> or
+                                <option>idle</option>. See
+                                <citerefentry><refentrytitle>ioprio_set</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>IOSchedulingPriority=</varname></term>
+
+                                <listitem><para>Sets the IO scheduling
+                                priority for executed processes. Takes
+                                an integer between 0 (highest
+                                priority) and 7 (lowest priority). The
+                                available priorities depend on the
+                                selected IO scheduling class (see
+                                above). See
+                                <citerefentry><refentrytitle>ioprio_set</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CPUSchedulingPolicy=</varname></term>
+
+                                <listitem><para>Sets the CPU
+                                scheduling policy for executed
+                                processes. Takes one of
+                                <option>other</option>,
+                                <option>batch</option>,
+                                <option>idle</option>,
+                                <option>fifo</option> or
+                                <option>rr</option>. See
+                                <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CPUSchedulingPriority=</varname></term>
+
+                                <listitem><para>Sets the CPU
+                                scheduling priority for executed
+                                processes. The available priority
+                                range depends on the selected CPU
+                                scheduling policy (see above). For
+                                real-time scheduling policies an
+                                integer between 1 (lowest priority)
+                                and 99 (highest priority) can be used.
+                                See <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CPUSchedulingResetOnFork=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true elevated CPU
+                                scheduling priorities and policies
+                                will be reset when the executed
+                                processes fork, and can hence not leak
+                                into child processes. See
+                                <citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details. Defaults to false.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CPUAffinity=</varname></term>
+
+                                <listitem><para>Controls the CPU
+                                affinity of the executed
+                                processes. Takes a space-separated
+                                list of CPU indexes. See
+                                <citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>UMask=</varname></term>
+
+                                <listitem><para>Controls the file mode
+                                creation mask. Takes an access mode in
+                                octal notation. See
+                                <citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details. Defaults to
+                                0022.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Environment=</varname></term>
+
+                                <listitem><para>Sets environment
+                                variables for executed
+                                processes. Takes a space-separated
+                                list of variable assignments. This
+                                option may be specified more than once
+                                in which case all listed variables
+                                will be set. If the same variable is
+                                set twice the later setting will
+                                override the earlier setting. See
+                                <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>EnvironmentFile=</varname></term>
+                                <listitem><para>Similar to
+                                <varname>Environment=</varname> but
+                                reads the environment variables from a
+                                text file. The text file should
+                                contain new-line separated variable
+                                assignments. Empty lines and lines
+                                starting with ; or # will be ignored,
+                                which may be used for commenting. The
+                                parser strips leading and
+                                trailing whitespace from the values
+                                of assignments, unless you use
+                                double quotes (").
+                                The
+                                argument passed should be an absolute
+                                file name or wildcard expression, optionally prefixed with
+                                "-", which indicates that if the file
+                                does not exist it won't be read and no
+                                error or warning message is
+                                logged. The files listed with this
+                                directive will be read shortly before
+                                the process is executed. Settings from
+                                these files override settings made
+                                with
+                                <varname>Environment=</varname>. If
+                                the same variable is set twice from
+                                these files the files will be read in
+                                the order they are specified and the
+                                later setting will override the
+                                earlier setting. </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>StandardInput=</varname></term>
+                                <listitem><para>Controls where file
+                                descriptor 0 (STDIN) of the executed
+                                processes is connected to. Takes one
+                                of <option>null</option>,
+                                <option>tty</option>,
+                                <option>tty-force</option>,
+                                <option>tty-fail</option> or
+                                <option>socket</option>. If
+                                <option>null</option> is selected
+                                standard input will be connected to
+                                <filename>/dev/null</filename>,
+                                i.e. all read attempts by the process
+                                will result in immediate EOF. If
+                                <option>tty</option> is selected
+                                standard input is connected to a TTY
+                                (as configured by
+                                <varname>TTYPath=</varname>, see
+                                below) and the executed process
+                                becomes the controlling process of the
+                                terminal. If the terminal is already
+                                being controlled by another process the
+                                executed process waits until the current
+                                controlling process releases the
+                                terminal.
+                                <option>tty-force</option>
+                                is similar to <option>tty</option>,
+                                but the executed process is forcefully
+                                and immediately made the controlling
+                                process of the terminal, potentially
+                                removing previous controlling
+                                processes from the
+                                terminal. <option>tty-fail</option> is
+                                similar to <option>tty</option> but if
+                                the terminal already has a controlling
+                                process start-up of the executed
+                                process fails.  The
+                                <option>socket</option> option is only
+                                valid in socket-activated services,
+                                and only when the socket configuration
+                                file (see
+                                <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details) specifies a single socket
+                                only. If this option is set standard
+                                input will be connected to the socket
+                                the service was activated from, which
+                                is primarily useful for compatibility
+                                with daemons designed for use with the
+                                traditional
+                                <citerefentry><refentrytitle>inetd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                daemon. This setting defaults to
+                                <option>null</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>StandardOutput=</varname></term>
+                                <listitem><para>Controls where file
+                                descriptor 1 (STDOUT) of the executed
+                                processes is connected to. Takes one
+                                of <option>inherit</option>,
+                                <option>null</option>,
+                                <option>tty</option>,
+                                <option>syslog</option>,
+                                <option>kmsg</option>,
+                                <option>journal</option>,
+                                <option>syslog+console</option>,
+                                <option>kmsg+console</option>,
+                                <option>journal+console</option> or
+                                <option>socket</option>. If set to
+                                <option>inherit</option> the file
+                                descriptor of standard input is
+                                duplicated for standard output. If set
+                                to <option>null</option> standard
+                                output will be connected to
+                                <filename>/dev/null</filename>,
+                                i.e. everything written to it will be
+                                lost. If set to <option>tty</option>
+                                standard output will be connected to a
+                                tty (as configured via
+                                <varname>TTYPath=</varname>, see
+                                below). If the TTY is used for output
+                                only the executed process will not
+                                become the controlling process of the
+                                terminal, and will not fail or wait
+                                for other processes to release the
+                                terminal. <option>syslog</option>
+                                connects standard output to the
+                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                system syslog
+                                service. <option>kmsg</option>
+                                connects it with the kernel log buffer
+                                which is accessible via
+                                <citerefentry><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>. <option>journal</option>
+                                connects it with the journal which is
+                                accessible via
+                                <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                (Note that everything that is written
+                                to syslog or kmsg is implicitly stored
+                                in the journal as well, those options
+                                are hence supersets of this
+                                one). <option>syslog+console</option>,
+                                <option>journal+console</option> and
+                                <option>kmsg+console</option> work
+                                similarly but copy the output to the
+                                system console as
+                                well. <option>socket</option> connects
+                                standard output to a socket from
+                                socket activation, semantics are
+                                similar to the respective option of
+                                <varname>StandardInput=</varname>.
+                                This setting defaults to the value set
+                                with
+                                <option>DefaultStandardOutput=</option>
+                                in
+                                <citerefentry><refentrytitle>systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                                which defaults to
+                                <option>journal</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>StandardError=</varname></term>
+                                <listitem><para>Controls where file
+                                descriptor 2 (STDERR) of the executed
+                                processes is connected to. The
+                                available options are identical to
+                                those of
+                                <varname>StandardOutput=</varname>,
+                                with one exception: if set to
+                                <option>inherit</option> the file
+                                descriptor used for standard output is
+                                duplicated for standard error. This
+                                setting defaults to the value set with
+                                <option>DefaultStandardError=</option>
+                                in
+                                <citerefentry><refentrytitle>systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                                which defaults to
+                                <option>inherit</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>TTYPath=</varname></term>
+                                <listitem><para>Sets the terminal
+                                device node to use if standard input,
+                                output or stderr are connected to a
+                                TTY (see above). Defaults to
+                                <filename>/dev/console</filename>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>TTYReset=</varname></term>
+                                <listitem><para>Reset the terminal
+                                device specified with
+                                <varname>TTYPath=</varname> before and
+                                after execution. Defaults to
+                                <literal>no</literal>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>TTYVHangup=</varname></term>
+                                <listitem><para>Disconnect all clients
+                                which have opened the terminal device
+                                specified with
+                                <varname>TTYPath=</varname>
+                                before and after execution. Defaults
+                                to
+                                <literal>no</literal>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>TTYVTDisallocate=</varname></term>
+                                <listitem><para>If the terminal
+                                device specified with
+                                <varname>TTYPath=</varname> is a
+                                virtual console terminal try to
+                                deallocate the TTY before and after
+                                execution. This ensures that the
+                                screen and scrollback buffer is
+                                cleared. Defaults to
+                                <literal>no</literal>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>SyslogIdentifier=</varname></term>
+                                <listitem><para>Sets the process name
+                                to prefix log lines sent to syslog or
+                                the kernel log buffer with. If not set
+                                defaults to the process name of the
+                                executed process. This option is only
+                                useful when
+                                <varname>StandardOutput=</varname> or
+                                <varname>StandardError=</varname> are
+                                set to <option>syslog</option> or
+                                <option>kmsg</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>SyslogFacility=</varname></term>
+                                <listitem><para>Sets the syslog
+                                facility to use when logging to
+                                syslog. One of <option>kern</option>,
+                                <option>user</option>,
+                                <option>mail</option>,
+                                <option>daemon</option>,
+                                <option>auth</option>,
+                                <option>syslog</option>,
+                                <option>lpr</option>,
+                                <option>news</option>,
+                                <option>uucp</option>,
+                                <option>cron</option>,
+                                <option>authpriv</option>,
+                                <option>ftp</option>,
+                                <option>local0</option>,
+                                <option>local1</option>,
+                                <option>local2</option>,
+                                <option>local3</option>,
+                                <option>local4</option>,
+                                <option>local5</option>,
+                                <option>local6</option> or
+                                <option>local7</option>. See
+                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                for details. This option is only
+                                useful when
+                                <varname>StandardOutput=</varname> or
+                                <varname>StandardError=</varname> are
+                                set to <option>syslog</option>.
+                                Defaults to
+                                <option>daemon</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>SyslogLevel=</varname></term>
+                                <listitem><para>Default syslog level
+                                to use when logging to syslog or the
+                                kernel log buffer. One of
+                                <option>emerg</option>,
+                                <option>alert</option>,
+                                <option>crit</option>,
+                                <option>err</option>,
+                                <option>warning</option>,
+                                <option>notice</option>,
+                                <option>info</option>,
+                                <option>debug</option>. See
+                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                for details. This option is only
+                                useful when
+                                <varname>StandardOutput=</varname> or
+                                <varname>StandardError=</varname> are
+                                set to <option>syslog</option> or
+                                <option>kmsg</option>. Note that
+                                individual lines output by the daemon
+                                might be prefixed with a different log
+                                level which can be used to override
+                                the default log level specified
+                                here. The interpretation of these
+                                prefixes may be disabled with
+                                <varname>SyslogLevelPrefix=</varname>,
+                                see below. For details see
+                                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+
+                                Defaults to
+                                <option>info</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SyslogLevelPrefix=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If true and
+                                <varname>StandardOutput=</varname> or
+                                <varname>StandardError=</varname> are
+                                set to <option>syslog</option>,
+                                <option>kmsg</option> or
+                                <option>journal</option>, log lines
+                                written by the executed process that
+                                are prefixed with a log level will be
+                                passed on to syslog with this log
+                                level set but the prefix removed. If
+                                set to false, the interpretation of
+                                these prefixes is disabled and the
+                                logged lines are passed on as-is. For
+                                details about this prefixing see
+                                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                                Defaults to true.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimerSlackNSec=</varname></term>
+                                <listitem><para>Sets the timer slack
+                                in nanoseconds for the executed
+                                processes. The timer slack controls
+                                the accuracy of wake-ups triggered by
+                                timers. See
+                                <citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for more information. Note that in
+                                contrast to most other time span
+                                definitions this parameter takes an
+                                integer value in nano-seconds if no
+                                unit is specified. The usual time
+                                units are understood
+                                too.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>LimitCPU=</varname></term>
+                                <term><varname>LimitFSIZE=</varname></term>
+                                <term><varname>LimitDATA=</varname></term>
+                                <term><varname>LimitSTACK=</varname></term>
+                                <term><varname>LimitCORE=</varname></term>
+                                <term><varname>LimitRSS=</varname></term>
+                                <term><varname>LimitNOFILE=</varname></term>
+                                <term><varname>LimitAS=</varname></term>
+                                <term><varname>LimitNPROC=</varname></term>
+                                <term><varname>LimitMEMLOCK=</varname></term>
+                                <term><varname>LimitLOCKS=</varname></term>
+                                <term><varname>LimitSIGPENDING=</varname></term>
+                                <term><varname>LimitMSGQUEUE=</varname></term>
+                                <term><varname>LimitNICE=</varname></term>
+                                <term><varname>LimitRTPRIO=</varname></term>
+                                <term><varname>LimitRTTIME=</varname></term>
+                                <listitem><para>These settings control
+                                various resource limits for executed
+                                processes. See
+                                <citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details. Use the string
+                                <varname>infinity</varname> to
+                                configure no limit on a specific
+                                resource.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PAMName=</varname></term>
+                                <listitem><para>Sets the PAM service
+                                name to set up a session as. If set
+                                the executed process will be
+                                registered as a PAM session under the
+                                specified service name. This is only
+                                useful in conjunction with the
+                                <varname>User=</varname> setting. If
+                                not set no PAM session will be opened
+                                for the executed processes. See
+                                <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TCPWrapName=</varname></term>
+                                <listitem><para>If this is a
+                                socket-activated service this sets the
+                                tcpwrap service name to check the
+                                permission for the current connection
+                                with. This is only useful in
+                                conjunction with socket-activated
+                                services, and stream sockets (TCP) in
+                                particular. It has no effect on other
+                                socket types (e.g. datagram/UDP) and
+                                on processes unrelated to socket-based
+                                activation. If the tcpwrap
+                                verification fails daemon start-up
+                                will fail and the connection is
+                                terminated. See
+                                <citerefentry><refentrytitle>tcpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for details. Note that this option may
+                                be used to do access control checks
+                                only. Shell commands and commands
+                                described in
+                                <citerefentry><refentrytitle>hosts_options</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                are not supported.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CapabilityBoundingSet=</varname></term>
+
+                                <listitem><para>Controls which
+                                capabilities to include in the
+                                capability bounding set for the
+                                executed process. See
+                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details. Takes a whitespace
+                                separated list of capability names as
+                                read by
+                                <citerefentry><refentrytitle>cap_from_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                                Capabilities listed will be included
+                                in the bounding set, all others are
+                                removed. If the list of capabilities
+                                is prefixed with ~ all but the listed
+                                capabilities will be included, the
+                                effect of the assignment
+                                inverted. Note that this option also
+                                effects the respective capabilities in
+                                the effective, permitted and
+                                inheritable capability sets, on top of
+                                what <varname>Capabilities=</varname>
+                                does. If this option is not used the
+                                capability bounding set is not
+                                modified on process execution, hence
+                                no limits on the capabilities of the
+                                process are
+                                enforced.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SecureBits=</varname></term>
+                                <listitem><para>Controls the secure
+                                bits set for the executed process. See
+                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details. Takes a list of strings:
+                                <option>keep-caps</option>,
+                                <option>keep-caps-locked</option>,
+                                <option>no-setuid-fixup</option>,
+                                <option>no-setuid-fixup-locked</option>,
+                                <option>noroot</option> and/or
+                                <option>noroot-locked</option>.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Capabilities=</varname></term>
+                                <listitem><para>Controls the
+                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                set for the executed process. Take a
+                                capability string describing the
+                                effective, permitted and inherited
+                                capability sets as documented in
+                                <citerefentry><refentrytitle>cap_from_text</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                                Note that these capability sets are
+                                usually influenced by the capabilities
+                                attached to the executed file. Due to
+                                that
+                                <varname>CapabilityBoundingSet=</varname>
+                                is probably the much more useful
+                                setting.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ControlGroup=</varname></term>
+
+                                <listitem><para>Controls the control
+                                groups the executed processes shall be
+                                made members of. Takes a
+                                space-separated list of cgroup
+                                identifiers. A cgroup identifier has a
+                                format like
+                                <filename>cpu:/foo/bar</filename>,
+                                where "cpu" identifies the kernel
+                                control group controller used, and
+                                <filename>/foo/bar</filename> is the
+                                control group path. The controller
+                                name and ":" may be omitted in which
+                                case the named systemd control group
+                                hierarchy is implied. Alternatively,
+                                the path and ":" may be omitted, in
+                                which case the default control group
+                                path for this unit is implied. This
+                                option may be used to place executed
+                                processes in arbitrary groups in
+                                arbitrary hierarchies -- which can be
+                                configured externally with additional
+                                execution limits. By default systemd
+                                will place all executed processes in
+                                separate per-unit control groups
+                                (named after the unit) in the systemd
+                                named hierarchy. Since every process
+                                can be in one group per hierarchy only
+                                overriding the control group path in
+                                the named systemd hierarchy will
+                                disable automatic placement in the
+                                default group. This option is
+                                primarily intended to place executed
+                                processes in specific paths in
+                                specific kernel controller
+                                hierarchies. It is however not
+                                recommended to manipulate the service
+                                control group path in the systemd
+                                named hierarchy. For details about
+                                control groups see <ulink
+                                url="http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ControlGroupModify=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If true, the control groups
+                                created for this unit will be owned by
+                                the user specified with
+                                <varname>User=</varname> (and the
+                                appropriate group), and he/she can create
+                                subgroups as well as add processes to
+                                the group.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ControlGroupPersistent=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If true, the control groups
+                                created for this unit will be marked
+                                to be persistent, i.e. systemd will
+                                not remove them when stopping the
+                                unit. The default is false, meaning
+                                that the control groups will be
+                                removed when the unit is stopped. For
+                                details about the semantics of this
+                                logic see <ulink
+                                url="http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups">PaxControlGroups</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ControlGroupAttribute=</varname></term>
+
+                                <listitem><para>Set a specific control
+                                group attribute for executed
+                                processes, and (if needed) add the
+                                executed processes to a cgroup in the
+                                hierarchy of the controller the
+                                attribute belongs to. Takes two
+                                space-separated arguments: the
+                                attribute name (syntax is
+                                <literal>cpu.shares</literal> where
+                                <literal>cpu</literal> refers to a
+                                specific controller and
+                                <literal>shares</literal> to the
+                                attribute name), and the attribute
+                                value. Example:
+                                <literal>ControlGroupAttribute=cpu.shares
+                                512</literal>. If this option is used
+                                for an attribute that belongs to a
+                                kernel controller hierarchy the unit
+                                is not already configured to be added
+                                to (for example via the
+                                <literal>ControlGroup=</literal>
+                                option) then the unit will be added to
+                                the controller and the default unit
+                                cgroup path is implied. Thus, using
+                                <varname>ControlGroupAttribute=</varname>
+                                is in most case sufficient to make use
+                                of control group enforcements,
+                                explicit
+                                <varname>ControlGroup=</varname> are
+                                only necessary in case the implied
+                                default control group path for a
+                                service is not desirable. For details
+                                about control group attributes see
+                                <ulink
+                                url="http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt</ulink>. This
+                                option may appear more than once, in
+                                order to set multiple control group
+                                attributes.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CPUShares=</varname></term>
+
+                                <listitem><para>Assign the specified
+                                overall CPU time shares to the
+                                processes executed. Takes an integer
+                                value. This controls the
+                                <literal>cpu.shares</literal> control
+                                group attribute, which defaults to
+                                1024. For details about this control
+                                group attribute see <ulink
+                                url="http://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt">sched-design-CFS.txt</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>MemoryLimit=</varname></term>
+                                <term><varname>MemorySoftLimit=</varname></term>
+
+                                <listitem><para>Limit the overall memory usage
+                                of the executed processes to a certain
+                                size. Takes a memory size in bytes. If
+                                the value is suffixed with K, M, G or
+                                T the specified memory size is parsed
+                                as Kilobytes, Megabytes, Gigabytes,
+                                or Terabytes (to the base
+                                1024), respectively. This controls the
+                                <literal>memory.limit_in_bytes</literal>
+                                and
+                                <literal>memory.soft_limit_in_bytes</literal>
+                                control group attributes. For details
+                                about these control group attributes
+                                see <ulink
+                                url="http://www.kernel.org/doc/Documentation/cgroups/memory.txt">memory.txt</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>DeviceAllow=</varname></term>
+                                <term><varname>DeviceDeny=</varname></term>
+
+                                <listitem><para>Control access to
+                                specific device nodes by the executed processes. Takes two
+                                space separated strings: a device node
+                                path (such as
+                                <filename>/dev/null</filename>)
+                                followed by a combination of r, w, m
+                                to control reading, writing, or
+                                creating of the specific device node
+                                by the unit, respectively. This controls the
+                                <literal>devices.allow</literal>
+                                and
+                                <literal>devices.deny</literal>
+                                control group attributes. For details
+                                about these control group attributes
+                                see <ulink
+                                url="http://www.kernel.org/doc/Documentation/cgroups/devices.txt">devices.txt</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>BlockIOWeight=</varname></term>
+
+                                <listitem><para>Set the default or
+                                per-device overall block IO weight
+                                value for the executed
+                                processes. Takes either a single
+                                weight value (between 10 and 1000) to
+                                set the default block IO weight, or a
+                                space separated pair of a file path
+                                and a weight value to specify the
+                                device specific weight value (Example:
+                                "/dev/sda 500"). The file path may be
+                                specified as path to a block device
+                                node or as any other file in which
+                                case the backing block device of the
+                                file system of the file is
+                                determined. This controls the
+                                <literal>blkio.weight</literal> and
+                                <literal>blkio.weight_device</literal>
+                                control group attributes, which
+                                default to 1000. Use this option
+                                multiple times to set weights for
+                                multiple devices. For details about
+                                these control group attributes see
+                                <ulink
+                                url="http://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>BlockIOReadBandwidth=</varname></term>
+                                <term><varname>BlockIOWriteBandwidth=</varname></term>
+
+                                <listitem><para>Set the per-device
+                                overall block IO bandwidth limit for
+                                the executed processes. Takes a space
+                                separated pair of a file path and a
+                                bandwidth value (in bytes per second)
+                                to specify the device specific
+                                bandwidth. The file path may be
+                                specified as path to a block device
+                                node or as any other file in which
+                                case the backing block device of the
+                                file system of the file is determined.
+                                If the bandwidth is suffixed with K, M,
+                                G, or T the specified bandwidth is
+                                parsed as Kilobytes, Megabytes,
+                                Gigabytes, or Terabytes, respectively (Example:
+                                "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0
+                                5M"). This controls the
+                                <literal>blkio.read_bps_device</literal>
+                                and
+                                <literal>blkio.write_bps_device</literal>
+                                control group attributes. Use this
+                                option multiple times to set bandwidth
+                                limits for multiple devices. For
+                                details about these control group
+                                attributes see <ulink
+                                url="http://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt</ulink>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ReadWriteDirectories=</varname></term>
+                                <term><varname>ReadOnlyDirectories=</varname></term>
+                                <term><varname>InaccessibleDirectories=</varname></term>
+
+                                <listitem><para>Sets up a new
+                                file-system name space for executed
+                                processes. These options may be used
+                                to limit access a process might have
+                                to the main file-system
+                                hierarchy. Each setting takes a
+                                space-separated list of absolute
+                                directory paths. Directories listed in
+                                <varname>ReadWriteDirectories=</varname>
+                                are accessible from within the
+                                namespace with the same access rights
+                                as from outside. Directories listed in
+                                <varname>ReadOnlyDirectories=</varname>
+                                are accessible for reading only,
+                                writing will be refused even if the
+                                usual file access controls would
+                                permit this. Directories listed in
+                                <varname>InaccessibleDirectories=</varname>
+                                will be made inaccessible for processes
+                                inside the namespace. Note that
+                                restricting access with these options
+                                does not extend to submounts of a
+                                directory. You must list submounts
+                                separately in these settings to
+                                ensure the same limited access. These
+                                options may be specified more than
+                                once in which case all directories
+                                listed will have limited access from
+                                within the
+                                namespace.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PrivateTmp=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true sets up a new file
+                                system namespace for the executed
+                                processes and mounts a private
+                                <filename>/tmp</filename> directory
+                                inside it, that is not shared by
+                                processes outside of the
+                                namespace. This is useful to secure
+                                access to temporary files of the
+                                process, but makes sharing between
+                                processes via
+                                <filename>/tmp</filename>
+                                impossible. Defaults to
+                                false.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PrivateNetwork=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true sets up a new
+                                network namespace for the executed
+                                processes and configures only the
+                                loopback network device
+                                <literal>lo</literal> inside it. No
+                                other network devices will be
+                                available to the executed process.
+                                This is useful to securely turn off
+                                network access by the executed
+                                process. Defaults to
+                                false.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>MountFlags=</varname></term>
+
+                                <listitem><para>Takes a mount
+                                propagation flag:
+                                <option>shared</option>,
+                                <option>slave</option> or
+                                <option>private</option>, which
+                                control whether the file system
+                                namespace set up for this unit's
+                                processes will receive or propagate
+                                new mounts. See
+                                <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details. Default to
+                                <option>shared</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>UtmpIdentifier=</varname></term>
+
+                                <listitem><para>Takes a four
+                                character identifier string for an
+                                utmp/wtmp entry for this service. This
+                                should only be set for services such
+                                as <command>getty</command>
+                                implementations where utmp/wtmp
+                                entries must be created and cleared
+                                before and after execution. If the
+                                configured string is longer than four
+                                characters it is truncated and the
+                                terminal four characters are
+                                used. This setting interprets %I style
+                                string replacements. This setting is
+                                unset by default, i.e. no utmp/wtmp
+                                entries are created or cleaned up for
+                                this service.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>IgnoreSIGPIPE=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true causes SIGPIPE to be
+                                ignored in the executed
+                                process. Defaults to true, since
+                                SIGPIPE generally is useful only in
+                                shell pipelines.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>NoNewPrivileges=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true ensures that the
+                                service process and all its children
+                                can never gain new privileges. This
+                                option is more powerful than the respective
+                                secure bits flags (see above), as it
+                                also prohibits UID changes of any
+                                kind. This is the simplest, most
+                                effective way to ensure that a process
+                                and its children can never elevate
+                                privileges again.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SystemCallFilter=</varname></term>
+
+                                <listitem><para>Takes a space
+                                separated list of system call
+                                names. If this setting is used all
+                                system calls executed by the unit
+                                process except for the listed ones
+                                will result in immediate process
+                                termination with the SIGSYS signal
+                                (whitelisting). If the first character
+                                of the list is <literal>~</literal>
+                                the effect is inverted: only the
+                                listed system calls will result in
+                                immediate process termination
+                                (blacklisting). If this option is used
+                                <varname>NoNewPrivileges=yes</varname>
+                                is implied. This feature makes use of
+                                the Secure Computing Mode 2 interfaces
+                                of the kernel ('seccomp filtering')
+                                and is useful for enforcing a minimal
+                                sandboxing environment. Note that the
+                                <function>execve</function>,
+                                <function>rt_sigreturn</function>,
+                                <function>sigreturn</function>,
+                                <function>exit_group</function>,
+                                <function>exit</function> system calls
+                                are implicitly whitelisted and don't
+                                need to be listed
+                                explicitly.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
new file mode 100644 (file)
index 0000000..76a436d
--- /dev/null
@@ -0,0 +1,450 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.journal-fields">
+
+        <refentryinfo>
+                <title>systemd.journal-fields</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.journal-fields</refentrytitle>
+                <manvolnum>7</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.journal-fields</refname>
+                <refpurpose>Special journal fields</refpurpose>
+        </refnamediv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>Entries in the journal resemble an environment
+                block in their syntax, however with fields that can
+                include binary data. Primarily, fields are formatted
+                UTF-8 text strings, and binary formatting is used only
+                where formatting as UTF-8 text strings makes little
+                sense. New fields may freely be defined by
+                applications, but a few fields have special
+                meaning. All fields with special meanings are
+                optional. In some cases fields may appear more than
+                once per entry.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>User Journal Fields</title>
+
+                <para>User fields are fields that are directly passed
+                from clients and stored in the journal.</para>
+
+                <variablelist class='journal-directives'>
+                        <varlistentry>
+                                <term><varname>MESSAGE=</varname></term>
+                                <listitem>
+                                        <para>The human readable
+                                        message string for this
+                                        entry. This is supposed to be
+                                        the primary text shown to the
+                                        user. It is usually not
+                                        translated (but might be in
+                                        some cases), and is not
+                                        supposed to be parsed for meta
+                                        data.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>MESSAGE_ID=</varname></term>
+                                <listitem>
+                                        <para>A 128bit message
+                                        identifier ID for recognizing
+                                        certain message types, if this
+                                        is desirable. This should
+                                        contain a 128bit id formatted
+                                        as lower-case hexadecimal
+                                        string, without any separating
+                                        dashes or suchlike. This is
+                                        recommended to be a UUID
+                                        compatible ID, but this is not
+                                        enforced, and formatted
+                                        differently. Developers can
+                                        generate a new ID for this
+                                        purpose with
+                                        <command>journalctl
+                                        --new-id</command>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PRIORITY=</varname></term>
+                                <listitem>
+                                        <para>A priority value between
+                                        0 (<literal>emerg</literal>)
+                                        and 7
+                                        (<literal>debug</literal>)
+                                        formatted as decimal
+                                        string. This field is
+                                        compatible with syslog's
+                                        priority concept.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>CODE_FILE=</varname></term>
+                                <term><varname>CODE_LINE=</varname></term>
+                                <term><varname>CODE_FUNC=</varname></term>
+                                <listitem>
+                                        <para>The code location
+                                        generating this message, if
+                                        known. Contains the source
+                                        file name, the line number and
+                                        the function name.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ERRNO=</varname></term>
+                                <listitem>
+                                        <para>The low-level Unix error
+                                        number causing this entry, if
+                                        any. Contains the numeric
+                                        value of
+                                        <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                        formatted as decimal
+                                        string.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SYSLOG_FACILITY=</varname></term>
+                                <term><varname>SYSLOG_IDENTIFIER=</varname></term>
+                                <term><varname>SYSLOG_PID=</varname></term>
+                                <listitem>
+                                        <para>Syslog compatibility
+                                        fields containing the facility
+                                        (formatted as decimal string),
+                                        the identifier string
+                                        (i.e. "tag"), and the client
+                                        PID.</para>
+                                </listitem>
+
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Trusted Journal Fields</title>
+
+                <para>Fields prefixed with an underscore are trusted
+                fields, i.e. fields that are implicitly added by the
+                journal and cannot be altered by client code.</para>
+
+                <variablelist class='journal-directives'>
+                        <varlistentry>
+                                <term><varname>_PID=</varname></term>
+                                <term><varname>_UID=</varname></term>
+                                <term><varname>_GID=</varname></term>
+                                <listitem>
+                                        <para>The process, user and
+                                        group ID of the process the
+                                        journal entry originates from
+                                        formatted as decimal
+                                        string.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_COMM=</varname></term>
+                                <term><varname>_EXE=</varname></term>
+                                <term><varname>_CMDLINE=</varname></term>
+                                <listitem>
+                                        <para>The name, the executable
+                                        path and the command line of
+                                        the process the journal entry
+                                        originates from.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_AUDIT_SESSION=</varname></term>
+                                <term><varname>_AUDIT_LOGINUID=</varname></term>
+                                <listitem>
+                                        <para>The session and login
+                                        UID of the process the journal
+                                        entry originates from, as
+                                        maintained by the kernel audit
+                                        subsystem.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_SYSTEMD_CGROUP=</varname></term>
+                                <term><varname>_SYSTEMD_SESSION=</varname></term>
+                                <term><varname>_SYSTEMD_UNIT=</varname></term>
+                                <term><varname>_SYSTEMD_OWNER_UID=</varname></term>
+
+                                <listitem>
+                                        <para>The control group path in
+                                        the systemd hierarchy, the
+                                        systemd session ID (if any),
+                                        the systemd unit name (if any)
+                                        and the owner UID of the
+                                        systemd session (if any) of
+                                        the process the journal entry
+                                        originates from.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_SELINUX_CONTEXT=</varname></term>
+                                <listitem>
+                                        <para>The SELinux security
+                                        context of the process the
+                                        journal entry originates
+                                        from.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_SOURCE_REALTIME_TIMESTAMP=</varname></term>
+                                <listitem>
+                                        <para>The earliest trusted
+                                        timestamp of the message, if
+                                        any is known that is different
+                                        from the reception time of the
+                                        journal. This is the time in
+                                        usec since the epoch UTC
+                                        formatted as decimal
+                                        string.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_BOOT_ID=</varname></term>
+                                <listitem>
+                                        <para>The kernel boot ID for
+                                        the boot the message was
+                                        generated in, formatted as
+                                        128bit hexadecimal
+                                        string.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_MACHINE_ID=</varname></term>
+                                <listitem>
+                                        <para>The machine ID of the
+                                        originating host, as available
+                                        in
+                                        <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_HOSTNAME=</varname></term>
+                                <listitem>
+                                        <para>The name of the
+                                        originating host.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>_TRANSPORT=</varname></term>
+                                <listitem>
+                                        <para>How the entry was
+                                        received by the journal
+                                        service. One of
+                                        <literal>driver</literal>,
+                                        <literal>syslog</literal>,
+                                        <literal>journal</literal>,
+                                        <literal>stdout</literal>,
+                                        <literal>kernel</literal> for
+                                        internally generated messages,
+                                        for those received via the
+                                        local syslog socket with the
+                                        syslog protocol, for those
+                                        received via the native
+                                        journal protocol, for the
+                                        those read from a services'
+                                        standard output or error
+                                        output, or for those read
+                                        from the kernel, respectively.
+                                        </para>
+                                </listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Journal Fields</title>
+
+                <para>Kernel fields are fields that are used by
+                messages originating in the kernel and stored in the
+                journal.</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>_KERNEL_DEVICE=</term>
+                                <listitem>
+                                        <para>The kernel device
+                                        name. If the entry is
+                                        associated to a block device,
+                                        the major and minor of the
+                                        device node, separated by ':'
+                                        and prefixed by 'b'. Similar
+                                        for character devices, but
+                                        prefixed by 'c'. For network
+                                        devices the interface index,
+                                        prefixed by 'n'. For all other
+                                        devices '+' followed by the
+                                        subsystem name, followed by
+                                        ':', followed by the kernel
+                                        device name.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term>_KERNEL_SUBSYSTEM=</term>
+                                <listitem>
+                                        <para>The kernel subsystem name.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term>_UDEV_SYSNAME=</term>
+                                <listitem>
+                                        <para>The kernel device name
+                                        as it shows up in the device
+                                        tree below
+                                        <filename>/sys</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term>_UDEV_DEVNODE=</term>
+                                <listitem>
+                                        <para>The device node path of
+                                        this device in
+                                        <filename>/dev</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term>_UDEV_DEVLINK=</term>
+                                <listitem>
+                                        <para>Additional symlink names
+                                        pointing to the device node in
+                                        <filename>/dev</filename>. This
+                                        field is frequently set more
+                                        than once per entry.</para>
+                                </listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Address Fields</title>
+
+                <para>During serialization into external formats, such
+                as the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+                Export Format</ulink> or the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal
+                JSON Format</ulink>, the addresses of journal entries
+                are serialized into fields prefixed with double
+                underscores. Note that these aren't proper fields when
+                stored in the journal, but addressing meta data of
+                entries. They cannot be written as part of structured
+                log entries via calls such as
+                <citerefentry><refentrytitle>sd_journal_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>. They
+                may also not be used as matches for
+                <citerefentry><refentrytitle>sd_journal_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry></para>
+
+                <variablelist class='journal-directives'>
+                        <varlistentry>
+                                <term><varname>__CURSOR=</varname></term>
+                                <listitem>
+                                        <para>The cursor for the
+                                        entry. A cursor is an opaque
+                                        text string that uniquely
+                                        describes the position of an
+                                        entry in the journal and is
+                                        portable across machines,
+                                        platforms and journal
+                                        files.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>__REALTIME_TIMESTAMP=</varname></term>
+                                <listitem>
+                                        <para>The wallclock time
+                                        (CLOCK_REALTIME) at the point
+                                        in time the entry was received
+                                        by the journal, in usec since
+                                        the epoch UTC formatted as
+                                        decimal string. This has
+                                        different properties from
+                                        <literal>_SOURCE_REALTIME_TIMESTAMP=</literal>
+                                        as it is usually a bit later
+                                        but more likely to be
+                                        monotonic.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>__MONOTONIC_TIMESTAMP=</varname></term>
+                                <listitem>
+                                        <para>The monotonic time
+                                        (CLOCK_MONOTONIC) at the point
+                                        in time the entry was received
+                                        by the journal in usec
+                                        formatted as decimal
+                                        string. To be useful as an
+                                        address for the entry this
+                                        should be combined with with
+                                        boot ID in
+                                        <literal>_BOOT_ID=</literal>.</para>
+                                </listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml
new file mode 100644 (file)
index 0000000..3fff2f5
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.kill">
+        <refentryinfo>
+                <title>systemd.kill</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.kill</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.kill</refname>
+                <refpurpose>Kill environment configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.service</filename>,
+                <filename>systemd.socket</filename>,
+                <filename>systemd.mount</filename>,
+                <filename>systemd.swap</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>Unit configuration files for services, sockets,
+                mount points and swap devices share a subset of
+                configuration options which define the process killing
+                parameters of spawned processes.</para>
+
+                <para>This man page lists the configuration options
+                shared by these four unit types. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files, and
+                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more information on the specific unit
+                configuration files. The execution specific
+                configuration options are configured in the [Service],
+                [Socket], [Mount], or [Swap] section, depending on the unit
+                type.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>KillMode=</varname></term>
+                                <listitem><para>Specifies how
+                                processes of this service shall be
+                                killed. One of
+                                <option>control-group</option>,
+                                <option>process</option>,
+                                <option>none</option>.</para>
+
+                                <para>If set to
+                                <option>control-group</option> all
+                                remaining processes in the control
+                                group of this unit will be terminated
+                                on unit stop (for services: after the
+                                stop command is executed, as
+                                configured with
+                                <varname>ExecStop=</varname>). If set
+                                to <option>process</option> only the
+                                main process itself is killed. If set
+                                to <option>none</option> no process is
+                                killed. In this case only the stop
+                                command will be executed on unit
+                                stop, but no process be killed
+                                otherwise. Processes remaining alive
+                                after stop are left in their control
+                                group and the control group continues
+                                to exist after stop unless it is
+                                empty. Defaults to
+                                <option>control-group</option>.</para>
+
+                                <para>Processes will first be
+                                terminated via SIGTERM (unless the
+                                signal to send is changed via
+                                <varname>KillSignal=</varname>). If
+                                then after a delay (configured via the
+                                <varname>TimeoutSec=</varname> option)
+                                processes still remain, the
+                                termination request is repeated with
+                                the SIGKILL signal (unless this is
+                                disabled via the
+                                <varname>SendSIGKILL=</varname>
+                                option). See
+                                <citerefentry><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for more
+                                information.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>KillSignal=</varname></term>
+                                <listitem><para>Specifies which signal
+                                to use when killing a
+                                service. Defaults to SIGTERM.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL to remaining processes
+                                after a timeout, if the normal
+                                shutdown procedure left processes of
+                                the service around. Takes a boolean
+                                value. Defaults to "yes".
+                                </para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
new file mode 100644 (file)
index 0000000..78b5f52
--- /dev/null
@@ -0,0 +1,289 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.mount">
+        <refentryinfo>
+                <title>systemd.mount</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.mount</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.mount</refname>
+                <refpurpose>Mount unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.mount</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.mount</filename> encodes information about
+                a file system mount point controlled and supervised by
+                systemd.</para>
+
+                <para>This man page lists the configuration options
+                specific to this unit type. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic [Unit] and [Install] sections. The
+                mount specific configuration options are configured
+                in the [Mount] section.</para>
+
+                <para>Additional options are listed in
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                which define the execution environment the
+                <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                binary is executed in, and in
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                which define the way the processes are
+                terminated. Note that the User= and Group= options are
+                not particularly useful for mount units specifying a
+                <literal>Type=</literal> option or using configuration
+                not specified in <filename>/etc/fstab</filename>;
+                <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                will refuse options that aren't listed in
+                <filename>/etc/fstab</filename> if it is not run as
+                UID 0.</para>
+
+                <para>Mount units must be named after the mount point
+                directories they control. Example: the mount point
+                <filename>/home/lennart</filename> must be configured
+                in a unit file
+                <filename>home-lennart.mount</filename>. For details
+                about the escaping logic used to convert a file system
+                path to a unit name see
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+                <para>Optionally, a mount unit may be accompanied by
+                an automount unit, to allow on-demand or parallelized
+                mounting. See
+                <citerefentry><refentrytitle>systemd.automount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+                <para>If a mount point is beneath another mount point
+                in the file system hierarchy, a dependency between both
+                units is created automatically.</para>
+
+                <para>Mount points created at runtime independent on
+                unit files or <filename>/etc/fstab</filename> will be
+                monitored by systemd and appear like any other mount
+                unit in systemd.</para>
+        </refsect1>
+
+        <refsect1>
+                <title><filename>/etc/fstab</filename></title>
+
+                <para>Mount units may either be configured via unit
+                files, or via <filename>/etc/fstab</filename> (see
+                <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details). Mounts listed in
+                <filename>/etc/fstab</filename> will be converted into
+                native units dynamically at boot and when the
+                configuration of the system manager is reloaded. See
+                <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                for details about the conversion.</para>
+
+                <para>When reading <filename>/etc/fstab</filename> a
+                few special mount options are understood by systemd
+                which influence how dependencies are created for mount
+                points from <filename>/etc/fstab</filename>. systemd
+                will create a dependency of type
+                <option>Wants</option> from either
+                <filename>local-fs.target</filename> or
+                <filename>remote-fs.target</filename>, depending
+                whether the file system is local or remote. If
+                <option>x-systemd.automount</option> is set, an
+                automount unit will be created for the file
+                system. See
+                <citerefentry><refentrytitle>systemd.automount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details. If
+                <option>x-systemd.device-timeout=</option> is
+                specified it may be used to configure how long systemd
+                should wait for a device to show up before giving up
+                on an entry from
+                <filename>/etc/fstab</filename>. Specify a time in
+                seconds or explicitly specify a unit as
+                <literal>s</literal>, <literal>min</literal>,
+                <literal>h</literal>, <literal>ms</literal>.</para>
+
+                <para>If a mount point is configured in both
+                <filename>/etc/fstab</filename> and a unit file, the
+                configuration in the latter takes precedence.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>Mount files must include a [Mount] section,
+                which carries information about the file system mount points it
+                supervises. A number of options that may be used in
+                this section are shared with other unit types. These
+                options are documented in
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
+                options specific to the [Mount] section of mount
+                units are the following:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>What=</varname></term>
+                                <listitem><para>Takes an absolute path
+                                of a device node, file or other
+                                resource to mount. See
+                                <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for details. If this refers to a
+                                device node, a dependency on the
+                                respective device unit is
+                                automatically created. (See
+                                <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.)
+                                This option is
+                                mandatory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Where=</varname></term>
+                                <listitem><para>Takes an absolute path
+                                of a directory of the mount point. If
+                                the mount point does not exist at the
+                                time of mounting, it is created. This
+                                string must be reflected in the unit
+                                file name. (See above.) This option is
+                                mandatory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Type=</varname></term>
+                                <listitem><para>Takes a string for the
+                                filesystem type. See
+                                <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for details. This setting is
+                                optional.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Options=</varname></term>
+
+                                <listitem><para>Mount options to use
+                                when mounting. This takes a comma
+                                separated list of options. This
+                                setting is optional.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>DirectoryMode=</varname></term>
+                                <listitem><para>Directories of mount
+                                points (and any parent directories)
+                                are automatically created if
+                                needed. This option specifies the file
+                                system access mode used when creating
+                                these directories. Takes an access
+                                mode in octal notation. Defaults to
+                                0755.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimeoutSec=</varname></term>
+                                <listitem><para>Configures the time to
+                                wait for the mount command to
+                                finish. If a command does not exit
+                                within the configured time the mount
+                                will be considered failed and be shut
+                                down again. All commands still running
+                                will be terminated forcibly via
+                                SIGTERM, and after another delay of
+                                this time with SIGKILL. (See
+                                <option>KillMode=</option> in
+                                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>.)
+                                Takes a unit-less value in seconds, or
+                                a time span value such as "5min
+                                20s". Pass 0 to disable the timeout
+                                logic. Defaults to
+                                90s.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>Check
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more settings.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Compatibility Options</title>
+
+                <para>The following option is also available in the
+                <literal>[Mount]</literal> section, but exists purely
+                for compatibility reasons and should not be used in
+                newly written mount files.</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>FsckPassNo=</varname></term>
+
+                                <listitem><para>The pass number for
+                                the file system checking service for
+                                this mount. See
+                                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for more information on this setting.
+                                </para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.path.xml b/man/systemd.path.xml
new file mode 100644 (file)
index 0000000..a27a97b
--- /dev/null
@@ -0,0 +1,220 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.path">
+        <refentryinfo>
+                <title>systemd.path</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.path</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.path</refname>
+                <refpurpose>Path unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.path</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.path</filename> encodes information about
+                a path monitored by systemd, for
+                path-based activation.</para>
+
+                <para>This man page lists the configuration options
+                specific to this unit type. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic [Unit] and [Install] sections. The
+                path specific configuration options are configured in
+                the [Path] section.</para>
+
+                <para>For each path file, a matching unit file must
+                exist, describing the unit to activate when the path
+                changes. By default, a service by the same name as the
+                path (except for the suffix) is activated. Example: a
+                path file <filename>foo.path</filename> activates a
+                matching service <filename>foo.service</filename>. The
+                unit to activate may be controlled by
+                <varname>Unit=</varname> (see below).</para>
+
+                <para>Internally, path units use the
+                <citerefentry><refentrytitle>inotify</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                API to monitor file systems. Due to that, it suffers by the
+                same limitations as inotify, and for example cannot be
+                used to monitor files or directories changed by other
+                machines on remote NFS file systems.</para>
+
+                <para>If a path unit is beneath another mount
+                point in the file system hierarchy, a dependency
+                between both units is created automatically.</para>
+
+                <para>Unless <varname>DefaultDependencies=</varname>
+                is set to <option>false</option>, path units will
+                implicitly have dependencies of type
+                <varname>Conflicts=</varname> and
+                <varname>Before=</varname> on
+                <filename>shutdown.target</filename>. These ensure
+                that path units are terminated cleanly prior to system
+                shutdown. Only path units involved with early boot or
+                late system shutdown should disable this
+                option.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>Path files must include a [Path] section,
+                which carries information about the path(s) it
+                monitors. The options specific to the [Path] section
+                of path units are the following:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>PathExists=</varname></term>
+                                <term><varname>PathExistsGlob=</varname></term>
+                                <term><varname>PathChanged=</varname></term>
+                                <term><varname>PathModified=</varname></term>
+                                <term><varname>DirectoryNotEmpty=</varname></term>
+
+                                <listitem><para>Defines paths to
+                                monitor for certain changes:
+                                <varname>PathExists=</varname> may be
+                                used to watch the mere existence of a
+                                file or directory. If the file
+                                specified exists the configured unit
+                                is
+                                activated. <varname>PathExistsGlob=</varname>
+                                works similar, but checks for the
+                                existence of at least one file
+                                matching the globbing pattern
+                                specified. <varname>PathChanged=</varname>
+                                may be used to watch a file or
+                                directory and activate the configured
+                                unit whenever it changes. It is not activated
+                                on every write to the watched file but it is
+                                activated if the file which was open for writing
+                                gets closed. <varname>PathModified=</varname>
+                                is similar, but additionally it is activated
+                                also on simple writes to the watched file.
+
+                                <varname>DirectoryNotEmpty=</varname>
+                                may be used to watch a directory and
+                                activate the configured unit whenever
+                                it contains at least one file.</para>
+
+                                <para>The arguments of these
+                                directives must be absolute file
+                                system paths.</para>
+
+                                <para>Multiple directives may be
+                                combined, of the same and of different
+                                types, to watch multiple paths.</para>
+
+                                <para>If a path is already existing
+                                (in case of
+                                <varname>PathExists=</varname> and
+                                <varname>PathExistsGlob=</varname>) or
+                                a directory already is not empty (in
+                                case of
+                                <varname>DirectoryNotEmpty=</varname>)
+                                at the time the path unit is
+                                activated, then the configured unit is
+                                immediately activated as
+                                well. Something similar does not apply
+                                to <varname>PathChanged=</varname>.
+                                </para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Unit=</varname></term>
+
+                                <listitem><para>The unit to activate
+                                when any of the configured paths
+                                changes. The argument is a unit name,
+                                whose suffix is not
+                                <filename>.path</filename>. If not
+                                specified, this value defaults to a
+                                service that has the same name as the
+                                path unit, except for the suffix. (See
+                                above.) It is recommended that the
+                                unit name that is activated and the
+                                unit name of the path unit are named
+                                identical, except for the
+                                suffix.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>MakeDirectory=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true the directories to
+                                watch are created before
+                                watching. This option is ignored for
+                                <varname>PathExists=</varname>
+                                settings. Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>DirectoryMode=</varname></term>
+
+                                <listitem><para>If
+                                <varname>MakeDirectory=</varname> is
+                                enabled use the mode specified here to
+                                create the directories in
+                                question. Takes an access mode in
+                                octal notation. Defaults to
+                                <option>0755</option>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>inotify</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml
new file mode 100644 (file)
index 0000000..a692053
--- /dev/null
@@ -0,0 +1,204 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd.preset">
+
+        <refentryinfo>
+                <title>systemd.preset</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.preset</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.preset</refname>
+                <refpurpose>Service enablement presets</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/systemd/system-preset/*.preset</filename></para>
+                <para><filename>/run/systemd/system-preset/*.preset</filename></para>
+                <para><filename>/usr/lib/systemd/system-preset/*.preset</filename></para>
+                <para><filename>/etc/systemd/user-preset/*.preset</filename></para>
+                <para><filename>/run/systemd/user-preset/*.preset</filename></para>
+                <para><filename>/usr/lib/systemd/user-preset/*.preset</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>Preset files may be used to encode policy which
+                units shall be enabled by default and which ones
+                shall be disabled. They are read by <command>systemctl
+                preset</command> (for more information see
+                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>)
+                which uses this information to enable or disable a
+                unit according to preset policy. <command>systemctl
+                preset</command> is used by the post install
+                scriptlets of RPM packages (or other OS package formats),
+                to enable/disable specific units by default on package
+                installation, enforcing distribution, spin or
+                administrator preset policy. This allows choosing a certain
+                set of units to be enabled/disabled even before
+                installing the actual package.</para>
+
+                <para>For more information on the preset logic please
+                have a look at the <ulink
+                url="http://freedesktop.org/wiki/Software/systemd/Preset">Presets</ulink>
+                document.</para>
+
+                <para>It is not recommended to ship preset files
+                within the respective software packages implementing
+                the units, but rather centralize them in a
+                distribution or spin default policy, which can be
+                amended by administrator policy.</para>
+
+                <para>If no preset files exist, <command>systemctl
+                preset</command> will enable all units that are
+                installed by default. If this is not desired and all
+                units shall rather be disabled it is necessary to ship
+                a preset file with a single, catchall
+                "<filename>disable *</filename>" line. (See example 1,
+                below.)</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Preset File Format</title>
+
+                <para>The preset files contain a list of
+                directives consisting of either the word
+                <literal>enable</literal> or
+                <literal>disable</literal> followed by a space and a
+                unit name (possibly with shell style wildcards),
+                separated by newlines. Empty lines and lines whose
+                first non-whitespace character is # or ; are
+                ignored.</para>
+
+                <para>Two different directives are understood:
+                <literal>enable</literal> may be used to enable units
+                by default, <literal>disable</literal> to disable
+                units by default.</para>
+
+                <para>If multiple lines apply to a unit name the
+                first matching one takes precedence over all
+                others.</para>
+
+                <para>Each preset file shall be named in the style of
+                <filename>&lt;priority&gt;-&lt;program&gt;.conf</filename>.
+                Files in <filename>/etc/</filename> override files
+                with the same name in <filename>/usr/lib/</filename>
+                and <filename>/run/</filename>.  Files in
+                <filename>/run/</filename> override files with the
+                same name in <filename>/usr/lib/</filename>. Packages
+                should install their preset files in
+                <filename>/usr/lib/</filename>. Files in
+                <filename>/etc/</filename> are reserved for the local
+                administrator, who may use this logic to override the
+                preset files installed by vendor packages. All preset
+                files are sorted by their filename in alphabetical
+                order, regardless in which of the directories they
+                reside, to guarantee that a specific preset file takes
+                precedence over another file with an alphabetically
+                earlier name, if both files contain lines that apply
+                to the same unit names. It is recommended to prefix
+                all file names with two-digit number, to simplify
+                ordering.</para>
+
+                <para>If the administrator wants to disable a preset
+                file supplied by the vendor the recommended way is to
+                place a symlink to <filename>/dev/null</filename> in
+                <filename>/etc/systemd/system-preset/</filename>
+                bearing the same file name.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+
+                <example>
+                        <title>Default off example <filename>/usr/lib/systemd/system-preset/99-default.preset</filename>:</title>
+
+                        <programlisting>disable *</programlisting>
+                </example>
+
+                <para>This disables all units. Due to the file name
+                prefix <literal>99-</literal> it will be read last and
+                hence can easily be overridden by spin or
+                administrator preset policy or suchlike.</para>
+
+                <example>
+                        <title>A GNOME spin example <filename>/usr/lib/systemd/system-preset/50-gnome.preset</filename>:</title>
+
+                        <programlisting>enable gdm.service
+enable colord.service
+enable accounts-daemon.service
+enable avahi-daemon.*</programlisting>
+
+                </example>
+
+                <para>This enables the three mentioned units, plus all
+                <filename>avahi-daemon</filename> regardless of which
+                unit type. A file like this could be useful for
+                inclusion in a GNOME spin of a distribution. It will
+                ensure that the units necessary for GNOME are properly
+                enabled as they are installed. It leaves all other
+                units untouched, and subject to other (later) preset
+                files, for example like the one from the first example
+                above.</para>
+
+                <example>
+                        <title>Administrator policy <filename>/etc/systemd/system-preset/00-lennart.preset</filename>:</title>
+
+                        <programlisting>enable httpd.service
+enable sshd.service
+enable postfix.service
+disable *</programlisting>
+                </example>
+
+                <para>This enables three specific services and
+                disables all others. This is useful for administrators
+                to specifically select the units to enable, and
+                disable all others. Due to the file name prefix
+                <literal>00-</literal> it will be read early and hence
+                overrides all other preset policy files.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
new file mode 100644 (file)
index 0000000..598e863
--- /dev/null
@@ -0,0 +1,929 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.service">
+        <refentryinfo>
+                <title>systemd.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.service</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.service</refname>
+                <refpurpose>Service unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.service</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.service</filename> encodes information
+                about a process controlled and supervised by
+                systemd.</para>
+
+                <para>This man page lists the configuration options
+                specific to this unit type. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic <literal>[Unit]</literal> and
+                <literal>[Install]</literal> sections. The service
+                specific configuration options are configured in the
+                <literal>[Service]</literal> section.</para>
+
+                <para>Additional options are listed in
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                which define the execution environment the commands
+                are executed in, and in
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                which define the way the processes of the service are
+                terminated.</para>
+
+                <para>Unless <varname>DefaultDependencies=</varname>
+                is set to <option>false</option>, service units will
+                implicitly have dependencies of type
+                <varname>Requires=</varname> and
+                <varname>After=</varname> on
+                <filename>basic.target</filename> as well as
+                dependencies of type <varname>Conflicts=</varname> and
+                <varname>Before=</varname> on
+                <filename>shutdown.target</filename>. These ensure
+                that normal service units pull in basic system
+                initialization, and are terminated cleanly prior to
+                system shutdown. Only services involved with early
+                boot or late system shutdown should disable this
+                option.</para>
+
+                <para>If a service is requested under a certain name
+                but no unit configuration file is found, systemd looks
+                for a SysV init script by the same name (with the
+                <filename>.service</filename> suffix removed) and
+                dynamically creates a service unit from that
+                script. This is useful for compatibility with
+                SysV. Note that this compatibility is quite
+                comprehensive but not 100%. For details about the
+                incompatibilities see the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/Incompatibilities">Incompatibilities
+                with SysV</ulink> document.
+                </para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>Service files must include a
+                <literal>[Service]</literal> section, which carries
+                information about the service and the process it
+                supervises. A number of options that may be used in
+                this section are shared with other unit types. These
+                options are documented in
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
+                options specific to the <literal>[Service]</literal>
+                section of service units are the following:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>Type=</varname></term>
+
+                                <listitem><para>Configures the process
+                                start-up type for this service
+                                unit. One of <option>simple</option>,
+                                <option>forking</option>,
+                                <option>oneshot</option>,
+                                <option>dbus</option>,
+                                <option>notify</option> or
+                                <option>idle</option>.</para>
+
+                                <para>If set to
+                                <option>simple</option> (the default
+                                value if <varname>BusName=</varname>
+                                is not specified) it is expected that
+                                the process configured with
+                                <varname>ExecStart=</varname> is the
+                                main process of the service. In this
+                                mode, if the process offers
+                                functionality to other processes on
+                                the system its communication channels
+                                should be installed before the daemon
+                                is started up (e.g. sockets set up by
+                                systemd, via socket activation), as
+                                systemd will immediately proceed
+                                starting follow-up units.</para>
+
+                                <para>If set to
+                                <option>forking</option> it is
+                                expected that the process configured
+                                with <varname>ExecStart=</varname>
+                                will call <function>fork()</function>
+                                as part of its start-up. The parent process is
+                                expected to exit when start-up is
+                                complete and all communication
+                                channels set up. The child continues
+                                to run as the main daemon
+                                process. This is the behavior of
+                                traditional UNIX daemons. If this
+                                setting is used, it is recommended to
+                                also use the
+                                <varname>PIDFile=</varname> option, so
+                                that systemd can identify the main
+                                process of the daemon. systemd will
+                                proceed starting follow-up units as
+                                soon as the parent process
+                                exits.</para>
+
+                                <para>Behavior of
+                                <option>oneshot</option> is similar
+                                to <option>simple</option>, however
+                                it is expected that the process has to
+                                exit before systemd starts follow-up
+                                units. <varname>RemainAfterExit=</varname>
+                                is particularly useful for this type
+                                of service.</para>
+
+                                <para>Behavior of
+                                <option>dbus</option> is similar to
+                                <option>simple</option>, however it is
+                                expected that the daemon acquires a
+                                name on the D-Bus bus, as configured
+                                by
+                                <varname>BusName=</varname>. systemd
+                                will proceed starting follow-up units
+                                after the D-Bus bus name has been
+                                acquired. Service units with this
+                                option configured implicitly gain
+                                dependencies on the
+                                <filename>dbus.socket</filename>
+                                unit. This type is the default if
+                                <varname>BusName=</varname> is
+                                specified.</para>
+
+                                <para>Behavior of
+                                <option>notify</option> is similar to
+                                <option>simple</option>, however it is
+                                expected that the daemon sends a
+                                notification message via
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                or an equivalent call when it finished
+                                starting up. systemd will proceed
+                                starting follow-up units after this
+                                notification message has been sent. If
+                                this option is used
+                                <varname>NotifyAccess=</varname> (see
+                                below) should be set to open access to
+                                the notification socket provided by
+                                systemd. If
+                                <varname>NotifyAccess=</varname> is
+                                not set, it will be implicitly set to
+                                <option>main</option>.</para>
+
+                                <para>Behavior of
+                                <option>idle</option> is very similar
+                                to <option>simple</option>, however
+                                actual execution of the service
+                                binary is delayed until all jobs are
+                                dispatched. This may be used to avoid
+                                interleaving of output of shell
+                                services with the status output on the
+                                console.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RemainAfterExit=</varname></term>
+
+                                <listitem><para>Takes a boolean value
+                                that specifies whether the service
+                                shall be considered active even when
+                                all its processes exited. Defaults to
+                                <option>no</option>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>GuessMainPID=</varname></term>
+
+                                <listitem><para>Takes a boolean value
+                                that specifies whether systemd should
+                                try to guess the main PID of a service
+                                if it cannot be determined
+                                reliably. This option is ignored
+                                unless <option>Type=forking</option>
+                                is set and <option>PIDFile=</option>
+                                is unset because for the other types
+                                or with an explicitly configured PID
+                                file the main PID is always known. The
+                                guessing algorithm might come to
+                                incorrect conclusions if a daemon
+                                consists of more than one process. If
+                                the main PID cannot be determined
+                                failure detection and automatic
+                                restarting of a service will not work
+                                reliably. Defaults to
+                                <option>yes</option>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PIDFile=</varname></term>
+
+                                <listitem><para>Takes an absolute file
+                                name pointing to the PID file of this
+                                daemon. Use of this option is
+                                recommended for services where
+                                <varname>Type=</varname> is set to
+                                <option>forking</option>. systemd will
+                                read the PID of the main process of
+                                the daemon after start-up of the
+                                service. systemd will not write to the
+                                file configured here.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>BusName=</varname></term>
+
+                                <listitem><para>Takes a D-Bus bus
+                                name, that this service is reachable
+                                as. This option is mandatory for
+                                services where
+                                <varname>Type=</varname> is set to
+                                <option>dbus</option>, but its use
+                                is otherwise recommended as well if
+                                the process takes a name on the D-Bus
+                                bus.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ExecStart=</varname></term>
+                                <listitem><para>Commands with their
+                                arguments that are executed when this
+                                service is started.
+                                </para>
+
+                                <para>When
+                                <varname>Type=oneshot</varname> is
+                                used, more than one command may be
+                                specified. Multiple command lines may
+                                be concatenated in a single directive,
+                                by separating them with semicolons
+                                (these semicolons must be passed as
+                                separate words). Alternatively, this
+                                directive may be specified more than
+                                once with the same effect. However,
+                                the latter syntax is not recommended
+                                for compatibility with parsers
+                                suitable for XDG
+                                <filename>.desktop</filename> files.
+                                The commands are invoked one by
+                                one sequentially in the order they
+                                appear in the unit file.
+                                When <varname>Type</varname> is
+                                not <option>oneshot</option>, only one
+                                command may be given. Lone semicolons
+                                may be escaped as
+                                '<literal>\;</literal>'.</para>
+
+                                <para>Unless
+                                <varname>Type=forking</varname> is
+                                set, the process started via this
+                                command line will be considered the
+                                main process of the daemon.</para>
+
+                                <para>The command line accepts
+                                '<literal>%</literal>' specifiers as
+                                described in
+                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Note
+                                that the first argument of the command
+                                line (i.e. the program to execute) may
+                                not include specifiers.</para>
+
+                                <para>Optionally, if the absolute file
+                                name is prefixed with
+                                '<literal>@</literal>', the second token
+                                will be passed as
+                                <literal>argv[0]</literal> to the
+                                executed process, followed by the
+                                further arguments specified. If the
+                                absolute file name is prefixed with
+                                '<literal>-</literal>' an exit code of
+                                the command normally considered a
+                                failure (i.e. non-zero exit status or
+                                abnormal exit due to signal) is ignored
+                                and considered success. If both
+                                '<literal>-</literal>' and
+                                '<literal>@</literal>' are used they
+                                can appear in either order.</para>
+
+                                <para>On top of that basic environment
+                                variable substitution is
+                                supported. Use
+                                <literal>${FOO}</literal> as part of a
+                                word, or as a word of its own on the
+                                command line, in which case it will be
+                                replaced by the value of the
+                                environment variable including all
+                                whitespace it contains, resulting in a
+                                single argument.  Use
+                                <literal>$FOO</literal> as a separate
+                                word on the command line, in which
+                                case it will be replaced by the value
+                                of the environment variable split up
+                                at whitespace, resulting in no or more
+                                arguments. Note that the first
+                                argument (i.e. the program to execute)
+                                may not be a variable, and must be a
+                                literal and absolute path
+                                name.</para>
+
+                                <para>Note that this setting does not
+                                directly support shell command
+                                lines. If shell command lines are to
+                                be used they need to be passed
+                                explicitly to a shell implementation
+                                of some kind. Example:
+                                <literal>ExecStart=/bin/sh -c 'dmesg | tac'</literal></para>
+
+                                <para>For services run by a user
+                                instance of systemd the special
+                                environment variable
+                                <literal>MANAGERPID</literal> is set
+                                to the PID of the systemd
+                                instance.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ExecStartPre=</varname></term>
+                                <term><varname>ExecStartPost=</varname></term>
+                                <listitem><para>Additional commands
+                                that are executed before or after
+                                the command in
+                                <varname>ExecStart=</varname>, respectively.
+                                Syntax is the same as for
+                                <varname>ExecStart=</varname>, except
+                                that multiple command lines are allowed
+                                and the commands are executed one
+                                after the other, serially.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ExecReload=</varname></term>
+                                <listitem><para>Commands to execute to
+                                trigger a configuration reload in the
+                                service. This argument takes multiple
+                                command lines, following the same
+                                scheme as described for
+                                <varname>ExecStart=</varname>
+                                above. Use of this setting is
+                                optional. Specifier and environment
+                                variable substitution is supported
+                                here following the same scheme as for
+                                <varname>ExecStart=</varname>. One
+                                additional special environment
+                                variables is set: if known
+                                <literal>$MAINPID</literal> is set to
+                                the main process of the daemon, and
+                                may be used for command lines like the
+                                following: <command>/bin/kill -HUP
+                                $MAINPID</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ExecStop=</varname></term>
+                                <listitem><para>Commands to execute to
+                                stop the service started via
+                                <varname>ExecStart=</varname>. This
+                                argument takes multiple command lines,
+                                following the same scheme as described
+                                for <varname>ExecStart=</varname>
+                                above. Use of this setting is
+                                optional. All processes remaining for
+                                a service after the commands
+                                configured in this option are run are
+                                terminated according to the
+                                <varname>KillMode=</varname> setting
+                                (see
+                                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>). If
+                                this option is not specified the
+                                process is terminated right-away when
+                                service stop is requested. Specifier
+                                and environment variable substitution
+                                is supported (including
+                                <literal>$MAINPID</literal>, see
+                                above).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ExecStopPost=</varname></term>
+                                <listitem><para>Additional commands
+                                that are executed after the service
+                                was stopped using the commands
+                                configured in
+                                <varname>ExecStop=</varname>. This
+                                argument takes multiple command lines,
+                                following the same scheme as described
+                                for <varname>ExecStart</varname>. Use
+                                of these settings is
+                                optional. Specifier and environment
+                                variable substitution is
+                                supported.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RestartSec=</varname></term>
+                                <listitem><para>Configures the time to
+                                sleep before restarting a service (as
+                                configured with
+                                <varname>Restart=</varname>). Takes a
+                                unit-less value in seconds, or a time
+                                span value such as "5min
+                                20s". Defaults to
+                                100ms.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimeoutStartSec=</varname></term>
+                                <listitem><para>Configures the time to
+                                wait for start-up. If a
+                                daemon service does not signal
+                                start-up completion within the
+                                configured time, the service will be
+                                considered failed and be shut down
+                                again.
+                                Takes a unit-less value in seconds, or a
+                                time span value such as "5min
+                                20s". Pass 0 to disable the timeout
+                                logic. Defaults to 90s, except when
+                                <varname>Type=oneshot</varname> is
+                                used in which case the timeout
+                                is disabled by default.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimeoutStopSec=</varname></term>
+                                <listitem><para>Configures the time to
+                                wait for stop. If a service is asked
+                                to stop but does not terminate in the
+                                specified time, it will be terminated
+                                forcibly via SIGTERM, and after
+                                another delay of this time with
+                                SIGKILL (See
+                                <varname>KillMode=</varname>
+                                in <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+                                Takes a unit-less value in seconds, or a
+                                time span value such as "5min
+                                20s". Pass 0 to disable the timeout
+                                logic. Defaults to 90s.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimeoutSec=</varname></term>
+                                <listitem><para>A shorthand for configuring
+                                both <varname>TimeoutStartSec=</varname>
+                                and <varname>TimeoutStopSec=</varname>
+                                to the specified value.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>WatchdogSec=</varname></term>
+                                <listitem><para>Configures the
+                                watchdog timeout for a service. This
+                                is activated when the start-up is
+                                completed. The service must call
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                regularly with "WATCHDOG=1" (i.e. the
+                                "keep-alive ping"). If the time
+                                between two such calls is larger than
+                                the configured time then the service
+                                is placed in a failure state. By
+                                setting <varname>Restart=</varname> to
+                                <option>on-failure</option> or
+                                <option>always</option> the service
+                                will be automatically restarted. The
+                                time configured here will be passed to
+                                the executed service process in the
+                                <varname>WATCHDOG_USEC=</varname>
+                                environment variable. This allows
+                                daemons to automatically enable the
+                                keep-alive pinging logic if watchdog
+                                support is enabled for the service. If
+                                this option is used
+                                <varname>NotifyAccess=</varname> (see
+                                below) should be set to open access to
+                                the notification socket provided by
+                                systemd. If
+                                <varname>NotifyAccess=</varname> is
+                                not set, it will be implicitly set to
+                                <option>main</option>. Defaults to 0,
+                                which disables this
+                                feature.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Restart=</varname></term>
+                                <listitem><para>Configures whether the
+                                main service process shall be
+                                restarted when it exits. Takes one of
+                                <option>no</option>,
+                                <option>on-success</option>,
+                                <option>on-failure</option>,
+                                <option>on-abort</option> or
+                                <option>always</option>. If set to
+                                <option>no</option> (the default) the
+                                service will not be restarted when it
+                                exits. If set to
+                                <option>on-success</option> it will be
+                                restarted only when it exited cleanly,
+                                i.e. terminated with an exit code of
+                                0. If set to
+                                <option>on-failure</option> it will be
+                                restarted only when it exited with an
+                                exit code not equaling 0, when
+                                terminated by a signal (including on
+                                core dump), when an operation (such as
+                                service reload) times out or when the
+                                configured watchdog timeout is
+                                triggered. If set to
+                                <option>on-abort</option> it will be
+                                restarted only if it exits due to
+                                reception of an uncaught signal
+                                (including on core dump). If set to
+                                <option>always</option> the service
+                                will be restarted regardless whether
+                                it exited cleanly or not, got
+                                terminated abnormally by a signal or
+                                hit a timeout.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SuccessExitStatus=</varname></term>
+                                <listitem><para>Takes a list of exit
+                                status definitions that when returned
+                                by the main service process will be
+                                considered successful termination, in
+                                addition to the normal successful exit
+                                code 0 and the signals SIGHUP, SIGINT,
+                                SIGTERM and SIGPIPE. Exit status
+                                definitions can either be numeric exit
+                                codes or termination signal names, and
+                                are separated by spaces. Example:
+                                "<literal>SuccessExitStatus=1 2 8
+                                SIGKILL</literal>", ensures that exit
+                                codes 1, 2, 8 and the termination
+                                signal SIGKILL are considered clean
+                                service
+                                terminations.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RestartPreventExitStatus=</varname></term>
+                                <listitem><para>Takes a list of exit
+                                status definitions that when returned
+                                by the main service process will
+                                prevent automatic service restarts
+                                regardless of the restart setting
+                                configured with
+                                <varname>Restart=</varname>. Exit
+                                status definitions can either be
+                                numeric exit codes or termination
+                                signal names, and are separated by
+                                spaces. Defaults to the empty list, so
+                                that by default no exit status is
+                                excluded from the configured restart
+                                logic. Example:
+                                "<literal>RestartPreventExitStatus=1 6
+                                SIGABRT</literal>", ensures that exit
+                                codes 1 and 6 and the termination signal
+                                SIGABRT will not result in automatic
+                                service restarting.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PermissionsStartOnly=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If true, the permission
+                                related execution options as
+                                configured with
+                                <varname>User=</varname> and similar
+                                options (see
+                                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for more information) are only applied
+                                to the process started with
+                                <varname>ExecStart=</varname>, and not
+                                to the various other
+                                <varname>ExecStartPre=</varname>,
+                                <varname>ExecStartPost=</varname>,
+                                <varname>ExecReload=</varname>,
+                                <varname>ExecStop=</varname>,
+                                <varname>ExecStopPost=</varname>
+                                commands. If false, the setting is
+                                applied to all configured commands the
+                                same way. Defaults to
+                                false.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RootDirectoryStartOnly=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If true, the root directory
+                                as configured with the
+                                <varname>RootDirectory=</varname>
+                                option (see
+                                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for more information) is only applied
+                                to the process started with
+                                <varname>ExecStart=</varname>, and not
+                                to the various other
+                                <varname>ExecStartPre=</varname>,
+                                <varname>ExecStartPost=</varname>,
+                                <varname>ExecReload=</varname>,
+                                <varname>ExecStop=</varname>,
+                                <varname>ExecStopPost=</varname>
+                                commands. If false, the setting is
+                                applied to all configured commands the
+                                same way. Defaults to
+                                false.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>NonBlocking=</varname></term>
+                                <listitem><para>Set O_NONBLOCK flag
+                                for all file descriptors passed via
+                                socket-based activation. If true, all
+                                file descriptors >= 3 (i.e. all except
+                                STDIN/STDOUT/STDERR) will have
+                                the O_NONBLOCK flag set and hence are in
+                                non-blocking mode. This option is only
+                                useful in conjunction with a socket
+                                unit, as described in
+                                <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Defaults
+                                to false.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>NotifyAccess=</varname></term>
+                                <listitem><para>Controls access to the
+                                service status notification socket, as
+                                accessible via the
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                call. Takes one of
+                                <option>none</option> (the default),
+                                <option>main</option> or
+                                <option>all</option>. If
+                                <option>none</option> no daemon status
+                                updates are accepted from the service
+                                processes, all status update messages
+                                are ignored. If <option>main</option>
+                                only service updates sent from the
+                                main process of the service are
+                                accepted. If <option>all</option> all
+                                services updates from all members of
+                                the service's control group are
+                                accepted. This option should be set to
+                                open access to the notification socket
+                                when using
+                                <varname>Type=notify</varname> or
+                                <varname>WatchdogUsec=</varname> (see
+                                above). If those options are used but
+                                <varname>NotifyAccess=</varname> not
+                                configured it will be implicitly set
+                                to
+                                <option>main</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Sockets=</varname></term>
+                                <listitem><para>Specifies the name of
+                                the socket units this service shall
+                                inherit the sockets from when the
+                                service is started. Normally it
+                                should not be necessary to use this
+                                setting as all sockets whose unit
+                                shares the same name as the service
+                                (ignoring the different suffix of course)
+                                are passed to the spawned
+                                process.</para>
+
+                                <para>Note that the same socket may be
+                                passed to multiple processes at the
+                                same time. Also note that a different
+                                service may be activated on incoming
+                                traffic than inherits the sockets. Or
+                                in other words: The
+                                <varname>Service=</varname> setting of
+                                <filename>.socket</filename> units
+                                doesn't have to match the inverse of the
+                                <varname>Sockets=</varname> setting of
+                                the <filename>.service</filename> it
+                                refers to.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>StartLimitInterval=</varname></term>
+                                <term><varname>StartLimitBurst=</varname></term>
+
+                                <listitem><para>Configure service
+                                start rate limiting. By default
+                                services which are started more often
+                                than 5 times within 10s are not
+                                permitted to start any more times
+                                until the 10s interval ends. With
+                                these two options this rate limiting
+                                may be modified. Use
+                                <varname>StartLimitInterval=</varname>
+                                to configure the checking interval
+                                (defaults to 10s, set to 0 to disable
+                                any kind of rate limiting). Use
+                                <varname>StartLimitBurst=</varname> to
+                                configure how many starts per interval
+                                are allowed (defaults to 5). These
+                                configuration options are particularly
+                                useful in conjunction with
+                                <varname>Restart=</varname>, however
+                                apply to all kinds of starts
+                                (including manual), not just those
+                                triggered by the
+                                <varname>Restart=</varname> logic.
+                                Note that units which are configured
+                                for <varname>Restart=</varname> and
+                                which reach the start limit are not
+                                attempted to be restarted anymore,
+                                however they may still be restarted
+                                manually at a later point from which
+                                point on the restart logic is again
+                                activated. Note that
+                                <command>systemctl
+                                reset-failed</command> will cause the
+                                restart rate counter for a service to
+                                be flushed, which is useful if the
+                                administrator wants to manually start
+                                a service and the start limit
+                                interferes with
+                                that.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>StartLimitAction=</varname></term>
+
+                                <listitem><para>Configure the action
+                                to take if the rate limit configured
+                                with
+                                <varname>StartLimitInterval=</varname>
+                                and
+                                <varname>StartLimitBurst=</varname> is
+                                hit. Takes one of
+                                <option>none</option>,
+                                <option>reboot</option>,
+                                <option>reboot-force</option> or
+                                <option>reboot-immediate</option>. If
+                                <option>none</option> is set,
+                                hitting the rate limit will trigger no
+                                action besides that the start will not
+                                be
+                                permitted. <option>reboot</option>
+                                causes a reboot following the normal
+                                shutdown procedure (i.e. equivalent to
+                                <command>systemctl reboot</command>),
+                                <option>reboot-force</option> causes
+                                an forced reboot which will terminate
+                                all processes forcibly but should
+                                cause no dirty file systems on reboot
+                                (i.e. equivalent to <command>systemctl
+                                reboot -f</command>) and
+                                <option>reboot-immediate</option>
+                                causes immediate execution of the
+                                <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                system call, which might result in
+                                data loss.  Defaults to
+                                <option>none</option>.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+                <para>Check
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more settings.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Compatibility Options</title>
+
+                <para>The following options are also available in the
+                <literal>[Service]</literal> section, but exist purely
+                for compatibility reasons and should not be used in
+                newly written service files.</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>SysVStartPriority=</varname></term>
+                                <listitem><para>Set the SysV start
+                                priority to use to order this service
+                                in relation to SysV services lacking
+                                LSB headers. This option is only
+                                necessary to fix ordering in relation
+                                to legacy SysV services, that have no
+                                ordering information encoded in the
+                                script headers. As such it should only
+                                be used as temporary compatibility
+                                option, and not be used in new unit
+                                files. Almost always it is a better
+                                choice to add explicit ordering
+                                directives via
+                                <varname>After=</varname> or
+                                <varname>Before=</varname>,
+                                instead. For more details see
+                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. If
+                                used, pass an integer value in the
+                                range 0-99.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>FsckPassNo=</varname></term>
+                                <listitem><para>Set the fsck passno
+                                priority to use to order this service
+                                in relation to other file system
+                                checking services. This option is only
+                                necessary to fix ordering in relation
+                                to fsck jobs automatically created for
+                                all <filename>/etc/fstab</filename>
+                                entries with a value in the fs_passno
+                                column > 0. As such it should only be
+                                used as option for fsck
+                                services. Almost always it is a better
+                                choice to add explicit ordering
+                                directives via
+                                <varname>After=</varname> or
+                                <varname>Before=</varname>,
+                                instead. For more details see
+                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. If
+                                used, pass an integer value in the
+                                same range as
+                                <filename>/etc/fstab</filename>'s
+                                fs_passno column. See
+                                <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.snapshot.xml b/man/systemd.snapshot.xml
new file mode 100644 (file)
index 0000000..b432682
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.snapshot">
+        <refentryinfo>
+                <title>systemd.snapshot</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.snapshot</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.snapshot</refname>
+                <refpurpose>Snapshot unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.snapshot</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>Snapshot units are not configured via unit
+                configuration files. Nonetheless they are named
+                similar to filenames. A unit name whose name ends in
+                <filename>.snapshot</filename> refers to a dynamic
+                snapshot of the systemd runtime state.</para>
+
+                <para>Snapshots are not configured on disk but created
+                dynamically via <command>systemctl snapshot</command>
+                (see
+                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                for details) or an equivalent command. When created,
+                they will automatically get dependencies on the
+                currently activated units. They act as saved
+                runtime state of the systemd manager. Later on, the
+                user may choose to return to the saved state via
+                <command>systemctl isolate</command>. They are
+                useful to roll back to a defined state after
+                temporarily starting/stopping services or
+                similar.</para>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
new file mode 100644 (file)
index 0000000..4b1fcc8
--- /dev/null
@@ -0,0 +1,685 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.socket">
+        <refentryinfo>
+                <title>systemd.socket</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.socket</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.socket</refname>
+                <refpurpose>Socket unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.socket</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.socket</filename> encodes information about
+                an IPC or network socket or a file system FIFO
+                controlled and supervised by systemd, for socket-based
+                activation.</para>
+
+                <para>This man page lists the configuration options
+                specific to this unit type. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic [Unit] and [Install] sections. The
+                socket specific configuration options are configured
+                in the [Socket] section.</para>
+
+                <para>Additional options are listed in
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                which define the execution environment the
+                <option>ExecStartPre=</option>,
+                <option>ExecStartPost=</option>,
+                <option>ExecStopPre=</option> and
+                <option>ExecStoptPost=</option> commands are executed
+                in, and in
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                which define the way the processes are
+                terminated.</para>
+
+                <para>For each socket file a matching service file
+                (see
+                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details) must exist, describing the service to
+                start on incoming traffic on the socket. Depending on
+                the setting of <option>Accept=</option> (see below),
+                this must either be named like the socket unit, but
+                with the suffix replaced; or it must be a template
+                file named the same way. Example: a socket file
+                <filename>foo.socket</filename> needs a matching
+                service <filename>foo.service</filename> if
+                <option>Accept=false</option> is set. If
+                <option>Accept=true</option> is set a service template
+                file <filename>foo@.service</filename> must exist from
+                which services are instantiated for each incoming
+                connection.</para>
+
+                <para>Unless <varname>DefaultDependencies=</varname>
+                is set to <option>false</option>, socket units will
+                implicitly have dependencies of type
+                <varname>Requires=</varname> and
+                <varname>After=</varname> on
+                <filename>sysinit.target</filename> as well as
+                dependencies of type <varname>Conflicts=</varname> and
+                <varname>Before=</varname> on
+                <filename>shutdown.target</filename>. These ensure
+                that socket units pull in basic system
+                initialization, and are terminated cleanly prior to
+                system shutdown. Only sockets involved with early
+                boot or late system shutdown should disable this
+                option.</para>
+
+                <para>Socket units may be used to implement on-demand
+                starting of services, as well as parallelized starting
+                of services.</para>
+
+                <para>Note that the daemon software configured for
+                socket activation with socket units needs to be able
+                to accept sockets from systemd, either via systemd's
+                native socket passing interface (see
+                <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                for details) or via the traditional
+                <citerefentry><refentrytitle>inetd</refentrytitle><manvolnum>8</manvolnum></citerefentry>-style
+                socket passing (i.e. sockets passed in via STDIN and
+                STDOUT, using <varname>StandardInput=socket</varname>
+                in the service file).</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>Socket files must include a [Socket] section,
+                which carries information about the socket or FIFO it
+                supervises. A number of options that may be used in
+                this section are shared with other unit types. These
+                options are documented in
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
+                options specific to the [Socket] section of socket
+                units are the following:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>ListenStream=</varname></term>
+                                <term><varname>ListenDatagram=</varname></term>
+                                <term><varname>ListenSequentialPacket=</varname></term>
+                                <listitem><para>Specifies an address
+                                to listen on for a stream
+                                (SOCK_STREAM), datagram (SOCK_DGRAM),
+                                or sequential packet
+                                (SOCK_SEQPACKET) socket, respectively. The address
+                                can be written in various formats:</para>
+
+                                <para>If the address starts with a
+                                slash (/), it is read as file system
+                                socket in the AF_UNIX socket
+                                family.</para>
+
+                                <para>If the address starts with an
+                                at symbol (@) it is read as abstract
+                                namespace socket in the AF_UNIX
+                                family. The @ is replaced with a NUL
+                                character before binding. For details
+                                see
+                                <citerefentry><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+
+                                <para>If the address string is a
+                                single number it is read as port
+                                number to listen on via
+                                IPv6. Depending on the value of
+                                <varname>BindIPv6Only=</varname> (see below) this
+                                might result in the service being
+                                available via both IPv6 and IPv4 (default) or
+                                just via IPv6.
+                                </para>
+
+                                <para>If the address string is a
+                                string in the format v.w.x.y:z it is
+                                read as IPv4 specifier for listening
+                                on an address v.w.x.y on a port
+                                z.</para>
+
+                                <para>If the address string is a
+                                string in the format [x]:y it is read
+                                as IPv6 address x on a port y. Note
+                                that this might make the service
+                                available via IPv4, too, depending on
+                                the <varname>BindIPv6Only=</varname>
+                                setting (see below).
+                                </para>
+
+                                <para>Note that SOCK_SEQPACKET
+                                (i.e. <varname>ListenSequentialPacket=</varname>)
+                                is only available for AF_UNIX
+                                sockets. SOCK_STREAM
+                                (i.e. <varname>ListenStream=</varname>)
+                                when used for IP sockets refers to TCP
+                                sockets, SOCK_DGRAM
+                                (i.e. <varname>ListenDatagram=</varname>)
+                                to UDP.</para>
+
+                                <para>These options may be specified
+                                more than once in which case incoming
+                                traffic on any of the sockets will trigger
+                                service activation, and all listed
+                                sockets will be passed to the service,
+                                regardless whether there is incoming
+                                traffic on them or not.</para>
+
+                                <para>If an IP address is used here, it
+                                is often desirable to listen on it
+                                before the interface it is configured
+                                on is up and running, and even
+                                regardless whether it will be up and
+                                running ever at all. To deal with this it is
+                                recommended to set the
+                                <varname>FreeBind=</varname> option
+                                described below.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ListenFIFO=</varname></term>
+                                <listitem><para>Specifies a file
+                                system FIFO to listen on. This expects
+                                an absolute file system path as
+                                argument. Behavior otherwise is very
+                                similar to the
+                                <varname>ListenDatagram=</varname>
+                                directive above.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ListenSpecial=</varname></term>
+                                <listitem><para>Specifies a special
+                                file in the file system to listen
+                                on. This expects an absolute file
+                                system path as argument. Behavior
+                                otherwise is very similar to the
+                                <varname>ListenFIFO=</varname>
+                                directive above. Use this to open
+                                character device nodes as well as
+                                special files in
+                                <filename>/proc</filename> and
+                                <filename>/sys</filename>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ListenNetlink=</varname></term>
+                                <listitem><para>Specifies a Netlink
+                                family to create a socket for to
+                                listen on. This expects a short string
+                                referring to the AF_NETLINK family
+                                name (such as <varname>audit</varname>
+                                or <varname>kobject-uevent</varname>)
+                                as argument, optionally suffixed by a
+                                whitespace followed by a multicast
+                                group integer. Behavior otherwise is
+                                very similar to the
+                                <varname>ListenDatagram=</varname>
+                                directive above.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ListenMessageQueue=</varname></term>
+                                <listitem><para>Specifies a POSIX
+                                message queue name to listen on. This
+                                expects a valid message queue name
+                                (i.e. beginning with /). Behavior
+                                otherwise is very similar to the
+                                <varname>ListenFIFO=</varname>
+                                directive above. On Linux message
+                                queue descriptors are actually file
+                                descriptors and can be inherited
+                                between processes.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>BindIPv6Only=</varname></term>
+                                <listitem><para>Takes a one of
+                                <option>default</option>,
+                                <option>both</option> or
+                                <option>ipv6-only</option>. Controls
+                                the IPV6_V6ONLY socket option (see
+                                <citerefentry><refentrytitle>ipv6</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details). If
+                                <option>both</option>, IPv6 sockets
+                                bound will be accessible via both IPv4
+                                and IPv6. If
+                                <option>ipv6-only</option>, they will
+                                be accessible via IPv6 only. If
+                                <option>default</option> (which is the
+                                default, surprise!) the system wide
+                                default setting is used, as controlled
+                                by
+                                <filename>/proc/sys/net/ipv6/bindv6only</filename>,
+                                which in turn defaults to the
+                                equivalent of
+                                <option>both</option>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Backlog=</varname></term>
+                                <listitem><para>Takes an unsigned
+                                integer argument. Specifies the number
+                                of connections to queue that have not
+                                been accepted yet. This setting
+                                matters only for stream and sequential
+                                packet sockets. See
+                                <citerefentry><refentrytitle>listen</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details. Defaults to SOMAXCONN
+                                (128).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>BindToDevice=</varname></term>
+                                <listitem><para>Specifies a network
+                                interface name to bind this socket
+                                to. If set traffic will only be
+                                accepted from the specified network
+                                interfaces. This controls the
+                                SO_BINDTODEVICE socket option (see
+                                <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details). If this option is used,
+                                an automatic dependency from this
+                                socket unit on the network interface
+                                device unit
+                                (<citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                is created.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>DirectoryMode=</varname></term>
+                                <listitem><para>If listening on a file
+                                system socket or FIFO, the parent
+                                directories are automatically created
+                                if needed. This option specifies the
+                                file system access mode used when
+                                creating these directories. Takes an
+                                access mode in octal
+                                notation. Defaults to
+                                0755.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SocketMode=</varname></term>
+                                <listitem><para>If listening on a file
+                                system socket or FIFO, this option
+                                specifies the file system access mode
+                                used when creating the file
+                                node. Takes an access mode in octal
+                                notation. Defaults to
+                                0666.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Accept=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If true, a service instance
+                                is spawned for each incoming
+                                connection and only the connection
+                                socket is passed to it. If false, all
+                                listening sockets themselves are
+                                passed to the started service unit,
+                                and only one service unit is spawned
+                                for all connections (also see
+                                above). This value is ignored for
+                                datagram sockets and FIFOs where
+                                a single service unit unconditionally
+                                handles all incoming traffic. Defaults
+                                to <option>false</option>. For
+                                performance reasons, it is recommended
+                                to write new daemons only in a way
+                                that is suitable for
+                                <option>Accept=false</option>. This
+                                option is mostly useful to allow
+                                daemons designed for usage with
+                                <citerefentry><refentrytitle>inetd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                                to work unmodified with systemd socket
+                                activation.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>MaxConnections=</varname></term>
+                                <listitem><para>The maximum number of
+                                connections to simultaneously run
+                                services instances for, when
+                                <option>Accept=true</option> is
+                                set. If more concurrent connections
+                                are coming in, they will be refused
+                                until at least one existing connection
+                                is terminated. This setting has no
+                                effect for sockets configured with
+                                <option>Accept=false</option> or datagram
+                                sockets. Defaults to
+                                64.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>KeepAlive=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If true, the TCP/IP stack
+                                will send a keep alive message after
+                                2h (depending on the configuration of
+                                <filename>/proc/sys/net/ipv4/tcp_keepalive_time</filename>)
+                                for all TCP streams accepted on this
+                                socket. This controls the SO_KEEPALIVE
+                                socket option (see
+                                <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                and the <ulink
+                                url="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP
+                                Keepalive HOWTO</ulink> for details.)
+                                Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Priority=</varname></term>
+                                <listitem><para>Takes an integer
+                                argument controlling the priority for
+                                all traffic sent from this
+                                socket. This controls the SO_PRIORITY
+                                socket option (see
+                                <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details.).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ReceiveBuffer=</varname></term>
+                                <term><varname>SendBuffer=</varname></term>
+                                <listitem><para>Takes an integer
+                                argument controlling the receive
+                                or send buffer sizes of this
+                                socket, respectively. This controls the SO_RCVBUF
+                                and SO_SNDBUF socket options (see
+                                <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details.).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>IPTOS=</varname></term>
+                                <listitem><para>Takes an integer
+                                argument controlling the IP
+                                Type-Of-Service field for packets
+                                generated from this socket. This
+                                controls the IP_TOS socket option (see
+                                <citerefentry><refentrytitle>ip</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details.). Either a numeric string
+                                or one of <option>low-delay</option>,
+                                <option>throughput</option>,
+                                <option>reliability</option> or
+                                <option>low-cost</option> may be
+                                specified.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>IPTTL=</varname></term>
+                                <listitem><para>Takes an integer
+                                argument controlling the IPv4
+                                Time-To-Live/IPv6 Hop-Count field for
+                                packets generated from this
+                                socket. This sets the
+                                IP_TTL/IPV6_UNICAST_HOPS socket
+                                options (see
+                                <citerefentry><refentrytitle>ip</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                and
+                                <citerefentry><refentrytitle>ipv6</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details.)</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Mark=</varname></term>
+                                <listitem><para>Takes an integer
+                                value. Controls the firewall mark of
+                                packets generated by this socket. This
+                                can be used in the firewall logic to
+                                filter packets from this socket. This
+                                sets the SO_MARK socket option. See
+                                <citerefentry><refentrytitle>iptables</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SmackLabel=</varname></term>
+                                <term><varname>SmackLabelIPIn=</varname></term>
+                                <term><varname>SmackLabelIPOut=</varname></term>
+                                <listitem><para>Takes a string
+                                value. Controls the extended
+                                attributes
+                                <literal>security.SMACK64</literal>,
+                                <literal>security.SMACK64IPIN</literal>
+                                and
+                                <literal>security.SMACK64IPOUT</literal>,
+                                respectively, i.e. the security label
+                                of the FIFO, or the security label for
+                                the incoming or outgoing connections
+                                of the socket, respectively.  See
+                                <ulink
+                                url="https://www.kernel.org/doc/Documentation/security/Smack.txt">Smack.txt</ulink>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PipeSize=</varname></term>
+                                <listitem><para>Takes an integer
+                                value. Controls the pipe buffer size
+                                of FIFOs configured in this socket
+                                unit.  See
+                                <citerefentry><refentrytitle>fcntl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>MessageQueueMaxMessages=</varname>,
+                                <varname>MessageQueueMessageSize=</varname></term>
+                                <listitem><para>These two settings
+                                take integer values and control the
+                                mq_maxmsg field or the mq_msgsize field, respectively, when
+                                creating the message queue. Note that
+                                either none or both of these variables
+                                need to be set. See
+                                <citerefentry><refentrytitle>mq_setattr</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>FreeBind=</varname></term>
+                                <listitem><para>Takes a boolean
+                                value. Controls whether the socket can
+                                be bound to non-local IP
+                                addresses. This is useful to configure
+                                sockets listening on specific IP
+                                addresses before those IP addresses
+                                are successfully configured on a
+                                network interface. This sets the
+                                IP_FREEBIND socket option. For
+                                robustness reasons it is recommended
+                                to use this option whenever you bind a
+                                socket to a specific IP
+                                address. Defaults to <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Transparent=</varname></term>
+                                <listitem><para>Takes a boolean
+                                value. Controls the IP_TRANSPARENT
+                                socket option. Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Broadcast=</varname></term>
+                                <listitem><para>Takes a boolean
+                                value. This controls the SO_BROADCAST
+                                socket option, which allows broadcast
+                                datagrams to be sent from this
+                                socket. Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PassCredentials=</varname></term>
+                                <listitem><para>Takes a boolean
+                                value. This controls the SO_PASSCRED
+                                socket option, which allows AF_UNIX sockets to
+                                receive the credentials of the sending
+                                process in an ancillary message.
+                                Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PassSecurity=</varname></term>
+                                <listitem><para>Takes a boolean
+                                value. This controls the SO_PASSSEC
+                                socket option, which allows AF_UNIX
+                                sockets to receive the security
+                                context of the sending process in an
+                                ancillary message.  Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TCPCongestion=</varname></term>
+                                <listitem><para>Takes a string
+                                value. Controls the TCP congestion
+                                algorithm used by this socket. Should
+                                be one of "westwood", "veno", "cubic",
+                                "lp" or any other available algorithm
+                                supported by the IP stack. This
+                                setting applies only to stream
+                                sockets.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ExecStartPre=</varname></term>
+                                <term><varname>ExecStartPost=</varname></term>
+                                <listitem><para>Takes one or more
+                                command lines, which are executed
+                                before or after the listening
+                                sockets/FIFOs are created and
+                                bound, respectively. The first token of the command
+                                line must be an absolute file name,
+                                then followed by arguments for the
+                                process. Multiple command lines may be
+                                specified following the same scheme as
+                                used for
+                                <varname>ExecStartPre=</varname> of
+                                service unit files.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ExecStopPre=</varname></term>
+                                <term><varname>ExecStopPost=</varname></term>
+                                <listitem><para>Additional commands
+                                that are executed before or after
+                                the listening sockets/FIFOs are closed
+                                and removed, respectively. Multiple command lines
+                                may be specified following the same
+                                scheme as used for
+                                <varname>ExecStartPre=</varname> of
+                                service unit files.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimeoutSec=</varname></term>
+                                <listitem><para>Configures the time to
+                                wait for the commands specified in
+                                <varname>ExecStartPre=</varname>,
+                                <varname>ExecStartPost=</varname>,
+                                <varname>ExecStopPre=</varname> and
+                                <varname>ExecStopPost=</varname> to
+                                finish. If a command does not exit
+                                within the configured time, the socket
+                                will be considered failed and be shut
+                                down again. All commands still running,
+                                will be terminated forcibly via
+                                SIGTERM, and after another delay of
+                                this time with SIGKILL. (See
+                                <option>KillMode=</option> in <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>.)
+                                Takes a unit-less value in seconds, or
+                                a time span value such as "5min
+                                20s". Pass 0 to disable the timeout
+                                logic. Defaults to
+                                90s.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Service=</varname></term>
+                                <listitem><para>Specifies the service
+                                unit name to activate on incoming
+                                traffic. This defaults to the service
+                                that bears the same name as the socket
+                                (ignoring the different suffixes). In
+                                most cases it should not be necessary
+                                to use this option.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+                <para>Check
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more settings.</para>
+
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
new file mode 100644 (file)
index 0000000..9ea288e
--- /dev/null
@@ -0,0 +1,817 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.special">
+
+        <refentryinfo>
+                <title>systemd.special</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.special</refentrytitle>
+                <manvolnum>7</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.special</refname>
+                <refpurpose>Special systemd units</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>basic.target</filename>,
+                <filename>bluetooth.target</filename>,
+                <filename>ctrl-alt-del.target</filename>,
+                <filename>cryptsetup.target</filename>,
+                <filename>dbus.service</filename>,
+                <filename>dbus.socket</filename>,
+                <filename>default.target</filename>,
+                <filename>display-manager.service</filename>,
+                <filename>emergency.target</filename>,
+                <filename>exit.target</filename>,
+                <filename>final.target</filename>,
+                <filename>getty.target</filename>,
+                <filename>graphical.target</filename>,
+                <filename>halt.target</filename>,
+                <filename>hibernate.target</filename>,
+                <filename>hybrid-sleep.target</filename>,
+                <filename>kbrequest.target</filename>,
+                <filename>kexec.target</filename>,
+                <filename>local-fs.target</filename>,
+                <filename>local-fs-pre.target</filename>,
+                <filename>mail-transfer-agent.target</filename>,
+                <filename>multi-user.target</filename>,
+                <filename>network.target</filename>,
+                <filename>nss-lookup.target</filename>,
+                <filename>nss-user-lookup.target</filename>,
+                <filename>poweroff.target</filename>,
+                <filename>printer.target</filename>,
+                <filename>reboot.target</filename>,
+                <filename>remote-fs.target</filename>,
+                <filename>remote-fs-pre.target</filename>,
+                <filename>rescue.target</filename>,
+                <filename>rpcbind.target</filename>,
+                <filename>runlevel2.target</filename>,
+                <filename>runlevel3.target</filename>,
+                <filename>runlevel4.target</filename>,
+                <filename>runlevel5.target</filename>,
+                <filename>shutdown.target</filename>,
+                <filename>sigpwr.target</filename>,
+                <filename>sleep.target</filename>,
+                <filename>smartcard.target</filename>,
+                <filename>sockets.target</filename>,
+                <filename>sound.target</filename>,
+                <filename>suspend.target</filename>,
+                <filename>swap.target</filename>,
+                <filename>sysinit.target</filename>,
+                <filename>syslog.socket</filename>,
+                <filename>syslog.target</filename>,
+                <filename>system-update.target</filename>,
+                <filename>time-sync.target</filename>,
+                <filename>umount.target</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A few units are treated specially by
+                systemd. They have special internal semantics and
+                cannot be renamed.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Special System Units</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>basic.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        covering early boot-up.</para>
+                                        <para>systemd automatically
+                                        adds dependencies of the types
+                                        Requires and After for this
+                                        target unit to all SysV
+                                        service units configured for
+                                        runlevel 1 to 5.</para>
+                                        <para>Usually this should pull-in
+                                        all sockets, mount points,
+                                        swap devices and other basic
+                                        initialization necessary for
+                                        the general purpose
+                                        daemons. Most normal daemons
+                                        should have dependencies of
+                                        type After and Requires on
+                                        this unit.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>bluetooth.target</filename></term>
+                                <listitem>
+                                        <para>This target is started
+                                        automatically as soon as a
+                                        bluetooth controller is
+                                        plugged in or becomes
+                                        available at boot.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>ctrl-alt-del.target</filename></term>
+                                <listitem>
+                                        <para>systemd starts this
+                                        target whenever
+                                        Control+Alt+Del is pressed on
+                                        the console. Usually this
+                                        should be aliased (symlinked)
+                                        to
+                                        <filename>reboot.target</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>cryptsetup.target</filename></term>
+                                <listitem>
+                                        <para>A target that pulls in
+                                        setup services for all
+                                        encrypted block
+                                        devices.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>dbus.service</filename></term>
+                                <listitem>
+                                        <para>A special unit for the
+                                        D-Bus system bus. As soon as
+                                        this service is fully started
+                                        up systemd will connect to it
+                                        and register its
+                                        service.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>dbus.socket</filename></term>
+                                <listitem>
+                                        <para>A special unit for the
+                                        D-Bus system bus socket. All
+                                        units with
+                                        <literal>Type=dbus</literal>
+                                        automatically gain a
+                                        dependency on this
+                                        unit.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>default.target</filename></term>
+                                <listitem>
+                                        <para>The default unit systemd
+                                        starts at bootup. Usually this
+                                        should be aliased (symlinked)
+                                        to
+                                        <filename>multi-user.target</filename>
+                                        or
+                                        <filename>graphical.target</filename>.</para>
+                                        <para>The default unit systemd
+                                        starts at bootup can be
+                                        overridden with the
+                                        <varname>systemd.unit=</varname>
+                                        kernel command line option.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>display-manager.service</filename></term>
+                                <listitem>
+                                        <para>The display manager
+                                        service. Usually this should
+                                        be aliased (symlinked) to
+                                        <filename>gdm.service</filename>
+                                        or a similar display manager
+                                        service.</para>
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After for this target unit to
+                                        all SysV init script service
+                                        units with a LSB header
+                                        referring to the
+                                        <literal>$x-display-manager</literal>
+                                        facility.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>emergency.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        that starts an emergency
+                                        shell on the main
+                                        console. This unit is supposed
+                                        to be used with the kernel
+                                        command line option
+                                        <varname>systemd.unit=</varname>
+                                        and has otherwise little use.
+                                        </para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>final.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        that is used during the
+                                        shutdown logic and may be used
+                                        to pull in late services after
+                                        all normal services are
+                                        already terminated and all
+                                        mounts unmounted.
+                                        </para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>getty.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        that pulls in all local TTY
+                                        <filename>getty</filename> instances.
+                                        </para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>graphical.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for setting up a graphical
+                                        login screen. This pulls in
+                                        <filename>multi-user.target</filename>.</para>
+
+                                        <para>Units that are needed
+                                        for graphical login shall add
+                                        Wants dependencies for their
+                                        unit to this unit (or
+                                        <filename>multi-user.target</filename>)
+                                        during installation.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>hibernate.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for hibernating the
+                                        system. This pulls in
+                                        <filename>sleep.target</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>hybrid-sleep.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for hibernating and suspending the
+                                        system at the same time. This pulls in
+                                        <filename>sleep.target</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>halt.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for shutting down and halting the system.</para>
+
+                                        <para>Applications wanting to
+                                        halt the system should start
+                                        this unit.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>kbrequest.target</filename></term>
+                                <listitem>
+                                        <para>systemd starts this
+                                        target whenever Alt+ArrowUp is
+                                        pressed on the console. This
+                                        is a good candidate to be
+                                        aliased (symlinked) to
+                                        <filename>rescue.target</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>kexec.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for shutting down and rebooting the system via kexec.</para>
+
+                                        <para>Applications wanting to
+                                        reboot the system with kexec should start
+                                        this unit.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>local-fs.target</filename></term>
+                                <listitem>
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After to all mount units that
+                                        refer to local mount points
+                                        for this target unit. In
+                                        addition, systemd adds
+                                        dependencies of type Wants to
+                                        this target unit for those
+                                        mounts listed in
+                                        <filename>/etc/fstab</filename>
+                                        that have the
+                                        <option>auto</option> and
+                                        <option>comment=systemd.mount</option>
+                                        mount options set.</para>
+
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After for this target unit to
+                                        all SysV init script service
+                                        units with an LSB header
+                                        referring to the
+                                        <literal>$local_fs</literal>
+                                        facility.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>local-fs-pre.target</filename></term>
+                                <listitem>
+                                        <para>This target unit is
+                                        automatically ordered before
+                                        all local mount points marked
+                                        with <option>auto</option>
+                                        (see above). It can be used to
+                                        execute certain units before
+                                        all local mounts.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>mail-transfer-agent.target</filename></term>
+                                <listitem>
+                                        <para>The mail transfer agent
+                                        (MTA) service. Usually this
+                                        should pull-in all units
+                                        necessary for
+                                        sending/receiving mails on the
+                                        local host.</para>
+
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After for this target unit to
+                                        all SysV init script service
+                                        units with an LSB header
+                                        referring to the
+                                        <literal>$mail-transfer-agent</literal>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>multi-user.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for setting up a multi-user
+                                        system (non-graphical). This
+                                        is pulled in by
+                                        <filename>graphical.target</filename>.</para>
+
+                                        <para>Units that are needed
+                                        for a multi-user system shall
+                                        add Wants dependencies to
+                                        this unit for their unit during
+                                        installation.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>network.target</filename></term>
+                                <listitem>
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After for this target unit to
+                                        all SysV init script service
+                                        units with an LSB header
+                                        referring to the
+                                        <literal>$network</literal>
+                                        facility.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>nss-lookup.target</filename></term>
+                                <listitem>
+                                        <para>A target that should be
+                                        used as synchronization point
+                                        for all host/network name
+                                        service lookups. Note that
+                                        this is independent of
+                                        user/group name lookups for
+                                        which
+                                        <filename>nss-user-lookup.target</filename>
+                                        should be used. systemd
+                                        automatically adds
+                                        dependencies of type After for
+                                        this target unit to all SysV
+                                        init script service units with
+                                        an LSB header referring to the
+                                        <literal>$named</literal>
+                                        facility.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>nss-user-lookup.target</filename></term>
+                                <listitem>
+                                        <para>A target that should be
+                                        used as synchronization point
+                                        for all user/group name
+                                        service lookups. Note that
+                                        this is independent of
+                                        host/network name lookups for
+                                        which
+                                        <filename>nss-lookup.target</filename>
+                                        should be used. </para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>poweroff.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for shutting down and powering off the system.</para>
+
+                                        <para>Applications wanting to
+                                        power off the system should start
+                                        this unit.</para>
+
+                                        <para><filename>runlevel0.target</filename>
+                                        is an alias for this target
+                                        unit, for compatibility with SysV.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>printer.target</filename></term>
+                                <listitem>
+                                        <para>This target is started
+                                        automatically as soon as a
+                                        printer is plugged in or
+                                        becomes available at
+                                        boot.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>reboot.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for shutting down and rebooting the system.</para>
+
+                                        <para>Applications wanting to
+                                        reboot the system should start
+                                        this unit.</para>
+
+                                        <para><filename>runlevel6.target</filename>
+                                        is an alias for this target
+                                        unit, for compatibility with SysV.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>remote-fs.target</filename></term>
+                                <listitem>
+                                        <para>Similar to
+                                        <filename>local-fs.target</filename>,
+                                        but for remote mount
+                                        points.</para>
+
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After for this target unit to
+                                        all SysV init script service
+                                        units with an LSB header
+                                        referring to the
+                                        <literal>$remote_fs</literal>
+                                        facility.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>remote-fs-pre.target</filename></term>
+                                <listitem>
+                                        <para>This target unit is
+                                        automatically ordered before
+                                        all remote mount points marked
+                                        with <option>auto</option>
+                                        (see above). It can be used to
+                                        execute certain units before
+                                        all remote mounts.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>rescue.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for setting up the base system
+                                        and a rescue shell.</para>
+
+                                        <para><filename>runlevel1.target</filename>
+                                        is an alias for this target
+                                        unit, for compatibility with SysV.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>rpcbind.target</filename></term>
+                                <listitem>
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After for this target unit to
+                                        all SysV init script service
+                                        units with an LSB header
+                                        referring to the
+                                        <literal>$portmap</literal>
+                                        facility.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>runlevel2.target</filename></term>
+                                <term><filename>runlevel3.target</filename></term>
+                                <term><filename>runlevel4.target</filename></term>
+                                <term><filename>runlevel5.target</filename></term>
+                                <listitem>
+                                        <para>These are targets that
+                                        are called whenever the SysV
+                                        compatibility code asks for
+                                        runlevel 2, 3, 4, 5,
+                                        respectively. It is a good
+                                        idea to make this an alias for
+                                        (i.e. symlink to)
+                                        <filename>multi-user.target</filename>
+                                        (for runlevel 2) or
+                                        <filename>graphical.target</filename>
+                                        (the others).</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>shutdown.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        that terminates the services
+                                        on system shutdown.</para>
+
+                                        <para>Services that shall be
+                                        terminated on system shutdown
+                                        shall add Conflicts
+                                        dependencies to this unit for
+                                        their service unit, which is
+                                        implicitly done when
+                                        <varname>DefaultDependencies=yes</varname>
+                                        is set (the default).</para>
+
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        Conflicts to this target unit
+                                        for all SysV init script
+                                        service units that shall be
+                                        terminated in SysV runlevels 0
+                                        or 6.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>sigpwr.target</filename></term>
+                                <listitem>
+                                        <para>A special target that is
+                                        started when systemd receives
+                                        the SIGPWR process signal,
+                                        which is normally sent by the
+                                        kernel or UPS daemons when
+                                        power fails.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>sleep.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        that is pulled in by
+                                        <filename>suspend.target</filename>,
+                                        <filename>hibernate.target</filename> and <filename>hybrid-sleep.target</filename>
+                                        and may be used to hook units
+                                        into the sleep state
+                                        logic.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>smartcard.target</filename></term>
+                                <listitem>
+                                        <para>This target is started
+                                        automatically as soon as a
+                                        smartcard controller is
+                                        plugged in or becomes
+                                        available at boot.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>sockets.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        that sets up all service
+                                        sockets.</para>
+
+                                        <para>Services that can be
+                                        socket-activated shall add
+                                        Wants dependencies to this
+                                        unit for their socket unit
+                                        during installation.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>sound.target</filename></term>
+                                <listitem>
+                                        <para>This target is started
+                                        automatically as soon as a
+                                        sound card is plugged in or
+                                        becomes available at
+                                        boot.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>suspend.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        for suspending the
+                                        system. This pulls in
+                                        <filename>sleep.target</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>swap.target</filename></term>
+                                <listitem>
+                                        <para>Similar to
+                                        <filename>local-fs.target</filename>, but for swap
+                                        partitions and swap
+                                        files.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>sysinit.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        covering early boot-up scripts.</para>
+                                        <para>systemd automatically
+                                        adds dependencies of the types
+                                        Wants and After for all
+                                        SysV service units configured
+                                        for runlevels that are not 0
+                                        to 6 to this target unit.
+                                        This covers the special
+                                        boot-up runlevels some
+                                        distributions have, such as S
+                                        or b.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>syslog.socket</filename></term>
+                                <listitem>
+                                        <para>The socket unit
+                                        syslog implementations should
+                                        listen on. All userspace log
+                                        messages will be made
+                                        available on this socket. For
+                                        more information about syslog
+                                        integration, please consult
+                                        the <ulink
+                                        url="http://www.freedesktop.org/wiki/Software/systemd/syslog">Syslog
+                                        Interface</ulink>
+                                        document.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>syslog.target</filename></term>
+                                <listitem>
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After for this target unit to
+                                        all SysV init script service
+                                        units with an LSB header
+                                        referring to the
+                                        <literal>$syslog</literal>
+                                        facility.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>system-update.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        that is used for off-line
+                                        system updates.
+                                        <citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                        will redirect the boot process
+                                        to this target if
+                                        <filename>/system-update</filename>
+                                        exists. For more information
+                                        see the <ulink
+                                        url="http://freedesktop.org/wiki/Software/systemd/SystemUpdates">System
+                                        Updates
+                                        Specification</ulink>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>time-sync.target</filename></term>
+                                <listitem>
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        After for this target unit to
+                                        all SysV init script service
+                                        units with an LSB header
+                                        referring to the
+                                        <literal>$time</literal>
+                                        facility.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>umount.target</filename></term>
+                                <listitem>
+                                        <para>A special target unit
+                                        that umounts all mount and
+                                        automount points on system
+                                        shutdown.</para>
+
+                                        <para>Mounts that shall be
+                                        unmounted on system shutdown
+                                        shall add Conflicts
+                                        dependencies to this unit for
+                                        their mount unit, which is
+                                        implicitly done when
+                                        <varname>DefaultDependencies=yes</varname>
+                                        is set (the default).</para>
+                                </listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Special User Units</title>
+
+                <para>When systemd runs as a user instance, the
+                following special units are available, which have
+                similar definitions as their system counterparts:
+                <filename>default.target</filename>,
+                <filename>shutdown.target</filename>,
+                <filename>sockets.target</filename></para>
+
+                <para>In addition the following special unit is
+                understood only when systemd runs as service instance:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>exit.target</filename></term>
+                                <listitem>
+                                        <para>A special service unit
+                                        for shutting down the
+                                        user service manager.</para>
+
+                                        <para>Applications wanting to
+                                        terminate the user service
+                                        manager should start this
+                                        unit. If systemd receives
+                                        SIGTERM or SIGINT when running
+                                        as user service daemon it will
+                                        start this unit.</para>
+
+                                        <para>Normally, this pulls in
+                                        <filename>shutdown.target</filename>
+                                        which in turn should be
+                                        conflicted by all units that
+                                        want to be shut down on
+                                        user service manager exit.</para>
+                                </listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
new file mode 100644 (file)
index 0000000..a932143
--- /dev/null
@@ -0,0 +1,213 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.swap">
+        <refentryinfo>
+                <title>systemd.swap</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.swap</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.swap</refname>
+                <refpurpose>Swap unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.swap</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.swap</filename> encodes information about a
+                swap device or file for memory paging controlled and
+                supervised by systemd.</para>
+
+                <para>This man page lists the configuration options
+                specific to this unit type. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic [Unit] and [Install] sections. The swap
+                specific configuration options are configured in the
+                [Swap] section.</para>
+
+                <para>Additional options are listed in
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                which define the execution environment the
+                <citerefentry><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                binary is executed in, and in
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                which define the way the processes are
+                terminated.</para>
+
+                <para>Swap units must be named after the devices
+                or files they control. Example: the swap device
+                <filename>/dev/sda5</filename> must be configured in a
+                unit file <filename>dev-sda5.swap</filename>. For
+                details about the escaping logic used to convert a
+                file system path to a unit name see
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+                <para>All swap units automatically get the appropriate
+                dependencies on the devices or on the mount points
+                of the files they are activated from.</para>
+
+                <para>Swap units with
+                <varname>DefaultDependencies=</varname> enabled
+                implicitly acquire a conflicting dependency to
+                <filename>umount.target</filename> so that they are
+                deactivated at shutdown.</para>
+        </refsect1>
+
+        <refsect1>
+                <title><filename>fstab</filename></title>
+
+                <para>Swap units may either be configured via unit
+                files, or via <filename>/etc/fstab</filename> (see
+                <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details). Swaps listed in
+                <filename>/etc/fstab</filename> will be converted into
+                native units dynamically at boot and when the
+                configuration of the system manager is
+                reloaded. See
+                <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                for details about the conversion.</para>
+
+                <para>If a swap device or file is configured in both
+                <filename>/etc/fstab</filename> and a unit file the
+                configuration in the latter takes precedence.</para>
+
+                <para>Unless the <option>noauto</option> option is set
+                for them all swap units configured in
+                <filename>/etc/fstab</filename> are also added as
+                requirements to <filename>swap.target</filename>, so
+                that they are waited for and activated during
+                boot.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>Swap files must include a [Swap] section, which
+                carries information about the swap device it
+                supervises. A number of options that may be used in
+                this section are shared with other unit types. These
+                options are documented in
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
+                options specific to the [Swap] section of swap units
+                are the following:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>What=</varname></term>
+                                <listitem><para>Takes an absolute path
+                                of a device node or file to use for
+                                paging. See
+                                <citerefentry><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                for details. If this refers to a
+                                device node, a dependency on the
+                                respective device unit is
+                                automatically created. (See
+                                <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for more information.) If this refers
+                                to a file, a dependency on the
+                                respective mount unit is automatically
+                                created. (See
+                                <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for more information.) This option is
+                                mandatory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Priority=</varname></term>
+
+                                <listitem><para>Swap priority to use
+                                when activating the swap device or
+                                file. This takes an integer. This
+                                setting is optional.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimeoutSec=</varname></term>
+                                <listitem><para>Configures the time to
+                                wait for the swapon command to
+                                finish. If a command does not exit
+                                within the configured time the swap
+                                will be considered failed and be shut
+                                down again. All commands still running
+                                will be terminated forcibly via
+                                SIGTERM, and after another delay of
+                                this time with SIGKILL. (See
+                                <option>KillMode=</option> in
+                                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>.)
+                                Takes a unit-less value in seconds, or
+                                a time span value such as "5min
+                                20s". Pass 0 to disable the timeout
+                                logic. Defaults to
+                                90s.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>Check
+                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                and
+                <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more settings.</para>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.target.xml b/man/systemd.target.xml
new file mode 100644 (file)
index 0000000..d1f4d22
--- /dev/null
@@ -0,0 +1,108 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.target">
+        <refentryinfo>
+                <title>systemd.target</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.target</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.target</refname>
+                <refpurpose>Target unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.target</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.target</filename> encodes information about
+                a target unit of systemd, which is used for grouping
+                units and as well-known synchronization points during
+                start-up.</para>
+
+                <para>This unit type has no specific options. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic [Unit] and [Install] sections. A
+                separate [Target] section does not exist, since no
+                target-specific options may be configured.</para>
+
+                <para>Target units do not offer any additional
+                functionality on top of the generic functionality
+                provided by units. They exist merely to group units via dependencies
+                (useful as boot targets), and to establish
+                standardized names for synchronization points used in
+                dependencies between units. Among other things, target
+                units are a more flexible replacement for SysV
+                runlevels in the classic SysV init system. (And for
+                compatibility reasons special
+                target units such as
+                <filename>runlevel3.target</filename> exist which are used by
+                the SysV runlevel compatibility code in systemd. See
+                <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                for details).</para>
+
+                <para>Unless <varname>DefaultDependencies=</varname>
+                is set to <option>false</option>, target units will
+                implicitly complement all configured dependencies of
+                type <varname>Wants=</varname>,
+                <varname>Requires=</varname>,
+                <varname>RequiresOverridable=</varname> with
+                dependencies of type <varname>After=</varname> if the
+                units in question also have
+                <varname>DefaultDependencies=true</varname>.
+                </para>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.time.xml b/man/systemd.time.xml
new file mode 100644 (file)
index 0000000..4f80a30
--- /dev/null
@@ -0,0 +1,291 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.time">
+
+        <refentryinfo>
+                <title>systemd.time</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.time</refentrytitle>
+                <manvolnum>7</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.time</refname>
+                <refpurpose>Time and date specifications</refpurpose>
+        </refnamediv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>In systemd timestamps, timespans, and calendar
+                events are displayed and may be specified in closely
+                related syntaxes.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Displaying Timespans</title>
+
+                <para>Timespans refer to time durations. On display
+                systemd will present timespans as a space separated
+                series of time values each suffixed by a time
+                unit.</para>
+
+                <programlisting>2h 30min</programlisting>
+
+                <para>All specified time values are meant to be added
+                up. The above hence refers to 150 minutes.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Parsing Timespans</title>
+
+                <para>When parsing systemd will accept the same
+                timespan syntax. Separating spaces may be omitted. The
+                following time units are understood:</para>
+
+                <itemizedlist>
+                        <listitem><para>usec, us</para></listitem>
+                        <listitem><para>msec, ms</para></listitem>
+                        <listitem><para>seconds, second, sec, s</para></listitem>
+                        <listitem><para>minutes, minute, min, m</para></listitem>
+                        <listitem><para>hours, hour, hr, h</para></listitem>
+                        <listitem><para>days, day, d</para></listitem>
+                        <listitem><para>weeks, week, w</para></listitem>
+                        <listitem><para>months, month</para></listitem>
+                        <listitem><para>years, year, y</para></listitem>
+                </itemizedlist>
+
+                <para>If no time unit is specified, generally seconds
+                are assumed, but some exceptions exist and are marked
+                as such. In a few cases <literal>ns</literal>,
+                <literal>nsec</literal> is accepted too, where the
+                granularity of the timespan allows for this.</para>
+
+                <para>Examples for valid timespan specifications:</para>
+
+                <programlisting>2 h
+2hours
+48hr
+1y 12month
+55s500ms
+300ms20s 5day</programlisting>
+        </refsect1>
+
+        <refsect1>
+                <title>Displaying Timestamps</title>
+
+                <para>Timestamps refer to specific, unique points in
+                time. On display systemd will format these in the
+                local timezone as follows:</para>
+
+                <programlisting>Fri 2012-11-23 23:02:15 CET</programlisting>
+
+                <para>The week day is printed according to the locale
+                choice of the user.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Parsing Timestamps</title>
+
+                <para>When parsing systemd will accept a similar
+                timestamp syntax, but excluding any timezone
+                specification (this limitation might be removed
+                eventually). The week day specification is optional,
+                but when the week day is specified it must either be
+                in the abbreviated (<literal>Wed</literal>) or
+                non-abbreviated (<literal>Wednesday</literal>) english
+                language form (case doesn't matter), and is not
+                subject to the locale choice of the user. Either the
+                date, or the time part may be omitted, in which case
+                the current date or 00:00:00, resp., is assumed. The
+                seconds component of the time may also be omitted, in
+                which case ":00" is assumed. Year numbers may be
+                specified in full or may be abbreviated (omitting the
+                century).</para>
+
+                <para>A timestamp is considered invalid if a week day
+                is specified and the date does not actually match the
+                specified day of the week.</para>
+
+                <para>When parsing systemd will also accept a few
+                special placeholders instead of timestamps:
+                <literal>now</literal> may be used to refer to the
+                current time (or of the invocation of the command
+                that is currently executed). <literal>today</literal>,
+                <literal>yesterday</literal>,
+                <literal>tomorrow</literal> refer to 00:00:00 of the
+                current day, the day before or the next day,
+                respectively.</para>
+
+                <para>When parsing systemd will also accept relative
+                time specifications. A timespan (see above) that is
+                prefixed with <literal>+</literal> is evaluated to the
+                current time plus the specified
+                timespan. Correspondingly a timespan that is prefix
+                with <literal>-</literal> is evaluated to the current
+                time minus the specified timespan. Instead of
+                prefixing the timespan with <literal>-</literal> it
+                may also be suffixed with a space and the word
+                <literal>ago</literal>.</para>
+
+                <para>Examples for valid timestamps and their
+                normalized form (assuming the current time was
+                2012-11-23 18:15:22):</para>
+
+                <programlisting>Fri 2012-11-23 11:12:13 → Fri 2012-11-23 11:12:13
+    2012-11-23 11:12:13 → Fri 2012-11-23 11:12:13
+             2012-11-23 → Fri 2012-11-23 00:00:00
+               12-11-23 → Fri 2012-11-23 00:00:00
+               11:12:13 → Fri 2012-11-23 11:12:13
+                  11:12 → Fri 2012-11-23 11:12:00
+                    now → Fri 2012-11-23 18:15:22
+                  today → Fri 2012-11-23 00:00:00
+              yesterday → Fri 2012-11-22 00:00:00
+               tomorrow → Fri 2012-11-24 00:00:00
+               +3h30min → Fri 2012-11-23 21:45:22
+                    -5s → Fri 2012-11-23 18:15:17
+              11min ago → Fri 2012-11-23 18:04:22</programlisting>
+
+                <para>Note that timestamps printed by systemd will not
+                be parsed correctly by systemd, as the timezone
+                specification is not accepted, and printing timestamps
+                is subject to locale settings for the week day while
+                parsing only accepts english week day names.</para>
+
+                <para>In some cases systemd will display a relative
+                timestamp (relative to the current time, or the time
+                of invocation of the command) instead or in addition
+                to an absolute timestamp as described above. A
+                relative timestamp is formatted as follows:</para>
+
+                <para>2 months 5 days ago</para>
+
+                <para>Note that any relative timestamp will also parse
+                correctly where a timestamp is expected. (see above)</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Calendar Events</title>
+
+                <para>Calendar events may be used to refer to one or
+                more points in time in a single expression. They form
+                a superset of the absolute timestamps explained above:</para>
+
+                <programlisting>Thu,Fri 2012-*-1,5 11:12:13</programlisting>
+
+                <para>The above refers to 11:12:13 of the first or
+                fifth day of any month of the year 2012, given that it
+                is a thursday or friday.</para>
+
+                <para>The weekday specification is optional. If
+                specified it should consist of one or more english
+                language week day names, either in the abbreviated
+                (Wed) or non-abbreviated (Wednesday) form (case does
+                not matter), separated by colons. Specifying two week
+                days separated by "-" refers to a range of continuous
+                week days. "," and "-" may be combined freely.</para>
+
+                <para>In the date and time specifications any
+                component may be specified as "*" in which case any
+                value will match. Alternatively, each component can be
+                specified as list of values separated by
+                colons. Values may also be suffixed with "/" and a
+                repetition value, which indicates that the value and
+                all values plus multiples of the repetition value are
+                matched.</para>
+
+                <para>Either time or date specification may be
+                omitted, in which case the current day and 00:00:00 is
+                implied, respectively. If the second component is not
+                specified ":00" is assumed.</para>
+
+                <para>Timezone names may not be specified.</para>
+
+                <para>The special expressions
+                <literal>hourly</literal>, <literal>daily</literal>,
+                <literal>monthly</literal> and <literal>weekly</literal>
+                may be used as calendar events which refer to
+                <literal>*-*-* *:00:00</literal>, <literal>*-*-*
+                00:00:00</literal>, <literal>*-*-01 00:00:00</literal> and
+                <literal>Mon *-*-* 00:00:00</literal>,
+                respectively.</para>
+
+                <para>Examples for valid timestamps and their
+                normalized form:</para>
+
+<programlisting>   Sat,Thu,Mon-Wed,Sat-Sun → Mon-Thu,Sat,Sun *-*-* 00:00:00
+     Mon,Sun 12-*-* 2,1:23 → Mon,Sun 2012-*-* 01,02:23:00
+                   Wed *-1 → Wed *-*-01 00:00:00
+           Wed-Wed,Wed *-1 → Wed *-*-01 00:00:00
+                Wed, 17:48 → Wed *-*-* 17:48:00
+Wed-Sat,Tue 12-10-15 1:2:3 → Tue-Sat 2012-10-15 01:02:03
+               *-*-7 0:0:0 → *-*-07 00:00:00
+                     10-15 → *-10-15 00:00:00
+       monday *-12-* 17:00 → Mon *-12-* 17:00:00
+ Mon,Fri *-*-3,1,2 *:30:45 → Mon,Fri *-*-01,02,03 *:30:45
+      12,14,13,12:20,10,30 → *-*-* 12,13,14:10,20,30:00
+ mon,fri *-1/2-1,3 *:30:45 → Mon,Fri *-01/2-01,03 *:30:45
+            03-05 08:05:40 → *-03-05 08:05:40
+                  08:05:40 → *-*-* 08:05:40
+                     05:40 → *-*-* 05:40:00
+    Sat,Sun 12-05 08:05:40 → Sat,Sun *-12-05 08:05:40
+          Sat,Sun 08:05:40 → Sat,Sun *-*-* 08:05:40
+          2003-03-05 05:40 → 2003-03-05 05:40:00
+                2003-03-05 → 2003-03-05 00:00:00
+                     03-05 → *-03-05 00:00:00
+                    hourly → *-*-* *:00:00
+                     daily → *-*-* 00:00:00
+                   monthly → *-*-01 00:00:00
+                    weekly → Mon *-*-* 00:00:00
+                     *:2/3 → *-*-* *:02/3:00</programlisting>
+
+                  <para>Calendar events are used by timer units, see
+                  <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  for details.</para>
+
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
new file mode 100644 (file)
index 0000000..5cc543e
--- /dev/null
@@ -0,0 +1,206 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.timer">
+        <refentryinfo>
+                <title>systemd.timer</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.timer</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.timer</refname>
+                <refpurpose>Timer unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.timer</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file whose name ends in
+                <filename>.timer</filename> encodes information about
+                a timer controlled and supervised by systemd, for
+                timer-based activation.</para>
+
+                <para>This man page lists the configuration options
+                specific to this unit type. See
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for the common options of all unit configuration
+                files. The common configuration items are configured
+                in the generic [Unit] and [Install] sections. The
+                timer specific configuration options are configured in
+                the [Timer] section.</para>
+
+                <para>For each timer file, a matching unit file must
+                exist, describing the unit to activate when the timer
+                elapses. By default, a service by the same name as the
+                timer (except for the suffix) is activated. Example: a
+                timer file <filename>foo.timer</filename> activates a
+                matching service <filename>foo.service</filename>. The
+                unit to activate may be controlled by
+                <varname>Unit=</varname> (see below).</para>
+
+                <para>Unless <varname>DefaultDependencies=</varname>
+                is set to <option>false</option>, timer units will
+                implicitly have dependencies of type
+                <varname>Conflicts=</varname> and
+                <varname>Before=</varname> on
+                <filename>shutdown.target</filename>. These ensure
+                that timer units are stopped cleanly prior to system
+                shutdown. Only timer units involved with early boot or
+                late system shutdown should disable this
+                option.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>Timer files must include a [Timer] section,
+                which carries information about the timer it
+                defines. The options specific to the [Timer] section
+                of timer units are the following:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>OnActiveSec=</varname></term>
+                                <term><varname>OnBootSec=</varname></term>
+                                <term><varname>OnStartupSec=</varname></term>
+                                <term><varname>OnUnitActiveSec=</varname></term>
+                                <term><varname>OnUnitInactiveSec=</varname></term>
+
+                                <listitem><para>Defines monotonic timers
+                                relative to different starting points:
+                                <varname>OnActiveSec=</varname> defines a
+                                timer relative to the moment the timer
+                                itself is
+                                activated. <varname>OnBootSec=</varname>
+                                defines a timer relative to when the
+                                machine was booted
+                                up. <varname>OnStartupSec=</varname>
+                                defines a timer relative to when
+                                systemd was
+                                started. <varname>OnUnitActiveSec=</varname>
+                                defines a timer relative to when the
+                                unit the timer is activating was last
+                                activated. <varname>OnUnitInactiveSec=</varname>
+                                defines a timer relative to when the
+                                unit the timer is activating was last
+                                deactivated.</para>
+
+                                <para>Multiple directives may be
+                                combined of the same and of different
+                                types. For example, by combining
+                                <varname>OnBootSec=</varname> and
+                                <varname>OnUnitActiveSec=</varname> it is
+                                possible to define a timer that
+                                elapses in regular intervals and
+                                activates a specific service each
+                                time.</para>
+
+                                <para>The arguments to the directives
+                                are time spans configured in
+                                seconds. Example: "OnBootSec=50" means
+                                50s after boot-up. The argument may
+                                also include time units. Example:
+                                "OnBootSec=5h 30min" means 5 hours and
+                                30 minutes after boot-up. For details
+                                about the syntax of time spans see
+                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+                                <para>If a timer configured with
+                                <varname>OnBootSec=</varname> or
+                                <varname>OnStartupSec=</varname> is
+                                already in the past when the timer
+                                unit is activated, it will immediately
+                                elapse and the configured unit is
+                                started. This is not the case for
+                                timers defined in the other
+                                directives.</para>
+
+                                <para>These are monotonic timers,
+                                independent of wall-clock time and timezones. If the
+                                computer is temporarily suspended, the
+                                monotonic clock stops too.</para></listitem>
+
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>OnCalendar=</varname></term>
+
+                                <listitem><para>Defines realtime
+                                (i.e. wallclock) timers via calendar
+                                event expressions. See
+                                <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for more information on the syntax of
+                                calendar event
+                                expressions.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Unit=</varname></term>
+
+                                <listitem><para>The unit to activate
+                                when this timer elapses. The argument is a
+                                unit name, whose suffix is not
+                                <filename>.timer</filename>. If not
+                                specified, this value defaults to a
+                                service that has the same name as the
+                                timer unit, except for the
+                                suffix. (See above.) It is recommended
+                                that the unit name that is activated
+                                and the unit name of the timer unit
+                                are named identically, except for the
+                                suffix.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
new file mode 100644 (file)
index 0000000..8570815
--- /dev/null
@@ -0,0 +1,1108 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.unit">
+
+        <refentryinfo>
+                <title>systemd.unit</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.unit</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.unit</refname>
+                <refpurpose>Unit configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd.service</filename>,
+                <filename>systemd.socket</filename>,
+                <filename>systemd.device</filename>,
+                <filename>systemd.mount</filename>,
+                <filename>systemd.automount</filename>,
+                <filename>systemd.swap</filename>,
+                <filename>systemd.target</filename>,
+                <filename>systemd.path</filename>,
+                <filename>systemd.timer</filename>,
+                <filename>systemd.snapshot</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>A unit configuration file encodes information
+                about a service, a socket, a device, a mount point, an
+                automount point, a swap file or partition, a start-up
+                target, a file system path or a timer controlled and
+                supervised by
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>. The
+                syntax is inspired by <ulink
+                url="http://standards.freedesktop.org/desktop-entry-spec/latest/">XDG
+                Desktop Entry Specification</ulink> <filename>.desktop</filename> files, which are in turn
+                inspired by Microsoft Windows
+                <filename>.ini</filename> files.</para>
+
+                <para>This man page lists the common configuration
+                options of all the unit types. These options need to
+                be configured in the [Unit] or [Install]
+                sections of the unit files.</para>
+
+                <para>In addition to the generic [Unit] and [Install]
+                sections described here, each unit should have a
+                type-specific section, e.g. [Service] for a service
+                unit. See the respective man pages for more
+                information.</para>
+
+                <para>Unit files may contain additional options on top
+                of those listed here. If systemd encounters an unknown
+                option it will write a warning log message but
+                continue loading the unit. If an option is prefixed
+                with <option>X-</option> it is ignored completely by
+                systemd. Applications may use this to include
+                additional information in the unit files.</para>
+
+                <para>Boolean arguments used in unit files can be
+                written in various formats. For positive settings the
+                strings <option>1</option>, <option>yes</option>,
+                <option>true</option> and <option>on</option> are
+                equivalent. For negative settings the strings
+                <option>0</option>, <option>no</option>,
+                <option>false</option> and <option>off</option> are
+                equivalent.</para>
+
+                <para>Time span values encoded in unit files can be
+                written in various formats. A stand-alone number
+                specifies a time in seconds. If suffixed with a time
+                unit, the unit is honored. A concatenation of
+                multiple values with units is supported, in which case
+                the values are added up. Example: "50" refers to 50
+                seconds; "2min 200ms" refers to 2 minutes plus 200
+                milliseconds, i.e. 120200ms. The following time units
+                are understood: s, min, h, d, w, ms, us. For details see <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+
+                <para>Empty lines and lines starting with # or ; are
+                ignored. This may be used for commenting. Lines ending
+                in a backslash are concatenated with the following
+                line while reading and the backslash is replaced by a
+                space character. This may be used to wrap long lines.</para>
+
+                <para>If a line starts with <option>.include</option>
+                followed by a file name, the specified file will be
+                parsed at this point. Make sure that the file that is
+                included has the appropriate section headers before
+                any directives.</para>
+
+                <para>Along with a unit file
+                <filename>foo.service</filename> a directory
+                <filename>foo.service.wants/</filename> may exist. All
+                units symlinked from such a directory are implicitly
+                added as dependencies of type
+                <varname>Wanted=</varname> to the unit. This is useful
+                to hook units into the start-up of other units,
+                without having to modify their unit configuration
+                files. For details about the semantics of
+                <varname>Wanted=</varname> see below. The preferred
+                way to create symlinks in the
+                <filename>.wants/</filename> directory of a service is
+                with the <command>enable</command> command of the
+                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                tool which reads information from the [Install]
+                section of unit files. (See below.) A similar
+                functionality exists for <varname>Requires=</varname>
+                type dependencies as well, the directory suffix is
+                <filename>.requires/</filename> in this case.</para>
+
+                <para>Note that while systemd offers a flexible
+                dependency system between units it is recommended to
+                use this functionality only sparsely and instead rely
+                on techniques such as bus-based or socket-based
+                activation which makes dependencies implicit, which
+                both results in a simpler and more flexible
+                system.</para>
+
+                <para>Some unit names reflect paths existing in the
+                file system name space. Example: a device unit
+                <filename>dev-sda.device</filename> refers to a device
+                with the device node <filename>/dev/sda</filename> in
+                the file system namespace. If this applies a special
+                way to escape the path name is used, so that the
+                result is usable as part of a file name. Basically,
+                given a path, "/" is replaced by "-", and all
+                unprintable characters and the "-" are replaced by
+                C-style "\x20" escapes. The root directory "/" is
+                encoded as single dash, while otherwise the initial
+                and ending "/" is removed from all paths during
+                transformation. This escaping is reversible.</para>
+
+                <para>Optionally, units may be instantiated from a
+                template file at runtime. This allows creation of
+                multiple units from a single configuration file. If
+                systemd looks for a unit configuration file it will
+                first search for the literal unit name in the
+                filesystem. If that yields no success and the unit
+                name contains an @ character, systemd will look for a
+                unit template that shares the same name but with the
+                instance string (i.e. the part between the @ character
+                and the suffix) removed. Example: if a service
+                <filename>getty@tty3.service</filename> is requested
+                and no file by that name is found, systemd will look
+                for <filename>getty@.service</filename> and
+                instantiate a service from that configuration file if
+                it is found.</para>
+
+                <para>To refer to the instance string from
+                within the configuration file you may use the special
+                <literal>%i</literal> specifier in many of the
+                configuration options. Other specifiers exist, the
+                full list is:</para>
+
+                <table>
+                  <title>Specifiers available in unit files</title>
+                  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+                    <colspec colname="spec" />
+                    <colspec colname="mean" />
+                    <colspec colname="detail" />
+                    <thead>
+                      <row>
+                        <entry>Specifier</entry>
+                        <entry>Meaning</entry>
+                        <entry>Details</entry>
+                      </row>
+                    </thead>
+                    <tbody>
+                      <row>
+                        <entry><literal>%n</literal></entry>
+                        <entry>Full unit name</entry>
+                        <entry></entry>
+                      </row>
+                      <row>
+                        <entry><literal>%N</literal></entry>
+                        <entry>Unescaped full unit name</entry>
+                        <entry></entry>
+                      </row>
+                      <row>
+                        <entry><literal>%p</literal></entry>
+                        <entry>Prefix name</entry>
+                        <entry>This refers to the string before the @, i.e. "getty" in the example above, where "tty3" is the instance name.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%P</literal></entry>
+                        <entry>Unescaped prefix name</entry>
+                        <entry></entry>
+                      </row>
+                      <row>
+                        <entry><literal>%i</literal></entry>
+                        <entry>Instance name</entry>
+                        <entry>This is the string between the @ character and the suffix.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%I</literal></entry>
+                        <entry>Unescaped instance name</entry>
+                        <entry></entry>
+                      </row>
+                      <row>
+                        <entry><literal>%f</literal></entry>
+                        <entry>Unescaped file name</entry>
+                        <entry>This is either the unescaped instance name (if set) with / prepended (if necessary), or the prefix name similarly prepended with /.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%c</literal></entry>
+                        <entry>Control group path of the unit</entry>
+                        <entry></entry>
+                      </row>
+                      <row>
+                        <entry><literal>%r</literal></entry>
+                        <entry>Root control group path of systemd</entry>
+                        <entry></entry>
+                      </row>
+                      <row>
+                        <entry><literal>%R</literal></entry>
+                        <entry>Parent directory of the root control group path of systemd</entry>
+                        <entry></entry>
+                      </row>
+                      <row>
+                        <entry><literal>%t</literal></entry>
+                        <entry>Runtime socket dir</entry>
+                        <entry>This is either /run (for the system manager) or $XDG_RUNTIME_DIR (for user managers).</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%u</literal></entry>
+                        <entry>User name</entry>
+                        <entry>This is the name of the configured user of the unit, or (if none is set) the user running the systemd instance.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%U</literal></entry>
+                        <entry>User uid</entry>
+                        <entry>This is the uid of the configured user of the unit, or (if none is set) the user running the systemd instance.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%h</literal></entry>
+                        <entry>User home directory</entry>
+                        <entry>This is the home directory of the configured user of the unit, or (if none is set) the user running the systemd instance.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%s</literal></entry>
+                        <entry>User shell</entry>
+                        <entry>This is the shell of the configured user of the unit, or (if none is set) the user running the systemd instance.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%m</literal></entry>
+                        <entry>Machine ID</entry>
+                        <entry>The machine ID of the running system, formatted as string. See <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%b</literal></entry>
+                        <entry>Boot ID</entry>
+                        <entry>The boot ID of the running system, formatted as string. See <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry> for more information.</entry>
+                      </row>
+                      <row>
+                        <entry><literal>%H</literal></entry>
+                        <entry>Host name</entry>
+                        <entry>The host name of the running system.</entry>
+                      </row>
+                    </tbody>
+                  </tgroup>
+                </table>
+
+                <para>If a unit file is empty (i.e. has the file size
+                0) or is symlinked to <filename>/dev/null</filename>
+                its configuration will not be loaded and it appears
+                with a load state of <literal>masked</literal>, and
+                cannot be activated. Use this as an effective way to
+                fully disable a unit, making it impossible to start it
+                even manually.</para>
+
+                <para>The unit file format is covered by the
+                <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
+                Stability Promise</ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>Unit file may include a [Unit] section, which
+                carries generic information about the unit that is not
+                dependent on the type of unit:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>Description=</varname></term>
+                                <listitem><para>A free-form string
+                                describing the unit. This is intended
+                                for use in UIs to show descriptive
+                                information along with the unit
+                                name.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Documentation=</varname></term>
+                                <listitem><para>A space separated list
+                                of URIs referencing documentation for
+                                this unit or its
+                                configuration. Accepted are only URIs
+                                of the types
+                                <literal>http://</literal>,
+                                <literal>https://</literal>,
+                                <literal>file:</literal>,
+                                <literal>info:</literal>,
+                                <literal>man:</literal>. For more
+                                information about the syntax of these
+                                URIs see
+                                <citerefentry><refentrytitle>uri</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The
+                                URIs should be listed in order of
+                                relevance, starting with the most
+                                relevant. It is a good idea to first
+                                reference documentation that explains
+                                what the unit's purpose is, followed
+                                by how it is configured, followed by
+                                any other related
+                                documentation.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Requires=</varname></term>
+
+                                <listitem><para>Configures requirement
+                                dependencies on other units. If this
+                                unit gets activated, the units listed
+                                here will be activated as well. If one
+                                of the other units gets deactivated or
+                                its activation fails, this unit will
+                                be deactivated. This option may be
+                                specified more than once, in which
+                                case requirement dependencies for all
+                                listed names are created. Note that
+                                requirement dependencies do not
+                                influence the order in which services
+                                are started or stopped. This has to be
+                                configured independently with the
+                                <varname>After=</varname> or
+                                <varname>Before=</varname> options. If
+                                a unit
+                                <filename>foo.service</filename>
+                                requires a unit
+                                <filename>bar.service</filename> as
+                                configured with
+                                <varname>Requires=</varname> and no
+                                ordering is configured with
+                                <varname>After=</varname> or
+                                <varname>Before=</varname>, then both
+                                units will be started simultaneously
+                                and without any delay between them if
+                                <filename>foo.service</filename> is
+                                activated. Often it is a better choice
+                                to use <varname>Wants=</varname>
+                                instead of
+                                <varname>Requires=</varname> in order
+                                to achieve a system that is more
+                                robust when dealing with failing
+                                services.</para>
+
+                                <para>Note that dependencies of this
+                                type may also be configured outside of
+                                the unit configuration file by
+                                adding a symlink to a
+                                <filename>.requires/</filename> directory
+                                accompanying the unit file. For
+                                details see above.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RequiresOverridable=</varname></term>
+
+                                <listitem><para>Similar to
+                                <varname>Requires=</varname>.
+                                Dependencies listed in
+                                <varname>RequiresOverridable=</varname>
+                                which cannot be fulfilled or fail to
+                                start are ignored if the startup was
+                                explicitly requested by the user. If
+                                the start-up was pulled in indirectly
+                                by some dependency or automatic
+                                start-up of units that is not
+                                requested by the user this dependency
+                                must be fulfilled and otherwise the
+                                transaction fails. Hence, this option
+                                may be used to configure dependencies
+                                that are normally honored unless the
+                                user explicitly starts up the unit, in
+                                which case whether they failed or not
+                                is irrelevant.</para></listitem>
+
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Requisite=</varname></term>
+                                <term><varname>RequisiteOverridable=</varname></term>
+
+                                <listitem><para>Similar to
+                                <varname>Requires=</varname>
+                                and <varname>RequiresOverridable=</varname>, respectively. However,
+                                if a unit listed here is not started
+                                already it will not be started and the
+                                transaction fails
+                                immediately.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Wants=</varname></term>
+
+                                <listitem><para>A weaker version of
+                                <varname>Requires=</varname>. A unit
+                                listed in this option will be started
+                                if the configuring unit is. However,
+                                if the listed unit fails to start up
+                                or cannot be added to the transaction
+                                this has no impact on the validity of
+                                the transaction as a whole. This is
+                                the recommended way to hook start-up
+                                of one unit to the start-up of another
+                                unit.</para>
+
+                                <para>Note that dependencies of this
+                                type may also be configured outside of
+                                the unit configuration file by
+                                adding a symlink to a
+                                <filename>.wants/</filename> directory
+                                accompanying the unit file. For
+                                details see above.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>BindsTo=</varname></term>
+
+                                <listitem><para>Configures requirement
+                                dependencies, very similar in style to
+                                <varname>Requires=</varname>, however
+                                in addition to this behavior it also
+                                declares that this unit is stopped
+                                when any of the units listed suddenly
+                                disappears. Units can suddenly,
+                                unexpectedly disappear if a service
+                                terminates on its own choice, a device
+                                is unplugged or a mount point
+                                unmounted without involvement of
+                                systemd.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PartOf=</varname></term>
+
+                                <listitem><para>Configures dependencies
+                                similar to <varname>Requires=</varname>,
+                                but limited to stopping and restarting
+                                of units. When systemd stops or restarts
+                                the units listed here, the action is
+                                propagated to this unit.
+                                Note that this is a one way dependency -
+                                changes to this unit do not affect the
+                                listed units.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Conflicts=</varname></term>
+
+                                <listitem><para>Configures negative
+                                requirement dependencies. If a unit
+                                has a
+                                <varname>Conflicts=</varname> setting
+                                on another unit, starting the former
+                                will stop the latter and vice
+                                versa. Note that this setting is
+                                independent of and orthogonal to the
+                                <varname>After=</varname> and
+                                <varname>Before=</varname> ordering
+                                dependencies.</para>
+
+                                <para>If a unit A that conflicts with
+                                a unit B is scheduled to be started at
+                                the same time as B, the transaction
+                                will either fail (in case both are
+                                required part of the transaction) or
+                                be modified to be fixed (in case one
+                                or both jobs are not a required part
+                                of the transaction). In the latter
+                                case the job that is not the required
+                                will be removed, or in case both are
+                                not required the unit that conflicts
+                                will be started and the unit that is
+                                conflicted is
+                                stopped.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Before=</varname></term>
+                                <term><varname>After=</varname></term>
+
+                                <listitem><para>Configures ordering
+                                dependencies between units. If a unit
+                                <filename>foo.service</filename>
+                                contains a setting
+                                <option>Before=bar.service</option>
+                                and both units are being started,
+                                <filename>bar.service</filename>'s
+                                start-up is delayed until
+                                <filename>foo.service</filename> is
+                                started up. Note that this setting is
+                                independent of and orthogonal to the
+                                requirement dependencies as configured
+                                by <varname>Requires=</varname>. It is
+                                a common pattern to include a unit
+                                name in both the
+                                <varname>After=</varname> and
+                                <varname>Requires=</varname> option in
+                                which case the unit listed will be
+                                started before the unit that is
+                                configured with these options. This
+                                option may be specified more than
+                                once, in which case ordering
+                                dependencies for all listed names are
+                                created. <varname>After=</varname> is
+                                the inverse of
+                                <varname>Before=</varname>, i.e. while
+                                <varname>After=</varname> ensures that
+                                the configured unit is started after
+                                the listed unit finished starting up,
+                                <varname>Before=</varname> ensures the
+                                opposite, i.e.  that the configured
+                                unit is fully started up before the
+                                listed unit is started. Note that when
+                                two units with an ordering dependency
+                                between them are shut down, the
+                                inverse of the start-up order is
+                                applied. i.e. if a unit is configured
+                                with <varname>After=</varname> on
+                                another unit, the former is stopped
+                                before the latter if both are shut
+                                down. If one unit with an ordering
+                                dependency on another unit is shut
+                                down while the latter is started up,
+                                the shut down is ordered before the
+                                start-up regardless whether the
+                                ordering dependency is actually of
+                                type <varname>After=</varname> or
+                                <varname>Before=</varname>. If two
+                                units have no ordering dependencies
+                                between them they are shut down
+                                or started up simultaneously, and
+                                no ordering takes
+                                place. </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>OnFailure=</varname></term>
+
+                                <listitem><para>Lists one or more
+                                units that are activated when this
+                                unit enters the
+                                '<literal>failed</literal>'
+                                state.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PropagatesReloadTo=</varname></term>
+                                <term><varname>ReloadPropagatedFrom=</varname></term>
+
+                                <listitem><para>Lists one or more
+                                units where reload requests on the
+                                unit will be propagated to/on the
+                                other unit will be propagated
+                                from. Issuing a reload request on a
+                                unit will automatically also enqueue a
+                                reload request on all units that the
+                                reload request shall be propagated to
+                                via these two
+                                settings.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RequiresMountsFor=</varname></term>
+
+                                <listitem><para>Takes a space
+                                separated list of absolute paths. Automatically
+                                adds dependencies of type
+                                <varname>Requires=</varname> and
+                                <varname>After=</varname> for all
+                                mount units required to access the
+                                specified path.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>OnFailureIsolate=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option> the
+                                unit listed in
+                                <varname>OnFailure=</varname> will be
+                                enqueued in isolation mode, i.e. all
+                                units that are not its dependency will
+                                be stopped. If this is set only a
+                                single unit may be listed in
+                                <varname>OnFailure=</varname>. Defaults
+                                to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>IgnoreOnIsolate=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                this unit will not be stopped when
+                                isolating another unit. Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>IgnoreOnSnapshot=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                this unit will not be included in
+                                snapshots. Defaults to
+                                <option>true</option> for device and
+                                snapshot units, <option>false</option>
+                                for the others.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>StopWhenUnneeded=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                this unit will be stopped when it is
+                                no longer used. Note that in order to
+                                minimize the work to be executed,
+                                systemd will not stop units by default
+                                unless they are conflicting with other
+                                units, or the user explicitly
+                                requested their shut down. If this
+                                option is set, a unit will be
+                                automatically cleaned up if no other
+                                active unit requires it. Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RefuseManualStart=</varname></term>
+                                <term><varname>RefuseManualStop=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                this unit can only be activated
+                                or deactivated indirectly. In
+                                this case explicit start-up
+                                or termination requested by the
+                                user is denied, however if it is
+                                started or stopped as a
+                                dependency of another unit, start-up
+                                or termination will succeed. This
+                                is mostly a safety feature to ensure
+                                that the user does not accidentally
+                                activate units that are not intended
+                                to be activated explicitly, and not
+                                accidentally deactivate units that are
+                                not intended to be deactivated.
+                                These options default to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>AllowIsolate=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                this unit may be used with the
+                                <command>systemctl isolate</command>
+                                command. Otherwise this will be
+                                refused. It probably is a good idea to
+                                leave this disabled except for target
+                                units that shall be used similar to
+                                runlevels in SysV init systems, just
+                                as a precaution to avoid unusable
+                                system states. This option defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>DefaultDependencies=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                (the default), a few default
+                                dependencies will implicitly be
+                                created for the unit. The actual
+                                dependencies created depend on the
+                                unit type. For example, for service
+                                units, these dependencies ensure that
+                                the service is started only after
+                                basic system initialization is
+                                completed and is properly terminated on
+                                system shutdown. See the respective
+                                man pages for details. Generally, only
+                                services involved with early boot or
+                                late shutdown should set this option
+                                to <option>false</option>. It is
+                                highly recommended to leave this
+                                option enabled for the majority of
+                                common units. If set to
+                                <option>false</option> this option
+                                does not disable all implicit
+                                dependencies, just non-essential
+                                ones.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>JobTimeoutSec=</varname></term>
+
+                                <listitem><para>When clients are
+                                waiting for a job of this unit to
+                                complete, time out after the specified
+                                time. If this time limit is reached
+                                the job will be cancelled, the unit
+                                however will not change state or even
+                                enter the '<literal>failed</literal>'
+                                mode. This value defaults to 0 (job
+                                timeouts disabled), except for device
+                                units. NB: this timeout is independent
+                                from any unit-specific timeout (for
+                                example, the timeout set with
+                                <varname>Timeout=</varname> in service
+                                units) as the job timeout has no
+                                effect on the unit itself, only on the
+                                job that might be pending for it. Or
+                                in other words: unit-specific timeouts
+                                are useful to abort unit state
+                                changes, and revert them. The job
+                                timeout set with this option however
+                                is useful to abort only the job
+                                waiting for the unit state to
+                                change.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ConditionPathExists=</varname></term>
+                                <term><varname>ConditionPathExistsGlob=</varname></term>
+                                <term><varname>ConditionPathIsDirectory=</varname></term>
+                                <term><varname>ConditionPathIsSymbolicLink=</varname></term>
+                                <term><varname>ConditionPathIsMountPoint=</varname></term>
+                                <term><varname>ConditionPathIsReadWrite=</varname></term>
+                                <term><varname>ConditionDirectoryNotEmpty=</varname></term>
+                                <term><varname>ConditionFileNotEmpty=</varname></term>
+                                <term><varname>ConditionFileIsExecutable=</varname></term>
+                                <term><varname>ConditionKernelCommandLine=</varname></term>
+                                <term><varname>ConditionVirtualization=</varname></term>
+                                <term><varname>ConditionSecurity=</varname></term>
+                                <term><varname>ConditionCapability=</varname></term>
+                                <term><varname>ConditionHost=</varname></term>
+                                <term><varname>ConditionACPower=</varname></term>
+                                <term><varname>ConditionNull=</varname></term>
+
+                                <listitem><para>Before starting a unit
+                                verify that the specified condition is
+                                true. If it is not true the starting
+                                of the unit will be skipped, however
+                                all ordering dependencies of it are
+                                still respected. A failing condition
+                                will not result in the unit being
+                                moved into a failure state. The
+                                condition is checked at the time the
+                                queued start job is to be
+                                executed.</para>
+
+                                <para>With
+                                <varname>ConditionPathExists=</varname>
+                                a file existence condition is
+                                checked before a unit is started. If
+                                the specified absolute path name does
+                                not exist the condition will
+                                fail. If the absolute path name passed
+                                to
+                                <varname>ConditionPathExists=</varname>
+                                is prefixed with an exclamation mark
+                                ('!'), the test is negated, and the unit
+                                is only started if the path does not
+                                exist.</para>
+
+                                <para><varname>ConditionPathExistsGlob=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>,
+                                but checks for the existence of at
+                                least one file or directory matching
+                                the specified globbing pattern.</para>
+
+                                <para><varname>ConditionPathIsDirectory=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>
+                                but verifies whether a certain path
+                                exists and is a
+                                directory.</para>
+
+                                <para><varname>ConditionPathIsSymbolicLink=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>
+                                but verifies whether a certain path
+                                exists and is a symbolic
+                                link.</para>
+
+                                <para><varname>ConditionPathIsMountPoint=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>
+                                but verifies whether a certain path
+                                exists and is a mount
+                                point.</para>
+
+                                <para><varname>ConditionPathIsReadWrite=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>
+                                but verifies whether the underlying
+                                file system is readable and writable
+                                (i.e. not mounted
+                                read-only).</para>
+
+                                <para><varname>ConditionDirectoryNotEmpty=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>
+                                but verifies whether a certain path
+                                exists and is a non-empty
+                                directory.</para>
+
+                                <para><varname>ConditionFileNotEmpty=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>
+                                but verifies whether a certain path
+                                exists and refers to a regular file
+                                with a non-zero size.</para>
+
+                                <para><varname>ConditionFileIsExecutable=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>
+                                but verifies whether a certain path
+                                exists, is a regular file and marked
+                                executable.</para>
+
+                                <para>Similar,
+                                <varname>ConditionKernelCommandLine=</varname>
+                                may be used to check whether a
+                                specific kernel command line option is
+                                set (or if prefixed with the
+                                exclamation mark unset). The argument
+                                must either be a single word, or an
+                                assignment (i.e. two words, separated
+                                '='). In the former
+                                case the kernel command line is
+                                searched for the word appearing as is,
+                                or as left hand side of an
+                                assignment. In the latter case the
+                                exact assignment is looked for with
+                                right and left hand side
+                                matching.</para>
+
+                                <para><varname>ConditionVirtualization=</varname>
+                                may be used to check whether the
+                                system is executed in a virtualized
+                                environment and optionally test
+                                whether it is a specific
+                                implementation. Takes either boolean
+                                value to check if being executed in
+                                any virtualized environment, or one of
+                                <varname>vm</varname> and
+                                <varname>container</varname> to test
+                                against a generic type of
+                                virtualization solution, or one of
+                                <varname>qemu</varname>,
+                                <varname>kvm</varname>,
+                                <varname>vmware</varname>,
+                                <varname>microsoft</varname>,
+                                <varname>oracle</varname>,
+                                <varname>xen</varname>,
+                                <varname>bochs</varname>,
+                                <varname>chroot</varname>,
+                                <varname>openvz</varname>,
+                                <varname>lxc</varname>,
+                                <varname>lxc-libvirt</varname>,
+                                <varname>systemd-nspawn</varname> to
+                                test against a specific
+                                implementation. If multiple
+                                virtualization technologies are nested
+                                only the innermost is considered. The
+                                test may be negated by prepending an
+                                exclamation mark.</para>
+
+                                <para><varname>ConditionSecurity=</varname>
+                                may be used to check whether the given
+                                security module is enabled on the
+                                system.  Currently the only recognized
+                                value is <varname>selinux</varname>.
+                                The test may be negated by prepending
+                                an exclamation
+                                mark.</para>
+
+                                <para><varname>ConditionCapability=</varname>
+                                may be used to check whether the given
+                                capability exists in the capability
+                                bounding set of the service manager
+                                (i.e. this does not check whether
+                                capability is actually available in
+                                the permitted or effective sets, see
+                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details). Pass a capability name
+                                such as <literal>CAP_MKNOD</literal>,
+                                possibly prefixed with an exclamation
+                                mark to negate the check.</para>
+
+                                <para><varname>ConditionHost=</varname>
+                                may be used to match against the
+                                host name or machine ID of the
+                                host. This either takes a host name
+                                string (optionally with shell style
+                                globs) which is tested against the
+                                locally set host name as returned by
+                                <citerefentry><refentrytitle>gethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+                                or a machine ID formatted as string
+                                (see
+                                <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+                                The test may be negated by prepending
+                                an exclamation mark.</para>
+
+                                <para><varname>ConditionACPower=</varname>
+                                may may be used to check whether the
+                                system has AC power, or is exlcusively
+                                battery powered at the time of
+                                activation of the unit. This takes a
+                                boolean argument. If set to
+                                <varname>true</varname> the condition
+                                will hold only if at least one AC
+                                connector of the system is connected
+                                to a power source, or if no AC
+                                connectors are known. Conversely, if
+                                set to <varname>false</varname> the
+                                condition will hold only if there is
+                                at least one AC connector known and
+                                all AC connectors are disconnected
+                                from a power source.</para>
+
+                                <para>Finally,
+                                <varname>ConditionNull=</varname> may
+                                be used to add a constant condition
+                                check value to the unit. It takes a
+                                boolean argument. If set to
+                                <varname>false</varname> the condition
+                                will always fail, otherwise
+                                succeed.</para>
+
+                                <para>If multiple conditions are
+                                specified the unit will be executed if
+                                all of them apply (i.e. a logical AND
+                                is applied). Condition checks can be
+                                prefixed with a pipe symbol (|) in
+                                which case a condition becomes a
+                                triggering condition. If at least one
+                                triggering condition is defined for a
+                                unit then the unit will be executed if
+                                at least one of the triggering
+                                conditions apply and all of the
+                                non-triggering conditions. If you
+                                prefix an argument with the pipe
+                                symbol and an exclamation mark the
+                                pipe symbol must be passed first, the
+                                exclamation second. Except for
+                                <varname>ConditionPathIsSymbolicLink=</varname>,
+                                all path checks follow
+                                symlinks.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SourcePath=</varname></term>
+                                <listitem><para>A path to a
+                                configuration file this unit has been
+                                generated from. This is primarily
+                                useful for implementation of generator
+                                tools that convert configuration from
+                                an external configuration file format
+                                into native unit files. Thus
+                                functionality should not be used in
+                                normal units.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>Unit file may include a [Install] section, which
+                carries installation information for the unit. This
+                section is not interpreted by
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                during runtime. It is used exclusively by the
+                <command>enable</command> and
+                <command>disable</command> commands of the
+                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                tool during installation of a unit:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>Alias=</varname></term>
+
+                                <listitem><para>Additional names this
+                                unit shall be installed under. The
+                                names listed here must have the same
+                                suffix (i.e. type) as the unit file
+                                name. This option may be specified
+                                more than once, in which case all
+                                listed names are used. At installation
+                                time,
+                                <command>systemctl enable</command>
+                                will create symlinks from these names
+                                to the unit file name.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>WantedBy=</varname></term>
+                                <term><varname>RequiredBy=</varname></term>
+
+                                <listitem><para>Installs a symlink in
+                                the <filename>.wants/</filename>
+                                or <filename>.requires/</filename>
+                                subdirectory for a unit, respectively. This has the
+                                effect that when the listed unit name
+                                is activated the unit listing it is
+                                activated
+                                too. <command>WantedBy=foo.service</command>
+                                in a service
+                                <filename>bar.service</filename> is
+                                mostly equivalent to
+                                <command>Alias=foo.service.wants/bar.service</command>
+                                in the same file.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Also=</varname></term>
+
+                                <listitem><para>Additional units to
+                                install when this unit is
+                                installed. If the user requests
+                                installation of a unit with this
+                                option configured,
+                                <command>systemctl enable</command>
+                                will automatically install units
+                                listed in this option as
+                                well.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.automount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.path</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.snapshot</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.xml b/man/systemd.xml
new file mode 100644 (file)
index 0000000..7b3d265
--- /dev/null
@@ -0,0 +1,1272 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd">
+
+        <refentryinfo>
+                <title>systemd</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd</refname>
+                <refname>init</refname>
+                <refpurpose>systemd system and service manager</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+                </cmdsynopsis>
+                <cmdsynopsis>
+                        <command>init <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>systemd is a system and service manager for
+                Linux operating systems. When run as first process on
+                boot (as PID 1), it acts as init system that brings
+                up and maintains userspace services.</para>
+
+                <para>For compatibility with SysV, if systemd is called
+                as <command>init</command> and a PID that is not
+                1, it will execute <command>telinit</command> and pass
+                all command line arguments unmodified. That means
+                <command>init</command> and <command>telinit</command>
+                are mostly equivalent when invoked from normal login sessions. See
+                <citerefentry><refentrytitle>telinit</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                for more information.</para>
+
+                <para>When run as system instance, systemd interprets
+                the configuration file
+                <filename>system.conf</filename>, otherwise
+                <filename>user.conf</filename>. See
+                <citerefentry><refentrytitle>systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more information.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-h</option></term>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a systemd version
+                                identifier and exits.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--test</option></term>
+
+                                <listitem><para>Determine startup
+                                sequence, dump it and exit. This is an
+                                option useful for debugging
+                                only.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--dump-configuration-items</option></term>
+
+                                <listitem><para>Dump understood unit
+                                configuration items. This outputs a
+                                terse but complete list of
+                                configuration items understood in unit
+                                definition files.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--introspect=</option></term>
+
+                                <listitem><para>Extract D-Bus
+                                interface introspection data. This is
+                                mostly useful at install time
+                                to generate data suitable for the
+                                D-Bus interfaces
+                                repository. Optionally the interface
+                                name for the introspection data may be
+                                specified. If omitted, the
+                                introspection data for all interfaces
+                                is dumped.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--unit=</option></term>
+
+                                <listitem><para>Set default unit to
+                                activate on startup. If not specified
+                                defaults to
+                                <filename>default.target</filename>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--system</option></term>
+                                <term><option>--user</option></term>
+
+                                <listitem><para>For <option>--system</option>,
+                                tell systemd to run a
+                                system instance, even if the process ID is
+                                not 1, i.e. systemd is not run as init process.
+                                <option>--user</option> does the opposite,
+                                running a user instance even if the process
+                                ID is 1.
+                                Normally it should not be necessary to
+                                pass these options, as systemd
+                                automatically detects the mode it is
+                                started in. These options are hence of
+                                little use except for debugging. Note
+                                that it is not supported booting and
+                                maintaining a full system with systemd
+                                running in <option>--system</option>
+                                mode, but PID not 1. In practice,
+                                passing <option>--system</option> explicitly is
+                                only useful in conjunction with
+                                <option>--test</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--dump-core</option></term>
+
+                                <listitem><para>Dump core on
+                                crash. This switch has no effect when
+                                run as user
+                                instance.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--crash-shell</option></term>
+
+                                <listitem><para>Run shell on
+                                crash. This switch has no effect when
+                                run as user
+                                instance.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--confirm-spawn</option></term>
+
+                                <listitem><para>Ask for confirmation
+                                when spawning processes. This switch
+                                has no effect when run as user
+                                instance.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--show-status=</option></term>
+
+                                <listitem><para>Show terse service
+                                status information while booting. This
+                                switch has no effect when run as user
+                                instance. Takes a boolean argument
+                                which may be omitted which is
+                                interpreted as
+                                <option>true</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--log-target=</option></term>
+
+                                <listitem><para>Set log
+                                target. Argument must be one of
+                                <option>console</option>,
+                                <option>journal</option>,
+                                <option>syslog</option>,
+                                <option>kmsg</option>,
+                                <option>journal-or-kmsg</option>,
+                                <option>syslog-or-kmsg</option>,
+                                <option>null</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--log-level=</option></term>
+
+                                <listitem><para>Set log level. As
+                                argument this accepts a numerical log
+                                level or the well-known <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                symbolic names (lowercase):
+                                <option>emerg</option>,
+                                <option>alert</option>,
+                                <option>crit</option>,
+                                <option>err</option>,
+                                <option>warning</option>,
+                                <option>notice</option>,
+                                <option>info</option>,
+                                <option>debug</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--log-color=</option></term>
+
+                                <listitem><para>Highlight important
+                                log messages. Argument is a boolean
+                                value. If the argument is omitted it
+                                defaults to
+                                <option>true</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--log-location=</option></term>
+
+                                <listitem><para>Include code location
+                                in log messages. This is mostly
+                                relevant for debugging
+                                purposes. Argument is a boolean
+                                value. If the argument is omitted
+                                it defaults to
+                                <option>true</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><option>--default-standard-output=</option></term>
+                                <term><option>--default-standard-error=</option></term>
+
+                                <listitem><para>Sets the default
+                                output or error output for all
+                                services and sockets, respectively. That is, controls
+                                the default for
+                                <option>StandardOutput=</option>
+                                and <option>StandardError=</option>
+                                (see
+                                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details). Takes one of
+                                <option>inherit</option>,
+                                <option>null</option>,
+                                <option>tty</option>,
+                                <option>journal</option>,
+                                <option>journal+console</option>,
+                                <option>syslog</option>,
+                                <option>syslog+console</option>,
+                                <option>kmsg</option>,
+                                <option>kmsg+console</option>.  If the
+                                argument is omitted
+                                <option>--default-standard-output=</option>
+                                defaults to <option>journal</option>
+                                and
+                                <option>--default-standard-error=</option>
+                                to
+                                <option>inherit</option>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Concepts</title>
+
+                <para>systemd provides a dependency system between
+                various entities called "units". Units encapsulate
+                various objects that are relevant for system boot-up
+                and maintenance. The majority of units are configured
+                in unit configuration files, whose syntax and basic
+                set of options is described in
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                however some are created automatically from other
+                configuration or dynamically from system state. Units
+                may be 'active' (meaning started, bound, plugged in,
+                ...  depending on the unit type, see below), or
+                'inactive' (meaning stopped, unbound, unplugged, ...),
+                as well as in the process of being activated or
+                deactivated, i.e. between the two states (these states
+                are called 'activating', 'deactivating'). A special
+                'failed' state is available as well which is very
+                similar to 'inactive' and is entered when the service
+                failed in some way (process returned error code on
+                exit, or crashed, or an operation timed out). If this
+                state is entered the cause will be logged, for later
+                reference. Note that the various unit types may have a
+                number of additional substates, which are mapped to
+                the five generalized unit states described
+                here.</para>
+
+                <para>The following unit types are available:</para>
+
+                <orderedlist>
+                        <listitem><para>Service units, which control
+                        daemons and the processes they consist of. For
+                        details see
+                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Socket units, which
+                        encapsulate local IPC or network sockets in
+                        the system, useful for socket-based
+                        activation. For details about socket units see
+                        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        for details on socket-based activation and
+                        other forms of activation, see
+                        <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Target units are useful to
+                        group units, or provide well-known
+                        synchronization points during boot-up, see
+                        <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Device units expose kernel
+                        devices in systemd and may be used to
+                        implement device-based activation. For details
+                        see
+                        <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Mount units control mount
+                        points in the file system, for details see
+                        <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Automount units provide
+                        automount capabilities, for on-demand mounting
+                        of file systems as well as parallelized
+                        boot-up. See
+                        <citerefentry><refentrytitle>systemd.automount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Snapshot units can be used to
+                        temporarily save the state of the set of
+                        systemd units, which later may be restored by
+                        activating the saved snapshot unit. For more
+                        information see
+                        <citerefentry><refentrytitle>systemd.snapshot</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Timer units are useful for
+                        triggering activation of other units based on
+                        timers. You may find details in
+                        <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Swap units are very similar to
+                        mount units and encapsulate memory swap
+                        partitions or files of the operating
+                        system. They are described in <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                        <listitem><para>Path units may be used
+                        to activate other services when file system
+                        objects change or are modified. See
+                        <citerefentry><refentrytitle>systemd.path</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+
+                </orderedlist>
+
+                <para>Units are named as their configuration
+                files. Some units have special semantics. A detailed
+                list is available in
+                <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+
+                <para>systemd knows various kinds of dependencies,
+                including positive and negative requirement
+                dependencies (i.e. <varname>Requires=</varname> and
+                <varname>Conflicts=</varname>) as well as ordering
+                dependencies (<varname>After=</varname> and
+                <varname>Before=</varname>). NB: ordering and
+                requirement dependencies are orthogonal. If only a
+                requirement dependency exists between two units
+                (e.g. <filename>foo.service</filename> requires
+                <filename>bar.service</filename>), but no ordering
+                dependency (e.g. <filename>foo.service</filename>
+                after <filename>bar.service</filename>) and both are
+                requested to start, they will be started in
+                parallel. It is a common pattern that both requirement
+                and ordering dependencies are placed between two
+                units. Also note that the majority of dependencies are
+                implicitly created and maintained by systemd. In most
+                cases it should be unnecessary to declare additional
+                dependencies manually, however it is possible to do
+                this.</para>
+
+                <para>Application programs and units (via
+                dependencies) may request state changes of units. In
+                systemd, these requests are encapsulated as 'jobs' and
+                maintained in a job queue. Jobs may succeed or can
+                fail, their execution is ordered based on the ordering
+                dependencies of the units they have been scheduled
+                for.</para>
+
+                <para>On boot systemd activates the target unit
+                <filename>default.target</filename> whose job is to
+                activate on-boot services and other on-boot units by
+                pulling them in via dependencies. Usually the unit
+                name is just an alias (symlink) for either
+                <filename>graphical.target</filename> (for
+                fully-featured boots into the UI) or
+                <filename>multi-user.target</filename> (for limited
+                console-only boots for use in embedded or server
+                environments, or similar; a subset of
+                graphical.target). However it is at the discretion of
+                the administrator to configure it as an alias to any
+                other target unit. See
+                <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                for details about these target units.</para>
+
+                <para>Processes systemd spawns are placed in
+                individual Linux control groups named after the unit
+                which they belong to in the private systemd
+                hierarchy. (see <ulink
+                url="http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt</ulink>
+                for more information about control groups, or short
+                "cgroups"). systemd uses this to effectively keep
+                track of processes. Control group information is
+                maintained in the kernel, and is accessible via the
+                file system hierarchy (beneath
+                <filename>/sys/fs/cgroup/systemd/</filename>), or in tools
+                such as
+                <citerefentry><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                (<command>ps xawf -eo pid,user,cgroup,args</command>
+                is particularly useful to list all processes and the
+                systemd units they belong to.).</para>
+
+                <para>systemd is compatible with the SysV init system
+                to a large degree: SysV init scripts are supported and
+                simply read as an alternative (though limited)
+                configuration file format. The SysV
+                <filename>/dev/initctl</filename> interface is
+                provided, and compatibility implementations of the
+                various SysV client tools are available. In addition to
+                that, various established Unix functionality such as
+                <filename>/etc/fstab</filename> or the
+                <filename>utmp</filename> database are
+                supported.</para>
+
+                <para>systemd has a minimal transaction system: if a
+                unit is requested to start up or shut down it will add
+                it and all its dependencies to a temporary
+                transaction. Then, it will verify if the transaction
+                is consistent (i.e. whether the ordering of all units
+                is cycle-free). If it is not, systemd will try to fix
+                it up, and removes non-essential jobs from the
+                transaction that might remove the loop. Also, systemd
+                tries to suppress non-essential jobs in the
+                transaction that would stop a running service. Finally
+                it is checked whether the jobs of the transaction
+                contradict jobs that have already been queued, and
+                optionally the transaction is aborted then. If all
+                worked out and the transaction is consistent and
+                minimized in its impact it is merged with all already
+                outstanding jobs and added to the run
+                queue. Effectively this means that before executing a
+                requested operation, systemd will verify that it makes
+                sense, fixing it if possible, and only failing if it
+                really cannot work.</para>
+
+                <para>Systemd contains native implementations of
+                various tasks that need to be executed as part of the
+                boot process. For example, it sets the host name or
+                configures the loopback network device. It also sets
+                up and mounts various API file systems, such as
+                <filename>/sys</filename> or
+                <filename>/proc</filename>.</para>
+
+                <para>For more information about the concepts and
+                ideas behind systemd please refer to the <ulink
+                url="http://0pointer.de/blog/projects/systemd.html">Original
+                Design Document</ulink>.</para>
+
+                <para>Note that some but not all interfaces provided
+                by systemd are covered by the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
+                Stability Promise</ulink>.</para>
+
+                <para>Units may be generated dynamically at boot and
+                system manager reload time, for example based on other
+                configuration files or parameters passed on the kernel
+                command line. For details see the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/Generators">Generators
+                Specification</ulink>.</para>
+
+                <para>Systems which invoke systemd in a container
+                or initrd environment should implement the
+                <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
+                Interface</ulink> or <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface">initrd
+                Interface</ulink> specifications, respectively.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Directories</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>System unit directories</term>
+
+                                <listitem><para>The systemd system
+                                manager reads unit configuration from
+                                various directories. Packages that
+                                want to install unit files shall place
+                                them in the directory returned by
+                                <command>pkg-config systemd
+                                --variable=systemdsystemunitdir</command>. Other
+                                directories checked are
+                                <filename>/usr/local/lib/systemd/system</filename>
+                                and
+                                <filename>/usr/lib/systemd/system</filename>. User
+                                configuration always takes
+                                precedence. <command>pkg-config
+                                systemd
+                                --variable=systemdsystemconfdir</command>
+                                returns the path of the system
+                                configuration directory. Packages
+                                should alter the content of these
+                                directories only with the
+                                <command>enable</command> and
+                                <command>disable</command> commands of
+                                the
+                                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                tool.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>User unit directories</term>
+
+                                <listitem><para>Similar rules apply
+                                for the user unit
+                                directories. However, here the <ulink
+                                url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
+                                Base Directory specification</ulink>
+                                is followed to find
+                                units. Applications should place their
+                                unit files in the directory returned
+                                by <command>pkg-config systemd
+                                --variable=systemduserunitdir</command>. Global
+                                configuration is done in the directory
+                                reported by <command>pkg-config
+                                systemd
+                                --variable=systemduserconfdir</command>. The
+                                <command>enable</command> and
+                                <command>disable</command> commands of
+                                the
+                                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                tool can handle both global (i.e. for
+                                all users) and private (for one user)
+                                enabling/disabling of
+                                units.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>SysV init scripts directory</term>
+
+                                <listitem><para>The location of the
+                                SysV init script directory varies
+                                between distributions. If systemd
+                                cannot find a native unit file for a
+                                requested service, it will look for a
+                                SysV init script of the same name
+                                (with the
+                                <filename>.service</filename> suffix
+                                removed).</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>SysV runlevel link farm directory</term>
+
+                                <listitem><para>The location of the
+                                SysV runlevel link farm directory
+                                varies between distributions. systemd
+                                will take the link farm into account
+                                when figuring out whether a service
+                                shall be enabled. Note that a service
+                                unit with a native unit configuration
+                                file cannot be started by activating it
+                                in the SysV runlevel link
+                                farm.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Signals</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term>SIGTERM</term>
+
+                                <listitem><para>Upon receiving this
+                                signal the systemd system manager
+                                serializes its state, reexecutes
+                                itself and deserializes the saved
+                                state again. This is mostly equivalent
+                                to <command>systemctl
+                                daemon-reexec</command>.</para>
+
+                                <para>systemd user managers will
+                                start the
+                                <filename>exit.target</filename> unit
+                                when this signal is received. This is
+                                mostly equivalent to
+                                <command>systemctl --user start
+                                exit.target</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGINT</term>
+
+                                <listitem><para>Upon receiving this
+                                signal the systemd system manager will
+                                start the
+                                <filename>ctrl-alt-del.target</filename> unit. This
+                                is mostly equivalent to
+                                <command>systemctl start
+                                ctl-alt-del.target</command>.</para>
+
+                                <para>systemd user managers
+                                treat this signal the same way as
+                                SIGTERM.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGWINCH</term>
+
+                                <listitem><para>When this signal is
+                                received the systemd system manager
+                                will start the
+                                <filename>kbrequest.target</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl start
+                                kbrequest.target</command>.</para>
+
+                                <para>This signal is ignored by
+                                systemd user
+                                managers.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGPWR</term>
+
+                                <listitem><para>When this signal is
+                                received the systemd manager
+                                will start the
+                                <filename>sigpwr.target</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl start
+                                sigpwr.target</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGUSR1</term>
+
+                                <listitem><para>When this signal is
+                                received the systemd manager will try
+                                to reconnect to the D-Bus
+                                bus.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGUSR2</term>
+
+                                <listitem><para>When this signal is
+                                received the systemd manager will log
+                                its complete state in human readable
+                                form. The data logged is the same as
+                                printed by <command>systemctl
+                                dump</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGHUP</term>
+
+                                <listitem><para>Reloads the complete
+                                daemon configuration. This is mostly
+                                equivalent to <command>systemctl
+                                daemon-reload</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+0</term>
+
+                                <listitem><para>Enters default mode, starts the
+                                <filename>default.target</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl start
+                                default.target</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+1</term>
+
+                                <listitem><para>Enters rescue mode,
+                                starts the
+                                <filename>rescue.target</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl isolate
+                                rescue.target</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+2</term>
+
+                                <listitem><para>Enters emergency mode,
+                                starts the
+                                <filename>emergency.service</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl isolate
+                                emergency.service</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+3</term>
+
+                                <listitem><para>Halts the machine,
+                                starts the
+                                <filename>halt.target</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl start
+                                halt.target</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+4</term>
+
+                                <listitem><para>Powers off the machine,
+                                starts the
+                                <filename>poweroff.target</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl start
+                                poweroff.target</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+5</term>
+
+                                <listitem><para>Reboots the machine,
+                                starts the
+                                <filename>reboot.target</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl start
+                                reboot.target</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+6</term>
+
+                                <listitem><para>Reboots the machine via kexec,
+                                starts the
+                                <filename>kexec.target</filename>
+                                unit. This is mostly equivalent to
+                                <command>systemctl start
+                                kexec.target</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+13</term>
+
+                                <listitem><para>Immediately halts the machine.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+14</term>
+
+                                <listitem><para>Immediately powers off the machine.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+15</term>
+
+                                <listitem><para>Immediately reboots the machine.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+16</term>
+
+                                <listitem><para>Immediately reboots the machine with kexec.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+20</term>
+
+                                <listitem><para>Enables display of
+                                status messages on the console, as
+                                controlled via
+                                <varname>systemd.show_status=1</varname>
+                                on the kernel command
+                                line.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+21</term>
+
+                                <listitem><para>Disables display of
+                                status messages on the console, as
+                                controlled via
+                                <varname>systemd.show_status=0</varname>
+                                on the kernel command
+                                line.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+22</term>
+                                <term>SIGRTMIN+23</term>
+
+                                <listitem><para>Sets the log level to
+                                <literal>debug</literal>
+                                (or <literal>info</literal> on
+                                <literal>SIGRTMIN+23</literal>), as
+                                controlled via
+                                <varname>systemd.log_level=debug</varname>
+                                (or <varname>systemd.log_level=info</varname>
+                                on <literal>SIGRTMIN+23</literal>) on
+                                the kernel command
+                                line.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+24</term>
+
+                                <listitem><para>Immediately exits the
+                                manager (only available for --user
+                                instances).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+26</term>
+                                <term>SIGRTMIN+27</term>
+                                <term>SIGRTMIN+28</term>
+                                <term>SIGRTMIN+29</term>
+
+                                <listitem><para>Sets the log level to
+                                <literal>journal-or-kmsg</literal>
+                                (or <literal>console</literal> on
+                                <literal>SIGRTMIN+27</literal>,
+                                <literal>kmsg</literal> on
+                                <literal>SIGRTMIN+28</literal>,
+                                or <literal>syslog-or-kmsg</literal>
+                                on <literal>SIGRTMIN+29</literal>), as
+                                controlled via
+                                <varname>systemd.log_target=journal-or-kmsg</varname>
+                                (or <varname>systemd.log_target=console</varname>
+                                on <literal>SIGRTMIN+27</literal>,
+                                <varname>systemd.log_target=kmsg</varname>
+                                on <literal>SIGRTMIN+28</literal>,
+                                or
+                                <varname>systemd.log_target=syslog-or-kmsg</varname>
+                                on <literal>SIGRTMIN+29</literal>) on
+                                the kernel command
+                                line.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_LOG_LEVEL</varname></term>
+                                <listitem><para>systemd reads the
+                                log level from this environment
+                                variable. This can be overridden with
+                                <option>--log-level=</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_LOG_TARGET</varname></term>
+                                <listitem><para>systemd reads the
+                                log target from this environment
+                                variable. This can be overridden with
+                                <option>--log-target=</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_LOG_COLOR</varname></term>
+                                <listitem><para>Controls whether
+                                systemd highlights important log
+                                messages. This can be overridden with
+                                <option>--log-color=</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_LOG_LOCATION</varname></term>
+                                <listitem><para>Controls whether
+                                systemd prints the code location along
+                                with log messages. This can be
+                                overridden with
+                                <option>--log-location=</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$XDG_CONFIG_HOME</varname></term>
+                                <term><varname>$XDG_CONFIG_DIRS</varname></term>
+                                <term><varname>$XDG_DATA_HOME</varname></term>
+                                <term><varname>$XDG_DATA_DIRS</varname></term>
+
+                                <listitem><para>The systemd user
+                                manager uses these variables in
+                                accordance to the <ulink
+                                url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
+                                Base Directory specification</ulink>
+                                to find its configuration.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_UNIT_PATH</varname></term>
+
+                                <listitem><para>Controls where systemd
+                                looks for unit
+                                files.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_SYSVINIT_PATH</varname></term>
+
+                                <listitem><para>Controls where systemd
+                                looks for SysV init scripts.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_SYSVRCND_PATH</varname></term>
+
+                                <listitem><para>Controls where systemd
+                                looks for SysV init script runlevel link
+                                farms.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$LISTEN_PID</varname></term>
+                                <term><varname>$LISTEN_FDS</varname></term>
+
+                                <listitem><para>Set by systemd for
+                                supervised processes during
+                                socket-based activation. See
+                                <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                for more information.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>$NOTIFY_SOCKET</varname></term>
+
+                                <listitem><para>Set by systemd for
+                                supervised processes for status and
+                                start-up completion notification. See
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                for more information.
+                                </para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Kernel Command Line</title>
+
+                <para>When run as system instance systemd parses a
+                number of kernel command line
+                arguments<footnote><para>If run inside a Linux
+                container these arguments may be passed as command
+                line arguments to systemd itself, next to any of the
+                command line options listed in the Options section
+                above. If run outside of Linux containers, these
+                arguments are parsed from
+                <filename>/proc/cmdline</filename>
+                instead.</para></footnote>:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>systemd.unit=</varname></term>
+                                <term><varname>rd.systemd.unit=</varname></term>
+
+                                <listitem><para>Overrides the unit to
+                                activate on boot. Defaults to
+                                <filename>default.target</filename>. This
+                                may be used to temporarily boot into a
+                                different boot unit, for example
+                                <filename>rescue.target</filename> or
+                                <filename>emergency.service</filename>. See
+                                <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details about these units. The
+                                option prefixed with
+                                <literal>rd.</literal> is honored
+                                only in the initial RAM disk (initrd),
+                                while the one that isn't prefixed only
+                                in the main system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.dump_core=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                systemd dumps core when it
+                                crashes. Otherwise no core dump is
+                                created. Defaults to
+                                <option>true</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.crash_shell=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                systemd spawns a shell when it
+                                crashes. Otherwise no shell is
+                                spawned. Defaults to
+                                <option>false</option>, for security
+                                reasons, as the shell is not protected
+                                by any password
+                                authentication.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.crash_chvt=</varname></term>
+
+                                <listitem><para>Takes an integer
+                                argument. If positive systemd
+                                activates the specified virtual
+                                terminal when it crashes. Defaults to
+                                <literal>-1</literal>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.confirm_spawn=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                asks for confirmation when spawning
+                                processes. Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.show_status=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option>
+                                shows terse service status updates on
+                                the console during bootup. Defaults to
+                                <option>true</option>, unless
+                                <option>quiet</option> is passed as
+                                kernel command line option in which
+                                case it defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.log_target=</varname></term>
+                                <term><varname>systemd.log_level=</varname></term>
+                                <term><varname>systemd.log_color=</varname></term>
+                                <term><varname>systemd.log_location=</varname></term>
+
+                                <listitem><para>Controls log output,
+                                with the same effect as the
+                                <varname>$SYSTEMD_LOG_TARGET</varname>, <varname>$SYSTEMD_LOG_LEVEL</varname>, <varname>$SYSTEMD_LOG_COLOR</varname>, <varname>$SYSTEMD_LOG_LOCATION</varname>
+                                environment variables described above.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.default_standard_output=</varname></term>
+                                <term><varname>systemd.default_standard_error=</varname></term>
+                                <listitem><para>Controls default
+                                standard output and error output for
+                                services, with the same effect as the
+                                <option>--default-standard-output=</option>
+                                and <option>--default-standard-error=</option>
+                                command line arguments described
+                                above, respectively.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.setenv=</varname></term>
+
+                                <listitem><para>Takes a string
+                                argument in the form
+                                VARIABLE=VALUE. May be used to set
+                                environment variables for the init
+                                process and all its children at boot
+                                time. May be used more than once to
+                                set multiple variables. If the equal
+                                sign and variable are missing it unsets
+                                an environment variable which might be
+                                passed in from the initial ram
+                                disk.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>quiet</varname></term>
+
+                                <listitem><para>If passed turns off
+                                status output at boot, much like
+                                <varname>systemd.show_status=false</varname>
+                                would. Note that this option is also
+                                read by the kernel itself and disables
+                                kernel log output to the
+                                kernel. Passing this option hence
+                                turns off the usual output from both
+                                the system manager and the
+                                kernel.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>emergency</varname></term>
+
+                                <listitem><para>Boot into emergency
+                                mode. This is equivalent to
+                                <varname>systemd.unit=emergency.target</varname>
+                                and provided for compatibility
+                                reasons and to be easier to type.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>single</varname></term>
+                                <term><varname>s</varname></term>
+                                <term><varname>S</varname></term>
+                                <term><varname>1</varname></term>
+
+                                <listitem><para>Boot into rescue
+                                mode. This is equivalent to
+                                <varname>systemd.unit=rescue.target</varname>
+                                and provided for compatibility reasons
+                                and to be easier to
+                                type.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>2</varname></term>
+                                <term><varname>3</varname></term>
+                                <term><varname>4</varname></term>
+                                <term><varname>5</varname></term>
+
+                                <listitem><para>Boot into the
+                                specified legacy SysV runlevel. These
+                                are equivalent to
+                                <varname>systemd.unit=runlevel2.target</varname>,
+                                <varname>systemd.unit=runlevel3.target</varname>,
+                                <varname>systemd.unit=runlevel4.target</varname>,
+                                and <varname>systemd.unit=runlevel5.target</varname>, respectively,
+                                and provided for compatibility reasons
+                                and to be easier to
+                                type.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>locale.LANG=</varname></term>
+                                <term><varname>locale.LANGUAGE=</varname></term>
+                                <term><varname>locale.LC_CTYPE=</varname></term>
+                                <term><varname>locale.LC_NUMERIC=</varname></term>
+                                <term><varname>locale.LC_TIME=</varname></term>
+                                <term><varname>locale.LC_COLLATE=</varname></term>
+                                <term><varname>locale.LC_MONETARY=</varname></term>
+                                <term><varname>locale.LC_MESSAGES=</varname></term>
+                                <term><varname>locale.LC_PAPER=</varname></term>
+                                <term><varname>locale.LC_NAME=</varname></term>
+                                <term><varname>locale.LC_ADDRESS=</varname></term>
+                                <term><varname>locale.LC_TELEPHONE=</varname></term>
+                                <term><varname>locale.LC_MEASUREMENT=</varname></term>
+                                <term><varname>locale.LC_IDENTIFICATION=</varname></term>
+
+                                <listitem><para>Set the system locale
+                                to use. This overrides the settings in
+                                <filename>/etc/locale.conf</filename>. For
+                                more information see
+                                <citerefentry><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                and
+                                <citerefentry><refentrytitle>locale</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+                                </para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>For other kernel command line parameters
+                understood by components of the core OS, please refer
+                to
+                <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Sockets and FIFOs</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>/run/systemd/notify</filename></term>
+
+                                <listitem><para>Daemon status
+                                notification socket. This is an
+                                AF_UNIX datagram socket and is used to
+                                implement the daemon notification
+                                logic as implemented by
+                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/run/systemd/shutdownd</filename></term>
+
+                                <listitem><para>Used internally by the
+                                <citerefentry><refentrytitle>shutdown</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                tool to implement delayed
+                                shutdowns. This is an AF_UNIX datagram
+                                socket.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/run/systemd/private</filename></term>
+
+                                <listitem><para>Used internally as
+                                communication channel between
+                                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                and the systemd process. This is an
+                                AF_UNIX stream socket. This interface
+                                is private to systemd and should not
+                                be used in external
+                                projects.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/dev/initctl</filename></term>
+
+                                <listitem><para>Limited compatibility
+                                support for the SysV client interface,
+                                as implemented by the
+                                <filename>systemd-initctl.service</filename>
+                                unit. This is a named pipe in the file
+                                system. This interface is obsolete and
+                                should not be used in new
+                                applications.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-notify</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/telinit.xml b/man/telinit.xml
new file mode 100644 (file)
index 0000000..4c6064f
--- /dev/null
@@ -0,0 +1,195 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="telinit">
+
+        <refentryinfo>
+                <title>telinit</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>telinit</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>telinit</refname>
+                <refpurpose>Change SysV runlevel</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>telinit <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>telinit</command> may be used to change
+                the SysV system runlevel. Since the concept of SysV
+                runlevels is obsolete the runlevel requests
+                will be transparently translated into systemd unit
+                activation requests.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-wall</option></term>
+
+                                <listitem><para>Don't send wall
+                                message before
+                                reboot/halt/power-off.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>The following commands are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><command>0</command></term>
+
+                                <listitem><para>Power-off the
+                                machine. This is translated into an
+                                activation request for
+                                <filename>poweroff.target</filename>
+                                and is equivalent to
+                                <command>systemctl
+                                poweroff</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>6</command></term>
+
+                                <listitem><para>Reboot the
+                                machine. This is translated into an
+                                activation request for
+                                <filename>reboot.target</filename> and
+                                is equivalent to <command>systemctl
+                                reboot</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>2</command></term>
+                                <term><command>3</command></term>
+                                <term><command>4</command></term>
+                                <term><command>5</command></term>
+
+                                <listitem><para>Change the SysV
+                                runlevel. This is translated into an
+                                activation request for
+                                <filename>runlevel2.target</filename>,
+                                <filename>runlevel3.target</filename>,
+                                ... and is equivalent to
+                                <command>systemctl isolate
+                                runlevel2.target</command>,
+                                <command>systemctl isolate
+                                runlevel3.target</command>,
+                                ...</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>1</command></term>
+                                <term><command>s</command></term>
+                                <term><command>S</command></term>
+
+                                <listitem><para>Change into system
+                                rescue mode. This is translated into
+                                an activation request for
+                                <filename>rescue.target</filename> and
+                                is equivalent to <command>systemctl
+                                rescue</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>q</command></term>
+                                <term><command>Q</command></term>
+
+                                <listitem><para>Reload daemon
+                                configuration. This is equivalent to
+                                <command>systemctl
+                                daemon-reload</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>u</command></term>
+                                <term><command>U</command></term>
+
+                                <listitem><para>Serialize state,
+                                reexecute daemon and deserialize state
+                                again. This is equivalent to
+                                <command>systemctl
+                                daemon-reexec</command>.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Notes</title>
+
+                <para>This is a legacy command available for compatibility
+                only. It should not be used anymore, as the concept of
+                runlevels is obsolete.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/timedatectl.xml b/man/timedatectl.xml
new file mode 100644 (file)
index 0000000..01ca0a7
--- /dev/null
@@ -0,0 +1,293 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="timedatectl">
+
+        <refentryinfo>
+                <title>timedatectl</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>timedatectl</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>timedatectl</refname>
+                <refpurpose>Control the system time and date</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>timedatectl <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>timedatectl</command> may be used to
+                query and change the system clock and its
+                settings.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--help</option></term>
+                                <term><option>-h</option></term>
+
+                                <listitem><para>Prints a short help
+                                text and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--version</option></term>
+
+                                <listitem><para>Prints a short version
+                                string and exits.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+                                <listitem><para>Do not pipe output into a
+                                pager.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--no-ask-password</option></term>
+
+                                <listitem><para>Don't query the user
+                                for authentication for privileged
+                                operations.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-H</option></term>
+                                <term><option>--host</option></term>
+
+                                <listitem><para>Execute the operation
+                                remotely. Specify a hostname, or
+                                username and hostname separated by @,
+                                to connect to. This will use SSH to
+                                talk to a remote
+                                system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--adjust-system-clock</option></term>
+
+                                <listitem><para>If
+                                <command>set-local-rtc</command> is
+                                invoked and this option is passed the
+                                system clock is synchronized from the
+                                RTC again, taking the new setting into
+                                account. Otherwise the RTC is
+                                synchronized from the system
+                                clock.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+
+                <para>The following commands are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><command>status</command></term>
+
+                                <listitem><para>Show current settings
+                                of the system clock and
+                                RTC.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-time [TIME]</command></term>
+
+                                <listitem><para>Set the system clock
+                                to the specified time. This will also
+                                update the RTC time accordingly. The time
+                                may be specified in the format
+                                "2012-10-30
+                                18:17:16".</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-timezone [TIMEZONE]</command></term>
+
+                                <listitem><para>Set the system time
+                                zone to the specified value. Available
+                                time zones can be listed with
+                                <command>list-timezones</command>. If
+                                the RTC is configured to be in the
+                                local time this will also update the
+                                RTC time. This call will alter the
+                                <filename>/etc/localtime</filename>
+                                symlink. See
+                                <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for more
+                                information.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>list-timezones</command></term>
+
+                                <listitem><para>List available time
+                                zones, one per line. Entries from the
+                                list can be set as the system
+                                time zone with
+                                <command>set-timezone</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-local-rtc [BOOL]</command></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <literal>0</literal> the
+                                system is configured to maintain the
+                                RTC in universal time, if
+                                <literal>1</literal> it will maintain
+                                the RTC in local time instead. Note
+                                that maintaining the RTC in the local
+                                time zone is not fully supported and
+                                will create various problems with time
+                                zone changes and daylight saving
+                                adjustments. If at all possible use
+                                RTC in UTC. Note that invoking this
+                                will also synchronize the RTC from the
+                                system clock, unless
+                                <option>--adjust-system-clock</option> is
+                                passed (see above). This command will
+                                change the 3rd line of
+                                <filename>/etc/adjtime</filename>, as
+                                documented in
+                                <citerefentry><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-ntp [BOOL]</command></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. Controls whether NTP based
+                                network time synchronization is
+                                enabled (if
+                                available).</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Environment</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><varname>$SYSTEMD_PAGER</varname></term>
+                                <listitem><para>Pager to use when
+                                <option>--no-pager</option> is not given;
+                                overrides <varname>$PAGER</varname>.  Setting
+                                this to an empty string or the value
+                                <literal>cat</literal> is equivalent to passing
+                                <option>--no-pager</option>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+                <para>Show current settings:
+                <programlisting>
+$ timedatectl
+      Local time: Fri, 2012-11-02 09:26:46 CET
+  Universal time: Fri, 2012-11-02 08:26:46 UTC
+        RTC time: Fri, 2012-11-02 08:26:45
+        Timezone: Europe/Warsaw
+      UTC offset: +0100
+     NTP enabled: no
+NTP synchronized: no
+ RTC in local TZ: no
+      DST active: no
+ Last DST change: CEST → CET, DST became inactive
+                  Sun, 2012-10-28 02:59:59 CEST
+                  Sun, 2012-10-28 02:00:00 CET
+ Next DST change: CET → CEST, DST will become active
+                  the clock will jump one hour forward
+                  Sun, 2013-03-31 01:59:59 CET
+                  Sun, 2013-03-31 03:00:00 CEST
+                </programlisting>
+                </para>
+
+                <para>Enable an NTP daemon (chronyd):
+                <programlisting>
+$ timedatectl set-ntp true
+==== AUTHENTICATING FOR org.freedesktop.timedate1.set-ntp ===
+Authentication is required to control whether network time synchronization shall be enabled.
+Authenticating as: user
+Password: ********
+==== AUTHENTICATION COMPLETE ===
+                </programlisting>
+
+                <programlisting>
+$ systemctl status chronyd.service
+chronyd.service - NTP client/server
+          Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled)
+          Active: active (running) since Fri, 2012-11-02 09:36:25 CET; 5s ago
+...
+                </programlisting>
+                </para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>date</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-timedated.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
new file mode 100644 (file)
index 0000000..785264e
--- /dev/null
@@ -0,0 +1,321 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Brandon Philips
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="tmpfiles.d">
+
+        <refentryinfo>
+                <title>tmpfiles.d</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Documentation</contrib>
+                                <firstname>Brandon</firstname>
+                                <surname>Philips</surname>
+                                <email>brandon@ifup.org</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>tmpfiles.d</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>tmpfiles.d</refname>
+                <refpurpose>Configuration for creation, deletion and
+                cleaning of volatile and temporary files</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/tmpfiles.d/*.conf</filename></para>
+                <para><filename>/run/tmpfiles.d/*.conf</filename></para>
+                <para><filename>/usr/lib/tmpfiles.d/*.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-tmpfiles</command> uses the
+                configuration files from the above directories to describe the
+                creation, cleaning and removal of volatile and
+                temporary files and directories which usually reside
+                in directories such as <filename>/run</filename>
+                or <filename>/tmp</filename>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Configuration Format</title>
+
+                <para>Each configuration file shall be named in the
+                style of <filename>&lt;program&gt;.conf</filename>.
+                Files in <filename>/etc/</filename> override files
+                with the same name in <filename>/usr/lib/</filename>
+                and <filename>/run/</filename>.  Files in
+                <filename>/run/</filename> override files with the same
+                name in <filename>/usr/lib/</filename>. Packages
+                should install their configuration files in
+                <filename>/usr/lib/</filename>. Files in
+                <filename>/etc/</filename> are reserved for the local
+                administrator, who may use this logic to override the
+                configuration files installed by vendor packages. All
+                configuration files are sorted by their filename in
+                alphabetical order, regardless in which of the
+                directories they reside, to guarantee that a specific
+                configuration file takes precedence over another file
+                with an alphabetically later name.</para>
+
+                <para>If the administrator wants to disable a
+                configuration file supplied by the vendor the
+                recommended way is to place a symlink to
+                <filename>/dev/null</filename> in
+                <filename>/etc/tmpfiles.d/</filename> bearing the
+                same file name.</para>
+
+                <para>The configuration format is one line per path
+                containing action, path, mode, ownership, age and argument
+                fields:</para>
+
+                <programlisting>Type Path        Mode UID  GID  Age Argument
+d    /run/user   0755 root root 10d -
+L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
+
+                <refsect2>
+                        <title>Type</title>
+                        <variablelist>
+                                <varlistentry>
+                                        <term><varname>f</varname></term>
+                                        <listitem><para>Create a file if it doesn't exist yet (optionally writing a short string into it, if the argument parameter is passed)</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>F</varname></term>
+                                        <listitem><para>Create or truncate a file (optionally writing a short string into it, if the argument parameter is passed)</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>w</varname></term>
+                                        <listitem><para>Write the argument parameter to a file, if the file exists.
+                                            Lines of this type accept shell-style globs in place of normal path
+                                            names. The argument parameter will be written without a trailing
+                                            newline. C-style backslash escapes are interpreted.</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>d</varname></term>
+                                        <listitem><para>Create a directory if it doesn't exist yet</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>D</varname></term>
+                                        <listitem><para>Create or empty a directory</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>p</varname></term>
+                                        <listitem><para>Create a named pipe (FIFO) if it doesn't exist yet</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>L</varname></term>
+                                        <listitem><para>Create a symlink if it doesn't exist yet</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>c</varname></term>
+                                        <listitem><para>Create a character device node if it doesn't exist yet</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>b</varname></term>
+                                        <listitem><para>Create a block device node if it doesn't exist yet</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>x</varname></term>
+                                        <listitem><para>Ignore a path
+                                        during cleaning. Use this type
+                                        to exclude paths from clean-up
+                                        as controlled with the Age
+                                        parameter. Note that lines of
+                                        this type do not influence the
+                                        effect of r or R lines. Lines
+                                        of this type accept
+                                        shell-style globs in place of
+                                        normal path
+                                        names.</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>r</varname></term>
+                                        <listitem><para>Remove a file
+                                        or directory if it
+                                        exists. This may not be used
+                                        to remove non-empty
+                                        directories, use R for
+                                        that. Lines of this type
+                                        accept shell-style globs in
+                                        place of normal path
+                                        names.</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>R</varname></term>
+                                        <listitem><para>Recursively
+                                        remove a path and all its
+                                        subdirectories (if it is a
+                                        directory). Lines of this type
+                                        accept shell-style globs in
+                                        place of normal path
+                                        names.</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>z</varname></term>
+                                        <listitem><para>Restore
+                                        SELinux security context label
+                                        and set ownership and access
+                                        mode of a file or directory if
+                                        it exists.  Lines of this type
+                                        accept shell-style globs in
+                                        place of normal path names.
+                                        </para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>Z</varname></term>
+                                        <listitem><para>Recursively
+                                        restore SELinux security
+                                        context label and set
+                                        ownership and access mode of a
+                                        path and all its
+                                        subdirectories (if it is a
+                                        directory). Lines of this type
+                                        accept shell-style globs in
+                                        place of normal path
+                                        names.</para></listitem>
+                                </varlistentry>
+                        </variablelist>
+                </refsect2>
+
+                <refsect2>
+                        <title>Mode</title>
+
+                        <para>The file access mode to use when
+                        creating this file or directory. If omitted or
+                        when set to - the default is used: 0755 for
+                        directories, 0644 for all other file
+                        objects. For z, Z lines if omitted or when set
+                        to - the file access mode will not be
+                        modified. This parameter is ignored for x, r,
+                        R, L lines.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>UID, GID</title>
+
+                        <para>The user and group to use for this file
+                        or directory. This may either be a numeric
+                        user/group ID or a user or group name. If
+                        omitted or when set to - the default 0 (root)
+                        is used. For z, Z lines when omitted or when set to -
+                        the file ownership will not be modified.
+                        These parameters are ignored for x, r, R, L lines.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>Age</title>
+                        <para>The date field, when set, is used to
+                        decide what files to delete when cleaning. If
+                        a file or directory is older than the current
+                        time minus the age field it is deleted. The
+                        field format is a series of integers each
+                        followed by one of the following
+                        postfixes for the respective time units:</para>
+
+                        <variablelist>
+                                <varlistentry>
+                                <term><varname>s</varname></term>
+                                <term><varname>min</varname></term>
+                                <term><varname>h</varname></term>
+                                <term><varname>d</varname></term>
+                                <term><varname>w</varname></term>
+                                <term><varname>ms</varname></term>
+                                <term><varname>m</varname></term>
+                                <term><varname>us</varname></term></varlistentry>
+                        </variablelist>
+
+                        <para>If multiple integers and units are specified the time
+                        values are summed up. If an integer is given without a unit,
+                        s is assumed.
+                        </para>
+
+                        <para>When the age is set to zero, the files are cleaned
+                        unconditionally.</para>
+
+                        <para>The age field only applies to lines starting with
+                        d, D and x. If omitted or set to - no automatic clean-up
+                        is done.</para>
+
+                        <para>If the age field starts with a tilde
+                        character (~) the clean-up is only applied to
+                        files and directories one level inside the
+                        directory specified, but not the files and
+                        directories immediately inside it.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>Argument</title>
+
+                        <para>For L lines determines the destination
+                        path of the symlink. For c, b determines the
+                        major/minor of the device node, with major and
+                        minor formatted as integers, separated by :,
+                        e.g. "1:3". For f, F, w may be used to specify
+                        a short string that is written to the file,
+                        suffixed by a newline. Ignored for all other
+                        lines.</para>
+                </refsect2>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+                <example>
+                        <title>/etc/tmpfiles.d/screen.conf example</title>
+                        <para><command>screen</command> needs two directories created at boot with specific modes and ownership.</para>
+
+                        <programlisting>d /var/run/screens  1777 root root 10d
+d /var/run/uscreens 0755 root root 10d12h</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/udev.xml b/man/udev.xml
new file mode 100644 (file)
index 0000000..7ec7a3f
--- /dev/null
@@ -0,0 +1,705 @@
+<?xml version='1.0'?>
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="udev">
+  <refentryinfo>
+    <title>udev</title>
+    <productname>systemd</productname>
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Greg</firstname>
+        <surname>Kroah-Hartmann</surname>
+        <email>greg@kroah.com</email>
+      </author>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Kay</firstname>
+        <surname>Sievers</surname>
+        <email>kay@vrfy.org</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>udev</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>udev</refname>
+    <refpurpose>Linux dynamic device management</refpurpose>
+  </refnamediv>
+
+  <refsect1><title>Description</title>
+    <para>udev supplies the system software with device events, manages permissions
+    of device nodes and may create additional symlinks in the <filename>/dev</filename>
+    directory, or renames network interfaces. The kernel usually just assigns unpredictable
+    device names based on the order of discovery. Meaningful symlinks or network device
+    names provide a way to reliably identify devices based on their properties or
+    current configuration.</para>
+
+    <para>The udev daemon, <citerefentry><refentrytitle>systemd-udevd.service</refentrytitle>
+    <manvolnum>8</manvolnum></citerefentry>, receives device uevents directly from
+    the kernel whenever a device is added or removed from the system, or it changes its
+    state. When udev receives a device event, it matches its configured set of rules
+    against various device attributes to identify the device. Rules that match may
+    provide additional device information to be stored in the udev database or
+    to be used to create meaningful symlink names.</para>
+
+    <para>All device information udev processes is stored in the udev database and
+    sent out to possible event subscribers. Access to all stored data and the event
+    sources is provided by the library libudev.</para>
+  </refsect1>
+
+  <refsect1><title>Configuration</title>
+    <para>udev configuration files are placed in <filename>/etc/udev</filename>
+    and <filename>/usr/lib/udev</filename>. All empty lines or lines beginning with
+    '#' are ignored.</para>
+
+    <refsect2><title>Configuration file</title>
+      <para>udev expects its main configuration file at <filename>/etc/udev/udev.conf</filename>.
+      It consists of a set of variables allowing the user to override default udev values.
+      The following variables can be set:</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>udev_log</option></term>
+          <listitem>
+            <para>The logging priority. Valid values are the numerical syslog priorities
+            or their textual representations: <option>err</option>, <option>info</option>
+            and <option>debug</option>.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2><title>Rules files</title>
+      <para>The udev rules are read from the files located in the
+      system rules directory <filename>/usr/lib/udev/rules.d</filename>,
+      the volatile runtime directory <filename>/run/udev/rules.d</filename>
+      and the local administration directory <filename>/etc/udev/rules.d</filename>.
+      All rules files are collectively sorted and processed in lexical order,
+      regardless of the directories in which they live. However, files with
+      identical file names replace each other. Files in <filename>/etc</filename>
+      have the highest priority, files in <filename>/run</filename> take precedence
+      over files with the same name in <filename>/lib</filename>. This can be
+      used to override a system-supplied rules file with a local file if needed;
+      a symlink in <filename>/etc</filename> with the same name as a rules file in
+      <filename>/lib</filename>, pointing to <filename>/dev/null</filename>,
+      disables the rules file entirely.</para>
+
+      <para>Rule files must have the extension <filename>.rules</filename>; other
+      extensions are ignored.</para>
+
+      <para>Every line in the rules file contains at least one key-value pair.
+      There are two kinds of keys: match and assignment.
+      If all match keys are matching against its value, the rule gets applied and the
+      assignment keys get the specified value assigned.</para>
+
+      <para>A matching rule may rename a network interface, add symlinks
+      pointing to the device node, or run a specified program as part of
+      the event handling.</para>
+
+      <para>A rule consists of a comma-separated list of one or more key-value pairs.
+      Each key has a distinct operation, depending on the used operator. Valid
+      operators are:</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>==</option></term>
+          <listitem>
+            <para>Compare for equality.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>!=</option></term>
+          <listitem>
+            <para>Compare for inequality.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>=</option></term>
+          <listitem>
+            <para>Assign a value to a key. Keys that represent a list are reset
+            and only this single value is assigned.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>+=</option></term>
+          <listitem>
+            <para>Add the value to a key that holds a list of entries.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>:=</option></term>
+          <listitem>
+            <para>Assign  a  value  to  a key finally; disallow any later changes.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <para>The following key names can be used to match against device properties.
+      Some of the keys also match against properties of the parent devices in sysfs,
+      not only the device that has generated the event. If multiple keys that match
+      a parent device are specified in a single rule, all these keys must match at
+      one and the same parent device.</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>ACTION</option></term>
+          <listitem>
+            <para>Match the name of the event action.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>DEVPATH</option></term>
+          <listitem>
+            <para>Match the devpath of the event device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>KERNEL</option></term>
+          <listitem>
+            <para>Match the name of the event device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>NAME</option></term>
+          <listitem>
+            <para>Match the name of a network interface. It can be used once the
+            NAME key has been set in one of the preceding rules.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>SYMLINK</option></term>
+          <listitem>
+            <para>Match the name of a symlink targeting the node. It can
+            be used once a SYMLINK key has been set in one of the preceding
+            rules. There may be multiple symlinks; only one needs to match.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>SUBSYSTEM</option></term>
+          <listitem>
+            <para>Match the subsystem of the event device.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>DRIVER</option></term>
+          <listitem>
+            <para>Match the driver name of the event device. Only set this key for devices
+            which are bound to a driver at the time the event is generated.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>ATTR{<replaceable>filename</replaceable>}</option></term>
+          <listitem>
+            <para>Match sysfs attribute values of the event device. Trailing
+            whitespace in the attribute values is ignored unless the specified match
+            value itself contains trailing whitespace.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>KERNELS</option></term>
+          <listitem>
+            <para>Search the devpath upwards for a matching device name.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>SUBSYSTEMS</option></term>
+          <listitem>
+            <para>Search the devpath upwards for a matching device subsystem name.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>DRIVERS</option></term>
+          <listitem>
+            <para>Search the devpath upwards for a matching device driver name.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>ATTRS{<replaceable>filename</replaceable>}</option></term>
+          <listitem>
+            <para>Search the devpath upwards for a device with matching sysfs attribute values.
+            If multiple <option>ATTRS</option> matches are specified, all of them
+            must match on the same device. Trailing whitespace in the attribute values is ignored
+            unless the specified match value itself contains trailing whitespace.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>TAGS</option></term>
+          <listitem>
+            <para>Search the devpath upwards for a device with matching tag.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>ENV{<replaceable>key</replaceable>}</option></term>
+          <listitem>
+            <para>Match against a device property value.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>TAG</option></term>
+          <listitem>
+            <para>Match against a device tag.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>TEST{<replaceable>octal mode mask</replaceable>}</option></term>
+          <listitem>
+            <para>Test the existence of a file. An octal mode mask can be specified
+            if needed.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>PROGRAM</option></term>
+          <listitem>
+            <para>Execute a program to determine whether there
+            is a match; the key is true if the program returns
+            successfully. The device properties are made available to the
+            executed program in the environment. The program's stdout
+            is available in the RESULT key.</para>
+            <para>This can only be used for very short-running foreground tasks. For details
+            see <option>RUN</option>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>RESULT</option></term>
+          <listitem>
+            <para>Match the returned string of the last PROGRAM call. This key can
+            be used in the same or in any later rule after a PROGRAM call.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <para>Most of the fields support shell-style pattern matching. The following
+      pattern characters are supported:</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>*</option></term>
+          <listitem>
+            <para>Matches zero or more characters.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>?</option></term>
+          <listitem>
+            <para>Matches any single character.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>[]</option></term>
+          <listitem>
+            <para>Matches any single character specified within the brackets. For
+            example, the pattern string 'tty[SR]' would match either 'ttyS' or 'ttyR'.
+            Ranges are also supported via the '-' character.
+            For example, to match on the range of all digits, the pattern [0-9] could
+            be used. If the first character following the '[' is a '!', any characters
+            not enclosed are matched.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <para>The following keys can get values assigned:</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>NAME</option></term>
+          <listitem>
+            <para>The name to use for a network interface. The name of a device node
+            cannot be changed by udev, only additional symlinks can be created.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>SYMLINK</option></term>
+          <listitem>
+            <para>The name of a symlink targeting the node. Every matching rule adds
+            this value to the list of symlinks to be created.</para>
+            <para>The set of characters to name a symlink is limited. Allowed
+            characters are [0-9A-Za-z#+-.:=@_/], valid utf8 character sequences,
+            and "\x00" hex encoding. All other characters are replaced by
+            a '_' character.</para>
+            <para>Multiple symlinks may be specified by separating the names by the
+            space character. In case multiple devices claim the same name, the link
+            always points to the device with the highest link_priority. If the current
+            device goes away, the links are re-evaluated and the device with the
+            next highest link_priority becomes the owner of the link. If no
+            link_priority is specified, the order of the devices (and which one of
+            them owns the link) is undefined.</para>
+            <para>Symlink names must never conflict with the kernel's default device
+            node names, as that would result in unpredictable behavior.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>OWNER, GROUP, MODE</option></term>
+          <listitem>
+            <para>The permissions for the device node. Every specified value overrides
+            the compiled-in default value.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>ATTR{<replaceable>key</replaceable>}</option></term>
+          <listitem>
+            <para>The value that should be written to a sysfs attribute of the
+            event device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>ENV{<replaceable>key</replaceable>}</option></term>
+          <listitem>
+            <para>Set a device property value. Property names with a leading '.'
+            are neither stored in the database nor exported to events or
+            external tools (run by, say, the PROGRAM match key).</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>TAG</option></term>
+          <listitem>
+            <para>Attach a tag to a device. This is used to filter events for users
+            of libudev's monitor functionality, or to enumerate a group of tagged
+            devices. The implementation can only work efficiently if only a few
+            tags are attached to a device. It is only meant to be used in
+            contexts with specific device filter requirements, and not as a
+            general-purpose flag. Excessive use might result in inefficient event
+            handling.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>RUN</option></term>
+          <listitem>
+            <para>Add a program to the list of programs to be executed for a specific
+            device.</para>
+            <para>If no absolute path is given, the program is expected to live in
+            /usr/lib/udev, otherwise the absolute path must be specified. The program
+            name and following arguments are separated by spaces. Single quotes can
+            be used to specify arguments with spaces.</para>
+            <para>This can only be used for very short-running foreground tasks. Running an
+            event process for a long period of time may block all further events for
+            this or a dependent device.</para>
+            <para>Starting daemons or other long running processes is not appropriate
+            for udev; the forked processes, detached or not, will be unconditionally
+            killed after the event handling has finished.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>LABEL</option></term>
+          <listitem>
+            <para>A named label to which a GOTO may jump.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>GOTO</option></term>
+          <listitem>
+            <para>Jumps to the next LABEL with a matching name.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>IMPORT{<replaceable>type</replaceable>}</option></term>
+          <listitem>
+            <para>Import a set of variables as device properties,
+            depending on <replaceable>type</replaceable>:</para>
+            <variablelist>
+              <varlistentry>
+                <term><option>program</option></term>
+                <listitem>
+                  <para>Execute an external program specified as the assigned value and
+                  import its output, which must be in environment key
+                  format. Path specification, command/argument separation,
+                  and quoting work like in <option>RUN</option>.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>file</option></term>
+                <listitem>
+                  <para>Import a text file specified as the assigned value, the content
+                  of which must be in environment key format.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>db</option></term>
+                <listitem>
+                  <para>Import a single property specified as the assigned value from the
+                  current device database. This works only if the database is already populated
+                  by an earlier event.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>cmdline</option></term>
+                <listitem>
+                  <para>Import a single property from the kernel command line. For simple flags
+                  the value of the property is set to '1'.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>parent</option></term>
+                <listitem>
+                  <para>Import the stored keys from the parent device by reading
+                  the database entry of the parent device. The value assigned to
+                  <option>IMPORT{parent}</option> is used as a filter of key names
+                  to import (with the same shell-style pattern matching used for
+                  comparisons).</para>
+                </listitem>
+              </varlistentry>
+            </variablelist>
+            <para>This can only be used for very short-running foreground tasks. For details
+            see <option>RUN</option>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>WAIT_FOR</option></term>
+          <listitem>
+            <para>Wait for a file to become available or until a timeout of
+            10 seconds expires. The path is relative to the sysfs device;
+            if no path is specified, this waits for an attribute to appear.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>OPTIONS</option></term>
+          <listitem>
+            <para>Rule and device options:</para>
+            <variablelist>
+              <varlistentry>
+                <term><option>link_priority=<replaceable>value</replaceable></option></term>
+                <listitem>
+                  <para>Specify the priority of the created symlinks. Devices with higher
+                  priorities overwrite existing symlinks of other devices. The default is 0.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>event_timeout=</option></term>
+                <listitem>
+                  <para>Number of seconds an event waits for operations to finish before
+                  giving up and terminating itself.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>string_escape=<replaceable>none|replace</replaceable></option></term>
+                <listitem>
+                  <para>Usually control and other possibly unsafe characters are replaced
+                  in strings used for device naming. The mode of replacement can be specified
+                  with this option.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>static_node=</option></term>
+                <listitem>
+                  <para>Apply the permissions specified in this rule to the static device node with
+                  the specified name. Static device node creation can be requested by kernel modules.
+                  These nodes might not have a corresponding kernel device at the time systemd-udevd is
+                  started; they can trigger automatic kernel module loading.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>watch</option></term>
+                <listitem>
+                  <para>Watch the device node with inotify; when the node is closed after being opened for
+                  writing, a change uevent is synthesized.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>nowatch</option></term>
+                <listitem>
+                  <para>Disable the watching of a device node with inotify.</para>
+                </listitem>
+              </varlistentry>
+            </variablelist>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <para>The <option>NAME</option>, <option>SYMLINK</option>, <option>PROGRAM</option>,
+      <option>OWNER</option>, <option>GROUP</option>, <option>MODE</option>  and  <option>RUN</option>
+      fields support simple string substitutions. The <option>RUN</option>
+      substitutions are performed after all rules have been processed, right before the program
+      is executed, allowing for the use of device properties set by earlier matching
+      rules. For all other fields, substitutions are performed while the individual rule is
+      being processed. The available substitutions are:</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>$kernel</option>, <option>%k</option></term>
+          <listitem>
+            <para>The kernel name for this device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$number</option>, <option>%n</option></term>
+          <listitem>
+            <para>The kernel number for this device. For example, 'sda3' has
+            kernel number of '3'</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$devpath</option>, <option>%p</option></term>
+          <listitem>
+            <para>The devpath of the device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$id</option>, <option>%b</option></term>
+          <listitem>
+            <para>The name of the device matched while searching the devpath upwards for
+              <option>SUBSYSTEMS</option>, <option>KERNELS</option>, <option>DRIVERS</option> and <option>ATTRS</option>.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$driver</option></term>
+          <listitem>
+            <para>The driver name of the device matched while searching the devpath upwards for
+              <option>SUBSYSTEMS</option>, <option>KERNELS</option>, <option>DRIVERS</option> and <option>ATTRS</option>.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$attr{<replaceable>file</replaceable>}</option>, <option>%s{<replaceable>file</replaceable>}</option></term>
+          <listitem>
+            <para>The value of a sysfs attribute found at the device where
+            all keys of the rule have matched. If the matching device does not have
+            such an attribute, and a previous KERNELS, SUBSYSTEMS, DRIVERS, or
+            ATTRS test selected a parent device, then the attribute from that
+            parent device is used.</para>
+            <para>If the attribute is a symlink, the last element of the symlink target is
+            returned as the value.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$env{<replaceable>key</replaceable>}</option>, <option>%E{<replaceable>key</replaceable>}</option></term>
+          <listitem>
+            <para>A device property value.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$major</option>, <option>%M</option></term>
+          <listitem>
+            <para>The kernel major number for the device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$minor</option>, <option>%m</option></term>
+          <listitem>
+            <para>The kernel minor number for the device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$result</option>, <option>%c</option></term>
+          <listitem>
+            <para>The string returned by the external program requested with PROGRAM.
+            A single part of the string, separated by a space character, may be selected
+            by specifying the part number as an attribute: <option>%c{N}</option>.
+            If the number is followed by the '+' character, this part plus all remaining parts
+            of the result string are substituted: <option>%c{N+}</option></para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$parent</option>, <option>%P</option></term>
+          <listitem>
+            <para>The node name of the parent device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$name</option></term>
+          <listitem>
+            <para>The current name of the device. If not changed by a rule, it is the
+            name of the kernel device.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$links</option></term>
+          <listitem>
+            <para>A space-separated list of the current symlinks. The value is
+            only set during a remove event or if an earlier rule assigned a value.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$root</option>, <option>%r</option></term>
+          <listitem>
+            <para>The udev_root value.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$sys</option>, <option>%S</option></term>
+          <listitem>
+            <para>The sysfs mount point.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$devnode</option>, <option>%N</option></term>
+          <listitem>
+            <para>The name of the device node.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>%%</option></term>
+          <listitem>
+          <para>The '%' character itself.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>$$</option></term>
+          <listitem>
+          <para>The '$' character itself.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para><citerefentry>
+        <refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum>
+    </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/man/udevadm.xml b/man/udevadm.xml
new file mode 100644 (file)
index 0000000..7791028
--- /dev/null
@@ -0,0 +1,495 @@
+<?xml version='1.0'?>
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="udevadm">
+  <refentryinfo>
+    <title>udevadm</title>
+    <productname>systemd</productname>
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Kay</firstname>
+        <surname>Sievers</surname>
+        <email>kay@vrfy.org</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>udevadm</refentrytitle>
+    <manvolnum>8</manvolnum>
+    <refmiscinfo class="version"></refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>udevadm</refname><refpurpose>udev management tool</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>udevadm</command>
+        <arg><option>--debug</option></arg>
+        <arg><option>--version</option></arg>
+        <arg><option>--help</option></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>udevadm info <replaceable>options</replaceable></command>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>udevadm trigger <optional>options</optional></command>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>udevadm settle <optional>options</optional></command>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>udevadm control <replaceable>command</replaceable></command>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>udevadm monitor <optional>options</optional></command>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>udevadm hwdb <optional>options</optional></command>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>udevadm test <optional>options</optional> <replaceable>devpath</replaceable></command>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>udevadm test-builtin <optional>options</optional> <replaceable>command</replaceable> <replaceable>devpath</replaceable></command>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+    <para>udevadm expects a command and command specific options.  It
+    controls the runtime behavior of udev, requests kernel events,
+    manages the event queue, and provides simple debugging mechanisms.</para>
+  </refsect1>
+
+  <refsect1><title>OPTIONS</title>
+    <variablelist>
+      <varlistentry>
+        <term><option>--debug</option></term>
+        <listitem>
+          <para>Print debug messages to stderr.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--version</option></term>
+        <listitem>
+          <para>Print version number.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>--help</option></term>
+        <listitem>
+          <para>Print help text.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <refsect2><title>udevadm info <replaceable>options</replaceable></title>
+      <para>Queries the udev database for device information
+      stored in the udev database. It can also query the properties
+      of a device from its sysfs representation to help creating udev
+      rules that match this device.</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>--query=<replaceable>type</replaceable></option></term>
+          <listitem>
+            <para>Query the database for specified type of device data. It needs the
+            <option>--path</option> or <option>--name</option> to identify the specified
+            device. Valid queries are:
+            <command>name</command>, <command>symlink</command>, <command>path</command>,
+            <command>property</command>, <command>all</command>.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--path=<replaceable>devpath</replaceable></option></term>
+          <listitem>
+            <para>The devpath of the device to query.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--name=<replaceable>file</replaceable></option></term>
+          <listitem>
+            <para>The name of the device node or a symlink to query</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--root</option></term>
+          <listitem>
+            <para>Print absolute paths in <command>name</command> or <command>symlink</command>
+            query.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--attribute-walk</option></term>
+          <listitem>
+            <para>Print all sysfs properties of the specified device that can be used
+            in udev rules to match the specified device. It prints all devices
+            along the chain, up to the root of sysfs that can be used in udev rules.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--export</option></term>
+          <listitem>
+            <para>Print output as key/value pairs. Values are enclosed in single quotes.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--export-prefix=<replaceable>name</replaceable></option></term>
+          <listitem>
+            <para>Add a prefix to the key name of exported values.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--device-id-of-file=<replaceable>file</replaceable></option></term>
+          <listitem>
+            <para>Print major/minor numbers of the underlying device, where the file
+            lives on.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--export-db</option></term>
+          <listitem>
+            <para>Export the content of the udev database.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--cleanup-db</option></term>
+          <listitem>
+            <para>Cleanup the udev database.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--version</option></term>
+          <listitem>
+            <para>Print version.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--help</option></term>
+          <listitem>
+            <para>Print help text.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2><title>udevadm trigger <optional>options</optional></title>
+      <para>Request device events from the kernel. Primarily used to replay events at system coldplug time.</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>--verbose</option></term>
+          <listitem>
+            <para>Print the list of devices which will be triggered.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--dry-run</option></term>
+          <listitem>
+            <para>Do not actually trigger the event.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--type=<replaceable>type</replaceable></option></term>
+          <listitem>
+            <para>Trigger a specific type of devices. Valid types are:
+            <command>devices</command>, <command>subsystems</command>.
+            The default value is <command>devices</command>.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--action=<replaceable>action</replaceable></option></term>
+          <listitem>
+            <para>Type of event to be triggered. The default value is <command>change</command>.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--subsystem-match=<replaceable>subsystem</replaceable></option></term>
+          <listitem>
+            <para>Trigger events for devices which belong to a matching subsystem. This option
+            can be specified multiple times and supports shell style pattern matching.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--subsystem-nomatch=<replaceable>subsystem</replaceable></option></term>
+          <listitem>
+            <para>Do not trigger events for devices which belong to a matching subsystem. This option
+            can be specified multiple times and supports shell style pattern matching.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--attr-match=<replaceable>attribute</replaceable>=<replaceable>value</replaceable></option></term>
+          <listitem>
+            <para>Trigger events for devices with a matching sysfs attribute. If a value is specified
+            along with the attribute name, the content of the attribute is matched against the given
+            value using shell style pattern matching. If no value is specified, the existence of the
+            sysfs attribute is checked. This option can be specified multiple times.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--attr-nomatch=<replaceable>attribute</replaceable>=<replaceable>value</replaceable></option></term>
+          <listitem>
+            <para>Do not trigger events for devices with a matching sysfs attribute. If a value is
+            specified along with the attribute name, the content of the attribute is matched against
+            the given value using shell style pattern matching. If no value is specified, the existence
+            of the sysfs attribute is checked. This option can be specified multiple times.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--property-match=<replaceable>property</replaceable>=<replaceable>value</replaceable></option></term>
+          <listitem>
+            <para>Trigger events for devices with a matching property value. This option can be
+            specified multiple times and supports shell style pattern matching.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--tag-match=<replaceable>property</replaceable></option></term>
+          <listitem>
+            <para>Trigger events for devices with a matching tag. This option can be
+            specified multiple times.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--sysname-match=<replaceable>name</replaceable></option></term>
+          <listitem>
+            <para>Trigger events for devices with a matching sys device name. This option can be
+            specified multiple times and supports shell style pattern matching.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--parent-match=<replaceable>syspath</replaceable></option></term>
+          <listitem>
+            <para>Trigger events for all children of a given device.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2><title>udevadm settle <optional>options</optional></title>
+      <para>Watches the udev event queue, and exits if all current events are handled.</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>--timeout=<replaceable>seconds</replaceable></option></term>
+          <listitem>
+            <para>Maximum number of seconds to wait for the event queue to become empty.
+            The default value is 120 seconds. A value of 0 will check if the queue is empty
+            and always return immediately.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--seq-start=<replaceable>seqnum</replaceable></option></term>
+          <listitem>
+            <para>Wait only for events after the given sequence number.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--seq-end=<replaceable>seqnum</replaceable></option></term>
+          <listitem>
+            <para>Wait only for events before the given sequence number.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--exit-if-exists=<replaceable>file</replaceable></option></term>
+          <listitem>
+            <para>Stop waiting if file exists.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--quiet</option></term>
+          <listitem>
+            <para>Do not print any output, like the remaining queue entries when reaching the timeout.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--help</option></term>
+          <listitem>
+            <para>Print help text.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2><title>udevadm control <replaceable>command</replaceable></title>
+      <para>Modify the internal state of the running udev daemon.</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>--exit</option></term>
+          <listitem>
+            <para>Signal and wait for systemd-udevd to exit.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--log-priority=<replaceable>value</replaceable></option></term>
+          <listitem>
+            <para>Set the internal log level of systemd-udevd. Valid values are the numerical
+            syslog priorities or their textual representations: <option>err</option>,
+            <option>info</option> and <option>debug</option>.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--stop-exec-queue</option></term>
+          <listitem>
+            <para>Signal systemd-udevd to stop executing new events. Incoming events
+            will be queued.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--start-exec-queue</option></term>
+          <listitem>
+            <para>Signal systemd-udevd to enable the execution of events.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--reload</option></term>
+          <listitem>
+            <para>Signal systemd-udevd to reload the rules files and other databases like the kernel
+            module index. Reloading rules and databases does not apply any changes to already
+            existing devices; the new configuration will only be applied to new events.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--property=<replaceable>KEY</replaceable>=<replaceable>value</replaceable></option></term>
+          <listitem>
+            <para>Set a global property for all events.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--children-max=</option><replaceable>value</replaceable></term>
+          <listitem>
+            <para>Set the maximum number of events, systemd-udevd will handle at the
+            same time.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--timeout=</option><replaceable>seconds</replaceable></term>
+          <listitem>
+            <para>The maximum number of seconds to wait for a reply from systemd-udevd.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--help</option></term>
+          <listitem>
+            <para>Print help text.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2><title>udevadm monitor <optional>options</optional></title>
+      <para>Listens to the kernel uevents and events sent out by a udev rule
+      and prints the devpath of the event to the console. It can be used to analyze the
+      event timing, by comparing the timestamps of the kernel uevent and the udev event.
+      </para>
+      <variablelist>
+        <varlistentry>
+          <term><option>--kernel</option></term>
+          <listitem>
+            <para>Print the kernel uevents.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--udev</option></term>
+          <listitem>
+            <para>Print the udev event after the rule processing.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--property</option></term>
+          <listitem>
+            <para>Also print the properties of the event.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--subsystem-match=<replaceable>string[/string]</replaceable></option></term>
+          <listitem>
+            <para>Filter events by subsystem[/devtype]. Only udev events with a matching subsystem value will pass.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--tag-match=<replaceable>string</replaceable></option></term>
+          <listitem>
+            <para>Filter events by property. Only udev events with a given tag attached will pass.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--help</option></term>
+          <listitem>
+            <para>Print help text.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2><title>udevadm hwdb <optional>options</optional></title>
+      <para>Maintain the hardware database index in <filename>/etc/udev/hwdb.bin</filename>.</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>--update</option></term>
+          <listitem>
+            <para>Compile the hardware database information located in /usr/lib/udev/hwdb.d/,
+            /etc/udev/hwdb.d/ and store it in <filename>/etc/udev/hwdb.bin</filename>. This should be done after
+            any update to the source files; it will not be called automatically. The running
+            udev daemon will detect a new database on its own and does not need to be
+            notified about it.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--test=<replaceable>string</replaceable></option></term>
+          <listitem>
+            <para>Query the database with a modalias string, and print the
+            retrieved properties.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2><title>udevadm test <optional>options</optional> <replaceable>devpath</replaceable></title>
+      <para>Simulate a udev event run for the given device, and print debug output.</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>--action=<replaceable>string</replaceable></option></term>
+          <listitem>
+            <para>The action string.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--subsystem=<replaceable>string</replaceable></option></term>
+          <listitem>
+            <para>The subsystem string.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--help</option></term>
+          <listitem>
+            <para>Print help text.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2><title>udevadm test-builtin <optional>options</optional> <replaceable>command</replaceable> <replaceable>devpath</replaceable></title>
+      <para>Run a built-in command for the given device, and print debug output.</para>
+      <variablelist>
+        <varlistentry>
+          <term><option>--help</option></term>
+          <listitem>
+            <para>Print help text.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para><citerefentry>
+        <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum>
+    </citerefentry>
+    <citerefentry>
+        <refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum>
+    </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/man/vconsole.conf.xml b/man/vconsole.conf.xml
new file mode 100644 (file)
index 0000000..45156b7
--- /dev/null
@@ -0,0 +1,147 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="vconsole.conf">
+        <refentryinfo>
+                <title>vconsole.conf</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>vconsole.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>vconsole.conf</refname>
+                <refpurpose>Configuration file for the virtual console</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/vconsole.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>The <filename>/etc/vconsole.conf</filename> file
+                configures the virtual console, i.e. keyboard mapping
+                and console font. It is applied at boot by
+                <citerefentry><refentrytitle>systemd-vconsole-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+                <para>The basic file format of the
+                <filename>vconsole.conf</filename> is a
+                newline-separated list of environment-like
+                shell-compatible variable assignments. It is possible
+                to source the configuration from shell scripts,
+                however, beyond mere variable assignments no shell
+                features are supported, allowing applications to read
+                the file without implementing a shell compatible
+                execution engine.</para>
+
+                <para>Note that the kernel command line options
+                <varname>vconsole.keymap=</varname>,
+                <varname>vconsole.keymap.toggle=</varname>,
+                <varname>vconsole.font=</varname>,
+                <varname>vconsole.font.map=</varname>,
+                <varname>vconsole.font.unimap=</varname> may be used
+                to override the console settings at boot.</para>
+
+                <para>Depending on the operating system other
+                configuration files might be checked for configuration
+                of the virtual console as well, however only as
+                fallback.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><varname>KEYMAP=</varname></term>
+                                <term><varname>KEYMAP_TOGGLE=</varname></term>
+
+                                <listitem><para>Configures the key
+                                mapping table for the
+                                keyboard. <varname>KEYMAP=</varname>
+                                defaults to <literal>us</literal> if
+                                not set. The
+                                <varname>KEYMAP_TOGGLE=</varname> can
+                                be used to configure a second toggle
+                                keymap and is by default
+                                unset.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>FONT=</varname></term>
+                                <term><varname>FONT_MAP=</varname></term>
+                                <term><varname>FONT_UNIMAP=</varname></term>
+
+                                <listitem><para>Configures the console
+                                font, the console map and the unicode
+                                font map.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+
+                <example>
+                        <title>German keyboard and console</title>
+
+                        <para><filename>/etc/vconsole.conf:</filename></para>
+
+                        <programlisting>KEYMAP=de-latin1
+FONT=latarcyrheb-sun16</programlisting>
+                </example>
+
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                          <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-vconsole-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
diff --git a/po/.gitignore b/po/.gitignore
new file mode 100644 (file)
index 0000000..1fa8d3f
--- /dev/null
@@ -0,0 +1,5 @@
+POTFILES
+Makefile.in.in
+.intltool-merge-cache
+Makefile
+systemd.pot
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644 (file)
index 0000000..2829c87
--- /dev/null
@@ -0,0 +1,5 @@
+src/hostname/org.freedesktop.hostname1.policy.in
+src/locale/org.freedesktop.locale1.policy.in
+src/login/org.freedesktop.login1.policy.in
+src/timedate/org.freedesktop.timedate1.policy.in
+src/core/org.freedesktop.systemd1.policy.in.in
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
new file mode 100644 (file)
index 0000000..0502c13
--- /dev/null
@@ -0,0 +1,20 @@
+src/core/dbus-automount.c
+src/core/dbus-device.c
+src/core/dbus-job.c
+src/core/dbus-manager.c
+src/core/dbus-mount.c
+src/core/dbus-path.c
+src/core/dbus-service.c
+src/core/dbus-snapshot.c
+src/core/dbus-socket.c
+src/core/dbus-swap.c
+src/core/dbus-target.c
+src/core/dbus-timer.c
+src/core/dbus-unit.c
+src/hostname/hostnamed.c
+src/locale/localed.c
+src/core/org.freedesktop.systemd1.policy.in
+src/timedate/timedated.c
+units/systemd-readahead-done.service.in
+units/user@.service.in
+units/debug-shell.service.in
diff --git a/po/pl.po b/po/pl.po
new file mode 100644 (file)
index 0000000..2581d01
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,175 @@
+# translation of pl.po to Polish
+# Piotr Drąg <piotrdrag@gmail.com>, 2011.
+# Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-10-14 16:18+0200\n"
+"PO-Revision-Date: 2011-10-14 16:20+0200\n"
+"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
+"Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../src/org.freedesktop.hostname1.policy.in.h:1
+msgid "Authentication is required to set local machine information."
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby ustawić informacje o lokalnym komputerze."
+
+#: ../src/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "Wymagane jest uwierzytelnienie, aby ustawić nazwę lokalnego komputera."
+
+#: ../src/org.freedesktop.hostname1.policy.in.h:3
+msgid ""
+"Authentication is required to set the statically configured local host name, "
+"as well as the pretty host name."
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby ustawić statycznie skonfigurowaną nazwę "
+"lokalnego komputera, a także jego ładną nazwę."
+
+#: ../src/org.freedesktop.hostname1.policy.in.h:4
+msgid "Set host name"
+msgstr "Ustawienie nazwy komputera"
+
+#: ../src/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Ustawienie informacji o komputerze"
+
+#: ../src/org.freedesktop.hostname1.policy.in.h:6
+msgid "Set static host name"
+msgstr "Ustawienie statycznej nazwy komputera"
+
+#: ../src/org.freedesktop.locale1.policy.in.h:1
+msgid "Authentication is required to set the system keyboard settings."
+msgstr "Wymagane jest uwierzytelnienie, aby ustawić klawiaturę systemu."
+
+#: ../src/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr "Wymagane jest uwierzytelnienie, aby ustawić lokalizację systemu."
+
+#: ../src/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Ustawienie klawiatury systemu"
+
+#: ../src/org.freedesktop.locale1.policy.in.h:4
+msgid "Set system locale"
+msgstr "Ustawienie lokalizacji systemu"
+
+#: ../src/org.freedesktop.login1.policy.in.h:1
+msgid "Allow attaching devices to seats"
+msgstr "Zezwolenie na podłączanie urządzeń do stanowisk"
+
+#: ../src/org.freedesktop.login1.policy.in.h:2
+msgid "Allow non-logged-in users to run programs"
+msgstr "Zezwolenie niezalogowanym użytkownikom na uruchamianie programów"
+
+#: ../src/org.freedesktop.login1.policy.in.h:3
+msgid ""
+"Authentication is required to allow a non-logged-in user to run programs"
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby ustawić zezwolić niezalogowanym "
+"użytkownikom na uruchamianie programów"
+
+#: ../src/org.freedesktop.login1.policy.in.h:4
+msgid "Authentication is required to allow attaching a device to a seat"
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby zezwolić na podłączenie urządzenia do "
+"stanowiska"
+
+#: ../src/org.freedesktop.login1.policy.in.h:5
+msgid "Authentication is required to allow powering off the system"
+msgstr "Wymagane jest uwierzytelnienie, aby zezwolić na wyłączanie systemu"
+
+#: ../src/org.freedesktop.login1.policy.in.h:6
+msgid ""
+"Authentication is required to allow powering off the system while other "
+"users are logged in"
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby zezwolić na wyłączanie systemu, kiedy są "
+"zalogowani inni użytkownicy"
+
+#: ../src/org.freedesktop.login1.policy.in.h:7
+msgid "Authentication is required to allow rebooting the system"
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby zezwolić na ponowne uruchamianie systemu"
+
+#: ../src/org.freedesktop.login1.policy.in.h:8
+msgid ""
+"Authentication is required to allow rebooting the system while other users "
+"are logged in"
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby zezwolić na ponowne uruchamianie "
+"systemu, kiedy są zalogowani inni użytkownicy"
+
+#: ../src/org.freedesktop.login1.policy.in.h:9
+msgid ""
+"Authentication is required to allow resetting how devices are attached to "
+"seats"
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby zezwolić na ponowne ustawianie sposobu "
+"podłączenia urządzeń do stanowisk"
+
+#: ../src/org.freedesktop.login1.policy.in.h:10
+msgid "Flush device to seat attachments"
+msgstr "Usunięcie podłączenia urządzeń do stanowisk"
+
+#: ../src/org.freedesktop.login1.policy.in.h:11
+msgid "Power off the system"
+msgstr "Wyłączenie systemu"
+
+#: ../src/org.freedesktop.login1.policy.in.h:12
+msgid "Power off the system when other users are logged in"
+msgstr "Wyłączenie systemu, kiedy są zalogowani inni użytkownicy"
+
+#: ../src/org.freedesktop.login1.policy.in.h:13
+msgid "Reboot the system"
+msgstr "Ponowne uruchomienie systemu"
+
+#: ../src/org.freedesktop.login1.policy.in.h:14
+msgid "Reboot the system when other users are logged in"
+msgstr "Ponowne uruchomienie systemu, kiedy są zalogowani inni użytkownicy"
+
+#: ../src/org.freedesktop.timedate1.policy.in.h:1
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby kontrolować, czy włączyć synchronizację "
+"czasu przez sieć."
+
+#: ../src/org.freedesktop.timedate1.policy.in.h:2
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr ""
+"Wymagane jest uwierzytelnienie, aby kontrolować, czy RTC przechowuje czas "
+"lokalny lub czas UTC."
+
+#: ../src/org.freedesktop.timedate1.policy.in.h:3
+msgid "Authentication is required to set the system time."
+msgstr "Wymagane jest uwierzytelnienie, aby ustawić czas systemu."
+
+#: ../src/org.freedesktop.timedate1.policy.in.h:4
+msgid "Authentication is required to set the system timezone."
+msgstr "Wymagane jest uwierzytelnienie, aby ustawić strefę czasową systemu."
+
+#: ../src/org.freedesktop.timedate1.policy.in.h:5
+msgid "Set RTC to local timezone or UTC"
+msgstr "Ustawienie RTC na lokalną strefę czasową lub strefę UTC"
+
+#: ../src/org.freedesktop.timedate1.policy.in.h:6
+msgid "Set system time"
+msgstr "Ustawienie czasu systemu"
+
+#: ../src/org.freedesktop.timedate1.policy.in.h:7
+msgid "Set system timezone"
+msgstr "Ustawienie strefy czasowej systemu"
+
+#: ../src/org.freedesktop.timedate1.policy.in.h:8
+msgid "Turn network time synchronization on or off"
+msgstr "Włączenie lub wyłączenie synchronizacji czasu przez sieć"
diff --git a/rules/.gitignore b/rules/.gitignore
new file mode 100644 (file)
index 0000000..93a50dd
--- /dev/null
@@ -0,0 +1 @@
+/99-systemd.rules
diff --git a/rules/42-usb-hid-pm.rules b/rules/42-usb-hid-pm.rules
new file mode 100644 (file)
index 0000000..2b56b11
--- /dev/null
@@ -0,0 +1,39 @@
+# do not edit this file, it will be overwritten on update
+#
+# Enable autosuspend for qemu emulated usb hid devices
+
+# Note that there are buggy qemu versions which advertise remote
+# wakeup support but don't actually implement it correctly.  This
+# is the reason why we need a match for the serial number here.
+# The serial number "42" is used to tag the implementations where
+# remote wakeup is working.
+ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Mouse", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
+ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Tablet", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
+ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Keyboard", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
+
+# Catch-all for Avocent HID devices. Keyed off interface in order to only
+# trigger on HID class devices.
+ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0624", ATTR{bInterfaceClass}=="03", TEST=="../power/control", ATTR{../power/control}="auto"
+
+# Dell DRAC 4
+ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="2500", TEST=="power/control", ATTR{power/control}="auto"
+
+# Dell DRAC 5
+ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="0000", TEST=="power/control", ATTR{power/control}="auto"
+
+# IBM remote access
+ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b3", ATTR{idProduct}=="4001", TEST=="power/control", ATTR{power/control}="auto"
+ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b3", ATTR{idProduct}=="4002", TEST=="power/control", ATTR{power/control}="auto"
+ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="04b3", ATTR{idProduct}=="4012", TEST=="power/control", ATTR{power/control}="auto"
+
+# Raritan Computer, Inc KVM.
+ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="14dd", ATTR{idProduct}=="0002", TEST=="power/control", ATTR{power/control}="auto"
+
+# USB HID devices that are internal to the machine should also be safe to autosuspend
+
+ACTION=="add", SUBSYSTEM=="usb", SUBSYSTEMS=="usb", ATTRS{removable}=="removable", GOTO="usb_hid_pm_end"
+ACTION=="add", SUBSYSTEM=="usb", SUBSYSTEMS=="usb", ATTRS{removable}=="unknown", GOTO="usb_hid_pm_end"        
+
+ACTION=="add", SUBSYSTEM=="usb", ATTR{bInterfaceClass}=="03", ATTRS{removable}=="fixed", TEST=="../power/control", ATTR{../power/control}="auto"
+
+LABEL="usb_hid_pm_end"
diff --git a/rules/50-udev-default.rules b/rules/50-udev-default.rules
new file mode 100644 (file)
index 0000000..fc52fd1
--- /dev/null
@@ -0,0 +1,90 @@
+# do not edit this file, it will be overwritten on update
+
+SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
+SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666"
+SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty"
+
+# serial
+KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
+
+# virtio serial / console ports
+SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}"
+
+# mem
+SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640"
+
+# input
+SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
+SUBSYSTEM=="input", KERNEL=="mouse*|mice|event*", MODE="0640"
+SUBSYSTEM=="input", KERNEL=="ts[0-9]*|uinput", MODE="0640"
+SUBSYSTEM=="input", KERNEL=="js[0-9]*", MODE="0644"
+
+# video4linux
+SUBSYSTEM=="video4linux", GROUP="video"
+
+# graphics
+SUBSYSTEM=="misc", KERNEL=="agpgart", GROUP="video"
+SUBSYSTEM=="graphics", GROUP="video"
+SUBSYSTEM=="drm", GROUP="video"
+
+# sound
+SUBSYSTEM=="sound", GROUP="audio", \
+  OPTIONS+="static_node=snd/seq", OPTIONS+="static_node=snd/timer"
+
+# DVB (video)
+SUBSYSTEM=="dvb", GROUP="video"
+
+# FireWire (firewire-core driver: IIDC devices, AV/C devices)
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", GROUP="video"
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", GROUP="video"
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", GROUP="video"
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", GROUP="video"
+
+# 'libusb' device nodes
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
+
+# printer
+KERNEL=="parport[0-9]*", GROUP="lp"
+SUBSYSTEM=="printer", KERNEL=="lp*", GROUP="lp"
+SUBSYSTEM=="ppdev", GROUP="lp"
+KERNEL=="lp[0-9]*", GROUP="lp"
+KERNEL=="irlpt[0-9]*", GROUP="lp"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", GROUP="lp"
+
+# block
+SUBSYSTEM=="block", GROUP="disk"
+
+# floppy
+SUBSYSTEM=="block", KERNEL=="fd[0-9]", GROUP="floppy"
+
+# cdrom
+SUBSYSTEM=="block", KERNEL=="sr[0-9]*", GROUP="cdrom"
+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", GROUP="cdrom"
+KERNEL=="sch[0-9]*", GROUP="cdrom"
+KERNEL=="pktcdvd[0-9]*", GROUP="cdrom"
+KERNEL=="pktcdvd", GROUP="cdrom"
+
+# tape
+SUBSYSTEM=="scsi_generic|scsi_tape", SUBSYSTEMS=="scsi", ATTRS{type}=="1|8", GROUP="tape"
+
+# block-related
+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="0", GROUP="disk"
+KERNEL=="qft[0-9]*|nqft[0-9]*|zqft[0-9]*|nzqft[0-9]*|rawqft[0-9]*|nrawqft[0-9]*", GROUP="disk"
+KERNEL=="rawctl", GROUP="disk"
+SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", GROUP="disk"
+SUBSYSTEM=="aoe", GROUP="disk", MODE="0220"
+SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440"
+
+# network
+KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun"
+KERNEL=="rfkill", MODE="0644"
+
+KERNEL=="fuse", ACTION=="add", MODE="0666", OPTIONS+="static_node=fuse"
+
+SUBSYSTEM=="rtc", ATTR{hctosys}=="1", MODE="0644", SYMLINK+="rtc"
+
+SUBSYSTEM=="firmware", ACTION=="add", IMPORT{builtin}="firmware"
+
+ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
diff --git a/rules/60-cdrom_id.rules b/rules/60-cdrom_id.rules
new file mode 100644 (file)
index 0000000..6eaf76a
--- /dev/null
@@ -0,0 +1,20 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="cdrom_end"
+SUBSYSTEM!="block", GOTO="cdrom_end"
+KERNEL!="sr[0-9]*|xvd*", GOTO="cdrom_end"
+ENV{DEVTYPE}!="disk", GOTO="cdrom_end"
+
+# unconditionally tag device as CDROM
+KERNEL=="sr[0-9]*", ENV{ID_CDROM}="1"
+
+# media eject button pressed
+ENV{DISK_EJECT_REQUEST}=="?*", RUN+="cdrom_id --eject-media $devnode", GOTO="cdrom_end"
+
+# import device and media properties and lock tray to
+# enable the receiving of media eject button events
+IMPORT{program}="cdrom_id --lock-media $devnode"
+
+KERNEL=="sr0", SYMLINK+="cdrom", OPTIONS+="link_priority=-100"
+
+LABEL="cdrom_end"
diff --git a/rules/60-persistent-alsa.rules b/rules/60-persistent-alsa.rules
new file mode 100644 (file)
index 0000000..8154e2d
--- /dev/null
@@ -0,0 +1,14 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="persistent_alsa_end"
+SUBSYSTEM!="sound", GOTO="persistent_alsa_end"
+KERNEL!="controlC[0-9]*", GOTO="persistent_alsa_end"
+
+SUBSYSTEMS=="usb", ENV{ID_MODEL}=="", IMPORT{builtin}="usb_id"
+ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}"
+ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
+
+IMPORT{builtin}="path_id"
+ENV{ID_PATH}=="?*", SYMLINK+="snd/by-path/$env{ID_PATH}"
+
+LABEL="persistent_alsa_end"
diff --git a/rules/60-persistent-input.rules b/rules/60-persistent-input.rules
new file mode 100644 (file)
index 0000000..0e33e68
--- /dev/null
@@ -0,0 +1,38 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="persistent_input_end"
+SUBSYSTEM!="input", GOTO="persistent_input_end"
+SUBSYSTEMS=="bluetooth", GOTO="persistent_input_end"
+
+SUBSYSTEMS=="usb", ENV{ID_BUS}=="", IMPORT{builtin}="usb_id"
+
+# determine class name for persistent symlinks
+ENV{ID_INPUT_KEYBOARD}=="?*", ENV{.INPUT_CLASS}="kbd"
+ENV{ID_INPUT_MOUSE}=="?*", ENV{.INPUT_CLASS}="mouse"
+ENV{ID_INPUT_TOUCHPAD}=="?*", ENV{.INPUT_CLASS}="mouse"
+ENV{ID_INPUT_TABLET}=="?*", ENV{.INPUT_CLASS}="mouse"
+ENV{ID_INPUT_JOYSTICK}=="?*", ENV{.INPUT_CLASS}="joystick"
+DRIVERS=="pcspkr", ENV{.INPUT_CLASS}="spkr"
+ATTRS{name}=="*dvb*|*DVB*|* IR *", ENV{.INPUT_CLASS}="ir"
+
+# fill empty serial number
+ENV{.INPUT_CLASS}=="?*", ENV{ID_SERIAL}=="", ENV{ID_SERIAL}="noserial"
+
+# by-id links
+KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="|00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{.INPUT_CLASS}"
+KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="?*", ATTRS{bInterfaceNumber}!="00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$attr{bInterfaceNumber}-$env{.INPUT_CLASS}"
+KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="|00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-$env{.INPUT_CLASS}"
+KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="?*", ATTRS{bInterfaceNumber}!="00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$attr{bInterfaceNumber}-event-$env{.INPUT_CLASS}"
+# allow empty class for USB devices, by appending the interface number
+SUBSYSTEMS=="usb", ENV{ID_BUS}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="", ATTRS{bInterfaceNumber}=="?*", \
+  SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-if$attr{bInterfaceNumber}"
+
+# by-path
+SUBSYSTEMS=="pci|usb|platform|acpi", IMPORT{builtin}="path_id"
+ENV{ID_PATH}=="?*", KERNEL=="mouse*|js*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{.INPUT_CLASS}"
+ENV{ID_PATH}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-event-$env{.INPUT_CLASS}"
+# allow empty class for platform and usb devices; platform supports only a single interface that way
+SUBSYSTEMS=="usb|platform", ENV{ID_PATH}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="", \
+  SYMLINK+="input/by-path/$env{ID_PATH}-event"
+
+LABEL="persistent_input_end"
diff --git a/rules/60-persistent-serial.rules b/rules/60-persistent-serial.rules
new file mode 100644 (file)
index 0000000..2948200
--- /dev/null
@@ -0,0 +1,20 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="persistent_serial_end"
+SUBSYSTEM!="tty", GOTO="persistent_serial_end"
+KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="persistent_serial_end"
+
+SUBSYSTEMS=="usb-serial", ENV{.ID_PORT}="$attr{port_number}"
+
+IMPORT{builtin}="path_id"
+ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH}"
+ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH}-port$env{.ID_PORT}"
+
+IMPORT{builtin}="usb_id"
+ENV{ID_SERIAL}=="", GOTO="persistent_serial_end"
+SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACE_NUM}="$attr{bInterfaceNumber}"
+ENV{ID_USB_INTERFACE_NUM}=="", GOTO="persistent_serial_end"
+ENV{.ID_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}"
+ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}-port$env{.ID_PORT}"
+
+LABEL="persistent_serial_end"
diff --git a/rules/60-persistent-storage-tape.rules b/rules/60-persistent-storage-tape.rules
new file mode 100644 (file)
index 0000000..f2eabd9
--- /dev/null
@@ -0,0 +1,25 @@
+# do not edit this file, it will be overwritten on update
+
+# persistent storage links: /dev/tape/{by-id,by-path}
+
+ACTION=="remove", GOTO="persistent_storage_tape_end"
+
+# type 8 devices are "Medium Changers"
+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{program}="scsi_id --sg-version=3 --export --whitelisted -d $devnode", \
+  SYMLINK+="tape/by-id/scsi-$env{ID_SERIAL}"
+
+SUBSYSTEM!="scsi_tape", GOTO="persistent_storage_tape_end"
+
+KERNEL=="st*[0-9]|nst*[0-9]", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{ieee1394_id}", ENV{ID_BUS}="ieee1394"
+KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
+KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", KERNELS=="[0-9]*:*[0-9]", ENV{.BSG_DEV}="$root/bsg/$id"
+KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --whitelisted --export --device=$env{.BSG_DEV}", ENV{ID_BUS}="scsi"
+KERNEL=="st*[0-9]",  ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
+KERNEL=="nst*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}-nst"
+
+# by-path (parent device path)
+KERNEL=="st*[0-9]|nst*[0-9]", IMPORT{builtin}="path_id"
+KERNEL=="st*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}"
+KERNEL=="nst*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}-nst"
+
+LABEL="persistent_storage_tape_end"
diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules
new file mode 100644 (file)
index 0000000..b74821e
--- /dev/null
@@ -0,0 +1,89 @@
+# do not edit this file, it will be overwritten on update
+
+# persistent storage links: /dev/disk/{by-id,by-uuid,by-label,by-path}
+# scheme based on "Linux persistent device names", 2004, Hannes Reinecke <hare@suse.de>
+
+# forward scsi device event to corresponding block device
+ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change"
+
+ACTION=="remove", GOTO="persistent_storage_end"
+
+# enable in-kernel media-presence polling
+ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_poll_msecs}=="0", ATTR{parameters/events_dfl_poll_msecs}="2000"
+
+SUBSYSTEM!="block", GOTO="persistent_storage_end"
+
+# skip rules for inappropriate block devices
+KERNEL=="fd*|mtd*|nbd*|gnbd*|btibm*|dm-*|md*", GOTO="persistent_storage_end"
+
+# ignore partitions that span the entire disk
+TEST=="whole_disk", GOTO="persistent_storage_end"
+
+# for partitions import parent information
+ENV{DEVTYPE}=="partition", IMPORT{parent}="ID_*"
+
+# virtio-blk
+KERNEL=="vd*[!0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}"
+KERNEL=="vd*[0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}-part%n"
+
+# ATA devices with their own "ata" kernel subsystem
+KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="ata", IMPORT{program}="ata_id --export $devnode"
+# ATA devices using the "scsi" subsystem
+KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", IMPORT{program}="ata_id --export $devnode"
+# ATA/ATAPI devices (SPC-3 or later) using the "scsi" subsystem
+KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{type}=="5", ATTRS{scsi_level}=="[6-9]*", IMPORT{program}="ata_id --export $devnode"
+
+# Run ata_id on non-removable USB Mass Storage (SATA/PATA disks in enclosures)
+KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", ATTR{removable}=="0", SUBSYSTEMS=="usb", IMPORT{program}="ata_id --export $devnode"
+# Otherwise fall back to using usb_id for USB devices
+KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
+
+# scsi devices
+KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $devnode", ENV{ID_BUS}="scsi"
+KERNEL=="cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $devnode", ENV{ID_BUS}="cciss"
+KERNEL=="sd*|sr*|cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
+KERNEL=="sd*|cciss*", ENV{DEVTYPE}=="partition", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
+
+# firewire
+KERNEL=="sd*[!0-9]|sr*", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}"
+KERNEL=="sd*[0-9]", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}-part%n"
+
+KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
+KERNEL=="mmcblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
+KERNEL=="mspblk[0-9]", SUBSYSTEMS=="memstick", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}"
+KERNEL=="mspblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
+
+# by-path (parent device path)
+ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id"
+ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
+ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
+
+# skip unpartitioned removable media devices from drivers which do not send "change" events
+ENV{DEVTYPE}=="disk", KERNEL!="sd*|sr*", ATTR{removable}=="1", GOTO="persistent_storage_end"
+
+# probe filesystem metadata of optical drives which have a media inserted
+KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="?*", \
+  IMPORT{builtin}="blkid --offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}"
+# single-session CDs do not have ID_CDROM_MEDIA_SESSION_LAST_OFFSET
+KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="", \
+  IMPORT{builtin}="blkid --noraid"
+
+# probe filesystem metadata of disks
+KERNEL!="sr*", IMPORT{builtin}="blkid"
+
+# watch metadata changes by tools closing the device after writing
+KERNEL!="sr*", OPTIONS+="watch"
+
+# by-label/by-uuid links (filesystem metadata)
+ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
+ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
+
+# by-id (World Wide Name)
+ENV{DEVTYPE}=="disk", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}"
+ENV{DEVTYPE}=="partition", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}-part%n"
+
+# by-partlabel/by-partuuid links (partition metadata)
+ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}"
+ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}"
+
+LABEL="persistent_storage_end"
diff --git a/rules/60-persistent-v4l.rules b/rules/60-persistent-v4l.rules
new file mode 100644 (file)
index 0000000..93c5ee8
--- /dev/null
@@ -0,0 +1,20 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="persistent_v4l_end"
+SUBSYSTEM!="video4linux", GOTO="persistent_v4l_end"
+ENV{MAJOR}=="", GOTO="persistent_v4l_end"
+
+IMPORT{program}="v4l_id $devnode"
+
+SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
+KERNEL=="video*", ENV{ID_SERIAL}=="?*", SYMLINK+="v4l/by-id/$env{ID_BUS}-$env{ID_SERIAL}-video-index$attr{index}"
+
+# check for valid "index" number
+TEST!="index", GOTO="persistent_v4l_end"
+ATTR{index}!="?*", GOTO="persistent_v4l_end"
+
+IMPORT{builtin}="path_id"
+ENV{ID_PATH}=="?*", KERNEL=="video*|vbi*", SYMLINK+="v4l/by-path/$env{ID_PATH}-video-index$attr{index}"
+ENV{ID_PATH}=="?*", KERNEL=="audio*", SYMLINK+="v4l/by-path/$env{ID_PATH}-audio-index$attr{index}"
+
+LABEL="persistent_v4l_end"
diff --git a/rules/61-accelerometer.rules b/rules/61-accelerometer.rules
new file mode 100644 (file)
index 0000000..a6a2bfd
--- /dev/null
@@ -0,0 +1,3 @@
+# do not edit this file, it will be overwritten on update
+
+SUBSYSTEM=="input", ACTION!="remove", ENV{ID_INPUT_ACCELEROMETER}=="1", IMPORT{program}="accelerometer %p"
diff --git a/rules/64-btrfs.rules b/rules/64-btrfs.rules
new file mode 100644 (file)
index 0000000..fe01001
--- /dev/null
@@ -0,0 +1,13 @@
+# do not edit this file, it will be overwritten on update
+
+SUBSYSTEM!="block", GOTO="btrfs_end"
+ACTION=="remove", GOTO="btrfs_end"
+ENV{ID_FS_TYPE}!="btrfs", GOTO="btrfs_end"
+
+# let the kernel know about this btrfs filesystem, and check if it is complete
+IMPORT{builtin}="btrfs ready $devnode"
+
+# mark the device as not ready to be used by the system
+ENV{ID_BTRFS_READY}=="0", ENV{SYSTEMD_READY}="0"
+
+LABEL="btrfs_end"
diff --git a/rules/75-net-description.rules b/rules/75-net-description.rules
new file mode 100644 (file)
index 0000000..fe9fca1
--- /dev/null
@@ -0,0 +1,14 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="net_end"
+SUBSYSTEM!="net", GOTO="net_end"
+
+IMPORT{builtin}="net_id"
+SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
+SUBSYSTEMS=="usb", GOTO="net_end"
+
+SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
+
+IMPORT{builtin}="hwdb"
+
+LABEL="net_end"
diff --git a/rules/75-probe_mtd.rules b/rules/75-probe_mtd.rules
new file mode 100644 (file)
index 0000000..8848aee
--- /dev/null
@@ -0,0 +1,7 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION!="add", GOTO="mtd_probe_end"
+
+KERNEL=="mtd*ro", IMPORT{program}="mtd_probe $devnode"
+
+LABEL="mtd_probe_end"
diff --git a/rules/75-tty-description.rules b/rules/75-tty-description.rules
new file mode 100644 (file)
index 0000000..83083d9
--- /dev/null
@@ -0,0 +1,13 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="tty_end"
+SUBSYSTEM!="tty", GOTO="tty_end"
+
+SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
+SUBSYSTEMS=="usb", GOTO="tty_end"
+
+SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
+
+IMPORT{builtin}="hwdb"
+
+LABEL="tty_end"
diff --git a/rules/78-sound-card.rules b/rules/78-sound-card.rules
new file mode 100644 (file)
index 0000000..295f490
--- /dev/null
@@ -0,0 +1,86 @@
+# do not edit this file, it will be overwritten on update
+
+SUBSYSTEM!="sound", GOTO="sound_end"
+
+ACTION=="add|change", KERNEL=="controlC*", ATTR{../uevent}="change"
+ACTION!="change", GOTO="sound_end"
+
+# Ok, we probably need a little explanation here for what the two lines above
+# are good for.
+#
+# The story goes like this: when ALSA registers a new sound card it emits a
+# series of 'add' events to userspace, for the main card device and for all the
+# child device nodes that belong to it. udev relays those to applications,
+# however only maintains the order between father and child, but not between
+# the siblings. The control device node creation can be used as synchronization
+# point. All other devices that belong to a card are created in the kernel
+# before it. However unfortunately due to the fact that siblings are forwarded
+# out of order by udev this fact is lost to applications.
+#
+# OTOH before an application can open a device it needs to make sure that all
+# its device nodes are completely created and set up.
+#
+# As a workaround for this issue we have added the udev rule above which will
+# generate a 'change' event on the main card device from the 'add' event of the
+# card's control device. Due to the ordering semantics of udev this event will
+# only be relayed after all child devices have finished processing properly.
+# When an application needs to listen for appearing devices it can hence look
+# for 'change' events only, and ignore the actual 'add' events.
+#
+# When the application is initialized at the same time as a device is plugged
+# in it may need to figure out if the 'change' event has already been triggered
+# or not for a card. To find that out we store the flag environment variable
+# SOUND_INITIALIZED on the device which simply tells us if the card 'change'
+# event has already been processed.
+
+KERNEL!="card*", GOTO="sound_end"
+
+ENV{SOUND_INITIALIZED}="1"
+
+IMPORT{builtin}="hwdb"
+SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
+SUBSYSTEMS=="usb", GOTO="skip_pci"
+
+SUBSYSTEMS=="firewire", ATTRS{vendor_name}=="?*", ATTRS{model_name}=="?*", \
+  ENV{ID_BUS}="firewire", ENV{ID_VENDOR}="$attr{vendor_name}", ENV{ID_MODEL}="$attr{model_name}"
+SUBSYSTEMS=="firewire", ATTRS{guid}=="?*", ENV{ID_ID}="firewire-$attr{guid}"
+SUBSYSTEMS=="firewire", GOTO="skip_pci"
+
+SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
+LABEL="skip_pci"
+
+ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}-$attr{id}"
+ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$attr{id}"
+
+IMPORT{builtin}="path_id"
+
+# The values used here for $SOUND_FORM_FACTOR and $SOUND_CLASS should be kept
+# in sync with those defined for PulseAudio's src/pulse/proplist.h
+# PA_PROP_DEVICE_FORM_FACTOR, PA_PROP_DEVICE_CLASS properties.
+
+# If the first PCM device of this card has the pcm class 'modem', then the card is a modem
+ATTR{pcmC%nD0p/pcm_class}=="modem", ENV{SOUND_CLASS}="modem", GOTO="sound_end"
+
+# Identify cards on the internal PCI bus as internal
+SUBSYSTEMS=="pci", DEVPATH=="*/0000:00:??.?/sound/*", ENV{SOUND_FORM_FACTOR}="internal", GOTO="sound_end"
+
+# Devices that also support Image/Video interfaces are most likely webcams
+SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACES}=="*:0e????:*", ENV{SOUND_FORM_FACTOR}="webcam", GOTO="sound_end"
+
+# Matching on the model strings is a bit ugly, I admit
+ENV{ID_MODEL}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end"
+ENV{ID_MODEL_FROM_DATABASE}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end"
+
+ENV{ID_MODEL}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end"
+ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end"
+
+ENV{ID_MODEL}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end"
+ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end"
+
+ENV{ID_MODEL}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end"
+ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end"
+
+ENV{ID_MODEL}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end"
+ENV{ID_MODEL_FROM_DATABASE}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end"
+
+LABEL="sound_end"
diff --git a/rules/80-drivers.rules b/rules/80-drivers.rules
new file mode 100644 (file)
index 0000000..a0615cc
--- /dev/null
@@ -0,0 +1,13 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="drivers_end"
+
+DRIVER!="?*", ENV{MODALIAS}=="?*", IMPORT{builtin}="kmod load $env{MODALIAS}"
+SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", IMPORT{builtin}="kmod load tifm_sd"
+SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", IMPORT{builtin}="kmod load tifm_ms"
+SUBSYSTEM=="memstick", IMPORT{builtin}="kmod load ms_block mspro_block"
+SUBSYSTEM=="i2o", IMPORT{builtin}="kmod load i2o_block"
+SUBSYSTEM=="module", KERNEL=="parport_pc", RUN{builtin}="kmod load ppdev"
+KERNEL=="mtd*ro", ENV{MTD_FTL}=="smartmedia", IMPORT{builtin}="kmod load sm_ftl"
+
+LABEL="drivers_end"
diff --git a/rules/80-net-name-slot.rules b/rules/80-net-name-slot.rules
new file mode 100644 (file)
index 0000000..2834e82
--- /dev/null
@@ -0,0 +1,11 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="net_name_slot_end"
+SUBSYSTEM!="net", GOTO="net_name_slot_end"
+NAME!="", GOTO="net_name_slot_end"
+
+NAME=="", ENV{ID_NET_NAME_ONBOARD}!="", NAME="$env{ID_NET_NAME_ONBOARD}"
+NAME=="", ENV{ID_NET_NAME_SLOT}!="", NAME="$env{ID_NET_NAME_SLOT}"
+NAME=="", ENV{ID_NET_NAME_PATH}!="", NAME="$env{ID_NET_NAME_PATH}"
+
+LABEL="net_name_slot_end"
diff --git a/rules/95-udev-late.rules b/rules/95-udev-late.rules
new file mode 100644 (file)
index 0000000..eca0faa
--- /dev/null
@@ -0,0 +1,4 @@
+# do not edit this file, it will be overwritten on update
+
+# run a command on remove events
+ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"
diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in
new file mode 100644 (file)
index 0000000..d17bdd9
--- /dev/null
@@ -0,0 +1,60 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+ACTION=="remove", GOTO="systemd_end"
+
+SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*", TAG+="systemd"
+
+KERNEL=="vport*", TAG+="systemd"
+
+SUBSYSTEM=="block", KERNEL!="ram*|loop*", TAG+="systemd"
+SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0"
+
+# Ignore encrypted devices with no identified superblock on it, since
+# we are probably still calling mke2fs or mkswap on it.
+SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="0"
+
+# Ignore raid devices that are not yet assembled and started
+SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0"
+SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0"
+
+# Ignore nbd devices in the "add" event, with "change" the nbd is ready
+ACTION=="add", SUBSYSTEM=="block", KERNEL=="nbd*", ENV{SYSTEMD_READY}="0"
+
+# We need a hardware independent way to identify network devices. We
+# use the /sys/subsystem path for this. Current vanilla kernels don't
+# actually support that hierarchy right now, however upcoming kernels
+# will. HAL and udev internally support /sys/subsystem already, hence
+# it should be safe to use this here, too. This is mostly just an
+# identification string for systemd, so whether the path actually is
+# accessible or not does not matter as long as it is unique and in the
+# filesystem namespace.
+#
+# http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev/libudev-enumerate.c#n922
+
+SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/net/devices/$name"
+SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k"
+
+SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}+="bluetooth.target"
+ENV{ID_SMARTCARD_READER}=="*?", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target"
+SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target"
+
+SUBSYSTEM=="printer", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target"
+SUBSYSTEM=="usb", KERNEL=="lp*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target"
+
+# Apply sysctl variables to network devices (and only to those) as they appear.
+
+SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name"
+
+# Asynchronously mount file systems implemented by these modules as
+# soon as they are loaded.
+
+SUBSYSTEM=="module", KERNEL=="fuse", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sys-fs-fuse-connections.mount"
+SUBSYSTEM=="module", KERNEL=="configfs", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sys-kernel-config.mount"
+
+LABEL="systemd_end"
diff --git a/shell-completion/systemd-bash-completion.sh b/shell-completion/systemd-bash-completion.sh
new file mode 100644 (file)
index 0000000..52dc72b
--- /dev/null
@@ -0,0 +1,607 @@
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd 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 Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__systemctl() {
+        systemctl --full --no-legend "$@"
+}
+
+__contains_word () {
+        local word=$1; shift
+        for w in $*; do [[ $w = $word ]] && return 0; done
+        return 1
+}
+
+__filter_units_by_property () {
+        local property=$1 value=$2 ; shift 2
+        local units=("$@")
+        local props
+        IFS=$'\n' read -rd '' -a props < \
+            <(__systemctl show --property "$property" -- "${units[@]}")
+        for ((i=0; $i < ${#units[*]}; i++)); do
+                if [[ "${props[i]}" = "$property=$value" ]]; then
+                        printf "%s\n" "${units[i]}"
+                fi
+        done
+}
+
+__get_all_units      () { __systemctl list-units --all \
+        | { while read -r a b; do printf "%s\n" "$a"; done; }; }
+__get_active_units   () { __systemctl list-units       \
+        | { while read -r a b; do printf "%s\n" "$a"; done; }; }
+__get_inactive_units () { __systemctl list-units --all \
+        | { while read -r a b c d; do [[ $c == "inactive" ]] && printf "%s\n" "$a"; done; }; }
+__get_failed_units   () { __systemctl list-units       \
+        | { while read -r a b c d; do [[ $c == "failed"   ]] && printf "%s\n" "$a"; done; }; }
+__get_enabled_units  () { __systemctl list-unit-files  \
+        | { while read -r a b c  ; do [[ $b == "enabled"  ]] && printf "%s\n" "$a"; done; }; }
+__get_disabled_units () { __systemctl list-unit-files  \
+        | { while read -r a b c  ; do [[ $b == "disabled" ]] && printf "%s\n" "$a"; done; }; }
+__get_masked_units   () { __systemctl list-unit-files  \
+        | { while read -r a b c  ; do [[ $b == "masked"   ]] && printf "%s\n" "$a"; done; }; }
+
+_systemctl () {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local i verb comps
+
+        local -A OPTS=(
+               [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
+                             --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
+                             --order --require --quiet -q --privileged -P --system --user --version --runtime'
+                      [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
+        )
+
+        if __contains_word "$prev" ${OPTS[ARG]}; then
+                case $prev in
+                        --signal|-s)
+                                comps=$(compgen -A signal)
+                        ;;
+                        --type|-t)
+                                comps='automount device mount path service snapshot socket swap target timer'
+                        ;;
+                        --kill-who)
+                                comps='all control main'
+                        ;;
+                        --kill-mode)
+                                comps='control-group process'
+                        ;;
+                        --root)
+                                comps=$(compgen -A directory -- "$cur" )
+                                compopt -o filenames
+                        ;;
+                        --host|-H)
+                                comps=$(compgen -A hostname)
+                        ;;
+                        --property|-p)
+                                comps=''
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+
+        if [[ "$cur" = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+                [ALL_UNITS]='is-active is-failed is-enabled status show mask preset'
+            [ENABLED_UNITS]='disable reenable'
+           [DISABLED_UNITS]='enable'
+             [FAILED_UNITS]='reset-failed'
+          [STARTABLE_UNITS]='start'
+          [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
+         [ISOLATABLE_UNITS]='isolate'
+         [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
+        [RESTARTABLE_UNITS]='restart reload-or-restart'
+             [MASKED_UNITS]='unmask'
+                     [JOBS]='cancel'
+                [SNAPSHOTS]='delete'
+                     [ENVS]='set-environment unset-environment'
+               [STANDALONE]='daemon-reexec daemon-reload default dot dump
+                             emergency exit halt hibernate hybrid-sleep kexec list-jobs
+                             list-units list-unit-files poweroff reboot rescue
+                             show-environment suspend'
+                     [NAME]='snapshot load'
+                     [FILE]='link'
+        )
+
+        for ((i=0; $i <= $COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if   [[ -z $verb ]]; then
+                comps="${VERBS[*]}"
+
+        elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
+                comps=$( __get_all_units )
+
+        elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
+                comps=$( __get_enabled_units )
+
+        elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
+                comps=$( __get_disabled_units )
+
+        elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
+                comps=$( __filter_units_by_property CanStart yes \
+                      $( __get_inactive_units \
+                        | while read -r line; do \
+                                [[ "$line" =~ \.(device|snapshot)$ ]] || printf "%s\n" "$line"; \
+                        done ))
+
+        elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
+                comps=$( __filter_units_by_property CanStart yes \
+                      $( __get_all_units \
+                        | while read -r line; do \
+                                [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || printf "%s\n" "$line"; \
+                        done ))
+
+        elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
+                comps=$( __filter_units_by_property CanStop yes \
+                      $( __get_active_units ) )
+
+        elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
+                comps=$( __filter_units_by_property CanReload yes \
+                      $( __get_active_units ) )
+
+        elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
+                comps=$( __filter_units_by_property AllowIsolate yes \
+                      $( __get_all_units ) )
+
+        elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
+                comps=$( __get_failed_units )
+
+        elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
+                comps=$( __get_masked_units )
+
+        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
+                comps=''
+
+        elif __contains_word "$verb" ${VERBS[JOBS]}; then
+                comps=$( __systemctl list-jobs | { while read -r a b; do printf "%s\n" "$a"; done; } )
+
+        elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then
+                comps=$( __systemctl list-units --type snapshot --full --all \
+                        | { while read -r a b; do printf "%s\n" "$a"; done; } )
+
+        elif __contains_word "$verb" ${VERBS[ENVS]}; then
+                comps=$( __systemctl show-environment \
+                    | while read -r line; do printf "%s\n" "${line%%=*}=";done )
+                compopt -o nospace
+
+        elif __contains_word "$verb" ${VERBS[FILE]}; then
+                comps=$( compgen -A file -- "$cur" )
+                compopt -o filenames
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+complete -F _systemctl systemctl
+
+__get_all_sessions () { loginctl list-sessions | { while read -r a b; do printf "%s\n" "$a"; done; } ; }
+__get_all_users    () { loginctl list-users    | { while read -r a b; do printf "%s\n" "$b"; done; } ; }
+__get_all_seats    () { loginctl list-seats    | { while read -r a b; do printf "%s\n" "$a"; done; } ; }
+
+_loginctl () {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local i verb comps
+
+        local -A OPTS=(
+               [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
+                      [ARG]='--host -H --kill-who --property -p --signal -s'
+        )
+
+        if __contains_word "$prev" ${OPTS[ARG]}; then
+                case $prev in
+                        --signal|-s)
+                                comps=$(compgen -A signal)
+                        ;;
+                        --kill-who)
+                                comps='all leader'
+                        ;;
+                        --host|-H)
+                                comps=$(compgen -A hostname)
+                        ;;
+                        --property|-p)
+                                comps=''
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+
+        if [[ "$cur" = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+                [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
+                [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
+                [SEATS]='seat-status show-seat terminate-seat'
+                [STANDALONE]='list-sessions list-users list-seats flush-devices'
+                [ATTACH]='attach'
+        )
+
+        for ((i=0; $i <= $COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if   [[ -z $verb ]]; then
+                comps="${VERBS[*]}"
+
+        elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
+                comps=$( __get_all_sessions )
+
+        elif __contains_word "$verb" ${VERBS[USERS]}; then
+                comps=$( __get_all_users )
+
+        elif __contains_word "$verb" ${VERBS[SEATS]}; then
+                comps=$( __get_all_seats )
+
+        elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+                comps=''
+
+        elif __contains_word "$verb" ${VERBS[ATTACH]}; then
+                if [[ $prev = $verb ]]; then
+                        comps=$( __get_all_seats )
+                else
+                        comps=$(compgen -A file -- "$cur" )
+                        compopt -o filenames
+                fi
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+complete -F _loginctl loginctl
+
+__journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
+                  ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} COREDUMP_EXE
+                  _{P,U,G}ID _COMM _EXE _CMDLINE
+                  _AUDIT_{SESSION,LOGINUID}
+                  _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID}
+                  _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP
+                  _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT
+                  _KERNEL_{DEVICE,SUBSYSTEM}
+                  _UDEV_{SYSNAME,DEVNODE,DEVLINK}
+                  __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP)
+
+_journalctl() {
+        local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local -A OPTS=(
+                [STANDALONE]='-a --all --full
+                              -b --this-boot --disk-usage -f --follow --header
+                              -h --help -l --local --new-id128 -m --merge --no-pager
+                              --no-tail -q --quiet --setup-keys --this-boot --verify
+                              --version --list-catalog --update-catalog'
+                       [ARG]='-D --directory -F --field -o --output -u --unit'
+                [ARGUNKNOWN]='-c --cursor --interval -n --lines -p --priority --since --until
+                              --verify-key'
+        )
+
+        if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then
+                case $prev in
+                        --directory|-D)
+                                comps=$(compgen -d -- "$cur")
+                                compopt -o filenames
+                        ;;
+                        --output|-o)
+                                comps='short short-monotonic verbose export json cat'
+                        ;;
+                        --field|-F)
+                                comps=${__journal_fields[*]}
+                        ;;
+                        --unit|-u)
+                                comps=$(journalctl -F '_SYSTEMD_UNIT')
+                        ;;
+                        *)
+                                return 0
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        if [[ $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        elif [[ $cur = *=* ]]; then
+                mapfile -t field_vals < <(journalctl -F "${prev%=}" 2>/dev/null)
+                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
+        elif [[ $prev = '=' ]]; then
+                mapfile -t field_vals < <(journalctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
+                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "$cur") )
+        else
+                compopt -o nospace
+                COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
+        fi
+}
+complete -F _journalctl journalctl
+
+_coredumpctl() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field'
+
+        local -A VERBS=(
+            [LIST]='list'
+            [DUMP]='dump gdb'
+        )
+
+        if __contains_word "$prev" '--output -o'; then
+                comps=$( compgen -A file -- "$cur" )
+                compopt -o filenames
+        elif __contains_word "$prev" '--FIELD -F'; then
+                comps=$( compgen -W '${__journal_fields[*]}' -- "$cur" )
+        elif [[ $cur = -* ]]; then
+                comps=${OPTS}
+        elif __contains_word "$prev" ${VERBS[*]} &&
+           ! __contains_word ${COMP_WORDS[COMP_CWORD-2]} '--output -o -F --field'; then
+                compopt -o nospace
+                COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
+               return 0
+        elif [[ $cur = *=* ]]; then
+                mapfile -t field_vals < <(systemd-coredumpctl -F "${prev%=}" 2>/dev/null)
+                COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
+                return 0
+        elif [[ $prev = '=' ]]; then
+                mapfile -t field_vals < <(systemd-coredumpctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
+                comps=${field_vals[*]}
+        else
+                for ((i=0; i <= COMP_CWORD; i++)); do
+                        if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+                                verb=${COMP_WORDS[i]}
+                                break
+                        fi
+                done
+
+                if [[ -z $verb ]]; then
+                        comps=${VERBS[*]}
+                elif __contains_word "$verb" ${VERBS[LIST]} ${VERBS[DUMP]}; then
+                        comps=''
+                fi
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+complete -F _coredumpctl systemd-coredumpctl
+
+_timedatectl() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --adjust-system-clock --no-pager
+                    --no-ask-password -H --host'
+
+        if __contains_word "$prev" $OPTS; then
+                case $prev in
+                        --host|-H)
+                                comps=''
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        if [[ $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+                  [BOOLEAN]='set-local-rtc set-ntp'
+               [STANDALONE]='status set-time list-timezones'
+                [TIMEZONES]='set-timezone'
+                     [TIME]='set-time'
+        )
+
+        for ((i=0; i <= COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if [[ -z $verb ]]; then
+                comps=${VERBS[*]}
+        elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then
+                comps='true false'
+        elif __contains_word "$verb" ${VERBS[TIMEZONES]}; then
+                comps=$(command timedatectl list-timezones)
+        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[TIME]}; then
+                comps=''
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+complete -F _timedatectl timedatectl
+
+_localectl() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --no-convert --no-pager --no-ask-password
+                    -H --host'
+
+        if __contains_word "$prev" $OPTS; then
+                case $prev in
+                        --host|-H)
+                                comps=''
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        if [[ $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+               [STANDALONE]='status list-locales list-keymaps'
+                  [LOCALES]='set-locale'
+                  [KEYMAPS]='set-keymap'
+                      [X11]='set-x11-keymap'
+        )
+
+        for ((i=0; i <= COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if [[ -z $verb ]]; then
+                comps=${VERBS[*]}
+        elif __contains_word "$verb" ${VERBS[LOCALES]}; then
+                comps=$(command localectl list-locales)
+        elif __contains_word "$verb" ${VERBS[KEYMAPS]}; then
+                comps=$(command localectl list-keymaps)
+        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[X11]}; then
+                comps=''
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+complete -F _localectl localectl
+
+_hostnamectl() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --transient --static --pretty
+                    --no-ask-password -H --host'
+
+        if [[ $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        local -A VERBS=(
+                [STANDALONE]='status'
+                     [ICONS]='set-icon-name'
+                      [NAME]='set-hostname'
+        )
+
+        for ((i=0; i <= COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if [[ -z $verb ]]; then
+                comps=${VERBS[*]}
+        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[ICONS]} ${VERBS[NAME]}; then
+                comps=''
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+complete -F _hostnamectl hostnamectl
+
+__get_all_sysdevs() {
+        local -a devs=(/sys/bus/*/devices/*/ /sys/class/*/*/)
+        printf '%s\n' "${devs[@]%/}"
+}
+
+_udevadm() {
+        local i verb comps
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local OPTS='-h --help --version --debug'
+
+        local -A VERBS=(
+                [INFO]='info'
+                [TRIGGER]='trigger'
+                [SETTLE]='settle'
+                [CONTROL]='control'
+                [MONITOR]='monitor'
+                [HWDB]='hwdb'
+                [TESTBUILTIN]='test-builtin'
+                [TEST]='test'
+        )
+
+        for ((i=0; $i <= $COMP_CWORD; i++)); do
+                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+                        verb=${COMP_WORDS[i]}
+                        break
+                fi
+        done
+
+        if [[ -z $verb  && $cur = -* ]]; then
+                COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+                return 0
+        fi
+
+        if [[ -z $verb ]]; then
+                comps=${VERBS[*]}
+
+        elif __contains_word "$verb" ${VERBS[INFO]}; then
+                if [[ $cur = -* ]]; then
+                        comps='--help --query= --path= --name= --root --attribute-walk --export-db --cleanup-db'
+                else
+                        comps=$( __get_all_sysdevs )
+                fi
+
+        elif __contains_word "$verb" ${VERBS[TRIGGER]}; then
+                comps='--help --verbose --dry-run --type= --action= --subsystem-match=
+                       --subsystem-nomatch= --attr-match= --attr-nomatch= --property-match=
+                       --tag-match= --sysname-match= --parent-match='
+
+        elif __contains_word "$verb" ${VERBS[SETTLE]}; then
+                comps='--help --timeout= --seq-start= --seq-end= --exit-if-exists= --quiet'
+
+        elif __contains_word "$verb" ${VERBS[CONTROL]}; then
+                comps='--help --exit --log-priority= --stop-exec-queue --start-exec-queue
+                       --reload --property= --children-max= --timeout='
+
+        elif __contains_word "$verb" ${VERBS[MONITOR]}; then
+                comps='--help --kernel --udev --property --subsystem-match= --tag-match='
+
+        elif __contains_word "$verb" ${VERBS[HWDB]}; then
+                comps='--help --update --test='
+
+        elif __contains_word "$verb" ${VERBS[TEST]}; then
+                if [[ $cur = -* ]]; then
+                        comps='--help --action='
+                else
+                        comps=$( __get_all_sysdevs )
+                fi
+
+        elif __contains_word "$verb" ${VERBS[TESTBUILTIN]}; then
+                      comps='blkid btrfs firmware hwdb input_id kmod net_id path_id usb_id uaccess'
+        fi
+
+        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        return 0
+}
+complete -F _udevadm udevadm
diff --git a/shell-completion/systemd-zsh-completion.zsh b/shell-completion/systemd-zsh-completion.zsh
new file mode 100644 (file)
index 0000000..d5fb850
--- /dev/null
@@ -0,0 +1,1029 @@
+#compdef systemctl loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent
+
+_ctls()
+{
+    local curcontext="$curcontext" state lstate line
+    case "$service" in
+        systemctl)
+            # -s for aggregated options like -aP
+            _arguments -s \
+                {-h,--help}'[Show help]' \
+                '--version[Show package version]' \
+                {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \
+                \*{-p,--property=}'[Show only properties by specific name]:unit property' \
+                {-a,--all}'[Show all units/properties, including dead/empty ones]' \
+                '--failed[Show only failed units]' \
+                "--full[Don't ellipsize unit names on output]" \
+                '--fail[When queueing a new job, fail if conflicting jobs are pending]' \
+                '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \
+                '--kill-who=[Who to send signal to]:killwho:(main control all)' \
+                {-s,--signal=}'[Which signal to send]:signal:_signals' \
+                {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \
+                {-P,--privileged}'[Acquire privileges before execution]' \
+                {-q,--quiet}'[Suppress output]' \
+                '--no-block[Do not wait until operation finished]' \
+                "--no-wall[Don't send wall message before halt/power-off/reboot]" \
+                "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \
+                '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \
+                '--no-pager[Do not pipe output into a pager]' \
+                '--no-ask-password[Do not ask for system passwords]' \
+                '--order[When generating graph for dot, show only order]' \
+                '--require[When generating graph for dot, show only requirement]' \
+                '--system[Connect to system manager]' \
+                '--user[Connect to user service manager]' \
+                '--global[Enable/disable unit files globally]' \
+                {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \
+                '--root=[Enable unit files in the specified root directory]:directory:_directories' \
+                '--runtime[Enable unit files only temporarily until next reboot]' \
+                {-n,--lines=}'[Journal entries to show]:number of entries' \
+                {-o,--output=}'[Change journal output mode]:modes:_outputmodes' \
+                '*::systemctl command:_systemctl_command'
+        ;;
+        loginctl)
+            _arguments -s \
+                {-h,--help}'[Show help]' \
+                '--version[Show package version]' \
+                \*{-p,--property=}'[Show only properties by this name]:unit property' \
+                {-a,--all}'[Show all properties, including empty ones]' \
+                '--kill-who=[Who to send signal to]:killwho:(main control all)' \
+                {-s,--signal=}'[Which signal to send]:signal:_signals' \
+                '--no-ask-password[Do not ask for system passwords]' \
+                {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \
+                {-P,--privileged}'[Acquire privileges before execution]' \
+                '--no-pager[Do not pipe output into a pager]' \
+                '*::loginctl command:_loginctl_command'
+        ;;
+
+        hostnamectl)
+            _arguments -s \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                '--transient[Only set transient hostname]' \
+                '--static[Only set static hostname]' \
+                '--pretty[Only set pretty hostname]' \
+                '--no-ask-password[Do not prompt for password]' \
+                {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \
+                '*::hostnamectl commands:_hostnamectl_command'
+        ;;
+        journalctl)
+            _arguments -s \
+                '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \
+                '--until=[Stop showing entries older or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \
+                {-c,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \
+                {-b,--this-boot}'[Show data only from current boot]' \
+                {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \
+                {-p,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \
+                {-f,--follow}'[Follow journal]' \
+                {-n,--lines=}'[Number of journal entries to show]:integer' \
+                '--no-tail[Show all lines, even in follow mode]' \
+                {-o,--output=}'[Change journal output mode]:output modes:_outputmodes' \
+                '--full[Show long fields in full]' \
+                {-a,--all}'[Show all fields, including long and unprintable]' \
+                {-q,--quiet}"[Don't show privilege warning]" \
+                '--no-pager[Do not pipe output into a pager]' \
+                {-m,--merge}'[Show entries from all available journals]' \
+                {-D,--directory=}'[Show journal files from directory]:directories:_directories' \
+                '--interval=[Time interval for changing the FSS sealing key]:time interval' \
+                '--verify-key=[Specify FSS verification key]:FSS key' \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                '--new-id128[Generate a new 128 Bit ID]' \
+                '--header[Show journal header information]' \
+                '--disk-usage[Show total disk usage]' \
+                {-F,--field=}'[List all values a certain field takes]:Fields:_list_fields' \
+                '--setup-keys[Generate new FSS key pair]' \
+                '--verify[Verify journal file consistency]' \
+                '--list-catalog[List messages in catalog]' \
+                '--update-catalog[Update binary catalog database]' \
+        ;;
+        localectl)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                "--no-convert[Don't convert keyboard mappings]" \
+                '--no-pager[Do not pipe output into a pager]' \
+                '--no-ask-password[Do not prompt for password]' \
+                {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \
+                '*::localectl commands:_localectl_command'
+        ;;
+        systemd-coredumpctl)
+            _arguments \
+                {-o,--output=}'[Write output to FILE]:output file:_files' \
+                '--no-pager[Do not pipe output into a pager]' \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                '*::systemd-coredumpctl commands:_systemd-coredumpctl_command'
+
+        ;;
+        timedatectl)
+            _arguments -s \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                '--adjust-system-clock[Adjust system clock when changing local RTC mode]' \
+                '--no-pager[Do not pipe output into a pager]' \
+                '--no-ask-password[Do not prompt for password]' \
+                {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \
+                '*::timedatectl commands:_timedatectl_command'
+        ;;
+        udevadm)
+            _arguments \
+                '--debug[Print debug messages to stderr]' \
+                '--version[Print version number]' \
+                '--help[Print help text]' \
+                '*::udevadm commands:_udevadm_command'
+        ;;
+        systemd-analyze)
+            _arguments \
+                {-h,--help}'[Show help text.]' \
+                '--user[Shows performance data of user sessions instead of the system manager.]' \
+                '*::systemd-analyze commands:_systemd_analyze_command'
+        ;;
+        systemd-ask-password)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--icon=[Icon name]' \
+                '--timeout=[Timeout in sec]' \
+                '--no-tty[Ask question via agent even on TTY]' \
+                '--accept-cached[Accept cached passwords]' \
+                '--multiple[List multiple passwords if available]'
+        ;;
+        systemd-cat)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version.]' \
+                {-t,--identifier=}'[Set syslog identifier.]' \
+                {-p,--priority=}'[Set priority value.]:value:({0..7})' \
+                '--level-prefix=[Control whether level prefix shall be parsed.]:boolean:(1 0)' \
+                ':Message'
+        ;;
+        systemd-cgls)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                '--no-pager[Do not pipe output into a pager]' \
+                {-a,--all}'[Show all groups, including empty]' \
+                '-k[Include kernel threads in output]' \
+                ':cgroups:(cpuset cpu cpuacct memory devices freezer net_cls blkio)'
+        ;;
+        systemd-cgtop)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Print version and exit]' \
+                '(-c -m -i -t)-p[Order by path]' \
+                '(-c -p -m -i)-t[Order by number of tasks]' \
+                '(-m -p -i -t)-c[Order by CPU load]' \
+                '(-c -p -i -t)-m[Order by memory load]' \
+                '(-c -m -p -t)-i[Order by IO load]' \
+                {-d,--delay=}'[Specify delay]' \
+                {-n,--iterations=}'[Run for N iterations before exiting]' \
+                {-b,--batch}'[Run in batch mode, accepting no input]' \
+                '--depth=[Maximum traversal depth]'
+        ;;
+        systemd-delta)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                '--no-pager[Do not pipe output into a pager]' \
+                '--diff=[Show a diff when overridden files differ]:boolean:(1 0)' \
+                {-t,--type=}'[Only display a selected set of override types]:types:(masked equivalent redirected overridden unchanged)' \
+                ':SUFFIX:(tmpfiles.d sysctl.d systemd/system)'
+        ;;
+        systemd-detect-virt)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                {-c,--container}'[Only detect whether we are run in a container]' \
+                {-v,--vm}'[Only detect whether we are run in a VM]' \
+                {-q,--quiet}"[Don't output anything, just set return value]"
+        ;;
+        systemd-inhibit)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                '--what=[Operations to inhibit]:options:(shutdown sleep idle handle-power-key handle-suspend-key handle-hibernate-key handle-lid-switch)' \
+                '--who=[A descriptive string who is inhibiting]' \
+                '--why=[A descriptive string why is being inhibited]' \
+                '--mode=[One of block or delay]' \
+                '--list[List active inhibitors]' \
+                '*:commands:_systemd_inhibit_command'
+        ;;
+        systemd-machine-id-setup)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]'
+        ;;
+        systemd-notify)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                '--version[Show package version]' \
+                '--ready[Inform the init system about service start-up completion.]' \
+                '--pid=[Inform the init system about the main PID of the daemon]' \
+                '--status=[Send a free-form status string for the daemon to the init systemd]' \
+                '--booted[Returns 0 if the system was booted up with systemd]' \
+                '--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)'
+        ;;
+        systemd-nspawn)
+            _arguments \
+                {-h,--help}'[Show this help]' \
+                {--directory=,-D}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \
+                {--boot,-b}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \
+                {--user=,-u}'[Run the command under specified user, create home directory and cd into it.]' \
+                '--uuid=[Set the specified uuid for the container.]' \
+                {--controllers=,-C}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \
+                '--private-network[Turn off networking in the container. This makes all network interfaces unavailable in the container, with the exception of the loopback device.]' \
+                '--read-only[Mount the root file system read only for the container.]' \
+                '--capability=[List one or more additional capabilities to grant the container.]:capabilities:_systemd-nspawn' \
+                "--link-journal=[Control whether the container's journal shall be made visible to the host system.]:options:(no, host, guest, auto)" \
+                '-j[Equivalent to --link-journal=guest.]'
+        ;;
+        systemd-tmpfiles)
+            _arguments \
+                '--create[Create, set ownership/permissions based on the config files.]' \
+                '--clean[Clean up all files and directories with an age parameter configured.]' \
+                '--remove[All files and directories marked with r, R in the configuration files are removed.]' \
+                '--prefix=[Only apply rules that apply to paths with the specified prefix.]' \
+                '--help[Prints a short help text and exits.]' \
+                '*::files:_files'
+        ;;
+        systemd-tty-ask-password-agent)
+            _arguments \
+                {-h,--help}'[Prints a short help text and exits.]' \
+                '--version[Prints a short version string and exits.]' \
+                '--list[Lists all currently pending system password requests.]' \
+                '--query[Process all currently pending system password requests by querying the user on the calling TTY.]' \
+                '--watch[Continuously process password requests.]' \
+                '--wall[Forward password requests to wall(1).]' \
+                '--plymouth[Ask question with plymouth(8).]' \
+                '--console[Ask question on /dev/console.]'
+        ;;
+        *) _message 'eh?' ;;
+    esac
+}
+
+_systemd-nspawn(){
+    local -a _caps
+    _caps=( CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH
+            CAP_FOWNER CAP_FSETID CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE
+            CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETGID CAP_SETFCAP CAP_SETPCAP
+            CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_TTY_CONFIG
+            CAP_SYS_RESOURCE CAP_SYS_BOOT )
+    _values -s , 'capabilities' "$_caps[@]"
+}
+
+_systemd_inhibit_command(){
+    if (( CURRENT == 1 )); then 
+        compset -q
+        _normal
+    else
+        local n=${words[(b:2:i)[^-]*]}
+        if (( n <= CURRENT )); then
+            compset -n $n
+            _alternative \
+                'files:file:_files' \
+                'commands:command:_normal' && return 0
+        fi
+        _default
+    fi
+
+}
+
+_systemd_analyze_command(){
+    local -a _systemd_analyze_cmds
+    _systemd_analyze_cmds=(
+        'time:Print the time taken to start'
+        'blame:prints a list of all running units, ordered by the time they took to initialize'
+        'plot:prints an SVG graphic detailing which system services have been started at what time'
+    )
+
+    if (( CURRENT == 1 )); then
+        _describe "options" _systemd_analyze_cmds
+    else
+        _message "no more options"
+    fi
+}
+
+_hosts_or_user_at_host()
+{
+  _alternative \
+    'users-hosts:: _user_at_host' \
+    'hosts:: _hosts'
+}
+
+_outputmodes() {
+    local -a _output_opts
+    _output_opts=(short short-monotonic verbose export json json-pretty json-see cat)
+    _describe -t output 'output mode' _output_opts || compadd "$@"
+}
+        
+
+(( $+functions[_systemctl_command] )) || _systemctl_command()
+{
+  local -a _systemctl_cmds
+  _systemctl_cmds=(
+    "list-units:List units"
+    "start:Start (activate) one or more units"
+    "stop:Stop (deactivate) one or more units"
+    "reload:Reload one or more units"
+    "restart:Start or restart one or more units"
+    "condrestart:Restart one or more units if active"
+    "try-restart:Restart one or more units if active"
+    "reload-or-restart:Reload one or more units if possible, otherwise start or restart"
+    "force-reload:Reload one or more units if possible, otherwise restart if active"
+    "hibernate:Hibernate the system"
+    "hybrid-sleep:Hibernate and suspend the system"
+    "reload-or-try-restart:Reload one or more units if possible, otherwise restart if active"
+    "isolate:Start one unit and stop all others"
+    "kill:Send signal to processes of a unit"
+    "is-active:Check whether units are active"
+    "is-failed:Check whether units are failed"
+    "status:Show runtime status of one or more units"
+    "show:Show properties of one or more units/jobs or the manager"
+    "reset-failed:Reset failed state for all, one, or more units"
+    "load:Load one or more units"
+    "list-unit-files:List installed unit files"
+    "enable:Enable one or more unit files"
+    "disable:Disable one or more unit files"
+    "reenable:Reenable one or more unit files"
+    "preset:Enable/disable one or more unit files based on preset configuration"
+    "mask:Mask one or more units"
+    "unmask:Unmask one or more units"
+    "link:Link one or more units files into the search path"
+    "is-enabled:Check whether unit files are enabled"
+    "list-jobs:List jobs"
+    "cancel:Cancel all, one, or more jobs"
+    "dump:Dump server status"
+    "dot:Dump dependency graph for dot(1)"
+    "snapshot:Create a snapshot"
+    "delete:Remove one or more snapshots"
+    "show-environment:Dump environment"
+    "set-environment:Set one or more environment variables"
+    "unset-environment:Unset one or more environment variables"
+    "daemon-reload:Reload systemd manager configuration"
+    "daemon-reexec:Reexecute systemd manager"
+    "default:Enter system default mode"
+    "rescue:Enter system rescue mode"
+    "emergency:Enter system emergency mode"
+    "halt:Shut down and halt the system"
+    "suspend:Suspend the system"
+    "poweroff:Shut down and power-off the system"
+    "reboot:Shut down and reboot the system"
+    "kexec:Shut down and reboot the system with kexec"
+    "exit:Ask for user instance termination"
+  )
+
+  if (( CURRENT == 1 )); then
+    _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@"
+  else
+    local curcontext="$curcontext"
+
+    cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}"
+    # Deal with any aliases
+    case $cmd in
+      condrestart) cmd="try-restart";;
+      force-reload) cmd="reload-or-try-restart";;
+    esac
+
+    if (( $#cmd )); then
+      curcontext="${curcontext%:*:*}:systemctl-${cmd}:"
+
+      local update_policy
+      zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+      if [[ -z "$update_policy" ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy
+      fi
+
+      _call_function ret _systemctl_$cmd || _message 'no more arguments'
+    else
+      _message "unknown systemctl command: $words[1]"
+    fi
+    return ret
+  fi
+}
+
+__systemctl()
+{
+  systemctl --full --no-legend --no-pager "$@"
+}
+
+
+# Fills the unit list
+_systemctl_all_units()
+{
+  if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) &&
+    ! _retrieve_cache SYS_ALL_UNITS;
+  then
+    _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo "$a"; done; }) )
+    _store_cache SYS_ALL_UNITS _sys_all_units
+  fi
+}
+
+# Fills the unit list including all file units
+_systemctl_really_all_units()
+{
+  local -a all_unit_files;
+  local -a really_all_units;
+  if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) &&
+    ! _retrieve_cache SYS_REALLY_ALL_UNITS;
+  then
+    all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo "$a"; done; }) )
+    _systemctl_all_units
+    really_all_units=($_sys_all_units $all_unit_files)
+    _sys_really_all_units=(${(u)really_all_units})
+    _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units
+  fi
+}
+
+_filter_units_by_property() {
+  local property=$1 value=$2 ; shift ; shift
+  local -a units ; units=($*)
+  local prop unit
+  for ((i=1; $i <= ${#units[*]}; i++)); do
+    # FIXME: "Failed to issue method call: Unknown unit" errors are ignored for
+    # now (related to DBUS_ERROR_UNKNOWN_OBJECT). in the future, we need to
+    # revert to calling 'systemctl show' once for all units, which is way
+    # faster
+    unit=${units[i]}
+    prop=${(f)"$(_call_program units "$service show --no-pager --property="$property" ${unit} 2>/dev/null")"}
+    if [[ "${prop}" = "$property=$value" ]]; then
+      echo "${unit}"
+    fi
+  done
+}
+
+_systemctl_active_units()  {_sys_active_units=(  $(__systemctl list-units          | { while read a b; do echo "$a"; done; }) )}
+_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all    | { while read a b c d; do [[ $c == "inactive" ]] && echo "$a"; done; }) )}
+_systemctl_failed_units()  {_sys_failed_units=(  $(__systemctl list-units --failed | { while read a b; do echo "$a"; done; }) )}
+_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files     | { while read a b; do [[ $b == "enabled" ]] && echo "$a"; done; }) )}
+_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files     | { while read a b; do [[ $b == "disabled" ]] && echo "$a"; done; }) )}
+_systemctl_masked_units()  {_sys_masked_units=(  $(__systemctl list-unit-files     | { while read a b; do [[ $b == "masked" ]] && echo "$a"; done; }) )}
+
+# Completion functions for ALL_UNITS
+for fun in is-active is-failed is-enabled status show mask preset ; do
+  (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
+  {
+    _systemctl_really_all_units
+    compadd "$@" -a - _sys_really_all_units
+  }
+done
+
+# Completion functions for ENABLED_UNITS
+for fun in disable reenable ; do
+  (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
+  {
+    _systemctl_enabled_units
+    compadd "$@" -a - _sys_enabled_units
+  }
+done
+
+# Completion functions for DISABLED_UNITS
+(( $+functions[_systemctl_enable] )) || _systemctl_enable()
+{
+  _systemctl_disabled_units
+  compadd "$@" -a - _sys_disabled_units
+}
+
+# Completion functions for FAILED_UNITS
+(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed()
+{
+  _systemctl_failed_units
+  compadd "$@" -a - _sys_failed_units || _message "no failed unit found"
+}
+
+# Completion functions for STARTABLE_UNITS
+(( $+functions[_systemctl_start] )) || _systemctl_start()
+{
+  _systemctl_inactive_units
+  compadd "$@" -a - _sys_inactive_units
+}
+
+# Completion functions for STOPPABLE_UNITS
+for fun in stop kill try-restart condrestart ; do
+  (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
+  {
+    _systemctl_active_units
+    compadd "$@" - $( _filter_units_by_property CanStop yes \
+      ${_sys_active_units[*]} )
+  }
+done
+
+# Completion functions for ISOLATABLE_UNITS
+(( $+functions[_systemctl_isolate] )) || _systemctl_isolate()
+{
+  _systemctl_all_units
+  compadd "$@" - $( _filter_units_by_property AllowIsolate yes \
+    ${_sys_all_units[*]} )
+}
+
+# Completion functions for RELOADABLE_UNITS
+for fun in reload reload-or-try-restart force-reload ; do
+  (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
+  {
+    _systemctl_active_units
+    compadd "$@" - $( _filter_units_by_property CanReload yes \
+      ${_sys_active_units[*]} )
+  }
+done
+
+# Completion functions for RESTARTABLE_UNITS
+for fun in restart reload-or-restart ; do
+  (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
+  {
+    _systemctl_all_units
+    compadd "$@" - $( _filter_units_by_property CanStart yes \
+      ${_sys_all_units[*]} | while read line; do \
+      [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || echo "$line"; \
+      done )
+  }
+done
+
+# Completion functions for MASKED_UNITS
+(( $+functions[_systemctl_unmask] )) || _systemctl_unmask()
+{
+  _systemctl_masked_units
+  compadd "$@" -a - _sys_masked_units || _message "no masked unit found"
+}
+
+# Completion functions for JOBS
+(( $+functions[_systemctl_cancel] )) || _systemctl_cancel()
+{
+  compadd "$@" - $(__systemctl list-jobs \
+    | cut -d' ' -f1  2>/dev/null ) || _message "no job found"
+}
+
+# Completion functions for SNAPSHOTS
+(( $+functions[_systemctl_delete] )) || _systemctl_delete()
+{
+  compadd "$@" - $(__systemctl list-units --type snapshot --all \
+    | cut -d' ' -f1  2>/dev/null ) || _message "no snampshot found"
+}
+
+# Completion functions for ENVS
+for fun in set-environment unset-environment ; do
+  (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
+  {
+    local fun=$0 ; fun=${fun##_systemctl_}
+    local suf
+    if [[ "${fun}" = "set-environment" ]]; then
+      suf='-S='
+    fi
+
+    compadd "$@" ${suf} - $(systemctl show-environment \
+      | while read line; do echo "${line%%\=}";done )
+  }
+done
+
+(( $+functions[_systemctl_link] )) || _systemctl_link() { _files }
+
+# no systemctl completion for:
+#    [STANDALONE]='daemon-reexec daemon-reload default dot dump
+#                  emergency exit halt kexec list-jobs list-units
+#                  list-unit-files poweroff reboot rescue show-environment'
+#         [NAME]='snapshot load'
+
+_systemctl_caching_policy()
+{
+  local _sysunits
+  local -a oldcache
+
+  # rebuild if cache is more than a day old
+  oldcache=( "$1"(mh+1) )
+  (( $#oldcache )) && return 0
+
+  _sysunits=($(__systemctl --all | cut -d' ' -f1))
+
+  if (( $#_sysunits )); then
+    for unit in $_sysunits; do
+      [[ "$unit" -nt "$1" ]] && return 0
+    done
+  fi
+
+  return 1
+}
+
+_list_fields() {
+    local -a journal_fields
+    journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
+                    ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID}
+                    _{P,U,G}ID _COMM _EXE _CMDLINE
+                    _AUDIT_{SESSION,LOGINUID}
+                    _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID}
+                    _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP
+                    _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT
+                    _KERNEL_{DEVICE,SUBSYSTEM}
+                    _UDEV_{SYSNAME,DEVNODE,DEVLINK}
+                    __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP)
+    _describe 'possible fields' journal_fields
+}
+
+_journal_fields() {
+    local -a _fields cmd
+    cmd=("journalctl" "-F ${@[-1]}" "2>/dev/null" )
+    _fields=( ${(f)"$(_call_program fields $cmd[@])"} ) 
+    typeset -U _fields
+    _describe 'possible values' _fields
+}
+
+
+_loginctl_all_sessions(){_sys_all_sessions=($(loginctl list-sessions | { while read a b; do echo "$a"; done; }) )}
+_loginctl_all_users()   {_sys_all_users=(   $(loginctl list-users    | { while read a b; do echo "$a"; done; }) )}
+_loginctl_all_seats()   {_sys_all_seats=(   $(loginctl list-seats    | { while read a b; do echo "$a"; done; }) )}
+
+# Completion functions for SESSIONS
+for fun in session-status show-session activate lock-session unlock-session terminate-session kill-session ; do
+  (( $+functions[_loginctl_$fun] )) || _loginctl_$fun()
+  {
+    _loginctl_all_sessions
+    compadd "$@" -a - _sys_all_sessions
+  }
+done
+
+# Completion functions for USERS
+for fun in user-status show-user enable-linger disable-linger terminate-user kill-user ; do
+  (( $+functions[_loginctl_$fun] )) || _loginctl_$fun()
+  {
+    _loginctl_all_users
+    compadd "$@" -a - _sys_all_users
+  }
+done
+
+# Completion functions for SEATS
+(( $+functions[_loginctl_seats] )) || _loginctl_seats()
+{
+  _loginctl_all_seats
+  compadd "$@" -a - _sys_all_seats
+}
+for fun in seat-status show-seat terminate-seat ; do
+  (( $+functions[_loginctl_$fun] )) || _loginctl_$fun()
+  { _loginctl_seats }
+done
+
+# Completion functions for ATTACH
+(( $+functions[_loginctl_attach] )) || _loginctl_attach()
+{
+  _loginctl_all_seats
+
+  _arguments -w -C -S -s \
+    ':seat:_loginctl_seats' \
+    '*:device:_files'
+}
+
+# no loginctl completion for:
+# [STANDALONE]='list-sessions list-users list-seats flush-devices'
+
+(( $+functions[_loginctl_command] )) || _loginctl_command()
+{
+  local -a _loginctl_cmds
+  _loginctl_cmds=(
+    "list-sessions:List sessions"
+    "session-status:Show session status"
+    "show-session:Show properties of one or more sessions"
+    "activate:Activate a session"
+    "lock-session:Screen lock one or more sessions"
+    "unlock-session:Screen unlock one or more sessions"
+    "terminate-session:Terminate one or more sessions"
+    "kill-session:Send signal to processes of a session"
+    "list-users:List users"
+    "user-status:Show user status"
+    "show-user:Show properties of one or more users"
+    "enable-linger:Enable linger state of one or more users"
+    "disable-linger:Disable linger state of one or more users"
+    "terminate-user:Terminate all sessions of one or more users"
+    "kill-user:Send signal to processes of a user"
+    "list-seats:List seats"
+    "seat-status:Show seat status"
+    "show-seat:Show properties of one or more seats"
+    "attach:Attach one or more devices to a seat"
+    "flush-devices:Flush all device associations"
+    "terminate-seat:Terminate all sessions on one or more seats"
+  )
+
+  if (( CURRENT == 1 )); then
+    _describe -t commands 'loginctl command' _loginctl_cmds || compadd "$@"
+  else
+    local curcontext="$curcontext"
+
+    cmd="${${_loginctl_cmds[(r)$words[1]:*]%%:*}}"
+
+    if (( $#cmd )); then
+      curcontext="${curcontext%:*:*}:loginctl-${cmd}:"
+
+      _call_function ret _loginctl_$cmd || _message 'no more arguments'
+    else
+      _message "unknown loginctl command: $words[1]"
+    fi
+    return ret
+  fi
+}
+
+_hostnamectl_command() {
+    local -a _hostnamectl_cmds
+    _hostnamectl_cmds=(
+        "status:Show current hostname settings"
+        "set-hostname:Set system hostname"
+        "set-icon-name:Set icon name for host"
+    )
+    if (( CURRENT == 1 )); then
+        _describe -t commands 'hostnamectl commands' _hostnamectl_cmds || compadd "$@"
+    else
+        local curcontext="$curcontext"
+        cmd="${${_hostnamectl_cmds[(r)$words[1]:*]%%:*}}"
+        if (( $#cmd )); then
+            [[ $cmd == status ]] && msg="no options" || msg="options for $cmd"
+            _message "$msg"
+        else
+            _message "unknown hostnamectl command: $words[1]"
+        fi
+    fi
+}
+
+_localectl_set-locale() {
+    local -a _confs _locales
+    local expl suf
+    _locales=( ${(f)"$(_call_program locales "$service" list-locales)"} )
+    _confs=( ${${(f)"$(_call_program confs "locale 2>/dev/null")"}%\=*} )
+    if [[ -prefix 1 *\= ]]; then
+        local conf=${PREFIX%%\=*}
+        compset -P1 '*='
+        _wanted locales expl "locales configs" \
+            _combination localeconfs  confs=$conf locales "$@" -
+    else
+        compadd -S '='  $_confs
+    fi
+}
+
+_localectl_set-keymap() {
+    local -a _keymaps
+    _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} )
+    if (( CURRENT <= 3 )); then
+        _describe keymaps _keymaps
+    else
+        _message "no more options"
+    fi
+}
+
+_localectl_set-x11-keymap() {
+    if (( $+commands[pkg-config] )); then
+        local -a _file _layout _model _variant _options
+        local _xorg_lst
+        _xorg_lst=${"$($commands[pkg-config] xkeyboard-config --variable=xkb_base)"}
+        _file=( ${(ps:\n\!:)"$(<$_xorg_lst/rules/xorg.lst)"} )
+        _layout=( ${${${(M)${(f)_file[1]}:#  *}#  }%% *} )
+        _model=( ${${${(M)${(f)_file[2]}:#  *}#  }%% *} )
+        _variant=( ${${${(M)${(f)_file[3]}:#  *}#  }%% *} )
+        _options=( ${${${(M)${(f)_file[4]}:#  *}#  }%% *} )
+        #_layout=( ${(f)"$( echo $_file[1] | awk '/^  / {print $1}' )"} )
+        #_model=( ${(f)"$(echo $_file[2] | awk '/^  / {print $1}')"} )
+        #_variant=( ${(f)"$(echo $_file[3] | awk '/^  / {print $1}')"} )
+        #_options=( ${(f)"$(echo ${_file[4]//:/\\:} | awk '/^  / {print $1}')"} )
+        
+        case $CURRENT in 
+            2) _describe layouts _layout ;;
+            3) _describe models _model;;
+            4) _describe variants _variant;;
+            5) _describe options _options;;
+            *) _message "no more options"
+        esac
+    fi
+}
+
+
+_localectl_command() {
+    local -a _localectl_cmds
+    _localectl_cmds=(
+        'status:Show current locale settings'
+        'set-locale:Set system locale'
+        'list-locales:Show known locales'
+        'set-keymap:Set virtual console keyboard mapping'
+        'list-keymaps:Show known virtual console keyboard mappings'
+        'set-x11-keymap:Set X11 keyboard mapping'
+    )
+    if (( CURRENT == 1 )); then
+        _describe -t commands 'localectl command' _localectl_cmds
+    else
+        local curcontext="$curcontext"
+        cmd="${${_localectl_cmds[(r)$words[1]:*]%%:*}}"
+        if (( $+functions[_localectl_$cmd] )); then
+            _localectl_$cmd
+        else
+            _message "no more options"
+        fi
+    fi
+}
+
+_timedatectl_set-timezone(){
+    local -a _timezones
+    _timezones=( ${(f)"$(_call_program timezones "${service}" list-timezones)"} )
+    compadd "$_timezones[@]"
+}
+
+_timedatectl_set-time(){
+    _message "YYYY-MM-DD HH:MM:SS"
+}
+
+_timedatectl_set-local-rtc(){
+    local -a _options
+    _options=(
+        '0:Maintain RTC in universal time'
+        '1:Maintain RTC in local time'
+    )
+    _describe options _options
+}
+
+_timedatectl_set-ntp(){
+    local -a _options
+    _options=(
+        '0:Disable NTP based network time configuration'
+        '1:Enable NTP based network time configuration'
+    )
+    _describe options _options
+}
+
+_timedatectl_command(){
+    local -a _timedatectl_cmds
+    _timedatectl_cmds=(
+        'status:Show current time settings'
+        'set-time:Set system time'
+        'set-timezone:Set system timezone'
+        'list-timezones:Show known timezones'
+        'set-local-rtc:Control whether RTC is in local time'
+        'set-ntp:Control whether NTP is enabled'
+    )
+    if (( CURRENT == 1 )); then
+        _describe -t commands 'timedatectl command' _timedatectl_cmds
+    else
+        local curcontext="$curcontext"
+        cmd="${${_timedatectl_cmds[(r)$words[1]:*]%%:*}}"
+        if (( $#cmd )); then
+            if (( $+functions[_timedatectl_$cmd] )); then
+                _timedatectl_$cmd
+            else
+                _message "no more options"
+            fi
+        else
+            _message "unknown timedatectl command: $words[1]"
+        fi
+    fi
+}
+_systemd-coredumpctl_command(){
+    local -a _systemd_coredumpctl_cmds
+    _systemd_coredumpctl_cmds=(
+            'list:List available coredumps'
+            'dump:Print coredump to std'
+    )
+    if (( CURRENT == 1 )); then
+        _describe -t commands 'systemd-coredumpctl command' _systemd_coredumpctl_cmds
+    else
+        local curcontext="$curcontext"
+        local -a dumps
+        cmd="${${_systemd_coredumpctl_cmds[(r)$words[1]:*]%%:*}}"
+        if (( $#cmd  )); then
+            dumps=( "${(f)$(_call_program dumps "systemd-coredumpctl list 2>/dev/null")}" )
+            if [[ -n "$dumps" ]]; then
+                compadd "${dumps[@]}"
+            else
+                _message "no coredumps"
+            fi
+        else
+            _message "no more options"
+        fi
+
+    fi
+
+}
+
+_udevadm_info(){
+    _arguments \
+        '--query=[Query the database for specified type of device data. It needs the --path or --name to identify the specified device.]:type:(name symlink path property all)' \
+        '--path=[The devpath of the device to query.]:sys files:_files -P /sys/ -W /sys' \
+        '--name=[The name of the device node or a symlink to query]:device files:_files -P /dev/ -W /dev' \
+        '--root[Print absolute paths in name or symlink query.]' \
+        '--attribute-walk[Print all sysfs properties of the specified device that can be used in udev rules to match the specified device]' \
+        '--export[Print output as key/value pairs.]' \
+        '--export-prefix=[Add a prefix to the key name of exported values.]:prefix' \
+        '--device-id-of-file=[Print major/minor numbers of the underlying device, where the file lives on.]:files:_udevadm_mounts' \
+        '--export-db[Export the content of the udev database.]' \
+        '--cleanup-db[Cleanup the udev database.]'
+}
+
+_udevadm_trigger(){
+    _arguments \
+        '--verbose[Print the list of devices which will be triggered.]' \
+        '--dry-run[Do not actually trigger the event.]' \
+        '--type=[Trigger a specific type of devices.]:types:(devices subsystems failed)' \
+        '--action=[Type of event to be triggered.]:actions:(add change remove)' \
+        '--subsystem-match=[Trigger events for devices which belong to a matching subsystem.]' \
+        '--subsystem-nomatch=[Do not trigger events for devices which belong to a matching subsystem.]' \
+        '--attr-match=attribute=[Trigger events for devices with a matching sysfs attribute.]' \
+        '--attr-nomatch=attribute=[Do not trigger events for devices with a matching sysfs attribute.]' \
+        '--property-match=[Trigger events for devices with a matching property value.]' \
+        '--tag-match=property[Trigger events for devices with a matching tag.]' \
+        '--sysname-match=[Trigger events for devices with a matching sys device name.]' \
+        '--parent-match=[Trigger events for all children of a given device.]'
+}
+
+_udevadm_settle(){
+    _arguments \
+       '--timeout=[Maximum number of seconds to wait for the event queue to become empty.]' \
+       '--seq-start=[Wait only for events after the given sequence number.]' \
+       '--seq-end=[Wait only for events before the given sequence number.]' \
+       '--exit-if-exists=[Stop waiting if file exists.]:files:_files' \
+       '--quiet[Do not print any output, like the remaining queue entries when reaching the timeout.]' \
+       '--help[Print help text.]'
+}
+
+_udevadm_control(){
+    _arguments \
+        '--exit[Signal and wait for systemd-udevd to exit.]' \
+        '--log-priority=[Set the internal log level of systemd-udevd.]:priorities:(err info debug)' \
+        '--stop-exec-queue[Signal systemd-udevd to stop executing new events. Incoming events will be queued.]' \
+        '--start-exec-queue[Signal systemd-udevd to enable the execution of events.]' \
+        '--reload[Signal systemd-udevd to reload the rules files and other databases like the kernel module index.]' \
+        '--property=[Set a global property for all events.]' \
+        '--children-max=[Set the maximum number of events.]' \
+        '--timeout=[The maximum number of seconds to wait for a reply from systemd-udevd.]' \
+        '--help[Print help text.]'
+}
+_udevadm_monitor(){
+    _arguments \
+        '--kernel[Print the kernel uevents.]' \
+        '--udev[Print the udev event after the rule processing.]' \
+        '--property[Also print the properties of the event.]' \
+        '--subsystem-match=[Filter events by subsystem[/devtype].]' \
+        '--tag-match=[Filter events by property.]' \
+        '--help[Print help text.]'
+}
+
+_udevadm_test(){
+    _arguments \
+        '--action=[The action string.]:actions:(add change remove)' \
+        '--subsystem=[The subsystem string.]' \
+        '--help[Print help text.]' \
+        '*::devpath:_files -P /sys/ -W /sys'
+}
+
+_udevadm_test-builtin(){
+    if (( CURRENT == 2 )); then
+    _arguments \
+        '--help[Print help text]' \
+        '*::builtins:(blkid btrfs firmware hwdb input_id kmod path_id usb_id uaccess)'
+    elif  (( CURRENT == 3 )); then
+        _arguments \
+            '--help[Print help text]' \
+            '*::syspath:_files -P /sys -W /sys'
+    else
+        _arguments \
+            '--help[Print help text]'
+    fi
+}
+
+_udevadm_mounts(){
+  local dev_tmp dpath_tmp mp_tmp mline
+
+    tmp=( "${(@f)$(< /etc/mtab)}" )
+    dev_tmp=( "${(@)${(@)tmp%% *}:#none}" )
+    mp_tmp=( "${(@)${(@)tmp#* }%% *}" )
+
+  local MATCH
+  mp_tmp=("${(@q)mp_tmp//(#m)\\[0-7](#c3)/${(#)$(( 8#${MATCH[2,-1]} ))}}")
+  dpath_tmp=( "${(@Mq)dev_tmp:#/*}" )
+  dev_tmp=( "${(@q)dev_tmp:#/*}" )
+
+  _alternative \
+    'device-paths: device path:compadd -a dpath_tmp' \
+    'directories:mount point:compadd -a mp_tmp'
+}
+
+
+_udevadm_command(){
+    local -a _udevadm_cmds
+    _udevadm_cmds=(
+        'info:query sysfs or the udev database'
+        'trigger:request events from the kernel'
+        'settle:wait for the event queue to finish'
+        'control:control the udev daemon'
+        'monitor:listen to kernel and udev events'
+        'test:test an event run'
+        'test-builtin:test a built-in command'
+    )
+
+    if ((CURRENT == 1)); then
+        _describe -t commands 'udevadm commands' _udevadm_cmds
+    else
+        local curcontext="$curcontext"
+        cmd="${${_udevadm_cmds[(r)$words[1]:*]%%:*}}"
+        if (($#cmd)); then
+            if (( $+functions[_udevadm_$cmd] )); then
+                _udevadm_$cmd
+            else
+                _message "no options for $cmd"
+            fi
+        else
+            _message "no more options"
+        fi
+    fi
+}
+
+_ctls "$@"
+
+#vim: set ft=zsh sw=4 ts=4 et
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644 (file)
index 0000000..afabb6a
--- /dev/null
@@ -0,0 +1,6 @@
+load-fragment-gperf-nulstr.c
+load-fragment-gperf.c
+load-fragment-gperf.gperf
+org.freedesktop.systemd1.policy.in
+org.freedesktop.systemd1.policy
+99-systemd.rules
diff --git a/src/Makefile b/src/Makefile
new file mode 100644 (file)
index 0000000..9d07505
--- /dev/null
@@ -0,0 +1,28 @@
+#  This file is part of systemd.
+#
+#  Copyright 2010 Lennart Poettering
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+# This file is a dirty trick to simplify compilation from within
+# emacs. This file is not intended to be distributed. So, don't touch
+# it, even better ignore it!
+
+all:
+       $(MAKE) -C ..
+
+clean:
+       $(MAKE) -C .. clean
+
+.PHONY: all clean
diff --git a/src/ac-power/Makefile b/src/ac-power/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/ac-power/ac-power.c b/src/ac-power/ac-power.c
new file mode 100644 (file)
index 0000000..bd1b6ec
--- /dev/null
@@ -0,0 +1,37 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        /* This is mostly intended to be used for scripts which want
+         * to detect whether AC power is plugged in or not. */
+
+        r = on_ac_power();
+        if (r < 0) {
+                log_error("Failed to read AC status: %s", strerror(-r));
+                return EXIT_FAILURE;
+        }
+
+        return r != 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/analyze/.gitignore b/src/analyze/.gitignore
new file mode 100644 (file)
index 0000000..752ea23
--- /dev/null
@@ -0,0 +1 @@
+/systemd-analyze
diff --git a/src/analyze/Makefile b/src/analyze/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/analyze/systemd-analyze.in b/src/analyze/systemd-analyze.in
new file mode 100755 (executable)
index 0000000..26a9f7b
--- /dev/null
@@ -0,0 +1,310 @@
+#!@PYTHON_BINARY@
+
+import sys, os
+import argparse
+from gi.repository import Gio
+try:
+        import cairo
+except ImportError:
+        cairo = None
+
+def acquire_time_data():
+        manager = Gio.DBusProxy.new_for_bus_sync(bus, Gio.DBusProxyFlags.NONE,
+                None, 'org.freedesktop.systemd1', '/org/freedesktop/systemd1', 'org.freedesktop.systemd1.Manager', None)
+        units = manager.ListUnits()
+
+        l = []
+
+        for i in units:
+                if i[5] != "":
+                        continue
+
+                properties = Gio.DBusProxy.new_for_bus_sync(bus, Gio.DBusProxyFlags.NONE,
+                        None, 'org.freedesktop.systemd1', i[6], 'org.freedesktop.DBus.Properties', None)
+
+                ixt = properties.Get('(ss)', 'org.freedesktop.systemd1.Unit', 'InactiveExitTimestampMonotonic')
+                aet = properties.Get('(ss)', 'org.freedesktop.systemd1.Unit', 'ActiveEnterTimestampMonotonic')
+                axt = properties.Get('(ss)', 'org.freedesktop.systemd1.Unit', 'ActiveExitTimestampMonotonic')
+                iet = properties.Get('(ss)', 'org.freedesktop.systemd1.Unit', 'InactiveEnterTimestampMonotonic')
+
+                l.append((str(i[0]), ixt, aet, axt, iet))
+
+        return l
+
+def acquire_start_time():
+        properties = Gio.DBusProxy.new_for_bus_sync(bus, Gio.DBusProxyFlags.NONE,
+                None, 'org.freedesktop.systemd1', '/org/freedesktop/systemd1', 'org.freedesktop.DBus.Properties', None)
+
+        # Note that the firmware/loader times are returned as positive
+        # values but are actually considered negative from the point
+        # in time of kernel initialization. Also, the monotonic kernel
+        # time will always be 0 since that's the epoch of the
+        # monotonic clock. Since we want to know whether the kernel
+        # timestamp is set at all we will instead ask for the realtime
+        # clock for this timestamp.
+
+        firmware_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'FirmwareTimestampMonotonic')
+        loader_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'LoaderTimestampMonotonic')
+        kernel_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'KernelTimestamp')
+        initrd_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'InitRDTimestampMonotonic')
+        userspace_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'UserspaceTimestampMonotonic')
+        finish_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'FinishTimestampMonotonic')
+
+        if finish_time == 0:
+                sys.exit("Bootup is not yet finished. Please try again later.")
+
+        assert firmware_time >= loader_time
+        assert initrd_time <= userspace_time
+        assert userspace_time <= finish_time
+
+        return firmware_time, loader_time, kernel_time, initrd_time, userspace_time, finish_time
+
+def draw_box(context, j, k, l, m, r = 0, g = 0, b = 0):
+        context.save()
+        context.set_source_rgb(r, g, b)
+        context.rectangle(j, k, l, m)
+        context.fill()
+        context.restore()
+
+def draw_text(context, x, y, text, size = 12, r = 0, g = 0, b = 0, vcenter = 0.5, hcenter = 0.5):
+        context.save()
+
+        context.set_source_rgb(r, g, b)
+        context.select_font_face("Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
+        context.set_font_size(size)
+
+        if vcenter or hcenter:
+                x_bearing, y_bearing, width, height = context.text_extents(text)[:4]
+
+                if hcenter:
+                        x = x - width*hcenter - x_bearing
+
+                if vcenter:
+                        y = y - height*vcenter - y_bearing
+
+        context.move_to(x, y)
+        context.show_text(text)
+
+        context.restore()
+
+def time():
+
+        firmware_time, loader_time, kernel_time, initrd_time, userspace_time, finish_time = acquire_start_time()
+
+        sys.stdout.write("Startup finished in ")
+
+        if firmware_time > 0:
+                sys.stdout.write("%lums (firmware) + " % ((firmware_time - loader_time) / 1000))
+        if loader_time > 0:
+                sys.stdout.write("%lums (loader) + " % (loader_time / 1000))
+        if initrd_time > 0:
+                sys.stdout.write("%lums (kernel) + %lums (initrd) + " % (initrd_time / 1000, (userspace_time - initrd_time) / 1000))
+        elif kernel_time > 0:
+                sys.stdout.write("%lums (kernel) + " % (userspace_time  / 1000))
+
+        sys.stdout.write("%lums (userspace) " % ((finish_time - userspace_time) / 1000))
+
+        if kernel_time > 0:
+                sys.stdout.write("= %lums\n" % ((firmware_time + finish_time) / 1000))
+        else:
+                sys.stdout.write("= %lums\n" % ((finish_time - userspace_time) / 1000))
+
+def blame():
+
+        data = acquire_time_data()
+        s = sorted(data, key = lambda i: i[2] - i[1], reverse = True)
+
+        for name, ixt, aet, axt, iet in s:
+
+                if ixt <= 0 or aet <= 0:
+                        continue
+
+                if aet <= ixt:
+                        continue
+
+                sys.stdout.write("%6lums %s\n" % ((aet - ixt) / 1000, name))
+
+def plot():
+        if cairo is None:
+                sys.exit("Failed to initilize python-cairo required for 'plot' verb.")
+        firmware_time, loader_time, kernel_time, initrd_time, userspace_time, finish_time = acquire_start_time()
+        data = acquire_time_data()
+        s = sorted(data, key = lambda i: i[1])
+
+        # Account for kernel and initramfs bars if they exist
+        if initrd_time > 0:
+                count = 3
+        else:
+                count = 2
+
+        for name, ixt, aet, axt, iet in s:
+
+                if (ixt >= userspace_time and ixt <= finish_time) or \
+                                (aet >= userspace_time and aet <= finish_time) or \
+                                (axt >= userspace_time and axt <= finish_time):
+                        count += 1
+
+        border = 100
+        bar_height = 20
+        bar_space = bar_height * 0.1
+
+        # 1000px = 10s, 1px = 10ms
+        width = finish_time/10000 + border*2
+        height = count * (bar_height + bar_space) + border * 2
+
+        if width < 1000:
+                width = 1000
+
+        surface = cairo.SVGSurface(sys.stdout, width, height)
+        context = cairo.Context(surface)
+
+        draw_box(context, 0, 0, width, height, 1, 1, 1)
+
+        context.translate(border + 0.5, border + 0.5)
+
+        context.save()
+        context.set_line_width(1)
+        context.set_source_rgb(0.7, 0.7, 0.7)
+
+        for x in range(0, int(finish_time/10000) + 100, 100):
+                context.move_to(x, 0)
+                context.line_to(x, height-border*2)
+
+        context.move_to(0, 0)
+        context.line_to(width-border*2, 0)
+
+        context.move_to(0, height-border*2)
+        context.line_to(width-border*2, height-border*2)
+
+        context.stroke()
+        context.restore()
+
+        osrel = "Linux"
+        if os.path.exists("/etc/os-release"):
+                for line in open("/etc/os-release"):
+                        if line.startswith('PRETTY_NAME='):
+                                osrel = line[12:]
+                                osrel = osrel.strip('\"\n')
+                                break
+
+        banner = "{} {} ({} {}) {}".format(osrel, *(os.uname()[1:5]))
+        draw_text(context, 0, -15, banner, hcenter = 0, vcenter = 1)
+
+        for x in range(0, int(finish_time/10000) + 100, 100):
+                draw_text(context, x, -5, "%lus" % (x/100), vcenter = 0, hcenter = 0)
+
+        y = 0
+
+        # draw boxes for kernel and initramfs boot time
+        if initrd_time > 0:
+                draw_box(context, 0, y, initrd_time/10000, bar_height, 0.7, 0.7, 0.7)
+                draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0)
+                y += bar_height + bar_space
+
+                draw_box(context, initrd_time/10000, y, userspace_time/10000-initrd_time/10000, bar_height, 0.7, 0.7, 0.7)
+                draw_text(context, initrd_time/10000 + 10, y + bar_height/2, "initramfs", hcenter = 0)
+                y += bar_height + bar_space
+
+        else:
+                draw_box(context, 0, y, userspace_time/10000, bar_height, 0.6, 0.6, 0.6)
+                draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0)
+                y += bar_height + bar_space
+
+        draw_box(context, userspace_time/10000, y, finish_time/10000-userspace_time/10000, bar_height, 0.7, 0.7, 0.7)
+        draw_text(context, userspace_time/10000 + 10, y + bar_height/2, "userspace", hcenter = 0)
+        y += bar_height + bar_space
+
+        for name, ixt, aet, axt, iet in s:
+
+                drawn = False
+                left = -1
+
+                if ixt >= userspace_time and ixt <= finish_time:
+
+                        # Activating
+                        a = ixt
+                        b = min(filter(lambda x: x >= ixt, (aet, axt, iet, finish_time))) - ixt
+
+                        draw_box(context, a/10000, y, b/10000, bar_height, 1, 0, 0)
+                        drawn = True
+
+                        if left < 0:
+                                left = a
+
+                if aet >= userspace_time and aet <= finish_time:
+
+                        # Active
+                        a = aet
+                        b = min(filter(lambda x: x >= aet, (axt, iet, finish_time))) - aet
+
+                        draw_box(context, a/10000, y, b/10000, bar_height, .8, .6, .6)
+                        drawn = True
+
+                        if left < 0:
+                                left = a
+
+                if axt >= userspace_time and axt <= finish_time:
+
+                        # Deactivating
+                        a = axt
+                        b = min(filter(lambda x: x >= axt, (iet, finish_time))) - axt
+
+                        draw_box(context, a/10000, y, b/10000, bar_height, .6, .4, .4)
+                        drawn = True
+
+                        if left < 0:
+                                left = a
+
+                if drawn:
+                        x = left/10000
+
+                        if x < width/2-border:
+                                draw_text(context, x + 10, y + bar_height/2, name, hcenter = 0)
+                        else:
+                                draw_text(context, x - 10, y + bar_height/2, name, hcenter = 1)
+
+                        y += bar_height + bar_space
+
+        draw_text(context, 0, height-border*2, "Legend: Red = Activating; Pink = Active; Dark Pink = Deactivating", hcenter = 0, vcenter = -1)
+
+        if initrd_time > 0:
+                draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums" % ( \
+                        initrd_time/1000, \
+                        (userspace_time - initrd_time)/1000, \
+                        (finish_time - userspace_time)/1000, \
+                        finish_time/1000), hcenter = 0, vcenter = -1)
+        else:
+                draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (userspace) = %lums" % ( \
+                        userspace_time/1000, \
+                        (finish_time - userspace_time)/1000, \
+                        finish_time/1000), hcenter = 0, vcenter = -1)
+
+        surface.finish()
+
+parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
+                                 version='systemd-analyze @PACKAGE_VERSION@',
+                                 description='Process systemd profiling information',
+                                 epilog='''\
+time - print time spent in the kernel before reaching userspace
+blame - print list of running units ordered by time to init
+plot - output SVG graphic showing service initialization
+''')
+
+parser.add_argument('action', choices=('time', 'blame', 'plot'),
+                    default='time', nargs='?',
+                    help='action to perform (default: time)')
+parser.add_argument('--user', action='store_true',
+                    help='use the session bus')
+
+args = parser.parse_args()
+
+if args.user:
+        bus = Gio.BusType.SESSION
+else:
+        bus = Gio.BusType.SYSTEM
+
+verb = {'time' : time,
+       'blame': blame,
+       'plot' : plot,
+       }
+verb.get(args.action)()
diff --git a/src/ask-password/Makefile b/src/ask-password/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/ask-password/ask-password.c b/src/ask-password/ask-password.c
new file mode 100644 (file)
index 0000000..5f67570
--- /dev/null
@@ -0,0 +1,184 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/signalfd.h>
+#include <getopt.h>
+#include <termios.h>
+#include <limits.h>
+#include <stddef.h>
+
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+#include "strv.h"
+#include "ask-password-api.h"
+#include "def.h"
+
+static const char *arg_icon = NULL;
+static const char *arg_message = NULL;
+static bool arg_use_tty = true;
+static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC;
+static bool arg_accept_cached = false;
+static bool arg_multiple = false;
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] MESSAGE\n\n"
+               "Query the user for a system passphrase, via the TTY or an UI agent.\n\n"
+               "  -h --help          Show this help\n"
+               "     --icon=NAME     Icon name\n"
+               "     --timeout=SEC   Timeout in sec\n"
+               "     --no-tty        Ask question via agent even on TTY\n"
+               "     --accept-cached Accept cached passwords\n"
+               "     --multiple      List multiple passwords if available\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_ICON = 0x100,
+                ARG_TIMEOUT,
+                ARG_NO_TTY,
+                ARG_ACCEPT_CACHED,
+                ARG_MULTIPLE
+        };
+
+        static const struct option options[] = {
+                { "help",          no_argument,       NULL, 'h'               },
+                { "icon",          required_argument, NULL, ARG_ICON          },
+                { "timeout",       required_argument, NULL, ARG_TIMEOUT       },
+                { "no-tty",        no_argument,       NULL, ARG_NO_TTY        },
+                { "accept-cached", no_argument,       NULL, ARG_ACCEPT_CACHED },
+                { "multiple",      no_argument,       NULL, ARG_MULTIPLE      },
+                { NULL,            0,                 NULL, 0                 }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_ICON:
+                        arg_icon = optarg;
+                        break;
+
+                case ARG_TIMEOUT:
+                        if (parse_usec(optarg, &arg_timeout) < 0) {
+                                log_error("Failed to parse --timeout parameter %s", optarg);
+                                return -EINVAL;
+                        }
+                        break;
+
+                case ARG_NO_TTY:
+                        arg_use_tty = false;
+                        break;
+
+                case ARG_ACCEPT_CACHED:
+                        arg_accept_cached = true;
+                        break;
+
+                case ARG_MULTIPLE:
+                        arg_multiple = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind != argc-1) {
+                help();
+                return -EINVAL;
+        }
+
+        arg_message = argv[optind];
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+        usec_t timeout;
+
+        log_parse_environment();
+        log_open();
+
+        if ((r = parse_argv(argc, argv)) <= 0)
+                goto finish;
+
+        if (arg_timeout > 0)
+                timeout = now(CLOCK_MONOTONIC) + arg_timeout;
+        else
+                timeout = 0;
+
+        if (arg_use_tty && isatty(STDIN_FILENO)) {
+                char *password = NULL;
+
+                if ((r = ask_password_tty(arg_message, timeout, NULL, &password)) >= 0) {
+                        puts(password);
+                        free(password);
+                }
+
+        } else {
+                char **l;
+
+                if ((r = ask_password_agent(arg_message, arg_icon, timeout, arg_accept_cached, &l)) >= 0) {
+                        char **p;
+
+                        STRV_FOREACH(p, l) {
+                                puts(*p);
+
+                                if (!arg_multiple)
+                                        break;
+                        }
+
+                        strv_free(l);
+                }
+        }
+
+finish:
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/binfmt/Makefile b/src/binfmt/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c
new file mode 100644 (file)
index 0000000..788fd4b
--- /dev/null
@@ -0,0 +1,170 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#include "log.h"
+#include "hashmap.h"
+#include "strv.h"
+#include "util.h"
+#include "conf-files.h"
+
+static int delete_rule(const char *rule) {
+        char *x, *fn = NULL, *e;
+        int r;
+
+        assert(rule[0]);
+
+        if (!(x = strdup(rule)))
+                return log_oom();
+
+        e = strchrnul(x+1, x[0]);
+        *e = 0;
+
+        asprintf(&fn, "/proc/sys/fs/binfmt_misc/%s", x+1);
+        free(x);
+
+        if (!fn)
+                return log_oom();
+
+        r = write_one_line_file(fn, "-1");
+        free(fn);
+
+        return r;
+}
+
+static int apply_rule(const char *rule) {
+        int r;
+
+        delete_rule(rule);
+
+        if ((r = write_one_line_file("/proc/sys/fs/binfmt_misc/register", rule)) < 0) {
+                log_error("Failed to add binary format: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+static int apply_file(const char *path, bool ignore_enoent) {
+        FILE *f;
+        int r = 0;
+
+        assert(path);
+
+        if (!(f = fopen(path, "re"))) {
+                if (ignore_enoent && errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open file '%s', ignoring: %m", path);
+                return -errno;
+        }
+
+        log_debug("apply: %s\n", path);
+        while (!feof(f)) {
+                char l[LINE_MAX], *p;
+                int k;
+
+                if (!fgets(l, sizeof(l), f)) {
+                        if (feof(f))
+                                break;
+
+                        log_error("Failed to read file '%s', ignoring: %m", path);
+                        r = -errno;
+                        goto finish;
+                }
+
+                p = strstrip(l);
+
+                if (!*p)
+                        continue;
+
+                if (strchr(COMMENTS, *p))
+                        continue;
+
+                if ((k = apply_rule(p)) < 0 && r == 0)
+                        r = k;
+        }
+
+finish:
+        fclose(f);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        int r = 0;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argc > 1) {
+                int i;
+
+                for (i = 1; i < argc; i++) {
+                        int k;
+
+                        k = apply_file(argv[i], false);
+                        if (k < 0 && r == 0)
+                                r = k;
+                }
+        } else {
+                char **files, **f;
+
+                r = conf_files_list(&files, ".conf",
+                                    "/etc/binfmt.d",
+                                    "/run/binfmt.d",
+                                    "/usr/local/lib/binfmt.d",
+                                    "/usr/lib/binfmt.d",
+#ifdef HAVE_SPLIT_USR
+                                    "/lib/binfmt.d",
+#endif
+                                    NULL);
+                if (r < 0) {
+                        log_error("Failed to enumerate binfmt.d files: %s", strerror(-r));
+                        goto finish;
+                }
+
+                /* Flush out all rules */
+                write_one_line_file("/proc/sys/fs/binfmt_misc/status", "-1");
+
+                STRV_FOREACH(f, files) {
+                        int k;
+
+                        k = apply_file(*f, true);
+                        if (k < 0 && r == 0)
+                                r = k;
+                }
+
+                strv_free(files);
+        }
+finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/cgls/Makefile b/src/cgls/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c
new file mode 100644 (file)
index 0000000..cfb728b
--- /dev/null
@@ -0,0 +1,178 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <getopt.h>
+#include <string.h>
+
+#include "cgroup-show.h"
+#include "cgroup-util.h"
+#include "log.h"
+#include "path-util.h"
+#include "util.h"
+#include "pager.h"
+#include "build.h"
+
+static bool arg_no_pager = false;
+static bool arg_kernel_threads = false;
+static bool arg_all = false;
+
+static void help(void) {
+
+        printf("%s [OPTIONS...] [CGROUP...]\n\n"
+               "Recursively show control group contents.\n\n"
+               "  -h --help           Show this help\n"
+               "     --version        Show package version\n"
+               "     --no-pager       Do not pipe output into a pager\n"
+               "  -a --all            Show all groups, including empty\n"
+               "  -k                  Include kernel threads in output\n",
+               program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_NO_PAGER = 0x100,
+                ARG_VERSION
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'          },
+                { "version",   no_argument,       NULL, ARG_VERSION  },
+                { "no-pager",  no_argument,       NULL, ARG_NO_PAGER },
+                { "all",       no_argument,       NULL, 'a'          },
+                { NULL,        0,                 NULL, 0            }
+        };
+
+        int c;
+
+        assert(argc >= 1);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hka", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case 'a':
+                        arg_all = true;
+                        break;
+
+                case 'k':
+                        arg_kernel_threads = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r = 0, retval = EXIT_FAILURE;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                goto finish;
+        else if (r == 0) {
+                retval = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        if (!arg_no_pager)
+                pager_open();
+
+        if (optind < argc) {
+                unsigned i;
+
+                for (i = (unsigned) optind; i < (unsigned) argc; i++) {
+                        int q;
+                        printf("%s:\n", argv[i]);
+
+                        q = show_cgroup_by_path(argv[i], NULL, 0, arg_kernel_threads, arg_all);
+                        if (q < 0)
+                                r = q;
+                }
+
+        } else {
+                char _cleanup_free_ *p;
+
+                p = get_current_dir_name();
+                if (!p) {
+                        log_error("Cannot determine current working directory: %m");
+                        goto finish;
+                }
+
+                if (path_startswith(p, "/sys/fs/cgroup")) {
+                        printf("Working Directory %s:\n", p);
+                        r = show_cgroup_by_path(p, NULL, 0, arg_kernel_threads, arg_all);
+                } else {
+                        char _cleanup_free_ *root = NULL;
+                        const char *t = NULL;
+
+                        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root);
+                        if (r < 0)
+                                t = "/";
+                        else {
+                                if (endswith(root, "/system"))
+                                        root[strlen(root)-7] = 0;
+
+                                t = root[0] ? root : "/";
+                        }
+
+                        r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, t, NULL, 0, arg_kernel_threads, arg_all);
+                }
+        }
+
+        if (r < 0)
+                log_error("Failed to list cgroup tree: %s", strerror(-r));
+
+        retval = EXIT_SUCCESS;
+
+finish:
+        pager_close();
+
+        return retval;
+}
diff --git a/src/cgroups-agent/Makefile b/src/cgroups-agent/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c
new file mode 100644 (file)
index 0000000..7a6173e
--- /dev/null
@@ -0,0 +1,101 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include <stdlib.h>
+
+#include "log.h"
+#include "dbus-common.h"
+
+int main(int argc, char *argv[]) {
+        DBusError error;
+        DBusConnection *bus = NULL;
+        DBusMessage *m = NULL;
+        int r = EXIT_FAILURE;
+
+        dbus_error_init(&error);
+
+        if (argc != 2) {
+                log_error("Incorrect number of arguments.");
+                goto finish;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        /* We send this event to the private D-Bus socket and then the
+         * system instance will forward this to the system bus. We do
+         * this to avoid an activation loop when we start dbus when we
+         * are called when the dbus service is shut down. */
+
+        if (!(bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error))) {
+#ifndef LEGACY
+                dbus_error_free(&error);
+
+                /* Retry with the pre v21 socket name, to ease upgrades */
+                if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", &error))) {
+#endif
+                        log_error("Failed to get D-Bus connection: %s", bus_error_message(&error));
+                        goto finish;
+                }
+#ifndef LEGACY
+        }
+#endif
+
+        if (bus_check_peercred(bus) < 0) {
+                log_error("Bus owner not root.");
+                goto finish;
+        }
+
+        if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1/agent", "org.freedesktop.systemd1.Agent", "Released"))) {
+                log_error("Could not allocate signal message.");
+                goto finish;
+        }
+
+        if (!dbus_message_append_args(m,
+                                      DBUS_TYPE_STRING, &argv[1],
+                                      DBUS_TYPE_INVALID)) {
+                log_error("Could not attach group information to signal message.");
+                goto finish;
+        }
+
+        if (!dbus_connection_send(bus, m, NULL)) {
+                log_error("Failed to send signal message on private connection.");
+                goto finish;
+        }
+
+        r = EXIT_SUCCESS;
+
+finish:
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        if (m)
+                dbus_message_unref(m);
+
+        dbus_error_free(&error);
+        return r;
+}
diff --git a/src/cgtop/Makefile b/src/cgtop/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
new file mode 100644 (file)
index 0000000..f2e6276
--- /dev/null
@@ -0,0 +1,793 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <alloca.h>
+#include <getopt.h>
+
+#include "path-util.h"
+#include "util.h"
+#include "hashmap.h"
+#include "cgroup-util.h"
+#include "build.h"
+
+typedef struct Group {
+        char *path;
+
+        bool n_tasks_valid:1;
+        bool cpu_valid:1;
+        bool memory_valid:1;
+        bool io_valid:1;
+
+        unsigned n_tasks;
+
+        unsigned cpu_iteration;
+        uint64_t cpu_usage;
+        struct timespec cpu_timestamp;
+        double cpu_fraction;
+
+        uint64_t memory;
+
+        unsigned io_iteration;
+        uint64_t io_input, io_output;
+        struct timespec io_timestamp;
+        uint64_t io_input_bps, io_output_bps;
+} Group;
+
+static unsigned arg_depth = 3;
+static unsigned arg_iterations = 0;
+static bool arg_batch = false;
+static usec_t arg_delay = 1*USEC_PER_SEC;
+
+static enum {
+        ORDER_PATH,
+        ORDER_TASKS,
+        ORDER_CPU,
+        ORDER_MEMORY,
+        ORDER_IO
+} arg_order = ORDER_CPU;
+
+static void group_free(Group *g) {
+        assert(g);
+
+        free(g->path);
+        free(g);
+}
+
+static void group_hashmap_clear(Hashmap *h) {
+        Group *g;
+
+        while ((g = hashmap_steal_first(h)))
+                group_free(g);
+}
+
+static void group_hashmap_free(Hashmap *h) {
+        group_hashmap_clear(h);
+        hashmap_free(h);
+}
+
+static int process(const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration) {
+        Group *g;
+        int r;
+        FILE *f;
+        pid_t pid;
+        unsigned n;
+
+        assert(controller);
+        assert(path);
+        assert(a);
+
+        g = hashmap_get(a, path);
+        if (!g) {
+                g = hashmap_get(b, path);
+                if (!g) {
+                        g = new0(Group, 1);
+                        if (!g)
+                                return -ENOMEM;
+
+                        g->path = strdup(path);
+                        if (!g->path) {
+                                group_free(g);
+                                return -ENOMEM;
+                        }
+
+                        r = hashmap_put(a, g->path, g);
+                        if (r < 0) {
+                                group_free(g);
+                                return r;
+                        }
+                } else {
+                        assert_se(hashmap_move_one(a, b, path) == 0);
+                        g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false;
+                }
+        }
+
+        /* Regardless which controller, let's find the maximum number
+         * of processes in any of it */
+
+        r = cg_enumerate_tasks(controller, path, &f);
+        if (r < 0)
+                return r;
+
+        n = 0;
+        while (cg_read_pid(f, &pid) > 0)
+                n++;
+        fclose(f);
+
+        if (n > 0) {
+                if (g->n_tasks_valid)
+                        g->n_tasks = MAX(g->n_tasks, n);
+                else
+                        g->n_tasks = n;
+
+                g->n_tasks_valid = true;
+        }
+
+        if (streq(controller, "cpuacct")) {
+                uint64_t new_usage;
+                char *p, *v;
+                struct timespec ts;
+
+                r = cg_get_path(controller, path, "cpuacct.usage", &p);
+                if (r < 0)
+                        return r;
+
+                r = read_one_line_file(p, &v);
+                free(p);
+                if (r < 0)
+                        return r;
+
+                r = safe_atou64(v, &new_usage);
+                free(v);
+                if (r < 0)
+                        return r;
+
+                assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
+
+                if (g->cpu_iteration == iteration - 1) {
+                        uint64_t x, y;
+
+                        x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) -
+                                ((uint64_t) g->cpu_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->cpu_timestamp.tv_nsec);
+
+                        y = new_usage - g->cpu_usage;
+
+                        if (y > 0) {
+                                g->cpu_fraction = (double) y / (double) x;
+                                g->cpu_valid = true;
+                        }
+                }
+
+                g->cpu_usage = new_usage;
+                g->cpu_timestamp = ts;
+                g->cpu_iteration = iteration;
+
+        } else if (streq(controller, "memory")) {
+                char *p, *v;
+
+                r = cg_get_path(controller, path, "memory.usage_in_bytes", &p);
+                if (r < 0)
+                        return r;
+
+                r = read_one_line_file(p, &v);
+                free(p);
+                if (r < 0)
+                        return r;
+
+                r = safe_atou64(v, &g->memory);
+                free(v);
+                if (r < 0)
+                        return r;
+
+                if (g->memory > 0)
+                        g->memory_valid = true;
+
+        } else if (streq(controller, "blkio")) {
+                char *p;
+                uint64_t wr = 0, rd = 0;
+                struct timespec ts;
+
+                r = cg_get_path(controller, path, "blkio.io_service_bytes", &p);
+                if (r < 0)
+                        return r;
+
+                f = fopen(p, "re");
+                free(p);
+
+                if (!f)
+                        return -errno;
+
+                for (;;) {
+                        char line[LINE_MAX], *l;
+                        uint64_t k, *q;
+
+                        if (!fgets(line, sizeof(line), f))
+                                break;
+
+                        l = strstrip(line);
+                        l += strcspn(l, WHITESPACE);
+                        l += strspn(l, WHITESPACE);
+
+                        if (first_word(l, "Read")) {
+                                l += 4;
+                                q = &rd;
+                        } else if (first_word(l, "Write")) {
+                                l += 5;
+                                q = &wr;
+                        } else
+                                continue;
+
+                        l += strspn(l, WHITESPACE);
+                        r = safe_atou64(l, &k);
+                        if (r < 0)
+                                continue;
+
+                        *q += k;
+                }
+
+                fclose(f);
+
+                assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
+
+                if (g->io_iteration == iteration - 1) {
+                        uint64_t x, yr, yw;
+
+                        x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) -
+                                ((uint64_t) g->io_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->io_timestamp.tv_nsec);
+
+                        yr = rd - g->io_input;
+                        yw = wr - g->io_output;
+
+                        if (yr > 0 || yw > 0) {
+                                g->io_input_bps = (yr * 1000000000ULL) / x;
+                                g->io_output_bps = (yw * 1000000000ULL) / x;
+                                g->io_valid = true;
+
+                        }
+                }
+
+                g->io_input = rd;
+                g->io_output = wr;
+                g->io_timestamp = ts;
+                g->io_iteration = iteration;
+        }
+
+        return 0;
+}
+
+static int refresh_one(
+                const char *controller,
+                const char *path,
+                Hashmap *a,
+                Hashmap *b,
+                unsigned iteration,
+                unsigned depth) {
+
+        DIR *d = NULL;
+        int r;
+
+        assert(controller);
+        assert(path);
+        assert(a);
+
+        if (depth > arg_depth)
+                return 0;
+
+        r = process(controller, path, a, b, iteration);
+        if (r < 0)
+                return r;
+
+        r = cg_enumerate_subgroups(controller, path, &d);
+        if (r < 0) {
+                if (r == -ENOENT)
+                        return 0;
+
+                return r;
+        }
+
+        for (;;) {
+                char *fn, *p;
+
+                r = cg_read_subgroup(d, &fn);
+                if (r <= 0)
+                        goto finish;
+
+                p = strjoin(path, "/", fn, NULL);
+                free(fn);
+
+                if (!p) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                path_kill_slashes(p);
+
+                r = refresh_one(controller, p, a, b, iteration, depth + 1);
+                free(p);
+
+                if (r < 0)
+                        goto finish;
+        }
+
+finish:
+        if (d)
+                closedir(d);
+
+        return r;
+}
+
+static int refresh(Hashmap *a, Hashmap *b, unsigned iteration) {
+        int r;
+
+        assert(a);
+
+        r = refresh_one("name=systemd", "/", a, b, iteration, 0);
+        if (r < 0)
+                if (r != -ENOENT)
+                    return r;
+        r = refresh_one("cpuacct", "/", a, b, iteration, 0);
+        if (r < 0)
+                if (r != -ENOENT)
+                    return r;
+        r = refresh_one("memory", "/", a, b, iteration, 0);
+        if (r < 0)
+                if (r != -ENOENT)
+                    return r;
+
+        r = refresh_one("blkio", "/", a, b, iteration, 0);
+        if (r < 0)
+                if (r != -ENOENT)
+                    return r;
+        return 0;
+}
+
+static int group_compare(const void*a, const void *b) {
+        const Group *x = *(Group**)a, *y = *(Group**)b;
+
+        if (path_startswith(y->path, x->path))
+                return -1;
+        if (path_startswith(x->path, y->path))
+                return 1;
+
+        if (arg_order == ORDER_CPU) {
+                if (x->cpu_valid && y->cpu_valid) {
+
+                        if (x->cpu_fraction > y->cpu_fraction)
+                                return -1;
+                        else if (x->cpu_fraction < y->cpu_fraction)
+                                return 1;
+                } else if (x->cpu_valid)
+                        return -1;
+                else if (y->cpu_valid)
+                        return 1;
+        }
+
+        if (arg_order == ORDER_TASKS) {
+
+                if (x->n_tasks_valid && y->n_tasks_valid) {
+                        if (x->n_tasks > y->n_tasks)
+                                return -1;
+                        else if (x->n_tasks < y->n_tasks)
+                                return 1;
+                } else if (x->n_tasks_valid)
+                        return -1;
+                else if (y->n_tasks_valid)
+                        return 1;
+        }
+
+        if (arg_order == ORDER_MEMORY) {
+                if (x->memory_valid && y->memory_valid) {
+                        if (x->memory > y->memory)
+                                return -1;
+                        else if (x->memory < y->memory)
+                                return 1;
+                } else if (x->memory_valid)
+                        return -1;
+                else if (y->memory_valid)
+                        return 1;
+        }
+
+        if (arg_order == ORDER_IO) {
+                if (x->io_valid && y->io_valid) {
+                        if (x->io_input_bps + x->io_output_bps > y->io_input_bps + y->io_output_bps)
+                                return -1;
+                        else if (x->io_input_bps + x->io_output_bps < y->io_input_bps + y->io_output_bps)
+                                return 1;
+                } else if (x->io_valid)
+                        return -1;
+                else if (y->io_valid)
+                        return 1;
+        }
+
+        return strcmp(x->path, y->path);
+}
+
+static int display(Hashmap *a) {
+        Iterator i;
+        Group *g;
+        Group **array;
+        unsigned rows, path_columns, n = 0, j;
+
+        assert(a);
+
+        /* Set cursor to top left corner and clear screen */
+        fputs("\033[H"
+              "\033[2J", stdout);
+
+        array = alloca(sizeof(Group*) * hashmap_size(a));
+
+        HASHMAP_FOREACH(g, a, i)
+                if (g->n_tasks_valid || g->cpu_valid || g->memory_valid || g->io_valid)
+                        array[n++] = g;
+
+        qsort(array, n, sizeof(Group*), group_compare);
+
+        rows = lines();
+        if (rows <= 10)
+                rows = 10;
+
+        path_columns = columns() - 42;
+        if (path_columns < 10)
+                path_columns = 10;
+
+        printf("%s%-*s%s %s%7s%s %s%6s%s %s%8s%s %s%8s%s %s%8s%s\n\n",
+               arg_order == ORDER_PATH   ? ANSI_HIGHLIGHT_ON : "", path_columns, "Path",
+                      arg_order == ORDER_PATH   ? ANSI_HIGHLIGHT_OFF : "",
+               arg_order == ORDER_TASKS  ? ANSI_HIGHLIGHT_ON : "", "Tasks",
+                      arg_order == ORDER_TASKS  ? ANSI_HIGHLIGHT_OFF : "",
+               arg_order == ORDER_CPU    ? ANSI_HIGHLIGHT_ON : "", "%CPU",
+                      arg_order == ORDER_CPU    ? ANSI_HIGHLIGHT_OFF : "",
+               arg_order == ORDER_MEMORY ? ANSI_HIGHLIGHT_ON : "", "Memory",
+                      arg_order == ORDER_MEMORY ? ANSI_HIGHLIGHT_OFF : "",
+               arg_order == ORDER_IO     ? ANSI_HIGHLIGHT_ON : "", "Input/s",
+                      arg_order == ORDER_IO     ? ANSI_HIGHLIGHT_OFF : "",
+               arg_order == ORDER_IO     ? ANSI_HIGHLIGHT_ON : "", "Output/s",
+                      arg_order == ORDER_IO     ? ANSI_HIGHLIGHT_OFF : "");
+
+        for (j = 0; j < n; j++) {
+                char *p;
+                char m[FORMAT_BYTES_MAX];
+
+                if (j + 5 > rows)
+                        break;
+
+                g = array[j];
+
+                p = ellipsize(g->path, path_columns, 33);
+                printf("%-*s", path_columns, p ? p : g->path);
+                free(p);
+
+                if (g->n_tasks_valid)
+                        printf(" %7u", g->n_tasks);
+                else
+                        fputs("       -", stdout);
+
+                if (g->cpu_valid)
+                        printf(" %6.1f", g->cpu_fraction*100);
+                else
+                        fputs("      -", stdout);
+
+                if (g->memory_valid)
+                        printf(" %8s", format_bytes(m, sizeof(m), g->memory));
+                else
+                        fputs("        -", stdout);
+
+                if (g->io_valid) {
+                        printf(" %8s",
+                               format_bytes(m, sizeof(m), g->io_input_bps));
+                        printf(" %8s",
+                               format_bytes(m, sizeof(m), g->io_output_bps));
+                } else
+                        fputs("        -        -", stdout);
+
+                putchar('\n');
+        }
+
+        return 0;
+}
+
+static void help(void) {
+
+        printf("%s [OPTIONS...]\n\n"
+               "Show top control groups by their resource usage.\n\n"
+               "  -h --help           Show this help\n"
+               "  --version           Print version and exit\n"
+               "  -p                  Order by path\n"
+               "  -t                  Order by number of tasks\n"
+               "  -c                  Order by CPU load\n"
+               "  -m                  Order by memory load\n"
+               "  -i                  Order by IO load\n"
+               "  -d --delay=DELAY    Specify delay\n"
+               "  -n --iterations=N   Run for N iterations before exiting\n"
+               "  -b --batch          Run in batch mode, accepting no input\n"
+               "     --depth=DEPTH    Maximum traversal depth (default: 2)\n",
+               program_invocation_short_name);
+}
+
+static void version(void) {
+        puts(PACKAGE_STRING " cgtop");
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_DEPTH,
+        };
+
+        static const struct option options[] = {
+                { "help",       no_argument,       NULL, 'h'         },
+                { "version",    no_argument,       NULL, ARG_VERSION },
+                { "delay",      required_argument, NULL, 'd'         },
+                { "iterations", required_argument, NULL, 'n'         },
+                { "batch",      no_argument,       NULL, 'b'         },
+                { "depth",      required_argument, NULL, ARG_DEPTH   },
+                { NULL,         0,                 NULL, 0           }
+        };
+
+        int c;
+        int r;
+
+        assert(argc >= 1);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        version();
+                        return 0;
+
+                case ARG_DEPTH:
+                        r = safe_atou(optarg, &arg_depth);
+                        if (r < 0) {
+                                log_error("Failed to parse depth parameter.");
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case 'd':
+                        r = parse_usec(optarg, &arg_delay);
+                        if (r < 0 || arg_delay <= 0) {
+                                log_error("Failed to parse delay parameter.");
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case 'n':
+                        r = safe_atou(optarg, &arg_iterations);
+                        if (r < 0) {
+                                log_error("Failed to parse iterations parameter.");
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case 'b':
+                        arg_batch = true;
+                        break;
+
+                case 'p':
+                        arg_order = ORDER_PATH;
+                        break;
+
+                case 't':
+                        arg_order = ORDER_TASKS;
+                        break;
+
+                case 'c':
+                        arg_order = ORDER_CPU;
+                        break;
+
+                case 'm':
+                        arg_order = ORDER_MEMORY;
+                        break;
+
+                case 'i':
+                        arg_order = ORDER_IO;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind < argc) {
+                log_error("Too many arguments.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+        Hashmap *a = NULL, *b = NULL;
+        unsigned iteration = 0;
+        usec_t last_refresh = 0;
+        bool quit = false, immediate_refresh = false;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        a = hashmap_new(string_hash_func, string_compare_func);
+        b = hashmap_new(string_hash_func, string_compare_func);
+        if (!a || !b) {
+                r = log_oom();
+                goto finish;
+        }
+
+        signal(SIGWINCH, columns_lines_cache_reset);
+
+        while (!quit) {
+                Hashmap *c;
+                usec_t t;
+                char key;
+                char h[FORMAT_TIMESPAN_MAX];
+
+                t = now(CLOCK_MONOTONIC);
+
+                if (t >= last_refresh + arg_delay || immediate_refresh) {
+
+                        r = refresh(a, b, iteration++);
+                        if (r < 0)
+                                goto finish;
+
+                        group_hashmap_clear(b);
+
+                        c = a;
+                        a = b;
+                        b = c;
+
+                        last_refresh = t;
+                        immediate_refresh = false;
+                }
+
+                r = display(b);
+                if (r < 0)
+                        goto finish;
+
+                if (arg_iterations && iteration >= arg_iterations)
+                        break;
+
+                if (arg_batch) {
+                        usleep(last_refresh + arg_delay - t);
+                } else {
+                        r = read_one_char(stdin, &key,
+                                          last_refresh + arg_delay - t, NULL);
+                        if (r == -ETIMEDOUT)
+                                continue;
+                        if (r < 0) {
+                                log_error("Couldn't read key: %s", strerror(-r));
+                                goto finish;
+                        }
+                }
+
+                fputs("\r \r", stdout);
+                fflush(stdout);
+
+                if (arg_batch)
+                        continue;
+
+                switch (key) {
+
+                case ' ':
+                        immediate_refresh = true;
+                        break;
+
+                case 'q':
+                        quit = true;
+                        break;
+
+                case 'p':
+                        arg_order = ORDER_PATH;
+                        break;
+
+                case 't':
+                        arg_order = ORDER_TASKS;
+                        break;
+
+                case 'c':
+                        arg_order = ORDER_CPU;
+                        break;
+
+                case 'm':
+                        arg_order = ORDER_MEMORY;
+                        break;
+
+                case 'i':
+                        arg_order = ORDER_IO;
+                        break;
+
+                case '+':
+                        if (arg_delay < USEC_PER_SEC)
+                                arg_delay += USEC_PER_MSEC*250;
+                        else
+                                arg_delay += USEC_PER_SEC;
+
+                        fprintf(stdout, "\nIncreased delay to %s.", format_timespan(h, sizeof(h), arg_delay));
+                        fflush(stdout);
+                        sleep(1);
+                        break;
+
+                case '-':
+                        if (arg_delay <= USEC_PER_MSEC*500)
+                                arg_delay = USEC_PER_MSEC*250;
+                        else if (arg_delay < USEC_PER_MSEC*1250)
+                                arg_delay -= USEC_PER_MSEC*250;
+                        else
+                                arg_delay -= USEC_PER_SEC;
+
+                        fprintf(stdout, "\nDecreased delay to %s.", format_timespan(h, sizeof(h), arg_delay));
+                        fflush(stdout);
+                        sleep(1);
+                        break;
+
+                case '?':
+                case 'h':
+                        fprintf(stdout,
+                                "\t<" ANSI_HIGHLIGHT_ON "P" ANSI_HIGHLIGHT_OFF "> By path; <" ANSI_HIGHLIGHT_ON "T" ANSI_HIGHLIGHT_OFF "> By tasks; <" ANSI_HIGHLIGHT_ON "C" ANSI_HIGHLIGHT_OFF "> By CPU; <" ANSI_HIGHLIGHT_ON "M" ANSI_HIGHLIGHT_OFF "> By memory; <" ANSI_HIGHLIGHT_ON "I" ANSI_HIGHLIGHT_OFF "> By I/O\n"
+                                "\t<" ANSI_HIGHLIGHT_ON "Q" ANSI_HIGHLIGHT_OFF "> Quit; <" ANSI_HIGHLIGHT_ON "+" ANSI_HIGHLIGHT_OFF "> Increase delay; <" ANSI_HIGHLIGHT_ON "-" ANSI_HIGHLIGHT_OFF "> Decrease delay; <" ANSI_HIGHLIGHT_ON "SPACE" ANSI_HIGHLIGHT_OFF "> Refresh");
+                        fflush(stdout);
+                        sleep(3);
+                        break;
+
+                default:
+                        fprintf(stdout, "\nUnknown key '%c'. Ignoring.", key);
+                        fflush(stdout);
+                        sleep(1);
+                        break;
+                }
+        }
+
+        log_info("Exiting.");
+
+        r = 0;
+
+finish:
+        group_hashmap_free(a);
+        group_hashmap_free(b);
+
+        if (r < 0) {
+                log_error("Exiting with failure: %s", strerror(-r));
+                return EXIT_FAILURE;
+        }
+
+        return EXIT_SUCCESS;
+}
diff --git a/src/core/.gitignore b/src/core/.gitignore
new file mode 100644 (file)
index 0000000..a763f72
--- /dev/null
@@ -0,0 +1,6 @@
+/syscall-from-name.gperf
+/syscall-from-name.h
+/syscall-list.txt
+/syscall-to-name.h
+/macros.systemd
+/systemd.pc
diff --git a/src/core/Makefile b/src/core/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/core/audit-fd.c b/src/core/audit-fd.c
new file mode 100644 (file)
index 0000000..5955bd8
--- /dev/null
@@ -0,0 +1,73 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+
+#include <errno.h>
+#include "audit-fd.h"
+
+#ifdef HAVE_AUDIT
+
+#include <stdbool.h>
+#include <libaudit.h>
+
+#include "log.h"
+#include "util.h"
+
+static bool initialized = false;
+static int audit_fd;
+
+int get_audit_fd(void) {
+
+        if (!initialized) {
+                audit_fd = audit_open();
+
+                if (audit_fd < 0) {
+                        if (errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
+                                log_error("Failed to connect to audit log: %m");
+
+                        audit_fd = errno ? -errno : -EINVAL;
+                }
+
+                initialized = true;
+        }
+
+        return audit_fd;
+}
+
+void close_audit_fd(void) {
+
+        if (initialized && audit_fd >= 0)
+                close_nointr_nofail(audit_fd);
+
+        initialized = true;
+        audit_fd = -ECONNRESET;
+}
+
+#else
+
+int get_audit_fd(void) {
+        return -EAFNOSUPPORT;
+}
+
+void close_audit_fd(void) {
+}
+
+#endif
diff --git a/src/core/audit-fd.h b/src/core/audit-fd.h
new file mode 100644 (file)
index 0000000..8b58289
--- /dev/null
@@ -0,0 +1,25 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int get_audit_fd(void);
+void close_audit_fd(void);
diff --git a/src/core/automount.c b/src/core/automount.c
new file mode 100644 (file)
index 0000000..4a98540
--- /dev/null
@@ -0,0 +1,922 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <limits.h>
+#include <sys/mount.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <sys/stat.h>
+#include <linux/auto_fs4.h>
+#include <linux/auto_dev-ioctl.h>
+
+#include "unit.h"
+#include "automount.h"
+#include "mount.h"
+#include "load-fragment.h"
+#include "load-dropin.h"
+#include "unit-name.h"
+#include "dbus-automount.h"
+#include "bus-errors.h"
+#include "special.h"
+#include "label.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "dbus-common.h"
+
+static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
+        [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
+        [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
+        [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
+        [AUTOMOUNT_FAILED] = UNIT_FAILED
+};
+
+static int open_dev_autofs(Manager *m);
+
+static void automount_init(Unit *u) {
+        Automount *a = AUTOMOUNT(u);
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        a->pipe_watch.fd = a->pipe_fd = -1;
+        a->pipe_watch.type = WATCH_INVALID;
+
+        a->directory_mode = 0755;
+
+        UNIT(a)->ignore_on_isolate = true;
+}
+
+static void repeat_unmout(const char *path) {
+        assert(path);
+
+        for (;;) {
+                /* If there are multiple mounts on a mount point, this
+                 * removes them all */
+
+                if (umount2(path, MNT_DETACH) >= 0)
+                        continue;
+
+                if (errno != EINVAL)
+                        log_error("Failed to unmount: %m");
+
+                break;
+        }
+}
+
+static void unmount_autofs(Automount *a) {
+        assert(a);
+
+        if (a->pipe_fd < 0)
+                return;
+
+        automount_send_ready(a, -EHOSTDOWN);
+
+        unit_unwatch_fd(UNIT(a), &a->pipe_watch);
+        close_nointr_nofail(a->pipe_fd);
+        a->pipe_fd = -1;
+
+        /* If we reload/reexecute things we keep the mount point
+         * around */
+        if (a->where &&
+            (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
+             UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
+                repeat_unmout(a->where);
+}
+
+static void automount_done(Unit *u) {
+        Automount *a = AUTOMOUNT(u);
+
+        assert(a);
+
+        unmount_autofs(a);
+        unit_ref_unset(&a->mount);
+
+        free(a->where);
+        a->where = NULL;
+
+        set_free(a->tokens);
+        a->tokens = NULL;
+}
+
+int automount_add_one_mount_link(Automount *a, Mount *m) {
+        int r;
+
+        assert(a);
+        assert(m);
+
+        if (UNIT(a)->load_state != UNIT_LOADED ||
+            UNIT(m)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (!path_startswith(a->where, m->where))
+                return 0;
+
+        if (path_equal(a->where, m->where))
+                return 0;
+
+        r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int automount_add_mount_links(Automount *a) {
+        Unit *other;
+        int r;
+
+        assert(a);
+
+        LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT]) {
+                r = automount_add_one_mount_link(a, MOUNT(other));
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int automount_add_default_dependencies(Automount *a) {
+        int r;
+
+        assert(a);
+
+        if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
+                return 0;
+
+        r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int automount_verify(Automount *a) {
+        bool b;
+        char *e;
+        assert(a);
+
+        if (UNIT(a)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (path_equal(a->where, "/")) {
+                log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
+                return -EINVAL;
+        }
+
+        e = unit_name_from_path(a->where, ".automount");
+        if (!e)
+                return -ENOMEM;
+
+        b = unit_has_name(UNIT(a), e);
+        free(e);
+
+        if (!b) {
+                log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static int automount_load(Unit *u) {
+        int r;
+        Automount *a = AUTOMOUNT(u);
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        /* Load a .automount file */
+        r = unit_load_fragment_and_dropin_optional(u);
+        if (r < 0)
+                return r;
+
+        if (u->load_state == UNIT_LOADED) {
+                Unit *x;
+
+                if (!a->where) {
+                        a->where = unit_name_to_path(u->id);
+                        if (!a->where)
+                                return -ENOMEM;
+                }
+
+                path_kill_slashes(a->where);
+
+                r = automount_add_mount_links(a);
+                if (r < 0)
+                        return r;
+
+                r = unit_load_related_unit(u, ".mount", &x);
+                if (r < 0)
+                        return r;
+
+                unit_ref_set(&a->mount, x);
+
+                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true);
+                if (r < 0)
+                        return r;
+
+                if (UNIT(a)->default_dependencies) {
+                        r = automount_add_default_dependencies(a);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return automount_verify(a);
+}
+
+static void automount_set_state(Automount *a, AutomountState state) {
+        AutomountState old_state;
+        assert(a);
+
+        old_state = a->state;
+        a->state = state;
+
+        if (state != AUTOMOUNT_WAITING &&
+            state != AUTOMOUNT_RUNNING)
+                unmount_autofs(a);
+
+        if (state != old_state)
+                log_debug_unit(UNIT(a)->id,
+                               "%s changed %s -> %s",
+                               UNIT(a)->id,
+                               automount_state_to_string(old_state),
+                               automount_state_to_string(state));
+
+        unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
+}
+
+static int automount_coldplug(Unit *u) {
+        Automount *a = AUTOMOUNT(u);
+        int r;
+
+        assert(a);
+        assert(a->state == AUTOMOUNT_DEAD);
+
+        if (a->deserialized_state != a->state) {
+
+                r = open_dev_autofs(u->manager);
+                if (r < 0)
+                        return r;
+
+                if (a->deserialized_state == AUTOMOUNT_WAITING ||
+                    a->deserialized_state == AUTOMOUNT_RUNNING) {
+
+                        assert(a->pipe_fd >= 0);
+
+                        r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch);
+                        if (r < 0)
+                                return r;
+                }
+
+                automount_set_state(a, a->deserialized_state);
+        }
+
+        return 0;
+}
+
+static void automount_dump(Unit *u, FILE *f, const char *prefix) {
+        Automount *a = AUTOMOUNT(u);
+
+        assert(a);
+
+        fprintf(f,
+                "%sAutomount State: %s\n"
+                "%sResult: %s\n"
+                "%sWhere: %s\n"
+                "%sDirectoryMode: %04o\n",
+                prefix, automount_state_to_string(a->state),
+                prefix, automount_result_to_string(a->result),
+                prefix, a->where,
+                prefix, a->directory_mode);
+}
+
+static void automount_enter_dead(Automount *a, AutomountResult f) {
+        assert(a);
+
+        if (f != AUTOMOUNT_SUCCESS)
+                a->result = f;
+
+        automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
+}
+
+static int open_dev_autofs(Manager *m) {
+        struct autofs_dev_ioctl param;
+
+        assert(m);
+
+        if (m->dev_autofs_fd >= 0)
+                return m->dev_autofs_fd;
+
+        label_fix("/dev/autofs", false, false);
+
+        m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
+        if (m->dev_autofs_fd < 0) {
+                log_error("Failed to open /dev/autofs: %s", strerror(errno));
+                return -errno;
+        }
+
+        init_autofs_dev_ioctl(&param);
+        if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
+                close_nointr_nofail(m->dev_autofs_fd);
+                m->dev_autofs_fd = -1;
+                return -errno;
+        }
+
+        log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
+
+        return m->dev_autofs_fd;
+}
+
+static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
+        struct autofs_dev_ioctl *param;
+        size_t l;
+
+        assert(dev_autofs_fd >= 0);
+        assert(where);
+
+        l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
+        param = alloca(l);
+
+        init_autofs_dev_ioctl(param);
+        param->size = l;
+        param->ioctlfd = -1;
+        param->openmount.devid = devid;
+        strcpy(param->path, where);
+
+        if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
+                return -errno;
+
+        if (param->ioctlfd < 0)
+                return -EIO;
+
+        fd_cloexec(param->ioctlfd, true);
+        return param->ioctlfd;
+}
+
+static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
+        uint32_t major, minor;
+        struct autofs_dev_ioctl param;
+
+        assert(dev_autofs_fd >= 0);
+        assert(ioctl_fd >= 0);
+
+        init_autofs_dev_ioctl(&param);
+        param.ioctlfd = ioctl_fd;
+
+        if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, &param) < 0)
+                return -errno;
+
+        major = param.protover.version;
+
+        init_autofs_dev_ioctl(&param);
+        param.ioctlfd = ioctl_fd;
+
+        if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, &param) < 0)
+                return -errno;
+
+        minor = param.protosubver.sub_version;
+
+        log_debug("Autofs protocol version %i.%i", major, minor);
+        return 0;
+}
+
+static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
+        struct autofs_dev_ioctl param;
+
+        assert(dev_autofs_fd >= 0);
+        assert(ioctl_fd >= 0);
+
+        init_autofs_dev_ioctl(&param);
+        param.ioctlfd = ioctl_fd;
+        param.timeout.timeout = sec;
+
+        if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) < 0)
+                return -errno;
+
+        return 0;
+}
+
+static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
+        struct autofs_dev_ioctl param;
+
+        assert(dev_autofs_fd >= 0);
+        assert(ioctl_fd >= 0);
+
+        init_autofs_dev_ioctl(&param);
+        param.ioctlfd = ioctl_fd;
+
+        if (status) {
+                param.fail.token = token;
+                param.fail.status = status;
+        } else
+                param.ready.token = token;
+
+        if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, &param) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int automount_send_ready(Automount *a, int status) {
+        int ioctl_fd, r;
+        unsigned token;
+
+        assert(a);
+        assert(status <= 0);
+
+        if (set_isempty(a->tokens))
+                return 0;
+
+        ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
+        if (ioctl_fd < 0) {
+                r = ioctl_fd;
+                goto fail;
+        }
+
+        if (status)
+                log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
+        else
+                log_debug_unit(UNIT(a)->id, "Sending success.");
+
+        r = 0;
+
+        /* Autofs thankfully does not hand out 0 as a token */
+        while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
+                int k;
+
+                /* Autofs fun fact II:
+                 *
+                 * if you pass a positive status code here, the kernel will
+                 * freeze! Yay! */
+
+                k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
+                                      ioctl_fd,
+                                      token,
+                                      status);
+                if (k < 0)
+                        r = k;
+        }
+
+fail:
+        if (ioctl_fd >= 0)
+                close_nointr_nofail(ioctl_fd);
+
+        return r;
+}
+
+static void automount_enter_waiting(Automount *a) {
+        int p[2] = { -1, -1 };
+        char name[32], options[128];
+        bool mounted = false;
+        int r, ioctl_fd = -1, dev_autofs_fd;
+        struct stat st;
+
+        assert(a);
+        assert(a->pipe_fd < 0);
+        assert(a->where);
+
+        if (a->tokens)
+                set_clear(a->tokens);
+
+        dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
+        if (dev_autofs_fd < 0) {
+                r = dev_autofs_fd;
+                goto fail;
+        }
+
+        /* We knowingly ignore the results of this call */
+        mkdir_p_label(a->where, 0555);
+
+        warn_if_dir_nonempty(a->meta.id, a->where);
+
+        if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
+        char_array_0(options);
+
+        snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
+        char_array_0(name);
+
+        if (mount(name, a->where, "autofs", 0, options) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        mounted = true;
+
+        close_nointr_nofail(p[1]);
+        p[1] = -1;
+
+        if (stat(a->where, &st) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
+        if (ioctl_fd < 0) {
+                r = ioctl_fd;
+                goto fail;
+        }
+
+        r = autofs_protocol(dev_autofs_fd, ioctl_fd);
+        if (r < 0)
+                goto fail;
+
+        r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
+        if (r < 0)
+                goto fail;
+
+        /* Autofs fun fact:
+         *
+         * Unless we close the ioctl fd here, for some weird reason
+         * the direct mount will not receive events from the
+         * kernel. */
+
+        close_nointr_nofail(ioctl_fd);
+        ioctl_fd = -1;
+
+        r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch);
+        if (r < 0)
+                goto fail;
+
+        a->pipe_fd = p[0];
+        a->dev_id = st.st_dev;
+
+        automount_set_state(a, AUTOMOUNT_WAITING);
+
+        return;
+
+fail:
+        assert_se(close_pipe(p) == 0);
+
+        if (ioctl_fd >= 0)
+                close_nointr_nofail(ioctl_fd);
+
+        if (mounted)
+                repeat_unmout(a->where);
+
+        log_error_unit(UNIT(a)->id,
+                       "Failed to initialize automounter: %s", strerror(-r));
+        automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
+}
+
+static void automount_enter_runnning(Automount *a) {
+        int r;
+        struct stat st;
+        _cleanup_dbus_error_free_ DBusError error;
+
+        assert(a);
+        assert(UNIT_DEREF(a->mount));
+
+        dbus_error_init(&error);
+
+        /* We don't take mount requests anymore if we are supposed to
+         * shut down anyway */
+        if (unit_pending_inactive(UNIT(a))) {
+                log_debug_unit(UNIT(a)->id,
+                               "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
+                automount_send_ready(a, -EHOSTDOWN);
+                return;
+        }
+
+        mkdir_p_label(a->where, a->directory_mode);
+
+        /* Before we do anything, let's see if somebody is playing games with us? */
+        if (lstat(a->where, &st) < 0) {
+                log_warning_unit(UNIT(a)->id,
+                                 "%s failed to stat automount point: %m", UNIT(a)->id);
+                goto fail;
+        }
+
+        if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
+                log_info_unit(UNIT(a)->id,
+                              "%s's automount point already active?", UNIT(a)->id);
+        else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
+                log_warning_unit(UNIT(a)->id,
+                                 "%s failed to queue mount startup job: %s",
+                                 UNIT(a)->id, bus_error(&error, r));
+                goto fail;
+        }
+
+        automount_set_state(a, AUTOMOUNT_RUNNING);
+        return;
+
+fail:
+        automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
+}
+
+static int automount_start(Unit *u) {
+        Automount *a = AUTOMOUNT(u);
+
+        assert(a);
+        assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
+
+        if (path_is_mount_point(a->where, false)) {
+                log_error_unit(u->id,
+                               "Path %s is already a mount point, refusing start for %s",
+                               a->where, u->id);
+                return -EEXIST;
+        }
+
+        if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED)
+                return -ENOENT;
+
+        a->result = AUTOMOUNT_SUCCESS;
+        automount_enter_waiting(a);
+        return 0;
+}
+
+static int automount_stop(Unit *u) {
+        Automount *a = AUTOMOUNT(u);
+
+        assert(a);
+        assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
+
+        automount_enter_dead(a, AUTOMOUNT_SUCCESS);
+        return 0;
+}
+
+static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Automount *a = AUTOMOUNT(u);
+        void *p;
+        Iterator i;
+
+        assert(a);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
+        unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
+        unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
+
+        SET_FOREACH(p, a->tokens, i)
+                unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
+
+        if (a->pipe_fd >= 0) {
+                int copy;
+
+                copy = fdset_put_dup(fds, a->pipe_fd);
+                if (copy < 0)
+                        return copy;
+
+                unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
+        }
+
+        return 0;
+}
+
+static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Automount *a = AUTOMOUNT(u);
+        int r;
+
+        assert(a);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                AutomountState state;
+
+                state = automount_state_from_string(value);
+                if (state < 0)
+                        log_debug_unit(u->id, "Failed to parse state value %s", value);
+                else
+                        a->deserialized_state = state;
+        } else if (streq(key, "result")) {
+                AutomountResult f;
+
+                f = automount_result_from_string(value);
+                if (f < 0)
+                        log_debug_unit(u->id, "Failed to parse result value %s", value);
+                else if (f != AUTOMOUNT_SUCCESS)
+                        a->result = f;
+
+        } else if (streq(key, "dev-id")) {
+                unsigned d;
+
+                if (safe_atou(value, &d) < 0)
+                        log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
+                else
+                        a->dev_id = (unsigned) d;
+        } else if (streq(key, "token")) {
+                unsigned token;
+
+                if (safe_atou(value, &token) < 0)
+                        log_debug_unit(u->id, "Failed to parse token value %s", value);
+                else {
+                        if (!a->tokens)
+                                if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
+                                        return -ENOMEM;
+
+                        r = set_put(a->tokens, UINT_TO_PTR(token));
+                        if (r < 0)
+                                return r;
+                }
+        } else if (streq(key, "pipe-fd")) {
+                int fd;
+
+                if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+                        log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
+                else {
+                        if (a->pipe_fd >= 0)
+                                close_nointr_nofail(a->pipe_fd);
+
+                        a->pipe_fd = fdset_remove(fds, fd);
+                }
+        } else
+                log_debug_unit(u->id, "Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static UnitActiveState automount_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[AUTOMOUNT(u)->state];
+}
+
+static const char *automount_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return automount_state_to_string(AUTOMOUNT(u)->state);
+}
+
+static bool automount_check_gc(Unit *u) {
+        Automount *a = AUTOMOUNT(u);
+
+        assert(a);
+
+        if (!UNIT_DEREF(a->mount))
+                return false;
+
+        return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount));
+}
+
+static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+        Automount *a = AUTOMOUNT(u);
+        union autofs_v5_packet_union packet;
+        ssize_t l;
+        int r;
+
+        assert(a);
+        assert(fd == a->pipe_fd);
+
+        if (events != EPOLLIN) {
+                log_error_unit(u->id, "Got invalid poll event on pipe.");
+                goto fail;
+        }
+
+        l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
+        if (l != sizeof(packet)) {
+                log_error_unit(u->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
+                goto fail;
+        }
+
+        switch (packet.hdr.type) {
+
+        case autofs_ptype_missing_direct:
+
+                if (packet.v5_packet.pid > 0) {
+                        _cleanup_free_ char *p = NULL;
+
+                        get_process_comm(packet.v5_packet.pid, &p);
+                        log_debug_unit(u->id,
+                                       "Got direct mount request on %s, triggered by %lu (%s)",
+                                       a->where, (unsigned long) packet.v5_packet.pid, strna(p));
+                } else
+                        log_debug_unit(u->id, "Got direct mount request on %s", a->where);
+
+                r = set_ensure_allocated(&a->tokens, trivial_hash_func, trivial_compare_func);
+                if (r < 0) {
+                        log_error_unit(u->id, "Failed to allocate token set.");
+                        goto fail;
+                }
+
+                r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
+                if (r < 0) {
+                        log_error_unit(u->id, "Failed to remember token: %s", strerror(-r));
+                        goto fail;
+                }
+
+                automount_enter_runnning(a);
+                break;
+
+        default:
+                log_error_unit(u->id, "Received unknown automount request %i", packet.hdr.type);
+                break;
+        }
+
+        return;
+
+fail:
+        automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
+}
+
+static void automount_shutdown(Manager *m) {
+        assert(m);
+
+        if (m->dev_autofs_fd >= 0)
+                close_nointr_nofail(m->dev_autofs_fd);
+}
+
+static void automount_reset_failed(Unit *u) {
+        Automount *a = AUTOMOUNT(u);
+
+        assert(a);
+
+        if (a->state == AUTOMOUNT_FAILED)
+                automount_set_state(a, AUTOMOUNT_DEAD);
+
+        a->result = AUTOMOUNT_SUCCESS;
+}
+
+static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
+        [AUTOMOUNT_DEAD] = "dead",
+        [AUTOMOUNT_WAITING] = "waiting",
+        [AUTOMOUNT_RUNNING] = "running",
+        [AUTOMOUNT_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
+
+static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
+        [AUTOMOUNT_SUCCESS] = "success",
+        [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
+
+const UnitVTable automount_vtable = {
+        .object_size = sizeof(Automount),
+        .sections =
+                "Unit\0"
+                "Automount\0"
+                "Install\0",
+
+        .no_alias = true,
+        .no_instances = true,
+
+        .init = automount_init,
+        .load = automount_load,
+        .done = automount_done,
+
+        .coldplug = automount_coldplug,
+
+        .dump = automount_dump,
+
+        .start = automount_start,
+        .stop = automount_stop,
+
+        .serialize = automount_serialize,
+        .deserialize_item = automount_deserialize_item,
+
+        .active_state = automount_active_state,
+        .sub_state_to_string = automount_sub_state_to_string,
+
+        .check_gc = automount_check_gc,
+
+        .fd_event = automount_fd_event,
+
+        .reset_failed = automount_reset_failed,
+
+        .bus_interface = "org.freedesktop.systemd1.Automount",
+        .bus_message_handler = bus_automount_message_handler,
+        .bus_invalidating_properties = bus_automount_invalidating_properties,
+
+        .shutdown = automount_shutdown,
+
+        .status_message_formats = {
+                .finished_start_job = {
+                        [JOB_DONE]       = "Set up automount %s.",
+                        [JOB_FAILED]     = "Failed to set up automount %s.",
+                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                },
+                .finished_stop_job = {
+                        [JOB_DONE]       = "Unset automount %s.",
+                        [JOB_FAILED]     = "Failed to unset automount %s.",
+                },
+        },
+};
diff --git a/src/core/automount.h b/src/core/automount.h
new file mode 100644 (file)
index 0000000..3d5736d
--- /dev/null
@@ -0,0 +1,73 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Automount Automount;
+
+#include "unit.h"
+
+typedef enum AutomountState {
+        AUTOMOUNT_DEAD,
+        AUTOMOUNT_WAITING,
+        AUTOMOUNT_RUNNING,
+        AUTOMOUNT_FAILED,
+        _AUTOMOUNT_STATE_MAX,
+        _AUTOMOUNT_STATE_INVALID = -1
+} AutomountState;
+
+typedef enum AutomountResult {
+        AUTOMOUNT_SUCCESS,
+        AUTOMOUNT_FAILURE_RESOURCES,
+        _AUTOMOUNT_RESULT_MAX,
+        _AUTOMOUNT_RESULT_INVALID = -1
+} AutomountResult;
+
+struct Automount {
+        Unit meta;
+
+        AutomountState state, deserialized_state;
+
+        char *where;
+
+        UnitRef mount;
+
+        int pipe_fd;
+        mode_t directory_mode;
+        Watch pipe_watch;
+        dev_t dev_id;
+
+        Set *tokens;
+
+        AutomountResult result;
+};
+
+extern const UnitVTable automount_vtable;
+
+int automount_send_ready(Automount *a, int status);
+
+int automount_add_one_mount_link(Automount *a, Mount *m);
+
+const char* automount_state_to_string(AutomountState i);
+AutomountState automount_state_from_string(const char *s);
+
+const char* automount_result_to_string(AutomountResult i);
+AutomountResult automount_result_from_string(const char *s);
diff --git a/src/core/build.h b/src/core/build.h
new file mode 100644 (file)
index 0000000..4513a0b
--- /dev/null
@@ -0,0 +1,84 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_PAM
+#define _PAM_FEATURE_ "+PAM"
+#else
+#define _PAM_FEATURE_ "-PAM"
+#endif
+
+#ifdef HAVE_LIBWRAP
+#define _LIBWRAP_FEATURE_ "+LIBWRAP"
+#else
+#define _LIBWRAP_FEATURE_ "-LIBWRAP"
+#endif
+
+#ifdef HAVE_AUDIT
+#define _AUDIT_FEATURE_ "+AUDIT"
+#else
+#define _AUDIT_FEATURE_ "-AUDIT"
+#endif
+
+#ifdef HAVE_SELINUX
+#define _SELINUX_FEATURE_ "+SELINUX"
+#else
+#define _SELINUX_FEATURE_ "-SELINUX"
+#endif
+
+#ifdef HAVE_IMA
+#define _IMA_FEATURE_ "+IMA"
+#else
+#define _IMA_FEATURE_ "-IMA"
+#endif
+
+#ifdef HAVE_SYSV_COMPAT
+#define _SYSVINIT_FEATURE_ "+SYSVINIT"
+#else
+#define _SYSVINIT_FEATURE_ "-SYSVINIT"
+#endif
+
+#ifdef HAVE_LIBCRYPTSETUP
+#define _LIBCRYPTSETUP_FEATURE_ "+LIBCRYPTSETUP"
+#else
+#define _LIBCRYPTSETUP_FEATURE_ "-LIBCRYPTSETUP"
+#endif
+
+#ifdef HAVE_GCRYPT
+#define _GCRYPT_FEATURE_ "+GCRYPT"
+#else
+#define _GCRYPT_FEATURE_ "-GCRYPT"
+#endif
+
+#ifdef HAVE_ACL
+#define _ACL_FEATURE_ "+ACL"
+#else
+#define _ACL_FEATURE_ "-ACL"
+#endif
+
+#ifdef HAVE_XZ
+#define _XZ_FEATURE_ "+XZ"
+#else
+#define _XZ_FEATURE_ "-XZ"
+#endif
+
+#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _IMA_FEATURE_ " " _SYSVINIT_FEATURE_ " " _LIBCRYPTSETUP_FEATURE_ " " _GCRYPT_FEATURE_ " " _ACL_FEATURE_ " " _XZ_FEATURE_
diff --git a/src/core/bus-errors.h b/src/core/bus-errors.h
new file mode 100644 (file)
index 0000000..04c1b28
--- /dev/null
@@ -0,0 +1,55 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <dbus/dbus.h>
+
+#define BUS_ERROR_NO_SUCH_UNIT "org.freedesktop.systemd1.NoSuchUnit"
+#define BUS_ERROR_NO_SUCH_JOB "org.freedesktop.systemd1.NoSuchJob"
+#define BUS_ERROR_NOT_SUBSCRIBED "org.freedesktop.systemd1.NotSubscribed"
+#define BUS_ERROR_INVALID_PATH "org.freedesktop.systemd1.InvalidPath"
+#define BUS_ERROR_INVALID_NAME "org.freedesktop.systemd1.InvalidName"
+#define BUS_ERROR_UNIT_TYPE_MISMATCH "org.freedesktop.systemd1.UnitTypeMismatch"
+#define BUS_ERROR_UNIT_EXISTS "org.freedesktop.systemd1.UnitExists"
+#define BUS_ERROR_NOT_SUPPORTED "org.freedesktop.systemd1.NotSupported"
+#define BUS_ERROR_INVALID_JOB_MODE "org.freedesktop.systemd1.InvalidJobMode"
+#define BUS_ERROR_ONLY_BY_DEPENDENCY "org.freedesktop.systemd1.OnlyByDependency"
+#define BUS_ERROR_NO_ISOLATION "org.freedesktop.systemd1.NoIsolation"
+#define BUS_ERROR_LOAD_FAILED "org.freedesktop.systemd1.LoadFailed"
+#define BUS_ERROR_MASKED "org.freedesktop.systemd1.Masked"
+#define BUS_ERROR_JOB_TYPE_NOT_APPLICABLE "org.freedesktop.systemd1.JobTypeNotApplicable"
+#define BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE "org.freedesktop.systemd1.TransactionIsDestructive"
+#define BUS_ERROR_TRANSACTION_JOBS_CONFLICTING "org.freedesktop.systemd1.TransactionJobsConflicting"
+#define BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC "org.freedesktop.systemd1.TransactionOrderIsCyclic"
+#define BUS_ERROR_SHUTTING_DOWN "org.freedesktop.systemd1.ShuttingDown"
+#define BUS_ERROR_NO_SUCH_PROCESS "org.freedesktop.systemd1.NoSuchProcess"
+
+static inline const char *bus_error(const DBusError *e, int r) {
+        if (e && e->message)
+                return e->message;
+
+        if (r >= 0)
+                return strerror(r);
+
+        return strerror(-r);
+}
diff --git a/src/core/cgroup-attr.c b/src/core/cgroup-attr.c
new file mode 100644 (file)
index 0000000..71af09c
--- /dev/null
@@ -0,0 +1,102 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "cgroup-attr.h"
+#include "cgroup-util.h"
+#include "list.h"
+
+int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b) {
+        int r;
+        char *path = NULL;
+        char *v = NULL;
+
+        assert(a);
+
+        b = cgroup_bonding_find_list(b, a->controller);
+        if (!b)
+                return 0;
+
+        if (a->map_callback) {
+                r = a->map_callback(a->controller, a->name, a->value, &v);
+                if (r < 0)
+                        return r;
+        }
+
+        r = cg_get_path(a->controller, b->path, a->name, &path);
+        if (r < 0) {
+                free(v);
+                return r;
+        }
+
+        r = write_one_line_file(path, v ? v : a->value);
+        if (r < 0)
+                log_warning("Failed to write '%s' to %s: %s", v ? v : a->value, path, strerror(-r));
+
+        free(path);
+        free(v);
+
+        return r;
+}
+
+int cgroup_attribute_apply_list(CGroupAttribute *first, CGroupBonding *b) {
+        CGroupAttribute *a;
+        int r = 0;
+
+        LIST_FOREACH(by_unit, a, first) {
+                int k;
+
+                k = cgroup_attribute_apply(a, b);
+                if (r == 0)
+                        r = k;
+        }
+
+        return r;
+}
+
+CGroupAttribute *cgroup_attribute_find_list(CGroupAttribute *first, const char *controller, const char *name) {
+        CGroupAttribute *a;
+
+        assert(controller);
+        assert(name);
+
+        LIST_FOREACH(by_unit, a, first)
+                if (streq(a->controller, controller) &&
+                    streq(a->name, name))
+                        return a;
+
+        return NULL;
+}
+
+static void cgroup_attribute_free(CGroupAttribute *a) {
+        assert(a);
+
+        free(a->controller);
+        free(a->name);
+        free(a->value);
+        free(a);
+}
+
+void cgroup_attribute_free_list(CGroupAttribute *first) {
+        CGroupAttribute *a, *n;
+
+        LIST_FOREACH_SAFE(by_unit, a, n, first)
+                cgroup_attribute_free(a);
+}
diff --git a/src/core/cgroup-attr.h b/src/core/cgroup-attr.h
new file mode 100644 (file)
index 0000000..2b754ea
--- /dev/null
@@ -0,0 +1,46 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct CGroupAttribute CGroupAttribute;
+
+typedef int (*CGroupAttributeMapCallback)(const char *controller, const char*name, const char *value, char **ret);
+
+#include "unit.h"
+#include "cgroup.h"
+
+struct CGroupAttribute {
+        char *controller;
+        char *name;
+        char *value;
+
+        CGroupAttributeMapCallback map_callback;
+
+        LIST_FIELDS(CGroupAttribute, by_unit);
+};
+
+int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b);
+int cgroup_attribute_apply_list(CGroupAttribute *first, CGroupBonding *b);
+
+CGroupAttribute *cgroup_attribute_find_list(CGroupAttribute *first, const char *controller, const char *name);
+
+void cgroup_attribute_free_list(CGroupAttribute *first);
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
new file mode 100644 (file)
index 0000000..8fc1731
--- /dev/null
@@ -0,0 +1,598 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+
+#include "cgroup.h"
+#include "cgroup-util.h"
+#include "log.h"
+#include "strv.h"
+#include "path-util.h"
+
+int cgroup_bonding_realize(CGroupBonding *b) {
+        int r;
+
+        assert(b);
+        assert(b->path);
+        assert(b->controller);
+
+        r = cg_create(b->controller, b->path);
+        if (r < 0) {
+                log_warning("Failed to create cgroup %s:%s: %s", b->controller, b->path, strerror(-r));
+                return r;
+        }
+
+        b->realized = true;
+
+        return 0;
+}
+
+int cgroup_bonding_realize_list(CGroupBonding *first) {
+        CGroupBonding *b;
+        int r;
+
+        LIST_FOREACH(by_unit, b, first)
+                if ((r = cgroup_bonding_realize(b)) < 0 && b->essential)
+                        return r;
+
+        return 0;
+}
+
+void cgroup_bonding_free(CGroupBonding *b, bool trim) {
+        assert(b);
+
+        if (b->unit) {
+                CGroupBonding *f;
+
+                LIST_REMOVE(CGroupBonding, by_unit, b->unit->cgroup_bondings, b);
+
+                if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                        assert_se(f = hashmap_get(b->unit->manager->cgroup_bondings, b->path));
+                        LIST_REMOVE(CGroupBonding, by_path, f, b);
+
+                        if (f)
+                                hashmap_replace(b->unit->manager->cgroup_bondings, b->path, f);
+                        else
+                                hashmap_remove(b->unit->manager->cgroup_bondings, b->path);
+                }
+        }
+
+        if (b->realized && b->ours && trim)
+                cg_trim(b->controller, b->path, false);
+
+        free(b->controller);
+        free(b->path);
+        free(b);
+}
+
+void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim) {
+        CGroupBonding *b, *n;
+
+        LIST_FOREACH_SAFE(by_unit, b, n, first)
+                cgroup_bonding_free(b, remove_or_trim);
+}
+
+void cgroup_bonding_trim(CGroupBonding *b, bool delete_root) {
+        assert(b);
+
+        if (b->realized && b->ours)
+                cg_trim(b->controller, b->path, delete_root);
+}
+
+void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root) {
+        CGroupBonding *b;
+
+        LIST_FOREACH(by_unit, b, first)
+                cgroup_bonding_trim(b, delete_root);
+}
+
+
+int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *cgroup_suffix) {
+        char *p = NULL;
+        const char *path;
+        int r;
+
+        assert(b);
+        assert(pid >= 0);
+
+        if (cgroup_suffix) {
+                p = strjoin(b->path, "/", cgroup_suffix, NULL);
+                if (!p)
+                        return -ENOMEM;
+
+                path = p;
+        } else
+                path = b->path;
+
+        r = cg_create_and_attach(b->controller, path, pid);
+        free(p);
+
+        if (r < 0)
+                return r;
+
+        b->realized = true;
+        return 0;
+}
+
+int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *cgroup_suffix) {
+        CGroupBonding *b;
+        int r;
+
+        LIST_FOREACH(by_unit, b, first) {
+                r = cgroup_bonding_install(b, pid, cgroup_suffix);
+                if (r < 0 && b->essential)
+                        return r;
+        }
+
+        return 0;
+}
+
+int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) {
+        assert(b);
+
+        if (!b->realized)
+                return -EINVAL;
+
+        return cg_set_group_access(b->controller, b->path, mode, uid, gid);
+}
+
+int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) {
+        CGroupBonding *b;
+        int r;
+
+        LIST_FOREACH(by_unit, b, first) {
+                r = cgroup_bonding_set_group_access(b, mode, uid, gid);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky) {
+        assert(b);
+
+        if (!b->realized)
+                return -EINVAL;
+
+        return cg_set_task_access(b->controller, b->path, mode, uid, gid, sticky);
+}
+
+int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid, int sticky) {
+        CGroupBonding *b;
+        int r;
+
+        LIST_FOREACH(by_unit, b, first) {
+                r = cgroup_bonding_set_task_access(b, mode, uid, gid, sticky);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, bool rem, Set *s, const char *cgroup_suffix) {
+        char *p = NULL;
+        const char *path;
+        int r;
+
+        assert(b);
+        assert(sig >= 0);
+
+        /* Don't kill cgroups that aren't ours */
+        if (!b->ours)
+                return 0;
+
+        if (cgroup_suffix) {
+                p = strjoin(b->path, "/", cgroup_suffix, NULL);
+                if (!p)
+                        return -ENOMEM;
+
+                path = p;
+        } else
+                path = b->path;
+
+        r = cg_kill_recursive(b->controller, path, sig, sigcont, true, rem, s);
+        free(p);
+
+        return r;
+}
+
+int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, bool rem, Set *s, const char *cgroup_suffix) {
+        CGroupBonding *b;
+        Set *allocated_set = NULL;
+        int ret = -EAGAIN, r;
+
+        if (!first)
+                return 0;
+
+        if (!s)
+                if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
+                        return -ENOMEM;
+
+        LIST_FOREACH(by_unit, b, first) {
+                r = cgroup_bonding_kill(b, sig, sigcont, rem, s, cgroup_suffix);
+                if (r < 0) {
+                        if (r == -EAGAIN || r == -ESRCH)
+                                continue;
+
+                        ret = r;
+                        goto finish;
+                }
+
+                if (ret < 0 || r > 0)
+                        ret = r;
+        }
+
+finish:
+        if (allocated_set)
+                set_free(allocated_set);
+
+        return ret;
+}
+
+/* Returns 1 if the group is empty, 0 if it is not, -EAGAIN if we
+ * cannot know */
+int cgroup_bonding_is_empty(CGroupBonding *b) {
+        int r;
+
+        assert(b);
+
+        if ((r = cg_is_empty_recursive(b->controller, b->path, true)) < 0)
+                return r;
+
+        /* If it is empty it is empty */
+        if (r > 0)
+                return 1;
+
+        /* It's not only us using this cgroup, so we just don't know */
+        return b->ours ? 0 : -EAGAIN;
+}
+
+int cgroup_bonding_is_empty_list(CGroupBonding *first) {
+        CGroupBonding *b;
+
+        LIST_FOREACH(by_unit, b, first) {
+                int r;
+
+                if ((r = cgroup_bonding_is_empty(b)) < 0) {
+                        /* If this returned -EAGAIN, then we don't know if the
+                         * group is empty, so let's see if another group can
+                         * tell us */
+
+                        if (r != -EAGAIN)
+                                return r;
+                } else
+                        return r;
+        }
+
+        return -EAGAIN;
+}
+
+int manager_setup_cgroup(Manager *m) {
+        char *current = NULL, *path = NULL;
+        int r;
+        char suffix[32];
+
+        assert(m);
+
+        /* 0. Be nice to Ingo Molnar #628004 */
+        if (path_is_mount_point("/sys/fs/cgroup/systemd", false) <= 0) {
+                log_warning("No control group support available, not creating root group.");
+                return 0;
+        }
+
+        /* 1. Determine hierarchy */
+        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &current);
+        if (r < 0) {
+                log_error("Cannot determine cgroup we are running in: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (m->running_as == SYSTEMD_SYSTEM)
+                strcpy(suffix, "/system");
+        else {
+                snprintf(suffix, sizeof(suffix), "/systemd-%lu", (unsigned long) getpid());
+                char_array_0(suffix);
+        }
+
+        free(m->cgroup_hierarchy);
+        if (endswith(current, suffix)) {
+                /* We probably got reexecuted and can continue to use our root cgroup */
+                m->cgroup_hierarchy = current;
+                current = NULL;
+
+        } else {
+                /* We need a new root cgroup */
+                m->cgroup_hierarchy = NULL;
+                if (asprintf(&m->cgroup_hierarchy, "%s%s", streq(current, "/") ? "" : current, suffix) < 0) {
+                        r = log_oom();
+                        goto finish;
+                }
+        }
+
+        /* 2. Show data */
+        r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path);
+        if (r < 0) {
+                log_error("Cannot find cgroup mount point: %s", strerror(-r));
+                goto finish;
+        }
+
+        log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
+
+        /* 3. Install agent */
+        r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH);
+        if (r < 0)
+                log_warning("Failed to install release agent, ignoring: %s", strerror(-r));
+        else if (r > 0)
+                log_debug("Installed release agent.");
+        else
+                log_debug("Release agent already installed.");
+
+        /* 4. Realize the group */
+        r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, 0);
+        if (r < 0) {
+                log_error("Failed to create root cgroup hierarchy: %s", strerror(-r));
+                goto finish;
+        }
+
+        /* 5. And pin it, so that it cannot be unmounted */
+        if (m->pin_cgroupfs_fd >= 0)
+                close_nointr_nofail(m->pin_cgroupfs_fd);
+
+        m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK);
+        if (r < 0) {
+                log_error("Failed to open pin file: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        log_debug("Created root group.");
+
+        cg_shorten_controllers(m->default_controllers);
+
+finish:
+        free(current);
+        free(path);
+
+        return r;
+}
+
+void manager_shutdown_cgroup(Manager *m, bool delete) {
+        assert(m);
+
+        if (delete && m->cgroup_hierarchy)
+                cg_delete(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy);
+
+        if (m->pin_cgroupfs_fd >= 0) {
+                close_nointr_nofail(m->pin_cgroupfs_fd);
+                m->pin_cgroupfs_fd = -1;
+        }
+
+        free(m->cgroup_hierarchy);
+        m->cgroup_hierarchy = NULL;
+}
+
+int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding) {
+        CGroupBonding *b;
+        char *p;
+
+        assert(m);
+        assert(cgroup);
+        assert(bonding);
+
+        b = hashmap_get(m->cgroup_bondings, cgroup);
+        if (b) {
+                *bonding = b;
+                return 1;
+        }
+
+        p = strdup(cgroup);
+        if (!p)
+                return -ENOMEM;
+
+        for (;;) {
+                char *e;
+
+                e = strrchr(p, '/');
+                if (!e || e == p) {
+                        free(p);
+                        *bonding = NULL;
+                        return 0;
+                }
+
+                *e = 0;
+
+                b = hashmap_get(m->cgroup_bondings, p);
+                if (b) {
+                        free(p);
+                        *bonding = b;
+                        return 1;
+                }
+        }
+}
+
+int cgroup_notify_empty(Manager *m, const char *group) {
+        CGroupBonding *l, *b;
+        int r;
+
+        assert(m);
+        assert(group);
+
+        r = cgroup_bonding_get(m, group, &l);
+        if (r <= 0)
+                return r;
+
+        LIST_FOREACH(by_path, b, l) {
+                int t;
+
+                if (!b->unit)
+                        continue;
+
+                t = cgroup_bonding_is_empty_list(b);
+                if (t < 0) {
+
+                        /* If we don't know, we don't know */
+                        if (t != -EAGAIN)
+                                log_warning("Failed to check whether cgroup is empty: %s", strerror(errno));
+
+                        continue;
+                }
+
+                if (t > 0) {
+                        /* If it is empty, let's delete it */
+                        cgroup_bonding_trim_list(b->unit->cgroup_bondings, true);
+
+                        if (UNIT_VTABLE(b->unit)->cgroup_notify_empty)
+                                UNIT_VTABLE(b->unit)->cgroup_notify_empty(b->unit);
+                }
+        }
+
+        return 0;
+}
+
+Unit* cgroup_unit_by_pid(Manager *m, pid_t pid) {
+        CGroupBonding *l, *b;
+        char *group = NULL;
+
+        assert(m);
+
+        if (pid <= 1)
+                return NULL;
+
+        if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &group) < 0)
+                return NULL;
+
+        l = hashmap_get(m->cgroup_bondings, group);
+
+        if (!l) {
+                char *slash;
+
+                while ((slash = strrchr(group, '/'))) {
+                        if (slash == group)
+                                break;
+
+                        *slash = 0;
+
+                        if ((l = hashmap_get(m->cgroup_bondings, group)))
+                                break;
+                }
+        }
+
+        free(group);
+
+        LIST_FOREACH(by_path, b, l) {
+
+                if (!b->unit)
+                        continue;
+
+                if (b->ours)
+                        return b->unit;
+        }
+
+        return NULL;
+}
+
+CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller) {
+        CGroupBonding *b;
+
+        assert(controller);
+
+        LIST_FOREACH(by_unit, b, first)
+                if (streq(b->controller, controller))
+                        return b;
+
+        return NULL;
+}
+
+char *cgroup_bonding_to_string(CGroupBonding *b) {
+        char *r;
+
+        assert(b);
+
+        if (asprintf(&r, "%s:%s", b->controller, b->path) < 0)
+                return NULL;
+
+        return r;
+}
+
+pid_t cgroup_bonding_search_main_pid(CGroupBonding *b) {
+        FILE *f;
+        pid_t pid = 0, npid, mypid;
+
+        assert(b);
+
+        if (!b->ours)
+                return 0;
+
+        if (cg_enumerate_processes(b->controller, b->path, &f) < 0)
+                return 0;
+
+        mypid = getpid();
+
+        while (cg_read_pid(f, &npid) > 0)  {
+                pid_t ppid;
+
+                if (npid == pid)
+                        continue;
+
+                /* Ignore processes that aren't our kids */
+                if (get_parent_of_pid(npid, &ppid) >= 0 && ppid != mypid)
+                        continue;
+
+                if (pid != 0) {
+                        /* Dang, there's more than one daemonized PID
+                        in this group, so we don't know what process
+                        is the main process. */
+                        pid = 0;
+                        break;
+                }
+
+                pid = npid;
+        }
+
+        fclose(f);
+
+        return pid;
+}
+
+pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *first) {
+        CGroupBonding *b;
+        pid_t pid;
+
+        /* Try to find a main pid from this cgroup, but checking if
+         * there's only one PID in the cgroup and returning it. Later
+         * on we might want to add additional, smarter heuristics
+         * here. */
+
+        LIST_FOREACH(by_unit, b, first)
+                if ((pid = cgroup_bonding_search_main_pid(b)) != 0)
+                        return pid;
+
+        return 0;
+
+}
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
new file mode 100644 (file)
index 0000000..229da52
--- /dev/null
@@ -0,0 +1,91 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct CGroupBonding CGroupBonding;
+
+#include "unit.h"
+
+/* Binds a cgroup to a name */
+struct CGroupBonding {
+        char *controller;
+        char *path;
+
+        Unit *unit;
+
+        /* For the Unit::cgroup_bondings list */
+        LIST_FIELDS(CGroupBonding, by_unit);
+
+        /* For the Manager::cgroup_bondings hashmap */
+        LIST_FIELDS(CGroupBonding, by_path);
+
+        /* When shutting down, remove cgroup? Are our own tasks the
+         * only ones in this group?*/
+        bool ours:1;
+
+        /* If we cannot create this group, or add a process to it, is this fatal? */
+        bool essential:1;
+
+        /* This cgroup is realized */
+        bool realized:1;
+};
+
+int cgroup_bonding_realize(CGroupBonding *b);
+int cgroup_bonding_realize_list(CGroupBonding *first);
+
+void cgroup_bonding_free(CGroupBonding *b, bool trim);
+void cgroup_bonding_free_list(CGroupBonding *first, bool trim);
+
+int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *suffix);
+int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *suffix);
+
+int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
+int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
+
+int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky);
+int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky);
+
+int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, bool rem, Set *s, const char *suffix);
+int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, bool rem, Set *s, const char *suffix);
+
+void cgroup_bonding_trim(CGroupBonding *first, bool delete_root);
+void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root);
+
+int cgroup_bonding_is_empty(CGroupBonding *b);
+int cgroup_bonding_is_empty_list(CGroupBonding *first);
+
+CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller);
+
+char *cgroup_bonding_to_string(CGroupBonding *b);
+
+pid_t cgroup_bonding_search_main_pid(CGroupBonding *b);
+pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *b);
+
+#include "manager.h"
+
+int manager_setup_cgroup(Manager *m);
+void manager_shutdown_cgroup(Manager *m, bool delete);
+
+int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding);
+int cgroup_notify_empty(Manager *m, const char *group);
+
+Unit* cgroup_unit_by_pid(Manager *m, pid_t pid);
diff --git a/src/core/condition.c b/src/core/condition.c
new file mode 100644 (file)
index 0000000..b318492
--- /dev/null
@@ -0,0 +1,384 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/capability.h>
+#include <sys/statvfs.h>
+#include <fnmatch.h>
+
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#include <systemd/sd-id128.h>
+#include "util.h"
+#include "condition.h"
+#include "virt.h"
+#include "path-util.h"
+
+Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
+        Condition *c;
+
+        assert(type < _CONDITION_TYPE_MAX);
+
+        c = new0(Condition, 1);
+        if (!c)
+                return NULL;
+
+        c->type = type;
+        c->trigger = trigger;
+        c->negate = negate;
+
+        if (parameter) {
+                c->parameter = strdup(parameter);
+                if (!c->parameter) {
+                        free(c);
+                        return NULL;
+                }
+        }
+
+        return c;
+}
+
+void condition_free(Condition *c) {
+        assert(c);
+
+        free(c->parameter);
+        free(c);
+}
+
+void condition_free_list(Condition *first) {
+        Condition *c, *n;
+
+        LIST_FOREACH_SAFE(conditions, c, n, first)
+                condition_free(c);
+}
+
+static bool test_kernel_command_line(const char *parameter) {
+        char *line, *w, *state, *word = NULL;
+        bool equal;
+        int r;
+        size_t l, pl;
+        bool found = false;
+
+        assert(parameter);
+
+        if (detect_container(NULL) > 0)
+                return false;
+
+        r = read_one_line_file("/proc/cmdline", &line);
+        if (r < 0) {
+                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return false;
+        }
+
+        equal = !!strchr(parameter, '=');
+        pl = strlen(parameter);
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+
+                free(word);
+                word = strndup(w, l);
+                if (!word)
+                        break;
+
+                if (equal) {
+                        if (streq(word, parameter)) {
+                                found = true;
+                                break;
+                        }
+                } else {
+                        if (startswith(word, parameter) && (word[pl] == '=' || word[pl] == 0)) {
+                                found = true;
+                                break;
+                        }
+                }
+
+        }
+
+        free(word);
+        free(line);
+
+        return found;
+}
+
+static bool test_virtualization(const char *parameter) {
+        int b;
+        Virtualization v;
+        const char *id;
+
+        assert(parameter);
+
+        v = detect_virtualization(&id);
+        if (v < 0) {
+                log_warning("Failed to detect virtualization, ignoring: %s", strerror(-v));
+                return false;
+        }
+
+        /* First, compare with yes/no */
+        b = parse_boolean(parameter);
+
+        if (v > 0 && b > 0)
+                return true;
+
+        if (v == 0 && b == 0)
+                return true;
+
+        /* Then, compare categorization */
+        if (v == VIRTUALIZATION_VM && streq(parameter, "vm"))
+                return true;
+
+        if (v == VIRTUALIZATION_CONTAINER && streq(parameter, "container"))
+                return true;
+
+        /* Finally compare id */
+        return v > 0 && streq(parameter, id);
+}
+
+static bool test_security(const char *parameter) {
+#ifdef HAVE_SELINUX
+        if (streq(parameter, "selinux"))
+                return is_selinux_enabled() > 0;
+#endif
+        return false;
+}
+
+static bool test_capability(const char *parameter) {
+        cap_value_t value;
+        FILE *f;
+        char line[LINE_MAX];
+        unsigned long long capabilities = (unsigned long long) -1;
+
+        /* If it's an invalid capability, we don't have it */
+
+        if (cap_from_name(parameter, &value) < 0)
+                return false;
+
+        /* If it's a valid capability we default to assume
+         * that we have it */
+
+        f = fopen("/proc/self/status", "re");
+        if (!f)
+                return true;
+
+        while (fgets(line, sizeof(line), f)) {
+                truncate_nl(line);
+
+                if (startswith(line, "CapBnd:")) {
+                        (void) sscanf(line+7, "%llx", &capabilities);
+                        break;
+                }
+        }
+
+        fclose(f);
+
+        return !!(capabilities & (1ULL << value));
+}
+
+static bool test_host(const char *parameter) {
+        sd_id128_t x, y;
+        char *h;
+        int r;
+        bool b;
+
+        if (sd_id128_from_string(parameter, &x) >= 0) {
+
+                r = sd_id128_get_machine(&y);
+                if (r < 0)
+                        return false;
+
+                return sd_id128_equal(x, y);
+        }
+
+        h = gethostname_malloc();
+        if (!h)
+                return false;
+
+        b = fnmatch(parameter, h, FNM_CASEFOLD) == 0;
+        free(h);
+
+        return b;
+}
+
+static bool test_ac_power(const char *parameter) {
+        int r;
+
+        r = parse_boolean(parameter);
+        if (r < 0)
+                return true;
+
+        return (on_ac_power() != 0) == !!r;
+}
+
+bool condition_test(Condition *c) {
+        assert(c);
+
+        switch(c->type) {
+
+        case CONDITION_PATH_EXISTS:
+                return (access(c->parameter, F_OK) >= 0) == !c->negate;
+
+        case CONDITION_PATH_EXISTS_GLOB:
+                return (glob_exists(c->parameter) > 0) == !c->negate;
+
+        case CONDITION_PATH_IS_DIRECTORY: {
+                struct stat st;
+
+                if (stat(c->parameter, &st) < 0)
+                        return c->negate;
+                return S_ISDIR(st.st_mode) == !c->negate;
+        }
+
+        case CONDITION_PATH_IS_SYMBOLIC_LINK: {
+                struct stat st;
+
+                if (lstat(c->parameter, &st) < 0)
+                        return c->negate;
+                return S_ISLNK(st.st_mode) == !c->negate;
+        }
+
+        case CONDITION_PATH_IS_MOUNT_POINT:
+                return (path_is_mount_point(c->parameter, true) > 0) == !c->negate;
+
+        case CONDITION_PATH_IS_READ_WRITE:
+                return (path_is_read_only_fs(c->parameter) > 0) == c->negate;
+
+        case CONDITION_DIRECTORY_NOT_EMPTY: {
+                int k;
+
+                k = dir_is_empty(c->parameter);
+                return !(k == -ENOENT || k > 0) == !c->negate;
+        }
+
+        case CONDITION_FILE_NOT_EMPTY: {
+                struct stat st;
+
+                if (stat(c->parameter, &st) < 0)
+                        return c->negate;
+
+                return (S_ISREG(st.st_mode) && st.st_size > 0) == !c->negate;
+        }
+
+        case CONDITION_FILE_IS_EXECUTABLE: {
+                struct stat st;
+
+                if (stat(c->parameter, &st) < 0)
+                        return c->negate;
+
+                return (S_ISREG(st.st_mode) && (st.st_mode & 0111)) == !c->negate;
+        }
+
+        case CONDITION_KERNEL_COMMAND_LINE:
+                return test_kernel_command_line(c->parameter) == !c->negate;
+
+        case CONDITION_VIRTUALIZATION:
+                return test_virtualization(c->parameter) == !c->negate;
+
+        case CONDITION_SECURITY:
+                return test_security(c->parameter) == !c->negate;
+
+        case CONDITION_CAPABILITY:
+                return test_capability(c->parameter) == !c->negate;
+
+        case CONDITION_HOST:
+                return test_host(c->parameter) == !c->negate;
+
+        case CONDITION_AC_POWER:
+                return test_ac_power(c->parameter) == !c->negate;
+
+        case CONDITION_NULL:
+                return !c->negate;
+
+        default:
+                assert_not_reached("Invalid condition type.");
+        }
+}
+
+bool condition_test_list(Condition *first) {
+        Condition *c;
+        int triggered = -1;
+
+        /* If the condition list is empty, then it is true */
+        if (!first)
+                return true;
+
+        /* Otherwise, if all of the non-trigger conditions apply and
+         * if any of the trigger conditions apply (unless there are
+         * none) we return true */
+        LIST_FOREACH(conditions, c, first) {
+                bool b;
+
+                b = condition_test(c);
+
+                if (!c->trigger && !b)
+                        return false;
+
+                if (c->trigger && triggered <= 0)
+                        triggered = b;
+        }
+
+        return triggered != 0;
+}
+
+void condition_dump(Condition *c, FILE *f, const char *prefix) {
+        assert(c);
+        assert(f);
+
+        if (!prefix)
+                prefix = "";
+
+        fprintf(f,
+                "%s\t%s: %s%s%s\n",
+                prefix,
+                condition_type_to_string(c->type),
+                c->trigger ? "|" : "",
+                c->negate ? "!" : "",
+                c->parameter);
+}
+
+void condition_dump_list(Condition *first, FILE *f, const char *prefix) {
+        Condition *c;
+
+        LIST_FOREACH(conditions, c, first)
+                condition_dump(c, f, prefix);
+}
+
+static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
+        [CONDITION_PATH_EXISTS] = "ConditionPathExists",
+        [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob",
+        [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory",
+        [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
+        [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
+        [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
+        [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
+        [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
+        [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
+        [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
+        [CONDITION_SECURITY] = "ConditionSecurity",
+        [CONDITION_HOST] = "ConditionHost",
+        [CONDITION_AC_POWER] = "ConditionACPower",
+        [CONDITION_NULL] = "ConditionNull"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);
diff --git a/src/core/condition.h b/src/core/condition.h
new file mode 100644 (file)
index 0000000..1797385
--- /dev/null
@@ -0,0 +1,70 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "list.h"
+
+typedef enum ConditionType {
+        CONDITION_PATH_EXISTS,
+        CONDITION_PATH_EXISTS_GLOB,
+        CONDITION_PATH_IS_DIRECTORY,
+        CONDITION_PATH_IS_SYMBOLIC_LINK,
+        CONDITION_PATH_IS_MOUNT_POINT,
+        CONDITION_PATH_IS_READ_WRITE,
+        CONDITION_DIRECTORY_NOT_EMPTY,
+        CONDITION_FILE_NOT_EMPTY,
+        CONDITION_FILE_IS_EXECUTABLE,
+        CONDITION_KERNEL_COMMAND_LINE,
+        CONDITION_VIRTUALIZATION,
+        CONDITION_SECURITY,
+        CONDITION_CAPABILITY,
+        CONDITION_HOST,
+        CONDITION_AC_POWER,
+        CONDITION_NULL,
+        _CONDITION_TYPE_MAX,
+        _CONDITION_TYPE_INVALID = -1
+} ConditionType;
+
+typedef struct Condition {
+        ConditionType type;
+        char *parameter;
+
+        bool trigger:1;
+        bool negate:1;
+
+        LIST_FIELDS(struct Condition, conditions);
+} Condition;
+
+Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate);
+void condition_free(Condition *c);
+void condition_free_list(Condition *c);
+
+bool condition_test(Condition *c);
+bool condition_test_list(Condition *c);
+
+void condition_dump(Condition *c, FILE *f, const char *prefix);
+void condition_dump_list(Condition *c, FILE *f, const char *prefix);
+
+const char* condition_type_to_string(ConditionType t);
+int condition_type_from_string(const char *s);
diff --git a/src/core/dbus-automount.c b/src/core/dbus-automount.c
new file mode 100644 (file)
index 0000000..060cbf7
--- /dev/null
@@ -0,0 +1,75 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus-unit.h"
+#include "dbus-automount.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_AUTOMOUNT_INTERFACE                                      \
+        " <interface name=\"org.freedesktop.systemd1.Automount\">\n" \
+        "  <property name=\"Where\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
+        " </interface>\n"
+
+#define INTROSPECTION                                                \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                    \
+        "<node>\n"                                                   \
+        BUS_UNIT_INTERFACE                                           \
+        BUS_AUTOMOUNT_INTERFACE                                      \
+        BUS_PROPERTIES_INTERFACE                                     \
+        BUS_PEER_INTERFACE                                           \
+        BUS_INTROSPECTABLE_INTERFACE                                 \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Automount\0"
+
+const char bus_automount_interface[] _introspect_("Automount") = BUS_AUTOMOUNT_INTERFACE;
+
+const char bus_automount_invalidating_properties[] =
+        "Result\0";
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_automount_append_automount_result, automount_result, AutomountResult);
+
+static const BusProperty bus_automount_properties[] = {
+        { "Where",         bus_property_append_string, "s", offsetof(Automount, where),    true },
+        { "DirectoryMode", bus_property_append_mode,   "u", offsetof(Automount, directory_mode) },
+        { "Result",        bus_automount_append_automount_result, "s", offsetof(Automount, result) },
+        { NULL, }
+};
+
+DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        Automount *am = AUTOMOUNT(u);
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",      bus_unit_properties,      u  },
+                { "org.freedesktop.systemd1.Automount", bus_automount_properties, am },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+}
diff --git a/src/core/dbus-automount.h b/src/core/dbus-automount.h
new file mode 100644 (file)
index 0000000..b338e25
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_automount_interface[];
+extern const char bus_automount_invalidating_properties[];
diff --git a/src/core/dbus-device.c b/src/core/dbus-device.c
new file mode 100644 (file)
index 0000000..dbd91fe
--- /dev/null
@@ -0,0 +1,68 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "dbus-unit.h"
+#include "dbus-device.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_DEVICE_INTERFACE                                            \
+        " <interface name=\"org.freedesktop.systemd1.Device\">\n"       \
+        "  <property name=\"SysFSPath\" type=\"s\" access=\"read\"/>\n" \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_DEVICE_INTERFACE                                            \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Device\0"
+
+const char bus_device_interface[] _introspect_("Device") = BUS_DEVICE_INTERFACE;
+
+const char bus_device_invalidating_properties[] =
+        "SysFSPath\0";
+
+static const BusProperty bus_device_properties[] = {
+        { "SysFSPath", bus_property_append_string, "s", offsetof(Device, sysfs), true },
+        { NULL, }
+};
+
+
+DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        Device *d = DEVICE(u);
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",   bus_unit_properties,   u },
+                { "org.freedesktop.systemd1.Device", bus_device_properties, d },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+}
diff --git a/src/core/dbus-device.h b/src/core/dbus-device.h
new file mode 100644 (file)
index 0000000..311e068
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_device_interface[];
+extern const char bus_device_invalidating_properties[];
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
new file mode 100644 (file)
index 0000000..e815cb5
--- /dev/null
@@ -0,0 +1,439 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <dbus/dbus.h>
+#include <sys/prctl.h>
+
+#include "dbus-execute.h"
+#include "missing.h"
+#include "ioprio.h"
+#include "strv.h"
+#include "dbus-common.h"
+#include "syscall-list.h"
+
+DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput);
+DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput);
+
+int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data) {
+        char **env_files = data, **j;
+        DBusMessageIter sub, sub2;
+
+        assert(i);
+        assert(property);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sb)", &sub))
+                return -ENOMEM;
+
+        STRV_FOREACH(j, env_files) {
+                dbus_bool_t b = false;
+                char *fn = *j;
+
+                if (fn[0] == '-') {
+                        b = true;
+                        fn++;
+                }
+
+                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &fn) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_BOOLEAN, &b) ||
+                    !dbus_message_iter_close_container(&sub, &sub2))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        int32_t n;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (c->oom_score_adjust_set)
+                n = c->oom_score_adjust;
+        else {
+                char *t;
+
+                n = 0;
+                if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0) {
+                        safe_atoi(t, &n);
+                        free(t);
+                }
+        }
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        int32_t n;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (c->nice_set)
+                n = c->nice;
+        else
+                n = getpriority(PRIO_PROCESS, 0);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        int32_t n;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (c->ioprio_set)
+                n = c->ioprio;
+        else
+                n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        int32_t n;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (c->cpu_sched_set)
+                n = c->cpu_sched_policy;
+        else
+                n = sched_getscheduler(0);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        int32_t n;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (c->cpu_sched_set)
+                n = c->cpu_sched_priority;
+        else {
+                struct sched_param p;
+                n = 0;
+
+                zero(p);
+                if (sched_getparam(0, &p) >= 0)
+                        n = p.sched_priority;
+        }
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        dbus_bool_t b;
+        DBusMessageIter sub;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub))
+                return -ENOMEM;
+
+        if (c->cpuset)
+                b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
+        else
+                b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, 0);
+
+        if (!b)
+                return -ENOMEM;
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        uint64_t u;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (c->timer_slack_nsec != (nsec_t) -1)
+                u = (uint64_t) c->timer_slack_nsec;
+        else
+                u = (uint64_t) prctl(PR_GET_TIMERSLACK);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        uint64_t normal, inverted;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        /* We store this negated internally, to match the kernel, but
+         * we expose it normalized. */
+
+        normal = *(uint64_t*) data;
+        inverted = ~normal;
+
+        return bus_property_append_uint64(i, property, &inverted);
+}
+
+int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        char *t = NULL;
+        const char *s;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (c->capabilities)
+                s = t = cap_to_text(c->capabilities, NULL);
+        else
+                s = "";
+
+        if (!s)
+                return -ENOMEM;
+
+        b = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &s);
+
+        if (t)
+                cap_free(t);
+
+        if (!b)
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        int r;
+        uint64_t u;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        assert_se((r = rlimit_from_string(property)) >= 0);
+
+        if (c->rlimit[r])
+                u = (uint64_t) c->rlimit[r]->rlim_max;
+        else {
+                struct rlimit rl;
+
+                zero(rl);
+                getrlimit(r, &rl);
+
+                u = (uint64_t) rl.rlim_max;
+        }
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_command(DBusMessageIter *i, const char *property, void *data) {
+        ExecCommand *c = data;
+        DBusMessageIter sub, sub2, sub3;
+
+        assert(i);
+        assert(property);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sasbttttuii)", &sub))
+                return -ENOMEM;
+
+        LIST_FOREACH(command, c, c) {
+                char **l;
+                uint32_t pid;
+                int32_t code, status;
+                dbus_bool_t b;
+
+                if (!c->path)
+                        continue;
+
+                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &c->path) ||
+                    !dbus_message_iter_open_container(&sub2, DBUS_TYPE_ARRAY, "s", &sub3))
+                        return -ENOMEM;
+
+                STRV_FOREACH(l, c->argv)
+                        if (!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, l))
+                                return -ENOMEM;
+
+                pid = (uint32_t) c->exec_status.pid;
+                code = (int32_t) c->exec_status.code;
+                status = (int32_t) c->exec_status.status;
+
+                b = !!c->ignore;
+
+                if (!dbus_message_iter_close_container(&sub2, &sub3) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_BOOLEAN, &b) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.realtime) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.monotonic) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.realtime) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.monotonic) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &pid) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &code) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &status))
+                        return -ENOMEM;
+
+                if (!dbus_message_iter_close_container(&sub, &sub2))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data) {
+        ExecContext *c = data;
+        dbus_bool_t b;
+        DBusMessageIter sub;
+
+        assert(i);
+        assert(property);
+        assert(c);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "u", &sub))
+                return -ENOMEM;
+
+        if (c->syscall_filter)
+                b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_UINT32, &c->syscall_filter, (syscall_max() + 31) >> 4);
+        else
+                b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_UINT32, &c->syscall_filter, 0);
+
+        if (!b)
+                return -ENOMEM;
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+const BusProperty bus_exec_context_properties[] = {
+        { "Environment",              bus_property_append_strv,             "as", offsetof(ExecContext, environment),            true },
+        { "EnvironmentFiles",         bus_execute_append_env_files,      "a(sb)", offsetof(ExecContext, environment_files),      true },
+        { "UMask",                    bus_property_append_mode,              "u", offsetof(ExecContext, umask)                        },
+        { "LimitCPU",                 bus_execute_append_rlimits,            "t", 0 },
+        { "LimitFSIZE",               bus_execute_append_rlimits,            "t", 0 },
+        { "LimitDATA",                bus_execute_append_rlimits,            "t", 0 },
+        { "LimitSTACK",               bus_execute_append_rlimits,            "t", 0 },
+        { "LimitCORE",                bus_execute_append_rlimits,            "t", 0 },
+        { "LimitRSS",                 bus_execute_append_rlimits,            "t", 0 },
+        { "LimitNOFILE",              bus_execute_append_rlimits,            "t", 0 },
+        { "LimitAS",                  bus_execute_append_rlimits,            "t", 0 },
+        { "LimitNPROC",               bus_execute_append_rlimits,            "t", 0 },
+        { "LimitMEMLOCK",             bus_execute_append_rlimits,            "t", 0 },
+        { "LimitLOCKS",               bus_execute_append_rlimits,            "t", 0 },
+        { "LimitSIGPENDING",          bus_execute_append_rlimits,            "t", 0 },
+        { "LimitMSGQUEUE",            bus_execute_append_rlimits,            "t", 0 },
+        { "LimitNICE",                bus_execute_append_rlimits,            "t", 0 },
+        { "LimitRTPRIO",              bus_execute_append_rlimits,            "t", 0 },
+        { "LimitRTTIME",              bus_execute_append_rlimits,            "t", 0 },
+        { "WorkingDirectory",         bus_property_append_string,            "s", offsetof(ExecContext, working_directory),      true },
+        { "RootDirectory",            bus_property_append_string,            "s", offsetof(ExecContext, root_directory),         true },
+        { "OOMScoreAdjust",           bus_execute_append_oom_score_adjust,   "i", 0 },
+        { "Nice",                     bus_execute_append_nice,               "i", 0 },
+        { "IOScheduling",             bus_execute_append_ioprio,             "i", 0 },
+        { "CPUSchedulingPolicy",      bus_execute_append_cpu_sched_policy,   "i", 0 },
+        { "CPUSchedulingPriority",    bus_execute_append_cpu_sched_priority, "i", 0 },
+        { "CPUAffinity",              bus_execute_append_affinity,          "ay", 0 },
+        { "TimerSlackNSec",           bus_execute_append_timer_slack_nsec,   "t", 0 },
+        { "CPUSchedulingResetOnFork", bus_property_append_bool,              "b", offsetof(ExecContext, cpu_sched_reset_on_fork)      },
+        { "NonBlocking",              bus_property_append_bool,              "b", offsetof(ExecContext, non_blocking)                 },
+        { "StandardInput",            bus_execute_append_input,              "s", offsetof(ExecContext, std_input)                    },
+        { "StandardOutput",           bus_execute_append_output,             "s", offsetof(ExecContext, std_output)                   },
+        { "StandardError",            bus_execute_append_output,             "s", offsetof(ExecContext, std_error)                    },
+        { "TTYPath",                  bus_property_append_string,            "s", offsetof(ExecContext, tty_path),               true },
+        { "TTYReset",                 bus_property_append_bool,              "b", offsetof(ExecContext, tty_reset)                    },
+        { "TTYVHangup",               bus_property_append_bool,              "b", offsetof(ExecContext, tty_vhangup)                  },
+        { "TTYVTDisallocate",         bus_property_append_bool,              "b", offsetof(ExecContext, tty_vt_disallocate)           },
+        { "SyslogPriority",           bus_property_append_int,               "i", offsetof(ExecContext, syslog_priority)              },
+        { "SyslogIdentifier",         bus_property_append_string,            "s", offsetof(ExecContext, syslog_identifier),      true },
+        { "SyslogLevelPrefix",        bus_property_append_bool,              "b", offsetof(ExecContext, syslog_level_prefix)          },
+        { "Capabilities",             bus_execute_append_capabilities,       "s", 0 },
+        { "SecureBits",               bus_property_append_int,               "i", offsetof(ExecContext, secure_bits)                  },
+        { "CapabilityBoundingSet",    bus_execute_append_capability_bs,      "t", offsetof(ExecContext, capability_bounding_set_drop) },
+        { "User",                     bus_property_append_string,            "s", offsetof(ExecContext, user),                   true },
+        { "Group",                    bus_property_append_string,            "s", offsetof(ExecContext, group),                  true },
+        { "SupplementaryGroups",      bus_property_append_strv,             "as", offsetof(ExecContext, supplementary_groups),   true },
+        { "TCPWrapName",              bus_property_append_string,            "s", offsetof(ExecContext, tcpwrap_name),           true },
+        { "PAMName",                  bus_property_append_string,            "s", offsetof(ExecContext, pam_name),               true },
+        { "ReadWriteDirectories",     bus_property_append_strv,             "as", offsetof(ExecContext, read_write_dirs),        true },
+        { "ReadOnlyDirectories",      bus_property_append_strv,             "as", offsetof(ExecContext, read_only_dirs),         true },
+        { "InaccessibleDirectories",  bus_property_append_strv,             "as", offsetof(ExecContext, inaccessible_dirs),      true },
+        { "MountFlags",               bus_property_append_ul,                "t", offsetof(ExecContext, mount_flags)                  },
+        { "PrivateTmp",               bus_property_append_bool,              "b", offsetof(ExecContext, private_tmp)                  },
+        { "PrivateNetwork",           bus_property_append_bool,              "b", offsetof(ExecContext, private_network)              },
+        { "SameProcessGroup",         bus_property_append_bool,              "b", offsetof(ExecContext, same_pgrp)                    },
+        { "UtmpIdentifier",           bus_property_append_string,            "s", offsetof(ExecContext, utmp_id),                true },
+        { "ControlGroupModify",       bus_property_append_bool,              "b", offsetof(ExecContext, control_group_modify)         },
+        { "ControlGroupPersistent",   bus_property_append_tristate_false,    "b", offsetof(ExecContext, control_group_persistent)     },
+        { "IgnoreSIGPIPE",            bus_property_append_bool,              "b", offsetof(ExecContext, ignore_sigpipe)               },
+        { "NoNewPrivileges",          bus_property_append_bool,              "b", offsetof(ExecContext, no_new_privileges)            },
+        { "SystemCallFilter",         bus_execute_append_syscall_filter,    "au", 0                                                   },
+        { NULL, }
+};
diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h
new file mode 100644 (file)
index 0000000..eaa1b73
--- /dev/null
@@ -0,0 +1,124 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "manager.h"
+#include "dbus-common.h"
+
+#define BUS_EXEC_STATUS_INTERFACE(prefix)                               \
+        "  <property name=\"" prefix "StartTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"" prefix "StartTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"" prefix "ExitTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"" prefix "ExitTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"" prefix "PID\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"" prefix "Code\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"" prefix "Status\" type=\"i\" access=\"read\"/>\n"
+
+#define BUS_EXEC_CONTEXT_INTERFACE                                      \
+        "  <property name=\"Environment\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"UMask\" type=\"u\" access=\"read\"/>\n"     \
+        "  <property name=\"LimitCPU\" type=\"t\" access=\"read\"/>\n"  \
+        "  <property name=\"LimitFSIZE\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitDATA\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitSTACK\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitCORE\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitRSS\" type=\"t\" access=\"read\"/>\n"  \
+        "  <property name=\"LimitNOFILE\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitAS\" type=\"t\" access=\"read\"/>\n"   \
+        "  <property name=\"LimitNPROC\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitMEMLOCK\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitLOCKS\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitSIGPENDING\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitMSGQUEUE\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitNICE\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitRTPRIO\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LimitRTTIME\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"WorkingDirectory\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"RootDirectory\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"OOMScoreAdjust\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"Nice\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"IOScheduling\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"CPUSchedulingPolicy\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"CPUSchedulingPriority\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"CPUAffinity\" type=\"ay\" access=\"read\"/>\n" \
+        "  <property name=\"TimerSlackNS\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"CPUSchedulingResetOnFork\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"NonBlocking\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"StandardInput\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"StandardOutput\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"StandardError\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"TTYPath\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"TTYReset\" type=\"b\" access=\"read\"/>\n"   \
+        "  <property name=\"TTYVHangup\" type=\"b\" access=\"read\"/>\n"   \
+        "  <property name=\"TTYVTDisallocate\" type=\"b\" access=\"read\"/>\n"   \
+        "  <property name=\"SyslogPriority\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"SyslogIdentifier\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"SyslogLevelPrefix\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"Capabilities\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"SecureBits\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"CapabilityBoundingSet\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"User\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Group\" type=\"s\" access=\"read\"/>\n"     \
+        "  <property name=\"SupplementaryGroups\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"TCPWrapName\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"PAMName\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"ReadWriteDirectories\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"ReadOnlyDirectories\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"InaccessibleDirectories\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"MountFlags\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"PrivateTmp\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"SameProcessGroup\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"KillSignal\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"UtmpIdentifier\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"ControlGroupModify\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"ControlGroupPersistent\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"PrivateNetwork\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"IgnoreSIGPIPE\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"NoNewPrivileges\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"SystemCallFilter\" type=\"au\" access=\"read\"/>\n"
+
+#define BUS_EXEC_COMMAND_INTERFACE(name)                             \
+        "  <property name=\"" name "\" type=\"a(sasbttuii)\" access=\"read\"/>\n"
+
+extern const BusProperty bus_exec_context_properties[];
+
+#define BUS_EXEC_COMMAND_PROPERTY(name, command, indirect)             \
+        { name, bus_execute_append_command, "a(sasbttttuii)", (command), (indirect), NULL }
+
+int bus_execute_append_output(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_input(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_command(DBusMessageIter *u, const char *property, void *data);
+int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data);
diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c
new file mode 100644 (file)
index 0000000..fdc1dce
--- /dev/null
@@ -0,0 +1,378 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus.h"
+#include "log.h"
+#include "dbus-job.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_JOB_INTERFACE                                             \
+        " <interface name=\"org.freedesktop.systemd1.Job\">\n"        \
+        "  <method name=\"Cancel\"/>\n"                               \
+        "  <property name=\"Id\" type=\"u\" access=\"read\"/>\n"      \
+        "  <property name=\"Unit\" type=\"(so)\" access=\"read\"/>\n" \
+        "  <property name=\"JobType\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"State\" type=\"s\" access=\"read\"/>\n"   \
+        " </interface>\n"
+
+#define INTROSPECTION                                                 \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                     \
+        "<node>\n"                                                    \
+        BUS_JOB_INTERFACE                                             \
+        BUS_PROPERTIES_INTERFACE                                      \
+        BUS_PEER_INTERFACE                                            \
+        BUS_INTROSPECTABLE_INTERFACE                                  \
+        "</node>\n"
+
+const char bus_job_interface[] _introspect_("Job") = BUS_JOB_INTERFACE;
+
+#define INTERFACES_LIST                              \
+        BUS_GENERIC_INTERFACES_LIST                  \
+        "org.freedesktop.systemd1.Job\0"
+
+#define INVALIDATING_PROPERTIES                 \
+        "State\0"
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_state, job_state, JobState);
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_type, job_type, JobType);
+
+static int bus_job_append_unit(DBusMessageIter *i, const char *property, void *data) {
+        Job *j = data;
+        DBusMessageIter sub;
+        char *p;
+
+        assert(i);
+        assert(property);
+        assert(j);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
+                return -ENOMEM;
+
+        p = unit_dbus_path(j->unit);
+        if (!p)
+                return -ENOMEM;
+
+        if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &j->unit->id) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) {
+                free(p);
+                return -ENOMEM;
+        }
+
+        free(p);
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static const BusProperty bus_job_properties[] = {
+        { "Id",      bus_property_append_uint32, "u", offsetof(Job, id)    },
+        { "State",   bus_job_append_state,       "s", offsetof(Job, state) },
+        { "JobType", bus_job_append_type,        "s", offsetof(Job, type)  },
+        { "Unit",    bus_job_append_unit,     "(so)", 0 },
+        { NULL, }
+};
+
+static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connection, DBusMessage *message) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Job", "Cancel")) {
+
+                SELINUX_UNIT_ACCESS_CHECK(j->unit, connection, message, "stop");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+                job_finish_and_invalidate(j, JOB_CANCELED, true);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.systemd1.Job", bus_job_properties, j },
+                        { NULL, }
+                };
+
+                SELINUX_UNIT_ACCESS_CHECK(j->unit, connection, message, "status");
+
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
+
+        if (!dbus_connection_send(connection, reply, NULL))
+                return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBusMessage  *message, void *data) {
+        Manager *m = data;
+        Job *j;
+        int r;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+
+        assert(connection);
+        assert(message);
+        assert(m);
+
+        if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/job")) {
+                /* Be nice to gdbus and return introspection data for our mid-level paths */
+
+                if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+                        char *introspection = NULL;
+                        FILE *f;
+                        Iterator i;
+                        size_t size;
+
+                        SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                        reply = dbus_message_new_method_return(message);
+                        if (!reply)
+                                goto oom;
+
+                        /* We roll our own introspection code here, instead of
+                         * relying on bus_default_message_handler() because we
+                         * need to generate our introspection string
+                         * dynamically. */
+
+                        f = open_memstream(&introspection, &size);
+                        if (!f)
+                                goto oom;
+
+                        fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+                              "<node>\n", f);
+
+                        fputs(BUS_INTROSPECTABLE_INTERFACE, f);
+                        fputs(BUS_PEER_INTERFACE, f);
+
+                        HASHMAP_FOREACH(j, m->jobs, i)
+                                fprintf(f, "<node name=\"job/%lu\"/>", (unsigned long) j->id);
+
+                        fputs("</node>\n", f);
+
+                        if (ferror(f)) {
+                                fclose(f);
+                                free(introspection);
+                                goto oom;
+                        }
+
+                        fclose(f);
+
+                        if (!introspection)
+                                goto oom;
+
+                        if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
+                                free(introspection);
+                                goto oom;
+                        }
+
+                        free(introspection);
+
+                        if (!dbus_connection_send(connection, reply, NULL))
+                                goto oom;
+
+                        return DBUS_HANDLER_RESULT_HANDLED;
+                }
+
+                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        }
+
+        r = manager_get_job_from_dbus_path(m, dbus_message_get_path(message), &j);
+        if (r == -ENOMEM)
+                goto oom;
+        if (r == -ENOENT) {
+                DBusError e;
+
+                dbus_error_init(&e);
+                dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown job");
+                return bus_send_error_reply(connection, message, &e, r);
+        }
+        if (r < 0)
+                return bus_send_error_reply(connection, message, NULL, r);
+
+        return bus_job_message_dispatch(j, connection, message);
+
+oom:
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+const DBusObjectPathVTable bus_job_vtable = {
+        .message_function = bus_job_message_handler
+};
+
+static int job_send_message(Job *j, DBusMessage* (*new_message)(Job *j)) {
+        DBusMessage *m = NULL;
+        int r;
+
+        assert(j);
+        assert(new_message);
+
+        if (bus_has_subscriber(j->manager) || j->forgot_bus_clients) {
+                m = new_message(j);
+                if (!m)
+                        goto oom;
+                r = bus_broadcast(j->manager, m);
+                dbus_message_unref(m);
+                if (r < 0)
+                        return r;
+
+        } else {
+                /* If nobody is subscribed, we just send the message
+                 * to the client(s) which created the job */
+                JobBusClient *cl;
+                assert(j->bus_client_list);
+                LIST_FOREACH(client, cl, j->bus_client_list) {
+                        assert(cl->bus);
+
+                        m = new_message(j);
+                        if (!m)
+                                goto oom;
+
+                        if (!dbus_message_set_destination(m, cl->name))
+                                goto oom;
+
+                        if (!dbus_connection_send(cl->bus, m, NULL))
+                                goto oom;
+
+                        dbus_message_unref(m);
+                        m = NULL;
+                }
+        }
+
+        return 0;
+oom:
+        if (m)
+                dbus_message_unref(m);
+        return -ENOMEM;
+}
+
+static DBusMessage* new_change_signal_message(Job *j) {
+        DBusMessage *m = NULL;
+        char *p = NULL;
+
+        p = job_dbus_path(j);
+        if (!p)
+                goto oom;
+
+        if (j->sent_dbus_new_signal) {
+                /* Send a properties changed signal */
+                m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Job", INVALIDATING_PROPERTIES);
+                if (!m)
+                        goto oom;
+
+        } else {
+                /* Send a new signal */
+
+                m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobNew");
+                if (!m)
+                        goto oom;
+
+                if (!dbus_message_append_args(m,
+                                              DBUS_TYPE_UINT32, &j->id,
+                                              DBUS_TYPE_OBJECT_PATH, &p,
+                                              DBUS_TYPE_STRING, &j->unit->id,
+                                              DBUS_TYPE_INVALID))
+                        goto oom;
+        }
+
+        return m;
+
+oom:
+        if (m)
+                dbus_message_unref(m);
+        free(p);
+        return NULL;
+}
+
+static DBusMessage* new_removed_signal_message(Job *j) {
+        DBusMessage *m = NULL;
+        char *p = NULL;
+        const char *r;
+
+        p = job_dbus_path(j);
+        if (!p)
+                goto oom;
+
+        m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobRemoved");
+        if (!m)
+                goto oom;
+
+        r = job_result_to_string(j->result);
+
+        if (!dbus_message_append_args(m,
+                                      DBUS_TYPE_UINT32, &j->id,
+                                      DBUS_TYPE_OBJECT_PATH, &p,
+                                      DBUS_TYPE_STRING, &j->unit->id,
+                                      DBUS_TYPE_STRING, &r,
+                                      DBUS_TYPE_INVALID))
+                goto oom;
+
+        return m;
+
+oom:
+        if (m)
+                dbus_message_unref(m);
+        free(p);
+        return NULL;
+}
+
+void bus_job_send_change_signal(Job *j) {
+        assert(j);
+
+        if (j->in_dbus_queue) {
+                LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
+                j->in_dbus_queue = false;
+        }
+
+        if (!bus_has_subscriber(j->manager) && !j->bus_client_list && !j->forgot_bus_clients) {
+                j->sent_dbus_new_signal = true;
+                return;
+        }
+
+        if (job_send_message(j, new_change_signal_message) < 0)
+                goto oom;
+
+        j->sent_dbus_new_signal = true;
+
+        return;
+
+oom:
+        log_error("Failed to allocate job change signal.");
+}
+
+void bus_job_send_removed_signal(Job *j) {
+        assert(j);
+
+        if (!bus_has_subscriber(j->manager) && !j->bus_client_list && !j->forgot_bus_clients)
+                return;
+
+        if (!j->sent_dbus_new_signal)
+                bus_job_send_change_signal(j);
+
+        if (job_send_message(j, new_removed_signal_message) < 0)
+                goto oom;
+
+        return;
+
+oom:
+        log_error("Failed to allocate job remove signal.");
+}
diff --git a/src/core/dbus-job.h b/src/core/dbus-job.h
new file mode 100644 (file)
index 0000000..a1b928f
--- /dev/null
@@ -0,0 +1,33 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "job.h"
+
+void bus_job_send_change_signal(Job *j);
+void bus_job_send_removed_signal(Job *j);
+
+extern const DBusObjectPathVTable bus_job_vtable;
+
+extern const char bus_job_interface[];
diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c
new file mode 100644 (file)
index 0000000..165f630
--- /dev/null
@@ -0,0 +1,35 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <dbus/dbus.h>
+
+#include "dbus-kill.h"
+#include "dbus-common.h"
+
+DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_kill_append_mode, kill_mode, KillMode);
+
+const BusProperty bus_kill_context_properties[] = {
+        { "KillMode",    bus_kill_append_mode,     "s", offsetof(KillContext, kill_mode)    },
+        { "KillSignal",  bus_property_append_int,  "i", offsetof(KillContext, kill_signal)  },
+        { "SendSIGKILL", bus_property_append_bool, "b", offsetof(KillContext, send_sigkill) },
+        { NULL, }
+};
diff --git a/src/core/dbus-kill.h b/src/core/dbus-kill.h
new file mode 100644 (file)
index 0000000..238fbd3
--- /dev/null
@@ -0,0 +1,39 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "manager.h"
+#include "dbus-common.h"
+
+#define BUS_KILL_CONTEXT_INTERFACE                                      \
+        "  <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"KillSignal\" type=\"i\" access=\"read\"/>\n" \
+        "  <property name=\"SendSIGKILL\" type=\"b\" access=\"read\"/>\n"
+
+#define BUS_KILL_COMMAND_INTERFACE(name)                                \
+        "  <property name=\"" name "\" type=\"a(sasbttuii)\" access=\"read\"/>\n"
+
+extern const BusProperty bus_kill_context_properties[];
+
+int bus_kill_append_mode(DBusMessageIter *i, const char *property, void *data);
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
new file mode 100644 (file)
index 0000000..859fa1a
--- /dev/null
@@ -0,0 +1,1684 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "dbus.h"
+#include "log.h"
+#include "dbus-manager.h"
+#include "strv.h"
+#include "bus-errors.h"
+#include "build.h"
+#include "dbus-common.h"
+#include "install.h"
+#include "selinux-access.h"
+#include "watchdog.h"
+#include "hwclock.h"
+#include "path-util.h"
+#include "dbus-unit.h"
+#include "virt.h"
+
+#define BUS_MANAGER_INTERFACE_BEGIN                                     \
+        " <interface name=\"org.freedesktop.systemd1.Manager\">\n"
+
+#define BUS_MANAGER_INTERFACE_METHODS                                   \
+        "  <method name=\"GetUnit\">\n"                                 \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"unit\" type=\"o\" direction=\"out\"/>\n"        \
+        "  </method>\n"                                                 \
+        "  <method name=\"GetUnitByPID\">\n"                            \
+        "   <arg name=\"pid\" type=\"u\" direction=\"in\"/>\n"          \
+        "   <arg name=\"unit\" type=\"o\" direction=\"out\"/>\n"        \
+        "  </method>\n"                                                 \
+        "  <method name=\"LoadUnit\">\n"                                \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"unit\" type=\"o\" direction=\"out\"/>\n"        \
+        "  </method>\n"                                                 \
+        "  <method name=\"StartUnit\">\n"                               \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"StartUnitReplace\">\n"                        \
+        "   <arg name=\"old_unit\" type=\"s\" direction=\"in\"/>\n"     \
+        "   <arg name=\"new_unit\" type=\"s\" direction=\"in\"/>\n"     \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"StopUnit\">\n"                                \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReloadUnit\">\n"                              \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"RestartUnit\">\n"                             \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"TryRestartUnit\">\n"                          \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReloadOrRestartUnit\">\n"                     \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReloadOrTryRestartUnit\">\n"                  \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"KillUnit\">\n"                                \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"who\" type=\"s\" direction=\"in\"/>\n"          \
+        "   <arg name=\"signal\" type=\"i\" direction=\"in\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"ResetFailedUnit\">\n"                         \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"GetJob\">\n"                                  \
+        "   <arg name=\"id\" type=\"u\" direction=\"in\"/>\n"           \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ClearJobs\"/>\n"                              \
+        "  <method name=\"ResetFailed\"/>\n"                            \
+        "  <method name=\"ListUnits\">\n"                               \
+        "   <arg name=\"units\" type=\"a(ssssssouso)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"ListJobs\">\n"                                \
+        "   <arg name=\"jobs\" type=\"a(usssoo)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"Subscribe\"/>\n"                              \
+        "  <method name=\"Unsubscribe\"/>\n"                            \
+        "  <method name=\"Dump\">\n"                                    \
+        "   <arg name=\"dump\" type=\"s\" direction=\"out\"/>\n"        \
+        "  </method>\n"                                                 \
+        "  <method name=\"CreateSnapshot\">\n"                          \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"cleanup\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"unit\" type=\"o\" direction=\"out\"/>\n"        \
+        "  </method>\n"                                                 \
+        "  <method name=\"Reload\"/>\n"                                 \
+        "  <method name=\"Reexecute\"/>\n"                              \
+        "  <method name=\"Exit\"/>\n"                                   \
+        "  <method name=\"Reboot\"/>\n"                                 \
+        "  <method name=\"PowerOff\"/>\n"                               \
+        "  <method name=\"Halt\"/>\n"                                   \
+        "  <method name=\"KExec\"/>\n"                                  \
+        "  <method name=\"SwitchRoot\">\n"                              \
+        "   <arg name=\"new_root\" type=\"s\" direction=\"in\"/>\n"     \
+        "   <arg name=\"init\" type=\"s\" direction=\"in\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetEnvironment\">\n"                          \
+        "   <arg name=\"names\" type=\"as\" direction=\"in\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"UnsetEnvironment\">\n"                        \
+        "   <arg name=\"names\" type=\"as\" direction=\"in\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"UnsetAndSetEnvironment\">\n"                  \
+        "   <arg name=\"unset\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"set\" type=\"as\" direction=\"in\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ListUnitFiles\">\n"                            \
+        "   <arg name=\"files\" type=\"a(ss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"GetUnitFileState\">\n"                        \
+        "   <arg name=\"file\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"state\" type=\"s\" direction=\"out\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"EnableUnitFiles\">\n"                         \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"carries_install_info\" type=\"b\" direction=\"out\"/>\n" \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"DisableUnitFiles\">\n"                        \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReenableUnitFiles\">\n"                       \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"carries_install_info\" type=\"b\" direction=\"out\"/>\n" \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"LinkUnitFiles\">\n"                           \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"PresetUnitFiles\">\n"                         \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"carries_install_info\" type=\"b\" direction=\"out\"/>\n" \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"MaskUnitFiles\">\n"                           \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"UnmaskUnitFiles\">\n"                         \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"
+
+#define BUS_MANAGER_INTERFACE_SIGNALS                                   \
+        "  <signal name=\"UnitNew\">\n"                                 \
+        "   <arg name=\"id\" type=\"s\"/>\n"                            \
+        "   <arg name=\"unit\" type=\"o\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"UnitRemoved\">\n"                             \
+        "   <arg name=\"id\" type=\"s\"/>\n"                            \
+        "   <arg name=\"unit\" type=\"o\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"JobNew\">\n"                                  \
+        "   <arg name=\"id\" type=\"u\"/>\n"                            \
+        "   <arg name=\"job\" type=\"o\"/>\n"                           \
+        "   <arg name=\"unit\" type=\"s\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"JobRemoved\">\n"                              \
+        "   <arg name=\"id\" type=\"u\"/>\n"                            \
+        "   <arg name=\"job\" type=\"o\"/>\n"                           \
+        "   <arg name=\"unit\" type=\"s\"/>\n"                          \
+        "   <arg name=\"result\" type=\"s\"/>\n"                        \
+        "  </signal>"                                                   \
+        "  <signal name=\"StartupFinished\">\n"                         \
+        "   <arg name=\"firmware\" type=\"t\"/>\n"                      \
+        "   <arg name=\"loader\" type=\"t\"/>\n"                        \
+        "   <arg name=\"kernel\" type=\"t\"/>\n"                        \
+        "   <arg name=\"initrd\" type=\"t\"/>\n"                        \
+        "   <arg name=\"userspace\" type=\"t\"/>\n"                     \
+        "   <arg name=\"total\" type=\"t\"/>\n"                         \
+        "  </signal>"                                                   \
+        "  <signal name=\"UnitFilesChanged\"/>\n"
+
+#define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL                        \
+        "  <property name=\"Version\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"Features\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"Tainted\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"FirmwareTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"FirmwareTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LoaderTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LoaderTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"KernelTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"KernelTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"InitRDTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"InitRDTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"UserspaceTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"UserspaceTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"FinishTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"FinishTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"LogLevel\" type=\"s\" access=\"readwrite\"/>\n"  \
+        "  <property name=\"LogTarget\" type=\"s\" access=\"readwrite\"/>\n" \
+        "  <property name=\"NNames\" type=\"u\" access=\"read\"/>\n"    \
+        "  <property name=\"NJobs\" type=\"u\" access=\"read\"/>\n"     \
+        "  <property name=\"NInstalledJobs\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"NFailedJobs\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"Progress\" type=\"d\" access=\"read\"/>\n"  \
+        "  <property name=\"Environment\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"ConfirmSpawn\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"ShowStatus\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"UnitPath\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"ControlGroupHierarchy\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"DefaultControllers\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"DefaultStandardOutput\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"DefaultStandardError\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"RuntimeWatchdogUSec\" type=\"s\" access=\"readwrite\"/>\n" \
+        "  <property name=\"ShutdownWatchdogUSec\" type=\"s\" access=\"readwrite\"/>\n" \
+        "  <property name=\"Virtualization\" type=\"s\" access=\"read\"/>\n"
+
+#define BUS_MANAGER_INTERFACE_END                                       \
+        " </interface>\n"
+
+#define BUS_MANAGER_INTERFACE                                           \
+        BUS_MANAGER_INTERFACE_BEGIN                                     \
+        BUS_MANAGER_INTERFACE_METHODS                                   \
+        BUS_MANAGER_INTERFACE_SIGNALS                                   \
+        BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL                        \
+        BUS_MANAGER_INTERFACE_END
+
+#define INTROSPECTION_BEGIN                                             \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_MANAGER_INTERFACE                                           \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE
+
+#define INTROSPECTION_END                                               \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_GENERIC_INTERFACES_LIST                  \
+        "org.freedesktop.systemd1.Manager\0"
+
+const char bus_manager_interface[] _introspect_("Manager") = BUS_MANAGER_INTERFACE;
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_exec_output, exec_output, ExecOutput);
+
+static int bus_manager_append_tainted(DBusMessageIter *i, const char *property, void *data) {
+        const char *t;
+        Manager *m = data;
+        char buf[LINE_MAX] = "", *e = buf, *p = NULL;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        if (m->taint_usr)
+                e = stpcpy(e, "split-usr:");
+
+        if (readlink_malloc("/etc/mtab", &p) < 0)
+                e = stpcpy(e, "mtab-not-symlink:");
+        else
+                free(p);
+
+        if (access("/proc/cgroups", F_OK) < 0)
+                e = stpcpy(e, "cgroups-missing:");
+
+        if (hwclock_is_localtime() > 0)
+                e = stpcpy(e, "local-hwclock:");
+
+        /* remove the last ':' */
+        if (e != buf)
+                e[-1] = 0;
+
+        t = buf;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_manager_append_log_target(DBusMessageIter *i, const char *property, void *data) {
+        const char *t;
+
+        assert(i);
+        assert(property);
+
+        t = log_target_to_string(log_get_target());
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_manager_set_log_target(DBusMessageIter *i, const char *property, void *data) {
+        const char *t;
+
+        assert(i);
+        assert(property);
+
+        dbus_message_iter_get_basic(i, &t);
+
+        return log_set_target_from_string(t);
+}
+
+static int bus_manager_append_log_level(DBusMessageIter *i, const char *property, void *data) {
+        char *t;
+        int r;
+
+        assert(i);
+        assert(property);
+
+        r = log_level_to_string_alloc(log_get_max_level(), &t);
+        if (r < 0)
+                return r;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t))
+                r = -ENOMEM;
+
+        free(t);
+        return r;
+}
+
+static int bus_manager_set_log_level(DBusMessageIter *i, const char *property, void *data) {
+        const char *t;
+
+        assert(i);
+        assert(property);
+
+        dbus_message_iter_get_basic(i, &t);
+
+        return log_set_max_level_from_string(t);
+}
+
+static int bus_manager_append_n_names(DBusMessageIter *i, const char *property, void *data) {
+        Manager *m = data;
+        uint32_t u;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        u = hashmap_size(m->units);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &u))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_manager_append_n_jobs(DBusMessageIter *i, const char *property, void *data) {
+        Manager *m = data;
+        uint32_t u;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        u = hashmap_size(m->jobs);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &u))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_manager_append_progress(DBusMessageIter *i, const char *property, void *data) {
+        double d;
+        Manager *m = data;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        if (dual_timestamp_is_set(&m->finish_timestamp))
+                d = 1.0;
+        else
+                d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_DOUBLE, &d))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_manager_append_virt(DBusMessageIter *i, const char *property, void *data) {
+        Manager *m = data;
+        const char *id = "";
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        detect_virtualization(&id);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &id))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static DBusMessage *message_from_file_changes(
+                DBusMessage *m,
+                UnitFileChange *changes,
+                unsigned n_changes,
+                int carries_install_info) {
+
+        DBusMessageIter iter, sub, sub2;
+        DBusMessage *reply;
+        unsigned i;
+
+        reply = dbus_message_new_method_return(m);
+        if (!reply)
+                return NULL;
+
+        dbus_message_iter_init_append(reply, &iter);
+
+        if (carries_install_info >= 0) {
+                dbus_bool_t b;
+
+                b = !!carries_install_info;
+                if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b))
+                        goto oom;
+        }
+
+        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sss)", &sub))
+                goto oom;
+
+        for (i = 0; i < n_changes; i++) {
+                const char *type, *path, *source;
+
+                type = unit_file_change_type_to_string(changes[i].type);
+                path = strempty(changes[i].path);
+                source = strempty(changes[i].source);
+
+                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &type) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &path) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &source) ||
+                    !dbus_message_iter_close_container(&sub, &sub2))
+                        goto oom;
+        }
+
+        if (!dbus_message_iter_close_container(&iter, &sub))
+                goto oom;
+
+        return reply;
+
+oom:
+        dbus_message_unref(reply);
+        return NULL;
+}
+
+static int bus_manager_send_unit_files_changed(Manager *m) {
+        DBusMessage *s;
+        int r;
+
+        s = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
+        if (!s)
+                return -ENOMEM;
+
+        r = bus_broadcast(m, s);
+        dbus_message_unref(s);
+
+        return r;
+}
+
+static int bus_manager_set_runtime_watchdog_usec(DBusMessageIter *i, const char *property, void *data) {
+        uint64_t *t = data;
+
+        assert(i);
+        assert(property);
+
+        dbus_message_iter_get_basic(i, t);
+
+        return watchdog_set_timeout(t);
+}
+
+static const char systemd_property_string[] =
+        PACKAGE_STRING "\0"
+        SYSTEMD_FEATURES;
+
+static const BusProperty bus_systemd_properties[] = {
+        { "Version",       bus_property_append_string,    "s",  0                      },
+        { "Features",      bus_property_append_string,    "s",  sizeof(PACKAGE_STRING) },
+        { NULL, }
+};
+
+static const BusProperty bus_manager_properties[] = {
+        { "Tainted",                     bus_manager_append_tainted,     "s",  0                                                },
+        { "FirmwareTimestamp",           bus_property_append_uint64,     "t",  offsetof(Manager, firmware_timestamp.realtime)   },
+        { "FirmwareTimestampMonotonic",  bus_property_append_uint64,     "t",  offsetof(Manager, firmware_timestamp.monotonic)  },
+        { "LoaderTimestamp",             bus_property_append_uint64,     "t",  offsetof(Manager, loader_timestamp.realtime)     },
+        { "LoaderTimestampMonotonic",    bus_property_append_uint64,     "t",  offsetof(Manager, loader_timestamp.monotonic)    },
+        { "KernelTimestamp",             bus_property_append_uint64,     "t",  offsetof(Manager, kernel_timestamp.realtime)     },
+        { "KernelTimestampMonotonic",    bus_property_append_uint64,     "t",  offsetof(Manager, kernel_timestamp.monotonic)    },
+        { "InitRDTimestamp",             bus_property_append_uint64,     "t",  offsetof(Manager, initrd_timestamp.realtime)     },
+        { "InitRDTimestampMonotonic",    bus_property_append_uint64,     "t",  offsetof(Manager, initrd_timestamp.monotonic)    },
+        { "UserspaceTimestamp",          bus_property_append_uint64,     "t",  offsetof(Manager, userspace_timestamp.realtime)  },
+        { "UserspaceTimestampMonotonic", bus_property_append_uint64,     "t",  offsetof(Manager, userspace_timestamp.monotonic) },
+        { "FinishTimestamp",             bus_property_append_uint64,     "t",  offsetof(Manager, finish_timestamp.realtime)     },
+        { "FinishTimestampMonotonic",    bus_property_append_uint64,     "t",  offsetof(Manager, finish_timestamp.monotonic)    },
+        { "LogLevel",                    bus_manager_append_log_level,   "s",  0,                                               false, bus_manager_set_log_level },
+        { "LogTarget",                   bus_manager_append_log_target,  "s",  0,                                               false, bus_manager_set_log_target },
+        { "NNames",                      bus_manager_append_n_names,     "u",  0                                                },
+        { "NJobs",                       bus_manager_append_n_jobs,      "u",  0                                                },
+        { "NInstalledJobs",              bus_property_append_uint32,     "u",  offsetof(Manager, n_installed_jobs)              },
+        { "NFailedJobs",                 bus_property_append_uint32,     "u",  offsetof(Manager, n_failed_jobs)                 },
+        { "Progress",                    bus_manager_append_progress,    "d",  0                                                },
+        { "Environment",                 bus_property_append_strv,       "as", offsetof(Manager, environment),                  true },
+        { "ConfirmSpawn",                bus_property_append_bool,       "b",  offsetof(Manager, confirm_spawn)                 },
+        { "ShowStatus",                  bus_property_append_bool,       "b",  offsetof(Manager, show_status)                   },
+        { "UnitPath",                    bus_property_append_strv,       "as", offsetof(Manager, lookup_paths.unit_path),       true },
+        { "ControlGroupHierarchy",       bus_property_append_string,     "s",  offsetof(Manager, cgroup_hierarchy),             true },
+        { "DefaultControllers",          bus_property_append_strv,       "as", offsetof(Manager, default_controllers),          true },
+        { "DefaultStandardOutput",       bus_manager_append_exec_output, "s",  offsetof(Manager, default_std_output)            },
+        { "DefaultStandardError",        bus_manager_append_exec_output, "s",  offsetof(Manager, default_std_error)             },
+        { "RuntimeWatchdogUSec",         bus_property_append_usec,       "t",  offsetof(Manager, runtime_watchdog),             false, bus_manager_set_runtime_watchdog_usec },
+        { "ShutdownWatchdogUSec",        bus_property_append_usec,       "t",  offsetof(Manager, shutdown_watchdog),            false, bus_property_set_usec },
+        { "Virtualization",              bus_manager_append_virt,        "s",  0,                                               },
+        { NULL, }
+};
+
+static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        _cleanup_free_ char * path = NULL;
+        Manager *m = data;
+        int r;
+        DBusError error;
+        JobType job_type = _JOB_TYPE_INVALID;
+        bool reload_if_possible = false;
+        const char *member;
+
+        assert(connection);
+        assert(message);
+        assert(m);
+
+        dbus_error_init(&error);
+
+        member = dbus_message_get_member(message);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnit")) {
+                const char *name;
+                Unit *u;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                u = manager_get_unit(m, name);
+                if (!u) {
+                        dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+                }
+
+                SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                path = unit_dbus_path(u);
+                if (!path)
+                        goto oom;
+
+                if (!dbus_message_append_args(
+                                    reply,
+                                    DBUS_TYPE_OBJECT_PATH, &path,
+                                    DBUS_TYPE_INVALID))
+                        goto oom;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitByPID")) {
+                Unit *u;
+                uint32_t pid;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_UINT32, &pid,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                u = cgroup_unit_by_pid(m, (pid_t) pid);
+                if (!u) {
+                        dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "No unit for PID %lu is loaded.", (unsigned long) pid);
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+                }
+
+                SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                path = unit_dbus_path(u);
+                if (!path)
+                        goto oom;
+
+                if (!dbus_message_append_args(
+                                    reply,
+                                    DBUS_TYPE_OBJECT_PATH, &path,
+                                    DBUS_TYPE_INVALID))
+                        goto oom;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LoadUnit")) {
+                const char *name;
+                Unit *u;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                r = manager_load_unit(m, name, NULL, &error, &u);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                path = unit_dbus_path(u);
+                if (!path)
+                        goto oom;
+
+                if (!dbus_message_append_args(
+                                    reply,
+                                    DBUS_TYPE_OBJECT_PATH, &path,
+                                    DBUS_TYPE_INVALID))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnit"))
+                job_type = JOB_START;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnitReplace"))
+                job_type = JOB_START;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StopUnit"))
+                job_type = JOB_STOP;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadUnit"))
+                job_type = JOB_RELOAD;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "RestartUnit"))
+                job_type = JOB_RESTART;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "TryRestartUnit"))
+                job_type = JOB_TRY_RESTART;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadOrRestartUnit")) {
+                reload_if_possible = true;
+                job_type = JOB_RESTART;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadOrTryRestartUnit")) {
+                reload_if_possible = true;
+                job_type = JOB_TRY_RESTART;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "KillUnit")) {
+                const char *name, *swho;
+                int32_t signo;
+                Unit *u;
+                KillWho who;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_STRING, &swho,
+                                    DBUS_TYPE_INT32, &signo,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(swho))
+                        who = KILL_ALL;
+                else {
+                        who = kill_who_from_string(swho);
+                        if (who < 0)
+                                return bus_send_error_reply(connection, message, &error, -EINVAL);
+                }
+
+                if (signo <= 0 || signo >= _NSIG)
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                u = manager_get_unit(m, name);
+                if (!u) {
+                        dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+                }
+
+                SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop");
+
+                r = unit_kill(u, who, signo, &error);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) {
+                uint32_t id;
+                Job *j;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_UINT32, &id,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                j = manager_get_job(m, id);
+                if (!j) {
+                        dbus_set_error(&error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+                }
+
+                SELINUX_UNIT_ACCESS_CHECK(j->unit, connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                path = job_dbus_path(j);
+                if (!path)
+                        goto oom;
+
+                if (!dbus_message_append_args(
+                                    reply,
+                                    DBUS_TYPE_OBJECT_PATH, &path,
+                                    DBUS_TYPE_INVALID))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ClearJobs")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "reboot");
+
+                manager_clear_jobs(m);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ResetFailed")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "reload");
+
+                manager_reset_failed(m);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ResetFailedUnit")) {
+                const char *name;
+                Unit *u;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                u = manager_get_unit(m, name);
+                if (!u) {
+                        dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+                }
+
+                SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "reload");
+
+                unit_reset_failed(u);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnits")) {
+                DBusMessageIter iter, sub;
+                Iterator i;
+                Unit *u;
+                const char *k;
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssssssouso)", &sub))
+                        goto oom;
+
+                HASHMAP_FOREACH_KEY(u, k, m->units, i) {
+                        char *u_path, *j_path;
+                        const char *description, *load_state, *active_state, *sub_state, *sjob_type, *following;
+                        DBusMessageIter sub2;
+                        uint32_t job_id;
+                        Unit *f;
+
+                        if (k != u->id)
+                                continue;
+
+                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
+                                goto oom;
+
+                        description = unit_description(u);
+                        load_state = unit_load_state_to_string(u->load_state);
+                        active_state = unit_active_state_to_string(unit_active_state(u));
+                        sub_state = unit_sub_state_to_string(u);
+
+                        f = unit_following(u);
+                        following = f ? f->id : "";
+
+                        u_path = unit_dbus_path(u);
+                        if (!u_path)
+                                goto oom;
+
+                        if (u->job) {
+                                job_id = (uint32_t) u->job->id;
+
+                                if (!(j_path = job_dbus_path(u->job))) {
+                                        free(u_path);
+                                        goto oom;
+                                }
+
+                                sjob_type = job_type_to_string(u->job->type);
+                        } else {
+                                job_id = 0;
+                                j_path = u_path;
+                                sjob_type = "";
+                        }
+
+                        if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &u->id) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &description) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &load_state) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &active_state) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sub_state) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &following) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &job_id) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sjob_type) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path)) {
+                                free(u_path);
+                                if (u->job)
+                                        free(j_path);
+                                goto oom;
+                        }
+
+                        free(u_path);
+                        if (u->job)
+                                free(j_path);
+
+                        if (!dbus_message_iter_close_container(&sub, &sub2))
+                                goto oom;
+                }
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListJobs")) {
+                DBusMessageIter iter, sub;
+                Iterator i;
+                Job *j;
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(usssoo)", &sub))
+                        goto oom;
+
+                HASHMAP_FOREACH(j, m->jobs, i) {
+                        char *u_path, *j_path;
+                        const char *state, *type;
+                        uint32_t id;
+                        DBusMessageIter sub2;
+
+                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
+                                goto oom;
+
+                        id = (uint32_t) j->id;
+                        state = job_state_to_string(j->state);
+                        type = job_type_to_string(j->type);
+
+                        j_path = job_dbus_path(j);
+                        if (!j_path)
+                                goto oom;
+
+                        u_path = unit_dbus_path(j->unit);
+                        if (!u_path) {
+                                free(j_path);
+                                goto oom;
+                        }
+
+                        if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &id) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &j->unit->id) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &type) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &state) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path)) {
+                                free(j_path);
+                                free(u_path);
+                                goto oom;
+                        }
+
+                        free(j_path);
+                        free(u_path);
+
+                        if (!dbus_message_iter_close_container(&sub, &sub2))
+                                goto oom;
+                }
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Subscribe")) {
+                char *client;
+                Set *s;
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                s = BUS_CONNECTION_SUBSCRIBED(m, connection);
+                if (!s) {
+                        s = set_new(string_hash_func, string_compare_func);
+                        if (!s)
+                                goto oom;
+
+                        if (!dbus_connection_set_data(connection, m->subscribed_data_slot, s, NULL)) {
+                                set_free(s);
+                                goto oom;
+                        }
+                }
+
+                client = strdup(bus_message_get_sender_with_fallback(message));
+                if (!client)
+                        goto oom;
+
+                r = set_put(s, client);
+                if (r < 0) {
+                        free(client);
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Unsubscribe")) {
+                char *client;
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                client = set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) bus_message_get_sender_with_fallback(message));
+                if (!client) {
+                        dbus_set_error(&error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+                }
+
+                free(client);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Dump")) {
+                FILE *f;
+                char *dump = NULL;
+                size_t size;
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                f = open_memstream(&dump, &size);
+                if (!f)
+                        goto oom;
+
+                manager_dump_units(m, f, NULL);
+                manager_dump_jobs(m, f, NULL);
+
+                if (ferror(f)) {
+                        fclose(f);
+                        free(dump);
+                        goto oom;
+                }
+
+                fclose(f);
+
+                if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &dump, DBUS_TYPE_INVALID)) {
+                        free(dump);
+                        goto oom;
+                }
+
+                free(dump);
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "CreateSnapshot")) {
+                const char *name;
+                dbus_bool_t cleanup;
+                Snapshot *s;
+
+                SELINUX_ACCESS_CHECK(connection, message, "start");
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_BOOLEAN, &cleanup,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(name))
+                        name = NULL;
+
+                r = snapshot_create(m, name, cleanup, &error, &s);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                path = unit_dbus_path(UNIT(s));
+                if (!path)
+                        goto oom;
+
+                if (!dbus_message_append_args(
+                                    reply,
+                                    DBUS_TYPE_OBJECT_PATH, &path,
+                                    DBUS_TYPE_INVALID))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+                char *introspection = NULL;
+                FILE *f;
+                Iterator i;
+                Unit *u;
+                Job *j;
+                const char *k;
+                size_t size;
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                /* We roll our own introspection code here, instead of
+                 * relying on bus_default_message_handler() because we
+                 * need to generate our introspection string
+                 * dynamically. */
+
+                f = open_memstream(&introspection, &size);
+                if (!f)
+                        goto oom;
+
+                fputs(INTROSPECTION_BEGIN, f);
+
+                HASHMAP_FOREACH_KEY(u, k, m->units, i) {
+                        char *p;
+
+                        if (k != u->id)
+                                continue;
+
+                        p = bus_path_escape(k);
+                        if (!p) {
+                                fclose(f);
+                                free(introspection);
+                                goto oom;
+                        }
+
+                        fprintf(f, "<node name=\"unit/%s\"/>", p);
+                        free(p);
+                }
+
+                HASHMAP_FOREACH(j, m->jobs, i)
+                        fprintf(f, "<node name=\"job/%lu\"/>", (unsigned long) j->id);
+
+                fputs(INTROSPECTION_END, f);
+
+                if (ferror(f)) {
+                        fclose(f);
+                        free(introspection);
+                        goto oom;
+                }
+
+                fclose(f);
+
+                if (!introspection)
+                        goto oom;
+
+                if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
+                        free(introspection);
+                        goto oom;
+                }
+
+                free(introspection);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reload")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "reload");
+
+                assert(!m->queued_message);
+
+                /* Instead of sending the reply back right away, we
+                 * just remember that we need to and then send it
+                 * after the reload is finished. That way the caller
+                 * knows when the reload finished. */
+
+                m->queued_message = dbus_message_new_method_return(message);
+                if (!m->queued_message)
+                        goto oom;
+
+                m->queued_message_connection = connection;
+                m->exit_code = MANAGER_RELOAD;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reexecute")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "reload");
+
+                /* We don't send a reply back here, the client should
+                 * just wait for us disconnecting. */
+
+                m->exit_code = MANAGER_REEXECUTE;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Exit")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "halt");
+
+                if (m->running_as == SYSTEMD_SYSTEM) {
+                        dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
+                        return bus_send_error_reply(connection, message, &error, -ENOTSUP);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                m->exit_code = MANAGER_EXIT;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reboot")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "reboot");
+
+                if (m->running_as != SYSTEMD_SYSTEM) {
+                        dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
+                        return bus_send_error_reply(connection, message, &error, -ENOTSUP);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                m->exit_code = MANAGER_REBOOT;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PowerOff")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "halt");
+
+                if (m->running_as != SYSTEMD_SYSTEM) {
+                        dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
+                        return bus_send_error_reply(connection, message, &error, -ENOTSUP);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                m->exit_code = MANAGER_POWEROFF;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Halt")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "halt");
+
+                if (m->running_as != SYSTEMD_SYSTEM) {
+                        dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Halting is only supported for system managers.");
+                        return bus_send_error_reply(connection, message, &error, -ENOTSUP);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                m->exit_code = MANAGER_HALT;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "KExec")) {
+
+                SELINUX_ACCESS_CHECK(connection, message, "reboot");
+
+                if (m->running_as != SYSTEMD_SYSTEM) {
+                        dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "kexec is only supported for system managers.");
+                        return bus_send_error_reply(connection, message, &error, -ENOTSUP);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                m->exit_code = MANAGER_KEXEC;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SwitchRoot")) {
+                const char *switch_root, *switch_root_init;
+                char *u, *v;
+                int k;
+
+                SELINUX_ACCESS_CHECK(connection, message, "reboot");
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &switch_root,
+                                    DBUS_TYPE_STRING, &switch_root_init,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (path_equal(switch_root, "/") || !path_is_absolute(switch_root))
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                if (!isempty(switch_root_init) && !path_is_absolute(switch_root_init))
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                if (m->running_as != SYSTEMD_SYSTEM) {
+                        dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Switching root is only supported for system managers.");
+                        return bus_send_error_reply(connection, message, &error, -ENOTSUP);
+                }
+
+                /* Safety check */
+                if (isempty(switch_root_init))
+                        k = access(switch_root, F_OK);
+                else {
+                        char *p;
+
+                        p = strjoin(switch_root, "/", switch_root_init, NULL);
+                        if (!p)
+                                goto oom;
+
+                        k = access(p, X_OK);
+                        free(p);
+                }
+                if (k < 0)
+                        return bus_send_error_reply(connection, message, NULL, -errno);
+
+                u = strdup(switch_root);
+                if (!u)
+                        goto oom;
+
+                if (!isempty(switch_root_init)) {
+                        v = strdup(switch_root_init);
+                        if (!v) {
+                                free(u);
+                                goto oom;
+                        }
+                } else
+                        v = NULL;
+
+                free(m->switch_root);
+                free(m->switch_root_init);
+                m->switch_root = u;
+                m->switch_root_init = v;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                m->exit_code = MANAGER_SWITCH_ROOT;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetEnvironment")) {
+                char **l = NULL, **e = NULL;
+
+                SELINUX_ACCESS_CHECK(connection, message, "reboot");
+
+                r = bus_parse_strv(message, &l);
+                if (r == -ENOMEM)
+                        goto oom;
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                e = strv_env_merge(2, m->environment, l);
+                strv_free(l);
+                if (!e)
+                        goto oom;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply) {
+                        strv_free(e);
+                        goto oom;
+                }
+
+                strv_free(m->environment);
+                m->environment = e;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetEnvironment")) {
+                char **l = NULL, **e = NULL;
+
+                SELINUX_ACCESS_CHECK(connection, message, "reboot");
+
+                r = bus_parse_strv(message, &l);
+                if (r == -ENOMEM)
+                        goto oom;
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                e = strv_env_delete(m->environment, 1, l);
+                strv_free(l);
+
+                if (!e)
+                        goto oom;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply) {
+                        strv_free(e);
+                        goto oom;
+                }
+
+                strv_free(m->environment);
+                m->environment = e;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment")) {
+                char **l_set = NULL, **l_unset = NULL, **e = NULL, **f = NULL;
+                DBusMessageIter iter;
+
+                SELINUX_ACCESS_CHECK(connection, message, "reboot");
+
+                if (!dbus_message_iter_init(message, &iter))
+                        goto oom;
+
+                r = bus_parse_strv_iter(&iter, &l_unset);
+                if (r == -ENOMEM)
+                        goto oom;
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                if (!dbus_message_iter_next(&iter)) {
+                        strv_free(l_unset);
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+                }
+
+                r = bus_parse_strv_iter(&iter, &l_set);
+                if (r < 0) {
+                        strv_free(l_unset);
+                        if (r == -ENOMEM)
+                                goto oom;
+
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                e = strv_env_delete(m->environment, 1, l_unset);
+                strv_free(l_unset);
+
+                if (!e) {
+                        strv_free(l_set);
+                        goto oom;
+                }
+
+                f = strv_env_merge(2, e, l_set);
+                strv_free(l_set);
+                strv_free(e);
+
+                if (!f)
+                        goto oom;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply) {
+                        strv_free(f);
+                        goto oom;
+                }
+
+                strv_free(m->environment);
+                m->environment = f;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnitFiles")) {
+                DBusMessageIter iter, sub, sub2;
+                Hashmap *h;
+                Iterator i;
+                UnitFileList *item;
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                h = hashmap_new(string_hash_func, string_compare_func);
+                if (!h)
+                        goto oom;
+
+                r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
+                if (r < 0) {
+                        unit_file_list_free(h);
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ss)", &sub)) {
+                        unit_file_list_free(h);
+                        goto oom;
+                }
+
+                HASHMAP_FOREACH(item, h, i) {
+                        const char *state;
+
+                        state = unit_file_state_to_string(item->state);
+                        assert(state);
+
+                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &item->path) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &state) ||
+                            !dbus_message_iter_close_container(&sub, &sub2)) {
+                                unit_file_list_free(h);
+                                goto oom;
+                        }
+                }
+
+                unit_file_list_free(h);
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitFileState")) {
+                const char *name;
+                UnitFileState state;
+                const char *s;
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                state = unit_file_get_state(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, name);
+                if (state < 0)
+                        return bus_send_error_reply(connection, message, NULL, state);
+
+                s = unit_file_state_to_string(state);
+                assert(s);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                if (!dbus_message_append_args(
+                                    reply,
+                                    DBUS_TYPE_STRING, &s,
+                                    DBUS_TYPE_INVALID))
+                        goto oom;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "EnableUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReenableUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LinkUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PresetUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "MaskUnitFiles")) {
+
+                char **l = NULL;
+                DBusMessageIter iter;
+                UnitFileScope scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
+                UnitFileChange *changes = NULL;
+                unsigned n_changes = 0;
+                dbus_bool_t runtime, force;
+                int carries_install_info = -1;
+
+                SELINUX_ACCESS_CHECK(connection, message, streq(member, "MaskUnitFiles") ? "disable" : "enable");
+
+                if (!dbus_message_iter_init(message, &iter))
+                        goto oom;
+
+                r = bus_parse_strv_iter(&iter, &l);
+                if (r < 0) {
+                        if (r == -ENOMEM)
+                                goto oom;
+
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                if (!dbus_message_iter_next(&iter) ||
+                    bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, true) < 0 ||
+                    bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &force, false) < 0) {
+                        strv_free(l);
+                        return bus_send_error_reply(connection, message, NULL, -EIO);
+                }
+
+                if (streq(member, "EnableUnitFiles")) {
+                        r = unit_file_enable(scope, runtime, NULL, l, force, &changes, &n_changes);
+                        carries_install_info = r;
+                } else if (streq(member, "ReenableUnitFiles")) {
+                        r = unit_file_reenable(scope, runtime, NULL, l, force, &changes, &n_changes);
+                        carries_install_info = r;
+                } else if (streq(member, "LinkUnitFiles"))
+                        r = unit_file_link(scope, runtime, NULL, l, force, &changes, &n_changes);
+                else if (streq(member, "PresetUnitFiles")) {
+                        r = unit_file_preset(scope, runtime, NULL, l, force, &changes, &n_changes);
+                        carries_install_info = r;
+                } else if (streq(member, "MaskUnitFiles"))
+                        r = unit_file_mask(scope, runtime, NULL, l, force, &changes, &n_changes);
+                else
+                        assert_not_reached("Uh? Wrong method");
+
+                strv_free(l);
+                bus_manager_send_unit_files_changed(m);
+
+                if (r < 0) {
+                        unit_file_changes_free(changes, n_changes);
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                reply = message_from_file_changes(message, changes, n_changes, carries_install_info);
+                unit_file_changes_free(changes, n_changes);
+
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "DisableUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnmaskUnitFiles")) {
+
+                char **l = NULL;
+                DBusMessageIter iter;
+                UnitFileScope scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
+                UnitFileChange *changes = NULL;
+                unsigned n_changes = 0;
+                dbus_bool_t runtime;
+
+                SELINUX_ACCESS_CHECK(connection, message, streq(member, "UnmaskUnitFiles") ? "enable" : "disable");
+
+                if (!dbus_message_iter_init(message, &iter))
+                        goto oom;
+
+                r = bus_parse_strv_iter(&iter, &l);
+                if (r < 0) {
+                        if (r == -ENOMEM)
+                                goto oom;
+
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                if (!dbus_message_iter_next(&iter) ||
+                    bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, false) < 0) {
+                        strv_free(l);
+                        return bus_send_error_reply(connection, message, NULL, -EIO);
+                }
+
+                if (streq(member, "DisableUnitFiles"))
+                        r = unit_file_disable(scope, runtime, NULL, l, &changes, &n_changes);
+                else if (streq(member, "UnmaskUnitFiles"))
+                        r = unit_file_unmask(scope, runtime, NULL, l, &changes, &n_changes);
+                else
+                        assert_not_reached("Uh? Wrong method");
+
+                strv_free(l);
+                bus_manager_send_unit_files_changed(m);
+
+                if (r < 0) {
+                        unit_file_changes_free(changes, n_changes);
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                reply = message_from_file_changes(message, changes, n_changes, -1);
+                unit_file_changes_free(changes, n_changes);
+
+                if (!reply)
+                        goto oom;
+
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.systemd1.Manager", bus_systemd_properties, systemd_property_string },
+                        { "org.freedesktop.systemd1.Manager", bus_manager_properties, m },
+                        { NULL, }
+                };
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps);
+        }
+
+        if (job_type != _JOB_TYPE_INVALID) {
+                const char *name, *smode, *old_name = NULL;
+                JobMode mode;
+                Unit *u;
+                dbus_bool_t b;
+
+                if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnitReplace"))
+                        b = dbus_message_get_args(
+                                        message,
+                                        &error,
+                                        DBUS_TYPE_STRING, &old_name,
+                                        DBUS_TYPE_STRING, &name,
+                                        DBUS_TYPE_STRING, &smode,
+                                        DBUS_TYPE_INVALID);
+                else
+                        b = dbus_message_get_args(
+                                        message,
+                                        &error,
+                                        DBUS_TYPE_STRING, &name,
+                                        DBUS_TYPE_STRING, &smode,
+                                        DBUS_TYPE_INVALID);
+                if (!b)
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (old_name) {
+                        u = manager_get_unit(m, old_name);
+                        if (!u || !u->job || u->job->type != JOB_START) {
+                                dbus_set_error(&error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
+                                return bus_send_error_reply(connection, message, &error, -ENOENT);
+                        }
+                }
+
+                mode = job_mode_from_string(smode);
+                if (mode < 0) {
+                        dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode);
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+                }
+
+                r = manager_load_unit(m, name, NULL, &error, &u);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                return bus_unit_queue_job(connection, message, u, job_type, mode, reload_if_possible);
+        }
+
+        if (reply)
+                if (!dbus_connection_send(connection, reply, NULL))
+                        goto oom;
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+const DBusObjectPathVTable bus_manager_vtable = {
+        .message_function = bus_manager_message_handler
+};
diff --git a/src/core/dbus-manager.h b/src/core/dbus-manager.h
new file mode 100644 (file)
index 0000000..f0dce5a
--- /dev/null
@@ -0,0 +1,28 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+extern const DBusObjectPathVTable bus_manager_vtable;
+
+extern const char bus_manager_interface[];
diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c
new file mode 100644 (file)
index 0000000..d81edeb
--- /dev/null
@@ -0,0 +1,168 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus-unit.h"
+#include "dbus-mount.h"
+#include "dbus-kill.h"
+#include "dbus-execute.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_MOUNT_INTERFACE                                             \
+        " <interface name=\"org.freedesktop.systemd1.Mount\">\n"        \
+        "  <property name=\"Where\" type=\"s\" access=\"read\"/>\n"     \
+        "  <property name=\"What\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Options\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"Type\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+        BUS_EXEC_COMMAND_INTERFACE("ExecMount")                         \
+        BUS_EXEC_COMMAND_INTERFACE("ExecUnmount")                       \
+        BUS_EXEC_COMMAND_INTERFACE("ExecRemount")                       \
+        BUS_EXEC_CONTEXT_INTERFACE                                      \
+        BUS_KILL_CONTEXT_INTERFACE                                      \
+        "  <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_MOUNT_INTERFACE                                             \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Mount\0"
+
+const char bus_mount_interface[] _introspect_("Mount") = BUS_MOUNT_INTERFACE;
+
+const char bus_mount_invalidating_properties[] =
+        "What\0"
+        "Options\0"
+        "Type\0"
+        "ExecMount\0"
+        "ExecUnmount\0"
+        "ExecRemount\0"
+        "ControlPID\0"
+        "Result\0";
+
+static int bus_mount_append_what(DBusMessageIter *i, const char *property, void *data) {
+        Mount *m = data;
+        const char *d;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
+                d = m->parameters_proc_self_mountinfo.what;
+        else if (m->from_fragment && m->parameters_fragment.what)
+                d = m->parameters_fragment.what;
+        else
+                d = "";
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_mount_append_options(DBusMessageIter *i, const char *property, void *data) {
+        Mount *m = data;
+        const char *d;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
+                d = m->parameters_proc_self_mountinfo.options;
+        else if (m->from_fragment && m->parameters_fragment.options)
+                d = m->parameters_fragment.options;
+        else
+                d = "";
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_mount_append_type(DBusMessageIter *i, const char *property, void *data) {
+        Mount *m = data;
+        const char *d;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
+                d = m->parameters_proc_self_mountinfo.fstype;
+        else if (m->from_fragment && m->parameters_fragment.fstype)
+                d = m->parameters_fragment.fstype;
+        else
+                d = "";
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_mount_append_mount_result, mount_result, MountResult);
+
+static const BusProperty bus_mount_properties[] = {
+        { "Where",         bus_property_append_string, "s", offsetof(Mount, where),    true },
+        { "What",          bus_mount_append_what,      "s", 0 },
+        { "Options",       bus_mount_append_options,   "s", 0 },
+        { "Type",          bus_mount_append_type,      "s", 0 },
+        { "TimeoutUSec",   bus_property_append_usec,   "t", offsetof(Mount, timeout_usec)   },
+        BUS_EXEC_COMMAND_PROPERTY("ExecMount",   offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]),   false),
+        BUS_EXEC_COMMAND_PROPERTY("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), false),
+        BUS_EXEC_COMMAND_PROPERTY("ExecRemount", offsetof(Mount, exec_command[MOUNT_EXEC_REMOUNT]), false),
+        { "ControlPID",    bus_property_append_pid,    "u", offsetof(Mount, control_pid)    },
+        { "DirectoryMode", bus_property_append_mode,   "u", offsetof(Mount, directory_mode) },
+        { "Result",        bus_mount_append_mount_result, "s", offsetof(Mount, result)      },
+        { NULL, }
+};
+
+DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        Mount *m = MOUNT(u);
+
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",  bus_unit_properties,         u },
+                { "org.freedesktop.systemd1.Mount", bus_mount_properties,        m },
+                { "org.freedesktop.systemd1.Mount", bus_exec_context_properties, &m->exec_context },
+                { "org.freedesktop.systemd1.Mount", bus_kill_context_properties, &m->kill_context },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps );
+}
diff --git a/src/core/dbus-mount.h b/src/core/dbus-mount.h
new file mode 100644 (file)
index 0000000..8597394
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_mount_interface[];
+extern const char bus_mount_invalidating_properties[];
diff --git a/src/core/dbus-path.c b/src/core/dbus-path.c
new file mode 100644 (file)
index 0000000..f7fed17
--- /dev/null
@@ -0,0 +1,122 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus-unit.h"
+#include "dbus-path.h"
+#include "dbus-execute.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_PATH_INTERFACE                                              \
+        " <interface name=\"org.freedesktop.systemd1.Path\">\n"         \
+        "  <property name=\"Unit\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Paths\" type=\"a(ss)\" access=\"read\"/>\n" \
+        "  <property name=\"MakeDirectory\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_PATH_INTERFACE                                              \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Path\0"
+
+const char bus_path_interface[] _introspect_("Path") = BUS_PATH_INTERFACE;
+
+const char bus_path_invalidating_properties[] =
+        "Result\0";
+
+static int bus_path_append_paths(DBusMessageIter *i, const char *property, void *data) {
+        Path *p = data;
+        DBusMessageIter sub, sub2;
+        PathSpec *k;
+
+        assert(i);
+        assert(property);
+        assert(p);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &sub))
+                return -ENOMEM;
+
+        LIST_FOREACH(spec, k, p->specs) {
+                const char *t = path_type_to_string(k->type);
+
+                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &t) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &k->path) ||
+                    !dbus_message_iter_close_container(&sub, &sub2))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_path_append_unit(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        Path *p = PATH(u);
+        const char *t;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        t = UNIT_DEREF(p->unit) ? UNIT_DEREF(p->unit)->id : "";
+
+        return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM;
+}
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_path_append_path_result, path_result, PathResult);
+
+static const BusProperty bus_path_properties[] = {
+        { "Unit",          bus_path_append_unit,      "s", 0 },
+        { "Paths",         bus_path_append_paths, "a(ss)", 0 },
+        { "MakeDirectory", bus_property_append_bool,  "b", offsetof(Path, make_directory) },
+        { "DirectoryMode", bus_property_append_mode,  "u", offsetof(Path, directory_mode) },
+        { "Result",        bus_path_append_path_result, "s", offsetof(Path, result) },
+        { NULL, }
+};
+
+DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        Path *p = PATH(u);
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit", bus_unit_properties, u },
+                { "org.freedesktop.systemd1.Path", bus_path_properties, p },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+}
diff --git a/src/core/dbus-path.h b/src/core/dbus-path.h
new file mode 100644 (file)
index 0000000..c945f7d
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_path_interface[];
+
+extern const char bus_path_invalidating_properties[];
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
new file mode 100644 (file)
index 0000000..d99058d
--- /dev/null
@@ -0,0 +1,161 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus-unit.h"
+#include "dbus-execute.h"
+#include "dbus-kill.h"
+#include "dbus-service.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_SERVICE_INTERFACE                                           \
+        " <interface name=\"org.freedesktop.systemd1.Service\">\n"      \
+        "  <property name=\"Type\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Restart\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"PIDFile\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"NotifyAccess\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"RestartUSec\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"WatchdogUSec\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"WatchdogTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"WatchdogTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"StartLimitInterval\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"StartLimitBurst\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"StartLimitAction\" type=\"s\" access=\"readwrite\"/>\n" \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStartPre")                      \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStart")                         \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStartPost")                     \
+        BUS_EXEC_COMMAND_INTERFACE("ExecReload")                        \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStop")                          \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStopPost")                      \
+        BUS_EXEC_CONTEXT_INTERFACE                                      \
+        BUS_KILL_CONTEXT_INTERFACE                                      \
+        "  <property name=\"PermissionsStartOnly\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"RootDirectoryStartOnly\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"RemainAfterExit\" type=\"b\" access=\"read\"/>\n" \
+        BUS_EXEC_STATUS_INTERFACE("ExecMain")                           \
+        "  <property name=\"MainPID\" type=\"u\" access=\"read\"/>\n"   \
+        "  <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"BusName\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"StatusText\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
+       " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_SERVICE_INTERFACE                                           \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Service\0"
+
+const char bus_service_interface[] _introspect_("Service") = BUS_SERVICE_INTERFACE;
+
+const char bus_service_invalidating_properties[] =
+        "ExecStartPre\0"
+        "ExecStart\0"
+        "ExecStartPost\0"
+        "ExecReload\0"
+        "ExecStop\0"
+        "ExecStopPost\0"
+        "ExecMain\0"
+        "WatchdogTimestamp\0"
+        "WatchdogTimestampMonotonic\0"
+        "MainPID\0"
+        "ControlPID\0"
+        "StatusText\0"
+        "Result\0";
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType);
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_restart, service_restart, ServiceRestart);
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_notify_access, notify_access, NotifyAccess);
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_service_result, service_result, ServiceResult);
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_start_limit_action, start_limit_action, StartLimitAction);
+static DEFINE_BUS_PROPERTY_SET_ENUM(bus_service_set_start_limit_action, start_limit_action, StartLimitAction);
+
+static const BusProperty bus_exec_main_status_properties[] = {
+        { "ExecMainStartTimestamp",         bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime)  },
+        { "ExecMainStartTimestampMonotonic",bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) },
+        { "ExecMainExitTimestamp",          bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime)  },
+        { "ExecMainExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) },
+        { "ExecMainPID",                    bus_property_append_pid,  "u", offsetof(ExecStatus, pid)                       },
+        { "ExecMainCode",                   bus_property_append_int,  "i", offsetof(ExecStatus, code)                      },
+        { "ExecMainStatus",                 bus_property_append_int,  "i", offsetof(ExecStatus, status)                    },
+        { NULL, }
+};
+
+static const BusProperty bus_service_properties[] = {
+        { "Type",                   bus_service_append_type,          "s", offsetof(Service, type)                         },
+        { "Restart",                bus_service_append_restart,       "s", offsetof(Service, restart)                      },
+        { "PIDFile",                bus_property_append_string,       "s", offsetof(Service, pid_file),               true },
+        { "NotifyAccess",           bus_service_append_notify_access, "s", offsetof(Service, notify_access)                },
+        { "RestartUSec",            bus_property_append_usec,         "t", offsetof(Service, restart_usec)                 },
+        { "TimeoutUSec",            bus_property_append_usec,         "t", offsetof(Service, timeout_start_usec)           },
+        { "TimeoutStartUSec",       bus_property_append_usec,         "t", offsetof(Service, timeout_start_usec)           },
+        { "TimeoutStopUSec",        bus_property_append_usec,         "t", offsetof(Service, timeout_stop_usec)            },
+        { "WatchdogUSec",           bus_property_append_usec,         "t", offsetof(Service, watchdog_usec)                },
+        { "WatchdogTimestamp",      bus_property_append_usec,         "t", offsetof(Service, watchdog_timestamp.realtime)  },
+        { "WatchdogTimestampMonotonic",bus_property_append_usec,      "t", offsetof(Service, watchdog_timestamp.monotonic) },
+        { "StartLimitInterval",     bus_property_append_usec,         "t", offsetof(Service, start_limit.interval)         },
+        { "StartLimitBurst",        bus_property_append_uint32,       "u", offsetof(Service, start_limit.burst)            },
+        { "StartLimitAction",       bus_service_append_start_limit_action,"s", offsetof(Service, start_limit_action), false, bus_service_set_start_limit_action},
+        BUS_EXEC_COMMAND_PROPERTY("ExecStartPre",  offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]),  true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStart",     offsetof(Service, exec_command[SERVICE_EXEC_START]),      true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecReload",    offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]),     true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStop",      offsetof(Service, exec_command[SERVICE_EXEC_STOP]),       true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStopPost",  offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]),  true ),
+        { "PermissionsStartOnly",   bus_property_append_bool,         "b", offsetof(Service, permissions_start_only)       },
+        { "RootDirectoryStartOnly", bus_property_append_bool,         "b", offsetof(Service, root_directory_start_only)    },
+        { "RemainAfterExit",        bus_property_append_bool,         "b", offsetof(Service, remain_after_exit)            },
+        { "GuessMainPID",           bus_property_append_bool,         "b", offsetof(Service, guess_main_pid)               },
+        { "MainPID",                bus_property_append_pid,          "u", offsetof(Service, main_pid)                     },
+        { "ControlPID",             bus_property_append_pid,          "u", offsetof(Service, control_pid)                  },
+        { "BusName",                bus_property_append_string,       "s", offsetof(Service, bus_name),               true },
+        { "StatusText",             bus_property_append_string,       "s", offsetof(Service, status_text),            true },
+        { "Result",                 bus_service_append_service_result,"s", offsetof(Service, result)                       },
+        { NULL, }
+};
+
+DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) {
+        Service *s = SERVICE(u);
+
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",    bus_unit_properties,             u },
+                { "org.freedesktop.systemd1.Service", bus_service_properties,          s },
+                { "org.freedesktop.systemd1.Service", bus_exec_context_properties,     &s->exec_context },
+                { "org.freedesktop.systemd1.Service", bus_kill_context_properties,     &s->kill_context },
+                { "org.freedesktop.systemd1.Service", bus_exec_main_status_properties, &s->main_exec_status },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status");
+
+        return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+}
diff --git a/src/core/dbus-service.h b/src/core/dbus-service.h
new file mode 100644 (file)
index 0000000..143aed7
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_service_interface[];
+extern const char bus_service_invalidating_properties[];
diff --git a/src/core/dbus-snapshot.c b/src/core/dbus-snapshot.c
new file mode 100644 (file)
index 0000000..435c6df
--- /dev/null
@@ -0,0 +1,94 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "dbus-unit.h"
+#include "dbus-snapshot.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_SNAPSHOT_INTERFACE                                          \
+        " <interface name=\"org.freedesktop.systemd1.Snapshot\">\n"     \
+        "  <method name=\"Remove\"/>\n"                                 \
+        "  <property name=\"Cleanup\" type=\"b\" access=\"read\"/>\n"   \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_SNAPSHOT_INTERFACE                                          \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Snapshot\0"
+
+const char bus_snapshot_interface[] _introspect_("Snapshot") = BUS_SNAPSHOT_INTERFACE;
+
+static const BusProperty bus_snapshot_properties[] = {
+        { "Cleanup", bus_property_append_bool, "b", offsetof(Snapshot, cleanup) },
+        { NULL, }
+};
+
+DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        Snapshot *s = SNAPSHOT(u);
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        DBusError error;
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Snapshot", "Remove")) {
+
+                SELINUX_UNIT_ACCESS_CHECK(u, c, message, "stop");
+
+                snapshot_remove(SNAPSHOT(u));
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.systemd1.Unit",     bus_unit_properties,     u },
+                        { "org.freedesktop.systemd1.Snapshot", bus_snapshot_properties, s },
+                        { NULL, }
+                };
+
+                SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+                return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
+
+        if (reply) {
+                if (!dbus_connection_send(c, reply, NULL))
+                        goto oom;
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
diff --git a/src/core/dbus-snapshot.h b/src/core/dbus-snapshot.h
new file mode 100644 (file)
index 0000000..1208aaf
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_snapshot_interface[];
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
new file mode 100644 (file)
index 0000000..095a031
--- /dev/null
@@ -0,0 +1,151 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus-unit.h"
+#include "dbus-socket.h"
+#include "dbus-execute.h"
+#include "dbus-kill.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_SOCKET_INTERFACE                                            \
+        " <interface name=\"org.freedesktop.systemd1.Socket\">\n"       \
+        "  <property name=\"BindIPv6Only\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"Backlog\" type=\"u\" access=\"read\"/>\n"   \
+        "  <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStartPre")                      \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStartPost")                     \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStopPre")                       \
+        BUS_EXEC_COMMAND_INTERFACE("ExecStopPost")                      \
+        BUS_EXEC_CONTEXT_INTERFACE                                      \
+        BUS_KILL_CONTEXT_INTERFACE                                      \
+        "  <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"BindToDevice\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"SocketMode\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"Accept\" type=\"b\" access=\"read\"/>\n"    \
+        "  <property name=\"KeepAlive\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"Priority\" type=\"i\" access=\"read\"/>\n"  \
+        "  <property name=\"ReceiveBuffer\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"SendBuffer\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"IPTOS\" type=\"i\" access=\"read\"/>\n"     \
+        "  <property name=\"IPTTL\" type=\"i\" access=\"read\"/>\n"     \
+        "  <property name=\"PipeSize\" type=\"t\" access=\"read\"/>\n"  \
+        "  <property name=\"FreeBind\" type=\"b\" access=\"read\"/>\n"  \
+        "  <property name=\"Transparent\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"Broadcast\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"PassCredentials\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"PassSecurity\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"Mark\" type=\"i\" access=\"read\"/>\n"      \
+        "  <property name=\"MaxConnections\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"NAccepted\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"NConnections\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"MessageQueueMaxMessages\" type=\"x\" access=\"read\"/>\n" \
+        "  <property name=\"MessageQueueMessageSize\" type=\"x\" access=\"read\"/>\n" \
+        "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
+        "  <property name=\"SmackLabel\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"SmackLabelIPIn\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"SmackLabelIPOut\" type=\"s\" access=\"read\"/>\n" \
+        " </interface>\n"                                               \
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_SOCKET_INTERFACE                                            \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Socket\0"
+
+const char bus_socket_interface[] _introspect_("Socket") = BUS_SOCKET_INTERFACE;
+
+const char bus_socket_invalidating_properties[] =
+        "ExecStartPre\0"
+        "ExecStartPost\0"
+        "ExecStopPre\0"
+        "ExecStopPost\0"
+        "ControlPID\0"
+        "NAccepted\0"
+        "NConnections\0"
+        "Result\0";
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_socket_result, socket_result, SocketResult);
+
+static const BusProperty bus_socket_properties[] = {
+        { "BindIPv6Only",   bus_socket_append_bind_ipv6_only,  "s", offsetof(Socket, bind_ipv6_only)  },
+        { "Backlog",        bus_property_append_unsigned,      "u", offsetof(Socket, backlog)         },
+        { "TimeoutUSec",    bus_property_append_usec,          "t", offsetof(Socket, timeout_usec)    },
+        BUS_EXEC_COMMAND_PROPERTY("ExecStartPre",  offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]),  true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStopPre",   offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]),   true ),
+        BUS_EXEC_COMMAND_PROPERTY("ExecStopPost",  offsetof(Socket, exec_command[SOCKET_EXEC_STOP_POST]),  true ),
+        { "ControlPID",     bus_property_append_pid,           "u", offsetof(Socket, control_pid)     },
+        { "BindToDevice",   bus_property_append_string,        "s", offsetof(Socket, bind_to_device), true },
+        { "DirectoryMode",  bus_property_append_mode,          "u", offsetof(Socket, directory_mode)  },
+        { "SocketMode",     bus_property_append_mode,          "u", offsetof(Socket, socket_mode)     },
+        { "Accept",         bus_property_append_bool,          "b", offsetof(Socket, accept)          },
+        { "KeepAlive",      bus_property_append_bool,          "b", offsetof(Socket, keep_alive)      },
+        { "Priority",       bus_property_append_int,           "i", offsetof(Socket, priority)        },
+        { "ReceiveBuffer",  bus_property_append_size,          "t", offsetof(Socket, receive_buffer)  },
+        { "SendBuffer",     bus_property_append_size,          "t", offsetof(Socket, send_buffer)     },
+        { "IPTOS",          bus_property_append_int,           "i", offsetof(Socket, ip_tos)          },
+        { "IPTTL",          bus_property_append_int,           "i", offsetof(Socket, ip_ttl)          },
+        { "PipeSize",       bus_property_append_size,          "t", offsetof(Socket, pipe_size)       },
+        { "FreeBind",       bus_property_append_bool,          "b", offsetof(Socket, free_bind)       },
+        { "Transparent",    bus_property_append_bool,          "b", offsetof(Socket, transparent)     },
+        { "Broadcast",      bus_property_append_bool,          "b", offsetof(Socket, broadcast)       },
+        { "PassCredentials",bus_property_append_bool,          "b", offsetof(Socket, pass_cred)       },
+        { "PassSecurity",   bus_property_append_bool,          "b", offsetof(Socket, pass_sec)        },
+        { "Mark",           bus_property_append_int,           "i", offsetof(Socket, mark)            },
+        { "MaxConnections", bus_property_append_unsigned,      "u", offsetof(Socket, max_connections) },
+        { "NConnections",   bus_property_append_unsigned,      "u", offsetof(Socket, n_connections)   },
+        { "NAccepted",      bus_property_append_unsigned,      "u", offsetof(Socket, n_accepted)      },
+        { "MessageQueueMaxMessages", bus_property_append_long, "x", offsetof(Socket, mq_maxmsg)       },
+        { "MessageQueueMessageSize", bus_property_append_long, "x", offsetof(Socket, mq_msgsize)      },
+        { "Result",         bus_socket_append_socket_result,   "s", offsetof(Socket, result)          },
+        { "SmackLabel",     bus_property_append_string,        "s", offsetof(Socket, smack),          true },
+        { "SmackLabelIPIn", bus_property_append_string,        "s", offsetof(Socket, smack_ip_in),    true },
+        { "SmackLabelIPOut",bus_property_append_string,        "s", offsetof(Socket, smack_ip_out),   true },
+        { NULL, }
+};
+
+DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        Socket *s = SOCKET(u);
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",   bus_unit_properties,         u },
+                { "org.freedesktop.systemd1.Socket", bus_socket_properties,       s },
+                { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context },
+                { "org.freedesktop.systemd1.Socket", bus_kill_context_properties, &s->kill_context },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+}
diff --git a/src/core/dbus-socket.h b/src/core/dbus-socket.h
new file mode 100644 (file)
index 0000000..5369b22
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_socket_interface[];
+extern const char bus_socket_invalidating_properties[];
diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c
new file mode 100644 (file)
index 0000000..67ea0f2
--- /dev/null
@@ -0,0 +1,115 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright 2010 Maarten Lankhorst
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus-unit.h"
+#include "dbus-swap.h"
+#include "dbus-execute.h"
+#include "dbus-kill.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_SWAP_INTERFACE                                              \
+        " <interface name=\"org.freedesktop.systemd1.Swap\">\n"         \
+        "  <property name=\"What\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Priority\" type=\"i\" access=\"read\"/>\n"  \
+        "  <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+        BUS_EXEC_COMMAND_INTERFACE("ExecActivate")                      \
+        BUS_EXEC_COMMAND_INTERFACE("ExecDeactivate")                    \
+        BUS_EXEC_CONTEXT_INTERFACE                                      \
+        BUS_KILL_CONTEXT_INTERFACE                                      \
+        "  <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_SWAP_INTERFACE                                              \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Swap\0"
+
+const char bus_swap_interface[] _introspect_("Swap") = BUS_SWAP_INTERFACE;
+
+const char bus_swap_invalidating_properties[] =
+        "What\0"
+        "Priority\0"
+        "ExecActivate\0"
+        "ExecDeactivate\0"
+        "ControlPID\0"
+        "Result\0";
+
+static int bus_swap_append_priority(DBusMessageIter *i, const char *property, void *data) {
+        Swap *s = data;
+        dbus_int32_t j;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        if (s->from_proc_swaps)
+                j = s->parameters_proc_swaps.priority;
+        else if (s->from_fragment)
+                j = s->parameters_fragment.priority;
+        else
+                j = -1;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &j))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_swap_append_swap_result, swap_result, SwapResult);
+
+static const BusProperty bus_swap_properties[] = {
+        { "What",       bus_property_append_string, "s", offsetof(Swap, what),  true },
+        { "Priority",   bus_swap_append_priority,   "i", 0 },
+        BUS_EXEC_COMMAND_PROPERTY("ExecActivate",   offsetof(Swap, exec_command[SWAP_EXEC_ACTIVATE]),   false),
+        BUS_EXEC_COMMAND_PROPERTY("ExecDeactivate", offsetof(Swap, exec_command[SWAP_EXEC_DEACTIVATE]), false),
+        { "ControlPID", bus_property_append_pid,    "u", offsetof(Swap, control_pid) },
+        { "Result",     bus_swap_append_swap_result,"s", offsetof(Swap, result)      },
+        { NULL, }
+};
+
+DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        Swap *s = SWAP(u);
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit", bus_unit_properties,         u },
+                { "org.freedesktop.systemd1.Swap", bus_swap_properties,         s },
+                { "org.freedesktop.systemd1.Swap", bus_exec_context_properties, &s->exec_context },
+                { "org.freedesktop.systemd1.Swap", bus_kill_context_properties, &s->kill_context },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+}
diff --git a/src/core/dbus-swap.h b/src/core/dbus-swap.h
new file mode 100644 (file)
index 0000000..41fe444
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright 2010 Maarten Lankhorst
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_swap_interface[];
+extern const char bus_swap_invalidating_properties[];
diff --git a/src/core/dbus-target.c b/src/core/dbus-target.c
new file mode 100644 (file)
index 0000000..6a77550
--- /dev/null
@@ -0,0 +1,58 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus-unit.h"
+#include "dbus-target.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_TARGET_INTERFACE                                            \
+        " <interface name=\"org.freedesktop.systemd1.Target\">\n"       \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_TARGET_INTERFACE                                            \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Target\0"
+
+const char bus_target_interface[] _introspect_("Target") = BUS_TARGET_INTERFACE;
+
+DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit", bus_unit_properties, u },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+}
diff --git a/src/core/dbus-target.h b/src/core/dbus-target.h
new file mode 100644 (file)
index 0000000..a8a0304
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_target_interface[];
diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c
new file mode 100644 (file)
index 0000000..11d18cb
--- /dev/null
@@ -0,0 +1,142 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus-unit.h"
+#include "dbus-timer.h"
+#include "dbus-execute.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+#define BUS_TIMER_INTERFACE                                             \
+        " <interface name=\"org.freedesktop.systemd1.Timer\">\n"        \
+        "  <property name=\"Unit\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Timers\" type=\"a(stt)\" access=\"read\"/>\n" \
+        "  <property name=\"NextElapseUSec\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_UNIT_INTERFACE                                              \
+        BUS_TIMER_INTERFACE                                             \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_UNIT_INTERFACES_LIST                     \
+        "org.freedesktop.systemd1.Timer\0"
+
+const char bus_timer_interface[] _introspect_("Timer") = BUS_TIMER_INTERFACE;
+
+const char bus_timer_invalidating_properties[] =
+        "Timers\0"
+        "NextElapseUSec\0"
+        "Result\0";
+
+static int bus_timer_append_timers(DBusMessageIter *i, const char *property, void *data) {
+        Timer *p = data;
+        DBusMessageIter sub, sub2;
+        TimerValue *k;
+
+        assert(i);
+        assert(property);
+        assert(p);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(stt)", &sub))
+                return -ENOMEM;
+
+        LIST_FOREACH(value, k, p->values) {
+                char *buf;
+                const char *t;
+                size_t l;
+                bool b;
+
+                t = timer_base_to_string(k->base);
+                assert(endswith(t, "Sec"));
+
+                /* s/Sec/USec/ */
+                l = strlen(t);
+                buf = new(char, l+2);
+                if (!buf)
+                        return -ENOMEM;
+
+                memcpy(buf, t, l-3);
+                memcpy(buf+l-3, "USec", 5);
+
+                b = dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) &&
+                        dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &buf) &&
+                        dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->value) &&
+                        dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->next_elapse) &&
+                        dbus_message_iter_close_container(&sub, &sub2);
+
+                free(buf);
+                if (!b)
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_timer_append_unit(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        Timer *timer = TIMER(u);
+        const char *t;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        t = UNIT_DEREF(timer->unit) ? UNIT_DEREF(timer->unit)->id : "";
+
+        return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM;
+}
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_timer_append_timer_result, timer_result, TimerResult);
+
+static const BusProperty bus_timer_properties[] = {
+        { "Unit",           bus_timer_append_unit,        "s", 0 },
+        { "Timers",         bus_timer_append_timers, "a(stt)", 0 },
+        { "NextElapseUSec", bus_property_append_usec,     "t", offsetof(Timer, next_elapse_monotonic) },
+        { "NextElapseUSecRealtime", bus_property_append_usec, "t", offsetof(Timer, next_elapse_realtime) },
+        { "Result",         bus_timer_append_timer_result,"s", offsetof(Timer, result)      },
+        { NULL, }
+};
+
+DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
+        Timer *t = TIMER(u);
+        const BusBoundProperties bps[] = {
+                { "org.freedesktop.systemd1.Unit",  bus_unit_properties,  u },
+                { "org.freedesktop.systemd1.Timer", bus_timer_properties, t },
+                { NULL, }
+        };
+
+        SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
+
+        return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
+}
diff --git a/src/core/dbus-timer.h b/src/core/dbus-timer.h
new file mode 100644 (file)
index 0000000..9ac3050
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "unit.h"
+
+DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
+
+extern const char bus_timer_interface[];
+extern const char bus_timer_invalidating_properties[];
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
new file mode 100644 (file)
index 0000000..8433a72
--- /dev/null
@@ -0,0 +1,877 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "dbus.h"
+#include "log.h"
+#include "dbus-unit.h"
+#include "bus-errors.h"
+#include "dbus-common.h"
+#include "selinux-access.h"
+
+const char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE;
+
+#define INVALIDATING_PROPERTIES                 \
+        "LoadState\0"                           \
+        "ActiveState\0"                         \
+        "SubState\0"                            \
+        "InactiveExitTimestamp\0"               \
+        "ActiveEnterTimestamp\0"                \
+        "ActiveExitTimestamp\0"                 \
+        "InactiveEnterTimestamp\0"              \
+        "Job\0"                                 \
+        "NeedDaemonReload\0"
+
+static int bus_unit_append_names(DBusMessageIter *i, const char *property, void *data) {
+        char *t;
+        Iterator j;
+        DBusMessageIter sub;
+        Unit *u = data;
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
+                return -ENOMEM;
+
+        SET_FOREACH(t, u->names, j)
+                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t))
+                        return -ENOMEM;
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_following(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data, *f;
+        const char *d;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        f = unit_following(u);
+        d = f ? f->id : "";
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_dependencies(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u;
+        Iterator j;
+        DBusMessageIter sub;
+        Set *s = data;
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
+                return -ENOMEM;
+
+        SET_FOREACH(u, s, j)
+                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &u->id))
+                        return -ENOMEM;
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_description(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        const char *d;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        d = unit_description(u);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_unit_append_load_state, unit_load_state, UnitLoadState);
+
+static int bus_unit_append_active_state(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        const char *state;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        state = unit_active_state_to_string(unit_active_state(u));
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_sub_state(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        const char *state;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        state = unit_sub_state_to_string(u);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_file_state(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        const char *state;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        state = strempty(unit_file_state_to_string(unit_get_unit_file_state(u)));
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_can_start(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        b = unit_can_start(u) &&
+                !u->refuse_manual_start;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_can_stop(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        /* On the lower levels we assume that every unit we can start
+         * we can also stop */
+
+        b = unit_can_start(u) &&
+                !u->refuse_manual_stop;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_can_reload(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        b = unit_can_reload(u);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_can_isolate(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        b = unit_can_isolate(u) &&
+                !u->refuse_manual_start;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_job(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        DBusMessageIter sub;
+        _cleanup_free_ char *p = NULL;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
+                return -ENOMEM;
+
+        if (u->job) {
+
+                p = job_dbus_path(u->job);
+                if (!p)
+                        return -ENOMEM;
+
+                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->job->id) ||
+                    !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p))
+                        return -ENOMEM;
+        } else {
+                uint32_t id = 0;
+
+                /* No job, so let's fill in some placeholder
+                 * data. Since we need to fill in a valid path we
+                 * simple point to ourselves. */
+
+                p = unit_dbus_path(u);
+                if (!p)
+                        return -ENOMEM;
+
+                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &id) ||
+                    !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        char *t;
+        CGroupBonding *cgb;
+        bool success;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        cgb = unit_get_default_cgroup(u);
+        if (cgb) {
+                t = cgroup_bonding_to_string(cgb);
+                if (!t)
+                        return -ENOMEM;
+        } else
+                t = (char*) "";
+
+        success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t);
+
+        if (cgb)
+                free(t);
+
+        return success ? 0 : -ENOMEM;
+}
+
+static int bus_unit_append_cgroups(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        CGroupBonding *cgb;
+        DBusMessageIter sub;
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
+                return -ENOMEM;
+
+        LIST_FOREACH(by_unit, cgb, u->cgroup_bondings) {
+                char _cleanup_free_ *t = NULL;
+                bool success;
+
+                t = cgroup_bonding_to_string(cgb);
+                if (!t)
+                        return -ENOMEM;
+
+                success = dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t);
+                if (!success)
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_cgroup_attrs(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        CGroupAttribute *a;
+        DBusMessageIter sub, sub2;
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sss)", &sub))
+                return -ENOMEM;
+
+        LIST_FOREACH(by_unit, a, u->cgroup_attributes) {
+                char _cleanup_free_ *v = NULL;
+                bool success;
+
+                if (a->map_callback)
+                        a->map_callback(a->controller, a->name, a->value, &v);
+
+                success =
+                        dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) &&
+                        dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->controller) &&
+                        dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->name) &&
+                        dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, v ? &v : &a->value) &&
+                        dbus_message_iter_close_container(&sub, &sub2);
+                if (!success)
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        b = unit_need_daemon_reload(u);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_unit_append_load_error(DBusMessageIter *i, const char *property, void *data) {
+        Unit *u = data;
+        const char *name, *message;
+        DBusMessageIter sub;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        if (u->load_error != 0) {
+                name = bus_errno_to_dbus(u->load_error);
+                message = strempty(strerror(-u->load_error));
+        } else
+                name = message = "";
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &message) ||
+            !dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *connection, DBusMessage *message) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        DBusError error;
+        JobType job_type = _JOB_TYPE_INVALID;
+        bool reload_if_possible = false;
+        int r;
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Start"))
+                job_type = JOB_START;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Stop"))
+                job_type = JOB_STOP;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Reload"))
+                job_type = JOB_RELOAD;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Restart"))
+                job_type = JOB_RESTART;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "TryRestart"))
+                job_type = JOB_TRY_RESTART;
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrRestart")) {
+                reload_if_possible = true;
+                job_type = JOB_RESTART;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrTryRestart")) {
+                reload_if_possible = true;
+                job_type = JOB_TRY_RESTART;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Kill")) {
+                const char *swho;
+                int32_t signo;
+                KillWho who;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &swho,
+                                    DBUS_TYPE_INT32, &signo,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(swho))
+                        who = KILL_ALL;
+                else {
+                        who = kill_who_from_string(swho);
+                        if (who < 0)
+                                return bus_send_error_reply(connection, message, &error, -EINVAL);
+                }
+
+                if (signo <= 0 || signo >= _NSIG)
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop");
+
+                r = unit_kill(u, who, signo, &error);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ResetFailed")) {
+
+                SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "reload");
+
+                unit_reset_failed(u);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (UNIT_VTABLE(u)->bus_message_handler)
+                return UNIT_VTABLE(u)->bus_message_handler(u, connection, message);
+        else
+                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+        if (job_type != _JOB_TYPE_INVALID) {
+                const char *smode;
+                JobMode mode;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &smode,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                mode = job_mode_from_string(smode);
+                if (mode < 0) {
+                        dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode);
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+                }
+
+                return bus_unit_queue_job(connection, message, u, job_type, mode, reload_if_possible);
+        }
+
+        if (reply)
+                if (!dbus_connection_send(connection, reply, NULL))
+                        goto oom;
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        dbus_error_free(&error);
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DBusMessage  *message, void *data) {
+        Manager *m = data;
+        Unit *u;
+        int r;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        DBusError error;
+
+        assert(connection);
+        assert(message);
+        assert(m);
+
+        dbus_error_init(&error);
+
+        if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/unit")) {
+                /* Be nice to gdbus and return introspection data for our mid-level paths */
+
+                SELINUX_ACCESS_CHECK(connection, message, "status");
+
+                if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+                        char *introspection = NULL;
+                        FILE *f;
+                        Iterator i;
+                        const char *k;
+                        size_t size;
+
+                        reply = dbus_message_new_method_return(message);
+                        if (!reply)
+                                goto oom;
+
+                        /* We roll our own introspection code here, instead of
+                         * relying on bus_default_message_handler() because we
+                         * need to generate our introspection string
+                         * dynamically. */
+
+                        f = open_memstream(&introspection, &size);
+                        if (!f)
+                                goto oom;
+
+                        fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+                              "<node>\n", f);
+
+                        fputs(BUS_INTROSPECTABLE_INTERFACE, f);
+                        fputs(BUS_PEER_INTERFACE, f);
+
+                        HASHMAP_FOREACH_KEY(u, k, m->units, i) {
+                                char *p;
+
+                                if (k != u->id)
+                                        continue;
+
+                                p = bus_path_escape(k);
+                                if (!p) {
+                                        fclose(f);
+                                        free(introspection);
+                                        goto oom;
+                                }
+
+                                fprintf(f, "<node name=\"%s\"/>", p);
+                                free(p);
+                        }
+
+                        fputs("</node>\n", f);
+
+                        if (ferror(f)) {
+                                fclose(f);
+                                free(introspection);
+                                goto oom;
+                        }
+
+                        fclose(f);
+
+                        if (!introspection)
+                                goto oom;
+
+                        if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
+                                free(introspection);
+                                goto oom;
+                        }
+
+                        free(introspection);
+
+                        if (!dbus_connection_send(connection, reply, NULL))
+                                goto oom;
+
+                        return DBUS_HANDLER_RESULT_HANDLED;
+                }
+
+                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        }
+
+        r = manager_load_unit_from_dbus_path(m, dbus_message_get_path(message), &error, &u);
+        if (r == -ENOMEM)
+                goto oom;
+        if (r < 0)
+                return bus_send_error_reply(connection, message, &error, r);
+
+        return bus_unit_message_dispatch(u, connection, message);
+
+oom:
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+const DBusObjectPathVTable bus_unit_vtable = {
+        .message_function = bus_unit_message_handler
+};
+
+void bus_unit_send_change_signal(Unit *u) {
+        _cleanup_free_ char *p = NULL;
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL;
+
+        assert(u);
+
+        if (u->in_dbus_queue) {
+                LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
+                u->in_dbus_queue = false;
+        }
+
+        if (!u->id)
+                return;
+
+        if (!bus_has_subscriber(u->manager)) {
+                u->sent_dbus_new_signal = true;
+                return;
+        }
+
+        p = unit_dbus_path(u);
+        if (!p)
+                goto oom;
+
+        if (u->sent_dbus_new_signal) {
+                /* Send a properties changed signal. First for the
+                 * specific type, then for the generic unit. The
+                 * clients may rely on this order to get atomic
+                 * behavior if needed. */
+
+                if (UNIT_VTABLE(u)->bus_invalidating_properties) {
+
+                        m = bus_properties_changed_new(p,
+                                                       UNIT_VTABLE(u)->bus_interface,
+                                                       UNIT_VTABLE(u)->bus_invalidating_properties);
+                        if (!m)
+                                goto oom;
+
+                        if (bus_broadcast(u->manager, m) < 0)
+                                goto oom;
+
+                        dbus_message_unref(m);
+                }
+
+                m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit",
+                                               INVALIDATING_PROPERTIES);
+                if (!m)
+                        goto oom;
+
+        } else {
+                /* Send a new signal */
+
+                m = dbus_message_new_signal("/org/freedesktop/systemd1",
+                                            "org.freedesktop.systemd1.Manager",
+                                            "UnitNew");
+                if (!m)
+                        goto oom;
+
+                if (!dbus_message_append_args(m,
+                                              DBUS_TYPE_STRING, &u->id,
+                                              DBUS_TYPE_OBJECT_PATH, &p,
+                                              DBUS_TYPE_INVALID))
+                        goto oom;
+        }
+
+        if (bus_broadcast(u->manager, m) < 0)
+                goto oom;
+
+        u->sent_dbus_new_signal = true;
+
+        return;
+
+oom:
+        log_oom();
+}
+
+void bus_unit_send_removed_signal(Unit *u) {
+        _cleanup_free_ char *p = NULL;
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL;
+
+        assert(u);
+
+        if (!bus_has_subscriber(u->manager))
+                return;
+
+        if (!u->sent_dbus_new_signal)
+                bus_unit_send_change_signal(u);
+
+        if (!u->id)
+                return;
+
+        p = unit_dbus_path(u);
+        if (!p)
+                goto oom;
+
+        m = dbus_message_new_signal("/org/freedesktop/systemd1",
+                                    "org.freedesktop.systemd1.Manager",
+                                    "UnitRemoved");
+        if (!m)
+                goto oom;
+
+        if (!dbus_message_append_args(m,
+                                      DBUS_TYPE_STRING, &u->id,
+                                      DBUS_TYPE_OBJECT_PATH, &p,
+                                      DBUS_TYPE_INVALID))
+                goto oom;
+
+        if (bus_broadcast(u->manager, m) < 0)
+                goto oom;
+
+        return;
+
+oom:
+        log_oom();
+}
+
+DBusHandlerResult bus_unit_queue_job(
+                DBusConnection *connection,
+                DBusMessage *message,
+                Unit *u,
+                JobType type,
+                JobMode mode,
+                bool reload_if_possible) {
+
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        _cleanup_free_ char *path = NULL;
+        Job *j;
+        JobBusClient *cl;
+        DBusError error;
+        int r;
+
+        assert(connection);
+        assert(message);
+        assert(u);
+        assert(type >= 0 && type < _JOB_TYPE_MAX);
+        assert(mode >= 0 && mode < _JOB_MODE_MAX);
+
+        dbus_error_init(&error);
+
+        if (reload_if_possible && unit_can_reload(u)) {
+                if (type == JOB_RESTART)
+                        type = JOB_RELOAD_OR_START;
+                else if (type == JOB_TRY_RESTART)
+                        type = JOB_RELOAD;
+        }
+
+        SELINUX_UNIT_ACCESS_CHECK(u, connection, message,
+                                  (type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" :
+                                  type == JOB_STOP ? "stop" : "reload");
+
+        if (type == JOB_STOP && u->load_state == UNIT_ERROR && unit_active_state(u) == UNIT_INACTIVE) {
+                dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
+                return bus_send_error_reply(connection, message, &error, -EPERM);
+        }
+
+        if ((type == JOB_START && u->refuse_manual_start) ||
+            (type == JOB_STOP && u->refuse_manual_stop) ||
+            ((type == JOB_RESTART || type == JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop))) {
+                dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY,
+                               "Operation refused, unit %s may be requested by dependency only.", u->id);
+                return bus_send_error_reply(connection, message, &error, -EPERM);
+        }
+
+        r = manager_add_job(u->manager, type, u, mode, true, &error, &j);
+        if (r < 0)
+                return bus_send_error_reply(connection, message, &error, r);
+
+        cl = job_bus_client_new(connection, bus_message_get_sender_with_fallback(message));
+        if (!cl)
+                goto oom;
+
+        LIST_PREPEND(JobBusClient, client, j->bus_client_list, cl);
+
+        reply = dbus_message_new_method_return(message);
+        if (!reply)
+                goto oom;
+
+        path = job_dbus_path(j);
+        if (!path)
+                goto oom;
+
+        if (!dbus_message_append_args(
+                            reply,
+                            DBUS_TYPE_OBJECT_PATH, &path,
+                            DBUS_TYPE_INVALID))
+                goto oom;
+
+        if (!dbus_connection_send(connection, reply, NULL))
+                goto oom;
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+const BusProperty bus_unit_properties[] = {
+        { "Id",                   bus_property_append_string,         "s", offsetof(Unit, id),                                         true },
+        { "Names",                bus_unit_append_names,             "as", 0 },
+        { "Following",            bus_unit_append_following,          "s", 0 },
+        { "Requires",             bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUIRES]),                true },
+        { "RequiresOverridable",  bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]),    true },
+        { "Requisite",            bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUISITE]),               true },
+        { "RequisiteOverridable", bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]),   true },
+        { "Wants",                bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_WANTS]),                   true },
+        { "BindsTo",              bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_BINDS_TO]),                true },
+        { "PartOf",               bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_PART_OF]),                 true },
+        { "RequiredBy",           bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]),             true },
+        { "RequiredByOverridable",bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true },
+        { "WantedBy",             bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]),               true },
+        { "BoundBy",              bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]),                true },
+        { "ConsistsOf",           bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_CONSISTS_OF]),             true },
+        { "Conflicts",            bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]),               true },
+        { "ConflictedBy",         bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]),           true },
+        { "Before",               bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_BEFORE]),                  true },
+        { "After",                bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_AFTER]),                   true },
+        { "OnFailure",            bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]),              true },
+        { "Triggers",             bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]),                true },
+        { "TriggeredBy",          bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]),            true },
+        { "PropagatesReloadTo",   bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]),    true },
+        { "ReloadPropagatedFrom", bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]),  true },
+        { "RequiresMountsFor",    bus_property_append_strv,          "as", offsetof(Unit, requires_mounts_for),                        true },
+        { "Documentation",        bus_property_append_strv,          "as", offsetof(Unit, documentation),                              true },
+        { "Description",          bus_unit_append_description,        "s", 0 },
+        { "LoadState",            bus_unit_append_load_state,         "s", offsetof(Unit, load_state)                         },
+        { "ActiveState",          bus_unit_append_active_state,       "s", 0 },
+        { "SubState",             bus_unit_append_sub_state,          "s", 0 },
+        { "FragmentPath",         bus_property_append_string,         "s", offsetof(Unit, fragment_path),                              true },
+        { "SourcePath",           bus_property_append_string,         "s", offsetof(Unit, source_path),                                true },
+        { "UnitFileState",        bus_unit_append_file_state,         "s", 0 },
+        { "InactiveExitTimestamp",bus_property_append_usec,           "t", offsetof(Unit, inactive_exit_timestamp.realtime)   },
+        { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic)  },
+        { "ActiveEnterTimestamp", bus_property_append_usec,           "t", offsetof(Unit, active_enter_timestamp.realtime)    },
+        { "ActiveEnterTimestampMonotonic", bus_property_append_usec,  "t", offsetof(Unit, active_enter_timestamp.monotonic)   },
+        { "ActiveExitTimestamp",  bus_property_append_usec,           "t", offsetof(Unit, active_exit_timestamp.realtime)     },
+        { "ActiveExitTimestampMonotonic",  bus_property_append_usec,  "t", offsetof(Unit, active_exit_timestamp.monotonic)    },
+        { "InactiveEnterTimestamp", bus_property_append_usec,         "t", offsetof(Unit, inactive_enter_timestamp.realtime)  },
+        { "InactiveEnterTimestampMonotonic",bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) },
+        { "CanStart",             bus_unit_append_can_start,          "b", 0 },
+        { "CanStop",              bus_unit_append_can_stop,           "b", 0 },
+        { "CanReload",            bus_unit_append_can_reload,         "b", 0 },
+        { "CanIsolate",           bus_unit_append_can_isolate,        "b", 0 },
+        { "Job",                  bus_unit_append_job,             "(uo)", 0 },
+        { "StopWhenUnneeded",     bus_property_append_bool,           "b", offsetof(Unit, stop_when_unneeded)                 },
+        { "RefuseManualStart",    bus_property_append_bool,           "b", offsetof(Unit, refuse_manual_start)                },
+        { "RefuseManualStop",     bus_property_append_bool,           "b", offsetof(Unit, refuse_manual_stop)                 },
+        { "AllowIsolate",         bus_property_append_bool,           "b", offsetof(Unit, allow_isolate)                      },
+        { "DefaultDependencies",  bus_property_append_bool,           "b", offsetof(Unit, default_dependencies)               },
+        { "OnFailureIsolate",     bus_property_append_bool,           "b", offsetof(Unit, on_failure_isolate)                 },
+        { "IgnoreOnIsolate",      bus_property_append_bool,           "b", offsetof(Unit, ignore_on_isolate)                  },
+        { "IgnoreOnSnapshot",     bus_property_append_bool,           "b", offsetof(Unit, ignore_on_snapshot)                 },
+        { "DefaultControlGroup",  bus_unit_append_default_cgroup,     "s", 0 },
+        { "ControlGroup",         bus_unit_append_cgroups,           "as", 0 },
+        { "ControlGroupAttributes", bus_unit_append_cgroup_attrs,"a(sss)", 0 },
+        { "NeedDaemonReload",     bus_unit_append_need_daemon_reload, "b", 0 },
+        { "JobTimeoutUSec",       bus_property_append_usec,           "t", offsetof(Unit, job_timeout)                        },
+        { "ConditionTimestamp",   bus_property_append_usec,           "t", offsetof(Unit, condition_timestamp.realtime)       },
+        { "ConditionTimestampMonotonic", bus_property_append_usec,    "t", offsetof(Unit, condition_timestamp.monotonic)      },
+        { "ConditionResult",      bus_property_append_bool,           "b", offsetof(Unit, condition_result)                   },
+        { "LoadError",            bus_unit_append_load_error,      "(ss)", 0 },
+        { NULL, }
+};
diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h
new file mode 100644 (file)
index 0000000..ac6785a
--- /dev/null
@@ -0,0 +1,147 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "manager.h"
+#include "dbus-common.h"
+
+#define BUS_UNIT_INTERFACE \
+        " <interface name=\"org.freedesktop.systemd1.Unit\">\n"         \
+        "  <method name=\"Start\">\n"                                   \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"Stop\">\n"                                    \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"Reload\">\n"                                  \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"Restart\">\n"                                 \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"TryRestart\">\n"                              \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReloadOrRestart\">\n"                         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReloadOrTryRestart\">\n"                      \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"Kill\">\n"                                    \
+        "   <arg name=\"who\" type=\"s\" direction=\"in\"/>\n"          \
+        "   <arg name=\"signal\" type=\"i\" direction=\"in\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"ResetFailed\"/>\n"                            \
+        "  <property name=\"Id\" type=\"s\" access=\"read\"/>\n"        \
+        "  <property name=\"Names\" type=\"as\" access=\"read\"/>\n"    \
+        "  <property name=\"Following\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"Requires\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"RequiresOverridable\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"Requisite\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"RequisiteOverridable\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"Wants\" type=\"as\" access=\"read\"/>\n"    \
+        "  <property name=\"BindsTo\" type=\"as\" access=\"read\"/>\n"    \
+        "  <property name=\"RequiredBy\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"RequiredByOverridable\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"WantedBy\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"BoundBy\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"Conflicts\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"ConflictedBy\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"Before\" type=\"as\" access=\"read\"/>\n"   \
+        "  <property name=\"After\" type=\"as\" access=\"read\"/>\n"    \
+        "  <property name=\"OnFailure\" type=\"as\" access=\"read\"/>\n"    \
+        "  <property name=\"Triggers\" type=\"as\" access=\"read\"/>\n"    \
+        "  <property name=\"TriggeredBy\" type=\"as\" access=\"read\"/>\n"    \
+        "  <property name=\"PropagatesReloadTo\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"ReloadPropagatedFrom\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"RequiresMountsFor\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"SourcePath\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"Documentation\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"SubState\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"FragmentPath\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"UnitFileState\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"InactiveExitTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"InactiveExitTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"ActiveEnterTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"ActiveEnterTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"ActiveExitTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"ActiveExitTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"InactiveEnterTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"InactiveEnterTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"CanStart\" type=\"b\" access=\"read\"/>\n"  \
+        "  <property name=\"CanStop\" type=\"b\" access=\"read\"/>\n"   \
+        "  <property name=\"CanReload\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"CanIsolate\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"Job\" type=\"(uo)\" access=\"read\"/>\n"    \
+        "  <property name=\"StopWhenUnneeded\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"RefuseManualStart\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"RefuseManualStop\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"AllowIsolate\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"DefaultDependencies\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"OnFailureIsolate\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"IgnoreOnIsolate\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"IgnoreOnSnapshot\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"DefaultControlGroup\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"ControlGroup\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"ControlGroupAttributes\" type=\"a(sss)\" access=\"read\"/>\n" \
+        "  <property name=\"NeedDaemonReload\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"JobTimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"ConditionTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"ConditionTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"ConditionResult\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"LoadError\" type=\"(ss)\" access=\"read\"/>\n" \
+        " </interface>\n"
+
+#define BUS_UNIT_INTERFACES_LIST                \
+        BUS_GENERIC_INTERFACES_LIST             \
+        "org.freedesktop.systemd1.Unit\0"
+
+extern const BusProperty bus_unit_properties[];
+
+void bus_unit_send_change_signal(Unit *u);
+void bus_unit_send_removed_signal(Unit *u);
+
+
+DBusHandlerResult bus_unit_queue_job(
+                DBusConnection *connection,
+                DBusMessage *message,
+                Unit *u,
+                JobType type,
+                JobMode mode,
+                bool reload_if_possible);
+
+extern const DBusObjectPathVTable bus_unit_vtable;
+
+extern const char bus_unit_interface[];
diff --git a/src/core/dbus.c b/src/core/dbus.c
new file mode 100644 (file)
index 0000000..2a1c660
--- /dev/null
@@ -0,0 +1,1479 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <dbus/dbus.h>
+
+#include "dbus.h"
+#include "log.h"
+#include "strv.h"
+#include "cgroup.h"
+#include "mkdir.h"
+#include "missing.h"
+#include "dbus-unit.h"
+#include "dbus-job.h"
+#include "dbus-manager.h"
+#include "dbus-service.h"
+#include "dbus-socket.h"
+#include "dbus-target.h"
+#include "dbus-device.h"
+#include "dbus-mount.h"
+#include "dbus-automount.h"
+#include "dbus-snapshot.h"
+#include "dbus-swap.h"
+#include "dbus-timer.h"
+#include "dbus-path.h"
+#include "bus-errors.h"
+#include "special.h"
+#include "dbus-common.h"
+
+#define CONNECTIONS_MAX 52
+
+/* Well-known address (http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types) */
+#define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
+/* Only used as a fallback */
+#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:"
+
+static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE;
+static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE;
+
+const char *const bus_interface_table[] = {
+        "org.freedesktop.DBus.Properties",     bus_properties_interface,
+        "org.freedesktop.DBus.Introspectable", bus_introspectable_interface,
+        "org.freedesktop.systemd1.Manager",    bus_manager_interface,
+        "org.freedesktop.systemd1.Job",        bus_job_interface,
+        "org.freedesktop.systemd1.Unit",       bus_unit_interface,
+        "org.freedesktop.systemd1.Service",    bus_service_interface,
+        "org.freedesktop.systemd1.Socket",     bus_socket_interface,
+        "org.freedesktop.systemd1.Target",     bus_target_interface,
+        "org.freedesktop.systemd1.Device",     bus_device_interface,
+        "org.freedesktop.systemd1.Mount",      bus_mount_interface,
+        "org.freedesktop.systemd1.Automount",  bus_automount_interface,
+        "org.freedesktop.systemd1.Snapshot",   bus_snapshot_interface,
+        "org.freedesktop.systemd1.Swap",       bus_swap_interface,
+        "org.freedesktop.systemd1.Timer",      bus_timer_interface,
+        "org.freedesktop.systemd1.Path",       bus_path_interface,
+        NULL
+};
+
+static void bus_done_api(Manager *m);
+static void bus_done_system(Manager *m);
+static void bus_done_private(Manager *m);
+static void shutdown_connection(Manager *m, DBusConnection *c);
+
+static void bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data)  {
+        Manager *m = data;
+
+        assert(bus);
+        assert(m);
+
+        /* We maintain two sets, one for those connections where we
+         * requested a dispatch, and another where we didn't. And then,
+         * we move the connections between the two sets. */
+
+        if (status == DBUS_DISPATCH_COMPLETE)
+                set_move_one(m->bus_connections, m->bus_connections_for_dispatch, bus);
+        else
+                set_move_one(m->bus_connections_for_dispatch, m->bus_connections, bus);
+}
+
+void bus_watch_event(Manager *m, Watch *w, int events) {
+        assert(m);
+        assert(w);
+
+        /* This is called by the event loop whenever there is
+         * something happening on D-Bus' file handles. */
+
+        if (!dbus_watch_get_enabled(w->data.bus_watch))
+                return;
+
+        dbus_watch_handle(w->data.bus_watch, bus_events_to_flags(events));
+}
+
+static dbus_bool_t bus_add_watch(DBusWatch *bus_watch, void *data) {
+        Manager *m = data;
+        Watch *w;
+        struct epoll_event ev;
+
+        assert(bus_watch);
+        assert(m);
+
+        if (!(w = new0(Watch, 1)))
+                return FALSE;
+
+        w->fd = dbus_watch_get_unix_fd(bus_watch);
+        w->type = WATCH_DBUS_WATCH;
+        w->data.bus_watch = bus_watch;
+
+        zero(ev);
+        ev.events = bus_flags_to_events(bus_watch);
+        ev.data.ptr = w;
+
+        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) {
+
+                if (errno != EEXIST) {
+                        free(w);
+                        return FALSE;
+                }
+
+                /* Hmm, bloody D-Bus creates multiple watches on the
+                 * same fd. epoll() does not like that. As a dirty
+                 * hack we simply dup() the fd and hence get a second
+                 * one we can safely add to the epoll(). */
+
+                if ((w->fd = dup(w->fd)) < 0) {
+                        free(w);
+                        return FALSE;
+                }
+
+                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) {
+                        close_nointr_nofail(w->fd);
+                        free(w);
+                        return FALSE;
+                }
+
+                w->fd_is_dupped = true;
+        }
+
+        dbus_watch_set_data(bus_watch, w, NULL);
+
+        return TRUE;
+}
+
+static void bus_remove_watch(DBusWatch *bus_watch, void *data) {
+        Manager *m = data;
+        Watch *w;
+
+        assert(bus_watch);
+        assert(m);
+
+        w = dbus_watch_get_data(bus_watch);
+        if (!w)
+                return;
+
+        assert(w->type == WATCH_DBUS_WATCH);
+        assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
+
+        if (w->fd_is_dupped)
+                close_nointr_nofail(w->fd);
+
+        free(w);
+}
+
+static void bus_toggle_watch(DBusWatch *bus_watch, void *data) {
+        Manager *m = data;
+        Watch *w;
+        struct epoll_event ev;
+
+        assert(bus_watch);
+        assert(m);
+
+        w = dbus_watch_get_data(bus_watch);
+        if (!w)
+                return;
+
+        assert(w->type == WATCH_DBUS_WATCH);
+
+        zero(ev);
+        ev.events = bus_flags_to_events(bus_watch);
+        ev.data.ptr = w;
+
+        assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_MOD, w->fd, &ev) == 0);
+}
+
+static int bus_timeout_arm(Manager *m, Watch *w) {
+        struct itimerspec its;
+
+        assert(m);
+        assert(w);
+
+        zero(its);
+
+        if (dbus_timeout_get_enabled(w->data.bus_timeout)) {
+                timespec_store(&its.it_value, dbus_timeout_get_interval(w->data.bus_timeout) * USEC_PER_MSEC);
+                its.it_interval = its.it_value;
+        }
+
+        if (timerfd_settime(w->fd, 0, &its, NULL) < 0)
+                return -errno;
+
+        return 0;
+}
+
+void bus_timeout_event(Manager *m, Watch *w, int events) {
+        assert(m);
+        assert(w);
+
+        /* This is called by the event loop whenever there is
+         * something happening on D-Bus' file handles. */
+
+        if (!(dbus_timeout_get_enabled(w->data.bus_timeout)))
+                return;
+
+        dbus_timeout_handle(w->data.bus_timeout);
+}
+
+static dbus_bool_t bus_add_timeout(DBusTimeout *timeout, void *data) {
+        Manager *m = data;
+        Watch *w;
+        struct epoll_event ev;
+
+        assert(timeout);
+        assert(m);
+
+        if (!(w = new0(Watch, 1)))
+                return FALSE;
+
+        if ((w->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
+                goto fail;
+
+        w->type = WATCH_DBUS_TIMEOUT;
+        w->data.bus_timeout = timeout;
+
+        if (bus_timeout_arm(m, w) < 0)
+                goto fail;
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.ptr = w;
+
+        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0)
+                goto fail;
+
+        dbus_timeout_set_data(timeout, w, NULL);
+
+        return TRUE;
+
+fail:
+        if (w->fd >= 0)
+                close_nointr_nofail(w->fd);
+
+        free(w);
+        return FALSE;
+}
+
+static void bus_remove_timeout(DBusTimeout *timeout, void *data) {
+        Manager *m = data;
+        Watch *w;
+
+        assert(timeout);
+        assert(m);
+
+        w = dbus_timeout_get_data(timeout);
+        if (!w)
+                return;
+
+        assert(w->type == WATCH_DBUS_TIMEOUT);
+
+        assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
+        close_nointr_nofail(w->fd);
+        free(w);
+}
+
+static void bus_toggle_timeout(DBusTimeout *timeout, void *data) {
+        Manager *m = data;
+        Watch *w;
+        int r;
+
+        assert(timeout);
+        assert(m);
+
+        w = dbus_timeout_get_data(timeout);
+        if (!w)
+                return;
+
+        assert(w->type == WATCH_DBUS_TIMEOUT);
+
+        if ((r = bus_timeout_arm(m, w)) < 0)
+                log_error("Failed to rearm timer: %s", strerror(-r));
+}
+
+static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
+        Manager *m = data;
+        DBusError error;
+        DBusMessage *reply = NULL;
+
+        assert(connection);
+        assert(message);
+        assert(m);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
+            dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
+                log_debug("Got D-Bus request: %s.%s() on %s",
+                          dbus_message_get_interface(message),
+                          dbus_message_get_member(message),
+                          dbus_message_get_path(message));
+
+        if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
+                log_debug("API D-Bus connection terminated.");
+                bus_done_api(m);
+
+        } else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
+                const char *name, *old_owner, *new_owner;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_STRING, &name,
+                                           DBUS_TYPE_STRING, &old_owner,
+                                           DBUS_TYPE_STRING, &new_owner,
+                                           DBUS_TYPE_INVALID))
+                        log_error("Failed to parse NameOwnerChanged message: %s", bus_error_message(&error));
+                else  {
+                        if (set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) name))
+                                log_debug("Subscription client vanished: %s (left: %u)", name, set_size(BUS_CONNECTION_SUBSCRIBED(m, connection)));
+
+                        if (old_owner[0] == 0)
+                                old_owner = NULL;
+
+                        if (new_owner[0] == 0)
+                                new_owner = NULL;
+
+                        manager_dispatch_bus_name_owner_changed(m, name, old_owner, new_owner);
+                }
+        } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Activator", "ActivationRequest")) {
+                const char *name;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_STRING, &name,
+                                           DBUS_TYPE_INVALID))
+                        log_error("Failed to parse ActivationRequest message: %s", bus_error_message(&error));
+                else  {
+                        int r;
+                        Unit *u;
+
+                        log_debug("Got D-Bus activation request for %s", name);
+
+                        if (manager_unit_pending_inactive(m, SPECIAL_DBUS_SERVICE) ||
+                            manager_unit_pending_inactive(m, SPECIAL_DBUS_SOCKET)) {
+                                r = -EADDRNOTAVAIL;
+                                dbus_set_error(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
+                        } else {
+                                r = manager_load_unit(m, name, NULL, &error, &u);
+
+                                if (r >= 0 && u->refuse_manual_start)
+                                        r = -EPERM;
+
+                                if (r >= 0)
+                                        r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
+                        }
+
+                        if (r < 0) {
+                                const char *id, *text;
+
+                                log_debug("D-Bus activation failed for %s: %s", name, strerror(-r));
+
+                                if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure")))
+                                        goto oom;
+
+                                id = error.name ? error.name : bus_errno_to_dbus(r);
+                                text = bus_error(&error, r);
+
+                                if (!dbus_message_set_destination(reply, DBUS_SERVICE_DBUS) ||
+                                    !dbus_message_append_args(reply,
+                                                              DBUS_TYPE_STRING, &name,
+                                                              DBUS_TYPE_STRING, &id,
+                                                              DBUS_TYPE_STRING, &text,
+                                                              DBUS_TYPE_INVALID))
+                                        goto oom;
+                        }
+
+                        /* On success we don't do anything, the service will be spawned now */
+                }
+        }
+
+        dbus_error_free(&error);
+
+        if (reply) {
+                if (!dbus_connection_send(connection, reply, NULL))
+                        goto oom;
+
+                dbus_message_unref(reply);
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
+        Manager *m = data;
+        DBusError error;
+
+        assert(connection);
+        assert(message);
+        assert(m);
+
+        dbus_error_init(&error);
+
+        if (m->api_bus != m->system_bus &&
+            (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
+             dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL))
+                log_debug("Got D-Bus request on system bus: %s.%s() on %s",
+                          dbus_message_get_interface(message),
+                          dbus_message_get_member(message),
+                          dbus_message_get_path(message));
+
+        if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
+                log_debug("System D-Bus connection terminated.");
+                bus_done_system(m);
+
+        } else if (m->running_as != SYSTEMD_SYSTEM &&
+                   dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
+
+                const char *cgroup;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_STRING, &cgroup,
+                                           DBUS_TYPE_INVALID))
+                        log_error("Failed to parse Released message: %s", bus_error_message(&error));
+                else
+                        cgroup_notify_empty(m, cgroup);
+        }
+
+        dbus_error_free(&error);
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
+        Manager *m = data;
+        DBusError error;
+
+        assert(connection);
+        assert(message);
+        assert(m);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
+            dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
+                log_debug("Got D-Bus request: %s.%s() on %s",
+                          dbus_message_get_interface(message),
+                          dbus_message_get_member(message),
+                          dbus_message_get_path(message));
+
+        if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected"))
+                shutdown_connection(m, connection);
+        else if (m->running_as == SYSTEMD_SYSTEM &&
+                 dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
+
+                const char *cgroup;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_STRING, &cgroup,
+                                           DBUS_TYPE_INVALID))
+                        log_error("Failed to parse Released message: %s", bus_error_message(&error));
+                else
+                        cgroup_notify_empty(m, cgroup);
+
+                /* Forward the message to the system bus, so that user
+                 * instances are notified as well */
+
+                if (m->system_bus)
+                        dbus_connection_send(m->system_bus, message, NULL);
+        }
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+unsigned bus_dispatch(Manager *m) {
+        DBusConnection *c;
+
+        assert(m);
+
+        if (m->queued_message) {
+                /* If we cannot get rid of this message we won't
+                 * dispatch any D-Bus messages, so that we won't end
+                 * up wanting to queue another message. */
+
+                if (m->queued_message_connection)
+                        if (!dbus_connection_send(m->queued_message_connection, m->queued_message, NULL))
+                                return 0;
+
+                dbus_message_unref(m->queued_message);
+                m->queued_message = NULL;
+                m->queued_message_connection = NULL;
+        }
+
+        if ((c = set_first(m->bus_connections_for_dispatch))) {
+                if (dbus_connection_dispatch(c) == DBUS_DISPATCH_COMPLETE)
+                        set_move_one(m->bus_connections, m->bus_connections_for_dispatch, c);
+
+                return 1;
+        }
+
+        return 0;
+}
+
+static void request_name_pending_cb(DBusPendingCall *pending, void *userdata) {
+        DBusMessage *reply;
+        DBusError error;
+
+        dbus_error_init(&error);
+
+        assert_se(reply = dbus_pending_call_steal_reply(pending));
+
+        switch (dbus_message_get_type(reply)) {
+
+        case DBUS_MESSAGE_TYPE_ERROR:
+
+                assert_se(dbus_set_error_from_message(&error, reply));
+                log_warning("RequestName() failed: %s", bus_error_message(&error));
+                break;
+
+        case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
+                uint32_t r;
+
+                if (!dbus_message_get_args(reply,
+                                           &error,
+                                           DBUS_TYPE_UINT32, &r,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse RequestName() reply: %s", bus_error_message(&error));
+                        break;
+                }
+
+                if (r == 1)
+                        log_debug("Successfully acquired name.");
+                else
+                        log_error("Name already owned.");
+
+                break;
+        }
+
+        default:
+                assert_not_reached("Invalid reply message");
+        }
+
+        dbus_message_unref(reply);
+        dbus_error_free(&error);
+}
+
+static int request_name(Manager *m) {
+        const char *name = "org.freedesktop.systemd1";
+        /* Allow replacing of our name, to ease implementation of
+         * reexecution, where we keep the old connection open until
+         * after the new connection is set up and the name installed
+         * to allow clients to synchronously wait for reexecution to
+         * finish */
+        uint32_t flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT|DBUS_NAME_FLAG_REPLACE_EXISTING;
+        DBusMessage *message = NULL;
+        DBusPendingCall *pending = NULL;
+
+        if (!(message = dbus_message_new_method_call(
+                              DBUS_SERVICE_DBUS,
+                              DBUS_PATH_DBUS,
+                              DBUS_INTERFACE_DBUS,
+                              "RequestName")))
+                goto oom;
+
+        if (!dbus_message_append_args(
+                            message,
+                            DBUS_TYPE_STRING, &name,
+                            DBUS_TYPE_UINT32, &flags,
+                            DBUS_TYPE_INVALID))
+                goto oom;
+
+        if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
+                goto oom;
+
+        if (!dbus_pending_call_set_notify(pending, request_name_pending_cb, m, NULL))
+                goto oom;
+
+        dbus_message_unref(message);
+        dbus_pending_call_unref(pending);
+
+        /* We simple ask for the name and don't wait for it. Sooner or
+         * later we'll have it. */
+
+        return 0;
+
+oom:
+        if (pending) {
+                dbus_pending_call_cancel(pending);
+                dbus_pending_call_unref(pending);
+        }
+
+        if (message)
+                dbus_message_unref(message);
+
+        return -ENOMEM;
+}
+
+static void query_name_list_pending_cb(DBusPendingCall *pending, void *userdata) {
+        DBusMessage *reply;
+        DBusError error;
+        Manager *m = userdata;
+
+        assert(m);
+
+        dbus_error_init(&error);
+
+        assert_se(reply = dbus_pending_call_steal_reply(pending));
+
+        switch (dbus_message_get_type(reply)) {
+
+        case DBUS_MESSAGE_TYPE_ERROR:
+
+                assert_se(dbus_set_error_from_message(&error, reply));
+                log_warning("ListNames() failed: %s", bus_error_message(&error));
+                break;
+
+        case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
+                int r;
+                char **l;
+
+                if ((r = bus_parse_strv(reply, &l)) < 0)
+                        log_warning("Failed to parse ListNames() reply: %s", strerror(-r));
+                else {
+                        char **t;
+
+                        STRV_FOREACH(t, l)
+                                /* This is a bit hacky, we say the
+                                 * owner of the name is the name
+                                 * itself, because we don't want the
+                                 * extra traffic to figure out the
+                                 * real owner. */
+                                manager_dispatch_bus_name_owner_changed(m, *t, NULL, *t);
+
+                        strv_free(l);
+                }
+
+                break;
+        }
+
+        default:
+                assert_not_reached("Invalid reply message");
+        }
+
+        dbus_message_unref(reply);
+        dbus_error_free(&error);
+}
+
+static int query_name_list(Manager *m) {
+        DBusMessage *message = NULL;
+        DBusPendingCall *pending = NULL;
+
+        /* Asks for the currently installed bus names */
+
+        if (!(message = dbus_message_new_method_call(
+                              DBUS_SERVICE_DBUS,
+                              DBUS_PATH_DBUS,
+                              DBUS_INTERFACE_DBUS,
+                              "ListNames")))
+                goto oom;
+
+        if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
+                goto oom;
+
+        if (!dbus_pending_call_set_notify(pending, query_name_list_pending_cb, m, NULL))
+                goto oom;
+
+        dbus_message_unref(message);
+        dbus_pending_call_unref(pending);
+
+        /* We simple ask for the list and don't wait for it. Sooner or
+         * later we'll get it. */
+
+        return 0;
+
+oom:
+        if (pending) {
+                dbus_pending_call_cancel(pending);
+                dbus_pending_call_unref(pending);
+        }
+
+        if (message)
+                dbus_message_unref(message);
+
+        return -ENOMEM;
+}
+
+static int bus_setup_loop(Manager *m, DBusConnection *bus) {
+        assert(m);
+        assert(bus);
+
+        dbus_connection_set_exit_on_disconnect(bus, FALSE);
+
+        if (!dbus_connection_set_watch_functions(bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) ||
+            !dbus_connection_set_timeout_functions(bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL))
+                return log_oom();
+
+        if (set_put(m->bus_connections_for_dispatch, bus) < 0)
+                return log_oom();
+
+        dbus_connection_set_dispatch_status_function(bus, bus_dispatch_status, m, NULL);
+        return 0;
+}
+
+static dbus_bool_t allow_only_same_user(DBusConnection *connection, unsigned long uid, void *data) {
+        return uid == 0 || uid == geteuid();
+}
+
+static void bus_new_connection(
+                DBusServer *server,
+                DBusConnection *new_connection,
+                void *data) {
+
+        Manager *m = data;
+
+        assert(m);
+
+        if (set_size(m->bus_connections) >= CONNECTIONS_MAX) {
+                log_error("Too many concurrent connections.");
+                return;
+        }
+
+        dbus_connection_set_unix_user_function(new_connection, allow_only_same_user, NULL, NULL);
+
+        if (bus_setup_loop(m, new_connection) < 0)
+                return;
+
+        if (!dbus_connection_register_object_path(new_connection, "/org/freedesktop/systemd1", &bus_manager_vtable, m) ||
+            !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) ||
+            !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) ||
+            !dbus_connection_add_filter(new_connection, private_bus_message_filter, m, NULL)) {
+                log_oom();
+                return;
+        }
+
+        log_debug("Accepted connection on private bus.");
+
+        dbus_connection_ref(new_connection);
+}
+
+static int init_registered_system_bus(Manager *m) {
+        char *id;
+
+        if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL))
+                return log_oom();
+
+        if (m->running_as != SYSTEMD_SYSTEM) {
+                DBusError error;
+
+                dbus_error_init(&error);
+
+                dbus_bus_add_match(m->system_bus,
+                                   "type='signal',"
+                                   "interface='org.freedesktop.systemd1.Agent',"
+                                   "member='Released',"
+                                   "path='/org/freedesktop/systemd1/agent'",
+                                   &error);
+
+                if (dbus_error_is_set(&error)) {
+                        log_error("Failed to register match: %s", bus_error_message(&error));
+                        dbus_error_free(&error);
+                        return -1;
+                }
+        }
+
+        log_debug("Successfully connected to system D-Bus bus %s as %s",
+                 strnull((id = dbus_connection_get_server_id(m->system_bus))),
+                 strnull(dbus_bus_get_unique_name(m->system_bus)));
+        dbus_free(id);
+
+        return 0;
+}
+
+static int init_registered_api_bus(Manager *m) {
+        int r;
+
+        if (!dbus_connection_register_object_path(m->api_bus, "/org/freedesktop/systemd1", &bus_manager_vtable, m) ||
+            !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) ||
+            !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) ||
+            !dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL))
+                return log_oom();
+
+        /* Get NameOwnerChange messages */
+        dbus_bus_add_match(m->api_bus,
+                           "type='signal',"
+                           "sender='"DBUS_SERVICE_DBUS"',"
+                           "interface='"DBUS_INTERFACE_DBUS"',"
+                           "member='NameOwnerChanged',"
+                           "path='"DBUS_PATH_DBUS"'",
+                           NULL);
+
+        /* Get activation requests */
+        dbus_bus_add_match(m->api_bus,
+                           "type='signal',"
+                           "sender='"DBUS_SERVICE_DBUS"',"
+                           "interface='org.freedesktop.systemd1.Activator',"
+                           "member='ActivationRequest',"
+                           "path='"DBUS_PATH_DBUS"'",
+                           NULL);
+
+        r = request_name(m);
+        if (r < 0)
+                return r;
+
+        r = query_name_list(m);
+        if (r < 0)
+                return r;
+
+        if (m->running_as == SYSTEMD_USER) {
+                char *id;
+                log_debug("Successfully connected to API D-Bus bus %s as %s",
+                         strnull((id = dbus_connection_get_server_id(m->api_bus))),
+                         strnull(dbus_bus_get_unique_name(m->api_bus)));
+                dbus_free(id);
+        } else
+                log_debug("Successfully initialized API on the system bus");
+
+        return 0;
+}
+
+static void bus_register_cb(DBusPendingCall *pending, void *userdata) {
+        Manager *m = userdata;
+        DBusConnection **conn;
+        DBusMessage *reply;
+        DBusError error;
+        const char *name;
+        int r = 0;
+
+        dbus_error_init(&error);
+
+        conn = dbus_pending_call_get_data(pending, m->conn_data_slot);
+        assert(conn == &m->system_bus || conn == &m->api_bus);
+
+        reply = dbus_pending_call_steal_reply(pending);
+
+        switch (dbus_message_get_type(reply)) {
+        case DBUS_MESSAGE_TYPE_ERROR:
+                assert_se(dbus_set_error_from_message(&error, reply));
+                log_warning("Failed to register to bus: %s", bus_error_message(&error));
+                r = -1;
+                break;
+        case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+                if (!dbus_message_get_args(reply, &error,
+                                           DBUS_TYPE_STRING, &name,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse Hello reply: %s", bus_error_message(&error));
+                        r = -1;
+                        break;
+                }
+
+                log_debug("Received name %s in reply to Hello", name);
+                if (!dbus_bus_set_unique_name(*conn, name)) {
+                        log_error("Failed to set unique name");
+                        r = -1;
+                        break;
+                }
+
+                if (conn == &m->system_bus) {
+                        r = init_registered_system_bus(m);
+                        if (r == 0 && m->running_as == SYSTEMD_SYSTEM)
+                                r = init_registered_api_bus(m);
+                } else
+                        r = init_registered_api_bus(m);
+
+                break;
+        default:
+                assert_not_reached("Invalid reply message");
+        }
+
+        dbus_message_unref(reply);
+        dbus_error_free(&error);
+
+        if (r < 0) {
+                if (conn == &m->system_bus) {
+                        log_debug("Failed setting up the system bus");
+                        bus_done_system(m);
+                } else {
+                        log_debug("Failed setting up the API bus");
+                        bus_done_api(m);
+                }
+        }
+}
+
+static int manager_bus_async_register(Manager *m, DBusConnection **conn) {
+        DBusMessage *message = NULL;
+        DBusPendingCall *pending = NULL;
+
+        message = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
+                                               DBUS_PATH_DBUS,
+                                               DBUS_INTERFACE_DBUS,
+                                               "Hello");
+        if (!message)
+                goto oom;
+
+        if (!dbus_connection_send_with_reply(*conn, message, &pending, -1))
+                goto oom;
+
+        if (!dbus_pending_call_set_data(pending, m->conn_data_slot, conn, NULL))
+                goto oom;
+
+        if (!dbus_pending_call_set_notify(pending, bus_register_cb, m, NULL))
+                goto oom;
+
+        dbus_message_unref(message);
+        dbus_pending_call_unref(pending);
+
+        return 0;
+oom:
+        if (pending) {
+                dbus_pending_call_cancel(pending);
+                dbus_pending_call_unref(pending);
+        }
+
+        if (message)
+                dbus_message_unref(message);
+
+        return -ENOMEM;
+}
+
+static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) {
+        const char *address;
+        DBusConnection *connection;
+        DBusError error;
+
+        switch (type) {
+        case DBUS_BUS_SYSTEM:
+                address = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
+                if (!address || !address[0])
+                        address = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS;
+                break;
+        case DBUS_BUS_SESSION:
+                address = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
+                if (!address || !address[0])
+                        address = DBUS_SESSION_BUS_DEFAULT_ADDRESS;
+                break;
+        default:
+                assert_not_reached("Invalid bus type");
+        }
+
+        dbus_error_init(&error);
+
+        connection = dbus_connection_open_private(address, &error);
+        if (!connection) {
+                log_warning("Failed to open private bus connection: %s", bus_error_message(&error));
+                goto fail;
+        }
+
+        return connection;
+fail:
+        if (connection)
+                dbus_connection_close(connection);
+        dbus_error_free(&error);
+        return NULL;
+}
+
+static int bus_init_system(Manager *m) {
+        int r;
+
+        if (m->system_bus)
+                return 0;
+
+        m->system_bus = manager_bus_connect_private(m, DBUS_BUS_SYSTEM);
+        if (!m->system_bus) {
+                log_debug("Failed to connect to system D-Bus, retrying later");
+                r = 0;
+                goto fail;
+        }
+
+        r = bus_setup_loop(m, m->system_bus);
+        if (r < 0)
+                goto fail;
+
+        r = manager_bus_async_register(m, &m->system_bus);
+        if (r < 0)
+                goto fail;
+
+        return 0;
+fail:
+        bus_done_system(m);
+
+        return r;
+}
+
+static int bus_init_api(Manager *m) {
+        int r;
+
+        if (m->api_bus)
+                return 0;
+
+        if (m->running_as == SYSTEMD_SYSTEM) {
+                m->api_bus = m->system_bus;
+                /* In this mode there is no distinct connection to the API bus,
+                 * the API is published on the system bus.
+                 * bus_register_cb() is aware of that and will init the API
+                 * when the system bus gets registered.
+                 * No need to setup anything here. */
+                return 0;
+        }
+
+        m->api_bus = manager_bus_connect_private(m, DBUS_BUS_SESSION);
+        if (!m->api_bus) {
+                log_debug("Failed to connect to API D-Bus, retrying later");
+                r = 0;
+                goto fail;
+        }
+
+        r = bus_setup_loop(m, m->api_bus);
+        if (r < 0)
+                goto fail;
+
+        r = manager_bus_async_register(m, &m->api_bus);
+        if (r < 0)
+                goto fail;
+
+        return 0;
+fail:
+        bus_done_api(m);
+
+        return r;
+}
+
+static int bus_init_private(Manager *m) {
+        DBusError error;
+        int r;
+        const char *const external_only[] = {
+                "EXTERNAL",
+                NULL
+        };
+
+        assert(m);
+
+        dbus_error_init(&error);
+
+        if (m->private_bus)
+                return 0;
+
+        if (m->running_as == SYSTEMD_SYSTEM) {
+
+                /* We want the private bus only when running as init */
+                if (getpid() != 1)
+                        return 0;
+
+                unlink("/run/systemd/private");
+                m->private_bus = dbus_server_listen("unix:path=/run/systemd/private", &error);
+        } else {
+                const char *e;
+                char *p;
+
+                e = secure_getenv("XDG_RUNTIME_DIR");
+                if (!e)
+                        return 0;
+
+                if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0) {
+                        r = log_oom();
+                        goto fail;
+                }
+
+                mkdir_parents_label(p+10, 0755);
+                unlink(p+10);
+                m->private_bus = dbus_server_listen(p, &error);
+                free(p);
+        }
+
+        if (!m->private_bus) {
+                log_error("Failed to create private D-Bus server: %s", bus_error_message(&error));
+                r = -EIO;
+                goto fail;
+        }
+
+        if (!dbus_server_set_auth_mechanisms(m->private_bus, (const char**) external_only) ||
+            !dbus_server_set_watch_functions(m->private_bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) ||
+            !dbus_server_set_timeout_functions(m->private_bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) {
+                r = log_oom();
+                goto fail;
+        }
+
+        dbus_server_set_new_connection_function(m->private_bus, bus_new_connection, m, NULL);
+
+        log_debug("Successfully created private D-Bus server.");
+
+        return 0;
+
+fail:
+        bus_done_private(m);
+        dbus_error_free(&error);
+
+        return r;
+}
+
+int bus_init(Manager *m, bool try_bus_connect) {
+        int r;
+
+        if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 ||
+            set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0)
+                goto oom;
+
+        if (m->name_data_slot < 0)
+                if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot))
+                        goto oom;
+
+        if (m->conn_data_slot < 0)
+                if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot))
+                        goto oom;
+
+        if (m->subscribed_data_slot < 0)
+                if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot))
+                        goto oom;
+
+        if (try_bus_connect) {
+                if ((r = bus_init_system(m)) < 0 ||
+                    (r = bus_init_api(m)) < 0)
+                        return r;
+        }
+
+        if ((r = bus_init_private(m)) < 0)
+                return r;
+
+        return 0;
+oom:
+        return log_oom();
+}
+
+static void shutdown_connection(Manager *m, DBusConnection *c) {
+        Set *s;
+        Job *j;
+        Iterator i;
+
+        HASHMAP_FOREACH(j, m->jobs, i) {
+                JobBusClient *cl, *nextcl;
+                LIST_FOREACH_SAFE(client, cl, nextcl, j->bus_client_list) {
+                        if (cl->bus == c) {
+                                LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
+                                free(cl);
+                        }
+                }
+        }
+
+        set_remove(m->bus_connections, c);
+        set_remove(m->bus_connections_for_dispatch, c);
+
+        if ((s = BUS_CONNECTION_SUBSCRIBED(m, c))) {
+                char *t;
+
+                while ((t = set_steal_first(s)))
+                        free(t);
+
+                set_free(s);
+        }
+
+        if (m->queued_message_connection == c) {
+                m->queued_message_connection = NULL;
+
+                if (m->queued_message) {
+                        dbus_message_unref(m->queued_message);
+                        m->queued_message = NULL;
+                }
+        }
+
+        dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL);
+        /* system manager cannot afford to block on DBus */
+        if (m->running_as != SYSTEMD_SYSTEM)
+                dbus_connection_flush(c);
+        dbus_connection_close(c);
+        dbus_connection_unref(c);
+}
+
+static void bus_done_api(Manager *m) {
+        if (!m->api_bus)
+                return;
+
+        if (m->running_as == SYSTEMD_USER)
+                shutdown_connection(m, m->api_bus);
+
+        m->api_bus = NULL;
+
+        if (m->queued_message) {
+                dbus_message_unref(m->queued_message);
+                m->queued_message = NULL;
+        }
+}
+
+static void bus_done_system(Manager *m) {
+        if (!m->system_bus)
+                return;
+
+        if (m->running_as == SYSTEMD_SYSTEM)
+                bus_done_api(m);
+
+        shutdown_connection(m, m->system_bus);
+        m->system_bus = NULL;
+}
+
+static void bus_done_private(Manager *m) {
+        if (!m->private_bus)
+                return;
+
+        dbus_server_disconnect(m->private_bus);
+        dbus_server_unref(m->private_bus);
+        m->private_bus = NULL;
+}
+
+void bus_done(Manager *m) {
+        DBusConnection *c;
+
+        bus_done_api(m);
+        bus_done_system(m);
+        bus_done_private(m);
+
+        while ((c = set_steal_first(m->bus_connections)))
+                shutdown_connection(m, c);
+
+        while ((c = set_steal_first(m->bus_connections_for_dispatch)))
+                shutdown_connection(m, c);
+
+        set_free(m->bus_connections);
+        set_free(m->bus_connections_for_dispatch);
+
+        if (m->name_data_slot >= 0)
+               dbus_pending_call_free_data_slot(&m->name_data_slot);
+
+        if (m->conn_data_slot >= 0)
+               dbus_pending_call_free_data_slot(&m->conn_data_slot);
+
+        if (m->subscribed_data_slot >= 0)
+                dbus_connection_free_data_slot(&m->subscribed_data_slot);
+}
+
+static void query_pid_pending_cb(DBusPendingCall *pending, void *userdata) {
+        Manager *m = userdata;
+        DBusMessage *reply;
+        DBusError error;
+        const char *name;
+
+        dbus_error_init(&error);
+
+        assert_se(name = BUS_PENDING_CALL_NAME(m, pending));
+        assert_se(reply = dbus_pending_call_steal_reply(pending));
+
+        switch (dbus_message_get_type(reply)) {
+
+        case DBUS_MESSAGE_TYPE_ERROR:
+
+                assert_se(dbus_set_error_from_message(&error, reply));
+                log_warning("GetConnectionUnixProcessID() failed: %s", bus_error_message(&error));
+                break;
+
+        case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
+                uint32_t r;
+
+                if (!dbus_message_get_args(reply,
+                                           &error,
+                                           DBUS_TYPE_UINT32, &r,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse GetConnectionUnixProcessID() reply: %s", bus_error_message(&error));
+                        break;
+                }
+
+                manager_dispatch_bus_query_pid_done(m, name, (pid_t) r);
+                break;
+        }
+
+        default:
+                assert_not_reached("Invalid reply message");
+        }
+
+        dbus_message_unref(reply);
+        dbus_error_free(&error);
+}
+
+int bus_query_pid(Manager *m, const char *name) {
+        DBusMessage *message = NULL;
+        DBusPendingCall *pending = NULL;
+        char *n = NULL;
+
+        assert(m);
+        assert(name);
+
+        if (!(message = dbus_message_new_method_call(
+                              DBUS_SERVICE_DBUS,
+                              DBUS_PATH_DBUS,
+                              DBUS_INTERFACE_DBUS,
+                              "GetConnectionUnixProcessID")))
+                goto oom;
+
+        if (!(dbus_message_append_args(
+                              message,
+                              DBUS_TYPE_STRING, &name,
+                              DBUS_TYPE_INVALID)))
+                goto oom;
+
+        if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
+                goto oom;
+
+        if (!(n = strdup(name)))
+                goto oom;
+
+        if (!dbus_pending_call_set_data(pending, m->name_data_slot, n, free))
+                goto oom;
+
+        n = NULL;
+
+        if (!dbus_pending_call_set_notify(pending, query_pid_pending_cb, m, NULL))
+                goto oom;
+
+        dbus_message_unref(message);
+        dbus_pending_call_unref(pending);
+
+        return 0;
+
+oom:
+        free(n);
+
+        if (pending) {
+                dbus_pending_call_cancel(pending);
+                dbus_pending_call_unref(pending);
+        }
+
+        if (message)
+                dbus_message_unref(message);
+
+        return -ENOMEM;
+}
+
+int bus_broadcast(Manager *m, DBusMessage *message) {
+        bool oom = false;
+        Iterator i;
+        DBusConnection *c;
+
+        assert(m);
+        assert(message);
+
+        SET_FOREACH(c, m->bus_connections_for_dispatch, i)
+                if (c != m->system_bus || m->running_as == SYSTEMD_SYSTEM)
+                        oom = !dbus_connection_send(c, message, NULL);
+
+        SET_FOREACH(c, m->bus_connections, i)
+                if (c != m->system_bus || m->running_as == SYSTEMD_SYSTEM)
+                        oom = !dbus_connection_send(c, message, NULL);
+
+        return oom ? -ENOMEM : 0;
+}
+
+bool bus_has_subscriber(Manager *m) {
+        Iterator i;
+        DBusConnection *c;
+
+        assert(m);
+
+        SET_FOREACH(c, m->bus_connections_for_dispatch, i)
+                if (bus_connection_has_subscriber(m, c))
+                        return true;
+
+        SET_FOREACH(c, m->bus_connections, i)
+                if (bus_connection_has_subscriber(m, c))
+                        return true;
+
+        return false;
+}
+
+bool bus_connection_has_subscriber(Manager *m, DBusConnection *c) {
+        assert(m);
+        assert(c);
+
+        return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c));
+}
+
+int bus_fdset_add_all(Manager *m, FDSet *fds) {
+        Iterator i;
+        DBusConnection *c;
+
+        assert(m);
+        assert(fds);
+
+        /* When we are about to reexecute we add all D-Bus fds to the
+         * set to pass over to the newly executed systemd. They won't
+         * be used there however, except that they are closed at the
+         * very end of deserialization, those making it possible for
+         * clients to synchronously wait for systemd to reexec by
+         * simply waiting for disconnection */
+
+        SET_FOREACH(c, m->bus_connections_for_dispatch, i) {
+                int fd;
+
+                if (dbus_connection_get_unix_fd(c, &fd)) {
+                        fd = fdset_put_dup(fds, fd);
+
+                        if (fd < 0)
+                                return fd;
+                }
+        }
+
+        SET_FOREACH(c, m->bus_connections, i) {
+                int fd;
+
+                if (dbus_connection_get_unix_fd(c, &fd)) {
+                        fd = fdset_put_dup(fds, fd);
+
+                        if (fd < 0)
+                                return fd;
+                }
+        }
+
+        return 0;
+}
+
+void bus_broadcast_finished(
+                Manager *m,
+                usec_t firmware_usec,
+                usec_t loader_usec,
+                usec_t kernel_usec,
+                usec_t initrd_usec,
+                usec_t userspace_usec,
+                usec_t total_usec) {
+
+        DBusMessage *message;
+
+        assert(m);
+
+        message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
+        if (!message) {
+                log_oom();
+                return;
+        }
+
+        assert_cc(sizeof(usec_t) == sizeof(uint64_t));
+        if (!dbus_message_append_args(message,
+                                      DBUS_TYPE_UINT64, &firmware_usec,
+                                      DBUS_TYPE_UINT64, &loader_usec,
+                                      DBUS_TYPE_UINT64, &kernel_usec,
+                                      DBUS_TYPE_UINT64, &initrd_usec,
+                                      DBUS_TYPE_UINT64, &userspace_usec,
+                                      DBUS_TYPE_UINT64, &total_usec,
+                                      DBUS_TYPE_INVALID)) {
+                log_oom();
+                goto finish;
+        }
+
+
+        if (bus_broadcast(m, message) < 0) {
+                log_oom();
+                goto finish;
+        }
+
+finish:
+        if (message)
+                dbus_message_unref(message);
+}
diff --git a/src/core/dbus.h b/src/core/dbus.h
new file mode 100644 (file)
index 0000000..c7a058e
--- /dev/null
@@ -0,0 +1,50 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include "manager.h"
+
+int bus_init(Manager *m, bool try_bus_connect);
+void bus_done(Manager *m);
+
+unsigned bus_dispatch(Manager *m);
+
+void bus_watch_event(Manager *m, Watch *w, int events);
+void bus_timeout_event(Manager *m, Watch *w, int events);
+
+int bus_query_pid(Manager *m, const char *name);
+
+int bus_broadcast(Manager *m, DBusMessage *message);
+
+bool bus_has_subscriber(Manager *m);
+bool bus_connection_has_subscriber(Manager *m, DBusConnection *c);
+
+int bus_fdset_add_all(Manager *m, FDSet *fds);
+
+void bus_broadcast_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec);
+
+#define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot)
+#define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot)
+
+extern const char * const bus_interface_table[];
diff --git a/src/core/device.c b/src/core/device.c
new file mode 100644 (file)
index 0000000..0b01718
--- /dev/null
@@ -0,0 +1,644 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <sys/epoll.h>
+#include <libudev.h>
+
+#include "unit.h"
+#include "device.h"
+#include "strv.h"
+#include "log.h"
+#include "unit-name.h"
+#include "dbus-device.h"
+#include "def.h"
+#include "path-util.h"
+
+static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
+        [DEVICE_DEAD] = UNIT_INACTIVE,
+        [DEVICE_PLUGGED] = UNIT_ACTIVE
+};
+
+static void device_unset_sysfs(Device *d) {
+        Device *first;
+
+        assert(d);
+
+        if (!d->sysfs)
+                return;
+
+        /* Remove this unit from the chain of devices which share the
+         * same sysfs path. */
+        first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, d->sysfs);
+        LIST_REMOVE(Device, same_sysfs, first, d);
+
+        if (first)
+                hashmap_remove_and_replace(UNIT(d)->manager->devices_by_sysfs, d->sysfs, first->sysfs, first);
+        else
+                hashmap_remove(UNIT(d)->manager->devices_by_sysfs, d->sysfs);
+
+        free(d->sysfs);
+        d->sysfs = NULL;
+}
+
+static void device_init(Unit *u) {
+        Device *d = DEVICE(u);
+
+        assert(d);
+        assert(UNIT(d)->load_state == UNIT_STUB);
+
+        /* In contrast to all other unit types we timeout jobs waiting
+         * for devices by default. This is because they otherwise wait
+         * indefinitely for plugged in devices, something which cannot
+         * happen for the other units since their operations time out
+         * anyway. */
+        UNIT(d)->job_timeout = DEFAULT_TIMEOUT_USEC;
+
+        UNIT(d)->ignore_on_isolate = true;
+        UNIT(d)->ignore_on_snapshot = true;
+}
+
+static void device_done(Unit *u) {
+        Device *d = DEVICE(u);
+
+        assert(d);
+
+        device_unset_sysfs(d);
+}
+
+static void device_set_state(Device *d, DeviceState state) {
+        DeviceState old_state;
+        assert(d);
+
+        old_state = d->state;
+        d->state = state;
+
+        if (state != old_state)
+                log_debug_unit(UNIT(d)->id,
+                               "%s changed %s -> %s", UNIT(d)->id,
+                               device_state_to_string(old_state),
+                               device_state_to_string(state));
+
+        unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
+}
+
+static int device_coldplug(Unit *u) {
+        Device *d = DEVICE(u);
+
+        assert(d);
+        assert(d->state == DEVICE_DEAD);
+
+        if (d->sysfs)
+                device_set_state(d, DEVICE_PLUGGED);
+
+        return 0;
+}
+
+static void device_dump(Unit *u, FILE *f, const char *prefix) {
+        Device *d = DEVICE(u);
+
+        assert(d);
+
+        fprintf(f,
+                "%sDevice State: %s\n"
+                "%sSysfs Path: %s\n",
+                prefix, device_state_to_string(d->state),
+                prefix, strna(d->sysfs));
+}
+
+static UnitActiveState device_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[DEVICE(u)->state];
+}
+
+static const char *device_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return device_state_to_string(DEVICE(u)->state);
+}
+
+static int device_add_escaped_name(Unit *u, const char *dn) {
+        char *e;
+        int r;
+
+        assert(u);
+        assert(dn);
+        assert(dn[0] == '/');
+
+        e = unit_name_from_path(dn, ".device");
+        if (!e)
+                return -ENOMEM;
+
+        r = unit_add_name(u, e);
+        free(e);
+
+        if (r < 0 && r != -EEXIST)
+                return r;
+
+        return 0;
+}
+
+static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) {
+        char *e;
+        Unit *u;
+
+        assert(m);
+        assert(dn);
+        assert(dn[0] == '/');
+        assert(_u);
+
+        e = unit_name_from_path(dn, ".device");
+        if (!e)
+                return -ENOMEM;
+
+        u = manager_get_unit(m, e);
+        free(e);
+
+        if (u) {
+                *_u = u;
+                return 1;
+        }
+
+        return 0;
+}
+
+static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
+        const char *sysfs, *model;
+        Unit *u = NULL;
+        int r;
+        bool delete;
+
+        assert(m);
+
+        if (!(sysfs = udev_device_get_syspath(dev)))
+                return -ENOMEM;
+
+        if ((r = device_find_escape_name(m, path, &u)) < 0)
+                return r;
+
+        if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs))
+                return -EEXIST;
+
+        if (!u) {
+                delete = true;
+
+                u = unit_new(m, sizeof(Device));
+                if (!u)
+                        return -ENOMEM;
+
+                r = device_add_escaped_name(u, path);
+                if (r < 0)
+                        goto fail;
+
+                unit_add_to_load_queue(u);
+        } else
+                delete = false;
+
+        /* If this was created via some dependency and has not
+         * actually been seen yet ->sysfs will not be
+         * initialized. Hence initialize it if necessary. */
+
+        if (!DEVICE(u)->sysfs) {
+                Device *first;
+
+                if (!(DEVICE(u)->sysfs = strdup(sysfs))) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                if (!m->devices_by_sysfs)
+                        if (!(m->devices_by_sysfs = hashmap_new(string_hash_func, string_compare_func))) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                first = hashmap_get(m->devices_by_sysfs, sysfs);
+                LIST_PREPEND(Device, same_sysfs, first, DEVICE(u));
+
+                if ((r = hashmap_replace(m->devices_by_sysfs, DEVICE(u)->sysfs, first)) < 0)
+                        goto fail;
+        }
+
+        if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) ||
+            (model = udev_device_get_property_value(dev, "ID_MODEL"))) {
+                if ((r = unit_set_description(u, model)) < 0)
+                        goto fail;
+        } else
+                if ((r = unit_set_description(u, path)) < 0)
+                        goto fail;
+
+        if (main) {
+                /* The additional systemd udev properties we only
+                 * interpret for the main object */
+                const char *wants, *alias;
+
+                alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
+                if (alias) {
+                        char *state, *w;
+                        size_t l;
+
+                        FOREACH_WORD_QUOTED(w, l, alias, state) {
+                                char *e;
+
+                                e = strndup(w, l);
+                                if (!e) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                if (!is_path(e)) {
+                                        log_warning("SYSTEMD_ALIAS for %s is not a path, ignoring: %s", sysfs, e);
+                                        free(e);
+                                } else {
+                                        device_update_unit(m, dev, e, false);
+                                        free(e);
+                                }
+                        }
+                }
+
+                wants = udev_device_get_property_value(dev, "SYSTEMD_WANTS");
+                if (wants) {
+                        char *state, *w;
+                        size_t l;
+
+                        FOREACH_WORD_QUOTED(w, l, wants, state) {
+                                char *e;
+
+                                e = strndup(w, l);
+                                if (!e) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                r = unit_add_dependency_by_name(u, UNIT_WANTS, e, NULL, true);
+                                free(e);
+                                if (r < 0)
+                                        goto fail;
+                        }
+                }
+        }
+
+        unit_add_to_dbus_queue(u);
+        return 0;
+
+fail:
+        log_warning("Failed to load device unit: %s", strerror(-r));
+
+        if (delete && u)
+                unit_free(u);
+
+        return r;
+}
+
+static int device_process_new_device(Manager *m, struct udev_device *dev, bool update_state) {
+        const char *sysfs, *dn;
+        struct udev_list_entry *item = NULL, *first = NULL;
+
+        assert(m);
+
+        if (!(sysfs = udev_device_get_syspath(dev)))
+                return -ENOMEM;
+
+        /* Add the main unit named after the sysfs path */
+        device_update_unit(m, dev, sysfs, true);
+
+        /* Add an additional unit for the device node */
+        if ((dn = udev_device_get_devnode(dev)))
+                device_update_unit(m, dev, dn, false);
+
+        /* Add additional units for all symlinks */
+        first = udev_device_get_devlinks_list_entry(dev);
+        udev_list_entry_foreach(item, first) {
+                const char *p;
+                struct stat st;
+
+                /* Don't bother with the /dev/block links */
+                p = udev_list_entry_get_name(item);
+
+                if (path_startswith(p, "/dev/block/") ||
+                    path_startswith(p, "/dev/char/"))
+                        continue;
+
+                /* Verify that the symlink in the FS actually belongs
+                 * to this device. This is useful to deal with
+                 * conflicting devices, e.g. when two disks want the
+                 * same /dev/disk/by-label/xxx link because they have
+                 * the same label. We want to make sure that the same
+                 * device that won the symlink wins in systemd, so we
+                 * check the device node major/minor*/
+                if (stat(p, &st) >= 0)
+                        if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
+                            st.st_rdev != udev_device_get_devnum(dev))
+                                continue;
+
+                device_update_unit(m, dev, p, false);
+        }
+
+        if (update_state) {
+                Device *d, *l;
+
+                manager_dispatch_load_queue(m);
+
+                l = hashmap_get(m->devices_by_sysfs, sysfs);
+                LIST_FOREACH(same_sysfs, d, l)
+                        device_set_state(d, DEVICE_PLUGGED);
+        }
+
+        return 0;
+}
+
+static int device_process_path(Manager *m, const char *path, bool update_state) {
+        int r;
+        struct udev_device *dev;
+
+        assert(m);
+        assert(path);
+
+        if (!(dev = udev_device_new_from_syspath(m->udev, path))) {
+                log_warning("Failed to get udev device object from udev for path %s.", path);
+                return -ENOMEM;
+        }
+
+        r = device_process_new_device(m, dev, update_state);
+        udev_device_unref(dev);
+        return r;
+}
+
+static int device_process_removed_device(Manager *m, struct udev_device *dev) {
+        const char *sysfs;
+        Device *d;
+
+        assert(m);
+        assert(dev);
+
+        if (!(sysfs = udev_device_get_syspath(dev)))
+                return -ENOMEM;
+
+        /* Remove all units of this sysfs path */
+        while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) {
+                device_unset_sysfs(d);
+                device_set_state(d, DEVICE_DEAD);
+        }
+
+        return 0;
+}
+
+static Unit *device_following(Unit *u) {
+        Device *d = DEVICE(u);
+        Device *other, *first = NULL;
+
+        assert(d);
+
+        if (startswith(u->id, "sys-"))
+                return NULL;
+
+        /* Make everybody follow the unit that's named after the sysfs path */
+        for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
+                if (startswith(UNIT(other)->id, "sys-"))
+                        return UNIT(other);
+
+        for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
+                if (startswith(UNIT(other)->id, "sys-"))
+                        return UNIT(other);
+
+                first = other;
+        }
+
+        return UNIT(first);
+}
+
+static int device_following_set(Unit *u, Set **_s) {
+        Device *d = DEVICE(u);
+        Device *other;
+        Set *s;
+        int r;
+
+        assert(d);
+        assert(_s);
+
+        if (!d->same_sysfs_prev && !d->same_sysfs_next) {
+                *_s = NULL;
+                return 0;
+        }
+
+        if (!(s = set_new(NULL, NULL)))
+                return -ENOMEM;
+
+        for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
+                if ((r = set_put(s, other)) < 0)
+                        goto fail;
+
+        for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev)
+                if ((r = set_put(s, other)) < 0)
+                        goto fail;
+
+        *_s = s;
+        return 1;
+
+fail:
+        set_free(s);
+        return r;
+}
+
+static void device_shutdown(Manager *m) {
+        assert(m);
+
+        if (m->udev_monitor) {
+                udev_monitor_unref(m->udev_monitor);
+                m->udev_monitor = NULL;
+        }
+
+        if (m->udev) {
+                udev_unref(m->udev);
+                m->udev = NULL;
+        }
+
+        hashmap_free(m->devices_by_sysfs);
+        m->devices_by_sysfs = NULL;
+}
+
+static int device_enumerate(Manager *m) {
+        struct epoll_event ev;
+        int r;
+        struct udev_enumerate *e = NULL;
+        struct udev_list_entry *item = NULL, *first = NULL;
+
+        assert(m);
+
+        if (!m->udev) {
+                if (!(m->udev = udev_new()))
+                        return -ENOMEM;
+
+                if (!(m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev"))) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                /* This will fail if we are unprivileged, but that
+                 * should not matter much, as user instances won't run
+                 * during boot. */
+                udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
+
+                if (udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd") < 0) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                if (udev_monitor_enable_receiving(m->udev_monitor) < 0) {
+                        r = -EIO;
+                        goto fail;
+                }
+
+                m->udev_watch.type = WATCH_UDEV;
+                m->udev_watch.fd = udev_monitor_get_fd(m->udev_monitor);
+
+                zero(ev);
+                ev.events = EPOLLIN;
+                ev.data.ptr = &m->udev_watch;
+
+                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_watch.fd, &ev) < 0)
+                        return -errno;
+        }
+
+        if (!(e = udev_enumerate_new(m->udev))) {
+                r = -ENOMEM;
+                goto fail;
+        }
+        if (udev_enumerate_add_match_tag(e, "systemd") < 0) {
+                r = -EIO;
+                goto fail;
+        }
+
+        if (udev_enumerate_scan_devices(e) < 0) {
+                r = -EIO;
+                goto fail;
+        }
+
+        first = udev_enumerate_get_list_entry(e);
+        udev_list_entry_foreach(item, first)
+                device_process_path(m, udev_list_entry_get_name(item), false);
+
+        udev_enumerate_unref(e);
+        return 0;
+
+fail:
+        if (e)
+                udev_enumerate_unref(e);
+
+        device_shutdown(m);
+        return r;
+}
+
+void device_fd_event(Manager *m, int events) {
+        struct udev_device *dev;
+        int r;
+        const char *action, *ready;
+
+        assert(m);
+
+        if (events != EPOLLIN) {
+                static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
+
+                if (!ratelimit_test(&limit))
+                        log_error("Failed to get udev event: %m");
+                if (!(events & EPOLLIN))
+                        return;
+        }
+
+        if (!(dev = udev_monitor_receive_device(m->udev_monitor))) {
+                /*
+                 * libudev might filter-out devices which pass the bloom filter,
+                 * so getting NULL here is not necessarily an error
+                 */
+                return;
+        }
+
+        if (!(action = udev_device_get_action(dev))) {
+                log_error("Failed to get udev action string.");
+                goto fail;
+        }
+
+        ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
+
+        if (streq(action, "remove") || (ready && parse_boolean(ready) == 0)) {
+                if ((r = device_process_removed_device(m, dev)) < 0) {
+                        log_error("Failed to process udev device event: %s", strerror(-r));
+                        goto fail;
+                }
+        } else {
+                if ((r = device_process_new_device(m, dev, true)) < 0) {
+                        log_error("Failed to process udev device event: %s", strerror(-r));
+                        goto fail;
+                }
+        }
+
+fail:
+        udev_device_unref(dev);
+}
+
+static const char* const device_state_table[_DEVICE_STATE_MAX] = {
+        [DEVICE_DEAD] = "dead",
+        [DEVICE_PLUGGED] = "plugged"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
+
+const UnitVTable device_vtable = {
+        .object_size = sizeof(Device),
+        .sections =
+                "Unit\0"
+                "Device\0"
+                "Install\0",
+
+        .no_instances = true,
+
+        .init = device_init,
+
+        .load = unit_load_fragment_and_dropin_optional,
+        .done = device_done,
+        .coldplug = device_coldplug,
+
+        .dump = device_dump,
+
+        .active_state = device_active_state,
+        .sub_state_to_string = device_sub_state_to_string,
+
+        .bus_interface = "org.freedesktop.systemd1.Device",
+        .bus_message_handler = bus_device_message_handler,
+        .bus_invalidating_properties =  bus_device_invalidating_properties,
+
+        .following = device_following,
+        .following_set = device_following_set,
+
+        .enumerate = device_enumerate,
+        .shutdown = device_shutdown,
+
+        .status_message_formats = {
+                .starting_stopping = {
+                        [0] = "Expecting device %s...",
+                },
+                .finished_start_job = {
+                        [JOB_DONE]       = "Found device %s.",
+                        [JOB_TIMEOUT]    = "Timed out waiting for device %s.",
+                },
+        },
+};
diff --git a/src/core/device.h b/src/core/device.h
new file mode 100644 (file)
index 0000000..3c4604f
--- /dev/null
@@ -0,0 +1,56 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Device Device;
+
+#include "unit.h"
+
+/* We simply watch devices, we cannot plug/unplug them. That
+ * simplifies the state engine greatly */
+typedef enum DeviceState {
+        DEVICE_DEAD,
+        DEVICE_PLUGGED,
+        _DEVICE_STATE_MAX,
+        _DEVICE_STATE_INVALID = -1
+} DeviceState;
+
+struct Device {
+        Unit meta;
+
+        char *sysfs;
+
+        /* In order to be able to distinguish dependencies on
+        different device nodes we might end up creating multiple
+        devices for the same sysfs path. We chain them up here. */
+
+        LIST_FIELDS(struct Device, same_sysfs);
+
+        DeviceState state;
+};
+
+extern const UnitVTable device_vtable;
+
+void device_fd_event(Manager *m, int events);
+
+const char* device_state_to_string(DeviceState i);
+DeviceState device_state_from_string(const char *s);
diff --git a/src/core/execute.c b/src/core/execute.c
new file mode 100644 (file)
index 0000000..7dc1504
--- /dev/null
@@ -0,0 +1,2160 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/prctl.h>
+#include <linux/sched.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <grp.h>
+#include <pwd.h>
+#include <sys/mount.h>
+#include <linux/fs.h>
+#include <linux/oom.h>
+#include <sys/poll.h>
+#include <linux/seccomp-bpf.h>
+#include <glob.h>
+
+#ifdef HAVE_PAM
+#include <security/pam_appl.h>
+#endif
+
+#include "execute.h"
+#include "strv.h"
+#include "macro.h"
+#include "capability.h"
+#include "util.h"
+#include "log.h"
+#include "sd-messages.h"
+#include "ioprio.h"
+#include "securebits.h"
+#include "cgroup.h"
+#include "namespace.h"
+#include "tcpwrap.h"
+#include "exit-status.h"
+#include "missing.h"
+#include "utmp-wtmp.h"
+#include "def.h"
+#include "loopback-setup.h"
+#include "path-util.h"
+#include "syscall-list.h"
+
+#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
+
+/* This assumes there is a 'tty' group */
+#define TTY_MODE 0620
+
+static int shift_fds(int fds[], unsigned n_fds) {
+        int start, restart_from;
+
+        if (n_fds <= 0)
+                return 0;
+
+        /* Modifies the fds array! (sorts it) */
+
+        assert(fds);
+
+        start = 0;
+        for (;;) {
+                int i;
+
+                restart_from = -1;
+
+                for (i = start; i < (int) n_fds; i++) {
+                        int nfd;
+
+                        /* Already at right index? */
+                        if (fds[i] == i+3)
+                                continue;
+
+                        if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
+                                return -errno;
+
+                        close_nointr_nofail(fds[i]);
+                        fds[i] = nfd;
+
+                        /* Hmm, the fd we wanted isn't free? Then
+                         * let's remember that and try again from here*/
+                        if (nfd != i+3 && restart_from < 0)
+                                restart_from = i;
+                }
+
+                if (restart_from < 0)
+                        break;
+
+                start = restart_from;
+        }
+
+        return 0;
+}
+
+static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
+        unsigned i;
+        int r;
+
+        if (n_fds <= 0)
+                return 0;
+
+        assert(fds);
+
+        /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
+
+        for (i = 0; i < n_fds; i++) {
+
+                if ((r = fd_nonblock(fds[i], nonblock)) < 0)
+                        return r;
+
+                /* We unconditionally drop FD_CLOEXEC from the fds,
+                 * since after all we want to pass these fds to our
+                 * children */
+
+                if ((r = fd_cloexec(fds[i], false)) < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static const char *tty_path(const ExecContext *context) {
+        assert(context);
+
+        if (context->tty_path)
+                return context->tty_path;
+
+        return "/dev/console";
+}
+
+void exec_context_tty_reset(const ExecContext *context) {
+        assert(context);
+
+        if (context->tty_vhangup)
+                terminal_vhangup(tty_path(context));
+
+        if (context->tty_reset)
+                reset_terminal(tty_path(context));
+
+        if (context->tty_vt_disallocate && context->tty_path)
+                vt_disallocate(context->tty_path);
+}
+
+static int open_null_as(int flags, int nfd) {
+        int fd, r;
+
+        assert(nfd >= 0);
+
+        if ((fd = open("/dev/null", flags|O_NOCTTY)) < 0)
+                return -errno;
+
+        if (fd != nfd) {
+                r = dup2(fd, nfd) < 0 ? -errno : nfd;
+                close_nointr_nofail(fd);
+        } else
+                r = nfd;
+
+        return r;
+}
+
+static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd) {
+        int fd, r;
+        union sockaddr_union sa;
+
+        assert(context);
+        assert(output < _EXEC_OUTPUT_MAX);
+        assert(ident);
+        assert(nfd >= 0);
+
+        fd = socket(AF_UNIX, SOCK_STREAM, 0);
+        if (fd < 0)
+                return -errno;
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path));
+
+        r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
+        if (r < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        if (shutdown(fd, SHUT_RD) < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        dprintf(fd,
+                "%s\n"
+                "%s\n"
+                "%i\n"
+                "%i\n"
+                "%i\n"
+                "%i\n"
+                "%i\n",
+                context->syslog_identifier ? context->syslog_identifier : ident,
+                unit_id,
+                context->syslog_priority,
+                !!context->syslog_level_prefix,
+                output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
+                output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
+                output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || output == EXEC_OUTPUT_KMSG_AND_CONSOLE || output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE);
+
+        if (fd != nfd) {
+                r = dup2(fd, nfd) < 0 ? -errno : nfd;
+                close_nointr_nofail(fd);
+        } else
+                r = nfd;
+
+        return r;
+}
+static int open_terminal_as(const char *path, mode_t mode, int nfd) {
+        int fd, r;
+
+        assert(path);
+        assert(nfd >= 0);
+
+        if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0)
+                return fd;
+
+        if (fd != nfd) {
+                r = dup2(fd, nfd) < 0 ? -errno : nfd;
+                close_nointr_nofail(fd);
+        } else
+                r = nfd;
+
+        return r;
+}
+
+static bool is_terminal_input(ExecInput i) {
+        return
+                i == EXEC_INPUT_TTY ||
+                i == EXEC_INPUT_TTY_FORCE ||
+                i == EXEC_INPUT_TTY_FAIL;
+}
+
+static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
+
+        if (is_terminal_input(std_input) && !apply_tty_stdin)
+                return EXEC_INPUT_NULL;
+
+        if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
+                return EXEC_INPUT_NULL;
+
+        return std_input;
+}
+
+static int fixup_output(ExecOutput std_output, int socket_fd) {
+
+        if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
+                return EXEC_OUTPUT_INHERIT;
+
+        return std_output;
+}
+
+static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) {
+        ExecInput i;
+
+        assert(context);
+
+        i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
+
+        switch (i) {
+
+        case EXEC_INPUT_NULL:
+                return open_null_as(O_RDONLY, STDIN_FILENO);
+
+        case EXEC_INPUT_TTY:
+        case EXEC_INPUT_TTY_FORCE:
+        case EXEC_INPUT_TTY_FAIL: {
+                int fd, r;
+
+                if ((fd = acquire_terminal(
+                                     tty_path(context),
+                                     i == EXEC_INPUT_TTY_FAIL,
+                                     i == EXEC_INPUT_TTY_FORCE,
+                                     false,
+                                     (usec_t) -1)) < 0)
+                        return fd;
+
+                if (fd != STDIN_FILENO) {
+                        r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
+                        close_nointr_nofail(fd);
+                } else
+                        r = STDIN_FILENO;
+
+                return r;
+        }
+
+        case EXEC_INPUT_SOCKET:
+                return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
+
+        default:
+                assert_not_reached("Unknown input type");
+        }
+}
+
+static int setup_output(const ExecContext *context, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) {
+        ExecOutput o;
+        ExecInput i;
+
+        assert(context);
+        assert(ident);
+
+        i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
+        o = fixup_output(context->std_output, socket_fd);
+
+        /* This expects the input is already set up */
+
+        switch (o) {
+
+        case EXEC_OUTPUT_INHERIT:
+
+                /* If input got downgraded, inherit the original value */
+                if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
+                        return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO);
+
+                /* If the input is connected to anything that's not a /dev/null, inherit that... */
+                if (i != EXEC_INPUT_NULL)
+                        return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO;
+
+                /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
+                if (getppid() != 1)
+                        return STDOUT_FILENO;
+
+                /* We need to open /dev/null here anew, to get the
+                 * right access mode. So we fall through */
+
+        case EXEC_OUTPUT_NULL:
+                return open_null_as(O_WRONLY, STDOUT_FILENO);
+
+        case EXEC_OUTPUT_TTY:
+                if (is_terminal_input(i))
+                        return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO;
+
+                /* We don't reset the terminal if this is just about output */
+                return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO);
+
+        case EXEC_OUTPUT_SYSLOG:
+        case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
+        case EXEC_OUTPUT_KMSG:
+        case EXEC_OUTPUT_KMSG_AND_CONSOLE:
+        case EXEC_OUTPUT_JOURNAL:
+        case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
+                return connect_logger_as(context, o, ident, unit_id, STDOUT_FILENO);
+
+        case EXEC_OUTPUT_SOCKET:
+                assert(socket_fd >= 0);
+                return dup2(socket_fd, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO;
+
+        default:
+                assert_not_reached("Unknown output type");
+        }
+}
+
+static int setup_error(const ExecContext *context, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) {
+        ExecOutput o, e;
+        ExecInput i;
+
+        assert(context);
+        assert(ident);
+
+        i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
+        o = fixup_output(context->std_output, socket_fd);
+        e = fixup_output(context->std_error, socket_fd);
+
+        /* This expects the input and output are already set up */
+
+        /* Don't change the stderr file descriptor if we inherit all
+         * the way and are not on a tty */
+        if (e == EXEC_OUTPUT_INHERIT &&
+            o == EXEC_OUTPUT_INHERIT &&
+            i == EXEC_INPUT_NULL &&
+            !is_terminal_input(context->std_input) &&
+            getppid () != 1)
+                return STDERR_FILENO;
+
+        /* Duplicate from stdout if possible */
+        if (e == o || e == EXEC_OUTPUT_INHERIT)
+                return dup2(STDOUT_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO;
+
+        switch (e) {
+
+        case EXEC_OUTPUT_NULL:
+                return open_null_as(O_WRONLY, STDERR_FILENO);
+
+        case EXEC_OUTPUT_TTY:
+                if (is_terminal_input(i))
+                        return dup2(STDIN_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO;
+
+                /* We don't reset the terminal if this is just about output */
+                return open_terminal_as(tty_path(context), O_WRONLY, STDERR_FILENO);
+
+        case EXEC_OUTPUT_SYSLOG:
+        case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
+        case EXEC_OUTPUT_KMSG:
+        case EXEC_OUTPUT_KMSG_AND_CONSOLE:
+        case EXEC_OUTPUT_JOURNAL:
+        case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
+                return connect_logger_as(context, e, ident, unit_id, STDERR_FILENO);
+
+        case EXEC_OUTPUT_SOCKET:
+                assert(socket_fd >= 0);
+                return dup2(socket_fd, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO;
+
+        default:
+                assert_not_reached("Unknown error type");
+        }
+}
+
+static int chown_terminal(int fd, uid_t uid) {
+        struct stat st;
+
+        assert(fd >= 0);
+
+        /* This might fail. What matters are the results. */
+        (void) fchown(fd, uid, -1);
+        (void) fchmod(fd, TTY_MODE);
+
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE)
+                return -EPERM;
+
+        return 0;
+}
+
+static int setup_confirm_stdio(int *_saved_stdin,
+                               int *_saved_stdout) {
+        int fd = -1, saved_stdin, saved_stdout = -1, r;
+
+        assert(_saved_stdin);
+        assert(_saved_stdout);
+
+        saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
+        if (saved_stdin < 0)
+                return -errno;
+
+        saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
+        if (saved_stdout < 0) {
+                r = errno;
+                goto fail;
+        }
+
+        fd = acquire_terminal(
+                        "/dev/console",
+                        false,
+                        false,
+                        false,
+                        DEFAULT_CONFIRM_USEC);
+        if (fd < 0) {
+                r = fd;
+                goto fail;
+        }
+
+        r = chown_terminal(fd, getuid());
+        if (r < 0)
+                goto fail;
+
+        if (dup2(fd, STDIN_FILENO) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if (dup2(fd, STDOUT_FILENO) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if (fd >= 2)
+                close_nointr_nofail(fd);
+
+        *_saved_stdin = saved_stdin;
+        *_saved_stdout = saved_stdout;
+
+        return 0;
+
+fail:
+        if (saved_stdout >= 0)
+                close_nointr_nofail(saved_stdout);
+
+        if (saved_stdin >= 0)
+                close_nointr_nofail(saved_stdin);
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
+
+static int write_confirm_message(const char *format, ...) {
+        int fd;
+        va_list ap;
+
+        assert(format);
+
+        fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        va_start(ap, format);
+        vdprintf(fd, format, ap);
+        va_end(ap);
+
+        close_nointr_nofail(fd);
+
+        return 0;
+}
+
+static int restore_confirm_stdio(int *saved_stdin,
+                                 int *saved_stdout) {
+
+        int r = 0;
+
+        assert(saved_stdin);
+        assert(saved_stdout);
+
+        release_terminal();
+
+        if (*saved_stdin >= 0)
+                if (dup2(*saved_stdin, STDIN_FILENO) < 0)
+                        r = -errno;
+
+        if (*saved_stdout >= 0)
+                if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
+                        r = -errno;
+
+        if (*saved_stdin >= 0)
+                close_nointr_nofail(*saved_stdin);
+
+        if (*saved_stdout >= 0)
+                close_nointr_nofail(*saved_stdout);
+
+        return r;
+}
+
+static int ask_for_confirmation(char *response, char **argv) {
+        int saved_stdout = -1, saved_stdin = -1, r;
+        char *line;
+
+        r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
+        if (r < 0)
+                return r;
+
+        line = exec_command_line(argv);
+        if (!line)
+                return -ENOMEM;
+
+        r = ask(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
+        free(line);
+
+        restore_confirm_stdio(&saved_stdin, &saved_stdout);
+
+        return r;
+}
+
+static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
+        bool keep_groups = false;
+        int r;
+
+        assert(context);
+
+        /* Lookup and set GID and supplementary group list. Here too
+         * we avoid NSS lookups for gid=0. */
+
+        if (context->group || username) {
+
+                if (context->group) {
+                        const char *g = context->group;
+
+                        if ((r = get_group_creds(&g, &gid)) < 0)
+                                return r;
+                }
+
+                /* First step, initialize groups from /etc/groups */
+                if (username && gid != 0) {
+                        if (initgroups(username, gid) < 0)
+                                return -errno;
+
+                        keep_groups = true;
+                }
+
+                /* Second step, set our gids */
+                if (setresgid(gid, gid, gid) < 0)
+                        return -errno;
+        }
+
+        if (context->supplementary_groups) {
+                int ngroups_max, k;
+                gid_t *gids;
+                char **i;
+
+                /* Final step, initialize any manually set supplementary groups */
+                assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
+
+                if (!(gids = new(gid_t, ngroups_max)))
+                        return -ENOMEM;
+
+                if (keep_groups) {
+                        if ((k = getgroups(ngroups_max, gids)) < 0) {
+                                free(gids);
+                                return -errno;
+                        }
+                } else
+                        k = 0;
+
+                STRV_FOREACH(i, context->supplementary_groups) {
+                        const char *g;
+
+                        if (k >= ngroups_max) {
+                                free(gids);
+                                return -E2BIG;
+                        }
+
+                        g = *i;
+                        r = get_group_creds(&g, gids+k);
+                        if (r < 0) {
+                                free(gids);
+                                return r;
+                        }
+
+                        k++;
+                }
+
+                if (setgroups(k, gids) < 0) {
+                        free(gids);
+                        return -errno;
+                }
+
+                free(gids);
+        }
+
+        return 0;
+}
+
+static int enforce_user(const ExecContext *context, uid_t uid) {
+        int r;
+        assert(context);
+
+        /* Sets (but doesn't lookup) the uid and make sure we keep the
+         * capabilities while doing so. */
+
+        if (context->capabilities) {
+                cap_t d;
+                static const cap_value_t bits[] = {
+                        CAP_SETUID,   /* Necessary so that we can run setresuid() below */
+                        CAP_SETPCAP   /* Necessary so that we can set PR_SET_SECUREBITS later on */
+                };
+
+                /* First step: If we need to keep capabilities but
+                 * drop privileges we need to make sure we keep our
+                 * caps, whiel we drop privileges. */
+                if (uid != 0) {
+                        int sb = context->secure_bits|SECURE_KEEP_CAPS;
+
+                        if (prctl(PR_GET_SECUREBITS) != sb)
+                                if (prctl(PR_SET_SECUREBITS, sb) < 0)
+                                        return -errno;
+                }
+
+                /* Second step: set the capabilities. This will reduce
+                 * the capabilities to the minimum we need. */
+
+                if (!(d = cap_dup(context->capabilities)))
+                        return -errno;
+
+                if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
+                    cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) {
+                        r = -errno;
+                        cap_free(d);
+                        return r;
+                }
+
+                if (cap_set_proc(d) < 0) {
+                        r = -errno;
+                        cap_free(d);
+                        return r;
+                }
+
+                cap_free(d);
+        }
+
+        /* Third step: actually set the uids */
+        if (setresuid(uid, uid, uid) < 0)
+                return -errno;
+
+        /* At this point we should have all necessary capabilities but
+           are otherwise a normal user. However, the caps might got
+           corrupted due to the setresuid() so we need clean them up
+           later. This is done outside of this call. */
+
+        return 0;
+}
+
+#ifdef HAVE_PAM
+
+static int null_conv(
+                int num_msg,
+                const struct pam_message **msg,
+                struct pam_response **resp,
+                void *appdata_ptr) {
+
+        /* We don't support conversations */
+
+        return PAM_CONV_ERR;
+}
+
+static int setup_pam(
+                const char *name,
+                const char *user,
+                uid_t uid,
+                const char *tty,
+                char ***pam_env,
+                int fds[], unsigned n_fds) {
+
+        static const struct pam_conv conv = {
+                .conv = null_conv,
+                .appdata_ptr = NULL
+        };
+
+        pam_handle_t *handle = NULL;
+        sigset_t ss, old_ss;
+        int pam_code = PAM_SUCCESS;
+        int err;
+        char **e = NULL;
+        bool close_session = false;
+        pid_t pam_pid = 0, parent_pid;
+
+        assert(name);
+        assert(user);
+        assert(pam_env);
+
+        /* We set up PAM in the parent process, then fork. The child
+         * will then stay around until killed via PR_GET_PDEATHSIG or
+         * systemd via the cgroup logic. It will then remove the PAM
+         * session again. The parent process will exec() the actual
+         * daemon. We do things this way to ensure that the main PID
+         * of the daemon is the one we initially fork()ed. */
+
+        if ((pam_code = pam_start(name, user, &conv, &handle)) != PAM_SUCCESS) {
+                handle = NULL;
+                goto fail;
+        }
+
+        if (tty)
+                if ((pam_code = pam_set_item(handle, PAM_TTY, tty)) != PAM_SUCCESS)
+                        goto fail;
+
+        if ((pam_code = pam_acct_mgmt(handle, PAM_SILENT)) != PAM_SUCCESS)
+                goto fail;
+
+        if ((pam_code = pam_open_session(handle, PAM_SILENT)) != PAM_SUCCESS)
+                goto fail;
+
+        close_session = true;
+
+        if ((!(e = pam_getenvlist(handle)))) {
+                pam_code = PAM_BUF_ERR;
+                goto fail;
+        }
+
+        /* Block SIGTERM, so that we know that it won't get lost in
+         * the child */
+        if (sigemptyset(&ss) < 0 ||
+            sigaddset(&ss, SIGTERM) < 0 ||
+            sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0)
+                goto fail;
+
+        parent_pid = getpid();
+
+        if ((pam_pid = fork()) < 0)
+                goto fail;
+
+        if (pam_pid == 0) {
+                int sig;
+                int r = EXIT_PAM;
+
+                /* The child's job is to reset the PAM session on
+                 * termination */
+
+                /* This string must fit in 10 chars (i.e. the length
+                 * of "/sbin/init"), to look pretty in /bin/ps */
+                rename_process("(sd-pam)");
+
+                /* Make sure we don't keep open the passed fds in this
+                child. We assume that otherwise only those fds are
+                open here that have been opened by PAM. */
+                close_many(fds, n_fds);
+
+                /* Drop privileges - we don't need any to pam_close_session
+                 * and this will make PR_SET_PDEATHSIG work in most cases.
+                 * If this fails, ignore the error - but expect sd-pam threads
+                 * to fail to exit normally */
+                if (setresuid(uid, uid, uid) < 0)
+                        log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r));
+
+                /* Wait until our parent died. This will only work if
+                 * the above setresuid() succeeds, otherwise the kernel
+                 * will not allow unprivileged parents kill their privileged
+                 * children this way. We rely on the control groups kill logic
+                 * to do the rest for us. */
+                if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
+                        goto child_finish;
+
+                /* Check if our parent process might already have
+                 * died? */
+                if (getppid() == parent_pid) {
+                        for (;;) {
+                                if (sigwait(&ss, &sig) < 0) {
+                                        if (errno == EINTR)
+                                                continue;
+
+                                        goto child_finish;
+                                }
+
+                                assert(sig == SIGTERM);
+                                break;
+                        }
+                }
+
+                /* If our parent died we'll end the session */
+                if (getppid() != parent_pid)
+                        if ((pam_code = pam_close_session(handle, PAM_DATA_SILENT)) != PAM_SUCCESS)
+                                goto child_finish;
+
+                r = 0;
+
+        child_finish:
+                pam_end(handle, pam_code | PAM_DATA_SILENT);
+                _exit(r);
+        }
+
+        /* If the child was forked off successfully it will do all the
+         * cleanups, so forget about the handle here. */
+        handle = NULL;
+
+        /* Unblock SIGTERM again in the parent */
+        if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0)
+                goto fail;
+
+        /* We close the log explicitly here, since the PAM modules
+         * might have opened it, but we don't want this fd around. */
+        closelog();
+
+        *pam_env = e;
+        e = NULL;
+
+        return 0;
+
+fail:
+        if (pam_code != PAM_SUCCESS)
+                err = -EPERM;  /* PAM errors do not map to errno */
+        else
+                err = -errno;
+
+        if (handle) {
+                if (close_session)
+                        pam_code = pam_close_session(handle, PAM_DATA_SILENT);
+
+                pam_end(handle, pam_code | PAM_DATA_SILENT);
+        }
+
+        strv_free(e);
+
+        closelog();
+
+        if (pam_pid > 1) {
+                kill(pam_pid, SIGTERM);
+                kill(pam_pid, SIGCONT);
+        }
+
+        return err;
+}
+#endif
+
+static void rename_process_from_path(const char *path) {
+        char process_name[11];
+        const char *p;
+        size_t l;
+
+        /* This resulting string must fit in 10 chars (i.e. the length
+         * of "/sbin/init") to look pretty in /bin/ps */
+
+        p = path_get_file_name(path);
+        if (isempty(p)) {
+                rename_process("(...)");
+                return;
+        }
+
+        l = strlen(p);
+        if (l > 8) {
+                /* The end of the process name is usually more
+                 * interesting, since the first bit might just be
+                 * "systemd-" */
+                p = p + l - 8;
+                l = 8;
+        }
+
+        process_name[0] = '(';
+        memcpy(process_name+1, p, l);
+        process_name[1+l] = ')';
+        process_name[1+l+1] = 0;
+
+        rename_process(process_name);
+}
+
+static int apply_seccomp(uint32_t *syscall_filter) {
+        static const struct sock_filter header[] = {
+                VALIDATE_ARCHITECTURE,
+                EXAMINE_SYSCALL
+        };
+        static const struct sock_filter footer[] = {
+                _KILL_PROCESS
+        };
+
+        int i;
+        unsigned n;
+        struct sock_filter *f;
+        struct sock_fprog prog;
+
+        assert(syscall_filter);
+
+        /* First: count the syscalls to check for */
+        for (i = 0, n = 0; i < syscall_max(); i++)
+                if (syscall_filter[i >> 4] & (1 << (i & 31)))
+                        n++;
+
+        /* Second: build the filter program from a header the syscall
+         * matches and the footer */
+        f = alloca(sizeof(struct sock_filter) * (ELEMENTSOF(header) + 2*n + ELEMENTSOF(footer)));
+        memcpy(f, header, sizeof(header));
+
+        for (i = 0, n = 0; i < syscall_max(); i++)
+                if (syscall_filter[i >> 4] & (1 << (i & 31))) {
+                        struct sock_filter item[] = {
+                                BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, i, 0, 1),
+                                BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
+                        };
+
+                        assert_cc(ELEMENTSOF(item) == 2);
+
+                        f[ELEMENTSOF(header) + 2*n]  = item[0];
+                        f[ELEMENTSOF(header) + 2*n+1] = item[1];
+
+                        n++;
+                }
+
+        memcpy(f + (ELEMENTSOF(header) + 2*n), footer, sizeof(footer));
+
+        /* Third: install the filter */
+        zero(prog);
+        prog.len = ELEMENTSOF(header) + ELEMENTSOF(footer) + 2*n;
+        prog.filter = f;
+        if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int exec_spawn(ExecCommand *command,
+               char **argv,
+               const ExecContext *context,
+               int fds[], unsigned n_fds,
+               char **environment,
+               bool apply_permissions,
+               bool apply_chroot,
+               bool apply_tty_stdin,
+               bool confirm_spawn,
+               CGroupBonding *cgroup_bondings,
+               CGroupAttribute *cgroup_attributes,
+               const char *cgroup_suffix,
+               const char *unit_id,
+               int idle_pipe[2],
+               pid_t *ret) {
+
+        pid_t pid;
+        int r;
+        char *line;
+        int socket_fd;
+        char _cleanup_strv_free_ **files_env = NULL;
+
+        assert(command);
+        assert(context);
+        assert(ret);
+        assert(fds || n_fds <= 0);
+
+        if (context->std_input == EXEC_INPUT_SOCKET ||
+            context->std_output == EXEC_OUTPUT_SOCKET ||
+            context->std_error == EXEC_OUTPUT_SOCKET) {
+
+                if (n_fds != 1)
+                        return -EINVAL;
+
+                socket_fd = fds[0];
+
+                fds = NULL;
+                n_fds = 0;
+        } else
+                socket_fd = -1;
+
+        r = exec_context_load_environment(context, &files_env);
+        if (r < 0) {
+                log_struct(LOG_ERR,
+                           "UNIT=%s", unit_id,
+                           "MESSAGE=Failed to load environment files: %s", strerror(-r),
+                           "ERRNO=%d", -r,
+                           NULL);
+                return r;
+        }
+
+        if (!argv)
+                argv = command->argv;
+
+        line = exec_command_line(argv);
+        if (!line)
+                return log_oom();
+
+        log_struct(LOG_DEBUG,
+                   "UNIT=%s", unit_id,
+                   "MESSAGE=About to execute %s", line,
+                   NULL);
+        free(line);
+
+        r = cgroup_bonding_realize_list(cgroup_bondings);
+        if (r < 0)
+                return r;
+
+        cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings);
+
+        pid = fork();
+        if (pid < 0)
+                return -errno;
+
+        if (pid == 0) {
+                int i, err;
+                sigset_t ss;
+                const char *username = NULL, *home = NULL;
+                uid_t uid = (uid_t) -1;
+                gid_t gid = (gid_t) -1;
+                char _cleanup_strv_free_ **our_env = NULL, **pam_env = NULL,
+                        **final_env = NULL, **final_argv = NULL;
+                unsigned n_env = 0;
+                bool set_access = false;
+
+                /* child */
+
+                rename_process_from_path(command->path);
+
+                /* We reset exactly these signals, since they are the
+                 * only ones we set to SIG_IGN in the main daemon. All
+                 * others we leave untouched because we set them to
+                 * SIG_DFL or a valid handler initially, both of which
+                 * will be demoted to SIG_DFL. */
+                default_signals(SIGNALS_CRASH_HANDLER,
+                                SIGNALS_IGNORE, -1);
+
+                if (context->ignore_sigpipe)
+                        ignore_signals(SIGPIPE, -1);
+
+                assert_se(sigemptyset(&ss) == 0);
+                if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
+                        err = -errno;
+                        r = EXIT_SIGNAL_MASK;
+                        goto fail_child;
+                }
+
+                if (idle_pipe) {
+                        if (idle_pipe[1] >= 0)
+                                close_nointr_nofail(idle_pipe[1]);
+                        if (idle_pipe[0] >= 0) {
+                                fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
+                                close_nointr_nofail(idle_pipe[0]);
+                        }
+                }
+
+                /* Close sockets very early to make sure we don't
+                 * block init reexecution because it cannot bind its
+                 * sockets */
+                log_forget_fds();
+                err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
+                                           socket_fd >= 0 ? 1 : n_fds);
+                if (err < 0) {
+                        r = EXIT_FDS;
+                        goto fail_child;
+                }
+
+                if (!context->same_pgrp)
+                        if (setsid() < 0) {
+                                err = -errno;
+                                r = EXIT_SETSID;
+                                goto fail_child;
+                        }
+
+                if (context->tcpwrap_name) {
+                        if (socket_fd >= 0)
+                                if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
+                                        err = -EACCES;
+                                        r = EXIT_TCPWRAP;
+                                        goto fail_child;
+                                }
+
+                        for (i = 0; i < (int) n_fds; i++) {
+                                if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
+                                        err = -EACCES;
+                                        r = EXIT_TCPWRAP;
+                                        goto fail_child;
+                                }
+                        }
+                }
+
+                exec_context_tty_reset(context);
+
+                if (confirm_spawn) {
+                        char response;
+
+                        err = ask_for_confirmation(&response, argv);
+                        if (err == -ETIMEDOUT)
+                                write_confirm_message("Confirmation question timed out, assuming positive response.\n");
+                        else if (err < 0)
+                                write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-err));
+                        else if (response == 's') {
+                                write_confirm_message("Skipping execution.\n");
+                                err = -ECANCELED;
+                                r = EXIT_CONFIRM;
+                                goto fail_child;
+                        } else if (response == 'n') {
+                                write_confirm_message("Failing execution.\n");
+                                err = r = 0;
+                                goto fail_child;
+                        }
+                }
+
+                /* If a socket is connected to STDIN/STDOUT/STDERR, we
+                 * must sure to drop O_NONBLOCK */
+                if (socket_fd >= 0)
+                        fd_nonblock(socket_fd, false);
+
+                err = setup_input(context, socket_fd, apply_tty_stdin);
+                if (err < 0) {
+                        r = EXIT_STDIN;
+                        goto fail_child;
+                }
+
+                err = setup_output(context, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
+                if (err < 0) {
+                        r = EXIT_STDOUT;
+                        goto fail_child;
+                }
+
+                err = setup_error(context, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
+                if (err < 0) {
+                        r = EXIT_STDERR;
+                        goto fail_child;
+                }
+
+                if (cgroup_bondings) {
+                        err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix);
+                        if (err < 0) {
+                                r = EXIT_CGROUP;
+                                goto fail_child;
+                        }
+                }
+
+                if (context->oom_score_adjust_set) {
+                        char t[16];
+
+                        snprintf(t, sizeof(t), "%i", context->oom_score_adjust);
+                        char_array_0(t);
+
+                        if (write_one_line_file("/proc/self/oom_score_adj", t) < 0) {
+                                err = -errno;
+                                r = EXIT_OOM_ADJUST;
+                                goto fail_child;
+                        }
+                }
+
+                if (context->nice_set)
+                        if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
+                                err = -errno;
+                                r = EXIT_NICE;
+                                goto fail_child;
+                        }
+
+                if (context->cpu_sched_set) {
+                        struct sched_param param;
+
+                        zero(param);
+                        param.sched_priority = context->cpu_sched_priority;
+
+                        if (sched_setscheduler(0, context->cpu_sched_policy |
+                                               (context->cpu_sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0), &param) < 0) {
+                                err = -errno;
+                                r = EXIT_SETSCHEDULER;
+                                goto fail_child;
+                        }
+                }
+
+                if (context->cpuset)
+                        if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
+                                err = -errno;
+                                r = EXIT_CPUAFFINITY;
+                                goto fail_child;
+                        }
+
+                if (context->ioprio_set)
+                        if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
+                                err = -errno;
+                                r = EXIT_IOPRIO;
+                                goto fail_child;
+                        }
+
+                if (context->timer_slack_nsec != (nsec_t) -1)
+                        if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
+                                err = -errno;
+                                r = EXIT_TIMERSLACK;
+                                goto fail_child;
+                        }
+
+                if (context->utmp_id)
+                        utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
+
+                if (context->user) {
+                        username = context->user;
+                        err = get_user_creds(&username, &uid, &gid, &home, NULL);
+                        if (err < 0) {
+                                r = EXIT_USER;
+                                goto fail_child;
+                        }
+
+                        if (is_terminal_input(context->std_input)) {
+                                err = chown_terminal(STDIN_FILENO, uid);
+                                if (err < 0) {
+                                        r = EXIT_STDIN;
+                                        goto fail_child;
+                                }
+                        }
+
+                        if (cgroup_bondings && context->control_group_modify) {
+                                err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid);
+                                if (err >= 0)
+                                        err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid, context->control_group_persistent);
+                                if (err < 0) {
+                                        r = EXIT_CGROUP;
+                                        goto fail_child;
+                                }
+
+                                set_access = true;
+                        }
+                }
+
+                if (cgroup_bondings && !set_access && context->control_group_persistent >= 0)  {
+                        err = cgroup_bonding_set_task_access_list(cgroup_bondings, (mode_t) -1, (uid_t) -1, (uid_t) -1, context->control_group_persistent);
+                        if (err < 0) {
+                                r = EXIT_CGROUP;
+                                goto fail_child;
+                        }
+                }
+
+                if (apply_permissions) {
+                        err = enforce_groups(context, username, gid);
+                        if (err < 0) {
+                                r = EXIT_GROUP;
+                                goto fail_child;
+                        }
+                }
+
+                umask(context->umask);
+
+#ifdef HAVE_PAM
+                if (apply_permissions && context->pam_name && username) {
+                        err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
+                        if (err < 0) {
+                                r = EXIT_PAM;
+                                goto fail_child;
+                        }
+                }
+#endif
+                if (context->private_network) {
+                        if (unshare(CLONE_NEWNET) < 0) {
+                                err = -errno;
+                                r = EXIT_NETWORK;
+                                goto fail_child;
+                        }
+
+                        loopback_setup();
+                }
+
+                if (strv_length(context->read_write_dirs) > 0 ||
+                    strv_length(context->read_only_dirs) > 0 ||
+                    strv_length(context->inaccessible_dirs) > 0 ||
+                    context->mount_flags != 0 ||
+                    context->private_tmp) {
+                        err = setup_namespace(context->read_write_dirs,
+                                              context->read_only_dirs,
+                                              context->inaccessible_dirs,
+                                              context->private_tmp,
+                                              context->mount_flags);
+                        if (err < 0) {
+                                r = EXIT_NAMESPACE;
+                                goto fail_child;
+                        }
+                }
+
+                if (apply_chroot) {
+                        if (context->root_directory)
+                                if (chroot(context->root_directory) < 0) {
+                                        err = -errno;
+                                        r = EXIT_CHROOT;
+                                        goto fail_child;
+                                }
+
+                        if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
+                                err = -errno;
+                                r = EXIT_CHDIR;
+                                goto fail_child;
+                        }
+                } else {
+                        char _cleanup_free_ *d = NULL;
+
+                        if (asprintf(&d, "%s/%s",
+                                     context->root_directory ? context->root_directory : "",
+                                     context->working_directory ? context->working_directory : "") < 0) {
+                                err = -ENOMEM;
+                                r = EXIT_MEMORY;
+                                goto fail_child;
+                        }
+
+                        if (chdir(d) < 0) {
+                                err = -errno;
+                                r = EXIT_CHDIR;
+                                goto fail_child;
+                        }
+                }
+
+                /* We repeat the fd closing here, to make sure that
+                 * nothing is leaked from the PAM modules */
+                err = close_all_fds(fds, n_fds);
+                if (err >= 0)
+                        err = shift_fds(fds, n_fds);
+                if (err >= 0)
+                        err = flags_fds(fds, n_fds, context->non_blocking);
+                if (err < 0) {
+                        r = EXIT_FDS;
+                        goto fail_child;
+                }
+
+                if (apply_permissions) {
+
+                        for (i = 0; i < RLIMIT_NLIMITS; i++) {
+                                if (!context->rlimit[i])
+                                        continue;
+
+                                if (setrlimit_closest(i, context->rlimit[i]) < 0) {
+                                        err = -errno;
+                                        r = EXIT_LIMITS;
+                                        goto fail_child;
+                                }
+                        }
+
+                        if (context->capability_bounding_set_drop) {
+                                err = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
+                                if (err < 0) {
+                                        r = EXIT_CAPABILITIES;
+                                        goto fail_child;
+                                }
+                        }
+
+                        if (context->user) {
+                                err = enforce_user(context, uid);
+                                if (err < 0) {
+                                        r = EXIT_USER;
+                                        goto fail_child;
+                                }
+                        }
+
+                        /* PR_GET_SECUREBITS is not privileged, while
+                         * PR_SET_SECUREBITS is. So to suppress
+                         * potential EPERMs we'll try not to call
+                         * PR_SET_SECUREBITS unless necessary. */
+                        if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
+                                if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
+                                        err = -errno;
+                                        r = EXIT_SECUREBITS;
+                                        goto fail_child;
+                                }
+
+                        if (context->capabilities)
+                                if (cap_set_proc(context->capabilities) < 0) {
+                                        err = -errno;
+                                        r = EXIT_CAPABILITIES;
+                                        goto fail_child;
+                                }
+
+                        if (context->no_new_privileges)
+                                if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
+                                        err = -errno;
+                                        r = EXIT_NO_NEW_PRIVILEGES;
+                                        goto fail_child;
+                                }
+
+                        if (context->syscall_filter) {
+                                err = apply_seccomp(context->syscall_filter);
+                                if (err < 0) {
+                                        r = EXIT_SECCOMP;
+                                        goto fail_child;
+                                }
+                        }
+                }
+
+                if (!(our_env = new0(char*, 7))) {
+                        err = -ENOMEM;
+                        r = EXIT_MEMORY;
+                        goto fail_child;
+                }
+
+                if (n_fds > 0)
+                        if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
+                            asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) {
+                                err = -ENOMEM;
+                                r = EXIT_MEMORY;
+                                goto fail_child;
+                        }
+
+                if (home)
+                        if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) {
+                                err = -ENOMEM;
+                                r = EXIT_MEMORY;
+                                goto fail_child;
+                        }
+
+                if (username)
+                        if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
+                            asprintf(our_env + n_env++, "USER=%s", username) < 0) {
+                                err = -ENOMEM;
+                                r = EXIT_MEMORY;
+                                goto fail_child;
+                        }
+
+                if (is_terminal_input(context->std_input) ||
+                    context->std_output == EXEC_OUTPUT_TTY ||
+                    context->std_error == EXEC_OUTPUT_TTY)
+                        if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) {
+                                err = -ENOMEM;
+                                r = EXIT_MEMORY;
+                                goto fail_child;
+                        }
+
+                assert(n_env <= 7);
+
+                if (!(final_env = strv_env_merge(
+                                      5,
+                                      environment,
+                                      our_env,
+                                      context->environment,
+                                      files_env,
+                                      pam_env,
+                                      NULL))) {
+                        err = -ENOMEM;
+                        r = EXIT_MEMORY;
+                        goto fail_child;
+                }
+
+                if (!(final_argv = replace_env_argv(argv, final_env))) {
+                        err = -ENOMEM;
+                        r = EXIT_MEMORY;
+                        goto fail_child;
+                }
+
+                final_env = strv_env_clean(final_env);
+
+                execve(command->path, final_argv, final_env);
+                err = -errno;
+                r = EXIT_EXEC;
+
+        fail_child:
+                if (r != 0) {
+                        log_open();
+                        log_struct(LOG_ERR, MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
+                                   "EXECUTABLE=%s", command->path,
+                                   "MESSAGE=Failed at step %s spawning %s: %s",
+                                          exit_status_to_string(r, EXIT_STATUS_SYSTEMD),
+                                          command->path, strerror(-err),
+                                   "ERRNO=%d", -err,
+                                   NULL);
+                        log_close();
+                }
+
+                _exit(r);
+        }
+
+        log_struct(LOG_DEBUG,
+                   "UNIT=%s", unit_id,
+                   "MESSAGE=Forked %s as %lu",
+                          command->path, (unsigned long) pid,
+                   NULL);
+
+        /* We add the new process to the cgroup both in the child (so
+         * that we can be sure that no user code is ever executed
+         * outside of the cgroup) and in the parent (so that we can be
+         * sure that when we kill the cgroup the process will be
+         * killed too). */
+        if (cgroup_bondings)
+                cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix);
+
+        exec_status_start(&command->exec_status, pid);
+
+        *ret = pid;
+        return 0;
+}
+
+void exec_context_init(ExecContext *c) {
+        assert(c);
+
+        c->umask = 0022;
+        c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
+        c->cpu_sched_policy = SCHED_OTHER;
+        c->syslog_priority = LOG_DAEMON|LOG_INFO;
+        c->syslog_level_prefix = true;
+        c->control_group_persistent = -1;
+        c->ignore_sigpipe = true;
+        c->timer_slack_nsec = (nsec_t) -1;
+}
+
+void exec_context_done(ExecContext *c) {
+        unsigned l;
+
+        assert(c);
+
+        strv_free(c->environment);
+        c->environment = NULL;
+
+        strv_free(c->environment_files);
+        c->environment_files = NULL;
+
+        for (l = 0; l < ELEMENTSOF(c->rlimit); l++) {
+                free(c->rlimit[l]);
+                c->rlimit[l] = NULL;
+        }
+
+        free(c->working_directory);
+        c->working_directory = NULL;
+        free(c->root_directory);
+        c->root_directory = NULL;
+
+        free(c->tty_path);
+        c->tty_path = NULL;
+
+        free(c->tcpwrap_name);
+        c->tcpwrap_name = NULL;
+
+        free(c->syslog_identifier);
+        c->syslog_identifier = NULL;
+
+        free(c->user);
+        c->user = NULL;
+
+        free(c->group);
+        c->group = NULL;
+
+        strv_free(c->supplementary_groups);
+        c->supplementary_groups = NULL;
+
+        free(c->pam_name);
+        c->pam_name = NULL;
+
+        if (c->capabilities) {
+                cap_free(c->capabilities);
+                c->capabilities = NULL;
+        }
+
+        strv_free(c->read_only_dirs);
+        c->read_only_dirs = NULL;
+
+        strv_free(c->read_write_dirs);
+        c->read_write_dirs = NULL;
+
+        strv_free(c->inaccessible_dirs);
+        c->inaccessible_dirs = NULL;
+
+        if (c->cpuset)
+                CPU_FREE(c->cpuset);
+
+        free(c->utmp_id);
+        c->utmp_id = NULL;
+
+        free(c->syscall_filter);
+        c->syscall_filter = NULL;
+}
+
+void exec_command_done(ExecCommand *c) {
+        assert(c);
+
+        free(c->path);
+        c->path = NULL;
+
+        strv_free(c->argv);
+        c->argv = NULL;
+}
+
+void exec_command_done_array(ExecCommand *c, unsigned n) {
+        unsigned i;
+
+        for (i = 0; i < n; i++)
+                exec_command_done(c+i);
+}
+
+void exec_command_free_list(ExecCommand *c) {
+        ExecCommand *i;
+
+        while ((i = c)) {
+                LIST_REMOVE(ExecCommand, command, c, i);
+                exec_command_done(i);
+                free(i);
+        }
+}
+
+void exec_command_free_array(ExecCommand **c, unsigned n) {
+        unsigned i;
+
+        for (i = 0; i < n; i++) {
+                exec_command_free_list(c[i]);
+                c[i] = NULL;
+        }
+}
+
+int exec_context_load_environment(const ExecContext *c, char ***l) {
+        char **i, **r = NULL;
+
+        assert(c);
+        assert(l);
+
+        STRV_FOREACH(i, c->environment_files) {
+                char *fn;
+                int k;
+                bool ignore = false;
+                char **p;
+                glob_t pglob;
+                int count, n;
+
+                fn = *i;
+
+                if (fn[0] == '-') {
+                        ignore = true;
+                        fn ++;
+                }
+
+                if (!path_is_absolute(fn)) {
+
+                        if (ignore)
+                                continue;
+
+                        strv_free(r);
+                        return -EINVAL;
+                }
+
+                /* Filename supports globbing, take all matching files */
+                zero(pglob);
+                errno = 0;
+                if (glob(fn, 0, NULL, &pglob) != 0) {
+                        globfree(&pglob);
+                        if (ignore)
+                                continue;
+
+                        strv_free(r);
+                        return errno ? -errno : -EINVAL;
+                }
+                count = pglob.gl_pathc;
+                if (count == 0) {
+                        globfree(&pglob);
+                        if (ignore)
+                                continue;
+
+                        strv_free(r);
+                        return -EINVAL;
+                }
+                for (n = 0; n < count; n++) {
+                        k = load_env_file(pglob.gl_pathv[n], &p);
+                        if (k < 0) {
+                                if (ignore)
+                                        continue;
+
+                                strv_free(r);
+                                globfree(&pglob);
+                                return k;
+                         }
+
+                        if (r == NULL)
+                                r = p;
+                        else {
+                                char **m;
+
+                                m = strv_env_merge(2, r, p);
+                                strv_free(r);
+                                strv_free(p);
+
+                                if (!m) {
+                                        globfree(&pglob);
+                                        return -ENOMEM;
+                                }
+
+                                r = m;
+                        }
+                }
+                globfree(&pglob);
+        }
+
+        *l = r;
+
+        return 0;
+}
+
+static void strv_fprintf(FILE *f, char **l) {
+        char **g;
+
+        assert(f);
+
+        STRV_FOREACH(g, l)
+                fprintf(f, " %s", *g);
+}
+
+void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
+        char ** e;
+        unsigned i;
+
+        assert(c);
+        assert(f);
+
+        if (!prefix)
+                prefix = "";
+
+        fprintf(f,
+                "%sUMask: %04o\n"
+                "%sWorkingDirectory: %s\n"
+                "%sRootDirectory: %s\n"
+                "%sNonBlocking: %s\n"
+                "%sPrivateTmp: %s\n"
+                "%sControlGroupModify: %s\n"
+                "%sControlGroupPersistent: %s\n"
+                "%sPrivateNetwork: %s\n"
+                "%sIgnoreSIGPIPE: %s\n",
+                prefix, c->umask,
+                prefix, c->working_directory ? c->working_directory : "/",
+                prefix, c->root_directory ? c->root_directory : "/",
+                prefix, yes_no(c->non_blocking),
+                prefix, yes_no(c->private_tmp),
+                prefix, yes_no(c->control_group_modify),
+                prefix, yes_no(c->control_group_persistent),
+                prefix, yes_no(c->private_network),
+                prefix, yes_no(c->ignore_sigpipe));
+
+        STRV_FOREACH(e, c->environment)
+                fprintf(f, "%sEnvironment: %s\n", prefix, *e);
+
+        STRV_FOREACH(e, c->environment_files)
+                fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
+
+        if (c->tcpwrap_name)
+                fprintf(f,
+                        "%sTCPWrapName: %s\n",
+                        prefix, c->tcpwrap_name);
+
+        if (c->nice_set)
+                fprintf(f,
+                        "%sNice: %i\n",
+                        prefix, c->nice);
+
+        if (c->oom_score_adjust_set)
+                fprintf(f,
+                        "%sOOMScoreAdjust: %i\n",
+                        prefix, c->oom_score_adjust);
+
+        for (i = 0; i < RLIM_NLIMITS; i++)
+                if (c->rlimit[i])
+                        fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max);
+
+        if (c->ioprio_set) {
+                char *class_str;
+                int r;
+
+                r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
+                if (r < 0)
+                        class_str = NULL;
+                fprintf(f,
+                        "%sIOSchedulingClass: %s\n"
+                        "%sIOPriority: %i\n",
+                        prefix, strna(class_str),
+                        prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
+                free(class_str);
+        }
+
+        if (c->cpu_sched_set) {
+                char *policy_str;
+                int r;
+
+                r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
+                if (r < 0)
+                        policy_str = NULL;
+                fprintf(f,
+                        "%sCPUSchedulingPolicy: %s\n"
+                        "%sCPUSchedulingPriority: %i\n"
+                        "%sCPUSchedulingResetOnFork: %s\n",
+                        prefix, strna(policy_str),
+                        prefix, c->cpu_sched_priority,
+                        prefix, yes_no(c->cpu_sched_reset_on_fork));
+                free(policy_str);
+       }
+
+        if (c->cpuset) {
+                fprintf(f, "%sCPUAffinity:", prefix);
+                for (i = 0; i < c->cpuset_ncpus; i++)
+                        if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
+                                fprintf(f, " %i", i);
+                fputs("\n", f);
+        }
+
+        if (c->timer_slack_nsec != (nsec_t) -1)
+                fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, (unsigned long)c->timer_slack_nsec);
+
+        fprintf(f,
+                "%sStandardInput: %s\n"
+                "%sStandardOutput: %s\n"
+                "%sStandardError: %s\n",
+                prefix, exec_input_to_string(c->std_input),
+                prefix, exec_output_to_string(c->std_output),
+                prefix, exec_output_to_string(c->std_error));
+
+        if (c->tty_path)
+                fprintf(f,
+                        "%sTTYPath: %s\n"
+                        "%sTTYReset: %s\n"
+                        "%sTTYVHangup: %s\n"
+                        "%sTTYVTDisallocate: %s\n",
+                        prefix, c->tty_path,
+                        prefix, yes_no(c->tty_reset),
+                        prefix, yes_no(c->tty_vhangup),
+                        prefix, yes_no(c->tty_vt_disallocate));
+
+        if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL ||
+            c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
+            c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL ||
+            c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
+                char *fac_str, *lvl_str;
+                int r;
+
+                r = log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
+                if (r < 0)
+                        fac_str = NULL;
+
+                r = log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
+                if (r < 0)
+                        lvl_str = NULL;
+
+                fprintf(f,
+                        "%sSyslogFacility: %s\n"
+                        "%sSyslogLevel: %s\n",
+                        prefix, strna(fac_str),
+                        prefix, strna(lvl_str));
+                free(lvl_str);
+                free(fac_str);
+        }
+
+        if (c->capabilities) {
+                char *t;
+                if ((t = cap_to_text(c->capabilities, NULL))) {
+                        fprintf(f, "%sCapabilities: %s\n",
+                                prefix, t);
+                        cap_free(t);
+                }
+        }
+
+        if (c->secure_bits)
+                fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
+                        prefix,
+                        (c->secure_bits & SECURE_KEEP_CAPS) ? " keep-caps" : "",
+                        (c->secure_bits & SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
+                        (c->secure_bits & SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
+                        (c->secure_bits & SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
+                        (c->secure_bits & SECURE_NOROOT) ? " noroot" : "",
+                        (c->secure_bits & SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
+
+        if (c->capability_bounding_set_drop) {
+                unsigned long l;
+                fprintf(f, "%sCapabilityBoundingSet:", prefix);
+
+                for (l = 0; l <= cap_last_cap(); l++)
+                        if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) {
+                                char *t;
+
+                                if ((t = cap_to_name(l))) {
+                                        fprintf(f, " %s", t);
+                                        cap_free(t);
+                                }
+                        }
+
+                fputs("\n", f);
+        }
+
+        if (c->user)
+                fprintf(f, "%sUser: %s\n", prefix, c->user);
+        if (c->group)
+                fprintf(f, "%sGroup: %s\n", prefix, c->group);
+
+        if (strv_length(c->supplementary_groups) > 0) {
+                fprintf(f, "%sSupplementaryGroups:", prefix);
+                strv_fprintf(f, c->supplementary_groups);
+                fputs("\n", f);
+        }
+
+        if (c->pam_name)
+                fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
+
+        if (strv_length(c->read_write_dirs) > 0) {
+                fprintf(f, "%sReadWriteDirs:", prefix);
+                strv_fprintf(f, c->read_write_dirs);
+                fputs("\n", f);
+        }
+
+        if (strv_length(c->read_only_dirs) > 0) {
+                fprintf(f, "%sReadOnlyDirs:", prefix);
+                strv_fprintf(f, c->read_only_dirs);
+                fputs("\n", f);
+        }
+
+        if (strv_length(c->inaccessible_dirs) > 0) {
+                fprintf(f, "%sInaccessibleDirs:", prefix);
+                strv_fprintf(f, c->inaccessible_dirs);
+                fputs("\n", f);
+        }
+
+        if (c->utmp_id)
+                fprintf(f,
+                        "%sUtmpIdentifier: %s\n",
+                        prefix, c->utmp_id);
+}
+
+void exec_status_start(ExecStatus *s, pid_t pid) {
+        assert(s);
+
+        zero(*s);
+        s->pid = pid;
+        dual_timestamp_get(&s->start_timestamp);
+}
+
+void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
+        assert(s);
+
+        if (s->pid && s->pid != pid)
+                zero(*s);
+
+        s->pid = pid;
+        dual_timestamp_get(&s->exit_timestamp);
+
+        s->code = code;
+        s->status = status;
+
+        if (context) {
+                if (context->utmp_id)
+                        utmp_put_dead_process(context->utmp_id, pid, code, status);
+
+                exec_context_tty_reset(context);
+        }
+}
+
+void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
+        char buf[FORMAT_TIMESTAMP_MAX];
+
+        assert(s);
+        assert(f);
+
+        if (!prefix)
+                prefix = "";
+
+        if (s->pid <= 0)
+                return;
+
+        fprintf(f,
+                "%sPID: %lu\n",
+                prefix, (unsigned long) s->pid);
+
+        if (s->start_timestamp.realtime > 0)
+                fprintf(f,
+                        "%sStart Timestamp: %s\n",
+                        prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
+
+        if (s->exit_timestamp.realtime > 0)
+                fprintf(f,
+                        "%sExit Timestamp: %s\n"
+                        "%sExit Code: %s\n"
+                        "%sExit Status: %i\n",
+                        prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
+                        prefix, sigchld_code_to_string(s->code),
+                        prefix, s->status);
+}
+
+char *exec_command_line(char **argv) {
+        size_t k;
+        char *n, *p, **a;
+        bool first = true;
+
+        assert(argv);
+
+        k = 1;
+        STRV_FOREACH(a, argv)
+                k += strlen(*a)+3;
+
+        if (!(n = new(char, k)))
+                return NULL;
+
+        p = n;
+        STRV_FOREACH(a, argv) {
+
+                if (!first)
+                        *(p++) = ' ';
+                else
+                        first = false;
+
+                if (strpbrk(*a, WHITESPACE)) {
+                        *(p++) = '\'';
+                        p = stpcpy(p, *a);
+                        *(p++) = '\'';
+                } else
+                        p = stpcpy(p, *a);
+
+        }
+
+        *p = 0;
+
+        /* FIXME: this doesn't really handle arguments that have
+         * spaces and ticks in them */
+
+        return n;
+}
+
+void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
+        char *p2;
+        const char *prefix2;
+
+        char *cmd;
+
+        assert(c);
+        assert(f);
+
+        if (!prefix)
+                prefix = "";
+        p2 = strappend(prefix, "\t");
+        prefix2 = p2 ? p2 : prefix;
+
+        cmd = exec_command_line(c->argv);
+
+        fprintf(f,
+                "%sCommand Line: %s\n",
+                prefix, cmd ? cmd : strerror(ENOMEM));
+
+        free(cmd);
+
+        exec_status_dump(&c->exec_status, f, prefix2);
+
+        free(p2);
+}
+
+void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
+        assert(f);
+
+        if (!prefix)
+                prefix = "";
+
+        LIST_FOREACH(command, c, c)
+                exec_command_dump(c, f, prefix);
+}
+
+void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
+        ExecCommand *end;
+
+        assert(l);
+        assert(e);
+
+        if (*l) {
+                /* It's kind of important, that we keep the order here */
+                LIST_FIND_TAIL(ExecCommand, command, *l, end);
+                LIST_INSERT_AFTER(ExecCommand, command, *l, end, e);
+        } else
+              *l = e;
+}
+
+int exec_command_set(ExecCommand *c, const char *path, ...) {
+        va_list ap;
+        char **l, *p;
+
+        assert(c);
+        assert(path);
+
+        va_start(ap, path);
+        l = strv_new_ap(path, ap);
+        va_end(ap);
+
+        if (!l)
+                return -ENOMEM;
+
+        if (!(p = strdup(path))) {
+                strv_free(l);
+                return -ENOMEM;
+        }
+
+        free(c->path);
+        c->path = p;
+
+        strv_free(c->argv);
+        c->argv = l;
+
+        return 0;
+}
+
+static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
+        [EXEC_INPUT_NULL] = "null",
+        [EXEC_INPUT_TTY] = "tty",
+        [EXEC_INPUT_TTY_FORCE] = "tty-force",
+        [EXEC_INPUT_TTY_FAIL] = "tty-fail",
+        [EXEC_INPUT_SOCKET] = "socket"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
+
+static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
+        [EXEC_OUTPUT_INHERIT] = "inherit",
+        [EXEC_OUTPUT_NULL] = "null",
+        [EXEC_OUTPUT_TTY] = "tty",
+        [EXEC_OUTPUT_SYSLOG] = "syslog",
+        [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
+        [EXEC_OUTPUT_KMSG] = "kmsg",
+        [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
+        [EXEC_OUTPUT_JOURNAL] = "journal",
+        [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
+        [EXEC_OUTPUT_SOCKET] = "socket"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
diff --git a/src/core/execute.h b/src/core/execute.h
new file mode 100644 (file)
index 0000000..2bcd2e1
--- /dev/null
@@ -0,0 +1,209 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct ExecStatus ExecStatus;
+typedef struct ExecCommand ExecCommand;
+typedef struct ExecContext ExecContext;
+
+#include <linux/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/capability.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sched.h>
+
+struct CGroupBonding;
+struct CGroupAttribute;
+
+#include "list.h"
+#include "util.h"
+
+typedef enum ExecInput {
+        EXEC_INPUT_NULL,
+        EXEC_INPUT_TTY,
+        EXEC_INPUT_TTY_FORCE,
+        EXEC_INPUT_TTY_FAIL,
+        EXEC_INPUT_SOCKET,
+        _EXEC_INPUT_MAX,
+        _EXEC_INPUT_INVALID = -1
+} ExecInput;
+
+typedef enum ExecOutput {
+        EXEC_OUTPUT_INHERIT,
+        EXEC_OUTPUT_NULL,
+        EXEC_OUTPUT_TTY,
+        EXEC_OUTPUT_SYSLOG,
+        EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
+        EXEC_OUTPUT_KMSG,
+        EXEC_OUTPUT_KMSG_AND_CONSOLE,
+        EXEC_OUTPUT_JOURNAL,
+        EXEC_OUTPUT_JOURNAL_AND_CONSOLE,
+        EXEC_OUTPUT_SOCKET,
+        _EXEC_OUTPUT_MAX,
+        _EXEC_OUTPUT_INVALID = -1
+} ExecOutput;
+
+struct ExecStatus {
+        dual_timestamp start_timestamp;
+        dual_timestamp exit_timestamp;
+        pid_t pid;
+        int code;     /* as in siginfo_t::si_code */
+        int status;   /* as in sigingo_t::si_status */
+};
+
+struct ExecCommand {
+        char *path;
+        char **argv;
+        ExecStatus exec_status;
+        LIST_FIELDS(ExecCommand, command); /* useful for chaining commands */
+        bool ignore;
+};
+
+struct ExecContext {
+        char **environment;
+        char **environment_files;
+
+        struct rlimit *rlimit[RLIMIT_NLIMITS];
+        char *working_directory, *root_directory;
+
+        mode_t umask;
+        int oom_score_adjust;
+        int nice;
+        int ioprio;
+        int cpu_sched_policy;
+        int cpu_sched_priority;
+
+        cpu_set_t *cpuset;
+        unsigned cpuset_ncpus;
+
+        ExecInput std_input;
+        ExecOutput std_output;
+        ExecOutput std_error;
+
+        nsec_t timer_slack_nsec;
+
+        char *tcpwrap_name;
+
+        char *tty_path;
+
+        bool tty_reset;
+        bool tty_vhangup;
+        bool tty_vt_disallocate;
+
+        bool ignore_sigpipe;
+
+        /* Since resolving these names might might involve socket
+         * connections and we don't want to deadlock ourselves these
+         * names are resolved on execution only and in the child
+         * process. */
+        char *user;
+        char *group;
+        char **supplementary_groups;
+
+        char *pam_name;
+
+        char *utmp_id;
+
+        char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;
+        unsigned long mount_flags;
+
+        uint64_t capability_bounding_set_drop;
+
+        cap_t capabilities;
+        int secure_bits;
+
+        int syslog_priority;
+        char *syslog_identifier;
+        bool syslog_level_prefix;
+
+        bool cpu_sched_reset_on_fork;
+        bool non_blocking;
+        bool private_tmp;
+        bool private_network;
+
+        bool no_new_privileges;
+
+        bool control_group_modify;
+        int control_group_persistent;
+
+        /* This is not exposed to the user but available
+         * internally. We need it to make sure that whenever we spawn
+         * /bin/mount it is run in the same process group as us so
+         * that the autofs logic detects that it belongs to us and we
+         * don't enter a trigger loop. */
+        bool same_pgrp;
+
+        uint32_t *syscall_filter;
+
+        bool oom_score_adjust_set:1;
+        bool nice_set:1;
+        bool ioprio_set:1;
+        bool cpu_sched_set:1;
+};
+
+int exec_spawn(ExecCommand *command,
+               char **argv,
+               const ExecContext *context,
+               int fds[], unsigned n_fds,
+               char **environment,
+               bool apply_permissions,
+               bool apply_chroot,
+               bool apply_tty_stdin,
+               bool confirm_spawn,
+               struct CGroupBonding *cgroup_bondings,
+               struct CGroupAttribute *cgroup_attributes,
+               const char *cgroup_suffix,
+               const char *unit_id,
+               int pipe_fd[2],
+               pid_t *ret);
+
+void exec_command_done(ExecCommand *c);
+void exec_command_done_array(ExecCommand *c, unsigned n);
+
+void exec_command_free_list(ExecCommand *c);
+void exec_command_free_array(ExecCommand **c, unsigned n);
+
+char *exec_command_line(char **argv);
+
+void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix);
+void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix);
+void exec_command_append_list(ExecCommand **l, ExecCommand *e);
+int exec_command_set(ExecCommand *c, const char *path, ...);
+
+void exec_context_init(ExecContext *c);
+void exec_context_done(ExecContext *c);
+void exec_context_dump(ExecContext *c, FILE* f, const char *prefix);
+void exec_context_tty_reset(const ExecContext *context);
+
+int exec_context_load_environment(const ExecContext *c, char ***l);
+
+void exec_status_start(ExecStatus *s, pid_t pid);
+void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status);
+void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix);
+
+const char* exec_output_to_string(ExecOutput i);
+ExecOutput exec_output_from_string(const char *s);
+
+const char* exec_input_to_string(ExecInput i);
+ExecInput exec_input_from_string(const char *s);
diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c
new file mode 100644 (file)
index 0000000..7894f8a
--- /dev/null
@@ -0,0 +1,91 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "hostname-setup.h"
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+
+static int read_and_strip_hostname(const char *path, char **hn) {
+        char *s;
+        int r;
+
+        assert(path);
+        assert(hn);
+
+        r = read_one_line_file(path, &s);
+        if (r < 0)
+                return r;
+
+        hostname_cleanup(s);
+
+        if (isempty(s)) {
+                free(s);
+                return -ENOENT;
+        }
+
+        *hn = s;
+        return 0;
+}
+
+int hostname_setup(void) {
+        int r;
+        _cleanup_free_ char *b = NULL;
+        const char *hn;
+        bool enoent = false;
+
+        r = read_and_strip_hostname("/etc/hostname", &b);
+        if (r < 0) {
+                if (r == -ENOENT)
+                        enoent = true;
+                else
+                        log_warning("Failed to read configured hostname: %s", strerror(-r));
+
+                hn = NULL;
+        } else
+                hn = b;
+
+        if (isempty(hn)) {
+                /* Don't override the hostname if it is already set
+                 * and not explicitly configured */
+                if (hostname_is_set())
+                        return 0;
+
+                if (enoent)
+                        log_info("No hostname configured.");
+
+                hn = "localhost";
+        }
+
+        if (sethostname(hn, strlen(hn)) < 0) {
+                log_warning("Failed to set hostname to <%s>: %m", hn);
+                return -errno;
+        }
+
+        log_info("Set hostname to <%s>.", hn);
+        return 0;
+}
diff --git a/src/core/hostname-setup.h b/src/core/hostname-setup.h
new file mode 100644 (file)
index 0000000..8dc3a9e
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int hostname_setup(void);
diff --git a/src/core/ima-setup.c b/src/core/ima-setup.c
new file mode 100644 (file)
index 0000000..e8cc1ba
--- /dev/null
@@ -0,0 +1,115 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy
+                                     TORSEC group -- http://security.polito.it
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "ima-setup.h"
+#include "mount-setup.h"
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+#include "label.h"
+
+#define IMA_SECFS_DIR "/sys/kernel/security/ima"
+#define IMA_SECFS_POLICY IMA_SECFS_DIR "/policy"
+#define IMA_POLICY_PATH "/etc/ima/ima-policy"
+
+int ima_setup(void) {
+
+#ifdef HAVE_IMA
+       struct stat st;
+       ssize_t policy_size = 0, written = 0;
+       char *policy;
+       int policyfd = -1, imafd = -1;
+       int result = 0;
+
+#ifndef HAVE_SELINUX
+       /* Mount the securityfs filesystem */
+       mount_setup_early();
+#endif
+
+       if (stat(IMA_POLICY_PATH, &st) < 0)
+               return 0;
+
+       policy_size = st.st_size;
+       if (stat(IMA_SECFS_DIR, &st) < 0) {
+               log_debug("IMA support is disabled in the kernel, ignoring.");
+               return 0;
+       }
+
+       if (stat(IMA_SECFS_POLICY, &st) < 0) {
+               log_error("Another IMA custom policy has already been loaded, "
+                         "ignoring.");
+               return 0;
+       }
+
+       policyfd = open(IMA_POLICY_PATH, O_RDONLY|O_CLOEXEC);
+       if (policyfd < 0) {
+               log_error("Failed to open the IMA custom policy file %s (%m), "
+                         "ignoring.", IMA_POLICY_PATH);
+               return 0;
+       }
+
+       imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC);
+       if (imafd < 0) {
+               log_error("Failed to open the IMA kernel interface %s (%m), "
+                         "ignoring.", IMA_SECFS_POLICY);
+               goto out;
+       }
+
+       policy = mmap(NULL, policy_size, PROT_READ, MAP_PRIVATE, policyfd, 0);
+       if (policy == MAP_FAILED) {
+               log_error("mmap() failed (%m), freezing");
+               result = -errno;
+               goto out;
+       }
+
+       written = loop_write(imafd, policy, (size_t)policy_size, false);
+       if (written != policy_size) {
+               log_error("Failed to load the IMA custom policy file %s (%m), "
+                         "ignoring.", IMA_POLICY_PATH);
+               goto out_mmap;
+       }
+
+       log_info("Successfully loaded the IMA custom policy %s.",
+                IMA_POLICY_PATH);
+out_mmap:
+       munmap(policy, policy_size);
+out:
+       if (policyfd >= 0)
+                close_nointr_nofail(policyfd);
+       if (imafd >= 0)
+                close_nointr_nofail(imafd);
+       if (result)
+                return result;
+#endif /* HAVE_IMA */
+
+       return 0;
+}
diff --git a/src/core/ima-setup.h b/src/core/ima-setup.h
new file mode 100644 (file)
index 0000000..14b56d1
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy
+                                     TORSEC group -- http://security.polito.it
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int ima_setup(void);
diff --git a/src/core/initreq.h b/src/core/initreq.h
new file mode 100644 (file)
index 0000000..859042c
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * initreq.h   Interface to talk to init through /dev/initctl.
+ *
+ *             Copyright (C) 1995-2004 Miquel van Smoorenburg
+ *
+ *             This library is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU Lesser General Public
+ *             License as published by the Free Software Foundation; either
+ *             version 2 of the License, or (at your option) any later version.
+ *
+ * Version:     @(#)initreq.h  1.28  31-Mar-2004 MvS
+ *
+ */
+#ifndef _INITREQ_H
+#define _INITREQ_H
+
+#include <sys/param.h>
+
+#if defined(__FreeBSD_kernel__)
+#  define INIT_FIFO  "/etc/.initctl"
+#else
+#  define INIT_FIFO  "/dev/initctl"
+#endif
+
+#define INIT_MAGIC 0x03091969
+#define INIT_CMD_START         0
+#define INIT_CMD_RUNLVL                1
+#define INIT_CMD_POWERFAIL     2
+#define INIT_CMD_POWERFAILNOW  3
+#define INIT_CMD_POWEROK       4
+#define INIT_CMD_BSD           5
+#define INIT_CMD_SETENV                6
+#define INIT_CMD_UNSETENV      7
+
+#define INIT_CMD_CHANGECONS    12345
+
+#ifdef MAXHOSTNAMELEN
+#  define INITRQ_HLEN  MAXHOSTNAMELEN
+#else
+#  define INITRQ_HLEN  64
+#endif
+
+/*
+ *     This is what BSD 4.4 uses when talking to init.
+ *     Linux doesn't use this right now.
+ */
+struct init_request_bsd {
+       char    gen_id[8];              /* Beats me.. telnetd uses "fe" */
+       char    tty_id[16];             /* Tty name minus /dev/tty      */
+       char    host[INITRQ_HLEN];      /* Hostname                     */
+       char    term_type[16];          /* Terminal type                */
+       int     signal;                 /* Signal to send               */
+       int     pid;                    /* Process to send to           */
+       char    exec_name[128];         /* Program to execute           */
+       char    reserved[128];          /* For future expansion.        */
+};
+
+
+/*
+ *     Because of legacy interfaces, "runlevel" and "sleeptime"
+ *     aren't in a separate struct in the union.
+ *
+ *     The weird sizes are because init expects the whole
+ *     struct to be 384 bytes.
+ */
+struct init_request {
+       int     magic;                  /* Magic number                 */
+       int     cmd;                    /* What kind of request         */
+       int     runlevel;               /* Runlevel to change to        */
+       int     sleeptime;              /* Time between TERM and KILL   */
+       union {
+               struct init_request_bsd bsd;
+               char                    data[368];
+       } i;
+};
+
+#endif
diff --git a/src/core/job.c b/src/core/job.c
new file mode 100644 (file)
index 0000000..5ff95f5
--- /dev/null
@@ -0,0 +1,1102 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/timerfd.h>
+#include <sys/epoll.h>
+
+#include "systemd/sd-id128.h"
+#include "systemd/sd-messages.h"
+#include "set.h"
+#include "unit.h"
+#include "macro.h"
+#include "strv.h"
+#include "load-fragment.h"
+#include "load-dropin.h"
+#include "log.h"
+#include "dbus-job.h"
+
+JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name) {
+        JobBusClient *cl;
+        size_t name_len;
+
+        name_len = strlen(name);
+        cl = malloc0(sizeof(JobBusClient) + name_len + 1);
+        if (!cl)
+                return NULL;
+
+        cl->bus = connection;
+        memcpy(cl->name, name, name_len + 1);
+        return cl;
+}
+
+Job* job_new_raw(Unit *unit) {
+        Job *j;
+
+        /* used for deserialization */
+
+        assert(unit);
+
+        j = new0(Job, 1);
+        if (!j)
+                return NULL;
+
+        j->manager = unit->manager;
+        j->unit = unit;
+        j->type = _JOB_TYPE_INVALID;
+        j->timer_watch.type = WATCH_INVALID;
+
+        return j;
+}
+
+Job* job_new(Unit *unit, JobType type) {
+        Job *j;
+
+        assert(type < _JOB_TYPE_MAX);
+
+        j = job_new_raw(unit);
+        if (!j)
+                return NULL;
+
+        j->id = j->manager->current_job_id++;
+        j->type = type;
+
+        /* We don't link it here, that's what job_dependency() is for */
+
+        return j;
+}
+
+void job_free(Job *j) {
+        JobBusClient *cl;
+
+        assert(j);
+        assert(!j->installed);
+        assert(!j->transaction_prev);
+        assert(!j->transaction_next);
+        assert(!j->subject_list);
+        assert(!j->object_list);
+
+        if (j->in_run_queue)
+                LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
+
+        if (j->in_dbus_queue)
+                LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
+
+        if (j->timer_watch.type != WATCH_INVALID) {
+                assert(j->timer_watch.type == WATCH_JOB_TIMER);
+                assert(j->timer_watch.data.job == j);
+                assert(j->timer_watch.fd >= 0);
+
+                assert_se(epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_DEL, j->timer_watch.fd, NULL) >= 0);
+                close_nointr_nofail(j->timer_watch.fd);
+        }
+
+        while ((cl = j->bus_client_list)) {
+                LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
+                free(cl);
+        }
+        free(j);
+}
+
+void job_uninstall(Job *j) {
+        Job **pj;
+
+        assert(j->installed);
+
+        pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
+        assert(*pj == j);
+
+        /* Detach from next 'bigger' objects */
+
+        /* daemon-reload should be transparent to job observers */
+        if (j->manager->n_reloading <= 0)
+                bus_job_send_removed_signal(j);
+
+        *pj = NULL;
+
+        unit_add_to_gc_queue(j->unit);
+
+        hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
+        j->installed = false;
+}
+
+static bool job_type_allows_late_merge(JobType t) {
+        /* Tells whether it is OK to merge a job of type 't' with an already
+         * running job.
+         * Reloads cannot be merged this way. Think of the sequence:
+         * 1. Reload of a daemon is in progress; the daemon has already loaded
+         *    its config file, but hasn't completed the reload operation yet.
+         * 2. Edit foo's config file.
+         * 3. Trigger another reload to have the daemon use the new config.
+         * Should the second reload job be merged into the first one, the daemon
+         * would not know about the new config.
+         * JOB_RESTART jobs on the other hand can be merged, because they get
+         * patched into JOB_START after stopping the unit. So if we see a
+         * JOB_RESTART running, it means the unit hasn't stopped yet and at
+         * this time the merge is still allowed. */
+        return t != JOB_RELOAD;
+}
+
+static void job_merge_into_installed(Job *j, Job *other) {
+        assert(j->installed);
+        assert(j->unit == other->unit);
+
+        if (j->type != JOB_NOP)
+                job_type_merge_and_collapse(&j->type, other->type, j->unit);
+        else
+                assert(other->type == JOB_NOP);
+
+        j->override = j->override || other->override;
+}
+
+Job* job_install(Job *j) {
+        Job **pj;
+        Job *uj;
+
+        assert(!j->installed);
+        assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
+
+        pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
+        uj = *pj;
+
+        if (uj) {
+                if (j->type != JOB_NOP && job_type_is_conflicting(uj->type, j->type))
+                        job_finish_and_invalidate(uj, JOB_CANCELED, false);
+                else {
+                        /* not conflicting, i.e. mergeable */
+
+                        if (j->type == JOB_NOP || uj->state == JOB_WAITING ||
+                            (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
+                                job_merge_into_installed(uj, j);
+                                log_debug_unit(uj->unit->id,
+                                               "Merged into installed job %s/%s as %u",
+                                               uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
+                                return uj;
+                        } else {
+                                /* already running and not safe to merge into */
+                                /* Patch uj to become a merged job and re-run it. */
+                                /* XXX It should be safer to queue j to run after uj finishes, but it is
+                                 * not currently possible to have more than one installed job per unit. */
+                                job_merge_into_installed(uj, j);
+                                log_debug_unit(uj->unit->id,
+                                               "Merged into running job, re-running: %s/%s as %u",
+                                               uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
+                                uj->state = JOB_WAITING;
+                                return uj;
+                        }
+                }
+        }
+
+        /* Install the job */
+        *pj = j;
+        j->installed = true;
+        j->manager->n_installed_jobs ++;
+        log_debug_unit(j->unit->id,
+                       "Installed new job %s/%s as %u",
+                       j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
+        return j;
+}
+
+int job_install_deserialized(Job *j) {
+        Job **pj;
+
+        assert(!j->installed);
+
+        if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
+                log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
+                return -EINVAL;
+        }
+
+        pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
+
+        if (*pj) {
+                log_debug_unit(j->unit->id,
+                               "Unit %s already has a job installed. Not installing deserialized job.",
+                               j->unit->id);
+                return -EEXIST;
+        }
+        *pj = j;
+        j->installed = true;
+        log_debug_unit(j->unit->id,
+                       "Reinstalled deserialized job %s/%s as %u",
+                       j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
+        return 0;
+}
+
+JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
+        JobDependency *l;
+
+        assert(object);
+
+        /* Adds a new job link, which encodes that the 'subject' job
+         * needs the 'object' job in some way. If 'subject' is NULL
+         * this means the 'anchor' job (i.e. the one the user
+         * explicitly asked for) is the requester. */
+
+        if (!(l = new0(JobDependency, 1)))
+                return NULL;
+
+        l->subject = subject;
+        l->object = object;
+        l->matters = matters;
+        l->conflicts = conflicts;
+
+        if (subject)
+                LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
+
+        LIST_PREPEND(JobDependency, object, object->object_list, l);
+
+        return l;
+}
+
+void job_dependency_free(JobDependency *l) {
+        assert(l);
+
+        if (l->subject)
+                LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
+
+        LIST_REMOVE(JobDependency, object, l->object->object_list, l);
+
+        free(l);
+}
+
+void job_dump(Job *j, FILE*f, const char *prefix) {
+        assert(j);
+        assert(f);
+
+        if (!prefix)
+                prefix = "";
+
+        fprintf(f,
+                "%s-> Job %u:\n"
+                "%s\tAction: %s -> %s\n"
+                "%s\tState: %s\n"
+                "%s\tForced: %s\n",
+                prefix, j->id,
+                prefix, j->unit->id, job_type_to_string(j->type),
+                prefix, job_state_to_string(j->state),
+                prefix, yes_no(j->override));
+}
+
+/*
+ * Merging is commutative, so imagine the matrix as symmetric. We store only
+ * its lower triangle to avoid duplication. We don't store the main diagonal,
+ * because A merged with A is simply A.
+ *
+ * If the resulting type is collapsed immediately afterwards (to get rid of
+ * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
+ * the following properties hold:
+ *
+ * Merging is associative! A merged with B merged with C is the same as
+ * A merged with C merged with B.
+ *
+ * Mergeability is transitive! If A can be merged with B and B with C then
+ * A also with C.
+ *
+ * Also, if A merged with B cannot be merged with C, then either A or B cannot
+ * be merged with C either.
+ */
+static const JobType job_merging_table[] = {
+/* What \ With       *  JOB_START         JOB_VERIFY_ACTIVE  JOB_STOP JOB_RELOAD */
+/*********************************************************************************/
+/*JOB_START          */
+/*JOB_VERIFY_ACTIVE  */ JOB_START,
+/*JOB_STOP           */ -1,                  -1,
+/*JOB_RELOAD         */ JOB_RELOAD_OR_START, JOB_RELOAD,          -1,
+/*JOB_RESTART        */ JOB_RESTART,         JOB_RESTART,         -1, JOB_RESTART,
+};
+
+JobType job_type_lookup_merge(JobType a, JobType b) {
+        assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
+        assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
+        assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
+
+        if (a == b)
+                return a;
+
+        if (a < b) {
+                JobType tmp = a;
+                a = b;
+                b = tmp;
+        }
+
+        return job_merging_table[(a - 1) * a / 2 + b];
+}
+
+bool job_type_is_redundant(JobType a, UnitActiveState b) {
+        switch (a) {
+
+        case JOB_START:
+                return
+                        b == UNIT_ACTIVE ||
+                        b == UNIT_RELOADING;
+
+        case JOB_STOP:
+                return
+                        b == UNIT_INACTIVE ||
+                        b == UNIT_FAILED;
+
+        case JOB_VERIFY_ACTIVE:
+                return
+                        b == UNIT_ACTIVE ||
+                        b == UNIT_RELOADING;
+
+        case JOB_RELOAD:
+                return
+                        b == UNIT_RELOADING;
+
+        case JOB_RESTART:
+                return
+                        b == UNIT_ACTIVATING;
+
+        default:
+                assert_not_reached("Invalid job type");
+        }
+}
+
+void job_type_collapse(JobType *t, Unit *u) {
+        UnitActiveState s;
+
+        switch (*t) {
+
+        case JOB_TRY_RESTART:
+                s = unit_active_state(u);
+                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
+                        *t = JOB_NOP;
+                else
+                        *t = JOB_RESTART;
+                break;
+
+        case JOB_RELOAD_OR_START:
+                s = unit_active_state(u);
+                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
+                        *t = JOB_START;
+                else
+                        *t = JOB_RELOAD;
+                break;
+
+        default:
+                ;
+        }
+}
+
+int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
+        JobType t = job_type_lookup_merge(*a, b);
+        if (t < 0)
+                return -EEXIST;
+        *a = t;
+        job_type_collapse(a, u);
+        return 0;
+}
+
+bool job_is_runnable(Job *j) {
+        Iterator i;
+        Unit *other;
+
+        assert(j);
+        assert(j->installed);
+
+        /* Checks whether there is any job running for the units this
+         * job needs to be running after (in the case of a 'positive'
+         * job type) or before (in the case of a 'negative' job
+         * type. */
+
+        /* First check if there is an override */
+        if (j->ignore_order)
+                return true;
+
+        if (j->type == JOB_NOP)
+                return true;
+
+        if (j->type == JOB_START ||
+            j->type == JOB_VERIFY_ACTIVE ||
+            j->type == JOB_RELOAD) {
+
+                /* Immediate result is that the job is or might be
+                 * started. In this case lets wait for the
+                 * dependencies, regardless whether they are
+                 * starting or stopping something. */
+
+                SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
+                        if (other->job)
+                                return false;
+        }
+
+        /* Also, if something else is being stopped and we should
+         * change state after it, then lets wait. */
+
+        SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
+                if (other->job &&
+                    (other->job->type == JOB_STOP ||
+                     other->job->type == JOB_RESTART))
+                        return false;
+
+        /* This means that for a service a and a service b where b
+         * shall be started after a:
+         *
+         *  start a + start b → 1st step start a, 2nd step start b
+         *  start a + stop b  → 1st step stop b,  2nd step start a
+         *  stop a  + start b → 1st step stop a,  2nd step start b
+         *  stop a  + stop b  → 1st step stop b,  2nd step stop a
+         *
+         *  This has the side effect that restarts are properly
+         *  synchronized too. */
+
+        return true;
+}
+
+static void job_change_type(Job *j, JobType newtype) {
+        log_debug_unit(j->unit->id,
+                       "Converting job %s/%s -> %s/%s",
+                       j->unit->id, job_type_to_string(j->type),
+                       j->unit->id, job_type_to_string(newtype));
+
+        j->type = newtype;
+}
+
+int job_run_and_invalidate(Job *j) {
+        int r;
+        uint32_t id;
+        Manager *m;
+
+        assert(j);
+        assert(j->installed);
+        assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
+        assert(j->in_run_queue);
+
+        LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
+        j->in_run_queue = false;
+
+        if (j->state != JOB_WAITING)
+                return 0;
+
+        if (!job_is_runnable(j))
+                return -EAGAIN;
+
+        j->state = JOB_RUNNING;
+        job_add_to_dbus_queue(j);
+
+        /* While we execute this operation the job might go away (for
+         * example: because it is replaced by a new, conflicting
+         * job.) To make sure we don't access a freed job later on we
+         * store the id here, so that we can verify the job is still
+         * valid. */
+        id = j->id;
+        m = j->manager;
+
+        switch (j->type) {
+
+                case JOB_START:
+                        r = unit_start(j->unit);
+
+                        /* If this unit cannot be started, then simply wait */
+                        if (r == -EBADR)
+                                r = 0;
+                        break;
+
+                case JOB_VERIFY_ACTIVE: {
+                        UnitActiveState t = unit_active_state(j->unit);
+                        if (UNIT_IS_ACTIVE_OR_RELOADING(t))
+                                r = -EALREADY;
+                        else if (t == UNIT_ACTIVATING)
+                                r = -EAGAIN;
+                        else
+                                r = -ENOEXEC;
+                        break;
+                }
+
+                case JOB_STOP:
+                case JOB_RESTART:
+                        r = unit_stop(j->unit);
+
+                        /* If this unit cannot stopped, then simply wait. */
+                        if (r == -EBADR)
+                                r = 0;
+                        break;
+
+                case JOB_RELOAD:
+                        r = unit_reload(j->unit);
+                        break;
+
+                case JOB_NOP:
+                        r = -EALREADY;
+                        break;
+
+                default:
+                        assert_not_reached("Unknown job type");
+        }
+
+        j = manager_get_job(m, id);
+        if (j) {
+                if (r == -EALREADY)
+                        r = job_finish_and_invalidate(j, JOB_DONE, true);
+                else if (r == -ENOEXEC)
+                        r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
+                else if (r == -EAGAIN)
+                        j->state = JOB_WAITING;
+                else if (r < 0)
+                        r = job_finish_and_invalidate(j, JOB_FAILED, true);
+        }
+
+        return r;
+}
+
+static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
+        const UnitStatusMessageFormats *format_table;
+
+        assert(u);
+        assert(t >= 0);
+        assert(t < _JOB_TYPE_MAX);
+
+        format_table = &UNIT_VTABLE(u)->status_message_formats;
+        if (!format_table)
+                return NULL;
+
+        if (t == JOB_START)
+                return format_table->finished_start_job[result];
+        else if (t == JOB_STOP || t == JOB_RESTART)
+                return format_table->finished_stop_job[result];
+
+        return NULL;
+}
+
+static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
+        const char *format;
+
+        assert(u);
+        assert(t >= 0);
+        assert(t < _JOB_TYPE_MAX);
+
+        format = job_get_status_message_format(u, t, result);
+        if (format)
+                return format;
+
+        /* Return generic strings */
+        if (t == JOB_START) {
+                if (result == JOB_DONE)
+                        return "Started %s.";
+                else if (result == JOB_FAILED)
+                        return "Failed to start %s.";
+                else if (result == JOB_DEPENDENCY)
+                        return "Dependency failed for %s.";
+                else if (result == JOB_TIMEOUT)
+                        return "Timed out starting %s.";
+        } else if (t == JOB_STOP || t == JOB_RESTART) {
+                if (result == JOB_DONE)
+                        return "Stopped %s.";
+                else if (result == JOB_FAILED)
+                        return "Stopped (with error) %s.";
+                else if (result == JOB_TIMEOUT)
+                        return "Timed out stoppping %s.";
+        } else if (t == JOB_RELOAD) {
+                if (result == JOB_DONE)
+                        return "Reloaded %s.";
+                else if (result == JOB_FAILED)
+                        return "Reload failed for %s.";
+                else if (result == JOB_TIMEOUT)
+                        return "Timed out reloading %s.";
+        }
+
+        return NULL;
+}
+
+static void job_print_status_message(Unit *u, JobType t, JobResult result) {
+        const char *format;
+
+        assert(u);
+        assert(t >= 0);
+        assert(t < _JOB_TYPE_MAX);
+
+        if (t == JOB_START) {
+                format = job_get_status_message_format(u, t, result);
+                if (!format)
+                        return;
+
+                switch (result) {
+
+                case JOB_DONE:
+                        if (u->condition_result)
+                                unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
+                        break;
+
+                case JOB_FAILED:
+                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
+                        unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id);
+                        break;
+
+                case JOB_DEPENDENCY:
+                        unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
+                        break;
+
+                case JOB_TIMEOUT:
+                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
+                        break;
+
+                default:
+                        ;
+                }
+
+        } else if (t == JOB_STOP || t == JOB_RESTART) {
+
+                format = job_get_status_message_format(u, t, result);
+                if (!format)
+                        return;
+
+                switch (result) {
+
+                case JOB_TIMEOUT:
+                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
+                        break;
+
+                case JOB_DONE:
+                case JOB_FAILED:
+                        unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
+                        break;
+
+                default:
+                        ;
+                }
+
+        } else if (t == JOB_VERIFY_ACTIVE) {
+
+                /* When verify-active detects the unit is inactive, report it.
+                 * Most likely a DEPEND warning from a requisiting unit will
+                 * occur next and it's nice to see what was requisited. */
+                if (result == JOB_SKIPPED)
+                        unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.", unit_description(u));
+        }
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+        const char *format;
+        char buf[LINE_MAX];
+
+        assert(u);
+        assert(t >= 0);
+        assert(t < _JOB_TYPE_MAX);
+
+        /* Skip this if it goes to the console. since we already print
+         * to the console anyway... */
+
+        if (log_on_console())
+                return;
+
+        format = job_get_status_message_format_try_harder(u, t, result);
+        if (!format)
+                return;
+
+        snprintf(buf, sizeof(buf), format, unit_description(u));
+        char_array_0(buf);
+
+        if (t == JOB_START) {
+                sd_id128_t mid;
+
+                mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
+                log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                           MESSAGE_ID(mid),
+                           "UNIT=%s", u->id,
+                           "RESULT=%s", job_result_to_string(result),
+                           "MESSAGE=%s", buf,
+                           NULL);
+
+        } else if (t == JOB_STOP)
+                log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                           MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
+                           "UNIT=%s", u->id,
+                           "RESULT=%s", job_result_to_string(result),
+                           "MESSAGE=%s", buf,
+                           NULL);
+
+        else if (t == JOB_RELOAD)
+                log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                           MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
+                           "UNIT=%s", u->id,
+                           "RESULT=%s", job_result_to_string(result),
+                           "MESSAGE=%s", buf,
+                           NULL);
+}
+#pragma GCC diagnostic pop
+
+int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
+        Unit *u;
+        Unit *other;
+        JobType t;
+        Iterator i;
+
+        assert(j);
+        assert(j->installed);
+        assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
+
+        u = j->unit;
+        t = j->type;
+
+        j->result = result;
+
+        log_debug_unit(u->id, "Job %s/%s finished, result=%s",
+                       u->id, job_type_to_string(t), job_result_to_string(result));
+
+        job_print_status_message(u, t, result);
+        job_log_status_message(u, t, result);
+
+        job_add_to_dbus_queue(j);
+
+        /* Patch restart jobs so that they become normal start jobs */
+        if (result == JOB_DONE && t == JOB_RESTART) {
+
+                job_change_type(j, JOB_START);
+                j->state = JOB_WAITING;
+
+                job_add_to_run_queue(j);
+
+                goto finish;
+        }
+
+        if (result == JOB_FAILED)
+                j->manager->n_failed_jobs ++;
+
+        job_uninstall(j);
+        job_free(j);
+
+        /* Fail depending jobs on failure */
+        if (result != JOB_DONE && recursive) {
+
+                if (t == JOB_START ||
+                    t == JOB_VERIFY_ACTIVE) {
+
+                        SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
+                                if (other->job &&
+                                    (other->job->type == JOB_START ||
+                                     other->job->type == JOB_VERIFY_ACTIVE))
+                                        job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
+
+                        SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
+                                if (other->job &&
+                                    (other->job->type == JOB_START ||
+                                     other->job->type == JOB_VERIFY_ACTIVE))
+                                        job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
+
+                        SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
+                                if (other->job &&
+                                    !other->job->override &&
+                                    (other->job->type == JOB_START ||
+                                     other->job->type == JOB_VERIFY_ACTIVE))
+                                        job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
+
+                } else if (t == JOB_STOP) {
+
+                        SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
+                                if (other->job &&
+                                    (other->job->type == JOB_START ||
+                                     other->job->type == JOB_VERIFY_ACTIVE))
+                                        job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
+                }
+        }
+
+        /* Trigger OnFailure dependencies that are not generated by
+         * the unit itself. We don't treat JOB_CANCELED as failure in
+         * this context. And JOB_FAILURE is already handled by the
+         * unit itself. */
+        if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
+                log_struct(LOG_NOTICE,
+                           "UNIT=%s", u->id,
+                           "JOB_TYPE=%s", job_type_to_string(t),
+                           "JOB_RESULT=%s", job_result_to_string(t),
+                           "Job %s/%s failed with result '%s'.",
+                           u->id,
+                           job_type_to_string(t),
+                           job_result_to_string(result),
+                           NULL);
+
+                unit_trigger_on_failure(u);
+        }
+
+finish:
+        /* Try to start the next jobs that can be started */
+        SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
+                if (other->job)
+                        job_add_to_run_queue(other->job);
+        SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
+                if (other->job)
+                        job_add_to_run_queue(other->job);
+
+        manager_check_finished(u->manager);
+
+        return 0;
+}
+
+int job_start_timer(Job *j) {
+        struct itimerspec its;
+        struct epoll_event ev;
+        int fd, r;
+        assert(j);
+
+        if (j->unit->job_timeout <= 0 ||
+            j->timer_watch.type == WATCH_JOB_TIMER)
+                return 0;
+
+        assert(j->timer_watch.type == WATCH_INVALID);
+
+        if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        zero(its);
+        timespec_store(&its.it_value, j->unit->job_timeout);
+
+        if (timerfd_settime(fd, 0, &its, NULL) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        zero(ev);
+        ev.data.ptr = &j->timer_watch;
+        ev.events = EPOLLIN;
+
+        if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        j->timer_watch.type = WATCH_JOB_TIMER;
+        j->timer_watch.fd = fd;
+        j->timer_watch.data.job = j;
+
+        return 0;
+
+fail:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
+
+void job_add_to_run_queue(Job *j) {
+        assert(j);
+        assert(j->installed);
+
+        if (j->in_run_queue)
+                return;
+
+        LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
+        j->in_run_queue = true;
+}
+
+void job_add_to_dbus_queue(Job *j) {
+        assert(j);
+        assert(j->installed);
+
+        if (j->in_dbus_queue)
+                return;
+
+        /* We don't check if anybody is subscribed here, since this
+         * job might just have been created and not yet assigned to a
+         * connection/client. */
+
+        LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
+        j->in_dbus_queue = true;
+}
+
+char *job_dbus_path(Job *j) {
+        char *p;
+
+        assert(j);
+
+        if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
+                return NULL;
+
+        return p;
+}
+
+void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
+        assert(j);
+        assert(w == &j->timer_watch);
+
+        log_warning_unit(j->unit->id, "Job %s/%s timed out.",
+                         j->unit->id, job_type_to_string(j->type));
+        job_finish_and_invalidate(j, JOB_TIMEOUT, true);
+}
+
+int job_serialize(Job *j, FILE *f, FDSet *fds) {
+        fprintf(f, "job-id=%u\n", j->id);
+        fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
+        fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
+        fprintf(f, "job-override=%s\n", yes_no(j->override));
+        fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
+        fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
+        /* Cannot save bus clients. Just note the fact that we're losing
+         * them. job_send_message() will fallback to broadcasting. */
+        fprintf(f, "job-forgot-bus-clients=%s\n",
+                yes_no(j->forgot_bus_clients || j->bus_client_list));
+        if (j->timer_watch.type == WATCH_JOB_TIMER) {
+                int copy = fdset_put_dup(fds, j->timer_watch.fd);
+                if (copy < 0)
+                        return copy;
+                fprintf(f, "job-timer-watch-fd=%d\n", copy);
+        }
+
+        /* End marker */
+        fputc('\n', f);
+        return 0;
+}
+
+int job_deserialize(Job *j, FILE *f, FDSet *fds) {
+        for (;;) {
+                char line[LINE_MAX], *l, *v;
+                size_t k;
+
+                if (!fgets(line, sizeof(line), f)) {
+                        if (feof(f))
+                                return 0;
+                        return -errno;
+                }
+
+                char_array_0(line);
+                l = strstrip(line);
+
+                /* End marker */
+                if (l[0] == 0)
+                        return 0;
+
+                k = strcspn(l, "=");
+
+                if (l[k] == '=') {
+                        l[k] = 0;
+                        v = l+k+1;
+                } else
+                        v = l+k;
+
+                if (streq(l, "job-id")) {
+                        if (safe_atou32(v, &j->id) < 0)
+                                log_debug("Failed to parse job id value %s", v);
+                } else if (streq(l, "job-type")) {
+                        JobType t = job_type_from_string(v);
+                        if (t < 0)
+                                log_debug("Failed to parse job type %s", v);
+                        else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
+                                log_debug("Cannot deserialize job of type %s", v);
+                        else
+                                j->type = t;
+                } else if (streq(l, "job-state")) {
+                        JobState s = job_state_from_string(v);
+                        if (s < 0)
+                                log_debug("Failed to parse job state %s", v);
+                        else
+                                j->state = s;
+                } else if (streq(l, "job-override")) {
+                        int b = parse_boolean(v);
+                        if (b < 0)
+                                log_debug("Failed to parse job override flag %s", v);
+                        else
+                                j->override = j->override || b;
+                } else if (streq(l, "job-sent-dbus-new-signal")) {
+                        int b = parse_boolean(v);
+                        if (b < 0)
+                                log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
+                        else
+                                j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
+                } else if (streq(l, "job-ignore-order")) {
+                        int b = parse_boolean(v);
+                        if (b < 0)
+                                log_debug("Failed to parse job ignore_order flag %s", v);
+                        else
+                                j->ignore_order = j->ignore_order || b;
+                } else if (streq(l, "job-forgot-bus-clients")) {
+                        int b = parse_boolean(v);
+                        if (b < 0)
+                                log_debug("Failed to parse job forgot_bus_clients flag %s", v);
+                        else
+                                j->forgot_bus_clients = j->forgot_bus_clients || b;
+                } else if (streq(l, "job-timer-watch-fd")) {
+                        int fd;
+                        if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+                                log_debug("Failed to parse job-timer-watch-fd value %s", v);
+                        else {
+                                if (j->timer_watch.type == WATCH_JOB_TIMER)
+                                        close_nointr_nofail(j->timer_watch.fd);
+
+                                j->timer_watch.type = WATCH_JOB_TIMER;
+                                j->timer_watch.fd = fdset_remove(fds, fd);
+                                j->timer_watch.data.job = j;
+                        }
+                }
+        }
+}
+
+int job_coldplug(Job *j) {
+        struct epoll_event ev;
+
+        if (j->timer_watch.type != WATCH_JOB_TIMER)
+                return 0;
+
+        zero(ev);
+        ev.data.ptr = &j->timer_watch;
+        ev.events = EPOLLIN;
+
+        if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
+                return -errno;
+
+        return 0;
+}
+
+static const char* const job_state_table[_JOB_STATE_MAX] = {
+        [JOB_WAITING] = "waiting",
+        [JOB_RUNNING] = "running"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
+
+static const char* const job_type_table[_JOB_TYPE_MAX] = {
+        [JOB_START] = "start",
+        [JOB_VERIFY_ACTIVE] = "verify-active",
+        [JOB_STOP] = "stop",
+        [JOB_RELOAD] = "reload",
+        [JOB_RELOAD_OR_START] = "reload-or-start",
+        [JOB_RESTART] = "restart",
+        [JOB_TRY_RESTART] = "try-restart",
+        [JOB_NOP] = "nop",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
+
+static const char* const job_mode_table[_JOB_MODE_MAX] = {
+        [JOB_FAIL] = "fail",
+        [JOB_REPLACE] = "replace",
+        [JOB_ISOLATE] = "isolate",
+        [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
+        [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
+
+static const char* const job_result_table[_JOB_RESULT_MAX] = {
+        [JOB_DONE] = "done",
+        [JOB_CANCELED] = "canceled",
+        [JOB_TIMEOUT] = "timeout",
+        [JOB_FAILED] = "failed",
+        [JOB_DEPENDENCY] = "dependency",
+        [JOB_SKIPPED] = "skipped"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
diff --git a/src/core/job.h b/src/core/job.h
new file mode 100644 (file)
index 0000000..3aa49d4
--- /dev/null
@@ -0,0 +1,230 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <inttypes.h>
+#include <errno.h>
+
+typedef struct Job Job;
+typedef struct JobDependency JobDependency;
+typedef struct JobBusClient JobBusClient;
+typedef enum JobType JobType;
+typedef enum JobState JobState;
+typedef enum JobMode JobMode;
+typedef enum JobResult JobResult;
+
+/* Be careful when changing the job types! Adjust job_merging_table[] accordingly! */
+enum JobType {
+        JOB_START,                  /* if a unit does not support being started, we'll just wait until it becomes active */
+        JOB_VERIFY_ACTIVE,
+
+        JOB_STOP,
+
+        JOB_RELOAD,                 /* if running, reload */
+
+        /* Note that restarts are first treated like JOB_STOP, but
+         * then instead of finishing are patched to become
+         * JOB_START. */
+        JOB_RESTART,                /* If running, stop. Then start unconditionally. */
+
+        _JOB_TYPE_MAX_MERGING,
+
+        /* JOB_NOP can enter into a transaction, but as it won't pull in
+         * any dependencies, it won't have to merge with anything.
+         * job_install() avoids the problem of merging JOB_NOP too (it's
+         * special-cased, only merges with other JOB_NOPs). */
+        JOB_NOP = _JOB_TYPE_MAX_MERGING, /* do nothing */
+
+        _JOB_TYPE_MAX_IN_TRANSACTION,
+
+        /* JOB_TRY_RESTART can never appear in a transaction, because
+         * it always collapses into JOB_RESTART or JOB_NOP before entering.
+         * Thus we never need to merge it with anything. */
+        JOB_TRY_RESTART = _JOB_TYPE_MAX_IN_TRANSACTION, /* if running, stop and then start */
+
+        /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
+         * from transaction merging (there's no way for JOB_RELOAD and
+         * JOB_START to meet in one transaction). It can result from a merge
+         * during job installation, but then it will immediately collapse into
+         * one of the two simpler types. */
+        JOB_RELOAD_OR_START,        /* if running, reload, otherwise start */
+
+        _JOB_TYPE_MAX,
+        _JOB_TYPE_INVALID = -1
+};
+
+enum JobState {
+        JOB_WAITING,
+        JOB_RUNNING,
+        _JOB_STATE_MAX,
+        _JOB_STATE_INVALID = -1
+};
+
+enum JobMode {
+        JOB_FAIL,                /* Fail if a conflicting job is already queued */
+        JOB_REPLACE,             /* Replace an existing conflicting job */
+        JOB_ISOLATE,             /* Start a unit, and stop all others */
+        JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */
+        JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */
+        _JOB_MODE_MAX,
+        _JOB_MODE_INVALID = -1
+};
+
+enum JobResult {
+        JOB_DONE,                /* Job completed successfully */
+        JOB_CANCELED,            /* Job canceled by a conflicting job installation or by explicit cancel request */
+        JOB_TIMEOUT,             /* JobTimeout elapsed */
+        JOB_FAILED,              /* Job failed */
+        JOB_DEPENDENCY,          /* A required dependency job did not result in JOB_DONE */
+        JOB_SKIPPED,             /* JOB_RELOAD of inactive unit; negative result of JOB_VERIFY_ACTIVE */
+        _JOB_RESULT_MAX,
+        _JOB_RESULT_INVALID = -1
+};
+
+#include "manager.h"
+#include "unit.h"
+#include "hashmap.h"
+#include "list.h"
+
+struct JobDependency {
+        /* Encodes that the 'subject' job needs the 'object' job in
+         * some way. This structure is used only while building a transaction. */
+        Job *subject;
+        Job *object;
+
+        LIST_FIELDS(JobDependency, subject);
+        LIST_FIELDS(JobDependency, object);
+
+        bool matters;
+        bool conflicts;
+};
+
+struct JobBusClient {
+        LIST_FIELDS(JobBusClient, client);
+        /* Note that this bus object is not ref counted here. */
+        DBusConnection *bus;
+        char name[0];
+};
+
+struct Job {
+        Manager *manager;
+        Unit *unit;
+
+        LIST_FIELDS(Job, transaction);
+        LIST_FIELDS(Job, run_queue);
+        LIST_FIELDS(Job, dbus_queue);
+
+        LIST_HEAD(JobDependency, subject_list);
+        LIST_HEAD(JobDependency, object_list);
+
+        /* Used for graph algs as a "I have been here" marker */
+        Job* marker;
+        unsigned generation;
+
+        uint32_t id;
+
+        JobType type;
+        JobState state;
+
+        Watch timer_watch;
+
+        /* There can be more than one client, because of job merging. */
+        LIST_HEAD(JobBusClient, bus_client_list);
+
+        JobResult result;
+
+        bool installed:1;
+        bool in_run_queue:1;
+        bool matters_to_anchor:1;
+        bool override:1;
+        bool in_dbus_queue:1;
+        bool sent_dbus_new_signal:1;
+        bool ignore_order:1;
+        bool forgot_bus_clients:1;
+};
+
+JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name);
+
+Job* job_new(Unit *unit, JobType type);
+Job* job_new_raw(Unit *unit);
+void job_free(Job *job);
+Job* job_install(Job *j);
+int job_install_deserialized(Job *j);
+void job_uninstall(Job *j);
+void job_dump(Job *j, FILE*f, const char *prefix);
+int job_serialize(Job *j, FILE *f, FDSet *fds);
+int job_deserialize(Job *j, FILE *f, FDSet *fds);
+int job_coldplug(Job *j);
+
+JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts);
+void job_dependency_free(JobDependency *l);
+
+int job_merge(Job *j, Job *other);
+
+JobType job_type_lookup_merge(JobType a, JobType b);
+
+static inline bool job_type_is_mergeable(JobType a, JobType b) {
+        return job_type_lookup_merge(a, b) >= 0;
+}
+
+static inline bool job_type_is_conflicting(JobType a, JobType b) {
+        return !job_type_is_mergeable(a, b);
+}
+
+static inline bool job_type_is_superset(JobType a, JobType b) {
+        /* Checks whether operation a is a "superset" of b in its actions */
+        return a == job_type_lookup_merge(a, b);
+}
+
+bool job_type_is_redundant(JobType a, UnitActiveState b);
+
+/* Collapses a state-dependent job type into a simpler type by observing
+ * the state of the unit which it is going to be applied to. */
+void job_type_collapse(JobType *t, Unit *u);
+
+int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u);
+
+bool job_is_runnable(Job *j);
+
+void job_add_to_run_queue(Job *j);
+void job_add_to_dbus_queue(Job *j);
+
+int job_start_timer(Job *j);
+void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w);
+
+int job_run_and_invalidate(Job *j);
+int job_finish_and_invalidate(Job *j, JobResult result, bool recursive);
+
+char *job_dbus_path(Job *j);
+
+const char* job_type_to_string(JobType t);
+JobType job_type_from_string(const char *s);
+
+const char* job_state_to_string(JobState t);
+JobState job_state_from_string(const char *s);
+
+const char* job_mode_to_string(JobMode t);
+JobMode job_mode_from_string(const char *s);
+
+const char* job_result_to_string(JobResult t);
+JobResult job_result_from_string(const char *s);
diff --git a/src/core/kill.c b/src/core/kill.c
new file mode 100644 (file)
index 0000000..0775653
--- /dev/null
@@ -0,0 +1,63 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "kill.h"
+#include "util.h"
+
+void kill_context_init(KillContext *c) {
+        assert(c);
+
+        c->kill_signal = SIGTERM;
+        c->send_sigkill = true;
+}
+
+void kill_context_dump(KillContext *c, FILE *f, const char *prefix) {
+        assert(c);
+
+        if (!prefix)
+                prefix = "";
+
+        fprintf(f,
+                "%sKillMode: %s\n"
+                "%sKillSignal: SIG%s\n"
+                "%sSendSIGKILL: %s\n",
+                prefix, kill_mode_to_string(c->kill_mode),
+                prefix, signal_to_string(c->kill_signal),
+                prefix, yes_no(c->send_sigkill));
+}
+
+static const char* const kill_mode_table[_KILL_MODE_MAX] = {
+        [KILL_CONTROL_GROUP] = "control-group",
+        [KILL_PROCESS] = "process",
+        [KILL_NONE] = "none"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(kill_mode, KillMode);
+
+static const char* const kill_who_table[_KILL_WHO_MAX] = {
+        [KILL_MAIN] = "main",
+        [KILL_CONTROL] = "control",
+        [KILL_ALL] = "all"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);
diff --git a/src/core/kill.h b/src/core/kill.h
new file mode 100644 (file)
index 0000000..3c9b0ab
--- /dev/null
@@ -0,0 +1,60 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct KillContext KillContext;
+
+#include <stdbool.h>
+#include <stdio.h>
+
+typedef enum KillMode {
+        /* The kill mode is a property of a unit. */
+        KILL_CONTROL_GROUP = 0,
+        KILL_PROCESS,
+        KILL_NONE,
+        _KILL_MODE_MAX,
+        _KILL_MODE_INVALID = -1
+} KillMode;
+
+struct KillContext {
+        KillMode kill_mode;
+        int kill_signal;
+        bool send_sigkill;
+};
+
+typedef enum KillWho {
+        /* Kill who is a property of an operation */
+        KILL_MAIN,
+        KILL_CONTROL,
+        KILL_ALL,
+        _KILL_WHO_MAX,
+        _KILL_WHO_INVALID = -1
+} KillWho;
+
+void kill_context_init(KillContext *c);
+void kill_context_dump(KillContext *c, FILE *f, const char *prefix);
+
+const char *kill_mode_to_string(KillMode k);
+KillMode kill_mode_from_string(const char *s);
+
+const char *kill_who_to_string(KillWho k);
+KillWho kill_who_from_string(const char *s);
diff --git a/src/core/killall.c b/src/core/killall.c
new file mode 100644 (file)
index 0000000..55200ff
--- /dev/null
@@ -0,0 +1,177 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 ProFUSION embedded systems
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/wait.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "util.h"
+#include "def.h"
+#include "killall.h"
+
+#define TIMEOUT_USEC (5 * USEC_PER_SEC)
+
+static bool ignore_proc(pid_t pid) {
+        char buf[PATH_MAX];
+        FILE *f;
+        char c;
+        size_t count;
+        uid_t uid;
+        int r;
+
+        /* We are PID 1, let's not commit suicide */
+        if (pid == 1)
+                return true;
+
+        r = get_process_uid(pid, &uid);
+        if (r < 0)
+                return true; /* not really, but better safe than sorry */
+
+        /* Non-root processes otherwise are always subject to be killed */
+        if (uid != 0)
+                return false;
+
+        snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid);
+        char_array_0(buf);
+
+        f = fopen(buf, "re");
+        if (!f)
+                return true; /* not really, but has the desired effect */
+
+        count = fread(&c, 1, 1, f);
+        fclose(f);
+
+        /* Kernel threads have an empty cmdline */
+        if (count <= 0)
+                return true;
+
+        /* Processes with argv[0][0] = '@' we ignore from the killing
+         * spree.
+         *
+         * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */
+        if (count == 1 && c == '@')
+                return true;
+
+        return false;
+}
+
+static void wait_for_children(int n_processes, sigset_t *mask) {
+        usec_t until;
+
+        assert(mask);
+
+        until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
+        for (;;) {
+                struct timespec ts;
+                int k;
+                usec_t n;
+
+                for (;;) {
+                        pid_t pid = waitpid(-1, NULL, WNOHANG);
+
+                        if (pid == 0)
+                                break;
+
+                        if (pid < 0 && errno == ECHILD)
+                                return;
+
+                        if (n_processes > 0)
+                                if (--n_processes == 0)
+                                        return;
+                }
+
+                n = now(CLOCK_MONOTONIC);
+                if (n >= until)
+                        return;
+
+                timespec_store(&ts, until - n);
+
+                if ((k = sigtimedwait(mask, NULL, &ts)) != SIGCHLD) {
+
+                        if (k < 0 && errno != EAGAIN) {
+                                log_error("sigtimedwait() failed: %m");
+                                return;
+                        }
+
+                        if (k >= 0)
+                                log_warning("sigtimedwait() returned unexpected signal.");
+                }
+        }
+}
+
+static int killall(int sig) {
+        DIR *dir;
+        struct dirent *d;
+        unsigned int n_processes = 0;
+
+        dir = opendir("/proc");
+        if (!dir)
+                return -errno;
+
+        while ((d = readdir(dir))) {
+                pid_t pid;
+
+                if (d->d_type != DT_DIR &&
+                    d->d_type != DT_UNKNOWN)
+                        continue;
+
+                if (parse_pid(d->d_name, &pid) < 0)
+                        continue;
+
+                if (ignore_proc(pid))
+                        continue;
+
+                if (kill(pid, sig) >= 0)
+                        n_processes++;
+                else if (errno != ENOENT)
+                        log_warning("Could not kill %d: %m", pid);
+        }
+
+        closedir(dir);
+
+        return n_processes;
+}
+
+void broadcast_signal(int sig, bool wait_for_exit) {
+        sigset_t mask, oldmask;
+        int n_processes;
+
+        assert_se(sigemptyset(&mask) == 0);
+        assert_se(sigaddset(&mask, SIGCHLD) == 0);
+        assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
+
+        if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
+                log_warning("kill(-1, SIGSTOP) failed: %m");
+
+        n_processes = killall(sig);
+
+        if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
+                log_warning("kill(-1, SIGCONT) failed: %m");
+
+        if (n_processes <= 0)
+                goto finish;
+
+        if (wait_for_exit)
+                wait_for_children(n_processes, &mask);
+
+finish:
+        sigprocmask(SIG_SETMASK, &oldmask, NULL);
+}
diff --git a/src/core/killall.h b/src/core/killall.h
new file mode 100644 (file)
index 0000000..d08ac14
--- /dev/null
@@ -0,0 +1,27 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef fookillallhfoo
+#define fookillallhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+void broadcast_signal(int sig, bool wait);
+
+#endif
diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c
new file mode 100644 (file)
index 0000000..20ab232
--- /dev/null
@@ -0,0 +1,104 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/wait.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <libkmod.h>
+
+#include "macro.h"
+#include "execute.h"
+
+#include "kmod-setup.h"
+
+typedef struct Kmodule {
+        const char *name;
+        const char *directory;
+        bool (*condition_fn)(void);
+} KModule;
+
+static const KModule kmod_table[] = {
+        { "autofs4",  "/sys/class/misc/autofs",    NULL } ,
+        { "ipv6",     "/sys/module/ipv6",          NULL },
+        { "unix",     "/proc/net/unix",            NULL } ,
+};
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+static void systemd_kmod_log(void *data, int priority, const char *file, int line,
+                             const char *fn, const char *format, va_list args)
+{
+        /* library logging is enabled at debug only */
+        log_metav(LOG_DEBUG, file, line, fn, format, args);
+}
+#pragma GCC diagnostic pop
+
+int kmod_setup(void) {
+        unsigned i;
+        struct kmod_ctx *ctx = NULL;
+        struct kmod_module *mod;
+        int err;
+
+        for (i = 0; i < ELEMENTSOF(kmod_table); i += 2) {
+                if (kmod_table[i].condition_fn && !kmod_table[i].condition_fn())
+                        continue;
+
+                if (access(kmod_table[i].directory, F_OK) >= 0)
+                        continue;
+
+                log_debug("Your kernel apparently lacks built-in %s support. Might be a good idea to compile it in. "
+                          "We'll now try to work around this by loading the module...",
+                          kmod_table[i].name);
+
+                if (!ctx) {
+                        ctx = kmod_new(NULL, NULL);
+                        if (!ctx) {
+                                log_error("Failed to allocate memory for kmod");
+                                return -ENOMEM;
+                        }
+
+                        kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
+                        kmod_load_resources(ctx);
+                }
+
+                err = kmod_module_new_from_name(ctx, kmod_table[i].name, &mod);
+                if (err < 0) {
+                        log_error("Failed to lookup module '%s'", kmod_table[i].name);
+                        continue;
+                }
+
+                err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
+                if (err == 0)
+                        log_info("Inserted module '%s'", kmod_module_get_name(mod));
+                else if (err == KMOD_PROBE_APPLY_BLACKLIST)
+                        log_info("Module '%s' is blacklisted", kmod_module_get_name(mod));
+                else
+                        log_error("Failed to insert module '%s'", kmod_module_get_name(mod));
+
+                kmod_module_unref(mod);
+        }
+
+        if (ctx)
+                kmod_unref(ctx);
+
+        return 0;
+}
diff --git a/src/core/kmod-setup.h b/src/core/kmod-setup.h
new file mode 100644 (file)
index 0000000..24dcddd
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int kmod_setup(void);
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
new file mode 100644 (file)
index 0000000..86f81c7
--- /dev/null
@@ -0,0 +1,150 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dirent.h>
+#include <errno.h>
+
+#include "unit.h"
+#include "load-dropin.h"
+#include "log.h"
+#include "strv.h"
+#include "unit-name.h"
+
+static int iterate_dir(Unit *u, const char *path, UnitDependency dependency) {
+        DIR *d;
+        struct dirent *de;
+        int r;
+
+        assert(u);
+        assert(path);
+
+        d = opendir(path);
+        if (!d) {
+
+                if (errno == ENOENT)
+                        return 0;
+
+                return -errno;
+        }
+
+        while ((de = readdir(d))) {
+                char *f;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                f = strjoin(path, "/", de->d_name, NULL);
+                if (!f) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true);
+                free(f);
+
+                if (r < 0)
+                        log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r));
+        }
+
+        r = 0;
+
+finish:
+        closedir(d);
+        return r;
+}
+
+static int process_dir(Unit *u, const char *unit_path, const char *name, const char *suffix, UnitDependency dependency) {
+        int r;
+        char *path;
+
+        assert(u);
+        assert(unit_path);
+        assert(name);
+        assert(suffix);
+
+        path = strjoin(unit_path, "/", name, suffix, NULL);
+        if (!path)
+                return -ENOMEM;
+
+        if (u->manager->unit_path_cache &&
+            !set_get(u->manager->unit_path_cache, path))
+                r = 0;
+        else
+                r = iterate_dir(u, path, dependency);
+        free(path);
+
+        if (r < 0)
+                return r;
+
+        if (u->instance) {
+                char *template;
+                /* Also try the template dir */
+
+                template = unit_name_template(name);
+                if (!template)
+                        return -ENOMEM;
+
+                path = strjoin(unit_path, "/", template, suffix, NULL);
+                free(template);
+
+                if (!path)
+                        return -ENOMEM;
+
+                if (u->manager->unit_path_cache &&
+                    !set_get(u->manager->unit_path_cache, path))
+                        r = 0;
+                else
+                        r = iterate_dir(u, path, dependency);
+                free(path);
+
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int unit_load_dropin(Unit *u) {
+        Iterator i;
+        char *t;
+
+        assert(u);
+
+        /* Load dependencies from supplementary drop-in directories */
+
+        SET_FOREACH(t, u->names, i) {
+                char **p;
+
+                STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
+                        int r;
+
+                        r = process_dir(u, *p, t, ".wants", UNIT_WANTS);
+                        if (r < 0)
+                                return r;
+
+                        r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}
diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h
new file mode 100644 (file)
index 0000000..1d2fafe
--- /dev/null
@@ -0,0 +1,28 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "unit.h"
+
+/* Read service data supplementary drop-in directories */
+
+int unit_load_dropin(Unit *u);
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
new file mode 100644 (file)
index 0000000..7fba0cf
--- /dev/null
@@ -0,0 +1,258 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "load-fragment.h"
+#include "missing.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name load_fragment_gperf_hash
+%define lookup-function-name load_fragment_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+m4_dnl Define the context options only once
+m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
+`$1.WorkingDirectory,            config_parse_unit_path_printf,      0,                             offsetof($1, exec_context.working_directory)
+$1.RootDirectory,                config_parse_unit_path_printf,      0,                             offsetof($1, exec_context.root_directory)
+$1.User,                         config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.user)
+$1.Group,                        config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.group)
+$1.SupplementaryGroups,          config_parse_strv,                  0,                             offsetof($1, exec_context.supplementary_groups)
+$1.Nice,                         config_parse_exec_nice,             0,                             offsetof($1, exec_context)
+$1.OOMScoreAdjust,               config_parse_exec_oom_score_adjust, 0,                             offsetof($1, exec_context)
+$1.IOSchedulingClass,            config_parse_exec_io_class,         0,                             offsetof($1, exec_context)
+$1.IOSchedulingPriority,         config_parse_exec_io_priority,      0,                             offsetof($1, exec_context)
+$1.CPUSchedulingPolicy,          config_parse_exec_cpu_sched_policy, 0,                             offsetof($1, exec_context)
+$1.CPUSchedulingPriority,        config_parse_exec_cpu_sched_prio,   0,                             offsetof($1, exec_context)
+$1.CPUSchedulingResetOnFork,     config_parse_bool,                  0,                             offsetof($1, exec_context.cpu_sched_reset_on_fork)
+$1.CPUAffinity,                  config_parse_exec_cpu_affinity,     0,                             offsetof($1, exec_context)
+$1.UMask,                        config_parse_mode,                  0,                             offsetof($1, exec_context.umask)
+$1.Environment,                  config_parse_unit_strv_printf,      0,                             offsetof($1, exec_context.environment)
+$1.EnvironmentFile,              config_parse_unit_env_file,         0,                             offsetof($1, exec_context.environment_files)
+$1.StandardInput,                config_parse_input,                 0,                             offsetof($1, exec_context.std_input)
+$1.StandardOutput,               config_parse_output,                0,                             offsetof($1, exec_context.std_output)
+$1.StandardError,                config_parse_output,                0,                             offsetof($1, exec_context.std_error)
+$1.TTYPath,                      config_parse_unit_path_printf,      0,                             offsetof($1, exec_context.tty_path)
+$1.TTYReset,                     config_parse_bool,                  0,                             offsetof($1, exec_context.tty_reset)
+$1.TTYVHangup,                   config_parse_bool,                  0,                             offsetof($1, exec_context.tty_vhangup)
+$1.TTYVTDisallocate,             config_parse_bool,                  0,                             offsetof($1, exec_context.tty_vt_disallocate)
+$1.SyslogIdentifier,             config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.syslog_identifier)
+$1.SyslogFacility,               config_parse_facility,              0,                             offsetof($1, exec_context.syslog_priority)
+$1.SyslogLevel,                  config_parse_level,                 0,                             offsetof($1, exec_context.syslog_priority)
+$1.SyslogLevelPrefix,            config_parse_bool,                  0,                             offsetof($1, exec_context.syslog_level_prefix)
+$1.Capabilities,                 config_parse_exec_capabilities,     0,                             offsetof($1, exec_context)
+$1.SecureBits,                   config_parse_exec_secure_bits,      0,                             offsetof($1, exec_context)
+$1.CapabilityBoundingSet,        config_parse_bounding_set,          0,                             offsetof($1, exec_context.capability_bounding_set_drop)
+$1.TimerSlackNSec,               config_parse_nsec,                  0,                             offsetof($1, exec_context.timer_slack_nsec)
+$1.NoNewPrivileges               config_parse_bool,                  0,                             offsetof($1, exec_context.no_new_privileges)
+$1.SystemCallFilter,             config_parse_syscall_filter,        0,                             offsetof($1, exec_context)
+$1.LimitCPU,                     config_parse_limit,                 RLIMIT_CPU,                    offsetof($1, exec_context.rlimit)
+$1.LimitFSIZE,                   config_parse_limit,                 RLIMIT_FSIZE,                  offsetof($1, exec_context.rlimit)
+$1.LimitDATA,                    config_parse_limit,                 RLIMIT_DATA,                   offsetof($1, exec_context.rlimit)
+$1.LimitSTACK,                   config_parse_limit,                 RLIMIT_STACK,                  offsetof($1, exec_context.rlimit)
+$1.LimitCORE,                    config_parse_limit,                 RLIMIT_CORE,                   offsetof($1, exec_context.rlimit)
+$1.LimitRSS,                     config_parse_limit,                 RLIMIT_RSS,                    offsetof($1, exec_context.rlimit)
+$1.LimitNOFILE,                  config_parse_limit,                 RLIMIT_NOFILE,                 offsetof($1, exec_context.rlimit)
+$1.LimitAS,                      config_parse_limit,                 RLIMIT_AS,                     offsetof($1, exec_context.rlimit)
+$1.LimitNPROC,                   config_parse_limit,                 RLIMIT_NPROC,                  offsetof($1, exec_context.rlimit)
+$1.LimitMEMLOCK,                 config_parse_limit,                 RLIMIT_MEMLOCK,                offsetof($1, exec_context.rlimit)
+$1.LimitLOCKS,                   config_parse_limit,                 RLIMIT_LOCKS,                  offsetof($1, exec_context.rlimit)
+$1.LimitSIGPENDING,              config_parse_limit,                 RLIMIT_SIGPENDING,             offsetof($1, exec_context.rlimit)
+$1.LimitMSGQUEUE,                config_parse_limit,                 RLIMIT_MSGQUEUE,               offsetof($1, exec_context.rlimit)
+$1.LimitNICE,                    config_parse_limit,                 RLIMIT_NICE,                   offsetof($1, exec_context.rlimit)
+$1.LimitRTPRIO,                  config_parse_limit,                 RLIMIT_RTPRIO,                 offsetof($1, exec_context.rlimit)
+$1.LimitRTTIME,                  config_parse_limit,                 RLIMIT_RTTIME,                 offsetof($1, exec_context.rlimit)
+$1.ControlGroup,                 config_parse_unit_cgroup,           0,                             0
+$1.ControlGroupAttribute,        config_parse_unit_cgroup_attr,      0,                             0
+$1.CPUShares,                    config_parse_unit_cpu_shares,       0,                             0
+$1.MemoryLimit,                  config_parse_unit_memory_limit,     0,                             0
+$1.MemorySoftLimit,              config_parse_unit_memory_limit,     0,                             0
+$1.DeviceAllow,                  config_parse_unit_device_allow,     0,                             0
+$1.DeviceDeny,                   config_parse_unit_device_allow,     0,                             0
+$1.BlockIOWeight,                config_parse_unit_blkio_weight,     0,                             0
+$1.BlockIOReadBandwidth,         config_parse_unit_blkio_bandwidth,  0,                             0
+$1.BlockIOWriteBandwidth,        config_parse_unit_blkio_bandwidth,  0,                             0
+$1.ReadWriteDirectories,         config_parse_path_strv,             0,                             offsetof($1, exec_context.read_write_dirs)
+$1.ReadOnlyDirectories,          config_parse_path_strv,             0,                             offsetof($1, exec_context.read_only_dirs)
+$1.InaccessibleDirectories,      config_parse_path_strv,             0,                             offsetof($1, exec_context.inaccessible_dirs)
+$1.PrivateTmp,                   config_parse_bool,                  0,                             offsetof($1, exec_context.private_tmp)
+$1.PrivateNetwork,               config_parse_bool,                  0,                             offsetof($1, exec_context.private_network)
+$1.MountFlags,                   config_parse_exec_mount_flags,      0,                             offsetof($1, exec_context)
+$1.TCPWrapName,                  config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.tcpwrap_name)
+$1.PAMName,                      config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.pam_name)
+$1.IgnoreSIGPIPE,                config_parse_bool,                  0,                             offsetof($1, exec_context.ignore_sigpipe)
+$1.UtmpIdentifier,               config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.utmp_id)
+$1.ControlGroupModify,           config_parse_bool,                  0,                             offsetof($1, exec_context.control_group_modify)
+$1.ControlGroupPersistent,       config_parse_tristate,              0,                             offsetof($1, exec_context.control_group_persistent)'
+)m4_dnl
+m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
+`$1.SendSIGKILL,                  config_parse_bool,                  0,                             offsetof($1, kill_context.send_sigkill)
+$1.KillMode,                     config_parse_kill_mode,             0,                             offsetof($1, kill_context.kill_mode)
+$1.KillSignal,                   config_parse_kill_signal,           0,                             offsetof($1, kill_context.kill_signal)'
+)m4_dnl
+Unit.Description,                config_parse_unit_string_printf,    0,                             offsetof(Unit, description)
+Unit.Documentation,              config_parse_documentation,         0,                             offsetof(Unit, documentation)
+Unit.SourcePath,                 config_parse_path,                  0,                             offsetof(Unit, source_path)
+Unit.Requires,                   config_parse_unit_deps,             UNIT_REQUIRES,                 0
+Unit.RequiresOverridable,        config_parse_unit_deps,             UNIT_REQUIRES_OVERRIDABLE,     0
+Unit.Requisite,                  config_parse_unit_deps,             UNIT_REQUISITE,                0
+Unit.RequisiteOverridable,       config_parse_unit_deps,             UNIT_REQUISITE_OVERRIDABLE,    0
+Unit.Wants,                      config_parse_unit_deps,             UNIT_WANTS,                    0
+Unit.BindsTo,                    config_parse_unit_deps,             UNIT_BINDS_TO,                 0
+Unit.BindTo,                     config_parse_unit_deps,             UNIT_BINDS_TO,                 0
+Unit.Conflicts,                  config_parse_unit_deps,             UNIT_CONFLICTS,                0
+Unit.Before,                     config_parse_unit_deps,             UNIT_BEFORE,                   0
+Unit.After,                      config_parse_unit_deps,             UNIT_AFTER,                    0
+Unit.OnFailure,                  config_parse_unit_deps,             UNIT_ON_FAILURE,               0
+Unit.PropagatesReloadTo,         config_parse_unit_deps,             UNIT_PROPAGATES_RELOAD_TO,     0
+Unit.PropagateReloadTo,          config_parse_unit_deps,             UNIT_PROPAGATES_RELOAD_TO,     0
+Unit.ReloadPropagatedFrom,       config_parse_unit_deps,             UNIT_RELOAD_PROPAGATED_FROM,   0
+Unit.PropagateReloadFrom,        config_parse_unit_deps,             UNIT_RELOAD_PROPAGATED_FROM,   0
+Unit.PartOf,                     config_parse_unit_deps,             UNIT_PART_OF,                  0
+Unit.RequiresMountsFor,          config_parse_unit_requires_mounts_for, 0,                          offsetof(Unit, requires_mounts_for)
+Unit.StopWhenUnneeded,           config_parse_bool,                  0,                             offsetof(Unit, stop_when_unneeded)
+Unit.RefuseManualStart,          config_parse_bool,                  0,                             offsetof(Unit, refuse_manual_start)
+Unit.RefuseManualStop,           config_parse_bool,                  0,                             offsetof(Unit, refuse_manual_stop)
+Unit.AllowIsolate,               config_parse_bool,                  0,                             offsetof(Unit, allow_isolate)
+Unit.DefaultDependencies,        config_parse_bool,                  0,                             offsetof(Unit, default_dependencies)
+Unit.OnFailureIsolate,           config_parse_bool,                  0,                             offsetof(Unit, on_failure_isolate)
+Unit.IgnoreOnIsolate,            config_parse_bool,                  0,                             offsetof(Unit, ignore_on_isolate)
+Unit.IgnoreOnSnapshot,           config_parse_bool,                  0,                             offsetof(Unit, ignore_on_snapshot)
+Unit.JobTimeoutSec,              config_parse_usec,                  0,                             offsetof(Unit, job_timeout)
+Unit.ConditionPathExists,        config_parse_unit_condition_path,   CONDITION_PATH_EXISTS,         0
+Unit.ConditionPathExistsGlob,    config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB,    0
+Unit.ConditionPathIsDirectory,   config_parse_unit_condition_path,   CONDITION_PATH_IS_DIRECTORY,   0
+Unit.ConditionPathIsSymbolicLink,config_parse_unit_condition_path,   CONDITION_PATH_IS_SYMBOLIC_LINK,0
+Unit.ConditionPathIsMountPoint,  config_parse_unit_condition_path,   CONDITION_PATH_IS_MOUNT_POINT, 0
+Unit.ConditionPathIsReadWrite,   config_parse_unit_condition_path,   CONDITION_PATH_IS_READ_WRITE,  0
+Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY, 0
+Unit.ConditionFileNotEmpty,      config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY,      0
+Unit.ConditionFileIsExecutable,  config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE,  0
+Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0
+Unit.ConditionVirtualization,    config_parse_unit_condition_string, CONDITION_VIRTUALIZATION,      0
+Unit.ConditionSecurity,          config_parse_unit_condition_string, CONDITION_SECURITY,            0
+Unit.ConditionCapability,        config_parse_unit_condition_string, CONDITION_CAPABILITY,          0
+Unit.ConditionHost,              config_parse_unit_condition_string, CONDITION_HOST,                0
+Unit.ConditionACPower,           config_parse_unit_condition_string, CONDITION_AC_POWER,            0
+Unit.ConditionNull,              config_parse_unit_condition_null,   0,                             0
+m4_dnl
+Service.PIDFile,                 config_parse_unit_path_printf,      0,                             offsetof(Service, pid_file)
+Service.ExecStartPre,            config_parse_exec,                  SERVICE_EXEC_START_PRE,        offsetof(Service, exec_command)
+Service.ExecStart,               config_parse_exec,                  SERVICE_EXEC_START,            offsetof(Service, exec_command)
+Service.ExecStartPost,           config_parse_exec,                  SERVICE_EXEC_START_POST,       offsetof(Service, exec_command)
+Service.ExecReload,              config_parse_exec,                  SERVICE_EXEC_RELOAD,           offsetof(Service, exec_command)
+Service.ExecStop,                config_parse_exec,                  SERVICE_EXEC_STOP,             offsetof(Service, exec_command)
+Service.ExecStopPost,            config_parse_exec,                  SERVICE_EXEC_STOP_POST,        offsetof(Service, exec_command)
+Service.RestartSec,              config_parse_usec,                  0,                             offsetof(Service, restart_usec)
+Service.TimeoutSec,              config_parse_service_timeout,       0,                             offsetof(Service, timeout_start_usec)
+Service.TimeoutStartSec,         config_parse_service_timeout,       0,                             offsetof(Service, timeout_start_usec)
+Service.TimeoutStopSec,          config_parse_service_timeout,       0,                             offsetof(Service, timeout_stop_usec)
+Service.WatchdogSec,             config_parse_usec,                  0,                             offsetof(Service, watchdog_usec)
+Service.StartLimitInterval,      config_parse_usec,                  0,                             offsetof(Service, start_limit.interval)
+Service.StartLimitBurst,         config_parse_unsigned,              0,                             offsetof(Service, start_limit.burst)
+Service.StartLimitAction,        config_parse_start_limit_action,    0,                             offsetof(Service, start_limit_action)
+Service.Type,                    config_parse_service_type,          0,                             offsetof(Service, type)
+Service.Restart,                 config_parse_service_restart,       0,                             offsetof(Service, restart)
+Service.PermissionsStartOnly,    config_parse_bool,                  0,                             offsetof(Service, permissions_start_only)
+Service.RootDirectoryStartOnly,  config_parse_bool,                  0,                             offsetof(Service, root_directory_start_only)
+Service.RemainAfterExit,         config_parse_bool,                  0,                             offsetof(Service, remain_after_exit)
+Service.GuessMainPID,            config_parse_bool,                  0,                             offsetof(Service, guess_main_pid)
+Service.RestartPreventExitStatus, config_parse_set_status,           0,                             offsetof(Service, restart_ignore_status)
+Service.SuccessExitStatus,       config_parse_set_status,            0,                             offsetof(Service, success_status)
+m4_ifdef(`HAVE_SYSV_COMPAT',
+`Service.SysVStartPriority,      config_parse_sysv_priority,         0,                             offsetof(Service, sysv_start_priority)',
+`Service.SysVStartPriority,      config_parse_warn_compat,           0,                             0')
+Service.NonBlocking,             config_parse_bool,                  0,                             offsetof(Service, exec_context.non_blocking)
+Service.BusName,                 config_parse_unit_string_printf,    0,                             offsetof(Service, bus_name)
+Service.NotifyAccess,            config_parse_notify_access,         0,                             offsetof(Service, notify_access)
+Service.Sockets,                 config_parse_service_sockets,       0,                             0
+Service.FsckPassNo,              config_parse_fsck_passno,           0,                             offsetof(Service, fsck_passno)
+EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
+KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
+m4_dnl
+Socket.ListenStream,             config_parse_socket_listen,         0,                             0
+Socket.ListenDatagram,           config_parse_socket_listen,         0,                             0
+Socket.ListenSequentialPacket,   config_parse_socket_listen,         0,                             0
+Socket.ListenFIFO,               config_parse_socket_listen,         0,                             0
+Socket.ListenNetlink,            config_parse_socket_listen,         0,                             0
+Socket.ListenSpecial,            config_parse_socket_listen,         0,                             0
+Socket.ListenMessageQueue,       config_parse_socket_listen,         0,                             0
+Socket.BindIPv6Only,             config_parse_socket_bind,           0,                             0,
+Socket.Backlog,                  config_parse_unsigned,              0,                             offsetof(Socket, backlog)
+Socket.BindToDevice,             config_parse_socket_bindtodevice,   0,                             0
+Socket.ExecStartPre,             config_parse_exec,                  SOCKET_EXEC_START_PRE,         offsetof(Socket, exec_command)
+Socket.ExecStartPost,            config_parse_exec,                  SOCKET_EXEC_START_POST,        offsetof(Socket, exec_command)
+Socket.ExecStopPre,              config_parse_exec,                  SOCKET_EXEC_STOP_PRE,          offsetof(Socket, exec_command)
+Socket.ExecStopPost,             config_parse_exec,                  SOCKET_EXEC_STOP_POST,         offsetof(Socket, exec_command)
+Socket.TimeoutSec,               config_parse_usec,                  0,                             offsetof(Socket, timeout_usec)
+Socket.DirectoryMode,            config_parse_mode,                  0,                             offsetof(Socket, directory_mode)
+Socket.SocketMode,               config_parse_mode,                  0,                             offsetof(Socket, socket_mode)
+Socket.Accept,                   config_parse_bool,                  0,                             offsetof(Socket, accept)
+Socket.MaxConnections,           config_parse_unsigned,              0,                             offsetof(Socket, max_connections)
+Socket.KeepAlive,                config_parse_bool,                  0,                             offsetof(Socket, keep_alive)
+Socket.Priority,                 config_parse_int,                   0,                             offsetof(Socket, priority)
+Socket.ReceiveBuffer,            config_parse_bytes_size,            0,                             offsetof(Socket, receive_buffer)
+Socket.SendBuffer,               config_parse_bytes_size,            0,                             offsetof(Socket, send_buffer)
+Socket.IPTOS,                    config_parse_ip_tos,                0,                             offsetof(Socket, ip_tos)
+Socket.IPTTL,                    config_parse_int,                   0,                             offsetof(Socket, ip_ttl)
+Socket.Mark,                     config_parse_int,                   0,                             offsetof(Socket, mark)
+Socket.PipeSize,                 config_parse_bytes_size,            0,                             offsetof(Socket, pipe_size)
+Socket.FreeBind,                 config_parse_bool,                  0,                             offsetof(Socket, free_bind)
+Socket.Transparent,              config_parse_bool,                  0,                             offsetof(Socket, transparent)
+Socket.Broadcast,                config_parse_bool,                  0,                             offsetof(Socket, broadcast)
+Socket.PassCredentials,          config_parse_bool,                  0,                             offsetof(Socket, pass_cred)
+Socket.PassSecurity,             config_parse_bool,                  0,                             offsetof(Socket, pass_sec)
+Socket.TCPCongestion,            config_parse_string,                0,                             offsetof(Socket, tcp_congestion)
+Socket.MessageQueueMaxMessages,  config_parse_long,                  0,                             offsetof(Socket, mq_maxmsg)
+Socket.MessageQueueMessageSize,  config_parse_long,                  0,                             offsetof(Socket, mq_msgsize)
+Socket.Service,                  config_parse_socket_service,        0,                             0
+Socket.SmackLabel,               config_parse_string,                0,                             offsetof(Socket, smack)
+Socket.SmackLabelIPIn,           config_parse_string,                0,                             offsetof(Socket, smack_ip_in)
+Socket.SmackLabelIPOut,          config_parse_string,                0,                             offsetof(Socket, smack_ip_out)
+EXEC_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
+KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
+m4_dnl
+Mount.What,                      config_parse_string,                0,                             offsetof(Mount, parameters_fragment.what)
+Mount.Where,                     config_parse_path,                  0,                             offsetof(Mount, where)
+Mount.Options,                   config_parse_string,                0,                             offsetof(Mount, parameters_fragment.options)
+Mount.Type,                      config_parse_string,                0,                             offsetof(Mount, parameters_fragment.fstype)
+Mount.FsckPassNo,                config_parse_fsck_passno,           0,                             offsetof(Mount, parameters_fragment.passno)
+Mount.TimeoutSec,                config_parse_usec,                  0,                             offsetof(Mount, timeout_usec)
+Mount.DirectoryMode,             config_parse_mode,                  0,                             offsetof(Mount, directory_mode)
+EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
+KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
+m4_dnl
+Automount.Where,                 config_parse_path,                  0,                             offsetof(Automount, where)
+Automount.DirectoryMode,         config_parse_mode,                  0,                             offsetof(Automount, directory_mode)
+m4_dnl
+Swap.What,                       config_parse_path,                  0,                             offsetof(Swap, parameters_fragment.what)
+Swap.Priority,                   config_parse_int,                   0,                             offsetof(Swap, parameters_fragment.priority)
+Swap.TimeoutSec,                 config_parse_usec,                  0,                             offsetof(Swap, timeout_usec)
+EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
+KILL_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
+m4_dnl
+Timer.OnCalendar,                config_parse_timer,                 0,                             0
+Timer.OnActiveSec,               config_parse_timer,                 0,                             0
+Timer.OnBootSec,                 config_parse_timer,                 0,                             0
+Timer.OnStartupSec,              config_parse_timer,                 0,                             0
+Timer.OnUnitActiveSec,           config_parse_timer,                 0,                             0
+Timer.OnUnitInactiveSec,         config_parse_timer,                 0,                             0
+Timer.Unit,                      config_parse_timer_unit,            0,                             0
+m4_dnl
+Path.PathExists,                 config_parse_path_spec,             0,                             0
+Path.PathExistsGlob,             config_parse_path_spec,             0,                             0
+Path.PathChanged,                config_parse_path_spec,             0,                             0
+Path.PathModified,               config_parse_path_spec,             0,                             0
+Path.DirectoryNotEmpty,          config_parse_path_spec,             0,                             0
+Path.Unit,                       config_parse_path_unit,             0,                             0
+Path.MakeDirectory,              config_parse_bool,                  0,                             offsetof(Path, make_directory)
+Path.DirectoryMode,              config_parse_mode,                  0,                             offsetof(Path, directory_mode)
+m4_dnl The [Install] section is ignored here.
+Install.Alias,                   NULL,                               0,                             0
+Install.WantedBy,                NULL,                               0,                             0
+Install.RequiredBy,              NULL,                               0,                             0
+Install.Also,                    NULL,                               0,                             0
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
new file mode 100644 (file)
index 0000000..e35fdbc
--- /dev/null
@@ -0,0 +1,2576 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright 2012 Holger Hans Peter Freyther
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <linux/oom.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <sys/prctl.h>
+#include <sys/mount.h>
+#include <linux/fs.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include "unit.h"
+#include "strv.h"
+#include "conf-parser.h"
+#include "load-fragment.h"
+#include "log.h"
+#include "ioprio.h"
+#include "securebits.h"
+#include "missing.h"
+#include "unit-name.h"
+#include "unit-printf.h"
+#include "bus-errors.h"
+#include "utf8.h"
+#include "path-util.h"
+#include "syscall-list.h"
+
+#ifndef HAVE_SYSV_COMPAT
+int config_parse_warn_compat(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        log_debug("[%s:%u] Support for option %s= has been disabled at compile time and is ignored", filename, line, lvalue);
+        return 0;
+}
+#endif
+
+int config_parse_unit_deps(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        UnitDependency d = ltype;
+        Unit *u = userdata;
+        char *w;
+        size_t l;
+        char *state;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                char _cleanup_free_ *t = NULL, *k = NULL;
+                int r;
+
+                t = strndup(w, l);
+                if (!t)
+                        return -ENOMEM;
+
+                k = unit_name_printf(u, t);
+                if (!k)
+                        return -ENOMEM;
+
+                r = unit_add_dependency_by_name(u, d, k, NULL, true);
+                if (r < 0)
+                        log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s",
+                                  filename, line, k, strerror(-r));
+        }
+
+        return 0;
+}
+
+int config_parse_unit_string_printf(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = userdata;
+        char *k;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(u);
+
+        k = unit_full_printf(u, rvalue);
+        if (!k)
+                return -ENOMEM;
+
+        r = config_parse_string(filename, line, section, lvalue, ltype, k, data, userdata);
+        free (k);
+
+        return r;
+}
+
+int config_parse_unit_strv_printf(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = userdata;
+        char *k;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(u);
+
+        k = unit_full_printf(u, rvalue);
+        if (!k)
+                return -ENOMEM;
+
+        r = config_parse_strv(filename, line, section, lvalue, ltype, k, data, userdata);
+        free(k);
+
+        return r;
+}
+
+int config_parse_unit_path_printf(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = userdata;
+        char *k;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(u);
+
+        k = unit_full_printf(u, rvalue);
+        if (!k)
+                return log_oom();
+
+        r = config_parse_path(filename, line, section, lvalue, ltype, k, data, userdata);
+        free(k);
+
+        return r;
+}
+
+int config_parse_socket_listen(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        SocketPort *p, *tail;
+        Socket *s;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        s = SOCKET(data);
+
+        p = new0(SocketPort, 1);
+        if (!p)
+                return -ENOMEM;
+
+        if (streq(lvalue, "ListenFIFO")) {
+                p->type = SOCKET_FIFO;
+
+                if (!(p->path = unit_full_printf(UNIT(s), rvalue))) {
+                        free(p);
+                        return -ENOMEM;
+                }
+
+                path_kill_slashes(p->path);
+
+        } else if (streq(lvalue, "ListenSpecial")) {
+                p->type = SOCKET_SPECIAL;
+
+                if (!(p->path = unit_full_printf(UNIT(s), rvalue))) {
+                        free(p);
+                        return -ENOMEM;
+                }
+
+                path_kill_slashes(p->path);
+
+        } else if (streq(lvalue, "ListenMessageQueue")) {
+
+                p->type = SOCKET_MQUEUE;
+
+                if (!(p->path = unit_full_printf(UNIT(s), rvalue))) {
+                        free(p);
+                        return -ENOMEM;
+                }
+
+                path_kill_slashes(p->path);
+
+        } else if (streq(lvalue, "ListenNetlink")) {
+                char  *k;
+                int r;
+
+                p->type = SOCKET_SOCKET;
+                k = unit_full_printf(UNIT(s), rvalue);
+                r = socket_address_parse_netlink(&p->address, k);
+                free(k);
+
+                if (r < 0) {
+                        log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue);
+                        free(p);
+                        return 0;
+                }
+
+        } else {
+                char *k;
+                int r;
+
+                p->type = SOCKET_SOCKET;
+                k = unit_full_printf(UNIT(s), rvalue);
+                r = socket_address_parse(&p->address, k);
+                free(k);
+
+                if (r < 0) {
+                        log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue);
+                        free(p);
+                        return 0;
+                }
+
+                if (streq(lvalue, "ListenStream"))
+                        p->address.type = SOCK_STREAM;
+                else if (streq(lvalue, "ListenDatagram"))
+                        p->address.type = SOCK_DGRAM;
+                else {
+                        assert(streq(lvalue, "ListenSequentialPacket"));
+                        p->address.type = SOCK_SEQPACKET;
+                }
+
+                if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) {
+                        log_error("[%s:%u] Address family not supported, ignoring: %s", filename, line, rvalue);
+                        free(p);
+                        return 0;
+                }
+        }
+
+        p->fd = -1;
+
+        if (s->ports) {
+                LIST_FIND_TAIL(SocketPort, port, s->ports, tail);
+                LIST_INSERT_AFTER(SocketPort, port, s->ports, tail, p);
+        } else
+                LIST_PREPEND(SocketPort, port, s->ports, p);
+
+        return 0;
+}
+
+int config_parse_socket_bind(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Socket *s;
+        SocketAddressBindIPv6Only b;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        s = SOCKET(data);
+
+        b = socket_address_bind_ipv6_only_from_string(rvalue);
+        if (b < 0) {
+                int r;
+
+                r = parse_boolean(rvalue);
+                if (r < 0) {
+                        log_error("[%s:%u] Failed to parse bind IPv6 only value, ignoring: %s", filename, line, rvalue);
+                        return 0;
+                }
+
+                s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH;
+        } else
+                s->bind_ipv6_only = b;
+
+        return 0;
+}
+
+int config_parse_exec_nice(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int priority;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (safe_atoi(rvalue, &priority) < 0) {
+                log_error("[%s:%u] Failed to parse nice priority, ignoring: %s. ", filename, line, rvalue);
+                return 0;
+        }
+
+        if (priority < PRIO_MIN || priority >= PRIO_MAX) {
+                log_error("[%s:%u] Nice priority out of range, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        c->nice = priority;
+        c->nice_set = true;
+
+        return 0;
+}
+
+int config_parse_exec_oom_score_adjust(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int oa;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (safe_atoi(rvalue, &oa) < 0) {
+                log_error("[%s:%u] Failed to parse the OOM score adjust value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if (oa < OOM_SCORE_ADJ_MIN || oa > OOM_SCORE_ADJ_MAX) {
+                log_error("[%s:%u] OOM score adjust value out of range, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        c->oom_score_adjust = oa;
+        c->oom_score_adjust_set = true;
+
+        return 0;
+}
+
+int config_parse_exec(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecCommand **e = data, *nce;
+        char *path, **n;
+        unsigned k;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(e);
+
+        /* We accept an absolute path as first argument, or
+         * alternatively an absolute prefixed with @ to allow
+         * overriding of argv[0]. */
+
+        e += ltype;
+
+        for (;;) {
+                int i;
+                char *w;
+                size_t l;
+                char *state;
+                bool honour_argv0 = false, ignore = false;
+
+                path = NULL;
+                nce = NULL;
+                n = NULL;
+
+                rvalue += strspn(rvalue, WHITESPACE);
+
+                if (rvalue[0] == 0)
+                        break;
+
+                for (i = 0; i < 2; i++) {
+                        if (rvalue[0] == '-' && !ignore) {
+                                ignore = true;
+                                rvalue ++;
+                        }
+
+                        if (rvalue[0] == '@' && !honour_argv0) {
+                                honour_argv0 = true;
+                                rvalue ++;
+                        }
+                }
+
+                if (*rvalue != '/') {
+                        log_error("[%s:%u] Executable path is not absolute, ignoring: %s",
+                                  filename, line, rvalue);
+                        return 0;
+                }
+
+                k = 0;
+                FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                        if (strncmp(w, ";", MAX(l, 1U)) == 0)
+                                break;
+
+                        k++;
+                }
+
+                n = new(char*, k + !honour_argv0);
+                if (!n)
+                        return -ENOMEM;
+
+                k = 0;
+                FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                        if (strncmp(w, ";", MAX(l, 1U)) == 0)
+                                break;
+                        else if (strncmp(w, "\\;", MAX(l, 1U)) == 0)
+                                w ++;
+
+                        if (honour_argv0 && w == rvalue) {
+                                assert(!path);
+
+                                path = strndup(w, l);
+                                if (!path) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                if (!utf8_is_valid(path)) {
+                                        log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
+                                        r = 0;
+                                        goto fail;
+                                }
+
+                        } else {
+                                char *c;
+
+                                c = n[k++] = cunescape_length(w, l);
+                                if (!c) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                if (!utf8_is_valid(c)) {
+                                        log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
+                                        r = 0;
+                                        goto fail;
+                                }
+                        }
+                }
+
+                n[k] = NULL;
+
+                if (!n[0]) {
+                        log_error("[%s:%u] Invalid command line, ignoring: %s", filename, line, rvalue);
+                        r = 0;
+                        goto fail;
+                }
+
+                if (!path) {
+                        path = strdup(n[0]);
+                        if (!path) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+                }
+
+                assert(path_is_absolute(path));
+
+                nce = new0(ExecCommand, 1);
+                if (!nce) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                nce->argv = n;
+                nce->path = path;
+                nce->ignore = ignore;
+
+                path_kill_slashes(nce->path);
+
+                exec_command_append_list(e, nce);
+
+                rvalue = state;
+        }
+
+        return 0;
+
+fail:
+        n[k] = NULL;
+        strv_free(n);
+        free(path);
+        free(nce);
+
+        return r;
+}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
+
+int config_parse_socket_bindtodevice(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Socket *s = data;
+        char *n;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (rvalue[0] && !streq(rvalue, "*")) {
+                if (!(n = strdup(rvalue)))
+                        return -ENOMEM;
+        } else
+                n = NULL;
+
+        free(s->bind_to_device);
+        s->bind_to_device = n;
+
+        return 0;
+}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier");
+
+int config_parse_exec_io_class(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int x;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        x = ioprio_class_from_string(rvalue);
+        if (x < 0) {
+                log_error("[%s:%u] Failed to parse IO scheduling class, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        c->ioprio = IOPRIO_PRIO_VALUE(x, IOPRIO_PRIO_DATA(c->ioprio));
+        c->ioprio_set = true;
+
+        return 0;
+}
+
+int config_parse_exec_io_priority(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int i;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (safe_atoi(rvalue, &i) < 0 || i < 0 || i >= IOPRIO_BE_NR) {
+                log_error("[%s:%u] Failed to parse io priority, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i);
+        c->ioprio_set = true;
+
+        return 0;
+}
+
+int config_parse_exec_cpu_sched_policy(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+
+        ExecContext *c = data;
+        int x;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        x = sched_policy_from_string(rvalue);
+        if (x < 0) {
+                log_error("[%s:%u] Failed to parse CPU scheduling policy, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        c->cpu_sched_policy = x;
+        /* Moving to or from real-time policy? We need to adjust the priority */
+        c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(x), sched_get_priority_max(x));
+        c->cpu_sched_set = true;
+
+        return 0;
+}
+
+int config_parse_exec_cpu_sched_prio(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int i, min, max;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (safe_atoi(rvalue, &i) < 0) {
+                log_error("[%s:%u] Failed to parse CPU scheduling priority, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+
+        /* On Linux RR/FIFO range from 1 to 99 and OTHER/BATCH may only be 0 */
+        min = sched_get_priority_min(c->cpu_sched_policy);
+        max = sched_get_priority_max(c->cpu_sched_policy);
+
+        if (i < min || i > max) {
+                log_error("[%s:%u] CPU scheduling priority is out of range, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        c->cpu_sched_priority = i;
+        c->cpu_sched_set = true;
+
+        return 0;
+}
+
+int config_parse_exec_cpu_affinity(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        char *w;
+        size_t l;
+        char *state;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                char _cleanup_free_ *t = NULL;
+                int r;
+                unsigned cpu;
+
+                t = strndup(w, l);
+                if (!t)
+                        return -ENOMEM;
+
+                r = safe_atou(t, &cpu);
+
+                if (!c->cpuset) {
+                        c->cpuset = cpu_set_malloc(&c->cpuset_ncpus);
+                        if (!c->cpuset)
+                                return -ENOMEM;
+                }
+
+                if (r < 0 || cpu >= c->cpuset_ncpus) {
+                        log_error("[%s:%u] Failed to parse CPU affinity %s, ignoring: %s",
+                                  filename, line, t, rvalue);
+                        return 0;
+                }
+
+                CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset);
+        }
+
+        return 0;
+}
+
+int config_parse_exec_capabilities(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        cap_t cap;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (!(cap = cap_from_text(rvalue))) {
+                if (errno == ENOMEM)
+                        return -ENOMEM;
+
+                log_error("[%s:%u] Failed to parse capabilities, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if (c->capabilities)
+                cap_free(c->capabilities);
+        c->capabilities = cap;
+
+        return 0;
+}
+
+int config_parse_exec_secure_bits(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        char *w;
+        size_t l;
+        char *state;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                if (first_word(w, "keep-caps"))
+                        c->secure_bits |= SECURE_KEEP_CAPS;
+                else if (first_word(w, "keep-caps-locked"))
+                        c->secure_bits |= SECURE_KEEP_CAPS_LOCKED;
+                else if (first_word(w, "no-setuid-fixup"))
+                        c->secure_bits |= SECURE_NO_SETUID_FIXUP;
+                else if (first_word(w, "no-setuid-fixup-locked"))
+                        c->secure_bits |= SECURE_NO_SETUID_FIXUP_LOCKED;
+                else if (first_word(w, "noroot"))
+                        c->secure_bits |= SECURE_NOROOT;
+                else if (first_word(w, "noroot-locked"))
+                        c->secure_bits |= SECURE_NOROOT_LOCKED;
+                else {
+                        log_error("[%s:%u] Failed to parse secure bits, ignoring: %s",
+                                  filename, line, rvalue);
+                        return 0;
+                }
+        }
+
+        return 0;
+}
+
+int config_parse_bounding_set(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        uint64_t *capability_bounding_set_drop = data;
+        char *w;
+        size_t l;
+        char *state;
+        bool invert = false;
+        uint64_t sum = 0;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (rvalue[0] == '~') {
+                invert = true;
+                rvalue++;
+        }
+
+        /* Note that we store this inverted internally, since the
+         * kernel wants it like this. But we actually expose it
+         * non-inverted everywhere to have a fully normalized
+         * interface. */
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                char _cleanup_free_ *t = NULL;
+                int r;
+                cap_value_t cap;
+
+                t = strndup(w, l);
+                if (!t)
+                        return -ENOMEM;
+
+                r = cap_from_name(t, &cap);
+                if (r < 0) {
+                        log_error("[%s:%u] Failed to parse capability in bounding set, ignoring: %s",
+                                  filename, line, t);
+                        continue;
+                }
+
+                sum |= ((uint64_t) 1ULL) << (uint64_t) cap;
+        }
+
+        if (invert)
+                *capability_bounding_set_drop |= sum;
+        else
+                *capability_bounding_set_drop |= ~sum;
+
+        return 0;
+}
+
+int config_parse_limit(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        struct rlimit **rl = data;
+        unsigned long long u;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        rl += ltype;
+
+        if (streq(rvalue, "infinity"))
+                u = (unsigned long long) RLIM_INFINITY;
+        else if (safe_atollu(rvalue, &u) < 0) {
+                log_error("[%s:%u] Failed to parse resource value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if (!*rl)
+                if (!(*rl = new(struct rlimit, 1)))
+                        return -ENOMEM;
+
+        (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u;
+        return 0;
+}
+
+int config_parse_unit_cgroup(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = userdata;
+        char *w;
+        size_t l;
+        char *state;
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                char _cleanup_free_ *t = NULL, *k = NULL, *ku = NULL;
+                int r;
+
+                t = strndup(w, l);
+                if (!t)
+                        return -ENOMEM;
+
+                k = unit_full_printf(u, t);
+                if (!k)
+                        return -ENOMEM;
+
+                ku = cunescape(k);
+                if (!ku)
+                        return -ENOMEM;
+
+                r = unit_add_cgroup_from_text(u, ku);
+                if (r < 0) {
+                        log_error("[%s:%u] Failed to parse cgroup value %s, ignoring: %s",
+                                  filename, line, k, rvalue);
+                        return 0;
+                }
+        }
+
+        return 0;
+}
+
+#ifdef HAVE_SYSV_COMPAT
+int config_parse_sysv_priority(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        int *priority = data;
+        int i;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (safe_atoi(rvalue, &i) < 0 || i < 0) {
+                log_error("[%s:%u] Failed to parse SysV start priority, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *priority = (int) i;
+        return 0;
+}
+#endif
+
+int config_parse_fsck_passno(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        int *passno = data;
+        int i;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (safe_atoi(rvalue, &i) || i < 0) {
+                log_error("[%s:%u] Failed to parse fsck pass number, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *passno = (int) i;
+        return 0;
+}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
+
+int config_parse_kill_signal(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        int *sig = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(sig);
+
+        if ((r = signal_from_string_try_harder(rvalue)) <= 0) {
+                log_error("[%s:%u] Failed to parse kill signal, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *sig = r;
+        return 0;
+}
+
+int config_parse_exec_mount_flags(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        char *w;
+        size_t l;
+        char *state;
+        unsigned long flags = 0;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        FOREACH_WORD_SEPARATOR(w, l, rvalue, ", ", state) {
+                char _cleanup_free_ *t;
+
+                t = strndup(w, l);
+                if (!t)
+                        return -ENOMEM;
+
+                if (streq(t, "shared"))
+                        flags |= MS_SHARED;
+                else if (streq(t, "slave"))
+                        flags |= MS_SLAVE;
+                else if (streq(w, "private"))
+                        flags |= MS_PRIVATE;
+                else {
+                        log_error("[%s:%u] Failed to parse mount flag %s, ignoring: %s",
+                                  filename, line, t, rvalue);
+                        return 0;
+                }
+        }
+
+        c->mount_flags = flags;
+        return 0;
+}
+
+int config_parse_timer(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Timer *t = data;
+        usec_t u = 0;
+        TimerValue *v;
+        TimerBase b;
+        CalendarSpec *c = NULL;
+        clockid_t id;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        b = timer_base_from_string(lvalue);
+        if (b < 0) {
+                log_error("[%s:%u] Failed to parse timer base, ignoring: %s", filename, line, lvalue);
+                return 0;
+        }
+
+        if (b == TIMER_CALENDAR) {
+                if (calendar_spec_from_string(rvalue, &c) < 0) {
+                        log_error("[%s:%u] Failed to parse calendar specification, ignoring: %s", filename, line, rvalue);
+                        return 0;
+                }
+
+                id = CLOCK_REALTIME;
+        } else {
+                if (parse_usec(rvalue, &u) < 0) {
+                        log_error("[%s:%u] Failed to parse timer value, ignoring: %s", filename, line, rvalue);
+                        return 0;
+                }
+
+                id = CLOCK_MONOTONIC;
+        }
+
+        v = new0(TimerValue, 1);
+        if (!v)
+                return -ENOMEM;
+
+        v->base = b;
+        v->clock_id = id;
+        v->value = u;
+        v->calendar_spec = c;
+
+        LIST_PREPEND(TimerValue, value, t->values, v);
+
+        return 0;
+}
+
+int config_parse_timer_unit(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Timer *t = data;
+        int r;
+        DBusError error;
+        Unit *u;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        dbus_error_init(&error);
+
+        if (endswith(rvalue, ".timer")) {
+                log_error("[%s:%u] Unit cannot be of type timer, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        r = manager_load_unit(UNIT(t)->manager, rvalue, NULL, NULL, &u);
+        if (r < 0) {
+                log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+                dbus_error_free(&error);
+                return 0;
+        }
+
+        unit_ref_set(&t->unit, u);
+
+        return 0;
+}
+
+int config_parse_path_spec(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Path *p = data;
+        PathSpec *s;
+        PathType b;
+        char *k;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        b = path_type_from_string(lvalue);
+        if (b < 0) {
+                log_error("[%s:%u] Failed to parse path type, ignoring: %s", filename, line, lvalue);
+                return 0;
+        }
+
+        k = unit_full_printf(UNIT(p), rvalue);
+        if (!k)
+                return log_oom();
+
+        if (!path_is_absolute(k)) {
+                log_error("[%s:%u] Path is not absolute, ignoring: %s", filename, line, k);
+                free(k);
+                return 0;
+        }
+
+        s = new0(PathSpec, 1);
+        if (!s) {
+                free(k);
+                return log_oom();
+        }
+
+        s->path = path_kill_slashes(k);
+        s->type = b;
+        s->inotify_fd = -1;
+
+        LIST_PREPEND(PathSpec, spec, p->specs, s);
+
+        return 0;
+}
+
+int config_parse_path_unit(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Path *t = data;
+        int r;
+        DBusError error;
+        Unit *u;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        dbus_error_init(&error);
+
+        if (endswith(rvalue, ".path")) {
+                log_error("[%s:%u] Unit cannot be of type path, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if ((r = manager_load_unit(UNIT(t)->manager, rvalue, NULL, &error, &u)) < 0) {
+                log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+                dbus_error_free(&error);
+                return 0;
+        }
+
+        unit_ref_set(&t->unit, u);
+
+        return 0;
+}
+
+int config_parse_socket_service(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Socket *s = data;
+        int r;
+        DBusError error;
+        Unit *x;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        dbus_error_init(&error);
+
+        if (!endswith(rvalue, ".service")) {
+                log_error("[%s:%u] Unit must be of type service, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        r = manager_load_unit(UNIT(s)->manager, rvalue, NULL, &error, &x);
+        if (r < 0) {
+                log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+                dbus_error_free(&error);
+                return 0;
+        }
+
+        unit_ref_set(&s->service, x);
+
+        return 0;
+}
+
+int config_parse_service_sockets(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Service *s = data;
+        int r;
+        char *state, *w;
+        size_t l;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                char _cleanup_free_ *t = NULL, *k = NULL;
+
+                t = strndup(w, l);
+                if (!t)
+                        return -ENOMEM;
+
+                k = unit_name_printf(UNIT(s), t);
+                if (!k)
+                        return -ENOMEM;
+
+                if (!endswith(k, ".socket")) {
+                        log_error("[%s:%u] Unit must be of type socket, ignoring: %s",
+                                  filename, line, k);
+                        continue;
+                }
+
+                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true);
+                if (r < 0)
+                        log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s",
+                                  filename, line, k, strerror(-r));
+
+                r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int config_parse_service_timeout(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Service *s = userdata;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(s);
+
+        r = config_parse_usec(filename, line, section, lvalue, ltype, rvalue, data, userdata);
+
+        if (r)
+                return r;
+
+        if (streq(lvalue, "TimeoutSec")) {
+                s->start_timeout_defined = true;
+                s->timeout_stop_usec = s->timeout_start_usec;
+        } else if (streq(lvalue, "TimeoutStartSec"))
+                s->start_timeout_defined = true;
+
+        return 0;
+}
+
+int config_parse_unit_env_file(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char ***env = data, **k;
+        Unit *u = userdata;
+        char *s;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        s = unit_full_printf(u, rvalue);
+        if (!s)
+                return -ENOMEM;
+
+        if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) {
+                log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, s);
+                free(s);
+                return 0;
+        }
+
+        k = strv_append(*env, s);
+        free(s);
+        if (!k)
+                return -ENOMEM;
+
+        strv_free(*env);
+        *env = k;
+
+        return 0;
+}
+
+int config_parse_ip_tos(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        int *ip_tos = data, x;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        x = ip_tos_from_string(rvalue);
+        if (x < 0) {
+                log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *ip_tos = x;
+        return 0;
+}
+
+int config_parse_unit_condition_path(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ConditionType cond = ltype;
+        Unit *u = data;
+        bool trigger, negate;
+        Condition *c;
+        _cleanup_free_ char *p = NULL;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        trigger = rvalue[0] == '|';
+        if (trigger)
+                rvalue++;
+
+        negate = rvalue[0] == '!';
+        if (negate)
+                rvalue++;
+
+        p = unit_full_printf(u, rvalue);
+        if (!p)
+                return -ENOMEM;
+
+        if (!path_is_absolute(p)) {
+                log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, p);
+                return 0;
+        }
+
+        c = condition_new(cond, p, trigger, negate);
+        if (!c)
+                return -ENOMEM;
+
+        LIST_PREPEND(Condition, conditions, u->conditions, c);
+        return 0;
+}
+
+int config_parse_unit_condition_string(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ConditionType cond = ltype;
+        Unit *u = data;
+        bool trigger, negate;
+        Condition *c;
+        _cleanup_free_ char *s = NULL;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        trigger = rvalue[0] == '|';
+        if (trigger)
+                rvalue++;
+
+        negate = rvalue[0] == '!';
+        if (negate)
+                rvalue++;
+
+        s = unit_full_printf(u, rvalue);
+        if (!s)
+                return -ENOMEM;
+
+        c = condition_new(cond, s, trigger, negate);
+        if (!c)
+                return log_oom();
+
+        LIST_PREPEND(Condition, conditions, u->conditions, c);
+        return 0;
+}
+
+int config_parse_unit_condition_null(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = data;
+        Condition *c;
+        bool trigger, negate;
+        int b;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if ((trigger = rvalue[0] == '|'))
+                rvalue++;
+
+        if ((negate = rvalue[0] == '!'))
+                rvalue++;
+
+        if ((b = parse_boolean(rvalue)) < 0) {
+                log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if (!b)
+                negate = !negate;
+
+        if (!(c = condition_new(CONDITION_NULL, NULL, trigger, negate)))
+                return -ENOMEM;
+
+        LIST_PREPEND(Condition, conditions, u->conditions, c);
+        return 0;
+}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier");
+
+int config_parse_unit_cgroup_attr(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = data;
+        char **l;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        l = strv_split_quoted(rvalue);
+        if (!l)
+                return -ENOMEM;
+
+        if (strv_length(l) != 2) {
+                log_error("[%s:%u] Failed to parse cgroup attribute value, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        r = unit_add_cgroup_attribute(u, NULL, l[0], l[1], NULL);
+        strv_free(l);
+
+        if (r < 0) {
+                log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_unit_cpu_shares(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+        Unit *u = data;
+        int r;
+        unsigned long ul;
+        char *t;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (safe_atolu(rvalue, &ul) < 0 || ul < 1) {
+                log_error("[%s:%u] Failed to parse CPU shares value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if (asprintf(&t, "%lu", ul) < 0)
+                return -ENOMEM;
+
+        r = unit_add_cgroup_attribute(u, "cpu", "cpu.shares", t, NULL);
+        free(t);
+
+        if (r < 0) {
+                log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_unit_memory_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+        Unit *u = data;
+        int r;
+        off_t sz;
+        char *t;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (parse_bytes(rvalue, &sz) < 0 || sz <= 0) {
+                log_error("[%s:%u] Failed to parse memory limit value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if (asprintf(&t, "%llu", (unsigned long long) sz) < 0)
+                return -ENOMEM;
+
+        r = unit_add_cgroup_attribute(u,
+                                      "memory",
+                                      streq(lvalue, "MemorySoftLimit") ? "memory.soft_limit_in_bytes" : "memory.limit_in_bytes",
+                                      t, NULL);
+        free(t);
+
+        if (r < 0) {
+                log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+static int device_map(const char *controller, const char *name, const char *value, char **ret) {
+        char **l;
+
+        assert(controller);
+        assert(name);
+        assert(value);
+        assert(ret);
+
+        l = strv_split_quoted(value);
+        if (!l)
+                return -ENOMEM;
+
+        assert(strv_length(l) >= 1);
+
+        if (streq(l[0], "*")) {
+
+                if (asprintf(ret, "a *:*%s%s",
+                             isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) {
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+
+        } else {
+                struct stat st;
+
+                if (stat(l[0], &st) < 0) {
+                        log_warning("Couldn't stat device %s", l[0]);
+                        strv_free(l);
+                        return -errno;
+                }
+
+                if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
+                        log_warning("%s is not a device.", l[0]);
+                        strv_free(l);
+                        return -ENODEV;
+                }
+
+                if (asprintf(ret, "%c %u:%u%s%s",
+                             S_ISCHR(st.st_mode) ? 'c' : 'b',
+                             major(st.st_rdev), minor(st.st_rdev),
+                             isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) {
+
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+        }
+
+        strv_free(l);
+        return 0;
+}
+
+int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+        Unit *u = data;
+        char **l;
+        int r;
+        unsigned k;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        l = strv_split_quoted(rvalue);
+        if (!l)
+                return -ENOMEM;
+
+        k = strv_length(l);
+        if (k < 1 || k > 2) {
+                log_error("[%s:%u] Failed to parse device value, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        if (!streq(l[0], "*") && !path_startswith(l[0], "/dev")) {
+                log_error("[%s:%u] Device node path not absolute, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        if (!isempty(l[1]) && !in_charset(l[1], "rwm")) {
+                log_error("[%s:%u] Device access string invalid, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+        strv_free(l);
+
+        r = unit_add_cgroup_attribute(u, "devices",
+                                      streq(lvalue, "DeviceAllow") ? "devices.allow" : "devices.deny",
+                                      rvalue, device_map);
+
+        if (r < 0) {
+                log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+static int blkio_map(const char *controller, const char *name, const char *value, char **ret) {
+        struct stat st;
+        char **l;
+        dev_t d;
+
+        assert(controller);
+        assert(name);
+        assert(value);
+        assert(ret);
+
+        l = strv_split_quoted(value);
+        if (!l)
+                return -ENOMEM;
+
+        assert(strv_length(l) == 2);
+
+        if (stat(l[0], &st) < 0) {
+                log_warning("Couldn't stat device %s", l[0]);
+                strv_free(l);
+                return -errno;
+        }
+
+        if (S_ISBLK(st.st_mode))
+                d = st.st_rdev;
+        else if (major(st.st_dev) != 0) {
+                /* If this is not a device node then find the block
+                 * device this file is stored on */
+                d = st.st_dev;
+
+                /* If this is a partition, try to get the originating
+                 * block device */
+                block_get_whole_disk(d, &d);
+        } else {
+                log_warning("%s is not a block device and file system block device cannot be determined or is not local.", l[0]);
+                strv_free(l);
+                return -ENODEV;
+        }
+
+        if (asprintf(ret, "%u:%u %s", major(d), minor(d), l[1]) < 0) {
+                strv_free(l);
+                return -ENOMEM;
+        }
+
+        strv_free(l);
+        return 0;
+}
+
+int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+        Unit *u = data;
+        int r;
+        unsigned long ul;
+        const char *device = NULL, *weight;
+        unsigned k;
+        char *t, **l;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        l = strv_split_quoted(rvalue);
+        if (!l)
+                return -ENOMEM;
+
+        k = strv_length(l);
+        if (k < 1 || k > 2) {
+                log_error("[%s:%u] Failed to parse weight value, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        if (k == 1)
+                weight = l[0];
+        else {
+                device = l[0];
+                weight = l[1];
+        }
+
+        if (device && !path_is_absolute(device)) {
+                log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        if (safe_atolu(weight, &ul) < 0 || ul < 10 || ul > 1000) {
+                log_error("[%s:%u] Failed to parse block IO weight value, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        if (device)
+                r = asprintf(&t, "%s %lu", device, ul);
+        else
+                r = asprintf(&t, "%lu", ul);
+        strv_free(l);
+
+        if (r < 0)
+                return -ENOMEM;
+
+        if (device)
+                r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight_device", t, blkio_map);
+        else
+                r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight", t, NULL);
+        free(t);
+
+        if (r < 0) {
+                log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+        Unit *u = data;
+        int r;
+        off_t bytes;
+        unsigned k;
+        char *t, **l;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        l = strv_split_quoted(rvalue);
+        if (!l)
+                return -ENOMEM;
+
+        k = strv_length(l);
+        if (k != 2) {
+                log_error("[%s:%u] Failed to parse bandwidth value, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        if (!path_is_absolute(l[0])) {
+                log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        if (parse_bytes(l[1], &bytes) < 0 || bytes <= 0) {
+                log_error("[%s:%u] Failed to parse block IO bandwidth value, ignoring: %s", filename, line, rvalue);
+                strv_free(l);
+                return 0;
+        }
+
+        r = asprintf(&t, "%s %llu", l[0], (unsigned long long) bytes);
+        strv_free(l);
+
+        if (r < 0)
+                return -ENOMEM;
+
+        r = unit_add_cgroup_attribute(u, "blkio",
+                                      streq(lvalue, "BlockIOReadBandwidth") ? "blkio.read_bps_device" : "blkio.write_bps_device",
+                                      t, blkio_map);
+        free(t);
+
+        if (r < 0) {
+                log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_unit_requires_mounts_for(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = userdata;
+        int r;
+        bool empty_before;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        empty_before = !u->requires_mounts_for;
+
+        r = config_parse_path_strv(filename, line, section, lvalue, ltype, rvalue, data, userdata);
+
+        /* Make it easy to find units with requires_mounts set */
+        if (empty_before && u->requires_mounts_for)
+                LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
+
+        return r;
+}
+
+int config_parse_documentation(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = userdata;
+        int r;
+        char **a, **b;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(u);
+
+        r = config_parse_unit_strv_printf(filename, line, section, lvalue, ltype, rvalue, data, userdata);
+        if (r < 0)
+                return r;
+
+        for (a = b = u->documentation; a && *a; a++) {
+
+                if (is_valid_documentation_url(*a))
+                        *(b++) = *a;
+                else {
+                        log_error("[%s:%u] Invalid URL, ignoring: %s", filename, line, *a);
+                        free(*a);
+                }
+        }
+        *b = NULL;
+
+        return r;
+}
+
+static void syscall_set(uint32_t *p, int nr) {
+        p[nr >> 4] |= 1 << (nr & 31);
+}
+
+static void syscall_unset(uint32_t *p, int nr) {
+        p[nr >> 4] &= ~(1 << (nr & 31));
+}
+
+int config_parse_syscall_filter(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        Unit *u = userdata;
+        bool invert = false;
+        char *w;
+        size_t l;
+        char *state;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(u);
+
+        if (rvalue[0] == '~') {
+                invert = true;
+                rvalue++;
+        }
+
+        if (!c->syscall_filter) {
+                size_t n;
+
+                n = (syscall_max() + 31) >> 4;
+                c->syscall_filter = new(uint32_t, n);
+                if (!c->syscall_filter)
+                        return -ENOMEM;
+
+                memset(c->syscall_filter, invert ? 0xFF : 0, n * sizeof(uint32_t));
+
+                /* Add these by default */
+                syscall_set(c->syscall_filter, __NR_execve);
+                syscall_set(c->syscall_filter, __NR_rt_sigreturn);
+#ifdef __NR_sigreturn
+                syscall_set(c->syscall_filter, __NR_sigreturn);
+#endif
+                syscall_set(c->syscall_filter, __NR_exit_group);
+                syscall_set(c->syscall_filter, __NR_exit);
+        }
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                int id;
+                char _cleanup_free_ *t = NULL;
+
+                t = strndup(w, l);
+                if (!t)
+                        return -ENOMEM;
+
+                id = syscall_from_name(t);
+
+                if (id < 0)  {
+                        log_error("[%s:%u] Failed to parse syscall, ignoring: %s",
+                                  filename, line, t);
+                        continue;
+                }
+
+                if (invert)
+                        syscall_unset(c->syscall_filter, id);
+                else
+                        syscall_set(c->syscall_filter, id);
+        }
+
+        c->no_new_privileges = true;
+
+        return 0;
+}
+
+#define FOLLOW_MAX 8
+
+static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
+        unsigned c = 0;
+        int fd, r;
+        FILE *f;
+        char *id = NULL;
+
+        assert(filename);
+        assert(*filename);
+        assert(_f);
+        assert(names);
+
+        /* This will update the filename pointer if the loaded file is
+         * reached by a symlink. The old string will be freed. */
+
+        for (;;) {
+                char *target, *name;
+
+                if (c++ >= FOLLOW_MAX)
+                        return -ELOOP;
+
+                path_kill_slashes(*filename);
+
+                /* Add the file name we are currently looking at to
+                 * the names of this unit, but only if it is a valid
+                 * unit name. */
+                name = path_get_file_name(*filename);
+
+                if (unit_name_is_valid(name, true)) {
+
+                        id = set_get(names, name);
+                        if (!id) {
+                                id = strdup(name);
+                                if (!id)
+                                        return -ENOMEM;
+
+                                r = set_put(names, id);
+                                if (r < 0) {
+                                        free(id);
+                                        return r;
+                                }
+                        }
+                }
+
+                /* Try to open the file name, but don't if its a symlink */
+                fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+                if (fd >= 0)
+                        break;
+
+                if (errno != ELOOP)
+                        return -errno;
+
+                /* Hmm, so this is a symlink. Let's read the name, and follow it manually */
+                r = readlink_and_make_absolute(*filename, &target);
+                if (r < 0)
+                        return r;
+
+                free(*filename);
+                *filename = target;
+        }
+
+        f = fdopen(fd, "re");
+        if (!f) {
+                r = -errno;
+                close_nointr_nofail(fd);
+                return r;
+        }
+
+        *_f = f;
+        *_final = id;
+        return 0;
+}
+
+static int merge_by_names(Unit **u, Set *names, const char *id) {
+        char *k;
+        int r;
+
+        assert(u);
+        assert(*u);
+        assert(names);
+
+        /* Let's try to add in all symlink names we found */
+        while ((k = set_steal_first(names))) {
+
+                /* First try to merge in the other name into our
+                 * unit */
+                r = unit_merge_by_name(*u, k);
+                if (r < 0) {
+                        Unit *other;
+
+                        /* Hmm, we couldn't merge the other unit into
+                         * ours? Then let's try it the other way
+                         * round */
+
+                        other = manager_get_unit((*u)->manager, k);
+                        free(k);
+
+                        if (other) {
+                                r = unit_merge(other, *u);
+                                if (r >= 0) {
+                                        *u = other;
+                                        return merge_by_names(u, names, NULL);
+                                }
+                        }
+
+                        return r;
+                }
+
+                if (id == k)
+                        unit_choose_id(*u, id);
+
+                free(k);
+        }
+
+        return 0;
+}
+
+static int load_from_path(Unit *u, const char *path) {
+        int r;
+        Set *symlink_names;
+        FILE *f = NULL;
+        char *filename = NULL, *id = NULL;
+        Unit *merged;
+        struct stat st;
+
+        assert(u);
+        assert(path);
+
+        symlink_names = set_new(string_hash_func, string_compare_func);
+        if (!symlink_names)
+                return -ENOMEM;
+
+        if (path_is_absolute(path)) {
+
+                filename = strdup(path);
+                if (!filename) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                r = open_follow(&filename, &f, symlink_names, &id);
+                if (r < 0) {
+                        free(filename);
+                        filename = NULL;
+
+                        if (r != -ENOENT)
+                                goto finish;
+                }
+
+        } else  {
+                char **p;
+
+                STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
+
+                        /* Instead of opening the path right away, we manually
+                         * follow all symlinks and add their name to our unit
+                         * name set while doing so */
+                        filename = path_make_absolute(path, *p);
+                        if (!filename) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        if (u->manager->unit_path_cache &&
+                            !set_get(u->manager->unit_path_cache, filename))
+                                r = -ENOENT;
+                        else
+                                r = open_follow(&filename, &f, symlink_names, &id);
+
+                        if (r < 0) {
+                                free(filename);
+                                filename = NULL;
+
+                                if (r != -ENOENT)
+                                        goto finish;
+
+                                /* Empty the symlink names for the next run */
+                                set_clear_free(symlink_names);
+                                continue;
+                        }
+
+                        break;
+                }
+        }
+
+        if (!filename) {
+                /* Hmm, no suitable file found? */
+                r = 0;
+                goto finish;
+        }
+
+        merged = u;
+        r = merge_by_names(&merged, symlink_names, id);
+        if (r < 0)
+                goto finish;
+
+        if (merged != u) {
+                u->load_state = UNIT_MERGED;
+                r = 0;
+                goto finish;
+        }
+
+        if (fstat(fileno(f), &st) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (null_or_empty(&st))
+                u->load_state = UNIT_MASKED;
+        else {
+                /* Now, parse the file contents */
+                r = config_parse(filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
+                if (r < 0)
+                        goto finish;
+
+                u->load_state = UNIT_LOADED;
+        }
+
+        free(u->fragment_path);
+        u->fragment_path = filename;
+        filename = NULL;
+
+        u->fragment_mtime = timespec_load(&st.st_mtim);
+
+        if (u->source_path) {
+                if (stat(u->source_path, &st) >= 0)
+                        u->source_mtime = timespec_load(&st.st_mtim);
+                else
+                        u->source_mtime = 0;
+        }
+
+        r = 0;
+
+finish:
+        set_free_free(symlink_names);
+        free(filename);
+
+        if (f)
+                fclose(f);
+
+        return r;
+}
+
+int unit_load_fragment(Unit *u) {
+        int r;
+        Iterator i;
+        const char *t;
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+        assert(u->id);
+
+        /* First, try to find the unit under its id. We always look
+         * for unit files in the default directories, to make it easy
+         * to override things by placing things in /etc/systemd/system */
+        r = load_from_path(u, u->id);
+        if (r < 0)
+                return r;
+
+        /* Try to find an alias we can load this with */
+        if (u->load_state == UNIT_STUB)
+                SET_FOREACH(t, u->names, i) {
+
+                        if (t == u->id)
+                                continue;
+
+                        r = load_from_path(u, t);
+                        if (r < 0)
+                                return r;
+
+                        if (u->load_state != UNIT_STUB)
+                                break;
+                }
+
+        /* And now, try looking for it under the suggested (originally linked) path */
+        if (u->load_state == UNIT_STUB && u->fragment_path) {
+
+                r = load_from_path(u, u->fragment_path);
+                if (r < 0)
+                        return r;
+
+                if (u->load_state == UNIT_STUB) {
+                        /* Hmm, this didn't work? Then let's get rid
+                         * of the fragment path stored for us, so that
+                         * we don't point to an invalid location. */
+                        free(u->fragment_path);
+                        u->fragment_path = NULL;
+                }
+        }
+
+        /* Look for a template */
+        if (u->load_state == UNIT_STUB && u->instance) {
+                char *k;
+
+                k = unit_name_template(u->id);
+                if (!k)
+                        return -ENOMEM;
+
+                r = load_from_path(u, k);
+                free(k);
+
+                if (r < 0)
+                        return r;
+
+                if (u->load_state == UNIT_STUB)
+                        SET_FOREACH(t, u->names, i) {
+
+                                if (t == u->id)
+                                        continue;
+
+                                k = unit_name_template(t);
+                                if (!k)
+                                        return -ENOMEM;
+
+                                r = load_from_path(u, k);
+                                free(k);
+
+                                if (r < 0)
+                                        return r;
+
+                                if (u->load_state != UNIT_STUB)
+                                        break;
+                        }
+        }
+
+        return 0;
+}
+
+void unit_dump_config_items(FILE *f) {
+        static const struct {
+                const ConfigParserCallback callback;
+                const char *rvalue;
+        } table[] = {
+                { config_parse_int,                   "INTEGER" },
+                { config_parse_unsigned,              "UNSIGNED" },
+                { config_parse_bytes_size,            "SIZE" },
+                { config_parse_bool,                  "BOOLEAN" },
+                { config_parse_string,                "STRING" },
+                { config_parse_path,                  "PATH" },
+                { config_parse_unit_path_printf,      "PATH" },
+                { config_parse_strv,                  "STRING [...]" },
+                { config_parse_exec_nice,             "NICE" },
+                { config_parse_exec_oom_score_adjust, "OOMSCOREADJUST" },
+                { config_parse_exec_io_class,         "IOCLASS" },
+                { config_parse_exec_io_priority,      "IOPRIORITY" },
+                { config_parse_exec_cpu_sched_policy, "CPUSCHEDPOLICY" },
+                { config_parse_exec_cpu_sched_prio,   "CPUSCHEDPRIO" },
+                { config_parse_exec_cpu_affinity,     "CPUAFFINITY" },
+                { config_parse_mode,                  "MODE" },
+                { config_parse_unit_env_file,         "FILE" },
+                { config_parse_output,                "OUTPUT" },
+                { config_parse_input,                 "INPUT" },
+                { config_parse_facility,              "FACILITY" },
+                { config_parse_level,                 "LEVEL" },
+                { config_parse_exec_capabilities,     "CAPABILITIES" },
+                { config_parse_exec_secure_bits,      "SECUREBITS" },
+                { config_parse_bounding_set,          "BOUNDINGSET" },
+                { config_parse_limit,                 "LIMIT" },
+                { config_parse_unit_cgroup,           "CGROUP [...]" },
+                { config_parse_unit_deps,             "UNIT [...]" },
+                { config_parse_exec,                  "PATH [ARGUMENT [...]]" },
+                { config_parse_service_type,          "SERVICETYPE" },
+                { config_parse_service_restart,       "SERVICERESTART" },
+#ifdef HAVE_SYSV_COMPAT
+                { config_parse_sysv_priority,         "SYSVPRIORITY" },
+#else
+                { config_parse_warn_compat,           "NOTSUPPORTED" },
+#endif
+                { config_parse_kill_mode,             "KILLMODE" },
+                { config_parse_kill_signal,           "SIGNAL" },
+                { config_parse_socket_listen,         "SOCKET [...]" },
+                { config_parse_socket_bind,           "SOCKETBIND" },
+                { config_parse_socket_bindtodevice,   "NETWORKINTERFACE" },
+                { config_parse_usec,                  "SECONDS" },
+                { config_parse_nsec,                  "NANOSECONDS" },
+                { config_parse_path_strv,             "PATH [...]" },
+                { config_parse_unit_requires_mounts_for, "PATH [...]" },
+                { config_parse_exec_mount_flags,      "MOUNTFLAG [...]" },
+                { config_parse_unit_string_printf,    "STRING" },
+                { config_parse_timer,                 "TIMER" },
+                { config_parse_timer_unit,            "NAME" },
+                { config_parse_path_spec,             "PATH" },
+                { config_parse_path_unit,             "UNIT" },
+                { config_parse_notify_access,         "ACCESS" },
+                { config_parse_ip_tos,                "TOS" },
+                { config_parse_unit_condition_path,   "CONDITION" },
+                { config_parse_unit_condition_string, "CONDITION" },
+                { config_parse_unit_condition_null,   "CONDITION" },
+        };
+
+        const char *prev = NULL;
+        const char *i;
+
+        assert(f);
+
+        NULSTR_FOREACH(i, load_fragment_gperf_nulstr) {
+                const char *rvalue = "OTHER", *lvalue;
+                unsigned j;
+                size_t prefix_len;
+                const char *dot;
+                const ConfigPerfItem *p;
+
+                assert_se(p = load_fragment_gperf_lookup(i, strlen(i)));
+
+                dot = strchr(i, '.');
+                lvalue = dot ? dot + 1 : i;
+                prefix_len = dot-i;
+
+                if (dot)
+                        if (!prev || strncmp(prev, i, prefix_len+1) != 0) {
+                                if (prev)
+                                        fputc('\n', f);
+
+                                fprintf(f, "[%.*s]\n", (int) prefix_len, i);
+                        }
+
+                for (j = 0; j < ELEMENTSOF(table); j++)
+                        if (p->parse == table[j].callback) {
+                                rvalue = table[j].rvalue;
+                                break;
+                        }
+
+                fprintf(f, "%s=%s\n", lvalue, rvalue);
+                prev = i;
+        }
+}
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
new file mode 100644 (file)
index 0000000..24f7384
--- /dev/null
@@ -0,0 +1,88 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "unit.h"
+
+/* Read service data from .desktop file style configuration fragments */
+
+int unit_load_fragment(Unit *u);
+
+void unit_dump_config_items(FILE *f);
+
+int config_parse_warn_compat(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_deps(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_string_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_strv_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_path_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_documentation(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_socket_listen(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_socket_bind(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_nice(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_oom_score_adjust(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_service_timeout(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_service_type(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_service_restart(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_socket_bindtodevice(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_output(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_input(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_io_class(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_io_priority(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_cpu_sched_policy(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_cpu_sched_prio(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_cpu_affinity(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_capabilities(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_secure_bits(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bounding_set(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_cgroup(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_sysv_priority(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_fsck_passno(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_kill_signal(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_mount_flags(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_timer(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_timer_unit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_path_spec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_path_unit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_socket_service(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_service_sockets(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_env_file(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_ip_tos(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_condition_path(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_condition_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_condition_null(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_kill_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_notify_access(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_start_limit_action(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_cgroup_attr(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_cpu_shares(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_memory_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_requires_mounts_for(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_syscall_filter(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+/* gperf prototypes */
+const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
+extern const char load_fragment_gperf_nulstr[];
diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c
new file mode 100644 (file)
index 0000000..48b59bf
--- /dev/null
@@ -0,0 +1,146 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "locale-setup.h"
+#include "util.h"
+#include "macro.h"
+#include "virt.h"
+
+enum {
+        /* We don't list LC_ALL here on purpose. People should be
+         * using LANG instead. */
+
+        VARIABLE_LANG,
+        VARIABLE_LANGUAGE,
+        VARIABLE_LC_CTYPE,
+        VARIABLE_LC_NUMERIC,
+        VARIABLE_LC_TIME,
+        VARIABLE_LC_COLLATE,
+        VARIABLE_LC_MONETARY,
+        VARIABLE_LC_MESSAGES,
+        VARIABLE_LC_PAPER,
+        VARIABLE_LC_NAME,
+        VARIABLE_LC_ADDRESS,
+        VARIABLE_LC_TELEPHONE,
+        VARIABLE_LC_MEASUREMENT,
+        VARIABLE_LC_IDENTIFICATION,
+        _VARIABLE_MAX
+};
+
+static const char * const variable_names[_VARIABLE_MAX] = {
+        [VARIABLE_LANG] = "LANG",
+        [VARIABLE_LANGUAGE] = "LANGUAGE",
+        [VARIABLE_LC_CTYPE] = "LC_CTYPE",
+        [VARIABLE_LC_NUMERIC] = "LC_NUMERIC",
+        [VARIABLE_LC_TIME] = "LC_TIME",
+        [VARIABLE_LC_COLLATE] = "LC_COLLATE",
+        [VARIABLE_LC_MONETARY] = "LC_MONETARY",
+        [VARIABLE_LC_MESSAGES] = "LC_MESSAGES",
+        [VARIABLE_LC_PAPER] = "LC_PAPER",
+        [VARIABLE_LC_NAME] = "LC_NAME",
+        [VARIABLE_LC_ADDRESS] = "LC_ADDRESS",
+        [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE",
+        [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT",
+        [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
+};
+
+int locale_setup(void) {
+        char *variables[_VARIABLE_MAX];
+        int r = 0, i;
+
+        zero(variables);
+
+        if (detect_container(NULL) <= 0) {
+                r = parse_env_file("/proc/cmdline", WHITESPACE,
+                                   "locale.LANG",              &variables[VARIABLE_LANG],
+                                   "locale.LANGUAGE",          &variables[VARIABLE_LANGUAGE],
+                                   "locale.LC_CTYPE",          &variables[VARIABLE_LC_CTYPE],
+                                   "locale.LC_NUMERIC",        &variables[VARIABLE_LC_NUMERIC],
+                                   "locale.LC_TIME",           &variables[VARIABLE_LC_TIME],
+                                   "locale.LC_COLLATE",        &variables[VARIABLE_LC_COLLATE],
+                                   "locale.LC_MONETARY",       &variables[VARIABLE_LC_MONETARY],
+                                   "locale.LC_MESSAGES",       &variables[VARIABLE_LC_MESSAGES],
+                                   "locale.LC_PAPER",          &variables[VARIABLE_LC_PAPER],
+                                   "locale.LC_NAME",           &variables[VARIABLE_LC_NAME],
+                                   "locale.LC_ADDRESS",        &variables[VARIABLE_LC_ADDRESS],
+                                   "locale.LC_TELEPHONE",      &variables[VARIABLE_LC_TELEPHONE],
+                                   "locale.LC_MEASUREMENT",    &variables[VARIABLE_LC_MEASUREMENT],
+                                   "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
+                                   NULL);
+
+                if (r < 0 && r != -ENOENT)
+                        log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
+        }
+
+        /* Hmm, nothing set on the kernel cmd line? Then let's
+         * try /etc/locale.conf */
+        if (r <= 0) {
+                r = parse_env_file("/etc/locale.conf", NEWLINE,
+                                   "LANG",              &variables[VARIABLE_LANG],
+                                   "LANGUAGE",          &variables[VARIABLE_LANGUAGE],
+                                   "LC_CTYPE",          &variables[VARIABLE_LC_CTYPE],
+                                   "LC_NUMERIC",        &variables[VARIABLE_LC_NUMERIC],
+                                   "LC_TIME",           &variables[VARIABLE_LC_TIME],
+                                   "LC_COLLATE",        &variables[VARIABLE_LC_COLLATE],
+                                   "LC_MONETARY",       &variables[VARIABLE_LC_MONETARY],
+                                   "LC_MESSAGES",       &variables[VARIABLE_LC_MESSAGES],
+                                   "LC_PAPER",          &variables[VARIABLE_LC_PAPER],
+                                   "LC_NAME",           &variables[VARIABLE_LC_NAME],
+                                   "LC_ADDRESS",        &variables[VARIABLE_LC_ADDRESS],
+                                   "LC_TELEPHONE",      &variables[VARIABLE_LC_TELEPHONE],
+                                   "LC_MEASUREMENT",    &variables[VARIABLE_LC_MEASUREMENT],
+                                   "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
+                                   NULL);
+
+                if (r < 0 && r != -ENOENT)
+                        log_warning("Failed to read /etc/locale.conf: %s", strerror(-r));
+        }
+
+        if (!variables[VARIABLE_LANG]) {
+                variables[VARIABLE_LANG] = strdup("C");
+                if (!variables[VARIABLE_LANG]) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+        }
+
+        for (i = 0; i < _VARIABLE_MAX; i++) {
+                if (variables[i]) {
+                        if (setenv(variable_names[i], variables[i], 1) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+                } else
+                        unsetenv(variable_names[i]);
+        }
+
+        r = 0;
+
+finish:
+        for (i = 0; i < _VARIABLE_MAX; i++)
+                free(variables[i]);
+
+        return r;
+}
diff --git a/src/core/locale-setup.h b/src/core/locale-setup.h
new file mode 100644 (file)
index 0000000..5a0f2f7
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int locale_setup(void);
diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c
new file mode 100644 (file)
index 0000000..065b75a
--- /dev/null
@@ -0,0 +1,317 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <asm/types.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include "util.h"
+#include "macro.h"
+#include "loopback-setup.h"
+#include "socket-util.h"
+
+#define NLMSG_TAIL(nmsg)                                                \
+        ((struct rtattr *) (((uint8_t*) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
+
+static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type, const void *data, size_t data_length) {
+        size_t length;
+        struct rtattr *rta;
+
+        length = RTA_LENGTH(data_length);
+
+        if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
+                return -E2BIG;
+
+        rta = NLMSG_TAIL(n);
+        rta->rta_type = type;
+        rta->rta_len = length;
+        memcpy(RTA_DATA(rta), data, data_length);
+        n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
+
+        return 0;
+}
+
+static ssize_t sendto_loop(int fd, const void *buf, size_t buf_len, int flags, const struct sockaddr *sa, socklen_t sa_len) {
+
+        for (;;) {
+                ssize_t l;
+
+                l = sendto(fd, buf, buf_len, flags, sa, sa_len);
+                if (l >= 0)
+                        return l;
+
+                if (errno != EINTR)
+                        return -errno;
+        }
+}
+
+static ssize_t recvfrom_loop(int fd, void *buf, size_t buf_len, int flags, struct sockaddr *sa, socklen_t *sa_len) {
+
+        for (;;) {
+                ssize_t l;
+
+                l = recvfrom(fd, buf, buf_len, flags, sa, sa_len);
+                if (l >= 0)
+                        return l;
+
+                if (errno != EINTR)
+                        return -errno;
+        }
+}
+
+static int add_adresses(int fd, int if_loopback, unsigned *requests) {
+        union {
+                struct sockaddr sa;
+                struct sockaddr_nl nl;
+        } sa;
+        union {
+                struct nlmsghdr header;
+                uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
+                            NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
+                            RTA_LENGTH(sizeof(struct in6_addr))];
+        } request;
+
+        struct ifaddrmsg *ifaddrmsg;
+        uint32_t ipv4_address = htonl(INADDR_LOOPBACK);
+        int r;
+
+        zero(request);
+
+        request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+        request.header.nlmsg_type = RTM_NEWADDR;
+        request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK;
+        request.header.nlmsg_seq = *requests + 1;
+
+        ifaddrmsg = NLMSG_DATA(&request.header);
+        ifaddrmsg->ifa_family = AF_INET;
+        ifaddrmsg->ifa_prefixlen = 8;
+        ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
+        ifaddrmsg->ifa_scope = RT_SCOPE_HOST;
+        ifaddrmsg->ifa_index = if_loopback;
+
+        r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &ipv4_address, sizeof(ipv4_address));
+        if (r < 0)
+                return r;
+
+        zero(sa);
+        sa.nl.nl_family = AF_NETLINK;
+
+        if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0)
+                return -errno;
+        (*requests)++;
+
+        if (!socket_ipv6_is_supported())
+                return 0;
+
+        request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+        request.header.nlmsg_seq = *requests + 1;
+
+        ifaddrmsg->ifa_family = AF_INET6;
+        ifaddrmsg->ifa_prefixlen = 128;
+
+        r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &in6addr_loopback, sizeof(in6addr_loopback));
+        if (r < 0)
+                return r;
+
+        if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0)
+                return -errno;
+        (*requests)++;
+
+        return 0;
+}
+
+static int start_interface(int fd, int if_loopback, unsigned *requests) {
+        union {
+                struct sockaddr sa;
+                struct sockaddr_nl nl;
+        } sa;
+        union {
+                struct nlmsghdr header;
+                uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
+                            NLMSG_ALIGN(sizeof(struct ifinfomsg))];
+        } request;
+
+        struct ifinfomsg *ifinfomsg;
+
+        zero(request);
+
+        request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+        request.header.nlmsg_type = RTM_NEWLINK;
+        request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
+        request.header.nlmsg_seq = *requests + 1;
+
+        ifinfomsg = NLMSG_DATA(&request.header);
+        ifinfomsg->ifi_family = AF_UNSPEC;
+        ifinfomsg->ifi_index = if_loopback;
+        ifinfomsg->ifi_flags = IFF_UP;
+        ifinfomsg->ifi_change = IFF_UP;
+
+        zero(sa);
+        sa.nl.nl_family = AF_NETLINK;
+
+        if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0)
+                return -errno;
+
+        (*requests)++;
+
+        return 0;
+}
+
+static int read_response(int fd, unsigned requests_max) {
+        union {
+                struct sockaddr sa;
+                struct sockaddr_nl nl;
+        } sa;
+        union {
+                struct nlmsghdr header;
+                uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
+                            NLMSG_ALIGN(sizeof(struct nlmsgerr))];
+        } response;
+
+        ssize_t l;
+        socklen_t sa_len = sizeof(sa);
+        struct nlmsgerr *nlmsgerr;
+
+        l = recvfrom_loop(fd, &response, sizeof(response), 0, &sa.sa, &sa_len);
+        if (l < 0)
+                return -errno;
+
+        if (sa_len != sizeof(sa.nl) ||
+            sa.nl.nl_family != AF_NETLINK)
+                return -EIO;
+
+        if (sa.nl.nl_pid != 0)
+                return 0;
+
+        if ((size_t) l < sizeof(struct nlmsghdr))
+                return -EIO;
+
+        if (response.header.nlmsg_type != NLMSG_ERROR ||
+            (pid_t) response.header.nlmsg_pid != getpid() ||
+            response.header.nlmsg_seq >= requests_max)
+                return 0;
+
+        if ((size_t) l < NLMSG_LENGTH(sizeof(struct nlmsgerr)) ||
+            response.header.nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
+                return -EIO;
+
+        nlmsgerr = NLMSG_DATA(&response.header);
+
+        if (nlmsgerr->error < 0 && nlmsgerr->error != -EEXIST)
+                return nlmsgerr->error;
+
+        return response.header.nlmsg_seq;
+}
+
+static int check_loopback(void) {
+        int r, fd;
+        union {
+                struct sockaddr sa;
+                struct sockaddr_in in;
+        } sa;
+
+        /* If we failed to set up the loop back device, check whether
+         * it might already be set up */
+
+        fd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
+        if (fd < 0)
+                return -errno;
+
+        zero(sa);
+        sa.in.sin_family = AF_INET;
+        sa.in.sin_addr.s_addr = INADDR_LOOPBACK;
+
+        if (bind(fd, &sa.sa, sizeof(sa.in)) >= 0)
+                r = 1;
+        else
+                r = errno == EADDRNOTAVAIL ? 0 : -errno;
+
+        close_nointr_nofail(fd);
+
+        return r;
+}
+
+int loopback_setup(void) {
+        int r, if_loopback;
+        union {
+                struct sockaddr sa;
+                struct sockaddr_nl nl;
+        } sa;
+        unsigned requests = 0, i;
+        int fd;
+        bool eperm = false;
+
+        errno = 0;
+        if_loopback = (int) if_nametoindex("lo");
+        if (if_loopback <= 0)
+                return errno ? -errno : -ENODEV;
+
+        fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+        if (fd < 0)
+                return -errno;
+
+        zero(sa);
+        sa.nl.nl_family = AF_NETLINK;
+        if (bind(fd, &sa.sa, sizeof(sa)) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        r = add_adresses(fd, if_loopback, &requests);
+        if (r < 0)
+                goto finish;
+
+        r = start_interface(fd, if_loopback, &requests);
+        if (r < 0)
+                goto finish;
+
+        for (i = 0; i < requests; i++) {
+                r = read_response(fd, requests);
+
+                if (r == -EPERM)
+                        eperm = true;
+                else if (r  < 0)
+                        goto finish;
+        }
+
+        if (eperm && check_loopback() < 0) {
+                r = -EPERM;
+                goto finish;
+        }
+
+        r = 0;
+
+finish:
+        if (r < 0)
+                log_warning("Failed to configure loopback device: %s", strerror(-r));
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
diff --git a/src/core/loopback-setup.h b/src/core/loopback-setup.h
new file mode 100644 (file)
index 0000000..dd83cf1
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int loopback_setup(void);
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
new file mode 100644 (file)
index 0000000..7f4c23b
--- /dev/null
@@ -0,0 +1,246 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/mount.h>
+
+#include <systemd/sd-id128.h>
+
+#include "machine-id-setup.h"
+#include "macro.h"
+#include "util.h"
+#include "mkdir.h"
+#include "log.h"
+#include "virt.h"
+
+static int shorten_uuid(char destination[36], const char *source) {
+        unsigned i, j;
+
+        for (i = 0, j = 0; i < 36 && j < 32; i++) {
+                int t;
+
+                t = unhexchar(source[i]);
+                if (t < 0)
+                        continue;
+
+                destination[j++] = hexchar(t);
+        }
+
+        if (i == 36 && j == 32) {
+                destination[32] = '\n';
+                destination[33] = 0;
+                return 0;
+        }
+
+        return -EINVAL;
+}
+
+static int generate(char id[34]) {
+        int fd, r;
+        unsigned char *p;
+        sd_id128_t buf;
+        char *q;
+        ssize_t k;
+        const char *vm_id;
+
+        assert(id);
+
+        /* First, try reading the D-Bus machine id, unless it is a symlink */
+        fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        if (fd >= 0) {
+
+                k = loop_read(fd, id, 32, false);
+                close_nointr_nofail(fd);
+
+                if (k >= 32) {
+                        id[32] = '\n';
+                        id[33] = 0;
+
+                        log_info("Initializing machine ID from D-Bus machine ID.");
+                        return 0;
+                }
+        }
+
+        /* If that didn't work, see if we are running in qemu/kvm and a
+         * machine ID was passed in via -uuid on the qemu/kvm command
+         * line */
+
+        r = detect_vm(&vm_id);
+        if (r > 0 && streq(vm_id, "kvm")) {
+                char uuid[37];
+
+                fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+                if (fd >= 0) {
+                        k = loop_read(fd, uuid, 36, false);
+                        close_nointr_nofail(fd);
+
+                        if (k >= 36) {
+                                r = shorten_uuid(id, uuid);
+                                if (r >= 0) {
+                                        log_info("Initializing machine ID from KVM UUID.");
+                                        return 0;
+                                }
+                        }
+                }
+        }
+
+        /* If that didn't work either, see if we are running in a
+         * container, and a machine ID was passed in via
+         * $container_uuid the way libvirt/LXC does it */
+        r = detect_container(NULL);
+        if (r > 0) {
+                char *e;
+
+                r = getenv_for_pid(1, "container_uuid", &e);
+                if (r > 0) {
+                        if (strlen(e) >= 36) {
+                                r = shorten_uuid(id, e);
+                                if (r >= 0) {
+                                        log_info("Initializing machine ID from container UUID.");
+                                        free(e);
+                                        return 0;
+                                }
+                        }
+
+                        free(e);
+                }
+        }
+
+        /* If that didn't work, generate a random machine id */
+        r = sd_id128_randomize(&buf);
+        if (r < 0) {
+                log_error("Failed to open /dev/urandom: %s", strerror(-r));
+                return r;
+        }
+
+        for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += 2) {
+                q[0] = hexchar(*p >> 4);
+                q[1] = hexchar(*p & 15);
+        }
+
+        id[32] = '\n';
+        id[33] = 0;
+
+        log_info("Initializing machine ID from random generator.");
+
+        return 0;
+}
+
+int machine_id_setup(void) {
+        int fd, r;
+        bool writable;
+        struct stat st;
+        char id[34]; /* 32 + \n + \0 */
+        mode_t m;
+
+        m = umask(0000);
+
+        /* We create this 0444, to indicate that this isn't really
+         * something you should ever modify. Of course, since the file
+         * will be owned by root it doesn't matter much, but maybe
+         * people look. */
+
+        fd = open("/etc/machine-id", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
+        if (fd >= 0)
+                writable = true;
+        else {
+                fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (fd < 0) {
+                        umask(m);
+                        log_error("Cannot open /etc/machine-id: %m");
+                        return -errno;
+                }
+
+                writable = false;
+        }
+
+        umask(m);
+
+        if (fstat(fd, &st) < 0) {
+                log_error("fstat() failed: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if (S_ISREG(st.st_mode)) {
+                if (loop_read(fd, id, 32, false) >= 32) {
+                        r = 0;
+                        goto finish;
+                }
+        }
+
+        /* Hmm, so, the id currently stored is not useful, then let's
+         * generate one */
+
+        r = generate(id);
+        if (r < 0)
+                goto finish;
+
+        if (S_ISREG(st.st_mode) && writable) {
+                lseek(fd, 0, SEEK_SET);
+
+                if (loop_write(fd, id, 33, false) == 33) {
+                        r = 0;
+                        goto finish;
+                }
+        }
+
+        close_nointr_nofail(fd);
+        fd = -1;
+
+        /* Hmm, we couldn't write it? So let's write it to
+         * /run/machine-id as a replacement */
+
+        m = umask(0022);
+        r = write_one_line_file("/run/machine-id", id);
+        umask(m);
+
+        if (r < 0) {
+                log_error("Cannot write /run/machine-id: %s", strerror(-r));
+
+                unlink("/run/machine-id");
+                goto finish;
+        }
+
+        /* And now, let's mount it over */
+        r = mount("/run/machine-id", "/etc/machine-id", NULL, MS_BIND, NULL) < 0 ? -errno : 0;
+        if (r < 0) {
+                unlink("/run/machine-id");
+                log_error("Failed to mount /etc/machine-id: %s", strerror(-r));
+        } else {
+                log_info("Installed transient /etc/machine-id file.");
+
+                /* Mark the mount read-only */
+                mount(NULL, "/etc/machine-id", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL);
+        }
+
+finish:
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
diff --git a/src/core/machine-id-setup.h b/src/core/machine-id-setup.h
new file mode 100644 (file)
index 0000000..b9e6b4d
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int machine_id_setup(void);
diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in
new file mode 100644 (file)
index 0000000..647cce6
--- /dev/null
@@ -0,0 +1,73 @@
+#  -*- Mode: makefile; indent-tabs-mode: t -*- */
+#
+#  This file is part of systemd.
+#
+#  Copyright 2012 Lennart Poettering
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+# RPM macros for packages installing systemd unit files
+
+%_unitdir @systemunitdir@
+%_presetdir @systempresetdir@
+%_udevhwdbdir @udevhwdbdir@
+%_udevrulesdir @udevrulesdir@
+%_journalcatalogdir @catalogdir@
+%_tmpfilesdir @tmpfilesdir@
+%_sysctldir @sysctldir@
+
+%systemd_requires \
+Requires(post): systemd \
+Requires(preun): systemd \
+Requires(postun): systemd \
+%{nil}
+
+%systemd_post() \
+if [ $1 -eq 1 ] ; then \
+        # Initial installation \
+        @rootbindir@/systemctl preset %{?*} >/dev/null 2>&1 || : \
+fi \
+%{nil}
+
+%systemd_preun() \
+if [ $1 -eq 0 ] ; then \
+        # Package removal, not upgrade \
+        @rootbindir@/systemctl --no-reload disable %{?*} > /dev/null 2>&1 || : \
+        @rootbindir@/systemctl stop %{?*} > /dev/null 2>&1 || : \
+fi \
+%{nil}
+
+%systemd_postun() \
+@rootbindir@/systemctl daemon-reload >/dev/null 2>&1 || : \
+%{nil}
+
+%systemd_postun_with_restart() \
+@rootbindir@/systemctl daemon-reload >/dev/null 2>&1 || : \
+if [ $1 -ge 1 ] ; then \
+        # Package upgrade, not uninstall \
+        @rootbindir@/systemctl try-restart %{?*} >/dev/null 2>&1 || : \
+fi \
+%{nil}
+
+%udev_hwdb_update() \
+@bindir@/udevadm hwdb --update >/dev/null 2>&1 || : \
+%{nil}
+
+%udev_rules_update() \
+@bindir@/udevadm control --reload >/dev/null 2>&1 || : \
+%{nil}
+
+%journal_catalog_update() \
+@rootbindir@/journalctl --update-catalog >/dev/null 2>&1 || : \
+%{nil}
diff --git a/src/core/main.c b/src/core/main.c
new file mode 100644 (file)
index 0000000..1ee3c9c
--- /dev/null
@@ -0,0 +1,1959 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <getopt.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <sys/prctl.h>
+#include <sys/mount.h>
+
+#include "manager.h"
+#include "log.h"
+#include "load-fragment.h"
+#include "fdset.h"
+#include "special.h"
+#include "conf-parser.h"
+#include "bus-errors.h"
+#include "missing.h"
+#include "label.h"
+#include "build.h"
+#include "strv.h"
+#include "def.h"
+#include "virt.h"
+#include "watchdog.h"
+#include "path-util.h"
+#include "switch-root.h"
+#include "capability.h"
+#include "killall.h"
+
+#include "mount-setup.h"
+#include "loopback-setup.h"
+#ifdef HAVE_KMOD
+#include "kmod-setup.h"
+#endif
+#include "hostname-setup.h"
+#include "machine-id-setup.h"
+#include "locale-setup.h"
+#include "hwclock.h"
+#include "selinux-setup.h"
+#include "ima-setup.h"
+#include "sd-daemon.h"
+
+static enum {
+        ACTION_RUN,
+        ACTION_HELP,
+        ACTION_VERSION,
+        ACTION_TEST,
+        ACTION_DUMP_CONFIGURATION_ITEMS,
+        ACTION_DONE
+} arg_action = ACTION_RUN;
+
+static char *arg_default_unit = NULL;
+static SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID;
+
+static bool arg_dump_core = true;
+static bool arg_crash_shell = false;
+static int arg_crash_chvt = -1;
+static bool arg_confirm_spawn = false;
+static bool arg_show_status = true;
+static bool arg_switched_root = false;
+static char **arg_default_controllers = NULL;
+static char ***arg_join_controllers = NULL;
+static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
+static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
+static usec_t arg_runtime_watchdog = 0;
+static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
+static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
+static uint64_t arg_capability_bounding_set_drop = 0;
+static nsec_t arg_timer_slack_nsec = (nsec_t) -1;
+
+static FILE* serialization = NULL;
+
+static void nop_handler(int sig) {
+}
+
+_noreturn_ static void crash(int sig) {
+
+        if (!arg_dump_core)
+                log_error("Caught <%s>, not dumping core.", signal_to_string(sig));
+        else {
+                struct sigaction sa;
+                pid_t pid;
+
+                /* We want to wait for the core process, hence let's enable SIGCHLD */
+                zero(sa);
+                sa.sa_handler = nop_handler;
+                sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
+                assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
+
+                if ((pid = fork()) < 0)
+                        log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno));
+
+                else if (pid == 0) {
+                        struct rlimit rl;
+
+                        /* Enable default signal handler for core dump */
+                        zero(sa);
+                        sa.sa_handler = SIG_DFL;
+                        assert_se(sigaction(sig, &sa, NULL) == 0);
+
+                        /* Don't limit the core dump size */
+                        zero(rl);
+                        rl.rlim_cur = RLIM_INFINITY;
+                        rl.rlim_max = RLIM_INFINITY;
+                        setrlimit(RLIMIT_CORE, &rl);
+
+                        /* Just to be sure... */
+                        assert_se(chdir("/") == 0);
+
+                        /* Raise the signal again */
+                        raise(sig);
+
+                        assert_not_reached("We shouldn't be here...");
+                        _exit(1);
+
+                } else {
+                        siginfo_t status;
+                        int r;
+
+                        /* Order things nicely. */
+                        if ((r = wait_for_terminate(pid, &status)) < 0)
+                                log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r));
+                        else if (status.si_code != CLD_DUMPED)
+                                log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
+                        else
+                                log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid);
+                }
+        }
+
+        if (arg_crash_chvt)
+                chvt(arg_crash_chvt);
+
+        if (arg_crash_shell) {
+                struct sigaction sa;
+                pid_t pid;
+
+                log_info("Executing crash shell in 10s...");
+                sleep(10);
+
+                /* Let the kernel reap children for us */
+                zero(sa);
+                sa.sa_handler = SIG_IGN;
+                sa.sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART;
+                assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
+
+                pid = fork();
+                if (pid < 0)
+                        log_error("Failed to fork off crash shell: %m");
+                else if (pid == 0) {
+                        make_console_stdio();
+                        execl("/bin/sh", "/bin/sh", NULL);
+
+                        log_error("execl() failed: %m");
+                        _exit(1);
+                }
+
+                log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid);
+        }
+
+        log_info("Freezing execution.");
+        freeze();
+}
+
+static void install_crash_handler(void) {
+        struct sigaction sa;
+
+        zero(sa);
+
+        sa.sa_handler = crash;
+        sa.sa_flags = SA_NODEFER;
+
+        sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
+}
+
+static int console_setup(bool do_reset) {
+        int tty_fd, r;
+
+        /* If we are init, we connect stdin/stdout/stderr to /dev/null
+         * and make sure we don't have a controlling tty. */
+
+        release_terminal();
+
+        if (!do_reset)
+                return 0;
+
+        tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+        if (tty_fd < 0) {
+                log_error("Failed to open /dev/console: %s", strerror(-tty_fd));
+                return -tty_fd;
+        }
+
+        /* We don't want to force text mode.
+         * plymouth may be showing pictures already from initrd. */
+        r = reset_terminal_fd(tty_fd, false);
+        if (r < 0)
+                log_error("Failed to reset /dev/console: %s", strerror(-r));
+
+        close_nointr_nofail(tty_fd);
+        return r;
+}
+
+static int set_default_unit(const char *u) {
+        char *c;
+
+        assert(u);
+
+        c = strdup(u);
+        if (!c)
+                return -ENOMEM;
+
+        free(arg_default_unit);
+        arg_default_unit = c;
+
+        return 0;
+}
+
+static int parse_proc_cmdline_word(const char *word) {
+
+        static const char * const rlmap[] = {
+                "emergency", SPECIAL_EMERGENCY_TARGET,
+                "-b",        SPECIAL_EMERGENCY_TARGET,
+                "single",    SPECIAL_RESCUE_TARGET,
+                "-s",        SPECIAL_RESCUE_TARGET,
+                "s",         SPECIAL_RESCUE_TARGET,
+                "S",         SPECIAL_RESCUE_TARGET,
+                "1",         SPECIAL_RESCUE_TARGET,
+                "2",         SPECIAL_RUNLEVEL2_TARGET,
+                "3",         SPECIAL_RUNLEVEL3_TARGET,
+                "4",         SPECIAL_RUNLEVEL4_TARGET,
+                "5",         SPECIAL_RUNLEVEL5_TARGET,
+        };
+
+        assert(word);
+
+        if (startswith(word, "systemd.unit=")) {
+
+                if (!in_initrd())
+                        return set_default_unit(word + 13);
+
+        } else if (startswith(word, "rd.systemd.unit=")) {
+
+                if (in_initrd())
+                        return set_default_unit(word + 16);
+
+        } else if (startswith(word, "systemd.log_target=")) {
+
+                if (log_set_target_from_string(word + 19) < 0)
+                        log_warning("Failed to parse log target %s. Ignoring.", word + 19);
+
+        } else if (startswith(word, "systemd.log_level=")) {
+
+                if (log_set_max_level_from_string(word + 18) < 0)
+                        log_warning("Failed to parse log level %s. Ignoring.", word + 18);
+
+        } else if (startswith(word, "systemd.log_color=")) {
+
+                if (log_show_color_from_string(word + 18) < 0)
+                        log_warning("Failed to parse log color setting %s. Ignoring.", word + 18);
+
+        } else if (startswith(word, "systemd.log_location=")) {
+
+                if (log_show_location_from_string(word + 21) < 0)
+                        log_warning("Failed to parse log location setting %s. Ignoring.", word + 21);
+
+        } else if (startswith(word, "systemd.dump_core=")) {
+                int r;
+
+                if ((r = parse_boolean(word + 18)) < 0)
+                        log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18);
+                else
+                        arg_dump_core = r;
+
+        } else if (startswith(word, "systemd.crash_shell=")) {
+                int r;
+
+                if ((r = parse_boolean(word + 20)) < 0)
+                        log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20);
+                else
+                        arg_crash_shell = r;
+
+        } else if (startswith(word, "systemd.confirm_spawn=")) {
+                int r;
+
+                if ((r = parse_boolean(word + 22)) < 0)
+                        log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22);
+                else
+                        arg_confirm_spawn = r;
+
+        } else if (startswith(word, "systemd.crash_chvt=")) {
+                int k;
+
+                if (safe_atoi(word + 19, &k) < 0)
+                        log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19);
+                else
+                        arg_crash_chvt = k;
+
+        } else if (startswith(word, "systemd.show_status=")) {
+                int r;
+
+                if ((r = parse_boolean(word + 20)) < 0)
+                        log_warning("Failed to parse show status switch %s. Ignoring.", word + 20);
+                else
+                        arg_show_status = r;
+        } else if (startswith(word, "systemd.default_standard_output=")) {
+                int r;
+
+                if ((r = exec_output_from_string(word + 32)) < 0)
+                        log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32);
+                else
+                        arg_default_std_output = r;
+        } else if (startswith(word, "systemd.default_standard_error=")) {
+                int r;
+
+                if ((r = exec_output_from_string(word + 31)) < 0)
+                        log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31);
+                else
+                        arg_default_std_error = r;
+        } else if (startswith(word, "systemd.setenv=")) {
+                char *cenv, *eq;
+                int r;
+
+                cenv = strdup(word + 15);
+                if (!cenv)
+                        return -ENOMEM;
+
+                eq = strchr(cenv, '=');
+                if (!eq) {
+                        r = unsetenv(cenv);
+                        if (r < 0)
+                                log_warning("unsetenv failed %m. Ignoring.");
+                } else {
+                        *eq = 0;
+                        r = setenv(cenv, eq + 1, 1);
+                        if (r < 0)
+                                log_warning("setenv failed %m. Ignoring.");
+                }
+                free(cenv);
+
+        } else if (startswith(word, "systemd.") ||
+                   (in_initrd() && startswith(word, "rd.systemd."))) {
+
+                log_warning("Unknown kernel switch %s. Ignoring.", word);
+
+                log_info("Supported kernel switches:\n"
+                         "systemd.unit=UNIT                        Default unit to start\n"
+                         "rd.systemd.unit=UNIT                     Default unit to start when run in initrd\n"
+                         "systemd.dump_core=0|1                    Dump core on crash\n"
+                         "systemd.crash_shell=0|1                  Run shell on crash\n"
+                         "systemd.crash_chvt=N                     Change to VT #N on crash\n"
+                         "systemd.confirm_spawn=0|1                Confirm every process spawn\n"
+                         "systemd.show_status=0|1                  Show status updates on the console during bootup\n"
+                         "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
+                         "                                         Log target\n"
+                         "systemd.log_level=LEVEL                  Log level\n"
+                         "systemd.log_color=0|1                    Highlight important log messages\n"
+                         "systemd.log_location=0|1                 Include code location in log messages\n"
+                         "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
+                         "                                         Set default log output for services\n"
+                         "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
+                         "                                         Set default log error output for services\n"
+                         "systemd.setenv=ASSIGNMENT                Set an environment variable for all spawned processes\n");
+
+        } else if (streq(word, "quiet"))
+                arg_show_status = false;
+        else if (!in_initrd()) {
+                unsigned i;
+
+                /* SysV compatibility */
+                for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
+                        if (streq(word, rlmap[i]))
+                                return set_default_unit(rlmap[i+1]);
+        }
+
+        return 0;
+}
+
+static int config_parse_level2(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        log_set_max_level_from_string(rvalue);
+        return 0;
+}
+
+static int config_parse_target(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        log_set_target_from_string(rvalue);
+        return 0;
+}
+
+static int config_parse_color(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        log_show_color_from_string(rvalue);
+        return 0;
+}
+
+static int config_parse_location(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        log_show_location_from_string(rvalue);
+        return 0;
+}
+
+static int config_parse_cpu_affinity2(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char *w;
+        size_t l;
+        char *state;
+        cpu_set_t *c = NULL;
+        unsigned ncpus = 0;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                char *t;
+                int r;
+                unsigned cpu;
+
+                if (!(t = strndup(w, l)))
+                        return log_oom();
+
+                r = safe_atou(t, &cpu);
+                free(t);
+
+                if (!c)
+                        if (!(c = cpu_set_malloc(&ncpus)))
+                                return log_oom();
+
+                if (r < 0 || cpu >= ncpus) {
+                        log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue);
+                        CPU_FREE(c);
+                        return -EBADMSG;
+                }
+
+                CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
+        }
+
+        if (c) {
+                if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
+                        log_warning("Failed to set CPU affinity: %m");
+
+                CPU_FREE(c);
+        }
+
+        return 0;
+}
+
+static void strv_free_free(char ***l) {
+        char ***i;
+
+        if (!l)
+                return;
+
+        for (i = l; *i; i++)
+                strv_free(*i);
+
+        free(l);
+}
+
+static void free_join_controllers(void) {
+        if (!arg_join_controllers)
+                return;
+
+        strv_free_free(arg_join_controllers);
+        arg_join_controllers = NULL;
+}
+
+static int config_parse_join_controllers(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        unsigned n = 0;
+        char *state, *w;
+        size_t length;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        free_join_controllers();
+
+        FOREACH_WORD_QUOTED(w, length, rvalue, state) {
+                char *s, **l;
+
+                s = strndup(w, length);
+                if (!s)
+                        return log_oom();
+
+                l = strv_split(s, ",");
+                free(s);
+
+                strv_uniq(l);
+
+                if (strv_length(l) <= 1) {
+                        strv_free(l);
+                        continue;
+                }
+
+                if (!arg_join_controllers) {
+                        arg_join_controllers = new(char**, 2);
+                        if (!arg_join_controllers) {
+                                strv_free(l);
+                                return log_oom();
+                        }
+
+                        arg_join_controllers[0] = l;
+                        arg_join_controllers[1] = NULL;
+
+                        n = 1;
+                } else {
+                        char ***a;
+                        char ***t;
+
+                        t = new0(char**, n+2);
+                        if (!t) {
+                                strv_free(l);
+                                return log_oom();
+                        }
+
+                        n = 0;
+
+                        for (a = arg_join_controllers; *a; a++) {
+
+                                if (strv_overlap(*a, l)) {
+                                        char **c;
+
+                                        c = strv_merge(*a, l);
+                                        if (!c) {
+                                                strv_free(l);
+                                                strv_free_free(t);
+                                                return log_oom();
+                                        }
+
+                                        strv_free(l);
+                                        l = c;
+                                } else {
+                                        char **c;
+
+                                        c = strv_copy(*a);
+                                        if (!c) {
+                                                strv_free(l);
+                                                strv_free_free(t);
+                                                return log_oom();
+                                        }
+
+                                        t[n++] = c;
+                                }
+                        }
+
+                        t[n++] = strv_uniq(l);
+
+                        strv_free_free(arg_join_controllers);
+                        arg_join_controllers = t;
+                }
+        }
+
+        return 0;
+}
+
+static int parse_config_file(void) {
+
+        const ConfigTableItem items[] = {
+                { "Manager", "LogLevel",              config_parse_level2,       0, NULL                     },
+                { "Manager", "LogTarget",             config_parse_target,       0, NULL                     },
+                { "Manager", "LogColor",              config_parse_color,        0, NULL                     },
+                { "Manager", "LogLocation",           config_parse_location,     0, NULL                     },
+                { "Manager", "DumpCore",              config_parse_bool,         0, &arg_dump_core           },
+                { "Manager", "CrashShell",            config_parse_bool,         0, &arg_crash_shell         },
+                { "Manager", "ShowStatus",            config_parse_bool,         0, &arg_show_status         },
+                { "Manager", "CrashChVT",             config_parse_int,          0, &arg_crash_chvt          },
+                { "Manager", "CPUAffinity",           config_parse_cpu_affinity2, 0, NULL                    },
+                { "Manager", "DefaultControllers",    config_parse_strv,         0, &arg_default_controllers },
+                { "Manager", "DefaultStandardOutput", config_parse_output,       0, &arg_default_std_output  },
+                { "Manager", "DefaultStandardError",  config_parse_output,       0, &arg_default_std_error   },
+                { "Manager", "JoinControllers",       config_parse_join_controllers, 0, &arg_join_controllers },
+                { "Manager", "RuntimeWatchdogSec",    config_parse_usec,         0, &arg_runtime_watchdog    },
+                { "Manager", "ShutdownWatchdogSec",   config_parse_usec,         0, &arg_shutdown_watchdog   },
+                { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop },
+                { "Manager", "TimerSlackNSec",        config_parse_nsec,         0, &arg_timer_slack_nsec    },
+                { "Manager", "DefaultLimitCPU",       config_parse_limit,        0, &arg_default_rlimit[RLIMIT_CPU]},
+                { "Manager", "DefaultLimitFSIZE",     config_parse_limit,        0, &arg_default_rlimit[RLIMIT_FSIZE]},
+                { "Manager", "DefaultLimitDATA",      config_parse_limit,        0, &arg_default_rlimit[RLIMIT_DATA]},
+                { "Manager", "DefaultLimitSTACK",     config_parse_limit,        0, &arg_default_rlimit[RLIMIT_STACK]},
+                { "Manager", "DefaultLimitCORE",      config_parse_limit,        0, &arg_default_rlimit[RLIMIT_CORE]},
+                { "Manager", "DefaultLimitRSS",       config_parse_limit,        0, &arg_default_rlimit[RLIMIT_RSS]},
+                { "Manager", "DefaultLimitNOFILE",    config_parse_limit,        0, &arg_default_rlimit[RLIMIT_NOFILE]},
+                { "Manager", "DefaultLimitAS",        config_parse_limit,        0, &arg_default_rlimit[RLIMIT_AS]},
+                { "Manager", "DefaultLimitNPROC",     config_parse_limit,        0, &arg_default_rlimit[RLIMIT_NPROC]},
+                { "Manager", "DefaultLimitMEMLOCK",   config_parse_limit,        0, &arg_default_rlimit[RLIMIT_MEMLOCK]},
+                { "Manager", "DefaultLimitLOCKS",     config_parse_limit,        0, &arg_default_rlimit[RLIMIT_LOCKS]},
+                { "Manager", "DefaultLimitSIGPENDING",config_parse_limit,        0, &arg_default_rlimit[RLIMIT_SIGPENDING]},
+                { "Manager", "DefaultLimitMSGQUEUE",  config_parse_limit,        0, &arg_default_rlimit[RLIMIT_MSGQUEUE]},
+                { "Manager", "DefaultLimitNICE",      config_parse_limit,        0, &arg_default_rlimit[RLIMIT_NICE]},
+                { "Manager", "DefaultLimitRTPRIO",    config_parse_limit,        0, &arg_default_rlimit[RLIMIT_RTPRIO]},
+                { "Manager", "DefaultLimitRTTIME",    config_parse_limit,        0, &arg_default_rlimit[RLIMIT_RTTIME]},
+                { NULL, NULL, NULL, 0, NULL }
+        };
+
+        FILE *f;
+        const char *fn;
+        int r;
+
+        fn = arg_running_as == SYSTEMD_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE;
+        f = fopen(fn, "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_warning("Failed to open configuration file '%s': %m", fn);
+                return 0;
+        }
+
+        r = config_parse(fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, NULL);
+        if (r < 0)
+                log_warning("Failed to parse configuration file: %s", strerror(-r));
+
+        fclose(f);
+
+        return 0;
+}
+
+static int parse_proc_cmdline(void) {
+        char *line, *w, *state;
+        int r;
+        size_t l;
+
+        /* Don't read /proc/cmdline if we are in a container, since
+         * that is only relevant for the host system */
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) {
+                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                char *word;
+
+                if (!(word = strndup(w, l))) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                r = parse_proc_cmdline_word(word);
+                if (r < 0) {
+                        log_error("Failed on cmdline argument %s: %s", word, strerror(-r));
+                        free(word);
+                        goto finish;
+                }
+
+                free(word);
+        }
+
+        r = 0;
+
+finish:
+        free(line);
+        return r;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_LOG_LEVEL = 0x100,
+                ARG_LOG_TARGET,
+                ARG_LOG_COLOR,
+                ARG_LOG_LOCATION,
+                ARG_UNIT,
+                ARG_SYSTEM,
+                ARG_USER,
+                ARG_TEST,
+                ARG_VERSION,
+                ARG_DUMP_CONFIGURATION_ITEMS,
+                ARG_DUMP_CORE,
+                ARG_CRASH_SHELL,
+                ARG_CONFIRM_SPAWN,
+                ARG_SHOW_STATUS,
+                ARG_DESERIALIZE,
+                ARG_SWITCHED_ROOT,
+                ARG_INTROSPECT,
+                ARG_DEFAULT_STD_OUTPUT,
+                ARG_DEFAULT_STD_ERROR
+        };
+
+        static const struct option options[] = {
+                { "log-level",                required_argument, NULL, ARG_LOG_LEVEL                },
+                { "log-target",               required_argument, NULL, ARG_LOG_TARGET               },
+                { "log-color",                optional_argument, NULL, ARG_LOG_COLOR                },
+                { "log-location",             optional_argument, NULL, ARG_LOG_LOCATION             },
+                { "unit",                     required_argument, NULL, ARG_UNIT                     },
+                { "system",                   no_argument,       NULL, ARG_SYSTEM                   },
+                { "user",                     no_argument,       NULL, ARG_USER                     },
+                { "test",                     no_argument,       NULL, ARG_TEST                     },
+                { "help",                     no_argument,       NULL, 'h'                          },
+                { "version",                  no_argument,       NULL, ARG_VERSION                  },
+                { "dump-configuration-items", no_argument,       NULL, ARG_DUMP_CONFIGURATION_ITEMS },
+                { "dump-core",                optional_argument, NULL, ARG_DUMP_CORE                },
+                { "crash-shell",              optional_argument, NULL, ARG_CRASH_SHELL              },
+                { "confirm-spawn",            optional_argument, NULL, ARG_CONFIRM_SPAWN            },
+                { "show-status",              optional_argument, NULL, ARG_SHOW_STATUS              },
+                { "deserialize",              required_argument, NULL, ARG_DESERIALIZE              },
+                { "switched-root",            no_argument,       NULL, ARG_SWITCHED_ROOT            },
+                { "introspect",               optional_argument, NULL, ARG_INTROSPECT               },
+                { "default-standard-output",  required_argument, NULL, ARG_DEFAULT_STD_OUTPUT,      },
+                { "default-standard-error",   required_argument, NULL, ARG_DEFAULT_STD_ERROR,       },
+                { NULL,                       0,                 NULL, 0                            }
+        };
+
+        int c, r;
+
+        assert(argc >= 1);
+        assert(argv);
+
+        if (getpid() == 1)
+                opterr = 0;
+
+        while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
+
+                switch (c) {
+
+                case ARG_LOG_LEVEL:
+                        if ((r = log_set_max_level_from_string(optarg)) < 0) {
+                                log_error("Failed to parse log level %s.", optarg);
+                                return r;
+                        }
+
+                        break;
+
+                case ARG_LOG_TARGET:
+
+                        if ((r = log_set_target_from_string(optarg)) < 0) {
+                                log_error("Failed to parse log target %s.", optarg);
+                                return r;
+                        }
+
+                        break;
+
+                case ARG_LOG_COLOR:
+
+                        if (optarg) {
+                                if ((r = log_show_color_from_string(optarg)) < 0) {
+                                        log_error("Failed to parse log color setting %s.", optarg);
+                                        return r;
+                                }
+                        } else
+                                log_show_color(true);
+
+                        break;
+
+                case ARG_LOG_LOCATION:
+
+                        if (optarg) {
+                                if ((r = log_show_location_from_string(optarg)) < 0) {
+                                        log_error("Failed to parse log location setting %s.", optarg);
+                                        return r;
+                                }
+                        } else
+                                log_show_location(true);
+
+                        break;
+
+                case ARG_DEFAULT_STD_OUTPUT:
+
+                        if ((r = exec_output_from_string(optarg)) < 0) {
+                                log_error("Failed to parse default standard output setting %s.", optarg);
+                                return r;
+                        } else
+                                arg_default_std_output = r;
+                        break;
+
+                case ARG_DEFAULT_STD_ERROR:
+
+                        if ((r = exec_output_from_string(optarg)) < 0) {
+                                log_error("Failed to parse default standard error output setting %s.", optarg);
+                                return r;
+                        } else
+                                arg_default_std_error = r;
+                        break;
+
+                case ARG_UNIT:
+
+                        if ((r = set_default_unit(optarg)) < 0) {
+                                log_error("Failed to set default unit %s: %s", optarg, strerror(-r));
+                                return r;
+                        }
+
+                        break;
+
+                case ARG_SYSTEM:
+                        arg_running_as = SYSTEMD_SYSTEM;
+                        break;
+
+                case ARG_USER:
+                        arg_running_as = SYSTEMD_USER;
+                        break;
+
+                case ARG_TEST:
+                        arg_action = ACTION_TEST;
+                        break;
+
+                case ARG_VERSION:
+                        arg_action = ACTION_VERSION;
+                        break;
+
+                case ARG_DUMP_CONFIGURATION_ITEMS:
+                        arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
+                        break;
+
+                case ARG_DUMP_CORE:
+                        r = optarg ? parse_boolean(optarg) : 1;
+                        if (r < 0) {
+                                log_error("Failed to parse dump core boolean %s.", optarg);
+                                return r;
+                        }
+                        arg_dump_core = r;
+                        break;
+
+                case ARG_CRASH_SHELL:
+                        r = optarg ? parse_boolean(optarg) : 1;
+                        if (r < 0) {
+                                log_error("Failed to parse crash shell boolean %s.", optarg);
+                                return r;
+                        }
+                        arg_crash_shell = r;
+                        break;
+
+                case ARG_CONFIRM_SPAWN:
+                        r = optarg ? parse_boolean(optarg) : 1;
+                        if (r < 0) {
+                                log_error("Failed to parse confirm spawn boolean %s.", optarg);
+                                return r;
+                        }
+                        arg_confirm_spawn = r;
+                        break;
+
+                case ARG_SHOW_STATUS:
+                        r = optarg ? parse_boolean(optarg) : 1;
+                        if (r < 0) {
+                                log_error("Failed to parse show status boolean %s.", optarg);
+                                return r;
+                        }
+                        arg_show_status = r;
+                        break;
+
+                case ARG_DESERIALIZE: {
+                        int fd;
+                        FILE *f;
+
+                        r = safe_atoi(optarg, &fd);
+                        if (r < 0 || fd < 0) {
+                                log_error("Failed to parse deserialize option %s.", optarg);
+                                return r < 0 ? r : -EINVAL;
+                        }
+
+                        fd_cloexec(fd, true);
+
+                        f = fdopen(fd, "r");
+                        if (!f) {
+                                log_error("Failed to open serialization fd: %m");
+                                return -errno;
+                        }
+
+                        if (serialization)
+                                fclose(serialization);
+
+                        serialization = f;
+
+                        break;
+                }
+
+                case ARG_SWITCHED_ROOT:
+                        arg_switched_root = true;
+                        break;
+
+                case ARG_INTROSPECT: {
+                        const char * const * i = NULL;
+
+                        for (i = bus_interface_table; *i; i += 2)
+                                if (!optarg || streq(i[0], optarg)) {
+                                        fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+                                              "<node>\n", stdout);
+                                        fputs(i[1], stdout);
+                                        fputs("</node>\n", stdout);
+
+                                        if (optarg)
+                                                break;
+                                }
+
+                        if (!i[0] && optarg)
+                                log_error("Unknown interface %s.", optarg);
+
+                        arg_action = ACTION_DONE;
+                        break;
+                }
+
+                case 'h':
+                        arg_action = ACTION_HELP;
+                        break;
+
+                case 'D':
+                        log_set_max_level(LOG_DEBUG);
+                        break;
+
+                case 'b':
+                case 's':
+                case 'z':
+                        /* Just to eat away the sysvinit kernel
+                         * cmdline args without getopt() error
+                         * messages that we'll parse in
+                         * parse_proc_cmdline_word() or ignore. */
+
+                case '?':
+                default:
+                        if (getpid() != 1) {
+                                log_error("Unknown option code %c", c);
+                                return -EINVAL;
+                        }
+
+                        break;
+                }
+
+        if (optind < argc && getpid() != 1) {
+                /* Hmm, when we aren't run as init system
+                 * let's complain about excess arguments */
+
+                log_error("Excess arguments.");
+                return -EINVAL;
+        }
+
+        if (detect_container(NULL) > 0) {
+                char **a;
+
+                /* All /proc/cmdline arguments the kernel didn't
+                 * understand it passed to us. We're not really
+                 * interested in that usually since /proc/cmdline is
+                 * more interesting and complete. With one exception:
+                 * if we are run in a container /proc/cmdline is not
+                 * relevant for the container, hence we rely on argv[]
+                 * instead. */
+
+                for (a = argv; a < argv + argc; a++)
+                        if ((r = parse_proc_cmdline_word(*a)) < 0) {
+                                log_error("Failed on cmdline argument %s: %s", *a, strerror(-r));
+                                return r;
+                        }
+        }
+
+        return 0;
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...]\n\n"
+               "Starts up and maintains the system or user services.\n\n"
+               "  -h --help                      Show this help\n"
+               "     --test                      Determine startup sequence, dump it and exit\n"
+               "     --dump-configuration-items  Dump understood unit configuration items\n"
+               "     --introspect[=INTERFACE]    Extract D-Bus interface data\n"
+               "     --unit=UNIT                 Set default unit\n"
+               "     --system                    Run a system instance, even if PID != 1\n"
+               "     --user                      Run a user instance\n"
+               "     --dump-core[=0|1]           Dump core on crash\n"
+               "     --crash-shell[=0|1]         Run shell on crash\n"
+               "     --confirm-spawn[=0|1]       Ask for confirmation when spawning processes\n"
+               "     --show-status[=0|1]         Show status updates on the console during bootup\n"
+               "     --log-target=TARGET         Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
+               "     --log-level=LEVEL           Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
+               "     --log-color[=0|1]           Highlight important log messages\n"
+               "     --log-location[=0|1]        Include code location in log messages\n"
+               "     --default-standard-output=  Set default standard output for services\n"
+               "     --default-standard-error=   Set default standard error output for services\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int version(void) {
+        puts(PACKAGE_STRING);
+        puts(SYSTEMD_FEATURES);
+
+        return 0;
+}
+
+static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool serialize_jobs) {
+        FILE *f = NULL;
+        FDSet *fds = NULL;
+        int r;
+
+        assert(m);
+        assert(_f);
+        assert(_fds);
+
+        /* Make sure nothing is really destructed when we shut down */
+        m->n_reloading ++;
+
+        r = manager_open_serialization(m, &f);
+        if (r < 0) {
+                log_error("Failed to create serialization file: %s", strerror(-r));
+                goto fail;
+        }
+
+        fds = fdset_new();
+        if (!fds) {
+                r = -ENOMEM;
+                log_error("Failed to allocate fd set: %s", strerror(-r));
+                goto fail;
+        }
+
+        r = manager_serialize(m, f, fds, serialize_jobs);
+        if (r < 0) {
+                log_error("Failed to serialize state: %s", strerror(-r));
+                goto fail;
+        }
+
+        if (fseeko(f, 0, SEEK_SET) < 0) {
+                log_error("Failed to rewind serialization fd: %m");
+                goto fail;
+        }
+
+        r = fd_cloexec(fileno(f), false);
+        if (r < 0) {
+                log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r));
+                goto fail;
+        }
+
+        r = fdset_cloexec(fds, false);
+        if (r < 0) {
+                log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r));
+                goto fail;
+        }
+
+        *_f = f;
+        *_fds = fds;
+
+        return 0;
+
+fail:
+        fdset_free(fds);
+
+        if (f)
+                fclose(f);
+
+        return r;
+}
+
+static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
+        struct rlimit nl;
+        int r;
+
+        assert(saved_rlimit);
+
+        /* Save the original RLIMIT_NOFILE so that we can reset it
+         * later when transitioning from the initrd to the main
+         * systemd or suchlike. */
+        if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) {
+                log_error("Reading RLIMIT_NOFILE failed: %m");
+                return -errno;
+        }
+
+        /* Make sure forked processes get the default kernel setting */
+        if (!arg_default_rlimit[RLIMIT_NOFILE]) {
+                struct rlimit *rl;
+
+                rl = newdup(struct rlimit, saved_rlimit, 1);
+                if (!rl)
+                        return log_oom();
+
+                arg_default_rlimit[RLIMIT_NOFILE] = rl;
+        }
+
+        /* Bump up the resource limit for ourselves substantially */
+        nl.rlim_cur = nl.rlim_max = 64*1024;
+        r = setrlimit_closest(RLIMIT_NOFILE, &nl);
+        if (r < 0) {
+                log_error("Setting RLIMIT_NOFILE failed: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
+        const char *e;
+        unsigned long long a, b;
+
+        assert(t);
+
+        e = getenv("RD_TIMESTAMP");
+        if (!e)
+                return NULL;
+
+        if (sscanf(e, "%llu %llu", &a, &b) != 2)
+                return NULL;
+
+        t->realtime = (usec_t) a;
+        t->monotonic = (usec_t) b;
+
+        return t;
+}
+
+static void test_mtab(void) {
+        char *p;
+
+        /* Check that /etc/mtab is a symlink */
+
+        if (readlink_malloc("/etc/mtab", &p) >= 0) {
+                bool b;
+
+                b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts");
+                free(p);
+
+                if (b)
+                        return;
+        }
+
+        log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
+                    "This is not supported anymore. "
+                    "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
+}
+
+static void test_usr(void) {
+
+        /* Check that /usr is not a separate fs */
+
+        if (dir_is_empty("/usr") <= 0)
+                return;
+
+        log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. "
+                    "Some things will probably break (sometimes even silently) in mysterious ways. "
+                    "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
+}
+
+static void test_cgroups(void) {
+
+        if (access("/proc/cgroups", F_OK) >= 0)
+                return;
+
+        log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. "
+                    "Systems without control groups are not supported. "
+                    "We will now sleep for 10s, and then continue boot-up. "
+                    "Expect breakage and please do not file bugs. "
+                    "Instead fix your kernel and enable CONFIG_CGROUPS. "
+                    "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
+
+        sleep(10);
+}
+
+static int initialize_join_controllers(void) {
+        /* By default, mount "cpu" + "cpuacct" together, and "net_cls"
+         * + "net_prio". We'd like to add "cpuset" to the mix, but
+         * "cpuset" does't really work for groups with no initialized
+         * attributes. */
+
+        arg_join_controllers = new(char**, 3);
+        if (!arg_join_controllers)
+                return -ENOMEM;
+
+        arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
+        if (!arg_join_controllers[0])
+                return -ENOMEM;
+
+        arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
+        if (!arg_join_controllers[1])
+                return -ENOMEM;
+
+        arg_join_controllers[2] = NULL;
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        Manager *m = NULL;
+        int r, retval = EXIT_FAILURE;
+        usec_t before_startup, after_startup;
+        char timespan[FORMAT_TIMESPAN_MAX];
+        FDSet *fds = NULL;
+        bool reexecute = false;
+        const char *shutdown_verb = NULL;
+        dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
+        static char systemd[] = "systemd";
+        bool skip_setup = false;
+        int j;
+        bool loaded_policy = false;
+        bool arm_reboot_watchdog = false;
+        bool queue_default_job = false;
+        char *switch_root_dir = NULL, *switch_root_init = NULL;
+        static struct rlimit saved_rlimit_nofile = { 0, 0 };
+
+#ifdef HAVE_SYSV_COMPAT
+        if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
+                /* This is compatibility support for SysV, where
+                 * calling init as a user is identical to telinit. */
+
+                errno = -ENOENT;
+                execv(SYSTEMCTL_BINARY_PATH, argv);
+                log_error("Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
+                return 1;
+        }
+#endif
+
+        /* Determine if this is a reexecution or normal bootup. We do
+         * the full command line parsing much later, so let's just
+         * have a quick peek here. */
+        for (j = 1; j < argc; j++)
+                if (streq(argv[j], "--deserialize")) {
+                        skip_setup = true;
+                        break;
+                }
+
+        /* If we have switched root, do all the special setup
+         * things */
+        for (j = 1; j < argc; j++)
+                if (streq(argv[j], "--switched-root")) {
+                        skip_setup = false;
+                        break;
+                }
+
+        /* If we get started via the /sbin/init symlink then we are
+           called 'init'. After a subsequent reexecution we are then
+           called 'systemd'. That is confusing, hence let's call us
+           systemd right-away. */
+        program_invocation_short_name = systemd;
+        prctl(PR_SET_NAME, systemd);
+
+        saved_argv = argv;
+        saved_argc = argc;
+
+        log_show_color(isatty(STDERR_FILENO) > 0);
+
+        if (getpid() == 1 && detect_container(NULL) <= 0) {
+
+                /* Running outside of a container as PID 1 */
+                arg_running_as = SYSTEMD_SYSTEM;
+                make_null_stdio();
+                log_set_target(LOG_TARGET_KMSG);
+                log_open();
+
+                if (in_initrd()) {
+                        char *rd_timestamp = NULL;
+
+                        dual_timestamp_get(&initrd_timestamp);
+                        asprintf(&rd_timestamp, "%llu %llu",
+                                 (unsigned long long) initrd_timestamp.realtime,
+                                 (unsigned long long) initrd_timestamp.monotonic);
+                        if (rd_timestamp) {
+                                setenv("RD_TIMESTAMP", rd_timestamp, 1);
+                                free(rd_timestamp);
+                        }
+                }
+
+                if (!skip_setup) {
+                        if (selinux_setup(&loaded_policy) < 0)
+                                goto finish;
+                        if (ima_setup() < 0)
+                                goto finish;
+                }
+
+                if (label_init(NULL) < 0)
+                        goto finish;
+
+                if (!skip_setup) {
+                        if (hwclock_is_localtime() > 0) {
+                                int min;
+
+                                /* The first-time call to settimeofday() does a time warp in the kernel */
+                                r = hwclock_set_timezone(&min);
+                                if (r < 0)
+                                        log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
+                                else
+                                        log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
+                        } else if (!in_initrd()) {
+                                /*
+                                 * Do dummy first-time call to seal the kernel's time warp magic
+                                 *
+                                 * Do not call this this from inside the initrd. The initrd might not
+                                 * carry /etc/adjtime with LOCAL, but the real system could be set up
+                                 * that way. In such case, we need to delay the time-warp or the sealing
+                                 * until we reach the real system.
+                                 */
+                                hwclock_reset_timezone();
+
+                                /* Tell the kernel our time zone */
+                                r = hwclock_set_timezone(NULL);
+                                if (r < 0)
+                                        log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r));
+                        }
+                }
+
+                /* Set the default for later on, but don't actually
+                 * open the logs like this for now. Note that if we
+                 * are transitioning from the initrd there might still
+                 * be journal fd open, and we shouldn't attempt
+                 * opening that before we parsed /proc/cmdline which
+                 * might redirect output elsewhere. */
+                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+
+        } else if (getpid() == 1) {
+
+                /* Running inside a container, as PID 1 */
+                arg_running_as = SYSTEMD_SYSTEM;
+                log_set_target(LOG_TARGET_CONSOLE);
+                log_open();
+
+                /* For the later on, see above... */
+                log_set_target(LOG_TARGET_JOURNAL);
+
+        } else {
+
+                /* Running as user instance */
+                arg_running_as = SYSTEMD_USER;
+                log_set_target(LOG_TARGET_AUTO);
+                log_open();
+        }
+
+        /* Initialize default unit */
+        r = set_default_unit(SPECIAL_DEFAULT_TARGET);
+        if (r < 0) {
+                log_error("Failed to set default unit %s: %s", SPECIAL_DEFAULT_TARGET, strerror(-r));
+                goto finish;
+        }
+
+        r = initialize_join_controllers();
+        if (r < 0)
+                goto finish;
+
+        /* Mount /proc, /sys and friends, so that /proc/cmdline and
+         * /proc/$PID/fd is available. */
+        if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
+                r = mount_setup(loaded_policy);
+                if (r < 0)
+                        goto finish;
+        }
+
+        /* Reset all signal handlers. */
+        assert_se(reset_all_signal_handlers() == 0);
+
+        /* If we are init, we can block sigkill. Yay. */
+        ignore_signals(SIGNALS_IGNORE, -1);
+
+        if (parse_config_file() < 0)
+                goto finish;
+
+        if (arg_running_as == SYSTEMD_SYSTEM)
+                if (parse_proc_cmdline() < 0)
+                        goto finish;
+
+        log_parse_environment();
+
+        if (parse_argv(argc, argv) < 0)
+                goto finish;
+
+        if (arg_action == ACTION_TEST &&
+            geteuid() == 0) {
+                log_error("Don't run test mode as root.");
+                goto finish;
+        }
+
+        if (arg_running_as == SYSTEMD_USER &&
+            arg_action == ACTION_RUN &&
+            sd_booted() <= 0) {
+                log_error("Trying to run as user instance, but the system has not been booted with systemd.");
+                goto finish;
+        }
+
+        if (arg_running_as == SYSTEMD_SYSTEM &&
+            arg_action == ACTION_RUN &&
+            running_in_chroot() > 0) {
+                log_error("Cannot be run in a chroot() environment.");
+                goto finish;
+        }
+
+        if (arg_action == ACTION_HELP) {
+                retval = help();
+                goto finish;
+        } else if (arg_action == ACTION_VERSION) {
+                retval = version();
+                goto finish;
+        } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) {
+                unit_dump_config_items(stdout);
+                retval = EXIT_SUCCESS;
+                goto finish;
+        } else if (arg_action == ACTION_DONE) {
+                retval = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST);
+
+        /* Close logging fds, in order not to confuse fdset below */
+        log_close();
+
+        /* Remember open file descriptors for later deserialization */
+        r = fdset_new_fill(&fds);
+        if (r < 0) {
+                log_error("Failed to allocate fd set: %s", strerror(-r));
+                goto finish;
+        } else
+                fdset_cloexec(fds, true);
+
+        if (serialization)
+                assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
+
+        /* Set up PATH unless it is already set */
+        setenv("PATH",
+#ifdef HAVE_SPLIT_USR
+               "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+#else
+               "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
+#endif
+               arg_running_as == SYSTEMD_SYSTEM);
+
+        if (arg_running_as == SYSTEMD_SYSTEM) {
+                /* Parse the data passed to us. We leave this
+                 * variables set, but the manager later on will not
+                 * pass them on to our children. */
+                if (!in_initrd())
+                        parse_initrd_timestamp(&initrd_timestamp);
+
+                /* Unset some environment variables passed in from the
+                 * kernel that don't really make sense for us. */
+                unsetenv("HOME");
+                unsetenv("TERM");
+
+                /* When we are invoked by a shell, these might be set,
+                 * but make little sense to pass on */
+                unsetenv("PWD");
+                unsetenv("SHLVL");
+                unsetenv("_");
+
+                /* When we are invoked by a chroot-like tool such as
+                 * nspawn, these might be set, but make little sense
+                 * to pass on */
+                unsetenv("USER");
+                unsetenv("LOGNAME");
+
+                /* We suppress the socket activation env vars, as
+                 * we'll try to match *any* open fd to units if
+                 * possible. */
+                unsetenv("LISTEN_FDS");
+                unsetenv("LISTEN_PID");
+
+                /* All other variables are left as is, so that clients
+                 * can still read them via /proc/1/environ */
+        }
+
+        /* Move out of the way, so that we won't block unmounts */
+        assert_se(chdir("/")  == 0);
+
+        if (arg_running_as == SYSTEMD_SYSTEM) {
+                /* Become a session leader if we aren't one yet. */
+                setsid();
+
+                /* Disable the umask logic */
+                umask(0);
+        }
+
+        /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
+        dbus_connection_set_change_sigpipe(FALSE);
+
+        /* Reset the console, but only if this is really init and we
+         * are freshly booted */
+        if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN)
+                console_setup(getpid() == 1 && !skip_setup);
+
+        /* Open the logging devices, if possible and necessary */
+        log_open();
+
+        /* Make sure we leave a core dump without panicing the
+         * kernel. */
+        if (getpid() == 1)
+                install_crash_handler();
+
+        if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
+                r = mount_cgroup_controllers(arg_join_controllers);
+                if (r < 0)
+                        goto finish;
+        }
+
+        if (arg_running_as == SYSTEMD_SYSTEM) {
+                const char *virtualization = NULL;
+
+                log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES ")");
+
+                detect_virtualization(&virtualization);
+                if (virtualization)
+                        log_info("Detected virtualization '%s'.", virtualization);
+
+                if (in_initrd())
+                        log_info("Running in initial RAM disk.");
+
+        } else
+                log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")");
+
+        if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
+                locale_setup();
+
+                if (arg_show_status || plymouth_running())
+                        status_welcome();
+
+#ifdef HAVE_KMOD
+                kmod_setup();
+#endif
+                hostname_setup();
+                machine_id_setup();
+                loopback_setup();
+
+                test_mtab();
+                test_usr();
+                test_cgroups();
+        }
+
+        if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0)
+                watchdog_set_timeout(&arg_runtime_watchdog);
+
+        if (arg_timer_slack_nsec != (nsec_t) -1)
+                if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
+                        log_error("Failed to adjust timer slack: %m");
+
+        if (arg_capability_bounding_set_drop) {
+                r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true);
+                if (r < 0) {
+                        log_error("Failed to drop capability bounding set: %s", strerror(-r));
+                        goto finish;
+                }
+                r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop);
+                if (r < 0) {
+                        log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r));
+                        goto finish;
+                }
+        }
+
+        if (arg_running_as == SYSTEMD_USER) {
+                /* Become reaper of our children */
+                if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) {
+                        log_warning("Failed to make us a subreaper: %m");
+                        if (errno == EINVAL)
+                                log_info("Perhaps the kernel version is too old (< 3.4?)");
+                }
+        }
+
+        if (arg_running_as == SYSTEMD_SYSTEM)
+                bump_rlimit_nofile(&saved_rlimit_nofile);
+
+        r = manager_new(arg_running_as, &m);
+        if (r < 0) {
+                log_error("Failed to allocate manager object: %s", strerror(-r));
+                goto finish;
+        }
+
+        m->confirm_spawn = arg_confirm_spawn;
+        m->default_std_output = arg_default_std_output;
+        m->default_std_error = arg_default_std_error;
+        m->runtime_watchdog = arg_runtime_watchdog;
+        m->shutdown_watchdog = arg_shutdown_watchdog;
+
+        manager_set_default_rlimits(m, arg_default_rlimit);
+
+        if (dual_timestamp_is_set(&initrd_timestamp))
+                m->initrd_timestamp = initrd_timestamp;
+
+        if (arg_default_controllers)
+                manager_set_default_controllers(m, arg_default_controllers);
+
+        manager_set_show_status(m, arg_show_status);
+
+        /* Remember whether we should queue the default job */
+        queue_default_job = !serialization || arg_switched_root;
+
+        before_startup = now(CLOCK_MONOTONIC);
+
+        r = manager_startup(m, serialization, fds);
+        if (r < 0)
+                log_error("Failed to fully start up daemon: %s", strerror(-r));
+
+        /* This will close all file descriptors that were opened, but
+         * not claimed by any unit. */
+        fdset_free(fds);
+
+        if (serialization) {
+                fclose(serialization);
+                serialization = NULL;
+        }
+
+        if (queue_default_job) {
+                DBusError error;
+                Unit *target = NULL;
+                Job *default_unit_job;
+
+                dbus_error_init(&error);
+
+                log_debug("Activating default unit: %s", arg_default_unit);
+
+                r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
+                if (r < 0) {
+                        log_error("Failed to load default target: %s", bus_error(&error, r));
+                        dbus_error_free(&error);
+                } else if (target->load_state == UNIT_ERROR)
+                        log_error("Failed to load default target: %s", strerror(-target->load_error));
+                else if (target->load_state == UNIT_MASKED)
+                        log_error("Default target masked.");
+
+                if (!target || target->load_state != UNIT_LOADED) {
+                        log_info("Trying to load rescue target...");
+
+                        r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
+                        if (r < 0) {
+                                log_error("Failed to load rescue target: %s", bus_error(&error, r));
+                                dbus_error_free(&error);
+                                goto finish;
+                        } else if (target->load_state == UNIT_ERROR) {
+                                log_error("Failed to load rescue target: %s", strerror(-target->load_error));
+                                goto finish;
+                        } else if (target->load_state == UNIT_MASKED) {
+                                log_error("Rescue target masked.");
+                                goto finish;
+                        }
+                }
+
+                assert(target->load_state == UNIT_LOADED);
+
+                if (arg_action == ACTION_TEST) {
+                        printf("-> By units:\n");
+                        manager_dump_units(m, stdout, "\t");
+                }
+
+                r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job);
+                if (r < 0) {
+                        log_error("Failed to start default target: %s", bus_error(&error, r));
+                        dbus_error_free(&error);
+                        goto finish;
+                }
+                m->default_unit_job_id = default_unit_job->id;
+
+                after_startup = now(CLOCK_MONOTONIC);
+                log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
+                         "Loaded units and determined initial transaction in %s.",
+                          format_timespan(timespan, sizeof(timespan), after_startup - before_startup));
+
+                if (arg_action == ACTION_TEST) {
+                        printf("-> By jobs:\n");
+                        manager_dump_jobs(m, stdout, "\t");
+                        retval = EXIT_SUCCESS;
+                        goto finish;
+                }
+        }
+
+        for (;;) {
+                r = manager_loop(m);
+                if (r < 0) {
+                        log_error("Failed to run mainloop: %s", strerror(-r));
+                        goto finish;
+                }
+
+                switch (m->exit_code) {
+
+                case MANAGER_EXIT:
+                        retval = EXIT_SUCCESS;
+                        log_debug("Exit.");
+                        goto finish;
+
+                case MANAGER_RELOAD:
+                        log_info("Reloading.");
+                        r = manager_reload(m);
+                        if (r < 0)
+                                log_error("Failed to reload: %s", strerror(-r));
+                        break;
+
+                case MANAGER_REEXECUTE:
+
+                        if (prepare_reexecute(m, &serialization, &fds, true) < 0)
+                                goto finish;
+
+                        reexecute = true;
+                        log_notice("Reexecuting.");
+                        goto finish;
+
+                case MANAGER_SWITCH_ROOT:
+                        /* Steal the switch root parameters */
+                        switch_root_dir = m->switch_root;
+                        switch_root_init = m->switch_root_init;
+                        m->switch_root = m->switch_root_init = NULL;
+
+                        if (!switch_root_init)
+                                if (prepare_reexecute(m, &serialization, &fds, false) < 0)
+                                        goto finish;
+
+                        reexecute = true;
+                        log_notice("Switching root.");
+                        goto finish;
+
+                case MANAGER_REBOOT:
+                case MANAGER_POWEROFF:
+                case MANAGER_HALT:
+                case MANAGER_KEXEC: {
+                        static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
+                                [MANAGER_REBOOT] = "reboot",
+                                [MANAGER_POWEROFF] = "poweroff",
+                                [MANAGER_HALT] = "halt",
+                                [MANAGER_KEXEC] = "kexec"
+                        };
+
+                        assert_se(shutdown_verb = table[m->exit_code]);
+                        arm_reboot_watchdog = m->exit_code == MANAGER_REBOOT;
+
+                        log_notice("Shutting down.");
+                        goto finish;
+                }
+
+                default:
+                        assert_not_reached("Unknown exit code.");
+                }
+        }
+
+finish:
+        if (m)
+                manager_free(m);
+
+        for (j = 0; j < RLIMIT_NLIMITS; j++)
+                free(arg_default_rlimit[j]);
+
+        free(arg_default_unit);
+        strv_free(arg_default_controllers);
+        free_join_controllers();
+
+        dbus_shutdown();
+        label_finish();
+
+        if (reexecute) {
+                const char **args;
+                unsigned i, args_size;
+
+                /* Close and disarm the watchdog, so that the new
+                 * instance can reinitialize it, but doesn't get
+                 * rebooted while we do that */
+                watchdog_close(true);
+
+                /* Reset the RLIMIT_NOFILE to the kernel default, so
+                 * that the new systemd can pass the kernel default to
+                 * its child processes */
+                if (saved_rlimit_nofile.rlim_cur > 0)
+                        setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
+
+                if (switch_root_dir) {
+                        /* Kill all remaining processes from the
+                         * initrd, but don't wait for them, so that we
+                         * can handle the SIGCHLD for them after
+                         * deserializing. */
+                        broadcast_signal(SIGTERM, false);
+
+                        /* And switch root */
+                        r = switch_root(switch_root_dir);
+                        if (r < 0)
+                                log_error("Failed to switch root, ignoring: %s", strerror(-r));
+                }
+
+                args_size = MAX(6, argc+1);
+                args = newa(const char*, args_size);
+
+                if (!switch_root_init) {
+                        char sfd[16];
+
+                        /* First try to spawn ourselves with the right
+                         * path, and with full serialization. We do
+                         * this only if the user didn't specify an
+                         * explicit init to spawn. */
+
+                        assert(serialization);
+                        assert(fds);
+
+                        snprintf(sfd, sizeof(sfd), "%i", fileno(serialization));
+                        char_array_0(sfd);
+
+                        i = 0;
+                        args[i++] = SYSTEMD_BINARY_PATH;
+                        if (switch_root_dir)
+                                args[i++] = "--switched-root";
+                        args[i++] = arg_running_as == SYSTEMD_SYSTEM ? "--system" : "--user";
+                        args[i++] = "--deserialize";
+                        args[i++] = sfd;
+                        args[i++] = NULL;
+
+                        assert(i <= args_size);
+                        execv(args[0], (char* const*) args);
+                }
+
+                /* Try the fallback, if there is any, without any
+                 * serialization. We pass the original argv[] and
+                 * envp[]. (Well, modulo the ordering changes due to
+                 * getopt() in argv[], and some cleanups in envp[],
+                 * but let's hope that doesn't matter.) */
+
+                if (serialization) {
+                        fclose(serialization);
+                        serialization = NULL;
+                }
+
+                if (fds) {
+                        fdset_free(fds);
+                        fds = NULL;
+                }
+
+                /* Reopen the console */
+                make_console_stdio();
+
+                for (j = 1, i = 1; j < argc; j++)
+                        args[i++] = argv[j];
+                args[i++] = NULL;
+                assert(i <= args_size);
+
+                if (switch_root_init) {
+                        args[0] = switch_root_init;
+                        execv(args[0], (char* const*) args);
+                        log_warning("Failed to execute configured init, trying fallback: %m");
+                }
+
+                args[0] = "/sbin/init";
+                execv(args[0], (char* const*) args);
+
+                if (errno == ENOENT) {
+                        log_warning("No /sbin/init, trying fallback");
+
+                        args[0] = "/bin/sh";
+                        args[1] = NULL;
+                        execv(args[0], (char* const*) args);
+                        log_error("Failed to execute /bin/sh, giving up: %m");
+                } else
+                        log_warning("Failed to execute /sbin/init, giving up: %m");
+        }
+
+        if (serialization)
+                fclose(serialization);
+
+        if (fds)
+                fdset_free(fds);
+
+        if (shutdown_verb) {
+                const char * command_line[] = {
+                        SYSTEMD_SHUTDOWN_BINARY_PATH,
+                        shutdown_verb,
+                        NULL
+                };
+                char **env_block;
+
+                if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
+                        char e[32];
+
+                        /* If we reboot let's set the shutdown
+                         * watchdog and tell the shutdown binary to
+                         * repeatedly ping it */
+                        watchdog_set_timeout(&arg_shutdown_watchdog);
+                        watchdog_close(false);
+
+                        /* Tell the binary how often to ping */
+                        snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog);
+                        char_array_0(e);
+
+                        env_block = strv_append(environ, e);
+                } else {
+                        env_block = strv_copy(environ);
+                        watchdog_close(true);
+                }
+
+                execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
+                free(env_block);
+                log_error("Failed to execute shutdown binary, freezing: %m");
+        }
+
+        if (getpid() == 1)
+                freeze();
+
+        return retval;
+}
diff --git a/src/core/manager.c b/src/core/manager.c
new file mode 100644 (file)
index 0000000..3a4023f
--- /dev/null
@@ -0,0 +1,2461 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <signal.h>
+#include <sys/signalfd.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <sys/reboot.h>
+#include <sys/ioctl.h>
+#include <linux/kd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <sys/timerfd.h>
+
+#ifdef HAVE_AUDIT
+#include <libaudit.h>
+#endif
+
+#include "systemd/sd-daemon.h"
+#include "systemd/sd-id128.h"
+#include "systemd/sd-messages.h"
+
+#include "manager.h"
+#include "transaction.h"
+#include "hashmap.h"
+#include "macro.h"
+#include "strv.h"
+#include "log.h"
+#include "util.h"
+#include "mkdir.h"
+#include "ratelimit.h"
+#include "cgroup.h"
+#include "mount-setup.h"
+#include "unit-name.h"
+#include "dbus-unit.h"
+#include "dbus-job.h"
+#include "missing.h"
+#include "path-lookup.h"
+#include "special.h"
+#include "bus-errors.h"
+#include "exit-status.h"
+#include "virt.h"
+#include "watchdog.h"
+#include "cgroup-util.h"
+#include "path-util.h"
+#include "audit-fd.h"
+
+/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
+#define GC_QUEUE_ENTRIES_MAX 16
+
+/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
+#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
+
+/* Where clients shall send notification messages to */
+#define NOTIFY_SOCKET "@/org/freedesktop/systemd1/notify"
+
+static int manager_setup_notify(Manager *m) {
+        union {
+                struct sockaddr sa;
+                struct sockaddr_un un;
+        } sa;
+        struct epoll_event ev;
+        int one = 1;
+
+        assert(m);
+
+        m->notify_watch.type = WATCH_NOTIFY;
+        m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (m->notify_watch.fd < 0) {
+                log_error("Failed to allocate notification socket: %m");
+                return -errno;
+        }
+
+        zero(sa);
+        sa.sa.sa_family = AF_UNIX;
+
+        if (getpid() != 1 || detect_container(NULL) > 0)
+                snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET "/%llu", random_ull());
+        else
+                strncpy(sa.un.sun_path, NOTIFY_SOCKET, sizeof(sa.un.sun_path));
+
+        sa.un.sun_path[0] = 0;
+
+        if (bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
+                log_error("bind() failed: %m");
+                return -errno;
+        }
+
+        if (setsockopt(m->notify_watch.fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) {
+                log_error("SO_PASSCRED failed: %m");
+                return -errno;
+        }
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.ptr = &m->notify_watch;
+
+        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0) {
+                log_error("Failed to add timer change fd to epoll: %m");
+                return -errno;
+        }
+
+        sa.un.sun_path[0] = '@';
+        m->notify_socket = strdup(sa.un.sun_path);
+        if (!m->notify_socket)
+                return log_oom();
+
+        log_debug("Using notification socket %s", m->notify_socket);
+
+        return 0;
+}
+
+static int manager_setup_time_change(Manager *m) {
+        struct epoll_event ev;
+        struct itimerspec its;
+
+        assert(m);
+        assert(m->time_change_watch.type == WATCH_INVALID);
+
+        /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
+         * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
+
+        m->time_change_watch.type = WATCH_TIME_CHANGE;
+        m->time_change_watch.fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+        if (m->time_change_watch.fd < 0) {
+                log_error("Failed to create timerfd: %m");
+                return -errno;
+        }
+
+        zero(its);
+
+        /* We only care for the cancellation event, hence we set the
+         * timeout to the latest possible value. */
+        assert_cc(sizeof(time_t) == sizeof(long));
+        its.it_value.tv_sec = LONG_MAX;
+
+        if (timerfd_settime(m->time_change_watch.fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
+                log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
+                close_nointr_nofail(m->time_change_watch.fd);
+                watch_init(&m->time_change_watch);
+                return 0;
+        }
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.ptr = &m->time_change_watch;
+
+        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->time_change_watch.fd, &ev) < 0) {
+                log_error("Failed to add timer change fd to epoll: %m");
+                return -errno;
+        }
+
+        log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
+
+        return 0;
+}
+
+static int enable_special_signals(Manager *m) {
+        int fd;
+
+        assert(m);
+
+        /* Enable that we get SIGINT on control-alt-del. In containers
+         * this will fail with EPERM (older) or EINVAL (newer), so
+         * ignore that. */
+        if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
+                log_warning("Failed to enable ctrl-alt-del handling: %m");
+
+        fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0) {
+                /* Support systems without virtual console */
+                if (fd != -ENOENT)
+                        log_warning("Failed to open /dev/tty0: %m");
+        } else {
+                /* Enable that we get SIGWINCH on kbrequest */
+                if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
+                        log_warning("Failed to enable kbrequest handling: %s", strerror(errno));
+
+                close_nointr_nofail(fd);
+        }
+
+        return 0;
+}
+
+static int manager_setup_signals(Manager *m) {
+        sigset_t mask;
+        struct epoll_event ev;
+        struct sigaction sa;
+
+        assert(m);
+
+        /* We are not interested in SIGSTOP and friends. */
+        zero(sa);
+        sa.sa_handler = SIG_DFL;
+        sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
+        assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
+
+        assert_se(sigemptyset(&mask) == 0);
+
+        sigset_add_many(&mask,
+                        SIGCHLD,     /* Child died */
+                        SIGTERM,     /* Reexecute daemon */
+                        SIGHUP,      /* Reload configuration */
+                        SIGUSR1,     /* systemd/upstart: reconnect to D-Bus */
+                        SIGUSR2,     /* systemd: dump status */
+                        SIGINT,      /* Kernel sends us this on control-alt-del */
+                        SIGWINCH,    /* Kernel sends us this on kbrequest (alt-arrowup) */
+                        SIGPWR,      /* Some kernel drivers and upsd send us this on power failure */
+                        SIGRTMIN+0,  /* systemd: start default.target */
+                        SIGRTMIN+1,  /* systemd: isolate rescue.target */
+                        SIGRTMIN+2,  /* systemd: isolate emergency.target */
+                        SIGRTMIN+3,  /* systemd: start halt.target */
+                        SIGRTMIN+4,  /* systemd: start poweroff.target */
+                        SIGRTMIN+5,  /* systemd: start reboot.target */
+                        SIGRTMIN+6,  /* systemd: start kexec.target */
+                        SIGRTMIN+13, /* systemd: Immediate halt */
+                        SIGRTMIN+14, /* systemd: Immediate poweroff */
+                        SIGRTMIN+15, /* systemd: Immediate reboot */
+                        SIGRTMIN+16, /* systemd: Immediate kexec */
+                        SIGRTMIN+20, /* systemd: enable status messages */
+                        SIGRTMIN+21, /* systemd: disable status messages */
+                        SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
+                        SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
+                        SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
+                        SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
+                        SIGRTMIN+27, /* systemd: set log target to console */
+                        SIGRTMIN+28, /* systemd: set log target to kmsg */
+                        SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */
+                        -1);
+        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+        m->signal_watch.type = WATCH_SIGNAL;
+        m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (m->signal_watch.fd < 0)
+                return -errno;
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.ptr = &m->signal_watch;
+
+        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
+                return -errno;
+
+        if (m->running_as == SYSTEMD_SYSTEM)
+                return enable_special_signals(m);
+
+        return 0;
+}
+
+static void manager_strip_environment(Manager *m) {
+        assert(m);
+
+        /* Remove variables from the inherited set that are part of
+         * the container interface:
+         * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface */
+        strv_remove_prefix(m->environment, "container=");
+        strv_remove_prefix(m->environment, "container_");
+
+        /* Remove variables from the inherited set that are part of
+         * the initrd interface:
+         * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */
+        strv_remove_prefix(m->environment, "RD_");
+}
+
+int manager_new(SystemdRunningAs running_as, Manager **_m) {
+        Manager *m;
+        int r = -ENOMEM;
+
+        assert(_m);
+        assert(running_as >= 0);
+        assert(running_as < _SYSTEMD_RUNNING_AS_MAX);
+
+        m = new0(Manager, 1);
+        if (!m)
+                return -ENOMEM;
+
+        dual_timestamp_get(&m->userspace_timestamp);
+
+        m->running_as = running_as;
+        m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
+        m->exit_code = _MANAGER_EXIT_CODE_INVALID;
+        m->pin_cgroupfs_fd = -1;
+        m->idle_pipe[0] = m->idle_pipe[1] = -1;
+
+        watch_init(&m->signal_watch);
+        watch_init(&m->mount_watch);
+        watch_init(&m->swap_watch);
+        watch_init(&m->udev_watch);
+        watch_init(&m->time_change_watch);
+
+        m->epoll_fd = m->dev_autofs_fd = -1;
+        m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
+
+        m->environment = strv_copy(environ);
+        if (!m->environment)
+                goto fail;
+
+        manager_strip_environment(m);
+
+        if (running_as == SYSTEMD_SYSTEM) {
+                m->default_controllers = strv_new("cpu", NULL);
+                if (!m->default_controllers)
+                        goto fail;
+        }
+
+        if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
+                goto fail;
+
+        if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
+                goto fail;
+
+        if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func)))
+                goto fail;
+
+        if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func)))
+                goto fail;
+
+        if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func)))
+                goto fail;
+
+        m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+        if (m->epoll_fd < 0)
+                goto fail;
+
+        r = manager_setup_signals(m);
+        if (r < 0)
+                goto fail;
+
+        r = manager_setup_cgroup(m);
+        if (r < 0)
+                goto fail;
+
+        r = manager_setup_notify(m);
+        if (r < 0)
+                goto fail;
+
+        r = manager_setup_time_change(m);
+        if (r < 0)
+                goto fail;
+
+        /* Try to connect to the busses, if possible. */
+        r = bus_init(m, running_as != SYSTEMD_SYSTEM);
+        if (r < 0)
+                goto fail;
+
+        m->taint_usr = dir_is_empty("/usr") > 0;
+
+        *_m = m;
+        return 0;
+
+fail:
+        manager_free(m);
+        return r;
+}
+
+static unsigned manager_dispatch_cleanup_queue(Manager *m) {
+        Unit *u;
+        unsigned n = 0;
+
+        assert(m);
+
+        while ((u = m->cleanup_queue)) {
+                assert(u->in_cleanup_queue);
+
+                unit_free(u);
+                n++;
+        }
+
+        return n;
+}
+
+enum {
+        GC_OFFSET_IN_PATH,  /* This one is on the path we were traveling */
+        GC_OFFSET_UNSURE,   /* No clue */
+        GC_OFFSET_GOOD,     /* We still need this unit */
+        GC_OFFSET_BAD,      /* We don't need this unit anymore */
+        _GC_OFFSET_MAX
+};
+
+static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
+        Iterator i;
+        Unit *other;
+        bool is_bad;
+
+        assert(u);
+
+        if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
+            u->gc_marker == gc_marker + GC_OFFSET_BAD ||
+            u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
+                return;
+
+        if (u->in_cleanup_queue)
+                goto bad;
+
+        if (unit_check_gc(u))
+                goto good;
+
+        u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
+
+        is_bad = true;
+
+        SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
+                unit_gc_sweep(other, gc_marker);
+
+                if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
+                        goto good;
+
+                if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
+                        is_bad = false;
+        }
+
+        if (is_bad)
+                goto bad;
+
+        /* We were unable to find anything out about this entry, so
+         * let's investigate it later */
+        u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
+        unit_add_to_gc_queue(u);
+        return;
+
+bad:
+        /* We definitely know that this one is not useful anymore, so
+         * let's mark it for deletion */
+        u->gc_marker = gc_marker + GC_OFFSET_BAD;
+        unit_add_to_cleanup_queue(u);
+        return;
+
+good:
+        u->gc_marker = gc_marker + GC_OFFSET_GOOD;
+}
+
+static unsigned manager_dispatch_gc_queue(Manager *m) {
+        Unit *u;
+        unsigned n = 0;
+        unsigned gc_marker;
+
+        assert(m);
+
+        if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) &&
+            (m->gc_queue_timestamp <= 0 ||
+             (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC)))
+                return 0;
+
+        log_debug("Running GC...");
+
+        m->gc_marker += _GC_OFFSET_MAX;
+        if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
+                m->gc_marker = 1;
+
+        gc_marker = m->gc_marker;
+
+        while ((u = m->gc_queue)) {
+                assert(u->in_gc_queue);
+
+                unit_gc_sweep(u, gc_marker);
+
+                LIST_REMOVE(Unit, gc_queue, m->gc_queue, u);
+                u->in_gc_queue = false;
+
+                n++;
+
+                if (u->gc_marker == gc_marker + GC_OFFSET_BAD ||
+                    u->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
+                        log_debug_unit(u->id, "Collecting %s", u->id);
+                        u->gc_marker = gc_marker + GC_OFFSET_BAD;
+                        unit_add_to_cleanup_queue(u);
+                }
+        }
+
+        m->n_in_gc_queue = 0;
+        m->gc_queue_timestamp = 0;
+
+        return n;
+}
+
+static void manager_clear_jobs_and_units(Manager *m) {
+        Unit *u;
+
+        assert(m);
+
+        while ((u = hashmap_first(m->units)))
+                unit_free(u);
+
+        manager_dispatch_cleanup_queue(m);
+
+        assert(!m->load_queue);
+        assert(!m->run_queue);
+        assert(!m->dbus_unit_queue);
+        assert(!m->dbus_job_queue);
+        assert(!m->cleanup_queue);
+        assert(!m->gc_queue);
+
+        assert(hashmap_isempty(m->jobs));
+        assert(hashmap_isempty(m->units));
+}
+
+void manager_free(Manager *m) {
+        UnitType c;
+        int i;
+
+        assert(m);
+
+        manager_clear_jobs_and_units(m);
+
+        for (c = 0; c < _UNIT_TYPE_MAX; c++)
+                if (unit_vtable[c]->shutdown)
+                        unit_vtable[c]->shutdown(m);
+
+        /* If we reexecute ourselves, we keep the root cgroup
+         * around */
+        manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
+
+        manager_undo_generators(m);
+
+        bus_done(m);
+
+        hashmap_free(m->units);
+        hashmap_free(m->jobs);
+        hashmap_free(m->watch_pids);
+        hashmap_free(m->watch_bus);
+
+        if (m->epoll_fd >= 0)
+                close_nointr_nofail(m->epoll_fd);
+        if (m->signal_watch.fd >= 0)
+                close_nointr_nofail(m->signal_watch.fd);
+        if (m->notify_watch.fd >= 0)
+                close_nointr_nofail(m->notify_watch.fd);
+        if (m->time_change_watch.fd >= 0)
+                close_nointr_nofail(m->time_change_watch.fd);
+
+        free(m->notify_socket);
+
+        lookup_paths_free(&m->lookup_paths);
+        strv_free(m->environment);
+
+        strv_free(m->default_controllers);
+
+        hashmap_free(m->cgroup_bondings);
+        set_free_free(m->unit_path_cache);
+
+        close_pipe(m->idle_pipe);
+
+        free(m->switch_root);
+        free(m->switch_root_init);
+
+        for (i = 0; i < RLIMIT_NLIMITS; i++)
+                free(m->rlimit[i]);
+
+        free(m);
+}
+
+int manager_enumerate(Manager *m) {
+        int r = 0, q;
+        UnitType c;
+
+        assert(m);
+
+        /* Let's ask every type to load all units from disk/kernel
+         * that it might know */
+        for (c = 0; c < _UNIT_TYPE_MAX; c++)
+                if (unit_vtable[c]->enumerate)
+                        if ((q = unit_vtable[c]->enumerate(m)) < 0)
+                                r = q;
+
+        manager_dispatch_load_queue(m);
+        return r;
+}
+
+int manager_coldplug(Manager *m) {
+        int r = 0, q;
+        Iterator i;
+        Unit *u;
+        char *k;
+
+        assert(m);
+
+        /* Then, let's set up their initial state. */
+        HASHMAP_FOREACH_KEY(u, k, m->units, i) {
+
+                /* ignore aliases */
+                if (u->id != k)
+                        continue;
+
+                if ((q = unit_coldplug(u)) < 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+static void manager_build_unit_path_cache(Manager *m) {
+        char **i;
+        DIR *d = NULL;
+        int r;
+
+        assert(m);
+
+        set_free_free(m->unit_path_cache);
+
+        if (!(m->unit_path_cache = set_new(string_hash_func, string_compare_func))) {
+                log_error("Failed to allocate unit path cache.");
+                return;
+        }
+
+        /* This simply builds a list of files we know exist, so that
+         * we don't always have to go to disk */
+
+        STRV_FOREACH(i, m->lookup_paths.unit_path) {
+                struct dirent *de;
+
+                d = opendir(*i);
+                if (!d) {
+                        log_error("Failed to open directory: %m");
+                        continue;
+                }
+
+                while ((de = readdir(d))) {
+                        char *p;
+
+                        if (ignore_file(de->d_name))
+                                continue;
+
+                        p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
+                        if (!p) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        if ((r = set_put(m->unit_path_cache, p)) < 0) {
+                                free(p);
+                                goto fail;
+                        }
+                }
+
+                closedir(d);
+                d = NULL;
+        }
+
+        return;
+
+fail:
+        log_error("Failed to build unit path cache: %s", strerror(-r));
+
+        set_free_free(m->unit_path_cache);
+        m->unit_path_cache = NULL;
+
+        if (d)
+                closedir(d);
+}
+
+int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
+        int r, q;
+
+        assert(m);
+
+        manager_run_generators(m);
+
+        r = lookup_paths_init(
+                        &m->lookup_paths, m->running_as, true,
+                        m->generator_unit_path,
+                        m->generator_unit_path_early,
+                        m->generator_unit_path_late);
+        if (r < 0)
+                return r;
+
+        manager_build_unit_path_cache(m);
+
+        /* If we will deserialize make sure that during enumeration
+         * this is already known, so we increase the counter here
+         * already */
+        if (serialization)
+                m->n_reloading ++;
+
+        /* First, enumerate what we can from all config files */
+        r = manager_enumerate(m);
+
+        /* Second, deserialize if there is something to deserialize */
+        if (serialization) {
+                q = manager_deserialize(m, serialization, fds);
+                if (q < 0)
+                        r = q;
+        }
+
+        /* Any fds left? Find some unit which wants them. This is
+         * useful to allow container managers to pass some file
+         * descriptors to us pre-initialized. This enables
+         * socket-based activation of entire containers. */
+        if (fdset_size(fds) > 0) {
+                q = manager_distribute_fds(m, fds);
+                if (q < 0)
+                        r = q;
+        }
+
+        /* Third, fire things up! */
+        q = manager_coldplug(m);
+        if (q < 0)
+                r = q;
+
+        if (serialization) {
+                assert(m->n_reloading > 0);
+                m->n_reloading --;
+        }
+
+        return r;
+}
+
+int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) {
+        int r;
+        Transaction *tr;
+
+        assert(m);
+        assert(type < _JOB_TYPE_MAX);
+        assert(unit);
+        assert(mode < _JOB_MODE_MAX);
+
+        if (mode == JOB_ISOLATE && type != JOB_START) {
+                dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start.");
+                return -EINVAL;
+        }
+
+        if (mode == JOB_ISOLATE && !unit->allow_isolate) {
+                dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
+                return -EPERM;
+        }
+
+        log_debug_unit(unit->id,
+                       "Trying to enqueue job %s/%s/%s", unit->id,
+                       job_type_to_string(type), job_mode_to_string(mode));
+
+        job_type_collapse(&type, unit);
+
+        tr = transaction_new();
+        if (!tr)
+                return -ENOMEM;
+
+        r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
+                                                 mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
+                                                 mode == JOB_IGNORE_DEPENDENCIES, e);
+        if (r < 0)
+                goto tr_abort;
+
+        if (mode == JOB_ISOLATE) {
+                r = transaction_add_isolate_jobs(tr, m);
+                if (r < 0)
+                        goto tr_abort;
+        }
+
+        r = transaction_activate(tr, m, mode, e);
+        if (r < 0)
+                goto tr_abort;
+
+        log_debug_unit(unit->id,
+                       "Enqueued job %s/%s as %u", unit->id,
+                       job_type_to_string(type), (unsigned) tr->anchor_job->id);
+
+        if (_ret)
+                *_ret = tr->anchor_job;
+
+        transaction_free(tr);
+        return 0;
+
+tr_abort:
+        transaction_abort(tr);
+        transaction_free(tr);
+        return r;
+}
+
+int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, DBusError *e, Job **_ret) {
+        Unit *unit;
+        int r;
+
+        assert(m);
+        assert(type < _JOB_TYPE_MAX);
+        assert(name);
+        assert(mode < _JOB_MODE_MAX);
+
+        r = manager_load_unit(m, name, NULL, NULL, &unit);
+        if (r < 0)
+                return r;
+
+        return manager_add_job(m, type, unit, mode, override, e, _ret);
+}
+
+Job *manager_get_job(Manager *m, uint32_t id) {
+        assert(m);
+
+        return hashmap_get(m->jobs, UINT32_TO_PTR(id));
+}
+
+Unit *manager_get_unit(Manager *m, const char *name) {
+        assert(m);
+        assert(name);
+
+        return hashmap_get(m->units, name);
+}
+
+unsigned manager_dispatch_load_queue(Manager *m) {
+        Unit *u;
+        unsigned n = 0;
+
+        assert(m);
+
+        /* Make sure we are not run recursively */
+        if (m->dispatching_load_queue)
+                return 0;
+
+        m->dispatching_load_queue = true;
+
+        /* Dispatches the load queue. Takes a unit from the queue and
+         * tries to load its data until the queue is empty */
+
+        while ((u = m->load_queue)) {
+                assert(u->in_load_queue);
+
+                unit_load(u);
+                n++;
+        }
+
+        m->dispatching_load_queue = false;
+        return n;
+}
+
+int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
+        Unit *ret;
+        UnitType t;
+        int r;
+
+        assert(m);
+        assert(name || path);
+
+        /* This will prepare the unit for loading, but not actually
+         * load anything from disk. */
+
+        if (path && !is_path(path)) {
+                dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path);
+                return -EINVAL;
+        }
+
+        if (!name)
+                name = path_get_file_name(path);
+
+        t = unit_name_to_type(name);
+
+        if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, false)) {
+                dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name);
+                return -EINVAL;
+        }
+
+        ret = manager_get_unit(m, name);
+        if (ret) {
+                *_ret = ret;
+                return 1;
+        }
+
+        ret = unit_new(m, unit_vtable[t]->object_size);
+        if (!ret)
+                return -ENOMEM;
+
+        if (path) {
+                ret->fragment_path = strdup(path);
+                if (!ret->fragment_path) {
+                        unit_free(ret);
+                        return -ENOMEM;
+                }
+        }
+
+        if ((r = unit_add_name(ret, name)) < 0) {
+                unit_free(ret);
+                return r;
+        }
+
+        unit_add_to_load_queue(ret);
+        unit_add_to_dbus_queue(ret);
+        unit_add_to_gc_queue(ret);
+
+        if (_ret)
+                *_ret = ret;
+
+        return 0;
+}
+
+int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
+        int r;
+
+        assert(m);
+
+        /* This will load the service information files, but not actually
+         * start any services or anything. */
+
+        r = manager_load_unit_prepare(m, name, path, e, _ret);
+        if (r != 0)
+                return r;
+
+        manager_dispatch_load_queue(m);
+
+        if (_ret)
+                *_ret = unit_follow_merge(*_ret);
+
+        return 0;
+}
+
+void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
+        Iterator i;
+        Job *j;
+
+        assert(s);
+        assert(f);
+
+        HASHMAP_FOREACH(j, s->jobs, i)
+                job_dump(j, f, prefix);
+}
+
+void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
+        Iterator i;
+        Unit *u;
+        const char *t;
+
+        assert(s);
+        assert(f);
+
+        HASHMAP_FOREACH_KEY(u, t, s->units, i)
+                if (u->id == t)
+                        unit_dump(u, f, prefix);
+}
+
+void manager_clear_jobs(Manager *m) {
+        Job *j;
+
+        assert(m);
+
+        while ((j = hashmap_first(m->jobs)))
+                /* No need to recurse. We're cancelling all jobs. */
+                job_finish_and_invalidate(j, JOB_CANCELED, false);
+}
+
+unsigned manager_dispatch_run_queue(Manager *m) {
+        Job *j;
+        unsigned n = 0;
+
+        if (m->dispatching_run_queue)
+                return 0;
+
+        m->dispatching_run_queue = true;
+
+        while ((j = m->run_queue)) {
+                assert(j->installed);
+                assert(j->in_run_queue);
+
+                job_run_and_invalidate(j);
+                n++;
+        }
+
+        m->dispatching_run_queue = false;
+        return n;
+}
+
+unsigned manager_dispatch_dbus_queue(Manager *m) {
+        Job *j;
+        Unit *u;
+        unsigned n = 0;
+
+        assert(m);
+
+        if (m->dispatching_dbus_queue)
+                return 0;
+
+        m->dispatching_dbus_queue = true;
+
+        while ((u = m->dbus_unit_queue)) {
+                assert(u->in_dbus_queue);
+
+                bus_unit_send_change_signal(u);
+                n++;
+        }
+
+        while ((j = m->dbus_job_queue)) {
+                assert(j->in_dbus_queue);
+
+                bus_job_send_change_signal(j);
+                n++;
+        }
+
+        m->dispatching_dbus_queue = false;
+        return n;
+}
+
+static int manager_process_notify_fd(Manager *m) {
+        ssize_t n;
+
+        assert(m);
+
+        for (;;) {
+                char buf[4096];
+                struct msghdr msghdr;
+                struct iovec iovec;
+                struct ucred *ucred;
+                union {
+                        struct cmsghdr cmsghdr;
+                        uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
+                } control;
+                Unit *u;
+                char **tags;
+
+                zero(iovec);
+                iovec.iov_base = buf;
+                iovec.iov_len = sizeof(buf)-1;
+
+                zero(control);
+                zero(msghdr);
+                msghdr.msg_iov = &iovec;
+                msghdr.msg_iovlen = 1;
+                msghdr.msg_control = &control;
+                msghdr.msg_controllen = sizeof(control);
+
+                n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT);
+                if (n <= 0) {
+                        if (n >= 0)
+                                return -EIO;
+
+                        if (errno == EAGAIN || errno == EINTR)
+                                break;
+
+                        return -errno;
+                }
+
+                if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
+                    control.cmsghdr.cmsg_level != SOL_SOCKET ||
+                    control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
+                    control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
+                        log_warning("Received notify message without credentials. Ignoring.");
+                        continue;
+                }
+
+                ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
+
+                u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid));
+                if (!u) {
+                        u = cgroup_unit_by_pid(m, ucred->pid);
+                        if (!u) {
+                                log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid);
+                                continue;
+                        }
+                }
+
+                assert((size_t) n < sizeof(buf));
+                buf[n] = 0;
+                tags = strv_split(buf, "\n\r");
+                if (!tags)
+                        return log_oom();
+
+                log_debug_unit(u->id, "Got notification message for unit %s", u->id);
+
+                if (UNIT_VTABLE(u)->notify_message)
+                        UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags);
+
+                strv_free(tags);
+        }
+
+        return 0;
+}
+
+static int manager_dispatch_sigchld(Manager *m) {
+        assert(m);
+
+        for (;;) {
+                siginfo_t si;
+                Unit *u;
+                int r;
+
+                zero(si);
+
+                /* First we call waitd() for a PID and do not reap the
+                 * zombie. That way we can still access /proc/$PID for
+                 * it while it is a zombie. */
+                if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
+
+                        if (errno == ECHILD)
+                                break;
+
+                        if (errno == EINTR)
+                                continue;
+
+                        return -errno;
+                }
+
+                if (si.si_pid <= 0)
+                        break;
+
+                if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
+                        char _cleanup_free_ *name = NULL;
+
+                        get_process_comm(si.si_pid, &name);
+                        log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
+                }
+
+                /* Let's flush any message the dying child might still
+                 * have queued for us. This ensures that the process
+                 * still exists in /proc so that we can figure out
+                 * which cgroup and hence unit it belongs to. */
+                r = manager_process_notify_fd(m);
+                if (r < 0)
+                        return r;
+
+                /* And now figure out the unit this belongs to */
+                u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid));
+                if (!u)
+                        u = cgroup_unit_by_pid(m, si.si_pid);
+
+                /* And now, we actually reap the zombie. */
+                if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
+                        if (errno == EINTR)
+                                continue;
+
+                        return -errno;
+                }
+
+                if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
+                        continue;
+
+                log_debug("Child %lu died (code=%s, status=%i/%s)",
+                          (long unsigned) si.si_pid,
+                          sigchld_code_to_string(si.si_code),
+                          si.si_status,
+                          strna(si.si_code == CLD_EXITED
+                                ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
+                                : signal_to_string(si.si_status)));
+
+                if (!u)
+                        continue;
+
+                log_debug_unit(u->id,
+                               "Child %lu belongs to %s", (long unsigned) si.si_pid, u->id);
+
+                hashmap_remove(m->watch_pids, LONG_TO_PTR(si.si_pid));
+                UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
+        }
+
+        return 0;
+}
+
+static int manager_start_target(Manager *m, const char *name, JobMode mode) {
+        int r;
+        DBusError error;
+
+        dbus_error_init(&error);
+
+        log_debug_unit(name, "Activating special unit %s", name);
+
+        r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL);
+        if (r < 0)
+                log_error_unit(name,
+                               "Failed to enqueue %s job: %s", name, bus_error(&error, r));
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int manager_process_signal_fd(Manager *m) {
+        ssize_t n;
+        struct signalfd_siginfo sfsi;
+        bool sigchld = false;
+
+        assert(m);
+
+        for (;;) {
+                n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi));
+                if (n != sizeof(sfsi)) {
+
+                        if (n >= 0)
+                                return -EIO;
+
+                        if (errno == EINTR || errno == EAGAIN)
+                                break;
+
+                        return -errno;
+                }
+
+                if (sfsi.ssi_pid > 0) {
+                        char *p = NULL;
+
+                        get_process_comm(sfsi.ssi_pid, &p);
+
+                        log_debug("Received SIG%s from PID %lu (%s).",
+                                  signal_to_string(sfsi.ssi_signo),
+                                  (unsigned long) sfsi.ssi_pid, strna(p));
+                        free(p);
+                } else
+                        log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo));
+
+                switch (sfsi.ssi_signo) {
+
+                case SIGCHLD:
+                        sigchld = true;
+                        break;
+
+                case SIGTERM:
+                        if (m->running_as == SYSTEMD_SYSTEM) {
+                                /* This is for compatibility with the
+                                 * original sysvinit */
+                                m->exit_code = MANAGER_REEXECUTE;
+                                break;
+                        }
+
+                        /* Fall through */
+
+                case SIGINT:
+                        if (m->running_as == SYSTEMD_SYSTEM) {
+                                manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
+                                break;
+                        }
+
+                        /* Run the exit target if there is one, if not, just exit. */
+                        if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
+                                m->exit_code = MANAGER_EXIT;
+                                return 0;
+                        }
+
+                        break;
+
+                case SIGWINCH:
+                        if (m->running_as == SYSTEMD_SYSTEM)
+                                manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
+
+                        /* This is a nop on non-init */
+                        break;
+
+                case SIGPWR:
+                        if (m->running_as == SYSTEMD_SYSTEM)
+                                manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
+
+                        /* This is a nop on non-init */
+                        break;
+
+                case SIGUSR1: {
+                        Unit *u;
+
+                        u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
+
+                        if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
+                                log_info("Trying to reconnect to bus...");
+                                bus_init(m, true);
+                        }
+
+                        if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
+                                log_info("Loading D-Bus service...");
+                                manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
+                        }
+
+                        break;
+                }
+
+                case SIGUSR2: {
+                        FILE *f;
+                        char *dump = NULL;
+                        size_t size;
+
+                        if (!(f = open_memstream(&dump, &size))) {
+                                log_warning("Failed to allocate memory stream.");
+                                break;
+                        }
+
+                        manager_dump_units(m, f, "\t");
+                        manager_dump_jobs(m, f, "\t");
+
+                        if (ferror(f)) {
+                                fclose(f);
+                                free(dump);
+                                log_warning("Failed to write status stream");
+                                break;
+                        }
+
+                        fclose(f);
+                        log_dump(LOG_INFO, dump);
+                        free(dump);
+
+                        break;
+                }
+
+                case SIGHUP:
+                        m->exit_code = MANAGER_RELOAD;
+                        break;
+
+                default: {
+
+                        /* Starting SIGRTMIN+0 */
+                        static const char * const target_table[] = {
+                                [0] = SPECIAL_DEFAULT_TARGET,
+                                [1] = SPECIAL_RESCUE_TARGET,
+                                [2] = SPECIAL_EMERGENCY_TARGET,
+                                [3] = SPECIAL_HALT_TARGET,
+                                [4] = SPECIAL_POWEROFF_TARGET,
+                                [5] = SPECIAL_REBOOT_TARGET,
+                                [6] = SPECIAL_KEXEC_TARGET
+                        };
+
+                        /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
+                        static const ManagerExitCode code_table[] = {
+                                [0] = MANAGER_HALT,
+                                [1] = MANAGER_POWEROFF,
+                                [2] = MANAGER_REBOOT,
+                                [3] = MANAGER_KEXEC
+                        };
+
+                        if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
+                            (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
+                                int idx = (int) sfsi.ssi_signo - SIGRTMIN;
+                                manager_start_target(m, target_table[idx],
+                                                     (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
+                                break;
+                        }
+
+                        if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
+                            (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
+                                m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
+                                break;
+                        }
+
+                        switch (sfsi.ssi_signo - SIGRTMIN) {
+
+                        case 20:
+                                log_debug("Enabling showing of status.");
+                                manager_set_show_status(m, true);
+                                break;
+
+                        case 21:
+                                log_debug("Disabling showing of status.");
+                                manager_set_show_status(m, false);
+                                break;
+
+                        case 22:
+                                log_set_max_level(LOG_DEBUG);
+                                log_notice("Setting log level to debug.");
+                                break;
+
+                        case 23:
+                                log_set_max_level(LOG_INFO);
+                                log_notice("Setting log level to info.");
+                                break;
+
+                        case 24:
+                                if (m->running_as == SYSTEMD_USER) {
+                                        m->exit_code = MANAGER_EXIT;
+                                        return 0;
+                                }
+
+                                /* This is a nop on init */
+                                break;
+
+                        case 26:
+                                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+                                log_notice("Setting log target to journal-or-kmsg.");
+                                break;
+
+                        case 27:
+                                log_set_target(LOG_TARGET_CONSOLE);
+                                log_notice("Setting log target to console.");
+                                break;
+
+                        case 28:
+                                log_set_target(LOG_TARGET_KMSG);
+                                log_notice("Setting log target to kmsg.");
+                                break;
+
+                        case 29:
+                                log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
+                                log_notice("Setting log target to syslog-or-kmsg.");
+                                break;
+
+                        default:
+                                log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
+                        }
+                }
+                }
+        }
+
+        if (sigchld)
+                return manager_dispatch_sigchld(m);
+
+        return 0;
+}
+
+static int process_event(Manager *m, struct epoll_event *ev) {
+        int r;
+        Watch *w;
+
+        assert(m);
+        assert(ev);
+
+        assert_se(w = ev->data.ptr);
+
+        if (w->type == WATCH_INVALID)
+                return 0;
+
+        switch (w->type) {
+
+        case WATCH_SIGNAL:
+
+                /* An incoming signal? */
+                if (ev->events != EPOLLIN)
+                        return -EINVAL;
+
+                if ((r = manager_process_signal_fd(m)) < 0)
+                        return r;
+
+                break;
+
+        case WATCH_NOTIFY:
+
+                /* An incoming daemon notification event? */
+                if (ev->events != EPOLLIN)
+                        return -EINVAL;
+
+                if ((r = manager_process_notify_fd(m)) < 0)
+                        return r;
+
+                break;
+
+        case WATCH_FD:
+
+                /* Some fd event, to be dispatched to the units */
+                UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w);
+                break;
+
+        case WATCH_UNIT_TIMER:
+        case WATCH_JOB_TIMER: {
+                uint64_t v;
+                ssize_t k;
+
+                /* Some timer event, to be dispatched to the units */
+                k = read(w->fd, &v, sizeof(v));
+                if (k != sizeof(v)) {
+
+                        if (k < 0 && (errno == EINTR || errno == EAGAIN))
+                                break;
+
+                        log_error("Failed to read timer event counter: %s", k < 0 ? strerror(-k) : "Short read");
+                        return k < 0 ? -errno : -EIO;
+                }
+
+                if (w->type == WATCH_UNIT_TIMER)
+                        UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w);
+                else
+                        job_timer_event(w->data.job, v, w);
+                break;
+        }
+
+        case WATCH_MOUNT:
+                /* Some mount table change, intended for the mount subsystem */
+                mount_fd_event(m, ev->events);
+                break;
+
+        case WATCH_SWAP:
+                /* Some swap table change, intended for the swap subsystem */
+                swap_fd_event(m, ev->events);
+                break;
+
+        case WATCH_UDEV:
+                /* Some notification from udev, intended for the device subsystem */
+                device_fd_event(m, ev->events);
+                break;
+
+        case WATCH_DBUS_WATCH:
+                bus_watch_event(m, w, ev->events);
+                break;
+
+        case WATCH_DBUS_TIMEOUT:
+                bus_timeout_event(m, w, ev->events);
+                break;
+
+        case WATCH_TIME_CHANGE: {
+                Unit *u;
+                Iterator i;
+
+                log_struct(LOG_INFO,
+                           MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
+                           "MESSAGE=Time has been changed",
+                           NULL);
+
+                /* Restart the watch */
+                close_nointr_nofail(m->time_change_watch.fd);
+                watch_init(&m->time_change_watch);
+                manager_setup_time_change(m);
+
+                HASHMAP_FOREACH(u, m->units, i) {
+                        if (UNIT_VTABLE(u)->time_change)
+                                UNIT_VTABLE(u)->time_change(u);
+                }
+
+                break;
+        }
+
+        default:
+                log_error("event type=%i", w->type);
+                assert_not_reached("Unknown epoll event type.");
+        }
+
+        return 0;
+}
+
+int manager_loop(Manager *m) {
+        int r;
+
+        RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
+
+        assert(m);
+        m->exit_code = MANAGER_RUNNING;
+
+        /* Release the path cache */
+        set_free_free(m->unit_path_cache);
+        m->unit_path_cache = NULL;
+
+        manager_check_finished(m);
+
+        /* There might still be some zombies hanging around from
+         * before we were exec()'ed. Leat's reap them */
+        r = manager_dispatch_sigchld(m);
+        if (r < 0)
+                return r;
+
+        while (m->exit_code == MANAGER_RUNNING) {
+                struct epoll_event event;
+                int n;
+                int wait_msec = -1;
+
+                if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM)
+                        watchdog_ping();
+
+                if (!ratelimit_test(&rl)) {
+                        /* Yay, something is going seriously wrong, pause a little */
+                        log_warning("Looping too fast. Throttling execution a little.");
+                        sleep(1);
+                        continue;
+                }
+
+                if (manager_dispatch_load_queue(m) > 0)
+                        continue;
+
+                if (manager_dispatch_run_queue(m) > 0)
+                        continue;
+
+                if (bus_dispatch(m) > 0)
+                        continue;
+
+                if (manager_dispatch_cleanup_queue(m) > 0)
+                        continue;
+
+                if (manager_dispatch_gc_queue(m) > 0)
+                        continue;
+
+                if (manager_dispatch_dbus_queue(m) > 0)
+                        continue;
+
+                if (swap_dispatch_reload(m) > 0)
+                        continue;
+
+                /* Sleep for half the watchdog time */
+                if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM) {
+                        wait_msec = (int) (m->runtime_watchdog / 2 / USEC_PER_MSEC);
+                        if (wait_msec <= 0)
+                                wait_msec = 1;
+                } else
+                        wait_msec = -1;
+
+                n = epoll_wait(m->epoll_fd, &event, 1, wait_msec);
+                if (n < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        return -errno;
+                } else if (n == 0)
+                        continue;
+
+                assert(n == 1);
+
+                r = process_event(m, &event);
+                if (r < 0)
+                        return r;
+        }
+
+        return m->exit_code;
+}
+
+int manager_load_unit_from_dbus_path(Manager *m, const char *s, DBusError *e, Unit **_u) {
+        char *n;
+        Unit *u;
+        int r;
+
+        assert(m);
+        assert(s);
+        assert(_u);
+
+        if (!startswith(s, "/org/freedesktop/systemd1/unit/"))
+                return -EINVAL;
+
+        n = bus_path_unescape(s+31);
+        if (!n)
+                return -ENOMEM;
+
+        r = manager_load_unit(m, n, NULL, e, &u);
+        free(n);
+
+        if (r < 0)
+                return r;
+
+        *_u = u;
+
+        return 0;
+}
+
+int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
+        Job *j;
+        unsigned id;
+        int r;
+
+        assert(m);
+        assert(s);
+        assert(_j);
+
+        if (!startswith(s, "/org/freedesktop/systemd1/job/"))
+                return -EINVAL;
+
+        r = safe_atou(s + 30, &id);
+        if (r < 0)
+                return r;
+
+        j = manager_get_job(m, id);
+        if (!j)
+                return -ENOENT;
+
+        *_j = j;
+
+        return 0;
+}
+
+void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
+
+#ifdef HAVE_AUDIT
+        char *p;
+        int audit_fd;
+
+        audit_fd = get_audit_fd();
+        if (audit_fd < 0)
+                return;
+
+        /* Don't generate audit events if the service was already
+         * started and we're just deserializing */
+        if (m->n_reloading > 0)
+                return;
+
+        if (m->running_as != SYSTEMD_SYSTEM)
+                return;
+
+        if (u->type != UNIT_SERVICE)
+                return;
+
+        p = unit_name_to_prefix_and_instance(u->id);
+        if (!p) {
+                log_error_unit(u->id,
+                               "Failed to allocate unit name for audit message: %s", strerror(ENOMEM));
+                return;
+        }
+
+        if (audit_log_user_comm_message(audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
+                if (errno == EPERM) {
+                        /* We aren't allowed to send audit messages?
+                         * Then let's not retry again. */
+                        close_audit_fd();
+                } else
+                        log_warning("Failed to send audit message: %m");
+        }
+
+        free(p);
+#endif
+
+}
+
+void manager_send_unit_plymouth(Manager *m, Unit *u) {
+        int fd = -1;
+        union sockaddr_union sa;
+        int n = 0;
+        char *message = NULL;
+
+        /* Don't generate plymouth events if the service was already
+         * started and we're just deserializing */
+        if (m->n_reloading > 0)
+                return;
+
+        if (m->running_as != SYSTEMD_SYSTEM)
+                return;
+
+        if (u->type != UNIT_SERVICE &&
+            u->type != UNIT_MOUNT &&
+            u->type != UNIT_SWAP)
+                return;
+
+        /* We set SOCK_NONBLOCK here so that we rather drop the
+         * message then wait for plymouth */
+        if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
+                log_error("socket() failed: %m");
+                return;
+        }
+
+        zero(sa);
+        sa.sa.sa_family = AF_UNIX;
+        strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
+        if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
+
+                if (errno != EPIPE &&
+                    errno != EAGAIN &&
+                    errno != ENOENT &&
+                    errno != ECONNREFUSED &&
+                    errno != ECONNRESET &&
+                    errno != ECONNABORTED)
+                        log_error("connect() failed: %m");
+
+                goto finish;
+        }
+
+        if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
+                log_oom();
+                goto finish;
+        }
+
+        errno = 0;
+        if (write(fd, message, n + 1) != n + 1) {
+
+                if (errno != EPIPE &&
+                    errno != EAGAIN &&
+                    errno != ENOENT &&
+                    errno != ECONNREFUSED &&
+                    errno != ECONNRESET &&
+                    errno != ECONNABORTED)
+                        log_error("Failed to write Plymouth message: %m");
+
+                goto finish;
+        }
+
+finish:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        free(message);
+}
+
+void manager_dispatch_bus_name_owner_changed(
+                Manager *m,
+                const char *name,
+                const char* old_owner,
+                const char *new_owner) {
+
+        Unit *u;
+
+        assert(m);
+        assert(name);
+
+        if (!(u = hashmap_get(m->watch_bus, name)))
+                return;
+
+        UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
+}
+
+void manager_dispatch_bus_query_pid_done(
+                Manager *m,
+                const char *name,
+                pid_t pid) {
+
+        Unit *u;
+
+        assert(m);
+        assert(name);
+        assert(pid >= 1);
+
+        if (!(u = hashmap_get(m->watch_bus, name)))
+                return;
+
+        UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid);
+}
+
+int manager_open_serialization(Manager *m, FILE **_f) {
+        char *path = NULL;
+        mode_t saved_umask;
+        int fd;
+        FILE *f;
+
+        assert(_f);
+
+        if (m->running_as == SYSTEMD_SYSTEM)
+                asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid());
+        else
+                asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid());
+
+        if (!path)
+                return -ENOMEM;
+
+        saved_umask = umask(0077);
+        fd = mkostemp(path, O_RDWR|O_CLOEXEC);
+        umask(saved_umask);
+
+        if (fd < 0) {
+                free(path);
+                return -errno;
+        }
+
+        unlink(path);
+
+        log_debug("Serializing state to %s", path);
+        free(path);
+
+        f = fdopen(fd, "w+");
+        if (!f)
+                return -errno;
+
+        *_f = f;
+
+        return 0;
+}
+
+int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs) {
+        Iterator i;
+        Unit *u;
+        const char *t;
+        int r;
+
+        assert(m);
+        assert(f);
+        assert(fds);
+
+        m->n_reloading ++;
+
+        fprintf(f, "current-job-id=%i\n", m->current_job_id);
+        fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
+        fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
+        fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
+
+        dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp);
+        dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp);
+        dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp);
+        dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
+
+        if (!in_initrd()) {
+                dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp);
+                dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
+        }
+
+        fputc('\n', f);
+
+        HASHMAP_FOREACH_KEY(u, t, m->units, i) {
+                if (u->id != t)
+                        continue;
+
+                if (!unit_can_serialize(u))
+                        continue;
+
+                /* Start marker */
+                fputs(u->id, f);
+                fputc('\n', f);
+
+                if ((r = unit_serialize(u, f, fds, serialize_jobs)) < 0) {
+                        m->n_reloading --;
+                        return r;
+                }
+        }
+
+        assert(m->n_reloading > 0);
+        m->n_reloading --;
+
+        if (ferror(f))
+                return -EIO;
+
+        r = bus_fdset_add_all(m, fds);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+        int r = 0;
+
+        assert(m);
+        assert(f);
+
+        log_debug("Deserializing state...");
+
+        m->n_reloading ++;
+
+        for (;;) {
+                char line[LINE_MAX], *l;
+
+                if (!fgets(line, sizeof(line), f)) {
+                        if (feof(f))
+                                r = 0;
+                        else
+                                r = -errno;
+
+                        goto finish;
+                }
+
+                char_array_0(line);
+                l = strstrip(line);
+
+                if (l[0] == 0)
+                        break;
+
+                if (startswith(l, "current-job-id=")) {
+                        uint32_t id;
+
+                        if (safe_atou32(l+15, &id) < 0)
+                                log_debug("Failed to parse current job id value %s", l+15);
+                        else
+                                m->current_job_id = MAX(m->current_job_id, id);
+                } else if (startswith(l, "n-installed-jobs=")) {
+                        uint32_t n;
+
+                        if (safe_atou32(l+17, &n) < 0)
+                                log_debug("Failed to parse installed jobs counter %s", l+17);
+                        else
+                                m->n_installed_jobs += n;
+                } else if (startswith(l, "n-failed-jobs=")) {
+                        uint32_t n;
+
+                        if (safe_atou32(l+14, &n) < 0)
+                                log_debug("Failed to parse failed jobs counter %s", l+14);
+                        else
+                                m->n_failed_jobs += n;
+                } else if (startswith(l, "taint-usr=")) {
+                        int b;
+
+                        if ((b = parse_boolean(l+10)) < 0)
+                                log_debug("Failed to parse taint /usr flag %s", l+10);
+                        else
+                                m->taint_usr = m->taint_usr || b;
+                } else if (startswith(l, "firmware-timestamp="))
+                        dual_timestamp_deserialize(l+19, &m->firmware_timestamp);
+                else if (startswith(l, "loader-timestamp="))
+                        dual_timestamp_deserialize(l+17, &m->loader_timestamp);
+                else if (startswith(l, "kernel-timestamp="))
+                        dual_timestamp_deserialize(l+17, &m->kernel_timestamp);
+                else if (startswith(l, "initrd-timestamp="))
+                        dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
+                else if (startswith(l, "userspace-timestamp="))
+                        dual_timestamp_deserialize(l+20, &m->userspace_timestamp);
+                else if (startswith(l, "finish-timestamp="))
+                        dual_timestamp_deserialize(l+17, &m->finish_timestamp);
+                else
+                        log_debug("Unknown serialization item '%s'", l);
+        }
+
+        for (;;) {
+                Unit *u;
+                char name[UNIT_NAME_MAX+2];
+
+                /* Start marker */
+                if (!fgets(name, sizeof(name), f)) {
+                        if (feof(f))
+                                r = 0;
+                        else
+                                r = -errno;
+
+                        goto finish;
+                }
+
+                char_array_0(name);
+
+                r = manager_load_unit(m, strstrip(name), NULL, NULL, &u);
+                if (r < 0)
+                        goto finish;
+
+                r = unit_deserialize(u, f, fds);
+                if (r < 0)
+                        goto finish;
+        }
+
+finish:
+        if (ferror(f)) {
+                r = -EIO;
+                goto finish;
+        }
+
+        assert(m->n_reloading > 0);
+        m->n_reloading --;
+
+        return r;
+}
+
+int manager_distribute_fds(Manager *m, FDSet *fds) {
+        Unit *u;
+        Iterator i;
+        int r;
+
+        assert(m);
+
+        HASHMAP_FOREACH(u, m->units, i) {
+
+                if (fdset_size(fds) <= 0)
+                        break;
+
+                if (UNIT_VTABLE(u)->distribute_fds) {
+                        r = UNIT_VTABLE(u)->distribute_fds(u, fds);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}
+
+int manager_reload(Manager *m) {
+        int r, q;
+        FILE *f;
+        FDSet *fds;
+
+        assert(m);
+
+        r = manager_open_serialization(m, &f);
+        if (r < 0)
+                return r;
+
+        m->n_reloading ++;
+
+        fds = fdset_new();
+        if (!fds) {
+                m->n_reloading --;
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = manager_serialize(m, f, fds, true);
+        if (r < 0) {
+                m->n_reloading --;
+                goto finish;
+        }
+
+        if (fseeko(f, 0, SEEK_SET) < 0) {
+                m->n_reloading --;
+                r = -errno;
+                goto finish;
+        }
+
+        /* From here on there is no way back. */
+        manager_clear_jobs_and_units(m);
+        manager_undo_generators(m);
+        lookup_paths_free(&m->lookup_paths);
+
+        /* Find new unit paths */
+        manager_run_generators(m);
+
+        q = lookup_paths_init(
+                        &m->lookup_paths, m->running_as, true,
+                        m->generator_unit_path,
+                        m->generator_unit_path_early,
+                        m->generator_unit_path_late);
+        if (q < 0)
+                r = q;
+
+        manager_build_unit_path_cache(m);
+
+        /* First, enumerate what we can from all config files */
+        q = manager_enumerate(m);
+        if (q < 0)
+                r = q;
+
+        /* Second, deserialize our stored data */
+        q = manager_deserialize(m, f, fds);
+        if (q < 0)
+                r = q;
+
+        fclose(f);
+        f = NULL;
+
+        /* Third, fire things up! */
+        q = manager_coldplug(m);
+        if (q < 0)
+                r = q;
+
+        assert(m->n_reloading > 0);
+        m->n_reloading--;
+
+finish:
+        if (f)
+                fclose(f);
+
+        if (fds)
+                fdset_free(fds);
+
+        return r;
+}
+
+bool manager_is_booting_or_shutting_down(Manager *m) {
+        Unit *u;
+
+        assert(m);
+
+        /* Is the initial job still around? */
+        if (manager_get_job(m, m->default_unit_job_id))
+                return true;
+
+        /* Is there a job for the shutdown target? */
+        u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
+        if (u)
+                return !!u->job;
+
+        return false;
+}
+
+void manager_reset_failed(Manager *m) {
+        Unit *u;
+        Iterator i;
+
+        assert(m);
+
+        HASHMAP_FOREACH(u, m->units, i)
+                unit_reset_failed(u);
+}
+
+bool manager_unit_pending_inactive(Manager *m, const char *name) {
+        Unit *u;
+
+        assert(m);
+        assert(name);
+
+        /* Returns true if the unit is inactive or going down */
+        u = manager_get_unit(m, name);
+        if (!u)
+                return true;
+
+        return unit_pending_inactive(u);
+}
+
+void manager_check_finished(Manager *m) {
+        char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
+        usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
+
+        assert(m);
+
+        if (hashmap_size(m->jobs) > 0)
+                return;
+
+        /* Notify Type=idle units that we are done now */
+        close_pipe(m->idle_pipe);
+
+        /* Turn off confirm spawn now */
+        m->confirm_spawn = false;
+
+        if (dual_timestamp_is_set(&m->finish_timestamp))
+                return;
+
+        dual_timestamp_get(&m->finish_timestamp);
+
+        if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) {
+
+                /* Note that m->kernel_usec.monotonic is always at 0,
+                 * and m->firmware_usec.monotonic and
+                 * m->loader_usec.monotonic should be considered
+                 * negative values. */
+
+                firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic;
+                loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic;
+                userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
+                total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic;
+
+                if (dual_timestamp_is_set(&m->initrd_timestamp)) {
+
+                        kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic;
+                        initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
+
+                        if (!log_on_console())
+                                log_struct(LOG_INFO,
+                                           MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
+                                           "KERNEL_USEC=%llu", (unsigned long long) kernel_usec,
+                                           "INITRD_USEC=%llu", (unsigned long long) initrd_usec,
+                                           "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
+                                           "MESSAGE=Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
+                                           format_timespan(kernel, sizeof(kernel), kernel_usec),
+                                           format_timespan(initrd, sizeof(initrd), initrd_usec),
+                                           format_timespan(userspace, sizeof(userspace), userspace_usec),
+                                           format_timespan(sum, sizeof(sum), total_usec),
+                                           NULL);
+                } else {
+                        kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic;
+                        initrd_usec = 0;
+
+                        if (!log_on_console())
+                                log_struct(LOG_INFO,
+                                           MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
+                                           "KERNEL_USEC=%llu", (unsigned long long) kernel_usec,
+                                           "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
+                                           "MESSAGE=Startup finished in %s (kernel) + %s (userspace) = %s.",
+                                           format_timespan(kernel, sizeof(kernel), kernel_usec),
+                                           format_timespan(userspace, sizeof(userspace), userspace_usec),
+                                           format_timespan(sum, sizeof(sum), total_usec),
+                                           NULL);
+                }
+        } else {
+                firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
+                total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
+
+                if (!log_on_console())
+                        log_struct(LOG_INFO,
+                                   MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
+                                   "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
+                                   "MESSAGE=Startup finished in %s.",
+                                   format_timespan(sum, sizeof(sum), total_usec),
+                                   NULL);
+        }
+
+        bus_broadcast_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
+
+        sd_notifyf(false,
+                   "READY=1\nSTATUS=Startup finished in %s.",
+                   format_timespan(sum, sizeof(sum), total_usec));
+}
+
+static int create_generator_dir(Manager *m, char **generator, const char *name) {
+        char *p;
+        int r;
+
+        assert(m);
+        assert(generator);
+        assert(name);
+
+        if (*generator)
+                return 0;
+
+        if (m->running_as == SYSTEMD_SYSTEM && getpid() == 1) {
+
+                p = strappend("/run/systemd/", name);
+                if (!p)
+                        return log_oom();
+
+                r = mkdir_p_label(p, 0755);
+                if (r < 0) {
+                        log_error("Failed to create generator directory: %s", strerror(-r));
+                        free(p);
+                        return r;
+                }
+        } else {
+                p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL);
+                if (!p)
+                        return log_oom();
+
+                if (!mkdtemp(p)) {
+                        free(p);
+                        log_error("Failed to create generator directory: %m");
+                        return -errno;
+                }
+        }
+
+        *generator = p;
+        return 0;
+}
+
+static void trim_generator_dir(Manager *m, char **generator) {
+        assert(m);
+        assert(generator);
+
+        if (!*generator)
+                return;
+
+        if (rmdir(*generator) >= 0) {
+                free(*generator);
+                *generator = NULL;
+        }
+
+        return;
+}
+
+void manager_run_generators(Manager *m) {
+        DIR *d = NULL;
+        const char *generator_path;
+        const char *argv[5];
+        mode_t u;
+        int r;
+
+        assert(m);
+
+        generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
+        d = opendir(generator_path);
+        if (!d) {
+                if (errno == ENOENT)
+                        return;
+
+                log_error("Failed to enumerate generator directory: %m");
+                return;
+        }
+
+        r = create_generator_dir(m, &m->generator_unit_path, "generator");
+        if (r < 0)
+                goto finish;
+
+        r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early");
+        if (r < 0)
+                goto finish;
+
+        r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late");
+        if (r < 0)
+                goto finish;
+
+        argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
+        argv[1] = m->generator_unit_path;
+        argv[2] = m->generator_unit_path_early;
+        argv[3] = m->generator_unit_path_late;
+        argv[4] = NULL;
+
+        u = umask(0022);
+        execute_directory(generator_path, d, (char**) argv);
+        umask(u);
+
+        trim_generator_dir(m, &m->generator_unit_path);
+        trim_generator_dir(m, &m->generator_unit_path_early);
+        trim_generator_dir(m, &m->generator_unit_path_late);
+
+finish:
+        if (d)
+                closedir(d);
+}
+
+static void remove_generator_dir(Manager *m, char **generator) {
+        assert(m);
+        assert(generator);
+
+        if (!*generator)
+                return;
+
+        strv_remove(m->lookup_paths.unit_path, *generator);
+        rm_rf(*generator, false, true, false);
+
+        free(*generator);
+        *generator = NULL;
+}
+
+void manager_undo_generators(Manager *m) {
+        assert(m);
+
+        remove_generator_dir(m, &m->generator_unit_path);
+        remove_generator_dir(m, &m->generator_unit_path_early);
+        remove_generator_dir(m, &m->generator_unit_path_late);
+}
+
+int manager_set_default_controllers(Manager *m, char **controllers) {
+        char **l;
+
+        assert(m);
+
+        l = strv_copy(controllers);
+        if (!l)
+                return -ENOMEM;
+
+        strv_free(m->default_controllers);
+        m->default_controllers = l;
+
+        cg_shorten_controllers(m->default_controllers);
+
+        return 0;
+}
+
+int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
+        int i;
+
+        assert(m);
+
+        for (i = 0; i < RLIMIT_NLIMITS; i++) {
+                if (!default_rlimit[i])
+                        continue;
+
+                m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
+                if (!m->rlimit[i])
+                        return -ENOMEM;
+        }
+
+        return 0;
+}
+
+void manager_recheck_journal(Manager *m) {
+        Unit *u;
+
+        assert(m);
+
+        if (m->running_as != SYSTEMD_SYSTEM)
+                return;
+
+        u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
+        if (u && SOCKET(u)->state != SOCKET_RUNNING) {
+                log_close_journal();
+                return;
+        }
+
+        u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
+        if (u && SERVICE(u)->state != SERVICE_RUNNING) {
+                log_close_journal();
+                return;
+        }
+
+        /* Hmm, OK, so the socket is fully up and the service is up
+         * too, then let's make use of the thing. */
+        log_open();
+}
+
+void manager_set_show_status(Manager *m, bool b) {
+        assert(m);
+
+        if (m->running_as != SYSTEMD_SYSTEM)
+                return;
+
+        m->show_status = b;
+
+        if (b)
+                touch("/run/systemd/show-status");
+        else
+                unlink("/run/systemd/show-status");
+}
+
+bool manager_get_show_status(Manager *m) {
+        assert(m);
+
+        if (m->running_as != SYSTEMD_SYSTEM)
+                return false;
+
+        if (m->show_status)
+                return true;
+
+        /* If Plymouth is running make sure we show the status, so
+         * that there's something nice to see when people press Esc */
+
+        return plymouth_running();
+}
+
+void watch_init(Watch *w) {
+        assert(w);
+
+        w->type = WATCH_INVALID;
+        w->fd = -1;
+}
diff --git a/src/core/manager.h b/src/core/manager.h
new file mode 100644 (file)
index 0000000..cc4edf8
--- /dev/null
@@ -0,0 +1,298 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <dbus/dbus.h>
+
+#include "fdset.h"
+
+/* Enforce upper limit how many names we allow */
+#define MANAGER_MAX_NAMES 131072 /* 128K */
+
+typedef struct Manager Manager;
+typedef enum WatchType WatchType;
+typedef struct Watch Watch;
+
+typedef enum ManagerExitCode {
+        MANAGER_RUNNING,
+        MANAGER_EXIT,
+        MANAGER_RELOAD,
+        MANAGER_REEXECUTE,
+        MANAGER_REBOOT,
+        MANAGER_POWEROFF,
+        MANAGER_HALT,
+        MANAGER_KEXEC,
+        MANAGER_SWITCH_ROOT,
+        _MANAGER_EXIT_CODE_MAX,
+        _MANAGER_EXIT_CODE_INVALID = -1
+} ManagerExitCode;
+
+enum WatchType {
+        WATCH_INVALID,
+        WATCH_SIGNAL,
+        WATCH_NOTIFY,
+        WATCH_FD,
+        WATCH_UNIT_TIMER,
+        WATCH_JOB_TIMER,
+        WATCH_MOUNT,
+        WATCH_SWAP,
+        WATCH_UDEV,
+        WATCH_DBUS_WATCH,
+        WATCH_DBUS_TIMEOUT,
+        WATCH_TIME_CHANGE
+};
+
+struct Watch {
+        int fd;
+        WatchType type;
+        union {
+                struct Unit *unit;
+                struct Job *job;
+                DBusWatch *bus_watch;
+                DBusTimeout *bus_timeout;
+        } data;
+        bool fd_is_dupped:1;
+        bool socket_accept:1;
+};
+
+#include "unit.h"
+#include "job.h"
+#include "hashmap.h"
+#include "list.h"
+#include "set.h"
+#include "dbus.h"
+#include "path-lookup.h"
+
+struct Manager {
+        /* Note that the set of units we know of is allowed to be
+         * inconsistent. However the subset of it that is loaded may
+         * not, and the list of jobs may neither. */
+
+        /* Active jobs and units */
+        Hashmap *units;  /* name string => Unit object n:1 */
+        Hashmap *jobs;   /* job id => Job object 1:1 */
+
+        /* To make it easy to iterate through the units of a specific
+         * type we maintain a per type linked list */
+        LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]);
+
+        /* To optimize iteration of units that have requires_mounts_for set */
+        LIST_HEAD(Unit, has_requires_mounts_for);
+
+        /* Units that need to be loaded */
+        LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */
+
+        /* Jobs that need to be run */
+        LIST_HEAD(Job, run_queue);   /* more a stack than a queue, too */
+
+        /* Units and jobs that have not yet been announced via
+         * D-Bus. When something about a job changes it is added here
+         * if it is not in there yet. This allows easy coalescing of
+         * D-Bus change signals. */
+        LIST_HEAD(Unit, dbus_unit_queue);
+        LIST_HEAD(Job, dbus_job_queue);
+
+        /* Units to remove */
+        LIST_HEAD(Unit, cleanup_queue);
+
+        /* Units to check when doing GC */
+        LIST_HEAD(Unit, gc_queue);
+
+        Hashmap *watch_pids;  /* pid => Unit object n:1 */
+
+        char *notify_socket;
+
+        Watch notify_watch;
+        Watch signal_watch;
+        Watch time_change_watch;
+
+        int epoll_fd;
+
+        unsigned n_snapshots;
+
+        LookupPaths lookup_paths;
+        Set *unit_path_cache;
+
+        char **environment;
+        char **default_controllers;
+
+        usec_t runtime_watchdog;
+        usec_t shutdown_watchdog;
+
+        dual_timestamp firmware_timestamp;
+        dual_timestamp loader_timestamp;
+        dual_timestamp kernel_timestamp;
+        dual_timestamp initrd_timestamp;
+        dual_timestamp userspace_timestamp;
+        dual_timestamp finish_timestamp;
+
+        char *generator_unit_path;
+        char *generator_unit_path_early;
+        char *generator_unit_path_late;
+
+        /* Data specific to the device subsystem */
+        struct udev* udev;
+        struct udev_monitor* udev_monitor;
+        Watch udev_watch;
+        Hashmap *devices_by_sysfs;
+
+        /* Data specific to the mount subsystem */
+        FILE *proc_self_mountinfo;
+        Watch mount_watch;
+
+        /* Data specific to the swap filesystem */
+        FILE *proc_swaps;
+        Hashmap *swaps_by_proc_swaps;
+        bool request_reload;
+        Watch swap_watch;
+
+        /* Data specific to the D-Bus subsystem */
+        DBusConnection *api_bus, *system_bus;
+        DBusServer *private_bus;
+        Set *bus_connections, *bus_connections_for_dispatch;
+
+        DBusMessage *queued_message; /* This is used during reloading:
+                                      * before the reload we queue the
+                                      * reply message here, and
+                                      * afterwards we send it */
+        DBusConnection *queued_message_connection; /* The connection to send the queued message on */
+
+        Hashmap *watch_bus;  /* D-Bus names => Unit object n:1 */
+        int32_t name_data_slot;
+        int32_t conn_data_slot;
+        int32_t subscribed_data_slot;
+
+        uint32_t current_job_id;
+        uint32_t default_unit_job_id;
+
+        /* Data specific to the Automount subsystem */
+        int dev_autofs_fd;
+
+        /* Data specific to the cgroup subsystem */
+        Hashmap *cgroup_bondings; /* path string => CGroupBonding object 1:n */
+        char *cgroup_hierarchy;
+
+        usec_t gc_queue_timestamp;
+        int gc_marker;
+        unsigned n_in_gc_queue;
+
+        /* Make sure the user cannot accidentally unmount our cgroup
+         * file system */
+        int pin_cgroupfs_fd;
+
+        /* Flags */
+        SystemdRunningAs running_as;
+        ManagerExitCode exit_code:5;
+
+        bool dispatching_load_queue:1;
+        bool dispatching_run_queue:1;
+        bool dispatching_dbus_queue:1;
+
+        bool taint_usr:1;
+
+        bool show_status;
+        bool confirm_spawn;
+
+        ExecOutput default_std_output, default_std_error;
+
+        struct rlimit *rlimit[RLIMIT_NLIMITS];
+
+        /* non-zero if we are reloading or reexecuting, */
+        int n_reloading;
+
+        unsigned n_installed_jobs;
+        unsigned n_failed_jobs;
+
+        /* Type=idle pipes */
+        int idle_pipe[2];
+
+        char *switch_root;
+        char *switch_root_init;
+};
+
+int manager_new(SystemdRunningAs running_as, Manager **m);
+void manager_free(Manager *m);
+
+int manager_enumerate(Manager *m);
+int manager_coldplug(Manager *m);
+int manager_startup(Manager *m, FILE *serialization, FDSet *fds);
+
+Job *manager_get_job(Manager *m, uint32_t id);
+Unit *manager_get_unit(Manager *m, const char *name);
+
+int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j);
+
+int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret);
+int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret);
+int manager_load_unit_from_dbus_path(Manager *m, const char *s, DBusError *e, Unit **_u);
+
+int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool force, DBusError *e, Job **_ret);
+int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool force, DBusError *e, Job **_ret);
+
+void manager_dump_units(Manager *s, FILE *f, const char *prefix);
+void manager_dump_jobs(Manager *s, FILE *f, const char *prefix);
+
+void manager_clear_jobs(Manager *m);
+
+unsigned manager_dispatch_load_queue(Manager *m);
+unsigned manager_dispatch_run_queue(Manager *m);
+unsigned manager_dispatch_dbus_queue(Manager *m);
+
+int manager_set_default_controllers(Manager *m, char **controllers);
+int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
+
+int manager_loop(Manager *m);
+
+void manager_dispatch_bus_name_owner_changed(Manager *m, const char *name, const char* old_owner, const char *new_owner);
+void manager_dispatch_bus_query_pid_done(Manager *m, const char *name, pid_t pid);
+
+int manager_open_serialization(Manager *m, FILE **_f);
+
+int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs);
+int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
+int manager_distribute_fds(Manager *m, FDSet *fds);
+
+int manager_reload(Manager *m);
+
+bool manager_is_booting_or_shutting_down(Manager *m);
+
+void manager_reset_failed(Manager *m);
+
+void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success);
+void manager_send_unit_plymouth(Manager *m, Unit *u);
+
+bool manager_unit_pending_inactive(Manager *m, const char *name);
+
+void manager_check_finished(Manager *m);
+
+void manager_run_generators(Manager *m);
+void manager_undo_generators(Manager *m);
+
+void manager_recheck_journal(Manager *m);
+
+void manager_set_show_status(Manager *m, bool b);
+bool manager_get_show_status(Manager *m);
+
+void watch_init(Watch *w);
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
new file mode 100644 (file)
index 0000000..98614d0
--- /dev/null
@@ -0,0 +1,441 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/mount.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+#include <assert.h>
+#include <unistd.h>
+#include <ftw.h>
+
+#include "mount-setup.h"
+#include "dev-setup.h"
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+#include "label.h"
+#include "set.h"
+#include "strv.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "missing.h"
+#include "virt.h"
+
+#ifndef TTY_GID
+#define TTY_GID 5
+#endif
+
+typedef enum MountMode {
+        MNT_NONE  =        0,
+        MNT_FATAL =        1 <<  0,
+        MNT_IN_CONTAINER = 1 <<  1,
+} MountMode;
+
+typedef struct MountPoint {
+        const char *what;
+        const char *where;
+        const char *type;
+        const char *options;
+        unsigned long flags;
+        bool (*condition_fn)(void);
+        MountMode mode;
+} MountPoint;
+
+/* The first three entries we might need before SELinux is up. The
+ * fourth (securityfs) is needed by IMA to load a custom policy. The
+ * other ones we can delay until SELinux and IMA are loaded. */
+#define N_EARLY_MOUNT 4
+
+static const MountPoint mount_table[] = {
+        { "proc",       "/proc",                     "proc",       NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
+          NULL,       MNT_FATAL|MNT_IN_CONTAINER },
+        { "sysfs",      "/sys",                      "sysfs",      NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
+          NULL,       MNT_FATAL|MNT_IN_CONTAINER },
+        { "devtmpfs",   "/dev",                      "devtmpfs",   "mode=755", MS_NOSUID|MS_STRICTATIME,
+          NULL,       MNT_FATAL|MNT_IN_CONTAINER },
+        { "securityfs", "/sys/kernel/security",      "securityfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
+          NULL,       MNT_NONE },
+        { "efivarfs",   "/sys/firmware/efi/efivars", "efivarfs",   NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
+          is_efiboot, MNT_NONE },
+        { "tmpfs",      "/dev/shm",                  "tmpfs",      "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+          NULL,       MNT_FATAL|MNT_IN_CONTAINER },
+        { "devpts",     "/dev/pts",                  "devpts",     "mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC,
+          NULL,       MNT_IN_CONTAINER },
+        { "tmpfs",      "/run",                      "tmpfs",      "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+          NULL,       MNT_FATAL|MNT_IN_CONTAINER },
+        { "tmpfs",      "/sys/fs/cgroup",            "tmpfs",      "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
+          NULL,       MNT_IN_CONTAINER },
+        { "cgroup",     "/sys/fs/cgroup/systemd",    "cgroup",     "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV,
+          NULL,       MNT_IN_CONTAINER },
+};
+
+/* These are API file systems that might be mounted by other software,
+ * we just list them here so that we know that we should ignore them */
+
+static const char ignore_paths[] =
+        /* SELinux file systems */
+        "/sys/fs/selinux\0"
+        "/selinux\0"
+        /* Legacy cgroup mount points */
+        "/dev/cgroup\0"
+        "/cgroup\0"
+        /* Legacy kernel file system */
+        "/proc/bus/usb\0"
+        /* Container bind mounts */
+        "/proc/sys\0"
+        "/dev/console\0"
+        "/proc/kmsg\0";
+
+bool mount_point_is_api(const char *path) {
+        unsigned i;
+
+        /* Checks if this mount point is considered "API", and hence
+         * should be ignored */
+
+        for (i = 0; i < ELEMENTSOF(mount_table); i ++)
+                if (path_equal(path, mount_table[i].where))
+                        return true;
+
+        return path_startswith(path, "/sys/fs/cgroup/");
+}
+
+bool mount_point_ignore(const char *path) {
+        const char *i;
+
+        NULSTR_FOREACH(i, ignore_paths)
+                if (path_equal(path, i))
+                        return true;
+
+        return false;
+}
+
+static int mount_one(const MountPoint *p, bool relabel) {
+        int r;
+
+        assert(p);
+
+        if (p->condition_fn && !p->condition_fn())
+                return 0;
+
+        /* Relabel first, just in case */
+        if (relabel)
+                label_fix(p->where, true, true);
+
+        r = path_is_mount_point(p->where, true);
+        if (r < 0)
+                return r;
+
+        if (r > 0)
+                return 0;
+
+        /* Skip securityfs in a container */
+        if (!(p->mode & MNT_IN_CONTAINER) && detect_container(NULL) > 0)
+                return 0;
+
+        /* The access mode here doesn't really matter too much, since
+         * the mounted file system will take precedence anyway. */
+        mkdir_p_label(p->where, 0755);
+
+        log_debug("Mounting %s to %s of type %s with options %s.",
+                  p->what,
+                  p->where,
+                  p->type,
+                  strna(p->options));
+
+        if (mount(p->what,
+                  p->where,
+                  p->type,
+                  p->flags,
+                  p->options) < 0) {
+                log_full((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, "Failed to mount %s: %s", p->where, strerror(errno));
+                return (p->mode & MNT_FATAL) ? -errno : 0;
+        }
+
+        /* Relabel again, since we now mounted something fresh here */
+        if (relabel)
+                label_fix(p->where, false, false);
+
+        return 1;
+}
+
+int mount_setup_early(void) {
+        unsigned i;
+        int r = 0;
+
+        assert_cc(N_EARLY_MOUNT <= ELEMENTSOF(mount_table));
+
+        /* Do a minimal mount of /proc and friends to enable the most
+         * basic stuff, such as SELinux */
+        for (i = 0; i < N_EARLY_MOUNT; i ++)  {
+                int j;
+
+                j = mount_one(mount_table + i, false);
+                if (r == 0)
+                        r = j;
+        }
+
+        return r;
+}
+
+int mount_cgroup_controllers(char ***join_controllers) {
+        int r;
+        FILE *f;
+        char buf[LINE_MAX];
+        Set *controllers;
+
+        /* Mount all available cgroup controllers that are built into the kernel. */
+
+        f = fopen("/proc/cgroups", "re");
+        if (!f) {
+                log_error("Failed to enumerate cgroup controllers: %m");
+                return 0;
+        }
+
+        controllers = set_new(string_hash_func, string_compare_func);
+        if (!controllers) {
+                r = log_oom();
+                goto finish;
+        }
+
+        /* Ignore the header line */
+        (void) fgets(buf, sizeof(buf), f);
+
+        for (;;) {
+                char *controller;
+                int enabled = 0;
+
+                if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) {
+
+                        if (feof(f))
+                                break;
+
+                        log_error("Failed to parse /proc/cgroups.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if (!enabled) {
+                        free(controller);
+                        continue;
+                }
+
+                r = set_put(controllers, controller);
+                if (r < 0) {
+                        log_error("Failed to add controller to set.");
+                        free(controller);
+                        goto finish;
+                }
+        }
+
+        for (;;) {
+                MountPoint p;
+                char *controller, *where, *options;
+                char ***k = NULL;
+
+                controller = set_steal_first(controllers);
+                if (!controller)
+                        break;
+
+                if (join_controllers)
+                        for (k = join_controllers; *k; k++)
+                                if (strv_find(*k, controller))
+                                        break;
+
+                if (k && *k) {
+                        char **i, **j;
+
+                        for (i = *k, j = *k; *i; i++) {
+
+                                if (!streq(*i, controller)) {
+                                        char *t;
+
+                                        t = set_remove(controllers, *i);
+                                        if (!t) {
+                                                free(*i);
+                                                continue;
+                                        }
+                                        free(t);
+                                }
+
+                                *(j++) = *i;
+                        }
+
+                        *j = NULL;
+
+                        options = strv_join(*k, ",");
+                        if (!options) {
+                                free(controller);
+                                r = log_oom();
+                                goto finish;
+                        }
+
+                } else {
+                        options = controller;
+                        controller = NULL;
+                }
+
+                where = strappend("/sys/fs/cgroup/", options);
+                if (!where) {
+                        free(options);
+                        r = log_oom();
+                        goto finish;
+                }
+
+                zero(p);
+                p.what = "cgroup";
+                p.where = where;
+                p.type = "cgroup";
+                p.options = options;
+                p.flags = MS_NOSUID|MS_NOEXEC|MS_NODEV;
+
+                r = mount_one(&p, true);
+                free(controller);
+                free(where);
+
+                if (r < 0) {
+                        free(options);
+                        goto finish;
+                }
+
+                if (r > 0 && k && *k) {
+                        char **i;
+
+                        for (i = *k; *i; i++) {
+                                char *t;
+
+                                t = strappend("/sys/fs/cgroup/", *i);
+                                if (!t) {
+                                        r = log_oom();
+                                        free(options);
+                                        goto finish;
+                                }
+
+                                r = symlink(options, t);
+                                free(t);
+
+                                if (r < 0 && errno != EEXIST) {
+                                        log_error("Failed to create symlink: %m");
+                                        r = -errno;
+                                        free(options);
+                                        goto finish;
+                                }
+                        }
+                }
+
+                free(options);
+        }
+
+        r = 0;
+
+finish:
+        set_free_free(controllers);
+
+        fclose(f);
+
+        return r;
+}
+
+static int nftw_cb(
+                const char *fpath,
+                const struct stat *sb,
+                int tflag,
+                struct FTW *ftwbuf) {
+
+        /* No need to label /dev twice in a row... */
+        if (_unlikely_(ftwbuf->level == 0))
+                return FTW_CONTINUE;
+
+        label_fix(fpath, false, false);
+
+        /* /run/initramfs is static data and big, no need to
+         * dynamically relabel its contents at boot... */
+        if (_unlikely_(ftwbuf->level == 1 &&
+                      tflag == FTW_D &&
+                      streq(fpath, "/run/initramfs")))
+                return FTW_SKIP_SUBTREE;
+
+        return FTW_CONTINUE;
+};
+
+int mount_setup(bool loaded_policy) {
+
+        static const char relabel[] =
+                "/run/initramfs/root-fsck\0"
+                "/run/initramfs/shutdown\0";
+
+        int r;
+        unsigned i;
+        const char *j;
+
+        for (i = 0; i < ELEMENTSOF(mount_table); i ++) {
+                r = mount_one(mount_table + i, true);
+
+                if (r < 0)
+                        return r;
+        }
+
+        /* Nodes in devtmpfs and /run need to be manually updated for
+         * the appropriate labels, after mounting. The other virtual
+         * API file systems like /sys and /proc do not need that, they
+         * use the same label for all their files. */
+        if (loaded_policy) {
+                usec_t before_relabel, after_relabel;
+                char timespan[FORMAT_TIMESPAN_MAX];
+
+                before_relabel = now(CLOCK_MONOTONIC);
+
+                nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+                nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+
+                /* Explicitly relabel these */
+                NULSTR_FOREACH(j, relabel)
+                        label_fix(j, true, false);
+
+                after_relabel = now(CLOCK_MONOTONIC);
+
+                log_info("Relabelled /dev and /run in %s.",
+                         format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel));
+        }
+
+        /* Create a few default symlinks, which are normally created
+         * by udevd, but some scripts might need them before we start
+         * udevd. */
+        dev_setup(NULL);
+
+        /* Mark the root directory as shared in regards to mount
+         * propagation. The kernel defaults to "private", but we think
+         * it makes more sense to have a default of "shared" so that
+         * nspawn and the container tools work out of the box. If
+         * specific setups need other settings they can reset the
+         * propagation mode to private if needed. */
+        if (detect_container(NULL) <= 0)
+                if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0)
+                        log_warning("Failed to set up the root directory for shared mount propagation: %m");
+
+        /* Create a few directories we always want around */
+        mkdir_label("/run/systemd", 0755);
+        mkdir_label("/run/systemd/system", 0755);
+
+        return 0;
+}
diff --git a/src/core/mount-setup.h b/src/core/mount-setup.h
new file mode 100644 (file)
index 0000000..4b521ad
--- /dev/null
@@ -0,0 +1,33 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+int mount_setup_early(void);
+
+int mount_setup(bool loaded_policy);
+
+int mount_cgroup_controllers(char ***join_controllers);
+
+bool mount_point_is_api(const char *path);
+bool mount_point_ignore(const char *path);
diff --git a/src/core/mount.c b/src/core/mount.c
new file mode 100644 (file)
index 0000000..5d2b010
--- /dev/null
@@ -0,0 +1,1952 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <stdio.h>
+#include <mntent.h>
+#include <sys/epoll.h>
+#include <signal.h>
+
+#include "unit.h"
+#include "mount.h"
+#include "load-fragment.h"
+#include "load-dropin.h"
+#include "log.h"
+#include "sd-messages.h"
+#include "strv.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "mount-setup.h"
+#include "unit-name.h"
+#include "dbus-mount.h"
+#include "special.h"
+#include "bus-errors.h"
+#include "exit-status.h"
+#include "def.h"
+
+static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
+        [MOUNT_DEAD] = UNIT_INACTIVE,
+        [MOUNT_MOUNTING] = UNIT_ACTIVATING,
+        [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE,
+        [MOUNT_MOUNTED] = UNIT_ACTIVE,
+        [MOUNT_REMOUNTING] = UNIT_RELOADING,
+        [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
+        [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING,
+        [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING,
+        [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING,
+        [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING,
+        [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
+        [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
+        [MOUNT_FAILED] = UNIT_FAILED
+};
+
+static void mount_init(Unit *u) {
+        Mount *m = MOUNT(u);
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        m->timeout_usec = DEFAULT_TIMEOUT_USEC;
+        m->directory_mode = 0755;
+
+        exec_context_init(&m->exec_context);
+
+        if (unit_has_name(u, "-.mount")) {
+                /* Don't allow start/stop for root directory */
+                UNIT(m)->refuse_manual_start = true;
+                UNIT(m)->refuse_manual_stop = true;
+        } else {
+                /* The stdio/kmsg bridge socket is on /, in order to avoid a
+                 * dep loop, don't use kmsg logging for -.mount */
+                m->exec_context.std_output = u->manager->default_std_output;
+                m->exec_context.std_error = u->manager->default_std_error;
+        }
+
+        kill_context_init(&m->kill_context);
+
+        /* We need to make sure that /bin/mount is always called in
+         * the same process group as us, so that the autofs kernel
+         * side doesn't send us another mount request while we are
+         * already trying to comply its last one. */
+        m->exec_context.same_pgrp = true;
+
+        m->timer_watch.type = WATCH_INVALID;
+
+        m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
+
+        UNIT(m)->ignore_on_isolate = true;
+}
+
+static void mount_unwatch_control_pid(Mount *m) {
+        assert(m);
+
+        if (m->control_pid <= 0)
+                return;
+
+        unit_unwatch_pid(UNIT(m), m->control_pid);
+        m->control_pid = 0;
+}
+
+static void mount_parameters_done(MountParameters *p) {
+        assert(p);
+
+        free(p->what);
+        free(p->options);
+        free(p->fstype);
+
+        p->what = p->options = p->fstype = NULL;
+}
+
+static void mount_done(Unit *u) {
+        Mount *m = MOUNT(u);
+
+        assert(m);
+
+        free(m->where);
+        m->where = NULL;
+
+        mount_parameters_done(&m->parameters_proc_self_mountinfo);
+        mount_parameters_done(&m->parameters_fragment);
+
+        exec_context_done(&m->exec_context);
+        exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
+        m->control_command = NULL;
+
+        mount_unwatch_control_pid(m);
+
+        unit_unwatch_timer(u, &m->timer_watch);
+}
+
+static MountParameters* get_mount_parameters_fragment(Mount *m) {
+        assert(m);
+
+        if (m->from_fragment)
+                return &m->parameters_fragment;
+
+        return NULL;
+}
+
+static MountParameters* get_mount_parameters(Mount *m) {
+        assert(m);
+
+        if (m->from_proc_self_mountinfo)
+                return &m->parameters_proc_self_mountinfo;
+
+        return get_mount_parameters_fragment(m);
+}
+
+static int mount_add_mount_links(Mount *m) {
+        Unit *other;
+        int r;
+        MountParameters *pm;
+
+        assert(m);
+
+        pm = get_mount_parameters_fragment(m);
+
+        /* Adds in links to other mount points that might lie below or
+         * above us in the hierarchy */
+
+        LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_MOUNT]) {
+                Mount *n = MOUNT(other);
+                MountParameters *pn;
+
+                if (n == m)
+                        continue;
+
+                if (UNIT(n)->load_state != UNIT_LOADED)
+                        continue;
+
+                pn = get_mount_parameters_fragment(n);
+
+                if (path_startswith(m->where, n->where)) {
+
+                        if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
+                                return r;
+
+                        if (pn)
+                                if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
+                                        return r;
+
+                } else if (path_startswith(n->where, m->where)) {
+
+                        if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
+                                return r;
+
+                        if (pm)
+                                if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
+                                        return r;
+
+                } else if (pm && pm->what && path_startswith(pm->what, n->where)) {
+
+                        if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
+                                return r;
+
+                        if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
+                                return r;
+
+                } else if (pn && pn->what && path_startswith(pn->what, m->where)) {
+
+                        if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
+                                return r;
+
+                        if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}
+
+static int mount_add_swap_links(Mount *m) {
+        Unit *other;
+        int r;
+
+        assert(m);
+
+        LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP]) {
+                r = swap_add_one_mount_link(SWAP(other), m);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int mount_add_path_links(Mount *m) {
+        Unit *other;
+        int r;
+
+        assert(m);
+
+        LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH]) {
+                r = path_add_one_mount_link(PATH(other), m);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int mount_add_automount_links(Mount *m) {
+        Unit *other;
+        int r;
+
+        assert(m);
+
+        LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT]) {
+                r = automount_add_one_mount_link(AUTOMOUNT(other), m);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int mount_add_socket_links(Mount *m) {
+        Unit *other;
+        int r;
+
+        assert(m);
+
+        LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET]) {
+                r = socket_add_one_mount_link(SOCKET(other), m);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int mount_add_requires_mounts_links(Mount *m) {
+        Unit *other;
+        int r;
+
+        assert(m);
+
+        LIST_FOREACH(has_requires_mounts_for, other, UNIT(m)->manager->has_requires_mounts_for) {
+                r = unit_add_one_mount_link(other, m);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static char* mount_test_option(const char *haystack, const char *needle) {
+        struct mntent me;
+
+        assert(needle);
+
+        /* Like glibc's hasmntopt(), but works on a string, not a
+         * struct mntent */
+
+        if (!haystack)
+                return NULL;
+
+        zero(me);
+        me.mnt_opts = (char*) haystack;
+
+        return hasmntopt(&me, needle);
+}
+
+static bool mount_is_network(MountParameters *p) {
+        assert(p);
+
+        if (mount_test_option(p->options, "_netdev"))
+                return true;
+
+        if (p->fstype && fstype_is_network(p->fstype))
+                return true;
+
+        return false;
+}
+
+static bool mount_is_bind(MountParameters *p) {
+        assert(p);
+
+        if (mount_test_option(p->options, "bind"))
+                return true;
+
+        if (p->fstype && streq(p->fstype, "bind"))
+                return true;
+
+        return false;
+}
+
+static bool needs_quota(MountParameters *p) {
+        assert(p);
+
+        if (mount_is_network(p))
+                return false;
+
+        if (mount_is_bind(p))
+                return false;
+
+        return mount_test_option(p->options, "usrquota") ||
+                mount_test_option(p->options, "grpquota") ||
+                mount_test_option(p->options, "quota") ||
+                mount_test_option(p->options, "usrjquota") ||
+                mount_test_option(p->options, "grpjquota");
+}
+
+static int mount_add_device_links(Mount *m) {
+        MountParameters *p;
+        int r;
+
+        assert(m);
+
+        p = get_mount_parameters_fragment(m);
+        if (!p)
+                return 0;
+
+        if (!p->what)
+                return 0;
+
+        if (mount_is_bind(p))
+                return 0;
+
+        if (!is_device_path(p->what))
+                return 0;
+
+        if (path_equal(m->where, "/"))
+                return 0;
+
+        r = unit_add_node_link(UNIT(m), p->what, false);
+        if (r < 0)
+                return r;
+
+        if (p->passno > 0 &&
+            UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) {
+                char *name;
+                Unit *fsck;
+                /* Let's add in the fsck service */
+
+                /* aka SPECIAL_FSCK_SERVICE */
+                name = unit_name_from_path_instance("systemd-fsck", p->what, ".service");
+                if (!name)
+                        return -ENOMEM;
+
+                r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck);
+                if (r < 0) {
+                        log_warning_unit(name,
+                                         "Failed to prepare unit %s: %s", name, strerror(-r));
+                        free(name);
+                        return r;
+                }
+                free(name);
+
+                SERVICE(fsck)->fsck_passno = p->passno;
+
+                r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_REQUIRES, fsck, true);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int mount_add_quota_links(Mount *m) {
+        int r;
+        MountParameters *p;
+
+        assert(m);
+
+        if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
+                return 0;
+
+        p = get_mount_parameters_fragment(m);
+        if (!p)
+                return 0;
+
+        if (!needs_quota(p))
+                return 0;
+
+        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
+        if (r < 0)
+                return r;
+
+        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int mount_add_default_dependencies(Mount *m) {
+        int r;
+        MountParameters *p;
+        const char *after;
+
+        assert(m);
+
+        if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
+                return 0;
+
+        p = get_mount_parameters_fragment(m);
+        if (!p)
+                return 0;
+
+        if (path_equal(m->where, "/"))
+                return 0;
+
+        if (mount_is_network(p))
+                after = SPECIAL_REMOTE_FS_PRE_TARGET;
+        else
+                after = SPECIAL_LOCAL_FS_PRE_TARGET;
+
+        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, after, NULL, true);
+        if (r < 0)
+                return r;
+
+        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int mount_fix_timeouts(Mount *m) {
+        MountParameters *p;
+        const char *timeout = NULL;
+        Unit *other;
+        Iterator i;
+        usec_t u;
+        char *t;
+        int r;
+
+        assert(m);
+
+        p = get_mount_parameters_fragment(m);
+        if (!p)
+                return 0;
+
+        /* Allow configuration how long we wait for a device that
+         * backs a mount point to show up. This is useful to support
+         * endless device timeouts for devices that show up only after
+         * user input, like crypto devices. */
+
+        if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout")))
+                timeout += 31;
+        else if ((timeout = mount_test_option(p->options, "x-systemd.device-timeout")))
+                timeout += 25;
+        else
+                return 0;
+
+        t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE));
+        if (!t)
+                return -ENOMEM;
+
+        r = parse_usec(t, &u);
+        free(t);
+
+        if (r < 0) {
+                log_warning_unit(UNIT(m)->id,
+                                 "Failed to parse timeout for %s, ignoring: %s",
+                                 m->where, timeout);
+                return r;
+        }
+
+        SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) {
+                if (other->type != UNIT_DEVICE)
+                        continue;
+
+                other->job_timeout = u;
+        }
+
+        return 0;
+}
+
+static int mount_verify(Mount *m) {
+        bool b;
+        char *e;
+        assert(m);
+
+        if (UNIT(m)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (!m->from_fragment && !m->from_proc_self_mountinfo)
+                return -ENOENT;
+
+        if (!(e = unit_name_from_path(m->where, ".mount")))
+                return -ENOMEM;
+
+        b = unit_has_name(UNIT(m), e);
+        free(e);
+
+        if (!b) {
+                log_error_unit(UNIT(m)->id,
+                               "%s's Where setting doesn't match unit name. Refusing.",
+                               UNIT(m)->id);
+                return -EINVAL;
+        }
+
+        if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
+                log_error_unit(UNIT(m)->id,
+                               "Cannot create mount unit for API file system %s. Refusing.",
+                               m->where);
+                return -EINVAL;
+        }
+
+        if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
+                log_error_unit(UNIT(m)->id,
+                               "%s's What setting is missing. Refusing.", UNIT(m)->id);
+                return -EBADMSG;
+        }
+
+        if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
+                log_error_unit(UNIT(m)->id,
+                               "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",
+                               UNIT(m)->id);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static int mount_add_extras(Mount *m) {
+        Unit *u = UNIT(m);
+        int r;
+
+        if (UNIT(m)->fragment_path)
+                m->from_fragment = true;
+
+        if (!m->where) {
+                m->where = unit_name_to_path(u->id);
+                if (!m->where)
+                        return -ENOMEM;
+        }
+
+        path_kill_slashes(m->where);
+
+        r = unit_add_exec_dependencies(u, &m->exec_context);
+        if (r < 0)
+                return r;
+
+        if (!UNIT(m)->description) {
+                r = unit_set_description(u, m->where);
+                if (r < 0)
+                        return r;
+        }
+
+        r = mount_add_device_links(m);
+        if (r < 0)
+                return r;
+
+        r = mount_add_mount_links(m);
+        if (r < 0)
+                return r;
+
+        r = mount_add_socket_links(m);
+        if (r < 0)
+                return r;
+
+        r = mount_add_swap_links(m);
+        if (r < 0)
+                return r;
+
+        r = mount_add_path_links(m);
+        if (r < 0)
+                return r;
+
+        r = mount_add_requires_mounts_links(m);
+        if (r < 0)
+                return r;
+
+        r = mount_add_automount_links(m);
+        if (r < 0)
+                return r;
+
+        r = mount_add_quota_links(m);
+        if (r < 0)
+                return r;
+
+        if (UNIT(m)->default_dependencies) {
+                r = mount_add_default_dependencies(m);
+                if (r < 0)
+                        return r;
+        }
+
+        r = unit_add_default_cgroups(u);
+        if (r < 0)
+                return r;
+
+        r = mount_fix_timeouts(m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int mount_load(Unit *u) {
+        Mount *m = MOUNT(u);
+        int r;
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        if (m->from_proc_self_mountinfo)
+                r = unit_load_fragment_and_dropin_optional(u);
+        else
+                r = unit_load_fragment_and_dropin(u);
+
+        if (r < 0)
+                return r;
+
+        /* This is a new unit? Then let's add in some extras */
+        if (u->load_state == UNIT_LOADED) {
+                r = mount_add_extras(m);
+                if (r < 0)
+                        return r;
+
+                r = unit_exec_context_defaults(u, &m->exec_context);
+                if (r < 0)
+                        return r;
+        }
+
+        return mount_verify(m);
+}
+
+static int mount_notify_automount(Mount *m, int status) {
+        Unit *p;
+        int r;
+        Iterator i;
+
+        assert(m);
+
+        SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
+                if (p->type == UNIT_AUTOMOUNT) {
+                         r = automount_send_ready(AUTOMOUNT(p), status);
+                         if (r < 0)
+                                 return r;
+                }
+
+        return 0;
+}
+
+static void mount_set_state(Mount *m, MountState state) {
+        MountState old_state;
+        assert(m);
+
+        old_state = m->state;
+        m->state = state;
+
+        if (state != MOUNT_MOUNTING &&
+            state != MOUNT_MOUNTING_DONE &&
+            state != MOUNT_REMOUNTING &&
+            state != MOUNT_UNMOUNTING &&
+            state != MOUNT_MOUNTING_SIGTERM &&
+            state != MOUNT_MOUNTING_SIGKILL &&
+            state != MOUNT_UNMOUNTING_SIGTERM &&
+            state != MOUNT_UNMOUNTING_SIGKILL &&
+            state != MOUNT_REMOUNTING_SIGTERM &&
+            state != MOUNT_REMOUNTING_SIGKILL) {
+                unit_unwatch_timer(UNIT(m), &m->timer_watch);
+                mount_unwatch_control_pid(m);
+                m->control_command = NULL;
+                m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
+        }
+
+        if (state == MOUNT_MOUNTED ||
+            state == MOUNT_REMOUNTING)
+                mount_notify_automount(m, 0);
+        else if (state == MOUNT_DEAD ||
+                 state == MOUNT_UNMOUNTING ||
+                 state == MOUNT_MOUNTING_SIGTERM ||
+                 state == MOUNT_MOUNTING_SIGKILL ||
+                 state == MOUNT_REMOUNTING_SIGTERM ||
+                 state == MOUNT_REMOUNTING_SIGKILL ||
+                 state == MOUNT_UNMOUNTING_SIGTERM ||
+                 state == MOUNT_UNMOUNTING_SIGKILL ||
+                 state == MOUNT_FAILED) {
+               if (state != old_state)
+                       mount_notify_automount(m, -ENODEV);
+       }
+
+        if (state != old_state)
+                log_debug_unit(UNIT(m)->id,
+                               "%s changed %s -> %s",
+                               UNIT(m)->id,
+                               mount_state_to_string(old_state),
+                               mount_state_to_string(state));
+
+        unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
+        m->reload_result = MOUNT_SUCCESS;
+}
+
+static int mount_coldplug(Unit *u) {
+        Mount *m = MOUNT(u);
+        MountState new_state = MOUNT_DEAD;
+        int r;
+
+        assert(m);
+        assert(m->state == MOUNT_DEAD);
+
+        if (m->deserialized_state != m->state)
+                new_state = m->deserialized_state;
+        else if (m->from_proc_self_mountinfo)
+                new_state = MOUNT_MOUNTED;
+
+        if (new_state != m->state) {
+
+                if (new_state == MOUNT_MOUNTING ||
+                    new_state == MOUNT_MOUNTING_DONE ||
+                    new_state == MOUNT_REMOUNTING ||
+                    new_state == MOUNT_UNMOUNTING ||
+                    new_state == MOUNT_MOUNTING_SIGTERM ||
+                    new_state == MOUNT_MOUNTING_SIGKILL ||
+                    new_state == MOUNT_UNMOUNTING_SIGTERM ||
+                    new_state == MOUNT_UNMOUNTING_SIGKILL ||
+                    new_state == MOUNT_REMOUNTING_SIGTERM ||
+                    new_state == MOUNT_REMOUNTING_SIGKILL) {
+
+                        if (m->control_pid <= 0)
+                                return -EBADMSG;
+
+                        r = unit_watch_pid(UNIT(m), m->control_pid);
+                        if (r < 0)
+                                return r;
+
+                        r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
+                        if (r < 0)
+                                return r;
+                }
+
+                mount_set_state(m, new_state);
+        }
+
+        return 0;
+}
+
+static void mount_dump(Unit *u, FILE *f, const char *prefix) {
+        Mount *m = MOUNT(u);
+        MountParameters *p;
+
+        assert(m);
+        assert(f);
+
+        p = get_mount_parameters(m);
+
+        fprintf(f,
+                "%sMount State: %s\n"
+                "%sResult: %s\n"
+                "%sWhere: %s\n"
+                "%sWhat: %s\n"
+                "%sFile System Type: %s\n"
+                "%sOptions: %s\n"
+                "%sFrom /proc/self/mountinfo: %s\n"
+                "%sFrom fragment: %s\n"
+                "%sDirectoryMode: %04o\n",
+                prefix, mount_state_to_string(m->state),
+                prefix, mount_result_to_string(m->result),
+                prefix, m->where,
+                prefix, strna(p->what),
+                prefix, strna(p->fstype),
+                prefix, strna(p->options),
+                prefix, yes_no(m->from_proc_self_mountinfo),
+                prefix, yes_no(m->from_fragment),
+                prefix, m->directory_mode);
+
+        if (m->control_pid > 0)
+                fprintf(f,
+                        "%sControl PID: %lu\n",
+                        prefix, (unsigned long) m->control_pid);
+
+        exec_context_dump(&m->exec_context, f, prefix);
+        kill_context_dump(&m->kill_context, f, prefix);
+}
+
+static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
+        pid_t pid;
+        int r;
+
+        assert(m);
+        assert(c);
+        assert(_pid);
+
+        r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
+        if (r < 0)
+                goto fail;
+
+        if ((r = exec_spawn(c,
+                            NULL,
+                            &m->exec_context,
+                            NULL, 0,
+                            UNIT(m)->manager->environment,
+                            true,
+                            true,
+                            true,
+                            UNIT(m)->manager->confirm_spawn,
+                            UNIT(m)->cgroup_bondings,
+                            UNIT(m)->cgroup_attributes,
+                            NULL,
+                            UNIT(m)->id,
+                            NULL,
+                            &pid)) < 0)
+                goto fail;
+
+        if ((r = unit_watch_pid(UNIT(m), pid)) < 0)
+                /* FIXME: we need to do something here */
+                goto fail;
+
+        *_pid = pid;
+
+        return 0;
+
+fail:
+        unit_unwatch_timer(UNIT(m), &m->timer_watch);
+
+        return r;
+}
+
+static void mount_enter_dead(Mount *m, MountResult f) {
+        assert(m);
+
+        if (f != MOUNT_SUCCESS)
+                m->result = f;
+
+        mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
+}
+
+static void mount_enter_mounted(Mount *m, MountResult f) {
+        assert(m);
+
+        if (f != MOUNT_SUCCESS)
+                m->result = f;
+
+        mount_set_state(m, MOUNT_MOUNTED);
+}
+
+static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
+        int r;
+        Set *pid_set = NULL;
+        bool wait_for_exit = false;
+
+        assert(m);
+
+        if (f != MOUNT_SUCCESS)
+                m->result = f;
+
+        if (m->kill_context.kill_mode != KILL_NONE) {
+                int sig = (state == MOUNT_MOUNTING_SIGTERM ||
+                           state == MOUNT_UNMOUNTING_SIGTERM ||
+                           state == MOUNT_REMOUNTING_SIGTERM) ? m->kill_context.kill_signal : SIGKILL;
+
+                if (m->control_pid > 0) {
+                        if (kill_and_sigcont(m->control_pid, sig) < 0 && errno != ESRCH)
+
+                                log_warning_unit(UNIT(m)->id,
+                                                 "Failed to kill control process %li: %m",
+                                                 (long) m->control_pid);
+                        else
+                                wait_for_exit = true;
+                }
+
+                if (m->kill_context.kill_mode == KILL_CONTROL_GROUP) {
+
+                        if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        /* Exclude the control pid from being killed via the cgroup */
+                        if (m->control_pid > 0)
+                                if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0)
+                                        goto fail;
+
+                        r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, false, pid_set, NULL);
+                        if (r < 0) {
+                                if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
+                                        log_warning_unit(UNIT(m)->id,
+                                                         "Failed to kill control group: %s",
+                                                         strerror(-r));
+                        } else if (r > 0)
+                                wait_for_exit = true;
+
+                        set_free(pid_set);
+                        pid_set = NULL;
+                }
+        }
+
+        if (wait_for_exit) {
+                r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
+                if (r < 0)
+                        goto fail;
+
+                mount_set_state(m, state);
+        } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
+                mount_enter_mounted(m, MOUNT_SUCCESS);
+        else
+                mount_enter_dead(m, MOUNT_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(m)->id,
+                         "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
+
+        if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
+                mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
+        else
+                mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
+
+        if (pid_set)
+                set_free(pid_set);
+}
+
+void warn_if_dir_nonempty(const char *unit, const char* where) {
+        if (dir_is_empty(where) > 0)
+                return;
+        log_struct(LOG_NOTICE,
+                   "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.",
+                   unit, where,
+                   "WHERE=%s", where,
+                   "_SYSTEMD_UNIT=%s", unit,
+                   MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
+                   NULL);
+}
+
+static void mount_enter_unmounting(Mount *m) {
+        int r;
+
+        assert(m);
+
+        m->control_command_id = MOUNT_EXEC_UNMOUNT;
+        m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
+
+        if ((r = exec_command_set(
+                             m->control_command,
+                             "/bin/umount",
+                             m->where,
+                             NULL)) < 0)
+                goto fail;
+
+        mount_unwatch_control_pid(m);
+
+        if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
+                goto fail;
+
+        mount_set_state(m, MOUNT_UNMOUNTING);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(m)->id,
+                         "%s failed to run 'umount' task: %s",
+                         UNIT(m)->id, strerror(-r));
+        mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
+}
+
+static void mount_enter_mounting(Mount *m) {
+        int r;
+        MountParameters *p;
+
+        assert(m);
+
+        m->control_command_id = MOUNT_EXEC_MOUNT;
+        m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
+
+        mkdir_p_label(m->where, m->directory_mode);
+
+        warn_if_dir_nonempty(m->meta.id, m->where);
+
+        /* Create the source directory for bind-mounts if needed */
+        p = get_mount_parameters_fragment(m);
+        if (p && mount_is_bind(p))
+                mkdir_p_label(p->what, m->directory_mode);
+
+        if (m->from_fragment)
+                r = exec_command_set(
+                                m->control_command,
+                                "/bin/mount",
+                                m->parameters_fragment.what,
+                                m->where,
+                                "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
+                                m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options,
+                                NULL);
+        else
+                r = -ENOENT;
+
+        if (r < 0)
+                goto fail;
+
+        mount_unwatch_control_pid(m);
+
+        r = mount_spawn(m, m->control_command, &m->control_pid);
+        if (r < 0)
+                goto fail;
+
+        mount_set_state(m, MOUNT_MOUNTING);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(m)->id,
+                         "%s failed to run 'mount' task: %s",
+                         UNIT(m)->id, strerror(-r));
+        mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
+}
+
+static void mount_enter_mounting_done(Mount *m) {
+        assert(m);
+
+        mount_set_state(m, MOUNT_MOUNTING_DONE);
+}
+
+static void mount_enter_remounting(Mount *m) {
+        int r;
+
+        assert(m);
+
+        m->control_command_id = MOUNT_EXEC_REMOUNT;
+        m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
+
+        if (m->from_fragment) {
+                char *buf = NULL;
+                const char *o;
+
+                if (m->parameters_fragment.options) {
+                        if (!(buf = strappend("remount,", m->parameters_fragment.options))) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        o = buf;
+                } else
+                        o = "remount";
+
+                r = exec_command_set(
+                                m->control_command,
+                                "/bin/mount",
+                                m->parameters_fragment.what,
+                                m->where,
+                                "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
+                                "-o", o,
+                                NULL);
+
+                free(buf);
+        } else
+                r = -ENOENT;
+
+        if (r < 0)
+                goto fail;
+
+        mount_unwatch_control_pid(m);
+
+        if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
+                goto fail;
+
+        mount_set_state(m, MOUNT_REMOUNTING);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(m)->id,
+                         "%s failed to run 'remount' task: %s",
+                         UNIT(m)->id, strerror(-r));
+        m->reload_result = MOUNT_FAILURE_RESOURCES;
+        mount_enter_mounted(m, MOUNT_SUCCESS);
+}
+
+static int mount_start(Unit *u) {
+        Mount *m = MOUNT(u);
+
+        assert(m);
+
+        /* We cannot fulfill this request right now, try again later
+         * please! */
+        if (m->state == MOUNT_UNMOUNTING ||
+            m->state == MOUNT_UNMOUNTING_SIGTERM ||
+            m->state == MOUNT_UNMOUNTING_SIGKILL ||
+            m->state == MOUNT_MOUNTING_SIGTERM ||
+            m->state == MOUNT_MOUNTING_SIGKILL)
+                return -EAGAIN;
+
+        /* Already on it! */
+        if (m->state == MOUNT_MOUNTING)
+                return 0;
+
+        assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
+
+        m->result = MOUNT_SUCCESS;
+        m->reload_result = MOUNT_SUCCESS;
+
+        mount_enter_mounting(m);
+        return 0;
+}
+
+static int mount_stop(Unit *u) {
+        Mount *m = MOUNT(u);
+
+        assert(m);
+
+        /* Already on it */
+        if (m->state == MOUNT_UNMOUNTING ||
+            m->state == MOUNT_UNMOUNTING_SIGKILL ||
+            m->state == MOUNT_UNMOUNTING_SIGTERM ||
+            m->state == MOUNT_MOUNTING_SIGTERM ||
+            m->state == MOUNT_MOUNTING_SIGKILL)
+                return 0;
+
+        assert(m->state == MOUNT_MOUNTING ||
+               m->state == MOUNT_MOUNTING_DONE ||
+               m->state == MOUNT_MOUNTED ||
+               m->state == MOUNT_REMOUNTING ||
+               m->state == MOUNT_REMOUNTING_SIGTERM ||
+               m->state == MOUNT_REMOUNTING_SIGKILL);
+
+        mount_enter_unmounting(m);
+        return 0;
+}
+
+static int mount_reload(Unit *u) {
+        Mount *m = MOUNT(u);
+
+        assert(m);
+
+        if (m->state == MOUNT_MOUNTING_DONE)
+                return -EAGAIN;
+
+        assert(m->state == MOUNT_MOUNTED);
+
+        mount_enter_remounting(m);
+        return 0;
+}
+
+static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Mount *m = MOUNT(u);
+
+        assert(m);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
+        unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
+        unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
+
+        if (m->control_pid > 0)
+                unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) m->control_pid);
+
+        if (m->control_command_id >= 0)
+                unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
+
+        return 0;
+}
+
+static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Mount *m = MOUNT(u);
+
+        assert(u);
+        assert(key);
+        assert(value);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                MountState state;
+
+                if ((state = mount_state_from_string(value)) < 0)
+                        log_debug_unit(u->id, "Failed to parse state value %s", value);
+                else
+                        m->deserialized_state = state;
+        } else if (streq(key, "result")) {
+                MountResult f;
+
+                f = mount_result_from_string(value);
+                if (f < 0)
+                        log_debug_unit(UNIT(m)->id,
+                                       "Failed to parse result value %s", value);
+                else if (f != MOUNT_SUCCESS)
+                        m->result = f;
+
+        } else if (streq(key, "reload-result")) {
+                MountResult f;
+
+                f = mount_result_from_string(value);
+                if (f < 0)
+                        log_debug_unit(UNIT(m)->id,
+                                       "Failed to parse reload result value %s", value);
+                else if (f != MOUNT_SUCCESS)
+                        m->reload_result = f;
+
+        } else if (streq(key, "control-pid")) {
+                pid_t pid;
+
+                if (parse_pid(value, &pid) < 0)
+                        log_debug_unit(UNIT(m)->id,
+                                       "Failed to parse control-pid value %s", value);
+                else
+                        m->control_pid = pid;
+        } else if (streq(key, "control-command")) {
+                MountExecCommand id;
+
+                if ((id = mount_exec_command_from_string(value)) < 0)
+                        log_debug_unit(UNIT(m)->id,
+                                       "Failed to parse exec-command value %s", value);
+                else {
+                        m->control_command_id = id;
+                        m->control_command = m->exec_command + id;
+                }
+
+        } else
+                log_debug_unit(UNIT(m)->id,
+                               "Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static UnitActiveState mount_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[MOUNT(u)->state];
+}
+
+static const char *mount_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return mount_state_to_string(MOUNT(u)->state);
+}
+
+static bool mount_check_gc(Unit *u) {
+        Mount *m = MOUNT(u);
+
+        assert(m);
+
+        return m->from_proc_self_mountinfo;
+}
+
+static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+        Mount *m = MOUNT(u);
+        MountResult f;
+
+        assert(m);
+        assert(pid >= 0);
+
+        if (pid != m->control_pid)
+                return;
+
+        m->control_pid = 0;
+
+        if (is_clean_exit(code, status, NULL))
+                f = MOUNT_SUCCESS;
+        else if (code == CLD_EXITED)
+                f = MOUNT_FAILURE_EXIT_CODE;
+        else if (code == CLD_KILLED)
+                f = MOUNT_FAILURE_SIGNAL;
+        else if (code == CLD_DUMPED)
+                f = MOUNT_FAILURE_CORE_DUMP;
+        else
+                assert_not_reached("Unknown code");
+
+        if (f != MOUNT_SUCCESS)
+                m->result = f;
+
+        if (m->control_command) {
+                exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
+
+                m->control_command = NULL;
+                m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
+        }
+
+        log_full_unit(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id,
+                      "%s mount process exited, code=%s status=%i",
+                      u->id, sigchld_code_to_string(code), status);
+
+        /* Note that mount(8) returning and the kernel sending us a
+         * mount table change event might happen out-of-order. If an
+         * operation succeed we assume the kernel will follow soon too
+         * and already change into the resulting state.  If it fails
+         * we check if the kernel still knows about the mount. and
+         * change state accordingly. */
+
+        switch (m->state) {
+
+        case MOUNT_MOUNTING:
+        case MOUNT_MOUNTING_DONE:
+        case MOUNT_MOUNTING_SIGKILL:
+        case MOUNT_MOUNTING_SIGTERM:
+
+                if (f == MOUNT_SUCCESS)
+                        mount_enter_mounted(m, f);
+                else if (m->from_proc_self_mountinfo)
+                        mount_enter_mounted(m, f);
+                else
+                        mount_enter_dead(m, f);
+                break;
+
+        case MOUNT_REMOUNTING:
+        case MOUNT_REMOUNTING_SIGKILL:
+        case MOUNT_REMOUNTING_SIGTERM:
+
+                m->reload_result = f;
+                if (m->from_proc_self_mountinfo)
+                        mount_enter_mounted(m, MOUNT_SUCCESS);
+                else
+                        mount_enter_dead(m, MOUNT_SUCCESS);
+
+                break;
+
+        case MOUNT_UNMOUNTING:
+        case MOUNT_UNMOUNTING_SIGKILL:
+        case MOUNT_UNMOUNTING_SIGTERM:
+
+                if (f == MOUNT_SUCCESS)
+                        mount_enter_dead(m, f);
+                else if (m->from_proc_self_mountinfo)
+                        mount_enter_mounted(m, f);
+                else
+                        mount_enter_dead(m, f);
+                break;
+
+        default:
+                assert_not_reached("Uh, control process died at wrong time.");
+        }
+
+        /* Notify clients about changed exit status */
+        unit_add_to_dbus_queue(u);
+}
+
+static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
+        Mount *m = MOUNT(u);
+
+        assert(m);
+        assert(elapsed == 1);
+        assert(w == &m->timer_watch);
+
+        switch (m->state) {
+
+        case MOUNT_MOUNTING:
+        case MOUNT_MOUNTING_DONE:
+                log_warning_unit(u->id,
+                                 "%s mounting timed out. Stopping.", u->id);
+                mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
+                break;
+
+        case MOUNT_REMOUNTING:
+                log_warning_unit(u->id,
+                                 "%s remounting timed out. Stopping.", u->id);
+                m->reload_result = MOUNT_FAILURE_TIMEOUT;
+                mount_enter_mounted(m, MOUNT_SUCCESS);
+                break;
+
+        case MOUNT_UNMOUNTING:
+                log_warning_unit(u->id,
+                                 "%s unmounting timed out. Stopping.", u->id);
+                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
+                break;
+
+        case MOUNT_MOUNTING_SIGTERM:
+                if (m->kill_context.send_sigkill) {
+                        log_warning_unit(u->id,
+                                         "%s mounting timed out. Killing.", u->id);
+                        mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id,
+                                         "%s mounting timed out. Skipping SIGKILL. Ignoring.",
+                                         u->id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
+                        else
+                                mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
+                }
+                break;
+
+        case MOUNT_REMOUNTING_SIGTERM:
+                if (m->kill_context.send_sigkill) {
+                        log_warning_unit(u->id,
+                                         "%s remounting timed out. Killing.", u->id);
+                        mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id,
+                                         "%s remounting timed out. Skipping SIGKILL. Ignoring.",
+                                         u->id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
+                        else
+                                mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
+                }
+                break;
+
+        case MOUNT_UNMOUNTING_SIGTERM:
+                if (m->kill_context.send_sigkill) {
+                        log_warning_unit(u->id,
+                                         "%s unmounting timed out. Killing.", u->id);
+                        mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id,
+                                         "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
+                                         u->id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
+                        else
+                                mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
+                }
+                break;
+
+        case MOUNT_MOUNTING_SIGKILL:
+        case MOUNT_REMOUNTING_SIGKILL:
+        case MOUNT_UNMOUNTING_SIGKILL:
+                log_warning_unit(u->id,
+                                 "%s mount process still around after SIGKILL. Ignoring.",
+                                 u->id);
+
+                if (m->from_proc_self_mountinfo)
+                        mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
+                else
+                        mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
+                break;
+
+        default:
+                assert_not_reached("Timeout at wrong time.");
+        }
+}
+
+static int mount_add_one(
+                Manager *m,
+                const char *what,
+                const char *where,
+                const char *options,
+                const char *fstype,
+                int passno,
+                bool set_flags) {
+        int r;
+        Unit *u;
+        bool delete;
+        char *e, *w = NULL, *o = NULL, *f = NULL;
+        MountParameters *p;
+        bool load_extras = false;
+
+        assert(m);
+        assert(what);
+        assert(where);
+        assert(options);
+        assert(fstype);
+
+        /* Ignore API mount points. They should never be referenced in
+         * dependencies ever. */
+        if (mount_point_is_api(where) || mount_point_ignore(where))
+                return 0;
+
+        if (streq(fstype, "autofs"))
+                return 0;
+
+        /* probably some kind of swap, ignore */
+        if (!is_path(where))
+                return 0;
+
+        e = unit_name_from_path(where, ".mount");
+        if (!e)
+                return -ENOMEM;
+
+        u = manager_get_unit(m, e);
+        if (!u) {
+                delete = true;
+
+                u = unit_new(m, sizeof(Mount));
+                if (!u) {
+                        free(e);
+                        return -ENOMEM;
+                }
+
+                r = unit_add_name(u, e);
+                free(e);
+
+                if (r < 0)
+                        goto fail;
+
+                MOUNT(u)->where = strdup(where);
+                if (!MOUNT(u)->where) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                unit_add_to_load_queue(u);
+        } else {
+                delete = false;
+                free(e);
+
+                if (!MOUNT(u)->where) {
+                        MOUNT(u)->where = strdup(where);
+                        if (!MOUNT(u)->where) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+                }
+
+                if (u->load_state == UNIT_ERROR) {
+                        u->load_state = UNIT_LOADED;
+                        u->load_error = 0;
+
+                        /* Load in the extras later on, after we
+                         * finished initialization of the unit */
+                        load_extras = true;
+                }
+        }
+
+        if (!(w = strdup(what)) ||
+            !(o = strdup(options)) ||
+            !(f = strdup(fstype))) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        p = &MOUNT(u)->parameters_proc_self_mountinfo;
+        if (set_flags) {
+                MOUNT(u)->is_mounted = true;
+                MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
+                MOUNT(u)->just_changed = !streq_ptr(p->options, o);
+        }
+
+        MOUNT(u)->from_proc_self_mountinfo = true;
+
+        free(p->what);
+        p->what = w;
+
+        free(p->options);
+        p->options = o;
+
+        free(p->fstype);
+        p->fstype = f;
+
+        p->passno = passno;
+
+        if (load_extras) {
+                r = mount_add_extras(MOUNT(u));
+                if (r < 0)
+                        goto fail;
+        }
+
+        unit_add_to_dbus_queue(u);
+
+        return 0;
+
+fail:
+        free(w);
+        free(o);
+        free(f);
+
+        if (delete && u)
+                unit_free(u);
+
+        return r;
+}
+
+static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
+        int r = 0;
+        unsigned i;
+        char *device, *path, *options, *options2, *fstype, *d, *p, *o;
+
+        assert(m);
+
+        rewind(m->proc_self_mountinfo);
+
+        for (i = 1;; i++) {
+                int k;
+
+                device = path = options = options2 = fstype = d = p = o = NULL;
+
+                if ((k = fscanf(m->proc_self_mountinfo,
+                                "%*s "       /* (1) mount id */
+                                "%*s "       /* (2) parent id */
+                                "%*s "       /* (3) major:minor */
+                                "%*s "       /* (4) root */
+                                "%ms "       /* (5) mount point */
+                                "%ms"        /* (6) mount options */
+                                "%*[^-]"     /* (7) optional fields */
+                                "- "         /* (8) separator */
+                                "%ms "       /* (9) file system type */
+                                "%ms"        /* (10) mount source */
+                                "%ms"        /* (11) mount options 2 */
+                                "%*[^\n]",   /* some rubbish at the end */
+                                &path,
+                                &options,
+                                &fstype,
+                                &device,
+                                &options2)) != 5) {
+
+                        if (k == EOF)
+                                break;
+
+                        log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
+                        goto clean_up;
+                }
+
+                o = strjoin(options, ",", options2, NULL);
+                if (!o) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (!(d = cunescape(device)) ||
+                    !(p = cunescape(path))) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if ((k = mount_add_one(m, d, p, o, fstype, 0, set_flags)) < 0)
+                        r = k;
+
+clean_up:
+                free(device);
+                free(path);
+                free(options);
+                free(options2);
+                free(fstype);
+                free(d);
+                free(p);
+                free(o);
+        }
+
+finish:
+        free(device);
+        free(path);
+        free(options);
+        free(options2);
+        free(fstype);
+        free(d);
+        free(p);
+        free(o);
+
+        return r;
+}
+
+static void mount_shutdown(Manager *m) {
+        assert(m);
+
+        if (m->proc_self_mountinfo) {
+                fclose(m->proc_self_mountinfo);
+                m->proc_self_mountinfo = NULL;
+        }
+}
+
+static int mount_enumerate(Manager *m) {
+        int r;
+        struct epoll_event ev;
+        assert(m);
+
+        if (!m->proc_self_mountinfo) {
+                if (!(m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re")))
+                        return -errno;
+
+                m->mount_watch.type = WATCH_MOUNT;
+                m->mount_watch.fd = fileno(m->proc_self_mountinfo);
+
+                zero(ev);
+                ev.events = EPOLLPRI;
+                ev.data.ptr = &m->mount_watch;
+
+                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0)
+                        return -errno;
+        }
+
+        if ((r = mount_load_proc_self_mountinfo(m, false)) < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        mount_shutdown(m);
+        return r;
+}
+
+void mount_fd_event(Manager *m, int events) {
+        Unit *u;
+        int r;
+
+        assert(m);
+        assert(events & EPOLLPRI);
+
+        /* The manager calls this for every fd event happening on the
+         * /proc/self/mountinfo file, which informs us about mounting
+         * table changes */
+
+        r = mount_load_proc_self_mountinfo(m, true);
+        if (r < 0) {
+                log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r));
+
+                /* Reset flags, just in case, for later calls */
+                LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
+                        Mount *mount = MOUNT(u);
+
+                        mount->is_mounted = mount->just_mounted = mount->just_changed = false;
+                }
+
+                return;
+        }
+
+        manager_dispatch_load_queue(m);
+
+        LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
+                Mount *mount = MOUNT(u);
+
+                if (!mount->is_mounted) {
+                        /* This has just been unmounted. */
+
+                        mount->from_proc_self_mountinfo = false;
+
+                        switch (mount->state) {
+
+                        case MOUNT_MOUNTED:
+                                mount_enter_dead(mount, MOUNT_SUCCESS);
+                                break;
+
+                        default:
+                                mount_set_state(mount, mount->state);
+                                break;
+
+                        }
+
+                } else if (mount->just_mounted || mount->just_changed) {
+
+                        /* New or changed mount entry */
+
+                        switch (mount->state) {
+
+                        case MOUNT_DEAD:
+                        case MOUNT_FAILED:
+                                mount_enter_mounted(mount, MOUNT_SUCCESS);
+                                break;
+
+                        case MOUNT_MOUNTING:
+                                mount_enter_mounting_done(mount);
+                                break;
+
+                        default:
+                                /* Nothing really changed, but let's
+                                 * issue an notification call
+                                 * nonetheless, in case somebody is
+                                 * waiting for this. (e.g. file system
+                                 * ro/rw remounts.) */
+                                mount_set_state(mount, mount->state);
+                                break;
+                        }
+                }
+
+                /* Reset the flags for later calls */
+                mount->is_mounted = mount->just_mounted = mount->just_changed = false;
+        }
+}
+
+static void mount_reset_failed(Unit *u) {
+        Mount *m = MOUNT(u);
+
+        assert(m);
+
+        if (m->state == MOUNT_FAILED)
+                mount_set_state(m, MOUNT_DEAD);
+
+        m->result = MOUNT_SUCCESS;
+        m->reload_result = MOUNT_SUCCESS;
+}
+
+static int mount_kill(Unit *u, KillWho who, int signo, DBusError *error) {
+        Mount *m = MOUNT(u);
+        int r = 0;
+        Set *pid_set = NULL;
+
+        assert(m);
+
+        if (who == KILL_MAIN) {
+                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Mount units have no main processes");
+                return -ESRCH;
+        }
+
+        if (m->control_pid <= 0 && who == KILL_CONTROL) {
+                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
+                return -ESRCH;
+        }
+
+        if (who == KILL_CONTROL || who == KILL_ALL)
+                if (m->control_pid > 0)
+                        if (kill(m->control_pid, signo) < 0)
+                                r = -errno;
+
+        if (who == KILL_ALL) {
+                int q;
+
+                pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!pid_set)
+                        return -ENOMEM;
+
+                /* Exclude the control pid from being killed via the cgroup */
+                if (m->control_pid > 0) {
+                        q = set_put(pid_set, LONG_TO_PTR(m->control_pid));
+                        if (q < 0) {
+                                r = q;
+                                goto finish;
+                        }
+                }
+
+                q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, false, pid_set, NULL);
+                if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
+                        r = q;
+        }
+
+finish:
+        if (pid_set)
+                set_free(pid_set);
+
+        return r;
+}
+
+static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
+        [MOUNT_DEAD] = "dead",
+        [MOUNT_MOUNTING] = "mounting",
+        [MOUNT_MOUNTING_DONE] = "mounting-done",
+        [MOUNT_MOUNTED] = "mounted",
+        [MOUNT_REMOUNTING] = "remounting",
+        [MOUNT_UNMOUNTING] = "unmounting",
+        [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
+        [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
+        [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
+        [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
+        [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
+        [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
+        [MOUNT_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
+
+static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
+        [MOUNT_EXEC_MOUNT] = "ExecMount",
+        [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
+        [MOUNT_EXEC_REMOUNT] = "ExecRemount",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
+
+static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
+        [MOUNT_SUCCESS] = "success",
+        [MOUNT_FAILURE_RESOURCES] = "resources",
+        [MOUNT_FAILURE_TIMEOUT] = "timeout",
+        [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
+        [MOUNT_FAILURE_SIGNAL] = "signal",
+        [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
+
+const UnitVTable mount_vtable = {
+        .object_size = sizeof(Mount),
+        .exec_context_offset = offsetof(Mount, exec_context),
+
+        .sections =
+                "Unit\0"
+                "Mount\0"
+                "Install\0",
+
+        .no_alias = true,
+        .no_instances = true,
+
+        .init = mount_init,
+        .load = mount_load,
+        .done = mount_done,
+
+        .coldplug = mount_coldplug,
+
+        .dump = mount_dump,
+
+        .start = mount_start,
+        .stop = mount_stop,
+        .reload = mount_reload,
+
+        .kill = mount_kill,
+
+        .serialize = mount_serialize,
+        .deserialize_item = mount_deserialize_item,
+
+        .active_state = mount_active_state,
+        .sub_state_to_string = mount_sub_state_to_string,
+
+        .check_gc = mount_check_gc,
+
+        .sigchld_event = mount_sigchld_event,
+        .timer_event = mount_timer_event,
+
+        .reset_failed = mount_reset_failed,
+
+        .bus_interface = "org.freedesktop.systemd1.Mount",
+        .bus_message_handler = bus_mount_message_handler,
+        .bus_invalidating_properties =  bus_mount_invalidating_properties,
+
+        .enumerate = mount_enumerate,
+        .shutdown = mount_shutdown,
+
+        .status_message_formats = {
+                .starting_stopping = {
+                        [0] = "Mounting %s...",
+                        [1] = "Unmounting %s...",
+                },
+                .finished_start_job = {
+                        [JOB_DONE]       = "Mounted %s.",
+                        [JOB_FAILED]     = "Failed to mount %s.",
+                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                        [JOB_TIMEOUT]    = "Timed out mounting %s.",
+                },
+                .finished_stop_job = {
+                        [JOB_DONE]       = "Unmounted %s.",
+                        [JOB_FAILED]     = "Failed unmounting %s.",
+                        [JOB_TIMEOUT]    = "Timed out unmounting %s.",
+                },
+        },
+};
diff --git a/src/core/mount.h b/src/core/mount.h
new file mode 100644 (file)
index 0000000..30c6d9b
--- /dev/null
@@ -0,0 +1,123 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Mount Mount;
+
+#include "unit.h"
+#include "kill.h"
+
+typedef enum MountState {
+        MOUNT_DEAD,
+        MOUNT_MOUNTING,               /* /bin/mount is running, but the mount is not done yet. */
+        MOUNT_MOUNTING_DONE,          /* /bin/mount is running, and the mount is done. */
+        MOUNT_MOUNTED,
+        MOUNT_REMOUNTING,
+        MOUNT_UNMOUNTING,
+        MOUNT_MOUNTING_SIGTERM,
+        MOUNT_MOUNTING_SIGKILL,
+        MOUNT_REMOUNTING_SIGTERM,
+        MOUNT_REMOUNTING_SIGKILL,
+        MOUNT_UNMOUNTING_SIGTERM,
+        MOUNT_UNMOUNTING_SIGKILL,
+        MOUNT_FAILED,
+        _MOUNT_STATE_MAX,
+        _MOUNT_STATE_INVALID = -1
+} MountState;
+
+typedef enum MountExecCommand {
+        MOUNT_EXEC_MOUNT,
+        MOUNT_EXEC_UNMOUNT,
+        MOUNT_EXEC_REMOUNT,
+        _MOUNT_EXEC_COMMAND_MAX,
+        _MOUNT_EXEC_COMMAND_INVALID = -1
+} MountExecCommand;
+
+typedef struct MountParameters {
+        char *what;
+        char *options;
+        char *fstype;
+        int passno;
+} MountParameters;
+
+typedef enum MountResult {
+        MOUNT_SUCCESS,
+        MOUNT_FAILURE_RESOURCES,
+        MOUNT_FAILURE_TIMEOUT,
+        MOUNT_FAILURE_EXIT_CODE,
+        MOUNT_FAILURE_SIGNAL,
+        MOUNT_FAILURE_CORE_DUMP,
+        _MOUNT_RESULT_MAX,
+        _MOUNT_RESULT_INVALID = -1
+} MountResult;
+
+struct Mount {
+        Unit meta;
+
+        char *where;
+
+        MountParameters parameters_proc_self_mountinfo;
+        MountParameters parameters_fragment;
+
+        bool from_proc_self_mountinfo:1;
+        bool from_fragment:1;
+
+        /* Used while looking for mount points that vanished or got
+         * added from/to /proc/self/mountinfo */
+        bool is_mounted:1;
+        bool just_mounted:1;
+        bool just_changed:1;
+
+        MountResult result;
+        MountResult reload_result;
+
+        mode_t directory_mode;
+
+        usec_t timeout_usec;
+
+        ExecCommand exec_command[_MOUNT_EXEC_COMMAND_MAX];
+        ExecContext exec_context;
+        KillContext kill_context;
+
+        MountState state, deserialized_state;
+
+        ExecCommand* control_command;
+        MountExecCommand control_command_id;
+        pid_t control_pid;
+
+        Watch timer_watch;
+};
+
+extern const UnitVTable mount_vtable;
+
+void mount_fd_event(Manager *m, int events);
+
+const char* mount_state_to_string(MountState i);
+MountState mount_state_from_string(const char *s);
+
+const char* mount_exec_command_to_string(MountExecCommand i);
+MountExecCommand mount_exec_command_from_string(const char *s);
+
+const char* mount_result_to_string(MountResult i);
+MountResult mount_result_from_string(const char *s);
+
+void warn_if_dir_nonempty(const char *unit, const char* where);
diff --git a/src/core/namespace.c b/src/core/namespace.c
new file mode 100644 (file)
index 0000000..ba18ddc
--- /dev/null
@@ -0,0 +1,330 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <sys/mount.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sched.h>
+#include <sys/syscall.h>
+#include <limits.h>
+#include <linux/fs.h>
+
+#include "strv.h"
+#include "util.h"
+#include "path-util.h"
+#include "namespace.h"
+#include "missing.h"
+
+typedef enum PathMode {
+        /* This is ordered by priority! */
+        INACCESSIBLE,
+        READONLY,
+        PRIVATE_TMP,
+        PRIVATE_VAR_TMP,
+        READWRITE
+} PathMode;
+
+typedef struct Path {
+        const char *path;
+        PathMode mode;
+        bool done;
+} Path;
+
+static int append_paths(Path **p, char **strv, PathMode mode) {
+        char **i;
+
+        STRV_FOREACH(i, strv) {
+
+                if (!path_is_absolute(*i))
+                        return -EINVAL;
+
+                (*p)->path = *i;
+                (*p)->mode = mode;
+                (*p)++;
+        }
+
+        return 0;
+}
+
+static int path_compare(const void *a, const void *b) {
+        const Path *p = a, *q = b;
+
+        if (path_equal(p->path, q->path)) {
+
+                /* If the paths are equal, check the mode */
+                if (p->mode < q->mode)
+                        return -1;
+
+                if (p->mode > q->mode)
+                        return 1;
+
+                return 0;
+        }
+
+        /* If the paths are not equal, then order prefixes first */
+        if (path_startswith(p->path, q->path))
+                return 1;
+
+        if (path_startswith(q->path, p->path))
+                return -1;
+
+        return 0;
+}
+
+static void drop_duplicates(Path *p, unsigned *n, bool *need_inaccessible) {
+        Path *f, *t, *previous;
+
+        assert(p);
+        assert(n);
+        assert(need_inaccessible);
+
+        for (f = p, t = p, previous = NULL; f < p+*n; f++) {
+
+                /* The first one wins */
+                if (previous && path_equal(f->path, previous->path))
+                        continue;
+
+                t->path = f->path;
+                t->mode = f->mode;
+
+                if (t->mode == INACCESSIBLE)
+                        *need_inaccessible = true;
+
+                previous = t;
+
+                t++;
+        }
+
+        *n = t - p;
+}
+
+static int apply_mount(
+                Path *p,
+                const char *tmp_dir,
+                const char *var_tmp_dir,
+                const char *inaccessible_dir) {
+
+        const char *what;
+        int r;
+
+        assert(p);
+
+        switch (p->mode) {
+
+        case INACCESSIBLE:
+                what = inaccessible_dir;
+                break;
+
+        case READONLY:
+        case READWRITE:
+                what = p->path;
+                break;
+
+        case PRIVATE_TMP:
+                what = tmp_dir;
+                break;
+
+        case PRIVATE_VAR_TMP:
+                what = var_tmp_dir;
+                break;
+
+        default:
+                assert_not_reached("Unknown mode");
+        }
+
+        assert(what);
+
+        r = mount(what, p->path, NULL, MS_BIND|MS_REC, NULL);
+        if (r >= 0)
+                log_debug("Successfully mounted %s to %s", what, p->path);
+
+        return r;
+}
+
+static int make_read_only(Path *p) {
+        int r;
+
+        assert(p);
+
+        if (p->mode != INACCESSIBLE && p->mode != READONLY)
+                return 0;
+
+        r = mount(NULL, p->path, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL);
+        if (r < 0)
+                return -errno;
+
+        return 0;
+}
+
+int setup_namespace(
+                char **writable,
+                char **readable,
+                char **inaccessible,
+                bool private_tmp,
+                unsigned long flags) {
+
+        char
+                tmp_dir[] = "/tmp/systemd-private-XXXXXX",
+                var_tmp_dir[] = "/var/tmp/systemd-private-XXXXXX",
+                inaccessible_dir[] = "/tmp/systemd-inaccessible-XXXXXX";
+
+        Path *paths, *p;
+        unsigned n;
+        bool need_inaccessible = false;
+        bool remove_tmp = false, remove_var_tmp = false, remove_inaccessible = false;
+        int r;
+
+        if (!flags)
+                flags = MS_SHARED;
+
+        n =
+                strv_length(writable) +
+                strv_length(readable) +
+                strv_length(inaccessible) +
+                (private_tmp ? 2 : 0);
+
+        p = paths = alloca(sizeof(Path) * n);
+        if ((r = append_paths(&p, writable, READWRITE)) < 0 ||
+            (r = append_paths(&p, readable, READONLY)) < 0 ||
+            (r = append_paths(&p, inaccessible, INACCESSIBLE)) < 0)
+                goto fail;
+
+        if (private_tmp) {
+                p->path = "/tmp";
+                p->mode = PRIVATE_TMP;
+                p++;
+
+                p->path = "/var/tmp";
+                p->mode = PRIVATE_VAR_TMP;
+                p++;
+        }
+
+        assert(paths + n == p);
+
+        qsort(paths, n, sizeof(Path), path_compare);
+        drop_duplicates(paths, &n, &need_inaccessible);
+
+        if (need_inaccessible) {
+                mode_t u;
+                char *d;
+
+                u = umask(0777);
+                d = mkdtemp(inaccessible_dir);
+                umask(u);
+
+                if (!d) {
+                        r = -errno;
+                        goto fail;
+                }
+
+                remove_inaccessible = true;
+        }
+
+        if (private_tmp) {
+                mode_t u;
+                char *d;
+
+                u = umask(0000);
+                d = mkdtemp(tmp_dir);
+                umask(u);
+
+                if (!d) {
+                        r = -errno;
+                        goto fail;
+                }
+
+                remove_tmp = true;
+
+                u = umask(0000);
+                d = mkdtemp(var_tmp_dir);
+                umask(u);
+
+                if (!d) {
+                        r = -errno;
+                        goto fail;
+                }
+
+                remove_var_tmp = true;
+
+                if (chmod(tmp_dir, 0777 + S_ISVTX) < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+
+                if (chmod(var_tmp_dir, 0777 + S_ISVTX) < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+        }
+
+        if (unshare(CLONE_NEWNS) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        /* Remount / as SLAVE so that nothing now mounted in the namespace
+           shows up in the parent */
+        if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        for (p = paths; p < paths + n; p++) {
+                r = apply_mount(p, tmp_dir, var_tmp_dir, inaccessible_dir);
+                if (r < 0)
+                        goto undo_mounts;
+        }
+
+        for (p = paths; p < paths + n; p++) {
+                r = make_read_only(p);
+                if (r < 0)
+                        goto undo_mounts;
+        }
+
+        /* Remount / as the desired mode */
+        if (mount(NULL, "/", NULL, flags|MS_REC, NULL) < 0) {
+                r = -errno;
+                goto undo_mounts;
+        }
+
+        return 0;
+
+undo_mounts:
+        for (p = paths; p < paths + n; p++)
+                if (p->done)
+                        umount2(p->path, MNT_DETACH);
+
+fail:
+        if (remove_inaccessible)
+                rmdir(inaccessible_dir);
+
+        if (remove_tmp)
+                rmdir(tmp_dir);
+
+        if (remove_var_tmp)
+                rmdir(var_tmp_dir);
+
+        return r;
+}
diff --git a/src/core/namespace.h b/src/core/namespace.h
new file mode 100644 (file)
index 0000000..5d72ed9
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+int setup_namespace(
+                char **writable,
+                char **readable,
+                char **inaccessible,
+                bool private_tmp,
+                unsigned long flags);
diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf
new file mode 100644 (file)
index 0000000..a07a8e1
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0"?> <!--*-nxml-*-->
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<busconfig>
+
+        <policy user="root">
+                <allow own="org.freedesktop.systemd1"/>
+
+                <!-- Root clients can do everything -->
+                <allow send_destination="org.freedesktop.systemd1"/>
+                <allow receive_sender="org.freedesktop.systemd1"/>
+
+                <!-- systemd may receive activator requests -->
+                <allow receive_interface="org.freedesktop.systemd1.Activator"
+                       receive_member="ActivationRequest"/>
+        </policy>
+
+        <policy context="default">
+                <deny send_destination="org.freedesktop.systemd1"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.DBus.Introspectable"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.DBus.Peer"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.DBus.Properties"
+                       send_member="Get"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.DBus.Properties"
+                       send_member="GetAll"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="GetUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="GetUnitByPID"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="LoadUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="GetJob"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ListUnits"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ListUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="GetUnitFileState"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ListJobs"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="Subscribe"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="Unsubscribe"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="Dump"/>
+
+                <allow receive_sender="org.freedesktop.systemd1"/>
+        </policy>
+
+</busconfig>
diff --git a/src/core/org.freedesktop.systemd1.policy.in.in b/src/core/org.freedesktop.systemd1.policy.in.in
new file mode 100644 (file)
index 0000000..51bdafa
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<policyconfig>
+
+        <vendor>The systemd Project</vendor>
+        <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
+
+        <action id="org.freedesktop.systemd1.reply-password">
+                <_description>Send passphrase back to system</_description>
+                <_message>Authentication is required to send the entered passphrase back to the system.</_message>
+                <defaults>
+                        <allow_any>no</allow_any>
+                        <allow_inactive>no</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.exec.path">@rootlibexecdir@/systemd-reply-password</annotate>
+        </action>
+
+        <action id="org.freedesktop.systemd1.bus-access">
+                <_description>Privileged system and service manager access</_description>
+                <_message>Authentication is required to access the system and service manager.</_message>
+                <defaults>
+                        <allow_any>no</allow_any>
+                        <allow_inactive>no</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.exec.path">@bindir@/systemd-stdio-bridge</annotate>
+        </action>
+
+</policyconfig>
diff --git a/src/core/org.freedesktop.systemd1.service b/src/core/org.freedesktop.systemd1.service
new file mode 100644 (file)
index 0000000..d4df3e9
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[D-BUS Service]
+Name=org.freedesktop.systemd1
+Exec=/bin/false
+User=root
diff --git a/src/core/path.c b/src/core/path.c
new file mode 100644 (file)
index 0000000..767620b
--- /dev/null
@@ -0,0 +1,777 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/inotify.h>
+#include <sys/epoll.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "unit.h"
+#include "unit-name.h"
+#include "path.h"
+#include "mkdir.h"
+#include "dbus-path.h"
+#include "special.h"
+#include "bus-errors.h"
+#include "path-util.h"
+
+static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
+        [PATH_DEAD] = UNIT_INACTIVE,
+        [PATH_WAITING] = UNIT_ACTIVE,
+        [PATH_RUNNING] = UNIT_ACTIVE,
+        [PATH_FAILED] = UNIT_FAILED
+};
+
+int path_spec_watch(PathSpec *s, Unit *u) {
+
+        static const int flags_table[_PATH_TYPE_MAX] = {
+                [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+                [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+                [PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
+                [PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY,
+                [PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
+        };
+
+        bool exists = false;
+        char *k, *slash;
+        int r;
+
+        assert(u);
+        assert(s);
+
+        path_spec_unwatch(s, u);
+
+        if (!(k = strdup(s->path)))
+                return -ENOMEM;
+
+        if ((s->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC)) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if (unit_watch_fd(u, s->inotify_fd, EPOLLIN, &s->watch) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        s->primary_wd = inotify_add_watch(s->inotify_fd, k, flags_table[s->type]);
+        if (s->primary_wd >= 0)
+                exists = true;
+
+        do {
+                int flags;
+
+                /* This assumes the path was passed through path_kill_slashes()! */
+                slash = strrchr(k, '/');
+                if (!slash)
+                        break;
+
+                /* Trim the path at the last slash. Keep the slash if it's the root dir. */
+                slash[slash == k] = 0;
+
+                flags = IN_MOVE_SELF;
+                if (!exists)
+                        flags |= IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO;
+
+                if (inotify_add_watch(s->inotify_fd, k, flags) >= 0)
+                        exists = true;
+        } while (slash != k);
+
+        return 0;
+
+fail:
+        free(k);
+
+        path_spec_unwatch(s, u);
+        return r;
+}
+
+void path_spec_unwatch(PathSpec *s, Unit *u) {
+
+        if (s->inotify_fd < 0)
+                return;
+
+        unit_unwatch_fd(u, &s->watch);
+
+        close_nointr_nofail(s->inotify_fd);
+        s->inotify_fd = -1;
+}
+
+int path_spec_fd_event(PathSpec *s, uint32_t events) {
+        uint8_t *buf = NULL;
+        struct inotify_event *e;
+        ssize_t k;
+        int l;
+        int r = 0;
+
+        if (events != EPOLLIN) {
+                log_error("Got invalid poll event on inotify.");
+                r = -EINVAL;
+                goto out;
+        }
+
+        if (ioctl(s->inotify_fd, FIONREAD, &l) < 0) {
+                log_error("FIONREAD failed: %m");
+                r = -errno;
+                goto out;
+        }
+
+        assert(l > 0);
+
+        buf = malloc(l);
+        if (!buf) {
+                log_error("Failed to allocate buffer: %m");
+                r = -errno;
+                goto out;
+        }
+
+        k = read(s->inotify_fd, buf, l);
+        if (k < 0) {
+                log_error("Failed to read inotify event: %m");
+                r = -errno;
+                goto out;
+        }
+
+        e = (struct inotify_event*) buf;
+
+        while (k > 0) {
+                size_t step;
+
+                if ((s->type == PATH_CHANGED || s->type == PATH_MODIFIED) &&
+                    s->primary_wd == e->wd)
+                        r = 1;
+
+                step = sizeof(struct inotify_event) + e->len;
+                assert(step <= (size_t) k);
+
+                e = (struct inotify_event*) ((uint8_t*) e + step);
+                k -= step;
+        }
+out:
+        free(buf);
+        return r;
+}
+
+static bool path_spec_check_good(PathSpec *s, bool initial) {
+        bool good = false;
+
+        switch (s->type) {
+
+        case PATH_EXISTS:
+                good = access(s->path, F_OK) >= 0;
+                break;
+
+        case PATH_EXISTS_GLOB:
+                good = glob_exists(s->path) > 0;
+                break;
+
+        case PATH_DIRECTORY_NOT_EMPTY: {
+                int k;
+
+                k = dir_is_empty(s->path);
+                good = !(k == -ENOENT || k > 0);
+                break;
+        }
+
+        case PATH_CHANGED:
+        case PATH_MODIFIED: {
+                bool b;
+
+                b = access(s->path, F_OK) >= 0;
+                good = !initial && b != s->previous_exists;
+                s->previous_exists = b;
+                break;
+        }
+
+        default:
+                ;
+        }
+
+        return good;
+}
+
+static bool path_spec_startswith(PathSpec *s, const char *what) {
+        return path_startswith(s->path, what);
+}
+
+static void path_spec_mkdir(PathSpec *s, mode_t mode) {
+        int r;
+
+        if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB)
+                return;
+
+        r = mkdir_p_label(s->path, mode);
+        if (r < 0)
+                log_warning("mkdir(%s) failed: %s", s->path, strerror(-r));
+}
+
+static void path_spec_dump(PathSpec *s, FILE *f, const char *prefix) {
+        fprintf(f,
+                "%s%s: %s\n",
+                prefix,
+                path_type_to_string(s->type),
+                s->path);
+}
+
+void path_spec_done(PathSpec *s) {
+        assert(s);
+        assert(s->inotify_fd == -1);
+
+        free(s->path);
+}
+
+static void path_init(Unit *u) {
+        Path *p = PATH(u);
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        p->directory_mode = 0755;
+}
+
+static void path_done(Unit *u) {
+        Path *p = PATH(u);
+        PathSpec *s;
+
+        assert(p);
+
+        unit_ref_unset(&p->unit);
+
+        while ((s = p->specs)) {
+                path_spec_unwatch(s, u);
+                LIST_REMOVE(PathSpec, spec, p->specs, s);
+                path_spec_done(s);
+                free(s);
+        }
+}
+
+int path_add_one_mount_link(Path *p, Mount *m) {
+        PathSpec *s;
+        int r;
+
+        assert(p);
+        assert(m);
+
+        if (UNIT(p)->load_state != UNIT_LOADED ||
+            UNIT(m)->load_state != UNIT_LOADED)
+                return 0;
+
+        LIST_FOREACH(spec, s, p->specs) {
+
+                if (!path_spec_startswith(s, m->where))
+                        continue;
+
+                if ((r = unit_add_two_dependencies(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int path_add_mount_links(Path *p) {
+        Unit *other;
+        int r;
+
+        assert(p);
+
+        LIST_FOREACH(units_by_type, other, UNIT(p)->manager->units_by_type[UNIT_MOUNT])
+                if ((r = path_add_one_mount_link(p, MOUNT(other))) < 0)
+                        return r;
+
+        return 0;
+}
+
+static int path_verify(Path *p) {
+        assert(p);
+
+        if (UNIT(p)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (!p->specs) {
+                log_error_unit(UNIT(p)->id,
+                               "%s lacks path setting. Refusing.", UNIT(p)->id);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static int path_add_default_dependencies(Path *p) {
+        int r;
+
+        assert(p);
+
+        if (UNIT(p)->manager->running_as == SYSTEMD_SYSTEM) {
+                if ((r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
+                        return r;
+
+                if ((r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0)
+                        return r;
+        }
+
+        return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+}
+
+static int path_load(Unit *u) {
+        Path *p = PATH(u);
+        int r;
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        if ((r = unit_load_fragment_and_dropin(u)) < 0)
+                return r;
+
+        if (u->load_state == UNIT_LOADED) {
+
+                if (!UNIT_DEREF(p->unit)) {
+                        Unit *x;
+
+                        r = unit_load_related_unit(u, ".service", &x);
+                        if (r < 0)
+                                return r;
+
+                        unit_ref_set(&p->unit, x);
+                }
+
+                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(p->unit), true);
+                if (r < 0)
+                        return r;
+
+                if ((r = path_add_mount_links(p)) < 0)
+                        return r;
+
+                if (UNIT(p)->default_dependencies)
+                        if ((r = path_add_default_dependencies(p)) < 0)
+                                return r;
+        }
+
+        return path_verify(p);
+}
+
+static void path_dump(Unit *u, FILE *f, const char *prefix) {
+        Path *p = PATH(u);
+        PathSpec *s;
+
+        assert(p);
+        assert(f);
+
+        fprintf(f,
+                "%sPath State: %s\n"
+                "%sResult: %s\n"
+                "%sUnit: %s\n"
+                "%sMakeDirectory: %s\n"
+                "%sDirectoryMode: %04o\n",
+                prefix, path_state_to_string(p->state),
+                prefix, path_result_to_string(p->result),
+                prefix, UNIT_DEREF(p->unit)->id,
+                prefix, yes_no(p->make_directory),
+                prefix, p->directory_mode);
+
+        LIST_FOREACH(spec, s, p->specs)
+                path_spec_dump(s, f, prefix);
+}
+
+static void path_unwatch(Path *p) {
+        PathSpec *s;
+
+        assert(p);
+
+        LIST_FOREACH(spec, s, p->specs)
+                path_spec_unwatch(s, UNIT(p));
+}
+
+static int path_watch(Path *p) {
+        int r;
+        PathSpec *s;
+
+        assert(p);
+
+        LIST_FOREACH(spec, s, p->specs)
+                if ((r = path_spec_watch(s, UNIT(p))) < 0)
+                        return r;
+
+        return 0;
+}
+
+static void path_set_state(Path *p, PathState state) {
+        PathState old_state;
+        assert(p);
+
+        old_state = p->state;
+        p->state = state;
+
+        if (state != PATH_WAITING &&
+            (state != PATH_RUNNING || p->inotify_triggered))
+                path_unwatch(p);
+
+        if (state != old_state)
+                log_debug("%s changed %s -> %s",
+                          UNIT(p)->id,
+                          path_state_to_string(old_state),
+                          path_state_to_string(state));
+
+        unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state], true);
+}
+
+static void path_enter_waiting(Path *p, bool initial, bool recheck);
+
+static int path_coldplug(Unit *u) {
+        Path *p = PATH(u);
+
+        assert(p);
+        assert(p->state == PATH_DEAD);
+
+        if (p->deserialized_state != p->state) {
+
+                if (p->deserialized_state == PATH_WAITING ||
+                    p->deserialized_state == PATH_RUNNING)
+                        path_enter_waiting(p, true, true);
+                else
+                        path_set_state(p, p->deserialized_state);
+        }
+
+        return 0;
+}
+
+static void path_enter_dead(Path *p, PathResult f) {
+        assert(p);
+
+        if (f != PATH_SUCCESS)
+                p->result = f;
+
+        path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD);
+}
+
+static void path_enter_running(Path *p) {
+        int r;
+        DBusError error;
+
+        assert(p);
+        dbus_error_init(&error);
+
+        /* Don't start job if we are supposed to go down */
+        if (UNIT(p)->job && UNIT(p)->job->type == JOB_STOP)
+                return;
+
+        if ((r = manager_add_job(UNIT(p)->manager, JOB_START, UNIT_DEREF(p->unit), JOB_REPLACE, true, &error, NULL)) < 0)
+                goto fail;
+
+        p->inotify_triggered = false;
+
+        if ((r = path_watch(p)) < 0)
+                goto fail;
+
+        path_set_state(p, PATH_RUNNING);
+        return;
+
+fail:
+        log_warning("%s failed to queue unit startup job: %s", UNIT(p)->id, bus_error(&error, r));
+        path_enter_dead(p, PATH_FAILURE_RESOURCES);
+
+        dbus_error_free(&error);
+}
+
+static bool path_check_good(Path *p, bool initial) {
+        PathSpec *s;
+        bool good = false;
+
+        assert(p);
+
+        LIST_FOREACH(spec, s, p->specs) {
+                good = path_spec_check_good(s, initial);
+
+                if (good)
+                        break;
+        }
+
+        return good;
+}
+
+static void path_enter_waiting(Path *p, bool initial, bool recheck) {
+        int r;
+
+        if (recheck)
+                if (path_check_good(p, initial)) {
+                        log_debug("%s got triggered.", UNIT(p)->id);
+                        path_enter_running(p);
+                        return;
+                }
+
+        if ((r = path_watch(p)) < 0)
+                goto fail;
+
+        /* Hmm, so now we have created inotify watches, but the file
+         * might have appeared/been removed by now, so we must
+         * recheck */
+
+        if (recheck)
+                if (path_check_good(p, false)) {
+                        log_debug("%s got triggered.", UNIT(p)->id);
+                        path_enter_running(p);
+                        return;
+                }
+
+        path_set_state(p, PATH_WAITING);
+        return;
+
+fail:
+        log_warning("%s failed to enter waiting state: %s", UNIT(p)->id, strerror(-r));
+        path_enter_dead(p, PATH_FAILURE_RESOURCES);
+}
+
+static void path_mkdir(Path *p) {
+        PathSpec *s;
+
+        assert(p);
+
+        if (!p->make_directory)
+                return;
+
+        LIST_FOREACH(spec, s, p->specs)
+                path_spec_mkdir(s, p->directory_mode);
+}
+
+static int path_start(Unit *u) {
+        Path *p = PATH(u);
+
+        assert(p);
+        assert(p->state == PATH_DEAD || p->state == PATH_FAILED);
+
+        if (UNIT_DEREF(p->unit)->load_state != UNIT_LOADED)
+                return -ENOENT;
+
+        path_mkdir(p);
+
+        p->result = PATH_SUCCESS;
+        path_enter_waiting(p, true, true);
+
+        return 0;
+}
+
+static int path_stop(Unit *u) {
+        Path *p = PATH(u);
+
+        assert(p);
+        assert(p->state == PATH_WAITING || p->state == PATH_RUNNING);
+
+        path_enter_dead(p, PATH_SUCCESS);
+        return 0;
+}
+
+static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Path *p = PATH(u);
+
+        assert(u);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", path_state_to_string(p->state));
+        unit_serialize_item(u, f, "result", path_result_to_string(p->result));
+
+        return 0;
+}
+
+static int path_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Path *p = PATH(u);
+
+        assert(u);
+        assert(key);
+        assert(value);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                PathState state;
+
+                if ((state = path_state_from_string(value)) < 0)
+                        log_debug("Failed to parse state value %s", value);
+                else
+                        p->deserialized_state = state;
+
+        } else if (streq(key, "result")) {
+                PathResult f;
+
+                f = path_result_from_string(value);
+                if (f < 0)
+                        log_debug("Failed to parse result value %s", value);
+                else if (f != PATH_SUCCESS)
+                        p->result = f;
+
+        } else
+                log_debug("Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static UnitActiveState path_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[PATH(u)->state];
+}
+
+static const char *path_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return path_state_to_string(PATH(u)->state);
+}
+
+static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+        Path *p = PATH(u);
+        PathSpec *s;
+        int changed;
+
+        assert(p);
+        assert(fd >= 0);
+
+        if (p->state != PATH_WAITING &&
+            p->state != PATH_RUNNING)
+                return;
+
+        /* log_debug("inotify wakeup on %s.", u->id); */
+
+        LIST_FOREACH(spec, s, p->specs)
+                if (path_spec_owns_inotify_fd(s, fd))
+                        break;
+
+        if (!s) {
+                log_error("Got event on unknown fd.");
+                goto fail;
+        }
+
+        changed = path_spec_fd_event(s, events);
+        if (changed < 0)
+                goto fail;
+
+        /* If we are already running, then remember that one event was
+         * dispatched so that we restart the service only if something
+         * actually changed on disk */
+        p->inotify_triggered = true;
+
+        if (changed)
+                path_enter_running(p);
+        else
+                path_enter_waiting(p, false, true);
+
+        return;
+
+fail:
+        path_enter_dead(p, PATH_FAILURE_RESOURCES);
+}
+
+void path_unit_notify(Unit *u, UnitActiveState new_state) {
+        Iterator i;
+        Unit *k;
+
+        if (u->type == UNIT_PATH)
+                return;
+
+        SET_FOREACH(k, u->dependencies[UNIT_TRIGGERED_BY], i) {
+                Path *p;
+
+                if (k->type != UNIT_PATH)
+                        continue;
+
+                if (k->load_state != UNIT_LOADED)
+                        continue;
+
+                p = PATH(k);
+
+                if (p->state == PATH_RUNNING && new_state == UNIT_INACTIVE) {
+                        log_debug("%s got notified about unit deactivation.", UNIT(p)->id);
+
+                        /* Hmm, so inotify was triggered since the
+                         * last activation, so I guess we need to
+                         * recheck what is going on. */
+                        path_enter_waiting(p, false, p->inotify_triggered);
+                }
+        }
+}
+
+static void path_reset_failed(Unit *u) {
+        Path *p = PATH(u);
+
+        assert(p);
+
+        if (p->state == PATH_FAILED)
+                path_set_state(p, PATH_DEAD);
+
+        p->result = PATH_SUCCESS;
+}
+
+static const char* const path_state_table[_PATH_STATE_MAX] = {
+        [PATH_DEAD] = "dead",
+        [PATH_WAITING] = "waiting",
+        [PATH_RUNNING] = "running",
+        [PATH_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(path_state, PathState);
+
+static const char* const path_type_table[_PATH_TYPE_MAX] = {
+        [PATH_EXISTS] = "PathExists",
+        [PATH_EXISTS_GLOB] = "PathExistsGlob",
+        [PATH_CHANGED] = "PathChanged",
+        [PATH_MODIFIED] = "PathModified",
+        [PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(path_type, PathType);
+
+static const char* const path_result_table[_PATH_RESULT_MAX] = {
+        [PATH_SUCCESS] = "success",
+        [PATH_FAILURE_RESOURCES] = "resources"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult);
+
+const UnitVTable path_vtable = {
+        .object_size = sizeof(Path),
+        .sections =
+                "Unit\0"
+                "Path\0"
+                "Install\0",
+
+        .init = path_init,
+        .done = path_done,
+        .load = path_load,
+
+        .coldplug = path_coldplug,
+
+        .dump = path_dump,
+
+        .start = path_start,
+        .stop = path_stop,
+
+        .serialize = path_serialize,
+        .deserialize_item = path_deserialize_item,
+
+        .active_state = path_active_state,
+        .sub_state_to_string = path_sub_state_to_string,
+
+        .fd_event = path_fd_event,
+
+        .reset_failed = path_reset_failed,
+
+        .bus_interface = "org.freedesktop.systemd1.Path",
+        .bus_message_handler = bus_path_message_handler,
+        .bus_invalidating_properties = bus_path_invalidating_properties
+};
diff --git a/src/core/path.h b/src/core/path.h
new file mode 100644 (file)
index 0000000..7792688
--- /dev/null
@@ -0,0 +1,110 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Path Path;
+
+#include "unit.h"
+#include "mount.h"
+
+typedef enum PathState {
+        PATH_DEAD,
+        PATH_WAITING,
+        PATH_RUNNING,
+        PATH_FAILED,
+        _PATH_STATE_MAX,
+        _PATH_STATE_INVALID = -1
+} PathState;
+
+typedef enum PathType {
+        PATH_EXISTS,
+        PATH_EXISTS_GLOB,
+        PATH_DIRECTORY_NOT_EMPTY,
+        PATH_CHANGED,
+        PATH_MODIFIED,
+        _PATH_TYPE_MAX,
+        _PATH_TYPE_INVALID = -1
+} PathType;
+
+typedef struct PathSpec {
+        char *path;
+
+        Watch watch;
+
+        LIST_FIELDS(struct PathSpec, spec);
+
+        PathType type;
+        int inotify_fd;
+        int primary_wd;
+
+        bool previous_exists;
+} PathSpec;
+
+int path_spec_watch(PathSpec *s, Unit *u);
+void path_spec_unwatch(PathSpec *s, Unit *u);
+int path_spec_fd_event(PathSpec *s, uint32_t events);
+void path_spec_done(PathSpec *s);
+
+static inline bool path_spec_owns_inotify_fd(PathSpec *s, int fd) {
+        return s->inotify_fd == fd;
+}
+
+typedef enum PathResult {
+        PATH_SUCCESS,
+        PATH_FAILURE_RESOURCES,
+        _PATH_RESULT_MAX,
+        _PATH_RESULT_INVALID = -1
+} PathResult;
+
+struct Path {
+        Unit meta;
+
+        LIST_HEAD(PathSpec, specs);
+
+        UnitRef unit;
+
+        PathState state, deserialized_state;
+
+        bool inotify_triggered;
+
+        bool make_directory;
+        mode_t directory_mode;
+
+        PathResult result;
+};
+
+void path_unit_notify(Unit *u, UnitActiveState new_state);
+
+/* Called from the mount code figure out if a mount is a dependency of
+ * any of the paths of this path object */
+int path_add_one_mount_link(Path *p, Mount *m);
+
+extern const UnitVTable path_vtable;
+
+const char* path_state_to_string(PathState i);
+PathState path_state_from_string(const char *s);
+
+const char* path_type_to_string(PathType i);
+PathType path_type_from_string(const char *s);
+
+const char* path_result_to_string(PathResult i);
+PathResult path_result_from_string(const char *s);
diff --git a/src/core/securebits.h b/src/core/securebits.h
new file mode 100644 (file)
index 0000000..ba0bba5
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _LINUX_SECUREBITS_H
+#define _LINUX_SECUREBITS_H 1
+
+/* This is minimal version of Linux' linux/securebits.h header file,
+ * which is licensed GPL2 */
+
+#define SECUREBITS_DEFAULT 0x00000000
+
+/* When set UID 0 has no special privileges. When unset, we support
+   inheritance of root-permissions and suid-root executable under
+   compatibility mode. We raise the effective and inheritable bitmasks
+   *of the executable file* if the effective uid of the new process is
+   0. If the real uid is 0, we raise the effective (legacy) bit of the
+   executable file. */
+#define SECURE_NOROOT                  0
+#define SECURE_NOROOT_LOCKED           1  /* make bit-0 immutable */
+
+/* When set, setuid to/from uid 0 does not trigger capability-"fixup".
+   When unset, to provide compatibility with old programs relying on
+   set*uid to gain/lose privilege, transitions to/from uid 0 cause
+   capabilities to be gained/lost. */
+#define SECURE_NO_SETUID_FIXUP         2
+#define SECURE_NO_SETUID_FIXUP_LOCKED  3  /* make bit-2 immutable */
+
+/* When set, a process can retain its capabilities even after
+   transitioning to a non-root user (the set-uid fixup suppressed by
+   bit 2). Bit-4 is cleared when a process calls exec(); setting both
+   bit 4 and 5 will create a barrier through exec that no exec()'d
+   child can use this feature again. */
+#define SECURE_KEEP_CAPS               4
+#define SECURE_KEEP_CAPS_LOCKED                5  /* make bit-4 immutable */
+
+/* Each securesetting is implemented using two bits. One bit specifies
+   whether the setting is on or off. The other bit specify whether the
+   setting is locked or not. A setting which is locked cannot be
+   changed from user-level. */
+#define issecure_mask(X)       (1 << (X))
+#define issecure(X)            (issecure_mask(X) & current_cred_xxx(securebits))
+
+#define SECURE_ALL_BITS                (issecure_mask(SECURE_NOROOT) | \
+                                issecure_mask(SECURE_NO_SETUID_FIXUP) | \
+                                issecure_mask(SECURE_KEEP_CAPS))
+#define SECURE_ALL_LOCKS       (SECURE_ALL_BITS << 1)
+
+#endif /* !_LINUX_SECUREBITS_H */
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c
new file mode 100644 (file)
index 0000000..6dfe8b4
--- /dev/null
@@ -0,0 +1,441 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Dan Walsh
+
+  systemd 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.
+
+  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "selinux-access.h"
+
+#ifdef HAVE_SELINUX
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <selinux/selinux.h>
+#include <selinux/avc.h>
+#ifdef HAVE_AUDIT
+#include <libaudit.h>
+#endif
+#include <dbus.h>
+
+#include "util.h"
+#include "log.h"
+#include "bus-errors.h"
+#include "dbus-common.h"
+#include "audit.h"
+#include "selinux-util.h"
+#include "audit-fd.h"
+
+static bool initialized = false;
+
+struct auditstruct {
+        const char *path;
+        char *cmdline;
+        uid_t loginuid;
+        uid_t uid;
+        gid_t gid;
+};
+
+static int bus_get_selinux_security_context(
+                DBusConnection *connection,
+                const char *name,
+                char **scon,
+                DBusError *error) {
+
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
+        DBusMessageIter iter, sub;
+        const char *bytes;
+        char *b;
+        int nbytes;
+
+        m = dbus_message_new_method_call(
+                        DBUS_SERVICE_DBUS,
+                        DBUS_PATH_DBUS,
+                        DBUS_INTERFACE_DBUS,
+                        "GetConnectionSELinuxSecurityContext");
+        if (!m) {
+                dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL);
+                return -ENOMEM;
+        }
+
+        if (!dbus_message_append_args(
+                            m,
+                            DBUS_TYPE_STRING, &name,
+                            DBUS_TYPE_INVALID)) {
+                dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL);
+                return -ENOMEM;
+        }
+
+        reply = dbus_connection_send_with_reply_and_block(connection, m, -1, error);
+        if (!reply)
+                return -EIO;
+
+        if (dbus_set_error_from_message(error, reply))
+                return -EIO;
+
+        if (!dbus_message_iter_init(reply, &iter))
+                return -EIO;
+
+        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+                return -EIO;
+
+        dbus_message_iter_recurse(&iter, &sub);
+        dbus_message_iter_get_fixed_array(&sub, &bytes, &nbytes);
+
+        b = strndup(bytes, nbytes);
+        if (!b)
+                return -ENOMEM;
+
+        *scon = b;
+
+        log_debug("GetConnectionSELinuxSecurityContext %s (pid %ld)", *scon, (long) bus_get_unix_process_id(connection, name, error));
+
+        return 0;
+}
+
+static int bus_get_audit_data(
+                DBusConnection *connection,
+                const char *name,
+                struct auditstruct *audit,
+                DBusError *error) {
+
+        pid_t pid;
+        int r;
+
+        pid = bus_get_unix_process_id(connection, name, error);
+        if (pid <= 0)
+                return -EIO;
+
+        r = audit_loginuid_from_pid(pid, &audit->loginuid);
+        if (r < 0)
+                return r;
+
+        r = get_process_uid(pid, &audit->uid);
+        if (r < 0)
+                return r;
+
+        r = get_process_gid(pid, &audit->gid);
+        if (r < 0)
+                return r;
+
+        r = get_process_cmdline(pid, LINE_MAX, true, &audit->cmdline);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+/*
+   Any time an access gets denied this callback will be called
+   with the aduit data.  We then need to just copy the audit data into the msgbuf.
+*/
+static int audit_callback(
+                void *auditdata,
+                security_class_t cls,
+                char *msgbuf,
+                size_t msgbufsize) {
+
+        struct auditstruct *audit = (struct auditstruct *) auditdata;
+
+        snprintf(msgbuf, msgbufsize,
+                 "auid=%d uid=%d gid=%d%s%s%s%s%s%s",
+                 audit->loginuid,
+                 audit->uid,
+                 audit->gid,
+                 (audit->path ? " path=\"" : ""),
+                 strempty(audit->path),
+                 (audit->path ? "\"" : ""),
+                 (audit->cmdline ? " cmdline=\"" : ""),
+                 strempty(audit->cmdline),
+                 (audit->cmdline ? "\"" : ""));
+
+        msgbuf[msgbufsize-1] = 0;
+
+        return 0;
+}
+
+/*
+   Any time an access gets denied this callback will be called
+   code copied from dbus. If audit is turned on the messages will go as
+   user_avc's into the /var/log/audit/audit.log, otherwise they will be
+   sent to syslog.
+*/
+static int log_callback(int type, const char *fmt, ...) {
+        va_list ap;
+
+        va_start(ap, fmt);
+
+#ifdef HAVE_AUDIT
+        if (get_audit_fd() >= 0) {
+                char buf[LINE_MAX];
+
+                vsnprintf(buf, sizeof(buf), fmt, ap);
+                audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
+                va_end(ap);
+
+                return 0;
+        }
+#endif
+        log_metav(LOG_USER | LOG_INFO, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
+        va_end(ap);
+
+        return 0;
+}
+
+/*
+   Function must be called once to initialize the SELinux AVC environment.
+   Sets up callbacks.
+   If you want to cleanup memory you should need to call selinux_access_finish.
+*/
+static int access_init(void) {
+        int r;
+
+        if (avc_open(NULL, 0)) {
+                log_error("avc_open() failed: %m");
+                return -errno;
+        }
+
+        selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback);
+        selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback);
+
+        if (security_getenforce() >= 0)
+                return 0;
+
+        r = -errno;
+        avc_destroy();
+
+        return r;
+}
+
+static int selinux_access_init(DBusError *error) {
+        int r;
+
+        if (initialized)
+                return 0;
+
+        if (use_selinux()) {
+                r = access_init();
+                if (r < 0) {
+                        dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to initialize SELinux.");
+                        return r;
+                }
+        }
+
+        initialized = true;
+        return 0;
+}
+
+void selinux_access_free(void) {
+        if (!initialized)
+                return;
+
+        avc_destroy();
+        initialized = false;
+}
+
+static int get_audit_data(
+                DBusConnection *connection,
+                DBusMessage *message,
+                struct auditstruct *audit,
+                DBusError *error) {
+
+        const char *sender;
+        int r, fd;
+        struct ucred ucred;
+        socklen_t len;
+
+        sender = dbus_message_get_sender(message);
+        if (sender)
+                return bus_get_audit_data(connection, sender, audit, error);
+
+        if (!dbus_connection_get_unix_fd(connection, &fd))
+                return -EINVAL;
+
+        r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len);
+        if (r < 0) {
+                log_error("Failed to determine peer credentials: %m");
+                return -errno;
+        }
+
+        audit->uid = ucred.uid;
+        audit->gid = ucred.gid;
+
+        r = audit_loginuid_from_pid(ucred.pid, &audit->loginuid);
+        if (r < 0)
+                return r;
+
+        r = get_process_cmdline(ucred.pid, LINE_MAX, true, &audit->cmdline);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+/*
+   This function returns the security context of the remote end of the dbus
+   connections.  Whether it is on the bus or a local connection.
+*/
+static int get_calling_context(
+                DBusConnection *connection,
+                DBusMessage *message,
+                security_context_t *scon,
+                DBusError *error) {
+
+        const char *sender;
+        int r;
+        int fd;
+
+        /*
+           If sender exists then
+           if sender is NULL this indicates a local connection.  Grab the fd
+           from dbus and do an getpeercon to peers process context
+        */
+        sender = dbus_message_get_sender(message);
+        if (sender) {
+                log_error("SELinux Got Sender %s", sender);
+
+                r = bus_get_selinux_security_context(connection, sender, scon, error);
+                if (r >= 0)
+                        return r;
+
+                log_error("bus_get_selinux_security_context failed: %m");
+                return r;
+        }
+
+        log_debug("SELinux No Sender");
+        if (!dbus_connection_get_unix_fd(connection, &fd)) {
+                log_error("bus_connection_get_unix_fd failed %m");
+                return -EINVAL;
+        }
+
+        r = getpeercon(fd, scon);
+        if (r < 0) {
+                log_error("getpeercon failed %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+/*
+   This function communicates with the kernel to check whether or not it should
+   allow the access.
+   If the machine is in permissive mode it will return ok.  Audit messages will
+   still be generated if the access would be denied in enforcing mode.
+*/
+int selinux_access_check(
+                DBusConnection *connection,
+                DBusMessage *message,
+                const char *path,
+                const char *permission,
+                DBusError *error) {
+
+        security_context_t scon = NULL, fcon = NULL;
+        int r = 0;
+        const char *tclass = NULL;
+        struct auditstruct audit;
+
+        assert(connection);
+        assert(message);
+        assert(permission);
+        assert(error);
+
+        if (!use_selinux())
+                return 0;
+
+        r = selinux_access_init(error);
+        if (r < 0)
+                return r;
+
+        log_debug("SELinux access check for path=%s permission=%s", strna(path), permission);
+
+        audit.uid = audit.loginuid = (uid_t) -1;
+        audit.gid = (gid_t) -1;
+        audit.cmdline = NULL;
+        audit.path = path;
+
+        r = get_calling_context(connection, message, &scon, error);
+        if (r < 0) {
+                log_error("Failed to get caller's security context on: %m");
+                goto finish;
+        }
+
+        if (path) {
+                tclass = "service";
+                /* get the file context of the unit file */
+                r = getfilecon(path, &fcon);
+                if (r < 0) {
+                        dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to get file context on %s.", path);
+                        r = -errno;
+                        log_error("Failed to get security context on %s: %m",path);
+                        goto finish;
+                }
+
+        } else {
+                tclass = "system";
+                r = getcon(&fcon);
+                if (r < 0) {
+                        dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to get current context.");
+                        r = -errno;
+                        log_error("Failed to get current process context on: %m");
+                        goto finish;
+                }
+        }
+
+        (void) get_audit_data(connection, message, &audit, error);
+
+        errno = 0;
+        r = selinux_check_access(scon, fcon, tclass, permission, &audit);
+        if (r < 0) {
+                dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "SELinux policy denies access.");
+                r = -errno;
+                log_error("SELinux policy denies access.");
+        }
+
+        log_debug("SELinux access check scon=%s tcon=%s tclass=%s perm=%s path=%s cmdline=%s: %i", scon, fcon, tclass, permission, path, audit.cmdline, r);
+
+finish:
+        free(audit.cmdline);
+        freecon(scon);
+        freecon(fcon);
+
+        if (r && security_getenforce() != 1) {
+                dbus_error_init(error);
+                r = 0;
+        }
+
+        return r;
+}
+
+#else
+
+int selinux_access_check(
+                DBusConnection *connection,
+                DBusMessage *message,
+                const char *path,
+                const char *permission,
+                DBusError *error) {
+
+        return 0;
+}
+
+void selinux_access_free(void) {
+}
+
+#endif
diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h
new file mode 100644 (file)
index 0000000..9183cbc
--- /dev/null
@@ -0,0 +1,62 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Dan Walsh
+
+  systemd 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.
+
+  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus.h>
+
+void selinux_access_free(void);
+
+int selinux_access_check(DBusConnection *connection, DBusMessage *message, const char *path, const char *permission, DBusError *error);
+
+#ifdef HAVE_SELINUX
+
+#define SELINUX_ACCESS_CHECK(connection, message, permission) \
+        do {                                                            \
+                DBusError _error;                                       \
+                int _r;                                                 \
+                DBusConnection *_c = (connection);                      \
+                DBusMessage *_m = (message);                            \
+                dbus_error_init(&_error);                               \
+                _r = selinux_access_check(_c, _m, NULL, (permission), &_error); \
+                if (_r < 0)                                             \
+                        return bus_send_error_reply(_c, _m, &_error, _r); \
+        } while (false)
+
+#define SELINUX_UNIT_ACCESS_CHECK(unit, connection, message, permission) \
+        do {                                                            \
+                DBusError _error;                                       \
+                int _r;                                                 \
+                DBusConnection *_c = (connection);                      \
+                DBusMessage *_m = (message);                            \
+                Unit *_u = (unit);                                      \
+                dbus_error_init(&_error);                               \
+                _r = selinux_access_check(_c, _m, _u->source_path ?: _u->fragment_path, (permission), &_error); \
+                if (_r < 0)                                             \
+                        return bus_send_error_reply(_c, _m, &_error, _r); \
+        } while (false)
+
+#else
+
+#define SELINUX_ACCESS_CHECK(connection, message, permission) do { } while (false)
+#define SELINUX_UNIT_ACCESS_CHECK(unit, connection, message, permission) do { } while (false)
+
+#endif
diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c
new file mode 100644 (file)
index 0000000..e9c0de9
--- /dev/null
@@ -0,0 +1,123 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#include "selinux-setup.h"
+#include "selinux-util.h"
+#include "label.h"
+#include "mount-setup.h"
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+
+#ifdef HAVE_SELINUX
+static int null_log(int type, const char *fmt, ...) {
+        return 0;
+}
+#endif
+
+int selinux_setup(bool *loaded_policy) {
+
+#ifdef HAVE_SELINUX
+       int enforce = 0;
+       usec_t before_load, after_load;
+       security_context_t con;
+       int r;
+       union selinux_callback cb;
+
+       assert(loaded_policy);
+
+       /* Turn off all of SELinux' own logging, we want to do that */
+       cb.func_log = null_log;
+       selinux_set_callback(SELINUX_CB_LOG, cb);
+
+       /* Make sure getcon() works, which needs /proc and /sys */
+       mount_setup_early();
+
+       /* Already initialized by somebody else? */
+       r = getcon_raw(&con);
+       if (r == 0) {
+               bool initialized;
+
+               initialized = !streq(con, "kernel");
+               freecon(con);
+
+               if (initialized)
+                       return 0;
+       }
+
+       /* Make sure we have no fds open while loading the policy and
+        * transitioning */
+       log_close();
+
+       /* Now load the policy */
+       before_load = now(CLOCK_MONOTONIC);
+       r = selinux_init_load_policy(&enforce);
+       if (r == 0) {
+               char timespan[FORMAT_TIMESPAN_MAX];
+               char *label;
+
+               retest_selinux();
+
+               /* Transition to the new context */
+               r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
+               if (r < 0 || label == NULL) {
+                       log_open();
+                       log_error("Failed to compute init label, ignoring.");
+               } else {
+                       r = setcon(label);
+
+                       log_open();
+                       if (r < 0)
+                               log_error("Failed to transition into init label '%s', ignoring.", label);
+
+                       label_free(label);
+               }
+
+               after_load = now(CLOCK_MONOTONIC);
+
+               log_info("Successfully loaded SELinux policy in %s.",
+                         format_timespan(timespan, sizeof(timespan), after_load - before_load));
+
+               *loaded_policy = true;
+
+       } else {
+               log_open();
+
+               if (enforce > 0) {
+                       log_error("Failed to load SELinux policy. Freezing.");
+                       return -EIO;
+               } else
+                       log_debug("Unable to load SELinux policy. Ignoring.");
+       }
+#endif
+
+       return 0;
+}
diff --git a/src/core/selinux-setup.h b/src/core/selinux-setup.h
new file mode 100644 (file)
index 0000000..39e2bc2
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+int selinux_setup(bool *loaded_policy);
diff --git a/src/core/service.c b/src/core/service.c
new file mode 100644 (file)
index 0000000..2a4e691
--- /dev/null
@@ -0,0 +1,3901 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <signal.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/reboot.h>
+
+#include "manager.h"
+#include "unit.h"
+#include "service.h"
+#include "load-fragment.h"
+#include "load-dropin.h"
+#include "log.h"
+#include "strv.h"
+#include "unit-name.h"
+#include "unit-printf.h"
+#include "dbus-service.h"
+#include "special.h"
+#include "bus-errors.h"
+#include "exit-status.h"
+#include "def.h"
+#include "path-util.h"
+#include "util.h"
+#include "utf8.h"
+
+#ifdef HAVE_SYSV_COMPAT
+
+#define DEFAULT_SYSV_TIMEOUT_USEC (5*USEC_PER_MINUTE)
+
+typedef enum RunlevelType {
+        RUNLEVEL_UP,
+        RUNLEVEL_DOWN
+} RunlevelType;
+
+static const struct {
+        const char *path;
+        const char *target;
+        const RunlevelType type;
+} rcnd_table[] = {
+        /* Standard SysV runlevels for start-up */
+        { "rc1.d",  SPECIAL_RESCUE_TARGET,    RUNLEVEL_UP },
+        { "rc2.d",  SPECIAL_RUNLEVEL2_TARGET, RUNLEVEL_UP },
+        { "rc3.d",  SPECIAL_RUNLEVEL3_TARGET, RUNLEVEL_UP },
+        { "rc4.d",  SPECIAL_RUNLEVEL4_TARGET, RUNLEVEL_UP },
+        { "rc5.d",  SPECIAL_RUNLEVEL5_TARGET, RUNLEVEL_UP },
+
+        /* Standard SysV runlevels for shutdown */
+        { "rc0.d",  SPECIAL_POWEROFF_TARGET,  RUNLEVEL_DOWN },
+        { "rc6.d",  SPECIAL_REBOOT_TARGET,    RUNLEVEL_DOWN }
+
+        /* Note that the order here matters, as we read the
+           directories in this order, and we want to make sure that
+           sysv_start_priority is known when we first load the
+           unit. And that value we only know from S links. Hence
+           UP must be read before DOWN */
+};
+
+#define RUNLEVELS_UP "12345"
+#endif
+
+static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
+        [SERVICE_DEAD] = UNIT_INACTIVE,
+        [SERVICE_START_PRE] = UNIT_ACTIVATING,
+        [SERVICE_START] = UNIT_ACTIVATING,
+        [SERVICE_START_POST] = UNIT_ACTIVATING,
+        [SERVICE_RUNNING] = UNIT_ACTIVE,
+        [SERVICE_EXITED] = UNIT_ACTIVE,
+        [SERVICE_RELOAD] = UNIT_RELOADING,
+        [SERVICE_STOP] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_POST] = UNIT_DEACTIVATING,
+        [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING,
+        [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING,
+        [SERVICE_FAILED] = UNIT_FAILED,
+        [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING
+};
+
+/* For Type=idle we never want to delay any other jobs, hence we
+ * consider idle jobs active as soon as we start working on them */
+static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] = {
+        [SERVICE_DEAD] = UNIT_INACTIVE,
+        [SERVICE_START_PRE] = UNIT_ACTIVE,
+        [SERVICE_START] = UNIT_ACTIVE,
+        [SERVICE_START_POST] = UNIT_ACTIVE,
+        [SERVICE_RUNNING] = UNIT_ACTIVE,
+        [SERVICE_EXITED] = UNIT_ACTIVE,
+        [SERVICE_RELOAD] = UNIT_RELOADING,
+        [SERVICE_STOP] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_POST] = UNIT_DEACTIVATING,
+        [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING,
+        [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING,
+        [SERVICE_FAILED] = UNIT_FAILED,
+        [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING
+};
+
+static void service_init(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        s->timeout_start_usec = DEFAULT_TIMEOUT_USEC;
+        s->timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
+        s->restart_usec = DEFAULT_RESTART_USEC;
+        s->type = _SERVICE_TYPE_INVALID;
+
+        watch_init(&s->watchdog_watch);
+        watch_init(&s->timer_watch);
+
+#ifdef HAVE_SYSV_COMPAT
+        s->sysv_start_priority = -1;
+        s->sysv_start_priority_from_rcnd = -1;
+#endif
+        s->socket_fd = -1;
+        s->guess_main_pid = true;
+
+        exec_context_init(&s->exec_context);
+        kill_context_init(&s->kill_context);
+
+        RATELIMIT_INIT(s->start_limit, 10*USEC_PER_SEC, 5);
+
+        s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
+}
+
+static void service_unwatch_control_pid(Service *s) {
+        assert(s);
+
+        if (s->control_pid <= 0)
+                return;
+
+        unit_unwatch_pid(UNIT(s), s->control_pid);
+        s->control_pid = 0;
+}
+
+static void service_unwatch_main_pid(Service *s) {
+        assert(s);
+
+        if (s->main_pid <= 0)
+                return;
+
+        unit_unwatch_pid(UNIT(s), s->main_pid);
+        s->main_pid = 0;
+}
+
+static void service_unwatch_pid_file(Service *s) {
+        if (!s->pid_file_pathspec)
+                return;
+
+        log_debug_unit(UNIT(s)->id, "Stopping watch for %s's PID file %s",
+                       UNIT(s)->id, s->pid_file_pathspec->path);
+        path_spec_unwatch(s->pid_file_pathspec, UNIT(s));
+        path_spec_done(s->pid_file_pathspec);
+        free(s->pid_file_pathspec);
+        s->pid_file_pathspec = NULL;
+}
+
+static int service_set_main_pid(Service *s, pid_t pid) {
+        pid_t ppid;
+
+        assert(s);
+
+        if (pid <= 1)
+                return -EINVAL;
+
+        if (pid == getpid())
+                return -EINVAL;
+
+        s->main_pid = pid;
+        s->main_pid_known = true;
+
+        if (get_parent_of_pid(pid, &ppid) >= 0 && ppid != getpid()) {
+                log_warning_unit(UNIT(s)->id,
+                                 "%s: Supervising process %lu which is not our child. We'll most likely not notice when it exits.",
+                                 UNIT(s)->id, (unsigned long) pid);
+
+                s->main_pid_alien = true;
+        } else
+                s->main_pid_alien = false;
+
+        exec_status_start(&s->main_exec_status, pid);
+
+        return 0;
+}
+
+static void service_close_socket_fd(Service *s) {
+        assert(s);
+
+        if (s->socket_fd < 0)
+                return;
+
+        close_nointr_nofail(s->socket_fd);
+        s->socket_fd = -1;
+}
+
+static void service_connection_unref(Service *s) {
+        assert(s);
+
+        if (!UNIT_DEREF(s->accept_socket))
+                return;
+
+        socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket)));
+        unit_ref_unset(&s->accept_socket);
+}
+
+static void service_stop_watchdog(Service *s) {
+        assert(s);
+
+        unit_unwatch_timer(UNIT(s), &s->watchdog_watch);
+        s->watchdog_timestamp.realtime = 0;
+        s->watchdog_timestamp.monotonic = 0;
+}
+
+static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart);
+
+static void service_handle_watchdog(Service *s) {
+        usec_t offset;
+        int r;
+
+        assert(s);
+
+        if (s->watchdog_usec == 0)
+                return;
+
+        offset = now(CLOCK_MONOTONIC) - s->watchdog_timestamp.monotonic;
+        if (offset >= s->watchdog_usec) {
+                log_error_unit(UNIT(s)->id, "%s watchdog timeout!", UNIT(s)->id);
+                service_enter_dead(s, SERVICE_FAILURE_WATCHDOG, true);
+                return;
+        }
+
+        r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->watchdog_usec - offset, &s->watchdog_watch);
+        if (r < 0)
+                log_warning_unit(UNIT(s)->id,
+                                 "%s failed to install watchdog timer: %s",
+                                 UNIT(s)->id, strerror(-r));
+}
+
+static void service_reset_watchdog(Service *s) {
+        assert(s);
+
+        dual_timestamp_get(&s->watchdog_timestamp);
+        service_handle_watchdog(s);
+}
+
+static void service_done(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        free(s->pid_file);
+        s->pid_file = NULL;
+
+#ifdef HAVE_SYSV_COMPAT
+        free(s->sysv_runlevels);
+        s->sysv_runlevels = NULL;
+#endif
+
+        free(s->status_text);
+        s->status_text = NULL;
+
+        exec_context_done(&s->exec_context);
+        exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
+        s->control_command = NULL;
+        s->main_command = NULL;
+
+        set_free(s->restart_ignore_status.code);
+        s->restart_ignore_status.code = NULL;
+        set_free(s->restart_ignore_status.signal);
+        s->restart_ignore_status.signal = NULL;
+
+        set_free(s->success_status.code);
+        s->success_status.code = NULL;
+        set_free(s->success_status.signal);
+        s->success_status.signal = NULL;
+
+        /* This will leak a process, but at least no memory or any of
+         * our resources */
+        service_unwatch_main_pid(s);
+        service_unwatch_control_pid(s);
+        service_unwatch_pid_file(s);
+
+        if (s->bus_name)  {
+                unit_unwatch_bus_name(u, s->bus_name);
+                free(s->bus_name);
+                s->bus_name = NULL;
+        }
+
+        service_close_socket_fd(s);
+        service_connection_unref(s);
+
+        unit_ref_unset(&s->accept_socket);
+
+        service_stop_watchdog(s);
+
+        unit_unwatch_timer(u, &s->timer_watch);
+}
+
+#ifdef HAVE_SYSV_COMPAT
+static char *sysv_translate_name(const char *name) {
+        char *r;
+
+        if (!(r = new(char, strlen(name) + sizeof(".service"))))
+                return NULL;
+
+        if (endswith(name, ".sh"))
+                /* Drop Debian-style .sh suffix */
+                strcpy(stpcpy(r, name) - 3, ".service");
+        if (startswith(name, "rc."))
+                /* Drop Frugalware-style rc. prefix */
+                strcpy(stpcpy(r, name + 3), ".service");
+        else
+                /* Normal init scripts */
+                strcpy(stpcpy(r, name), ".service");
+
+        return r;
+}
+
+static int sysv_translate_facility(const char *name, const char *filename, char **_r) {
+
+        /* We silently ignore the $ prefix here. According to the LSB
+         * spec it simply indicates whether something is a
+         * standardized name or a distribution-specific one. Since we
+         * just follow what already exists and do not introduce new
+         * uses or names we don't care who introduced a new name. */
+
+        static const char * const table[] = {
+                /* LSB defined facilities */
+                "local_fs",             SPECIAL_LOCAL_FS_TARGET,
+                /* Due to unfortunate name selection in Mandriva,
+                 * $network is provided by network-up which is ordered
+                 * after network which actually starts interfaces.
+                 * To break the loop, just ignore it */
+                "network",              SPECIAL_NETWORK_TARGET,
+                "named",                SPECIAL_NSS_LOOKUP_TARGET,
+                "portmap",              SPECIAL_RPCBIND_TARGET,
+                "remote_fs",            SPECIAL_REMOTE_FS_TARGET,
+                "syslog",               SPECIAL_SYSLOG_TARGET,
+                "time",                 SPECIAL_TIME_SYNC_TARGET,
+
+                /* common extensions */
+                "mail-transfer-agent",  SPECIAL_MAIL_TRANSFER_AGENT_TARGET,
+                "x-display-manager",    SPECIAL_DISPLAY_MANAGER_SERVICE,
+                "null",                 NULL,
+                "mail-transport-agent", SPECIAL_MAIL_TRANSFER_AGENT_TARGET,
+                "smtp",                 SPECIAL_MAIL_TRANSFER_AGENT_TARGET,
+        };
+
+        unsigned i;
+        char *r;
+        const char *n;
+
+        assert(name);
+        assert(_r);
+
+        n = *name == '$' ? name + 1 : name;
+
+        for (i = 0; i < ELEMENTSOF(table); i += 2) {
+
+                if (!streq(table[i], n))
+                        continue;
+
+                if (!table[i+1])
+                        return 0;
+
+                if (!(r = strdup(table[i+1])))
+                        return -ENOMEM;
+
+                goto finish;
+        }
+
+        /* If we don't know this name, fallback heuristics to figure
+         * out whether something is a target or a service alias. */
+
+        if (*name == '$') {
+                if (!unit_prefix_is_valid(n))
+                        return -EINVAL;
+
+                /* Facilities starting with $ are most likely targets */
+                r = unit_name_build(n, NULL, ".target");
+        } else if (filename && streq(name, filename))
+                /* Names equaling the file name of the services are redundant */
+                return 0;
+        else
+                /* Everything else we assume to be normal service names */
+                r = sysv_translate_name(n);
+
+        if (!r)
+                return -ENOMEM;
+
+finish:
+        *_r = r;
+
+        return 1;
+}
+
+static int sysv_fix_order(Service *s) {
+        Unit *other;
+        int r;
+
+        assert(s);
+
+        if (s->sysv_start_priority < 0)
+                return 0;
+
+        /* For each pair of services where at least one lacks a LSB
+         * header, we use the start priority value to order things. */
+
+        LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_SERVICE]) {
+                Service *t;
+                UnitDependency d;
+                bool special_s, special_t;
+
+                t = SERVICE(other);
+
+                if (s == t)
+                        continue;
+
+                if (UNIT(t)->load_state != UNIT_LOADED)
+                        continue;
+
+                if (t->sysv_start_priority < 0)
+                        continue;
+
+                /* If both units have modern headers we don't care
+                 * about the priorities */
+                if ((UNIT(s)->fragment_path || s->sysv_has_lsb) &&
+                    (UNIT(t)->fragment_path || t->sysv_has_lsb))
+                        continue;
+
+                special_s = s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels);
+                special_t = t->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, t->sysv_runlevels);
+
+                if (special_t && !special_s)
+                        d = UNIT_AFTER;
+                else if (special_s && !special_t)
+                        d = UNIT_BEFORE;
+                else if (t->sysv_start_priority < s->sysv_start_priority)
+                        d = UNIT_AFTER;
+                else if (t->sysv_start_priority > s->sysv_start_priority)
+                        d = UNIT_BEFORE;
+                else
+                        continue;
+
+                /* FIXME: Maybe we should compare the name here lexicographically? */
+
+                if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static ExecCommand *exec_command_new(const char *path, const char *arg1) {
+        ExecCommand *c;
+
+        if (!(c = new0(ExecCommand, 1)))
+                return NULL;
+
+        if (!(c->path = strdup(path))) {
+                free(c);
+                return NULL;
+        }
+
+        if (!(c->argv = strv_new(path, arg1, NULL))) {
+                free(c->path);
+                free(c);
+                return NULL;
+        }
+
+        return c;
+}
+
+static int sysv_exec_commands(Service *s, const bool supports_reload) {
+        ExecCommand *c;
+
+        assert(s);
+        assert(s->is_sysv);
+        assert(UNIT(s)->source_path);
+
+        c = exec_command_new(UNIT(s)->source_path, "start");
+        if (!c)
+                return -ENOMEM;
+        exec_command_append_list(s->exec_command+SERVICE_EXEC_START, c);
+
+        c = exec_command_new(UNIT(s)->source_path, "stop");
+        if (!c)
+                return -ENOMEM;
+        exec_command_append_list(s->exec_command+SERVICE_EXEC_STOP, c);
+
+        if (supports_reload) {
+                c = exec_command_new(UNIT(s)->source_path, "reload");
+                if (!c)
+                        return -ENOMEM;
+                exec_command_append_list(s->exec_command+SERVICE_EXEC_RELOAD, c);
+        }
+
+        return 0;
+}
+
+static bool usage_contains_reload(const char *line) {
+        return (strcasestr(line, "{reload|") ||
+                strcasestr(line, "{reload}") ||
+                strcasestr(line, "{reload\"") ||
+                strcasestr(line, "|reload|") ||
+                strcasestr(line, "|reload}") ||
+                strcasestr(line, "|reload\""));
+}
+
+static int service_load_sysv_path(Service *s, const char *path) {
+        FILE *f;
+        Unit *u;
+        unsigned line = 0;
+        int r;
+        enum {
+                NORMAL,
+                DESCRIPTION,
+                LSB,
+                LSB_DESCRIPTION,
+                USAGE_CONTINUATION
+        } state = NORMAL;
+        char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL, *description;
+        struct stat st;
+        bool supports_reload = false;
+
+        assert(s);
+        assert(path);
+
+        u = UNIT(s);
+
+        f = fopen(path, "re");
+        if (!f) {
+                r = errno == ENOENT ? 0 : -errno;
+                goto finish;
+        }
+
+        if (fstat(fileno(f), &st) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        free(u->source_path);
+        u->source_path = strdup(path);
+        if (!u->source_path) {
+                r = -ENOMEM;
+                goto finish;
+        }
+        u->source_mtime = timespec_load(&st.st_mtim);
+
+        if (null_or_empty(&st)) {
+                u->load_state = UNIT_MASKED;
+                r = 0;
+                goto finish;
+        }
+
+        s->is_sysv = true;
+
+        while (!feof(f)) {
+                char l[LINE_MAX], *t;
+
+                if (!fgets(l, sizeof(l), f)) {
+                        if (feof(f))
+                                break;
+
+                        r = -errno;
+                        log_error_unit(u->id,
+                                       "Failed to read configuration file '%s': %s",
+                                       path, strerror(-r));
+                        goto finish;
+                }
+
+                line++;
+
+                t = strstrip(l);
+                if (*t != '#') {
+                        /* Try to figure out whether this init script supports
+                         * the reload operation. This heuristic looks for
+                         * "Usage" lines which include the reload option. */
+                        if ( state == USAGE_CONTINUATION ||
+                            (state == NORMAL && strcasestr(t, "usage"))) {
+                                if (usage_contains_reload(t)) {
+                                        supports_reload = true;
+                                        state = NORMAL;
+                                } else if (t[strlen(t)-1] == '\\')
+                                        state = USAGE_CONTINUATION;
+                                else
+                                        state = NORMAL;
+                        }
+
+                        continue;
+                }
+
+                if (state == NORMAL && streq(t, "### BEGIN INIT INFO")) {
+                        state = LSB;
+                        s->sysv_has_lsb = true;
+                        continue;
+                }
+
+                if ((state == LSB_DESCRIPTION || state == LSB) && streq(t, "### END INIT INFO")) {
+                        state = NORMAL;
+                        continue;
+                }
+
+                t++;
+                t += strspn(t, WHITESPACE);
+
+                if (state == NORMAL) {
+
+                        /* Try to parse Red Hat style chkconfig headers */
+
+                        if (startswith_no_case(t, "chkconfig:")) {
+                                int start_priority;
+                                char runlevels[16], *k;
+
+                                state = NORMAL;
+
+                                if (sscanf(t+10, "%15s %i %*i",
+                                           runlevels,
+                                           &start_priority) != 2) {
+
+                                        log_warning_unit(u->id,
+                                                         "[%s:%u] Failed to parse chkconfig line. Ignoring.",
+                                                         path, line);
+                                        continue;
+                                }
+
+                                /* A start priority gathered from the
+                                 * symlink farms is preferred over the
+                                 * data from the LSB header. */
+                                if (start_priority < 0 || start_priority > 99)
+                                        log_warning_unit(u->id,
+                                                         "[%s:%u] Start priority out of range. Ignoring.",
+                                                         path, line);
+                                else
+                                        s->sysv_start_priority = start_priority;
+
+                                char_array_0(runlevels);
+                                k = delete_chars(runlevels, WHITESPACE "-");
+
+                                if (k[0]) {
+                                        char *d;
+
+                                        if (!(d = strdup(k))) {
+                                                r = -ENOMEM;
+                                                goto finish;
+                                        }
+
+                                        free(s->sysv_runlevels);
+                                        s->sysv_runlevels = d;
+                                }
+
+                        } else if (startswith_no_case(t, "description:")) {
+
+                                size_t k = strlen(t);
+                                char *d;
+                                const char *j;
+
+                                if (t[k-1] == '\\') {
+                                        state = DESCRIPTION;
+                                        t[k-1] = 0;
+                                }
+
+                                if ((j = strstrip(t+12)) && *j) {
+                                        if (!(d = strdup(j))) {
+                                                r = -ENOMEM;
+                                                goto finish;
+                                        }
+                                } else
+                                        d = NULL;
+
+                                free(chkconfig_description);
+                                chkconfig_description = d;
+
+                        } else if (startswith_no_case(t, "pidfile:")) {
+
+                                char *fn;
+
+                                state = NORMAL;
+
+                                fn = strstrip(t+8);
+                                if (!path_is_absolute(fn)) {
+                                        log_warning_unit(u->id,
+                                                         "[%s:%u] PID file not absolute. Ignoring.",
+                                                         path, line);
+                                        continue;
+                                }
+
+                                if (!(fn = strdup(fn))) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                free(s->pid_file);
+                                s->pid_file = fn;
+                        }
+
+                } else if (state == DESCRIPTION) {
+
+                        /* Try to parse Red Hat style description
+                         * continuation */
+
+                        size_t k = strlen(t);
+                        char *j;
+
+                        if (t[k-1] == '\\')
+                                t[k-1] = 0;
+                        else
+                                state = NORMAL;
+
+                        if ((j = strstrip(t)) && *j) {
+                                char *d = NULL;
+
+                                if (chkconfig_description)
+                                        d = strjoin(chkconfig_description, " ", j, NULL);
+                                else
+                                        d = strdup(j);
+
+                                if (!d) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                free(chkconfig_description);
+                                chkconfig_description = d;
+                        }
+
+                } else if (state == LSB || state == LSB_DESCRIPTION) {
+
+                        if (startswith_no_case(t, "Provides:")) {
+                                char *i, *w;
+                                size_t z;
+
+                                state = LSB;
+
+                                FOREACH_WORD_QUOTED(w, z, t+9, i) {
+                                        char *n, *m;
+
+                                        if (!(n = strndup(w, z))) {
+                                                r = -ENOMEM;
+                                                goto finish;
+                                        }
+
+                                        r = sysv_translate_facility(n, path_get_file_name(path), &m);
+                                        free(n);
+
+                                        if (r < 0)
+                                                goto finish;
+
+                                        if (r == 0)
+                                                continue;
+
+                                        if (unit_name_to_type(m) == UNIT_SERVICE)
+                                                r = unit_add_name(u, m);
+                                        else
+                                                /* NB: SysV targets
+                                                 * which are provided
+                                                 * by a service are
+                                                 * pulled in by the
+                                                 * services, as an
+                                                 * indication that the
+                                                 * generic service is
+                                                 * now available. This
+                                                 * is strictly
+                                                 * one-way. The
+                                                 * targets do NOT pull
+                                                 * in the SysV
+                                                 * services! */
+                                                r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_WANTS, m, NULL, true);
+
+                                        if (r < 0)
+                                                log_error_unit(u->id,
+                                                               "[%s:%u] Failed to add LSB Provides name %s, ignoring: %s",
+                                                               path, line, m, strerror(-r));
+
+                                        free(m);
+                                }
+
+                        } else if (startswith_no_case(t, "Required-Start:") ||
+                                   startswith_no_case(t, "Should-Start:") ||
+                                   startswith_no_case(t, "X-Start-Before:") ||
+                                   startswith_no_case(t, "X-Start-After:")) {
+                                char *i, *w;
+                                size_t z;
+
+                                state = LSB;
+
+                                FOREACH_WORD_QUOTED(w, z, strchr(t, ':')+1, i) {
+                                        char *n, *m;
+
+                                        if (!(n = strndup(w, z))) {
+                                                r = -ENOMEM;
+                                                goto finish;
+                                        }
+
+                                        r = sysv_translate_facility(n, path_get_file_name(path), &m);
+
+                                        if (r < 0) {
+                                                log_error_unit(u->id,
+                                                               "[%s:%u] Failed to translate LSB dependency %s, ignoring: %s",
+                                                               path, line, n, strerror(-r));
+                                                free(n);
+                                                continue;
+                                        }
+
+                                        free(n);
+
+                                        if (r == 0)
+                                                continue;
+
+                                        r = unit_add_dependency_by_name(u, startswith_no_case(t, "X-Start-Before:") ? UNIT_BEFORE : UNIT_AFTER, m, NULL, true);
+
+                                        if (r < 0)
+                                                log_error_unit(u->id, "[%s:%u] Failed to add dependency on %s, ignoring: %s",
+                                                               path, line, m, strerror(-r));
+
+                                        free(m);
+                                }
+                        } else if (startswith_no_case(t, "Default-Start:")) {
+                                char *k, *d;
+
+                                state = LSB;
+
+                                k = delete_chars(t+14, WHITESPACE "-");
+
+                                if (k[0] != 0) {
+                                        if (!(d = strdup(k))) {
+                                                r = -ENOMEM;
+                                                goto finish;
+                                        }
+
+                                        free(s->sysv_runlevels);
+                                        s->sysv_runlevels = d;
+                                }
+
+                        } else if (startswith_no_case(t, "Description:")) {
+                                char *d, *j;
+
+                                state = LSB_DESCRIPTION;
+
+                                if ((j = strstrip(t+12)) && *j) {
+                                        if (!(d = strdup(j))) {
+                                                r = -ENOMEM;
+                                                goto finish;
+                                        }
+                                } else
+                                        d = NULL;
+
+                                free(long_description);
+                                long_description = d;
+
+                        } else if (startswith_no_case(t, "Short-Description:")) {
+                                char *d, *j;
+
+                                state = LSB;
+
+                                if ((j = strstrip(t+18)) && *j) {
+                                        if (!(d = strdup(j))) {
+                                                r = -ENOMEM;
+                                                goto finish;
+                                        }
+                                } else
+                                        d = NULL;
+
+                                free(short_description);
+                                short_description = d;
+
+                        } else if (state == LSB_DESCRIPTION) {
+
+                                if (startswith(l, "#\t") || startswith(l, "#  ")) {
+                                        char *j;
+
+                                        if ((j = strstrip(t)) && *j) {
+                                                char *d = NULL;
+
+                                                if (long_description)
+                                                        d = strjoin(long_description, " ", t, NULL);
+                                                else
+                                                        d = strdup(j);
+
+                                                if (!d) {
+                                                        r = -ENOMEM;
+                                                        goto finish;
+                                                }
+
+                                                free(long_description);
+                                                long_description = d;
+                                        }
+
+                                } else
+                                        state = LSB;
+                        }
+                }
+        }
+
+        if ((r = sysv_exec_commands(s, supports_reload)) < 0)
+                goto finish;
+
+        if (s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) {
+                /* If there a runlevels configured for this service
+                 * but none of the standard ones, then we assume this
+                 * is some special kind of service (which might be
+                 * needed for early boot) and don't create any links
+                 * to it. */
+
+                UNIT(s)->default_dependencies = false;
+
+                /* Don't timeout special services during boot (like fsck) */
+                s->timeout_start_usec = 0;
+                s->timeout_stop_usec = 0;
+        } else {
+                s->timeout_start_usec = DEFAULT_SYSV_TIMEOUT_USEC;
+                s->timeout_stop_usec = DEFAULT_SYSV_TIMEOUT_USEC;
+        }
+
+        /* Special setting for all SysV services */
+        s->type = SERVICE_FORKING;
+        s->remain_after_exit = !s->pid_file;
+        s->guess_main_pid = false;
+        s->restart = SERVICE_RESTART_NO;
+        s->exec_context.ignore_sigpipe = false;
+        s->kill_context.kill_mode = KILL_PROCESS;
+
+        /* We use the long description only if
+         * no short description is set. */
+
+        if (short_description)
+                description = short_description;
+        else if (chkconfig_description)
+                description = chkconfig_description;
+        else if (long_description)
+                description = long_description;
+        else
+                description = NULL;
+
+        if (description) {
+                char *d;
+
+                if (!(d = strappend(s->sysv_has_lsb ? "LSB: " : "SYSV: ", description))) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                u->description = d;
+        }
+
+        /* The priority that has been set in /etc/rcN.d/ hierarchies
+         * takes precedence over what is stored as default in the LSB
+         * header */
+        if (s->sysv_start_priority_from_rcnd >= 0)
+                s->sysv_start_priority = s->sysv_start_priority_from_rcnd;
+
+        u->load_state = UNIT_LOADED;
+        r = 0;
+
+finish:
+
+        if (f)
+                fclose(f);
+
+        free(short_description);
+        free(long_description);
+        free(chkconfig_description);
+
+        return r;
+}
+
+static int service_load_sysv_name(Service *s, const char *name) {
+        char **p;
+
+        assert(s);
+        assert(name);
+
+        /* For SysV services we strip the rc.* and *.sh
+         * prefixes/suffixes. */
+        if (startswith(name, "rc.") ||
+            endswith(name, ".sh.service"))
+                return -ENOENT;
+
+        STRV_FOREACH(p, UNIT(s)->manager->lookup_paths.sysvinit_path) {
+                char *path;
+                int r;
+
+                path = strjoin(*p, "/", name, NULL);
+                if (!path)
+                        return -ENOMEM;
+
+                assert(endswith(path, ".service"));
+                path[strlen(path)-8] = 0;
+
+                r = service_load_sysv_path(s, path);
+
+                if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) {
+                        /* Try Debian style *.sh source'able init scripts */
+                        strcat(path, ".sh");
+                        r = service_load_sysv_path(s, path);
+                }
+                free(path);
+
+                if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) {
+                        /* Try Frugalware style rc.* init scripts */
+
+                        path = strjoin(*p, "/rc.", name, NULL);
+                        if (!path)
+                                return -ENOMEM;
+
+                        /* Drop .service suffix */
+                        path[strlen(path)-8] = 0;
+                        r = service_load_sysv_path(s, path);
+                        free(path);
+                }
+
+                if (r < 0)
+                        return r;
+
+                if (UNIT(s)->load_state != UNIT_STUB)
+                        break;
+        }
+
+        return 0;
+}
+
+static int service_load_sysv(Service *s) {
+        const char *t;
+        Iterator i;
+        int r;
+
+        assert(s);
+
+        /* Load service data from SysV init scripts, preferably with
+         * LSB headers ... */
+
+        if (strv_isempty(UNIT(s)->manager->lookup_paths.sysvinit_path))
+                return 0;
+
+        if ((t = UNIT(s)->id))
+                if ((r = service_load_sysv_name(s, t)) < 0)
+                        return r;
+
+        if (UNIT(s)->load_state == UNIT_STUB)
+                SET_FOREACH(t, UNIT(s)->names, i) {
+                        if (t == UNIT(s)->id)
+                                continue;
+
+                        if ((r = service_load_sysv_name(s, t)) < 0)
+                                return r;
+
+                        if (UNIT(s)->load_state != UNIT_STUB)
+                                break;
+                }
+
+        return 0;
+}
+#endif
+
+static int fsck_fix_order(Service *s) {
+        Unit *other;
+        int r;
+
+        assert(s);
+
+        if (s->fsck_passno <= 0)
+                return 0;
+
+        /* For each pair of services where both have an fsck priority
+         * we order things based on it. */
+
+        LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_SERVICE]) {
+                Service *t;
+                UnitDependency d;
+
+                t = SERVICE(other);
+
+                if (s == t)
+                        continue;
+
+                if (UNIT(t)->load_state != UNIT_LOADED)
+                        continue;
+
+                if (t->fsck_passno <= 0)
+                        continue;
+
+                if (t->fsck_passno < s->fsck_passno)
+                        d = UNIT_AFTER;
+                else if (t->fsck_passno > s->fsck_passno)
+                        d = UNIT_BEFORE;
+                else
+                        continue;
+
+                if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int service_verify(Service *s) {
+        assert(s);
+
+        if (UNIT(s)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (!s->exec_command[SERVICE_EXEC_START]) {
+                log_error_unit(UNIT(s)->id,
+                               "%s lacks ExecStart setting. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->type != SERVICE_ONESHOT &&
+            s->exec_command[SERVICE_EXEC_START]->command_next) {
+                log_error_unit(UNIT(s)->id,
+                               "%s has more than one ExecStart setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->type == SERVICE_DBUS && !s->bus_name) {
+                log_error_unit(UNIT(s)->id,
+                               "%s is of type D-Bus but no D-Bus service name has been specified. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->bus_name && s->type != SERVICE_DBUS)
+                log_warning_unit(UNIT(s)->id,
+                                 "%s has a D-Bus service name specified, but is not of type dbus. Ignoring.", UNIT(s)->id);
+
+        if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
+                log_error_unit(UNIT(s)->id,
+                               "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static int service_add_default_dependencies(Service *s) {
+        int r;
+
+        assert(s);
+
+        /* Add a number of automatic dependencies useful for the
+         * majority of services. */
+
+        /* First, pull in base system */
+        if (UNIT(s)->manager->running_as == SYSTEMD_SYSTEM) {
+
+                if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
+                        return r;
+
+        } else if (UNIT(s)->manager->running_as == SYSTEMD_USER) {
+
+                if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SOCKETS_TARGET, NULL, true)) < 0)
+                        return r;
+        }
+
+        /* Second, activate normal shutdown */
+        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+}
+
+static void service_fix_output(Service *s) {
+        assert(s);
+
+        /* If nothing has been explicitly configured, patch default
+         * output in. If input is socket/tty we avoid this however,
+         * since in that case we want output to default to the same
+         * place as we read input from. */
+
+        if (s->exec_context.std_error == EXEC_OUTPUT_INHERIT &&
+            s->exec_context.std_output == EXEC_OUTPUT_INHERIT &&
+            s->exec_context.std_input == EXEC_INPUT_NULL)
+                s->exec_context.std_error = UNIT(s)->manager->default_std_error;
+
+        if (s->exec_context.std_output == EXEC_OUTPUT_INHERIT &&
+            s->exec_context.std_input == EXEC_INPUT_NULL)
+                s->exec_context.std_output = UNIT(s)->manager->default_std_output;
+}
+
+static int service_load(Unit *u) {
+        int r;
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        /* Load a .service file */
+        if ((r = unit_load_fragment(u)) < 0)
+                return r;
+
+#ifdef HAVE_SYSV_COMPAT
+        /* Load a classic init script as a fallback, if we couldn't find anything */
+        if (u->load_state == UNIT_STUB)
+                if ((r = service_load_sysv(s)) < 0)
+                        return r;
+#endif
+
+        /* Still nothing found? Then let's give up */
+        if (u->load_state == UNIT_STUB)
+                return -ENOENT;
+
+        /* We were able to load something, then let's add in the
+         * dropin directories. */
+        if ((r = unit_load_dropin(unit_follow_merge(u))) < 0)
+                return r;
+
+        /* This is a new unit? Then let's add in some extras */
+        if (u->load_state == UNIT_LOADED) {
+                if (s->type == _SERVICE_TYPE_INVALID)
+                        s->type = s->bus_name ? SERVICE_DBUS : SERVICE_SIMPLE;
+
+                /* Oneshot services have disabled start timeout by default */
+                if (s->type == SERVICE_ONESHOT && !s->start_timeout_defined)
+                        s->timeout_start_usec = 0;
+
+                service_fix_output(s);
+
+                if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
+                        return r;
+
+                if ((r = unit_add_default_cgroups(u)) < 0)
+                        return r;
+
+#ifdef HAVE_SYSV_COMPAT
+                if ((r = sysv_fix_order(s)) < 0)
+                        return r;
+#endif
+
+                if ((r = fsck_fix_order(s)) < 0)
+                        return r;
+
+                if (s->bus_name)
+                        if ((r = unit_watch_bus_name(u, s->bus_name)) < 0)
+                                return r;
+
+                if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE)
+                        s->notify_access = NOTIFY_MAIN;
+
+                if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE)
+                        s->notify_access = NOTIFY_MAIN;
+
+                if (s->type == SERVICE_DBUS || s->bus_name)
+                        if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true)) < 0)
+                                return r;
+
+                if (UNIT(s)->default_dependencies)
+                        if ((r = service_add_default_dependencies(s)) < 0)
+                                return r;
+
+                r = unit_exec_context_defaults(u, &s->exec_context);
+                if (r < 0)
+                        return r;
+        }
+
+        return service_verify(s);
+}
+
+static void service_dump(Unit *u, FILE *f, const char *prefix) {
+
+        ServiceExecCommand c;
+        Service *s = SERVICE(u);
+        const char *prefix2;
+        char *p2;
+
+        assert(s);
+
+        p2 = strappend(prefix, "\t");
+        prefix2 = p2 ? p2 : prefix;
+
+        fprintf(f,
+                "%sService State: %s\n"
+                "%sResult: %s\n"
+                "%sReload Result: %s\n"
+                "%sPermissionsStartOnly: %s\n"
+                "%sRootDirectoryStartOnly: %s\n"
+                "%sRemainAfterExit: %s\n"
+                "%sGuessMainPID: %s\n"
+                "%sType: %s\n"
+                "%sRestart: %s\n"
+                "%sNotifyAccess: %s\n",
+                prefix, service_state_to_string(s->state),
+                prefix, service_result_to_string(s->result),
+                prefix, service_result_to_string(s->reload_result),
+                prefix, yes_no(s->permissions_start_only),
+                prefix, yes_no(s->root_directory_start_only),
+                prefix, yes_no(s->remain_after_exit),
+                prefix, yes_no(s->guess_main_pid),
+                prefix, service_type_to_string(s->type),
+                prefix, service_restart_to_string(s->restart),
+                prefix, notify_access_to_string(s->notify_access));
+
+        if (s->control_pid > 0)
+                fprintf(f,
+                        "%sControl PID: %lu\n",
+                        prefix, (unsigned long) s->control_pid);
+
+        if (s->main_pid > 0)
+                fprintf(f,
+                        "%sMain PID: %lu\n"
+                        "%sMain PID Known: %s\n"
+                        "%sMain PID Alien: %s\n",
+                        prefix, (unsigned long) s->main_pid,
+                        prefix, yes_no(s->main_pid_known),
+                        prefix, yes_no(s->main_pid_alien));
+
+        if (s->pid_file)
+                fprintf(f,
+                        "%sPIDFile: %s\n",
+                        prefix, s->pid_file);
+
+        if (s->bus_name)
+                fprintf(f,
+                        "%sBusName: %s\n"
+                        "%sBus Name Good: %s\n",
+                        prefix, s->bus_name,
+                        prefix, yes_no(s->bus_name_good));
+
+        kill_context_dump(&s->kill_context, f, prefix);
+        exec_context_dump(&s->exec_context, f, prefix);
+
+        for (c = 0; c < _SERVICE_EXEC_COMMAND_MAX; c++) {
+
+                if (!s->exec_command[c])
+                        continue;
+
+                fprintf(f, "%s-> %s:\n",
+                        prefix, service_exec_command_to_string(c));
+
+                exec_command_dump_list(s->exec_command[c], f, prefix2);
+        }
+
+#ifdef HAVE_SYSV_COMPAT
+        if (s->is_sysv)
+                fprintf(f,
+                        "%sSysV Init Script has LSB Header: %s\n"
+                        "%sSysVEnabled: %s\n",
+                        prefix, yes_no(s->sysv_has_lsb),
+                        prefix, yes_no(s->sysv_enabled));
+
+        if (s->sysv_start_priority >= 0)
+                fprintf(f,
+                        "%sSysVStartPriority: %i\n",
+                        prefix, s->sysv_start_priority);
+
+        if (s->sysv_runlevels)
+                fprintf(f, "%sSysVRunLevels: %s\n",
+                        prefix, s->sysv_runlevels);
+#endif
+
+        if (s->fsck_passno > 0)
+                fprintf(f,
+                        "%sFsckPassNo: %i\n",
+                        prefix, s->fsck_passno);
+
+        if (s->status_text)
+                fprintf(f, "%sStatus Text: %s\n",
+                        prefix, s->status_text);
+
+        free(p2);
+}
+
+static int service_load_pid_file(Service *s, bool may_warn) {
+        char *k;
+        int r;
+        pid_t pid;
+
+        assert(s);
+
+        if (!s->pid_file)
+                return -ENOENT;
+
+        if ((r = read_one_line_file(s->pid_file, &k)) < 0) {
+                if (may_warn)
+                        log_info_unit(UNIT(s)->id,
+                                      "PID file %s not readable (yet?) after %s.",
+                                      s->pid_file, service_state_to_string(s->state));
+                return r;
+        }
+
+        r = parse_pid(k, &pid);
+        free(k);
+
+        if (r < 0)
+                return r;
+
+        if (kill(pid, 0) < 0 && errno != EPERM) {
+                if (may_warn)
+                        log_info_unit(UNIT(s)->id,
+                                      "PID %lu read from file %s does not exist.",
+                                      (unsigned long) pid, s->pid_file);
+                return -ESRCH;
+        }
+
+        if (s->main_pid_known) {
+                if (pid == s->main_pid)
+                        return 0;
+
+                log_debug_unit(UNIT(s)->id,
+                               "Main PID changing: %lu -> %lu",
+                               (unsigned long) s->main_pid, (unsigned long) pid);
+                service_unwatch_main_pid(s);
+                s->main_pid_known = false;
+        } else
+                log_debug_unit(UNIT(s)->id,
+                               "Main PID loaded: %lu", (unsigned long) pid);
+
+        if ((r = service_set_main_pid(s, pid)) < 0)
+                return r;
+
+        if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
+                /* FIXME: we need to do something here */
+                return r;
+
+        return 0;
+}
+
+static int service_search_main_pid(Service *s) {
+        pid_t pid;
+        int r;
+
+        assert(s);
+
+        /* If we know it anyway, don't ever fallback to unreliable
+         * heuristics */
+        if (s->main_pid_known)
+                return 0;
+
+        if (!s->guess_main_pid)
+                return 0;
+
+        assert(s->main_pid <= 0);
+
+        if ((pid = cgroup_bonding_search_main_pid_list(UNIT(s)->cgroup_bondings)) <= 0)
+                return -ENOENT;
+
+        log_debug_unit(UNIT(s)->id,
+                       "Main PID guessed: %lu", (unsigned long) pid);
+        if ((r = service_set_main_pid(s, pid)) < 0)
+                return r;
+
+        if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
+                /* FIXME: we need to do something here */
+                return r;
+
+        return 0;
+}
+
+static void service_notify_sockets_dead(Service *s, bool failed_permanent) {
+        Iterator i;
+        Unit *u;
+
+        assert(s);
+
+        /* Notifies all our sockets when we die */
+
+        if (s->socket_fd >= 0)
+                return;
+
+        SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i)
+                if (u->type == UNIT_SOCKET)
+                        socket_notify_service_dead(SOCKET(u), failed_permanent);
+
+        return;
+}
+
+static void service_set_state(Service *s, ServiceState state) {
+        ServiceState old_state;
+        const UnitActiveState *table;
+        assert(s);
+
+        table = s->type == SERVICE_IDLE ? state_translation_table_idle : state_translation_table;
+
+        old_state = s->state;
+        s->state = state;
+
+        service_unwatch_pid_file(s);
+
+        if (state != SERVICE_START_PRE &&
+            state != SERVICE_START &&
+            state != SERVICE_START_POST &&
+            state != SERVICE_RELOAD &&
+            state != SERVICE_STOP &&
+            state != SERVICE_STOP_SIGTERM &&
+            state != SERVICE_STOP_SIGKILL &&
+            state != SERVICE_STOP_POST &&
+            state != SERVICE_FINAL_SIGTERM &&
+            state != SERVICE_FINAL_SIGKILL &&
+            state != SERVICE_AUTO_RESTART)
+                unit_unwatch_timer(UNIT(s), &s->timer_watch);
+
+        if (state != SERVICE_START &&
+            state != SERVICE_START_POST &&
+            state != SERVICE_RUNNING &&
+            state != SERVICE_RELOAD &&
+            state != SERVICE_STOP &&
+            state != SERVICE_STOP_SIGTERM &&
+            state != SERVICE_STOP_SIGKILL) {
+                service_unwatch_main_pid(s);
+                s->main_command = NULL;
+        }
+
+        if (state != SERVICE_START_PRE &&
+            state != SERVICE_START &&
+            state != SERVICE_START_POST &&
+            state != SERVICE_RELOAD &&
+            state != SERVICE_STOP &&
+            state != SERVICE_STOP_SIGTERM &&
+            state != SERVICE_STOP_SIGKILL &&
+            state != SERVICE_STOP_POST &&
+            state != SERVICE_FINAL_SIGTERM &&
+            state != SERVICE_FINAL_SIGKILL) {
+                service_unwatch_control_pid(s);
+                s->control_command = NULL;
+                s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
+        }
+
+        if (state == SERVICE_DEAD ||
+            state == SERVICE_STOP ||
+            state == SERVICE_STOP_SIGTERM ||
+            state == SERVICE_STOP_SIGKILL ||
+            state == SERVICE_STOP_POST ||
+            state == SERVICE_FINAL_SIGTERM ||
+            state == SERVICE_FINAL_SIGKILL ||
+            state == SERVICE_FAILED ||
+            state == SERVICE_AUTO_RESTART)
+                service_notify_sockets_dead(s, false);
+
+        if (state != SERVICE_START_PRE &&
+            state != SERVICE_START &&
+            state != SERVICE_START_POST &&
+            state != SERVICE_RUNNING &&
+            state != SERVICE_RELOAD &&
+            state != SERVICE_STOP &&
+            state != SERVICE_STOP_SIGTERM &&
+            state != SERVICE_STOP_SIGKILL &&
+            state != SERVICE_STOP_POST &&
+            state != SERVICE_FINAL_SIGTERM &&
+            state != SERVICE_FINAL_SIGKILL &&
+            !(state == SERVICE_DEAD && UNIT(s)->job)) {
+                service_close_socket_fd(s);
+                service_connection_unref(s);
+        }
+
+        if (state == SERVICE_STOP)
+                service_stop_watchdog(s);
+
+        /* For the inactive states unit_notify() will trim the cgroup,
+         * but for exit we have to do that ourselves... */
+        if (state == SERVICE_EXITED && UNIT(s)->manager->n_reloading <= 0)
+                cgroup_bonding_trim_list(UNIT(s)->cgroup_bondings, true);
+
+        if (old_state != state)
+                log_debug_unit(UNIT(s)->id,
+                               "%s changed %s -> %s", UNIT(s)->id,
+                               service_state_to_string(old_state),
+                               service_state_to_string(state));
+
+        unit_notify(UNIT(s), table[old_state], table[state], s->reload_result == SERVICE_SUCCESS);
+        s->reload_result = SERVICE_SUCCESS;
+}
+
+static int service_coldplug(Unit *u) {
+        Service *s = SERVICE(u);
+        int r;
+
+        assert(s);
+        assert(s->state == SERVICE_DEAD);
+
+        if (s->deserialized_state != s->state) {
+
+                if (s->deserialized_state == SERVICE_START_PRE ||
+                    s->deserialized_state == SERVICE_START ||
+                    s->deserialized_state == SERVICE_START_POST ||
+                    s->deserialized_state == SERVICE_RELOAD ||
+                    s->deserialized_state == SERVICE_STOP ||
+                    s->deserialized_state == SERVICE_STOP_SIGTERM ||
+                    s->deserialized_state == SERVICE_STOP_SIGKILL ||
+                    s->deserialized_state == SERVICE_STOP_POST ||
+                    s->deserialized_state == SERVICE_FINAL_SIGTERM ||
+                    s->deserialized_state == SERVICE_FINAL_SIGKILL ||
+                    s->deserialized_state == SERVICE_AUTO_RESTART) {
+                        if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_start_usec > 0) {
+                                usec_t k;
+
+                                k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_start_usec;
+
+                                r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, k, &s->timer_watch);
+                                if (r < 0)
+                                        return r;
+                        }
+                }
+
+                if ((s->deserialized_state == SERVICE_START &&
+                     (s->type == SERVICE_FORKING ||
+                      s->type == SERVICE_DBUS ||
+                      s->type == SERVICE_ONESHOT ||
+                      s->type == SERVICE_NOTIFY)) ||
+                    s->deserialized_state == SERVICE_START_POST ||
+                    s->deserialized_state == SERVICE_RUNNING ||
+                    s->deserialized_state == SERVICE_RELOAD ||
+                    s->deserialized_state == SERVICE_STOP ||
+                    s->deserialized_state == SERVICE_STOP_SIGTERM ||
+                    s->deserialized_state == SERVICE_STOP_SIGKILL)
+                        if (s->main_pid > 0)
+                                if ((r = unit_watch_pid(UNIT(s), s->main_pid)) < 0)
+                                        return r;
+
+                if (s->deserialized_state == SERVICE_START_PRE ||
+                    s->deserialized_state == SERVICE_START ||
+                    s->deserialized_state == SERVICE_START_POST ||
+                    s->deserialized_state == SERVICE_RELOAD ||
+                    s->deserialized_state == SERVICE_STOP ||
+                    s->deserialized_state == SERVICE_STOP_SIGTERM ||
+                    s->deserialized_state == SERVICE_STOP_SIGKILL ||
+                    s->deserialized_state == SERVICE_STOP_POST ||
+                    s->deserialized_state == SERVICE_FINAL_SIGTERM ||
+                    s->deserialized_state == SERVICE_FINAL_SIGKILL)
+                        if (s->control_pid > 0)
+                                if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0)
+                                        return r;
+
+                if (s->deserialized_state == SERVICE_START_POST ||
+                    s->deserialized_state == SERVICE_RUNNING)
+                        service_handle_watchdog(s);
+
+                service_set_state(s, s->deserialized_state);
+        }
+        return 0;
+}
+
+static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
+        Iterator i;
+        int r;
+        int *rfds = NULL;
+        unsigned rn_fds = 0;
+        Unit *u;
+
+        assert(s);
+        assert(fds);
+        assert(n_fds);
+
+        if (s->socket_fd >= 0)
+                return 0;
+
+        SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) {
+                int *cfds;
+                unsigned cn_fds;
+                Socket *sock;
+
+                if (u->type != UNIT_SOCKET)
+                        continue;
+
+                sock = SOCKET(u);
+
+                if ((r = socket_collect_fds(sock, &cfds, &cn_fds)) < 0)
+                        goto fail;
+
+                if (!cfds)
+                        continue;
+
+                if (!rfds) {
+                        rfds = cfds;
+                        rn_fds = cn_fds;
+                } else {
+                        int *t;
+
+                        if (!(t = new(int, rn_fds+cn_fds))) {
+                                free(cfds);
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        memcpy(t, rfds, rn_fds * sizeof(int));
+                        memcpy(t+rn_fds, cfds, cn_fds * sizeof(int));
+                        free(rfds);
+                        free(cfds);
+
+                        rfds = t;
+                        rn_fds = rn_fds+cn_fds;
+                }
+        }
+
+        *fds = rfds;
+        *n_fds = rn_fds;
+
+        return 0;
+
+fail:
+        free(rfds);
+
+        return r;
+}
+
+static int service_spawn(
+                Service *s,
+                ExecCommand *c,
+                bool timeout,
+                bool pass_fds,
+                bool apply_permissions,
+                bool apply_chroot,
+                bool apply_tty_stdin,
+                bool set_notify_socket,
+                bool is_control,
+                pid_t *_pid) {
+
+        pid_t pid;
+        int r;
+        int *fds = NULL, *fdsbuf = NULL;
+        unsigned n_fds = 0, n_env = 0;
+        char **argv = NULL, **final_env = NULL, **our_env = NULL;
+
+        assert(s);
+        assert(c);
+        assert(_pid);
+
+        if (pass_fds ||
+            s->exec_context.std_input == EXEC_INPUT_SOCKET ||
+            s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
+            s->exec_context.std_error == EXEC_OUTPUT_SOCKET) {
+
+                if (s->socket_fd >= 0) {
+                        fds = &s->socket_fd;
+                        n_fds = 1;
+                } else {
+                        if ((r = service_collect_fds(s, &fdsbuf, &n_fds)) < 0)
+                                goto fail;
+
+                        fds = fdsbuf;
+                }
+        }
+
+        if (timeout && s->timeout_start_usec) {
+                r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_start_usec, &s->timer_watch);
+                if (r < 0)
+                        goto fail;
+        } else
+                unit_unwatch_timer(UNIT(s), &s->timer_watch);
+
+        if (!(argv = unit_full_printf_strv(UNIT(s), c->argv))) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        our_env = new0(char*, 5);
+        if (!our_env) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        if (set_notify_socket)
+                if (asprintf(our_env + n_env++, "NOTIFY_SOCKET=%s", UNIT(s)->manager->notify_socket) < 0) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+        if (s->main_pid > 0)
+                if (asprintf(our_env + n_env++, "MAINPID=%lu", (unsigned long) s->main_pid) < 0) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+        if (s->watchdog_usec > 0)
+                if (asprintf(our_env + n_env++, "WATCHDOG_USEC=%llu", (unsigned long long) s->watchdog_usec) < 0) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+        if (s->meta.manager->running_as != SYSTEMD_SYSTEM)
+                if (asprintf(our_env + n_env++, "MANAGERPID=%lu", (unsigned long) getpid()) < 0) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+        final_env = strv_env_merge(2, UNIT(s)->manager->environment, our_env, NULL);
+        if (!final_env) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        r = exec_spawn(c,
+                       argv,
+                       &s->exec_context,
+                       fds, n_fds,
+                       final_env,
+                       apply_permissions,
+                       apply_chroot,
+                       apply_tty_stdin,
+                       UNIT(s)->manager->confirm_spawn,
+                       UNIT(s)->cgroup_bondings,
+                       UNIT(s)->cgroup_attributes,
+                       is_control ? "control" : NULL,
+                       UNIT(s)->id,
+                       s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL,
+                       &pid);
+
+        if (r < 0)
+                goto fail;
+
+        if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
+                /* FIXME: we need to do something here */
+                goto fail;
+
+        free(fdsbuf);
+        strv_free(argv);
+        strv_free(our_env);
+        strv_free(final_env);
+
+        *_pid = pid;
+
+        return 0;
+
+fail:
+        free(fdsbuf);
+        strv_free(argv);
+        strv_free(our_env);
+        strv_free(final_env);
+
+        if (timeout)
+                unit_unwatch_timer(UNIT(s), &s->timer_watch);
+
+        return r;
+}
+
+static int main_pid_good(Service *s) {
+        assert(s);
+
+        /* Returns 0 if the pid is dead, 1 if it is good, -1 if we
+         * don't know */
+
+        /* If we know the pid file, then lets just check if it is
+         * still valid */
+        if (s->main_pid_known) {
+
+                /* If it's an alien child let's check if it is still
+                 * alive ... */
+                if (s->main_pid_alien)
+                        return kill(s->main_pid, 0) >= 0 || errno != ESRCH;
+
+                /* .. otherwise assume we'll get a SIGCHLD for it,
+                 * which we really should wait for to collect exit
+                 * status and code */
+                return s->main_pid > 0;
+        }
+
+        /* We don't know the pid */
+        return -EAGAIN;
+}
+
+static int control_pid_good(Service *s) {
+        assert(s);
+
+        return s->control_pid > 0;
+}
+
+static int cgroup_good(Service *s) {
+        int r;
+
+        assert(s);
+
+        if ((r = cgroup_bonding_is_empty_list(UNIT(s)->cgroup_bondings)) < 0)
+                return r;
+
+        return !r;
+}
+
+static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
+        int r;
+        assert(s);
+
+        if (f != SERVICE_SUCCESS)
+                s->result = f;
+
+        service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
+
+        if (allow_restart &&
+            !s->forbid_restart &&
+            (s->restart == SERVICE_RESTART_ALWAYS ||
+             (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) ||
+             (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) ||
+             (s->restart == SERVICE_RESTART_ON_ABORT && (s->result == SERVICE_FAILURE_SIGNAL ||
+                                                         s->result == SERVICE_FAILURE_CORE_DUMP))) &&
+            (s->result != SERVICE_FAILURE_EXIT_CODE ||
+             !set_contains(s->restart_ignore_status.code, INT_TO_PTR(s->main_exec_status.status))) &&
+            (s->result != SERVICE_FAILURE_SIGNAL ||
+             !set_contains(s->restart_ignore_status.signal, INT_TO_PTR(s->main_exec_status.status)))
+                ) {
+
+                r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->restart_usec, &s->timer_watch);
+                if (r < 0)
+                        goto fail;
+
+                service_set_state(s, SERVICE_AUTO_RESTART);
+        }
+
+        s->forbid_restart = false;
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run install restart timer: %s",
+                         UNIT(s)->id, strerror(-r));
+        service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false);
+}
+
+static void service_enter_signal(Service *s, ServiceState state, ServiceResult f);
+
+static void service_enter_stop_post(Service *s, ServiceResult f) {
+        int r;
+        assert(s);
+
+        if (f != SERVICE_SUCCESS)
+                s->result = f;
+
+        service_unwatch_control_pid(s);
+
+        if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP_POST])) {
+                s->control_command_id = SERVICE_EXEC_STOP_POST;
+
+                r = service_spawn(s,
+                                  s->control_command,
+                                  true,
+                                  false,
+                                  !s->permissions_start_only,
+                                  !s->root_directory_start_only,
+                                  true,
+                                  false,
+                                  true,
+                                  &s->control_pid);
+                if (r < 0)
+                        goto fail;
+
+
+                service_set_state(s, SERVICE_STOP_POST);
+        } else
+                service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'stop-post' task: %s",
+                         UNIT(s)->id, strerror(-r));
+        service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+}
+
+static void service_enter_signal(Service *s, ServiceState state, ServiceResult f) {
+        int r;
+        Set *pid_set = NULL;
+        bool wait_for_exit = false;
+
+        assert(s);
+
+        if (f != SERVICE_SUCCESS)
+                s->result = f;
+
+        if (s->kill_context.kill_mode != KILL_NONE) {
+                int sig = (state == SERVICE_STOP_SIGTERM || state == SERVICE_FINAL_SIGTERM) ? s->kill_context.kill_signal : SIGKILL;
+
+                if (s->main_pid > 0) {
+                        if (kill_and_sigcont(s->main_pid, sig) < 0 && errno != ESRCH)
+                                log_warning_unit(UNIT(s)->id,
+                                                 "Failed to kill main process %li: %m", (long) s->main_pid);
+                        else
+                                wait_for_exit = !s->main_pid_alien;
+                }
+
+                if (s->control_pid > 0) {
+                        if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
+                                log_warning_unit(UNIT(s)->id,
+                                                 "Failed to kill control process %li: %m", (long) s->control_pid);
+                        else
+                                wait_for_exit = true;
+                }
+
+                if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) {
+
+                        pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                        if (!pid_set) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        /* Exclude the main/control pids from being killed via the cgroup */
+                        if (s->main_pid > 0)
+                                if ((r = set_put(pid_set, LONG_TO_PTR(s->main_pid))) < 0)
+                                        goto fail;
+
+                        if (s->control_pid > 0)
+                                if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
+                                        goto fail;
+
+                        r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
+                        if (r < 0) {
+                                if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
+                                        log_warning_unit(UNIT(s)->id,
+                                                         "Failed to kill control group: %s", strerror(-r));
+                        } else if (r > 0)
+                                wait_for_exit = true;
+
+                        set_free(pid_set);
+                        pid_set = NULL;
+                }
+        }
+
+        if (wait_for_exit) {
+                if (s->timeout_stop_usec > 0) {
+                        r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_stop_usec, &s->timer_watch);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                service_set_state(s, state);
+        } else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL)
+                service_enter_stop_post(s, SERVICE_SUCCESS);
+        else
+                service_enter_dead(s, SERVICE_SUCCESS, true);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
+
+        if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL)
+                service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES);
+        else
+                service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
+
+        if (pid_set)
+                set_free(pid_set);
+}
+
+static void service_enter_stop(Service *s, ServiceResult f) {
+        int r;
+
+        assert(s);
+
+        if (f != SERVICE_SUCCESS)
+                s->result = f;
+
+        service_unwatch_control_pid(s);
+
+        if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP])) {
+                s->control_command_id = SERVICE_EXEC_STOP;
+
+                r = service_spawn(s,
+                                  s->control_command,
+                                  true,
+                                  false,
+                                  !s->permissions_start_only,
+                                  !s->root_directory_start_only,
+                                  false,
+                                  false,
+                                  true,
+                                  &s->control_pid);
+                if (r < 0)
+                        goto fail;
+
+                service_set_state(s, SERVICE_STOP);
+        } else
+                service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'stop' task: %s", UNIT(s)->id, strerror(-r));
+        service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
+}
+
+static void service_enter_running(Service *s, ServiceResult f) {
+        int main_pid_ok, cgroup_ok;
+        assert(s);
+
+        if (f != SERVICE_SUCCESS)
+                s->result = f;
+
+        main_pid_ok = main_pid_good(s);
+        cgroup_ok = cgroup_good(s);
+
+        if ((main_pid_ok > 0 || (main_pid_ok < 0 && cgroup_ok != 0)) &&
+            (s->bus_name_good || s->type != SERVICE_DBUS))
+                service_set_state(s, SERVICE_RUNNING);
+        else if (s->remain_after_exit)
+                service_set_state(s, SERVICE_EXITED);
+        else
+                service_enter_stop(s, SERVICE_SUCCESS);
+}
+
+static void service_enter_start_post(Service *s) {
+        int r;
+        assert(s);
+
+        service_unwatch_control_pid(s);
+
+        if (s->watchdog_usec > 0)
+                service_reset_watchdog(s);
+
+        if ((s->control_command = s->exec_command[SERVICE_EXEC_START_POST])) {
+                s->control_command_id = SERVICE_EXEC_START_POST;
+
+                r = service_spawn(s,
+                                  s->control_command,
+                                  true,
+                                  false,
+                                  !s->permissions_start_only,
+                                  !s->root_directory_start_only,
+                                  false,
+                                  false,
+                                  true,
+                                  &s->control_pid);
+                if (r < 0)
+                        goto fail;
+
+                service_set_state(s, SERVICE_START_POST);
+        } else
+                service_enter_running(s, SERVICE_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r));
+        service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+}
+
+static void service_enter_start(Service *s) {
+        pid_t pid;
+        int r;
+        ExecCommand *c;
+
+        assert(s);
+
+        assert(s->exec_command[SERVICE_EXEC_START]);
+        assert(!s->exec_command[SERVICE_EXEC_START]->command_next || s->type == SERVICE_ONESHOT);
+
+        if (s->type == SERVICE_FORKING)
+                service_unwatch_control_pid(s);
+        else
+                service_unwatch_main_pid(s);
+
+        /* We want to ensure that nobody leaks processes from
+         * START_PRE here, so let's go on a killing spree, People
+         * should not spawn long running processes from START_PRE. */
+        cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control");
+
+        if (s->type == SERVICE_FORKING) {
+                s->control_command_id = SERVICE_EXEC_START;
+                c = s->control_command = s->exec_command[SERVICE_EXEC_START];
+
+                s->main_command = NULL;
+        } else {
+                s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
+                s->control_command = NULL;
+
+                c = s->main_command = s->exec_command[SERVICE_EXEC_START];
+        }
+
+        r = service_spawn(s,
+                          c,
+                          s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY || s->type == SERVICE_ONESHOT,
+                          true,
+                          true,
+                          true,
+                          true,
+                          s->notify_access != NOTIFY_NONE,
+                          false,
+                          &pid);
+        if (r < 0)
+                goto fail;
+
+        if (s->type == SERVICE_SIMPLE || s->type == SERVICE_IDLE) {
+                /* For simple services we immediately start
+                 * the START_POST binaries. */
+
+                service_set_main_pid(s, pid);
+                service_enter_start_post(s);
+
+        } else  if (s->type == SERVICE_FORKING) {
+
+                /* For forking services we wait until the start
+                 * process exited. */
+
+                s->control_pid = pid;
+                service_set_state(s, SERVICE_START);
+
+        } else if (s->type == SERVICE_ONESHOT ||
+                   s->type == SERVICE_DBUS ||
+                   s->type == SERVICE_NOTIFY) {
+
+                /* For oneshot services we wait until the start
+                 * process exited, too, but it is our main process. */
+
+                /* For D-Bus services we know the main pid right away,
+                 * but wait for the bus name to appear on the
+                 * bus. Notify services are similar. */
+
+                service_set_main_pid(s, pid);
+                service_set_state(s, SERVICE_START);
+        } else
+                assert_not_reached("Unknown service type");
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'start' task: %s", UNIT(s)->id, strerror(-r));
+        service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+}
+
+static void service_enter_start_pre(Service *s) {
+        int r;
+
+        assert(s);
+
+        service_unwatch_control_pid(s);
+
+        if ((s->control_command = s->exec_command[SERVICE_EXEC_START_PRE])) {
+
+                /* Before we start anything, let's clear up what might
+                 * be left from previous runs. */
+                cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control");
+
+                s->control_command_id = SERVICE_EXEC_START_PRE;
+
+                r = service_spawn(s,
+                                  s->control_command,
+                                  true,
+                                  false,
+                                  !s->permissions_start_only,
+                                  !s->root_directory_start_only,
+                                  true,
+                                  false,
+                                  true,
+                                  &s->control_pid);
+                if (r < 0)
+                        goto fail;
+
+                service_set_state(s, SERVICE_START_PRE);
+        } else
+                service_enter_start(s);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r));
+        service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
+}
+
+static void service_enter_restart(Service *s) {
+        int r;
+        DBusError error;
+
+        assert(s);
+        dbus_error_init(&error);
+
+        if (UNIT(s)->job && UNIT(s)->job->type == JOB_STOP) {
+                /* Don't restart things if we are going down anyway */
+                log_info_unit(UNIT(s)->id,
+                              "Stop job pending for unit, delaying automatic restart.");
+
+                r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->restart_usec, &s->timer_watch);
+                if (r < 0)
+                        goto fail;
+
+                return;
+        }
+
+        /* Any units that are bound to this service must also be
+         * restarted. We use JOB_RESTART (instead of the more obvious
+         * JOB_START) here so that those dependency jobs will be added
+         * as well. */
+        r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_FAIL, false, &error, NULL);
+        if (r < 0)
+                goto fail;
+
+        /* Note that we stay in the SERVICE_AUTO_RESTART state here,
+         * it will be canceled as part of the service_stop() call that
+         * is executed as part of JOB_RESTART. */
+
+        log_debug_unit(UNIT(s)->id,
+                       "%s scheduled restart job.", UNIT(s)->id);
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to schedule restart job: %s",
+                         UNIT(s)->id, bus_error(&error, -r));
+        service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false);
+
+        dbus_error_free(&error);
+}
+
+static void service_enter_reload(Service *s) {
+        int r;
+
+        assert(s);
+
+        service_unwatch_control_pid(s);
+
+        if ((s->control_command = s->exec_command[SERVICE_EXEC_RELOAD])) {
+                s->control_command_id = SERVICE_EXEC_RELOAD;
+
+                r = service_spawn(s,
+                                  s->control_command,
+                                  true,
+                                  false,
+                                  !s->permissions_start_only,
+                                  !s->root_directory_start_only,
+                                  false,
+                                  false,
+                                  true,
+                                  &s->control_pid);
+                if (r < 0)
+                        goto fail;
+
+                service_set_state(s, SERVICE_RELOAD);
+        } else
+                service_enter_running(s, SERVICE_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'reload' task: %s",
+                         UNIT(s)->id, strerror(-r));
+        s->reload_result = SERVICE_FAILURE_RESOURCES;
+        service_enter_running(s, SERVICE_SUCCESS);
+}
+
+static void service_run_next_control(Service *s) {
+        int r;
+
+        assert(s);
+        assert(s->control_command);
+        assert(s->control_command->command_next);
+
+        assert(s->control_command_id != SERVICE_EXEC_START);
+
+        s->control_command = s->control_command->command_next;
+        service_unwatch_control_pid(s);
+
+        r = service_spawn(s,
+                          s->control_command,
+                          true,
+                          false,
+                          !s->permissions_start_only,
+                          !s->root_directory_start_only,
+                          s->control_command_id == SERVICE_EXEC_START_PRE ||
+                          s->control_command_id == SERVICE_EXEC_STOP_POST,
+                          false,
+                          true,
+                          &s->control_pid);
+        if (r < 0)
+                goto fail;
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run next control task: %s",
+                         UNIT(s)->id, strerror(-r));
+
+        if (s->state == SERVICE_START_PRE)
+                service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+        else if (s->state == SERVICE_STOP)
+                service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
+        else if (s->state == SERVICE_STOP_POST)
+                service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
+        else if (s->state == SERVICE_RELOAD) {
+                s->reload_result = SERVICE_FAILURE_RESOURCES;
+                service_enter_running(s, SERVICE_SUCCESS);
+        } else
+                service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+}
+
+static void service_run_next_main(Service *s) {
+        pid_t pid;
+        int r;
+
+        assert(s);
+        assert(s->main_command);
+        assert(s->main_command->command_next);
+        assert(s->type == SERVICE_ONESHOT);
+
+        s->main_command = s->main_command->command_next;
+        service_unwatch_main_pid(s);
+
+        r = service_spawn(s,
+                          s->main_command,
+                          true,
+                          true,
+                          true,
+                          true,
+                          true,
+                          s->notify_access != NOTIFY_NONE,
+                          false,
+                          &pid);
+        if (r < 0)
+                goto fail;
+
+        service_set_main_pid(s, pid);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run next main task: %s", UNIT(s)->id, strerror(-r));
+        service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+}
+
+static int service_start_limit_test(Service *s) {
+        assert(s);
+
+        if (ratelimit_test(&s->start_limit))
+                return 0;
+
+        switch (s->start_limit_action) {
+
+        case SERVICE_START_LIMIT_NONE:
+                log_warning_unit(UNIT(s)->id,
+                                 "%s start request repeated too quickly, refusing to start.",
+                                 UNIT(s)->id);
+                break;
+
+        case SERVICE_START_LIMIT_REBOOT: {
+                DBusError error;
+                int r;
+
+                dbus_error_init(&error);
+
+                log_warning_unit(UNIT(s)->id,
+                                 "%s start request repeated too quickly, rebooting.", UNIT(s)->id);
+
+                r = manager_add_job_by_name(UNIT(s)->manager, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL);
+                if (r < 0) {
+                        log_error_unit(UNIT(s)->id,
+                                       "Failed to reboot: %s.", bus_error(&error, r));
+                        dbus_error_free(&error);
+                }
+
+                break;
+        }
+
+        case SERVICE_START_LIMIT_REBOOT_FORCE:
+                log_warning_unit(UNIT(s)->id,
+                                 "%s start request repeated too quickly, forcibly rebooting.", UNIT(s)->id);
+                UNIT(s)->manager->exit_code = MANAGER_REBOOT;
+                break;
+
+        case SERVICE_START_LIMIT_REBOOT_IMMEDIATE:
+                log_warning_unit(UNIT(s)->id,
+                                 "%s start request repeated too quickly, rebooting immediately.", UNIT(s)->id);
+                sync();
+                reboot(RB_AUTOBOOT);
+                break;
+
+        default:
+                log_error_unit(UNIT(s)->id,
+                               "start limit action=%i", s->start_limit_action);
+                assert_not_reached("Unknown StartLimitAction.");
+        }
+
+        return -ECANCELED;
+}
+
+static int service_start(Unit *u) {
+        Service *s = SERVICE(u);
+        int r;
+
+        assert(s);
+
+        /* We cannot fulfill this request right now, try again later
+         * please! */
+        if (s->state == SERVICE_STOP ||
+            s->state == SERVICE_STOP_SIGTERM ||
+            s->state == SERVICE_STOP_SIGKILL ||
+            s->state == SERVICE_STOP_POST ||
+            s->state == SERVICE_FINAL_SIGTERM ||
+            s->state == SERVICE_FINAL_SIGKILL)
+                return -EAGAIN;
+
+        /* Already on it! */
+        if (s->state == SERVICE_START_PRE ||
+            s->state == SERVICE_START ||
+            s->state == SERVICE_START_POST)
+                return 0;
+
+        /* A service that will be restarted must be stopped first to
+         * trigger BindsTo and/or OnFailure dependencies. If a user
+         * does not want to wait for the holdoff time to elapse, the
+         * service should be manually restarted, not started. We
+         * simply return EAGAIN here, so that any start jobs stay
+         * queued, and assume that the auto restart timer will
+         * eventually trigger the restart. */
+        if (s->state == SERVICE_AUTO_RESTART)
+                return -EAGAIN;
+
+        assert(s->state == SERVICE_DEAD || s->state == SERVICE_FAILED);
+
+        /* Make sure we don't enter a busy loop of some kind. */
+        r = service_start_limit_test(s);
+        if (r < 0) {
+                service_enter_dead(s, SERVICE_FAILURE_START_LIMIT, false);
+                return r;
+        }
+
+        s->result = SERVICE_SUCCESS;
+        s->reload_result = SERVICE_SUCCESS;
+        s->main_pid_known = false;
+        s->main_pid_alien = false;
+        s->forbid_restart = false;
+
+        service_enter_start_pre(s);
+        return 0;
+}
+
+static int service_stop(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        /* Don't create restart jobs from here. */
+        s->forbid_restart = true;
+
+        /* Already on it */
+        if (s->state == SERVICE_STOP ||
+            s->state == SERVICE_STOP_SIGTERM ||
+            s->state == SERVICE_STOP_SIGKILL ||
+            s->state == SERVICE_STOP_POST ||
+            s->state == SERVICE_FINAL_SIGTERM ||
+            s->state == SERVICE_FINAL_SIGKILL)
+                return 0;
+
+        /* A restart will be scheduled or is in progress. */
+        if (s->state == SERVICE_AUTO_RESTART) {
+                service_set_state(s, SERVICE_DEAD);
+                return 0;
+        }
+
+        /* If there's already something running we go directly into
+         * kill mode. */
+        if (s->state == SERVICE_START_PRE ||
+            s->state == SERVICE_START ||
+            s->state == SERVICE_START_POST ||
+            s->state == SERVICE_RELOAD) {
+                service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS);
+                return 0;
+        }
+
+        assert(s->state == SERVICE_RUNNING ||
+               s->state == SERVICE_EXITED);
+
+        service_enter_stop(s, SERVICE_SUCCESS);
+        return 0;
+}
+
+static int service_reload(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED);
+
+        service_enter_reload(s);
+        return 0;
+}
+
+static bool service_can_reload(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        return !!s->exec_command[SERVICE_EXEC_RELOAD];
+}
+
+static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Service *s = SERVICE(u);
+
+        assert(u);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", service_state_to_string(s->state));
+        unit_serialize_item(u, f, "result", service_result_to_string(s->result));
+        unit_serialize_item(u, f, "reload-result", service_result_to_string(s->reload_result));
+
+        if (s->control_pid > 0)
+                unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
+
+        if (s->main_pid_known && s->main_pid > 0)
+                unit_serialize_item_format(u, f, "main-pid", "%lu", (unsigned long) s->main_pid);
+
+        unit_serialize_item(u, f, "main-pid-known", yes_no(s->main_pid_known));
+
+        if (s->status_text)
+                unit_serialize_item(u, f, "status-text", s->status_text);
+
+        /* FIXME: There's a minor uncleanliness here: if there are
+         * multiple commands attached here, we will start from the
+         * first one again */
+        if (s->control_command_id >= 0)
+                unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id));
+
+        if (s->socket_fd >= 0) {
+                int copy;
+
+                if ((copy = fdset_put_dup(fds, s->socket_fd)) < 0)
+                        return copy;
+
+                unit_serialize_item_format(u, f, "socket-fd", "%i", copy);
+        }
+
+        if (s->main_exec_status.pid > 0) {
+                unit_serialize_item_format(u, f, "main-exec-status-pid", "%lu", (unsigned long) s->main_exec_status.pid);
+                dual_timestamp_serialize(f, "main-exec-status-start", &s->main_exec_status.start_timestamp);
+                dual_timestamp_serialize(f, "main-exec-status-exit", &s->main_exec_status.exit_timestamp);
+
+                if (dual_timestamp_is_set(&s->main_exec_status.exit_timestamp)) {
+                        unit_serialize_item_format(u, f, "main-exec-status-code", "%i", s->main_exec_status.code);
+                        unit_serialize_item_format(u, f, "main-exec-status-status", "%i", s->main_exec_status.status);
+                }
+        }
+        if (dual_timestamp_is_set(&s->watchdog_timestamp))
+                dual_timestamp_serialize(f, "watchdog-timestamp", &s->watchdog_timestamp);
+
+        return 0;
+}
+
+static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Service *s = SERVICE(u);
+
+        assert(u);
+        assert(key);
+        assert(value);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                ServiceState state;
+
+                if ((state = service_state_from_string(value)) < 0)
+                        log_debug_unit(u->id, "Failed to parse state value %s", value);
+                else
+                        s->deserialized_state = state;
+        } else if (streq(key, "result")) {
+                ServiceResult f;
+
+                f = service_result_from_string(value);
+                if (f < 0)
+                        log_debug_unit(u->id, "Failed to parse result value %s", value);
+                else if (f != SERVICE_SUCCESS)
+                        s->result = f;
+
+        } else if (streq(key, "reload-result")) {
+                ServiceResult f;
+
+                f = service_result_from_string(value);
+                if (f < 0)
+                        log_debug_unit(u->id, "Failed to parse reload result value %s", value);
+                else if (f != SERVICE_SUCCESS)
+                        s->reload_result = f;
+
+        } else if (streq(key, "control-pid")) {
+                pid_t pid;
+
+                if (parse_pid(value, &pid) < 0)
+                        log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
+                else
+                        s->control_pid = pid;
+        } else if (streq(key, "main-pid")) {
+                pid_t pid;
+
+                if (parse_pid(value, &pid) < 0)
+                        log_debug_unit(u->id, "Failed to parse main-pid value %s", value);
+                else
+                        service_set_main_pid(s, (pid_t) pid);
+        } else if (streq(key, "main-pid-known")) {
+                int b;
+
+                if ((b = parse_boolean(value)) < 0)
+                        log_debug_unit(u->id, "Failed to parse main-pid-known value %s", value);
+                else
+                        s->main_pid_known = b;
+        } else if (streq(key, "status-text")) {
+                char *t;
+
+                if ((t = strdup(value))) {
+                        free(s->status_text);
+                        s->status_text = t;
+                }
+
+        } else if (streq(key, "control-command")) {
+                ServiceExecCommand id;
+
+                if ((id = service_exec_command_from_string(value)) < 0)
+                        log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
+                else {
+                        s->control_command_id = id;
+                        s->control_command = s->exec_command[id];
+                }
+        } else if (streq(key, "socket-fd")) {
+                int fd;
+
+                if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+                        log_debug_unit(u->id, "Failed to parse socket-fd value %s", value);
+                else {
+
+                        if (s->socket_fd >= 0)
+                                close_nointr_nofail(s->socket_fd);
+                        s->socket_fd = fdset_remove(fds, fd);
+                }
+        } else if (streq(key, "main-exec-status-pid")) {
+                pid_t pid;
+
+                if (parse_pid(value, &pid) < 0)
+                        log_debug_unit(u->id, "Failed to parse main-exec-status-pid value %s", value);
+                else
+                        s->main_exec_status.pid = pid;
+        } else if (streq(key, "main-exec-status-code")) {
+                int i;
+
+                if (safe_atoi(value, &i) < 0)
+                        log_debug_unit(u->id, "Failed to parse main-exec-status-code value %s", value);
+                else
+                        s->main_exec_status.code = i;
+        } else if (streq(key, "main-exec-status-status")) {
+                int i;
+
+                if (safe_atoi(value, &i) < 0)
+                        log_debug_unit(u->id, "Failed to parse main-exec-status-status value %s", value);
+                else
+                        s->main_exec_status.status = i;
+        } else if (streq(key, "main-exec-status-start"))
+                dual_timestamp_deserialize(value, &s->main_exec_status.start_timestamp);
+        else if (streq(key, "main-exec-status-exit"))
+                dual_timestamp_deserialize(value, &s->main_exec_status.exit_timestamp);
+        else if (streq(key, "watchdog-timestamp"))
+                dual_timestamp_deserialize(value, &s->watchdog_timestamp);
+        else
+                log_debug_unit(u->id, "Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static UnitActiveState service_active_state(Unit *u) {
+        const UnitActiveState *table;
+
+        assert(u);
+
+        table = SERVICE(u)->type == SERVICE_IDLE ? state_translation_table_idle : state_translation_table;
+
+        return table[SERVICE(u)->state];
+}
+
+static const char *service_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return service_state_to_string(SERVICE(u)->state);
+}
+
+static bool service_check_gc(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        /* Never clean up services that still have a process around,
+         * even if the service is formally dead. */
+        if (cgroup_good(s) > 0 ||
+            main_pid_good(s) > 0 ||
+            control_pid_good(s) > 0)
+                return true;
+
+#ifdef HAVE_SYSV_COMPAT
+        if (s->is_sysv)
+                return true;
+#endif
+
+        return false;
+}
+
+static bool service_check_snapshot(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        return !s->got_socket_fd;
+}
+
+static int service_retry_pid_file(Service *s) {
+        int r;
+
+        assert(s->pid_file);
+        assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
+
+        r = service_load_pid_file(s, false);
+        if (r < 0)
+                return r;
+
+        service_unwatch_pid_file(s);
+
+        service_enter_running(s, SERVICE_SUCCESS);
+        return 0;
+}
+
+static int service_watch_pid_file(Service *s) {
+        int r;
+
+        log_debug_unit(UNIT(s)->id,
+                       "Setting watch for %s's PID file %s",
+                       UNIT(s)->id, s->pid_file_pathspec->path);
+        r = path_spec_watch(s->pid_file_pathspec, UNIT(s));
+        if (r < 0)
+                goto fail;
+
+        /* the pidfile might have appeared just before we set the watch */
+        service_retry_pid_file(s);
+
+        return 0;
+fail:
+        log_error_unit(UNIT(s)->id,
+                       "Failed to set a watch for %s's PID file %s: %s",
+                       UNIT(s)->id, s->pid_file_pathspec->path, strerror(-r));
+        service_unwatch_pid_file(s);
+        return r;
+}
+
+static int service_demand_pid_file(Service *s) {
+        PathSpec *ps;
+
+        assert(s->pid_file);
+        assert(!s->pid_file_pathspec);
+
+        ps = new0(PathSpec, 1);
+        if (!ps)
+                return -ENOMEM;
+
+        ps->path = strdup(s->pid_file);
+        if (!ps->path) {
+                free(ps);
+                return -ENOMEM;
+        }
+
+        path_kill_slashes(ps->path);
+
+        /* PATH_CHANGED would not be enough. There are daemons (sendmail) that
+         * keep their PID file open all the time. */
+        ps->type = PATH_MODIFIED;
+        ps->inotify_fd = -1;
+
+        s->pid_file_pathspec = ps;
+
+        return service_watch_pid_file(s);
+}
+
+static void service_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+        assert(fd >= 0);
+        assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
+        assert(s->pid_file_pathspec);
+        assert(path_spec_owns_inotify_fd(s->pid_file_pathspec, fd));
+
+        log_debug_unit(u->id, "inotify event for %s", u->id);
+
+        if (path_spec_fd_event(s->pid_file_pathspec, events) < 0)
+                goto fail;
+
+        if (service_retry_pid_file(s) == 0)
+                return;
+
+        if (service_watch_pid_file(s) < 0)
+                goto fail;
+
+        return;
+fail:
+        service_unwatch_pid_file(s);
+        service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
+}
+
+static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+        Service *s = SERVICE(u);
+        ServiceResult f;
+
+        assert(s);
+        assert(pid >= 0);
+
+        if (UNIT(s)->fragment_path ? is_clean_exit(code, status, &s->success_status) :
+                                     is_clean_exit_lsb(code, status, &s->success_status))
+                f = SERVICE_SUCCESS;
+        else if (code == CLD_EXITED)
+                f = SERVICE_FAILURE_EXIT_CODE;
+        else if (code == CLD_KILLED)
+                f = SERVICE_FAILURE_SIGNAL;
+        else if (code == CLD_DUMPED)
+                f = SERVICE_FAILURE_CORE_DUMP;
+        else
+                assert_not_reached("Unknown code");
+
+        if (s->main_pid == pid) {
+                /* Forking services may occasionally move to a new PID.
+                 * As long as they update the PID file before exiting the old
+                 * PID, they're fine. */
+                if (service_load_pid_file(s, false) == 0)
+                        return;
+
+                s->main_pid = 0;
+                exec_status_exit(&s->main_exec_status, &s->exec_context, pid, code, status);
+
+                /* If this is not a forking service than the main
+                 * process got started and hence we copy the exit
+                 * status so that it is recorded both as main and as
+                 * control process exit status */
+                if (s->main_command) {
+                        s->main_command->exec_status = s->main_exec_status;
+
+                        if (s->main_command->ignore)
+                                f = SERVICE_SUCCESS;
+                }
+
+                log_struct(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+                           "MESSAGE=%s: main process exited, code=%s, status=%i/%s",
+                                  u->id, sigchld_code_to_string(code), status,
+                                  strna(code == CLD_EXITED
+                                        ? exit_status_to_string(status, EXIT_STATUS_FULL)
+                                        : signal_to_string(status)),
+                           "UNIT=%s", u->id,
+                           "EXIT_CODE=%s", sigchld_code_to_string(code),
+                           "EXIT_STATUS=%i", status,
+                           NULL);
+
+                if (f != SERVICE_SUCCESS)
+                        s->result = f;
+
+                if (s->main_command &&
+                    s->main_command->command_next &&
+                    f == SERVICE_SUCCESS) {
+
+                        /* There is another command to *
+                         * execute, so let's do that. */
+
+                        log_debug_unit(u->id,
+                                       "%s running next main command for state %s",
+                                       u->id, service_state_to_string(s->state));
+                        service_run_next_main(s);
+
+                } else {
+
+                        /* The service exited, so the service is officially
+                         * gone. */
+                        s->main_command = NULL;
+
+                        switch (s->state) {
+
+                        case SERVICE_START_POST:
+                        case SERVICE_RELOAD:
+                        case SERVICE_STOP:
+                                /* Need to wait until the operation is
+                                 * done */
+                                break;
+
+                        case SERVICE_START:
+                                if (s->type == SERVICE_ONESHOT) {
+                                        /* This was our main goal, so let's go on */
+                                        if (f == SERVICE_SUCCESS)
+                                                service_enter_start_post(s);
+                                        else
+                                                service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+                                        break;
+                                }
+
+                                /* Fall through */
+
+                        case SERVICE_RUNNING:
+                                service_enter_running(s, f);
+                                break;
+
+                        case SERVICE_STOP_SIGTERM:
+                        case SERVICE_STOP_SIGKILL:
+
+                                if (!control_pid_good(s))
+                                        service_enter_stop_post(s, f);
+
+                                /* If there is still a control process, wait for that first */
+                                break;
+
+                        default:
+                                assert_not_reached("Uh, main process died at wrong time.");
+                        }
+                }
+
+        } else if (s->control_pid == pid) {
+
+                s->control_pid = 0;
+
+                if (s->control_command) {
+                        exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
+
+                        if (s->control_command->ignore)
+                                f = SERVICE_SUCCESS;
+                }
+
+                log_full_unit(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id,
+                              "%s: control process exited, code=%s status=%i",
+                              u->id, sigchld_code_to_string(code), status);
+
+                if (f != SERVICE_SUCCESS)
+                        s->result = f;
+
+                /* Immediately get rid of the cgroup, so that the
+                 * kernel doesn't delay the cgroup empty messages for
+                 * the service cgroup any longer than necessary */
+                cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control");
+
+                if (s->control_command &&
+                    s->control_command->command_next &&
+                    f == SERVICE_SUCCESS) {
+
+                        /* There is another command to *
+                         * execute, so let's do that. */
+
+                        log_debug_unit(u->id,
+                                       "%s running next control command for state %s",
+                                       u->id, service_state_to_string(s->state));
+                        service_run_next_control(s);
+
+                } else {
+                        /* No further commands for this step, so let's
+                         * figure out what to do next */
+
+                        s->control_command = NULL;
+                        s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
+
+                        log_debug_unit(u->id,
+                                       "%s got final SIGCHLD for state %s",
+                                       u->id, service_state_to_string(s->state));
+
+                        switch (s->state) {
+
+                        case SERVICE_START_PRE:
+                                if (f == SERVICE_SUCCESS)
+                                        service_enter_start(s);
+                                else
+                                        service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+                                break;
+
+                        case SERVICE_START:
+                                if (s->type != SERVICE_FORKING)
+                                        /* Maybe spurious event due to a reload that changed the type? */
+                                        break;
+
+                                if (f != SERVICE_SUCCESS) {
+                                        service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+                                        break;
+                                }
+
+                                if (s->pid_file) {
+                                        bool has_start_post;
+                                        int r;
+
+                                        /* Let's try to load the pid file here if we can.
+                                         * The PID file might actually be created by a START_POST
+                                         * script. In that case don't worry if the loading fails. */
+
+                                        has_start_post = !!s->exec_command[SERVICE_EXEC_START_POST];
+                                        r = service_load_pid_file(s, !has_start_post);
+                                        if (!has_start_post && r < 0) {
+                                                r = service_demand_pid_file(s);
+                                                if (r < 0 || !cgroup_good(s))
+                                                        service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+                                                break;
+                                        }
+                                } else
+                                        service_search_main_pid(s);
+
+                                service_enter_start_post(s);
+                                break;
+
+                        case SERVICE_START_POST:
+                                if (f != SERVICE_SUCCESS) {
+                                        service_enter_stop(s, f);
+                                        break;
+                                }
+
+                                if (s->pid_file) {
+                                        int r;
+
+                                        r = service_load_pid_file(s, true);
+                                        if (r < 0) {
+                                                r = service_demand_pid_file(s);
+                                                if (r < 0 || !cgroup_good(s))
+                                                        service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+                                                break;
+                                        }
+                                } else
+                                        service_search_main_pid(s);
+
+                                service_enter_running(s, SERVICE_SUCCESS);
+                                break;
+
+                        case SERVICE_RELOAD:
+                                if (f == SERVICE_SUCCESS) {
+                                        service_load_pid_file(s, true);
+                                        service_search_main_pid(s);
+                                }
+
+                                s->reload_result = f;
+                                service_enter_running(s, SERVICE_SUCCESS);
+                                break;
+
+                        case SERVICE_STOP:
+                                service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
+                                break;
+
+                        case SERVICE_STOP_SIGTERM:
+                        case SERVICE_STOP_SIGKILL:
+                                if (main_pid_good(s) <= 0)
+                                        service_enter_stop_post(s, f);
+
+                                /* If there is still a service
+                                 * process around, wait until
+                                 * that one quit, too */
+                                break;
+
+                        case SERVICE_STOP_POST:
+                        case SERVICE_FINAL_SIGTERM:
+                        case SERVICE_FINAL_SIGKILL:
+                                service_enter_dead(s, f, true);
+                                break;
+
+                        default:
+                                assert_not_reached("Uh, control process died at wrong time.");
+                        }
+                }
+        }
+
+        /* Notify clients about changed exit status */
+        unit_add_to_dbus_queue(u);
+}
+
+static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+        assert(elapsed == 1);
+
+        if (w == &s->watchdog_watch) {
+                service_handle_watchdog(s);
+                return;
+        }
+
+        assert(w == &s->timer_watch);
+
+        switch (s->state) {
+
+        case SERVICE_START_PRE:
+        case SERVICE_START:
+                log_warning_unit(u->id,
+                                 "%s operation timed out. Terminating.", u->id);
+                service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT);
+                break;
+
+        case SERVICE_START_POST:
+                log_warning_unit(u->id,
+                                 "%s operation timed out. Stopping.", u->id);
+                service_enter_stop(s, SERVICE_FAILURE_TIMEOUT);
+                break;
+
+        case SERVICE_RELOAD:
+                log_warning_unit(u->id,
+                                 "%s operation timed out. Stopping.", u->id);
+                s->reload_result = SERVICE_FAILURE_TIMEOUT;
+                service_enter_running(s, SERVICE_SUCCESS);
+                break;
+
+        case SERVICE_STOP:
+                log_warning_unit(u->id,
+                                 "%s stopping timed out. Terminating.", u->id);
+                service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
+                break;
+
+        case SERVICE_STOP_SIGTERM:
+                if (s->kill_context.send_sigkill) {
+                        log_warning_unit(u->id,
+                                         "%s stopping timed out. Killing.", u->id);
+                        service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id,
+                                         "%s stopping timed out. Skipping SIGKILL.", u->id);
+                        service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT);
+                }
+
+                break;
+
+        case SERVICE_STOP_SIGKILL:
+                /* Uh, we sent a SIGKILL and it is still not gone?
+                 * Must be something we cannot kill, so let's just be
+                 * weirded out and continue */
+
+                log_warning_unit(u->id,
+                                 "%s still around after SIGKILL. Ignoring.", u->id);
+                service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT);
+                break;
+
+        case SERVICE_STOP_POST:
+                log_warning_unit(u->id,
+                                 "%s stopping timed out (2). Terminating.", u->id);
+                service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT);
+                break;
+
+        case SERVICE_FINAL_SIGTERM:
+                if (s->kill_context.send_sigkill) {
+                        log_warning_unit(u->id,
+                                         "%s stopping timed out (2). Killing.", u->id);
+                        service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id,
+                                         "%s stopping timed out (2). Skipping SIGKILL. Entering failed mode.",
+                                         u->id);
+                        service_enter_dead(s, SERVICE_FAILURE_TIMEOUT, false);
+                }
+
+                break;
+
+        case SERVICE_FINAL_SIGKILL:
+                log_warning_unit(u->id,
+                                 "%s still around after SIGKILL (2). Entering failed mode.", u->id);
+                service_enter_dead(s, SERVICE_FAILURE_TIMEOUT, true);
+                break;
+
+        case SERVICE_AUTO_RESTART:
+                log_info_unit(u->id,
+                              "%s holdoff time over, scheduling restart.", u->id);
+                service_enter_restart(s);
+                break;
+
+        default:
+                assert_not_reached("Timeout at wrong time.");
+        }
+}
+
+static void service_cgroup_notify_event(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(u);
+
+        log_debug_unit(u->id,
+                       "%s: cgroup is empty", u->id);
+
+        switch (s->state) {
+
+                /* Waiting for SIGCHLD is usually more interesting,
+                 * because it includes return codes/signals. Which is
+                 * why we ignore the cgroup events for most cases,
+                 * except when we don't know pid which to expect the
+                 * SIGCHLD for. */
+
+        case SERVICE_START:
+        case SERVICE_START_POST:
+                /* If we were hoping for the daemon to write its PID file,
+                 * we can give up now. */
+                if (s->pid_file_pathspec) {
+                        log_warning_unit(u->id,
+                                         "%s never wrote its PID file. Failing.", UNIT(s)->id);
+                        service_unwatch_pid_file(s);
+                        if (s->state == SERVICE_START)
+                                service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+                        else
+                                service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+                }
+                break;
+
+        case SERVICE_RUNNING:
+                /* service_enter_running() will figure out what to do */
+                service_enter_running(s, SERVICE_SUCCESS);
+                break;
+
+        case SERVICE_STOP_SIGTERM:
+        case SERVICE_STOP_SIGKILL:
+
+                if (main_pid_good(s) <= 0 && !control_pid_good(s))
+                        service_enter_stop_post(s, SERVICE_SUCCESS);
+
+                break;
+
+        case SERVICE_FINAL_SIGTERM:
+        case SERVICE_FINAL_SIGKILL:
+                if (main_pid_good(s) <= 0 && !control_pid_good(s))
+                        service_enter_dead(s, SERVICE_SUCCESS, true);
+
+                break;
+
+        default:
+                ;
+        }
+}
+
+static void service_notify_message(Unit *u, pid_t pid, char **tags) {
+        Service *s = SERVICE(u);
+        const char *e;
+
+        assert(u);
+
+        if (s->notify_access == NOTIFY_NONE) {
+                log_warning_unit(u->id,
+                                 "%s: Got notification message from PID %lu, but reception is disabled.",
+                                 u->id, (unsigned long) pid);
+                return;
+        }
+
+        if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) {
+                log_warning_unit(u->id,
+                                 "%s: Got notification message from PID %lu, but reception only permitted for PID %lu",
+                                 u->id, (unsigned long) pid, (unsigned long) s->main_pid);
+                return;
+        }
+
+        log_debug_unit(u->id,
+                       "%s: Got message", u->id);
+
+        /* Interpret MAINPID= */
+        if ((e = strv_find_prefix(tags, "MAINPID=")) &&
+            (s->state == SERVICE_START ||
+             s->state == SERVICE_START_POST ||
+             s->state == SERVICE_RUNNING ||
+             s->state == SERVICE_RELOAD)) {
+
+                if (parse_pid(e + 8, &pid) < 0)
+                        log_warning_unit(u->id,
+                                         "Failed to parse notification message %s", e);
+                else {
+                        log_debug_unit(u->id,
+                                       "%s: got %s", u->id, e);
+                        service_set_main_pid(s, pid);
+                }
+        }
+
+        /* Interpret READY= */
+        if (s->type == SERVICE_NOTIFY &&
+            s->state == SERVICE_START &&
+            strv_find(tags, "READY=1")) {
+                log_debug_unit(u->id,
+                               "%s: got READY=1", u->id);
+
+                service_enter_start_post(s);
+        }
+
+        /* Interpret STATUS= */
+        e = strv_find_prefix(tags, "STATUS=");
+        if (e) {
+                char *t;
+
+                if (e[7]) {
+
+                        if (!utf8_is_valid(e+7)) {
+                                log_warning_unit(u->id,
+                                                 "Status message in notification is not UTF-8 clean.");
+                                return;
+                        }
+
+                        t = strdup(e+7);
+                        if (!t) {
+                                log_error_unit(u->id,
+                                               "Failed to allocate string.");
+                                return;
+                        }
+
+                        log_debug_unit(u->id,
+                                       "%s: got %s", u->id, e);
+
+                        free(s->status_text);
+                        s->status_text = t;
+                } else {
+                        free(s->status_text);
+                        s->status_text = NULL;
+                }
+
+        }
+        if (strv_find(tags, "WATCHDOG=1")) {
+                log_debug_unit(u->id,
+                               "%s: got WATCHDOG=1", u->id);
+                service_reset_watchdog(s);
+        }
+
+        /* Notify clients about changed status or main pid */
+        unit_add_to_dbus_queue(u);
+}
+
+#ifdef HAVE_SYSV_COMPAT
+
+static int service_enumerate(Manager *m) {
+        char **p;
+        unsigned i;
+        DIR *d = NULL;
+        char *path = NULL, *fpath = NULL, *name = NULL;
+        Set *runlevel_services[ELEMENTSOF(rcnd_table)], *shutdown_services = NULL;
+        Unit *service;
+        Iterator j;
+        int r;
+
+        assert(m);
+
+        if (m->running_as != SYSTEMD_SYSTEM)
+                return 0;
+
+        zero(runlevel_services);
+
+        STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path)
+                for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
+                        struct dirent *de;
+
+                        free(path);
+                        path = strjoin(*p, "/", rcnd_table[i].path, NULL);
+                        if (!path) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        if (d)
+                                closedir(d);
+
+                        if (!(d = opendir(path))) {
+                                if (errno != ENOENT)
+                                        log_warning("opendir() failed on %s: %s", path, strerror(errno));
+
+                                continue;
+                        }
+
+                        while ((de = readdir(d))) {
+                                int a, b;
+
+                                if (ignore_file(de->d_name))
+                                        continue;
+
+                                if (de->d_name[0] != 'S' && de->d_name[0] != 'K')
+                                        continue;
+
+                                if (strlen(de->d_name) < 4)
+                                        continue;
+
+                                a = undecchar(de->d_name[1]);
+                                b = undecchar(de->d_name[2]);
+
+                                if (a < 0 || b < 0)
+                                        continue;
+
+                                free(fpath);
+                                fpath = strjoin(path, "/", de->d_name, NULL);
+                                if (!fpath) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                if (access(fpath, X_OK) < 0) {
+
+                                        if (errno != ENOENT)
+                                                log_warning("access() failed on %s: %s", fpath, strerror(errno));
+
+                                        continue;
+                                }
+
+                                free(name);
+                                if (!(name = sysv_translate_name(de->d_name + 3))) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                r = manager_load_unit_prepare(m, name, NULL, NULL, &service);
+                                if (r < 0) {
+                                        log_warning("Failed to prepare unit %s: %s", name, strerror(-r));
+                                        continue;
+                                }
+
+                                if (de->d_name[0] == 'S')  {
+
+                                        if (rcnd_table[i].type == RUNLEVEL_UP) {
+                                                SERVICE(service)->sysv_start_priority_from_rcnd =
+                                                        MAX(a*10 + b, SERVICE(service)->sysv_start_priority_from_rcnd);
+
+                                                SERVICE(service)->sysv_enabled = true;
+                                        }
+
+                                        if ((r = set_ensure_allocated(&runlevel_services[i], trivial_hash_func, trivial_compare_func)) < 0)
+                                                goto finish;
+
+                                        if ((r = set_put(runlevel_services[i], service)) < 0)
+                                                goto finish;
+
+                                } else if (de->d_name[0] == 'K' &&
+                                           (rcnd_table[i].type == RUNLEVEL_DOWN)) {
+
+                                        if ((r = set_ensure_allocated(&shutdown_services, trivial_hash_func, trivial_compare_func)) < 0)
+                                                goto finish;
+
+                                        if ((r = set_put(shutdown_services, service)) < 0)
+                                                goto finish;
+                                }
+                        }
+                }
+
+        /* Now we loaded all stubs and are aware of the lowest
+        start-up priority for all services, not let's actually load
+        the services, this will also tell us which services are
+        actually native now */
+        manager_dispatch_load_queue(m);
+
+        /* If this is a native service, rely on native ways to pull in
+         * a service, don't pull it in via sysv rcN.d links. */
+        for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
+                SET_FOREACH(service, runlevel_services[i], j) {
+                        service = unit_follow_merge(service);
+
+                        if (service->fragment_path)
+                                continue;
+
+                        if ((r = unit_add_two_dependencies_by_name_inverse(service, UNIT_AFTER, UNIT_WANTS, rcnd_table[i].target, NULL, true)) < 0)
+                                goto finish;
+                }
+
+        /* We honour K links only for halt/reboot. For the normal
+         * runlevels we assume the stop jobs will be implicitly added
+         * by the core logic. Also, we don't really distinguish here
+         * between the runlevels 0 and 6 and just add them to the
+         * special shutdown target. */
+        SET_FOREACH(service, shutdown_services, j) {
+                service = unit_follow_merge(service);
+
+                if (service->fragment_path)
+                        continue;
+
+                if ((r = unit_add_two_dependencies_by_name(service, UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true)) < 0)
+                        goto finish;
+        }
+
+        r = 0;
+
+finish:
+        free(path);
+        free(fpath);
+        free(name);
+
+        for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
+                set_free(runlevel_services[i]);
+        set_free(shutdown_services);
+
+        if (d)
+                closedir(d);
+
+        return r;
+}
+#endif
+
+static void service_bus_name_owner_change(
+                Unit *u,
+                const char *name,
+                const char *old_owner,
+                const char *new_owner) {
+
+        Service *s = SERVICE(u);
+
+        assert(s);
+        assert(name);
+
+        assert(streq(s->bus_name, name));
+        assert(old_owner || new_owner);
+
+        if (old_owner && new_owner)
+                log_debug_unit(u->id,
+                               "%s's D-Bus name %s changed owner from %s to %s",
+                               u->id, name, old_owner, new_owner);
+        else if (old_owner)
+                log_debug_unit(u->id,
+                               "%s's D-Bus name %s no longer registered by %s",
+                               u->id, name, old_owner);
+        else
+                log_debug_unit(u->id,
+                               "%s's D-Bus name %s now registered by %s",
+                               u->id, name, new_owner);
+
+        s->bus_name_good = !!new_owner;
+
+        if (s->type == SERVICE_DBUS) {
+
+                /* service_enter_running() will figure out what to
+                 * do */
+                if (s->state == SERVICE_RUNNING)
+                        service_enter_running(s, SERVICE_SUCCESS);
+                else if (s->state == SERVICE_START && new_owner)
+                        service_enter_start_post(s);
+
+        } else if (new_owner &&
+                   s->main_pid <= 0 &&
+                   (s->state == SERVICE_START ||
+                    s->state == SERVICE_START_POST ||
+                    s->state == SERVICE_RUNNING ||
+                    s->state == SERVICE_RELOAD)) {
+
+                /* Try to acquire PID from bus service */
+                log_debug_unit(u->id,
+                               "Trying to acquire PID from D-Bus name...");
+
+                bus_query_pid(u->manager, name);
+        }
+}
+
+static void service_bus_query_pid_done(
+                Unit *u,
+                const char *name,
+                pid_t pid) {
+
+        Service *s = SERVICE(u);
+
+        assert(s);
+        assert(name);
+
+        log_debug_unit(u->id,
+                       "%s's D-Bus name %s is now owned by process %u",
+                       u->id, name, (unsigned) pid);
+
+        if (s->main_pid <= 0 &&
+            (s->state == SERVICE_START ||
+             s->state == SERVICE_START_POST ||
+             s->state == SERVICE_RUNNING ||
+             s->state == SERVICE_RELOAD))
+                service_set_main_pid(s, pid);
+}
+
+int service_set_socket_fd(Service *s, int fd, Socket *sock) {
+
+        assert(s);
+        assert(fd >= 0);
+
+        /* This is called by the socket code when instantiating a new
+         * service for a stream socket and the socket needs to be
+         * configured. */
+
+        if (UNIT(s)->load_state != UNIT_LOADED)
+                return -EINVAL;
+
+        if (s->socket_fd >= 0)
+                return -EBUSY;
+
+        if (s->state != SERVICE_DEAD)
+                return -EAGAIN;
+
+        s->socket_fd = fd;
+        s->got_socket_fd = true;
+
+        unit_ref_set(&s->accept_socket, UNIT(sock));
+
+        return unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false);
+}
+
+static void service_reset_failed(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        if (s->state == SERVICE_FAILED)
+                service_set_state(s, SERVICE_DEAD);
+
+        s->result = SERVICE_SUCCESS;
+        s->reload_result = SERVICE_SUCCESS;
+
+        RATELIMIT_RESET(s->start_limit);
+}
+
+static int service_kill(Unit *u, KillWho who, int signo, DBusError *error) {
+        Service *s = SERVICE(u);
+        int r = 0;
+        Set *pid_set = NULL;
+
+        assert(s);
+
+        if (s->main_pid <= 0 && who == KILL_MAIN) {
+                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
+                return -ESRCH;
+        }
+
+        if (s->control_pid <= 0 && who == KILL_CONTROL) {
+                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
+                return -ESRCH;
+        }
+
+        if (who == KILL_CONTROL || who == KILL_ALL)
+                if (s->control_pid > 0)
+                        if (kill(s->control_pid, signo) < 0)
+                                r = -errno;
+
+        if (who == KILL_MAIN || who == KILL_ALL)
+                if (s->main_pid > 0)
+                        if (kill(s->main_pid, signo) < 0)
+                                r = -errno;
+
+        if (who == KILL_ALL) {
+                int q;
+
+                pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!pid_set)
+                        return -ENOMEM;
+
+                /* Exclude the control/main pid from being killed via the cgroup */
+                if (s->control_pid > 0) {
+                        q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
+                        if (q < 0) {
+                                r = q;
+                                goto finish;
+                        }
+                }
+
+                if (s->main_pid > 0) {
+                        q = set_put(pid_set, LONG_TO_PTR(s->main_pid));
+                        if (q < 0) {
+                                r = q;
+                                goto finish;
+                        }
+                }
+
+                q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
+                if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
+                        r = q;
+        }
+
+finish:
+        if (pid_set)
+                set_free(pid_set);
+
+        return r;
+}
+
+static const char* const service_state_table[_SERVICE_STATE_MAX] = {
+        [SERVICE_DEAD] = "dead",
+        [SERVICE_START_PRE] = "start-pre",
+        [SERVICE_START] = "start",
+        [SERVICE_START_POST] = "start-post",
+        [SERVICE_RUNNING] = "running",
+        [SERVICE_EXITED] = "exited",
+        [SERVICE_RELOAD] = "reload",
+        [SERVICE_STOP] = "stop",
+        [SERVICE_STOP_SIGTERM] = "stop-sigterm",
+        [SERVICE_STOP_SIGKILL] = "stop-sigkill",
+        [SERVICE_STOP_POST] = "stop-post",
+        [SERVICE_FINAL_SIGTERM] = "final-sigterm",
+        [SERVICE_FINAL_SIGKILL] = "final-sigkill",
+        [SERVICE_FAILED] = "failed",
+        [SERVICE_AUTO_RESTART] = "auto-restart",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
+
+static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
+        [SERVICE_RESTART_NO] = "no",
+        [SERVICE_RESTART_ON_SUCCESS] = "on-success",
+        [SERVICE_RESTART_ON_FAILURE] = "on-failure",
+        [SERVICE_RESTART_ON_ABORT] = "on-abort",
+        [SERVICE_RESTART_ALWAYS] = "always"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);
+
+static const char* const service_type_table[_SERVICE_TYPE_MAX] = {
+        [SERVICE_SIMPLE] = "simple",
+        [SERVICE_FORKING] = "forking",
+        [SERVICE_ONESHOT] = "oneshot",
+        [SERVICE_DBUS] = "dbus",
+        [SERVICE_NOTIFY] = "notify",
+        [SERVICE_IDLE] = "idle"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(service_type, ServiceType);
+
+static const char* const service_exec_command_table[_SERVICE_EXEC_COMMAND_MAX] = {
+        [SERVICE_EXEC_START_PRE] = "ExecStartPre",
+        [SERVICE_EXEC_START] = "ExecStart",
+        [SERVICE_EXEC_START_POST] = "ExecStartPost",
+        [SERVICE_EXEC_RELOAD] = "ExecReload",
+        [SERVICE_EXEC_STOP] = "ExecStop",
+        [SERVICE_EXEC_STOP_POST] = "ExecStopPost",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand);
+
+static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
+        [NOTIFY_NONE] = "none",
+        [NOTIFY_MAIN] = "main",
+        [NOTIFY_ALL] = "all"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
+
+static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
+        [SERVICE_SUCCESS] = "success",
+        [SERVICE_FAILURE_RESOURCES] = "resources",
+        [SERVICE_FAILURE_TIMEOUT] = "timeout",
+        [SERVICE_FAILURE_EXIT_CODE] = "exit-code",
+        [SERVICE_FAILURE_SIGNAL] = "signal",
+        [SERVICE_FAILURE_CORE_DUMP] = "core-dump",
+        [SERVICE_FAILURE_WATCHDOG] = "watchdog",
+        [SERVICE_FAILURE_START_LIMIT] = "start-limit"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult);
+
+static const char* const start_limit_action_table[_SERVICE_START_LIMIT_MAX] = {
+        [SERVICE_START_LIMIT_NONE] = "none",
+        [SERVICE_START_LIMIT_REBOOT] = "reboot",
+        [SERVICE_START_LIMIT_REBOOT_FORCE] = "reboot-force",
+        [SERVICE_START_LIMIT_REBOOT_IMMEDIATE] = "reboot-immediate"
+};
+DEFINE_STRING_TABLE_LOOKUP(start_limit_action, StartLimitAction);
+
+const UnitVTable service_vtable = {
+        .object_size = sizeof(Service),
+        .exec_context_offset = offsetof(Service, exec_context),
+
+        .sections =
+                "Unit\0"
+                "Service\0"
+                "Install\0",
+
+        .init = service_init,
+        .done = service_done,
+        .load = service_load,
+
+        .coldplug = service_coldplug,
+
+        .dump = service_dump,
+
+        .start = service_start,
+        .stop = service_stop,
+        .reload = service_reload,
+
+        .can_reload = service_can_reload,
+
+        .kill = service_kill,
+
+        .serialize = service_serialize,
+        .deserialize_item = service_deserialize_item,
+
+        .active_state = service_active_state,
+        .sub_state_to_string = service_sub_state_to_string,
+
+        .check_gc = service_check_gc,
+        .check_snapshot = service_check_snapshot,
+
+        .sigchld_event = service_sigchld_event,
+        .timer_event = service_timer_event,
+        .fd_event = service_fd_event,
+
+        .reset_failed = service_reset_failed,
+
+        .cgroup_notify_empty = service_cgroup_notify_event,
+        .notify_message = service_notify_message,
+
+        .bus_name_owner_change = service_bus_name_owner_change,
+        .bus_query_pid_done = service_bus_query_pid_done,
+
+        .bus_interface = "org.freedesktop.systemd1.Service",
+        .bus_message_handler = bus_service_message_handler,
+        .bus_invalidating_properties =  bus_service_invalidating_properties,
+
+#ifdef HAVE_SYSV_COMPAT
+        .enumerate = service_enumerate,
+#endif
+        .status_message_formats = {
+                .starting_stopping = {
+                        [0] = "Starting %s...",
+                        [1] = "Stopping %s...",
+                },
+                .finished_start_job = {
+                        [JOB_DONE]       = "Started %s.",
+                        [JOB_FAILED]     = "Failed to start %s.",
+                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                        [JOB_TIMEOUT]    = "Timed out starting %s.",
+                },
+                .finished_stop_job = {
+                        [JOB_DONE]       = "Stopped %s.",
+                        [JOB_FAILED]     = "Stopped (with error) %s.",
+                        [JOB_TIMEOUT]    = "Timed out stopping %s.",
+                },
+        },
+};
diff --git a/src/core/service.h b/src/core/service.h
new file mode 100644 (file)
index 0000000..d1e53bf
--- /dev/null
@@ -0,0 +1,225 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Service Service;
+
+#include "unit.h"
+#include "path.h"
+#include "ratelimit.h"
+#include "service.h"
+#include "kill.h"
+#include "exit-status.h"
+
+typedef enum ServiceState {
+        SERVICE_DEAD,
+        SERVICE_START_PRE,
+        SERVICE_START,
+        SERVICE_START_POST,
+        SERVICE_RUNNING,
+        SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */
+        SERVICE_RELOAD,
+        SERVICE_STOP,              /* No STOP_PRE state, instead just register multiple STOP executables */
+        SERVICE_STOP_SIGTERM,
+        SERVICE_STOP_SIGKILL,
+        SERVICE_STOP_POST,
+        SERVICE_FINAL_SIGTERM,     /* In case the STOP_POST executable hangs, we shoot that down, too */
+        SERVICE_FINAL_SIGKILL,
+        SERVICE_FAILED,
+        SERVICE_AUTO_RESTART,
+        _SERVICE_STATE_MAX,
+        _SERVICE_STATE_INVALID = -1
+} ServiceState;
+
+typedef enum ServiceRestart {
+        SERVICE_RESTART_NO,
+        SERVICE_RESTART_ON_SUCCESS,
+        SERVICE_RESTART_ON_FAILURE,
+        SERVICE_RESTART_ON_ABORT,
+        SERVICE_RESTART_ALWAYS,
+        _SERVICE_RESTART_MAX,
+        _SERVICE_RESTART_INVALID = -1
+} ServiceRestart;
+
+typedef enum ServiceType {
+        SERVICE_SIMPLE,   /* we fork and go on right-away (i.e. modern socket activated daemons) */
+        SERVICE_FORKING,  /* forks by itself (i.e. traditional daemons) */
+        SERVICE_ONESHOT,  /* we fork and wait until the program finishes (i.e. programs like fsck which run and need to finish before we continue) */
+        SERVICE_DBUS,     /* we fork and wait until a specific D-Bus name appears on the bus */
+        SERVICE_NOTIFY,   /* we fork and wait until a daemon sends us a ready message with sd_notify() */
+        SERVICE_IDLE,     /* much like simple, but delay exec() until all jobs are dispatched. */
+        _SERVICE_TYPE_MAX,
+        _SERVICE_TYPE_INVALID = -1
+} ServiceType;
+
+typedef enum ServiceExecCommand {
+        SERVICE_EXEC_START_PRE,
+        SERVICE_EXEC_START,
+        SERVICE_EXEC_START_POST,
+        SERVICE_EXEC_RELOAD,
+        SERVICE_EXEC_STOP,
+        SERVICE_EXEC_STOP_POST,
+        _SERVICE_EXEC_COMMAND_MAX,
+        _SERVICE_EXEC_COMMAND_INVALID = -1
+} ServiceExecCommand;
+
+typedef enum NotifyAccess {
+        NOTIFY_NONE,
+        NOTIFY_ALL,
+        NOTIFY_MAIN,
+        _NOTIFY_ACCESS_MAX,
+        _NOTIFY_ACCESS_INVALID = -1
+} NotifyAccess;
+
+typedef enum ServiceResult {
+        SERVICE_SUCCESS,
+        SERVICE_FAILURE_RESOURCES,
+        SERVICE_FAILURE_TIMEOUT,
+        SERVICE_FAILURE_EXIT_CODE,
+        SERVICE_FAILURE_SIGNAL,
+        SERVICE_FAILURE_CORE_DUMP,
+        SERVICE_FAILURE_WATCHDOG,
+        SERVICE_FAILURE_START_LIMIT,
+        _SERVICE_RESULT_MAX,
+        _SERVICE_RESULT_INVALID = -1
+} ServiceResult;
+
+typedef enum StartLimitAction {
+        SERVICE_START_LIMIT_NONE,
+        SERVICE_START_LIMIT_REBOOT,
+        SERVICE_START_LIMIT_REBOOT_FORCE,
+        SERVICE_START_LIMIT_REBOOT_IMMEDIATE,
+        _SERVICE_START_LIMIT_MAX,
+        _SERVICE_START_LIMIT_INVALID = -1
+} StartLimitAction;
+
+struct Service {
+        Unit meta;
+
+        ServiceType type;
+        ServiceRestart restart;
+        ExitStatusSet restart_ignore_status;
+        ExitStatusSet success_status;
+
+        /* If set we'll read the main daemon PID from this file */
+        char *pid_file;
+
+        usec_t restart_usec;
+        usec_t timeout_start_usec;
+        usec_t timeout_stop_usec;
+
+        dual_timestamp watchdog_timestamp;
+        usec_t watchdog_usec;
+        Watch watchdog_watch;
+
+        ExecCommand* exec_command[_SERVICE_EXEC_COMMAND_MAX];
+
+        ExecContext exec_context;
+        KillContext kill_context;
+
+        ServiceState state, deserialized_state;
+
+        /* The exit status of the real main process */
+        ExecStatus main_exec_status;
+
+        /* The currently executed control process */
+        ExecCommand *control_command;
+
+        /* The currently executed main process, which may be NULL if
+         * the main process got started via forking mode and not by
+         * us */
+        ExecCommand *main_command;
+
+        /* The ID of the control command currently being executed */
+        ServiceExecCommand control_command_id;
+
+        pid_t main_pid, control_pid;
+        int socket_fd;
+
+        int fsck_passno;
+
+        bool permissions_start_only;
+        bool root_directory_start_only;
+        bool remain_after_exit;
+        bool guess_main_pid;
+
+        /* If we shut down, remember why */
+        ServiceResult result;
+        ServiceResult reload_result;
+
+        bool main_pid_known:1;
+        bool main_pid_alien:1;
+        bool bus_name_good:1;
+        bool forbid_restart:1;
+        bool got_socket_fd:1;
+        bool start_timeout_defined:1;
+#ifdef HAVE_SYSV_COMPAT
+        bool is_sysv:1;
+        bool sysv_has_lsb:1;
+        bool sysv_enabled:1;
+        int sysv_start_priority_from_rcnd;
+        int sysv_start_priority;
+
+        char *sysv_runlevels;
+#endif
+
+        char *bus_name;
+
+        char *status_text;
+
+        RateLimit start_limit;
+        StartLimitAction start_limit_action;
+
+        UnitRef accept_socket;
+
+        Watch timer_watch;
+        PathSpec *pid_file_pathspec;
+
+        NotifyAccess notify_access;
+};
+
+extern const UnitVTable service_vtable;
+
+struct Socket;
+
+int service_set_socket_fd(Service *s, int fd, struct Socket *socket);
+
+const char* service_state_to_string(ServiceState i);
+ServiceState service_state_from_string(const char *s);
+
+const char* service_restart_to_string(ServiceRestart i);
+ServiceRestart service_restart_from_string(const char *s);
+
+const char* service_type_to_string(ServiceType i);
+ServiceType service_type_from_string(const char *s);
+
+const char* service_exec_command_to_string(ServiceExecCommand i);
+ServiceExecCommand service_exec_command_from_string(const char *s);
+
+const char* notify_access_to_string(NotifyAccess i);
+NotifyAccess notify_access_from_string(const char *s);
+
+const char* service_result_to_string(ServiceResult i);
+ServiceResult service_result_from_string(const char *s);
+
+const char* start_limit_action_to_string(StartLimitAction i);
+StartLimitAction start_limit_action_from_string(const char *s);
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
new file mode 100644 (file)
index 0000000..0b0e0c3
--- /dev/null
@@ -0,0 +1,327 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 ProFUSION embedded systems
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/reboot.h>
+#include <linux/reboot.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "missing.h"
+#include "log.h"
+#include "umount.h"
+#include "util.h"
+#include "mkdir.h"
+#include "virt.h"
+#include "watchdog.h"
+#include "killall.h"
+
+#define FINALIZE_ATTEMPTS 50
+
+static int prepare_new_root(void) {
+        static const char dirs[] =
+                "/run/initramfs/oldroot\0"
+                "/run/initramfs/proc\0"
+                "/run/initramfs/sys\0"
+                "/run/initramfs/dev\0"
+                "/run/initramfs/run\0";
+
+        const char *dir;
+
+        if (mount("/run/initramfs", "/run/initramfs", NULL, MS_BIND, NULL) < 0) {
+                log_error("Failed to mount bind /run/initramfs on /run/initramfs: %m");
+                return -errno;
+        }
+
+        if (mount(NULL, "/run/initramfs", NULL, MS_PRIVATE, NULL) < 0) {
+                log_error("Failed to make /run/initramfs private mount: %m");
+                return -errno;
+        }
+
+        NULSTR_FOREACH(dir, dirs)
+                if (mkdir_p_label(dir, 0755) < 0 && errno != EEXIST) {
+                        log_error("Failed to mkdir %s: %m", dir);
+                        return -errno;
+                }
+
+        if (mount("/sys", "/run/initramfs/sys", NULL, MS_BIND, NULL) < 0) {
+                log_error("Failed to mount bind /sys on /run/initramfs/sys: %m");
+                return -errno;
+        }
+
+        if (mount("/proc", "/run/initramfs/proc", NULL, MS_BIND, NULL) < 0) {
+                log_error("Failed to mount bind /proc on /run/initramfs/proc: %m");
+                return -errno;
+        }
+
+        if (mount("/dev", "/run/initramfs/dev", NULL, MS_BIND, NULL) < 0) {
+                log_error("Failed to mount bind /dev on /run/initramfs/dev: %m");
+                return -errno;
+        }
+
+        if (mount("/run", "/run/initramfs/run", NULL, MS_BIND, NULL) < 0) {
+                log_error("Failed to mount bind /run on /run/initramfs/run: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+static int pivot_to_new_root(void) {
+
+        if (chdir("/run/initramfs") < 0) {
+                log_error("Failed to change directory to /run/initramfs: %m");
+                return -errno;
+        }
+
+        /* Work-around for a kernel bug: for some reason the kernel
+         * refuses switching root if any file systems are mounted
+         * MS_SHARED. Hence remount them MS_PRIVATE here as a
+         * work-around.
+         *
+         * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
+        if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
+                log_warning("Failed to make \"/\" private mount: %m");
+
+        if (pivot_root(".", "oldroot") < 0) {
+                log_error("pivot failed: %m");
+                /* only chroot if pivot root succeeded */
+                return -errno;
+        }
+
+        chroot(".");
+
+        setsid();
+        make_console_stdio();
+
+        log_info("Successfully changed into root pivot.");
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        int cmd, r;
+        unsigned retries;
+        bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true;
+        bool in_container, use_watchdog = false;
+        char *arguments[3];
+
+        log_parse_environment();
+        log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */
+        log_open();
+
+        umask(0022);
+
+        if (getpid() != 1) {
+                log_error("Not executed by init (pid 1).");
+                r = -EPERM;
+                goto error;
+        }
+
+        if (argc != 2) {
+                log_error("Invalid number of arguments.");
+                r = -EINVAL;
+                goto error;
+        }
+
+        in_container = detect_container(NULL) > 0;
+
+        if (streq(argv[1], "reboot"))
+                cmd = RB_AUTOBOOT;
+        else if (streq(argv[1], "poweroff"))
+                cmd = RB_POWER_OFF;
+        else if (streq(argv[1], "halt"))
+                cmd = RB_HALT_SYSTEM;
+        else if (streq(argv[1], "kexec"))
+                cmd = LINUX_REBOOT_CMD_KEXEC;
+        else {
+                log_error("Unknown action '%s'.", argv[1]);
+                r = -EINVAL;
+                goto error;
+        }
+
+        use_watchdog = !!getenv("WATCHDOG_USEC");
+
+        /* lock us into memory */
+        mlockall(MCL_CURRENT|MCL_FUTURE);
+
+        log_info("Sending SIGTERM to remaining processes...");
+        broadcast_signal(SIGTERM, true);
+
+        log_info("Sending SIGKILL to remaining processes...");
+        broadcast_signal(SIGKILL, true);
+
+        if (in_container) {
+                need_swapoff = false;
+                need_dm_detach = false;
+                need_loop_detach = false;
+        }
+
+        /* Unmount all mountpoints, swaps, and loopback devices */
+        for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) {
+                bool changed = false;
+
+                if (use_watchdog)
+                        watchdog_ping();
+
+                if (need_umount) {
+                        log_info("Unmounting file systems.");
+                        r = umount_all(&changed);
+                        if (r == 0) {
+                                need_umount = false;
+                                log_info("All filesystems unmounted.");
+                        } else if (r > 0)
+                                log_info("Not all file systems unmounted, %d left.", r);
+                        else
+                                log_error("Failed to unmount file systems: %s", strerror(-r));
+                }
+
+                if (need_swapoff) {
+                        log_info("Deactivating swaps.");
+                        r = swapoff_all(&changed);
+                        if (r == 0) {
+                                need_swapoff = false;
+                                log_info("All swaps deactivated.");
+                        } else if (r > 0)
+                                log_info("Not all swaps deactivated, %d left.", r);
+                        else
+                                log_error("Failed to deactivate swaps: %s", strerror(-r));
+                }
+
+                if (need_loop_detach) {
+                        log_info("Detaching loop devices.");
+                        r = loopback_detach_all(&changed);
+                        if (r == 0) {
+                                need_loop_detach = false;
+                                log_info("All loop devices detached.");
+                        } else if (r > 0)
+                                log_info("Not all loop devices detached, %d left.", r);
+                        else
+                                log_error("Failed to detach loop devices: %s", strerror(-r));
+                }
+
+                if (need_dm_detach) {
+                        log_info("Detaching DM devices.");
+                        r = dm_detach_all(&changed);
+                        if (r == 0) {
+                                need_dm_detach = false;
+                                log_info("All DM devices detached.");
+                        } else if (r > 0)
+                                log_info("Not all DM devices detached, %d left.", r);
+                        else
+                                log_error("Failed to detach DM devices: %s", strerror(-r));
+                }
+
+                if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) {
+                        if (retries > 0)
+                                log_info("All filesystems, swaps, loop devices, DM devices detached.");
+                        /* Yay, done */
+                        break;
+                }
+
+                /* If in this iteration we didn't manage to
+                 * unmount/deactivate anything, we simply give up */
+                if (!changed) {
+                        log_error("Cannot finalize remaining file systems and devices, giving up.");
+                        break;
+                }
+
+                log_debug("Couldn't finalize remaining file systems and devices after %u retries, trying again.", retries+1);
+        }
+
+        if (retries >= FINALIZE_ATTEMPTS)
+                log_error("Too many iterations, giving up.");
+
+        arguments[0] = NULL;
+        arguments[1] = argv[1];
+        arguments[2] = NULL;
+        execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, arguments);
+
+        if (!in_container && !in_initrd() &&
+            access("/run/initramfs/shutdown", X_OK) == 0) {
+
+                if (prepare_new_root() >= 0 &&
+                    pivot_to_new_root() >= 0) {
+                        execv("/shutdown", argv);
+                        log_error("Failed to execute shutdown binary: %m");
+                }
+        }
+
+        /* The kernel will automaticall flush ATA disks and suchlike
+         * on reboot(), but the file systems need to be synce'd
+         * explicitly in advance. So let's do this here, but not
+         * needlessly slow down containers. */
+        if (!in_container)
+                sync();
+
+        if (cmd == LINUX_REBOOT_CMD_KEXEC) {
+
+                if (!in_container) {
+                        /* We cheat and exec kexec to avoid doing all its work */
+                        pid_t pid = fork();
+
+                        if (pid < 0)
+                                log_error("Could not fork: %m. Falling back to normal reboot.");
+                        else if (pid > 0) {
+                                wait_for_terminate_and_warn("kexec", pid);
+                                log_warning("kexec failed. Falling back to normal reboot.");
+                        } else {
+                                /* Child */
+                                const char *args[3] = { "/sbin/kexec", "-e", NULL };
+                                execv(args[0], (char * const *) args);
+                                return EXIT_FAILURE;
+                        }
+                }
+
+                cmd = RB_AUTOBOOT;
+        }
+
+        reboot(cmd);
+
+        if (errno == EPERM && in_container) {
+                /* If we are in a container, and we lacked
+                 * CAP_SYS_BOOT just exit, this will kill our
+                 * container for good. */
+                log_error("Exiting container.");
+                exit(0);
+        }
+
+        log_error("Failed to invoke reboot(): %m");
+        r = -errno;
+
+  error:
+        log_error("Critical error while doing system shutdown: %s", strerror(-r));
+
+        freeze();
+        return EXIT_FAILURE;
+}
diff --git a/src/core/snapshot.c b/src/core/snapshot.c
new file mode 100644 (file)
index 0000000..5c2a319
--- /dev/null
@@ -0,0 +1,308 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "unit.h"
+#include "snapshot.h"
+#include "unit-name.h"
+#include "dbus-snapshot.h"
+#include "bus-errors.h"
+
+static const UnitActiveState state_translation_table[_SNAPSHOT_STATE_MAX] = {
+        [SNAPSHOT_DEAD] = UNIT_INACTIVE,
+        [SNAPSHOT_ACTIVE] = UNIT_ACTIVE
+};
+
+static void snapshot_init(Unit *u) {
+        Snapshot *s = SNAPSHOT(u);
+
+        assert(s);
+        assert(UNIT(s)->load_state == UNIT_STUB);
+
+        UNIT(s)->ignore_on_isolate = true;
+        UNIT(s)->ignore_on_snapshot = true;
+}
+
+static void snapshot_set_state(Snapshot *s, SnapshotState state) {
+        SnapshotState old_state;
+        assert(s);
+
+        old_state = s->state;
+        s->state = state;
+
+        if (state != old_state)
+                log_debug("%s changed %s -> %s",
+                          UNIT(s)->id,
+                          snapshot_state_to_string(old_state),
+                          snapshot_state_to_string(state));
+
+        unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
+}
+
+static int snapshot_load(Unit *u) {
+        Snapshot *s = SNAPSHOT(u);
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        /* Make sure that only snapshots created via snapshot_create()
+         * can be loaded */
+        if (!s->by_snapshot_create && UNIT(s)->manager->n_reloading <= 0)
+                return -ENOENT;
+
+        u->load_state = UNIT_LOADED;
+        return 0;
+}
+
+static int snapshot_coldplug(Unit *u) {
+        Snapshot *s = SNAPSHOT(u);
+
+        assert(s);
+        assert(s->state == SNAPSHOT_DEAD);
+
+        if (s->deserialized_state != s->state)
+                snapshot_set_state(s, s->deserialized_state);
+
+        return 0;
+}
+
+static void snapshot_dump(Unit *u, FILE *f, const char *prefix) {
+        Snapshot *s = SNAPSHOT(u);
+
+        assert(s);
+        assert(f);
+
+        fprintf(f,
+                "%sSnapshot State: %s\n"
+                "%sClean Up: %s\n",
+                prefix, snapshot_state_to_string(s->state),
+                prefix, yes_no(s->cleanup));
+}
+
+static int snapshot_start(Unit *u) {
+        Snapshot *s = SNAPSHOT(u);
+
+        assert(s);
+        assert(s->state == SNAPSHOT_DEAD);
+
+        snapshot_set_state(s, SNAPSHOT_ACTIVE);
+
+        if (s->cleanup)
+                unit_add_to_cleanup_queue(u);
+
+        return 0;
+}
+
+static int snapshot_stop(Unit *u) {
+        Snapshot *s = SNAPSHOT(u);
+
+        assert(s);
+        assert(s->state == SNAPSHOT_ACTIVE);
+
+        snapshot_set_state(s, SNAPSHOT_DEAD);
+        return 0;
+}
+
+static int snapshot_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Snapshot *s = SNAPSHOT(u);
+        Unit *other;
+        Iterator i;
+
+        assert(s);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", snapshot_state_to_string(s->state));
+        unit_serialize_item(u, f, "cleanup", yes_no(s->cleanup));
+        SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
+                unit_serialize_item(u, f, "wants", other->id);
+
+        return 0;
+}
+
+static int snapshot_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Snapshot *s = SNAPSHOT(u);
+        int r;
+
+        assert(u);
+        assert(key);
+        assert(value);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                SnapshotState state;
+
+                if ((state = snapshot_state_from_string(value)) < 0)
+                        log_debug("Failed to parse state value %s", value);
+                else
+                        s->deserialized_state = state;
+
+        } else if (streq(key, "cleanup")) {
+
+                if ((r = parse_boolean(value)) < 0)
+                        log_debug("Failed to parse cleanup value %s", value);
+                else
+                        s->cleanup = r;
+
+        } else if (streq(key, "wants")) {
+
+                if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, value, NULL, true)) < 0)
+                        return r;
+        } else
+                log_debug("Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static UnitActiveState snapshot_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[SNAPSHOT(u)->state];
+}
+
+static const char *snapshot_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return snapshot_state_to_string(SNAPSHOT(u)->state);
+}
+
+int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Snapshot **_s) {
+        Iterator i;
+        Unit *other, *u = NULL;
+        char *n = NULL;
+        int r;
+        const char *k;
+
+        assert(m);
+        assert(_s);
+
+        if (name) {
+                if (!unit_name_is_valid(name, false)) {
+                        dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name);
+                        return -EINVAL;
+                }
+
+                if (unit_name_to_type(name) != UNIT_SNAPSHOT) {
+                        dbus_set_error(e, BUS_ERROR_UNIT_TYPE_MISMATCH, "Unit name %s lacks snapshot suffix.", name);
+                        return -EINVAL;
+                }
+
+                if (manager_get_unit(m, name)) {
+                        dbus_set_error(e, BUS_ERROR_UNIT_EXISTS, "Snapshot %s exists already.", name);
+                        return -EEXIST;
+                }
+
+        } else {
+
+                for (;;) {
+                        if (asprintf(&n, "snapshot-%u.snapshot", ++ m->n_snapshots) < 0)
+                                return -ENOMEM;
+
+                        if (!manager_get_unit(m, n))
+                                break;
+
+                        free(n);
+                }
+
+                name = n;
+        }
+
+        r = manager_load_unit_prepare(m, name, NULL, e, &u);
+        free(n);
+
+        if (r < 0)
+                goto fail;
+
+        SNAPSHOT(u)->by_snapshot_create = true;
+        manager_dispatch_load_queue(m);
+        assert(u->load_state == UNIT_LOADED);
+
+        HASHMAP_FOREACH_KEY(other, k, m->units, i) {
+
+                if (other->ignore_on_snapshot)
+                        continue;
+
+                if (k != other->id)
+                        continue;
+
+                if (UNIT_VTABLE(other)->check_snapshot)
+                        if (!UNIT_VTABLE(other)->check_snapshot(other))
+                            continue;
+
+                if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        continue;
+
+                if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, other, true)) < 0)
+                        goto fail;
+        }
+
+        SNAPSHOT(u)->cleanup = cleanup;
+        *_s = SNAPSHOT(u);
+
+        return 0;
+
+fail:
+        if (u)
+                unit_add_to_cleanup_queue(u);
+
+        return r;
+}
+
+void snapshot_remove(Snapshot *s) {
+        assert(s);
+
+        unit_add_to_cleanup_queue(UNIT(s));
+}
+
+static const char* const snapshot_state_table[_SNAPSHOT_STATE_MAX] = {
+        [SNAPSHOT_DEAD] = "dead",
+        [SNAPSHOT_ACTIVE] = "active"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(snapshot_state, SnapshotState);
+
+const UnitVTable snapshot_vtable = {
+        .object_size = sizeof(Snapshot),
+
+        .no_alias = true,
+        .no_instances = true,
+        .no_gc = true,
+
+        .init = snapshot_init,
+
+        .load = snapshot_load,
+        .coldplug = snapshot_coldplug,
+
+        .dump = snapshot_dump,
+
+        .start = snapshot_start,
+        .stop = snapshot_stop,
+
+        .serialize = snapshot_serialize,
+        .deserialize_item = snapshot_deserialize_item,
+
+        .active_state = snapshot_active_state,
+        .sub_state_to_string = snapshot_sub_state_to_string,
+
+        .bus_interface = "org.freedesktop.systemd1.Snapshot",
+        .bus_message_handler = bus_snapshot_message_handler
+};
diff --git a/src/core/snapshot.h b/src/core/snapshot.h
new file mode 100644 (file)
index 0000000..9662d93
--- /dev/null
@@ -0,0 +1,50 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Snapshot Snapshot;
+
+#include "unit.h"
+
+typedef enum SnapshotState {
+        SNAPSHOT_DEAD,
+        SNAPSHOT_ACTIVE,
+        _SNAPSHOT_STATE_MAX,
+        _SNAPSHOT_STATE_INVALID = -1
+} SnapshotState;
+
+struct Snapshot {
+        Unit meta;
+
+        SnapshotState state, deserialized_state;
+
+        bool cleanup;
+        bool by_snapshot_create:1;
+};
+
+extern const UnitVTable snapshot_vtable;
+
+int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Snapshot **s);
+void snapshot_remove(Snapshot *s);
+
+const char* snapshot_state_to_string(SnapshotState i);
+SnapshotState snapshot_state_from_string(const char *s);
diff --git a/src/core/socket.c b/src/core/socket.c
new file mode 100644 (file)
index 0000000..fcbcdbe
--- /dev/null
@@ -0,0 +1,2440 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <signal.h>
+#include <arpa/inet.h>
+#include <mqueue.h>
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
+#include "unit.h"
+#include "socket.h"
+#include "netinet/tcp.h"
+#include "log.h"
+#include "load-dropin.h"
+#include "load-fragment.h"
+#include "strv.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "unit-name.h"
+#include "unit-printf.h"
+#include "dbus-socket.h"
+#include "missing.h"
+#include "special.h"
+#include "bus-errors.h"
+#include "label.h"
+#include "exit-status.h"
+#include "def.h"
+
+static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
+        [SOCKET_DEAD] = UNIT_INACTIVE,
+        [SOCKET_START_PRE] = UNIT_ACTIVATING,
+        [SOCKET_START_POST] = UNIT_ACTIVATING,
+        [SOCKET_LISTENING] = UNIT_ACTIVE,
+        [SOCKET_RUNNING] = UNIT_ACTIVE,
+        [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
+        [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
+        [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
+        [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
+        [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
+        [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
+        [SOCKET_FAILED] = UNIT_FAILED
+};
+
+static void socket_init(Unit *u) {
+        Socket *s = SOCKET(u);
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        s->backlog = SOMAXCONN;
+        s->timeout_usec = DEFAULT_TIMEOUT_USEC;
+        s->directory_mode = 0755;
+        s->socket_mode = 0666;
+
+        s->max_connections = 64;
+
+        s->priority = -1;
+        s->ip_tos = -1;
+        s->ip_ttl = -1;
+        s->mark = -1;
+
+        exec_context_init(&s->exec_context);
+        s->exec_context.std_output = u->manager->default_std_output;
+        s->exec_context.std_error = u->manager->default_std_error;
+        kill_context_init(&s->kill_context);
+
+        s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
+}
+
+static void socket_unwatch_control_pid(Socket *s) {
+        assert(s);
+
+        if (s->control_pid <= 0)
+                return;
+
+        unit_unwatch_pid(UNIT(s), s->control_pid);
+        s->control_pid = 0;
+}
+
+static void socket_done(Unit *u) {
+        Socket *s = SOCKET(u);
+        SocketPort *p;
+
+        assert(s);
+
+        while ((p = s->ports)) {
+                LIST_REMOVE(SocketPort, port, s->ports, p);
+
+                if (p->fd >= 0) {
+                        unit_unwatch_fd(UNIT(s), &p->fd_watch);
+                        close_nointr_nofail(p->fd);
+                }
+
+                free(p->path);
+                free(p);
+        }
+
+        exec_context_done(&s->exec_context);
+        exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
+        s->control_command = NULL;
+
+        socket_unwatch_control_pid(s);
+
+        unit_ref_unset(&s->service);
+
+        free(s->tcp_congestion);
+        s->tcp_congestion = NULL;
+
+        free(s->bind_to_device);
+        s->bind_to_device = NULL;
+
+        free(s->smack);
+        free(s->smack_ip_in);
+        free(s->smack_ip_out);
+
+        unit_unwatch_timer(u, &s->timer_watch);
+}
+
+static int socket_instantiate_service(Socket *s) {
+        char *prefix, *name;
+        int r;
+        Unit *u;
+
+        assert(s);
+
+        /* This fills in s->service if it isn't filled in yet. For
+         * Accept=yes sockets we create the next connection service
+         * here. For Accept=no this is mostly a NOP since the service
+         * is figured out at load time anyway. */
+
+        if (UNIT_DEREF(s->service))
+                return 0;
+
+        assert(s->accept);
+
+        if (!(prefix = unit_name_to_prefix(UNIT(s)->id)))
+                return -ENOMEM;
+
+        r = asprintf(&name, "%s@%u.service", prefix, s->n_accepted);
+        free(prefix);
+
+        if (r < 0)
+                return -ENOMEM;
+
+        r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u);
+        free(name);
+
+        if (r < 0)
+                return r;
+
+#ifdef HAVE_SYSV_COMPAT
+        if (SERVICE(u)->is_sysv) {
+                log_error("Using SysV services for socket activation is not supported. Refusing.");
+                return -ENOENT;
+        }
+#endif
+
+        u->no_gc = true;
+        unit_ref_set(&s->service, u);
+
+        return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
+}
+
+static bool have_non_accept_socket(Socket *s) {
+        SocketPort *p;
+
+        assert(s);
+
+        if (!s->accept)
+                return true;
+
+        LIST_FOREACH(port, p, s->ports) {
+
+                if (p->type != SOCKET_SOCKET)
+                        return true;
+
+                if (!socket_address_can_accept(&p->address))
+                        return true;
+        }
+
+        return false;
+}
+
+static int socket_verify(Socket *s) {
+        assert(s);
+
+        if (UNIT(s)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (!s->ports) {
+                log_error_unit(UNIT(s)->id,
+                               "%s lacks Listen setting. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->accept && have_non_accept_socket(s)) {
+                log_error_unit(UNIT(s)->id,
+                               "%s configured for accepting sockets, but sockets are non-accepting. Refusing.",
+                               UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->accept && s->max_connections <= 0) {
+                log_error_unit(UNIT(s)->id,
+                               "%s's MaxConnection setting too small. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->accept && UNIT_DEREF(s->service)) {
+                log_error_unit(UNIT(s)->id,
+                               "Explicit service configuration for accepting sockets not supported on %s. Refusing.",
+                               UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
+                log_error_unit(UNIT(s)->id,
+                               "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.",
+                               UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static bool socket_needs_mount(Socket *s, const char *prefix) {
+        SocketPort *p;
+
+        assert(s);
+
+        LIST_FOREACH(port, p, s->ports) {
+
+                if (p->type == SOCKET_SOCKET) {
+                        if (socket_address_needs_mount(&p->address, prefix))
+                                return true;
+                } else if (p->type == SOCKET_FIFO || p->type == SOCKET_SPECIAL) {
+                        if (path_startswith(p->path, prefix))
+                                return true;
+                }
+        }
+
+        return false;
+}
+
+int socket_add_one_mount_link(Socket *s, Mount *m) {
+        int r;
+
+        assert(s);
+        assert(m);
+
+        if (UNIT(s)->load_state != UNIT_LOADED ||
+            UNIT(m)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (!socket_needs_mount(s, m->where))
+                return 0;
+
+        r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int socket_add_mount_links(Socket *s) {
+        Unit *other;
+        int r;
+
+        assert(s);
+
+        LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) {
+                r = socket_add_one_mount_link(s, MOUNT(other));
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int socket_add_device_link(Socket *s) {
+        char *t;
+        int r;
+
+        assert(s);
+
+        if (!s->bind_to_device)
+                return 0;
+
+        if (asprintf(&t, "/sys/subsystem/net/devices/%s", s->bind_to_device) < 0)
+                return -ENOMEM;
+
+        r = unit_add_node_link(UNIT(s), t, false);
+        free(t);
+
+        return r;
+}
+
+static int socket_add_default_dependencies(Socket *s) {
+        int r;
+        assert(s);
+
+        if (UNIT(s)->manager->running_as == SYSTEMD_SYSTEM) {
+                if ((r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true)) < 0)
+                        return r;
+
+                if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0)
+                        return r;
+        }
+
+        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+}
+
+static bool socket_has_exec(Socket *s) {
+        unsigned i;
+        assert(s);
+
+        for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
+                if (s->exec_command[i])
+                        return true;
+
+        return false;
+}
+
+static int socket_load(Unit *u) {
+        Socket *s = SOCKET(u);
+        int r;
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        if ((r = unit_load_fragment_and_dropin(u)) < 0)
+                return r;
+
+        /* This is a new unit? Then let's add in some extras */
+        if (u->load_state == UNIT_LOADED) {
+
+                if (have_non_accept_socket(s)) {
+
+                        if (!UNIT_DEREF(s->service)) {
+                                Unit *x;
+
+                                r = unit_load_related_unit(u, ".service", &x);
+                                if (r < 0)
+                                        return r;
+
+                                unit_ref_set(&s->service, x);
+                        }
+
+                        r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true);
+                        if (r < 0)
+                                return r;
+                }
+
+                if ((r = socket_add_mount_links(s)) < 0)
+                        return r;
+
+                if ((r = socket_add_device_link(s)) < 0)
+                        return r;
+
+                if (socket_has_exec(s))
+                        if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
+                                return r;
+
+                if ((r = unit_add_default_cgroups(u)) < 0)
+                        return r;
+
+                if (UNIT(s)->default_dependencies)
+                        if ((r = socket_add_default_dependencies(s)) < 0)
+                                return r;
+
+                r = unit_exec_context_defaults(u, &s->exec_context);
+                if (r < 0)
+                        return r;
+        }
+
+        return socket_verify(s);
+}
+
+static const char* listen_lookup(int family, int type) {
+
+        if (family == AF_NETLINK)
+                return "ListenNetlink";
+
+        if (type == SOCK_STREAM)
+                return "ListenStream";
+        else if (type == SOCK_DGRAM)
+                return "ListenDatagram";
+        else if (type == SOCK_SEQPACKET)
+                return "ListenSequentialPacket";
+
+        assert_not_reached("Unknown socket type");
+        return NULL;
+}
+
+static void socket_dump(Unit *u, FILE *f, const char *prefix) {
+
+        SocketExecCommand c;
+        Socket *s = SOCKET(u);
+        SocketPort *p;
+        const char *prefix2;
+        char *p2;
+
+        assert(s);
+        assert(f);
+
+        p2 = strappend(prefix, "\t");
+        prefix2 = p2 ? p2 : prefix;
+
+        fprintf(f,
+                "%sSocket State: %s\n"
+                "%sResult: %s\n"
+                "%sBindIPv6Only: %s\n"
+                "%sBacklog: %u\n"
+                "%sSocketMode: %04o\n"
+                "%sDirectoryMode: %04o\n"
+                "%sKeepAlive: %s\n"
+                "%sFreeBind: %s\n"
+                "%sTransparent: %s\n"
+                "%sBroadcast: %s\n"
+                "%sPassCredentials: %s\n"
+                "%sPassSecurity: %s\n"
+                "%sTCPCongestion: %s\n",
+                prefix, socket_state_to_string(s->state),
+                prefix, socket_result_to_string(s->result),
+                prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
+                prefix, s->backlog,
+                prefix, s->socket_mode,
+                prefix, s->directory_mode,
+                prefix, yes_no(s->keep_alive),
+                prefix, yes_no(s->free_bind),
+                prefix, yes_no(s->transparent),
+                prefix, yes_no(s->broadcast),
+                prefix, yes_no(s->pass_cred),
+                prefix, yes_no(s->pass_sec),
+                prefix, strna(s->tcp_congestion));
+
+        if (s->control_pid > 0)
+                fprintf(f,
+                        "%sControl PID: %lu\n",
+                        prefix, (unsigned long) s->control_pid);
+
+        if (s->bind_to_device)
+                fprintf(f,
+                        "%sBindToDevice: %s\n",
+                        prefix, s->bind_to_device);
+
+        if (s->accept)
+                fprintf(f,
+                        "%sAccepted: %u\n"
+                        "%sNConnections: %u\n"
+                        "%sMaxConnections: %u\n",
+                        prefix, s->n_accepted,
+                        prefix, s->n_connections,
+                        prefix, s->max_connections);
+
+        if (s->priority >= 0)
+                fprintf(f,
+                        "%sPriority: %i\n",
+                        prefix, s->priority);
+
+        if (s->receive_buffer > 0)
+                fprintf(f,
+                        "%sReceiveBuffer: %zu\n",
+                        prefix, s->receive_buffer);
+
+        if (s->send_buffer > 0)
+                fprintf(f,
+                        "%sSendBuffer: %zu\n",
+                        prefix, s->send_buffer);
+
+        if (s->ip_tos >= 0)
+                fprintf(f,
+                        "%sIPTOS: %i\n",
+                        prefix, s->ip_tos);
+
+        if (s->ip_ttl >= 0)
+                fprintf(f,
+                        "%sIPTTL: %i\n",
+                        prefix, s->ip_ttl);
+
+        if (s->pipe_size > 0)
+                fprintf(f,
+                        "%sPipeSize: %zu\n",
+                        prefix, s->pipe_size);
+
+        if (s->mark >= 0)
+                fprintf(f,
+                        "%sMark: %i\n",
+                        prefix, s->mark);
+
+        if (s->mq_maxmsg > 0)
+                fprintf(f,
+                        "%sMessageQueueMaxMessages: %li\n",
+                        prefix, s->mq_maxmsg);
+
+        if (s->mq_msgsize > 0)
+                fprintf(f,
+                        "%sMessageQueueMessageSize: %li\n",
+                        prefix, s->mq_msgsize);
+
+        if (s->smack)
+                fprintf(f,
+                        "%sSmackLabel: %s\n",
+                        prefix, s->smack);
+
+        if (s->smack_ip_in)
+                fprintf(f,
+                        "%sSmackLabelIPIn: %s\n",
+                        prefix, s->smack_ip_in);
+
+        if (s->smack_ip_out)
+                fprintf(f,
+                        "%sSmackLabelIPOut: %s\n",
+                        prefix, s->smack_ip_out);
+
+        LIST_FOREACH(port, p, s->ports) {
+
+                if (p->type == SOCKET_SOCKET) {
+                        const char *t;
+                        int r;
+                        char *k = NULL;
+
+                        if ((r = socket_address_print(&p->address, &k)) < 0)
+                                t = strerror(-r);
+                        else
+                                t = k;
+
+                        fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t);
+                        free(k);
+                } else if (p->type == SOCKET_SPECIAL)
+                        fprintf(f, "%sListenSpecial: %s\n", prefix, p->path);
+                else if (p->type == SOCKET_MQUEUE)
+                        fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path);
+                else
+                        fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
+        }
+
+        exec_context_dump(&s->exec_context, f, prefix);
+        kill_context_dump(&s->kill_context, f, prefix);
+
+        for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
+                if (!s->exec_command[c])
+                        continue;
+
+                fprintf(f, "%s-> %s:\n",
+                        prefix, socket_exec_command_to_string(c));
+
+                exec_command_dump_list(s->exec_command[c], f, prefix2);
+        }
+
+        free(p2);
+}
+
+static int instance_from_socket(int fd, unsigned nr, char **instance) {
+        socklen_t l;
+        char *r;
+        union {
+                struct sockaddr sa;
+                struct sockaddr_un un;
+                struct sockaddr_in in;
+                struct sockaddr_in6 in6;
+                struct sockaddr_storage storage;
+        } local, remote;
+
+        assert(fd >= 0);
+        assert(instance);
+
+        l = sizeof(local);
+        if (getsockname(fd, &local.sa, &l) < 0)
+                return -errno;
+
+        l = sizeof(remote);
+        if (getpeername(fd, &remote.sa, &l) < 0)
+                return -errno;
+
+        switch (local.sa.sa_family) {
+
+        case AF_INET: {
+                uint32_t
+                        a = ntohl(local.in.sin_addr.s_addr),
+                        b = ntohl(remote.in.sin_addr.s_addr);
+
+                if (asprintf(&r,
+                             "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
+                             nr,
+                             a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
+                             ntohs(local.in.sin_port),
+                             b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
+                             ntohs(remote.in.sin_port)) < 0)
+                        return -ENOMEM;
+
+                break;
+        }
+
+        case AF_INET6: {
+                static const unsigned char ipv4_prefix[] = {
+                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
+                };
+
+                if (memcmp(&local.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0 &&
+                    memcmp(&remote.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
+                        const uint8_t
+                                *a = local.in6.sin6_addr.s6_addr+12,
+                                *b = remote.in6.sin6_addr.s6_addr+12;
+
+                        if (asprintf(&r,
+                                     "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
+                                     nr,
+                                     a[0], a[1], a[2], a[3],
+                                     ntohs(local.in6.sin6_port),
+                                     b[0], b[1], b[2], b[3],
+                                     ntohs(remote.in6.sin6_port)) < 0)
+                                return -ENOMEM;
+                } else {
+                        char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
+
+                        if (asprintf(&r,
+                                     "%u-%s:%u-%s:%u",
+                                     nr,
+                                     inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
+                                     ntohs(local.in6.sin6_port),
+                                     inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
+                                     ntohs(remote.in6.sin6_port)) < 0)
+                                return -ENOMEM;
+                }
+
+                break;
+        }
+
+        case AF_UNIX: {
+                struct ucred ucred;
+
+                l = sizeof(ucred);
+                if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
+                        return -errno;
+
+                if (asprintf(&r,
+                             "%u-%lu-%lu",
+                             nr,
+                             (unsigned long) ucred.pid,
+                             (unsigned long) ucred.uid) < 0)
+                        return -ENOMEM;
+
+                break;
+        }
+
+        default:
+                assert_not_reached("Unhandled socket type.");
+        }
+
+        *instance = r;
+        return 0;
+}
+
+static void socket_close_fds(Socket *s) {
+        SocketPort *p;
+
+        assert(s);
+
+        LIST_FOREACH(port, p, s->ports) {
+                if (p->fd < 0)
+                        continue;
+
+                unit_unwatch_fd(UNIT(s), &p->fd_watch);
+                close_nointr_nofail(p->fd);
+
+                /* One little note: we should never delete any sockets
+                 * in the file system here! After all some other
+                 * process we spawned might still have a reference of
+                 * this fd and wants to continue to use it. Therefore
+                 * we delete sockets in the file system before we
+                 * create a new one, not after we stopped using
+                 * one! */
+
+                p->fd = -1;
+        }
+}
+
+static void socket_apply_socket_options(Socket *s, int fd) {
+        assert(s);
+        assert(fd >= 0);
+
+        if (s->keep_alive) {
+                int b = s->keep_alive;
+                if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)) < 0)
+                        log_warning_unit(UNIT(s)->id, "SO_KEEPALIVE failed: %m");
+        }
+
+        if (s->broadcast) {
+                int one = 1;
+                if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
+                        log_warning_unit(UNIT(s)->id, "SO_BROADCAST failed: %m");
+        }
+
+        if (s->pass_cred) {
+                int one = 1;
+                if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
+                        log_warning_unit(UNIT(s)->id, "SO_PASSCRED failed: %m");
+        }
+
+        if (s->pass_sec) {
+                int one = 1;
+                if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)) < 0)
+                        log_warning_unit(UNIT(s)->id, "SO_PASSSEC failed: %m");
+        }
+
+        if (s->priority >= 0)
+                if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0)
+                        log_warning_unit(UNIT(s)->id, "SO_PRIORITY failed: %m");
+
+        if (s->receive_buffer > 0) {
+                int value = (int) s->receive_buffer;
+
+                /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */
+
+                if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
+                        if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
+                                log_warning_unit(UNIT(s)->id, "SO_RCVBUF failed: %m");
+        }
+
+        if (s->send_buffer > 0) {
+                int value = (int) s->send_buffer;
+                if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
+                        if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
+                                log_warning_unit(UNIT(s)->id, "SO_SNDBUF failed: %m");
+        }
+
+        if (s->mark >= 0)
+                if (setsockopt(fd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)) < 0)
+                        log_warning_unit(UNIT(s)->id, "SO_MARK failed: %m");
+
+        if (s->ip_tos >= 0)
+                if (setsockopt(fd, IPPROTO_IP, IP_TOS, &s->ip_tos, sizeof(s->ip_tos)) < 0)
+                        log_warning_unit(UNIT(s)->id, "IP_TOS failed: %m");
+
+        if (s->ip_ttl >= 0) {
+                int r, x;
+
+                r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl));
+
+                if (socket_ipv6_is_supported())
+                        x = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s->ip_ttl, sizeof(s->ip_ttl));
+                else {
+                        x = -1;
+                        errno = EAFNOSUPPORT;
+                }
+
+                if (r < 0 && x < 0)
+                        log_warning_unit(UNIT(s)->id,
+                                         "IP_TTL/IPV6_UNICAST_HOPS failed: %m");
+        }
+
+        if (s->tcp_congestion)
+                if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
+                        log_warning_unit(UNIT(s)->id, "TCP_CONGESTION failed: %m");
+
+#ifdef HAVE_ATTR_XATTR_H
+        if (s->smack_ip_in)
+                if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0)
+                        log_error_unit(UNIT(s)->id,
+                                       "fsetxattr(\"security.SMACK64IPIN\"): %m");
+
+        if (s->smack_ip_out)
+                if (fsetxattr(fd, "security.SMACK64IPOUT", s->smack_ip_out, strlen(s->smack_ip_out), 0) < 0)
+                        log_error_unit(UNIT(s)->id,
+                                       "fsetxattr(\"security.SMACK64IPOUT\"): %m");
+#endif
+}
+
+static void socket_apply_fifo_options(Socket *s, int fd) {
+        assert(s);
+        assert(fd >= 0);
+
+        if (s->pipe_size > 0)
+                if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
+                        log_warning_unit(UNIT(s)->id,
+                                         "F_SETPIPE_SZ: %m");
+
+#ifdef HAVE_ATTR_XATTR_H
+        if (s->smack)
+                if (fsetxattr(fd, "security.SMACK64", s->smack, strlen(s->smack), 0) < 0)
+                        log_error_unit(UNIT(s)->id,
+                                       "fsetxattr(\"security.SMACK64\"): %m");
+#endif
+}
+
+static int fifo_address_create(
+                const char *path,
+                mode_t directory_mode,
+                mode_t socket_mode,
+                int *_fd) {
+
+        int fd = -1, r = 0;
+        struct stat st;
+        mode_t old_mask;
+
+        assert(path);
+        assert(_fd);
+
+        mkdir_parents_label(path, directory_mode);
+
+        r = label_context_set(path, S_IFIFO);
+        if (r < 0)
+                goto fail;
+
+        /* Enforce the right access mode for the fifo */
+        old_mask = umask(~ socket_mode);
+
+        /* Include the original umask in our mask */
+        umask(~socket_mode | old_mask);
+
+        r = mkfifo(path, socket_mode);
+        umask(old_mask);
+
+        if (r < 0 && errno != EEXIST) {
+                r = -errno;
+                goto fail;
+        }
+
+        if ((fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        label_context_clear();
+
+        if (fstat(fd, &st) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if (!S_ISFIFO(st.st_mode) ||
+            (st.st_mode & 0777) != (socket_mode & ~old_mask) ||
+            st.st_uid != getuid() ||
+            st.st_gid != getgid()) {
+
+                r = -EEXIST;
+                goto fail;
+        }
+
+        *_fd = fd;
+        return 0;
+
+fail:
+        label_context_clear();
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
+
+static int special_address_create(
+                const char *path,
+                int *_fd) {
+
+        int fd = -1, r = 0;
+        struct stat st;
+
+        assert(path);
+        assert(_fd);
+
+        if ((fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if (fstat(fd, &st) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        /* Check whether this is a /proc, /sys or /dev file or char device */
+        if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
+                r = -EEXIST;
+                goto fail;
+        }
+
+        *_fd = fd;
+        return 0;
+
+fail:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
+
+static int mq_address_create(
+                const char *path,
+                mode_t mq_mode,
+                long maxmsg,
+                long msgsize,
+                int *_fd) {
+
+        int fd = -1, r = 0;
+        struct stat st;
+        mode_t old_mask;
+        struct mq_attr _attr, *attr = NULL;
+
+        assert(path);
+        assert(_fd);
+
+        if (maxmsg > 0 && msgsize > 0) {
+                zero(_attr);
+                _attr.mq_flags = O_NONBLOCK;
+                _attr.mq_maxmsg = maxmsg;
+                _attr.mq_msgsize = msgsize;
+                attr = &_attr;
+        }
+
+        /* Enforce the right access mode for the mq */
+        old_mask = umask(~ mq_mode);
+
+        /* Include the original umask in our mask */
+        umask(~mq_mode | old_mask);
+
+        fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
+        umask(old_mask);
+
+        if (fd < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if (fstat(fd, &st) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
+            st.st_uid != getuid() ||
+            st.st_gid != getgid()) {
+
+                r = -EEXIST;
+                goto fail;
+        }
+
+        *_fd = fd;
+        return 0;
+
+fail:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
+
+static int socket_open_fds(Socket *s) {
+        SocketPort *p;
+        int r;
+        char *label = NULL;
+        bool know_label = false;
+
+        assert(s);
+
+        LIST_FOREACH(port, p, s->ports) {
+
+                if (p->fd >= 0)
+                        continue;
+
+                if (p->type == SOCKET_SOCKET) {
+
+                        if (!know_label) {
+
+                                if ((r = socket_instantiate_service(s)) < 0)
+                                        return r;
+
+                                if (UNIT_DEREF(s->service) &&
+                                    SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
+                                        r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
+
+                                        if (r < 0) {
+                                                if (r != -EPERM)
+                                                        return r;
+                                        }
+                                }
+
+                                know_label = true;
+                        }
+
+                        if ((r = socket_address_listen(
+                                             &p->address,
+                                             s->backlog,
+                                             s->bind_ipv6_only,
+                                             s->bind_to_device,
+                                             s->free_bind,
+                                             s->transparent,
+                                             s->directory_mode,
+                                             s->socket_mode,
+                                             label,
+                                             &p->fd)) < 0)
+                                goto rollback;
+
+                        socket_apply_socket_options(s, p->fd);
+
+                } else  if (p->type == SOCKET_SPECIAL) {
+
+                        if ((r = special_address_create(
+                                             p->path,
+                                             &p->fd)) < 0)
+                                goto rollback;
+
+                } else  if (p->type == SOCKET_FIFO) {
+
+                        if ((r = fifo_address_create(
+                                             p->path,
+                                             s->directory_mode,
+                                             s->socket_mode,
+                                             &p->fd)) < 0)
+                                goto rollback;
+
+                        socket_apply_fifo_options(s, p->fd);
+                } else if (p->type == SOCKET_MQUEUE) {
+
+                        if ((r = mq_address_create(
+                                             p->path,
+                                             s->socket_mode,
+                                             s->mq_maxmsg,
+                                             s->mq_msgsize,
+                                             &p->fd)) < 0)
+                                goto rollback;
+                } else
+                        assert_not_reached("Unknown port type");
+        }
+
+        label_free(label);
+        return 0;
+
+rollback:
+        socket_close_fds(s);
+        label_free(label);
+        return r;
+}
+
+static void socket_unwatch_fds(Socket *s) {
+        SocketPort *p;
+
+        assert(s);
+
+        LIST_FOREACH(port, p, s->ports) {
+                if (p->fd < 0)
+                        continue;
+
+                unit_unwatch_fd(UNIT(s), &p->fd_watch);
+        }
+}
+
+static int socket_watch_fds(Socket *s) {
+        SocketPort *p;
+        int r;
+
+        assert(s);
+
+        LIST_FOREACH(port, p, s->ports) {
+                if (p->fd < 0)
+                        continue;
+
+                p->fd_watch.socket_accept =
+                        s->accept &&
+                        p->type == SOCKET_SOCKET &&
+                        socket_address_can_accept(&p->address);
+
+                if ((r = unit_watch_fd(UNIT(s), p->fd, EPOLLIN, &p->fd_watch)) < 0)
+                        goto fail;
+        }
+
+        return 0;
+
+fail:
+        socket_unwatch_fds(s);
+        return r;
+}
+
+static void socket_set_state(Socket *s, SocketState state) {
+        SocketState old_state;
+        assert(s);
+
+        old_state = s->state;
+        s->state = state;
+
+        if (state != SOCKET_START_PRE &&
+            state != SOCKET_START_POST &&
+            state != SOCKET_STOP_PRE &&
+            state != SOCKET_STOP_PRE_SIGTERM &&
+            state != SOCKET_STOP_PRE_SIGKILL &&
+            state != SOCKET_STOP_POST &&
+            state != SOCKET_FINAL_SIGTERM &&
+            state != SOCKET_FINAL_SIGKILL) {
+                unit_unwatch_timer(UNIT(s), &s->timer_watch);
+                socket_unwatch_control_pid(s);
+                s->control_command = NULL;
+                s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
+        }
+
+        if (state != SOCKET_LISTENING)
+                socket_unwatch_fds(s);
+
+        if (state != SOCKET_START_POST &&
+            state != SOCKET_LISTENING &&
+            state != SOCKET_RUNNING &&
+            state != SOCKET_STOP_PRE &&
+            state != SOCKET_STOP_PRE_SIGTERM &&
+            state != SOCKET_STOP_PRE_SIGKILL)
+                socket_close_fds(s);
+
+        if (state != old_state)
+                log_debug_unit(UNIT(s)->id,
+                               "%s changed %s -> %s", UNIT(s)->id,
+                               socket_state_to_string(old_state),
+                               socket_state_to_string(state));
+
+        unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
+}
+
+static int socket_coldplug(Unit *u) {
+        Socket *s = SOCKET(u);
+        int r;
+
+        assert(s);
+        assert(s->state == SOCKET_DEAD);
+
+        if (s->deserialized_state != s->state) {
+
+                if (s->deserialized_state == SOCKET_START_PRE ||
+                    s->deserialized_state == SOCKET_START_POST ||
+                    s->deserialized_state == SOCKET_STOP_PRE ||
+                    s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
+                    s->deserialized_state == SOCKET_STOP_PRE_SIGKILL ||
+                    s->deserialized_state == SOCKET_STOP_POST ||
+                    s->deserialized_state == SOCKET_FINAL_SIGTERM ||
+                    s->deserialized_state == SOCKET_FINAL_SIGKILL) {
+
+                        if (s->control_pid <= 0)
+                                return -EBADMSG;
+
+                        r = unit_watch_pid(UNIT(s), s->control_pid);
+                        if (r < 0)
+                                return r;
+
+                        r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
+                        if (r < 0)
+                                return r;
+                }
+
+                if (s->deserialized_state == SOCKET_START_POST ||
+                    s->deserialized_state == SOCKET_LISTENING ||
+                    s->deserialized_state == SOCKET_RUNNING ||
+                    s->deserialized_state == SOCKET_STOP_PRE ||
+                    s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
+                    s->deserialized_state == SOCKET_STOP_PRE_SIGKILL)
+                        if ((r = socket_open_fds(s)) < 0)
+                                return r;
+
+                if (s->deserialized_state == SOCKET_LISTENING)
+                        if ((r = socket_watch_fds(s)) < 0)
+                                return r;
+
+                socket_set_state(s, s->deserialized_state);
+        }
+
+        return 0;
+}
+
+static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
+        pid_t pid;
+        int r;
+        char **argv;
+
+        assert(s);
+        assert(c);
+        assert(_pid);
+
+        r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
+        if (r < 0)
+                goto fail;
+
+        argv = unit_full_printf_strv(UNIT(s), c->argv);
+        if (!argv) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        r = exec_spawn(c,
+                       argv,
+                       &s->exec_context,
+                       NULL, 0,
+                       UNIT(s)->manager->environment,
+                       true,
+                       true,
+                       true,
+                       UNIT(s)->manager->confirm_spawn,
+                       UNIT(s)->cgroup_bondings,
+                       UNIT(s)->cgroup_attributes,
+                       NULL,
+                       UNIT(s)->id,
+                       NULL,
+                       &pid);
+
+        strv_free(argv);
+        if (r < 0)
+                goto fail;
+
+        if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
+                /* FIXME: we need to do something here */
+                goto fail;
+
+        *_pid = pid;
+
+        return 0;
+
+fail:
+        unit_unwatch_timer(UNIT(s), &s->timer_watch);
+
+        return r;
+}
+
+static void socket_enter_dead(Socket *s, SocketResult f) {
+        assert(s);
+
+        if (f != SOCKET_SUCCESS)
+                s->result = f;
+
+        socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
+}
+
+static void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
+
+static void socket_enter_stop_post(Socket *s, SocketResult f) {
+        int r;
+        assert(s);
+
+        if (f != SOCKET_SUCCESS)
+                s->result = f;
+
+        socket_unwatch_control_pid(s);
+
+        s->control_command_id = SOCKET_EXEC_STOP_POST;
+
+        if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
+                if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
+                        goto fail;
+
+                socket_set_state(s, SOCKET_STOP_POST);
+        } else
+                socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'stop-post' task: %s",
+                         UNIT(s)->id, strerror(-r));
+        socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
+}
+
+static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) {
+        int r;
+        Set *pid_set = NULL;
+        bool wait_for_exit = false;
+
+        assert(s);
+
+        if (f != SOCKET_SUCCESS)
+                s->result = f;
+
+        if (s->kill_context.kill_mode != KILL_NONE) {
+                int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? s->kill_context.kill_signal : SIGKILL;
+
+                if (s->control_pid > 0) {
+                        if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
+
+                                log_warning_unit(UNIT(s)->id,
+                                                 "Failed to kill control process %li: %m",
+                                                 (long) s->control_pid);
+                        else
+                                wait_for_exit = true;
+                }
+
+                if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) {
+
+                        if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        /* Exclude the control pid from being killed via the cgroup */
+                        if (s->control_pid > 0)
+                                if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
+                                        goto fail;
+
+                        r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
+                        if (r < 0) {
+                                if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
+                                        log_warning_unit(UNIT(s)->id,
+                                                         "Failed to kill control group: %s",
+                                                         strerror(-r));
+                        } else if (r > 0)
+                                wait_for_exit = true;
+
+                        set_free(pid_set);
+                        pid_set = NULL;
+                }
+        }
+
+        if (wait_for_exit) {
+                r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
+                if (r < 0)
+                        goto fail;
+
+                socket_set_state(s, state);
+        } else if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
+                socket_enter_stop_post(s, SOCKET_SUCCESS);
+        else
+                socket_enter_dead(s, SOCKET_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to kill processes: %s",
+                         UNIT(s)->id, strerror(-r));
+
+        if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
+                socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
+        else
+                socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
+
+        if (pid_set)
+                set_free(pid_set);
+}
+
+static void socket_enter_stop_pre(Socket *s, SocketResult f) {
+        int r;
+        assert(s);
+
+        if (f != SOCKET_SUCCESS)
+                s->result = f;
+
+        socket_unwatch_control_pid(s);
+
+        s->control_command_id = SOCKET_EXEC_STOP_PRE;
+
+        if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
+                if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
+                        goto fail;
+
+                socket_set_state(s, SOCKET_STOP_PRE);
+        } else
+                socket_enter_stop_post(s, SOCKET_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'stop-pre' task: %s",
+                         UNIT(s)->id, strerror(-r));
+        socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
+}
+
+static void socket_enter_listening(Socket *s) {
+        int r;
+        assert(s);
+
+        r = socket_watch_fds(s);
+        if (r < 0) {
+                log_warning_unit(UNIT(s)->id,
+                                 "%s failed to watch sockets: %s",
+                                 UNIT(s)->id, strerror(-r));
+                goto fail;
+        }
+
+        socket_set_state(s, SOCKET_LISTENING);
+        return;
+
+fail:
+        socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
+}
+
+static void socket_enter_start_post(Socket *s) {
+        int r;
+        assert(s);
+
+        r = socket_open_fds(s);
+        if (r < 0) {
+                log_warning_unit(UNIT(s)->id,
+                                 "%s failed to listen on sockets: %s",
+                                 UNIT(s)->id, strerror(-r));
+                goto fail;
+        }
+
+        socket_unwatch_control_pid(s);
+
+        s->control_command_id = SOCKET_EXEC_START_POST;
+
+        if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
+                r = socket_spawn(s, s->control_command, &s->control_pid);
+                if (r < 0) {
+                        log_warning_unit(UNIT(s)->id,
+                                         "%s failed to run 'start-post' task: %s",
+                                         UNIT(s)->id, strerror(-r));
+                        goto fail;
+                }
+
+                socket_set_state(s, SOCKET_START_POST);
+        } else
+                socket_enter_listening(s);
+
+        return;
+
+fail:
+        socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
+}
+
+static void socket_enter_start_pre(Socket *s) {
+        int r;
+        assert(s);
+
+        socket_unwatch_control_pid(s);
+
+        s->control_command_id = SOCKET_EXEC_START_PRE;
+
+        if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
+                if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
+                        goto fail;
+
+                socket_set_state(s, SOCKET_START_PRE);
+        } else
+                socket_enter_start_post(s);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'start-pre' task: %s",
+                         UNIT(s)->id, strerror(-r));
+        socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
+}
+
+static void socket_enter_running(Socket *s, int cfd) {
+        int r;
+        DBusError error;
+
+        assert(s);
+        dbus_error_init(&error);
+
+        /* We don't take connections anymore if we are supposed to
+         * shut down anyway */
+        if (unit_pending_inactive(UNIT(s))) {
+                log_debug_unit(UNIT(s)->id,
+                               "Suppressing connection request on %s since unit stop is scheduled.",
+                               UNIT(s)->id);
+
+                if (cfd >= 0)
+                        close_nointr_nofail(cfd);
+                else  {
+                        /* Flush all sockets by closing and reopening them */
+                        socket_close_fds(s);
+
+                        r = socket_watch_fds(s);
+                        if (r < 0) {
+                                log_warning_unit(UNIT(s)->id,
+                                                 "%s failed to watch sockets: %s",
+                                                 UNIT(s)->id, strerror(-r));
+                                socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
+                        }
+                }
+
+                return;
+        }
+
+        if (cfd < 0) {
+                Iterator i;
+                Unit *u;
+                bool pending = false;
+
+                /* If there's already a start pending don't bother to
+                 * do anything */
+                SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERS], i)
+                        if (unit_pending_active(u)) {
+                                pending = true;
+                                break;
+                        }
+
+                if (!pending) {
+                        r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                socket_set_state(s, SOCKET_RUNNING);
+        } else {
+                char *prefix, *instance = NULL, *name;
+                Service *service;
+
+                if (s->n_connections >= s->max_connections) {
+                        log_warning_unit(UNIT(s)->id,
+                                         "%s: Too many incoming connections (%u)",
+                                         UNIT(s)->id, s->n_connections);
+                        close_nointr_nofail(cfd);
+                        return;
+                }
+
+                r = socket_instantiate_service(s);
+                if (r < 0)
+                        goto fail;
+
+                r = instance_from_socket(cfd, s->n_accepted, &instance);
+                if (r < 0) {
+                        if (r != -ENOTCONN)
+                                goto fail;
+
+                        /* ENOTCONN is legitimate if TCP RST was received.
+                         * This connection is over, but the socket unit lives on. */
+                        close_nointr_nofail(cfd);
+                        return;
+                }
+
+                prefix = unit_name_to_prefix(UNIT(s)->id);
+                if (!prefix) {
+                        free(instance);
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                name = unit_name_build(prefix, instance, ".service");
+                free(prefix);
+                free(instance);
+
+                if (!name) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                r = unit_add_name(UNIT_DEREF(s->service), name);
+                if (r < 0) {
+                        free(name);
+                        goto fail;
+                }
+
+                service = SERVICE(UNIT_DEREF(s->service));
+                unit_ref_unset(&s->service);
+                s->n_accepted ++;
+
+                UNIT(service)->no_gc = false;
+
+                unit_choose_id(UNIT(service), name);
+                free(name);
+
+                r = service_set_socket_fd(service, cfd, s);
+                if (r < 0)
+                        goto fail;
+
+                cfd = -1;
+                s->n_connections ++;
+
+                r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL);
+                if (r < 0)
+                        goto fail;
+
+                /* Notify clients about changed counters */
+                unit_add_to_dbus_queue(UNIT(s));
+        }
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
+                         UNIT(s)->id,
+                         cfd >= 0 ? "template" : "non-template",
+                         bus_error(&error, r));
+        socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
+
+        if (cfd >= 0)
+                close_nointr_nofail(cfd);
+
+        dbus_error_free(&error);
+}
+
+static void socket_run_next(Socket *s) {
+        int r;
+
+        assert(s);
+        assert(s->control_command);
+        assert(s->control_command->command_next);
+
+        socket_unwatch_control_pid(s);
+
+        s->control_command = s->control_command->command_next;
+
+        if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
+                goto fail;
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run next task: %s",
+                         UNIT(s)->id, strerror(-r));
+
+        if (s->state == SOCKET_START_POST)
+                socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
+        else if (s->state == SOCKET_STOP_POST)
+                socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
+        else
+                socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
+}
+
+static int socket_start(Unit *u) {
+        Socket *s = SOCKET(u);
+
+        assert(s);
+
+        /* We cannot fulfill this request right now, try again later
+         * please! */
+        if (s->state == SOCKET_STOP_PRE ||
+            s->state == SOCKET_STOP_PRE_SIGKILL ||
+            s->state == SOCKET_STOP_PRE_SIGTERM ||
+            s->state == SOCKET_STOP_POST ||
+            s->state == SOCKET_FINAL_SIGTERM ||
+            s->state == SOCKET_FINAL_SIGKILL)
+                return -EAGAIN;
+
+        if (s->state == SOCKET_START_PRE ||
+            s->state == SOCKET_START_POST)
+                return 0;
+
+        /* Cannot run this without the service being around */
+        if (UNIT_DEREF(s->service)) {
+                Service *service;
+
+                service = SERVICE(UNIT_DEREF(s->service));
+
+                if (UNIT(service)->load_state != UNIT_LOADED) {
+                        log_error_unit(UNIT(service)->id,
+                                       "Socket service %s not loaded, refusing.",
+                                       UNIT(service)->id);
+                        return -ENOENT;
+                }
+
+                /* If the service is already active we cannot start the
+                 * socket */
+                if (service->state != SERVICE_DEAD &&
+                    service->state != SERVICE_FAILED &&
+                    service->state != SERVICE_AUTO_RESTART) {
+                        log_error_unit(UNIT(service)->id,
+                                       "Socket service %s already active, refusing.",
+                                       UNIT(service)->id);
+                        return -EBUSY;
+                }
+
+#ifdef HAVE_SYSV_COMPAT
+                if (service->is_sysv) {
+                        log_error_unit(UNIT(s)->id,
+                                       "Using SysV services for socket activation is not supported. Refusing.");
+                        return -ENOENT;
+                }
+#endif
+        }
+
+        assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
+
+        s->result = SOCKET_SUCCESS;
+        socket_enter_start_pre(s);
+        return 0;
+}
+
+static int socket_stop(Unit *u) {
+        Socket *s = SOCKET(u);
+
+        assert(s);
+
+        /* Already on it */
+        if (s->state == SOCKET_STOP_PRE ||
+            s->state == SOCKET_STOP_PRE_SIGTERM ||
+            s->state == SOCKET_STOP_PRE_SIGKILL ||
+            s->state == SOCKET_STOP_POST ||
+            s->state == SOCKET_FINAL_SIGTERM ||
+            s->state == SOCKET_FINAL_SIGKILL)
+                return 0;
+
+        /* If there's already something running we go directly into
+         * kill mode. */
+        if (s->state == SOCKET_START_PRE ||
+            s->state == SOCKET_START_POST) {
+                socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
+                return -EAGAIN;
+        }
+
+        assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
+
+        socket_enter_stop_pre(s, SOCKET_SUCCESS);
+        return 0;
+}
+
+static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Socket *s = SOCKET(u);
+        SocketPort *p;
+        int r;
+
+        assert(u);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", socket_state_to_string(s->state));
+        unit_serialize_item(u, f, "result", socket_result_to_string(s->result));
+        unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted);
+
+        if (s->control_pid > 0)
+                unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
+
+        if (s->control_command_id >= 0)
+                unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
+
+        LIST_FOREACH(port, p, s->ports) {
+                int copy;
+
+                if (p->fd < 0)
+                        continue;
+
+                if ((copy = fdset_put_dup(fds, p->fd)) < 0)
+                        return copy;
+
+                if (p->type == SOCKET_SOCKET) {
+                        char *t;
+
+                        r = socket_address_print(&p->address, &t);
+                        if (r < 0)
+                                return r;
+
+                        if (socket_address_family(&p->address) == AF_NETLINK)
+                                unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t);
+                        else
+                                unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t);
+                        free(t);
+                } else if (p->type == SOCKET_SPECIAL)
+                        unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path);
+                else if (p->type == SOCKET_MQUEUE)
+                        unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path);
+                else {
+                        assert(p->type == SOCKET_FIFO);
+                        unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path);
+                }
+        }
+
+        return 0;
+}
+
+static int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Socket *s = SOCKET(u);
+
+        assert(u);
+        assert(key);
+        assert(value);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                SocketState state;
+
+                state = socket_state_from_string(value);
+                if (state < 0)
+                        log_debug_unit(u->id,
+                                       "Failed to parse state value %s", value);
+                else
+                        s->deserialized_state = state;
+        } else if (streq(key, "result")) {
+                SocketResult f;
+
+                f = socket_result_from_string(value);
+                if (f < 0)
+                        log_debug_unit(u->id,
+                                       "Failed to parse result value %s", value);
+                else if (f != SOCKET_SUCCESS)
+                        s->result = f;
+
+        } else if (streq(key, "n-accepted")) {
+                unsigned k;
+
+                if (safe_atou(value, &k) < 0)
+                        log_debug_unit(u->id,
+                                       "Failed to parse n-accepted value %s", value);
+                else
+                        s->n_accepted += k;
+        } else if (streq(key, "control-pid")) {
+                pid_t pid;
+
+                if (parse_pid(value, &pid) < 0)
+                        log_debug_unit(u->id,
+                                       "Failed to parse control-pid value %s", value);
+                else
+                        s->control_pid = pid;
+        } else if (streq(key, "control-command")) {
+                SocketExecCommand id;
+
+                id = socket_exec_command_from_string(value);
+                if (id < 0)
+                        log_debug_unit(u->id,
+                                       "Failed to parse exec-command value %s", value);
+                else {
+                        s->control_command_id = id;
+                        s->control_command = s->exec_command[id];
+                }
+        } else if (streq(key, "fifo")) {
+                int fd, skip = 0;
+                SocketPort *p;
+
+                if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
+                        log_debug_unit(u->id,
+                                       "Failed to parse fifo value %s", value);
+                else {
+
+                        LIST_FOREACH(port, p, s->ports)
+                                if (p->type == SOCKET_FIFO &&
+                                    streq_ptr(p->path, value+skip))
+                                        break;
+
+                        if (p) {
+                                if (p->fd >= 0)
+                                        close_nointr_nofail(p->fd);
+                                p->fd = fdset_remove(fds, fd);
+                        }
+                }
+
+        } else if (streq(key, "special")) {
+                int fd, skip = 0;
+                SocketPort *p;
+
+                if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
+                        log_debug_unit(u->id,
+                                       "Failed to parse special value %s", value);
+                else {
+
+                        LIST_FOREACH(port, p, s->ports)
+                                if (p->type == SOCKET_SPECIAL &&
+                                    streq_ptr(p->path, value+skip))
+                                        break;
+
+                        if (p) {
+                                if (p->fd >= 0)
+                                        close_nointr_nofail(p->fd);
+                                p->fd = fdset_remove(fds, fd);
+                        }
+                }
+
+        } else if (streq(key, "mqueue")) {
+                int fd, skip = 0;
+                SocketPort *p;
+
+                if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
+                        log_debug_unit(u->id,
+                                       "Failed to parse mqueue value %s", value);
+                else {
+
+                        LIST_FOREACH(port, p, s->ports)
+                                if (p->type == SOCKET_MQUEUE &&
+                                    streq_ptr(p->path, value+skip))
+                                        break;
+
+                        if (p) {
+                                if (p->fd >= 0)
+                                        close_nointr_nofail(p->fd);
+                                p->fd = fdset_remove(fds, fd);
+                        }
+                }
+
+        } else if (streq(key, "socket")) {
+                int fd, type, skip = 0;
+                SocketPort *p;
+
+                if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd))
+                        log_debug_unit(u->id,
+                                       "Failed to parse socket value %s", value);
+                else {
+
+                        LIST_FOREACH(port, p, s->ports)
+                                if (socket_address_is(&p->address, value+skip, type))
+                                        break;
+
+                        if (p) {
+                                if (p->fd >= 0)
+                                        close_nointr_nofail(p->fd);
+                                p->fd = fdset_remove(fds, fd);
+                        }
+                }
+
+        } else if (streq(key, "netlink")) {
+                int fd, skip = 0;
+                SocketPort *p;
+
+                if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
+                        log_debug_unit(u->id,
+                                       "Failed to parse socket value %s", value);
+                else {
+
+                        LIST_FOREACH(port, p, s->ports)
+                                if (socket_address_is_netlink(&p->address, value+skip))
+                                        break;
+
+                        if (p) {
+                                if (p->fd >= 0)
+                                        close_nointr_nofail(p->fd);
+                                p->fd = fdset_remove(fds, fd);
+                        }
+                }
+
+        } else
+                log_debug_unit(UNIT(s)->id,
+                               "Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static int socket_distribute_fds(Unit *u, FDSet *fds) {
+        Socket *s = SOCKET(u);
+        SocketPort *p;
+
+        assert(u);
+
+        LIST_FOREACH(port, p, s->ports) {
+                Iterator i;
+                int fd;
+
+                if (p->type != SOCKET_SOCKET)
+                        continue;
+
+                if (p->fd >= 0)
+                        continue;
+
+                FDSET_FOREACH(fd, fds, i) {
+                        if (socket_address_matches_fd(&p->address, fd)) {
+                                p->fd = fdset_remove(fds, fd);
+                                s->deserialized_state = SOCKET_LISTENING;
+                                break;
+                        }
+                }
+        }
+
+        return 0;
+}
+
+static UnitActiveState socket_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[SOCKET(u)->state];
+}
+
+static const char *socket_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return socket_state_to_string(SOCKET(u)->state);
+}
+
+static bool socket_check_gc(Unit *u) {
+        Socket *s = SOCKET(u);
+
+        assert(u);
+
+        return s->n_connections > 0;
+}
+
+static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+        Socket *s = SOCKET(u);
+        int cfd = -1;
+
+        assert(s);
+        assert(fd >= 0);
+
+        if (s->state != SOCKET_LISTENING)
+                return;
+
+        log_debug_unit(u->id, "Incoming traffic on %s", u->id);
+
+        if (events != EPOLLIN) {
+
+                if (events & EPOLLHUP)
+                        log_error_unit(u->id,
+                                       "%s: Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.",
+                                       u->id);
+                else
+                        log_error_unit(u->id,
+                                       "%s: Got unexpected poll event (0x%x) on socket.",
+                                       u->id, events);
+
+                goto fail;
+        }
+
+        if (w->socket_accept) {
+                for (;;) {
+
+                        cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
+                        if (cfd < 0) {
+
+                                if (errno == EINTR)
+                                        continue;
+
+                                log_error_unit(u->id,
+                                               "Failed to accept socket: %m");
+                                goto fail;
+                        }
+
+                        break;
+                }
+
+                socket_apply_socket_options(s, cfd);
+        }
+
+        socket_enter_running(s, cfd);
+        return;
+
+fail:
+        socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
+}
+
+static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+        Socket *s = SOCKET(u);
+        SocketResult f;
+
+        assert(s);
+        assert(pid >= 0);
+
+        if (pid != s->control_pid)
+                return;
+
+        s->control_pid = 0;
+
+        if (is_clean_exit(code, status, NULL))
+                f = SOCKET_SUCCESS;
+        else if (code == CLD_EXITED)
+                f = SOCKET_FAILURE_EXIT_CODE;
+        else if (code == CLD_KILLED)
+                f = SOCKET_FAILURE_SIGNAL;
+        else if (code == CLD_DUMPED)
+                f = SOCKET_FAILURE_CORE_DUMP;
+        else
+                assert_not_reached("Unknown code");
+
+        if (s->control_command) {
+                exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
+
+                if (s->control_command->ignore)
+                        f = SOCKET_SUCCESS;
+        }
+
+        log_full_unit(f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+                      u->id,
+                      "%s control process exited, code=%s status=%i",
+                      u->id, sigchld_code_to_string(code), status);
+
+        if (f != SOCKET_SUCCESS)
+                s->result = f;
+
+        if (s->control_command &&
+            s->control_command->command_next &&
+            f == SOCKET_SUCCESS) {
+
+                log_debug_unit(u->id,
+                               "%s running next command for state %s",
+                               u->id, socket_state_to_string(s->state));
+                socket_run_next(s);
+        } else {
+                s->control_command = NULL;
+                s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
+
+                /* No further commands for this step, so let's figure
+                 * out what to do next */
+
+                log_debug_unit(u->id,
+                               "%s got final SIGCHLD for state %s",
+                               u->id, socket_state_to_string(s->state));
+
+                switch (s->state) {
+
+                case SOCKET_START_PRE:
+                        if (f == SOCKET_SUCCESS)
+                                socket_enter_start_post(s);
+                        else
+                                socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f);
+                        break;
+
+                case SOCKET_START_POST:
+                        if (f == SOCKET_SUCCESS)
+                                socket_enter_listening(s);
+                        else
+                                socket_enter_stop_pre(s, f);
+                        break;
+
+                case SOCKET_STOP_PRE:
+                case SOCKET_STOP_PRE_SIGTERM:
+                case SOCKET_STOP_PRE_SIGKILL:
+                        socket_enter_stop_post(s, f);
+                        break;
+
+                case SOCKET_STOP_POST:
+                case SOCKET_FINAL_SIGTERM:
+                case SOCKET_FINAL_SIGKILL:
+                        socket_enter_dead(s, f);
+                        break;
+
+                default:
+                        assert_not_reached("Uh, control process died at wrong time.");
+                }
+        }
+
+        /* Notify clients about changed exit status */
+        unit_add_to_dbus_queue(u);
+}
+
+static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
+        Socket *s = SOCKET(u);
+
+        assert(s);
+        assert(elapsed == 1);
+        assert(w == &s->timer_watch);
+
+        switch (s->state) {
+
+        case SOCKET_START_PRE:
+                log_warning_unit(u->id,
+                                 "%s starting timed out. Terminating.", u->id);
+                socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
+                break;
+
+        case SOCKET_START_POST:
+                log_warning_unit(u->id,
+                                 "%s starting timed out. Stopping.", u->id);
+                socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
+                break;
+
+        case SOCKET_STOP_PRE:
+                log_warning_unit(u->id,
+                                 "%s stopping timed out. Terminating.", u->id);
+                socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT);
+                break;
+
+        case SOCKET_STOP_PRE_SIGTERM:
+                if (s->kill_context.send_sigkill) {
+                        log_warning_unit(u->id,
+                                         "%s stopping timed out. Killing.", u->id);
+                        socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id,
+                                         "%s stopping timed out. Skipping SIGKILL. Ignoring.",
+                                         u->id);
+                        socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
+                }
+                break;
+
+        case SOCKET_STOP_PRE_SIGKILL:
+                log_warning_unit(u->id,
+                                 "%s still around after SIGKILL. Ignoring.", u->id);
+                socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
+                break;
+
+        case SOCKET_STOP_POST:
+                log_warning_unit(u->id,
+                                 "%s stopping timed out (2). Terminating.", u->id);
+                socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
+                break;
+
+        case SOCKET_FINAL_SIGTERM:
+                if (s->kill_context.send_sigkill) {
+                        log_warning_unit(u->id,
+                                         "%s stopping timed out (2). Killing.", u->id);
+                        socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id,
+                                         "%s stopping timed out (2). Skipping SIGKILL. Ignoring.",
+                                         u->id);
+                        socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
+                }
+                break;
+
+        case SOCKET_FINAL_SIGKILL:
+                log_warning_unit(u->id,
+                                 "%s still around after SIGKILL (2). Entering failed mode.",
+                                 u->id);
+                socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
+                break;
+
+        default:
+                assert_not_reached("Timeout at wrong time.");
+        }
+}
+
+int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
+        int *rfds;
+        unsigned rn_fds, k;
+        SocketPort *p;
+
+        assert(s);
+        assert(fds);
+        assert(n_fds);
+
+        /* Called from the service code for requesting our fds */
+
+        rn_fds = 0;
+        LIST_FOREACH(port, p, s->ports)
+                if (p->fd >= 0)
+                        rn_fds++;
+
+        if (rn_fds <= 0) {
+                *fds = NULL;
+                *n_fds = 0;
+                return 0;
+        }
+
+        if (!(rfds = new(int, rn_fds)))
+                return -ENOMEM;
+
+        k = 0;
+        LIST_FOREACH(port, p, s->ports)
+                if (p->fd >= 0)
+                        rfds[k++] = p->fd;
+
+        assert(k == rn_fds);
+
+        *fds = rfds;
+        *n_fds = rn_fds;
+
+        return 0;
+}
+
+void socket_notify_service_dead(Socket *s, bool failed_permanent) {
+        assert(s);
+
+        /* The service is dead. Dang!
+         *
+         * This is strictly for one-instance-for-all-connections
+         * services. */
+
+        if (s->state == SOCKET_RUNNING) {
+                log_debug_unit(UNIT(s)->id,
+                               "%s got notified about service death (failed permanently: %s)",
+                               UNIT(s)->id, yes_no(failed_permanent));
+                if (failed_permanent)
+                        socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_FAILED_PERMANENT);
+                else
+                        socket_enter_listening(s);
+        }
+}
+
+void socket_connection_unref(Socket *s) {
+        assert(s);
+
+        /* The service is dead. Yay!
+         *
+         * This is strictly for one-instance-per-connection
+         * services. */
+
+        assert(s->n_connections > 0);
+        s->n_connections--;
+
+        log_debug_unit(UNIT(s)->id,
+                       "%s: One connection closed, %u left.", UNIT(s)->id, s->n_connections);
+}
+
+static void socket_reset_failed(Unit *u) {
+        Socket *s = SOCKET(u);
+
+        assert(s);
+
+        if (s->state == SOCKET_FAILED)
+                socket_set_state(s, SOCKET_DEAD);
+
+        s->result = SOCKET_SUCCESS;
+}
+
+static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) {
+        Socket *s = SOCKET(u);
+        int r = 0;
+        Set *pid_set = NULL;
+
+        assert(s);
+
+        if (who == KILL_MAIN) {
+                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Socket units have no main processes");
+                return -ESRCH;
+        }
+
+        if (s->control_pid <= 0 && who == KILL_CONTROL) {
+                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
+                return -ESRCH;
+        }
+
+        if (who == KILL_CONTROL || who == KILL_ALL)
+                if (s->control_pid > 0)
+                        if (kill(s->control_pid, signo) < 0)
+                                r = -errno;
+
+        if (who == KILL_ALL) {
+                int q;
+
+                pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!pid_set)
+                        return -ENOMEM;
+
+                /* Exclude the control pid from being killed via the cgroup */
+                if (s->control_pid > 0) {
+                        q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
+                        if (q < 0) {
+                                r = q;
+                                goto finish;
+                        }
+                }
+
+                q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
+                if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
+                        r = q;
+        }
+
+finish:
+        if (pid_set)
+                set_free(pid_set);
+
+        return r;
+}
+
+static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
+        [SOCKET_DEAD] = "dead",
+        [SOCKET_START_PRE] = "start-pre",
+        [SOCKET_START_POST] = "start-post",
+        [SOCKET_LISTENING] = "listening",
+        [SOCKET_RUNNING] = "running",
+        [SOCKET_STOP_PRE] = "stop-pre",
+        [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
+        [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
+        [SOCKET_STOP_POST] = "stop-post",
+        [SOCKET_FINAL_SIGTERM] = "final-sigterm",
+        [SOCKET_FINAL_SIGKILL] = "final-sigkill",
+        [SOCKET_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
+
+static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
+        [SOCKET_EXEC_START_PRE] = "StartPre",
+        [SOCKET_EXEC_START_POST] = "StartPost",
+        [SOCKET_EXEC_STOP_PRE] = "StopPre",
+        [SOCKET_EXEC_STOP_POST] = "StopPost"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand);
+
+static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
+        [SOCKET_SUCCESS] = "success",
+        [SOCKET_FAILURE_RESOURCES] = "resources",
+        [SOCKET_FAILURE_TIMEOUT] = "timeout",
+        [SOCKET_FAILURE_EXIT_CODE] = "exit-code",
+        [SOCKET_FAILURE_SIGNAL] = "signal",
+        [SOCKET_FAILURE_CORE_DUMP] = "core-dump",
+        [SOCKET_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult);
+
+const UnitVTable socket_vtable = {
+        .object_size = sizeof(Socket),
+        .exec_context_offset = offsetof(Socket, exec_context),
+
+        .sections =
+                "Unit\0"
+                "Socket\0"
+                "Install\0",
+
+        .init = socket_init,
+        .done = socket_done,
+        .load = socket_load,
+
+        .kill = socket_kill,
+
+        .coldplug = socket_coldplug,
+
+        .dump = socket_dump,
+
+        .start = socket_start,
+        .stop = socket_stop,
+
+        .serialize = socket_serialize,
+        .deserialize_item = socket_deserialize_item,
+        .distribute_fds = socket_distribute_fds,
+
+        .active_state = socket_active_state,
+        .sub_state_to_string = socket_sub_state_to_string,
+
+        .check_gc = socket_check_gc,
+
+        .fd_event = socket_fd_event,
+        .sigchld_event = socket_sigchld_event,
+        .timer_event = socket_timer_event,
+
+        .reset_failed = socket_reset_failed,
+
+        .bus_interface = "org.freedesktop.systemd1.Socket",
+        .bus_message_handler = bus_socket_message_handler,
+        .bus_invalidating_properties =  bus_socket_invalidating_properties,
+
+        .status_message_formats = {
+                /*.starting_stopping = {
+                        [0] = "Starting socket %s...",
+                        [1] = "Stopping socket %s...",
+                },*/
+                .finished_start_job = {
+                        [JOB_DONE]       = "Listening on %s.",
+                        [JOB_FAILED]     = "Failed to listen on %s.",
+                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                        [JOB_TIMEOUT]    = "Timed out starting %s.",
+                },
+                .finished_stop_job = {
+                        [JOB_DONE]       = "Closed %s.",
+                        [JOB_FAILED]     = "Failed stopping %s.",
+                        [JOB_TIMEOUT]    = "Timed out stopping %s.",
+                },
+        },
+};
diff --git a/src/core/socket.h b/src/core/socket.h
new file mode 100644 (file)
index 0000000..f099520
--- /dev/null
@@ -0,0 +1,175 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Socket Socket;
+
+#include "manager.h"
+#include "unit.h"
+#include "socket-util.h"
+#include "mount.h"
+#include "service.h"
+
+typedef enum SocketState {
+        SOCKET_DEAD,
+        SOCKET_START_PRE,
+        SOCKET_START_POST,
+        SOCKET_LISTENING,
+        SOCKET_RUNNING,
+        SOCKET_STOP_PRE,
+        SOCKET_STOP_PRE_SIGTERM,
+        SOCKET_STOP_PRE_SIGKILL,
+        SOCKET_STOP_POST,
+        SOCKET_FINAL_SIGTERM,
+        SOCKET_FINAL_SIGKILL,
+        SOCKET_FAILED,
+        _SOCKET_STATE_MAX,
+        _SOCKET_STATE_INVALID = -1
+} SocketState;
+
+typedef enum SocketExecCommand {
+        SOCKET_EXEC_START_PRE,
+        SOCKET_EXEC_START_POST,
+        SOCKET_EXEC_STOP_PRE,
+        SOCKET_EXEC_STOP_POST,
+        _SOCKET_EXEC_COMMAND_MAX,
+        _SOCKET_EXEC_COMMAND_INVALID = -1
+} SocketExecCommand;
+
+typedef enum SocketType {
+        SOCKET_SOCKET,
+        SOCKET_FIFO,
+        SOCKET_SPECIAL,
+        SOCKET_MQUEUE,
+        _SOCKET_FIFO_MAX,
+        _SOCKET_FIFO_INVALID = -1
+} SocketType;
+
+typedef enum SocketResult {
+        SOCKET_SUCCESS,
+        SOCKET_FAILURE_RESOURCES,
+        SOCKET_FAILURE_TIMEOUT,
+        SOCKET_FAILURE_EXIT_CODE,
+        SOCKET_FAILURE_SIGNAL,
+        SOCKET_FAILURE_CORE_DUMP,
+        SOCKET_FAILURE_SERVICE_FAILED_PERMANENT,
+        _SOCKET_RESULT_MAX,
+        _SOCKET_RESULT_INVALID = -1
+} SocketResult;
+
+typedef struct SocketPort {
+        SocketType type;
+        int fd;
+
+        SocketAddress address;
+        char *path;
+        Watch fd_watch;
+
+        LIST_FIELDS(struct SocketPort, port);
+} SocketPort;
+
+struct Socket {
+        Unit meta;
+
+        LIST_HEAD(SocketPort, ports);
+
+        unsigned n_accepted;
+        unsigned n_connections;
+        unsigned max_connections;
+
+        unsigned backlog;
+        usec_t timeout_usec;
+
+        ExecCommand* exec_command[_SOCKET_EXEC_COMMAND_MAX];
+        ExecContext exec_context;
+        KillContext kill_context;
+
+        /* For Accept=no sockets refers to the one service we'll
+        activate. For Accept=yes sockets is either NULL, or filled
+        when the next service we spawn. */
+        UnitRef service;
+
+        SocketState state, deserialized_state;
+
+        Watch timer_watch;
+
+        ExecCommand* control_command;
+        SocketExecCommand control_command_id;
+        pid_t control_pid;
+
+        mode_t directory_mode;
+        mode_t socket_mode;
+
+        SocketResult result;
+
+        bool accept;
+
+        /* Socket options */
+        bool keep_alive;
+        bool free_bind;
+        bool transparent;
+        bool broadcast;
+        bool pass_cred;
+        bool pass_sec;
+        int priority;
+        int mark;
+        size_t receive_buffer;
+        size_t send_buffer;
+        int ip_tos;
+        int ip_ttl;
+        size_t pipe_size;
+        char *bind_to_device;
+        char *tcp_congestion;
+        long mq_maxmsg;
+        long mq_msgsize;
+
+        /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
+        SocketAddressBindIPv6Only bind_ipv6_only;
+
+        char *smack;
+        char *smack_ip_in;
+        char *smack_ip_out;
+};
+
+/* Called from the service code when collecting fds */
+int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds);
+
+/* Called from the service when it shut down */
+void socket_notify_service_dead(Socket *s, bool failed_permanent);
+
+/* Called from the mount code figure out if a mount is a dependency of
+ * any of the sockets of this socket */
+int socket_add_one_mount_link(Socket *s, Mount *m);
+
+/* Called from the service code when a per-connection service ended */
+void socket_connection_unref(Socket *s);
+
+extern const UnitVTable socket_vtable;
+
+const char* socket_state_to_string(SocketState i);
+SocketState socket_state_from_string(const char *s);
+
+const char* socket_exec_command_to_string(SocketExecCommand i);
+SocketExecCommand socket_exec_command_from_string(const char *s);
+
+const char* socket_result_to_string(SocketResult i);
+SocketResult socket_result_from_string(const char *s);
diff --git a/src/core/special.h b/src/core/special.h
new file mode 100644 (file)
index 0000000..ef72260
--- /dev/null
@@ -0,0 +1,113 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#define SPECIAL_DEFAULT_TARGET "default.target"
+
+/* Shutdown targets */
+#define SPECIAL_UMOUNT_TARGET "umount.target"
+/* This is not really intended to be started by directly. This is
+ * mostly so that other targets (reboot/halt/poweroff) can depend on
+ * it to bring all services down that want to be brought down on
+ * system shutdown. */
+#define SPECIAL_SHUTDOWN_TARGET "shutdown.target"
+#define SPECIAL_HALT_TARGET "halt.target"
+#define SPECIAL_POWEROFF_TARGET "poweroff.target"
+#define SPECIAL_REBOOT_TARGET "reboot.target"
+#define SPECIAL_KEXEC_TARGET "kexec.target"
+#define SPECIAL_EXIT_TARGET "exit.target"
+#define SPECIAL_SUSPEND_TARGET "suspend.target"
+#define SPECIAL_HIBERNATE_TARGET "hibernate.target"
+#define SPECIAL_HYBRID_SLEEP_TARGET "hybrid-sleep.target"
+
+/* Special boot targets */
+#define SPECIAL_RESCUE_TARGET "rescue.target"
+#define SPECIAL_EMERGENCY_TARGET "emergency.target"
+
+/* Early boot targets */
+#define SPECIAL_SYSINIT_TARGET "sysinit.target"
+#define SPECIAL_SOCKETS_TARGET "sockets.target"
+#define SPECIAL_LOCAL_FS_TARGET "local-fs.target"         /* LSB's $local_fs */
+#define SPECIAL_LOCAL_FS_PRE_TARGET "local-fs-pre.target"
+#define SPECIAL_REMOTE_FS_TARGET "remote-fs.target"       /* LSB's $remote_fs */
+#define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target"
+#define SPECIAL_SWAP_TARGET "swap.target"
+#define SPECIAL_BASIC_TARGET "basic.target"
+
+/* LSB compatibility */
+#define SPECIAL_NETWORK_TARGET "network.target"           /* LSB's $network */
+#define SPECIAL_NSS_LOOKUP_TARGET "nss-lookup.target"     /* LSB's $named */
+#define SPECIAL_RPCBIND_TARGET "rpcbind.target"           /* LSB's $portmap */
+#define SPECIAL_SYSLOG_TARGET "syslog.target"             /* LSB's $syslog */
+#define SPECIAL_TIME_SYNC_TARGET "time-sync.target"       /* LSB's $time */
+#define SPECIAL_DISPLAY_MANAGER_SERVICE "display-manager.service" /* Common extension of LSB */
+#define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Common extension of LSB */
+
+/*
+ * Rules regarding adding further high level targets like the above:
+ *
+ * - Be conservative, only add more of these when we really need
+ *   them. We need strong usecases for further additions.
+ *
+ * - When there can be multiple implementations running side-by-side,
+ *   it needs to be a .target unit which can pull in all
+ *   implementations.
+ *
+ * - If something can be implemented with socket activation, and
+ *   without, it needs to be a .target unit, so that it can pull in
+ *   the appropriate unit.
+ *
+ * - Otherwise, it should be a .service unit.
+ *
+ * - In some cases it is OK to have both a .service and a .target
+ *   unit, i.e. if there can be multiple parallel implementations, but
+ *   only one is the "system" one. Example: syslog.
+ *
+ * Or to put this in other words: .service symlinks can be used to
+ * arbitrate between multiple implementations if there can be only one
+ * of a kind. .target units can be used to support multiple
+ * implementations that can run side-by-side.
+ */
+
+/* Magic early boot services */
+#define SPECIAL_FSCK_SERVICE "systemd-fsck@.service"
+#define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck.service"
+#define SPECIAL_QUOTAON_SERVICE "quotaon.service"
+#define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service"
+
+/* Services systemd relies on */
+#define SPECIAL_DBUS_SERVICE "dbus.service"
+#define SPECIAL_DBUS_SOCKET "dbus.socket"
+#define SPECIAL_JOURNALD_SOCKET "systemd-journald.socket"
+#define SPECIAL_JOURNALD_SERVICE "systemd-journald.service"
+
+/* Magic init signals */
+#define SPECIAL_KBREQUEST_TARGET "kbrequest.target"
+#define SPECIAL_SIGPWR_TARGET "sigpwr.target"
+#define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target"
+
+/* For SysV compatibility. Usually an alias for a saner target. On
+ * SysV-free systems this doesn't exist. */
+#define SPECIAL_RUNLEVEL2_TARGET "runlevel2.target"
+#define SPECIAL_RUNLEVEL3_TARGET "runlevel3.target"
+#define SPECIAL_RUNLEVEL4_TARGET "runlevel4.target"
+#define SPECIAL_RUNLEVEL5_TARGET "runlevel5.target"
diff --git a/src/core/swap.c b/src/core/swap.c
new file mode 100644 (file)
index 0000000..c8e25d0
--- /dev/null
@@ -0,0 +1,1448 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+#include <libudev.h>
+
+#include "unit.h"
+#include "swap.h"
+#include "load-fragment.h"
+#include "load-dropin.h"
+#include "unit-name.h"
+#include "dbus-swap.h"
+#include "special.h"
+#include "bus-errors.h"
+#include "exit-status.h"
+#include "def.h"
+#include "path-util.h"
+#include "virt.h"
+
+static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
+        [SWAP_DEAD] = UNIT_INACTIVE,
+        [SWAP_ACTIVATING] = UNIT_ACTIVATING,
+        [SWAP_ACTIVE] = UNIT_ACTIVE,
+        [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
+        [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
+        [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
+        [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
+        [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
+        [SWAP_FAILED] = UNIT_FAILED
+};
+
+static void swap_unset_proc_swaps(Swap *s) {
+        Swap *first;
+        Hashmap *swaps;
+
+        assert(s);
+
+        if (!s->parameters_proc_swaps.what)
+                return;
+
+        /* Remove this unit from the chain of swaps which share the
+         * same kernel swap device. */
+        swaps = UNIT(s)->manager->swaps_by_proc_swaps;
+        first = hashmap_get(swaps, s->parameters_proc_swaps.what);
+        LIST_REMOVE(Swap, same_proc_swaps, first, s);
+
+        if (first)
+                hashmap_remove_and_replace(swaps,
+                                           s->parameters_proc_swaps.what,
+                                           first->parameters_proc_swaps.what,
+                                           first);
+        else
+                hashmap_remove(swaps, s->parameters_proc_swaps.what);
+
+        free(s->parameters_proc_swaps.what);
+        s->parameters_proc_swaps.what = NULL;
+}
+
+static void swap_init(Unit *u) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+        assert(UNIT(s)->load_state == UNIT_STUB);
+
+        s->timeout_usec = DEFAULT_TIMEOUT_USEC;
+
+        exec_context_init(&s->exec_context);
+        s->exec_context.std_output = u->manager->default_std_output;
+        s->exec_context.std_error = u->manager->default_std_error;
+        kill_context_init(&s->kill_context);
+
+        s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
+
+        s->timer_watch.type = WATCH_INVALID;
+
+        s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
+
+        UNIT(s)->ignore_on_isolate = true;
+}
+
+static void swap_unwatch_control_pid(Swap *s) {
+        assert(s);
+
+        if (s->control_pid <= 0)
+                return;
+
+        unit_unwatch_pid(UNIT(s), s->control_pid);
+        s->control_pid = 0;
+}
+
+static void swap_done(Unit *u) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+
+        swap_unset_proc_swaps(s);
+
+        free(s->what);
+        s->what = NULL;
+
+        free(s->parameters_fragment.what);
+        s->parameters_fragment.what = NULL;
+
+        exec_context_done(&s->exec_context);
+        exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
+        s->control_command = NULL;
+
+        swap_unwatch_control_pid(s);
+
+        unit_unwatch_timer(u, &s->timer_watch);
+}
+
+int swap_add_one_mount_link(Swap *s, Mount *m) {
+         int r;
+
+        assert(s);
+        assert(m);
+
+        if (UNIT(s)->load_state != UNIT_LOADED ||
+            UNIT(m)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (is_device_path(s->what))
+                return 0;
+
+        if (!path_startswith(s->what, m->where))
+                return 0;
+
+        r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int swap_add_mount_links(Swap *s) {
+        Unit *other;
+        int r;
+
+        assert(s);
+
+        LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
+                if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
+                        return r;
+
+        return 0;
+}
+
+static int swap_add_device_links(Swap *s) {
+        SwapParameters *p;
+
+        assert(s);
+
+        if (!s->what)
+                return 0;
+
+        if (s->from_fragment)
+                p = &s->parameters_fragment;
+        else
+                return 0;
+
+        if (is_device_path(s->what))
+                return unit_add_node_link(UNIT(s), s->what,
+                                          !p->noauto && p->nofail &&
+                                          UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
+        else
+                /* File based swap devices need to be ordered after
+                 * systemd-remount-fs.service, since they might need a
+                 * writable file system. */
+                return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
+}
+
+static int swap_add_default_dependencies(Swap *s) {
+        int r;
+
+        assert(s);
+
+        if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
+                return 0;
+
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int swap_verify(Swap *s) {
+        bool b;
+        char _cleanup_free_ *e = NULL;
+
+        if (UNIT(s)->load_state != UNIT_LOADED)
+                  return 0;
+
+        e = unit_name_from_path(s->what, ".swap");
+        if (e == NULL)
+                return log_oom();
+
+        b = unit_has_name(UNIT(s), e);
+        if (!b) {
+                log_error_unit(UNIT(s)->id,
+                               "%s: Value of \"What\" and unit name do not match, not loading.",
+                               UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
+                log_error_unit(UNIT(s)->id,
+                               "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
+                               UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static int swap_load(Unit *u) {
+        int r;
+        Swap *s = SWAP(u);
+
+        assert(s);
+        assert(u->load_state == UNIT_STUB);
+
+        /* Load a .swap file */
+        r = unit_load_fragment_and_dropin_optional(u);
+        if (r < 0)
+                return r;
+
+        if (u->load_state == UNIT_LOADED) {
+                r = unit_add_exec_dependencies(u, &s->exec_context);
+                if (r < 0)
+                        return r;
+
+                if (UNIT(s)->fragment_path)
+                        s->from_fragment = true;
+
+                if (!s->what) {
+                        if (s->parameters_fragment.what)
+                                s->what = strdup(s->parameters_fragment.what);
+                        else if (s->parameters_proc_swaps.what)
+                                s->what = strdup(s->parameters_proc_swaps.what);
+                        else
+                                s->what = unit_name_to_path(u->id);
+
+                        if (!s->what)
+                                return -ENOMEM;
+                }
+
+                path_kill_slashes(s->what);
+
+                if (!UNIT(s)->description)
+                        if ((r = unit_set_description(u, s->what)) < 0)
+                                return r;
+
+                r = swap_add_device_links(s);
+                if (r < 0)
+                        return r;
+
+                r = swap_add_mount_links(s);
+                if (r < 0)
+                        return r;
+
+                r = unit_add_default_cgroups(u);
+                if (r < 0)
+                        return r;
+
+                if (UNIT(s)->default_dependencies) {
+                        r = swap_add_default_dependencies(s);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = unit_exec_context_defaults(u, &s->exec_context);
+                if (r < 0)
+                        return r;
+        }
+
+        return swap_verify(s);
+}
+
+static int swap_add_one(
+                Manager *m,
+                const char *what,
+                const char *what_proc_swaps,
+                int priority,
+                bool noauto,
+                bool nofail,
+                bool set_flags) {
+
+        Unit *u = NULL;
+        char _cleanup_free_ *e = NULL;
+        char *wp = NULL;
+        bool delete = false;
+        int r;
+        SwapParameters *p;
+        Swap *first;
+
+        assert(m);
+        assert(what);
+        assert(what_proc_swaps);
+
+        e = unit_name_from_path(what, ".swap");
+        if (!e)
+                return log_oom();
+
+        u = manager_get_unit(m, e);
+
+        if (u &&
+            SWAP(u)->from_proc_swaps &&
+            !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
+                return -EEXIST;
+
+        if (!u) {
+                delete = true;
+
+                u = unit_new(m, sizeof(Swap));
+                if (!u)
+                        return log_oom();
+
+                r = unit_add_name(u, e);
+                if (r < 0)
+                        goto fail;
+
+                SWAP(u)->what = strdup(what);
+                if (!SWAP(u)->what) {
+                        r = log_oom();
+                        goto fail;
+                }
+
+                unit_add_to_load_queue(u);
+        } else
+                delete = false;
+
+        p = &SWAP(u)->parameters_proc_swaps;
+
+        if (!p->what) {
+                wp = strdup(what_proc_swaps);
+                if (!wp) {
+                        r = log_oom();
+                        goto fail;
+                }
+
+                if (!m->swaps_by_proc_swaps) {
+                        m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
+                        if (!m->swaps_by_proc_swaps) {
+                                r = log_oom();
+                                goto fail;
+                        }
+                }
+
+                free(p->what);
+                p->what = wp;
+
+                first = hashmap_get(m->swaps_by_proc_swaps, wp);
+                LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
+
+                r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
+                if (r < 0)
+                        goto fail;
+        }
+
+        if (set_flags) {
+                SWAP(u)->is_active = true;
+                SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
+        }
+
+        SWAP(u)->from_proc_swaps = true;
+
+        p->priority = priority;
+        p->noauto = noauto;
+        p->nofail = nofail;
+
+        unit_add_to_dbus_queue(u);
+
+        return 0;
+
+fail:
+        log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
+
+        free(wp);
+
+        if (delete && u)
+                unit_free(u);
+
+        return r;
+}
+
+static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
+        struct stat st;
+        int r = 0, k;
+
+        assert(m);
+
+        if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
+                struct udev_device *d;
+                const char *dn;
+                struct udev_list_entry *item = NULL, *first = NULL;
+
+                /* So this is a proper swap device. Create swap units
+                 * for all names this swap device is known under */
+
+                d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
+                if (!d)
+                        return log_oom();
+
+                dn = udev_device_get_devnode(d);
+                /* Skip dn==device, since that case will be handled below */
+                if (dn && !streq(dn, device))
+                        r = swap_add_one(m, dn, device, prio, false, false, set_flags);
+
+                /* Add additional units for all symlinks */
+                first = udev_device_get_devlinks_list_entry(d);
+                udev_list_entry_foreach(item, first) {
+                        const char *p;
+
+                        /* Don't bother with the /dev/block links */
+                        p = udev_list_entry_get_name(item);
+
+                        if (path_startswith(p, "/dev/block/"))
+                                continue;
+
+                        if (stat(p, &st) >= 0)
+                                if ((!S_ISBLK(st.st_mode)) ||
+                                    st.st_rdev != udev_device_get_devnum(d))
+                                        continue;
+
+                        k = swap_add_one(m, p, device, prio, false, false, set_flags);
+                        if (k < 0)
+                                r = k;
+                }
+
+                udev_device_unref(d);
+        }
+
+        k = swap_add_one(m, device, device, prio, false, false, set_flags);
+        if (k < 0)
+                r = k;
+
+        return r;
+}
+
+static void swap_set_state(Swap *s, SwapState state) {
+        SwapState old_state;
+
+        assert(s);
+
+        old_state = s->state;
+        s->state = state;
+
+        if (state != SWAP_ACTIVATING &&
+            state != SWAP_ACTIVATING_SIGTERM &&
+            state != SWAP_ACTIVATING_SIGKILL &&
+            state != SWAP_DEACTIVATING &&
+            state != SWAP_DEACTIVATING_SIGTERM &&
+            state != SWAP_DEACTIVATING_SIGKILL) {
+                unit_unwatch_timer(UNIT(s), &s->timer_watch);
+                swap_unwatch_control_pid(s);
+                s->control_command = NULL;
+                s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
+        }
+
+        if (state != old_state)
+                log_debug_unit(UNIT(s)->id,
+                               "%s changed %s -> %s",
+                               UNIT(s)->id,
+                               swap_state_to_string(old_state),
+                               swap_state_to_string(state));
+
+        unit_notify(UNIT(s), state_translation_table[old_state],
+                    state_translation_table[state], true);
+}
+
+static int swap_coldplug(Unit *u) {
+        Swap *s = SWAP(u);
+        SwapState new_state = SWAP_DEAD;
+        int r;
+
+        assert(s);
+        assert(s->state == SWAP_DEAD);
+
+        if (s->deserialized_state != s->state)
+                new_state = s->deserialized_state;
+        else if (s->from_proc_swaps)
+                new_state = SWAP_ACTIVE;
+
+        if (new_state != s->state) {
+
+                if (new_state == SWAP_ACTIVATING ||
+                    new_state == SWAP_ACTIVATING_SIGTERM ||
+                    new_state == SWAP_ACTIVATING_SIGKILL ||
+                    new_state == SWAP_DEACTIVATING ||
+                    new_state == SWAP_DEACTIVATING_SIGTERM ||
+                    new_state == SWAP_DEACTIVATING_SIGKILL) {
+
+                        if (s->control_pid <= 0)
+                                return -EBADMSG;
+
+                        r = unit_watch_pid(UNIT(s), s->control_pid);
+                        if (r < 0)
+                                return r;
+
+                        r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
+                        if (r < 0)
+                                return r;
+                }
+
+                swap_set_state(s, new_state);
+        }
+
+        return 0;
+}
+
+static void swap_dump(Unit *u, FILE *f, const char *prefix) {
+        Swap *s = SWAP(u);
+        SwapParameters *p;
+
+        assert(s);
+        assert(f);
+
+        if (s->from_proc_swaps)
+                p = &s->parameters_proc_swaps;
+        else if (s->from_fragment)
+                p = &s->parameters_fragment;
+        else
+                p = NULL;
+
+        fprintf(f,
+                "%sSwap State: %s\n"
+                "%sResult: %s\n"
+                "%sWhat: %s\n"
+                "%sFrom /proc/swaps: %s\n"
+                "%sFrom fragment: %s\n",
+                prefix, swap_state_to_string(s->state),
+                prefix, swap_result_to_string(s->result),
+                prefix, s->what,
+                prefix, yes_no(s->from_proc_swaps),
+                prefix, yes_no(s->from_fragment));
+
+        if (p)
+                fprintf(f,
+                        "%sPriority: %i\n"
+                        "%sNoAuto: %s\n"
+                        "%sNoFail: %s\n",
+                        prefix, p->priority,
+                        prefix, yes_no(p->noauto),
+                        prefix, yes_no(p->nofail));
+
+        if (s->control_pid > 0)
+                fprintf(f,
+                        "%sControl PID: %lu\n",
+                        prefix, (unsigned long) s->control_pid);
+
+        exec_context_dump(&s->exec_context, f, prefix);
+        kill_context_dump(&s->kill_context, f, prefix);
+}
+
+static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
+        pid_t pid;
+        int r;
+
+        assert(s);
+        assert(c);
+        assert(_pid);
+
+        r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
+        if (r < 0)
+                goto fail;
+
+        r = exec_spawn(c,
+                       NULL,
+                       &s->exec_context,
+                       NULL, 0,
+                       UNIT(s)->manager->environment,
+                       true,
+                       true,
+                       true,
+                       UNIT(s)->manager->confirm_spawn,
+                       UNIT(s)->cgroup_bondings,
+                       UNIT(s)->cgroup_attributes,
+                       NULL,
+                       UNIT(s)->id,
+                       NULL,
+                       &pid);
+        if (r < 0)
+                goto fail;
+
+        r = unit_watch_pid(UNIT(s), pid);
+        if (r < 0)
+                /* FIXME: we need to do something here */
+                goto fail;
+
+        *_pid = pid;
+
+        return 0;
+
+fail:
+        unit_unwatch_timer(UNIT(s), &s->timer_watch);
+
+        return r;
+}
+
+static void swap_enter_dead(Swap *s, SwapResult f) {
+        assert(s);
+
+        if (f != SWAP_SUCCESS)
+                s->result = f;
+
+        swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
+}
+
+static void swap_enter_active(Swap *s, SwapResult f) {
+        assert(s);
+
+        if (f != SWAP_SUCCESS)
+                s->result = f;
+
+        swap_set_state(s, SWAP_ACTIVE);
+}
+
+static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
+        int r;
+        Set *pid_set = NULL;
+        bool wait_for_exit = false;
+
+        assert(s);
+
+        if (f != SWAP_SUCCESS)
+                s->result = f;
+
+        if (s->kill_context.kill_mode != KILL_NONE) {
+                int sig = (state == SWAP_ACTIVATING_SIGTERM ||
+                           state == SWAP_DEACTIVATING_SIGTERM) ? s->kill_context.kill_signal : SIGKILL;
+
+                if (s->control_pid > 0) {
+                        if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
+
+                                log_warning_unit(UNIT(s)->id,
+                                                 "Failed to kill control process %li: %m",
+                                                 (long) s->control_pid);
+                        else
+                                wait_for_exit = true;
+                }
+
+                if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) {
+
+                        pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                        if (!pid_set) {
+                                r = log_oom();
+                                goto fail;
+                        }
+
+                        /* Exclude the control pid from being killed via the cgroup */
+                        if (s->control_pid > 0) {
+                                r = set_put(pid_set, LONG_TO_PTR(s->control_pid));
+                                if (r < 0)
+                                        goto fail;
+                        }
+
+                        r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
+                        if (r < 0) {
+                                if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
+                                        log_warning_unit(UNIT(s)->id,
+                                                         "Failed to kill control group: %s", strerror(-r));
+                        } else if (r > 0)
+                                wait_for_exit = true;
+
+                        set_free(pid_set);
+                        pid_set = NULL;
+                }
+        }
+
+        if (wait_for_exit) {
+                r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
+                if (r < 0)
+                        goto fail;
+
+                swap_set_state(s, state);
+        } else
+                swap_enter_dead(s, SWAP_SUCCESS);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
+
+        swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
+
+        if (pid_set)
+                set_free(pid_set);
+}
+
+static void swap_enter_activating(Swap *s) {
+        int r, priority;
+
+        assert(s);
+
+        s->control_command_id = SWAP_EXEC_ACTIVATE;
+        s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
+
+        if (s->from_fragment)
+                priority = s->parameters_fragment.priority;
+        else
+                priority = -1;
+
+        if (priority >= 0) {
+                char p[LINE_MAX];
+
+                snprintf(p, sizeof(p), "%i", priority);
+                char_array_0(p);
+
+                r = exec_command_set(
+                                s->control_command,
+                                "/sbin/swapon",
+                                "-p",
+                                p,
+                                s->what,
+                                NULL);
+        } else
+                r = exec_command_set(
+                                s->control_command,
+                                "/sbin/swapon",
+                                s->what,
+                                NULL);
+
+        if (r < 0)
+                goto fail;
+
+        swap_unwatch_control_pid(s);
+
+        r = swap_spawn(s, s->control_command, &s->control_pid);
+        if (r < 0)
+                goto fail;
+
+        swap_set_state(s, SWAP_ACTIVATING);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'swapon' task: %s",
+                         UNIT(s)->id, strerror(-r));
+        swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
+}
+
+static void swap_enter_deactivating(Swap *s) {
+        int r;
+
+        assert(s);
+
+        s->control_command_id = SWAP_EXEC_DEACTIVATE;
+        s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
+
+        r = exec_command_set(s->control_command,
+                             "/sbin/swapoff",
+                             s->what,
+                             NULL);
+        if (r < 0)
+                goto fail;
+
+        swap_unwatch_control_pid(s);
+
+        r = swap_spawn(s, s->control_command, &s->control_pid);
+        if (r < 0)
+                goto fail;
+
+        swap_set_state(s, SWAP_DEACTIVATING);
+
+        return;
+
+fail:
+        log_warning_unit(UNIT(s)->id,
+                         "%s failed to run 'swapoff' task: %s",
+                         UNIT(s)->id, strerror(-r));
+        swap_enter_active(s, SWAP_FAILURE_RESOURCES);
+}
+
+static int swap_start(Unit *u) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+
+        /* We cannot fulfill this request right now, try again later
+         * please! */
+
+        if (s->state == SWAP_DEACTIVATING ||
+            s->state == SWAP_DEACTIVATING_SIGTERM ||
+            s->state == SWAP_DEACTIVATING_SIGKILL ||
+            s->state == SWAP_ACTIVATING_SIGTERM ||
+            s->state == SWAP_ACTIVATING_SIGKILL)
+                return -EAGAIN;
+
+        if (s->state == SWAP_ACTIVATING)
+                return 0;
+
+        assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
+
+        if (detect_container(NULL) > 0)
+                return -EPERM;
+
+        s->result = SWAP_SUCCESS;
+        swap_enter_activating(s);
+        return 0;
+}
+
+static int swap_stop(Unit *u) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+
+        if (s->state == SWAP_DEACTIVATING ||
+            s->state == SWAP_DEACTIVATING_SIGTERM ||
+            s->state == SWAP_DEACTIVATING_SIGKILL ||
+            s->state == SWAP_ACTIVATING_SIGTERM ||
+            s->state == SWAP_ACTIVATING_SIGKILL)
+                return 0;
+
+        assert(s->state == SWAP_ACTIVATING ||
+               s->state == SWAP_ACTIVE);
+
+        if (detect_container(NULL) > 0)
+                return -EPERM;
+
+        swap_enter_deactivating(s);
+        return 0;
+}
+
+static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
+        unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
+
+        if (s->control_pid > 0)
+                unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
+
+        if (s->control_command_id >= 0)
+                unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
+
+        return 0;
+}
+
+static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                SwapState state;
+
+                state = swap_state_from_string(value);
+                if (state < 0)
+                        log_debug_unit(u->id, "Failed to parse state value %s", value);
+                else
+                        s->deserialized_state = state;
+        } else if (streq(key, "result")) {
+                SwapResult f;
+
+                f = swap_result_from_string(value);
+                if (f < 0)
+                        log_debug_unit(u->id, "Failed to parse result value %s", value);
+                else if (f != SWAP_SUCCESS)
+                        s->result = f;
+        } else if (streq(key, "control-pid")) {
+                pid_t pid;
+
+                if (parse_pid(value, &pid) < 0)
+                        log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
+                else
+                        s->control_pid = pid;
+
+        } else if (streq(key, "control-command")) {
+                SwapExecCommand id;
+
+                id = swap_exec_command_from_string(value);
+                if (id < 0)
+                        log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
+                else {
+                        s->control_command_id = id;
+                        s->control_command = s->exec_command + id;
+                }
+
+        } else
+                log_debug_unit(u->id, "Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static UnitActiveState swap_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[SWAP(u)->state];
+}
+
+static const char *swap_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return swap_state_to_string(SWAP(u)->state);
+}
+
+static bool swap_check_gc(Unit *u) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+
+        return s->from_proc_swaps;
+}
+
+static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+        Swap *s = SWAP(u);
+        SwapResult f;
+
+        assert(s);
+        assert(pid >= 0);
+
+        if (pid != s->control_pid)
+                return;
+
+        s->control_pid = 0;
+
+        if (is_clean_exit(code, status, NULL))
+                f = SWAP_SUCCESS;
+        else if (code == CLD_EXITED)
+                f = SWAP_FAILURE_EXIT_CODE;
+        else if (code == CLD_KILLED)
+                f = SWAP_FAILURE_SIGNAL;
+        else if (code == CLD_DUMPED)
+                f = SWAP_FAILURE_CORE_DUMP;
+        else
+                assert_not_reached("Unknown code");
+
+        if (f != SWAP_SUCCESS)
+                s->result = f;
+
+        if (s->control_command) {
+                exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
+
+                s->control_command = NULL;
+                s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
+        }
+
+        log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+                      u->id,
+                      "%s swap process exited, code=%s status=%i",
+                      u->id, sigchld_code_to_string(code), status);
+
+        switch (s->state) {
+
+        case SWAP_ACTIVATING:
+        case SWAP_ACTIVATING_SIGTERM:
+        case SWAP_ACTIVATING_SIGKILL:
+
+                if (f == SWAP_SUCCESS)
+                        swap_enter_active(s, f);
+                else
+                        swap_enter_dead(s, f);
+                break;
+
+        case SWAP_DEACTIVATING:
+        case SWAP_DEACTIVATING_SIGKILL:
+        case SWAP_DEACTIVATING_SIGTERM:
+
+                if (f == SWAP_SUCCESS)
+                        swap_enter_dead(s, f);
+                else
+                        swap_enter_dead(s, f);
+                break;
+
+        default:
+                assert_not_reached("Uh, control process died at wrong time.");
+        }
+
+        /* Notify clients about changed exit status */
+        unit_add_to_dbus_queue(u);
+
+        /* Request a reload of /proc/swaps, so that following units
+         * can follow our state change */
+        u->manager->request_reload = true;
+}
+
+static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+        assert(elapsed == 1);
+        assert(w == &s->timer_watch);
+
+        switch (s->state) {
+
+        case SWAP_ACTIVATING:
+                log_warning_unit(u->id, "%s activation timed out. Stopping.", u->id);
+                swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
+                break;
+
+        case SWAP_DEACTIVATING:
+                log_warning_unit(u->id, "%s deactivation timed out. Stopping.", u->id);
+                swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
+                break;
+
+        case SWAP_ACTIVATING_SIGTERM:
+                if (s->kill_context.send_sigkill) {
+                        log_warning_unit(u->id, "%s activation timed out. Killing.", u->id);
+                        swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
+                        swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
+                }
+                break;
+
+        case SWAP_DEACTIVATING_SIGTERM:
+                if (s->kill_context.send_sigkill) {
+                        log_warning_unit(u->id, "%s deactivation timed out. Killing.", u->id);
+                        swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
+                } else {
+                        log_warning_unit(u->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
+                        swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
+                }
+                break;
+
+        case SWAP_ACTIVATING_SIGKILL:
+        case SWAP_DEACTIVATING_SIGKILL:
+                log_warning_unit(u->id, "%s swap process still around after SIGKILL. Ignoring.", u->id);
+                swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
+                break;
+
+        default:
+                assert_not_reached("Timeout at wrong time.");
+        }
+}
+
+static int swap_load_proc_swaps(Manager *m, bool set_flags) {
+        unsigned i;
+        int r = 0;
+
+        assert(m);
+
+        rewind(m->proc_swaps);
+
+        (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
+
+        for (i = 1;; i++) {
+                char *dev = NULL, *d;
+                int prio = 0, k;
+
+                k = fscanf(m->proc_swaps,
+                           "%ms "  /* device/file */
+                           "%*s "  /* type of swap */
+                           "%*s "  /* swap size */
+                           "%*s "  /* used */
+                           "%i\n", /* priority */
+                           &dev, &prio);
+                if (k != 2) {
+                        if (k == EOF)
+                                break;
+
+                        log_warning("Failed to parse /proc/swaps:%u", i);
+                        free(dev);
+                        continue;
+                }
+
+                d = cunescape(dev);
+                free(dev);
+
+                if (!d)
+                        return -ENOMEM;
+
+                k = swap_process_new_swap(m, d, prio, set_flags);
+                free(d);
+
+                if (k < 0)
+                        r = k;
+        }
+
+        return r;
+}
+
+int swap_dispatch_reload(Manager *m) {
+        /* This function should go as soon as the kernel properly notifies us */
+
+        if (_likely_(!m->request_reload))
+                return 0;
+
+        m->request_reload = false;
+
+        return swap_fd_event(m, EPOLLPRI);
+}
+
+int swap_fd_event(Manager *m, int events) {
+        Unit *u;
+        int r;
+
+        assert(m);
+        assert(events & EPOLLPRI);
+
+        r = swap_load_proc_swaps(m, true);
+        if (r < 0) {
+                log_error("Failed to reread /proc/swaps: %s", strerror(-r));
+
+                /* Reset flags, just in case, for late calls */
+                LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
+                        Swap *swap = SWAP(u);
+
+                        swap->is_active = swap->just_activated = false;
+                }
+
+                return 0;
+        }
+
+        manager_dispatch_load_queue(m);
+
+        LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
+                Swap *swap = SWAP(u);
+
+                if (!swap->is_active) {
+                        /* This has just been deactivated */
+
+                        swap->from_proc_swaps = false;
+                        swap_unset_proc_swaps(swap);
+
+                        switch (swap->state) {
+
+                        case SWAP_ACTIVE:
+                                swap_enter_dead(swap, SWAP_SUCCESS);
+                                break;
+
+                        default:
+                                swap_set_state(swap, swap->state);
+                                break;
+                        }
+
+                } else if (swap->just_activated) {
+
+                        /* New swap entry */
+
+                        switch (swap->state) {
+
+                        case SWAP_DEAD:
+                        case SWAP_FAILED:
+                                swap_enter_active(swap, SWAP_SUCCESS);
+                                break;
+
+                        default:
+                                /* Nothing really changed, but let's
+                                 * issue an notification call
+                                 * nonetheless, in case somebody is
+                                 * waiting for this. */
+                                swap_set_state(swap, swap->state);
+                                break;
+                        }
+                }
+
+                /* Reset the flags for later calls */
+                swap->is_active = swap->just_activated = false;
+        }
+
+        return 1;
+}
+
+static Unit *swap_following(Unit *u) {
+        Swap *s = SWAP(u);
+        Swap *other, *first = NULL;
+
+        assert(s);
+
+        if (streq_ptr(s->what, s->parameters_proc_swaps.what))
+                return NULL;
+
+        /* Make everybody follow the unit that's named after the swap
+         * device in the kernel */
+
+        LIST_FOREACH_AFTER(same_proc_swaps, other, s)
+                if (streq_ptr(other->what, other->parameters_proc_swaps.what))
+                        return UNIT(other);
+
+        LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
+                if (streq_ptr(other->what, other->parameters_proc_swaps.what))
+                        return UNIT(other);
+
+                first = other;
+        }
+
+        return UNIT(first);
+}
+
+static int swap_following_set(Unit *u, Set **_set) {
+        Swap *s = SWAP(u);
+        Swap *other;
+        Set *set;
+        int r;
+
+        assert(s);
+        assert(_set);
+
+        if (LIST_JUST_US(same_proc_swaps, s)) {
+                *_set = NULL;
+                return 0;
+        }
+
+        if (!(set = set_new(NULL, NULL)))
+                return -ENOMEM;
+
+        LIST_FOREACH_AFTER(same_proc_swaps, other, s)
+                if ((r = set_put(set, other)) < 0)
+                        goto fail;
+
+        LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
+                if ((r = set_put(set, other)) < 0)
+                        goto fail;
+
+        *_set = set;
+        return 1;
+
+fail:
+        set_free(set);
+        return r;
+}
+
+static void swap_shutdown(Manager *m) {
+        assert(m);
+
+        if (m->proc_swaps) {
+                fclose(m->proc_swaps);
+                m->proc_swaps = NULL;
+        }
+
+        hashmap_free(m->swaps_by_proc_swaps);
+        m->swaps_by_proc_swaps = NULL;
+}
+
+static int swap_enumerate(Manager *m) {
+        int r;
+        struct epoll_event ev;
+        assert(m);
+
+        if (!m->proc_swaps) {
+                m->proc_swaps = fopen("/proc/swaps", "re");
+                if (!m->proc_swaps)
+                        return (errno == ENOENT) ? 0 : -errno;
+
+                m->swap_watch.type = WATCH_SWAP;
+                m->swap_watch.fd = fileno(m->proc_swaps);
+
+                zero(ev);
+                ev.events = EPOLLPRI;
+                ev.data.ptr = &m->swap_watch;
+
+                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
+                        return -errno;
+        }
+
+        r = swap_load_proc_swaps(m, false);
+        if (r < 0)
+                swap_shutdown(m);
+
+        return r;
+}
+
+static void swap_reset_failed(Unit *u) {
+        Swap *s = SWAP(u);
+
+        assert(s);
+
+        if (s->state == SWAP_FAILED)
+                swap_set_state(s, SWAP_DEAD);
+
+        s->result = SWAP_SUCCESS;
+}
+
+static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
+        Swap *s = SWAP(u);
+        int r = 0;
+        Set *pid_set = NULL;
+
+        assert(s);
+
+        if (who == KILL_MAIN) {
+                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
+                return -ESRCH;
+        }
+
+        if (s->control_pid <= 0 && who == KILL_CONTROL) {
+                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
+                return -ESRCH;
+        }
+
+        if (who == KILL_CONTROL || who == KILL_ALL)
+                if (s->control_pid > 0)
+                        if (kill(s->control_pid, signo) < 0)
+                                r = -errno;
+
+        if (who == KILL_ALL) {
+                int q;
+
+                pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!pid_set)
+                        return -ENOMEM;
+
+                /* Exclude the control pid from being killed via the cgroup */
+                if (s->control_pid > 0) {
+                        q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
+                        if (q < 0) {
+                                r = q;
+                                goto finish;
+                        }
+                }
+
+                q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
+                if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
+                        r = q;
+        }
+
+finish:
+        if (pid_set)
+                set_free(pid_set);
+
+        return r;
+}
+
+static const char* const swap_state_table[_SWAP_STATE_MAX] = {
+        [SWAP_DEAD] = "dead",
+        [SWAP_ACTIVATING] = "activating",
+        [SWAP_ACTIVE] = "active",
+        [SWAP_DEACTIVATING] = "deactivating",
+        [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
+        [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
+        [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
+        [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
+        [SWAP_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
+
+static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
+        [SWAP_EXEC_ACTIVATE] = "ExecActivate",
+        [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
+
+static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
+        [SWAP_SUCCESS] = "success",
+        [SWAP_FAILURE_RESOURCES] = "resources",
+        [SWAP_FAILURE_TIMEOUT] = "timeout",
+        [SWAP_FAILURE_EXIT_CODE] = "exit-code",
+        [SWAP_FAILURE_SIGNAL] = "signal",
+        [SWAP_FAILURE_CORE_DUMP] = "core-dump"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
+
+const UnitVTable swap_vtable = {
+        .object_size = sizeof(Swap),
+        .exec_context_offset = offsetof(Swap, exec_context),
+
+        .sections =
+                "Unit\0"
+                "Swap\0"
+                "Install\0",
+
+        .no_alias = true,
+        .no_instances = true,
+
+        .init = swap_init,
+        .load = swap_load,
+        .done = swap_done,
+
+        .coldplug = swap_coldplug,
+
+        .dump = swap_dump,
+
+        .start = swap_start,
+        .stop = swap_stop,
+
+        .kill = swap_kill,
+
+        .serialize = swap_serialize,
+        .deserialize_item = swap_deserialize_item,
+
+        .active_state = swap_active_state,
+        .sub_state_to_string = swap_sub_state_to_string,
+
+        .check_gc = swap_check_gc,
+
+        .sigchld_event = swap_sigchld_event,
+        .timer_event = swap_timer_event,
+
+        .reset_failed = swap_reset_failed,
+
+        .bus_interface = "org.freedesktop.systemd1.Swap",
+        .bus_message_handler = bus_swap_message_handler,
+        .bus_invalidating_properties =  bus_swap_invalidating_properties,
+
+        .following = swap_following,
+        .following_set = swap_following_set,
+
+        .enumerate = swap_enumerate,
+        .shutdown = swap_shutdown,
+
+        .status_message_formats = {
+                .starting_stopping = {
+                        [0] = "Activating swap %s...",
+                        [1] = "Deactivating swap %s...",
+                },
+                .finished_start_job = {
+                        [JOB_DONE]       = "Activated swap %s.",
+                        [JOB_FAILED]     = "Failed to activate swap %s.",
+                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                        [JOB_TIMEOUT]    = "Timed out activating swap %s.",
+                },
+                .finished_stop_job = {
+                        [JOB_DONE]       = "Deactivated swap %s.",
+                        [JOB_FAILED]     = "Failed deactivating swap %s.",
+                        [JOB_TIMEOUT]    = "Timed out deactivating swap %s.",
+                },
+        },
+};
diff --git a/src/core/swap.h b/src/core/swap.h
new file mode 100644 (file)
index 0000000..35d47fd
--- /dev/null
@@ -0,0 +1,121 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright 2010 Maarten Lankhorst
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Swap Swap;
+
+#include "unit.h"
+
+typedef enum SwapState {
+        SWAP_DEAD,
+        SWAP_ACTIVATING,
+        SWAP_ACTIVE,
+        SWAP_DEACTIVATING,
+        SWAP_ACTIVATING_SIGTERM,
+        SWAP_ACTIVATING_SIGKILL,
+        SWAP_DEACTIVATING_SIGTERM,
+        SWAP_DEACTIVATING_SIGKILL,
+        SWAP_FAILED,
+        _SWAP_STATE_MAX,
+        _SWAP_STATE_INVALID = -1
+} SwapState;
+
+typedef enum SwapExecCommand {
+        SWAP_EXEC_ACTIVATE,
+        SWAP_EXEC_DEACTIVATE,
+        _SWAP_EXEC_COMMAND_MAX,
+        _SWAP_EXEC_COMMAND_INVALID = -1
+} SwapExecCommand;
+
+typedef struct SwapParameters {
+        char *what;
+        int priority;
+        bool noauto:1;
+        bool nofail:1;
+} SwapParameters;
+
+typedef enum SwapResult {
+        SWAP_SUCCESS,
+        SWAP_FAILURE_RESOURCES,
+        SWAP_FAILURE_TIMEOUT,
+        SWAP_FAILURE_EXIT_CODE,
+        SWAP_FAILURE_SIGNAL,
+        SWAP_FAILURE_CORE_DUMP,
+        _SWAP_RESULT_MAX,
+        _SWAP_RESULT_INVALID = -1
+} SwapResult;
+
+struct Swap {
+        Unit meta;
+
+        char *what;
+
+        SwapParameters parameters_proc_swaps;
+        SwapParameters parameters_fragment;
+
+        bool from_proc_swaps:1;
+        bool from_fragment:1;
+
+        /* Used while looking for swaps that vanished or got added
+         * from/to /proc/swaps */
+        bool is_active:1;
+        bool just_activated:1;
+
+        SwapResult result;
+
+        usec_t timeout_usec;
+
+        ExecCommand exec_command[_SWAP_EXEC_COMMAND_MAX];
+        ExecContext exec_context;
+        KillContext kill_context;
+
+        SwapState state, deserialized_state;
+
+        ExecCommand* control_command;
+        SwapExecCommand control_command_id;
+        pid_t control_pid;
+
+        Watch timer_watch;
+
+        /* In order to be able to distinguish dependencies on
+        different device nodes we might end up creating multiple
+        devices for the same swap. We chain them up here. */
+
+        LIST_FIELDS(struct Swap, same_proc_swaps);
+};
+
+extern const UnitVTable swap_vtable;
+
+int swap_add_one_mount_link(Swap *s, Mount *m);
+
+int swap_dispatch_reload(Manager *m);
+int swap_fd_event(Manager *m, int events);
+
+const char* swap_state_to_string(SwapState i);
+SwapState swap_state_from_string(const char *s);
+
+const char* swap_exec_command_to_string(SwapExecCommand i);
+SwapExecCommand swap_exec_command_from_string(const char *s);
+
+const char* swap_result_to_string(SwapResult i);
+SwapResult swap_result_from_string(const char *s);
diff --git a/src/core/switch-root.c b/src/core/switch-root.c
new file mode 100644 (file)
index 0000000..ce0e41d
--- /dev/null
@@ -0,0 +1,167 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Harald Hoyer, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/stat.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "util.h"
+#include "path-util.h"
+#include "switch-root.h"
+#include "missing.h"
+
+int switch_root(const char *new_root) {
+
+        /*  Don't try to unmount/move the old "/", there's no way to do it. */
+        static const char move_mounts[] =
+                "/dev\0"
+                "/proc\0"
+                "/sys\0"
+                "/run\0";
+
+        int r, old_root_fd = -1;
+        struct stat new_root_stat;
+        bool old_root_remove;
+        const char *i;
+        _cleanup_free_ char *temporary_old_root = NULL;
+
+        if (path_equal(new_root, "/"))
+                return 0;
+
+        /* When using pivot_root() we assume that /mnt exists as place
+         * we can temporarily move the old root to. As we immediately
+         * unmount it from there it doesn't matter much which
+         * directory we choose for this, but it should be more likely
+         * than not that /mnt exists and is suitable as mount point
+         * and is on the same fs as the old root dir */
+        temporary_old_root = strappend(new_root, "/mnt");
+        if (!temporary_old_root)
+                return -ENOMEM;
+
+        old_root_remove = in_initrd();
+
+        if (stat(new_root, &new_root_stat) < 0) {
+                r = -errno;
+                log_error("Failed to stat directory %s: %m", new_root);
+                goto fail;
+        }
+
+        /* Work-around for a kernel bug: for some reason the kernel
+         * refuses switching root if any file systems are mounted
+         * MS_SHARED. Hence remount them MS_PRIVATE here as a
+         * work-around.
+         *
+         * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
+        if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
+                log_warning("Failed to make \"/\" private mount: %m");
+
+        NULSTR_FOREACH(i, move_mounts) {
+                char new_mount[PATH_MAX];
+                struct stat sb;
+
+                snprintf(new_mount, sizeof(new_mount), "%s%s", new_root, i);
+                char_array_0(new_mount);
+
+                if ((stat(new_mount, &sb) < 0) ||
+                    sb.st_dev != new_root_stat.st_dev) {
+
+                        /* Mount point seems to be mounted already or
+                         * stat failed. Unmount the old mount
+                         * point. */
+                        if (umount2(i, MNT_DETACH) < 0)
+                                log_warning("Failed to unmount %s: %m", i);
+                        continue;
+                }
+
+                if (mount(i, new_mount, NULL, MS_MOVE, NULL) < 0) {
+                        log_error("Failed to move mount %s to %s, forcing unmount: %m", i, new_mount);
+
+                        if (umount2(i, MNT_FORCE) < 0)
+                                log_warning("Failed to unmount %s: %m", i);
+                }
+        }
+
+        if (chdir(new_root) < 0) {
+                r = -errno;
+                log_error("Failed to change directory to %s: %m", new_root);
+                goto fail;
+        }
+
+        if (old_root_remove) {
+                old_root_fd = open("/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY|O_DIRECTORY);
+                if (old_root_fd < 0)
+                        log_warning("Failed to open root directory: %m");
+        }
+
+        /* We first try a pivot_root() so that we can umount the old
+         * root dir. In many cases (i.e. where rootfs is /), that's
+         * not possible however, and hence we simply overmount root */
+        if (pivot_root(new_root, temporary_old_root) >= 0) {
+
+                /* Immediately get rid of the old root. Since we are
+                 * running off it we need to do this lazily. */
+                if (umount2(temporary_old_root, MNT_DETACH) < 0) {
+                        r = -errno;
+                        log_error("Failed to umount old root dir %s: %m", temporary_old_root);
+                        goto fail;
+                }
+
+        } else if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0) {
+                r = -errno;
+                log_error("Failed to mount moving %s to /: %m", new_root);
+                goto fail;
+        }
+
+        if (chroot(".") < 0) {
+                r = -errno;
+                log_error("Failed to change root: %m");
+                goto fail;
+        }
+
+        if (chdir("/") < 0) {
+                r = -errno;
+                log_error("Failed to change directory: %m");
+                goto fail;
+        }
+
+        if (old_root_fd >= 0) {
+                struct stat rb;
+
+                if (fstat(old_root_fd, &rb) < 0)
+                        log_warning("Failed to stat old root directory, leaving: %m");
+                else {
+                        rm_rf_children(old_root_fd, false, false, &rb);
+                        old_root_fd = -1;
+                }
+        }
+
+        r = 0;
+
+fail:
+        if (old_root_fd >= 0)
+                close_nointr_nofail(old_root_fd);
+
+        return r;
+}
diff --git a/src/core/switch-root.h b/src/core/switch-root.h
new file mode 100644 (file)
index 0000000..0c4cd1e
--- /dev/null
@@ -0,0 +1,27 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef fooswitchroothfoo
+#define fooswitchroothfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Harald Hoyer, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int switch_root(const char *switch_root);
+
+#endif
diff --git a/src/core/syscall-list.c b/src/core/syscall-list.c
new file mode 100644 (file)
index 0000000..05fad3e
--- /dev/null
@@ -0,0 +1,55 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/syscall.h>
+#include <string.h>
+
+#include "util.h"
+
+#include "syscall-list.h"
+
+const struct syscall_name *lookup_syscall(register const char *str, register unsigned int len);
+
+#include "syscall-to-name.h"
+#include "syscall-from-name.h"
+
+const char *syscall_to_name(int id) {
+        if (id < 0 || id >= (int) ELEMENTSOF(syscall_names))
+                return NULL;
+
+        return syscall_names[id];
+}
+
+int syscall_from_name(const char *name) {
+        const struct syscall_name *sc;
+
+        assert(name);
+
+        sc = lookup_syscall(name, strlen(name));
+        if (!sc)
+                return -1;
+
+        return sc->id;
+}
+
+int syscall_max(void) {
+        return ELEMENTSOF(syscall_names);
+}
diff --git a/src/core/syscall-list.h b/src/core/syscall-list.h
new file mode 100644 (file)
index 0000000..0fc6859
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosyscalllisthfoo
+#define foosyscalllisthfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+const char *syscall_to_name(int id);
+int syscall_from_name(const char *name);
+
+int syscall_max(void);
+
+#endif
diff --git a/src/core/sysfs-show.h b/src/core/sysfs-show.h
new file mode 100644 (file)
index 0000000..9ffd129
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int show_sysfs(const char *seat, const char *prefix, unsigned columns);
diff --git a/src/core/system.conf b/src/core/system.conf
new file mode 100644 (file)
index 0000000..68076d9
--- /dev/null
@@ -0,0 +1,43 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+# See systemd.conf(5) for details
+
+[Manager]
+#LogLevel=info
+#LogTarget=journal-or-kmsg
+#LogColor=yes
+#LogLocation=no
+#DumpCore=yes
+#CrashShell=no
+#ShowStatus=yes
+#CrashChVT=1
+#CPUAffinity=1 2
+#DefaultControllers=cpu
+#DefaultStandardOutput=journal
+#DefaultStandardError=inherit
+#JoinControllers=cpu,cpuacct,cpuset net_cls,net_prio
+#RuntimeWatchdogSec=0
+#ShutdownWatchdogSec=10min
+#CapabilityBoundingSet=
+#TimerSlackNSec=
+#DefaultLimitCPU=
+#DefaultLimitFSIZE=
+#DefaultLimitDATA=
+#DefaultLimitSTACK=
+#DefaultLimitCORE=
+#DefaultLimitRSS=
+#DefaultLimitNOFILE=
+#DefaultLimitAS=
+#DefaultLimitNPROC=
+#DefaultLimitMEMLOCK=
+#DefaultLimitLOCKS=
+#DefaultLimitSIGPENDING=
+#DefaultLimitMSGQUEUE=
+#DefaultLimitNICE=
+#DefaultLimitRTPRIO=
+#DefaultLimitRTTIME=
diff --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in
new file mode 100644 (file)
index 0000000..2f49d5d
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+systemdutildir=@rootlibexecdir@
+systemdsystemunitdir=@systemunitdir@
+systemdsystempresetdir=@systempresetdir@
+systemduserunitdir=@userunitdir@
+systemduserpresetdir=@userpresetdir@
+systemdsystemconfdir=@pkgsysconfdir@/system
+systemduserconfdir=@pkgsysconfdir@/user
+systemdsystemunitpath=${systemdsystemconfdir}:/etc/systemd/system:/run/systemd/system:/usr/local/lib/systemd/system:${systemdsystemunitdir}:/usr/lib/systemd/system:/lib/systemd/system
+systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/run/systemd/user:/usr/local/lib/systemd/user:/usr/local/share/systemd/user:${systemduserunitdir}:/usr/lib/systemd/user:/usr/share/systemd/user
+
+Name: systemd
+Description: systemd System and Service Manager
+URL: @PACKAGE_URL@
+Version: @PACKAGE_VERSION@
diff --git a/src/core/target.c b/src/core/target.c
new file mode 100644 (file)
index 0000000..9814241
--- /dev/null
@@ -0,0 +1,239 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "unit.h"
+#include "target.h"
+#include "load-fragment.h"
+#include "log.h"
+#include "dbus-target.h"
+#include "special.h"
+#include "unit-name.h"
+
+static const UnitActiveState state_translation_table[_TARGET_STATE_MAX] = {
+        [TARGET_DEAD] = UNIT_INACTIVE,
+        [TARGET_ACTIVE] = UNIT_ACTIVE
+};
+
+static void target_set_state(Target *t, TargetState state) {
+        TargetState old_state;
+        assert(t);
+
+        old_state = t->state;
+        t->state = state;
+
+        if (state != old_state)
+                log_debug("%s changed %s -> %s",
+                          UNIT(t)->id,
+                          target_state_to_string(old_state),
+                          target_state_to_string(state));
+
+        unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true);
+}
+
+static int target_add_default_dependencies(Target *t) {
+
+        static const UnitDependency deps[] = {
+                UNIT_REQUIRES,
+                UNIT_REQUIRES_OVERRIDABLE,
+                UNIT_REQUISITE,
+                UNIT_REQUISITE_OVERRIDABLE,
+                UNIT_WANTS,
+                UNIT_BINDS_TO,
+                UNIT_PART_OF
+        };
+
+        Iterator i;
+        Unit *other;
+        int r;
+        unsigned k;
+
+        assert(t);
+
+        /* Imply ordering for requirement dependencies on target
+         * units. Note that when the user created a contradicting
+         * ordering manually we won't add anything in here to make
+         * sure we don't create a loop. */
+
+        for (k = 0; k < ELEMENTSOF(deps); k++)
+                SET_FOREACH(other, UNIT(t)->dependencies[deps[k]], i) {
+                        r = unit_add_default_target_dependency(other, UNIT(t));
+                        if (r < 0)
+                                return r;
+                }
+
+        /* Make sure targets are unloaded on shutdown */
+        return unit_add_dependency_by_name(UNIT(t), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+}
+
+static int target_load(Unit *u) {
+        Target *t = TARGET(u);
+        int r;
+
+        assert(t);
+
+        r = unit_load_fragment_and_dropin(u);
+        if (r < 0)
+                return r;
+
+        /* This is a new unit? Then let's add in some extras */
+        if (u->load_state == UNIT_LOADED && u->default_dependencies) {
+                r = target_add_default_dependencies(t);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int target_coldplug(Unit *u) {
+        Target *t = TARGET(u);
+
+        assert(t);
+        assert(t->state == TARGET_DEAD);
+
+        if (t->deserialized_state != t->state)
+                target_set_state(t, t->deserialized_state);
+
+        return 0;
+}
+
+static void target_dump(Unit *u, FILE *f, const char *prefix) {
+        Target *t = TARGET(u);
+
+        assert(t);
+        assert(f);
+
+        fprintf(f,
+                "%sTarget State: %s\n",
+                prefix, target_state_to_string(t->state));
+}
+
+static int target_start(Unit *u) {
+        Target *t = TARGET(u);
+
+        assert(t);
+        assert(t->state == TARGET_DEAD);
+
+        target_set_state(t, TARGET_ACTIVE);
+        return 0;
+}
+
+static int target_stop(Unit *u) {
+        Target *t = TARGET(u);
+
+        assert(t);
+        assert(t->state == TARGET_ACTIVE);
+
+        target_set_state(t, TARGET_DEAD);
+        return 0;
+}
+
+static int target_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Target *s = TARGET(u);
+
+        assert(s);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", target_state_to_string(s->state));
+        return 0;
+}
+
+static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Target *s = TARGET(u);
+
+        assert(u);
+        assert(key);
+        assert(value);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                TargetState state;
+
+                state = target_state_from_string(value);
+                if (state < 0)
+                        log_debug("Failed to parse state value %s", value);
+                else
+                        s->deserialized_state = state;
+
+        } else
+                log_debug("Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static UnitActiveState target_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[TARGET(u)->state];
+}
+
+static const char *target_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return target_state_to_string(TARGET(u)->state);
+}
+
+static const char* const target_state_table[_TARGET_STATE_MAX] = {
+        [TARGET_DEAD] = "dead",
+        [TARGET_ACTIVE] = "active"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(target_state, TargetState);
+
+const UnitVTable target_vtable = {
+        .object_size = sizeof(Target),
+        .sections =
+                "Unit\0"
+                "Target\0"
+                "Install\0",
+
+        .load = target_load,
+        .coldplug = target_coldplug,
+
+        .dump = target_dump,
+
+        .start = target_start,
+        .stop = target_stop,
+
+        .serialize = target_serialize,
+        .deserialize_item = target_deserialize_item,
+
+        .active_state = target_active_state,
+        .sub_state_to_string = target_sub_state_to_string,
+
+        .bus_interface = "org.freedesktop.systemd1.Target",
+        .bus_message_handler = bus_target_message_handler,
+
+        .status_message_formats = {
+                .finished_start_job = {
+                        [JOB_DONE]       = "Reached target %s.",
+                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                },
+                .finished_stop_job = {
+                        [JOB_DONE]       = "Stopped target %s.",
+                },
+        },
+};
diff --git a/src/core/target.h b/src/core/target.h
new file mode 100644 (file)
index 0000000..1676553
--- /dev/null
@@ -0,0 +1,44 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Target Target;
+
+#include "unit.h"
+
+typedef enum TargetState {
+        TARGET_DEAD,
+        TARGET_ACTIVE,
+        _TARGET_STATE_MAX,
+        _TARGET_STATE_INVALID = -1
+} TargetState;
+
+struct Target {
+        Unit meta;
+
+        TargetState state, deserialized_state;
+};
+
+extern const UnitVTable target_vtable;
+
+const char* target_state_to_string(TargetState i);
+TargetState target_state_from_string(const char *s);
diff --git a/src/core/tcpwrap.c b/src/core/tcpwrap.c
new file mode 100644 (file)
index 0000000..6c630fa
--- /dev/null
@@ -0,0 +1,68 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#ifdef HAVE_LIBWRAP
+#include <tcpd.h>
+#endif
+
+#include "tcpwrap.h"
+#include "log.h"
+
+bool socket_tcpwrap(int fd, const char *name) {
+#ifdef HAVE_LIBWRAP
+        struct request_info req;
+        union {
+                struct sockaddr sa;
+                struct sockaddr_in in;
+                struct sockaddr_in6 in6;
+                struct sockaddr_un un;
+                struct sockaddr_storage storage;
+        } sa_union;
+        socklen_t l = sizeof(sa_union);
+
+        if (getsockname(fd, &sa_union.sa, &l) < 0)
+                return true;
+
+        if (sa_union.sa.sa_family != AF_INET &&
+            sa_union.sa.sa_family != AF_INET6)
+                return true;
+
+        request_init(&req,
+                     RQ_DAEMON, name,
+                     RQ_FILE, fd,
+                     NULL);
+
+        fromhost(&req);
+
+        if (!hosts_access(&req)) {
+                log_warning("Connection refused by tcpwrap.");
+                return false;
+        }
+
+        log_debug("Connection accepted by tcpwrap.");
+#endif
+        return true;
+}
diff --git a/src/core/tcpwrap.h b/src/core/tcpwrap.h
new file mode 100644 (file)
index 0000000..3353b65
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+bool socket_tcpwrap(int fd, const char *name);
diff --git a/src/core/timer.c b/src/core/timer.c
new file mode 100644 (file)
index 0000000..31ef176
--- /dev/null
@@ -0,0 +1,616 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "unit.h"
+#include "unit-name.h"
+#include "timer.h"
+#include "dbus-timer.h"
+#include "special.h"
+#include "bus-errors.h"
+
+static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
+        [TIMER_DEAD] = UNIT_INACTIVE,
+        [TIMER_WAITING] = UNIT_ACTIVE,
+        [TIMER_RUNNING] = UNIT_ACTIVE,
+        [TIMER_ELAPSED] = UNIT_ACTIVE,
+        [TIMER_FAILED] = UNIT_FAILED
+};
+
+static void timer_init(Unit *u) {
+        Timer *t = TIMER(u);
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        t->next_elapse_monotonic = (usec_t) -1;
+        t->next_elapse_realtime = (usec_t) -1;
+        watch_init(&t->monotonic_watch);
+        watch_init(&t->realtime_watch);
+}
+
+static void timer_done(Unit *u) {
+        Timer *t = TIMER(u);
+        TimerValue *v;
+
+        assert(t);
+
+        while ((v = t->values)) {
+                LIST_REMOVE(TimerValue, value, t->values, v);
+
+                if (v->calendar_spec)
+                        calendar_spec_free(v->calendar_spec);
+
+                free(v);
+        }
+
+        unit_unwatch_timer(u, &t->monotonic_watch);
+        unit_unwatch_timer(u, &t->realtime_watch);
+
+        unit_ref_unset(&t->unit);
+}
+
+static int timer_verify(Timer *t) {
+        assert(t);
+
+        if (UNIT(t)->load_state != UNIT_LOADED)
+                return 0;
+
+        if (!t->values) {
+                log_error_unit(UNIT(t)->id,
+                               "%s lacks value setting. Refusing.", UNIT(t)->id);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static int timer_add_default_dependencies(Timer *t) {
+        int r;
+
+        assert(t);
+
+        if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) {
+                r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true);
+                if (r < 0)
+                        return r;
+
+                r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
+                if (r < 0)
+                        return r;
+        }
+
+        return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+}
+
+static int timer_load(Unit *u) {
+        Timer *t = TIMER(u);
+        int r;
+
+        assert(u);
+        assert(u->load_state == UNIT_STUB);
+
+        r = unit_load_fragment_and_dropin(u);
+        if (r < 0)
+                return r;
+
+        if (u->load_state == UNIT_LOADED) {
+
+                if (!UNIT_DEREF(t->unit)) {
+                        Unit *x;
+
+                        r = unit_load_related_unit(u, ".service", &x);
+                        if (r < 0)
+                                return r;
+
+                        unit_ref_set(&t->unit, x);
+                }
+
+                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(t->unit), true);
+                if (r < 0)
+                        return r;
+
+                if (UNIT(t)->default_dependencies) {
+                        r = timer_add_default_dependencies(t);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return timer_verify(t);
+}
+
+static void timer_dump(Unit *u, FILE *f, const char *prefix) {
+        Timer *t = TIMER(u);
+        TimerValue *v;
+
+        fprintf(f,
+                "%sTimer State: %s\n"
+                "%sResult: %s\n"
+                "%sUnit: %s\n",
+                prefix, timer_state_to_string(t->state),
+                prefix, timer_result_to_string(t->result),
+                prefix, UNIT_DEREF(t->unit)->id);
+
+        LIST_FOREACH(value, v, t->values) {
+
+                if (v->base == TIMER_CALENDAR) {
+                        _cleanup_free_ char *p = NULL;
+
+                        calendar_spec_to_string(v->calendar_spec, &p);
+
+                        fprintf(f,
+                                "%s%s: %s\n",
+                                prefix,
+                                timer_base_to_string(v->base),
+                                strna(p));
+                } else  {
+                        char timespan1[FORMAT_TIMESPAN_MAX];
+
+                        fprintf(f,
+                                "%s%s: %s\n",
+                                prefix,
+                                timer_base_to_string(v->base),
+                                strna(format_timespan(timespan1, sizeof(timespan1), v->value)));
+                }
+        }
+}
+
+static void timer_set_state(Timer *t, TimerState state) {
+        TimerState old_state;
+        assert(t);
+
+        old_state = t->state;
+        t->state = state;
+
+        if (state != TIMER_WAITING) {
+                unit_unwatch_timer(UNIT(t), &t->monotonic_watch);
+                unit_unwatch_timer(UNIT(t), &t->realtime_watch);
+        }
+
+        if (state != old_state)
+                log_debug_unit(UNIT(t)->id,
+                               "%s changed %s -> %s", UNIT(t)->id,
+                               timer_state_to_string(old_state),
+                               timer_state_to_string(state));
+
+        unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true);
+}
+
+static void timer_enter_waiting(Timer *t, bool initial);
+
+static int timer_coldplug(Unit *u) {
+        Timer *t = TIMER(u);
+
+        assert(t);
+        assert(t->state == TIMER_DEAD);
+
+        if (t->deserialized_state != t->state) {
+
+                if (t->deserialized_state == TIMER_WAITING)
+                        timer_enter_waiting(t, false);
+                else
+                        timer_set_state(t, t->deserialized_state);
+        }
+
+        return 0;
+}
+
+static void timer_enter_dead(Timer *t, TimerResult f) {
+        assert(t);
+
+        if (f != TIMER_SUCCESS)
+                t->result = f;
+
+        timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD);
+}
+
+static void timer_enter_waiting(Timer *t, bool initial) {
+        TimerValue *v;
+        usec_t base = 0;
+        dual_timestamp ts;
+        bool found_monotonic = false, found_realtime = false;
+        int r;
+
+        dual_timestamp_get(&ts);
+        t->next_elapse_monotonic = t->next_elapse_realtime = 0;
+
+        LIST_FOREACH(value, v, t->values) {
+
+                if (v->disabled)
+                        continue;
+
+                if (v->base == TIMER_CALENDAR) {
+
+                        r = calendar_spec_next_usec(v->calendar_spec, ts.realtime, &v->next_elapse);
+                        if (r < 0)
+                                continue;
+
+                        if (!initial && v->next_elapse < ts.realtime) {
+                                v->disabled = true;
+                                continue;
+                        }
+
+                        if (!found_realtime)
+                                t->next_elapse_realtime = v->next_elapse;
+                        else
+                                t->next_elapse_realtime = MIN(t->next_elapse_realtime, v->next_elapse);
+
+                        found_realtime = true;
+
+                } else  {
+                        switch (v->base) {
+
+                        case TIMER_ACTIVE:
+                                if (state_translation_table[t->state] == UNIT_ACTIVE)
+                                        base = UNIT(t)->inactive_exit_timestamp.monotonic;
+                                else
+                                        base = ts.monotonic;
+                                break;
+
+                        case TIMER_BOOT:
+                                /* CLOCK_MONOTONIC equals the uptime on Linux */
+                                base = 0;
+                                break;
+
+                        case TIMER_STARTUP:
+                                base = UNIT(t)->manager->userspace_timestamp.monotonic;
+                                break;
+
+                        case TIMER_UNIT_ACTIVE:
+
+                                if (UNIT_DEREF(t->unit)->inactive_exit_timestamp.monotonic <= 0)
+                                        continue;
+
+                                base = UNIT_DEREF(t->unit)->inactive_exit_timestamp.monotonic;
+                                break;
+
+                        case TIMER_UNIT_INACTIVE:
+
+                                if (UNIT_DEREF(t->unit)->inactive_enter_timestamp.monotonic <= 0)
+                                        continue;
+
+                                base = UNIT_DEREF(t->unit)->inactive_enter_timestamp.monotonic;
+                                break;
+
+                        default:
+                                assert_not_reached("Unknown timer base");
+                        }
+
+                        v->next_elapse = base + v->value;
+
+                        if (!initial && v->next_elapse < ts.monotonic) {
+                                v->disabled = true;
+                                continue;
+                        }
+
+                        if (!found_monotonic)
+                                t->next_elapse_monotonic = v->next_elapse;
+                        else
+                                t->next_elapse_monotonic = MIN(t->next_elapse_monotonic, v->next_elapse);
+
+                        found_monotonic = true;
+                }
+        }
+
+        if (!found_monotonic && !found_realtime) {
+                log_debug_unit(UNIT(t)->id, "%s: Timer is elapsed.", UNIT(t)->id);
+                timer_set_state(t, TIMER_ELAPSED);
+                return;
+        }
+
+        if (found_monotonic) {
+                char buf[FORMAT_TIMESPAN_MAX];
+                log_debug_unit(UNIT(t)->id,
+                               "%s: Monotonic timer elapses in %s the next time.",
+                               UNIT(t)->id,
+                               format_timespan(buf, sizeof(buf), t->next_elapse_monotonic - ts.monotonic));
+
+                r = unit_watch_timer(UNIT(t), CLOCK_MONOTONIC, false, t->next_elapse_monotonic, &t->monotonic_watch);
+                if (r < 0)
+                        goto fail;
+        } else
+                unit_unwatch_timer(UNIT(t), &t->monotonic_watch);
+
+        if (found_realtime) {
+                char buf[FORMAT_TIMESTAMP_MAX];
+                log_debug_unit(UNIT(t)->id,
+                               "%s: Realtime timer elapses at %s the next time.",
+                               UNIT(t)->id,
+                               format_timestamp(buf, sizeof(buf), t->next_elapse_realtime));
+
+                r = unit_watch_timer(UNIT(t), CLOCK_REALTIME, false, t->next_elapse_realtime, &t->realtime_watch);
+                if (r < 0)
+                        goto fail;
+        } else
+                unit_unwatch_timer(UNIT(t), &t->realtime_watch);
+
+        timer_set_state(t, TIMER_WAITING);
+        return;
+
+fail:
+        log_warning_unit(UNIT(t)->id,
+                         "%s failed to enter waiting state: %s",
+                         UNIT(t)->id, strerror(-r));
+        timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
+}
+
+static void timer_enter_running(Timer *t) {
+        DBusError error;
+        int r;
+
+        assert(t);
+        dbus_error_init(&error);
+
+        /* Don't start job if we are supposed to go down */
+        if (UNIT(t)->job && UNIT(t)->job->type == JOB_STOP)
+                return;
+
+        r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_DEREF(t->unit), JOB_REPLACE, true, &error, NULL);
+        if (r < 0)
+                goto fail;
+
+        timer_set_state(t, TIMER_RUNNING);
+        return;
+
+fail:
+        log_warning_unit(UNIT(t)->id,
+                         "%s failed to queue unit startup job: %s",
+                         UNIT(t)->id, bus_error(&error, r));
+        timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
+
+        dbus_error_free(&error);
+}
+
+static int timer_start(Unit *u) {
+        Timer *t = TIMER(u);
+
+        assert(t);
+        assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
+
+        if (UNIT_DEREF(t->unit)->load_state != UNIT_LOADED)
+                return -ENOENT;
+
+        t->result = TIMER_SUCCESS;
+        timer_enter_waiting(t, true);
+        return 0;
+}
+
+static int timer_stop(Unit *u) {
+        Timer *t = TIMER(u);
+
+        assert(t);
+        assert(t->state == TIMER_WAITING || t->state == TIMER_RUNNING || t->state == TIMER_ELAPSED);
+
+        timer_enter_dead(t, TIMER_SUCCESS);
+        return 0;
+}
+
+static int timer_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Timer *t = TIMER(u);
+
+        assert(u);
+        assert(f);
+        assert(fds);
+
+        unit_serialize_item(u, f, "state", timer_state_to_string(t->state));
+        unit_serialize_item(u, f, "result", timer_result_to_string(t->result));
+
+        return 0;
+}
+
+static int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
+        Timer *t = TIMER(u);
+
+        assert(u);
+        assert(key);
+        assert(value);
+        assert(fds);
+
+        if (streq(key, "state")) {
+                TimerState state;
+
+                state = timer_state_from_string(value);
+                if (state < 0)
+                        log_debug_unit(u->id, "Failed to parse state value %s", value);
+                else
+                        t->deserialized_state = state;
+        } else if (streq(key, "result")) {
+                TimerResult f;
+
+                f = timer_result_from_string(value);
+                if (f < 0)
+                        log_debug_unit(u->id, "Failed to parse result value %s", value);
+                else if (f != TIMER_SUCCESS)
+                        t->result = f;
+
+        } else
+                log_debug_unit(u->id, "Unknown serialization key '%s'", key);
+
+        return 0;
+}
+
+static UnitActiveState timer_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[TIMER(u)->state];
+}
+
+static const char *timer_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return timer_state_to_string(TIMER(u)->state);
+}
+
+static void timer_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
+        Timer *t = TIMER(u);
+
+        assert(t);
+        assert(elapsed == 1);
+
+        if (t->state != TIMER_WAITING)
+                return;
+
+        log_debug_unit(u->id, "Timer elapsed on %s", u->id);
+        timer_enter_running(t);
+}
+
+void timer_unit_notify(Unit *u, UnitActiveState new_state) {
+        Iterator i;
+        Unit *k;
+
+        if (u->type == UNIT_TIMER)
+                return;
+
+        SET_FOREACH(k, u->dependencies[UNIT_TRIGGERED_BY], i) {
+                Timer *t;
+                TimerValue *v;
+
+                if (k->type != UNIT_TIMER)
+                        continue;
+
+                if (k->load_state != UNIT_LOADED)
+                        continue;
+
+                t = TIMER(k);
+
+                /* Reenable all timers that depend on unit state */
+                LIST_FOREACH(value, v, t->values)
+                        if (v->base == TIMER_UNIT_ACTIVE ||
+                            v->base == TIMER_UNIT_INACTIVE)
+                                v->disabled = false;
+
+                switch (t->state) {
+
+                case TIMER_WAITING:
+                case TIMER_ELAPSED:
+
+                        /* Recalculate sleep time */
+                        timer_enter_waiting(t, false);
+                        break;
+
+                case TIMER_RUNNING:
+
+                        if (UNIT_IS_INACTIVE_OR_FAILED(new_state)) {
+                                log_debug_unit(UNIT(t)->id,
+                                               "%s got notified about unit deactivation.",
+                                               UNIT(t)->id);
+                                timer_enter_waiting(t, false);
+                        }
+
+                        break;
+
+                case TIMER_DEAD:
+                case TIMER_FAILED:
+                        break;
+
+                default:
+                        assert_not_reached("Unknown timer state");
+                }
+        }
+}
+
+static void timer_reset_failed(Unit *u) {
+        Timer *t = TIMER(u);
+
+        assert(t);
+
+        if (t->state == TIMER_FAILED)
+                timer_set_state(t, TIMER_DEAD);
+
+        t->result = TIMER_SUCCESS;
+}
+
+static void timer_time_change(Unit *u) {
+        Timer *t = TIMER(u);
+
+        assert(u);
+
+        if (t->state != TIMER_WAITING)
+                return;
+
+        log_info_unit(u->id,
+                      "%s: time change, recalculating next elapse.", u->id);
+        timer_enter_waiting(t, false);
+}
+
+static const char* const timer_state_table[_TIMER_STATE_MAX] = {
+        [TIMER_DEAD] = "dead",
+        [TIMER_WAITING] = "waiting",
+        [TIMER_RUNNING] = "running",
+        [TIMER_ELAPSED] = "elapsed",
+        [TIMER_FAILED] = "failed"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState);
+
+static const char* const timer_base_table[_TIMER_BASE_MAX] = {
+        [TIMER_ACTIVE] = "OnActiveSec",
+        [TIMER_BOOT] = "OnBootSec",
+        [TIMER_STARTUP] = "OnStartupSec",
+        [TIMER_UNIT_ACTIVE] = "OnUnitActiveSec",
+        [TIMER_UNIT_INACTIVE] = "OnUnitInactiveSec",
+        [TIMER_CALENDAR] = "OnCalendar"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
+
+static const char* const timer_result_table[_TIMER_RESULT_MAX] = {
+        [TIMER_SUCCESS] = "success",
+        [TIMER_FAILURE_RESOURCES] = "resources"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult);
+
+const UnitVTable timer_vtable = {
+        .object_size = sizeof(Timer),
+        .sections =
+                "Unit\0"
+                "Timer\0"
+                "Install\0",
+
+        .init = timer_init,
+        .done = timer_done,
+        .load = timer_load,
+
+        .coldplug = timer_coldplug,
+
+        .dump = timer_dump,
+
+        .start = timer_start,
+        .stop = timer_stop,
+
+        .serialize = timer_serialize,
+        .deserialize_item = timer_deserialize_item,
+
+        .active_state = timer_active_state,
+        .sub_state_to_string = timer_sub_state_to_string,
+
+        .timer_event = timer_timer_event,
+
+        .reset_failed = timer_reset_failed,
+        .time_change = timer_time_change,
+
+        .bus_interface = "org.freedesktop.systemd1.Timer",
+        .bus_message_handler = bus_timer_message_handler,
+        .bus_invalidating_properties =  bus_timer_invalidating_properties
+};
diff --git a/src/core/timer.h b/src/core/timer.h
new file mode 100644 (file)
index 0000000..57a514a
--- /dev/null
@@ -0,0 +1,96 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Timer Timer;
+
+#include "unit.h"
+#include "calendarspec.h"
+
+typedef enum TimerState {
+        TIMER_DEAD,
+        TIMER_WAITING,
+        TIMER_RUNNING,
+        TIMER_ELAPSED,
+        TIMER_FAILED,
+        _TIMER_STATE_MAX,
+        _TIMER_STATE_INVALID = -1
+} TimerState;
+
+typedef enum TimerBase {
+        TIMER_ACTIVE,
+        TIMER_BOOT,
+        TIMER_STARTUP,
+        TIMER_UNIT_ACTIVE,
+        TIMER_UNIT_INACTIVE,
+        TIMER_CALENDAR,
+        _TIMER_BASE_MAX,
+        _TIMER_BASE_INVALID = -1
+} TimerBase;
+
+typedef struct TimerValue {
+        TimerBase base;
+        bool disabled;
+        clockid_t clock_id;
+
+        usec_t value;
+        CalendarSpec *calendar_spec;
+        usec_t next_elapse;
+
+        LIST_FIELDS(struct TimerValue, value);
+} TimerValue;
+
+typedef enum TimerResult {
+        TIMER_SUCCESS,
+        TIMER_FAILURE_RESOURCES,
+        _TIMER_RESULT_MAX,
+        _TIMER_RESULT_INVALID = -1
+} TimerResult;
+
+struct Timer {
+        Unit meta;
+
+        LIST_HEAD(TimerValue, values);
+        usec_t next_elapse_monotonic;
+        usec_t next_elapse_realtime;
+
+        TimerState state, deserialized_state;
+        UnitRef unit;
+
+        Watch monotonic_watch;
+        Watch realtime_watch;
+
+        TimerResult result;
+};
+
+void timer_unit_notify(Unit *u, UnitActiveState new_state);
+
+extern const UnitVTable timer_vtable;
+
+const char *timer_state_to_string(TimerState i);
+TimerState timer_state_from_string(const char *s);
+
+const char *timer_base_to_string(TimerBase i);
+TimerBase timer_base_from_string(const char *s);
+
+const char* timer_result_to_string(TimerResult i);
+TimerResult timer_result_from_string(const char *s);
diff --git a/src/core/transaction.c b/src/core/transaction.c
new file mode 100644 (file)
index 0000000..1854047
--- /dev/null
@@ -0,0 +1,1128 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "transaction.h"
+#include "bus-errors.h"
+
+static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies);
+
+static void transaction_delete_job(Transaction *tr, Job *j, bool delete_dependencies) {
+        assert(tr);
+        assert(j);
+
+        /* Deletes one job from the transaction */
+
+        transaction_unlink_job(tr, j, delete_dependencies);
+
+        job_free(j);
+}
+
+static void transaction_delete_unit(Transaction *tr, Unit *u) {
+        Job *j;
+
+        /* Deletes all jobs associated with a certain unit from the
+         * transaction */
+
+        while ((j = hashmap_get(tr->jobs, u)))
+                transaction_delete_job(tr, j, true);
+}
+
+void transaction_abort(Transaction *tr) {
+        Job *j;
+
+        assert(tr);
+
+        while ((j = hashmap_first(tr->jobs)))
+                transaction_delete_job(tr, j, false);
+
+        assert(hashmap_isempty(tr->jobs));
+}
+
+static void transaction_find_jobs_that_matter_to_anchor(Job *j, unsigned generation) {
+        JobDependency *l;
+
+        /* A recursive sweep through the graph that marks all units
+         * that matter to the anchor job, i.e. are directly or
+         * indirectly a dependency of the anchor job via paths that
+         * are fully marked as mattering. */
+
+        j->matters_to_anchor = true;
+        j->generation = generation;
+
+        LIST_FOREACH(subject, l, j->subject_list) {
+
+                /* This link does not matter */
+                if (!l->matters)
+                        continue;
+
+                /* This unit has already been marked */
+                if (l->object->generation == generation)
+                        continue;
+
+                transaction_find_jobs_that_matter_to_anchor(l->object, generation);
+        }
+}
+
+static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other, JobType t) {
+        JobDependency *l, *last;
+
+        assert(j);
+        assert(other);
+        assert(j->unit == other->unit);
+        assert(!j->installed);
+
+        /* Merges 'other' into 'j' and then deletes 'other'. */
+
+        j->type = t;
+        j->state = JOB_WAITING;
+        j->override = j->override || other->override;
+
+        j->matters_to_anchor = j->matters_to_anchor || other->matters_to_anchor;
+
+        /* Patch us in as new owner of the JobDependency objects */
+        last = NULL;
+        LIST_FOREACH(subject, l, other->subject_list) {
+                assert(l->subject == other);
+                l->subject = j;
+                last = l;
+        }
+
+        /* Merge both lists */
+        if (last) {
+                last->subject_next = j->subject_list;
+                if (j->subject_list)
+                        j->subject_list->subject_prev = last;
+                j->subject_list = other->subject_list;
+        }
+
+        /* Patch us in as new owner of the JobDependency objects */
+        last = NULL;
+        LIST_FOREACH(object, l, other->object_list) {
+                assert(l->object == other);
+                l->object = j;
+                last = l;
+        }
+
+        /* Merge both lists */
+        if (last) {
+                last->object_next = j->object_list;
+                if (j->object_list)
+                        j->object_list->object_prev = last;
+                j->object_list = other->object_list;
+        }
+
+        /* Kill the other job */
+        other->subject_list = NULL;
+        other->object_list = NULL;
+        transaction_delete_job(tr, other, true);
+}
+
+static bool job_is_conflicted_by(Job *j) {
+        JobDependency *l;
+
+        assert(j);
+
+        /* Returns true if this job is pulled in by a least one
+         * ConflictedBy dependency. */
+
+        LIST_FOREACH(object, l, j->object_list)
+                if (l->conflicts)
+                        return true;
+
+        return false;
+}
+
+static int delete_one_unmergeable_job(Transaction *tr, Job *j) {
+        Job *k;
+
+        assert(j);
+
+        /* Tries to delete one item in the linked list
+         * j->transaction_next->transaction_next->... that conflicts
+         * with another one, in an attempt to make an inconsistent
+         * transaction work. */
+
+        /* We rely here on the fact that if a merged with b does not
+         * merge with c, either a or b merge with c neither */
+        LIST_FOREACH(transaction, j, j)
+                LIST_FOREACH(transaction, k, j->transaction_next) {
+                        Job *d;
+
+                        /* Is this one mergeable? Then skip it */
+                        if (job_type_is_mergeable(j->type, k->type))
+                                continue;
+
+                        /* Ok, we found two that conflict, let's see if we can
+                         * drop one of them */
+                        if (!j->matters_to_anchor && !k->matters_to_anchor) {
+
+                                /* Both jobs don't matter, so let's
+                                 * find the one that is smarter to
+                                 * remove. Let's think positive and
+                                 * rather remove stops then starts --
+                                 * except if something is being
+                                 * stopped because it is conflicted by
+                                 * another unit in which case we
+                                 * rather remove the start. */
+
+                                log_debug_unit(j->unit->id,
+                                               "Looking at job %s/%s conflicted_by=%s",
+                                               j->unit->id, job_type_to_string(j->type),
+                                               yes_no(j->type == JOB_STOP && job_is_conflicted_by(j)));
+                                log_debug_unit(k->unit->id,
+                                               "Looking at job %s/%s conflicted_by=%s",
+                                               k->unit->id, job_type_to_string(k->type),
+                                               yes_no(k->type == JOB_STOP && job_is_conflicted_by(k)));
+
+                                if (j->type == JOB_STOP) {
+
+                                        if (job_is_conflicted_by(j))
+                                                d = k;
+                                        else
+                                                d = j;
+
+                                } else if (k->type == JOB_STOP) {
+
+                                        if (job_is_conflicted_by(k))
+                                                d = j;
+                                        else
+                                                d = k;
+                                } else
+                                        d = j;
+
+                        } else if (!j->matters_to_anchor)
+                                d = j;
+                        else if (!k->matters_to_anchor)
+                                d = k;
+                        else
+                                return -ENOEXEC;
+
+                        /* Ok, we can drop one, so let's do so. */
+                        log_debug_unit(d->unit->id,
+                                       "Fixing conflicting jobs by deleting job %s/%s",
+                                       d->unit->id, job_type_to_string(d->type));
+                        transaction_delete_job(tr, d, true);
+                        return 0;
+                }
+
+        return -EINVAL;
+}
+
+static int transaction_merge_jobs(Transaction *tr, DBusError *e) {
+        Job *j;
+        Iterator i;
+        int r;
+
+        assert(tr);
+
+        /* First step, check whether any of the jobs for one specific
+         * task conflict. If so, try to drop one of them. */
+        HASHMAP_FOREACH(j, tr->jobs, i) {
+                JobType t;
+                Job *k;
+
+                t = j->type;
+                LIST_FOREACH(transaction, k, j->transaction_next) {
+                        if (job_type_merge_and_collapse(&t, k->type, j->unit) >= 0)
+                                continue;
+
+                        /* OK, we could not merge all jobs for this
+                         * action. Let's see if we can get rid of one
+                         * of them */
+
+                        r = delete_one_unmergeable_job(tr, j);
+                        if (r >= 0)
+                                /* Ok, we managed to drop one, now
+                                 * let's ask our callers to call us
+                                 * again after garbage collecting */
+                                return -EAGAIN;
+
+                        /* We couldn't merge anything. Failure */
+                        dbus_set_error(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.",
+                                       job_type_to_string(t), job_type_to_string(k->type), k->unit->id);
+                        return r;
+                }
+        }
+
+        /* Second step, merge the jobs. */
+        HASHMAP_FOREACH(j, tr->jobs, i) {
+                JobType t = j->type;
+                Job *k;
+
+                /* Merge all transaction jobs for j->unit */
+                LIST_FOREACH(transaction, k, j->transaction_next)
+                        assert_se(job_type_merge_and_collapse(&t, k->type, j->unit) == 0);
+
+                while ((k = j->transaction_next)) {
+                        if (tr->anchor_job == k) {
+                                transaction_merge_and_delete_job(tr, k, j, t);
+                                j = k;
+                        } else
+                                transaction_merge_and_delete_job(tr, j, k, t);
+                }
+
+                assert(!j->transaction_next);
+                assert(!j->transaction_prev);
+        }
+
+        return 0;
+}
+
+static void transaction_drop_redundant(Transaction *tr) {
+        Job *j;
+        Iterator i;
+
+        /* Goes through the transaction and removes all jobs of the units
+         * whose jobs are all noops. If not all of a unit's jobs are
+         * redundant, they are kept. */
+
+        assert(tr);
+
+rescan:
+        HASHMAP_FOREACH(j, tr->jobs, i) {
+                Job *k;
+
+                LIST_FOREACH(transaction, k, j) {
+
+                        if (tr->anchor_job == k ||
+                            !job_type_is_redundant(k->type, unit_active_state(k->unit)) ||
+                            (k->unit->job && job_type_is_conflicting(k->type, k->unit->job->type)))
+                                goto next_unit;
+                }
+
+                /* log_debug("Found redundant job %s/%s, dropping.", j->unit->id, job_type_to_string(j->type)); */
+                transaction_delete_job(tr, j, false);
+                goto rescan;
+        next_unit:;
+        }
+}
+
+static bool unit_matters_to_anchor(Unit *u, Job *j) {
+        assert(u);
+        assert(!j->transaction_prev);
+
+        /* Checks whether at least one of the jobs for this unit
+         * matters to the anchor. */
+
+        LIST_FOREACH(transaction, j, j)
+                if (j->matters_to_anchor)
+                        return true;
+
+        return false;
+}
+
+static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsigned generation, DBusError *e) {
+        Iterator i;
+        Unit *u;
+        int r;
+
+        assert(tr);
+        assert(j);
+        assert(!j->transaction_prev);
+
+        /* Does a recursive sweep through the ordering graph, looking
+         * for a cycle. If we find cycle we try to break it. */
+
+        /* Have we seen this before? */
+        if (j->generation == generation) {
+                Job *k, *delete;
+
+                /* If the marker is NULL we have been here already and
+                 * decided the job was loop-free from here. Hence
+                 * shortcut things and return right-away. */
+                if (!j->marker)
+                        return 0;
+
+                /* So, the marker is not NULL and we already have been
+                 * here. We have a cycle. Let's try to break it. We go
+                 * backwards in our path and try to find a suitable
+                 * job to remove. We use the marker to find our way
+                 * back, since smart how we are we stored our way back
+                 * in there. */
+                log_warning_unit(j->unit->id,
+                                 "Found ordering cycle on %s/%s",
+                                 j->unit->id, job_type_to_string(j->type));
+
+                delete = NULL;
+                for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) {
+
+                        /* logging for j not k here here to provide consistent narrative */
+                        log_info_unit(j->unit->id,
+                                      "Walked on cycle path to %s/%s",
+                                      k->unit->id, job_type_to_string(k->type));
+
+                        if (!delete &&
+                            !unit_matters_to_anchor(k->unit, k)) {
+                                /* Ok, we can drop this one, so let's
+                                 * do so. */
+                                delete = k;
+                        }
+
+                        /* Check if this in fact was the beginning of
+                         * the cycle */
+                        if (k == j)
+                                break;
+                }
+
+
+                if (delete) {
+                        /* logging for j not k here here to provide consistent narrative */
+                        log_warning_unit(j->unit->id,
+                                         "Breaking ordering cycle by deleting job %s/%s",
+                                         delete->unit->id, job_type_to_string(delete->type));
+                        log_error_unit(delete->unit->id,
+                                       "Job %s/%s deleted to break ordering cycle starting with %s/%s",
+                                       delete->unit->id, job_type_to_string(delete->type),
+                                       j->unit->id, job_type_to_string(j->type));
+                        status_printf(ANSI_HIGHLIGHT_RED_ON " SKIP " ANSI_HIGHLIGHT_OFF, true,
+                                      "Ordering cycle found, skipping %s", unit_description(delete->unit));
+                        transaction_delete_unit(tr, delete->unit);
+                        return -EAGAIN;
+                }
+
+                log_error("Unable to break cycle");
+
+                dbus_set_error(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC,
+                               "Transaction order is cyclic. See system logs for details.");
+                return -ENOEXEC;
+        }
+
+        /* Make the marker point to where we come from, so that we can
+         * find our way backwards if we want to break a cycle. We use
+         * a special marker for the beginning: we point to
+         * ourselves. */
+        j->marker = from ? from : j;
+        j->generation = generation;
+
+        /* We assume that the dependencies are bidirectional, and
+         * hence can ignore UNIT_AFTER */
+        SET_FOREACH(u, j->unit->dependencies[UNIT_BEFORE], i) {
+                Job *o;
+
+                /* Is there a job for this unit? */
+                o = hashmap_get(tr->jobs, u);
+                if (!o) {
+                        /* Ok, there is no job for this in the
+                         * transaction, but maybe there is already one
+                         * running? */
+                        o = u->job;
+                        if (!o)
+                                continue;
+                }
+
+                r = transaction_verify_order_one(tr, o, j, generation, e);
+                if (r < 0)
+                        return r;
+        }
+
+        /* Ok, let's backtrack, and remember that this entry is not on
+         * our path anymore. */
+        j->marker = NULL;
+
+        return 0;
+}
+
+static int transaction_verify_order(Transaction *tr, unsigned *generation, DBusError *e) {
+        Job *j;
+        int r;
+        Iterator i;
+        unsigned g;
+
+        assert(tr);
+        assert(generation);
+
+        /* Check if the ordering graph is cyclic. If it is, try to fix
+         * that up by dropping one of the jobs. */
+
+        g = (*generation)++;
+
+        HASHMAP_FOREACH(j, tr->jobs, i)
+                if ((r = transaction_verify_order_one(tr, j, NULL, g, e)) < 0)
+                        return r;
+
+        return 0;
+}
+
+static void transaction_collect_garbage(Transaction *tr) {
+        Iterator i;
+        Job *j;
+
+        assert(tr);
+
+        /* Drop jobs that are not required by any other job */
+
+rescan:
+        HASHMAP_FOREACH(j, tr->jobs, i) {
+                if (tr->anchor_job == j || j->object_list) {
+                        /* log_debug("Keeping job %s/%s because of %s/%s", */
+                        /*           j->unit->id, job_type_to_string(j->type), */
+                        /*           j->object_list->subject ? j->object_list->subject->unit->id : "root", */
+                        /*           j->object_list->subject ? job_type_to_string(j->object_list->subject->type) : "root"); */
+                        continue;
+                }
+
+                /* log_debug("Garbage collecting job %s/%s", j->unit->id, job_type_to_string(j->type)); */
+                transaction_delete_job(tr, j, true);
+                goto rescan;
+        }
+}
+
+static int transaction_is_destructive(Transaction *tr, DBusError *e) {
+        Iterator i;
+        Job *j;
+
+        assert(tr);
+
+        /* Checks whether applying this transaction means that
+         * existing jobs would be replaced */
+
+        HASHMAP_FOREACH(j, tr->jobs, i) {
+
+                /* Assume merged */
+                assert(!j->transaction_prev);
+                assert(!j->transaction_next);
+
+                if (j->unit->job &&
+                    !job_type_is_superset(j->type, j->unit->job->type)) {
+
+                        dbus_set_error(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive.");
+                        return -EEXIST;
+                }
+        }
+
+        return 0;
+}
+
+static void transaction_minimize_impact(Transaction *tr) {
+        Job *j;
+        Iterator i;
+
+        assert(tr);
+
+        /* Drops all unnecessary jobs that reverse already active jobs
+         * or that stop a running service. */
+
+rescan:
+        HASHMAP_FOREACH(j, tr->jobs, i) {
+                LIST_FOREACH(transaction, j, j) {
+                        bool stops_running_service, changes_existing_job;
+
+                        /* If it matters, we shouldn't drop it */
+                        if (j->matters_to_anchor)
+                                continue;
+
+                        /* Would this stop a running service?
+                         * Would this change an existing job?
+                         * If so, let's drop this entry */
+
+                        stops_running_service =
+                                j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit));
+
+                        changes_existing_job =
+                                j->unit->job &&
+                                job_type_is_conflicting(j->type, j->unit->job->type);
+
+                        if (!stops_running_service && !changes_existing_job)
+                                continue;
+
+                        if (stops_running_service)
+                                log_debug_unit(j->unit->id,
+                                               "%s/%s would stop a running service.",
+                                               j->unit->id, job_type_to_string(j->type));
+
+                        if (changes_existing_job)
+                                log_debug_unit(j->unit->id,
+                                               "%s/%s would change existing job.",
+                                               j->unit->id, job_type_to_string(j->type));
+
+                        /* Ok, let's get rid of this */
+                        log_debug_unit(j->unit->id,
+                                       "Deleting %s/%s to minimize impact.",
+                                       j->unit->id, job_type_to_string(j->type));
+
+                        transaction_delete_job(tr, j, true);
+                        goto rescan;
+                }
+        }
+}
+
+static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) {
+        Iterator i;
+        Job *j;
+        int r;
+
+        /* Moves the transaction jobs to the set of active jobs */
+
+        if (mode == JOB_ISOLATE) {
+
+                /* When isolating first kill all installed jobs which
+                 * aren't part of the new transaction */
+                HASHMAP_FOREACH(j, m->jobs, i) {
+                        assert(j->installed);
+
+                        if (hashmap_get(tr->jobs, j->unit))
+                                continue;
+
+                        /* Not invalidating recursively. Avoids triggering
+                         * OnFailure= actions of dependent jobs. Also avoids
+                         * invalidating our iterator. */
+                        job_finish_and_invalidate(j, JOB_CANCELED, false);
+                }
+        }
+
+        HASHMAP_FOREACH(j, tr->jobs, i) {
+                /* Assume merged */
+                assert(!j->transaction_prev);
+                assert(!j->transaction_next);
+
+                r = hashmap_put(m->jobs, UINT32_TO_PTR(j->id), j);
+                if (r < 0)
+                        goto rollback;
+        }
+
+        while ((j = hashmap_steal_first(tr->jobs))) {
+                Job *installed_job;
+
+                /* Clean the job dependencies */
+                transaction_unlink_job(tr, j, false);
+
+                installed_job = job_install(j);
+                if (installed_job != j) {
+                        /* j has been merged into a previously installed job */
+                        if (tr->anchor_job == j)
+                                tr->anchor_job = installed_job;
+                        hashmap_remove(m->jobs, UINT32_TO_PTR(j->id));
+                        job_free(j);
+                        j = installed_job;
+                }
+
+                job_add_to_run_queue(j);
+                job_add_to_dbus_queue(j);
+                job_start_timer(j);
+        }
+
+        return 0;
+
+rollback:
+
+        HASHMAP_FOREACH(j, tr->jobs, i)
+                hashmap_remove(m->jobs, UINT32_TO_PTR(j->id));
+
+        return r;
+}
+
+int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e) {
+        Iterator i;
+        Job *j;
+        int r;
+        unsigned generation = 1;
+
+        assert(tr);
+
+        /* This applies the changes recorded in tr->jobs to
+         * the actual list of jobs, if possible. */
+
+        /* Reset the generation counter of all installed jobs. The detection of cycles
+         * looks at installed jobs. If they had a non-zero generation from some previous
+         * walk of the graph, the algorithm would break. */
+        HASHMAP_FOREACH(j, m->jobs, i)
+                j->generation = 0;
+
+        /* First step: figure out which jobs matter */
+        transaction_find_jobs_that_matter_to_anchor(tr->anchor_job, generation++);
+
+        /* Second step: Try not to stop any running services if
+         * we don't have to. Don't try to reverse running
+         * jobs if we don't have to. */
+        if (mode == JOB_FAIL)
+                transaction_minimize_impact(tr);
+
+        /* Third step: Drop redundant jobs */
+        transaction_drop_redundant(tr);
+
+        for (;;) {
+                /* Fourth step: Let's remove unneeded jobs that might
+                 * be lurking. */
+                if (mode != JOB_ISOLATE)
+                        transaction_collect_garbage(tr);
+
+                /* Fifth step: verify order makes sense and correct
+                 * cycles if necessary and possible */
+                r = transaction_verify_order(tr, &generation, e);
+                if (r >= 0)
+                        break;
+
+                if (r != -EAGAIN) {
+                        log_warning("Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error(e, r));
+                        return r;
+                }
+
+                /* Let's see if the resulting transaction ordering
+                 * graph is still cyclic... */
+        }
+
+        for (;;) {
+                /* Sixth step: let's drop unmergeable entries if
+                 * necessary and possible, merge entries we can
+                 * merge */
+                r = transaction_merge_jobs(tr, e);
+                if (r >= 0)
+                        break;
+
+                if (r != -EAGAIN) {
+                        log_warning("Requested transaction contains unmergeable jobs: %s", bus_error(e, r));
+                        return r;
+                }
+
+                /* Seventh step: an entry got dropped, let's garbage
+                 * collect its dependencies. */
+                if (mode != JOB_ISOLATE)
+                        transaction_collect_garbage(tr);
+
+                /* Let's see if the resulting transaction still has
+                 * unmergeable entries ... */
+        }
+
+        /* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */
+        transaction_drop_redundant(tr);
+
+        /* Ninth step: check whether we can actually apply this */
+        if (mode == JOB_FAIL) {
+                r = transaction_is_destructive(tr, e);
+                if (r < 0) {
+                        log_notice("Requested transaction contradicts existing jobs: %s", bus_error(e, r));
+                        return r;
+                }
+        }
+
+        /* Tenth step: apply changes */
+        r = transaction_apply(tr, m, mode);
+        if (r < 0) {
+                log_warning("Failed to apply transaction: %s", strerror(-r));
+                return r;
+        }
+
+        assert(hashmap_isempty(tr->jobs));
+
+        if (!hashmap_isempty(m->jobs)) {
+                /* Are there any jobs now? Then make sure we have the
+                 * idle pipe around. We don't really care too much
+                 * whether this works or not, as the idle pipe is a
+                 * feature for cosmetics, not actually useful for
+                 * anything beyond that. */
+
+                if (m->idle_pipe[0] < 0 && m->idle_pipe[1] < 0)
+                        pipe2(m->idle_pipe, O_NONBLOCK|O_CLOEXEC);
+        }
+
+        return 0;
+}
+
+static Job* transaction_add_one_job(Transaction *tr, JobType type, Unit *unit, bool override, bool *is_new) {
+        Job *j, *f;
+
+        assert(tr);
+        assert(unit);
+
+        /* Looks for an existing prospective job and returns that. If
+         * it doesn't exist it is created and added to the prospective
+         * jobs list. */
+
+        f = hashmap_get(tr->jobs, unit);
+
+        LIST_FOREACH(transaction, j, f) {
+                assert(j->unit == unit);
+
+                if (j->type == type) {
+                        if (is_new)
+                                *is_new = false;
+                        return j;
+                }
+        }
+
+        j = job_new(unit, type);
+        if (!j)
+                return NULL;
+
+        j->generation = 0;
+        j->marker = NULL;
+        j->matters_to_anchor = false;
+        j->override = override;
+
+        LIST_PREPEND(Job, transaction, f, j);
+
+        if (hashmap_replace(tr->jobs, unit, f) < 0) {
+                LIST_REMOVE(Job, transaction, f, j);
+                job_free(j);
+                return NULL;
+        }
+
+        if (is_new)
+                *is_new = true;
+
+        /* log_debug("Added job %s/%s to transaction.", unit->id, job_type_to_string(type)); */
+
+        return j;
+}
+
+static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies) {
+        assert(tr);
+        assert(j);
+
+        if (j->transaction_prev)
+                j->transaction_prev->transaction_next = j->transaction_next;
+        else if (j->transaction_next)
+                hashmap_replace(tr->jobs, j->unit, j->transaction_next);
+        else
+                hashmap_remove_value(tr->jobs, j->unit, j);
+
+        if (j->transaction_next)
+                j->transaction_next->transaction_prev = j->transaction_prev;
+
+        j->transaction_prev = j->transaction_next = NULL;
+
+        while (j->subject_list)
+                job_dependency_free(j->subject_list);
+
+        while (j->object_list) {
+                Job *other = j->object_list->matters ? j->object_list->subject : NULL;
+
+                job_dependency_free(j->object_list);
+
+                if (other && delete_dependencies) {
+                        log_debug_unit(other->unit->id,
+                                       "Deleting job %s/%s as dependency of job %s/%s",
+                                       other->unit->id, job_type_to_string(other->type),
+                                       j->unit->id, job_type_to_string(j->type));
+                        transaction_delete_job(tr, other, delete_dependencies);
+                }
+        }
+}
+
+int transaction_add_job_and_dependencies(
+                Transaction *tr,
+                JobType type,
+                Unit *unit,
+                Job *by,
+                bool matters,
+                bool override,
+                bool conflicts,
+                bool ignore_requirements,
+                bool ignore_order,
+                DBusError *e) {
+        Job *ret;
+        Iterator i;
+        Unit *dep;
+        int r;
+        bool is_new;
+
+        assert(tr);
+        assert(type < _JOB_TYPE_MAX);
+        assert(type < _JOB_TYPE_MAX_IN_TRANSACTION);
+        assert(unit);
+
+        /* log_debug("Pulling in %s/%s from %s/%s", */
+        /*           unit->id, job_type_to_string(type), */
+        /*           by ? by->unit->id : "NA", */
+        /*           by ? job_type_to_string(by->type) : "NA"); */
+
+        if (unit->load_state != UNIT_LOADED &&
+            unit->load_state != UNIT_ERROR &&
+            unit->load_state != UNIT_MASKED) {
+                dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
+                return -EINVAL;
+        }
+
+        if (type != JOB_STOP && unit->load_state == UNIT_ERROR) {
+                dbus_set_error(e, BUS_ERROR_LOAD_FAILED,
+                               "Unit %s failed to load: %s. "
+                               "See system logs and 'systemctl status %s' for details.",
+                               unit->id,
+                               strerror(-unit->load_error),
+                               unit->id);
+                return -EINVAL;
+        }
+
+        if (type != JOB_STOP && unit->load_state == UNIT_MASKED) {
+                dbus_set_error(e, BUS_ERROR_MASKED, "Unit %s is masked.", unit->id);
+                return -EADDRNOTAVAIL;
+        }
+
+        if (!unit_job_is_applicable(unit, type)) {
+                dbus_set_error(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->id);
+                return -EBADR;
+        }
+
+        /* First add the job. */
+        ret = transaction_add_one_job(tr, type, unit, override, &is_new);
+        if (!ret)
+                return -ENOMEM;
+
+        ret->ignore_order = ret->ignore_order || ignore_order;
+
+        /* Then, add a link to the job. */
+        if (by) {
+                if (!job_dependency_new(by, ret, matters, conflicts))
+                        return -ENOMEM;
+        } else {
+                /* If the job has no parent job, it is the anchor job. */
+                assert(!tr->anchor_job);
+                tr->anchor_job = ret;
+        }
+
+        if (is_new && !ignore_requirements && type != JOB_NOP) {
+                Set *following;
+
+                /* If we are following some other unit, make sure we
+                 * add all dependencies of everybody following. */
+                if (unit_following_set(ret->unit, &following) > 0) {
+                        SET_FOREACH(dep, following, i) {
+                                r = transaction_add_job_and_dependencies(tr, type, dep, ret, false, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        log_warning_unit(dep->id,
+                                                         "Cannot add dependency job for unit %s, ignoring: %s",
+                                                         dep->id, bus_error(e, r));
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        set_free(following);
+                }
+
+                /* Finally, recursively add in all dependencies. */
+                if (type == JOB_START || type == JOB_RESTART) {
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        if (r != -EBADR)
+                                                goto fail;
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_BINDS_TO], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        if (r != -EBADR)
+                                                goto fail;
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, !override, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id,
+                                                      "Cannot add dependency job for unit %s, ignoring: %s",
+                                                      dep->id, bus_error(e, r));
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_WANTS], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, false, false, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id,
+                                                      "Cannot add dependency job for unit %s, ignoring: %s",
+                                                      dep->id, bus_error(e, r));
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        if (r != -EBADR)
+                                                goto fail;
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE_OVERRIDABLE], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id,
+                                                      "Cannot add dependency job for unit %s, ignoring: %s",
+                                                      dep->id, bus_error(e, r));
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTS], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, true, override, true, false, ignore_order, e);
+                                if (r < 0) {
+                                        if (r != -EBADR)
+                                                goto fail;
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTED_BY], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, false, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        log_warning_unit(dep->id,
+                                                         "Cannot add dependency job for unit %s, ignoring: %s",
+                                                         dep->id, bus_error(e, r));
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                }
+
+                if (type == JOB_STOP || type == JOB_RESTART) {
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRED_BY], i) {
+                                r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        if (r != -EBADR)
+                                                goto fail;
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_BOUND_BY], i) {
+                                r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        if (r != -EBADR)
+                                                goto fail;
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONSISTS_OF], i) {
+                                r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        if (r != -EBADR)
+                                                goto fail;
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+
+                }
+
+                if (type == JOB_RELOAD) {
+
+                        SET_FOREACH(dep, ret->unit->dependencies[UNIT_PROPAGATES_RELOAD_TO], i) {
+                                r = transaction_add_job_and_dependencies(tr, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e);
+                                if (r < 0) {
+                                        log_warning_unit(dep->id,
+                                                         "Cannot add dependency reload job for unit %s, ignoring: %s",
+                                                         dep->id, bus_error(e, r));
+
+                                        if (e)
+                                                dbus_error_free(e);
+                                }
+                        }
+                }
+
+                /* JOB_VERIFY_STARTED require no dependency handling */
+        }
+
+        return 0;
+
+fail:
+        return r;
+}
+
+int transaction_add_isolate_jobs(Transaction *tr, Manager *m) {
+        Iterator i;
+        Unit *u;
+        char *k;
+        int r;
+
+        assert(tr);
+        assert(m);
+
+        HASHMAP_FOREACH_KEY(u, k, m->units, i) {
+
+                /* ignore aliases */
+                if (u->id != k)
+                        continue;
+
+                if (u->ignore_on_isolate)
+                        continue;
+
+                /* No need to stop inactive jobs */
+                if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)) && !u->job)
+                        continue;
+
+                /* Is there already something listed for this? */
+                if (hashmap_get(tr->jobs, u))
+                        continue;
+
+                r = transaction_add_job_and_dependencies(tr, JOB_STOP, u, tr->anchor_job, true, false, false, false, false, NULL);
+                if (r < 0)
+                        log_warning_unit(u->id,
+                                         "Cannot add isolate job for unit %s, ignoring: %s",
+                                         u->id, strerror(-r));
+        }
+
+        return 0;
+}
+
+Transaction *transaction_new(void) {
+        Transaction *tr;
+
+        tr = new0(Transaction, 1);
+        if (!tr)
+                return NULL;
+
+        tr->jobs = hashmap_new(trivial_hash_func, trivial_compare_func);
+        if (!tr->jobs) {
+                free(tr);
+                return NULL;
+        }
+
+        return tr;
+}
+
+void transaction_free(Transaction *tr) {
+        assert(hashmap_isempty(tr->jobs));
+        hashmap_free(tr->jobs);
+        free(tr);
+}
diff --git a/src/core/transaction.h b/src/core/transaction.h
new file mode 100644 (file)
index 0000000..67ace4d
--- /dev/null
@@ -0,0 +1,56 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef footransactionhfoo
+#define footransactionhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Transaction Transaction;
+
+#include "unit.h"
+#include "manager.h"
+#include "job.h"
+#include "hashmap.h"
+
+struct Transaction {
+        /* Jobs to be added */
+        Hashmap *jobs;      /* Unit object => Job object list 1:1 */
+        Job *anchor_job;      /* the job the user asked for */
+};
+
+Transaction *transaction_new(void);
+void transaction_free(Transaction *tr);
+
+int transaction_add_job_and_dependencies(
+                Transaction *tr,
+                JobType type,
+                Unit *unit,
+                Job *by,
+                bool matters,
+                bool override,
+                bool conflicts,
+                bool ignore_requirements,
+                bool ignore_order,
+                DBusError *e);
+int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e);
+int transaction_add_isolate_jobs(Transaction *tr, Manager *m);
+void transaction_abort(Transaction *tr);
+
+#endif
diff --git a/src/core/umount.c b/src/core/umount.c
new file mode 100644 (file)
index 0000000..96232d3
--- /dev/null
@@ -0,0 +1,638 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 ProFUSION embedded systems
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/swap.h>
+#include <unistd.h>
+#include <linux/loop.h>
+#include <linux/dm-ioctl.h>
+#include <libudev.h>
+
+#include "list.h"
+#include "mount-setup.h"
+#include "umount.h"
+#include "path-util.h"
+#include "util.h"
+#include "virt.h"
+
+typedef struct MountPoint {
+        char *path;
+        dev_t devnum;
+        LIST_FIELDS (struct MountPoint, mount_point);
+} MountPoint;
+
+static void mount_point_free(MountPoint **head, MountPoint *m) {
+        assert(head);
+        assert(m);
+
+        LIST_REMOVE(MountPoint, mount_point, *head, m);
+
+        free(m->path);
+        free(m);
+}
+
+static void mount_points_list_free(MountPoint **head) {
+        assert(head);
+
+        while (*head)
+                mount_point_free(head, *head);
+}
+
+static int mount_points_list_get(MountPoint **head) {
+        FILE *proc_self_mountinfo;
+        char *path, *p;
+        unsigned int i;
+        int r;
+
+        assert(head);
+
+        if (!(proc_self_mountinfo = fopen("/proc/self/mountinfo", "re")))
+                return -errno;
+
+        for (i = 1;; i++) {
+                int k;
+                MountPoint *m;
+
+                path = p = NULL;
+
+                if ((k = fscanf(proc_self_mountinfo,
+                                "%*s "       /* (1) mount id */
+                                "%*s "       /* (2) parent id */
+                                "%*s "       /* (3) major:minor */
+                                "%*s "       /* (4) root */
+                                "%ms "       /* (5) mount point */
+                                "%*s"        /* (6) mount options */
+                                "%*[^-]"     /* (7) optional fields */
+                                "- "         /* (8) separator */
+                                "%*s "       /* (9) file system type */
+                                "%*s"        /* (10) mount source */
+                                "%*s"        /* (11) mount options 2 */
+                                "%*[^\n]",   /* some rubbish at the end */
+                                &path)) != 1) {
+                        if (k == EOF)
+                                break;
+
+                        log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
+
+                        free(path);
+                        continue;
+                }
+
+                p = cunescape(path);
+                free(path);
+
+                if (!p) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                /* Ignore mount points we can't unmount because they
+                 * are API or because we are keeping them open (like
+                 * /dev/console) */
+                if (mount_point_is_api(p) ||
+                    mount_point_ignore(p) ||
+                    path_equal(p, "/dev/console")) {
+                        free(p);
+                        continue;
+                }
+
+                if (!(m = new0(MountPoint, 1))) {
+                        free(p);
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                m->path = p;
+                LIST_PREPEND(MountPoint, mount_point, *head, m);
+        }
+
+        r = 0;
+
+finish:
+        fclose(proc_self_mountinfo);
+
+        return r;
+}
+
+static int swap_list_get(MountPoint **head) {
+        FILE *proc_swaps;
+        unsigned int i;
+        int r;
+
+        assert(head);
+
+        if (!(proc_swaps = fopen("/proc/swaps", "re")))
+                return (errno == ENOENT) ? 0 : -errno;
+
+        (void) fscanf(proc_swaps, "%*s %*s %*s %*s %*s\n");
+
+        for (i = 2;; i++) {
+                MountPoint *swap;
+                char *dev = NULL, *d;
+                int k;
+
+                if ((k = fscanf(proc_swaps,
+                                "%ms " /* device/file */
+                                "%*s " /* type of swap */
+                                "%*s " /* swap size */
+                                "%*s " /* used */
+                                "%*s\n", /* priority */
+                                &dev)) != 1) {
+
+                        if (k == EOF)
+                                break;
+
+                        log_warning("Failed to parse /proc/swaps:%u.", i);
+
+                        free(dev);
+                        continue;
+                }
+
+                if (endswith(dev, "(deleted)")) {
+                        free(dev);
+                        continue;
+                }
+
+                d = cunescape(dev);
+                free(dev);
+
+                if (!d) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (!(swap = new0(MountPoint, 1))) {
+                        free(d);
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                swap->path = d;
+                LIST_PREPEND(MountPoint, mount_point, *head, swap);
+        }
+
+        r = 0;
+
+finish:
+        fclose(proc_swaps);
+
+        return r;
+}
+
+static int loopback_list_get(MountPoint **head) {
+        int r;
+        struct udev *udev;
+        struct udev_enumerate *e = NULL;
+        struct udev_list_entry *item = NULL, *first = NULL;
+
+        assert(head);
+
+        if (!(udev = udev_new())) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (!(e = udev_enumerate_new(udev))) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (udev_enumerate_add_match_subsystem(e, "block") < 0 ||
+            udev_enumerate_add_match_sysname(e, "loop*") < 0) {
+                r = -EIO;
+                goto finish;
+        }
+
+        if (udev_enumerate_scan_devices(e) < 0) {
+                r = -EIO;
+                goto finish;
+        }
+
+        first = udev_enumerate_get_list_entry(e);
+        udev_list_entry_foreach(item, first) {
+                MountPoint *lb;
+                struct udev_device *d;
+                char *loop;
+                const char *dn;
+
+                if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (!(dn = udev_device_get_devnode(d))) {
+                        udev_device_unref(d);
+                        continue;
+                }
+
+                loop = strdup(dn);
+                udev_device_unref(d);
+
+                if (!loop) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (!(lb = new0(MountPoint, 1))) {
+                        free(loop);
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                lb->path = loop;
+                LIST_PREPEND(MountPoint, mount_point, *head, lb);
+        }
+
+        r = 0;
+
+finish:
+        if (e)
+                udev_enumerate_unref(e);
+
+        if (udev)
+                udev_unref(udev);
+
+        return r;
+}
+
+static int dm_list_get(MountPoint **head) {
+        int r;
+        struct udev *udev;
+        struct udev_enumerate *e = NULL;
+        struct udev_list_entry *item = NULL, *first = NULL;
+
+        assert(head);
+
+        if (!(udev = udev_new())) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (!(e = udev_enumerate_new(udev))) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (udev_enumerate_add_match_subsystem(e, "block") < 0 ||
+            udev_enumerate_add_match_sysname(e, "dm-*") < 0) {
+                r = -EIO;
+                goto finish;
+        }
+
+        if (udev_enumerate_scan_devices(e) < 0) {
+                r = -EIO;
+                goto finish;
+        }
+
+        first = udev_enumerate_get_list_entry(e);
+
+        udev_list_entry_foreach(item, first) {
+                MountPoint *m;
+                struct udev_device *d;
+                dev_t devnum;
+                char *node;
+                const char *dn;
+
+                if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                devnum = udev_device_get_devnum(d);
+                dn = udev_device_get_devnode(d);
+
+                if (major(devnum) == 0 || !dn) {
+                        udev_device_unref(d);
+                        continue;
+                }
+
+                node = strdup(dn);
+                udev_device_unref(d);
+
+                if (!node) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (!(m = new(MountPoint, 1))) {
+                        free(node);
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                m->path = node;
+                m->devnum = devnum;
+                LIST_PREPEND(MountPoint, mount_point, *head, m);
+        }
+
+        r = 0;
+
+finish:
+        if (e)
+                udev_enumerate_unref(e);
+
+        if (udev)
+                udev_unref(udev);
+
+        return r;
+}
+
+static int delete_loopback(const char *device) {
+        int fd, r;
+
+        if ((fd = open(device, O_RDONLY|O_CLOEXEC)) < 0)
+                return errno == ENOENT ? 0 : -errno;
+
+        r = ioctl(fd, LOOP_CLR_FD, 0);
+        close_nointr_nofail(fd);
+
+        if (r >= 0)
+                return 1;
+
+        /* ENXIO: not bound, so no error */
+        if (errno == ENXIO)
+                return 0;
+
+        return -errno;
+}
+
+static int delete_dm(dev_t devnum) {
+        int fd, r;
+        struct dm_ioctl dm;
+
+        assert(major(devnum) != 0);
+
+        if ((fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC)) < 0)
+                return -errno;
+
+        zero(dm);
+        dm.version[0] = DM_VERSION_MAJOR;
+        dm.version[1] = DM_VERSION_MINOR;
+        dm.version[2] = DM_VERSION_PATCHLEVEL;
+
+        dm.data_size = sizeof(dm);
+        dm.dev = devnum;
+
+        r = ioctl(fd, DM_DEV_REMOVE, &dm);
+        close_nointr_nofail(fd);
+
+        return r >= 0 ? 0 : -errno;
+}
+
+static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) {
+        MountPoint *m, *n;
+        int n_failed = 0;
+
+        assert(head);
+
+        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+
+                /* If we are in a container, don't attempt to
+                   read-only mount anything as that brings no real
+                   benefits, but might confuse the host, as we remount
+                   the superblock here, not the bind mound. */
+                if (detect_container(NULL) <= 0)  {
+                        /* We always try to remount directories
+                         * read-only first, before we go on and umount
+                         * them.
+                         *
+                         * Mount points can be stacked. If a mount
+                         * point is stacked below / or /usr, we
+                         * cannnot umount or remount it directly,
+                         * since there is no way to refer to the
+                         * underlying mount. There's nothing we can do
+                         * about it for the general case, but we can
+                         * do something about it if it is aliased
+                         * somehwere else via a bind mount. If we
+                         * explicitly remount the super block of that
+                         * alias read-only we hence should be
+                         * relatively safe regarding keeping the fs we
+                         * can otherwise not see dirty. */
+                        mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
+                }
+
+                /* Skip / and /usr since we cannot unmount that
+                 * anyway, since we are running from it. They have
+                 * already been remounted ro. */
+                if (path_equal(m->path, "/")
+#ifndef HAVE_SPLIT_USR
+                    || path_equal(m->path, "/usr")
+#endif
+                )
+                        continue;
+
+                /* Trying to umount. Forcing to umount if busy (only for NFS mounts) */
+                log_info("Unmounting %s.", m->path);
+                if (umount2(m->path, MNT_FORCE) == 0) {
+                        if (changed)
+                                *changed = true;
+
+                        mount_point_free(head, m);
+                } else if (log_error) {
+                        log_warning("Could not unmount %s: %m", m->path);
+                        n_failed++;
+                }
+        }
+
+        return n_failed;
+}
+
+static int swap_points_list_off(MountPoint **head, bool *changed) {
+        MountPoint *m, *n;
+        int n_failed = 0;
+
+        assert(head);
+
+        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+                log_info("Deactivating swap %s.", m->path);
+                if (swapoff(m->path) == 0) {
+                        if (changed)
+                                *changed = true;
+
+                        mount_point_free(head, m);
+                } else {
+                        log_warning("Could not deactivate swap %s: %m", m->path);
+                        n_failed++;
+                }
+        }
+
+        return n_failed;
+}
+
+static int loopback_points_list_detach(MountPoint **head, bool *changed) {
+        MountPoint *m, *n;
+        int n_failed = 0, k;
+        struct stat root_st;
+
+        assert(head);
+
+        k = lstat("/", &root_st);
+
+        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+                int r;
+                struct stat loopback_st;
+
+                if (k >= 0 &&
+                    major(root_st.st_dev) != 0 &&
+                    lstat(m->path, &loopback_st) >= 0 &&
+                    root_st.st_dev == loopback_st.st_rdev) {
+                        n_failed ++;
+                        continue;
+                }
+
+                log_info("Detaching loopback %s.", m->path);
+                r = delete_loopback(m->path);
+                if (r >= 0) {
+                        if (r > 0 && changed)
+                                *changed = true;
+
+                        mount_point_free(head, m);
+                } else {
+                        log_warning("Could not detach loopback %s: %m", m->path);
+                        n_failed++;
+                }
+        }
+
+        return n_failed;
+}
+
+static int dm_points_list_detach(MountPoint **head, bool *changed) {
+        MountPoint *m, *n;
+        int n_failed = 0, k;
+        struct stat root_st;
+
+        assert(head);
+
+        k = lstat("/", &root_st);
+
+        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+                int r;
+
+                if (k >= 0 &&
+                    major(root_st.st_dev) != 0 &&
+                    root_st.st_dev == m->devnum) {
+                        n_failed ++;
+                        continue;
+                }
+
+                log_info("Detaching DM %u:%u.", major(m->devnum), minor(m->devnum));
+                r = delete_dm(m->devnum);
+                if (r >= 0) {
+                        if (changed)
+                                *changed = true;
+
+                        mount_point_free(head, m);
+                } else {
+                        log_warning("Could not detach DM %s: %m", m->path);
+                        n_failed++;
+                }
+        }
+
+        return n_failed;
+}
+
+int umount_all(bool *changed) {
+        int r;
+        bool umount_changed;
+        LIST_HEAD(MountPoint, mp_list_head);
+
+        LIST_HEAD_INIT(MountPoint, mp_list_head);
+        r = mount_points_list_get(&mp_list_head);
+        if (r < 0)
+                goto end;
+
+        /* retry umount, until nothing can be umounted anymore */
+        do {
+                umount_changed = false;
+
+                mount_points_list_umount(&mp_list_head, &umount_changed, false);
+                if (umount_changed)
+                        *changed = true;
+
+        } while (umount_changed);
+
+        /* umount one more time with logging enabled */
+        r = mount_points_list_umount(&mp_list_head, &umount_changed, true);
+        if (r <= 0)
+                goto end;
+
+  end:
+        mount_points_list_free(&mp_list_head);
+
+        return r;
+}
+
+int swapoff_all(bool *changed) {
+        int r;
+        LIST_HEAD(MountPoint, swap_list_head);
+
+        LIST_HEAD_INIT(MountPoint, swap_list_head);
+
+        r = swap_list_get(&swap_list_head);
+        if (r < 0)
+                goto end;
+
+        r = swap_points_list_off(&swap_list_head, changed);
+
+  end:
+        mount_points_list_free(&swap_list_head);
+
+        return r;
+}
+
+int loopback_detach_all(bool *changed) {
+        int r;
+        LIST_HEAD(MountPoint, loopback_list_head);
+
+        LIST_HEAD_INIT(MountPoint, loopback_list_head);
+
+        r = loopback_list_get(&loopback_list_head);
+        if (r < 0)
+                goto end;
+
+        r = loopback_points_list_detach(&loopback_list_head, changed);
+
+  end:
+        mount_points_list_free(&loopback_list_head);
+
+        return r;
+}
+
+int dm_detach_all(bool *changed) {
+        int r;
+        LIST_HEAD(MountPoint, dm_list_head);
+
+        LIST_HEAD_INIT(MountPoint, dm_list_head);
+
+        r = dm_list_get(&dm_list_head);
+        if (r < 0)
+                goto end;
+
+        r = dm_points_list_detach(&dm_list_head, changed);
+
+  end:
+        mount_points_list_free(&dm_list_head);
+
+        return r;
+}
diff --git a/src/core/umount.h b/src/core/umount.h
new file mode 100644 (file)
index 0000000..8439ffe
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 ProFUSION embedded systems
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int umount_all(bool *changed);
+
+int swapoff_all(bool *changed);
+
+int loopback_detach_all(bool *changed);
+
+int dm_detach_all(bool *changed);
diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c
new file mode 100644 (file)
index 0000000..a58c96c
--- /dev/null
@@ -0,0 +1,353 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "systemd/sd-id128.h"
+#include "unit.h"
+#include "specifier.h"
+#include "path-util.h"
+#include "strv.h"
+#include "unit-name.h"
+#include "unit-printf.h"
+
+static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        assert(u);
+
+        return unit_name_to_prefix_and_instance(u->id);
+}
+
+static char *specifier_prefix(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        assert(u);
+
+        return unit_name_to_prefix(u->id);
+}
+
+static char *specifier_prefix_unescaped(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        char *p, *r;
+
+        assert(u);
+
+        p = unit_name_to_prefix(u->id);
+        if (!p)
+                return NULL;
+
+        r = unit_name_unescape(p);
+        free(p);
+
+        return r;
+}
+
+static char *specifier_instance_unescaped(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        assert(u);
+
+        if (u->instance)
+                return unit_name_unescape(u->instance);
+
+        return strdup("");
+}
+
+static char *specifier_filename(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        assert(u);
+
+        if (u->instance)
+                return unit_name_path_unescape(u->instance);
+
+        return unit_name_to_path(u->id);
+}
+
+static char *specifier_cgroup(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        assert(u);
+
+        return unit_default_cgroup_path(u);
+}
+
+static char *specifier_cgroup_root(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        char *p;
+        assert(u);
+
+        if (specifier == 'r')
+                return strdup(u->manager->cgroup_hierarchy);
+
+        if (path_get_parent(u->manager->cgroup_hierarchy, &p) < 0)
+                return strdup("");
+
+        if (streq(p, "/")) {
+                free(p);
+                return strdup("");
+        }
+
+        return p;
+}
+
+static char *specifier_runtime(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        assert(u);
+
+        if (u->manager->running_as == SYSTEMD_USER) {
+                const char *e;
+
+                e = getenv("XDG_RUNTIME_DIR");
+                if (e)
+                        return strdup(e);
+        }
+
+        return strdup("/run");
+}
+
+static char *specifier_user_name(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        ExecContext *c;
+        int r;
+        const char *username;
+        uid_t uid;
+        char *printed = NULL;
+
+        assert(u);
+
+        c = unit_get_exec_context(u);
+
+        /* get USER env from our own env if set */
+        if (!c || !c->user)
+                return getusername_malloc();
+
+        /* fish username from passwd */
+        username = c->user;
+        r = get_user_creds(&username, &uid, NULL, NULL, NULL);
+        if (r < 0)
+                return NULL;
+
+        switch (specifier) {
+                case 'U':
+                        if (asprintf(&printed, "%d", uid) < 0)
+                                return NULL;
+                        break;
+                case 'u':
+                        printed = strdup(username);
+                        break;
+        }
+
+        return printed;
+}
+
+static char *specifier_user_home(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        ExecContext *c;
+        int r;
+        const char *username, *home;
+
+        assert(u);
+
+        c = unit_get_exec_context(u);
+
+        /* return HOME if set, otherwise from passwd */
+        if (!c || !c->user) {
+                char *h;
+
+                r = get_home_dir(&h);
+                if (r < 0)
+                        return NULL;
+
+                return h;
+        }
+
+        username = c->user;
+        r = get_user_creds(&username, NULL, NULL, &home, NULL);
+        if (r < 0)
+               return NULL;
+
+        return strdup(home);
+}
+
+static char *specifier_user_shell(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        ExecContext *c;
+        int r;
+        const char *username, *shell;
+
+        assert(u);
+
+        c = unit_get_exec_context(u);
+
+        /* return HOME if set, otherwise from passwd */
+        if (!c || !c->user) {
+                char *sh;
+
+                r = get_shell(&sh);
+                if (r < 0)
+                        return strdup("/bin/sh");
+
+                return sh;
+        }
+
+        username = c->user;
+        r = get_user_creds(&username, NULL, NULL, NULL, &shell);
+        if (r < 0)
+                return strdup("/bin/sh");
+
+        return strdup(shell);
+}
+
+static char *specifier_machine_id(char specifier, void *data, void *userdata) {
+        sd_id128_t id;
+        char *buf;
+        int r;
+
+        r = sd_id128_get_machine(&id);
+        if (r < 0)
+                return NULL;
+
+        buf = new(char, 33);
+        if (!buf)
+                return NULL;
+
+        return sd_id128_to_string(id, buf);
+}
+
+static char *specifier_boot_id(char specifier, void *data, void *userdata) {
+        sd_id128_t id;
+        char *buf;
+        int r;
+
+        r = sd_id128_get_boot(&id);
+        if (r < 0)
+                return NULL;
+
+        buf = new(char, 33);
+        if (!buf)
+                return NULL;
+
+        return sd_id128_to_string(id, buf);
+}
+
+static char *specifier_host_name(char specifier, void *data, void *userdata) {
+        return gethostname_malloc();
+}
+
+char *unit_name_printf(Unit *u, const char* format) {
+
+        /*
+         * This will use the passed string as format string and
+         * replace the following specifiers:
+         *
+         * %n: the full id of the unit                 (foo@bar.waldo)
+         * %N: the id of the unit without the suffix   (foo@bar)
+         * %p: the prefix                              (foo)
+         * %i: the instance                            (bar)
+         */
+
+        const Specifier table[] = {
+                { 'n', specifier_string,              u->id },
+                { 'N', specifier_prefix_and_instance, NULL },
+                { 'p', specifier_prefix,              NULL },
+                { 'i', specifier_string,              u->instance },
+                { 0, NULL, NULL }
+        };
+
+        assert(u);
+        assert(format);
+
+        return specifier_printf(format, table, u);
+}
+
+char *unit_full_printf(Unit *u, const char *format) {
+
+        /* This is similar to unit_name_printf() but also supports
+         * unescaping. Also, adds a couple of additional codes:
+         *
+         * %f the the instance if set, otherwise the id
+         * %c cgroup path of unit
+         * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711")
+         * %R parent of root cgroup path (e.g. "/usr/lennart/shared")
+         * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
+         * %u the username of the configured user or running user
+         * %h the homedir of the configured user or running user
+         * %s the shell of the configured user or running user
+         * %m the machine ID of the running system
+         * %b the boot ID of the running system
+         * %H the host name of the running system
+         */
+
+        const Specifier table[] = {
+                { 'n', specifier_string,              u->id },
+                { 'N', specifier_prefix_and_instance, NULL },
+                { 'p', specifier_prefix,              NULL },
+                { 'P', specifier_prefix_unescaped,    NULL },
+                { 'i', specifier_string,              u->instance },
+                { 'I', specifier_instance_unescaped,  NULL },
+
+                { 'f', specifier_filename,            NULL },
+                { 'c', specifier_cgroup,              NULL },
+                { 'r', specifier_cgroup_root,         NULL },
+                { 'R', specifier_cgroup_root,         NULL },
+                { 't', specifier_runtime,             NULL },
+                { 'U', specifier_user_name,           NULL },
+                { 'u', specifier_user_name,           NULL },
+                { 'h', specifier_user_home,           NULL },
+                { 's', specifier_user_shell,          NULL },
+
+                { 'm', specifier_machine_id,          NULL },
+                { 'H', specifier_host_name,           NULL },
+                { 'b', specifier_boot_id,             NULL },
+                { 0, NULL, NULL }
+        };
+
+        assert(u);
+        assert(format);
+
+        return specifier_printf(format, table, u);
+}
+
+char **unit_full_printf_strv(Unit *u, char **l) {
+        size_t n;
+        char **r, **i, **j;
+
+        /* Applies unit_full_printf to every entry in l */
+
+        assert(u);
+
+        n = strv_length(l);
+        r = new(char*, n+1);
+        if (!r)
+                return NULL;
+
+        for (i = l, j = r; *i; i++, j++) {
+                *j = unit_full_printf(u, *i);
+                if (!*j)
+                        goto fail;
+        }
+
+        *j = NULL;
+        return r;
+
+fail:
+        for (j--; j >= r; j--)
+                free(*j);
+
+        free(r);
+
+        return NULL;
+}
diff --git a/src/core/unit-printf.h b/src/core/unit-printf.h
new file mode 100644 (file)
index 0000000..d2f4ccd
--- /dev/null
@@ -0,0 +1,28 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "unit.h"
+
+char *unit_name_printf(Unit *u, const char* text);
+char *unit_full_printf(Unit *u, const char *text);
+char **unit_full_printf_strv(Unit *u, char **l);
diff --git a/src/core/unit.c b/src/core/unit.c
new file mode 100644 (file)
index 0000000..45453dc
--- /dev/null
@@ -0,0 +1,2739 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <sys/poll.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "systemd/sd-id128.h"
+#include "systemd/sd-messages.h"
+#include "set.h"
+#include "unit.h"
+#include "macro.h"
+#include "strv.h"
+#include "path-util.h"
+#include "load-fragment.h"
+#include "load-dropin.h"
+#include "log.h"
+#include "unit-name.h"
+#include "dbus-unit.h"
+#include "special.h"
+#include "cgroup-util.h"
+#include "missing.h"
+#include "cgroup-attr.h"
+
+const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
+        [UNIT_SERVICE] = &service_vtable,
+        [UNIT_TIMER] = &timer_vtable,
+        [UNIT_SOCKET] = &socket_vtable,
+        [UNIT_TARGET] = &target_vtable,
+        [UNIT_DEVICE] = &device_vtable,
+        [UNIT_MOUNT] = &mount_vtable,
+        [UNIT_AUTOMOUNT] = &automount_vtable,
+        [UNIT_SNAPSHOT] = &snapshot_vtable,
+        [UNIT_SWAP] = &swap_vtable,
+        [UNIT_PATH] = &path_vtable
+};
+
+Unit *unit_new(Manager *m, size_t size) {
+        Unit *u;
+
+        assert(m);
+        assert(size >= sizeof(Unit));
+
+        u = malloc0(size);
+        if (!u)
+                return NULL;
+
+        u->names = set_new(string_hash_func, string_compare_func);
+        if (!u->names) {
+                free(u);
+                return NULL;
+        }
+
+        u->manager = m;
+        u->type = _UNIT_TYPE_INVALID;
+        u->deserialized_job = _JOB_TYPE_INVALID;
+        u->default_dependencies = true;
+        u->unit_file_state = _UNIT_FILE_STATE_INVALID;
+
+        return u;
+}
+
+bool unit_has_name(Unit *u, const char *name) {
+        assert(u);
+        assert(name);
+
+        return !!set_get(u->names, (char*) name);
+}
+
+int unit_add_name(Unit *u, const char *text) {
+        UnitType t;
+        char *s, *i = NULL;
+        int r;
+
+        assert(u);
+        assert(text);
+
+        if (unit_name_is_template(text)) {
+                if (!u->instance)
+                        return -EINVAL;
+
+                s = unit_name_replace_instance(text, u->instance);
+        } else
+                s = strdup(text);
+
+        if (!s)
+                return -ENOMEM;
+
+        if (!unit_name_is_valid(s, false)) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        assert_se((t = unit_name_to_type(s)) >= 0);
+
+        if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        if ((r = unit_name_to_instance(s, &i)) < 0)
+                goto fail;
+
+        if (i && unit_vtable[t]->no_instances) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        /* Ensure that this unit is either instanced or not instanced,
+         * but not both. */
+        if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        if (unit_vtable[t]->no_alias &&
+            !set_isempty(u->names) &&
+            !set_get(u->names, s)) {
+                r = -EEXIST;
+                goto fail;
+        }
+
+        if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
+                r = -E2BIG;
+                goto fail;
+        }
+
+        if ((r = set_put(u->names, s)) < 0) {
+                if (r == -EEXIST)
+                        r = 0;
+                goto fail;
+        }
+
+        if ((r = hashmap_put(u->manager->units, s, u)) < 0) {
+                set_remove(u->names, s);
+                goto fail;
+        }
+
+        if (u->type == _UNIT_TYPE_INVALID) {
+
+                u->type = t;
+                u->id = s;
+                u->instance = i;
+
+                LIST_PREPEND(Unit, units_by_type, u->manager->units_by_type[t], u);
+
+                if (UNIT_VTABLE(u)->init)
+                        UNIT_VTABLE(u)->init(u);
+        } else
+                free(i);
+
+        unit_add_to_dbus_queue(u);
+        return 0;
+
+fail:
+        free(s);
+        free(i);
+
+        return r;
+}
+
+int unit_choose_id(Unit *u, const char *name) {
+        char *s, *t = NULL, *i;
+        int r;
+
+        assert(u);
+        assert(name);
+
+        if (unit_name_is_template(name)) {
+
+                if (!u->instance)
+                        return -EINVAL;
+
+                if (!(t = unit_name_replace_instance(name, u->instance)))
+                        return -ENOMEM;
+
+                name = t;
+        }
+
+        /* Selects one of the names of this unit as the id */
+        s = set_get(u->names, (char*) name);
+        free(t);
+
+        if (!s)
+                return -ENOENT;
+
+        if ((r = unit_name_to_instance(s, &i)) < 0)
+                return r;
+
+        u->id = s;
+
+        free(u->instance);
+        u->instance = i;
+
+        unit_add_to_dbus_queue(u);
+
+        return 0;
+}
+
+int unit_set_description(Unit *u, const char *description) {
+        char *s;
+
+        assert(u);
+
+        if (!(s = strdup(description)))
+                return -ENOMEM;
+
+        free(u->description);
+        u->description = s;
+
+        unit_add_to_dbus_queue(u);
+        return 0;
+}
+
+bool unit_check_gc(Unit *u) {
+        assert(u);
+
+        if (u->load_state == UNIT_STUB)
+                return true;
+
+        if (UNIT_VTABLE(u)->no_gc)
+                return true;
+
+        if (u->no_gc)
+                return true;
+
+        if (u->job)
+                return true;
+
+        if (u->nop_job)
+                return true;
+
+        if (unit_active_state(u) != UNIT_INACTIVE)
+                return true;
+
+        if (u->refs)
+                return true;
+
+        if (UNIT_VTABLE(u)->check_gc)
+                if (UNIT_VTABLE(u)->check_gc(u))
+                        return true;
+
+        return false;
+}
+
+void unit_add_to_load_queue(Unit *u) {
+        assert(u);
+        assert(u->type != _UNIT_TYPE_INVALID);
+
+        if (u->load_state != UNIT_STUB || u->in_load_queue)
+                return;
+
+        LIST_PREPEND(Unit, load_queue, u->manager->load_queue, u);
+        u->in_load_queue = true;
+}
+
+void unit_add_to_cleanup_queue(Unit *u) {
+        assert(u);
+
+        if (u->in_cleanup_queue)
+                return;
+
+        LIST_PREPEND(Unit, cleanup_queue, u->manager->cleanup_queue, u);
+        u->in_cleanup_queue = true;
+}
+
+void unit_add_to_gc_queue(Unit *u) {
+        assert(u);
+
+        if (u->in_gc_queue || u->in_cleanup_queue)
+                return;
+
+        if (unit_check_gc(u))
+                return;
+
+        LIST_PREPEND(Unit, gc_queue, u->manager->gc_queue, u);
+        u->in_gc_queue = true;
+
+        u->manager->n_in_gc_queue ++;
+
+        if (u->manager->gc_queue_timestamp <= 0)
+                u->manager->gc_queue_timestamp = now(CLOCK_MONOTONIC);
+}
+
+void unit_add_to_dbus_queue(Unit *u) {
+        assert(u);
+        assert(u->type != _UNIT_TYPE_INVALID);
+
+        if (u->load_state == UNIT_STUB || u->in_dbus_queue)
+                return;
+
+        /* Shortcut things if nobody cares */
+        if (!bus_has_subscriber(u->manager)) {
+                u->sent_dbus_new_signal = true;
+                return;
+        }
+
+        LIST_PREPEND(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
+        u->in_dbus_queue = true;
+}
+
+static void bidi_set_free(Unit *u, Set *s) {
+        Iterator i;
+        Unit *other;
+
+        assert(u);
+
+        /* Frees the set and makes sure we are dropped from the
+         * inverse pointers */
+
+        SET_FOREACH(other, s, i) {
+                UnitDependency d;
+
+                for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
+                        set_remove(other->dependencies[d], u);
+
+                unit_add_to_gc_queue(other);
+        }
+
+        set_free(s);
+}
+
+void unit_free(Unit *u) {
+        UnitDependency d;
+        Iterator i;
+        char *t;
+
+        assert(u);
+
+        bus_unit_send_removed_signal(u);
+
+        if (u->load_state != UNIT_STUB)
+                if (UNIT_VTABLE(u)->done)
+                        UNIT_VTABLE(u)->done(u);
+
+        SET_FOREACH(t, u->names, i)
+                hashmap_remove_value(u->manager->units, t, u);
+
+        if (u->job) {
+                Job *j = u->job;
+                job_uninstall(j);
+                job_free(j);
+        }
+
+        if (u->nop_job) {
+                Job *j = u->nop_job;
+                job_uninstall(j);
+                job_free(j);
+        }
+
+        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
+                bidi_set_free(u, u->dependencies[d]);
+
+        if (u->requires_mounts_for) {
+                LIST_REMOVE(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
+                strv_free(u->requires_mounts_for);
+        }
+
+        if (u->type != _UNIT_TYPE_INVALID)
+                LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u);
+
+        if (u->in_load_queue)
+                LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
+
+        if (u->in_dbus_queue)
+                LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
+
+        if (u->in_cleanup_queue)
+                LIST_REMOVE(Unit, cleanup_queue, u->manager->cleanup_queue, u);
+
+        if (u->in_gc_queue) {
+                LIST_REMOVE(Unit, gc_queue, u->manager->gc_queue, u);
+                u->manager->n_in_gc_queue--;
+        }
+
+        cgroup_bonding_free_list(u->cgroup_bondings, u->manager->n_reloading <= 0);
+        cgroup_attribute_free_list(u->cgroup_attributes);
+
+        free(u->description);
+        strv_free(u->documentation);
+        free(u->fragment_path);
+        free(u->source_path);
+        free(u->instance);
+
+        set_free_free(u->names);
+
+        condition_free_list(u->conditions);
+
+        while (u->refs)
+                unit_ref_unset(u->refs);
+
+        free(u);
+}
+
+UnitActiveState unit_active_state(Unit *u) {
+        assert(u);
+
+        if (u->load_state == UNIT_MERGED)
+                return unit_active_state(unit_follow_merge(u));
+
+        /* After a reload it might happen that a unit is not correctly
+         * loaded but still has a process around. That's why we won't
+         * shortcut failed loading to UNIT_INACTIVE_FAILED. */
+
+        return UNIT_VTABLE(u)->active_state(u);
+}
+
+const char* unit_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return UNIT_VTABLE(u)->sub_state_to_string(u);
+}
+
+static void complete_move(Set **s, Set **other) {
+        assert(s);
+        assert(other);
+
+        if (!*other)
+                return;
+
+        if (*s)
+                set_move(*s, *other);
+        else {
+                *s = *other;
+                *other = NULL;
+        }
+}
+
+static void merge_names(Unit *u, Unit *other) {
+        char *t;
+        Iterator i;
+
+        assert(u);
+        assert(other);
+
+        complete_move(&u->names, &other->names);
+
+        set_free_free(other->names);
+        other->names = NULL;
+        other->id = NULL;
+
+        SET_FOREACH(t, u->names, i)
+                assert_se(hashmap_replace(u->manager->units, t, u) == 0);
+}
+
+static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
+        Iterator i;
+        Unit *back;
+        int r;
+
+        assert(u);
+        assert(other);
+        assert(d < _UNIT_DEPENDENCY_MAX);
+
+        /* Fix backwards pointers */
+        SET_FOREACH(back, other->dependencies[d], i) {
+                UnitDependency k;
+
+                for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++)
+                        if ((r = set_remove_and_put(back->dependencies[k], other, u)) < 0) {
+
+                                if (r == -EEXIST)
+                                        set_remove(back->dependencies[k], other);
+                                else
+                                        assert(r == -ENOENT);
+                        }
+        }
+
+        complete_move(&u->dependencies[d], &other->dependencies[d]);
+
+        set_free(other->dependencies[d]);
+        other->dependencies[d] = NULL;
+}
+
+int unit_merge(Unit *u, Unit *other) {
+        UnitDependency d;
+
+        assert(u);
+        assert(other);
+        assert(u->manager == other->manager);
+        assert(u->type != _UNIT_TYPE_INVALID);
+
+        other = unit_follow_merge(other);
+
+        if (other == u)
+                return 0;
+
+        if (u->type != other->type)
+                return -EINVAL;
+
+        if (!u->instance != !other->instance)
+                return -EINVAL;
+
+        if (other->load_state != UNIT_STUB &&
+            other->load_state != UNIT_ERROR)
+                return -EEXIST;
+
+        if (other->job)
+                return -EEXIST;
+
+        if (other->nop_job)
+                return -EEXIST;
+
+        if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
+                return -EEXIST;
+
+        /* Merge names */
+        merge_names(u, other);
+
+        /* Redirect all references */
+        while (other->refs)
+                unit_ref_set(other->refs, u);
+
+        /* Merge dependencies */
+        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
+                merge_dependencies(u, other, d);
+
+        other->load_state = UNIT_MERGED;
+        other->merged_into = u;
+
+        /* If there is still some data attached to the other node, we
+         * don't need it anymore, and can free it. */
+        if (other->load_state != UNIT_STUB)
+                if (UNIT_VTABLE(other)->done)
+                        UNIT_VTABLE(other)->done(other);
+
+        unit_add_to_dbus_queue(u);
+        unit_add_to_cleanup_queue(other);
+
+        return 0;
+}
+
+int unit_merge_by_name(Unit *u, const char *name) {
+        Unit *other;
+        int r;
+        char *s = NULL;
+
+        assert(u);
+        assert(name);
+
+        if (unit_name_is_template(name)) {
+                if (!u->instance)
+                        return -EINVAL;
+
+                if (!(s = unit_name_replace_instance(name, u->instance)))
+                        return -ENOMEM;
+
+                name = s;
+        }
+
+        if (!(other = manager_get_unit(u->manager, name)))
+                r = unit_add_name(u, name);
+        else
+                r = unit_merge(u, other);
+
+        free(s);
+        return r;
+}
+
+Unit* unit_follow_merge(Unit *u) {
+        assert(u);
+
+        while (u->load_state == UNIT_MERGED)
+                assert_se(u = u->merged_into);
+
+        return u;
+}
+
+int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
+        int r;
+
+        assert(u);
+        assert(c);
+
+        if (c->std_output != EXEC_OUTPUT_KMSG &&
+            c->std_output != EXEC_OUTPUT_SYSLOG &&
+            c->std_output != EXEC_OUTPUT_JOURNAL &&
+            c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
+            c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
+            c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
+            c->std_error != EXEC_OUTPUT_KMSG &&
+            c->std_error != EXEC_OUTPUT_SYSLOG &&
+            c->std_error != EXEC_OUTPUT_JOURNAL &&
+            c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
+            c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
+            c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
+                return 0;
+
+        /* If syslog or kernel logging is requested, make sure our own
+         * logging daemon is run first. */
+
+        if (u->manager->running_as == SYSTEMD_SYSTEM)
+                if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true)) < 0)
+                        return r;
+
+        return 0;
+}
+
+const char *unit_description(Unit *u) {
+        assert(u);
+
+        if (u->description)
+                return u->description;
+
+        return strna(u->id);
+}
+
+void unit_dump(Unit *u, FILE *f, const char *prefix) {
+        char *t, **j;
+        UnitDependency d;
+        Iterator i;
+        char *p2;
+        const char *prefix2;
+        char
+                timestamp1[FORMAT_TIMESTAMP_MAX],
+                timestamp2[FORMAT_TIMESTAMP_MAX],
+                timestamp3[FORMAT_TIMESTAMP_MAX],
+                timestamp4[FORMAT_TIMESTAMP_MAX],
+                timespan[FORMAT_TIMESPAN_MAX];
+        Unit *following;
+
+        assert(u);
+        assert(u->type >= 0);
+
+        if (!prefix)
+                prefix = "";
+        p2 = strappend(prefix, "\t");
+        prefix2 = p2 ? p2 : prefix;
+
+        fprintf(f,
+                "%s-> Unit %s:\n"
+                "%s\tDescription: %s\n"
+                "%s\tInstance: %s\n"
+                "%s\tUnit Load State: %s\n"
+                "%s\tUnit Active State: %s\n"
+                "%s\tInactive Exit Timestamp: %s\n"
+                "%s\tActive Enter Timestamp: %s\n"
+                "%s\tActive Exit Timestamp: %s\n"
+                "%s\tInactive Enter Timestamp: %s\n"
+                "%s\tGC Check Good: %s\n"
+                "%s\tNeed Daemon Reload: %s\n",
+                prefix, u->id,
+                prefix, unit_description(u),
+                prefix, strna(u->instance),
+                prefix, unit_load_state_to_string(u->load_state),
+                prefix, unit_active_state_to_string(unit_active_state(u)),
+                prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
+                prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
+                prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
+                prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
+                prefix, yes_no(unit_check_gc(u)),
+                prefix, yes_no(unit_need_daemon_reload(u)));
+
+        SET_FOREACH(t, u->names, i)
+                fprintf(f, "%s\tName: %s\n", prefix, t);
+
+        STRV_FOREACH(j, u->documentation)
+                fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
+
+        if ((following = unit_following(u)))
+                fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
+
+        if (u->fragment_path)
+                fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
+
+        if (u->source_path)
+                fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
+
+        if (u->job_timeout > 0)
+                fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout));
+
+        condition_dump_list(u->conditions, f, prefix);
+
+        if (dual_timestamp_is_set(&u->condition_timestamp))
+                fprintf(f,
+                        "%s\tCondition Timestamp: %s\n"
+                        "%s\tCondition Result: %s\n",
+                        prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
+                        prefix, yes_no(u->condition_result));
+
+        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
+                Unit *other;
+
+                SET_FOREACH(other, u->dependencies[d], i)
+                        fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
+        }
+
+        if (!strv_isempty(u->requires_mounts_for)) {
+                fprintf(f,
+                        "%s\tRequiresMountsFor:", prefix);
+
+                STRV_FOREACH(j, u->requires_mounts_for)
+                        fprintf(f, " %s", *j);
+
+                fputs("\n", f);
+        }
+
+        if (u->load_state == UNIT_LOADED) {
+                CGroupBonding *b;
+                CGroupAttribute *a;
+
+                fprintf(f,
+                        "%s\tStopWhenUnneeded: %s\n"
+                        "%s\tRefuseManualStart: %s\n"
+                        "%s\tRefuseManualStop: %s\n"
+                        "%s\tDefaultDependencies: %s\n"
+                        "%s\tOnFailureIsolate: %s\n"
+                        "%s\tIgnoreOnIsolate: %s\n"
+                        "%s\tIgnoreOnSnapshot: %s\n",
+                        prefix, yes_no(u->stop_when_unneeded),
+                        prefix, yes_no(u->refuse_manual_start),
+                        prefix, yes_no(u->refuse_manual_stop),
+                        prefix, yes_no(u->default_dependencies),
+                        prefix, yes_no(u->on_failure_isolate),
+                        prefix, yes_no(u->ignore_on_isolate),
+                        prefix, yes_no(u->ignore_on_snapshot));
+
+                LIST_FOREACH(by_unit, b, u->cgroup_bondings)
+                        fprintf(f, "%s\tControlGroup: %s:%s\n",
+                                prefix, b->controller, b->path);
+
+                LIST_FOREACH(by_unit, a, u->cgroup_attributes) {
+                        char *v = NULL;
+
+                        if (a->map_callback)
+                                a->map_callback(a->controller, a->name, a->value, &v);
+
+                        fprintf(f, "%s\tControlGroupAttribute: %s %s \"%s\"\n",
+                                prefix, a->controller, a->name, v ? v : a->value);
+
+                        free(v);
+                }
+
+                if (UNIT_VTABLE(u)->dump)
+                        UNIT_VTABLE(u)->dump(u, f, prefix2);
+
+        } else if (u->load_state == UNIT_MERGED)
+                fprintf(f,
+                        "%s\tMerged into: %s\n",
+                        prefix, u->merged_into->id);
+        else if (u->load_state == UNIT_ERROR)
+                fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
+
+
+        if (u->job)
+                job_dump(u->job, f, prefix2);
+
+        if (u->nop_job)
+                job_dump(u->nop_job, f, prefix2);
+
+        free(p2);
+}
+
+/* Common implementation for multiple backends */
+int unit_load_fragment_and_dropin(Unit *u) {
+        int r;
+
+        assert(u);
+
+        /* Load a .service file */
+        if ((r = unit_load_fragment(u)) < 0)
+                return r;
+
+        if (u->load_state == UNIT_STUB)
+                return -ENOENT;
+
+        /* Load drop-in directory data */
+        if ((r = unit_load_dropin(unit_follow_merge(u))) < 0)
+                return r;
+
+        return 0;
+}
+
+/* Common implementation for multiple backends */
+int unit_load_fragment_and_dropin_optional(Unit *u) {
+        int r;
+
+        assert(u);
+
+        /* Same as unit_load_fragment_and_dropin(), but whether
+         * something can be loaded or not doesn't matter. */
+
+        /* Load a .service file */
+        if ((r = unit_load_fragment(u)) < 0)
+                return r;
+
+        if (u->load_state == UNIT_STUB)
+                u->load_state = UNIT_LOADED;
+
+        /* Load drop-in directory data */
+        if ((r = unit_load_dropin(unit_follow_merge(u))) < 0)
+                return r;
+
+        return 0;
+}
+
+int unit_add_default_target_dependency(Unit *u, Unit *target) {
+        assert(u);
+        assert(target);
+
+        if (target->type != UNIT_TARGET)
+                return 0;
+
+        /* Only add the dependency if both units are loaded, so that
+         * that loop check below is reliable */
+        if (u->load_state != UNIT_LOADED ||
+            target->load_state != UNIT_LOADED)
+                return 0;
+
+        /* If either side wants no automatic dependencies, then let's
+         * skip this */
+        if (!u->default_dependencies ||
+            !target->default_dependencies)
+                return 0;
+
+        /* Don't create loops */
+        if (set_get(target->dependencies[UNIT_BEFORE], u))
+                return 0;
+
+        return unit_add_dependency(target, UNIT_AFTER, u, true);
+}
+
+static int unit_add_default_dependencies(Unit *u) {
+        static const UnitDependency deps[] = {
+                UNIT_REQUIRED_BY,
+                UNIT_REQUIRED_BY_OVERRIDABLE,
+                UNIT_WANTED_BY,
+                UNIT_BOUND_BY
+        };
+
+        Unit *target;
+        Iterator i;
+        int r;
+        unsigned k;
+
+        assert(u);
+
+        for (k = 0; k < ELEMENTSOF(deps); k++)
+                SET_FOREACH(target, u->dependencies[deps[k]], i)
+                        if ((r = unit_add_default_target_dependency(u, target)) < 0)
+                                return r;
+
+        return 0;
+}
+
+int unit_load(Unit *u) {
+        int r;
+
+        assert(u);
+
+        if (u->in_load_queue) {
+                LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
+                u->in_load_queue = false;
+        }
+
+        if (u->type == _UNIT_TYPE_INVALID)
+                return -EINVAL;
+
+        if (u->load_state != UNIT_STUB)
+                return 0;
+
+        if (UNIT_VTABLE(u)->load)
+                if ((r = UNIT_VTABLE(u)->load(u)) < 0)
+                        goto fail;
+
+        if (u->load_state == UNIT_STUB) {
+                r = -ENOENT;
+                goto fail;
+        }
+
+        if (u->load_state == UNIT_LOADED &&
+            u->default_dependencies)
+                if ((r = unit_add_default_dependencies(u)) < 0)
+                        goto fail;
+
+        if (u->load_state == UNIT_LOADED) {
+                r = unit_add_mount_links(u);
+                if (r < 0)
+                        return r;
+        }
+
+        if (u->on_failure_isolate &&
+            set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
+
+                log_error("More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.",
+                          u->id);
+
+                r = -EINVAL;
+                goto fail;
+        }
+
+        assert((u->load_state != UNIT_MERGED) == !u->merged_into);
+
+        unit_add_to_dbus_queue(unit_follow_merge(u));
+        unit_add_to_gc_queue(u);
+
+        return 0;
+
+fail:
+        u->load_state = UNIT_ERROR;
+        u->load_error = r;
+        unit_add_to_dbus_queue(u);
+        unit_add_to_gc_queue(u);
+
+        log_debug("Failed to load configuration for %s: %s", u->id, strerror(-r));
+
+        return r;
+}
+
+bool unit_condition_test(Unit *u) {
+        assert(u);
+
+        dual_timestamp_get(&u->condition_timestamp);
+        u->condition_result = condition_test_list(u->conditions);
+
+        return u->condition_result;
+}
+
+static const char* unit_get_status_message_format(Unit *u, JobType t) {
+        const UnitStatusMessageFormats *format_table;
+
+        assert(u);
+        assert(t >= 0);
+        assert(t < _JOB_TYPE_MAX);
+
+        if (t != JOB_START && t != JOB_STOP)
+                return NULL;
+
+        format_table = &UNIT_VTABLE(u)->status_message_formats;
+        if (!format_table)
+                return NULL;
+
+        return format_table->starting_stopping[t == JOB_STOP];
+}
+
+static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
+        const char *format;
+
+        assert(u);
+        assert(t >= 0);
+        assert(t < _JOB_TYPE_MAX);
+
+        format = unit_get_status_message_format(u, t);
+        if (format)
+                return format;
+
+        /* Return generic strings */
+        if (t == JOB_START)
+                return "Starting %s.";
+        else if (t == JOB_STOP)
+                return "Stopping %s.";
+        else if (t == JOB_RELOAD)
+                return "Reloading %s.";
+
+        return NULL;
+}
+
+static void unit_status_print_starting_stopping(Unit *u, JobType t) {
+        const char *format;
+
+        assert(u);
+
+        /* We only print status messages for selected units on
+         * selected operations. */
+
+        format = unit_get_status_message_format(u, t);
+        if (!format)
+                return;
+
+        unit_status_printf(u, "", format, unit_description(u));
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
+        const char *format;
+        char buf[LINE_MAX];
+        sd_id128_t mid;
+
+        assert(u);
+
+        if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
+                return;
+
+        if (log_on_console())
+                return;
+
+        /* We log status messages for all units and all operations. */
+
+        format = unit_get_status_message_format_try_harder(u, t);
+        if (!format)
+                return;
+
+        snprintf(buf, sizeof(buf), format, unit_description(u));
+        char_array_0(buf);
+
+        mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
+              t == JOB_STOP  ? SD_MESSAGE_UNIT_STOPPING :
+                               SD_MESSAGE_UNIT_RELOADING;
+
+        log_struct(LOG_INFO,
+                   MESSAGE_ID(mid),
+                   "UNIT=%s", u->id,
+                   "MESSAGE=%s", buf,
+                   NULL);
+}
+#pragma GCC diagnostic pop
+
+/* Errors:
+ *         -EBADR:     This unit type does not support starting.
+ *         -EALREADY:  Unit is already started.
+ *         -EAGAIN:    An operation is already in progress. Retry later.
+ *         -ECANCELED: Too many requests for now.
+ */
+int unit_start(Unit *u) {
+        UnitActiveState state;
+        Unit *following;
+
+        assert(u);
+
+        if (u->load_state != UNIT_LOADED)
+                return -EINVAL;
+
+        /* If this is already started, then this will succeed. Note
+         * that this will even succeed if this unit is not startable
+         * by the user. This is relied on to detect when we need to
+         * wait for units and when waiting is finished. */
+        state = unit_active_state(u);
+        if (UNIT_IS_ACTIVE_OR_RELOADING(state))
+                return -EALREADY;
+
+        /* If the conditions failed, don't do anything at all. If we
+         * already are activating this call might still be useful to
+         * speed up activation in case there is some hold-off time,
+         * but we don't want to recheck the condition in that case. */
+        if (state != UNIT_ACTIVATING &&
+            !unit_condition_test(u)) {
+                log_debug("Starting of %s requested but condition failed. Ignoring.", u->id);
+                return -EALREADY;
+        }
+
+        /* Forward to the main object, if we aren't it. */
+        if ((following = unit_following(u))) {
+                log_debug("Redirecting start request from %s to %s.", u->id, following->id);
+                return unit_start(following);
+        }
+
+        unit_status_log_starting_stopping_reloading(u, JOB_START);
+        unit_status_print_starting_stopping(u, JOB_START);
+
+        /* If it is stopped, but we cannot start it, then fail */
+        if (!UNIT_VTABLE(u)->start)
+                return -EBADR;
+
+        /* We don't suppress calls to ->start() here when we are
+         * already starting, to allow this request to be used as a
+         * "hurry up" call, for example when the unit is in some "auto
+         * restart" state where it waits for a holdoff timer to elapse
+         * before it will start again. */
+
+        unit_add_to_dbus_queue(u);
+
+        return UNIT_VTABLE(u)->start(u);
+}
+
+bool unit_can_start(Unit *u) {
+        assert(u);
+
+        return !!UNIT_VTABLE(u)->start;
+}
+
+bool unit_can_isolate(Unit *u) {
+        assert(u);
+
+        return unit_can_start(u) &&
+                u->allow_isolate;
+}
+
+/* Errors:
+ *         -EBADR:    This unit type does not support stopping.
+ *         -EALREADY: Unit is already stopped.
+ *         -EAGAIN:   An operation is already in progress. Retry later.
+ */
+int unit_stop(Unit *u) {
+        UnitActiveState state;
+        Unit *following;
+
+        assert(u);
+
+        state = unit_active_state(u);
+        if (UNIT_IS_INACTIVE_OR_FAILED(state))
+                return -EALREADY;
+
+        if ((following = unit_following(u))) {
+                log_debug("Redirecting stop request from %s to %s.", u->id, following->id);
+                return unit_stop(following);
+        }
+
+        unit_status_log_starting_stopping_reloading(u, JOB_STOP);
+        unit_status_print_starting_stopping(u, JOB_STOP);
+
+        if (!UNIT_VTABLE(u)->stop)
+                return -EBADR;
+
+        unit_add_to_dbus_queue(u);
+
+        return UNIT_VTABLE(u)->stop(u);
+}
+
+/* Errors:
+ *         -EBADR:    This unit type does not support reloading.
+ *         -ENOEXEC:  Unit is not started.
+ *         -EAGAIN:   An operation is already in progress. Retry later.
+ */
+int unit_reload(Unit *u) {
+        UnitActiveState state;
+        Unit *following;
+
+        assert(u);
+
+        if (u->load_state != UNIT_LOADED)
+                return -EINVAL;
+
+        if (!unit_can_reload(u))
+                return -EBADR;
+
+        state = unit_active_state(u);
+        if (state == UNIT_RELOADING)
+                return -EALREADY;
+
+        if (state != UNIT_ACTIVE)
+                return -ENOEXEC;
+
+        if ((following = unit_following(u))) {
+                log_debug("Redirecting reload request from %s to %s.", u->id, following->id);
+                return unit_reload(following);
+        }
+
+        unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
+
+        unit_add_to_dbus_queue(u);
+        return UNIT_VTABLE(u)->reload(u);
+}
+
+bool unit_can_reload(Unit *u) {
+        assert(u);
+
+        if (!UNIT_VTABLE(u)->reload)
+                return false;
+
+        if (!UNIT_VTABLE(u)->can_reload)
+                return true;
+
+        return UNIT_VTABLE(u)->can_reload(u);
+}
+
+static void unit_check_unneeded(Unit *u) {
+        Iterator i;
+        Unit *other;
+
+        assert(u);
+
+        /* If this service shall be shut down when unneeded then do
+         * so. */
+
+        if (!u->stop_when_unneeded)
+                return;
+
+        if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
+                return;
+
+        SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
+                if (unit_pending_active(other))
+                        return;
+
+        SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
+                if (unit_pending_active(other))
+                        return;
+
+        SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
+                if (unit_pending_active(other))
+                        return;
+
+        SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
+                if (unit_pending_active(other))
+                        return;
+
+        log_info("Service %s is not needed anymore. Stopping.", u->id);
+
+        /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
+        manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
+}
+
+static void retroactively_start_dependencies(Unit *u) {
+        Iterator i;
+        Unit *other;
+
+        assert(u);
+        assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
+
+        SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
+                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
+                    !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
+
+        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
+                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
+                    !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
+
+        SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
+                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
+                    !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
+
+        SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
+                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
+                    !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
+
+        SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
+                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
+                    !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
+
+        SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
+
+        SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
+}
+
+static void retroactively_stop_dependencies(Unit *u) {
+        Iterator i;
+        Unit *other;
+
+        assert(u);
+        assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
+
+        /* Pull down units which are bound to us recursively if enabled */
+        SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
+}
+
+static void check_unneeded_dependencies(Unit *u) {
+        Iterator i;
+        Unit *other;
+
+        assert(u);
+        assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
+
+        /* Garbage collect services that might not be needed anymore, if enabled */
+        SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        unit_check_unneeded(other);
+        SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        unit_check_unneeded(other);
+        SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        unit_check_unneeded(other);
+        SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        unit_check_unneeded(other);
+        SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        unit_check_unneeded(other);
+        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        unit_check_unneeded(other);
+}
+
+void unit_trigger_on_failure(Unit *u) {
+        Unit *other;
+        Iterator i;
+
+        assert(u);
+
+        if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
+                return;
+
+        log_info("Triggering OnFailure= dependencies of %s.", u->id);
+
+        SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
+                int r;
+
+                if ((r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0)
+                        log_error("Failed to enqueue OnFailure= job: %s", strerror(-r));
+        }
+}
+
+void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
+        bool unexpected;
+
+        assert(u);
+        assert(os < _UNIT_ACTIVE_STATE_MAX);
+        assert(ns < _UNIT_ACTIVE_STATE_MAX);
+
+        /* Note that this is called for all low-level state changes,
+         * even if they might map to the same high-level
+         * UnitActiveState! That means that ns == os is OK an expected
+         * behavior here. For example: if a mount point is remounted
+         * this function will be called too! */
+
+        if (u->manager->n_reloading <= 0) {
+                dual_timestamp ts;
+
+                dual_timestamp_get(&ts);
+
+                if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
+                        u->inactive_exit_timestamp = ts;
+                else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
+                        u->inactive_enter_timestamp = ts;
+
+                if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
+                        u->active_enter_timestamp = ts;
+                else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
+                        u->active_exit_timestamp = ts;
+
+                timer_unit_notify(u, ns);
+                path_unit_notify(u, ns);
+        }
+
+        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
+                cgroup_bonding_trim_list(u->cgroup_bondings, true);
+
+        if (u->job) {
+                unexpected = false;
+
+                if (u->job->state == JOB_WAITING)
+
+                        /* So we reached a different state for this
+                         * job. Let's see if we can run it now if it
+                         * failed previously due to EAGAIN. */
+                        job_add_to_run_queue(u->job);
+
+                /* Let's check whether this state change constitutes a
+                 * finished job, or maybe contradicts a running job and
+                 * hence needs to invalidate jobs. */
+
+                switch (u->job->type) {
+
+                case JOB_START:
+                case JOB_VERIFY_ACTIVE:
+
+                        if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
+                                job_finish_and_invalidate(u->job, JOB_DONE, true);
+                        else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
+                                unexpected = true;
+
+                                if (UNIT_IS_INACTIVE_OR_FAILED(ns))
+                                        job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
+                        }
+
+                        break;
+
+                case JOB_RELOAD:
+                case JOB_RELOAD_OR_START:
+
+                        if (u->job->state == JOB_RUNNING) {
+                                if (ns == UNIT_ACTIVE)
+                                        job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
+                                else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
+                                        unexpected = true;
+
+                                        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
+                                                job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
+                                }
+                        }
+
+                        break;
+
+                case JOB_STOP:
+                case JOB_RESTART:
+                case JOB_TRY_RESTART:
+
+                        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
+                                job_finish_and_invalidate(u->job, JOB_DONE, true);
+                        else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
+                                unexpected = true;
+                                job_finish_and_invalidate(u->job, JOB_FAILED, true);
+                        }
+
+                        break;
+
+                default:
+                        assert_not_reached("Job type unknown");
+                }
+
+        } else
+                unexpected = true;
+
+        if (u->manager->n_reloading <= 0) {
+
+                /* If this state change happened without being
+                 * requested by a job, then let's retroactively start
+                 * or stop dependencies. We skip that step when
+                 * deserializing, since we don't want to create any
+                 * additional jobs just because something is already
+                 * activated. */
+
+                if (unexpected) {
+                        if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
+                                retroactively_start_dependencies(u);
+                        else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
+                                retroactively_stop_dependencies(u);
+                }
+
+                /* stop unneeded units regardless if going down was expected or not */
+                if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
+                        check_unneeded_dependencies(u);
+
+                if (ns != os && ns == UNIT_FAILED) {
+                        log_struct(LOG_NOTICE,
+                                   "MESSAGE=Unit %s entered failed state", u->id,
+                                   "UNIT=%s", u->id,
+                                   NULL);
+                        unit_trigger_on_failure(u);
+                }
+        }
+
+        /* Some names are special */
+        if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
+
+                if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
+                        /* The bus just might have become available,
+                         * hence try to connect to it, if we aren't
+                         * yet connected. */
+                        bus_init(u->manager, true);
+
+                if (u->type == UNIT_SERVICE &&
+                    !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
+                    u->manager->n_reloading <= 0) {
+                        /* Write audit record if we have just finished starting up */
+                        manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, true);
+                        u->in_audit = true;
+                }
+
+                if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
+                        manager_send_unit_plymouth(u->manager, u);
+
+        } else {
+
+                /* We don't care about D-Bus here, since we'll get an
+                 * asynchronous notification for it anyway. */
+
+                if (u->type == UNIT_SERVICE &&
+                    UNIT_IS_INACTIVE_OR_FAILED(ns) &&
+                    !UNIT_IS_INACTIVE_OR_FAILED(os) &&
+                    u->manager->n_reloading <= 0) {
+
+                        /* Hmm, if there was no start record written
+                         * write it now, so that we always have a nice
+                         * pair */
+                        if (!u->in_audit) {
+                                manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
+
+                                if (ns == UNIT_INACTIVE)
+                                        manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, true);
+                        } else
+                                /* Write audit record if we have just finished shutting down */
+                                manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
+
+                        u->in_audit = false;
+                }
+        }
+
+        manager_recheck_journal(u->manager);
+
+        /* Maybe we finished startup and are now ready for being
+         * stopped because unneeded? */
+        unit_check_unneeded(u);
+
+        unit_add_to_dbus_queue(u);
+        unit_add_to_gc_queue(u);
+}
+
+int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
+        struct epoll_event ev;
+
+        assert(u);
+        assert(fd >= 0);
+        assert(w);
+        assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
+
+        zero(ev);
+        ev.data.ptr = w;
+        ev.events = events;
+
+        if (epoll_ctl(u->manager->epoll_fd,
+                      w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
+                      fd,
+                      &ev) < 0)
+                return -errno;
+
+        w->fd = fd;
+        w->type = WATCH_FD;
+        w->data.unit = u;
+
+        return 0;
+}
+
+void unit_unwatch_fd(Unit *u, Watch *w) {
+        assert(u);
+        assert(w);
+
+        if (w->type == WATCH_INVALID)
+                return;
+
+        assert(w->type == WATCH_FD);
+        assert(w->data.unit == u);
+        assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
+
+        w->fd = -1;
+        w->type = WATCH_INVALID;
+        w->data.unit = NULL;
+}
+
+int unit_watch_pid(Unit *u, pid_t pid) {
+        assert(u);
+        assert(pid >= 1);
+
+        /* Watch a specific PID. We only support one unit watching
+         * each PID for now. */
+
+        return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
+}
+
+void unit_unwatch_pid(Unit *u, pid_t pid) {
+        assert(u);
+        assert(pid >= 1);
+
+        hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
+}
+
+int unit_watch_timer(Unit *u, clockid_t clock_id, bool relative, usec_t usec, Watch *w) {
+        struct itimerspec its;
+        int flags, fd;
+        bool ours;
+
+        assert(u);
+        assert(w);
+        assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u));
+
+        /* This will try to reuse the old timer if there is one */
+
+        if (w->type == WATCH_UNIT_TIMER) {
+                assert(w->data.unit == u);
+                assert(w->fd >= 0);
+
+                ours = false;
+                fd = w->fd;
+        } else if (w->type == WATCH_INVALID) {
+
+                ours = true;
+                fd = timerfd_create(clock_id, TFD_NONBLOCK|TFD_CLOEXEC);
+                if (fd < 0)
+                        return -errno;
+        } else
+                assert_not_reached("Invalid watch type");
+
+        zero(its);
+
+        if (usec <= 0) {
+                /* Set absolute time in the past, but not 0, since we
+                 * don't want to disarm the timer */
+                its.it_value.tv_sec = 0;
+                its.it_value.tv_nsec = 1;
+
+                flags = TFD_TIMER_ABSTIME;
+        } else {
+                timespec_store(&its.it_value, usec);
+                flags = relative ? 0 : TFD_TIMER_ABSTIME;
+        }
+
+        /* This will also flush the elapse counter */
+        if (timerfd_settime(fd, flags, &its, NULL) < 0)
+                goto fail;
+
+        if (w->type == WATCH_INVALID) {
+                struct epoll_event ev;
+
+                zero(ev);
+                ev.data.ptr = w;
+                ev.events = EPOLLIN;
+
+                if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
+                        goto fail;
+        }
+
+        w->type = WATCH_UNIT_TIMER;
+        w->fd = fd;
+        w->data.unit = u;
+
+        return 0;
+
+fail:
+        if (ours)
+                close_nointr_nofail(fd);
+
+        return -errno;
+}
+
+void unit_unwatch_timer(Unit *u, Watch *w) {
+        assert(u);
+        assert(w);
+
+        if (w->type == WATCH_INVALID)
+                return;
+
+        assert(w->type == WATCH_UNIT_TIMER);
+        assert(w->data.unit == u);
+        assert(w->fd >= 0);
+
+        assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
+        close_nointr_nofail(w->fd);
+
+        w->fd = -1;
+        w->type = WATCH_INVALID;
+        w->data.unit = NULL;
+}
+
+bool unit_job_is_applicable(Unit *u, JobType j) {
+        assert(u);
+        assert(j >= 0 && j < _JOB_TYPE_MAX);
+
+        switch (j) {
+
+        case JOB_VERIFY_ACTIVE:
+        case JOB_START:
+        case JOB_STOP:
+        case JOB_NOP:
+                return true;
+
+        case JOB_RESTART:
+        case JOB_TRY_RESTART:
+                return unit_can_start(u);
+
+        case JOB_RELOAD:
+                return unit_can_reload(u);
+
+        case JOB_RELOAD_OR_START:
+                return unit_can_reload(u) && unit_can_start(u);
+
+        default:
+                assert_not_reached("Invalid job type");
+        }
+}
+
+int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
+
+        static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
+                [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
+                [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
+                [UNIT_WANTS] = UNIT_WANTED_BY,
+                [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
+                [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
+                [UNIT_BINDS_TO] = UNIT_BOUND_BY,
+                [UNIT_PART_OF] = UNIT_CONSISTS_OF,
+                [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_BOUND_BY] = UNIT_BINDS_TO,
+                [UNIT_CONSISTS_OF] = UNIT_PART_OF,
+                [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
+                [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
+                [UNIT_BEFORE] = UNIT_AFTER,
+                [UNIT_AFTER] = UNIT_BEFORE,
+                [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
+                [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
+                [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
+                [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
+                [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
+                [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
+        };
+        int r, q = 0, v = 0, w = 0;
+
+        assert(u);
+        assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
+        assert(other);
+
+        u = unit_follow_merge(u);
+        other = unit_follow_merge(other);
+
+        /* We won't allow dependencies on ourselves. We will not
+         * consider them an error however. */
+        if (u == other)
+                return 0;
+
+        if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
+                return r;
+
+        if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
+                if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
+                        return r;
+
+        if (add_reference)
+                if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
+                    (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
+                        return r;
+
+        if ((q = set_put(u->dependencies[d], other)) < 0)
+                return q;
+
+        if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
+                if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
+                        r = v;
+                        goto fail;
+                }
+
+        if (add_reference) {
+                if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
+                        r = w;
+                        goto fail;
+                }
+
+                if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
+                        goto fail;
+        }
+
+        unit_add_to_dbus_queue(u);
+        return 0;
+
+fail:
+        if (q > 0)
+                set_remove(u->dependencies[d], other);
+
+        if (v > 0)
+                set_remove(other->dependencies[inverse_table[d]], u);
+
+        if (w > 0)
+                set_remove(u->dependencies[UNIT_REFERENCES], other);
+
+        return r;
+}
+
+int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
+        int r;
+
+        assert(u);
+
+        if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
+                return r;
+
+        if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
+                return r;
+
+        return 0;
+}
+
+static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
+        char *s;
+
+        assert(u);
+        assert(name || path);
+
+        if (!name)
+                name = path_get_file_name(path);
+
+        if (!unit_name_is_template(name)) {
+                *p = NULL;
+                return name;
+        }
+
+        if (u->instance)
+                s = unit_name_replace_instance(name, u->instance);
+        else {
+                char *i;
+
+                if (!(i = unit_name_to_prefix(u->id)))
+                        return NULL;
+
+                s = unit_name_replace_instance(name, i);
+                free(i);
+        }
+
+        if (!s)
+                return NULL;
+
+        *p = s;
+        return s;
+}
+
+int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
+        Unit *other;
+        int r;
+        char *s;
+
+        assert(u);
+        assert(name || path);
+
+        if (!(name = resolve_template(u, name, path, &s)))
+                return -ENOMEM;
+
+        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
+                goto finish;
+
+        r = unit_add_dependency(u, d, other, add_reference);
+
+finish:
+        free(s);
+        return r;
+}
+
+int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
+        Unit *other;
+        int r;
+        char *s;
+
+        assert(u);
+        assert(name || path);
+
+        if (!(name = resolve_template(u, name, path, &s)))
+                return -ENOMEM;
+
+        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
+                goto finish;
+
+        r = unit_add_two_dependencies(u, d, e, other, add_reference);
+
+finish:
+        free(s);
+        return r;
+}
+
+int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
+        Unit *other;
+        int r;
+        char *s;
+
+        assert(u);
+        assert(name || path);
+
+        if (!(name = resolve_template(u, name, path, &s)))
+                return -ENOMEM;
+
+        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
+                goto finish;
+
+        r = unit_add_dependency(other, d, u, add_reference);
+
+finish:
+        free(s);
+        return r;
+}
+
+int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
+        Unit *other;
+        int r;
+        char *s;
+
+        assert(u);
+        assert(name || path);
+
+        if (!(name = resolve_template(u, name, path, &s)))
+                return -ENOMEM;
+
+        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
+                goto finish;
+
+        if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
+                goto finish;
+
+finish:
+        free(s);
+        return r;
+}
+
+int set_unit_path(const char *p) {
+        char *cwd, *c;
+        int r;
+
+        /* This is mostly for debug purposes */
+
+        if (path_is_absolute(p)) {
+                if (!(c = strdup(p)))
+                        return -ENOMEM;
+        } else {
+                if (!(cwd = get_current_dir_name()))
+                        return -errno;
+
+                r = asprintf(&c, "%s/%s", cwd, p);
+                free(cwd);
+
+                if (r < 0)
+                        return -ENOMEM;
+        }
+
+        if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0) {
+                r = -errno;
+                free(c);
+                return r;
+        }
+
+        return 0;
+}
+
+char *unit_dbus_path(Unit *u) {
+        assert(u);
+
+        if (!u->id)
+                return NULL;
+
+        return unit_dbus_path_from_name(u->id);
+}
+
+int unit_add_cgroup(Unit *u, CGroupBonding *b) {
+        int r;
+
+        assert(u);
+        assert(b);
+
+        assert(b->path);
+
+        if (!b->controller) {
+                if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER)))
+                        return -ENOMEM;
+
+                b->ours = true;
+        }
+
+        /* Ensure this hasn't been added yet */
+        assert(!b->unit);
+
+        if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                CGroupBonding *l;
+
+                l = hashmap_get(u->manager->cgroup_bondings, b->path);
+                LIST_PREPEND(CGroupBonding, by_path, l, b);
+
+                if ((r = hashmap_replace(u->manager->cgroup_bondings, b->path, l)) < 0) {
+                        LIST_REMOVE(CGroupBonding, by_path, l, b);
+                        return r;
+                }
+        }
+
+        LIST_PREPEND(CGroupBonding, by_unit, u->cgroup_bondings, b);
+        b->unit = u;
+
+        return 0;
+}
+
+char *unit_default_cgroup_path(Unit *u) {
+        char *p;
+
+        assert(u);
+
+        if (u->instance) {
+                char *t;
+
+                t = unit_name_template(u->id);
+                if (!t)
+                        return NULL;
+
+                p = strjoin(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL);
+                free(t);
+        } else
+                p = strjoin(u->manager->cgroup_hierarchy, "/", u->id, NULL);
+
+        return p;
+}
+
+int unit_add_cgroup_from_text(Unit *u, const char *name) {
+        char *controller = NULL, *path = NULL;
+        CGroupBonding *b = NULL;
+        bool ours = false;
+        int r;
+
+        assert(u);
+        assert(name);
+
+        if ((r = cg_split_spec(name, &controller, &path)) < 0)
+                return r;
+
+        if (!path) {
+                path = unit_default_cgroup_path(u);
+                ours = true;
+        }
+
+        if (!controller) {
+                controller = strdup(SYSTEMD_CGROUP_CONTROLLER);
+                ours = true;
+        }
+
+        if (!path || !controller) {
+                free(path);
+                free(controller);
+
+                return -ENOMEM;
+        }
+
+        if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) {
+                r = -EEXIST;
+                goto fail;
+        }
+
+        if (!(b = new0(CGroupBonding, 1))) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        b->controller = controller;
+        b->path = path;
+        b->ours = ours;
+        b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
+
+        if ((r = unit_add_cgroup(u, b)) < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        free(path);
+        free(controller);
+        free(b);
+
+        return r;
+}
+
+static int unit_add_one_default_cgroup(Unit *u, const char *controller) {
+        CGroupBonding *b = NULL;
+        int r = -ENOMEM;
+
+        assert(u);
+
+        if (!controller)
+                controller = SYSTEMD_CGROUP_CONTROLLER;
+
+        if (cgroup_bonding_find_list(u->cgroup_bondings, controller))
+                return 0;
+
+        if (!(b = new0(CGroupBonding, 1)))
+                return -ENOMEM;
+
+        if (!(b->controller = strdup(controller)))
+                goto fail;
+
+        b->path = unit_default_cgroup_path(u);
+        if (!b->path)
+                goto fail;
+
+        b->ours = true;
+        b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
+
+        if ((r = unit_add_cgroup(u, b)) < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        free(b->path);
+        free(b->controller);
+        free(b);
+
+        return r;
+}
+
+int unit_add_default_cgroups(Unit *u) {
+        CGroupAttribute *a;
+        char **c;
+        int r;
+
+        assert(u);
+
+        /* Adds in the default cgroups, if they weren't specified
+         * otherwise. */
+
+        if (!u->manager->cgroup_hierarchy)
+                return 0;
+
+        if ((r = unit_add_one_default_cgroup(u, NULL)) < 0)
+                return r;
+
+        STRV_FOREACH(c, u->manager->default_controllers)
+                unit_add_one_default_cgroup(u, *c);
+
+        LIST_FOREACH(by_unit, a, u->cgroup_attributes)
+                unit_add_one_default_cgroup(u, a->controller);
+
+        return 0;
+}
+
+CGroupBonding* unit_get_default_cgroup(Unit *u) {
+        assert(u);
+
+        return cgroup_bonding_find_list(u->cgroup_bondings, SYSTEMD_CGROUP_CONTROLLER);
+}
+
+int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback) {
+        int r;
+        char *c = NULL;
+        CGroupAttribute *a;
+
+        assert(u);
+        assert(name);
+        assert(value);
+
+        if (!controller) {
+                const char *dot;
+
+                dot = strchr(name, '.');
+                if (!dot)
+                        return -EINVAL;
+
+                c = strndup(name, dot - name);
+                if (!c)
+                        return -ENOMEM;
+
+                controller = c;
+        }
+
+        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        a = new0(CGroupAttribute, 1);
+        if (!a) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (c) {
+                a->controller = c;
+                c = NULL;
+        } else
+                a->controller = strdup(controller);
+
+        a->name = strdup(name);
+        a->value = strdup(value);
+
+        if (!a->controller || !a->name || !a->value) {
+                free(a->controller);
+                free(a->name);
+                free(a->value);
+                free(a);
+
+                return -ENOMEM;
+        }
+
+        a->map_callback = map_callback;
+
+        LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a);
+
+        r = 0;
+
+finish:
+        free(c);
+        return r;
+}
+
+int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
+        char *t;
+        int r;
+
+        assert(u);
+        assert(type);
+        assert(_found);
+
+        if (!(t = unit_name_change_suffix(u->id, type)))
+                return -ENOMEM;
+
+        assert(!unit_has_name(u, t));
+
+        r = manager_load_unit(u->manager, t, NULL, NULL, _found);
+        free(t);
+
+        assert(r < 0 || *_found != u);
+
+        return r;
+}
+
+int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
+        Unit *found;
+        char *t;
+
+        assert(u);
+        assert(type);
+        assert(_found);
+
+        if (!(t = unit_name_change_suffix(u->id, type)))
+                return -ENOMEM;
+
+        assert(!unit_has_name(u, t));
+
+        found = manager_get_unit(u->manager, t);
+        free(t);
+
+        if (!found)
+                return -ENOENT;
+
+        *_found = found;
+        return 0;
+}
+
+int unit_watch_bus_name(Unit *u, const char *name) {
+        assert(u);
+        assert(name);
+
+        /* Watch a specific name on the bus. We only support one unit
+         * watching each name for now. */
+
+        return hashmap_put(u->manager->watch_bus, name, u);
+}
+
+void unit_unwatch_bus_name(Unit *u, const char *name) {
+        assert(u);
+        assert(name);
+
+        hashmap_remove_value(u->manager->watch_bus, name, u);
+}
+
+bool unit_can_serialize(Unit *u) {
+        assert(u);
+
+        return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
+}
+
+int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
+        int r;
+
+        assert(u);
+        assert(f);
+        assert(fds);
+
+        if (!unit_can_serialize(u))
+                return 0;
+
+        if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
+                return r;
+
+
+        if (serialize_jobs) {
+                if (u->job) {
+                        fprintf(f, "job\n");
+                        job_serialize(u->job, f, fds);
+                }
+
+                if (u->nop_job) {
+                        fprintf(f, "job\n");
+                        job_serialize(u->nop_job, f, fds);
+                }
+        }
+
+        dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
+        dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
+        dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
+        dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
+        dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
+
+        if (dual_timestamp_is_set(&u->condition_timestamp))
+                unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
+
+        /* End marker */
+        fputc('\n', f);
+        return 0;
+}
+
+void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
+        va_list ap;
+
+        assert(u);
+        assert(f);
+        assert(key);
+        assert(format);
+
+        fputs(key, f);
+        fputc('=', f);
+
+        va_start(ap, format);
+        vfprintf(f, format, ap);
+        va_end(ap);
+
+        fputc('\n', f);
+}
+
+void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
+        assert(u);
+        assert(f);
+        assert(key);
+        assert(value);
+
+        fprintf(f, "%s=%s\n", key, value);
+}
+
+int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
+        int r;
+
+        assert(u);
+        assert(f);
+        assert(fds);
+
+        if (!unit_can_serialize(u))
+                return 0;
+
+        for (;;) {
+                char line[LINE_MAX], *l, *v;
+                size_t k;
+
+                if (!fgets(line, sizeof(line), f)) {
+                        if (feof(f))
+                                return 0;
+                        return -errno;
+                }
+
+                char_array_0(line);
+                l = strstrip(line);
+
+                /* End marker */
+                if (l[0] == 0)
+                        return 0;
+
+                k = strcspn(l, "=");
+
+                if (l[k] == '=') {
+                        l[k] = 0;
+                        v = l+k+1;
+                } else
+                        v = l+k;
+
+                if (streq(l, "job")) {
+                        if (v[0] == '\0') {
+                                /* new-style serialized job */
+                                Job *j = job_new_raw(u);
+                                if (!j)
+                                        return -ENOMEM;
+
+                                r = job_deserialize(j, f, fds);
+                                if (r < 0) {
+                                        job_free(j);
+                                        return r;
+                                }
+
+                                r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
+                                if (r < 0) {
+                                        job_free(j);
+                                        return r;
+                                }
+
+                                r = job_install_deserialized(j);
+                                if (r < 0) {
+                                        hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
+                                        job_free(j);
+                                        return r;
+                                }
+                        } else {
+                                /* legacy */
+                                JobType type = job_type_from_string(v);
+                                if (type < 0)
+                                        log_debug("Failed to parse job type value %s", v);
+                                else
+                                        u->deserialized_job = type;
+                        }
+                        continue;
+                } else if (streq(l, "inactive-exit-timestamp")) {
+                        dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
+                        continue;
+                } else if (streq(l, "active-enter-timestamp")) {
+                        dual_timestamp_deserialize(v, &u->active_enter_timestamp);
+                        continue;
+                } else if (streq(l, "active-exit-timestamp")) {
+                        dual_timestamp_deserialize(v, &u->active_exit_timestamp);
+                        continue;
+                } else if (streq(l, "inactive-enter-timestamp")) {
+                        dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
+                        continue;
+                } else if (streq(l, "condition-timestamp")) {
+                        dual_timestamp_deserialize(v, &u->condition_timestamp);
+                        continue;
+                } else if (streq(l, "condition-result")) {
+                        int b;
+
+                        if ((b = parse_boolean(v)) < 0)
+                                log_debug("Failed to parse condition result value %s", v);
+                        else
+                                u->condition_result = b;
+
+                        continue;
+                }
+
+                if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0)
+                        return r;
+        }
+}
+
+int unit_add_node_link(Unit *u, const char *what, bool wants) {
+        Unit *device;
+        char *e;
+        int r;
+
+        assert(u);
+
+        if (!what)
+                return 0;
+
+        /* Adds in links to the device node that this unit is based on */
+
+        if (!is_device_path(what))
+                return 0;
+
+        e = unit_name_from_path(what, ".device");
+        if (!e)
+                return -ENOMEM;
+
+        r = manager_load_unit(u->manager, e, NULL, NULL, &device);
+        free(e);
+        if (r < 0)
+                return r;
+
+        r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
+        if (r < 0)
+                return r;
+
+        if (wants) {
+                r = unit_add_dependency(device, UNIT_WANTS, u, false);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int unit_coldplug(Unit *u) {
+        int r;
+
+        assert(u);
+
+        if (UNIT_VTABLE(u)->coldplug)
+                if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
+                        return r;
+
+        if (u->job) {
+                r = job_coldplug(u->job);
+                if (r < 0)
+                        return r;
+        } else if (u->deserialized_job >= 0) {
+                /* legacy */
+                r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
+                if (r < 0)
+                        return r;
+
+                u->deserialized_job = _JOB_TYPE_INVALID;
+        }
+
+        return 0;
+}
+
+void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
+        va_list ap;
+
+        assert(u);
+        assert(format);
+
+        if (!manager_get_show_status(u->manager))
+                return;
+
+        if (!manager_is_booting_or_shutting_down(u->manager))
+                return;
+
+        va_start(ap, format);
+        status_vprintf(status, true, format, ap);
+        va_end(ap);
+}
+
+bool unit_need_daemon_reload(Unit *u) {
+        struct stat st;
+
+        assert(u);
+
+        if (u->fragment_path) {
+                zero(st);
+                if (stat(u->fragment_path, &st) < 0)
+                        /* What, cannot access this anymore? */
+                        return true;
+
+                if (u->fragment_mtime > 0 &&
+                    timespec_load(&st.st_mtim) != u->fragment_mtime)
+                        return true;
+        }
+
+        if (u->source_path) {
+                zero(st);
+                if (stat(u->source_path, &st) < 0)
+                        return true;
+
+                if (u->source_mtime > 0 &&
+                    timespec_load(&st.st_mtim) != u->source_mtime)
+                        return true;
+        }
+
+        return false;
+}
+
+void unit_reset_failed(Unit *u) {
+        assert(u);
+
+        if (UNIT_VTABLE(u)->reset_failed)
+                UNIT_VTABLE(u)->reset_failed(u);
+}
+
+Unit *unit_following(Unit *u) {
+        assert(u);
+
+        if (UNIT_VTABLE(u)->following)
+                return UNIT_VTABLE(u)->following(u);
+
+        return NULL;
+}
+
+bool unit_pending_inactive(Unit *u) {
+        assert(u);
+
+        /* Returns true if the unit is inactive or going down */
+
+        if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
+                return true;
+
+        if (u->job && u->job->type == JOB_STOP)
+                return true;
+
+        return false;
+}
+
+bool unit_pending_active(Unit *u) {
+        assert(u);
+
+        /* Returns true if the unit is active or going up */
+
+        if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
+                return true;
+
+        if (u->job &&
+            (u->job->type == JOB_START ||
+             u->job->type == JOB_RELOAD_OR_START ||
+             u->job->type == JOB_RESTART))
+                return true;
+
+        return false;
+}
+
+int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) {
+        assert(u);
+        assert(w >= 0 && w < _KILL_WHO_MAX);
+        assert(signo > 0);
+        assert(signo < _NSIG);
+
+        if (!UNIT_VTABLE(u)->kill)
+                return -ENOTSUP;
+
+        return UNIT_VTABLE(u)->kill(u, w, signo, error);
+}
+
+int unit_following_set(Unit *u, Set **s) {
+        assert(u);
+        assert(s);
+
+        if (UNIT_VTABLE(u)->following_set)
+                return UNIT_VTABLE(u)->following_set(u, s);
+
+        *s = NULL;
+        return 0;
+}
+
+UnitFileState unit_get_unit_file_state(Unit *u) {
+        assert(u);
+
+        if (u->unit_file_state < 0 && u->fragment_path)
+                u->unit_file_state = unit_file_get_state(
+                                u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
+                                NULL, path_get_file_name(u->fragment_path));
+
+        return u->unit_file_state;
+}
+
+Unit* unit_ref_set(UnitRef *ref, Unit *u) {
+        assert(ref);
+        assert(u);
+
+        if (ref->unit)
+                unit_ref_unset(ref);
+
+        ref->unit = u;
+        LIST_PREPEND(UnitRef, refs, u->refs, ref);
+        return u;
+}
+
+void unit_ref_unset(UnitRef *ref) {
+        assert(ref);
+
+        if (!ref->unit)
+                return;
+
+        LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref);
+        ref->unit = NULL;
+}
+
+int unit_add_one_mount_link(Unit *u, Mount *m) {
+        char **i;
+
+        assert(u);
+        assert(m);
+
+        if (u->load_state != UNIT_LOADED ||
+            UNIT(m)->load_state != UNIT_LOADED)
+                return 0;
+
+        STRV_FOREACH(i, u->requires_mounts_for) {
+
+                if (UNIT(m) == u)
+                        continue;
+
+                if (!path_startswith(*i, m->where))
+                        continue;
+
+                return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
+        }
+
+        return 0;
+}
+
+int unit_add_mount_links(Unit *u) {
+        Unit *other;
+        int r;
+
+        assert(u);
+
+        LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) {
+                r = unit_add_one_mount_link(u, MOUNT(other));
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int unit_exec_context_defaults(Unit *u, ExecContext *c) {
+        unsigned i;
+        int r;
+
+        assert(u);
+        assert(c);
+
+        /* This only copies in the ones that need memory */
+
+        for (i = 0; i < RLIMIT_NLIMITS; i++)
+                if (u->manager->rlimit[i] && !c->rlimit[i]) {
+                        c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
+                        if (!c->rlimit[i])
+                                return -ENOMEM;
+                }
+
+        if (u->manager->running_as == SYSTEMD_USER &&
+            !c->working_directory) {
+
+                r = get_home_dir(&c->working_directory);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+ExecContext *unit_get_exec_context(Unit *u) {
+        size_t offset;
+        assert(u);
+
+        offset = UNIT_VTABLE(u)->exec_context_offset;
+        if (offset <= 0)
+                return NULL;
+
+        return (ExecContext*) ((uint8_t*) u + offset);
+}
+
+static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
+        [UNIT_ACTIVE] = "active",
+        [UNIT_RELOADING] = "reloading",
+        [UNIT_INACTIVE] = "inactive",
+        [UNIT_FAILED] = "failed",
+        [UNIT_ACTIVATING] = "activating",
+        [UNIT_DEACTIVATING] = "deactivating"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
+
+static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
+        [UNIT_REQUIRES] = "Requires",
+        [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
+        [UNIT_REQUISITE] = "Requisite",
+        [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
+        [UNIT_WANTS] = "Wants",
+        [UNIT_BINDS_TO] = "BindsTo",
+        [UNIT_PART_OF] = "PartOf",
+        [UNIT_REQUIRED_BY] = "RequiredBy",
+        [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
+        [UNIT_WANTED_BY] = "WantedBy",
+        [UNIT_BOUND_BY] = "BoundBy",
+        [UNIT_CONSISTS_OF] = "ConsistsOf",
+        [UNIT_CONFLICTS] = "Conflicts",
+        [UNIT_CONFLICTED_BY] = "ConflictedBy",
+        [UNIT_BEFORE] = "Before",
+        [UNIT_AFTER] = "After",
+        [UNIT_ON_FAILURE] = "OnFailure",
+        [UNIT_TRIGGERS] = "Triggers",
+        [UNIT_TRIGGERED_BY] = "TriggeredBy",
+        [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
+        [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
+        [UNIT_REFERENCES] = "References",
+        [UNIT_REFERENCED_BY] = "ReferencedBy",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
diff --git a/src/core/unit.h b/src/core/unit.h
new file mode 100644 (file)
index 0000000..702bfee
--- /dev/null
@@ -0,0 +1,564 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+typedef struct Unit Unit;
+typedef struct UnitVTable UnitVTable;
+typedef enum UnitActiveState UnitActiveState;
+typedef enum UnitDependency UnitDependency;
+typedef struct UnitRef UnitRef;
+typedef struct UnitStatusMessageFormats UnitStatusMessageFormats;
+
+#include "set.h"
+#include "util.h"
+#include "list.h"
+#include "socket-util.h"
+#include "execute.h"
+#include "condition.h"
+#include "install.h"
+#include "unit-name.h"
+
+enum UnitActiveState {
+        UNIT_ACTIVE,
+        UNIT_RELOADING,
+        UNIT_INACTIVE,
+        UNIT_FAILED,
+        UNIT_ACTIVATING,
+        UNIT_DEACTIVATING,
+        _UNIT_ACTIVE_STATE_MAX,
+        _UNIT_ACTIVE_STATE_INVALID = -1
+};
+
+static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) {
+        return t == UNIT_ACTIVE || t == UNIT_RELOADING;
+}
+
+static inline bool UNIT_IS_ACTIVE_OR_ACTIVATING(UnitActiveState t) {
+        return t == UNIT_ACTIVE || t == UNIT_ACTIVATING || t == UNIT_RELOADING;
+}
+
+static inline bool UNIT_IS_INACTIVE_OR_DEACTIVATING(UnitActiveState t) {
+        return t == UNIT_INACTIVE || t == UNIT_FAILED || t == UNIT_DEACTIVATING;
+}
+
+static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
+        return t == UNIT_INACTIVE || t == UNIT_FAILED;
+}
+
+enum UnitDependency {
+        /* Positive dependencies */
+        UNIT_REQUIRES,
+        UNIT_REQUIRES_OVERRIDABLE,
+        UNIT_REQUISITE,
+        UNIT_REQUISITE_OVERRIDABLE,
+        UNIT_WANTS,
+        UNIT_BINDS_TO,
+        UNIT_PART_OF,
+
+        /* Inverse of the above */
+        UNIT_REQUIRED_BY,             /* inverse of 'requires' and 'requisite' is 'required_by' */
+        UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' and 'requisite_overridable' is 'soft_required_by' */
+        UNIT_WANTED_BY,               /* inverse of 'wants' */
+        UNIT_BOUND_BY,                /* inverse of 'binds_to' */
+        UNIT_CONSISTS_OF,             /* inverse of 'part_of' */
+
+        /* Negative dependencies */
+        UNIT_CONFLICTS,               /* inverse of 'conflicts' is 'conflicted_by' */
+        UNIT_CONFLICTED_BY,
+
+        /* Order */
+        UNIT_BEFORE,                  /* inverse of 'before' is 'after' and vice versa */
+        UNIT_AFTER,
+
+        /* On Failure */
+        UNIT_ON_FAILURE,
+
+        /* Triggers (i.e. a socket triggers a service) */
+        UNIT_TRIGGERS,
+        UNIT_TRIGGERED_BY,
+
+        /* Propagate reloads */
+        UNIT_PROPAGATES_RELOAD_TO,
+        UNIT_RELOAD_PROPAGATED_FROM,
+
+        /* Reference information for GC logic */
+        UNIT_REFERENCES,              /* Inverse of 'references' is 'referenced_by' */
+        UNIT_REFERENCED_BY,
+
+        _UNIT_DEPENDENCY_MAX,
+        _UNIT_DEPENDENCY_INVALID = -1
+};
+
+#include "manager.h"
+#include "job.h"
+#include "cgroup.h"
+#include "cgroup-attr.h"
+
+struct Unit {
+        Manager *manager;
+
+        UnitType type;
+        UnitLoadState load_state;
+        Unit *merged_into;
+
+        char *id; /* One name is special because we use it for identification. Points to an entry in the names set */
+        char *instance;
+
+        Set *names;
+        Set *dependencies[_UNIT_DEPENDENCY_MAX];
+
+        char **requires_mounts_for;
+
+        char *description;
+        char **documentation;
+
+        char *fragment_path; /* if loaded from a config file this is the primary path to it */
+        char *source_path; /* if converted, the source file */
+        usec_t fragment_mtime;
+        usec_t source_mtime;
+
+        /* If there is something to do with this unit, then this is the installed job for it */
+        Job *job;
+
+        /* JOB_NOP jobs are special and can be installed without disturbing the real job. */
+        Job *nop_job;
+
+        usec_t job_timeout;
+
+        /* References to this */
+        LIST_HEAD(UnitRef, refs);
+
+        /* Conditions to check */
+        LIST_HEAD(Condition, conditions);
+
+        dual_timestamp condition_timestamp;
+
+        dual_timestamp inactive_exit_timestamp;
+        dual_timestamp active_enter_timestamp;
+        dual_timestamp active_exit_timestamp;
+        dual_timestamp inactive_enter_timestamp;
+
+        /* Counterparts in the cgroup filesystem */
+        CGroupBonding *cgroup_bondings;
+        CGroupAttribute *cgroup_attributes;
+
+        /* Per type list */
+        LIST_FIELDS(Unit, units_by_type);
+
+        /* All units which have requires_mounts_for set */
+        LIST_FIELDS(Unit, has_requires_mounts_for);
+
+        /* Load queue */
+        LIST_FIELDS(Unit, load_queue);
+
+        /* D-Bus queue */
+        LIST_FIELDS(Unit, dbus_queue);
+
+        /* Cleanup queue */
+        LIST_FIELDS(Unit, cleanup_queue);
+
+        /* GC queue */
+        LIST_FIELDS(Unit, gc_queue);
+
+        /* Used during GC sweeps */
+        unsigned gc_marker;
+
+        /* When deserializing, temporarily store the job type for this
+         * unit here, if there was a job scheduled.
+         * Only for deserializing from a legacy version. New style uses full
+         * serialized jobs. */
+        int deserialized_job; /* This is actually of type JobType */
+
+        /* Error code when we didn't manage to load the unit (negative) */
+        int load_error;
+
+        /* Cached unit file state */
+        UnitFileState unit_file_state;
+
+        /* Garbage collect us we nobody wants or requires us anymore */
+        bool stop_when_unneeded;
+
+        /* Create default dependencies */
+        bool default_dependencies;
+
+        /* Refuse manual starting, allow starting only indirectly via dependency. */
+        bool refuse_manual_start;
+
+        /* Don't allow the user to stop this unit manually, allow stopping only indirectly via dependency. */
+        bool refuse_manual_stop;
+
+        /* Allow isolation requests */
+        bool allow_isolate;
+
+        /* Isolate OnFailure unit */
+        bool on_failure_isolate;
+
+        /* Ignore this unit when isolating */
+        bool ignore_on_isolate;
+
+        /* Ignore this unit when snapshotting */
+        bool ignore_on_snapshot;
+
+        /* Did the last condition check succeed? */
+        bool condition_result;
+
+        bool in_load_queue:1;
+        bool in_dbus_queue:1;
+        bool in_cleanup_queue:1;
+        bool in_gc_queue:1;
+
+        bool sent_dbus_new_signal:1;
+
+        bool no_gc:1;
+
+        bool in_audit:1;
+};
+
+struct UnitRef {
+        /* Keeps tracks of references to a unit. This is useful so
+         * that we can merge two units if necessary and correct all
+         * references to them */
+
+        Unit* unit;
+        LIST_FIELDS(UnitRef, refs);
+};
+
+struct UnitStatusMessageFormats {
+        const char *starting_stopping[2];
+        const char *finished_start_job[_JOB_RESULT_MAX];
+        const char *finished_stop_job[_JOB_RESULT_MAX];
+};
+
+#include "service.h"
+#include "timer.h"
+#include "socket.h"
+#include "target.h"
+#include "device.h"
+#include "mount.h"
+#include "automount.h"
+#include "snapshot.h"
+#include "swap.h"
+#include "path.h"
+
+struct UnitVTable {
+        /* How much memory does an object of this unit type need */
+        size_t object_size;
+
+        /* If greater than 0, the offset into the object where
+         * ExecContext is found, if the unit type has that */
+        size_t exec_context_offset;
+
+        /* Config file sections this unit type understands, separated
+         * by NUL chars */
+        const char *sections;
+
+        /* This should reset all type-specific variables. This should
+         * not allocate memory, and is called with zero-initialized
+         * data. It should hence only initialize variables that need
+         * to be set != 0. */
+        void (*init)(Unit *u);
+
+        /* This should free all type-specific variables. It should be
+         * idempotent. */
+        void (*done)(Unit *u);
+
+        /* Actually load data from disk. This may fail, and should set
+         * load_state to UNIT_LOADED, UNIT_MERGED or leave it at
+         * UNIT_STUB if no configuration could be found. */
+        int (*load)(Unit *u);
+
+        /* If a lot of units got created via enumerate(), this is
+         * where to actually set the state and call unit_notify(). */
+        int (*coldplug)(Unit *u);
+
+        void (*dump)(Unit *u, FILE *f, const char *prefix);
+
+        int (*start)(Unit *u);
+        int (*stop)(Unit *u);
+        int (*reload)(Unit *u);
+
+        int (*kill)(Unit *u, KillWho w, int signo, DBusError *error);
+
+        bool (*can_reload)(Unit *u);
+
+        /* Write all data that cannot be restored from other sources
+         * away using unit_serialize_item() */
+        int (*serialize)(Unit *u, FILE *f, FDSet *fds);
+
+        /* Restore one item from the serialization */
+        int (*deserialize_item)(Unit *u, const char *key, const char *data, FDSet *fds);
+
+        /* Try to match up fds with what we need for this unit */
+        int (*distribute_fds)(Unit *u, FDSet *fds);
+
+        /* Boils down the more complex internal state of this unit to
+         * a simpler one that the engine can understand */
+        UnitActiveState (*active_state)(Unit *u);
+
+        /* Returns the substate specific to this unit type as
+         * string. This is purely information so that we can give the
+         * user a more fine grained explanation in which actual state a
+         * unit is in. */
+        const char* (*sub_state_to_string)(Unit *u);
+
+        /* Return true when there is reason to keep this entry around
+         * even nothing references it and it isn't active in any
+         * way */
+        bool (*check_gc)(Unit *u);
+
+        /* Return true when this unit is suitable for snapshotting */
+        bool (*check_snapshot)(Unit *u);
+
+        void (*fd_event)(Unit *u, int fd, uint32_t events, Watch *w);
+        void (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
+        void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w);
+
+        /* Reset failed state if we are in failed state */
+        void (*reset_failed)(Unit *u);
+
+        /* Called whenever any of the cgroups this unit watches for
+         * ran empty */
+        void (*cgroup_notify_empty)(Unit *u);
+
+        /* Called whenever a process of this unit sends us a message */
+        void (*notify_message)(Unit *u, pid_t pid, char **tags);
+
+        /* Called whenever a name thus Unit registered for comes or
+         * goes away. */
+        void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner);
+
+        /* Called whenever a bus PID lookup finishes */
+        void (*bus_query_pid_done)(Unit *u, const char *name, pid_t pid);
+
+        /* Called for each message received on the bus */
+        DBusHandlerResult (*bus_message_handler)(Unit *u, DBusConnection *c, DBusMessage *message);
+
+        /* Return the unit this unit is following */
+        Unit *(*following)(Unit *u);
+
+        /* Return the set of units that are following each other */
+        int (*following_set)(Unit *u, Set **s);
+
+        /* Called whenever CLOCK_REALTIME made a jump */
+        void (*time_change)(Unit *u);
+
+        /* This is called for each unit type and should be used to
+         * enumerate existing devices and load them. However,
+         * everything that is loaded here should still stay in
+         * inactive state. It is the job of the coldplug() call above
+         * to put the units into the initial state.  */
+        int (*enumerate)(Manager *m);
+
+        /* Type specific cleanups. */
+        void (*shutdown)(Manager *m);
+
+        /* When sending out PropertiesChanged signal, which properties
+         * shall be invalidated? This is a NUL separated list of
+         * strings, to minimize relocations a little. */
+        const char *bus_invalidating_properties;
+
+        /* The interface name */
+        const char *bus_interface;
+
+        UnitStatusMessageFormats status_message_formats;
+
+        /* Can units of this type have multiple names? */
+        bool no_alias:1;
+
+        /* Instances make no sense for this type */
+        bool no_instances:1;
+
+        /* Exclude from automatic gc */
+        bool no_gc:1;
+};
+
+extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
+
+#define UNIT_VTABLE(u) unit_vtable[(u)->type]
+
+/* For casting a unit into the various unit types */
+#define DEFINE_CAST(UPPERCASE, MixedCase)                               \
+        static inline MixedCase* UPPERCASE(Unit *u) {                   \
+                if (_unlikely_(!u || u->type != UNIT_##UPPERCASE))      \
+                        return NULL;                                    \
+                                                                        \
+                return (MixedCase*) u;                                  \
+        }
+
+/* For casting the various unit types into a unit */
+#define UNIT(u) (&(u)->meta)
+
+DEFINE_CAST(SOCKET, Socket);
+DEFINE_CAST(TIMER, Timer);
+DEFINE_CAST(SERVICE, Service);
+DEFINE_CAST(TARGET, Target);
+DEFINE_CAST(DEVICE, Device);
+DEFINE_CAST(MOUNT, Mount);
+DEFINE_CAST(AUTOMOUNT, Automount);
+DEFINE_CAST(SNAPSHOT, Snapshot);
+DEFINE_CAST(SWAP, Swap);
+DEFINE_CAST(PATH, Path);
+
+Unit *unit_new(Manager *m, size_t size);
+void unit_free(Unit *u);
+
+int unit_add_name(Unit *u, const char *name);
+
+int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference);
+int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference);
+
+int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference);
+int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference);
+
+int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference);
+int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference);
+
+int unit_add_exec_dependencies(Unit *u, ExecContext *c);
+
+int unit_add_cgroup(Unit *u, CGroupBonding *b);
+int unit_add_cgroup_from_text(Unit *u, const char *name);
+int unit_add_default_cgroups(Unit *u);
+CGroupBonding* unit_get_default_cgroup(Unit *u);
+int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback);
+
+int unit_choose_id(Unit *u, const char *name);
+int unit_set_description(Unit *u, const char *description);
+
+bool unit_check_gc(Unit *u);
+
+void unit_add_to_load_queue(Unit *u);
+void unit_add_to_dbus_queue(Unit *u);
+void unit_add_to_cleanup_queue(Unit *u);
+void unit_add_to_gc_queue(Unit *u);
+
+int unit_merge(Unit *u, Unit *other);
+int unit_merge_by_name(Unit *u, const char *other);
+
+Unit *unit_follow_merge(Unit *u);
+
+int unit_load_fragment_and_dropin(Unit *u);
+int unit_load_fragment_and_dropin_optional(Unit *u);
+int unit_load(Unit *unit);
+
+const char *unit_description(Unit *u);
+
+bool unit_has_name(Unit *u, const char *name);
+
+UnitActiveState unit_active_state(Unit *u);
+
+const char* unit_sub_state_to_string(Unit *u);
+
+void unit_dump(Unit *u, FILE *f, const char *prefix);
+
+bool unit_can_reload(Unit *u);
+bool unit_can_start(Unit *u);
+bool unit_can_isolate(Unit *u);
+
+int unit_start(Unit *u);
+int unit_stop(Unit *u);
+int unit_reload(Unit *u);
+
+int unit_kill(Unit *u, KillWho w, int signo, DBusError *error);
+
+void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success);
+
+int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w);
+void unit_unwatch_fd(Unit *u, Watch *w);
+
+int unit_watch_pid(Unit *u, pid_t pid);
+void unit_unwatch_pid(Unit *u, pid_t pid);
+
+int unit_watch_timer(Unit *u, clockid_t, bool relative, usec_t usec, Watch *w);
+void unit_unwatch_timer(Unit *u, Watch *w);
+
+int unit_watch_bus_name(Unit *u, const char *name);
+void unit_unwatch_bus_name(Unit *u, const char *name);
+
+bool unit_job_is_applicable(Unit *u, JobType j);
+
+int set_unit_path(const char *p);
+
+char *unit_dbus_path(Unit *u);
+
+int unit_load_related_unit(Unit *u, const char *type, Unit **_found);
+int unit_get_related_unit(Unit *u, const char *type, Unit **_found);
+
+bool unit_can_serialize(Unit *u);
+int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs);
+void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_attr_(4,5);
+void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value);
+int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
+
+int unit_add_node_link(Unit *u, const char *what, bool wants);
+
+int unit_coldplug(Unit *u);
+
+void unit_status_printf(Unit *u, const char *status, const char *format, ...);
+
+bool unit_need_daemon_reload(Unit *u);
+
+void unit_reset_failed(Unit *u);
+
+Unit *unit_following(Unit *u);
+
+bool unit_pending_inactive(Unit *u);
+bool unit_pending_active(Unit *u);
+
+int unit_add_default_target_dependency(Unit *u, Unit *target);
+
+char *unit_default_cgroup_path(Unit *u);
+
+int unit_following_set(Unit *u, Set **s);
+
+void unit_trigger_on_failure(Unit *u);
+
+bool unit_condition_test(Unit *u);
+
+UnitFileState unit_get_unit_file_state(Unit *u);
+
+Unit* unit_ref_set(UnitRef *ref, Unit *u);
+void unit_ref_unset(UnitRef *ref);
+
+#define UNIT_DEREF(ref) ((ref).unit)
+
+int unit_add_one_mount_link(Unit *u, Mount *m);
+int unit_add_mount_links(Unit *u);
+
+int unit_exec_context_defaults(Unit *u, ExecContext *c);
+
+ExecContext *unit_get_exec_context(Unit *u);
+
+const char *unit_active_state_to_string(UnitActiveState i);
+UnitActiveState unit_active_state_from_string(const char *s);
+
+const char *unit_dependency_to_string(UnitDependency i);
+UnitDependency unit_dependency_from_string(const char *s);
+
+#define log_full_unit(level, unit, ...) log_meta_object(level,   __FILE__, __LINE__, __func__, "UNIT=", unit, __VA_ARGS__)
+#define log_debug_unit(unit, ...)       log_full_unit(LOG_DEBUG, unit, __VA_ARGS__)
+#define log_info_unit(unit, ...)        log_full_unit(LOG_INFO, unit, __VA_ARGS__)
+#define log_notice_unit(unit, ...)      log_full_unit(LOG_NOTICE, unit, __VA_ARGS__)
+#define log_warning_unit(unit, ...)     log_full_unit(LOG_WARNING, unit, __VA_ARGS__)
+#define log_error_unit(unit, ...)       log_full_unit(LOG_ERR, unit, __VA_ARGS__)
diff --git a/src/core/user.conf b/src/core/user.conf
new file mode 100644 (file)
index 0000000..e02b46b
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+# See systemd.conf(5) for details
+
+[Manager]
+#LogLevel=info
+#LogTarget=console
+#LogColor=yes
+#LogLocation=no
+#DefaultControllers=cpu
+#DefaultStandardOutput=inherit
+#DefaultStandardError=inherit
diff --git a/src/cryptsetup/Makefile b/src/cryptsetup/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
new file mode 100644 (file)
index 0000000..6e7b707
--- /dev/null
@@ -0,0 +1,445 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+#include "unit-name.h"
+#include "mkdir.h"
+#include "virt.h"
+#include "strv.h"
+
+static const char *arg_dest = "/tmp";
+static bool arg_enabled = true;
+static bool arg_read_crypttab = true;
+static char **arg_proc_cmdline_disks = NULL;
+
+static bool has_option(const char *haystack, const char *needle) {
+        const char *f = haystack;
+        size_t l;
+
+        assert(needle);
+
+        if (!haystack)
+                return false;
+
+        l = strlen(needle);
+
+        while ((f = strstr(f, needle))) {
+
+                if (f > haystack && f[-1] != ',') {
+                        f++;
+                        continue;
+                }
+
+                if (f[l] != 0 && f[l] != ',') {
+                        f++;
+                        continue;
+                }
+
+                return true;
+        }
+
+        return false;
+}
+
+static int create_disk(
+                const char *name,
+                const char *device,
+                const char *password,
+                const char *options) {
+
+        char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL;
+        int r;
+        FILE *f = NULL;
+        bool noauto, nofail;
+
+        assert(name);
+        assert(device);
+
+        noauto = has_option(options, "noauto");
+        nofail = has_option(options, "nofail");
+
+        n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service");
+        if (!n) {
+                r = log_oom();
+                goto fail;
+        }
+
+        p = strjoin(arg_dest, "/", n, NULL);
+        if (!p) {
+                r = log_oom();
+                goto fail;
+        }
+
+        u = fstab_node_to_udev_node(device);
+        if (!u) {
+                r = log_oom();
+                goto fail;
+        }
+
+        d = unit_name_from_path(u, ".device");
+        if (!d) {
+                r = log_oom();
+                goto fail;
+        }
+
+        f = fopen(p, "wxe");
+        if (!f) {
+                r = -errno;
+                log_error("Failed to create unit file %s: %m", p);
+                goto fail;
+        }
+
+        fprintf(f,
+                "# Automatically generated by systemd-cryptsetup-generator\n\n"
+                "[Unit]\n"
+                "Description=Cryptography Setup for %%I\n"
+                "Documentation=man:systemd-cryptsetup@.service(8) man:crypttab(5)\n"
+                "SourcePath=/etc/crypttab\n"
+                "Conflicts=umount.target\n"
+                "DefaultDependencies=no\n"
+                "BindsTo=%s dev-mapper-%%i.device\n"
+                "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n"
+                "Before=umount.target\n",
+                d, d);
+
+        if (!nofail)
+                fprintf(f,
+                        "Before=cryptsetup.target\n");
+
+        if (password && (streq(password, "/dev/urandom") ||
+                         streq(password, "/dev/random") ||
+                         streq(password, "/dev/hw_random")))
+                fputs("After=systemd-random-seed-load.service\n", f);
+        else
+                fputs("Before=local-fs.target\n", f);
+
+        fprintf(f,
+                "\n[Service]\n"
+                "Type=oneshot\n"
+                "RemainAfterExit=yes\n"
+                "TimeoutSec=0\n" /* the binary handles timeouts anyway */
+                "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
+                "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
+                name, u, strempty(password), strempty(options),
+                name);
+
+        if (has_option(options, "tmp"))
+                fprintf(f,
+                        "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
+                        name);
+
+        if (has_option(options, "swap"))
+                fprintf(f,
+                        "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
+                        name);
+
+        fflush(f);
+
+        if (ferror(f)) {
+                r = -errno;
+                log_error("Failed to write file %s: %m", p);
+                goto fail;
+        }
+
+        if (asprintf(&from, "../%s", n) < 0) {
+                r = log_oom();
+                goto fail;
+        }
+
+        if (!noauto) {
+
+                to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
+                if (!to) {
+                        r = log_oom();
+                        goto fail;
+                }
+
+                mkdir_parents_label(to, 0755);
+                if (symlink(from, to) < 0) {
+                        log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+                        r = -errno;
+                        goto fail;
+                }
+
+                free(to);
+
+                if (!nofail)
+                        to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
+                else
+                        to = strjoin(arg_dest, "/cryptsetup.target.wants/", n, NULL);
+                if (!to) {
+                        r = log_oom();
+                        goto fail;
+                }
+
+                mkdir_parents_label(to, 0755);
+                if (symlink(from, to) < 0) {
+                        log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+                        r = -errno;
+                        goto fail;
+                }
+
+                free(to);
+                to = NULL;
+        }
+
+        e = unit_name_escape(name);
+        to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
+        if (!to) {
+                r = log_oom();
+                goto fail;
+        }
+
+        mkdir_parents_label(to, 0755);
+        if (symlink(from, to) < 0) {
+                log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+                r = -errno;
+                goto fail;
+        }
+
+        r = 0;
+
+fail:
+        free(p);
+        free(n);
+        free(d);
+        free(e);
+
+        free(from);
+        free(to);
+
+        if (f)
+                fclose(f);
+
+        return r;
+}
+
+static int parse_proc_cmdline(void) {
+        char *line, *w, *state;
+        int r;
+        size_t l;
+
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        r = read_one_line_file("/proc/cmdline", &line);
+        if (r < 0) {
+                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                char *word;
+
+                word = strndup(w, l);
+                if (!word) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                if (startswith(word, "luks=")) {
+                        r = parse_boolean(word + 5);
+                        if (r < 0)
+                                log_warning("Failed to parse luks switch %s. Ignoring.", word + 5);
+                        else
+                                arg_enabled = r;
+
+                } else if (startswith(word, "rd.luks=")) {
+
+                        if (in_initrd()) {
+                                r = parse_boolean(word + 8);
+                                if (r < 0)
+                                        log_warning("Failed to parse luks switch %s. Ignoring.", word + 8);
+                                else
+                                        arg_enabled = r;
+                        }
+
+                } else if (startswith(word, "luks.crypttab=")) {
+                        r = parse_boolean(word + 14);
+                        if (r < 0)
+                                log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14);
+                        else
+                                arg_read_crypttab = r;
+
+                } else if (startswith(word, "rd.luks.crypttab=")) {
+
+                        if (in_initrd()) {
+                                r = parse_boolean(word + 17);
+                                if (r < 0)
+                                        log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17);
+                                else
+                                        arg_read_crypttab = r;
+                        }
+
+                } else if (startswith(word, "luks.uuid=")) {
+                        char **t;
+
+                        t = strv_append(arg_proc_cmdline_disks, word + 10);
+                        if (!t) {
+                                r = log_oom();
+                                goto finish;
+                        }
+                        strv_free(arg_proc_cmdline_disks);
+                        arg_proc_cmdline_disks = t;
+
+                } else if (startswith(word, "rd.luks.uuid=")) {
+
+                        if (in_initrd()) {
+                                char **t;
+
+                                t = strv_append(arg_proc_cmdline_disks, word + 13);
+                                if (!t) {
+                                        r = log_oom();
+                                        goto finish;
+                                }
+                                strv_free(arg_proc_cmdline_disks);
+                                arg_proc_cmdline_disks = t;
+                        }
+
+                } else if (startswith(word, "luks.") ||
+                           (in_initrd() && startswith(word, "rd.luks."))) {
+
+                        log_warning("Unknown kernel switch %s. Ignoring.", word);
+                }
+
+                free(word);
+        }
+
+        r = 0;
+
+finish:
+        free(line);
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        FILE *f = NULL;
+        int r = EXIT_SUCCESS;
+        unsigned n = 0;
+        char **i;
+
+        if (argc > 1 && argc != 4) {
+                log_error("This program takes three or no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1)
+                arg_dest = argv[1];
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (parse_proc_cmdline() < 0)
+                return EXIT_FAILURE;
+
+        if (!arg_enabled) {
+                r = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        STRV_FOREACH(i, arg_proc_cmdline_disks) {
+                char *name, *device;
+                const char *p = *i;
+
+                if (startswith(p, "luks-"))
+                        p += 5;
+
+                name = strappend("luks-", p);
+                device = strappend("UUID=", p);
+
+                if (!name || !device) {
+                        log_oom();
+                        r = EXIT_FAILURE;
+                        free(name);
+                        free(device);
+                        goto finish;
+                }
+
+                if (create_disk(name, device, NULL, NULL) < 0)
+                        r = EXIT_FAILURE;
+
+                free(name);
+                free(device);
+        }
+
+        if (!arg_read_crypttab)
+                return r;
+
+        f = fopen("/etc/crypttab", "re");
+        if (!f) {
+
+                if (errno == ENOENT)
+                        r = EXIT_SUCCESS;
+                else {
+                        r = EXIT_FAILURE;
+                        log_error("Failed to open /etc/crypttab: %m");
+                }
+
+                goto finish;
+        }
+
+        for (;;) {
+                char line[LINE_MAX], *l;
+                char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
+                int k;
+
+                if (!fgets(line, sizeof(line), f))
+                        break;
+
+                n++;
+
+                l = strstrip(line);
+                if (*l == '#' || *l == 0)
+                        continue;
+
+                k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options);
+                if (k < 2 || k > 4) {
+                        log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
+                        r = EXIT_FAILURE;
+                        goto next;
+                }
+
+                if (create_disk(name, device, password, options) < 0)
+                        r = EXIT_FAILURE;
+
+        next:
+                free(name);
+                free(device);
+                free(password);
+                free(options);
+        }
+
+finish:
+        if (f)
+                fclose(f);
+
+        strv_free(arg_proc_cmdline_disks);
+
+        return r;
+}
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
new file mode 100644 (file)
index 0000000..f332843
--- /dev/null
@@ -0,0 +1,560 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <mntent.h>
+
+#include <libcryptsetup.h>
+#include <libudev.h>
+
+#include "log.h"
+#include "util.h"
+#include "path-util.h"
+#include "strv.h"
+#include "ask-password-api.h"
+#include "def.h"
+
+static const char *opt_type = NULL; /* LUKS1 or PLAIN */
+static char *opt_cipher = NULL;
+static unsigned opt_key_size = 0;
+static unsigned opt_keyfile_size = 0;
+static unsigned opt_keyfile_offset = 0;
+static char *opt_hash = NULL;
+static unsigned opt_tries = 0;
+static bool opt_readonly = false;
+static bool opt_verify = false;
+static bool opt_discards = false;
+static usec_t opt_timeout = DEFAULT_TIMEOUT_USEC;
+
+/* Options Debian's crypttab knows we don't:
+
+    offset=
+    skip=
+    precheck=
+    check=
+    checkargs=
+    noearly=
+    loud=
+    keyscript=
+*/
+
+static int parse_one_option(const char *option) {
+        assert(option);
+
+        /* Handled outside of this tool */
+        if (streq(option, "noauto") || streq(option, "nofail"))
+                return 0;
+
+        if (startswith(option, "cipher=")) {
+                char *t;
+
+                if (!(t = strdup(option+7)))
+                        return -ENOMEM;
+
+                free(opt_cipher);
+                opt_cipher = t;
+
+        } else if (startswith(option, "size=")) {
+
+                if (safe_atou(option+5, &opt_key_size) < 0) {
+                        log_error("size= parse failure, ignoring.");
+                        return 0;
+                }
+
+        } else if (startswith(option, "keyfile-size=")) {
+
+                if (safe_atou(option+13, &opt_keyfile_size) < 0) {
+                        log_error("keyfile-size= parse failure, ignoring.");
+                        return 0;
+                }
+
+        } else if (startswith(option, "keyfile-offset=")) {
+
+                if (safe_atou(option+15, &opt_keyfile_offset) < 0) {
+                        log_error("keyfile-offset= parse failure, ignoring.");
+                        return 0;
+                }
+
+        } else if (startswith(option, "hash=")) {
+                char *t;
+
+                if (!(t = strdup(option+5)))
+                        return -ENOMEM;
+
+                free(opt_hash);
+                opt_hash = t;
+
+        } else if (startswith(option, "tries=")) {
+
+                if (safe_atou(option+6, &opt_tries) < 0) {
+                        log_error("tries= parse failure, ignoring.");
+                        return 0;
+                }
+
+        } else if (streq(option, "readonly"))
+                opt_readonly = true;
+        else if (streq(option, "verify"))
+                opt_verify = true;
+        else if (streq(option, "allow-discards"))
+                opt_discards = true;
+        else if (streq(option, "luks"))
+                opt_type = CRYPT_LUKS1;
+        else if (streq(option, "plain") ||
+                 streq(option, "swap") ||
+                 streq(option, "tmp"))
+                opt_type = CRYPT_PLAIN;
+        else if (startswith(option, "timeout=")) {
+
+                if (parse_usec(option+8, &opt_timeout) < 0) {
+                        log_error("timeout= parse failure, ignoring.");
+                        return 0;
+                }
+
+        } else if (!streq(option, "none"))
+                log_error("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
+
+        return 0;
+}
+
+static int parse_options(const char *options) {
+        char *state;
+        char *w;
+        size_t l;
+
+        assert(options);
+
+        FOREACH_WORD_SEPARATOR(w, l, options, ",", state) {
+                char *o;
+                int r;
+
+                if (!(o = strndup(w, l)))
+                        return -ENOMEM;
+
+                r = parse_one_option(o);
+                free(o);
+
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static void log_glue(int level, const char *msg, void *usrptr) {
+        log_debug("%s", msg);
+}
+
+static char *disk_description(const char *path) {
+        struct udev *udev = NULL;
+        struct udev_device *device = NULL;
+        struct stat st;
+        char *description = NULL;
+        const char *model;
+
+        assert(path);
+
+        if (stat(path, &st) < 0)
+                return NULL;
+
+        if (!S_ISBLK(st.st_mode))
+                return NULL;
+
+        if (!(udev = udev_new()))
+                return NULL;
+
+        if (!(device = udev_device_new_from_devnum(udev, 'b', st.st_rdev)))
+                goto finish;
+
+        if ((model = udev_device_get_property_value(device, "ID_MODEL_FROM_DATABASE")) ||
+            (model = udev_device_get_property_value(device, "ID_MODEL")) ||
+            (model = udev_device_get_property_value(device, "DM_NAME")))
+                description = strdup(model);
+
+finish:
+        if (device)
+                udev_device_unref(device);
+
+        if (udev)
+                udev_unref(udev);
+
+        return description;
+}
+
+static char *disk_mount_point(const char *label) {
+        char *mp = NULL, *device = NULL;
+        FILE *f = NULL;
+        struct mntent *m;
+
+        /* Yeah, we don't support native systemd unit files here for now */
+
+        if (asprintf(&device, "/dev/mapper/%s", label) < 0)
+                goto finish;
+
+        f = setmntent("/etc/fstab", "r");
+        if (!f)
+                goto finish;
+
+        while ((m = getmntent(f)))
+                if (path_equal(m->mnt_fsname, device)) {
+                        mp = strdup(m->mnt_dir);
+                        break;
+                }
+
+finish:
+        if (f)
+                endmntent(f);
+
+        free(device);
+
+        return mp;
+}
+
+static int help(void) {
+
+        printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n"
+               "%s detach VOLUME\n\n"
+               "Attaches or detaches an encrypted block device.\n",
+               program_invocation_short_name,
+               program_invocation_short_name);
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        int r = EXIT_FAILURE;
+        struct crypt_device *cd = NULL;
+        char **passwords = NULL, *truncated_cipher = NULL;
+        const char *cipher = NULL, *cipher_mode = NULL, *hash = NULL, *name = NULL;
+        char *description = NULL, *name_buffer = NULL, *mount_point = NULL;
+
+        if (argc <= 1) {
+                help();
+                return EXIT_SUCCESS;
+        }
+
+        if (argc < 3) {
+                log_error("This program requires at least two arguments.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (streq(argv[1], "attach")) {
+                uint32_t flags = 0;
+                int k;
+                unsigned try;
+                const char *key_file = NULL;
+                usec_t until;
+                crypt_status_info status;
+
+                /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */
+
+                if (argc < 4) {
+                        log_error("attach requires at least two arguments.");
+                        goto finish;
+                }
+
+                if (argc >= 5 &&
+                    argv[4][0] &&
+                    !streq(argv[4], "-") &&
+                    !streq(argv[4], "none")) {
+
+                        if (!path_is_absolute(argv[4]))
+                                log_error("Password file path %s is not absolute. Ignoring.", argv[4]);
+                        else
+                                key_file = argv[4];
+                }
+
+                if (argc >= 6 && argv[5][0] && !streq(argv[5], "-"))
+                        parse_options(argv[5]);
+
+                /* A delicious drop of snake oil */
+                mlockall(MCL_FUTURE);
+
+                description = disk_description(argv[3]);
+                mount_point = disk_mount_point(argv[2]);
+
+                if (description && streq(argv[2], description)) {
+                        /* If the description string is simply the
+                         * volume name, then let's not show this
+                         * twice */
+                        free(description);
+                        description = NULL;
+                }
+
+                if (mount_point && description)
+                        asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point);
+                else if (mount_point)
+                        asprintf(&name_buffer, "%s on %s", argv[2], mount_point);
+                else if (description)
+                        asprintf(&name_buffer, "%s (%s)", description, argv[2]);
+
+                name = name_buffer ? name_buffer : argv[2];
+
+                if ((k = crypt_init(&cd, argv[3]))) {
+                        log_error("crypt_init() failed: %s", strerror(-k));
+                        goto finish;
+                }
+
+                crypt_set_log_callback(cd, log_glue, NULL);
+
+                status = crypt_status(cd, argv[2]);
+                if (status == CRYPT_ACTIVE || status == CRYPT_BUSY) {
+                        log_info("Volume %s already active.", argv[2]);
+                        r = EXIT_SUCCESS;
+                        goto finish;
+                }
+
+                if (opt_readonly)
+                        flags |= CRYPT_ACTIVATE_READONLY;
+
+                if (opt_discards)
+                        flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
+
+                if (opt_timeout > 0)
+                        until = now(CLOCK_MONOTONIC) + opt_timeout;
+                else
+                        until = 0;
+
+                opt_tries = opt_tries > 0 ? opt_tries : 3;
+                opt_key_size = (opt_key_size > 0 ? opt_key_size : 256);
+                if (opt_hash) {
+                        /* plain isn't a real hash type. it just means "use no hash" */
+                        if (!streq(opt_hash, "plain"))
+                                hash = opt_hash;
+                } else
+                        hash = "ripemd160";
+
+                if (opt_cipher) {
+                        size_t l;
+
+                        l = strcspn(opt_cipher, "-");
+
+                        if (!(truncated_cipher = strndup(opt_cipher, l))) {
+                                log_oom();
+                                goto finish;
+                        }
+
+                        cipher = truncated_cipher;
+                        cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain";
+                } else {
+                        cipher = "aes";
+                        cipher_mode = "cbc-essiv:sha256";
+                }
+
+                for (try = 0; try < opt_tries; try++) {
+                        bool pass_volume_key = false;
+
+                        strv_free(passwords);
+                        passwords = NULL;
+
+                        if (!key_file) {
+                                char *text;
+                                char **p;
+
+                                if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) {
+                                        log_oom();
+                                        goto finish;
+                                }
+
+                                k = ask_password_auto(text, "drive-harddisk", until, try == 0 && !opt_verify, &passwords);
+                                free(text);
+
+                                if (k < 0) {
+                                        log_error("Failed to query password: %s", strerror(-k));
+                                        goto finish;
+                                }
+
+                                if (opt_verify) {
+                                        char **passwords2 = NULL;
+
+                                        assert(strv_length(passwords) == 1);
+
+                                        if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) {
+                                                log_oom();
+                                                goto finish;
+                                        }
+
+                                        k = ask_password_auto(text, "drive-harddisk", until, false, &passwords2);
+                                        free(text);
+
+                                        if (k < 0) {
+                                                log_error("Failed to query verification password: %s", strerror(-k));
+                                                goto finish;
+                                        }
+
+                                        assert(strv_length(passwords2) == 1);
+
+                                        if (!streq(passwords[0], passwords2[0])) {
+                                                log_warning("Passwords did not match, retrying.");
+                                                strv_free(passwords2);
+                                                continue;
+                                        }
+
+                                        strv_free(passwords2);
+                                }
+
+                                strv_uniq(passwords);
+
+                                STRV_FOREACH(p, passwords) {
+                                        char *c;
+
+                                        if (strlen(*p)+1 >= opt_key_size)
+                                                continue;
+
+                                        /* Pad password if necessary */
+                                        if (!(c = new(char, opt_key_size))) {
+                                                log_oom();
+                                                goto finish;
+                                        }
+
+                                        strncpy(c, *p, opt_key_size);
+                                        free(*p);
+                                        *p = c;
+                                }
+                        }
+
+                        k = 0;
+
+                        if (!opt_type || streq(opt_type, CRYPT_LUKS1))
+                                k = crypt_load(cd, CRYPT_LUKS1, NULL);
+
+                        if ((!opt_type && k < 0) || streq_ptr(opt_type, CRYPT_PLAIN)) {
+                                struct crypt_params_plain params;
+
+                                zero(params);
+                                params.hash = hash;
+
+                                /* for CRYPT_PLAIN limit reads
+                                * from keyfile to key length, and
+                                * ignore keyfile-size */
+                                opt_keyfile_size = opt_key_size / 8;
+
+                                /* In contrast to what the name
+                                 * crypt_setup() might suggest this
+                                 * doesn't actually format anything,
+                                 * it just configures encryption
+                                 * parameters when used for plain
+                                 * mode. */
+                                k = crypt_format(cd, CRYPT_PLAIN,
+                                                 cipher,
+                                                 cipher_mode,
+                                                 NULL,
+                                                 NULL,
+                                                 opt_keyfile_size,
+                                                 &params);
+
+                                /* hash == NULL implies the user passed "plain" */
+                                pass_volume_key = (hash == NULL);
+                        }
+
+                        if (k < 0) {
+                                log_error("Loading of cryptographic parameters failed: %s", strerror(-k));
+                                goto finish;
+                        }
+
+                        log_info("Set cipher %s, mode %s, key size %i bits for device %s.",
+                                 crypt_get_cipher(cd),
+                                 crypt_get_cipher_mode(cd),
+                                 crypt_get_volume_key_size(cd)*8,
+                                 argv[3]);
+
+                        if (key_file)
+                                k = crypt_activate_by_keyfile_offset(cd, argv[2], CRYPT_ANY_SLOT, key_file, opt_keyfile_size,
+                                            opt_keyfile_offset, flags);
+                        else {
+                                char **p;
+
+                                STRV_FOREACH(p, passwords) {
+
+                                        if (pass_volume_key)
+                                                k = crypt_activate_by_volume_key(cd, argv[2], *p, opt_key_size, flags);
+                                        else
+                                                k = crypt_activate_by_passphrase(cd, argv[2], CRYPT_ANY_SLOT, *p, strlen(*p), flags);
+
+                                        if (k >= 0)
+                                                break;
+                                }
+                        }
+
+                        if (k >= 0)
+                                break;
+
+                        if (k != -EPERM) {
+                                log_error("Failed to activate: %s", strerror(-k));
+                                goto finish;
+                        }
+
+                        log_warning("Invalid passphrase.");
+                }
+
+                if (try >= opt_tries) {
+                        log_error("Too many attempts.");
+                        r = EXIT_FAILURE;
+                        goto finish;
+                }
+
+        } else if (streq(argv[1], "detach")) {
+                int k;
+
+                if ((k = crypt_init_by_name(&cd, argv[2]))) {
+                        log_error("crypt_init() failed: %s", strerror(-k));
+                        goto finish;
+                }
+
+                crypt_set_log_callback(cd, log_glue, NULL);
+
+                if ((k = crypt_deactivate(cd, argv[2])) < 0) {
+                        log_error("Failed to deactivate: %s", strerror(-k));
+                        goto finish;
+                }
+
+        } else {
+                log_error("Unknown verb %s.", argv[1]);
+                goto finish;
+        }
+
+        r = EXIT_SUCCESS;
+
+finish:
+
+        if (cd)
+                crypt_free(cd);
+
+        free(opt_cipher);
+        free(opt_hash);
+
+        free(truncated_cipher);
+
+        strv_free(passwords);
+
+        free(description);
+        free(mount_point);
+        free(name_buffer);
+
+        return r;
+}
diff --git a/src/delta/Makefile b/src/delta/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/delta/delta.c b/src/delta/delta.c
new file mode 100644 (file)
index 0000000..9f20938
--- /dev/null
@@ -0,0 +1,489 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "hashmap.h"
+#include "util.h"
+#include "path-util.h"
+#include "log.h"
+#include "pager.h"
+#include "build.h"
+
+static bool arg_no_pager = false;
+static int arg_diff = -1;
+
+static enum {
+        SHOW_MASKED = 1 << 0,
+        SHOW_EQUIVALENT = 1 << 1,
+        SHOW_REDIRECTED = 1 << 2,
+        SHOW_OVERRIDDEN = 1 << 3,
+        SHOW_UNCHANGED = 1 << 4,
+
+        SHOW_DEFAULTS =
+        (SHOW_MASKED | SHOW_EQUIVALENT | SHOW_REDIRECTED | SHOW_OVERRIDDEN)
+} arg_flags = 0;
+
+static int equivalent(const char *a, const char *b) {
+        _cleanup_free_ char *x = NULL, *y = NULL;
+
+        x = canonicalize_file_name(a);
+        if (!x)
+                return -errno;
+
+        y = canonicalize_file_name(b);
+        if (!y)
+                return -errno;
+
+        return path_equal(x, y);
+}
+
+static int notify_override_masked(const char *top, const char *bottom) {
+        if (!(arg_flags & SHOW_MASKED))
+                return 0;
+
+        printf(ANSI_HIGHLIGHT_RED_ON "[MASKED]" ANSI_HIGHLIGHT_OFF "     %s → %s\n", top, bottom);
+        return 1;
+}
+
+static int notify_override_equivalent(const char *top, const char *bottom) {
+        if (!(arg_flags & SHOW_EQUIVALENT))
+                return 0;
+
+        printf(ANSI_HIGHLIGHT_GREEN_ON "[EQUIVALENT]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom);
+        return 1;
+}
+
+static int notify_override_redirected(const char *top, const char *bottom) {
+        if (!(arg_flags & SHOW_REDIRECTED))
+                return 0;
+
+        printf(ANSI_HIGHLIGHT_ON "[REDIRECTED]" ANSI_HIGHLIGHT_OFF "   %s → %s\n", top, bottom);
+        return 1;
+}
+
+static int notify_override_overridden(const char *top, const char *bottom) {
+        if (!(arg_flags & SHOW_OVERRIDDEN))
+                return 0;
+
+        printf(ANSI_HIGHLIGHT_ON "[OVERRIDDEN]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom);
+        return 1;
+}
+
+static int notify_override_unchanged(const char *f) {
+        if (!(arg_flags & SHOW_UNCHANGED))
+                return 0;
+
+        printf("[UNCHANGED]  %s\n", f);
+        return 1;
+}
+
+static int found_override(const char *top, const char *bottom) {
+        _cleanup_free_ char *dest = NULL;
+        int k;
+        pid_t pid;
+
+        assert(top);
+        assert(bottom);
+
+        if (null_or_empty_path(top) > 0) {
+                notify_override_masked(top, bottom);
+                return 0;
+        }
+
+        k = readlink_malloc(top, &dest);
+        if (k >= 0) {
+                if (equivalent(dest, bottom) > 0)
+                        notify_override_equivalent(top, bottom);
+                else
+                        notify_override_redirected(top, bottom);
+
+                return 0;
+        }
+
+        notify_override_overridden(top, bottom);
+        if (!arg_diff)
+                return 0;
+
+        putchar('\n');
+
+        fflush(stdout);
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("Failed to fork off diff: %m");
+                return -errno;
+        } else if (pid == 0) {
+                execlp("diff", "diff", "-us", "--", bottom, top, NULL);
+                log_error("Failed to execute diff: %m");
+                _exit(1);
+        }
+
+        wait_for_terminate(pid, NULL);
+
+        putchar('\n');
+
+        return 0;
+}
+
+static int enumerate_dir(Hashmap *top, Hashmap *bottom, const char *path) {
+        _cleanup_closedir_ DIR *d;
+
+        assert(top);
+        assert(bottom);
+        assert(path);
+
+        d = opendir(path);
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to enumerate %s: %m", path);
+                return -errno;
+        }
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                int k;
+                char *p;
+
+                k = readdir_r(d, &buf.de, &de);
+                if (k != 0)
+                        return -k;
+
+                if (!de)
+                        break;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                p = strjoin(path, "/", de->d_name, NULL);
+                if (!p)
+                        return -ENOMEM;
+
+                path_kill_slashes(p);
+
+                k = hashmap_put(top, path_get_file_name(p), p);
+                if (k >= 0) {
+                        p = strdup(p);
+                        if (!p)
+                                return -ENOMEM;
+                } else if (k != -EEXIST) {
+                        free(p);
+                        return k;
+                }
+
+                free(hashmap_remove(bottom, path_get_file_name(p)));
+                k = hashmap_put(bottom, path_get_file_name(p), p);
+                if (k < 0) {
+                        free(p);
+                        return k;
+                }
+        }
+
+        return 0;
+}
+
+static int process_suffix(const char *prefixes, const char *suffix) {
+        const char *p;
+        char *f;
+        Hashmap *top, *bottom=NULL;
+        int r = 0, k;
+        Iterator i;
+        int n_found = 0;
+
+        assert(prefixes);
+        assert(suffix);
+
+        top = hashmap_new(string_hash_func, string_compare_func);
+        if (!top) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        bottom = hashmap_new(string_hash_func, string_compare_func);
+        if (!bottom) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        NULSTR_FOREACH(p, prefixes) {
+                _cleanup_free_ char *t = NULL;
+
+                t = strjoin(p, "/", suffix, NULL);
+                if (!t) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                k = enumerate_dir(top, bottom, t);
+                if (k < 0)
+                        r = k;
+
+                log_debug("Looking at %s", t);
+        }
+
+        HASHMAP_FOREACH(f, top, i) {
+                char *o;
+
+                o = hashmap_get(bottom, path_get_file_name(f));
+                assert(o);
+
+                if (path_equal(o, f)) {
+                        notify_override_unchanged(f);
+                        continue;
+                }
+
+                k = found_override(f, o);
+                if (k < 0)
+                        r = k;
+
+                n_found ++;
+        }
+
+finish:
+        if (top)
+                hashmap_free_free(top);
+        if (bottom)
+                hashmap_free_free(bottom);
+
+        return r < 0 ? r : n_found;
+}
+
+static int process_suffix_chop(const char *prefixes, const char *suffix) {
+        const char *p;
+
+        assert(prefixes);
+        assert(suffix);
+
+        if (!path_is_absolute(suffix))
+                return process_suffix(prefixes, suffix);
+
+        /* Strip prefix from the suffix */
+        NULSTR_FOREACH(p, prefixes) {
+                if (startswith(suffix, p)) {
+                        suffix += strlen(p);
+                        suffix += strspn(suffix, "/");
+                        return process_suffix(prefixes, suffix);
+                }
+        }
+
+        log_error("Invalid suffix specification %s.", suffix);
+        return -EINVAL;
+}
+
+static void help(void) {
+
+        printf("%s [OPTIONS...] [SUFFIX...]\n\n"
+               "Find overridden configuration files.\n\n"
+               "  -h --help           Show this help\n"
+               "     --version        Show package version\n"
+               "     --no-pager       Do not pipe output into a pager\n"
+               "     --diff[=1|0]     Show a diff when overridden files differ\n"
+               "  -t --type=LIST...   Only display a selected set of override types\n",
+               program_invocation_short_name);
+}
+
+static int parse_flags(const char *flag_str, int flags) {
+        char *w, *state;
+        size_t l;
+
+        FOREACH_WORD(w, l, flag_str, state) {
+                if (strncmp("masked", w, l) == 0)
+                        flags |= SHOW_MASKED;
+                else if (strncmp ("equivalent", w, l) == 0)
+                        flags |= SHOW_EQUIVALENT;
+                else if (strncmp("redirected", w, l) == 0)
+                        flags |= SHOW_REDIRECTED;
+                else if (strncmp("overridden", w, l) == 0)
+                        flags |= SHOW_OVERRIDDEN;
+                else if (strncmp("unchanged", w, l) == 0)
+                        flags |= SHOW_UNCHANGED;
+                else if (strncmp("default", w, l) == 0)
+                        flags |= SHOW_DEFAULTS;
+                else
+                        return -EINVAL;
+        }
+        return flags;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_NO_PAGER = 0x100,
+                ARG_DIFF,
+                ARG_VERSION
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'          },
+                { "version",   no_argument,       NULL, ARG_VERSION  },
+                { "no-pager",  no_argument,       NULL, ARG_NO_PAGER },
+                { "diff",      optional_argument, NULL, ARG_DIFF     },
+                { "type",      required_argument, NULL, 't'          },
+                { NULL,        0,                 NULL, 0            }
+        };
+
+        int c;
+
+        assert(argc >= 1);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "ht:", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                case 't': {
+                        int f;
+                        f = parse_flags(optarg, arg_flags);
+                        if (f < 0) {
+                                log_error("Failed to parse flags field.");
+                                return -EINVAL;
+                        }
+                        arg_flags = f;
+                        break;
+                }
+
+                case ARG_DIFF:
+                        if (!optarg)
+                                arg_diff = 1;
+                        else {
+                                int b;
+
+                                b = parse_boolean(optarg);
+                                if (b < 0) {
+                                        log_error("Failed to parse diff boolean.");
+                                        return -EINVAL;
+                                } else if (b)
+                                        arg_diff = 1;
+                                else
+                                        arg_diff = 0;
+                        }
+                        break;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+
+        const char prefixes[] =
+                "/etc\0"
+                "/run\0"
+                "/usr/local/lib\0"
+                "/usr/local/share\0"
+                "/usr/lib\0"
+                "/usr/share\0"
+#ifdef HAVE_SPLIT_USR
+                "/lib\0"
+#endif
+                ;
+
+        const char suffixes[] =
+                "sysctl.d\0"
+                "tmpfiles.d\0"
+                "modules-load.d\0"
+                "binfmt.d\0"
+                "systemd/system\0"
+                "systemd/user\0"
+                "systemd/system-preset\0"
+                "systemd/user-preset\0"
+                "udev/rules.d\0"
+                "modprobe.d\0";
+
+        int r = 0, k;
+        int n_found = 0;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        if (arg_flags == 0)
+                arg_flags = SHOW_DEFAULTS;
+
+        if (arg_diff < 0)
+                arg_diff = !!(arg_flags & SHOW_OVERRIDDEN);
+        else if (arg_diff)
+                arg_flags |= SHOW_OVERRIDDEN;
+
+        if (!arg_no_pager)
+                pager_open();
+
+        if (optind < argc) {
+                int i;
+
+                for (i = optind; i < argc; i++) {
+                        k = process_suffix_chop(prefixes, argv[i]);
+                        if (k < 0)
+                                r = k;
+                        else
+                                n_found += k;
+                }
+
+        } else {
+                const char *n;
+
+                NULSTR_FOREACH(n, suffixes) {
+                        k = process_suffix(prefixes, n);
+                        if (k < 0)
+                                r = k;
+                        else
+                                n_found += k;
+                }
+        }
+
+        if (r >= 0)
+                printf("\n%i overridden configuration files found.\n", n_found);
+
+finish:
+        pager_close();
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/detect-virt/Makefile b/src/detect-virt/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c
new file mode 100644 (file)
index 0000000..bd3ee45
--- /dev/null
@@ -0,0 +1,171 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "util.h"
+#include "virt.h"
+#include "build.h"
+
+static bool arg_quiet = false;
+static enum {
+        ANY_VIRTUALIZATION,
+        ONLY_VM,
+        ONLY_CONTAINER
+} arg_mode = ANY_VIRTUALIZATION;
+
+static int help(void) {
+
+        printf("%s [OPTIONS...]\n\n"
+               "Detect execution in a virtualized environment.\n\n"
+               "  -h --help             Show this help\n"
+               "     --version          Show package version\n"
+               "  -c --container        Only detect whether we are run in a container\n"
+               "  -v --vm               Only detect whether we are run in a VM\n"
+               "  -q --quiet            Don't output anything, just set return value\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "container", no_argument,       NULL, 'c'           },
+                { "vm",        optional_argument, NULL, 'v'           },
+                { "quiet",     no_argument,       NULL, 'q'           },
+                { NULL,        0,                 NULL, 0             }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case 'q':
+                        arg_quiet = true;
+                        break;
+
+                case 'c':
+                        arg_mode = ONLY_CONTAINER;
+                        break;
+
+                case 'v':
+                        arg_mode = ONLY_VM;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind < argc) {
+                help();
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        const char *id = NULL;
+        int r;
+        int retval = EXIT_SUCCESS;
+
+        /* This is mostly intended to be used for scripts which want
+         * to detect whether we are being run in a virtualized
+         * environment or not */
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+        switch (arg_mode) {
+
+        case ANY_VIRTUALIZATION: {
+                Virtualization v;
+
+                v = detect_virtualization(&id);
+                if (v < 0) {
+                        log_error("Failed to check for virtualization: %s", strerror(-v));
+                        return EXIT_FAILURE;
+                }
+
+                retval = v != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
+                break;
+        }
+
+        case ONLY_CONTAINER:
+                r = detect_container(&id);
+                if (r < 0) {
+                        log_error("Failed to check for container: %s", strerror(-r));
+                        return EXIT_FAILURE;
+                }
+
+                retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+                break;
+
+        case ONLY_VM:
+                r = detect_vm(&id);
+                if (r < 0) {
+                        log_error("Failed to check for vm: %s", strerror(-r));
+                        return EXIT_FAILURE;
+                }
+
+                retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+                break;
+        }
+
+        if (!arg_quiet)
+                puts(id ? id : "none");
+
+        return retval;
+}
diff --git a/src/fsck/Makefile b/src/fsck/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
new file mode 100644 (file)
index 0000000..f5d38ad
--- /dev/null
@@ -0,0 +1,416 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/file.h>
+
+#include <libudev.h>
+#include <dbus/dbus.h>
+
+#include "util.h"
+#include "dbus-common.h"
+#include "special.h"
+#include "bus-errors.h"
+#include "virt.h"
+
+static bool arg_skip = false;
+static bool arg_force = false;
+static bool arg_show_progress = false;
+
+static void start_target(const char *target, bool isolate) {
+        DBusMessage *m = NULL, *reply = NULL;
+        DBusError error;
+        const char *mode, *basic_target = "basic.target";
+        DBusConnection *bus = NULL;
+
+        assert(target);
+
+        dbus_error_init(&error);
+
+        if (bus_connect(DBUS_BUS_SYSTEM, &bus, NULL, &error) < 0) {
+                log_error("Failed to get D-Bus connection: %s", bus_error_message(&error));
+                goto finish;
+        }
+
+        if (isolate)
+                mode = "isolate";
+        else
+                mode = "replace";
+
+        log_info("Running request %s/start/%s", target, mode);
+
+        if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnitReplace"))) {
+                log_error("Could not allocate message.");
+                goto finish;
+        }
+
+        /* Start these units only if we can replace base.target with it */
+
+        if (!dbus_message_append_args(m,
+                                      DBUS_TYPE_STRING, &basic_target,
+                                      DBUS_TYPE_STRING, &target,
+                                      DBUS_TYPE_STRING, &mode,
+                                      DBUS_TYPE_INVALID)) {
+                log_error("Could not attach target and flag information to message.");
+                goto finish;
+        }
+
+        if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+
+                /* Don't print a warning if we aren't called during
+                 * startup */
+                if (!dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_JOB))
+                        log_error("Failed to start unit: %s", bus_error_message(&error));
+
+                goto finish;
+        }
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        dbus_error_free(&error);
+}
+
+static int parse_proc_cmdline(void) {
+        char *line, *w, *state;
+        int r;
+        size_t l;
+
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        r = read_one_line_file("/proc/cmdline", &line);
+        if (r < 0) {
+                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+
+                if (strneq(w, "fsck.mode=auto", l))
+                        arg_force = arg_skip = false;
+                else if (strneq(w, "fsck.mode=force", l))
+                        arg_force = true;
+                else if (strneq(w, "fsck.mode=skip", l))
+                        arg_skip = true;
+                else if (startswith(w, "fsck"))
+                        log_warning("Invalid fsck parameter. Ignoring.");
+#ifdef HAVE_SYSV_COMPAT
+                else if (strneq(w, "fastboot", l)) {
+                        log_error("Please pass 'fsck.mode=skip' rather than 'fastboot' on the kernel command line.");
+                        arg_skip = true;
+                } else if (strneq(w, "forcefsck", l)) {
+                        log_error("Please pass 'fsck.mode=force' rather than 'forcefsck' on the kernel command line.");
+                        arg_force = true;
+                }
+#endif
+        }
+
+        free(line);
+        return 0;
+}
+
+static void test_files(void) {
+#ifdef HAVE_SYSV_COMPAT
+        if (access("/fastboot", F_OK) >= 0) {
+                log_error("Please pass 'fsck.mode=skip' on the kernel command line rather than creating /fastboot on the root file system.");
+                arg_skip = true;
+        }
+
+        if (access("/forcefsck", F_OK) >= 0) {
+                log_error("Please pass 'fsck.mode=force' on the kernel command line rather than creating /forcefsck on the root file system.");
+                arg_force = true;
+        }
+#endif
+
+        if (access("/run/systemd/show-status", F_OK) >= 0 || plymouth_running())
+                arg_show_progress = true;
+}
+
+static double percent(int pass, unsigned long cur, unsigned long max) {
+        /* Values stolen from e2fsck */
+
+        static const int pass_table[] = {
+                0, 70, 90, 92, 95, 100
+        };
+
+        if (pass <= 0)
+                return 0.0;
+
+        if ((unsigned) pass >= ELEMENTSOF(pass_table) || max == 0)
+                return 100.0;
+
+        return (double) pass_table[pass-1] +
+                ((double) pass_table[pass] - (double) pass_table[pass-1]) *
+                (double) cur / (double) max;
+}
+
+static int process_progress(int fd) {
+        FILE *f, *console;
+        usec_t last = 0;
+        bool locked = false;
+        int clear = 0;
+
+        f = fdopen(fd, "r");
+        if (!f) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        console = fopen("/dev/console", "w");
+        if (!console) {
+                fclose(f);
+                return -ENOMEM;
+        }
+
+        while (!feof(f)) {
+                int pass, m;
+                unsigned long cur, max;
+                char *device;
+                double p;
+                usec_t t;
+
+                if (fscanf(f, "%i %lu %lu %ms", &pass, &cur, &max, &device) != 4)
+                        break;
+
+                /* Only show one progress counter at max */
+                if (!locked) {
+                        if (flock(fileno(console), LOCK_EX|LOCK_NB) < 0) {
+                                free(device);
+                                continue;
+                        }
+
+                        locked = true;
+                }
+
+                /* Only update once every 50ms */
+                t = now(CLOCK_MONOTONIC);
+                if (last + 50 * USEC_PER_MSEC > t)  {
+                        free(device);
+                        continue;
+                }
+
+                last = t;
+
+                p = percent(pass, cur, max);
+                fprintf(console, "\r%s: fsck %3.1f%% complete...\r%n", device, p, &m);
+                fflush(console);
+
+                free(device);
+
+                if (m > clear)
+                        clear = m;
+        }
+
+        if (clear > 0) {
+                unsigned j;
+
+                fputc('\r', console);
+                for (j = 0; j < (unsigned) clear; j++)
+                        fputc(' ', console);
+                fputc('\r', console);
+                fflush(console);
+        }
+
+        fclose(f);
+        fclose(console);
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        const char *cmdline[9];
+        int i = 0, r = EXIT_FAILURE, q;
+        pid_t pid;
+        siginfo_t status;
+        struct udev *udev = NULL;
+        struct udev_device *udev_device = NULL;
+        const char *device;
+        bool root_directory;
+        int progress_pipe[2] = { -1, -1 };
+        char dash_c[2+10+1];
+
+        if (argc > 2) {
+                log_error("This program expects one or no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        parse_proc_cmdline();
+        test_files();
+
+        if (!arg_force && arg_skip)
+                return 0;
+
+        if (argc > 1) {
+                device = argv[1];
+                root_directory = false;
+        } else {
+                struct stat st;
+                struct timespec times[2];
+
+                /* Find root device */
+
+                if (stat("/", &st) < 0) {
+                        log_error("Failed to stat() the root directory: %m");
+                        goto finish;
+                }
+
+                /* Virtual root devices don't need an fsck */
+                if (major(st.st_dev) == 0)
+                        return 0;
+
+                /* check if we are already writable */
+                times[0] = st.st_atim;
+                times[1] = st.st_mtim;
+                if (utimensat(AT_FDCWD, "/", times, 0) == 0) {
+                        log_info("Root directory is writable, skipping check.");
+                        return 0;
+                }
+
+                if (!(udev = udev_new())) {
+                        log_oom();
+                        goto finish;
+                }
+
+                if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) {
+                        log_error("Failed to detect root device.");
+                        goto finish;
+                }
+
+                if (!(device = udev_device_get_devnode(udev_device))) {
+                        log_error("Failed to detect device node of root directory.");
+                        goto finish;
+                }
+
+                root_directory = true;
+        }
+
+        if (arg_show_progress)
+                if (pipe(progress_pipe) < 0) {
+                        log_error("pipe(): %m");
+                        goto finish;
+                }
+
+        cmdline[i++] = "/sbin/fsck";
+        cmdline[i++] = "-a";
+        cmdline[i++] = "-T";
+        cmdline[i++] = "-l";
+
+        if (!root_directory)
+                cmdline[i++] = "-M";
+
+        if (arg_force)
+                cmdline[i++] = "-f";
+
+        if (progress_pipe[1] >= 0) {
+                snprintf(dash_c, sizeof(dash_c), "-C%i", progress_pipe[1]);
+                char_array_0(dash_c);
+                cmdline[i++] = dash_c;
+        }
+
+        cmdline[i++] = device;
+        cmdline[i++] = NULL;
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("fork(): %m");
+                goto finish;
+        } else if (pid == 0) {
+                /* Child */
+                if (progress_pipe[0] >= 0)
+                        close_nointr_nofail(progress_pipe[0]);
+                execv(cmdline[0], (char**) cmdline);
+                _exit(8); /* Operational error */
+        }
+
+        if (progress_pipe[1] >= 0) {
+                close_nointr_nofail(progress_pipe[1]);
+                progress_pipe[1] = -1;
+        }
+
+        if (progress_pipe[0] >= 0) {
+                process_progress(progress_pipe[0]);
+                progress_pipe[0] = -1;
+        }
+
+        q = wait_for_terminate(pid, &status);
+        if (q < 0) {
+                log_error("waitid(): %s", strerror(-q));
+                goto finish;
+        }
+
+        if (status.si_code != CLD_EXITED || (status.si_status & ~1)) {
+
+                if (status.si_code == CLD_KILLED || status.si_code == CLD_DUMPED)
+                        log_error("fsck terminated by signal %s.", signal_to_string(status.si_status));
+                else if (status.si_code == CLD_EXITED)
+                        log_error("fsck failed with error code %i.", status.si_status);
+                else
+                        log_error("fsck failed due to unknown reason.");
+
+                if (status.si_code == CLD_EXITED && (status.si_status & 2) && root_directory)
+                        /* System should be rebooted. */
+                        start_target(SPECIAL_REBOOT_TARGET, false);
+                else if (status.si_code == CLD_EXITED && (status.si_status & 6))
+                        /* Some other problem */
+                        start_target(SPECIAL_EMERGENCY_TARGET, true);
+                else {
+                        r = EXIT_SUCCESS;
+                        log_warning("Ignoring error.");
+                }
+
+        } else
+                r = EXIT_SUCCESS;
+
+        if (status.si_code == CLD_EXITED && (status.si_status & 1))
+                touch("/run/systemd/quotacheck");
+
+finish:
+        if (udev_device)
+                udev_device_unref(udev_device);
+
+        if (udev)
+                udev_unref(udev);
+
+        close_pipe(progress_pipe);
+
+        return r;
+}
diff --git a/src/fstab-generator/Makefile b/src/fstab-generator/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
new file mode 100644 (file)
index 0000000..f3ecc24
--- /dev/null
@@ -0,0 +1,587 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <mntent.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+#include "unit-name.h"
+#include "path-util.h"
+#include "mount-setup.h"
+#include "special.h"
+#include "mkdir.h"
+#include "virt.h"
+
+static const char *arg_dest = "/tmp";
+static bool arg_enabled = true;
+
+static int device_name(const char *path, char **unit) {
+        char *p;
+
+        assert(path);
+
+        if (!is_device_path(path))
+                return 0;
+
+        p = unit_name_from_path(path, ".device");
+        if (!p)
+                return log_oom();
+
+        *unit = p;
+        return 1;
+}
+
+static int mount_find_pri(struct mntent *me, int *ret) {
+        char *end, *pri;
+        unsigned long r;
+
+        assert(me);
+        assert(ret);
+
+        pri = hasmntopt(me, "pri");
+        if (!pri)
+                return 0;
+
+        pri += 4;
+
+        errno = 0;
+        r = strtoul(pri, &end, 10);
+        if (errno != 0)
+                return -errno;
+
+        if (end == pri || (*end != ',' && *end != 0))
+                return -EINVAL;
+
+        *ret = (int) r;
+        return 1;
+}
+
+static int add_swap(const char *what, struct mntent *me) {
+        char _cleanup_free_ *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL;
+        FILE _cleanup_fclose_ *f = NULL;
+        bool noauto, nofail;
+        int r, pri = -1;
+
+        assert(what);
+        assert(me);
+
+        r = mount_find_pri(me, &pri);
+        if (r < 0) {
+                log_error("Failed to parse priority");
+                return pri;
+        }
+
+        noauto = !!hasmntopt(me, "noauto");
+        nofail = !!hasmntopt(me, "nofail");
+
+        name = unit_name_from_path(what, ".swap");
+        if (!name)
+                return log_oom();
+
+        unit = strjoin(arg_dest, "/", name, NULL);
+        if (!unit)
+                return log_oom();
+
+        f = fopen(unit, "wxe");
+        if (!f) {
+                if (errno == EEXIST)
+                        log_error("Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit);
+                else
+                        log_error("Failed to create unit file %s: %m", unit);
+                return -errno;
+        }
+
+        fputs("# Automatically generated by systemd-fstab-generator\n\n"
+              "[Unit]\n"
+              "SourcePath=/etc/fstab\n"
+              "DefaultDependencies=no\n"
+              "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
+              "Before=" SPECIAL_UMOUNT_TARGET "\n", f);
+
+        if (!noauto && !nofail)
+                fputs("Before=" SPECIAL_SWAP_TARGET "\n", f);
+
+        fprintf(f,
+                "\n"
+                "[Swap]\n"
+                "What=%s\n",
+                what);
+
+        if (pri >= 0)
+                fprintf(f,
+                        "Priority=%i\n",
+                        pri);
+
+        fflush(f);
+        if (ferror(f)) {
+                log_error("Failed to write unit file %s: %m", unit);
+                return -errno;
+        }
+
+        if (!noauto) {
+                lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
+                if (!lnk)
+                        return log_oom();
+
+                mkdir_parents_label(lnk, 0755);
+                if (symlink(unit, lnk) < 0) {
+                        log_error("Failed to create symlink %s: %m", lnk);
+                        return -errno;
+                }
+
+                r = device_name(what, &device);
+                if (r < 0)
+                        return r;
+
+                if (r > 0) {
+                        free(lnk);
+                        lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL);
+                        if (!lnk)
+                                return log_oom();
+
+                        mkdir_parents_label(lnk, 0755);
+                        if (symlink(unit, lnk) < 0) {
+                                log_error("Failed to create symlink %s: %m", lnk);
+                                return -errno;
+                        }
+                }
+        }
+
+        return 0;
+}
+
+static bool mount_is_bind(struct mntent *me) {
+        assert(me);
+
+        return
+                hasmntopt(me, "bind") ||
+                streq(me->mnt_type, "bind");
+}
+
+static bool mount_is_network(struct mntent *me) {
+        assert(me);
+
+        return
+                hasmntopt(me, "_netdev") ||
+                fstype_is_network(me->mnt_type);
+}
+
+static int add_mount(const char *what, const char *where, const char *type, const char *opts,
+                     int passno, bool wait, bool noauto, bool nofail, bool automount, bool isbind, bool isnetwork,
+                     const char *source) {
+        char _cleanup_free_
+                *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL,
+                *automount_name = NULL, *automount_unit = NULL;
+        FILE _cleanup_fclose_ *f = NULL;
+        int r;
+        const char *post, *pre;
+
+        assert(what);
+        assert(where);
+        assert(type);
+        assert(opts);
+        assert(source);
+
+        if (streq(type, "autofs"))
+                return 0;
+
+        if (!is_path(where)) {
+                log_warning("Mount point %s is not a valid path, ignoring.", where);
+                return 0;
+        }
+
+        if (mount_point_is_api(where) ||
+            mount_point_ignore(where))
+                return 0;
+
+        if (isnetwork) {
+                post = SPECIAL_REMOTE_FS_TARGET;
+                pre = SPECIAL_REMOTE_FS_PRE_TARGET;
+        } else {
+                post = SPECIAL_LOCAL_FS_TARGET;
+                pre = SPECIAL_LOCAL_FS_PRE_TARGET;
+        }
+
+        name = unit_name_from_path(where, ".mount");
+        if (!name)
+                return log_oom();
+
+        unit = strjoin(arg_dest, "/", name, NULL);
+        if (!unit)
+                return log_oom();
+
+        f = fopen(unit, "wxe");
+        if (!f) {
+                if (errno == EEXIST)
+                        log_error("Failed to create mount unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit);
+                else
+                        log_error("Failed to create unit file %s: %m", unit);
+                return -errno;
+        }
+
+        fprintf(f,
+              "# Automatically generated by systemd-fstab-generator\n\n"
+              "[Unit]\n"
+              "SourcePath=%s\n"
+              "DefaultDependencies=no\n",
+              source);
+
+        if (!path_equal(where, "/"))
+                fprintf(f,
+                        "After=%s\n"
+                        "Wants=%s\n"
+                        "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
+                        "Before=" SPECIAL_UMOUNT_TARGET "\n",
+                        pre,
+                        pre);
+
+
+        if (!noauto && !nofail && !automount)
+                fprintf(f,
+                        "Before=%s\n",
+                        post);
+
+        fprintf(f,
+                "\n"
+                "[Mount]\n"
+                "What=%s\n"
+                "Where=%s\n"
+                "Type=%s\n"
+                "FsckPassNo=%i\n",
+                what,
+                where,
+                type,
+                passno);
+
+        if (!isempty(opts) &&
+            !streq(opts, "defaults"))
+                fprintf(f,
+                        "Options=%s\n",
+                        opts);
+
+        if (wait)
+                fprintf(f,
+                        "TimeoutSec=0\n");
+
+        fflush(f);
+        if (ferror(f)) {
+                log_error("Failed to write unit file %s: %m", unit);
+                return -errno;
+        }
+
+        if (!noauto) {
+                lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
+                if (!lnk)
+                        return log_oom();
+
+                mkdir_parents_label(lnk, 0755);
+                if (symlink(unit, lnk) < 0) {
+                        log_error("Failed to create symlink %s: %m", lnk);
+                        return -errno;
+                }
+
+                if (!isbind &&
+                    !path_equal(where, "/")) {
+
+                        r = device_name(what, &device);
+                        if (r < 0)
+                                return r;
+
+                        if (r > 0) {
+                                free(lnk);
+                                lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL);
+                                if (!lnk)
+                                        return log_oom();
+
+                                mkdir_parents_label(lnk, 0755);
+                                if (symlink(unit, lnk) < 0) {
+                                        log_error("Failed to create symlink %s: %m", lnk);
+                                        return -errno;
+                                }
+                        }
+                }
+        }
+
+        if (automount && !path_equal(where, "/")) {
+                automount_name = unit_name_from_path(where, ".automount");
+                if (!name)
+                        return log_oom();
+
+                automount_unit = strjoin(arg_dest, "/", automount_name, NULL);
+                if (!automount_unit)
+                        return log_oom();
+
+                fclose(f);
+                f = fopen(automount_unit, "wxe");
+                if (!f) {
+                        log_error("Failed to create unit file %s: %m", automount_unit);
+                        return -errno;
+                }
+
+                fprintf(f,
+                        "# Automatically generated by systemd-fstab-generator\n\n"
+                        "[Unit]\n"
+                        "SourcePath=/etc/fstab\n"
+                        "DefaultDependencies=no\n"
+                        "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
+                        "Before=" SPECIAL_UMOUNT_TARGET " %s\n"
+                        "\n"
+                        "[Automount]\n"
+                        "Where=%s\n",
+                        post,
+                        where);
+
+                fflush(f);
+                if (ferror(f)) {
+                        log_error("Failed to write unit file %s: %m", automount_unit);
+                        return -errno;
+                }
+
+                free(lnk);
+                lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL);
+                if (!lnk)
+                        return log_oom();
+
+                mkdir_parents_label(lnk, 0755);
+                if (symlink(automount_unit, lnk) < 0) {
+                        log_error("Failed to create symlink %s: %m", lnk);
+                        return -errno;
+                }
+        }
+
+        return 0;
+}
+
+static int parse_fstab(void) {
+        FILE *f;
+        int r = 0;
+        struct mntent *me;
+
+        errno = 0;
+        f = setmntent("/etc/fstab", "r");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /etc/fstab: %m");
+                return -errno;
+        }
+
+        while ((me = getmntent(f))) {
+                char _cleanup_free_ *where = NULL, *what = NULL;
+                int k;
+
+                what = fstab_node_to_udev_node(me->mnt_fsname);
+                where = strdup(me->mnt_dir);
+                if (!what || !where) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                if (is_path(where))
+                        path_kill_slashes(where);
+
+                log_debug("Found entry what=%s where=%s type=%s", what, where, me->mnt_type);
+
+                if (streq(me->mnt_type, "swap"))
+                        k = add_swap(what, me);
+                else {
+                        bool noauto, nofail, automount, isbind, isnetwork;
+
+                        noauto = !!hasmntopt(me, "noauto");
+                        nofail = !!hasmntopt(me, "nofail");
+                        automount =
+                                  hasmntopt(me, "comment=systemd.automount") ||
+                                  hasmntopt(me, "x-systemd.automount");
+                        isbind = mount_is_bind(me);
+                        isnetwork = mount_is_network(me);
+
+                        k = add_mount(what, where, me->mnt_type, me->mnt_opts,
+                                     me->mnt_passno, false, noauto, nofail,
+                                     automount, isbind, isnetwork,
+                                     "/etc/fstab");
+                }
+
+                if (k < 0)
+                        r = k;
+        }
+
+finish:
+        endmntent(f);
+        return r;
+}
+
+static int parse_new_root_from_proc_cmdline(void) {
+        char *w, *state;
+        _cleanup_free_ char *what = NULL, *type = NULL, *opts = NULL, *line = NULL;
+        int r;
+        size_t l;
+        bool wait = false;
+
+        r = read_one_line_file("/proc/cmdline", &line);
+        if (r < 0) {
+                log_error("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        opts = strdup("defaults");
+        type = strdup("auto");
+        if (!opts || !type)
+                return log_oom();
+
+       /* root= and roofstype= may occur more than once, the last instance should take precedence.
+        * In the case of multiple rootflags= the arguments should be concatenated */
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                char *word, *tmp_word;
+
+                word = strndup(w, l);
+                if (!word)
+                        return log_oom();
+
+                else if (startswith(word, "root=")) {
+                        free(what);
+                        what = fstab_node_to_udev_node(word+5);
+                        if (!what)
+                                return log_oom();
+
+                } else if (startswith(word, "rootfstype=")) {
+                        free(type);
+                        type = strdup(word + 11);
+                        if (!type)
+                                return log_oom();
+
+                } else if (startswith(word, "rootflags=")) {
+                        tmp_word = opts;
+                        opts = strjoin(opts, ",", word + 10, NULL);
+                        free(tmp_word);
+                        if (!opts)
+                                return log_oom();
+
+                } else if (streq(word, "ro") || streq(word, "rw")) {
+                        tmp_word = opts;
+                        opts = strjoin(opts, ",", word, NULL);
+                        free(tmp_word);
+                        if (!opts)
+                                return log_oom();
+
+                } else if (streq(word, "rootwait"))
+                        wait = true;
+
+                free(word);
+        }
+
+        if (what) {
+
+                log_debug("Found entry what=%s where=/new_root type=%s", what, type);
+                r = add_mount(what, "/new_root", type, opts, 0, wait, false, false,
+                              false, false, false, "/proc/cmdline");
+
+                if (r < 0)
+                        return r;
+        } else
+                log_error("Could not find a root= entry on the kernel commandline.");
+
+        return 0;
+}
+
+static int parse_proc_cmdline(void) {
+        char _cleanup_free_ *line = NULL;
+        char *w, *state;
+        int r;
+        size_t l;
+
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        r = read_one_line_file("/proc/cmdline", &line);
+        if (r < 0) {
+                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                char _cleanup_free_ *word = NULL;
+
+                word = strndup(w, l);
+                if (!word)
+                        return log_oom();
+
+                if (startswith(word, "fstab=")) {
+                        r = parse_boolean(word + 6);
+                        if (r < 0)
+                                log_warning("Failed to parse fstab switch %s. Ignoring.", word + 6);
+                        else
+                                arg_enabled = r;
+
+                } else if (startswith(word, "rd.fstab=")) {
+
+                        if (in_initrd()) {
+                                r = parse_boolean(word + 6);
+                                if (r < 0)
+                                        log_warning("Failed to parse fstab switch %s. Ignoring.", word + 6);
+                                else
+                                        arg_enabled = r;
+                        }
+
+                } else if (startswith(word, "fstab.") ||
+                           (in_initrd() && startswith(word, "rd.fstab."))) {
+
+                        log_warning("Unknown kernel switch %s. Ignoring.", word);
+                }
+        }
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        int r, k = 0;
+
+        if (argc > 1 && argc != 4) {
+                log_error("This program takes three or no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1)
+                arg_dest = argv[1];
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (parse_proc_cmdline() < 0)
+                return EXIT_FAILURE;
+
+        if (in_initrd())
+                k = parse_new_root_from_proc_cmdline();
+
+        if (!arg_enabled)
+                return EXIT_SUCCESS;
+
+        r = parse_fstab();
+
+        return (r < 0) || (k < 0) ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/getty-generator/Makefile b/src/getty-generator/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c
new file mode 100644 (file)
index 0000000..cb38f21
--- /dev/null
@@ -0,0 +1,180 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+#include "mkdir.h"
+#include "unit-name.h"
+#include "virt.h"
+
+static const char *arg_dest = "/tmp";
+
+static int add_symlink(const char *fservice, const char *tservice) {
+        char *from = NULL, *to = NULL;
+        int r;
+
+        assert(fservice);
+        assert(tservice);
+
+        from = strappend(SYSTEM_DATA_UNIT_PATH "/", fservice);
+        to = strjoin(arg_dest,"/getty.target.wants/", tservice, NULL);
+
+        if (!from || !to) {
+                r = log_oom();
+                goto finish;
+        }
+
+        mkdir_parents_label(to, 0755);
+
+        r = symlink(from, to);
+        if (r < 0) {
+                if (errno == EEXIST)
+                        /* In case console=hvc0 is passed this will very likely result in EEXIST */
+                        r = 0;
+                else {
+                        log_error("Failed to create symlink from %s to %s: %m", from, to);
+                        r = -errno;
+                }
+        }
+
+finish:
+
+        free(from);
+        free(to);
+
+        return r;
+}
+
+static int add_serial_getty(const char *tty) {
+        char *n;
+        int r;
+
+        assert(tty);
+
+        log_debug("Automatically adding serial getty for /dev/%s.", tty);
+
+        n = unit_name_replace_instance("serial-getty@.service", tty);
+        if (!n)
+                return log_oom();
+
+        r = add_symlink("serial-getty@.service", n);
+        free(n);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+
+        static const char virtualization_consoles[] =
+                "hvc0\0"
+                "xvc0\0"
+                "hvsi0\0";
+
+        int r = EXIT_SUCCESS;
+        char *active;
+        const char *j;
+
+        if (argc > 1 && argc != 4) {
+                log_error("This program takes three or no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1)
+                arg_dest = argv[1];
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (detect_container(NULL) > 0) {
+                log_debug("Automatically adding console shell.");
+
+                if (add_symlink("console-getty.service", "console-getty.service") < 0)
+                        r = EXIT_FAILURE;
+
+                /* Don't add any further magic if we are in a container */
+                goto finish;
+        }
+
+        if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
+                const char *tty;
+
+                tty = strrchr(active, ' ');
+                if (tty)
+                        tty ++;
+                else
+                        tty = active;
+
+                /* Automatically add in a serial getty on the kernel
+                 * console */
+                if (isempty(tty) || tty_is_vc(tty))
+                        free(active);
+                else {
+                        int k;
+
+                        /* We assume that gettys on virtual terminals are
+                         * started via manual configuration and do this magic
+                         * only for non-VC terminals. */
+
+                        k = add_serial_getty(tty);
+                        free(active);
+
+                        if (k < 0) {
+                                r = EXIT_FAILURE;
+                                goto finish;
+                        }
+                }
+        }
+
+        /* Automatically add in a serial getty on the first
+         * virtualizer console */
+        NULSTR_FOREACH(j, virtualization_consoles) {
+                char *p;
+                int k;
+
+                if (asprintf(&p, "/sys/class/tty/%s", j) < 0) {
+                        log_oom();
+                        r = EXIT_FAILURE;
+                        goto finish;
+                }
+
+                k = access(p, F_OK);
+                free(p);
+
+                if (k < 0)
+                        continue;
+
+                k = add_serial_getty(j);
+                if (k < 0) {
+                        r = EXIT_FAILURE;
+                        goto finish;
+                }
+        }
+
+finish:
+        return r;
+}
diff --git a/src/gudev/.gitignore b/src/gudev/.gitignore
new file mode 100644 (file)
index 0000000..4577903
--- /dev/null
@@ -0,0 +1,7 @@
+gudev-1.0.pc
+gudevenumtypes.c
+gudevenumtypes.h
+gudevmarshal.c
+gudevmarshal.h
+GUdev-1.0.gir
+GUdev-1.0.typelib
diff --git a/src/gudev/Makefile b/src/gudev/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/gudev/gjs-example.js b/src/gudev/gjs-example.js
new file mode 100755 (executable)
index 0000000..5586fd6
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env gjs-console
+
+// This currently depends on the following patches to gjs
+//
+// http://bugzilla.gnome.org/show_bug.cgi?id=584558
+// http://bugzilla.gnome.org/show_bug.cgi?id=584560
+// http://bugzilla.gnome.org/show_bug.cgi?id=584568
+
+const GUdev = imports.gi.GUdev;
+const Mainloop = imports.mainloop;
+
+function print_device (device) {
+  print ("  subsystem:             " + device.get_subsystem ());
+  print ("  devtype:               " + device.get_devtype ());
+  print ("  name:                  " + device.get_name ());
+  print ("  number:                " + device.get_number ());
+  print ("  sysfs_path:            " + device.get_sysfs_path ());
+  print ("  driver:                " + device.get_driver ());
+  print ("  action:                " + device.get_action ());
+  print ("  seqnum:                " + device.get_seqnum ());
+  print ("  device type:           " + device.get_device_type ());
+  print ("  device number:         " + device.get_device_number ());
+  print ("  device file:           " + device.get_device_file ());
+  print ("  device file symlinks:  " + device.get_device_file_symlinks ());
+  print ("  foo: " + device.get_sysfs_attr_as_strv ("stat"));
+  var keys = device.get_property_keys ();
+  for (var n = 0; n < keys.length; n++) {
+    print ("    " + keys[n] + "=" + device.get_property (keys[n]));
+  }
+}
+
+function on_uevent (client, action, device) {
+  print ("action " + action + " on device " + device.get_sysfs_path());
+  print_device (device);
+  print ("");
+}
+
+var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
+client.connect ("uevent", on_uevent);
+
+var block_devices = client.query_by_subsystem ("block");
+for (var n = 0; n < block_devices.length; n++) {
+  print ("block device: " + block_devices[n].get_device_file ());
+}
+
+var d;
+
+d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
+if (d == null) {
+  print ("query_by_device_number 0x810 -> null");
+} else {
+  print ("query_by_device_number 0x810 -> " + d.get_device_file ());
+  var dd = d.get_parent_with_subsystem ("usb", null);
+  print_device (dd);
+  print ("--------------------------------------------------------------------------");
+  while (d != null) {
+    print_device (d);
+    print ("");
+    d = d.get_parent ();
+  }
+}
+
+d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
+print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
+
+d = client.query_by_subsystem_and_name ("block", "sda2");
+print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/sda");
+print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/block/8:0");
+print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
+
+Mainloop.run('udev-example');
diff --git a/src/gudev/gudev-1.0.pc.in b/src/gudev/gudev-1.0.pc.in
new file mode 100644 (file)
index 0000000..058262d
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gudev-1.0
+Description: GObject bindings for libudev
+Version: @VERSION@
+Requires: glib-2.0, gobject-2.0
+Libs: -L${libdir} -lgudev-1.0
+Cflags: -I${includedir}/gudev-1.0
diff --git a/src/gudev/gudev.h b/src/gudev/gudev.h
new file mode 100644 (file)
index 0000000..1dc42b1
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __G_UDEV_H__
+#define __G_UDEV_H__
+
+#define _GUDEV_INSIDE_GUDEV_H
+#include <gudev/gudevenums.h>
+#include <gudev/gudevenumtypes.h>
+#include <gudev/gudevtypes.h>
+#include <gudev/gudevclient.h>
+#include <gudev/gudevdevice.h>
+#include <gudev/gudevenumerator.h>
+#undef _GUDEV_INSIDE_GUDEV_H
+
+#endif /* __G_UDEV_H__ */
diff --git a/src/gudev/gudevclient.c b/src/gudev/gudevclient.c
new file mode 100644 (file)
index 0000000..a151b50
--- /dev/null
@@ -0,0 +1,525 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gudevclient.h"
+#include "gudevdevice.h"
+#include "gudevmarshal.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevclient
+ * @short_description: Query devices and listen to uevents
+ *
+ * #GUdevClient is used to query information about devices on a Linux
+ * system from the Linux kernel and the udev device
+ * manager.
+ *
+ * Device information is retrieved from the kernel (through the
+ * <literal>sysfs</literal> filesystem) and the udev daemon (through a
+ * <literal>tmpfs</literal> filesystem) and presented through
+ * #GUdevDevice objects. This means that no blocking IO ever happens
+ * (in both cases, we are essentially just reading data from kernel
+ * memory) and as such there are no asynchronous versions of the
+ * provided methods.
+ *
+ * To get #GUdevDevice objects, use
+ * g_udev_client_query_by_subsystem(),
+ * g_udev_client_query_by_device_number(),
+ * g_udev_client_query_by_device_file(),
+ * g_udev_client_query_by_sysfs_path(),
+ * g_udev_client_query_by_subsystem_and_name()
+ * or the #GUdevEnumerator type.
+ *
+ * To listen to uevents, connect to the #GUdevClient::uevent signal.
+ */
+
+struct _GUdevClientPrivate
+{
+  GSource *watch_source;
+  struct udev *udev;
+  struct udev_monitor *monitor;
+
+  gchar **subsystems;
+};
+
+enum
+{
+  PROP_0,
+  PROP_SUBSYSTEMS,
+};
+
+enum
+{
+  UEVENT_SIGNAL,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GUdevClient, g_udev_client, G_TYPE_OBJECT)
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+monitor_event (GIOChannel *source,
+               GIOCondition condition,
+               gpointer data)
+{
+  GUdevClient *client = (GUdevClient *) data;
+  GUdevDevice *device;
+  struct udev_device *udevice;
+
+  if (client->priv->monitor == NULL)
+    goto out;
+  udevice = udev_monitor_receive_device (client->priv->monitor);
+  if (udevice == NULL)
+    goto out;
+
+  device = _g_udev_device_new (udevice);
+  udev_device_unref (udevice);
+  g_signal_emit (client,
+                 signals[UEVENT_SIGNAL],
+                 0,
+                 g_udev_device_get_action (device),
+                 device);
+  g_object_unref (device);
+
+ out:
+  return TRUE;
+}
+
+static void
+g_udev_client_finalize (GObject *object)
+{
+  GUdevClient *client = G_UDEV_CLIENT (object);
+
+  if (client->priv->watch_source != NULL)
+    {
+      g_source_destroy (client->priv->watch_source);
+      client->priv->watch_source = NULL;
+    }
+
+  if (client->priv->monitor != NULL)
+    {
+      udev_monitor_unref (client->priv->monitor);
+      client->priv->monitor = NULL;
+    }
+
+  if (client->priv->udev != NULL)
+    {
+      udev_unref (client->priv->udev);
+      client->priv->udev = NULL;
+    }
+
+  g_strfreev (client->priv->subsystems);
+
+  if (G_OBJECT_CLASS (g_udev_client_parent_class)->finalize != NULL)
+    G_OBJECT_CLASS (g_udev_client_parent_class)->finalize (object);
+}
+
+static void
+g_udev_client_set_property (GObject      *object,
+                            guint         prop_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+  GUdevClient *client = G_UDEV_CLIENT (object);
+
+  switch (prop_id)
+    {
+    case PROP_SUBSYSTEMS:
+      if (client->priv->subsystems != NULL)
+        g_strfreev (client->priv->subsystems);
+      client->priv->subsystems = g_strdupv (g_value_get_boxed (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_udev_client_get_property (GObject     *object,
+                            guint        prop_id,
+                            GValue      *value,
+                            GParamSpec  *pspec)
+{
+  GUdevClient *client = G_UDEV_CLIENT (object);
+
+  switch (prop_id)
+    {
+    case PROP_SUBSYSTEMS:
+      g_value_set_boxed (value, client->priv->subsystems);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_udev_client_constructed (GObject *object)
+{
+  GUdevClient *client = G_UDEV_CLIENT (object);
+  GIOChannel *channel;
+  guint n;
+
+  client->priv->udev = udev_new ();
+
+  /* connect to event source */
+  client->priv->monitor = udev_monitor_new_from_netlink (client->priv->udev, "udev");
+
+  //g_debug ("ss = %p", client->priv->subsystems);
+
+  if (client->priv->subsystems != NULL)
+    {
+      /* install subsystem filters to only wake up for certain events */
+      for (n = 0; client->priv->subsystems[n] != NULL; n++)
+        {
+          gchar *subsystem;
+          gchar *devtype;
+          gchar *s;
+
+          subsystem = g_strdup (client->priv->subsystems[n]);
+          devtype = NULL;
+
+          //g_debug ("s = '%s'", subsystem);
+
+          s = strstr (subsystem, "/");
+          if (s != NULL)
+            {
+              devtype = s + 1;
+              *s = '\0';
+            }
+
+          if (client->priv->monitor != NULL)
+              udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);
+
+          g_free (subsystem);
+        }
+
+      /* listen to events, and buffer them */
+      if (client->priv->monitor != NULL)
+        {
+          udev_monitor_enable_receiving (client->priv->monitor);
+          channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
+          client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
+          g_io_channel_unref (channel);
+          g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL);
+          g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ());
+          g_source_unref (client->priv->watch_source);
+        }
+      else
+        {
+          client->priv->watch_source = NULL;
+        }
+    }
+
+  if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL)
+    G_OBJECT_CLASS (g_udev_client_parent_class)->constructed (object);
+}
+
+
+static void
+g_udev_client_class_init (GUdevClientClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+
+  gobject_class->constructed  = g_udev_client_constructed;
+  gobject_class->set_property = g_udev_client_set_property;
+  gobject_class->get_property = g_udev_client_get_property;
+  gobject_class->finalize     = g_udev_client_finalize;
+
+  /**
+   * GUdevClient:subsystems:
+   *
+   * The subsystems to listen for uevents on.
+   *
+   * To listen for only a specific DEVTYPE for a given SUBSYSTEM, use
+   * "subsystem/devtype". For example, to only listen for uevents
+   * where SUBSYSTEM is usb and DEVTYPE is usb_interface, use
+   * "usb/usb_interface".
+   *
+   * If this property is %NULL, then no events will be reported. If
+   * it's the empty array, events from all subsystems will be
+   * reported.
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_SUBSYSTEMS,
+                                   g_param_spec_boxed ("subsystems",
+                                                       "The subsystems to listen for changes on",
+                                                       "The subsystems to listen for changes on",
+                                                       G_TYPE_STRV,
+                                                       G_PARAM_CONSTRUCT_ONLY |
+                                                       G_PARAM_READWRITE));
+
+  /**
+   * GUdevClient::uevent:
+   * @client: The #GUdevClient receiving the event.
+   * @action: The action for the uevent e.g. "add", "remove", "change", "move", etc.
+   * @device: Details about the #GUdevDevice the event is for.
+   *
+   * Emitted when @client receives an uevent.
+   *
+   * This signal is emitted in the
+   * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+   * of the thread that @client was created in.
+   */
+  signals[UEVENT_SIGNAL] = g_signal_new ("uevent",
+                                         G_TYPE_FROM_CLASS (klass),
+                                         G_SIGNAL_RUN_LAST,
+                                         G_STRUCT_OFFSET (GUdevClientClass, uevent),
+                                         NULL,
+                                         NULL,
+                                         g_udev_marshal_VOID__STRING_OBJECT,
+                                         G_TYPE_NONE,
+                                         2,
+                                         G_TYPE_STRING,
+                                         G_UDEV_TYPE_DEVICE);
+
+  g_type_class_add_private (klass, sizeof (GUdevClientPrivate));
+}
+
+static void
+g_udev_client_init (GUdevClient *client)
+{
+  client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
+                                              G_UDEV_TYPE_CLIENT,
+                                              GUdevClientPrivate);
+}
+
+/**
+ * g_udev_client_new:
+ * @subsystems: (array zero-terminated=1) (element-type utf8) (transfer none) (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter.
+ *
+ * Constructs a #GUdevClient object that can be used to query
+ * information about devices. Connect to the #GUdevClient::uevent
+ * signal to listen for uevents. Note that signals are emitted in the
+ * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+ * of the thread that you call this constructor from.
+ *
+ * Returns: A new #GUdevClient object. Free with g_object_unref().
+ */
+GUdevClient *
+g_udev_client_new (const gchar * const *subsystems)
+{
+  return G_UDEV_CLIENT (g_object_new (G_UDEV_TYPE_CLIENT, "subsystems", subsystems, NULL));
+}
+
+/**
+ * g_udev_client_query_by_subsystem:
+ * @client: A #GUdevClient.
+ * @subsystem: (allow-none): The subsystem to get devices for or %NULL to get all devices.
+ *
+ * Gets all devices belonging to @subsystem.
+ *
+ * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
+ */
+GList *
+g_udev_client_query_by_subsystem (GUdevClient  *client,
+                                  const gchar  *subsystem)
+{
+  struct udev_enumerate *enumerate;
+  struct udev_list_entry *l, *devices;
+  GList *ret;
+
+  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+
+  ret = NULL;
+
+  /* prepare a device scan */
+  enumerate = udev_enumerate_new (client->priv->udev);
+
+  /* filter for subsystem */
+  if (subsystem != NULL)
+    udev_enumerate_add_match_subsystem (enumerate, subsystem);
+  /* retrieve the list */
+  udev_enumerate_scan_devices (enumerate);
+
+  /* add devices to the list */
+  devices = udev_enumerate_get_list_entry (enumerate);
+  for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
+    {
+      struct udev_device *udevice;
+      GUdevDevice *device;
+
+      udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
+                                              udev_list_entry_get_name (l));
+      if (udevice == NULL)
+        continue;
+      device = _g_udev_device_new (udevice);
+      udev_device_unref (udevice);
+      ret = g_list_prepend (ret, device);
+    }
+  udev_enumerate_unref (enumerate);
+
+  ret = g_list_reverse (ret);
+
+  return ret;
+}
+
+/**
+ * g_udev_client_query_by_device_number:
+ * @client: A #GUdevClient.
+ * @type: A value from the #GUdevDeviceType enumeration.
+ * @number: A device number.
+ *
+ * Looks up a device for a type and device number.
+ *
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_device_number (GUdevClient      *client,
+                                      GUdevDeviceType   type,
+                                      GUdevDeviceNumber number)
+{
+  struct udev_device *udevice;
+  GUdevDevice *device;
+
+  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+
+  device = NULL;
+  udevice = udev_device_new_from_devnum (client->priv->udev, type, number);
+
+  if (udevice == NULL)
+    goto out;
+
+  device = _g_udev_device_new (udevice);
+  udev_device_unref (udevice);
+
+ out:
+  return device;
+}
+
+/**
+ * g_udev_client_query_by_device_file:
+ * @client: A #GUdevClient.
+ * @device_file: A device file.
+ *
+ * Looks up a device for a device file.
+ *
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_device_file (GUdevClient  *client,
+                                    const gchar  *device_file)
+{
+  struct stat stat_buf;
+  GUdevDevice *device;
+
+  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+  g_return_val_if_fail (device_file != NULL, NULL);
+
+  device = NULL;
+
+  if (stat (device_file, &stat_buf) != 0)
+    goto out;
+
+  if (stat_buf.st_rdev == 0)
+    goto out;
+
+  if (S_ISBLK (stat_buf.st_mode))
+    device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_BLOCK, stat_buf.st_rdev);
+  else if (S_ISCHR (stat_buf.st_mode))
+    device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_CHAR, stat_buf.st_rdev);
+
+ out:
+  return device;
+}
+
+/**
+ * g_udev_client_query_by_sysfs_path:
+ * @client: A #GUdevClient.
+ * @sysfs_path: A sysfs path.
+ *
+ * Looks up a device for a sysfs path.
+ *
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_sysfs_path (GUdevClient  *client,
+                                   const gchar  *sysfs_path)
+{
+  struct udev_device *udevice;
+  GUdevDevice *device;
+
+  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+  g_return_val_if_fail (sysfs_path != NULL, NULL);
+
+  device = NULL;
+  udevice = udev_device_new_from_syspath (client->priv->udev, sysfs_path);
+  if (udevice == NULL)
+    goto out;
+
+  device = _g_udev_device_new (udevice);
+  udev_device_unref (udevice);
+
+ out:
+  return device;
+}
+
+/**
+ * g_udev_client_query_by_subsystem_and_name:
+ * @client: A #GUdevClient.
+ * @subsystem: A subsystem name.
+ * @name: The name of the device.
+ *
+ * Looks up a device for a subsystem and name.
+ *
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_subsystem_and_name (GUdevClient  *client,
+                                           const gchar  *subsystem,
+                                           const gchar  *name)
+{
+  struct udev_device *udevice;
+  GUdevDevice *device;
+
+  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+  g_return_val_if_fail (subsystem != NULL, NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  device = NULL;
+  udevice = udev_device_new_from_subsystem_sysname (client->priv->udev, subsystem, name);
+  if (udevice == NULL)
+    goto out;
+
+  device = _g_udev_device_new (udevice);
+  udev_device_unref (udevice);
+
+ out:
+  return device;
+}
+
+struct udev *
+_g_udev_client_get_udev (GUdevClient *client)
+{
+  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+  return client->priv->udev;
+}
diff --git a/src/gudev/gudevclient.h b/src/gudev/gudevclient.h
new file mode 100644 (file)
index 0000000..23bfce6
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_CLIENT_H__
+#define __G_UDEV_CLIENT_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_CLIENT         (g_udev_client_get_type ())
+#define G_UDEV_CLIENT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_CLIENT, GUdevClient))
+#define G_UDEV_CLIENT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_CLIENT, GUdevClientClass))
+#define G_UDEV_IS_CLIENT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_CLIENT))
+#define G_UDEV_IS_CLIENT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_CLIENT))
+#define G_UDEV_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_CLIENT, GUdevClientClass))
+
+typedef struct _GUdevClientClass   GUdevClientClass;
+typedef struct _GUdevClientPrivate GUdevClientPrivate;
+
+/**
+ * GUdevClient:
+ *
+ * The #GUdevClient struct is opaque and should not be accessed directly.
+ */
+struct _GUdevClient
+{
+  GObject              parent;
+
+  /*< private >*/
+  GUdevClientPrivate *priv;
+};
+
+/**
+ * GUdevClientClass:
+ * @parent_class: Parent class.
+ * @uevent: Signal class handler for the #GUdevClient::uevent signal.
+ *
+ * Class structure for #GUdevClient.
+ */
+struct _GUdevClientClass
+{
+  GObjectClass   parent_class;
+
+  /* signals */
+  void (*uevent) (GUdevClient  *client,
+                  const gchar  *action,
+                  GUdevDevice  *device);
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*reserved1) (void);
+  void (*reserved2) (void);
+  void (*reserved3) (void);
+  void (*reserved4) (void);
+  void (*reserved5) (void);
+  void (*reserved6) (void);
+  void (*reserved7) (void);
+  void (*reserved8) (void);
+};
+
+GType        g_udev_client_get_type                    (void) G_GNUC_CONST;
+GUdevClient *g_udev_client_new                         (const gchar* const *subsystems);
+GList       *g_udev_client_query_by_subsystem          (GUdevClient        *client,
+                                                        const gchar        *subsystem);
+GUdevDevice *g_udev_client_query_by_device_number      (GUdevClient        *client,
+                                                        GUdevDeviceType     type,
+                                                        GUdevDeviceNumber   number);
+GUdevDevice *g_udev_client_query_by_device_file        (GUdevClient        *client,
+                                                        const gchar        *device_file);
+GUdevDevice *g_udev_client_query_by_sysfs_path         (GUdevClient        *client,
+                                                        const gchar        *sysfs_path);
+GUdevDevice *g_udev_client_query_by_subsystem_and_name (GUdevClient        *client,
+                                                        const gchar        *subsystem,
+                                                        const gchar        *name);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_CLIENT_H__ */
diff --git a/src/gudev/gudevdevice.c b/src/gudev/gudevdevice.c
new file mode 100644 (file)
index 0000000..6c9e0f5
--- /dev/null
@@ -0,0 +1,961 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gudevdevice.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevdevice
+ * @short_description: Get information about a device
+ *
+ * The #GUdevDevice class is used to get information about a specific
+ * device. Note that you cannot instantiate a #GUdevDevice object
+ * yourself. Instead you must use #GUdevClient to obtain #GUdevDevice
+ * objects.
+ *
+ * To get basic information about a device, use
+ * g_udev_device_get_subsystem(), g_udev_device_get_devtype(),
+ * g_udev_device_get_name(), g_udev_device_get_number(),
+ * g_udev_device_get_sysfs_path(), g_udev_device_get_driver(),
+ * g_udev_device_get_action(), g_udev_device_get_seqnum(),
+ * g_udev_device_get_device_type(), g_udev_device_get_device_number(),
+ * g_udev_device_get_device_file(),
+ * g_udev_device_get_device_file_symlinks().
+ *
+ * To navigate the device tree, use g_udev_device_get_parent() and
+ * g_udev_device_get_parent_with_subsystem().
+ *
+ * To access udev properties for the device, use
+ * g_udev_device_get_property_keys(),
+ * g_udev_device_has_property(),
+ * g_udev_device_get_property(),
+ * g_udev_device_get_property_as_int(),
+ * g_udev_device_get_property_as_uint64(),
+ * g_udev_device_get_property_as_double(),
+ * g_udev_device_get_property_as_boolean() and
+ * g_udev_device_get_property_as_strv().
+ *
+ * To access sysfs attributes for the device, use
+ * g_udev_device_get_sysfs_attr(),
+ * g_udev_device_get_sysfs_attr_as_int(),
+ * g_udev_device_get_sysfs_attr_as_uint64(),
+ * g_udev_device_get_sysfs_attr_as_double(),
+ * g_udev_device_get_sysfs_attr_as_boolean() and
+ * g_udev_device_get_sysfs_attr_as_strv().
+ *
+ * Note that all getters on #GUdevDevice are non-reffing – returned
+ * values are owned by the object, should not be freed and are only
+ * valid as long as the object is alive.
+ *
+ * By design, #GUdevDevice will not react to changes for a device – it
+ * only contains a snapshot of information when the #GUdevDevice
+ * object was created. To work with changes, you typically connect to
+ * the #GUdevClient::uevent signal on a #GUdevClient and get a new
+ * #GUdevDevice whenever an event happens.
+ */
+
+struct _GUdevDevicePrivate
+{
+  struct udev_device *udevice;
+
+  /* computed ondemand and cached */
+  gchar **device_file_symlinks;
+  gchar **property_keys;
+  gchar **tags;
+  GHashTable *prop_strvs;
+  GHashTable *sysfs_attr_strvs;
+};
+
+G_DEFINE_TYPE (GUdevDevice, g_udev_device, G_TYPE_OBJECT)
+
+static void
+g_udev_device_finalize (GObject *object)
+{
+  GUdevDevice *device = G_UDEV_DEVICE (object);
+
+  g_strfreev (device->priv->device_file_symlinks);
+  g_strfreev (device->priv->property_keys);
+  g_strfreev (device->priv->tags);
+
+  if (device->priv->udevice != NULL)
+    udev_device_unref (device->priv->udevice);
+
+  if (device->priv->prop_strvs != NULL)
+    g_hash_table_unref (device->priv->prop_strvs);
+
+  if (device->priv->sysfs_attr_strvs != NULL)
+    g_hash_table_unref (device->priv->sysfs_attr_strvs);
+
+  if (G_OBJECT_CLASS (g_udev_device_parent_class)->finalize != NULL)
+    (* G_OBJECT_CLASS (g_udev_device_parent_class)->finalize) (object);
+}
+
+static void
+g_udev_device_class_init (GUdevDeviceClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+
+  gobject_class->finalize = g_udev_device_finalize;
+
+  g_type_class_add_private (klass, sizeof (GUdevDevicePrivate));
+}
+
+static void
+g_udev_device_init (GUdevDevice *device)
+{
+  device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
+                                              G_UDEV_TYPE_DEVICE,
+                                              GUdevDevicePrivate);
+}
+
+
+GUdevDevice *
+_g_udev_device_new (struct udev_device *udevice)
+{
+  GUdevDevice *device;
+
+  device =  G_UDEV_DEVICE (g_object_new (G_UDEV_TYPE_DEVICE, NULL));
+  device->priv->udevice = udev_device_ref (udevice);
+
+  return device;
+}
+
+/**
+ * g_udev_device_get_subsystem:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the subsystem for @device.
+ *
+ * Returns: The subsystem for @device.
+ */
+const gchar *
+g_udev_device_get_subsystem (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  return udev_device_get_subsystem (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_devtype:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device type for @device.
+ *
+ * Returns: The devtype for @device.
+ */
+const gchar *
+g_udev_device_get_devtype (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  return udev_device_get_devtype (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_name:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the name of @device, e.g. "sda3".
+ *
+ * Returns: The name of @device.
+ */
+const gchar *
+g_udev_device_get_name (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  return udev_device_get_sysname (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_number:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the number of @device, e.g. "3" if g_udev_device_get_name() returns "sda3".
+ *
+ * Returns: The number of @device.
+ */
+const gchar *
+g_udev_device_get_number (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  return udev_device_get_sysnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_sysfs_path:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the sysfs path for @device.
+ *
+ * Returns: The sysfs path for @device.
+ */
+const gchar *
+g_udev_device_get_sysfs_path (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  return udev_device_get_syspath (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_driver:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the name of the driver used for @device.
+ *
+ * Returns: The name of the driver for @device or %NULL if unknown.
+ */
+const gchar *
+g_udev_device_get_driver (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  return udev_device_get_driver (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_action:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the most recent action (e.g. "add", "remove", "change", etc.) for @device.
+ *
+ * Returns: An action string.
+ */
+const gchar *
+g_udev_device_get_action (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  return udev_device_get_action (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_seqnum:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the most recent sequence number for @device.
+ *
+ * Returns: A sequence number.
+ */
+guint64
+g_udev_device_get_seqnum (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+  return udev_device_get_seqnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_type:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the type of the device file, if any, for @device.
+ *
+ * Returns: The device number for @device or #G_UDEV_DEVICE_TYPE_NONE if the device does not have a device file.
+ */
+GUdevDeviceType
+g_udev_device_get_device_type (GUdevDevice *device)
+{
+  struct stat stat_buf;
+  const gchar *device_file;
+  GUdevDeviceType type;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), G_UDEV_DEVICE_TYPE_NONE);
+
+  type = G_UDEV_DEVICE_TYPE_NONE;
+
+  /* TODO: would be better to have support for this in libudev... */
+
+  device_file = g_udev_device_get_device_file (device);
+  if (device_file == NULL)
+    goto out;
+
+  if (stat (device_file, &stat_buf) != 0)
+    goto out;
+
+  if (S_ISBLK (stat_buf.st_mode))
+    type = G_UDEV_DEVICE_TYPE_BLOCK;
+  else if (S_ISCHR (stat_buf.st_mode))
+    type = G_UDEV_DEVICE_TYPE_CHAR;
+
+ out:
+  return type;
+}
+
+/**
+ * g_udev_device_get_device_number:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device number, if any, for @device.
+ *
+ * Returns: The device number for @device or 0 if unknown.
+ */
+GUdevDeviceNumber
+g_udev_device_get_device_number (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+  return udev_device_get_devnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_file:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device file for @device.
+ *
+ * Returns: The device file for @device or %NULL if no device file
+ * exists.
+ */
+const gchar *
+g_udev_device_get_device_file (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  return udev_device_get_devnode (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_file_symlinks:
+ * @device: A #GUdevDevice.
+ *
+ * Gets a list of symlinks (in <literal>/dev</literal>) that points to
+ * the device file for @device.
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of symlinks. This array is owned by @device and should not be freed by the caller.
+ */
+const gchar * const *
+g_udev_device_get_device_file_symlinks (GUdevDevice *device)
+{
+  struct udev_list_entry *l;
+  GPtrArray *p;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+  if (device->priv->device_file_symlinks != NULL)
+    goto out;
+
+  p = g_ptr_array_new ();
+  for (l = udev_device_get_devlinks_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+    {
+      g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+    }
+  g_ptr_array_add (p, NULL);
+  device->priv->device_file_symlinks = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+  return (const gchar * const *) device->priv->device_file_symlinks;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_parent:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the immediate parent of @device, if any.
+ *
+ * Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_device_get_parent (GUdevDevice  *device)
+{
+  GUdevDevice *ret;
+  struct udev_device *udevice;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+  ret = NULL;
+
+  udevice = udev_device_get_parent (device->priv->udevice);
+  if (udevice == NULL)
+    goto out;
+
+  ret = _g_udev_device_new (udevice);
+
+ out:
+  return ret;
+}
+
+/**
+ * g_udev_device_get_parent_with_subsystem:
+ * @device: A #GUdevDevice.
+ * @subsystem: The subsystem of the parent to get.
+ * @devtype: (allow-none): The devtype of the parent to get or %NULL.
+ *
+ * Walks up the chain of parents of @device and returns the first
+ * device encountered where @subsystem and @devtype matches, if any.
+ *
+ * Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent with @subsystem and @devtype. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_device_get_parent_with_subsystem (GUdevDevice  *device,
+                                         const gchar  *subsystem,
+                                         const gchar  *devtype)
+{
+  GUdevDevice *ret;
+  struct udev_device *udevice;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  g_return_val_if_fail (subsystem != NULL, NULL);
+
+  ret = NULL;
+
+  udevice = udev_device_get_parent_with_subsystem_devtype (device->priv->udevice,
+                                                           subsystem,
+                                                           devtype);
+  if (udevice == NULL)
+    goto out;
+
+  ret = _g_udev_device_new (udevice);
+
+ out:
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_property_keys:
+ * @device: A #GUdevDevice.
+ *
+ * Gets all keys for properties on @device.
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of property keys. This array is owned by @device and should not be freed by the caller.
+ */
+const gchar* const *
+g_udev_device_get_property_keys (GUdevDevice *device)
+{
+  struct udev_list_entry *l;
+  GPtrArray *p;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+  if (device->priv->property_keys != NULL)
+    goto out;
+
+  p = g_ptr_array_new ();
+  for (l = udev_device_get_properties_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+    {
+      g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+    }
+  g_ptr_array_add (p, NULL);
+  device->priv->property_keys = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+  return (const gchar * const *) device->priv->property_keys;
+}
+
+
+/**
+ * g_udev_device_has_property:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Check if a the property with the given key exists.
+ *
+ * Returns: %TRUE only if the value for @key exist.
+ */
+gboolean
+g_udev_device_has_property (GUdevDevice  *device,
+                            const gchar  *key)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+  return udev_device_get_property_value (device->priv->udevice, key) != NULL;
+}
+
+/**
+ * g_udev_device_get_property:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device.
+ *
+ * Returns: The value for @key or %NULL if @key doesn't exist on @device. Do not free this string, it is owned by @device.
+ */
+const gchar *
+g_udev_device_get_property (GUdevDevice  *device,
+                            const gchar  *key)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+  return udev_device_get_property_value (device->priv->udevice, key);
+}
+
+/**
+ * g_udev_device_get_property_as_int:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an integer
+ * using strtol().
+ *
+ * Returns: The value for @key or 0 if @key doesn't exist or
+ * isn't an integer.
+ */
+gint
+g_udev_device_get_property_as_int (GUdevDevice  *device,
+                                   const gchar  *key)
+{
+  gint result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+  g_return_val_if_fail (key != NULL, 0);
+
+  result = 0;
+  s = g_udev_device_get_property (device, key);
+  if (s == NULL)
+    goto out;
+
+  result = strtol (s, NULL, 0);
+out:
+  return result;
+}
+
+/**
+ * g_udev_device_get_property_as_uint64:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an unsigned
+ * 64-bit integer using g_ascii_strtoull().
+ *
+ * Returns: The value  for @key or 0 if @key doesn't  exist or isn't a
+ * #guint64.
+ */
+guint64
+g_udev_device_get_property_as_uint64 (GUdevDevice  *device,
+                                      const gchar  *key)
+{
+  guint64 result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+  g_return_val_if_fail (key != NULL, 0);
+
+  result = 0;
+  s = g_udev_device_get_property (device, key);
+  if (s == NULL)
+    goto out;
+
+  result = g_ascii_strtoull (s, NULL, 0);
+out:
+  return result;
+}
+
+/**
+ * g_udev_device_get_property_as_double:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to a double
+ * precision floating point number using strtod().
+ *
+ * Returns: The value for @key or 0.0 if @key doesn't exist or isn't a
+ * #gdouble.
+ */
+gdouble
+g_udev_device_get_property_as_double (GUdevDevice  *device,
+                                      const gchar  *key)
+{
+  gdouble result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
+  g_return_val_if_fail (key != NULL, 0.0);
+
+  result = 0.0;
+  s = g_udev_device_get_property (device, key);
+  if (s == NULL)
+    goto out;
+
+  result = strtod (s, NULL);
+out:
+  return result;
+}
+
+/**
+ * g_udev_device_get_property_as_boolean:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an
+ * boolean. This is done by doing a case-insensitive string comparison
+ * on the string value against "1" and "true".
+ *
+ * Returns: The value for @key or %FALSE if @key doesn't exist or
+ * isn't a #gboolean.
+ */
+gboolean
+g_udev_device_get_property_as_boolean (GUdevDevice  *device,
+                                       const gchar  *key)
+{
+  gboolean result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+
+  result = FALSE;
+  s = g_udev_device_get_property (device, key);
+  if (s == NULL)
+    goto out;
+
+  if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
+    result = TRUE;
+ out:
+  return result;
+}
+
+static gchar **
+split_at_whitespace (const gchar *s)
+{
+  gchar **result;
+  guint n;
+  guint m;
+
+  result = g_strsplit_set (s, " \v\t\r\n", 0);
+
+  /* remove empty strings, thanks GLib */
+  for (n = 0; result[n] != NULL; n++)
+    {
+      if (strlen (result[n]) == 0)
+        {
+          g_free (result[n]);
+          for (m = n; result[m] != NULL; m++)
+            result[m] = result[m + 1];
+          n--;
+        }
+    }
+
+  return result;
+}
+
+/**
+ * g_udev_device_get_property_as_strv:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and return the result of
+ * splitting it into non-empty tokens split at white space (only space
+ * (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'),
+ * horizontal tab ('\t'), and vertical tab ('\v') are considered; the
+ * locale is not taken into account).
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of @key on @device split into tokens or %NULL if @key doesn't exist. This array is owned by @device and should not be freed by the caller.
+ */
+const gchar* const *
+g_udev_device_get_property_as_strv (GUdevDevice  *device,
+                                    const gchar  *key)
+{
+  gchar **result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  if (device->priv->prop_strvs != NULL)
+    {
+      result = g_hash_table_lookup (device->priv->prop_strvs, key);
+      if (result != NULL)
+        goto out;
+    }
+
+  result = NULL;
+  s = g_udev_device_get_property (device, key);
+  if (s == NULL)
+    goto out;
+
+  result = split_at_whitespace (s);
+  if (result == NULL)
+    goto out;
+
+  if (device->priv->prop_strvs == NULL)
+    device->priv->prop_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
+  g_hash_table_insert (device->priv->prop_strvs, g_strdup (key), result);
+
+out:
+  return (const gchar* const *) result;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_sysfs_attr:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device.
+ *
+ * Returns: The value of the sysfs attribute or %NULL if there is no
+ * such attribute. Do not free this string, it is owned by @device.
+ */
+const gchar *
+g_udev_device_get_sysfs_attr (GUdevDevice  *device,
+                              const gchar  *name)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  return udev_device_get_sysattr_value (device->priv->udevice, name);
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_int:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an integer
+ * using strtol().
+ *
+ * Returns: The value of the sysfs attribute or 0 if there is no such
+ * attribute.
+ */
+gint
+g_udev_device_get_sysfs_attr_as_int (GUdevDevice  *device,
+                                     const gchar  *name)
+{
+  gint result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+  g_return_val_if_fail (name != NULL, 0);
+
+  result = 0;
+  s = g_udev_device_get_sysfs_attr (device, name);
+  if (s == NULL)
+    goto out;
+
+  result = strtol (s, NULL, 0);
+out:
+  return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_uint64:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an unsigned
+ * 64-bit integer using g_ascii_strtoull().
+ *
+ * Returns: The value of the sysfs attribute or 0 if there is no such
+ * attribute.
+ */
+guint64
+g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice  *device,
+                                        const gchar  *name)
+{
+  guint64 result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+  g_return_val_if_fail (name != NULL, 0);
+
+  result = 0;
+  s = g_udev_device_get_sysfs_attr (device, name);
+  if (s == NULL)
+    goto out;
+
+  result = g_ascii_strtoull (s, NULL, 0);
+out:
+  return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_double:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to a double
+ * precision floating point number using strtod().
+ *
+ * Returns: The value of the sysfs attribute or 0.0 if there is no such
+ * attribute.
+ */
+gdouble
+g_udev_device_get_sysfs_attr_as_double (GUdevDevice  *device,
+                                        const gchar  *name)
+{
+  gdouble result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
+  g_return_val_if_fail (name != NULL, 0.0);
+
+  result = 0.0;
+  s = g_udev_device_get_sysfs_attr (device, name);
+  if (s == NULL)
+    goto out;
+
+  result = strtod (s, NULL);
+out:
+  return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_boolean:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an
+ * boolean. This is done by doing a case-insensitive string comparison
+ * on the string value against "1" and "true".
+ *
+ * Returns: The value of the sysfs attribute or %FALSE if there is no such
+ * attribute.
+ */
+gboolean
+g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice  *device,
+                                         const gchar  *name)
+{
+  gboolean result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+  g_return_val_if_fail (name != NULL, FALSE);
+
+  result = FALSE;
+  s = g_udev_device_get_sysfs_attr (device, name);
+  if (s == NULL)
+    goto out;
+
+  if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
+    result = TRUE;
+ out:
+  return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_strv:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and return the result of
+ * splitting it into non-empty tokens split at white space (only space (' '),
+ * form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
+ * tab ('\t'), and vertical tab ('\v') are considered; the locale is
+ * not taken into account).
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of the sysfs attribute split into tokens or %NULL if there is no such attribute. This array is owned by @device and should not be freed by the caller.
+ */
+const gchar * const *
+g_udev_device_get_sysfs_attr_as_strv (GUdevDevice  *device,
+                                      const gchar  *name)
+{
+  gchar **result;
+  const gchar *s;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  if (device->priv->sysfs_attr_strvs != NULL)
+    {
+      result = g_hash_table_lookup (device->priv->sysfs_attr_strvs, name);
+      if (result != NULL)
+        goto out;
+    }
+
+  result = NULL;
+  s = g_udev_device_get_sysfs_attr (device, name);
+  if (s == NULL)
+    goto out;
+
+  result = split_at_whitespace (s);
+  if (result == NULL)
+    goto out;
+
+  if (device->priv->sysfs_attr_strvs == NULL)
+    device->priv->sysfs_attr_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
+  g_hash_table_insert (device->priv->sysfs_attr_strvs, g_strdup (name), result);
+
+out:
+  return (const gchar* const *) result;
+}
+
+/**
+ * g_udev_device_get_tags:
+ * @device: A #GUdevDevice.
+ *
+ * Gets all tags for @device.
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of tags. This array is owned by @device and should not be freed by the caller.
+ *
+ * Since: 165
+ */
+const gchar* const *
+g_udev_device_get_tags (GUdevDevice  *device)
+{
+  struct udev_list_entry *l;
+  GPtrArray *p;
+
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+  if (device->priv->tags != NULL)
+    goto out;
+
+  p = g_ptr_array_new ();
+  for (l = udev_device_get_tags_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+    {
+      g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+    }
+  g_ptr_array_add (p, NULL);
+  device->priv->tags = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+  return (const gchar * const *) device->priv->tags;
+}
+
+/**
+ * g_udev_device_get_is_initialized:
+ * @device: A #GUdevDevice.
+ *
+ * Gets whether @device has been initalized.
+ *
+ * Returns: Whether @device has been initialized.
+ *
+ * Since: 165
+ */
+gboolean
+g_udev_device_get_is_initialized (GUdevDevice  *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+  return udev_device_get_is_initialized (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_usec_since_initialized:
+ * @device: A #GUdevDevice.
+ *
+ * Gets number of micro-seconds since @device was initialized.
+ *
+ * This only works for devices with properties in the udev
+ * database. All other devices return 0.
+ *
+ * Returns: Number of micro-seconds since @device was initialized or 0 if unknown.
+ *
+ * Since: 165
+ */
+guint64
+g_udev_device_get_usec_since_initialized (GUdevDevice *device)
+{
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+  return udev_device_get_usec_since_initialized (device->priv->udevice);
+}
diff --git a/src/gudev/gudevdevice.h b/src/gudev/gudevdevice.h
new file mode 100644 (file)
index 0000000..457b961
--- /dev/null
@@ -0,0 +1,127 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_DEVICE_H__
+#define __G_UDEV_DEVICE_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_DEVICE         (g_udev_device_get_type ())
+#define G_UDEV_DEVICE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_DEVICE, GUdevDevice))
+#define G_UDEV_DEVICE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
+#define G_UDEV_IS_DEVICE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_DEVICE))
+#define G_UDEV_IS_DEVICE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_DEVICE))
+#define G_UDEV_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
+
+typedef struct _GUdevDeviceClass   GUdevDeviceClass;
+typedef struct _GUdevDevicePrivate GUdevDevicePrivate;
+
+/**
+ * GUdevDevice:
+ *
+ * The #GUdevDevice struct is opaque and should not be accessed directly.
+ */
+struct _GUdevDevice
+{
+  GObject             parent;
+
+  /*< private >*/
+  GUdevDevicePrivate *priv;
+};
+
+/**
+ * GUdevDeviceClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #GUdevDevice.
+ */
+struct _GUdevDeviceClass
+{
+  GObjectClass parent_class;
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*reserved1) (void);
+  void (*reserved2) (void);
+  void (*reserved3) (void);
+  void (*reserved4) (void);
+  void (*reserved5) (void);
+  void (*reserved6) (void);
+  void (*reserved7) (void);
+  void (*reserved8) (void);
+};
+
+GType               g_udev_device_get_type                  (void) G_GNUC_CONST;
+gboolean            g_udev_device_get_is_initialized        (GUdevDevice  *device);
+guint64             g_udev_device_get_usec_since_initialized (GUdevDevice  *device);
+const gchar        *g_udev_device_get_subsystem             (GUdevDevice  *device);
+const gchar        *g_udev_device_get_devtype               (GUdevDevice  *device);
+const gchar        *g_udev_device_get_name                  (GUdevDevice  *device);
+const gchar        *g_udev_device_get_number                (GUdevDevice  *device);
+const gchar        *g_udev_device_get_sysfs_path            (GUdevDevice  *device);
+const gchar        *g_udev_device_get_driver                (GUdevDevice  *device);
+const gchar        *g_udev_device_get_action                (GUdevDevice  *device);
+guint64             g_udev_device_get_seqnum                (GUdevDevice  *device);
+GUdevDeviceType     g_udev_device_get_device_type           (GUdevDevice  *device);
+GUdevDeviceNumber   g_udev_device_get_device_number         (GUdevDevice  *device);
+const gchar        *g_udev_device_get_device_file           (GUdevDevice  *device);
+const gchar* const *g_udev_device_get_device_file_symlinks  (GUdevDevice  *device);
+GUdevDevice        *g_udev_device_get_parent                (GUdevDevice  *device);
+GUdevDevice        *g_udev_device_get_parent_with_subsystem (GUdevDevice  *device,
+                                                             const gchar  *subsystem,
+                                                             const gchar  *devtype);
+const gchar* const *g_udev_device_get_property_keys         (GUdevDevice  *device);
+gboolean            g_udev_device_has_property              (GUdevDevice  *device,
+                                                             const gchar  *key);
+const gchar        *g_udev_device_get_property              (GUdevDevice  *device,
+                                                             const gchar  *key);
+gint                g_udev_device_get_property_as_int       (GUdevDevice  *device,
+                                                             const gchar  *key);
+guint64             g_udev_device_get_property_as_uint64    (GUdevDevice  *device,
+                                                             const gchar  *key);
+gdouble             g_udev_device_get_property_as_double    (GUdevDevice  *device,
+                                                             const gchar  *key);
+gboolean            g_udev_device_get_property_as_boolean   (GUdevDevice  *device,
+                                                             const gchar  *key);
+const gchar* const *g_udev_device_get_property_as_strv      (GUdevDevice  *device,
+                                                             const gchar  *key);
+
+const gchar        *g_udev_device_get_sysfs_attr            (GUdevDevice  *device,
+                                                             const gchar  *name);
+gint                g_udev_device_get_sysfs_attr_as_int     (GUdevDevice  *device,
+                                                             const gchar  *name);
+guint64             g_udev_device_get_sysfs_attr_as_uint64  (GUdevDevice  *device,
+                                                             const gchar  *name);
+gdouble             g_udev_device_get_sysfs_attr_as_double  (GUdevDevice  *device,
+                                                             const gchar  *name);
+gboolean            g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice  *device,
+                                                             const gchar  *name);
+const gchar* const *g_udev_device_get_sysfs_attr_as_strv    (GUdevDevice  *device,
+                                                             const gchar  *name);
+const gchar* const *g_udev_device_get_tags                  (GUdevDevice  *device);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_DEVICE_H__ */
diff --git a/src/gudev/gudevenumerator.c b/src/gudev/gudevenumerator.c
new file mode 100644 (file)
index 0000000..1fb3098
--- /dev/null
@@ -0,0 +1,429 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gudevclient.h"
+#include "gudevenumerator.h"
+#include "gudevdevice.h"
+#include "gudevmarshal.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevenumerator
+ * @short_description: Lookup and sort devices
+ *
+ * #GUdevEnumerator is used to lookup and sort devices.
+ *
+ * Since: 165
+ */
+
+struct _GUdevEnumeratorPrivate
+{
+  GUdevClient *client;
+  struct udev_enumerate *e;
+};
+
+enum
+{
+  PROP_0,
+  PROP_CLIENT,
+};
+
+G_DEFINE_TYPE (GUdevEnumerator, g_udev_enumerator, G_TYPE_OBJECT)
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+g_udev_enumerator_finalize (GObject *object)
+{
+  GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+  if (enumerator->priv->client != NULL)
+    {
+      g_object_unref (enumerator->priv->client);
+      enumerator->priv->client = NULL;
+    }
+
+  if (enumerator->priv->e != NULL)
+    {
+      udev_enumerate_unref (enumerator->priv->e);
+      enumerator->priv->e = NULL;
+    }
+
+  if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize != NULL)
+    G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize (object);
+}
+
+static void
+g_udev_enumerator_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+  switch (prop_id)
+    {
+    case PROP_CLIENT:
+      if (enumerator->priv->client != NULL)
+        g_object_unref (enumerator->priv->client);
+      enumerator->priv->client = g_value_dup_object (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_udev_enumerator_get_property (GObject     *object,
+                                guint        prop_id,
+                                GValue      *value,
+                                GParamSpec  *pspec)
+{
+  GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+  switch (prop_id)
+    {
+    case PROP_CLIENT:
+      g_value_set_object (value, enumerator->priv->client);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_udev_enumerator_constructed (GObject *object)
+{
+  GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+  g_assert (G_UDEV_IS_CLIENT (enumerator->priv->client));
+
+  enumerator->priv->e = udev_enumerate_new (_g_udev_client_get_udev (enumerator->priv->client));
+
+  if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed != NULL)
+    G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed (object);
+}
+
+static void
+g_udev_enumerator_class_init (GUdevEnumeratorClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+
+  gobject_class->finalize     = g_udev_enumerator_finalize;
+  gobject_class->set_property = g_udev_enumerator_set_property;
+  gobject_class->get_property = g_udev_enumerator_get_property;
+  gobject_class->constructed  = g_udev_enumerator_constructed;
+
+  /**
+   * GUdevEnumerator:client:
+   *
+   * The #GUdevClient to enumerate devices from.
+   *
+   * Since: 165
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_CLIENT,
+                                   g_param_spec_object ("client",
+                                                        "The client to enumerate devices from",
+                                                        "The client to enumerate devices from",
+                                                        G_UDEV_TYPE_CLIENT,
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_READWRITE));
+
+  g_type_class_add_private (klass, sizeof (GUdevEnumeratorPrivate));
+}
+
+static void
+g_udev_enumerator_init (GUdevEnumerator *enumerator)
+{
+  enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator,
+                                                  G_UDEV_TYPE_ENUMERATOR,
+                                                  GUdevEnumeratorPrivate);
+}
+
+/**
+ * g_udev_enumerator_new:
+ * @client: A #GUdevClient to enumerate devices from.
+ *
+ * Constructs a #GUdevEnumerator object that can be used to enumerate
+ * and sort devices. Use the add_match_*() and add_nomatch_*() methods
+ * and execute the query to get a list of devices with
+ * g_udev_enumerator_execute().
+ *
+ * Returns: A new #GUdevEnumerator object. Free with g_object_unref().
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_new (GUdevClient *client)
+{
+  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+  return G_UDEV_ENUMERATOR (g_object_new (G_UDEV_TYPE_ENUMERATOR, "client", client, NULL));
+}
+
+
+/**
+ * g_udev_enumerator_add_match_subsystem:
+ * @enumerator: A #GUdevEnumerator.
+ * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
+ *
+ * All returned devices will match the given @subsystem.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_subsystem (GUdevEnumerator  *enumerator,
+                                       const gchar      *subsystem)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  g_return_val_if_fail (subsystem != NULL, NULL);
+  udev_enumerate_add_match_subsystem (enumerator->priv->e, subsystem);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_nomatch_subsystem:
+ * @enumerator: A #GUdevEnumerator.
+ * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
+ *
+ * All returned devices will not match the given @subsystem.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator  *enumerator,
+                                         const gchar      *subsystem)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  g_return_val_if_fail (subsystem != NULL, NULL);
+  udev_enumerate_add_nomatch_subsystem (enumerator->priv->e, subsystem);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_sysfs_attr:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for sysfs attribute key.
+ * @value: Wildcard filter for sysfs attribute value.
+ *
+ * All returned devices will have a sysfs attribute matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator  *enumerator,
+                                        const gchar      *name,
+                                        const gchar      *value)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (value != NULL, NULL);
+  udev_enumerate_add_match_sysattr (enumerator->priv->e, name, value);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_nomatch_sysfs_attr:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for sysfs attribute key.
+ * @value: Wildcard filter for sysfs attribute value.
+ *
+ * All returned devices will not have a sysfs attribute matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator  *enumerator,
+                                          const gchar      *name,
+                                          const gchar      *value)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (value != NULL, NULL);
+  udev_enumerate_add_nomatch_sysattr (enumerator->priv->e, name, value);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_property:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for property name.
+ * @value: Wildcard filter for property value.
+ *
+ * All returned devices will have a property matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_property (GUdevEnumerator  *enumerator,
+                                      const gchar      *name,
+                                      const gchar      *value)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (value != NULL, NULL);
+  udev_enumerate_add_match_property (enumerator->priv->e, name, value);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_name:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for kernel name e.g. "sda*".
+ *
+ * All returned devices will match the given @name.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_name (GUdevEnumerator  *enumerator,
+                                  const gchar      *name)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  udev_enumerate_add_match_sysname (enumerator->priv->e, name);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_sysfs_path:
+ * @enumerator: A #GUdevEnumerator.
+ * @sysfs_path: A sysfs path, e.g. "/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda"
+ *
+ * Add a device to the list of devices, to retrieve it back sorted in dependency order.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_sysfs_path (GUdevEnumerator  *enumerator,
+                                  const gchar      *sysfs_path)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  g_return_val_if_fail (sysfs_path != NULL, NULL);
+  udev_enumerate_add_syspath (enumerator->priv->e, sysfs_path);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_tag:
+ * @enumerator: A #GUdevEnumerator.
+ * @tag: A udev tag e.g. "udev-acl".
+ *
+ * All returned devices will match the given @tag.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_tag (GUdevEnumerator  *enumerator,
+                                 const gchar      *tag)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  g_return_val_if_fail (tag != NULL, NULL);
+  udev_enumerate_add_match_tag (enumerator->priv->e, tag);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_is_initialized:
+ * @enumerator: A #GUdevEnumerator.
+ *
+ * All returned devices will be initialized.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_is_initialized (GUdevEnumerator  *enumerator)
+{
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+  udev_enumerate_add_match_is_initialized (enumerator->priv->e);
+  return enumerator;
+}
+
+/**
+ * g_udev_enumerator_execute:
+ * @enumerator: A #GUdevEnumerator.
+ *
+ * Executes the query in @enumerator.
+ *
+ * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
+ *
+ * Since: 165
+ */
+GList *
+g_udev_enumerator_execute (GUdevEnumerator  *enumerator)
+{
+  GList *ret;
+  struct udev_list_entry *l, *devices;
+
+  g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+
+  ret = NULL;
+
+  /* retrieve the list */
+  udev_enumerate_scan_devices (enumerator->priv->e);
+
+  devices = udev_enumerate_get_list_entry (enumerator->priv->e);
+  for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
+    {
+      struct udev_device *udevice;
+      GUdevDevice *device;
+
+      udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator->priv->e),
+                                              udev_list_entry_get_name (l));
+      if (udevice == NULL)
+        continue;
+
+      device = _g_udev_device_new (udevice);
+      udev_device_unref (udevice);
+      ret = g_list_prepend (ret, device);
+    }
+
+  ret = g_list_reverse (ret);
+
+  return ret;
+}
diff --git a/src/gudev/gudevenumerator.h b/src/gudev/gudevenumerator.h
new file mode 100644 (file)
index 0000000..e1dbcf1
--- /dev/null
@@ -0,0 +1,106 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_ENUMERATOR_H__
+#define __G_UDEV_ENUMERATOR_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_ENUMERATOR         (g_udev_enumerator_get_type ())
+#define G_UDEV_ENUMERATOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumerator))
+#define G_UDEV_ENUMERATOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
+#define G_UDEV_IS_ENUMERATOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_ENUMERATOR))
+#define G_UDEV_IS_ENUMERATOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_ENUMERATOR))
+#define G_UDEV_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
+
+typedef struct _GUdevEnumeratorClass   GUdevEnumeratorClass;
+typedef struct _GUdevEnumeratorPrivate GUdevEnumeratorPrivate;
+
+/**
+ * GUdevEnumerator:
+ *
+ * The #GUdevEnumerator struct is opaque and should not be accessed directly.
+ *
+ * Since: 165
+ */
+struct _GUdevEnumerator
+{
+  GObject              parent;
+
+  /*< private >*/
+  GUdevEnumeratorPrivate *priv;
+};
+
+/**
+ * GUdevEnumeratorClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #GUdevEnumerator.
+ *
+ * Since: 165
+ */
+struct _GUdevEnumeratorClass
+{
+  GObjectClass   parent_class;
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*reserved1) (void);
+  void (*reserved2) (void);
+  void (*reserved3) (void);
+  void (*reserved4) (void);
+  void (*reserved5) (void);
+  void (*reserved6) (void);
+  void (*reserved7) (void);
+  void (*reserved8) (void);
+};
+
+GType            g_udev_enumerator_get_type                     (void) G_GNUC_CONST;
+GUdevEnumerator *g_udev_enumerator_new                          (GUdevClient      *client);
+GUdevEnumerator *g_udev_enumerator_add_match_subsystem          (GUdevEnumerator  *enumerator,
+                                                                 const gchar      *subsystem);
+GUdevEnumerator *g_udev_enumerator_add_nomatch_subsystem        (GUdevEnumerator  *enumerator,
+                                                                 const gchar      *subsystem);
+GUdevEnumerator *g_udev_enumerator_add_match_sysfs_attr         (GUdevEnumerator  *enumerator,
+                                                                 const gchar      *name,
+                                                                 const gchar      *value);
+GUdevEnumerator *g_udev_enumerator_add_nomatch_sysfs_attr       (GUdevEnumerator  *enumerator,
+                                                                 const gchar      *name,
+                                                                 const gchar      *value);
+GUdevEnumerator *g_udev_enumerator_add_match_property           (GUdevEnumerator  *enumerator,
+                                                                 const gchar      *name,
+                                                                 const gchar      *value);
+GUdevEnumerator *g_udev_enumerator_add_match_name               (GUdevEnumerator  *enumerator,
+                                                                 const gchar      *name);
+GUdevEnumerator *g_udev_enumerator_add_match_tag                (GUdevEnumerator  *enumerator,
+                                                                 const gchar      *tag);
+GUdevEnumerator *g_udev_enumerator_add_match_is_initialized     (GUdevEnumerator  *enumerator);
+GUdevEnumerator *g_udev_enumerator_add_sysfs_path               (GUdevEnumerator  *enumerator,
+                                                                 const gchar      *sysfs_path);
+GList           *g_udev_enumerator_execute                      (GUdevEnumerator  *enumerator);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_ENUMERATOR_H__ */
diff --git a/src/gudev/gudevenums.h b/src/gudev/gudevenums.h
new file mode 100644 (file)
index 0000000..467e93b
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_ENUMS_H__
+#define __G_UDEV_ENUMS_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GUdevDeviceType:
+ * @G_UDEV_DEVICE_TYPE_NONE: Device does not have a device file.
+ * @G_UDEV_DEVICE_TYPE_BLOCK: Device is a block device.
+ * @G_UDEV_DEVICE_TYPE_CHAR: Device is a character device.
+ *
+ * Enumeration used to specify a the type of a device.
+ */
+typedef enum
+{
+  G_UDEV_DEVICE_TYPE_NONE = 0,
+  G_UDEV_DEVICE_TYPE_BLOCK = 'b',
+  G_UDEV_DEVICE_TYPE_CHAR = 'c',
+} GUdevDeviceType;
+
+G_END_DECLS
+
+#endif /* __G_UDEV_ENUMS_H__ */
diff --git a/src/gudev/gudevenumtypes.c.template b/src/gudev/gudevenumtypes.c.template
new file mode 100644 (file)
index 0000000..fc30b39
--- /dev/null
@@ -0,0 +1,39 @@
+/*** BEGIN file-header ***/
+#include <gudev.h>
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+
+  if (g_once_init_enter (&g_define_type_id__volatile))
+    {
+      static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+        { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+        { 0, NULL, NULL }
+      };
+      GType g_define_type_id =
+        g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+    }
+
+  return g_define_type_id__volatile;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+/*** END file-tail ***/
diff --git a/src/gudev/gudevenumtypes.h.template b/src/gudev/gudevenumtypes.h.template
new file mode 100644 (file)
index 0000000..d0ab339
--- /dev/null
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef __GUDEV_ENUM_TYPES_H__
+#define __GUDEV_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __GUDEV_ENUM_TYPES_H__ */
+/*** END file-tail ***/
diff --git a/src/gudev/gudevmarshal.list b/src/gudev/gudevmarshal.list
new file mode 100644 (file)
index 0000000..7e66599
--- /dev/null
@@ -0,0 +1 @@
+VOID:STRING,OBJECT
diff --git a/src/gudev/gudevprivate.h b/src/gudev/gudevprivate.h
new file mode 100644 (file)
index 0000000..52e272b
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_PRIVATE_H__
+#define __G_UDEV_PRIVATE_H__
+
+#include <gudev/gudevtypes.h>
+
+#include <libudev.h>
+
+G_BEGIN_DECLS
+
+GUdevDevice *
+_g_udev_device_new (struct udev_device *udevice);
+
+struct udev *_g_udev_client_get_udev (GUdevClient *client);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_PRIVATE_H__ */
diff --git a/src/gudev/gudevtypes.h b/src/gudev/gudevtypes.h
new file mode 100644 (file)
index 0000000..e2f688f
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_TYPES_H__
+#define __G_UDEV_TYPES_H__
+
+#include <gudev/gudevenums.h>
+#include <sys/types.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GUdevClient GUdevClient;
+typedef struct _GUdevDevice GUdevDevice;
+typedef struct _GUdevEnumerator GUdevEnumerator;
+
+/**
+ * GUdevDeviceNumber:
+ *
+ * Corresponds to the standard #dev_t type as defined by POSIX (Until
+ * bug 584517 is resolved this work-around is needed).
+ */
+#ifdef _GUDEV_WORK_AROUND_DEV_T_BUG
+typedef guint64 GUdevDeviceNumber; /* __UQUAD_TYPE */
+#else
+typedef dev_t GUdevDeviceNumber;
+#endif
+
+G_END_DECLS
+
+#endif /* __G_UDEV_TYPES_H__ */
diff --git a/src/gudev/seed-example-enum.js b/src/gudev/seed-example-enum.js
new file mode 100755 (executable)
index 0000000..66206ad
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/bin/env seed
+
+const GLib = imports.gi.GLib;
+const GUdev = imports.gi.GUdev;
+
+function print_device(device) {
+  print("  initialized:            " + device.get_is_initialized());
+  print("  usec since initialized: " + device.get_usec_since_initialized());
+  print("  subsystem:              " + device.get_subsystem());
+  print("  devtype:                " + device.get_devtype());
+  print("  name:                   " + device.get_name());
+  print("  number:                 " + device.get_number());
+  print("  sysfs_path:             " + device.get_sysfs_path());
+  print("  driver:                 " + device.get_driver());
+  print("  action:                 " + device.get_action());
+  print("  seqnum:                 " + device.get_seqnum());
+  print("  device type:            " + device.get_device_type());
+  print("  device number:          " + device.get_device_number());
+  print("  device file:            " + device.get_device_file());
+  print("  device file symlinks:   " + device.get_device_file_symlinks());
+  print("  tags:                   " + device.get_tags());
+  var keys = device.get_property_keys();
+  for (var n = 0; n < keys.length; n++) {
+    print("    " + keys[n] + "=" + device.get_property(keys[n]));
+  }
+}
+
+var client = new GUdev.Client({subsystems: []});
+var enumerator = new GUdev.Enumerator({client: client});
+enumerator.add_match_subsystem('b*')
+
+var devices = enumerator.execute();
+
+for (var n=0; n < devices.length; n++) {
+    var device = devices[n];
+    print_device(device);
+    print("");
+}
diff --git a/src/gudev/seed-example.js b/src/gudev/seed-example.js
new file mode 100755 (executable)
index 0000000..e2ac324
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/env seed
+
+// seed example
+
+const GLib = imports.gi.GLib;
+const GUdev = imports.gi.GUdev;
+
+function print_device (device) {
+  print ("  subsystem:             " + device.get_subsystem ());
+  print ("  devtype:               " + device.get_devtype ());
+  print ("  name:                  " + device.get_name ());
+  print ("  number:                " + device.get_number ());
+  print ("  sysfs_path:            " + device.get_sysfs_path ());
+  print ("  driver:                " + device.get_driver ());
+  print ("  action:                " + device.get_action ());
+  print ("  seqnum:                " + device.get_seqnum ());
+  print ("  device type:           " + device.get_device_type ());
+  print ("  device number:         " + device.get_device_number ());
+  print ("  device file:           " + device.get_device_file ());
+  print ("  device file symlinks:  " + device.get_device_file_symlinks ());
+  print ("  foo: " + device.get_sysfs_attr_as_strv ("stat"));
+  var keys = device.get_property_keys ();
+  for (var n = 0; n < keys.length; n++) {
+    print ("    " + keys[n] + "=" + device.get_property (keys[n]));
+  }
+}
+
+function on_uevent (client, action, device) {
+  print ("action " + action + " on device " + device.get_sysfs_path());
+  print_device (device);
+  print ("");
+}
+
+var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
+client.signal.connect ("uevent", on_uevent);
+
+var block_devices = client.query_by_subsystem ("block");
+for (var n = 0; n < block_devices.length; n++) {
+  print ("block device: " + block_devices[n].get_device_file ());
+}
+
+var d;
+
+d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
+if (d == null) {
+  print ("query_by_device_number 0x810 -> null");
+} else {
+  print ("query_by_device_number 0x810 -> " + d.get_device_file ());
+  dd = d.get_parent_with_subsystem ("usb", null);
+  print_device (dd);
+  print ("--------------------------------------------------------------------------");
+  while (d != null) {
+    print_device (d);
+    print ("");
+    d = d.get_parent ();
+  }
+}
+
+d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
+print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
+
+d = client.query_by_subsystem_and_name ("block", "sda2");
+print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/sda");
+print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/block/8:0");
+print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
+
+var mainloop = GLib.main_loop_new ();
+GLib.main_loop_run (mainloop);
diff --git a/src/hostname/.gitignore b/src/hostname/.gitignore
new file mode 100644 (file)
index 0000000..1ff281b
--- /dev/null
@@ -0,0 +1 @@
+org.freedesktop.hostname1.policy
diff --git a/src/hostname/Makefile b/src/hostname/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c
new file mode 100644 (file)
index 0000000..ff1f091
--- /dev/null
@@ -0,0 +1,578 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <locale.h>
+#include <string.h>
+#include <sys/timex.h>
+#include <sys/utsname.h>
+
+#include "dbus-common.h"
+#include "util.h"
+#include "spawn-polkit-agent.h"
+#include "build.h"
+#include "hwclock.h"
+#include "strv.h"
+#include "sd-id128.h"
+#include "virt.h"
+
+static enum transport {
+        TRANSPORT_NORMAL,
+        TRANSPORT_SSH,
+        TRANSPORT_POLKIT
+} arg_transport = TRANSPORT_NORMAL;
+static bool arg_ask_password = true;
+static const char *arg_host = NULL;
+static bool arg_set_transient = false;
+static bool arg_set_pretty = false;
+static bool arg_set_static = false;
+
+static void polkit_agent_open_if_enabled(void) {
+
+        /* Open the polkit agent as a child process if necessary */
+
+        if (!arg_ask_password)
+                return;
+
+        polkit_agent_open();
+}
+
+typedef struct StatusInfo {
+        const char *hostname;
+        const char *static_hostname;
+        const char *pretty_hostname;
+        const char *icon_name;
+        const char *chassis;
+} StatusInfo;
+
+static void print_status_info(StatusInfo *i) {
+        sd_id128_t mid, bid;
+        int r;
+        const char *id = NULL;
+        _cleanup_free_ char *pretty_name = NULL, *cpe_name = NULL;
+        struct utsname u;
+
+        assert(i);
+
+        printf("   Static hostname: %s\n",
+               strna(i->static_hostname));
+
+        if (!streq_ptr(i->hostname, i->static_hostname))
+                printf("Transient hostname: %s\n",
+                       strna(i->hostname));
+
+        printf("   Pretty hostname: %s\n"
+               "         Icon name: %s\n"
+               "           Chassis: %s\n",
+               strna(i->pretty_hostname),
+               strna(i->icon_name),
+               strna(i->chassis));
+
+        r = sd_id128_get_machine(&mid);
+        if (r >= 0)
+                printf("        Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(mid));
+
+        r = sd_id128_get_boot(&bid);
+        if (r >= 0)
+                printf("           Boot ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(bid));
+
+        if (detect_virtualization(&id) > 0)
+                printf("    Virtualization: %s\n", id);
+
+        r = parse_env_file("/etc/os-release", NEWLINE,
+                           "PRETTY_NAME", &pretty_name,
+                           "CPE_NAME", &cpe_name,
+                           NULL);
+
+        if (!isempty(pretty_name))
+                printf("  Operating System: %s\n", pretty_name);
+
+        if (!isempty(cpe_name))
+                printf("       CPE OS Name: %s\n", cpe_name);
+
+        assert_se(uname(&u) >= 0);
+        printf("            Kernel: %s %s\n"
+               "      Architecture: %s\n", u.sysname, u.release, u.machine);
+
+}
+
+static int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) {
+        assert(name);
+        assert(iter);
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRING: {
+                const char *s;
+
+                dbus_message_iter_get_basic(iter, &s);
+                if (!isempty(s)) {
+                        if (streq(name, "Hostname"))
+                                i->hostname = s;
+                        if (streq(name, "StaticHostname"))
+                                i->static_hostname = s;
+                        if (streq(name, "PrettyHostname"))
+                                i->pretty_hostname = s;
+                        if (streq(name, "IconName"))
+                                i->icon_name = s;
+                        if (streq(name, "Chassis"))
+                                i->chassis = s;
+                }
+                break;
+        }
+        }
+
+        return 0;
+}
+
+static int show_status(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        const char *interface = "";
+        int r;
+        DBusMessageIter iter, sub, sub2, sub3;
+        StatusInfo info;
+
+        assert(args);
+
+        r = bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.hostname1",
+                        "/org/freedesktop/hostname1",
+                        "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_INVALID);
+        if (r < 0)
+                return r;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)  {
+                log_error("Failed to parse reply.");
+                return -EIO;
+        }
+
+        zero(info);
+        dbus_message_iter_recurse(&iter, &sub);
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *name;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)  {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                dbus_message_iter_recurse(&sub2, &sub3);
+
+                r = status_property(name, &sub3, &info);
+                if (r < 0) {
+                        log_error("Failed to parse reply.");
+                        return r;
+                }
+
+                dbus_message_iter_next(&sub);
+        }
+
+        print_status_info(&info);
+        return 0;
+}
+
+static char* hostname_simplify(char *s) {
+        char *p, *d;
+
+        for (p = s, d = s; *p; p++) {
+                if ((*p >= 'a' && *p <= 'z') ||
+                    (*p >= '0' && *p <= '9') ||
+                    *p == '-' || *p == '_')
+                        *(d++) = *p;
+                else if (*p >= 'A' && *p <= 'Z')
+                        *(d++) = *p - 'A' + 'a';
+                else if (*p == ' ')
+                        *(d++) = '-';
+        }
+
+        *d = 0;
+
+        strshorten(s, HOST_NAME_MAX);
+        return s;
+}
+
+static int set_hostname(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t interactive = true;
+        _cleanup_free_ char *h = NULL;
+        const char *hostname = args[1];
+        int r;
+
+        assert(args);
+        assert(n == 2);
+
+        polkit_agent_open_if_enabled();
+
+        if (arg_set_pretty) {
+                r = bus_method_call_with_reply(
+                                bus,
+                                "org.freedesktop.hostname1",
+                                "/org/freedesktop/hostname1",
+                                "org.freedesktop.hostname1",
+                                "SetPrettyHostname",
+                                &reply,
+                                NULL,
+                                DBUS_TYPE_STRING, &hostname,
+                                DBUS_TYPE_BOOLEAN, &interactive,
+                                DBUS_TYPE_INVALID);
+                if (r < 0)
+                        return r;
+
+                h = strdup(hostname);
+                if (!h)
+                        return log_oom();
+
+                hostname = hostname_simplify(h);
+        }
+
+        if (arg_set_static) {
+                r = bus_method_call_with_reply(
+                                bus,
+                                "org.freedesktop.hostname1",
+                                "/org/freedesktop/hostname1",
+                                "org.freedesktop.hostname1",
+                                "SetStaticHostname",
+                                &reply,
+                                NULL,
+                                DBUS_TYPE_STRING, &hostname,
+                                DBUS_TYPE_BOOLEAN, &interactive,
+                                DBUS_TYPE_INVALID);
+
+                if (r < 0)
+                        return r;
+        }
+
+        if (arg_set_transient) {
+                r = bus_method_call_with_reply(
+                                bus,
+                                "org.freedesktop.hostname1",
+                                "/org/freedesktop/hostname1",
+                                "org.freedesktop.hostname1",
+                                "SetHostname",
+                                &reply,
+                                NULL,
+                                DBUS_TYPE_STRING, &hostname,
+                                DBUS_TYPE_BOOLEAN, &interactive,
+                                DBUS_TYPE_INVALID);
+
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int set_icon_name(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t interactive = true;
+
+        assert(args);
+        assert(n == 2);
+
+        polkit_agent_open_if_enabled();
+
+        return bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.hostname1",
+                        "/org/freedesktop/hostname1",
+                        "org.freedesktop.hostname1",
+                        "SetIconName",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &args[1],
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static int set_chassis(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t interactive = true;
+
+        assert(args);
+        assert(n == 2);
+
+        polkit_agent_open_if_enabled();
+
+        return bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.hostname1",
+                        "/org/freedesktop/hostname1",
+                        "org.freedesktop.hostname1",
+                        "SetChassis",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &args[1],
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] COMMAND ...\n\n"
+               "Query or change system hostname.\n\n"
+               "  -h --help              Show this help\n"
+               "     --version           Show package version\n"
+               "     --transient         Only set transient hostname\n"
+               "     --static            Only set static hostname\n"
+               "     --pretty            Only set pretty hostname\n"
+               "     --no-ask-password   Do not prompt for password\n"
+               "  -H --host=[USER@]HOST  Operate on remote host\n\n"
+               "Commands:\n"
+               "  status                 Show current hostname settings\n"
+               "  set-hostname NAME      Set system hostname\n"
+               "  set-icon-name NAME     Set icon name for host\n"
+               "  set-chassis NAME       Set chassis type for host\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_NO_ASK_PASSWORD,
+                ARG_SET_TRANSIENT,
+                ARG_SET_STATIC,
+                ARG_SET_PRETTY
+        };
+
+        static const struct option options[] = {
+                { "help",            no_argument,       NULL, 'h'                 },
+                { "version",         no_argument,       NULL, ARG_VERSION         },
+                { "transient",       no_argument,       NULL, ARG_SET_TRANSIENT   },
+                { "static",          no_argument,       NULL, ARG_SET_STATIC      },
+                { "pretty",          no_argument,       NULL, ARG_SET_PRETTY      },
+                { "host",            required_argument, NULL, 'H'                 },
+                { "privileged",      no_argument,       NULL, 'P'                 },
+                { "no-ask-password", no_argument,       NULL, ARG_NO_ASK_PASSWORD },
+                { NULL,              0,                 NULL, 0                   }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hH:P", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case 'P':
+                        arg_transport = TRANSPORT_POLKIT;
+                        break;
+
+                case 'H':
+                        arg_transport = TRANSPORT_SSH;
+                        arg_host = optarg;
+                        break;
+
+                case ARG_SET_TRANSIENT:
+                        arg_set_transient = true;
+                        break;
+
+                case ARG_SET_PRETTY:
+                        arg_set_pretty = true;
+                        break;
+
+                case ARG_SET_STATIC:
+                        arg_set_static = true;
+                        break;
+
+                case ARG_NO_ASK_PASSWORD:
+                        arg_ask_password = false;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (!arg_set_transient && !arg_set_pretty && !arg_set_static)
+                arg_set_transient = arg_set_pretty = arg_set_static = true;
+
+        return 1;
+}
+
+static int hostnamectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) {
+
+        static const struct {
+                const char* verb;
+                const enum {
+                        MORE,
+                        LESS,
+                        EQUAL
+                } argc_cmp;
+                const int argc;
+                int (* const dispatch)(DBusConnection *bus, char **args, unsigned n);
+        } verbs[] = {
+                { "status",        LESS,  1, show_status   },
+                { "set-hostname",  EQUAL, 2, set_hostname  },
+                { "set-icon-name", EQUAL, 2, set_icon_name },
+                { "set-chassis",   EQUAL, 2, set_chassis   },
+        };
+
+        int left;
+        unsigned i;
+
+        assert(argc >= 0);
+        assert(argv);
+        assert(error);
+
+        left = argc - optind;
+
+        if (left <= 0)
+                /* Special rule: no arguments means "status" */
+                i = 0;
+        else {
+                if (streq(argv[optind], "help")) {
+                        help();
+                        return 0;
+                }
+
+                for (i = 0; i < ELEMENTSOF(verbs); i++)
+                        if (streq(argv[optind], verbs[i].verb))
+                                break;
+
+                if (i >= ELEMENTSOF(verbs)) {
+                        log_error("Unknown operation %s", argv[optind]);
+                        return -EINVAL;
+                }
+        }
+
+        switch (verbs[i].argc_cmp) {
+
+        case EQUAL:
+                if (left != verbs[i].argc) {
+                        log_error("Invalid number of arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case MORE:
+                if (left < verbs[i].argc) {
+                        log_error("Too few arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case LESS:
+                if (left > verbs[i].argc) {
+                        log_error("Too many arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("Unknown comparison operator.");
+        }
+
+        if (!bus) {
+                log_error("Failed to get D-Bus connection: %s", error->message);
+                return -EIO;
+        }
+
+        return verbs[i].dispatch(bus, argv + optind, left);
+}
+
+int main(int argc, char *argv[]) {
+        int r, retval = EXIT_FAILURE;
+        DBusConnection *bus = NULL;
+        DBusError error;
+
+        dbus_error_init(&error);
+
+        setlocale(LC_ALL, "");
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                goto finish;
+        else if (r == 0) {
+                retval = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        if (arg_transport == TRANSPORT_NORMAL)
+                bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        else if (arg_transport == TRANSPORT_POLKIT)
+                bus_connect_system_polkit(&bus, &error);
+        else if (arg_transport == TRANSPORT_SSH)
+                bus_connect_system_ssh(NULL, arg_host, &bus, &error);
+        else
+                assert_not_reached("Uh, invalid transport...");
+
+        r = hostnamectl_main(bus, argc, argv, &error);
+        retval = r < 0 ? EXIT_FAILURE : r;
+
+finish:
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        dbus_error_free(&error);
+        dbus_shutdown();
+
+        return retval;
+}
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
new file mode 100644 (file)
index 0000000..92b150b
--- /dev/null
@@ -0,0 +1,737 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <dlfcn.h>
+
+#include "util.h"
+#include "strv.h"
+#include "dbus-common.h"
+#include "polkit.h"
+#include "def.h"
+#include "virt.h"
+
+#define INTERFACE \
+        " <interface name=\"org.freedesktop.hostname1\">\n"             \
+        "  <property name=\"Hostname\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"StaticHostname\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"PrettyHostname\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"IconName\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"Chassis\" type=\"s\" access=\"read\"/>\n"   \
+        "  <method name=\"SetHostname\">\n"                             \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetStaticHostname\">\n"                       \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetPrettyHostname\">\n"                       \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetIconName\">\n"                             \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetChassis\">\n"                              \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        INTERFACE                                                       \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        BUS_PEER_INTERFACE                                              \
+        "</node>\n"
+
+#define INTERFACES_LIST                         \
+        BUS_GENERIC_INTERFACES_LIST             \
+        "org.freedesktop.hostname1\0"
+
+const char hostname_interface[] _introspect_("hostname1") = INTERFACE;
+
+enum {
+        PROP_HOSTNAME,
+        PROP_STATIC_HOSTNAME,
+        PROP_PRETTY_HOSTNAME,
+        PROP_ICON_NAME,
+        PROP_CHASSIS,
+        _PROP_MAX
+};
+
+static char *data[_PROP_MAX] = {
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL
+};
+
+static usec_t remain_until = 0;
+
+static void free_data(void) {
+        int p;
+
+        for (p = 0; p < _PROP_MAX; p++) {
+                free(data[p]);
+                data[p] = NULL;
+        }
+}
+
+static int read_data(void) {
+        int r;
+
+        free_data();
+
+        data[PROP_HOSTNAME] = gethostname_malloc();
+        if (!data[PROP_HOSTNAME])
+                return -ENOMEM;
+
+        r = read_one_line_file("/etc/hostname", &data[PROP_STATIC_HOSTNAME]);
+        if (r < 0 && r != -ENOENT)
+                return r;
+
+        r = parse_env_file("/etc/machine-info", NEWLINE,
+                           "PRETTY_HOSTNAME", &data[PROP_PRETTY_HOSTNAME],
+                           "ICON_NAME", &data[PROP_ICON_NAME],
+                           "CHASSIS", &data[PROP_CHASSIS],
+                           NULL);
+        if (r < 0 && r != -ENOENT)
+                return r;
+
+        return 0;
+}
+
+static bool check_nss(void) {
+        void *dl;
+
+        dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY);
+        if (dl) {
+                dlclose(dl);
+                return true;
+        }
+
+        return false;
+}
+
+static bool valid_chassis(const char *chassis) {
+
+        assert(chassis);
+
+        return nulstr_contains(
+                        "vm\0"
+                        "container\0"
+                        "desktop\0"
+                        "laptop\0"
+                        "server\0"
+                        "tablet\0"
+                        "handset\0",
+                        chassis);
+}
+
+static const char* fallback_chassis(void) {
+        int r;
+        char *type;
+        unsigned t;
+        Virtualization v;
+
+        v = detect_virtualization(NULL);
+
+        if (v == VIRTUALIZATION_VM)
+                return "vm";
+        if (v == VIRTUALIZATION_CONTAINER)
+                return "container";
+
+        r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
+        if (r < 0)
+                goto try_dmi;
+
+        r = safe_atou(type, &t);
+        free(type);
+        if (r < 0)
+                goto try_dmi;
+
+        /* We only list the really obvious cases here as the ACPI data
+         * is not really super reliable.
+         *
+         * See the ACPI 5.0 Spec Section 5.2.9.1 for details:
+         *
+         * http://www.acpi.info/DOWNLOADS/ACPIspec50.pdf
+         */
+
+        switch(t) {
+
+        case 1:
+        case 3:
+        case 6:
+                return "desktop";
+
+        case 2:
+                return "laptop";
+
+        case 4:
+        case 5:
+        case 7:
+                return "server";
+
+        case 8:
+                return "tablet";
+        }
+
+try_dmi:
+        r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type);
+        if (r < 0)
+                return NULL;
+
+        r = safe_atou(type, &t);
+        free(type);
+        if (r < 0)
+                return NULL;
+
+        /* We only list the really obvious cases here. The DMI data is
+           unreliable enough, so let's not do any additional guesswork
+           on top of that.
+
+           See the SMBIOS Specification 2.7.1 section 7.4.1 for
+           details about the values listed here:
+
+           http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
+         */
+
+        switch (t) {
+
+        case 0x3:
+        case 0x4:
+        case 0x6:
+        case 0x7:
+                return "desktop";
+
+        case 0x8:
+        case 0x9:
+        case 0xA:
+        case 0xE:
+                return "laptop";
+
+        case 0xB:
+                return "handset";
+
+        case 0x11:
+        case 0x1C:
+                return "server";
+        }
+
+        return NULL;
+}
+
+static char* fallback_icon_name(void) {
+        const char *chassis;
+
+        if (!isempty(data[PROP_CHASSIS]))
+                return strappend("computer-", data[PROP_CHASSIS]);
+
+        chassis = fallback_chassis();
+        if (chassis)
+                return strappend("computer-", chassis);
+
+        return strdup("computer");
+}
+
+static int write_data_hostname(void) {
+        const char *hn;
+
+        if (isempty(data[PROP_HOSTNAME]))
+                hn = "localhost";
+        else
+                hn = data[PROP_HOSTNAME];
+
+        if (sethostname(hn, strlen(hn)) < 0)
+                return -errno;
+
+        return 0;
+}
+
+static int write_data_static_hostname(void) {
+
+        if (isempty(data[PROP_STATIC_HOSTNAME])) {
+
+                if (unlink("/etc/hostname") < 0)
+                        return errno == ENOENT ? 0 : -errno;
+
+                return 0;
+        }
+
+        return write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
+}
+
+static int write_data_other(void) {
+
+        static const char * const name[_PROP_MAX] = {
+                [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME",
+                [PROP_ICON_NAME] = "ICON_NAME",
+                [PROP_CHASSIS] = "CHASSIS"
+        };
+
+        char **l = NULL;
+        int r, p;
+
+        r = load_env_file("/etc/machine-info", &l);
+        if (r < 0 && r != -ENOENT)
+                return r;
+
+        for (p = 2; p < _PROP_MAX; p++) {
+                char *t, **u;
+
+                assert(name[p]);
+
+                if (isempty(data[p]))  {
+                        strv_env_unset(l, name[p]);
+                        continue;
+                }
+
+                if (asprintf(&t, "%s=%s", name[p], strempty(data[p])) < 0) {
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+
+                u = strv_env_set(l, t);
+                free(t);
+                strv_free(l);
+
+                if (!u)
+                        return -ENOMEM;
+                l = u;
+        }
+
+        if (strv_isempty(l)) {
+
+                if (unlink("/etc/machine-info") < 0)
+                        return errno == ENOENT ? 0 : -errno;
+
+                return 0;
+        }
+
+        r = write_env_file("/etc/machine-info", l);
+        strv_free(l);
+
+        return r;
+}
+
+static int bus_hostname_append_icon_name(DBusMessageIter *i, const char *property, void *userdata) {
+        const char *name;
+        _cleanup_free_ char *n = NULL;
+
+        assert(i);
+        assert(property);
+
+        if (isempty(data[PROP_ICON_NAME]))
+                name = n = fallback_icon_name();
+        else
+                name = data[PROP_ICON_NAME];
+
+        return bus_property_append_string(i, property, (void*) name);
+}
+
+static int bus_hostname_append_chassis(DBusMessageIter *i, const char *property, void *userdata) {
+        const char *name;
+
+        assert(i);
+        assert(property);
+
+        if (isempty(data[PROP_CHASSIS]))
+                name = fallback_chassis();
+        else
+                name = data[PROP_CHASSIS];
+
+        return bus_property_append_string(i, property, (void*) name);
+}
+
+static const BusProperty bus_hostname_properties[] = {
+        { "Hostname",       bus_property_append_string,    "s", sizeof(data[0])*PROP_HOSTNAME,        true },
+        { "StaticHostname", bus_property_append_string,    "s", sizeof(data[0])*PROP_STATIC_HOSTNAME, true },
+        { "PrettyHostname", bus_property_append_string,    "s", sizeof(data[0])*PROP_PRETTY_HOSTNAME, true },
+        { "IconName",       bus_hostname_append_icon_name, "s", sizeof(data[0])*PROP_ICON_NAME,       true },
+        { "Chassis",        bus_hostname_append_chassis,   "s", sizeof(data[0])*PROP_CHASSIS,         true },
+        { NULL, }
+};
+
+static const BusBoundProperties bps[] = {
+        { "org.freedesktop.hostname1", bus_hostname_properties, data },
+        { NULL, }
+};
+
+static DBusHandlerResult hostname_message_handler(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+
+        DBusMessage *reply = NULL, *changed = NULL;
+        DBusError error;
+        int r;
+
+        assert(connection);
+        assert(message);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetHostname")) {
+                const char *name;
+                dbus_bool_t interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(name))
+                        name = data[PROP_STATIC_HOSTNAME];
+
+                if (isempty(name))
+                        name = "localhost";
+
+                if (!hostname_is_valid(name))
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                if (!streq_ptr(name, data[PROP_HOSTNAME])) {
+                        char *h;
+
+                        r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-hostname", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        h = strdup(name);
+                        if (!h)
+                                goto oom;
+
+                        free(data[PROP_HOSTNAME]);
+                        data[PROP_HOSTNAME] = h;
+
+                        r = write_data_hostname();
+                        if (r < 0) {
+                                log_error("Failed to set host name: %s", strerror(-r));
+                                return bus_send_error_reply(connection, message, NULL, r);
+                        }
+
+                        log_info("Changed host name to '%s'", strempty(data[PROP_HOSTNAME]));
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/hostname1",
+                                        "org.freedesktop.hostname1",
+                                        "Hostname\0");
+                        if (!changed)
+                                goto oom;
+                }
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetStaticHostname")) {
+                const char *name;
+                dbus_bool_t interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(name))
+                        name = NULL;
+
+                if (!streq_ptr(name, data[PROP_STATIC_HOSTNAME])) {
+
+                        r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-static-hostname", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        if (isempty(name)) {
+                                free(data[PROP_STATIC_HOSTNAME]);
+                                data[PROP_STATIC_HOSTNAME] = NULL;
+                        } else {
+                                char *h;
+
+                                if (!hostname_is_valid(name))
+                                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                                h = strdup(name);
+                                if (!h)
+                                        goto oom;
+
+                                free(data[PROP_STATIC_HOSTNAME]);
+                                data[PROP_STATIC_HOSTNAME] = h;
+                        }
+
+                        r = write_data_static_hostname();
+                        if (r < 0) {
+                                log_error("Failed to write static host name: %s", strerror(-r));
+                                return bus_send_error_reply(connection, message, NULL, r);
+                        }
+
+                        log_info("Changed static host name to '%s'", strempty(data[PROP_STATIC_HOSTNAME]));
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/hostname1",
+                                        "org.freedesktop.hostname1",
+                                        "StaticHostname\0");
+                        if (!changed)
+                                goto oom;
+                }
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetPrettyHostname") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetIconName") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetChassis")) {
+
+                const char *name;
+                dbus_bool_t interactive;
+                int k;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(name))
+                        name = NULL;
+
+                k = streq(dbus_message_get_member(message), "SetPrettyHostname") ? PROP_PRETTY_HOSTNAME :
+                        streq(dbus_message_get_member(message), "SetChassis") ? PROP_CHASSIS : PROP_ICON_NAME;
+
+                if (!streq_ptr(name, data[k])) {
+
+                        /* Since the pretty hostname should always be
+                         * changed at the same time as the static one,
+                         * use the same policy action for both... */
+
+                        r = verify_polkit(connection, message, k == PROP_PRETTY_HOSTNAME ?
+                                          "org.freedesktop.hostname1.set-static-hostname" :
+                                          "org.freedesktop.hostname1.set-machine-info", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        if (isempty(name)) {
+                                free(data[k]);
+                                data[k] = NULL;
+                        } else {
+                                char *h;
+
+                                /* The icon name might ultimately be
+                                 * used as file name, so better be
+                                 * safe than sorry */
+                                if (k == PROP_ICON_NAME && !filename_is_safe(name))
+                                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+                                if (k == PROP_PRETTY_HOSTNAME && !string_is_safe(name))
+                                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+                                if (k == PROP_CHASSIS && !valid_chassis(name))
+                                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                                h = strdup(name);
+                                if (!h)
+                                        goto oom;
+
+                                free(data[k]);
+                                data[k] = h;
+                        }
+
+                        r = write_data_other();
+                        if (r < 0) {
+                                log_error("Failed to write machine info: %s", strerror(-r));
+                                return bus_send_error_reply(connection, message, NULL, r);
+                        }
+
+                        log_info("Changed %s to '%s'",
+                                 k == PROP_PRETTY_HOSTNAME ? "pretty host name" :
+                                 k == PROP_CHASSIS ? "chassis" : "icon name", strempty(data[k]));
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/hostname1",
+                                        "org.freedesktop.hostname1",
+                                        k == PROP_PRETTY_HOSTNAME ? "PrettyHostname\0" :
+                                        k == PROP_CHASSIS ? "Chassis\0" : "IconName\0");
+                        if (!changed)
+                                goto oom;
+                }
+
+        } else
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+
+        reply = dbus_message_new_method_return(message);
+        if (!reply)
+                goto oom;
+
+        if (!dbus_connection_send(connection, reply, NULL))
+                goto oom;
+
+        dbus_message_unref(reply);
+        reply = NULL;
+
+        if (changed) {
+
+                if (!dbus_connection_send(connection, changed, NULL))
+                        goto oom;
+
+                dbus_message_unref(changed);
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        if (changed)
+                dbus_message_unref(changed);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static int connect_bus(DBusConnection **_bus) {
+        static const DBusObjectPathVTable hostname_vtable = {
+                .message_function = hostname_message_handler
+        };
+        DBusError error;
+        DBusConnection *bus = NULL;
+        int r;
+
+        assert(_bus);
+
+        dbus_error_init(&error);
+
+        bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        if (!bus) {
+                log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
+                r = -ECONNREFUSED;
+                goto fail;
+        }
+
+        dbus_connection_set_exit_on_disconnect(bus, FALSE);
+
+        if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL) ||
+            !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) {
+                r = log_oom();
+                goto fail;
+        }
+
+        r = dbus_bus_request_name(bus, "org.freedesktop.hostname1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to register name on bus: %s", bus_error_message(&error));
+                r = -EEXIST;
+                goto fail;
+        }
+
+        if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+                log_error("Failed to acquire name.");
+                r = -EEXIST;
+                goto fail;
+        }
+
+        if (_bus)
+                *_bus = bus;
+
+        return 0;
+
+fail:
+        dbus_connection_close(bus);
+        dbus_connection_unref(bus);
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+        DBusConnection *bus = NULL;
+        bool exiting = false;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argc == 2 && streq(argv[1], "--introspect")) {
+                fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+                      "<node>\n", stdout);
+                fputs(hostname_interface, stdout);
+                fputs("</node>\n", stdout);
+                return 0;
+        }
+
+        if (argc != 1) {
+                log_error("This program takes no arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        if (!check_nss())
+                log_warning("Warning: nss-myhostname is not installed. Changing the local hostname might make it unresolveable. Please install nss-myhostname!");
+
+        r = read_data();
+        if (r < 0) {
+                log_error("Failed to read hostname data: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = connect_bus(&bus);
+        if (r < 0)
+                goto finish;
+
+        remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
+        for (;;) {
+
+                if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
+                        break;
+
+                if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
+                        exiting = true;
+                        bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1");
+                }
+        }
+
+        r = 0;
+
+finish:
+        free_data();
+
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/hostname/org.freedesktop.hostname1.conf b/src/hostname/org.freedesktop.hostname1.conf
new file mode 100644 (file)
index 0000000..46b4aad
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0"?> <!--*-nxml-*-->
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<busconfig>
+
+        <policy user="root">
+                <allow own="org.freedesktop.hostname1"/>
+                <allow send_destination="org.freedesktop.hostname1"/>
+                <allow receive_sender="org.freedesktop.hostname1"/>
+        </policy>
+
+        <policy context="default">
+                <allow send_destination="org.freedesktop.hostname1"/>
+                <allow receive_sender="org.freedesktop.hostname1"/>
+        </policy>
+
+</busconfig>
diff --git a/src/hostname/org.freedesktop.hostname1.policy.in b/src/hostname/org.freedesktop.hostname1.policy.in
new file mode 100644 (file)
index 0000000..c32c1d4
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<policyconfig>
+
+        <vendor>The systemd Project</vendor>
+        <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
+
+        <action id="org.freedesktop.hostname1.set-hostname">
+                <_description>Set host name</_description>
+                <_message>Authentication is required to set the local host name.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.hostname1.set-static-hostname">
+                <_description>Set static host name</_description>
+                <_message>Authentication is required to set the statically configured local host name, as well as the pretty host name.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.hostname1.set-hostname org.freedesktop.hostname1.set-machine-info</annotate>
+        </action>
+
+        <action id="org.freedesktop.hostname1.set-machine-info">
+                <_description>Set machine information</_description>
+                <_message>Authentication is required to set local machine information.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+</policyconfig>
diff --git a/src/hostname/org.freedesktop.hostname1.service b/src/hostname/org.freedesktop.hostname1.service
new file mode 100644 (file)
index 0000000..6041ed6
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[D-BUS Service]
+Name=org.freedesktop.hostname1
+Exec=/bin/false
+User=root
+SystemdService=dbus-org.freedesktop.hostname1.service
diff --git a/src/initctl/Makefile b/src/initctl/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
new file mode 100644 (file)
index 0000000..0eb008d
--- /dev/null
@@ -0,0 +1,451 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <time.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <sys/epoll.h>
+#include <sys/un.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include <dbus/dbus.h>
+#include <systemd/sd-daemon.h>
+
+#include "util.h"
+#include "log.h"
+#include "list.h"
+#include "initreq.h"
+#include "special.h"
+#include "dbus-common.h"
+#include "def.h"
+
+#define SERVER_FD_MAX 16
+#define TIMEOUT_MSEC ((int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))
+
+typedef struct Fifo Fifo;
+
+typedef struct Server {
+        int epoll_fd;
+
+        LIST_HEAD(Fifo, fifos);
+        unsigned n_fifos;
+
+        DBusConnection *bus;
+
+        bool quit;
+} Server;
+
+struct Fifo {
+        Server *server;
+
+        int fd;
+
+        struct init_request buffer;
+        size_t bytes_read;
+
+        LIST_FIELDS(Fifo, fifo);
+};
+
+static const char *translate_runlevel(int runlevel, bool *isolate) {
+        static const struct {
+                const int runlevel;
+                const char *special;
+                bool isolate;
+        } table[] = {
+                { '0', SPECIAL_POWEROFF_TARGET,  false },
+                { '1', SPECIAL_RESCUE_TARGET,    true  },
+                { 's', SPECIAL_RESCUE_TARGET,    true  },
+                { 'S', SPECIAL_RESCUE_TARGET,    true  },
+                { '2', SPECIAL_RUNLEVEL2_TARGET, true  },
+                { '3', SPECIAL_RUNLEVEL3_TARGET, true  },
+                { '4', SPECIAL_RUNLEVEL4_TARGET, true  },
+                { '5', SPECIAL_RUNLEVEL5_TARGET, true  },
+                { '6', SPECIAL_REBOOT_TARGET,    false },
+        };
+
+        unsigned i;
+
+        assert(isolate);
+
+        for (i = 0; i < ELEMENTSOF(table); i++)
+                if (table[i].runlevel == runlevel) {
+                        *isolate = table[i].isolate;
+                        if (runlevel == '6' && kexec_loaded())
+                                return SPECIAL_KEXEC_TARGET;
+                        return table[i].special;
+                }
+
+        return NULL;
+}
+
+static void change_runlevel(Server *s, int runlevel) {
+        const char *target;
+        DBusMessage *m = NULL, *reply = NULL;
+        DBusError error;
+        const char *mode;
+        bool isolate = false;
+
+        assert(s);
+
+        dbus_error_init(&error);
+
+        if (!(target = translate_runlevel(runlevel, &isolate))) {
+                log_warning("Got request for unknown runlevel %c, ignoring.", runlevel);
+                goto finish;
+        }
+
+        if (isolate)
+                mode = "isolate";
+        else
+                mode = "replace";
+
+        log_debug("Running request %s/start/%s", target, mode);
+
+        if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) {
+                log_error("Could not allocate message.");
+                goto finish;
+        }
+
+        if (!dbus_message_append_args(m,
+                                      DBUS_TYPE_STRING, &target,
+                                      DBUS_TYPE_STRING, &mode,
+                                      DBUS_TYPE_INVALID)) {
+                log_error("Could not attach target and flag information to message.");
+                goto finish;
+        }
+
+        if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) {
+                log_error("Failed to start unit: %s", bus_error_message(&error));
+                goto finish;
+        }
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+}
+
+static void request_process(Server *s, const struct init_request *req) {
+        assert(s);
+        assert(req);
+
+        if (req->magic != INIT_MAGIC) {
+                log_error("Got initctl request with invalid magic. Ignoring.");
+                return;
+        }
+
+        switch (req->cmd) {
+
+        case INIT_CMD_RUNLVL:
+                if (!isprint(req->runlevel))
+                        log_error("Got invalid runlevel. Ignoring.");
+                else
+                        switch (req->runlevel) {
+
+                        /* we are async anyway, so just use kill for reexec/reload */
+                        case 'u':
+                        case 'U':
+                                if (kill(1, SIGTERM) < 0)
+                                        log_error("kill() failed: %m");
+
+                                /* The bus connection will be
+                                 * terminated if PID 1 is reexecuted,
+                                 * hence let's just exit here, and
+                                 * rely on that we'll be restarted on
+                                 * the next request */
+                                s->quit = true;
+                                break;
+
+                        case 'q':
+                        case 'Q':
+                                if (kill(1, SIGHUP) < 0)
+                                        log_error("kill() failed: %m");
+                                break;
+
+                        default:
+                                change_runlevel(s, req->runlevel);
+                        }
+                return;
+
+        case INIT_CMD_POWERFAIL:
+        case INIT_CMD_POWERFAILNOW:
+        case INIT_CMD_POWEROK:
+                log_warning("Received UPS/power initctl request. This is not implemented in systemd. Upgrade your UPS daemon!");
+                return;
+
+        case INIT_CMD_CHANGECONS:
+                log_warning("Received console change initctl request. This is not implemented in systemd.");
+                return;
+
+        case INIT_CMD_SETENV:
+        case INIT_CMD_UNSETENV:
+                log_warning("Received environment initctl request. This is not implemented in systemd.");
+                return;
+
+        default:
+                log_warning("Received unknown initctl request. Ignoring.");
+                return;
+        }
+}
+
+static int fifo_process(Fifo *f) {
+        ssize_t l;
+
+        assert(f);
+
+        errno = EIO;
+        if ((l = read(f->fd, ((uint8_t*) &f->buffer) + f->bytes_read, sizeof(f->buffer) - f->bytes_read)) <= 0) {
+
+                if (errno == EAGAIN)
+                        return 0;
+
+                log_warning("Failed to read from fifo: %s", strerror(errno));
+                return -1;
+        }
+
+        f->bytes_read += l;
+        assert(f->bytes_read <= sizeof(f->buffer));
+
+        if (f->bytes_read == sizeof(f->buffer)) {
+                request_process(f->server, &f->buffer);
+                f->bytes_read = 0;
+        }
+
+        return 0;
+}
+
+static void fifo_free(Fifo *f) {
+        assert(f);
+
+        if (f->server) {
+                assert(f->server->n_fifos > 0);
+                f->server->n_fifos--;
+                LIST_REMOVE(Fifo, fifo, f->server->fifos, f);
+        }
+
+        if (f->fd >= 0) {
+                if (f->server)
+                        epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL);
+
+                close_nointr_nofail(f->fd);
+        }
+
+        free(f);
+}
+
+static void server_done(Server *s) {
+        assert(s);
+
+        while (s->fifos)
+                fifo_free(s->fifos);
+
+        if (s->epoll_fd >= 0)
+                close_nointr_nofail(s->epoll_fd);
+
+        if (s->bus) {
+                dbus_connection_flush(s->bus);
+                dbus_connection_close(s->bus);
+                dbus_connection_unref(s->bus);
+        }
+}
+
+static int server_init(Server *s, unsigned n_sockets) {
+        int r;
+        unsigned i;
+        DBusError error;
+
+        assert(s);
+        assert(n_sockets > 0);
+
+        dbus_error_init(&error);
+
+        zero(*s);
+
+        if ((s->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
+                r = -errno;
+                log_error("Failed to create epoll object: %s", strerror(errno));
+                goto fail;
+        }
+
+        for (i = 0; i < n_sockets; i++) {
+                struct epoll_event ev;
+                Fifo *f;
+                int fd;
+
+                fd = SD_LISTEN_FDS_START+i;
+
+                if ((r = sd_is_fifo(fd, NULL)) < 0) {
+                        log_error("Failed to determine file descriptor type: %s", strerror(-r));
+                        goto fail;
+                }
+
+                if (!r) {
+                        log_error("Wrong file descriptor type.");
+                        r = -EINVAL;
+                        goto fail;
+                }
+
+                if (!(f = new0(Fifo, 1))) {
+                        r = -ENOMEM;
+                        log_error("Failed to create fifo object: %s", strerror(errno));
+                        goto fail;
+                }
+
+                f->fd = -1;
+
+                zero(ev);
+                ev.events = EPOLLIN;
+                ev.data.ptr = f;
+                if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
+                        r = -errno;
+                        fifo_free(f);
+                        log_error("Failed to add fifo fd to epoll object: %s", strerror(errno));
+                        goto fail;
+                }
+
+                f->fd = fd;
+                LIST_PREPEND(Fifo, fifo, s->fifos, f);
+                f->server = s;
+                s->n_fifos ++;
+        }
+
+        if (bus_connect(DBUS_BUS_SYSTEM, &s->bus, NULL, &error) < 0) {
+                log_error("Failed to get D-Bus connection: %s", bus_error_message(&error));
+                goto fail;
+        }
+
+        return 0;
+
+fail:
+        server_done(s);
+
+        dbus_error_free(&error);
+        return r;
+}
+
+static int process_event(Server *s, struct epoll_event *ev) {
+        int r;
+        Fifo *f;
+
+        assert(s);
+
+        if (!(ev->events & EPOLLIN)) {
+                log_info("Got invalid event from epoll. (3)");
+                return -EIO;
+        }
+
+        f = (Fifo*) ev->data.ptr;
+
+        if ((r = fifo_process(f)) < 0) {
+                log_info("Got error on fifo: %s", strerror(-r));
+                fifo_free(f);
+                return r;
+        }
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        Server server;
+        int r = EXIT_FAILURE, n;
+
+        if (getppid() != 1) {
+                log_error("This program should be invoked by init only.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1) {
+                log_error("This program does not take arguments.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if ((n = sd_listen_fds(true)) < 0) {
+                log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
+                return EXIT_FAILURE;
+        }
+
+        if (n <= 0 || n > SERVER_FD_MAX) {
+                log_error("No or too many file descriptors passed.");
+                return EXIT_FAILURE;
+        }
+
+        if (server_init(&server, (unsigned) n) < 0)
+                return EXIT_FAILURE;
+
+        log_debug("systemd-initctl running as pid %lu", (unsigned long) getpid());
+
+        sd_notify(false,
+                  "READY=1\n"
+                  "STATUS=Processing requests...");
+
+        while (!server.quit) {
+                struct epoll_event event;
+                int k;
+
+                if ((k = epoll_wait(server.epoll_fd,
+                                    &event, 1,
+                                    TIMEOUT_MSEC)) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        log_error("epoll_wait() failed: %s", strerror(errno));
+                        goto fail;
+                }
+
+                if (k <= 0)
+                        break;
+
+                if (process_event(&server, &event) < 0)
+                        goto fail;
+        }
+
+        r = EXIT_SUCCESS;
+
+        log_debug("systemd-initctl stopped as pid %lu", (unsigned long) getpid());
+
+fail:
+        sd_notify(false,
+                  "STATUS=Shutting down...");
+
+        server_done(&server);
+
+        dbus_shutdown();
+
+        return r;
+}
diff --git a/src/journal/.gitignore b/src/journal/.gitignore
new file mode 100644 (file)
index 0000000..d6a7946
--- /dev/null
@@ -0,0 +1,2 @@
+/journald-gperf.c
+/libsystemd-journal.pc
diff --git a/src/journal/Makefile b/src/journal/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/journal/browse.html b/src/journal/browse.html
new file mode 100644 (file)
index 0000000..3594f70
--- /dev/null
@@ -0,0 +1,544 @@
+<!DOCTYPE html>
+<html>
+<head>
+        <title>Journal</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+        <style type="text/css">
+                div#divlogs, div#diventry {
+                        font-family: monospace;
+                        font-size: 7pt;
+                        background-color: #ffffff;
+                        padding: 1em;
+                        margin: 2em 0em;
+                        border-radius: 10px 10px 10px 10px;
+                        border: 1px solid threedshadow;
+                        white-space: nowrap;
+                        overflow-x: scroll;
+                }
+                div#diventry {
+                        display: none;
+                }
+                div#divlogs {
+                        display: block;
+                }
+                body {
+                        background-color: #ededed;
+                        color: #313739;
+                        font: message-box;
+                        margin: 3em;
+                }
+                td.timestamp {
+                        text-align: right;
+                        border-right: 1px dotted lightgrey;
+                        padding-right: 5px;
+                }
+                td.process {
+                        border-right: 1px dotted lightgrey;
+                        padding-left: 5px;
+                        padding-right: 5px;
+                }
+                td.message {
+                        padding-left: 5px;
+                }
+                td.message > a:link, td.message > a:visited {
+                        text-decoration: none;
+                        color: #313739;
+                }
+                td.message-error {
+                        padding-left: 5px;
+                        color: red;
+                        font-weight: bold;
+                }
+                td.message-error > a:link, td.message-error > a:visited {
+                        text-decoration: none;
+                        color: red;
+                }
+                td.message-highlight {
+                        padding-left: 5px;
+                        font-weight: bold;
+                }
+                td.message-highlight > a:link, td.message-highlight > a:visited {
+                        text-decoration: none;
+                        color: #313739;
+                }
+                td > a:hover, td > a:active {
+                        text-decoration: underline;
+                        color: #c13739;
+                }
+                table#tablelogs, table#tableentry {
+                        border-collapse: collapse;
+                }
+                td.field {
+                        text-align: right;
+                        border-right: 1px dotted lightgrey;
+                        padding-right: 5px;
+                }
+                td.data {
+                        padding-left: 5px;
+                }
+                div#keynav {
+                        text-align: center;
+                        font-size: 7pt;
+                        color: #818789;
+                        padding-top: 2em;
+                }
+                span.key {
+                        font-weight: bold;
+                        color: #313739;
+                }
+                div#buttonnav {
+                        text-align: center;
+                }
+                button {
+                        font-size: 18pt;
+                        font-weight: bold;
+                        width: 2em;
+                        height: 2em;
+                }
+                div#filternav {
+                        text-align: center;
+                }
+                select {
+                        width: 50em;
+                }
+        </style>
+</head>
+
+<body>
+        <!-- TODO:
+                - live display
+                - show red lines for reboots -->
+
+        <h1 id="title"></h1>
+
+        <div id="os"></div>
+        <div id="virtualization"></div>
+        <div id="cutoff"></div>
+        <div id="machine"></div>
+        <div id="usage"></div>
+        <div id="showing"></div>
+
+        <div id="filternav">
+                <select id="filter" onchange="onFilterChange(this);" onfocus="onFilterFocus(this);">
+                        <option>No filter</option>
+                </select>
+                &nbsp;&nbsp;&nbsp;&nbsp;
+                <input id="boot" type="checkbox" onchange="onBootChange(this);">Only current boot</input>
+        </div>
+
+        <div id="divlogs"><table id="tablelogs"></table></div>
+        <a name="entry"></a>
+        <div id="diventry"><table id="tableentry"></table></div>
+
+        <div id="buttonnav">
+                <button id="head" onclick="entriesLoadHead();" title="First Page">&#8676;</button>
+                <button id="previous" type="button" onclick="entriesLoadPrevious();" title="Previous Page"/>&#8592;</button>
+                <button id="next" type="button" onclick="entriesLoadNext();" title="Next Page"/>&#8594;</button>
+                <button id="tail" type="button" onclick="entriesLoadTail();" title="Last Page"/>&#8677;</button>
+                &nbsp;&nbsp;&nbsp;&nbsp;
+                <button id="more" type="button" onclick="entriesMore();" title="More Entries"/>+</button>
+                <button id="less" type="button" onclick="entriesLess();" title="Fewer Entries"/>-</button>
+        </div>
+
+        <div id="keynav">
+                <span class="key">g</span>: First Page &nbsp;&nbsp;&nbsp;&nbsp;
+                <span class="key">&#8592;, k, BACKSPACE</span>: Previous Page &nbsp;&nbsp;&nbsp;&nbsp;
+                <span class="key">&#8594;, j, SPACE</span>: Next Page &nbsp;&nbsp;&nbsp;&nbsp;
+                <span class="key">G</span>: Last Page &nbsp;&nbsp;&nbsp;&nbsp;
+                <span class="key">+</span>: More entries &nbsp;&nbsp;&nbsp;&nbsp;
+                <span class="key">-</span>: Fewer entries
+        </div>
+
+        <script type="text/javascript">
+                var first_cursor = null;
+                var last_cursor = null;
+
+                function getNEntries() {
+                        var n;
+                        n = localStorage["n_entries"];
+                        if (n == null)
+                                return 50;
+                        n = parseInt(n);
+                        if (n < 10)
+                                return 10;
+                        if (n > 1000)
+                                return 1000;
+                        return n;
+                }
+
+                function showNEntries(n) {
+                        var showing = document.getElementById("showing");
+                        showing.innerHTML = "Showing <b>" + n.toString() + "</b> entries.";
+                }
+
+                function setNEntries(n) {
+                        if (n < 10)
+                                return 10;
+                        if (n > 1000)
+                                return 1000;
+                        localStorage["n_entries"] = n.toString();
+                        showNEntries(n);
+                }
+
+                function machineLoad() {
+                        var request = new XMLHttpRequest();
+                        request.open("GET", "/machine");
+                        request.onreadystatechange = machineOnResult;
+                        request.setRequestHeader("Accept", "application/json");
+                        request.send(null);
+                }
+
+                function formatBytes(u) {
+                        if (u >= 1024*1024*1024*1024)
+                                return (u/1024/1024/1024/1024).toFixed(1) + " TiB";
+                        else if (u >= 1024*1024*1024)
+                                return (u/1024/1024/1024).toFixed(1) + " GiB";
+                        else if (u >= 1024*1024)
+                                return (u/1024/1024).toFixed(1) + " MiB";
+                        else if (u >= 1024)
+                                return (u/1024).toFixed(1) + " KiB";
+                        else
+                                return u.toString() + " B";
+                }
+
+                function escapeHTML(s) {
+                        return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
+                }
+
+                function machineOnResult(event) {
+                        if ((event.currentTarget.readyState != 4) ||
+                                (event.currentTarget.status != 200 && event.currentTarget.status != 0))
+                                return;
+
+                        var d = JSON.parse(event.currentTarget.responseText);
+
+                        var title = document.getElementById("title");
+                        title.innerHTML = 'Journal of ' + escapeHTML(d.hostname);
+                        document.title = 'Journal of ' + escapeHTML(d.hostname);
+
+                        var machine = document.getElementById("machine");
+                        machine.innerHTML = 'Machine ID is <b>' + d.machine_id + '</b>, current boot ID is <b>' + d.boot_id + '</b>.';
+
+                        var cutoff = document.getElementById("cutoff");
+                        var from = new Date(parseInt(d.cutoff_from_realtime) / 1000);
+                        var to = new Date(parseInt(d.cutoff_to_realtime) / 1000);
+                        cutoff.innerHTML = 'Journal begins at <b>' + from.toLocaleString() + '</b> and ends at <b>' + to.toLocaleString() + '</b>.';
+
+                        var usage = document.getElementById("usage");
+                        usage.innerHTML = 'Disk usage is <b>' + formatBytes(parseInt(d.usage)) + '</b>.';
+
+                        var os = document.getElementById("os");
+                        os.innerHTML = 'Operating system is <b>' + escapeHTML(d.os_pretty_name) + '</b>.';
+
+                        var virtualization = document.getElementById("virtualization");
+                        virtualization.innerHTML = d.virtualization == "bare" ? "Running on <b>bare metal</b>." : "Running on virtualization <b>" + escapeHTML(d.virtualization) + "</b>.";
+                }
+
+                function entriesLoad(range) {
+
+                        if (range == null)
+                                range = localStorage["cursor"] + ":0";
+                        if (range == null)
+                                range = "";
+
+                        var url = "/entries";
+
+                        if (localStorage["filter"] != "" && localStorage["filter"] != null) {
+                                url += "?_SYSTEMD_UNIT=" + escape(localStorage["filter"]);
+
+                                if (localStorage["boot"] == "1")
+                                        url += "&boot";
+                        } else {
+                                if (localStorage["boot"] == "1")
+                                        url += "?boot";
+                        }
+
+                        var request = new XMLHttpRequest();
+                        request.open("GET", url);
+                        request.onreadystatechange = entriesOnResult;
+                        request.setRequestHeader("Accept", "application/json");
+                        request.setRequestHeader("Range", "entries=" + range + ":" + getNEntries().toString());
+                        request.send(null);
+                }
+
+                function entriesLoadNext() {
+                        if (last_cursor == null)
+                                entriesLoad("");
+                        else
+                                entriesLoad(last_cursor + ":1");
+                }
+
+                function entriesLoadPrevious() {
+                        if (first_cursor == null)
+                                entriesLoad("");
+                        else
+                                entriesLoad(first_cursor + ":-" + getNEntries().toString());
+                }
+
+                function entriesLoadHead() {
+                        entriesLoad("");
+                }
+
+                function entriesLoadTail() {
+                        entriesLoad(":-" + getNEntries().toString());
+                }
+
+                function entriesOnResult(event) {
+
+                        if ((event.currentTarget.readyState != 4) ||
+                                (event.currentTarget.status != 200 && event.currentTarget.status != 0))
+                                return;
+
+                        var logs = document.getElementById("tablelogs");
+
+                        var lc = null;
+                        var fc = null;
+
+                        var i, l = event.currentTarget.responseText.split('\n');
+
+                        if (l.length <= 1) {
+                                logs.innerHTML = '<tbody><tr><td colspan="3"><i>No further entries...</i></td></tr></tbody>';
+                                return;
+                        }
+
+                        var buf = '';
+
+                        for (i in l) {
+
+                                if (l[i] == '')
+                                        continue;
+
+                                var d = JSON.parse(l[i]);
+                                if (d.MESSAGE == undefined || d.__CURSOR == undefined)
+                                        continue;
+
+                                if (fc == null)
+                                        fc = d.__CURSOR;
+                                lc = d.__CURSOR;
+
+                                var priority;
+                                if (d.PRIORITY != undefined)
+                                        priority = parseInt(d.PRIORITY);
+                                else
+                                        priority = 6;
+
+                                if (priority <= 3)
+                                        clazz = "message-error";
+                                else if (priority <= 5)
+                                        clazz = "message-highlight";
+                                else
+                                        clazz = "message";
+
+                                buf += '<tr><td class="timestamp">';
+
+                                if (d.__REALTIME_TIMESTAMP != undefined) {
+                                        var timestamp = new Date(parseInt(d.__REALTIME_TIMESTAMP) / 1000);
+                                        buf += timestamp.toLocaleString();
+                                }
+
+                                buf += '</td><td class="process">';
+
+                                if (d.SYSLOG_IDENTIFIER != undefined)
+                                        buf += escapeHTML(d.SYSLOG_IDENTIFIER);
+                                else if (d._COMM != undefined)
+                                        buf += escapeHTML(d._COMM);
+
+                                if (d._PID != undefined)
+                                        buf += "[" + escapeHTML(d._PID) + "]";
+                                else if (d.SYSLOG_PID != undefined)
+                                        buf += "[" + escapeHTML(d.SYSLOG_PID) + "]";
+
+                                buf += '</td><td class="' + clazz + '"><a href="#entry" onclick="onMessageClick(\'' + d.__CURSOR + '\');">';
+
+                                if (d.MESSAGE == null)
+                                        buf += "[blob data]";
+                                else if (d.MESSAGE instanceof Array)
+                                        buf += "[" + formatBytes(d.MESSAGE.length) + " blob data]";
+                                else
+                                        buf += escapeHTML(d.MESSAGE);
+
+                                buf += '</a></td></tr>';
+                        }
+
+                        logs.innerHTML = '<tbody>' + buf + '</tbody>';
+
+                        if (fc != null) {
+                                first_cursor = fc;
+                                localStorage["cursor"] = fc;
+                        }
+                        if (lc != null)
+                                last_cursor = lc;
+                }
+
+                function entriesMore() {
+                        setNEntries(getNEntries() + 10);
+                        entriesLoad(first_cursor);
+                }
+
+                function entriesLess() {
+                        setNEntries(getNEntries() - 10);
+                        entriesLoad(first_cursor);
+                }
+
+                function onResultMessageClick(event) {
+                        if ((event.currentTarget.readyState != 4) ||
+                                (event.currentTarget.status != 200 && event.currentTarget.status != 0))
+                                return;
+
+                        var d = JSON.parse(event.currentTarget.responseText);
+
+                        document.getElementById("diventry").style.display = "block";
+                        entry = document.getElementById("tableentry");
+
+                        var buf = "";
+                        for (var key in d){
+                                var data = d[key];
+
+                                if (data == null)
+                                        data = "[blob data]";
+                                else if (data instanceof Array)
+                                        data = "[" + formatBytes(data.length) + " blob data]";
+                                else
+                                        data = escapeHTML(data);
+
+                                buf += '<tr><td class="field">' + key + '</td><td class="data">' + data + '</td></tr>';
+                        }
+                        entry.innerHTML = '<tbody>' + buf + '</tbody>';
+                }
+
+                function onMessageClick(t) {
+                        var request = new XMLHttpRequest();
+                        request.open("GET", "/entries?discrete");
+                        request.onreadystatechange = onResultMessageClick;
+                        request.setRequestHeader("Accept", "application/json");
+                        request.setRequestHeader("Range", "entries=" + t + ":0:1");
+                        request.send(null);
+                }
+
+                function onKeyUp(event) {
+                        switch (event.keyCode) {
+                                case 8:
+                                case 37:
+                                case 75:
+                                        entriesLoadPrevious();
+                                        break;
+                                case 32:
+                                case 39:
+                                case 74:
+                                        entriesLoadNext();
+                                        break;
+
+                                case 71:
+                                        if (event.shiftKey)
+                                                entriesLoadTail();
+                                        else
+                                                entriesLoadHead();
+                                        break;
+                                case 171:
+                                        entriesMore();
+                                        break;
+                                case 173:
+                                        entriesLess();
+                                        break;
+                        }
+                }
+
+                function onMouseWheel(event) {
+                        if (event.detail < 0 || event.wheelDelta > 0)
+                                entriesLoadPrevious();
+                        else
+                                entriesLoadNext();
+                }
+
+                function onResultFilterFocus(event) {
+                        if ((event.currentTarget.readyState != 4) ||
+                                (event.currentTarget.status != 200 && event.currentTarget.status != 0))
+                                return;
+
+                        f = document.getElementById("filter");
+
+                        var l = event.currentTarget.responseText.split('\n');
+                        var buf = '<option>No filter</option>';
+                        var j = -1;
+
+                        for (i in l) {
+
+                                if (l[i] == '')
+                                      continue;
+
+                                var d = JSON.parse(l[i]);
+                                if (d._SYSTEMD_UNIT == undefined)
+                                      continue;
+
+                                buf += '<option value="' + escape(d._SYSTEMD_UNIT) + '">' + escapeHTML(d._SYSTEMD_UNIT) + '</option>';
+
+                                if (d._SYSTEMD_UNIT == localStorage["filter"])
+                                        j = i;
+                        }
+
+                        if (j < 0) {
+                                if (localStorage["filter"] != null && localStorage["filter"] != "") {
+                                          buf += '<option value="' + escape(localStorage["filter"]) + '">' + escapeHTML(localStorage["filter"]) + '</option>';
+                                          j = i + 1;
+                                } else
+                                          j = 0;
+                        }
+
+                        f.innerHTML = buf;
+                        f.selectedIndex = j;
+                }
+
+                function onFilterFocus(w) {
+                        var request = new XMLHttpRequest();
+                        request.open("GET", "/fields/_SYSTEMD_UNIT");
+                        request.onreadystatechange = onResultFilterFocus;
+                        request.setRequestHeader("Accept", "application/json");
+                        request.send(null);
+                }
+
+                function onFilterChange(w) {
+                        if (w.selectedIndex <= 0)
+                                localStorage["filter"] = "";
+                        else
+                                localStorage["filter"] = unescape(w.options[w.selectedIndex].value);
+
+                        entriesLoadHead();
+                }
+
+                function onBootChange(w) {
+                        localStorage["boot"] = w.checked ? "1" : "0";
+                        entriesLoadHead();
+                }
+
+                function initFilter() {
+                        f = document.getElementById("filter");
+
+                        var buf = '<option>No filter</option>';
+
+                        var filter = localStorage["filter"];
+                        if (filter != null && filter != "") {
+                                buf += '<option value="' + escape(filter) + '">' + escapeHTML(filter) + '</option>';
+                                j = 1;
+                        } else
+                                j = 0;
+
+                        f.innerHTML = buf;
+                        f.selectedIndex = j;
+                }
+
+                function installHandlers() {
+                        document.onkeyup = onKeyUp;
+
+                        logs = document.getElementById("divlogs");
+                        logs.addEventListener("mousewheel", onMouseWheel, false);
+                        logs.addEventListener("DOMMouseScroll", onMouseWheel, false);
+                }
+
+                machineLoad();
+                entriesLoad(null);
+                showNEntries(getNEntries());
+                initFilter();
+                installHandlers();
+        </script>
+</body>
+</html>
diff --git a/src/journal/cat.c b/src/journal/cat.c
new file mode 100644 (file)
index 0000000..a95392c
--- /dev/null
@@ -0,0 +1,179 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <getopt.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/fcntl.h>
+
+#include <systemd/sd-journal.h>
+
+#include "util.h"
+#include "build.h"
+
+static char *arg_identifier = NULL;
+static int arg_priority = LOG_INFO;
+static bool arg_level_prefix = true;
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
+               "Execute process with stdout/stderr connected to the journal.\n\n"
+               "  -h --help               Show this help\n"
+               "     --version            Show package version\n"
+               "  -t --identifier=STRING  Set syslog identifier\n"
+               "  -p --priority=PRIORITY  Set priority value (0..7)\n"
+               "     --level-prefix=BOOL  Control whether level prefix shall be parsed\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_LEVEL_PREFIX
+        };
+
+        static const struct option options[] = {
+                { "help",         no_argument,       NULL, 'h'              },
+                { "version",      no_argument,       NULL, ARG_VERSION      },
+                { "identifier",   required_argument, NULL, 't'              },
+                { "priority",     required_argument, NULL, 'p'              },
+                { "level-prefix", required_argument, NULL, ARG_LEVEL_PREFIX },
+                { NULL,           0,                 NULL, 0                }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "+ht:p:", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case 't':
+                        free(arg_identifier);
+                        if (isempty(optarg))
+                                arg_identifier = NULL;
+                        else {
+                                arg_identifier = strdup(optarg);
+                                if (!arg_identifier)
+                                        return log_oom();
+                        }
+                        break;
+
+                case 'p':
+                        arg_priority = log_level_from_string(optarg);
+                        if (arg_priority < 0) {
+                                log_error("Failed to parse priority value.");
+                                return arg_priority;
+                        }
+                        break;
+
+                case ARG_LEVEL_PREFIX: {
+                        int k;
+
+                        k = parse_boolean(optarg);
+                        if (k < 0) {
+                                log_error("Failed to parse level prefix value.");
+                                return k;
+                        }
+                        arg_level_prefix = k;
+                        break;
+                }
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r, fd = -1, saved_stderr = -1;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        fd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix);
+        if (fd < 0) {
+                log_error("Failed to create stream fd: %s", strerror(-fd));
+                r = fd;
+                goto finish;
+        }
+
+        saved_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3);
+
+        if (dup3(fd, STDOUT_FILENO, 0) < 0 ||
+            dup3(fd, STDERR_FILENO, 0) < 0) {
+                log_error("Failed to duplicate fd: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if (fd >= 3)
+                close_nointr_nofail(fd);
+
+        fd = -1;
+
+        if (argc <= optind)
+                execl("/bin/cat", "/bin/cat", NULL);
+        else
+                execvp(argv[optind], argv + optind);
+
+        r = -errno;
+
+        /* Let's try to restore a working stderr, so we can print the error message */
+        if (saved_stderr >= 0)
+                dup3(saved_stderr, STDERR_FILENO, 0);
+
+        log_error("Failed to execute process: %s", strerror(-r));
+
+finish:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        if (saved_stderr >= 0)
+                close_nointr_nofail(saved_stderr);
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/journal/catalog.c b/src/journal/catalog.c
new file mode 100644 (file)
index 0000000..3735ad9
--- /dev/null
@@ -0,0 +1,593 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <locale.h>
+
+#include "util.h"
+#include "log.h"
+#include "sparse-endian.h"
+#include "sd-id128.h"
+#include "hashmap.h"
+#include "strv.h"
+#include "strbuf.h"
+#include "conf-files.h"
+#include "mkdir.h"
+#include "catalog.h"
+
+static const char * const conf_file_dirs[] = {
+        "/usr/local/lib/systemd/catalog/",
+        "/usr/lib/systemd/catalog/",
+        NULL
+};
+
+#define CATALOG_SIGNATURE (uint8_t[]) { 'R', 'H', 'H', 'H', 'K', 'S', 'L', 'P' }
+
+typedef struct CatalogHeader {
+        uint8_t signature[8];  /* "RHHHKSLP" */
+        le32_t compatible_flags;
+        le32_t incompatible_flags;
+        le64_t header_size;
+        le64_t n_items;
+        le64_t catalog_item_size;
+} CatalogHeader;
+
+typedef struct CatalogItem {
+        sd_id128_t id;
+        char language[32];
+        le64_t offset;
+} CatalogItem;
+
+static unsigned catalog_hash_func(const void *p) {
+        const CatalogItem *i = p;
+
+        assert_cc(sizeof(unsigned) == sizeof(uint8_t)*4);
+
+        return (((unsigned) i->id.bytes[0] << 24) |
+                ((unsigned) i->id.bytes[1] << 16) |
+                ((unsigned) i->id.bytes[2] << 8) |
+                ((unsigned) i->id.bytes[3])) ^
+               (((unsigned) i->id.bytes[4] << 24) |
+                ((unsigned) i->id.bytes[5] << 16) |
+                ((unsigned) i->id.bytes[6] << 8) |
+                ((unsigned) i->id.bytes[7])) ^
+               (((unsigned) i->id.bytes[8] << 24) |
+                ((unsigned) i->id.bytes[9] << 16) |
+                ((unsigned) i->id.bytes[10] << 8) |
+                ((unsigned) i->id.bytes[11])) ^
+               (((unsigned) i->id.bytes[12] << 24) |
+                ((unsigned) i->id.bytes[13] << 16) |
+                ((unsigned) i->id.bytes[14] << 8) |
+                ((unsigned) i->id.bytes[15])) ^
+                string_hash_func(i->language);
+}
+
+static int catalog_compare_func(const void *a, const void *b) {
+        const CatalogItem *i = a, *j = b;
+        unsigned k;
+
+        for (k = 0; k < ELEMENTSOF(j->id.bytes); k++) {
+                 if (i->id.bytes[k] < j->id.bytes[k])
+                        return -1;
+                 if (i->id.bytes[k] > j->id.bytes[k])
+                        return 1;
+        }
+
+        return strncmp(i->language, j->language, sizeof(i->language));
+}
+
+static int finish_item(
+                Hashmap *h,
+                struct strbuf *sb,
+                sd_id128_t id,
+                const char *language,
+                const char *payload) {
+
+        ssize_t offset;
+        CatalogItem *i;
+        int r;
+
+        assert(h);
+        assert(sb);
+        assert(payload);
+
+        offset = strbuf_add_string(sb, payload, strlen(payload));
+        if (offset < 0)
+                return log_oom();
+
+        i = new0(CatalogItem, 1);
+        if (!i)
+                return log_oom();
+
+        i->id = id;
+        strncpy(i->language, language, sizeof(i->language));
+        i->offset = htole64((uint64_t) offset);
+
+        r = hashmap_put(h, i, i);
+        if (r == EEXIST) {
+                log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.", SD_ID128_FORMAT_VAL(id), language ? language : "C");
+                free(i);
+                return 0;
+        }
+
+        return 0;
+}
+
+static int import_file(Hashmap *h, struct strbuf *sb, const char *path) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *payload = NULL;
+        unsigned n = 0;
+        sd_id128_t id;
+        char language[32];
+        bool got_id = false, empty_line = true;
+        int r;
+
+        assert(h);
+        assert(sb);
+        assert(path);
+
+        f = fopen(path, "re");
+        if (!f) {
+                log_error("Failed to open file %s: %m", path);
+                return -errno;
+        }
+
+        for (;;) {
+                char line[LINE_MAX];
+                size_t a, b, c;
+                char *t;
+
+                if (!fgets(line, sizeof(line), f)) {
+                        if (feof(f))
+                                break;
+
+                        log_error("Failed to read file %s: %m", path);
+                        return -errno;
+                }
+
+                n++;
+
+                truncate_nl(line);
+
+                if (line[0] == 0) {
+                        empty_line = true;
+                        continue;
+                }
+
+                if (strchr(COMMENTS, line[0]))
+                        continue;
+
+                if (empty_line &&
+                    strlen(line) >= 2+1+32 &&
+                    line[0] == '-' &&
+                    line[1] == '-' &&
+                    line[2] == ' ' &&
+                    (line[2+1+32] == ' ' || line[2+1+32] == 0)) {
+
+                        bool with_language;
+                        sd_id128_t jd;
+
+                        /* New entry */
+
+                        with_language = line[2+1+32] != 0;
+                        line[2+1+32] = 0;
+
+                        if (sd_id128_from_string(line + 2 + 1, &jd) >= 0) {
+
+                                if (got_id) {
+                                        r = finish_item(h, sb, id, language, payload);
+                                        if (r < 0)
+                                                return r;
+                                }
+
+                                if (with_language) {
+                                        t = strstrip(line + 2 + 1 + 32 + 1);
+
+                                        c = strlen(t);
+                                        if (c <= 0) {
+                                                log_error("[%s:%u] Language too short.", path, n);
+                                                return -EINVAL;
+                                        }
+                                        if (c > sizeof(language)) {
+                                                log_error("[%s:%u] language too long.", path, n);
+                                                return -EINVAL;
+                                        }
+
+                                        strncpy(language, t, sizeof(language));
+                                } else
+                                        zero(language);
+
+                                got_id = true;
+                                empty_line = false;
+                                id = jd;
+
+                                if (payload)
+                                        payload[0] = 0;
+
+                                continue;
+                        }
+                }
+
+                /* Payload */
+                if (!got_id) {
+                        log_error("[%s:%u] Got payload before ID.", path, n);
+                        return -EINVAL;
+                }
+
+                a = payload ? strlen(payload) : 0;
+                b = strlen(line);
+
+                c = a + (empty_line ? 1 : 0) + b + 1 + 1;
+                t = realloc(payload, c);
+                if (!t)
+                        return log_oom();
+
+                if (empty_line) {
+                        t[a] = '\n';
+                        memcpy(t + a + 1, line, b);
+                        t[a+b+1] = '\n';
+                        t[a+b+2] = 0;
+                } else {
+                        memcpy(t + a, line, b);
+                        t[a+b] = '\n';
+                        t[a+b+1] = 0;
+                }
+
+                payload = t;
+                empty_line = false;
+        }
+
+        if (got_id) {
+                r = finish_item(h, sb, id, language, payload);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+#define CATALOG_DATABASE CATALOG_PATH "/database"
+
+int catalog_update(void) {
+        _cleanup_strv_free_ char **files = NULL;
+        _cleanup_fclose_ FILE *w = NULL;
+        _cleanup_free_ char *p = NULL;
+        char **f;
+        Hashmap *h;
+        struct strbuf *sb = NULL;
+        _cleanup_free_ CatalogItem *items = NULL;
+        CatalogItem *i;
+        CatalogHeader header;
+        size_t k;
+        Iterator j;
+        unsigned n;
+        int r;
+
+        h = hashmap_new(catalog_hash_func, catalog_compare_func);
+        if (!h)
+                return -ENOMEM;
+
+        sb = strbuf_new();
+        if (!sb) {
+                r = log_oom();
+                goto finish;
+        }
+
+        r = conf_files_list_strv(&files, ".catalog", (const char **) conf_file_dirs);
+        if (r < 0) {
+                log_error("Failed to get catalog files: %s", strerror(-r));
+                goto finish;
+        }
+
+        STRV_FOREACH(f, files) {
+                log_debug("reading file '%s'", *f);
+                import_file(h, sb, *f);
+        }
+
+        if (hashmap_size(h) <= 0) {
+                log_info("No items in catalog.");
+                r = 0;
+                goto finish;
+        } else
+                log_debug("Found %u items in catalog.", hashmap_size(h));
+
+        strbuf_complete(sb);
+
+        items = new(CatalogItem, hashmap_size(h));
+        if (!items) {
+                r = log_oom();
+                goto finish;
+        }
+
+        n = 0;
+        HASHMAP_FOREACH(i, h, j) {
+                log_debug("Found " SD_ID128_FORMAT_STR ", language %s", SD_ID128_FORMAT_VAL(i->id), isempty(i->language) ? "C" : i->language);
+                items[n++] = *i;
+        }
+
+        assert(n == hashmap_size(h));
+        qsort(items, n, sizeof(CatalogItem), catalog_compare_func);
+
+        r = mkdir_p(CATALOG_PATH, 0775);
+        if (r < 0) {
+                log_error("Recursive mkdir %s: %s", CATALOG_PATH, strerror(-r));
+                goto finish;
+        }
+
+        r = fopen_temporary(CATALOG_DATABASE, &w, &p);
+        if (r < 0) {
+                log_error("Failed to open database for writing: %s: %s",
+                          CATALOG_DATABASE, strerror(-r));
+                goto finish;
+        }
+
+        zero(header);
+        memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature));
+        header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8));
+        header.catalog_item_size = htole64(sizeof(CatalogItem));
+        header.n_items = htole64(hashmap_size(h));
+
+        k = fwrite(&header, 1, sizeof(header), w);
+        if (k != sizeof(header)) {
+                log_error("%s: failed to write header.", p);
+                goto finish;
+        }
+
+        k = fwrite(items, 1, n * sizeof(CatalogItem), w);
+        if (k != n * sizeof(CatalogItem)) {
+                log_error("%s: failed to write database.", p);
+                goto finish;
+        }
+
+        k = fwrite(sb->buf, 1, sb->len, w);
+        if (k != sb->len) {
+                log_error("%s: failed to write strings.", p);
+                goto finish;
+        }
+
+        fflush(w);
+
+        if (ferror(w)) {
+                log_error("%s: failed to write database.", p);
+                goto finish;
+        }
+
+        fchmod(fileno(w), 0644);
+
+        if (rename(p, CATALOG_DATABASE) < 0) {
+                log_error("rename (%s -> %s) failed: %m", p, CATALOG_DATABASE);
+                r = -errno;
+                goto finish;
+        }
+
+        log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.",
+                 CATALOG_DATABASE, n, sb->len, ftell(w));
+
+        free(p);
+        p = NULL;
+
+        r = 0;
+
+finish:
+        hashmap_free_free(h);
+
+        if (sb)
+                strbuf_cleanup(sb);
+
+        if (p)
+                unlink(p);
+
+        return r;
+}
+
+static int open_mmap(int *_fd, struct stat *_st, void **_p) {
+        const CatalogHeader *h;
+        int fd;
+        void *p;
+        struct stat st;
+
+        assert(_fd);
+        assert(_st);
+        assert(_p);
+
+        fd = open(CATALOG_DATABASE, O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        if (fstat(fd, &st) < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        if (st.st_size < (off_t) sizeof(CatalogHeader)) {
+                close_nointr_nofail(fd);
+                return -EINVAL;
+        }
+
+        p = mmap(NULL, PAGE_ALIGN(st.st_size), PROT_READ, MAP_SHARED, fd, 0);
+        if (p == MAP_FAILED) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        h = p;
+        if (memcmp(h->signature, CATALOG_SIGNATURE, sizeof(h->signature)) != 0 ||
+            le64toh(h->header_size) < sizeof(CatalogHeader) ||
+            le64toh(h->catalog_item_size) < sizeof(CatalogItem) ||
+            h->incompatible_flags != 0 ||
+            le64toh(h->n_items) <= 0 ||
+            st.st_size < (off_t) (le64toh(h->header_size) + le64toh(h->catalog_item_size) * le64toh(h->n_items))) {
+                close_nointr_nofail(fd);
+                munmap(p, st.st_size);
+                return -EBADMSG;
+        }
+
+        *_fd = fd;
+        *_st = st;
+        *_p = p;
+
+        return 0;
+}
+
+static const char *find_id(void *p, sd_id128_t id) {
+        CatalogItem key, *f = NULL;
+        const CatalogHeader *h = p;
+        const char *loc;
+
+        zero(key);
+        key.id = id;
+
+        loc = setlocale(LC_MESSAGES, NULL);
+        if (loc && loc[0] && !streq(loc, "C") && !streq(loc, "POSIX")) {
+                strncpy(key.language, loc, sizeof(key.language));
+                key.language[strcspn(key.language, ".@")] = 0;
+
+                f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func);
+                if (!f) {
+                        char *e;
+
+                        e = strchr(key.language, '_');
+                        if (e) {
+                                *e = 0;
+                                f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func);
+                        }
+                }
+        }
+
+        if (!f) {
+                zero(key.language);
+                f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func);
+        }
+
+        if (!f)
+                return NULL;
+
+        return (const char*) p +
+                le64toh(h->header_size) +
+                le64toh(h->n_items) * le64toh(h->catalog_item_size) +
+                le64toh(f->offset);
+}
+
+int catalog_get(sd_id128_t id, char **_text) {
+        _cleanup_close_ int fd = -1;
+        void *p = NULL;
+        struct stat st;
+        char *text = NULL;
+        int r;
+        const char *s;
+
+        assert(_text);
+
+        r = open_mmap(&fd, &st, &p);
+        if (r < 0)
+                return r;
+
+        s = find_id(p, id);
+        if (!s) {
+                r = -ENOENT;
+                goto finish;
+        }
+
+        text = strdup(s);
+        if (!text) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        *_text = text;
+        r = 0;
+
+finish:
+        if (p)
+                munmap(p, st.st_size);
+
+        return r;
+}
+
+static char *find_header(const char *s, const char *header) {
+
+        for (;;) {
+                const char *v, *e;
+
+                v = startswith(s, header);
+                if (v) {
+                        v += strspn(v, WHITESPACE);
+                        return strndup(v, strcspn(v, NEWLINE));
+                }
+
+                /* End of text */
+                e = strchr(s, '\n');
+                if (!e)
+                        return NULL;
+
+                /* End of header */
+                if (e == s)
+                        return NULL;
+
+                s = e + 1;
+        }
+}
+
+int catalog_list(FILE *f) {
+        _cleanup_close_ int fd = -1;
+        void *p = NULL;
+        struct stat st;
+        const CatalogHeader *h;
+        const CatalogItem *items;
+        int r;
+        unsigned n;
+        sd_id128_t last_id;
+        bool last_id_set = false;
+
+        r = open_mmap(&fd, &st, &p);
+        if (r < 0)
+                return r;
+
+        h = p;
+        items = (const CatalogItem*) ((const uint8_t*) p + le64toh(h->header_size));
+
+        for (n = 0; n < le64toh(h->n_items); n++) {
+                const char *s;
+                _cleanup_free_ char *subject = NULL, *defined_by = NULL;
+
+                if (last_id_set && sd_id128_equal(last_id, items[n].id))
+                        continue;
+
+                assert_se(s = find_id(p, items[n].id));
+
+                subject = find_header(s, "Subject:");
+                defined_by = find_header(s, "Defined-By:");
+
+                fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n", SD_ID128_FORMAT_VAL(items[n].id), strna(defined_by), strna(subject));
+
+                last_id_set = true;
+                last_id = items[n].id;
+        }
+
+        munmap(p, st.st_size);
+
+        return 0;
+}
diff --git a/src/journal/catalog.h b/src/journal/catalog.h
new file mode 100644 (file)
index 0000000..9add773
--- /dev/null
@@ -0,0 +1,28 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-id128.h"
+
+int catalog_update(void);
+int catalog_get(sd_id128_t id, char **data);
+int catalog_list(FILE *f);
diff --git a/src/journal/compress.c b/src/journal/compress.c
new file mode 100644 (file)
index 0000000..a4427be
--- /dev/null
@@ -0,0 +1,216 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lzma.h>
+
+#include "macro.h"
+#include "compress.h"
+
+bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) {
+        lzma_stream s = LZMA_STREAM_INIT;
+        lzma_ret ret;
+        bool b = false;
+
+        assert(src);
+        assert(src_size > 0);
+        assert(dst);
+        assert(dst_size);
+
+        /* Returns false if we couldn't compress the data or the
+         * compressed result is longer than the original */
+
+        ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_NONE);
+        if (ret != LZMA_OK)
+                return false;
+
+        s.next_in = src;
+        s.avail_in = src_size;
+        s.next_out = dst;
+        s.avail_out = src_size;
+
+        /* Does it fit? */
+        if (lzma_code(&s, LZMA_FINISH) != LZMA_STREAM_END)
+                goto fail;
+
+        /* Is it actually shorter? */
+        if (s.avail_out == 0)
+                goto fail;
+
+        *dst_size = src_size - s.avail_out;
+        b = true;
+
+fail:
+        lzma_end(&s);
+
+        return b;
+}
+
+bool uncompress_blob(const void *src, uint64_t src_size,
+                     void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max) {
+
+        lzma_stream s = LZMA_STREAM_INIT;
+        lzma_ret ret;
+        uint64_t space;
+        bool b = false;
+
+        assert(src);
+        assert(src_size > 0);
+        assert(dst);
+        assert(dst_alloc_size);
+        assert(dst_size);
+        assert(*dst_alloc_size == 0 || *dst);
+
+        ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
+        if (ret != LZMA_OK)
+                return false;
+
+        if (*dst_alloc_size <= src_size) {
+                void *p;
+
+                p = realloc(*dst, src_size*2);
+                if (!p)
+                        return false;
+
+                *dst = p;
+                *dst_alloc_size = src_size*2;
+        }
+
+        s.next_in = src;
+        s.avail_in = src_size;
+
+        s.next_out = *dst;
+        space = dst_max > 0 ? MIN(*dst_alloc_size, dst_max) : *dst_alloc_size;
+        s.avail_out = space;
+
+        for (;;) {
+                void *p;
+
+                ret = lzma_code(&s, LZMA_FINISH);
+
+                if (ret == LZMA_STREAM_END)
+                        break;
+
+                if (ret != LZMA_OK)
+                        goto fail;
+
+                if (dst_max > 0 && (space - s.avail_out) >= dst_max)
+                        break;
+
+                p = realloc(*dst, space*2);
+                if (!p)
+                        goto fail;
+
+                s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *dst);
+                s.avail_out += space;
+
+                space *= 2;
+
+                *dst = p;
+                *dst_alloc_size = space;
+        }
+
+        *dst_size = space - s.avail_out;
+        b = true;
+
+fail:
+        lzma_end(&s);
+
+        return b;
+}
+
+bool uncompress_startswith(const void *src, uint64_t src_size,
+                           void **buffer, uint64_t *buffer_size,
+                           const void *prefix, uint64_t prefix_len,
+                           uint8_t extra) {
+
+        lzma_stream s = LZMA_STREAM_INIT;
+        lzma_ret ret;
+        bool b = false;
+
+        /* Checks whether the uncompressed blob starts with the
+         * mentioned prefix. The byte extra needs to follow the
+         * prefix */
+
+        assert(src);
+        assert(src_size > 0);
+        assert(buffer);
+        assert(buffer_size);
+        assert(prefix);
+        assert(*buffer_size == 0 || *buffer);
+
+        ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
+        if (ret != LZMA_OK)
+                return false;
+
+        if (*buffer_size <= prefix_len) {
+                void *p;
+
+                p = realloc(*buffer, prefix_len*2);
+                if (!p)
+                        return false;
+
+                *buffer = p;
+                *buffer_size = prefix_len*2;
+        }
+
+        s.next_in = src;
+        s.avail_in = src_size;
+
+        s.next_out = *buffer;
+        s.avail_out = *buffer_size;
+
+        for (;;) {
+                void *p;
+
+                ret = lzma_code(&s, LZMA_FINISH);
+
+                if (ret != LZMA_STREAM_END && ret != LZMA_OK)
+                        goto fail;
+
+                if ((*buffer_size - s.avail_out > prefix_len) &&
+                    memcmp(*buffer, prefix, prefix_len) == 0 &&
+                    ((const uint8_t*) *buffer)[prefix_len] == extra)
+                        break;
+
+                if (ret == LZMA_STREAM_END)
+                        goto fail;
+
+                p = realloc(*buffer, *buffer_size*2);
+                if (!p)
+                        goto fail;
+
+                s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *buffer);
+                s.avail_out += *buffer_size;
+
+                *buffer = p;
+                *buffer_size *= 2;
+        }
+
+        b = true;
+
+fail:
+        lzma_end(&s);
+
+        return b;
+}
diff --git a/src/journal/compress.h b/src/journal/compress.h
new file mode 100644 (file)
index 0000000..2b87e73
--- /dev/null
@@ -0,0 +1,35 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size);
+
+bool uncompress_blob(const void *src, uint64_t src_size,
+                     void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max);
+
+bool uncompress_startswith(const void *src, uint64_t src_size,
+                           void **buffer, uint64_t *buffer_size,
+                           const void *prefix, uint64_t prefix_len,
+                           uint8_t extra);
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
new file mode 100644 (file)
index 0000000..a507fc6
--- /dev/null
@@ -0,0 +1,278 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/prctl.h>
+
+#include <systemd/sd-journal.h>
+
+#ifdef HAVE_LOGIND
+#include <systemd/sd-login.h>
+#endif
+
+#include "log.h"
+#include "util.h"
+#include "mkdir.h"
+#include "special.h"
+#include "cgroup-util.h"
+
+#define COREDUMP_MAX (24*1024*1024)
+
+enum {
+        ARG_PID = 1,
+        ARG_UID,
+        ARG_GID,
+        ARG_SIGNAL,
+        ARG_TIMESTAMP,
+        ARG_COMM,
+        _ARG_MAX
+};
+
+static int divert_coredump(void) {
+        FILE *f;
+        int r;
+
+        log_info("Detected coredump of the journal daemon itself, diverting coredump to /var/lib/systemd/coredump/.");
+
+        mkdir_p_label("/var/lib/systemd/coredump", 0755);
+
+        f = fopen("/var/lib/systemd/coredump/core.systemd-journald", "we");
+        if (!f) {
+                log_error("Failed to create coredump file: %m");
+                return -errno;
+        }
+
+        for (;;) {
+                uint8_t buffer[4096];
+                size_t l, q;
+
+                l = fread(buffer, 1, sizeof(buffer), stdin);
+                if (l <= 0) {
+                        if (ferror(f)) {
+                                log_error("Failed to read coredump: %m");
+                                r = -errno;
+                                goto finish;
+                        }
+
+                        r = 0;
+                        break;
+                }
+
+                q = fwrite(buffer, 1, l, f);
+                if (q != l) {
+                        log_error("Failed to write coredump: %m");
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        fflush(f);
+
+        if (ferror(f)) {
+                log_error("Failed to write coredump: %m");
+                r = -errno;
+        }
+
+finish:
+        fclose(f);
+        return r;
+}
+
+int main(int argc, char* argv[]) {
+        int r, j = 0;
+        char *p = NULL;
+        ssize_t n;
+        pid_t pid;
+        uid_t uid;
+        gid_t gid;
+        struct iovec iovec[14];
+        char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL,
+                *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL,
+                *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *t;
+
+        prctl(PR_SET_DUMPABLE, 0);
+
+        if (argc != _ARG_MAX) {
+                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+                log_open();
+
+                log_error("Invalid number of arguments passed from kernel.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        r = parse_pid(argv[ARG_PID], &pid);
+        if (r < 0) {
+                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+                log_open();
+
+                log_error("Failed to parse PID.");
+                goto finish;
+        }
+
+        if (cg_pid_get_unit(pid, &t) >= 0) {
+
+                if (streq(t, SPECIAL_JOURNALD_SERVICE)) {
+                        /* Make sure we don't make use of the journal,
+                         * if it's the journal which is crashing */
+                        log_set_target(LOG_TARGET_KMSG);
+                        log_open();
+
+                        r = divert_coredump();
+                        goto finish;
+                }
+
+                core_unit = strappend("COREDUMP_UNIT=", t);
+                free(t);
+
+                if (core_unit)
+                        IOVEC_SET_STRING(iovec[j++], core_unit);
+        }
+
+        /* OK, now we know it's not the journal, hence make use of
+         * it */
+        log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+        log_open();
+
+        r = parse_uid(argv[ARG_UID], &uid);
+        if (r < 0) {
+                log_error("Failed to parse UID.");
+                goto finish;
+        }
+
+        r = parse_gid(argv[ARG_GID], &gid);
+        if (r < 0) {
+                log_error("Failed to parse GID.");
+                goto finish;
+        }
+
+        core_pid = strappend("COREDUMP_PID=", argv[ARG_PID]);
+        if (core_pid)
+                IOVEC_SET_STRING(iovec[j++], core_pid);
+
+        core_uid = strappend("COREDUMP_UID=", argv[ARG_UID]);
+        if (core_uid)
+                IOVEC_SET_STRING(iovec[j++], core_uid);
+
+        core_gid = strappend("COREDUMP_GID=", argv[ARG_GID]);
+        if (core_gid)
+                IOVEC_SET_STRING(iovec[j++], core_gid);
+
+        core_signal = strappend("COREDUMP_SIGNAL=", argv[ARG_SIGNAL]);
+        if (core_signal)
+                IOVEC_SET_STRING(iovec[j++], core_signal);
+
+        core_comm = strappend("COREDUMP_COMM=", argv[ARG_COMM]);
+        if (core_comm)
+                IOVEC_SET_STRING(iovec[j++], core_comm);
+
+#ifdef HAVE_LOGIND
+        if (sd_pid_get_session(pid, &t) >= 0) {
+                core_session = strappend("COREDUMP_SESSION=", t);
+                free(t);
+
+                if (core_session)
+                        IOVEC_SET_STRING(iovec[j++], core_session);
+        }
+
+#endif
+
+        if (get_process_exe(pid, &t) >= 0) {
+                core_exe = strappend("COREDUMP_EXE=", t);
+                free(t);
+
+                if (core_exe)
+                        IOVEC_SET_STRING(iovec[j++], core_exe);
+        }
+
+        if (get_process_cmdline(pid, LINE_MAX, false, &t) >= 0) {
+                core_cmdline = strappend("COREDUMP_CMDLINE=", t);
+                free(t);
+
+                if (core_cmdline)
+                        IOVEC_SET_STRING(iovec[j++], core_cmdline);
+        }
+
+        core_timestamp = strjoin("COREDUMP_TIMESTAMP=", argv[ARG_TIMESTAMP], "000000", NULL);
+        if (core_timestamp)
+                IOVEC_SET_STRING(iovec[j++], core_timestamp);
+
+        IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
+        IOVEC_SET_STRING(iovec[j++], "PRIORITY=2");
+
+        core_message = strjoin("MESSAGE=Process ", argv[ARG_PID], " (", argv[ARG_COMM], ") dumped core.", NULL);
+        if (core_message)
+                IOVEC_SET_STRING(iovec[j++], core_message);
+
+        /* Now, let's drop privileges to become the user who owns the
+         * segfaulted process and allocate the coredump memory under
+         * his uid. This also ensures that the credentials journald
+         * will see are the ones of the coredumping user, thus making
+         * sure the user himself gets access to the core dump. */
+
+        if (setresgid(gid, gid, gid) < 0 ||
+            setresuid(uid, uid, uid) < 0) {
+                log_error("Failed to drop privileges: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        p = malloc(9 + COREDUMP_MAX);
+        if (!p) {
+                r = log_oom();
+                goto finish;
+        }
+
+        memcpy(p, "COREDUMP=", 9);
+
+        n = loop_read(STDIN_FILENO, p + 9, COREDUMP_MAX, false);
+        if (n < 0) {
+                log_error("Failed to read core dump data: %s", strerror(-n));
+                r = (int) n;
+                goto finish;
+        }
+
+        iovec[j].iov_base = p;
+        iovec[j].iov_len = 9 + n;
+        j++;
+
+        r = sd_journal_sendv(iovec, j);
+        if (r < 0)
+                log_error("Failed to send coredump: %s", strerror(-r));
+
+finish:
+        free(p);
+        free(core_pid);
+        free(core_uid);
+        free(core_gid);
+        free(core_signal);
+        free(core_timestamp);
+        free(core_comm);
+        free(core_exe);
+        free(core_cmdline);
+        free(core_unit);
+        free(core_session);
+        free(core_message);
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c
new file mode 100644 (file)
index 0000000..b6e5581
--- /dev/null
@@ -0,0 +1,592 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <systemd/sd-journal.h>
+
+#include "build.h"
+#include "set.h"
+#include "util.h"
+#include "log.h"
+#include "path-util.h"
+#include "pager.h"
+
+static enum {
+        ACTION_NONE,
+        ACTION_LIST,
+        ACTION_DUMP,
+        ACTION_GDB,
+} arg_action = ACTION_LIST;
+
+static Set *matches = NULL;
+static FILE* output = NULL;
+static char* field = NULL;
+
+static int arg_no_pager = false;
+static int arg_no_legend = false;
+
+static Set *new_matches(void) {
+        Set *set;
+        char *tmp;
+        int r;
+
+        set = set_new(trivial_hash_func, trivial_compare_func);
+        if (!set) {
+                log_oom();
+                return NULL;
+        }
+
+        tmp = strdup("MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
+        if (!tmp) {
+                log_oom();
+                set_free(set);
+                return NULL;
+        }
+
+        r = set_put(set, tmp);
+        if (r < 0) {
+                log_error("failed to add to set: %s", strerror(-r));
+                free(tmp);
+                set_free(set);
+                return NULL;
+        }
+
+        return set;
+}
+
+static int help(void) {
+        printf("%s [OPTIONS...] [MATCHES...]\n\n"
+               "List or retrieve coredumps from the journal.\n\n"
+               "Flags:\n"
+               "  -o --output=FILE  Write output to FILE\n"
+               "     --no-pager     Do not pipe output into a pager\n"
+
+               "Commands:\n"
+               "  -h --help         Show this help\n"
+               "  --version         Print version string\n"
+               "  -F --field=FIELD  List all values a certain field takes\n"
+               "  gdb               Start gdb for the first matching coredump\n"
+               "  list              List available coredumps\n"
+               "  dump PID          Print coredump to stdout\n"
+               "  dump PATH         Print coredump to stdout\n"
+               , program_invocation_short_name);
+
+        return 0;
+}
+
+static int add_match(Set *set, const char *match) {
+        int r = -ENOMEM;
+        unsigned pid;
+        const char* prefix;
+        char *pattern = NULL;
+        char _cleanup_free_ *p = NULL;
+
+        if (strchr(match, '='))
+                prefix = "";
+        else if (strchr(match, '/')) {
+                p = path_make_absolute_cwd(match);
+                if (!p)
+                        goto fail;
+
+                match = p;
+                prefix = "COREDUMP_EXE=";
+        }
+        else if (safe_atou(match, &pid) == 0)
+                prefix = "COREDUMP_PID=";
+        else
+                prefix = "COREDUMP_COMM=";
+
+        pattern = strjoin(prefix, match, NULL);
+        if (!pattern)
+                goto fail;
+
+        r = set_put(set, pattern);
+        if (r < 0) {
+                log_error("failed to add pattern '%s': %s",
+                          pattern, strerror(-r));
+                goto fail;
+        }
+        log_debug("Added pattern: %s", pattern);
+
+        return 0;
+fail:
+        free(pattern);
+        log_error("failed to add match: %s", strerror(-r));
+        return r;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_NO_PAGER,
+                ARG_NO_LEGEND,
+        };
+
+        int r, c;
+
+        static const struct option options[] = {
+                { "help",         no_argument,       NULL, 'h'           },
+                { "version" ,     no_argument,       NULL, ARG_VERSION   },
+                { "no-pager",     no_argument,       NULL, ARG_NO_PAGER  },
+                { "no-legend",    no_argument,       NULL, ARG_NO_LEGEND },
+                { "output",       required_argument, NULL, 'o'           },
+                { "field",        required_argument, NULL, 'F'           },
+                { NULL,           0,                 NULL, 0             }
+        };
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "ho:F:", options, NULL)) >= 0)
+                switch(c) {
+                case 'h':
+                        help();
+                        arg_action = ACTION_NONE;
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        arg_action = ACTION_NONE;
+                        return 0;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case ARG_NO_LEGEND:
+                        arg_no_legend = true;
+                        break;
+
+                case 'o':
+                        if (output) {
+                                log_error("cannot set output more than once");
+                                return -EINVAL;
+                        }
+
+                        output = fopen(optarg, "we");
+                        if (!output) {
+                                log_error("writing to '%s': %m", optarg);
+                                return -errno;
+                        }
+
+                        break;
+
+                case 'F':
+                        if (field) {
+                                log_error("cannot use --field/-F more than once");
+                                return -EINVAL;
+                        }
+
+                        field = optarg;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+
+        if (optind < argc) {
+                const char *cmd = argv[optind++];
+                if(streq(cmd, "list"))
+                        arg_action = ACTION_LIST;
+                else if (streq(cmd, "dump"))
+                        arg_action = ACTION_DUMP;
+                else if (streq(cmd, "gdb"))
+                        arg_action = ACTION_GDB;
+                else {
+                        log_error("Unknown action '%s'", cmd);
+                        return -EINVAL;
+                }
+        }
+
+        if (field && arg_action != ACTION_LIST) {
+                log_error("Option --field/-F only makes sense with list");
+                return -EINVAL;
+        }
+
+        while (optind < argc) {
+                r = add_match(matches, argv[optind]);
+                if (r != 0)
+                        return r;
+                optind++;
+        }
+
+        return 0;
+}
+
+static int retrieve(const void *data,
+                    size_t len,
+                    const char *name,
+                    const char **var) {
+
+        size_t ident;
+
+        ident = strlen(name) + 1; /* name + "=" */
+
+        if (len < ident)
+                return 0;
+
+        if (memcmp(data, name, ident - 1) != 0)
+                return 0;
+
+        if (((const char*) data)[ident - 1] != '=')
+                return 0;
+
+        *var = strndup((const char*)data + ident, len - ident);
+        if (!*var)
+                return log_oom();
+
+        return 0;
+}
+
+static void print_field(FILE* file, sd_journal *j) {
+        const char _cleanup_free_ *value = NULL;
+        const void *d;
+        size_t l;
+
+        assert(field);
+
+        SD_JOURNAL_FOREACH_DATA(j, d, l)
+                retrieve(d, l, field, &value);
+        if (value)
+                fprintf(file, "%s\n", value);
+}
+
+static int print_entry(FILE* file, sd_journal *j, int had_legend) {
+        const char _cleanup_free_
+                *pid = NULL, *uid = NULL, *gid = NULL,
+                *sgnl = NULL, *exe = NULL;
+        const void *d;
+        size_t l;
+        usec_t t;
+        char buf[FORMAT_TIMESTAMP_MAX];
+        int r;
+
+        SD_JOURNAL_FOREACH_DATA(j, d, l) {
+                retrieve(d, l, "COREDUMP_PID", &pid);
+                retrieve(d, l, "COREDUMP_PID", &pid);
+                retrieve(d, l, "COREDUMP_UID", &uid);
+                retrieve(d, l, "COREDUMP_GID", &gid);
+                retrieve(d, l, "COREDUMP_SIGNAL", &sgnl);
+                retrieve(d, l, "COREDUMP_EXE", &exe);
+                if (!exe)
+                        retrieve(d, l, "COREDUMP_COMM", &exe);
+                if (!exe)
+                        retrieve(d, l, "COREDUMP_CMDLINE", &exe);
+        }
+
+        if (!pid && !uid && !gid && !sgnl && !exe) {
+                log_warning("Empty coredump log entry");
+                return -EINVAL;
+        }
+
+        r = sd_journal_get_realtime_usec(j, &t);
+        if (r < 0) {
+                log_error("Failed to get realtime timestamp: %s", strerror(-r));
+                return r;
+        }
+
+        format_timestamp(buf, sizeof(buf), t);
+
+        if (!had_legend && !arg_no_legend)
+                fprintf(file, "%-*s %*s %*s %*s %*s %s\n",
+                        FORMAT_TIMESTAMP_MAX-1, "TIME",
+                        6, "PID",
+                        5, "UID",
+                        5, "GID",
+                        3, "SIG",
+                           "EXE");
+
+        fprintf(file, "%*s %*s %*s %*s %*s %s\n",
+                FORMAT_TIMESTAMP_MAX-1, buf,
+                6, pid,
+                5, uid,
+                5, gid,
+                3, sgnl,
+                exe);
+
+        return 0;
+}
+
+static int dump_list(sd_journal *j) {
+        int found = 0;
+
+        assert(j);
+
+        /* The coredumps are likely to compressed, and for just
+         * listing them we don#t need to decompress them, so let's
+         * pick a fairly low data threshold here */
+        sd_journal_set_data_threshold(j, 4096);
+
+        SD_JOURNAL_FOREACH(j) {
+                if (field)
+                        print_field(stdout, j);
+                else
+                        print_entry(stdout, j, found++);
+        }
+
+        if (!field && !found) {
+                log_notice("No coredumps found");
+                return -ESRCH;
+        }
+
+        return 0;
+}
+
+static int focus(sd_journal *j) {
+        int r;
+
+        r = sd_journal_seek_tail(j);
+        if (r == 0)
+                r = sd_journal_previous(j);
+        if (r < 0) {
+                log_error("Failed to search journal: %s", strerror(-r));
+                return r;
+        }
+        if (r == 0) {
+                log_error("No match found");
+                return -ESRCH;
+        }
+        return r;
+}
+
+static int dump_core(sd_journal* j) {
+        const void *data;
+        size_t len, ret;
+        int r;
+
+        assert(j);
+
+        /* We want full data, nothing truncated. */
+        sd_journal_set_data_threshold(j, 0);
+
+        r = focus(j);
+        if (r < 0)
+                return r;
+
+        print_entry(output ? stdout : stderr, j, false);
+
+        if (on_tty() && !output) {
+                log_error("Refusing to dump core to tty");
+                return -ENOTTY;
+        }
+
+        r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len);
+        if (r < 0) {
+                log_error("Failed to retrieve COREDUMP field: %s", strerror(-r));
+                return r;
+        }
+
+        assert(len >= 9);
+        data = (const uint8_t*) data + 9;
+        len -= 9;
+
+        ret = fwrite(data, len, 1, output ? output : stdout);
+        if (ret != 1) {
+                log_error("dumping coredump: %m (%zu)", ret);
+                return -errno;
+        }
+
+        r = sd_journal_previous(j);
+        if (r >= 0)
+                log_warning("More than one entry matches, ignoring rest.\n");
+
+        return 0;
+}
+
+static int run_gdb(sd_journal *j) {
+        char path[] = "/var/tmp/coredump-XXXXXX";
+        const void *data;
+        size_t len;
+        ssize_t sz;
+        pid_t pid;
+        _cleanup_free_ char *exe = NULL;
+        int r;
+        _cleanup_close_ int fd = -1;
+        siginfo_t st;
+
+        assert(j);
+
+        sd_journal_set_data_threshold(j, 0);
+
+        r = focus(j);
+        if (r < 0)
+                return r;
+
+        print_entry(stdout, j, false);
+
+        r = sd_journal_get_data(j, "COREDUMP_EXE", (const void**) &data, &len);
+        if (r < 0) {
+                log_error("Failed to retrieve COREDUMP_EXE field: %s", strerror(-r));
+                return r;
+        }
+
+        assert(len >= 13);
+        data = (const uint8_t*) data + 13;
+        len -= 13;
+
+        exe = strndup(data, len);
+        if (!exe)
+                return log_oom();
+
+        if (endswith(exe, " (deleted)")) {
+                log_error("Binary already deleted.");
+                return -ENOENT;
+        }
+
+        r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len);
+        if (r < 0) {
+                log_error("Failed to retrieve COREDUMP field: %s", strerror(-r));
+                return r;
+        }
+
+        assert(len >= 9);
+        data = (const uint8_t*) data + 9;
+        len -= 9;
+
+        fd = mkostemp(path, O_WRONLY);
+        if (fd < 0) {
+                log_error("Failed to create temporary file: %m");
+                return -errno;
+        }
+
+        sz = write(fd, data, len);
+        if (sz < 0) {
+                log_error("Failed to write temporary file: %s", strerror(errno));
+                r = -errno;
+                goto finish;
+        }
+        if (sz != (ssize_t) len) {
+                log_error("Short write to temporary file.");
+                r = -EIO;
+                goto finish;
+        }
+
+        close_nointr_nofail(fd);
+        fd = -1;
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("Failed to fork(): %m");
+                r = -errno;
+                goto finish;
+        }
+        if (pid == 0) {
+                execlp("gdb", "gdb", exe, path, NULL);
+                log_error("Failed to invoke gdb: %m");
+                _exit(1);
+        }
+
+        r = wait_for_terminate(pid, &st);
+        if (r < 0) {
+                log_error("Failed to wait for gdb: %m");
+                goto finish;
+        }
+
+        r = st.si_code == CLD_EXITED ? st.si_status : 255;
+
+finish:
+        unlink(path);
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        sd_journal *j = NULL;
+        const char* match;
+        Iterator it;
+        int r = 0;
+
+        setlocale(LC_ALL, "");
+        log_parse_environment();
+        log_open();
+
+        matches = new_matches();
+        if (!matches) {
+                r = -ENOMEM;
+                goto end;
+        }
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                goto end;
+
+        if (arg_action == ACTION_NONE)
+                goto end;
+
+        r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
+        if (r < 0) {
+                log_error("Failed to open journal: %s", strerror(-r));
+                goto end;
+        }
+
+        SET_FOREACH(match, matches, it) {
+                r = sd_journal_add_match(j, match, strlen(match));
+                if (r != 0) {
+                        log_error("Failed to add match '%s': %s",
+                                  match, strerror(-r));
+                        goto end;
+                }
+        }
+
+        switch(arg_action) {
+
+        case ACTION_LIST:
+                if (!arg_no_pager)
+                        pager_open();
+
+                r = dump_list(j);
+                break;
+
+        case ACTION_DUMP:
+                r = dump_core(j);
+                break;
+
+        case  ACTION_GDB:
+                r = run_gdb(j);
+                break;
+
+        default:
+                assert_not_reached("Shouldn't be here");
+        }
+
+end:
+        if (j)
+                sd_journal_close(j);
+
+        set_free_free(matches);
+
+        pager_close();
+
+        if (output)
+                fclose(output);
+
+        return r >= 0 ? r : EXIT_FAILURE;
+}
diff --git a/src/journal/fsprg.c b/src/journal/fsprg.c
new file mode 100644 (file)
index 0000000..2190b7c
--- /dev/null
@@ -0,0 +1,384 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * fsprg v0.1  -  (seekable) forward-secure pseudorandom generator
+ * Copyright (C) 2012 B. Poettering
+ * Contact: fsprg@point-at-infinity.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ *
+ */
+
+#include <gcrypt.h>
+#include <string.h>
+#include <assert.h>
+
+#include "fsprg.h"
+
+#define ISVALID_SECPAR(secpar) (((secpar) % 16 == 0) && ((secpar) >= 16) && ((secpar) <= 16384))
+#define VALIDATE_SECPAR(secpar) assert(ISVALID_SECPAR(secpar));
+
+#define RND_HASH GCRY_MD_SHA256
+#define RND_GEN_P 0x01
+#define RND_GEN_Q 0x02
+#define RND_GEN_X 0x03
+
+/******************************************************************************/
+
+static void mpi_export(void *buf, size_t buflen, const gcry_mpi_t x) {
+        unsigned len;
+        size_t nwritten;
+
+        assert(gcry_mpi_cmp_ui(x, 0) >= 0);
+        len = (gcry_mpi_get_nbits(x) + 7) / 8;
+        assert(len <= buflen);
+        memset(buf, 0, buflen);
+        gcry_mpi_print(GCRYMPI_FMT_USG, buf + (buflen - len), len, &nwritten, x);
+        assert(nwritten == len);
+}
+
+static gcry_mpi_t mpi_import(const void *buf, size_t buflen) {
+        gcry_mpi_t h;
+        unsigned len;
+
+        gcry_mpi_scan(&h, GCRYMPI_FMT_USG, buf, buflen, NULL);
+        len = (gcry_mpi_get_nbits(h) + 7) / 8;
+        assert(len <= buflen);
+        assert(gcry_mpi_cmp_ui(h, 0) >= 0);
+
+        return h;
+}
+
+static void uint64_export(void *buf, size_t buflen, uint64_t x) {
+        assert(buflen == 8);
+        ((uint8_t*) buf)[0] = (x >> 56) & 0xff;
+        ((uint8_t*) buf)[1] = (x >> 48) & 0xff;
+        ((uint8_t*) buf)[2] = (x >> 40) & 0xff;
+        ((uint8_t*) buf)[3] = (x >> 32) & 0xff;
+        ((uint8_t*) buf)[4] = (x >> 24) & 0xff;
+        ((uint8_t*) buf)[5] = (x >> 16) & 0xff;
+        ((uint8_t*) buf)[6] = (x >>  8) & 0xff;
+        ((uint8_t*) buf)[7] = (x >>  0) & 0xff;
+}
+
+static uint64_t uint64_import(const void *buf, size_t buflen) {
+        assert(buflen == 8);
+        return
+                (uint64_t)(((uint8_t*) buf)[0]) << 56 |
+                (uint64_t)(((uint8_t*) buf)[1]) << 48 |
+                (uint64_t)(((uint8_t*) buf)[2]) << 40 |
+                (uint64_t)(((uint8_t*) buf)[3]) << 32 |
+                (uint64_t)(((uint8_t*) buf)[4]) << 24 |
+                (uint64_t)(((uint8_t*) buf)[5]) << 16 |
+                (uint64_t)(((uint8_t*) buf)[6]) <<  8 |
+                (uint64_t)(((uint8_t*) buf)[7]) <<  0;
+}
+
+/* deterministically generate from seed/idx a string of buflen pseudorandom bytes */
+static void det_randomize(void *buf, size_t buflen, const void *seed, size_t seedlen, uint32_t idx) {
+        gcry_md_hd_t hd, hd2;
+        size_t olen, cpylen;
+        uint32_t ctr;
+
+        olen = gcry_md_get_algo_dlen(RND_HASH);
+        gcry_md_open(&hd, RND_HASH, 0);
+        gcry_md_write(hd, seed, seedlen);
+        gcry_md_putc(hd, (idx >> 24) & 0xff);
+        gcry_md_putc(hd, (idx >> 16) & 0xff);
+        gcry_md_putc(hd, (idx >>  8) & 0xff);
+        gcry_md_putc(hd, (idx >>  0) & 0xff);
+
+        for (ctr = 0; buflen; ctr++) {
+                gcry_md_copy(&hd2, hd);
+                gcry_md_putc(hd2, (ctr >> 24) & 0xff);
+                gcry_md_putc(hd2, (ctr >> 16) & 0xff);
+                gcry_md_putc(hd2, (ctr >>  8) & 0xff);
+                gcry_md_putc(hd2, (ctr >>  0) & 0xff);
+                gcry_md_final(hd2);
+                cpylen = (buflen < olen) ? buflen : olen;
+                memcpy(buf, gcry_md_read(hd2, RND_HASH), cpylen);
+                gcry_md_close(hd2);
+                buf += cpylen;
+                buflen -= cpylen;
+        }
+        gcry_md_close(hd);
+}
+
+/* deterministically generate from seed/idx a prime of length `bits' that is 3 (mod 4) */
+static gcry_mpi_t genprime3mod4(int bits, const void *seed, size_t seedlen, uint32_t idx) {
+        size_t buflen = bits / 8;
+        uint8_t buf[buflen];
+        gcry_mpi_t p;
+
+        assert(bits % 8 == 0);
+        assert(buflen > 0);
+
+        det_randomize(buf, buflen, seed, seedlen, idx);
+        buf[0] |= 0xc0; /* set upper two bits, so that n=pq has maximum size */
+        buf[buflen - 1] |= 0x03; /* set lower two bits, to have result 3 (mod 4) */
+
+        p = mpi_import(buf, buflen);
+        while (gcry_prime_check(p, 0))
+                gcry_mpi_add_ui(p, p, 4);
+
+        return p;
+}
+
+/* deterministically generate from seed/idx a quadratic residue (mod n) */
+static gcry_mpi_t gensquare(const gcry_mpi_t n, const void *seed, size_t seedlen, uint32_t idx, unsigned secpar) {
+        size_t buflen = secpar / 8;
+        uint8_t buf[buflen];
+        gcry_mpi_t x;
+
+        det_randomize(buf, buflen, seed, seedlen, idx);
+        buf[0] &= 0x7f; /* clear upper bit, so that we have x < n */
+        x = mpi_import(buf, buflen);
+        assert(gcry_mpi_cmp(x, n) < 0);
+        gcry_mpi_mulm(x, x, x, n);
+        return x;
+}
+
+/* compute 2^m (mod phi(p)), for a prime p */
+static gcry_mpi_t twopowmodphi(uint64_t m, const gcry_mpi_t p) {
+        gcry_mpi_t phi, r;
+        int n;
+
+        phi = gcry_mpi_new(0);
+        gcry_mpi_sub_ui(phi, p, 1);
+
+        /* count number of used bits in m */
+        for (n = 0; (1ULL << n) <= m; n++)
+                ;
+
+        r = gcry_mpi_new(0);
+        gcry_mpi_set_ui(r, 1);
+        while (n) { /* square and multiply algorithm for fast exponentiation */
+                n--;
+                gcry_mpi_mulm(r, r, r, phi);
+                if (m & ((uint64_t)1 << n)) {
+                        gcry_mpi_add(r, r, r);
+                        if (gcry_mpi_cmp(r, phi) >= 0)
+                                gcry_mpi_sub(r, r, phi);
+                }
+        }
+
+        gcry_mpi_release(phi);
+        return r;
+}
+
+/* Decompose $x \in Z_n$ into $(xp,xq) \in Z_p \times Z_q$ using Chinese Remainder Theorem */
+static void CRT_decompose(gcry_mpi_t *xp, gcry_mpi_t *xq, const gcry_mpi_t x, const gcry_mpi_t p, const gcry_mpi_t q) {
+        *xp = gcry_mpi_new(0);
+        *xq = gcry_mpi_new(0);
+        gcry_mpi_mod(*xp, x, p);
+        gcry_mpi_mod(*xq, x, q);
+}
+
+/* Compose $(xp,xq) \in Z_p \times Z_q$ into $x \in Z_n$ using Chinese Remainder Theorem */
+static void CRT_compose(gcry_mpi_t *x, const gcry_mpi_t xp, const gcry_mpi_t xq, const gcry_mpi_t p, const gcry_mpi_t q) {
+        gcry_mpi_t a, u;
+
+        a = gcry_mpi_new(0);
+        u = gcry_mpi_new(0);
+        *x = gcry_mpi_new(0);
+        gcry_mpi_subm(a, xq, xp, q);
+        gcry_mpi_invm(u, p, q);
+        gcry_mpi_mulm(a, a, u, q); /* a = (xq - xp) / p  (mod q) */
+        gcry_mpi_mul(*x, p, a);
+        gcry_mpi_add(*x, *x, xp); /* x = p * ((xq - xp) / p mod q) + xp */
+        gcry_mpi_release(a);
+        gcry_mpi_release(u);
+}
+
+static void initialize_libgcrypt(void) {
+        const char *p;
+        if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
+                return;
+
+        p = gcry_check_version("1.4.5");
+        assert(p);
+
+        /* Turn off "secmem". Clients which whish to make use of this
+         * feature should initialize the library manually */
+        gcry_control(GCRYCTL_DISABLE_SECMEM);
+        gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+}
+
+/******************************************************************************/
+
+size_t FSPRG_mskinbytes(unsigned _secpar) {
+        VALIDATE_SECPAR(_secpar);
+        return 2 + 2 * (_secpar / 2) / 8; /* to store header,p,q */
+}
+
+size_t FSPRG_mpkinbytes(unsigned _secpar) {
+        VALIDATE_SECPAR(_secpar);
+        return 2 + _secpar / 8; /* to store header,n */
+}
+
+size_t FSPRG_stateinbytes(unsigned _secpar) {
+        VALIDATE_SECPAR(_secpar);
+        return 2 + 2 * _secpar / 8 + 8; /* to store header,n,x,epoch */
+}
+
+static void store_secpar(void *buf, uint16_t secpar) {
+        secpar = secpar / 16 - 1;
+        ((uint8_t*) buf)[0] = (secpar >> 8) & 0xff;
+        ((uint8_t*) buf)[1] = (secpar >> 0) & 0xff;
+}
+
+static uint16_t read_secpar(const void *buf) {
+        uint16_t secpar;
+        secpar =
+                (uint16_t)(((uint8_t*) buf)[0]) << 8 |
+                (uint16_t)(((uint8_t*) buf)[1]) << 0;
+        return 16 * (secpar + 1);
+}
+
+void FSPRG_GenMK(void *msk, void *mpk, const void *seed, size_t seedlen, unsigned _secpar) {
+        uint8_t iseed[FSPRG_RECOMMENDED_SEEDLEN];
+        gcry_mpi_t n, p, q;
+        uint16_t secpar;
+
+        VALIDATE_SECPAR(_secpar);
+        secpar = _secpar;
+
+        initialize_libgcrypt();
+
+        if (!seed) {
+                gcry_randomize(iseed, FSPRG_RECOMMENDED_SEEDLEN, GCRY_STRONG_RANDOM);
+                seed = iseed;
+                seedlen = FSPRG_RECOMMENDED_SEEDLEN;
+        }
+
+        p = genprime3mod4(secpar / 2, seed, seedlen, RND_GEN_P);
+        q = genprime3mod4(secpar / 2, seed, seedlen, RND_GEN_Q);
+
+        if (msk) {
+                store_secpar(msk + 0, secpar);
+                mpi_export(msk + 2 + 0 * (secpar / 2) / 8, (secpar / 2) / 8, p);
+                mpi_export(msk + 2 + 1 * (secpar / 2) / 8, (secpar / 2) / 8, q);
+        }
+
+        if (mpk) {
+                n = gcry_mpi_new(0);
+                gcry_mpi_mul(n, p, q);
+                assert(gcry_mpi_get_nbits(n) == secpar);
+
+                store_secpar(mpk + 0, secpar);
+                mpi_export(mpk + 2, secpar / 8, n);
+
+                gcry_mpi_release(n);
+        }
+
+        gcry_mpi_release(p);
+        gcry_mpi_release(q);
+}
+
+void FSPRG_GenState0(void *state, const void *mpk, const void *seed, size_t seedlen) {
+        gcry_mpi_t n, x;
+        uint16_t secpar;
+
+        initialize_libgcrypt();
+
+        secpar = read_secpar(mpk + 0);
+        n = mpi_import(mpk + 2, secpar / 8);
+        x = gensquare(n, seed, seedlen, RND_GEN_X, secpar);
+
+        memcpy(state, mpk, 2 + secpar / 8);
+        mpi_export(state + 2 + 1 * secpar / 8, secpar / 8, x);
+        memset(state + 2 + 2 * secpar / 8, 0, 8);
+
+        gcry_mpi_release(n);
+        gcry_mpi_release(x);
+}
+
+void FSPRG_Evolve(void *state) {
+        gcry_mpi_t n, x;
+        uint16_t secpar;
+        uint64_t epoch;
+
+        initialize_libgcrypt();
+
+        secpar = read_secpar(state + 0);
+        n = mpi_import(state + 2 + 0 * secpar / 8, secpar / 8);
+        x = mpi_import(state + 2 + 1 * secpar / 8, secpar / 8);
+        epoch = uint64_import(state + 2 + 2 * secpar / 8, 8);
+
+        gcry_mpi_mulm(x, x, x, n);
+        epoch++;
+
+        mpi_export(state + 2 + 1 * secpar / 8, secpar / 8, x);
+        uint64_export(state + 2 + 2 * secpar / 8, 8, epoch);
+
+        gcry_mpi_release(n);
+        gcry_mpi_release(x);
+}
+
+uint64_t FSPRG_GetEpoch(const void *state) {
+        uint16_t secpar;
+        secpar = read_secpar(state + 0);
+        return uint64_import(state + 2 + 2 * secpar / 8, 8);
+}
+
+void FSPRG_Seek(void *state, uint64_t epoch, const void *msk, const void *seed, size_t seedlen) {
+        gcry_mpi_t p, q, n, x, xp, xq, kp, kq, xm;
+        uint16_t secpar;
+
+        initialize_libgcrypt();
+
+        secpar = read_secpar(msk + 0);
+        p  = mpi_import(msk + 2 + 0 * (secpar / 2) / 8, (secpar / 2) / 8);
+        q  = mpi_import(msk + 2 + 1 * (secpar / 2) / 8, (secpar / 2) / 8);
+
+        n = gcry_mpi_new(0);
+        gcry_mpi_mul(n, p, q);
+
+        x = gensquare(n, seed, seedlen, RND_GEN_X, secpar);
+        CRT_decompose(&xp, &xq, x, p, q); /* split (mod n) into (mod p) and (mod q) using CRT */
+
+        kp = twopowmodphi(epoch, p); /* compute 2^epoch (mod phi(p)) */
+        kq = twopowmodphi(epoch, q); /* compute 2^epoch (mod phi(q)) */
+
+        gcry_mpi_powm(xp, xp, kp, p); /* compute x^(2^epoch) (mod p) */
+        gcry_mpi_powm(xq, xq, kq, q); /* compute x^(2^epoch) (mod q) */
+
+        CRT_compose(&xm, xp, xq, p, q); /* combine (mod p) and (mod q) to (mod n) using CRT */
+
+        store_secpar(state + 0, secpar);
+        mpi_export(state + 2 + 0 * secpar / 8, secpar / 8, n);
+        mpi_export(state + 2 + 1 * secpar / 8, secpar / 8, xm);
+        uint64_export(state + 2 + 2 * secpar / 8, 8, epoch);
+
+        gcry_mpi_release(p);
+        gcry_mpi_release(q);
+        gcry_mpi_release(n);
+        gcry_mpi_release(x);
+        gcry_mpi_release(xp);
+        gcry_mpi_release(xq);
+        gcry_mpi_release(kp);
+        gcry_mpi_release(kq);
+        gcry_mpi_release(xm);
+}
+
+void FSPRG_GetKey(const void *state, void *key, size_t keylen, uint32_t idx) {
+        uint16_t secpar;
+
+        initialize_libgcrypt();
+
+        secpar = read_secpar(state + 0);
+        det_randomize(key, keylen, state + 2, 2 * secpar / 8 + 8, idx);
+}
diff --git a/src/journal/fsprg.h b/src/journal/fsprg.h
new file mode 100644 (file)
index 0000000..306ef18
--- /dev/null
@@ -0,0 +1,64 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef __fsprgh__
+#define __fsprgh__
+
+/*
+ * fsprg v0.1  -  (seekable) forward-secure pseudorandom generator
+ * Copyright (C) 2012 B. Poettering
+ * Contact: fsprg@point-at-infinity.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ *
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FSPRG_RECOMMENDED_SECPAR 1536
+#define FSPRG_RECOMMENDED_SEEDLEN (96/8)
+
+size_t FSPRG_mskinbytes(unsigned secpar);
+size_t FSPRG_mpkinbytes(unsigned secpar);
+size_t FSPRG_stateinbytes(unsigned secpar);
+
+/* Setup msk and mpk. Providing seed != NULL makes this algorithm deterministic. */
+void FSPRG_GenMK(void *msk, void *mpk, const void *seed, size_t seedlen, unsigned secpar);
+
+/* Initialize state deterministically in dependence on seed. */
+/* Note: in case one wants to run only one GenState0 per GenMK it is safe to use
+   the same seed for both GenMK and GenState0.
+*/
+void FSPRG_GenState0(void *state, const void *mpk, const void *seed, size_t seedlen);
+
+void FSPRG_Evolve(void *state);
+
+uint64_t FSPRG_GetEpoch(const void *state);
+
+/* Seek to any arbitrary state (by providing msk together with seed from GenState0). */
+void FSPRG_Seek(void *state, uint64_t epoch, const void *msk, const void *seed, size_t seedlen);
+
+void FSPRG_GetKey(const void *state, void *key, size_t keylen, uint32_t idx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c
new file mode 100644 (file)
index 0000000..64bf968
--- /dev/null
@@ -0,0 +1,563 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "journal-def.h"
+#include "journal-file.h"
+#include "journal-authenticate.h"
+#include "fsprg.h"
+
+static uint64_t journal_file_tag_seqnum(JournalFile *f) {
+        uint64_t r;
+
+        assert(f);
+
+        r = le64toh(f->header->n_tags) + 1;
+        f->header->n_tags = htole64(r);
+
+        return r;
+}
+
+int journal_file_append_tag(JournalFile *f) {
+        Object *o;
+        uint64_t p;
+        int r;
+
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        if (!f->hmac_running)
+                return 0;
+
+        assert(f->hmac);
+
+        r = journal_file_append_object(f, OBJECT_TAG, sizeof(struct TagObject), &o, &p);
+        if (r < 0)
+                return r;
+
+        o->tag.seqnum = htole64(journal_file_tag_seqnum(f));
+        o->tag.epoch = htole64(FSPRG_GetEpoch(f->fsprg_state));
+
+        log_debug("Writing tag %llu for epoch %llu\n",
+                  (unsigned long long) le64toh(o->tag.seqnum),
+                  (unsigned long long) FSPRG_GetEpoch(f->fsprg_state));
+
+        /* Add the tag object itself, so that we can protect its
+         * header. This will exclude the actual hash value in it */
+        r = journal_file_hmac_put_object(f, OBJECT_TAG, o, p);
+        if (r < 0)
+                return r;
+
+        /* Get the HMAC tag and store it in the object */
+        memcpy(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH);
+        f->hmac_running = false;
+
+        return 0;
+}
+
+int journal_file_hmac_start(JournalFile *f) {
+        uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        if (f->hmac_running)
+                return 0;
+
+        /* Prepare HMAC for next cycle */
+        gcry_md_reset(f->hmac);
+        FSPRG_GetKey(f->fsprg_state, key, sizeof(key), 0);
+        gcry_md_setkey(f->hmac, key, sizeof(key));
+
+        f->hmac_running = true;
+
+        return 0;
+}
+
+static int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *epoch) {
+        uint64_t t;
+
+        assert(f);
+        assert(epoch);
+        assert(f->seal);
+
+        if (f->fss_start_usec == 0 ||
+            f->fss_interval_usec == 0)
+                return -ENOTSUP;
+
+        if (realtime < f->fss_start_usec)
+                return -ESTALE;
+
+        t = realtime - f->fss_start_usec;
+        t = t / f->fss_interval_usec;
+
+        *epoch = t;
+        return 0;
+}
+
+static int journal_file_fsprg_need_evolve(JournalFile *f, uint64_t realtime) {
+        uint64_t goal, epoch;
+        int r;
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        r = journal_file_get_epoch(f, realtime, &goal);
+        if (r < 0)
+                return r;
+
+        epoch = FSPRG_GetEpoch(f->fsprg_state);
+        if (epoch > goal)
+                return -ESTALE;
+
+        return epoch != goal;
+}
+
+int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) {
+        uint64_t goal, epoch;
+        int r;
+
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        r = journal_file_get_epoch(f, realtime, &goal);
+        if (r < 0)
+                return r;
+
+        epoch = FSPRG_GetEpoch(f->fsprg_state);
+        if (epoch < goal)
+                log_debug("Evolving FSPRG key from epoch %llu to %llu.", (unsigned long long) epoch, (unsigned long long) goal);
+
+        for (;;) {
+                if (epoch > goal)
+                        return -ESTALE;
+                if (epoch == goal)
+                        return 0;
+
+                FSPRG_Evolve(f->fsprg_state);
+                epoch = FSPRG_GetEpoch(f->fsprg_state);
+        }
+}
+
+int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) {
+        void *msk;
+        uint64_t epoch;
+
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        assert(f->fsprg_seed);
+
+        if (f->fsprg_state) {
+                /* Cheaper... */
+
+                epoch = FSPRG_GetEpoch(f->fsprg_state);
+                if (goal == epoch)
+                        return 0;
+
+                if (goal == epoch+1) {
+                        FSPRG_Evolve(f->fsprg_state);
+                        return 0;
+                }
+        } else {
+                f->fsprg_state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
+                f->fsprg_state = malloc(f->fsprg_state_size);
+
+                if (!f->fsprg_state)
+                        return -ENOMEM;
+        }
+
+        log_debug("Seeking FSPRG key to %llu.", (unsigned long long) goal);
+
+        msk = alloca(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR));
+        FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR);
+        FSPRG_Seek(f->fsprg_state, goal, msk, f->fsprg_seed, f->fsprg_seed_size);
+        return 0;
+}
+
+int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
+        int r;
+
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        if (realtime <= 0)
+                realtime = now(CLOCK_REALTIME);
+
+        r = journal_file_fsprg_need_evolve(f, realtime);
+        if (r <= 0)
+                return 0;
+
+        r = journal_file_append_tag(f);
+        if (r < 0)
+                return r;
+
+        r = journal_file_fsprg_evolve(f, realtime);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int journal_file_hmac_put_object(JournalFile *f, int type, Object *o, uint64_t p) {
+        int r;
+
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        r = journal_file_hmac_start(f);
+        if (r < 0)
+                return r;
+
+        if (!o) {
+                r = journal_file_move_to_object(f, type, p, &o);
+                if (r < 0)
+                        return r;
+        } else {
+                if (type >= 0 && o->object.type != type)
+                        return -EBADMSG;
+        }
+
+        gcry_md_write(f->hmac, o, offsetof(ObjectHeader, payload));
+
+        switch (o->object.type) {
+
+        case OBJECT_DATA:
+                /* All but hash and payload are mutable */
+                gcry_md_write(f->hmac, &o->data.hash, sizeof(o->data.hash));
+                gcry_md_write(f->hmac, o->data.payload, le64toh(o->object.size) - offsetof(DataObject, payload));
+                break;
+
+        case OBJECT_FIELD:
+                /* Same here */
+                gcry_md_write(f->hmac, &o->field.hash, sizeof(o->field.hash));
+                gcry_md_write(f->hmac, o->field.payload, le64toh(o->object.size) - offsetof(FieldObject, payload));
+                break;
+
+        case OBJECT_ENTRY:
+                /* All */
+                gcry_md_write(f->hmac, &o->entry.seqnum, le64toh(o->object.size) - offsetof(EntryObject, seqnum));
+                break;
+
+        case OBJECT_FIELD_HASH_TABLE:
+        case OBJECT_DATA_HASH_TABLE:
+        case OBJECT_ENTRY_ARRAY:
+                /* Nothing: everything is mutable */
+                break;
+
+        case OBJECT_TAG:
+                /* All but the tag itself */
+                gcry_md_write(f->hmac, &o->tag.seqnum, sizeof(o->tag.seqnum));
+                gcry_md_write(f->hmac, &o->tag.epoch, sizeof(o->tag.epoch));
+                break;
+        default:
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+int journal_file_hmac_put_header(JournalFile *f) {
+        int r;
+
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        r = journal_file_hmac_start(f);
+        if (r < 0)
+                return r;
+
+        /* All but state+reserved, boot_id, arena_size,
+         * tail_object_offset, n_objects, n_entries,
+         * tail_entry_seqnum, head_entry_seqnum, entry_array_offset,
+         * head_entry_realtime, tail_entry_realtime,
+         * tail_entry_monotonic, n_data, n_fields, n_tags,
+         * n_entry_arrays. */
+
+        gcry_md_write(f->hmac, f->header->signature, offsetof(Header, state) - offsetof(Header, signature));
+        gcry_md_write(f->hmac, &f->header->file_id, offsetof(Header, boot_id) - offsetof(Header, file_id));
+        gcry_md_write(f->hmac, &f->header->seqnum_id, offsetof(Header, arena_size) - offsetof(Header, seqnum_id));
+        gcry_md_write(f->hmac, &f->header->data_hash_table_offset, offsetof(Header, tail_object_offset) - offsetof(Header, data_hash_table_offset));
+
+        return 0;
+}
+
+int journal_file_fss_load(JournalFile *f) {
+        int r, fd = -1;
+        char *p = NULL;
+        struct stat st;
+        FSSHeader *m = NULL;
+        sd_id128_t machine;
+
+        assert(f);
+
+        if (!f->seal)
+                return 0;
+
+        r = sd_id128_get_machine(&machine);
+        if (r < 0)
+                return r;
+
+        if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
+                     SD_ID128_FORMAT_VAL(machine)) < 0)
+                return -ENOMEM;
+
+        fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY, 0600);
+        if (fd < 0) {
+                if (errno != ENOENT)
+                        log_error("Failed to open %s: %m", p);
+
+                r = -errno;
+                goto finish;
+        }
+
+        if (fstat(fd, &st) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (st.st_size < (off_t) sizeof(FSSHeader)) {
+                r = -ENODATA;
+                goto finish;
+        }
+
+        m = mmap(NULL, PAGE_ALIGN(sizeof(FSSHeader)), PROT_READ, MAP_SHARED, fd, 0);
+        if (m == MAP_FAILED) {
+                m = NULL;
+                r = -errno;
+                goto finish;
+        }
+
+        if (memcmp(m->signature, FSS_HEADER_SIGNATURE, 8) != 0) {
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        if (m->incompatible_flags != 0) {
+                r = -EPROTONOSUPPORT;
+                goto finish;
+        }
+
+        if (le64toh(m->header_size) < sizeof(FSSHeader)) {
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        if (le64toh(m->fsprg_state_size) != FSPRG_stateinbytes(le16toh(m->fsprg_secpar))) {
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        f->fss_file_size = le64toh(m->header_size) + le64toh(m->fsprg_state_size);
+        if ((uint64_t) st.st_size < f->fss_file_size) {
+                r = -ENODATA;
+                goto finish;
+        }
+
+        if (!sd_id128_equal(machine, m->machine_id)) {
+                r = -EHOSTDOWN;
+                goto finish;
+        }
+
+        if (le64toh(m->start_usec) <= 0 ||
+            le64toh(m->interval_usec) <= 0) {
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+        if (f->fss_file == MAP_FAILED) {
+                f->fss_file = NULL;
+                r = -errno;
+                goto finish;
+        }
+
+        f->fss_start_usec = le64toh(f->fss_file->start_usec);
+        f->fss_interval_usec = le64toh(f->fss_file->interval_usec);
+
+        f->fsprg_state = (uint8_t*) f->fss_file + le64toh(f->fss_file->header_size);
+        f->fsprg_state_size = le64toh(f->fss_file->fsprg_state_size);
+
+        r = 0;
+
+finish:
+        if (m)
+                munmap(m, PAGE_ALIGN(sizeof(FSSHeader)));
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        free(p);
+        return r;
+}
+
+static void initialize_libgcrypt(void) {
+        const char *p;
+
+        if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
+                return;
+
+        p = gcry_check_version("1.4.5");
+        assert(p);
+
+        gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+}
+
+int journal_file_hmac_setup(JournalFile *f) {
+        gcry_error_t e;
+
+        if (!f->seal)
+                return 0;
+
+        initialize_libgcrypt();
+
+        e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
+        if (e != 0)
+                return -ENOTSUP;
+
+        return 0;
+}
+
+int journal_file_append_first_tag(JournalFile *f) {
+        int r;
+        uint64_t p;
+
+        if (!f->seal)
+                return 0;
+
+        log_debug("Calculating first tag...");
+
+        r = journal_file_hmac_put_header(f);
+        if (r < 0)
+                return r;
+
+        p = le64toh(f->header->field_hash_table_offset);
+        if (p < offsetof(Object, hash_table.items))
+                return -EINVAL;
+        p -= offsetof(Object, hash_table.items);
+
+        r = journal_file_hmac_put_object(f, OBJECT_FIELD_HASH_TABLE, NULL, p);
+        if (r < 0)
+                return r;
+
+        p = le64toh(f->header->data_hash_table_offset);
+        if (p < offsetof(Object, hash_table.items))
+                return -EINVAL;
+        p -= offsetof(Object, hash_table.items);
+
+        r = journal_file_hmac_put_object(f, OBJECT_DATA_HASH_TABLE, NULL, p);
+        if (r < 0)
+                return r;
+
+        r = journal_file_append_tag(f);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int journal_file_parse_verification_key(JournalFile *f, const char *key) {
+        uint8_t *seed;
+        size_t seed_size, c;
+        const char *k;
+        int r;
+        unsigned long long start, interval;
+
+        seed_size = FSPRG_RECOMMENDED_SEEDLEN;
+        seed = malloc(seed_size);
+        if (!seed)
+                return -ENOMEM;
+
+        k = key;
+        for (c = 0; c < seed_size; c++) {
+                int x, y;
+
+                while (*k == '-')
+                        k++;
+
+                x = unhexchar(*k);
+                if (x < 0) {
+                        free(seed);
+                        return -EINVAL;
+                }
+                k++;
+                y = unhexchar(*k);
+                if (y < 0) {
+                        free(seed);
+                        return -EINVAL;
+                }
+                k++;
+
+                seed[c] = (uint8_t) (x * 16 + y);
+        }
+
+        if (*k != '/') {
+                free(seed);
+                return -EINVAL;
+        }
+        k++;
+
+        r = sscanf(k, "%llx-%llx", &start, &interval);
+        if (r != 2) {
+                free(seed);
+                return -EINVAL;
+        }
+
+        f->fsprg_seed = seed;
+        f->fsprg_seed_size = seed_size;
+
+        f->fss_start_usec = start * interval;
+        f->fss_interval_usec = interval;
+
+        return 0;
+}
+
+bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) {
+        uint64_t epoch;
+
+        assert(f);
+        assert(u);
+
+        if (!f->seal)
+                return false;
+
+        epoch = FSPRG_GetEpoch(f->fsprg_state);
+
+        *u = (usec_t) (f->fss_start_usec + f->fss_interval_usec * epoch + f->fss_interval_usec);
+
+        return true;
+}
diff --git a/src/journal/journal-authenticate.h b/src/journal/journal-authenticate.h
new file mode 100644 (file)
index 0000000..0aaf836
--- /dev/null
@@ -0,0 +1,44 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include "journal-file.h"
+
+int journal_file_append_tag(JournalFile *f);
+int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime);
+int journal_file_append_first_tag(JournalFile *f);
+
+int journal_file_hmac_setup(JournalFile *f);
+int journal_file_hmac_start(JournalFile *f);
+int journal_file_hmac_put_header(JournalFile *f);
+int journal_file_hmac_put_object(JournalFile *f, int type, Object *o, uint64_t p);
+
+int journal_file_fss_load(JournalFile *f);
+int journal_file_parse_verification_key(JournalFile *f, const char *key);
+
+int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime);
+int journal_file_fsprg_seek(JournalFile *f, uint64_t epoch);
+
+bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u);
diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h
new file mode 100644 (file)
index 0000000..7e407a4
--- /dev/null
@@ -0,0 +1,216 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sparse-endian.h"
+
+#include <systemd/sd-id128.h>
+
+#include "macro.h"
+
+/*
+ * If you change this file you probably should also change its documentation:
+ *
+ * http://www.freedesktop.org/wiki/Software/systemd/journal-files
+ *
+ */
+
+typedef struct Header Header;
+
+typedef struct ObjectHeader ObjectHeader;
+typedef union Object Object;
+
+typedef struct DataObject DataObject;
+typedef struct FieldObject FieldObject;
+typedef struct EntryObject EntryObject;
+typedef struct HashTableObject HashTableObject;
+typedef struct EntryArrayObject EntryArrayObject;
+typedef struct TagObject TagObject;
+
+typedef struct EntryItem EntryItem;
+typedef struct HashItem HashItem;
+
+typedef struct FSSHeader FSSHeader;
+
+/* Object types */
+enum {
+        OBJECT_UNUSED,
+        OBJECT_DATA,
+        OBJECT_FIELD,
+        OBJECT_ENTRY,
+        OBJECT_DATA_HASH_TABLE,
+        OBJECT_FIELD_HASH_TABLE,
+        OBJECT_ENTRY_ARRAY,
+        OBJECT_TAG,
+        _OBJECT_TYPE_MAX
+};
+
+/* Object flags */
+enum {
+        OBJECT_COMPRESSED = 1
+};
+
+struct ObjectHeader {
+        uint8_t type;
+        uint8_t flags;
+        uint8_t reserved[6];
+        le64_t size;
+        uint8_t payload[];
+} _packed_;
+
+struct DataObject {
+        ObjectHeader object;
+        le64_t hash;
+        le64_t next_hash_offset;
+        le64_t next_field_offset;
+        le64_t entry_offset; /* the first array entry we store inline */
+        le64_t entry_array_offset;
+        le64_t n_entries;
+        uint8_t payload[];
+} _packed_;
+
+struct FieldObject {
+        ObjectHeader object;
+        le64_t hash;
+        le64_t next_hash_offset;
+        le64_t head_data_offset;
+        uint8_t payload[];
+} _packed_;
+
+struct EntryItem {
+        le64_t object_offset;
+        le64_t hash;
+} _packed_;
+
+struct EntryObject {
+        ObjectHeader object;
+        le64_t seqnum;
+        le64_t realtime;
+        le64_t monotonic;
+        sd_id128_t boot_id;
+        le64_t xor_hash;
+        EntryItem items[];
+} _packed_;
+
+struct HashItem {
+        le64_t head_hash_offset;
+        le64_t tail_hash_offset;
+} _packed_;
+
+struct HashTableObject {
+        ObjectHeader object;
+        HashItem items[];
+} _packed_;
+
+struct EntryArrayObject {
+        ObjectHeader object;
+        le64_t next_entry_array_offset;
+        le64_t items[];
+} _packed_;
+
+#define TAG_LENGTH (256/8)
+
+struct TagObject {
+        ObjectHeader object;
+        le64_t seqnum;
+        le64_t epoch;
+        uint8_t tag[TAG_LENGTH]; /* SHA-256 HMAC */
+} _packed_;
+
+union Object {
+        ObjectHeader object;
+        DataObject data;
+        FieldObject field;
+        EntryObject entry;
+        HashTableObject hash_table;
+        EntryArrayObject entry_array;
+        TagObject tag;
+};
+
+enum {
+        STATE_OFFLINE = 0,
+        STATE_ONLINE = 1,
+        STATE_ARCHIVED = 2,
+        _STATE_MAX
+};
+
+/* Header flags */
+enum {
+        HEADER_INCOMPATIBLE_COMPRESSED = 1
+};
+
+enum {
+        HEADER_COMPATIBLE_SEALED = 1
+};
+
+#define HEADER_SIGNATURE ((char[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' })
+
+struct Header {
+        uint8_t signature[8]; /* "LPKSHHRH" */
+        le32_t compatible_flags;
+        le32_t incompatible_flags;
+        uint8_t state;
+        uint8_t reserved[7];
+        sd_id128_t file_id;
+        sd_id128_t machine_id;
+        sd_id128_t boot_id;    /* last writer */
+        sd_id128_t seqnum_id;
+        le64_t header_size;
+        le64_t arena_size;
+        le64_t data_hash_table_offset;
+        le64_t data_hash_table_size;
+        le64_t field_hash_table_offset;
+        le64_t field_hash_table_size;
+        le64_t tail_object_offset;
+        le64_t n_objects;
+        le64_t n_entries;
+        le64_t tail_entry_seqnum;
+        le64_t head_entry_seqnum;
+        le64_t entry_array_offset;
+        le64_t head_entry_realtime;
+        le64_t tail_entry_realtime;
+        le64_t tail_entry_monotonic;
+        /* Added in 187 */
+        le64_t n_data;
+        le64_t n_fields;
+        /* Added in 189 */
+        le64_t n_tags;
+        le64_t n_entry_arrays;
+
+        /* Size: 224 */
+} _packed_;
+
+#define FSS_HEADER_SIGNATURE ((char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' })
+
+struct FSSHeader {
+        uint8_t signature[8]; /* "KSHHRHLP" */
+        le32_t compatible_flags;
+        le32_t incompatible_flags;
+        sd_id128_t machine_id;
+        sd_id128_t boot_id;    /* last writer */
+        le64_t header_size;
+        le64_t start_usec;
+        le64_t interval_usec;
+        le16_t fsprg_secpar;
+        le16_t reserved[3];
+        le64_t fsprg_state_size;
+} _packed_;
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
new file mode 100644 (file)
index 0000000..13fc8ed
--- /dev/null
@@ -0,0 +1,2871 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/mman.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <sys/statvfs.h>
+#include <fcntl.h>
+#include <stddef.h>
+
+#ifdef HAVE_XATTR
+#include <attr/xattr.h>
+#endif
+
+#include "journal-def.h"
+#include "journal-file.h"
+#include "journal-authenticate.h"
+#include "lookup3.h"
+#include "compress.h"
+#include "fsprg.h"
+
+#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
+#define DEFAULT_FIELD_HASH_TABLE_SIZE (333ULL*sizeof(HashItem))
+
+#define COMPRESSION_SIZE_THRESHOLD (512ULL)
+
+/* This is the minimum journal file size */
+#define JOURNAL_FILE_SIZE_MIN (64ULL*1024ULL)                  /* 64 KiB */
+
+/* These are the lower and upper bounds if we deduce the max_use value
+ * from the file system size */
+#define DEFAULT_MAX_USE_LOWER (1ULL*1024ULL*1024ULL)           /* 1 MiB */
+#define DEFAULT_MAX_USE_UPPER (4ULL*1024ULL*1024ULL*1024ULL)   /* 4 GiB */
+
+/* This is the upper bound if we deduce max_size from max_use */
+#define DEFAULT_MAX_SIZE_UPPER (128ULL*1024ULL*1024ULL)        /* 128 MiB */
+
+/* This is the upper bound if we deduce the keep_free value from the
+ * file system size */
+#define DEFAULT_KEEP_FREE_UPPER (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
+
+/* This is the keep_free value when we can't determine the system
+ * size */
+#define DEFAULT_KEEP_FREE (1024ULL*1024ULL)                    /* 1 MB */
+
+/* n_data was the first entry we added after the initial file format design */
+#define HEADER_SIZE_MIN ALIGN64(offsetof(Header, n_data))
+
+/* How many entries to keep in the entry array chain cache at max */
+#define CHAIN_CACHE_MAX 20
+
+void journal_file_close(JournalFile *f) {
+        assert(f);
+
+#ifdef HAVE_GCRYPT
+        /* Write the final tag */
+        if (f->seal && f->writable)
+                journal_file_append_tag(f);
+#endif
+
+        /* Sync everything to disk, before we mark the file offline */
+        if (f->mmap && f->fd >= 0)
+                mmap_cache_close_fd(f->mmap, f->fd);
+
+        if (f->writable && f->fd >= 0)
+                fdatasync(f->fd);
+
+        if (f->header) {
+                /* Mark the file offline. Don't override the archived state if it already is set */
+                if (f->writable && f->header->state == STATE_ONLINE)
+                        f->header->state = STATE_OFFLINE;
+
+                munmap(f->header, PAGE_ALIGN(sizeof(Header)));
+        }
+
+        if (f->fd >= 0)
+                close_nointr_nofail(f->fd);
+
+        free(f->path);
+
+        if (f->mmap)
+                mmap_cache_unref(f->mmap);
+
+        hashmap_free_free(f->chain_cache);
+
+#ifdef HAVE_XZ
+        free(f->compress_buffer);
+#endif
+
+#ifdef HAVE_GCRYPT
+        if (f->fss_file)
+                munmap(f->fss_file, PAGE_ALIGN(f->fss_file_size));
+        else if (f->fsprg_state)
+                free(f->fsprg_state);
+
+        free(f->fsprg_seed);
+
+        if (f->hmac)
+                gcry_md_close(f->hmac);
+#endif
+
+        free(f);
+}
+
+static int journal_file_init_header(JournalFile *f, JournalFile *template) {
+        Header h;
+        ssize_t k;
+        int r;
+
+        assert(f);
+
+        zero(h);
+        memcpy(h.signature, HEADER_SIGNATURE, 8);
+        h.header_size = htole64(ALIGN64(sizeof(h)));
+
+        h.incompatible_flags =
+                htole32(f->compress ? HEADER_INCOMPATIBLE_COMPRESSED : 0);
+
+        h.compatible_flags =
+                htole32(f->seal ? HEADER_COMPATIBLE_SEALED : 0);
+
+        r = sd_id128_randomize(&h.file_id);
+        if (r < 0)
+                return r;
+
+        if (template) {
+                h.seqnum_id = template->header->seqnum_id;
+                h.tail_entry_seqnum = template->header->tail_entry_seqnum;
+        } else
+                h.seqnum_id = h.file_id;
+
+        k = pwrite(f->fd, &h, sizeof(h), 0);
+        if (k < 0)
+                return -errno;
+
+        if (k != sizeof(h))
+                return -EIO;
+
+        return 0;
+}
+
+static int journal_file_refresh_header(JournalFile *f) {
+        int r;
+        sd_id128_t boot_id;
+
+        assert(f);
+
+        r = sd_id128_get_machine(&f->header->machine_id);
+        if (r < 0)
+                return r;
+
+        r = sd_id128_get_boot(&boot_id);
+        if (r < 0)
+                return r;
+
+        if (sd_id128_equal(boot_id, f->header->boot_id))
+                f->tail_entry_monotonic_valid = true;
+
+        f->header->boot_id = boot_id;
+
+        f->header->state = STATE_ONLINE;
+
+        /* Sync the online state to disk */
+        msync(f->header, PAGE_ALIGN(sizeof(Header)), MS_SYNC);
+        fdatasync(f->fd);
+
+        return 0;
+}
+
+static int journal_file_verify_header(JournalFile *f) {
+        assert(f);
+
+        if (memcmp(f->header->signature, HEADER_SIGNATURE, 8))
+                return -EBADMSG;
+
+        /* In both read and write mode we refuse to open files with
+         * incompatible flags we don't know */
+#ifdef HAVE_XZ
+        if ((le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) != 0)
+                return -EPROTONOSUPPORT;
+#else
+        if (f->header->incompatible_flags != 0)
+                return -EPROTONOSUPPORT;
+#endif
+
+        /* When open for writing we refuse to open files with
+         * compatible flags, too */
+        if (f->writable) {
+#ifdef HAVE_GCRYPT
+                if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0)
+                        return -EPROTONOSUPPORT;
+#else
+                if (f->header->compatible_flags != 0)
+                        return -EPROTONOSUPPORT;
+#endif
+        }
+
+        if (f->header->state >= _STATE_MAX)
+                return -EBADMSG;
+
+        /* The first addition was n_data, so check that we are at least this large */
+        if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
+                return -EBADMSG;
+
+        if (JOURNAL_HEADER_SEALED(f->header) && !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
+                return -EBADMSG;
+
+        if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size)
+                return -ENODATA;
+
+        if (le64toh(f->header->tail_object_offset) > (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
+                return -ENODATA;
+
+        if (!VALID64(le64toh(f->header->data_hash_table_offset)) ||
+            !VALID64(le64toh(f->header->field_hash_table_offset)) ||
+            !VALID64(le64toh(f->header->tail_object_offset)) ||
+            !VALID64(le64toh(f->header->entry_array_offset)))
+                return -ENODATA;
+
+        if (le64toh(f->header->data_hash_table_offset) < le64toh(f->header->header_size) ||
+            le64toh(f->header->field_hash_table_offset) < le64toh(f->header->header_size) ||
+            le64toh(f->header->tail_object_offset) < le64toh(f->header->header_size) ||
+            le64toh(f->header->entry_array_offset) < le64toh(f->header->header_size))
+                return -ENODATA;
+
+        if (f->writable) {
+                uint8_t state;
+                sd_id128_t machine_id;
+                int r;
+
+                r = sd_id128_get_machine(&machine_id);
+                if (r < 0)
+                        return r;
+
+                if (!sd_id128_equal(machine_id, f->header->machine_id))
+                        return -EHOSTDOWN;
+
+                state = f->header->state;
+
+                if (state == STATE_ONLINE) {
+                        log_debug("Journal file %s is already online. Assuming unclean closing.", f->path);
+                        return -EBUSY;
+                } else if (state == STATE_ARCHIVED)
+                        return -ESHUTDOWN;
+                else if (state != STATE_OFFLINE) {
+                        log_debug("Journal file %s has unknown state %u.", f->path, state);
+                        return -EBUSY;
+                }
+        }
+
+        f->compress = JOURNAL_HEADER_COMPRESSED(f->header);
+
+        f->seal = JOURNAL_HEADER_SEALED(f->header);
+
+        return 0;
+}
+
+static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) {
+        uint64_t old_size, new_size;
+        int r;
+
+        assert(f);
+
+        /* We assume that this file is not sparse, and we know that
+         * for sure, since we always call posix_fallocate()
+         * ourselves */
+
+        old_size =
+                le64toh(f->header->header_size) +
+                le64toh(f->header->arena_size);
+
+        new_size = PAGE_ALIGN(offset + size);
+        if (new_size < le64toh(f->header->header_size))
+                new_size = le64toh(f->header->header_size);
+
+        if (new_size <= old_size)
+                return 0;
+
+        if (f->metrics.max_size > 0 &&
+            new_size > f->metrics.max_size)
+                return -E2BIG;
+
+        if (new_size > f->metrics.min_size &&
+            f->metrics.keep_free > 0) {
+                struct statvfs svfs;
+
+                if (fstatvfs(f->fd, &svfs) >= 0) {
+                        uint64_t available;
+
+                        available = svfs.f_bfree * svfs.f_bsize;
+
+                        if (available >= f->metrics.keep_free)
+                                available -= f->metrics.keep_free;
+                        else
+                                available = 0;
+
+                        if (new_size - old_size > available)
+                                return -E2BIG;
+                }
+        }
+
+        /* Note that the glibc fallocate() fallback is very
+           inefficient, hence we try to minimize the allocation area
+           as we can. */
+        r = posix_fallocate(f->fd, old_size, new_size - old_size);
+        if (r != 0)
+                return -r;
+
+        if (fstat(f->fd, &f->last_stat) < 0)
+                return -errno;
+
+        f->header->arena_size = htole64(new_size - le64toh(f->header->header_size));
+
+        return 0;
+}
+
+static int journal_file_move_to(JournalFile *f, int context, bool keep_always, uint64_t offset, uint64_t size, void **ret) {
+        assert(f);
+        assert(ret);
+
+        if (size <= 0)
+                return -EINVAL;
+
+        /* Avoid SIGBUS on invalid accesses */
+        if (offset + size > (uint64_t) f->last_stat.st_size) {
+                /* Hmm, out of range? Let's refresh the fstat() data
+                 * first, before we trust that check. */
+
+                if (fstat(f->fd, &f->last_stat) < 0 ||
+                    offset + size > (uint64_t) f->last_stat.st_size)
+                        return -EADDRNOTAVAIL;
+        }
+
+        return mmap_cache_get(f->mmap, f->fd, f->prot, context, keep_always, offset, size, &f->last_stat, ret);
+}
+
+static uint64_t minimum_header_size(Object *o) {
+
+        static uint64_t table[] = {
+                [OBJECT_DATA] = sizeof(DataObject),
+                [OBJECT_FIELD] = sizeof(FieldObject),
+                [OBJECT_ENTRY] = sizeof(EntryObject),
+                [OBJECT_DATA_HASH_TABLE] = sizeof(HashTableObject),
+                [OBJECT_FIELD_HASH_TABLE] = sizeof(HashTableObject),
+                [OBJECT_ENTRY_ARRAY] = sizeof(EntryArrayObject),
+                [OBJECT_TAG] = sizeof(TagObject),
+        };
+
+        if (o->object.type >= ELEMENTSOF(table) || table[o->object.type] <= 0)
+                return sizeof(ObjectHeader);
+
+        return table[o->object.type];
+}
+
+int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret) {
+        int r;
+        void *t;
+        Object *o;
+        uint64_t s;
+        unsigned context;
+
+        assert(f);
+        assert(ret);
+
+        /* Objects may only be located at multiple of 64 bit */
+        if (!VALID64(offset))
+                return -EFAULT;
+
+        /* One context for each type, plus one catch-all for the rest */
+        context = type > 0 && type < _OBJECT_TYPE_MAX ? type : 0;
+
+        r = journal_file_move_to(f, context, false, offset, sizeof(ObjectHeader), &t);
+        if (r < 0)
+                return r;
+
+        o = (Object*) t;
+        s = le64toh(o->object.size);
+
+        if (s < sizeof(ObjectHeader))
+                return -EBADMSG;
+
+        if (o->object.type <= OBJECT_UNUSED)
+                return -EBADMSG;
+
+        if (s < minimum_header_size(o))
+                return -EBADMSG;
+
+        if (type > 0 && o->object.type != type)
+                return -EBADMSG;
+
+        if (s > sizeof(ObjectHeader)) {
+                r = journal_file_move_to(f, o->object.type, false, offset, s, &t);
+                if (r < 0)
+                        return r;
+
+                o = (Object*) t;
+        }
+
+        *ret = o;
+        return 0;
+}
+
+static uint64_t journal_file_entry_seqnum(JournalFile *f, uint64_t *seqnum) {
+        uint64_t r;
+
+        assert(f);
+
+        r = le64toh(f->header->tail_entry_seqnum) + 1;
+
+        if (seqnum) {
+                /* If an external seqnum counter was passed, we update
+                 * both the local and the external one, and set it to
+                 * the maximum of both */
+
+                if (*seqnum + 1 > r)
+                        r = *seqnum + 1;
+
+                *seqnum = r;
+        }
+
+        f->header->tail_entry_seqnum = htole64(r);
+
+        if (f->header->head_entry_seqnum == 0)
+                f->header->head_entry_seqnum = htole64(r);
+
+        return r;
+}
+
+int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset) {
+        int r;
+        uint64_t p;
+        Object *tail, *o;
+        void *t;
+
+        assert(f);
+        assert(type > 0 && type < _OBJECT_TYPE_MAX);
+        assert(size >= sizeof(ObjectHeader));
+        assert(offset);
+        assert(ret);
+
+        p = le64toh(f->header->tail_object_offset);
+        if (p == 0)
+                p = le64toh(f->header->header_size);
+        else {
+                r = journal_file_move_to_object(f, -1, p, &tail);
+                if (r < 0)
+                        return r;
+
+                p += ALIGN64(le64toh(tail->object.size));
+        }
+
+        r = journal_file_allocate(f, p, size);
+        if (r < 0)
+                return r;
+
+        r = journal_file_move_to(f, type, false, p, size, &t);
+        if (r < 0)
+                return r;
+
+        o = (Object*) t;
+
+        zero(o->object);
+        o->object.type = type;
+        o->object.size = htole64(size);
+
+        f->header->tail_object_offset = htole64(p);
+        f->header->n_objects = htole64(le64toh(f->header->n_objects) + 1);
+
+        *ret = o;
+        *offset = p;
+
+        return 0;
+}
+
+static int journal_file_setup_data_hash_table(JournalFile *f) {
+        uint64_t s, p;
+        Object *o;
+        int r;
+
+        assert(f);
+
+        /* We estimate that we need 1 hash table entry per 768 of
+           journal file and we want to make sure we never get beyond
+           75% fill level. Calculate the hash table size for the
+           maximum file size based on these metrics. */
+
+        s = (f->metrics.max_size * 4 / 768 / 3) * sizeof(HashItem);
+        if (s < DEFAULT_DATA_HASH_TABLE_SIZE)
+                s = DEFAULT_DATA_HASH_TABLE_SIZE;
+
+        log_debug("Reserving %llu entries in hash table.", (unsigned long long) (s / sizeof(HashItem)));
+
+        r = journal_file_append_object(f,
+                                       OBJECT_DATA_HASH_TABLE,
+                                       offsetof(Object, hash_table.items) + s,
+                                       &o, &p);
+        if (r < 0)
+                return r;
+
+        memset(o->hash_table.items, 0, s);
+
+        f->header->data_hash_table_offset = htole64(p + offsetof(Object, hash_table.items));
+        f->header->data_hash_table_size = htole64(s);
+
+        return 0;
+}
+
+static int journal_file_setup_field_hash_table(JournalFile *f) {
+        uint64_t s, p;
+        Object *o;
+        int r;
+
+        assert(f);
+
+        /* We use a fixed size hash table for the fields as this
+         * number should grow very slowly only */
+
+        s = DEFAULT_FIELD_HASH_TABLE_SIZE;
+        r = journal_file_append_object(f,
+                                       OBJECT_FIELD_HASH_TABLE,
+                                       offsetof(Object, hash_table.items) + s,
+                                       &o, &p);
+        if (r < 0)
+                return r;
+
+        memset(o->hash_table.items, 0, s);
+
+        f->header->field_hash_table_offset = htole64(p + offsetof(Object, hash_table.items));
+        f->header->field_hash_table_size = htole64(s);
+
+        return 0;
+}
+
+static int journal_file_map_data_hash_table(JournalFile *f) {
+        uint64_t s, p;
+        void *t;
+        int r;
+
+        assert(f);
+
+        p = le64toh(f->header->data_hash_table_offset);
+        s = le64toh(f->header->data_hash_table_size);
+
+        r = journal_file_move_to(f,
+                                 OBJECT_DATA_HASH_TABLE,
+                                 true,
+                                 p, s,
+                                 &t);
+        if (r < 0)
+                return r;
+
+        f->data_hash_table = t;
+        return 0;
+}
+
+static int journal_file_map_field_hash_table(JournalFile *f) {
+        uint64_t s, p;
+        void *t;
+        int r;
+
+        assert(f);
+
+        p = le64toh(f->header->field_hash_table_offset);
+        s = le64toh(f->header->field_hash_table_size);
+
+        r = journal_file_move_to(f,
+                                 OBJECT_FIELD_HASH_TABLE,
+                                 true,
+                                 p, s,
+                                 &t);
+        if (r < 0)
+                return r;
+
+        f->field_hash_table = t;
+        return 0;
+}
+
+static int journal_file_link_field(
+                JournalFile *f,
+                Object *o,
+                uint64_t offset,
+                uint64_t hash) {
+
+        uint64_t p, h;
+        int r;
+
+        assert(f);
+        assert(o);
+        assert(offset > 0);
+
+        if (o->object.type != OBJECT_FIELD)
+                return -EINVAL;
+
+        /* This might alter the window we are looking at */
+
+        o->field.next_hash_offset = o->field.head_data_offset = 0;
+
+        h = hash % (le64toh(f->header->field_hash_table_size) / sizeof(HashItem));
+        p = le64toh(f->field_hash_table[h].tail_hash_offset);
+        if (p == 0)
+                f->field_hash_table[h].head_hash_offset = htole64(offset);
+        else {
+                r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o);
+                if (r < 0)
+                        return r;
+
+                o->field.next_hash_offset = htole64(offset);
+        }
+
+        f->field_hash_table[h].tail_hash_offset = htole64(offset);
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_fields))
+                f->header->n_fields = htole64(le64toh(f->header->n_fields) + 1);
+
+        return 0;
+}
+
+static int journal_file_link_data(
+                JournalFile *f,
+                Object *o,
+                uint64_t offset,
+                uint64_t hash) {
+
+        uint64_t p, h;
+        int r;
+
+        assert(f);
+        assert(o);
+        assert(offset > 0);
+
+        if (o->object.type != OBJECT_DATA)
+                return -EINVAL;
+
+        /* This might alter the window we are looking at */
+
+        o->data.next_hash_offset = o->data.next_field_offset = 0;
+        o->data.entry_offset = o->data.entry_array_offset = 0;
+        o->data.n_entries = 0;
+
+        h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem));
+        p = le64toh(f->data_hash_table[h].tail_hash_offset);
+        if (p == 0)
+                /* Only entry in the hash table is easy */
+                f->data_hash_table[h].head_hash_offset = htole64(offset);
+        else {
+                /* Move back to the previous data object, to patch in
+                 * pointer */
+
+                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+                if (r < 0)
+                        return r;
+
+                o->data.next_hash_offset = htole64(offset);
+        }
+
+        f->data_hash_table[h].tail_hash_offset = htole64(offset);
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_data))
+                f->header->n_data = htole64(le64toh(f->header->n_data) + 1);
+
+        return 0;
+}
+
+int journal_file_find_field_object_with_hash(
+                JournalFile *f,
+                const void *field, uint64_t size, uint64_t hash,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t p, osize, h;
+        int r;
+
+        assert(f);
+        assert(field && size > 0);
+
+        osize = offsetof(Object, field.payload) + size;
+
+        if (f->header->field_hash_table_size == 0)
+                return -EBADMSG;
+
+        h = hash % (le64toh(f->header->field_hash_table_size) / sizeof(HashItem));
+        p = le64toh(f->field_hash_table[h].head_hash_offset);
+
+        while (p > 0) {
+                Object *o;
+
+                r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o);
+                if (r < 0)
+                        return r;
+
+                if (le64toh(o->field.hash) == hash &&
+                    le64toh(o->object.size) == osize &&
+                    memcmp(o->field.payload, field, size) == 0) {
+
+                        if (ret)
+                                *ret = o;
+                        if (offset)
+                                *offset = p;
+
+                        return 1;
+                }
+
+                p = le64toh(o->field.next_hash_offset);
+        }
+
+        return 0;
+}
+
+int journal_file_find_field_object(
+                JournalFile *f,
+                const void *field, uint64_t size,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t hash;
+
+        assert(f);
+        assert(field && size > 0);
+
+        hash = hash64(field, size);
+
+        return journal_file_find_field_object_with_hash(f,
+                                                        field, size, hash,
+                                                        ret, offset);
+}
+
+int journal_file_find_data_object_with_hash(
+                JournalFile *f,
+                const void *data, uint64_t size, uint64_t hash,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t p, osize, h;
+        int r;
+
+        assert(f);
+        assert(data || size == 0);
+
+        osize = offsetof(Object, data.payload) + size;
+
+        if (f->header->data_hash_table_size == 0)
+                return -EBADMSG;
+
+        h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem));
+        p = le64toh(f->data_hash_table[h].head_hash_offset);
+
+        while (p > 0) {
+                Object *o;
+
+                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+                if (r < 0)
+                        return r;
+
+                if (le64toh(o->data.hash) != hash)
+                        goto next;
+
+                if (o->object.flags & OBJECT_COMPRESSED) {
+#ifdef HAVE_XZ
+                        uint64_t l, rsize;
+
+                        l = le64toh(o->object.size);
+                        if (l <= offsetof(Object, data.payload))
+                                return -EBADMSG;
+
+                        l -= offsetof(Object, data.payload);
+
+                        if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize, 0))
+                                return -EBADMSG;
+
+                        if (rsize == size &&
+                            memcmp(f->compress_buffer, data, size) == 0) {
+
+                                if (ret)
+                                        *ret = o;
+
+                                if (offset)
+                                        *offset = p;
+
+                                return 1;
+                        }
+#else
+                        return -EPROTONOSUPPORT;
+#endif
+
+                } else if (le64toh(o->object.size) == osize &&
+                           memcmp(o->data.payload, data, size) == 0) {
+
+                        if (ret)
+                                *ret = o;
+
+                        if (offset)
+                                *offset = p;
+
+                        return 1;
+                }
+
+        next:
+                p = le64toh(o->data.next_hash_offset);
+        }
+
+        return 0;
+}
+
+int journal_file_find_data_object(
+                JournalFile *f,
+                const void *data, uint64_t size,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t hash;
+
+        assert(f);
+        assert(data || size == 0);
+
+        hash = hash64(data, size);
+
+        return journal_file_find_data_object_with_hash(f,
+                                                       data, size, hash,
+                                                       ret, offset);
+}
+
+static int journal_file_append_field(
+                JournalFile *f,
+                const void *field, uint64_t size,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t hash, p;
+        uint64_t osize;
+        Object *o;
+        int r;
+
+        assert(f);
+        assert(field && size > 0);
+
+        hash = hash64(field, size);
+
+        r = journal_file_find_field_object_with_hash(f, field, size, hash, &o, &p);
+        if (r < 0)
+                return r;
+        else if (r > 0) {
+
+                if (ret)
+                        *ret = o;
+
+                if (offset)
+                        *offset = p;
+
+                return 0;
+        }
+
+        osize = offsetof(Object, field.payload) + size;
+        r = journal_file_append_object(f, OBJECT_FIELD, osize, &o, &p);
+
+        o->field.hash = htole64(hash);
+        memcpy(o->field.payload, field, size);
+
+        r = journal_file_link_field(f, o, p, hash);
+        if (r < 0)
+                return r;
+
+        /* The linking might have altered the window, so let's
+         * refresh our pointer */
+        r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o);
+        if (r < 0)
+                return r;
+
+#ifdef HAVE_GCRYPT
+        r = journal_file_hmac_put_object(f, OBJECT_FIELD, o, p);
+        if (r < 0)
+                return r;
+#endif
+
+        if (ret)
+                *ret = o;
+
+        if (offset)
+                *offset = p;
+
+        return 0;
+}
+
+static int journal_file_append_data(
+                JournalFile *f,
+                const void *data, uint64_t size,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t hash, p;
+        uint64_t osize;
+        Object *o;
+        int r;
+        bool compressed = false;
+        const void *eq;
+
+        assert(f);
+        assert(data || size == 0);
+
+        hash = hash64(data, size);
+
+        r = journal_file_find_data_object_with_hash(f, data, size, hash, &o, &p);
+        if (r < 0)
+                return r;
+        else if (r > 0) {
+
+                if (ret)
+                        *ret = o;
+
+                if (offset)
+                        *offset = p;
+
+                return 0;
+        }
+
+        osize = offsetof(Object, data.payload) + size;
+        r = journal_file_append_object(f, OBJECT_DATA, osize, &o, &p);
+        if (r < 0)
+                return r;
+
+        o->data.hash = htole64(hash);
+
+#ifdef HAVE_XZ
+        if (f->compress &&
+            size >= COMPRESSION_SIZE_THRESHOLD) {
+                uint64_t rsize;
+
+                compressed = compress_blob(data, size, o->data.payload, &rsize);
+
+                if (compressed) {
+                        o->object.size = htole64(offsetof(Object, data.payload) + rsize);
+                        o->object.flags |= OBJECT_COMPRESSED;
+
+                        log_debug("Compressed data object %lu -> %lu", (unsigned long) size, (unsigned long) rsize);
+                }
+        }
+#endif
+
+        if (!compressed && size > 0)
+                memcpy(o->data.payload, data, size);
+
+        r = journal_file_link_data(f, o, p, hash);
+        if (r < 0)
+                return r;
+
+        /* The linking might have altered the window, so let's
+         * refresh our pointer */
+        r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+        if (r < 0)
+                return r;
+
+        eq = memchr(data, '=', size);
+        if (eq && eq > data) {
+                uint64_t fp;
+                Object *fo;
+
+                /* Create field object ... */
+                r = journal_file_append_field(f, data, (uint8_t*) eq - (uint8_t*) data, &fo, &fp);
+                if (r < 0)
+                        return r;
+
+                /* ... and link it in. */
+                o->data.next_field_offset = fo->field.head_data_offset;
+                fo->field.head_data_offset = le64toh(p);
+        }
+
+#ifdef HAVE_GCRYPT
+        r = journal_file_hmac_put_object(f, OBJECT_DATA, o, p);
+        if (r < 0)
+                return r;
+#endif
+
+        if (ret)
+                *ret = o;
+
+        if (offset)
+                *offset = p;
+
+        return 0;
+}
+
+uint64_t journal_file_entry_n_items(Object *o) {
+        assert(o);
+
+        if (o->object.type != OBJECT_ENTRY)
+                return 0;
+
+        return (le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem);
+}
+
+uint64_t journal_file_entry_array_n_items(Object *o) {
+        assert(o);
+
+        if (o->object.type != OBJECT_ENTRY_ARRAY)
+                return 0;
+
+        return (le64toh(o->object.size) - offsetof(Object, entry_array.items)) / sizeof(uint64_t);
+}
+
+uint64_t journal_file_hash_table_n_items(Object *o) {
+        assert(o);
+
+        if (o->object.type != OBJECT_DATA_HASH_TABLE &&
+            o->object.type != OBJECT_FIELD_HASH_TABLE)
+                return 0;
+
+        return (le64toh(o->object.size) - offsetof(Object, hash_table.items)) / sizeof(HashItem);
+}
+
+static int link_entry_into_array(JournalFile *f,
+                                 le64_t *first,
+                                 le64_t *idx,
+                                 uint64_t p) {
+        int r;
+        uint64_t n = 0, ap = 0, q, i, a, hidx;
+        Object *o;
+
+        assert(f);
+        assert(first);
+        assert(idx);
+        assert(p > 0);
+
+        a = le64toh(*first);
+        i = hidx = le64toh(*idx);
+        while (a > 0) {
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
+                if (r < 0)
+                        return r;
+
+                n = journal_file_entry_array_n_items(o);
+                if (i < n) {
+                        o->entry_array.items[i] = htole64(p);
+                        *idx = htole64(hidx + 1);
+                        return 0;
+                }
+
+                i -= n;
+                ap = a;
+                a = le64toh(o->entry_array.next_entry_array_offset);
+        }
+
+        if (hidx > n)
+                n = (hidx+1) * 2;
+        else
+                n = n * 2;
+
+        if (n < 4)
+                n = 4;
+
+        r = journal_file_append_object(f, OBJECT_ENTRY_ARRAY,
+                                       offsetof(Object, entry_array.items) + n * sizeof(uint64_t),
+                                       &o, &q);
+        if (r < 0)
+                return r;
+
+#ifdef HAVE_GCRYPT
+        r = journal_file_hmac_put_object(f, OBJECT_ENTRY_ARRAY, o, q);
+        if (r < 0)
+                return r;
+#endif
+
+        o->entry_array.items[i] = htole64(p);
+
+        if (ap == 0)
+                *first = htole64(q);
+        else {
+                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, ap, &o);
+                if (r < 0)
+                        return r;
+
+                o->entry_array.next_entry_array_offset = htole64(q);
+        }
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
+                f->header->n_entry_arrays = htole64(le64toh(f->header->n_entry_arrays) + 1);
+
+        *idx = htole64(hidx + 1);
+
+        return 0;
+}
+
+static int link_entry_into_array_plus_one(JournalFile *f,
+                                          le64_t *extra,
+                                          le64_t *first,
+                                          le64_t *idx,
+                                          uint64_t p) {
+
+        int r;
+
+        assert(f);
+        assert(extra);
+        assert(first);
+        assert(idx);
+        assert(p > 0);
+
+        if (*idx == 0)
+                *extra = htole64(p);
+        else {
+                le64_t i;
+
+                i = htole64(le64toh(*idx) - 1);
+                r = link_entry_into_array(f, first, &i, p);
+                if (r < 0)
+                        return r;
+        }
+
+        *idx = htole64(le64toh(*idx) + 1);
+        return 0;
+}
+
+static int journal_file_link_entry_item(JournalFile *f, Object *o, uint64_t offset, uint64_t i) {
+        uint64_t p;
+        int r;
+        assert(f);
+        assert(o);
+        assert(offset > 0);
+
+        p = le64toh(o->entry.items[i].object_offset);
+        if (p == 0)
+                return -EINVAL;
+
+        r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+        if (r < 0)
+                return r;
+
+        return link_entry_into_array_plus_one(f,
+                                              &o->data.entry_offset,
+                                              &o->data.entry_array_offset,
+                                              &o->data.n_entries,
+                                              offset);
+}
+
+static int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) {
+        uint64_t n, i;
+        int r;
+
+        assert(f);
+        assert(o);
+        assert(offset > 0);
+
+        if (o->object.type != OBJECT_ENTRY)
+                return -EINVAL;
+
+        __sync_synchronize();
+
+        /* Link up the entry itself */
+        r = link_entry_into_array(f,
+                                  &f->header->entry_array_offset,
+                                  &f->header->n_entries,
+                                  offset);
+        if (r < 0)
+                return r;
+
+        /* log_debug("=> %s seqnr=%lu n_entries=%lu", f->path, (unsigned long) o->entry.seqnum, (unsigned long) f->header->n_entries); */
+
+        if (f->header->head_entry_realtime == 0)
+                f->header->head_entry_realtime = o->entry.realtime;
+
+        f->header->tail_entry_realtime = o->entry.realtime;
+        f->header->tail_entry_monotonic = o->entry.monotonic;
+
+        f->tail_entry_monotonic_valid = true;
+
+        /* Link up the items */
+        n = journal_file_entry_n_items(o);
+        for (i = 0; i < n; i++) {
+                r = journal_file_link_entry_item(f, o, offset, i);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int journal_file_append_entry_internal(
+                JournalFile *f,
+                const dual_timestamp *ts,
+                uint64_t xor_hash,
+                const EntryItem items[], unsigned n_items,
+                uint64_t *seqnum,
+                Object **ret, uint64_t *offset) {
+        uint64_t np;
+        uint64_t osize;
+        Object *o;
+        int r;
+
+        assert(f);
+        assert(items || n_items == 0);
+        assert(ts);
+
+        osize = offsetof(Object, entry.items) + (n_items * sizeof(EntryItem));
+
+        r = journal_file_append_object(f, OBJECT_ENTRY, osize, &o, &np);
+        if (r < 0)
+                return r;
+
+        o->entry.seqnum = htole64(journal_file_entry_seqnum(f, seqnum));
+        memcpy(o->entry.items, items, n_items * sizeof(EntryItem));
+        o->entry.realtime = htole64(ts->realtime);
+        o->entry.monotonic = htole64(ts->monotonic);
+        o->entry.xor_hash = htole64(xor_hash);
+        o->entry.boot_id = f->header->boot_id;
+
+#ifdef HAVE_GCRYPT
+        r = journal_file_hmac_put_object(f, OBJECT_ENTRY, o, np);
+        if (r < 0)
+                return r;
+#endif
+
+        r = journal_file_link_entry(f, o, np);
+        if (r < 0)
+                return r;
+
+        if (ret)
+                *ret = o;
+
+        if (offset)
+                *offset = np;
+
+        return 0;
+}
+
+void journal_file_post_change(JournalFile *f) {
+        assert(f);
+
+        /* inotify() does not receive IN_MODIFY events from file
+         * accesses done via mmap(). After each access we hence
+         * trigger IN_MODIFY by truncating the journal file to its
+         * current size which triggers IN_MODIFY. */
+
+        __sync_synchronize();
+
+        if (ftruncate(f->fd, f->last_stat.st_size) < 0)
+                log_error("Failed to truncate file to its own size: %m");
+}
+
+static int entry_item_cmp(const void *_a, const void *_b) {
+        const EntryItem *a = _a, *b = _b;
+
+        if (le64toh(a->object_offset) < le64toh(b->object_offset))
+                return -1;
+        if (le64toh(a->object_offset) > le64toh(b->object_offset))
+                return 1;
+        return 0;
+}
+
+int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqnum, Object **ret, uint64_t *offset) {
+        unsigned i;
+        EntryItem *items;
+        int r;
+        uint64_t xor_hash = 0;
+        struct dual_timestamp _ts;
+
+        assert(f);
+        assert(iovec || n_iovec == 0);
+
+        if (!f->writable)
+                return -EPERM;
+
+        if (!ts) {
+                dual_timestamp_get(&_ts);
+                ts = &_ts;
+        }
+
+        if (f->tail_entry_monotonic_valid &&
+            ts->monotonic < le64toh(f->header->tail_entry_monotonic))
+                return -EINVAL;
+
+#ifdef HAVE_GCRYPT
+        r = journal_file_maybe_append_tag(f, ts->realtime);
+        if (r < 0)
+                return r;
+#endif
+
+        /* alloca() can't take 0, hence let's allocate at least one */
+        items = alloca(sizeof(EntryItem) * MAX(1, n_iovec));
+
+        for (i = 0; i < n_iovec; i++) {
+                uint64_t p;
+                Object *o;
+
+                r = journal_file_append_data(f, iovec[i].iov_base, iovec[i].iov_len, &o, &p);
+                if (r < 0)
+                        return r;
+
+                xor_hash ^= le64toh(o->data.hash);
+                items[i].object_offset = htole64(p);
+                items[i].hash = o->data.hash;
+        }
+
+        /* Order by the position on disk, in order to improve seek
+         * times for rotating media. */
+        qsort(items, n_iovec, sizeof(EntryItem), entry_item_cmp);
+
+        r = journal_file_append_entry_internal(f, ts, xor_hash, items, n_iovec, seqnum, ret, offset);
+
+        journal_file_post_change(f);
+
+        return r;
+}
+
+typedef struct ChainCacheItem {
+        uint64_t first; /* the array at the begin of the chain */
+        uint64_t array; /* the cached array */
+        uint64_t begin; /* the first item in the cached array */
+        uint64_t total; /* the total number of items in all arrays before this one in the chain */
+} ChainCacheItem;
+
+static void chain_cache_put(
+                Hashmap *h,
+                ChainCacheItem *ci,
+                uint64_t first,
+                uint64_t array,
+                uint64_t begin,
+                uint64_t total) {
+
+        if (!ci) {
+                /* If the chain item to cache for this chain is the
+                 * first one it's not worth caching anything */
+                if (array == first)
+                        return;
+
+                if (hashmap_size(h) >= CHAIN_CACHE_MAX)
+                        ci = hashmap_steal_first(h);
+                else {
+                        ci = new(ChainCacheItem, 1);
+                        if (!ci)
+                                return;
+                }
+
+                ci->first = first;
+
+                if (hashmap_put(h, &ci->first, ci) < 0) {
+                        free(ci);
+                        return;
+                }
+        } else
+                assert(ci->first == first);
+
+        ci->array = array;
+        ci->begin = begin;
+        ci->total = total;
+}
+
+static int generic_array_get(JournalFile *f,
+                             uint64_t first,
+                             uint64_t i,
+                             Object **ret, uint64_t *offset) {
+
+        Object *o;
+        uint64_t p = 0, a, t = 0;
+        int r;
+        ChainCacheItem *ci;
+
+        assert(f);
+
+        a = first;
+
+        /* Try the chain cache first */
+        ci = hashmap_get(f->chain_cache, &first);
+        if (ci && i > ci->total) {
+                a = ci->array;
+                i -= ci->total;
+                t = ci->total;
+        }
+
+        while (a > 0) {
+                uint64_t k;
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
+                if (r < 0)
+                        return r;
+
+                k = journal_file_entry_array_n_items(o);
+                if (i < k) {
+                        p = le64toh(o->entry_array.items[i]);
+                        goto found;
+                }
+
+                i -= k;
+                t += k;
+                a = le64toh(o->entry_array.next_entry_array_offset);
+        }
+
+        return 0;
+
+found:
+        /* Let's cache this item for the next invocation */
+        chain_cache_put(f->chain_cache, ci, first, a, o->entry_array.items[0], t);
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
+        if (r < 0)
+                return r;
+
+        if (ret)
+                *ret = o;
+
+        if (offset)
+                *offset = p;
+
+        return 1;
+}
+
+static int generic_array_get_plus_one(JournalFile *f,
+                                      uint64_t extra,
+                                      uint64_t first,
+                                      uint64_t i,
+                                      Object **ret, uint64_t *offset) {
+
+        Object *o;
+
+        assert(f);
+
+        if (i == 0) {
+                int r;
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, &o);
+                if (r < 0)
+                        return r;
+
+                if (ret)
+                        *ret = o;
+
+                if (offset)
+                        *offset = extra;
+
+                return 1;
+        }
+
+        return generic_array_get(f, first, i-1, ret, offset);
+}
+
+enum {
+        TEST_FOUND,
+        TEST_LEFT,
+        TEST_RIGHT
+};
+
+static int generic_array_bisect(JournalFile *f,
+                                uint64_t first,
+                                uint64_t n,
+                                uint64_t needle,
+                                int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
+                                direction_t direction,
+                                Object **ret,
+                                uint64_t *offset,
+                                uint64_t *idx) {
+
+        uint64_t a, p, t = 0, i = 0, last_p = 0;
+        bool subtract_one = false;
+        Object *o, *array = NULL;
+        int r;
+        ChainCacheItem *ci;
+
+        assert(f);
+        assert(test_object);
+
+        /* Start with the first array in the chain */
+        a = first;
+
+        ci = hashmap_get(f->chain_cache, &first);
+        if (ci && n > ci->total) {
+                /* Ah, we have iterated this bisection array chain
+                 * previously! Let's see if we can skip ahead in the
+                 * chain, as far as the last time. But we can't jump
+                 * backwards in the chain, so let's check that
+                 * first. */
+
+                r = test_object(f, ci->begin, needle);
+                if (r < 0)
+                        return r;
+
+                if (r == TEST_LEFT) {
+                        /* OK, what we are looking for is right of th
+                         * begin of this EntryArray, so let's jump
+                         * straight to previously cached array in the
+                         * chain */
+
+                        a = ci->array;
+                        n -= ci->total;
+                        t = ci->total;
+                }
+        }
+
+        while (a > 0) {
+                uint64_t left, right, k, lp;
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array);
+                if (r < 0)
+                        return r;
+
+                k = journal_file_entry_array_n_items(array);
+                right = MIN(k, n);
+                if (right <= 0)
+                        return 0;
+
+                i = right - 1;
+                lp = p = le64toh(array->entry_array.items[i]);
+                if (p <= 0)
+                        return -EBADMSG;
+
+                r = test_object(f, p, needle);
+                if (r < 0)
+                        return r;
+
+                if (r == TEST_FOUND)
+                        r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;
+
+                if (r == TEST_RIGHT) {
+                        left = 0;
+                        right -= 1;
+                        for (;;) {
+                                if (left == right) {
+                                        if (direction == DIRECTION_UP)
+                                                subtract_one = true;
+
+                                        i = left;
+                                        goto found;
+                                }
+
+                                assert(left < right);
+
+                                i = (left + right) / 2;
+                                p = le64toh(array->entry_array.items[i]);
+                                if (p <= 0)
+                                        return -EBADMSG;
+
+                                r = test_object(f, p, needle);
+                                if (r < 0)
+                                        return r;
+
+                                if (r == TEST_FOUND)
+                                        r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;
+
+                                if (r == TEST_RIGHT)
+                                        right = i;
+                                else
+                                        left = i + 1;
+                        }
+                }
+
+                if (k > n) {
+                        if (direction == DIRECTION_UP) {
+                                i = n;
+                                subtract_one = true;
+                                goto found;
+                        }
+
+                        return 0;
+                }
+
+                last_p = lp;
+
+                n -= k;
+                t += k;
+                a = le64toh(array->entry_array.next_entry_array_offset);
+        }
+
+        return 0;
+
+found:
+        if (subtract_one && t == 0 && i == 0)
+                return 0;
+
+        /* Let's cache this item for the next invocation */
+        chain_cache_put(f->chain_cache, ci, first, a, array->entry_array.items[0], t);
+
+        if (subtract_one && i == 0)
+                p = last_p;
+        else if (subtract_one)
+                p = le64toh(array->entry_array.items[i-1]);
+        else
+                p = le64toh(array->entry_array.items[i]);
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
+        if (r < 0)
+                return r;
+
+        if (ret)
+                *ret = o;
+
+        if (offset)
+                *offset = p;
+
+        if (idx)
+                *idx = t + i + (subtract_one ? -1 : 0);
+
+        return 1;
+}
+
+static int generic_array_bisect_plus_one(JournalFile *f,
+                                         uint64_t extra,
+                                         uint64_t first,
+                                         uint64_t n,
+                                         uint64_t needle,
+                                         int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
+                                         direction_t direction,
+                                         Object **ret,
+                                         uint64_t *offset,
+                                         uint64_t *idx) {
+
+        int r;
+        bool step_back = false;
+        Object *o;
+
+        assert(f);
+        assert(test_object);
+
+        if (n <= 0)
+                return 0;
+
+        /* This bisects the array in object 'first', but first checks
+         * an extra  */
+        r = test_object(f, extra, needle);
+        if (r < 0)
+                return r;
+
+        if (r == TEST_FOUND)
+                r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;
+
+        /* if we are looking with DIRECTION_UP then we need to first
+           see if in the actual array there is a matching entry, and
+           return the last one of that. But if there isn't any we need
+           to return this one. Hence remember this, and return it
+           below. */
+        if (r == TEST_LEFT)
+                step_back = direction == DIRECTION_UP;
+
+        if (r == TEST_RIGHT) {
+                if (direction == DIRECTION_DOWN)
+                        goto found;
+                else
+                        return 0;
+        }
+
+        r = generic_array_bisect(f, first, n-1, needle, test_object, direction, ret, offset, idx);
+
+        if (r == 0 && step_back)
+                goto found;
+
+        if (r > 0 && idx)
+                (*idx) ++;
+
+        return r;
+
+found:
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, &o);
+        if (r < 0)
+                return r;
+
+        if (ret)
+                *ret = o;
+
+        if (offset)
+                *offset = extra;
+
+        if (idx)
+                *idx = 0;
+
+        return 1;
+}
+
+static int test_object_offset(JournalFile *f, uint64_t p, uint64_t needle) {
+        assert(f);
+        assert(p > 0);
+
+        if (p == needle)
+                return TEST_FOUND;
+        else if (p < needle)
+                return TEST_LEFT;
+        else
+                return TEST_RIGHT;
+}
+
+int journal_file_move_to_entry_by_offset(
+                JournalFile *f,
+                uint64_t p,
+                direction_t direction,
+                Object **ret,
+                uint64_t *offset) {
+
+        return generic_array_bisect(f,
+                                    le64toh(f->header->entry_array_offset),
+                                    le64toh(f->header->n_entries),
+                                    p,
+                                    test_object_offset,
+                                    direction,
+                                    ret, offset, NULL);
+}
+
+
+static int test_object_seqnum(JournalFile *f, uint64_t p, uint64_t needle) {
+        Object *o;
+        int r;
+
+        assert(f);
+        assert(p > 0);
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
+        if (r < 0)
+                return r;
+
+        if (le64toh(o->entry.seqnum) == needle)
+                return TEST_FOUND;
+        else if (le64toh(o->entry.seqnum) < needle)
+                return TEST_LEFT;
+        else
+                return TEST_RIGHT;
+}
+
+int journal_file_move_to_entry_by_seqnum(
+                JournalFile *f,
+                uint64_t seqnum,
+                direction_t direction,
+                Object **ret,
+                uint64_t *offset) {
+
+        return generic_array_bisect(f,
+                                    le64toh(f->header->entry_array_offset),
+                                    le64toh(f->header->n_entries),
+                                    seqnum,
+                                    test_object_seqnum,
+                                    direction,
+                                    ret, offset, NULL);
+}
+
+static int test_object_realtime(JournalFile *f, uint64_t p, uint64_t needle) {
+        Object *o;
+        int r;
+
+        assert(f);
+        assert(p > 0);
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
+        if (r < 0)
+                return r;
+
+        if (le64toh(o->entry.realtime) == needle)
+                return TEST_FOUND;
+        else if (le64toh(o->entry.realtime) < needle)
+                return TEST_LEFT;
+        else
+                return TEST_RIGHT;
+}
+
+int journal_file_move_to_entry_by_realtime(
+                JournalFile *f,
+                uint64_t realtime,
+                direction_t direction,
+                Object **ret,
+                uint64_t *offset) {
+
+        return generic_array_bisect(f,
+                                    le64toh(f->header->entry_array_offset),
+                                    le64toh(f->header->n_entries),
+                                    realtime,
+                                    test_object_realtime,
+                                    direction,
+                                    ret, offset, NULL);
+}
+
+static int test_object_monotonic(JournalFile *f, uint64_t p, uint64_t needle) {
+        Object *o;
+        int r;
+
+        assert(f);
+        assert(p > 0);
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
+        if (r < 0)
+                return r;
+
+        if (le64toh(o->entry.monotonic) == needle)
+                return TEST_FOUND;
+        else if (le64toh(o->entry.monotonic) < needle)
+                return TEST_LEFT;
+        else
+                return TEST_RIGHT;
+}
+
+int journal_file_move_to_entry_by_monotonic(
+                JournalFile *f,
+                sd_id128_t boot_id,
+                uint64_t monotonic,
+                direction_t direction,
+                Object **ret,
+                uint64_t *offset) {
+
+        char t[9+32+1] = "_BOOT_ID=";
+        Object *o;
+        int r;
+
+        assert(f);
+
+        sd_id128_to_string(boot_id, t + 9);
+        r = journal_file_find_data_object(f, t, strlen(t), &o, NULL);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return -ENOENT;
+
+        return generic_array_bisect_plus_one(f,
+                                             le64toh(o->data.entry_offset),
+                                             le64toh(o->data.entry_array_offset),
+                                             le64toh(o->data.n_entries),
+                                             monotonic,
+                                             test_object_monotonic,
+                                             direction,
+                                             ret, offset, NULL);
+}
+
+int journal_file_next_entry(
+                JournalFile *f,
+                Object *o, uint64_t p,
+                direction_t direction,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t i, n;
+        int r;
+
+        assert(f);
+        assert(p > 0 || !o);
+
+        n = le64toh(f->header->n_entries);
+        if (n <= 0)
+                return 0;
+
+        if (!o)
+                i = direction == DIRECTION_DOWN ? 0 : n - 1;
+        else {
+                if (o->object.type != OBJECT_ENTRY)
+                        return -EINVAL;
+
+                r = generic_array_bisect(f,
+                                         le64toh(f->header->entry_array_offset),
+                                         le64toh(f->header->n_entries),
+                                         p,
+                                         test_object_offset,
+                                         DIRECTION_DOWN,
+                                         NULL, NULL,
+                                         &i);
+                if (r <= 0)
+                        return r;
+
+                if (direction == DIRECTION_DOWN) {
+                        if (i >= n - 1)
+                                return 0;
+
+                        i++;
+                } else {
+                        if (i <= 0)
+                                return 0;
+
+                        i--;
+                }
+        }
+
+        /* And jump to it */
+        return generic_array_get(f,
+                                 le64toh(f->header->entry_array_offset),
+                                 i,
+                                 ret, offset);
+}
+
+int journal_file_skip_entry(
+                JournalFile *f,
+                Object *o, uint64_t p,
+                int64_t skip,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t i, n;
+        int r;
+
+        assert(f);
+        assert(o);
+        assert(p > 0);
+
+        if (o->object.type != OBJECT_ENTRY)
+                return -EINVAL;
+
+        r = generic_array_bisect(f,
+                                 le64toh(f->header->entry_array_offset),
+                                 le64toh(f->header->n_entries),
+                                 p,
+                                 test_object_offset,
+                                 DIRECTION_DOWN,
+                                 NULL, NULL,
+                                 &i);
+        if (r <= 0)
+                return r;
+
+        /* Calculate new index */
+        if (skip < 0) {
+                if ((uint64_t) -skip >= i)
+                        i = 0;
+                else
+                        i = i - (uint64_t) -skip;
+        } else
+                i  += (uint64_t) skip;
+
+        n = le64toh(f->header->n_entries);
+        if (n <= 0)
+                return -EBADMSG;
+
+        if (i >= n)
+                i = n-1;
+
+        return generic_array_get(f,
+                                 le64toh(f->header->entry_array_offset),
+                                 i,
+                                 ret, offset);
+}
+
+int journal_file_next_entry_for_data(
+                JournalFile *f,
+                Object *o, uint64_t p,
+                uint64_t data_offset,
+                direction_t direction,
+                Object **ret, uint64_t *offset) {
+
+        uint64_t n, i;
+        int r;
+        Object *d;
+
+        assert(f);
+        assert(p > 0 || !o);
+
+        r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
+        if (r < 0)
+                return r;
+
+        n = le64toh(d->data.n_entries);
+        if (n <= 0)
+                return n;
+
+        if (!o)
+                i = direction == DIRECTION_DOWN ? 0 : n - 1;
+        else {
+                if (o->object.type != OBJECT_ENTRY)
+                        return -EINVAL;
+
+                r = generic_array_bisect_plus_one(f,
+                                                  le64toh(d->data.entry_offset),
+                                                  le64toh(d->data.entry_array_offset),
+                                                  le64toh(d->data.n_entries),
+                                                  p,
+                                                  test_object_offset,
+                                                  DIRECTION_DOWN,
+                                                  NULL, NULL,
+                                                  &i);
+
+                if (r <= 0)
+                        return r;
+
+                if (direction == DIRECTION_DOWN) {
+                        if (i >= n - 1)
+                                return 0;
+
+                        i++;
+                } else {
+                        if (i <= 0)
+                                return 0;
+
+                        i--;
+                }
+
+        }
+
+        return generic_array_get_plus_one(f,
+                                          le64toh(d->data.entry_offset),
+                                          le64toh(d->data.entry_array_offset),
+                                          i,
+                                          ret, offset);
+}
+
+int journal_file_move_to_entry_by_offset_for_data(
+                JournalFile *f,
+                uint64_t data_offset,
+                uint64_t p,
+                direction_t direction,
+                Object **ret, uint64_t *offset) {
+
+        int r;
+        Object *d;
+
+        assert(f);
+
+        r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
+        if (r < 0)
+                return r;
+
+        return generic_array_bisect_plus_one(f,
+                                             le64toh(d->data.entry_offset),
+                                             le64toh(d->data.entry_array_offset),
+                                             le64toh(d->data.n_entries),
+                                             p,
+                                             test_object_offset,
+                                             direction,
+                                             ret, offset, NULL);
+}
+
+int journal_file_move_to_entry_by_monotonic_for_data(
+                JournalFile *f,
+                uint64_t data_offset,
+                sd_id128_t boot_id,
+                uint64_t monotonic,
+                direction_t direction,
+                Object **ret, uint64_t *offset) {
+
+        char t[9+32+1] = "_BOOT_ID=";
+        Object *o, *d;
+        int r;
+        uint64_t b, z;
+
+        assert(f);
+
+        /* First, seek by time */
+        sd_id128_to_string(boot_id, t + 9);
+        r = journal_file_find_data_object(f, t, strlen(t), &o, &b);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return -ENOENT;
+
+        r = generic_array_bisect_plus_one(f,
+                                          le64toh(o->data.entry_offset),
+                                          le64toh(o->data.entry_array_offset),
+                                          le64toh(o->data.n_entries),
+                                          monotonic,
+                                          test_object_monotonic,
+                                          direction,
+                                          NULL, &z, NULL);
+        if (r <= 0)
+                return r;
+
+        /* And now, continue seeking until we find an entry that
+         * exists in both bisection arrays */
+
+        for (;;) {
+                Object *qo;
+                uint64_t p, q;
+
+                r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
+                if (r < 0)
+                        return r;
+
+                r = generic_array_bisect_plus_one(f,
+                                                  le64toh(d->data.entry_offset),
+                                                  le64toh(d->data.entry_array_offset),
+                                                  le64toh(d->data.n_entries),
+                                                  z,
+                                                  test_object_offset,
+                                                  direction,
+                                                  NULL, &p, NULL);
+                if (r <= 0)
+                        return r;
+
+                r = journal_file_move_to_object(f, OBJECT_DATA, b, &o);
+                if (r < 0)
+                        return r;
+
+                r = generic_array_bisect_plus_one(f,
+                                                  le64toh(o->data.entry_offset),
+                                                  le64toh(o->data.entry_array_offset),
+                                                  le64toh(o->data.n_entries),
+                                                  p,
+                                                  test_object_offset,
+                                                  direction,
+                                                  &qo, &q, NULL);
+
+                if (r <= 0)
+                        return r;
+
+                if (p == q) {
+                        if (ret)
+                                *ret = qo;
+                        if (offset)
+                                *offset = q;
+
+                        return 1;
+                }
+
+                z = q;
+        }
+
+        return 0;
+}
+
+int journal_file_move_to_entry_by_seqnum_for_data(
+                JournalFile *f,
+                uint64_t data_offset,
+                uint64_t seqnum,
+                direction_t direction,
+                Object **ret, uint64_t *offset) {
+
+        Object *d;
+        int r;
+
+        assert(f);
+
+        r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
+        if (r < 0)
+                return r;
+
+        return generic_array_bisect_plus_one(f,
+                                             le64toh(d->data.entry_offset),
+                                             le64toh(d->data.entry_array_offset),
+                                             le64toh(d->data.n_entries),
+                                             seqnum,
+                                             test_object_seqnum,
+                                             direction,
+                                             ret, offset, NULL);
+}
+
+int journal_file_move_to_entry_by_realtime_for_data(
+                JournalFile *f,
+                uint64_t data_offset,
+                uint64_t realtime,
+                direction_t direction,
+                Object **ret, uint64_t *offset) {
+
+        Object *d;
+        int r;
+
+        assert(f);
+
+        r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
+        if (r < 0)
+                return r;
+
+        return generic_array_bisect_plus_one(f,
+                                             le64toh(d->data.entry_offset),
+                                             le64toh(d->data.entry_array_offset),
+                                             le64toh(d->data.n_entries),
+                                             realtime,
+                                             test_object_realtime,
+                                             direction,
+                                             ret, offset, NULL);
+}
+
+void journal_file_dump(JournalFile *f) {
+        Object *o;
+        int r;
+        uint64_t p;
+
+        assert(f);
+
+        journal_file_print_header(f);
+
+        p = le64toh(f->header->header_size);
+        while (p != 0) {
+                r = journal_file_move_to_object(f, -1, p, &o);
+                if (r < 0)
+                        goto fail;
+
+                switch (o->object.type) {
+
+                case OBJECT_UNUSED:
+                        printf("Type: OBJECT_UNUSED\n");
+                        break;
+
+                case OBJECT_DATA:
+                        printf("Type: OBJECT_DATA\n");
+                        break;
+
+                case OBJECT_FIELD:
+                        printf("Type: OBJECT_FIELD\n");
+                        break;
+
+                case OBJECT_ENTRY:
+                        printf("Type: OBJECT_ENTRY seqnum=%llu monotonic=%llu realtime=%llu\n",
+                               (unsigned long long) le64toh(o->entry.seqnum),
+                               (unsigned long long) le64toh(o->entry.monotonic),
+                               (unsigned long long) le64toh(o->entry.realtime));
+                        break;
+
+                case OBJECT_FIELD_HASH_TABLE:
+                        printf("Type: OBJECT_FIELD_HASH_TABLE\n");
+                        break;
+
+                case OBJECT_DATA_HASH_TABLE:
+                        printf("Type: OBJECT_DATA_HASH_TABLE\n");
+                        break;
+
+                case OBJECT_ENTRY_ARRAY:
+                        printf("Type: OBJECT_ENTRY_ARRAY\n");
+                        break;
+
+                case OBJECT_TAG:
+                        printf("Type: OBJECT_TAG seqnum=%llu epoch=%llu\n",
+                               (unsigned long long) le64toh(o->tag.seqnum),
+                               (unsigned long long) le64toh(o->tag.epoch));
+                        break;
+
+                default:
+                        printf("Type: unknown (%u)\n", o->object.type);
+                        break;
+                }
+
+                if (o->object.flags & OBJECT_COMPRESSED)
+                        printf("Flags: COMPRESSED\n");
+
+                if (p == le64toh(f->header->tail_object_offset))
+                        p = 0;
+                else
+                        p = p + ALIGN64(le64toh(o->object.size));
+        }
+
+        return;
+fail:
+        log_error("File corrupt");
+}
+
+void journal_file_print_header(JournalFile *f) {
+        char a[33], b[33], c[33];
+        char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX];
+        struct stat st;
+        char bytes[FORMAT_BYTES_MAX];
+
+        assert(f);
+
+        printf("File Path: %s\n"
+               "File ID: %s\n"
+               "Machine ID: %s\n"
+               "Boot ID: %s\n"
+               "Sequential Number ID: %s\n"
+               "State: %s\n"
+               "Compatible Flags:%s%s\n"
+               "Incompatible Flags:%s%s\n"
+               "Header size: %llu\n"
+               "Arena size: %llu\n"
+               "Data Hash Table Size: %llu\n"
+               "Field Hash Table Size: %llu\n"
+               "Rotate Suggested: %s\n"
+               "Head Sequential Number: %llu\n"
+               "Tail Sequential Number: %llu\n"
+               "Head Realtime Timestamp: %s\n"
+               "Tail Realtime Timestamp: %s\n"
+               "Objects: %llu\n"
+               "Entry Objects: %llu\n",
+               f->path,
+               sd_id128_to_string(f->header->file_id, a),
+               sd_id128_to_string(f->header->machine_id, b),
+               sd_id128_to_string(f->header->boot_id, c),
+               sd_id128_to_string(f->header->seqnum_id, c),
+               f->header->state == STATE_OFFLINE ? "OFFLINE" :
+               f->header->state == STATE_ONLINE ? "ONLINE" :
+               f->header->state == STATE_ARCHIVED ? "ARCHIVED" : "UNKNOWN",
+               JOURNAL_HEADER_SEALED(f->header) ? " SEALED" : "",
+               (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "",
+               JOURNAL_HEADER_COMPRESSED(f->header) ? " COMPRESSED" : "",
+               (le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
+               (unsigned long long) le64toh(f->header->header_size),
+               (unsigned long long) le64toh(f->header->arena_size),
+               (unsigned long long) le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
+               (unsigned long long) le64toh(f->header->field_hash_table_size) / sizeof(HashItem),
+               yes_no(journal_file_rotate_suggested(f, 0)),
+               (unsigned long long) le64toh(f->header->head_entry_seqnum),
+               (unsigned long long) le64toh(f->header->tail_entry_seqnum),
+               format_timestamp(x, sizeof(x), le64toh(f->header->head_entry_realtime)),
+               format_timestamp(y, sizeof(y), le64toh(f->header->tail_entry_realtime)),
+               (unsigned long long) le64toh(f->header->n_objects),
+               (unsigned long long) le64toh(f->header->n_entries));
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_data))
+                printf("Data Objects: %llu\n"
+                       "Data Hash Table Fill: %.1f%%\n",
+                       (unsigned long long) le64toh(f->header->n_data),
+                       100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))));
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_fields))
+                printf("Field Objects: %llu\n"
+                       "Field Hash Table Fill: %.1f%%\n",
+                       (unsigned long long) le64toh(f->header->n_fields),
+                       100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))));
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_tags))
+                printf("Tag Objects: %llu\n",
+                       (unsigned long long) le64toh(f->header->n_tags));
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
+                printf("Entry Array Objects: %llu\n",
+                       (unsigned long long) le64toh(f->header->n_entry_arrays));
+
+        if (fstat(f->fd, &st) >= 0)
+                printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (off_t) st.st_blocks * 512ULL));
+}
+
+int journal_file_open(
+                const char *fname,
+                int flags,
+                mode_t mode,
+                bool compress,
+                bool seal,
+                JournalMetrics *metrics,
+                MMapCache *mmap_cache,
+                JournalFile *template,
+                JournalFile **ret) {
+
+        JournalFile *f;
+        int r;
+        bool newly_created = false;
+
+        assert(fname);
+        assert(ret);
+
+        if ((flags & O_ACCMODE) != O_RDONLY &&
+            (flags & O_ACCMODE) != O_RDWR)
+                return -EINVAL;
+
+        if (!endswith(fname, ".journal") &&
+            !endswith(fname, ".journal~"))
+                return -EINVAL;
+
+        f = new0(JournalFile, 1);
+        if (!f)
+                return -ENOMEM;
+
+        f->fd = -1;
+        f->mode = mode;
+
+        f->flags = flags;
+        f->prot = prot_from_flags(flags);
+        f->writable = (flags & O_ACCMODE) != O_RDONLY;
+#ifdef HAVE_XZ
+        f->compress = compress;
+#endif
+#ifdef HAVE_GCRYPT
+        f->seal = seal;
+#endif
+
+        if (mmap_cache)
+                f->mmap = mmap_cache_ref(mmap_cache);
+        else {
+                f->mmap = mmap_cache_new();
+                if (!f->mmap) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+        }
+
+        f->path = strdup(fname);
+        if (!f->path) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        f->chain_cache = hashmap_new(uint64_hash_func, uint64_compare_func);
+        if (!f->chain_cache) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        f->fd = open(f->path, f->flags|O_CLOEXEC, f->mode);
+        if (f->fd < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if (fstat(f->fd, &f->last_stat) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        if (f->last_stat.st_size == 0 && f->writable) {
+#ifdef HAVE_XATTR
+                uint64_t crtime;
+
+                /* Let's attach the creation time to the journal file,
+                 * so that the vacuuming code knows the age of this
+                 * file even if the file might end up corrupted one
+                 * day... Ideally we'd just use the creation time many
+                 * file systems maintain for each file, but there is
+                 * currently no usable API to query this, hence let's
+                 * emulate this via extended attributes. If extended
+                 * attributes are not supported we'll just skip this,
+                 * and rely solely on mtime/atime/ctime of the file.*/
+
+                crtime = htole64((uint64_t) now(CLOCK_REALTIME));
+                fsetxattr(f->fd, "user.crtime_usec", &crtime, sizeof(crtime), XATTR_CREATE);
+#endif
+
+#ifdef HAVE_GCRYPT
+                /* Try to load the FSPRG state, and if we can't, then
+                 * just don't do sealing */
+                if (f->seal) {
+                        r = journal_file_fss_load(f);
+                        if (r < 0)
+                                f->seal = false;
+                }
+#endif
+
+                r = journal_file_init_header(f, template);
+                if (r < 0)
+                        goto fail;
+
+                if (fstat(f->fd, &f->last_stat) < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+
+                newly_created = true;
+        }
+
+        if (f->last_stat.st_size < (off_t) HEADER_SIZE_MIN) {
+                r = -EIO;
+                goto fail;
+        }
+
+        f->header = mmap(NULL, PAGE_ALIGN(sizeof(Header)), prot_from_flags(flags), MAP_SHARED, f->fd, 0);
+        if (f->header == MAP_FAILED) {
+                f->header = NULL;
+                r = -errno;
+                goto fail;
+        }
+
+        if (!newly_created) {
+                r = journal_file_verify_header(f);
+                if (r < 0)
+                        goto fail;
+        }
+
+#ifdef HAVE_GCRYPT
+        if (!newly_created && f->writable) {
+                r = journal_file_fss_load(f);
+                if (r < 0)
+                        goto fail;
+        }
+#endif
+
+        if (f->writable) {
+                if (metrics) {
+                        journal_default_metrics(metrics, f->fd);
+                        f->metrics = *metrics;
+                } else if (template)
+                        f->metrics = template->metrics;
+
+                r = journal_file_refresh_header(f);
+                if (r < 0)
+                        goto fail;
+        }
+
+#ifdef HAVE_GCRYPT
+        r = journal_file_hmac_setup(f);
+        if (r < 0)
+                goto fail;
+#endif
+
+        if (newly_created) {
+                r = journal_file_setup_field_hash_table(f);
+                if (r < 0)
+                        goto fail;
+
+                r = journal_file_setup_data_hash_table(f);
+                if (r < 0)
+                        goto fail;
+
+#ifdef HAVE_GCRYPT
+                r = journal_file_append_first_tag(f);
+                if (r < 0)
+                        goto fail;
+#endif
+        }
+
+        r = journal_file_map_field_hash_table(f);
+        if (r < 0)
+                goto fail;
+
+        r = journal_file_map_data_hash_table(f);
+        if (r < 0)
+                goto fail;
+
+        *ret = f;
+        return 0;
+
+fail:
+        journal_file_close(f);
+
+        return r;
+}
+
+int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
+        char *p;
+        size_t l;
+        JournalFile *old_file, *new_file = NULL;
+        int r;
+
+        assert(f);
+        assert(*f);
+
+        old_file = *f;
+
+        if (!old_file->writable)
+                return -EINVAL;
+
+        if (!endswith(old_file->path, ".journal"))
+                return -EINVAL;
+
+        l = strlen(old_file->path);
+
+        p = new(char, l + 1 + 32 + 1 + 16 + 1 + 16 + 1);
+        if (!p)
+                return -ENOMEM;
+
+        memcpy(p, old_file->path, l - 8);
+        p[l-8] = '@';
+        sd_id128_to_string(old_file->header->seqnum_id, p + l - 8 + 1);
+        snprintf(p + l - 8 + 1 + 32, 1 + 16 + 1 + 16 + 8 + 1,
+                 "-%016llx-%016llx.journal",
+                 (unsigned long long) le64toh((*f)->header->head_entry_seqnum),
+                 (unsigned long long) le64toh((*f)->header->head_entry_realtime));
+
+        r = rename(old_file->path, p);
+        free(p);
+
+        if (r < 0)
+                return -errno;
+
+        old_file->header->state = STATE_ARCHIVED;
+
+        r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, old_file, &new_file);
+        journal_file_close(old_file);
+
+        *f = new_file;
+        return r;
+}
+
+int journal_file_open_reliably(
+                const char *fname,
+                int flags,
+                mode_t mode,
+                bool compress,
+                bool seal,
+                JournalMetrics *metrics,
+                MMapCache *mmap_cache,
+                JournalFile *template,
+                JournalFile **ret) {
+
+        int r;
+        size_t l;
+        char *p;
+
+        r = journal_file_open(fname, flags, mode, compress, seal,
+                              metrics, mmap_cache, template, ret);
+        if (r != -EBADMSG && /* corrupted */
+            r != -ENODATA && /* truncated */
+            r != -EHOSTDOWN && /* other machine */
+            r != -EPROTONOSUPPORT && /* incompatible feature */
+            r != -EBUSY && /* unclean shutdown */
+            r != -ESHUTDOWN /* already archived */)
+                return r;
+
+        if ((flags & O_ACCMODE) == O_RDONLY)
+                return r;
+
+        if (!(flags & O_CREAT))
+                return r;
+
+        if (!endswith(fname, ".journal"))
+                return r;
+
+        /* The file is corrupted. Rotate it away and try it again (but only once) */
+
+        l = strlen(fname);
+        if (asprintf(&p, "%.*s@%016llx-%016llx.journal~",
+                     (int) (l-8), fname,
+                     (unsigned long long) now(CLOCK_REALTIME),
+                     random_ull()) < 0)
+                return -ENOMEM;
+
+        r = rename(fname, p);
+        free(p);
+        if (r < 0)
+                return -errno;
+
+        log_warning("File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
+
+        return journal_file_open(fname, flags, mode, compress, seal,
+                                 metrics, mmap_cache, template, ret);
+}
+
+int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset) {
+        uint64_t i, n;
+        uint64_t q, xor_hash = 0;
+        int r;
+        EntryItem *items;
+        dual_timestamp ts;
+
+        assert(from);
+        assert(to);
+        assert(o);
+        assert(p);
+
+        if (!to->writable)
+                return -EPERM;
+
+        ts.monotonic = le64toh(o->entry.monotonic);
+        ts.realtime = le64toh(o->entry.realtime);
+
+        if (to->tail_entry_monotonic_valid &&
+            ts.monotonic < le64toh(to->header->tail_entry_monotonic))
+                return -EINVAL;
+
+        n = journal_file_entry_n_items(o);
+        items = alloca(sizeof(EntryItem) * n);
+
+        for (i = 0; i < n; i++) {
+                uint64_t l, h;
+                le64_t le_hash;
+                size_t t;
+                void *data;
+                Object *u;
+
+                q = le64toh(o->entry.items[i].object_offset);
+                le_hash = o->entry.items[i].hash;
+
+                r = journal_file_move_to_object(from, OBJECT_DATA, q, &o);
+                if (r < 0)
+                        return r;
+
+                if (le_hash != o->data.hash)
+                        return -EBADMSG;
+
+                l = le64toh(o->object.size) - offsetof(Object, data.payload);
+                t = (size_t) l;
+
+                /* We hit the limit on 32bit machines */
+                if ((uint64_t) t != l)
+                        return -E2BIG;
+
+                if (o->object.flags & OBJECT_COMPRESSED) {
+#ifdef HAVE_XZ
+                        uint64_t rsize;
+
+                        if (!uncompress_blob(o->data.payload, l, &from->compress_buffer, &from->compress_buffer_size, &rsize, 0))
+                                return -EBADMSG;
+
+                        data = from->compress_buffer;
+                        l = rsize;
+#else
+                        return -EPROTONOSUPPORT;
+#endif
+                } else
+                        data = o->data.payload;
+
+                r = journal_file_append_data(to, data, l, &u, &h);
+                if (r < 0)
+                        return r;
+
+                xor_hash ^= le64toh(u->data.hash);
+                items[i].object_offset = htole64(h);
+                items[i].hash = u->data.hash;
+
+                r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o);
+                if (r < 0)
+                        return r;
+        }
+
+        return journal_file_append_entry_internal(to, &ts, xor_hash, items, n, seqnum, ret, offset);
+}
+
+void journal_default_metrics(JournalMetrics *m, int fd) {
+        uint64_t fs_size = 0;
+        struct statvfs ss;
+        char a[FORMAT_BYTES_MAX], b[FORMAT_BYTES_MAX], c[FORMAT_BYTES_MAX], d[FORMAT_BYTES_MAX];
+
+        assert(m);
+        assert(fd >= 0);
+
+        if (fstatvfs(fd, &ss) >= 0)
+                fs_size = ss.f_frsize * ss.f_blocks;
+
+        if (m->max_use == (uint64_t) -1) {
+
+                if (fs_size > 0) {
+                        m->max_use = PAGE_ALIGN(fs_size / 10); /* 10% of file system size */
+
+                        if (m->max_use > DEFAULT_MAX_USE_UPPER)
+                                m->max_use = DEFAULT_MAX_USE_UPPER;
+
+                        if (m->max_use < DEFAULT_MAX_USE_LOWER)
+                                m->max_use = DEFAULT_MAX_USE_LOWER;
+                } else
+                        m->max_use = DEFAULT_MAX_USE_LOWER;
+        } else {
+                m->max_use = PAGE_ALIGN(m->max_use);
+
+                if (m->max_use < JOURNAL_FILE_SIZE_MIN*2)
+                        m->max_use = JOURNAL_FILE_SIZE_MIN*2;
+        }
+
+        if (m->max_size == (uint64_t) -1) {
+                m->max_size = PAGE_ALIGN(m->max_use / 8); /* 8 chunks */
+
+                if (m->max_size > DEFAULT_MAX_SIZE_UPPER)
+                        m->max_size = DEFAULT_MAX_SIZE_UPPER;
+        } else
+                m->max_size = PAGE_ALIGN(m->max_size);
+
+        if (m->max_size < JOURNAL_FILE_SIZE_MIN)
+                m->max_size = JOURNAL_FILE_SIZE_MIN;
+
+        if (m->max_size*2 > m->max_use)
+                m->max_use = m->max_size*2;
+
+        if (m->min_size == (uint64_t) -1)
+                m->min_size = JOURNAL_FILE_SIZE_MIN;
+        else {
+                m->min_size = PAGE_ALIGN(m->min_size);
+
+                if (m->min_size < JOURNAL_FILE_SIZE_MIN)
+                        m->min_size = JOURNAL_FILE_SIZE_MIN;
+
+                if (m->min_size > m->max_size)
+                        m->max_size = m->min_size;
+        }
+
+        if (m->keep_free == (uint64_t) -1) {
+
+                if (fs_size > 0) {
+                        m->keep_free = PAGE_ALIGN(fs_size / 20); /* 5% of file system size */
+
+                        if (m->keep_free > DEFAULT_KEEP_FREE_UPPER)
+                                m->keep_free = DEFAULT_KEEP_FREE_UPPER;
+
+                } else
+                        m->keep_free = DEFAULT_KEEP_FREE;
+        }
+
+        log_debug("Fixed max_use=%s max_size=%s min_size=%s keep_free=%s",
+                  format_bytes(a, sizeof(a), m->max_use),
+                  format_bytes(b, sizeof(b), m->max_size),
+                  format_bytes(c, sizeof(c), m->min_size),
+                  format_bytes(d, sizeof(d), m->keep_free));
+}
+
+int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to) {
+        assert(f);
+        assert(from || to);
+
+        if (from) {
+                if (f->header->head_entry_realtime == 0)
+                        return -ENOENT;
+
+                *from = le64toh(f->header->head_entry_realtime);
+        }
+
+        if (to) {
+                if (f->header->tail_entry_realtime == 0)
+                        return -ENOENT;
+
+                *to = le64toh(f->header->tail_entry_realtime);
+        }
+
+        return 1;
+}
+
+int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, usec_t *from, usec_t *to) {
+        char t[9+32+1] = "_BOOT_ID=";
+        Object *o;
+        uint64_t p;
+        int r;
+
+        assert(f);
+        assert(from || to);
+
+        sd_id128_to_string(boot_id, t + 9);
+
+        r = journal_file_find_data_object(f, t, strlen(t), &o, &p);
+        if (r <= 0)
+                return r;
+
+        if (le64toh(o->data.n_entries) <= 0)
+                return 0;
+
+        if (from) {
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, le64toh(o->data.entry_offset), &o);
+                if (r < 0)
+                        return r;
+
+                *from = le64toh(o->entry.monotonic);
+        }
+
+        if (to) {
+                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+                if (r < 0)
+                        return r;
+
+                r = generic_array_get_plus_one(f,
+                                               le64toh(o->data.entry_offset),
+                                               le64toh(o->data.entry_array_offset),
+                                               le64toh(o->data.n_entries)-1,
+                                               &o, NULL);
+                if (r <= 0)
+                        return r;
+
+                *to = le64toh(o->entry.monotonic);
+        }
+
+        return 1;
+}
+
+bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec) {
+        assert(f);
+
+        /* If we gained new header fields we gained new features,
+         * hence suggest a rotation */
+        if (le64toh(f->header->header_size) < sizeof(Header)) {
+                log_debug("%s uses an outdated header, suggesting rotation.", f->path);
+                return true;
+        }
+
+        /* Let's check if the hash tables grew over a certain fill
+         * level (75%, borrowing this value from Java's hash table
+         * implementation), and if so suggest a rotation. To calculate
+         * the fill level we need the n_data field, which only exists
+         * in newer versions. */
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_data))
+                if (le64toh(f->header->n_data) * 4ULL > (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)) * 3ULL) {
+                        log_debug("Data hash table of %s has a fill level at %.1f (%llu of %llu items, %llu file size, %llu bytes per hash table item), suggesting rotation.",
+                                  f->path,
+                                  100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))),
+                                  (unsigned long long) le64toh(f->header->n_data),
+                                  (unsigned long long) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)),
+                                  (unsigned long long) (f->last_stat.st_size),
+                                  (unsigned long long) (f->last_stat.st_size / le64toh(f->header->n_data)));
+                        return true;
+                }
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_fields))
+                if (le64toh(f->header->n_fields) * 4ULL > (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)) * 3ULL) {
+                        log_debug("Field hash table of %s has a fill level at %.1f (%llu of %llu items), suggesting rotation.",
+                                  f->path,
+                                  100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))),
+                                  (unsigned long long) le64toh(f->header->n_fields),
+                                  (unsigned long long) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)));
+                        return true;
+                }
+
+        /* Are the data objects properly indexed by field objects? */
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_data) &&
+            JOURNAL_HEADER_CONTAINS(f->header, n_fields) &&
+            le64toh(f->header->n_data) > 0 &&
+            le64toh(f->header->n_fields) == 0)
+                return true;
+
+        if (max_file_usec > 0) {
+                usec_t t, h;
+
+                h = le64toh(f->header->head_entry_realtime);
+                t = now(CLOCK_REALTIME);
+
+                if (h > 0 && t > h + max_file_usec)
+                        return true;
+        }
+
+        return false;
+}
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
new file mode 100644 (file)
index 0000000..cdbc8e4
--- /dev/null
@@ -0,0 +1,193 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+
+#ifdef HAVE_GCRYPT
+#include <gcrypt.h>
+#endif
+
+#include <systemd/sd-id128.h>
+
+#include "sparse-endian.h"
+#include "journal-def.h"
+#include "util.h"
+#include "mmap-cache.h"
+#include "hashmap.h"
+
+typedef struct JournalMetrics {
+        uint64_t max_use;
+        uint64_t max_size;
+        uint64_t min_size;
+        uint64_t keep_free;
+} JournalMetrics;
+
+typedef struct JournalFile {
+        int fd;
+        char *path;
+        struct stat last_stat;
+        mode_t mode;
+
+        int flags;
+        int prot;
+        bool writable;
+        bool compress;
+        bool seal;
+
+        bool tail_entry_monotonic_valid;
+
+        Header *header;
+        HashItem *data_hash_table;
+        HashItem *field_hash_table;
+
+        uint64_t current_offset;
+
+        JournalMetrics metrics;
+        MMapCache *mmap;
+
+        Hashmap *chain_cache;
+
+#ifdef HAVE_XZ
+        void *compress_buffer;
+        uint64_t compress_buffer_size;
+#endif
+
+#ifdef HAVE_GCRYPT
+        gcry_md_hd_t hmac;
+        bool hmac_running;
+
+        FSSHeader *fss_file;
+        size_t fss_file_size;
+
+        uint64_t fss_start_usec;
+        uint64_t fss_interval_usec;
+
+        void *fsprg_state;
+        size_t fsprg_state_size;
+
+        void *fsprg_seed;
+        size_t fsprg_seed_size;
+#endif
+} JournalFile;
+
+typedef enum direction {
+        DIRECTION_UP,
+        DIRECTION_DOWN
+} direction_t;
+
+int journal_file_open(
+                const char *fname,
+                int flags,
+                mode_t mode,
+                bool compress,
+                bool seal,
+                JournalMetrics *metrics,
+                MMapCache *mmap_cache,
+                JournalFile *template,
+                JournalFile **ret);
+
+void journal_file_close(JournalFile *j);
+
+int journal_file_open_reliably(
+                const char *fname,
+                int flags,
+                mode_t mode,
+                bool compress,
+                bool seal,
+                JournalMetrics *metrics,
+                MMapCache *mmap_cache,
+                JournalFile *template,
+                JournalFile **ret);
+
+#define ALIGN64(x) (((x) + 7ULL) & ~7ULL)
+#define VALID64(x) (((x) & 7ULL) == 0ULL)
+
+static inline bool VALID_REALTIME(uint64_t u) {
+        /* This considers timestamps until the year 3112 valid. That should be plenty room... */
+        return u > 0 && u < (1ULL << 55);
+}
+
+static inline bool VALID_MONOTONIC(uint64_t u) {
+        /* This considers timestamps until 1142 years of runtime valid. */
+        return u < (1ULL << 55);
+}
+
+static inline bool VALID_EPOCH(uint64_t u) {
+        /* This allows changing the key for 1142 years, every usec. */
+        return u < (1ULL << 55);
+}
+
+#define JOURNAL_HEADER_CONTAINS(h, field) \
+        (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field))
+
+#define JOURNAL_HEADER_SEALED(h) \
+        (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED))
+
+#define JOURNAL_HEADER_COMPRESSED(h) \
+        (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED))
+
+int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret);
+
+uint64_t journal_file_entry_n_items(Object *o);
+uint64_t journal_file_entry_array_n_items(Object *o);
+uint64_t journal_file_hash_table_n_items(Object *o);
+
+int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset);
+int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqno, Object **ret, uint64_t *offset);
+
+int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset);
+int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
+
+int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset);
+int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
+
+int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip, Object **ret, uint64_t *offset);
+
+int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
+
+int journal_file_move_to_entry_by_offset(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
+
+int journal_file_move_to_entry_by_offset_for_data(JournalFile *f, uint64_t data_offset, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, uint64_t data_offset, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, uint64_t data_offset, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_monotonic_for_data(JournalFile *f, uint64_t data_offset, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
+
+int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset);
+
+void journal_file_dump(JournalFile *f);
+void journal_file_print_header(JournalFile *f);
+
+int journal_file_rotate(JournalFile **f, bool compress, bool seal);
+
+void journal_file_post_change(JournalFile *f);
+
+void journal_default_metrics(JournalMetrics *m, int fd);
+
+int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to);
+int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to);
+
+bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec);
diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c
new file mode 100644 (file)
index 0000000..63d9744
--- /dev/null
@@ -0,0 +1,915 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <microhttpd.h>
+
+#include "log.h"
+#include "util.h"
+#include "sd-journal.h"
+#include "sd-daemon.h"
+#include "logs-show.h"
+#include "virt.h"
+
+typedef struct RequestMeta {
+        sd_journal *journal;
+
+        OutputMode mode;
+
+        char *cursor;
+        int64_t n_skip;
+        uint64_t n_entries;
+        bool n_entries_set;
+
+        FILE *tmp;
+        uint64_t delta, size;
+
+        int argument_parse_error;
+
+        bool follow;
+        bool discrete;
+
+        uint64_t n_fields;
+        bool n_fields_set;
+} RequestMeta;
+
+static const char* const mime_types[_OUTPUT_MODE_MAX] = {
+        [OUTPUT_SHORT] = "text/plain",
+        [OUTPUT_JSON] = "application/json",
+        [OUTPUT_JSON_SSE] = "text/event-stream",
+        [OUTPUT_EXPORT] = "application/vnd.fdo.journal",
+};
+
+static RequestMeta *request_meta(void **connection_cls) {
+        RequestMeta *m;
+
+        if (*connection_cls)
+                return *connection_cls;
+
+        m = new0(RequestMeta, 1);
+        if (!m)
+                return NULL;
+
+        *connection_cls = m;
+        return m;
+}
+
+static void request_meta_free(
+                void *cls,
+                struct MHD_Connection *connection,
+                void **connection_cls,
+                enum MHD_RequestTerminationCode toe) {
+
+        RequestMeta *m = *connection_cls;
+
+        if (!m)
+                return;
+
+        if (m->journal)
+                sd_journal_close(m->journal);
+
+        if (m->tmp)
+                fclose(m->tmp);
+
+        free(m->cursor);
+        free(m);
+}
+
+static int open_journal(RequestMeta *m) {
+        assert(m);
+
+        if (m->journal)
+                return 0;
+
+        return sd_journal_open(&m->journal, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY);
+}
+
+
+static int respond_oom(struct MHD_Connection *connection) {
+        struct MHD_Response *response;
+        const char m[] = "Out of memory.\n";
+        int ret;
+
+        assert(connection);
+
+        response = MHD_create_response_from_buffer(sizeof(m)-1, (char*) m, MHD_RESPMEM_PERSISTENT);
+        if (!response)
+                return MHD_NO;
+
+        MHD_add_response_header(response, "Content-Type", "text/plain");
+        ret = MHD_queue_response(connection, MHD_HTTP_SERVICE_UNAVAILABLE, response);
+        MHD_destroy_response(response);
+
+        return ret;
+}
+
+static int respond_error(
+                struct MHD_Connection *connection,
+                unsigned code,
+                const char *format, ...) {
+
+        struct MHD_Response *response;
+        char *m;
+        int r;
+        va_list ap;
+
+        assert(connection);
+        assert(format);
+
+        va_start(ap, format);
+        r = vasprintf(&m, format, ap);
+        va_end(ap);
+
+        if (r < 0)
+                return respond_oom(connection);
+
+        response = MHD_create_response_from_buffer(strlen(m), m, MHD_RESPMEM_MUST_FREE);
+        if (!response) {
+                free(m);
+                return respond_oom(connection);
+        }
+
+        MHD_add_response_header(response, "Content-Type", "text/plain");
+        r = MHD_queue_response(connection, code, response);
+        MHD_destroy_response(response);
+
+        return r;
+}
+
+static ssize_t request_reader_entries(
+                void *cls,
+                uint64_t pos,
+                char *buf,
+                size_t max) {
+
+        RequestMeta *m = cls;
+        int r;
+        size_t n, k;
+
+        assert(m);
+        assert(buf);
+        assert(max > 0);
+        assert(pos >= m->delta);
+
+        pos -= m->delta;
+
+        while (pos >= m->size) {
+                off_t sz;
+
+                /* End of this entry, so let's serialize the next
+                 * one */
+
+                if (m->n_entries_set &&
+                    m->n_entries <= 0)
+                        return MHD_CONTENT_READER_END_OF_STREAM;
+
+                if (m->n_skip < 0)
+                        r = sd_journal_previous_skip(m->journal, (uint64_t) -m->n_skip + 1);
+                else if (m->n_skip > 0)
+                        r = sd_journal_next_skip(m->journal, (uint64_t) m->n_skip + 1);
+                else
+                        r = sd_journal_next(m->journal);
+
+                if (r < 0) {
+                        log_error("Failed to advance journal pointer: %s", strerror(-r));
+                        return MHD_CONTENT_READER_END_WITH_ERROR;
+                } else if (r == 0) {
+
+                        if (m->follow) {
+                                r = sd_journal_wait(m->journal, (uint64_t) -1);
+                                if (r < 0) {
+                                        log_error("Couldn't wait for journal event: %s", strerror(-r));
+                                        return MHD_CONTENT_READER_END_WITH_ERROR;
+                                }
+
+                                continue;
+                        }
+
+                        return MHD_CONTENT_READER_END_OF_STREAM;
+                }
+
+                if (m->discrete) {
+                        assert(m->cursor);
+
+                        r = sd_journal_test_cursor(m->journal, m->cursor);
+                        if (r < 0) {
+                                log_error("Failed to test cursor: %s", strerror(-r));
+                                return MHD_CONTENT_READER_END_WITH_ERROR;
+                        }
+
+                        if (r == 0)
+                                return MHD_CONTENT_READER_END_OF_STREAM;
+                }
+
+                pos -= m->size;
+                m->delta += m->size;
+
+                if (m->n_entries_set)
+                        m->n_entries -= 1;
+
+                m->n_skip = 0;
+
+                if (m->tmp)
+                        rewind(m->tmp);
+                else {
+                        m->tmp = tmpfile();
+                        if (!m->tmp) {
+                                log_error("Failed to create temporary file: %m");
+                                return MHD_CONTENT_READER_END_WITH_ERROR;
+                        }
+                }
+
+                r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH);
+                if (r < 0) {
+                        log_error("Failed to serialize item: %s", strerror(-r));
+                        return MHD_CONTENT_READER_END_WITH_ERROR;
+                }
+
+                sz = ftello(m->tmp);
+                if (sz == (off_t) -1) {
+                        log_error("Failed to retrieve file position: %m");
+                        return MHD_CONTENT_READER_END_WITH_ERROR;
+                }
+
+                m->size = (uint64_t) sz;
+        }
+
+        if (fseeko(m->tmp, pos, SEEK_SET) < 0) {
+                log_error("Failed to seek to position: %m");
+                return MHD_CONTENT_READER_END_WITH_ERROR;
+        }
+
+        n = m->size - pos;
+        if (n > max)
+                n = max;
+
+        errno = 0;
+        k = fread(buf, 1, n, m->tmp);
+        if (k != n) {
+                log_error("Failed to read from file: %s", errno ? strerror(errno) : "Premature EOF");
+                return MHD_CONTENT_READER_END_WITH_ERROR;
+        }
+
+        return (ssize_t) k;
+}
+
+static int request_parse_accept(
+                RequestMeta *m,
+                struct MHD_Connection *connection) {
+
+        const char *header;
+
+        assert(m);
+        assert(connection);
+
+        header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Accept");
+        if (!header)
+                return 0;
+
+        if (streq(header, mime_types[OUTPUT_JSON]))
+                m->mode = OUTPUT_JSON;
+        else if (streq(header, mime_types[OUTPUT_JSON_SSE]))
+                m->mode = OUTPUT_JSON_SSE;
+        else if (streq(header, mime_types[OUTPUT_EXPORT]))
+                m->mode = OUTPUT_EXPORT;
+        else
+                m->mode = OUTPUT_SHORT;
+
+        return 0;
+}
+
+static int request_parse_range(
+                RequestMeta *m,
+                struct MHD_Connection *connection) {
+
+        const char *range, *colon, *colon2;
+        int r;
+
+        assert(m);
+        assert(connection);
+
+        range = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Range");
+        if (!range)
+                return 0;
+
+        if (!startswith(range, "entries="))
+                return 0;
+
+        range += 8;
+        range += strspn(range, WHITESPACE);
+
+        colon = strchr(range, ':');
+        if (!colon)
+                m->cursor = strdup(range);
+        else {
+                const char *p;
+
+                colon2 = strchr(colon + 1, ':');
+                if (colon2) {
+                        char _cleanup_free_ *t;
+
+                        t = strndup(colon + 1, colon2 - colon - 1);
+                        if (!t)
+                                return -ENOMEM;
+
+                        r = safe_atoi64(t, &m->n_skip);
+                        if (r < 0)
+                                return r;
+                }
+
+                p = (colon2 ? colon2 : colon) + 1;
+                if (*p) {
+                        r = safe_atou64(p, &m->n_entries);
+                        if (r < 0)
+                                return r;
+
+                        if (m->n_entries <= 0)
+                                return -EINVAL;
+
+                        m->n_entries_set = true;
+                }
+
+                m->cursor = strndup(range, colon - range);
+        }
+
+        if (!m->cursor)
+                return -ENOMEM;
+
+        m->cursor[strcspn(m->cursor, WHITESPACE)] = 0;
+        if (isempty(m->cursor)) {
+                free(m->cursor);
+                m->cursor = NULL;
+        }
+
+        return 0;
+}
+
+static int request_parse_arguments_iterator(
+                void *cls,
+                enum MHD_ValueKind kind,
+                const char *key,
+                const char *value) {
+
+        RequestMeta *m = cls;
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        assert(m);
+
+        if (isempty(key)) {
+                m->argument_parse_error = -EINVAL;
+                return MHD_NO;
+        }
+
+        if (streq(key, "follow")) {
+                if (isempty(value)) {
+                        m->follow = true;
+                        return MHD_YES;
+                }
+
+                r = parse_boolean(value);
+                if (r < 0) {
+                        m->argument_parse_error = r;
+                        return MHD_NO;
+                }
+
+                m->follow = r;
+                return MHD_YES;
+        }
+
+        if (streq(key, "discrete")) {
+                if (isempty(value)) {
+                        m->discrete = true;
+                        return MHD_YES;
+                }
+
+                r = parse_boolean(value);
+                if (r < 0) {
+                        m->argument_parse_error = r;
+                        return MHD_NO;
+                }
+
+                m->discrete = r;
+                return MHD_YES;
+        }
+
+        if (streq(key, "boot")) {
+                if (isempty(value))
+                        r = true;
+                else {
+                        r = parse_boolean(value);
+                        if (r < 0) {
+                                m->argument_parse_error = r;
+                                return MHD_NO;
+                        }
+                }
+
+                if (r) {
+                        char match[9 + 32 + 1] = "_BOOT_ID=";
+                        sd_id128_t bid;
+
+                        r = sd_id128_get_boot(&bid);
+                        if (r < 0) {
+                                log_error("Failed to get boot ID: %s", strerror(-r));
+                                return MHD_NO;
+                        }
+
+                        sd_id128_to_string(bid, match + 9);
+                        r = sd_journal_add_match(m->journal, match, sizeof(match)-1);
+                        if (r < 0) {
+                                m->argument_parse_error = r;
+                                return MHD_NO;
+                        }
+                }
+
+                return MHD_YES;
+        }
+
+        p = strjoin(key, "=", strempty(value), NULL);
+        if (!p) {
+                m->argument_parse_error = log_oom();
+                return MHD_NO;
+        }
+
+        r = sd_journal_add_match(m->journal, p, 0);
+        if (r < 0) {
+                m->argument_parse_error = r;
+                return MHD_NO;
+        }
+
+        return MHD_YES;
+}
+
+static int request_parse_arguments(
+                RequestMeta *m,
+                struct MHD_Connection *connection) {
+
+        assert(m);
+        assert(connection);
+
+        m->argument_parse_error = 0;
+        MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, request_parse_arguments_iterator, m);
+
+        return m->argument_parse_error;
+}
+
+static int request_handler_entries(
+                struct MHD_Connection *connection,
+                void **connection_cls) {
+
+        struct MHD_Response *response;
+        RequestMeta *m;
+        int r;
+
+        assert(connection);
+        assert(connection_cls);
+
+        m = request_meta(connection_cls);
+        if (!m)
+                return respond_oom(connection);
+
+        r = open_journal(m);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
+
+        if (request_parse_accept(m, connection) < 0)
+                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n");
+
+        if (request_parse_range(m, connection) < 0)
+                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Range header.\n");
+
+        if (request_parse_arguments(m, connection) < 0)
+                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse URL arguments.\n");
+
+        if (m->discrete) {
+                if (!m->cursor)
+                        return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Discrete seeks require a cursor specification.\n");
+
+                m->n_entries = 1;
+                m->n_entries_set = true;
+        }
+
+        if (m->cursor)
+                r = sd_journal_seek_cursor(m->journal, m->cursor);
+        else if (m->n_skip >= 0)
+                r = sd_journal_seek_head(m->journal);
+        else if (m->n_skip < 0)
+                r = sd_journal_seek_tail(m->journal);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to seek in journal.\n");
+
+        response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 4*1024, request_reader_entries, m, NULL);
+        if (!response)
+                return respond_oom(connection);
+
+        MHD_add_response_header(response, "Content-Type", mime_types[m->mode]);
+
+        r = MHD_queue_response(connection, MHD_HTTP_OK, response);
+        MHD_destroy_response(response);
+
+        return r;
+}
+
+static int output_field(FILE *f, OutputMode m, const char *d, size_t l) {
+        const char *eq;
+        size_t j;
+
+        eq = memchr(d, '=', l);
+        if (!eq)
+                return -EINVAL;
+
+        j = l - (eq - d + 1);
+
+        if (m == OUTPUT_JSON) {
+                fprintf(f, "{ \"%.*s\" : ", (int) (eq - d), d);
+                json_escape(f, eq+1, j, OUTPUT_FULL_WIDTH);
+                fputs(" }\n", f);
+        } else {
+                fwrite(eq+1, 1, j, f);
+                fputc('\n', f);
+        }
+
+        return 0;
+}
+
+static ssize_t request_reader_fields(
+                void *cls,
+                uint64_t pos,
+                char *buf,
+                size_t max) {
+
+        RequestMeta *m = cls;
+        int r;
+        size_t n, k;
+
+        assert(m);
+        assert(buf);
+        assert(max > 0);
+        assert(pos >= m->delta);
+
+        pos -= m->delta;
+
+        while (pos >= m->size) {
+                off_t sz;
+                const void *d;
+                size_t l;
+
+                /* End of this field, so let's serialize the next
+                 * one */
+
+                if (m->n_fields_set &&
+                    m->n_fields <= 0)
+                        return MHD_CONTENT_READER_END_OF_STREAM;
+
+                r = sd_journal_enumerate_unique(m->journal, &d, &l);
+                if (r < 0) {
+                        log_error("Failed to advance field index: %s", strerror(-r));
+                        return MHD_CONTENT_READER_END_WITH_ERROR;
+                } else if (r == 0)
+                        return MHD_CONTENT_READER_END_OF_STREAM;
+
+                pos -= m->size;
+                m->delta += m->size;
+
+                if (m->n_fields_set)
+                        m->n_fields -= 1;
+
+                if (m->tmp)
+                        rewind(m->tmp);
+                else {
+                        m->tmp = tmpfile();
+                        if (!m->tmp) {
+                                log_error("Failed to create temporary file: %m");
+                                return MHD_CONTENT_READER_END_WITH_ERROR;
+                        }
+                }
+
+                r = output_field(m->tmp, m->mode, d, l);
+                if (r < 0) {
+                        log_error("Failed to serialize item: %s", strerror(-r));
+                        return MHD_CONTENT_READER_END_WITH_ERROR;
+                }
+
+                sz = ftello(m->tmp);
+                if (sz == (off_t) -1) {
+                        log_error("Failed to retrieve file position: %m");
+                        return MHD_CONTENT_READER_END_WITH_ERROR;
+                }
+
+                m->size = (uint64_t) sz;
+        }
+
+        if (fseeko(m->tmp, pos, SEEK_SET) < 0) {
+                log_error("Failed to seek to position: %m");
+                return MHD_CONTENT_READER_END_WITH_ERROR;
+        }
+
+        n = m->size - pos;
+        if (n > max)
+                n = max;
+
+        errno = 0;
+        k = fread(buf, 1, n, m->tmp);
+        if (k != n) {
+                log_error("Failed to read from file: %s", errno ? strerror(errno) : "Premature EOF");
+                return MHD_CONTENT_READER_END_WITH_ERROR;
+        }
+
+        return (ssize_t) k;
+}
+
+static int request_handler_fields(
+                struct MHD_Connection *connection,
+                const char *field,
+                void *connection_cls) {
+
+        struct MHD_Response *response;
+        RequestMeta *m;
+        int r;
+
+        assert(connection);
+        assert(connection_cls);
+
+        m = request_meta(connection_cls);
+        if (!m)
+                return respond_oom(connection);
+
+        r = open_journal(m);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
+
+        if (request_parse_accept(m, connection) < 0)
+                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n");
+
+        r = sd_journal_query_unique(m->journal, field);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to query unique fields.\n");
+
+        response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 4*1024, request_reader_fields, m, NULL);
+        if (!response)
+                return respond_oom(connection);
+
+        MHD_add_response_header(response, "Content-Type", mime_types[m->mode == OUTPUT_JSON ? OUTPUT_JSON : OUTPUT_SHORT]);
+
+        r = MHD_queue_response(connection, MHD_HTTP_OK, response);
+        MHD_destroy_response(response);
+
+        return r;
+}
+
+static int request_handler_redirect(
+                struct MHD_Connection *connection,
+                const char *target) {
+
+        char *page;
+        struct MHD_Response *response;
+        int ret;
+
+        assert(connection);
+        assert(target);
+
+        if (asprintf(&page, "<html><body>Please continue to the <a href=\"%s\">journal browser</a>.</body></html>", target) < 0)
+                return respond_oom(connection);
+
+        response = MHD_create_response_from_buffer(strlen(page), page, MHD_RESPMEM_MUST_FREE);
+        if (!response) {
+                free(page);
+                return respond_oom(connection);
+        }
+
+        MHD_add_response_header(response, "Content-Type", "text/html");
+        MHD_add_response_header(response, "Location", target);
+
+        ret = MHD_queue_response(connection, MHD_HTTP_MOVED_PERMANENTLY, response);
+        MHD_destroy_response(response);
+
+        return ret;
+}
+
+static int request_handler_file(
+                struct MHD_Connection *connection,
+                const char *path,
+                const char *mime_type) {
+
+        struct MHD_Response *response;
+        int ret;
+        _cleanup_close_ int fd = -1;
+        struct stat st;
+
+        assert(connection);
+        assert(path);
+        assert(mime_type);
+
+        fd = open(path, O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
+                return respond_error(connection, MHD_HTTP_NOT_FOUND, "Failed to open file %s: %m\n", path);
+
+        if (fstat(fd, &st) < 0)
+                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to stat file: %m\n");
+
+        response = MHD_create_response_from_fd_at_offset(st.st_size, fd, 0);
+        if (!response)
+                return respond_oom(connection);
+
+        fd = -1;
+
+        MHD_add_response_header(response, "Content-Type", mime_type);
+
+        ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+        MHD_destroy_response(response);
+
+        return ret;
+}
+
+static int request_handler_machine(
+                struct MHD_Connection *connection,
+                void **connection_cls) {
+
+        struct MHD_Response *response;
+        RequestMeta *m;
+        int r;
+        _cleanup_free_ char* hostname = NULL, *os_name = NULL;
+        uint64_t cutoff_from, cutoff_to, usage;
+        char *json;
+        sd_id128_t mid, bid;
+        const char *v = "bare";
+
+        assert(connection);
+
+        m = request_meta(connection_cls);
+        if (!m)
+                return respond_oom(connection);
+
+        r = open_journal(m);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
+
+        r = sd_id128_get_machine(&mid);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine machine ID: %s\n", strerror(-r));
+
+        r = sd_id128_get_boot(&bid);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine boot ID: %s\n", strerror(-r));
+
+        hostname = gethostname_malloc();
+        if (!hostname)
+                return respond_oom(connection);
+
+        r = sd_journal_get_usage(m->journal, &usage);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r));
+
+        r = sd_journal_get_cutoff_realtime_usec(m->journal, &cutoff_from, &cutoff_to);
+        if (r < 0)
+                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r));
+
+        parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL);
+
+        detect_virtualization(&v);
+
+        r = asprintf(&json,
+                     "{ \"machine_id\" : \"" SD_ID128_FORMAT_STR "\","
+                     "\"boot_id\" : \"" SD_ID128_FORMAT_STR "\","
+                     "\"hostname\" : \"%s\","
+                     "\"os_pretty_name\" : \"%s\","
+                     "\"virtualization\" : \"%s\","
+                     "\"usage\" : \"%llu\","
+                     "\"cutoff_from_realtime\" : \"%llu\","
+                     "\"cutoff_to_realtime\" : \"%llu\" }\n",
+                     SD_ID128_FORMAT_VAL(mid),
+                     SD_ID128_FORMAT_VAL(bid),
+                     hostname_cleanup(hostname),
+                     os_name ? os_name : "Linux",
+                     v,
+                     (unsigned long long) usage,
+                     (unsigned long long) cutoff_from,
+                     (unsigned long long) cutoff_to);
+
+        if (r < 0)
+                return respond_oom(connection);
+
+        response = MHD_create_response_from_buffer(strlen(json), json, MHD_RESPMEM_MUST_FREE);
+        if (!response) {
+                free(json);
+                return respond_oom(connection);
+        }
+
+        MHD_add_response_header(response, "Content-Type", "application/json");
+        r = MHD_queue_response(connection, MHD_HTTP_OK, response);
+        MHD_destroy_response(response);
+
+        return r;
+}
+
+static int request_handler(
+                void *cls,
+                struct MHD_Connection *connection,
+                const char *url,
+                const char *method,
+                const char *version,
+                const char *upload_data,
+                size_t *upload_data_size,
+                void **connection_cls) {
+
+        assert(connection);
+        assert(url);
+        assert(method);
+
+        if (!streq(method, "GET"))
+                return MHD_NO;
+
+        if (streq(url, "/"))
+                return request_handler_redirect(connection, "/browse");
+
+        if (streq(url, "/entries"))
+                return request_handler_entries(connection, connection_cls);
+
+        if (startswith(url, "/fields/"))
+                return request_handler_fields(connection, url + 8, connection_cls);
+
+        if (streq(url, "/browse"))
+                return request_handler_file(connection, DOCUMENT_ROOT "/browse.html", "text/html");
+
+        if (streq(url, "/machine"))
+                return request_handler_machine(connection, connection_cls);
+
+        return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n");
+}
+
+int main(int argc, char *argv[]) {
+        struct MHD_Daemon *d = NULL;
+        int r = EXIT_FAILURE, n;
+
+        if (argc > 1) {
+                log_error("This program does not take arguments.");
+                goto finish;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        n = sd_listen_fds(1);
+        if (n < 0) {
+                log_error("Failed to determine passed sockets: %s", strerror(-n));
+                goto finish;
+        } else if (n > 1) {
+                log_error("Can't listen on more than one socket.");
+                goto finish;
+        } else if (n > 0) {
+                d = MHD_start_daemon(
+                                MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG,
+                                19531,
+                                NULL, NULL,
+                                request_handler, NULL,
+                                MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START,
+                                MHD_OPTION_NOTIFY_COMPLETED, request_meta_free, NULL,
+                                MHD_OPTION_END);
+        } else {
+                d = MHD_start_daemon(
+                                MHD_USE_DEBUG|MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL,
+                                19531,
+                                NULL, NULL,
+                                request_handler, NULL,
+                                MHD_OPTION_NOTIFY_COMPLETED, request_meta_free, NULL,
+                                MHD_OPTION_END);
+        }
+
+        if (!d) {
+                log_error("Failed to start daemon!");
+                goto finish;
+        }
+
+        pause();
+
+        r = EXIT_SUCCESS;
+
+finish:
+        if (d)
+                MHD_stop_daemon(d);
+
+        return r;
+}
diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
new file mode 100644 (file)
index 0000000..97de0e7
--- /dev/null
@@ -0,0 +1,129 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <systemd/sd-id128.h>
+
+#include "journal-def.h"
+#include "list.h"
+#include "hashmap.h"
+#include "journal-file.h"
+
+typedef struct Match Match;
+typedef struct Location Location;
+typedef struct Directory Directory;
+
+typedef enum MatchType {
+        MATCH_DISCRETE,
+        MATCH_OR_TERM,
+        MATCH_AND_TERM
+} MatchType;
+
+struct Match {
+        MatchType type;
+        Match *parent;
+        LIST_FIELDS(Match, matches);
+
+        /* For concrete matches */
+        char *data;
+        size_t size;
+        le64_t le_hash;
+
+        /* For terms */
+        LIST_HEAD(Match, matches);
+};
+
+typedef enum LocationType {
+        /* The first and last entries, resp. */
+        LOCATION_HEAD,
+        LOCATION_TAIL,
+
+        /* We already read the entry we currently point to, and the
+         * next one to read should probably not be this one again. */
+        LOCATION_DISCRETE,
+
+        /* We should seek to the precise location specified, and
+         * return it, as we haven't read it yet. */
+        LOCATION_SEEK
+} LocationType;
+
+struct Location {
+        LocationType type;
+
+        uint64_t seqnum;
+        sd_id128_t seqnum_id;
+        bool seqnum_set;
+
+        uint64_t realtime;
+        bool realtime_set;
+
+        uint64_t monotonic;
+        sd_id128_t boot_id;
+        bool monotonic_set;
+
+        uint64_t xor_hash;
+        bool xor_hash_set;
+};
+
+struct Directory {
+        char *path;
+        int wd;
+        bool is_root;
+};
+
+struct sd_journal {
+        int flags;
+
+        char *path;
+
+        Hashmap *files;
+        MMapCache *mmap;
+
+        Location current_location;
+
+        JournalFile *current_file;
+        uint64_t current_field;
+
+        Hashmap *directories_by_path;
+        Hashmap *directories_by_wd;
+
+        int inotify_fd;
+
+        Match *level0, *level1;
+
+        unsigned current_invalidate_counter, last_invalidate_counter;
+
+        char *unique_field;
+        JournalFile *unique_file;
+        uint64_t unique_offset;
+
+        bool on_network;
+
+        size_t data_threshold;
+};
+
+char *journal_make_match_string(sd_journal *j);
+void journal_print_header(sd_journal *j);
diff --git a/src/journal/journal-qrcode.c b/src/journal/journal-qrcode.c
new file mode 100644 (file)
index 0000000..10a14e4
--- /dev/null
@@ -0,0 +1,138 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <qrencode.h>
+
+#include "journal-qrcode.h"
+
+#define WHITE_ON_BLACK "\033[40;37;1m"
+#define NORMAL "\033[0m"
+
+static void print_border(FILE *output, unsigned width) {
+        unsigned x, y;
+
+        /* Four rows of border */
+        for (y = 0; y < 4; y += 2) {
+                fputs(WHITE_ON_BLACK, output);
+
+                for (x = 0; x < 4 + width + 4; x++)
+                        fputs("\342\226\210", output);
+
+                fputs(NORMAL "\n", output);
+        }
+}
+
+int print_qr_code(
+                FILE *output,
+                const void *seed,
+                size_t seed_size,
+                uint64_t start,
+                uint64_t interval,
+                const char *hn,
+                sd_id128_t machine) {
+
+        FILE *f;
+        char *url = NULL;
+        size_t url_size = 0, i;
+        QRcode* qr;
+        unsigned x, y;
+
+        assert(seed);
+        assert(seed_size > 0);
+
+        f = open_memstream(&url, &url_size);
+        if (!f)
+                return -ENOMEM;
+
+        fputs("fss://", f);
+
+        for (i = 0; i < seed_size; i++) {
+                if (i > 0 && i % 3 == 0)
+                        fputc('-', f);
+                fprintf(f, "%02x", ((uint8_t*) seed)[i]);
+        }
+
+        fprintf(f, "/%llx-%llx?machine=" SD_ID128_FORMAT_STR,
+                (unsigned long long) start,
+                (unsigned long long) interval,
+                SD_ID128_FORMAT_VAL(machine));
+
+        if (hn)
+                fprintf(f, ";hostname=%s", hn);
+
+        if (ferror(f)) {
+                fclose(f);
+                free(url);
+                return -ENOMEM;
+        }
+
+        fclose(f);
+
+        qr = QRcode_encodeString(url, 0, QR_ECLEVEL_L, QR_MODE_8, 1);
+        free(url);
+
+        if (!qr)
+                return -ENOMEM;
+
+        print_border(output, qr->width);
+
+        for (y = 0; y < (unsigned) qr->width; y += 2) {
+                const uint8_t *row1, *row2;
+
+                row1 = qr->data + qr->width * y;
+                row2 = row1 + qr->width;
+
+                fputs(WHITE_ON_BLACK, output);
+                for (x = 0; x < 4; x++)
+                        fputs("\342\226\210", output);
+
+                for (x = 0; x < (unsigned) qr->width; x ++) {
+                        bool a, b;
+
+                        a = row1[x] & 1;
+                        b = (y+1) < (unsigned) qr->width ? (row2[x] & 1) : false;
+
+                        if (a && b)
+                                fputc(' ', output);
+                        else if (a)
+                                fputs("\342\226\204", output);
+                        else if (b)
+                                fputs("\342\226\200", output);
+                        else
+                                fputs("\342\226\210", output);
+                }
+
+                for (x = 0; x < 4; x++)
+                        fputs("\342\226\210", output);
+                fputs(NORMAL "\n", output);
+        }
+
+        print_border(output, qr->width);
+
+        QRcode_free(qr);
+        return 0;
+}
diff --git a/src/journal/journal-qrcode.h b/src/journal/journal-qrcode.h
new file mode 100644 (file)
index 0000000..da6244c
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+#include <systemd/sd-id128.h>
+
+int print_qr_code(FILE *f, const void *seed, size_t seed_size, uint64_t start, uint64_t interval, const char *hn, sd_id128_t machine);
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
new file mode 100644 (file)
index 0000000..d5ec73e
--- /dev/null
@@ -0,0 +1,622 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <printf.h>
+
+#define SD_JOURNAL_SUPPRESS_LOCATION
+
+#include "sd-journal.h"
+#include "util.h"
+#include "socket-util.h"
+
+#define SNDBUF_SIZE (8*1024*1024)
+
+#define ALLOCA_CODE_FUNC(f, func)                 \
+        do {                                      \
+                size_t _fl;                       \
+                const char *_func = (func);       \
+                char **_f = &(f);                 \
+                _fl = strlen(_func) + 1;          \
+                *_f = alloca(_fl + 10);           \
+                memcpy(*_f, "CODE_FUNC=", 10);    \
+                memcpy(*_f + 10, _func, _fl);     \
+        } while(false)
+
+/* We open a single fd, and we'll share it with the current process,
+ * all its threads, and all its subprocesses. This means we need to
+ * initialize it atomically, and need to operate on it atomically
+ * never assuming we are the only user */
+
+static int journal_fd(void) {
+        int fd;
+        static int fd_plus_one = 0;
+
+retry:
+        if (fd_plus_one > 0)
+                return fd_plus_one - 1;
+
+        fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+        if (fd < 0)
+                return -errno;
+
+        fd_inc_sndbuf(fd, SNDBUF_SIZE);
+
+        if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) {
+                close_nointr_nofail(fd);
+                goto retry;
+        }
+
+        return fd;
+}
+
+_public_ int sd_journal_print(int priority, const char *format, ...) {
+        int r;
+        va_list ap;
+
+        va_start(ap, format);
+        r = sd_journal_printv(priority, format, ap);
+        va_end(ap);
+
+        return r;
+}
+
+_public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
+
+        /* FIXME: Instead of limiting things to LINE_MAX we could do a
+           C99 variable-length array on the stack here in a loop. */
+
+        char buffer[8 + LINE_MAX], p[11]; struct iovec iov[2];
+
+        if (priority < 0 || priority > 7)
+                return -EINVAL;
+
+        if (!format)
+                return -EINVAL;
+
+        snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK);
+        char_array_0(p);
+
+        memcpy(buffer, "MESSAGE=", 8);
+        vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
+        char_array_0(buffer);
+
+        zero(iov);
+        IOVEC_SET_STRING(iov[0], buffer);
+        IOVEC_SET_STRING(iov[1], p);
+
+        return sd_journal_sendv(iov, 2);
+}
+
+static int fill_iovec_sprintf(const char *format, va_list ap, int extra, struct iovec **_iov) {
+        int r, n = 0, i = 0, j;
+        struct iovec *iov = NULL;
+        int saved_errno;
+
+        assert(_iov);
+        saved_errno = errno;
+
+        if (extra > 0) {
+                n = MAX(extra * 2, extra + 4);
+                iov = malloc0(n * sizeof(struct iovec));
+                if (!iov) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                i = extra;
+        }
+
+        while (format) {
+                struct iovec *c;
+                char *buffer;
+                va_list aq;
+
+                if (i >= n) {
+                        n = MAX(i*2, 4);
+                        c = realloc(iov, n * sizeof(struct iovec));
+                        if (!c) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        iov = c;
+                }
+
+                va_copy(aq, ap);
+                if (vasprintf(&buffer, format, aq) < 0) {
+                        va_end(aq);
+                        r = -ENOMEM;
+                        goto fail;
+                }
+                va_end(aq);
+
+                VA_FORMAT_ADVANCE(format, ap);
+
+                IOVEC_SET_STRING(iov[i++], buffer);
+
+                format = va_arg(ap, char *);
+        }
+
+        *_iov = iov;
+
+        errno = saved_errno;
+        return i;
+
+fail:
+        for (j = 0; j < i; j++)
+                free(iov[j].iov_base);
+
+        free(iov);
+
+        errno = saved_errno;
+        return r;
+}
+
+_public_ int sd_journal_send(const char *format, ...) {
+        int r, i, j;
+        va_list ap;
+        struct iovec *iov = NULL;
+
+        va_start(ap, format);
+        i = fill_iovec_sprintf(format, ap, 0, &iov);
+        va_end(ap);
+
+        if (_unlikely_(i < 0)) {
+                r = i;
+                goto finish;
+        }
+
+        r = sd_journal_sendv(iov, i);
+
+finish:
+        for (j = 0; j < i; j++)
+                free(iov[j].iov_base);
+
+        free(iov);
+
+        return r;
+}
+
+_public_ int sd_journal_sendv(const struct iovec *iov, int n) {
+        int fd, buffer_fd;
+        struct iovec *w;
+        uint64_t *l;
+        int r, i, j = 0;
+        struct msghdr mh;
+        struct sockaddr_un sa;
+        ssize_t k;
+        int saved_errno;
+        union {
+                struct cmsghdr cmsghdr;
+                uint8_t buf[CMSG_SPACE(sizeof(int))];
+        } control;
+        struct cmsghdr *cmsg;
+        /* We use /dev/shm instead of /tmp here, since we want this to
+         * be a tmpfs, and one that is available from early boot on
+         * and where unprivileged users can create files. */
+        char path[] = "/dev/shm/journal.XXXXXX";
+        bool have_syslog_identifier = false;
+
+        if (_unlikely_(!iov))
+                return -EINVAL;
+
+        if (_unlikely_(n <= 0))
+                return -EINVAL;
+
+        saved_errno = errno;
+
+        w = alloca(sizeof(struct iovec) * n * 5 + 3);
+        l = alloca(sizeof(uint64_t) * n);
+
+        for (i = 0; i < n; i++) {
+                char *c, *nl;
+
+                if (_unlikely_(!iov[i].iov_base || iov[i].iov_len <= 1)) {
+                        r = -EINVAL;
+                        goto finish;
+                }
+
+                c = memchr(iov[i].iov_base, '=', iov[i].iov_len);
+                if (_unlikely_(!c || c == iov[i].iov_base)) {
+                        r = -EINVAL;
+                        goto finish;
+                }
+
+                have_syslog_identifier = have_syslog_identifier ||
+                        (c == (char *) iov[i].iov_base + 17 &&
+                         memcmp(iov[i].iov_base, "SYSLOG_IDENTIFIER", 17) == 0);
+
+                nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
+                if (nl) {
+                        if (_unlikely_(nl < c)) {
+                                r = -EINVAL;
+                                goto finish;
+                        }
+
+                        /* Already includes a newline? Bummer, then
+                         * let's write the variable name, then a
+                         * newline, then the size (64bit LE), followed
+                         * by the data and a final newline */
+
+                        w[j].iov_base = iov[i].iov_base;
+                        w[j].iov_len = c - (char*) iov[i].iov_base;
+                        j++;
+
+                        IOVEC_SET_STRING(w[j++], "\n");
+
+                        l[i] = htole64(iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1);
+                        w[j].iov_base = &l[i];
+                        w[j].iov_len = sizeof(uint64_t);
+                        j++;
+
+                        w[j].iov_base = c + 1;
+                        w[j].iov_len = iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1;
+                        j++;
+
+                } else
+                        /* Nothing special? Then just add the line and
+                         * append a newline */
+                        w[j++] = iov[i];
+
+                IOVEC_SET_STRING(w[j++], "\n");
+        }
+
+        if (!have_syslog_identifier &&
+            string_is_safe(program_invocation_short_name)) {
+
+                /* Implicitly add program_invocation_short_name, if it
+                 * is not set explicitly. We only do this for
+                 * program_invocation_short_name, and nothing else
+                 * since everything else is much nicer to retrieve
+                 * from the outside. */
+
+                IOVEC_SET_STRING(w[j++], "SYSLOG_IDENTIFIER=");
+                IOVEC_SET_STRING(w[j++], program_invocation_short_name);
+                IOVEC_SET_STRING(w[j++], "\n");
+        }
+
+        fd = journal_fd();
+        if (_unlikely_(fd < 0)) {
+                r = fd;
+                goto finish;
+        }
+
+        zero(sa);
+        sa.sun_family = AF_UNIX;
+        strncpy(sa.sun_path, "/run/systemd/journal/socket", sizeof(sa.sun_path));
+
+        zero(mh);
+        mh.msg_name = &sa;
+        mh.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path);
+        mh.msg_iov = w;
+        mh.msg_iovlen = j;
+
+        k = sendmsg(fd, &mh, MSG_NOSIGNAL);
+        if (k >= 0) {
+                r = 0;
+                goto finish;
+        }
+
+        if (errno != EMSGSIZE && errno != ENOBUFS) {
+                r = -errno;
+                goto finish;
+        }
+
+        /* Message doesn't fit... Let's dump the data in a temporary
+         * file and just pass a file descriptor of it to the other
+         * side */
+
+        buffer_fd = mkostemp(path, O_CLOEXEC|O_RDWR);
+        if (buffer_fd < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (unlink(path) < 0) {
+                close_nointr_nofail(buffer_fd);
+                r = -errno;
+                goto finish;
+        }
+
+        n = writev(buffer_fd, w, j);
+        if (n < 0) {
+                close_nointr_nofail(buffer_fd);
+                r = -errno;
+                goto finish;
+        }
+
+        mh.msg_iov = NULL;
+        mh.msg_iovlen = 0;
+
+        zero(control);
+        mh.msg_control = &control;
+        mh.msg_controllen = sizeof(control);
+
+        cmsg = CMSG_FIRSTHDR(&mh);
+        cmsg->cmsg_level = SOL_SOCKET;
+        cmsg->cmsg_type = SCM_RIGHTS;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+        memcpy(CMSG_DATA(cmsg), &buffer_fd, sizeof(int));
+
+        mh.msg_controllen = cmsg->cmsg_len;
+
+        k = sendmsg(fd, &mh, MSG_NOSIGNAL);
+        close_nointr_nofail(buffer_fd);
+
+        if (k < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        r = 0;
+
+finish:
+        errno = saved_errno;
+
+        return r;
+}
+
+static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) {
+        size_t n, k, r;
+        int saved_errno;
+
+        saved_errno = errno;
+
+        k = isempty(message) ? 0 : strlen(message) + 2;
+        n = 8 + k + 256 + 1;
+
+        for (;;) {
+                char buffer[n];
+                char* j;
+
+                errno = 0;
+                j = strerror_r(saved_errno, buffer + 8 + k, n - 8 - k);
+                if (errno == 0) {
+                        char error[6 + 10 + 1]; /* for a 32bit value */
+
+                        if (j != buffer + 8 + k)
+                                memmove(buffer + 8 + k, j, strlen(j)+1);
+
+                        memcpy(buffer, "MESSAGE=", 8);
+
+                        if (k > 0) {
+                                memcpy(buffer + 8, message, k - 2);
+                                memcpy(buffer + 8 + k - 2, ": ", 2);
+                        }
+
+                        snprintf(error, sizeof(error), "ERRNO=%u", saved_errno);
+                        char_array_0(error);
+
+                        IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3");
+                        IOVEC_SET_STRING(iov[skip+1], buffer);
+                        IOVEC_SET_STRING(iov[skip+2], error);
+
+                        r = sd_journal_sendv(iov, skip + 3);
+
+                        errno = saved_errno;
+                        return r;
+                }
+
+                if (errno != ERANGE) {
+                        r = -errno;
+                        errno = saved_errno;
+                        return r;
+                }
+
+                n *= 2;
+        }
+}
+
+_public_ int sd_journal_perror(const char *message) {
+        struct iovec iovec[3];
+
+        return fill_iovec_perror_and_send(message, 0, iovec);
+}
+
+_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
+        union sockaddr_union sa;
+        int fd;
+        char *header;
+        size_t l;
+        ssize_t r;
+
+        if (priority < 0 || priority > 7)
+                return -EINVAL;
+
+        fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
+        if (fd < 0)
+                return -errno;
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path));
+
+        r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+        if (r < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        if (shutdown(fd, SHUT_RD) < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        fd_inc_sndbuf(fd, SNDBUF_SIZE);
+
+        if (!identifier)
+                identifier = "";
+
+        l = strlen(identifier);
+        header = alloca(l + 1 + 1 + 2 + 2 + 2 + 2 + 2);
+
+        memcpy(header, identifier, l);
+        header[l++] = '\n';
+        header[l++] = '\n'; /* unit id */
+        header[l++] = '0' + priority;
+        header[l++] = '\n';
+        header[l++] = '0' + !!level_prefix;
+        header[l++] = '\n';
+        header[l++] = '0';
+        header[l++] = '\n';
+        header[l++] = '0';
+        header[l++] = '\n';
+        header[l++] = '0';
+        header[l++] = '\n';
+
+        r = loop_write(fd, header, l, false);
+        if (r < 0) {
+                close_nointr_nofail(fd);
+                return (int) r;
+        }
+
+        if ((size_t) r != l) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        return fd;
+}
+
+_public_ int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) {
+        int r;
+        va_list ap;
+
+        va_start(ap, format);
+        r = sd_journal_printv_with_location(priority, file, line, func, format, ap);
+        va_end(ap);
+
+        return r;
+}
+
+_public_ int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) {
+        char buffer[8 + LINE_MAX], p[11];
+        struct iovec iov[5];
+        char *f;
+
+        if (priority < 0 || priority > 7)
+                return -EINVAL;
+
+        if (_unlikely_(!format))
+                return -EINVAL;
+
+        snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK);
+        char_array_0(p);
+
+        memcpy(buffer, "MESSAGE=", 8);
+        vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
+        char_array_0(buffer);
+
+        /* func is initialized from __func__ which is not a macro, but
+         * a static const char[], hence cannot easily be prefixed with
+         * CODE_FUNC=, hence let's do it manually here. */
+        ALLOCA_CODE_FUNC(f, func);
+
+        zero(iov);
+        IOVEC_SET_STRING(iov[0], buffer);
+        IOVEC_SET_STRING(iov[1], p);
+        IOVEC_SET_STRING(iov[2], file);
+        IOVEC_SET_STRING(iov[3], line);
+        IOVEC_SET_STRING(iov[4], f);
+
+        return sd_journal_sendv(iov, ELEMENTSOF(iov));
+}
+
+_public_ int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) {
+        int r, i, j;
+        va_list ap;
+        struct iovec *iov = NULL;
+        char *f;
+
+        va_start(ap, format);
+        i = fill_iovec_sprintf(format, ap, 3, &iov);
+        va_end(ap);
+
+        if (_unlikely_(i < 0)) {
+                r = i;
+                goto finish;
+        }
+
+        ALLOCA_CODE_FUNC(f, func);
+
+        IOVEC_SET_STRING(iov[0], file);
+        IOVEC_SET_STRING(iov[1], line);
+        IOVEC_SET_STRING(iov[2], f);
+
+        r = sd_journal_sendv(iov, i);
+
+finish:
+        for (j = 3; j < i; j++)
+                free(iov[j].iov_base);
+
+        free(iov);
+
+        return r;
+}
+
+_public_ int sd_journal_sendv_with_location(
+                const char *file, const char *line,
+                const char *func,
+                const struct iovec *iov, int n) {
+
+        struct iovec *niov;
+        char *f;
+
+        if (_unlikely_(!iov))
+                return -EINVAL;
+
+        if (_unlikely_(n <= 0))
+                return -EINVAL;
+
+        niov = alloca(sizeof(struct iovec) * (n + 3));
+        memcpy(niov, iov, sizeof(struct iovec) * n);
+
+        ALLOCA_CODE_FUNC(f, func);
+
+        IOVEC_SET_STRING(niov[n++], file);
+        IOVEC_SET_STRING(niov[n++], line);
+        IOVEC_SET_STRING(niov[n++], f);
+
+        return sd_journal_sendv(niov, n);
+}
+
+_public_ int sd_journal_perror_with_location(
+                const char *file, const char *line,
+                const char *func,
+                const char *message) {
+
+        struct iovec iov[6];
+        char *f;
+
+        ALLOCA_CODE_FUNC(f, func);
+
+        IOVEC_SET_STRING(iov[0], file);
+        IOVEC_SET_STRING(iov[1], line);
+        IOVEC_SET_STRING(iov[2], f);
+
+        return fill_iovec_perror_and_send(message, 3, iov);
+}
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
new file mode 100644 (file)
index 0000000..731f6c7
--- /dev/null
@@ -0,0 +1,318 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <unistd.h>
+
+#ifdef HAVE_XATTR
+#include <attr/xattr.h>
+#endif
+
+#include "journal-def.h"
+#include "journal-file.h"
+#include "journal-vacuum.h"
+#include "sd-id128.h"
+#include "util.h"
+
+struct vacuum_info {
+        off_t usage;
+        char *filename;
+
+        uint64_t realtime;
+        sd_id128_t seqnum_id;
+        uint64_t seqnum;
+
+        bool have_seqnum;
+};
+
+static int vacuum_compare(const void *_a, const void *_b) {
+        const struct vacuum_info *a, *b;
+
+        a = _a;
+        b = _b;
+
+        if (a->have_seqnum && b->have_seqnum &&
+            sd_id128_equal(a->seqnum_id, b->seqnum_id)) {
+                if (a->seqnum < b->seqnum)
+                        return -1;
+                else if (a->seqnum > b->seqnum)
+                        return 1;
+                else
+                        return 0;
+        }
+
+        if (a->realtime < b->realtime)
+                return -1;
+        else if (a->realtime > b->realtime)
+                return 1;
+        else if (a->have_seqnum && b->have_seqnum)
+                return memcmp(&a->seqnum_id, &b->seqnum_id, 16);
+        else
+                return strcmp(a->filename, b->filename);
+}
+
+static void patch_realtime(
+                const char *dir,
+                const char *fn,
+                const struct stat *st,
+                unsigned long long *realtime) {
+
+        usec_t x;
+
+#ifdef HAVE_XATTR
+        uint64_t crtime;
+        _cleanup_free_ const char *path = NULL;
+#endif
+
+        /* The timestamp was determined by the file name, but let's
+         * see if the file might actually be older than the file name
+         * suggested... */
+
+        assert(dir);
+        assert(fn);
+        assert(st);
+        assert(realtime);
+
+        x = timespec_load(&st->st_ctim);
+        if (x > 0 && x != (usec_t) -1 && x < *realtime)
+                *realtime = x;
+
+        x = timespec_load(&st->st_atim);
+        if (x > 0 && x != (usec_t) -1 && x < *realtime)
+                *realtime = x;
+
+        x = timespec_load(&st->st_mtim);
+        if (x > 0 && x != (usec_t) -1 && x < *realtime)
+                *realtime = x;
+
+#ifdef HAVE_XATTR
+        /* Let's read the original creation time, if possible. Ideally
+         * we'd just query the creation time the FS might provide, but
+         * unfortunately there's currently no sane API to query
+         * it. Hence let's implement this manually... */
+
+        /* Unfortunately there is is not fgetxattrat(), so we need to
+         * go via path here. :-( */
+
+        path = strjoin(dir, "/", fn, NULL);
+        if (!path)
+                return;
+
+        if (getxattr(path, "user.crtime_usec", &crtime, sizeof(crtime)) == sizeof(crtime)) {
+                crtime = le64toh(crtime);
+
+                if (crtime > 0 && crtime != (uint64_t) -1 && crtime < *realtime)
+                        *realtime = crtime;
+        }
+#endif
+}
+
+int journal_directory_vacuum(
+                const char *directory,
+                uint64_t max_use,
+                uint64_t min_free,
+                usec_t max_retention_usec,
+                usec_t *oldest_usec) {
+
+        DIR *d;
+        int r = 0;
+        struct vacuum_info *list = NULL;
+        unsigned n_list = 0, n_allocated = 0, i;
+        uint64_t sum = 0;
+        usec_t retention_limit = 0;
+
+        assert(directory);
+
+        if (max_use <= 0 && min_free <= 0 && max_retention_usec <= 0)
+                return 0;
+
+        if (max_retention_usec > 0) {
+                retention_limit = now(CLOCK_REALTIME);
+                if (retention_limit > max_retention_usec)
+                        retention_limit -= max_retention_usec;
+                else
+                        max_retention_usec = retention_limit = 0;
+        }
+
+        d = opendir(directory);
+        if (!d)
+                return -errno;
+
+        for (;;) {
+                int k;
+                struct dirent *de;
+                union dirent_storage buf;
+                size_t q;
+                struct stat st;
+                char *p;
+                unsigned long long seqnum = 0, realtime;
+                sd_id128_t seqnum_id;
+                bool have_seqnum;
+
+                k = readdir_r(d, &buf.de, &de);
+                if (k != 0) {
+                        r = -k;
+                        goto finish;
+                }
+
+                if (!de)
+                        break;
+
+                if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
+                        continue;
+
+                if (!S_ISREG(st.st_mode))
+                        continue;
+
+                q = strlen(de->d_name);
+
+                if (endswith(de->d_name, ".journal")) {
+
+                        /* Vacuum archived files */
+
+                        if (q < 1 + 32 + 1 + 16 + 1 + 16 + 8)
+                                continue;
+
+                        if (de->d_name[q-8-16-1] != '-' ||
+                            de->d_name[q-8-16-1-16-1] != '-' ||
+                            de->d_name[q-8-16-1-16-1-32-1] != '@')
+                                continue;
+
+                        p = strdup(de->d_name);
+                        if (!p) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        de->d_name[q-8-16-1-16-1] = 0;
+                        if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) {
+                                free(p);
+                                continue;
+                        }
+
+                        if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) {
+                                free(p);
+                                continue;
+                        }
+
+                        have_seqnum = true;
+
+                } else if (endswith(de->d_name, ".journal~")) {
+                        unsigned long long tmp;
+
+                        /* Vacuum corrupted files */
+
+                        if (q < 1 + 16 + 1 + 16 + 8 + 1)
+                                continue;
+
+                        if (de->d_name[q-1-8-16-1] != '-' ||
+                            de->d_name[q-1-8-16-1-16-1] != '@')
+                                continue;
+
+                        p = strdup(de->d_name);
+                        if (!p) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) {
+                                free(p);
+                                continue;
+                        }
+
+                        have_seqnum = false;
+                } else
+                        /* We do not vacuum active files or unknown files! */
+                        continue;
+
+                patch_realtime(directory, de->d_name, &st, &realtime);
+
+                if (n_list >= n_allocated) {
+                        struct vacuum_info *j;
+
+                        n_allocated = MAX(n_allocated * 2U, 8U);
+                        j = realloc(list, n_allocated * sizeof(struct vacuum_info));
+                        if (!j) {
+                                free(p);
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        list = j;
+                }
+
+                list[n_list].filename = p;
+                list[n_list].usage = 512UL * (uint64_t) st.st_blocks;
+                list[n_list].seqnum = seqnum;
+                list[n_list].realtime = realtime;
+                list[n_list].seqnum_id = seqnum_id;
+                list[n_list].have_seqnum = have_seqnum;
+
+                sum += list[n_list].usage;
+
+                n_list ++;
+        }
+
+        if (n_list > 0)
+                qsort(list, n_list, sizeof(struct vacuum_info), vacuum_compare);
+
+        for (i = 0; i < n_list; i++) {
+                struct statvfs ss;
+
+                if (fstatvfs(dirfd(d), &ss) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if ((max_retention_usec <= 0 || list[i].realtime >= retention_limit) &&
+                    (max_use <= 0 || sum <= max_use) &&
+                    (min_free <= 0 || (uint64_t) ss.f_bavail * (uint64_t) ss.f_bsize >= min_free))
+                        break;
+
+                if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) {
+                        log_debug("Deleted archived journal %s/%s.", directory, list[i].filename);
+
+                        if ((uint64_t) list[i].usage > sum)
+                                sum -= list[i].usage;
+                        else
+                                sum = 0;
+
+                } else if (errno != ENOENT)
+                        log_warning("Failed to delete %s/%s: %m", directory, list[i].filename);
+        }
+
+        if (oldest_usec && i < n_list && (*oldest_usec == 0 || list[i].realtime < *oldest_usec))
+                *oldest_usec = list[i].realtime;
+
+finish:
+        for (i = 0; i < n_list; i++)
+                free(list[i].filename);
+
+        free(list);
+
+        if (d)
+                closedir(d);
+
+        return r;
+}
diff --git a/src/journal/journal-vacuum.h b/src/journal/journal-vacuum.h
new file mode 100644 (file)
index 0000000..f5e3e52
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+
+int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free, usec_t max_retention_usec, usec_t *oldest_usec);
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
new file mode 100644 (file)
index 0000000..ed28b45
--- /dev/null
@@ -0,0 +1,1163 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stddef.h>
+
+#include "util.h"
+#include "macro.h"
+#include "journal-def.h"
+#include "journal-file.h"
+#include "journal-authenticate.h"
+#include "journal-verify.h"
+#include "lookup3.h"
+#include "compress.h"
+#include "fsprg.h"
+
+static int journal_file_object_verify(JournalFile *f, Object *o) {
+        uint64_t i;
+
+        assert(f);
+        assert(o);
+
+        /* This does various superficial tests about the length an
+         * possible field values. It does not follow any references to
+         * other objects. */
+
+        if ((o->object.flags & OBJECT_COMPRESSED) &&
+            o->object.type != OBJECT_DATA)
+                return -EBADMSG;
+
+        switch (o->object.type) {
+
+        case OBJECT_DATA: {
+                uint64_t h1, h2;
+
+                if (le64toh(o->data.entry_offset) <= 0 ||
+                    le64toh(o->data.n_entries) <= 0)
+                        return -EBADMSG;
+
+                if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0)
+                        return -EBADMSG;
+
+                h1 = le64toh(o->data.hash);
+
+                if (o->object.flags & OBJECT_COMPRESSED) {
+#ifdef HAVE_XZ
+                        void *b = NULL;
+                        uint64_t alloc = 0, b_size;
+
+                        if (!uncompress_blob(o->data.payload,
+                                             le64toh(o->object.size) - offsetof(Object, data.payload),
+                                             &b, &alloc, &b_size, 0))
+                                return -EBADMSG;
+
+                        h2 = hash64(b, b_size);
+                        free(b);
+#else
+                        return -EPROTONOSUPPORT;
+#endif
+                } else
+                        h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload));
+
+                if (h1 != h2)
+                        return -EBADMSG;
+
+                if (!VALID64(o->data.next_hash_offset) ||
+                    !VALID64(o->data.next_field_offset) ||
+                    !VALID64(o->data.entry_offset) ||
+                    !VALID64(o->data.entry_array_offset))
+                        return -EBADMSG;
+
+                break;
+        }
+
+        case OBJECT_FIELD:
+                if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0)
+                        return -EBADMSG;
+
+                if (!VALID64(o->field.next_hash_offset) ||
+                    !VALID64(o->field.head_data_offset))
+                        return -EBADMSG;
+                break;
+
+        case OBJECT_ENTRY:
+                if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0)
+                        return -EBADMSG;
+
+                if ((le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem) <= 0)
+                        return -EBADMSG;
+
+                if (le64toh(o->entry.seqnum) <= 0 ||
+                    !VALID_REALTIME(le64toh(o->entry.realtime)) ||
+                    !VALID_MONOTONIC(le64toh(o->entry.monotonic)))
+                        return -EBADMSG;
+
+                for (i = 0; i < journal_file_entry_n_items(o); i++) {
+                        if (o->entry.items[i].object_offset == 0 ||
+                            !VALID64(o->entry.items[i].object_offset))
+                                return -EBADMSG;
+                }
+
+                break;
+
+        case OBJECT_DATA_HASH_TABLE:
+        case OBJECT_FIELD_HASH_TABLE:
+                if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0)
+                        return -EBADMSG;
+
+                if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0)
+                        return -EBADMSG;
+
+                for (i = 0; i < journal_file_hash_table_n_items(o); i++) {
+                        if (o->hash_table.items[i].head_hash_offset != 0 &&
+                            !VALID64(le64toh(o->hash_table.items[i].head_hash_offset)))
+                                return -EBADMSG;
+                        if (o->hash_table.items[i].tail_hash_offset != 0 &&
+                            !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset)))
+                                return -EBADMSG;
+
+                        if ((o->hash_table.items[i].head_hash_offset != 0) !=
+                            (o->hash_table.items[i].tail_hash_offset != 0))
+                                return -EBADMSG;
+                }
+
+                break;
+
+        case OBJECT_ENTRY_ARRAY:
+                if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) % sizeof(le64_t) != 0)
+                        return -EBADMSG;
+
+                if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0)
+                        return -EBADMSG;
+
+                if (!VALID64(o->entry_array.next_entry_array_offset))
+                        return -EBADMSG;
+
+                for (i = 0; i < journal_file_entry_array_n_items(o); i++)
+                        if (o->entry_array.items[i] != 0 &&
+                            !VALID64(o->entry_array.items[i]))
+                                return -EBADMSG;
+
+                break;
+
+        case OBJECT_TAG:
+                if (le64toh(o->object.size) != sizeof(TagObject))
+                        return -EBADMSG;
+
+                if (!VALID_EPOCH(o->tag.epoch))
+                        return -EBADMSG;
+
+                break;
+        }
+
+        return 0;
+}
+
+static void draw_progress(uint64_t p, usec_t *last_usec) {
+        unsigned n, i, j, k;
+        usec_t z, x;
+
+        if (!on_tty())
+                return;
+
+        z = now(CLOCK_MONOTONIC);
+        x = *last_usec;
+
+        if (x != 0 && x + 40 * USEC_PER_MSEC > z)
+                return;
+
+        *last_usec = z;
+
+        n = (3 * columns()) / 4;
+        j = (n * (unsigned) p) / 65535ULL;
+        k = n - j;
+
+        fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
+
+        for (i = 0; i < j; i++)
+                fputs("\xe2\x96\x88", stdout);
+
+        fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
+        for (i = 0; i < k; i++)
+                fputs("\xe2\x96\x91", stdout);
+
+        printf(" %3lu%%", 100LU * (unsigned long) p / 65535LU);
+
+        fputs("\r\x1B[?25h", stdout);
+        fflush(stdout);
+}
+
+static void flush_progress(void) {
+        unsigned n, i;
+
+        if (!on_tty())
+                return;
+
+        n = (3 * columns()) / 4;
+
+        putchar('\r');
+
+        for (i = 0; i < n + 5; i++)
+                putchar(' ');
+
+        putchar('\r');
+        fflush(stdout);
+}
+
+static int write_uint64(int fd, uint64_t p) {
+        ssize_t k;
+
+        k = write(fd, &p, sizeof(p));
+        if (k < 0)
+                return -errno;
+        if (k != sizeof(p))
+                return -EIO;
+
+        return 0;
+}
+
+static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
+        uint64_t a, b;
+        int r;
+
+        assert(m);
+        assert(fd >= 0);
+
+        /* Bisection ... */
+
+        a = 0; b = n;
+        while (a < b) {
+                uint64_t c, *z;
+
+                c = (a + b) / 2;
+
+                r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
+                if (r < 0)
+                        return r;
+
+                if (*z == p)
+                        return 1;
+
+                if (a + 1 >= b)
+                        return 0;
+
+                if (p < *z)
+                        b = c;
+                else
+                        a = c;
+        }
+
+        return 0;
+}
+
+static int entry_points_to_data(
+                JournalFile *f,
+                int entry_fd,
+                uint64_t n_entries,
+                uint64_t entry_p,
+                uint64_t data_p) {
+
+        int r;
+        uint64_t i, n, a;
+        Object *o;
+        bool found = false;
+
+        assert(f);
+        assert(entry_fd >= 0);
+
+        if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) {
+                log_error("Data object references invalid entry at %llu", (unsigned long long) data_p);
+                return -EBADMSG;
+        }
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, entry_p, &o);
+        if (r < 0)
+                return r;
+
+        n = journal_file_entry_n_items(o);
+        for (i = 0; i < n; i++)
+                if (le64toh(o->entry.items[i].object_offset) == data_p) {
+                        found = true;
+                        break;
+                }
+
+        if (!found) {
+                log_error("Data object not referenced by linked entry at %llu", (unsigned long long) data_p);
+                return -EBADMSG;
+        }
+
+        /* Check if this entry is also in main entry array. Since the
+         * main entry array has already been verified we can rely on
+         * its consistency.*/
+
+        i = 0;
+        n = le64toh(f->header->n_entries);
+        a = le64toh(f->header->entry_array_offset);
+
+        while (i < n) {
+                uint64_t m, u;
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
+                if (r < 0)
+                        return r;
+
+                m = journal_file_entry_array_n_items(o);
+                u = MIN(n - i, m);
+
+                if (entry_p <= le64toh(o->entry_array.items[u-1])) {
+                        uint64_t x, y, z;
+
+                        x = 0;
+                        y = u;
+
+                        while (x < y) {
+                                z = (x + y) / 2;
+
+                                if (le64toh(o->entry_array.items[z]) == entry_p)
+                                        return 0;
+
+                                if (x + 1 >= y)
+                                        break;
+
+                                if (entry_p < le64toh(o->entry_array.items[z]))
+                                        y = z;
+                                else
+                                        x = z;
+                        }
+
+                        log_error("Entry object doesn't exist in main entry array at %llu", (unsigned long long) entry_p);
+                        return -EBADMSG;
+                }
+
+                i += u;
+                a = le64toh(o->entry_array.next_entry_array_offset);
+        }
+
+        return 0;
+}
+
+static int verify_data(
+                JournalFile *f,
+                Object *o, uint64_t p,
+                int entry_fd, uint64_t n_entries,
+                int entry_array_fd, uint64_t n_entry_arrays) {
+
+        uint64_t i, n, a, last, q;
+        int r;
+
+        assert(f);
+        assert(o);
+        assert(entry_fd >= 0);
+        assert(entry_array_fd >= 0);
+
+        n = le64toh(o->data.n_entries);
+        a = le64toh(o->data.entry_array_offset);
+
+        /* We already checked this earlier */
+        assert(n > 0);
+
+        last = q = le64toh(o->data.entry_offset);
+        r = entry_points_to_data(f, entry_fd, n_entries, q, p);
+        if (r < 0)
+                return r;
+
+        i = 1;
+        while (i < n) {
+                uint64_t next, m, j;
+
+                if (a == 0) {
+                        log_error("Array chain too short at %llu", (unsigned long long) p);
+                        return -EBADMSG;
+                }
+
+                if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
+                        log_error("Invalid array at %llu", (unsigned long long) p);
+                        return -EBADMSG;
+                }
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
+                if (r < 0)
+                        return r;
+
+                next = le64toh(o->entry_array.next_entry_array_offset);
+                if (next != 0 && next <= a) {
+                        log_error("Array chain has cycle at %llu", (unsigned long long) p);
+                        return -EBADMSG;
+                }
+
+                m = journal_file_entry_array_n_items(o);
+                for (j = 0; i < n && j < m; i++, j++) {
+
+                        q = le64toh(o->entry_array.items[j]);
+                        if (q <= last) {
+                                log_error("Data object's entry array not sorted at %llu", (unsigned long long) p);
+                                return -EBADMSG;
+                        }
+                        last = q;
+
+                        r = entry_points_to_data(f, entry_fd, n_entries, q, p);
+                        if (r < 0)
+                                return r;
+
+                        /* Pointer might have moved, reposition */
+                        r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
+                        if (r < 0)
+                                return r;
+                }
+
+                a = next;
+        }
+
+        return 0;
+}
+
+static int verify_hash_table(
+                JournalFile *f,
+                int data_fd, uint64_t n_data,
+                int entry_fd, uint64_t n_entries,
+                int entry_array_fd, uint64_t n_entry_arrays,
+                usec_t *last_usec,
+                bool show_progress) {
+
+        uint64_t i, n;
+        int r;
+
+        assert(f);
+        assert(data_fd >= 0);
+        assert(entry_fd >= 0);
+        assert(entry_array_fd >= 0);
+        assert(last_usec);
+
+        n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
+        for (i = 0; i < n; i++) {
+                uint64_t last = 0, p;
+
+                if (show_progress)
+                        draw_progress(0xC000 + (0x3FFF * i / n), last_usec);
+
+                p = le64toh(f->data_hash_table[i].head_hash_offset);
+                while (p != 0) {
+                        Object *o;
+                        uint64_t next;
+
+                        if (!contains_uint64(f->mmap, data_fd, n_data, p)) {
+                                log_error("Invalid data object at hash entry %llu of %llu",
+                                          (unsigned long long) i, (unsigned long long) n);
+                                return -EBADMSG;
+                        }
+
+                        r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+                        if (r < 0)
+                                return r;
+
+                        next = le64toh(o->data.next_hash_offset);
+                        if (next != 0 && next <= p) {
+                                log_error("Hash chain has a cycle in hash entry %llu of %llu",
+                                          (unsigned long long) i, (unsigned long long) n);
+                                return -EBADMSG;
+                        }
+
+                        if (le64toh(o->data.hash) % n != i) {
+                                log_error("Hash value mismatch in hash entry %llu of %llu",
+                                          (unsigned long long) i, (unsigned long long) n);
+                                return -EBADMSG;
+                        }
+
+                        r = verify_data(f, o, p, entry_fd, n_entries, entry_array_fd, n_entry_arrays);
+                        if (r < 0)
+                                return r;
+
+                        last = p;
+                        p = next;
+                }
+
+                if (last != le64toh(f->data_hash_table[i].tail_hash_offset)) {
+                        log_error("Tail hash pointer mismatch in hash table");
+                        return -EBADMSG;
+                }
+        }
+
+        return 0;
+}
+
+static int data_object_in_hash_table(JournalFile *f, uint64_t hash, uint64_t p) {
+        uint64_t n, h, q;
+        int r;
+        assert(f);
+
+        n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
+        h = hash % n;
+
+        q = le64toh(f->data_hash_table[h].head_hash_offset);
+        while (q != 0) {
+                Object *o;
+
+                if (p == q)
+                        return 1;
+
+                r = journal_file_move_to_object(f, OBJECT_DATA, q, &o);
+                if (r < 0)
+                        return r;
+
+                q = le64toh(o->data.next_hash_offset);
+        }
+
+        return 0;
+}
+
+static int verify_entry(
+                JournalFile *f,
+                Object *o, uint64_t p,
+                int data_fd, uint64_t n_data) {
+
+        uint64_t i, n;
+        int r;
+
+        assert(f);
+        assert(o);
+        assert(data_fd >= 0);
+
+        n = journal_file_entry_n_items(o);
+        for (i = 0; i < n; i++) {
+                uint64_t q, h;
+                Object *u;
+
+                q = le64toh(o->entry.items[i].object_offset);
+                h = le64toh(o->entry.items[i].hash);
+
+                if (!contains_uint64(f->mmap, data_fd, n_data, q)) {
+                        log_error("Invalid data object at entry %llu",
+                                  (unsigned long long) p);
+                                return -EBADMSG;
+                        }
+
+                r = journal_file_move_to_object(f, OBJECT_DATA, q, &u);
+                if (r < 0)
+                        return r;
+
+                if (le64toh(u->data.hash) != h) {
+                        log_error("Hash mismatch for data object at entry %llu",
+                                  (unsigned long long) p);
+                        return -EBADMSG;
+                }
+
+                r = data_object_in_hash_table(f, h, q);
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        log_error("Data object missing from hash at entry %llu",
+                                  (unsigned long long) p);
+                        return -EBADMSG;
+                }
+        }
+
+        return 0;
+}
+
+static int verify_entry_array(
+                JournalFile *f,
+                int data_fd, uint64_t n_data,
+                int entry_fd, uint64_t n_entries,
+                int entry_array_fd, uint64_t n_entry_arrays,
+                usec_t *last_usec,
+                bool show_progress) {
+
+        uint64_t i = 0, a, n, last = 0;
+        int r;
+
+        assert(f);
+        assert(data_fd >= 0);
+        assert(entry_fd >= 0);
+        assert(entry_array_fd >= 0);
+        assert(last_usec);
+
+        n = le64toh(f->header->n_entries);
+        a = le64toh(f->header->entry_array_offset);
+        while (i < n) {
+                uint64_t next, m, j;
+                Object *o;
+
+                if (show_progress)
+                        draw_progress(0x8000 + (0x3FFF * i / n), last_usec);
+
+                if (a == 0) {
+                        log_error("Array chain too short at %llu of %llu",
+                                  (unsigned long long) i, (unsigned long long) n);
+                        return -EBADMSG;
+                }
+
+                if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
+                        log_error("Invalid array at %llu of %llu",
+                                  (unsigned long long) i, (unsigned long long) n);
+                        return -EBADMSG;
+                }
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
+                if (r < 0)
+                        return r;
+
+                next = le64toh(o->entry_array.next_entry_array_offset);
+                if (next != 0 && next <= a) {
+                        log_error("Array chain has cycle at %llu of %llu",
+                                  (unsigned long long) i, (unsigned long long) n);
+                        return -EBADMSG;
+                }
+
+                m = journal_file_entry_array_n_items(o);
+                for (j = 0; i < n && j < m; i++, j++) {
+                        uint64_t p;
+
+                        p = le64toh(o->entry_array.items[j]);
+                        if (p <= last) {
+                                log_error("Entry array not sorted at %llu of %llu",
+                                          (unsigned long long) i, (unsigned long long) n);
+                                return -EBADMSG;
+                        }
+                        last = p;
+
+                        if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) {
+                                log_error("Invalid array entry at %llu of %llu",
+                                          (unsigned long long) i, (unsigned long long) n);
+                                return -EBADMSG;
+                        }
+
+                        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
+                        if (r < 0)
+                                return r;
+
+                        r = verify_entry(f, o, p, data_fd, n_data);
+                        if (r < 0)
+                                return r;
+
+                        /* Pointer might have moved, reposition */
+                        r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
+                        if (r < 0)
+                                return r;
+                }
+
+                a = next;
+        }
+
+        return 0;
+}
+
+int journal_file_verify(
+                JournalFile *f,
+                const char *key,
+                usec_t *first_contained, usec_t *last_validated, usec_t *last_contained,
+                bool show_progress) {
+        int r;
+        Object *o;
+        uint64_t p = 0, last_epoch = 0, last_tag_realtime = 0, last_sealed_realtime = 0;
+
+        uint64_t entry_seqnum = 0, entry_monotonic = 0, entry_realtime = 0;
+        sd_id128_t entry_boot_id;
+        bool entry_seqnum_set = false, entry_monotonic_set = false, entry_realtime_set = false, found_main_entry_array = false;
+        uint64_t n_weird = 0, n_objects = 0, n_entries = 0, n_data = 0, n_fields = 0, n_data_hash_tables = 0, n_field_hash_tables = 0, n_entry_arrays = 0, n_tags = 0;
+        usec_t last_usec = 0;
+        int data_fd = -1, entry_fd = -1, entry_array_fd = -1;
+        char data_path[] = "/var/tmp/journal-data-XXXXXX",
+                entry_path[] = "/var/tmp/journal-entry-XXXXXX",
+                entry_array_path[] = "/var/tmp/journal-entry-array-XXXXXX";
+        unsigned i;
+        bool found_last;
+#ifdef HAVE_GCRYPT
+        uint64_t last_tag = 0;
+#endif
+        assert(f);
+
+        if (key) {
+#ifdef HAVE_GCRYPT
+                r = journal_file_parse_verification_key(f, key);
+                if (r < 0) {
+                        log_error("Failed to parse seed.");
+                        return r;
+                }
+#else
+                return -ENOTSUP;
+#endif
+        } else if (f->seal)
+                return -ENOKEY;
+
+        data_fd = mkostemp(data_path, O_CLOEXEC);
+        if (data_fd < 0) {
+                log_error("Failed to create data file: %m");
+                r = -errno;
+                goto fail;
+        }
+        unlink(data_path);
+
+        entry_fd = mkostemp(entry_path, O_CLOEXEC);
+        if (entry_fd < 0) {
+                log_error("Failed to create entry file: %m");
+                r = -errno;
+                goto fail;
+        }
+        unlink(entry_path);
+
+        entry_array_fd = mkostemp(entry_array_path, O_CLOEXEC);
+        if (entry_array_fd < 0) {
+                log_error("Failed to create entry array file: %m");
+                r = -errno;
+                goto fail;
+        }
+        unlink(entry_array_path);
+
+#ifdef HAVE_GCRYPT
+        if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0)
+#else
+        if (f->header->compatible_flags != 0)
+#endif
+        {
+                log_error("Cannot verify file with unknown extensions.");
+                r = -ENOTSUP;
+                goto fail;
+        }
+
+        for (i = 0; i < sizeof(f->header->reserved); i++)
+                if (f->header->reserved[i] != 0) {
+                        log_error("Reserved field in non-zero.");
+                        r = -EBADMSG;
+                        goto fail;
+                }
+
+        /* First iteration: we go through all objects, verify the
+         * superficial structure, headers, hashes. */
+
+        p = le64toh(f->header->header_size);
+        while (p != 0) {
+                if (show_progress)
+                        draw_progress(0x7FFF * p / le64toh(f->header->tail_object_offset), &last_usec);
+
+                r = journal_file_move_to_object(f, -1, p, &o);
+                if (r < 0) {
+                        log_error("Invalid object at %llu", (unsigned long long) p);
+                        goto fail;
+                }
+
+                if (p > le64toh(f->header->tail_object_offset)) {
+                        log_error("Invalid tail object pointer");
+                        r = -EBADMSG;
+                        goto fail;
+                }
+
+                if (p == le64toh(f->header->tail_object_offset))
+                        found_last = true;
+
+                n_objects ++;
+
+                r = journal_file_object_verify(f, o);
+                if (r < 0) {
+                        log_error("Invalid object contents at %llu", (unsigned long long) p);
+                        goto fail;
+                }
+
+                if ((o->object.flags & OBJECT_COMPRESSED) && !JOURNAL_HEADER_COMPRESSED(f->header)) {
+                        log_error("Compressed object in file without compression at %llu", (unsigned long long) p);
+                        r = -EBADMSG;
+                        goto fail;
+                }
+
+                switch (o->object.type) {
+
+                case OBJECT_DATA:
+                        r = write_uint64(data_fd, p);
+                        if (r < 0)
+                                goto fail;
+
+                        n_data++;
+                        break;
+
+                case OBJECT_FIELD:
+                        n_fields++;
+                        break;
+
+                case OBJECT_ENTRY:
+                        if (JOURNAL_HEADER_SEALED(f->header) && n_tags <= 0) {
+                                log_error("First entry before first tag at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        r = write_uint64(entry_fd, p);
+                        if (r < 0)
+                                goto fail;
+
+                        if (le64toh(o->entry.realtime) < last_tag_realtime) {
+                                log_error("Older entry after newer tag at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        if (!entry_seqnum_set &&
+                            le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) {
+                                log_error("Head entry sequence number incorrect at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        if (entry_seqnum_set &&
+                            entry_seqnum >= le64toh(o->entry.seqnum)) {
+                                log_error("Entry sequence number out of synchronization at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        entry_seqnum = le64toh(o->entry.seqnum);
+                        entry_seqnum_set = true;
+
+                        if (entry_monotonic_set &&
+                            sd_id128_equal(entry_boot_id, o->entry.boot_id) &&
+                            entry_monotonic > le64toh(o->entry.monotonic)) {
+                                log_error("Entry timestamp out of synchronization at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        entry_monotonic = le64toh(o->entry.monotonic);
+                        entry_boot_id = o->entry.boot_id;
+                        entry_monotonic_set = true;
+
+                        if (!entry_realtime_set &&
+                            le64toh(o->entry.realtime) != le64toh(f->header->head_entry_realtime)) {
+                                log_error("Head entry realtime timestamp incorrect");
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        entry_realtime = le64toh(o->entry.realtime);
+                        entry_realtime_set = true;
+
+                        n_entries ++;
+                        break;
+
+                case OBJECT_DATA_HASH_TABLE:
+                        if (n_data_hash_tables > 1) {
+                                log_error("More than one data hash table at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        if (le64toh(f->header->data_hash_table_offset) != p + offsetof(HashTableObject, items) ||
+                            le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
+                                log_error("Header fields for data hash table invalid");
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        n_data_hash_tables++;
+                        break;
+
+                case OBJECT_FIELD_HASH_TABLE:
+                        if (n_field_hash_tables > 1) {
+                                log_error("More than one field hash table at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        if (le64toh(f->header->field_hash_table_offset) != p + offsetof(HashTableObject, items) ||
+                            le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
+                                log_error("Header fields for field hash table invalid");
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        n_field_hash_tables++;
+                        break;
+
+                case OBJECT_ENTRY_ARRAY:
+                        r = write_uint64(entry_array_fd, p);
+                        if (r < 0)
+                                goto fail;
+
+                        if (p == le64toh(f->header->entry_array_offset)) {
+                                if (found_main_entry_array) {
+                                        log_error("More than one main entry array at %llu", (unsigned long long) p);
+                                        r = -EBADMSG;
+                                        goto fail;
+                                }
+
+                                found_main_entry_array = true;
+                        }
+
+                        n_entry_arrays++;
+                        break;
+
+                case OBJECT_TAG:
+                        if (!JOURNAL_HEADER_SEALED(f->header)) {
+                                log_error("Tag object in file without sealing at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        if (le64toh(o->tag.seqnum) != n_tags + 1) {
+                                log_error("Tag sequence number out of synchronization at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        if (le64toh(o->tag.epoch) < last_epoch) {
+                                log_error("Epoch sequence out of synchronization at %llu", (unsigned long long) p);
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+#ifdef HAVE_GCRYPT
+                        if (f->seal) {
+                                uint64_t q, rt;
+
+                                log_debug("Checking tag %llu..", (unsigned long long) le64toh(o->tag.seqnum));
+
+                                rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec;
+                                if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) {
+                                        log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p);
+                                        r = -EBADMSG;
+                                        goto fail;
+                                }
+
+                                /* OK, now we know the epoch. So let's now set
+                                 * it, and calculate the HMAC for everything
+                                 * since the last tag. */
+                                r = journal_file_fsprg_seek(f, le64toh(o->tag.epoch));
+                                if (r < 0)
+                                        goto fail;
+
+                                r = journal_file_hmac_start(f);
+                                if (r < 0)
+                                        goto fail;
+
+                                if (last_tag == 0) {
+                                        r = journal_file_hmac_put_header(f);
+                                        if (r < 0)
+                                                goto fail;
+
+                                        q = le64toh(f->header->header_size);
+                                } else
+                                        q = last_tag;
+
+                                while (q <= p) {
+                                        r = journal_file_move_to_object(f, -1, q, &o);
+                                        if (r < 0)
+                                                goto fail;
+
+                                        r = journal_file_hmac_put_object(f, -1, o, q);
+                                        if (r < 0)
+                                                goto fail;
+
+                                        q = q + ALIGN64(le64toh(o->object.size));
+                                }
+
+                                /* Position might have changed, let's reposition things */
+                                r = journal_file_move_to_object(f, -1, p, &o);
+                                if (r < 0)
+                                        goto fail;
+
+                                if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) {
+                                        log_error("Tag failed verification at %llu", (unsigned long long) p);
+                                        r = -EBADMSG;
+                                        goto fail;
+                                }
+
+                                f->hmac_running = false;
+                                last_tag_realtime = rt;
+                                last_sealed_realtime = entry_realtime;
+                        }
+
+                        last_tag = p + ALIGN64(le64toh(o->object.size));
+#endif
+
+                        last_epoch = le64toh(o->tag.epoch);
+
+                        n_tags ++;
+                        break;
+
+                default:
+                        n_weird ++;
+                }
+
+                if (p == le64toh(f->header->tail_object_offset))
+                        p = 0;
+                else
+                        p = p + ALIGN64(le64toh(o->object.size));
+        }
+
+        if (!found_last) {
+                log_error("Tail object pointer dead");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (n_objects != le64toh(f->header->n_objects)) {
+                log_error("Object number mismatch");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (n_entries != le64toh(f->header->n_entries)) {
+                log_error("Entry number mismatch");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_data) &&
+            n_data != le64toh(f->header->n_data)) {
+                log_error("Data number mismatch");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_fields) &&
+            n_fields != le64toh(f->header->n_fields)) {
+                log_error("Field number mismatch");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_tags) &&
+            n_tags != le64toh(f->header->n_tags)) {
+                log_error("Tag number mismatch");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays) &&
+            n_entry_arrays != le64toh(f->header->n_entry_arrays)) {
+                log_error("Entry array number mismatch");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (n_data_hash_tables != 1) {
+                log_error("Missing data hash table");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (n_field_hash_tables != 1) {
+                log_error("Missing field hash table");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (!found_main_entry_array) {
+                log_error("Missing entry array");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (entry_seqnum_set &&
+            entry_seqnum != le64toh(f->header->tail_entry_seqnum)) {
+                log_error("Invalid tail seqnum");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (entry_monotonic_set &&
+            (!sd_id128_equal(entry_boot_id, f->header->boot_id) ||
+             entry_monotonic != le64toh(f->header->tail_entry_monotonic))) {
+                log_error("Invalid tail monotonic timestamp");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        if (entry_realtime_set && entry_realtime != le64toh(f->header->tail_entry_realtime)) {
+                log_error("Invalid tail realtime timestamp");
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        /* Second iteration: we follow all objects referenced from the
+         * two entry points: the object hash table and the entry
+         * array. We also check that everything referenced (directly
+         * or indirectly) in the data hash table also exists in the
+         * entry array, and vice versa. Note that we do not care for
+         * unreferenced objects. We only care that everything that is
+         * referenced is consistent. */
+
+        r = verify_entry_array(f,
+                               data_fd, n_data,
+                               entry_fd, n_entries,
+                               entry_array_fd, n_entry_arrays,
+                               &last_usec,
+                               show_progress);
+        if (r < 0)
+                goto fail;
+
+        r = verify_hash_table(f,
+                              data_fd, n_data,
+                              entry_fd, n_entries,
+                              entry_array_fd, n_entry_arrays,
+                              &last_usec,
+                              show_progress);
+        if (r < 0)
+                goto fail;
+
+        if (show_progress)
+                flush_progress();
+
+        mmap_cache_close_fd(f->mmap, data_fd);
+        mmap_cache_close_fd(f->mmap, entry_fd);
+        mmap_cache_close_fd(f->mmap, entry_array_fd);
+
+        close_nointr_nofail(data_fd);
+        close_nointr_nofail(entry_fd);
+        close_nointr_nofail(entry_array_fd);
+
+        if (first_contained)
+                *first_contained = le64toh(f->header->head_entry_realtime);
+        if (last_validated)
+                *last_validated = last_sealed_realtime;
+        if (last_contained)
+                *last_contained = le64toh(f->header->tail_entry_realtime);
+
+        return 0;
+
+fail:
+        if (show_progress)
+                flush_progress();
+
+        log_error("File corruption detected at %s:%llu (of %llu, %llu%%).",
+                  f->path,
+                  (unsigned long long) p,
+                  (unsigned long long) f->last_stat.st_size,
+                  (unsigned long long) (100 * p / f->last_stat.st_size));
+
+        if (data_fd >= 0) {
+                mmap_cache_close_fd(f->mmap, data_fd);
+                close_nointr_nofail(data_fd);
+        }
+
+        if (entry_fd >= 0) {
+                mmap_cache_close_fd(f->mmap, entry_fd);
+                close_nointr_nofail(entry_fd);
+        }
+
+        if (entry_array_fd >= 0) {
+                mmap_cache_close_fd(f->mmap, entry_array_fd);
+                close_nointr_nofail(entry_array_fd);
+        }
+
+        return r;
+}
diff --git a/src/journal/journal-verify.h b/src/journal/journal-verify.h
new file mode 100644 (file)
index 0000000..e392ab6
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journal-file.h"
+
+int journal_file_verify(JournalFile *f, const char *key, usec_t *first_contained, usec_t *last_validated, usec_t *last_contained, bool show_progress);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
new file mode 100644 (file)
index 0000000..a74d43b
--- /dev/null
@@ -0,0 +1,1104 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <locale.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/poll.h>
+#include <time.h>
+#include <getopt.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
+#include <systemd/sd-journal.h>
+
+#include "log.h"
+#include "util.h"
+#include "path-util.h"
+#include "build.h"
+#include "pager.h"
+#include "logs-show.h"
+#include "strv.h"
+#include "journal-internal.h"
+#include "journal-def.h"
+#include "journal-verify.h"
+#include "journal-authenticate.h"
+#include "journal-qrcode.h"
+#include "fsprg.h"
+#include "unit-name.h"
+#include "catalog.h"
+
+#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
+
+static OutputMode arg_output = OUTPUT_SHORT;
+static bool arg_follow = false;
+static bool arg_full = false;
+static bool arg_all = false;
+static bool arg_no_pager = false;
+static unsigned arg_lines = 0;
+static bool arg_no_tail = false;
+static bool arg_quiet = false;
+static bool arg_merge = false;
+static bool arg_this_boot = false;
+static const char *arg_cursor = NULL;
+static const char *arg_directory = NULL;
+static int arg_priorities = 0xFF;
+static const char *arg_verify_key = NULL;
+#ifdef HAVE_GCRYPT
+static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
+#endif
+static usec_t arg_since, arg_until;
+static bool arg_since_set = false, arg_until_set = false;
+static const char *arg_unit = NULL;
+static const char *arg_field = NULL;
+static bool arg_catalog = false;
+
+static enum {
+        ACTION_SHOW,
+        ACTION_NEW_ID128,
+        ACTION_PRINT_HEADER,
+        ACTION_SETUP_KEYS,
+        ACTION_VERIFY,
+        ACTION_DISK_USAGE,
+        ACTION_LIST_CATALOG,
+        ACTION_UPDATE_CATALOG
+} arg_action = ACTION_SHOW;
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] [MATCHES...]\n\n"
+               "Query the journal.\n\n"
+               "Flags:\n"
+               "     --since=DATE        Start showing entries newer or of the specified date\n"
+               "     --until=DATE        Stop showing entries older or of the specified date\n"
+               "  -c --cursor=CURSOR     Start showing entries from specified cursor\n"
+               "  -b --this-boot         Show data only from current boot\n"
+               "  -u --unit=UNIT         Show data only from the specified unit\n"
+               "  -p --priority=RANGE    Show only messages within the specified priority range\n"
+               "  -f --follow            Follow journal\n"
+               "  -n --lines[=INTEGER]   Number of journal entries to show\n"
+               "     --no-tail           Show all lines, even in follow mode\n"
+               "  -o --output=STRING     Change journal output mode (short, short-monotonic,\n"
+               "                         verbose, export, json, json-pretty, json-sse, cat)\n"
+               "  -x --catalog           Add message explanations where available\n"
+               "     --full              Do not ellipsize fields\n"
+               "  -a --all               Show all fields, including long and unprintable\n"
+               "  -q --quiet             Don't show privilege warning\n"
+               "     --no-pager          Do not pipe output into a pager\n"
+               "  -m --merge             Show entries from all available journals\n"
+               "  -D --directory=PATH    Show journal files from directory\n"
+#ifdef HAVE_GCRYPT
+               "     --interval=TIME     Time interval for changing the FSS sealing key\n"
+               "     --verify-key=KEY    Specify FSS verification key\n"
+#endif
+               "\nCommands:\n"
+               "  -h --help              Show this help\n"
+               "     --version           Show package version\n"
+               "     --new-id128         Generate a new 128 Bit ID\n"
+               "     --header            Show journal header information\n"
+               "     --disk-usage        Show total disk usage\n"
+               "  -F --field=FIELD       List all values a certain field takes\n"
+               "     --list-catalog      Show message IDs of all entries in the message catalog\n"
+               "     --update-catalog    Update the message catalog database\n"
+#ifdef HAVE_GCRYPT
+               "     --setup-keys        Generate new FSS key pair\n"
+               "     --verify            Verify journal file consistency\n"
+#endif
+               , program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_NO_PAGER,
+                ARG_NO_TAIL,
+                ARG_NEW_ID128,
+                ARG_HEADER,
+                ARG_FULL,
+                ARG_SETUP_KEYS,
+                ARG_INTERVAL,
+                ARG_VERIFY,
+                ARG_VERIFY_KEY,
+                ARG_DISK_USAGE,
+                ARG_SINCE,
+                ARG_UNTIL,
+                ARG_LIST_CATALOG,
+                ARG_UPDATE_CATALOG
+        };
+
+        static const struct option options[] = {
+                { "help",         no_argument,       NULL, 'h'              },
+                { "version" ,     no_argument,       NULL, ARG_VERSION      },
+                { "no-pager",     no_argument,       NULL, ARG_NO_PAGER     },
+                { "follow",       no_argument,       NULL, 'f'              },
+                { "output",       required_argument, NULL, 'o'              },
+                { "all",          no_argument,       NULL, 'a'              },
+                { "full",         no_argument,       NULL, ARG_FULL         },
+                { "lines",        optional_argument, NULL, 'n'              },
+                { "no-tail",      no_argument,       NULL, ARG_NO_TAIL      },
+                { "new-id128",    no_argument,       NULL, ARG_NEW_ID128    },
+                { "quiet",        no_argument,       NULL, 'q'              },
+                { "merge",        no_argument,       NULL, 'm'              },
+                { "this-boot",    no_argument,       NULL, 'b'              },
+                { "directory",    required_argument, NULL, 'D'              },
+                { "header",       no_argument,       NULL, ARG_HEADER       },
+                { "priority",     required_argument, NULL, 'p'              },
+                { "setup-keys",   no_argument,       NULL, ARG_SETUP_KEYS   },
+                { "interval",     required_argument, NULL, ARG_INTERVAL     },
+                { "verify",       no_argument,       NULL, ARG_VERIFY       },
+                { "verify-key",   required_argument, NULL, ARG_VERIFY_KEY   },
+                { "disk-usage",   no_argument,       NULL, ARG_DISK_USAGE   },
+                { "cursor",       required_argument, NULL, 'c'              },
+                { "since",        required_argument, NULL, ARG_SINCE        },
+                { "until",        required_argument, NULL, ARG_UNTIL        },
+                { "unit",         required_argument, NULL, 'u'              },
+                { "field",        required_argument, NULL, 'F'              },
+                { "catalog",      no_argument,       NULL, 'x'              },
+                { "list-catalog", no_argument,       NULL, ARG_LIST_CATALOG },
+                { "update-catalog",no_argument,      NULL, ARG_UPDATE_CATALOG },
+                { NULL,           0,                 NULL, 0                }
+        };
+
+        int c, r;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:x", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case 'f':
+                        arg_follow = true;
+                        break;
+
+                case 'o':
+                        arg_output = output_mode_from_string(optarg);
+                        if (arg_output < 0) {
+                                log_error("Unknown output format '%s'.", optarg);
+                                return -EINVAL;
+                        }
+
+                        if (arg_output == OUTPUT_EXPORT ||
+                            arg_output == OUTPUT_JSON ||
+                            arg_output == OUTPUT_JSON_PRETTY ||
+                            arg_output == OUTPUT_JSON_SSE ||
+                            arg_output == OUTPUT_CAT)
+                                arg_quiet = true;
+
+                        break;
+
+                case ARG_FULL:
+                        arg_full = true;
+                        break;
+
+                case 'a':
+                        arg_all = true;
+                        break;
+
+                case 'n':
+                        if (optarg) {
+                                r = safe_atou(optarg, &arg_lines);
+                                if (r < 0 || arg_lines <= 0) {
+                                        log_error("Failed to parse lines '%s'", optarg);
+                                        return -EINVAL;
+                                }
+                        } else
+                                arg_lines = 10;
+
+                        break;
+
+                case ARG_NO_TAIL:
+                        arg_no_tail = true;
+                        break;
+
+                case ARG_NEW_ID128:
+                        arg_action = ACTION_NEW_ID128;
+                        break;
+
+                case 'q':
+                        arg_quiet = true;
+                        break;
+
+                case 'm':
+                        arg_merge = true;
+                        break;
+
+                case 'b':
+                        arg_this_boot = true;
+                        break;
+
+                case 'D':
+                        arg_directory = optarg;
+                        break;
+
+                case 'c':
+                        arg_cursor = optarg;
+                        break;
+
+                case ARG_HEADER:
+                        arg_action = ACTION_PRINT_HEADER;
+                        break;
+
+                case ARG_VERIFY:
+                        arg_action = ACTION_VERIFY;
+                        break;
+
+                case ARG_DISK_USAGE:
+                        arg_action = ACTION_DISK_USAGE;
+                        break;
+
+#ifdef HAVE_GCRYPT
+                case ARG_SETUP_KEYS:
+                        arg_action = ACTION_SETUP_KEYS;
+                        break;
+
+
+                case ARG_VERIFY_KEY:
+                        arg_action = ACTION_VERIFY;
+                        arg_verify_key = optarg;
+                        arg_merge = false;
+                        break;
+
+                case ARG_INTERVAL:
+                        r = parse_usec(optarg, &arg_interval);
+                        if (r < 0 || arg_interval <= 0) {
+                                log_error("Failed to parse sealing key change interval: %s", optarg);
+                                return -EINVAL;
+                        }
+                        break;
+#else
+                case ARG_SETUP_KEYS:
+                case ARG_VERIFY_KEY:
+                case ARG_INTERVAL:
+                        log_error("Forward-secure sealing not available.");
+                        return -ENOTSUP;
+#endif
+
+                case 'p': {
+                        const char *dots;
+
+                        dots = strstr(optarg, "..");
+                        if (dots) {
+                                char *a;
+                                int from, to, i;
+
+                                /* a range */
+                                a = strndup(optarg, dots - optarg);
+                                if (!a)
+                                        return log_oom();
+
+                                from = log_level_from_string(a);
+                                to = log_level_from_string(dots + 2);
+                                free(a);
+
+                                if (from < 0 || to < 0) {
+                                        log_error("Failed to parse log level range %s", optarg);
+                                        return -EINVAL;
+                                }
+
+                                arg_priorities = 0;
+
+                                if (from < to) {
+                                        for (i = from; i <= to; i++)
+                                                arg_priorities |= 1 << i;
+                                } else {
+                                        for (i = to; i <= from; i++)
+                                                arg_priorities |= 1 << i;
+                                }
+
+                        } else {
+                                int p, i;
+
+                                p = log_level_from_string(optarg);
+                                if (p < 0) {
+                                        log_error("Unknown log level %s", optarg);
+                                        return -EINVAL;
+                                }
+
+                                arg_priorities = 0;
+
+                                for (i = 0; i <= p; i++)
+                                        arg_priorities |= 1 << i;
+                        }
+
+                        break;
+                }
+
+                case ARG_SINCE:
+                        r = parse_timestamp(optarg, &arg_since);
+                        if (r < 0) {
+                                log_error("Failed to parse timestamp: %s", optarg);
+                                return -EINVAL;
+                        }
+                        arg_since_set = true;
+                        break;
+
+                case ARG_UNTIL:
+                        r = parse_timestamp(optarg, &arg_until);
+                        if (r < 0) {
+                                log_error("Failed to parse timestamp: %s", optarg);
+                                return -EINVAL;
+                        }
+                        arg_until_set = true;
+                        break;
+
+                case 'u':
+                        arg_unit = optarg;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                case 'F':
+                        arg_field = optarg;
+                        break;
+
+                case 'x':
+                        arg_catalog = true;
+                        break;
+
+                case ARG_LIST_CATALOG:
+                        arg_action = ACTION_LIST_CATALOG;
+                        break;
+
+                case ARG_UPDATE_CATALOG:
+                        arg_action = ACTION_UPDATE_CATALOG;
+                        break;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (arg_follow && !arg_no_tail && arg_lines <= 0)
+                arg_lines = 10;
+
+        if (arg_since_set && arg_until_set && arg_since_set > arg_until_set) {
+                log_error("--since= must be before --until=.");
+                return -EINVAL;
+        }
+
+        if (arg_cursor && arg_since_set) {
+                log_error("Please specify either --since= or --cursor=, not both.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+static int generate_new_id128(void) {
+        sd_id128_t id;
+        int r;
+        unsigned i;
+
+        r = sd_id128_randomize(&id);
+        if (r < 0) {
+                log_error("Failed to generate ID: %s", strerror(-r));
+                return r;
+        }
+
+        printf("As string:\n"
+               SD_ID128_FORMAT_STR "\n\n"
+               "As UUID:\n"
+               "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
+               "As macro:\n"
+              "#define MESSAGE_XYZ SD_ID128_MAKE(",
+               SD_ID128_FORMAT_VAL(id),
+               SD_ID128_FORMAT_VAL(id));
+
+        for (i = 0; i < 16; i++)
+                printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
+
+        fputs(")\n", stdout);
+
+        return 0;
+}
+
+static int add_matches(sd_journal *j, char **args) {
+        char **i;
+        int r;
+
+        assert(j);
+
+        STRV_FOREACH(i, args) {
+
+                if (streq(*i, "+"))
+                        r = sd_journal_add_disjunction(j);
+                else if (path_is_absolute(*i)) {
+                        char *p, *t = NULL;
+                        const char *path;
+                        struct stat st;
+
+                        p = canonicalize_file_name(*i);
+                        path = p ? p : *i;
+
+                        if (stat(path, &st) < 0)  {
+                                free(p);
+                                log_error("Couldn't stat file: %m");
+                                return -errno;
+                        }
+
+                        if (S_ISREG(st.st_mode) && (0111 & st.st_mode))
+                                t = strappend("_EXE=", path);
+                        else if (S_ISCHR(st.st_mode))
+                                asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev));
+                        else if (S_ISBLK(st.st_mode))
+                                asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
+                        else {
+                                free(p);
+                                log_error("File is not a device node, regular file or is not executable: %s", *i);
+                                return -EINVAL;
+                        }
+
+                        free(p);
+
+                        if (!t)
+                                return log_oom();
+
+                        r = sd_journal_add_match(j, t, 0);
+                        free(t);
+                } else
+                        r = sd_journal_add_match(j, *i, 0);
+
+                if (r < 0) {
+                        log_error("Failed to add match '%s': %s", *i, strerror(-r));
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
+static int add_this_boot(sd_journal *j) {
+        char match[9+32+1] = "_BOOT_ID=";
+        sd_id128_t boot_id;
+        int r;
+
+        assert(j);
+
+        if (!arg_this_boot)
+                return 0;
+
+        r = sd_id128_get_boot(&boot_id);
+        if (r < 0) {
+                log_error("Failed to get boot id: %s", strerror(-r));
+                return r;
+        }
+
+        sd_id128_to_string(boot_id, match + 9);
+        r = sd_journal_add_match(j, match, strlen(match));
+        if (r < 0) {
+                log_error("Failed to add match: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+static int add_unit(sd_journal *j) {
+        _cleanup_free_ char *m = NULL, *u = NULL;
+        int r;
+
+        assert(j);
+
+        if (isempty(arg_unit))
+                return 0;
+
+        u = unit_name_mangle(arg_unit);
+        if (!u)
+                return log_oom();
+
+        m = strappend("_SYSTEMD_UNIT=", u);
+        if (!m)
+                return log_oom();
+
+        r = sd_journal_add_match(j, m, strlen(m));
+        if (r < 0) {
+                log_error("Failed to add match: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+static int add_priorities(sd_journal *j) {
+        char match[] = "PRIORITY=0";
+        int i, r;
+
+        assert(j);
+
+        if (arg_priorities == 0xFF)
+                return 0;
+
+        for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
+                if (arg_priorities & (1 << i)) {
+                        match[sizeof(match)-2] = '0' + i;
+
+                        r = sd_journal_add_match(j, match, strlen(match));
+                        if (r < 0) {
+                                log_error("Failed to add match: %s", strerror(-r));
+                                return r;
+                        }
+                }
+
+        return 0;
+}
+
+static int setup_keys(void) {
+#ifdef HAVE_GCRYPT
+        size_t mpk_size, seed_size, state_size, i;
+        uint8_t *mpk, *seed, *state;
+        ssize_t l;
+        int fd = -1, r, attr = 0;
+        sd_id128_t machine, boot;
+        char *p = NULL, *k = NULL;
+        struct FSSHeader h;
+        uint64_t n;
+
+        r = sd_id128_get_machine(&machine);
+        if (r < 0) {
+                log_error("Failed to get machine ID: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_id128_get_boot(&boot);
+        if (r < 0) {
+                log_error("Failed to get boot ID: %s", strerror(-r));
+                return r;
+        }
+
+        if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
+                     SD_ID128_FORMAT_VAL(machine)) < 0)
+                return log_oom();
+
+        if (access(p, F_OK) >= 0) {
+                log_error("Sealing key file %s exists already.", p);
+                r = -EEXIST;
+                goto finish;
+        }
+
+        if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
+                     SD_ID128_FORMAT_VAL(machine)) < 0) {
+                r = log_oom();
+                goto finish;
+        }
+
+        mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
+        mpk = alloca(mpk_size);
+
+        seed_size = FSPRG_RECOMMENDED_SEEDLEN;
+        seed = alloca(seed_size);
+
+        state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
+        state = alloca(state_size);
+
+        fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0) {
+                log_error("Failed to open /dev/random: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        log_info("Generating seed...");
+        l = loop_read(fd, seed, seed_size, true);
+        if (l < 0 || (size_t) l != seed_size) {
+                log_error("Failed to read random seed: %s", strerror(EIO));
+                r = -EIO;
+                goto finish;
+        }
+
+        log_info("Generating key pair...");
+        FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
+
+        log_info("Generating sealing key...");
+        FSPRG_GenState0(state, mpk, seed, seed_size);
+
+        assert(arg_interval > 0);
+
+        n = now(CLOCK_REALTIME);
+        n /= arg_interval;
+
+        close_nointr_nofail(fd);
+        fd = mkostemp(k, O_WRONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0) {
+                log_error("Failed to open %s: %m", k);
+                r = -errno;
+                goto finish;
+        }
+
+        /* Enable secure remove, exclusion from dump, synchronous
+         * writing and in-place updating */
+        if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
+                log_warning("FS_IOC_GETFLAGS failed: %m");
+
+        attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
+
+        if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
+                log_warning("FS_IOC_SETFLAGS failed: %m");
+
+        zero(h);
+        memcpy(h.signature, "KSHHRHLP", 8);
+        h.machine_id = machine;
+        h.boot_id = boot;
+        h.header_size = htole64(sizeof(h));
+        h.start_usec = htole64(n * arg_interval);
+        h.interval_usec = htole64(arg_interval);
+        h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
+        h.fsprg_state_size = htole64(state_size);
+
+        l = loop_write(fd, &h, sizeof(h), false);
+        if (l < 0 || (size_t) l != sizeof(h)) {
+                log_error("Failed to write header: %s", strerror(EIO));
+                r = -EIO;
+                goto finish;
+        }
+
+        l = loop_write(fd, state, state_size, false);
+        if (l < 0 || (size_t) l != state_size) {
+                log_error("Failed to write state: %s", strerror(EIO));
+                r = -EIO;
+                goto finish;
+        }
+
+        if (link(k, p) < 0) {
+                log_error("Failed to link file: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if (on_tty()) {
+                fprintf(stderr,
+                        "\n"
+                        "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
+                        "the following local file. This key file is automatically updated when the\n"
+                        "sealing key is advanced. It should not be used on multiple hosts.\n"
+                        "\n"
+                        "\t%s\n"
+                        "\n"
+                        "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
+                        "at a safe location and should not be saved locally on disk.\n"
+                        "\n\t" ANSI_HIGHLIGHT_RED_ON, p);
+                fflush(stderr);
+        }
+        for (i = 0; i < seed_size; i++) {
+                if (i > 0 && i % 3 == 0)
+                        putchar('-');
+                printf("%02x", ((uint8_t*) seed)[i]);
+        }
+
+        printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
+
+        if (on_tty()) {
+                char tsb[FORMAT_TIMESPAN_MAX], *hn;
+
+                fprintf(stderr,
+                        ANSI_HIGHLIGHT_OFF "\n"
+                        "The sealing key is automatically changed every %s.\n",
+                        format_timespan(tsb, sizeof(tsb), arg_interval));
+
+                hn = gethostname_malloc();
+
+                if (hn) {
+                        hostname_cleanup(hn);
+                        fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
+                } else
+                        fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
+
+#ifdef HAVE_QRENCODE
+                /* If this is not an UTF-8 system don't print any QR codes */
+                if (is_locale_utf8()) {
+                        fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
+                        print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
+                }
+#endif
+                free(hn);
+        }
+
+        r = 0;
+
+finish:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        if (k) {
+                unlink(k);
+                free(k);
+        }
+
+        free(p);
+
+        return r;
+#else
+        log_error("Forward-secure sealing not available.");
+        return -ENOTSUP;
+#endif
+}
+
+static int verify(sd_journal *j) {
+        int r = 0;
+        Iterator i;
+        JournalFile *f;
+
+        assert(j);
+
+        log_show_color(true);
+
+        HASHMAP_FOREACH(f, j->files, i) {
+                int k;
+                usec_t first, validated, last;
+
+#ifdef HAVE_GCRYPT
+                if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
+                        log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
+#endif
+
+                k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
+                if (k == -EINVAL) {
+                        /* If the key was invalid give up right-away. */
+                        return k;
+                } else if (k < 0) {
+                        log_warning("FAIL: %s (%s)", f->path, strerror(-k));
+                        r = k;
+                } else {
+                        char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
+                        log_info("PASS: %s", f->path);
+
+                        if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
+                                if (validated > 0) {
+                                        log_info("=> Validated from %s to %s, final %s entries not sealed.",
+                                                 format_timestamp(a, sizeof(a), first),
+                                                 format_timestamp(b, sizeof(b), validated),
+                                                 format_timespan(c, sizeof(c), last > validated ? last - validated : 0));
+                                } else if (last > 0)
+                                        log_info("=> No sealing yet, %s of entries not sealed.",
+                                                 format_timespan(c, sizeof(c), last - first));
+                                else
+                                        log_info("=> No sealing yet, no entries in file.");
+                        }
+                }
+        }
+
+        return r;
+}
+
+static int access_check(void) {
+
+#ifdef HAVE_ACL
+        if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("adm") <= 0) {
+                log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'adm' can always see messages.");
+                return -EACCES;
+        }
+
+        if (!arg_quiet && geteuid() != 0 && in_group("adm") <= 0)
+                log_warning("Showing user generated messages only. Users in the group 'adm' can see all messages. Pass -q to turn this notice off.");
+#else
+        if (geteuid() != 0 && in_group("adm") <= 0) {
+                log_error("No access to messages. Only users in the group 'adm' can see messages.");
+                return -EACCES;
+        }
+#endif
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+        sd_journal *j = NULL;
+        bool need_seek = false;
+        sd_id128_t previous_boot_id;
+        bool previous_boot_id_valid = false;
+        unsigned n_shown = 0;
+
+        setlocale(LC_ALL, "");
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        signal(SIGWINCH, columns_lines_cache_reset);
+
+        if (arg_action == ACTION_NEW_ID128) {
+                r = generate_new_id128();
+                goto finish;
+        }
+
+        if (arg_action == ACTION_SETUP_KEYS) {
+                r = setup_keys();
+                goto finish;
+        }
+
+        if (arg_action == ACTION_LIST_CATALOG)  {
+                r = catalog_list(stdout);
+                if (r < 0)
+                        log_error("Failed to list catalog: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (arg_action == ACTION_UPDATE_CATALOG)  {
+                r = catalog_update();
+                goto finish;
+        }
+
+        r = access_check();
+        if (r < 0)
+                goto finish;
+
+        if (arg_directory)
+                r = sd_journal_open_directory(&j, arg_directory, 0);
+        else
+                r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY);
+        if (r < 0) {
+                log_error("Failed to open journal: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (arg_action == ACTION_VERIFY) {
+                r = verify(j);
+                goto finish;
+        }
+
+        if (arg_action == ACTION_PRINT_HEADER) {
+                journal_print_header(j);
+                r = 0;
+                goto finish;
+        }
+
+        if (arg_action == ACTION_DISK_USAGE) {
+                uint64_t bytes;
+                char sbytes[FORMAT_BYTES_MAX];
+
+                r = sd_journal_get_usage(j, &bytes);
+                if (r < 0)
+                        goto finish;
+
+                printf("Journals take up %s on disk.\n", format_bytes(sbytes, sizeof(sbytes), bytes));
+                r = 0;
+                goto finish;
+        }
+
+        r = add_this_boot(j);
+        if (r < 0)
+                goto finish;
+
+        r = add_unit(j);
+        if (r < 0)
+                goto finish;
+
+        r = add_matches(j, argv + optind);
+        if (r < 0)
+                goto finish;
+
+        r = add_priorities(j);
+        if (r < 0)
+                goto finish;
+
+        if (arg_field) {
+                const void *data;
+                size_t size;
+
+                r = sd_journal_query_unique(j, arg_field);
+                if (r < 0) {
+                        log_error("Failed to query unique data objects: %s", strerror(-r));
+                        goto finish;
+                }
+
+                SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
+                        const void *eq;
+
+                        if (arg_lines > 0 && n_shown >= arg_lines)
+                                break;
+
+                        eq = memchr(data, '=', size);
+                        if (eq)
+                                printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
+                        else
+                                printf("%.*s\n", (int) size, (const char*) data);
+
+                        n_shown ++;
+                }
+
+                r = 0;
+                goto finish;
+        }
+
+        if (arg_cursor) {
+                r = sd_journal_seek_cursor(j, arg_cursor);
+                if (r < 0) {
+                        log_error("Failed to seek to cursor: %s", strerror(-r));
+                        goto finish;
+                }
+
+                r = sd_journal_next(j);
+
+        } else if (arg_since_set) {
+                r = sd_journal_seek_realtime_usec(j, arg_since);
+                if (r < 0) {
+                        log_error("Failed to seek to date: %s", strerror(-r));
+                        goto finish;
+                }
+                r = sd_journal_next(j);
+
+        } else if (arg_lines > 0) {
+                r = sd_journal_seek_tail(j);
+                if (r < 0) {
+                        log_error("Failed to seek to tail: %s", strerror(-r));
+                        goto finish;
+                }
+
+                r = sd_journal_previous_skip(j, arg_lines);
+
+        } else {
+                r = sd_journal_seek_head(j);
+                if (r < 0) {
+                        log_error("Failed to seek to head: %s", strerror(-r));
+                        goto finish;
+                }
+
+                r = sd_journal_next(j);
+        }
+
+        if (r < 0) {
+                log_error("Failed to iterate through journal: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (!arg_no_pager && !arg_follow)
+                pager_open();
+
+        if (!arg_quiet) {
+                usec_t start, end;
+                char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
+
+                r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
+                if (r < 0) {
+                        log_error("Failed to get cutoff: %s", strerror(-r));
+                        goto finish;
+                }
+
+                if (r > 0) {
+                        if (arg_follow)
+                                printf("-- Logs begin at %s. --\n",
+                                       format_timestamp(start_buf, sizeof(start_buf), start));
+                        else
+                                printf("-- Logs begin at %s, end at %s. --\n",
+                                       format_timestamp(start_buf, sizeof(start_buf), start),
+                                       format_timestamp(end_buf, sizeof(end_buf), end));
+                }
+        }
+
+        for (;;) {
+                while (arg_lines == 0 || arg_follow || n_shown < arg_lines) {
+                        int flags;
+
+                        if (need_seek) {
+                                r = sd_journal_next(j);
+                                if (r < 0) {
+                                        log_error("Failed to iterate through journal: %s", strerror(-r));
+                                        goto finish;
+                                }
+                        }
+
+                        if (r == 0)
+                                break;
+
+                        if (arg_until_set) {
+                                usec_t usec;
+
+                                r = sd_journal_get_realtime_usec(j, &usec);
+                                if (r < 0) {
+                                        log_error("Failed to determine timestamp: %s", strerror(-r));
+                                        goto finish;
+                                }
+                        }
+
+                        if (!arg_merge) {
+                                sd_id128_t boot_id;
+
+                                r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
+                                if (r >= 0) {
+                                        if (previous_boot_id_valid &&
+                                            !sd_id128_equal(boot_id, previous_boot_id))
+                                                printf(ANSI_HIGHLIGHT_ON "-- Reboot --" ANSI_HIGHLIGHT_OFF "\n");
+
+                                        previous_boot_id = boot_id;
+                                        previous_boot_id_valid = true;
+                                }
+                        }
+
+                        flags =
+                                arg_all * OUTPUT_SHOW_ALL |
+                                (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+                                on_tty() * OUTPUT_COLOR |
+                                arg_catalog * OUTPUT_CATALOG;
+
+                        r = output_journal(stdout, j, arg_output, 0, flags);
+                        if (r < 0)
+                                goto finish;
+
+                        need_seek = true;
+                        n_shown++;
+                }
+
+                if (!arg_follow)
+                        break;
+
+                r = sd_journal_wait(j, (uint64_t) -1);
+                if (r < 0) {
+                        log_error("Couldn't wait for journal event: %s", strerror(-r));
+                        goto finish;
+                }
+        }
+
+finish:
+        if (j)
+                sd_journal_close(j);
+
+        pager_close();
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c
new file mode 100644 (file)
index 0000000..be55f94
--- /dev/null
@@ -0,0 +1,86 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include "journald-server.h"
+#include "journald-console.h"
+
+void server_forward_console(
+                Server *s,
+                int priority,
+                const char *identifier,
+                const char *message,
+                struct ucred *ucred) {
+
+        struct iovec iovec[4];
+        char header_pid[16];
+        int n = 0, fd;
+        char *ident_buf = NULL;
+        const char *tty;
+
+        assert(s);
+        assert(message);
+
+        if (LOG_PRI(priority) > s->max_level_console)
+                return;
+
+        /* First: identifier and PID */
+        if (ucred) {
+                if (!identifier) {
+                        get_process_comm(ucred->pid, &ident_buf);
+                        identifier = ident_buf;
+                }
+
+                snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
+                char_array_0(header_pid);
+
+                if (identifier)
+                        IOVEC_SET_STRING(iovec[n++], identifier);
+
+                IOVEC_SET_STRING(iovec[n++], header_pid);
+        } else if (identifier) {
+                IOVEC_SET_STRING(iovec[n++], identifier);
+                IOVEC_SET_STRING(iovec[n++], ": ");
+        }
+
+        /* Third: message */
+        IOVEC_SET_STRING(iovec[n++], message);
+        IOVEC_SET_STRING(iovec[n++], "\n");
+
+        tty = s->tty_path ? s->tty_path : "/dev/console";
+
+        fd = open_terminal(tty, O_WRONLY|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0) {
+                log_debug("Failed to open %s for logging: %s", tty, strerror(errno));
+                goto finish;
+        }
+
+        if (writev(fd, iovec, n) < 0)
+                log_debug("Failed to write to %s for logging: %s", tty, strerror(errno));
+
+        close_nointr_nofail(fd);
+
+finish:
+        free(ident_buf);
+}
diff --git a/src/journal/journald-console.h b/src/journal/journald-console.h
new file mode 100644 (file)
index 0000000..aa8e657
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journald-server.h"
+
+void server_forward_console(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred);
diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf
new file mode 100644 (file)
index 0000000..1baef14
--- /dev/null
@@ -0,0 +1,39 @@
+%{
+#include <stddef.h>
+#include <sys/socket.h>
+#include "conf-parser.h"
+#include "journald-server.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name journald_gperf_hash
+%define lookup-function-name journald_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+Journal.Storage,            config_parse_storage,   0, offsetof(Server, storage)
+Journal.Compress,           config_parse_bool,      0, offsetof(Server, compress)
+Journal.Seal,               config_parse_bool,      0, offsetof(Server, seal)
+Journal.RateLimitInterval,  config_parse_usec,      0, offsetof(Server, rate_limit_interval)
+Journal.RateLimitBurst,     config_parse_unsigned,  0, offsetof(Server, rate_limit_burst)
+Journal.SystemMaxUse,       config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_use)
+Journal.SystemMaxFileSize,  config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_size)
+Journal.SystemKeepFree,     config_parse_bytes_off, 0, offsetof(Server, system_metrics.keep_free)
+Journal.RuntimeMaxUse,      config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_use)
+Journal.RuntimeMaxFileSize, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_size)
+Journal.RuntimeKeepFree,    config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.keep_free)
+Journal.MaxRetentionSec,    config_parse_usec,      0, offsetof(Server, max_retention_usec)
+Journal.MaxFileSec,         config_parse_usec,      0, offsetof(Server, max_file_usec)
+Journal.ForwardToSyslog,    config_parse_bool,      0, offsetof(Server, forward_to_syslog)
+Journal.ForwardToKMsg,      config_parse_bool,      0, offsetof(Server, forward_to_kmsg)
+Journal.ForwardToConsole,   config_parse_bool,      0, offsetof(Server, forward_to_console)
+Journal.TTYPath,            config_parse_path,      0, offsetof(Server, tty_path)
+Journal.MaxLevelStore,      config_parse_level,     0, offsetof(Server, max_level_store)
+Journal.MaxLevelSyslog,     config_parse_level,     0, offsetof(Server, max_level_syslog)
+Journal.MaxLevelKMsg,       config_parse_level,     0, offsetof(Server, max_level_kmsg)
+Journal.MaxLevelConsole,    config_parse_level,     0, offsetof(Server, max_level_console)
+Journal.SplitMode,          config_parse_split_mode,0, offsetof(Server, split_mode)
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
new file mode 100644 (file)
index 0000000..b819876
--- /dev/null
@@ -0,0 +1,438 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+
+#include <systemd/sd-messages.h>
+#include <libudev.h>
+
+#include "journald-server.h"
+#include "journald-kmsg.h"
+#include "journald-syslog.h"
+
+void server_forward_kmsg(
+        Server *s,
+        int priority,
+        const char *identifier,
+        const char *message,
+        struct ucred *ucred) {
+
+        struct iovec iovec[5];
+        char header_priority[6], header_pid[16];
+        int n = 0;
+        char *ident_buf = NULL;
+
+        assert(s);
+        assert(priority >= 0);
+        assert(priority <= 999);
+        assert(message);
+
+        if (_unlikely_(LOG_PRI(priority) > s->max_level_kmsg))
+                return;
+
+        if (_unlikely_(s->dev_kmsg_fd < 0))
+                return;
+
+        /* Never allow messages with kernel facility to be written to
+         * kmsg, regardless where the data comes from. */
+        priority = syslog_fixup_facility(priority);
+
+        /* First: priority field */
+        snprintf(header_priority, sizeof(header_priority), "<%i>", priority);
+        char_array_0(header_priority);
+        IOVEC_SET_STRING(iovec[n++], header_priority);
+
+        /* Second: identifier and PID */
+        if (ucred) {
+                if (!identifier) {
+                        get_process_comm(ucred->pid, &ident_buf);
+                        identifier = ident_buf;
+                }
+
+                snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
+                char_array_0(header_pid);
+
+                if (identifier)
+                        IOVEC_SET_STRING(iovec[n++], identifier);
+
+                IOVEC_SET_STRING(iovec[n++], header_pid);
+        } else if (identifier) {
+                IOVEC_SET_STRING(iovec[n++], identifier);
+                IOVEC_SET_STRING(iovec[n++], ": ");
+        }
+
+        /* Fourth: message */
+        IOVEC_SET_STRING(iovec[n++], message);
+        IOVEC_SET_STRING(iovec[n++], "\n");
+
+        if (writev(s->dev_kmsg_fd, iovec, n) < 0)
+                log_debug("Failed to write to /dev/kmsg for logging: %s", strerror(errno));
+
+        free(ident_buf);
+}
+
+static bool is_us(const char *pid) {
+        pid_t t;
+
+        assert(pid);
+
+        if (parse_pid(pid, &t) < 0)
+                return false;
+
+        return t == getpid();
+}
+
+static void dev_kmsg_record(Server *s, char *p, size_t l) {
+        struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
+        char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL;
+        int priority, r;
+        unsigned n = 0, z = 0, j;
+        unsigned long long usec;
+        char *identifier = NULL, *pid = NULL, *e, *f, *k;
+        uint64_t serial;
+        size_t pl;
+        char *kernel_device = NULL;
+
+        assert(s);
+        assert(p);
+
+        if (l <= 0)
+                return;
+
+        e = memchr(p, ',', l);
+        if (!e)
+                return;
+        *e = 0;
+
+        r = safe_atoi(p, &priority);
+        if (r < 0 || priority < 0 || priority > 999)
+                return;
+
+        if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN)
+                return;
+
+        l -= (e - p) + 1;
+        p = e + 1;
+        e = memchr(p, ',', l);
+        if (!e)
+                return;
+        *e = 0;
+
+        r = safe_atou64(p, &serial);
+        if (r < 0)
+                return;
+
+        if (s->kernel_seqnum) {
+                /* We already read this one? */
+                if (serial < *s->kernel_seqnum)
+                        return;
+
+                /* Did we lose any? */
+                if (serial > *s->kernel_seqnum)
+                        server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %llu kernel messages", (unsigned long long) serial - *s->kernel_seqnum - 1);
+
+                /* Make sure we never read this one again. Note that
+                 * we always store the next message serial we expect
+                 * here, simply because this makes handling the first
+                 * message with serial 0 easy. */
+                *s->kernel_seqnum = serial + 1;
+        }
+
+        l -= (e - p) + 1;
+        p = e + 1;
+        f = memchr(p, ';', l);
+        if (!f)
+                return;
+        /* Kernel 3.6 has the flags field, kernel 3.5 lacks that */
+        e = memchr(p, ',', l);
+        if (!e || f < e)
+                e = f;
+        *e = 0;
+
+        r = safe_atollu(p, &usec);
+        if (r < 0)
+                return;
+
+        l -= (f - p) + 1;
+        p = f + 1;
+        e = memchr(p, '\n', l);
+        if (!e)
+                return;
+        *e = 0;
+
+        pl = e - p;
+        l -= (e - p) + 1;
+        k = e + 1;
+
+        for (j = 0; l > 0 && j < N_IOVEC_KERNEL_FIELDS; j++) {
+                char *m;
+                /* Meta data fields attached */
+
+                if (*k != ' ')
+                        break;
+
+                k ++, l --;
+
+                e = memchr(k, '\n', l);
+                if (!e)
+                        return;
+
+                *e = 0;
+
+                m = cunescape_length_with_prefix(k, e - k, "_KERNEL_");
+                if (!m)
+                        break;
+
+                if (startswith(m, "_KERNEL_DEVICE="))
+                        kernel_device = m + 15;
+
+                IOVEC_SET_STRING(iovec[n++], m);
+                z++;
+
+                l -= (e - k) + 1;
+                k = e + 1;
+        }
+
+        if (kernel_device) {
+                struct udev_device *ud;
+
+                ud = udev_device_new_from_device_id(s->udev, kernel_device);
+                if (ud) {
+                        const char *g;
+                        struct udev_list_entry *ll;
+                        char *b;
+
+                        g = udev_device_get_devnode(ud);
+                        if (g) {
+                                b = strappend("_UDEV_DEVNODE=", g);
+                                if (b) {
+                                        IOVEC_SET_STRING(iovec[n++], b);
+                                        z++;
+                                }
+                        }
+
+                        g = udev_device_get_sysname(ud);
+                        if (g) {
+                                b = strappend("_UDEV_SYSNAME=", g);
+                                if (b) {
+                                        IOVEC_SET_STRING(iovec[n++], b);
+                                        z++;
+                                }
+                        }
+
+                        j = 0;
+                        ll = udev_device_get_devlinks_list_entry(ud);
+                        udev_list_entry_foreach(ll, ll) {
+
+                                if (j > N_IOVEC_UDEV_FIELDS)
+                                        break;
+
+                                g = udev_list_entry_get_name(ll);
+                                b = strappend("_UDEV_DEVLINK=", g);
+                                if (g) {
+                                        IOVEC_SET_STRING(iovec[n++], b);
+                                        z++;
+                                }
+
+                                j++;
+                        }
+
+                        udev_device_unref(ud);
+                }
+        }
+
+        if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", usec) >= 0)
+                IOVEC_SET_STRING(iovec[n++], source_time);
+
+        IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=kernel");
+
+        if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
+                IOVEC_SET_STRING(iovec[n++], syslog_priority);
+
+        if ((priority & LOG_FACMASK) == LOG_KERN)
+                IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel");
+        else {
+                pl -= syslog_parse_identifier((const char**) &p, &identifier, &pid);
+
+                /* Avoid any messages we generated ourselves via
+                 * log_info() and friends. */
+                if (pid && is_us(pid))
+                        goto finish;
+
+                if (identifier) {
+                        syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
+                        if (syslog_identifier)
+                                IOVEC_SET_STRING(iovec[n++], syslog_identifier);
+                }
+
+                if (pid) {
+                        syslog_pid = strappend("SYSLOG_PID=", pid);
+                        if (syslog_pid)
+                                IOVEC_SET_STRING(iovec[n++], syslog_pid);
+                }
+
+                if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], syslog_facility);
+        }
+
+        message = cunescape_length_with_prefix(p, pl, "MESSAGE=");
+        if (message)
+                IOVEC_SET_STRING(iovec[n++], message);
+
+        server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, NULL, 0, NULL, priority);
+
+finish:
+        for (j = 0; j < z; j++)
+                free(iovec[j].iov_base);
+
+        free(message);
+        free(syslog_priority);
+        free(syslog_identifier);
+        free(syslog_pid);
+        free(syslog_facility);
+        free(source_time);
+        free(identifier);
+        free(pid);
+}
+
+int server_read_dev_kmsg(Server *s) {
+        char buffer[8192+1]; /* the kernel-side limit per record is 8K currently */
+        ssize_t l;
+
+        assert(s);
+        assert(s->dev_kmsg_fd >= 0);
+
+        l = read(s->dev_kmsg_fd, buffer, sizeof(buffer) - 1);
+        if (l == 0)
+                return 0;
+        if (l < 0) {
+                /* Old kernels who don't allow reading from /dev/kmsg
+                 * return EINVAL when we try. So handle this cleanly,
+                 * but don' try to ever read from it again. */
+                if (errno == EINVAL) {
+                        epoll_ctl(s->epoll_fd, EPOLL_CTL_DEL, s->dev_kmsg_fd, NULL);
+                        return 0;
+                }
+
+                if (errno == EAGAIN || errno == EINTR || errno == EPIPE)
+                        return 0;
+
+                log_error("Failed to read from kernel: %m");
+                return -errno;
+        }
+
+        dev_kmsg_record(s, buffer, l);
+        return 1;
+}
+
+int server_flush_dev_kmsg(Server *s) {
+        int r;
+
+        assert(s);
+
+        if (s->dev_kmsg_fd < 0)
+                return 0;
+
+        if (!s->dev_kmsg_readable)
+                return 0;
+
+        log_debug("Flushing /dev/kmsg...");
+
+        for (;;) {
+                r = server_read_dev_kmsg(s);
+                if (r < 0)
+                        return r;
+
+                if (r == 0)
+                        break;
+        }
+
+        return 0;
+}
+
+int server_open_dev_kmsg(Server *s) {
+        struct epoll_event ev;
+
+        assert(s);
+
+        s->dev_kmsg_fd = open("/dev/kmsg", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        if (s->dev_kmsg_fd < 0) {
+                log_warning("Failed to open /dev/kmsg, ignoring: %m");
+                return 0;
+        }
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.fd = s->dev_kmsg_fd;
+        if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->dev_kmsg_fd, &ev) < 0) {
+
+                /* This will fail with EPERM on older kernels where
+                 * /dev/kmsg is not readable. */
+                if (errno == EPERM)
+                        return 0;
+
+                log_error("Failed to add /dev/kmsg fd to epoll object: %m");
+                return -errno;
+        }
+
+        s->dev_kmsg_readable = true;
+
+        return 0;
+}
+
+int server_open_kernel_seqnum(Server *s) {
+        int fd;
+        uint64_t *p;
+
+        assert(s);
+
+        /* We store the seqnum we last read in an mmaped file. That
+         * way we can just use it like a variable, but it is
+         * persistent and automatically flushed at reboot. */
+
+        fd = open("/run/systemd/journal/kernel-seqnum", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
+        if (fd < 0) {
+                log_error("Failed to open /run/systemd/journal/kernel-seqnum, ignoring: %m");
+                return 0;
+        }
+
+        if (posix_fallocate(fd, 0, sizeof(uint64_t)) < 0) {
+                log_error("Failed to allocate sequential number file, ignoring: %m");
+                close_nointr_nofail(fd);
+                return 0;
+        }
+
+        p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+        if (p == MAP_FAILED) {
+                log_error("Failed to map sequential number file, ignoring: %m");
+                close_nointr_nofail(fd);
+                return 0;
+        }
+
+        close_nointr_nofail(fd);
+        s->kernel_seqnum = p;
+
+        return 0;
+}
diff --git a/src/journal/journald-kmsg.h b/src/journal/journald-kmsg.h
new file mode 100644 (file)
index 0000000..f287161
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journald-server.h"
+
+int server_open_dev_kmsg(Server *s);
+int server_read_dev_kmsg(Server *s);
+int server_flush_dev_kmsg(Server *s);
+
+void server_forward_kmsg(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred);
+
+int server_open_kernel_seqnum(Server *s);
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
new file mode 100644 (file)
index 0000000..0691147
--- /dev/null
@@ -0,0 +1,420 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/epoll.h>
+
+#include "socket-util.h"
+#include "path-util.h"
+#include "journald-server.h"
+#include "journald-native.h"
+#include "journald-kmsg.h"
+#include "journald-console.h"
+#include "journald-syslog.h"
+
+#define ENTRY_SIZE_MAX (1024*1024*64)
+#define DATA_SIZE_MAX (1024*1024*64)
+
+static bool valid_user_field(const char *p, size_t l) {
+        const char *a;
+
+        /* We kinda enforce POSIX syntax recommendations for
+           environment variables here, but make a couple of additional
+           requirements.
+
+           http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
+
+        /* No empty field names */
+        if (l <= 0)
+                return false;
+
+        /* Don't allow names longer than 64 chars */
+        if (l > 64)
+                return false;
+
+        /* Variables starting with an underscore are protected */
+        if (p[0] == '_')
+                return false;
+
+        /* Don't allow digits as first character */
+        if (p[0] >= '0' && p[0] <= '9')
+                return false;
+
+        /* Only allow A-Z0-9 and '_' */
+        for (a = p; a < p + l; a++)
+                if (!((*a >= 'A' && *a <= 'Z') ||
+                      (*a >= '0' && *a <= '9') ||
+                      *a == '_'))
+                        return false;
+
+        return true;
+}
+
+void server_process_native_message(
+                Server *s,
+                const void *buffer, size_t buffer_size,
+                struct ucred *ucred,
+                struct timeval *tv,
+                const char *label, size_t label_len) {
+
+        struct iovec *iovec = NULL;
+        unsigned n = 0, m = 0, j, tn = (unsigned) -1;
+        const char *p;
+        size_t remaining;
+        int priority = LOG_INFO;
+        char *identifier = NULL, *message = NULL;
+
+        assert(s);
+        assert(buffer || buffer_size == 0);
+
+        p = buffer;
+        remaining = buffer_size;
+
+        while (remaining > 0) {
+                const char *e, *q;
+
+                e = memchr(p, '\n', remaining);
+
+                if (!e) {
+                        /* Trailing noise, let's ignore it, and flush what we collected */
+                        log_debug("Received message with trailing noise, ignoring.");
+                        break;
+                }
+
+                if (e == p) {
+                        /* Entry separator */
+                        server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
+                        n = 0;
+                        priority = LOG_INFO;
+
+                        p++;
+                        remaining--;
+                        continue;
+                }
+
+                if (*p == '.' || *p == '#') {
+                        /* Ignore control commands for now, and
+                         * comments too. */
+                        remaining -= (e - p) + 1;
+                        p = e + 1;
+                        continue;
+                }
+
+                /* A property follows */
+
+                if (n+N_IOVEC_META_FIELDS >= m) {
+                        struct iovec *c;
+                        unsigned u;
+
+                        u = MAX((n+N_IOVEC_META_FIELDS+1) * 2U, 4U);
+                        c = realloc(iovec, u * sizeof(struct iovec));
+                        if (!c) {
+                                log_oom();
+                                break;
+                        }
+
+                        iovec = c;
+                        m = u;
+                }
+
+                q = memchr(p, '=', e - p);
+                if (q) {
+                        if (valid_user_field(p, q - p)) {
+                                size_t l;
+
+                                l = e - p;
+
+                                /* If the field name starts with an
+                                 * underscore, skip the variable,
+                                 * since that indidates a trusted
+                                 * field */
+                                iovec[n].iov_base = (char*) p;
+                                iovec[n].iov_len = l;
+                                n++;
+
+                                /* We need to determine the priority
+                                 * of this entry for the rate limiting
+                                 * logic */
+                                if (l == 10 &&
+                                    memcmp(p, "PRIORITY=", 9) == 0 &&
+                                    p[9] >= '0' && p[9] <= '9')
+                                        priority = (priority & LOG_FACMASK) | (p[9] - '0');
+
+                                else if (l == 17 &&
+                                         memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
+                                         p[16] >= '0' && p[16] <= '9')
+                                        priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
+
+                                else if (l == 18 &&
+                                         memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
+                                         p[16] >= '0' && p[16] <= '9' &&
+                                         p[17] >= '0' && p[17] <= '9')
+                                        priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
+
+                                else if (l >= 19 &&
+                                         memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) {
+                                        char *t;
+
+                                        t = strndup(p + 18, l - 18);
+                                        if (t) {
+                                                free(identifier);
+                                                identifier = t;
+                                        }
+                                } else if (l >= 8 &&
+                                           memcmp(p, "MESSAGE=", 8) == 0) {
+                                        char *t;
+
+                                        t = strndup(p + 8, l - 8);
+                                        if (t) {
+                                                free(message);
+                                                message = t;
+                                        }
+                                }
+                        }
+
+                        remaining -= (e - p) + 1;
+                        p = e + 1;
+                        continue;
+                } else {
+                        le64_t l_le;
+                        uint64_t l;
+                        char *k;
+
+                        if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
+                                log_debug("Failed to parse message, ignoring.");
+                                break;
+                        }
+
+                        memcpy(&l_le, e + 1, sizeof(uint64_t));
+                        l = le64toh(l_le);
+
+                        if (l > DATA_SIZE_MAX) {
+                                log_debug("Received binary data block too large, ignoring.");
+                                break;
+                        }
+
+                        if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
+                            e[1+sizeof(uint64_t)+l] != '\n') {
+                                log_debug("Failed to parse message, ignoring.");
+                                break;
+                        }
+
+                        k = malloc((e - p) + 1 + l);
+                        if (!k) {
+                                log_oom();
+                                break;
+                        }
+
+                        memcpy(k, p, e - p);
+                        k[e - p] = '=';
+                        memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
+
+                        if (valid_user_field(p, e - p)) {
+                                iovec[n].iov_base = k;
+                                iovec[n].iov_len = (e - p) + 1 + l;
+                                n++;
+                        } else
+                                free(k);
+
+                        remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
+                        p = e + 1 + sizeof(uint64_t) + l + 1;
+                }
+        }
+
+        if (n <= 0)
+                goto finish;
+
+        tn = n++;
+        IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
+
+        if (message) {
+                if (s->forward_to_syslog)
+                        server_forward_syslog(s, priority, identifier, message, ucred, tv);
+
+                if (s->forward_to_kmsg)
+                        server_forward_kmsg(s, priority, identifier, message, ucred);
+
+                if (s->forward_to_console)
+                        server_forward_console(s, priority, identifier, message, ucred);
+        }
+
+        server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
+
+finish:
+        for (j = 0; j < n; j++)  {
+                if (j == tn)
+                        continue;
+
+                if (iovec[j].iov_base < buffer ||
+                    (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
+                        free(iovec[j].iov_base);
+        }
+
+        free(iovec);
+        free(identifier);
+        free(message);
+}
+
+void server_process_native_file(
+                Server *s,
+                int fd,
+                struct ucred *ucred,
+                struct timeval *tv,
+                const char *label, size_t label_len) {
+
+        struct stat st;
+        _cleanup_free_ void *p = NULL;
+        ssize_t n;
+        int r;
+
+        assert(s);
+        assert(fd >= 0);
+
+        if (!ucred || ucred->uid != 0) {
+                _cleanup_free_ char *sl = NULL, *k = NULL;
+                const char *e;
+
+                if (asprintf(&sl, "/proc/self/fd/%i", fd) < 0) {
+                        log_oom();
+                        return;
+                }
+
+                r = readlink_malloc(sl, &k);
+                if (r < 0) {
+                        log_error("readlink(%s) failed: %m", sl);
+                        return;
+                }
+
+                e = path_startswith(k, "/dev/shm/");
+                if (!e)
+                        e = path_startswith(k, "/tmp/");
+                if (!e)
+                        e = path_startswith(k, "/var/tmp/");
+                if (!e) {
+                        log_error("Received file outside of allowed directories. Refusing.");
+                        return;
+                }
+
+                if (!filename_is_safe(e)) {
+                        log_error("Received file in subdirectory of allowed directories. Refusing.");
+                        return;
+                }
+        }
+
+        /* Data is in the passed file, since it didn't fit in a
+         * datagram. We can't map the file here, since clients might
+         * then truncate it and trigger a SIGBUS for us. So let's
+         * stupidly read it */
+
+        if (fstat(fd, &st) < 0) {
+                log_error("Failed to stat passed file, ignoring: %m");
+                return;
+        }
+
+        if (!S_ISREG(st.st_mode)) {
+                log_error("File passed is not regular. Ignoring.");
+                return;
+        }
+
+        if (st.st_size <= 0)
+                return;
+
+        if (st.st_size > ENTRY_SIZE_MAX) {
+                log_error("File passed too large. Ignoring.");
+                return;
+        }
+
+        p = malloc(st.st_size);
+        if (!p) {
+                log_oom();
+                return;
+        }
+
+        n = pread(fd, p, st.st_size, 0);
+        if (n < 0)
+                log_error("Failed to read file, ignoring: %s", strerror(-n));
+        else if (n > 0)
+                server_process_native_message(s, p, n, ucred, tv, label, label_len);
+}
+
+int server_open_native_socket(Server*s) {
+        union sockaddr_union sa;
+        int one, r;
+        struct epoll_event ev;
+
+        assert(s);
+
+        if (s->native_fd < 0) {
+
+                s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+                if (s->native_fd < 0) {
+                        log_error("socket() failed: %m");
+                        return -errno;
+                }
+
+                zero(sa);
+                sa.un.sun_family = AF_UNIX;
+                strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
+
+                unlink(sa.un.sun_path);
+
+                r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+                if (r < 0) {
+                        log_error("bind() failed: %m");
+                        return -errno;
+                }
+
+                chmod(sa.un.sun_path, 0666);
+        } else
+                fd_nonblock(s->native_fd, 1);
+
+        one = 1;
+        r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
+        if (r < 0) {
+                log_error("SO_PASSCRED failed: %m");
+                return -errno;
+        }
+
+#ifdef HAVE_SELINUX
+        one = 1;
+        r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
+        if (r < 0)
+                log_warning("SO_PASSSEC failed: %m");
+#endif
+
+        one = 1;
+        r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
+        if (r < 0) {
+                log_error("SO_TIMESTAMP failed: %m");
+                return -errno;
+        }
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.fd = s->native_fd;
+        if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->native_fd, &ev) < 0) {
+                log_error("Failed to add native server fd to epoll object: %m");
+                return -errno;
+        }
+
+        return 0;
+}
diff --git a/src/journal/journald-native.h b/src/journal/journald-native.h
new file mode 100644 (file)
index 0000000..16c09f5
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journald-server.h"
+
+void server_process_native_message(Server *s, const void *buffer, size_t buffer_size, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len);
+
+void server_process_native_file(Server *s, int fd, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len);
+
+int server_open_native_socket(Server*s);
diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c
new file mode 100644 (file)
index 0000000..8bd6847
--- /dev/null
@@ -0,0 +1,275 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <errno.h>
+
+#include "journald-rate-limit.h"
+#include "list.h"
+#include "util.h"
+#include "hashmap.h"
+
+#define POOLS_MAX 5
+#define BUCKETS_MAX 127
+#define GROUPS_MAX 2047
+
+static const int priority_map[] = {
+        [LOG_EMERG]   = 0,
+        [LOG_ALERT]   = 0,
+        [LOG_CRIT]    = 0,
+        [LOG_ERR]     = 1,
+        [LOG_WARNING] = 2,
+        [LOG_NOTICE]  = 3,
+        [LOG_INFO]    = 3,
+        [LOG_DEBUG]   = 4
+};
+
+typedef struct JournalRateLimitPool JournalRateLimitPool;
+typedef struct JournalRateLimitGroup JournalRateLimitGroup;
+
+struct JournalRateLimitPool {
+        usec_t begin;
+        unsigned num;
+        unsigned suppressed;
+};
+
+struct JournalRateLimitGroup {
+        JournalRateLimit *parent;
+
+        char *id;
+        JournalRateLimitPool pools[POOLS_MAX];
+        unsigned hash;
+
+        LIST_FIELDS(JournalRateLimitGroup, bucket);
+        LIST_FIELDS(JournalRateLimitGroup, lru);
+};
+
+struct JournalRateLimit {
+        usec_t interval;
+        unsigned burst;
+
+        JournalRateLimitGroup* buckets[BUCKETS_MAX];
+        JournalRateLimitGroup *lru, *lru_tail;
+
+        unsigned n_groups;
+};
+
+JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) {
+        JournalRateLimit *r;
+
+        assert(interval > 0 || burst == 0);
+
+        r = new0(JournalRateLimit, 1);
+        if (!r)
+                return NULL;
+
+        r->interval = interval;
+        r->burst = burst;
+
+        return r;
+}
+
+static void journal_rate_limit_group_free(JournalRateLimitGroup *g) {
+        assert(g);
+
+        if (g->parent) {
+                assert(g->parent->n_groups > 0);
+
+                if (g->parent->lru_tail == g)
+                        g->parent->lru_tail = g->lru_prev;
+
+                LIST_REMOVE(JournalRateLimitGroup, lru, g->parent->lru, g);
+                LIST_REMOVE(JournalRateLimitGroup, bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g);
+
+                g->parent->n_groups --;
+        }
+
+        free(g->id);
+        free(g);
+}
+
+void journal_rate_limit_free(JournalRateLimit *r) {
+        assert(r);
+
+        while (r->lru)
+                journal_rate_limit_group_free(r->lru);
+
+        free(r);
+}
+
+static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, usec_t ts) {
+        unsigned i;
+
+        assert(g);
+
+        for (i = 0; i < POOLS_MAX; i++)
+                if (g->pools[i].begin + g->parent->interval >= ts)
+                        return false;
+
+        return true;
+}
+
+static void journal_rate_limit_vacuum(JournalRateLimit *r, usec_t ts) {
+        assert(r);
+
+        /* Makes room for at least one new item, but drop all
+         * expored items too. */
+
+        while (r->n_groups >= GROUPS_MAX ||
+               (r->lru_tail && journal_rate_limit_group_expired(r->lru_tail, ts)))
+                journal_rate_limit_group_free(r->lru_tail);
+}
+
+static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) {
+        JournalRateLimitGroup *g;
+
+        assert(r);
+        assert(id);
+
+        g = new0(JournalRateLimitGroup, 1);
+        if (!g)
+                return NULL;
+
+        g->id = strdup(id);
+        if (!g->id)
+                goto fail;
+
+        g->hash = string_hash_func(g->id);
+
+        journal_rate_limit_vacuum(r, ts);
+
+        LIST_PREPEND(JournalRateLimitGroup, bucket, r->buckets[g->hash % BUCKETS_MAX], g);
+        LIST_PREPEND(JournalRateLimitGroup, lru, r->lru, g);
+        if (!g->lru_next)
+                r->lru_tail = g;
+        r->n_groups ++;
+
+        g->parent = r;
+        return g;
+
+fail:
+        journal_rate_limit_group_free(g);
+        return NULL;
+}
+
+static uint64_t u64log2(uint64_t n) {
+        unsigned r;
+
+        if (n <= 1)
+                return 0;
+
+        r = 0;
+        for (;;) {
+                n = n >> 1;
+                if (!n)
+                        return r;
+                r++;
+        }
+}
+
+static unsigned burst_modulate(unsigned burst, uint64_t available) {
+        unsigned k;
+
+        /* Modulates the burst rate a bit with the amount of available
+         * disk space */
+
+        k = u64log2(available);
+
+        /* 1MB */
+        if (k <= 20)
+                return burst;
+
+        burst = (burst * (k-20)) / 4;
+
+        /*
+         * Example:
+         *
+         *      <= 1MB = rate * 1
+         *        16MB = rate * 2
+         *       256MB = rate * 3
+         *         4GB = rate * 4
+         *        64GB = rate * 5
+         *         1TB = rate * 6
+         */
+
+        return burst;
+}
+
+int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
+        unsigned h;
+        JournalRateLimitGroup *g;
+        JournalRateLimitPool *p;
+        unsigned burst;
+        usec_t ts;
+
+        assert(id);
+
+        if (!r)
+                return 1;
+
+        if (r->interval == 0 || r->burst == 0)
+                return 1;
+
+        burst = burst_modulate(r->burst, available);
+
+        ts = now(CLOCK_MONOTONIC);
+
+        h = string_hash_func(id);
+        g = r->buckets[h % BUCKETS_MAX];
+
+        LIST_FOREACH(bucket, g, g)
+                if (streq(g->id, id))
+                        break;
+
+        if (!g) {
+                g = journal_rate_limit_group_new(r, id, ts);
+                if (!g)
+                        return -ENOMEM;
+        }
+
+        p = &g->pools[priority_map[priority]];
+
+        if (p->begin <= 0) {
+                p->suppressed = 0;
+                p->num = 1;
+                p->begin = ts;
+                return 1;
+        }
+
+        if (p->begin + r->interval < ts) {
+                unsigned s;
+
+                s = p->suppressed;
+                p->suppressed = 0;
+                p->num = 1;
+                p->begin = ts;
+
+                return 1 + s;
+        }
+
+        if (p->num <= burst) {
+                p->num++;
+                return 1;
+        }
+
+        p->suppressed++;
+        return 0;
+}
diff --git a/src/journal/journald-rate-limit.h b/src/journal/journald-rate-limit.h
new file mode 100644 (file)
index 0000000..648ab22
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+#include "util.h"
+
+typedef struct JournalRateLimit JournalRateLimit;
+
+JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst);
+void journal_rate_limit_free(JournalRateLimit *r);
+int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available);
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
new file mode 100644 (file)
index 0000000..43ffe75
--- /dev/null
@@ -0,0 +1,1504 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/signalfd.h>
+#include <sys/ioctl.h>
+#include <linux/sockios.h>
+#include <sys/statvfs.h>
+#include <sys/mman.h>
+
+#include <libudev.h>
+#include <systemd/sd-journal.h>
+#include <systemd/sd-messages.h>
+#include <systemd/sd-daemon.h>
+
+#ifdef HAVE_LOGIND
+#include <systemd/sd-login.h>
+#endif
+
+#include "mkdir.h"
+#include "hashmap.h"
+#include "journal-file.h"
+#include "socket-util.h"
+#include "cgroup-util.h"
+#include "list.h"
+#include "virt.h"
+#include "missing.h"
+#include "conf-parser.h"
+#include "journal-internal.h"
+#include "journal-vacuum.h"
+#include "journal-authenticate.h"
+#include "journald-server.h"
+#include "journald-rate-limit.h"
+#include "journald-kmsg.h"
+#include "journald-syslog.h"
+#include "journald-stream.h"
+#include "journald-console.h"
+#include "journald-native.h"
+
+#ifdef HAVE_ACL
+#include <sys/acl.h>
+#include <acl/libacl.h>
+#include "acl-util.h"
+#endif
+
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#define USER_JOURNALS_MAX 1024
+
+#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC)
+#define DEFAULT_RATE_LIMIT_BURST 200
+
+#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
+
+static const char* const storage_table[] = {
+        [STORAGE_AUTO] = "auto",
+        [STORAGE_VOLATILE] = "volatile",
+        [STORAGE_PERSISTENT] = "persistent",
+        [STORAGE_NONE] = "none"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(storage, Storage);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
+
+static const char* const split_mode_table[] = {
+        [SPLIT_NONE] = "none",
+        [SPLIT_UID] = "uid",
+        [SPLIT_LOGIN] = "login"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
+
+static uint64_t available_space(Server *s) {
+        char ids[33], *p;
+        const char *f;
+        sd_id128_t machine;
+        struct statvfs ss;
+        uint64_t sum = 0, avail = 0, ss_avail = 0;
+        int r;
+        DIR *d;
+        usec_t ts;
+        JournalMetrics *m;
+
+        ts = now(CLOCK_MONOTONIC);
+
+        if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts)
+                return s->cached_available_space;
+
+        r = sd_id128_get_machine(&machine);
+        if (r < 0)
+                return 0;
+
+        if (s->system_journal) {
+                f = "/var/log/journal/";
+                m = &s->system_metrics;
+        } else {
+                f = "/run/log/journal/";
+                m = &s->runtime_metrics;
+        }
+
+        assert(m);
+
+        p = strappend(f, sd_id128_to_string(machine, ids));
+        if (!p)
+                return 0;
+
+        d = opendir(p);
+        free(p);
+
+        if (!d)
+                return 0;
+
+        if (fstatvfs(dirfd(d), &ss) < 0)
+                goto finish;
+
+        for (;;) {
+                struct stat st;
+                struct dirent *de;
+                union dirent_storage buf;
+
+                r = readdir_r(d, &buf.de, &de);
+                if (r != 0)
+                        break;
+
+                if (!de)
+                        break;
+
+                if (!endswith(de->d_name, ".journal") &&
+                    !endswith(de->d_name, ".journal~"))
+                        continue;
+
+                if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
+                        continue;
+
+                if (!S_ISREG(st.st_mode))
+                        continue;
+
+                sum += (uint64_t) st.st_blocks * 512UL;
+        }
+
+        avail = sum >= m->max_use ? 0 : m->max_use - sum;
+
+        ss_avail = ss.f_bsize * ss.f_bavail;
+
+        ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free;
+
+        if (ss_avail < avail)
+                avail = ss_avail;
+
+        s->cached_available_space = avail;
+        s->cached_available_space_timestamp = ts;
+
+finish:
+        closedir(d);
+
+        return avail;
+}
+
+static void server_read_file_gid(Server *s) {
+        const char *adm = "adm";
+        int r;
+
+        assert(s);
+
+        if (s->file_gid_valid)
+                return;
+
+        r = get_group_creds(&adm, &s->file_gid);
+        if (r < 0)
+                log_warning("Failed to resolve 'adm' group: %s", strerror(-r));
+
+        /* if we couldn't read the gid, then it will be 0, but that's
+         * fine and we shouldn't try to resolve the group again, so
+         * let's just pretend it worked right-away. */
+        s->file_gid_valid = true;
+}
+
+void server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
+        int r;
+#ifdef HAVE_ACL
+        acl_t acl;
+        acl_entry_t entry;
+        acl_permset_t permset;
+#endif
+
+        assert(f);
+
+        server_read_file_gid(s);
+
+        r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid);
+        if (r < 0)
+                log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r));
+
+#ifdef HAVE_ACL
+        if (uid <= 0)
+                return;
+
+        acl = acl_get_fd(f->fd);
+        if (!acl) {
+                log_warning("Failed to read ACL on %s, ignoring: %m", f->path);
+                return;
+        }
+
+        r = acl_find_uid(acl, uid, &entry);
+        if (r <= 0) {
+
+                if (acl_create_entry(&acl, &entry) < 0 ||
+                    acl_set_tag_type(entry, ACL_USER) < 0 ||
+                    acl_set_qualifier(entry, &uid) < 0) {
+                        log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
+                        goto finish;
+                }
+        }
+
+        if (acl_get_permset(entry, &permset) < 0 ||
+            acl_add_perm(permset, ACL_READ) < 0 ||
+            acl_calc_mask(&acl) < 0) {
+                log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
+                goto finish;
+        }
+
+        if (acl_set_fd(f->fd, acl) < 0)
+                log_warning("Failed to set ACL on %s, ignoring: %m", f->path);
+
+finish:
+        acl_free(acl);
+#endif
+}
+
+static JournalFile* find_journal(Server *s, uid_t uid) {
+        char *p;
+        int r;
+        JournalFile *f;
+        sd_id128_t machine;
+
+        assert(s);
+
+        /* We split up user logs only on /var, not on /run. If the
+         * runtime file is open, we write to it exclusively, in order
+         * to guarantee proper order as soon as we flush /run to
+         * /var and close the runtime file. */
+
+        if (s->runtime_journal)
+                return s->runtime_journal;
+
+        if (uid <= 0)
+                return s->system_journal;
+
+        r = sd_id128_get_machine(&machine);
+        if (r < 0)
+                return s->system_journal;
+
+        f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
+        if (f)
+                return f;
+
+        if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-%lu.journal",
+                     SD_ID128_FORMAT_VAL(machine), (unsigned long) uid) < 0)
+                return s->system_journal;
+
+        while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
+                /* Too many open? Then let's close one */
+                f = hashmap_steal_first(s->user_journals);
+                assert(f);
+                journal_file_close(f);
+        }
+
+        r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f);
+        free(p);
+
+        if (r < 0)
+                return s->system_journal;
+
+        server_fix_perms(s, f, uid);
+
+        r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
+        if (r < 0) {
+                journal_file_close(f);
+                return s->system_journal;
+        }
+
+        return f;
+}
+
+void server_rotate(Server *s) {
+        JournalFile *f;
+        void *k;
+        Iterator i;
+        int r;
+
+        log_debug("Rotating...");
+
+        if (s->runtime_journal) {
+                r = journal_file_rotate(&s->runtime_journal, s->compress, false);
+                if (r < 0)
+                        if (s->runtime_journal)
+                                log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
+                        else
+                                log_error("Failed to create new runtime journal: %s", strerror(-r));
+                else
+                        server_fix_perms(s, s->runtime_journal, 0);
+        }
+
+        if (s->system_journal) {
+                r = journal_file_rotate(&s->system_journal, s->compress, s->seal);
+                if (r < 0)
+                        if (s->system_journal)
+                                log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
+                        else
+                                log_error("Failed to create new system journal: %s", strerror(-r));
+
+                else
+                        server_fix_perms(s, s->system_journal, 0);
+        }
+
+        HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
+                r = journal_file_rotate(&f, s->compress, s->seal);
+                if (r < 0)
+                        if (f)
+                                log_error("Failed to rotate %s: %s", f->path, strerror(-r));
+                        else
+                                log_error("Failed to create user journal: %s", strerror(-r));
+                else {
+                        hashmap_replace(s->user_journals, k, f);
+                        server_fix_perms(s, f, PTR_TO_UINT32(k));
+                }
+        }
+}
+
+void server_vacuum(Server *s) {
+        char *p;
+        char ids[33];
+        sd_id128_t machine;
+        int r;
+
+        log_debug("Vacuuming...");
+
+        s->oldest_file_usec = 0;
+
+        r = sd_id128_get_machine(&machine);
+        if (r < 0) {
+                log_error("Failed to get machine ID: %s", strerror(-r));
+                return;
+        }
+
+        sd_id128_to_string(machine, ids);
+
+        if (s->system_journal) {
+                p = strappend("/var/log/journal/", ids);
+                if (!p) {
+                        log_oom();
+                        return;
+                }
+
+                r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
+                if (r < 0 && r != -ENOENT)
+                        log_error("Failed to vacuum %s: %s", p, strerror(-r));
+                free(p);
+        }
+
+        if (s->runtime_journal) {
+                p = strappend("/run/log/journal/", ids);
+                if (!p) {
+                        log_oom();
+                        return;
+                }
+
+                r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
+                if (r < 0 && r != -ENOENT)
+                        log_error("Failed to vacuum %s: %s", p, strerror(-r));
+                free(p);
+        }
+
+        s->cached_available_space_timestamp = 0;
+}
+
+static char *shortened_cgroup_path(pid_t pid) {
+        int r;
+        char *process_path, *init_path, *path;
+
+        assert(pid > 0);
+
+        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &process_path);
+        if (r < 0)
+                return NULL;
+
+        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &init_path);
+        if (r < 0) {
+                free(process_path);
+                return NULL;
+        }
+
+        if (endswith(init_path, "/system"))
+                init_path[strlen(init_path) - 7] = 0;
+        else if (streq(init_path, "/"))
+                init_path[0] = 0;
+
+        if (startswith(process_path, init_path)) {
+                char *p;
+
+                p = strdup(process_path + strlen(init_path));
+                if (!p) {
+                        free(process_path);
+                        free(init_path);
+                        return NULL;
+                }
+                path = p;
+        } else {
+                path = process_path;
+                process_path = NULL;
+        }
+
+        free(process_path);
+        free(init_path);
+
+        return path;
+}
+
+bool shall_try_append_again(JournalFile *f, int r) {
+
+        /* -E2BIG            Hit configured limit
+           -EFBIG            Hit fs limit
+           -EDQUOT           Quota limit hit
+           -ENOSPC           Disk full
+           -EHOSTDOWN        Other machine
+           -EBUSY            Unclean shutdown
+           -EPROTONOSUPPORT  Unsupported feature
+           -EBADMSG          Corrupted
+           -ENODATA          Truncated
+           -ESHUTDOWN        Already archived */
+
+        if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
+                log_debug("%s: Allocation limit reached, rotating.", f->path);
+        else if (r == -EHOSTDOWN)
+                log_info("%s: Journal file from other machine, rotating.", f->path);
+        else if (r == -EBUSY)
+                log_info("%s: Unclean shutdown, rotating.", f->path);
+        else if (r == -EPROTONOSUPPORT)
+                log_info("%s: Unsupported feature, rotating.", f->path);
+        else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
+                log_warning("%s: Journal file corrupted, rotating.", f->path);
+        else
+                return false;
+
+        return true;
+}
+
+static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) {
+        JournalFile *f;
+        bool vacuumed = false;
+        int r;
+
+        assert(s);
+        assert(iovec);
+        assert(n > 0);
+
+        f = find_journal(s, uid);
+        if (!f)
+                return;
+
+        if (journal_file_rotate_suggested(f, s->max_file_usec)) {
+                log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
+                server_rotate(s);
+                server_vacuum(s);
+                vacuumed = true;
+
+                f = find_journal(s, uid);
+                if (!f)
+                        return;
+        }
+
+        r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
+        if (r >= 0)
+                return;
+
+        if (vacuumed || !shall_try_append_again(f, r)) {
+                log_error("Failed to write entry, ignoring: %s", strerror(-r));
+                return;
+        }
+
+        server_rotate(s);
+        server_vacuum(s);
+
+        f = find_journal(s, uid);
+        if (!f)
+                return;
+
+        log_debug("Retrying write.");
+        r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
+        if (r < 0)
+                log_error("Failed to write entry, ignoring: %s", strerror(-r));
+}
+
+static void dispatch_message_real(
+                Server *s,
+                struct iovec *iovec, unsigned n, unsigned m,
+                struct ucred *ucred,
+                struct timeval *tv,
+                const char *label, size_t label_len,
+                const char *unit_id) {
+
+        char *pid = NULL, *uid = NULL, *gid = NULL,
+                *source_time = NULL, *boot_id = NULL, *machine_id = NULL,
+                *comm = NULL, *cmdline = NULL, *hostname = NULL,
+                *audit_session = NULL, *audit_loginuid = NULL,
+                *exe = NULL, *cgroup = NULL, *session = NULL,
+                *owner_uid = NULL, *unit = NULL, *selinux_context = NULL;
+
+        char idbuf[33];
+        sd_id128_t id;
+        int r;
+        char *t;
+        uid_t loginuid = 0, realuid = 0;
+
+        assert(s);
+        assert(iovec);
+        assert(n > 0);
+        assert(n + N_IOVEC_META_FIELDS <= m);
+
+        if (ucred) {
+                uint32_t audit;
+#ifdef HAVE_LOGIND
+                uid_t owner;
+#endif
+
+                realuid = ucred->uid;
+
+                if (asprintf(&pid, "_PID=%lu", (unsigned long) ucred->pid) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], pid);
+
+                if (asprintf(&uid, "_UID=%lu", (unsigned long) ucred->uid) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], uid);
+
+                if (asprintf(&gid, "_GID=%lu", (unsigned long) ucred->gid) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], gid);
+
+                r = get_process_comm(ucred->pid, &t);
+                if (r >= 0) {
+                        comm = strappend("_COMM=", t);
+                        free(t);
+
+                        if (comm)
+                                IOVEC_SET_STRING(iovec[n++], comm);
+                }
+
+                r = get_process_exe(ucred->pid, &t);
+                if (r >= 0) {
+                        exe = strappend("_EXE=", t);
+                        free(t);
+
+                        if (exe)
+                                IOVEC_SET_STRING(iovec[n++], exe);
+                }
+
+                r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t);
+                if (r >= 0) {
+                        cmdline = strappend("_CMDLINE=", t);
+                        free(t);
+
+                        if (cmdline)
+                                IOVEC_SET_STRING(iovec[n++], cmdline);
+                }
+
+                r = audit_session_from_pid(ucred->pid, &audit);
+                if (r >= 0)
+                        if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0)
+                                IOVEC_SET_STRING(iovec[n++], audit_session);
+
+                r = audit_loginuid_from_pid(ucred->pid, &loginuid);
+                if (r >= 0)
+                        if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
+                                IOVEC_SET_STRING(iovec[n++], audit_loginuid);
+
+                t = shortened_cgroup_path(ucred->pid);
+                if (t) {
+                        cgroup = strappend("_SYSTEMD_CGROUP=", t);
+                        free(t);
+
+                        if (cgroup)
+                                IOVEC_SET_STRING(iovec[n++], cgroup);
+                }
+
+#ifdef HAVE_LOGIND
+                if (sd_pid_get_session(ucred->pid, &t) >= 0) {
+                        session = strappend("_SYSTEMD_SESSION=", t);
+                        free(t);
+
+                        if (session)
+                                IOVEC_SET_STRING(iovec[n++], session);
+                }
+
+                if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0)
+                        if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0)
+                                IOVEC_SET_STRING(iovec[n++], owner_uid);
+#endif
+
+                if (cg_pid_get_unit(ucred->pid, &t) >= 0) {
+                        unit = strappend("_SYSTEMD_UNIT=", t);
+                        free(t);
+                } else if (unit_id)
+                        unit = strappend("_SYSTEMD_UNIT=", unit_id);
+
+                if (unit)
+                        IOVEC_SET_STRING(iovec[n++], unit);
+
+#ifdef HAVE_SELINUX
+                if (label) {
+                        selinux_context = malloc(sizeof("_SELINUX_CONTEXT=") + label_len);
+                        if (selinux_context) {
+                                memcpy(selinux_context, "_SELINUX_CONTEXT=", sizeof("_SELINUX_CONTEXT=")-1);
+                                memcpy(selinux_context+sizeof("_SELINUX_CONTEXT=")-1, label, label_len);
+                                selinux_context[sizeof("_SELINUX_CONTEXT=")-1+label_len] = 0;
+                                IOVEC_SET_STRING(iovec[n++], selinux_context);
+                        }
+                } else {
+                        security_context_t con;
+
+                        if (getpidcon(ucred->pid, &con) >= 0) {
+                                selinux_context = strappend("_SELINUX_CONTEXT=", con);
+                                if (selinux_context)
+                                        IOVEC_SET_STRING(iovec[n++], selinux_context);
+
+                                freecon(con);
+                        }
+                }
+#endif
+        }
+
+        if (tv) {
+                if (asprintf(&source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu",
+                             (unsigned long long) timeval_load(tv)) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], source_time);
+        }
+
+        /* Note that strictly speaking storing the boot id here is
+         * redundant since the entry includes this in-line
+         * anyway. However, we need this indexed, too. */
+        r = sd_id128_get_boot(&id);
+        if (r >= 0)
+                if (asprintf(&boot_id, "_BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], boot_id);
+
+        r = sd_id128_get_machine(&id);
+        if (r >= 0)
+                if (asprintf(&machine_id, "_MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], machine_id);
+
+        t = gethostname_malloc();
+        if (t) {
+                hostname = strappend("_HOSTNAME=", t);
+                free(t);
+                if (hostname)
+                        IOVEC_SET_STRING(iovec[n++], hostname);
+        }
+
+        assert(n <= m);
+
+        write_to_journal(s,
+                         s->split_mode == SPLIT_NONE ? 0 :
+                         (s->split_mode == SPLIT_UID ? realuid :
+                          (realuid == 0 ? 0 : loginuid)), iovec, n);
+
+        free(pid);
+        free(uid);
+        free(gid);
+        free(comm);
+        free(exe);
+        free(cmdline);
+        free(source_time);
+        free(boot_id);
+        free(machine_id);
+        free(hostname);
+        free(audit_session);
+        free(audit_loginuid);
+        free(cgroup);
+        free(session);
+        free(owner_uid);
+        free(unit);
+        free(selinux_context);
+}
+
+void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
+        char mid[11 + 32 + 1];
+        char buffer[16 + LINE_MAX + 1];
+        struct iovec iovec[N_IOVEC_META_FIELDS + 4];
+        int n = 0;
+        va_list ap;
+        struct ucred ucred;
+
+        assert(s);
+        assert(format);
+
+        IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
+        IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
+
+        memcpy(buffer, "MESSAGE=", 8);
+        va_start(ap, format);
+        vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap);
+        va_end(ap);
+        char_array_0(buffer);
+        IOVEC_SET_STRING(iovec[n++], buffer);
+
+        if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
+                snprintf(mid, sizeof(mid), MESSAGE_ID(message_id));
+                char_array_0(mid);
+                IOVEC_SET_STRING(iovec[n++], mid);
+        }
+
+        zero(ucred);
+        ucred.pid = getpid();
+        ucred.uid = getuid();
+        ucred.gid = getgid();
+
+        dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL);
+}
+
+void server_dispatch_message(
+                Server *s,
+                struct iovec *iovec, unsigned n, unsigned m,
+                struct ucred *ucred,
+                struct timeval *tv,
+                const char *label, size_t label_len,
+                const char *unit_id,
+                int priority) {
+
+        int rl;
+        char *path = NULL, *c;
+
+        assert(s);
+        assert(iovec || n == 0);
+
+        if (n == 0)
+                return;
+
+        if (LOG_PRI(priority) > s->max_level_store)
+                return;
+
+        if (!ucred)
+                goto finish;
+
+        path = shortened_cgroup_path(ucred->pid);
+        if (!path)
+                goto finish;
+
+        /* example: /user/lennart/3/foobar
+         *          /system/dbus.service/foobar
+         *
+         * So let's cut of everything past the third /, since that is
+         * where user directories start */
+
+        c = strchr(path, '/');
+        if (c) {
+                c = strchr(c+1, '/');
+                if (c) {
+                        c = strchr(c+1, '/');
+                        if (c)
+                                *c = 0;
+                }
+        }
+
+        rl = journal_rate_limit_test(s->rate_limit, path, priority & LOG_PRIMASK, available_space(s));
+
+        if (rl == 0) {
+                free(path);
+                return;
+        }
+
+        /* Write a suppression message if we suppressed something */
+        if (rl > 1)
+                server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED, "Suppressed %u messages from %s", rl - 1, path);
+
+        free(path);
+
+finish:
+        dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id);
+}
+
+
+static int system_journal_open(Server *s) {
+        int r;
+        char *fn;
+        sd_id128_t machine;
+        char ids[33];
+
+        r = sd_id128_get_machine(&machine);
+        if (r < 0)
+                return r;
+
+        sd_id128_to_string(machine, ids);
+
+        if (!s->system_journal &&
+            (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
+            access("/run/systemd/journal/flushed", F_OK) >= 0) {
+
+                /* If in auto mode: first try to create the machine
+                 * path, but not the prefix.
+                 *
+                 * If in persistent mode: create /var/log/journal and
+                 * the machine path */
+
+                if (s->storage == STORAGE_PERSISTENT)
+                        (void) mkdir("/var/log/journal/", 0755);
+
+                fn = strappend("/var/log/journal/", ids);
+                if (!fn)
+                        return -ENOMEM;
+
+                (void) mkdir(fn, 0755);
+                free(fn);
+
+                fn = strjoin("/var/log/journal/", ids, "/system.journal", NULL);
+                if (!fn)
+                        return -ENOMEM;
+
+                r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
+                free(fn);
+
+                if (r >= 0) {
+                        char fb[FORMAT_BYTES_MAX];
+
+                        server_fix_perms(s, s->system_journal, 0);
+                        server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.",
+                                              format_bytes(fb, sizeof(fb), s->system_metrics.max_use));
+
+                } else if (r < 0) {
+
+                        if (r != -ENOENT && r != -EROFS)
+                                log_warning("Failed to open system journal: %s", strerror(-r));
+
+                        r = 0;
+                }
+        }
+
+        if (!s->runtime_journal &&
+            (s->storage != STORAGE_NONE)) {
+
+                fn = strjoin("/run/log/journal/", ids, "/system.journal", NULL);
+                if (!fn)
+                        return -ENOMEM;
+
+                if (s->system_journal) {
+
+                        /* Try to open the runtime journal, but only
+                         * if it already exists, so that we can flush
+                         * it into the system journal */
+
+                        r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
+                        free(fn);
+
+                        if (r < 0) {
+                                if (r != -ENOENT)
+                                        log_warning("Failed to open runtime journal: %s", strerror(-r));
+
+                                r = 0;
+                        }
+
+                } else {
+
+                        /* OK, we really need the runtime journal, so create
+                         * it if necessary. */
+
+                        (void) mkdir_parents(fn, 0755);
+                        r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
+                        free(fn);
+
+                        if (r < 0) {
+                                log_error("Failed to open runtime journal: %s", strerror(-r));
+                                return r;
+                        }
+                }
+
+                if (s->runtime_journal) {
+                        char fb[FORMAT_BYTES_MAX];
+
+                        server_fix_perms(s, s->runtime_journal, 0);
+                        server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.",
+                                              format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use));
+                }
+        }
+
+        return r;
+}
+
+int server_flush_to_var(Server *s) {
+        int r;
+        sd_id128_t machine;
+        sd_journal *j = NULL;
+
+        assert(s);
+
+        if (s->storage != STORAGE_AUTO &&
+            s->storage != STORAGE_PERSISTENT)
+                return 0;
+
+        if (!s->runtime_journal)
+                return 0;
+
+        system_journal_open(s);
+
+        if (!s->system_journal)
+                return 0;
+
+        log_debug("Flushing to /var...");
+
+        r = sd_id128_get_machine(&machine);
+        if (r < 0) {
+                log_error("Failed to get machine id: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY);
+        if (r < 0) {
+                log_error("Failed to read runtime journal: %s", strerror(-r));
+                return r;
+        }
+
+        sd_journal_set_data_threshold(j, 0);
+
+        SD_JOURNAL_FOREACH(j) {
+                Object *o = NULL;
+                JournalFile *f;
+
+                f = j->current_file;
+                assert(f && f->current_offset > 0);
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+                if (r < 0) {
+                        log_error("Can't read entry: %s", strerror(-r));
+                        goto finish;
+                }
+
+                r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
+                if (r >= 0)
+                        continue;
+
+                if (!shall_try_append_again(s->system_journal, r)) {
+                        log_error("Can't write entry: %s", strerror(-r));
+                        goto finish;
+                }
+
+                server_rotate(s);
+                server_vacuum(s);
+
+                log_debug("Retrying write.");
+                r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
+                if (r < 0) {
+                        log_error("Can't write entry: %s", strerror(-r));
+                        goto finish;
+                }
+        }
+
+finish:
+        journal_file_post_change(s->system_journal);
+
+        journal_file_close(s->runtime_journal);
+        s->runtime_journal = NULL;
+
+        if (r >= 0)
+                rm_rf("/run/log/journal", false, true, false);
+
+        if (j)
+                sd_journal_close(j);
+
+        return r;
+}
+
+int process_event(Server *s, struct epoll_event *ev) {
+        assert(s);
+        assert(ev);
+
+        if (ev->data.fd == s->signal_fd) {
+                struct signalfd_siginfo sfsi;
+                ssize_t n;
+
+                if (ev->events != EPOLLIN) {
+                        log_error("Got invalid event from epoll.");
+                        return -EIO;
+                }
+
+                n = read(s->signal_fd, &sfsi, sizeof(sfsi));
+                if (n != sizeof(sfsi)) {
+
+                        if (n >= 0)
+                                return -EIO;
+
+                        if (errno == EINTR || errno == EAGAIN)
+                                return 1;
+
+                        return -errno;
+                }
+
+                log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo));
+
+                if (sfsi.ssi_signo == SIGUSR1) {
+                        touch("/run/systemd/journal/flushed");
+                        server_flush_to_var(s);
+                        return 1;
+                }
+
+                if (sfsi.ssi_signo == SIGUSR2) {
+                        server_rotate(s);
+                        server_vacuum(s);
+                        return 1;
+                }
+
+                return 0;
+
+        } else if (ev->data.fd == s->dev_kmsg_fd) {
+                int r;
+
+                if (ev->events != EPOLLIN) {
+                        log_error("Got invalid event from epoll.");
+                        return -EIO;
+                }
+
+                r = server_read_dev_kmsg(s);
+                if (r < 0)
+                        return r;
+
+                return 1;
+
+        } else if (ev->data.fd == s->native_fd ||
+                   ev->data.fd == s->syslog_fd) {
+
+                if (ev->events != EPOLLIN) {
+                        log_error("Got invalid event from epoll.");
+                        return -EIO;
+                }
+
+                for (;;) {
+                        struct msghdr msghdr;
+                        struct iovec iovec;
+                        struct ucred *ucred = NULL;
+                        struct timeval *tv = NULL;
+                        struct cmsghdr *cmsg;
+                        char *label = NULL;
+                        size_t label_len = 0;
+                        union {
+                                struct cmsghdr cmsghdr;
+
+                                /* We use NAME_MAX space for the
+                                 * SELinux label here. The kernel
+                                 * currently enforces no limit, but
+                                 * according to suggestions from the
+                                 * SELinux people this will change and
+                                 * it will probably be identical to
+                                 * NAME_MAX. For now we use that, but
+                                 * this should be updated one day when
+                                 * the final limit is known.*/
+                                uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
+                                            CMSG_SPACE(sizeof(struct timeval)) +
+                                            CMSG_SPACE(sizeof(int)) + /* fd */
+                                            CMSG_SPACE(NAME_MAX)]; /* selinux label */
+                        } control;
+                        ssize_t n;
+                        int v;
+                        int *fds = NULL;
+                        unsigned n_fds = 0;
+
+                        if (ioctl(ev->data.fd, SIOCINQ, &v) < 0) {
+                                log_error("SIOCINQ failed: %m");
+                                return -errno;
+                        }
+
+                        if (s->buffer_size < (size_t) v) {
+                                void *b;
+                                size_t l;
+
+                                l = MAX(LINE_MAX + (size_t) v, s->buffer_size * 2);
+                                b = realloc(s->buffer, l+1);
+
+                                if (!b) {
+                                        log_error("Couldn't increase buffer.");
+                                        return -ENOMEM;
+                                }
+
+                                s->buffer_size = l;
+                                s->buffer = b;
+                        }
+
+                        zero(iovec);
+                        iovec.iov_base = s->buffer;
+                        iovec.iov_len = s->buffer_size;
+
+                        zero(control);
+                        zero(msghdr);
+                        msghdr.msg_iov = &iovec;
+                        msghdr.msg_iovlen = 1;
+                        msghdr.msg_control = &control;
+                        msghdr.msg_controllen = sizeof(control);
+
+                        n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
+                        if (n < 0) {
+
+                                if (errno == EINTR || errno == EAGAIN)
+                                        return 1;
+
+                                log_error("recvmsg() failed: %m");
+                                return -errno;
+                        }
+
+                        for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
+
+                                if (cmsg->cmsg_level == SOL_SOCKET &&
+                                    cmsg->cmsg_type == SCM_CREDENTIALS &&
+                                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
+                                        ucred = (struct ucred*) CMSG_DATA(cmsg);
+                                else if (cmsg->cmsg_level == SOL_SOCKET &&
+                                         cmsg->cmsg_type == SCM_SECURITY) {
+                                        label = (char*) CMSG_DATA(cmsg);
+                                        label_len = cmsg->cmsg_len - CMSG_LEN(0);
+                                } else if (cmsg->cmsg_level == SOL_SOCKET &&
+                                         cmsg->cmsg_type == SO_TIMESTAMP &&
+                                         cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
+                                        tv = (struct timeval*) CMSG_DATA(cmsg);
+                                else if (cmsg->cmsg_level == SOL_SOCKET &&
+                                         cmsg->cmsg_type == SCM_RIGHTS) {
+                                        fds = (int*) CMSG_DATA(cmsg);
+                                        n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+                                }
+                        }
+
+                        if (ev->data.fd == s->syslog_fd) {
+                                char *e;
+
+                                if (n > 0 && n_fds == 0) {
+                                        e = memchr(s->buffer, '\n', n);
+                                        if (e)
+                                                *e = 0;
+                                        else
+                                                s->buffer[n] = 0;
+
+                                        server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
+                                } else if (n_fds > 0)
+                                        log_warning("Got file descriptors via syslog socket. Ignoring.");
+
+                        } else {
+                                if (n > 0 && n_fds == 0)
+                                        server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len);
+                                else if (n == 0 && n_fds == 1)
+                                        server_process_native_file(s, fds[0], ucred, tv, label, label_len);
+                                else if (n_fds > 0)
+                                        log_warning("Got too many file descriptors via native socket. Ignoring.");
+                        }
+
+                        close_many(fds, n_fds);
+                }
+
+                return 1;
+
+        } else if (ev->data.fd == s->stdout_fd) {
+
+                if (ev->events != EPOLLIN) {
+                        log_error("Got invalid event from epoll.");
+                        return -EIO;
+                }
+
+                stdout_stream_new(s);
+                return 1;
+
+        } else {
+                StdoutStream *stream;
+
+                if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
+                        log_error("Got invalid event from epoll.");
+                        return -EIO;
+                }
+
+                /* If it is none of the well-known fds, it must be an
+                 * stdout stream fd. Note that this is a bit ugly here
+                 * (since we rely that none of the well-known fds
+                 * could be interpreted as pointer), but nonetheless
+                 * safe, since the well-known fds would never get an
+                 * fd > 4096, i.e. beyond the first memory page */
+
+                stream = ev->data.ptr;
+
+                if (stdout_stream_process(stream) <= 0)
+                        stdout_stream_free(stream);
+
+                return 1;
+        }
+
+        log_error("Unknown event.");
+        return 0;
+}
+
+static int open_signalfd(Server *s) {
+        sigset_t mask;
+        struct epoll_event ev;
+
+        assert(s);
+
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, -1);
+        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+        s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (s->signal_fd < 0) {
+                log_error("signalfd(): %m");
+                return -errno;
+        }
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.fd = s->signal_fd;
+
+        if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) {
+                log_error("epoll_ctl(): %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+static int server_parse_proc_cmdline(Server *s) {
+        char *line, *w, *state;
+        int r;
+        size_t l;
+
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        r = read_one_line_file("/proc/cmdline", &line);
+        if (r < 0) {
+                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                char *word;
+
+                word = strndup(w, l);
+                if (!word) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (startswith(word, "systemd.journald.forward_to_syslog=")) {
+                        r = parse_boolean(word + 35);
+                        if (r < 0)
+                                log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35);
+                        else
+                                s->forward_to_syslog = r;
+                } else if (startswith(word, "systemd.journald.forward_to_kmsg=")) {
+                        r = parse_boolean(word + 33);
+                        if (r < 0)
+                                log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33);
+                        else
+                                s->forward_to_kmsg = r;
+                } else if (startswith(word, "systemd.journald.forward_to_console=")) {
+                        r = parse_boolean(word + 36);
+                        if (r < 0)
+                                log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
+                        else
+                                s->forward_to_console = r;
+                } else if (startswith(word, "systemd.journald"))
+                        log_warning("Invalid systemd.journald parameter. Ignoring.");
+
+                free(word);
+        }
+
+        r = 0;
+
+finish:
+        free(line);
+        return r;
+}
+
+static int server_parse_config_file(Server *s) {
+        FILE *f;
+        const char *fn;
+        int r;
+
+        assert(s);
+
+        fn = "/etc/systemd/journald.conf";
+        f = fopen(fn, "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_warning("Failed to open configuration file %s: %m", fn);
+                return -errno;
+        }
+
+        r = config_parse(fn, f, "Journal\0", config_item_perf_lookup, (void*) journald_gperf_lookup, false, s);
+        if (r < 0)
+                log_warning("Failed to parse configuration file: %s", strerror(-r));
+
+        fclose(f);
+
+        return r;
+}
+
+int server_init(Server *s) {
+        int n, r, fd;
+
+        assert(s);
+
+        zero(*s);
+        s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1;
+        s->compress = true;
+        s->seal = true;
+
+        s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
+        s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
+
+        s->forward_to_syslog = true;
+
+        s->max_level_store = LOG_DEBUG;
+        s->max_level_syslog = LOG_DEBUG;
+        s->max_level_kmsg = LOG_NOTICE;
+        s->max_level_console = LOG_INFO;
+
+        memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics));
+        memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics));
+
+        server_parse_config_file(s);
+        server_parse_proc_cmdline(s);
+
+        mkdir_p("/run/systemd/journal", 0755);
+
+        s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func);
+        if (!s->user_journals)
+                return log_oom();
+
+        s->mmap = mmap_cache_new();
+        if (!s->mmap)
+                return log_oom();
+
+        s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+        if (s->epoll_fd < 0) {
+                log_error("Failed to create epoll object: %m");
+                return -errno;
+        }
+
+        n = sd_listen_fds(true);
+        if (n < 0) {
+                log_error("Failed to read listening file descriptors from environment: %s", strerror(-n));
+                return n;
+        }
+
+        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
+
+                if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/socket", 0) > 0) {
+
+                        if (s->native_fd >= 0) {
+                                log_error("Too many native sockets passed.");
+                                return -EINVAL;
+                        }
+
+                        s->native_fd = fd;
+
+                } else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, "/run/systemd/journal/stdout", 0) > 0) {
+
+                        if (s->stdout_fd >= 0) {
+                                log_error("Too many stdout sockets passed.");
+                                return -EINVAL;
+                        }
+
+                        s->stdout_fd = fd;
+
+                } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0) {
+
+                        if (s->syslog_fd >= 0) {
+                                log_error("Too many /dev/log sockets passed.");
+                                return -EINVAL;
+                        }
+
+                        s->syslog_fd = fd;
+
+                } else {
+                        log_error("Unknown socket passed.");
+                        return -EINVAL;
+                }
+        }
+
+        r = server_open_syslog_socket(s);
+        if (r < 0)
+                return r;
+
+        r = server_open_native_socket(s);
+        if (r < 0)
+                return r;
+
+        r = server_open_stdout_socket(s);
+        if (r < 0)
+                return r;
+
+        r = server_open_dev_kmsg(s);
+        if (r < 0)
+                return r;
+
+        r = server_open_kernel_seqnum(s);
+        if (r < 0)
+                return r;
+
+        r = open_signalfd(s);
+        if (r < 0)
+                return r;
+
+        s->udev = udev_new();
+        if (!s->udev)
+                return -ENOMEM;
+
+        s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst);
+        if (!s->rate_limit)
+                return -ENOMEM;
+
+        r = system_journal_open(s);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+void server_maybe_append_tags(Server *s) {
+#ifdef HAVE_GCRYPT
+        JournalFile *f;
+        Iterator i;
+        usec_t n;
+
+        n = now(CLOCK_REALTIME);
+
+        if (s->system_journal)
+                journal_file_maybe_append_tag(s->system_journal, n);
+
+        HASHMAP_FOREACH(f, s->user_journals, i)
+                journal_file_maybe_append_tag(f, n);
+#endif
+}
+
+void server_done(Server *s) {
+        JournalFile *f;
+        assert(s);
+
+        while (s->stdout_streams)
+                stdout_stream_free(s->stdout_streams);
+
+        if (s->system_journal)
+                journal_file_close(s->system_journal);
+
+        if (s->runtime_journal)
+                journal_file_close(s->runtime_journal);
+
+        while ((f = hashmap_steal_first(s->user_journals)))
+                journal_file_close(f);
+
+        hashmap_free(s->user_journals);
+
+        if (s->epoll_fd >= 0)
+                close_nointr_nofail(s->epoll_fd);
+
+        if (s->signal_fd >= 0)
+                close_nointr_nofail(s->signal_fd);
+
+        if (s->syslog_fd >= 0)
+                close_nointr_nofail(s->syslog_fd);
+
+        if (s->native_fd >= 0)
+                close_nointr_nofail(s->native_fd);
+
+        if (s->stdout_fd >= 0)
+                close_nointr_nofail(s->stdout_fd);
+
+        if (s->dev_kmsg_fd >= 0)
+                close_nointr_nofail(s->dev_kmsg_fd);
+
+        if (s->rate_limit)
+                journal_rate_limit_free(s->rate_limit);
+
+        if (s->kernel_seqnum)
+                munmap(s->kernel_seqnum, sizeof(uint64_t));
+
+        free(s->buffer);
+        free(s->tty_path);
+
+        if (s->mmap)
+                mmap_cache_unref(s->mmap);
+
+        if (s->udev)
+                udev_unref(s->udev);
+}
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
new file mode 100644 (file)
index 0000000..9f50a29
--- /dev/null
@@ -0,0 +1,152 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <sys/epoll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "journal-file.h"
+#include "hashmap.h"
+#include "util.h"
+#include "audit.h"
+#include "journald-rate-limit.h"
+#include "list.h"
+
+typedef enum Storage {
+        STORAGE_AUTO,
+        STORAGE_VOLATILE,
+        STORAGE_PERSISTENT,
+        STORAGE_NONE,
+        _STORAGE_MAX,
+        _STORAGE_INVALID = -1
+} Storage;
+
+typedef enum SplitMode {
+        SPLIT_LOGIN,
+        SPLIT_UID,
+        SPLIT_NONE,
+        _SPLIT_MAX,
+        _SPLIT_INVALID = -1
+} SplitMode;
+
+typedef struct StdoutStream StdoutStream;
+
+typedef struct Server {
+        int epoll_fd;
+        int signal_fd;
+        int syslog_fd;
+        int native_fd;
+        int stdout_fd;
+        int dev_kmsg_fd;
+
+        JournalFile *runtime_journal;
+        JournalFile *system_journal;
+        Hashmap *user_journals;
+
+        uint64_t seqnum;
+
+        char *buffer;
+        size_t buffer_size;
+
+        JournalRateLimit *rate_limit;
+        usec_t rate_limit_interval;
+        unsigned rate_limit_burst;
+
+        JournalMetrics runtime_metrics;
+        JournalMetrics system_metrics;
+
+        bool compress;
+        bool seal;
+
+        bool forward_to_kmsg;
+        bool forward_to_syslog;
+        bool forward_to_console;
+
+        unsigned n_forward_syslog_missed;
+        usec_t last_warn_forward_syslog_missed;
+
+        uint64_t cached_available_space;
+        usec_t cached_available_space_timestamp;
+
+        uint64_t var_available_timestamp;
+
+        usec_t max_retention_usec;
+        usec_t max_file_usec;
+        usec_t oldest_file_usec;
+
+        gid_t file_gid;
+        bool file_gid_valid;
+
+        LIST_HEAD(StdoutStream, stdout_streams);
+        unsigned n_stdout_streams;
+
+        char *tty_path;
+
+        int max_level_store;
+        int max_level_syslog;
+        int max_level_kmsg;
+        int max_level_console;
+
+        Storage storage;
+        SplitMode split_mode;
+
+        MMapCache *mmap;
+
+        bool dev_kmsg_readable;
+
+        uint64_t *kernel_seqnum;
+
+        struct udev *udev;
+} Server;
+
+#define N_IOVEC_META_FIELDS 17
+#define N_IOVEC_KERNEL_FIELDS 64
+#define N_IOVEC_UDEV_FIELDS 32
+
+void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len, const char *unit_id, int priority);
+void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...);
+
+/* gperf lookup function */
+const struct ConfigPerfItem* journald_gperf_lookup(const char *key, unsigned length);
+
+int config_parse_storage(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+const char *storage_to_string(Storage s);
+Storage storage_from_string(const char *s);
+
+int config_parse_split_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+const char *split_mode_to_string(SplitMode s);
+SplitMode split_mode_from_string(const char *s);
+
+void server_fix_perms(Server *s, JournalFile *f, uid_t uid);
+bool shall_try_append_again(JournalFile *f, int r);
+int server_init(Server *s);
+void server_done(Server *s);
+void server_vacuum(Server *s);
+void server_rotate(Server *s);
+int server_flush_to_var(Server *s);
+int process_event(Server *s, struct epoll_event *ev);
+void server_maybe_append_tags(Server *s);
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
new file mode 100644 (file)
index 0000000..7b88f74
--- /dev/null
@@ -0,0 +1,459 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/epoll.h>
+
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#include "socket-util.h"
+#include "journald-server.h"
+#include "journald-stream.h"
+#include "journald-syslog.h"
+#include "journald-kmsg.h"
+#include "journald-console.h"
+
+#define STDOUT_STREAMS_MAX 4096
+
+typedef enum StdoutStreamState {
+        STDOUT_STREAM_IDENTIFIER,
+        STDOUT_STREAM_UNIT_ID,
+        STDOUT_STREAM_PRIORITY,
+        STDOUT_STREAM_LEVEL_PREFIX,
+        STDOUT_STREAM_FORWARD_TO_SYSLOG,
+        STDOUT_STREAM_FORWARD_TO_KMSG,
+        STDOUT_STREAM_FORWARD_TO_CONSOLE,
+        STDOUT_STREAM_RUNNING
+} StdoutStreamState;
+
+struct StdoutStream {
+        Server *server;
+        StdoutStreamState state;
+
+        int fd;
+
+        struct ucred ucred;
+#ifdef HAVE_SELINUX
+        security_context_t security_context;
+#endif
+
+        char *identifier;
+        char *unit_id;
+        int priority;
+        bool level_prefix:1;
+        bool forward_to_syslog:1;
+        bool forward_to_kmsg:1;
+        bool forward_to_console:1;
+
+        char buffer[LINE_MAX+1];
+        size_t length;
+
+        LIST_FIELDS(StdoutStream, stdout_stream);
+};
+
+static int stdout_stream_log(StdoutStream *s, const char *p) {
+        struct iovec iovec[N_IOVEC_META_FIELDS + 5];
+        char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL;
+        unsigned n = 0;
+        int priority;
+        char *label = NULL;
+        size_t label_len = 0;
+
+        assert(s);
+        assert(p);
+
+        if (isempty(p))
+                return 0;
+
+        priority = s->priority;
+
+        if (s->level_prefix)
+                syslog_parse_priority((char**) &p, &priority);
+
+        if (s->forward_to_syslog || s->server->forward_to_syslog)
+                server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);
+
+        if (s->forward_to_kmsg || s->server->forward_to_kmsg)
+                server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
+
+        if (s->forward_to_console || s->server->forward_to_console)
+                server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
+
+        IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
+
+        if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
+                IOVEC_SET_STRING(iovec[n++], syslog_priority);
+
+        if (priority & LOG_FACMASK)
+                if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], syslog_facility);
+
+        if (s->identifier) {
+                syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
+                if (syslog_identifier)
+                        IOVEC_SET_STRING(iovec[n++], syslog_identifier);
+        }
+
+        message = strappend("MESSAGE=", p);
+        if (message)
+                IOVEC_SET_STRING(iovec[n++], message);
+
+#ifdef HAVE_SELINUX
+        if (s->security_context) {
+                label = (char*) s->security_context;
+                label_len = strlen((char*) s->security_context);
+        }
+#endif
+
+        server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority);
+
+        free(message);
+        free(syslog_priority);
+        free(syslog_facility);
+        free(syslog_identifier);
+
+        return 0;
+}
+
+static int stdout_stream_line(StdoutStream *s, char *p) {
+        int r;
+
+        assert(s);
+        assert(p);
+
+        p = strstrip(p);
+
+        switch (s->state) {
+
+        case STDOUT_STREAM_IDENTIFIER:
+                if (isempty(p))
+                        s->identifier = NULL;
+                else  {
+                        s->identifier = strdup(p);
+                        if (!s->identifier)
+                                return log_oom();
+                }
+
+                s->state = STDOUT_STREAM_UNIT_ID;
+                return 0;
+
+        case STDOUT_STREAM_UNIT_ID:
+                if (s->ucred.uid == 0) {
+                        if (isempty(p))
+                                s->unit_id = NULL;
+                        else  {
+                                s->unit_id = strdup(p);
+                                if (!s->unit_id)
+                                        return log_oom();
+                        }
+                }
+
+                s->state = STDOUT_STREAM_PRIORITY;
+                return 0;
+
+        case STDOUT_STREAM_PRIORITY:
+                r = safe_atoi(p, &s->priority);
+                if (r < 0 || s->priority <= 0 || s->priority >= 999) {
+                        log_warning("Failed to parse log priority line.");
+                        return -EINVAL;
+                }
+
+                s->state = STDOUT_STREAM_LEVEL_PREFIX;
+                return 0;
+
+        case STDOUT_STREAM_LEVEL_PREFIX:
+                r = parse_boolean(p);
+                if (r < 0) {
+                        log_warning("Failed to parse level prefix line.");
+                        return -EINVAL;
+                }
+
+                s->level_prefix = !!r;
+                s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
+                return 0;
+
+        case STDOUT_STREAM_FORWARD_TO_SYSLOG:
+                r = parse_boolean(p);
+                if (r < 0) {
+                        log_warning("Failed to parse forward to syslog line.");
+                        return -EINVAL;
+                }
+
+                s->forward_to_syslog = !!r;
+                s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
+                return 0;
+
+        case STDOUT_STREAM_FORWARD_TO_KMSG:
+                r = parse_boolean(p);
+                if (r < 0) {
+                        log_warning("Failed to parse copy to kmsg line.");
+                        return -EINVAL;
+                }
+
+                s->forward_to_kmsg = !!r;
+                s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
+                return 0;
+
+        case STDOUT_STREAM_FORWARD_TO_CONSOLE:
+                r = parse_boolean(p);
+                if (r < 0) {
+                        log_warning("Failed to parse copy to console line.");
+                        return -EINVAL;
+                }
+
+                s->forward_to_console = !!r;
+                s->state = STDOUT_STREAM_RUNNING;
+                return 0;
+
+        case STDOUT_STREAM_RUNNING:
+                return stdout_stream_log(s, p);
+        }
+
+        assert_not_reached("Unknown stream state");
+}
+
+static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
+        char *p;
+        size_t remaining;
+        int r;
+
+        assert(s);
+
+        p = s->buffer;
+        remaining = s->length;
+        for (;;) {
+                char *end;
+                size_t skip;
+
+                end = memchr(p, '\n', remaining);
+                if (end)
+                        skip = end - p + 1;
+                else if (remaining >= sizeof(s->buffer) - 1) {
+                        end = p + sizeof(s->buffer) - 1;
+                        skip = remaining;
+                } else
+                        break;
+
+                *end = 0;
+
+                r = stdout_stream_line(s, p);
+                if (r < 0)
+                        return r;
+
+                remaining -= skip;
+                p += skip;
+        }
+
+        if (force_flush && remaining > 0) {
+                p[remaining] = 0;
+                r = stdout_stream_line(s, p);
+                if (r < 0)
+                        return r;
+
+                p += remaining;
+                remaining = 0;
+        }
+
+        if (p > s->buffer) {
+                memmove(s->buffer, p, remaining);
+                s->length = remaining;
+        }
+
+        return 0;
+}
+
+int stdout_stream_process(StdoutStream *s) {
+        ssize_t l;
+        int r;
+
+        assert(s);
+
+        l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
+        if (l < 0) {
+
+                if (errno == EAGAIN)
+                        return 0;
+
+                log_warning("Failed to read from stream: %m");
+                return -errno;
+        }
+
+        if (l == 0) {
+                r = stdout_stream_scan(s, true);
+                if (r < 0)
+                        return r;
+
+                return 0;
+        }
+
+        s->length += l;
+        r = stdout_stream_scan(s, false);
+        if (r < 0)
+                return r;
+
+        return 1;
+
+}
+
+void stdout_stream_free(StdoutStream *s) {
+        assert(s);
+
+        if (s->server) {
+                assert(s->server->n_stdout_streams > 0);
+                s->server->n_stdout_streams --;
+                LIST_REMOVE(StdoutStream, stdout_stream, s->server->stdout_streams, s);
+        }
+
+        if (s->fd >= 0) {
+                if (s->server)
+                        epoll_ctl(s->server->epoll_fd, EPOLL_CTL_DEL, s->fd, NULL);
+
+                close_nointr_nofail(s->fd);
+        }
+
+#ifdef HAVE_SELINUX
+        if (s->security_context)
+                freecon(s->security_context);
+#endif
+
+        free(s->identifier);
+        free(s);
+}
+
+int stdout_stream_new(Server *s) {
+        StdoutStream *stream;
+        int fd, r;
+        socklen_t len;
+        struct epoll_event ev;
+
+        assert(s);
+
+        fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
+        if (fd < 0) {
+                if (errno == EAGAIN)
+                        return 0;
+
+                log_error("Failed to accept stdout connection: %m");
+                return -errno;
+        }
+
+        if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
+                log_warning("Too many stdout streams, refusing connection.");
+                close_nointr_nofail(fd);
+                return 0;
+        }
+
+        stream = new0(StdoutStream, 1);
+        if (!stream) {
+                close_nointr_nofail(fd);
+                return log_oom();
+        }
+
+        stream->fd = fd;
+
+        len = sizeof(stream->ucred);
+        if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &stream->ucred, &len) < 0) {
+                log_error("Failed to determine peer credentials: %m");
+                r = -errno;
+                goto fail;
+        }
+
+#ifdef HAVE_SELINUX
+        if (getpeercon(fd, &stream->security_context) < 0 && errno != ENOPROTOOPT)
+                log_error("Failed to determine peer security context: %m");
+#endif
+
+        if (shutdown(fd, SHUT_WR) < 0) {
+                log_error("Failed to shutdown writing side of socket: %m");
+                r = -errno;
+                goto fail;
+        }
+
+        zero(ev);
+        ev.data.ptr = stream;
+        ev.events = EPOLLIN;
+        if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
+                log_error("Failed to add stream to event loop: %m");
+                r = -errno;
+                goto fail;
+        }
+
+        stream->server = s;
+        LIST_PREPEND(StdoutStream, stdout_stream, s->stdout_streams, stream);
+        s->n_stdout_streams ++;
+
+        return 0;
+
+fail:
+        stdout_stream_free(stream);
+        return r;
+}
+
+int server_open_stdout_socket(Server *s) {
+        union sockaddr_union sa;
+        int r;
+        struct epoll_event ev;
+
+        assert(s);
+
+        if (s->stdout_fd < 0) {
+
+                s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+                if (s->stdout_fd < 0) {
+                        log_error("socket() failed: %m");
+                        return -errno;
+                }
+
+                zero(sa);
+                sa.un.sun_family = AF_UNIX;
+                strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path));
+
+                unlink(sa.un.sun_path);
+
+                r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+                if (r < 0) {
+                        log_error("bind() failed: %m");
+                        return -errno;
+                }
+
+                chmod(sa.un.sun_path, 0666);
+
+                if (listen(s->stdout_fd, SOMAXCONN) < 0) {
+                        log_error("liste() failed: %m");
+                        return -errno;
+                }
+        } else
+                fd_nonblock(s->stdout_fd, 1);
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.fd = s->stdout_fd;
+        if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->stdout_fd, &ev) < 0) {
+                log_error("Failed to add stdout server fd to epoll object: %m");
+                return -errno;
+        }
+
+        return 0;
+}
diff --git a/src/journal/journald-stream.h b/src/journal/journald-stream.h
new file mode 100644 (file)
index 0000000..dfb6267
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journald-server.h"
+
+int server_open_stdout_socket(Server *s);
+
+int stdout_stream_new(Server *s);
+void stdout_stream_free(StdoutStream *s);
+int stdout_stream_process(StdoutStream *s);
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
new file mode 100644 (file)
index 0000000..afddca3
--- /dev/null
@@ -0,0 +1,492 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/epoll.h>
+
+#include "systemd/sd-messages.h"
+#include "socket-util.h"
+#include "journald-server.h"
+#include "journald-syslog.h"
+#include "journald-kmsg.h"
+#include "journald-console.h"
+
+/* Warn once every 30s if we missed syslog message */
+#define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC)
+
+static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) {
+        struct msghdr msghdr;
+        struct cmsghdr *cmsg;
+        union {
+                struct cmsghdr cmsghdr;
+                uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
+        } control;
+        union sockaddr_union sa;
+
+        assert(s);
+        assert(iovec);
+        assert(n_iovec > 0);
+
+        zero(msghdr);
+        msghdr.msg_iov = (struct iovec*) iovec;
+        msghdr.msg_iovlen = n_iovec;
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, "/run/systemd/journal/syslog", sizeof(sa.un.sun_path));
+        msghdr.msg_name = &sa;
+        msghdr.msg_namelen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
+
+        if (ucred) {
+                zero(control);
+                msghdr.msg_control = &control;
+                msghdr.msg_controllen = sizeof(control);
+
+                cmsg = CMSG_FIRSTHDR(&msghdr);
+                cmsg->cmsg_level = SOL_SOCKET;
+                cmsg->cmsg_type = SCM_CREDENTIALS;
+                cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
+                memcpy(CMSG_DATA(cmsg), ucred, sizeof(struct ucred));
+                msghdr.msg_controllen = cmsg->cmsg_len;
+        }
+
+        /* Forward the syslog message we received via /dev/log to
+         * /run/systemd/syslog. Unfortunately we currently can't set
+         * the SO_TIMESTAMP auxiliary data, and hence we don't. */
+
+        if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
+                return;
+
+        /* The socket is full? I guess the syslog implementation is
+         * too slow, and we shouldn't wait for that... */
+        if (errno == EAGAIN) {
+                s->n_forward_syslog_missed++;
+                return;
+        }
+
+        if (ucred && errno == ESRCH) {
+                struct ucred u;
+
+                /* Hmm, presumably the sender process vanished
+                 * by now, so let's fix it as good as we
+                 * can, and retry */
+
+                u = *ucred;
+                u.pid = getpid();
+                memcpy(CMSG_DATA(cmsg), &u, sizeof(struct ucred));
+
+                if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
+                        return;
+
+                if (errno == EAGAIN) {
+                        s->n_forward_syslog_missed++;
+                        return;
+                }
+        }
+
+        if (errno != ENOENT)
+                log_debug("Failed to forward syslog message: %m");
+}
+
+static void forward_syslog_raw(Server *s, int priority, const char *buffer, struct ucred *ucred, struct timeval *tv) {
+        struct iovec iovec;
+
+        assert(s);
+        assert(buffer);
+
+        if (LOG_PRI(priority) > s->max_level_syslog)
+                return;
+
+        IOVEC_SET_STRING(iovec, buffer);
+        forward_syslog_iovec(s, &iovec, 1, ucred, tv);
+}
+
+void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv) {
+        struct iovec iovec[5];
+        char header_priority[6], header_time[64], header_pid[16];
+        int n = 0;
+        time_t t;
+        struct tm *tm;
+        char *ident_buf = NULL;
+
+        assert(s);
+        assert(priority >= 0);
+        assert(priority <= 999);
+        assert(message);
+
+        if (LOG_PRI(priority) > s->max_level_syslog)
+                return;
+
+        /* First: priority field */
+        snprintf(header_priority, sizeof(header_priority), "<%i>", priority);
+        char_array_0(header_priority);
+        IOVEC_SET_STRING(iovec[n++], header_priority);
+
+        /* Second: timestamp */
+        t = tv ? tv->tv_sec : ((time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC));
+        tm = localtime(&t);
+        if (!tm)
+                return;
+        if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
+                return;
+        IOVEC_SET_STRING(iovec[n++], header_time);
+
+        /* Third: identifier and PID */
+        if (ucred) {
+                if (!identifier) {
+                        get_process_comm(ucred->pid, &ident_buf);
+                        identifier = ident_buf;
+                }
+
+                snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
+                char_array_0(header_pid);
+
+                if (identifier)
+                        IOVEC_SET_STRING(iovec[n++], identifier);
+
+                IOVEC_SET_STRING(iovec[n++], header_pid);
+        } else if (identifier) {
+                IOVEC_SET_STRING(iovec[n++], identifier);
+                IOVEC_SET_STRING(iovec[n++], ": ");
+        }
+
+        /* Fourth: message */
+        IOVEC_SET_STRING(iovec[n++], message);
+
+        forward_syslog_iovec(s, iovec, n, ucred, tv);
+
+        free(ident_buf);
+}
+
+int syslog_fixup_facility(int priority) {
+
+        if ((priority & LOG_FACMASK) == 0)
+                return (priority & LOG_PRIMASK) | LOG_USER;
+
+        return priority;
+}
+
+size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) {
+        const char *p;
+        char *t;
+        size_t l, e;
+
+        assert(buf);
+        assert(identifier);
+        assert(pid);
+
+        p = *buf;
+
+        p += strspn(p, WHITESPACE);
+        l = strcspn(p, WHITESPACE);
+
+        if (l <= 0 ||
+            p[l-1] != ':')
+                return 0;
+
+        e = l;
+        l--;
+
+        if (p[l-1] == ']') {
+                size_t k = l-1;
+
+                for (;;) {
+
+                        if (p[k] == '[') {
+                                t = strndup(p+k+1, l-k-2);
+                                if (t)
+                                        *pid = t;
+
+                                l = k;
+                                break;
+                        }
+
+                        if (k == 0)
+                                break;
+
+                        k--;
+                }
+        }
+
+        t = strndup(p, l);
+        if (t)
+                *identifier = t;
+
+        e += strspn(p + e, WHITESPACE);
+        *buf = p + e;
+        return e;
+}
+
+void syslog_parse_priority(char **p, int *priority) {
+        int a = 0, b = 0, c = 0;
+        int k;
+
+        assert(p);
+        assert(*p);
+        assert(priority);
+
+        if ((*p)[0] != '<')
+                return;
+
+        if (!strchr(*p, '>'))
+                return;
+
+        if ((*p)[2] == '>') {
+                c = undecchar((*p)[1]);
+                k = 3;
+        } else if ((*p)[3] == '>') {
+                b = undecchar((*p)[1]);
+                c = undecchar((*p)[2]);
+                k = 4;
+        } else if ((*p)[4] == '>') {
+                a = undecchar((*p)[1]);
+                b = undecchar((*p)[2]);
+                c = undecchar((*p)[3]);
+                k = 5;
+        } else
+                return;
+
+        if (a < 0 || b < 0 || c < 0)
+                return;
+
+        *priority = a*100+b*10+c;
+        *p += k;
+}
+
+static void syslog_skip_date(char **buf) {
+        enum {
+                LETTER,
+                SPACE,
+                NUMBER,
+                SPACE_OR_NUMBER,
+                COLON
+        } sequence[] = {
+                LETTER, LETTER, LETTER,
+                SPACE,
+                SPACE_OR_NUMBER, NUMBER,
+                SPACE,
+                SPACE_OR_NUMBER, NUMBER,
+                COLON,
+                SPACE_OR_NUMBER, NUMBER,
+                COLON,
+                SPACE_OR_NUMBER, NUMBER,
+                SPACE
+        };
+
+        char *p;
+        unsigned i;
+
+        assert(buf);
+        assert(*buf);
+
+        p = *buf;
+
+        for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
+
+                if (!*p)
+                        return;
+
+                switch (sequence[i]) {
+
+                case SPACE:
+                        if (*p != ' ')
+                                return;
+                        break;
+
+                case SPACE_OR_NUMBER:
+                        if (*p == ' ')
+                                break;
+
+                        /* fall through */
+
+                case NUMBER:
+                        if (*p < '0' || *p > '9')
+                                return;
+
+                        break;
+
+                case LETTER:
+                        if (!(*p >= 'A' && *p <= 'Z') &&
+                            !(*p >= 'a' && *p <= 'z'))
+                                return;
+
+                        break;
+
+                case COLON:
+                        if (*p != ':')
+                                return;
+                        break;
+
+                }
+        }
+
+        *buf = p;
+}
+
+void server_process_syslog_message(
+        Server *s,
+        const char *buf,
+        struct ucred *ucred,
+        struct timeval *tv,
+        const char *label,
+        size_t label_len) {
+
+        char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
+        struct iovec iovec[N_IOVEC_META_FIELDS + 6];
+        unsigned n = 0;
+        int priority = LOG_USER | LOG_INFO;
+        char *identifier = NULL, *pid = NULL;
+        const char *orig;
+
+        assert(s);
+        assert(buf);
+
+        orig = buf;
+        syslog_parse_priority((char**) &buf, &priority);
+
+        if (s->forward_to_syslog)
+                forward_syslog_raw(s, priority, orig, ucred, tv);
+
+        syslog_skip_date((char**) &buf);
+        syslog_parse_identifier(&buf, &identifier, &pid);
+
+        if (s->forward_to_kmsg)
+                server_forward_kmsg(s, priority, identifier, buf, ucred);
+
+        if (s->forward_to_console)
+                server_forward_console(s, priority, identifier, buf, ucred);
+
+        IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
+
+        if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
+                IOVEC_SET_STRING(iovec[n++], syslog_priority);
+
+        if (priority & LOG_FACMASK)
+                if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
+                        IOVEC_SET_STRING(iovec[n++], syslog_facility);
+
+        if (identifier) {
+                syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
+                if (syslog_identifier)
+                        IOVEC_SET_STRING(iovec[n++], syslog_identifier);
+        }
+
+        if (pid) {
+                syslog_pid = strappend("SYSLOG_PID=", pid);
+                if (syslog_pid)
+                        IOVEC_SET_STRING(iovec[n++], syslog_pid);
+        }
+
+        message = strappend("MESSAGE=", buf);
+        if (message)
+                IOVEC_SET_STRING(iovec[n++], message);
+
+        server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, label, label_len, NULL, priority);
+
+        free(message);
+        free(identifier);
+        free(pid);
+        free(syslog_priority);
+        free(syslog_facility);
+        free(syslog_identifier);
+        free(syslog_pid);
+}
+
+int server_open_syslog_socket(Server *s) {
+        union sockaddr_union sa;
+        int one, r;
+        struct epoll_event ev;
+
+        assert(s);
+
+        if (s->syslog_fd < 0) {
+
+                s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+                if (s->syslog_fd < 0) {
+                        log_error("socket() failed: %m");
+                        return -errno;
+                }
+
+                zero(sa);
+                sa.un.sun_family = AF_UNIX;
+                strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path));
+
+                unlink(sa.un.sun_path);
+
+                r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
+                if (r < 0) {
+                        log_error("bind() failed: %m");
+                        return -errno;
+                }
+
+                chmod(sa.un.sun_path, 0666);
+        } else
+                fd_nonblock(s->syslog_fd, 1);
+
+        one = 1;
+        r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
+        if (r < 0) {
+                log_error("SO_PASSCRED failed: %m");
+                return -errno;
+        }
+
+#ifdef HAVE_SELINUX
+        one = 1;
+        r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
+        if (r < 0)
+                log_warning("SO_PASSSEC failed: %m");
+#endif
+
+        one = 1;
+        r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
+        if (r < 0) {
+                log_error("SO_TIMESTAMP failed: %m");
+                return -errno;
+        }
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.fd = s->syslog_fd;
+        if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->syslog_fd, &ev) < 0) {
+                log_error("Failed to add syslog server fd to epoll object: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+void server_maybe_warn_forward_syslog_missed(Server *s) {
+        usec_t n;
+        assert(s);
+
+        if (s->n_forward_syslog_missed <= 0)
+                return;
+
+        n = now(CLOCK_MONOTONIC);
+        if (s->last_warn_forward_syslog_missed + WARN_FORWARD_SYSLOG_MISSED_USEC > n)
+                return;
+
+        server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED, "Forwarding to syslog missed %u messages.", s->n_forward_syslog_missed);
+
+        s->n_forward_syslog_missed = 0;
+        s->last_warn_forward_syslog_missed = n;
+}
diff --git a/src/journal/journald-syslog.h b/src/journal/journald-syslog.h
new file mode 100644 (file)
index 0000000..7ff215b
--- /dev/null
@@ -0,0 +1,36 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journald-server.h"
+
+int syslog_fixup_facility(int priority);
+
+void syslog_parse_priority(char **p, int *priority);
+size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid);
+
+void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv);
+
+void server_process_syslog_message(Server *s, const char *buf, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len);
+int server_open_syslog_socket(Server *s);
+
+void server_maybe_warn_forward_syslog_missed(Server *s);
diff --git a/src/journal/journald.c b/src/journal/journald.c
new file mode 100644 (file)
index 0000000..d6b9be5
--- /dev/null
@@ -0,0 +1,140 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <systemd/sd-journal.h>
+#include <systemd/sd-messages.h>
+#include <systemd/sd-daemon.h>
+
+#include "journal-authenticate.h"
+#include "journald-server.h"
+#include "journald-kmsg.h"
+#include "journald-syslog.h"
+
+int main(int argc, char *argv[]) {
+        Server server;
+        int r;
+
+        /* if (getppid() != 1) { */
+        /*         log_error("This program should be invoked by init only."); */
+        /*         return EXIT_FAILURE; */
+        /* } */
+
+        if (argc > 1) {
+                log_error("This program does not take arguments.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_set_facility(LOG_SYSLOG);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        r = server_init(&server);
+        if (r < 0)
+                goto finish;
+
+        server_vacuum(&server);
+        server_flush_to_var(&server);
+        server_flush_dev_kmsg(&server);
+
+        log_debug("systemd-journald running as pid %lu", (unsigned long) getpid());
+        server_driver_message(&server, SD_MESSAGE_JOURNAL_START, "Journal started");
+
+        sd_notify(false,
+                  "READY=1\n"
+                  "STATUS=Processing requests...");
+
+        for (;;) {
+                struct epoll_event event;
+                int t = -1;
+                usec_t n;
+
+                n = now(CLOCK_REALTIME);
+
+                if (server.max_retention_usec > 0 && server.oldest_file_usec > 0) {
+
+                        /* The retention time is reached, so let's vacuum! */
+                        if (server.oldest_file_usec + server.max_retention_usec < n) {
+                                log_info("Retention time reached.");
+                                server_rotate(&server);
+                                server_vacuum(&server);
+                                continue;
+                        }
+
+                        /* Calculate when to rotate the next time */
+                        t = (int) ((server.oldest_file_usec + server.max_retention_usec - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC);
+                        log_info("Sleeping for %i ms", t);
+                }
+
+#ifdef HAVE_GCRYPT
+                if (server.system_journal) {
+                        usec_t u;
+
+                        if (journal_file_next_evolve_usec(server.system_journal, &u)) {
+                                if (n >= u)
+                                        t = 0;
+                                else
+                                        t = MIN(t, (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC));
+                        }
+                }
+#endif
+
+                r = epoll_wait(server.epoll_fd, &event, 1, t);
+                if (r < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        log_error("epoll_wait() failed: %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (r > 0) {
+                        r = process_event(&server, &event);
+                        if (r < 0)
+                                goto finish;
+                        else if (r == 0)
+                                break;
+                }
+
+                server_maybe_append_tags(&server);
+                server_maybe_warn_forward_syslog_missed(&server);
+        }
+
+        log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());
+        server_driver_message(&server, SD_MESSAGE_JOURNAL_STOP, "Journal stopped");
+
+finish:
+        sd_notify(false,
+                  "STATUS=Shutting down...");
+
+        server_done(&server);
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/journal/journald.conf b/src/journal/journald.conf
new file mode 100644 (file)
index 0000000..948318b
--- /dev/null
@@ -0,0 +1,32 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+# See journald.conf(5) for details
+
+[Journal]
+#Storage=auto
+#Compress=yes
+#Seal=yes
+#SplitMode=login
+#RateLimitInterval=10s
+#RateLimitBurst=200
+#SystemMaxUse=
+#SystemKeepFree=
+#SystemMaxFileSize=
+#RuntimeMaxUse=
+#RuntimeKeepFree=
+#RuntimeMaxFileSize=
+#MaxRetentionSec=
+#MaxFileSec=1month
+#ForwardToSyslog=yes
+#ForwardToKMsg=no
+#ForwardToConsole=no
+#TTYPath=/dev/console
+#MaxLevelStore=debug
+#MaxLevelSyslog=debug
+#MaxLevelKMsg=notice
+#MaxLevelConsole=info
diff --git a/src/journal/libsystemd-journal.pc.in b/src/journal/libsystemd-journal.pc.in
new file mode 100644 (file)
index 0000000..9883595
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: systemd
+Description: systemd Journal Utility Library
+URL: @PACKAGE_URL@
+Version: @PACKAGE_VERSION@
+Requires: libsystemd-id128 = @PACKAGE_VERSION@
+Libs: -L${libdir} -lsystemd-journal
+Cflags: -I${includedir}
diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym
new file mode 100644 (file)
index 0000000..7b602f5
--- /dev/null
@@ -0,0 +1,91 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+/* Original symbols from systemd v38 */
+
+LIBSYSTEMD_JOURNAL_38 {
+global:
+        sd_journal_print;
+        sd_journal_printv;
+        sd_journal_send;
+        sd_journal_sendv;
+        sd_journal_stream_fd;
+        sd_journal_open;
+        sd_journal_close;
+        sd_journal_previous;
+        sd_journal_next;
+        sd_journal_previous_skip;
+        sd_journal_next_skip;
+        sd_journal_get_realtime_usec;
+        sd_journal_get_monotonic_usec;
+        sd_journal_get_data;
+        sd_journal_enumerate_data;
+        sd_journal_restart_data;
+        sd_journal_add_match;
+        sd_journal_flush_matches;
+        sd_journal_seek_head;
+        sd_journal_seek_tail;
+        sd_journal_seek_monotonic_usec;
+        sd_journal_seek_realtime_usec;
+        sd_journal_seek_cursor;
+        sd_journal_get_cursor;
+        sd_journal_get_fd;
+        sd_journal_process;
+local:
+        *;
+};
+
+LIBSYSTEMD_JOURNAL_183 {
+global:
+        sd_journal_print_with_location;
+        sd_journal_printv_with_location;
+        sd_journal_send_with_location;
+        sd_journal_sendv_with_location;
+} LIBSYSTEMD_JOURNAL_38;
+
+LIBSYSTEMD_JOURNAL_184 {
+global:
+        sd_journal_get_cutoff_realtime_usec;
+        sd_journal_get_cutoff_monotonic_usec;
+} LIBSYSTEMD_JOURNAL_183;
+
+LIBSYSTEMD_JOURNAL_187 {
+global:
+        sd_journal_wait;
+        sd_journal_open_directory;
+        sd_journal_add_disjunction;
+} LIBSYSTEMD_JOURNAL_184;
+
+LIBSYSTEMD_JOURNAL_188 {
+global:
+        sd_journal_perror;
+        sd_journal_perror_with_location;
+} LIBSYSTEMD_JOURNAL_187;
+
+LIBSYSTEMD_JOURNAL_190 {
+global:
+        sd_journal_get_usage;
+} LIBSYSTEMD_JOURNAL_188;
+
+LIBSYSTEMD_JOURNAL_195 {
+global:
+        sd_journal_test_cursor;
+        sd_journal_query_unique;
+        sd_journal_enumerate_unique;
+        sd_journal_restart_unique;
+} LIBSYSTEMD_JOURNAL_190;
+
+LIBSYSTEMD_JOURNAL_196 {
+global:
+        sd_journal_fd_reliable;
+        sd_journal_get_catalog;
+        sd_journal_get_catalog_for_message_id;
+        sd_journal_set_data_threshold;
+        sd_journal_get_data_threshold;
+} LIBSYSTEMD_JOURNAL_195;
diff --git a/src/journal/lookup3.c b/src/journal/lookup3.c
new file mode 100644 (file)
index 0000000..52ffdf7
--- /dev/null
@@ -0,0 +1,1009 @@
+/* Slightly modified by Lennart Poettering, to avoid name clashes, and
+ * unexport a few functions. */
+
+#include "lookup3.h"
+
+/*
+-------------------------------------------------------------------------------
+lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+
+These are functions for producing 32-bit hashes for hash table lookup.
+hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+are externally useful functions.  Routines to test the hash are included
+if SELF_TEST is defined.  You can use this free for any purpose.  It's in
+the public domain.  It has no warranty.
+
+You probably want to use hashlittle().  hashlittle() and hashbig()
+hash byte arrays.  hashlittle() is faster than hashbig() on
+little-endian machines.  Intel and AMD are little-endian machines.
+On second thought, you probably want hashlittle2(), which is identical to
+hashlittle() except it returns two 32-bit hashes for the price of one.
+You could implement hashbig2() if you wanted but I haven't bothered here.
+
+If you want to find a hash of, say, exactly 7 integers, do
+  a = i1;  b = i2;  c = i3;
+  mix(a,b,c);
+  a += i4; b += i5; c += i6;
+  mix(a,b,c);
+  a += i7;
+  final(a,b,c);
+then use c as the hash value.  If you have a variable length array of
+4-byte integers to hash, use hashword().  If you have a byte array (like
+a character string), use hashlittle().  If you have several byte arrays, or
+a mix of things, see the comments above hashlittle().
+
+Why is this so big?  I read 12 bytes at a time into 3 4-byte integers,
+then mix those integers.  This is fast (you can do a lot more thorough
+mixing with 12*3 instructions on 3 integers than you can with 3 instructions
+on 1 byte), but shoehorning those bytes into integers efficiently is messy.
+-------------------------------------------------------------------------------
+*/
+/* #define SELF_TEST 1 */
+
+#include <stdio.h>      /* defines printf for tests */
+#include <time.h>       /* defines time_t for timings in the test */
+#include <stdint.h>     /* defines uint32_t etc */
+#include <sys/param.h>  /* attempt to define endianness */
+#ifdef linux
+# include <endian.h>    /* attempt to define endianness */
+#endif
+
+/*
+ * My best guess at if you are big-endian or little-endian.  This may
+ * need adjustment.
+ */
+#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+     __BYTE_ORDER == __LITTLE_ENDIAN) || \
+    (defined(i386) || defined(__i386__) || defined(__i486__) || \
+     defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
+# define HASH_LITTLE_ENDIAN 1
+# define HASH_BIG_ENDIAN 0
+#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
+       __BYTE_ORDER == __BIG_ENDIAN) || \
+      (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 1
+#else
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 0
+#endif
+
+#define hashsize(n) ((uint32_t)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+/*
+-------------------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+
+This is reversible, so any information in (a,b,c) before mix() is
+still in (a,b,c) after mix().
+
+If four pairs of (a,b,c) inputs are run through mix(), or through
+mix() in reverse, there are at least 32 bits of the output that
+are sometimes the same for one pair and different for another pair.
+This was tested for:
+* pairs that differed by one bit, by two bits, in any combination
+  of top bits of (a,b,c), or in any combination of bottom bits of
+  (a,b,c).
+* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
+  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+  is commonly produced by subtraction) look like a single 1-bit
+  difference.
+* the base values were pseudorandom, all zero but one bit set, or
+  all zero plus a counter that starts at zero.
+
+Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
+satisfy this are
+    4  6  8 16 19  4
+    9 15  3 18 27 15
+   14  9  3  7 17  3
+Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
+for "differ" defined as + with a one-bit base and a two-bit delta.  I
+used http://burtleburtle.net/bob/hash/avalanche.html to choose
+the operations, constants, and arrangements of the variables.
+
+This does not achieve avalanche.  There are input bits of (a,b,c)
+that fail to affect some output bits of (a,b,c), especially of a.  The
+most thoroughly mixed value is c, but it doesn't really even achieve
+avalanche in c.
+
+This allows some parallelism.  Read-after-writes are good at doubling
+the number of bits affected, so the goal of mixing pulls in the opposite
+direction as the goal of parallelism.  I did what I could.  Rotates
+seem to cost as much as shifts on every machine I could lay my hands
+on, and rotates are much kinder to the top and bottom bits, so I used
+rotates.
+-------------------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+  a -= c;  a ^= rot(c, 4);  c += b; \
+  b -= a;  b ^= rot(a, 6);  a += c; \
+  c -= b;  c ^= rot(b, 8);  b += a; \
+  a -= c;  a ^= rot(c,16);  c += b; \
+  b -= a;  b ^= rot(a,19);  a += c; \
+  c -= b;  c ^= rot(b, 4);  b += a; \
+}
+
+/*
+-------------------------------------------------------------------------------
+final -- final mixing of 3 32-bit values (a,b,c) into c
+
+Pairs of (a,b,c) values differing in only a few bits will usually
+produce values of c that look totally different.  This was tested for
+* pairs that differed by one bit, by two bits, in any combination
+  of top bits of (a,b,c), or in any combination of bottom bits of
+  (a,b,c).
+* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
+  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+  is commonly produced by subtraction) look like a single 1-bit
+  difference.
+* the base values were pseudorandom, all zero but one bit set, or
+  all zero plus a counter that starts at zero.
+
+These constants passed:
+ 14 11 25 16 4 14 24
+ 12 14 25 16 4 14 24
+and these came close:
+  4  8 15 26 3 22 24
+ 10  8 15 26 3 22 24
+ 11  8 15 26 3 22 24
+-------------------------------------------------------------------------------
+*/
+#define final(a,b,c) \
+{ \
+  c ^= b; c -= rot(b,14); \
+  a ^= c; a -= rot(c,11); \
+  b ^= a; b -= rot(a,25); \
+  c ^= b; c -= rot(b,16); \
+  a ^= c; a -= rot(c,4);  \
+  b ^= a; b -= rot(a,14); \
+  c ^= b; c -= rot(b,24); \
+}
+
+/*
+--------------------------------------------------------------------
+ This works on all machines.  To be useful, it requires
+ -- that the key be an array of uint32_t's, and
+ -- that the length be the number of uint32_t's in the key
+
+ The function hashword() is identical to hashlittle() on little-endian
+ machines, and identical to hashbig() on big-endian machines,
+ except that the length has to be measured in uint32_ts rather than in
+ bytes.  hashlittle() is more complicated than hashword() only because
+ hashlittle() has to dance around fitting the key bytes into registers.
+--------------------------------------------------------------------
+*/
+uint32_t jenkins_hashword(
+const uint32_t *k,                   /* the key, an array of uint32_t values */
+size_t          length,               /* the length of the key, in uint32_ts */
+uint32_t        initval)         /* the previous hash, or an arbitrary value */
+{
+  uint32_t a,b,c;
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval;
+
+  /*------------------------------------------------- handle most of the key */
+  while (length > 3)
+  {
+    a += k[0];
+    b += k[1];
+    c += k[2];
+    mix(a,b,c);
+    length -= 3;
+    k += 3;
+  }
+
+  /*------------------------------------------- handle the last 3 uint32_t's */
+  switch(length)                     /* all the case statements fall through */
+  {
+  case 3 : c+=k[2];
+  case 2 : b+=k[1];
+  case 1 : a+=k[0];
+    final(a,b,c);
+  case 0:     /* case 0: nothing left to add */
+    break;
+  }
+  /*------------------------------------------------------ report the result */
+  return c;
+}
+
+
+/*
+--------------------------------------------------------------------
+hashword2() -- same as hashword(), but take two seeds and return two
+32-bit values.  pc and pb must both be nonnull, and *pc and *pb must
+both be initialized with seeds.  If you pass in (*pb)==0, the output
+(*pc) will be the same as the return value from hashword().
+--------------------------------------------------------------------
+*/
+void jenkins_hashword2 (
+const uint32_t *k,                   /* the key, an array of uint32_t values */
+size_t          length,               /* the length of the key, in uint32_ts */
+uint32_t       *pc,                      /* IN: seed OUT: primary hash value */
+uint32_t       *pb)               /* IN: more seed OUT: secondary hash value */
+{
+  uint32_t a,b,c;
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc;
+  c += *pb;
+
+  /*------------------------------------------------- handle most of the key */
+  while (length > 3)
+  {
+    a += k[0];
+    b += k[1];
+    c += k[2];
+    mix(a,b,c);
+    length -= 3;
+    k += 3;
+  }
+
+  /*------------------------------------------- handle the last 3 uint32_t's */
+  switch(length)                     /* all the case statements fall through */
+  {
+  case 3 : c+=k[2];
+  case 2 : b+=k[1];
+  case 1 : a+=k[0];
+    final(a,b,c);
+  case 0:     /* case 0: nothing left to add */
+    break;
+  }
+  /*------------------------------------------------------ report the result */
+  *pc=c; *pb=b;
+}
+
+
+/*
+-------------------------------------------------------------------------------
+hashlittle() -- hash a variable-length key into a 32-bit value
+  k       : the key (the unaligned variable-length array of bytes)
+  length  : the length of the key, counting by bytes
+  initval : can be any 4-byte value
+Returns a 32-bit value.  Every bit of the key affects every bit of
+the return value.  Two keys differing by one or two bits will have
+totally different hash values.
+
+The best hash table sizes are powers of 2.  There is no need to do
+mod a prime (mod is sooo slow!).  If you need less than 32 bits,
+use a bitmask.  For example, if you need only 10 bits, do
+  h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (uint8_t **)k, do it like this:
+  for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
+
+By Bob Jenkins, 2006.  bob_jenkins@burtleburtle.net.  You may use this
+code any way you wish, private, educational, or commercial.  It's free.
+
+Use for hash table lookup, or anything where one collision in 2^^32 is
+acceptable.  Do NOT use for cryptographic purposes.
+-------------------------------------------------------------------------------
+*/
+
+uint32_t jenkins_hashlittle( const void *key, size_t length, uint32_t initval)
+{
+  uint32_t a,b,c;                                          /* internal state */
+  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
+
+  u.ptr = key;
+  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
+    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
+
+    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      b += k[1];
+      c += k[2];
+      mix(a,b,c);
+      length -= 12;
+      k += 3;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    /*
+     * "k[2]&0xffffff" actually reads beyond the end of the string, but
+     * then masks off the part it's not allowed to read.  Because the
+     * string is aligned, the masked-off tail is in the same word as the
+     * rest of the string.  Every machine with memory protection I've seen
+     * does it on word boundaries, so is OK with this.  But VALGRIND will
+     * still catch it and complain.  The masking trick does make the hash
+     * noticeably faster for short strings (like English words).
+     */
+#ifndef VALGRIND
+
+    switch(length)
+    {
+    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
+    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
+    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
+    case 8 : b+=k[1]; a+=k[0]; break;
+    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
+    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
+    case 5 : b+=k[1]&0xff; a+=k[0]; break;
+    case 4 : a+=k[0]; break;
+    case 3 : a+=k[0]&0xffffff; break;
+    case 2 : a+=k[0]&0xffff; break;
+    case 1 : a+=k[0]&0xff; break;
+    case 0 : return c;              /* zero length strings require no mixing */
+    }
+
+#else /* make valgrind happy */
+    {
+      const uint8_t *k8 = (const uint8_t *) k;
+
+      switch(length)
+      {
+      case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+      case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */
+      case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */
+      case 9 : c+=k8[8];                   /* fall through */
+      case 8 : b+=k[1]; a+=k[0]; break;
+      case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */
+      case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */
+      case 5 : b+=k8[4];                   /* fall through */
+      case 4 : a+=k[0]; break;
+      case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
+      case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
+      case 1 : a+=k8[0]; break;
+      case 0 : return c;
+      }
+    }
+
+#endif /* !valgrind */
+
+  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
+    const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */
+    const uint8_t  *k8;
+
+    /*--------------- all but last block: aligned reads and different mixing */
+    while (length > 12)
+    {
+      a += k[0] + (((uint32_t)k[1])<<16);
+      b += k[2] + (((uint32_t)k[3])<<16);
+      c += k[4] + (((uint32_t)k[5])<<16);
+      mix(a,b,c);
+      length -= 12;
+      k += 6;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    k8 = (const uint8_t *)k;
+    switch(length)
+    {
+    case 12: c+=k[4]+(((uint32_t)k[5])<<16);
+             b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */
+    case 10: c+=k[4];
+             b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 9 : c+=k8[8];                      /* fall through */
+    case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */
+    case 6 : b+=k[2];
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 5 : b+=k8[4];                      /* fall through */
+    case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */
+    case 2 : a+=k[0];
+             break;
+    case 1 : a+=k8[0];
+             break;
+    case 0 : return c;                     /* zero length requires no mixing */
+    }
+
+  } else {                        /* need to read the key one byte at a time */
+    const uint8_t *k = (const uint8_t *)key;
+
+    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      a += ((uint32_t)k[1])<<8;
+      a += ((uint32_t)k[2])<<16;
+      a += ((uint32_t)k[3])<<24;
+      b += k[4];
+      b += ((uint32_t)k[5])<<8;
+      b += ((uint32_t)k[6])<<16;
+      b += ((uint32_t)k[7])<<24;
+      c += k[8];
+      c += ((uint32_t)k[9])<<8;
+      c += ((uint32_t)k[10])<<16;
+      c += ((uint32_t)k[11])<<24;
+      mix(a,b,c);
+      length -= 12;
+      k += 12;
+    }
+
+    /*-------------------------------- last block: affect all 32 bits of (c) */
+    switch(length)                   /* all the case statements fall through */
+    {
+    case 12: c+=((uint32_t)k[11])<<24;
+    case 11: c+=((uint32_t)k[10])<<16;
+    case 10: c+=((uint32_t)k[9])<<8;
+    case 9 : c+=k[8];
+    case 8 : b+=((uint32_t)k[7])<<24;
+    case 7 : b+=((uint32_t)k[6])<<16;
+    case 6 : b+=((uint32_t)k[5])<<8;
+    case 5 : b+=k[4];
+    case 4 : a+=((uint32_t)k[3])<<24;
+    case 3 : a+=((uint32_t)k[2])<<16;
+    case 2 : a+=((uint32_t)k[1])<<8;
+    case 1 : a+=k[0];
+             break;
+    case 0 : return c;
+    }
+  }
+
+  final(a,b,c);
+  return c;
+}
+
+
+/*
+ * hashlittle2: return 2 32-bit hash values
+ *
+ * This is identical to hashlittle(), except it returns two 32-bit hash
+ * values instead of just one.  This is good enough for hash table
+ * lookup with 2^^64 buckets, or if you want a second hash if you're not
+ * happy with the first, or if you want a probably-unique 64-bit ID for
+ * the key.  *pc is better mixed than *pb, so use *pc first.  If you want
+ * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
+ */
+void jenkins_hashlittle2(
+  const void *key,       /* the key to hash */
+  size_t      length,    /* length of the key */
+  uint32_t   *pc,        /* IN: primary initval, OUT: primary hash */
+  uint32_t   *pb)        /* IN: secondary initval, OUT: secondary hash */
+{
+  uint32_t a,b,c;                                          /* internal state */
+  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc;
+  c += *pb;
+
+  u.ptr = key;
+  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
+    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
+
+    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      b += k[1];
+      c += k[2];
+      mix(a,b,c);
+      length -= 12;
+      k += 3;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    /*
+     * "k[2]&0xffffff" actually reads beyond the end of the string, but
+     * then masks off the part it's not allowed to read.  Because the
+     * string is aligned, the masked-off tail is in the same word as the
+     * rest of the string.  Every machine with memory protection I've seen
+     * does it on word boundaries, so is OK with this.  But VALGRIND will
+     * still catch it and complain.  The masking trick does make the hash
+     * noticeably faster for short strings (like English words).
+     */
+#ifndef VALGRIND
+
+    switch(length)
+    {
+    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
+    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
+    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
+    case 8 : b+=k[1]; a+=k[0]; break;
+    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
+    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
+    case 5 : b+=k[1]&0xff; a+=k[0]; break;
+    case 4 : a+=k[0]; break;
+    case 3 : a+=k[0]&0xffffff; break;
+    case 2 : a+=k[0]&0xffff; break;
+    case 1 : a+=k[0]&0xff; break;
+    case 0 : *pc=c; *pb=b; return;  /* zero length strings require no mixing */
+    }
+
+#else /* make valgrind happy */
+
+    {
+      const uint8_t *k8 = (const uint8_t *)k;
+      switch(length)
+      {
+      case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+      case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */
+      case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */
+      case 9 : c+=k8[8];                   /* fall through */
+      case 8 : b+=k[1]; a+=k[0]; break;
+      case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */
+      case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */
+      case 5 : b+=k8[4];                   /* fall through */
+      case 4 : a+=k[0]; break;
+      case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
+      case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
+      case 1 : a+=k8[0]; break;
+      case 0 : *pc=c; *pb=b; return;  /* zero length strings require no mixing */
+      }
+    }
+
+#endif /* !valgrind */
+
+  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
+    const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */
+    const uint8_t  *k8;
+
+    /*--------------- all but last block: aligned reads and different mixing */
+    while (length > 12)
+    {
+      a += k[0] + (((uint32_t)k[1])<<16);
+      b += k[2] + (((uint32_t)k[3])<<16);
+      c += k[4] + (((uint32_t)k[5])<<16);
+      mix(a,b,c);
+      length -= 12;
+      k += 6;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    k8 = (const uint8_t *)k;
+    switch(length)
+    {
+    case 12: c+=k[4]+(((uint32_t)k[5])<<16);
+             b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */
+    case 10: c+=k[4];
+             b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 9 : c+=k8[8];                      /* fall through */
+    case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */
+    case 6 : b+=k[2];
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 5 : b+=k8[4];                      /* fall through */
+    case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */
+    case 2 : a+=k[0];
+             break;
+    case 1 : a+=k8[0];
+             break;
+    case 0 : *pc=c; *pb=b; return;  /* zero length strings require no mixing */
+    }
+
+  } else {                        /* need to read the key one byte at a time */
+    const uint8_t *k = (const uint8_t *)key;
+
+    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      a += ((uint32_t)k[1])<<8;
+      a += ((uint32_t)k[2])<<16;
+      a += ((uint32_t)k[3])<<24;
+      b += k[4];
+      b += ((uint32_t)k[5])<<8;
+      b += ((uint32_t)k[6])<<16;
+      b += ((uint32_t)k[7])<<24;
+      c += k[8];
+      c += ((uint32_t)k[9])<<8;
+      c += ((uint32_t)k[10])<<16;
+      c += ((uint32_t)k[11])<<24;
+      mix(a,b,c);
+      length -= 12;
+      k += 12;
+    }
+
+    /*-------------------------------- last block: affect all 32 bits of (c) */
+    switch(length)                   /* all the case statements fall through */
+    {
+    case 12: c+=((uint32_t)k[11])<<24;
+    case 11: c+=((uint32_t)k[10])<<16;
+    case 10: c+=((uint32_t)k[9])<<8;
+    case 9 : c+=k[8];
+    case 8 : b+=((uint32_t)k[7])<<24;
+    case 7 : b+=((uint32_t)k[6])<<16;
+    case 6 : b+=((uint32_t)k[5])<<8;
+    case 5 : b+=k[4];
+    case 4 : a+=((uint32_t)k[3])<<24;
+    case 3 : a+=((uint32_t)k[2])<<16;
+    case 2 : a+=((uint32_t)k[1])<<8;
+    case 1 : a+=k[0];
+             break;
+    case 0 : *pc=c; *pb=b; return;  /* zero length strings require no mixing */
+    }
+  }
+
+  final(a,b,c);
+  *pc=c; *pb=b;
+}
+
+
+
+/*
+ * hashbig():
+ * This is the same as hashword() on big-endian machines.  It is different
+ * from hashlittle() on all machines.  hashbig() takes advantage of
+ * big-endian byte ordering.
+ */
+uint32_t jenkins_hashbig( const void *key, size_t length, uint32_t initval)
+{
+  uint32_t a,b,c;
+  union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
+
+  u.ptr = key;
+  if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
+    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
+
+    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      b += k[1];
+      c += k[2];
+      mix(a,b,c);
+      length -= 12;
+      k += 3;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    /*
+     * "k[2]<<8" actually reads beyond the end of the string, but
+     * then shifts out the part it's not allowed to read.  Because the
+     * string is aligned, the illegal read is in the same word as the
+     * rest of the string.  Every machine with memory protection I've seen
+     * does it on word boundaries, so is OK with this.  But VALGRIND will
+     * still catch it and complain.  The masking trick does make the hash
+     * noticeably faster for short strings (like English words).
+     */
+#ifndef VALGRIND
+
+    switch(length)
+    {
+    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+    case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break;
+    case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break;
+    case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break;
+    case 8 : b+=k[1]; a+=k[0]; break;
+    case 7 : b+=k[1]&0xffffff00; a+=k[0]; break;
+    case 6 : b+=k[1]&0xffff0000; a+=k[0]; break;
+    case 5 : b+=k[1]&0xff000000; a+=k[0]; break;
+    case 4 : a+=k[0]; break;
+    case 3 : a+=k[0]&0xffffff00; break;
+    case 2 : a+=k[0]&0xffff0000; break;
+    case 1 : a+=k[0]&0xff000000; break;
+    case 0 : return c;              /* zero length strings require no mixing */
+    }
+
+#else  /* make valgrind happy */
+
+    {
+      const uint8_t *k8 = (const uint8_t *)k;
+      switch(length)                   /* all the case statements fall through */
+      {
+      case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+      case 11: c+=((uint32_t)k8[10])<<8;  /* fall through */
+      case 10: c+=((uint32_t)k8[9])<<16;  /* fall through */
+      case 9 : c+=((uint32_t)k8[8])<<24;  /* fall through */
+      case 8 : b+=k[1]; a+=k[0]; break;
+      case 7 : b+=((uint32_t)k8[6])<<8;   /* fall through */
+      case 6 : b+=((uint32_t)k8[5])<<16;  /* fall through */
+      case 5 : b+=((uint32_t)k8[4])<<24;  /* fall through */
+      case 4 : a+=k[0]; break;
+      case 3 : a+=((uint32_t)k8[2])<<8;   /* fall through */
+      case 2 : a+=((uint32_t)k8[1])<<16;  /* fall through */
+      case 1 : a+=((uint32_t)k8[0])<<24; break;
+      case 0 : return c;
+      }
+    }
+
+#endif /* !VALGRIND */
+
+  } else {                        /* need to read the key one byte at a time */
+    const uint8_t *k = (const uint8_t *)key;
+
+    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += ((uint32_t)k[0])<<24;
+      a += ((uint32_t)k[1])<<16;
+      a += ((uint32_t)k[2])<<8;
+      a += ((uint32_t)k[3]);
+      b += ((uint32_t)k[4])<<24;
+      b += ((uint32_t)k[5])<<16;
+      b += ((uint32_t)k[6])<<8;
+      b += ((uint32_t)k[7]);
+      c += ((uint32_t)k[8])<<24;
+      c += ((uint32_t)k[9])<<16;
+      c += ((uint32_t)k[10])<<8;
+      c += ((uint32_t)k[11]);
+      mix(a,b,c);
+      length -= 12;
+      k += 12;
+    }
+
+    /*-------------------------------- last block: affect all 32 bits of (c) */
+    switch(length)                   /* all the case statements fall through */
+    {
+    case 12: c+=k[11];
+    case 11: c+=((uint32_t)k[10])<<8;
+    case 10: c+=((uint32_t)k[9])<<16;
+    case 9 : c+=((uint32_t)k[8])<<24;
+    case 8 : b+=k[7];
+    case 7 : b+=((uint32_t)k[6])<<8;
+    case 6 : b+=((uint32_t)k[5])<<16;
+    case 5 : b+=((uint32_t)k[4])<<24;
+    case 4 : a+=k[3];
+    case 3 : a+=((uint32_t)k[2])<<8;
+    case 2 : a+=((uint32_t)k[1])<<16;
+    case 1 : a+=((uint32_t)k[0])<<24;
+             break;
+    case 0 : return c;
+    }
+  }
+
+  final(a,b,c);
+  return c;
+}
+
+
+#ifdef SELF_TEST
+
+/* used for timings */
+void driver1()
+{
+  uint8_t buf[256];
+  uint32_t i;
+  uint32_t h=0;
+  time_t a,z;
+
+  time(&a);
+  for (i=0; i<256; ++i) buf[i] = 'x';
+  for (i=0; i<1; ++i)
+  {
+    h = hashlittle(&buf[0],1,h);
+  }
+  time(&z);
+  if (z-a > 0) printf("time %d %.8x\n", z-a, h);
+}
+
+/* check that every input bit changes every output bit half the time */
+#define HASHSTATE 1
+#define HASHLEN   1
+#define MAXPAIR 60
+#define MAXLEN  70
+void driver2()
+{
+  uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1];
+  uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z;
+  uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE];
+  uint32_t x[HASHSTATE],y[HASHSTATE];
+  uint32_t hlen;
+
+  printf("No more than %d trials should ever be needed \n",MAXPAIR/2);
+  for (hlen=0; hlen < MAXLEN; ++hlen)
+  {
+    z=0;
+    for (i=0; i<hlen; ++i)  /*----------------------- for each input byte, */
+    {
+      for (j=0; j<8; ++j)   /*------------------------ for each input bit, */
+      {
+        for (m=1; m<8; ++m) /*------------ for serveral possible initvals, */
+        {
+          for (l=0; l<HASHSTATE; ++l)
+            e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32_t)0);
+
+          /*---- check that every output bit is affected by that input bit */
+          for (k=0; k<MAXPAIR; k+=2)
+          {
+            uint32_t finished=1;
+            /* keys have one bit different */
+            for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8_t)0;}
+            /* have a and b be two keys differing in only one bit */
+            a[i] ^= (k<<j);
+            a[i] ^= (k>>(8-j));
+             c[0] = hashlittle(a, hlen, m);
+            b[i] ^= ((k+1)<<j);
+            b[i] ^= ((k+1)>>(8-j));
+             d[0] = hashlittle(b, hlen, m);
+            /* check every bit is 1, 0, set, and not set at least once */
+            for (l=0; l<HASHSTATE; ++l)
+            {
+              e[l] &= (c[l]^d[l]);
+              f[l] &= ~(c[l]^d[l]);
+              g[l] &= c[l];
+              h[l] &= ~c[l];
+              x[l] &= d[l];
+              y[l] &= ~d[l];
+              if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0;
+            }
+            if (finished) break;
+          }
+          if (k>z) z=k;
+          if (k==MAXPAIR)
+          {
+             printf("Some bit didn't change: ");
+             printf("%.8x %.8x %.8x %.8x %.8x %.8x  ",
+                    e[0],f[0],g[0],h[0],x[0],y[0]);
+             printf("i %d j %d m %d len %d\n", i, j, m, hlen);
+          }
+          if (z==MAXPAIR) goto done;
+        }
+      }
+    }
+   done:
+    if (z < MAXPAIR)
+    {
+      printf("Mix success  %2d bytes  %2d initvals  ",i,m);
+      printf("required  %d  trials\n", z/2);
+    }
+  }
+  printf("\n");
+}
+
+/* Check for reading beyond the end of the buffer and alignment problems */
+void driver3()
+{
+  uint8_t buf[MAXLEN+20], *b;
+  uint32_t len;
+  uint8_t q[] = "This is the time for all good men to come to the aid of their country...";
+  uint32_t h;
+  uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country...";
+  uint32_t i;
+  uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country...";
+  uint32_t j;
+  uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country...";
+  uint32_t ref,x,y;
+  uint8_t *p;
+
+  printf("Endianness.  These lines should all be the same (for values filled in):\n");
+  printf("%.8x                            %.8x                            %.8x\n",
+         hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13),
+         hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13),
+         hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13));
+  p = q;
+  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
+         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+  p = &qq[1];
+  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
+         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+  p = &qqq[2];
+  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
+         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+  p = &qqqq[3];
+  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
+         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+  printf("\n");
+
+  /* check that hashlittle2 and hashlittle produce the same results */
+  i=47; j=0;
+  hashlittle2(q, sizeof(q), &i, &j);
+  if (hashlittle(q, sizeof(q), 47) != i)
+    printf("hashlittle2 and hashlittle mismatch\n");
+
+  /* check that hashword2 and hashword produce the same results */
+  len = 0xdeadbeef;
+  i=47, j=0;
+  hashword2(&len, 1, &i, &j);
+  if (hashword(&len, 1, 47) != i)
+    printf("hashword2 and hashword mismatch %x %x\n",
+           i, hashword(&len, 1, 47));
+
+  /* check hashlittle doesn't read before or after the ends of the string */
+  for (h=0, b=buf+1; h<8; ++h, ++b)
+  {
+    for (i=0; i<MAXLEN; ++i)
+    {
+      len = i;
+      for (j=0; j<i; ++j) *(b+j)=0;
+
+      /* these should all be equal */
+      ref = hashlittle(b, len, (uint32_t)1);
+      *(b+i)=(uint8_t)~0;
+      *(b-1)=(uint8_t)~0;
+      x = hashlittle(b, len, (uint32_t)1);
+      y = hashlittle(b, len, (uint32_t)1);
+      if ((ref != x) || (ref != y))
+      {
+        printf("alignment error: %.8x %.8x %.8x %d %d\n",ref,x,y,
+               h, i);
+      }
+    }
+  }
+}
+
+/* check for problems with nulls */
+ void driver4()
+{
+  uint8_t buf[1];
+  uint32_t h,i,state[HASHSTATE];
+
+
+  buf[0] = ~0;
+  for (i=0; i<HASHSTATE; ++i) state[i] = 1;
+  printf("These should all be different\n");
+  for (i=0, h=0; i<8; ++i)
+  {
+    h = hashlittle(buf, 0, h);
+    printf("%2ld  0-byte strings, hash is  %.8x\n", i, h);
+  }
+}
+
+void driver5()
+{
+  uint32_t b,c;
+  b=0, c=0, hashlittle2("", 0, &c, &b);
+  printf("hash is %.8lx %.8lx\n", c, b);   /* deadbeef deadbeef */
+  b=0xdeadbeef, c=0, hashlittle2("", 0, &c, &b);
+  printf("hash is %.8lx %.8lx\n", c, b);   /* bd5b7dde deadbeef */
+  b=0xdeadbeef, c=0xdeadbeef, hashlittle2("", 0, &c, &b);
+  printf("hash is %.8lx %.8lx\n", c, b);   /* 9c093ccd bd5b7dde */
+  b=0, c=0, hashlittle2("Four score and seven years ago", 30, &c, &b);
+  printf("hash is %.8lx %.8lx\n", c, b);   /* 17770551 ce7226e6 */
+  b=1, c=0, hashlittle2("Four score and seven years ago", 30, &c, &b);
+  printf("hash is %.8lx %.8lx\n", c, b);   /* e3607cae bd371de4 */
+  b=0, c=1, hashlittle2("Four score and seven years ago", 30, &c, &b);
+  printf("hash is %.8lx %.8lx\n", c, b);   /* cd628161 6cbea4b3 */
+  c = hashlittle("Four score and seven years ago", 30, 0);
+  printf("hash is %.8lx\n", c);   /* 17770551 */
+  c = hashlittle("Four score and seven years ago", 30, 1);
+  printf("hash is %.8lx\n", c);   /* cd628161 */
+}
+
+
+int main()
+{
+  driver1();   /* test that the key is hashed: used for timings */
+  driver2();   /* test that whole key is hashed thoroughly */
+  driver3();   /* test that nothing but the key is hashed */
+  driver4();   /* test hashing multiple buffers (all buffers are null) */
+  driver5();   /* test the hash against known vectors */
+  return 1;
+}
+
+#endif  /* SELF_TEST */
diff --git a/src/journal/lookup3.h b/src/journal/lookup3.h
new file mode 100644 (file)
index 0000000..502b42c
--- /dev/null
@@ -0,0 +1,22 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+#include <inttypes.h>
+#include <sys/types.h>
+
+uint32_t jenkins_hashword(const uint32_t *k, size_t length, uint32_t initval);
+void jenkins_hashword2(const uint32_t *k, size_t length, uint32_t *pc, uint32_t *pb);
+
+uint32_t jenkins_hashlittle(const void *key, size_t length, uint32_t initval);
+void jenkins_hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb);
+
+uint32_t jenkins_hashbig(const void *key, size_t length, uint32_t initval);
+
+static inline uint64_t hash64(const void *data, size_t length) {
+        uint32_t a = 0, b = 0;
+
+        jenkins_hashlittle2(data, length, &a, &b);
+
+        return ((uint64_t) a << 32ULL) | (uint64_t) b;
+}
diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
new file mode 100644 (file)
index 0000000..251aefe
--- /dev/null
@@ -0,0 +1,577 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include "hashmap.h"
+#include "list.h"
+#include "log.h"
+#include "util.h"
+#include "macro.h"
+#include "mmap-cache.h"
+
+typedef struct Window Window;
+typedef struct Context Context;
+typedef struct FileDescriptor FileDescriptor;
+
+struct Window {
+        MMapCache *cache;
+
+        bool keep_always;
+        bool in_unused;
+
+        void *ptr;
+        uint64_t offset;
+        int prot;
+        size_t size;
+
+        FileDescriptor *fd;
+
+        LIST_FIELDS(Window, by_fd);
+        LIST_FIELDS(Window, unused);
+
+        LIST_HEAD(Context, contexts);
+};
+
+struct Context {
+        MMapCache *cache;
+        unsigned id;
+        Window *window;
+
+        LIST_FIELDS(Context, by_window);
+};
+
+struct FileDescriptor {
+        MMapCache *cache;
+        int fd;
+        LIST_HEAD(Window, windows);
+};
+
+struct MMapCache {
+        int n_ref;
+
+        Hashmap *fds;
+        Hashmap *contexts;
+
+        unsigned n_windows;
+
+        LIST_HEAD(Window, unused);
+        Window *last_unused;
+};
+
+#define WINDOWS_MIN 64
+#define WINDOW_SIZE (8ULL*1024ULL*1024ULL)
+
+MMapCache* mmap_cache_new(void) {
+        MMapCache *m;
+
+        m = new0(MMapCache, 1);
+        if (!m)
+                return NULL;
+
+        m->n_ref = 1;
+        return m;
+}
+
+MMapCache* mmap_cache_ref(MMapCache *m) {
+        assert(m);
+        assert(m->n_ref > 0);
+
+        m->n_ref ++;
+        return m;
+}
+
+static void window_unlink(Window *w) {
+        Context *c;
+
+        assert(w);
+
+        if (w->ptr)
+                munmap(w->ptr, w->size);
+
+        if (w->fd)
+                LIST_REMOVE(Window, by_fd, w->fd->windows, w);
+
+        if (w->in_unused) {
+                if (w->cache->last_unused == w)
+                        w->cache->last_unused = w->unused_prev;
+
+                LIST_REMOVE(Window, unused, w->cache->unused, w);
+        }
+
+        LIST_FOREACH(by_window, c, w->contexts) {
+                assert(c->window == w);
+                c->window = NULL;
+        }
+}
+
+static void window_free(Window *w) {
+        assert(w);
+
+        window_unlink(w);
+        w->cache->n_windows--;
+        free(w);
+}
+
+static bool window_matches(Window *w, int fd, int prot, uint64_t offset, size_t size) {
+        assert(w);
+        assert(fd >= 0);
+        assert(size > 0);
+
+        return
+                w->fd &&
+                fd == w->fd->fd &&
+                prot == w->prot &&
+                offset >= w->offset &&
+                offset + size <= w->offset + w->size;
+}
+
+static Window *window_add(MMapCache *m) {
+        Window *w;
+
+        assert(m);
+
+        if (!m->last_unused || m->n_windows <= WINDOWS_MIN) {
+
+                /* Allocate a new window */
+                w = new0(Window, 1);
+                if (!w)
+                        return NULL;
+                m->n_windows++;
+        } else {
+
+                /* Reuse an existing one */
+                w = m->last_unused;
+                window_unlink(w);
+                zero(*w);
+        }
+
+        w->cache = m;
+        return w;
+}
+
+static void context_detach_window(Context *c) {
+        Window *w;
+
+        assert(c);
+
+        if (!c->window)
+                return;
+
+        w = c->window;
+        c->window = NULL;
+        LIST_REMOVE(Context, by_window, w->contexts, c);
+
+        if (!w->contexts && !w->keep_always) {
+                /* Not used anymore? */
+                LIST_PREPEND(Window, unused, c->cache->unused, w);
+                if (!c->cache->last_unused)
+                        c->cache->last_unused = w;
+
+                w->in_unused = true;
+        }
+}
+
+static void context_attach_window(Context *c, Window *w) {
+        assert(c);
+        assert(w);
+
+        if (c->window == w)
+                return;
+
+        context_detach_window(c);
+
+        if (w->in_unused) {
+                /* Used again? */
+                LIST_REMOVE(Window, unused, c->cache->unused, w);
+                if (c->cache->last_unused == w)
+                        c->cache->last_unused = w->unused_prev;
+
+                w->in_unused = false;
+        }
+
+        c->window = w;
+        LIST_PREPEND(Context, by_window, w->contexts, c);
+}
+
+static Context *context_add(MMapCache *m, unsigned id) {
+        Context *c;
+        int r;
+
+        assert(m);
+
+        c = hashmap_get(m->contexts, UINT_TO_PTR(id + 1));
+        if (c)
+                return c;
+
+        r = hashmap_ensure_allocated(&m->contexts, trivial_hash_func, trivial_compare_func);
+        if (r < 0)
+                return NULL;
+
+        c = new0(Context, 1);
+        if (!c)
+                return NULL;
+
+        c->cache = m;
+        c->id = id;
+
+        r = hashmap_put(m->contexts, UINT_TO_PTR(id + 1), c);
+        if (r < 0) {
+                free(c);
+                return NULL;
+        }
+
+        return c;
+}
+
+static void context_free(Context *c) {
+        assert(c);
+
+        context_detach_window(c);
+
+        if (c->cache)
+                assert_se(hashmap_remove(c->cache->contexts, UINT_TO_PTR(c->id + 1)));
+
+        free(c);
+}
+
+static void fd_free(FileDescriptor *f) {
+        assert(f);
+
+        while (f->windows)
+                window_free(f->windows);
+
+        if (f->cache)
+                assert_se(hashmap_remove(f->cache->fds, INT_TO_PTR(f->fd + 1)));
+
+        free(f);
+}
+
+static FileDescriptor* fd_add(MMapCache *m, int fd) {
+        FileDescriptor *f;
+        int r;
+
+        assert(m);
+        assert(fd >= 0);
+
+        f = hashmap_get(m->fds, INT_TO_PTR(fd + 1));
+        if (f)
+                return f;
+
+        r = hashmap_ensure_allocated(&m->fds, trivial_hash_func, trivial_compare_func);
+        if (r < 0)
+                return NULL;
+
+        f = new0(FileDescriptor, 1);
+        if (!f)
+                return NULL;
+
+        f->cache = m;
+        f->fd = fd;
+
+        r = hashmap_put(m->fds, UINT_TO_PTR(fd + 1), f);
+        if (r < 0) {
+                free(f);
+                return NULL;
+        }
+
+        return f;
+}
+
+static void mmap_cache_free(MMapCache *m) {
+        Context *c;
+        FileDescriptor *f;
+
+        assert(m);
+
+        while ((c = hashmap_first(m->contexts)))
+                context_free(c);
+
+        while ((f = hashmap_first(m->fds)))
+                fd_free(f);
+
+        while (m->unused)
+                window_free(m->unused);
+
+        free(m);
+}
+
+MMapCache* mmap_cache_unref(MMapCache *m) {
+        assert(m);
+        assert(m->n_ref > 0);
+
+        m->n_ref --;
+        if (m->n_ref == 0)
+                mmap_cache_free(m);
+
+        return NULL;
+}
+
+static int make_room(MMapCache *m) {
+        assert(m);
+
+        if (!m->last_unused)
+                return 0;
+
+        window_free(m->last_unused);
+        return 1;
+}
+
+static int try_context(
+                MMapCache *m,
+                int fd,
+                int prot,
+                unsigned context,
+                bool keep_always,
+                uint64_t offset,
+                size_t size,
+                void **ret) {
+
+        Context *c;
+
+        assert(m);
+        assert(m->n_ref > 0);
+        assert(fd >= 0);
+        assert(size > 0);
+        assert(ret);
+
+        c = hashmap_get(m->contexts, UINT_TO_PTR(context+1));
+        if (!c)
+                return 0;
+
+        assert(c->id == context);
+
+        if (!c->window)
+                return 0;
+
+        if (!window_matches(c->window, fd, prot, offset, size)) {
+
+                /* Drop the reference to the window, since it's unnecessary now */
+                context_detach_window(c);
+                return 0;
+        }
+
+        c->window->keep_always = c->window->keep_always || keep_always;
+
+        *ret = (uint8_t*) c->window->ptr + (offset - c->window->offset);
+        return 1;
+}
+
+static int find_mmap(
+                MMapCache *m,
+                int fd,
+                int prot,
+                unsigned context,
+                bool keep_always,
+                uint64_t offset,
+                size_t size,
+                void **ret) {
+
+        FileDescriptor *f;
+        Window *w;
+        Context *c;
+
+        assert(m);
+        assert(m->n_ref > 0);
+        assert(fd >= 0);
+        assert(size > 0);
+        assert(ret);
+
+        f = hashmap_get(m->fds, INT_TO_PTR(fd + 1));
+        if (!f)
+                return 0;
+
+        assert(f->fd == fd);
+
+        LIST_FOREACH(by_fd, w, f->windows)
+                if (window_matches(w, fd, prot, offset, size))
+                        break;
+
+        if (!w)
+                return 0;
+
+        c = context_add(m, context);
+        if (!c)
+                return -ENOMEM;
+
+        context_attach_window(c, w);
+        w->keep_always = w->keep_always || keep_always;
+
+        *ret = (uint8_t*) w->ptr + (offset - w->offset);
+        return 1;
+}
+
+static int add_mmap(
+                MMapCache *m,
+                int fd,
+                int prot,
+                unsigned context,
+                bool keep_always,
+                uint64_t offset,
+                size_t size,
+                struct stat *st,
+                void **ret) {
+
+        uint64_t woffset, wsize;
+        Context *c;
+        FileDescriptor *f;
+        Window *w;
+        void *d;
+        int r;
+
+        assert(m);
+        assert(m->n_ref > 0);
+        assert(fd >= 0);
+        assert(size > 0);
+        assert(ret);
+
+        woffset = offset & ~((uint64_t) page_size() - 1ULL);
+        wsize = size + (offset - woffset);
+        wsize = PAGE_ALIGN(wsize);
+
+        if (wsize < WINDOW_SIZE) {
+                uint64_t delta;
+
+                delta = PAGE_ALIGN((WINDOW_SIZE - wsize) / 2);
+
+                if (delta > offset)
+                        woffset = 0;
+                else
+                        woffset -= delta;
+
+                wsize = WINDOW_SIZE;
+        }
+
+        if (st) {
+                /* Memory maps that are larger then the files
+                   underneath have undefined behavior. Hence, clamp
+                   things to the file size if we know it */
+
+                if (woffset >= (uint64_t) st->st_size)
+                        return -EADDRNOTAVAIL;
+
+                if (woffset + wsize > (uint64_t) st->st_size)
+                        wsize = PAGE_ALIGN(st->st_size - woffset);
+        }
+
+        for (;;) {
+                d = mmap(NULL, wsize, prot, MAP_SHARED, fd, woffset);
+                if (d != MAP_FAILED)
+                        break;
+                if (errno != ENOMEM)
+                        return -errno;
+
+                r = make_room(m);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return -ENOMEM;
+        }
+
+        c = context_add(m, context);
+        if (!c)
+                return -ENOMEM;
+
+        f = fd_add(m, fd);
+        if (!f)
+                return -ENOMEM;
+
+        w = window_add(m);
+        if (!w)
+                return -ENOMEM;
+
+        w->keep_always = keep_always;
+        w->ptr = d;
+        w->offset = woffset;
+        w->prot = prot;
+        w->size = wsize;
+        w->fd = f;
+
+        LIST_PREPEND(Window, by_fd, f->windows, w);
+
+        context_detach_window(c);
+        c->window = w;
+        LIST_PREPEND(Context, by_window, w->contexts, c);
+
+        *ret = (uint8_t*) w->ptr + (offset - w->offset);
+        return 1;
+}
+
+int mmap_cache_get(
+                MMapCache *m,
+                int fd,
+                int prot,
+                unsigned context,
+                bool keep_always,
+                uint64_t offset,
+                size_t size,
+                struct stat *st,
+                void **ret) {
+
+        int r;
+
+        assert(m);
+        assert(m->n_ref > 0);
+        assert(fd >= 0);
+        assert(size > 0);
+        assert(ret);
+
+        /* Check whether the current context is the right one already */
+        r = try_context(m, fd, prot, context, keep_always, offset, size, ret);
+        if (r != 0)
+                return r;
+
+        /* Search for a matching mmap */
+        r = find_mmap(m, fd, prot, context, keep_always, offset, size, ret);
+        if (r != 0)
+                return r;
+
+        /* Create a new mmap */
+        return add_mmap(m, fd, prot, context, keep_always, offset, size, st, ret);
+}
+
+void mmap_cache_close_fd(MMapCache *m, int fd) {
+        FileDescriptor *f;
+
+        assert(m);
+        assert(fd >= 0);
+
+        f = hashmap_get(m->fds, INT_TO_PTR(fd + 1));
+        if (!f)
+                return;
+
+        fd_free(f);
+}
+
+void mmap_cache_close_context(MMapCache *m, unsigned context) {
+        Context *c;
+
+        assert(m);
+
+        c = hashmap_get(m->contexts, UINT_TO_PTR(context + 1));
+        if (!c)
+                return;
+
+        context_free(c);
+}
diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h
new file mode 100644 (file)
index 0000000..0c42fb8
--- /dev/null
@@ -0,0 +1,36 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+
+typedef struct MMapCache MMapCache;
+
+MMapCache* mmap_cache_new(void);
+MMapCache* mmap_cache_ref(MMapCache *m);
+MMapCache* mmap_cache_unref(MMapCache *m);
+
+int mmap_cache_get(MMapCache *m, int fd, int prot, unsigned context, bool keep_always, uint64_t offset, size_t size, struct stat *st, void **ret);
+void mmap_cache_close_fd(MMapCache *m, int fd);
+void mmap_cache_close_context(MMapCache *m, unsigned context);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
new file mode 100644 (file)
index 0000000..095fbb2
--- /dev/null
@@ -0,0 +1,2480 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/inotify.h>
+#include <sys/poll.h>
+#include <sys/vfs.h>
+#include <linux/magic.h>
+
+#include "sd-journal.h"
+#include "journal-def.h"
+#include "journal-file.h"
+#include "hashmap.h"
+#include "list.h"
+#include "path-util.h"
+#include "lookup3.h"
+#include "compress.h"
+#include "journal-internal.h"
+#include "missing.h"
+#include "catalog.h"
+#include "replace-var.h"
+
+#define JOURNAL_FILES_MAX 1024
+
+#define JOURNAL_FILES_RECHECK_USEC (2 * USEC_PER_SEC)
+
+#define REPLACE_VAR_MAX 256
+
+#define DEFAULT_DATA_THRESHOLD (64*1024)
+
+static void detach_location(sd_journal *j) {
+        Iterator i;
+        JournalFile *f;
+
+        assert(j);
+
+        j->current_file = NULL;
+        j->current_field = 0;
+
+        HASHMAP_FOREACH(f, j->files, i)
+                f->current_offset = 0;
+}
+
+static void reset_location(sd_journal *j) {
+        assert(j);
+
+        detach_location(j);
+        zero(j->current_location);
+}
+
+static void init_location(Location *l, LocationType type, JournalFile *f, Object *o) {
+        assert(l);
+        assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK);
+        assert(f);
+        assert(o->object.type == OBJECT_ENTRY);
+
+        l->type = type;
+        l->seqnum = le64toh(o->entry.seqnum);
+        l->seqnum_id = f->header->seqnum_id;
+        l->realtime = le64toh(o->entry.realtime);
+        l->monotonic = le64toh(o->entry.monotonic);
+        l->boot_id = o->entry.boot_id;
+        l->xor_hash = le64toh(o->entry.xor_hash);
+
+        l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true;
+}
+
+static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, uint64_t offset) {
+        assert(j);
+        assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK);
+        assert(f);
+        assert(o);
+
+        init_location(&j->current_location, type, f, o);
+
+        j->current_file = f;
+        j->current_field = 0;
+
+        f->current_offset = offset;
+}
+
+static int match_is_valid(const void *data, size_t size) {
+        const char *b, *p;
+
+        assert(data);
+
+        if (size < 2)
+                return false;
+
+        if (startswith(data, "__"))
+                return false;
+
+        b = data;
+        for (p = b; p < b + size; p++) {
+
+                if (*p == '=')
+                        return p > b;
+
+                if (*p == '_')
+                        continue;
+
+                if (*p >= 'A' && *p <= 'Z')
+                        continue;
+
+                if (*p >= '0' && *p <= '9')
+                        continue;
+
+                return false;
+        }
+
+        return false;
+}
+
+static bool same_field(const void *_a, size_t s, const void *_b, size_t t) {
+        const uint8_t *a = _a, *b = _b;
+        size_t j;
+
+        for (j = 0; j < s && j < t; j++) {
+
+                if (a[j] != b[j])
+                        return false;
+
+                if (a[j] == '=')
+                        return true;
+        }
+
+        return true;
+}
+
+static Match *match_new(Match *p, MatchType t) {
+        Match *m;
+
+        m = new0(Match, 1);
+        if (!m)
+                return NULL;
+
+        m->type = t;
+
+        if (p) {
+                m->parent = p;
+                LIST_PREPEND(Match, matches, p->matches, m);
+        }
+
+        return m;
+}
+
+static void match_free(Match *m) {
+        assert(m);
+
+        while (m->matches)
+                match_free(m->matches);
+
+        if (m->parent)
+                LIST_REMOVE(Match, matches, m->parent->matches, m);
+
+        free(m->data);
+        free(m);
+}
+
+static void match_free_if_empty(Match *m) {
+        assert(m);
+
+        if (m->matches)
+                return;
+
+        match_free(m);
+}
+
+_public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
+        Match *l2, *l3, *add_here = NULL, *m;
+        le64_t le_hash;
+
+        if (!j)
+                return -EINVAL;
+
+        if (!data)
+                return -EINVAL;
+
+        if (size == 0)
+                size = strlen(data);
+
+        if (!match_is_valid(data, size))
+                return -EINVAL;
+
+        /* level 0: OR term
+         * level 1: AND terms
+         * level 2: OR terms
+         * level 3: concrete matches */
+
+        if (!j->level0) {
+                j->level0 = match_new(NULL, MATCH_OR_TERM);
+                if (!j->level0)
+                        return -ENOMEM;
+        }
+
+        if (!j->level1) {
+                j->level1 = match_new(j->level0, MATCH_AND_TERM);
+                if (!j->level1)
+                        return -ENOMEM;
+        }
+
+        assert(j->level0->type == MATCH_OR_TERM);
+        assert(j->level1->type == MATCH_AND_TERM);
+
+        le_hash = htole64(hash64(data, size));
+
+        LIST_FOREACH(matches, l2, j->level1->matches) {
+                assert(l2->type == MATCH_OR_TERM);
+
+                LIST_FOREACH(matches, l3, l2->matches) {
+                        assert(l3->type == MATCH_DISCRETE);
+
+                        /* Exactly the same match already? Then ignore
+                         * this addition */
+                        if (l3->le_hash == le_hash &&
+                            l3->size == size &&
+                            memcmp(l3->data, data, size) == 0)
+                                return 0;
+
+                        /* Same field? Then let's add this to this OR term */
+                        if (same_field(data, size, l3->data, l3->size)) {
+                                add_here = l2;
+                                break;
+                        }
+                }
+
+                if (add_here)
+                        break;
+        }
+
+        if (!add_here) {
+                add_here = match_new(j->level1, MATCH_OR_TERM);
+                if (!add_here)
+                        goto fail;
+        }
+
+        m = match_new(add_here, MATCH_DISCRETE);
+        if (!m)
+                goto fail;
+
+        m->le_hash = le_hash;
+        m->size = size;
+        m->data = memdup(data, size);
+        if (!m->data)
+                goto fail;
+
+        detach_location(j);
+
+        return 0;
+
+fail:
+        if (add_here)
+                match_free_if_empty(add_here);
+
+        if (j->level1)
+                match_free_if_empty(j->level1);
+
+        if (j->level0)
+                match_free_if_empty(j->level0);
+
+        return -ENOMEM;
+}
+
+_public_ int sd_journal_add_disjunction(sd_journal *j) {
+        Match *m;
+
+        assert(j);
+
+        if (!j->level0)
+                return 0;
+
+        if (!j->level1)
+                return 0;
+
+        if (!j->level1->matches)
+                return 0;
+
+        m = match_new(j->level0, MATCH_AND_TERM);
+        if (!m)
+                return -ENOMEM;
+
+        j->level1 = m;
+        return 0;
+}
+
+static char *match_make_string(Match *m) {
+        char *p, *r;
+        Match *i;
+        bool enclose = false;
+
+        if (!m)
+                return strdup("");
+
+        if (m->type == MATCH_DISCRETE)
+                return strndup(m->data, m->size);
+
+        p = NULL;
+        LIST_FOREACH(matches, i, m->matches) {
+                char *t, *k;
+
+                t = match_make_string(i);
+                if (!t) {
+                        free(p);
+                        return NULL;
+                }
+
+                if (p) {
+                        k = strjoin(p, m->type == MATCH_OR_TERM ? " OR " : " AND ", t, NULL);
+                        free(p);
+                        free(t);
+
+                        if (!k)
+                                return NULL;
+
+                        p = k;
+
+                        enclose = true;
+                } else {
+                        free(p);
+                        p = t;
+                }
+        }
+
+        if (enclose) {
+                r = strjoin("(", p, ")", NULL);
+                free(p);
+                return r;
+        }
+
+        return p;
+}
+
+char *journal_make_match_string(sd_journal *j) {
+        assert(j);
+
+        return match_make_string(j->level0);
+}
+
+_public_ void sd_journal_flush_matches(sd_journal *j) {
+
+        if (!j)
+                return;
+
+        if (j->level0)
+                match_free(j->level0);
+
+        j->level0 = j->level1 = NULL;
+
+        detach_location(j);
+}
+
+static int compare_entry_order(JournalFile *af, Object *_ao,
+                         JournalFile *bf, uint64_t bp) {
+
+        uint64_t a, b;
+        Object *ao, *bo;
+        int r;
+
+        assert(af);
+        assert(bf);
+        assert(_ao);
+
+        /* The mmap cache might invalidate the object from the first
+         * file if we look at the one from the second file. Hence
+         * temporarily copy the header of the first one, and look at
+         * that only. */
+        ao = alloca(offsetof(EntryObject, items));
+        memcpy(ao, _ao, offsetof(EntryObject, items));
+
+        r = journal_file_move_to_object(bf, OBJECT_ENTRY, bp, &bo);
+        if (r < 0)
+                return strcmp(af->path, bf->path);
+
+        /* We operate on two different files here, hence we can access
+         * two objects at the same time, which we normally can't.
+         *
+         * If contents and timestamps match, these entries are
+         * identical, even if the seqnum does not match */
+
+        if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id) &&
+            ao->entry.monotonic == bo->entry.monotonic &&
+            ao->entry.realtime == bo->entry.realtime &&
+            ao->entry.xor_hash == bo->entry.xor_hash)
+                return 0;
+
+        if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {
+
+                /* If this is from the same seqnum source, compare
+                 * seqnums */
+                a = le64toh(ao->entry.seqnum);
+                b = le64toh(bo->entry.seqnum);
+
+                if (a < b)
+                        return -1;
+                if (a > b)
+                        return 1;
+
+                /* Wow! This is weird, different data but the same
+                 * seqnums? Something is borked, but let's make the
+                 * best of it and compare by time. */
+        }
+
+        if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id)) {
+
+                /* If the boot id matches compare monotonic time */
+                a = le64toh(ao->entry.monotonic);
+                b = le64toh(bo->entry.monotonic);
+
+                if (a < b)
+                        return -1;
+                if (a > b)
+                        return 1;
+        }
+
+        /* Otherwise compare UTC time */
+        a = le64toh(ao->entry.realtime);
+        b = le64toh(bo->entry.realtime);
+
+        if (a < b)
+                return -1;
+        if (a > b)
+                return 1;
+
+        /* Finally, compare by contents */
+        a = le64toh(ao->entry.xor_hash);
+        b = le64toh(bo->entry.xor_hash);
+
+        if (a < b)
+                return -1;
+        if (a > b)
+                return 1;
+
+        return 0;
+}
+
+static int compare_with_location(JournalFile *af, Object *ao, Location *l) {
+        uint64_t a;
+
+        assert(af);
+        assert(ao);
+        assert(l);
+        assert(l->type == LOCATION_DISCRETE || l->type == LOCATION_SEEK);
+
+        if (l->monotonic_set &&
+            sd_id128_equal(ao->entry.boot_id, l->boot_id) &&
+            l->realtime_set &&
+            le64toh(ao->entry.realtime) == l->realtime &&
+            l->xor_hash_set &&
+            le64toh(ao->entry.xor_hash) == l->xor_hash)
+                return 0;
+
+        if (l->seqnum_set &&
+            sd_id128_equal(af->header->seqnum_id, l->seqnum_id)) {
+
+                a = le64toh(ao->entry.seqnum);
+
+                if (a < l->seqnum)
+                        return -1;
+                if (a > l->seqnum)
+                        return 1;
+        }
+
+        if (l->monotonic_set &&
+            sd_id128_equal(ao->entry.boot_id, l->boot_id)) {
+
+                a = le64toh(ao->entry.monotonic);
+
+                if (a < l->monotonic)
+                        return -1;
+                if (a > l->monotonic)
+                        return 1;
+        }
+
+        if (l->realtime_set) {
+
+                a = le64toh(ao->entry.realtime);
+
+                if (a < l->realtime)
+                        return -1;
+                if (a > l->realtime)
+                        return 1;
+        }
+
+        if (l->xor_hash_set) {
+                a = le64toh(ao->entry.xor_hash);
+
+                if (a < l->xor_hash)
+                        return -1;
+                if (a > l->xor_hash)
+                        return 1;
+        }
+
+        return 0;
+}
+
+static int next_for_match(
+                sd_journal *j,
+                Match *m,
+                JournalFile *f,
+                uint64_t after_offset,
+                direction_t direction,
+                Object **ret,
+                uint64_t *offset) {
+
+        int r;
+        uint64_t np = 0;
+        Object *n;
+
+        assert(j);
+        assert(m);
+        assert(f);
+
+        if (m->type == MATCH_DISCRETE) {
+                uint64_t dp;
+
+                r = journal_file_find_data_object_with_hash(f, m->data, m->size, le64toh(m->le_hash), NULL, &dp);
+                if (r <= 0)
+                        return r;
+
+                return journal_file_move_to_entry_by_offset_for_data(f, dp, after_offset, direction, ret, offset);
+
+        } else if (m->type == MATCH_OR_TERM) {
+                Match *i;
+
+                /* Find the earliest match beyond after_offset */
+
+                LIST_FOREACH(matches, i, m->matches) {
+                        uint64_t cp;
+
+                        r = next_for_match(j, i, f, after_offset, direction, NULL, &cp);
+                        if (r < 0)
+                                return r;
+                        else if (r > 0) {
+                                if (np == 0 || (direction == DIRECTION_DOWN ? np > cp : np < cp))
+                                        np = cp;
+                        }
+                }
+
+        } else if (m->type == MATCH_AND_TERM) {
+                Match *i;
+                bool continue_looking;
+
+                /* Always jump to the next matching entry and repeat
+                 * this until we fine and offset that matches for all
+                 * matches. */
+
+                if (!m->matches)
+                        return 0;
+
+                np = 0;
+                do {
+                        continue_looking = false;
+
+                        LIST_FOREACH(matches, i, m->matches) {
+                                uint64_t cp, limit;
+
+                                if (np == 0)
+                                        limit = after_offset;
+                                else if (direction == DIRECTION_DOWN)
+                                        limit = MAX(np, after_offset);
+                                else
+                                        limit = MIN(np, after_offset);
+
+                                r = next_for_match(j, i, f, limit, direction, NULL, &cp);
+                                if (r <= 0)
+                                        return r;
+
+                                if ((direction == DIRECTION_DOWN ? cp >= after_offset : cp <= after_offset) &&
+                                    (np == 0 || (direction == DIRECTION_DOWN ? cp > np : np < cp))) {
+                                        np = cp;
+                                        continue_looking = true;
+                                }
+                        }
+
+                } while (continue_looking);
+        }
+
+        if (np == 0)
+                return 0;
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n);
+        if (r < 0)
+                return r;
+
+        if (ret)
+                *ret = n;
+        if (offset)
+                *offset = np;
+
+        return 1;
+}
+
+static int find_location_for_match(
+                sd_journal *j,
+                Match *m,
+                JournalFile *f,
+                direction_t direction,
+                Object **ret,
+                uint64_t *offset) {
+
+        int r;
+
+        assert(j);
+        assert(m);
+        assert(f);
+
+        if (m->type == MATCH_DISCRETE) {
+                uint64_t dp;
+
+                r = journal_file_find_data_object_with_hash(f, m->data, m->size, le64toh(m->le_hash), NULL, &dp);
+                if (r <= 0)
+                        return r;
+
+                /* FIXME: missing: find by monotonic */
+
+                if (j->current_location.type == LOCATION_HEAD)
+                        return journal_file_next_entry_for_data(f, NULL, 0, dp, DIRECTION_DOWN, ret, offset);
+                if (j->current_location.type == LOCATION_TAIL)
+                        return journal_file_next_entry_for_data(f, NULL, 0, dp, DIRECTION_UP, ret, offset);
+                if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id))
+                        return journal_file_move_to_entry_by_seqnum_for_data(f, dp, j->current_location.seqnum, direction, ret, offset);
+                if (j->current_location.monotonic_set) {
+                        r = journal_file_move_to_entry_by_monotonic_for_data(f, dp, j->current_location.boot_id, j->current_location.monotonic, direction, ret, offset);
+                        if (r != -ENOENT)
+                                return r;
+                }
+                if (j->current_location.realtime_set)
+                        return journal_file_move_to_entry_by_realtime_for_data(f, dp, j->current_location.realtime, direction, ret, offset);
+
+                return journal_file_next_entry_for_data(f, NULL, 0, dp, direction, ret, offset);
+
+        } else if (m->type == MATCH_OR_TERM) {
+                uint64_t np = 0;
+                Object *n;
+                Match *i;
+
+                /* Find the earliest match */
+
+                LIST_FOREACH(matches, i, m->matches) {
+                        uint64_t cp;
+
+                        r = find_location_for_match(j, i, f, direction, NULL, &cp);
+                        if (r < 0)
+                                return r;
+                        else if (r > 0) {
+                                if (np == 0 || (direction == DIRECTION_DOWN ? np > cp : np < cp))
+                                        np = cp;
+                        }
+                }
+
+                if (np == 0)
+                        return 0;
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n);
+                if (r < 0)
+                        return r;
+
+                if (ret)
+                        *ret = n;
+                if (offset)
+                        *offset = np;
+
+                return 1;
+
+        } else {
+                Match *i;
+                uint64_t np = 0;
+
+                assert(m->type == MATCH_AND_TERM);
+
+                /* First jump to the last match, and then find the
+                 * next one where all matches match */
+
+                if (!m->matches)
+                        return 0;
+
+                LIST_FOREACH(matches, i, m->matches) {
+                        uint64_t cp;
+
+                        r = find_location_for_match(j, i, f, direction, NULL, &cp);
+                        if (r <= 0)
+                                return r;
+
+                        if (np == 0 || (direction == DIRECTION_DOWN ? np < cp : np > cp))
+                                np = cp;
+                }
+
+                return next_for_match(j, m, f, np, direction, ret, offset);
+        }
+}
+
+static int find_location_with_matches(
+                sd_journal *j,
+                JournalFile *f,
+                direction_t direction,
+                Object **ret,
+                uint64_t *offset) {
+
+        int r;
+
+        assert(j);
+        assert(f);
+        assert(ret);
+        assert(offset);
+
+        if (!j->level0) {
+                /* No matches is simple */
+
+                if (j->current_location.type == LOCATION_HEAD)
+                        return journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, ret, offset);
+                if (j->current_location.type == LOCATION_TAIL)
+                        return journal_file_next_entry(f, NULL, 0, DIRECTION_UP, ret, offset);
+                if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id))
+                        return journal_file_move_to_entry_by_seqnum(f, j->current_location.seqnum, direction, ret, offset);
+                if (j->current_location.monotonic_set) {
+                        r = journal_file_move_to_entry_by_monotonic(f, j->current_location.boot_id, j->current_location.monotonic, direction, ret, offset);
+                        if (r != -ENOENT)
+                                return r;
+                }
+                if (j->current_location.realtime_set)
+                        return journal_file_move_to_entry_by_realtime(f, j->current_location.realtime, direction, ret, offset);
+
+                return journal_file_next_entry(f, NULL, 0, direction, ret, offset);
+        } else
+                return find_location_for_match(j, j->level0, f, direction, ret, offset);
+}
+
+static int next_with_matches(
+                sd_journal *j,
+                JournalFile *f,
+                direction_t direction,
+                Object **ret,
+                uint64_t *offset) {
+
+        Object *c;
+        uint64_t cp;
+
+        assert(j);
+        assert(f);
+        assert(ret);
+        assert(offset);
+
+        c = *ret;
+        cp = *offset;
+
+        /* No matches is easy. We simple advance the file
+         * pointer by one. */
+        if (!j->level0)
+                return journal_file_next_entry(f, c, cp, direction, ret, offset);
+
+        /* If we have a match then we look for the next matching entry
+         * with an offset at least one step larger */
+        return next_for_match(j, j->level0, f, direction == DIRECTION_DOWN ? cp+1 : cp-1, direction, ret, offset);
+}
+
+static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction, Object **ret, uint64_t *offset) {
+        Object *c;
+        uint64_t cp;
+        int r;
+
+        assert(j);
+        assert(f);
+
+        if (f->current_offset > 0) {
+                cp = f->current_offset;
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c);
+                if (r < 0)
+                        return r;
+
+                r = next_with_matches(j, f, direction, &c, &cp);
+                if (r <= 0)
+                        return r;
+        } else {
+                r = find_location_with_matches(j, f, direction, &c, &cp);
+                if (r <= 0)
+                        return r;
+        }
+
+        /* OK, we found the spot, now let's advance until to an entry
+         * that is actually different from what we were previously
+         * looking at. This is necessary to handle entries which exist
+         * in two (or more) journal files, and which shall all be
+         * suppressed but one. */
+
+        for (;;) {
+                bool found;
+
+                if (j->current_location.type == LOCATION_DISCRETE) {
+                        int k;
+
+                        k = compare_with_location(f, c, &j->current_location);
+                        if (direction == DIRECTION_DOWN)
+                                found = k > 0;
+                        else
+                                found = k < 0;
+                } else
+                        found = true;
+
+                if (found) {
+                        if (ret)
+                                *ret = c;
+                        if (offset)
+                                *offset = cp;
+                        return 1;
+                }
+
+                r = next_with_matches(j, f, direction, &c, &cp);
+                if (r <= 0)
+                        return r;
+        }
+}
+
+static int real_journal_next(sd_journal *j, direction_t direction) {
+        JournalFile *f, *new_file = NULL;
+        uint64_t new_offset = 0;
+        Object *o;
+        uint64_t p;
+        Iterator i;
+        int r;
+
+        if (!j)
+                return -EINVAL;
+
+        HASHMAP_FOREACH(f, j->files, i) {
+                bool found;
+
+                r = next_beyond_location(j, f, direction, &o, &p);
+                if (r < 0) {
+                        log_debug("Can't iterate through %s, ignoring: %s", f->path, strerror(-r));
+                        continue;
+                } else if (r == 0)
+                        continue;
+
+                if (!new_file)
+                        found = true;
+                else {
+                        int k;
+
+                        k = compare_entry_order(f, o, new_file, new_offset);
+
+                        if (direction == DIRECTION_DOWN)
+                                found = k < 0;
+                        else
+                                found = k > 0;
+                }
+
+                if (found) {
+                        new_file = f;
+                        new_offset = p;
+                }
+        }
+
+        if (!new_file)
+                return 0;
+
+        r = journal_file_move_to_object(new_file, OBJECT_ENTRY, new_offset, &o);
+        if (r < 0)
+                return r;
+
+        set_location(j, LOCATION_DISCRETE, new_file, o, new_offset);
+
+        return 1;
+}
+
+_public_ int sd_journal_next(sd_journal *j) {
+        return real_journal_next(j, DIRECTION_DOWN);
+}
+
+_public_ int sd_journal_previous(sd_journal *j) {
+        return real_journal_next(j, DIRECTION_UP);
+}
+
+static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t skip) {
+        int c = 0, r;
+
+        if (!j)
+                return -EINVAL;
+
+        if (skip == 0) {
+                /* If this is not a discrete skip, then at least
+                 * resolve the current location */
+                if (j->current_location.type != LOCATION_DISCRETE)
+                        return real_journal_next(j, direction);
+
+                return 0;
+        }
+
+        do {
+                r = real_journal_next(j, direction);
+                if (r < 0)
+                        return r;
+
+                if (r == 0)
+                        return c;
+
+                skip--;
+                c++;
+        } while (skip > 0);
+
+        return c;
+}
+
+_public_ int sd_journal_next_skip(sd_journal *j, uint64_t skip) {
+        return real_journal_next_skip(j, DIRECTION_DOWN, skip);
+}
+
+_public_ int sd_journal_previous_skip(sd_journal *j, uint64_t skip) {
+        return real_journal_next_skip(j, DIRECTION_UP, skip);
+}
+
+_public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
+        Object *o;
+        int r;
+        char bid[33], sid[33];
+
+        if (!j)
+                return -EINVAL;
+        if (!cursor)
+                return -EINVAL;
+
+        if (!j->current_file || j->current_file->current_offset <= 0)
+                return -EADDRNOTAVAIL;
+
+        r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->current_file->current_offset, &o);
+        if (r < 0)
+                return r;
+
+        sd_id128_to_string(j->current_file->header->seqnum_id, sid);
+        sd_id128_to_string(o->entry.boot_id, bid);
+
+        if (asprintf(cursor,
+                     "s=%s;i=%llx;b=%s;m=%llx;t=%llx;x=%llx",
+                     sid, (unsigned long long) le64toh(o->entry.seqnum),
+                     bid, (unsigned long long) le64toh(o->entry.monotonic),
+                     (unsigned long long) le64toh(o->entry.realtime),
+                     (unsigned long long) le64toh(o->entry.xor_hash)) < 0)
+                return -ENOMEM;
+
+        return 1;
+}
+
+_public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
+        char *w, *state;
+        size_t l;
+        unsigned long long seqnum, monotonic, realtime, xor_hash;
+        bool
+                seqnum_id_set = false,
+                seqnum_set = false,
+                boot_id_set = false,
+                monotonic_set = false,
+                realtime_set = false,
+                xor_hash_set = false;
+        sd_id128_t seqnum_id, boot_id;
+
+        if (!j)
+                return -EINVAL;
+        if (isempty(cursor))
+                return -EINVAL;
+
+        FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
+                char *item;
+                int k = 0;
+
+                if (l < 2 || w[1] != '=')
+                        return -EINVAL;
+
+                item = strndup(w, l);
+                if (!item)
+                        return -ENOMEM;
+
+                switch (w[0]) {
+
+                case 's':
+                        seqnum_id_set = true;
+                        k = sd_id128_from_string(item+2, &seqnum_id);
+                        break;
+
+                case 'i':
+                        seqnum_set = true;
+                        if (sscanf(item+2, "%llx", &seqnum) != 1)
+                                k = -EINVAL;
+                        break;
+
+                case 'b':
+                        boot_id_set = true;
+                        k = sd_id128_from_string(item+2, &boot_id);
+                        break;
+
+                case 'm':
+                        monotonic_set = true;
+                        if (sscanf(item+2, "%llx", &monotonic) != 1)
+                                k = -EINVAL;
+                        break;
+
+                case 't':
+                        realtime_set = true;
+                        if (sscanf(item+2, "%llx", &realtime) != 1)
+                                k = -EINVAL;
+                        break;
+
+                case 'x':
+                        xor_hash_set = true;
+                        if (sscanf(item+2, "%llx", &xor_hash) != 1)
+                                k = -EINVAL;
+                        break;
+                }
+
+                free(item);
+
+                if (k < 0)
+                        return k;
+        }
+
+        if ((!seqnum_set || !seqnum_id_set) &&
+            (!monotonic_set || !boot_id_set) &&
+            !realtime_set)
+                return -EINVAL;
+
+        reset_location(j);
+
+        j->current_location.type = LOCATION_SEEK;
+
+        if (realtime_set) {
+                j->current_location.realtime = (uint64_t) realtime;
+                j->current_location.realtime_set = true;
+        }
+
+        if (seqnum_set && seqnum_id_set) {
+                j->current_location.seqnum = (uint64_t) seqnum;
+                j->current_location.seqnum_id = seqnum_id;
+                j->current_location.seqnum_set = true;
+        }
+
+        if (monotonic_set && boot_id_set) {
+                j->current_location.monotonic = (uint64_t) monotonic;
+                j->current_location.boot_id = boot_id;
+                j->current_location.monotonic_set = true;
+        }
+
+        if (xor_hash_set) {
+                j->current_location.xor_hash = (uint64_t) xor_hash;
+                j->current_location.xor_hash_set = true;
+        }
+
+        return 0;
+}
+
+_public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
+        int r;
+        char *w, *state;
+        size_t l;
+        Object *o;
+
+        if (!j)
+                return -EINVAL;
+        if (isempty(cursor))
+                return -EINVAL;
+
+        if (!j->current_file || j->current_file->current_offset <= 0)
+                return -EADDRNOTAVAIL;
+
+        r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->current_file->current_offset, &o);
+        if (r < 0)
+                return r;
+
+        FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
+                _cleanup_free_ char *item = NULL;
+                sd_id128_t id;
+                unsigned long long ll;
+                int k = 0;
+
+                if (l < 2 || w[1] != '=')
+                        return -EINVAL;
+
+                item = strndup(w, l);
+                if (!item)
+                        return -ENOMEM;
+
+                switch (w[0]) {
+
+                case 's':
+                        k = sd_id128_from_string(item+2, &id);
+                        if (k < 0)
+                                return k;
+                        if (!sd_id128_equal(id, j->current_file->header->seqnum_id))
+                                return 0;
+                        break;
+
+                case 'i':
+                        if (sscanf(item+2, "%llx", &ll) != 1)
+                                return -EINVAL;
+                        if (ll != le64toh(o->entry.seqnum))
+                                return 0;
+                        break;
+
+                case 'b':
+                        k = sd_id128_from_string(item+2, &id);
+                        if (k < 0)
+                                return k;
+                        if (!sd_id128_equal(id, o->entry.boot_id))
+                                return 0;
+                        break;
+
+                case 'm':
+                        if (sscanf(item+2, "%llx", &ll) != 1)
+                                return -EINVAL;
+                        if (ll != le64toh(o->entry.monotonic))
+                                return 0;
+                        break;
+
+                case 't':
+                        if (sscanf(item+2, "%llx", &ll) != 1)
+                                return -EINVAL;
+                        if (ll != le64toh(o->entry.realtime))
+                                return 0;
+                        break;
+
+                case 'x':
+                        if (sscanf(item+2, "%llx", &ll) != 1)
+                                return -EINVAL;
+                        if (ll != le64toh(o->entry.xor_hash))
+                                return 0;
+                        break;
+                }
+        }
+
+        return 1;
+}
+
+
+_public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) {
+        if (!j)
+                return -EINVAL;
+
+        reset_location(j);
+        j->current_location.type = LOCATION_SEEK;
+        j->current_location.boot_id = boot_id;
+        j->current_location.monotonic = usec;
+        j->current_location.monotonic_set = true;
+
+        return 0;
+}
+
+_public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {
+        if (!j)
+                return -EINVAL;
+
+        reset_location(j);
+        j->current_location.type = LOCATION_SEEK;
+        j->current_location.realtime = usec;
+        j->current_location.realtime_set = true;
+
+        return 0;
+}
+
+_public_ int sd_journal_seek_head(sd_journal *j) {
+        if (!j)
+                return -EINVAL;
+
+        reset_location(j);
+        j->current_location.type = LOCATION_HEAD;
+
+        return 0;
+}
+
+_public_ int sd_journal_seek_tail(sd_journal *j) {
+        if (!j)
+                return -EINVAL;
+
+        reset_location(j);
+        j->current_location.type = LOCATION_TAIL;
+
+        return 0;
+}
+
+static void check_network(sd_journal *j, int fd) {
+        struct statfs sfs;
+
+        assert(j);
+
+        if (j->on_network)
+                return;
+
+        if (fstatfs(fd, &sfs) < 0)
+                return;
+
+        j->on_network =
+                (long)sfs.f_type == (long)CIFS_MAGIC_NUMBER ||
+                sfs.f_type == CODA_SUPER_MAGIC ||
+                sfs.f_type == NCP_SUPER_MAGIC ||
+                sfs.f_type == NFS_SUPER_MAGIC ||
+                sfs.f_type == SMB_SUPER_MAGIC;
+}
+
+static int add_file(sd_journal *j, const char *prefix, const char *filename) {
+        char *path;
+        int r;
+        JournalFile *f;
+
+        assert(j);
+        assert(prefix);
+        assert(filename);
+
+        if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) &&
+            !(streq(filename, "system.journal") ||
+              streq(filename, "system.journal~") ||
+              (startswith(filename, "system@") &&
+               (endswith(filename, ".journal") || endswith(filename, ".journal~")))))
+                return 0;
+
+        path = strjoin(prefix, "/", filename, NULL);
+        if (!path)
+                return -ENOMEM;
+
+        if (hashmap_get(j->files, path)) {
+                free(path);
+                return 0;
+        }
+
+        if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
+                log_debug("Too many open journal files, not adding %s, ignoring.", path);
+                free(path);
+                return 0;
+        }
+
+        r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f);
+        free(path);
+
+        if (r < 0) {
+                if (errno == ENOENT)
+                        return 0;
+
+                return r;
+        }
+
+        /* journal_file_dump(f); */
+
+        r = hashmap_put(j->files, f->path, f);
+        if (r < 0) {
+                journal_file_close(f);
+                return r;
+        }
+
+        check_network(j, f->fd);
+
+        j->current_invalidate_counter ++;
+
+        log_debug("File %s got added.", f->path);
+
+        return 0;
+}
+
+static int remove_file(sd_journal *j, const char *prefix, const char *filename) {
+        char *path;
+        JournalFile *f;
+
+        assert(j);
+        assert(prefix);
+        assert(filename);
+
+        path = strjoin(prefix, "/", filename, NULL);
+        if (!path)
+                return -ENOMEM;
+
+        f = hashmap_get(j->files, path);
+        free(path);
+        if (!f)
+                return 0;
+
+        hashmap_remove(j->files, f->path);
+
+        log_debug("File %s got removed.", f->path);
+
+        if (j->current_file == f) {
+                j->current_file = NULL;
+                j->current_field = 0;
+        }
+
+        if (j->unique_file == f) {
+                j->unique_file = NULL;
+                j->unique_offset = 0;
+        }
+
+        journal_file_close(f);
+
+        j->current_invalidate_counter ++;
+
+        return 0;
+}
+
+static int add_directory(sd_journal *j, const char *prefix, const char *dirname) {
+        char *path;
+        int r;
+        DIR *d;
+        sd_id128_t id, mid;
+        Directory *m;
+
+        assert(j);
+        assert(prefix);
+        assert(dirname);
+
+        if ((j->flags & SD_JOURNAL_LOCAL_ONLY) &&
+            (sd_id128_from_string(dirname, &id) < 0 ||
+             sd_id128_get_machine(&mid) < 0 ||
+             !sd_id128_equal(id, mid)))
+            return 0;
+
+        path = strjoin(prefix, "/", dirname, NULL);
+        if (!path)
+                return -ENOMEM;
+
+        d = opendir(path);
+        if (!d) {
+                log_debug("Failed to open %s: %m", path);
+                free(path);
+
+                if (errno == ENOENT)
+                        return 0;
+                return -errno;
+        }
+
+        m = hashmap_get(j->directories_by_path, path);
+        if (!m) {
+                m = new0(Directory, 1);
+                if (!m) {
+                        closedir(d);
+                        free(path);
+                        return -ENOMEM;
+                }
+
+                m->is_root = false;
+                m->path = path;
+
+                if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
+                        closedir(d);
+                        free(m->path);
+                        free(m);
+                        return -ENOMEM;
+                }
+
+                j->current_invalidate_counter ++;
+
+                log_debug("Directory %s got added.", m->path);
+
+        } else if (m->is_root) {
+                free (path);
+                closedir(d);
+                return 0;
+        }  else
+                free(path);
+
+        if (m->wd <= 0 && j->inotify_fd >= 0) {
+
+                m->wd = inotify_add_watch(j->inotify_fd, m->path,
+                                          IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
+                                          IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_MOVED_FROM|
+                                          IN_ONLYDIR);
+
+                if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0)
+                        inotify_rm_watch(j->inotify_fd, m->wd);
+        }
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+
+                r = readdir_r(d, &buf.de, &de);
+                if (r != 0 || !de)
+                        break;
+
+                if (dirent_is_file_with_suffix(de, ".journal") ||
+                    dirent_is_file_with_suffix(de, ".journal~")) {
+                        r = add_file(j, m->path, de->d_name);
+                        if (r < 0)
+                                log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r));
+                }
+        }
+
+        check_network(j, dirfd(d));
+
+        closedir(d);
+
+        return 0;
+}
+
+static int add_root_directory(sd_journal *j, const char *p) {
+        DIR *d;
+        Directory *m;
+        int r;
+
+        assert(j);
+        assert(p);
+
+        if ((j->flags & SD_JOURNAL_RUNTIME_ONLY) &&
+            !path_startswith(p, "/run"))
+                return -EINVAL;
+
+        d = opendir(p);
+        if (!d)
+                return -errno;
+
+        m = hashmap_get(j->directories_by_path, p);
+        if (!m) {
+                m = new0(Directory, 1);
+                if (!m) {
+                        closedir(d);
+                        return -ENOMEM;
+                }
+
+                m->is_root = true;
+                m->path = strdup(p);
+                if (!m->path) {
+                        closedir(d);
+                        free(m);
+                        return -ENOMEM;
+                }
+
+                if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
+                        closedir(d);
+                        free(m->path);
+                        free(m);
+                        return -ENOMEM;
+                }
+
+                j->current_invalidate_counter ++;
+
+                log_debug("Root directory %s got added.", m->path);
+
+        } else if (!m->is_root) {
+                closedir(d);
+                return 0;
+        }
+
+        if (m->wd <= 0 && j->inotify_fd >= 0) {
+
+                m->wd = inotify_add_watch(j->inotify_fd, m->path,
+                                          IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
+                                          IN_ONLYDIR);
+
+                if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0)
+                        inotify_rm_watch(j->inotify_fd, m->wd);
+        }
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                sd_id128_t id;
+
+                r = readdir_r(d, &buf.de, &de);
+                if (r != 0 || !de)
+                        break;
+
+                if (dirent_is_file_with_suffix(de, ".journal") ||
+                    dirent_is_file_with_suffix(de, ".journal~")) {
+                        r = add_file(j, m->path, de->d_name);
+                        if (r < 0)
+                                log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r));
+
+                } else if ((de->d_type == DT_DIR || de->d_type == DT_LNK || de->d_type == DT_UNKNOWN) &&
+                           sd_id128_from_string(de->d_name, &id) >= 0) {
+
+                        r = add_directory(j, m->path, de->d_name);
+                        if (r < 0)
+                                log_debug("Failed to add directory %s/%s: %s", m->path, de->d_name, strerror(-r));
+                }
+        }
+
+        check_network(j, dirfd(d));
+
+        closedir(d);
+
+        return 0;
+}
+
+static int remove_directory(sd_journal *j, Directory *d) {
+        assert(j);
+
+        if (d->wd > 0) {
+                hashmap_remove(j->directories_by_wd, INT_TO_PTR(d->wd));
+
+                if (j->inotify_fd >= 0)
+                        inotify_rm_watch(j->inotify_fd, d->wd);
+        }
+
+        hashmap_remove(j->directories_by_path, d->path);
+
+        if (d->is_root)
+                log_debug("Root directory %s got removed.", d->path);
+        else
+                log_debug("Directory %s got removed.", d->path);
+
+        free(d->path);
+        free(d);
+
+        return 0;
+}
+
+static int add_search_paths(sd_journal *j) {
+
+        const char search_paths[] =
+                "/run/log/journal\0"
+                "/var/log/journal\0";
+        const char *p;
+
+        assert(j);
+
+        /* We ignore most errors here, since the idea is to only open
+         * what's actually accessible, and ignore the rest. */
+
+        NULSTR_FOREACH(p, search_paths)
+                add_root_directory(j, p);
+
+        return 0;
+}
+
+static int allocate_inotify(sd_journal *j) {
+        assert(j);
+
+        if (j->inotify_fd < 0) {
+                j->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
+                if (j->inotify_fd < 0)
+                        return -errno;
+        }
+
+        if (!j->directories_by_wd) {
+                j->directories_by_wd = hashmap_new(trivial_hash_func, trivial_compare_func);
+                if (!j->directories_by_wd)
+                        return -ENOMEM;
+        }
+
+        return 0;
+}
+
+static sd_journal *journal_new(int flags, const char *path) {
+        sd_journal *j;
+
+        j = new0(sd_journal, 1);
+        if (!j)
+                return NULL;
+
+        j->inotify_fd = -1;
+        j->flags = flags;
+        j->data_threshold = DEFAULT_DATA_THRESHOLD;
+
+        if (path) {
+                j->path = strdup(path);
+                if (!j->path) {
+                        free(j);
+                        return NULL;
+                }
+        }
+
+        j->files = hashmap_new(string_hash_func, string_compare_func);
+        if (!j->files) {
+                free(j->path);
+                free(j);
+                return NULL;
+        }
+
+        j->directories_by_path = hashmap_new(string_hash_func, string_compare_func);
+        if (!j->directories_by_path) {
+                hashmap_free(j->files);
+                free(j->path);
+                free(j);
+                return NULL;
+        }
+
+        j->mmap = mmap_cache_new();
+        if (!j->mmap) {
+                hashmap_free(j->files);
+                hashmap_free(j->directories_by_path);
+                free(j->path);
+                free(j);
+                return NULL;
+        }
+
+        return j;
+}
+
+_public_ int sd_journal_open(sd_journal **ret, int flags) {
+        sd_journal *j;
+        int r;
+
+        if (!ret)
+                return -EINVAL;
+
+        if (flags & ~(SD_JOURNAL_LOCAL_ONLY|
+                      SD_JOURNAL_RUNTIME_ONLY|
+                      SD_JOURNAL_SYSTEM_ONLY))
+                return -EINVAL;
+
+        j = journal_new(flags, NULL);
+        if (!j)
+                return -ENOMEM;
+
+        r = add_search_paths(j);
+        if (r < 0)
+                goto fail;
+
+        *ret = j;
+        return 0;
+
+fail:
+        sd_journal_close(j);
+
+        return r;
+}
+
+_public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int flags) {
+        sd_journal *j;
+        int r;
+
+        if (!ret)
+                return -EINVAL;
+
+        if (!path || !path_is_absolute(path))
+                return -EINVAL;
+
+        if (flags != 0)
+                return -EINVAL;
+
+        j = journal_new(flags, path);
+        if (!j)
+                return -ENOMEM;
+
+        r = add_root_directory(j, path);
+        if (r < 0)
+                goto fail;
+
+        *ret = j;
+        return 0;
+
+fail:
+        sd_journal_close(j);
+
+        return r;
+}
+
+_public_ void sd_journal_close(sd_journal *j) {
+        Directory *d;
+        JournalFile *f;
+
+        if (!j)
+                return;
+
+        while ((f = hashmap_steal_first(j->files)))
+                journal_file_close(f);
+
+        hashmap_free(j->files);
+
+        while ((d = hashmap_first(j->directories_by_path)))
+                remove_directory(j, d);
+
+        while ((d = hashmap_first(j->directories_by_wd)))
+                remove_directory(j, d);
+
+        hashmap_free(j->directories_by_path);
+        hashmap_free(j->directories_by_wd);
+
+        if (j->inotify_fd >= 0)
+                close_nointr_nofail(j->inotify_fd);
+
+        sd_journal_flush_matches(j);
+
+        if (j->mmap)
+                mmap_cache_unref(j->mmap);
+
+        free(j->path);
+        free(j->unique_field);
+        free(j);
+}
+
+_public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) {
+        Object *o;
+        JournalFile *f;
+        int r;
+
+        if (!j)
+                return -EINVAL;
+        if (!ret)
+                return -EINVAL;
+
+        f = j->current_file;
+        if (!f)
+                return -EADDRNOTAVAIL;
+
+        if (f->current_offset <= 0)
+                return -EADDRNOTAVAIL;
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+        if (r < 0)
+                return r;
+
+        *ret = le64toh(o->entry.realtime);
+        return 0;
+}
+
+_public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id) {
+        Object *o;
+        JournalFile *f;
+        int r;
+        sd_id128_t id;
+
+        if (!j)
+                return -EINVAL;
+
+        f = j->current_file;
+        if (!f)
+                return -EADDRNOTAVAIL;
+
+        if (f->current_offset <= 0)
+                return -EADDRNOTAVAIL;
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+        if (r < 0)
+                return r;
+
+        if (ret_boot_id)
+                *ret_boot_id = o->entry.boot_id;
+        else {
+                r = sd_id128_get_boot(&id);
+                if (r < 0)
+                        return r;
+
+                if (!sd_id128_equal(id, o->entry.boot_id))
+                        return -ESTALE;
+        }
+
+        if (ret)
+                *ret = le64toh(o->entry.monotonic);
+
+        return 0;
+}
+
+static bool field_is_valid(const char *field) {
+        const char *p;
+
+        assert(field);
+
+        if (isempty(field))
+                return false;
+
+        if (startswith(field, "__"))
+                return false;
+
+        for (p = field; *p; p++) {
+
+                if (*p == '_')
+                        continue;
+
+                if (*p >= 'A' && *p <= 'Z')
+                        continue;
+
+                if (*p >= '0' && *p <= '9')
+                        continue;
+
+                return false;
+        }
+
+        return true;
+}
+
+_public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) {
+        JournalFile *f;
+        uint64_t i, n;
+        size_t field_length;
+        int r;
+        Object *o;
+
+        if (!j)
+                return -EINVAL;
+        if (!field)
+                return -EINVAL;
+        if (!data)
+                return -EINVAL;
+        if (!size)
+                return -EINVAL;
+
+        if (!field_is_valid(field))
+                return -EINVAL;
+
+        f = j->current_file;
+        if (!f)
+                return -EADDRNOTAVAIL;
+
+        if (f->current_offset <= 0)
+                return -EADDRNOTAVAIL;
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+        if (r < 0)
+                return r;
+
+        field_length = strlen(field);
+
+        n = journal_file_entry_n_items(o);
+        for (i = 0; i < n; i++) {
+                uint64_t p, l;
+                le64_t le_hash;
+                size_t t;
+
+                p = le64toh(o->entry.items[i].object_offset);
+                le_hash = o->entry.items[i].hash;
+                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+                if (r < 0)
+                        return r;
+
+                if (le_hash != o->data.hash)
+                        return -EBADMSG;
+
+                l = le64toh(o->object.size) - offsetof(Object, data.payload);
+
+                if (o->object.flags & OBJECT_COMPRESSED) {
+
+#ifdef HAVE_XZ
+                        if (uncompress_startswith(o->data.payload, l,
+                                                  &f->compress_buffer, &f->compress_buffer_size,
+                                                  field, field_length, '=')) {
+
+                                uint64_t rsize;
+
+                                if (!uncompress_blob(o->data.payload, l,
+                                                     &f->compress_buffer, &f->compress_buffer_size, &rsize,
+                                                     j->data_threshold))
+                                        return -EBADMSG;
+
+                                *data = f->compress_buffer;
+                                *size = (size_t) rsize;
+
+                                return 0;
+                        }
+#else
+                        return -EPROTONOSUPPORT;
+#endif
+
+                } else if (l >= field_length+1 &&
+                           memcmp(o->data.payload, field, field_length) == 0 &&
+                           o->data.payload[field_length] == '=') {
+
+                        t = (size_t) l;
+
+                        if ((uint64_t) t != l)
+                                return -E2BIG;
+
+                        *data = o->data.payload;
+                        *size = t;
+
+                        return 1;
+                }
+
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+                if (r < 0)
+                        return r;
+        }
+
+        return -ENOENT;
+}
+
+static int return_data(sd_journal *j, JournalFile *f, Object *o, const void **data, size_t *size) {
+        size_t t;
+        uint64_t l;
+
+        l = le64toh(o->object.size) - offsetof(Object, data.payload);
+        t = (size_t) l;
+
+        /* We can't read objects larger than 4G on a 32bit machine */
+        if ((uint64_t) t != l)
+                return -E2BIG;
+
+        if (o->object.flags & OBJECT_COMPRESSED) {
+#ifdef HAVE_XZ
+                uint64_t rsize;
+
+                if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize, j->data_threshold))
+                        return -EBADMSG;
+
+                *data = f->compress_buffer;
+                *size = (size_t) rsize;
+#else
+                return -EPROTONOSUPPORT;
+#endif
+        } else {
+                *data = o->data.payload;
+                *size = t;
+        }
+
+        return 0;
+}
+
+_public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) {
+        JournalFile *f;
+        uint64_t p, n;
+        le64_t le_hash;
+        int r;
+        Object *o;
+
+        if (!j)
+                return -EINVAL;
+        if (!data)
+                return -EINVAL;
+        if (!size)
+                return -EINVAL;
+
+        f = j->current_file;
+        if (!f)
+                return -EADDRNOTAVAIL;
+
+        if (f->current_offset <= 0)
+                return -EADDRNOTAVAIL;
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+        if (r < 0)
+                return r;
+
+        n = journal_file_entry_n_items(o);
+        if (j->current_field >= n)
+                return 0;
+
+        p = le64toh(o->entry.items[j->current_field].object_offset);
+        le_hash = o->entry.items[j->current_field].hash;
+        r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+        if (r < 0)
+                return r;
+
+        if (le_hash != o->data.hash)
+                return -EBADMSG;
+
+        r = return_data(j, f, o, data, size);
+        if (r < 0)
+                return r;
+
+        j->current_field ++;
+
+        return 1;
+}
+
+_public_ void sd_journal_restart_data(sd_journal *j) {
+        if (!j)
+                return;
+
+        j->current_field = 0;
+}
+
+_public_ int sd_journal_get_fd(sd_journal *j) {
+        int r;
+
+        if (!j)
+                return -EINVAL;
+
+        if (j->inotify_fd >= 0)
+                return j->inotify_fd;
+
+        r = allocate_inotify(j);
+        if (r < 0)
+                return r;
+
+        /* Iterate through all dirs again, to add them to the
+         * inotify */
+        if (j->path)
+                r = add_root_directory(j, j->path);
+        else
+                r = add_search_paths(j);
+        if (r < 0)
+                return r;
+
+        return j->inotify_fd;
+}
+
+static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
+        Directory *d;
+        int r;
+
+        assert(j);
+        assert(e);
+
+        /* Is this a subdirectory we watch? */
+        d = hashmap_get(j->directories_by_wd, INT_TO_PTR(e->wd));
+        if (d) {
+                sd_id128_t id;
+
+                if (!(e->mask & IN_ISDIR) && e->len > 0 &&
+                    (endswith(e->name, ".journal") ||
+                     endswith(e->name, ".journal~"))) {
+
+                        /* Event for a journal file */
+
+                        if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
+                                r = add_file(j, d->path, e->name);
+                                if (r < 0)
+                                        log_debug("Failed to add file %s/%s: %s", d->path, e->name, strerror(-r));
+
+                        } else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) {
+
+                                r = remove_file(j, d->path, e->name);
+                                if (r < 0)
+                                        log_debug("Failed to remove file %s/%s: %s", d->path, e->name, strerror(-r));
+                        }
+
+                } else if (!d->is_root && e->len == 0) {
+
+                        /* Event for a subdirectory */
+
+                        if (e->mask & (IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT)) {
+                                r = remove_directory(j, d);
+                                if (r < 0)
+                                        log_debug("Failed to remove directory %s: %s", d->path, strerror(-r));
+                        }
+
+
+                } else if (d->is_root && (e->mask & IN_ISDIR) && e->len > 0 && sd_id128_from_string(e->name, &id) >= 0) {
+
+                        /* Event for root directory */
+
+                        if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
+                                r = add_directory(j, d->path, e->name);
+                                if (r < 0)
+                                        log_debug("Failed to add directory %s/%s: %s", d->path, e->name, strerror(-r));
+                        }
+                }
+
+                return;
+        }
+
+        if (e->mask & IN_IGNORED)
+                return;
+
+        log_warning("Unknown inotify event.");
+}
+
+static int determine_change(sd_journal *j) {
+        bool b;
+
+        assert(j);
+
+        b = j->current_invalidate_counter != j->last_invalidate_counter;
+        j->last_invalidate_counter = j->current_invalidate_counter;
+
+        return b ? SD_JOURNAL_INVALIDATE : SD_JOURNAL_APPEND;
+}
+
+_public_ int sd_journal_process(sd_journal *j) {
+        uint8_t buffer[sizeof(struct inotify_event) + FILENAME_MAX] _alignas_(struct inotify_event);
+        bool got_something = false;
+
+        if (!j)
+                return -EINVAL;
+
+        for (;;) {
+                struct inotify_event *e;
+                ssize_t l;
+
+                l = read(j->inotify_fd, buffer, sizeof(buffer));
+                if (l < 0) {
+                        if (errno == EAGAIN || errno == EINTR)
+                                return got_something ? determine_change(j) : SD_JOURNAL_NOP;
+
+                        return -errno;
+                }
+
+                got_something = true;
+
+                e = (struct inotify_event*) buffer;
+                while (l > 0) {
+                        size_t step;
+
+                        process_inotify_event(j, e);
+
+                        step = sizeof(struct inotify_event) + e->len;
+                        assert(step <= (size_t) l);
+
+                        e = (struct inotify_event*) ((uint8_t*) e + step);
+                        l -= step;
+                }
+        }
+
+        return determine_change(j);
+}
+
+_public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
+        int r;
+
+        assert(j);
+
+        if (j->inotify_fd < 0) {
+
+                /* This is the first invocation, hence create the
+                 * inotify watch */
+                r = sd_journal_get_fd(j);
+                if (r < 0)
+                        return r;
+
+                /* The journal might have changed since the context
+                 * object was created and we weren't watching before,
+                 * hence don't wait for anything, and return
+                 * immediately. */
+                return determine_change(j);
+        }
+
+        if (j->on_network) {
+                /* If we are on the network we need to regularly check
+                 * for changes manually */
+
+                if (timeout_usec == (uint64_t) -1 || timeout_usec > JOURNAL_FILES_RECHECK_USEC)
+                        timeout_usec = JOURNAL_FILES_RECHECK_USEC;
+        }
+
+        do {
+                r = fd_wait_for_event(j->inotify_fd, POLLIN, timeout_usec);
+        } while (r == -EINTR);
+
+        if (r < 0)
+                return r;
+
+        return sd_journal_process(j);
+}
+
+_public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, uint64_t *to) {
+        Iterator i;
+        JournalFile *f;
+        bool first = true;
+        int r;
+
+        if (!j)
+                return -EINVAL;
+        if (!from && !to)
+                return -EINVAL;
+
+        HASHMAP_FOREACH(f, j->files, i) {
+                usec_t fr, t;
+
+                r = journal_file_get_cutoff_realtime_usec(f, &fr, &t);
+                if (r == -ENOENT)
+                        continue;
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        continue;
+
+                if (first) {
+                        if (from)
+                                *from = fr;
+                        if (to)
+                                *to = t;
+                        first = false;
+                } else {
+                        if (from)
+                                *from = MIN(fr, *from);
+                        if (to)
+                                *to = MAX(t, *to);
+                }
+        }
+
+        return first ? 0 : 1;
+}
+
+_public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) {
+        Iterator i;
+        JournalFile *f;
+        bool first = true;
+        int r;
+
+        if (!j)
+                return -EINVAL;
+        if (!from && !to)
+                return -EINVAL;
+
+        HASHMAP_FOREACH(f, j->files, i) {
+                usec_t fr, t;
+
+                r = journal_file_get_cutoff_monotonic_usec(f, boot_id, &fr, &t);
+                if (r == -ENOENT)
+                        continue;
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        continue;
+
+                if (first) {
+                        if (from)
+                                *from = fr;
+                        if (to)
+                                *to = t;
+                        first = false;
+                } else {
+                        if (from)
+                                *from = MIN(fr, *from);
+                        if (to)
+                                *to = MAX(t, *to);
+                }
+        }
+
+        return first ? 0 : 1;
+}
+
+void journal_print_header(sd_journal *j) {
+        Iterator i;
+        JournalFile *f;
+        bool newline = false;
+
+        assert(j);
+
+        HASHMAP_FOREACH(f, j->files, i) {
+                if (newline)
+                        putchar('\n');
+                else
+                        newline = true;
+
+                journal_file_print_header(f);
+        }
+}
+
+_public_ int sd_journal_get_usage(sd_journal *j, uint64_t *bytes) {
+        Iterator i;
+        JournalFile *f;
+        uint64_t sum = 0;
+
+        if (!j)
+                return -EINVAL;
+        if (!bytes)
+                return -EINVAL;
+
+        HASHMAP_FOREACH(f, j->files, i) {
+                struct stat st;
+
+                if (fstat(f->fd, &st) < 0)
+                        return -errno;
+
+                sum += (uint64_t) st.st_blocks * 512ULL;
+        }
+
+        *bytes = sum;
+        return 0;
+}
+
+_public_ int sd_journal_query_unique(sd_journal *j, const char *field) {
+        char *f;
+
+        if (!j)
+                return -EINVAL;
+        if (isempty(field))
+                return -EINVAL;
+        if (!field_is_valid(field))
+                return -EINVAL;
+
+        f = strdup(field);
+        if (!f)
+                return -ENOMEM;
+
+        free(j->unique_field);
+        j->unique_field = f;
+        j->unique_file = NULL;
+        j->unique_offset = 0;
+
+        return 0;
+}
+
+_public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l) {
+        Object *o;
+        size_t k;
+        int r;
+
+        if (!j)
+                return -EINVAL;
+        if (!data)
+                return -EINVAL;
+        if (!l)
+                return -EINVAL;
+        if (!j->unique_field)
+                return -EINVAL;
+
+        k = strlen(j->unique_field);
+
+        if (!j->unique_file) {
+                j->unique_file = hashmap_first(j->files);
+                if (!j->unique_file)
+                        return 0;
+                j->unique_offset = 0;
+        }
+
+        for (;;) {
+                JournalFile *of;
+                Iterator i;
+                const void *odata;
+                size_t ol;
+                bool found;
+
+                /* Proceed to next data object in the field's linked list */
+                if (j->unique_offset == 0) {
+                        r = journal_file_find_field_object(j->unique_file, j->unique_field, k, &o, NULL);
+                        if (r < 0)
+                                return r;
+
+                        j->unique_offset = r > 0 ? le64toh(o->field.head_data_offset) : 0;
+                } else {
+                        r = journal_file_move_to_object(j->unique_file, OBJECT_DATA, j->unique_offset, &o);
+                        if (r < 0)
+                                return r;
+
+                        j->unique_offset = le64toh(o->data.next_field_offset);
+                }
+
+                /* We reached the end of the list? Then start again, with the next file */
+                if (j->unique_offset == 0) {
+                        JournalFile *n;
+
+                        n = hashmap_next(j->files, j->unique_file->path);
+                        if (!n)
+                                return 0;
+
+                        j->unique_file = n;
+                        continue;
+                }
+
+                /* We do not use the type context here, but 0 instead,
+                 * so that we can look at this data object at the same
+                 * time as one on another file */
+                r = journal_file_move_to_object(j->unique_file, 0, j->unique_offset, &o);
+                if (r < 0)
+                        return r;
+
+                /* Let's do the type check by hand, since we used 0 context above. */
+                if (o->object.type != OBJECT_DATA)
+                        return -EBADMSG;
+
+                r = return_data(j, j->unique_file, o, &odata, &ol);
+                if (r < 0)
+                        return r;
+
+                /* OK, now let's see if we already returned this data
+                 * object by checking if it exists in the earlier
+                 * traversed files. */
+                found = false;
+                HASHMAP_FOREACH(of, j->files, i) {
+                        Object *oo;
+                        uint64_t op;
+
+                        if (of == j->unique_file)
+                                break;
+
+                        /* Skip this file it didn't have any fields
+                         * indexed */
+                        if (JOURNAL_HEADER_CONTAINS(of->header, n_fields) &&
+                            le64toh(of->header->n_fields) <= 0)
+                                continue;
+
+                        r = journal_file_find_data_object_with_hash(of, odata, ol, le64toh(o->data.hash), &oo, &op);
+                        if (r < 0)
+                                return r;
+
+                        if (r > 0)
+                                found = true;
+                }
+
+                if (found)
+                        continue;
+
+                r = return_data(j, j->unique_file, o, data, l);
+                if (r < 0)
+                        return r;
+
+                return 1;
+        }
+}
+
+_public_ void sd_journal_restart_unique(sd_journal *j) {
+        if (!j)
+                return;
+
+        j->unique_file = NULL;
+        j->unique_offset = 0;
+}
+
+_public_ int sd_journal_reliable_fd(sd_journal *j) {
+        if (!j)
+                return -EINVAL;
+
+        return !j->on_network;
+}
+
+static char *lookup_field(const char *field, void *userdata) {
+        sd_journal *j = userdata;
+        const void *data;
+        size_t size, d;
+        int r;
+
+        assert(field);
+        assert(j);
+
+        r = sd_journal_get_data(j, field, &data, &size);
+        if (r < 0 ||
+            size > REPLACE_VAR_MAX)
+                return strdup(field);
+
+        d = strlen(field) + 1;
+
+        return strndup((const char*) data + d, size - d);
+}
+
+_public_ int sd_journal_get_catalog(sd_journal *j, char **ret) {
+        const void *data;
+        size_t size;
+        sd_id128_t id;
+        _cleanup_free_ char *text = NULL, *cid = NULL;
+        char *t;
+        int r;
+
+        if (!j)
+                return -EINVAL;
+        if (!ret)
+                return -EINVAL;
+
+        r = sd_journal_get_data(j, "MESSAGE_ID", &data, &size);
+        if (r < 0)
+                return r;
+
+        cid = strndup((const char*) data + 11, size - 11);
+        if (!cid)
+                return -ENOMEM;
+
+        r = sd_id128_from_string(cid, &id);
+        if (r < 0)
+                return r;
+
+        r = catalog_get(id, &text);
+        if (r < 0)
+                return r;
+
+        t = replace_var(text, lookup_field, j);
+        if (!t)
+                return -ENOMEM;
+
+        *ret = t;
+        return 0;
+}
+
+_public_ int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret) {
+        if (!ret)
+                return -EINVAL;
+
+        return catalog_get(id, ret);
+}
+
+_public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) {
+        if (!j)
+                return -EINVAL;
+
+        j->data_threshold = sz;
+        return 0;
+}
+
+_public_ int sd_journal_get_data_threshold(sd_journal *j, size_t *sz) {
+        if (!j)
+                return -EINVAL;
+        if (!sz)
+                return -EINVAL;
+
+        *sz = j->data_threshold;
+        return 0;
+}
diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c
new file mode 100644 (file)
index 0000000..cec8a11
--- /dev/null
@@ -0,0 +1,48 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <locale.h>
+
+#include "util.h"
+#include "log.h"
+#include "catalog.h"
+#include "sd-messages.h"
+
+int main(int argc, char *argv[]) {
+
+        _cleanup_free_ char *text = NULL;
+
+        setlocale(LC_ALL, "de_DE.UTF-8");
+
+        log_set_max_level(LOG_DEBUG);
+
+        assert_se(catalog_update() >= 0);
+
+        assert_se(catalog_list(stdout) >= 0);
+
+        assert_se(catalog_get(SD_MESSAGE_COREDUMP, &text) >= 0);
+
+        printf(">>>%s<<<\n", text);
+
+        fflush(stdout);
+
+        return 0;
+}
diff --git a/src/journal/test-journal-enum.c b/src/journal/test-journal-enum.c
new file mode 100644 (file)
index 0000000..8a843ec
--- /dev/null
@@ -0,0 +1,53 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+
+#include "log.h"
+#include "sd-journal.h"
+
+int main(int argc, char *argv[]) {
+        unsigned n = 0;
+        sd_journal *j;
+
+        log_set_max_level(LOG_DEBUG);
+
+        assert_se(sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY) >= 0);
+
+        assert_se(sd_journal_add_match(j, "_TRANSPORT=syslog", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "_UID=0", 0) >= 0);
+
+        SD_JOURNAL_FOREACH_BACKWARDS(j) {
+                const void *d;
+                size_t l;
+
+                assert_se(sd_journal_get_data(j, "MESSAGE", &d, &l) >= 0);
+
+                printf("%.*s\n", (int) l, (char*) d);
+
+                n ++;
+                if (n >= 10)
+                        break;
+        }
+
+        sd_journal_close(j);
+        return 0;
+}
diff --git a/src/journal/test-journal-match.c b/src/journal/test-journal-match.c
new file mode 100644 (file)
index 0000000..fa22814
--- /dev/null
@@ -0,0 +1,67 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+
+#include <systemd/sd-journal.h>
+
+#include "journal-internal.h"
+#include "util.h"
+#include "log.h"
+
+int main(int argc, char *argv[]) {
+        sd_journal *j;
+        char *t;
+
+        log_set_max_level(LOG_DEBUG);
+
+        assert_se(sd_journal_open(&j, 0) >= 0);
+
+        assert_se(sd_journal_add_match(j, "foobar", 0) < 0);
+        assert_se(sd_journal_add_match(j, "foobar=waldo", 0) < 0);
+        assert_se(sd_journal_add_match(j, "", 0) < 0);
+        assert_se(sd_journal_add_match(j, "=", 0) < 0);
+        assert_se(sd_journal_add_match(j, "=xxxxx", 0) < 0);
+        assert_se(sd_journal_add_match(j, "HALLO=WALDO", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "QUUX=mmmm", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "HALLO=", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "QUUX=yyyyy", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "PIFF=paff", 0) >= 0);
+
+        assert_se(sd_journal_add_disjunction(j) >= 0);
+
+        assert_se(sd_journal_add_match(j, "ONE=one", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "ONE=two", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "TWO=two", 0) >= 0);
+
+        assert_se(t = journal_make_match_string(j));
+
+        assert_se(streq(t, "((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO)))"));
+
+        printf("resulting match expression is: %s\n", t);
+        free(t);
+
+        sd_journal_close(j);
+
+        return 0;
+}
diff --git a/src/journal/test-journal-send.c b/src/journal/test-journal-send.c
new file mode 100644 (file)
index 0000000..3e986ed
--- /dev/null
@@ -0,0 +1,78 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <systemd/sd-journal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "log.h"
+
+int main(int argc, char *argv[]) {
+        char huge[4096*1024];
+
+        log_set_max_level(LOG_DEBUG);
+
+        sd_journal_print(LOG_INFO, "piepapo");
+
+        sd_journal_send("MESSAGE=foobar",
+                        "VALUE=%i", 7,
+                        NULL);
+
+        errno = ENOENT;
+        sd_journal_perror("Foobar");
+
+        sd_journal_perror("");
+
+        memset(huge, 'x', sizeof(huge));
+        memcpy(huge, "HUGE=", 5);
+        char_array_0(huge);
+
+        sd_journal_send("MESSAGE=Huge field attached",
+                        huge,
+                        NULL);
+
+        sd_journal_send("MESSAGE=uiui",
+                        "VALUE=A",
+                        "VALUE=B",
+                        "VALUE=C",
+                        "SINGLETON=1",
+                        "OTHERVALUE=X",
+                        "OTHERVALUE=Y",
+                        "WITH_BINARY=this is a binary value \a",
+                        NULL);
+
+        syslog(LOG_NOTICE, "Hello World!");
+
+        sd_journal_print(LOG_NOTICE, "Hello World");
+
+        sd_journal_send("MESSAGE=Hello World!",
+                        "MESSAGE_ID=52fb62f99e2c49d89cfbf9d6de5e3555",
+                        "PRIORITY=5",
+                        "HOME=%s", getenv("HOME"),
+                        "TERM=%s", getenv("TERM"),
+                        "PAGE_SIZE=%li", sysconf(_SC_PAGESIZE),
+                        "N_CPUS=%li", sysconf(_SC_NPROCESSORS_ONLN),
+                        NULL);
+
+        sleep(10);
+
+        return 0;
+}
diff --git a/src/journal/test-journal-stream.c b/src/journal/test-journal-stream.c
new file mode 100644 (file)
index 0000000..b3e816d
--- /dev/null
@@ -0,0 +1,185 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <systemd/sd-journal.h>
+
+#include "journal-file.h"
+#include "journal-internal.h"
+#include "util.h"
+#include "log.h"
+
+#define N_ENTRIES 200
+
+static void verify_contents(sd_journal *j, unsigned skip) {
+        unsigned i;
+
+        assert(j);
+
+        i = 0;
+        SD_JOURNAL_FOREACH(j) {
+                const void *d;
+                char *k, *c;
+                size_t l;
+                unsigned u;
+
+                assert_se(sd_journal_get_cursor(j, &k) >= 0);
+                printf("cursor: %s\n", k);
+                free(k);
+
+                assert_se(sd_journal_get_data(j, "MAGIC", &d, &l) >= 0);
+                printf("\t%.*s\n", (int) l, (const char*) d);
+
+                assert_se(sd_journal_get_data(j, "NUMBER", &d, &l) >= 0);
+                assert_se(k = strndup(d, l));
+                printf("\t%s\n", k);
+
+                if (skip > 0) {
+                        assert_se(safe_atou(k + 7, &u) >= 0);
+                        assert_se(i == u);
+                        i += skip;
+                }
+
+                free(k);
+
+                assert_se(sd_journal_get_cursor(j, &c) >= 0);
+                assert_se(sd_journal_test_cursor(j, c) > 0);
+                free(c);
+        }
+
+        if (skip > 0)
+                assert_se(i == N_ENTRIES);
+}
+
+int main(int argc, char *argv[]) {
+        JournalFile *one, *two, *three;
+        char t[] = "/tmp/journal-stream-XXXXXX";
+        unsigned i;
+        sd_journal *j;
+        char *z;
+        const void *data;
+        size_t l;
+
+        log_set_max_level(LOG_DEBUG);
+
+        assert_se(mkdtemp(t));
+        assert_se(chdir(t) >= 0);
+
+        assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &one) == 0);
+        assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &two) == 0);
+        assert_se(journal_file_open("three.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &three) == 0);
+
+        for (i = 0; i < N_ENTRIES; i++) {
+                char *p, *q;
+                dual_timestamp ts;
+                struct iovec iovec[2];
+
+                dual_timestamp_get(&ts);
+
+                assert_se(asprintf(&p, "NUMBER=%u", i) >= 0);
+                iovec[0].iov_base = p;
+                iovec[0].iov_len = strlen(p);
+
+                assert_se(asprintf(&q, "MAGIC=%s", i % 5 == 0 ? "quux" : "waldo") >= 0);
+
+                iovec[1].iov_base = q;
+                iovec[1].iov_len = strlen(q);
+
+                if (i % 10 == 0)
+                        assert_se(journal_file_append_entry(three, &ts, iovec, 2, NULL, NULL, NULL) == 0);
+                else {
+                        if (i % 3 == 0)
+                                assert_se(journal_file_append_entry(two, &ts, iovec, 2, NULL, NULL, NULL) == 0);
+
+                        assert_se(journal_file_append_entry(one, &ts, iovec, 2, NULL, NULL, NULL) == 0);
+                }
+
+                free(p);
+                free(q);
+        }
+
+        journal_file_close(one);
+        journal_file_close(two);
+        journal_file_close(three);
+
+        assert_se(sd_journal_open_directory(&j, t, 0) >= 0);
+
+        assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0);
+        SD_JOURNAL_FOREACH_BACKWARDS(j) {
+                char *c;
+
+                assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0);
+                printf("\t%.*s\n", (int) l, (const char*) data);
+
+                assert_se(sd_journal_get_cursor(j, &c) >= 0);
+                assert_se(sd_journal_test_cursor(j, c) > 0);
+                free(c);
+        }
+
+        SD_JOURNAL_FOREACH(j) {
+                char *c;
+
+                assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0);
+                printf("\t%.*s\n", (int) l, (const char*) data);
+
+                assert_se(sd_journal_get_cursor(j, &c) >= 0);
+                assert_se(sd_journal_test_cursor(j, c) > 0);
+                free(c);
+        }
+
+        sd_journal_flush_matches(j);
+
+        verify_contents(j, 1);
+
+        printf("NEXT TEST\n");
+        assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0);
+
+        assert_se(z = journal_make_match_string(j));
+        printf("resulting match expression is: %s\n", z);
+        free(z);
+
+        verify_contents(j, 5);
+
+        printf("NEXT TEST\n");
+        sd_journal_flush_matches(j);
+        assert_se(sd_journal_add_match(j, "MAGIC=waldo", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "NUMBER=10", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "NUMBER=11", 0) >= 0);
+        assert_se(sd_journal_add_match(j, "NUMBER=12", 0) >= 0);
+
+        assert_se(z = journal_make_match_string(j));
+        printf("resulting match expression is: %s\n", z);
+        free(z);
+
+        verify_contents(j, 0);
+
+        assert_se(sd_journal_query_unique(j, "NUMBER") >= 0);
+        SD_JOURNAL_FOREACH_UNIQUE(j, data, l)
+                printf("%.*s\n", (int) l, (const char*) data);
+
+        sd_journal_close(j);
+
+        assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
+
+        return 0;
+}
diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
new file mode 100644 (file)
index 0000000..3ae8633
--- /dev/null
@@ -0,0 +1,44 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journald-syslog.h"
+#include "macro.h"
+
+static void test_syslog_parse_identifier(const char* str,
+                                         const char *ident, const char*pid, int ret) {
+        const char *buf = str;
+        char *ident2 = NULL, *pid2 = NULL;
+        int ret2;
+
+        ret2 = syslog_parse_identifier(&buf, &ident2, &pid2);
+
+        assert(ret == ret2);
+        assert(ident==ident2 || !strcmp(ident, ident2));
+        assert(pid==pid2 || !strcmp(pid, pid2));
+}
+
+int main(void) {
+        test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11);
+        test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6);
+        test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0);
+
+        return 0;
+}
diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c
new file mode 100644 (file)
index 0000000..b667721
--- /dev/null
@@ -0,0 +1,147 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "util.h"
+#include "log.h"
+#include "journal-file.h"
+#include "journal-verify.h"
+#include "journal-authenticate.h"
+
+#define N_ENTRIES 6000
+#define RANDOM_RANGE 77
+
+static void bit_toggle(const char *fn, uint64_t p) {
+        uint8_t b;
+        ssize_t r;
+        int fd;
+
+        fd = open(fn, O_RDWR|O_CLOEXEC);
+        assert(fd >= 0);
+
+        r = pread(fd, &b, 1, p/8);
+        assert(r == 1);
+
+        b ^= 1 << (p % 8);
+
+        r = pwrite(fd, &b, 1, p/8);
+        assert(r == 1);
+
+        close_nointr_nofail(fd);
+}
+
+static int raw_verify(const char *fn, const char *verification_key) {
+        JournalFile *f;
+        int r;
+
+        r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
+        if (r < 0)
+                return r;
+
+        r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
+        journal_file_close(f);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        char t[] = "/tmp/journal-XXXXXX";
+        unsigned n;
+        JournalFile *f;
+        const char *verification_key = argv[1];
+        usec_t from = 0, to = 0, total = 0;
+        char a[FORMAT_TIMESTAMP_MAX];
+        char b[FORMAT_TIMESTAMP_MAX];
+        char c[FORMAT_TIMESPAN_MAX];
+        struct stat st;
+        uint64_t p;
+
+        log_set_max_level(LOG_DEBUG);
+
+        assert_se(mkdtemp(t));
+        assert_se(chdir(t) >= 0);
+
+        log_info("Generating...");
+
+        assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
+
+        for (n = 0; n < N_ENTRIES; n++) {
+                struct iovec iovec;
+                struct dual_timestamp ts;
+                char *test;
+
+                dual_timestamp_get(&ts);
+
+                assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE));
+
+                iovec.iov_base = (void*) test;
+                iovec.iov_len = strlen(test);
+
+                assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
+
+                free(test);
+        }
+
+        journal_file_close(f);
+
+        log_info("Verifying...");
+
+        assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
+        /* journal_file_print_header(f); */
+        journal_file_dump(f);
+
+        assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
+
+        if (verification_key && JOURNAL_HEADER_SEALED(f->header)) {
+                log_info("=> Validated from %s to %s, %s missing",
+                         format_timestamp(a, sizeof(a), from),
+                         format_timestamp(b, sizeof(b), to),
+                         format_timespan(c, sizeof(c), total > to ? total - to : 0));
+        }
+
+        journal_file_close(f);
+
+        if (verification_key) {
+                log_info("Toggling bits...");
+
+                assert_se(stat("test.journal", &st) >= 0);
+
+                for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) {
+                        bit_toggle("test.journal", p);
+
+                        log_info("[ %llu+%llu]", (unsigned long long) p / 8, (unsigned long long) p % 8);
+
+                        if (raw_verify("test.journal", verification_key) >= 0)
+                                log_notice(ANSI_HIGHLIGHT_RED_ON ">>>> %llu (bit %llu) can be toggled without detection." ANSI_HIGHLIGHT_OFF, (unsigned long long) p / 8, (unsigned long long) p % 8);
+
+                        bit_toggle("test.journal", p);
+                }
+        }
+
+        log_info("Exiting...");
+
+        assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
+
+        return 0;
+}
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
new file mode 100644 (file)
index 0000000..f4dc52c
--- /dev/null
@@ -0,0 +1,129 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <systemd/sd-journal.h>
+
+#include "log.h"
+#include "journal-file.h"
+#include "journal-authenticate.h"
+#include "journal-vacuum.h"
+
+int main(int argc, char *argv[]) {
+        dual_timestamp ts;
+        JournalFile *f;
+        struct iovec iovec;
+        static const char test[] = "TEST1=1", test2[] = "TEST2=2";
+        Object *o;
+        uint64_t p;
+        char t[] = "/tmp/journal-XXXXXX";
+
+        log_set_max_level(LOG_DEBUG);
+
+        assert_se(mkdtemp(t));
+        assert_se(chdir(t) >= 0);
+
+        assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, &f) == 0);
+
+        dual_timestamp_get(&ts);
+
+        iovec.iov_base = (void*) test;
+        iovec.iov_len = strlen(test);
+        assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
+
+        iovec.iov_base = (void*) test2;
+        iovec.iov_len = strlen(test2);
+        assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
+
+        iovec.iov_base = (void*) test;
+        iovec.iov_len = strlen(test);
+        assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
+
+#ifdef HAVE_GCRYPT
+        journal_file_append_tag(f);
+#endif
+        journal_file_dump(f);
+
+        assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
+        assert(le64toh(o->entry.seqnum) == 1);
+
+        assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1);
+        assert(le64toh(o->entry.seqnum) == 2);
+
+        assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1);
+        assert(le64toh(o->entry.seqnum) == 3);
+
+        assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 0);
+
+        assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
+        assert(le64toh(o->entry.seqnum) == 1);
+
+        assert(journal_file_skip_entry(f, o, p, 2, &o, &p) == 1);
+        assert(le64toh(o->entry.seqnum) == 3);
+
+        assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1);
+        assert(le64toh(o->entry.seqnum) == 1);
+
+        assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1);
+        assert(le64toh(o->entry.seqnum) == 1);
+
+        assert(journal_file_find_data_object(f, test, strlen(test), NULL, &p) == 1);
+        assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
+        assert(le64toh(o->entry.seqnum) == 1);
+
+        assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1);
+        assert(le64toh(o->entry.seqnum) == 3);
+
+        assert(journal_file_find_data_object(f, test2, strlen(test2), NULL, &p) == 1);
+        assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1);
+        assert(le64toh(o->entry.seqnum) == 2);
+
+        assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
+        assert(le64toh(o->entry.seqnum) == 2);
+
+        assert(journal_file_find_data_object(f, "quux", 4, NULL, &p) == 0);
+
+        assert(journal_file_move_to_entry_by_seqnum(f, 1, DIRECTION_DOWN, &o, NULL) == 1);
+        assert(le64toh(o->entry.seqnum) == 1);
+
+        assert(journal_file_move_to_entry_by_seqnum(f, 3, DIRECTION_DOWN, &o, NULL) == 1);
+        assert(le64toh(o->entry.seqnum) == 3);
+
+        assert(journal_file_move_to_entry_by_seqnum(f, 2, DIRECTION_DOWN, &o, NULL) == 1);
+        assert(le64toh(o->entry.seqnum) == 2);
+
+        assert(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0);
+
+        journal_file_rotate(&f, true, true);
+        journal_file_rotate(&f, true, true);
+
+        journal_file_close(f);
+
+        journal_directory_vacuum(".", 3000000, 0, 0, NULL);
+
+        log_error("Exiting...");
+
+        assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
+
+        return 0;
+}
diff --git a/src/journal/test-mmap-cache.c b/src/journal/test-mmap-cache.c
new file mode 100644 (file)
index 0000000..e2ffaf4
--- /dev/null
@@ -0,0 +1,79 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+#include "mmap-cache.h"
+
+int main(int argc, char *argv[]) {
+        int x, y, z, r;
+        char px[] = "/tmp/testmmapXXXXXXX", py[] = "/tmp/testmmapYXXXXXX", pz[] = "/tmp/testmmapZXXXXXX";
+        MMapCache *m;
+        void *p, *q;
+
+        assert_se(m = mmap_cache_new());
+
+        x = mkstemp(px);
+        assert(x >= 0);
+        unlink(px);
+
+        y = mkstemp(py);
+        assert(y >= 0);
+        unlink(py);
+
+        z = mkstemp(pz);
+        assert(z >= 0);
+        unlink(pz);
+
+        r = mmap_cache_get(m, x, PROT_READ, 0, false, 1, 2, NULL, &p);
+        assert(r >= 0);
+
+        r = mmap_cache_get(m, x, PROT_READ, 0, false, 2, 2, NULL, &q);
+        assert(r >= 0);
+
+        assert((uint8_t*) p + 1 == (uint8_t*) q);
+
+        r = mmap_cache_get(m, x, PROT_READ, 1, false, 3, 2, NULL, &q);
+        assert(r >= 0);
+
+        assert((uint8_t*) p + 2 == (uint8_t*) q);
+
+        r = mmap_cache_get(m, x, PROT_READ, 0, false, 16ULL*1024ULL*1024ULL, 2, NULL, &p);
+        assert(r >= 0);
+
+        r = mmap_cache_get(m, x, PROT_READ, 1, false, 16ULL*1024ULL*1024ULL+1, 2, NULL, &q);
+        assert(r >= 0);
+
+        assert((uint8_t*) p + 1 == (uint8_t*) q);
+
+        mmap_cache_unref(m);
+
+        close_nointr_nofail(x);
+        close_nointr_nofail(y);
+        close_nointr_nofail(z);
+
+        return 0;
+}
diff --git a/src/libsystemd-daemon/.gitignore b/src/libsystemd-daemon/.gitignore
new file mode 100644 (file)
index 0000000..5184131
--- /dev/null
@@ -0,0 +1 @@
+/libsystemd-daemon.pc
diff --git a/src/libsystemd-daemon/Makefile b/src/libsystemd-daemon/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/libsystemd-daemon/libsystemd-daemon.pc.in b/src/libsystemd-daemon/libsystemd-daemon.pc.in
new file mode 100644 (file)
index 0000000..8bb3a74
--- /dev/null
@@ -0,0 +1,19 @@
+#  Permission is hereby granted, free of charge, to any person
+#  obtaining a copy of this software and associated documentation files
+#  (the "Software"), to deal in the Software without restriction,
+#  including without limitation the rights to use, copy, modify, merge,
+#  publish, distribute, sublicense, and/or sell copies of the Software,
+#  and to permit persons to whom the Software is furnished to do so,
+#  subject to the following conditions:
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: systemd
+Description: systemd Daemon Utility Library
+URL: @PACKAGE_URL@
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lsystemd-daemon
+Cflags: -I${includedir}
diff --git a/src/libsystemd-daemon/libsystemd-daemon.sym b/src/libsystemd-daemon/libsystemd-daemon.sym
new file mode 100644 (file)
index 0000000..f440238
--- /dev/null
@@ -0,0 +1,27 @@
+/***
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+***/
+
+/* Original symbols from systemd v31 */
+
+LIBSYSTEMD_DAEMON_31 {
+global:
+        sd_booted;
+        sd_is_fifo;
+        sd_is_mq;
+        sd_is_socket;
+        sd_is_socket_inet;
+        sd_is_socket_unix;
+        sd_is_special;
+        sd_listen_fds;
+        sd_notify;
+        sd_notifyf;
+local:
+        *;
+};
diff --git a/src/libsystemd-daemon/sd-daemon.c b/src/libsystemd-daemon/sd-daemon.c
new file mode 100644 (file)
index 0000000..80aadf7
--- /dev/null
@@ -0,0 +1,536 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  Copyright 2010 Lennart Poettering
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+***/
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#ifdef __BIONIC__
+#include <linux/fcntl.h>
+#else
+#include <sys/fcntl.h>
+#endif
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <limits.h>
+
+#if defined(__linux__)
+#include <mqueue.h>
+#endif
+
+#include "sd-daemon.h"
+
+#if (__GNUC__ >= 4)
+#ifdef SD_EXPORT_SYMBOLS
+/* Export symbols */
+#define _sd_export_ __attribute__ ((visibility("default")))
+#else
+/* Don't export the symbols */
+#define _sd_export_ __attribute__ ((visibility("hidden")))
+#endif
+#else
+#define _sd_export_
+#endif
+
+_sd_export_ int sd_listen_fds(int unset_environment) {
+
+#if defined(DISABLE_SYSTEMD) || !defined(__linux__)
+        return 0;
+#else
+        int r, fd;
+        const char *e;
+        char *p = NULL;
+        unsigned long l;
+
+        e = getenv("LISTEN_PID");
+        if (!e) {
+                r = 0;
+                goto finish;
+        }
+
+        errno = 0;
+        l = strtoul(e, &p, 10);
+
+        if (errno != 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (!p || p == e || *p || l <= 0) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        /* Is this for us? */
+        if (getpid() != (pid_t) l) {
+                r = 0;
+                goto finish;
+        }
+
+        e = getenv("LISTEN_FDS");
+        if (!e) {
+                r = 0;
+                goto finish;
+        }
+
+        errno = 0;
+        l = strtoul(e, &p, 10);
+
+        if (errno != 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (!p || p == e || *p) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) {
+                int flags;
+
+                flags = fcntl(fd, F_GETFD);
+                if (flags < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (flags & FD_CLOEXEC)
+                        continue;
+
+                if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        r = (int) l;
+
+finish:
+        if (unset_environment) {
+                unsetenv("LISTEN_PID");
+                unsetenv("LISTEN_FDS");
+        }
+
+        return r;
+#endif
+}
+
+_sd_export_ int sd_is_fifo(int fd, const char *path) {
+        struct stat st_fd;
+
+        if (fd < 0)
+                return -EINVAL;
+
+        if (fstat(fd, &st_fd) < 0)
+                return -errno;
+
+        if (!S_ISFIFO(st_fd.st_mode))
+                return 0;
+
+        if (path) {
+                struct stat st_path;
+
+                if (stat(path, &st_path) < 0) {
+
+                        if (errno == ENOENT || errno == ENOTDIR)
+                                return 0;
+
+                        return -errno;
+                }
+
+                return
+                        st_path.st_dev == st_fd.st_dev &&
+                        st_path.st_ino == st_fd.st_ino;
+        }
+
+        return 1;
+}
+
+_sd_export_ int sd_is_special(int fd, const char *path) {
+        struct stat st_fd;
+
+        if (fd < 0)
+                return -EINVAL;
+
+        if (fstat(fd, &st_fd) < 0)
+                return -errno;
+
+        if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode))
+                return 0;
+
+        if (path) {
+                struct stat st_path;
+
+                if (stat(path, &st_path) < 0) {
+
+                        if (errno == ENOENT || errno == ENOTDIR)
+                                return 0;
+
+                        return -errno;
+                }
+
+                if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode))
+                        return
+                                st_path.st_dev == st_fd.st_dev &&
+                                st_path.st_ino == st_fd.st_ino;
+                else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode))
+                        return st_path.st_rdev == st_fd.st_rdev;
+                else
+                        return 0;
+        }
+
+        return 1;
+}
+
+static int sd_is_socket_internal(int fd, int type, int listening) {
+        struct stat st_fd;
+
+        if (fd < 0 || type < 0)
+                return -EINVAL;
+
+        if (fstat(fd, &st_fd) < 0)
+                return -errno;
+
+        if (!S_ISSOCK(st_fd.st_mode))
+                return 0;
+
+        if (type != 0) {
+                int other_type = 0;
+                socklen_t l = sizeof(other_type);
+
+                if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0)
+                        return -errno;
+
+                if (l != sizeof(other_type))
+                        return -EINVAL;
+
+                if (other_type != type)
+                        return 0;
+        }
+
+        if (listening >= 0) {
+                int accepting = 0;
+                socklen_t l = sizeof(accepting);
+
+                if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0)
+                        return -errno;
+
+                if (l != sizeof(accepting))
+                        return -EINVAL;
+
+                if (!accepting != !listening)
+                        return 0;
+        }
+
+        return 1;
+}
+
+union sockaddr_union {
+        struct sockaddr sa;
+        struct sockaddr_in in4;
+        struct sockaddr_in6 in6;
+        struct sockaddr_un un;
+        struct sockaddr_storage storage;
+};
+
+_sd_export_ int sd_is_socket(int fd, int family, int type, int listening) {
+        int r;
+
+        if (family < 0)
+                return -EINVAL;
+
+        r = sd_is_socket_internal(fd, type, listening);
+        if (r <= 0)
+                return r;
+
+        if (family > 0) {
+                union sockaddr_union sockaddr;
+                socklen_t l;
+
+                memset(&sockaddr, 0, sizeof(sockaddr));
+                l = sizeof(sockaddr);
+
+                if (getsockname(fd, &sockaddr.sa, &l) < 0)
+                        return -errno;
+
+                if (l < sizeof(sa_family_t))
+                        return -EINVAL;
+
+                return sockaddr.sa.sa_family == family;
+        }
+
+        return 1;
+}
+
+_sd_export_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
+        union sockaddr_union sockaddr;
+        socklen_t l;
+        int r;
+
+        if (family != 0 && family != AF_INET && family != AF_INET6)
+                return -EINVAL;
+
+        r = sd_is_socket_internal(fd, type, listening);
+        if (r <= 0)
+                return r;
+
+        memset(&sockaddr, 0, sizeof(sockaddr));
+        l = sizeof(sockaddr);
+
+        if (getsockname(fd, &sockaddr.sa, &l) < 0)
+                return -errno;
+
+        if (l < sizeof(sa_family_t))
+                return -EINVAL;
+
+        if (sockaddr.sa.sa_family != AF_INET &&
+            sockaddr.sa.sa_family != AF_INET6)
+                return 0;
+
+        if (family > 0)
+                if (sockaddr.sa.sa_family != family)
+                        return 0;
+
+        if (port > 0) {
+                if (sockaddr.sa.sa_family == AF_INET) {
+                        if (l < sizeof(struct sockaddr_in))
+                                return -EINVAL;
+
+                        return htons(port) == sockaddr.in4.sin_port;
+                } else {
+                        if (l < sizeof(struct sockaddr_in6))
+                                return -EINVAL;
+
+                        return htons(port) == sockaddr.in6.sin6_port;
+                }
+        }
+
+        return 1;
+}
+
+_sd_export_ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
+        union sockaddr_union sockaddr;
+        socklen_t l;
+        int r;
+
+        r = sd_is_socket_internal(fd, type, listening);
+        if (r <= 0)
+                return r;
+
+        memset(&sockaddr, 0, sizeof(sockaddr));
+        l = sizeof(sockaddr);
+
+        if (getsockname(fd, &sockaddr.sa, &l) < 0)
+                return -errno;
+
+        if (l < sizeof(sa_family_t))
+                return -EINVAL;
+
+        if (sockaddr.sa.sa_family != AF_UNIX)
+                return 0;
+
+        if (path) {
+                if (length == 0)
+                        length = strlen(path);
+
+                if (length == 0)
+                        /* Unnamed socket */
+                        return l == offsetof(struct sockaddr_un, sun_path);
+
+                if (path[0])
+                        /* Normal path socket */
+                        return
+                                (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) &&
+                                memcmp(path, sockaddr.un.sun_path, length+1) == 0;
+                else
+                        /* Abstract namespace socket */
+                        return
+                                (l == offsetof(struct sockaddr_un, sun_path) + length) &&
+                                memcmp(path, sockaddr.un.sun_path, length) == 0;
+        }
+
+        return 1;
+}
+
+_sd_export_ int sd_is_mq(int fd, const char *path) {
+#if !defined(__linux__)
+        return 0;
+#else
+        struct mq_attr attr;
+
+        if (fd < 0)
+                return -EINVAL;
+
+        if (mq_getattr(fd, &attr) < 0)
+                return -errno;
+
+        if (path) {
+                char fpath[PATH_MAX];
+                struct stat a, b;
+
+                if (path[0] != '/')
+                        return -EINVAL;
+
+                if (fstat(fd, &a) < 0)
+                        return -errno;
+
+                strncpy(stpcpy(fpath, "/dev/mqueue"), path, sizeof(fpath) - 12);
+                fpath[sizeof(fpath)-1] = 0;
+
+                if (stat(fpath, &b) < 0)
+                        return -errno;
+
+                if (a.st_dev != b.st_dev ||
+                    a.st_ino != b.st_ino)
+                        return 0;
+        }
+
+        return 1;
+#endif
+}
+
+_sd_export_ int sd_notify(int unset_environment, const char *state) {
+#if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC)
+        return 0;
+#else
+        int fd = -1, r;
+        struct msghdr msghdr;
+        struct iovec iovec;
+        union sockaddr_union sockaddr;
+        const char *e;
+
+        if (!state) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        e = getenv("NOTIFY_SOCKET");
+        if (!e)
+                return 0;
+
+        /* Must be an abstract socket, or an absolute path */
+        if ((e[0] != '@' && e[0] != '/') || e[1] == 0) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+        if (fd < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        memset(&sockaddr, 0, sizeof(sockaddr));
+        sockaddr.sa.sa_family = AF_UNIX;
+        strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path));
+
+        if (sockaddr.un.sun_path[0] == '@')
+                sockaddr.un.sun_path[0] = 0;
+
+        memset(&iovec, 0, sizeof(iovec));
+        iovec.iov_base = (char*) state;
+        iovec.iov_len = strlen(state);
+
+        memset(&msghdr, 0, sizeof(msghdr));
+        msghdr.msg_name = &sockaddr;
+        msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
+
+        if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
+                msghdr.msg_namelen = sizeof(struct sockaddr_un);
+
+        msghdr.msg_iov = &iovec;
+        msghdr.msg_iovlen = 1;
+
+        if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        r = 1;
+
+finish:
+        if (unset_environment)
+                unsetenv("NOTIFY_SOCKET");
+
+        if (fd >= 0)
+                close(fd);
+
+        return r;
+#endif
+}
+
+_sd_export_ int sd_notifyf(int unset_environment, const char *format, ...) {
+#if defined(DISABLE_SYSTEMD) || !defined(__linux__)
+        return 0;
+#else
+        va_list ap;
+        char *p = NULL;
+        int r;
+
+        va_start(ap, format);
+        r = vasprintf(&p, format, ap);
+        va_end(ap);
+
+        if (r < 0 || !p)
+                return -ENOMEM;
+
+        r = sd_notify(unset_environment, p);
+        free(p);
+
+        return r;
+#endif
+}
+
+_sd_export_ int sd_booted(void) {
+#if defined(DISABLE_SYSTEMD) || !defined(__linux__)
+        return 0;
+#else
+
+        struct stat a, b;
+
+        /* We simply test whether the systemd cgroup hierarchy is
+         * mounted */
+
+        if (lstat("/sys/fs/cgroup", &a) < 0)
+                return 0;
+
+        if (lstat("/sys/fs/cgroup/systemd", &b) < 0)
+                return 0;
+
+        return a.st_dev != b.st_dev;
+#endif
+}
diff --git a/src/libsystemd-id128/.gitignore b/src/libsystemd-id128/.gitignore
new file mode 100644 (file)
index 0000000..144adf9
--- /dev/null
@@ -0,0 +1 @@
+/libsystemd-id128.pc
diff --git a/src/libsystemd-id128/Makefile b/src/libsystemd-id128/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/libsystemd-id128/libsystemd-id128.pc.in b/src/libsystemd-id128/libsystemd-id128.pc.in
new file mode 100644 (file)
index 0000000..bb65ffd
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: systemd
+Description: systemd 128 Bit ID Utility Library
+URL: @PACKAGE_URL@
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lsystemd-id128
+Cflags: -I${includedir}
diff --git a/src/libsystemd-id128/libsystemd-id128.sym b/src/libsystemd-id128/libsystemd-id128.sym
new file mode 100644 (file)
index 0000000..604c002
--- /dev/null
@@ -0,0 +1,21 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+/* Original symbols from systemd v38 */
+
+LIBSYSTEMD_ID128_38 {
+global:
+        sd_id128_to_string;
+        sd_id128_from_string;
+        sd_id128_randomize;
+        sd_id128_get_machine;
+        sd_id128_get_boot;
+local:
+        *;
+};
diff --git a/src/libsystemd-id128/sd-id128.c b/src/libsystemd-id128/sd-id128.c
new file mode 100644 (file)
index 0000000..4286ae7
--- /dev/null
@@ -0,0 +1,221 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "sd-id128.h"
+
+#include "util.h"
+#include "macro.h"
+
+_public_ char *sd_id128_to_string(sd_id128_t id, char s[33]) {
+        unsigned n;
+
+        if (!s)
+                return NULL;
+
+        for (n = 0; n < 16; n++) {
+                s[n*2] = hexchar(id.bytes[n] >> 4);
+                s[n*2+1] = hexchar(id.bytes[n] & 0xF);
+        }
+
+        s[32] = 0;
+
+        return s;
+}
+
+_public_ int sd_id128_from_string(const char s[33], sd_id128_t *ret) {
+        unsigned n;
+        sd_id128_t t;
+
+        if (!s)
+                return -EINVAL;
+        if (!ret)
+                return -EINVAL;
+
+        for (n = 0; n < 16; n++) {
+                int a, b;
+
+                a = unhexchar(s[n*2]);
+                if (a < 0)
+                        return -EINVAL;
+
+                b = unhexchar(s[n*2+1]);
+                if (b < 0)
+                        return -EINVAL;
+
+                t.bytes[n] = (a << 4) | b;
+        }
+
+        if (s[32] != 0)
+                return -EINVAL;
+
+        *ret = t;
+        return 0;
+}
+
+static sd_id128_t make_v4_uuid(sd_id128_t id) {
+        /* Stolen from generate_random_uuid() of drivers/char/random.c
+         * in the kernel sources */
+
+        /* Set UUID version to 4 --- truly random generation */
+        id.bytes[6] = (id.bytes[6] & 0x0F) | 0x40;
+
+        /* Set the UUID variant to DCE */
+        id.bytes[8] = (id.bytes[8] & 0x3F) | 0x80;
+
+        return id;
+}
+
+_public_ int sd_id128_get_machine(sd_id128_t *ret) {
+        static __thread sd_id128_t saved_machine_id;
+        static __thread bool saved_machine_id_valid = false;
+        int fd;
+        char buf[32];
+        ssize_t k;
+        unsigned j;
+        sd_id128_t t;
+
+        if (!ret)
+                return -EINVAL;
+
+        if (saved_machine_id_valid) {
+                *ret = saved_machine_id;
+                return 0;
+        }
+
+        fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                return -errno;
+
+        k = loop_read(fd, buf, 32, false);
+        close_nointr_nofail(fd);
+
+        if (k < 0)
+                return (int) k;
+
+        if (k < 32)
+                return -EIO;
+
+        for (j = 0; j < 16; j++) {
+                int a, b;
+
+                a = unhexchar(buf[j*2]);
+                b = unhexchar(buf[j*2+1]);
+
+                if (a < 0 || b < 0)
+                        return -EIO;
+
+                t.bytes[j] = a << 4 | b;
+        }
+
+        saved_machine_id = t;
+        saved_machine_id_valid = true;
+
+        *ret = t;
+        return 0;
+}
+
+_public_ int sd_id128_get_boot(sd_id128_t *ret) {
+        static __thread sd_id128_t saved_boot_id;
+        static __thread bool saved_boot_id_valid = false;
+        int fd;
+        char buf[36];
+        ssize_t k;
+        unsigned j;
+        sd_id128_t t;
+        char *p;
+
+        if (!ret)
+                return -EINVAL;
+
+        if (saved_boot_id_valid) {
+                *ret = saved_boot_id;
+                return 0;
+        }
+
+        fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                return -errno;
+
+        k = loop_read(fd, buf, 36, false);
+        close_nointr_nofail(fd);
+
+        if (k < 0)
+                return (int) k;
+
+        if (k < 36)
+                return -EIO;
+
+        for (j = 0, p = buf; j < 16; j++) {
+                int a, b;
+
+                if (*p == '-')
+                        p++;
+
+                a = unhexchar(p[0]);
+                b = unhexchar(p[1]);
+
+                if (a < 0 || b < 0)
+                        return -EIO;
+
+                t.bytes[j] = a << 4 | b;
+
+                p += 2;
+        }
+
+        saved_boot_id = t;
+        saved_boot_id_valid = true;
+
+        *ret = t;
+        return 0;
+}
+
+_public_ int sd_id128_randomize(sd_id128_t *ret) {
+        int fd;
+        ssize_t k;
+        sd_id128_t t;
+
+        if (!ret)
+                return -EINVAL;
+
+        fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                return -errno;
+
+        k = loop_read(fd, &t, 16, false);
+        close_nointr_nofail(fd);
+
+        if (k < 0)
+                return (int) k;
+
+        if (k < 16)
+                return -EIO;
+
+        /* Turn this into a valid v4 UUID, to be nice. Note that we
+         * only guarantee this for newly generated UUIDs, not for
+         * pre-existing ones.*/
+
+        *ret = make_v4_uuid(t);
+        return 0;
+}
diff --git a/src/libudev/.gitignore b/src/libudev/.gitignore
new file mode 100644 (file)
index 0000000..0c8a5d5
--- /dev/null
@@ -0,0 +1 @@
+/libudev.pc
diff --git a/src/libudev/Makefile b/src/libudev/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/libudev/libudev-device-private.c b/src/libudev/libudev-device-private.c
new file mode 100644 (file)
index 0000000..c123057
--- /dev/null
@@ -0,0 +1,192 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+static void udev_device_tag(struct udev_device *dev, const char *tag, bool add)
+{
+        const char *id;
+        char filename[UTIL_PATH_SIZE];
+
+        id = udev_device_get_id_filename(dev);
+        if (id == NULL)
+                return;
+        util_strscpyl(filename, sizeof(filename), "/run/udev/tags/", tag, "/", id, NULL);
+
+        if (add) {
+                int fd;
+
+                mkdir_parents(filename, 0755);
+                fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
+                if (fd >= 0)
+                        close(fd);
+        } else {
+                unlink(filename);
+        }
+}
+
+int udev_device_tag_index(struct udev_device *dev, struct udev_device *dev_old, bool add)
+{
+        struct udev_list_entry *list_entry;
+        bool found;
+
+        if (add && dev_old != NULL) {
+                /* delete possible left-over tags */
+                udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(dev_old)) {
+                        const char *tag_old = udev_list_entry_get_name(list_entry);
+                        struct udev_list_entry *list_entry_current;
+
+                        found = false;
+                        udev_list_entry_foreach(list_entry_current, udev_device_get_tags_list_entry(dev)) {
+                                const char *tag = udev_list_entry_get_name(list_entry_current);
+
+                                if (streq(tag, tag_old)) {
+                                        found = true;
+                                        break;
+                                }
+                        }
+                        if (!found)
+                                udev_device_tag(dev_old, tag_old, false);
+                }
+        }
+
+        udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(dev))
+                udev_device_tag(dev, udev_list_entry_get_name(list_entry), add);
+
+        return 0;
+}
+
+static bool device_has_info(struct udev_device *udev_device)
+{
+        struct udev_list_entry *list_entry;
+
+        if (udev_device_get_devlinks_list_entry(udev_device) != NULL)
+                return true;
+        if (udev_device_get_devlink_priority(udev_device) != 0)
+                return true;
+        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device))
+                if (udev_list_entry_get_num(list_entry))
+                        return true;
+        if (udev_device_get_tags_list_entry(udev_device) != NULL)
+                return true;
+        if (udev_device_get_watch_handle(udev_device) >= 0)
+                return true;
+        return false;
+}
+
+int udev_device_update_db(struct udev_device *udev_device)
+{
+        struct udev *udev = udev_device_get_udev(udev_device);
+        bool has_info;
+        const char *id;
+        char filename[UTIL_PATH_SIZE];
+        char filename_tmp[UTIL_PATH_SIZE];
+        FILE *f;
+        int r;
+
+        id = udev_device_get_id_filename(udev_device);
+        if (id == NULL)
+                return -1;
+
+        has_info = device_has_info(udev_device);
+        util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
+
+        /* do not store anything for otherwise empty devices */
+        if (!has_info &&
+            major(udev_device_get_devnum(udev_device)) == 0 &&
+            udev_device_get_ifindex(udev_device) == 0) {
+                unlink(filename);
+                return 0;
+        }
+
+        /* write a database file */
+        util_strscpyl(filename_tmp, sizeof(filename_tmp), filename, ".tmp", NULL);
+        mkdir_parents(filename_tmp, 0755);
+        f = fopen(filename_tmp, "we");
+        if (f == NULL) {
+                udev_err(udev, "unable to create temporary db file '%s': %m\n", filename_tmp);
+                return -1;
+        }
+
+        /*
+         * set 'sticky' bit to indicate that we should not clean the
+         * database when we transition from initramfs to the real root
+         */
+        if (udev_device_get_db_persist(udev_device))
+                fchmod(fileno(f), 01644);
+
+        if (has_info) {
+                struct udev_list_entry *list_entry;
+
+                if (major(udev_device_get_devnum(udev_device)) > 0) {
+                        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(udev_device))
+                                fprintf(f, "S:%s\n", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+                        if (udev_device_get_devlink_priority(udev_device) != 0)
+                                fprintf(f, "L:%i\n", udev_device_get_devlink_priority(udev_device));
+                        if (udev_device_get_watch_handle(udev_device) >= 0)
+                                fprintf(f, "W:%i\n", udev_device_get_watch_handle(udev_device));
+                }
+
+                if (udev_device_get_usec_initialized(udev_device) > 0)
+                        fprintf(f, "I:%llu\n", (unsigned long long)udev_device_get_usec_initialized(udev_device));
+
+                udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) {
+                        if (!udev_list_entry_get_num(list_entry))
+                                continue;
+                        fprintf(f, "E:%s=%s\n",
+                                udev_list_entry_get_name(list_entry),
+                                udev_list_entry_get_value(list_entry));
+                }
+
+                udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
+                        fprintf(f, "G:%s\n", udev_list_entry_get_name(list_entry));
+        }
+
+        fclose(f);
+        r = rename(filename_tmp, filename);
+        if (r < 0)
+                return -1;
+        udev_dbg(udev, "created %s file '%s' for '%s'\n", has_info ? "db" : "empty",
+             filename, udev_device_get_devpath(udev_device));
+        return 0;
+}
+
+int udev_device_delete_db(struct udev_device *udev_device)
+{
+        const char *id;
+        char filename[UTIL_PATH_SIZE];
+
+        id = udev_device_get_id_filename(udev_device);
+        if (id == NULL)
+                return -1;
+        util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
+        unlink(filename);
+        return 0;
+}
diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c
new file mode 100644 (file)
index 0000000..f218b02
--- /dev/null
@@ -0,0 +1,1799 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <net/if.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/sockios.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+/**
+ * SECTION:libudev-device
+ * @short_description: kernel sys devices
+ *
+ * Representation of kernel sys devices. Devices are uniquely identified
+ * by their syspath, every device has exactly one path in the kernel sys
+ * filesystem. Devices usually belong to a kernel subsystem, and and have
+ * a unique name inside that subsystem.
+ */
+
+/**
+ * udev_device:
+ *
+ * Opaque object representing one kernel sys device.
+ */
+struct udev_device {
+        struct udev *udev;
+        struct udev_device *parent_device;
+        char *syspath;
+        const char *devpath;
+        char *sysname;
+        const char *sysnum;
+        char *devnode;
+        mode_t devnode_mode;
+        uid_t devnode_uid;
+        gid_t devnode_gid;
+        char *subsystem;
+        char *devtype;
+        char *driver;
+        char *action;
+        char *devpath_old;
+        char *id_filename;
+        char **envp;
+        char *monitor_buf;
+        size_t monitor_buf_len;
+        struct udev_list devlinks_list;
+        struct udev_list properties_list;
+        struct udev_list sysattr_value_list;
+        struct udev_list sysattr_list;
+        struct udev_list tags_list;
+        unsigned long long int seqnum;
+        usec_t usec_initialized;
+        int devlink_priority;
+        int refcount;
+        dev_t devnum;
+        int ifindex;
+        int watch_handle;
+        int maj, min;
+        bool parent_set;
+        bool subsystem_set;
+        bool devtype_set;
+        bool devlinks_uptodate;
+        bool envp_uptodate;
+        bool tags_uptodate;
+        bool driver_set;
+        bool info_loaded;
+        bool db_loaded;
+        bool uevent_loaded;
+        bool is_initialized;
+        bool sysattr_list_read;
+        bool db_persist;
+};
+
+/**
+ * udev_device_get_seqnum:
+ * @udev_device: udev device
+ *
+ * This is only valid if the device was received through a monitor. Devices read from
+ * sys do not have a sequence number.
+ *
+ * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
+ **/
+_public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return 0;
+        return udev_device->seqnum;
+}
+
+static int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum)
+{
+        char num[32];
+
+        udev_device->seqnum = seqnum;
+        snprintf(num, sizeof(num), "%llu", seqnum);
+        udev_device_add_property(udev_device, "SEQNUM", num);
+        return 0;
+}
+
+int udev_device_get_ifindex(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_uevent_file(udev_device);
+        return udev_device->ifindex;
+}
+
+static int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex)
+{
+        char num[32];
+
+        udev_device->ifindex = ifindex;
+        snprintf(num, sizeof(num), "%u", ifindex);
+        udev_device_add_property(udev_device, "IFINDEX", num);
+        return 0;
+}
+
+/**
+ * udev_device_get_devnum:
+ * @udev_device: udev device
+ *
+ * Get the device major/minor number.
+ *
+ * Returns: the dev_t number.
+ **/
+_public_ dev_t udev_device_get_devnum(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return makedev(0, 0);
+        if (!udev_device->info_loaded)
+                udev_device_read_uevent_file(udev_device);
+        return udev_device->devnum;
+}
+
+static int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum)
+{
+        char num[32];
+
+        udev_device->devnum = devnum;
+
+        snprintf(num, sizeof(num), "%u", major(devnum));
+        udev_device_add_property(udev_device, "MAJOR", num);
+        snprintf(num, sizeof(num), "%u", minor(devnum));
+        udev_device_add_property(udev_device, "MINOR", num);
+        return 0;
+}
+
+const char *udev_device_get_devpath_old(struct udev_device *udev_device)
+{
+        return udev_device->devpath_old;
+}
+
+static int udev_device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old)
+{
+        const char *pos;
+
+        free(udev_device->devpath_old);
+        udev_device->devpath_old = strdup(devpath_old);
+        if (udev_device->devpath_old == NULL)
+                return -ENOMEM;
+        udev_device_add_property(udev_device, "DEVPATH_OLD", udev_device->devpath_old);
+
+        pos = strrchr(udev_device->devpath_old, '/');
+        if (pos == NULL)
+                return -EINVAL;
+        return 0;
+}
+
+/**
+ * udev_device_get_driver:
+ * @udev_device: udev device
+ *
+ * Get the kernel driver name.
+ *
+ * Returns: the driver name string, or #NULL if there is no driver attached.
+ **/
+_public_ const char *udev_device_get_driver(struct udev_device *udev_device)
+{
+        char driver[UTIL_NAME_SIZE];
+
+        if (udev_device == NULL)
+                return NULL;
+        if (!udev_device->driver_set) {
+                udev_device->driver_set = true;
+                if (util_get_sys_core_link_value(udev_device->udev, "driver", udev_device->syspath, driver, sizeof(driver)) > 0)
+                        udev_device->driver = strdup(driver);
+        }
+        return udev_device->driver;
+}
+
+static int udev_device_set_driver(struct udev_device *udev_device, const char *driver)
+{
+        free(udev_device->driver);
+        udev_device->driver = strdup(driver);
+        if (udev_device->driver == NULL)
+                return -ENOMEM;
+        udev_device->driver_set = true;
+        udev_device_add_property(udev_device, "DRIVER", udev_device->driver);
+        return 0;
+}
+
+/**
+ * udev_device_get_devtype:
+ * @udev_device: udev device
+ *
+ * Retrieve the devtype string of the udev device.
+ *
+ * Returns: the devtype name of the udev device, or #NULL if it can not be determined
+ **/
+_public_ const char *udev_device_get_devtype(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        if (!udev_device->devtype_set) {
+                udev_device->devtype_set = true;
+                udev_device_read_uevent_file(udev_device);
+        }
+        return udev_device->devtype;
+}
+
+static int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype)
+{
+        free(udev_device->devtype);
+        udev_device->devtype = strdup(devtype);
+        if (udev_device->devtype == NULL)
+                return -ENOMEM;
+        udev_device->devtype_set = true;
+        udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype);
+        return 0;
+}
+
+int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem)
+{
+        free(udev_device->subsystem);
+        udev_device->subsystem = strdup(subsystem);
+        if (udev_device->subsystem == NULL)
+                return -ENOMEM;
+        udev_device->subsystem_set = true;
+        udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem);
+        return 0;
+}
+
+/**
+ * udev_device_get_subsystem:
+ * @udev_device: udev device
+ *
+ * Retrieve the subsystem string of the udev device. The string does not
+ * contain any "/".
+ *
+ * Returns: the subsystem name of the udev device, or #NULL if it can not be determined
+ **/
+_public_ const char *udev_device_get_subsystem(struct udev_device *udev_device)
+{
+        char subsystem[UTIL_NAME_SIZE];
+
+        if (udev_device == NULL)
+                return NULL;
+        if (!udev_device->subsystem_set) {
+                udev_device->subsystem_set = true;
+                /* read "subsystem" link */
+                if (util_get_sys_core_link_value(udev_device->udev, "subsystem", udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
+                        udev_device_set_subsystem(udev_device, subsystem);
+                        return udev_device->subsystem;
+                }
+                /* implicit names */
+                if (startswith(udev_device->devpath, "/module/")) {
+                        udev_device_set_subsystem(udev_device, "module");
+                        return udev_device->subsystem;
+                }
+                if (strstr(udev_device->devpath, "/drivers/") != NULL) {
+                        udev_device_set_subsystem(udev_device, "drivers");
+                        return udev_device->subsystem;
+                }
+                if (startswith(udev_device->devpath, "/subsystem/") ||
+                    startswith(udev_device->devpath, "/class/") ||
+                    startswith(udev_device->devpath, "/bus/")) {
+                        udev_device_set_subsystem(udev_device, "subsystem");
+                        return udev_device->subsystem;
+                }
+        }
+        return udev_device->subsystem;
+}
+
+mode_t udev_device_get_devnode_mode(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_uevent_file(udev_device);
+        return udev_device->devnode_mode;
+}
+
+static int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t mode)
+{
+        char num[32];
+
+        udev_device->devnode_mode = mode;
+        snprintf(num, sizeof(num), "%#o", mode);
+        udev_device_add_property(udev_device, "DEVMODE", num);
+        return 0;
+}
+
+uid_t udev_device_get_devnode_uid(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_uevent_file(udev_device);
+        return udev_device->devnode_uid;
+}
+
+static int udev_device_set_devnode_uid(struct udev_device *udev_device, uid_t uid)
+{
+        char num[32];
+
+        udev_device->devnode_uid = uid;
+        snprintf(num, sizeof(num), "%u", uid);
+        udev_device_add_property(udev_device, "DEVUID", num);
+        return 0;
+}
+
+gid_t udev_device_get_devnode_gid(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_uevent_file(udev_device);
+        return udev_device->devnode_gid;
+}
+
+static int udev_device_set_devnode_gid(struct udev_device *udev_device, gid_t gid)
+{
+        char num[32];
+
+        udev_device->devnode_gid = gid;
+        snprintf(num, sizeof(num), "%u", gid);
+        udev_device_add_property(udev_device, "DEVGID", num);
+        return 0;
+}
+
+struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
+{
+        udev_device->envp_uptodate = false;
+        if (value == NULL) {
+                struct udev_list_entry *list_entry;
+
+                list_entry = udev_device_get_properties_list_entry(udev_device);
+                list_entry = udev_list_entry_get_by_name(list_entry, key);
+                if (list_entry != NULL)
+                        udev_list_entry_delete(list_entry);
+                return NULL;
+        }
+        return udev_list_entry_add(&udev_device->properties_list, key, value);
+}
+
+static struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property)
+{
+        char name[UTIL_LINE_SIZE];
+        char *val;
+
+        util_strscpy(name, sizeof(name), property);
+        val = strchr(name, '=');
+        if (val == NULL)
+                return NULL;
+        val[0] = '\0';
+        val = &val[1];
+        if (val[0] == '\0')
+                val = NULL;
+        return udev_device_add_property(udev_device, name, val);
+}
+
+/*
+ * parse property string, and if needed, update internal values accordingly
+ *
+ * udev_device_add_property_from_string_parse_finish() needs to be
+ * called after adding properties, and its return value checked
+ *
+ * udev_device_set_info_loaded() needs to be set, to avoid trying
+ * to use a device without a DEVPATH set
+ */
+void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property)
+{
+        if (startswith(property, "DEVPATH=")) {
+                char path[UTIL_PATH_SIZE];
+
+                util_strscpyl(path, sizeof(path), "/sys", &property[8], NULL);
+                udev_device_set_syspath(udev_device, path);
+        } else if (startswith(property, "SUBSYSTEM=")) {
+                udev_device_set_subsystem(udev_device, &property[10]);
+        } else if (startswith(property, "DEVTYPE=")) {
+                udev_device_set_devtype(udev_device, &property[8]);
+        } else if (startswith(property, "DEVNAME=")) {
+                udev_device_set_devnode(udev_device, &property[8]);
+        } else if (startswith(property, "DEVLINKS=")) {
+                char devlinks[UTIL_PATH_SIZE];
+                char *slink;
+                char *next;
+
+                util_strscpy(devlinks, sizeof(devlinks), &property[9]);
+                slink = devlinks;
+                next = strchr(slink, ' ');
+                while (next != NULL) {
+                        next[0] = '\0';
+                        udev_device_add_devlink(udev_device, slink);
+                        slink = &next[1];
+                        next = strchr(slink, ' ');
+                }
+                if (slink[0] != '\0')
+                        udev_device_add_devlink(udev_device, slink);
+        } else if (startswith(property, "TAGS=")) {
+                char tags[UTIL_PATH_SIZE];
+                char *next;
+
+                util_strscpy(tags, sizeof(tags), &property[5]);
+                next = strchr(tags, ':');
+                if (next != NULL) {
+                        next++;
+                        while (next[0] != '\0') {
+                                char *tag;
+
+                                tag = next;
+                                next = strchr(tag, ':');
+                                if (next == NULL)
+                                        break;
+                                next[0] = '\0';
+                                next++;
+                                udev_device_add_tag(udev_device, tag);
+                        }
+                }
+        } else if (startswith(property, "USEC_INITIALIZED=")) {
+                udev_device_set_usec_initialized(udev_device, strtoull(&property[19], NULL, 10));
+        } else if (startswith(property, "DRIVER=")) {
+                udev_device_set_driver(udev_device, &property[7]);
+        } else if (startswith(property, "ACTION=")) {
+                udev_device_set_action(udev_device, &property[7]);
+        } else if (startswith(property, "MAJOR=")) {
+                udev_device->maj = strtoull(&property[6], NULL, 10);
+        } else if (startswith(property, "MINOR=")) {
+                udev_device->min = strtoull(&property[6], NULL, 10);
+        } else if (startswith(property, "DEVPATH_OLD=")) {
+                udev_device_set_devpath_old(udev_device, &property[12]);
+        } else if (startswith(property, "SEQNUM=")) {
+                udev_device_set_seqnum(udev_device, strtoull(&property[7], NULL, 10));
+        } else if (startswith(property, "IFINDEX=")) {
+                udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10));
+        } else if (startswith(property, "DEVMODE=")) {
+                udev_device_set_devnode_mode(udev_device, strtoul(&property[8], NULL, 8));
+        } else if (startswith(property, "DEVUID=")) {
+                udev_device_set_devnode_uid(udev_device, strtoul(&property[7], NULL, 10));
+        } else if (startswith(property, "DEVGID=")) {
+                udev_device_set_devnode_gid(udev_device, strtoul(&property[7], NULL, 10));
+        } else {
+                udev_device_add_property_from_string(udev_device, property);
+        }
+}
+
+int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device)
+{
+        if (udev_device->maj > 0)
+                udev_device_set_devnum(udev_device, makedev(udev_device->maj, udev_device->min));
+        udev_device->maj = 0;
+        udev_device->min = 0;
+
+        if (udev_device->devpath == NULL || udev_device->subsystem == NULL)
+                return -EINVAL;
+        return 0;
+}
+
+/**
+ * udev_device_get_property_value:
+ * @udev_device: udev device
+ * @key: property name
+ *
+ * Get the value of a given property.
+ *
+ * Returns: the property string, or #NULL if there is no such property.
+ **/
+_public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key)
+{
+        struct udev_list_entry *list_entry;
+
+        if (udev_device == NULL)
+                return NULL;
+        if (key == NULL)
+                return NULL;
+
+        list_entry = udev_device_get_properties_list_entry(udev_device);
+        list_entry = udev_list_entry_get_by_name(list_entry, key);
+        return udev_list_entry_get_value(list_entry);
+}
+
+int udev_device_read_db(struct udev_device *udev_device, const char *dbfile)
+{
+        char filename[UTIL_PATH_SIZE];
+        char line[UTIL_LINE_SIZE];
+        FILE *f;
+
+        /* providing a database file will always force-load it */
+        if (dbfile == NULL) {
+                const char *id;
+
+                if (udev_device->db_loaded)
+                        return 0;
+                udev_device->db_loaded = true;
+
+                id = udev_device_get_id_filename(udev_device);
+                if (id == NULL)
+                        return -1;
+                util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
+                dbfile = filename;
+        }
+
+        f = fopen(dbfile, "re");
+        if (f == NULL) {
+                udev_dbg(udev_device->udev, "no db file to read %s: %m\n", dbfile);
+                return -1;
+        }
+        udev_device->is_initialized = true;
+
+        while (fgets(line, sizeof(line), f)) {
+                ssize_t len;
+                const char *val;
+                struct udev_list_entry *entry;
+
+                len = strlen(line);
+                if (len < 4)
+                        break;
+                line[len-1] = '\0';
+                val = &line[2];
+                switch(line[0]) {
+                case 'S':
+                        util_strscpyl(filename, sizeof(filename), "/dev/", val, NULL);
+                        udev_device_add_devlink(udev_device, filename);
+                        break;
+                case 'L':
+                        udev_device_set_devlink_priority(udev_device, atoi(val));
+                        break;
+                case 'E':
+                        entry = udev_device_add_property_from_string(udev_device, val);
+                        udev_list_entry_set_num(entry, true);
+                        break;
+                case 'G':
+                        udev_device_add_tag(udev_device, val);
+                        break;
+                case 'W':
+                        udev_device_set_watch_handle(udev_device, atoi(val));
+                        break;
+                case 'I':
+                        udev_device_set_usec_initialized(udev_device, strtoull(val, NULL, 10));
+                        break;
+                }
+        }
+        fclose(f);
+
+        udev_dbg(udev_device->udev, "device %p filled with db file data\n", udev_device);
+        return 0;
+}
+
+int udev_device_read_uevent_file(struct udev_device *udev_device)
+{
+        char filename[UTIL_PATH_SIZE];
+        FILE *f;
+        char line[UTIL_LINE_SIZE];
+        int maj = 0;
+        int min = 0;
+
+        if (udev_device->uevent_loaded)
+                return 0;
+
+        util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL);
+        f = fopen(filename, "re");
+        if (f == NULL)
+                return -1;
+        udev_device->uevent_loaded = true;
+
+        while (fgets(line, sizeof(line), f)) {
+                char *pos;
+
+                pos = strchr(line, '\n');
+                if (pos == NULL)
+                        continue;
+                pos[0] = '\0';
+
+                if (startswith(line, "DEVTYPE=")) {
+                        udev_device_set_devtype(udev_device, &line[8]);
+                        continue;
+                }
+                if (startswith(line, "IFINDEX=")) {
+                        udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10));
+                        continue;
+                }
+                if (startswith(line, "DEVNAME=")) {
+                        udev_device_set_devnode(udev_device, &line[8]);
+                        continue;
+                }
+
+                if (startswith(line, "MAJOR="))
+                        maj = strtoull(&line[6], NULL, 10);
+                else if (startswith(line, "MINOR="))
+                        min = strtoull(&line[6], NULL, 10);
+                else if (startswith(line, "DEVMODE="))
+                        udev_device->devnode_mode = strtoul(&line[8], NULL, 8);
+
+                udev_device_add_property_from_string(udev_device, line);
+        }
+
+        udev_device->devnum = makedev(maj, min);
+        fclose(f);
+        return 0;
+}
+
+void udev_device_set_info_loaded(struct udev_device *device)
+{
+        device->info_loaded = true;
+}
+
+struct udev_device *udev_device_new(struct udev *udev)
+{
+        struct udev_device *udev_device;
+        struct udev_list_entry *list_entry;
+
+        if (udev == NULL)
+                return NULL;
+
+        udev_device = calloc(1, sizeof(struct udev_device));
+        if (udev_device == NULL)
+                return NULL;
+        udev_device->refcount = 1;
+        udev_device->udev = udev;
+        udev_list_init(udev, &udev_device->devlinks_list, true);
+        udev_list_init(udev, &udev_device->properties_list, true);
+        udev_list_init(udev, &udev_device->sysattr_value_list, true);
+        udev_list_init(udev, &udev_device->sysattr_list, false);
+        udev_list_init(udev, &udev_device->tags_list, true);
+        udev_device->watch_handle = -1;
+        /* copy global properties */
+        udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev))
+                udev_device_add_property(udev_device,
+                                         udev_list_entry_get_name(list_entry),
+                                         udev_list_entry_get_value(list_entry));
+        return udev_device;
+}
+
+/**
+ * udev_device_new_from_syspath:
+ * @udev: udev library context
+ * @syspath: sys device path including sys directory
+ *
+ * Create new udev device, and fill in information from the sys
+ * device and the udev database entry. The syspath is the absolute
+ * path to the device, including the sys mount point.
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev device.
+ *
+ * Returns: a new udev device, or #NULL, if it does not exist
+ **/
+_public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath)
+{
+        const char *subdir;
+        char path[UTIL_PATH_SIZE];
+        char *pos;
+        struct stat statbuf;
+        struct udev_device *udev_device;
+
+        if (udev == NULL)
+                return NULL;
+        if (syspath == NULL)
+                return NULL;
+
+        /* path starts in sys */
+        if (!startswith(syspath, "/sys")) {
+                udev_dbg(udev, "not in sys :%s\n", syspath);
+                return NULL;
+        }
+
+        /* path is not a root directory */
+        subdir = syspath + strlen("/sys");
+        pos = strrchr(subdir, '/');
+        if (pos == NULL || pos[1] == '\0' || pos < &subdir[2])
+                return NULL;
+
+        /* resolve possible symlink to real path */
+        util_strscpy(path, sizeof(path), syspath);
+        util_resolve_sys_link(udev, path, sizeof(path));
+
+        if (startswith(path + strlen("/sys"), "/devices/")) {
+                char file[UTIL_PATH_SIZE];
+
+                /* all "devices" require a "uevent" file */
+                util_strscpyl(file, sizeof(file), path, "/uevent", NULL);
+                if (stat(file, &statbuf) != 0)
+                        return NULL;
+        } else {
+                /* everything else just needs to be a directory */
+                if (stat(path, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))
+                        return NULL;
+        }
+
+        udev_device = udev_device_new(udev);
+        if (udev_device == NULL)
+                return NULL;
+
+        udev_device_set_syspath(udev_device, path);
+        udev_dbg(udev, "device %p has devpath '%s'\n", udev_device, udev_device_get_devpath(udev_device));
+
+        return udev_device;
+}
+
+/**
+ * udev_device_new_from_devnum:
+ * @udev: udev library context
+ * @type: char or block device
+ * @devnum: device major/minor number
+ *
+ * Create new udev device, and fill in information from the sys
+ * device and the udev database entry. The device is looked-up
+ * by its major/minor number and type. Character and block device
+ * numbers are not unique across the two types.
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev device.
+ *
+ * Returns: a new udev device, or #NULL, if it does not exist
+ **/
+_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum)
+{
+        char path[UTIL_PATH_SIZE];
+        const char *type_str;
+
+        if (type == 'b')
+                type_str = "block";
+        else if (type == 'c')
+                type_str = "char";
+        else
+                return NULL;
+
+        /* use /sys/dev/{block,char}/<maj>:<min> link */
+        snprintf(path, sizeof(path), "/sys/dev/%s/%u:%u",
+                 type_str, major(devnum), minor(devnum));
+        return udev_device_new_from_syspath(udev, path);
+}
+
+/**
+ * udev_device_new_from_device_id:
+ * @udev: udev library context
+ * @id: text string identifying a kernel device
+ *
+ * Create new udev device, and fill in information from the sys
+ * device and the udev database entry. The device is looked-up
+ * by a special string:
+ *   b8:2          - block device major:minor
+ *   c128:1        - char device major:minor
+ *   n3            - network device ifindex
+ *   +sound:card29 - kernel driver core subsystem:device name
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev device.
+ *
+ * Returns: a new udev device, or #NULL, if it does not exist
+ **/
+_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, char *id)
+{
+        char type;
+        int maj, min;
+        char subsys[UTIL_PATH_SIZE];
+        char *sysname;
+
+        switch(id[0]) {
+        case 'b':
+        case 'c':
+                if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3)
+                        return NULL;
+                return udev_device_new_from_devnum(udev, type, makedev(maj, min));
+        case 'n': {
+                int sk;
+                struct ifreq ifr;
+                struct udev_device *dev;
+                int ifindex;
+
+                ifindex = strtoul(&id[1], NULL, 10);
+                if (ifindex <= 0)
+                        return NULL;
+
+                sk = socket(PF_INET, SOCK_DGRAM, 0);
+                if (sk < 0)
+                        return NULL;
+                memset(&ifr, 0x00, sizeof(struct ifreq));
+                ifr.ifr_ifindex = ifindex;
+                if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) {
+                        close(sk);
+                        return NULL;
+                }
+                close(sk);
+
+                dev = udev_device_new_from_subsystem_sysname(udev, "net", ifr.ifr_name);
+                if (dev == NULL)
+                        return NULL;
+                if (udev_device_get_ifindex(dev) == ifindex)
+                        return dev;
+                udev_device_unref(dev);
+                return NULL;
+        }
+        case '+':
+                util_strscpy(subsys, sizeof(subsys), &id[1]);
+                sysname = strchr(subsys, ':');
+                if (sysname == NULL)
+                        return NULL;
+                sysname[0] = '\0';
+                sysname = &sysname[1];
+                return udev_device_new_from_subsystem_sysname(udev, subsys, sysname);
+        default:
+                return NULL;
+        }
+}
+
+/**
+ * udev_device_new_from_subsystem_sysname:
+ * @udev: udev library context
+ * @subsystem: the subsystem of the device
+ * @sysname: the name of the device
+ *
+ * Create new udev device, and fill in information from the sys device
+ * and the udev database entry. The device is looked up by the subsystem
+ * and name string of the device, like "mem" / "zero", or "block" / "sda".
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev device.
+ *
+ * Returns: a new udev device, or #NULL, if it does not exist
+ **/
+_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname)
+{
+        char path[UTIL_PATH_SIZE];
+        struct stat statbuf;
+
+        if (streq(subsystem, "subsystem")) {
+                util_strscpyl(path, sizeof(path), "/sys/subsystem/", sysname, NULL);
+                if (stat(path, &statbuf) == 0)
+                        goto found;
+
+                util_strscpyl(path, sizeof(path), "/sys/bus/", sysname, NULL);
+                if (stat(path, &statbuf) == 0)
+                        goto found;
+
+                util_strscpyl(path, sizeof(path), "/sys/class/", sysname, NULL);
+                if (stat(path, &statbuf) == 0)
+                        goto found;
+                goto out;
+        }
+
+        if (streq(subsystem, "module")) {
+                util_strscpyl(path, sizeof(path), "/sys/module/", sysname, NULL);
+                if (stat(path, &statbuf) == 0)
+                        goto found;
+                goto out;
+        }
+
+        if (streq(subsystem, "drivers")) {
+                char subsys[UTIL_NAME_SIZE];
+                char *driver;
+
+                util_strscpy(subsys, sizeof(subsys), sysname);
+                driver = strchr(subsys, ':');
+                if (driver != NULL) {
+                        driver[0] = '\0';
+                        driver = &driver[1];
+
+                        util_strscpyl(path, sizeof(path), "/sys/subsystem/", subsys, "/drivers/", driver, NULL);
+                        if (stat(path, &statbuf) == 0)
+                                goto found;
+
+                        util_strscpyl(path, sizeof(path), "/sys/bus/", subsys, "/drivers/", driver, NULL);
+                        if (stat(path, &statbuf) == 0)
+                                goto found;
+                }
+                goto out;
+        }
+
+        util_strscpyl(path, sizeof(path), "/sys/subsystem/", subsystem, "/devices/", sysname, NULL);
+        if (stat(path, &statbuf) == 0)
+                goto found;
+
+        util_strscpyl(path, sizeof(path), "/sys/bus/", subsystem, "/devices/", sysname, NULL);
+        if (stat(path, &statbuf) == 0)
+                goto found;
+
+        util_strscpyl(path, sizeof(path), "/sys/class/", subsystem, "/", sysname, NULL);
+        if (stat(path, &statbuf) == 0)
+                goto found;
+out:
+        return NULL;
+found:
+        return udev_device_new_from_syspath(udev, path);
+}
+
+/**
+ * udev_device_new_from_environment
+ * @udev: udev library context
+ *
+ * Create new udev device, and fill in information from the
+ * current process environment. This only works reliable if
+ * the process is called from a udev rule. It is usually used
+ * for tools executed from IMPORT= rules.
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev device.
+ *
+ * Returns: a new udev device, or #NULL, if it does not exist
+ **/
+_public_ struct udev_device *udev_device_new_from_environment(struct udev *udev)
+{
+        int i;
+        struct udev_device *udev_device;
+
+        udev_device = udev_device_new(udev);
+        if (udev_device == NULL)
+                return NULL;
+        udev_device_set_info_loaded(udev_device);
+
+        for (i = 0; environ[i] != NULL; i++)
+                udev_device_add_property_from_string_parse(udev_device, environ[i]);
+
+        if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) {
+                udev_dbg(udev, "missing values, invalid device\n");
+                udev_device_unref(udev_device);
+                udev_device = NULL;
+        }
+
+        return udev_device;
+}
+
+static struct udev_device *device_new_from_parent(struct udev_device *udev_device)
+{
+        struct udev_device *udev_device_parent = NULL;
+        char path[UTIL_PATH_SIZE];
+        const char *subdir;
+
+        util_strscpy(path, sizeof(path), udev_device->syspath);
+        subdir = path + strlen("/sys/");
+        for (;;) {
+                char *pos;
+
+                pos = strrchr(subdir, '/');
+                if (pos == NULL || pos < &subdir[2])
+                        break;
+                pos[0] = '\0';
+                udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path);
+                if (udev_device_parent != NULL)
+                        return udev_device_parent;
+        }
+        return NULL;
+}
+
+/**
+ * udev_device_get_parent:
+ * @udev_device: the device to start searching from
+ *
+ * Find the next parent device, and fill in information from the sys
+ * device and the udev database entry.
+ *
+ * The returned the device is not referenced. It is attached to the
+ * child device, and will be cleaned up when the child device
+ * is cleaned up.
+ *
+ * It is not necessarily just the upper level directory, empty or not
+ * recognized sys directories are ignored.
+ *
+ * It can be called as many times as needed, without caring about
+ * references.
+ *
+ * Returns: a new udev device, or #NULL, if it no parent exist.
+ **/
+_public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        if (!udev_device->parent_set) {
+                udev_device->parent_set = true;
+                udev_device->parent_device = device_new_from_parent(udev_device);
+        }
+        return udev_device->parent_device;
+}
+
+/**
+ * udev_device_get_parent_with_subsystem_devtype:
+ * @udev_device: udev device to start searching from
+ * @subsystem: the subsystem of the device
+ * @devtype: the type (DEVTYPE) of the device
+ *
+ * Find the next parent device, with a matching subsystem and devtype
+ * value, and fill in information from the sys device and the udev
+ * database entry.
+ *
+ * If devtype is #NULL, only subsystem is checked, and any devtype will
+ * match.
+ *
+ * The returned the device is not referenced. It is attached to the
+ * child device, and will be cleaned up when the child device
+ * is cleaned up.
+ *
+ * It can be called as many times as needed, without caring about
+ * references.
+ *
+ * Returns: a new udev device, or #NULL if no matching parent exists.
+ **/
+_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype)
+{
+        struct udev_device *parent;
+
+        if (subsystem == NULL)
+                return NULL;
+
+        parent = udev_device_get_parent(udev_device);
+        while (parent != NULL) {
+                const char *parent_subsystem;
+                const char *parent_devtype;
+
+                parent_subsystem = udev_device_get_subsystem(parent);
+                if (parent_subsystem != NULL && streq(parent_subsystem, subsystem)) {
+                        if (devtype == NULL)
+                                break;
+                        parent_devtype = udev_device_get_devtype(parent);
+                        if (parent_devtype != NULL && streq(parent_devtype, devtype))
+                                break;
+                }
+                parent = udev_device_get_parent(parent);
+        }
+        return parent;
+}
+
+/**
+ * udev_device_get_udev:
+ * @udev_device: udev device
+ *
+ * Retrieve the udev library context the device was created with.
+ *
+ * Returns: the udev library context
+ **/
+_public_ struct udev *udev_device_get_udev(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        return udev_device->udev;
+}
+
+/**
+ * udev_device_ref:
+ * @udev_device: udev device
+ *
+ * Take a reference of a udev device.
+ *
+ * Returns: the passed udev device
+ **/
+_public_ struct udev_device *udev_device_ref(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        udev_device->refcount++;
+        return udev_device;
+}
+
+/**
+ * udev_device_unref:
+ * @udev_device: udev device
+ *
+ * Drop a reference of a udev device. If the refcount reaches zero,
+ * the resources of the device will be released.
+ *
+ * Returns: the passed udev device if it has still an active reference, or #NULL otherwise.
+ **/
+_public_ struct udev_device *udev_device_unref(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        udev_device->refcount--;
+        if (udev_device->refcount > 0)
+                return udev_device;
+        if (udev_device->parent_device != NULL)
+                udev_device_unref(udev_device->parent_device);
+        free(udev_device->syspath);
+        free(udev_device->sysname);
+        free(udev_device->devnode);
+        free(udev_device->subsystem);
+        free(udev_device->devtype);
+        udev_list_cleanup(&udev_device->devlinks_list);
+        udev_list_cleanup(&udev_device->properties_list);
+        udev_list_cleanup(&udev_device->sysattr_value_list);
+        udev_list_cleanup(&udev_device->sysattr_list);
+        udev_list_cleanup(&udev_device->tags_list);
+        free(udev_device->action);
+        free(udev_device->driver);
+        free(udev_device->devpath_old);
+        free(udev_device->id_filename);
+        free(udev_device->envp);
+        free(udev_device->monitor_buf);
+        free(udev_device);
+        return NULL;
+}
+
+/**
+ * udev_device_get_devpath:
+ * @udev_device: udev device
+ *
+ * Retrieve the kernel devpath value of the udev device. The path
+ * does not contain the sys mount point, and starts with a '/'.
+ *
+ * Returns: the devpath of the udev device
+ **/
+_public_ const char *udev_device_get_devpath(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        return udev_device->devpath;
+}
+
+/**
+ * udev_device_get_syspath:
+ * @udev_device: udev device
+ *
+ * Retrieve the sys path of the udev device. The path is an
+ * absolute path and starts with the sys mount point.
+ *
+ * Returns: the sys path of the udev device
+ **/
+_public_ const char *udev_device_get_syspath(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        return udev_device->syspath;
+}
+
+/**
+ * udev_device_get_sysname:
+ * @udev_device: udev device
+ *
+ * Get the kernel device name in /sys.
+ *
+ * Returns: the name string of the device device
+ **/
+_public_ const char *udev_device_get_sysname(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        return udev_device->sysname;
+}
+
+/**
+ * udev_device_get_sysnum:
+ * @udev_device: udev device
+ *
+ * Get the instance number of the device.
+ *
+ * Returns: the trailing number string of the device name
+ **/
+_public_ const char *udev_device_get_sysnum(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        return udev_device->sysnum;
+}
+
+/**
+ * udev_device_get_devnode:
+ * @udev_device: udev device
+ *
+ * Retrieve the device node file name belonging to the udev device.
+ * The path is an absolute path, and starts with the device directory.
+ *
+ * Returns: the device node file name of the udev device, or #NULL if no device node exists
+ **/
+_public_ const char *udev_device_get_devnode(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        if (udev_device->devnode != NULL)
+                return udev_device->devnode;
+        if (!udev_device->info_loaded)
+                udev_device_read_uevent_file(udev_device);
+        return udev_device->devnode;
+}
+
+/**
+ * udev_device_get_devlinks_list_entry:
+ * @udev_device: udev device
+ *
+ * Retrieve the list of device links pointing to the device file of
+ * the udev device. The next list entry can be retrieved with
+ * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
+ * The devlink path can be retrieved from the list entry by
+ * udev_list_entry_get_name(). The path is an absolute path, and starts with
+ * the device directory.
+ *
+ * Returns: the first entry of the device node link list
+ **/
+_public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        if (!udev_device->info_loaded)
+                udev_device_read_db(udev_device, NULL);
+        return udev_list_get_entry(&udev_device->devlinks_list);
+}
+
+void udev_device_cleanup_devlinks_list(struct udev_device *udev_device)
+{
+        udev_device->devlinks_uptodate = false;
+        udev_list_cleanup(&udev_device->devlinks_list);
+}
+
+/**
+ * udev_device_get_properties_list_entry:
+ * @udev_device: udev device
+ *
+ * Retrieve the list of key/value device properties of the udev
+ * device. The next list entry can be retrieved with udev_list_entry_get_next(),
+ * which returns #NULL if no more entries exist. The property name
+ * can be retrieved from the list entry by udev_list_entry_get_name(),
+ * the property value by udev_list_entry_get_value().
+ *
+ * Returns: the first entry of the property list
+ **/
+_public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        if (!udev_device->info_loaded) {
+                udev_device_read_uevent_file(udev_device);
+                udev_device_read_db(udev_device, NULL);
+        }
+        if (!udev_device->devlinks_uptodate) {
+                char symlinks[UTIL_PATH_SIZE];
+                struct udev_list_entry *list_entry;
+
+                udev_device->devlinks_uptodate = true;
+                list_entry = udev_device_get_devlinks_list_entry(udev_device);
+                if (list_entry != NULL) {
+                        char *s;
+                        size_t l;
+
+                        s = symlinks;
+                        l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
+                        udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
+                                l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
+                        udev_device_add_property(udev_device, "DEVLINKS", symlinks);
+                }
+        }
+        if (!udev_device->tags_uptodate) {
+                udev_device->tags_uptodate = true;
+                if (udev_device_get_tags_list_entry(udev_device) != NULL) {
+                        char tags[UTIL_PATH_SIZE];
+                        struct udev_list_entry *list_entry;
+                        char *s;
+                        size_t l;
+
+                        s = tags;
+                        l = util_strpcpyl(&s, sizeof(tags), ":", NULL);
+                        udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
+                                l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
+                        udev_device_add_property(udev_device, "TAGS", tags);
+                }
+        }
+        return udev_list_get_entry(&udev_device->properties_list);
+}
+
+/**
+ * udev_device_get_action:
+ * @udev_device: udev device
+ *
+ * This is only valid if the device was received through a monitor. Devices read from
+ * sys do not have an action string. Usual actions are: add, remove, change, online,
+ * offline.
+ *
+ * Returns: the kernel action value, or #NULL if there is no action value available.
+ **/
+_public_ const char *udev_device_get_action(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        return udev_device->action;
+}
+
+/**
+ * udev_device_get_usec_since_initialized:
+ * @udev_device: udev device
+ *
+ * Return the number of microseconds passed since udev set up the
+ * device for the first time.
+ *
+ * This is only implemented for devices with need to store properties
+ * in the udev database. All other devices return 0 here.
+ *
+ * Returns: the number of microseconds since the device was first seen.
+ **/
+_public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device)
+{
+        usec_t now_ts;
+
+        if (udev_device == NULL)
+                return 0;
+        if (!udev_device->info_loaded)
+                udev_device_read_db(udev_device, NULL);
+        if (udev_device->usec_initialized == 0)
+                return 0;
+        now_ts = now(CLOCK_MONOTONIC);
+        if (now_ts == 0)
+                return 0;
+        return now_ts - udev_device->usec_initialized;
+}
+
+usec_t udev_device_get_usec_initialized(struct udev_device *udev_device)
+{
+        return udev_device->usec_initialized;
+}
+
+void udev_device_set_usec_initialized(struct udev_device *udev_device, usec_t usec_initialized)
+{
+        char num[32];
+
+        udev_device->usec_initialized = usec_initialized;
+        snprintf(num, sizeof(num), "%llu", (unsigned long long)usec_initialized);
+        udev_device_add_property(udev_device, "USEC_INITIALIZED", num);
+}
+
+/**
+ * udev_device_get_sysattr_value:
+ * @udev_device: udev device
+ * @sysattr: attribute name
+ *
+ * The retrieved value is cached in the device. Repeated calls will return the same
+ * value and not open the attribute again.
+ *
+ * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value.
+ **/
+_public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
+{
+        struct udev_list_entry *list_entry;
+        char path[UTIL_PATH_SIZE];
+        char value[4096];
+        struct stat statbuf;
+        int fd;
+        ssize_t size;
+        const char *val = NULL;
+
+        if (udev_device == NULL)
+                return NULL;
+        if (sysattr == NULL)
+                return NULL;
+
+        /* look for possibly already cached result */
+        list_entry = udev_list_get_entry(&udev_device->sysattr_value_list);
+        list_entry = udev_list_entry_get_by_name(list_entry, sysattr);
+        if (list_entry != NULL)
+                return udev_list_entry_get_value(list_entry);
+
+        util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
+        if (lstat(path, &statbuf) != 0) {
+                udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL);
+                goto out;
+        }
+
+        if (S_ISLNK(statbuf.st_mode)) {
+                struct udev_device *dev;
+
+                /*
+                 * Some core links return only the last element of the target path,
+                 * these are just values, the paths should not be exposed.
+                 */
+                if (streq(sysattr, "driver") ||
+                    streq(sysattr, "subsystem") ||
+                    streq(sysattr, "module")) {
+                        if (util_get_sys_core_link_value(udev_device->udev, sysattr,
+                                                         udev_device->syspath, value, sizeof(value)) < 0)
+                                return NULL;
+                        list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
+                        val = udev_list_entry_get_value(list_entry);
+                        goto out;
+                }
+
+                /* resolve custom link to a device and return its syspath */
+                if (!streq(sysattr, "device")) {
+                        util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
+                        dev = udev_device_new_from_syspath(udev_device->udev, path);
+                        if (dev != NULL) {
+                                list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
+                                                                 udev_device_get_syspath(dev));
+                                val = udev_list_entry_get_value(list_entry);
+                                udev_device_unref(dev);
+                        }
+                }
+                goto out;
+        }
+
+        /* skip directories */
+        if (S_ISDIR(statbuf.st_mode))
+                goto out;
+
+        /* skip non-readable files */
+        if ((statbuf.st_mode & S_IRUSR) == 0)
+                goto out;
+
+        /* read attribute value */
+        fd = open(path, O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
+                goto out;
+        size = read(fd, value, sizeof(value));
+        close(fd);
+        if (size < 0)
+                goto out;
+        if (size == sizeof(value))
+                goto out;
+
+        /* got a valid value, store it in cache and return it */
+        value[size] = '\0';
+        util_remove_trailing_chars(value, '\n');
+        list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
+        val = udev_list_entry_get_value(list_entry);
+out:
+        return val;
+}
+
+static int udev_device_sysattr_list_read(struct udev_device *udev_device)
+{
+        struct dirent *dent;
+        DIR *dir;
+        int num = 0;
+
+        if (udev_device == NULL)
+                return -1;
+        if (udev_device->sysattr_list_read)
+                return 0;
+
+        dir = opendir(udev_device_get_syspath(udev_device));
+        if (!dir)
+                return -1;
+
+        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                char path[UTIL_PATH_SIZE];
+                struct stat statbuf;
+
+                /* only handle symlinks and regular files */
+                if (dent->d_type != DT_LNK && dent->d_type != DT_REG)
+                        continue;
+
+                util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL);
+                if (lstat(path, &statbuf) != 0)
+                        continue;
+                if ((statbuf.st_mode & S_IRUSR) == 0)
+                        continue;
+
+                udev_list_entry_add(&udev_device->sysattr_list, dent->d_name, NULL);
+                num++;
+        }
+
+        closedir(dir);
+        udev_device->sysattr_list_read = true;
+
+        return num;
+}
+
+/**
+ * udev_device_get_sysattr_list_entry:
+ * @udev_device: udev device
+ *
+ * Retrieve the list of available sysattrs, with value being empty;
+ * This just return all available sysfs attributes for a particular
+ * device without reading their values.
+ *
+ * Returns: the first entry of the property list
+ **/
+_public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device)
+{
+        if (!udev_device->sysattr_list_read) {
+                int ret;
+                ret = udev_device_sysattr_list_read(udev_device);
+                if (0 > ret)
+                        return NULL;
+        }
+
+        return udev_list_get_entry(&udev_device->sysattr_list);
+}
+
+int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
+{
+        const char *pos;
+        size_t len;
+
+        free(udev_device->syspath);
+        udev_device->syspath = strdup(syspath);
+        if (udev_device->syspath ==  NULL)
+                return -ENOMEM;
+        udev_device->devpath = udev_device->syspath + strlen("/sys");
+        udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath);
+
+        pos = strrchr(udev_device->syspath, '/');
+        if (pos == NULL)
+                return -EINVAL;
+        udev_device->sysname = strdup(&pos[1]);
+        if (udev_device->sysname == NULL)
+                return -ENOMEM;
+
+        /* some devices have '!' in their name, change that to '/' */
+        len = 0;
+        while (udev_device->sysname[len] != '\0') {
+                if (udev_device->sysname[len] == '!')
+                        udev_device->sysname[len] = '/';
+                len++;
+        }
+
+        /* trailing number */
+        while (len > 0 && isdigit(udev_device->sysname[--len]))
+                udev_device->sysnum = &udev_device->sysname[len];
+
+        /* sysname is completely numeric */
+        if (len == 0)
+                udev_device->sysnum = NULL;
+
+        return 0;
+}
+
+int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode)
+{
+        free(udev_device->devnode);
+        if (devnode[0] != '/') {
+                if (asprintf(&udev_device->devnode, "/dev/%s", devnode) < 0)
+                        udev_device->devnode = NULL;
+        } else {
+                udev_device->devnode = strdup(devnode);
+        }
+        if (udev_device->devnode == NULL)
+                return -ENOMEM;
+        udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode);
+        return 0;
+}
+
+int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink)
+{
+        struct udev_list_entry *list_entry;
+
+        udev_device->devlinks_uptodate = false;
+        list_entry = udev_list_entry_add(&udev_device->devlinks_list, devlink, NULL);
+        if (list_entry == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+const char *udev_device_get_id_filename(struct udev_device *udev_device)
+{
+        if (udev_device->id_filename == NULL) {
+                if (udev_device_get_subsystem(udev_device) == NULL)
+                        return NULL;
+
+                if (major(udev_device_get_devnum(udev_device)) > 0) {
+                        /* use dev_t -- b259:131072, c254:0 */
+                        if (asprintf(&udev_device->id_filename, "%c%u:%u",
+                                     streq(udev_device_get_subsystem(udev_device), "block") ? 'b' : 'c',
+                                     major(udev_device_get_devnum(udev_device)),
+                                     minor(udev_device_get_devnum(udev_device))) < 0)
+                                udev_device->id_filename = NULL;
+                } else if (udev_device_get_ifindex(udev_device) > 0) {
+                        /* use netdev ifindex -- n3 */
+                        if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0)
+                                udev_device->id_filename = NULL;
+                } else {
+                        /*
+                         * use $subsys:$syname -- pci:0000:00:1f.2
+                         * sysname() has '!' translated, get it from devpath
+                         */
+                        const char *sysname;
+                        sysname = strrchr(udev_device->devpath, '/');
+                        if (sysname == NULL)
+                                return NULL;
+                        sysname = &sysname[1];
+                        if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0)
+                                udev_device->id_filename = NULL;
+                }
+        }
+        return udev_device->id_filename;
+}
+
+/**
+ * udev_device_get_is_initialized:
+ * @udev_device: udev device
+ *
+ * Check if udev has already handled the device and has set up
+ * device node permissions and context, or has renamed a network
+ * device.
+ *
+ * This is only implemented for devices with a device node
+ * or network interfaces. All other devices return 1 here.
+ *
+ * Returns: 1 if the device is set up. 0 otherwise.
+ **/
+_public_ int udev_device_get_is_initialized(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_db(udev_device, NULL);
+        return udev_device->is_initialized;
+}
+
+void udev_device_set_is_initialized(struct udev_device *udev_device)
+{
+        udev_device->is_initialized = true;
+}
+
+int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
+{
+        if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL)
+                return -EINVAL;
+        udev_device->tags_uptodate = false;
+        if (udev_list_entry_add(&udev_device->tags_list, tag, NULL) != NULL)
+                return 0;
+        return -ENOMEM;
+}
+
+void udev_device_cleanup_tags_list(struct udev_device *udev_device)
+{
+        udev_device->tags_uptodate = false;
+        udev_list_cleanup(&udev_device->tags_list);
+}
+
+/**
+ * udev_device_get_tags_list_entry:
+ * @udev_device: udev device
+ *
+ * Retrieve the list of tags attached to the udev device. The next
+ * list entry can be retrieved with udev_list_entry_get_next(),
+ * which returns #NULL if no more entries exist. The tag string
+ * can be retrieved from the list entry by udev_list_entry_get_name().
+ *
+ * Returns: the first entry of the tag list
+ **/
+_public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device)
+{
+        if (udev_device == NULL)
+                return NULL;
+        if (!udev_device->info_loaded)
+                udev_device_read_db(udev_device, NULL);
+        return udev_list_get_entry(&udev_device->tags_list);
+}
+
+/**
+ * udev_device_has_tag:
+ * @udev_device: udev device
+ * @tag: tag name
+ *
+ * Check if a given device has a certain tag associated.
+ *
+ * Returns: 1 if the tag is found. 0 otherwise.
+ **/
+_public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
+{
+        struct udev_list_entry *list_entry;
+
+        if (udev_device == NULL)
+                return false;
+        if (!udev_device->info_loaded)
+                udev_device_read_db(udev_device, NULL);
+        list_entry = udev_device_get_tags_list_entry(udev_device);
+        if (udev_list_entry_get_by_name(list_entry, tag) != NULL)
+                return true;
+        return false;
+}
+
+#define ENVP_SIZE                        128
+#define MONITOR_BUF_SIZE                4096
+static int update_envp_monitor_buf(struct udev_device *udev_device)
+{
+        struct udev_list_entry *list_entry;
+        char *s;
+        size_t l;
+        unsigned int i;
+
+        /* monitor buffer of property strings */
+        free(udev_device->monitor_buf);
+        udev_device->monitor_buf_len = 0;
+        udev_device->monitor_buf = malloc(MONITOR_BUF_SIZE);
+        if (udev_device->monitor_buf == NULL)
+                return -ENOMEM;
+
+        /* envp array, strings will point into monitor buffer */
+        if (udev_device->envp == NULL)
+                udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE);
+        if (udev_device->envp == NULL)
+                return -ENOMEM;
+
+        i = 0;
+        s = udev_device->monitor_buf;
+        l = MONITOR_BUF_SIZE;
+        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) {
+                const char *key;
+
+                key = udev_list_entry_get_name(list_entry);
+                /* skip private variables */
+                if (key[0] == '.')
+                        continue;
+
+                /* add string to envp array */
+                udev_device->envp[i++] = s;
+                if (i+1 >= ENVP_SIZE)
+                        return -EINVAL;
+
+                /* add property string to monitor buffer */
+                l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL);
+                if (l == 0)
+                        return -EINVAL;
+                /* advance past the trailing '\0' that util_strpcpyl() guarantees */
+                s++;
+                l--;
+        }
+        udev_device->envp[i] = NULL;
+        udev_device->monitor_buf_len = s - udev_device->monitor_buf;
+        udev_device->envp_uptodate = true;
+        return 0;
+}
+
+char **udev_device_get_properties_envp(struct udev_device *udev_device)
+{
+        if (!udev_device->envp_uptodate)
+                if (update_envp_monitor_buf(udev_device) != 0)
+                        return NULL;
+        return udev_device->envp;
+}
+
+ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf)
+{
+        if (!udev_device->envp_uptodate)
+                if (update_envp_monitor_buf(udev_device) != 0)
+                        return -EINVAL;
+        *buf = udev_device->monitor_buf;
+        return udev_device->monitor_buf_len;
+}
+
+int udev_device_set_action(struct udev_device *udev_device, const char *action)
+{
+        free(udev_device->action);
+        udev_device->action = strdup(action);
+        if (udev_device->action == NULL)
+                return -ENOMEM;
+        udev_device_add_property(udev_device, "ACTION", udev_device->action);
+        return 0;
+}
+
+int udev_device_get_devlink_priority(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_db(udev_device, NULL);
+        return udev_device->devlink_priority;
+}
+
+int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio)
+{
+         udev_device->devlink_priority = prio;
+        return 0;
+}
+
+int udev_device_get_watch_handle(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_db(udev_device, NULL);
+        return udev_device->watch_handle;
+}
+
+int udev_device_set_watch_handle(struct udev_device *udev_device, int handle)
+{
+        udev_device->watch_handle = handle;
+        return 0;
+}
+
+bool udev_device_get_db_persist(struct udev_device *udev_device)
+{
+        return udev_device->db_persist;
+}
+
+void udev_device_set_db_persist(struct udev_device *udev_device)
+{
+        udev_device->db_persist = true;
+}
diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c
new file mode 100644 (file)
index 0000000..6a5f4e0
--- /dev/null
@@ -0,0 +1,958 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <fnmatch.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+/**
+ * SECTION:libudev-enumerate
+ * @short_description: lookup and sort sys devices
+ *
+ * Lookup devices in the sys filesystem, filter devices by properties,
+ * and return a sorted list of devices.
+ */
+
+struct syspath {
+        char *syspath;
+        size_t len;
+};
+
+/**
+ * udev_enumerate:
+ *
+ * Opaque object representing one device lookup/sort context.
+ */
+struct udev_enumerate {
+        struct udev *udev;
+        int refcount;
+        struct udev_list sysattr_match_list;
+        struct udev_list sysattr_nomatch_list;
+        struct udev_list subsystem_match_list;
+        struct udev_list subsystem_nomatch_list;
+        struct udev_list sysname_match_list;
+        struct udev_list properties_match_list;
+        struct udev_list tags_match_list;
+        struct udev_device *parent_match;
+        struct udev_list devices_list;
+        struct syspath *devices;
+        unsigned int devices_cur;
+        unsigned int devices_max;
+        bool devices_uptodate:1;
+        bool match_is_initialized;
+};
+
+/**
+ * udev_enumerate_new:
+ * @udev: udev library context
+ *
+ * Create an enumeration context to scan /sys.
+ *
+ * Returns: an enumeration context.
+ **/
+_public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev)
+{
+        struct udev_enumerate *udev_enumerate;
+
+        if (udev == NULL)
+                return NULL;
+        udev_enumerate = calloc(1, sizeof(struct udev_enumerate));
+        if (udev_enumerate == NULL)
+                return NULL;
+        udev_enumerate->refcount = 1;
+        udev_enumerate->udev = udev;
+        udev_list_init(udev, &udev_enumerate->sysattr_match_list, false);
+        udev_list_init(udev, &udev_enumerate->sysattr_nomatch_list, false);
+        udev_list_init(udev, &udev_enumerate->subsystem_match_list, true);
+        udev_list_init(udev, &udev_enumerate->subsystem_nomatch_list, true);
+        udev_list_init(udev, &udev_enumerate->sysname_match_list, true);
+        udev_list_init(udev, &udev_enumerate->properties_match_list, false);
+        udev_list_init(udev, &udev_enumerate->tags_match_list, true);
+        udev_list_init(udev, &udev_enumerate->devices_list, false);
+        return udev_enumerate;
+}
+
+/**
+ * udev_enumerate_ref:
+ * @udev_enumerate: context
+ *
+ * Take a reference of a enumeration context.
+ *
+ * Returns: the passed enumeration context
+ **/
+_public_ struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate)
+{
+        if (udev_enumerate == NULL)
+                return NULL;
+        udev_enumerate->refcount++;
+        return udev_enumerate;
+}
+
+/**
+ * udev_enumerate_unref:
+ * @udev_enumerate: context
+ *
+ * Drop a reference of an enumeration context. If the refcount reaches zero,
+ * all resources of the enumeration context will be released.
+ *
+ * Returns: the passed enumeration context if it has still an active reference, or #NULL otherwise.
+ **/
+_public_ struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate)
+{
+        unsigned int i;
+
+        if (udev_enumerate == NULL)
+                return NULL;
+        udev_enumerate->refcount--;
+        if (udev_enumerate->refcount > 0)
+                return udev_enumerate;
+        udev_list_cleanup(&udev_enumerate->sysattr_match_list);
+        udev_list_cleanup(&udev_enumerate->sysattr_nomatch_list);
+        udev_list_cleanup(&udev_enumerate->subsystem_match_list);
+        udev_list_cleanup(&udev_enumerate->subsystem_nomatch_list);
+        udev_list_cleanup(&udev_enumerate->sysname_match_list);
+        udev_list_cleanup(&udev_enumerate->properties_match_list);
+        udev_list_cleanup(&udev_enumerate->tags_match_list);
+        udev_device_unref(udev_enumerate->parent_match);
+        udev_list_cleanup(&udev_enumerate->devices_list);
+        for (i = 0; i < udev_enumerate->devices_cur; i++)
+                free(udev_enumerate->devices[i].syspath);
+        free(udev_enumerate->devices);
+        free(udev_enumerate);
+        return NULL;
+}
+
+/**
+ * udev_enumerate_get_udev:
+ * @udev_enumerate: context
+ *
+ * Get the udev library context.
+ *
+ * Returns: a pointer to the context.
+ */
+_public_ struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate)
+{
+        if (udev_enumerate == NULL)
+                return NULL;
+        return udev_enumerate->udev;
+}
+
+static int syspath_add(struct udev_enumerate *udev_enumerate, const char *syspath)
+{
+        char *path;
+        struct syspath *entry;
+
+        /* double array size if needed */
+        if (udev_enumerate->devices_cur >= udev_enumerate->devices_max) {
+                struct syspath *buf;
+                unsigned int add;
+
+                add = udev_enumerate->devices_max;
+                if (add < 1024)
+                        add = 1024;
+                buf = realloc(udev_enumerate->devices, (udev_enumerate->devices_max + add) * sizeof(struct syspath));
+                if (buf == NULL)
+                        return -ENOMEM;
+                udev_enumerate->devices = buf;
+                udev_enumerate->devices_max += add;
+        }
+
+        path = strdup(syspath);
+        if (path == NULL)
+                return -ENOMEM;
+        entry = &udev_enumerate->devices[udev_enumerate->devices_cur];
+        entry->syspath = path;
+        entry->len = strlen(path);
+        udev_enumerate->devices_cur++;
+        udev_enumerate->devices_uptodate = false;
+        return 0;
+}
+
+static int syspath_cmp(const void *p1, const void *p2)
+{
+        const struct syspath *path1 = p1;
+        const struct syspath *path2 = p2;
+        size_t len;
+        int ret;
+
+        len = MIN(path1->len, path2->len);
+        ret = memcmp(path1->syspath, path2->syspath, len);
+        if (ret == 0) {
+                if (path1->len < path2->len)
+                        ret = -1;
+                else if (path1->len > path2->len)
+                        ret = 1;
+        }
+        return ret;
+}
+
+/* For devices that should be moved to the absolute end of the list */
+static bool devices_delay_end(struct udev *udev, const char *syspath)
+{
+        static const char *delay_device_list[] = {
+                "/block/md",
+                "/block/dm-",
+                NULL
+        };
+        int i;
+
+        for (i = 0; delay_device_list[i] != NULL; i++) {
+                if (strstr(syspath + strlen("/sys"), delay_device_list[i]) != NULL)
+                        return true;
+        }
+        return false;
+}
+
+/* For devices that should just be moved a little bit later, just
+ * before the point where some common path prefix changes. Returns the
+ * number of characters that make up that common prefix */
+static size_t devices_delay_later(struct udev *udev, const char *syspath)
+{
+        const char *c;
+
+        /* For sound cards the control device must be enumerated last
+         * to make sure it's the final device node that gets ACLs
+         * applied. Applications rely on this fact and use ACL changes
+         * on the control node as an indicator that the ACL change of
+         * the entire sound card completed. The kernel makes this
+         * guarantee when creating those devices, and hence we should
+         * too when enumerating them. */
+
+        if ((c = strstr(syspath, "/sound/card"))) {
+                c += 11;
+                c += strcspn(c, "/");
+
+                if (startswith(c, "/controlC"))
+                        return c - syspath + 1;
+        }
+
+        return 0;
+}
+
+/**
+ * udev_enumerate_get_list_entry:
+ * @udev_enumerate: context
+ *
+ * Get the first entry of the sorted list of device paths.
+ *
+ * Returns: a udev_list_entry.
+ */
+_public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate)
+{
+        if (udev_enumerate == NULL)
+                return NULL;
+        if (!udev_enumerate->devices_uptodate) {
+                unsigned int i;
+                unsigned int max;
+                struct syspath *prev = NULL, *move_later = NULL;
+                size_t move_later_prefix = 0;
+
+                udev_list_cleanup(&udev_enumerate->devices_list);
+                qsort(udev_enumerate->devices, udev_enumerate->devices_cur, sizeof(struct syspath), syspath_cmp);
+
+                max = udev_enumerate->devices_cur;
+                for (i = 0; i < max; i++) {
+                        struct syspath *entry = &udev_enumerate->devices[i];
+
+                        /* skip duplicated entries */
+                        if (prev != NULL &&
+                            entry->len == prev->len &&
+                            memcmp(entry->syspath, prev->syspath, entry->len) == 0)
+                                continue;
+                        prev = entry;
+
+                        /* skip to be delayed devices, and add them to the end of the list */
+                        if (devices_delay_end(udev_enumerate->udev, entry->syspath)) {
+                                syspath_add(udev_enumerate, entry->syspath);
+                                /* need to update prev here for the case realloc() gives a different address */
+                                prev = &udev_enumerate->devices[i];
+                                continue;
+                        }
+
+                        /* skip to be delayed devices, and move the to
+                         * the point where the prefix changes. We can
+                         * only move one item at a time. */
+                        if (!move_later) {
+                                move_later_prefix = devices_delay_later(udev_enumerate->udev, entry->syspath);
+
+                                if (move_later_prefix > 0) {
+                                        move_later = entry;
+                                        continue;
+                                }
+                        }
+
+                        if (move_later &&
+                            strncmp(entry->syspath, move_later->syspath, move_later_prefix) != 0) {
+
+                                udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL);
+                                move_later = NULL;
+                        }
+
+                        udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL);
+                }
+
+                if (move_later)
+                        udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL);
+
+                /* add and cleanup delayed devices from end of list */
+                for (i = max; i < udev_enumerate->devices_cur; i++) {
+                        struct syspath *entry = &udev_enumerate->devices[i];
+
+                        udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL);
+                        free(entry->syspath);
+                }
+                udev_enumerate->devices_cur = max;
+
+                udev_enumerate->devices_uptodate = true;
+        }
+        return udev_list_get_entry(&udev_enumerate->devices_list);
+}
+
+/**
+ * udev_enumerate_add_match_subsystem:
+ * @udev_enumerate: context
+ * @subsystem: filter for a subsystem of the device to include in the list
+ *
+ * Match only devices belonging to a certain kernel subsystem.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (subsystem == NULL)
+                return 0;
+        if (udev_list_entry_add(&udev_enumerate->subsystem_match_list, subsystem, NULL) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+/**
+ * udev_enumerate_add_nomatch_subsystem:
+ * @udev_enumerate: context
+ * @subsystem: filter for a subsystem of the device to exclude from the list
+ *
+ * Match only devices not belonging to a certain kernel subsystem.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (subsystem == NULL)
+                return 0;
+        if (udev_list_entry_add(&udev_enumerate->subsystem_nomatch_list, subsystem, NULL) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+/**
+ * udev_enumerate_add_match_sysattr:
+ * @udev_enumerate: context
+ * @sysattr: filter for a sys attribute at the device to include in the list
+ * @value: optional value of the sys attribute
+ *
+ * Match only devices with a certain /sys device attribute.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (sysattr == NULL)
+                return 0;
+        if (udev_list_entry_add(&udev_enumerate->sysattr_match_list, sysattr, value) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+/**
+ * udev_enumerate_add_nomatch_sysattr:
+ * @udev_enumerate: context
+ * @sysattr: filter for a sys attribute at the device to exclude from the list
+ * @value: optional value of the sys attribute
+ *
+ * Match only devices not having a certain /sys device attribute.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (sysattr == NULL)
+                return 0;
+        if (udev_list_entry_add(&udev_enumerate->sysattr_nomatch_list, sysattr, value) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+static int match_sysattr_value(struct udev_device *dev, const char *sysattr, const char *match_val)
+{
+        const char *val = NULL;
+        bool match = false;
+
+        val = udev_device_get_sysattr_value(dev, sysattr);
+        if (val == NULL)
+                goto exit;
+        if (match_val == NULL) {
+                match = true;
+                goto exit;
+        }
+        if (fnmatch(match_val, val, 0) == 0) {
+                match = true;
+                goto exit;
+        }
+exit:
+        return match;
+}
+
+/**
+ * udev_enumerate_add_match_property:
+ * @udev_enumerate: context
+ * @property: filter for a property of the device to include in the list
+ * @value: value of the property
+ *
+ * Match only devices with a certain property.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (property == NULL)
+                return 0;
+        if (udev_list_entry_add(&udev_enumerate->properties_match_list, property, value) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+/**
+ * udev_enumerate_add_match_tag:
+ * @udev_enumerate: context
+ * @tag: filter for a tag of the device to include in the list
+ *
+ * Match only devices with a certain tag.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (tag == NULL)
+                return 0;
+        if (udev_list_entry_add(&udev_enumerate->tags_match_list, tag, NULL) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+/**
+ * udev_enumerate_add_match_parent:
+ * @udev_enumerate: context
+ * @parent: parent device where to start searching
+ *
+ * Return the devices on the subtree of one given device. The parent
+ * itself is included in the list.
+ *
+ * A reference for the device is held until the udev_enumerate context
+ * is cleaned up.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (parent == NULL)
+                return 0;
+        if (udev_enumerate->parent_match != NULL)
+                udev_device_unref(udev_enumerate->parent_match);
+        udev_enumerate->parent_match = udev_device_ref(parent);
+        return 0;
+}
+
+/**
+ * udev_enumerate_add_match_is_initialized:
+ * @udev_enumerate: context
+ *
+ * Match only devices which udev has set up already. This makes
+ * sure, that the device node permissions and context are properly set
+ * and that network devices are fully renamed.
+ *
+ * Usually, devices which are found in the kernel but not already
+ * handled by udev, have still pending events. Services should subscribe
+ * to monitor events and wait for these devices to become ready, instead
+ * of using uninitialized devices.
+ *
+ * For now, this will not affect devices which do not have a device node
+ * and are not network interfaces.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        udev_enumerate->match_is_initialized = true;
+        return 0;
+}
+
+/**
+ * udev_enumerate_add_match_sysname:
+ * @udev_enumerate: context
+ * @sysname: filter for the name of the device to include in the list
+ *
+ * Match only devices with a given /sys device name.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (sysname == NULL)
+                return 0;
+        if (udev_list_entry_add(&udev_enumerate->sysname_match_list, sysname, NULL) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+static bool match_sysattr(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
+{
+        struct udev_list_entry *list_entry;
+
+        /* skip list */
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_nomatch_list)) {
+                if (match_sysattr_value(dev, udev_list_entry_get_name(list_entry),
+                                        udev_list_entry_get_value(list_entry)))
+                        return false;
+        }
+        /* include list */
+        if (udev_list_get_entry(&udev_enumerate->sysattr_match_list) != NULL) {
+                udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_match_list)) {
+                        /* anything that does not match, will make it FALSE */
+                        if (!match_sysattr_value(dev, udev_list_entry_get_name(list_entry),
+                                                 udev_list_entry_get_value(list_entry)))
+                                return false;
+                }
+                return true;
+        }
+        return true;
+}
+
+static bool match_property(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
+{
+        struct udev_list_entry *list_entry;
+        bool match = false;
+
+        /* no match always matches */
+        if (udev_list_get_entry(&udev_enumerate->properties_match_list) == NULL)
+                return true;
+
+        /* loop over matches */
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->properties_match_list)) {
+                const char *match_key = udev_list_entry_get_name(list_entry);
+                const char *match_value = udev_list_entry_get_value(list_entry);
+                struct udev_list_entry *property_entry;
+
+                /* loop over device properties */
+                udev_list_entry_foreach(property_entry, udev_device_get_properties_list_entry(dev)) {
+                        const char *dev_key = udev_list_entry_get_name(property_entry);
+                        const char *dev_value = udev_list_entry_get_value(property_entry);
+
+                        if (fnmatch(match_key, dev_key, 0) != 0)
+                                continue;
+                        if (match_value == NULL && dev_value == NULL) {
+                                match = true;
+                                goto out;
+                        }
+                        if (match_value == NULL || dev_value == NULL)
+                                continue;
+                        if (fnmatch(match_value, dev_value, 0) == 0) {
+                                match = true;
+                                goto out;
+                        }
+                }
+        }
+out:
+        return match;
+}
+
+static bool match_tag(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
+{
+        struct udev_list_entry *list_entry;
+
+        /* no match always matches */
+        if (udev_list_get_entry(&udev_enumerate->tags_match_list) == NULL)
+                return true;
+
+        /* loop over matches */
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list))
+                if (!udev_device_has_tag(dev, udev_list_entry_get_name(list_entry)))
+                        return false;
+
+        return true;
+}
+
+static bool match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
+{
+        if (udev_enumerate->parent_match == NULL)
+                return true;
+
+        return startswith(udev_device_get_devpath(dev), udev_device_get_devpath(udev_enumerate->parent_match));
+}
+
+static bool match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname)
+{
+        struct udev_list_entry *list_entry;
+
+        if (udev_list_get_entry(&udev_enumerate->sysname_match_list) == NULL)
+                return true;
+
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysname_match_list)) {
+                if (fnmatch(udev_list_entry_get_name(list_entry), sysname, 0) != 0)
+                        continue;
+                return true;
+        }
+        return false;
+}
+
+static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate,
+                                    const char *basedir, const char *subdir1, const char *subdir2)
+{
+        char path[UTIL_PATH_SIZE];
+        size_t l;
+        char *s;
+        DIR *dir;
+        struct dirent *dent;
+
+        s = path;
+        l = util_strpcpyl(&s, sizeof(path), "/sys/", basedir, NULL);
+        if (subdir1 != NULL)
+                l = util_strpcpyl(&s, l, "/", subdir1, NULL);
+        if (subdir2 != NULL)
+                util_strpcpyl(&s, l, "/", subdir2, NULL);
+        dir = opendir(path);
+        if (dir == NULL)
+                return -ENOENT;
+        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                char syspath[UTIL_PATH_SIZE];
+                struct udev_device *dev;
+
+                if (dent->d_name[0] == '.')
+                        continue;
+
+                if (!match_sysname(udev_enumerate, dent->d_name))
+                        continue;
+
+                util_strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL);
+                dev = udev_device_new_from_syspath(udev_enumerate->udev, syspath);
+                if (dev == NULL)
+                        continue;
+
+                if (udev_enumerate->match_is_initialized) {
+                        /*
+                         * All devices with a device node or network interfaces
+                         * possibly need udev to adjust the device node permission
+                         * or context, or rename the interface before it can be
+                         * reliably used from other processes.
+                         *
+                         * For now, we can only check these types of devices, we
+                         * might not store a database, and have no way to find out
+                         * for all other types of devices.
+                         */
+                        if (!udev_device_get_is_initialized(dev) &&
+                            (major(udev_device_get_devnum(dev)) > 0 || udev_device_get_ifindex(dev) > 0))
+                                goto nomatch;
+                }
+                if (!match_parent(udev_enumerate, dev))
+                        goto nomatch;
+                if (!match_tag(udev_enumerate, dev))
+                        goto nomatch;
+                if (!match_property(udev_enumerate, dev))
+                        goto nomatch;
+                if (!match_sysattr(udev_enumerate, dev))
+                        goto nomatch;
+
+                syspath_add(udev_enumerate, udev_device_get_syspath(dev));
+nomatch:
+                udev_device_unref(dev);
+        }
+        closedir(dir);
+        return 0;
+}
+
+static bool match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
+{
+        struct udev_list_entry *list_entry;
+
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_nomatch_list)) {
+                if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0)
+                        return false;
+        }
+        if (udev_list_get_entry(&udev_enumerate->subsystem_match_list) != NULL) {
+                udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_match_list)) {
+                        if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0)
+                                return true;
+                }
+                return false;
+        }
+        return true;
+}
+
+static int scan_dir(struct udev_enumerate *udev_enumerate, const char *basedir, const char *subdir, const char *subsystem)
+{
+        char path[UTIL_PATH_SIZE];
+        DIR *dir;
+        struct dirent *dent;
+
+        util_strscpyl(path, sizeof(path), "/sys/", basedir, NULL);
+        dir = opendir(path);
+        if (dir == NULL)
+                return -1;
+        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                if (dent->d_name[0] == '.')
+                        continue;
+                if (!match_subsystem(udev_enumerate, subsystem != NULL ? subsystem : dent->d_name))
+                        continue;
+                scan_dir_and_add_devices(udev_enumerate, basedir, dent->d_name, subdir);
+        }
+        closedir(dir);
+        return 0;
+}
+
+/**
+ * udev_enumerate_add_syspath:
+ * @udev_enumerate: context
+ * @syspath: path of a device
+ *
+ * Add a device to the list of devices, to retrieve it back sorted in dependency order.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath)
+{
+        struct udev_device *udev_device;
+
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+        if (syspath == NULL)
+                return 0;
+        /* resolve to real syspath */
+        udev_device = udev_device_new_from_syspath(udev_enumerate->udev, syspath);
+        if (udev_device == NULL)
+                return -EINVAL;
+        syspath_add(udev_enumerate, udev_device_get_syspath(udev_device));
+        udev_device_unref(udev_device);
+        return 0;
+}
+
+static int scan_devices_tags(struct udev_enumerate *udev_enumerate)
+{
+        struct udev_list_entry *list_entry;
+
+        /* scan only tagged devices, use tags reverse-index, instead of searching all devices in /sys */
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) {
+                DIR *dir;
+                struct dirent *dent;
+                char path[UTIL_PATH_SIZE];
+
+                util_strscpyl(path, sizeof(path), "/run/udev/tags/", udev_list_entry_get_name(list_entry), NULL);
+                dir = opendir(path);
+                if (dir == NULL)
+                        continue;
+                for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                        struct udev_device *dev;
+
+                        if (dent->d_name[0] == '.')
+                                continue;
+
+                        dev = udev_device_new_from_device_id(udev_enumerate->udev, dent->d_name);
+                        if (dev == NULL)
+                                continue;
+
+                        if (!match_subsystem(udev_enumerate, udev_device_get_subsystem(dev)))
+                                goto nomatch;
+                        if (!match_sysname(udev_enumerate, udev_device_get_sysname(dev)))
+                                goto nomatch;
+                        if (!match_parent(udev_enumerate, dev))
+                                goto nomatch;
+                        if (!match_property(udev_enumerate, dev))
+                                goto nomatch;
+                        if (!match_sysattr(udev_enumerate, dev))
+                                goto nomatch;
+
+                        syspath_add(udev_enumerate, udev_device_get_syspath(dev));
+nomatch:
+                        udev_device_unref(dev);
+                }
+                closedir(dir);
+        }
+        return 0;
+}
+
+static int parent_add_child(struct udev_enumerate *enumerate, const char *path)
+{
+        struct udev_device *dev;
+
+        dev = udev_device_new_from_syspath(enumerate->udev, path);
+        if (dev == NULL)
+                return -ENODEV;
+
+        if (!match_subsystem(enumerate, udev_device_get_subsystem(dev)))
+                return 0;
+        if (!match_sysname(enumerate, udev_device_get_sysname(dev)))
+                return 0;
+        if (!match_property(enumerate, dev))
+                return 0;
+        if (!match_sysattr(enumerate, dev))
+                return 0;
+
+        syspath_add(enumerate, udev_device_get_syspath(dev));
+        udev_device_unref(dev);
+        return 1;
+}
+
+static int parent_crawl_children(struct udev_enumerate *enumerate, const char *path, int maxdepth)
+{
+        DIR *d;
+        struct dirent *dent;
+
+        d = opendir(path);
+        if (d == NULL)
+                return -errno;
+
+        for (dent = readdir(d); dent != NULL; dent = readdir(d)) {
+                char *child;
+
+                if (dent->d_name[0] == '.')
+                        continue;
+                if (dent->d_type != DT_DIR)
+                        continue;
+                if (asprintf(&child, "%s/%s", path, dent->d_name) < 0)
+                        continue;
+                parent_add_child(enumerate, child);
+                if (maxdepth > 0)
+                        parent_crawl_children(enumerate, child, maxdepth-1);
+                free(child);
+        }
+
+        closedir(d);
+        return 0;
+}
+
+static int scan_devices_children(struct udev_enumerate *enumerate)
+{
+        const char *path;
+
+        path = udev_device_get_syspath(enumerate->parent_match);
+        parent_add_child(enumerate, path);
+        return parent_crawl_children(enumerate, path, 256);
+}
+
+static int scan_devices_all(struct udev_enumerate *udev_enumerate)
+{
+        struct stat statbuf;
+
+        if (stat("/sys/subsystem", &statbuf) == 0) {
+                /* we have /subsystem/, forget all the old stuff */
+                scan_dir(udev_enumerate, "subsystem", "devices", NULL);
+        } else {
+                scan_dir(udev_enumerate, "bus", "devices", NULL);
+                scan_dir(udev_enumerate, "class", NULL, NULL);
+        }
+        return 0;
+}
+
+/**
+ * udev_enumerate_scan_devices:
+ * @udev_enumerate: udev enumeration context
+ *
+ * Scan /sys for all devices which match the given filters. No matches
+ * will return all currently available devices.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ **/
+_public_ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
+{
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+
+        /* efficiently lookup tags only, we maintain a reverse-index */
+        if (udev_list_get_entry(&udev_enumerate->tags_match_list) != NULL)
+                return scan_devices_tags(udev_enumerate);
+
+        /* walk the subtree of one parent device only */
+        if (udev_enumerate->parent_match != NULL)
+                return scan_devices_children(udev_enumerate);
+
+        /* scan devices of all subsystems */
+        return scan_devices_all(udev_enumerate);
+}
+
+/**
+ * udev_enumerate_scan_subsystems:
+ * @udev_enumerate: udev enumeration context
+ *
+ * Scan /sys for all kernel subsystems, including buses, classes, drivers.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ **/
+_public_ int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate)
+{
+        struct stat statbuf;
+        const char *subsysdir;
+
+        if (udev_enumerate == NULL)
+                return -EINVAL;
+
+        /* all kernel modules */
+        if (match_subsystem(udev_enumerate, "module"))
+                scan_dir_and_add_devices(udev_enumerate, "module", NULL, NULL);
+
+        if (stat("/sys/subsystem", &statbuf) == 0)
+                subsysdir = "subsystem";
+        else
+                subsysdir = "bus";
+
+        /* all subsystems (only buses support coldplug) */
+        if (match_subsystem(udev_enumerate, "subsystem"))
+                scan_dir_and_add_devices(udev_enumerate, subsysdir, NULL, NULL);
+
+        /* all subsystem drivers */
+        if (match_subsystem(udev_enumerate, "drivers"))
+                scan_dir(udev_enumerate, subsysdir, "drivers", "drivers");
+        return 0;
+}
diff --git a/src/libudev/libudev-hwdb-def.h b/src/libudev/libudev-hwdb-def.h
new file mode 100644 (file)
index 0000000..b76a13f
--- /dev/null
@@ -0,0 +1,74 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifndef _LIBUDEV_HWDB_DEF_H_
+#define _LIBUDEV_HWDB_DEF_H_
+
+#include "sparse-endian.h"
+
+#define HWDB_SIG { 'K', 'S', 'L', 'P', 'H', 'H', 'R', 'H' }
+
+/* on-disk trie objects */
+struct trie_header_f {
+        uint8_t signature[8];
+
+        /* version of tool which created the file */
+        le64_t tool_version;
+        le64_t file_size;
+
+        /* size of structures to allow them to grow */
+        le64_t header_size;
+        le64_t node_size;
+        le64_t child_entry_size;
+        le64_t value_entry_size;
+
+        /* offset of the root trie node */
+        le64_t nodes_root_off;
+
+        /* size of the nodes and string section */
+        le64_t nodes_len;
+        le64_t strings_len;
+} _packed_;
+
+struct trie_node_f {
+        /* prefix of lookup string, shared by all children  */
+        le64_t prefix_off;
+        /* size of children entry array appended to the node */
+        uint8_t children_count;
+        uint8_t padding[7];
+        /* size of value entry array appended to the node */
+        le64_t values_count;
+} _packed_;
+
+/* array of child entries, follows directly the node record */
+struct trie_child_entry_f {
+        /* index of the child node */
+        uint8_t c;
+        uint8_t padding[7];
+        /* offset of the child node */
+        le64_t child_off;
+} _packed_;
+
+/* array of value entries, follows directly the node record/child array */
+struct trie_value_entry_f {
+        le64_t key_off;
+        le64_t value_off;
+} _packed_;
+
+#endif
diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c
new file mode 100644 (file)
index 0000000..09096c4
--- /dev/null
@@ -0,0 +1,392 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers <kay@vrfy.org>
+  Copyright 2008 Alan Jenkins <alan.christopher.jenkins@googlemail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <fnmatch.h>
+#include <getopt.h>
+#include <sys/mman.h>
+
+#include "libudev-private.h"
+#include "libudev-hwdb-def.h"
+
+/**
+ * SECTION:libudev-hwdb
+ * @short_description: retrieve properties from the hardware database
+ *
+ * Libudev hardware database interface.
+ */
+
+/**
+ * udev_hwdb:
+ *
+ * Opaque object representing the hardware database.
+ */
+struct udev_hwdb {
+        struct udev *udev;
+        int refcount;
+
+        FILE *f;
+        struct stat st;
+        union {
+                struct trie_header_f *head;
+                const char *map;
+        };
+
+        struct udev_list properties_list;
+};
+
+struct linebuf {
+        char bytes[LINE_MAX];
+        size_t size;
+        size_t len;
+};
+
+static void linebuf_init(struct linebuf *buf) {
+        buf->size = 0;
+        buf->len = 0;
+}
+
+static const char *linebuf_get(struct linebuf *buf) {
+        if (buf->len + 1 >= sizeof(buf->bytes))
+                return NULL;
+        buf->bytes[buf->len] = '\0';
+        return buf->bytes;
+}
+
+static bool linebuf_add(struct linebuf *buf, const char *s, size_t len) {
+        if (buf->len + len >= sizeof(buf->bytes))
+                return false;
+        memcpy(buf->bytes + buf->len, s, len);
+        buf->len += len;
+        return true;
+}
+
+static bool linebuf_add_char(struct linebuf *buf, char c)
+{
+        if (buf->len + 1 >= sizeof(buf->bytes))
+                return false;
+        buf->bytes[buf->len++] = c;
+        return true;
+}
+
+static void linebuf_rem(struct linebuf *buf, size_t count) {
+        assert(buf->len >= count);
+        buf->len -= count;
+}
+
+static void linebuf_rem_char(struct linebuf *buf) {
+        linebuf_rem(buf, 1);
+}
+
+static const struct trie_child_entry_f *trie_node_children(struct udev_hwdb *hwdb, const struct trie_node_f *node) {
+        return (const struct trie_child_entry_f *)((const char *)node + le64toh(hwdb->head->node_size));
+}
+
+static const struct trie_value_entry_f *trie_node_values(struct udev_hwdb *hwdb, const struct trie_node_f *node) {
+        const char *base = (const char *)node;
+
+        base += le64toh(hwdb->head->node_size);
+        base += node->children_count * le64toh(hwdb->head->child_entry_size);
+        return (const struct trie_value_entry_f *)base;
+}
+
+static const struct trie_node_f *trie_node_from_off(struct udev_hwdb *hwdb, le64_t off) {
+        return (const struct trie_node_f *)(hwdb->map + le64toh(off));
+}
+
+static const char *trie_string(struct udev_hwdb *hwdb, le64_t off) {
+        return hwdb->map + le64toh(off);
+}
+
+static int trie_children_cmp_f(const void *v1, const void *v2) {
+        const struct trie_child_entry_f *n1 = v1;
+        const struct trie_child_entry_f *n2 = v2;
+
+        return n1->c - n2->c;
+}
+
+static const struct trie_node_f *node_lookup_f(struct udev_hwdb *hwdb, const struct trie_node_f *node, uint8_t c) {
+        struct trie_child_entry_f *child;
+        struct trie_child_entry_f search;
+
+        search.c = c;
+        child = bsearch(&search, trie_node_children(hwdb, node), node->children_count,
+                        le64toh(hwdb->head->child_entry_size), trie_children_cmp_f);
+        if (child)
+                return trie_node_from_off(hwdb, child->child_off);
+        return NULL;
+}
+
+static int hwdb_add_property(struct udev_hwdb *hwdb, const char *key, const char *value) {
+        /* TODO: add sub-matches (+) against DMI data */
+        if (key[0] != ' ')
+                return 0;
+        if (udev_list_entry_add(&hwdb->properties_list, key+1, value) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+static int trie_fnmatch_f(struct udev_hwdb *hwdb, const struct trie_node_f *node, size_t p,
+                          struct linebuf *buf, const char *search) {
+        size_t len;
+        size_t i;
+        const char *prefix;
+        int err;
+
+        prefix = trie_string(hwdb, node->prefix_off);
+        len = strlen(prefix + p);
+        linebuf_add(buf, prefix + p, len);
+
+        for (i = 0; i < node->children_count; i++) {
+                const struct trie_child_entry_f *child = &trie_node_children(hwdb, node)[i];
+
+                linebuf_add_char(buf, child->c);
+                err = trie_fnmatch_f(hwdb, trie_node_from_off(hwdb, child->child_off), 0, buf, search);
+                if (err < 0)
+                        return err;
+                linebuf_rem_char(buf);
+        }
+
+        if (le64toh(node->values_count) && fnmatch(linebuf_get(buf), search, 0) == 0)
+                for (i = 0; i < le64toh(node->values_count); i++) {
+                        err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[i].key_off),
+                                                trie_string(hwdb, trie_node_values(hwdb, node)[i].value_off));
+                        if (err < 0)
+                                return err;
+                }
+
+        linebuf_rem(buf, len);
+        return 0;
+}
+
+static int trie_search_f(struct udev_hwdb *hwdb, const char *search) {
+        struct linebuf buf;
+        const struct trie_node_f *node;
+        size_t i = 0;
+        int err;
+
+        linebuf_init(&buf);
+
+        node = trie_node_from_off(hwdb, hwdb->head->nodes_root_off);
+        while (node) {
+                const struct trie_node_f *child;
+                size_t p = 0;
+
+                if (node->prefix_off) {
+                        uint8_t c;
+
+                        for (; (c = trie_string(hwdb, node->prefix_off)[p]); p++) {
+                                if (c == '*' || c == '?' || c == '[')
+                                        return trie_fnmatch_f(hwdb, node, p, &buf, search + i + p);
+                                if (c != search[i + p])
+                                        return 0;
+                        }
+                        i += p;
+                }
+
+                child = node_lookup_f(hwdb, node, '*');
+                if (child) {
+                        linebuf_add_char(&buf, '*');
+                        err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
+                        if (err < 0)
+                                return err;
+                        linebuf_rem_char(&buf);
+                }
+
+                child = node_lookup_f(hwdb, node, '?');
+                if (child) {
+                        linebuf_add_char(&buf, '?');
+                        err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
+                        if (err < 0)
+                                return err;
+                        linebuf_rem_char(&buf);
+                }
+
+                child = node_lookup_f(hwdb, node, '[');
+                if (child) {
+                        linebuf_add_char(&buf, '[');
+                        err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i);
+                        if (err < 0)
+                                return err;
+                        linebuf_rem_char(&buf);
+                }
+
+                if (search[i] == '\0') {
+                        size_t n;
+
+                        for (n = 0; n < le64toh(node->values_count); n++) {
+                                err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[n].key_off),
+                                                        trie_string(hwdb, trie_node_values(hwdb, node)[n].value_off));
+                                if (err < 0)
+                                        return err;
+                        }
+                        return 0;
+                }
+
+                child = node_lookup_f(hwdb, node, search[i]);
+                node = child;
+                i++;
+        }
+        return 0;
+}
+
+/**
+ * udev_hwdb_new:
+ * @udev: udev library context
+ *
+ * Create a hardware database context to query properties for devices.
+ *
+ * Returns: a hwdb context.
+ **/
+_public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
+        struct udev_hwdb *hwdb;
+        const char sig[] = HWDB_SIG;
+
+        hwdb = new0(struct udev_hwdb, 1);
+        if (!hwdb)
+                return NULL;
+
+        hwdb->refcount = 1;
+        udev_list_init(udev, &hwdb->properties_list, true);
+
+        hwdb->f = fopen(HWDB_BIN, "re");
+        if (!hwdb->f) {
+                log_debug("error reading %s: %m", HWDB_BIN);
+                udev_hwdb_unref(hwdb);
+                return NULL;
+        }
+
+        if (fstat(fileno(hwdb->f), &hwdb->st) < 0 ||
+            (size_t)hwdb->st.st_size < offsetof(struct trie_header_f, strings_len) + 8) {
+                log_debug("error reading %s: %m", HWDB_BIN);
+                udev_hwdb_unref(hwdb);
+                return NULL;
+        }
+
+        hwdb->map = mmap(0, hwdb->st.st_size, PROT_READ, MAP_SHARED, fileno(hwdb->f), 0);
+        if (hwdb->map == MAP_FAILED) {
+                log_debug("error mapping %s: %m", HWDB_BIN);
+                udev_hwdb_unref(hwdb);
+                return NULL;
+        }
+
+        if (memcmp(hwdb->map, sig, sizeof(hwdb->head->signature)) != 0 ||
+            (size_t)hwdb->st.st_size != le64toh(hwdb->head->file_size)) {
+                log_debug("error recognizing the format of %s", HWDB_BIN);
+                udev_hwdb_unref(hwdb);
+                return NULL;
+        }
+
+        log_debug("=== trie on-disk ===\n");
+        log_debug("tool version:          %llu", (unsigned long long)le64toh(hwdb->head->tool_version));
+        log_debug("file size:        %8llu bytes\n", (unsigned long long)hwdb->st.st_size);
+        log_debug("header size       %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->header_size));
+        log_debug("strings           %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->strings_len));
+        log_debug("nodes             %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->nodes_len));
+        return hwdb;
+}
+
+/**
+ * udev_hwdb_ref:
+ * @hwdb: context
+ *
+ * Take a reference of a hwdb context.
+ *
+ * Returns: the passed enumeration context
+ **/
+_public_ struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb) {
+        if (!hwdb)
+                return NULL;
+        hwdb->refcount++;
+        return hwdb;
+}
+
+/**
+ * udev_hwdb_unref:
+ * @hwdb: context
+ *
+ * Drop a reference of a hwdb context. If the refcount reaches zero,
+ * all resources of the hwdb context will be released.
+ *
+ * Returns: the passed hwdb context if it has still an active reference, or #NULL otherwise.
+ **/
+_public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
+        if (!hwdb)
+                return NULL;
+        hwdb->refcount--;
+        if (hwdb->refcount > 0)
+                return hwdb;
+        if (hwdb->map)
+                munmap((void *)hwdb->map, hwdb->st.st_size);
+        if (hwdb->f)
+                fclose(hwdb->f);
+        udev_list_cleanup(&hwdb->properties_list);
+        free(hwdb);
+        return NULL;
+}
+
+bool udev_hwdb_validate(struct udev_hwdb *hwdb) {
+        struct stat st;
+
+        if (!hwdb)
+                return false;
+        if (!hwdb->f)
+                return false;
+        if (fstat(fileno(hwdb->f), &st) < 0)
+                return true;
+        if (timespec_load(&hwdb->st.st_mtim) != timespec_load(&st.st_mtim))
+                return true;
+        return false;
+}
+
+/**
+ * udev_hwdb_get_properties_list_entry:
+ * @hwdb: context
+ * @modalias: modalias string
+ * @flags: (unused)
+ *
+ * Lookup a matching device in the hardware database. The lookup key is a
+ * modalias string, whose formats are defined for the Linux kernel modules.
+ * Examples are: pci:v00008086d00001C2D*, usb:v04F2pB221*. The first entry
+ * of a list of retrieved properties is returned.
+ *
+ * Returns: a udev_list_entry.
+ */
+_public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) {
+        int err;
+
+        if (!hwdb || !hwdb->f) {
+                errno = EINVAL;
+                return NULL;
+        }
+
+        udev_list_cleanup(&hwdb->properties_list);
+        err = trie_search_f(hwdb, modalias);
+        if (err < 0) {
+                errno = -err;
+                return NULL;
+        }
+        return udev_list_get_entry(&hwdb->properties_list);
+}
diff --git a/src/libudev/libudev-list.c b/src/libudev/libudev-list.c
new file mode 100644 (file)
index 0000000..59ba69e
--- /dev/null
@@ -0,0 +1,355 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+/**
+ * SECTION:libudev-list
+ * @short_description: list operation
+ *
+ * Libudev list operations.
+ */
+
+/**
+ * udev_list_entry:
+ *
+ * Opaque object representing one entry in a list. An entry contains
+ * contains a name, and optionally a value.
+ */
+struct udev_list_entry {
+        struct udev_list_node node;
+        struct udev_list *list;
+        char *name;
+        char *value;
+        int num;
+};
+
+/* the list's head points to itself if empty */
+void udev_list_node_init(struct udev_list_node *list)
+{
+        list->next = list;
+        list->prev = list;
+}
+
+int udev_list_node_is_empty(struct udev_list_node *list)
+{
+        return list->next == list;
+}
+
+static void udev_list_node_insert_between(struct udev_list_node *new,
+                                          struct udev_list_node *prev,
+                                          struct udev_list_node *next)
+{
+        next->prev = new;
+        new->next = next;
+        new->prev = prev;
+        prev->next = new;
+}
+
+void udev_list_node_append(struct udev_list_node *new, struct udev_list_node *list)
+{
+        udev_list_node_insert_between(new, list->prev, list);
+}
+
+void udev_list_node_remove(struct udev_list_node *entry)
+{
+        struct udev_list_node *prev = entry->prev;
+        struct udev_list_node *next = entry->next;
+
+        next->prev = prev;
+        prev->next = next;
+
+        entry->prev = NULL;
+        entry->next = NULL;
+}
+
+/* return list entry which embeds this node */
+static inline struct udev_list_entry *list_node_to_entry(struct udev_list_node *node)
+{
+        return container_of(node, struct udev_list_entry, node);
+}
+
+void udev_list_init(struct udev *udev, struct udev_list *list, bool unique)
+{
+        memset(list, 0x00, sizeof(struct udev_list));
+        list->udev = udev;
+        list->unique = unique;
+        udev_list_node_init(&list->node);
+}
+
+/* insert entry into a list as the last element  */
+void udev_list_entry_append(struct udev_list_entry *new, struct udev_list *list)
+{
+        /* inserting before the list head make the node the last node in the list */
+        udev_list_node_insert_between(&new->node, list->node.prev, &list->node);
+        new->list = list;
+}
+
+/* insert entry into a list, before a given existing entry */
+void udev_list_entry_insert_before(struct udev_list_entry *new, struct udev_list_entry *entry)
+{
+        udev_list_node_insert_between(&new->node, entry->node.prev, &entry->node);
+        new->list = entry->list;
+}
+
+/* binary search in sorted array */
+static int list_search(struct udev_list *list, const char *name)
+{
+        unsigned int first, last;
+
+        first = 0;
+        last = list->entries_cur;
+        while (first < last) {
+                unsigned int i;
+                int cmp;
+
+                i = (first + last)/2;
+                cmp = strcmp(name, list->entries[i]->name);
+                if (cmp < 0)
+                        last = i;
+                else if (cmp > 0)
+                        first = i+1;
+                else
+                        return i;
+        }
+
+        /* not found, return negative insertion-index+1 */
+        return -(first+1);
+}
+
+struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char *name, const char *value)
+{
+        struct udev_list_entry *entry;
+        int i = 0;
+
+        if (list->unique) {
+                /* lookup existing name or insertion-index */
+                i = list_search(list, name);
+                if (i >= 0) {
+                        entry = list->entries[i];
+
+                        free(entry->value);
+                        if (value == NULL) {
+                                entry->value = NULL;
+                                return entry;
+                        }
+                        entry->value = strdup(value);
+                        if (entry->value == NULL)
+                                return NULL;
+                        return entry;
+                }
+        }
+
+        /* add new name */
+        entry = calloc(1, sizeof(struct udev_list_entry));
+        if (entry == NULL)
+                return NULL;
+        entry->name = strdup(name);
+        if (entry->name == NULL) {
+                free(entry);
+                return NULL;
+        }
+        if (value != NULL) {
+                entry->value = strdup(value);
+                if (entry->value == NULL) {
+                        free(entry->name);
+                        free(entry);
+                        return NULL;
+                }
+        }
+
+        if (list->unique) {
+                /* allocate or enlarge sorted array if needed */
+                if (list->entries_cur >= list->entries_max) {
+                        struct udev_list_entry **entries;
+                        unsigned int add;
+
+                        add = list->entries_max;
+                        if (add < 1)
+                                add = 64;
+                        entries = realloc(list->entries, (list->entries_max + add) * sizeof(struct udev_list_entry *));
+                        if (entries == NULL) {
+                                free(entry->name);
+                                free(entry->value);
+                                free(entry);
+                                return NULL;
+                        }
+                        list->entries = entries;
+                        list->entries_max += add;
+                }
+
+                /* the negative i returned the insertion index */
+                i = (-i)-1;
+
+                /* insert into sorted list */
+                if ((unsigned int)i < list->entries_cur)
+                        udev_list_entry_insert_before(entry, list->entries[i]);
+                else
+                        udev_list_entry_append(entry, list);
+
+                /* insert into sorted array */
+                memmove(&list->entries[i+1], &list->entries[i],
+                        (list->entries_cur - i) * sizeof(struct udev_list_entry *));
+                list->entries[i] = entry;
+                list->entries_cur++;
+        } else {
+                udev_list_entry_append(entry, list);
+        }
+
+        return entry;
+}
+
+void udev_list_entry_delete(struct udev_list_entry *entry)
+{
+        if (entry->list->entries != NULL) {
+                int i;
+                struct udev_list *list = entry->list;
+
+                /* remove entry from sorted array */
+                i = list_search(list, entry->name);
+                if (i >= 0) {
+                        memmove(&list->entries[i], &list->entries[i+1],
+                                ((list->entries_cur-1) - i) * sizeof(struct udev_list_entry *));
+                        list->entries_cur--;
+                }
+        }
+
+        udev_list_node_remove(&entry->node);
+        free(entry->name);
+        free(entry->value);
+        free(entry);
+}
+
+void udev_list_cleanup(struct udev_list *list)
+{
+        struct udev_list_entry *entry_loop;
+        struct udev_list_entry *entry_tmp;
+
+        free(list->entries);
+        list->entries = NULL;
+        list->entries_cur = 0;
+        list->entries_max = 0;
+        udev_list_entry_foreach_safe(entry_loop, entry_tmp, udev_list_get_entry(list))
+                udev_list_entry_delete(entry_loop);
+}
+
+struct udev_list_entry *udev_list_get_entry(struct udev_list *list)
+{
+        if (udev_list_node_is_empty(&list->node))
+                return NULL;
+        return list_node_to_entry(list->node.next);
+}
+
+/**
+ * udev_list_entry_get_next:
+ * @list_entry: current entry
+ *
+ * Get the next entry from the list.
+ *
+ * Returns: udev_list_entry, #NULL if no more entries are available.
+ */
+_public_ struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry)
+{
+        struct udev_list_node *next;
+
+        if (list_entry == NULL)
+                return NULL;
+        next = list_entry->node.next;
+        /* empty list or no more entries */
+        if (next == &list_entry->list->node)
+                return NULL;
+        return list_node_to_entry(next);
+}
+
+/**
+ * udev_list_entry_get_by_name:
+ * @list_entry: current entry
+ * @name: name string to match
+ *
+ * Lookup an entry in the list with a certain name.
+ *
+ * Returns: udev_list_entry, #NULL if no matching entry is found.
+ */
+_public_ struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name)
+{
+        int i;
+
+        if (list_entry == NULL)
+                return NULL;
+
+        if (!list_entry->list->unique)
+                return NULL;
+
+        i = list_search(list_entry->list, name);
+        if (i < 0)
+                return NULL;
+        return list_entry->list->entries[i];
+}
+
+/**
+ * udev_list_entry_get_name:
+ * @list_entry: current entry
+ *
+ * Get the name of a list entry.
+ *
+ * Returns: the name string of this entry.
+ */
+_public_ const char *udev_list_entry_get_name(struct udev_list_entry *list_entry)
+{
+        if (list_entry == NULL)
+                return NULL;
+        return list_entry->name;
+}
+
+/**
+ * udev_list_entry_get_value:
+ * @list_entry: current entry
+ *
+ * Get the value of list entry.
+ *
+ * Returns: the value string of this entry.
+ */
+_public_ const char *udev_list_entry_get_value(struct udev_list_entry *list_entry)
+{
+        if (list_entry == NULL)
+                return NULL;
+        return list_entry->value;
+}
+
+int udev_list_entry_get_num(struct udev_list_entry *list_entry)
+{
+        if (list_entry == NULL)
+                return -EINVAL;
+        return list_entry->num;
+}
+
+void udev_list_entry_set_num(struct udev_list_entry *list_entry, int num)
+{
+        if (list_entry == NULL)
+                return;
+        list_entry->num = num;
+}
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
new file mode 100644 (file)
index 0000000..b02ea88
--- /dev/null
@@ -0,0 +1,782 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <arpa/inet.h>
+#include <linux/netlink.h>
+#include <linux/filter.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+#include "socket-util.h"
+
+/**
+ * SECTION:libudev-monitor
+ * @short_description: device event source
+ *
+ * Connects to a device event source.
+ */
+
+/**
+ * udev_monitor:
+ *
+ * Opaque object handling an event source.
+ */
+struct udev_monitor {
+        struct udev *udev;
+        int refcount;
+        int sock;
+        union sockaddr_union snl;
+        union sockaddr_union snl_trusted_sender;
+        union sockaddr_union snl_destination;
+        socklen_t addrlen;
+        struct udev_list filter_subsystem_list;
+        struct udev_list filter_tag_list;
+        bool bound;
+};
+
+enum udev_monitor_netlink_group {
+        UDEV_MONITOR_NONE,
+        UDEV_MONITOR_KERNEL,
+        UDEV_MONITOR_UDEV,
+};
+
+#define UDEV_MONITOR_MAGIC                0xfeedcafe
+struct udev_monitor_netlink_header {
+        /* "libudev" prefix to distinguish libudev and kernel messages */
+        char prefix[8];
+        /*
+         * magic to protect against daemon <-> library message format mismatch
+         * used in the kernel from socket filter rules; needs to be stored in network order
+         */
+        unsigned int magic;
+        /* total length of header structure known to the sender */
+        unsigned int header_size;
+        /* properties string buffer */
+        unsigned int properties_off;
+        unsigned int properties_len;
+        /*
+         * hashes of primary device properties strings, to let libudev subscribers
+         * use in-kernel socket filters; values need to be stored in network order
+         */
+        unsigned int filter_subsystem_hash;
+        unsigned int filter_devtype_hash;
+        unsigned int filter_tag_bloom_hi;
+        unsigned int filter_tag_bloom_lo;
+};
+
+static struct udev_monitor *udev_monitor_new(struct udev *udev)
+{
+        struct udev_monitor *udev_monitor;
+
+        udev_monitor = calloc(1, sizeof(struct udev_monitor));
+        if (udev_monitor == NULL)
+                return NULL;
+        udev_monitor->refcount = 1;
+        udev_monitor->udev = udev;
+        udev_list_init(udev, &udev_monitor->filter_subsystem_list, false);
+        udev_list_init(udev, &udev_monitor->filter_tag_list, true);
+        return udev_monitor;
+}
+
+struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd)
+{
+        struct udev_monitor *udev_monitor;
+        unsigned int group;
+
+        if (udev == NULL)
+                return NULL;
+
+        if (name == NULL)
+                group = UDEV_MONITOR_NONE;
+        else if (strcmp(name, "udev") == 0)
+                group = UDEV_MONITOR_UDEV;
+        else if (strcmp(name, "kernel") == 0)
+                group = UDEV_MONITOR_KERNEL;
+        else
+                return NULL;
+
+        udev_monitor = udev_monitor_new(udev);
+        if (udev_monitor == NULL)
+                return NULL;
+
+        if (fd < 0) {
+                udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
+                if (udev_monitor->sock == -1) {
+                        udev_err(udev, "error getting socket: %m\n");
+                        free(udev_monitor);
+                        return NULL;
+                }
+        } else {
+                udev_monitor->bound = true;
+                udev_monitor->sock = fd;
+        }
+
+        udev_monitor->snl.nl.nl_family = AF_NETLINK;
+        udev_monitor->snl.nl.nl_groups = group;
+
+        /* default destination for sending */
+        udev_monitor->snl_destination.nl.nl_family = AF_NETLINK;
+        udev_monitor->snl_destination.nl.nl_groups = UDEV_MONITOR_UDEV;
+
+        return udev_monitor;
+}
+
+/**
+ * udev_monitor_new_from_netlink:
+ * @udev: udev library context
+ * @name: name of event source
+ *
+ * Create new udev monitor and connect to a specified event
+ * source. Valid sources identifiers are "udev" and "kernel".
+ *
+ * Applications should usually not connect directly to the
+ * "kernel" events, because the devices might not be useable
+ * at that time, before udev has configured them, and created
+ * device nodes. Accessing devices at the same time as udev,
+ * might result in unpredictable behavior. The "udev" events
+ * are sent out after udev has finished its event processing,
+ * all rules have been processed, and needed device nodes are
+ * created.
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev monitor.
+ *
+ * Returns: a new udev monitor, or #NULL, in case of an error
+ **/
+_public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name)
+{
+        return udev_monitor_new_from_netlink_fd(udev, name, -1);
+}
+
+static inline void bpf_stmt(struct sock_filter *inss, unsigned int *i,
+                            unsigned short code, unsigned int data)
+{
+        struct sock_filter *ins = &inss[*i];
+
+        ins->code = code;
+        ins->k = data;
+        (*i)++;
+}
+
+static inline void bpf_jmp(struct sock_filter *inss, unsigned int *i,
+                           unsigned short code, unsigned int data,
+                           unsigned short jt, unsigned short jf)
+{
+        struct sock_filter *ins = &inss[*i];
+
+        ins->code = code;
+        ins->jt = jt;
+        ins->jf = jf;
+        ins->k = data;
+        (*i)++;
+}
+
+/**
+ * udev_monitor_filter_update:
+ * @udev_monitor: monitor
+ *
+ * Update the installed socket filter. This is only needed,
+ * if the filter was removed or changed.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor)
+{
+        struct sock_filter ins[512];
+        struct sock_fprog filter;
+        unsigned int i;
+        struct udev_list_entry *list_entry;
+        int err;
+
+        if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL &&
+            udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL)
+                return 0;
+
+        memset(ins, 0x00, sizeof(ins));
+        i = 0;
+
+        /* load magic in A */
+        bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, magic));
+        /* jump if magic matches */
+        bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, UDEV_MONITOR_MAGIC, 1, 0);
+        /* wrong magic, pass packet */
+        bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
+
+        if (udev_list_get_entry(&udev_monitor->filter_tag_list) != NULL) {
+                int tag_matches;
+
+                /* count tag matches, to calculate end of tag match block */
+                tag_matches = 0;
+                udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list))
+                        tag_matches++;
+
+                /* add all tags matches */
+                udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) {
+                        uint64_t tag_bloom_bits = util_string_bloom64(udev_list_entry_get_name(list_entry));
+                        uint32_t tag_bloom_hi = tag_bloom_bits >> 32;
+                        uint32_t tag_bloom_lo = tag_bloom_bits & 0xffffffff;
+
+                        /* load device bloom bits in A */
+                        bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_tag_bloom_hi));
+                        /* clear bits (tag bits & bloom bits) */
+                        bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_hi);
+                        /* jump to next tag if it does not match */
+                        bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_hi, 0, 3);
+
+                        /* load device bloom bits in A */
+                        bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_tag_bloom_lo));
+                        /* clear bits (tag bits & bloom bits) */
+                        bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_lo);
+                        /* jump behind end of tag match block if tag matches */
+                        tag_matches--;
+                        bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_lo, 1 + (tag_matches * 6), 0);
+                }
+
+                /* nothing matched, drop packet */
+                bpf_stmt(ins, &i, BPF_RET|BPF_K, 0);
+        }
+
+        /* add all subsystem matches */
+        if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) != NULL) {
+                udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) {
+                        unsigned int hash = util_string_hash32(udev_list_entry_get_name(list_entry));
+
+                        /* load device subsystem value in A */
+                        bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_subsystem_hash));
+                        if (udev_list_entry_get_value(list_entry) == NULL) {
+                                /* jump if subsystem does not match */
+                                bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1);
+                        } else {
+                                /* jump if subsystem does not match */
+                                bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 3);
+
+                                /* load device devtype value in A */
+                                bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_devtype_hash));
+                                /* jump if value does not match */
+                                hash = util_string_hash32(udev_list_entry_get_value(list_entry));
+                                bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1);
+                        }
+
+                        /* matched, pass packet */
+                        bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
+
+                        if (i+1 >= ELEMENTSOF(ins))
+                                return -1;
+                }
+
+                /* nothing matched, drop packet */
+                bpf_stmt(ins, &i, BPF_RET|BPF_K, 0);
+        }
+
+        /* matched, pass packet */
+        bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
+
+        /* install filter */
+        memset(&filter, 0x00, sizeof(filter));
+        filter.len = i;
+        filter.filter = ins;
+        err = setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
+        return err;
+}
+
+int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender)
+{
+        udev_monitor->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid;
+        return 0;
+}
+/**
+ * udev_monitor_enable_receiving:
+ * @udev_monitor: the monitor which should receive events
+ *
+ * Binds the @udev_monitor socket to the event source.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor)
+{
+        int err = 0;
+        const int on = 1;
+
+        if (udev_monitor->snl.nl.nl_family == 0)
+                return -EINVAL;
+
+        udev_monitor_filter_update(udev_monitor);
+
+        if (!udev_monitor->bound) {
+                err = bind(udev_monitor->sock,
+                           &udev_monitor->snl.sa, sizeof(struct sockaddr_nl));
+                if (err == 0)
+                        udev_monitor->bound = true;
+        }
+
+        if (err >= 0) {
+                union sockaddr_union snl;
+                socklen_t addrlen;
+
+                /*
+                 * get the address the kernel has assigned us
+                 * it is usually, but not necessarily the pid
+                 */
+                addrlen = sizeof(struct sockaddr_nl);
+                err = getsockname(udev_monitor->sock, &snl.sa, &addrlen);
+                if (err == 0)
+                        udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid;
+        } else {
+                udev_err(udev_monitor->udev, "bind failed: %m\n");
+                return err;
+        }
+
+        /* enable receiving of sender credentials */
+        setsockopt(udev_monitor->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
+        return 0;
+}
+
+/**
+ * udev_monitor_set_receive_buffer_size:
+ * @udev_monitor: the monitor which should receive events
+ * @size: the size in bytes
+ *
+ * Set the size of the kernel socket buffer. This call needs the
+ * appropriate privileges to succeed.
+ *
+ * Returns: 0 on success, otherwise -1 on error.
+ */
+_public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size)
+{
+        if (udev_monitor == NULL)
+                return -1;
+        return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size));
+}
+
+int udev_monitor_disconnect(struct udev_monitor *udev_monitor)
+{
+        int err;
+
+        err = close(udev_monitor->sock);
+        udev_monitor->sock = -1;
+        return err;
+}
+
+/**
+ * udev_monitor_ref:
+ * @udev_monitor: udev monitor
+ *
+ * Take a reference of a udev monitor.
+ *
+ * Returns: the passed udev monitor
+ **/
+_public_ struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor)
+{
+        if (udev_monitor == NULL)
+                return NULL;
+        udev_monitor->refcount++;
+        return udev_monitor;
+}
+
+/**
+ * udev_monitor_unref:
+ * @udev_monitor: udev monitor
+ *
+ * Drop a reference of a udev monitor. If the refcount reaches zero,
+ * the bound socket will be closed, and the resources of the monitor
+ * will be released.
+ *
+ * Returns: the passed udev monitor if it has still an active reference, or #NULL otherwise.
+ **/
+_public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor)
+{
+        if (udev_monitor == NULL)
+                return NULL;
+        udev_monitor->refcount--;
+        if (udev_monitor->refcount > 0)
+                return udev_monitor;
+        if (udev_monitor->sock >= 0)
+                close(udev_monitor->sock);
+        udev_list_cleanup(&udev_monitor->filter_subsystem_list);
+        udev_list_cleanup(&udev_monitor->filter_tag_list);
+        free(udev_monitor);
+        return NULL;
+}
+
+/**
+ * udev_monitor_get_udev:
+ * @udev_monitor: udev monitor
+ *
+ * Retrieve the udev library context the monitor was created with.
+ *
+ * Returns: the udev library context
+ **/
+_public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor)
+{
+        if (udev_monitor == NULL)
+                return NULL;
+        return udev_monitor->udev;
+}
+
+/**
+ * udev_monitor_get_fd:
+ * @udev_monitor: udev monitor
+ *
+ * Retrieve the socket file descriptor associated with the monitor.
+ *
+ * Returns: the socket file descriptor
+ **/
+_public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor)
+{
+        if (udev_monitor == NULL)
+                return -1;
+        return udev_monitor->sock;
+}
+
+static int passes_filter(struct udev_monitor *udev_monitor, struct udev_device *udev_device)
+{
+        struct udev_list_entry *list_entry;
+
+        if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL)
+                goto tag;
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) {
+                const char *subsys = udev_list_entry_get_name(list_entry);
+                const char *dsubsys = udev_device_get_subsystem(udev_device);
+                const char *devtype;
+                const char *ddevtype;
+
+                if (strcmp(dsubsys, subsys) != 0)
+                        continue;
+
+                devtype = udev_list_entry_get_value(list_entry);
+                if (devtype == NULL)
+                        goto tag;
+                ddevtype = udev_device_get_devtype(udev_device);
+                if (ddevtype == NULL)
+                        continue;
+                if (strcmp(ddevtype, devtype) == 0)
+                        goto tag;
+        }
+        return 0;
+
+tag:
+        if (udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL)
+                return 1;
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) {
+                const char *tag = udev_list_entry_get_name(list_entry);
+
+                if (udev_device_has_tag(udev_device, tag))
+                        return 1;
+        }
+        return 0;
+}
+
+/**
+ * udev_monitor_receive_device:
+ * @udev_monitor: udev monitor
+ *
+ * Receive data from the udev monitor socket, allocate a new udev
+ * device, fill in the received data, and return the device.
+ *
+ * Only socket connections with uid=0 are accepted.
+ *
+ * The monitor socket is by default set to NONBLOCK. A variant of poll() on
+ * the file descriptor returned by udev_monitor_get_fd() should to be used to
+ * wake up when new devices arrive, or alternatively the file descriptor
+ * switched into blocking mode.
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev device.
+ *
+ * Returns: a new udev device, or #NULL, in case of an error
+ **/
+_public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor)
+{
+        struct udev_device *udev_device;
+        struct msghdr smsg;
+        struct iovec iov;
+        char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+        struct cmsghdr *cmsg;
+        union sockaddr_union snl;
+        struct ucred *cred;
+        char buf[8192];
+        ssize_t buflen;
+        ssize_t bufpos;
+        struct udev_monitor_netlink_header *nlh;
+
+retry:
+        if (udev_monitor == NULL)
+                return NULL;
+        iov.iov_base = &buf;
+        iov.iov_len = sizeof(buf);
+        memset (&smsg, 0x00, sizeof(struct msghdr));
+        smsg.msg_iov = &iov;
+        smsg.msg_iovlen = 1;
+        smsg.msg_control = cred_msg;
+        smsg.msg_controllen = sizeof(cred_msg);
+
+        if (udev_monitor->snl.nl.nl_family != 0) {
+                smsg.msg_name = &snl;
+                smsg.msg_namelen = sizeof(snl);
+        }
+
+        buflen = recvmsg(udev_monitor->sock, &smsg, 0);
+        if (buflen < 0) {
+                if (errno != EINTR)
+                        udev_dbg(udev_monitor->udev, "unable to receive message\n");
+                return NULL;
+        }
+
+        if (buflen < 32 || (size_t)buflen >= sizeof(buf)) {
+                udev_dbg(udev_monitor->udev, "invalid message length\n");
+                return NULL;
+        }
+
+        if (udev_monitor->snl.nl.nl_family != 0) {
+                if (snl.nl.nl_groups == 0) {
+                        /* unicast message, check if we trust the sender */
+                        if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 ||
+                            snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) {
+                                udev_dbg(udev_monitor->udev, "unicast netlink message ignored\n");
+                                return NULL;
+                        }
+                } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) {
+                        if (snl.nl.nl_pid > 0) {
+                                udev_dbg(udev_monitor->udev, "multicast kernel netlink message from pid %d ignored\n",
+                                     snl.nl.nl_pid);
+                                return NULL;
+                        }
+                }
+        }
+
+        cmsg = CMSG_FIRSTHDR(&smsg);
+        if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
+                udev_dbg(udev_monitor->udev, "no sender credentials received, message ignored\n");
+                return NULL;
+        }
+
+        cred = (struct ucred *)CMSG_DATA(cmsg);
+        if (cred->uid != 0) {
+                udev_dbg(udev_monitor->udev, "sender uid=%d, message ignored\n", cred->uid);
+                return NULL;
+        }
+
+        if (memcmp(buf, "libudev", 8) == 0) {
+                /* udev message needs proper version magic */
+                nlh = (struct udev_monitor_netlink_header *) buf;
+                if (nlh->magic != htonl(UDEV_MONITOR_MAGIC)) {
+                        udev_err(udev_monitor->udev, "unrecognized message signature (%x != %x)\n",
+                            nlh->magic, htonl(UDEV_MONITOR_MAGIC));
+                        return NULL;
+                }
+                if (nlh->properties_off+32 > (size_t)buflen)
+                        return NULL;
+                bufpos = nlh->properties_off;
+        } else {
+                /* kernel message with header */
+                bufpos = strlen(buf) + 1;
+                if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) {
+                        udev_dbg(udev_monitor->udev, "invalid message length\n");
+                        return NULL;
+                }
+
+                /* check message header */
+                if (strstr(buf, "@/") == NULL) {
+                        udev_dbg(udev_monitor->udev, "unrecognized message header\n");
+                        return NULL;
+                }
+        }
+
+        udev_device = udev_device_new(udev_monitor->udev);
+        if (udev_device == NULL)
+                return NULL;
+        udev_device_set_info_loaded(udev_device);
+
+        while (bufpos < buflen) {
+                char *key;
+                size_t keylen;
+
+                key = &buf[bufpos];
+                keylen = strlen(key);
+                if (keylen == 0)
+                        break;
+                bufpos += keylen + 1;
+                udev_device_add_property_from_string_parse(udev_device, key);
+        }
+
+        if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) {
+                udev_dbg(udev_monitor->udev, "missing values, invalid device\n");
+                udev_device_unref(udev_device);
+                return NULL;
+        }
+
+        /* skip device, if it does not pass the current filter */
+        if (!passes_filter(udev_monitor, udev_device)) {
+                struct pollfd pfd[1];
+                int rc;
+
+                udev_device_unref(udev_device);
+
+                /* if something is queued, get next device */
+                pfd[0].fd = udev_monitor->sock;
+                pfd[0].events = POLLIN;
+                rc = poll(pfd, 1, 0);
+                if (rc > 0)
+                        goto retry;
+                return NULL;
+        }
+
+        return udev_device;
+}
+
+int udev_monitor_send_device(struct udev_monitor *udev_monitor,
+                             struct udev_monitor *destination, struct udev_device *udev_device)
+{
+        const char *buf;
+        ssize_t blen;
+        ssize_t count;
+        struct msghdr smsg;
+        struct iovec iov[2];
+        const char *val;
+        struct udev_monitor_netlink_header nlh;
+        struct udev_list_entry *list_entry;
+        uint64_t tag_bloom_bits;
+
+        if (udev_monitor->snl.nl.nl_family == 0)
+                return -EINVAL;
+
+        blen = udev_device_get_properties_monitor_buf(udev_device, &buf);
+        if (blen < 32)
+                return -EINVAL;
+
+        /* add versioned header */
+        memset(&nlh, 0x00, sizeof(struct udev_monitor_netlink_header));
+        memcpy(nlh.prefix, "libudev", 8);
+        nlh.magic = htonl(UDEV_MONITOR_MAGIC);
+        nlh.header_size = sizeof(struct udev_monitor_netlink_header);
+        val = udev_device_get_subsystem(udev_device);
+        nlh.filter_subsystem_hash = htonl(util_string_hash32(val));
+        val = udev_device_get_devtype(udev_device);
+        if (val != NULL)
+                nlh.filter_devtype_hash = htonl(util_string_hash32(val));
+        iov[0].iov_base = &nlh;
+        iov[0].iov_len = sizeof(struct udev_monitor_netlink_header);
+
+        /* add tag bloom filter */
+        tag_bloom_bits = 0;
+        udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
+                tag_bloom_bits |= util_string_bloom64(udev_list_entry_get_name(list_entry));
+        if (tag_bloom_bits > 0) {
+                nlh.filter_tag_bloom_hi = htonl(tag_bloom_bits >> 32);
+                nlh.filter_tag_bloom_lo = htonl(tag_bloom_bits & 0xffffffff);
+        }
+
+        /* add properties list */
+        nlh.properties_off = iov[0].iov_len;
+        nlh.properties_len = blen;
+        iov[1].iov_base = (char *)buf;
+        iov[1].iov_len = blen;
+
+        memset(&smsg, 0x00, sizeof(struct msghdr));
+        smsg.msg_iov = iov;
+        smsg.msg_iovlen = 2;
+        /*
+         * Use custom address for target, or the default one.
+         *
+         * If we send to a multicast group, we will get
+         * ECONNREFUSED, which is expected.
+         */
+        if (destination != NULL)
+                smsg.msg_name = &destination->snl;
+        else
+                smsg.msg_name = &udev_monitor->snl_destination;
+        smsg.msg_namelen = sizeof(struct sockaddr_nl);
+        count = sendmsg(udev_monitor->sock, &smsg, 0);
+        udev_dbg(udev_monitor->udev, "passed %zi bytes to netlink monitor %p\n", count, udev_monitor);
+        return count;
+}
+
+/**
+ * udev_monitor_filter_add_match_subsystem_devtype:
+ * @udev_monitor: the monitor
+ * @subsystem: the subsystem value to match the incoming devices against
+ * @devtype: the devtype value to match the incoming devices against
+ *
+ * This filter is efficiently executed inside the kernel, and libudev subscribers
+ * will usually not be woken up for devices which do not match.
+ *
+ * The filter must be installed before the monitor is switched to listening mode.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype)
+{
+        if (udev_monitor == NULL)
+                return -EINVAL;
+        if (subsystem == NULL)
+                return -EINVAL;
+        if (udev_list_entry_add(&udev_monitor->filter_subsystem_list, subsystem, devtype) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+/**
+ * udev_monitor_filter_add_match_tag:
+ * @udev_monitor: the monitor
+ * @tag: the name of a tag
+ *
+ * This filter is efficiently executed inside the kernel, and libudev subscribers
+ * will usually not be woken up for devices which do not match.
+ *
+ * The filter must be installed before the monitor is switched to listening mode.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag)
+{
+        if (udev_monitor == NULL)
+                return -EINVAL;
+        if (tag == NULL)
+                return -EINVAL;
+        if (udev_list_entry_add(&udev_monitor->filter_tag_list, tag, NULL) == NULL)
+                return -ENOMEM;
+        return 0;
+}
+
+/**
+ * udev_monitor_filter_remove:
+ * @udev_monitor: monitor
+ *
+ * Remove all filters from monitor.
+ *
+ * Returns: 0 on success, otherwise a negative error value.
+ */
+_public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor)
+{
+        static struct sock_fprog filter = { 0, NULL };
+
+        udev_list_cleanup(&udev_monitor->filter_subsystem_list);
+        return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
+}
diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h
new file mode 100644 (file)
index 0000000..1b86384
--- /dev/null
@@ -0,0 +1,183 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifndef _LIBUDEV_PRIVATE_H_
+#define _LIBUDEV_PRIVATE_H_
+
+#include <syslog.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "libudev.h"
+#include "macro.h"
+#include "util.h"
+#include "mkdir.h"
+
+#define READ_END  0
+#define WRITE_END 1
+
+/* avoid (sometimes expensive) calculations of parameters for debug output */
+#define udev_log_cond(udev, prio, arg...) \
+  do { \
+    if (udev_get_log_priority(udev) >= prio) \
+      udev_log(udev, prio, __FILE__, __LINE__, __FUNCTION__, ## arg); \
+  } while (0)
+
+#define udev_dbg(udev, arg...) udev_log_cond(udev, LOG_DEBUG, ## arg)
+#define udev_info(udev, arg...) udev_log_cond(udev, LOG_INFO, ## arg)
+#define udev_err(udev, arg...) udev_log_cond(udev, LOG_ERR, ## arg)
+
+/* libudev.c */
+void udev_log(struct udev *udev,
+              int priority, const char *file, int line, const char *fn,
+              const char *format, ...)
+              __attribute__((format(printf, 6, 7)));
+int udev_get_rules_path(struct udev *udev, char **path[], usec_t *ts_usec[]);
+struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value);
+struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev);
+
+/* libudev-device.c */
+struct udev_device *udev_device_new(struct udev *udev);
+mode_t udev_device_get_devnode_mode(struct udev_device *udev_device);
+uid_t udev_device_get_devnode_uid(struct udev_device *udev_device);
+gid_t udev_device_get_devnode_gid(struct udev_device *udev_device);
+int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem);
+int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath);
+int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode);
+int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink);
+void udev_device_cleanup_devlinks_list(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value);
+void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property);
+int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device);
+char **udev_device_get_properties_envp(struct udev_device *udev_device);
+ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf);
+int udev_device_read_db(struct udev_device *udev_device, const char *dbfile);
+int udev_device_read_uevent_file(struct udev_device *udev_device);
+int udev_device_set_action(struct udev_device *udev_device, const char *action);
+const char *udev_device_get_devpath_old(struct udev_device *udev_device);
+const char *udev_device_get_id_filename(struct udev_device *udev_device);
+void udev_device_set_is_initialized(struct udev_device *udev_device);
+int udev_device_add_tag(struct udev_device *udev_device, const char *tag);
+void udev_device_cleanup_tags_list(struct udev_device *udev_device);
+usec_t udev_device_get_usec_initialized(struct udev_device *udev_device);
+void udev_device_set_usec_initialized(struct udev_device *udev_device, usec_t usec_initialized);
+int udev_device_get_devlink_priority(struct udev_device *udev_device);
+int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio);
+int udev_device_get_watch_handle(struct udev_device *udev_device);
+int udev_device_set_watch_handle(struct udev_device *udev_device, int handle);
+int udev_device_get_ifindex(struct udev_device *udev_device);
+void udev_device_set_info_loaded(struct udev_device *device);
+bool udev_device_get_db_persist(struct udev_device *udev_device);
+void udev_device_set_db_persist(struct udev_device *udev_device);
+
+/* libudev-device-private.c */
+int udev_device_update_db(struct udev_device *udev_device);
+int udev_device_delete_db(struct udev_device *udev_device);
+int udev_device_tag_index(struct udev_device *dev, struct udev_device *dev_old, bool add);
+
+/* libudev-monitor.c - netlink/unix socket communication  */
+int udev_monitor_disconnect(struct udev_monitor *udev_monitor);
+int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender);
+int udev_monitor_send_device(struct udev_monitor *udev_monitor,
+                             struct udev_monitor *destination, struct udev_device *udev_device);
+struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd);
+
+/* libudev-list.c */
+struct udev_list_node {
+        struct udev_list_node *next, *prev;
+};
+struct udev_list {
+        struct udev *udev;
+        struct udev_list_node node;
+        struct udev_list_entry **entries;
+        unsigned int entries_cur;
+        unsigned int entries_max;
+        bool unique;
+};
+#define UDEV_LIST(list) struct udev_list_node list = { &(list), &(list) }
+void udev_list_node_init(struct udev_list_node *list);
+int udev_list_node_is_empty(struct udev_list_node *list);
+void udev_list_node_append(struct udev_list_node *new, struct udev_list_node *list);
+void udev_list_node_remove(struct udev_list_node *entry);
+#define udev_list_node_foreach(node, list) \
+        for (node = (list)->next; \
+             node != list; \
+             node = (node)->next)
+#define udev_list_node_foreach_safe(node, tmp, list) \
+        for (node = (list)->next, tmp = (node)->next; \
+             node != list; \
+             node = tmp, tmp = (tmp)->next)
+void udev_list_init(struct udev *udev, struct udev_list *list, bool unique);
+void udev_list_cleanup(struct udev_list *list);
+struct udev_list_entry *udev_list_get_entry(struct udev_list *list);
+struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char *name, const char *value);
+void udev_list_entry_delete(struct udev_list_entry *entry);
+void udev_list_entry_insert_before(struct udev_list_entry *new, struct udev_list_entry *entry);
+void udev_list_entry_append(struct udev_list_entry *new, struct udev_list *list);
+int udev_list_entry_get_num(struct udev_list_entry *list_entry);
+void udev_list_entry_set_num(struct udev_list_entry *list_entry, int num);
+#define udev_list_entry_foreach_safe(entry, tmp, first) \
+        for (entry = first, tmp = udev_list_entry_get_next(entry); \
+             entry != NULL; \
+             entry = tmp, tmp = udev_list_entry_get_next(tmp))
+
+/* libudev-queue.c */
+unsigned long long int udev_get_kernel_seqnum(struct udev *udev);
+int udev_queue_read_seqnum(FILE *queue_file, unsigned long long int *seqnum);
+ssize_t udev_queue_read_devpath(FILE *queue_file, char *devpath, size_t size);
+ssize_t udev_queue_skip_devpath(FILE *queue_file);
+
+/* libudev-queue-private.c */
+struct udev_queue_export *udev_queue_export_new(struct udev *udev);
+struct udev_queue_export *udev_queue_export_unref(struct udev_queue_export *udev_queue_export);
+void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export);
+int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device);
+int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device);
+
+/* libudev-hwdb.c */
+bool udev_hwdb_validate(struct udev_hwdb *hwdb);
+
+/* libudev-util.c */
+#define UTIL_PATH_SIZE                      1024
+#define UTIL_NAME_SIZE                       512
+#define UTIL_LINE_SIZE                     16384
+#define UDEV_ALLOWED_CHARS_INPUT        "/ $%?,"
+ssize_t util_get_sys_core_link_value(struct udev *udev, const char *slink, const char *syspath, char *value, size_t size);
+int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size);
+int util_log_priority(const char *priority);
+size_t util_path_encode(const char *src, char *dest, size_t size);
+void util_remove_trailing_chars(char *path, char c);
+size_t util_strpcpy(char **dest, size_t size, const char *src);
+size_t util_strpcpyf(char **dest, size_t size, const char *src, ...) __attribute__((format(printf, 3, 4)));
+size_t util_strpcpyl(char **dest, size_t size, const char *src, ...) __attribute__((sentinel));
+size_t util_strscpy(char *dest, size_t size, const char *src);
+size_t util_strscpyl(char *dest, size_t size, const char *src, ...) __attribute__((sentinel));
+int util_replace_whitespace(const char *str, char *to, size_t len);
+int util_replace_chars(char *str, const char *white);
+unsigned int util_string_hash32(const char *key);
+uint64_t util_string_bloom64(const char *str);
+
+/* libudev-util-private.c */
+int util_delete_path(struct udev *udev, const char *path);
+uid_t util_lookup_user(struct udev *udev, const char *user);
+gid_t util_lookup_group(struct udev *udev, const char *group);
+int util_resolve_subsys_kernel(struct udev *udev, const char *string, char *result, size_t maxsize, int read_value);
+ssize_t print_kmsg(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+#endif
diff --git a/src/libudev/libudev-queue-private.c b/src/libudev/libudev-queue-private.c
new file mode 100644 (file)
index 0000000..80d7cee
--- /dev/null
@@ -0,0 +1,406 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+  Copyright 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * DISCLAIMER - The file format mentioned here is private to udev/libudev,
+ *              and may be changed without notice.
+ *
+ * The udev event queue is exported as a binary log file.
+ * Each log record consists of a sequence number followed by the device path.
+ *
+ * When a new event is queued, its details are appended to the log.
+ * When the event finishes, a second record is appended to the log
+ * with the same sequence number but a devpath len of 0.
+ *
+ * Example:
+ *        { 0x0000000000000001 }
+ *        { 0x0000000000000001, 0x0019, "/devices/virtual/mem/null" },
+ *        { 0x0000000000000002, 0x001b, "/devices/virtual/mem/random" },
+ *        { 0x0000000000000001, 0x0000 },
+ *        { 0x0000000000000003, 0x0019, "/devices/virtual/mem/zero" },
+ *
+ * Events 2 and 3 are still queued, but event 1 has finished.
+ *
+ * The queue does not grow indefinitely. It is periodically re-created
+ * to remove finished events. Atomic rename() makes this transparent to readers.
+ *
+ * The queue file starts with a single sequence number which specifies the
+ * minimum sequence number in the log that follows. Any events prior to this
+ * sequence number have already finished.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+static int rebuild_queue_file(struct udev_queue_export *udev_queue_export);
+
+struct udev_queue_export {
+        struct udev *udev;
+        int queued_count;        /* number of unfinished events exported in queue file */
+        FILE *queue_file;
+        unsigned long long int seqnum_max;        /* earliest sequence number in queue file */
+        unsigned long long int seqnum_min;        /* latest sequence number in queue file */
+        int waste_bytes;                        /* queue file bytes wasted on finished events */
+};
+
+struct udev_queue_export *udev_queue_export_new(struct udev *udev)
+{
+        struct udev_queue_export *udev_queue_export;
+        unsigned long long int initial_seqnum;
+
+        if (udev == NULL)
+                return NULL;
+
+        udev_queue_export = calloc(1, sizeof(struct udev_queue_export));
+        if (udev_queue_export == NULL)
+                return NULL;
+        udev_queue_export->udev = udev;
+
+        initial_seqnum = udev_get_kernel_seqnum(udev);
+        udev_queue_export->seqnum_min = initial_seqnum;
+        udev_queue_export->seqnum_max = initial_seqnum;
+
+        udev_queue_export_cleanup(udev_queue_export);
+        if (rebuild_queue_file(udev_queue_export) != 0) {
+                free(udev_queue_export);
+                return NULL;
+        }
+
+        return udev_queue_export;
+}
+
+struct udev_queue_export *udev_queue_export_unref(struct udev_queue_export *udev_queue_export)
+{
+        if (udev_queue_export == NULL)
+                return NULL;
+        if (udev_queue_export->queue_file != NULL)
+                fclose(udev_queue_export->queue_file);
+        free(udev_queue_export);
+        return NULL;
+}
+
+void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export)
+{
+        if (udev_queue_export == NULL)
+                return;
+        unlink("/run/udev/queue.tmp");
+        unlink("/run/udev/queue.bin");
+}
+
+static int skip_to(FILE *file, long offset)
+{
+        long old_offset;
+
+        /* fseek may drop buffered data, avoid it for small seeks */
+        old_offset = ftell(file);
+        if (offset > old_offset && offset - old_offset <= BUFSIZ) {
+                size_t skip_bytes = offset - old_offset;
+                char *buf = alloca(skip_bytes);
+
+                if (fread(buf, skip_bytes, 1, file) != skip_bytes)
+                        return -1;
+        }
+
+        return fseek(file, offset, SEEK_SET);
+}
+
+struct queue_devpaths {
+        unsigned int devpaths_first;        /* index of first queued event */
+        unsigned int devpaths_size;
+        long devpaths[];                /* seqnum -> offset of devpath in queue file (or 0) */
+};
+
+/*
+ * Returns a table mapping seqnum to devpath file offset for currently queued events.
+ * devpaths[i] represents the event with seqnum = i + udev_queue_export->seqnum_min.
+ */
+static struct queue_devpaths *build_index(struct udev_queue_export *udev_queue_export)
+{
+        struct queue_devpaths *devpaths;
+        unsigned long long int range;
+        long devpath_offset;
+        ssize_t devpath_len;
+        unsigned long long int seqnum;
+        unsigned long long int n;
+        unsigned int i;
+
+        /* seek to the first event in the file */
+        rewind(udev_queue_export->queue_file);
+        udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum);
+
+        /* allocate the table */
+        range = udev_queue_export->seqnum_min - udev_queue_export->seqnum_max;
+        if (range - 1 > INT_MAX) {
+                udev_err(udev_queue_export->udev, "queue file overflow\n");
+                return NULL;
+        }
+        devpaths = calloc(1, sizeof(struct queue_devpaths) + (range + 1) * sizeof(long));
+        if (devpaths == NULL)
+                return NULL;
+        devpaths->devpaths_size = range + 1;
+
+        /* read all records and populate the table */
+        for (;;) {
+                if (udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum) < 0)
+                        break;
+                n = seqnum - udev_queue_export->seqnum_max;
+                if (n >= devpaths->devpaths_size)
+                        goto read_error;
+
+                devpath_offset = ftell(udev_queue_export->queue_file);
+                devpath_len = udev_queue_skip_devpath(udev_queue_export->queue_file);
+                if (devpath_len < 0)
+                        goto read_error;
+
+                if (devpath_len > 0)
+                        devpaths->devpaths[n] = devpath_offset;
+                else
+                        devpaths->devpaths[n] = 0;
+        }
+
+        /* find first queued event */
+        for (i = 0; i < devpaths->devpaths_size; i++) {
+                if (devpaths->devpaths[i] != 0)
+                        break;
+        }
+        devpaths->devpaths_first = i;
+
+        return devpaths;
+
+read_error:
+        udev_err(udev_queue_export->udev, "queue file corrupted\n");
+        free(devpaths);
+        return NULL;
+}
+
+static int rebuild_queue_file(struct udev_queue_export *udev_queue_export)
+{
+        unsigned long long int seqnum;
+        struct queue_devpaths *devpaths = NULL;
+        FILE *new_queue_file = NULL;
+        unsigned int i;
+
+        /* read old queue file */
+        if (udev_queue_export->queue_file != NULL) {
+                devpaths = build_index(udev_queue_export);
+                if (devpaths != NULL)
+                        udev_queue_export->seqnum_max += devpaths->devpaths_first;
+        }
+        if (devpaths == NULL) {
+                udev_queue_export->queued_count = 0;
+                udev_queue_export->seqnum_max = udev_queue_export->seqnum_min;
+        }
+
+        /* create new queue file */
+        new_queue_file = fopen("/run/udev/queue.tmp", "w+e");
+        if (new_queue_file == NULL)
+                goto error;
+        seqnum = udev_queue_export->seqnum_max;
+        fwrite(&seqnum, 1, sizeof(unsigned long long int), new_queue_file);
+
+        /* copy unfinished events only to the new file */
+        if (devpaths != NULL) {
+                for (i = devpaths->devpaths_first; i < devpaths->devpaths_size; i++) {
+                        char devpath[UTIL_PATH_SIZE];
+                        int err;
+                        unsigned short devpath_len;
+
+                        if (devpaths->devpaths[i] != 0)
+                        {
+                                skip_to(udev_queue_export->queue_file, devpaths->devpaths[i]);
+                                err = udev_queue_read_devpath(udev_queue_export->queue_file, devpath, sizeof(devpath));
+                                devpath_len = err;
+
+                                fwrite(&seqnum, sizeof(unsigned long long int), 1, new_queue_file);
+                                fwrite(&devpath_len, sizeof(unsigned short), 1, new_queue_file);
+                                fwrite(devpath, 1, devpath_len, new_queue_file);
+                        }
+                        seqnum++;
+                }
+                free(devpaths);
+                devpaths = NULL;
+        }
+        fflush(new_queue_file);
+        if (ferror(new_queue_file))
+                goto error;
+
+        /* rename the new file on top of the old one */
+        if (rename("/run/udev/queue.tmp", "/run/udev/queue.bin") != 0)
+                goto error;
+
+        if (udev_queue_export->queue_file != NULL)
+                fclose(udev_queue_export->queue_file);
+        udev_queue_export->queue_file = new_queue_file;
+        udev_queue_export->waste_bytes = 0;
+
+        return 0;
+
+error:
+        udev_err(udev_queue_export->udev, "failed to create queue file: %m\n");
+        udev_queue_export_cleanup(udev_queue_export);
+
+        if (udev_queue_export->queue_file != NULL) {
+                fclose(udev_queue_export->queue_file);
+                udev_queue_export->queue_file = NULL;
+        }
+        if (new_queue_file != NULL)
+                fclose(new_queue_file);
+
+        if (devpaths != NULL)
+                free(devpaths);
+        udev_queue_export->queued_count = 0;
+        udev_queue_export->waste_bytes = 0;
+        udev_queue_export->seqnum_max = udev_queue_export->seqnum_min;
+
+        return -1;
+}
+
+static int write_queue_record(struct udev_queue_export *udev_queue_export,
+                              unsigned long long int seqnum, const char *devpath, size_t devpath_len)
+{
+        unsigned short len;
+
+        if (udev_queue_export->queue_file == NULL)
+                return -1;
+
+        if (fwrite(&seqnum, sizeof(unsigned long long int), 1, udev_queue_export->queue_file) != 1)
+                goto write_error;
+
+        len = (devpath_len < USHRT_MAX) ? devpath_len : USHRT_MAX;
+        if (fwrite(&len, sizeof(unsigned short), 1, udev_queue_export->queue_file) != 1)
+                goto write_error;
+        if (len > 0) {
+                if (fwrite(devpath, 1, len, udev_queue_export->queue_file) != len)
+                        goto write_error;
+        }
+
+        /* *must* flush output; caller may fork */
+        if (fflush(udev_queue_export->queue_file) != 0)
+                goto write_error;
+
+        return 0;
+
+write_error:
+        /* if we failed half way through writing a record to a file,
+           we should not try to write any further records to it. */
+        udev_err(udev_queue_export->udev, "error writing to queue file: %m\n");
+        fclose(udev_queue_export->queue_file);
+        udev_queue_export->queue_file = NULL;
+
+        return -1;
+}
+
+enum device_state {
+        DEVICE_QUEUED,
+        DEVICE_FINISHED,
+};
+
+static inline size_t queue_record_size(size_t devpath_len)
+{
+        return sizeof(unsigned long long int) + sizeof(unsigned short int) + devpath_len;
+}
+
+static int update_queue(struct udev_queue_export *udev_queue_export,
+                         struct udev_device *udev_device, enum device_state state)
+{
+        unsigned long long int seqnum = udev_device_get_seqnum(udev_device);
+        const char *devpath = NULL;
+        size_t devpath_len = 0;
+        int bytes;
+        int err;
+
+        /* FINISHED records have a zero length devpath */
+        if (state == DEVICE_QUEUED) {
+                devpath = udev_device_get_devpath(udev_device);
+                devpath_len = strlen(devpath);
+        }
+
+        /* recover from an earlier failed rebuild */
+        if (udev_queue_export->queue_file == NULL) {
+                if (rebuild_queue_file(udev_queue_export) != 0)
+                        return -1;
+        }
+
+        /* if we're removing the last event from the queue, that's the best time to rebuild it */
+        if (state != DEVICE_QUEUED && udev_queue_export->queued_count == 1) {
+                /* we don't need to read the old queue file */
+                fclose(udev_queue_export->queue_file);
+                udev_queue_export->queue_file = NULL;
+                rebuild_queue_file(udev_queue_export);
+                return 0;
+        }
+
+        /* try to rebuild the queue files before they grow larger than one page. */
+        bytes = ftell(udev_queue_export->queue_file) + queue_record_size(devpath_len);
+        if ((udev_queue_export->waste_bytes > bytes / 2) && bytes > 4096)
+                rebuild_queue_file(udev_queue_export);
+
+        /* don't record a finished event, if we already dropped the event in a failed rebuild */
+        if (seqnum < udev_queue_export->seqnum_max)
+                return 0;
+
+        /* now write to the queue */
+        if (state == DEVICE_QUEUED) {
+                udev_queue_export->queued_count++;
+                udev_queue_export->seqnum_min = seqnum;
+        } else {
+                udev_queue_export->waste_bytes += queue_record_size(devpath_len) + queue_record_size(0);
+                udev_queue_export->queued_count--;
+        }
+        err = write_queue_record(udev_queue_export, seqnum, devpath, devpath_len);
+
+        /* try to handle ENOSPC */
+        if (err != 0 && udev_queue_export->queued_count == 0) {
+                udev_queue_export_cleanup(udev_queue_export);
+                err = rebuild_queue_file(udev_queue_export);
+        }
+
+        return err;
+}
+
+static int update(struct udev_queue_export *udev_queue_export,
+                  struct udev_device *udev_device, enum device_state state)
+{
+        if (update_queue(udev_queue_export, udev_device, state) != 0)
+                return -1;
+
+        return 0;
+}
+
+int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device)
+{
+        return update(udev_queue_export, udev_device, DEVICE_QUEUED);
+}
+
+int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device)
+{
+        return update(udev_queue_export, udev_device, DEVICE_FINISHED);
+}
diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c
new file mode 100644 (file)
index 0000000..08d52ab
--- /dev/null
@@ -0,0 +1,480 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+  Copyright 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/stat.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+/**
+ * SECTION:libudev-queue
+ * @short_description: access to currently active events
+ *
+ * The udev daemon processes events asynchronously. All events which do not have
+ * interdependencies run in parallel. This exports the current state of the
+ * event processing queue, and the current event sequence numbers from the kernel
+ * and the udev daemon.
+ */
+
+/**
+ * udev_queue:
+ *
+ * Opaque object representing the current event queue in the udev daemon.
+ */
+struct udev_queue {
+        struct udev *udev;
+        int refcount;
+        struct udev_list queue_list;
+};
+
+/**
+ * udev_queue_new:
+ * @udev: udev library context
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev queue context.
+ *
+ * Returns: the udev queue context, or #NULL on error.
+ **/
+_public_ struct udev_queue *udev_queue_new(struct udev *udev)
+{
+        struct udev_queue *udev_queue;
+
+        if (udev == NULL)
+                return NULL;
+
+        udev_queue = calloc(1, sizeof(struct udev_queue));
+        if (udev_queue == NULL)
+                return NULL;
+        udev_queue->refcount = 1;
+        udev_queue->udev = udev;
+        udev_list_init(udev, &udev_queue->queue_list, false);
+        return udev_queue;
+}
+
+/**
+ * udev_queue_ref:
+ * @udev_queue: udev queue context
+ *
+ * Take a reference of a udev queue context.
+ *
+ * Returns: the same udev queue context.
+ **/
+_public_ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue)
+{
+        if (udev_queue == NULL)
+                return NULL;
+        udev_queue->refcount++;
+        return udev_queue;
+}
+
+/**
+ * udev_queue_unref:
+ * @udev_queue: udev queue context
+ *
+ * Drop a reference of a udev queue context. If the refcount reaches zero,
+ * the resources of the queue context will be released.
+ *
+ * Returns: the passed queue context if it has still an active reference, or #NULL otherwise.
+ **/
+_public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue)
+{
+        if (udev_queue == NULL)
+                return NULL;
+        udev_queue->refcount--;
+        if (udev_queue->refcount > 0)
+                return udev_queue;
+        udev_list_cleanup(&udev_queue->queue_list);
+        free(udev_queue);
+        return NULL;
+}
+
+/**
+ * udev_queue_get_udev:
+ * @udev_queue: udev queue context
+ *
+ * Retrieve the udev library context the queue context was created with.
+ *
+ * Returns: the udev library context.
+ **/
+_public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue)
+{
+        if (udev_queue == NULL)
+                return NULL;
+        return udev_queue->udev;
+}
+
+unsigned long long int udev_get_kernel_seqnum(struct udev *udev)
+{
+        unsigned long long int seqnum;
+        int fd;
+        char buf[32];
+        ssize_t len;
+
+        fd = open("/sys/kernel/uevent_seqnum", O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
+                return 0;
+        len = read(fd, buf, sizeof(buf));
+        close(fd);
+        if (len <= 2)
+                return 0;
+        buf[len-1] = '\0';
+        seqnum = strtoull(buf, NULL, 10);
+        return seqnum;
+}
+
+/**
+ * udev_queue_get_kernel_seqnum:
+ * @udev_queue: udev queue context
+ *
+ * Get the current kernel event sequence number.
+ *
+ * Returns: the sequence number.
+ **/
+_public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue)
+{
+        unsigned long long int seqnum;
+
+        if (udev_queue == NULL)
+                return -EINVAL;
+
+        seqnum = udev_get_kernel_seqnum(udev_queue->udev);
+        return seqnum;
+}
+
+int udev_queue_read_seqnum(FILE *queue_file, unsigned long long int *seqnum)
+{
+        if (fread(seqnum, sizeof(unsigned long long int), 1, queue_file) != 1)
+                return -1;
+
+        return 0;
+}
+
+ssize_t udev_queue_skip_devpath(FILE *queue_file)
+{
+        unsigned short int len;
+
+        if (fread(&len, sizeof(unsigned short int), 1, queue_file) == 1) {
+                char *devpath = alloca(len);
+
+                /* use fread to skip, fseek might drop buffered data */
+                if (fread(devpath, 1, len, queue_file) == len)
+                        return len;
+        }
+
+        return -1;
+}
+
+ssize_t udev_queue_read_devpath(FILE *queue_file, char *devpath, size_t size)
+{
+        unsigned short int read_bytes = 0;
+        unsigned short int len;
+
+        if (fread(&len, sizeof(unsigned short int), 1, queue_file) != 1)
+                return -1;
+
+        read_bytes = (len < size - 1) ? len : size - 1;
+        if (fread(devpath, 1, read_bytes, queue_file) != read_bytes)
+                return -1;
+        devpath[read_bytes] = '\0';
+
+        /* if devpath was too long, skip unread characters */
+        if (read_bytes != len) {
+                unsigned short int skip_bytes = len - read_bytes;
+                char *buf = alloca(skip_bytes);
+
+                if (fread(buf, 1, skip_bytes, queue_file) != skip_bytes)
+                        return -1;
+        }
+
+        return read_bytes;
+}
+
+static FILE *open_queue_file(struct udev_queue *udev_queue, unsigned long long int *seqnum_start)
+{
+        FILE *queue_file;
+
+        queue_file = fopen("/run/udev/queue.bin", "re");
+        if (queue_file == NULL)
+                return NULL;
+
+        if (udev_queue_read_seqnum(queue_file, seqnum_start) < 0) {
+                udev_err(udev_queue->udev, "corrupt queue file\n");
+                fclose(queue_file);
+                return NULL;
+        }
+
+        return queue_file;
+}
+
+/**
+ * udev_queue_get_udev_seqnum:
+ * @udev_queue: udev queue context
+ *
+ * Get the last known udev event sequence number.
+ *
+ * Returns: the sequence number.
+ **/
+_public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue)
+{
+        unsigned long long int seqnum_udev;
+        FILE *queue_file;
+
+        queue_file = open_queue_file(udev_queue, &seqnum_udev);
+        if (queue_file == NULL)
+                return 0;
+
+        for (;;) {
+                unsigned long long int seqnum;
+                ssize_t devpath_len;
+
+                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
+                        break;
+                devpath_len = udev_queue_skip_devpath(queue_file);
+                if (devpath_len < 0)
+                        break;
+                if (devpath_len > 0)
+                        seqnum_udev = seqnum;
+        }
+
+        fclose(queue_file);
+        return seqnum_udev;
+}
+
+/**
+ * udev_queue_get_udev_is_active:
+ * @udev_queue: udev queue context
+ *
+ * Check if udev is active on the system.
+ *
+ * Returns: a flag indicating if udev is active.
+ **/
+_public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue)
+{
+        unsigned long long int seqnum_start;
+        FILE *queue_file;
+
+        queue_file = open_queue_file(udev_queue, &seqnum_start);
+        if (queue_file == NULL)
+                return 0;
+
+        fclose(queue_file);
+        return 1;
+}
+
+/**
+ * udev_queue_get_queue_is_empty:
+ * @udev_queue: udev queue context
+ *
+ * Check if udev is currently processing any events.
+ *
+ * Returns: a flag indicating if udev is currently handling events.
+ **/
+_public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue)
+{
+        unsigned long long int seqnum_kernel;
+        unsigned long long int seqnum_udev = 0;
+        int queued = 0;
+        int is_empty = 0;
+        FILE *queue_file;
+
+        if (udev_queue == NULL)
+                return -EINVAL;
+        queue_file = open_queue_file(udev_queue, &seqnum_udev);
+        if (queue_file == NULL)
+                return 1;
+
+        for (;;) {
+                unsigned long long int seqnum;
+                ssize_t devpath_len;
+
+                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
+                        break;
+                devpath_len = udev_queue_skip_devpath(queue_file);
+                if (devpath_len < 0)
+                        break;
+
+                if (devpath_len > 0) {
+                        queued++;
+                        seqnum_udev = seqnum;
+                } else {
+                        queued--;
+                }
+        }
+
+        if (queued > 0)
+                goto out;
+
+        seqnum_kernel = udev_queue_get_kernel_seqnum(udev_queue);
+        if (seqnum_udev < seqnum_kernel)
+                goto out;
+
+        is_empty = 1;
+
+out:
+        fclose(queue_file);
+        return is_empty;
+}
+
+/**
+ * udev_queue_get_seqnum_sequence_is_finished:
+ * @udev_queue: udev queue context
+ * @start: first event sequence number
+ * @end: last event sequence number
+ *
+ * Check if udev is currently processing any events in a given sequence number range.
+ *
+ * Returns: a flag indicating if any of the sequence numbers in the given range is currently active.
+ **/
+_public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
+                                               unsigned long long int start, unsigned long long int end)
+{
+        unsigned long long int seqnum;
+        ssize_t devpath_len;
+        int unfinished;
+        FILE *queue_file;
+
+        if (udev_queue == NULL)
+                return -EINVAL;
+        queue_file = open_queue_file(udev_queue, &seqnum);
+        if (queue_file == NULL)
+                return 1;
+        if (start < seqnum)
+                start = seqnum;
+        if (start > end) {
+                fclose(queue_file);
+                return 1;
+        }
+        if (end - start > INT_MAX - 1) {
+                fclose(queue_file);
+                return -EOVERFLOW;
+        }
+
+        /*
+         * we might start with 0, and handle the initial seqnum
+         * only when we find an entry in the queue file
+         **/
+        unfinished = end - start;
+
+        do {
+                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
+                        break;
+                devpath_len = udev_queue_skip_devpath(queue_file);
+                if (devpath_len < 0)
+                        break;
+
+                /*
+                 * we might start with an empty or re-build queue file, where
+                 * the initial seqnum is not recorded as finished
+                 */
+                if (start == seqnum && devpath_len > 0)
+                        unfinished++;
+
+                if (devpath_len == 0) {
+                        if (seqnum >= start && seqnum <= end)
+                                unfinished--;
+                }
+        } while (unfinished > 0);
+
+        fclose(queue_file);
+
+        return (unfinished == 0);
+}
+
+/**
+ * udev_queue_get_seqnum_is_finished:
+ * @udev_queue: udev queue context
+ * @seqnum: sequence number
+ *
+ * Check if udev is currently processing a given sequence number.
+ *
+ * Returns: a flag indicating if the given sequence number is currently active.
+ **/
+_public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum)
+{
+        if (!udev_queue_get_seqnum_sequence_is_finished(udev_queue, seqnum, seqnum))
+                return 0;
+
+        return 1;
+}
+
+/**
+ * udev_queue_get_queued_list_entry:
+ * @udev_queue: udev queue context
+ *
+ * Get the first entry of the list of queued events.
+ *
+ * Returns: a udev_list_entry.
+ **/
+_public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue)
+{
+        unsigned long long int seqnum;
+        FILE *queue_file;
+
+        if (udev_queue == NULL)
+                return NULL;
+        udev_list_cleanup(&udev_queue->queue_list);
+
+        queue_file = open_queue_file(udev_queue, &seqnum);
+        if (queue_file == NULL)
+                return NULL;
+
+        for (;;) {
+                char syspath[UTIL_PATH_SIZE];
+                char *s;
+                size_t l;
+                ssize_t len;
+                char seqnum_str[32];
+                struct udev_list_entry *list_entry;
+
+                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
+                        break;
+                snprintf(seqnum_str, sizeof(seqnum_str), "%llu", seqnum);
+
+                s = syspath;
+                l = util_strpcpy(&s, sizeof(syspath), "/sys");
+                len = udev_queue_read_devpath(queue_file, s, l);
+                if (len < 0)
+                        break;
+
+                if (len > 0) {
+                        udev_list_entry_add(&udev_queue->queue_list, syspath, seqnum_str);
+                } else {
+                        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_queue->queue_list)) {
+                                if (strcmp(seqnum_str, udev_list_entry_get_value(list_entry)) == 0) {
+                                        udev_list_entry_delete(list_entry);
+                                        break;
+                                }
+                        }
+                }
+        }
+        fclose(queue_file);
+
+        return udev_list_get_entry(&udev_queue->queue_list);
+}
diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c
new file mode 100644 (file)
index 0000000..b55bf75
--- /dev/null
@@ -0,0 +1,742 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <time.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+/**
+ * SECTION:libudev-util
+ * @short_description: utils
+ *
+ * Utilities useful when dealing with devices and device node names.
+ */
+
+int util_delete_path(struct udev *udev, const char *path)
+{
+        char p[UTIL_PATH_SIZE];
+        char *pos;
+        int err = 0;
+
+        if (path[0] == '/')
+                while(path[1] == '/')
+                        path++;
+        util_strscpy(p, sizeof(p), path);
+        pos = strrchr(p, '/');
+        if (pos == p || pos == NULL)
+                return 0;
+
+        for (;;) {
+                *pos = '\0';
+                pos = strrchr(p, '/');
+
+                /* don't remove the last one */
+                if ((pos == p) || (pos == NULL))
+                        break;
+
+                err = rmdir(p);
+                if (err < 0) {
+                        if (errno == ENOENT)
+                                err = 0;
+                        break;
+                }
+        }
+        return err;
+}
+
+uid_t util_lookup_user(struct udev *udev, const char *user)
+{
+        char *endptr;
+        struct passwd pwbuf;
+        struct passwd *pw;
+        uid_t uid;
+        size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+        char *buf = alloca(buflen);
+
+        if (strcmp(user, "root") == 0)
+                return 0;
+        uid = strtoul(user, &endptr, 10);
+        if (endptr[0] == '\0')
+                return uid;
+
+        errno = getpwnam_r(user, &pwbuf, buf, buflen, &pw);
+        if (pw != NULL)
+                return pw->pw_uid;
+        if (errno == 0 || errno == ENOENT || errno == ESRCH)
+                udev_err(udev, "specified user '%s' unknown\n", user);
+        else
+                udev_err(udev, "error resolving user '%s': %m\n", user);
+        return 0;
+}
+
+gid_t util_lookup_group(struct udev *udev, const char *group)
+{
+        char *endptr;
+        struct group grbuf;
+        struct group *gr;
+        gid_t gid = 0;
+        size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+        char *buf = NULL;
+
+        if (strcmp(group, "root") == 0)
+                return 0;
+        gid = strtoul(group, &endptr, 10);
+        if (endptr[0] == '\0')
+                return gid;
+        gid = 0;
+        for (;;) {
+                char *newbuf;
+
+                newbuf = realloc(buf, buflen);
+                if (!newbuf)
+                        break;
+                buf = newbuf;
+                errno = getgrnam_r(group, &grbuf, buf, buflen, &gr);
+                if (gr != NULL) {
+                        gid = gr->gr_gid;
+                } else if (errno == ERANGE) {
+                        buflen *= 2;
+                        continue;
+                } else if (errno == 0 || errno == ENOENT || errno == ESRCH) {
+                        udev_err(udev, "specified group '%s' unknown\n", group);
+                } else {
+                        udev_err(udev, "error resolving group '%s': %m\n", group);
+                }
+                break;
+        }
+        free(buf);
+        return gid;
+}
+
+/* handle "[<SUBSYSTEM>/<KERNEL>]<attribute>" format */
+int util_resolve_subsys_kernel(struct udev *udev, const char *string,
+                               char *result, size_t maxsize, int read_value)
+{
+        char temp[UTIL_PATH_SIZE];
+        char *subsys;
+        char *sysname;
+        struct udev_device *dev;
+        char *attr;
+
+        if (string[0] != '[')
+                return -1;
+
+        util_strscpy(temp, sizeof(temp), string);
+
+        subsys = &temp[1];
+
+        sysname = strchr(subsys, '/');
+        if (sysname == NULL)
+                return -1;
+        sysname[0] = '\0';
+        sysname = &sysname[1];
+
+        attr = strchr(sysname, ']');
+        if (attr == NULL)
+                return -1;
+        attr[0] = '\0';
+        attr = &attr[1];
+        if (attr[0] == '/')
+                attr = &attr[1];
+        if (attr[0] == '\0')
+                attr = NULL;
+
+        if (read_value && attr == NULL)
+                return -1;
+
+        dev = udev_device_new_from_subsystem_sysname(udev, subsys, sysname);
+        if (dev == NULL)
+                return -1;
+
+        if (read_value) {
+                const char *val;
+
+                val = udev_device_get_sysattr_value(dev, attr);
+                if (val != NULL)
+                        util_strscpy(result, maxsize, val);
+                else
+                        result[0] = '\0';
+                udev_dbg(udev, "value '[%s/%s]%s' is '%s'\n", subsys, sysname, attr, result);
+        } else {
+                size_t l;
+                char *s;
+
+                s = result;
+                l = util_strpcpyl(&s, maxsize, udev_device_get_syspath(dev), NULL);
+                if (attr != NULL)
+                        util_strpcpyl(&s, l, "/", attr, NULL);
+                udev_dbg(udev, "path '[%s/%s]%s' is '%s'\n", subsys, sysname, attr, result);
+        }
+        udev_device_unref(dev);
+        return 0;
+}
+ssize_t util_get_sys_core_link_value(struct udev *udev, const char *slink, const char *syspath, char *value, size_t size)
+{
+        char path[UTIL_PATH_SIZE];
+        char target[UTIL_PATH_SIZE];
+        ssize_t len;
+        const char *pos;
+
+        util_strscpyl(path, sizeof(path), syspath, "/", slink, NULL);
+        len = readlink(path, target, sizeof(target));
+        if (len <= 0 || len == (ssize_t)sizeof(target))
+                return -1;
+        target[len] = '\0';
+        pos = strrchr(target, '/');
+        if (pos == NULL)
+                return -1;
+        pos = &pos[1];
+        return util_strscpy(value, size, pos);
+}
+
+int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size)
+{
+        char link_target[UTIL_PATH_SIZE];
+
+        ssize_t len;
+        int i;
+        int back;
+        char *base = NULL;
+
+        len = readlink(syspath, link_target, sizeof(link_target));
+        if (len <= 0 || len == (ssize_t)sizeof(link_target))
+                return -1;
+        link_target[len] = '\0';
+
+        for (back = 0; startswith(&link_target[back * 3], "../"); back++)
+                ;
+        for (i = 0; i <= back; i++) {
+                base = strrchr(syspath, '/');
+                if (base == NULL)
+                        return -EINVAL;
+                base[0] = '\0';
+        }
+        if (base == NULL)
+                return -EINVAL;
+        util_strscpyl(base, size - (base - syspath), "/", &link_target[back * 3], NULL);
+        return 0;
+}
+
+int util_log_priority(const char *priority)
+{
+        char *endptr;
+        int prio;
+
+        prio = strtol(priority, &endptr, 10);
+        if (endptr[0] == '\0' || isspace(endptr[0]))
+                return prio;
+        if (startswith(priority, "err"))
+                return LOG_ERR;
+        if (startswith(priority, "info"))
+                return LOG_INFO;
+        if (startswith(priority, "debug"))
+                return LOG_DEBUG;
+        return 0;
+}
+
+size_t util_path_encode(const char *src, char *dest, size_t size)
+{
+        size_t i, j;
+
+        for (i = 0, j = 0; src[i] != '\0'; i++) {
+                if (src[i] == '/') {
+                        if (j+4 >= size) {
+                                j = 0;
+                                break;
+                        }
+                        memcpy(&dest[j], "\\x2f", 4);
+                        j += 4;
+                } else if (src[i] == '\\') {
+                        if (j+4 >= size) {
+                                j = 0;
+                                break;
+                        }
+                        memcpy(&dest[j], "\\x5c", 4);
+                        j += 4;
+                } else {
+                        if (j+1 >= size) {
+                                j = 0;
+                                break;
+                        }
+                        dest[j] = src[i];
+                        j++;
+                }
+        }
+        dest[j] = '\0';
+        return j;
+}
+
+void util_remove_trailing_chars(char *path, char c)
+{
+        size_t len;
+
+        if (path == NULL)
+                return;
+        len = strlen(path);
+        while (len > 0 && path[len-1] == c)
+                path[--len] = '\0';
+}
+
+/*
+ * Concatenates strings. In any case, terminates in _all_ cases with '\0'
+ * and moves the @dest pointer forward to the added '\0'. Returns the
+ * remaining size, and 0 if the string was truncated.
+ */
+size_t util_strpcpy(char **dest, size_t size, const char *src)
+{
+        size_t len;
+
+        len = strlen(src);
+        if (len >= size) {
+                if (size > 1)
+                        *dest = mempcpy(*dest, src, size-1);
+                size = 0;
+        } else {
+                if (len > 0) {
+                        *dest = mempcpy(*dest, src, len);
+                        size -= len;
+                }
+        }
+        *dest[0] = '\0';
+        return size;
+}
+
+size_t util_strpcpyf(char **dest, size_t size, const char *src, ...)
+{
+        va_list va;
+        int i;
+
+        va_start(va, src);
+        i = vsnprintf(*dest, size, src, va);
+        if (i < (int)size) {
+                *dest += i;
+                size -= i;
+        } else {
+                *dest += size;
+                size = 0;
+        }
+        va_end(va);
+        *dest[0] = '\0';
+        return size;
+}
+
+/* concatenates list of strings, moves dest forward */
+size_t util_strpcpyl(char **dest, size_t size, const char *src, ...)
+{
+        va_list va;
+
+        va_start(va, src);
+        do {
+                size = util_strpcpy(dest, size, src);
+                src = va_arg(va, char *);
+        } while (src != NULL);
+        va_end(va);
+        return size;
+}
+
+/* copies string */
+size_t util_strscpy(char *dest, size_t size, const char *src)
+{
+        char *s;
+
+        s = dest;
+        return util_strpcpy(&s, size, src);
+}
+
+/* concatenates list of strings */
+size_t util_strscpyl(char *dest, size_t size, const char *src, ...)
+{
+        va_list va;
+        char *s;
+
+        va_start(va, src);
+        s = dest;
+        do {
+                size = util_strpcpy(&s, size, src);
+                src = va_arg(va, char *);
+        } while (src != NULL);
+        va_end(va);
+
+        return size;
+}
+
+/* count of characters used to encode one unicode char */
+static int utf8_encoded_expected_len(const char *str)
+{
+        unsigned char c = (unsigned char)str[0];
+
+        if (c < 0x80)
+                return 1;
+        if ((c & 0xe0) == 0xc0)
+                return 2;
+        if ((c & 0xf0) == 0xe0)
+                return 3;
+        if ((c & 0xf8) == 0xf0)
+                return 4;
+        if ((c & 0xfc) == 0xf8)
+                return 5;
+        if ((c & 0xfe) == 0xfc)
+                return 6;
+        return 0;
+}
+
+/* decode one unicode char */
+static int utf8_encoded_to_unichar(const char *str)
+{
+        int unichar;
+        int len;
+        int i;
+
+        len = utf8_encoded_expected_len(str);
+        switch (len) {
+        case 1:
+                return (int)str[0];
+        case 2:
+                unichar = str[0] & 0x1f;
+                break;
+        case 3:
+                unichar = (int)str[0] & 0x0f;
+                break;
+        case 4:
+                unichar = (int)str[0] & 0x07;
+                break;
+        case 5:
+                unichar = (int)str[0] & 0x03;
+                break;
+        case 6:
+                unichar = (int)str[0] & 0x01;
+                break;
+        default:
+                return -1;
+        }
+
+        for (i = 1; i < len; i++) {
+                if (((int)str[i] & 0xc0) != 0x80)
+                        return -1;
+                unichar <<= 6;
+                unichar |= (int)str[i] & 0x3f;
+        }
+
+        return unichar;
+}
+
+/* expected size used to encode one unicode char */
+static int utf8_unichar_to_encoded_len(int unichar)
+{
+        if (unichar < 0x80)
+                return 1;
+        if (unichar < 0x800)
+                return 2;
+        if (unichar < 0x10000)
+                return 3;
+        if (unichar < 0x200000)
+                return 4;
+        if (unichar < 0x4000000)
+                return 5;
+        return 6;
+}
+
+/* check if unicode char has a valid numeric range */
+static int utf8_unichar_valid_range(int unichar)
+{
+        if (unichar > 0x10ffff)
+                return 0;
+        if ((unichar & 0xfffff800) == 0xd800)
+                return 0;
+        if ((unichar > 0xfdcf) && (unichar < 0xfdf0))
+                return 0;
+        if ((unichar & 0xffff) == 0xffff)
+                return 0;
+        return 1;
+}
+
+/* validate one encoded unicode char and return its length */
+static int utf8_encoded_valid_unichar(const char *str)
+{
+        int len;
+        int unichar;
+        int i;
+
+        len = utf8_encoded_expected_len(str);
+        if (len == 0)
+                return -1;
+
+        /* ascii is valid */
+        if (len == 1)
+                return 1;
+
+        /* check if expected encoded chars are available */
+        for (i = 0; i < len; i++)
+                if ((str[i] & 0x80) != 0x80)
+                        return -1;
+
+        unichar = utf8_encoded_to_unichar(str);
+
+        /* check if encoded length matches encoded value */
+        if (utf8_unichar_to_encoded_len(unichar) != len)
+                return -1;
+
+        /* check if value has valid range */
+        if (!utf8_unichar_valid_range(unichar))
+                return -1;
+
+        return len;
+}
+
+int util_replace_whitespace(const char *str, char *to, size_t len)
+{
+        size_t i, j;
+
+        /* strip trailing whitespace */
+        len = strnlen(str, len);
+        while (len && isspace(str[len-1]))
+                len--;
+
+        /* strip leading whitespace */
+        i = 0;
+        while (isspace(str[i]) && (i < len))
+                i++;
+
+        j = 0;
+        while (i < len) {
+                /* substitute multiple whitespace with a single '_' */
+                if (isspace(str[i])) {
+                        while (isspace(str[i]))
+                                i++;
+                        to[j++] = '_';
+                }
+                to[j++] = str[i++];
+        }
+        to[j] = '\0';
+        return 0;
+}
+
+static int is_whitelisted(char c, const char *white)
+{
+        if ((c >= '0' && c <= '9') ||
+            (c >= 'A' && c <= 'Z') ||
+            (c >= 'a' && c <= 'z') ||
+            strchr("#+-.:=@_", c) != NULL ||
+            (white != NULL && strchr(white, c) != NULL))
+                return 1;
+        return 0;
+}
+
+/* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */
+int util_replace_chars(char *str, const char *white)
+{
+        size_t i = 0;
+        int replaced = 0;
+
+        while (str[i] != '\0') {
+                int len;
+
+                if (is_whitelisted(str[i], white)) {
+                        i++;
+                        continue;
+                }
+
+                /* accept hex encoding */
+                if (str[i] == '\\' && str[i+1] == 'x') {
+                        i += 2;
+                        continue;
+                }
+
+                /* accept valid utf8 */
+                len = utf8_encoded_valid_unichar(&str[i]);
+                if (len > 1) {
+                        i += len;
+                        continue;
+                }
+
+                /* if space is allowed, replace whitespace with ordinary space */
+                if (isspace(str[i]) && white != NULL && strchr(white, ' ') != NULL) {
+                        str[i] = ' ';
+                        i++;
+                        replaced++;
+                        continue;
+                }
+
+                /* everything else is replaced with '_' */
+                str[i] = '_';
+                i++;
+                replaced++;
+        }
+        return replaced;
+}
+
+/**
+ * udev_util_encode_string:
+ * @str: input string to be encoded
+ * @str_enc: output string to store the encoded input string
+ * @len: maximum size of the output string, which may be
+ *       four times as long as the input string
+ *
+ * Encode all potentially unsafe characters of a string to the
+ * corresponding 2 char hex value prefixed by '\x'.
+ *
+ * Returns: 0 if the entire string was copied, non-zero otherwise.
+ **/
+_public_ int udev_util_encode_string(const char *str, char *str_enc, size_t len)
+{
+        size_t i, j;
+
+        if (str == NULL || str_enc == NULL)
+                return -1;
+
+        for (i = 0, j = 0; str[i] != '\0'; i++) {
+                int seqlen;
+
+                seqlen = utf8_encoded_valid_unichar(&str[i]);
+                if (seqlen > 1) {
+                        if (len-j < (size_t)seqlen)
+                                goto err;
+                        memcpy(&str_enc[j], &str[i], seqlen);
+                        j += seqlen;
+                        i += (seqlen-1);
+                } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) {
+                        if (len-j < 4)
+                                goto err;
+                        sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]);
+                        j += 4;
+                } else {
+                        if (len-j < 1)
+                                goto err;
+                        str_enc[j] = str[i];
+                        j++;
+                }
+        }
+        if (len-j < 1)
+                goto err;
+        str_enc[j] = '\0';
+        return 0;
+err:
+        return -1;
+}
+
+/*
+ * http://sites.google.com/site/murmurhash/
+ *
+ * All code is released to the public domain. For business purposes,
+ * Murmurhash is under the MIT license.
+ *
+ */
+static unsigned int murmur_hash2(const char *key, int len, unsigned int seed)
+{
+        /*
+         *  'm' and 'r' are mixing constants generated offline.
+         *  They're not really 'magic', they just happen to work well.
+         */
+        const unsigned int m = 0x5bd1e995;
+        const int r = 24;
+
+        /* initialize the hash to a 'random' value */
+        unsigned int h = seed ^ len;
+
+        /* mix 4 bytes at a time into the hash */
+        const unsigned char * data = (const unsigned char *)key;
+
+        while(len >= 4) {
+                unsigned int k = *(unsigned int *)data;
+
+                k *= m;
+                k ^= k >> r;
+                k *= m;
+                h *= m;
+                h ^= k;
+
+                data += 4;
+                len -= 4;
+        }
+
+        /* handle the last few bytes of the input array */
+        switch(len) {
+        case 3:
+                h ^= data[2] << 16;
+        case 2:
+                h ^= data[1] << 8;
+        case 1:
+                h ^= data[0];
+                h *= m;
+        };
+
+        /* do a few final mixes of the hash to ensure the last few bytes are well-incorporated */
+        h ^= h >> 13;
+        h *= m;
+        h ^= h >> 15;
+
+        return h;
+}
+
+unsigned int util_string_hash32(const char *str)
+{
+        return murmur_hash2(str, strlen(str), 0);
+}
+
+/* get a bunch of bit numbers out of the hash, and set the bits in our bit field */
+uint64_t util_string_bloom64(const char *str)
+{
+        uint64_t bits = 0;
+        unsigned int hash = util_string_hash32(str);
+
+        bits |= 1LLU << (hash & 63);
+        bits |= 1LLU << ((hash >> 6) & 63);
+        bits |= 1LLU << ((hash >> 12) & 63);
+        bits |= 1LLU << ((hash >> 18) & 63);
+        return bits;
+}
+
+ssize_t print_kmsg(const char *fmt, ...)
+{
+        int fd;
+        va_list ap;
+        char text[1024];
+        ssize_t len;
+        ssize_t ret;
+
+        fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        len = snprintf(text, sizeof(text), "<30>systemd-udevd[%u]: ", getpid());
+
+        va_start(ap, fmt);
+        len += vsnprintf(text + len, sizeof(text) - len, fmt, ap);
+        va_end(ap);
+
+        ret = write(fd, text, len);
+        if (ret < 0)
+                ret = -errno;
+        close(fd);
+        return ret;
+}
diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c
new file mode 100644 (file)
index 0000000..d860ebc
--- /dev/null
@@ -0,0 +1,314 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+#include "missing.h"
+
+/**
+ * SECTION:libudev
+ * @short_description: libudev context
+ *
+ * The context contains the default values read from the udev config file,
+ * and is passed to all library operations.
+ */
+
+/**
+ * udev:
+ *
+ * Opaque object representing the library context.
+ */
+struct udev {
+        int refcount;
+        void (*log_fn)(struct udev *udev,
+                       int priority, const char *file, int line, const char *fn,
+                       const char *format, va_list args);
+        void *userdata;
+        struct udev_list properties_list;
+        int log_priority;
+};
+
+void udev_log(struct udev *udev,
+              int priority, const char *file, int line, const char *fn,
+              const char *format, ...)
+{
+        va_list args;
+
+        va_start(args, format);
+        udev->log_fn(udev, priority, file, line, fn, format, args);
+        va_end(args);
+}
+
+static void log_stderr(struct udev *udev,
+                       int priority, const char *file, int line, const char *fn,
+                       const char *format, va_list args)
+{
+        fprintf(stderr, "libudev: %s: ", fn);
+        vfprintf(stderr, format, args);
+}
+
+/**
+ * udev_get_userdata:
+ * @udev: udev library context
+ *
+ * Retrieve stored data pointer from library context. This might be useful
+ * to access from callbacks like a custom logging function.
+ *
+ * Returns: stored userdata
+ **/
+_public_ void *udev_get_userdata(struct udev *udev)
+{
+        if (udev == NULL)
+                return NULL;
+        return udev->userdata;
+}
+
+/**
+ * udev_set_userdata:
+ * @udev: udev library context
+ * @userdata: data pointer
+ *
+ * Store custom @userdata in the library context.
+ **/
+_public_ void udev_set_userdata(struct udev *udev, void *userdata)
+{
+        if (udev == NULL)
+                return;
+        udev->userdata = userdata;
+}
+
+/**
+ * udev_new:
+ *
+ * Create udev library context. This reads the udev configuration
+ * file, and fills in the default values.
+ *
+ * The initial refcount is 1, and needs to be decremented to
+ * release the resources of the udev library context.
+ *
+ * Returns: a new udev library context
+ **/
+_public_ struct udev *udev_new(void)
+{
+        struct udev *udev;
+        const char *env;
+        FILE *f;
+
+        udev = calloc(1, sizeof(struct udev));
+        if (udev == NULL)
+                return NULL;
+        udev->refcount = 1;
+        udev->log_fn = log_stderr;
+        udev->log_priority = LOG_ERR;
+        udev_list_init(udev, &udev->properties_list, true);
+
+        f = fopen("/etc/udev/udev.conf", "re");
+        if (f != NULL) {
+                char line[UTIL_LINE_SIZE];
+                int line_nr = 0;
+
+                while (fgets(line, sizeof(line), f)) {
+                        size_t len;
+                        char *key;
+                        char *val;
+
+                        line_nr++;
+
+                        /* find key */
+                        key = line;
+                        while (isspace(key[0]))
+                                key++;
+
+                        /* comment or empty line */
+                        if (key[0] == '#' || key[0] == '\0')
+                                continue;
+
+                        /* split key/value */
+                        val = strchr(key, '=');
+                        if (val == NULL) {
+                                udev_err(udev, "missing <key>=<value> in /etc/udev/udev.conf[%i]; skip line\n", line_nr);
+                                continue;
+                        }
+                        val[0] = '\0';
+                        val++;
+
+                        /* find value */
+                        while (isspace(val[0]))
+                                val++;
+
+                        /* terminate key */
+                        len = strlen(key);
+                        if (len == 0)
+                                continue;
+                        while (isspace(key[len-1]))
+                                len--;
+                        key[len] = '\0';
+
+                        /* terminate value */
+                        len = strlen(val);
+                        if (len == 0)
+                                continue;
+                        while (isspace(val[len-1]))
+                                len--;
+                        val[len] = '\0';
+
+                        if (len == 0)
+                                continue;
+
+                        /* unquote */
+                        if (val[0] == '"' || val[0] == '\'') {
+                                if (val[len-1] != val[0]) {
+                                        udev_err(udev, "inconsistent quoting in /etc/udev/udev.conf[%i]; skip line\n", line_nr);
+                                        continue;
+                                }
+                                val[len-1] = '\0';
+                                val++;
+                        }
+
+                        if (strcmp(key, "udev_log") == 0) {
+                                udev_set_log_priority(udev, util_log_priority(val));
+                                continue;
+                        }
+                }
+                fclose(f);
+        }
+
+        /* environment overrides config */
+        env = secure_getenv("UDEV_LOG");
+        if (env != NULL)
+                udev_set_log_priority(udev, util_log_priority(env));
+
+        return udev;
+}
+
+/**
+ * udev_ref:
+ * @udev: udev library context
+ *
+ * Take a reference of the udev library context.
+ *
+ * Returns: the passed udev library context
+ **/
+_public_ struct udev *udev_ref(struct udev *udev)
+{
+        if (udev == NULL)
+                return NULL;
+        udev->refcount++;
+        return udev;
+}
+
+/**
+ * udev_unref:
+ * @udev: udev library context
+ *
+ * Drop a reference of the udev library context. If the refcount
+ * reaches zero, the resources of the context will be released.
+ *
+ * Returns: the passed udev library context if it has still an active reference, or #NULL otherwise.
+ **/
+_public_ struct udev *udev_unref(struct udev *udev)
+{
+        if (udev == NULL)
+                return NULL;
+        udev->refcount--;
+        if (udev->refcount > 0)
+                return udev;
+        udev_list_cleanup(&udev->properties_list);
+        free(udev);
+        return NULL;
+}
+
+/**
+ * udev_set_log_fn:
+ * @udev: udev library context
+ * @log_fn: function to be called for logging messages
+ *
+ * The built-in logging writes to stderr. It can be
+ * overridden by a custom function, to plug log messages
+ * into the users' logging functionality.
+ *
+ **/
+_public_ void udev_set_log_fn(struct udev *udev,
+                     void (*log_fn)(struct udev *udev,
+                                    int priority, const char *file, int line, const char *fn,
+                                    const char *format, va_list args))
+{
+        udev->log_fn = log_fn;
+        udev_dbg(udev, "custom logging function %p registered\n", log_fn);
+}
+
+/**
+ * udev_get_log_priority:
+ * @udev: udev library context
+ *
+ * The initial logging priority is read from the udev config file
+ * at startup.
+ *
+ * Returns: the current logging priority
+ **/
+_public_ int udev_get_log_priority(struct udev *udev)
+{
+        return udev->log_priority;
+}
+
+/**
+ * udev_set_log_priority:
+ * @udev: udev library context
+ * @priority: the new logging priority
+ *
+ * Set the current logging priority. The value controls which messages
+ * are logged.
+ **/
+_public_ void udev_set_log_priority(struct udev *udev, int priority)
+{
+        char num[32];
+
+        udev->log_priority = priority;
+        snprintf(num, sizeof(num), "%u", udev->log_priority);
+        udev_add_property(udev, "UDEV_LOG", num);
+}
+
+struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value)
+{
+        if (value == NULL) {
+                struct udev_list_entry *list_entry;
+
+                list_entry = udev_get_properties_list_entry(udev);
+                list_entry = udev_list_entry_get_by_name(list_entry, key);
+                if (list_entry != NULL)
+                        udev_list_entry_delete(list_entry);
+                return NULL;
+        }
+        return udev_list_entry_add(&udev->properties_list, key, value);
+}
+
+struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev)
+{
+        return udev_list_get_entry(&udev->properties_list);
+}
diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h
new file mode 100644 (file)
index 0000000..bb41532
--- /dev/null
@@ -0,0 +1,204 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifndef _LIBUDEV_H_
+#define _LIBUDEV_H_
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * udev - library context
+ *
+ * reads the udev config and system environment
+ * allows custom logging
+ */
+struct udev;
+struct udev *udev_ref(struct udev *udev);
+struct udev *udev_unref(struct udev *udev);
+struct udev *udev_new(void);
+void udev_set_log_fn(struct udev *udev,
+                            void (*log_fn)(struct udev *udev,
+                                           int priority, const char *file, int line, const char *fn,
+                                           const char *format, va_list args));
+int udev_get_log_priority(struct udev *udev);
+void udev_set_log_priority(struct udev *udev, int priority);
+void *udev_get_userdata(struct udev *udev);
+void udev_set_userdata(struct udev *udev, void *userdata);
+
+/*
+ * udev_list
+ *
+ * access to libudev generated lists
+ */
+struct udev_list_entry;
+struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry);
+struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name);
+const char *udev_list_entry_get_name(struct udev_list_entry *list_entry);
+const char *udev_list_entry_get_value(struct udev_list_entry *list_entry);
+/**
+ * udev_list_entry_foreach:
+ * @list_entry: entry to store the current position
+ * @first_entry: first entry to start with
+ *
+ * Helper to iterate over all entries of a list.
+ */
+#define udev_list_entry_foreach(list_entry, first_entry) \
+        for (list_entry = first_entry; \
+             list_entry != NULL; \
+             list_entry = udev_list_entry_get_next(list_entry))
+
+/*
+ * udev_device
+ *
+ * access to sysfs/kernel devices
+ */
+struct udev_device;
+struct udev_device *udev_device_ref(struct udev_device *udev_device);
+struct udev_device *udev_device_unref(struct udev_device *udev_device);
+struct udev *udev_device_get_udev(struct udev_device *udev_device);
+struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath);
+struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum);
+struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname);
+struct udev_device *udev_device_new_from_device_id(struct udev *udev, char *id);
+struct udev_device *udev_device_new_from_environment(struct udev *udev);
+/* udev_device_get_parent_*() does not take a reference on the returned device, it is automatically unref'd with the parent */
+struct udev_device *udev_device_get_parent(struct udev_device *udev_device);
+struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device,
+                                                                  const char *subsystem, const char *devtype);
+/* retrieve device properties */
+const char *udev_device_get_devpath(struct udev_device *udev_device);
+const char *udev_device_get_subsystem(struct udev_device *udev_device);
+const char *udev_device_get_devtype(struct udev_device *udev_device);
+const char *udev_device_get_syspath(struct udev_device *udev_device);
+const char *udev_device_get_sysname(struct udev_device *udev_device);
+const char *udev_device_get_sysnum(struct udev_device *udev_device);
+const char *udev_device_get_devnode(struct udev_device *udev_device);
+int udev_device_get_is_initialized(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device);
+const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key);
+const char *udev_device_get_driver(struct udev_device *udev_device);
+dev_t udev_device_get_devnum(struct udev_device *udev_device);
+const char *udev_device_get_action(struct udev_device *udev_device);
+unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device);
+unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device);
+const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr);
+int udev_device_has_tag(struct udev_device *udev_device, const char *tag);
+
+/*
+ * udev_monitor
+ *
+ * access to kernel uevents and udev events
+ */
+struct udev_monitor;
+struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor);
+struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor);
+struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor);
+/* kernel and udev generated events over netlink */
+struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name);
+/* bind socket */
+int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor);
+int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size);
+int udev_monitor_get_fd(struct udev_monitor *udev_monitor);
+struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor);
+/* in-kernel socket filters to select messages that get delivered to a listener */
+int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor,
+                                                    const char *subsystem, const char *devtype);
+int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag);
+int udev_monitor_filter_update(struct udev_monitor *udev_monitor);
+int udev_monitor_filter_remove(struct udev_monitor *udev_monitor);
+
+/*
+ * udev_enumerate
+ *
+ * search sysfs for specific devices and provide a sorted list
+ */
+struct udev_enumerate;
+struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate);
+struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate);
+struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate);
+struct udev_enumerate *udev_enumerate_new(struct udev *udev);
+/* device properties filter */
+int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem);
+int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem);
+int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value);
+int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value);
+int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value);
+int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname);
+int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag);
+int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent);
+int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate);
+int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath);
+/* run enumeration with active filters */
+int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate);
+int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate);
+/* return device list */
+struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate);
+
+/*
+ * udev_queue
+ *
+ * access to the currently running udev events
+ */
+struct udev_queue;
+struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue);
+struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue);
+struct udev *udev_queue_get_udev(struct udev_queue *udev_queue);
+struct udev_queue *udev_queue_new(struct udev *udev);
+unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue);
+unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue);
+int udev_queue_get_udev_is_active(struct udev_queue *udev_queue);
+int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue);
+int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum);
+int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
+                                               unsigned long long int start, unsigned long long int end);
+struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue);
+
+/*
+ *  udev_hwdb
+ *
+ *  access to the static hardware properties database
+ */
+struct udev_hwdb;
+struct udev_hwdb *udev_hwdb_new(struct udev *udev);
+struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb);
+struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb);
+struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags);
+
+/*
+ * udev_util
+ *
+ * udev specific utilities
+ */
+int udev_util_encode_string(const char *str, char *str_enc, size_t len);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/src/libudev/libudev.pc.in b/src/libudev/libudev.pc.in
new file mode 100644 (file)
index 0000000..dad7139
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libudev
+Description: Library to access udev device information
+Version: @VERSION@
+Libs: -L${libdir} -ludev -lrt
+Libs.private:
+Cflags: -I${includedir}
diff --git a/src/libudev/libudev.sym b/src/libudev/libudev.sym
new file mode 100644 (file)
index 0000000..df6a1ae
--- /dev/null
@@ -0,0 +1,110 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+LIBUDEV_183 {
+global:
+        udev_device_get_action;
+        udev_device_get_devlinks_list_entry;
+        udev_device_get_devnode;
+        udev_device_get_devnum;
+        udev_device_get_devpath;
+        udev_device_get_devtype;
+        udev_device_get_driver;
+        udev_device_get_is_initialized;
+        udev_device_get_parent;
+        udev_device_get_parent_with_subsystem_devtype;
+        udev_device_get_properties_list_entry;
+        udev_device_get_property_value;
+        udev_device_get_seqnum;
+        udev_device_get_subsystem;
+        udev_device_get_sysattr_list_entry;
+        udev_device_get_sysattr_value;
+        udev_device_get_sysname;
+        udev_device_get_sysnum;
+        udev_device_get_syspath;
+        udev_device_get_tags_list_entry;
+        udev_device_get_udev;
+        udev_device_get_usec_since_initialized;
+        udev_device_has_tag;
+        udev_device_new_from_devnum;
+        udev_device_new_from_environment;
+        udev_device_new_from_subsystem_sysname;
+        udev_device_new_from_syspath;
+        udev_device_ref;
+        udev_device_unref;
+        udev_enumerate_add_match_is_initialized;
+        udev_enumerate_add_match_parent;
+        udev_enumerate_add_match_property;
+        udev_enumerate_add_match_subsystem;
+        udev_enumerate_add_match_sysattr;
+        udev_enumerate_add_match_sysname;
+        udev_enumerate_add_match_tag;
+        udev_enumerate_add_nomatch_subsystem;
+        udev_enumerate_add_nomatch_sysattr;
+        udev_enumerate_add_syspath;
+        udev_enumerate_get_list_entry;
+        udev_enumerate_get_udev;
+        udev_enumerate_new;
+        udev_enumerate_ref;
+        udev_enumerate_scan_devices;
+        udev_enumerate_scan_subsystems;
+        udev_enumerate_unref;
+        udev_get_log_priority;
+        udev_get_userdata;
+        udev_list_entry_get_by_name;
+        udev_list_entry_get_name;
+        udev_list_entry_get_next;
+        udev_list_entry_get_value;
+        udev_monitor_enable_receiving;
+        udev_monitor_filter_add_match_subsystem_devtype;
+        udev_monitor_filter_add_match_tag;
+        udev_monitor_filter_remove;
+        udev_monitor_filter_update;
+        udev_monitor_get_fd;
+        udev_monitor_get_udev;
+        udev_monitor_new_from_netlink;
+        udev_monitor_new_from_socket;
+        udev_monitor_receive_device;
+        udev_monitor_ref;
+        udev_monitor_set_receive_buffer_size;
+        udev_monitor_unref;
+        udev_new;
+        udev_queue_get_kernel_seqnum;
+        udev_queue_get_queue_is_empty;
+        udev_queue_get_queued_list_entry;
+        udev_queue_get_seqnum_is_finished;
+        udev_queue_get_seqnum_sequence_is_finished;
+        udev_queue_get_udev;
+        udev_queue_get_udev_is_active;
+        udev_queue_get_udev_seqnum;
+        udev_queue_new;
+        udev_queue_ref;
+        udev_queue_unref;
+        udev_ref;
+        udev_set_log_fn;
+        udev_set_log_priority;
+        udev_set_userdata;
+        udev_unref;
+        udev_util_encode_string;
+local:
+        *;
+};
+
+LIBUDEV_189 {
+global:
+        udev_device_new_from_device_id;
+} LIBUDEV_183;
+
+LIBUDEV_196 {
+global:
+        udev_hwdb_new;
+        udev_hwdb_ref;
+        udev_hwdb_unref;
+        udev_hwdb_get_properties_list_entry;
+} LIBUDEV_189;
diff --git a/src/locale/.gitignore b/src/locale/.gitignore
new file mode 100644 (file)
index 0000000..b1e0ba7
--- /dev/null
@@ -0,0 +1 @@
+org.freedesktop.locale1.policy
diff --git a/src/locale/Makefile b/src/locale/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/locale/generate-kbd-model-map b/src/locale/generate-kbd-model-map
new file mode 100755 (executable)
index 0000000..b8ffa0f
--- /dev/null
@@ -0,0 +1,31 @@
+import sys
+import system_config_keyboard.keyboard_models
+
+def strdash(s):
+        return s.strip() or '-'
+
+def tab_extend(s, n=1):
+        s = strdash(s)
+        k = len(s) // 8
+
+        if k >= n:
+                f = 1
+        else:
+                f = n - k
+
+        return s + '\t'*f
+
+
+models = system_config_keyboard.keyboard_models.KeyboardModels().get_models()
+
+print "# Generated from system-config-keyboard's model list"
+print "# consolelayout\t\txlayout\txmodel\t\txvariant\txoptions"
+
+for key, value in reversed(models.items()):
+        options = "terminate:ctrl_alt_bksp"
+        if value[4]:
+                options += ',' + value[4]
+
+        print ''.join((tab_extend(key, 3), tab_extend(value[1]),
+                       tab_extend(value[2], 2), tab_extend(value[3], 2),
+                       options))
diff --git a/src/locale/kbd-model-map b/src/locale/kbd-model-map
new file mode 100644 (file)
index 0000000..b0860ab
--- /dev/null
@@ -0,0 +1,76 @@
+# Generated from system-config-keyboard's model list
+# consolelayout                xlayout xmodel          xvariant        xoptions
+sg                     ch      pc105           de_nodeadkeys   terminate:ctrl_alt_bksp
+nl                     nl      pc105           -               terminate:ctrl_alt_bksp
+mk-utf                 mk,us   pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+trq                    tr      pc105           -               terminate:ctrl_alt_bksp
+guj                    in,us   pc105           guj             terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+uk                     gb      pc105           -               terminate:ctrl_alt_bksp
+is-latin1              is      pc105           -               terminate:ctrl_alt_bksp
+de                     de      pc105           -               terminate:ctrl_alt_bksp
+gur                    gur,us  pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+la-latin1              latam   pc105           -               terminate:ctrl_alt_bksp
+us                     us      pc105+inet      -               terminate:ctrl_alt_bksp
+ko                     kr      pc105           -               terminate:ctrl_alt_bksp
+ro-std                 ro      pc105           std             terminate:ctrl_alt_bksp
+de-latin1              de      pc105           -               terminate:ctrl_alt_bksp
+tml-inscript           in,us   pc105           tam             terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+slovene                        si      pc105           -               terminate:ctrl_alt_bksp
+hu101                  hu      pc105           qwerty          terminate:ctrl_alt_bksp
+jp106                  jp      jp106           -               terminate:ctrl_alt_bksp
+croat                  hr      pc105           -               terminate:ctrl_alt_bksp
+ben-probhat            in,us   pc105           ben_probhat     terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+fi-latin1              fi      pc105           -               terminate:ctrl_alt_bksp
+it2                    it      pc105           -               terminate:ctrl_alt_bksp
+hu                     hu      pc105           -               terminate:ctrl_alt_bksp
+sr-latin               rs      pc105           latin           terminate:ctrl_alt_bksp
+fi                     fi      pc105           -               terminate:ctrl_alt_bksp
+fr_CH                  ch      pc105           fr              terminate:ctrl_alt_bksp
+dk-latin1              dk      pc105           -               terminate:ctrl_alt_bksp
+fr                     fr      pc105           -               terminate:ctrl_alt_bksp
+it                     it      pc105           -               terminate:ctrl_alt_bksp
+tml-uni                        in,us   pc105           tam_TAB         terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ua-utf                 ua,us   pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+fr-latin1              fr      pc105           -               terminate:ctrl_alt_bksp
+sg-latin1              ch      pc105           de_nodeadkeys   terminate:ctrl_alt_bksp
+be-latin1              be      pc105           -               terminate:ctrl_alt_bksp
+dk                     dk      pc105           -               terminate:ctrl_alt_bksp
+fr-pc                  fr      pc105           -               terminate:ctrl_alt_bksp
+bg_pho-utf8            bg,us   pc105           ,phonetic       terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+it-ibm                 it      pc105           -               terminate:ctrl_alt_bksp
+cz-us-qwertz           cz,us   pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ar-digits              ara,us  pc105           digits          terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+br-abnt2               br      abnt2           -               terminate:ctrl_alt_bksp
+ro                     ro      pc105           -               terminate:ctrl_alt_bksp
+us-acentos             us      pc105           intl            terminate:ctrl_alt_bksp
+pt-latin1              pt      pc105           -               terminate:ctrl_alt_bksp
+ro-std-cedilla         ro      pc105           std_cedilla     terminate:ctrl_alt_bksp
+tj                     tj      pc105           -               terminate:ctrl_alt_bksp
+ar-qwerty              ara,us  pc105           qwerty          terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ar-azerty-digits       ara,us  pc105           azerty_digits   terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ben                    in,us   pc105           ben             terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+de-latin1-nodeadkeys   de      pc105           nodeadkeys      terminate:ctrl_alt_bksp
+no                     no      pc105           -               terminate:ctrl_alt_bksp
+bg_bds-utf8            bg,us   pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+dvorak                 us      pc105           dvorak          terminate:ctrl_alt_bksp
+ru                     ru,us   pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+cz-lat2                        cz      pc105           qwerty          terminate:ctrl_alt_bksp
+pl2                    pl      pc105           -               terminate:ctrl_alt_bksp
+es                     es      pc105           -               terminate:ctrl_alt_bksp
+ro-cedilla             ro      pc105           cedilla         terminate:ctrl_alt_bksp
+ie                     ie      pc105           -               terminate:ctrl_alt_bksp
+ar-azerty              ara,us  pc105           azerty          terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ar-qwerty-digits       ara,us  pc105           qwerty_digits   terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+et                     ee      pc105           -               terminate:ctrl_alt_bksp
+sk-qwerty              sk      pc105           -               terminate:ctrl_alt_bksp,qwerty
+dev                    dev,us  pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+fr-latin9              fr      pc105           latin9          terminate:ctrl_alt_bksp
+fr_CH-latin1           ch      pc105           fr              terminate:ctrl_alt_bksp
+cf                     ca      pc105           -               terminate:ctrl_alt_bksp
+sv-latin1              se      pc105           -               terminate:ctrl_alt_bksp
+sr-cy                  rs      pc105           -               terminate:ctrl_alt_bksp
+gr                     gr,us   pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+by                     by,us   pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+il                     il      pc105           -               terminate:ctrl_alt_bksp
+kazakh                 kz,us   pc105           -               terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+lt                     lt      pc105           -               terminate:ctrl_alt_bksp
diff --git a/src/locale/localectl.c b/src/locale/localectl.c
new file mode 100644 (file)
index 0000000..5d35f9c
--- /dev/null
@@ -0,0 +1,780 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <locale.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <ftw.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include "dbus-common.h"
+#include "util.h"
+#include "spawn-polkit-agent.h"
+#include "build.h"
+#include "strv.h"
+#include "pager.h"
+#include "set.h"
+#include "path-util.h"
+
+static bool arg_no_pager = false;
+static enum transport {
+        TRANSPORT_NORMAL,
+        TRANSPORT_SSH,
+        TRANSPORT_POLKIT
+} arg_transport = TRANSPORT_NORMAL;
+static bool arg_ask_password = true;
+static const char *arg_host = NULL;
+static bool arg_convert = true;
+
+static void pager_open_if_enabled(void) {
+
+        if (arg_no_pager)
+                return;
+
+        pager_open();
+}
+
+static void polkit_agent_open_if_enabled(void) {
+
+        /* Open the polkit agent as a child process if necessary */
+
+        if (!arg_ask_password)
+                return;
+
+        polkit_agent_open();
+}
+
+typedef struct StatusInfo {
+        char **locale;
+        const char *vconsole_keymap;
+        const char *vconsole_keymap_toggle;
+        const char *x11_layout;
+        const char *x11_model;
+        const char *x11_variant;
+        const char *x11_options;
+} StatusInfo;
+
+static void print_status_info(StatusInfo *i) {
+        assert(i);
+
+        if (strv_isempty(i->locale))
+                puts("   System Locale: n/a\n");
+        else {
+                char **j;
+
+                printf("   System Locale: %s\n", i->locale[0]);
+                STRV_FOREACH(j, i->locale + 1)
+                        printf("                  %s\n", *j);
+        }
+
+        printf("       VC Keymap: %s\n", strna(i->vconsole_keymap));
+        if (!isempty(i->vconsole_keymap_toggle))
+                printf("VC Toggle Keymap: %s\n", i->vconsole_keymap_toggle);
+
+        printf("      X11 Layout: %s\n", strna(i->x11_layout));
+        if (!isempty(i->x11_model))
+                printf("       X11 Model: %s\n", i->x11_model);
+        if (!isempty(i->x11_variant))
+                printf("     X11 Variant: %s\n", i->x11_variant);
+        if (!isempty(i->x11_options))
+                printf("     X11 Options: %s\n", i->x11_options);
+}
+
+static int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) {
+        int r;
+
+        assert(name);
+        assert(iter);
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRING: {
+                const char *s;
+
+                dbus_message_iter_get_basic(iter, &s);
+                if (!isempty(s)) {
+                        if (streq(name, "VConsoleKeymap"))
+                                i->vconsole_keymap = s;
+                        else if (streq(name, "VConsoleKeymapToggle"))
+                                i->vconsole_keymap_toggle = s;
+                        else if (streq(name, "X11Layout"))
+                                i->x11_layout = s;
+                        else if (streq(name, "X11Model"))
+                                i->x11_model = s;
+                        else if (streq(name, "X11Variant"))
+                                i->x11_variant = s;
+                        else if (streq(name, "X11Options"))
+                                i->x11_options = s;
+                }
+                break;
+        }
+
+        case DBUS_TYPE_ARRAY:
+
+                if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) {
+                        char **l;
+
+                        r = bus_parse_strv_iter(iter, &l);
+                        if (r < 0)
+                                return r;
+
+                        if (streq(name, "Locale")) {
+                                strv_free(i->locale);
+                                i->locale = l;
+                                l = NULL;
+                        }
+
+                        strv_free(l);
+                }
+        }
+
+        return 0;
+}
+
+static int show_status(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        const char *interface = "";
+        int r;
+        DBusMessageIter iter, sub, sub2, sub3;
+        StatusInfo info;
+
+        assert(args);
+
+        r = bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.locale1",
+                        "/org/freedesktop/locale1",
+                        "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_INVALID);
+        if (r < 0)
+                return r;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)  {
+                log_error("Failed to parse reply.");
+                return -EIO;
+        }
+
+        zero(info);
+        dbus_message_iter_recurse(&iter, &sub);
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *name;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)  {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                dbus_message_iter_recurse(&sub2, &sub3);
+
+                r = status_property(name, &sub3, &info);
+                if (r < 0) {
+                        log_error("Failed to parse reply.");
+                        return r;
+                }
+
+                dbus_message_iter_next(&sub);
+        }
+
+        print_status_info(&info);
+        strv_free(info.locale);
+        return 0;
+}
+
+static int set_locale(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
+        dbus_bool_t interactive = true;
+        DBusError error;
+        DBusMessageIter iter;
+        int r;
+
+        assert(bus);
+        assert(args);
+
+        dbus_error_init(&error);
+
+        polkit_agent_open_if_enabled();
+
+        m = dbus_message_new_method_call(
+                        "org.freedesktop.locale1",
+                        "/org/freedesktop/locale1",
+                        "org.freedesktop.locale1",
+                        "SetLocale");
+        if (!m)
+                return log_oom();
+
+        dbus_message_iter_init_append(m, &iter);
+
+        r = bus_append_strv_iter(&iter, args + 1);
+        if (r < 0)
+                return log_oom();
+
+        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &interactive))
+                return log_oom();
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+        if (!reply) {
+                log_error("Failed to issue method call: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        r = 0;
+
+finish:
+        dbus_error_free(&error);
+        return r;
+}
+
+static int list_locales(DBusConnection *bus, char **args, unsigned n) {
+        /* Stolen from glibc... */
+
+        struct locarhead {
+                uint32_t magic;
+                /* Serial number.  */
+                uint32_t serial;
+                /* Name hash table.  */
+                uint32_t namehash_offset;
+                uint32_t namehash_used;
+                uint32_t namehash_size;
+                /* String table.  */
+                uint32_t string_offset;
+                uint32_t string_used;
+                uint32_t string_size;
+                /* Table with locale records.  */
+                uint32_t locrectab_offset;
+                uint32_t locrectab_used;
+                uint32_t locrectab_size;
+                /* MD5 sum hash table.  */
+                uint32_t sumhash_offset;
+                uint32_t sumhash_used;
+                uint32_t sumhash_size;
+        };
+
+        struct namehashent {
+                /* Hash value of the name.  */
+                uint32_t hashval;
+                /* Offset of the name in the string table.  */
+                uint32_t name_offset;
+                /* Offset of the locale record.  */
+                uint32_t locrec_offset;
+        };
+
+        const struct locarhead *h;
+        const struct namehashent *e;
+        const void *p = MAP_FAILED;
+        _cleanup_close_ int fd = -1;
+        _cleanup_strv_free_ char **l = NULL;
+        char **j;
+        Set *locales;
+        size_t sz = 0;
+        struct stat st;
+        unsigned i;
+        int r;
+
+        locales = set_new(string_hash_func, string_compare_func);
+        if (!locales)
+                return log_oom();
+
+        fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0) {
+                log_error("Failed to open locale archive: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if (fstat(fd, &st) < 0) {
+                log_error("fstat() failed: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if (!S_ISREG(st.st_mode)) {
+                log_error("Archive file is not regular");
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        if (st.st_size < (off_t) sizeof(struct locarhead)) {
+                log_error("Archive has invalid size");
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+        if (p == MAP_FAILED) {
+                log_error("Failed to map archive: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        h = (const struct locarhead *) p;
+        if (h->magic != 0xde020109 ||
+            h->namehash_offset + h->namehash_size > st.st_size ||
+            h->string_offset + h->string_size > st.st_size ||
+            h->locrectab_offset + h->locrectab_size > st.st_size ||
+            h->sumhash_offset + h->sumhash_size > st.st_size) {
+                log_error("Invalid archive file.");
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        e = (const struct namehashent*) ((const uint8_t*) p + h->namehash_offset);
+        for (i = 0; i < h->namehash_size; i++) {
+                char *z;
+
+                if (e[i].locrec_offset == 0)
+                        continue;
+
+                z = strdup((char*) p + e[i].name_offset);
+                if (!z) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                r = set_put(locales, z);
+                if (r < 0) {
+                        free(z);
+                        log_error("Failed to add locale: %s", strerror(-r));
+                        goto finish;
+                }
+        }
+
+        l = set_get_strv(locales);
+        if (!l) {
+                r = log_oom();
+                goto finish;
+        }
+
+        set_free(locales);
+        locales = NULL;
+
+        strv_sort(l);
+
+        pager_open_if_enabled();
+
+        STRV_FOREACH(j, l)
+                puts(*j);
+
+        r = 0;
+
+finish:
+        if (p != MAP_FAILED)
+                munmap((void*) p, sz);
+
+        set_free_free(locales);
+
+        return r;
+}
+
+static int set_vconsole_keymap(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t interactive = true, b;
+        const char *map, *toggle_map;
+
+        assert(bus);
+        assert(args);
+
+        if (n > 3) {
+                log_error("Too many arguments.");
+                return -EINVAL;
+        }
+
+        polkit_agent_open_if_enabled();
+
+        map = args[1];
+        toggle_map = n > 2 ? args[2] : "";
+        b = arg_convert;
+
+        return bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.locale1",
+                        "/org/freedesktop/locale1",
+                        "org.freedesktop.locale1",
+                        "SetVConsoleKeyboard",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &map,
+                        DBUS_TYPE_STRING, &toggle_map,
+                        DBUS_TYPE_BOOLEAN, &b,
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static Set *keymaps = NULL;
+
+static int nftw_cb(
+                const char *fpath,
+                const struct stat *sb,
+                int tflag,
+                struct FTW *ftwbuf) {
+
+        char *p, *e;
+        int r;
+
+        if (tflag != FTW_F)
+                return 0;
+
+        if (!endswith(fpath, ".map") &&
+            !endswith(fpath, ".map.gz"))
+                return 0;
+
+        p = strdup(path_get_file_name(fpath));
+        if (!p)
+                return log_oom();
+
+        e = endswith(p, ".map");
+        if (e)
+                *e = 0;
+
+        e = endswith(p, ".map.gz");
+        if (e)
+                *e = 0;
+
+        r = set_put(keymaps, p);
+        if (r == -EEXIST)
+                free(p);
+        else if (r < 0) {
+                log_error("Can't add keymap: %s", strerror(-r));
+                free(p);
+                return r;
+        }
+
+        return 0;
+}
+
+static int list_vconsole_keymaps(DBusConnection *bus, char **args, unsigned n) {
+        char _cleanup_strv_free_ **l = NULL;
+        char **i;
+
+        keymaps = set_new(string_hash_func, string_compare_func);
+        if (!keymaps)
+                return log_oom();
+
+        nftw("/usr/share/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
+        nftw("/usr/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
+        nftw("/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
+
+        l = set_get_strv(keymaps);
+        if (!l) {
+                set_free_free(keymaps);
+                return log_oom();
+        }
+
+        set_free(keymaps);
+
+        if (strv_isempty(l)) {
+                log_error("Couldn't find any console keymaps.");
+                return -ENOENT;
+        }
+
+        strv_sort(l);
+
+        pager_open_if_enabled();
+
+        STRV_FOREACH(i, l)
+                puts(*i);
+
+
+        return 0;
+}
+
+static int set_x11_keymap(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t interactive = true, b;
+        const char *layout, *model, *variant, *options;
+
+        assert(bus);
+        assert(args);
+
+        if (n > 5) {
+                log_error("Too many arguments.");
+                return -EINVAL;
+        }
+
+        polkit_agent_open_if_enabled();
+
+        layout = args[1];
+        model = n > 2 ? args[2] : "";
+        variant = n > 3 ? args[3] : "";
+        options = n > 4 ? args[4] : "";
+        b = arg_convert;
+
+        return bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.locale1",
+                        "/org/freedesktop/locale1",
+                        "org.freedesktop.locale1",
+                        "SetX11Keyboard",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &layout,
+                        DBUS_TYPE_STRING, &model,
+                        DBUS_TYPE_STRING, &variant,
+                        DBUS_TYPE_STRING, &options,
+                        DBUS_TYPE_BOOLEAN, &b,
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] COMMAND ...\n\n"
+               "Query or change system time and date settings.\n\n"
+               "  -h --help              Show this help\n"
+               "     --version           Show package version\n"
+               "     --no-convert        Don't convert keyboard mappings\n"
+               "     --no-pager          Do not pipe output into a pager\n"
+               "     --no-ask-password   Do not prompt for password\n"
+               "  -H --host=[USER@]HOST  Operate on remote host\n\n"
+               "Commands:\n"
+               "  status                 Show current locale settings\n"
+               "  set-locale LOCALE...   Set system locale\n"
+               "  list-locales           Show known locales\n"
+               "  set-keymap MAP [MAP]   Set virtual console keyboard mapping\n"
+               "  list-keymaps           Show known virtual console keyboard mappings\n"
+               "  set-x11-keymap LAYOUT [MODEL] [VARIANT] [OPTIONS]\n"
+               "                         Set X11 keyboard mapping\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_NO_PAGER,
+                ARG_NO_CONVERT,
+                ARG_NO_ASK_PASSWORD
+        };
+
+        static const struct option options[] = {
+                { "help",                no_argument,       NULL, 'h'                     },
+                { "version",             no_argument,       NULL, ARG_VERSION             },
+                { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
+                { "host",                required_argument, NULL, 'H'                     },
+                { "privileged",          no_argument,       NULL, 'P'                     },
+                { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
+                { "no-convert",          no_argument,       NULL, ARG_NO_CONVERT          },
+                { NULL,                  0,                 NULL, 0                       }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "has:H:P", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case 'P':
+                        arg_transport = TRANSPORT_POLKIT;
+                        break;
+
+                case 'H':
+                        arg_transport = TRANSPORT_SSH;
+                        arg_host = optarg;
+                        break;
+
+                case ARG_NO_CONVERT:
+                        arg_convert = false;
+                        break;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        return 1;
+}
+
+static int localectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) {
+
+        static const struct {
+                const char* verb;
+                const enum {
+                        MORE,
+                        LESS,
+                        EQUAL
+                } argc_cmp;
+                const int argc;
+                int (* const dispatch)(DBusConnection *bus, char **args, unsigned n);
+        } verbs[] = {
+                { "status",         LESS,   1, show_status           },
+                { "set-locale",     MORE,   2, set_locale            },
+                { "list-locales",   EQUAL,  1, list_locales          },
+                { "set-keymap",     MORE,   2, set_vconsole_keymap   },
+                { "list-keymaps",   EQUAL,  1, list_vconsole_keymaps },
+                { "set-x11-keymap", MORE,   2, set_x11_keymap        },
+        };
+
+        int left;
+        unsigned i;
+
+        assert(argc >= 0);
+        assert(argv);
+        assert(error);
+
+        left = argc - optind;
+
+        if (left <= 0)
+                /* Special rule: no arguments means "status" */
+                i = 0;
+        else {
+                if (streq(argv[optind], "help")) {
+                        help();
+                        return 0;
+                }
+
+                for (i = 0; i < ELEMENTSOF(verbs); i++)
+                        if (streq(argv[optind], verbs[i].verb))
+                                break;
+
+                if (i >= ELEMENTSOF(verbs)) {
+                        log_error("Unknown operation %s", argv[optind]);
+                        return -EINVAL;
+                }
+        }
+
+        switch (verbs[i].argc_cmp) {
+
+        case EQUAL:
+                if (left != verbs[i].argc) {
+                        log_error("Invalid number of arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case MORE:
+                if (left < verbs[i].argc) {
+                        log_error("Too few arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case LESS:
+                if (left > verbs[i].argc) {
+                        log_error("Too many arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("Unknown comparison operator.");
+        }
+
+        if (!bus) {
+                log_error("Failed to get D-Bus connection: %s", error->message);
+                return -EIO;
+        }
+
+        return verbs[i].dispatch(bus, argv + optind, left);
+}
+
+int main(int argc, char *argv[]) {
+        int r, retval = EXIT_FAILURE;
+        DBusConnection *bus = NULL;
+        DBusError error;
+
+        dbus_error_init(&error);
+
+        setlocale(LC_ALL, "");
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                goto finish;
+        else if (r == 0) {
+                retval = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        if (arg_transport == TRANSPORT_NORMAL)
+                bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        else if (arg_transport == TRANSPORT_POLKIT)
+                bus_connect_system_polkit(&bus, &error);
+        else if (arg_transport == TRANSPORT_SSH)
+                bus_connect_system_ssh(NULL, arg_host, &bus, &error);
+        else
+                assert_not_reached("Uh, invalid transport...");
+
+        r = localectl_main(bus, argc, argv, &error);
+        retval = r < 0 ? EXIT_FAILURE : r;
+
+finish:
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        dbus_error_free(&error);
+        dbus_shutdown();
+
+        pager_close();
+
+        return retval;
+}
diff --git a/src/locale/localed.c b/src/locale/localed.c
new file mode 100644 (file)
index 0000000..bb2a3a2
--- /dev/null
@@ -0,0 +1,1417 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "mkdir.h"
+#include "strv.h"
+#include "dbus-common.h"
+#include "polkit.h"
+#include "def.h"
+
+#define INTERFACE                                                       \
+        " <interface name=\"org.freedesktop.locale1\">\n"               \
+        "  <property name=\"Locale\" type=\"as\" access=\"read\"/>\n"   \
+        "  <property name=\"VConsoleKeymap\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"VConsoleKeymapToggle\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"X11Layout\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"X11Model\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"X11Variant\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"X11Options\" type=\"s\" access=\"read\"/>\n" \
+        "  <method name=\"SetLocale\">\n"                               \
+        "   <arg name=\"locale\" type=\"as\" direction=\"in\"/>\n"      \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetVConsoleKeyboard\">\n"                      \
+        "   <arg name=\"keymap\" type=\"s\" direction=\"in\"/>\n"       \
+        "   <arg name=\"keymap_toggle\" type=\"s\" direction=\"in\"/>\n" \
+        "   <arg name=\"convert\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetX11Keyboard\">\n"                          \
+        "   <arg name=\"layout\" type=\"s\" direction=\"in\"/>\n"       \
+        "   <arg name=\"model\" type=\"s\" direction=\"in\"/>\n"        \
+        "   <arg name=\"variant\" type=\"s\" direction=\"in\"/>\n"      \
+        "   <arg name=\"options\" type=\"s\" direction=\"in\"/>\n"      \
+        "   <arg name=\"convert\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        INTERFACE                                                       \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        BUS_PEER_INTERFACE                                              \
+        "</node>\n"
+
+#define INTERFACES_LIST                         \
+        BUS_GENERIC_INTERFACES_LIST             \
+        "org.freedesktop.locale1\0"
+
+const char locale_interface[] _introspect_("locale1") = INTERFACE;
+
+enum {
+        /* We don't list LC_ALL here on purpose. People should be
+         * using LANG instead. */
+
+        PROP_LANG,
+        PROP_LANGUAGE,
+        PROP_LC_CTYPE,
+        PROP_LC_NUMERIC,
+        PROP_LC_TIME,
+        PROP_LC_COLLATE,
+        PROP_LC_MONETARY,
+        PROP_LC_MESSAGES,
+        PROP_LC_PAPER,
+        PROP_LC_NAME,
+        PROP_LC_ADDRESS,
+        PROP_LC_TELEPHONE,
+        PROP_LC_MEASUREMENT,
+        PROP_LC_IDENTIFICATION,
+        _PROP_MAX
+};
+
+static const char * const names[_PROP_MAX] = {
+        [PROP_LANG] = "LANG",
+        [PROP_LANGUAGE] = "LANGUAGE",
+        [PROP_LC_CTYPE] = "LC_CTYPE",
+        [PROP_LC_NUMERIC] = "LC_NUMERIC",
+        [PROP_LC_TIME] = "LC_TIME",
+        [PROP_LC_COLLATE] = "LC_COLLATE",
+        [PROP_LC_MONETARY] = "LC_MONETARY",
+        [PROP_LC_MESSAGES] = "LC_MESSAGES",
+        [PROP_LC_PAPER] = "LC_PAPER",
+        [PROP_LC_NAME] = "LC_NAME",
+        [PROP_LC_ADDRESS] = "LC_ADDRESS",
+        [PROP_LC_TELEPHONE] = "LC_TELEPHONE",
+        [PROP_LC_MEASUREMENT] = "LC_MEASUREMENT",
+        [PROP_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
+};
+
+static char *data[_PROP_MAX] = {
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL
+};
+
+typedef struct State {
+        char *x11_layout, *x11_model, *x11_variant, *x11_options;
+        char *vc_keymap, *vc_keymap_toggle;
+} State;
+
+static State state;
+
+static usec_t remain_until = 0;
+
+static int free_and_set(char **s, const char *v) {
+        int r;
+        char *t;
+
+        assert(s);
+
+        r = strdup_or_null(isempty(v) ? NULL : v, &t);
+        if (r < 0)
+                return r;
+
+        free(*s);
+        *s = t;
+
+        return 0;
+}
+
+static void free_data_locale(void) {
+        int p;
+
+        for (p = 0; p < _PROP_MAX; p++) {
+                free(data[p]);
+                data[p] = NULL;
+        }
+}
+
+static void free_data_x11(void) {
+        free(state.x11_layout);
+        free(state.x11_model);
+        free(state.x11_variant);
+        free(state.x11_options);
+
+        state.x11_layout = state.x11_model = state.x11_variant = state.x11_options = NULL;
+}
+
+static void free_data_vconsole(void) {
+        free(state.vc_keymap);
+        free(state.vc_keymap_toggle);
+
+        state.vc_keymap = state.vc_keymap_toggle = NULL;
+}
+
+static void simplify(void) {
+        int p;
+
+        for (p = 1; p < _PROP_MAX; p++)
+                if (isempty(data[p]) || streq_ptr(data[PROP_LANG], data[p])) {
+                        free(data[p]);
+                        data[p] = NULL;
+                }
+}
+
+static int read_data_locale(void) {
+        int r;
+
+        free_data_locale();
+
+        r = parse_env_file("/etc/locale.conf", NEWLINE,
+                           "LANG",              &data[PROP_LANG],
+                           "LANGUAGE",          &data[PROP_LANGUAGE],
+                           "LC_CTYPE",          &data[PROP_LC_CTYPE],
+                           "LC_NUMERIC",        &data[PROP_LC_NUMERIC],
+                           "LC_TIME",           &data[PROP_LC_TIME],
+                           "LC_COLLATE",        &data[PROP_LC_COLLATE],
+                           "LC_MONETARY",       &data[PROP_LC_MONETARY],
+                           "LC_MESSAGES",       &data[PROP_LC_MESSAGES],
+                           "LC_PAPER",          &data[PROP_LC_PAPER],
+                           "LC_NAME",           &data[PROP_LC_NAME],
+                           "LC_ADDRESS",        &data[PROP_LC_ADDRESS],
+                           "LC_TELEPHONE",      &data[PROP_LC_TELEPHONE],
+                           "LC_MEASUREMENT",    &data[PROP_LC_MEASUREMENT],
+                           "LC_IDENTIFICATION", &data[PROP_LC_IDENTIFICATION],
+                           NULL);
+
+        if (r == -ENOENT) {
+                int p;
+
+                /* Fill in what we got passed from systemd. */
+
+                for (p = 0; p < _PROP_MAX; p++) {
+                        char *e, *d;
+
+                        assert(names[p]);
+
+                        e = getenv(names[p]);
+                        if (e) {
+                                d = strdup(e);
+                                if (!d)
+                                        return -ENOMEM;
+                        } else
+                                d = NULL;
+
+                        free(data[p]);
+                        data[p] = d;
+                }
+
+                r = 0;
+        }
+
+        simplify();
+        return r;
+}
+
+static void free_data(void) {
+        free_data_locale();
+        free_data_vconsole();
+        free_data_x11();
+}
+
+static int read_data_vconsole(void) {
+        int r;
+
+        free_data_vconsole();
+
+        r = parse_env_file("/etc/vconsole.conf", NEWLINE,
+                           "KEYMAP",        &state.vc_keymap,
+                           "KEYMAP_TOGGLE", &state.vc_keymap_toggle,
+                           NULL);
+
+        if (r < 0 && r != -ENOENT)
+                return r;
+
+        return 0;
+}
+
+static int read_data_x11(void) {
+        FILE *f;
+        char line[LINE_MAX];
+        bool in_section = false;
+
+        free_data_x11();
+
+        f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
+        if (!f)
+                return errno == ENOENT ? 0 : -errno;
+
+        while (fgets(line, sizeof(line), f)) {
+                char *l;
+
+                char_array_0(line);
+                l = strstrip(line);
+
+                if (l[0] == 0 || l[0] == '#')
+                        continue;
+
+                if (in_section && first_word(l, "Option")) {
+                        char **a;
+
+                        a = strv_split_quoted(l);
+                        if (!a) {
+                                fclose(f);
+                                return -ENOMEM;
+                        }
+
+                        if (strv_length(a) == 3) {
+
+                                if (streq(a[1], "XkbLayout")) {
+                                        free(state.x11_layout);
+                                        state.x11_layout = a[2];
+                                        a[2] = NULL;
+                                } else if (streq(a[1], "XkbModel")) {
+                                        free(state.x11_model);
+                                        state.x11_model = a[2];
+                                        a[2] = NULL;
+                                } else if (streq(a[1], "XkbVariant")) {
+                                        free(state.x11_variant);
+                                        state.x11_variant = a[2];
+                                        a[2] = NULL;
+                                } else if (streq(a[1], "XkbOptions")) {
+                                        free(state.x11_options);
+                                        state.x11_options = a[2];
+                                        a[2] = NULL;
+                                }
+                        }
+
+                        strv_free(a);
+
+                } else if (!in_section && first_word(l, "Section")) {
+                        char **a;
+
+                        a = strv_split_quoted(l);
+                        if (!a) {
+                                fclose(f);
+                                return -ENOMEM;
+                        }
+
+                        if (strv_length(a) == 2 && streq(a[1], "InputClass"))
+                                in_section = true;
+
+                        strv_free(a);
+                } else if (in_section && first_word(l, "EndSection"))
+                        in_section = false;
+        }
+
+        fclose(f);
+
+        return 0;
+}
+
+static int read_data(void) {
+        int r, q, p;
+
+        r = read_data_locale();
+        q = read_data_vconsole();
+        p = read_data_x11();
+
+        return r < 0 ? r : q < 0 ? q : p;
+}
+
+static int write_data_locale(void) {
+        int r, p;
+        char **l = NULL;
+
+        r = load_env_file("/etc/locale.conf", &l);
+        if (r < 0 && r != -ENOENT)
+                return r;
+
+        for (p = 0; p < _PROP_MAX; p++) {
+                char *t, **u;
+
+                assert(names[p]);
+
+                if (isempty(data[p])) {
+                        l = strv_env_unset(l, names[p]);
+                        continue;
+                }
+
+                if (asprintf(&t, "%s=%s", names[p], data[p]) < 0) {
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+
+                u = strv_env_set(l, t);
+                free(t);
+                strv_free(l);
+
+                if (!u)
+                        return -ENOMEM;
+
+                l = u;
+        }
+
+        if (strv_isempty(l)) {
+                strv_free(l);
+
+                if (unlink("/etc/locale.conf") < 0)
+                        return errno == ENOENT ? 0 : -errno;
+
+                return 0;
+        }
+
+        r = write_env_file("/etc/locale.conf", l);
+        strv_free(l);
+
+        return r;
+}
+
+static void push_data(DBusConnection *bus) {
+        char **l_set = NULL, **l_unset = NULL, **t;
+        int c_set = 0, c_unset = 0, p;
+        DBusError error;
+        DBusMessage *m = NULL, *reply = NULL;
+        DBusMessageIter iter, sub;
+
+        dbus_error_init(&error);
+
+        assert(bus);
+
+        l_set = new0(char*, _PROP_MAX);
+        l_unset = new0(char*, _PROP_MAX);
+        if (!l_set || !l_unset) {
+                log_oom();
+                goto finish;
+        }
+
+        for (p = 0; p < _PROP_MAX; p++) {
+                assert(names[p]);
+
+                if (isempty(data[p]))
+                        l_unset[c_set++] = (char*) names[p];
+                else {
+                        char *s;
+
+                        if (asprintf(&s, "%s=%s", names[p], data[p]) < 0) {
+                                log_oom();
+                                goto finish;
+                        }
+
+                        l_set[c_unset++] = s;
+                }
+        }
+
+        assert(c_set + c_unset == _PROP_MAX);
+        m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment");
+        if (!m) {
+                log_error("Could not allocate message.");
+                goto finish;
+        }
+
+        dbus_message_iter_init_append(m, &iter);
+
+        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) {
+                log_oom();
+                goto finish;
+        }
+
+        STRV_FOREACH(t, l_unset)
+                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t)) {
+                        log_oom();
+                        goto finish;
+                }
+
+        if (!dbus_message_iter_close_container(&iter, &sub) ||
+            !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) {
+                log_oom();
+                goto finish;
+        }
+
+        STRV_FOREACH(t, l_set)
+                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t)) {
+                        log_oom();
+                        goto finish;
+                }
+
+        if (!dbus_message_iter_close_container(&iter, &sub)) {
+                log_oom();
+                goto finish;
+        }
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+        if (!reply) {
+                log_error("Failed to set locale information: %s", bus_error_message(&error));
+                goto finish;
+        }
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        strv_free(l_set);
+        free(l_unset);
+}
+
+static int write_data_vconsole(void) {
+        int r;
+        char **l = NULL;
+
+        r = load_env_file("/etc/vconsole.conf", &l);
+        if (r < 0 && r != -ENOENT)
+                return r;
+
+        if (isempty(state.vc_keymap))
+                l = strv_env_unset(l, "KEYMAP");
+        else {
+                char *s, **u;
+
+                s = strappend("KEYMAP=", state.vc_keymap);
+                if (!s) {
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+
+                u = strv_env_set(l, s);
+                free(s);
+                strv_free(l);
+
+                if (!u)
+                        return -ENOMEM;
+
+                l = u;
+        }
+
+        if (isempty(state.vc_keymap_toggle))
+                l = strv_env_unset(l, "KEYMAP_TOGGLE");
+        else  {
+                char *s, **u;
+
+                s = strappend("KEYMAP_TOGGLE=", state.vc_keymap_toggle);
+                if (!s) {
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+
+                u = strv_env_set(l, s);
+                free(s);
+                strv_free(l);
+
+                if (!u)
+                        return -ENOMEM;
+
+                l = u;
+        }
+
+        if (strv_isempty(l)) {
+                strv_free(l);
+
+                if (unlink("/etc/vconsole.conf") < 0)
+                        return errno == ENOENT ? 0 : -errno;
+
+                return 0;
+        }
+
+        r = write_env_file("/etc/vconsole.conf", l);
+        strv_free(l);
+
+        return r;
+}
+
+static int write_data_x11(void) {
+        FILE *f;
+        char *temp_path;
+        int r;
+
+        if (isempty(state.x11_layout) &&
+            isempty(state.x11_model) &&
+            isempty(state.x11_variant) &&
+            isempty(state.x11_options)) {
+
+                if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0)
+                        return errno == ENOENT ? 0 : -errno;
+
+                return 0;
+        }
+
+        mkdir_p_label("/etc/X11/xorg.conf.d", 0755);
+
+        r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path);
+        if (r < 0)
+                return r;
+
+        fchmod(fileno(f), 0644);
+
+        fputs("# Read and parsed by systemd-localed. It's probably wise not to edit this file\n"
+              "# manually too freely.\n"
+              "Section \"InputClass\"\n"
+              "        Identifier \"system-keyboard\"\n"
+              "        MatchIsKeyboard \"on\"\n", f);
+
+        if (!isempty(state.x11_layout))
+                fprintf(f, "        Option \"XkbLayout\" \"%s\"\n", state.x11_layout);
+
+        if (!isempty(state.x11_model))
+                fprintf(f, "        Option \"XkbModel\" \"%s\"\n", state.x11_model);
+
+        if (!isempty(state.x11_variant))
+                fprintf(f, "        Option \"XkbVariant\" \"%s\"\n", state.x11_variant);
+
+        if (!isempty(state.x11_options))
+                fprintf(f, "        Option \"XkbOptions\" \"%s\"\n", state.x11_options);
+
+        fputs("EndSection\n", f);
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) {
+                r = -errno;
+                unlink("/etc/X11/xorg.conf.d/00-keyboard.conf");
+                unlink(temp_path);
+        } else
+                r = 0;
+
+        fclose(f);
+        free(temp_path);
+
+        return r;
+}
+
+static int load_vconsole_keymap(DBusConnection *bus, DBusError *error) {
+        DBusMessage *m = NULL, *reply = NULL;
+        const char *name = "systemd-vconsole-setup.service", *mode = "replace";
+        int r;
+        DBusError _error;
+
+        assert(bus);
+
+        if (!error) {
+                dbus_error_init(&_error);
+                error = &_error;
+        }
+
+        m = dbus_message_new_method_call(
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "RestartUnit");
+        if (!m) {
+                log_error("Could not allocate message.");
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (!dbus_message_append_args(m,
+                                      DBUS_TYPE_STRING, &name,
+                                      DBUS_TYPE_STRING, &mode,
+                                      DBUS_TYPE_INVALID)) {
+                log_error("Could not append arguments to message.");
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+        if (!reply) {
+                log_error("Failed to issue method call: %s", bus_error_message(error));
+                r = -EIO;
+                goto finish;
+        }
+
+        r = 0;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        if (error == &_error)
+                dbus_error_free(error);
+
+        return r;
+}
+
+static char *strnulldash(const char *s) {
+        return s == NULL || *s == 0 || (s[0] == '-' && s[1] == 0) ? NULL : (char*) s;
+}
+
+static int read_next_mapping(FILE *f, unsigned *n, char ***a) {
+        assert(f);
+        assert(n);
+        assert(a);
+
+        for (;;) {
+                char line[LINE_MAX];
+                char *l, **b;
+
+                errno = 0;
+                if (!fgets(line, sizeof(line), f)) {
+
+                        if (ferror(f))
+                                return errno ? -errno : -EIO;
+
+                        return 0;
+                }
+
+                (*n) ++;
+
+                l = strstrip(line);
+                if (l[0] == 0 || l[0] == '#')
+                        continue;
+
+                b = strv_split_quoted(l);
+                if (!b)
+                        return -ENOMEM;
+
+                if (strv_length(b) < 5) {
+                        log_error("Invalid line "SYSTEMD_KBD_MODEL_MAP":%u, ignoring.", *n);
+                        strv_free(b);
+                        continue;
+
+                }
+
+                *a = b;
+                return 1;
+        }
+}
+
+static int convert_vconsole_to_x11(DBusConnection *connection) {
+        bool modified = false;
+
+        assert(connection);
+
+        if (isempty(state.vc_keymap)) {
+
+                modified =
+                        !isempty(state.x11_layout) ||
+                        !isempty(state.x11_model) ||
+                        !isempty(state.x11_variant) ||
+                        !isempty(state.x11_options);
+
+                free_data_x11();
+        } else {
+                FILE *f;
+                unsigned n = 0;
+
+                f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
+                if (!f)
+                        return -errno;
+
+                for (;;) {
+                        char **a;
+                        int r;
+
+                        r = read_next_mapping(f, &n, &a);
+                        if (r < 0) {
+                                fclose(f);
+                                return r;
+                        }
+
+                        if (r == 0)
+                                break;
+
+                        if (!streq(state.vc_keymap, a[0])) {
+                                strv_free(a);
+                                continue;
+                        }
+
+                        if (!streq_ptr(state.x11_layout, strnulldash(a[1])) ||
+                            !streq_ptr(state.x11_model, strnulldash(a[2])) ||
+                            !streq_ptr(state.x11_variant, strnulldash(a[3])) ||
+                            !streq_ptr(state.x11_options, strnulldash(a[4]))) {
+
+                                if (free_and_set(&state.x11_layout, strnulldash(a[1])) < 0 ||
+                                    free_and_set(&state.x11_model, strnulldash(a[2])) < 0 ||
+                                    free_and_set(&state.x11_variant, strnulldash(a[3])) < 0 ||
+                                    free_and_set(&state.x11_options, strnulldash(a[4])) < 0) {
+                                        strv_free(a);
+                                        fclose(f);
+                                        return -ENOMEM;
+                                }
+
+                                modified = true;
+                        }
+
+                        strv_free(a);
+                        break;
+                }
+
+                fclose(f);
+        }
+
+        if (modified) {
+                dbus_bool_t b;
+                DBusMessage *changed;
+                int r;
+
+                r = write_data_x11();
+                if (r < 0)
+                        log_error("Failed to set X11 keyboard layout: %s", strerror(-r));
+
+                changed = bus_properties_changed_new(
+                                "/org/freedesktop/locale1",
+                                "org.freedesktop.locale1",
+                                "X11Layout\0"
+                                "X11Model\0"
+                                "X11Variant\0"
+                                "X11Options\0");
+
+                if (!changed)
+                        return -ENOMEM;
+
+                b = dbus_connection_send(connection, changed, NULL);
+                dbus_message_unref(changed);
+
+                if (!b)
+                        return -ENOMEM;
+        }
+
+        return 0;
+}
+
+static int convert_x11_to_vconsole(DBusConnection *connection) {
+        bool modified = false;
+
+        assert(connection);
+
+        if (isempty(state.x11_layout)) {
+
+                modified =
+                        !isempty(state.vc_keymap) ||
+                        !isempty(state.vc_keymap_toggle);
+
+                free_data_x11();
+        } else {
+                FILE *f;
+                unsigned n = 0;
+                unsigned best_matching = 0;
+                char *new_keymap = NULL;
+
+                f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
+                if (!f)
+                        return -errno;
+
+                for (;;) {
+                        char **a;
+                        unsigned matching = 0;
+                        int r;
+
+                        r = read_next_mapping(f, &n, &a);
+                        if (r < 0) {
+                                fclose(f);
+                                return r;
+                        }
+
+                        if (r == 0)
+                                break;
+
+                        /* Determine how well matching this entry is */
+                        if (streq_ptr(state.x11_layout, a[1]))
+                                /* If we got an exact match, this is best */
+                                matching = 10;
+                        else {
+                                size_t x;
+
+                                x = strcspn(state.x11_layout, ",");
+
+                                /* We have multiple X layouts, look
+                                 * for an entry that matches our key
+                                 * with the everything but the first
+                                 * layout stripped off. */
+                                if (x > 0 &&
+                                    strlen(a[1]) == x &&
+                                    strncmp(state.x11_layout, a[1], x) == 0)
+                                        matching = 5;
+                                else  {
+                                        size_t w;
+
+                                        /* If that didn't work, strip
+                                         * off the other layouts from
+                                         * the entry, too */
+
+                                        w = strcspn(a[1], ",");
+
+                                        if (x > 0 && x == w &&
+                                            memcmp(state.x11_layout, a[1], x) == 0)
+                                                matching = 1;
+                                }
+                        }
+
+                        if (matching > 0 &&
+                            streq_ptr(state.x11_model, a[2])) {
+                                matching++;
+
+                                if (streq_ptr(state.x11_variant, a[3])) {
+                                        matching++;
+
+                                        if (streq_ptr(state.x11_options, a[4]))
+                                                matching++;
+                                }
+                        }
+
+                        /* The best matching entry so far, then let's
+                         * save that */
+                        if (matching > best_matching) {
+                                best_matching = matching;
+
+                                free(new_keymap);
+                                new_keymap = strdup(a[0]);
+
+                                if (!new_keymap) {
+                                        strv_free(a);
+                                        fclose(f);
+                                        return -ENOMEM;
+                                }
+                        }
+
+                        strv_free(a);
+                }
+
+                fclose(f);
+
+                if (!streq_ptr(state.vc_keymap, new_keymap)) {
+                        free(state.vc_keymap);
+                        state.vc_keymap = new_keymap;
+
+                        free(state.vc_keymap_toggle);
+                        state.vc_keymap_toggle = NULL;
+
+                        modified = true;
+                } else
+                        free(new_keymap);
+        }
+
+        if (modified) {
+                dbus_bool_t b;
+                DBusMessage *changed;
+                int r;
+
+                r = write_data_vconsole();
+                if (r < 0)
+                        log_error("Failed to set virtual console keymap: %s", strerror(-r));
+
+                changed = bus_properties_changed_new(
+                                "/org/freedesktop/locale1",
+                                "org.freedesktop.locale1",
+                                "VConsoleKeymap\0"
+                                "VConsoleKeymapToggle\0");
+
+                if (!changed)
+                        return -ENOMEM;
+
+                b = dbus_connection_send(connection, changed, NULL);
+                dbus_message_unref(changed);
+
+                if (!b)
+                        return -ENOMEM;
+
+                return load_vconsole_keymap(connection, NULL);
+        }
+
+        return 0;
+}
+
+static int append_locale(DBusMessageIter *i, const char *property, void *userdata) {
+        int r, c = 0, p;
+        char **l;
+
+        l = new0(char*, _PROP_MAX+1);
+        if (!l)
+                return -ENOMEM;
+
+        for (p = 0; p < _PROP_MAX; p++) {
+                char *t;
+
+                if (isempty(data[p]))
+                        continue;
+
+                if (asprintf(&t, "%s=%s", names[p], data[p]) < 0) {
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+
+                l[c++] = t;
+        }
+
+        r = bus_property_append_strv(i, property, (void*) l);
+        strv_free(l);
+
+        return r;
+}
+
+static const BusProperty bus_locale_properties[] = {
+        { "Locale",               append_locale,             "as", 0 },
+        { "X11Layout",            bus_property_append_string, "s", offsetof(State, x11_layout),       true },
+        { "X11Model",             bus_property_append_string, "s", offsetof(State, x11_model),        true },
+        { "X11Variant",           bus_property_append_string, "s", offsetof(State, x11_variant),      true },
+        { "X11Options",           bus_property_append_string, "s", offsetof(State, x11_options),      true },
+        { "VConsoleKeymap",       bus_property_append_string, "s", offsetof(State, vc_keymap),        true },
+        { "VConsoleKeymapToggle", bus_property_append_string, "s", offsetof(State, vc_keymap_toggle), true },
+        { NULL, }
+};
+
+static const BusBoundProperties bps[] = {
+        { "org.freedesktop.locale1", bus_locale_properties, &state },
+        { NULL, }
+};
+
+static DBusHandlerResult locale_message_handler(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+        DBusMessage *reply = NULL, *changed = NULL;
+        DBusError error;
+        int r;
+
+        assert(connection);
+        assert(message);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetLocale")) {
+                char **l = NULL, **i;
+                dbus_bool_t interactive;
+                DBusMessageIter iter;
+                bool modified = false;
+                bool passed[_PROP_MAX];
+                int p;
+
+                if (!dbus_message_iter_init(message, &iter))
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                r = bus_parse_strv_iter(&iter, &l);
+                if (r < 0) {
+                        if (r == -ENOMEM)
+                                goto oom;
+
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                if (!dbus_message_iter_next(&iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)  {
+                        strv_free(l);
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+                }
+
+                dbus_message_iter_get_basic(&iter, &interactive);
+
+                zero(passed);
+
+                /* Check whether a variable changed and if so valid */
+                STRV_FOREACH(i, l) {
+                        bool valid = false;
+
+                        for (p = 0; p < _PROP_MAX; p++) {
+                                size_t k;
+
+                                k = strlen(names[p]);
+                                if (startswith(*i, names[p]) &&
+                                    (*i)[k] == '=' &&
+                                    string_is_safe((*i) + k + 1)) {
+                                        valid = true;
+                                        passed[p] = true;
+
+                                        if (!streq_ptr(*i + k + 1, data[p]))
+                                                modified = true;
+
+                                        break;
+                                }
+                        }
+
+                        if (!valid) {
+                                strv_free(l);
+                                return bus_send_error_reply(connection, message, NULL, -EINVAL);
+                        }
+                }
+
+                /* Check whether a variable is unset */
+                if (!modified)  {
+                        for (p = 0; p < _PROP_MAX; p++)
+                                if (!isempty(data[p]) && !passed[p]) {
+                                        modified = true;
+                                        break;
+                                }
+                }
+
+                if (modified) {
+
+                        r = verify_polkit(connection, message, "org.freedesktop.locale1.set-locale", interactive, NULL, &error);
+                        if (r < 0) {
+                                strv_free(l);
+                                return bus_send_error_reply(connection, message, &error, r);
+                        }
+
+                        STRV_FOREACH(i, l) {
+                                for (p = 0; p < _PROP_MAX; p++) {
+                                        size_t k;
+
+                                        k = strlen(names[p]);
+                                        if (startswith(*i, names[p]) && (*i)[k] == '=') {
+                                                char *t;
+
+                                                t = strdup(*i + k + 1);
+                                                if (!t) {
+                                                        strv_free(l);
+                                                        goto oom;
+                                                }
+
+                                                free(data[p]);
+                                                data[p] = t;
+
+                                                break;
+                                        }
+                                }
+                        }
+
+                        strv_free(l);
+
+                        for (p = 0; p < _PROP_MAX; p++) {
+                                if (passed[p])
+                                        continue;
+
+                                free(data[p]);
+                                data[p] = NULL;
+                        }
+
+                        simplify();
+
+                        r = write_data_locale();
+                        if (r < 0) {
+                                log_error("Failed to set locale: %s", strerror(-r));
+                                return bus_send_error_reply(connection, message, NULL, r);
+                        }
+
+                        push_data(connection);
+
+                        log_info("Changed locale information.");
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/locale1",
+                                        "org.freedesktop.locale1",
+                                        "Locale\0");
+                        if (!changed)
+                                goto oom;
+                } else
+                        strv_free(l);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetVConsoleKeyboard")) {
+
+                const char *keymap, *keymap_toggle;
+                dbus_bool_t convert, interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &keymap,
+                                    DBUS_TYPE_STRING, &keymap_toggle,
+                                    DBUS_TYPE_BOOLEAN, &convert,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(keymap))
+                        keymap = NULL;
+
+                if (isempty(keymap_toggle))
+                        keymap_toggle = NULL;
+
+                if (!streq_ptr(keymap, state.vc_keymap) ||
+                    !streq_ptr(keymap_toggle, state.vc_keymap_toggle)) {
+
+                        if ((keymap && (!filename_is_safe(keymap) || !string_is_safe(keymap))) ||
+                            (keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle))))
+                                return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                        r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        if (free_and_set(&state.vc_keymap, keymap) < 0 ||
+                            free_and_set(&state.vc_keymap_toggle, keymap_toggle) < 0)
+                                goto oom;
+
+                        r = write_data_vconsole();
+                        if (r < 0) {
+                                log_error("Failed to set virtual console keymap: %s", strerror(-r));
+                                return bus_send_error_reply(connection, message, NULL, r);
+                        }
+
+                        log_info("Changed virtual console keymap to '%s'", strempty(state.vc_keymap));
+
+                        r = load_vconsole_keymap(connection, NULL);
+                        if (r < 0)
+                                log_error("Failed to request keymap reload: %s", strerror(-r));
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/locale1",
+                                        "org.freedesktop.locale1",
+                                        "VConsoleKeymap\0"
+                                        "VConsoleKeymapToggle\0");
+                        if (!changed)
+                                goto oom;
+
+                        if (convert) {
+                                r = convert_vconsole_to_x11(connection);
+
+                                if (r < 0)
+                                        log_error("Failed to convert keymap data: %s", strerror(-r));
+                        }
+                }
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetX11Keyboard")) {
+
+                const char *layout, *model, *variant, *options;
+                dbus_bool_t convert, interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &layout,
+                                    DBUS_TYPE_STRING, &model,
+                                    DBUS_TYPE_STRING, &variant,
+                                    DBUS_TYPE_STRING, &options,
+                                    DBUS_TYPE_BOOLEAN, &convert,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(layout))
+                        layout = NULL;
+
+                if (isempty(model))
+                        model = NULL;
+
+                if (isempty(variant))
+                        variant = NULL;
+
+                if (isempty(options))
+                        options = NULL;
+
+                if (!streq_ptr(layout, state.x11_layout) ||
+                    !streq_ptr(model, state.x11_model) ||
+                    !streq_ptr(variant, state.x11_variant) ||
+                    !streq_ptr(options, state.x11_options)) {
+
+                        if ((layout && !string_is_safe(layout)) ||
+                            (model && !string_is_safe(model)) ||
+                            (variant && !string_is_safe(variant)) ||
+                            (options && !string_is_safe(options)))
+                                return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                        r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        if (free_and_set(&state.x11_layout, layout) < 0 ||
+                            free_and_set(&state.x11_model, model) < 0 ||
+                            free_and_set(&state.x11_variant, variant) < 0 ||
+                            free_and_set(&state.x11_options, options) < 0)
+                                goto oom;
+
+                        r = write_data_x11();
+                        if (r < 0) {
+                                log_error("Failed to set X11 keyboard layout: %s", strerror(-r));
+                                return bus_send_error_reply(connection, message, NULL, r);
+                        }
+
+                        log_info("Changed X11 keyboard layout to '%s'", strempty(state.x11_layout));
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/locale1",
+                                        "org.freedesktop.locale1",
+                                        "X11Layout\0"
+                                        "X11Model\0"
+                                        "X11Variant\0"
+                                        "X11Options\0");
+                        if (!changed)
+                                goto oom;
+
+                        if (convert) {
+                                r = convert_x11_to_vconsole(connection);
+
+                                if (r < 0)
+                                        log_error("Failed to convert keymap data: %s", strerror(-r));
+                        }
+                }
+        } else
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+
+        if (!(reply = dbus_message_new_method_return(message)))
+                goto oom;
+
+        if (!dbus_connection_send(connection, reply, NULL))
+                goto oom;
+
+        dbus_message_unref(reply);
+        reply = NULL;
+
+        if (changed) {
+
+                if (!dbus_connection_send(connection, changed, NULL))
+                        goto oom;
+
+                dbus_message_unref(changed);
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        if (changed)
+                dbus_message_unref(changed);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static int connect_bus(DBusConnection **_bus) {
+        static const DBusObjectPathVTable locale_vtable = {
+                .message_function = locale_message_handler
+        };
+        DBusError error;
+        DBusConnection *bus = NULL;
+        int r;
+
+        assert(_bus);
+
+        dbus_error_init(&error);
+
+        bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        if (!bus) {
+                log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
+                r = -ECONNREFUSED;
+                goto fail;
+        }
+
+        dbus_connection_set_exit_on_disconnect(bus, FALSE);
+
+        if (!dbus_connection_register_object_path(bus, "/org/freedesktop/locale1", &locale_vtable, NULL) ||
+            !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) {
+                r = log_oom();
+                goto fail;
+        }
+
+        r = dbus_bus_request_name(bus, "org.freedesktop.locale1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to register name on bus: %s", bus_error_message(&error));
+                r = -EEXIST;
+                goto fail;
+        }
+
+        if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+                log_error("Failed to acquire name.");
+                r = -EEXIST;
+                goto fail;
+        }
+
+        if (_bus)
+                *_bus = bus;
+
+        return 0;
+
+fail:
+        dbus_connection_close(bus);
+        dbus_connection_unref(bus);
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+        DBusConnection *bus = NULL;
+        bool exiting = false;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argc == 2 && streq(argv[1], "--introspect")) {
+                fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+                      "<node>\n", stdout);
+                fputs(locale_interface, stdout);
+                fputs("</node>\n", stdout);
+                return 0;
+        }
+
+        if (argc != 1) {
+                log_error("This program takes no arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        r = read_data();
+        if (r < 0) {
+                log_error("Failed to read locale data: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = connect_bus(&bus);
+        if (r < 0)
+                goto finish;
+
+        remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
+        for (;;) {
+
+                if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
+                        break;
+
+                if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
+                        exiting = true;
+                        bus_async_unregister_and_exit(bus, "org.freedesktop.locale1");
+                }
+        }
+
+        r = 0;
+
+finish:
+        free_data();
+
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/locale/org.freedesktop.locale1.conf b/src/locale/org.freedesktop.locale1.conf
new file mode 100644 (file)
index 0000000..79d0ecd
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0"?> <!--*-nxml-*-->
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<busconfig>
+
+        <policy user="root">
+                <allow own="org.freedesktop.locale1"/>
+                <allow send_destination="org.freedesktop.locale1"/>
+                <allow receive_sender="org.freedesktop.locale1"/>
+        </policy>
+
+        <policy context="default">
+                <allow send_destination="org.freedesktop.locale1"/>
+                <allow receive_sender="org.freedesktop.locale1"/>
+        </policy>
+
+</busconfig>
diff --git a/src/locale/org.freedesktop.locale1.policy.in b/src/locale/org.freedesktop.locale1.policy.in
new file mode 100644 (file)
index 0000000..df63845
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<policyconfig>
+
+        <vendor>The systemd Project</vendor>
+        <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
+
+        <action id="org.freedesktop.locale1.set-locale">
+                <_description>Set system locale</_description>
+                <_message>Authentication is required to set the system locale.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.locale1.set-keyboard</annotate>
+        </action>
+
+        <action id="org.freedesktop.locale1.set-keyboard">
+                <_description>Set system keyboard settings</_description>
+                <_message>Authentication is required to set the system keyboard settings.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+</policyconfig>
diff --git a/src/locale/org.freedesktop.locale1.service b/src/locale/org.freedesktop.locale1.service
new file mode 100644 (file)
index 0000000..025f9a0
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[D-BUS Service]
+Name=org.freedesktop.locale1
+Exec=/bin/false
+User=root
+SystemdService=dbus-org.freedesktop.locale1.service
diff --git a/src/login/.gitignore b/src/login/.gitignore
new file mode 100644 (file)
index 0000000..d3840c7
--- /dev/null
@@ -0,0 +1,5 @@
+/libsystemd-login.pc
+/logind-gperf.c
+/org.freedesktop.login1.policy
+/71-seat.rules
+/73-seat-late.rules
diff --git a/src/login/70-power-switch.rules b/src/login/70-power-switch.rules
new file mode 100644 (file)
index 0000000..36fb827
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+ACTION=="remove", GOTO="power_switch_end"
+
+SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="acpi", TAG+="power-switch"
+SUBSYSTEM=="input", KERNEL=="event*", KERNELS=="thinkpad_acpi", TAG+="power-switch"
+
+LABEL="power_switch_end"
diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules
new file mode 100644 (file)
index 0000000..d1275f2
--- /dev/null
@@ -0,0 +1,75 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+ACTION=="remove", GOTO="uaccess_end"
+ENV{MAJOR}=="", GOTO="uaccess_end"
+
+# PTP/MTP protocol devices, cameras, portable media players
+SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id"
+SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="uaccess"
+
+# Digicams with proprietary protocol
+ENV{ID_GPHOTO2}=="*?", TAG+="uaccess"
+
+# SCSI and USB scanners
+ENV{libsane_matched}=="yes", TAG+="uaccess"
+
+# HPLIP devices (necessary for ink level check and HP tool maintenance)
+ENV{ID_HPLIP}=="1", TAG+="uaccess"
+
+# optical drives
+SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="uaccess"
+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="uaccess"
+
+# Sound devices
+SUBSYSTEM=="sound", TAG+="uaccess"
+
+# ffado is an userspace driver for firewire sound cards
+SUBSYSTEM=="firewire", ENV{ID_FFADO}=="1", TAG+="uaccess"
+
+# Webcams, frame grabber, TV cards
+SUBSYSTEM=="video4linux", TAG+="uaccess"
+SUBSYSTEM=="dvb", TAG+="uaccess"
+
+# IIDC devices: industrial cameras and some webcams
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*",  TAG+="uaccess"
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*",  TAG+="uaccess"
+# AV/C devices: camcorders, set-top boxes, TV sets, audio devices, and more
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", TAG+="uaccess"
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", TAG+="uaccess"
+
+# DRI video devices
+SUBSYSTEM=="drm", KERNEL=="card*", TAG+="uaccess"
+
+# KVM
+SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess"
+
+# smart-card readers
+ENV{ID_SMARTCARD_READER}=="*?", TAG+="uaccess"
+
+# (USB) authentication devices
+ENV{ID_SECURITY_TOKEN}=="*?", TAG+="uaccess"
+
+# PDA devices
+ENV{ID_PDA}=="*?", TAG+="uaccess"
+
+# Programmable remote control
+ENV{ID_REMOTE_CONTROL}=="1", TAG+="uaccess"
+
+# joysticks
+SUBSYSTEM=="input", ENV{ID_INPUT_JOYSTICK}=="?*", TAG+="uaccess"
+
+# color measurement devices
+ENV{COLOR_MEASUREMENT_DEVICE}=="*?", TAG+="uaccess"
+
+# DDC/CI device, usually high-end monitors such as the DreamColor
+ENV{DDC_DEVICE}=="*?", TAG+="uaccess"
+
+# media player raw devices (for user-mode drivers, Android SDK, etc.)
+SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess"
+
+LABEL="uaccess_end"
diff --git a/src/login/71-seat.rules.in b/src/login/71-seat.rules.in
new file mode 100644 (file)
index 0000000..f554d7f
--- /dev/null
@@ -0,0 +1,48 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+ACTION=="remove", GOTO="seat_end"
+
+TAG=="uaccess", SUBSYSTEM!="sound", TAG+="seat"
+SUBSYSTEM=="sound", KERNEL=="card*", TAG+="seat"
+SUBSYSTEM=="input", KERNEL=="input*", TAG+="seat"
+SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat"
+SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat"
+
+# 'Plugable' USB hub, sound, network, graphics adapter
+SUBSYSTEM=="usb", ATTR{idVendor}=="2230", ATTR{idProduct}=="000[13]", ENV{ID_AUTOSEAT}="1"
+
+# Mimo 720, with integrated USB hub, displaylink graphics, and e2i
+# touchscreen. This device carries no proper VID/PID in the USB hub,
+# but it does carry good ID data in the graphics component, hence we
+# check it from the parent. There's a bit of a race here however,
+# given that the child devices might not exist yet at the time this
+# rule is executed. To work around this we'll trigger the parent from
+# the child if we notice that the parent wasn't recognized yet.
+
+# Match parent
+SUBSYSTEM=="usb", ATTR{idVendor}=="058f", ATTR{idProduct}=="6254", \
+                  ATTR{%k.2/idVendor}=="17e9", ATTR{%k.2/idProduct}=="401a", ATTR{%k.2/product}=="mimo inc", \
+                  ENV{ID_AUTOSEAT}="1", ENV{ID_AVOID_LOOP}="1"
+
+# Match child, look for parent's ID_AVOID_LOOP
+SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="401a", ATTR{product}=="mimo inc", \
+                  ATTR{../idVendor}=="058f", ATTR{../idProduct}=="6254", \
+                  IMPORT{parent}="ID_AVOID_LOOP"
+
+# Match child, retrigger parent
+SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="401a", ATTR{product}=="mimo inc", \
+                  ATTR{../idVendor}=="058f", ATTR{../idProduct}=="6254", \
+                  ENV{ID_AVOID_LOOP}=="", \
+                  RUN+="@bindir@/udevadm trigger --parent-match=%p/.."
+
+TAG=="seat", ENV{ID_PATH}=="", IMPORT{builtin}="path_id"
+TAG=="seat", ENV{ID_FOR_SEAT}=="", ENV{ID_PATH_TAG}!="", ENV{ID_FOR_SEAT}="$env{SUBSYSTEM}-$env{ID_PATH_TAG}"
+
+SUBSYSTEM=="input", ATTR{name}=="Wiebetech LLC Wiebetech", RUN+="@rootbindir@/loginctl lock-sessions"
+
+LABEL="seat_end"
diff --git a/src/login/73-seat-late.rules.in b/src/login/73-seat-late.rules.in
new file mode 100644 (file)
index 0000000..901df75
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+ACTION=="remove", GOTO="seat_late_end"
+
+ENV{ID_SEAT}=="", ENV{ID_AUTOSEAT}=="1", ENV{ID_FOR_SEAT}!="", ENV{ID_SEAT}="seat-$env{ID_FOR_SEAT}"
+ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT"
+
+ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}"
+
+TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess"
+
+LABEL="seat_late_end"
diff --git a/src/login/Makefile b/src/login/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/login/inhibit.c b/src/login/inhibit.c
new file mode 100644 (file)
index 0000000..9b66133
--- /dev/null
@@ -0,0 +1,331 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <getopt.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <dbus.h>
+#include <unistd.h>
+
+#include "dbus-common.h"
+#include "util.h"
+#include "build.h"
+#include "strv.h"
+
+static const char* arg_what = "idle:sleep:shutdown";
+static const char* arg_who = NULL;
+static const char* arg_why = "Unknown reason";
+static const char* arg_mode = "block";
+
+static enum {
+        ACTION_INHIBIT,
+        ACTION_LIST
+} arg_action = ACTION_INHIBIT;
+
+static int inhibit(DBusConnection *bus, DBusError *error) {
+        DBusMessage *reply = NULL;
+        int r;
+
+        r = bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "Inhibit",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &arg_what,
+                        DBUS_TYPE_STRING, &arg_who,
+                        DBUS_TYPE_STRING, &arg_why,
+                        DBUS_TYPE_STRING, &arg_mode,
+                        DBUS_TYPE_INVALID);
+        if (r < 0)
+                return r;
+
+        if (!dbus_message_get_args(reply, error,
+                                   DBUS_TYPE_UNIX_FD, &r,
+                                   DBUS_TYPE_INVALID))
+                r = -EIO;
+
+        dbus_message_unref(reply);
+
+        return r;
+}
+
+static int print_inhibitors(DBusConnection *bus, DBusError *error) {
+        DBusMessage *reply = NULL;
+        unsigned n = 0;
+        DBusMessageIter iter, sub, sub2;
+        int r;
+
+        r = bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "ListInhibitors",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+        if (r < 0)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter)) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+                r = -EIO;
+                goto finish;
+        }
+
+        printf("%-21s %-20s %-20s %-5s %6s %6s\n",
+               "WHAT",
+               "WHO",
+               "WHY",
+               "MODE",
+               "UID",
+               "PID");
+
+        dbus_message_iter_recurse(&iter, &sub);
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *what, *who, *why, *mode;
+                char *ewho, *ewhy;
+                dbus_uint32_t uid, pid;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &what, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &who, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &why, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &mode, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, false) < 0) {
+                        r = -EIO;
+                        goto finish;
+                }
+
+                ewho = ellipsize(who, 20, 66);
+                ewhy = ellipsize(why, 20, 66);
+
+                printf("%-21s %-20s %-20s %-5s %6lu %6lu\n",
+                       what, ewho ? ewho : who, ewhy ? ewhy : why, mode, (unsigned long) uid, (unsigned long) pid);
+
+                free(ewho);
+                free(ewhy);
+
+                dbus_message_iter_next(&sub);
+
+                n++;
+        }
+
+        printf("\n%u inhibitors listed.\n", n);
+        r = 0;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
+               "Execute a process while inhibiting shutdown/sleep/idle.\n\n"
+               "  -h --help               Show this help\n"
+               "     --version            Show package version\n"
+               "     --what=WHAT          Operations to inhibit, colon separated list of:\n"
+               "                          shutdown, sleep, idle, handle-power-key,\n"
+               "                          handle-suspend-key, handle-hibernate-key,\n"
+               "                          handle-lid-switch\n"
+               "     --who=STRING         A descriptive string who is inhibiting\n"
+               "     --why=STRING         A descriptive string why is being inhibited\n"
+               "     --mode=MODE          One of block or delay\n"
+               "     --list               List active inhibitors\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_WHAT,
+                ARG_WHO,
+                ARG_WHY,
+                ARG_MODE,
+                ARG_LIST,
+        };
+
+        static const struct option options[] = {
+                { "help",         no_argument,       NULL, 'h'              },
+                { "version",      no_argument,       NULL, ARG_VERSION      },
+                { "what",         required_argument, NULL, ARG_WHAT         },
+                { "who",          required_argument, NULL, ARG_WHO          },
+                { "why",          required_argument, NULL, ARG_WHY          },
+                { "mode",         required_argument, NULL, ARG_MODE         },
+                { "list",         no_argument,       NULL, ARG_LIST         },
+                { NULL,           0,                 NULL, 0                }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_WHAT:
+                        arg_what = optarg;
+                        break;
+
+                case ARG_WHO:
+                        arg_who = optarg;
+                        break;
+
+                case ARG_WHY:
+                        arg_why = optarg;
+                        break;
+
+                case ARG_MODE:
+                        arg_mode = optarg;
+                        break;
+
+                case ARG_LIST:
+                        arg_action = ACTION_LIST;
+                        break;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (arg_action == ACTION_INHIBIT && optind >= argc) {
+                log_error("Missing command line to execute.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r, exit_code = 0;
+        DBusConnection *bus = NULL;
+        DBusError error;
+        int fd = -1;
+
+        dbus_error_init(&error);
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        if (!bus) {
+                log_error("Failed to connect to bus: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        if (arg_action == ACTION_LIST) {
+
+                r = print_inhibitors(bus, &error);
+                if (r < 0) {
+                        log_error("Failed to list inhibitors: %s", bus_error_message_or_strerror(&error, -r));
+                        goto finish;
+                }
+
+        } else {
+                char *w = NULL;
+                pid_t pid;
+
+                if (!arg_who)
+                        arg_who = w = strv_join(argv + optind, " ");
+
+                fd = inhibit(bus, &error);
+                free(w);
+
+                if (fd < 0) {
+                        log_error("Failed to inhibit: %s", bus_error_message_or_strerror(&error, -r));
+                        r = fd;
+                        goto finish;
+                }
+
+                pid = fork();
+                if (pid < 0) {
+                        log_error("Failed to fork: %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (pid == 0) {
+                        /* Child */
+
+                        close_nointr_nofail(fd);
+                        close_all_fds(NULL, 0);
+
+                        execvp(argv[optind], argv + optind);
+                        log_error("Failed to execute %s: %m", argv[optind]);
+                        _exit(EXIT_FAILURE);
+                }
+
+                r = wait_for_terminate_and_warn(argv[optind], pid);
+                if (r >= 0)
+                        exit_code = r;
+        }
+
+finish:
+        if (bus) {
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        dbus_error_free(&error);
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r < 0 ? EXIT_FAILURE : exit_code;
+}
diff --git a/src/login/libsystemd-login.pc.in b/src/login/libsystemd-login.pc.in
new file mode 100644 (file)
index 0000000..7b2a724
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: systemd
+Description: systemd Login Utility Library
+URL: @PACKAGE_URL@
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lsystemd-login
+Cflags: -I${includedir}
diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym
new file mode 100644 (file)
index 0000000..ff51be7
--- /dev/null
@@ -0,0 +1,55 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+/* Original symbols from systemd v31 */
+
+LIBSYSTEMD_LOGIN_31 {
+global:
+        sd_get_seats;
+        sd_get_sessions;
+        sd_get_uids;
+        sd_login_monitor_flush;
+        sd_login_monitor_get_fd;
+        sd_login_monitor_new;
+        sd_login_monitor_unref;
+        sd_pid_get_owner_uid;
+        sd_pid_get_session;
+        sd_seat_can_multi_session;
+        sd_seat_get_active;
+        sd_seat_get_sessions;
+        sd_session_get_seat;
+        sd_session_get_uid;
+        sd_session_is_active;
+        sd_uid_get_seats;
+        sd_uid_get_sessions;
+        sd_uid_get_state;
+        sd_uid_is_on_seat;
+local:
+        *;
+};
+
+LIBSYSTEMD_LOGIN_38 {
+global:
+        sd_pid_get_unit;
+        sd_session_get_service;
+} LIBSYSTEMD_LOGIN_31;
+
+LIBSYSTEMD_LOGIN_43 {
+global:
+        sd_session_get_type;
+        sd_session_get_class;
+        sd_session_get_display;
+} LIBSYSTEMD_LOGIN_38;
+
+LIBSYSTEMD_LOGIN_186 {
+global:
+        sd_session_get_state;
+        sd_seat_can_tty;
+        sd_seat_can_graphical;
+} LIBSYSTEMD_LOGIN_43;
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
new file mode 100644 (file)
index 0000000..e2b33a6
--- /dev/null
@@ -0,0 +1,1610 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+#include <pwd.h>
+#include <locale.h>
+
+#include "log.h"
+#include "util.h"
+#include "macro.h"
+#include "pager.h"
+#include "dbus-common.h"
+#include "build.h"
+#include "strv.h"
+#include "cgroup-show.h"
+#include "sysfs-show.h"
+#include "spawn-polkit-agent.h"
+
+static char **arg_property = NULL;
+static bool arg_all = false;
+static bool arg_no_pager = false;
+static const char *arg_kill_who = NULL;
+static int arg_signal = SIGTERM;
+static enum transport {
+        TRANSPORT_NORMAL,
+        TRANSPORT_SSH,
+        TRANSPORT_POLKIT
+} arg_transport = TRANSPORT_NORMAL;
+static bool arg_ask_password = true;
+static const char *arg_host = NULL;
+
+static void pager_open_if_enabled(void) {
+
+        /* Cache result before we open the pager */
+        if (arg_no_pager)
+                return;
+
+        pager_open();
+}
+
+static void polkit_agent_open_if_enabled(void) {
+
+        /* Open the polkit agent as a child process if necessary */
+
+        if (!arg_ask_password)
+                return;
+
+        polkit_agent_open();
+}
+
+static int list_sessions(DBusConnection *bus, char **args, unsigned n) {
+        DBusMessage *reply = NULL;
+        int r;
+        DBusMessageIter iter, sub, sub2;
+        unsigned k = 0;
+
+        pager_open_if_enabled();
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "ListSessions",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (on_tty())
+                printf("%10s %10s %-16s %-16s\n", "SESSION", "UID", "USER", "SEAT");
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *id, *user, *seat, *object;
+                uint32_t uid;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &user, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &seat, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                printf("%10s %10u %-16s %-16s\n", id, (unsigned) uid, user, seat);
+
+                k++;
+
+                dbus_message_iter_next(&sub);
+        }
+
+        if (on_tty())
+                printf("\n%u sessions listed.\n", k);
+
+        r = 0;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int list_users(DBusConnection *bus, char **args, unsigned n) {
+        DBusMessage *reply = NULL;
+        int r;
+        DBusMessageIter iter, sub, sub2;
+        unsigned k = 0;
+
+        pager_open_if_enabled();
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "ListUsers",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+        if (r)
+              goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (on_tty())
+                printf("%10s %-16s\n", "UID", "USER");
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *user, *object;
+                uint32_t uid;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &user, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                printf("%10u %-16s\n", (unsigned) uid, user);
+
+                k++;
+
+                dbus_message_iter_next(&sub);
+        }
+
+        if (on_tty())
+                printf("\n%u users listed.\n", k);
+
+        r = 0;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int list_seats(DBusConnection *bus, char **args, unsigned n) {
+        DBusMessage *reply = NULL;
+        int r;
+        DBusMessageIter iter, sub, sub2;
+        unsigned k = 0;
+
+        pager_open_if_enabled();
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "ListSeats",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (on_tty())
+                printf("%-16s\n", "SEAT");
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *seat, *object;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &seat, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                printf("%-16s\n", seat);
+
+                k++;
+
+                dbus_message_iter_next(&sub);
+        }
+
+        if (on_tty())
+                printf("\n%u seats listed.\n", k);
+
+        r = 0;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+typedef struct SessionStatusInfo {
+        const char *id;
+        uid_t uid;
+        const char *name;
+        usec_t timestamp;
+        const char *default_control_group;
+        int vtnr;
+        const char *seat;
+        const char *tty;
+        const char *display;
+        bool remote;
+        const char *remote_host;
+        const char *remote_user;
+        const char *service;
+        pid_t leader;
+        const char *type;
+        const char *class;
+        const char *state;
+} SessionStatusInfo;
+
+typedef struct UserStatusInfo {
+        uid_t uid;
+        const char *name;
+        usec_t timestamp;
+        const char *default_control_group;
+        const char *state;
+        char **sessions;
+        const char *display;
+} UserStatusInfo;
+
+typedef struct SeatStatusInfo {
+        const char *id;
+        const char *active_session;
+        char **sessions;
+} SeatStatusInfo;
+
+static void print_session_status_info(SessionStatusInfo *i) {
+        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
+        char since2[FORMAT_TIMESTAMP_MAX], *s2;
+        assert(i);
+
+        printf("%s - ", strna(i->id));
+
+        if (i->name)
+                printf("%s (%u)\n", i->name, (unsigned) i->uid);
+        else
+                printf("%u\n", (unsigned) i->uid);
+
+        s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
+        s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
+
+        if (s1)
+                printf("\t   Since: %s; %s\n", s2, s1);
+        else if (s2)
+                printf("\t   Since: %s\n", s2);
+
+        if (i->leader > 0) {
+                char *t = NULL;
+
+                printf("\t  Leader: %u", (unsigned) i->leader);
+
+                get_process_comm(i->leader, &t);
+                if (t) {
+                        printf(" (%s)", t);
+                        free(t);
+                }
+
+                printf("\n");
+        }
+
+        if (i->seat) {
+                printf("\t    Seat: %s", i->seat);
+
+                if (i->vtnr > 0)
+                        printf("; vc%i", i->vtnr);
+
+                printf("\n");
+        }
+
+        if (i->tty)
+                printf("\t     TTY: %s\n", i->tty);
+        else if (i->display)
+                printf("\t Display: %s\n", i->display);
+
+        if (i->remote_host && i->remote_user)
+                printf("\t  Remote: %s@%s\n", i->remote_user, i->remote_host);
+        else if (i->remote_host)
+                printf("\t  Remote: %s\n", i->remote_host);
+        else if (i->remote_user)
+                printf("\t  Remote: user %s\n", i->remote_user);
+        else if (i->remote)
+                printf("\t  Remote: Yes\n");
+
+        if (i->service) {
+                printf("\t Service: %s", i->service);
+
+                if (i->type)
+                        printf("; type %s", i->type);
+
+                if (i->class)
+                        printf("; class %s", i->class);
+
+                printf("\n");
+        } else if (i->type) {
+                printf("\t    Type: %s\n", i->type);
+
+                if (i->class)
+                        printf("; class %s", i->class);
+        } else if (i->class)
+                printf("\t   Class: %s\n", i->class);
+
+        if (i->state)
+                printf("\t   State: %s\n", i->state);
+
+        if (i->default_control_group) {
+                unsigned c;
+
+                printf("\t  CGroup: %s\n", i->default_control_group);
+
+                if (arg_transport != TRANSPORT_SSH) {
+                        c = columns();
+                        if (c > 18)
+                                c -= 18;
+                        else
+                                c = 0;
+
+                        show_cgroup_and_extra_by_spec(i->default_control_group, "\t\t  ", c, false, arg_all, &i->leader, i->leader > 0 ? 1 : 0);
+                }
+        }
+}
+
+static void print_user_status_info(UserStatusInfo *i) {
+        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
+        char since2[FORMAT_TIMESTAMP_MAX], *s2;
+        assert(i);
+
+        if (i->name)
+                printf("%s (%u)\n", i->name, (unsigned) i->uid);
+        else
+                printf("%u\n", (unsigned) i->uid);
+
+        s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
+        s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
+
+        if (s1)
+                printf("\t   Since: %s; %s\n", s2, s1);
+        else if (s2)
+                printf("\t   Since: %s\n", s2);
+
+        if (!isempty(i->state))
+                printf("\t   State: %s\n", i->state);
+
+        if (!strv_isempty(i->sessions)) {
+                char **l;
+                printf("\tSessions:");
+
+                STRV_FOREACH(l, i->sessions) {
+                        if (streq_ptr(*l, i->display))
+                                printf(" *%s", *l);
+                        else
+                                printf(" %s", *l);
+                }
+
+                printf("\n");
+        }
+
+        if (i->default_control_group) {
+                unsigned c;
+
+                printf("\t  CGroup: %s\n", i->default_control_group);
+
+                if (arg_transport != TRANSPORT_SSH) {
+                        c = columns();
+                        if (c > 18)
+                                c -= 18;
+                        else
+                                c = 0;
+
+                        show_cgroup_by_path(i->default_control_group, "\t\t  ", c, false, arg_all);
+                }
+        }
+}
+
+static void print_seat_status_info(SeatStatusInfo *i) {
+        assert(i);
+
+        printf("%s\n", strna(i->id));
+
+        if (!strv_isempty(i->sessions)) {
+                char **l;
+                printf("\tSessions:");
+
+                STRV_FOREACH(l, i->sessions) {
+                        if (streq_ptr(*l, i->active_session))
+                                printf(" *%s", *l);
+                        else
+                                printf(" %s", *l);
+                }
+
+                printf("\n");
+        }
+
+        if (arg_transport != TRANSPORT_SSH) {
+                unsigned c;
+
+                c = columns();
+                if (c > 21)
+                        c -= 21;
+                else
+                        c = 0;
+
+                printf("\t Devices:\n");
+
+                show_sysfs(i->id, "\t\t  ", c);
+        }
+}
+
+static int status_property_session(const char *name, DBusMessageIter *iter, SessionStatusInfo *i) {
+        assert(name);
+        assert(iter);
+        assert(i);
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRING: {
+                const char *s;
+
+                dbus_message_iter_get_basic(iter, &s);
+
+                if (!isempty(s)) {
+                        if (streq(name, "Id"))
+                                i->id = s;
+                        else if (streq(name, "Name"))
+                                i->name = s;
+                        else if (streq(name, "DefaultControlGroup"))
+                                i->default_control_group = s;
+                        else if (streq(name, "TTY"))
+                                i->tty = s;
+                        else if (streq(name, "Display"))
+                                i->display = s;
+                        else if (streq(name, "RemoteHost"))
+                                i->remote_host = s;
+                        else if (streq(name, "RemoteUser"))
+                                i->remote_user = s;
+                        else if (streq(name, "Service"))
+                                i->service = s;
+                        else if (streq(name, "Type"))
+                                i->type = s;
+                        else if (streq(name, "Class"))
+                                i->class = s;
+                        else if (streq(name, "State"))
+                                i->state = s;
+                }
+                break;
+        }
+
+        case DBUS_TYPE_UINT32: {
+                uint32_t u;
+
+                dbus_message_iter_get_basic(iter, &u);
+
+                if (streq(name, "VTNr"))
+                        i->vtnr = (int) u;
+                else if (streq(name, "Leader"))
+                        i->leader = (pid_t) u;
+
+                break;
+        }
+
+        case DBUS_TYPE_BOOLEAN: {
+                dbus_bool_t b;
+
+                dbus_message_iter_get_basic(iter, &b);
+
+                if (streq(name, "Remote"))
+                        i->remote = b;
+
+                break;
+        }
+
+        case DBUS_TYPE_UINT64: {
+                uint64_t u;
+
+                dbus_message_iter_get_basic(iter, &u);
+
+                if (streq(name, "Timestamp"))
+                        i->timestamp = (usec_t) u;
+
+                break;
+        }
+
+        case DBUS_TYPE_STRUCT: {
+                DBusMessageIter sub;
+
+                dbus_message_iter_recurse(iter, &sub);
+
+                if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && streq(name, "User")) {
+                        uint32_t u;
+
+                        dbus_message_iter_get_basic(&sub, &u);
+                        i->uid = (uid_t) u;
+
+                } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Seat")) {
+                        const char *s;
+
+                        dbus_message_iter_get_basic(&sub, &s);
+
+                        if (!isempty(s))
+                                i->seat = s;
+                }
+
+                break;
+        }
+        }
+
+        return 0;
+}
+
+static int status_property_user(const char *name, DBusMessageIter *iter, UserStatusInfo *i) {
+        assert(name);
+        assert(iter);
+        assert(i);
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRING: {
+                const char *s;
+
+                dbus_message_iter_get_basic(iter, &s);
+
+                if (!isempty(s)) {
+                        if (streq(name, "Name"))
+                                i->name = s;
+                        else if (streq(name, "DefaultControlGroup"))
+                                i->default_control_group = s;
+                        else if (streq(name, "State"))
+                                i->state = s;
+                }
+                break;
+        }
+
+        case DBUS_TYPE_UINT32: {
+                uint32_t u;
+
+                dbus_message_iter_get_basic(iter, &u);
+
+                if (streq(name, "UID"))
+                        i->uid = (uid_t) u;
+
+                break;
+        }
+
+        case DBUS_TYPE_UINT64: {
+                uint64_t u;
+
+                dbus_message_iter_get_basic(iter, &u);
+
+                if (streq(name, "Timestamp"))
+                        i->timestamp = (usec_t) u;
+
+                break;
+        }
+
+        case DBUS_TYPE_STRUCT: {
+                DBusMessageIter sub;
+
+                dbus_message_iter_recurse(iter, &sub);
+
+                if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Display")) {
+                        const char *s;
+
+                        dbus_message_iter_get_basic(&sub, &s);
+
+                        if (!isempty(s))
+                                i->display = s;
+                }
+
+                break;
+        }
+
+        case DBUS_TYPE_ARRAY: {
+
+                if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *id;
+                                const char *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) {
+                                        char **l;
+
+                                        l = strv_append(i->sessions, id);
+                                        if (!l)
+                                                return -ENOMEM;
+
+                                        strv_free(i->sessions);
+                                        i->sessions = l;
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+                }
+        }
+        }
+
+        return 0;
+}
+
+static int status_property_seat(const char *name, DBusMessageIter *iter, SeatStatusInfo *i) {
+        assert(name);
+        assert(iter);
+        assert(i);
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRING: {
+                const char *s;
+
+                dbus_message_iter_get_basic(iter, &s);
+
+                if (!isempty(s)) {
+                        if (streq(name, "Id"))
+                                i->id = s;
+                }
+                break;
+        }
+
+        case DBUS_TYPE_STRUCT: {
+                DBusMessageIter sub;
+
+                dbus_message_iter_recurse(iter, &sub);
+
+                if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "ActiveSession")) {
+                        const char *s;
+
+                        dbus_message_iter_get_basic(&sub, &s);
+
+                        if (!isempty(s))
+                                i->active_session = s;
+                }
+
+                break;
+        }
+
+        case DBUS_TYPE_ARRAY: {
+
+                if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *id;
+                                const char *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) {
+                                        char **l;
+
+                                        l = strv_append(i->sessions, id);
+                                        if (!l)
+                                                return -ENOMEM;
+
+                                        strv_free(i->sessions);
+                                        i->sessions = l;
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+                }
+        }
+        }
+
+        return 0;
+}
+
+static int print_property(const char *name, DBusMessageIter *iter) {
+        assert(name);
+        assert(iter);
+
+        if (arg_property && !strv_find(arg_property, name))
+                return 0;
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRUCT: {
+                DBusMessageIter sub;
+
+                dbus_message_iter_recurse(iter, &sub);
+
+                if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING &&
+                    (streq(name, "Display") || streq(name, "ActiveSession"))) {
+                        const char *s;
+
+                        dbus_message_iter_get_basic(&sub, &s);
+
+                        if (arg_all || !isempty(s))
+                                printf("%s=%s\n", name, s);
+                        return 0;
+                }
+                break;
+        }
+
+        case DBUS_TYPE_ARRAY:
+
+                if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) {
+                        DBusMessageIter sub, sub2;
+                        bool found = false;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *id;
+                                const char *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) {
+                                        if (found)
+                                                printf(" %s", id);
+                                        else {
+                                                printf("%s=%s", name, id);
+                                                found = true;
+                                        }
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        if (!found && arg_all)
+                                printf("%s=\n", name);
+                        else if (found)
+                                printf("\n");
+
+                        return 0;
+                }
+
+                break;
+        }
+
+        if (generic_print_property(name, iter, arg_all) > 0)
+                return 0;
+
+        if (arg_all)
+                printf("%s=[unprintable]\n", name);
+
+        return 0;
+}
+
+static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        const char *interface = "";
+        int r;
+        DBusMessageIter iter, sub, sub2, sub3;
+        SessionStatusInfo session_info;
+        UserStatusInfo user_info;
+        SeatStatusInfo seat_info;
+
+        assert(path);
+        assert(new_line);
+
+        zero(session_info);
+        zero(user_info);
+        zero(seat_info);
+
+        r = bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.login1",
+                        path,
+                        "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_INVALID);
+        if (r < 0)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (*new_line)
+                printf("\n");
+
+        *new_line = true;
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *name;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)  {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub2, &sub3);
+
+                if (show_properties)
+                        r = print_property(name, &sub3);
+                else if (strstr(verb, "session"))
+                        r = status_property_session(name, &sub3, &session_info);
+                else if (strstr(verb, "user"))
+                        r = status_property_user(name, &sub3, &user_info);
+                else
+                        r = status_property_seat(name, &sub3, &seat_info);
+
+                if (r < 0) {
+                        log_error("Failed to parse reply.");
+                        goto finish;
+                }
+
+                dbus_message_iter_next(&sub);
+        }
+
+        if (!show_properties) {
+                if (strstr(verb, "session"))
+                        print_session_status_info(&session_info);
+                else if (strstr(verb, "user"))
+                        print_user_status_info(&user_info);
+                else
+                        print_seat_status_info(&seat_info);
+        }
+
+        r = 0;
+
+finish:
+        strv_free(seat_info.sessions);
+        strv_free(user_info.sessions);
+
+        return r;
+}
+
+static int show(DBusConnection *bus, char **args, unsigned n) {
+        DBusMessage *reply = NULL;
+        int r, ret = 0;
+        DBusError error;
+        unsigned i;
+        bool show_properties, new_line = false;
+
+        assert(bus);
+        assert(args);
+
+        dbus_error_init(&error);
+
+        show_properties = !strstr(args[0], "status");
+
+        pager_open_if_enabled();
+
+        if (show_properties && n <= 1) {
+                /* If not argument is specified inspect the manager
+                 * itself */
+
+                ret = show_one(args[0], bus, "/org/freedesktop/login1", show_properties, &new_line);
+                goto finish;
+        }
+
+        for (i = 1; i < n; i++) {
+                const char *path = NULL;
+
+                if (strstr(args[0], "session")) {
+
+                        ret = bus_method_call_with_reply (
+                                        bus,
+                                        "org.freedesktop.login1",
+                                        "/org/freedesktop/login1",
+                                        "org.freedesktop.login1.Manager",
+                                        "GetSession",
+                                        &reply,
+                                        NULL,
+                                        DBUS_TYPE_STRING, &args[i],
+                                        DBUS_TYPE_INVALID);
+
+                } else if (strstr(args[0], "user")) {
+                        uid_t uid;
+                        uint32_t u;
+
+                        ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
+                        if (ret < 0) {
+                                log_error("User %s unknown.", args[i]);
+                                goto finish;
+                        }
+
+                        u = (uint32_t) uid;
+                        ret = bus_method_call_with_reply (
+                                        bus,
+                                        "org.freedesktop.login1",
+                                        "/org/freedesktop/login1",
+                                        "org.freedesktop.login1.Manager",
+                                        "GetUser",
+                                        &reply,
+                                        NULL,
+                                        DBUS_TYPE_UINT32, &u,
+                                        DBUS_TYPE_INVALID);
+                } else {
+
+                        ret = bus_method_call_with_reply (
+                                        bus,
+                                        "org.freedesktop.login1",
+                                        "/org/freedesktop/login1",
+                                        "org.freedesktop.login1.Manager",
+                                        "GetSeat",
+                                        &reply,
+                                        NULL,
+                                        DBUS_TYPE_STRING, &args[i],
+                                        DBUS_TYPE_INVALID);
+                }
+                if (ret)
+                        goto finish;
+
+                if (!dbus_message_get_args(reply, &error,
+                                           DBUS_TYPE_OBJECT_PATH, &path,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse reply: %s", bus_error_message(&error));
+                        ret = -EIO;
+                        goto finish;
+                }
+
+                r = show_one(args[0], bus, path, show_properties, &new_line);
+                if (r != 0)
+                        ret = r;
+
+                dbus_message_unref(reply);
+                reply = NULL;
+        }
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return ret;
+}
+
+static int activate(DBusConnection *bus, char **args, unsigned n) {
+        int ret = 0;
+        unsigned i;
+
+        assert(args);
+
+        for (i = 1; i < n; i++) {
+
+                ret = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                streq(args[0], "lock-session")      ? "LockSession" :
+                                streq(args[0], "unlock-session")    ? "UnlockSession" :
+                                streq(args[0], "terminate-session") ? "TerminateSession" :
+                                                                      "ActivateSession",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_STRING, &args[i],
+                                DBUS_TYPE_INVALID);
+                if (ret)
+                        goto finish;
+        }
+
+finish:
+        return ret;
+}
+
+static int kill_session(DBusConnection *bus, char **args, unsigned n) {
+        int ret = 0;
+        unsigned i;
+
+        assert(args);
+
+        if (!arg_kill_who)
+                arg_kill_who = "all";
+
+        for (i = 1; i < n; i++) {
+                ret = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                "KillSession",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_STRING, &args[i],
+                                DBUS_TYPE_STRING, &arg_kill_who,
+                                DBUS_TYPE_INT32, &arg_signal,
+                                DBUS_TYPE_INVALID);
+                if (ret)
+                        goto finish;
+        }
+
+finish:
+        return ret;
+}
+
+static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
+        int ret = 0;
+        unsigned i;
+        dbus_bool_t b, interactive = true;
+
+        assert(args);
+
+        polkit_agent_open_if_enabled();
+
+        b = streq(args[0], "enable-linger");
+
+        for (i = 1; i < n; i++) {
+                uint32_t u;
+                uid_t uid;
+
+                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
+                if (ret < 0) {
+                        log_error("Failed to resolve user %s: %s", args[i], strerror(-ret));
+                        goto finish;
+                }
+
+                u = (uint32_t) uid;
+                ret = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                "SetUserLinger",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_UINT32, &u,
+                                DBUS_TYPE_BOOLEAN, &b,
+                                DBUS_TYPE_BOOLEAN, &interactive,
+                                DBUS_TYPE_INVALID);
+                if (ret)
+                        goto finish;
+        }
+
+finish:
+        return ret;
+}
+
+static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
+        int ret = 0;
+        unsigned i;
+
+        assert(args);
+
+        for (i = 1; i < n; i++) {
+                uint32_t u;
+                uid_t uid;
+
+                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
+                if (ret < 0) {
+                        log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
+                        goto finish;
+                }
+
+                u = (uint32_t) uid;
+                ret = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                "TerminateUser",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_UINT32, &u,
+                                DBUS_TYPE_INVALID);
+                if (ret)
+                        goto finish;
+        }
+
+finish:
+        return ret;
+}
+
+static int kill_user(DBusConnection *bus, char **args, unsigned n) {
+        int ret = 0;
+        unsigned i;
+
+        assert(args);
+
+        if (!arg_kill_who)
+                arg_kill_who = "all";
+
+        for (i = 1; i < n; i++) {
+                uid_t uid;
+                uint32_t u;
+
+                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
+                if (ret < 0) {
+                        log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
+                        goto finish;
+                }
+
+                u = (uint32_t) uid;
+                ret = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                "KillUser",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_UINT32, &u,
+                                DBUS_TYPE_INT32, &arg_signal,
+                                DBUS_TYPE_INVALID);
+                if (ret)
+                        goto finish;
+        }
+
+finish:
+        return ret;
+}
+
+static int attach(DBusConnection *bus, char **args, unsigned n) {
+        int ret = 0;
+        unsigned i;
+        dbus_bool_t interactive = true;
+
+        assert(args);
+
+        polkit_agent_open_if_enabled();
+
+        for (i = 2; i < n; i++) {
+                ret = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                "AttachDevice",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_STRING, &args[1],
+                                DBUS_TYPE_STRING, &args[i],
+                                DBUS_TYPE_BOOLEAN, &interactive,
+                                DBUS_TYPE_INVALID);
+                if (ret)
+                        goto finish;
+        }
+
+finish:
+        return ret;
+}
+
+static int flush_devices(DBusConnection *bus, char **args, unsigned n) {
+        dbus_bool_t interactive = true;
+
+        assert(args);
+
+        polkit_agent_open_if_enabled();
+
+        return bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "FlushDevices",
+                        NULL,
+                        NULL,
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static int lock_sessions(DBusConnection *bus, char **args, unsigned n) {
+        polkit_agent_open_if_enabled();
+
+        return bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "LockSessions",
+                        NULL,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+}
+
+static int terminate_seat(DBusConnection *bus, char **args, unsigned n) {
+        int ret = 0;
+        unsigned i;
+
+        assert(args);
+
+        for (i = 1; i < n; i++) {
+                ret = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                "TerminateSeat",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_STRING, &args[i],
+                                DBUS_TYPE_INVALID);
+                if (ret)
+                        goto finish;
+        }
+
+finish:
+        return ret;
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
+               "Send control commands to or query the login manager.\n\n"
+               "  -h --help              Show this help\n"
+               "     --version           Show package version\n"
+               "  -p --property=NAME     Show only properties by this name\n"
+               "  -a --all               Show all properties, including empty ones\n"
+               "     --kill-who=WHO      Who to send signal to\n"
+               "  -s --signal=SIGNAL     Which signal to send\n"
+               "     --no-ask-password   Don't prompt for password\n"
+               "  -H --host=[USER@]HOST  Show information for remote host\n"
+               "  -P --privileged        Acquire privileges before execution\n"
+               "     --no-pager          Do not pipe output into a pager\n\n"
+               "Commands:\n"
+               "  list-sessions                   List sessions\n"
+               "  session-status [ID...]          Show session status\n"
+               "  show-session [ID...]            Show properties of one or more sessions\n"
+               "  activate [ID]                   Activate a session\n"
+               "  lock-session [ID...]            Screen lock one or more sessions\n"
+               "  unlock-session [ID...]          Screen unlock one or more sessions\n"
+               "  lock-sessions                   Screen lock all current sessions\n"
+               "  terminate-session [ID...]       Terminate one or more sessions\n"
+               "  kill-session [ID...]            Send signal to processes of a session\n"
+               "  list-users                      List users\n"
+               "  user-status [USER...]           Show user status\n"
+               "  show-user [USER...]             Show properties of one or more users\n"
+               "  enable-linger [USER...]         Enable linger state of one or more users\n"
+               "  disable-linger [USER...]        Disable linger state of one or more users\n"
+               "  terminate-user [USER...]        Terminate all sessions of one or more users\n"
+               "  kill-user [USER...]             Send signal to processes of a user\n"
+               "  list-seats                      List seats\n"
+               "  seat-status [NAME...]           Show seat status\n"
+               "  show-seat [NAME...]             Show properties of one or more seats\n"
+               "  attach [NAME] [DEVICE...]       Attach one or more devices to a seat\n"
+               "  flush-devices                   Flush all device associations\n"
+               "  terminate-seat [NAME...]        Terminate all sessions on one or more seats\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_NO_PAGER,
+                ARG_KILL_WHO,
+                ARG_NO_ASK_PASSWORD
+        };
+
+        static const struct option options[] = {
+                { "help",            no_argument,       NULL, 'h'                 },
+                { "version",         no_argument,       NULL, ARG_VERSION         },
+                { "property",        required_argument, NULL, 'p'                 },
+                { "all",             no_argument,       NULL, 'a'                 },
+                { "no-pager",        no_argument,       NULL, ARG_NO_PAGER        },
+                { "kill-who",        required_argument, NULL, ARG_KILL_WHO        },
+                { "signal",          required_argument, NULL, 's'                 },
+                { "host",            required_argument, NULL, 'H'                 },
+                { "privileged",      no_argument,       NULL, 'P'                 },
+                { "no-ask-password", no_argument,       NULL, ARG_NO_ASK_PASSWORD },
+                { NULL,              0,                 NULL, 0                   }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hp:as:H:P", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case 'p': {
+                        char **l;
+
+                        l = strv_append(arg_property, optarg);
+                        if (!l)
+                                return -ENOMEM;
+
+                        strv_free(arg_property);
+                        arg_property = l;
+
+                        /* If the user asked for a particular
+                         * property, show it to him, even if it is
+                         * empty. */
+                        arg_all = true;
+                        break;
+                }
+
+                case 'a':
+                        arg_all = true;
+                        break;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case ARG_NO_ASK_PASSWORD:
+                        arg_ask_password = false;
+                        break;
+
+                case ARG_KILL_WHO:
+                        arg_kill_who = optarg;
+                        break;
+
+                case 's':
+                        arg_signal = signal_from_string_try_harder(optarg);
+                        if (arg_signal < 0) {
+                                log_error("Failed to parse signal string %s.", optarg);
+                                return -EINVAL;
+                        }
+                        break;
+
+                case 'P':
+                        arg_transport = TRANSPORT_POLKIT;
+                        break;
+
+                case 'H':
+                        arg_transport = TRANSPORT_SSH;
+                        arg_host = optarg;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        return 1;
+}
+
+static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) {
+
+        static const struct {
+                const char* verb;
+                const enum {
+                        MORE,
+                        LESS,
+                        EQUAL
+                } argc_cmp;
+                const int argc;
+                int (* const dispatch)(DBusConnection *bus, char **args, unsigned n);
+        } verbs[] = {
+                { "list-sessions",         LESS,   1, list_sessions    },
+                { "session-status",        MORE,   2, show             },
+                { "show-session",          MORE,   1, show             },
+                { "activate",              EQUAL,  2, activate         },
+                { "lock-session",          MORE,   2, activate         },
+                { "unlock-session",        MORE,   2, activate         },
+                { "lock-sessions",         EQUAL,  1, lock_sessions    },
+                { "terminate-session",     MORE,   2, activate         },
+                { "kill-session",          MORE,   2, kill_session     },
+                { "list-users",            EQUAL,  1, list_users       },
+                { "user-status",           MORE,   2, show             },
+                { "show-user",             MORE,   1, show             },
+                { "enable-linger",         MORE,   2, enable_linger    },
+                { "disable-linger",        MORE,   2, enable_linger    },
+                { "terminate-user",        MORE,   2, terminate_user   },
+                { "kill-user",             MORE,   2, kill_user        },
+                { "list-seats",            EQUAL,  1, list_seats       },
+                { "seat-status",           MORE,   2, show             },
+                { "show-seat",             MORE,   1, show             },
+                { "attach",                MORE,   3, attach           },
+                { "flush-devices",         EQUAL,  1, flush_devices    },
+                { "terminate-seat",        MORE,   2, terminate_seat   },
+        };
+
+        int left;
+        unsigned i;
+
+        assert(argc >= 0);
+        assert(argv);
+        assert(error);
+
+        left = argc - optind;
+
+        if (left <= 0)
+                /* Special rule: no arguments means "list-sessions" */
+                i = 0;
+        else {
+                if (streq(argv[optind], "help")) {
+                        help();
+                        return 0;
+                }
+
+                for (i = 0; i < ELEMENTSOF(verbs); i++)
+                        if (streq(argv[optind], verbs[i].verb))
+                                break;
+
+                if (i >= ELEMENTSOF(verbs)) {
+                        log_error("Unknown operation %s", argv[optind]);
+                        return -EINVAL;
+                }
+        }
+
+        switch (verbs[i].argc_cmp) {
+
+        case EQUAL:
+                if (left != verbs[i].argc) {
+                        log_error("Invalid number of arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case MORE:
+                if (left < verbs[i].argc) {
+                        log_error("Too few arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case LESS:
+                if (left > verbs[i].argc) {
+                        log_error("Too many arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("Unknown comparison operator.");
+        }
+
+        if (!bus) {
+                log_error("Failed to get D-Bus connection: %s", error->message);
+                return -EIO;
+        }
+
+        return verbs[i].dispatch(bus, argv + optind, left);
+}
+
+int main(int argc, char*argv[]) {
+        int r, retval = EXIT_FAILURE;
+        DBusConnection *bus = NULL;
+        DBusError error;
+
+        dbus_error_init(&error);
+
+        setlocale(LC_ALL, "");
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                goto finish;
+        else if (r == 0) {
+                retval = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        if (arg_transport == TRANSPORT_NORMAL)
+                bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        else if (arg_transport == TRANSPORT_POLKIT)
+                bus_connect_system_polkit(&bus, &error);
+        else if (arg_transport == TRANSPORT_SSH)
+                bus_connect_system_ssh(NULL, arg_host, &bus, &error);
+        else
+                assert_not_reached("Uh, invalid transport...");
+
+        r = loginctl_main(bus, argc, argv, &error);
+        retval = r < 0 ? EXIT_FAILURE : r;
+
+finish:
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        dbus_error_free(&error);
+        dbus_shutdown();
+
+        strv_free(arg_property);
+
+        pager_close();
+
+        return retval;
+}
diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c
new file mode 100644 (file)
index 0000000..cb045a9
--- /dev/null
@@ -0,0 +1,248 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <sys/acl.h>
+#include <acl/libacl.h>
+#include <errno.h>
+#include <string.h>
+
+#include "logind-acl.h"
+#include "util.h"
+#include "acl-util.h"
+
+static int flush_acl(acl_t acl) {
+        acl_entry_t i;
+        int found;
+        bool changed = false;
+
+        assert(acl);
+
+        for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
+             found > 0;
+             found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
+
+                acl_tag_t tag;
+
+                if (acl_get_tag_type(i, &tag) < 0)
+                        return -errno;
+
+                if (tag != ACL_USER)
+                        continue;
+
+                if (acl_delete_entry(acl, i) < 0)
+                        return -errno;
+
+                changed = true;
+        }
+
+        if (found < 0)
+                return -errno;
+
+        return changed;
+}
+
+int devnode_acl(const char *path,
+                bool flush,
+                bool del, uid_t old_uid,
+                bool add, uid_t new_uid) {
+
+        acl_t acl;
+        int r = 0;
+        bool changed = false;
+
+        assert(path);
+
+        acl = acl_get_file(path, ACL_TYPE_ACCESS);
+        if (!acl)
+                return -errno;
+
+        if (flush) {
+
+                r = flush_acl(acl);
+                if (r < 0)
+                        goto finish;
+                if (r > 0)
+                        changed = true;
+
+        } else if (del && old_uid > 0) {
+                acl_entry_t entry;
+
+                r = acl_find_uid(acl, old_uid, &entry);
+                if (r < 0)
+                        goto finish;
+
+                if (r > 0) {
+                        if (acl_delete_entry(acl, entry) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                        changed = true;
+                }
+        }
+
+        if (add && new_uid > 0) {
+                acl_entry_t entry;
+                acl_permset_t permset;
+                int rd, wt;
+
+                r = acl_find_uid(acl, new_uid, &entry);
+                if (r < 0)
+                        goto finish;
+
+                if (r == 0) {
+                        if (acl_create_entry(&acl, &entry) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                        if (acl_set_tag_type(entry, ACL_USER) < 0 ||
+                            acl_set_qualifier(entry, &new_uid) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+                }
+
+                if (acl_get_permset(entry, &permset) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                rd = acl_get_perm(permset, ACL_READ);
+                if (rd < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                wt = acl_get_perm(permset, ACL_WRITE);
+                if (wt < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (!rd || !wt) {
+
+                        if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                        changed = true;
+                }
+        }
+
+        if (!changed)
+                goto finish;
+
+        if (acl_calc_mask(&acl) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (acl_set_file(path, ACL_TYPE_ACCESS, acl) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        r = 0;
+
+finish:
+        acl_free(acl);
+
+        return r;
+}
+
+int devnode_acl_all(struct udev *udev,
+                    const char *seat,
+                    bool flush,
+                    bool del, uid_t old_uid,
+                    bool add, uid_t new_uid) {
+
+        struct udev_list_entry *item = NULL, *first = NULL;
+        struct udev_enumerate *e;
+        int r;
+
+        assert(udev);
+
+        if (isempty(seat))
+                seat = "seat0";
+
+        e = udev_enumerate_new(udev);
+        if (!e)
+                return -ENOMEM;
+
+        /* We can only match by one tag in libudev. We choose
+         * "uaccess" for that. If we could match for two tags here we
+         * could add the seat name as second match tag, but this would
+         * be hardly optimizable in libudev, and hence checking the
+         * second tag manually in our loop is a good solution. */
+
+        r = udev_enumerate_add_match_tag(e, "uaccess");
+        if (r < 0)
+                goto finish;
+
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                goto finish;
+
+        first = udev_enumerate_get_list_entry(e);
+        udev_list_entry_foreach(item, first) {
+                struct udev_device *d;
+                const char *node, *sn;
+
+                d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
+                if (!d) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                sn = udev_device_get_property_value(d, "ID_SEAT");
+                if (isempty(sn))
+                        sn = "seat0";
+
+                if (!streq(seat, sn)) {
+                        udev_device_unref(d);
+                        continue;
+                }
+
+                node = udev_device_get_devnode(d);
+                if (!node) {
+                        /* In case people mistag devices with nodes, we need to ignore this */
+                        udev_device_unref(d);
+                        continue;
+                }
+
+                log_debug("Fixing up %s for seat %s...", node, sn);
+
+                r = devnode_acl(node, flush, del, old_uid, add, new_uid);
+                udev_device_unref(d);
+
+                if (r < 0)
+                        goto finish;
+        }
+
+finish:
+        if (e)
+                udev_enumerate_unref(e);
+
+        return r;
+}
diff --git a/src/login/logind-acl.h b/src/login/logind-acl.h
new file mode 100644 (file)
index 0000000..ec09843
--- /dev/null
@@ -0,0 +1,57 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <libudev.h>
+
+#ifdef HAVE_ACL
+
+int devnode_acl(const char *path,
+                bool flush,
+                bool del, uid_t old_uid,
+                bool add, uid_t new_uid);
+
+int devnode_acl_all(struct udev *udev,
+                    const char *seat,
+                    bool flush,
+                    bool del, uid_t old_uid,
+                    bool add, uid_t new_uid);
+#else
+
+static inline int devnode_acl(const char *path,
+                bool flush,
+                bool del, uid_t old_uid,
+                bool add, uid_t new_uid) {
+        return 0;
+}
+
+static inline int devnode_acl_all(struct udev *udev,
+                                  const char *seat,
+                                  bool flush,
+                                  bool del, uid_t old_uid,
+                                  bool add, uid_t new_uid) {
+        return 0;
+}
+
+#endif
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
new file mode 100644 (file)
index 0000000..e1517d6
--- /dev/null
@@ -0,0 +1,141 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+
+#include "conf-parser.h"
+#include "special.h"
+#include "dbus-common.h"
+#include "logind-action.h"
+
+int manager_handle_action(
+                Manager *m,
+                InhibitWhat inhibit_key,
+                HandleAction handle,
+                bool ignore_inhibited,
+                bool is_edge) {
+
+        static const char * const message_table[_HANDLE_ACTION_MAX] = {
+                [HANDLE_POWEROFF] = "Powering Off...",
+                [HANDLE_REBOOT] = "Rebooting...",
+                [HANDLE_HALT] = "Halting...",
+                [HANDLE_KEXEC] = "Rebooting via kexec...",
+                [HANDLE_SUSPEND] = "Suspending...",
+                [HANDLE_HIBERNATE] = "Hibernating...",
+                [HANDLE_HYBRID_SLEEP] = "Hibernating and suspending..."
+        };
+
+        static const char * const target_table[_HANDLE_ACTION_MAX] = {
+                [HANDLE_POWEROFF] = SPECIAL_POWEROFF_TARGET,
+                [HANDLE_REBOOT] = SPECIAL_REBOOT_TARGET,
+                [HANDLE_HALT] = SPECIAL_HALT_TARGET,
+                [HANDLE_KEXEC] = SPECIAL_KEXEC_TARGET,
+                [HANDLE_SUSPEND] = SPECIAL_SUSPEND_TARGET,
+                [HANDLE_HIBERNATE] = SPECIAL_HIBERNATE_TARGET,
+                [HANDLE_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET
+        };
+
+        DBusError error;
+        int r;
+        InhibitWhat inhibit_operation;
+        bool supported = true;
+
+        assert(m);
+
+        /* If the key handling is turned off, don't do anything */
+        if (handle == HANDLE_IGNORE) {
+                log_debug("Refusing operation, as it is turned off.");
+                return 0;
+        }
+
+        if (handle == HANDLE_SUSPEND)
+                supported = can_sleep("mem") > 0;
+        else if (handle == HANDLE_HIBERNATE)
+                supported = can_sleep("disk") > 0;
+        else if (handle == HANDLE_HYBRID_SLEEP)
+                supported = can_sleep("disk") > 0 && can_sleep_disk("suspend") > 0;
+        else if (handle == HANDLE_KEXEC)
+                supported = access("/sbin/kexec", X_OK) >= 0;
+
+        if (!supported) {
+                log_warning("Requested operation not supported, ignoring.");
+                return -ENOTSUP;
+        }
+
+        /* If the key handling is inhibited, don't do anything */
+        if (inhibit_key > 0) {
+                if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0)) {
+                        log_debug("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_key));
+                        return 0;
+                }
+        }
+
+        /* Locking is handled differently from the rest. */
+        if (handle == HANDLE_LOCK) {
+                log_info("Locking sessions...");
+                session_send_lock_all(m, true);
+                return 1;
+        }
+
+        inhibit_operation = handle == HANDLE_SUSPEND || handle == HANDLE_HIBERNATE || handle == HANDLE_HYBRID_SLEEP ? INHIBIT_SLEEP : INHIBIT_SHUTDOWN;
+
+        /* If the actual operation is inhibited, warn and fail */
+        if (!ignore_inhibited &&
+            manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0)) {
+
+                /* If this is just a recheck of the lid switch then don't warn about anything */
+                if (!is_edge) {
+                        log_debug("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation));
+                        return 0;
+                }
+
+                log_error("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation));
+                warn_melody();
+                return -EPERM;
+        }
+
+        log_info("%s", message_table[handle]);
+
+        dbus_error_init(&error);
+        r = bus_manager_shutdown_or_sleep_now_or_later(m, target_table[handle], inhibit_operation, &error);
+        if (r < 0) {
+                log_error("Failed to execute operation: %s", bus_error_message(&error));
+                dbus_error_free(&error);
+                return r;
+        }
+
+        return 1;
+}
+
+static const char* const handle_action_table[_HANDLE_ACTION_MAX] = {
+        [HANDLE_IGNORE] = "ignore",
+        [HANDLE_POWEROFF] = "poweroff",
+        [HANDLE_REBOOT] = "reboot",
+        [HANDLE_HALT] = "halt",
+        [HANDLE_KEXEC] = "kexec",
+        [HANDLE_SUSPEND] = "suspend",
+        [HANDLE_HIBERNATE] = "hibernate",
+        [HANDLE_HYBRID_SLEEP] = "hybrid-sleep",
+        [HANDLE_LOCK] = "lock"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(handle_action, HandleAction);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_handle_action, handle_action, HandleAction, "Failed to parse handle action setting");
diff --git a/src/login/logind-action.h b/src/login/logind-action.h
new file mode 100644 (file)
index 0000000..7ab4464
--- /dev/null
@@ -0,0 +1,54 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foologindactionhfoo
+#define foologindactionhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef enum HandleAction {
+        HANDLE_IGNORE,
+        HANDLE_POWEROFF,
+        HANDLE_REBOOT,
+        HANDLE_HALT,
+        HANDLE_KEXEC,
+        HANDLE_SUSPEND,
+        HANDLE_HIBERNATE,
+        HANDLE_HYBRID_SLEEP,
+        HANDLE_LOCK,
+        _HANDLE_ACTION_MAX,
+        _HANDLE_ACTION_INVALID = -1
+} HandleAction;
+
+#include "logind.h"
+#include "logind-inhibit.h"
+
+int manager_handle_action(
+                Manager *m,
+                InhibitWhat inhibit_key,
+                HandleAction handle,
+                bool ignore_inhibited,
+                bool is_edge);
+
+const char* handle_action_to_string(HandleAction h);
+HandleAction handle_action_from_string(const char *s);
+
+int config_parse_handle_action(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+#endif
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
new file mode 100644 (file)
index 0000000..dbf3d3c
--- /dev/null
@@ -0,0 +1,241 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <sys/epoll.h>
+
+#include "conf-parser.h"
+#include "util.h"
+#include "logind-button.h"
+#include "special.h"
+#include "dbus-common.h"
+
+Button* button_new(Manager *m, const char *name) {
+        Button *b;
+
+        assert(m);
+        assert(name);
+
+        b = new0(Button, 1);
+        if (!b)
+                return NULL;
+
+        b->name = strdup(name);
+        if (!b->name) {
+                free(b);
+                return NULL;
+        }
+
+        if (hashmap_put(m->buttons, b->name, b) < 0) {
+                free(b->name);
+                free(b);
+                return NULL;
+        }
+
+        b->manager = m;
+        b->fd = -1;
+
+        return b;
+}
+
+void button_free(Button *b) {
+        assert(b);
+
+        hashmap_remove(b->manager->buttons, b->name);
+
+        if (b->fd >= 0) {
+                hashmap_remove(b->manager->button_fds, INT_TO_PTR(b->fd + 1));
+                assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0);
+                close_nointr_nofail(b->fd);
+        }
+
+        free(b->name);
+        free(b->seat);
+        free(b);
+}
+
+int button_set_seat(Button *b, const char *sn) {
+        char *s;
+
+        assert(b);
+        assert(sn);
+
+        s = strdup(sn);
+        if (!s)
+                return -ENOMEM;
+
+        free(b->seat);
+        b->seat = s;
+
+        return 0;
+}
+
+int button_open(Button *b) {
+        char name[256], *p;
+        struct epoll_event ev;
+        int r;
+
+        assert(b);
+
+        if (b->fd >= 0) {
+                close_nointr_nofail(b->fd);
+                b->fd = -1;
+        }
+
+        p = strappend("/dev/input/", b->name);
+        if (!p)
+                return log_oom();
+
+        b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+        free(p);
+        if (b->fd < 0) {
+                log_warning("Failed to open %s: %m", b->name);
+                return -errno;
+        }
+
+        if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
+                log_error("Failed to get input name: %m");
+                r = -errno;
+                goto fail;
+        }
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.u32 = FD_OTHER_BASE + b->fd;
+
+        if (epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_ADD, b->fd, &ev) < 0) {
+                log_error("Failed to add to epoll: %m");
+                r = -errno;
+                goto fail;
+        }
+
+        r = hashmap_put(b->manager->button_fds, INT_TO_PTR(b->fd + 1), b);
+        if (r < 0) {
+                log_error("Failed to add to hash map: %s", strerror(-r));
+                assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0);
+                goto fail;
+        }
+
+        log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name);
+
+        return 0;
+
+fail:
+        close_nointr_nofail(b->fd);
+        b->fd = -1;
+        return r;
+}
+
+static int button_handle(
+                Button *b,
+                InhibitWhat inhibit_key,
+                HandleAction handle,
+                bool ignore_inhibited,
+                bool is_edge) {
+
+        int r;
+
+        assert(b);
+
+        r = manager_handle_action(b->manager, inhibit_key, handle, ignore_inhibited, is_edge);
+        if (r > 0)
+                /* We are executing the operation, so make sure we don't
+                 * execute another one until the lid is opened/closed again */
+                b->lid_close_queued = false;
+
+        return r;
+}
+
+int button_process(Button *b) {
+        struct input_event ev;
+        ssize_t l;
+
+        assert(b);
+
+        l = read(b->fd, &ev, sizeof(ev));
+        if (l < 0)
+                return errno != EAGAIN ? -errno : 0;
+        if ((size_t) l < sizeof(ev))
+                return -EIO;
+
+        if (ev.type == EV_KEY && ev.value > 0) {
+
+                switch (ev.code) {
+
+                case KEY_POWER:
+                case KEY_POWER2:
+                        log_info("Power key pressed.");
+                        return button_handle(b, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
+
+                /* The kernel is a bit confused here:
+
+                   KEY_SLEEP   = suspend-to-ram, which everybody else calls "suspend"
+                   KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate"
+                */
+
+                case KEY_SLEEP:
+                        log_info("Suspend key pressed.");
+                        return button_handle(b, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
+
+                case KEY_SUSPEND:
+                        log_info("Hibernate key pressed.");
+                        return button_handle(b, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
+                }
+
+        } else if (ev.type == EV_SW && ev.value > 0) {
+
+                switch (ev.code) {
+
+                case SW_LID:
+                        log_info("Lid closed.");
+                        b->lid_close_queued = true;
+
+                        return button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, true);
+                }
+
+        } else if (ev.type == EV_SW && ev.value == 0) {
+
+                switch (ev.code) {
+
+                case SW_LID:
+                        log_info("Lid opened.");
+                        b->lid_close_queued = false;
+                        break;
+                }
+        }
+
+        return 0;
+}
+
+int button_recheck(Button *b) {
+        assert(b);
+
+        if (!b->lid_close_queued)
+                return 0;
+
+        return button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, false);
+}
diff --git a/src/login/logind-button.h b/src/login/logind-button.h
new file mode 100644 (file)
index 0000000..1c5a845
--- /dev/null
@@ -0,0 +1,48 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foologindbuttonhfoo
+#define foologindbuttonhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Button Button;
+
+#include "list.h"
+#include "util.h"
+#include "logind.h"
+
+struct Button {
+        Manager *manager;
+
+        char *name;
+        char *seat;
+        int fd;
+
+        bool lid_close_queued;
+};
+
+Button* button_new(Manager *m, const char *name);
+void button_free(Button*b);
+int button_open(Button *b);
+int button_process(Button *b);
+int button_recheck(Button *b);
+int button_set_seat(Button *b, const char *sn);
+
+#endif
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
new file mode 100644 (file)
index 0000000..77a06f2
--- /dev/null
@@ -0,0 +1,2393 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#include "logind.h"
+#include "dbus-common.h"
+#include "strv.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "polkit.h"
+#include "special.h"
+#include "systemd/sd-id128.h"
+#include "systemd/sd-messages.h"
+
+#define BUS_MANAGER_INTERFACE                                           \
+        " <interface name=\"org.freedesktop.login1.Manager\">\n"        \
+        "  <method name=\"GetSession\">\n"                              \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "   <arg name=\"session\" type=\"o\" direction=\"out\"/>\n"     \
+        "  </method>\n"                                                 \
+        "  <method name=\"GetSessionByPID\">\n"                         \
+        "   <arg name=\"pid\" type=\"u\" direction=\"in\"/>\n"          \
+        "   <arg name=\"session\" type=\"o\" direction=\"out\"/>\n"     \
+        "  </method>\n"                                                 \
+        "  <method name=\"GetUser\">\n"                                 \
+        "   <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"          \
+        "   <arg name=\"user\" type=\"o\" direction=\"out\"/>\n"        \
+        "  </method>\n"                                                 \
+        "  <method name=\"GetSeat\">\n"                                 \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "   <arg name=\"seat\" type=\"o\" direction=\"out\"/>\n"        \
+        "  </method>\n"                                                 \
+        "  <method name=\"ListSessions\">\n"                            \
+        "   <arg name=\"sessions\" type=\"a(susso)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"ListUsers\">\n"                               \
+        "   <arg name=\"users\" type=\"a(uso)\" direction=\"out\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"ListSeats\">\n"                               \
+        "   <arg name=\"seats\" type=\"a(so)\" direction=\"out\"/>\n"   \
+        "  </method>\n"                                                 \
+        "  <method name=\"CreateSession\">\n"                           \
+        "   <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"          \
+        "   <arg name=\"leader\" type=\"u\" direction=\"in\"/>\n"       \
+        "   <arg name=\"sevice\" type=\"s\" direction=\"in\"/>\n"       \
+        "   <arg name=\"type\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"class\" type=\"s\" direction=\"in\"/>\n"        \
+        "   <arg name=\"seat\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"vtnr\" type=\"u\" direction=\"in\"/>\n"         \
+        "   <arg name=\"tty\" type=\"s\" direction=\"in\"/>\n"          \
+        "   <arg name=\"display\" type=\"s\" direction=\"in\"/>\n"      \
+        "   <arg name=\"remote\" type=\"b\" direction=\"in\"/>\n"       \
+        "   <arg name=\"remote_user\" type=\"s\" direction=\"in\"/>\n"  \
+        "   <arg name=\"remote_host\" type=\"s\" direction=\"in\"/>\n"  \
+        "   <arg name=\"controllers\" type=\"as\" direction=\"in\"/>\n" \
+        "   <arg name=\"reset_controllers\" type=\"as\" direction=\"in\"/>\n" \
+        "   <arg name=\"kill_processes\" type=\"b\" direction=\"in\"/>\n" \
+        "   <arg name=\"id\" type=\"s\" direction=\"out\"/>\n"          \
+        "   <arg name=\"path\" type=\"o\" direction=\"out\"/>\n"        \
+        "   <arg name=\"runtime_path\" type=\"o\" direction=\"out\"/>\n" \
+        "   <arg name=\"fd\" type=\"h\" direction=\"out\"/>\n"          \
+        "   <arg name=\"seat\" type=\"s\" direction=\"out\"/>\n"        \
+        "   <arg name=\"vtnr\" type=\"u\" direction=\"out\"/>\n"        \
+        "   <arg name=\"existing\" type=\"b\" direction=\"out\"/>\n"    \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReleaseSession\">\n"                          \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "  </method>\n"                                                 \
+        "  <method name=\"ActivateSession\">\n"                         \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "  </method>\n"                                                 \
+        "  <method name=\"ActivateSessionOnSeat\">\n"                   \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "   <arg name=\"seat\" type=\"s\" direction=\"in\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"LockSession\">\n"                             \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "  </method>\n"                                                 \
+        "  <method name=\"UnlockSession\">\n"                           \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "  </method>\n"                                                 \
+        "  <method name=\"LockSessions\"/>\n"                           \
+        "  <method name=\"KillSession\">\n"                             \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "   <arg name=\"who\" type=\"s\" direction=\"in\"/>\n"          \
+        "   <arg name=\"signal\" type=\"s\" direction=\"in\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"KillUser\">\n"                                \
+        "   <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"          \
+        "   <arg name=\"signal\" type=\"s\" direction=\"in\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"TerminateSession\">\n"                        \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "  </method>\n"                                                 \
+        "  <method name=\"TerminateUser\">\n"                           \
+        "   <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"          \
+        "  </method>\n"                                                 \
+        "  <method name=\"TerminateSeat\">\n"                           \
+        "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetUserLinger\">\n"                           \
+        "   <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"          \
+        "   <arg name=\"b\" type=\"b\" direction=\"in\"/>\n"            \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"AttachDevice\">\n"                            \
+        "   <arg name=\"seat\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"sysfs\" type=\"s\" direction=\"in\"/>\n"        \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"FlushDevices\">\n"                            \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"PowerOff\">\n"                                \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"Reboot\">\n"                                  \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"Suspend\">\n"                                 \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"Hibernate\">\n"                               \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"HybridSleep\">\n"                             \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
+        "  <method name=\"CanPowerOff\">\n"                             \
+        "   <arg name=\"result\" type=\"s\" direction=\"out\"/>\n"      \
+        "  </method>\n"                                                 \
+        "  <method name=\"CanReboot\">\n"                               \
+        "   <arg name=\"result\" type=\"s\" direction=\"out\"/>\n"      \
+        "  </method>\n"                                                 \
+        "  <method name=\"CanSuspend\">\n"                              \
+        "   <arg name=\"result\" type=\"s\" direction=\"out\"/>\n"      \
+        "  </method>\n"                                                 \
+        "  <method name=\"CanHibernate\">\n"                            \
+        "   <arg name=\"result\" type=\"s\" direction=\"out\"/>\n"      \
+        "  </method>\n"                                                 \
+        "  <method name=\"CanHybridSleep\">\n"                          \
+        "   <arg name=\"result\" type=\"s\" direction=\"out\"/>\n"      \
+        "  </method>\n"                                                 \
+        "  <method name=\"Inhibit\">\n"                                 \
+        "   <arg name=\"what\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"who\" type=\"s\" direction=\"in\"/>\n"          \
+        "   <arg name=\"why\" type=\"s\" direction=\"in\"/>\n"          \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"fd\" type=\"h\" direction=\"out\"/>\n"          \
+        "  </method>\n"                                                 \
+        "  <method name=\"ListInhibitors\">\n"                          \
+        "   <arg name=\"inhibitors\" type=\"a(ssssuu)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <signal name=\"SessionNew\">\n"                              \
+        "   <arg name=\"id\" type=\"s\"/>\n"                            \
+        "   <arg name=\"path\" type=\"o\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"SessionRemoved\">\n"                          \
+        "   <arg name=\"id\" type=\"s\"/>\n"                            \
+        "   <arg name=\"path\" type=\"o\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"UserNew\">\n"                                 \
+        "   <arg name=\"uid\" type=\"u\"/>\n"                           \
+        "   <arg name=\"path\" type=\"o\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"UserRemoved\">\n"                             \
+        "   <arg name=\"uid\" type=\"u\"/>\n"                           \
+        "   <arg name=\"path\" type=\"o\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"SeatNew\">\n"                                 \
+        "   <arg name=\"id\" type=\"s\"/>\n"                            \
+        "   <arg name=\"path\" type=\"o\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"SeatRemoved\">\n"                             \
+        "   <arg name=\"id\" type=\"s\"/>\n"                            \
+        "   <arg name=\"path\" type=\"o\"/>\n"                          \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"PrepareForShutdown\">\n"                      \
+        "   <arg name=\"active\" type=\"b\"/>\n"                        \
+        "  </signal>\n"                                                 \
+        "  <signal name=\"PrepareForSleep\">\n"                         \
+        "   <arg name=\"active\" type=\"b\"/>\n"                        \
+        "  </signal>\n"                                                 \
+        "  <property name=\"ControlGroupHierarchy\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"Controllers\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"ResetControllers\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"NAutoVTs\" type=\"u\" access=\"read\"/>\n" \
+        "  <property name=\"KillOnlyUsers\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"KillExcludeUsers\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"KillUserProcesses\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"IdleHint\" type=\"b\" access=\"read\"/>\n"  \
+        "  <property name=\"IdleSinceHint\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"IdleSinceHintMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"BlockInhibited\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"DelayInhibited\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"InhibitDelayMaxUSec\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"HandlePowerKey\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"HandleSuspendKey\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"HandleHibernateKey\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"HandleLidSwitch\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"IdleAction\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"IdleActionUSec\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"PreparingForShutdown\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"PreparingForSleep\" type=\"b\" access=\"read\"/>\n" \
+        " </interface>\n"
+
+#define INTROSPECTION_BEGIN                                             \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_MANAGER_INTERFACE                                           \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE
+
+#define INTROSPECTION_END                                               \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_GENERIC_INTERFACES_LIST                  \
+        "org.freedesktop.login1.Manager\0"
+
+static int bus_manager_append_idle_hint(DBusMessageIter *i, const char *property, void *data) {
+        Manager *m = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        b = manager_get_idle_hint(m, NULL) > 0;
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_manager_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) {
+        Manager *m = data;
+        dual_timestamp t;
+        uint64_t u;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        manager_get_idle_hint(m, &t);
+        u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_manager_append_inhibited(DBusMessageIter *i, const char *property, void *data) {
+        Manager *m = data;
+        InhibitWhat w;
+        const char *p;
+
+        w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
+        p = inhibit_what_to_string(w);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &p))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_manager_append_preparing(DBusMessageIter *i, const char *property, void *data) {
+        Manager *m = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+
+        if (streq(property, "PreparingForShutdown"))
+                b = !!(m->delayed_what & INHIBIT_SHUTDOWN);
+        else
+                b = !!(m->delayed_what & INHIBIT_SLEEP);
+
+        dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b);
+        return 0;
+}
+
+static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMessage **_reply) {
+        Session *session = NULL;
+        User *user = NULL;
+        const char *type, *class, *seat, *tty, *display, *remote_user, *remote_host, *service;
+        uint32_t uid, leader, audit_id = 0;
+        dbus_bool_t remote, kill_processes, exists;
+        char **controllers = NULL, **reset_controllers = NULL;
+        SessionType t;
+        SessionClass c;
+        Seat *s;
+        DBusMessageIter iter;
+        int r;
+        char *id = NULL, *p;
+        uint32_t vtnr = 0;
+        int fifo_fd = -1;
+        DBusMessage *reply = NULL;
+        bool b;
+
+        assert(m);
+        assert(message);
+        assert(_reply);
+
+        if (!dbus_message_iter_init(message, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &uid);
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &leader);
+
+        if (leader <= 0 ||
+            !dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &service);
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &type);
+        t = session_type_from_string(type);
+
+        if (t < 0 ||
+            !dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &class);
+        if (isempty(class))
+                c = SESSION_USER;
+        else
+                c = session_class_from_string(class);
+
+        if (c < 0 ||
+            !dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &seat);
+
+        if (isempty(seat))
+                s = NULL;
+        else {
+                s = hashmap_get(m->seats, seat);
+                if (!s)
+                        return -ENOENT;
+        }
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &vtnr);
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &tty);
+
+        if (tty_is_vc(tty)) {
+                int v;
+
+                if (!s)
+                        s = m->vtconsole;
+                else if (s != m->vtconsole)
+                        return -EINVAL;
+
+                v = vtnr_from_tty(tty);
+
+                if (v <= 0)
+                        return v < 0 ? v : -EINVAL;
+
+                if (vtnr <= 0)
+                        vtnr = (uint32_t) v;
+                else if (vtnr != (uint32_t) v)
+                        return -EINVAL;
+        } else if (tty_is_console(tty)) {
+
+                if (!s)
+                        s = m->vtconsole;
+                else if (s != m->vtconsole)
+                        return -EINVAL;
+
+                if (vtnr != 0)
+                        return -EINVAL;
+
+        }
+
+        if (s) {
+                if (seat_can_multi_session(s)) {
+                        if (vtnr > 63)
+                                return -EINVAL;
+                } else {
+                        if (vtnr != 0)
+                                return -EINVAL;
+                }
+        }
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &display);
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &remote);
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &remote_user);
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        dbus_message_iter_get_basic(&iter, &remote_host);
+
+        if (!dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING)
+                return -EINVAL;
+
+        r = bus_parse_strv_iter(&iter, &controllers);
+        if (r < 0)
+                return -EINVAL;
+
+        if (strv_contains(controllers, "systemd") ||
+            !dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        r = bus_parse_strv_iter(&iter, &reset_controllers);
+        if (r < 0)
+                goto fail;
+
+        if (strv_contains(reset_controllers, "systemd") ||
+            !dbus_message_iter_next(&iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        dbus_message_iter_get_basic(&iter, &kill_processes);
+
+        r = manager_add_user_by_uid(m, uid, &user);
+        if (r < 0)
+                goto fail;
+
+        audit_session_from_pid(leader, &audit_id);
+
+        if (audit_id > 0) {
+                asprintf(&id, "%lu", (unsigned long) audit_id);
+
+                if (!id) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                session = hashmap_get(m->sessions, id);
+
+                if (session) {
+                        free(id);
+
+                        fifo_fd = session_create_fifo(session);
+                        if (fifo_fd < 0) {
+                                r = fifo_fd;
+                                goto fail;
+                        }
+
+                        /* Session already exists, client is probably
+                         * something like "su" which changes uid but
+                         * is still the same audit session */
+
+                        reply = dbus_message_new_method_return(message);
+                        if (!reply) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        p = session_bus_path(session);
+                        if (!p) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        seat = session->seat ? session->seat->id : "";
+                        vtnr = session->vtnr;
+                        exists = true;
+
+                        b = dbus_message_append_args(
+                                        reply,
+                                        DBUS_TYPE_STRING, &session->id,
+                                        DBUS_TYPE_OBJECT_PATH, &p,
+                                        DBUS_TYPE_STRING, &session->user->runtime_path,
+                                        DBUS_TYPE_UNIX_FD, &fifo_fd,
+                                        DBUS_TYPE_STRING, &seat,
+                                        DBUS_TYPE_UINT32, &vtnr,
+                                        DBUS_TYPE_BOOLEAN, &exists,
+                                        DBUS_TYPE_INVALID);
+                        free(p);
+
+                        if (!b) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        close_nointr_nofail(fifo_fd);
+                        *_reply = reply;
+
+                        strv_free(controllers);
+                        strv_free(reset_controllers);
+
+                        return 0;
+                }
+
+        } else {
+                do {
+                        free(id);
+                        id = NULL;
+
+                        if (asprintf(&id, "c%lu", ++m->session_counter) < 0) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                } while (hashmap_get(m->sessions, id));
+        }
+
+        r = manager_add_session(m, user, id, &session);
+        free(id);
+        if (r < 0)
+                goto fail;
+
+        session->leader = leader;
+        session->audit_id = audit_id;
+        session->type = t;
+        session->class = c;
+        session->remote = remote;
+        session->controllers = controllers;
+        session->reset_controllers = reset_controllers;
+        session->kill_processes = kill_processes;
+        session->vtnr = vtnr;
+
+        controllers = reset_controllers = NULL;
+
+        if (!isempty(tty)) {
+                session->tty = strdup(tty);
+                if (!session->tty) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+        }
+
+        if (!isempty(display)) {
+                session->display = strdup(display);
+                if (!session->display) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+        }
+
+        if (!isempty(remote_user)) {
+                session->remote_user = strdup(remote_user);
+                if (!session->remote_user) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+        }
+
+        if (!isempty(remote_host)) {
+                session->remote_host = strdup(remote_host);
+                if (!session->remote_host) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+        }
+
+        if (!isempty(service)) {
+                session->service = strdup(service);
+                if (!session->service) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+        }
+
+        fifo_fd = session_create_fifo(session);
+        if (fifo_fd < 0) {
+                r = fifo_fd;
+                goto fail;
+        }
+
+        if (s) {
+                r = seat_attach_session(s, session);
+                if (r < 0)
+                        goto fail;
+        }
+
+        r = session_start(session);
+        if (r < 0)
+                goto fail;
+
+        reply = dbus_message_new_method_return(message);
+        if (!reply) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        p = session_bus_path(session);
+        if (!p) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        seat = s ? s->id : "";
+        exists = false;
+        b = dbus_message_append_args(
+                        reply,
+                        DBUS_TYPE_STRING, &session->id,
+                        DBUS_TYPE_OBJECT_PATH, &p,
+                        DBUS_TYPE_STRING, &session->user->runtime_path,
+                        DBUS_TYPE_UNIX_FD, &fifo_fd,
+                        DBUS_TYPE_STRING, &seat,
+                        DBUS_TYPE_UINT32, &vtnr,
+                        DBUS_TYPE_BOOLEAN, &exists,
+                        DBUS_TYPE_INVALID);
+        free(p);
+
+        if (!b) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        close_nointr_nofail(fifo_fd);
+        *_reply = reply;
+
+        return 0;
+
+fail:
+        strv_free(controllers);
+        strv_free(reset_controllers);
+
+        if (session)
+                session_add_to_gc_queue(session);
+
+        if (user)
+                user_add_to_gc_queue(user);
+
+        if (fifo_fd >= 0)
+                close_nointr_nofail(fifo_fd);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int bus_manager_inhibit(Manager *m, DBusConnection *connection, DBusMessage *message, DBusError *error, DBusMessage **_reply) {
+        Inhibitor *i = NULL;
+        char *id = NULL;
+        const char *who, *why, *what, *mode;
+        pid_t pid;
+        InhibitWhat w;
+        InhibitMode mm;
+        unsigned long ul;
+        int r, fifo_fd = -1;
+        DBusMessage *reply = NULL;
+
+        assert(m);
+        assert(connection);
+        assert(message);
+        assert(error);
+        assert(_reply);
+
+        if (!dbus_message_get_args(
+                            message,
+                            error,
+                            DBUS_TYPE_STRING, &what,
+                            DBUS_TYPE_STRING, &who,
+                            DBUS_TYPE_STRING, &why,
+                            DBUS_TYPE_STRING, &mode,
+                            DBUS_TYPE_INVALID)) {
+                r = -EIO;
+                goto fail;
+        }
+
+        w = inhibit_what_from_string(what);
+        if (w <= 0) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        mm = inhibit_mode_from_string(mode);
+        if (mm < 0) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        /* Delay is only supported for shutdown/sleep */
+        if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP))) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        r = verify_polkit(connection, message,
+                          w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
+                          w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
+                          w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
+                          w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
+                          w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
+                          w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
+                                                              "org.freedesktop.login1.inhibit-handle-lid-switch",
+                          false, NULL, error);
+        if (r < 0)
+                goto fail;
+
+        ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error);
+        if (ul == (unsigned long) -1) {
+                r = -EIO;
+                goto fail;
+        }
+
+        pid = bus_get_unix_process_id(connection, dbus_message_get_sender(message), error);
+        if (pid <= 0) {
+                r = -EIO;
+                goto fail;
+        }
+
+        do {
+                free(id);
+                id = NULL;
+
+                if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+        } while (hashmap_get(m->inhibitors, id));
+
+        r = manager_add_inhibitor(m, id, &i);
+        free(id);
+
+        if (r < 0)
+                goto fail;
+
+        i->what = w;
+        i->mode = mm;
+        i->pid = pid;
+        i->uid = (uid_t) ul;
+        i->why = strdup(why);
+        i->who = strdup(who);
+
+        if (!i->why || !i->who) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        fifo_fd = inhibitor_create_fifo(i);
+        if (fifo_fd < 0) {
+                r = fifo_fd;
+                goto fail;
+        }
+
+        reply = dbus_message_new_method_return(message);
+        if (!reply) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        if (!dbus_message_append_args(
+                            reply,
+                            DBUS_TYPE_UNIX_FD, &fifo_fd,
+                            DBUS_TYPE_INVALID)) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        close_nointr_nofail(fifo_fd);
+        *_reply = reply;
+
+        inhibitor_start(i);
+
+        return 0;
+
+fail:
+        if (i)
+                inhibitor_free(i);
+
+        if (fifo_fd >= 0)
+                close_nointr_nofail(fifo_fd);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int trigger_device(Manager *m, struct udev_device *d) {
+        struct udev_enumerate *e;
+        struct udev_list_entry *first, *item;
+        int r;
+
+        assert(m);
+
+        e = udev_enumerate_new(m->udev);
+        if (!e) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (d) {
+                if (udev_enumerate_add_match_parent(e, d) < 0) {
+                        r = -EIO;
+                        goto finish;
+                }
+        }
+
+        if (udev_enumerate_scan_devices(e) < 0) {
+                r = -EIO;
+                goto finish;
+        }
+
+        first = udev_enumerate_get_list_entry(e);
+        udev_list_entry_foreach(item, first) {
+                char *t;
+                const char *p;
+
+                p = udev_list_entry_get_name(item);
+
+                t = strappend(p, "/uevent");
+                if (!t) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                write_one_line_file(t, "change");
+                free(t);
+        }
+
+        r = 0;
+
+finish:
+        if (e)
+                udev_enumerate_unref(e);
+
+        return r;
+}
+
+static int attach_device(Manager *m, const char *seat, const char *sysfs) {
+        struct udev_device *d;
+        char *rule = NULL, *file = NULL;
+        const char *id_for_seat;
+        int r;
+
+        assert(m);
+        assert(seat);
+        assert(sysfs);
+
+        d = udev_device_new_from_syspath(m->udev, sysfs);
+        if (!d)
+                return -ENODEV;
+
+        if (!udev_device_has_tag(d, "seat")) {
+                r = -ENODEV;
+                goto finish;
+        }
+
+        id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
+        if (!id_for_seat) {
+                r = -ENODEV;
+                goto finish;
+        }
+
+        if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        mkdir_p_label("/etc/udev/rules.d", 0755);
+        r = write_one_line_file_atomic(file, rule);
+        if (r < 0)
+                goto finish;
+
+        r = trigger_device(m, d);
+
+finish:
+        free(rule);
+        free(file);
+
+        if (d)
+                udev_device_unref(d);
+
+        return r;
+}
+
+static int flush_devices(Manager *m) {
+        DIR *d;
+
+        assert(m);
+
+        d = opendir("/etc/udev/rules.d");
+        if (!d) {
+                if (errno != ENOENT)
+                        log_warning("Failed to open /etc/udev/rules.d: %m");
+        } else {
+                struct dirent *de;
+
+                while ((de = readdir(d))) {
+
+                        if (!dirent_is_file(de))
+                                continue;
+
+                        if (!startswith(de->d_name, "72-seat-"))
+                                continue;
+
+                        if (!endswith(de->d_name, ".rules"))
+                                continue;
+
+                        if (unlinkat(dirfd(d), de->d_name, 0) < 0)
+                                log_warning("Failed to unlink %s: %m", de->d_name);
+                }
+
+                closedir(d);
+        }
+
+        return trigger_device(m, NULL);
+}
+
+static int have_multiple_sessions(
+                Manager *m,
+                uid_t uid) {
+
+        Session *session;
+        Iterator i;
+
+        assert(m);
+
+        /* Check for other users' sessions. Greeter sessions do not count. */
+        HASHMAP_FOREACH(session, m->sessions, i)
+                if (session->class == SESSION_USER && session->user->uid != uid)
+                        return true;
+
+        return false;
+}
+
+static int send_start_unit(DBusConnection *connection, const char *unit_name, DBusError *error) {
+        const char *mode = "replace";
+
+        assert(unit_name);
+
+        return bus_method_call_with_reply (
+                        connection,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "StartUnit",
+                        NULL,
+                        NULL,
+                        DBUS_TYPE_STRING, &unit_name,
+                        DBUS_TYPE_STRING, &mode,
+                        DBUS_TYPE_INVALID);
+}
+
+static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
+        static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
+                [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
+                [INHIBIT_SLEEP] = "PrepareForSleep"
+        };
+
+        dbus_bool_t active = _active;
+        DBusMessage *message;
+        int r = 0;
+
+        assert(m);
+        assert(w >= 0);
+        assert(w < _INHIBIT_WHAT_MAX);
+        assert(signal_name[w]);
+
+        message = dbus_message_new_signal("/org/freedesktop/login1", "org.freedesktop.login1.Manager", signal_name[w]);
+        if (!message)
+                return -ENOMEM;
+
+        if (!dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &active, DBUS_TYPE_INVALID) ||
+            !dbus_connection_send(m->bus, message, NULL))
+                r = -ENOMEM;
+
+        dbus_message_unref(message);
+        return r;
+}
+
+static int delay_shutdown_or_sleep(Manager *m, InhibitWhat w, const char *unit_name) {
+        assert(m);
+        assert(w >= 0);
+        assert(w < _INHIBIT_WHAT_MAX);
+
+        /* Tell everybody to prepare for shutdown/sleep */
+        send_prepare_for(m, w, true);
+
+        /* Update timestamp for timeout */
+        if (!m->delayed_unit)
+                m->delayed_timestamp = now(CLOCK_MONOTONIC);
+
+        /* Remember what we want to do, possibly overriding what kind
+         * of unit we previously queued. */
+        m->delayed_unit = unit_name;
+        m->delayed_what = w;
+
+        return 0;
+}
+
+static int bus_manager_can_shutdown_or_sleep(
+                Manager *m,
+                DBusConnection *connection,
+                DBusMessage *message,
+                InhibitWhat w,
+                const char *action,
+                const char *action_multiple_sessions,
+                const char *action_ignore_inhibit,
+                const char *sleep_type,
+                const char *sleep_disk_type,
+                DBusError *error,
+                DBusMessage **_reply) {
+
+        bool multiple_sessions, challenge, blocked, b;
+        const char *result;
+        DBusMessage *reply = NULL;
+        int r;
+        unsigned long ul;
+
+        assert(m);
+        assert(connection);
+        assert(message);
+        assert(w >= 0);
+        assert(w <= _INHIBIT_WHAT_MAX);
+        assert(action);
+        assert(action_multiple_sessions);
+        assert(action_ignore_inhibit);
+        assert(error);
+        assert(_reply);
+
+        if (sleep_type) {
+                r = can_sleep(sleep_type);
+                if (r < 0)
+                        return r;
+
+                if (r == 0) {
+                        result = "na";
+                        goto finish;
+                }
+        }
+
+        if (sleep_disk_type) {
+                r = can_sleep_disk(sleep_disk_type);
+                if (r < 0)
+                        return r;
+
+                if (r == 0) {
+                        result = "na";
+                        goto finish;
+                }
+        }
+
+        ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error);
+        if (ul == (unsigned long) -1)
+                return -EIO;
+
+        r = have_multiple_sessions(m, (uid_t) ul);
+        if (r < 0)
+                return r;
+
+        multiple_sessions = r > 0;
+        blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, (uid_t) ul);
+
+        if (multiple_sessions) {
+                r = verify_polkit(connection, message, action_multiple_sessions, false, &challenge, error);
+                if (r < 0)
+                        return r;
+
+                if (r > 0)
+                        result = "yes";
+                else if (challenge)
+                        result = "challenge";
+                else
+                        result = "no";
+        }
+
+        if (blocked) {
+                r = verify_polkit(connection, message, action_ignore_inhibit, false, &challenge, error);
+                if (r < 0)
+                        return r;
+
+                if (r > 0 && !result)
+                        result = "yes";
+                else if (challenge && (!result || streq(result, "yes")))
+                        result = "challenge";
+                else
+                        result = "no";
+        }
+
+        if (!multiple_sessions && !blocked) {
+                /* If neither inhibit nor multiple sessions
+                 * apply then just check the normal policy */
+
+                r = verify_polkit(connection, message, action, false, &challenge, error);
+                if (r < 0)
+                        return r;
+
+                if (r > 0)
+                        result = "yes";
+                else if (challenge)
+                        result = "challenge";
+                else
+                        result = "no";
+        }
+
+finish:
+        reply = dbus_message_new_method_return(message);
+        if (!reply)
+                return -ENOMEM;
+
+        b = dbus_message_append_args(
+                        reply,
+                        DBUS_TYPE_STRING, &result,
+                        DBUS_TYPE_INVALID);
+        if (!b) {
+                dbus_message_unref(reply);
+                return -ENOMEM;
+        }
+
+        *_reply = reply;
+        return 0;
+}
+
+static int bus_manager_log_shutdown(
+                Manager *m,
+                InhibitWhat w,
+                const char *unit_name) {
+
+        const char *p, *q;
+
+        assert(m);
+        assert(unit_name);
+
+        if (w != INHIBIT_SHUTDOWN)
+                return 0;
+
+        if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
+                p = "MESSAGE=System is powering down.";
+                q = "SHUTDOWN=power-off";
+        } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
+                p = "MESSAGE=System is halting.";
+                q = "SHUTDOWN=halt";
+        } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
+                p = "MESSAGE=System is rebooting.";
+                q = "SHUTDOWN=reboot";
+        } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
+                p = "MESSAGE=System is rebooting with kexec.";
+                q = "SHUTDOWN=kexec";
+        } else {
+                p = "MESSAGE=System is shutting down.";
+                q = NULL;
+        }
+
+        return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
+                          p,
+                          q, NULL);
+}
+
+int bus_manager_shutdown_or_sleep_now_or_later(
+                Manager *m,
+                const char *unit_name,
+                InhibitWhat w,
+                DBusError *error) {
+
+        bool delayed;
+        int r;
+
+        assert(m);
+        assert(unit_name);
+        assert(w >= 0);
+        assert(w <= _INHIBIT_WHAT_MAX);
+
+        delayed =
+                m->inhibit_delay_max > 0 &&
+                manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0);
+
+        if (delayed)
+                /* Shutdown is delayed, keep in mind what we
+                 * want to do, and start a timeout */
+                r = delay_shutdown_or_sleep(m, w, unit_name);
+        else {
+                bus_manager_log_shutdown(m, w, unit_name);
+
+                /* Shutdown is not delayed, execute it
+                 * immediately */
+                r = send_start_unit(m->bus, unit_name, error);
+        }
+
+        return r;
+}
+
+static int bus_manager_do_shutdown_or_sleep(
+                Manager *m,
+                DBusConnection *connection,
+                DBusMessage *message,
+                const char *unit_name,
+                InhibitWhat w,
+                const char *action,
+                const char *action_multiple_sessions,
+                const char *action_ignore_inhibit,
+                const char *sleep_type,
+                const char *sleep_disk_type,
+                DBusError *error,
+                DBusMessage **_reply) {
+
+        dbus_bool_t interactive;
+        bool multiple_sessions, blocked;
+        DBusMessage *reply = NULL;
+        int r;
+        unsigned long ul;
+
+        assert(m);
+        assert(connection);
+        assert(message);
+        assert(unit_name);
+        assert(w >= 0);
+        assert(w <= _INHIBIT_WHAT_MAX);
+        assert(action);
+        assert(action_multiple_sessions);
+        assert(action_ignore_inhibit);
+        assert(error);
+        assert(_reply);
+
+        if (!dbus_message_get_args(
+                            message,
+                            error,
+                            DBUS_TYPE_BOOLEAN, &interactive,
+                            DBUS_TYPE_INVALID))
+                return -EINVAL;
+
+        if (sleep_type) {
+                r = can_sleep(sleep_type);
+                if (r < 0)
+                        return r;
+
+                if (r == 0)
+                        return -ENOTSUP;
+        }
+
+        if (sleep_disk_type) {
+                r = can_sleep_disk(sleep_disk_type);
+                if (r < 0)
+                        return r;
+
+                if (r == 0)
+                        return -ENOTSUP;
+        }
+
+        ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error);
+        if (ul == (unsigned long) -1)
+                return -EIO;
+
+        r = have_multiple_sessions(m, (uid_t) ul);
+        if (r < 0)
+                return r;
+
+        multiple_sessions = r > 0;
+        blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, (uid_t) ul);
+
+        if (multiple_sessions) {
+                r = verify_polkit(connection, message, action_multiple_sessions, interactive, NULL, error);
+                if (r < 0)
+                        return r;
+        }
+
+        if (blocked) {
+                r = verify_polkit(connection, message, action_ignore_inhibit, interactive, NULL, error);
+                if (r < 0)
+                        return r;
+        }
+
+        if (!multiple_sessions && !blocked) {
+                r = verify_polkit(connection, message, action, interactive, NULL, error);
+                if (r < 0)
+                        return r;
+        }
+
+        r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
+        if (r < 0)
+                return r;
+
+        reply = dbus_message_new_method_return(message);
+        if (!reply)
+                return -ENOMEM;
+
+        *_reply = reply;
+        return 0;
+}
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_handle_action, handle_action, HandleAction);
+
+static const BusProperty bus_login_manager_properties[] = {
+        { "ControlGroupHierarchy",  bus_property_append_string,         "s",  offsetof(Manager, cgroup_path),        true },
+        { "Controllers",            bus_property_append_strv,           "as", offsetof(Manager, controllers),        true },
+        { "ResetControllers",       bus_property_append_strv,           "as", offsetof(Manager, reset_controllers),  true },
+        { "NAutoVTs",               bus_property_append_unsigned,       "u",  offsetof(Manager, n_autovts)           },
+        { "KillOnlyUsers",          bus_property_append_strv,           "as", offsetof(Manager, kill_only_users),    true },
+        { "KillExcludeUsers",       bus_property_append_strv,           "as", offsetof(Manager, kill_exclude_users), true },
+        { "KillUserProcesses",      bus_property_append_bool,           "b",  offsetof(Manager, kill_user_processes) },
+        { "IdleHint",               bus_manager_append_idle_hint,       "b",  0 },
+        { "IdleSinceHint",          bus_manager_append_idle_hint_since, "t",  0 },
+        { "IdleSinceHintMonotonic", bus_manager_append_idle_hint_since, "t",  0 },
+        { "BlockInhibited",         bus_manager_append_inhibited,       "s",  0 },
+        { "DelayInhibited",         bus_manager_append_inhibited,       "s",  0 },
+        { "InhibitDelayMaxUSec",    bus_property_append_usec,           "t",  offsetof(Manager, inhibit_delay_max)   },
+        { "HandlePowerKey",         bus_manager_append_handle_action,   "s",  offsetof(Manager, handle_power_key)    },
+        { "HandleSuspendKey",       bus_manager_append_handle_action,   "s",  offsetof(Manager, handle_suspend_key)  },
+        { "HandleHibernateKey",     bus_manager_append_handle_action,   "s",  offsetof(Manager, handle_hibernate_key)},
+        { "HandleLidSwitch",        bus_manager_append_handle_action,   "s",  offsetof(Manager, handle_lid_switch)   },
+        { "IdleAction",             bus_manager_append_handle_action,   "s",  offsetof(Manager, idle_action)         },
+        { "IdleActionUSec",         bus_property_append_usec,           "t",  offsetof(Manager, idle_action_usec) },
+        { "PreparingForShutdown",   bus_manager_append_preparing,       "b",  0 },
+        { "PreparingForSleep",      bus_manager_append_preparing,       "b",  0 },
+        { NULL, }
+};
+
+static DBusHandlerResult manager_message_handler(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+        Manager *m = userdata;
+
+        DBusError error;
+        DBusMessage *reply = NULL;
+        int r;
+
+        assert(connection);
+        assert(message);
+        assert(m);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSession")) {
+                const char *name;
+                char *p;
+                Session *session;
+                bool b;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                session = hashmap_get(m->sessions, name);
+                if (!session)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                p = session_bus_path(session);
+                if (!p)
+                        goto oom;
+
+                b = dbus_message_append_args(
+                                reply,
+                                DBUS_TYPE_OBJECT_PATH, &p,
+                                DBUS_TYPE_INVALID);
+                free(p);
+
+                if (!b)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSessionByPID")) {
+                uint32_t pid;
+                char *p;
+                Session *session;
+                bool b;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_UINT32, &pid,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                r = manager_get_session_by_pid(m, pid, &session);
+                if (r <= 0)
+                        return bus_send_error_reply(connection, message, NULL, r < 0 ? r : -ENOENT);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                p = session_bus_path(session);
+                if (!p)
+                        goto oom;
+
+                b = dbus_message_append_args(
+                                reply,
+                                DBUS_TYPE_OBJECT_PATH, &p,
+                                DBUS_TYPE_INVALID);
+                free(p);
+
+                if (!b)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetUser")) {
+                uint32_t uid;
+                char *p;
+                User *user;
+                bool b;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_UINT32, &uid,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
+                if (!user)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                p = user_bus_path(user);
+                if (!p)
+                        goto oom;
+
+                b = dbus_message_append_args(
+                                reply,
+                                DBUS_TYPE_OBJECT_PATH, &p,
+                                DBUS_TYPE_INVALID);
+                free(p);
+
+                if (!b)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSeat")) {
+                const char *name;
+                char *p;
+                Seat *seat;
+                bool b;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                seat = hashmap_get(m->seats, name);
+                if (!seat)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                p = seat_bus_path(seat);
+                if (!p)
+                        goto oom;
+
+                b = dbus_message_append_args(
+                                reply,
+                                DBUS_TYPE_OBJECT_PATH, &p,
+                                DBUS_TYPE_INVALID);
+                free(p);
+
+                if (!b)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSessions")) {
+                char *p;
+                Session *session;
+                Iterator i;
+                DBusMessageIter iter, sub;
+                const char *empty = "";
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(susso)", &sub))
+                        goto oom;
+
+                HASHMAP_FOREACH(session, m->sessions, i) {
+                        DBusMessageIter sub2;
+                        uint32_t uid;
+
+                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
+                                goto oom;
+
+                        uid = session->user->uid;
+
+                        p = session_bus_path(session);
+                        if (!p)
+                                goto oom;
+
+                        if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->user->name) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, session->seat ? (const char**) &session->seat->id : &empty) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) {
+                                free(p);
+                                goto oom;
+                        }
+
+                        free(p);
+
+                        if (!dbus_message_iter_close_container(&sub, &sub2))
+                                goto oom;
+                }
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListUsers")) {
+                char *p;
+                User *user;
+                Iterator i;
+                DBusMessageIter iter, sub;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(uso)", &sub))
+                        goto oom;
+
+                HASHMAP_FOREACH(user, m->users, i) {
+                        DBusMessageIter sub2;
+                        uint32_t uid;
+
+                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
+                                goto oom;
+
+                        uid = user->uid;
+
+                        p = user_bus_path(user);
+                        if (!p)
+                                goto oom;
+
+                        if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &user->name) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) {
+                                free(p);
+                                goto oom;
+                        }
+
+                        free(p);
+
+                        if (!dbus_message_iter_close_container(&sub, &sub2))
+                                goto oom;
+                }
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSeats")) {
+                char *p;
+                Seat *seat;
+                Iterator i;
+                DBusMessageIter iter, sub;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(so)", &sub))
+                        goto oom;
+
+                HASHMAP_FOREACH(seat, m->seats, i) {
+                        DBusMessageIter sub2;
+
+                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
+                                goto oom;
+
+                        p = seat_bus_path(seat);
+                        if (!p)
+                                goto oom;
+
+                        if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &seat->id) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) {
+                                free(p);
+                                goto oom;
+                        }
+
+                        free(p);
+
+                        if (!dbus_message_iter_close_container(&sub, &sub2))
+                                goto oom;
+                }
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListInhibitors")) {
+                Inhibitor *inhibitor;
+                Iterator i;
+                DBusMessageIter iter, sub;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssssuu)", &sub))
+                        goto oom;
+
+                HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
+                        DBusMessageIter sub2;
+                        dbus_uint32_t uid, pid;
+                        const char *what, *who, *why, *mode;
+
+                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
+                                goto oom;
+
+                        what = strempty(inhibit_what_to_string(inhibitor->what));
+                        who = strempty(inhibitor->who);
+                        why = strempty(inhibitor->why);
+                        mode = strempty(inhibit_mode_to_string(inhibitor->mode));
+                        uid = (dbus_uint32_t) inhibitor->uid;
+                        pid = (dbus_uint32_t) inhibitor->pid;
+
+                        if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &what) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &who) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &why) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &mode) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &pid))
+                                goto oom;
+
+                        if (!dbus_message_iter_close_container(&sub, &sub2))
+                                goto oom;
+                }
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Inhibit")) {
+
+                r = bus_manager_inhibit(m, connection, message, &error, &reply);
+
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateSession")) {
+
+                r = bus_manager_create_session(m, message, &reply);
+
+                /* Don't delay the work on OOM here, since it might be
+                 * triggered by a low RLIMIT_NOFILE here (since we
+                 * send a dupped fd to the client), and we'd rather
+                 * see this fail quickly then be retried later */
+
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ReleaseSession")) {
+                const char *name;
+                Session *session;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                session = hashmap_get(m->sessions, name);
+                if (!session)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                /* We use the FIFO to detect stray sessions where the
+                process invoking PAM dies abnormally. We need to make
+                sure that that process is not killed if at the clean
+                end of the session it closes the FIFO. Hence, with
+                this call explicitly turn off the FIFO logic, so that
+                the PAM code can finish clean up on its own */
+                session_remove_fifo(session);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSession")) {
+                const char *name;
+                Session *session;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                session = hashmap_get(m->sessions, name);
+                if (!session)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                r = session_activate(session);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSessionOnSeat")) {
+                const char *session_name, *seat_name;
+                Session *session;
+                Seat *seat;
+
+                /* Same as ActivateSession() but refuses to work if
+                 * the seat doesn't match */
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &session_name,
+                                    DBUS_TYPE_STRING, &seat_name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                session = hashmap_get(m->sessions, session_name);
+                if (!session)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                seat = hashmap_get(m->seats, seat_name);
+                if (!seat)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                if (session->seat != seat)
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                r = session_activate(session);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSession") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "UnlockSession")) {
+                const char *name;
+                Session *session;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                session = hashmap_get(m->sessions, name);
+                if (!session)
+                        return bus_send_error_reply(connection, message, NULL, -ENOENT);
+
+                if (session_send_lock(session, streq(dbus_message_get_member(message), "LockSession")) < 0)
+                        goto oom;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSessions")) {
+                r = session_send_lock_all(m, true);
+                if (r < 0)
+                        bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillSession")) {
+                const char *swho;
+                int32_t signo;
+                KillWho who;
+                const char *name;
+                Session *session;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_STRING, &swho,
+                                    DBUS_TYPE_INT32, &signo,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(swho))
+                        who = KILL_ALL;
+                else {
+                        who = kill_who_from_string(swho);
+                        if (who < 0)
+                                return bus_send_error_reply(connection, message, &error, -EINVAL);
+                }
+
+                if (signo <= 0 || signo >= _NSIG)
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                session = hashmap_get(m->sessions, name);
+                if (!session)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                r = session_kill(session, who, signo);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillUser")) {
+                uint32_t uid;
+                User *user;
+                int32_t signo;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_UINT32, &uid,
+                                    DBUS_TYPE_INT32, &signo,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (signo <= 0 || signo >= _NSIG)
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
+                if (!user)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                r = user_kill(user, signo);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSession")) {
+                const char *name;
+                Session *session;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                session = hashmap_get(m->sessions, name);
+                if (!session)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                r = session_stop(session);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateUser")) {
+                uint32_t uid;
+                User *user;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_UINT32, &uid,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
+                if (!user)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                r = user_stop(user);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSeat")) {
+                const char *name;
+                Seat *seat;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                seat = hashmap_get(m->seats, name);
+                if (!seat)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                r = seat_stop_sessions(seat);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "SetUserLinger")) {
+                uint32_t uid;
+                struct passwd *pw;
+                dbus_bool_t b, interactive;
+                char *path;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_UINT32, &uid,
+                                    DBUS_TYPE_BOOLEAN, &b,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                errno = 0;
+                pw = getpwuid(uid);
+                if (!pw)
+                        return bus_send_error_reply(connection, message, NULL, errno ? -errno : -EINVAL);
+
+                r = verify_polkit(connection, message, "org.freedesktop.login1.set-user-linger", interactive, NULL, &error);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                mkdir_p_label("/var/lib/systemd", 0755);
+
+                r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                path = strappend("/var/lib/systemd/linger/", pw->pw_name);
+                if (!path)
+                        goto oom;
+
+                if (b) {
+                        User *u;
+
+                        r = touch(path);
+                        free(path);
+
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        if (manager_add_user_by_uid(m, uid, &u) >= 0)
+                                user_start(u);
+
+                } else {
+                        User *u;
+
+                        r = unlink(path);
+                        free(path);
+
+                        if (r < 0 && errno != ENOENT)
+                                return bus_send_error_reply(connection, message, &error, -errno);
+
+                        u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
+                        if (u)
+                                user_add_to_gc_queue(u);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "AttachDevice")) {
+                const char *sysfs, *seat;
+                dbus_bool_t interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &seat,
+                                    DBUS_TYPE_STRING, &sysfs,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (!path_startswith(sysfs, "/sys") || !seat_name_is_valid(seat))
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                r = verify_polkit(connection, message, "org.freedesktop.login1.attach-device", interactive, NULL, &error);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                r = attach_device(m, seat, sysfs);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "FlushDevices")) {
+                dbus_bool_t interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                r = verify_polkit(connection, message, "org.freedesktop.login1.flush-devices", interactive, NULL, &error);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                r = flush_devices(m);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "PowerOff")) {
+
+                r = bus_manager_do_shutdown_or_sleep(
+                                m, connection, message,
+                                SPECIAL_POWEROFF_TARGET,
+                                INHIBIT_SHUTDOWN,
+                                "org.freedesktop.login1.power-off",
+                                "org.freedesktop.login1.power-off-multiple-sessions",
+                                "org.freedesktop.login1.power-off-ignore-inhibit",
+                                NULL, NULL,
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Reboot")) {
+                r = bus_manager_do_shutdown_or_sleep(
+                                m, connection, message,
+                                SPECIAL_REBOOT_TARGET,
+                                INHIBIT_SHUTDOWN,
+                                "org.freedesktop.login1.reboot",
+                                "org.freedesktop.login1.reboot-multiple-sessions",
+                                "org.freedesktop.login1.reboot-ignore-inhibit",
+                                NULL, NULL,
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Suspend")) {
+                r = bus_manager_do_shutdown_or_sleep(
+                                m, connection, message,
+                                SPECIAL_SUSPEND_TARGET,
+                                INHIBIT_SLEEP,
+                                "org.freedesktop.login1.suspend",
+                                "org.freedesktop.login1.suspend-multiple-sessions",
+                                "org.freedesktop.login1.suspend-ignore-inhibit",
+                                "mem", NULL,
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Hibernate")) {
+                r = bus_manager_do_shutdown_or_sleep(
+                                m, connection, message,
+                                SPECIAL_HIBERNATE_TARGET,
+                                INHIBIT_SLEEP,
+                                "org.freedesktop.login1.hibernate",
+                                "org.freedesktop.login1.hibernate-multiple-sessions",
+                                "org.freedesktop.login1.hibernate-ignore-inhibit",
+                                "disk", NULL,
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "HybridSleep")) {
+                r = bus_manager_do_shutdown_or_sleep(
+                                m, connection, message,
+                                SPECIAL_HYBRID_SLEEP_TARGET,
+                                INHIBIT_SLEEP,
+                                "org.freedesktop.login1.hibernate",
+                                "org.freedesktop.login1.hibernate-multiple-sessions",
+                                "org.freedesktop.login1.hibernate-ignore-inhibit",
+                                "disk", "suspend",
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanPowerOff")) {
+
+                r = bus_manager_can_shutdown_or_sleep(
+                                m, connection, message,
+                                INHIBIT_SHUTDOWN,
+                                "org.freedesktop.login1.power-off",
+                                "org.freedesktop.login1.power-off-multiple-sessions",
+                                "org.freedesktop.login1.power-off-ignore-inhibit",
+                                NULL, NULL,
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanReboot")) {
+                r = bus_manager_can_shutdown_or_sleep(
+                                m, connection, message,
+                                INHIBIT_SHUTDOWN,
+                                "org.freedesktop.login1.reboot",
+                                "org.freedesktop.login1.reboot-multiple-sessions",
+                                "org.freedesktop.login1.reboot-ignore-inhibit",
+                                NULL, NULL,
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanSuspend")) {
+                r = bus_manager_can_shutdown_or_sleep(
+                                m, connection, message,
+                                INHIBIT_SLEEP,
+                                "org.freedesktop.login1.suspend",
+                                "org.freedesktop.login1.suspend-multiple-sessions",
+                                "org.freedesktop.login1.suspend-ignore-inhibit",
+                                "mem", NULL,
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanHibernate")) {
+                r = bus_manager_can_shutdown_or_sleep(
+                                m, connection, message,
+                                INHIBIT_SLEEP,
+                                "org.freedesktop.login1.hibernate",
+                                "org.freedesktop.login1.hibernate-multiple-sessions",
+                                "org.freedesktop.login1.hibernate-ignore-inhibit",
+                                "disk", NULL,
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanHybridSleep")) {
+                r = bus_manager_can_shutdown_or_sleep(
+                                m, connection, message,
+                                INHIBIT_SLEEP,
+                                "org.freedesktop.login1.hibernate",
+                                "org.freedesktop.login1.hibernate-multiple-sessions",
+                                "org.freedesktop.login1.hibernate-ignore-inhibit",
+                                "disk", "suspend",
+                                &error, &reply);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+                char *introspection = NULL;
+                FILE *f;
+                Iterator i;
+                Session *session;
+                Seat *seat;
+                User *user;
+                size_t size;
+                char *p;
+
+                if (!(reply = dbus_message_new_method_return(message)))
+                        goto oom;
+
+                /* We roll our own introspection code here, instead of
+                 * relying on bus_default_message_handler() because we
+                 * need to generate our introspection string
+                 * dynamically. */
+
+                if (!(f = open_memstream(&introspection, &size)))
+                        goto oom;
+
+                fputs(INTROSPECTION_BEGIN, f);
+
+                HASHMAP_FOREACH(seat, m->seats, i) {
+                        p = bus_path_escape(seat->id);
+
+                        if (p) {
+                                fprintf(f, "<node name=\"seat/%s\"/>", p);
+                                free(p);
+                        }
+                }
+
+                HASHMAP_FOREACH(user, m->users, i)
+                        fprintf(f, "<node name=\"user/%llu\"/>", (unsigned long long) user->uid);
+
+                HASHMAP_FOREACH(session, m->sessions, i) {
+                        p = bus_path_escape(session->id);
+
+                        if (p) {
+                                fprintf(f, "<node name=\"session/%s\"/>", p);
+                                free(p);
+                        }
+                }
+
+                fputs(INTROSPECTION_END, f);
+
+                if (ferror(f)) {
+                        fclose(f);
+                        free(introspection);
+                        goto oom;
+                }
+
+                fclose(f);
+
+                if (!introspection)
+                        goto oom;
+
+                if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
+                        free(introspection);
+                        goto oom;
+                }
+
+                free(introspection);
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.login1.Manager", bus_login_manager_properties, m },
+                        { NULL, }
+                };
+                return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps);
+        }
+
+        if (reply) {
+                if (!bus_maybe_send_reply(connection, message, reply))
+                                goto oom;
+
+                dbus_message_unref(reply);
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+const DBusObjectPathVTable bus_manager_vtable = {
+        .message_function = manager_message_handler
+};
+
+DBusHandlerResult bus_message_filter(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+        Manager *m = userdata;
+        DBusError error;
+
+        assert(m);
+        assert(connection);
+        assert(message);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
+                const char *cgroup;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_STRING, &cgroup,
+                                           DBUS_TYPE_INVALID))
+                        log_error("Failed to parse Released message: %s", bus_error_message(&error));
+                else
+                        manager_cgroup_notify_empty(m, cgroup);
+        }
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+int manager_send_changed(Manager *manager, const char *properties) {
+        DBusMessage *m;
+        int r = -ENOMEM;
+
+        assert(manager);
+
+        m = bus_properties_changed_new("/org/freedesktop/login1", "org.freedesktop.login1.Manager", properties);
+        if (!m)
+                goto finish;
+
+        if (!dbus_connection_send(manager->bus, m, NULL))
+                goto finish;
+
+        r = 0;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        return r;
+}
+
+int manager_dispatch_delayed(Manager *manager) {
+        const char *unit_name;
+        DBusError error;
+        bool delayed;
+        int r;
+
+        assert(manager);
+
+        if (!manager->delayed_unit)
+                return 0;
+
+        /* Continue delay? */
+        delayed =
+                manager->delayed_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC) &&
+                manager_is_inhibited(manager, manager->delayed_what, INHIBIT_DELAY, NULL, false, false, 0);
+        if (delayed)
+                return 0;
+
+        bus_manager_log_shutdown(manager, manager->delayed_what, manager->delayed_unit);
+
+        /* Reset delay data */
+        unit_name = manager->delayed_unit;
+        manager->delayed_unit = NULL;
+
+        /* Actually do the shutdown */
+        dbus_error_init(&error);
+        r = send_start_unit(manager->bus, unit_name, &error);
+        if (r < 0) {
+                log_warning("Failed to send delayed message: %s", bus_error_message_or_strerror(&error, -r));
+                dbus_error_free(&error);
+                return r;
+        }
+
+        /* Tell people about it */
+        send_prepare_for(manager, manager->delayed_what, false);
+
+        return 1;
+}
diff --git a/src/login/logind-device.c b/src/login/logind-device.c
new file mode 100644 (file)
index 0000000..51b1535
--- /dev/null
@@ -0,0 +1,96 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+
+#include "logind-device.h"
+#include "util.h"
+
+Device* device_new(Manager *m, const char *sysfs) {
+        Device *d;
+
+        assert(m);
+        assert(sysfs);
+
+        d = new0(Device, 1);
+        if (!d)
+                return NULL;
+
+        d->sysfs = strdup(sysfs);
+        if (!d->sysfs) {
+                free(d);
+                return NULL;
+        }
+
+        if (hashmap_put(m->devices, d->sysfs, d) < 0) {
+                free(d->sysfs);
+                free(d);
+                return NULL;
+        }
+
+        d->manager = m;
+        dual_timestamp_get(&d->timestamp);
+
+        return d;
+}
+
+void device_free(Device *d) {
+        assert(d);
+
+        device_detach(d);
+
+        hashmap_remove(d->manager->devices, d->sysfs);
+
+        free(d->sysfs);
+        free(d);
+}
+
+void device_detach(Device *d) {
+        Seat *s;
+        assert(d);
+
+        if (!d->seat)
+                return;
+
+        s = d->seat;
+        LIST_REMOVE(Device, devices, d->seat->devices, d);
+        d->seat = NULL;
+
+        seat_add_to_gc_queue(s);
+        seat_send_changed(s, "CanGraphical\0");
+}
+
+void device_attach(Device *d, Seat *s) {
+        assert(d);
+        assert(s);
+
+        if (d->seat == s)
+                return;
+
+        if (d->seat)
+                device_detach(d);
+
+        d->seat = s;
+        LIST_PREPEND(Device, devices, s->devices, d);
+
+        seat_send_changed(s, "CanGraphical\0");
+}
diff --git a/src/login/logind-device.h b/src/login/logind-device.h
new file mode 100644 (file)
index 0000000..3b15356
--- /dev/null
@@ -0,0 +1,45 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Device Device;
+
+#include "list.h"
+#include "util.h"
+#include "logind.h"
+#include "logind-seat.h"
+
+struct Device {
+        Manager *manager;
+
+        char *sysfs;
+        Seat *seat;
+
+        dual_timestamp timestamp;
+
+        LIST_FIELDS(struct Device, devices);
+};
+
+Device* device_new(Manager *m, const char *sysfs);
+void device_free(Device *d);
+void device_attach(Device *d, Seat *s);
+void device_detach(Device *d);
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
new file mode 100644 (file)
index 0000000..076d116
--- /dev/null
@@ -0,0 +1,34 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "logind.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name logind_gperf_hash
+%define lookup-function-name logind_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+Login.NAutoVTs,                    config_parse_unsigned,      0, offsetof(Manager, n_autovts)
+Login.ReserveVT,                   config_parse_unsigned,      0, offsetof(Manager, reserve_vt)
+Login.KillUserProcesses,           config_parse_bool,          0, offsetof(Manager, kill_user_processes)
+Login.KillOnlyUsers,               config_parse_strv,          0, offsetof(Manager, kill_only_users)
+Login.KillExcludeUsers,            config_parse_strv,          0, offsetof(Manager, kill_exclude_users)
+Login.Controllers,                 config_parse_strv,          0, offsetof(Manager, controllers)
+Login.ResetControllers,            config_parse_strv,          0, offsetof(Manager, reset_controllers)
+Login.InhibitDelayMaxSec,          config_parse_usec,          0, offsetof(Manager, inhibit_delay_max)
+Login.HandlePowerKey,              config_parse_handle_action, 0, offsetof(Manager, handle_power_key)
+Login.HandleSuspendKey,            config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key)
+Login.HandleHibernateKey,          config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key)
+Login.HandleLidSwitch,             config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch)
+Login.PowerKeyIgnoreInhibited,     config_parse_bool,          0, offsetof(Manager, power_key_ignore_inhibited)
+Login.SuspendKeyIgnoreInhibited,   config_parse_bool,          0, offsetof(Manager, suspend_key_ignore_inhibited)
+Login.HibernateKeyIgnoreInhibited, config_parse_bool,          0, offsetof(Manager, hibernate_key_ignore_inhibited)
+Login.LidSwitchIgnoreInhibited,    config_parse_bool,          0, offsetof(Manager, lid_switch_ignore_inhibited)
+Login.IdleAction,                  config_parse_handle_action, 0, offsetof(Manager, idle_action)
+Login.IdleActionSec,               config_parse_usec,          0, offsetof(Manager, idle_action_usec)
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
new file mode 100644 (file)
index 0000000..f1b9cca
--- /dev/null
@@ -0,0 +1,468 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "logind-inhibit.h"
+
+Inhibitor* inhibitor_new(Manager *m, const char* id) {
+        Inhibitor *i;
+
+        assert(m);
+
+        i = new0(Inhibitor, 1);
+        if (!i)
+                return NULL;
+
+        i->state_file = strappend("/run/systemd/inhibit/", id);
+        if (!i->state_file) {
+                free(i);
+                return NULL;
+        }
+
+        i->id = path_get_file_name(i->state_file);
+
+        if (hashmap_put(m->inhibitors, i->id, i) < 0) {
+                free(i->state_file);
+                free(i);
+                return NULL;
+        }
+
+        i->manager = m;
+        i->fifo_fd = -1;
+
+        return i;
+}
+
+void inhibitor_free(Inhibitor *i) {
+        assert(i);
+
+        free(i->who);
+        free(i->why);
+
+        hashmap_remove(i->manager->inhibitors, i->id);
+        inhibitor_remove_fifo(i);
+
+        if (i->state_file) {
+                unlink(i->state_file);
+                free(i->state_file);
+        }
+
+        free(i);
+}
+
+int inhibitor_save(Inhibitor *i) {
+        char *temp_path, *cc;
+        int r;
+        FILE *f;
+
+        assert(i);
+
+        r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0);
+        if (r < 0)
+                goto finish;
+
+        r = fopen_temporary(i->state_file, &f, &temp_path);
+        if (r < 0)
+                goto finish;
+
+        fchmod(fileno(f), 0644);
+
+        fprintf(f,
+                "# This is private data. Do not parse.\n"
+                "WHAT=%s\n"
+                "MODE=%s\n"
+                "UID=%lu\n"
+                "PID=%lu\n",
+                inhibit_what_to_string(i->what),
+                inhibit_mode_to_string(i->mode),
+                (unsigned long) i->uid,
+                (unsigned long) i->pid);
+
+        if (i->who) {
+                cc = cescape(i->who);
+                if (!cc)
+                        r = -ENOMEM;
+                else {
+                        fprintf(f, "WHO=%s\n", cc);
+                        free(cc);
+                }
+        }
+
+        if (i->why) {
+                cc = cescape(i->why);
+                if (!cc)
+                        r = -ENOMEM;
+                else {
+                        fprintf(f, "WHY=%s\n", cc);
+                        free(cc);
+                }
+        }
+
+        if (i->fifo_path)
+                fprintf(f, "FIFO=%s\n", i->fifo_path);
+
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, i->state_file) < 0) {
+                r = -errno;
+                unlink(i->state_file);
+                unlink(temp_path);
+        }
+
+        fclose(f);
+        free(temp_path);
+
+finish:
+        if (r < 0)
+                log_error("Failed to save inhibit data for %s: %s", i->id, strerror(-r));
+
+        return r;
+}
+
+int inhibitor_start(Inhibitor *i) {
+        assert(i);
+
+        if (i->started)
+                return 0;
+
+        dual_timestamp_get(&i->since);
+
+        log_debug("Inhibitor %s (%s) pid=%lu uid=%lu mode=%s started.",
+                  strna(i->who), strna(i->why),
+                  (unsigned long) i->pid, (unsigned long) i->uid,
+                  inhibit_mode_to_string(i->mode));
+
+        inhibitor_save(i);
+
+        i->started = true;
+
+        manager_send_changed(i->manager, i->mode == INHIBIT_BLOCK ? "BlockInhibited\0" : "DelayInhibited\0");
+
+        return 0;
+}
+
+int inhibitor_stop(Inhibitor *i) {
+        assert(i);
+
+        if (i->started)
+                log_debug("Inhibitor %s (%s) pid=%lu uid=%lu mode=%s stopped.",
+                          strna(i->who), strna(i->why),
+                          (unsigned long) i->pid, (unsigned long) i->uid,
+                          inhibit_mode_to_string(i->mode));
+
+        if (i->state_file)
+                unlink(i->state_file);
+
+        i->started = false;
+
+        manager_send_changed(i->manager, i->mode == INHIBIT_BLOCK ? "BlockInhibited\0" : "DelayInhibited\0");
+
+        return 0;
+}
+
+int inhibitor_load(Inhibitor *i) {
+        InhibitWhat w;
+        InhibitMode mm;
+        int r;
+        char *cc,
+                *what = NULL,
+                *uid = NULL,
+                *pid = NULL,
+                *who = NULL,
+                *why = NULL,
+                *mode = NULL;
+
+        r = parse_env_file(i->state_file, NEWLINE,
+                           "WHAT", &what,
+                           "UID", &uid,
+                           "PID", &pid,
+                           "WHO", &who,
+                           "WHY", &why,
+                           "MODE", &mode,
+                           "FIFO", &i->fifo_path,
+                           NULL);
+        if (r < 0)
+                goto finish;
+
+        w = what ? inhibit_what_from_string(what) : 0;
+        if (w >= 0)
+                i->what = w;
+
+        mm = mode ? inhibit_mode_from_string(mode) : INHIBIT_BLOCK;
+        if  (mm >= 0)
+                i->mode = mm;
+
+        if (uid) {
+                r = parse_uid(uid, &i->uid);
+                if (r < 0)
+                        goto finish;
+        }
+
+        if (pid) {
+                r = parse_pid(pid, &i->pid);
+                if (r < 0)
+                        goto finish;
+        }
+
+        if (who) {
+                cc = cunescape(who);
+                if (!cc) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                free(i->who);
+                i->who = cc;
+        }
+
+        if (why) {
+                cc = cunescape(why);
+                if (!cc) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                free(i->why);
+                i->why = cc;
+        }
+
+        if (i->fifo_path) {
+                int fd;
+
+                fd = inhibitor_create_fifo(i);
+                if (fd >= 0)
+                        close_nointr_nofail(fd);
+        }
+
+finish:
+        free(what);
+        free(uid);
+        free(pid);
+        free(who);
+        free(why);
+
+        return r;
+}
+
+int inhibitor_create_fifo(Inhibitor *i) {
+        int r;
+
+        assert(i);
+
+        /* Create FIFO */
+        if (!i->fifo_path) {
+                r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0);
+                if (r < 0)
+                        return r;
+
+                if (asprintf(&i->fifo_path, "/run/systemd/inhibit/%s.ref", i->id) < 0)
+                        return -ENOMEM;
+
+                if (mkfifo(i->fifo_path, 0600) < 0 && errno != EEXIST)
+                        return -errno;
+        }
+
+        /* Open reading side */
+        if (i->fifo_fd < 0) {
+                struct epoll_event ev;
+
+                i->fifo_fd = open(i->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY);
+                if (i->fifo_fd < 0)
+                        return -errno;
+
+                r = hashmap_put(i->manager->inhibitor_fds, INT_TO_PTR(i->fifo_fd + 1), i);
+                if (r < 0)
+                        return r;
+
+                zero(ev);
+                ev.events = 0;
+                ev.data.u32 = FD_OTHER_BASE + i->fifo_fd;
+
+                if (epoll_ctl(i->manager->epoll_fd, EPOLL_CTL_ADD, i->fifo_fd, &ev) < 0)
+                        return -errno;
+        }
+
+        /* Open writing side */
+        r = open(i->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY);
+        if (r < 0)
+                return -errno;
+
+        return r;
+}
+
+void inhibitor_remove_fifo(Inhibitor *i) {
+        assert(i);
+
+        if (i->fifo_fd >= 0) {
+                assert_se(hashmap_remove(i->manager->inhibitor_fds, INT_TO_PTR(i->fifo_fd + 1)) == i);
+                assert_se(epoll_ctl(i->manager->epoll_fd, EPOLL_CTL_DEL, i->fifo_fd, NULL) == 0);
+                close_nointr_nofail(i->fifo_fd);
+                i->fifo_fd = -1;
+        }
+
+        if (i->fifo_path) {
+                unlink(i->fifo_path);
+                free(i->fifo_path);
+                i->fifo_path = NULL;
+        }
+}
+
+InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
+        Inhibitor *i;
+        Iterator j;
+        InhibitWhat what = 0;
+
+        assert(m);
+
+        HASHMAP_FOREACH(i, m->inhibitor_fds, j)
+                if (i->mode == mm)
+                        what |= i->what;
+
+        return what;
+}
+
+static int pid_is_active(Manager *m, pid_t pid) {
+        Session *s;
+        int r;
+
+        r = manager_get_session_by_pid(m, pid, &s);
+        if (r <= 0)
+                return r;
+
+        return session_is_active(s);
+}
+
+bool manager_is_inhibited(
+                Manager *m,
+                InhibitWhat w,
+                InhibitMode mm,
+                dual_timestamp *since,
+                bool ignore_inactive,
+                bool ignore_uid,
+                uid_t uid) {
+
+        Inhibitor *i;
+        Iterator j;
+        struct dual_timestamp ts = { 0, 0 };
+        bool inhibited = false;
+
+        assert(m);
+        assert(w > 0 && w < _INHIBIT_WHAT_MAX);
+
+        HASHMAP_FOREACH(i, m->inhibitor_fds, j) {
+                if (!(i->what & w))
+                        continue;
+
+                if (i->mode != mm)
+                        continue;
+
+                if (ignore_inactive && pid_is_active(m, i->pid) <= 0)
+                        continue;
+
+                if (ignore_uid && i->uid == uid)
+                        continue;
+
+                if (!inhibited ||
+                    i->since.monotonic < ts.monotonic)
+                        ts = i->since;
+
+                inhibited = true;
+        }
+
+        if (since)
+                *since = ts;
+
+        return inhibited;
+}
+
+const char *inhibit_what_to_string(InhibitWhat w) {
+        static __thread char buffer[97];
+        char *p;
+
+        if (w < 0 || w >= _INHIBIT_WHAT_MAX)
+                return NULL;
+
+        p = buffer;
+        if (w & INHIBIT_SHUTDOWN)
+                p = stpcpy(p, "shutdown:");
+        if (w & INHIBIT_SLEEP)
+                p = stpcpy(p, "sleep:");
+        if (w & INHIBIT_IDLE)
+                p = stpcpy(p, "idle:");
+        if (w & INHIBIT_HANDLE_POWER_KEY)
+                p = stpcpy(p, "handle-power-key:");
+        if (w & INHIBIT_HANDLE_SUSPEND_KEY)
+                p = stpcpy(p, "handle-suspend-key:");
+        if (w & INHIBIT_HANDLE_HIBERNATE_KEY)
+                p = stpcpy(p, "handle-hibernate-key:");
+        if (w & INHIBIT_HANDLE_LID_SWITCH)
+                p = stpcpy(p, "handle-lid-switch:");
+
+        if (p > buffer)
+                *(p-1) = 0;
+        else
+                *p = 0;
+
+        return buffer;
+}
+
+InhibitWhat inhibit_what_from_string(const char *s) {
+        InhibitWhat what = 0;
+        char *w, *state;
+        size_t l;
+
+        FOREACH_WORD_SEPARATOR(w, l, s, ":", state) {
+                if (l == 8 && strncmp(w, "shutdown", l) == 0)
+                        what |= INHIBIT_SHUTDOWN;
+                else if (l == 5 && strncmp(w, "sleep", l) == 0)
+                        what |= INHIBIT_SLEEP;
+                else if (l == 4 && strncmp(w, "idle", l) == 0)
+                        what |= INHIBIT_IDLE;
+                else if (l == 16 && strncmp(w, "handle-power-key", l) == 0)
+                        what |= INHIBIT_HANDLE_POWER_KEY;
+                else if (l == 18 && strncmp(w, "handle-suspend-key", l) == 0)
+                        what |= INHIBIT_HANDLE_SUSPEND_KEY;
+                else if (l == 20 && strncmp(w, "handle-hibernate-key", l) == 0)
+                        what |= INHIBIT_HANDLE_HIBERNATE_KEY;
+                else if (l == 17 && strncmp(w, "handle-lid-switch", l) == 0)
+                        what |= INHIBIT_HANDLE_LID_SWITCH;
+                else
+                        return _INHIBIT_WHAT_INVALID;
+        }
+
+        return what;
+}
+
+static const char* const inhibit_mode_table[_INHIBIT_MODE_MAX] = {
+        [INHIBIT_BLOCK] = "block",
+        [INHIBIT_DELAY] = "delay"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(inhibit_mode, InhibitMode);
diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h
new file mode 100644 (file)
index 0000000..4c158ee
--- /dev/null
@@ -0,0 +1,95 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foologindinhibithfoo
+#define foologindinhibithfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Inhibitor Inhibitor;
+
+#include "list.h"
+#include "util.h"
+
+typedef enum InhibitWhat {
+        INHIBIT_SHUTDOWN = 1,
+        INHIBIT_SLEEP = 2,
+        INHIBIT_IDLE = 4,
+        INHIBIT_HANDLE_POWER_KEY = 8,
+        INHIBIT_HANDLE_SUSPEND_KEY = 16,
+        INHIBIT_HANDLE_HIBERNATE_KEY = 32,
+        INHIBIT_HANDLE_LID_SWITCH = 64,
+        _INHIBIT_WHAT_MAX = 128,
+        _INHIBIT_WHAT_INVALID = -1
+} InhibitWhat;
+
+typedef enum InhibitMode {
+        INHIBIT_BLOCK,
+        INHIBIT_DELAY,
+        _INHIBIT_MODE_MAX,
+        _INHIBIT_MODE_INVALID = -1
+} InhibitMode;
+
+#include "logind.h"
+#include "logind-seat.h"
+
+struct Inhibitor {
+        Manager *manager;
+
+        char *id;
+        char *state_file;
+
+        bool started;
+
+        InhibitWhat what;
+        char *who;
+        char *why;
+        InhibitMode mode;
+
+        pid_t pid;
+        uid_t uid;
+
+        dual_timestamp since;
+
+        char *fifo_path;
+        int fifo_fd;
+};
+
+Inhibitor* inhibitor_new(Manager *m, const char *id);
+void inhibitor_free(Inhibitor *i);
+
+int inhibitor_save(Inhibitor *i);
+int inhibitor_load(Inhibitor *i);
+
+int inhibitor_start(Inhibitor *i);
+int inhibitor_stop(Inhibitor *i);
+
+int inhibitor_create_fifo(Inhibitor *i);
+void inhibitor_remove_fifo(Inhibitor *i);
+
+InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm);
+bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid);
+
+const char *inhibit_what_to_string(InhibitWhat k);
+InhibitWhat inhibit_what_from_string(const char *s);
+
+const char *inhibit_mode_to_string(InhibitMode k);
+InhibitMode inhibit_mode_from_string(const char *s);
+
+#endif
diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c
new file mode 100644 (file)
index 0000000..7833d70
--- /dev/null
@@ -0,0 +1,444 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+
+#include "logind.h"
+#include "logind-seat.h"
+#include "dbus-common.h"
+#include "util.h"
+
+#define BUS_SEAT_INTERFACE \
+        " <interface name=\"org.freedesktop.login1.Seat\">\n"           \
+        "  <method name=\"Terminate\"/>\n"                              \
+        "  <method name=\"ActivateSession\">\n"                         \
+        "   <arg name=\"id\" type=\"s\"/>\n"                            \
+        "  </method>\n"                                                 \
+        "  <property name=\"Id\" type=\"s\" access=\"read\"/>\n"        \
+        "  <property name=\"ActiveSession\" type=\"so\" access=\"read\"/>\n" \
+        "  <property name=\"CanMultiSession\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"CanTTY\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"CanGraphical\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"Sessions\" type=\"a(so)\" access=\"read\"/>\n" \
+        "  <property name=\"IdleHint\" type=\"b\" access=\"read\"/>\n"  \
+        "  <property name=\"IdleSinceHint\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"IdleSinceHintMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        " </interface>\n"                                               \
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_SEAT_INTERFACE                                              \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_GENERIC_INTERFACES_LIST                  \
+        "org.freedesktop.login1.Seat\0"
+
+static int bus_seat_append_active(DBusMessageIter *i, const char *property, void *data) {
+        DBusMessageIter sub;
+        Seat *s = data;
+        const char *id, *path;
+        char *p = NULL;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
+                return -ENOMEM;
+
+        if (s->active) {
+                id = s->active->id;
+                path = p = session_bus_path(s->active);
+
+                if (!p)
+                        return -ENOMEM;
+        } else {
+                id = "";
+                path = "/";
+        }
+
+        if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) {
+                free(p);
+                return -ENOMEM;
+        }
+
+        free(p);
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_seat_append_sessions(DBusMessageIter *i, const char *property, void *data) {
+        DBusMessageIter sub, sub2;
+        Seat *s = data;
+        Session *session;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(so)", &sub))
+                return -ENOMEM;
+
+        LIST_FOREACH(sessions_by_seat, session, s->sessions) {
+                char *p;
+
+                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
+                        return -ENOMEM;
+
+                p = session_bus_path(session);
+                if (!p)
+                        return -ENOMEM;
+
+                if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) {
+                        free(p);
+                        return -ENOMEM;
+                }
+
+                free(p);
+
+                if (!dbus_message_iter_close_container(&sub, &sub2))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_seat_append_can_multi_session(DBusMessageIter *i, const char *property, void *data) {
+        Seat *s = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        b = seat_can_multi_session(s);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_seat_append_can_tty(DBusMessageIter *i, const char *property, void *data) {
+        Seat *s = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        b = seat_can_tty(s);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_seat_append_can_graphical(DBusMessageIter *i, const char *property, void *data) {
+        Seat *s = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        b = seat_can_graphical(s);
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_seat_append_idle_hint(DBusMessageIter *i, const char *property, void *data) {
+        Seat *s = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        b = seat_get_idle_hint(s, NULL) > 0;
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_seat_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) {
+        Seat *s = data;
+        dual_timestamp t;
+        uint64_t k;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        seat_get_idle_hint(s, &t);
+        k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &k))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int get_seat_for_path(Manager *m, const char *path, Seat **_s) {
+        Seat *s;
+        char *id;
+
+        assert(m);
+        assert(path);
+        assert(_s);
+
+        if (!startswith(path, "/org/freedesktop/login1/seat/"))
+                return -EINVAL;
+
+        id = bus_path_unescape(path + 29);
+        if (!id)
+                return -ENOMEM;
+
+        s = hashmap_get(m->seats, id);
+        free(id);
+
+        if (!s)
+                return -ENOENT;
+
+        *_s = s;
+        return 0;
+}
+
+static const BusProperty bus_login_seat_properties[] = {
+        { "Id",                     bus_property_append_string,      "s", offsetof(Seat, id), true },
+        { "ActiveSession",          bus_seat_append_active,       "(so)", 0 },
+        { "CanMultiSession",        bus_seat_append_can_multi_session, "b", 0 },
+        { "CanTTY",                 bus_seat_append_can_tty,         "b", 0 },
+        { "CanGraphical",           bus_seat_append_can_graphical,   "b", 0 },
+        { "Sessions",               bus_seat_append_sessions,    "a(so)", 0 },
+        { "IdleHint",               bus_seat_append_idle_hint,       "b", 0 },
+        { "IdleSinceHint",          bus_seat_append_idle_hint_since, "t", 0 },
+        { "IdleSinceHintMonotonic", bus_seat_append_idle_hint_since, "t", 0 },
+        { NULL, }
+};
+
+static DBusHandlerResult seat_message_dispatch(
+                Seat *s,
+                DBusConnection *connection,
+                DBusMessage *message) {
+
+        DBusError error;
+        DBusMessage *reply = NULL;
+        int r;
+
+        assert(s);
+        assert(connection);
+        assert(message);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "Terminate")) {
+
+                r = seat_stop_sessions(s);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "ActivateSession")) {
+                const char *name;
+                Session *session;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                session = hashmap_get(s->manager->sessions, name);
+                if (!session || session->seat != s)
+                        return bus_send_error_reply(connection, message, &error, -ENOENT);
+
+                r = session_activate(session);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.login1.Seat", bus_login_seat_properties, s },
+                        { NULL, }
+                };
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
+
+        if (reply) {
+                if (!dbus_connection_send(connection, reply, NULL))
+                        goto oom;
+
+                dbus_message_unref(reply);
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static DBusHandlerResult seat_message_handler(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+        Manager *m = userdata;
+        Seat *s;
+        int r;
+
+        r = get_seat_for_path(m, dbus_message_get_path(message), &s);
+        if (r < 0) {
+
+                if (r == -ENOMEM)
+                        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+                if (r == -ENOENT) {
+                        DBusError e;
+
+                        dbus_error_init(&e);
+                        dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown seat");
+                        return bus_send_error_reply(connection, message, &e, r);
+                }
+
+                return bus_send_error_reply(connection, message, NULL, r);
+        }
+
+        return seat_message_dispatch(s, connection, message);
+}
+
+const DBusObjectPathVTable bus_seat_vtable = {
+        .message_function = seat_message_handler
+};
+
+char *seat_bus_path(Seat *s) {
+        char *t, *r;
+
+        assert(s);
+
+        t = bus_path_escape(s->id);
+        if (!t)
+                return NULL;
+
+        r = strappend("/org/freedesktop/login1/seat/", t);
+        free(t);
+
+        return r;
+}
+
+int seat_send_signal(Seat *s, bool new_seat) {
+        DBusMessage *m;
+        int r = -ENOMEM;
+        char *p = NULL;
+
+        assert(s);
+
+        m = dbus_message_new_signal("/org/freedesktop/login1",
+                                    "org.freedesktop.login1.Manager",
+                                    new_seat ? "SeatNew" : "SeatRemoved");
+
+        if (!m)
+                return -ENOMEM;
+
+        p = seat_bus_path(s);
+        if (!p)
+                goto finish;
+
+        if (!dbus_message_append_args(
+                            m,
+                            DBUS_TYPE_STRING, &s->id,
+                            DBUS_TYPE_OBJECT_PATH, &p,
+                            DBUS_TYPE_INVALID))
+                goto finish;
+
+        if (!dbus_connection_send(s->manager->bus, m, NULL))
+                goto finish;
+
+        r = 0;
+
+finish:
+        dbus_message_unref(m);
+        free(p);
+
+        return r;
+}
+
+int seat_send_changed(Seat *s, const char *properties) {
+        DBusMessage *m;
+        int r = -ENOMEM;
+        char *p = NULL;
+
+        assert(s);
+
+        if (!s->started)
+                return 0;
+
+        p = seat_bus_path(s);
+        if (!p)
+                return -ENOMEM;
+
+        m = bus_properties_changed_new(p, "org.freedesktop.login1.Seat", properties);
+        if (!m)
+                goto finish;
+
+        if (!dbus_connection_send(s->manager->bus, m, NULL))
+                goto finish;
+
+        r = 0;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+        free(p);
+
+        return r;
+}
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
new file mode 100644 (file)
index 0000000..470d08b
--- /dev/null
@@ -0,0 +1,543 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/vt.h>
+#include <string.h>
+
+#include "systemd/sd-id128.h"
+#include "systemd/sd-messages.h"
+#include "logind-seat.h"
+#include "logind-acl.h"
+#include "util.h"
+#include "mkdir.h"
+#include "path-util.h"
+
+Seat *seat_new(Manager *m, const char *id) {
+        Seat *s;
+
+        assert(m);
+        assert(id);
+
+        s = new0(Seat, 1);
+        if (!s)
+                return NULL;
+
+        s->state_file = strappend("/run/systemd/seats/", id);
+        if (!s->state_file) {
+                free(s);
+                return NULL;
+        }
+
+        s->id = path_get_file_name(s->state_file);
+        s->manager = m;
+
+        if (hashmap_put(m->seats, s->id, s) < 0) {
+                free(s->state_file);
+                free(s);
+                return NULL;
+        }
+
+        return s;
+}
+
+void seat_free(Seat *s) {
+        assert(s);
+
+        if (s->in_gc_queue)
+                LIST_REMOVE(Seat, gc_queue, s->manager->seat_gc_queue, s);
+
+        while (s->sessions)
+                session_free(s->sessions);
+
+        assert(!s->active);
+
+        while (s->devices)
+                device_free(s->devices);
+
+        hashmap_remove(s->manager->seats, s->id);
+
+        free(s->state_file);
+        free(s);
+}
+
+int seat_save(Seat *s) {
+        int r;
+        FILE *f;
+        char *temp_path;
+
+        assert(s);
+
+        if (!s->started)
+                return 0;
+
+        r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0);
+        if (r < 0)
+                goto finish;
+
+        r = fopen_temporary(s->state_file, &f, &temp_path);
+        if (r < 0)
+                goto finish;
+
+        fchmod(fileno(f), 0644);
+
+        fprintf(f,
+                "# This is private data. Do not parse.\n"
+                "IS_VTCONSOLE=%i\n"
+                "CAN_MULTI_SESSION=%i\n"
+                "CAN_TTY=%i\n"
+                "CAN_GRAPHICAL=%i\n",
+                seat_is_vtconsole(s),
+                seat_can_multi_session(s),
+                seat_can_tty(s),
+                seat_can_graphical(s));
+
+        if (s->active) {
+                assert(s->active->user);
+
+                fprintf(f,
+                        "ACTIVE=%s\n"
+                        "ACTIVE_UID=%lu\n",
+                        s->active->id,
+                        (unsigned long) s->active->user->uid);
+        }
+
+        if (s->sessions) {
+                Session *i;
+
+                fputs("SESSIONS=", f);
+                LIST_FOREACH(sessions_by_seat, i, s->sessions) {
+                        fprintf(f,
+                                "%s%c",
+                                i->id,
+                                i->sessions_by_seat_next ? ' ' : '\n');
+                }
+
+                fputs("UIDS=", f);
+                LIST_FOREACH(sessions_by_seat, i, s->sessions)
+                        fprintf(f,
+                                "%lu%c",
+                                (unsigned long) i->user->uid,
+                                i->sessions_by_seat_next ? ' ' : '\n');
+        }
+
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, s->state_file) < 0) {
+                r = -errno;
+                unlink(s->state_file);
+                unlink(temp_path);
+        }
+
+        fclose(f);
+        free(temp_path);
+
+finish:
+        if (r < 0)
+                log_error("Failed to save seat data for %s: %s", s->id, strerror(-r));
+
+        return r;
+}
+
+int seat_load(Seat *s) {
+        assert(s);
+
+        /* There isn't actually anything to read here ... */
+
+        return 0;
+}
+
+static int vt_allocate(int vtnr) {
+        int fd, r;
+        char *p;
+
+        assert(vtnr >= 1);
+
+        if (asprintf(&p, "/dev/tty%i", vtnr) < 0)
+                return -ENOMEM;
+
+        fd = open_terminal(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
+        free(p);
+
+        r = fd < 0 ? -errno : 0;
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
+
+int seat_preallocate_vts(Seat *s) {
+        int r = 0;
+        unsigned i;
+
+        assert(s);
+        assert(s->manager);
+
+        log_debug("Preallocating VTs...");
+
+        if (s->manager->n_autovts <= 0)
+                return 0;
+
+        if (!seat_can_multi_session(s))
+                return 0;
+
+        for (i = 1; i <= s->manager->n_autovts; i++) {
+                int q;
+
+                q = vt_allocate(i);
+                if (q < 0) {
+                        log_error("Failed to preallocate VT %i: %s", i, strerror(-q));
+                        r = q;
+                }
+        }
+
+        return r;
+}
+
+int seat_apply_acls(Seat *s, Session *old_active) {
+        int r;
+
+        assert(s);
+
+        r = devnode_acl_all(s->manager->udev,
+                            s->id,
+                            false,
+                            !!old_active, old_active ? old_active->user->uid : 0,
+                            !!s->active, s->active ? s->active->user->uid : 0);
+
+        if (r < 0)
+                log_error("Failed to apply ACLs: %s", strerror(-r));
+
+        return r;
+}
+
+int seat_set_active(Seat *s, Session *session) {
+        Session *old_active;
+
+        assert(s);
+        assert(!session || session->seat == s);
+
+        if (session == s->active)
+                return 0;
+
+        old_active = s->active;
+        s->active = session;
+
+        seat_apply_acls(s, old_active);
+
+        if (session && session->started)
+                session_send_changed(session, "Active\0");
+
+        if (!session || session->started)
+                seat_send_changed(s, "ActiveSession\0");
+
+        seat_save(s);
+
+        if (session) {
+                session_save(session);
+                user_save(session->user);
+        }
+
+        if (old_active) {
+                session_save(old_active);
+                if (!session || session->user != old_active->user)
+                        user_save(old_active->user);
+        }
+
+        return 0;
+}
+
+int seat_active_vt_changed(Seat *s, int vtnr) {
+        Session *i, *new_active = NULL;
+        int r;
+
+        assert(s);
+        assert(vtnr >= 1);
+
+        if (!seat_can_multi_session(s))
+                return -EINVAL;
+
+        log_debug("VT changed to %i", vtnr);
+
+        LIST_FOREACH(sessions_by_seat, i, s->sessions)
+                if (i->vtnr == vtnr) {
+                        new_active = i;
+                        break;
+                }
+
+        r = seat_set_active(s, new_active);
+        manager_spawn_autovt(s->manager, vtnr);
+
+        return r;
+}
+
+int seat_read_active_vt(Seat *s) {
+        char t[64];
+        ssize_t k;
+        int r, vtnr;
+
+        assert(s);
+
+        if (!seat_can_multi_session(s))
+                return 0;
+
+        lseek(s->manager->console_active_fd, SEEK_SET, 0);
+
+        k = read(s->manager->console_active_fd, t, sizeof(t)-1);
+        if (k <= 0) {
+                log_error("Failed to read current console: %s", k < 0 ? strerror(-errno) : "EOF");
+                return k < 0 ? -errno : -EIO;
+        }
+
+        t[k] = 0;
+        truncate_nl(t);
+
+        if (!startswith(t, "tty")) {
+                log_error("Hm, /sys/class/tty/tty0/active is badly formatted.");
+                return -EIO;
+        }
+
+        r = safe_atoi(t+3, &vtnr);
+        if (r < 0) {
+                log_error("Failed to parse VT number %s", t+3);
+                return r;
+        }
+
+        if (vtnr <= 0) {
+                log_error("VT number invalid: %s", t+3);
+                return -EIO;
+        }
+
+        return seat_active_vt_changed(s, vtnr);
+}
+
+int seat_start(Seat *s) {
+        assert(s);
+
+        if (s->started)
+                return 0;
+
+        log_struct(LOG_INFO,
+                   MESSAGE_ID(SD_MESSAGE_SEAT_START),
+                   "SEAT_ID=%s", s->id,
+                   "MESSAGE=New seat %s.", s->id,
+                   NULL);
+
+        /* Initialize VT magic stuff */
+        seat_preallocate_vts(s);
+
+        /* Read current VT */
+        seat_read_active_vt(s);
+
+        s->started = true;
+
+        /* Save seat data */
+        seat_save(s);
+
+        seat_send_signal(s, true);
+
+        return 0;
+}
+
+int seat_stop(Seat *s) {
+        int r = 0;
+
+        assert(s);
+
+        if (s->started)
+                log_struct(LOG_INFO,
+                           MESSAGE_ID(SD_MESSAGE_SEAT_STOP),
+                           "SEAT_ID=%s", s->id,
+                           "MESSAGE=Removed seat %s.", s->id,
+                           NULL);
+
+        seat_stop_sessions(s);
+
+        unlink(s->state_file);
+        seat_add_to_gc_queue(s);
+
+        if (s->started)
+                seat_send_signal(s, false);
+
+        s->started = false;
+
+        return r;
+}
+
+int seat_stop_sessions(Seat *s) {
+        Session *session;
+        int r = 0, k;
+
+        assert(s);
+
+        LIST_FOREACH(sessions_by_seat, session, s->sessions) {
+                k = session_stop(session);
+                if (k < 0)
+                        r = k;
+        }
+
+        return r;
+}
+
+int seat_attach_session(Seat *s, Session *session) {
+        assert(s);
+        assert(session);
+        assert(!session->seat);
+
+        session->seat = s;
+        LIST_PREPEND(Session, sessions_by_seat, s->sessions, session);
+
+        seat_send_changed(s, "Sessions\0");
+
+        /* Note that even if a seat is not multi-session capable it
+         * still might have multiple sessions on it since old, dead
+         * sessions might continue to be tracked until all their
+         * processes are gone. The most recently added session
+         * (i.e. the first in s->sessions) is the one that matters. */
+
+        if (!seat_can_multi_session(s))
+                seat_set_active(s, session);
+
+        return 0;
+}
+
+bool seat_is_vtconsole(Seat *s) {
+        assert(s);
+
+        return s->manager->vtconsole == s;
+}
+
+bool seat_can_multi_session(Seat *s) {
+        assert(s);
+
+        if (!seat_is_vtconsole(s))
+                return false;
+
+        /* If we can't watch which VT is in the foreground, we don't
+         * support VT switching */
+
+        return s->manager->console_active_fd >= 0;
+}
+
+bool seat_can_tty(Seat *s) {
+        assert(s);
+
+        return seat_is_vtconsole(s);
+}
+
+bool seat_can_graphical(Seat *s) {
+        assert(s);
+
+        return !!s->devices;
+}
+
+int seat_get_idle_hint(Seat *s, dual_timestamp *t) {
+        Session *session;
+        bool idle_hint = true;
+        dual_timestamp ts = { 0, 0 };
+
+        assert(s);
+
+        LIST_FOREACH(sessions_by_seat, session, s->sessions) {
+                dual_timestamp k;
+                int ih;
+
+                ih = session_get_idle_hint(session, &k);
+                if (ih < 0)
+                        return ih;
+
+                if (!ih) {
+                        if (!idle_hint) {
+                                if (k.monotonic > ts.monotonic)
+                                        ts = k;
+                        } else {
+                                idle_hint = false;
+                                ts = k;
+                        }
+                } else if (idle_hint) {
+
+                        if (k.monotonic > ts.monotonic)
+                                ts = k;
+                }
+        }
+
+        if (t)
+                *t = ts;
+
+        return idle_hint;
+}
+
+int seat_check_gc(Seat *s, bool drop_not_started) {
+        assert(s);
+
+        if (drop_not_started && !s->started)
+                return 0;
+
+        if (seat_is_vtconsole(s))
+                return 1;
+
+        return !!s->devices;
+}
+
+void seat_add_to_gc_queue(Seat *s) {
+        assert(s);
+
+        if (s->in_gc_queue)
+                return;
+
+        LIST_PREPEND(Seat, gc_queue, s->manager->seat_gc_queue, s);
+        s->in_gc_queue = true;
+}
+
+static bool seat_name_valid_char(char c) {
+        return
+                (c >= 'a' && c <= 'z') ||
+                (c >= 'A' && c <= 'Z') ||
+                (c >= '0' && c <= '9') ||
+                c == '-' ||
+                c == '_';
+}
+
+bool seat_name_is_valid(const char *name) {
+        const char *p;
+
+        assert(name);
+
+        if (!startswith(name, "seat"))
+                return false;
+
+        if (!name[4])
+                return false;
+
+        for (p = name; *p; p++)
+                if (!seat_name_valid_char(*p))
+                        return false;
+
+        if (strlen(name) > 255)
+                return false;
+
+        return true;
+}
diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h
new file mode 100644 (file)
index 0000000..c8ab17f
--- /dev/null
@@ -0,0 +1,83 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Seat Seat;
+
+#include "list.h"
+#include "util.h"
+#include "logind.h"
+#include "logind-device.h"
+#include "logind-session.h"
+
+struct Seat {
+        Manager *manager;
+        char *id;
+
+        char *state_file;
+
+        LIST_HEAD(Device, devices);
+
+        Session *active;
+        LIST_HEAD(Session, sessions);
+
+        bool in_gc_queue:1;
+        bool started:1;
+
+        LIST_FIELDS(Seat, gc_queue);
+};
+
+Seat *seat_new(Manager *m, const char *id);
+void seat_free(Seat *s);
+
+int seat_save(Seat *s);
+int seat_load(Seat *s);
+
+int seat_apply_acls(Seat *s, Session *old_active);
+int seat_set_active(Seat *s, Session *session);
+int seat_active_vt_changed(Seat *s, int vtnr);
+int seat_read_active_vt(Seat *s);
+int seat_preallocate_vts(Seat *s);
+
+int seat_attach_session(Seat *s, Session *session);
+
+bool seat_is_vtconsole(Seat *s);
+bool seat_can_multi_session(Seat *s);
+bool seat_can_tty(Seat *s);
+bool seat_can_graphical(Seat *s);
+
+int seat_get_idle_hint(Seat *s, dual_timestamp *t);
+
+int seat_start(Seat *s);
+int seat_stop(Seat *s);
+int seat_stop_sessions(Seat *s);
+
+int seat_check_gc(Seat *s, bool drop_not_started);
+void seat_add_to_gc_queue(Seat *s);
+
+bool seat_name_is_valid(const char *name);
+char *seat_bus_path(Seat *s);
+
+extern const DBusObjectPathVTable bus_seat_vtable;
+
+int seat_send_signal(Seat *s, bool new_seat);
+int seat_send_changed(Seat *s, const char *properties);
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
new file mode 100644 (file)
index 0000000..ef73cd4
--- /dev/null
@@ -0,0 +1,590 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+
+#include "logind.h"
+#include "logind-session.h"
+#include "dbus-common.h"
+#include "util.h"
+
+#define BUS_SESSION_INTERFACE \
+        " <interface name=\"org.freedesktop.login1.Session\">\n"        \
+        "  <method name=\"Terminate\"/>\n"                              \
+        "  <method name=\"Activate\"/>\n"                               \
+        "  <method name=\"Lock\"/>\n"                                   \
+        "  <method name=\"Unlock\"/>\n"                                 \
+        "  <method name=\"SetIdleHint\">\n"                             \
+        "   <arg name=\"b\" type=\"b\"/>\n"                             \
+        "  </method>\n"                                                 \
+        "  <method name=\"Kill\">\n"                                    \
+        "   <arg name=\"who\" type=\"s\"/>\n"                           \
+        "   <arg name=\"signal\" type=\"s\"/>\n"                        \
+        "  </method>\n"                                                 \
+        "  <signal name=\"Lock\"/>\n"                                   \
+        "  <signal name=\"Unlock\"/>\n"                                 \
+        "  <property name=\"Id\" type=\"s\" access=\"read\"/>\n"        \
+        "  <property name=\"User\" type=\"(uo)\" access=\"read\"/>\n"   \
+        "  <property name=\"Name\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Timestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"TimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"DefaultControlGroup\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"VTNr\" type=\"u\" access=\"read\"/>\n"      \
+        "  <property name=\"Seat\" type=\"(so)\" access=\"read\"/>\n"   \
+        "  <property name=\"TTY\" type=\"s\" access=\"read\"/>\n"       \
+        "  <property name=\"Display\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"Remote\" type=\"b\" access=\"read\"/>\n"    \
+        "  <property name=\"RemoteHost\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"RemoteUser\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"Service\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"Leader\" type=\"u\" access=\"read\"/>\n"    \
+        "  <property name=\"Audit\" type=\"u\" access=\"read\"/>\n"     \
+        "  <property name=\"Type\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Class\" type=\"s\" access=\"read\"/>\n"     \
+        "  <property name=\"Active\" type=\"b\" access=\"read\"/>\n"    \
+        "  <property name=\"State\" type=\"s\" access=\"read\"/>\n"     \
+        "  <property name=\"Controllers\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"ResetControllers\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"KillProcesses\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"IdleHint\" type=\"b\" access=\"read\"/>\n"  \
+        "  <property name=\"IdleSinceHint\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"IdleSinceHintMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_SESSION_INTERFACE                                           \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_GENERIC_INTERFACES_LIST                  \
+        "org.freedesktop.login1.Session\0"
+
+static int bus_session_append_seat(DBusMessageIter *i, const char *property, void *data) {
+        DBusMessageIter sub;
+        Session *s = data;
+        const char *id, *path;
+        char *p = NULL;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
+                return -ENOMEM;
+
+        if (s->seat) {
+                id = s->seat->id;
+                path = p = seat_bus_path(s->seat);
+
+                if (!p)
+                        return -ENOMEM;
+        } else {
+                id = "";
+                path = "/";
+        }
+
+        if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) {
+                free(p);
+                return -ENOMEM;
+        }
+
+        free(p);
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_session_append_user(DBusMessageIter *i, const char *property, void *data) {
+        DBusMessageIter sub;
+        User *u = data;
+        char *p = NULL;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
+                return -ENOMEM;
+
+        p = user_bus_path(u);
+        if (!p)
+                return -ENOMEM;
+
+        if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->uid) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) {
+                free(p);
+                return -ENOMEM;
+        }
+
+        free(p);
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_session_append_active(DBusMessageIter *i, const char *property, void *data) {
+        Session *s = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        b = session_is_active(s);
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_session_append_idle_hint(DBusMessageIter *i, const char *property, void *data) {
+        Session *s = data;
+        int b;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        b = session_get_idle_hint(s, NULL) > 0;
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_session_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) {
+        Session *s = data;
+        dual_timestamp t;
+        uint64_t u;
+        int r;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        r = session_get_idle_hint(s, &t);
+        if (r < 0)
+                return r;
+
+        u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_session_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) {
+        Session *s = data;
+        char *t;
+        int r;
+        bool success;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        r = cg_join_spec(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, &t);
+        if (r < 0)
+                return r;
+
+        success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t);
+        free(t);
+
+        return success ? 0 : -ENOMEM;
+}
+
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_type, session_type, SessionType);
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_class, session_class, SessionClass);
+
+static int bus_session_append_state(DBusMessageIter *i, const char *property, void *data) {
+        Session *s = data;
+        const char *state;
+
+        assert(i);
+        assert(property);
+        assert(s);
+
+        state = session_state_to_string(session_get_state(s));
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int get_session_for_path(Manager *m, const char *path, Session **_s) {
+        Session *s;
+        char *id;
+
+        assert(m);
+        assert(path);
+        assert(_s);
+
+        if (!startswith(path, "/org/freedesktop/login1/session/"))
+                return -EINVAL;
+
+        id = bus_path_unescape(path + 32);
+        if (!id)
+                return -ENOMEM;
+
+        s = hashmap_get(m->sessions, id);
+        free(id);
+
+        if (!s)
+                return -ENOENT;
+
+        *_s = s;
+        return 0;
+}
+
+static const BusProperty bus_login_session_properties[] = {
+        { "Id",                     bus_property_append_string,         "s", offsetof(Session, id),                 true },
+        { "Timestamp",              bus_property_append_usec,           "t", offsetof(Session, timestamp.realtime)  },
+        { "TimestampMonotonic",     bus_property_append_usec,           "t", offsetof(Session, timestamp.monotonic) },
+        { "DefaultControlGroup",    bus_session_append_default_cgroup,  "s", 0,                                     },
+        { "VTNr",                   bus_property_append_uint32,         "u", offsetof(Session, vtnr)                },
+        { "Seat",                   bus_session_append_seat,         "(so)", 0 },
+        { "TTY",                    bus_property_append_string,         "s", offsetof(Session, tty),                true },
+        { "Display",                bus_property_append_string,         "s", offsetof(Session, display),            true },
+        { "Remote",                 bus_property_append_bool,           "b", offsetof(Session, remote)              },
+        { "RemoteUser",             bus_property_append_string,         "s", offsetof(Session, remote_user),        true },
+        { "RemoteHost",             bus_property_append_string,         "s", offsetof(Session, remote_host),        true },
+        { "Service",                bus_property_append_string,         "s", offsetof(Session, service),            true },
+        { "Leader",                 bus_property_append_pid,            "u", offsetof(Session, leader)              },
+        { "Audit",                  bus_property_append_uint32,         "u", offsetof(Session, audit_id)            },
+        { "Type",                   bus_session_append_type,            "s", offsetof(Session, type)                },
+        { "Class",                  bus_session_append_class,           "s", offsetof(Session, class)               },
+        { "Active",                 bus_session_append_active,          "b", 0 },
+        { "State",                  bus_session_append_state,           "s", 0 },
+        { "Controllers",            bus_property_append_strv,          "as", offsetof(Session, controllers),        true },
+        { "ResetControllers",       bus_property_append_strv,          "as", offsetof(Session, reset_controllers),  true },
+        { "KillProcesses",          bus_property_append_bool,           "b", offsetof(Session, kill_processes)      },
+        { "IdleHint",               bus_session_append_idle_hint,       "b", 0 },
+        { "IdleSinceHint",          bus_session_append_idle_hint_since, "t", 0 },
+        { "IdleSinceHintMonotonic", bus_session_append_idle_hint_since, "t", 0 },
+        { NULL, }
+};
+
+static const BusProperty bus_login_session_user_properties[] = {
+        { "User",                   bus_session_append_user,         "(uo)", 0 },
+        { "Name",                   bus_property_append_string,         "s", offsetof(User, name),                  true },
+        { NULL, }
+};
+
+static DBusHandlerResult session_message_dispatch(
+                Session *s,
+                DBusConnection *connection,
+                DBusMessage *message) {
+
+        DBusError error;
+        DBusMessage *reply = NULL;
+        int r;
+
+        assert(s);
+        assert(connection);
+        assert(message);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Terminate")) {
+
+                r = session_stop(s);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Activate")) {
+
+                r = session_activate(s);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Lock") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Unlock")) {
+
+                if (session_send_lock(s, streq(dbus_message_get_member(message), "Lock")) < 0)
+                        goto oom;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "SetIdleHint")) {
+                dbus_bool_t b;
+                unsigned long ul;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_BOOLEAN, &b,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), &error);
+                if (ul == (unsigned long) -1)
+                        return bus_send_error_reply(connection, message, &error, -EIO);
+
+                if (ul != 0 && ul != s->user->uid)
+                        return bus_send_error_reply(connection, message, NULL, -EPERM);
+
+                session_set_idle_hint(s, b);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Kill")) {
+                const char *swho;
+                int32_t signo;
+                KillWho who;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &swho,
+                                    DBUS_TYPE_INT32, &signo,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (isempty(swho))
+                        who = KILL_ALL;
+                else {
+                        who = kill_who_from_string(swho);
+                        if (who < 0)
+                                return bus_send_error_reply(connection, message, &error, -EINVAL);
+                }
+
+                if (signo <= 0 || signo >= _NSIG)
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                r = session_kill(s, who, signo);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.login1.Session", bus_login_session_properties,      s       },
+                        { "org.freedesktop.login1.Session", bus_login_session_user_properties, s->user },
+                        { NULL, }
+                };
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
+
+        if (reply) {
+                if (!dbus_connection_send(connection, reply, NULL))
+                        goto oom;
+
+                dbus_message_unref(reply);
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static DBusHandlerResult session_message_handler(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+        Manager *m = userdata;
+        Session *s;
+        int r;
+
+        r = get_session_for_path(m, dbus_message_get_path(message), &s);
+        if (r < 0) {
+
+                if (r == -ENOMEM)
+                        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+                if (r == -ENOENT) {
+                        DBusError e;
+
+                        dbus_error_init(&e);
+                        dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown session");
+                        return bus_send_error_reply(connection, message, &e, r);
+                }
+
+                return bus_send_error_reply(connection, message, NULL, r);
+        }
+
+        return session_message_dispatch(s, connection, message);
+}
+
+const DBusObjectPathVTable bus_session_vtable = {
+        .message_function = session_message_handler
+};
+
+char *session_bus_path(Session *s) {
+        char *t, *r;
+
+        assert(s);
+
+        t = bus_path_escape(s->id);
+        if (!t)
+                return NULL;
+
+        r = strappend("/org/freedesktop/login1/session/", t);
+        free(t);
+
+        return r;
+}
+
+int session_send_signal(Session *s, bool new_session) {
+        DBusMessage *m;
+        int r = -ENOMEM;
+        char *p = NULL;
+
+        assert(s);
+
+        m = dbus_message_new_signal("/org/freedesktop/login1",
+                                    "org.freedesktop.login1.Manager",
+                                    new_session ? "SessionNew" : "SessionRemoved");
+
+        if (!m)
+                return -ENOMEM;
+
+        p = session_bus_path(s);
+        if (!p)
+                goto finish;
+
+        if (!dbus_message_append_args(
+                            m,
+                            DBUS_TYPE_STRING, &s->id,
+                            DBUS_TYPE_OBJECT_PATH, &p,
+                            DBUS_TYPE_INVALID))
+                goto finish;
+
+        if (!dbus_connection_send(s->manager->bus, m, NULL))
+                goto finish;
+
+        r = 0;
+
+finish:
+        dbus_message_unref(m);
+        free(p);
+
+        return r;
+}
+
+int session_send_changed(Session *s, const char *properties) {
+        DBusMessage *m;
+        int r = -ENOMEM;
+        char *p = NULL;
+
+        assert(s);
+
+        if (!s->started)
+                return 0;
+
+        p = session_bus_path(s);
+        if (!p)
+                return -ENOMEM;
+
+        m = bus_properties_changed_new(p, "org.freedesktop.login1.Session", properties);
+        if (!m)
+                goto finish;
+
+        if (!dbus_connection_send(s->manager->bus, m, NULL))
+                goto finish;
+
+        r = 0;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+        free(p);
+
+        return r;
+}
+
+int session_send_lock(Session *s, bool lock) {
+        DBusMessage *m;
+        bool b;
+        char *p;
+
+        assert(s);
+
+        p = session_bus_path(s);
+        if (!p)
+                return -ENOMEM;
+
+        m = dbus_message_new_signal(p, "org.freedesktop.login1.Session", lock ? "Lock" : "Unlock");
+        free(p);
+
+        if (!m)
+                return -ENOMEM;
+
+        b = dbus_connection_send(s->manager->bus, m, NULL);
+        dbus_message_unref(m);
+
+        if (!b)
+                return -ENOMEM;
+
+        return 0;
+}
+
+int session_send_lock_all(Manager *m, bool lock) {
+        Session *session;
+        Iterator i;
+        int r = 0;
+
+        assert(m);
+
+        HASHMAP_FOREACH(session, m->sessions, i) {
+                int k;
+
+                k = session_send_lock(session, lock);
+                if (k < 0)
+                        r = k;
+        }
+
+        return r;
+}
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
new file mode 100644 (file)
index 0000000..b64a5d3
--- /dev/null
@@ -0,0 +1,1070 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+
+#include "systemd/sd-id128.h"
+#include "systemd/sd-messages.h"
+#include "strv.h"
+#include "util.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "cgroup-util.h"
+#include "logind-session.h"
+
+Session* session_new(Manager *m, User *u, const char *id) {
+        Session *s;
+
+        assert(m);
+        assert(id);
+
+        s = new0(Session, 1);
+        if (!s)
+                return NULL;
+
+        s->state_file = strappend("/run/systemd/sessions/", id);
+        if (!s->state_file) {
+                free(s);
+                return NULL;
+        }
+
+        s->id = path_get_file_name(s->state_file);
+
+        if (hashmap_put(m->sessions, s->id, s) < 0) {
+                free(s->state_file);
+                free(s);
+                return NULL;
+        }
+
+        s->manager = m;
+        s->fifo_fd = -1;
+        s->user = u;
+
+        LIST_PREPEND(Session, sessions_by_user, u->sessions, s);
+
+        return s;
+}
+
+void session_free(Session *s) {
+        assert(s);
+
+        if (s->in_gc_queue)
+                LIST_REMOVE(Session, gc_queue, s->manager->session_gc_queue, s);
+
+        if (s->user) {
+                LIST_REMOVE(Session, sessions_by_user, s->user->sessions, s);
+
+                if (s->user->display == s)
+                        s->user->display = NULL;
+        }
+
+        if (s->seat) {
+                if (s->seat->active == s)
+                        s->seat->active = NULL;
+
+                LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s);
+        }
+
+        if (s->cgroup_path)
+                hashmap_remove(s->manager->session_cgroups, s->cgroup_path);
+
+        free(s->cgroup_path);
+        strv_free(s->controllers);
+
+        free(s->tty);
+        free(s->display);
+        free(s->remote_host);
+        free(s->remote_user);
+        free(s->service);
+
+        hashmap_remove(s->manager->sessions, s->id);
+        session_remove_fifo(s);
+
+        free(s->state_file);
+        free(s);
+}
+
+int session_save(Session *s) {
+        FILE *f;
+        int r = 0;
+        char *temp_path;
+
+        assert(s);
+
+        if (!s->started)
+                return 0;
+
+        r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
+        if (r < 0)
+                goto finish;
+
+        r = fopen_temporary(s->state_file, &f, &temp_path);
+        if (r < 0)
+                goto finish;
+
+        assert(s->user);
+
+        fchmod(fileno(f), 0644);
+
+        fprintf(f,
+                "# This is private data. Do not parse.\n"
+                "UID=%lu\n"
+                "USER=%s\n"
+                "ACTIVE=%i\n"
+                "STATE=%s\n"
+                "REMOTE=%i\n"
+                "KILL_PROCESSES=%i\n",
+                (unsigned long) s->user->uid,
+                s->user->name,
+                session_is_active(s),
+                session_state_to_string(session_get_state(s)),
+                s->remote,
+                s->kill_processes);
+
+        if (s->type >= 0)
+                fprintf(f,
+                        "TYPE=%s\n",
+                        session_type_to_string(s->type));
+
+        if (s->class >= 0)
+                fprintf(f,
+                        "CLASS=%s\n",
+                        session_class_to_string(s->class));
+
+        if (s->cgroup_path)
+                fprintf(f,
+                        "CGROUP=%s\n",
+                        s->cgroup_path);
+
+        if (s->fifo_path)
+                fprintf(f,
+                        "FIFO=%s\n",
+                        s->fifo_path);
+
+        if (s->seat)
+                fprintf(f,
+                        "SEAT=%s\n",
+                        s->seat->id);
+
+        if (s->tty)
+                fprintf(f,
+                        "TTY=%s\n",
+                        s->tty);
+
+        if (s->display)
+                fprintf(f,
+                        "DISPLAY=%s\n",
+                        s->display);
+
+        if (s->remote_host)
+                fprintf(f,
+                        "REMOTE_HOST=%s\n",
+                        s->remote_host);
+
+        if (s->remote_user)
+                fprintf(f,
+                        "REMOTE_USER=%s\n",
+                        s->remote_user);
+
+        if (s->service)
+                fprintf(f,
+                        "SERVICE=%s\n",
+                        s->service);
+
+        if (s->seat && seat_can_multi_session(s->seat))
+                fprintf(f,
+                        "VTNR=%i\n",
+                        s->vtnr);
+
+        if (s->leader > 0)
+                fprintf(f,
+                        "LEADER=%lu\n",
+                        (unsigned long) s->leader);
+
+        if (s->audit_id > 0)
+                fprintf(f,
+                        "AUDIT=%llu\n",
+                        (unsigned long long) s->audit_id);
+
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, s->state_file) < 0) {
+                r = -errno;
+                unlink(s->state_file);
+                unlink(temp_path);
+        }
+
+        fclose(f);
+        free(temp_path);
+
+finish:
+        if (r < 0)
+                log_error("Failed to save session data for %s: %s", s->id, strerror(-r));
+
+        return r;
+}
+
+int session_load(Session *s) {
+        char *remote = NULL,
+                *kill_processes = NULL,
+                *seat = NULL,
+                *vtnr = NULL,
+                *leader = NULL,
+                *audit_id = NULL,
+                *type = NULL,
+                *class = NULL;
+
+        int k, r;
+
+        assert(s);
+
+        r = parse_env_file(s->state_file, NEWLINE,
+                           "REMOTE",         &remote,
+                           "KILL_PROCESSES", &kill_processes,
+                           "CGROUP",         &s->cgroup_path,
+                           "FIFO",           &s->fifo_path,
+                           "SEAT",           &seat,
+                           "TTY",            &s->tty,
+                           "DISPLAY",        &s->display,
+                           "REMOTE_HOST",    &s->remote_host,
+                           "REMOTE_USER",    &s->remote_user,
+                           "SERVICE",        &s->service,
+                           "VTNR",           &vtnr,
+                           "LEADER",         &leader,
+                           "TYPE",           &type,
+                           "CLASS",          &class,
+                           NULL);
+
+        if (r < 0)
+                goto finish;
+
+        if (remote) {
+                k = parse_boolean(remote);
+                if (k >= 0)
+                        s->remote = k;
+        }
+
+        if (kill_processes) {
+                k = parse_boolean(kill_processes);
+                if (k >= 0)
+                        s->kill_processes = k;
+        }
+
+        if (seat && !s->seat) {
+                Seat *o;
+
+                o = hashmap_get(s->manager->seats, seat);
+                if (o)
+                        seat_attach_session(o, s);
+        }
+
+        if (vtnr && s->seat && seat_can_multi_session(s->seat)) {
+                int v;
+
+                k = safe_atoi(vtnr, &v);
+                if (k >= 0 && v >= 1)
+                        s->vtnr = v;
+        }
+
+        if (leader) {
+                k = parse_pid(leader, &s->leader);
+                if (k >= 0)
+                        audit_session_from_pid(s->leader, &s->audit_id);
+        }
+
+        if (type) {
+                SessionType t;
+
+                t = session_type_from_string(type);
+                if (t >= 0)
+                        s->type = t;
+        }
+
+        if (class) {
+                SessionClass c;
+
+                c = session_class_from_string(class);
+                if (c >= 0)
+                        s->class = c;
+        }
+
+        if (s->fifo_path) {
+                int fd;
+
+                /* If we open an unopened pipe for reading we will not
+                   get an EOF. to trigger an EOF we hence open it for
+                   reading, but close it right-away which then will
+                   trigger the EOF. */
+
+                fd = session_create_fifo(s);
+                if (fd >= 0)
+                        close_nointr_nofail(fd);
+        }
+
+finish:
+        free(remote);
+        free(kill_processes);
+        free(seat);
+        free(vtnr);
+        free(leader);
+        free(audit_id);
+        free(class);
+
+        return r;
+}
+
+int session_activate(Session *s) {
+        int r;
+
+        assert(s);
+
+        if (s->vtnr < 0)
+                return -ENOTSUP;
+
+        if (!s->seat)
+                return -ENOTSUP;
+
+        if (s->seat->active == s)
+                return 0;
+
+        assert(seat_is_vtconsole(s->seat));
+
+        r = chvt(s->vtnr);
+        if (r < 0)
+                return r;
+
+        return seat_set_active(s->seat, s);
+}
+
+static int session_link_x11_socket(Session *s) {
+        char *t, *f, *c;
+        size_t k;
+
+        assert(s);
+        assert(s->user);
+        assert(s->user->runtime_path);
+
+        if (s->user->display)
+                return 0;
+
+        if (!s->display || !display_is_local(s->display))
+                return 0;
+
+        k = strspn(s->display+1, "0123456789");
+        f = new(char, sizeof("/tmp/.X11-unix/X") + k);
+        if (!f)
+                return log_oom();
+
+        c = stpcpy(f, "/tmp/.X11-unix/X");
+        memcpy(c, s->display+1, k);
+        c[k] = 0;
+
+        if (access(f, F_OK) < 0) {
+                log_warning("Session %s has display %s with non-existing socket %s.", s->id, s->display, f);
+                free(f);
+                return -ENOENT;
+        }
+
+        /* Note that this cannot be in a subdir to avoid
+         * vulnerabilities since we are privileged but the runtime
+         * path is owned by the user */
+
+        t = strappend(s->user->runtime_path, "/X11-display");
+        if (!t) {
+                free(f);
+                return log_oom();
+        }
+
+        if (link(f, t) < 0) {
+                if (errno == EEXIST) {
+                        unlink(t);
+
+                        if (link(f, t) >= 0)
+                                goto done;
+                }
+
+                if (symlink(f, t) < 0) {
+
+                        if (errno == EEXIST) {
+                                unlink(t);
+
+                                if (symlink(f, t) >= 0)
+                                        goto done;
+                        }
+
+                        log_error("Failed to link %s to %s: %m", f, t);
+                        free(f);
+                        free(t);
+                        return -errno;
+                }
+        }
+
+done:
+        log_info("Linked %s to %s.", f, t);
+        free(f);
+        free(t);
+
+        s->user->display = s;
+
+        return 0;
+}
+
+static int session_create_one_group(Session *s, const char *controller, const char *path) {
+        int r;
+
+        assert(s);
+        assert(controller);
+        assert(path);
+
+        if (s->leader > 0) {
+                r = cg_create_and_attach(controller, path, s->leader);
+                if (r < 0)
+                        r = cg_create(controller, path);
+        } else
+                r = cg_create(controller, path);
+
+        if (r < 0)
+                return r;
+
+        r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid, -1);
+        if (r >= 0)
+                r = cg_set_group_access(controller, path, 0755, s->user->uid, s->user->gid);
+
+        return r;
+}
+
+static int session_create_cgroup(Session *s) {
+        char **k;
+        char *p;
+        int r;
+
+        assert(s);
+        assert(s->user);
+        assert(s->user->cgroup_path);
+
+        if (!s->cgroup_path) {
+                if (asprintf(&p, "%s/%s", s->user->cgroup_path, s->id) < 0)
+                        return log_oom();
+        } else
+                p = s->cgroup_path;
+
+        r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, p);
+        if (r < 0) {
+                log_error("Failed to create "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r));
+                free(p);
+                s->cgroup_path = NULL;
+                return r;
+        }
+
+        s->cgroup_path = p;
+
+        STRV_FOREACH(k, s->controllers) {
+
+                if (strv_contains(s->reset_controllers, *k))
+                        continue;
+
+                r = session_create_one_group(s, *k, p);
+                if (r < 0)
+                        log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r));
+        }
+
+        STRV_FOREACH(k, s->manager->controllers) {
+
+                if (strv_contains(s->reset_controllers, *k) ||
+                    strv_contains(s->manager->reset_controllers, *k) ||
+                    strv_contains(s->controllers, *k))
+                        continue;
+
+                r = session_create_one_group(s, *k, p);
+                if (r < 0)
+                        log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r));
+        }
+
+        if (s->leader > 0) {
+
+                STRV_FOREACH(k, s->reset_controllers) {
+                        r = cg_attach(*k, "/", s->leader);
+                        if (r < 0)
+                                log_warning("Failed to reset controller %s: %s", *k, strerror(-r));
+
+                }
+
+                STRV_FOREACH(k, s->manager->reset_controllers) {
+
+                        if (strv_contains(s->reset_controllers, *k) ||
+                            strv_contains(s->controllers, *k))
+                                continue;
+
+                        r = cg_attach(*k, "/", s->leader);
+                        if (r < 0)
+                                log_warning("Failed to reset controller %s: %s", *k, strerror(-r));
+
+                }
+        }
+
+        r = hashmap_put(s->manager->session_cgroups, s->cgroup_path, s);
+        if (r < 0)
+                log_warning("Failed to create mapping between cgroup and session");
+
+        return 0;
+}
+
+int session_start(Session *s) {
+        int r;
+
+        assert(s);
+        assert(s->user);
+
+        if (s->started)
+                return 0;
+
+        r = user_start(s->user);
+        if (r < 0)
+                return r;
+
+        log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
+                   MESSAGE_ID(SD_MESSAGE_SESSION_START),
+                   "SESSION_ID=%s", s->id,
+                   "USER_ID=%s", s->user->name,
+                   "LEADER=%lu", (unsigned long) s->leader,
+                   "MESSAGE=New session %s of user %s.", s->id, s->user->name,
+                   NULL);
+
+        /* Create cgroup */
+        r = session_create_cgroup(s);
+        if (r < 0)
+                return r;
+
+        /* Create X11 symlink */
+        session_link_x11_socket(s);
+
+        dual_timestamp_get(&s->timestamp);
+
+        if (s->seat)
+                seat_read_active_vt(s->seat);
+
+        s->started = true;
+
+        /* Save session data */
+        session_save(s);
+        user_save(s->user);
+
+        session_send_signal(s, true);
+
+        if (s->seat) {
+                seat_save(s->seat);
+
+                if (s->seat->active == s)
+                        seat_send_changed(s->seat, "Sessions\0ActiveSession\0");
+                else
+                        seat_send_changed(s->seat, "Sessions\0");
+        }
+
+        user_send_changed(s->user, "Sessions\0");
+
+        return 0;
+}
+
+static bool session_shall_kill(Session *s) {
+        assert(s);
+
+        if (!s->kill_processes)
+                return false;
+
+        if (strv_contains(s->manager->kill_exclude_users, s->user->name))
+                return false;
+
+        if (strv_isempty(s->manager->kill_only_users))
+                return true;
+
+        return strv_contains(s->manager->kill_only_users, s->user->name);
+}
+
+static int session_terminate_cgroup(Session *s) {
+        int r;
+        char **k;
+
+        assert(s);
+
+        if (!s->cgroup_path)
+                return 0;
+
+        cg_trim(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false);
+
+        if (session_shall_kill(s)) {
+
+                r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true);
+                if (r < 0)
+                        log_error("Failed to kill session cgroup: %s", strerror(-r));
+
+        } else {
+                if (s->leader > 0) {
+                        Session *t;
+
+                        /* We still send a HUP to the leader process,
+                         * even if we are not supposed to kill the
+                         * whole cgroup. But let's first check the
+                         * leader still exists and belongs to our
+                         * session... */
+
+                        r = manager_get_session_by_pid(s->manager, s->leader, &t);
+                        if (r > 0 && t == s) {
+                                kill(s->leader, SIGTERM); /* for normal processes */
+                                kill(s->leader, SIGHUP);  /* for shells */
+                                kill(s->leader, SIGCONT); /* in case they are stopped */
+                        }
+                }
+
+                r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true);
+                if (r < 0)
+                        log_error("Failed to check session cgroup: %s", strerror(-r));
+                else if (r > 0) {
+                        r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path);
+                        if (r < 0)
+                                log_error("Failed to delete session cgroup: %s", strerror(-r));
+                }
+        }
+
+        STRV_FOREACH(k, s->user->manager->controllers)
+                cg_trim(*k, s->cgroup_path, true);
+
+        hashmap_remove(s->manager->session_cgroups, s->cgroup_path);
+
+        free(s->cgroup_path);
+        s->cgroup_path = NULL;
+
+        return 0;
+}
+
+static int session_unlink_x11_socket(Session *s) {
+        char *t;
+        int r;
+
+        assert(s);
+        assert(s->user);
+
+        if (s->user->display != s)
+                return 0;
+
+        s->user->display = NULL;
+
+        t = strappend(s->user->runtime_path, "/X11-display");
+        if (!t)
+                return log_oom();
+
+        r = unlink(t);
+        free(t);
+
+        return r < 0 ? -errno : 0;
+}
+
+int session_stop(Session *s) {
+        int r = 0, k;
+
+        assert(s);
+
+        if (s->started)
+                log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
+                           MESSAGE_ID(SD_MESSAGE_SESSION_STOP),
+                           "SESSION_ID=%s", s->id,
+                           "USER_ID=%s", s->user->name,
+                           "LEADER=%lu", (unsigned long) s->leader,
+                           "MESSAGE=Removed session %s.", s->id,
+                           NULL);
+
+        /* Kill cgroup */
+        k = session_terminate_cgroup(s);
+        if (k < 0)
+                r = k;
+
+        /* Remove X11 symlink */
+        session_unlink_x11_socket(s);
+
+        unlink(s->state_file);
+        session_add_to_gc_queue(s);
+        user_add_to_gc_queue(s->user);
+
+        if (s->started)
+                session_send_signal(s, false);
+
+        if (s->seat) {
+                if (s->seat->active == s)
+                        seat_set_active(s->seat, NULL);
+
+                seat_send_changed(s->seat, "Sessions\0");
+                seat_save(s->seat);
+        }
+
+        user_send_changed(s->user, "Sessions\0");
+        user_save(s->user);
+
+        s->started = false;
+
+        return r;
+}
+
+bool session_is_active(Session *s) {
+        assert(s);
+
+        if (!s->seat)
+                return true;
+
+        return s->seat->active == s;
+}
+
+static int get_tty_atime(const char *tty, usec_t *atime) {
+        _cleanup_free_ char *p = NULL;
+        struct stat st;
+
+        assert(tty);
+        assert(atime);
+
+        if (!path_is_absolute(tty)) {
+                p = strappend("/dev/", tty);
+                if (!p)
+                        return -ENOMEM;
+
+                tty = p;
+        } else if (!path_startswith(tty, "/dev/"))
+                return -ENOENT;
+
+        if (lstat(tty, &st) < 0)
+                return -errno;
+
+        *atime = timespec_load(&st.st_atim);
+        return 0;
+}
+
+static int get_process_ctty_atime(pid_t pid, usec_t *atime) {
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        assert(pid > 0);
+        assert(atime);
+
+        r = get_ctty(pid, NULL, &p);
+        if (r < 0)
+                return r;
+
+        return get_tty_atime(p, atime);
+}
+
+int session_get_idle_hint(Session *s, dual_timestamp *t) {
+        _cleanup_free_ char *p = NULL;
+        usec_t atime = 0, n;
+        int r;
+
+        assert(s);
+
+        /* Explicit idle hint is set */
+        if (s->idle_hint) {
+                if (t)
+                        *t = s->idle_hint_timestamp;
+
+                return s->idle_hint;
+        }
+
+        /* Graphical sessions really should really implement a real
+         * idle hint logic */
+        if (s->display)
+                goto dont_know;
+
+        /* For sessions with an explicitly configured tty, let's check
+         * its atime */
+        if (s->tty) {
+                r = get_tty_atime(s->tty, &atime);
+                if (r >= 0)
+                        goto found_atime;
+        }
+
+        /* For sessions with a leader but no explicitly configured
+         * tty, let's check the controlling tty of the leader */
+        if (s->leader > 0) {
+                r = get_process_ctty_atime(s->leader, &atime);
+                if (r >= 0)
+                        goto found_atime;
+        }
+
+        /* For other TTY sessions, let's find the most recent atime of
+         * the ttys of any of the processes of the session */
+        if (s->cgroup_path) {
+                _cleanup_fclose_ FILE *f = NULL;
+
+                if (cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, &f) >= 0) {
+                        pid_t pid;
+
+                        atime = 0;
+                        while (cg_read_pid(f, &pid) > 0) {
+                                usec_t a;
+
+                                if (get_process_ctty_atime(pid, &a) >= 0)
+                                        if (atime == 0 || atime < a)
+                                                atime = a;
+                        }
+
+                        if (atime != 0)
+                                goto found_atime;
+                }
+        }
+
+dont_know:
+        if (t)
+                *t = s->idle_hint_timestamp;
+
+        return 0;
+
+found_atime:
+        if (t)
+                dual_timestamp_from_realtime(t, atime);
+
+        n = now(CLOCK_REALTIME);
+
+        if (s->manager->idle_action_usec <= 0)
+                return 0;
+
+        return atime + s->manager->idle_action_usec <= n;
+}
+
+void session_set_idle_hint(Session *s, bool b) {
+        assert(s);
+
+        if (s->idle_hint == b)
+                return;
+
+        s->idle_hint = b;
+        dual_timestamp_get(&s->idle_hint_timestamp);
+
+        session_send_changed(s,
+                             "IdleHint\0"
+                             "IdleSinceHint\0"
+                             "IdleSinceHintMonotonic\0");
+
+        if (s->seat)
+                seat_send_changed(s->seat,
+                                  "IdleHint\0"
+                                  "IdleSinceHint\0"
+                                  "IdleSinceHintMonotonic\0");
+
+        user_send_changed(s->user,
+                          "IdleHint\0"
+                          "IdleSinceHint\0"
+                          "IdleSinceHintMonotonic\0");
+
+        manager_send_changed(s->manager,
+                             "IdleHint\0"
+                             "IdleSinceHint\0"
+                             "IdleSinceHintMonotonic\0");
+}
+
+int session_create_fifo(Session *s) {
+        int r;
+
+        assert(s);
+
+        /* Create FIFO */
+        if (!s->fifo_path) {
+                r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
+                if (r < 0)
+                        return r;
+
+                if (asprintf(&s->fifo_path, "/run/systemd/sessions/%s.ref", s->id) < 0)
+                        return -ENOMEM;
+
+                if (mkfifo(s->fifo_path, 0600) < 0 && errno != EEXIST)
+                        return -errno;
+        }
+
+        /* Open reading side */
+        if (s->fifo_fd < 0) {
+                struct epoll_event ev;
+
+                s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY);
+                if (s->fifo_fd < 0)
+                        return -errno;
+
+                r = hashmap_put(s->manager->session_fds, INT_TO_PTR(s->fifo_fd + 1), s);
+                if (r < 0)
+                        return r;
+
+                zero(ev);
+                ev.events = 0;
+                ev.data.u32 = FD_OTHER_BASE + s->fifo_fd;
+
+                if (epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_ADD, s->fifo_fd, &ev) < 0)
+                        return -errno;
+        }
+
+        /* Open writing side */
+        r = open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY);
+        if (r < 0)
+                return -errno;
+
+        return r;
+}
+
+void session_remove_fifo(Session *s) {
+        assert(s);
+
+        if (s->fifo_fd >= 0) {
+                assert_se(hashmap_remove(s->manager->session_fds, INT_TO_PTR(s->fifo_fd + 1)) == s);
+                assert_se(epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_DEL, s->fifo_fd, NULL) == 0);
+                close_nointr_nofail(s->fifo_fd);
+                s->fifo_fd = -1;
+
+                session_save(s);
+                user_save(s->user);
+        }
+
+        if (s->fifo_path) {
+                unlink(s->fifo_path);
+                free(s->fifo_path);
+                s->fifo_path = NULL;
+        }
+}
+
+int session_check_gc(Session *s, bool drop_not_started) {
+        int r;
+
+        assert(s);
+
+        if (drop_not_started && !s->started)
+                return 0;
+
+        if (s->fifo_fd >= 0) {
+
+                r = pipe_eof(s->fifo_fd);
+                if (r < 0)
+                        return r;
+
+                if (r == 0)
+                        return 1;
+        }
+
+        if (s->cgroup_path) {
+
+                r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false);
+                if (r < 0)
+                        return r;
+
+                if (r <= 0)
+                        return 1;
+        }
+
+        return 0;
+}
+
+void session_add_to_gc_queue(Session *s) {
+        assert(s);
+
+        if (s->in_gc_queue)
+                return;
+
+        LIST_PREPEND(Session, gc_queue, s->manager->session_gc_queue, s);
+        s->in_gc_queue = true;
+}
+
+SessionState session_get_state(Session *s) {
+        assert(s);
+
+        if (s->fifo_fd < 0)
+                return SESSION_CLOSING;
+
+        if (session_is_active(s))
+                return SESSION_ACTIVE;
+
+        return SESSION_ONLINE;
+}
+
+int session_kill(Session *s, KillWho who, int signo) {
+        int r = 0;
+        Set *pid_set = NULL;
+
+        assert(s);
+
+        if (!s->cgroup_path)
+                return -ESRCH;
+
+        if (s->leader <= 0 && who == KILL_LEADER)
+                return -ESRCH;
+
+        if (s->leader > 0)
+                if (kill(s->leader, signo) < 0)
+                        r = -errno;
+
+        if (who == KILL_ALL) {
+                int q;
+
+                pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!pid_set)
+                        return -ENOMEM;
+
+                if (s->leader > 0) {
+                        q = set_put(pid_set, LONG_TO_PTR(s->leader));
+                        if (q < 0)
+                                r = q;
+                }
+
+                q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set);
+                if (q < 0)
+                        if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
+                                r = q;
+        }
+
+        if (pid_set)
+                set_free(pid_set);
+
+        return r;
+}
+
+static const char* const session_state_table[_SESSION_TYPE_MAX] = {
+        [SESSION_ONLINE] = "online",
+        [SESSION_ACTIVE] = "active",
+        [SESSION_CLOSING] = "closing"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
+
+static const char* const session_type_table[_SESSION_TYPE_MAX] = {
+        [SESSION_TTY] = "tty",
+        [SESSION_X11] = "x11",
+        [SESSION_UNSPECIFIED] = "unspecified"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
+
+static const char* const session_class_table[_SESSION_CLASS_MAX] = {
+        [SESSION_USER] = "user",
+        [SESSION_GREETER] = "greeter",
+        [SESSION_LOCK_SCREEN] = "lock-screen"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass);
+
+static const char* const kill_who_table[_KILL_WHO_MAX] = {
+        [KILL_LEADER] = "leader",
+        [KILL_ALL] = "all"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
new file mode 100644 (file)
index 0000000..7598afa
--- /dev/null
@@ -0,0 +1,147 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Session Session;
+
+#include "list.h"
+#include "util.h"
+#include "logind.h"
+#include "logind-seat.h"
+#include "logind-user.h"
+
+typedef enum SessionState {
+        SESSION_ONLINE,   /* Logged in */
+        SESSION_ACTIVE,   /* Logged in and in the fg */
+        SESSION_CLOSING,  /* Logged out, but processes still remain */
+        _SESSION_STATE_MAX,
+        _SESSION_STATE_INVALID = -1
+} SessionState;
+
+typedef enum SessionType {
+        SESSION_UNSPECIFIED,
+        SESSION_TTY,
+        SESSION_X11,
+        _SESSION_TYPE_MAX,
+        _SESSION_TYPE_INVALID = -1
+} SessionType;
+
+typedef enum SessionClass {
+        SESSION_USER,
+        SESSION_GREETER,
+        SESSION_LOCK_SCREEN,
+        _SESSION_CLASS_MAX,
+        _SESSION_CLASS_INVALID = -1
+} SessionClass;
+
+typedef enum KillWho {
+        KILL_LEADER,
+        KILL_ALL,
+        _KILL_WHO_MAX,
+        _KILL_WHO_INVALID = -1
+} KillWho;
+
+struct Session {
+        Manager *manager;
+
+        char *id;
+        SessionType type;
+        SessionClass class;
+
+        char *state_file;
+
+        User *user;
+
+        dual_timestamp timestamp;
+
+        char *tty;
+        char *display;
+
+        bool remote;
+        char *remote_user;
+        char *remote_host;
+
+        char *service;
+
+        int vtnr;
+        Seat *seat;
+
+        pid_t leader;
+        uint32_t audit_id;
+
+        int fifo_fd;
+        char *fifo_path;
+
+        char *cgroup_path;
+        char **controllers, **reset_controllers;
+
+        bool idle_hint;
+        dual_timestamp idle_hint_timestamp;
+
+        bool kill_processes;
+        bool in_gc_queue:1;
+        bool started:1;
+
+        LIST_FIELDS(Session, sessions_by_user);
+        LIST_FIELDS(Session, sessions_by_seat);
+
+        LIST_FIELDS(Session, gc_queue);
+};
+
+Session *session_new(Manager *m, User *u, const char *id);
+void session_free(Session *s);
+int session_check_gc(Session *s, bool drop_not_started);
+void session_add_to_gc_queue(Session *s);
+int session_activate(Session *s);
+bool session_is_active(Session *s);
+int session_get_idle_hint(Session *s, dual_timestamp *t);
+void session_set_idle_hint(Session *s, bool b);
+int session_create_fifo(Session *s);
+void session_remove_fifo(Session *s);
+int session_start(Session *s);
+int session_stop(Session *s);
+int session_save(Session *s);
+int session_load(Session *s);
+int session_kill(Session *s, KillWho who, int signo);
+
+char *session_bus_path(Session *s);
+
+SessionState session_get_state(Session *u);
+
+extern const DBusObjectPathVTable bus_session_vtable;
+
+int session_send_signal(Session *s, bool new_session);
+int session_send_changed(Session *s, const char *properties);
+int session_send_lock(Session *s, bool lock);
+int session_send_lock_all(Manager *m, bool lock);
+
+const char* session_state_to_string(SessionState t);
+SessionState session_state_from_string(const char *s);
+
+const char* session_type_to_string(SessionType t);
+SessionType session_type_from_string(const char *s);
+
+const char* session_class_to_string(SessionClass t);
+SessionClass session_class_from_string(const char *s);
+
+const char *kill_who_to_string(KillWho k);
+KillWho kill_who_from_string(const char *s);
diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c
new file mode 100644 (file)
index 0000000..ddf9d9d
--- /dev/null
@@ -0,0 +1,437 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+
+#include "logind.h"
+#include "logind-user.h"
+#include "dbus-common.h"
+
+#define BUS_USER_INTERFACE \
+        " <interface name=\"org.freedesktop.login1.User\">\n"           \
+        "  <method name=\"Terminate\"/>\n"                              \
+        "  <method name=\"Kill\">\n"                                    \
+        "   <arg name=\"signal\" type=\"s\"/>\n"                        \
+        "  </method>\n"                                                 \
+        "  <property name=\"UID\" type=\"u\" access=\"read\"/>\n"       \
+        "  <property name=\"GID\" type=\"u\" access=\"read\"/>\n"       \
+        "  <property name=\"Name\" type=\"s\" access=\"read\"/>\n"      \
+        "  <property name=\"Timestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"TimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"RuntimePath\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"DefaultControlGroup\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"Service\" type=\"s\" access=\"read\"/>\n"   \
+        "  <property name=\"Display\" type=\"(so)\" access=\"read\"/>\n" \
+        "  <property name=\"State\" type=\"s\" access=\"read\"/>\n"     \
+        "  <property name=\"Sessions\" type=\"a(so)\" access=\"read\"/>\n" \
+        "  <property name=\"IdleHint\" type=\"b\" access=\"read\"/>\n"  \
+        "  <property name=\"IdleSinceHint\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"IdleSinceHintMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        " </interface>\n"                                               \
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        BUS_USER_INTERFACE                                              \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_PEER_INTERFACE                                              \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        "</node>\n"
+
+#define INTERFACES_LIST                              \
+        BUS_GENERIC_INTERFACES_LIST                  \
+        "org.freedesktop.login1.User\0"
+
+static int bus_user_append_display(DBusMessageIter *i, const char *property, void *data) {
+        DBusMessageIter sub;
+        User *u = data;
+        const char *id, *path;
+        char *p = NULL;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
+                return -ENOMEM;
+
+        if (u->display) {
+                id = u->display->id;
+                path = p = session_bus_path(u->display);
+
+                if (!p)
+                        return -ENOMEM;
+        } else {
+                id = "";
+                path = "/";
+        }
+
+        if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) {
+                free(p);
+                return -ENOMEM;
+        }
+
+        free(p);
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_user_append_state(DBusMessageIter *i, const char *property, void *data) {
+        User *u = data;
+        const char *state;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        state = user_state_to_string(user_get_state(u));
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_user_append_sessions(DBusMessageIter *i, const char *property, void *data) {
+        DBusMessageIter sub, sub2;
+        User *u = data;
+        Session *session;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(so)", &sub))
+                return -ENOMEM;
+
+        LIST_FOREACH(sessions_by_user, session, u->sessions) {
+                char *p;
+
+                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
+                        return -ENOMEM;
+
+                p = session_bus_path(session);
+                if (!p)
+                        return -ENOMEM;
+
+                if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) {
+                        free(p);
+                        return -ENOMEM;
+                }
+
+                free(p);
+
+                if (!dbus_message_iter_close_container(&sub, &sub2))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_user_append_idle_hint(DBusMessageIter *i, const char *property, void *data) {
+        User *u = data;
+        dbus_bool_t b;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        b = user_get_idle_hint(u, NULL) > 0;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_user_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) {
+        User *u = data;
+        dual_timestamp t;
+        uint64_t k;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        user_get_idle_hint(u, &t);
+        k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &k))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int bus_user_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) {
+        User *u = data;
+        char *t;
+        int r;
+        bool success;
+
+        assert(i);
+        assert(property);
+        assert(u);
+
+        r = cg_join_spec(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &t);
+        if (r < 0)
+                return r;
+
+        success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t);
+        free(t);
+
+        return success ? 0 : -ENOMEM;
+}
+
+static int get_user_for_path(Manager *m, const char *path, User **_u) {
+        User *u;
+        unsigned long lu;
+        int r;
+
+        assert(m);
+        assert(path);
+        assert(_u);
+
+        if (!startswith(path, "/org/freedesktop/login1/user/"))
+                return -EINVAL;
+
+        r = safe_atolu(path + 29, &lu);
+        if (r < 0)
+                return r;
+
+        u = hashmap_get(m->users, ULONG_TO_PTR(lu));
+        if (!u)
+                return -ENOENT;
+
+        *_u = u;
+        return 0;
+}
+
+static const BusProperty bus_login_user_properties[] = {
+        { "UID",                    bus_property_append_uid,         "u", offsetof(User, uid)                 },
+        { "GID",                    bus_property_append_gid,         "u", offsetof(User, gid)                 },
+        { "Name",                   bus_property_append_string,      "s", offsetof(User, name),               true },
+        { "Timestamp",              bus_property_append_usec,        "t", offsetof(User, timestamp.realtime)  },
+        { "TimestampMonotonic",     bus_property_append_usec,        "t", offsetof(User, timestamp.monotonic) },
+        { "RuntimePath",            bus_property_append_string,      "s", offsetof(User, runtime_path),       true },
+        { "DefaultControlGroup",    bus_user_append_default_cgroup,  "s", 0 },
+        { "Service",                bus_property_append_string,      "s", offsetof(User, service),            true },
+        { "Display",                bus_user_append_display,      "(so)", 0 },
+        { "State",                  bus_user_append_state,           "s", 0 },
+        { "Sessions",               bus_user_append_sessions,    "a(so)", 0 },
+        { "IdleHint",               bus_user_append_idle_hint,       "b", 0 },
+        { "IdleSinceHint",          bus_user_append_idle_hint_since, "t", 0 },
+        { "IdleSinceHintMonotonic", bus_user_append_idle_hint_since, "t", 0 },
+        { NULL, }
+};
+
+static DBusHandlerResult user_message_dispatch(
+                User *u,
+                DBusConnection *connection,
+                DBusMessage *message) {
+
+        DBusError error;
+        DBusMessage *reply = NULL;
+        int r;
+
+        assert(u);
+        assert(connection);
+        assert(message);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.login1.User", "Terminate")) {
+
+                r = user_stop(u);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.User", "Kill")) {
+                int32_t signo;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_INT32, &signo,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (signo <= 0 || signo >= _NSIG)
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                r = user_kill(u, signo);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else {
+                const BusBoundProperties bps[] = {
+                        { "org.freedesktop.login1.User", bus_login_user_properties, u },
+                        { NULL, }
+                };
+
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+        }
+
+        if (reply) {
+                if (!dbus_connection_send(connection, reply, NULL))
+                        goto oom;
+
+                dbus_message_unref(reply);
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static DBusHandlerResult user_message_handler(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+        Manager *m = userdata;
+        User *u;
+        int r;
+
+        r = get_user_for_path(m, dbus_message_get_path(message), &u);
+        if (r < 0) {
+
+                if (r == -ENOMEM)
+                        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+                if (r == -ENOENT) {
+                        DBusError e;
+
+                        dbus_error_init(&e);
+                        dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown user");
+                        return bus_send_error_reply(connection, message, &e, r);
+                }
+
+                return bus_send_error_reply(connection, message, NULL, r);
+        }
+
+        return user_message_dispatch(u, connection, message);
+}
+
+const DBusObjectPathVTable bus_user_vtable = {
+        .message_function = user_message_handler
+};
+
+char *user_bus_path(User *u) {
+        char *s;
+
+        assert(u);
+
+        if (asprintf(&s, "/org/freedesktop/login1/user/%llu", (unsigned long long) u->uid) < 0)
+                return NULL;
+
+        return s;
+}
+
+int user_send_signal(User *u, bool new_user) {
+        DBusMessage *m;
+        int r = -ENOMEM;
+        char *p = NULL;
+        uint32_t uid;
+
+        assert(u);
+
+        m = dbus_message_new_signal("/org/freedesktop/login1",
+                                    "org.freedesktop.login1.Manager",
+                                    new_user ? "UserNew" : "UserRemoved");
+
+        if (!m)
+                return -ENOMEM;
+
+        p = user_bus_path(u);
+        if (!p)
+                goto finish;
+
+        uid = u->uid;
+
+        if (!dbus_message_append_args(
+                            m,
+                            DBUS_TYPE_UINT32, &uid,
+                            DBUS_TYPE_OBJECT_PATH, &p,
+                            DBUS_TYPE_INVALID))
+                goto finish;
+
+        if (!dbus_connection_send(u->manager->bus, m, NULL))
+                goto finish;
+
+        r = 0;
+
+finish:
+        dbus_message_unref(m);
+        free(p);
+
+        return r;
+}
+
+int user_send_changed(User *u, const char *properties) {
+        DBusMessage *m;
+        int r = -ENOMEM;
+        char *p = NULL;
+
+        assert(u);
+
+        if (!u->started)
+                return 0;
+
+        p = user_bus_path(u);
+        if (!p)
+                return -ENOMEM;
+
+        m = bus_properties_changed_new(p, "org.freedesktop.login1.User", properties);
+        if (!m)
+                goto finish;
+
+        if (!dbus_connection_send(u->manager->bus, m, NULL))
+                goto finish;
+
+        r = 0;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+        free(p);
+
+        return r;
+}
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
new file mode 100644 (file)
index 0000000..b692b53
--- /dev/null
@@ -0,0 +1,656 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "logind-user.h"
+#include "util.h"
+#include "mkdir.h"
+#include "cgroup-util.h"
+#include "hashmap.h"
+#include "strv.h"
+
+User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
+        User *u;
+
+        assert(m);
+        assert(name);
+
+        u = new0(User, 1);
+        if (!u)
+                return NULL;
+
+        u->name = strdup(name);
+        if (!u->name) {
+                free(u);
+                return NULL;
+        }
+
+        if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0) {
+                free(u->name);
+                free(u);
+                return NULL;
+        }
+
+        if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0) {
+                free(u->state_file);
+                free(u->name);
+                free(u);
+                return NULL;
+        }
+
+        u->manager = m;
+        u->uid = uid;
+        u->gid = gid;
+
+        return u;
+}
+
+void user_free(User *u) {
+        assert(u);
+
+        if (u->in_gc_queue)
+                LIST_REMOVE(User, gc_queue, u->manager->user_gc_queue, u);
+
+        while (u->sessions)
+                session_free(u->sessions);
+
+        if (u->cgroup_path)
+                hashmap_remove(u->manager->user_cgroups, u->cgroup_path);
+        free(u->cgroup_path);
+
+        free(u->service);
+        free(u->runtime_path);
+
+        hashmap_remove(u->manager->users, ULONG_TO_PTR((unsigned long) u->uid));
+
+        free(u->name);
+        free(u->state_file);
+        free(u);
+}
+
+int user_save(User *u) {
+        FILE *f;
+        int r;
+        char *temp_path;
+
+        assert(u);
+        assert(u->state_file);
+
+        if (!u->started)
+                return 0;
+
+        r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0);
+        if (r < 0)
+                goto finish;
+
+        r = fopen_temporary(u->state_file, &f, &temp_path);
+        if (r < 0)
+                goto finish;
+
+        fchmod(fileno(f), 0644);
+
+        fprintf(f,
+                "# This is private data. Do not parse.\n"
+                "NAME=%s\n"
+                "STATE=%s\n",
+                u->name,
+                user_state_to_string(user_get_state(u)));
+
+        if (u->cgroup_path)
+                fprintf(f,
+                        "CGROUP=%s\n",
+                        u->cgroup_path);
+
+        if (u->runtime_path)
+                fprintf(f,
+                        "RUNTIME=%s\n",
+                        u->runtime_path);
+
+        if (u->service)
+                fprintf(f,
+                        "SERVICE=%s\n",
+                        u->service);
+
+        if (u->display)
+                fprintf(f,
+                        "DISPLAY=%s\n",
+                        u->display->id);
+
+        if (u->sessions) {
+                Session *i;
+                bool first;
+
+                fputs("SESSIONS=", f);
+                first = true;
+                LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                        if (first)
+                                first = false;
+                        else
+                                fputc(' ', f);
+
+                        fputs(i->id, f);
+                }
+
+                fputs("\nSEATS=", f);
+                first = true;
+                LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                        if (!i->seat)
+                                continue;
+
+                        if (first)
+                                first = false;
+                        else
+                                fputc(' ', f);
+
+                        fputs(i->seat->id, f);
+                }
+
+                fputs("\nACTIVE_SESSIONS=", f);
+                first = true;
+                LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                        if (!session_is_active(i))
+                                continue;
+
+                        if (first)
+                                first = false;
+                        else
+                                fputc(' ', f);
+
+                        fputs(i->id, f);
+                }
+
+                fputs("\nONLINE_SESSIONS=", f);
+                first = true;
+                LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                        if (session_get_state(i) == SESSION_CLOSING)
+                                continue;
+
+                        if (first)
+                                first = false;
+                        else
+                                fputc(' ', f);
+
+                        fputs(i->id, f);
+                }
+
+                fputs("\nACTIVE_SEATS=", f);
+                first = true;
+                LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                        if (!session_is_active(i) || !i->seat)
+                                continue;
+
+                        if (first)
+                                first = false;
+                        else
+                                fputc(' ', f);
+
+                        fputs(i->seat->id, f);
+                }
+
+                fputs("\nONLINE_SEATS=", f);
+                first = true;
+                LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                        if (session_get_state(i) == SESSION_CLOSING || !i->seat)
+                                continue;
+
+                        if (first)
+                                first = false;
+                        else
+                                fputc(' ', f);
+
+                        fputs(i->seat->id, f);
+                }
+                fputc('\n', f);
+        }
+
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, u->state_file) < 0) {
+                r = -errno;
+                unlink(u->state_file);
+                unlink(temp_path);
+        }
+
+        fclose(f);
+        free(temp_path);
+
+finish:
+        if (r < 0)
+                log_error("Failed to save user data for %s: %s", u->name, strerror(-r));
+
+        return r;
+}
+
+int user_load(User *u) {
+        int r;
+        char *display = NULL;
+        Session *s = NULL;
+
+        assert(u);
+
+        r = parse_env_file(u->state_file, NEWLINE,
+                           "CGROUP", &u->cgroup_path,
+                           "RUNTIME", &u->runtime_path,
+                           "SERVICE", &u->service,
+                           "DISPLAY", &display,
+                           NULL);
+        if (r < 0) {
+                free(display);
+
+                if (r == -ENOENT)
+                        return 0;
+
+                log_error("Failed to read %s: %s", u->state_file, strerror(-r));
+                return r;
+        }
+
+        if (display) {
+                s = hashmap_get(u->manager->sessions, display);
+                free(display);
+        }
+
+        if (s && s->display && display_is_local(s->display))
+                u->display = s;
+
+        return r;
+}
+
+static int user_mkdir_runtime_path(User *u) {
+        char *p;
+        int r;
+
+        assert(u);
+
+        r = mkdir_safe_label("/run/user", 0755, 0, 0);
+        if (r < 0) {
+                log_error("Failed to create /run/user: %s", strerror(-r));
+                return r;
+        }
+
+        if (!u->runtime_path) {
+                if (asprintf(&p, "/run/user/%lu", (unsigned long) u->uid) < 0)
+                        return log_oom();
+        } else
+                p = u->runtime_path;
+
+        r = mkdir_safe_label(p, 0700, u->uid, u->gid);
+        if (r < 0) {
+                log_error("Failed to create runtime directory %s: %s", p, strerror(-r));
+                free(p);
+                u->runtime_path = NULL;
+                return r;
+        }
+
+        u->runtime_path = p;
+        return 0;
+}
+
+static int user_create_cgroup(User *u) {
+        char **k;
+        char *p;
+        int r;
+
+        assert(u);
+
+        if (!u->cgroup_path) {
+                if (asprintf(&p, "%s/%s", u->manager->cgroup_path, u->name) < 0)
+                        return log_oom();
+        } else
+                p = u->cgroup_path;
+
+        r = cg_create(SYSTEMD_CGROUP_CONTROLLER, p);
+        if (r < 0) {
+                log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r));
+                free(p);
+                u->cgroup_path = NULL;
+                return r;
+        }
+
+        u->cgroup_path = p;
+
+        STRV_FOREACH(k, u->manager->controllers) {
+
+                if (strv_contains(u->manager->reset_controllers, *k))
+                        continue;
+
+                r = cg_create(*k, p);
+                if (r < 0)
+                        log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r));
+        }
+
+        r = hashmap_put(u->manager->user_cgroups, u->cgroup_path, u);
+        if (r < 0)
+                log_warning("Failed to create mapping between cgroup and user");
+
+        return 0;
+}
+
+static int user_start_service(User *u) {
+        assert(u);
+
+        /* FIXME: Fill me in later ... */
+
+        return 0;
+}
+
+int user_start(User *u) {
+        int r;
+
+        assert(u);
+
+        if (u->started)
+                return 0;
+
+        log_debug("New user %s logged in.", u->name);
+
+        /* Make XDG_RUNTIME_DIR */
+        r = user_mkdir_runtime_path(u);
+        if (r < 0)
+                return r;
+
+        /* Create cgroup */
+        r = user_create_cgroup(u);
+        if (r < 0)
+                return r;
+
+        /* Spawn user systemd */
+        r = user_start_service(u);
+        if (r < 0)
+                return r;
+
+        dual_timestamp_get(&u->timestamp);
+
+        u->started = true;
+
+        /* Save new user data */
+        user_save(u);
+
+        user_send_signal(u, true);
+
+        return 0;
+}
+
+static int user_stop_service(User *u) {
+        assert(u);
+
+        if (!u->service)
+                return 0;
+
+        return 0;
+}
+
+static int user_shall_kill(User *u) {
+        assert(u);
+
+        if (!u->manager->kill_user_processes)
+                return false;
+
+        if (strv_contains(u->manager->kill_exclude_users, u->name))
+                return false;
+
+        if (strv_isempty(u->manager->kill_only_users))
+                return true;
+
+        return strv_contains(u->manager->kill_only_users, u->name);
+}
+
+static int user_terminate_cgroup(User *u) {
+        int r;
+        char **k;
+
+        assert(u);
+
+        if (!u->cgroup_path)
+                return 0;
+
+        cg_trim(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false);
+
+        if (user_shall_kill(u)) {
+
+                r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
+                if (r < 0)
+                        log_error("Failed to kill user cgroup: %s", strerror(-r));
+        } else {
+
+                r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
+                if (r < 0)
+                        log_error("Failed to check user cgroup: %s", strerror(-r));
+                else if (r > 0) {
+                        r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path);
+                        if (r < 0)
+                                log_error("Failed to delete user cgroup: %s", strerror(-r));
+                } else
+                        r = -EBUSY;
+        }
+
+        STRV_FOREACH(k, u->manager->controllers)
+                cg_trim(*k, u->cgroup_path, true);
+
+        hashmap_remove(u->manager->user_cgroups, u->cgroup_path);
+
+        free(u->cgroup_path);
+        u->cgroup_path = NULL;
+
+        return r;
+}
+
+static int user_remove_runtime_path(User *u) {
+        int r;
+
+        assert(u);
+
+        if (!u->runtime_path)
+                return 0;
+
+        r = rm_rf(u->runtime_path, false, true, false);
+        if (r < 0)
+                log_error("Failed to remove runtime directory %s: %s", u->runtime_path, strerror(-r));
+
+        free(u->runtime_path);
+        u->runtime_path = NULL;
+
+        return r;
+}
+
+int user_stop(User *u) {
+        Session *s;
+        int r = 0, k;
+        assert(u);
+
+        if (u->started)
+                log_debug("User %s logged out.", u->name);
+
+        LIST_FOREACH(sessions_by_user, s, u->sessions) {
+                k = session_stop(s);
+                if (k < 0)
+                        r = k;
+        }
+
+        /* Kill systemd */
+        k = user_stop_service(u);
+        if (k < 0)
+                r = k;
+
+        /* Kill cgroup */
+        k = user_terminate_cgroup(u);
+        if (k < 0)
+                r = k;
+
+        /* Kill XDG_RUNTIME_DIR */
+        k = user_remove_runtime_path(u);
+        if (k < 0)
+                r = k;
+
+        unlink(u->state_file);
+        user_add_to_gc_queue(u);
+
+        if (u->started)
+                user_send_signal(u, false);
+
+        u->started = false;
+
+        return r;
+}
+
+int user_get_idle_hint(User *u, dual_timestamp *t) {
+        Session *s;
+        bool idle_hint = true;
+        dual_timestamp ts = { 0, 0 };
+
+        assert(u);
+
+        LIST_FOREACH(sessions_by_user, s, u->sessions) {
+                dual_timestamp k;
+                int ih;
+
+                ih = session_get_idle_hint(s, &k);
+                if (ih < 0)
+                        return ih;
+
+                if (!ih) {
+                        if (!idle_hint) {
+                                if (k.monotonic < ts.monotonic)
+                                        ts = k;
+                        } else {
+                                idle_hint = false;
+                                ts = k;
+                        }
+                } else if (idle_hint) {
+
+                        if (k.monotonic > ts.monotonic)
+                                ts = k;
+                }
+        }
+
+        if (t)
+                *t = ts;
+
+        return idle_hint;
+}
+
+static int user_check_linger_file(User *u) {
+        char *p;
+        int r;
+
+        if (asprintf(&p, "/var/lib/systemd/linger/%s", u->name) < 0)
+                return -ENOMEM;
+
+        r = access(p, F_OK) >= 0;
+        free(p);
+
+        return r;
+}
+
+int user_check_gc(User *u, bool drop_not_started) {
+        int r;
+
+        assert(u);
+
+        if (drop_not_started && !u->started)
+                return 0;
+
+        if (u->sessions)
+                return 1;
+
+        if (user_check_linger_file(u) > 0)
+                return 1;
+
+        if (u->cgroup_path) {
+                r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false);
+                if (r < 0)
+                        return r;
+
+                if (r <= 0)
+                        return 1;
+        }
+
+        return 0;
+}
+
+void user_add_to_gc_queue(User *u) {
+        assert(u);
+
+        if (u->in_gc_queue)
+                return;
+
+        LIST_PREPEND(User, gc_queue, u->manager->user_gc_queue, u);
+        u->in_gc_queue = true;
+}
+
+UserState user_get_state(User *u) {
+        Session *i;
+        bool all_closing = true;
+
+        assert(u);
+
+
+        LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                if (session_is_active(i))
+                        return USER_ACTIVE;
+                if (session_get_state(i) != SESSION_CLOSING)
+                        all_closing = false;
+        }
+
+        if (u->sessions)
+                return all_closing ? USER_CLOSING : USER_ONLINE;
+
+        if (user_check_linger_file(u) > 0)
+                return USER_LINGERING;
+
+        return USER_CLOSING;
+}
+
+int user_kill(User *u, int signo) {
+        int r = 0, q;
+        Set *pid_set = NULL;
+
+        assert(u);
+
+        if (!u->cgroup_path)
+                return -ESRCH;
+
+        pid_set = set_new(trivial_hash_func, trivial_compare_func);
+        if (!pid_set)
+                return -ENOMEM;
+
+        q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
+        if (q < 0)
+                if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
+                        r = q;
+
+        if (pid_set)
+                set_free(pid_set);
+
+        return r;
+}
+
+static const char* const user_state_table[_USER_STATE_MAX] = {
+        [USER_OFFLINE] = "offline",
+        [USER_LINGERING] = "lingering",
+        [USER_ONLINE] = "online",
+        [USER_ACTIVE] = "active",
+        [USER_CLOSING] = "closing"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(user_state, UserState);
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
new file mode 100644 (file)
index 0000000..a679d43
--- /dev/null
@@ -0,0 +1,84 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct User User;
+
+#include "list.h"
+#include "util.h"
+#include "logind.h"
+#include "logind-session.h"
+
+typedef enum UserState {
+        USER_OFFLINE,    /* Not logged in at all */
+        USER_LINGERING,  /* Lingering has been enabled by the admin for this user */
+        USER_ONLINE,     /* User logged in */
+        USER_ACTIVE,     /* User logged in and has a session in the fg */
+        USER_CLOSING,    /* User logged out, but processes still remain and lingering is not enabled */
+        _USER_STATE_MAX,
+        _USER_STATE_INVALID = -1
+} UserState;
+
+struct User {
+        Manager *manager;
+
+        uid_t uid;
+        gid_t gid;
+        char *name;
+
+        char *state_file;
+        char *runtime_path;
+        char *service;
+        char *cgroup_path;
+
+        Session *display;
+
+        dual_timestamp timestamp;
+
+        bool in_gc_queue:1;
+        bool started:1;
+
+        LIST_HEAD(Session, sessions);
+        LIST_FIELDS(User, gc_queue);
+};
+
+User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name);
+void user_free(User *u);
+int user_check_gc(User *u, bool drop_not_started);
+void user_add_to_gc_queue(User *u);
+int user_start(User *u);
+int user_stop(User *u);
+UserState user_get_state(User *u);
+int user_get_idle_hint(User *u, dual_timestamp *t);
+int user_save(User *u);
+int user_load(User *u);
+int user_kill(User *u, int signo);
+
+char *user_bus_path(User *s);
+
+extern const DBusObjectPathVTable bus_user_vtable;
+
+int user_send_signal(User *u, bool new_user);
+int user_send_changed(User *u, const char *properties);
+
+const char* user_state_to_string(UserState s);
+UserState user_state_from_string(const char *s);
diff --git a/src/login/logind.c b/src/login/logind.c
new file mode 100644 (file)
index 0000000..6438631
--- /dev/null
@@ -0,0 +1,1768 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <pwd.h>
+#include <libudev.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/epoll.h>
+#include <sys/ioctl.h>
+#include <linux/vt.h>
+#include <sys/timerfd.h>
+
+#include <systemd/sd-daemon.h>
+
+#include "logind.h"
+#include "dbus-common.h"
+#include "dbus-loop.h"
+#include "strv.h"
+#include "conf-parser.h"
+
+Manager *manager_new(void) {
+        Manager *m;
+
+        m = new0(Manager, 1);
+        if (!m)
+                return NULL;
+
+        m->console_active_fd = -1;
+        m->bus_fd = -1;
+        m->udev_seat_fd = -1;
+        m->udev_vcsa_fd = -1;
+        m->udev_button_fd = -1;
+        m->epoll_fd = -1;
+        m->reserve_vt_fd = -1;
+
+        m->n_autovts = 6;
+        m->reserve_vt = 6;
+        m->inhibit_delay_max = 5 * USEC_PER_SEC;
+        m->handle_power_key = HANDLE_POWEROFF;
+        m->handle_suspend_key = HANDLE_SUSPEND;
+        m->handle_hibernate_key = HANDLE_HIBERNATE;
+        m->handle_lid_switch = HANDLE_SUSPEND;
+        m->lid_switch_ignore_inhibited = true;
+
+        m->idle_action_fd = -1;
+        m->idle_action_usec = 30 * USEC_PER_MINUTE;
+        m->idle_action = HANDLE_IGNORE;
+        m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
+
+        m->devices = hashmap_new(string_hash_func, string_compare_func);
+        m->seats = hashmap_new(string_hash_func, string_compare_func);
+        m->sessions = hashmap_new(string_hash_func, string_compare_func);
+        m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
+        m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
+        m->buttons = hashmap_new(string_hash_func, string_compare_func);
+
+        m->user_cgroups = hashmap_new(string_hash_func, string_compare_func);
+        m->session_cgroups = hashmap_new(string_hash_func, string_compare_func);
+
+        m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
+        m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
+        m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
+
+        if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
+            !m->user_cgroups || !m->session_cgroups ||
+            !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
+                manager_free(m);
+                return NULL;
+        }
+
+        m->reset_controllers = strv_new("cpu", NULL);
+        m->kill_exclude_users = strv_new("root", NULL);
+        if (!m->reset_controllers || !m->kill_exclude_users) {
+                manager_free(m);
+                return NULL;
+        }
+
+        m->udev = udev_new();
+        if (!m->udev) {
+                manager_free(m);
+                return NULL;
+        }
+
+        if (cg_get_user_path(&m->cgroup_path) < 0) {
+                manager_free(m);
+                return NULL;
+        }
+
+        return m;
+}
+
+void manager_free(Manager *m) {
+        Session *session;
+        User *u;
+        Device *d;
+        Seat *s;
+        Inhibitor *i;
+        Button *b;
+
+        assert(m);
+
+        while ((session = hashmap_first(m->sessions)))
+                session_free(session);
+
+        while ((u = hashmap_first(m->users)))
+                user_free(u);
+
+        while ((d = hashmap_first(m->devices)))
+                device_free(d);
+
+        while ((s = hashmap_first(m->seats)))
+                seat_free(s);
+
+        while ((i = hashmap_first(m->inhibitors)))
+                inhibitor_free(i);
+
+        while ((b = hashmap_first(m->buttons)))
+                button_free(b);
+
+        hashmap_free(m->devices);
+        hashmap_free(m->seats);
+        hashmap_free(m->sessions);
+        hashmap_free(m->users);
+        hashmap_free(m->inhibitors);
+        hashmap_free(m->buttons);
+
+        hashmap_free(m->user_cgroups);
+        hashmap_free(m->session_cgroups);
+
+        hashmap_free(m->session_fds);
+        hashmap_free(m->inhibitor_fds);
+        hashmap_free(m->button_fds);
+
+        if (m->console_active_fd >= 0)
+                close_nointr_nofail(m->console_active_fd);
+
+        if (m->udev_seat_monitor)
+                udev_monitor_unref(m->udev_seat_monitor);
+        if (m->udev_vcsa_monitor)
+                udev_monitor_unref(m->udev_vcsa_monitor);
+        if (m->udev_button_monitor)
+                udev_monitor_unref(m->udev_button_monitor);
+
+        if (m->udev)
+                udev_unref(m->udev);
+
+        if (m->bus) {
+                dbus_connection_flush(m->bus);
+                dbus_connection_close(m->bus);
+                dbus_connection_unref(m->bus);
+        }
+
+        if (m->bus_fd >= 0)
+                close_nointr_nofail(m->bus_fd);
+
+        if (m->epoll_fd >= 0)
+                close_nointr_nofail(m->epoll_fd);
+
+        if (m->reserve_vt_fd >= 0)
+                close_nointr_nofail(m->reserve_vt_fd);
+
+        if (m->idle_action_fd >= 0)
+                close_nointr_nofail(m->idle_action_fd);
+
+        strv_free(m->controllers);
+        strv_free(m->reset_controllers);
+        strv_free(m->kill_only_users);
+        strv_free(m->kill_exclude_users);
+
+        free(m->cgroup_path);
+        free(m);
+}
+
+int manager_add_device(Manager *m, const char *sysfs, Device **_device) {
+        Device *d;
+
+        assert(m);
+        assert(sysfs);
+
+        d = hashmap_get(m->devices, sysfs);
+        if (d) {
+                if (_device)
+                        *_device = d;
+
+                return 0;
+        }
+
+        d = device_new(m, sysfs);
+        if (!d)
+                return -ENOMEM;
+
+        if (_device)
+                *_device = d;
+
+        return 0;
+}
+
+int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
+        Seat *s;
+
+        assert(m);
+        assert(id);
+
+        s = hashmap_get(m->seats, id);
+        if (s) {
+                if (_seat)
+                        *_seat = s;
+
+                return 0;
+        }
+
+        s = seat_new(m, id);
+        if (!s)
+                return -ENOMEM;
+
+        if (_seat)
+                *_seat = s;
+
+        return 0;
+}
+
+int manager_add_session(Manager *m, User *u, const char *id, Session **_session) {
+        Session *s;
+
+        assert(m);
+        assert(id);
+
+        s = hashmap_get(m->sessions, id);
+        if (s) {
+                if (_session)
+                        *_session = s;
+
+                return 0;
+        }
+
+        s = session_new(m, u, id);
+        if (!s)
+                return -ENOMEM;
+
+        if (_session)
+                *_session = s;
+
+        return 0;
+}
+
+int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
+        User *u;
+
+        assert(m);
+        assert(name);
+
+        u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
+        if (u) {
+                if (_user)
+                        *_user = u;
+
+                return 0;
+        }
+
+        u = user_new(m, uid, gid, name);
+        if (!u)
+                return -ENOMEM;
+
+        if (_user)
+                *_user = u;
+
+        return 0;
+}
+
+int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
+        uid_t uid;
+        gid_t gid;
+        int r;
+
+        assert(m);
+        assert(name);
+
+        r = get_user_creds(&name, &uid, &gid, NULL, NULL);
+        if (r < 0)
+                return r;
+
+        return manager_add_user(m, uid, gid, name, _user);
+}
+
+int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
+        struct passwd *p;
+
+        assert(m);
+
+        errno = 0;
+        p = getpwuid(uid);
+        if (!p)
+                return errno ? -errno : -ENOENT;
+
+        return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
+}
+
+int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
+        Inhibitor *i;
+
+        assert(m);
+        assert(id);
+
+        i = hashmap_get(m->inhibitors, id);
+        if (i) {
+                if (_inhibitor)
+                        *_inhibitor = i;
+
+                return 0;
+        }
+
+        i = inhibitor_new(m, id);
+        if (!i)
+                return -ENOMEM;
+
+        if (_inhibitor)
+                *_inhibitor = i;
+
+        return 0;
+}
+
+int manager_add_button(Manager *m, const char *name, Button **_button) {
+        Button *b;
+
+        assert(m);
+        assert(name);
+
+        b = hashmap_get(m->buttons, name);
+        if (b) {
+                if (_button)
+                        *_button = b;
+
+                return 0;
+        }
+
+        b = button_new(m, name);
+        if (!b)
+                return -ENOMEM;
+
+        if (_button)
+                *_button = b;
+
+        return 0;
+}
+
+int manager_process_seat_device(Manager *m, struct udev_device *d) {
+        Device *device;
+        int r;
+
+        assert(m);
+
+        if (streq_ptr(udev_device_get_action(d), "remove")) {
+
+                device = hashmap_get(m->devices, udev_device_get_syspath(d));
+                if (!device)
+                        return 0;
+
+                seat_add_to_gc_queue(device->seat);
+                device_free(device);
+
+        } else {
+                const char *sn;
+                Seat *seat;
+
+                sn = udev_device_get_property_value(d, "ID_SEAT");
+                if (isempty(sn))
+                        sn = "seat0";
+
+                if (!seat_name_is_valid(sn)) {
+                        log_warning("Device with invalid seat name %s found, ignoring.", sn);
+                        return 0;
+                }
+
+                r = manager_add_device(m, udev_device_get_syspath(d), &device);
+                if (r < 0)
+                        return r;
+
+                r = manager_add_seat(m, sn, &seat);
+                if (r < 0) {
+                        if (!device->seat)
+                                device_free(device);
+
+                        return r;
+                }
+
+                device_attach(device, seat);
+                seat_start(seat);
+        }
+
+        return 0;
+}
+
+int manager_process_button_device(Manager *m, struct udev_device *d) {
+        Button *b;
+
+        int r;
+
+        assert(m);
+
+        if (streq_ptr(udev_device_get_action(d), "remove")) {
+
+                b = hashmap_get(m->buttons, udev_device_get_sysname(d));
+                if (!b)
+                        return 0;
+
+                button_free(b);
+
+        } else {
+                const char *sn;
+
+                r = manager_add_button(m, udev_device_get_sysname(d), &b);
+                if (r < 0)
+                        return r;
+
+                sn = udev_device_get_property_value(d, "ID_SEAT");
+                if (isempty(sn))
+                        sn = "seat0";
+
+                button_set_seat(b, sn);
+                button_open(b);
+        }
+
+        return 0;
+}
+
+int manager_enumerate_devices(Manager *m) {
+        struct udev_list_entry *item = NULL, *first = NULL;
+        struct udev_enumerate *e;
+        int r;
+
+        assert(m);
+
+        /* Loads devices from udev and creates seats for them as
+         * necessary */
+
+        e = udev_enumerate_new(m->udev);
+        if (!e) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = udev_enumerate_add_match_subsystem(e, "graphics");
+        if (r < 0)
+                goto finish;
+
+        r = udev_enumerate_add_match_tag(e, "seat");
+        if (r < 0)
+                goto finish;
+
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                goto finish;
+
+        first = udev_enumerate_get_list_entry(e);
+        udev_list_entry_foreach(item, first) {
+                struct udev_device *d;
+                int k;
+
+                d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
+                if (!d) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                k = manager_process_seat_device(m, d);
+                udev_device_unref(d);
+
+                if (k < 0)
+                        r = k;
+        }
+
+finish:
+        if (e)
+                udev_enumerate_unref(e);
+
+        return r;
+}
+
+int manager_enumerate_buttons(Manager *m) {
+        struct udev_list_entry *item = NULL, *first = NULL;
+        struct udev_enumerate *e;
+        int r;
+
+        assert(m);
+
+        /* Loads buttons from udev */
+
+        if (m->handle_power_key == HANDLE_IGNORE &&
+            m->handle_suspend_key == HANDLE_IGNORE &&
+            m->handle_hibernate_key == HANDLE_IGNORE &&
+            m->handle_lid_switch == HANDLE_IGNORE)
+                return 0;
+
+        e = udev_enumerate_new(m->udev);
+        if (!e) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = udev_enumerate_add_match_subsystem(e, "input");
+        if (r < 0)
+                goto finish;
+
+        r = udev_enumerate_add_match_tag(e, "power-switch");
+        if (r < 0)
+                goto finish;
+
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                goto finish;
+
+        first = udev_enumerate_get_list_entry(e);
+        udev_list_entry_foreach(item, first) {
+                struct udev_device *d;
+                int k;
+
+                d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
+                if (!d) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                k = manager_process_button_device(m, d);
+                udev_device_unref(d);
+
+                if (k < 0)
+                        r = k;
+        }
+
+finish:
+        if (e)
+                udev_enumerate_unref(e);
+
+        return r;
+}
+
+int manager_enumerate_seats(Manager *m) {
+        DIR *d;
+        struct dirent *de;
+        int r = 0;
+
+        assert(m);
+
+        /* This loads data about seats stored on disk, but does not
+         * actually create any seats. Removes data of seats that no
+         * longer exist. */
+
+        d = opendir("/run/systemd/seats");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /run/systemd/seats: %m");
+                return -errno;
+        }
+
+        while ((de = readdir(d))) {
+                Seat *s;
+                int k;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                s = hashmap_get(m->seats, de->d_name);
+                if (!s) {
+                        unlinkat(dirfd(d), de->d_name, 0);
+                        continue;
+                }
+
+                k = seat_load(s);
+                if (k < 0)
+                        r = k;
+        }
+
+        closedir(d);
+
+        return r;
+}
+
+static int manager_enumerate_users_from_cgroup(Manager *m) {
+        int r = 0, k;
+        char *name;
+        DIR *d;
+
+        r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d);
+        if (r < 0) {
+                if (r == -ENOENT)
+                        return 0;
+
+                log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r));
+                return r;
+        }
+
+        while ((k = cg_read_subgroup(d, &name)) > 0) {
+                User *user;
+
+                k = manager_add_user_by_name(m, name, &user);
+                if (k < 0) {
+                        free(name);
+                        r = k;
+                        continue;
+                }
+
+                user_add_to_gc_queue(user);
+
+                if (!user->cgroup_path)
+                        if (asprintf(&user->cgroup_path, "%s/%s", m->cgroup_path, name) < 0) {
+                                r = -ENOMEM;
+                                free(name);
+                                break;
+                        }
+
+                free(name);
+        }
+
+        if (r >= 0 && k < 0)
+                r = k;
+
+        closedir(d);
+
+        return r;
+}
+
+static int manager_enumerate_linger_users(Manager *m) {
+        DIR *d;
+        struct dirent *de;
+        int r = 0;
+
+        d = opendir("/var/lib/systemd/linger");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /var/lib/systemd/linger/: %m");
+                return -errno;
+        }
+
+        while ((de = readdir(d))) {
+                int k;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                k = manager_add_user_by_name(m, de->d_name, NULL);
+                if (k < 0) {
+                        log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
+                        r = k;
+                }
+        }
+
+        closedir(d);
+
+        return r;
+}
+
+int manager_enumerate_users(Manager *m) {
+        DIR *d;
+        struct dirent *de;
+        int r, k;
+
+        assert(m);
+
+        /* First, enumerate user cgroups */
+        r = manager_enumerate_users_from_cgroup(m);
+
+        /* Second, add lingering users on top */
+        k = manager_enumerate_linger_users(m);
+        if (k < 0)
+                r = k;
+
+        /* Third, read in user data stored on disk */
+        d = opendir("/run/systemd/users");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /run/systemd/users: %m");
+                return -errno;
+        }
+
+        while ((de = readdir(d))) {
+                uid_t uid;
+                User *u;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                k = parse_uid(de->d_name, &uid);
+                if (k < 0) {
+                        log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k));
+                        continue;
+                }
+
+                u = hashmap_get(m->users, ULONG_TO_PTR(uid));
+                if (!u) {
+                        unlinkat(dirfd(d), de->d_name, 0);
+                        continue;
+                }
+
+                k = user_load(u);
+                if (k < 0)
+                        r = k;
+        }
+
+        closedir(d);
+
+        return r;
+}
+
+static int manager_enumerate_sessions_from_cgroup(Manager *m) {
+        User *u;
+        Iterator i;
+        int r = 0;
+
+        HASHMAP_FOREACH(u, m->users, i) {
+                DIR *d;
+                char *name;
+                int k;
+
+                if (!u->cgroup_path)
+                        continue;
+
+                k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d);
+                if (k < 0) {
+                        if (k == -ENOENT)
+                                continue;
+
+                        log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k));
+                        r = k;
+                        continue;
+                }
+
+                while ((k = cg_read_subgroup(d, &name)) > 0) {
+                        Session *session;
+
+                        if (streq(name, "shared"))
+                                continue;
+
+                        k = manager_add_session(m, u, name, &session);
+                        if (k < 0) {
+                                free(name);
+                                break;
+                        }
+
+                        session_add_to_gc_queue(session);
+
+                        if (!session->cgroup_path)
+                                if (asprintf(&session->cgroup_path, "%s/%s", u->cgroup_path, name) < 0) {
+                                        k = -ENOMEM;
+                                        free(name);
+                                        break;
+                                }
+
+                        free(name);
+                }
+
+                closedir(d);
+
+                if (k < 0)
+                        r = k;
+        }
+
+        return r;
+}
+
+int manager_enumerate_sessions(Manager *m) {
+        DIR *d;
+        struct dirent *de;
+        int r = 0;
+
+        assert(m);
+
+        /* First enumerate session cgroups */
+        r = manager_enumerate_sessions_from_cgroup(m);
+
+        /* Second, read in session data stored on disk */
+        d = opendir("/run/systemd/sessions");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /run/systemd/sessions: %m");
+                return -errno;
+        }
+
+        while ((de = readdir(d))) {
+                struct Session *s;
+                int k;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                s = hashmap_get(m->sessions, de->d_name);
+                if (!s) {
+                        unlinkat(dirfd(d), de->d_name, 0);
+                        continue;
+                }
+
+                k = session_load(s);
+                if (k < 0)
+                        r = k;
+        }
+
+        closedir(d);
+
+        return r;
+}
+
+int manager_enumerate_inhibitors(Manager *m) {
+        DIR *d;
+        struct dirent *de;
+        int r = 0;
+
+        assert(m);
+
+        d = opendir("/run/systemd/inhibit");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /run/systemd/inhibit: %m");
+                return -errno;
+        }
+
+        while ((de = readdir(d))) {
+                int k;
+                Inhibitor *i;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                k = manager_add_inhibitor(m, de->d_name, &i);
+                if (k < 0) {
+                        log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
+                        r = k;
+                        continue;
+                }
+
+                k = inhibitor_load(i);
+                if (k < 0)
+                        r = k;
+        }
+
+        closedir(d);
+
+        return r;
+}
+
+int manager_dispatch_seat_udev(Manager *m) {
+        struct udev_device *d;
+        int r;
+
+        assert(m);
+
+        d = udev_monitor_receive_device(m->udev_seat_monitor);
+        if (!d)
+                return -ENOMEM;
+
+        r = manager_process_seat_device(m, d);
+        udev_device_unref(d);
+
+        return r;
+}
+
+int manager_dispatch_vcsa_udev(Manager *m) {
+        struct udev_device *d;
+        int r = 0;
+        const char *name;
+
+        assert(m);
+
+        d = udev_monitor_receive_device(m->udev_vcsa_monitor);
+        if (!d)
+                return -ENOMEM;
+
+        name = udev_device_get_sysname(d);
+
+        /* Whenever a VCSA device is removed try to reallocate our
+         * VTs, to make sure our auto VTs never go away. */
+
+        if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
+                r = seat_preallocate_vts(m->vtconsole);
+
+        udev_device_unref(d);
+
+        return r;
+}
+
+int manager_dispatch_button_udev(Manager *m) {
+        struct udev_device *d;
+        int r;
+
+        assert(m);
+
+        d = udev_monitor_receive_device(m->udev_button_monitor);
+        if (!d)
+                return -ENOMEM;
+
+        r = manager_process_button_device(m, d);
+        udev_device_unref(d);
+
+        return r;
+}
+
+int manager_dispatch_console(Manager *m) {
+        assert(m);
+
+        if (m->vtconsole)
+                seat_read_active_vt(m->vtconsole);
+
+        return 0;
+}
+
+static int vt_is_busy(int vtnr) {
+        struct vt_stat vt_stat;
+        int r = 0, fd;
+
+        assert(vtnr >= 1);
+
+        /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
+         * we'd open the latter we'd open the foreground tty which
+         * hence would be unconditionally busy. By opening /dev/tty1
+         * we avoid this. Since tty1 is special and needs to be an
+         * explicitly loaded getty or DM this is safe. */
+
+        fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
+                r = -errno;
+        else
+                r = !!(vt_stat.v_state & (1 << vtnr));
+
+        close_nointr_nofail(fd);
+
+        return r;
+}
+
+int manager_spawn_autovt(Manager *m, int vtnr) {
+        int r;
+        char *name = NULL;
+        const char *mode = "fail";
+
+        assert(m);
+        assert(vtnr >= 1);
+
+        if ((unsigned) vtnr > m->n_autovts &&
+            (unsigned) vtnr != m->reserve_vt)
+                return 0;
+
+        if ((unsigned) vtnr != m->reserve_vt) {
+                /* If this is the reserved TTY, we'll start the getty
+                 * on it in any case, but otherwise only if it is not
+                 * busy. */
+
+                r = vt_is_busy(vtnr);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        return -EBUSY;
+        }
+
+        if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
+                log_error("Could not allocate service name.");
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = bus_method_call_with_reply (
+                        m->bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "StartUnit",
+                        NULL,
+                        NULL,
+                        DBUS_TYPE_STRING, &name,
+                        DBUS_TYPE_STRING, &mode,
+                        DBUS_TYPE_INVALID);
+
+finish:
+        free(name);
+
+        return r;
+}
+
+static int manager_reserve_vt(Manager *m) {
+        _cleanup_free_ char *p = NULL;
+
+        assert(m);
+
+        if (m->reserve_vt <= 0)
+                return 0;
+
+        if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
+                return log_oom();
+
+        m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
+        if (m->reserve_vt_fd < 0) {
+
+                /* Don't complain on VT-less systems */
+                if (errno != ENOENT)
+                        log_warning("Failed to pin reserved VT: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
+        Session *s;
+        char *p;
+
+        assert(m);
+        assert(cgroup);
+        assert(session);
+
+        s = hashmap_get(m->session_cgroups, cgroup);
+        if (s) {
+                *session = s;
+                return 1;
+        }
+
+        p = strdup(cgroup);
+        if (!p)
+                return log_oom();
+
+        for (;;) {
+                char *e;
+
+                e = strrchr(p, '/');
+                if (!e || e == p) {
+                        free(p);
+                        *session = NULL;
+                        return 0;
+                }
+
+                *e = 0;
+
+                s = hashmap_get(m->session_cgroups, p);
+                if (s) {
+                        free(p);
+                        *session = s;
+                        return 1;
+                }
+        }
+}
+
+int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
+        User *u;
+        char *p;
+
+        assert(m);
+        assert(cgroup);
+        assert(user);
+
+        u = hashmap_get(m->user_cgroups, cgroup);
+        if (u) {
+                *user = u;
+                return 1;
+        }
+
+        p = strdup(cgroup);
+        if (!p)
+                return log_oom();
+
+        for (;;) {
+                char *e;
+
+                e = strrchr(p, '/');
+                if (!e || e == p) {
+                        free(p);
+                        *user = NULL;
+                        return 0;
+                }
+
+                *e = 0;
+
+                u = hashmap_get(m->user_cgroups, p);
+                if (u) {
+                        free(p);
+                        *user = u;
+                        return 1;
+                }
+        }
+}
+
+int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
+        char *p;
+        int r;
+
+        assert(m);
+        assert(pid >= 1);
+        assert(session);
+
+        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
+        if (r < 0)
+                return r;
+
+        r = manager_get_session_by_cgroup(m, p, session);
+        free(p);
+
+        return r;
+}
+
+void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
+        Session *s;
+        User *u;
+        int r;
+
+        r = manager_get_session_by_cgroup(m, cgroup, &s);
+        if (r > 0)
+                session_add_to_gc_queue(s);
+
+        r = manager_get_user_by_cgroup(m, cgroup, &u);
+        if (r > 0)
+                user_add_to_gc_queue(u);
+}
+
+static void manager_dispatch_other(Manager *m, int fd) {
+        Session *s;
+        Inhibitor *i;
+        Button *b;
+
+        assert_se(m);
+        assert_se(fd >= 0);
+
+        s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
+        if (s) {
+                assert(s->fifo_fd == fd);
+                session_remove_fifo(s);
+                session_stop(s);
+                return;
+        }
+
+        i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
+        if (i) {
+                assert(i->fifo_fd == fd);
+                inhibitor_stop(i);
+                inhibitor_free(i);
+                return;
+        }
+
+        b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
+        if (b) {
+                assert(b->fd == fd);
+                button_process(b);
+                return;
+        }
+
+        assert_not_reached("Got event for unknown fd");
+}
+
+static int manager_connect_bus(Manager *m) {
+        DBusError error;
+        int r;
+        struct epoll_event ev;
+
+        assert(m);
+        assert(!m->bus);
+        assert(m->bus_fd < 0);
+
+        dbus_error_init(&error);
+
+        m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        if (!m->bus) {
+                log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
+                r = -ECONNREFUSED;
+                goto fail;
+        }
+
+        if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
+            !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
+            !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
+            !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
+            !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
+                r = log_oom();
+                goto fail;
+        }
+
+        dbus_bus_add_match(m->bus,
+                           "type='signal',"
+                           "interface='org.freedesktop.systemd1.Agent',"
+                           "member='Released',"
+                           "path='/org/freedesktop/systemd1/agent'",
+                           &error);
+
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to register match: %s", bus_error_message(&error));
+                r = -EIO;
+                goto fail;
+        }
+
+        r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to register name on bus: %s", bus_error_message(&error));
+                r = -EIO;
+                goto fail;
+        }
+
+        if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
+                log_error("Failed to acquire name.");
+                r = -EEXIST;
+                goto fail;
+        }
+
+        m->bus_fd = bus_loop_open(m->bus);
+        if (m->bus_fd < 0) {
+                r = m->bus_fd;
+                goto fail;
+        }
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.u32 = FD_BUS;
+
+        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int manager_connect_console(Manager *m) {
+        struct epoll_event ev;
+
+        assert(m);
+        assert(m->console_active_fd < 0);
+
+        /* On certain architectures (S390 and Xen, and containers),
+           /dev/tty0 does not exist, so don't fail if we can't open
+           it. */
+        if (access("/dev/tty0", F_OK) < 0) {
+                m->console_active_fd = -1;
+                return 0;
+        }
+
+        m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
+        if (m->console_active_fd < 0) {
+
+                /* On some systems the device node /dev/tty0 may exist
+                 * even though /sys/class/tty/tty0 does not. */
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /sys/class/tty/tty0/active: %m");
+                return -errno;
+        }
+
+        zero(ev);
+        ev.events = 0;
+        ev.data.u32 = FD_CONSOLE;
+
+        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
+                return -errno;
+
+        return 0;
+}
+
+static int manager_connect_udev(Manager *m) {
+        struct epoll_event ev;
+        int r;
+
+        assert(m);
+        assert(!m->udev_seat_monitor);
+        assert(!m->udev_vcsa_monitor);
+        assert(!m->udev_button_monitor);
+
+        m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
+        if (!m->udev_seat_monitor)
+                return -ENOMEM;
+
+        r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "seat");
+        if (r < 0)
+                return r;
+
+        r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_seat_monitor, "graphics", NULL);
+        if (r < 0)
+                return r;
+
+        r = udev_monitor_enable_receiving(m->udev_seat_monitor);
+        if (r < 0)
+                return r;
+
+        m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.u32 = FD_SEAT_UDEV;
+        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
+                return -errno;
+
+        /* Don't watch keys if nobody cares */
+        if (m->handle_power_key != HANDLE_IGNORE ||
+            m->handle_suspend_key != HANDLE_IGNORE ||
+            m->handle_hibernate_key != HANDLE_IGNORE ||
+            m->handle_lid_switch != HANDLE_IGNORE) {
+
+                m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
+                if (!m->udev_button_monitor)
+                        return -ENOMEM;
+
+                r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
+                if (r < 0)
+                        return r;
+
+                r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
+                if (r < 0)
+                        return r;
+
+                r = udev_monitor_enable_receiving(m->udev_button_monitor);
+                if (r < 0)
+                        return r;
+
+                m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
+
+                zero(ev);
+                ev.events = EPOLLIN;
+                ev.data.u32 = FD_BUTTON_UDEV;
+                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
+                        return -errno;
+        }
+
+        /* Don't bother watching VCSA devices, if nobody cares */
+        if (m->n_autovts > 0 && m->console_active_fd >= 0) {
+
+                m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
+                if (!m->udev_vcsa_monitor)
+                        return -ENOMEM;
+
+                r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
+                if (r < 0)
+                        return r;
+
+                r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
+                if (r < 0)
+                        return r;
+
+                m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
+
+                zero(ev);
+                ev.events = EPOLLIN;
+                ev.data.u32 = FD_VCSA_UDEV;
+                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
+                        return -errno;
+        }
+
+        return 0;
+}
+
+void manager_gc(Manager *m, bool drop_not_started) {
+        Seat *seat;
+        Session *session;
+        User *user;
+
+        assert(m);
+
+        while ((seat = m->seat_gc_queue)) {
+                LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
+                seat->in_gc_queue = false;
+
+                if (seat_check_gc(seat, drop_not_started) == 0) {
+                        seat_stop(seat);
+                        seat_free(seat);
+                }
+        }
+
+        while ((session = m->session_gc_queue)) {
+                LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
+                session->in_gc_queue = false;
+
+                if (session_check_gc(session, drop_not_started) == 0) {
+                        session_stop(session);
+                        session_free(session);
+                }
+        }
+
+        while ((user = m->user_gc_queue)) {
+                LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
+                user->in_gc_queue = false;
+
+                if (user_check_gc(user, drop_not_started) == 0) {
+                        user_stop(user);
+                        user_free(user);
+                }
+        }
+}
+
+int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
+        Session *s;
+        bool idle_hint;
+        dual_timestamp ts = { 0, 0 };
+        Iterator i;
+
+        assert(m);
+
+        idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
+
+        HASHMAP_FOREACH(s, m->sessions, i) {
+                dual_timestamp k;
+                int ih;
+
+                ih = session_get_idle_hint(s, &k);
+                if (ih < 0)
+                        return ih;
+
+                if (!ih) {
+                        if (!idle_hint) {
+                                if (k.monotonic < ts.monotonic)
+                                        ts = k;
+                        } else {
+                                idle_hint = false;
+                                ts = k;
+                        }
+                } else if (idle_hint) {
+
+                        if (k.monotonic > ts.monotonic)
+                                ts = k;
+                }
+        }
+
+        if (t)
+                *t = ts;
+
+        return idle_hint;
+}
+
+int manager_dispatch_idle_action(Manager *m) {
+        struct dual_timestamp since;
+        struct itimerspec its;
+        int r;
+        usec_t n;
+
+        assert(m);
+
+        if (m->idle_action == HANDLE_IGNORE ||
+            m->idle_action_usec <= 0) {
+                r = 0;
+                goto finish;
+        }
+
+        zero(its);
+        n = now(CLOCK_MONOTONIC);
+
+        r = manager_get_idle_hint(m, &since);
+        if (r <= 0)
+                /* Not idle. Let's check if after a timeout it it might be idle then. */
+                timespec_store(&its.it_value, n + m->idle_action_usec);
+        else {
+                /* Idle! Let's see if it's time to do something, or if
+                 * we shall sleep for longer. */
+
+                if (n >= since.monotonic + m->idle_action_usec &&
+                    (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
+                        log_info("System idle. Taking action.");
+
+                        manager_handle_action(m, 0, m->idle_action, false, false);
+                        m->idle_action_not_before_usec = n;
+                }
+
+                timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
+        }
+
+        if (m->idle_action_fd < 0) {
+                struct epoll_event ev;
+
+                m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
+                if (m->idle_action_fd < 0) {
+                        log_error("Failed to create idle action timer: %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                zero(ev);
+                ev.events = EPOLLIN;
+                ev.data.u32 = FD_IDLE_ACTION;
+
+                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
+                        log_error("Failed to add idle action timer to epoll: %m");
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
+                log_error("Failed to reset timerfd: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        return 0;
+
+finish:
+        if (m->idle_action_fd >= 0) {
+                close_nointr_nofail(m->idle_action_fd);
+                m->idle_action_fd = -1;
+        }
+
+        return r;
+}
+int manager_startup(Manager *m) {
+        int r;
+        Seat *seat;
+        Session *session;
+        User *user;
+        Inhibitor *inhibitor;
+        Iterator i;
+
+        assert(m);
+        assert(m->epoll_fd <= 0);
+
+        cg_shorten_controllers(m->reset_controllers);
+        cg_shorten_controllers(m->controllers);
+
+        m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+        if (m->epoll_fd < 0)
+                return -errno;
+
+        /* Connect to console */
+        r = manager_connect_console(m);
+        if (r < 0)
+                return r;
+
+        /* Connect to udev */
+        r = manager_connect_udev(m);
+        if (r < 0)
+                return r;
+
+        /* Connect to the bus */
+        r = manager_connect_bus(m);
+        if (r < 0)
+                return r;
+
+        /* Instantiate magic seat 0 */
+        r = manager_add_seat(m, "seat0", &m->vtconsole);
+        if (r < 0)
+                return r;
+
+        /* Deserialize state */
+        manager_enumerate_devices(m);
+        manager_enumerate_seats(m);
+        manager_enumerate_users(m);
+        manager_enumerate_sessions(m);
+        manager_enumerate_inhibitors(m);
+        manager_enumerate_buttons(m);
+
+        /* Remove stale objects before we start them */
+        manager_gc(m, false);
+
+        /* Reserve the special reserved VT */
+        manager_reserve_vt(m);
+
+        /* And start everything */
+        HASHMAP_FOREACH(seat, m->seats, i)
+                seat_start(seat);
+
+        HASHMAP_FOREACH(user, m->users, i)
+                user_start(user);
+
+        HASHMAP_FOREACH(session, m->sessions, i)
+                session_start(session);
+
+        HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
+                inhibitor_start(inhibitor);
+
+        manager_dispatch_idle_action(m);
+
+        return 0;
+}
+
+static int manager_recheck_buttons(Manager *m) {
+        Iterator i;
+        Button *b;
+        int r = 0;
+
+        assert(m);
+
+        HASHMAP_FOREACH(b, m->buttons, i) {
+                int q;
+
+                q = button_recheck(b);
+                if (q > 0)
+                        return 1;
+                if (q < 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+int manager_run(Manager *m) {
+        assert(m);
+
+        for (;;) {
+                struct epoll_event event;
+                int n;
+                int msec = -1;
+
+                manager_gc(m, true);
+
+                if (manager_dispatch_delayed(m) > 0)
+                        continue;
+
+                if (manager_recheck_buttons(m) > 0)
+                        continue;
+
+                if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
+                        continue;
+
+                manager_gc(m, true);
+
+                if (m->delayed_unit) {
+                        usec_t x, y;
+
+                        x = now(CLOCK_MONOTONIC);
+                        y = m->delayed_timestamp + m->inhibit_delay_max;
+
+                        msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
+                }
+
+                n = epoll_wait(m->epoll_fd, &event, 1, msec);
+                if (n < 0) {
+                        if (errno == EINTR || errno == EAGAIN)
+                                continue;
+
+                        log_error("epoll() failed: %m");
+                        return -errno;
+                }
+
+                if (n == 0)
+                        continue;
+
+                switch (event.data.u32) {
+
+                case FD_SEAT_UDEV:
+                        manager_dispatch_seat_udev(m);
+                        break;
+
+                case FD_VCSA_UDEV:
+                        manager_dispatch_vcsa_udev(m);
+                        break;
+
+                case FD_BUTTON_UDEV:
+                        manager_dispatch_button_udev(m);
+                        break;
+
+                case FD_CONSOLE:
+                        manager_dispatch_console(m);
+                        break;
+
+                case FD_IDLE_ACTION:
+                        manager_dispatch_idle_action(m);
+                        break;
+
+                case FD_BUS:
+                        bus_loop_dispatch(m->bus_fd);
+                        break;
+
+                default:
+                        if (event.data.u32 >= FD_OTHER_BASE)
+                                manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
+                }
+        }
+
+        return 0;
+}
+
+static int manager_parse_config_file(Manager *m) {
+        FILE *f;
+        const char *fn;
+        int r;
+
+        assert(m);
+
+        fn = "/etc/systemd/logind.conf";
+        f = fopen(fn, "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_warning("Failed to open configuration file %s: %m", fn);
+                return -errno;
+        }
+
+        r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
+        if (r < 0)
+                log_warning("Failed to parse configuration file: %s", strerror(-r));
+
+        fclose(f);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        Manager *m = NULL;
+        int r;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_set_facility(LOG_AUTH);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argc != 1) {
+                log_error("This program takes no arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        m = manager_new();
+        if (!m) {
+                r = log_oom();
+                goto finish;
+        }
+
+        manager_parse_config_file(m);
+
+        r = manager_startup(m);
+        if (r < 0) {
+                log_error("Failed to fully start up daemon: %s", strerror(-r));
+                goto finish;
+        }
+
+        log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
+
+        sd_notify(false,
+                  "READY=1\n"
+                  "STATUS=Processing requests...");
+
+        r = manager_run(m);
+
+        log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
+
+finish:
+        sd_notify(false,
+                  "STATUS=Shutting down...");
+
+        if (m)
+                manager_free(m);
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/login/logind.conf b/src/login/logind.conf
new file mode 100644 (file)
index 0000000..0861d73
--- /dev/null
@@ -0,0 +1,28 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+# See logind.conf(5) for details
+
+[Login]
+#NAutoVTs=6
+#ReserveVT=6
+#KillUserProcesses=no
+#KillOnlyUsers=
+#KillExcludeUsers=root
+#Controllers=
+#ResetControllers=cpu
+#InhibitDelayMaxSec=5
+#HandlePowerKey=poweroff
+#HandleSuspendKey=suspend
+#HandleHibernateKey=hibernate
+#HandleLidSwitch=suspend
+#PowerKeyIgnoreInhibited=no
+#SuspendKeyIgnoreInhibited=no
+#HibernateKeyIgnoreInhibited=no
+#LidSwitchIgnoreInhibited=yes
+#IdleAction=ignore
+#IdleActionSec=30min
diff --git a/src/login/logind.h b/src/login/logind.h
new file mode 100644 (file)
index 0000000..816635d
--- /dev/null
@@ -0,0 +1,182 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <inttypes.h>
+#include <dbus/dbus.h>
+#include <libudev.h>
+
+#include "util.h"
+#include "audit.h"
+#include "list.h"
+#include "hashmap.h"
+#include "cgroup-util.h"
+
+typedef struct Manager Manager;
+
+#include "logind-device.h"
+#include "logind-seat.h"
+#include "logind-session.h"
+#include "logind-user.h"
+#include "logind-inhibit.h"
+#include "logind-button.h"
+#include "logind-action.h"
+
+struct Manager {
+        DBusConnection *bus;
+
+        Hashmap *devices;
+        Hashmap *seats;
+        Hashmap *sessions;
+        Hashmap *users;
+        Hashmap *inhibitors;
+        Hashmap *buttons;
+
+        LIST_HEAD(Seat, seat_gc_queue);
+        LIST_HEAD(Session, session_gc_queue);
+        LIST_HEAD(User, user_gc_queue);
+
+        struct udev *udev;
+        struct udev_monitor *udev_seat_monitor, *udev_vcsa_monitor, *udev_button_monitor;
+
+        int udev_seat_fd;
+        int udev_vcsa_fd;
+        int udev_button_fd;
+
+        int console_active_fd;
+        int bus_fd;
+        int epoll_fd;
+
+        unsigned n_autovts;
+
+        unsigned reserve_vt;
+        int reserve_vt_fd;
+
+        Seat *vtconsole;
+
+        char *cgroup_path;
+        char **controllers, **reset_controllers;
+
+        char **kill_only_users, **kill_exclude_users;
+
+        bool kill_user_processes;
+
+        unsigned long session_counter;
+        unsigned long inhibit_counter;
+
+        Hashmap *session_cgroups;
+        Hashmap *user_cgroups;
+
+        Hashmap *session_fds;
+        Hashmap *inhibitor_fds;
+        Hashmap *button_fds;
+
+        /* If a shutdown was delayed due to a inhibitor this contains
+           the unit name we are supposed to start after the delay is
+           over */
+        const char *delayed_unit;
+        InhibitWhat delayed_what;
+        usec_t delayed_timestamp;
+
+        usec_t inhibit_delay_max;
+
+        int idle_action_fd;
+        usec_t idle_action_usec;
+        usec_t idle_action_not_before_usec;
+        HandleAction idle_action;
+
+        HandleAction handle_power_key;
+        HandleAction handle_suspend_key;
+        HandleAction handle_hibernate_key;
+        HandleAction handle_lid_switch;
+
+        bool power_key_ignore_inhibited;
+        bool suspend_key_ignore_inhibited;
+        bool hibernate_key_ignore_inhibited;
+        bool lid_switch_ignore_inhibited;
+};
+
+enum {
+        FD_SEAT_UDEV,
+        FD_VCSA_UDEV,
+        FD_BUTTON_UDEV,
+        FD_CONSOLE,
+        FD_BUS,
+        FD_IDLE_ACTION,
+        FD_OTHER_BASE
+};
+
+Manager *manager_new(void);
+void manager_free(Manager *m);
+
+int manager_add_device(Manager *m, const char *sysfs, Device **_device);
+int manager_add_button(Manager *m, const char *name, Button **_button);
+int manager_add_seat(Manager *m, const char *id, Seat **_seat);
+int manager_add_session(Manager *m, User *u, const char *id, Session **_session);
+int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user);
+int manager_add_user_by_name(Manager *m, const char *name, User **_user);
+int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user);
+int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor);
+
+int manager_process_seat_device(Manager *m, struct udev_device *d);
+int manager_process_button_device(Manager *m, struct udev_device *d);
+
+int manager_dispatch_seat_udev(Manager *m);
+int manager_dispatch_vcsa_udev(Manager *m);
+int manager_dispatch_button_udev(Manager *m);
+int manager_dispatch_console(Manager *m);
+int manager_dispatch_idle_action(Manager *m);
+
+int manager_enumerate_devices(Manager *m);
+int manager_enumerate_buttons(Manager *m);
+int manager_enumerate_seats(Manager *m);
+int manager_enumerate_sessions(Manager *m);
+int manager_enumerate_users(Manager *m);
+int manager_enumerate_inhibitors(Manager *m);
+
+int manager_startup(Manager *m);
+int manager_run(Manager *m);
+int manager_spawn_autovt(Manager *m, int vtnr);
+
+void manager_cgroup_notify_empty(Manager *m, const char *cgroup);
+
+void manager_gc(Manager *m, bool drop_not_started);
+
+int manager_get_idle_hint(Manager *m, dual_timestamp *t);
+
+int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user);
+int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session);
+int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
+
+extern const DBusObjectPathVTable bus_manager_vtable;
+
+DBusHandlerResult bus_message_filter(DBusConnection *c, DBusMessage *message, void *userdata);
+
+int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name, InhibitWhat w, DBusError *error);
+
+int manager_send_changed(Manager *manager, const char *properties);
+
+int manager_dispatch_delayed(Manager *manager);
+
+/* gperf lookup function */
+const struct ConfigPerfItem* logind_gperf_lookup(const char *key, unsigned length);
diff --git a/src/login/multi-seat-x.c b/src/login/multi-seat-x.c
new file mode 100644 (file)
index 0000000..83760d4
--- /dev/null
@@ -0,0 +1,108 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "mkdir.h"
+
+int main(int argc, char *argv[]) {
+
+        int i;
+        const char *seat = NULL;
+        char **new_argv;
+        _cleanup_free_ char *path = NULL;
+        int r;
+        _cleanup_fclose_ FILE *f = NULL;
+
+        /* This binary will go away as soon as X natively takes the
+         * arguments in question as command line parameters, instead
+         * of requiring them in the configuration file. */
+
+        /* If this file is removed, don't forget to remove the code
+         * that invokes this in gdm and other display managers. */
+
+        for (i = 1; i < argc; i++)
+                if (streq(argv[i], "-seat"))
+                        seat = argv[i+1];
+
+        if (isempty(seat) || streq(seat, "seat0")) {
+                argv[0] = (char*) X_SERVER;
+                execv(X_SERVER, argv);
+                log_error("Failed to execute real X server: %m");
+                goto fail;
+        }
+
+        r = mkdir_safe_label("/run/systemd/multi-session-x", 0755, 0, 0);
+        if (r < 0) {
+                log_error("Failed to create directory: %s", strerror(-r));
+                goto fail;
+        }
+
+        path = strappend("/run/systemd/multi-session-x/", seat);
+        if (!path) {
+                log_oom();
+                goto fail;
+        }
+
+        f = fopen(path, "we");
+        if (!f) {
+                log_error("Failed to write configuration file: %m");
+                goto fail;
+        }
+
+        fprintf(f,
+                "Section \"ServerFlags\"\n"
+                "        Option \"AutoAddDevices\" \"True\"\n"
+                "        Option \"AllowEmptyInput\" \"True\"\n"
+                "        Option \"DontVTSwitch\" \"True\"\n"
+                "EndSection\n"
+                "Section \"InputClass\"\n"
+                "        Identifier \"Force Input Devices to Seat\"\n"
+                "        Option \"GrabDevice\" \"True\"\n"
+                "EndSection\n");
+
+        fflush(f);
+
+        if (ferror(f)) {
+                log_error("Failed to write configuration file: %m");
+                goto fail;
+        }
+
+        fclose(f);
+        f = NULL;
+
+        new_argv = newa(char*, argc + 3 + 1);
+        memcpy(new_argv, argv, sizeof(char*) * (argc + 2 + 1));
+
+        new_argv[0] = (char*) X_SERVER;
+        new_argv[argc+0] = (char*) "-config";
+        new_argv[argc+1] = path;
+        new_argv[argc+2] = (char*) "-sharevts";
+        new_argv[argc+3] = NULL;
+
+        execv(X_SERVER, new_argv);
+        log_error("Failed to execute real X server: %m");
+
+fail:
+        return EXIT_FAILURE;
+}
diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf
new file mode 100644 (file)
index 0000000..6c1f2f5
--- /dev/null
@@ -0,0 +1,150 @@
+<?xml version="1.0"?> <!--*-nxml-*-->
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<busconfig>
+
+        <policy user="root">
+                <allow own="org.freedesktop.login1"/>
+                <allow send_destination="org.freedesktop.login1"/>
+                <allow receive_sender="org.freedesktop.login1"/>
+        </policy>
+
+        <policy context="default">
+                <deny send_destination="org.freedesktop.login1"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.DBus.Introspectable"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.DBus.Peer"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.DBus.Properties"
+                       send_member="Get"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.DBus.Properties"
+                       send_member="GetAll"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="GetSession"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="GetSessionByPID"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="GetUser"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="GetSeat"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="ListSessions"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="ListUsers"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="ListSeats"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="ListInhibitors"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="Inhibit"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="SetUserLinger"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="ActivateSession"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="ActivateSessionOnSeat"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="PowerOff"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="Reboot"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="Suspend"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="Hibernate"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="HybridSleep"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="CanPowerOff"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="CanReboot"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="CanSuspend"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="CanHibernate"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="CanHybridSleep"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="AttachDevice"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Manager"
+                       send_member="FlushDevices"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Seat"
+                       send_member="ActivateSession"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Session"
+                       send_member="Activate"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Session"
+                       send_member="SetIdleHint"/>
+
+                <allow receive_sender="org.freedesktop.login1"/>
+        </policy>
+
+</busconfig>
diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in
new file mode 100644 (file)
index 0000000..b5f5db4
--- /dev/null
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<policyconfig>
+
+        <vendor>The systemd Project</vendor>
+        <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
+
+        <action id="org.freedesktop.login1.inhibit-block-shutdown">
+                <_description>Allow applications to inhibit system shutdown</_description>
+                <_message>Authentication is required to allow an application to inhibit system shutdown.</_message>
+                <defaults>
+                        <allow_any>no</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.inhibit-delay-shutdown org.freedesktop.login1.inhibit-block-sleep org.freedesktop.login1.inhibit-delay-sleep org.freedesktop.login1.inhibit-block-idle</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.inhibit-delay-shutdown">
+                <_description>Allow applications to delay system shutdown</_description>
+                <_message>Authentication is required to allow an application to delay system shutdown.</_message>
+                <defaults>
+                        <allow_any>yes</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.inhibit-delay-sleep</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.inhibit-block-sleep">
+                <_description>Allow applications to inhibit system sleep</_description>
+                <_message>Authentication is required to allow an application to inhibit system sleep.</_message>
+                <defaults>
+                        <allow_any>no</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.inhibit-delay-sleep org.freedesktop.login1.inhibit-block-idle</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.inhibit-delay-sleep">
+                <_description>Allow applications to delay system sleep</_description>
+                <_message>Authentication is required to allow an application to delay system sleep.</_message>
+                <defaults>
+                        <allow_any>yes</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.inhibit-block-idle">
+                <_description>Allow applications to inhibit automatic system suspend</_description>
+                <_message>Authentication is required to allow an application to inhibit automatic system suspend.</_message>
+                <defaults>
+                        <allow_any>yes</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.inhibit-handle-power-key">
+                <_description>Allow applications to inhibit system handling of the power key</_description>
+                <_message>Authentication is required to allow an application to inhibit system handling of the power key.</_message>
+                <defaults>
+                        <allow_any>no</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.inhibit-handle-suspend-key org.freedesktop.login1.inhibit-handle-hibernate-key org.freedesktop.login1.inhibit-handle-lid-switch</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.inhibit-handle-suspend-key">
+                <_description>Allow applications to inhibit system handling of the suspend key</_description>
+                <_message>Authentication is required to allow an application to inhibit system handling of the suspend key.</_message>
+                <defaults>
+                        <allow_any>no</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.inhibit-handle-hibernate-key org.freedesktop.login1.inhibit-handle-lid-switch</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.inhibit-handle-hibernate-key">
+                <_description>Allow applications to inhibit system handling of the hibernate key</_description>
+                <_message>Authentication is required to allow an application to inhibit system handling of the hibernate key.</_message>
+                <defaults>
+                        <allow_any>no</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.inhibit-handle-lid-switch">
+                <_description>Allow applications to inhibit system handling of the lid switch</_description>
+                <_message>Authentication is required to allow an application to inhibit system handling of the lid switch.</_message>
+                <defaults>
+                        <allow_any>no</allow_any>
+                        <allow_inactive>yes</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.set-user-linger">
+                <_description>Allow non-logged-in users to run programs</_description>
+                <_message>Authentication is required to allow a non-logged-in user to run programs.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.attach-device">
+                <_description>Allow attaching devices to seats</_description>
+                <_message>Authentication is required for attaching a device to a seat.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.flush-devices</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.flush-devices">
+                <_description>Flush device to seat attachments</_description>
+                <_message>Authentication is required for resetting how devices are attached to seats.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.power-off">
+                <_description>Power off the system</_description>
+                <_message>Authentication is required for powering off the system.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.power-off-multiple-sessions">
+                <_description>Power off the system while other users are logged in</_description>
+                <_message>Authentication is required for powering off the system while other users are logged in.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.power-off</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.power-off-ignore-inhibit">
+                <_description>Power off the system while an application asked to inhibit it</_description>
+                <_message>Authentication is required for powering off the system while an application asked to inhibit it.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.power-off</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.reboot">
+                <_description>Reboot the system</_description>
+                <_message>Authentication is required for rebooting the system.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.reboot-multiple-sessions">
+                <_description>Reboot the system while other users are logged in</_description>
+                <_message>Authentication is required for rebooting the system while other users are logged in.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.reboot</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.reboot-ignore-inhibit">
+                <_description>Reboot the system while an application asked to inhibit it</_description>
+                <_message>Authentication is required for rebooting the system while an application asked to inhibit it.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.reboot</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.suspend">
+                <_description>Suspend the system</_description>
+                <_message>Authentication is required for suspending the system.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.suspend-multiple-sessions">
+                <_description>Suspend the system while other users are logged in</_description>
+                <_message>Authentication is required for suspending the system while other users are logged in.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.suspend</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.suspend-ignore-inhibit">
+                <_description>Suspend the system while an application asked to inhibit it</_description>
+                <_message>Authentication is required for suspending the system while an application asked to inhibit it.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.suspend</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.hibernate">
+                <_description>Hibernate the system</_description>
+                <_message>Authentication is required for hibernating the system.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>yes</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.login1.hibernate-multiple-sessions">
+                <_description>Hibernate the system while other users are logged in</_description>
+                <_message>Authentication is required for hibernating the system while other users are logged in.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.hibernate</annotate>
+        </action>
+
+        <action id="org.freedesktop.login1.hibernate-ignore-inhibit">
+                <_description>Hibernate the system while an application asked to inhibit it</_description>
+                <_message>Authentication is required for hibernating the system while an application asked to inhibit it.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.hibernate</annotate>
+        </action>
+
+</policyconfig>
diff --git a/src/login/org.freedesktop.login1.service b/src/login/org.freedesktop.login1.service
new file mode 100644 (file)
index 0000000..762dae2
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[D-BUS Service]
+Name=org.freedesktop.login1
+Exec=/bin/false
+User=root
+SystemdService=dbus-org.freedesktop.login1.service
diff --git a/src/login/pam-module.c b/src/login/pam-module.c
new file mode 100644 (file)
index 0000000..88b0ef9
--- /dev/null
@@ -0,0 +1,733 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <pwd.h>
+#include <endian.h>
+#include <sys/capability.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include <security/pam_misc.h>
+
+#include <systemd/sd-daemon.h>
+
+#include "util.h"
+#include "audit.h"
+#include "macro.h"
+#include "strv.h"
+#include "dbus-common.h"
+#include "def.h"
+#include "socket-util.h"
+
+static int parse_argv(pam_handle_t *handle,
+                      int argc, const char **argv,
+                      char ***controllers,
+                      char ***reset_controllers,
+                      bool *kill_processes,
+                      char ***kill_only_users,
+                      char ***kill_exclude_users,
+                      const char **class,
+                      bool *debug) {
+
+        unsigned i;
+
+        assert(argc >= 0);
+        assert(argc == 0 || argv);
+
+        for (i = 0; i < (unsigned) argc; i++) {
+                int k;
+
+                if (startswith(argv[i], "kill-session-processes=")) {
+                        if ((k = parse_boolean(argv[i] + 23)) < 0) {
+                                pam_syslog(handle, LOG_ERR, "Failed to parse kill-session-processes= argument.");
+                                return k;
+                        }
+
+                        if (kill_processes)
+                                *kill_processes = k;
+
+                } else if (startswith(argv[i], "kill-session=")) {
+                        /* As compatibility for old versions */
+
+                        if ((k = parse_boolean(argv[i] + 13)) < 0) {
+                                pam_syslog(handle, LOG_ERR, "Failed to parse kill-session= argument.");
+                                return k;
+                        }
+
+                        if (kill_processes)
+                                *kill_processes = k;
+
+                } else if (startswith(argv[i], "controllers=")) {
+
+                        if (controllers) {
+                                char **l;
+
+                                if (!(l = strv_split(argv[i] + 12, ","))) {
+                                        pam_syslog(handle, LOG_ERR, "Out of memory.");
+                                        return -ENOMEM;
+                                }
+
+                                strv_free(*controllers);
+                                *controllers = l;
+                        }
+
+                } else if (startswith(argv[i], "reset-controllers=")) {
+
+                        if (reset_controllers) {
+                                char **l;
+
+                                if (!(l = strv_split(argv[i] + 18, ","))) {
+                                        pam_syslog(handle, LOG_ERR, "Out of memory.");
+                                        return -ENOMEM;
+                                }
+
+                                strv_free(*reset_controllers);
+                                *reset_controllers = l;
+                        }
+
+                } else if (startswith(argv[i], "kill-only-users=")) {
+
+                        if (kill_only_users) {
+                                char **l;
+
+                                if (!(l = strv_split(argv[i] + 16, ","))) {
+                                        pam_syslog(handle, LOG_ERR, "Out of memory.");
+                                        return -ENOMEM;
+                                }
+
+                                strv_free(*kill_only_users);
+                                *kill_only_users = l;
+                        }
+
+                } else if (startswith(argv[i], "kill-exclude-users=")) {
+
+                        if (kill_exclude_users) {
+                                char **l;
+
+                                if (!(l = strv_split(argv[i] + 19, ","))) {
+                                        pam_syslog(handle, LOG_ERR, "Out of memory.");
+                                        return -ENOMEM;
+                                }
+
+                                strv_free(*kill_exclude_users);
+                                *kill_exclude_users = l;
+                        }
+
+                } else if (startswith(argv[i], "class=")) {
+
+                        if (class)
+                                *class = argv[i] + 6;
+
+                } else if (startswith(argv[i], "debug=")) {
+                        if ((k = parse_boolean(argv[i] + 6)) < 0) {
+                                pam_syslog(handle, LOG_ERR, "Failed to parse debug= argument.");
+                                return k;
+                        }
+
+                        if (debug)
+                                *debug = k;
+
+                } else if (startswith(argv[i], "create-session=") ||
+                           startswith(argv[i], "kill-user=")) {
+
+                        pam_syslog(handle, LOG_WARNING, "Option %s not supported anymore, ignoring.", argv[i]);
+
+                } else {
+                        pam_syslog(handle, LOG_ERR, "Unknown parameter '%s'.", argv[i]);
+                        return -EINVAL;
+                }
+        }
+
+        return 0;
+}
+
+static int get_user_data(
+                pam_handle_t *handle,
+                const char **ret_username,
+                struct passwd **ret_pw) {
+
+        const char *username = NULL;
+        struct passwd *pw = NULL;
+        uid_t uid;
+        int r;
+
+        assert(handle);
+        assert(ret_username);
+        assert(ret_pw);
+
+        r = audit_loginuid_from_pid(0, &uid);
+        if (r >= 0)
+                pw = pam_modutil_getpwuid(handle, uid);
+        else {
+                r = pam_get_user(handle, &username, NULL);
+                if (r != PAM_SUCCESS) {
+                        pam_syslog(handle, LOG_ERR, "Failed to get user name.");
+                        return r;
+                }
+
+                if (isempty(username)) {
+                        pam_syslog(handle, LOG_ERR, "User name not valid.");
+                        return PAM_AUTH_ERR;
+                }
+
+                pw = pam_modutil_getpwnam(handle, username);
+        }
+
+        if (!pw) {
+                pam_syslog(handle, LOG_ERR, "Failed to get user data.");
+                return PAM_USER_UNKNOWN;
+        }
+
+        *ret_pw = pw;
+        *ret_username = username ? username : pw->pw_name;
+
+        return PAM_SUCCESS;
+}
+
+static bool check_user_lists(
+                pam_handle_t *handle,
+                uid_t uid,
+                char **kill_only_users,
+                char **kill_exclude_users) {
+
+        const char *name = NULL;
+        char **l;
+
+        assert(handle);
+
+        if (uid == 0)
+                name = "root"; /* Avoid obvious NSS requests, to suppress network traffic */
+        else {
+                struct passwd *pw;
+
+                pw = pam_modutil_getpwuid(handle, uid);
+                if (pw)
+                        name = pw->pw_name;
+        }
+
+        STRV_FOREACH(l, kill_exclude_users) {
+                uid_t u;
+
+                if (parse_uid(*l, &u) >= 0)
+                        if (u == uid)
+                                return false;
+
+                if (name && streq(name, *l))
+                        return false;
+        }
+
+        if (strv_isempty(kill_only_users))
+                return true;
+
+        STRV_FOREACH(l, kill_only_users) {
+                uid_t u;
+
+                if (parse_uid(*l, &u) >= 0)
+                        if (u == uid)
+                                return true;
+
+                if (name && streq(name, *l))
+                        return true;
+        }
+
+        return false;
+}
+
+static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) {
+        char *p = NULL;
+        int r;
+        int fd;
+        union sockaddr_union sa;
+        struct ucred ucred;
+        socklen_t l;
+        char *tty;
+        int v;
+
+        assert(display);
+        assert(vtnr);
+
+        /* We deduce the X11 socket from the display name, then use
+         * SO_PEERCRED to determine the X11 server process, ask for
+         * the controlling tty of that and if it's a VC then we know
+         * the seat and the virtual terminal. Sounds ugly, is only
+         * semi-ugly. */
+
+        r = socket_from_display(display, &p);
+        if (r < 0)
+                return r;
+
+        fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
+        if (fd < 0) {
+                free(p);
+                return -errno;
+        }
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, p, sizeof(sa.un.sun_path)-1);
+        free(p);
+
+        if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        l = sizeof(ucred);
+        r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l);
+        close_nointr_nofail(fd);
+
+        if (r < 0)
+                return -errno;
+
+        r = get_ctty(ucred.pid, NULL, &tty);
+        if (r < 0)
+                return r;
+
+        v = vtnr_from_tty(tty);
+        free(tty);
+
+        if (v < 0)
+                return v;
+        else if (v == 0)
+                return -ENOENT;
+
+        if (seat)
+                *seat = "seat0";
+        *vtnr = (uint32_t) v;
+
+        return 0;
+}
+
+_public_ PAM_EXTERN int pam_sm_open_session(
+                pam_handle_t *handle,
+                int flags,
+                int argc, const char **argv) {
+
+        struct passwd *pw;
+        bool kill_processes = false, debug = false;
+        const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type = NULL, *class = NULL, *class_pam = NULL, *cvtnr = NULL;
+        char **controllers = NULL, **reset_controllers = NULL, **kill_only_users = NULL, **kill_exclude_users = NULL;
+        DBusError error;
+        uint32_t uid, pid;
+        DBusMessageIter iter;
+        dbus_bool_t kp;
+        int session_fd = -1;
+        DBusConnection *bus = NULL;
+        DBusMessage *m = NULL, *reply = NULL;
+        dbus_bool_t remote, existing;
+        int r;
+        uint32_t vtnr = 0;
+
+        assert(handle);
+
+        dbus_error_init(&error);
+
+        /* pam_syslog(handle, LOG_INFO, "pam-systemd initializing"); */
+
+        /* Make this a NOP on non-systemd systems */
+        if (sd_booted() <= 0)
+                return PAM_SUCCESS;
+
+        if (parse_argv(handle,
+                       argc, argv,
+                       &controllers, &reset_controllers,
+                       &kill_processes, &kill_only_users, &kill_exclude_users,
+                       &class_pam, &debug) < 0) {
+                r = PAM_SESSION_ERR;
+                goto finish;
+        }
+
+        r = get_user_data(handle, &username, &pw);
+        if (r != PAM_SUCCESS)
+                goto finish;
+
+        /* Make sure we don't enter a loop by talking to
+         * systemd-logind when it is actually waiting for the
+         * background to finish start-up. If the service is
+         * "systemd-shared" we simply set XDG_RUNTIME_DIR and
+         * leave. */
+
+        pam_get_item(handle, PAM_SERVICE, (const void**) &service);
+        if (streq_ptr(service, "systemd-shared")) {
+                char *p, *rt = NULL;
+
+                if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) pw->pw_uid) < 0) {
+                        r = PAM_BUF_ERR;
+                        goto finish;
+                }
+
+                r = parse_env_file(p, NEWLINE,
+                                   "RUNTIME", &rt,
+                                   NULL);
+                free(p);
+
+                if (r < 0 && r != -ENOENT) {
+                        r = PAM_SESSION_ERR;
+                        free(rt);
+                        goto finish;
+                }
+
+                if (rt)  {
+                        r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0);
+                        free(rt);
+
+                        if (r != PAM_SUCCESS) {
+                                pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
+                                goto finish;
+                        }
+                }
+
+                r = PAM_SUCCESS;
+                goto finish;
+        }
+
+        if (kill_processes)
+                kill_processes = check_user_lists(handle, pw->pw_uid, kill_only_users, kill_exclude_users);
+
+        dbus_connection_set_change_sigpipe(FALSE);
+
+        bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        if (!bus) {
+                pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", bus_error_message(&error));
+                r = PAM_SESSION_ERR;
+                goto finish;
+        }
+
+        m = dbus_message_new_method_call(
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "CreateSession");
+        if (!m) {
+                pam_syslog(handle, LOG_ERR, "Could not allocate create session message.");
+                r = PAM_BUF_ERR;
+                goto finish;
+        }
+
+        uid = pw->pw_uid;
+        pid = getpid();
+
+        pam_get_item(handle, PAM_XDISPLAY, (const void**) &display);
+        pam_get_item(handle, PAM_TTY, (const void**) &tty);
+        pam_get_item(handle, PAM_RUSER, (const void**) &remote_user);
+        pam_get_item(handle, PAM_RHOST, (const void**) &remote_host);
+
+        seat = pam_getenv(handle, "XDG_SEAT");
+        if (isempty(seat))
+                seat = getenv("XDG_SEAT");
+
+        cvtnr = pam_getenv(handle, "XDG_VTNR");
+        if (isempty(cvtnr))
+                cvtnr = getenv("XDG_VTNR");
+
+        service = strempty(service);
+        tty = strempty(tty);
+        display = strempty(display);
+        remote_user = strempty(remote_user);
+        remote_host = strempty(remote_host);
+        seat = strempty(seat);
+
+        if (strchr(tty, ':')) {
+                /* A tty with a colon is usually an X11 display, place
+                 * there to show up in utmp. We rearrange things and
+                 * don't pretend that an X display was a tty */
+
+                if (isempty(display))
+                        display = tty;
+                tty = "";
+        } else if (streq(tty, "cron")) {
+                /* cron has been setting PAM_TTY to "cron" for a very
+                 * long time and it probably shouldn't stop doing that
+                 * for compatibility reasons. */
+                tty = "";
+                type = "unspecified";
+        } else if (streq(tty, "ssh")) {
+                /* ssh has been setting PAM_TTY to "ssh" for a very
+                 * long time and probably shouldn't stop doing that
+                 * for compatibility reasons. */
+                tty = "";
+                type ="tty";
+        }
+
+        /* If this fails vtnr will be 0, that's intended */
+        if (!isempty(cvtnr))
+                safe_atou32(cvtnr, &vtnr);
+
+        if (!isempty(display) && vtnr <= 0) {
+                if (isempty(seat))
+                        get_seat_from_display(display, &seat, &vtnr);
+                else if (streq(seat, "seat0"))
+                        get_seat_from_display(display, NULL, &vtnr);
+        }
+
+        if (!type)
+                type = !isempty(display) ? "x11" :
+                        !isempty(tty) ? "tty" : "unspecified";
+
+        class = pam_getenv(handle, "XDG_SESSION_CLASS");
+        if (isempty(class))
+                class = getenv("XDG_SESSION_CLASS");
+        if (isempty(class))
+                class = class_pam;
+        if (isempty(class))
+                class = "user";
+
+        remote = !isempty(remote_host) &&
+                !streq(remote_host, "localhost") &&
+                !streq(remote_host, "localhost.localdomain");
+
+        if (!dbus_message_append_args(m,
+                                      DBUS_TYPE_UINT32, &uid,
+                                      DBUS_TYPE_UINT32, &pid,
+                                      DBUS_TYPE_STRING, &service,
+                                      DBUS_TYPE_STRING, &type,
+                                      DBUS_TYPE_STRING, &class,
+                                      DBUS_TYPE_STRING, &seat,
+                                      DBUS_TYPE_UINT32, &vtnr,
+                                      DBUS_TYPE_STRING, &tty,
+                                      DBUS_TYPE_STRING, &display,
+                                      DBUS_TYPE_BOOLEAN, &remote,
+                                      DBUS_TYPE_STRING, &remote_user,
+                                      DBUS_TYPE_STRING, &remote_host,
+                                      DBUS_TYPE_INVALID)) {
+                pam_syslog(handle, LOG_ERR, "Could not attach parameters to message.");
+                r = PAM_BUF_ERR;
+                goto finish;
+        }
+
+        dbus_message_iter_init_append(m, &iter);
+
+        r = bus_append_strv_iter(&iter, controllers);
+        if (r < 0) {
+                pam_syslog(handle, LOG_ERR, "Could not attach parameter to message.");
+                r = PAM_BUF_ERR;
+                goto finish;
+        }
+
+        r = bus_append_strv_iter(&iter, reset_controllers);
+        if (r < 0) {
+                pam_syslog(handle, LOG_ERR, "Could not attach parameter to message.");
+                r = PAM_BUF_ERR;
+                goto finish;
+        }
+
+        kp = kill_processes;
+        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &kp)) {
+                pam_syslog(handle, LOG_ERR, "Could not attach parameter to message.");
+                r = PAM_BUF_ERR;
+                goto finish;
+        }
+
+        if (debug)
+                pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: "
+                           "uid=%u pid=%u service=%s type=%s class=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s",
+                           uid, pid, service, type, class, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host);
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+        if (!reply) {
+                pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error));
+                r = PAM_SESSION_ERR;
+                goto finish;
+        }
+
+        if (!dbus_message_get_args(reply, &error,
+                                   DBUS_TYPE_STRING, &id,
+                                   DBUS_TYPE_OBJECT_PATH, &object_path,
+                                   DBUS_TYPE_STRING, &runtime_path,
+                                   DBUS_TYPE_UNIX_FD, &session_fd,
+                                   DBUS_TYPE_STRING, &seat,
+                                   DBUS_TYPE_UINT32, &vtnr,
+                                   DBUS_TYPE_BOOLEAN, &existing,
+                                   DBUS_TYPE_INVALID)) {
+                pam_syslog(handle, LOG_ERR, "Failed to parse message: %s", bus_error_message(&error));
+                r = PAM_SESSION_ERR;
+                goto finish;
+        }
+
+        if (debug)
+                pam_syslog(handle, LOG_DEBUG, "Reply from logind: "
+                           "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u",
+                           id, object_path, runtime_path, session_fd, seat, vtnr);
+
+        r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0);
+        if (r != PAM_SUCCESS) {
+                pam_syslog(handle, LOG_ERR, "Failed to set session id.");
+                goto finish;
+        }
+
+        r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0);
+        if (r != PAM_SUCCESS) {
+                pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
+                goto finish;
+        }
+
+        if (!isempty(seat)) {
+                r = pam_misc_setenv(handle, "XDG_SEAT", seat, 0);
+                if (r != PAM_SUCCESS) {
+                        pam_syslog(handle, LOG_ERR, "Failed to set seat.");
+                        goto finish;
+                }
+        }
+
+        if (vtnr > 0) {
+                char buf[11];
+                snprintf(buf, sizeof(buf), "%u", vtnr);
+                char_array_0(buf);
+
+                r = pam_misc_setenv(handle, "XDG_VTNR", buf, 0);
+                if (r != PAM_SUCCESS) {
+                        pam_syslog(handle, LOG_ERR, "Failed to set virtual terminal number.");
+                        goto finish;
+                }
+        }
+
+        r = pam_set_data(handle, "systemd.existing", INT_TO_PTR(!!existing), NULL);
+        if (r != PAM_SUCCESS) {
+                pam_syslog(handle, LOG_ERR, "Failed to install existing flag.");
+                return r;
+        }
+
+        if (session_fd >= 0) {
+                r = pam_set_data(handle, "systemd.session-fd", INT_TO_PTR(session_fd+1), NULL);
+                if (r != PAM_SUCCESS) {
+                        pam_syslog(handle, LOG_ERR, "Failed to install session fd.");
+                        return r;
+                }
+        }
+
+        session_fd = -1;
+
+        r = PAM_SUCCESS;
+
+finish:
+        strv_free(controllers);
+        strv_free(reset_controllers);
+        strv_free(kill_only_users);
+        strv_free(kill_exclude_users);
+
+        dbus_error_free(&error);
+
+        if (bus) {
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        if (session_fd >= 0)
+                close_nointr_nofail(session_fd);
+
+        return r;
+}
+
+_public_ PAM_EXTERN int pam_sm_close_session(
+                pam_handle_t *handle,
+                int flags,
+                int argc, const char **argv) {
+
+        const void *p = NULL, *existing = NULL;
+        const char *id;
+        DBusConnection *bus = NULL;
+        DBusMessage *m = NULL, *reply = NULL;
+        DBusError error;
+        int r;
+
+        assert(handle);
+
+        dbus_error_init(&error);
+
+        /* Only release session if it wasn't pre-existing when we
+         * tried to create it */
+        pam_get_data(handle, "systemd.existing", &existing);
+
+        id = pam_getenv(handle, "XDG_SESSION_ID");
+        if (id && !existing) {
+
+                /* Before we go and close the FIFO we need to tell
+                 * logind that this is a clean session shutdown, so
+                 * that it doesn't just go and slaughter us
+                 * immediately after closing the fd */
+
+                bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+                if (!bus) {
+                        pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", bus_error_message(&error));
+                        r = PAM_SESSION_ERR;
+                        goto finish;
+                }
+
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                "ReleaseSession");
+                if (!m) {
+                        pam_syslog(handle, LOG_ERR, "Could not allocate release session message.");
+                        r = PAM_BUF_ERR;
+                        goto finish;
+                }
+
+                if (!dbus_message_append_args(m,
+                                              DBUS_TYPE_STRING, &id,
+                                              DBUS_TYPE_INVALID)) {
+                        pam_syslog(handle, LOG_ERR, "Could not attach parameters to message.");
+                        r = PAM_BUF_ERR;
+                        goto finish;
+                }
+
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+                if (!reply) {
+                        pam_syslog(handle, LOG_ERR, "Failed to release session: %s", bus_error_message(&error));
+                        r = PAM_SESSION_ERR;
+                        goto finish;
+                }
+        }
+
+        r = PAM_SUCCESS;
+
+finish:
+        pam_get_data(handle, "systemd.session-fd", &p);
+        if (p)
+                close_nointr(PTR_TO_INT(p) - 1);
+
+        dbus_error_free(&error);
+
+        if (bus) {
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
diff --git a/src/login/sd-login.c b/src/login/sd-login.c
new file mode 100644 (file)
index 0000000..45e3bb8
--- /dev/null
@@ -0,0 +1,794 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/inotify.h>
+
+#include "util.h"
+#include "cgroup-util.h"
+#include "macro.h"
+#include "sd-login.h"
+#include "strv.h"
+
+_public_ int sd_pid_get_session(pid_t pid, char **session) {
+        int r;
+        char *cgroup, *p;
+
+        if (pid < 0)
+                return -EINVAL;
+
+        if (!session)
+                return -EINVAL;
+
+        r = cg_pid_get_cgroup(pid, NULL, &cgroup);
+        if (r < 0)
+                return r;
+
+        if (!startswith(cgroup, "/user/")) {
+                free(cgroup);
+                return -ENOENT;
+        }
+
+        p = strchr(cgroup + 6, '/');
+        if (!p) {
+                free(cgroup);
+                return -ENOENT;
+        }
+
+        p++;
+        if (startswith(p, "shared/") || streq(p, "shared")) {
+                free(cgroup);
+                return -ENOENT;
+        }
+
+        p = strndup(p, strcspn(p, "/"));
+        free(cgroup);
+
+        if (!p)
+                return -ENOMEM;
+
+        *session = p;
+        return 0;
+}
+
+_public_ int sd_pid_get_unit(pid_t pid, char **unit) {
+
+        if (pid < 0)
+                return -EINVAL;
+
+        if (!unit)
+                return -EINVAL;
+
+        return cg_pid_get_unit(pid, unit);
+}
+
+_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
+        int r;
+        char *root, *cgroup, *p, *cc;
+        struct stat st;
+
+        if (pid < 0)
+                return -EINVAL;
+
+        if (!uid)
+                return -EINVAL;
+
+        r = cg_pid_get_cgroup(pid, &root, &cgroup);
+        if (r < 0)
+                return r;
+
+        if (!startswith(cgroup, "/user/")) {
+                free(cgroup);
+                free(root);
+                return -ENOENT;
+        }
+
+        p = strchr(cgroup + 6, '/');
+        if (!p) {
+                free(cgroup);
+                return -ENOENT;
+        }
+
+        p++;
+        p += strcspn(p, "/");
+        *p = 0;
+
+        r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, cgroup, &cc);
+        free(root);
+        free(cgroup);
+
+        if (r < 0)
+                return -ENOMEM;
+
+        r = lstat(cc, &st);
+        free(cc);
+
+        if (r < 0)
+                return -errno;
+
+        if (!S_ISDIR(st.st_mode))
+                return -ENOTDIR;
+
+        *uid = st.st_uid;
+        return 0;
+}
+
+_public_ int sd_uid_get_state(uid_t uid, char**state) {
+        char *p, *s = NULL;
+        int r;
+
+        if (!state)
+                return -EINVAL;
+
+        if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
+        free(p);
+
+        if (r == -ENOENT) {
+                free(s);
+                s = strdup("offline");
+                if (!s)
+                        return -ENOMEM;
+
+                *state = s;
+                return 0;
+        } else if (r < 0) {
+                free(s);
+                return r;
+        } else if (!s)
+                return -EIO;
+
+        *state = s;
+        return 0;
+}
+
+_public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) {
+        char *p, *w, *t, *state, *s = NULL;
+        size_t l;
+        int r;
+        const char *variable;
+
+        if (!seat)
+                return -EINVAL;
+
+        variable = require_active ? "ACTIVE_UID" : "UIDS";
+
+        p = strappend("/run/systemd/seats/", seat);
+        if (!p)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, variable, &s, NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+                return r;
+        }
+
+        if (!s)
+                return -EIO;
+
+        if (asprintf(&t, "%lu", (unsigned long) uid) < 0) {
+                free(s);
+                return -ENOMEM;
+        }
+
+        FOREACH_WORD(w, l, s, state) {
+                if (strncmp(t, w, l) == 0) {
+                        free(s);
+                        free(t);
+
+                        return 1;
+                }
+        }
+
+        free(s);
+        free(t);
+
+        return 0;
+}
+
+static int uid_get_array(uid_t uid, const char *variable, char ***array) {
+        char *p, *s = NULL;
+        char **a;
+        int r;
+
+        if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE,
+                           variable, &s,
+                           NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+
+                if (r == -ENOENT) {
+                        if (array)
+                                *array = NULL;
+                        return 0;
+                }
+
+                return r;
+        }
+
+        if (!s) {
+                if (array)
+                        *array = NULL;
+                return 0;
+        }
+
+        a = strv_split(s, " ");
+        free(s);
+
+        if (!a)
+                return -ENOMEM;
+
+        strv_uniq(a);
+        r = strv_length(a);
+
+        if (array)
+                *array = a;
+        else
+                strv_free(a);
+
+        return r;
+}
+
+_public_ int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions) {
+        return uid_get_array(
+                        uid,
+                        require_active == 0 ? "ONLINE_SESSIONS" :
+                        require_active > 0  ? "ACTIVE_SESSIONS" :
+                                              "SESSIONS",
+                        sessions);
+}
+
+_public_ int sd_uid_get_seats(uid_t uid, int require_active, char ***seats) {
+        return uid_get_array(
+                        uid,
+                        require_active == 0 ? "ONLINE_SEATS" :
+                        require_active > 0  ? "ACTIVE_SEATS" :
+                                              "SEATS",
+                        seats);
+}
+
+static int file_of_session(const char *session, char **_p) {
+        char *p;
+        int r;
+
+        assert(_p);
+
+        if (session)
+                p = strappend("/run/systemd/sessions/", session);
+        else {
+                char *buf;
+
+                r = sd_pid_get_session(0, &buf);
+                if (r < 0)
+                        return r;
+
+                p = strappend("/run/systemd/sessions/", buf);
+                free(buf);
+        }
+
+        if (!p)
+                return -ENOMEM;
+
+        *_p = p;
+        return 0;
+}
+
+_public_ int sd_session_is_active(const char *session) {
+        int r;
+        char *p, *s = NULL;
+
+        r = file_of_session(session, &p);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+                return r;
+        }
+
+        if (!s)
+                return -EIO;
+
+        r = parse_boolean(s);
+        free(s);
+
+        return r;
+}
+
+_public_ int sd_session_get_state(const char *session, char **state) {
+        char *p, *s = NULL;
+        int r;
+
+        if (!state)
+                return -EINVAL;
+
+        r = file_of_session(session, &p);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+                return r;
+        } else if (!s)
+                return -EIO;
+
+        *state = s;
+        return 0;
+}
+
+_public_ int sd_session_get_uid(const char *session, uid_t *uid) {
+        int r;
+        char *p, *s = NULL;
+
+        if (!uid)
+                return -EINVAL;
+
+        r = file_of_session(session, &p);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(p, NEWLINE, "UID", &s, NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+                return r;
+        }
+
+        if (!s)
+                return -EIO;
+
+        r = parse_uid(s, uid);
+        free(s);
+
+        return r;
+}
+
+static int session_get_string(const char *session, const char *field, char **value) {
+        char *p, *s = NULL;
+        int r;
+
+        if (!value)
+                return -EINVAL;
+
+        r = file_of_session(session, &p);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(p, NEWLINE, field, &s, NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+                return r;
+        }
+
+        if (isempty(s))
+                return -ENOENT;
+
+        *value = s;
+        return 0;
+}
+
+_public_ int sd_session_get_seat(const char *session, char **seat) {
+        return session_get_string(session, "SEAT", seat);
+}
+
+_public_ int sd_session_get_service(const char *session, char **service) {
+        return session_get_string(session, "SERVICE", service);
+}
+
+_public_ int sd_session_get_type(const char *session, char **type) {
+        return session_get_string(session, "TYPE", type);
+}
+
+_public_ int sd_session_get_class(const char *session, char **class) {
+        return session_get_string(session, "CLASS", class);
+}
+
+_public_ int sd_session_get_display(const char *session, char **display) {
+        return session_get_string(session, "DISPLAY", display);
+}
+
+static int file_of_seat(const char *seat, char **_p) {
+        char *p;
+        int r;
+
+        assert(_p);
+
+        if (seat)
+                p = strappend("/run/systemd/seats/", seat);
+        else {
+                char *buf;
+
+                r = sd_session_get_seat(NULL, &buf);
+                if (r < 0)
+                        return r;
+
+                p = strappend("/run/systemd/seats/", buf);
+                free(buf);
+        }
+
+        if (!p)
+                return -ENOMEM;
+
+        *_p = p;
+        return 0;
+}
+
+_public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) {
+        char *p, *s = NULL, *t = NULL;
+        int r;
+
+        if (!session && !uid)
+                return -EINVAL;
+
+        r = file_of_seat(seat, &p);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(p, NEWLINE,
+                           "ACTIVE", &s,
+                           "ACTIVE_UID", &t,
+                           NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+                free(t);
+                return r;
+        }
+
+        if (session && !s)  {
+                free(t);
+                return -ENOENT;
+        }
+
+        if (uid && !t) {
+                free(s);
+                return -ENOENT;
+        }
+
+        if (uid && t) {
+                r = parse_uid(t, uid);
+                if (r < 0) {
+                        free(t);
+                        free(s);
+                        return r;
+                }
+        }
+
+        free(t);
+
+        if (session && s)
+                *session = s;
+        else
+                free(s);
+
+        return 0;
+}
+
+_public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) {
+        char *p, *s = NULL, *t = NULL, **a = NULL;
+        uid_t *b = NULL;
+        unsigned n = 0;
+        int r;
+
+        r = file_of_seat(seat, &p);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(p, NEWLINE,
+                           "SESSIONS", &s,
+                           "ACTIVE_SESSIONS", &t,
+                           NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+                free(t);
+                return r;
+        }
+
+        if (s) {
+                a = strv_split(s, " ");
+                if (!a) {
+                        free(s);
+                        free(t);
+                        return -ENOMEM;
+                }
+        }
+
+        free(s);
+
+        if (uids && t) {
+                char *w, *state;
+                size_t l;
+
+                FOREACH_WORD(w, l, t, state)
+                        n++;
+
+                if (n == 0)
+                        b = NULL;
+                else {
+                        unsigned i = 0;
+
+                        b = new(uid_t, n);
+                        if (!b) {
+                                strv_free(a);
+                                return -ENOMEM;
+                        }
+
+                        FOREACH_WORD(w, l, t, state) {
+                                char *k;
+
+                                k = strndup(w, l);
+                                if (!k) {
+                                        free(t);
+                                        free(b);
+                                        strv_free(a);
+                                        return -ENOMEM;
+                                }
+
+                                r = parse_uid(k, b + i);
+                                free(k);
+                                if (r < 0)
+                                        continue;
+
+                                i++;
+                        }
+                }
+        }
+
+        free(t);
+
+        r = strv_length(a);
+
+        if (sessions)
+                *sessions = a;
+        else
+                strv_free(a);
+
+        if (uids)
+                *uids = b;
+
+        if (n_uids)
+                *n_uids = n;
+
+        return r;
+}
+
+static int seat_get_can(const char *seat, const char *variable) {
+        char *p, *s = NULL;
+        int r;
+
+        r = file_of_seat(seat, &p);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(p, NEWLINE,
+                           variable, &s,
+                           NULL);
+        free(p);
+
+        if (r < 0) {
+                free(s);
+                return r;
+        }
+
+        if (s) {
+                r = parse_boolean(s);
+                free(s);
+        } else
+                r = 0;
+
+        return r;
+}
+
+_public_ int sd_seat_can_multi_session(const char *seat) {
+        return seat_get_can(seat, "CAN_MULTI_SESSION");
+}
+
+_public_ int sd_seat_can_tty(const char *seat) {
+        return seat_get_can(seat, "CAN_TTY");
+}
+
+_public_ int sd_seat_can_graphical(const char *seat) {
+        return seat_get_can(seat, "CAN_GRAPHICAL");
+}
+
+_public_ int sd_get_seats(char ***seats) {
+        return get_files_in_directory("/run/systemd/seats/", seats);
+}
+
+_public_ int sd_get_sessions(char ***sessions) {
+        return get_files_in_directory("/run/systemd/sessions/", sessions);
+}
+
+_public_ int sd_get_uids(uid_t **users) {
+        DIR *d;
+        int r = 0;
+        unsigned n = 0;
+        uid_t *l = NULL;
+
+        d = opendir("/run/systemd/users/");
+        if (!d)
+                return -errno;
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                int k;
+                uid_t uid;
+
+                k = readdir_r(d, &buf.de, &de);
+                if (k != 0) {
+                        r = -k;
+                        goto finish;
+                }
+
+                if (!de)
+                        break;
+
+                dirent_ensure_type(d, de);
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                k = parse_uid(de->d_name, &uid);
+                if (k < 0)
+                        continue;
+
+                if (users) {
+                        if ((unsigned) r >= n) {
+                                uid_t *t;
+
+                                n = MAX(16, 2*r);
+                                t = realloc(l, sizeof(uid_t) * n);
+                                if (!t) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                l = t;
+                        }
+
+                        assert((unsigned) r < n);
+                        l[r++] = uid;
+                } else
+                        r++;
+        }
+
+finish:
+        if (d)
+                closedir(d);
+
+        if (r >= 0) {
+                if (users)
+                        *users = l;
+        } else
+                free(l);
+
+        return r;
+}
+
+static inline int MONITOR_TO_FD(sd_login_monitor *m) {
+        return (int) (unsigned long) m - 1;
+}
+
+static inline sd_login_monitor* FD_TO_MONITOR(int fd) {
+        return (sd_login_monitor*) (unsigned long) (fd + 1);
+}
+
+_public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
+        int fd, k;
+        bool good = false;
+
+        if (!m)
+                return -EINVAL;
+
+        fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
+        if (fd < 0)
+                return errno;
+
+        if (!category || streq(category, "seat")) {
+                k = inotify_add_watch(fd, "/run/systemd/seats/", IN_MOVED_TO|IN_DELETE);
+                if (k < 0) {
+                        close_nointr_nofail(fd);
+                        return -errno;
+                }
+
+                good = true;
+        }
+
+        if (!category || streq(category, "session")) {
+                k = inotify_add_watch(fd, "/run/systemd/sessions/", IN_MOVED_TO|IN_DELETE);
+                if (k < 0) {
+                        close_nointr_nofail(fd);
+                        return -errno;
+                }
+
+                good = true;
+        }
+
+        if (!category || streq(category, "uid")) {
+                k = inotify_add_watch(fd, "/run/systemd/users/", IN_MOVED_TO|IN_DELETE);
+                if (k < 0) {
+                        close_nointr_nofail(fd);
+                        return -errno;
+                }
+
+                good = true;
+        }
+
+        if (!good) {
+                close_nointr(fd);
+                return -EINVAL;
+        }
+
+        *m = FD_TO_MONITOR(fd);
+        return 0;
+}
+
+_public_ sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) {
+        int fd;
+
+        if (!m)
+                return NULL;
+
+        fd = MONITOR_TO_FD(m);
+        close_nointr(fd);
+
+        return NULL;
+}
+
+_public_ int sd_login_monitor_flush(sd_login_monitor *m) {
+
+        if (!m)
+                return -EINVAL;
+
+        return flush_fd(MONITOR_TO_FD(m));
+}
+
+_public_ int sd_login_monitor_get_fd(sd_login_monitor *m) {
+
+        if (!m)
+                return -EINVAL;
+
+        return MONITOR_TO_FD(m);
+}
diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c
new file mode 100644 (file)
index 0000000..d113ec3
--- /dev/null
@@ -0,0 +1,190 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <libudev.h>
+
+#include "util.h"
+#include "sysfs-show.h"
+#include "path-util.h"
+
+static int show_sysfs_one(
+                struct udev *udev,
+                const char *seat,
+                struct udev_list_entry **item,
+                const char *sub,
+                const char *prefix,
+                unsigned n_columns) {
+
+        assert(udev);
+        assert(seat);
+        assert(item);
+        assert(prefix);
+
+        while (*item) {
+                struct udev_list_entry *next, *lookahead;
+                struct udev_device *d;
+                const char *sn, *name, *sysfs, *subsystem, *sysname;
+                char *l, *k;
+
+                sysfs = udev_list_entry_get_name(*item);
+                if (!path_startswith(sysfs, sub))
+                        return 0;
+
+                d = udev_device_new_from_syspath(udev, sysfs);
+                if (!d) {
+                        *item = udev_list_entry_get_next(*item);
+                        continue;
+                }
+
+                sn = udev_device_get_property_value(d, "ID_SEAT");
+                if (isempty(sn))
+                        sn = "seat0";
+
+                /* fixme, also check for tag 'seat' here */
+                if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
+                        udev_device_unref(d);
+                        *item = udev_list_entry_get_next(*item);
+                        continue;
+                }
+
+                name = udev_device_get_sysattr_value(d, "name");
+                if (!name)
+                        name = udev_device_get_sysattr_value(d, "id");
+                subsystem = udev_device_get_subsystem(d);
+                sysname = udev_device_get_sysname(d);
+
+                /* Look if there's more coming after this */
+                lookahead = next = udev_list_entry_get_next(*item);
+                while (lookahead) {
+                        const char *lookahead_sysfs;
+
+                        lookahead_sysfs = udev_list_entry_get_name(lookahead);
+
+                        if (path_startswith(lookahead_sysfs, sub) &&
+                            !path_startswith(lookahead_sysfs, sysfs)) {
+                                struct udev_device *lookahead_d;
+
+                                lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
+                                if (lookahead_d) {
+                                        const char *lookahead_sn;
+                                        bool found;
+
+                                        lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
+                                        if (isempty(lookahead_sn))
+                                                lookahead_sn = "seat0";
+
+                                        found = streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat");
+                                        udev_device_unref(lookahead_d);
+
+                                        if (found)
+                                                break;
+                                }
+                        }
+
+                        lookahead = udev_list_entry_get_next(lookahead);
+                }
+
+                k = ellipsize(sysfs, n_columns, 20);
+                printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT),
+                                   k ? k : sysfs);
+                free(k);
+
+                if (asprintf(&l,
+                             "(%s:%s)%s%s%s",
+                             subsystem, sysname,
+                             name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) {
+                        udev_device_unref(d);
+                        return -ENOMEM;
+                }
+
+                k = ellipsize(l, n_columns, 70);
+                printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ",
+                                   k ? k : l);
+                free(k);
+                free(l);
+
+                *item = next;
+                if (*item) {
+                        char *p;
+
+                        p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ");
+                        show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2);
+                        free(p);
+                }
+
+                udev_device_unref(d);
+        }
+
+        return 0;
+}
+
+int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
+        struct udev *udev;
+        struct udev_list_entry *first = NULL;
+        struct udev_enumerate *e;
+        int r;
+
+        if (n_columns <= 0)
+                n_columns = columns();
+
+        if (!prefix)
+                prefix = "";
+
+        if (isempty(seat))
+                seat = "seat0";
+
+        udev = udev_new();
+        if (!udev)
+                return -ENOMEM;
+
+        e = udev_enumerate_new(udev);
+        if (!e) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (!streq(seat, "seat0"))
+                r = udev_enumerate_add_match_tag(e, seat);
+        else
+                r = udev_enumerate_add_match_tag(e, "seat");
+
+        if (r < 0)
+                goto finish;
+
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                goto finish;
+
+        first = udev_enumerate_get_list_entry(e);
+        if (first)
+                show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
+
+finish:
+        if (e)
+                udev_enumerate_unref(e);
+
+        if (udev)
+                udev_unref(udev);
+
+        return r;
+}
diff --git a/src/login/test-inhibit.c b/src/login/test-inhibit.c
new file mode 100644 (file)
index 0000000..7b6deff
--- /dev/null
@@ -0,0 +1,139 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+
+#include <dbus/dbus.h>
+
+#include "macro.h"
+#include "util.h"
+#include "dbus-common.h"
+
+static int inhibit(DBusConnection *bus, const char *what) {
+        DBusMessage *m, *reply;
+        DBusError error;
+        const char *who = "Test Tool", *reason = "Just because!", *mode = "block";
+        int fd;
+
+        dbus_error_init(&error);
+
+        m = dbus_message_new_method_call(
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "Inhibit");
+        assert(m);
+
+        assert_se(dbus_message_append_args(m,
+                                           DBUS_TYPE_STRING, &what,
+                                           DBUS_TYPE_STRING, &who,
+                                           DBUS_TYPE_STRING, &reason,
+                                           DBUS_TYPE_STRING, &mode,
+                                           DBUS_TYPE_INVALID));
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+        assert(reply);
+
+        assert(dbus_message_get_args(reply, &error,
+                                     DBUS_TYPE_UNIX_FD, &fd,
+                                     DBUS_TYPE_INVALID));
+
+        dbus_message_unref(m);
+        dbus_message_unref(reply);
+
+        return fd;
+}
+
+static void print_inhibitors(DBusConnection *bus) {
+        DBusMessage *m, *reply;
+        DBusError error;
+        unsigned n = 0;
+        DBusMessageIter iter, sub, sub2;
+
+        dbus_error_init(&error);
+
+        m = dbus_message_new_method_call(
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        "ListInhibitors");
+        assert(m);
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+        assert(reply);
+
+        assert(dbus_message_iter_init(reply, &iter));
+        dbus_message_iter_recurse(&iter, &sub);
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *what, *who, *why, *mode;
+                dbus_uint32_t uid, pid;
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &what, true) >= 0);
+                assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &who, true) >= 0);
+                assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &why, true) >= 0);
+                assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &mode, true) >= 0);
+                assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) >= 0);
+                assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, false) >= 0);
+
+                printf("what=<%s> who=<%s> why=<%s> mode=<%s> uid=<%lu> pid=<%lu>\n",
+                       what, who, why, mode, (unsigned long) uid, (unsigned long) pid);
+
+                dbus_message_iter_next(&sub);
+
+                n++;
+        }
+
+        printf("%u inhibitors\n", n);
+
+        dbus_message_unref(m);
+        dbus_message_unref(reply);
+}
+
+int main(int argc, char*argv[]) {
+        DBusConnection *bus;
+        int fd1, fd2;
+
+        bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
+        assert(bus);
+
+        print_inhibitors(bus);
+
+        fd1 = inhibit(bus, "sleep");
+        assert(fd1 >= 0);
+        print_inhibitors(bus);
+
+        fd2 = inhibit(bus, "idle:shutdown");
+        assert(fd2 >= 0);
+        print_inhibitors(bus);
+
+        close_nointr_nofail(fd1);
+        sleep(1);
+        print_inhibitors(bus);
+
+        close_nointr_nofail(fd2);
+        sleep(1);
+        print_inhibitors(bus);
+
+        return 0;
+}
diff --git a/src/login/test-login.c b/src/login/test-login.c
new file mode 100644 (file)
index 0000000..159ff3e
--- /dev/null
@@ -0,0 +1,201 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/poll.h>
+#include <string.h>
+
+#include <systemd/sd-login.h>
+
+#include "util.h"
+#include "strv.h"
+
+int main(int argc, char* argv[]) {
+        int r, k;
+        uid_t u, u2;
+        char *seat, *type, *class, *display;
+        char *session;
+        char *state;
+        char *session2;
+        char *t;
+        char **seats, **sessions;
+        uid_t *uids;
+        unsigned n;
+        struct pollfd pollfd;
+        sd_login_monitor *m;
+
+        assert_se(sd_pid_get_session(0, &session) == 0);
+        printf("session = %s\n", session);
+
+        assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
+        printf("user = %lu\n", (unsigned long) u2);
+
+        r = sd_uid_get_sessions(u2, false, &sessions);
+        assert_se(r >= 0);
+        assert_se(r == (int) strv_length(sessions));
+        assert_se(t = strv_join(sessions, ", "));
+        strv_free(sessions);
+        printf("sessions = %s\n", t);
+        free(t);
+
+        assert_se(r == sd_uid_get_sessions(u2, false, NULL));
+
+        r = sd_uid_get_seats(u2, false, &seats);
+        assert_se(r >= 0);
+        assert_se(r == (int) strv_length(seats));
+        assert_se(t = strv_join(seats, ", "));
+        strv_free(seats);
+        printf("seats = %s\n", t);
+        free(t);
+
+        assert_se(r == sd_uid_get_seats(u2, false, NULL));
+
+        r = sd_session_is_active(session);
+        assert_se(r >= 0);
+        printf("active = %s\n", yes_no(r));
+
+        r = sd_session_get_state(session, &state);
+        assert_se(r >= 0);
+        printf("state = %s\n", state);
+        free(state);
+
+        assert_se(sd_session_get_uid(session, &u) >= 0);
+        printf("uid = %lu\n", (unsigned long) u);
+        assert_se(u == u2);
+
+        assert_se(sd_session_get_type(session, &type) >= 0);
+        printf("type = %s\n", type);
+        free(type);
+
+        assert_se(sd_session_get_class(session, &class) >= 0);
+        printf("class = %s\n", class);
+        free(class);
+
+        assert_se(sd_session_get_display(session, &display) >= 0);
+        printf("display = %s\n", display);
+        free(display);
+
+        assert_se(sd_session_get_seat(session, &seat) >= 0);
+        printf("seat = %s\n", seat);
+
+        r = sd_seat_can_multi_session(seat);
+        assert_se(r >= 0);
+        printf("can do multi session = %s\n", yes_no(r));
+
+        r = sd_seat_can_tty(seat);
+        assert_se(r >= 0);
+        printf("can do tty = %s\n", yes_no(r));
+
+        r = sd_seat_can_graphical(seat);
+        assert_se(r >= 0);
+        printf("can do graphical = %s\n", yes_no(r));
+
+        assert_se(sd_uid_get_state(u, &state) >= 0);
+        printf("state = %s\n", state);
+
+        assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+
+        k = sd_uid_is_on_seat(u, 1, seat);
+        assert_se(k >= 0);
+        assert_se(!!r == !!r);
+
+        assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
+        printf("session2 = %s\n", session2);
+        printf("uid2 = %lu\n", (unsigned long) u2);
+
+        r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
+        assert_se(r >= 0);
+        printf("n_sessions = %i\n", r);
+        assert_se(r == (int) strv_length(sessions));
+        assert_se(t = strv_join(sessions, ", "));
+        strv_free(sessions);
+        printf("sessions = %s\n", t);
+        free(t);
+        printf("uids =");
+        for (k = 0; k < (int) n; k++)
+                printf(" %lu", (unsigned long) uids[k]);
+        printf("\n");
+        free(uids);
+
+        assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+
+        free(session);
+        free(state);
+        free(session2);
+        free(seat);
+
+        r = sd_get_seats(&seats);
+        assert_se(r >= 0);
+        assert_se(r == (int) strv_length(seats));
+        assert_se(t = strv_join(seats, ", "));
+        strv_free(seats);
+        printf("n_seats = %i\n", r);
+        printf("seats = %s\n", t);
+        free(t);
+
+        assert_se(sd_get_seats(NULL) == r);
+
+        r = sd_seat_get_active(NULL, &t, NULL);
+        assert_se(r >= 0);
+        printf("active session on current seat = %s\n", t);
+        free(t);
+
+        r = sd_get_sessions(&sessions);
+        assert_se(r >= 0);
+        assert_se(r == (int) strv_length(sessions));
+        assert_se(t = strv_join(sessions, ", "));
+        strv_free(sessions);
+        printf("n_sessions = %i\n", r);
+        printf("sessions = %s\n", t);
+        free(t);
+
+        assert_se(sd_get_sessions(NULL) == r);
+
+        r = sd_get_uids(&uids);
+        assert_se(r >= 0);
+
+        printf("uids =");
+        for (k = 0; k < r; k++)
+                printf(" %lu", (unsigned long) uids[k]);
+        printf("\n");
+        free(uids);
+
+        printf("n_uids = %i\n", r);
+        assert_se(sd_get_uids(NULL) == r);
+
+        r = sd_login_monitor_new("session", &m);
+        assert_se(r >= 0);
+
+        zero(pollfd);
+        pollfd.fd = sd_login_monitor_get_fd(m);
+        pollfd.events = POLLIN;
+
+        for (n = 0; n < 5; n++) {
+                r = poll(&pollfd, 1, -1);
+                assert_se(r >= 0);
+
+                sd_login_monitor_flush(m);
+                printf("Wake!\n");
+        }
+
+        sd_login_monitor_unref(m);
+
+        return 0;
+}
diff --git a/src/login/uaccess.c b/src/login/uaccess.c
new file mode 100644 (file)
index 0000000..2c530c8
--- /dev/null
@@ -0,0 +1,91 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-login.h>
+
+#include "logind-acl.h"
+#include "util.h"
+#include "log.h"
+
+int main(int argc, char *argv[]) {
+        int r;
+        const char *path = NULL, *seat;
+        bool changed_acl = false;
+        uid_t uid;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argc < 2 || argc > 3) {
+                log_error("This program expects one or two arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        /* Make sure we don't muck around with ACLs the system is not
+         * running systemd. */
+        if (!sd_booted())
+                return 0;
+
+        path = argv[1];
+        seat = argc < 3 || isempty(argv[2]) ? "seat0" : argv[2];
+
+        r = sd_seat_get_active(seat, NULL, &uid);
+        if (r == -ENOENT) {
+                /* No active session on this seat */
+                r = 0;
+                goto finish;
+        } else if (r < 0) {
+                log_error("Failed to determine active user on seat %s.", seat);
+                goto finish;
+        }
+
+        r = devnode_acl(path, true, false, 0, true, uid);
+        if (r < 0) {
+                log_error("Failed to apply ACL on %s: %s", path, strerror(-r));
+                goto finish;
+        }
+
+        changed_acl = true;
+        r = 0;
+
+finish:
+        if (path && !changed_acl) {
+                int k;
+                /* Better be safe that sorry and reset ACL */
+
+                k = devnode_acl(path, true, false, 0, false, 0);
+                if (k < 0) {
+                        log_error("Failed to apply ACL on %s: %s", path, strerror(-k));
+                        if (r >= 0)
+                                r = k;
+                }
+        }
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/login/user-sessions.c b/src/login/user-sessions.c
new file mode 100644 (file)
index 0000000..91531e8
--- /dev/null
@@ -0,0 +1,101 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "log.h"
+#include "util.h"
+#include "cgroup-util.h"
+
+int main(int argc, char*argv[]) {
+        int ret = EXIT_FAILURE;
+
+        if (argc != 2) {
+                log_error("This program requires one argument.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (streq(argv[1], "start")) {
+                int q = 0, r = 0;
+
+                if (unlink("/run/nologin") < 0 && errno != ENOENT) {
+                        log_error("Failed to remove /run/nologin file: %m");
+                        r = -errno;
+                }
+
+                if (unlink("/etc/nologin") < 0 && errno != ENOENT) {
+
+                        /* If the file doesn't exist and /etc simply
+                         * was read-only (in which case unlink()
+                         * returns EROFS even if the file doesn't
+                         * exist), don't complain */
+
+                        if (errno != EROFS || access("/etc/nologin", F_OK) >= 0) {
+                                log_error("Failed to remove /etc/nologin file: %m");
+                                q = -errno;
+                        }
+                }
+
+                if (r < 0 || q < 0)
+                        goto finish;
+
+        } else if (streq(argv[1], "stop")) {
+                int r, q;
+                char *cgroup_user_tree = NULL;
+
+                r = write_one_line_file_atomic("/run/nologin", "System is going down.");
+                if (r < 0)
+                        log_error("Failed to create /run/nologin: %s", strerror(-r));
+
+                q = cg_get_user_path(&cgroup_user_tree);
+                if (q < 0) {
+                        log_error("Failed to determine use path: %s", strerror(-q));
+                        goto finish;
+                }
+
+                q = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup_user_tree, true);
+                free(cgroup_user_tree);
+                if (q < 0) {
+                        log_error("Failed to kill sessions: %s", strerror(-q));
+                        goto finish;
+                }
+
+                if (r < 0)
+                        goto finish;
+
+        } else {
+                log_error("Unknown verb %s.", argv[1]);
+                goto finish;
+        }
+
+        ret = EXIT_SUCCESS;
+
+finish:
+        return ret;
+}
diff --git a/src/machine-id-setup/Makefile b/src/machine-id-setup/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c
new file mode 100644 (file)
index 0000000..eb2d514
--- /dev/null
@@ -0,0 +1,101 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <errno.h>
+
+#include "machine-id-setup.h"
+#include "log.h"
+#include "build.h"
+
+static int help(void) {
+
+        printf("%s [OPTIONS...]\n\n"
+               "Initialize /etc/machine-id from a random source.\n\n"
+               "  -h --help             Show this help\n"
+               "     --version          Show package version\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { NULL,        0,                 NULL, 0             }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind < argc) {
+                help();
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+        return machine_id_setup() < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/modules-load/Makefile b/src/modules-load/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c
new file mode 100644 (file)
index 0000000..f6279e1
--- /dev/null
@@ -0,0 +1,259 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <dirent.h>
+#include <libkmod.h>
+
+#include "log.h"
+#include "util.h"
+#include "strv.h"
+#include "conf-files.h"
+#include "virt.h"
+
+static char **arg_proc_cmdline_modules = NULL;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+static void systemd_kmod_log(void *data, int priority, const char *file, int line,
+                             const char *fn, const char *format, va_list args)
+{
+        log_metav(priority, file, line, fn, format, args);
+}
+#pragma GCC diagnostic pop
+
+static int add_modules(const char *p) {
+        char **t, **k;
+
+        k = strv_split(p, ",");
+        if (!k)
+                return log_oom();
+
+        t = strv_merge(arg_proc_cmdline_modules, k);
+        strv_free(k);
+        if (!t)
+                return log_oom();
+
+        strv_free(arg_proc_cmdline_modules);
+        arg_proc_cmdline_modules = t;
+
+        return 0;
+}
+
+static int parse_proc_cmdline(void) {
+        char _cleanup_free_ *line = NULL;
+        char *w, *state;
+        int r;
+        size_t l;
+
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        r = read_one_line_file("/proc/cmdline", &line);
+        if (r < 0) {
+                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                char _cleanup_free_ *word;
+
+                word = strndup(w, l);
+                if (!word)
+                        return log_oom();
+
+                if (startswith(word, "modules-load=")) {
+
+                        r = add_modules(word + 13);
+                        if (r < 0)
+                                return r;
+
+                } else if (startswith(word, "rd.modules-load=")) {
+
+                        if (in_initrd()) {
+                                r = add_modules(word + 16);
+                                if (r < 0)
+                                        return r;
+                        }
+
+                }
+        }
+
+        return 0;
+}
+
+static int load_module(struct kmod_ctx *ctx, const char *m) {
+        const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST;
+        struct kmod_list *itr, *modlist = NULL;
+        int r = 0;
+
+        log_debug("load: %s\n", m);
+
+        r = kmod_module_new_from_lookup(ctx, m, &modlist);
+        if (r < 0) {
+                log_error("Failed to lookup alias '%s': %s", m, strerror(-r));
+                return r;
+        }
+
+        if (!modlist) {
+                log_error("Failed to find module '%s'", m);
+                return -ENOENT;
+        }
+
+        kmod_list_foreach(itr, modlist) {
+                struct kmod_module *mod;
+                int state, err;
+
+                mod = kmod_module_get_module(itr);
+                state = kmod_module_get_initstate(mod);
+
+                switch (state) {
+                case KMOD_MODULE_BUILTIN:
+                        log_info("Module '%s' is builtin", kmod_module_get_name(mod));
+                        break;
+
+                case KMOD_MODULE_LIVE:
+                        log_info("Module '%s' is already loaded", kmod_module_get_name(mod));
+                        break;
+
+                default:
+                        err = kmod_module_probe_insert_module(mod, probe_flags,
+                                                              NULL, NULL, NULL, NULL);
+
+                        if (err == 0)
+                                log_info("Inserted module '%s'", kmod_module_get_name(mod));
+                        else if (err == KMOD_PROBE_APPLY_BLACKLIST)
+                                log_info("Module '%s' is blacklisted", kmod_module_get_name(mod));
+                        else {
+                                log_error("Failed to insert '%s': %s", kmod_module_get_name(mod),
+                                          strerror(-err));
+                                r = err;
+                        }
+                }
+
+                kmod_module_unref(mod);
+        }
+
+        kmod_module_unref_list(modlist);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        int r = EXIT_FAILURE, k;
+        char **files = NULL, **fn, **i;
+        struct kmod_ctx *ctx;
+
+        if (argc > 1) {
+                log_error("This program takes no argument.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (parse_proc_cmdline() < 0)
+                return EXIT_FAILURE;
+
+        ctx = kmod_new(NULL, NULL);
+        if (!ctx) {
+                log_error("Failed to allocate memory for kmod.");
+                goto finish;
+        }
+
+        kmod_load_resources(ctx);
+        kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
+
+        r = EXIT_SUCCESS;
+
+        STRV_FOREACH(i, arg_proc_cmdline_modules) {
+                k = load_module(ctx, *i);
+                if (k < 0)
+                        r = EXIT_FAILURE;
+        }
+
+        k = conf_files_list(&files, ".conf",
+                            "/etc/modules-load.d",
+                            "/run/modules-load.d",
+                            "/usr/local/lib/modules-load.d",
+                            "/usr/lib/modules-load.d",
+#ifdef HAVE_SPLIT_USR
+                            "/lib/modules-load.d",
+#endif
+                            NULL);
+        if (k < 0) {
+                log_error("Failed to enumerate modules-load.d files: %s", strerror(-k));
+                r = EXIT_FAILURE;
+                goto finish;
+        }
+
+        STRV_FOREACH(fn, files) {
+                FILE *f;
+
+                f = fopen(*fn, "re");
+                if (!f) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        log_error("Failed to open %s: %m", *fn);
+                        r = EXIT_FAILURE;
+                        continue;
+                }
+
+                log_debug("apply: %s\n", *fn);
+                for (;;) {
+                        char line[LINE_MAX], *l;
+
+                        if (!fgets(line, sizeof(line), f))
+                                break;
+
+                        l = strstrip(line);
+                        if (*l == '#' || *l == 0)
+                                continue;
+
+                        k = load_module(ctx, l);
+                        if (k < 0)
+                                r = EXIT_FAILURE;
+                }
+
+                if (ferror(f)) {
+                        log_error("Failed to read from file: %m");
+                        r = EXIT_FAILURE;
+                }
+
+                fclose(f);
+        }
+
+finish:
+        strv_free(files);
+        kmod_unref(ctx);
+        strv_free(arg_proc_cmdline_modules);
+
+        return r;
+}
diff --git a/src/notify/Makefile b/src/notify/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/notify/notify.c b/src/notify/notify.c
new file mode 100644 (file)
index 0000000..f521f56
--- /dev/null
@@ -0,0 +1,227 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <getopt.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <systemd/sd-daemon.h>
+
+#include "strv.h"
+#include "util.h"
+#include "log.h"
+#include "sd-readahead.h"
+#include "build.h"
+
+static bool arg_ready = false;
+static pid_t arg_pid = 0;
+static const char *arg_status = NULL;
+static bool arg_booted = false;
+static const char *arg_readahead = NULL;
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n\n"
+               "Notify the init system about service status updates.\n\n"
+               "  -h --help             Show this help\n"
+               "     --version          Show package version\n"
+               "     --ready            Inform the init system about service start-up completion\n"
+               "     --pid[=PID]        Set main pid of daemon\n"
+               "     --status=TEXT      Set status text\n"
+               "     --booted           Returns 0 if the system was booted up with systemd, non-zero otherwise\n"
+               "     --readahead=ACTION Controls read-ahead operations\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_READY = 0x100,
+                ARG_VERSION,
+                ARG_PID,
+                ARG_STATUS,
+                ARG_BOOTED,
+                ARG_READAHEAD
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "ready",     no_argument,       NULL, ARG_READY     },
+                { "pid",       optional_argument, NULL, ARG_PID       },
+                { "status",    required_argument, NULL, ARG_STATUS    },
+                { "booted",    no_argument,       NULL, ARG_BOOTED    },
+                { "readahead", required_argument, NULL, ARG_READAHEAD },
+                { NULL,        0,                 NULL, 0             }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_READY:
+                        arg_ready = true;
+                        break;
+
+                case ARG_PID:
+
+                        if (optarg) {
+                                if (parse_pid(optarg, &arg_pid) < 0) {
+                                        log_error("Failed to parse PID %s.", optarg);
+                                        return -EINVAL;
+                                }
+                        } else
+                                arg_pid = getppid();
+
+                        break;
+
+                case ARG_STATUS:
+                        arg_status = optarg;
+                        break;
+
+                case ARG_BOOTED:
+                        arg_booted = true;
+                        break;
+
+                case ARG_READAHEAD:
+                        arg_readahead = optarg;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind >= argc &&
+            !arg_ready &&
+            !arg_status &&
+            !arg_pid &&
+            !arg_booted &&
+            !arg_readahead) {
+                help();
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+int main(int argc, char* argv[]) {
+        char* our_env[4], **final_env = NULL;
+        unsigned i = 0;
+        char *status = NULL, *cpid = NULL, *n = NULL;
+        int r, retval = EXIT_FAILURE;
+
+        log_parse_environment();
+        log_open();
+
+        if ((r = parse_argv(argc, argv)) <= 0) {
+                retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+                goto finish;
+        }
+
+        if (arg_booted)
+                return sd_booted() <= 0;
+
+        if (arg_readahead) {
+                if ((r = sd_readahead(arg_readahead)) < 0) {
+                        log_error("Failed to issue read-ahead control command: %s", strerror(-r));
+                        goto finish;
+                }
+        }
+
+        if (arg_ready)
+                our_env[i++] = (char*) "READY=1";
+
+        if (arg_status) {
+                if (!(status = strappend("STATUS=", arg_status))) {
+                        log_error("Failed to allocate STATUS string.");
+                        goto finish;
+                }
+
+                our_env[i++] = status;
+        }
+
+        if (arg_pid > 0) {
+                if (asprintf(&cpid, "MAINPID=%lu", (unsigned long) arg_pid) < 0) {
+                        log_error("Failed to allocate MAINPID string.");
+                        goto finish;
+                }
+
+                our_env[i++] = cpid;
+        }
+
+        our_env[i++] = NULL;
+
+        if (!(final_env = strv_env_merge(2, our_env, argv + optind))) {
+                log_error("Failed to merge string sets.");
+                goto finish;
+        }
+
+        if (strv_length(final_env) <= 0) {
+                retval = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        if (!(n = strv_join(final_env, "\n"))) {
+                log_error("Failed to concatenate strings.");
+                goto finish;
+        }
+
+        if ((r = sd_notify(false, n)) < 0) {
+                log_error("Failed to notify init system: %s", strerror(-r));
+                goto finish;
+        }
+
+        retval = r <= 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+finish:
+        free(status);
+        free(cpid);
+        free(n);
+
+        strv_free(final_env);
+
+        return retval;
+}
diff --git a/src/nspawn/Makefile b/src/nspawn/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
new file mode 100644 (file)
index 0000000..1f3bda5
--- /dev/null
@@ -0,0 +1,1533 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <signal.h>
+#include <sched.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <sys/capability.h>
+#include <getopt.h>
+#include <sys/epoll.h>
+#include <termios.h>
+#include <sys/signalfd.h>
+#include <grp.h>
+#include <linux/fs.h>
+#include <sys/un.h>
+#include <sys/socket.h>
+
+#include <systemd/sd-daemon.h>
+
+#include "log.h"
+#include "util.h"
+#include "mkdir.h"
+#include "macro.h"
+#include "audit.h"
+#include "missing.h"
+#include "cgroup-util.h"
+#include "strv.h"
+#include "path-util.h"
+#include "loopback-setup.h"
+#include "sd-id128.h"
+#include "dev-setup.h"
+#include "fdset.h"
+
+typedef enum LinkJournal {
+        LINK_NO,
+        LINK_AUTO,
+        LINK_HOST,
+        LINK_GUEST
+} LinkJournal;
+
+static char *arg_directory = NULL;
+static char *arg_user = NULL;
+static char **arg_controllers = NULL;
+static char *arg_uuid = NULL;
+static bool arg_private_network = false;
+static bool arg_read_only = false;
+static bool arg_boot = false;
+static LinkJournal arg_link_journal = LINK_AUTO;
+static uint64_t arg_retain =
+        (1ULL << CAP_CHOWN) |
+        (1ULL << CAP_DAC_OVERRIDE) |
+        (1ULL << CAP_DAC_READ_SEARCH) |
+        (1ULL << CAP_FOWNER) |
+        (1ULL << CAP_FSETID) |
+        (1ULL << CAP_IPC_OWNER) |
+        (1ULL << CAP_KILL) |
+        (1ULL << CAP_LEASE) |
+        (1ULL << CAP_LINUX_IMMUTABLE) |
+        (1ULL << CAP_NET_BIND_SERVICE) |
+        (1ULL << CAP_NET_BROADCAST) |
+        (1ULL << CAP_NET_RAW) |
+        (1ULL << CAP_SETGID) |
+        (1ULL << CAP_SETFCAP) |
+        (1ULL << CAP_SETPCAP) |
+        (1ULL << CAP_SETUID) |
+        (1ULL << CAP_SYS_ADMIN) |
+        (1ULL << CAP_SYS_CHROOT) |
+        (1ULL << CAP_SYS_NICE) |
+        (1ULL << CAP_SYS_PTRACE) |
+        (1ULL << CAP_SYS_TTY_CONFIG) |
+        (1ULL << CAP_SYS_RESOURCE) |
+        (1ULL << CAP_SYS_BOOT);
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
+               "Spawn a minimal namespace container for debugging, testing and building.\n\n"
+               "  -h --help               Show this help\n"
+               "  -D --directory=NAME     Root directory for the container\n"
+               "  -b --boot               Boot up full system (i.e. invoke init)\n"
+               "  -u --user=USER          Run the command under specified user or uid\n"
+               "  -C --controllers=LIST   Put the container in specified comma-separated cgroup hierarchies\n"
+               "     --uuid=UUID          Set a specific machine UUID for the container\n"
+               "     --private-network    Disable network in container\n"
+               "     --read-only          Mount the root directory read-only\n"
+               "     --capability=CAP     In addition to the default, retain specified capability\n"
+               "     --link-journal=MODE  Link up guest journal, one of no, auto, guest, host\n"
+               "  -j                      Equivalent to --link-journal=host\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_PRIVATE_NETWORK = 0x100,
+                ARG_UUID,
+                ARG_READ_ONLY,
+                ARG_CAPABILITY,
+                ARG_LINK_JOURNAL
+        };
+
+        static const struct option options[] = {
+                { "help",            no_argument,       NULL, 'h'                 },
+                { "directory",       required_argument, NULL, 'D'                 },
+                { "user",            required_argument, NULL, 'u'                 },
+                { "controllers",     required_argument, NULL, 'C'                 },
+                { "private-network", no_argument,       NULL, ARG_PRIVATE_NETWORK },
+                { "boot",            no_argument,       NULL, 'b'                 },
+                { "uuid",            required_argument, NULL, ARG_UUID            },
+                { "read-only",       no_argument,       NULL, ARG_READ_ONLY       },
+                { "capability",      required_argument, NULL, ARG_CAPABILITY      },
+                { "link-journal",    required_argument, NULL, ARG_LINK_JOURNAL    },
+                { NULL,              0,                 NULL, 0                   }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "+hD:u:C:bj", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case 'D':
+                        free(arg_directory);
+                        arg_directory = canonicalize_file_name(optarg);
+                        if (!arg_directory) {
+                                log_error("Failed to canonicalize root directory.");
+                                return -ENOMEM;
+                        }
+
+                        break;
+
+                case 'u':
+                        free(arg_user);
+                        if (!(arg_user = strdup(optarg))) {
+                                log_error("Failed to duplicate user name.");
+                                return -ENOMEM;
+                        }
+
+                        break;
+
+                case 'C':
+                        strv_free(arg_controllers);
+                        arg_controllers = strv_split(optarg, ",");
+                        if (!arg_controllers) {
+                                log_error("Failed to split controllers list.");
+                                return -ENOMEM;
+                        }
+                        strv_uniq(arg_controllers);
+
+                        break;
+
+                case ARG_PRIVATE_NETWORK:
+                        arg_private_network = true;
+                        break;
+
+                case 'b':
+                        arg_boot = true;
+                        break;
+
+                case ARG_UUID:
+                        arg_uuid = optarg;
+                        break;
+
+                case ARG_READ_ONLY:
+                        arg_read_only = true;
+                        break;
+
+                case ARG_CAPABILITY: {
+                        char *state, *word;
+                        size_t length;
+
+                        FOREACH_WORD_SEPARATOR(word, length, optarg, ",", state) {
+                                cap_value_t cap;
+                                char *t;
+
+                                t = strndup(word, length);
+                                if (!t)
+                                        return log_oom();
+
+                                if (cap_from_name(t, &cap) < 0) {
+                                        log_error("Failed to parse capability %s.", t);
+                                        free(t);
+                                        return -EINVAL;
+                                }
+
+                                free(t);
+                                arg_retain |= 1ULL << (uint64_t) cap;
+                        }
+
+                        break;
+                }
+
+                case 'j':
+                        arg_link_journal = LINK_GUEST;
+                        break;
+
+                case ARG_LINK_JOURNAL:
+                        if (streq(optarg, "auto"))
+                                arg_link_journal = LINK_AUTO;
+                        else if (streq(optarg, "no"))
+                                arg_link_journal = LINK_NO;
+                        else if (streq(optarg, "guest"))
+                                arg_link_journal = LINK_GUEST;
+                        else if (streq(optarg, "host"))
+                                arg_link_journal = LINK_HOST;
+                        else {
+                                log_error("Failed to parse link journal mode %s", optarg);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        return 1;
+}
+
+static int mount_all(const char *dest) {
+
+        typedef struct MountPoint {
+                const char *what;
+                const char *where;
+                const char *type;
+                const char *options;
+                unsigned long flags;
+                bool fatal;
+        } MountPoint;
+
+        static const MountPoint mount_table[] = {
+                { "proc",      "/proc",     "proc",  NULL,       MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
+                { "/proc/sys", "/proc/sys", NULL,    NULL,       MS_BIND, true                       },   /* Bind mount first */
+                { NULL,        "/proc/sys", NULL,    NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
+                { "sysfs",     "/sys",      "sysfs", NULL,       MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
+                { "tmpfs",     "/dev",      "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME,     true  },
+                { "/dev/pts",  "/dev/pts",  NULL,    NULL,       MS_BIND,                      true  },
+                { "tmpfs",     "/dev/shm",  "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true  },
+                { "tmpfs",     "/run",      "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true  },
+#ifdef HAVE_SELINUX
+                { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND,                      false },  /* Bind mount first */
+                { NULL,              "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false },  /* Then, make it r/o */
+#endif
+        };
+
+        unsigned k;
+        int r = 0;
+
+        for (k = 0; k < ELEMENTSOF(mount_table); k++) {
+                char _cleanup_free_ *where = NULL;
+                int t;
+
+                if (asprintf(&where, "%s/%s", dest, mount_table[k].where) < 0) {
+                        log_oom();
+
+                        if (r == 0)
+                                r = -ENOMEM;
+
+                        break;
+                }
+
+                t = path_is_mount_point(where, true);
+                if (t < 0) {
+                        log_error("Failed to detect whether %s is a mount point: %s", where, strerror(-t));
+
+                        if (r == 0)
+                                r = t;
+
+                        continue;
+                }
+
+                /* Skip this entry if it is not a remount. */
+                if (mount_table[k].what && t > 0)
+                        continue;
+
+                mkdir_p_label(where, 0755);
+
+                if (mount(mount_table[k].what,
+                          where,
+                          mount_table[k].type,
+                          mount_table[k].flags,
+                          mount_table[k].options) < 0 &&
+                    mount_table[k].fatal) {
+
+                        log_error("mount(%s) failed: %m", where);
+
+                        if (r == 0)
+                                r = -errno;
+                }
+        }
+
+        return r;
+}
+
+static int setup_timezone(const char *dest) {
+        _cleanup_free_ char *where = NULL, *p = NULL, *q = NULL, *check = NULL, *what = NULL;
+        char *z, *y;
+        int r;
+
+        assert(dest);
+
+        /* Fix the timezone, if possible */
+        r = readlink_malloc("/etc/localtime", &p);
+        if (r < 0) {
+                log_warning("/etc/localtime is not a symlink, not updating container timezone.");
+                return 0;
+        }
+
+        z = path_startswith(p, "../usr/share/zoneinfo/");
+        if (!z)
+                z = path_startswith(p, "/usr/share/zoneinfo/");
+        if (!z) {
+                log_warning("/etc/localtime does not point into /usr/share/zoneinfo/, not updating container timezone.");
+                return 0;
+        }
+
+        where = strappend(dest, "/etc/localtime");
+        if (!where)
+                return log_oom();
+
+        r = readlink_malloc(where, &q);
+        if (r >= 0) {
+                y = path_startswith(q, "../usr/share/zoneinfo/");
+                if (!y)
+                        y = path_startswith(q, "/usr/share/zoneinfo/");
+
+
+                /* Already pointing to the right place? Then do nothing .. */
+                if (y && streq(y, z))
+                        return 0;
+        }
+
+        check = strjoin(dest, "/usr/share/zoneinfo/", z, NULL);
+        if (!check)
+                return log_oom();
+
+        if (access(check, F_OK) < 0) {
+                log_warning("Timezone %s does not exist in container, not updating container timezone.", z);
+                return 0;
+        }
+
+        what = strappend("../usr/share/zoneinfo/", z);
+        if (!what)
+                return log_oom();
+
+        unlink(where);
+        if (symlink(what, where) < 0) {
+                log_error("Failed to correct timezone of container: %m");
+                return 0;
+        }
+
+        return 0;
+}
+
+static int setup_resolv_conf(const char *dest) {
+        char *where;
+
+        assert(dest);
+
+        if (arg_private_network)
+                return 0;
+
+        /* Fix resolv.conf, if possible */
+        where = strappend(dest, "/etc/resolv.conf");
+        if (!where)
+                return log_oom();
+
+        /* We don't really care for the results of this really. If it
+         * fails, it fails, but meh... */
+        if (mount("/etc/resolv.conf", where, "bind", MS_BIND, NULL) >= 0)
+                mount("/etc/resolv.conf", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
+
+        free(where);
+
+        return 0;
+}
+
+static int setup_boot_id(const char *dest) {
+        char _cleanup_free_ *from = NULL, *to = NULL;
+        sd_id128_t rnd;
+        char as_uuid[37];
+        int r;
+
+        assert(dest);
+
+        /* Generate a new randomized boot ID, so that each boot-up of
+         * the container gets a new one */
+
+        from = strappend(dest, "/dev/proc-sys-kernel-random-boot-id");
+        to = strappend(dest, "/proc/sys/kernel/random/boot_id");
+        if (!from || !to)
+                return log_oom();
+
+        r = sd_id128_randomize(&rnd);
+        if (r < 0) {
+                log_error("Failed to generate random boot id: %s", strerror(-r));
+                return r;
+        }
+
+        snprintf(as_uuid, sizeof(as_uuid),
+                 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                 SD_ID128_FORMAT_VAL(rnd));
+        char_array_0(as_uuid);
+
+        r = write_one_line_file(from, as_uuid);
+        if (r < 0) {
+                log_error("Failed to write boot id: %s", strerror(-r));
+                return r;
+        }
+
+        if (mount(from, to, "bind", MS_BIND, NULL) < 0) {
+                log_error("Failed to bind mount boot id: %m");
+                r = -errno;
+        } else
+                mount(from, to, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
+
+        unlink(from);
+        return r;
+}
+
+static int copy_devnodes(const char *dest) {
+
+        static const char devnodes[] =
+                "null\0"
+                "zero\0"
+                "full\0"
+                "random\0"
+                "urandom\0"
+                "tty\0"
+                "ptmx\0";
+
+        const char *d;
+        int r = 0;
+        mode_t _cleanup_umask_ u;
+
+        assert(dest);
+
+        u = umask(0000);
+
+        NULSTR_FOREACH(d, devnodes) {
+                struct stat st;
+                char _cleanup_free_ *from = NULL, *to = NULL;
+
+                asprintf(&from, "/dev/%s", d);
+                asprintf(&to, "%s/dev/%s", dest, d);
+
+                if (!from || !to) {
+                        log_oom();
+
+                        if (r == 0)
+                                r = -ENOMEM;
+
+                        break;
+                }
+
+                if (stat(from, &st) < 0) {
+
+                        if (errno != ENOENT) {
+                                log_error("Failed to stat %s: %m", from);
+                                if (r == 0)
+                                        r = -errno;
+                        }
+
+                } else if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
+
+                        log_error("%s is not a char or block device, cannot copy", from);
+                        if (r == 0)
+                                r = -EIO;
+
+                } else if (mknod(to, st.st_mode, st.st_rdev) < 0) {
+
+                        log_error("mknod(%s) failed: %m", dest);
+                        if (r == 0)
+                                r = -errno;
+                }
+        }
+
+        return r;
+}
+
+static int setup_dev_console(const char *dest, const char *console) {
+        struct stat st;
+        char _cleanup_free_ *to = NULL;
+        int r;
+        mode_t _cleanup_umask_ u;
+
+        assert(dest);
+        assert(console);
+
+        u = umask(0000);
+
+        if (stat(console, &st) < 0) {
+                log_error("Failed to stat %s: %m", console);
+                return -errno;
+
+        } else if (!S_ISCHR(st.st_mode)) {
+                log_error("/dev/console is not a char device");
+                return -EIO;
+        }
+
+        r = chmod_and_chown(console, 0600, 0, 0);
+        if (r < 0) {
+                log_error("Failed to correct access mode for TTY: %s", strerror(-r));
+                return r;
+        }
+
+        if (asprintf(&to, "%s/dev/console", dest) < 0)
+                return log_oom();
+
+        /* We need to bind mount the right tty to /dev/console since
+         * ptys can only exist on pts file systems. To have something
+         * to bind mount things on we create a device node first, that
+         * has the right major/minor (note that the major minor
+         * doesn't actually matter here, since we mount it over
+         * anyway). */
+
+        if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
+                log_error("mknod() for /dev/console failed: %m");
+                return -errno;
+        }
+
+        if (mount(console, to, "bind", MS_BIND, NULL) < 0) {
+                log_error("Bind mount for /dev/console failed: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+static int setup_kmsg(const char *dest, int kmsg_socket) {
+        char _cleanup_free_ *from = NULL, *to = NULL;
+        int r, fd, k;
+        mode_t _cleanup_umask_ u;
+        union {
+                struct cmsghdr cmsghdr;
+                uint8_t buf[CMSG_SPACE(sizeof(int))];
+        } control;
+        struct msghdr mh;
+        struct cmsghdr *cmsg;
+
+        assert(dest);
+        assert(kmsg_socket >= 0);
+
+        u = umask(0000);
+
+        /* We create the kmsg FIFO as /dev/kmsg, but immediately
+         * delete it after bind mounting it to /proc/kmsg. While FIFOs
+         * on the reading side behave very similar to /proc/kmsg,
+         * their writing side behaves differently from /dev/kmsg in
+         * that writing blocks when nothing is reading. In order to
+         * avoid any problems with containers deadlocking due to this
+         * we simply make /dev/kmsg unavailable to the container. */
+        if (asprintf(&from, "%s/dev/kmsg", dest) < 0 ||
+            asprintf(&to, "%s/proc/kmsg", dest) < 0)
+                return log_oom();
+
+        if (mkfifo(from, 0600) < 0) {
+                log_error("mkfifo() for /dev/kmsg failed: %m");
+                return -errno;
+        }
+
+        r = chmod_and_chown(from, 0600, 0, 0);
+        if (r < 0) {
+                log_error("Failed to correct access mode for /dev/kmsg: %s", strerror(-r));
+                return r;
+        }
+
+        if (mount(from, to, "bind", MS_BIND, NULL) < 0) {
+                log_error("Bind mount for /proc/kmsg failed: %m");
+                return -errno;
+        }
+
+        fd = open(from, O_RDWR|O_NDELAY|O_CLOEXEC);
+        if (fd < 0) {
+                log_error("Failed to open fifo: %m");
+                return -errno;
+        }
+
+        zero(mh);
+        zero(control);
+
+        mh.msg_control = &control;
+        mh.msg_controllen = sizeof(control);
+
+        cmsg = CMSG_FIRSTHDR(&mh);
+        cmsg->cmsg_level = SOL_SOCKET;
+        cmsg->cmsg_type = SCM_RIGHTS;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+        memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
+
+        mh.msg_controllen = cmsg->cmsg_len;
+
+        /* Store away the fd in the socket, so that it stays open as
+         * long as we run the child */
+        k = sendmsg(kmsg_socket, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
+        close_nointr_nofail(fd);
+
+        if (k < 0) {
+                log_error("Failed to send FIFO fd: %m");
+                return -errno;
+        }
+
+        /* And now make the FIFO unavailable as /dev/kmsg... */
+        unlink(from);
+        return 0;
+}
+
+static int setup_hostname(void) {
+        char *hn;
+        int r = 0;
+
+        hn = path_get_file_name(arg_directory);
+        if (hn) {
+                hn = strdup(hn);
+                if (!hn)
+                        return -ENOMEM;
+
+                hostname_cleanup(hn);
+
+                if (!isempty(hn))
+                        if (sethostname(hn, strlen(hn)) < 0)
+                                r = -errno;
+
+                free(hn);
+        }
+
+        return r;
+}
+
+static int setup_journal(const char *directory) {
+        sd_id128_t machine_id;
+        char _cleanup_free_ *p = NULL, *b = NULL, *q = NULL, *d = NULL;
+        char *id;
+        int r;
+
+        if (arg_link_journal == LINK_NO)
+                return 0;
+
+        p = strappend(directory, "/etc/machine-id");
+        if (!p)
+                return log_oom();
+
+        r = read_one_line_file(p, &b);
+        if (r == -ENOENT && arg_link_journal == LINK_AUTO)
+                return 0;
+        else if (r < 0) {
+                log_error("Failed to read machine ID from %s: %s", p, strerror(-r));
+                return r;
+        }
+
+        id = strstrip(b);
+        if (isempty(id) && arg_link_journal == LINK_AUTO)
+                return 0;
+
+        /* Verify validity */
+        r = sd_id128_from_string(id, &machine_id);
+        if (r < 0) {
+                log_error("Failed to parse machine ID from %s: %s", p, strerror(-r));
+                return r;
+        }
+
+        free(p);
+        p = strappend("/var/log/journal/", id);
+        q = strjoin(directory, "/var/log/journal/", id, NULL);
+        if (!p || !q)
+                return log_oom();
+
+        if (path_is_mount_point(p, false) > 0) {
+                if (arg_link_journal != LINK_AUTO) {
+                        log_error("%s: already a mount point, refusing to use for journal", p);
+                        return -EEXIST;
+                }
+
+                return 0;
+        }
+
+        if (path_is_mount_point(q, false) > 0) {
+                if (arg_link_journal != LINK_AUTO) {
+                        log_error("%s: already a mount point, refusing to use for journal", q);
+                        return -EEXIST;
+                }
+
+                return 0;
+        }
+
+        r = readlink_and_make_absolute(p, &d);
+        if (r >= 0) {
+                if ((arg_link_journal == LINK_GUEST ||
+                     arg_link_journal == LINK_AUTO) &&
+                    path_equal(d, q)) {
+
+                        r = mkdir_p(q, 0755);
+                        if (r < 0)
+                                log_warning("failed to create directory %s: %m", q);
+                        return 0;
+                }
+
+                if (unlink(p) < 0) {
+                        log_error("Failed to remove symlink %s: %m", p);
+                        return -errno;
+                }
+        } else if (r == -EINVAL) {
+
+                if (arg_link_journal == LINK_GUEST &&
+                    rmdir(p) < 0) {
+
+                        if (errno == ENOTDIR) {
+                                log_error("%s already exists and is neither a symlink nor a directory", p);
+                                return r;
+                        } else {
+                                log_error("Failed to remove %s: %m", p);
+                                return -errno;
+                        }
+                }
+        } else if (r != -ENOENT) {
+                log_error("readlink(%s) failed: %m", p);
+                return r;
+        }
+
+        if (arg_link_journal == LINK_GUEST) {
+
+                if (symlink(q, p) < 0) {
+                        log_error("Failed to symlink %s to %s: %m", q, p);
+                        return -errno;
+                }
+
+                r = mkdir_p(q, 0755);
+                if (r < 0)
+                        log_warning("failed to create directory %s: %m", q);
+                return 0;
+        }
+
+        if (arg_link_journal == LINK_HOST) {
+                r = mkdir_p(p, 0755);
+                if (r < 0) {
+                        log_error("Failed to create %s: %m", p);
+                        return r;
+                }
+
+        } else if (access(p, F_OK) < 0)
+                return 0;
+
+        if (dir_is_empty(q) == 0) {
+                log_error("%s not empty.", q);
+                return -ENOTEMPTY;
+        }
+
+        r = mkdir_p(q, 0755);
+        if (r < 0) {
+                log_error("Failed to create %s: %m", q);
+                return r;
+        }
+
+        if (mount(p, q, "bind", MS_BIND, NULL) < 0) {
+                log_error("Failed to bind mount journal from host into guest: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+static int drop_capabilities(void) {
+        return capability_bounding_set_drop(~arg_retain, false);
+}
+
+static int is_os_tree(const char *path) {
+        int r;
+        char *p;
+        /* We use /bin/sh as flag file if something is an OS */
+
+        if (asprintf(&p, "%s/bin/sh", path) < 0)
+                return -ENOMEM;
+
+        r = access(p, F_OK);
+        free(p);
+
+        return r < 0 ? 0 : 1;
+}
+
+static int process_pty(int master, pid_t pid, sigset_t *mask) {
+
+        char in_buffer[LINE_MAX], out_buffer[LINE_MAX];
+        size_t in_buffer_full = 0, out_buffer_full = 0;
+        struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev;
+        bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false;
+        int ep = -1, signal_fd = -1, r;
+        bool tried_orderly_shutdown = false;
+
+        assert(master >= 0);
+        assert(pid > 0);
+        assert(mask);
+
+        fd_nonblock(STDIN_FILENO, 1);
+        fd_nonblock(STDOUT_FILENO, 1);
+        fd_nonblock(master, 1);
+
+        signal_fd = signalfd(-1, mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (signal_fd < 0) {
+                log_error("signalfd(): %m");
+                r = -errno;
+                goto finish;
+        }
+
+        ep = epoll_create1(EPOLL_CLOEXEC);
+        if (ep < 0) {
+                log_error("Failed to create epoll: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        /* We read from STDIN only if this is actually a TTY,
+         * otherwise we assume non-interactivity. */
+        if (isatty(STDIN_FILENO)) {
+                zero(stdin_ev);
+                stdin_ev.events = EPOLLIN|EPOLLET;
+                stdin_ev.data.fd = STDIN_FILENO;
+
+                if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0) {
+                        log_error("Failed to register STDIN in epoll: %m");
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        zero(stdout_ev);
+        stdout_ev.events = EPOLLOUT|EPOLLET;
+        stdout_ev.data.fd = STDOUT_FILENO;
+
+        zero(master_ev);
+        master_ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
+        master_ev.data.fd = master;
+
+        zero(signal_ev);
+        signal_ev.events = EPOLLIN;
+        signal_ev.data.fd = signal_fd;
+
+        if (epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 ||
+            epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 ||
+            epoll_ctl(ep, EPOLL_CTL_ADD, signal_fd, &signal_ev) < 0) {
+                log_error("Failed to register fds in epoll: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        for (;;) {
+                struct epoll_event ev[16];
+                ssize_t k;
+                int i, nfds;
+
+                nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1);
+                if (nfds < 0) {
+
+                        if (errno == EINTR || errno == EAGAIN)
+                                continue;
+
+                        log_error("epoll_wait(): %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                assert(nfds >= 1);
+
+                for (i = 0; i < nfds; i++) {
+                        if (ev[i].data.fd == STDIN_FILENO) {
+
+                                if (ev[i].events & (EPOLLIN|EPOLLHUP))
+                                        stdin_readable = true;
+
+                        } else if (ev[i].data.fd == STDOUT_FILENO) {
+
+                                if (ev[i].events & (EPOLLOUT|EPOLLHUP))
+                                        stdout_writable = true;
+
+                        } else if (ev[i].data.fd == master) {
+
+                                if (ev[i].events & (EPOLLIN|EPOLLHUP))
+                                        master_readable = true;
+
+                                if (ev[i].events & (EPOLLOUT|EPOLLHUP))
+                                        master_writable = true;
+
+                        } else if (ev[i].data.fd == signal_fd) {
+                                struct signalfd_siginfo sfsi;
+                                ssize_t n;
+
+                                n = read(signal_fd, &sfsi, sizeof(sfsi));
+                                if (n != sizeof(sfsi)) {
+
+                                        if (n >= 0) {
+                                                log_error("Failed to read from signalfd: invalid block size");
+                                                r = -EIO;
+                                                goto finish;
+                                        }
+
+                                        if (errno != EINTR && errno != EAGAIN) {
+                                                log_error("Failed to read from signalfd: %m");
+                                                r = -errno;
+                                                goto finish;
+                                        }
+                                } else {
+
+                                        if (sfsi.ssi_signo == SIGWINCH) {
+                                                struct winsize ws;
+
+                                                /* The window size changed, let's forward that. */
+                                                if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
+                                                        ioctl(master, TIOCSWINSZ, &ws);
+                                        } else if (sfsi.ssi_signo == SIGTERM && arg_boot && !tried_orderly_shutdown) {
+
+                                                log_info("Trying to halt container. Send SIGTERM again to trigger immediate termination.");
+
+                                                /* This only works for systemd... */
+                                                tried_orderly_shutdown = true;
+                                                kill(pid, SIGRTMIN+3);
+
+                                        } else {
+                                                r = 0;
+                                                goto finish;
+                                        }
+                                }
+                        }
+                }
+
+                while ((stdin_readable && in_buffer_full <= 0) ||
+                       (master_writable && in_buffer_full > 0) ||
+                       (master_readable && out_buffer_full <= 0) ||
+                       (stdout_writable && out_buffer_full > 0)) {
+
+                        if (stdin_readable && in_buffer_full < LINE_MAX) {
+
+                                k = read(STDIN_FILENO, in_buffer + in_buffer_full, LINE_MAX - in_buffer_full);
+                                if (k < 0) {
+
+                                        if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
+                                                stdin_readable = false;
+                                        else {
+                                                log_error("read(): %m");
+                                                r = -errno;
+                                                goto finish;
+                                        }
+                                } else
+                                        in_buffer_full += (size_t) k;
+                        }
+
+                        if (master_writable && in_buffer_full > 0) {
+
+                                k = write(master, in_buffer, in_buffer_full);
+                                if (k < 0) {
+
+                                        if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
+                                                master_writable = false;
+                                        else {
+                                                log_error("write(): %m");
+                                                r = -errno;
+                                                goto finish;
+                                        }
+
+                                } else {
+                                        assert(in_buffer_full >= (size_t) k);
+                                        memmove(in_buffer, in_buffer + k, in_buffer_full - k);
+                                        in_buffer_full -= k;
+                                }
+                        }
+
+                        if (master_readable && out_buffer_full < LINE_MAX) {
+
+                                k = read(master, out_buffer + out_buffer_full, LINE_MAX - out_buffer_full);
+                                if (k < 0) {
+
+                                        if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
+                                                master_readable = false;
+                                        else {
+                                                log_error("read(): %m");
+                                                r = -errno;
+                                                goto finish;
+                                        }
+                                }  else
+                                        out_buffer_full += (size_t) k;
+                        }
+
+                        if (stdout_writable && out_buffer_full > 0) {
+
+                                k = write(STDOUT_FILENO, out_buffer, out_buffer_full);
+                                if (k < 0) {
+
+                                        if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
+                                                stdout_writable = false;
+                                        else {
+                                                log_error("write(): %m");
+                                                r = -errno;
+                                                goto finish;
+                                        }
+
+                                } else {
+                                        assert(out_buffer_full >= (size_t) k);
+                                        memmove(out_buffer, out_buffer + k, out_buffer_full - k);
+                                        out_buffer_full -= k;
+                                }
+                        }
+                }
+        }
+
+finish:
+        if (ep >= 0)
+                close_nointr_nofail(ep);
+
+        if (signal_fd >= 0)
+                close_nointr_nofail(signal_fd);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        pid_t pid = 0;
+        int r = EXIT_FAILURE, k;
+        char *oldcg = NULL, *newcg = NULL;
+        char **controller = NULL;
+        int master = -1, n_fd_passed;
+        const char *console = NULL;
+        struct termios saved_attr, raw_attr;
+        sigset_t mask;
+        bool saved_attr_valid = false;
+        struct winsize ws;
+        int kmsg_socket_pair[2] = { -1, -1 };
+        FDSet *fds = NULL;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        if (arg_directory) {
+                char *p;
+
+                p = path_make_absolute_cwd(arg_directory);
+                free(arg_directory);
+                arg_directory = p;
+        } else
+                arg_directory = get_current_dir_name();
+
+        if (!arg_directory) {
+                log_error("Failed to determine path");
+                goto finish;
+        }
+
+        path_kill_slashes(arg_directory);
+
+        if (geteuid() != 0) {
+                log_error("Need to be root.");
+                goto finish;
+        }
+
+        if (sd_booted() <= 0) {
+                log_error("Not running on a systemd system.");
+                goto finish;
+        }
+
+        if (path_equal(arg_directory, "/")) {
+                log_error("Spawning container on root directory not supported.");
+                goto finish;
+        }
+
+        if (is_os_tree(arg_directory) <= 0) {
+                log_error("Directory %s doesn't look like an OS root directory. Refusing.", arg_directory);
+                goto finish;
+        }
+
+        log_close();
+        n_fd_passed = sd_listen_fds(false);
+        if (n_fd_passed > 0) {
+                k = fdset_new_listen_fds(&fds, false);
+                if (k < 0) {
+                        log_error("Failed to collect file descriptors: %s", strerror(-k));
+                        goto finish;
+                }
+        }
+        fdset_close_others(fds);
+        log_open();
+
+        k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg);
+        if (k < 0) {
+                log_error("Failed to determine current cgroup: %s", strerror(-k));
+                goto finish;
+        }
+
+        if (asprintf(&newcg, "%s/nspawn-%lu", oldcg, (unsigned long) getpid()) < 0) {
+                log_error("Failed to allocate cgroup path.");
+                goto finish;
+        }
+
+        k = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, newcg, 0);
+        if (k < 0)  {
+                log_error("Failed to create cgroup: %s", strerror(-k));
+                goto finish;
+        }
+
+        STRV_FOREACH(controller, arg_controllers) {
+                k = cg_create_and_attach(*controller, newcg, 0);
+                if (k < 0)
+                        log_warning("Failed to create cgroup in controller %s: %s", *controller, strerror(-k));
+        }
+
+        master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
+        if (master < 0) {
+                log_error("Failed to acquire pseudo tty: %m");
+                goto finish;
+        }
+
+        console = ptsname(master);
+        if (!console) {
+                log_error("Failed to determine tty name: %m");
+                goto finish;
+        }
+
+        log_info("Spawning namespace container on %s (console is %s).", arg_directory, console);
+
+        if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
+                ioctl(master, TIOCSWINSZ, &ws);
+
+        if (unlockpt(master) < 0) {
+                log_error("Failed to unlock tty: %m");
+                goto finish;
+        }
+
+        if (tcgetattr(STDIN_FILENO, &saved_attr) >= 0) {
+                saved_attr_valid = true;
+
+                raw_attr = saved_attr;
+                cfmakeraw(&raw_attr);
+                raw_attr.c_lflag &= ~ECHO;
+        }
+
+        if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) {
+                log_error("Failed to create kmsg socket pair");
+                goto finish;
+        }
+
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1);
+        assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
+
+        for (;;) {
+                siginfo_t status;
+
+                if (saved_attr_valid) {
+                        if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
+                                log_error("Failed to set terminal attributes: %m");
+                                goto finish;
+                        }
+                }
+
+                pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL);
+                if (pid < 0) {
+                        if (errno == EINVAL)
+                                log_error("clone() failed, do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in): %m");
+                        else
+                                log_error("clone() failed: %m");
+
+                        goto finish;
+                }
+
+                if (pid == 0) {
+                        /* child */
+
+                        const char *home = NULL;
+                        uid_t uid = (uid_t) -1;
+                        gid_t gid = (gid_t) -1;
+                        unsigned n_env = 0;
+                        const char *envp[] = {
+                                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+                                "container=systemd-nspawn", /* LXC sets container=lxc, so follow the scheme here */
+                                NULL, /* TERM */
+                                NULL, /* HOME */
+                                NULL, /* USER */
+                                NULL, /* LOGNAME */
+                                NULL, /* container_uuid */
+                                NULL, /* LISTEN_FDS */
+                                NULL, /* LISTEN_PID */
+                                NULL
+                        };
+
+                        envp[2] = strv_find_prefix(environ, "TERM=");
+                        n_env = 3;
+
+                        close_nointr_nofail(master);
+                        master = -1;
+
+                        close_nointr(STDIN_FILENO);
+                        close_nointr(STDOUT_FILENO);
+                        close_nointr(STDERR_FILENO);
+
+                        close_nointr_nofail(kmsg_socket_pair[0]);
+                        kmsg_socket_pair[0] = -1;
+
+                        reset_all_signal_handlers();
+
+                        assert_se(sigemptyset(&mask) == 0);
+                        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+                        k = open_terminal(console, O_RDWR);
+                        if (k != STDIN_FILENO) {
+                                if (k >= 0) {
+                                        close_nointr_nofail(k);
+                                        k = -EINVAL;
+                                }
+
+                                log_error("Failed to open console: %s", strerror(-k));
+                                goto child_fail;
+                        }
+
+                        if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
+                            dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) {
+                                log_error("Failed to duplicate console: %m");
+                                goto child_fail;
+                        }
+
+                        if (setsid() < 0) {
+                                log_error("setsid() failed: %m");
+                                goto child_fail;
+                        }
+
+                        if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) {
+                                log_error("PR_SET_PDEATHSIG failed: %m");
+                                goto child_fail;
+                        }
+
+                        /* Mark everything as slave, so that we still
+                         * receive mounts from the real root, but don't
+                         * propagate mounts to the real root. */
+                        if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
+                                log_error("MS_SLAVE|MS_REC failed: %m");
+                                goto child_fail;
+                        }
+
+                        /* Turn directory into bind mount */
+                        if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REC, NULL) < 0) {
+                                log_error("Failed to make bind mount.");
+                                goto child_fail;
+                        }
+
+                        if (arg_read_only)
+                                if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) {
+                                        log_error("Failed to make read-only.");
+                                        goto child_fail;
+                                }
+
+                        if (mount_all(arg_directory) < 0)
+                                goto child_fail;
+
+                        if (copy_devnodes(arg_directory) < 0)
+                                goto child_fail;
+
+                        dev_setup(arg_directory);
+
+                        if (setup_dev_console(arg_directory, console) < 0)
+                                goto child_fail;
+
+                        if (setup_kmsg(arg_directory, kmsg_socket_pair[1]) < 0)
+                                goto child_fail;
+
+                        close_nointr_nofail(kmsg_socket_pair[1]);
+                        kmsg_socket_pair[1] = -1;
+
+                        if (setup_boot_id(arg_directory) < 0)
+                                goto child_fail;
+
+                        if (setup_timezone(arg_directory) < 0)
+                                goto child_fail;
+
+                        if (setup_resolv_conf(arg_directory) < 0)
+                                goto child_fail;
+
+                        if (setup_journal(arg_directory) < 0)
+                                goto child_fail;
+
+                        if (chdir(arg_directory) < 0) {
+                                log_error("chdir(%s) failed: %m", arg_directory);
+                                goto child_fail;
+                        }
+
+                        if (mount(arg_directory, "/", NULL, MS_MOVE, NULL) < 0) {
+                                log_error("mount(MS_MOVE) failed: %m");
+                                goto child_fail;
+                        }
+
+                        if (chroot(".") < 0) {
+                                log_error("chroot() failed: %m");
+                                goto child_fail;
+                        }
+
+                        if (chdir("/") < 0) {
+                                log_error("chdir() failed: %m");
+                                goto child_fail;
+                        }
+
+                        umask(0022);
+
+                        loopback_setup();
+
+                        if (drop_capabilities() < 0) {
+                                log_error("drop_capabilities() failed: %m");
+                                goto child_fail;
+                        }
+
+                        if (arg_user) {
+
+                                /* Note that this resolves user names
+                                 * inside the container, and hence
+                                 * accesses the NSS modules from the
+                                 * container and not the host. This is
+                                 * a bit weird... */
+
+                                if (get_user_creds((const char**)&arg_user, &uid, &gid, &home, NULL) < 0) {
+                                        log_error("get_user_creds() failed: %m");
+                                        goto child_fail;
+                                }
+
+                                if (mkdir_parents_label(home, 0775) < 0) {
+                                        log_error("mkdir_parents_label() failed: %m");
+                                        goto child_fail;
+                                }
+
+                                if (mkdir_safe_label(home, 0775, uid, gid) < 0) {
+                                        log_error("mkdir_safe_label() failed: %m");
+                                        goto child_fail;
+                                }
+
+                                if (initgroups((const char*)arg_user, gid) < 0) {
+                                        log_error("initgroups() failed: %m");
+                                        goto child_fail;
+                                }
+
+                                if (setresgid(gid, gid, gid) < 0) {
+                                        log_error("setregid() failed: %m");
+                                        goto child_fail;
+                                }
+
+                                if (setresuid(uid, uid, uid) < 0) {
+                                        log_error("setreuid() failed: %m");
+                                        goto child_fail;
+                                }
+                        } else {
+                                /* Reset everything fully to 0, just in case */
+
+                                if (setgroups(0, NULL) < 0) {
+                                        log_error("setgroups() failed: %m");
+                                        goto child_fail;
+                                }
+
+                                if (setresgid(0, 0, 0) < 0) {
+                                        log_error("setregid() failed: %m");
+                                        goto child_fail;
+                                }
+
+                                if (setresuid(0, 0, 0) < 0) {
+                                        log_error("setreuid() failed: %m");
+                                        goto child_fail;
+                                }
+                        }
+
+                        if ((asprintf((char**)(envp + n_env++), "HOME=%s", home ? home: "/root") < 0) ||
+                            (asprintf((char**)(envp + n_env++), "USER=%s", arg_user ? arg_user : "root") < 0) ||
+                            (asprintf((char**)(envp + n_env++), "LOGNAME=%s", arg_user ? arg_user : "root") < 0)) {
+                                log_oom();
+                                goto child_fail;
+                        }
+
+                        if (arg_uuid) {
+                                if (asprintf((char**)(envp + n_env++), "container_uuid=%s", arg_uuid) < 0) {
+                                        log_oom();
+                                        goto child_fail;
+                                }
+                        }
+
+                        if (fdset_size(fds) > 0) {
+                                k = fdset_cloexec(fds, false);
+                                if (k < 0) {
+                                        log_error("Failed to unset O_CLOEXEC for file descriptors.");
+                                        goto child_fail;
+                                }
+
+                                if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", n_fd_passed) < 0) ||
+                                    (asprintf((char **)(envp + n_env++), "LISTEN_PID=%lu", (unsigned long) getpid()) < 0)) {
+                                        log_oom();
+                                        goto child_fail;
+                                }
+                        }
+
+                        setup_hostname();
+
+                        if (arg_boot) {
+                                char **a;
+                                size_t l;
+
+                                /* Automatically search for the init system */
+
+                                l = 1 + argc - optind;
+                                a = newa(char*, l + 1);
+                                memcpy(a + 1, argv + optind, l * sizeof(char*));
+
+                                a[0] = (char*) "/usr/lib/systemd/systemd";
+                                execve(a[0], a, (char**) envp);
+
+                                a[0] = (char*) "/lib/systemd/systemd";
+                                execve(a[0], a, (char**) envp);
+
+                                a[0] = (char*) "/sbin/init";
+                                execve(a[0], a, (char**) envp);
+                        } else if (argc > optind)
+                                execvpe(argv[optind], argv + optind, (char**) envp);
+                        else {
+                                chdir(home ? home : "/root");
+                                execle("/bin/bash", "-bash", NULL, (char**) envp);
+                        }
+
+                        log_error("execv() failed: %m");
+
+                child_fail:
+                        _exit(EXIT_FAILURE);
+                }
+
+                fdset_free(fds);
+                fds = NULL;
+
+                if (process_pty(master, pid, &mask) < 0)
+                        goto finish;
+
+                if (saved_attr_valid)
+                        tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
+
+                r = wait_for_terminate(pid, &status);
+                if (r < 0) {
+                        r = EXIT_FAILURE;
+                        break;
+                }
+
+                if (status.si_code == CLD_EXITED) {
+                        if (status.si_status != 0) {
+                                log_error("Container failed with error code %i.", status.si_status);
+                                r = status.si_status;
+                                break;
+                        }
+
+                        log_debug("Container exited successfully.");
+                        break;
+                } else if (status.si_code == CLD_KILLED &&
+                           status.si_status == SIGINT) {
+                        log_info("Container has been shut down.");
+                        r = 0;
+                        break;
+                } else if (status.si_code == CLD_KILLED &&
+                           status.si_status == SIGHUP) {
+                        log_info("Container is being rebooted.");
+                        continue;
+                } else if (status.si_code == CLD_KILLED ||
+                           status.si_code == CLD_DUMPED) {
+
+                        log_error("Container terminated by signal %s.", signal_to_string(status.si_status));
+                        r = EXIT_FAILURE;
+                        break;
+                } else {
+                        log_error("Container failed due to unknown reason.");
+                        r = EXIT_FAILURE;
+                        break;
+                }
+        }
+
+finish:
+        if (saved_attr_valid)
+                tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
+
+        if (master >= 0)
+                close_nointr_nofail(master);
+
+        close_pipe(kmsg_socket_pair);
+
+        if (oldcg)
+                cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0);
+
+        if (newcg)
+                cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true);
+
+        free(arg_directory);
+        strv_free(arg_controllers);
+        free(oldcg);
+        free(newcg);
+
+        fdset_free(fds);
+
+        return r;
+}
diff --git a/src/python-systemd/Makefile b/src/python-systemd/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/python-systemd/__init__.py b/src/python-systemd/__init__.py
new file mode 100644 (file)
index 0000000..0d56b99
--- /dev/null
@@ -0,0 +1,18 @@
+#  -*- Mode: python; indent-tabs-mode: nil -*- */
+#
+#  This file is part of systemd.
+#
+#  Copyright 2012 David Strauss
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
diff --git a/src/python-systemd/_journal.c b/src/python-systemd/_journal.c
new file mode 100644 (file)
index 0000000..0bdf709
--- /dev/null
@@ -0,0 +1,141 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 David Strauss
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <Python.h>
+
+#include <alloca.h>
+
+#define SD_JOURNAL_SUPPRESS_LOCATION
+#include <systemd/sd-journal.h>
+
+PyDoc_STRVAR(journal_sendv__doc__,
+             "sendv('FIELD=value', 'FIELD=value', ...) -> None\n\n"
+             "Send an entry to the journal."
+);
+
+static PyObject *journal_sendv(PyObject *self, PyObject *args) {
+        struct iovec *iov = NULL;
+        int argc;
+        int i, r;
+        PyObject *ret = NULL;
+        PyObject **encoded;
+
+        /* Allocate an array for the argument strings */
+        argc = PyTuple_Size(args);
+        encoded = alloca(argc * sizeof(PyObject*));
+        memset(encoded, 0, argc * sizeof(PyObject*));
+
+        /* Allocate sufficient iovector space for the arguments. */
+        iov = alloca(argc * sizeof(struct iovec));
+
+        /* Iterate through the Python arguments and fill the iovector. */
+        for (i = 0; i < argc; ++i) {
+                PyObject *item = PyTuple_GetItem(args, i);
+                char *stritem;
+                Py_ssize_t length;
+
+                if (PyUnicode_Check(item)) {
+                        encoded[i] = PyUnicode_AsEncodedString(item, "utf-8", "strict");
+                        if (encoded[i] == NULL)
+                                goto out;
+                        item = encoded[i];
+                }
+                if (PyBytes_AsStringAndSize(item, &stritem, &length))
+                        goto out;
+
+                iov[i].iov_base = stritem;
+                iov[i].iov_len = length;
+        }
+
+        /* Send the iovector to the journal. */
+        r = sd_journal_sendv(iov, argc);
+        if (r < 0) {
+                errno = -r;
+                PyErr_SetFromErrno(PyExc_IOError);
+                goto out;
+        }
+
+        /* End with success. */
+        Py_INCREF(Py_None);
+        ret = Py_None;
+
+out:
+        for (i = 0; i < argc; ++i)
+                Py_XDECREF(encoded[i]);
+
+        return ret;
+}
+
+PyDoc_STRVAR(journal_stream_fd__doc__,
+             "stream_fd(identifier, priority, level_prefix) -> fd\n\n"
+             "Open a stream to journal by calling sd_journal_stream_fd(3)."
+);
+
+static PyObject* journal_stream_fd(PyObject *self, PyObject *args) {
+        const char* identifier;
+        int priority, level_prefix;
+        int fd;
+
+        if (!PyArg_ParseTuple(args, "sii:stream_fd",
+                              &identifier, &priority, &level_prefix))
+                return NULL;
+
+        fd = sd_journal_stream_fd(identifier, priority, level_prefix);
+        if (fd < 0) {
+                errno = -fd;
+                return PyErr_SetFromErrno(PyExc_IOError);
+        }
+
+        return PyLong_FromLong(fd);
+}
+
+static PyMethodDef methods[] = {
+        { "sendv",  journal_sendv, METH_VARARGS, journal_sendv__doc__ },
+        { "stream_fd", journal_stream_fd, METH_VARARGS, journal_stream_fd__doc__ },
+        { NULL, NULL, 0, NULL }        /* Sentinel */
+};
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+
+#if PY_MAJOR_VERSION < 3
+
+PyMODINIT_FUNC init_journal(void) {
+        (void) Py_InitModule("_journal", methods);
+}
+
+#else
+
+static struct PyModuleDef module = {
+        PyModuleDef_HEAD_INIT,
+        "_journal", /* name of module */
+        NULL, /* module documentation, may be NULL */
+        0, /* size of per-interpreter state of the module */
+        methods
+};
+
+PyMODINIT_FUNC PyInit__journal(void) {
+        return PyModule_Create(&module);
+}
+
+#endif
+
+#pragma GCC diagnostic pop
diff --git a/src/python-systemd/journal.py b/src/python-systemd/journal.py
new file mode 100644 (file)
index 0000000..516ca1a
--- /dev/null
@@ -0,0 +1,201 @@
+#  -*- Mode: python; indent-tabs-mode: nil -*- */
+#
+#  This file is part of systemd.
+#
+#  Copyright 2012 David Strauss
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+import traceback as _traceback
+import os as _os
+import logging as _logging
+from syslog import (LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
+                    LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG)
+from ._journal import sendv, stream_fd
+
+def _make_line(field, value):
+        if isinstance(value, bytes):
+                return field.encode('utf-8') + b'=' + value
+        else:
+                return field + '=' + value
+
+def send(MESSAGE, MESSAGE_ID=None,
+         CODE_FILE=None, CODE_LINE=None, CODE_FUNC=None,
+         **kwargs):
+        r"""Send a message to journald.
+
+        >>> journal.send('Hello world')
+        >>> journal.send('Hello, again, world', FIELD2='Greetings!')
+        >>> journal.send('Binary message', BINARY=b'\xde\xad\xbe\xef')
+
+        Value of the MESSAGE argument will be used for the MESSAGE=
+        field.
+
+        MESSAGE_ID can be given to uniquely identify the type of
+        message.
+
+        Other parts of the message can be specified as keyword
+        arguments.
+
+        Both MESSAGE and MESSAGE_ID, if present, must be strings, and
+        will be sent as UTF-8 to journal. Other arguments can be
+        bytes, in which case they will be sent as-is to journal.
+
+        CODE_LINE, CODE_FILE, and CODE_FUNC can be specified to
+        identify the caller. Unless at least on of the three is given,
+        values are extracted from the stack frame of the caller of
+        send(). CODE_FILE and CODE_FUNC must be strings, CODE_LINE
+        must be an integer.
+
+        Other useful fields include PRIORITY, SYSLOG_FACILITY,
+        SYSLOG_IDENTIFIER, SYSLOG_PID.
+        """
+
+        args = ['MESSAGE=' + MESSAGE]
+
+        if MESSAGE_ID is not None:
+                args.append('MESSAGE_ID=' + MESSAGE_ID)
+
+        if CODE_LINE == CODE_FILE == CODE_FUNC == None:
+                CODE_FILE, CODE_LINE, CODE_FUNC = \
+                        _traceback.extract_stack(limit=2)[0][:3]
+        if CODE_FILE is not None:
+                args.append('CODE_FILE=' + CODE_FILE)
+        if CODE_LINE is not None:
+                args.append('CODE_LINE={:d}'.format(CODE_LINE))
+        if CODE_FUNC is not None:
+                args.append('CODE_FUNC=' + CODE_FUNC)
+
+        args.extend(_make_line(key, val) for key, val in kwargs.items())
+        return sendv(*args)
+
+def stream(identifier, priority=LOG_DEBUG, level_prefix=False):
+        r"""Return a file object wrapping a stream to journal.
+
+        Log messages written to this file as simple newline sepearted
+        text strings are written to the journal.
+
+        The file will be line buffered, so messages are actually sent
+        after a newline character is written.
+
+        >>> stream = journal.stream('myapp')
+        >>> stream
+        <open file '<fdopen>', mode 'w' at 0x...>
+        >>> stream.write('message...\n')
+
+        will produce the following message in the journal:
+
+        PRIORITY=7
+        SYSLOG_IDENTIFIER=myapp
+        MESSAGE=message...
+
+        Using the interface with print might be more convinient:
+
+        >>> from __future__ import print_function
+        >>> print('message...', file=stream)
+
+        priority is the syslog priority, one of LOG_EMERG, LOG_ALERT,
+        LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG.
+
+        level_prefix is a boolean. If true, kernel-style log priority
+        level prefixes (such as '<1>') are interpreted. See
+        sd-daemon(3) for more information.
+        """
+
+        fd = stream_fd(identifier, priority, level_prefix)
+        return _os.fdopen(fd, 'w', 1)
+
+class JournalHandler(_logging.Handler):
+        """Journal handler class for the Python logging framework.
+
+        Please see the Python logging module documentation for an
+        overview: http://docs.python.org/library/logging.html
+
+        To create a custom logger whose messages go only to journal:
+
+        >>> log = logging.getLogger('custom_logger_name')
+        >>> log.propagate = False
+        >>> log.addHandler(journal.JournalHandler())
+        >>> log.warn("Some message: %s", detail)
+
+        Note that by default, message levels INFO and DEBUG are ignored
+        by the logging framework. To enable those log levels:
+
+        >>> log.setLevel(logging.DEBUG)
+
+        To attach journal MESSAGE_ID, an extra field is supported:
+
+        >>> log.warn("Message with ID",
+        >>>     extra={'MESSAGE_ID': '22bb01335f724c959ac4799627d1cb61'})
+
+        To redirect all logging messages to journal regardless of where
+        they come from, attach it to the root logger:
+
+        >>> logging.root.addHandler(journal.JournalHandler())
+
+        For more complex configurations when using dictConfig or
+        fileConfig, specify 'systemd.journal.JournalHandler' as the
+        handler class.  Only standard handler configuration options
+        are supported: level, formatter, filters.
+
+        The following journal fields will be sent:
+
+        MESSAGE, PRIORITY, THREAD_NAME, CODE_FILE, CODE_LINE,
+        CODE_FUNC, LOGGER (name as supplied to getLogger call),
+        MESSAGE_ID (optional, see above).
+        """
+
+        def emit(self, record):
+                """Write record as journal event.
+
+                MESSAGE is taken from the message provided by the
+                user, and PRIORITY, LOGGER, THREAD_NAME,
+                CODE_{FILE,LINE,FUNC} fields are appended
+                automatically. In addition, record.MESSAGE_ID will be
+                used if present.
+                """
+                try:
+                        msg = self.format(record)
+                        pri = self.mapPriority(record.levelno)
+                        mid = getattr(record, 'MESSAGE_ID', None)
+                        send(msg,
+                             MESSAGE_ID=mid,
+                             PRIORITY=format(pri),
+                             LOGGER=record.name,
+                             THREAD_NAME=record.threadName,
+                             CODE_FILE=record.pathname,
+                             CODE_LINE=record.lineno,
+                             CODE_FUNC=record.funcName)
+                except Exception:
+                        self.handleError(record)
+
+        @staticmethod
+        def mapPriority(levelno):
+                """Map logging levels to journald priorities.
+
+                Since Python log level numbers are "sparse", we have
+                to map numbers in between the standard levels too.
+                """
+                if levelno <= _logging.DEBUG:
+                        return LOG_DEBUG
+                elif levelno <= _logging.INFO:
+                        return LOG_INFO
+                elif levelno <= _logging.WARNING:
+                        return LOG_WARNING
+                elif levelno <= _logging.ERROR:
+                        return LOG_ERR
+                elif levelno <= _logging.CRITICAL:
+                        return LOG_CRIT
+                else:
+                        return LOG_ALERT
diff --git a/src/quotacheck/Makefile b/src/quotacheck/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c
new file mode 100644 (file)
index 0000000..e7a4405
--- /dev/null
@@ -0,0 +1,123 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "virt.h"
+
+static bool arg_skip = false;
+static bool arg_force = false;
+
+static int parse_proc_cmdline(void) {
+        char *line, *w, *state;
+        int r;
+        size_t l;
+
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) {
+                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+
+                if (strneq(w, "quotacheck.mode=auto", l))
+                        arg_force = arg_skip = false;
+                else if (strneq(w, "quotacheck.mode=force", l))
+                        arg_force = true;
+                else if (strneq(w, "quotacheck.mode=skip", l))
+                        arg_skip = true;
+                else if (startswith(w, "quotacheck"))
+                        log_warning("Invalid quotacheck parameter. Ignoring.");
+#ifdef HAVE_SYSV_COMPAT
+                else if (strneq(w, "forcequotacheck", l)) {
+                        log_error("Please use 'quotacheck.mode=force' rather than 'forcequotacheck' on the kernel command line.");
+                        arg_force = true;
+                }
+#endif
+        }
+
+        free(line);
+        return 0;
+}
+
+static void test_files(void) {
+#ifdef HAVE_SYSV_COMPAT
+        if (access("/forcequotacheck", F_OK) >= 0) {
+                log_error("Please pass 'quotacheck.mode=force' on the kernel command line rather than creating /forcequotacheck on the root file system.");
+                arg_force = true;
+        }
+#endif
+}
+
+int main(int argc, char *argv[]) {
+        static const char * const cmdline[] = {
+                "/sbin/quotacheck",
+                "-anug",
+                NULL
+        };
+
+        int r = EXIT_FAILURE;
+        pid_t pid;
+
+        if (argc > 1) {
+                log_error("This program takes no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        parse_proc_cmdline();
+        test_files();
+
+        if (!arg_force) {
+                if (arg_skip)
+                        return 0;
+
+                if (access("/run/systemd/quotacheck", F_OK) < 0)
+                        return 0;
+        }
+
+        if ((pid = fork()) < 0) {
+                log_error("fork(): %m");
+                goto finish;
+        } else if (pid == 0) {
+                /* Child */
+                execv(cmdline[0], (char**) cmdline);
+                _exit(1); /* Operational error */
+        }
+
+        r = wait_for_terminate_and_warn("quotacheck", pid) == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+
+finish:
+        return r;
+}
diff --git a/src/random-seed/Makefile b/src/random-seed/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
new file mode 100644 (file)
index 0000000..fdcaa1e
--- /dev/null
@@ -0,0 +1,149 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "log.h"
+#include "util.h"
+#include "mkdir.h"
+
+#define POOL_SIZE_MIN 512
+
+int main(int argc, char *argv[]) {
+        int seed_fd = -1, random_fd = -1;
+        int ret = EXIT_FAILURE;
+        void* buf;
+        size_t buf_size = 0;
+        ssize_t r;
+        FILE *f;
+
+        if (argc != 2) {
+                log_error("This program requires one argument.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        /* Read pool size, if possible */
+        if ((f = fopen("/proc/sys/kernel/random/poolsize", "re"))) {
+                if (fscanf(f, "%zu", &buf_size) > 0) {
+                        /* poolsize is in bits on 2.6, but we want bytes */
+                        buf_size /= 8;
+                }
+
+                fclose(f);
+        }
+
+        if (buf_size <= POOL_SIZE_MIN)
+                buf_size = POOL_SIZE_MIN;
+
+        if (!(buf = malloc(buf_size))) {
+                log_error("Failed to allocate buffer.");
+                goto finish;
+        }
+
+        if (mkdir_parents_label(RANDOM_SEED, 0755) < 0) {
+                log_error("Failed to create directories parents of %s: %m", RANDOM_SEED);
+                goto finish;
+        }
+
+        /* When we load the seed we read it and write it to the device
+         * and then immediately update the saved seed with new data,
+         * to make sure the next boot gets seeded differently. */
+
+        if (streq(argv[1], "load")) {
+
+                if ((seed_fd = open(RANDOM_SEED, O_RDWR|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600)) < 0) {
+                        if ((seed_fd = open(RANDOM_SEED, O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) {
+                                log_error("Failed to open random seed: %m");
+                                goto finish;
+                        }
+                }
+
+                if ((random_fd = open("/dev/urandom", O_RDWR|O_CLOEXEC|O_NOCTTY, 0600)) < 0) {
+                        if ((random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY, 0600)) < 0) {
+                                log_error("Failed to open /dev/urandom: %m");
+                                goto finish;
+                        }
+                }
+
+                if ((r = loop_read(seed_fd, buf, buf_size, false)) <= 0) {
+
+                        if (r != 0)
+                                log_error("Failed to read seed file: %m");
+                } else {
+                        lseek(seed_fd, 0, SEEK_SET);
+
+                        if ((r = loop_write(random_fd, buf, (size_t) r, false)) <= 0)
+                                log_error("Failed to write seed to /dev/urandom: %s",
+                                          r < 0 ? strerror(errno) : "short write");
+                }
+
+        } else if (streq(argv[1], "save")) {
+
+                if ((seed_fd = open(RANDOM_SEED, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600)) < 0) {
+                        log_error("Failed to open random seed: %m");
+                        goto finish;
+                }
+
+                if ((random_fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) {
+                        log_error("Failed to open /dev/urandom: %m");
+                        goto finish;
+                }
+        } else {
+                log_error("Unknown verb %s.", argv[1]);
+                goto finish;
+        }
+
+        /* This is just a safety measure. Given that we are root and
+         * most likely created the file ourselves the mode and owner
+         * should be correct anyway. */
+        fchmod(seed_fd, 0600);
+        fchown(seed_fd, 0, 0);
+
+        if ((r = loop_read(random_fd, buf, buf_size, false)) <= 0)
+                log_error("Failed to read new seed from /dev/urandom: %s", r < 0 ? strerror(errno) : "EOF");
+        else {
+                if ((r = loop_write(seed_fd, buf, (size_t) r, false)) <= 0)
+                        log_error("Failed to write new random seed file: %s", r < 0 ? strerror(errno) : "short write");
+        }
+
+        ret = EXIT_SUCCESS;
+
+finish:
+        if (random_fd >= 0)
+                close_nointr_nofail(random_fd);
+
+        if (seed_fd >= 0)
+                close_nointr_nofail(seed_fd);
+
+        free(buf);
+
+        return ret;
+}
diff --git a/src/rc-local-generator/Makefile b/src/rc-local-generator/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/rc-local-generator/rc-local-generator.c b/src/rc-local-generator/rc-local-generator.c
new file mode 100644 (file)
index 0000000..448980b
--- /dev/null
@@ -0,0 +1,115 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright 2011 Michal Schmidt
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+#include "mkdir.h"
+
+#ifndef RC_LOCAL_SCRIPT_PATH_START
+#define RC_LOCAL_SCRIPT_PATH_START "/etc/rc.d/rc.local"
+#endif
+
+#ifndef RC_LOCAL_SCRIPT_PATH_STOP
+#define RC_LOCAL_SCRIPT_PATH_STOP "/sbin/halt.local"
+#endif
+
+const char *arg_dest = "/tmp";
+
+static int add_symlink(const char *service, const char *where) {
+        char *from = NULL, *to = NULL;
+        int r;
+
+        assert(service);
+
+        asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", service);
+        asprintf(&to, "%s/%s.wants/%s", arg_dest, where, service);
+
+        if (!from || !to) {
+                r = log_oom();
+                goto finish;
+        }
+
+        mkdir_parents_label(to, 0755);
+
+        r = symlink(from, to);
+        if (r < 0) {
+                if (errno == EEXIST)
+                        r = 0;
+                else {
+                        log_error("Failed to create symlink from %s to %s: %m", from, to);
+                        r = -errno;
+                }
+        }
+
+finish:
+        free(from);
+        free(to);
+
+        return r;
+}
+
+static bool file_is_executable(const char *f) {
+        struct stat st;
+
+        if (stat(f, &st) < 0)
+                return false;
+
+        return S_ISREG(st.st_mode) && (st.st_mode & 0111);
+}
+
+int main(int argc, char *argv[]) {
+        int r = EXIT_SUCCESS;
+
+        if (argc > 1 && argc != 4) {
+                log_error("This program takes three or no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1)
+                arg_dest = argv[1];
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (file_is_executable(RC_LOCAL_SCRIPT_PATH_START)) {
+                log_debug("Automatically adding rc-local.service.");
+
+                if (add_symlink("rc-local.service", "multi-user.target") < 0)
+                        r = EXIT_FAILURE;
+        }
+
+        if (file_is_executable(RC_LOCAL_SCRIPT_PATH_STOP)) {
+                log_debug("Automatically adding halt-local.service.");
+
+                if (add_symlink("halt-local.service", "final.target") < 0)
+                        r = EXIT_FAILURE;
+        }
+
+        return r;
+}
diff --git a/src/readahead/Makefile b/src/readahead/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/readahead/readahead-analyze.c b/src/readahead/readahead-analyze.c
new file mode 100644 (file)
index 0000000..9a929c0
--- /dev/null
@@ -0,0 +1,150 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Auke Kok <auke-jan.h.kok@intel.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <linux/limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include "readahead-common.h"
+
+int main_analyze(const char *pack_path) {
+        char line[LINE_MAX];
+        FILE *pack;
+        int a;
+        int missing = 0;
+        off_t tsize = 0;
+
+        if (!pack_path)
+                pack_path = "/.readahead";
+
+        pack = fopen(pack_path, "re");
+        if (!pack) {
+                log_error("Pack file missing.");
+                goto fail;
+        }
+
+        if (!fgets(line, sizeof(line), pack)) {
+                log_error("Pack file corrupt.");
+                goto fail;
+        }
+
+        char_array_0(line);
+
+        if (!endswith(line, READAHEAD_PACK_FILE_VERSION)) {
+                log_error("Pack file version incompatible with this parser.");
+                goto fail;
+        }
+
+        if ((a = getc(pack)) == EOF) {
+                log_error("Pack file corrupt.");
+                goto fail;
+        }
+
+        fputs("   pct  sections     size: path\n"
+              "   ===  ========     ====: ====\n", stdout);
+
+        for (;;) {
+                char path[PATH_MAX];
+                struct stat st;
+                uint64_t inode;
+                int pages = 0;
+                int sections = 0;
+
+                if (!fgets(path, sizeof(path), pack))
+                        break; /* done */
+
+                path[strlen(path)-1] = 0;
+
+                if (fread(&inode, sizeof(inode), 1, pack) != 1) {
+                        log_error("Pack file corrupt.");
+                        goto fail;
+                }
+
+                for (;;) {
+                        uint32_t b, c;
+
+                        if (fread(&b, sizeof(b), 1, pack) != 1  ||
+                            fread(&c, sizeof(c), 1, pack) != 1) {
+                                log_error("Pack file corrupt.");
+                                goto fail;
+                        }
+                        if ((b == 0) && (c == 0))
+                                break;
+
+                        /* Uncomment this to get all the chunks separately
+                           printf(" %d: %d %d\n", sections, b, c);
+                         */
+
+                        pages += (c - b);
+                        sections++;
+                }
+
+                if (stat(path, &st) == 0) {
+                        off_t size;
+
+                        if (sections == 0)
+                                size = st.st_size;
+                        else
+                                size = pages * page_size();
+
+                        tsize += size;
+
+                        printf("  %4d%% (%2d) %12ld: %s\n",
+                                sections ? (int) (size * 100 / st.st_size) : 100,
+                                sections ? sections : 1,
+                                (unsigned long)size,
+                                path);
+                } else {
+                        printf("  %4dp (%2d) %12s: %s (MISSING)\n",
+                                sections ? pages : -1,
+                                sections ? sections : 1,
+                                "???",
+                                path);
+                        missing++;
+                }
+
+        }
+
+        fclose(pack);
+
+        printf("\nHOST:    %s"
+               "TYPE:    %c\n"
+               "MISSING: %d\n"
+               "TOTAL:   %llu\n",
+               line,
+               a,
+               missing,
+               (unsigned long long) tsize);
+
+        return EXIT_SUCCESS;
+
+fail:
+        if(pack)
+                fclose(pack);
+        return EXIT_FAILURE;
+}
diff --git a/src/readahead/readahead-collect.c b/src/readahead/readahead-collect.c
new file mode 100644 (file)
index 0000000..5d07f47
--- /dev/null
@@ -0,0 +1,623 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <linux/fanotify.h>
+#include <sys/signalfd.h>
+#include <sys/poll.h>
+#include <sys/mman.h>
+#include <linux/fs.h>
+#include <linux/fiemap.h>
+#include <sys/ioctl.h>
+#include <sys/vfs.h>
+#include <getopt.h>
+#include <sys/inotify.h>
+
+#ifdef HAVE_FANOTIFY_INIT
+#include <sys/fanotify.h>
+#endif
+
+#include <systemd/sd-daemon.h>
+
+#include "missing.h"
+#include "util.h"
+#include "set.h"
+#include "ioprio.h"
+#include "readahead-common.h"
+#include "virt.h"
+
+/* fixme:
+ *
+ * - detect ssd on btrfs/lvm...
+ * - read ahead directories
+ * - gzip?
+ * - remount rw?
+ * - handle files where nothing is in mincore
+ * - does ioprio_set work with fadvise()?
+ */
+
+static ReadaheadShared *shared = NULL;
+
+/* Avoid collisions with the NULL pointer */
+#define SECTOR_TO_PTR(s) ULONG_TO_PTR((s)+1)
+#define PTR_TO_SECTOR(p) (PTR_TO_ULONG(p)-1)
+
+static int btrfs_defrag(int fd) {
+        struct btrfs_ioctl_vol_args data;
+
+        zero(data);
+        data.fd = fd;
+
+        return ioctl(fd, BTRFS_IOC_DEFRAG, &data);
+}
+
+static int pack_file(FILE *pack, const char *fn, bool on_btrfs) {
+        struct stat st;
+        void *start = MAP_FAILED;
+        uint8_t *vec;
+        uint32_t b, c;
+        uint64_t inode;
+        size_t l, pages;
+        bool mapped;
+        int r = 0, fd = -1, k;
+
+        assert(pack);
+        assert(fn);
+
+        fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW);
+        if (fd < 0) {
+
+                if (errno == ENOENT)
+                        return 0;
+
+                if (errno == EPERM || errno == EACCES)
+                        return 0;
+
+                log_warning("open(%s) failed: %m", fn);
+                r = -errno;
+                goto finish;
+        }
+
+        k = file_verify(fd, fn, arg_file_size_max, &st);
+        if (k <= 0) {
+                r = k;
+                goto finish;
+        }
+
+        if (on_btrfs)
+                btrfs_defrag(fd);
+
+        l = PAGE_ALIGN(st.st_size);
+        start = mmap(NULL, l, PROT_READ, MAP_SHARED, fd, 0);
+        if (start == MAP_FAILED) {
+                log_warning("mmap(%s) failed: %m", fn);
+                r = -errno;
+                goto finish;
+        }
+
+        pages = l / page_size();
+        vec = alloca(pages);
+        memset(vec, 0, pages);
+        if (mincore(start, l, vec) < 0) {
+                log_warning("mincore(%s) failed: %m", fn);
+                r = -errno;
+                goto finish;
+        }
+
+        fputs(fn, pack);
+        fputc('\n', pack);
+
+        /* Store the inode, so that we notice when the file is deleted */
+        inode = (uint64_t) st.st_ino;
+        fwrite(&inode, sizeof(inode), 1, pack);
+
+        mapped = false;
+        for (c = 0; c < pages; c++) {
+                bool new_mapped = !!(vec[c] & 1);
+
+                if (!mapped && new_mapped)
+                        b = c;
+                else if (mapped && !new_mapped) {
+                        fwrite(&b, sizeof(b), 1, pack);
+                        fwrite(&c, sizeof(c), 1, pack);
+
+                        log_debug("%s: page %u to %u", fn, b, c);
+                }
+
+                mapped = new_mapped;
+        }
+
+        /* We don't write any range data if we should read the entire file */
+        if (mapped && b > 0) {
+                fwrite(&b, sizeof(b), 1, pack);
+                fwrite(&c, sizeof(c), 1, pack);
+
+                log_debug("%s: page %u to %u", fn, b, c);
+        }
+
+        /* End marker */
+        b = 0;
+        fwrite(&b, sizeof(b), 1, pack);
+        fwrite(&b, sizeof(b), 1, pack);
+
+finish:
+        if (start != MAP_FAILED)
+                munmap(start, l);
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
+
+static unsigned long fd_first_block(int fd) {
+        struct {
+                struct fiemap fiemap;
+                struct fiemap_extent extent;
+        } data;
+
+        zero(data);
+        data.fiemap.fm_length = ~0ULL;
+        data.fiemap.fm_extent_count = 1;
+
+        if (ioctl(fd, FS_IOC_FIEMAP, &data) < 0)
+                return 0;
+
+        if (data.fiemap.fm_mapped_extents <= 0)
+                return 0;
+
+        if (data.fiemap.fm_extents[0].fe_flags & FIEMAP_EXTENT_UNKNOWN)
+                return 0;
+
+        return (unsigned long) data.fiemap.fm_extents[0].fe_physical;
+}
+
+struct item {
+        const char *path;
+        unsigned long block;
+};
+
+static int qsort_compare(const void *a, const void *b) {
+        const struct item *i, *j;
+
+        i = a;
+        j = b;
+
+        if (i->block < j->block)
+                return -1;
+        if (i->block > j->block)
+                return 1;
+
+        return strcmp(i->path, j->path);
+}
+
+static int collect(const char *root) {
+        enum {
+                FD_FANOTIFY,  /* Get the actual fs events */
+                FD_SIGNAL,
+                FD_INOTIFY,   /* We get notifications to quit early via this fd */
+                _FD_MAX
+        };
+        struct pollfd pollfd[_FD_MAX];
+        int fanotify_fd = -1, signal_fd = -1, inotify_fd = -1, r = 0;
+        pid_t my_pid;
+        Hashmap *files = NULL;
+        Iterator i;
+        char *p, *q;
+        sigset_t mask;
+        FILE *pack = NULL;
+        char *pack_fn_new = NULL, *pack_fn = NULL;
+        bool on_ssd, on_btrfs;
+        struct statfs sfs;
+        usec_t not_after;
+        uint64_t previous_block_readahead;
+        bool previous_block_readahead_set = false;
+
+        assert(root);
+
+        if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
+                r = log_oom();
+                goto finish;
+        }
+
+        /* If there's no pack file yet we lower the kernel readahead
+         * so that mincore() is accurate. If there is a pack file
+         * already we assume it is accurate enough so that kernel
+         * readahead is never triggered. */
+        previous_block_readahead_set =
+                access(pack_fn, F_OK) < 0 &&
+                block_get_readahead(root, &previous_block_readahead) >= 0 &&
+                block_set_readahead(root, 8*1024) >= 0;
+
+        if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)) < 0)
+                log_warning("Failed to set IDLE IO priority class: %m");
+
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+        if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
+                log_error("signalfd(): %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if (!(files = hashmap_new(string_hash_func, string_compare_func))) {
+                log_error("Failed to allocate set.");
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if ((fanotify_fd = fanotify_init(FAN_CLOEXEC|FAN_NONBLOCK, O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_NOATIME)) < 0)  {
+                log_error("Failed to create fanotify object: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if (fanotify_mark(fanotify_fd, FAN_MARK_ADD|FAN_MARK_MOUNT, FAN_OPEN, AT_FDCWD, root) < 0) {
+                log_error("Failed to mark %s: %m", root);
+                r = -errno;
+                goto finish;
+        }
+
+        if ((inotify_fd = open_inotify()) < 0) {
+                r = inotify_fd;
+                goto finish;
+        }
+
+        not_after = now(CLOCK_MONOTONIC) + arg_timeout;
+
+        my_pid = getpid();
+
+        zero(pollfd);
+        pollfd[FD_FANOTIFY].fd = fanotify_fd;
+        pollfd[FD_FANOTIFY].events = POLLIN;
+        pollfd[FD_SIGNAL].fd = signal_fd;
+        pollfd[FD_SIGNAL].events = POLLIN;
+        pollfd[FD_INOTIFY].fd = inotify_fd;
+        pollfd[FD_INOTIFY].events = POLLIN;
+
+        sd_notify(0,
+                  "READY=1\n"
+                  "STATUS=Collecting readahead data");
+
+        log_debug("Collecting...");
+
+        if (access("/run/systemd/readahead/cancel", F_OK) >= 0) {
+                log_debug("Collection canceled");
+                r = -ECANCELED;
+                goto finish;
+        }
+
+        if (access("/run/systemd/readahead/done", F_OK) >= 0) {
+                log_debug("Got termination request");
+                goto done;
+        }
+
+        for (;;) {
+                union {
+                        struct fanotify_event_metadata metadata;
+                        char buffer[4096];
+                } data;
+                ssize_t n;
+                struct fanotify_event_metadata *m;
+                usec_t t;
+                int h;
+
+                if (hashmap_size(files) > arg_files_max) {
+                        log_debug("Reached maximum number of read ahead files, ending collection.");
+                        break;
+                }
+
+                t = now(CLOCK_MONOTONIC);
+                if (t >= not_after) {
+                        log_debug("Reached maximum collection time, ending collection.");
+                        break;
+                }
+
+                if ((h = poll(pollfd, _FD_MAX, (int) ((not_after - t) / USEC_PER_MSEC))) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        log_error("poll(): %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (h == 0) {
+                        log_debug("Reached maximum collection time, ending collection.");
+                        break;
+                }
+
+                if (pollfd[FD_SIGNAL].revents) {
+                        log_debug("Got signal.");
+                        break;
+                }
+
+                if (pollfd[FD_INOTIFY].revents) {
+                        uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
+                        struct inotify_event *e;
+
+                        if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
+                                if (errno == EINTR || errno == EAGAIN)
+                                        continue;
+
+                                log_error("Failed to read inotify event: %m");
+                                r = -errno;
+                                goto finish;
+                        }
+
+                        e = (struct inotify_event*) inotify_buffer;
+                        while (n > 0) {
+                                size_t step;
+
+                                if ((e->mask & IN_CREATE) && streq(e->name, "cancel")) {
+                                        log_debug("Collection canceled");
+                                        r = -ECANCELED;
+                                        goto finish;
+                                }
+
+                                if ((e->mask & IN_CREATE) && streq(e->name, "done")) {
+                                        log_debug("Got termination request");
+                                        goto done;
+                                }
+
+                                step = sizeof(struct inotify_event) + e->len;
+                                assert(step <= (size_t) n);
+
+                                e = (struct inotify_event*) ((uint8_t*) e + step);
+                                n -= step;
+                        }
+                }
+
+                if ((n = read(fanotify_fd, &data, sizeof(data))) < 0) {
+
+                        if (errno == EINTR || errno == EAGAIN)
+                                continue;
+
+                        /* fanotify sometimes returns EACCES on read()
+                         * where it shouldn't. For now let's just
+                         * ignore it here (which is safe), but
+                         * eventually this should be
+                         * dropped when the kernel is fixed.
+                         *
+                         * https://bugzilla.redhat.com/show_bug.cgi?id=707577 */
+                        if (errno == EACCES)
+                                continue;
+
+                        log_error("Failed to read event: %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                for (m = &data.metadata; FAN_EVENT_OK(m, n); m = FAN_EVENT_NEXT(m, n)) {
+                        char fn[PATH_MAX];
+                        int k;
+
+                        if (m->fd < 0)
+                                goto next_iteration;
+
+                        if (m->pid == my_pid)
+                                goto next_iteration;
+
+                        __sync_synchronize();
+                        if (m->pid == shared->replay)
+                                goto next_iteration;
+
+                        snprintf(fn, sizeof(fn), "/proc/self/fd/%i", m->fd);
+                        char_array_0(fn);
+
+                        if ((k = readlink_malloc(fn, &p)) >= 0) {
+                                if (startswith(p, "/tmp") ||
+                                    endswith(p, " (deleted)") ||
+                                    hashmap_get(files, p))
+                                        /* Not interesting, or
+                                         * already read */
+                                        free(p);
+                                else {
+                                        unsigned long ul;
+
+                                        ul = fd_first_block(m->fd);
+
+                                        if ((k = hashmap_put(files, p, SECTOR_TO_PTR(ul))) < 0) {
+                                                log_warning("set_put() failed: %s", strerror(-k));
+                                                free(p);
+                                        }
+                                }
+
+                        } else
+                                log_warning("readlink(%s) failed: %s", fn, strerror(-k));
+
+                next_iteration:
+                        if (m->fd >= 0)
+                                close_nointr_nofail(m->fd);
+                }
+        }
+
+done:
+        if (fanotify_fd >= 0) {
+                close_nointr_nofail(fanotify_fd);
+                fanotify_fd = -1;
+        }
+
+        log_debug("Writing Pack File...");
+
+        on_ssd = fs_on_ssd(root) > 0;
+        log_debug("On SSD: %s", yes_no(on_ssd));
+
+        on_btrfs = statfs(root, &sfs) >= 0 && (long) sfs.f_type == (long) BTRFS_SUPER_MAGIC;
+        log_debug("On btrfs: %s", yes_no(on_btrfs));
+
+        if (asprintf(&pack_fn_new, "%s/.readahead.new", root) < 0) {
+                r = log_oom();
+                goto finish;
+        }
+
+        pack = fopen(pack_fn_new, "we");
+        if (!pack) {
+                log_error("Failed to open pack file: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        fputs(CANONICAL_HOST READAHEAD_PACK_FILE_VERSION, pack);
+        putc(on_ssd ? 'S' : 'R', pack);
+
+        if (on_ssd || on_btrfs) {
+
+                /* On SSD or on btrfs, just write things out in the
+                 * order the files were accessed. */
+
+                HASHMAP_FOREACH_KEY(q, p, files, i)
+                        pack_file(pack, p, on_btrfs);
+        } else {
+                struct item *ordered, *j;
+                unsigned k, n;
+
+                /* On rotating media, order things by the block
+                 * numbers */
+
+                log_debug("Ordering...");
+
+                n = hashmap_size(files);
+                if (!(ordered = new(struct item, n))) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                j = ordered;
+                HASHMAP_FOREACH_KEY(q, p, files, i) {
+                        j->path = p;
+                        j->block = PTR_TO_SECTOR(q);
+                        j++;
+                }
+
+                assert(ordered + n == j);
+
+                qsort(ordered, n, sizeof(struct item), qsort_compare);
+
+                for (k = 0; k < n; k++)
+                        pack_file(pack, ordered[k].path, on_btrfs);
+
+                free(ordered);
+        }
+
+        log_debug("Finalizing...");
+
+        fflush(pack);
+
+        if (ferror(pack)) {
+                log_error("Failed to write pack file.");
+                r = -EIO;
+                goto finish;
+        }
+
+        if (rename(pack_fn_new, pack_fn) < 0) {
+                log_error("Failed to rename readahead file: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        fclose(pack);
+        pack = NULL;
+
+        log_debug("Done.");
+
+finish:
+        if (fanotify_fd >= 0)
+                close_nointr_nofail(fanotify_fd);
+
+        if (signal_fd >= 0)
+                close_nointr_nofail(signal_fd);
+
+        if (inotify_fd >= 0)
+                close_nointr_nofail(inotify_fd);
+
+        if (pack) {
+                fclose(pack);
+                unlink(pack_fn_new);
+        }
+        free(pack_fn_new);
+        free(pack_fn);
+
+        while ((p = hashmap_steal_first_key(files)))
+                free(p);
+
+        hashmap_free(files);
+
+        if (previous_block_readahead_set) {
+                uint64_t bytes;
+
+                /* Restore the original kernel readahead setting if we
+                 * changed it, and nobody has overwritten it since
+                 * yet. */
+                if (block_get_readahead(root, &bytes) >= 0 && bytes == 8*1024)
+                        block_set_readahead(root, previous_block_readahead);
+        }
+
+        return r;
+}
+
+int main_collect(const char *root) {
+
+        if (!root)
+                root = "/";
+
+        /* Skip this step on read-only media. Note that we check the
+         * underlying block device here, not he read-only flag of the
+         * file system on top, since that one is most likely mounted
+         * read-only anyway at boot, even if the underlying block
+         * device is theoretically writable. */
+        if (fs_on_read_only(root) > 0) {
+                log_info("Disabling readahead collector due to read-only media.");
+                return EXIT_SUCCESS;
+        }
+
+        if (!enough_ram()) {
+                log_info("Disabling readahead collector due to low memory.");
+                return EXIT_SUCCESS;
+        }
+
+        shared = shared_get();
+        if (!shared)
+                return EXIT_FAILURE;
+
+        shared->collect = getpid();
+        __sync_synchronize();
+
+        if (collect(root) < 0)
+                return EXIT_FAILURE;
+
+        return EXIT_SUCCESS;
+}
diff --git a/src/readahead/readahead-common.c b/src/readahead/readahead-common.c
new file mode 100644 (file)
index 0000000..41aaff0
--- /dev/null
@@ -0,0 +1,410 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/sysinfo.h>
+#include <sys/inotify.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <libudev.h>
+
+#include "log.h"
+#include "readahead-common.h"
+#include "util.h"
+#include "missing.h"
+
+int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) {
+        assert(fd >= 0);
+        assert(fn);
+        assert(st);
+
+        if (fstat(fd, st) < 0) {
+                log_warning("fstat(%s) failed: %m", fn);
+                return -errno;
+        }
+
+        if (!S_ISREG(st->st_mode)) {
+                log_debug("Not preloading special file %s", fn);
+                return 0;
+        }
+
+        if (st->st_size <= 0 || st->st_size > file_size_max) {
+                log_debug("Not preloading file %s with size out of bounds %llu", fn, (unsigned long long) st->st_size);
+                return 0;
+        }
+
+        return 1;
+}
+
+int fs_on_ssd(const char *p) {
+        struct stat st;
+        struct udev *udev = NULL;
+        struct udev_device *udev_device = NULL, *look_at = NULL;
+        bool b = false;
+        const char *devtype, *rotational, *model, *id;
+        int r;
+
+        assert(p);
+
+        if (stat(p, &st) < 0)
+                return -errno;
+
+        if (major(st.st_dev) == 0) {
+                _cleanup_fclose_ FILE *f = NULL;
+                int mount_id;
+                struct file_handle *h;
+
+                /* Might be btrfs, which exposes "ssd" as mount flag if it is on ssd.
+                 *
+                 * We first determine the mount ID here, if we can,
+                 * and then lookup the mount ID in mountinfo to find
+                 * the mount options. */
+
+                h = alloca(MAX_HANDLE_SZ);
+                h->handle_bytes = MAX_HANDLE_SZ;
+                r = name_to_handle_at(AT_FDCWD, p, h, &mount_id, AT_SYMLINK_FOLLOW);
+                if (r < 0)
+                        return false;
+
+                f = fopen("/proc/self/mountinfo", "re");
+                if (!f)
+                        return false;
+
+                for (;;) {
+                        char line[LINE_MAX], *e;
+                        _cleanup_free_ char *opts = NULL;
+                        int mid;
+
+                        if (!fgets(line, sizeof(line), f))
+                                return false;
+
+                        truncate_nl(line);
+
+                        if (sscanf(line, "%i", &mid) != 1)
+                                continue;
+
+                        if (mid != mount_id)
+                                continue;
+
+                        e = strstr(line, " - ");
+                        if (!e)
+                                continue;
+
+                        if (sscanf(e+3, "%*s %*s %ms", &opts) != 1)
+                                continue;
+
+                        if (streq(opts, "ssd") || startswith(opts, "ssd,") || endswith(opts, ",ssd") || strstr(opts, ",ssd,"))
+                                return true;
+                }
+
+                return false;
+        }
+
+        udev = udev_new();
+        if (!udev)
+                return -ENOMEM;
+
+        udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev);
+        if (!udev_device)
+                goto finish;
+
+        devtype = udev_device_get_property_value(udev_device, "DEVTYPE");
+        if (devtype && streq(devtype, "partition"))
+                look_at = udev_device_get_parent(udev_device);
+        else
+                look_at = udev_device;
+
+        if (!look_at)
+                goto finish;
+
+        /* First, try high-level property */
+        id = udev_device_get_property_value(look_at, "ID_SSD");
+        if (id) {
+                b = streq(id, "1");
+                goto finish;
+        }
+
+        /* Second, try kernel attribute */
+        rotational = udev_device_get_sysattr_value(look_at, "queue/rotational");
+        if (rotational) {
+                b = streq(rotational, "0");
+                goto finish;
+        }
+
+        /* Finally, fallback to heuristics */
+        look_at = udev_device_get_parent(look_at);
+        if (!look_at)
+                goto finish;
+
+        model = udev_device_get_sysattr_value(look_at, "model");
+        if (model)
+                b = !!strstr(model, "SSD");
+
+finish:
+        if (udev_device)
+                udev_device_unref(udev_device);
+
+        if (udev)
+                udev_unref(udev);
+
+        return b;
+}
+
+int fs_on_read_only(const char *p) {
+        struct stat st;
+        struct udev *udev = NULL;
+        struct udev_device *udev_device = NULL;
+        bool b = false;
+        const char *read_only;
+
+        assert(p);
+
+        if (stat(p, &st) < 0)
+                return -errno;
+
+        if (major(st.st_dev) == 0)
+                return false;
+
+        if (!(udev = udev_new()))
+                return -ENOMEM;
+
+        if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev)))
+                goto finish;
+
+        if ((read_only = udev_device_get_sysattr_value(udev_device, "ro")))
+                if ((b = streq(read_only, "1")))
+                        goto finish;
+
+finish:
+        if (udev_device)
+                udev_device_unref(udev_device);
+
+        if (udev)
+                udev_unref(udev);
+
+        return b;
+}
+
+bool enough_ram(void) {
+        struct sysinfo si;
+
+        assert_se(sysinfo(&si) >= 0);
+
+        /* Enable readahead only with at least 128MB memory */
+        return si.totalram > 127 * 1024*1024 / si.mem_unit;
+}
+
+int open_inotify(void) {
+        int fd;
+
+        if ((fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
+                log_error("Failed to create inotify handle: %m");
+                return -errno;
+        }
+
+        mkdir("/run/systemd", 0755);
+        mkdir("/run/systemd/readahead", 0755);
+
+        if (inotify_add_watch(fd, "/run/systemd/readahead", IN_CREATE) < 0) {
+                log_error("Failed to watch /run/systemd/readahead: %m");
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        return fd;
+}
+
+ReadaheadShared *shared_get(void) {
+        int fd;
+        ReadaheadShared *m = NULL;
+
+        mkdir("/run/systemd", 0755);
+        mkdir("/run/systemd/readahead", 0755);
+
+        if ((fd = open("/run/systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) {
+                log_error("Failed to create shared memory segment: %m");
+                goto finish;
+        }
+
+        if (ftruncate(fd, sizeof(ReadaheadShared)) < 0) {
+                log_error("Failed to truncate shared memory segment: %m");
+                goto finish;
+        }
+
+        if ((m = mmap(NULL, sizeof(ReadaheadShared), PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+                log_error("Failed to mmap shared memory segment: %m");
+                m = NULL;
+                goto finish;
+        }
+
+finish:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return m;
+}
+
+/* We use 20K instead of the more human digestable 16K here. Why?
+   Simply so that it is more unlikely that users end up picking this
+   value too so that we can recognize better whether the user changed
+   the value while we had it temporarily bumped. */
+#define BUMP_REQUEST_NR (20*1024)
+
+int block_bump_request_nr(const char *p) {
+        struct stat st;
+        uint64_t u;
+        char *ap = NULL, *line = NULL;
+        int r;
+        dev_t d;
+
+        assert(p);
+
+        if (stat(p, &st) < 0)
+                return -errno;
+
+        if (major(st.st_dev) == 0)
+                return 0;
+
+        d = st.st_dev;
+        block_get_whole_disk(d, &d);
+
+        if (asprintf(&ap, "/sys/dev/block/%u:%u/queue/nr_requests", major(d), minor(d)) < 0) {
+                r= -ENOMEM;
+                goto finish;
+        }
+
+        r = read_one_line_file(ap, &line);
+        if (r < 0) {
+                if (r == -ENOENT)
+                        r = 0;
+                goto finish;
+        }
+
+        r = safe_atou64(line, &u);
+        if (r >= 0 && u >= BUMP_REQUEST_NR) {
+                r = 0;
+                goto finish;
+        }
+
+        free(line);
+        line = NULL;
+
+        if (asprintf(&line, "%lu", (unsigned long) BUMP_REQUEST_NR) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = write_one_line_file(ap, line);
+        if (r < 0)
+                goto finish;
+
+        log_info("Bumped block_nr parameter of %u:%u to %lu. This is a temporary hack and should be removed one day.", major(d), minor(d), (unsigned long) BUMP_REQUEST_NR);
+        r = 1;
+
+finish:
+        free(ap);
+        free(line);
+
+        return r;
+}
+
+int block_get_readahead(const char *p, uint64_t *bytes) {
+        struct stat st;
+        char *ap = NULL, *line = NULL;
+        int r;
+        dev_t d;
+        uint64_t u;
+
+        assert(p);
+        assert(bytes);
+
+        if (stat(p, &st) < 0)
+                return -errno;
+
+        if (major(st.st_dev) == 0)
+                return 0;
+
+        d = st.st_dev;
+        block_get_whole_disk(d, &d);
+
+        if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = read_one_line_file(ap, &line);
+        if (r < 0)
+                goto finish;
+
+        r = safe_atou64(line, &u);
+        if (r < 0)
+                goto finish;
+
+        *bytes = u * 1024ULL;
+
+finish:
+        free(ap);
+        free(line);
+
+        return r;
+}
+
+int block_set_readahead(const char *p, uint64_t bytes) {
+        struct stat st;
+        char *ap = NULL, *line = NULL;
+        int r;
+        dev_t d;
+
+        assert(p);
+        assert(bytes);
+
+        if (stat(p, &st) < 0)
+                return -errno;
+
+        if (major(st.st_dev) == 0)
+                return 0;
+
+        d = st.st_dev;
+        block_get_whole_disk(d, &d);
+
+        if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (asprintf(&line, "%llu", (unsigned long long) bytes / 1024ULL) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = write_one_line_file(ap, line);
+        if (r < 0)
+                goto finish;
+
+finish:
+        free(ap);
+        free(line);
+
+        return r;
+}
diff --git a/src/readahead/readahead-common.h b/src/readahead/readahead-common.h
new file mode 100644 (file)
index 0000000..b34f3aa
--- /dev/null
@@ -0,0 +1,61 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "macro.h"
+#include "util.h"
+
+#define READAHEAD_FILE_SIZE_MAX (10*1024*1024)
+
+#define READAHEAD_PACK_FILE_VERSION ";VERSION=2\n"
+
+extern unsigned arg_files_max;
+extern off_t arg_file_size_max;
+extern usec_t arg_timeout;
+
+int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st);
+
+int fs_on_ssd(const char *p);
+int fs_on_read_only(const char *p);
+
+bool enough_ram(void);
+
+int open_inotify(void);
+
+typedef struct ReadaheadShared {
+        pid_t collect;
+        pid_t replay;
+} _packed_ ReadaheadShared;
+
+ReadaheadShared *shared_get(void);
+
+int block_bump_request_nr(const char *p);
+
+int block_get_readahead(const char *p, uint64_t *bytes);
+int block_set_readahead(const char *p, uint64_t bytes);
+
+int main_collect(const char *root);
+int main_replay(const char *root);
+int main_analyze(const char *pack_path);
diff --git a/src/readahead/readahead-replay.c b/src/readahead/readahead-replay.c
new file mode 100644 (file)
index 0000000..cb04e5f
--- /dev/null
@@ -0,0 +1,311 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/inotify.h>
+
+#include <systemd/sd-daemon.h>
+
+#include "missing.h"
+#include "util.h"
+#include "set.h"
+#include "ioprio.h"
+#include "readahead-common.h"
+#include "virt.h"
+
+static ReadaheadShared *shared = NULL;
+
+static int unpack_file(FILE *pack) {
+        char fn[PATH_MAX];
+        int r = 0, fd = -1;
+        bool any = false;
+        struct stat st;
+        uint64_t inode;
+
+        assert(pack);
+
+        if (!fgets(fn, sizeof(fn), pack))
+                return 0;
+
+        char_array_0(fn);
+        truncate_nl(fn);
+
+        fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW);
+        if (fd < 0) {
+
+                if (errno != ENOENT && errno != EPERM && errno != EACCES && errno != ELOOP)
+                        log_warning("open(%s) failed: %m", fn);
+
+        } else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0) {
+                close_nointr_nofail(fd);
+                fd = -1;
+        }
+
+        if (fread(&inode, sizeof(inode), 1, pack) != 1) {
+                log_error("Premature end of pack file.");
+                r = -EIO;
+                goto finish;
+        }
+
+        if (fd >= 0) {
+                /* If the inode changed the file got deleted, so just
+                 * ignore this entry */
+                if (st.st_ino != (uint64_t) inode) {
+                        close_nointr_nofail(fd);
+                        fd = -1;
+                }
+        }
+
+        for (;;) {
+                uint32_t b, c;
+
+                if (fread(&b, sizeof(b), 1, pack) != 1 ||
+                    fread(&c, sizeof(c), 1, pack) != 1) {
+                        log_error("Premature end of pack file.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if (b == 0 && c == 0)
+                        break;
+
+                if (c <= b) {
+                        log_error("Invalid pack file.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                log_debug("%s: page %u to %u", fn, b, c);
+
+                any = true;
+
+                if (fd >= 0)
+                        if (posix_fadvise(fd, b * page_size(), (c - b) * page_size(), POSIX_FADV_WILLNEED) < 0) {
+                                log_warning("posix_fadvise() failed: %m");
+                                goto finish;
+                        }
+        }
+
+        if (!any && fd >= 0) {
+                /* if no range is encoded in the pack file this is
+                 * intended to mean that the whole file shall be
+                 * read */
+
+                if (posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED) < 0) {
+                        log_warning("posix_fadvise() failed: %m");
+                        goto finish;
+                }
+        }
+
+finish:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
+
+static int replay(const char *root) {
+        FILE *pack = NULL;
+        char line[LINE_MAX];
+        int r = 0;
+        char *pack_fn = NULL;
+        int c;
+        bool on_ssd, ready = false;
+        int prio;
+        int inotify_fd = -1;
+
+        assert(root);
+
+        block_bump_request_nr(root);
+
+        if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
+                r = log_oom();
+                goto finish;
+        }
+
+        pack = fopen(pack_fn, "re");
+        if (!pack) {
+                if (errno == ENOENT)
+                        log_debug("No pack file found.");
+                else {
+                        log_error("Failed to open pack file: %m");
+                        r = -errno;
+                }
+
+                goto finish;
+        }
+
+        posix_fadvise(fileno(pack), 0, 0, POSIX_FADV_WILLNEED);
+
+        if ((inotify_fd = open_inotify()) < 0) {
+                r = inotify_fd;
+                goto finish;
+        }
+
+        if (!(fgets(line, sizeof(line), pack))) {
+                log_error("Premature end of pack file.");
+                r = -EIO;
+                goto finish;
+        }
+
+        char_array_0(line);
+
+        if (!streq(line, CANONICAL_HOST READAHEAD_PACK_FILE_VERSION)) {
+                log_debug("Pack file host or version type mismatch.");
+                goto finish;
+        }
+
+        if ((c = getc(pack)) == EOF) {
+                log_debug("Premature end of pack file.");
+                r = -EIO;
+                goto finish;
+        }
+
+        /* We do not retest SSD here, so that we can start replaying
+         * before udev is up.*/
+        on_ssd = c == 'S';
+        log_debug("On SSD: %s", yes_no(on_ssd));
+
+        if (on_ssd)
+                prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
+        else
+                /* We are not using RT here, since we'd starve IO that
+                we didn't record (which is for example blkid, since
+                its disk accesses go directly to the block device and
+                are thus not visible in fallocate) to death. However,
+                we do ask for an IO prio that is slightly higher than
+                the default (which is BE. 4) */
+                prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 2);
+
+        if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), prio) < 0)
+                log_warning("Failed to set IDLE IO priority class: %m");
+
+        sd_notify(0, "STATUS=Replaying readahead data");
+
+        log_debug("Replaying...");
+
+        if (access("/run/systemd/readahead/noreplay", F_OK) >= 0) {
+                log_debug("Got termination request");
+                goto done;
+        }
+
+        while (!feof(pack) && !ferror(pack)) {
+                uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
+                int k;
+                ssize_t n;
+
+                if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
+                        if (errno != EINTR && errno != EAGAIN) {
+                                log_error("Failed to read inotify event: %m");
+                                r = -errno;
+                                goto finish;
+                        }
+                } else {
+                        struct inotify_event *e = (struct inotify_event*) inotify_buffer;
+
+                        while (n > 0) {
+                                size_t step;
+
+                                if ((e->mask & IN_CREATE) && streq(e->name, "noreplay")) {
+                                        log_debug("Got termination request");
+                                        goto done;
+                                }
+
+                                step = sizeof(struct inotify_event) + e->len;
+                                assert(step <= (size_t) n);
+
+                                e = (struct inotify_event*) ((uint8_t*) e + step);
+                                n -= step;
+                        }
+                }
+
+                if ((k = unpack_file(pack)) < 0) {
+                        r = k;
+                        goto finish;
+                }
+
+                if (!ready) {
+                        /* We delay the ready notification until we
+                         * queued at least one read */
+                        sd_notify(0, "READY=1");
+                        ready = true;
+                }
+        }
+
+done:
+        if (!ready)
+                sd_notify(0, "READY=1");
+
+        if (ferror(pack)) {
+                log_error("Failed to read pack file.");
+                r = -EIO;
+                goto finish;
+        }
+
+        log_debug("Done.");
+
+finish:
+        if (pack)
+                fclose(pack);
+
+        if (inotify_fd >= 0)
+                close_nointr_nofail(inotify_fd);
+
+        free(pack_fn);
+
+        return r;
+}
+
+int main_replay(const char *root) {
+
+        if (!root)
+                root = "/";
+
+        if (!enough_ram()) {
+                log_info("Disabling readahead replay due to low memory.");
+                return EXIT_SUCCESS;
+        }
+
+        shared = shared_get();
+        if (!shared)
+                return EXIT_FAILURE;
+
+        shared->replay = getpid();
+        __sync_synchronize();
+
+        if (replay(root) < 0)
+                return EXIT_FAILURE;
+
+        return EXIT_SUCCESS;
+}
diff --git a/src/readahead/readahead.c b/src/readahead/readahead.c
new file mode 100644 (file)
index 0000000..abeecc7
--- /dev/null
@@ -0,0 +1,158 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <getopt.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include "util.h"
+#include "def.h"
+#include "readahead-common.h"
+
+unsigned arg_files_max = 16*1024;
+off_t arg_file_size_max = READAHEAD_FILE_SIZE_MAX;
+usec_t arg_timeout = 2*USEC_PER_MINUTE;
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] collect [DIRECTORY]\n\n"
+               "Collect read-ahead data on early boot.\n\n"
+               "  -h --help                 Show this help\n"
+               "     --max-files=INT        Maximum number of files to read ahead\n"
+               "     --file-size-max=BYTES  Maximum size of files to read ahead\n"
+               "     --timeout=USEC         Maximum time to spend collecting data\n\n\n",
+               program_invocation_short_name);
+
+        printf("%s [OPTIONS...] replay [DIRECTORY]\n\n"
+               "Replay collected read-ahead data on early boot.\n\n"
+               "  -h --help                 Show this help\n"
+               "     --file-size-max=BYTES  Maximum size of files to read ahead\n\n\n",
+               program_invocation_short_name);
+
+        printf("%s [OPTIONS...] analyze [PACK FILE]\n\n"
+               "Analyze collected read-ahead data.\n\n"
+               "  -h --help                 Show this help\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_FILES_MAX = 0x100,
+                ARG_FILE_SIZE_MAX,
+                ARG_TIMEOUT
+        };
+
+        static const struct option options[] = {
+                { "help",          no_argument,       NULL, 'h'                },
+                { "files-max",     required_argument, NULL, ARG_FILES_MAX      },
+                { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX  },
+                { "timeout",       required_argument, NULL, ARG_TIMEOUT        },
+                { NULL,            0,                 NULL, 0                  }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_FILES_MAX:
+                        if (safe_atou(optarg, &arg_files_max) < 0 || arg_files_max <= 0) {
+                                log_error("Failed to parse maximum number of files %s.", optarg);
+                                return -EINVAL;
+                        }
+                        break;
+
+                case ARG_FILE_SIZE_MAX: {
+                        unsigned long long ull;
+
+                        if (safe_atollu(optarg, &ull) < 0 || ull <= 0) {
+                                log_error("Failed to parse maximum file size %s.", optarg);
+                                return -EINVAL;
+                        }
+
+                        arg_file_size_max = (off_t) ull;
+                        break;
+                }
+
+                case ARG_TIMEOUT:
+                        if (parse_usec(optarg, &arg_timeout) < 0 || arg_timeout <= 0) {
+                                log_error("Failed to parse timeout %s.", optarg);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind != argc-1 &&
+            optind != argc-2) {
+                help();
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+        if (streq(argv[optind], "collect"))
+                return main_collect(argv[optind+1]);
+        else if (streq(argv[optind], "replay"))
+                return main_replay(argv[optind+1]);
+        else if (streq(argv[optind], "analyze"))
+                return main_analyze(argv[optind+1]);
+
+        log_error("Unknown verb %s.", argv[optind]);
+        return EXIT_FAILURE;
+}
diff --git a/src/readahead/sd-readahead.c b/src/readahead/sd-readahead.c
new file mode 100644 (file)
index 0000000..d48cd76
--- /dev/null
@@ -0,0 +1,89 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  Copyright 2010 Lennart Poettering
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+***/
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "sd-readahead.h"
+
+#if (__GNUC__ >= 4)
+#ifdef SD_EXPORT_SYMBOLS
+/* Export symbols */
+#define _sd_export_ __attribute__ ((visibility("default")))
+#else
+/* Don't export the symbols */
+#define _sd_export_ __attribute__ ((visibility("hidden")))
+#endif
+#else
+#define _sd_export_
+#endif
+
+static int touch(const char *path) {
+
+#if !defined(DISABLE_SYSTEMD) && defined(__linux__)
+        int fd;
+
+        mkdir("/run/systemd", 0755);
+        mkdir("/run/systemd/readahead", 0755);
+
+        fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666);
+        if (fd < 0)
+                return -errno;
+
+        for (;;) {
+                if (close(fd) >= 0)
+                        break;
+
+                if (errno != -EINTR)
+                        return -errno;
+        }
+
+#endif
+        return 0;
+}
+
+_sd_export_ int sd_readahead(const char *action) {
+
+        if (!action)
+                return -EINVAL;
+
+        if (strcmp(action, "cancel") == 0)
+                return touch("/run/systemd/readahead/cancel");
+        else if (strcmp(action, "done") == 0)
+                return touch("/run/systemd/readahead/done");
+        else if (strcmp(action, "noreplay") == 0)
+                return touch("/run/systemd/readahead/noreplay");
+
+        return -EINVAL;
+}
diff --git a/src/remount-fs/Makefile b/src/remount-fs/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c
new file mode 100644 (file)
index 0000000..b49d095
--- /dev/null
@@ -0,0 +1,170 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <mntent.h>
+
+#include "log.h"
+#include "util.h"
+#include "path-util.h"
+#include "set.h"
+#include "mount-setup.h"
+#include "exit-status.h"
+
+/* Goes through /etc/fstab and remounts all API file systems, applying
+ * options that are in /etc/fstab that systemd might not have
+ * respected */
+
+int main(int argc, char *argv[]) {
+        int ret = EXIT_FAILURE;
+        FILE *f = NULL;
+        struct mntent* me;
+        Hashmap *pids = NULL;
+
+        if (argc > 1) {
+                log_error("This program takes no argument.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        f = setmntent("/etc/fstab", "r");
+        if (!f) {
+                if (errno == ENOENT) {
+                        ret = EXIT_SUCCESS;
+                        goto finish;
+                }
+
+                log_error("Failed to open /etc/fstab: %m");
+                goto finish;
+        }
+
+        pids = hashmap_new(trivial_hash_func, trivial_compare_func);
+        if (!pids) {
+                log_error("Failed to allocate set");
+                goto finish;
+        }
+
+        ret = EXIT_SUCCESS;
+
+        while ((me = getmntent(f))) {
+                pid_t pid;
+                int k;
+                char *s;
+
+                /* Remount the root fs, /usr and all API VFS */
+                if (!mount_point_is_api(me->mnt_dir) &&
+                    !path_equal(me->mnt_dir, "/") &&
+                    !path_equal(me->mnt_dir, "/usr"))
+                        continue;
+
+                log_debug("Remounting %s", me->mnt_dir);
+
+                pid = fork();
+                if (pid < 0) {
+                        log_error("Failed to fork: %m");
+                        ret = EXIT_FAILURE;
+                        continue;
+                }
+
+                if (pid == 0) {
+                        const char *arguments[5];
+                        /* Child */
+
+                        arguments[0] = "/bin/mount";
+                        arguments[1] = me->mnt_dir;
+                        arguments[2] = "-o";
+                        arguments[3] = "remount";
+                        arguments[4] = NULL;
+
+                        execv("/bin/mount", (char **) arguments);
+
+                        log_error("Failed to execute /bin/mount: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
+                /* Parent */
+
+                s = strdup(me->mnt_dir);
+                if (!s) {
+                        log_oom();
+                        ret = EXIT_FAILURE;
+                        continue;
+                }
+
+
+                k = hashmap_put(pids, UINT_TO_PTR(pid), s);
+                if (k < 0) {
+                        log_error("Failed to add PID to set: %s", strerror(-k));
+                        ret = EXIT_FAILURE;
+                        continue;
+                }
+        }
+
+        while (!hashmap_isempty(pids)) {
+                siginfo_t si;
+                char *s;
+
+                zero(si);
+                if (waitid(P_ALL, 0, &si, WEXITED) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        log_error("waitid() failed: %m");
+                        ret = EXIT_FAILURE;
+                        break;
+                }
+
+                s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid));
+                if (s) {
+                        if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
+                                if (si.si_code == CLD_EXITED)
+                                        log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status);
+                                else
+                                        log_error("/bin/mount for %s terminated by signal %s.", s, signal_to_string(si.si_status));
+
+                                ret = EXIT_FAILURE;
+                        }
+
+                        free(s);
+                }
+        }
+
+finish:
+
+        if (pids)
+                hashmap_free_free(pids);
+
+        if (f)
+                endmntent(f);
+
+        return ret;
+}
diff --git a/src/reply-password/Makefile b/src/reply-password/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/reply-password/reply-password.c b/src/reply-password/reply-password.c
new file mode 100644 (file)
index 0000000..a935d0f
--- /dev/null
@@ -0,0 +1,109 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/signalfd.h>
+#include <getopt.h>
+#include <stddef.h>
+
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+
+static int send_on_socket(int fd, const char *socket_name, const void *packet, size_t size) {
+        union {
+                struct sockaddr sa;
+                struct sockaddr_un un;
+        } sa;
+
+        assert(fd >= 0);
+        assert(socket_name);
+        assert(packet);
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
+
+        if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) {
+                log_error("Failed to send: %m");
+                return -1;
+        }
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        int fd = -1, r = EXIT_FAILURE;
+        char packet[LINE_MAX];
+        size_t length;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        if (argc != 3) {
+                log_error("Wrong number of arguments.");
+                goto finish;
+        }
+
+        if (streq(argv[1], "1")) {
+
+                packet[0] = '+';
+                if (!fgets(packet+1, sizeof(packet)-1, stdin)) {
+                        log_error("Failed to read password: %m");
+                        goto finish;
+                }
+
+                truncate_nl(packet+1);
+                length = 1 + strlen(packet+1) + 1;
+        } else if (streq(argv[1], "0")) {
+                packet[0] = '-';
+                length = 1;
+        } else {
+                log_error("Invalid first argument %s", argv[1]);
+                goto finish;
+        }
+
+        if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
+                log_error("socket() failed: %m");
+                goto finish;
+        }
+
+        if (send_on_socket(fd, argv[2], packet, length) < 0)
+                goto finish;
+
+        r = EXIT_SUCCESS;
+
+finish:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
diff --git a/src/shared/Makefile b/src/shared/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c
new file mode 100644 (file)
index 0000000..d1eb6f2
--- /dev/null
@@ -0,0 +1,68 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <sys/acl.h>
+#include <acl/libacl.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include "acl-util.h"
+
+int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
+        acl_entry_t i;
+        int found;
+
+        assert(acl);
+        assert(entry);
+
+        for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
+             found > 0;
+             found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
+
+                acl_tag_t tag;
+                uid_t *u;
+                bool b;
+
+                if (acl_get_tag_type(i, &tag) < 0)
+                        return -errno;
+
+                if (tag != ACL_USER)
+                        continue;
+
+                u = acl_get_qualifier(i);
+                if (!u)
+                        return -errno;
+
+                b = *u == uid;
+                acl_free(u);
+
+                if (b) {
+                        *entry = i;
+                        return 1;
+                }
+        }
+
+        if (found < 0)
+                return -errno;
+
+        return 0;
+}
diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h
new file mode 100644 (file)
index 0000000..31fbbcd
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry);
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
new file mode 100644 (file)
index 0000000..8a0fb89
--- /dev/null
@@ -0,0 +1,576 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+#include <stdbool.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <sys/inotify.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <sys/un.h>
+#include <stddef.h>
+#include <sys/signalfd.h>
+
+#include "util.h"
+#include "mkdir.h"
+#include "strv.h"
+
+#include "ask-password-api.h"
+
+static void backspace_chars(int ttyfd, size_t p) {
+
+        if (ttyfd < 0)
+                return;
+
+        while (p > 0) {
+                p--;
+
+                loop_write(ttyfd, "\b \b", 3, false);
+        }
+}
+
+int ask_password_tty(
+                const char *message,
+                usec_t until,
+                const char *flag_file,
+                char **_passphrase) {
+
+        struct termios old_termios, new_termios;
+        char passphrase[LINE_MAX];
+        size_t p = 0;
+        int r, ttyfd = -1, notify = -1;
+        struct pollfd pollfd[2];
+        bool reset_tty = false;
+        bool silent_mode = false;
+        bool dirty = false;
+        enum {
+                POLL_TTY,
+                POLL_INOTIFY
+        };
+
+        assert(message);
+        assert(_passphrase);
+
+        if (flag_file) {
+                if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        if ((ttyfd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) >= 0) {
+
+                if (tcgetattr(ttyfd, &old_termios) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                loop_write(ttyfd, ANSI_HIGHLIGHT_ON, sizeof(ANSI_HIGHLIGHT_ON)-1, false);
+                loop_write(ttyfd, message, strlen(message), false);
+                loop_write(ttyfd, " ", 1, false);
+                loop_write(ttyfd, ANSI_HIGHLIGHT_OFF, sizeof(ANSI_HIGHLIGHT_OFF)-1, false);
+
+                new_termios = old_termios;
+                new_termios.c_lflag &= ~(ICANON|ECHO);
+                new_termios.c_cc[VMIN] = 1;
+                new_termios.c_cc[VTIME] = 0;
+
+                if (tcsetattr(ttyfd, TCSADRAIN, &new_termios) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                reset_tty = true;
+        }
+
+        zero(pollfd);
+
+        pollfd[POLL_TTY].fd = ttyfd >= 0 ? ttyfd : STDIN_FILENO;
+        pollfd[POLL_TTY].events = POLLIN;
+        pollfd[POLL_INOTIFY].fd = notify;
+        pollfd[POLL_INOTIFY].events = POLLIN;
+
+        for (;;) {
+                char c;
+                int sleep_for = -1, k;
+                ssize_t n;
+
+                if (until > 0) {
+                        usec_t y;
+
+                        y = now(CLOCK_MONOTONIC);
+
+                        if (y > until) {
+                                r = -ETIME;
+                                goto finish;
+                        }
+
+                        sleep_for = (int) ((until - y) / USEC_PER_MSEC);
+                }
+
+                if (flag_file)
+                        if (access(flag_file, F_OK) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                if ((k = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        r = -errno;
+                        goto finish;
+                } else if (k == 0) {
+                        r = -ETIME;
+                        goto finish;
+                }
+
+                if (notify > 0 && pollfd[POLL_INOTIFY].revents != 0)
+                        flush_fd(notify);
+
+                if (pollfd[POLL_TTY].revents == 0)
+                        continue;
+
+                if ((n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1)) < 0) {
+
+                        if (errno == EINTR || errno == EAGAIN)
+                                continue;
+
+                        r = -errno;
+                        goto finish;
+
+                } else if (n == 0)
+                        break;
+
+                if (c == '\n')
+                        break;
+                else if (c == 21) { /* C-u */
+
+                        if (!silent_mode)
+                                backspace_chars(ttyfd, p);
+                        p = 0;
+
+                } else if (c == '\b' || c == 127) {
+
+                        if (p > 0) {
+
+                                if (!silent_mode)
+                                        backspace_chars(ttyfd, 1);
+
+                                p--;
+                        } else if (!dirty && !silent_mode) {
+
+                                silent_mode = true;
+
+                                /* There are two ways to enter silent
+                                 * mode. Either by pressing backspace
+                                 * as first key (and only as first key),
+                                 * or ... */
+                                if (ttyfd >= 0)
+                                        loop_write(ttyfd, "(no echo) ", 10, false);
+
+                        } else if (ttyfd >= 0)
+                                loop_write(ttyfd, "\a", 1, false);
+
+                } else if (c == '\t' && !silent_mode) {
+
+                        backspace_chars(ttyfd, p);
+                        silent_mode = true;
+
+                        /* ... or by pressing TAB at any time. */
+
+                        if (ttyfd >= 0)
+                                loop_write(ttyfd, "(no echo) ", 10, false);
+                } else {
+                        passphrase[p++] = c;
+
+                        if (!silent_mode && ttyfd >= 0)
+                                loop_write(ttyfd, "*", 1, false);
+
+                        dirty = true;
+                }
+        }
+
+        passphrase[p] = 0;
+
+        if (!(*_passphrase = strdup(passphrase))) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = 0;
+
+finish:
+        if (notify >= 0)
+                close_nointr_nofail(notify);
+
+        if (ttyfd >= 0) {
+
+                if (reset_tty) {
+                        loop_write(ttyfd, "\n", 1, false);
+                        tcsetattr(ttyfd, TCSADRAIN, &old_termios);
+                }
+
+                close_nointr_nofail(ttyfd);
+        }
+
+        return r;
+}
+
+static int create_socket(char **name) {
+        int fd;
+        union {
+                struct sockaddr sa;
+                struct sockaddr_un un;
+        } sa;
+        int one = 1, r;
+        char *c;
+        mode_t u;
+
+        assert(name);
+
+        if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
+                log_error("socket() failed: %m");
+                return -errno;
+        }
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%llu", random_ull());
+
+        u = umask(0177);
+        r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
+        umask(u);
+
+        if (r < 0) {
+                r = -errno;
+                log_error("bind() failed: %m");
+                goto fail;
+        }
+
+        if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) {
+                r = -errno;
+                log_error("SO_PASSCRED failed: %m");
+                goto fail;
+        }
+
+        if (!(c = strdup(sa.un.sun_path))) {
+                r = log_oom();
+                goto fail;
+        }
+
+        *name = c;
+        return fd;
+
+fail:
+        close_nointr_nofail(fd);
+
+        return r;
+}
+
+int ask_password_agent(
+                const char *message,
+                const char *icon,
+                usec_t until,
+                bool accept_cached,
+                char ***_passphrases) {
+
+        enum {
+                FD_SOCKET,
+                FD_SIGNAL,
+                _FD_MAX
+        };
+
+        char temp[] = "/run/systemd/ask-password/tmp.XXXXXX";
+        char final[sizeof(temp)] = "";
+        int fd = -1, r;
+        FILE *f = NULL;
+        char *socket_name = NULL;
+        int socket_fd = -1, signal_fd = -1;
+        sigset_t mask, oldmask;
+        struct pollfd pollfd[_FD_MAX];
+        mode_t u;
+
+        assert(_passphrases);
+
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+        assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
+
+        mkdir_p_label("/run/systemd/ask-password", 0755);
+
+        u = umask(0022);
+        fd = mkostemp(temp, O_CLOEXEC|O_CREAT|O_WRONLY);
+        umask(u);
+
+        if (fd < 0) {
+                log_error("Failed to create password file: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        fchmod(fd, 0644);
+
+        if (!(f = fdopen(fd, "w"))) {
+                log_error("Failed to allocate FILE: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        fd = -1;
+
+        if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
+                log_error("signalfd(): %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if ((socket_fd = create_socket(&socket_name)) < 0) {
+                r = socket_fd;
+                goto finish;
+        }
+
+        fprintf(f,
+                "[Ask]\n"
+                "PID=%lu\n"
+                "Socket=%s\n"
+                "AcceptCached=%i\n"
+                "NotAfter=%llu\n",
+                (unsigned long) getpid(),
+                socket_name,
+                accept_cached ? 1 : 0,
+                (unsigned long long) until);
+
+        if (message)
+                fprintf(f, "Message=%s\n", message);
+
+        if (icon)
+                fprintf(f, "Icon=%s\n", icon);
+
+        fflush(f);
+
+        if (ferror(f)) {
+                log_error("Failed to write query file: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        memcpy(final, temp, sizeof(temp));
+
+        final[sizeof(final)-11] = 'a';
+        final[sizeof(final)-10] = 's';
+        final[sizeof(final)-9] = 'k';
+
+        if (rename(temp, final) < 0) {
+                log_error("Failed to rename query file: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        zero(pollfd);
+        pollfd[FD_SOCKET].fd = socket_fd;
+        pollfd[FD_SOCKET].events = POLLIN;
+        pollfd[FD_SIGNAL].fd = signal_fd;
+        pollfd[FD_SIGNAL].events = POLLIN;
+
+        for (;;) {
+                char passphrase[LINE_MAX+1];
+                struct msghdr msghdr;
+                struct iovec iovec;
+                struct ucred *ucred;
+                union {
+                        struct cmsghdr cmsghdr;
+                        uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
+                } control;
+                ssize_t n;
+                int k;
+                usec_t t;
+
+                t = now(CLOCK_MONOTONIC);
+
+                if (until > 0 && until <= t) {
+                        log_notice("Timed out");
+                        r = -ETIME;
+                        goto finish;
+                }
+
+                if ((k = poll(pollfd, _FD_MAX, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1)) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        log_error("poll() failed: %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (k <= 0) {
+                        log_notice("Timed out");
+                        r = -ETIME;
+                        goto finish;
+                }
+
+                if (pollfd[FD_SIGNAL].revents & POLLIN) {
+                        r = -EINTR;
+                        goto finish;
+                }
+
+                if (pollfd[FD_SOCKET].revents != POLLIN) {
+                        log_error("Unexpected poll() event.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                zero(iovec);
+                iovec.iov_base = passphrase;
+                iovec.iov_len = sizeof(passphrase);
+
+                zero(control);
+                zero(msghdr);
+                msghdr.msg_iov = &iovec;
+                msghdr.msg_iovlen = 1;
+                msghdr.msg_control = &control;
+                msghdr.msg_controllen = sizeof(control);
+
+                if ((n = recvmsg(socket_fd, &msghdr, 0)) < 0) {
+
+                        if (errno == EAGAIN ||
+                            errno == EINTR)
+                                continue;
+
+                        log_error("recvmsg() failed: %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (n <= 0) {
+                        log_error("Message too short");
+                        continue;
+                }
+
+                if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
+                    control.cmsghdr.cmsg_level != SOL_SOCKET ||
+                    control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
+                    control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
+                        log_warning("Received message without credentials. Ignoring.");
+                        continue;
+                }
+
+                ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
+                if (ucred->uid != 0) {
+                        log_warning("Got request from unprivileged user. Ignoring.");
+                        continue;
+                }
+
+                if (passphrase[0] == '+') {
+                        char **l;
+
+                        if (n == 1)
+                                l = strv_new("", NULL);
+                        else
+                                l = strv_parse_nulstr(passphrase+1, n-1);
+                                /* An empty message refers to the empty password */
+
+                        if (!l) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        if (strv_length(l) <= 0) {
+                                strv_free(l);
+                                log_error("Invalid packet");
+                                continue;
+                        }
+
+                        *_passphrases = l;
+
+                } else if (passphrase[0] == '-') {
+                        r = -ECANCELED;
+                        goto finish;
+                } else {
+                        log_error("Invalid packet");
+                        continue;
+                }
+
+                break;
+        }
+
+        r = 0;
+
+finish:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        if (socket_name) {
+                unlink(socket_name);
+                free(socket_name);
+        }
+
+        if (socket_fd >= 0)
+                close_nointr_nofail(socket_fd);
+
+        if (signal_fd >= 0)
+                close_nointr_nofail(signal_fd);
+
+        if (f)
+                fclose(f);
+
+        unlink(temp);
+
+        if (final[0])
+                unlink(final);
+
+        assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
+
+        return r;
+}
+
+int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases) {
+        assert(message);
+        assert(_passphrases);
+
+        if (isatty(STDIN_FILENO)) {
+                int r;
+                char *s = NULL, **l = NULL;
+
+                if ((r = ask_password_tty(message, until, NULL, &s)) < 0)
+                        return r;
+
+                l = strv_new(s, NULL);
+                free(s);
+
+                if (!l)
+                        return -ENOMEM;
+
+                *_passphrases = l;
+                return r;
+
+        } else
+                return ask_password_agent(message, icon, until, accept_cached, _passphrases);
+}
diff --git a/src/shared/ask-password-api.h b/src/shared/ask-password-api.h
new file mode 100644 (file)
index 0000000..288a0f4
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+
+int ask_password_tty(const char *message, usec_t until, const char *flag_file, char **_passphrase);
+
+int ask_password_agent(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases);
+
+int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases);
diff --git a/src/shared/audit.c b/src/shared/audit.c
new file mode 100644 (file)
index 0000000..e5c483a
--- /dev/null
@@ -0,0 +1,118 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/prctl.h>
+#include <sys/capability.h>
+
+#include "macro.h"
+#include "audit.h"
+#include "util.h"
+#include "log.h"
+
+int audit_session_from_pid(pid_t pid, uint32_t *id) {
+        char *s;
+        uint32_t u;
+        int r;
+
+        assert(id);
+
+        if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
+                return -ENOENT;
+
+        if (pid == 0)
+                r = read_one_line_file("/proc/self/sessionid", &s);
+        else {
+                char *p;
+
+                if (asprintf(&p, "/proc/%lu/sessionid", (unsigned long) pid) < 0)
+                        return -ENOMEM;
+
+                r = read_one_line_file(p, &s);
+                free(p);
+        }
+
+        if (r < 0)
+                return r;
+
+        r = safe_atou32(s, &u);
+        free(s);
+
+        if (r < 0)
+                return r;
+
+        if (u == (uint32_t) -1 || u <= 0)
+                return -ENOENT;
+
+        *id = u;
+        return 0;
+}
+
+int audit_loginuid_from_pid(pid_t pid, uid_t *uid) {
+        char *s;
+        uid_t u;
+        int r;
+
+        assert(uid);
+
+        /* Only use audit login uid if we are executed with sufficient
+         * capabilities so that pam_loginuid could do its job. If we
+         * are lacking the CAP_AUDIT_CONTROL capabality we most likely
+         * are being run in a container and /proc/self/loginuid is
+         * useless since it probably contains a uid of the host
+         * system. */
+
+        if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
+                return -ENOENT;
+
+        if (pid == 0)
+                r = read_one_line_file("/proc/self/loginuid", &s);
+        else {
+                char *p;
+
+                if (asprintf(&p, "/proc/%lu/loginuid", (unsigned long) pid) < 0)
+                        return -ENOMEM;
+
+                r = read_one_line_file(p, &s);
+                free(p);
+        }
+
+        if (r < 0)
+                return r;
+
+        r = parse_uid(s, &u);
+        free(s);
+
+        if (r < 0)
+                return r;
+
+        if (u == (uid_t) -1)
+                return -ENOENT;
+
+        *uid = (uid_t) u;
+        return 0;
+}
diff --git a/src/shared/audit.h b/src/shared/audit.h
new file mode 100644 (file)
index 0000000..490a0b0
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef fooaudithfoo
+#define fooaudithfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+#include "capability.h"
+
+int audit_session_from_pid(pid_t pid, uint32_t *id);
+int audit_loginuid_from_pid(pid_t pid, uid_t *uid);
+
+#endif
diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c
new file mode 100644 (file)
index 0000000..c2eae3f
--- /dev/null
@@ -0,0 +1,927 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "calendarspec.h"
+
+static void free_chain(CalendarComponent *c) {
+        CalendarComponent *n;
+
+        while (c) {
+                n = c->next;
+                free(c);
+                c = n;
+        }
+}
+
+void calendar_spec_free(CalendarSpec *c) {
+        assert(c);
+
+        free_chain(c->year);
+        free_chain(c->month);
+        free_chain(c->day);
+        free_chain(c->hour);
+        free_chain(c->minute);
+        free_chain(c->second);
+
+        free(c);
+}
+
+static int component_compare(const void *_a, const void *_b) {
+        CalendarComponent * const *a = _a, * const *b = _b;
+
+        if ((*a)->value < (*b)->value)
+                return -1;
+        if ((*a)->value > (*b)->value)
+                return 1;
+
+        if ((*a)->repeat < (*b)->repeat)
+                return -1;
+        if ((*a)->repeat > (*b)->repeat)
+                return 1;
+
+        return 0;
+}
+
+static void sort_chain(CalendarComponent **c) {
+        unsigned n = 0, k;
+        CalendarComponent **b, *i, **j, *next;
+
+        assert(c);
+
+        for (i = *c; i; i = i->next)
+                n++;
+
+        if (n <= 1)
+                return;
+
+        j = b = alloca(sizeof(CalendarComponent*) * n);
+        for (i = *c; i; i = i->next)
+                *(j++) = i;
+
+        qsort(b, n, sizeof(CalendarComponent*), component_compare);
+
+        b[n-1]->next = NULL;
+        next = b[n-1];
+
+        /* Drop non-unique entries */
+        for (k = n-1; k > 0; k--) {
+                if (b[k-1]->value == next->value &&
+                    b[k-1]->repeat == next->repeat) {
+                        free(b[k-1]);
+                        continue;
+                }
+
+                b[k-1]->next = next;
+                next = b[k-1];
+        }
+
+        *c = next;
+}
+
+static void fix_year(CalendarComponent *c) {
+        /* Turns 12 → 2012, 89 → 1989 */
+
+        while(c) {
+                CalendarComponent *n = c->next;
+
+                if (c->value >= 0 && c->value < 70)
+                        c->value += 2000;
+
+                if (c->value >= 70 && c->value < 100)
+                        c->value += 1900;
+
+                c = n;
+        }
+}
+
+int calendar_spec_normalize(CalendarSpec *c) {
+        assert(c);
+
+        if (c->weekdays_bits <= 0 || c->weekdays_bits >= 127)
+                c->weekdays_bits = -1;
+
+        fix_year(c->year);
+
+        sort_chain(&c->year);
+        sort_chain(&c->month);
+        sort_chain(&c->day);
+        sort_chain(&c->hour);
+        sort_chain(&c->minute);
+        sort_chain(&c->second);
+
+        return 0;
+}
+
+static bool chain_valid(CalendarComponent *c, int from, int to) {
+        if (!c)
+                return true;
+
+        if (c->value < from || c->value > to)
+                return false;
+
+        if (c->value + c->repeat > to)
+                return false;
+
+        if (c->next)
+                return chain_valid(c->next, from, to);
+
+        return true;
+}
+
+bool calendar_spec_valid(CalendarSpec *c) {
+        assert(c);
+
+        if (c->weekdays_bits > 127)
+                return false;
+
+        if (!chain_valid(c->year, 1970, 2199))
+                return false;
+
+        if (!chain_valid(c->month, 1, 12))
+                return false;
+
+        if (!chain_valid(c->day, 1, 31))
+                return false;
+
+        if (!chain_valid(c->hour, 0, 23))
+                return false;
+
+        if (!chain_valid(c->minute, 0, 59))
+                return false;
+
+        if (!chain_valid(c->second, 0, 59))
+                return false;
+
+        return true;
+}
+
+static void format_weekdays(FILE *f, const CalendarSpec *c) {
+        static const char *const days[] = {
+                "Mon",
+                "Tue",
+                "Wed",
+                "Thu",
+                "Fri",
+                "Sat",
+                "Sun"
+        };
+
+        int l, x;
+        bool need_colon = false;
+
+        assert(f);
+        assert(c);
+        assert(c->weekdays_bits > 0 && c->weekdays_bits <= 127);
+
+        for (x = 0, l = -1; x < (int) ELEMENTSOF(days); x++) {
+
+                if (c->weekdays_bits & (1 << x)) {
+
+                        if (l < 0) {
+                                if (need_colon)
+                                        fputc(',', f);
+                                else
+                                        need_colon = true;
+
+                                fputs(days[x], f);
+                                l = x;
+                        }
+
+                } else if (l >= 0) {
+
+                        if (x > l + 1) {
+                                fputc(x > l + 2 ? '-' : ',', f);
+                                fputs(days[x-1], f);
+                        }
+
+                        l = -1;
+                }
+        }
+
+        if (l >= 0 && x > l + 1) {
+                fputc(x > l + 2 ? '-' : ',', f);
+                fputs(days[x-1], f);
+        }
+}
+
+static void format_chain(FILE *f, int space, const CalendarComponent *c) {
+        assert(f);
+
+        if (!c) {
+                fputc('*', f);
+                return;
+        }
+
+        assert(c->value >= 0);
+        fprintf(f, "%0*i", space, c->value);
+
+        if (c->repeat > 0)
+                fprintf(f, "/%i", c->repeat);
+
+        if (c->next) {
+                fputc(',', f);
+                format_chain(f, space, c->next);
+        }
+}
+
+int calendar_spec_to_string(const CalendarSpec *c, char **p) {
+        char *buf = NULL;
+        size_t sz = 0;
+        FILE *f;
+
+        assert(c);
+        assert(p);
+
+        f = open_memstream(&buf, &sz);
+        if (!f)
+                return -ENOMEM;
+
+        if (c->weekdays_bits > 0 && c->weekdays_bits <= 127) {
+                format_weekdays(f, c);
+                fputc(' ', f);
+        }
+
+        format_chain(f, 4, c->year);
+        fputc('-', f);
+        format_chain(f, 2, c->month);
+        fputc('-', f);
+        format_chain(f, 2, c->day);
+        fputc(' ', f);
+        format_chain(f, 2, c->hour);
+        fputc(':', f);
+        format_chain(f, 2, c->minute);
+        fputc(':', f);
+        format_chain(f, 2, c->second);
+
+        fflush(f);
+
+        if (ferror(f)) {
+                free(buf);
+                fclose(f);
+                return -ENOMEM;
+        }
+
+        fclose(f);
+
+        *p = buf;
+        return 0;
+}
+
+static int parse_weekdays(const char **p, CalendarSpec *c) {
+        static const struct {
+                const char *name;
+                const int nr;
+        } day_nr[] = {
+                { "Monday",    0 },
+                { "Mon",       0 },
+                { "Tuesday",   1 },
+                { "Tue",       1 },
+                { "Wednesday", 2 },
+                { "Wed",       2 },
+                { "Thursday",  3 },
+                { "Thu",       3 },
+                { "Friday",    4 },
+                { "Fri",       4 },
+                { "Saturday",  5 },
+                { "Sat",       5 },
+                { "Sunday",    6 },
+                { "Sun",       6 }
+        };
+
+        int l = -1;
+        bool first = true;
+
+        assert(p);
+        assert(*p);
+        assert(c);
+
+        for (;;) {
+                unsigned i;
+
+                if (!first && **p == ' ')
+                        return 0;
+
+                for (i = 0; i < ELEMENTSOF(day_nr); i++) {
+                        size_t skip;
+
+                        if (!startswith_no_case(*p, day_nr[i].name))
+                                continue;
+
+                        skip = strlen(day_nr[i].name);
+
+                        if ((*p)[skip] != '-' &&
+                            (*p)[skip] != ',' &&
+                            (*p)[skip] != ' ' &&
+                            (*p)[skip] != 0)
+                                return -EINVAL;
+
+                        c->weekdays_bits |= 1 << day_nr[i].nr;
+
+                        if (l >= 0) {
+                                int j;
+
+                                if (l > day_nr[i].nr)
+                                        return -EINVAL;
+
+                                for (j = l + 1; j < day_nr[i].nr; j++)
+                                        c->weekdays_bits |= 1 << j;
+                        }
+
+                        *p += skip;
+                        break;
+                }
+
+                /* Couldn't find this prefix, so let's assume the
+                   weekday was not specified and let's continue with
+                   the date */
+                if (i >= ELEMENTSOF(day_nr))
+                        return first ? 0 : -EINVAL;
+
+                /* We reached the end of the string */
+                if (**p == 0)
+                        return 0;
+
+                /* We reached the end of the weekday spec part */
+                if (**p == ' ') {
+                        *p += strspn(*p, " ");
+                        return 0;
+                }
+
+                if (**p == '-') {
+                        if (l >= 0)
+                                return -EINVAL;
+
+                        l = day_nr[i].nr;
+                } else
+                        l = -1;
+
+                *p += 1;
+                first = false;
+        }
+}
+
+static int prepend_component(const char **p, CalendarComponent **c) {
+        unsigned long value, repeat = 0;
+        char *e = NULL, *ee = NULL;
+        CalendarComponent *cc;
+
+        assert(p);
+        assert(c);
+
+        errno = 0;
+        value = strtoul(*p, &e, 10);
+        if (errno != 0)
+                return -errno;
+        if (e == *p)
+                return -EINVAL;
+        if ((unsigned long) (int) value != value)
+                return -ERANGE;
+
+        if (*e == '/') {
+                repeat = strtoul(e+1, &ee, 10);
+                if (errno != 0)
+                        return -errno;
+                if (ee == e+1)
+                        return -EINVAL;
+                if ((unsigned long) (int) repeat != repeat)
+                        return -ERANGE;
+                if (repeat <= 0)
+                        return -ERANGE;
+
+                e = ee;
+        }
+
+        if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != ':')
+                return -EINVAL;
+
+        cc = new0(CalendarComponent, 1);
+        if (!cc)
+                return -ENOMEM;
+
+        cc->value = value;
+        cc->repeat = repeat;
+        cc->next = *c;
+
+        *p = e;
+        *c = cc;
+
+        if (*e ==',') {
+                *p += 1;
+                return prepend_component(p, c);
+        }
+
+        return 0;
+}
+
+static int parse_chain(const char **p, CalendarComponent **c) {
+        const char *t;
+        CalendarComponent *cc = NULL;
+        int r;
+
+        assert(p);
+        assert(c);
+
+        t = *p;
+
+        if (t[0] == '*') {
+                *p = t + 1;
+                *c = NULL;
+                return 0;
+        }
+
+        r = prepend_component(&t, &cc);
+        if (r < 0) {
+                free_chain(cc);
+                return r;
+        }
+
+        *p = t;
+        *c = cc;
+        return 0;
+}
+
+static int const_chain(int value, CalendarComponent **c) {
+        CalendarComponent *cc = NULL;
+
+        assert(c);
+
+        cc = new0(CalendarComponent, 1);
+        if (!cc)
+                return -ENOMEM;
+
+        cc->value = value;
+        cc->repeat = 0;
+        cc->next = NULL;
+
+        *c = cc;
+
+        return 0;
+}
+
+static int parse_date(const char **p, CalendarSpec *c) {
+        const char *t;
+        int r;
+        CalendarComponent *first, *second, *third;
+
+        assert(p);
+        assert(*p);
+        assert(c);
+
+        t = *p;
+
+        if (*t == 0)
+                return 0;
+
+        r = parse_chain(&t, &first);
+        if (r < 0)
+                return r;
+
+        /* Already the end? A ':' as separator? In that case this was a time, not a date */
+        if (*t == 0 || *t == ':') {
+                free_chain(first);
+                return 0;
+        }
+
+        if (*t != '-') {
+                free_chain(first);
+                return -EINVAL;
+        }
+
+        t++;
+        r = parse_chain(&t, &second);
+        if (r < 0) {
+                free_chain(first);
+                return r;
+        }
+
+        /* Got two parts, hence it's month and day */
+        if (*t == ' ' || *t == 0) {
+                *p = t + strspn(t, " ");
+                c->month = first;
+                c->day = second;
+                return 0;
+        }
+
+        if (*t != '-') {
+                free_chain(first);
+                free_chain(second);
+                return -EINVAL;
+        }
+
+        t++;
+        r = parse_chain(&t, &third);
+        if (r < 0) {
+                free_chain(first);
+                free_chain(second);
+                return r;
+        }
+
+        /* Got tree parts, hence it is year, month and day */
+        if (*t == ' ' || *t == 0) {
+                *p = t + strspn(t, " ");
+                c->year = first;
+                c->month = second;
+                c->day = third;
+                return 0;
+        }
+
+        free_chain(first);
+        free_chain(second);
+        free_chain(third);
+        return -EINVAL;
+}
+
+static int parse_time(const char **p, CalendarSpec *c) {
+        CalendarComponent *h = NULL, *m = NULL, *s = NULL;
+        const char *t;
+        int r;
+
+        assert(p);
+        assert(*p);
+        assert(c);
+
+        t = *p;
+
+        if (*t == 0) {
+                /* If no time is specified at all, but a date of some
+                 * kind, then this means 00:00:00 */
+                if (c->day || c->weekdays_bits > 0)
+                        goto null_hour;
+
+                goto finish;
+        }
+
+        r = parse_chain(&t, &h);
+        if (r < 0)
+                goto fail;
+
+        if (*t != ':') {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        t++;
+        r = parse_chain(&t, &m);
+        if (r < 0)
+                goto fail;
+
+        /* Already at the end? Then it's hours and minutes, and seconds are 0 */
+        if (*t == 0) {
+                if (m != NULL)
+                        goto null_second;
+
+                goto finish;
+        }
+
+        if (*t != ':') {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        t++;
+        r = parse_chain(&t, &s);
+        if (r < 0)
+                goto fail;
+
+        /* At the end? Then it's hours, minutes and seconds */
+        if (*t == 0)
+                goto finish;
+
+        r = -EINVAL;
+        goto fail;
+
+null_hour:
+        r = const_chain(0, &h);
+        if (r < 0)
+                goto fail;
+
+        r = const_chain(0, &m);
+        if (r < 0)
+                goto fail;
+
+null_second:
+        r = const_chain(0, &s);
+        if (r < 0)
+                goto fail;
+
+finish:
+        *p = t;
+        c->hour = h;
+        c->minute = m;
+        c->second = s;
+        return 0;
+
+fail:
+        free_chain(h);
+        free_chain(m);
+        free_chain(s);
+        return r;
+}
+
+int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
+        CalendarSpec *c;
+        int r;
+
+        assert(p);
+        assert(spec);
+
+        if (isempty(p))
+                return -EINVAL;
+
+        c = new0(CalendarSpec, 1);
+        if (!c)
+                return -ENOMEM;
+
+        if (strcasecmp(p, "hourly") == 0) {
+                r = const_chain(0, &c->minute);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->second);
+                if (r < 0)
+                        goto fail;
+
+        } else if (strcasecmp(p, "daily") == 0) {
+                r = const_chain(0, &c->hour);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->minute);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->second);
+                if (r < 0)
+                        goto fail;
+
+        } else if (strcasecmp(p, "monthly") == 0) {
+                r = const_chain(1, &c->day);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->hour);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->minute);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->second);
+                if (r < 0)
+                        goto fail;
+
+        } else if (strcasecmp(p, "weekly") == 0) {
+
+                c->weekdays_bits = 1;
+
+                r = const_chain(0, &c->hour);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->minute);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->second);
+                if (r < 0)
+                        goto fail;
+
+        } else {
+                r = parse_weekdays(&p, c);
+                if (r < 0)
+                        goto fail;
+
+                r = parse_date(&p, c);
+                if (r < 0)
+                        goto fail;
+
+                r = parse_time(&p, c);
+                if (r < 0)
+                        goto fail;
+
+                if (*p != 0) {
+                        r = -EINVAL;
+                        goto fail;
+                }
+        }
+
+        r = calendar_spec_normalize(c);
+        if (r < 0)
+                goto fail;
+
+        if (!calendar_spec_valid(c)) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        *spec = c;
+        return 0;
+
+fail:
+        calendar_spec_free(c);
+        return r;
+}
+
+static int find_matching_component(const CalendarComponent *c, int *val) {
+        const CalendarComponent *n;
+        int d = -1;
+        bool d_set = false;
+        int r;
+
+        assert(val);
+
+        if (!c)
+                return 0;
+
+        while (c) {
+                n = c->next;
+
+                if (c->value >= *val) {
+
+                        if (!d_set || c->value < d) {
+                                d = c->value;
+                                d_set = true;
+                        }
+
+                } else if (c->repeat > 0) {
+                        int k;
+
+                        k = c->value + c->repeat * ((*val - c->value + c->repeat -1) / c->repeat);
+
+                        if (!d_set || k < d) {
+                                d = k;
+                                d_set = true;
+                        }
+                }
+
+                c = n;
+        }
+
+        if (!d_set)
+                return -ENOENT;
+
+        r = *val != d;
+        *val = d;
+        return r;
+}
+
+static bool tm_out_of_bounds(const struct tm *tm) {
+        struct tm t;
+        assert(tm);
+
+        t = *tm;
+
+        if (mktime(&t) == (time_t) -1)
+                return true;
+
+        /* Did any normalization take place? If so, it was out of bounds before */
+        return
+                t.tm_year != tm->tm_year ||
+                t.tm_mon != tm->tm_mon ||
+                t.tm_mday != tm->tm_mday ||
+                t.tm_hour != tm->tm_hour ||
+                t.tm_min != tm->tm_min ||
+                t.tm_sec != tm->tm_sec;
+}
+
+static bool matches_weekday(int weekdays_bits, const struct tm *tm) {
+        struct tm t;
+        int k;
+
+        if (weekdays_bits < 0 || weekdays_bits >= 127)
+                return true;
+
+        t = *tm;
+        if (mktime(&t) == (time_t) -1)
+                return false;
+
+        k = t.tm_wday == 0 ? 6 : t.tm_wday - 1;
+        return (weekdays_bits & (1 << k));
+}
+
+static int find_next(const CalendarSpec *spec, struct tm *tm) {
+        struct tm c;
+        int r;
+
+        assert(spec);
+        assert(tm);
+
+        c = *tm;
+
+        for (;;) {
+                /* Normalize the current date */
+                mktime(&c);
+                c.tm_isdst = -1;
+
+                c.tm_year += 1900;
+                r = find_matching_component(spec->year, &c.tm_year);
+                c.tm_year -= 1900;
+
+                if (r > 0) {
+                        c.tm_mon = 0;
+                        c.tm_mday = 1;
+                        c.tm_hour = c.tm_min = c.tm_sec = 0;
+                }
+                if (r < 0 || tm_out_of_bounds(&c))
+                        return r;
+
+                c.tm_mon += 1;
+                r = find_matching_component(spec->month, &c.tm_mon);
+                c.tm_mon -= 1;
+
+                if (r > 0) {
+                        c.tm_mday = 1;
+                        c.tm_hour = c.tm_min = c.tm_sec = 0;
+                }
+                if (r < 0 || tm_out_of_bounds(&c)) {
+                        c.tm_year ++;
+                        c.tm_mon = 0;
+                        c.tm_mday = 1;
+                        c.tm_hour = c.tm_min = c.tm_sec = 0;
+                        continue;
+                }
+
+                r = find_matching_component(spec->day, &c.tm_mday);
+                if (r > 0)
+                        c.tm_hour = c.tm_min = c.tm_sec = 0;
+                if (r < 0 || tm_out_of_bounds(&c)) {
+                        c.tm_mon ++;
+                        c.tm_mday = 1;
+                        c.tm_hour = c.tm_min = c.tm_sec = 0;
+                        continue;
+                }
+
+                if (!matches_weekday(spec->weekdays_bits, &c)) {
+                        c.tm_mday++;
+                        c.tm_hour = c.tm_min = c.tm_sec = 0;
+                        continue;
+                }
+
+                r = find_matching_component(spec->hour, &c.tm_hour);
+                if (r > 0)
+                        c.tm_min = c.tm_sec = 0;
+                if (r < 0 || tm_out_of_bounds(&c)) {
+                        c.tm_mday ++;
+                        c.tm_hour = c.tm_min = c.tm_sec = 0;
+                        continue;
+                }
+
+                r = find_matching_component(spec->minute, &c.tm_min);
+                if (r > 0)
+                        c.tm_sec = 0;
+                if (r < 0 || tm_out_of_bounds(&c)) {
+                        c.tm_hour ++;
+                        c.tm_min = c.tm_sec = 0;
+                        continue;
+                }
+
+                r = find_matching_component(spec->second, &c.tm_sec);
+                if (r < 0 || tm_out_of_bounds(&c)) {
+                        c.tm_min ++;
+                        c.tm_sec = 0;
+                        continue;
+                }
+
+
+                *tm = c;
+                return 0;
+        }
+}
+
+int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next) {
+        struct tm tm;
+        time_t t;
+        int r;
+
+        assert(spec);
+        assert(next);
+
+        t = (time_t) (usec / USEC_PER_SEC) + 1;
+        assert_se(localtime_r(&t, &tm));
+
+        r = find_next(spec, &tm);
+        if (r < 0)
+                return r;
+
+        t = mktime(&tm);
+        if (t == (time_t) -1)
+                return -EINVAL;
+
+
+        *next = (usec_t) t * USEC_PER_SEC;
+        return 0;
+}
diff --git a/src/shared/calendarspec.h b/src/shared/calendarspec.h
new file mode 100644 (file)
index 0000000..7baf318
--- /dev/null
@@ -0,0 +1,57 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* A structure for specifying (possibly repetitive) points in calendar
+ * time, a la cron */
+
+#include <stdbool.h>
+#include "util.h"
+
+typedef struct CalendarComponent {
+        int value;
+        int repeat;
+
+        struct CalendarComponent *next;
+} CalendarComponent;
+
+typedef struct CalendarSpec {
+        int weekdays_bits;
+
+        CalendarComponent *year;
+        CalendarComponent *month;
+        CalendarComponent *day;
+
+        CalendarComponent *hour;
+        CalendarComponent *minute;
+        CalendarComponent *second;
+} CalendarSpec;
+
+void calendar_spec_free(CalendarSpec *c);
+
+int calendar_spec_normalize(CalendarSpec *spec);
+bool calendar_spec_valid(CalendarSpec *spec);
+
+int calendar_spec_to_string(const CalendarSpec *spec, char **p);
+int calendar_spec_from_string(const char *p, CalendarSpec **spec);
+
+int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next);
diff --git a/src/shared/capability.c b/src/shared/capability.c
new file mode 100644 (file)
index 0000000..9b743e8
--- /dev/null
@@ -0,0 +1,224 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+
+#include "macro.h"
+#include "capability.h"
+#include "util.h"
+#include "log.h"
+
+int have_effective_cap(int value) {
+        cap_t cap;
+        cap_flag_value_t fv;
+        int r;
+
+        cap = cap_get_proc();
+        if (!cap)
+                return -errno;
+
+        if (cap_get_flag(cap, value, CAP_EFFECTIVE, &fv) < 0)
+                r = -errno;
+        else
+                r = fv == CAP_SET;
+
+        cap_free(cap);
+        return r;
+}
+
+unsigned long cap_last_cap(void) {
+        static __thread unsigned long saved;
+        static __thread bool valid = false;
+        unsigned long p;
+
+        if (valid)
+                return saved;
+
+        p = (unsigned long) CAP_LAST_CAP;
+
+        if (prctl(PR_CAPBSET_READ, p) < 0) {
+
+                /* Hmm, look downwards, until we find one that
+                 * works */
+                for (p--; p > 0; p --)
+                        if (prctl(PR_CAPBSET_READ, p) >= 0)
+                                break;
+
+        } else {
+
+                /* Hmm, look upwards, until we find one that doesn't
+                 * work */
+                for (;; p++)
+                        if (prctl(PR_CAPBSET_READ, p+1) < 0)
+                                break;
+        }
+
+        saved = p;
+        valid = true;
+
+        return p;
+}
+
+int capability_bounding_set_drop(uint64_t drop, bool right_now) {
+        unsigned long i;
+        cap_t after_cap = NULL, temp_cap = NULL;
+        cap_flag_value_t fv;
+        int r;
+
+        /* If we are run as PID 1 we will lack CAP_SETPCAP by default
+         * in the effective set (yes, the kernel drops that when
+         * executing init!), so get it back temporarily so that we can
+         * call PR_CAPBSET_DROP. */
+
+        after_cap = cap_get_proc();
+        if (!after_cap)
+                return -errno;
+
+        if (cap_get_flag(after_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0) {
+                cap_free(after_cap);
+                return -errno;
+        }
+
+        if (fv != CAP_SET) {
+                static const cap_value_t v = CAP_SETPCAP;
+
+                temp_cap = cap_dup(after_cap);
+                if (!temp_cap) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (cap_set_flag(temp_cap, CAP_EFFECTIVE, 1, &v, CAP_SET) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (cap_set_proc(temp_cap) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        for (i = 0; i <= cap_last_cap(); i++) {
+
+                if (drop & ((uint64_t) 1ULL << (uint64_t) i)) {
+                        cap_value_t v;
+
+                        /* Drop it from the bounding set */
+                        if (prctl(PR_CAPBSET_DROP, i) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+                        v = i;
+
+                        /* Also drop it from the inheritable set, so
+                         * that anything we exec() loses the
+                         * capability for good. */
+                        if (cap_set_flag(after_cap, CAP_INHERITABLE, 1, &v, CAP_CLEAR) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                        /* If we shall apply this right now drop it
+                         * also from our own capability sets. */
+                        if (right_now) {
+                                if (cap_set_flag(after_cap, CAP_PERMITTED, 1, &v, CAP_CLEAR) < 0 ||
+                                    cap_set_flag(after_cap, CAP_EFFECTIVE, 1, &v, CAP_CLEAR) < 0) {
+                                        r = -errno;
+                                        goto finish;
+                                }
+                        }
+                }
+        }
+
+        r = 0;
+
+finish:
+        if (temp_cap)
+                cap_free(temp_cap);
+
+        if (after_cap) {
+                cap_set_proc(after_cap);
+                cap_free(after_cap);
+        }
+
+        return r;
+}
+
+static int drop_from_file(const char *fn, uint64_t drop) {
+        int r, k;
+        uint32_t hi, lo;
+        uint64_t current, after;
+        char *p;
+
+        r = read_one_line_file(fn, &p);
+        if (r < 0)
+                return r;
+
+        assert_cc(sizeof(hi) == sizeof(unsigned));
+        assert_cc(sizeof(lo) == sizeof(unsigned));
+
+        k = sscanf(p, "%u %u", &lo, &hi);
+        free(p);
+
+        if (k != 2)
+                return -EIO;
+
+        current = (uint64_t) lo | ((uint64_t) hi << 32ULL);
+        after = current & ~drop;
+
+        if (current == after)
+                return 0;
+
+        lo = (unsigned) (after & 0xFFFFFFFFULL);
+        hi = (unsigned) ((after >> 32ULL) & 0xFFFFFFFFULL);
+
+        if (asprintf(&p, "%u %u", lo, hi) < 0)
+                return -ENOMEM;
+
+        r = write_one_line_file(fn, p);
+        free(p);
+
+        return r;
+}
+
+int capability_bounding_set_drop_usermode(uint64_t drop) {
+        int r;
+
+        r = drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", drop);
+        if (r < 0)
+                return r;
+
+        r = drop_from_file("/proc/sys/kernel/usermodehelper/bset", drop);
+        if (r < 0)
+                return r;
+
+        return r;
+}
diff --git a/src/shared/capability.h b/src/shared/capability.h
new file mode 100644 (file)
index 0000000..6cb31bb
--- /dev/null
@@ -0,0 +1,33 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foocapabilityhfoo
+#define foocapabilityhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+unsigned long cap_last_cap(void);
+int have_effective_cap(int value);
+int capability_bounding_set_drop(uint64_t drop, bool right_now);
+int capability_bounding_set_drop_usermode(uint64_t drop);
+
+#endif
diff --git a/src/shared/cgroup-label.c b/src/shared/cgroup-label.c
new file mode 100644 (file)
index 0000000..beeeec5
--- /dev/null
@@ -0,0 +1,82 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <ftw.h>
+
+#include "cgroup-util.h"
+#include "log.h"
+#include "set.h"
+#include "macro.h"
+#include "util.h"
+#include "mkdir.h"
+
+int cg_create(const char *controller, const char *path) {
+        char *fs;
+        int r;
+
+        assert(controller);
+        assert(path);
+
+        r = cg_get_path_and_check(controller, path, NULL, &fs);
+        if (r < 0)
+                return r;
+
+        r = mkdir_parents_label(fs, 0755);
+
+        if (r >= 0) {
+                if (mkdir(fs, 0755) >= 0)
+                        r = 1;
+                else if (errno == EEXIST)
+                        r = 0;
+                else
+                        r = -errno;
+        }
+
+        free(fs);
+
+        return r;
+}
+
+int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
+        int r, q;
+
+        assert(controller);
+        assert(path);
+        assert(pid >= 0);
+
+        if ((r = cg_create(controller, path)) < 0)
+                return r;
+
+        if ((q = cg_attach(controller, path, pid)) < 0)
+                return q;
+
+        /* This does not remove the cgroup on failure */
+
+        return r;
+}
diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
new file mode 100644 (file)
index 0000000..2b79f37
--- /dev/null
@@ -0,0 +1,347 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "util.h"
+#include "macro.h"
+#include "path-util.h"
+#include "cgroup-util.h"
+#include "cgroup-show.h"
+
+static int compare(const void *a, const void *b) {
+        const pid_t *p = a, *q = b;
+
+        if (*p < *q)
+                return -1;
+        if (*p > *q)
+                return 1;
+        return 0;
+}
+
+static unsigned ilog10(unsigned long ul) {
+        int n = 0;
+
+        while (ul > 0) {
+                n++;
+                ul /= 10;
+        }
+
+        return n;
+}
+
+static void show_pid_array(int pids[], unsigned n_pids, const char *prefix, unsigned n_columns, bool extra, bool more, bool kernel_threads) {
+        unsigned i, m, pid_width;
+        pid_t biggest = 0;
+
+        /* Filter duplicates */
+        m = 0;
+        for (i = 0; i < n_pids; i++) {
+                unsigned j;
+
+                if (pids[i] > biggest)
+                        biggest = pids[i];
+
+                for (j = i+1; j < n_pids; j++)
+                        if (pids[i] == pids[j])
+                                break;
+
+                if (j >= n_pids)
+                        pids[m++] = pids[i];
+        }
+        n_pids = m;
+        pid_width = ilog10(biggest);
+
+        /* And sort */
+        qsort(pids, n_pids, sizeof(pid_t), compare);
+
+        if (n_columns > pid_width+2)
+                n_columns -= pid_width+2;
+        else
+                n_columns = 20;
+
+        for (i = 0; i < n_pids; i++) {
+                char *t = NULL;
+
+                get_process_cmdline(pids[i], n_columns, true, &t);
+
+                printf("%s%s%*lu %s\n",
+                       prefix,
+                       draw_special_char(extra ? DRAW_TRIANGULAR_BULLET :
+                                         ((more || i < n_pids-1) ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT)),
+                       pid_width,
+                       (unsigned long) pids[i],
+                       strna(t));
+
+                free(t);
+        }
+}
+
+
+static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigned n_columns, bool more, bool kernel_threads) {
+        char *fn;
+        FILE *f;
+        size_t n = 0, n_allocated = 0;
+        pid_t *pids = NULL;
+        char *p;
+        pid_t pid;
+        int r;
+
+        r = cg_fix_path(path, &p);
+        if (r < 0)
+                return r;
+
+        r = asprintf(&fn, "%s/cgroup.procs", p);
+        free(p);
+        if (r < 0)
+                return -ENOMEM;
+
+        f = fopen(fn, "re");
+        free(fn);
+        if (!f)
+                return -errno;
+
+        while ((r = cg_read_pid(f, &pid)) > 0) {
+
+                if (!kernel_threads && is_kernel_thread(pid) > 0)
+                        continue;
+
+                if (n >= n_allocated) {
+                        pid_t *npids;
+
+                        n_allocated = MAX(16U, n*2U);
+
+                        npids = realloc(pids, sizeof(pid_t) * n_allocated);
+                        if (!npids) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        pids = npids;
+                }
+
+                assert(n < n_allocated);
+                pids[n++] = pid;
+        }
+
+        if (r < 0)
+                goto finish;
+
+        if (n > 0)
+                show_pid_array(pids, n, prefix, n_columns, false, more, kernel_threads);
+
+        r = 0;
+
+finish:
+        free(pids);
+
+        if (f)
+                fclose(f);
+
+        return r;
+}
+
+int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, bool all) {
+        DIR *d;
+        char *last = NULL;
+        char *p1 = NULL, *p2 = NULL, *fn = NULL, *gn = NULL;
+        bool shown_pids = false;
+        int r;
+
+        assert(path);
+
+        if (n_columns <= 0)
+                n_columns = columns();
+
+        if (!prefix)
+                prefix = "";
+
+        r = cg_fix_path(path, &fn);
+        if (r < 0)
+                return r;
+
+        d = opendir(fn);
+        if (!d) {
+                free(fn);
+                return -errno;
+        }
+
+        while ((r = cg_read_subgroup(d, &gn)) > 0) {
+                char *k;
+
+                r = asprintf(&k, "%s/%s", fn, gn);
+                free(gn);
+                if (r < 0) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (!all && cg_is_empty_recursive(NULL, k, false) > 0) {
+                        free(k);
+                        continue;
+                }
+
+                if (!shown_pids) {
+                        show_cgroup_one_by_path(path, prefix, n_columns, true, kernel_threads);
+                        shown_pids = true;
+                }
+
+                if (last) {
+                        printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_BRANCH),
+                                           path_get_file_name(last));
+
+                        if (!p1) {
+                                p1 = strappend(prefix, draw_special_char(DRAW_TREE_VERT));
+                                if (!p1) {
+                                        free(k);
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+                        }
+
+                        show_cgroup_by_path(last, p1, n_columns-2, kernel_threads, all);
+                        free(last);
+                }
+
+                last = k;
+        }
+
+        if (r < 0)
+                goto finish;
+
+        if (!shown_pids)
+                show_cgroup_one_by_path(path, prefix, n_columns, !!last, kernel_threads);
+
+        if (last) {
+                printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT),
+                                   path_get_file_name(last));
+
+                if (!p2) {
+                        p2 = strappend(prefix, "  ");
+                        if (!p2) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+                }
+
+                show_cgroup_by_path(last, p2, n_columns-2, kernel_threads, all);
+        }
+
+        r = 0;
+
+finish:
+        free(p1);
+        free(p2);
+        free(last);
+        free(fn);
+
+        closedir(d);
+
+        return r;
+}
+
+int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, bool all) {
+        char *p;
+        int r;
+
+        assert(controller);
+        assert(path);
+
+        r = cg_get_path(controller, path, NULL, &p);
+        if (r < 0)
+                return r;
+
+        r = show_cgroup_by_path(p, prefix, n_columns, kernel_threads, all);
+        free(p);
+
+        return r;
+}
+
+static int show_extra_pids(const char *controller, const char *path, const char *prefix, unsigned n_columns, const pid_t pids[], unsigned n_pids) {
+        pid_t *copy;
+        unsigned i, j;
+        int r;
+
+        assert(controller);
+        assert(path);
+
+        if (n_pids <= 0)
+                return 0;
+
+        if (n_columns <= 0)
+                n_columns = columns();
+
+        if (!prefix)
+                prefix = "";
+
+        copy = new(pid_t, n_pids);
+        if (!copy)
+                return -ENOMEM;
+
+        for (i = 0, j = 0; i < n_pids; i++) {
+                char *k;
+
+                r = cg_get_by_pid(controller, pids[i], &k);
+                if (r < 0) {
+                        free(copy);
+                        return r;
+                }
+
+                if (path_startswith(k, path))
+                        continue;
+
+                copy[j++] = pids[i];
+        }
+
+        show_pid_array(copy, j, prefix, n_columns, true, false, false);
+
+        free(copy);
+        return 0;
+}
+
+int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, bool all, const pid_t extra_pids[], unsigned n_extra_pids) {
+        int r;
+
+        assert(controller);
+        assert(path);
+
+        r = show_cgroup(controller, path, prefix, n_columns, kernel_threads, all);
+        if (r < 0)
+                return r;
+
+        return show_extra_pids(controller, path, prefix, n_columns, extra_pids, n_extra_pids);
+}
+
+int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, bool kernel_threads, bool all, const pid_t extra_pids[], unsigned n_extra_pids) {
+        int r;
+        _cleanup_free_ char *controller = NULL, *path = NULL;
+
+        assert(spec);
+
+        r = cg_split_spec(spec, &controller, &path);
+        if (r < 0)
+                return r;
+
+        return show_cgroup_and_extra(controller, path, prefix, n_columns, kernel_threads, all, extra_pids, n_extra_pids);
+}
diff --git a/src/shared/cgroup-show.h b/src/shared/cgroup-show.h
new file mode 100644 (file)
index 0000000..dba900a
--- /dev/null
@@ -0,0 +1,34 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foocgroupshowhfoo
+#define foocgroupshowhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+int show_cgroup_by_path(const char *path, const char *prefix, unsigned columns, bool kernel_threads, bool all);
+int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned columns, bool kernel_threads, bool all);
+
+int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, bool kernel_threads, bool all, const pid_t extra_pids[], unsigned n_extra_pids);
+int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, bool all, const pid_t extra_pids[], unsigned n_extra_pids);
+
+#endif
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
new file mode 100644 (file)
index 0000000..18cbf04
--- /dev/null
@@ -0,0 +1,1270 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <ftw.h>
+
+#include "cgroup-util.h"
+#include "log.h"
+#include "set.h"
+#include "macro.h"
+#include "util.h"
+#include "path-util.h"
+#include "strv.h"
+
+int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
+        char *fs;
+        int r;
+        FILE *f;
+
+        assert(path);
+        assert(_f);
+
+        r = cg_get_path(controller, path, "cgroup.procs", &fs);
+        if (r < 0)
+                return r;
+
+        f = fopen(fs, "re");
+        free(fs);
+
+        if (!f)
+                return -errno;
+
+        *_f = f;
+        return 0;
+}
+
+int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) {
+        char *fs;
+        int r;
+        FILE *f;
+
+        assert(path);
+        assert(_f);
+
+        r = cg_get_path(controller, path, "tasks", &fs);
+        if (r < 0)
+                return r;
+
+        f = fopen(fs, "re");
+        free(fs);
+
+        if (!f)
+                return -errno;
+
+        *_f = f;
+        return 0;
+}
+
+int cg_read_pid(FILE *f, pid_t *_pid) {
+        unsigned long ul;
+
+        /* Note that the cgroup.procs might contain duplicates! See
+         * cgroups.txt for details. */
+
+        errno = 0;
+        if (fscanf(f, "%lu", &ul) != 1) {
+
+                if (feof(f))
+                        return 0;
+
+                return errno ? -errno : -EIO;
+        }
+
+        if (ul <= 0)
+                return -EIO;
+
+        *_pid = (pid_t) ul;
+        return 1;
+}
+
+int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
+        char *fs;
+        int r;
+        DIR *d;
+
+        assert(path);
+        assert(_d);
+
+        /* This is not recursive! */
+
+        r = cg_get_path(controller, path, NULL, &fs);
+        if (r < 0)
+                return r;
+
+        d = opendir(fs);
+        free(fs);
+
+        if (!d)
+                return -errno;
+
+        *_d = d;
+        return 0;
+}
+
+int cg_read_subgroup(DIR *d, char **fn) {
+        struct dirent *de;
+
+        assert(d);
+
+        errno = 0;
+        while ((de = readdir(d))) {
+                char *b;
+
+                if (de->d_type != DT_DIR)
+                        continue;
+
+                if (streq(de->d_name, ".") ||
+                    streq(de->d_name, ".."))
+                        continue;
+
+                if (!(b = strdup(de->d_name)))
+                        return -ENOMEM;
+
+                *fn = b;
+                return 1;
+        }
+
+        if (errno)
+                return -errno;
+
+        return 0;
+}
+
+int cg_rmdir(const char *controller, const char *path, bool honour_sticky) {
+        char *p;
+        int r;
+
+        r = cg_get_path(controller, path, NULL, &p);
+        if (r < 0)
+                return r;
+
+        if (honour_sticky) {
+                char *tasks;
+
+                /* If the sticky bit is set don't remove the directory */
+
+                tasks = strappend(p, "/tasks");
+                if (!tasks) {
+                        free(p);
+                        return -ENOMEM;
+                }
+
+                r = file_is_priv_sticky(tasks);
+                free(tasks);
+
+                if (r > 0) {
+                        free(p);
+                        return 0;
+                }
+        }
+
+        r = rmdir(p);
+        free(p);
+
+        return (r < 0 && errno != ENOENT) ? -errno : 0;
+}
+
+int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
+        bool done = false;
+        int r, ret = 0;
+        pid_t my_pid;
+        FILE *f = NULL;
+        Set *allocated_set = NULL;
+
+        assert(controller);
+        assert(path);
+        assert(sig >= 0);
+
+        /* This goes through the tasks list and kills them all. This
+         * is repeated until no further processes are added to the
+         * tasks list, to properly handle forking processes */
+
+        if (!s)
+                if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
+                        return -ENOMEM;
+
+        my_pid = getpid();
+
+        do {
+                pid_t pid = 0;
+                done = true;
+
+                if ((r = cg_enumerate_processes(controller, path, &f)) < 0) {
+                        if (ret >= 0 && r != -ENOENT)
+                                ret = r;
+
+                        goto finish;
+                }
+
+                while ((r = cg_read_pid(f, &pid)) > 0) {
+
+                        if (pid == my_pid && ignore_self)
+                                continue;
+
+                        if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
+                                continue;
+
+                        /* If we haven't killed this process yet, kill
+                         * it */
+                        if (kill(pid, sig) < 0) {
+                                if (ret >= 0 && errno != ESRCH)
+                                        ret = -errno;
+                        } else if (ret == 0) {
+
+                                if (sigcont)
+                                        kill(pid, SIGCONT);
+
+                                ret = 1;
+                        }
+
+                        done = false;
+
+                        if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) {
+                                if (ret >= 0)
+                                        ret = r;
+
+                                goto finish;
+                        }
+                }
+
+                if (r < 0) {
+                        if (ret >= 0)
+                                ret = r;
+
+                        goto finish;
+                }
+
+                fclose(f);
+                f = NULL;
+
+                /* To avoid racing against processes which fork
+                 * quicker than we can kill them we repeat this until
+                 * no new pids need to be killed. */
+
+        } while (!done);
+
+finish:
+        if (allocated_set)
+                set_free(allocated_set);
+
+        if (f)
+                fclose(f);
+
+        return ret;
+}
+
+int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) {
+        int r, ret = 0;
+        DIR *d = NULL;
+        char *fn;
+        Set *allocated_set = NULL;
+
+        assert(path);
+        assert(controller);
+        assert(sig >= 0);
+
+        if (!s)
+                if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
+                        return -ENOMEM;
+
+        ret = cg_kill(controller, path, sig, sigcont, ignore_self, s);
+
+        if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) {
+                if (ret >= 0 && r != -ENOENT)
+                        ret = r;
+
+                goto finish;
+        }
+
+        while ((r = cg_read_subgroup(d, &fn)) > 0) {
+                char *p = NULL;
+
+                r = asprintf(&p, "%s/%s", path, fn);
+                free(fn);
+
+                if (r < 0) {
+                        if (ret >= 0)
+                                ret = -ENOMEM;
+
+                        goto finish;
+                }
+
+                r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s);
+                free(p);
+
+                if (r != 0 && ret >= 0)
+                        ret = r;
+        }
+
+        if (r < 0 && ret >= 0)
+                ret = r;
+
+        if (rem)
+                if ((r = cg_rmdir(controller, path, true)) < 0) {
+                        if (ret >= 0 &&
+                            r != -ENOENT &&
+                            r != -EBUSY)
+                                ret = r;
+                }
+
+finish:
+        if (d)
+                closedir(d);
+
+        if (allocated_set)
+                set_free(allocated_set);
+
+        return ret;
+}
+
+int cg_kill_recursive_and_wait(const char *controller, const char *path, bool rem) {
+        unsigned i;
+
+        assert(path);
+        assert(controller);
+
+        /* This safely kills all processes; first it sends a SIGTERM,
+         * then checks 8 times after 200ms whether the group is now
+         * empty, then kills everything that is left with SIGKILL and
+         * finally checks 5 times after 200ms each whether the group
+         * is finally empty. */
+
+        for (i = 0; i < 15; i++) {
+                int sig, r;
+
+                if (i <= 0)
+                        sig = SIGTERM;
+                else if (i == 9)
+                        sig = SIGKILL;
+                else
+                        sig = 0;
+
+                if ((r = cg_kill_recursive(controller, path, sig, true, true, rem, NULL)) <= 0)
+                        return r;
+
+                usleep(200 * USEC_PER_MSEC);
+        }
+
+        return 0;
+}
+
+int cg_migrate(const char *controller, const char *from, const char *to, bool ignore_self) {
+        bool done = false;
+        Set *s;
+        int r, ret = 0;
+        pid_t my_pid;
+        FILE *f = NULL;
+
+        assert(controller);
+        assert(from);
+        assert(to);
+
+        if (!(s = set_new(trivial_hash_func, trivial_compare_func)))
+                return -ENOMEM;
+
+        my_pid = getpid();
+
+        do {
+                pid_t pid = 0;
+                done = true;
+
+                if ((r = cg_enumerate_tasks(controller, from, &f)) < 0) {
+                        if (ret >= 0 && r != -ENOENT)
+                                ret = r;
+
+                        goto finish;
+                }
+
+                while ((r = cg_read_pid(f, &pid)) > 0) {
+
+                        /* This might do weird stuff if we aren't a
+                         * single-threaded program. However, we
+                         * luckily know we are not */
+                        if (pid == my_pid && ignore_self)
+                                continue;
+
+                        if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
+                                continue;
+
+                        if ((r = cg_attach(controller, to, pid)) < 0) {
+                                if (ret >= 0 && r != -ESRCH)
+                                        ret = r;
+                        } else if (ret == 0)
+                                ret = 1;
+
+                        done = false;
+
+                        if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) {
+                                if (ret >= 0)
+                                        ret = r;
+
+                                goto finish;
+                        }
+                }
+
+                if (r < 0) {
+                        if (ret >= 0)
+                                ret = r;
+
+                        goto finish;
+                }
+
+                fclose(f);
+                f = NULL;
+
+        } while (!done);
+
+finish:
+        set_free(s);
+
+        if (f)
+                fclose(f);
+
+        return ret;
+}
+
+int cg_migrate_recursive(const char *controller, const char *from, const char *to, bool ignore_self, bool rem) {
+        int r, ret = 0;
+        DIR *d = NULL;
+        char *fn;
+
+        assert(controller);
+        assert(from);
+        assert(to);
+
+        ret = cg_migrate(controller, from, to, ignore_self);
+
+        if ((r = cg_enumerate_subgroups(controller, from, &d)) < 0) {
+                if (ret >= 0 && r != -ENOENT)
+                        ret = r;
+                goto finish;
+        }
+
+        while ((r = cg_read_subgroup(d, &fn)) > 0) {
+                char *p = NULL;
+
+                r = asprintf(&p, "%s/%s", from, fn);
+                free(fn);
+
+                if (r < 0) {
+                        if (ret >= 0)
+                                ret = -ENOMEM;
+
+                        goto finish;
+                }
+
+                r = cg_migrate_recursive(controller, p, to, ignore_self, rem);
+                free(p);
+
+                if (r != 0 && ret >= 0)
+                        ret = r;
+        }
+
+        if (r < 0 && ret >= 0)
+                ret = r;
+
+        if (rem)
+                if ((r = cg_rmdir(controller, from, true)) < 0) {
+                        if (ret >= 0 &&
+                            r != -ENOENT &&
+                            r != -EBUSY)
+                                ret = r;
+                }
+
+finish:
+        if (d)
+                closedir(d);
+
+        return ret;
+}
+
+static const char *normalize_controller(const char *controller) {
+
+        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
+                return "systemd";
+        else if (startswith(controller, "name="))
+                return controller + 5;
+        else
+                return controller;
+}
+
+static int join_path(const char *controller, const char *path, const char *suffix, char **fs) {
+        char *t = NULL;
+
+        if (!(controller || path))
+                return -EINVAL;
+
+        if (controller) {
+                if (path && suffix)
+                        t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL);
+                else if (path)
+                        t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL);
+                else if (suffix)
+                        t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL);
+                else
+                        t = strjoin("/sys/fs/cgroup/", controller, NULL);
+        } else {
+                if (path && suffix)
+                        t = strjoin(path, "/", suffix, NULL);
+                else if (path)
+                        t = strdup(path);
+        }
+
+        if (!t)
+                return -ENOMEM;
+
+        path_kill_slashes(t);
+
+        *fs = t;
+        return 0;
+}
+
+int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
+        const char *p;
+        static __thread bool good = false;
+
+        assert(fs);
+
+        if (_unlikely_(!good)) {
+                int r;
+
+                r = path_is_mount_point("/sys/fs/cgroup", false);
+                if (r <= 0)
+                        return r < 0 ? r : -ENOENT;
+
+                /* Cache this to save a few stat()s */
+                good = true;
+        }
+
+        p = controller ? normalize_controller(controller) : NULL;
+        return join_path(p, path, suffix, fs);
+}
+
+static int check(const char *p) {
+        char *cc;
+
+        assert(p);
+
+        /* Check if this controller actually really exists */
+        cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p));
+        strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p);
+        if (access(cc, F_OK) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
+        const char *p;
+        int r;
+
+        assert(controller);
+        assert(fs);
+
+        if (isempty(controller))
+                return -EINVAL;
+
+        /* Normalize the controller syntax */
+        p = normalize_controller(controller);
+
+        /* Check if this controller actually really exists */
+        r = check(p);
+        if (r < 0)
+                return r;
+
+        return join_path(p, path, suffix, fs);
+}
+
+static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
+        char *p;
+        bool is_sticky;
+
+        if (typeflag != FTW_DP)
+                return 0;
+
+        if (ftwbuf->level < 1)
+                return 0;
+
+        p = strappend(path, "/tasks");
+        if (!p) {
+                errno = ENOMEM;
+                return 1;
+        }
+
+        is_sticky = file_is_priv_sticky(p) > 0;
+        free(p);
+
+        if (is_sticky)
+                return 0;
+
+        rmdir(path);
+        return 0;
+}
+
+int cg_trim(const char *controller, const char *path, bool delete_root) {
+        char *fs;
+        int r = 0;
+
+        assert(controller);
+        assert(path);
+
+        r = cg_get_path(controller, path, NULL, &fs);
+        if (r < 0)
+                return r;
+
+        errno = 0;
+        if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0)
+                r = errno ? -errno : -EIO;
+
+        if (delete_root) {
+                bool is_sticky;
+                char *p;
+
+                p = strappend(fs, "/tasks");
+                if (!p) {
+                        free(fs);
+                        return -ENOMEM;
+                }
+
+                is_sticky = file_is_priv_sticky(p) > 0;
+                free(p);
+
+                if (!is_sticky)
+                        if (rmdir(fs) < 0 && errno != ENOENT) {
+                                if (r == 0)
+                                        r = -errno;
+                        }
+        }
+
+        free(fs);
+
+        return r;
+}
+
+int cg_delete(const char *controller, const char *path) {
+        char *parent;
+        int r;
+
+        assert(controller);
+        assert(path);
+
+        if ((r = path_get_parent(path, &parent)) < 0)
+                return r;
+
+        r = cg_migrate_recursive(controller, path, parent, false, true);
+        free(parent);
+
+        return r == -ENOENT ? 0 : r;
+}
+
+int cg_attach(const char *controller, const char *path, pid_t pid) {
+        char *fs;
+        int r;
+        char c[32];
+
+        assert(controller);
+        assert(path);
+        assert(pid >= 0);
+
+        r = cg_get_path_and_check(controller, path, "tasks", &fs);
+        if (r < 0)
+                return r;
+
+        if (pid == 0)
+                pid = getpid();
+
+        snprintf(c, sizeof(c), "%lu\n", (unsigned long) pid);
+        char_array_0(c);
+
+        r = write_one_line_file(fs, c);
+        free(fs);
+
+        return r;
+}
+
+int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid) {
+        char *fs;
+        int r;
+
+        assert(controller);
+        assert(path);
+
+        if (mode != (mode_t) -1)
+                mode &= 0777;
+
+        r = cg_get_path(controller, path, NULL, &fs);
+        if (r < 0)
+                return r;
+
+        r = chmod_and_chown(fs, mode, uid, gid);
+        free(fs);
+
+        return r;
+}
+
+int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid, int sticky) {
+        char *fs;
+        int r;
+
+        assert(controller);
+        assert(path);
+
+        if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1 && sticky < 0)
+                return 0;
+
+        if (mode != (mode_t) -1)
+                mode &= 0666;
+
+        r = cg_get_path(controller, path, "tasks", &fs);
+        if (r < 0)
+                return r;
+
+        if (sticky >= 0 && mode != (mode_t) -1)
+                /* Both mode and sticky param are passed */
+                mode |= (sticky ? S_ISVTX : 0);
+        else if ((sticky >= 0 && mode == (mode_t) -1) ||
+                 (mode != (mode_t) -1 && sticky < 0)) {
+                struct stat st;
+
+                /* Only one param is passed, hence read the current
+                 * mode from the file itself */
+
+                r = lstat(fs, &st);
+                if (r < 0) {
+                        free(fs);
+                        return -errno;
+                }
+
+                if (mode == (mode_t) -1)
+                        /* No mode set, we just shall set the sticky bit */
+                        mode = (st.st_mode & ~S_ISVTX) | (sticky ? S_ISVTX : 0);
+                else
+                        /* Only mode set, leave sticky bit untouched */
+                        mode = (st.st_mode & ~0777) | mode;
+        }
+
+        r = chmod_and_chown(fs, mode, uid, gid);
+        free(fs);
+
+        return r;
+}
+
+int cg_get_by_pid(const char *controller, pid_t pid, char **path) {
+        int r;
+        char *p = NULL;
+        FILE *f;
+        char *fs;
+        size_t cs;
+
+        assert(controller);
+        assert(path);
+        assert(pid >= 0);
+
+        if (pid == 0)
+                pid = getpid();
+
+        if (asprintf(&fs, "/proc/%lu/cgroup", (unsigned long) pid) < 0)
+                return -ENOMEM;
+
+        f = fopen(fs, "re");
+        free(fs);
+
+        if (!f)
+                return errno == ENOENT ? -ESRCH : -errno;
+
+        cs = strlen(controller);
+
+        while (!feof(f)) {
+                char line[LINE_MAX];
+                char *l;
+
+                errno = 0;
+                if (!(fgets(line, sizeof(line), f))) {
+                        if (feof(f))
+                                break;
+
+                        r = errno ? -errno : -EIO;
+                        goto finish;
+                }
+
+                truncate_nl(line);
+
+                if (!(l = strchr(line, ':')))
+                        continue;
+
+                l++;
+                if (strncmp(l, controller, cs) != 0)
+                        continue;
+
+                if (l[cs] != ':')
+                        continue;
+
+                if (!(p = strdup(l + cs + 1))) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                *path = p;
+                r = 0;
+                goto finish;
+        }
+
+        r = -ENOENT;
+
+finish:
+        fclose(f);
+
+        return r;
+}
+
+int cg_install_release_agent(const char *controller, const char *agent) {
+        char *fs = NULL, *contents = NULL, *line = NULL, *sc;
+        int r;
+
+        assert(controller);
+        assert(agent);
+
+        if ((r = cg_get_path(controller, NULL, "release_agent", &fs)) < 0)
+                return r;
+
+        if ((r = read_one_line_file(fs, &contents)) < 0)
+                goto finish;
+
+        sc = strstrip(contents);
+        if (sc[0] == 0) {
+
+                if (asprintf(&line, "%s\n", agent) < 0) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if ((r = write_one_line_file(fs, line)) < 0)
+                        goto finish;
+
+        } else if (!streq(sc, agent)) {
+                r = -EEXIST;
+                goto finish;
+        }
+
+        free(fs);
+        fs = NULL;
+        if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0)
+                goto finish;
+
+        free(contents);
+        contents = NULL;
+        if ((r = read_one_line_file(fs, &contents)) < 0)
+                goto finish;
+
+        sc = strstrip(contents);
+
+        if (streq(sc, "0")) {
+                if ((r = write_one_line_file(fs, "1\n")) < 0)
+                        goto finish;
+
+                r = 1;
+        } else if (!streq(sc, "1")) {
+                r = -EIO;
+                goto finish;
+        } else
+                r = 0;
+
+finish:
+        free(fs);
+        free(contents);
+        free(line);
+
+        return r;
+}
+
+int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
+        pid_t pid = 0, self_pid;
+        int r;
+        FILE *f = NULL;
+        bool found = false;
+
+        assert(path);
+
+        r = cg_enumerate_tasks(controller, path, &f);
+        if (r < 0)
+                return r == -ENOENT ? 1 : r;
+
+        self_pid = getpid();
+
+        while ((r = cg_read_pid(f, &pid)) > 0) {
+
+                if (ignore_self && pid == self_pid)
+                        continue;
+
+                found = true;
+                break;
+        }
+
+        fclose(f);
+
+        if (r < 0)
+                return r;
+
+        return !found;
+}
+
+int cg_is_empty_by_spec(const char *spec, bool ignore_self) {
+        int r;
+        _cleanup_free_ char *controller = NULL, *path = NULL;
+
+        assert(spec);
+
+        r = cg_split_spec(spec, &controller, &path);
+        if (r < 0)
+                return r;
+
+        return cg_is_empty(controller, path, ignore_self);
+}
+
+
+int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) {
+        int r;
+        DIR *d = NULL;
+        char *fn;
+
+        assert(path);
+
+        r = cg_is_empty(controller, path, ignore_self);
+        if (r <= 0)
+                return r;
+
+        r = cg_enumerate_subgroups(controller, path, &d);
+        if (r < 0)
+                return r == -ENOENT ? 1 : r;
+
+        while ((r = cg_read_subgroup(d, &fn)) > 0) {
+                char *p = NULL;
+
+                r = asprintf(&p, "%s/%s", path, fn);
+                free(fn);
+
+                if (r < 0) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                r = cg_is_empty_recursive(controller, p, ignore_self);
+                free(p);
+
+                if (r <= 0)
+                        goto finish;
+        }
+
+        if (r >= 0)
+                r = 1;
+
+finish:
+
+        if (d)
+                closedir(d);
+
+        return r;
+}
+
+int cg_split_spec(const char *spec, char **controller, char **path) {
+        const char *e;
+        char *t = NULL, *u = NULL;
+
+        assert(spec);
+        assert(controller || path);
+
+        if (*spec == '/') {
+
+                if (path) {
+                        if (!(t = strdup(spec)))
+                                return -ENOMEM;
+
+                        *path = t;
+                }
+
+                if (controller)
+                        *controller = NULL;
+
+                return 0;
+        }
+
+        if (!(e = strchr(spec, ':'))) {
+
+                if (strchr(spec, '/') || spec[0] == 0)
+                        return -EINVAL;
+
+                if (controller) {
+                        if (!(t = strdup(spec)))
+                                return -ENOMEM;
+
+                        *controller = t;
+                }
+
+                if (path)
+                        *path = NULL;
+
+                return 0;
+        }
+
+        if (e[1] != '/' ||
+            e == spec ||
+            memchr(spec, '/', e-spec))
+                return -EINVAL;
+
+        if (controller)
+                if (!(t = strndup(spec, e-spec)))
+                        return -ENOMEM;
+
+        if (path)
+                if (!(u = strdup(e+1))) {
+                        free(t);
+                        return -ENOMEM;
+                }
+
+        if (controller)
+                *controller = t;
+
+        if (path)
+                *path = u;
+
+        return 0;
+}
+
+int cg_join_spec(const char *controller, const char *path, char **spec) {
+        assert(controller);
+        assert(path);
+
+        if (!path_is_absolute(path) ||
+            controller[0] == 0 ||
+            strchr(controller, ':') ||
+            strchr(controller, '/'))
+                return -EINVAL;
+
+        if (asprintf(spec, "%s:%s", controller, path) < 0)
+                return -ENOMEM;
+
+        return 0;
+}
+
+int cg_fix_path(const char *path, char **result) {
+        char *t, *c, *p;
+        int r;
+
+        assert(path);
+        assert(result);
+
+        /* First check if it already is a filesystem path */
+        if (path_startswith(path, "/sys/fs/cgroup") &&
+            access(path, F_OK) >= 0) {
+
+                t = strdup(path);
+                if (!t)
+                        return -ENOMEM;
+
+                *result = t;
+                return 0;
+        }
+
+        /* Otherwise treat it as cg spec */
+        r = cg_split_spec(path, &c, &p);
+        if (r < 0)
+                return r;
+
+        r = cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result);
+        free(c);
+        free(p);
+
+        return r;
+}
+
+int cg_get_user_path(char **path) {
+        char *root, *p;
+
+        assert(path);
+
+        /* Figure out the place to put user cgroups below. We use the
+         * same as PID 1 has but with the "/system" suffix replaced by
+         * "/user" */
+
+        if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root) < 0)
+                p = strdup("/user");
+        else {
+                if (endswith(root, "/system"))
+                        root[strlen(root) - 7] = 0;
+                else if (streq(root, "/"))
+                        root[0] = 0;
+
+                p = strappend(root, "/user");
+                free(root);
+        }
+
+        if (!p)
+                return -ENOMEM;
+
+        *path = p;
+        return 0;
+}
+
+char **cg_shorten_controllers(char **controllers) {
+        char **f, **t;
+
+        controllers = strv_uniq(controllers);
+
+        if (!controllers)
+                return controllers;
+
+        for (f = controllers, t = controllers; *f; f++) {
+                int r;
+                const char *p;
+
+                if (streq(*f, "systemd") || streq(*f, SYSTEMD_CGROUP_CONTROLLER)) {
+                        free(*f);
+                        continue;
+                }
+
+                p = normalize_controller(*f);
+
+                r = check(p);
+                if (r < 0) {
+                        log_debug("Controller %s is not available, removing from controllers list.", *f);
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return controllers;
+}
+
+int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) {
+        char *cg_process, *cg_init, *p;
+        int r;
+
+        assert(pid >= 0);
+
+        if (pid == 0)
+                pid = getpid();
+
+        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process);
+        if (r < 0)
+                return r;
+
+        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &cg_init);
+        if (r < 0) {
+                free(cg_process);
+                return r;
+        }
+
+        if (endswith(cg_init, "/system"))
+                cg_init[strlen(cg_init)-7] = 0;
+        else if (streq(cg_init, "/"))
+                cg_init[0] = 0;
+
+        if (startswith(cg_process, cg_init))
+                p = cg_process + strlen(cg_init);
+        else
+                p = cg_process;
+
+        free(cg_init);
+
+        if (cgroup) {
+                char* c;
+
+                c = strdup(p);
+                if (!c) {
+                        free(cg_process);
+                        return -ENOMEM;
+                }
+
+                *cgroup = c;
+        }
+
+        if (root) {
+                cg_process[p-cg_process] = 0;
+                *root = cg_process;
+        } else
+                free(cg_process);
+
+        return 0;
+}
+
+int cg_pid_get_unit(pid_t pid, char **unit) {
+        int r;
+        char *cgroup, *p, *at, *b;
+        size_t k;
+
+        assert(pid >= 0);
+        assert(unit);
+
+        r = cg_pid_get_cgroup(pid, NULL, &cgroup);
+        if (r < 0)
+                return r;
+
+        if (!startswith(cgroup, "/system/")) {
+                free(cgroup);
+                return -ENOENT;
+        }
+
+        p = cgroup + 8;
+        k = strcspn(p, "/");
+
+        at = memchr(p, '@', k);
+        if (at && at[1] == '.') {
+                size_t j;
+
+                /* This is a templated service */
+                if (p[k] != '/') {
+                        free(cgroup);
+                        return -EIO;
+                }
+
+                j = strcspn(p+k+1, "/");
+
+                b = malloc(k + j + 1);
+
+                if (b) {
+                        memcpy(b, p, at - p + 1);
+                        memcpy(b + (at - p) + 1, p + k + 1, j);
+                        memcpy(b + (at - p) + 1 + j, at + 1, k - (at - p) - 1);
+                        b[k+j] = 0;
+                }
+        } else
+                  b = strndup(p, k);
+
+        free(cgroup);
+
+        if (!b)
+                return -ENOMEM;
+
+        *unit = b;
+        return 0;
+
+}
diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h
new file mode 100644 (file)
index 0000000..af2efc3
--- /dev/null
@@ -0,0 +1,75 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <dirent.h>
+
+#include "set.h"
+#include "def.h"
+
+int cg_enumerate_processes(const char *controller, const char *path, FILE **_f);
+int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f);
+int cg_read_pid(FILE *f, pid_t *_pid);
+
+int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d);
+int cg_read_subgroup(DIR *d, char **fn);
+
+int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s);
+int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool remove, Set *s);
+int cg_kill_recursive_and_wait(const char *controller, const char *path, bool remove);
+
+int cg_migrate(const char *controller, const char *from, const char *to, bool ignore_self);
+int cg_migrate_recursive(const char *controller, const char *from, const char *to, bool ignore_self, bool remove);
+
+int cg_split_spec(const char *spec, char **controller, char **path);
+int cg_join_spec(const char *controller, const char *path, char **spec);
+int cg_fix_path(const char *path, char **result);
+
+int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs);
+int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs);
+int cg_get_by_pid(const char *controller, pid_t pid, char **path);
+
+int cg_trim(const char *controller, const char *path, bool delete_root);
+
+int cg_rmdir(const char *controller, const char *path, bool honour_sticky);
+int cg_delete(const char *controller, const char *path);
+
+int cg_create(const char *controller, const char *path);
+int cg_attach(const char *controller, const char *path, pid_t pid);
+int cg_create_and_attach(const char *controller, const char *path, pid_t pid);
+
+int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid);
+int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid, int sticky);
+
+int cg_install_release_agent(const char *controller, const char *agent);
+
+int cg_is_empty(const char *controller, const char *path, bool ignore_self);
+int cg_is_empty_by_spec(const char *spec, bool ignore_self);
+int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self);
+
+int cg_get_user_path(char **path);
+int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup);
+int cg_pid_get_unit(pid_t pid, char **unit);
+
+char **cg_shorten_controllers(char **controllers);
diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c
new file mode 100644 (file)
index 0000000..34b8629
--- /dev/null
@@ -0,0 +1,153 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include "macro.h"
+#include "util.h"
+#include "missing.h"
+#include "log.h"
+#include "strv.h"
+#include "path-util.h"
+#include "hashmap.h"
+#include "conf-files.h"
+
+static int files_add(Hashmap *h, const char *path, const char *suffix) {
+        DIR *dir;
+        int r = 0;
+
+        dir = opendir(path);
+        if (!dir) {
+                if (errno == ENOENT)
+                        return 0;
+                return -errno;
+        }
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                int k;
+                char *p;
+
+                k = readdir_r(dir, &buf.de, &de);
+                if (k != 0) {
+                        r = -k;
+                        goto finish;
+                }
+
+                if (!de)
+                        break;
+
+                if (!dirent_is_file_with_suffix(de, suffix))
+                        continue;
+
+                if (asprintf(&p, "%s/%s", path, de->d_name) < 0) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (hashmap_put(h, path_get_file_name(p), p) <= 0) {
+                        log_debug("Skip overridden file: %s.", p);
+                        free(p);
+                }
+        }
+
+finish:
+        closedir(dir);
+        return r;
+}
+
+static int base_cmp(const void *a, const void *b) {
+        const char *s1, *s2;
+
+        s1 = *(char * const *)a;
+        s2 = *(char * const *)b;
+        return strcmp(path_get_file_name(s1), path_get_file_name(s2));
+}
+
+int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) {
+        Hashmap *fh = NULL;
+        char **files = NULL;
+        const char **p;
+        int r;
+
+        assert(dirs);
+
+        fh = hashmap_new(string_hash_func, string_compare_func);
+        if (!fh) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        STRV_FOREACH(p, dirs) {
+                r = files_add(fh, *p, suffix);
+                if (r < 0)
+                        log_warning("Failed to search for files in %s: %s",
+                                    *p, strerror(-r));
+        }
+
+        files = hashmap_get_strv(fh);
+        if (files == NULL) {
+                log_error("Failed to compose list of files.");
+                r = -ENOMEM;
+                goto finish;
+        }
+        qsort(files, hashmap_size(fh), sizeof(char *), base_cmp);
+        r = 0;
+
+finish:
+        hashmap_free(fh);
+        *strv = files;
+        return r;
+}
+
+int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) {
+        char **dirs = NULL;
+        va_list ap;
+        int r;
+
+        va_start(ap, dir);
+        dirs = strv_new_ap(dir, ap);
+        va_end(ap);
+        if (!dirs) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (!path_strv_canonicalize(dirs)) {
+                r = -ENOMEM;
+                goto finish;
+        }
+        strv_uniq(dirs);
+
+        r = conf_files_list_strv(strv, suffix, (const char **)dirs);
+
+finish:
+        strv_free(dirs);
+        return r;
+}
diff --git a/src/shared/conf-files.h b/src/shared/conf-files.h
new file mode 100644 (file)
index 0000000..f37ee1f
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef fooconffileshfoo
+#define fooconffileshfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010-2012 Lennart Poettering
+  Copyright 2010-2012 Kay Sievers
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+
+int conf_files_list(char ***strv, const char *suffix, const char *dir, ...);
+int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs);
+
+#endif
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
new file mode 100644 (file)
index 0000000..9f5c07c
--- /dev/null
@@ -0,0 +1,1007 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "conf-parser.h"
+#include "util.h"
+#include "macro.h"
+#include "strv.h"
+#include "log.h"
+#include "utf8.h"
+#include "path-util.h"
+#include "set.h"
+#include "exit-status.h"
+
+int config_item_table_lookup(
+                void *table,
+                const char *section,
+                const char *lvalue,
+                ConfigParserCallback *func,
+                int *ltype,
+                void **data,
+                void *userdata) {
+
+        ConfigTableItem *t;
+
+        assert(table);
+        assert(lvalue);
+        assert(func);
+        assert(ltype);
+        assert(data);
+
+        for (t = table; t->lvalue; t++) {
+
+                if (!streq(lvalue, t->lvalue))
+                        continue;
+
+                if (!streq_ptr(section, t->section))
+                        continue;
+
+                *func = t->parse;
+                *ltype = t->ltype;
+                *data = t->data;
+                return 1;
+        }
+
+        return 0;
+}
+
+int config_item_perf_lookup(
+                void *table,
+                const char *section,
+                const char *lvalue,
+                ConfigParserCallback *func,
+                int *ltype,
+                void **data,
+                void *userdata) {
+
+        ConfigPerfItemLookup lookup = (ConfigPerfItemLookup) table;
+        const ConfigPerfItem *p;
+
+        assert(table);
+        assert(lvalue);
+        assert(func);
+        assert(ltype);
+        assert(data);
+
+        if (!section)
+                p = lookup(lvalue, strlen(lvalue));
+        else {
+                char *key;
+
+                key = strjoin(section, ".", lvalue, NULL);
+                if (!key)
+                        return -ENOMEM;
+
+                p = lookup(key, strlen(key));
+                free(key);
+        }
+
+        if (!p)
+                return 0;
+
+        *func = p->parse;
+        *ltype = p->ltype;
+        *data = (uint8_t*) userdata + p->offset;
+        return 1;
+}
+
+/* Run the user supplied parser for an assignment */
+static int next_assignment(
+                const char *filename,
+                unsigned line,
+                ConfigItemLookup lookup,
+                void *table,
+                const char *section,
+                const char *lvalue,
+                const char *rvalue,
+                bool relaxed,
+                void *userdata) {
+
+        ConfigParserCallback func = NULL;
+        int ltype = 0;
+        void *data = NULL;
+        int r;
+
+        assert(filename);
+        assert(line > 0);
+        assert(lookup);
+        assert(lvalue);
+        assert(rvalue);
+
+        r = lookup(table, section, lvalue, &func, &ltype, &data, userdata);
+        if (r < 0)
+                return r;
+
+        if (r > 0) {
+                if (func)
+                        return func(filename, line, section, lvalue, ltype, rvalue, data, userdata);
+
+                return 0;
+        }
+
+        /* Warn about unknown non-extension fields. */
+        if (!relaxed && !startswith(lvalue, "X-"))
+                log_info("[%s:%u] Unknown lvalue '%s' in section '%s'. Ignoring.", filename, line, lvalue, section);
+
+        return 0;
+}
+
+/* Parse a variable assignment line */
+static int parse_line(
+                const char *filename,
+                unsigned line,
+                const char *sections,
+                ConfigItemLookup lookup,
+                void *table,
+                bool relaxed,
+                char **section,
+                char *l,
+                void *userdata) {
+
+        char *e;
+
+        assert(filename);
+        assert(line > 0);
+        assert(lookup);
+        assert(l);
+
+        l = strstrip(l);
+
+        if (!*l)
+                return 0;
+
+        if (strchr(COMMENTS, *l))
+                return 0;
+
+        if (startswith(l, ".include ")) {
+                char *fn;
+                int r;
+
+                fn = file_in_same_dir(filename, strstrip(l+9));
+                if (!fn)
+                        return -ENOMEM;
+
+                r = config_parse(fn, NULL, sections, lookup, table, relaxed, userdata);
+                free(fn);
+
+                return r;
+        }
+
+        if (*l == '[') {
+                size_t k;
+                char *n;
+
+                k = strlen(l);
+                assert(k > 0);
+
+                if (l[k-1] != ']') {
+                        log_error("[%s:%u] Invalid section header.", filename, line);
+                        return -EBADMSG;
+                }
+
+                n = strndup(l+1, k-2);
+                if (!n)
+                        return -ENOMEM;
+
+                if (sections && !nulstr_contains(sections, n)) {
+
+                        if (!relaxed)
+                                log_info("[%s:%u] Unknown section '%s'. Ignoring.", filename, line, n);
+
+                        free(n);
+                        *section = NULL;
+                } else {
+                        free(*section);
+                        *section = n;
+                }
+
+                return 0;
+        }
+
+        if (sections && !*section) {
+
+                if (!relaxed)
+                        log_info("[%s:%u] Assignment outside of section. Ignoring.", filename, line);
+
+                return 0;
+        }
+
+        e = strchr(l, '=');
+        if (!e) {
+                log_error("[%s:%u] Missing '='.", filename, line);
+                return -EBADMSG;
+        }
+
+        *e = 0;
+        e++;
+
+        return next_assignment(
+                        filename,
+                        line,
+                        lookup,
+                        table,
+                        *section,
+                        strstrip(l),
+                        strstrip(e),
+                        relaxed,
+                        userdata);
+}
+
+/* Go through the file and parse each line */
+int config_parse(
+                const char *filename,
+                FILE *f,
+                const char *sections,
+                ConfigItemLookup lookup,
+                void *table,
+                bool relaxed,
+                void *userdata) {
+
+        unsigned line = 0;
+        char *section = NULL;
+        int r;
+        bool ours = false;
+        char *continuation = NULL;
+
+        assert(filename);
+        assert(lookup);
+
+        if (!f) {
+                f = fopen(filename, "re");
+                if (!f) {
+                        r = -errno;
+                        log_error("Failed to open configuration file '%s': %s", filename, strerror(-r));
+                        goto finish;
+                }
+
+                ours = true;
+        }
+
+        while (!feof(f)) {
+                char l[LINE_MAX], *p, *c = NULL, *e;
+                bool escaped = false;
+
+                if (!fgets(l, sizeof(l), f)) {
+                        if (feof(f))
+                                break;
+
+                        r = -errno;
+                        log_error("Failed to read configuration file '%s': %s", filename, strerror(-r));
+                        goto finish;
+                }
+
+                truncate_nl(l);
+
+                if (continuation) {
+                        c = strappend(continuation, l);
+                        if (!c) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        free(continuation);
+                        continuation = NULL;
+                        p = c;
+                } else
+                        p = l;
+
+                for (e = p; *e; e++) {
+                        if (escaped)
+                                escaped = false;
+                        else if (*e == '\\')
+                                escaped = true;
+                }
+
+                if (escaped) {
+                        *(e-1) = ' ';
+
+                        if (c)
+                                continuation = c;
+                        else {
+                                continuation = strdup(l);
+                                if (!continuation) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+                        }
+
+                        continue;
+                }
+
+                r = parse_line(filename,
+                                ++line,
+                                sections,
+                                lookup,
+                                table,
+                                relaxed,
+                                &section,
+                                p,
+                                userdata);
+                free(c);
+
+                if (r < 0)
+                        goto finish;
+        }
+
+        r = 0;
+
+finish:
+        free(section);
+        free(continuation);
+
+        if (f && ours)
+                fclose(f);
+
+        return r;
+}
+
+int config_parse_int(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        int *i = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if ((r = safe_atoi(rvalue, i)) < 0) {
+                log_error("[%s:%u] Failed to parse numeric value, ingoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_long(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        long *i = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if ((r = safe_atoli(rvalue, i)) < 0) {
+                log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_uint64(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        uint64_t *u = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if ((r = safe_atou64(rvalue, u)) < 0) {
+                log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_unsigned(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        unsigned *u = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if ((r = safe_atou(rvalue, u)) < 0) {
+                log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+                return r;
+        }
+
+        return 0;
+}
+
+int config_parse_bytes_size(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        size_t *sz = data;
+        off_t o;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (parse_bytes(rvalue, &o) < 0 || (off_t) (size_t) o != o) {
+                log_error("[%s:%u] Failed to parse byte value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *sz = (size_t) o;
+        return 0;
+}
+
+
+int config_parse_bytes_off(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        off_t *bytes = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        assert_cc(sizeof(off_t) == sizeof(uint64_t));
+
+        if (parse_bytes(rvalue, bytes) < 0) {
+                log_error("[%s:%u] Failed to parse bytes value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_bool(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        int k;
+        bool *b = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if ((k = parse_boolean(rvalue)) < 0) {
+                log_error("[%s:%u] Failed to parse boolean value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *b = !!k;
+        return 0;
+}
+
+int config_parse_tristate(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        int k;
+        int *b = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        /* Tristates are like booleans, but can also take the 'default' value, i.e. "-1" */
+
+        k = parse_boolean(rvalue);
+        if (k < 0) {
+                log_error("[%s:%u] Failed to parse boolean value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *b = !!k;
+        return 0;
+}
+
+int config_parse_string(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char **s = data;
+        char *n;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        n = strdup(rvalue);
+        if (!n)
+                return -ENOMEM;
+
+        if (!utf8_is_valid(n)) {
+                log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
+                free(n);
+                return 0;
+        }
+
+        free(*s);
+        if (*n)
+                *s = n;
+        else {
+                free(n);
+                *s = NULL;
+        }
+
+        return 0;
+}
+
+int config_parse_path(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char **s = data;
+        char *n;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (!utf8_is_valid(rvalue)) {
+                log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if (!path_is_absolute(rvalue)) {
+                log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        n = strdup(rvalue);
+        if (!n)
+                return -ENOMEM;
+
+        path_kill_slashes(n);
+
+        free(*s);
+        *s = n;
+
+        return 0;
+}
+
+int config_parse_strv(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char*** sv = data;
+        char **n;
+        char *w;
+        unsigned k;
+        size_t l;
+        char *state;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        k = strv_length(*sv);
+        FOREACH_WORD_QUOTED(w, l, rvalue, state)
+                k++;
+
+        n = new(char*, k+1);
+        if (!n)
+                return -ENOMEM;
+
+        if (*sv)
+                for (k = 0; (*sv)[k]; k++)
+                        n[k] = (*sv)[k];
+        else
+                k = 0;
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                n[k] = cunescape_length(w, l);
+                if (!n[k]) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                if (!utf8_is_valid(n[k])) {
+                        log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
+                        free(n[k]);
+                        continue;
+                }
+
+                k++;
+        }
+
+        n[k] = NULL;
+        free(*sv);
+        *sv = n;
+
+        return 0;
+
+fail:
+        for (; k > 0; k--)
+                free(n[k-1]);
+        free(n);
+
+        return r;
+}
+
+int config_parse_path_strv(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char*** sv = data;
+        char **n;
+        char *w;
+        unsigned k;
+        size_t l;
+        char *state;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        k = strv_length(*sv);
+        FOREACH_WORD_QUOTED(w, l, rvalue, state)
+                k++;
+
+        n = new(char*, k+1);
+        if (!n)
+                return -ENOMEM;
+
+        k = 0;
+        if (*sv)
+                for (; (*sv)[k]; k++)
+                        n[k] = (*sv)[k];
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                n[k] = strndup(w, l);
+                if (!n[k]) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                if (!utf8_is_valid(n[k])) {
+                        log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
+                        free(n[k]);
+                        continue;
+                }
+
+                if (!path_is_absolute(n[k])) {
+                        log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue);
+                        free(n[k]);
+                        continue;
+                }
+
+                path_kill_slashes(n[k]);
+                k++;
+        }
+
+        n[k] = NULL;
+        free(*sv);
+        *sv = n;
+
+        return 0;
+
+fail:
+        for (; k > 0; k--)
+                free(n[k-1]);
+        free(n);
+
+        return r;
+}
+
+int config_parse_usec(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        usec_t *usec = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (parse_usec(rvalue, usec) < 0) {
+                log_error("[%s:%u] Failed to parse time value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_nsec(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        nsec_t *nsec = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (parse_nsec(rvalue, nsec) < 0) {
+                log_error("[%s:%u] Failed to parse time value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+int config_parse_mode(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        mode_t *m = data;
+        long l;
+        char *x = NULL;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        errno = 0;
+        l = strtol(rvalue, &x, 8);
+        if (!x || x == rvalue || *x || errno) {
+                log_error("[%s:%u] Failed to parse mode value, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        if (l < 0000 || l > 07777) {
+                log_error("[%s:%u] mode value out of range, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *m = (mode_t) l;
+        return 0;
+}
+
+int config_parse_facility(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+
+        int *o = data, x;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        x = log_facility_unshifted_from_string(rvalue);
+        if (x < 0) {
+                log_error("[%s:%u] Failed to parse log facility, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *o = (x << 3) | LOG_PRI(*o);
+
+        return 0;
+}
+
+int config_parse_level(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+
+        int *o = data, x;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        x = log_level_from_string(rvalue);
+        if (x < 0) {
+                log_error("[%s:%u] Failed to parse log level, ignoring: %s", filename, line, rvalue);
+                return 0;
+        }
+
+        *o = (*o & LOG_FACMASK) | x;
+        return 0;
+}
+
+int config_parse_set_status(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char *w;
+        size_t l;
+        char *state;
+        int r;
+        ExitStatusSet *status_set = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        FOREACH_WORD(w, l, rvalue, state) {
+                int val;
+                char *temp;
+
+                temp = strndup(w, l);
+                if (!temp)
+                        return log_oom();
+
+                r = safe_atoi(temp, &val);
+                if (r < 0) {
+                        val = signal_from_string_try_harder(temp);
+                        free(temp);
+
+                        if (val > 0) {
+                                r = set_ensure_allocated(&status_set->signal, trivial_hash_func, trivial_compare_func);
+                                if (r < 0)
+                                        return log_oom();
+
+                                r = set_put(status_set->signal, INT_TO_PTR(val));
+                                if (r < 0) {
+                                        log_error("[%s:%u] Unable to store: %s", filename, line, w);
+                                        return r;
+                                }
+                        } else {
+                                log_error("[%s:%u] Failed to parse value, ignoring: %s", filename, line, w);
+                                return 0;
+                        }
+                } else {
+                        free(temp);
+
+                        if (val < 0 || val > 255)
+                                log_warning("[%s:%u] Value %d is outside range 0-255, ignoring", filename, line, val);
+                        else {
+                                r = set_ensure_allocated(&status_set->code, trivial_hash_func, trivial_compare_func);
+                                if (r < 0)
+                                        return log_oom();
+
+                                r = set_put(status_set->code, INT_TO_PTR(val));
+                                if (r < 0) {
+                                        log_error("[%s:%u] Unable to store: %s", filename, line, w);
+                                        return r;
+                                }
+                        }
+                }
+        }
+
+        return 0;
+}
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
new file mode 100644 (file)
index 0000000..56ffc2f
--- /dev/null
@@ -0,0 +1,136 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdbool.h>
+
+/* An abstract parser for simple, line based, shallow configuration
+ * files consisting of variable assignments only. */
+
+/* Prototype for a parser for a specific configuration setting */
+typedef int (*ConfigParserCallback)(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata);
+
+/* Wraps information for parsing a specific configuration variable, to
+ * be stored in a simple array */
+typedef struct ConfigTableItem {
+        const char *section;            /* Section */
+        const char *lvalue;             /* Name of the variable */
+        ConfigParserCallback parse;     /* Function that is called to parse the variable's value */
+        int ltype;                      /* Distinguish different variables passed to the same callback */
+        void *data;                     /* Where to store the variable's data */
+} ConfigTableItem;
+
+/* Wraps information for parsing a specific configuration variable, to
+ * ve srored in a gperf perfect hashtable */
+typedef struct ConfigPerfItem {
+        const char *section_and_lvalue; /* Section + "." + name of the variable */
+        ConfigParserCallback parse;     /* Function that is called to parse the variable's value */
+        int ltype;                      /* Distinguish different variables passed to the same callback */
+        size_t offset;                  /* Offset where to store data, from the beginning of userdata */
+} ConfigPerfItem;
+
+/* Prototype for a low-level gperf lookup function */
+typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lvalue, unsigned length);
+
+/* Prototype for a generic high-level lookup function */
+typedef int (*ConfigItemLookup)(
+                void *table,
+                const char *section,
+                const char *lvalue,
+                ConfigParserCallback *func,
+                int *ltype,
+                void **data,
+                void *userdata);
+
+/* Linear table search implementation of ConfigItemLookup, based on
+ * ConfigTableItem arrays */
+int config_item_table_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
+
+/* gperf implementation of ConfigItemLookup, based on gperf
+ * ConfigPerfItem tables */
+int config_item_perf_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
+
+int config_parse(
+                const char *filename,
+                FILE *f,
+                const char *sections,  /* nulstr */
+                ConfigItemLookup lookup,
+                void *table,
+                bool relaxed,
+                void *userdata);
+
+/* Generic parsers */
+int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_long(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_uint64(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bytes_size(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bytes_off(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_tristate(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_path(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_usec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_nsec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_facility(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_level(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_set_status(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg)                \
+        int function(                                                   \
+                        const char *filename,                           \
+                        unsigned line,                                  \
+                        const char *section,                            \
+                        const char *lvalue,                             \
+                        int ltype,                                      \
+                        const char *rvalue,                             \
+                        void *data,                                     \
+                        void *userdata) {                               \
+                                                                        \
+                type *i = data, x;                                      \
+                                                                        \
+                assert(filename);                                       \
+                assert(lvalue);                                         \
+                assert(rvalue);                                         \
+                assert(data);                                           \
+                                                                        \
+                if ((x = name##_from_string(rvalue)) < 0) {             \
+                        log_error("[%s:%u] " msg ", ignoring: %s", filename, line, rvalue); \
+                        return 0;                                       \
+                }                                                       \
+                                                                        \
+                *i = x;                                                 \
+                                                                        \
+                return 0;                                               \
+        }
diff --git a/src/shared/dbus-common.c b/src/shared/dbus-common.c
new file mode 100644 (file)
index 0000000..e9a78c2
--- /dev/null
@@ -0,0 +1,1335 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dbus/dbus.h>
+#include <string.h>
+#include <sys/epoll.h>
+
+#include "log.h"
+#include "dbus-common.h"
+#include "util.h"
+#include "missing.h"
+#include "def.h"
+#include "strv.h"
+
+int bus_check_peercred(DBusConnection *c) {
+        int fd;
+        struct ucred ucred;
+        socklen_t l;
+
+        assert(c);
+
+        assert_se(dbus_connection_get_unix_fd(c, &fd));
+
+        l = sizeof(struct ucred);
+        if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) {
+                log_error("SO_PEERCRED failed: %m");
+                return -errno;
+        }
+
+        if (l != sizeof(struct ucred)) {
+                log_error("SO_PEERCRED returned wrong size.");
+                return -E2BIG;
+        }
+
+        if (ucred.uid != 0 && ucred.uid != geteuid())
+                return -EPERM;
+
+        return 1;
+}
+
+static int sync_auth(DBusConnection *bus, DBusError *error) {
+        usec_t begin, tstamp;
+
+        assert(bus);
+
+        /* This complexity should probably move into D-Bus itself:
+         *
+         * https://bugs.freedesktop.org/show_bug.cgi?id=35189 */
+
+        begin = tstamp = now(CLOCK_MONOTONIC);
+        for (;;) {
+
+                if (tstamp > begin + DEFAULT_TIMEOUT_USEC)
+                        break;
+
+                if (dbus_connection_get_is_authenticated(bus))
+                        break;
+
+                if (!dbus_connection_read_write_dispatch(bus, ((begin + DEFAULT_TIMEOUT_USEC - tstamp) + USEC_PER_MSEC - 1) / USEC_PER_MSEC))
+                        break;
+
+                tstamp = now(CLOCK_MONOTONIC);
+        }
+
+        if (!dbus_connection_get_is_connected(bus)) {
+                dbus_set_error_const(error, DBUS_ERROR_NO_SERVER, "Connection terminated during authentication.");
+                return -ECONNREFUSED;
+        }
+
+        if (!dbus_connection_get_is_authenticated(bus)) {
+                dbus_set_error_const(error, DBUS_ERROR_TIMEOUT, "Failed to authenticate in time.");
+                return -EACCES;
+        }
+
+        return 0;
+}
+
+int bus_connect(DBusBusType t, DBusConnection **_bus, bool *_private, DBusError *error) {
+        DBusConnection *bus = NULL;
+        int r;
+        bool private = true;
+
+        assert(_bus);
+
+        if (geteuid() == 0 && t == DBUS_BUS_SYSTEM) {
+                /* If we are root, then let's talk directly to the
+                 * system instance, instead of going via the bus */
+
+                bus = dbus_connection_open_private("unix:path=/run/systemd/private", error);
+                if (!bus)
+                        return -EIO;
+
+        } else {
+                if (t == DBUS_BUS_SESSION) {
+                        const char *e;
+
+                        /* If we are supposed to talk to the instance,
+                         * try via XDG_RUNTIME_DIR first, then
+                         * fallback to normal bus access */
+
+                        e = secure_getenv("XDG_RUNTIME_DIR");
+                        if (e) {
+                                char *p;
+
+                                if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0)
+                                        return -ENOMEM;
+
+                                bus = dbus_connection_open_private(p, NULL);
+                                free(p);
+                        }
+                }
+
+                if (!bus) {
+                        bus = dbus_bus_get_private(t, error);
+                        if (!bus)
+                                return -EIO;
+
+                        private = false;
+                }
+        }
+
+        dbus_connection_set_exit_on_disconnect(bus, FALSE);
+
+        if (private) {
+                if (bus_check_peercred(bus) < 0) {
+                        dbus_connection_close(bus);
+                        dbus_connection_unref(bus);
+
+                        dbus_set_error_const(error, DBUS_ERROR_ACCESS_DENIED, "Failed to verify owner of bus.");
+                        return -EACCES;
+                }
+        }
+
+        r = sync_auth(bus, error);
+        if (r < 0) {
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+                return r;
+        }
+
+        if (_private)
+                *_private = private;
+
+        *_bus = bus;
+        return 0;
+}
+
+int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error) {
+        DBusConnection *bus;
+        char *p = NULL;
+        int r;
+
+        assert(_bus);
+        assert(user || host);
+
+        if (user && host)
+                asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s@%s,argv3=systemd-stdio-bridge", user, host);
+        else if (user)
+                asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s@localhost,argv3=systemd-stdio-bridge", user);
+        else if (host)
+                asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s,argv3=systemd-stdio-bridge", host);
+
+        if (!p) {
+                dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL);
+                return -ENOMEM;
+        }
+
+        bus = dbus_connection_open_private(p, error);
+        free(p);
+
+        if (!bus)
+                return -EIO;
+
+        dbus_connection_set_exit_on_disconnect(bus, FALSE);
+
+        if ((r = sync_auth(bus, error)) < 0) {
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+                return r;
+        }
+
+        if (!dbus_bus_register(bus, error)) {
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+                return r;
+        }
+
+        *_bus = bus;
+        return 0;
+}
+
+int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error) {
+        DBusConnection *bus;
+        int r;
+
+        assert(_bus);
+
+        /* Don't bother with PolicyKit if we are root */
+        if (geteuid() == 0)
+                return bus_connect(DBUS_BUS_SYSTEM, _bus, NULL, error);
+
+        bus = dbus_connection_open_private("unixexec:path=pkexec,argv1=" SYSTEMD_STDIO_BRIDGE_BINARY_PATH, error);
+        if (!bus)
+                return -EIO;
+
+        dbus_connection_set_exit_on_disconnect(bus, FALSE);
+
+        r = sync_auth(bus, error);
+        if (r < 0) {
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+                return r;
+        }
+
+        if (!dbus_bus_register(bus, error)) {
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+                return r;
+        }
+
+        *_bus = bus;
+        return 0;
+}
+
+const char *bus_error_message(const DBusError *error) {
+        if (!error)
+                return NULL;
+
+        /* Sometimes the D-Bus server is a little bit too verbose with
+         * its error messages, so let's override them here */
+        if (dbus_error_has_name(error, DBUS_ERROR_ACCESS_DENIED))
+                return "Access denied";
+
+        return error->message;
+}
+
+const char *bus_error_message_or_strerror(const DBusError *error, int err) {
+
+        if (error && dbus_error_is_set(error))
+                return bus_error_message(error);
+
+        return strerror(err);
+}
+
+DBusHandlerResult bus_default_message_handler(
+                DBusConnection *c,
+                DBusMessage *message,
+                const char *introspection,
+                const char *interfaces,
+                const BusBoundProperties *bound_properties) {
+
+        DBusError error;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        int r;
+
+        assert(c);
+        assert(message);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect") && introspection) {
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Get") && bound_properties) {
+                const char *interface, *property;
+                const BusBoundProperties *bp;
+                const BusProperty *p;
+                void *data;
+                DBusMessageIter iter, sub;
+
+                if (!dbus_message_get_args(
+                            message,
+                            &error,
+                            DBUS_TYPE_STRING, &interface,
+                            DBUS_TYPE_STRING, &property,
+                            DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(c, message, &error, -EINVAL);
+
+                for (bp = bound_properties; bp->interface; bp++) {
+                        if (!streq(bp->interface, interface))
+                                continue;
+
+                        for (p = bp->properties; p->property; p++)
+                                if (streq(p->property, property))
+                                        goto get_prop;
+                }
+
+                /* no match */
+                if (!nulstr_contains(interfaces, interface))
+                        dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface");
+                else
+                        dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property");
+
+                return bus_send_error_reply(c, message, &error, -EINVAL);
+
+get_prop:
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, p->signature, &sub))
+                        goto oom;
+
+                data = (char*)bp->base + p->offset;
+                if (p->indirect)
+                        data = *(void**)data;
+
+                r = p->append(&sub, property, data);
+                if (r == -ENOMEM)
+                        goto oom;
+                if (r < 0)
+                        return bus_send_error_reply(c, message, NULL, r);
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && bound_properties) {
+                const char *interface;
+                const BusBoundProperties *bp;
+                const BusProperty *p;
+                DBusMessageIter iter, sub, sub2, sub3;
+
+                if (!dbus_message_get_args(
+                            message,
+                            &error,
+                            DBUS_TYPE_STRING, &interface,
+                            DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(c, message, &error, -EINVAL);
+
+                if (interface[0] && !nulstr_contains(interfaces, interface)) {
+                        dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface");
+                        return bus_send_error_reply(c, message, &error, -EINVAL);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub))
+                        goto oom;
+
+                for (bp = bound_properties; bp->interface; bp++) {
+                        if (interface[0] && !streq(bp->interface, interface))
+                                continue;
+
+                        for (p = bp->properties; p->property; p++) {
+                                void *data;
+
+                                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &sub2) ||
+                                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &p->property) ||
+                                    !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, p->signature, &sub3))
+                                        goto oom;
+
+                                data = (char*)bp->base + p->offset;
+                                if (p->indirect)
+                                        data = *(void**)data;
+                                r = p->append(&sub3, p->property, data);
+                                if (r == -ENOMEM)
+                                        goto oom;
+                                if (r < 0)
+                                        return bus_send_error_reply(c, message, NULL, r);
+
+                                if (!dbus_message_iter_close_container(&sub2, &sub3) ||
+                                    !dbus_message_iter_close_container(&sub, &sub2))
+                                        goto oom;
+                        }
+                }
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set") && bound_properties) {
+                const char *interface, *property;
+                DBusMessageIter iter;
+                const BusBoundProperties *bp;
+                const BusProperty *p;
+                DBusMessageIter sub;
+                char *sig;
+                void *data;
+                DBusMessage *changed;
+
+                if (!dbus_message_iter_init(message, &iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                        return bus_send_error_reply(c, message, NULL, -EINVAL);
+
+                dbus_message_iter_get_basic(&iter, &interface);
+
+                if (!dbus_message_iter_next(&iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+                        return bus_send_error_reply(c, message, NULL, -EINVAL);
+
+                dbus_message_iter_get_basic(&iter, &property);
+
+                if (!dbus_message_iter_next(&iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT ||
+                    dbus_message_iter_has_next(&iter))
+                        return bus_send_error_reply(c, message, NULL, -EINVAL);
+
+                for (bp = bound_properties; bp->interface; bp++) {
+                        if (!streq(bp->interface, interface))
+                                continue;
+
+                        for (p = bp->properties; p->property; p++)
+                                if (streq(p->property, property))
+                                        goto set_prop;
+                }
+
+                /* no match */
+                if (!nulstr_contains(interfaces, interface))
+                        dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface");
+                else
+                        dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property");
+
+                return bus_send_error_reply(c, message, &error, -EINVAL);
+
+set_prop:
+                if (!p->set) {
+                        dbus_set_error_const(&error, DBUS_ERROR_PROPERTY_READ_ONLY, "Property read-only");
+                        return bus_send_error_reply(c, message, &error, -EINVAL);
+                }
+
+                dbus_message_iter_recurse(&iter, &sub);
+
+                sig = dbus_message_iter_get_signature(&sub);
+                if (!sig)
+                        goto oom;
+
+                if (!streq(sig, p->signature)) {
+                        dbus_free(sig);
+                        return bus_send_error_reply(c, message, NULL, -EINVAL);
+                }
+                dbus_free(sig);
+
+                data = (uint8_t*) bp->base + p->offset;
+                if (p->indirect)
+                        data = *(void**)data;
+
+                r = p->set(&sub, property, data);
+                if (r == -ENOMEM)
+                        goto oom;
+                else if (r < 0)
+                        return bus_send_error_reply(c, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                /* Send out a signal about this, but it doesn't really
+                 * matter if this fails, so eat all errors */
+                changed = bus_properties_changed_one_new(
+                                dbus_message_get_path(message),
+                                interface,
+                                property);
+                if (changed) {
+                        dbus_connection_send(c, changed, NULL);
+                        dbus_message_unref(changed);
+                }
+
+
+        } else {
+                const char *interface = dbus_message_get_interface(message);
+
+                if (!interface || !nulstr_contains(interfaces, interface)) {
+                        dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface");
+                        return bus_send_error_reply(c, message, &error, -EINVAL);
+                }
+        }
+
+        if (reply) {
+                if (!bus_maybe_send_reply(c, message, reply))
+                        goto oom;
+
+                return DBUS_HANDLER_RESULT_HANDLED;
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+oom:
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+int bus_property_append_string(DBusMessageIter *i, const char *property, void *data) {
+        const char *t = data;
+
+        assert(i);
+        assert(property);
+
+        if (!t)
+                t = "";
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data) {
+        char **t = data;
+
+        assert(i);
+        assert(property);
+
+        return bus_append_strv_iter(i, t);
+}
+
+int bus_property_append_bool(DBusMessageIter *i, const char *property, void *data) {
+        bool *b = data;
+        dbus_bool_t db;
+
+        assert(i);
+        assert(property);
+        assert(b);
+
+        db = *b;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_append_tristate_false(DBusMessageIter *i, const char *property, void *data) {
+        int *b = data;
+        dbus_bool_t db;
+
+        assert(i);
+        assert(property);
+        assert(b);
+
+        db = *b > 0;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_append_uint64(DBusMessageIter *i, const char *property, void *data) {
+        assert(i);
+        assert(property);
+        assert(data);
+
+        /* Let's ensure that usec_t is actually 64bit, and hence this
+         * function can be used for usec_t */
+        assert_cc(sizeof(uint64_t) == sizeof(usec_t));
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, data))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_append_uint32(DBusMessageIter *i, const char *property, void *data) {
+        assert(i);
+        assert(property);
+        assert(data);
+
+        /* Let's ensure that pid_t, mode_t, uid_t, gid_t are actually
+         * 32bit, and hence this function can be used for
+         * pid_t/mode_t/uid_t/gid_t */
+        assert_cc(sizeof(uint32_t) == sizeof(pid_t));
+        assert_cc(sizeof(uint32_t) == sizeof(mode_t));
+        assert_cc(sizeof(uint32_t) == sizeof(unsigned));
+        assert_cc(sizeof(uint32_t) == sizeof(uid_t));
+        assert_cc(sizeof(uint32_t) == sizeof(gid_t));
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, data))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_append_int32(DBusMessageIter *i, const char *property, void *data) {
+        assert(i);
+        assert(property);
+        assert(data);
+
+        assert_cc(sizeof(int32_t) == sizeof(int));
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, data))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_append_size(DBusMessageIter *i, const char *property, void *data) {
+        uint64_t u;
+
+        assert(i);
+        assert(property);
+        assert(data);
+
+        u = (uint64_t) *(size_t*) data;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_append_ul(DBusMessageIter *i, const char *property, void *data) {
+        uint64_t u;
+
+        assert(i);
+        assert(property);
+        assert(data);
+
+        u = (uint64_t) *(unsigned long*) data;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_append_long(DBusMessageIter *i, const char *property, void *data) {
+        int64_t l;
+
+        assert(i);
+        assert(property);
+        assert(data);
+
+        l = (int64_t) *(long*) data;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT64, &l))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_property_set_uint64(DBusMessageIter *i, const char *property, void *data) {
+        uint64_t *t = data;
+
+        assert(i);
+        assert(property);
+
+        dbus_message_iter_get_basic(i, t);
+        return 0;
+}
+
+const char *bus_errno_to_dbus(int error) {
+
+        switch(error) {
+
+        case -EINVAL:
+                return DBUS_ERROR_INVALID_ARGS;
+
+        case -ENOMEM:
+                return DBUS_ERROR_NO_MEMORY;
+
+        case -EPERM:
+        case -EACCES:
+                return DBUS_ERROR_ACCESS_DENIED;
+
+        case -ESRCH:
+                return DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN;
+
+        case -ENOENT:
+                return DBUS_ERROR_FILE_NOT_FOUND;
+
+        case -EEXIST:
+                return DBUS_ERROR_FILE_EXISTS;
+
+        case -ETIMEDOUT:
+        case -ETIME:
+                return DBUS_ERROR_TIMEOUT;
+
+        case -EIO:
+                return DBUS_ERROR_IO_ERROR;
+
+        case -ENETRESET:
+        case -ECONNABORTED:
+        case -ECONNRESET:
+                return DBUS_ERROR_DISCONNECTED;
+        }
+
+        return DBUS_ERROR_FAILED;
+}
+
+dbus_bool_t bus_maybe_send_reply (DBusConnection   *c,
+                                  DBusMessage *message,
+                                  DBusMessage *reply)
+{
+        if (dbus_message_get_no_reply (message))
+                return TRUE;
+        return dbus_connection_send (c, reply, NULL);
+}
+
+DBusHandlerResult bus_send_error_reply(DBusConnection *c, DBusMessage *message, DBusError *berror, int error) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        const char *name, *text;
+
+        if (berror && dbus_error_is_set(berror)) {
+                name = berror->name;
+                text = berror->message;
+        } else {
+                name = bus_errno_to_dbus(error);
+                text = strerror(-error);
+        }
+
+        reply = dbus_message_new_error(message, name, text);
+        if (!reply)
+                goto oom;
+
+        if (!bus_maybe_send_reply(c, message, reply))
+                goto oom;
+
+        if (berror)
+                dbus_error_free(berror);
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        if (berror)
+                dbus_error_free(berror);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties) {
+        DBusMessage *m;
+        DBusMessageIter iter, sub;
+        const char *i;
+
+        assert(interface);
+        assert(properties);
+
+        m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged");
+        if (!m)
+                goto oom;
+
+        dbus_message_iter_init_append(m, &iter);
+
+        /* We won't send any property values, since they might be
+         * large and sometimes not cheap to generated */
+
+        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) ||
+            !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub) ||
+            !dbus_message_iter_close_container(&iter, &sub) ||
+            !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub))
+                goto oom;
+
+        NULSTR_FOREACH(i, properties)
+                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &i))
+                        goto oom;
+
+        if (!dbus_message_iter_close_container(&iter, &sub))
+                goto oom;
+
+        return m;
+
+oom:
+        if (m)
+                dbus_message_unref(m);
+
+        return NULL;
+}
+
+DBusMessage* bus_properties_changed_one_new(const char *path, const char *interface, const char *property) {
+        DBusMessage *m;
+        DBusMessageIter iter, sub;
+
+        assert(interface);
+        assert(property);
+
+        m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged");
+        if (!m)
+                goto oom;
+
+        dbus_message_iter_init_append(m, &iter);
+
+        /* We won't send any property values, since they might be
+         * large and sometimes not cheap to generated */
+
+        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) ||
+            !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub) ||
+            !dbus_message_iter_close_container(&iter, &sub) ||
+            !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub))
+                goto oom;
+
+        if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &property))
+                goto oom;
+
+        if (!dbus_message_iter_close_container(&iter, &sub))
+                goto oom;
+
+        return m;
+
+oom:
+        if (m)
+                dbus_message_unref(m);
+
+        return NULL;
+}
+
+uint32_t bus_flags_to_events(DBusWatch *bus_watch) {
+        unsigned flags;
+        uint32_t events = 0;
+
+        assert(bus_watch);
+
+        /* no watch flags for disabled watches */
+        if (!dbus_watch_get_enabled(bus_watch))
+                return 0;
+
+        flags = dbus_watch_get_flags(bus_watch);
+
+        if (flags & DBUS_WATCH_READABLE)
+                events |= EPOLLIN;
+        if (flags & DBUS_WATCH_WRITABLE)
+                events |= EPOLLOUT;
+
+        return events | EPOLLHUP | EPOLLERR;
+}
+
+unsigned bus_events_to_flags(uint32_t events) {
+        unsigned flags = 0;
+
+        if (events & EPOLLIN)
+                flags |= DBUS_WATCH_READABLE;
+        if (events & EPOLLOUT)
+                flags |= DBUS_WATCH_WRITABLE;
+        if (events & EPOLLHUP)
+                flags |= DBUS_WATCH_HANGUP;
+        if (events & EPOLLERR)
+                flags |= DBUS_WATCH_ERROR;
+
+        return flags;
+}
+
+int bus_parse_strv(DBusMessage *m, char ***_l) {
+        DBusMessageIter iter;
+
+        assert(m);
+        assert(_l);
+
+        if (!dbus_message_iter_init(m, &iter))
+                return -EINVAL;
+
+        return bus_parse_strv_iter(&iter, _l);
+}
+
+int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l) {
+        DBusMessageIter sub;
+        unsigned n = 0, i = 0;
+        char **l;
+
+        assert(iter);
+        assert(_l);
+
+        if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(iter) != DBUS_TYPE_STRING)
+            return -EINVAL;
+
+        dbus_message_iter_recurse(iter, &sub);
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                n++;
+                dbus_message_iter_next(&sub);
+        }
+
+        l = new(char*, n+1);
+        if (!l)
+                return -ENOMEM;
+
+        dbus_message_iter_recurse(iter, &sub);
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *s;
+
+                assert_se(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
+                dbus_message_iter_get_basic(&sub, &s);
+
+                if (!(l[i++] = strdup(s))) {
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+
+                dbus_message_iter_next(&sub);
+        }
+
+        assert(i == n);
+        l[i] = NULL;
+
+        if (_l)
+                *_l = l;
+
+        return 0;
+}
+
+int bus_append_strv_iter(DBusMessageIter *iter, char **l) {
+        DBusMessageIter sub;
+
+        assert(iter);
+
+        if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "s", &sub))
+                return -ENOMEM;
+
+        STRV_FOREACH(l, l)
+                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, l))
+                        return -ENOMEM;
+
+        if (!dbus_message_iter_close_container(iter, &sub))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *data, bool next) {
+
+        assert(iter);
+        assert(data);
+
+        if (dbus_message_iter_get_arg_type(iter) != type)
+                return -EIO;
+
+        dbus_message_iter_get_basic(iter, data);
+
+        if (!dbus_message_iter_next(iter) != !next)
+                return -EIO;
+
+        return 0;
+}
+
+int generic_print_property(const char *name, DBusMessageIter *iter, bool all) {
+        assert(name);
+        assert(iter);
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRING: {
+                const char *s;
+                dbus_message_iter_get_basic(iter, &s);
+
+                if (all || !isempty(s))
+                        printf("%s=%s\n", name, s);
+
+                return 1;
+        }
+
+        case DBUS_TYPE_BOOLEAN: {
+                dbus_bool_t b;
+
+                dbus_message_iter_get_basic(iter, &b);
+                printf("%s=%s\n", name, yes_no(b));
+
+                return 1;
+        }
+
+        case DBUS_TYPE_UINT64: {
+                uint64_t u;
+                dbus_message_iter_get_basic(iter, &u);
+
+                /* Yes, heuristics! But we can change this check
+                 * should it turn out to not be sufficient */
+
+                if (endswith(name, "Timestamp")) {
+                        char timestamp[FORMAT_TIMESTAMP_MAX], *t;
+
+                        t = format_timestamp(timestamp, sizeof(timestamp), u);
+                        if (t || all)
+                                printf("%s=%s\n", name, strempty(t));
+
+                } else if (strstr(name, "USec")) {
+                        char timespan[FORMAT_TIMESPAN_MAX];
+
+                        printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u));
+                } else
+                        printf("%s=%llu\n", name, (unsigned long long) u);
+
+                return 1;
+        }
+
+        case DBUS_TYPE_UINT32: {
+                uint32_t u;
+                dbus_message_iter_get_basic(iter, &u);
+
+                if (strstr(name, "UMask") || strstr(name, "Mode"))
+                        printf("%s=%04o\n", name, u);
+                else
+                        printf("%s=%u\n", name, (unsigned) u);
+
+                return 1;
+        }
+
+        case DBUS_TYPE_INT32: {
+                int32_t i;
+                dbus_message_iter_get_basic(iter, &i);
+
+                printf("%s=%i\n", name, (int) i);
+                return 1;
+        }
+
+        case DBUS_TYPE_DOUBLE: {
+                double d;
+                dbus_message_iter_get_basic(iter, &d);
+
+                printf("%s=%g\n", name, d);
+                return 1;
+        }
+
+        case DBUS_TYPE_ARRAY:
+
+                if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) {
+                        DBusMessageIter sub;
+                        bool space = false;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        if (all ||
+                            dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                printf("%s=", name);
+
+                                while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                        const char *s;
+
+                                        assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
+                                        dbus_message_iter_get_basic(&sub, &s);
+                                        printf("%s%s", space ? " " : "", s);
+
+                                        space = true;
+                                        dbus_message_iter_next(&sub);
+                                }
+
+                                puts("");
+                        }
+
+                        return 1;
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_BYTE) {
+                        DBusMessageIter sub;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        if (all ||
+                            dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                printf("%s=", name);
+
+                                while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                        uint8_t u;
+
+                                        assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE);
+                                        dbus_message_iter_get_basic(&sub, &u);
+                                        printf("%02x", u);
+
+                                        dbus_message_iter_next(&sub);
+                                }
+
+                                puts("");
+                        }
+
+                        return 1;
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_UINT32) {
+                        DBusMessageIter sub;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        if (all ||
+                            dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                printf("%s=", name);
+
+                                while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                        uint32_t u;
+
+                                        assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32);
+                                        dbus_message_iter_get_basic(&sub, &u);
+                                        printf("%08x", u);
+
+                                        dbus_message_iter_next(&sub);
+                                }
+
+                                puts("");
+                        }
+
+                        return 1;
+                }
+
+                break;
+        }
+
+        return 0;
+}
+
+static void release_name_pending_cb(DBusPendingCall *pending, void *userdata) {
+        DBusMessage *reply;
+        DBusConnection *bus = userdata;
+
+        assert_se(reply = dbus_pending_call_steal_reply(pending));
+        dbus_message_unref(reply);
+
+        dbus_connection_close(bus);
+}
+
+void bus_async_unregister_and_exit(DBusConnection *bus, const char *name) {
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL;
+        DBusPendingCall *pending = NULL;
+
+        assert(bus);
+
+        /* We unregister the name here, but we continue to process
+         * requests, until we get the response for it, so that all
+         * requests are guaranteed to be processed. */
+
+        m = dbus_message_new_method_call(
+                        DBUS_SERVICE_DBUS,
+                        DBUS_PATH_DBUS,
+                        DBUS_INTERFACE_DBUS,
+                        "ReleaseName");
+        if (!m)
+                goto oom;
+
+        if (!dbus_message_append_args(
+                            m,
+                            DBUS_TYPE_STRING,
+                            &name,
+                            DBUS_TYPE_INVALID))
+                goto oom;
+
+        if (!dbus_connection_send_with_reply(bus, m, &pending, -1))
+                goto oom;
+
+        if (!dbus_pending_call_set_notify(pending, release_name_pending_cb, bus, NULL))
+                goto oom;
+
+        dbus_pending_call_unref(pending);
+
+        return;
+
+oom:
+        log_oom();
+
+        if (pending) {
+                dbus_pending_call_cancel(pending);
+                dbus_pending_call_unref(pending);
+        }
+}
+
+DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata) {
+        usec_t *remain_until = userdata;
+
+        assert(bus);
+        assert(m);
+        assert(remain_until);
+
+        /* Every time we get a new message we reset out timeout */
+        *remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
+
+        if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected"))
+                dbus_connection_close(bus);
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+/* This mimics dbus_bus_get_unix_user() */
+pid_t bus_get_unix_process_id(
+                DBusConnection *connection,
+                const char *name,
+                DBusError *error) {
+
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
+        uint32_t pid = 0;
+
+        m = dbus_message_new_method_call(
+                        DBUS_SERVICE_DBUS,
+                        DBUS_PATH_DBUS,
+                        DBUS_INTERFACE_DBUS,
+                        "GetConnectionUnixProcessID");
+        if (!m) {
+                dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL);
+                return 0;
+        }
+
+        if (!dbus_message_append_args(
+                            m,
+                            DBUS_TYPE_STRING, &name,
+                            DBUS_TYPE_INVALID)) {
+                dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL);
+                return 0;
+        }
+
+        reply = dbus_connection_send_with_reply_and_block(connection, m, -1, error);
+        if (!reply)
+                return 0;
+
+        if (dbus_set_error_from_message(error, reply))
+                return 0;
+
+        if (!dbus_message_get_args(
+                            reply, error,
+                            DBUS_TYPE_UINT32, &pid,
+                            DBUS_TYPE_INVALID))
+                return 0;
+
+        return (pid_t) pid;
+}
+
+bool bus_error_is_no_service(const DBusError *error) {
+        assert(error);
+
+        if (!dbus_error_is_set(error))
+                return false;
+
+        if (dbus_error_has_name(error, DBUS_ERROR_NAME_HAS_NO_OWNER))
+                return true;
+
+        if (dbus_error_has_name(error, DBUS_ERROR_SERVICE_UNKNOWN))
+                return true;
+
+        return startswith(error->name, "org.freedesktop.DBus.Error.Spawn.");
+}
+
+int bus_method_call_with_reply(
+                DBusConnection *bus,
+                const char *destination,
+                const char *path,
+                const char *interface,
+                const char *method,
+                DBusMessage **return_reply,
+                DBusError *return_error,
+                int first_arg_type, ...) {
+
+        DBusError error;
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL;
+        DBusMessage *reply;
+        va_list ap;
+        int r = 0;
+
+        dbus_error_init(&error);
+        assert(bus);
+
+        m = dbus_message_new_method_call(destination, path, interface, method);
+        if (!m) {
+                r = log_oom();
+                goto finish;
+        }
+
+        va_start(ap, first_arg_type);
+        if (!dbus_message_append_args_valist(m, first_arg_type, ap)) {
+                va_end(ap);
+                r = log_oom();
+                goto finish;
+        }
+        va_end(ap);
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+        if (!reply) {
+                if (!return_error)
+                        log_error("Failed to issue method call: %s", bus_error_message(&error));
+
+                if (bus_error_is_no_service(&error))
+                        r = -ENOENT;
+                else if (dbus_error_has_name(&error, DBUS_ERROR_ACCESS_DENIED))
+                        r = -EACCES;
+                else if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY))
+                        r = -ETIMEDOUT;
+                else
+                        r = -EIO;
+                goto finish;
+        }
+
+        if (return_reply)
+                *return_reply = reply;
+        else
+                dbus_message_unref(reply);
+
+finish:
+        if (return_error)
+                *return_error = error;
+        else
+                dbus_error_free(&error);
+
+        return r;
+}
+
+void bus_message_unrefp(DBusMessage **reply) {
+        if (!reply)
+                return;
+
+        if (!*reply)
+                return;
+
+        dbus_message_unref(*reply);
+}
+
+const char *bus_message_get_sender_with_fallback(DBusMessage *m) {
+        const char *s;
+
+        assert(m);
+
+        s = dbus_message_get_sender(m);
+        if (s)
+                return s;
+
+        /* When the message came in from a direct connection the
+         * message will have no sender. We fix that here. */
+
+        return ":no-sender";
+}
diff --git a/src/shared/dbus-common.h b/src/shared/dbus-common.h
new file mode 100644 (file)
index 0000000..bcbf18f
--- /dev/null
@@ -0,0 +1,228 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+#include <inttypes.h>
+#include <sys/types.h>
+
+#ifndef DBUS_ERROR_UNKNOWN_OBJECT
+#define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject"
+#endif
+
+#ifndef DBUS_ERROR_UNKNOWN_INTERFACE
+#define DBUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface"
+#endif
+
+#ifndef DBUS_ERROR_UNKNOWN_PROPERTY
+#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty"
+#endif
+
+#ifndef DBUS_ERROR_PROPERTY_READ_ONLY
+#define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly"
+#endif
+
+#define BUS_PROPERTIES_INTERFACE                                        \
+        " <interface name=\"org.freedesktop.DBus.Properties\">\n"       \
+        "  <method name=\"Get\">\n"                                     \
+        "   <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"    \
+        "   <arg name=\"property\" direction=\"in\" type=\"s\"/>\n"     \
+        "   <arg name=\"value\" direction=\"out\" type=\"v\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"GetAll\">\n"                                  \
+        "   <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"    \
+        "   <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"Set\">\n"                                     \
+        "   <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"    \
+        "   <arg name=\"property\" direction=\"in\" type=\"s\"/>\n"     \
+        "   <arg name=\"value\" direction=\"in\" type=\"v\"/>\n"        \
+        "  </method>\n"                                                 \
+        "  <signal name=\"PropertiesChanged\">\n"                       \
+        "   <arg type=\"s\" name=\"interface\"/>\n"                     \
+        "   <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"        \
+        "   <arg type=\"as\" name=\"invalidated_properties\"/>\n"       \
+        "  </signal>\n"                                                 \
+        " </interface>\n"
+
+#define BUS_INTROSPECTABLE_INTERFACE                                    \
+        " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"   \
+        "  <method name=\"Introspect\">\n"                              \
+        "   <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"        \
+        "  </method>\n"                                                 \
+        " </interface>\n"
+
+#define BUS_PEER_INTERFACE                                              \
+        "<interface name=\"org.freedesktop.DBus.Peer\">\n"              \
+        " <method name=\"Ping\"/>\n"                                    \
+        " <method name=\"GetMachineId\">\n"                             \
+        "  <arg type=\"s\" name=\"machine_uuid\" direction=\"out\"/>\n" \
+        " </method>\n"                                                  \
+        "</interface>\n"
+
+#define BUS_GENERIC_INTERFACES_LIST             \
+        "org.freedesktop.DBus.Properties\0"     \
+        "org.freedesktop.DBus.Introspectable\0" \
+        "org.freedesktop.DBus.Peer\0"
+
+int bus_check_peercred(DBusConnection *c);
+
+int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private_bus, DBusError *error);
+
+int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error);
+int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error);
+
+const char *bus_error_message(const DBusError *error);
+const char *bus_error_message_or_strerror(const DBusError *error, int err);
+
+typedef int (*BusPropertyCallback)(DBusMessageIter *iter, const char *property, void *data);
+typedef int (*BusPropertySetCallback)(DBusMessageIter *iter, const char *property, void *data);
+
+typedef struct BusProperty {
+        const char *property;            /* name of the property */
+        BusPropertyCallback append;      /* Function that is called to serialize this property */
+        const char *signature;
+        const uint16_t offset;           /* Offset from BusBoundProperties::base address to the property data.
+                                          * uint16_t is sufficient, because we have no structs too big.
+                                          * -Werror=overflow will catch it if this does not hold. */
+        bool indirect;                   /* data is indirect, ie. not base+offset, but *(base+offset) */
+        BusPropertySetCallback set;      /* Optional: Function that is called to set this property */
+} BusProperty;
+
+typedef struct BusBoundProperties {
+        const char *interface;           /* interface of the properties */
+        const BusProperty *properties;   /* array of properties, ended by a NULL-filled element */
+        const void *const base;          /* base pointer to which the offset must be added to reach data */
+} BusBoundProperties;
+
+dbus_bool_t bus_maybe_send_reply (DBusConnection   *c,
+                                  DBusMessage *message,
+                                  DBusMessage *reply);
+
+DBusHandlerResult bus_send_error_reply(
+                DBusConnection *c,
+                DBusMessage *message,
+                DBusError *bus_error,
+                int error);
+
+DBusHandlerResult bus_default_message_handler(
+                DBusConnection *c,
+                DBusMessage *message,
+                const char *introspection,
+                const char *interfaces,
+                const BusBoundProperties *bound_properties);
+
+int bus_property_append_string(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_bool(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_tristate_false(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_int32(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_uint32(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_uint64(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_size(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_ul(DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_long(DBusMessageIter *i, const char *property, void *data);
+
+#define bus_property_append_int bus_property_append_int32
+#define bus_property_append_pid bus_property_append_uint32
+#define bus_property_append_uid bus_property_append_uint32
+#define bus_property_append_gid bus_property_append_uint32
+#define bus_property_append_mode bus_property_append_uint32
+#define bus_property_append_unsigned bus_property_append_uint32
+#define bus_property_append_usec bus_property_append_uint64
+
+int bus_property_set_uint64(DBusMessageIter *i, const char *property, void *data);
+#define bus_property_set_usec bus_property_set_uint64
+
+#define DEFINE_BUS_PROPERTY_APPEND_ENUM(function,name,type)             \
+        int function(DBusMessageIter *i, const char *property, void *data) { \
+                const char *value;                                      \
+                type *field = data;                                     \
+                                                                        \
+                assert(i);                                              \
+                assert(property);                                       \
+                                                                        \
+                value = strempty(name##_to_string(*field));             \
+                                                                        \
+                if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &value)) \
+                        return -ENOMEM;                                 \
+                                                                        \
+                return 0;                                               \
+        }
+
+#define DEFINE_BUS_PROPERTY_SET_ENUM(function,name,type)                \
+        int function(DBusMessageIter *i, const char *property, void *data) { \
+                const char *value;                                      \
+                type f, *field = data;                                  \
+                                                                        \
+                assert(i);                                              \
+                assert(property);                                       \
+                                                                        \
+                dbus_message_iter_get_basic(i, &value);                 \
+                                                                        \
+                f = name##_from_string(value);                          \
+                if (f < 0)                                              \
+                        return f;                                       \
+                                                                        \
+                *field = f;                                             \
+                return 0;                                               \
+        }
+
+const char *bus_errno_to_dbus(int error);
+
+DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties);
+DBusMessage* bus_properties_changed_one_new(const char *path, const char *interface, const char *property);
+
+uint32_t bus_flags_to_events(DBusWatch *bus_watch);
+unsigned bus_events_to_flags(uint32_t events);
+
+int bus_parse_strv(DBusMessage *m, char ***_l);
+int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l);
+
+int bus_append_strv_iter(DBusMessageIter *iter, char **l);
+
+int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *data, bool next);
+
+int generic_print_property(const char *name, DBusMessageIter *iter, bool all);
+
+void bus_async_unregister_and_exit(DBusConnection *bus, const char *name);
+
+DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata);
+
+pid_t bus_get_unix_process_id(DBusConnection *connection, const char *name, DBusError *error);
+
+bool bus_error_is_no_service(const DBusError *error);
+int bus_method_call_with_reply(DBusConnection *bus,
+                               const char *destination,
+                               const char *path,
+                               const char *interface,
+                               const char *method,
+                               DBusMessage **return_reply,
+                               DBusError *return_error,
+                               int first_arg_type, ...);
+
+const char *bus_message_get_sender_with_fallback(DBusMessage *m);
+
+void bus_message_unrefp(DBusMessage **reply);
+
+#define _cleanup_dbus_message_unref_ __attribute__((cleanup(bus_message_unrefp)))
+#define _cleanup_dbus_error_free_ __attribute__((cleanup(dbus_error_free)))
diff --git a/src/shared/dbus-loop.c b/src/shared/dbus-loop.c
new file mode 100644 (file)
index 0000000..da0a004
--- /dev/null
@@ -0,0 +1,263 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <assert.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+
+#include "dbus-loop.h"
+#include "dbus-common.h"
+#include "util.h"
+
+/* Minimal implementation of the dbus loop which integrates all dbus
+ * events into a single epoll fd which we can triviall integrate with
+ * other loops. Note that this is not used in the main systemd daemon
+ * since we run a more elaborate mainloop there. */
+
+typedef struct EpollData {
+        int fd;
+        void *object;
+        bool is_timeout:1;
+        bool fd_is_dupped:1;
+} EpollData;
+
+static dbus_bool_t add_watch(DBusWatch *watch, void *data) {
+        EpollData *e;
+        struct epoll_event ev;
+
+        assert(watch);
+
+        e = new0(EpollData, 1);
+        if (!e)
+                return FALSE;
+
+        e->fd = dbus_watch_get_unix_fd(watch);
+        e->object = watch;
+        e->is_timeout = false;
+
+        zero(ev);
+        ev.events = bus_flags_to_events(watch);
+        ev.data.ptr = e;
+
+        if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) {
+
+                if (errno != EEXIST) {
+                        free(e);
+                        return FALSE;
+                }
+
+                /* Hmm, bloody D-Bus creates multiple watches on the
+                 * same fd. epoll() does not like that. As a dirty
+                 * hack we simply dup() the fd and hence get a second
+                 * one we can safely add to the epoll(). */
+
+                e->fd = dup(e->fd);
+                if (e->fd < 0) {
+                        free(e);
+                        return FALSE;
+                }
+
+                if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) {
+                        close_nointr_nofail(e->fd);
+                        free(e);
+                        return FALSE;
+                }
+
+                e->fd_is_dupped = true;
+        }
+
+        dbus_watch_set_data(watch, e, NULL);
+
+        return TRUE;
+}
+
+static void remove_watch(DBusWatch *watch, void *data) {
+        EpollData *e;
+
+        assert(watch);
+
+        e = dbus_watch_get_data(watch);
+        if (!e)
+                return;
+
+        assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_DEL, e->fd, NULL) >= 0);
+
+        if (e->fd_is_dupped)
+                close_nointr_nofail(e->fd);
+
+        free(e);
+}
+
+static void toggle_watch(DBusWatch *watch, void *data) {
+        EpollData *e;
+        struct epoll_event ev;
+
+        assert(watch);
+
+        e = dbus_watch_get_data(watch);
+        if (!e)
+                return;
+
+        zero(ev);
+        ev.events = bus_flags_to_events(watch);
+        ev.data.ptr = e;
+
+        assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_MOD, e->fd, &ev) == 0);
+}
+
+static int timeout_arm(EpollData *e) {
+        struct itimerspec its;
+
+        assert(e);
+        assert(e->is_timeout);
+
+        zero(its);
+
+        if (dbus_timeout_get_enabled(e->object)) {
+                timespec_store(&its.it_value, dbus_timeout_get_interval(e->object) * USEC_PER_MSEC);
+                its.it_interval = its.it_value;
+        }
+
+        if (timerfd_settime(e->fd, 0, &its, NULL) < 0)
+                return -errno;
+
+        return 0;
+}
+
+static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) {
+        EpollData *e;
+        struct epoll_event ev;
+
+        assert(timeout);
+
+        e = new0(EpollData, 1);
+        if (!e)
+                return FALSE;
+
+        e->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
+        if (e->fd < 0)
+                goto fail;
+
+        e->object = timeout;
+        e->is_timeout = true;
+
+        if (timeout_arm(e) < 0)
+                goto fail;
+
+        zero(ev);
+        ev.events = EPOLLIN;
+        ev.data.ptr = e;
+
+        if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0)
+                goto fail;
+
+        dbus_timeout_set_data(timeout, e, NULL);
+
+        return TRUE;
+
+fail:
+        if (e->fd >= 0)
+                close_nointr_nofail(e->fd);
+
+        free(e);
+        return FALSE;
+}
+
+static void remove_timeout(DBusTimeout *timeout, void *data) {
+        EpollData *e;
+
+        assert(timeout);
+
+        e = dbus_timeout_get_data(timeout);
+        if (!e)
+                return;
+
+        assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_DEL, e->fd, NULL) >= 0);
+        close_nointr_nofail(e->fd);
+        free(e);
+}
+
+static void toggle_timeout(DBusTimeout *timeout, void *data) {
+        EpollData *e;
+        int r;
+
+        assert(timeout);
+
+        e = dbus_timeout_get_data(timeout);
+        if (!e)
+                return;
+
+        r = timeout_arm(e);
+        if (r < 0)
+                log_error("Failed to rearm timer: %s", strerror(-r));
+}
+
+int bus_loop_open(DBusConnection *c) {
+        int fd;
+
+        assert(c);
+
+        fd = epoll_create1(EPOLL_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        if (!dbus_connection_set_watch_functions(c, add_watch, remove_watch, toggle_watch, INT_TO_PTR(fd), NULL) ||
+            !dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, toggle_timeout, INT_TO_PTR(fd), NULL)) {
+                close_nointr_nofail(fd);
+                return -ENOMEM;
+        }
+
+        return fd;
+}
+
+int bus_loop_dispatch(int fd) {
+        int n;
+        struct epoll_event event;
+        EpollData *d;
+
+        assert(fd >= 0);
+
+        zero(event);
+
+        n = epoll_wait(fd, &event, 1, 0);
+        if (n < 0)
+                return errno == EAGAIN || errno == EINTR ? 0 : -errno;
+
+        assert_se(d = event.data.ptr);
+
+        if (d->is_timeout) {
+                DBusTimeout *t = d->object;
+
+                if (dbus_timeout_get_enabled(t))
+                        dbus_timeout_handle(t);
+        } else {
+                DBusWatch *w = d->object;
+
+                if (dbus_watch_get_enabled(w))
+                        dbus_watch_handle(w, bus_events_to_flags(event.events));
+        }
+
+        return 0;
+}
diff --git a/src/shared/dbus-loop.h b/src/shared/dbus-loop.h
new file mode 100644 (file)
index 0000000..a5e768d
--- /dev/null
@@ -0,0 +1,27 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+int bus_loop_open(DBusConnection *c);
+int bus_loop_dispatch(int fd);
diff --git a/src/shared/def.h b/src/shared/def.h
new file mode 100644 (file)
index 0000000..5ba170f
--- /dev/null
@@ -0,0 +1,35 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+
+#define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC)
+#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
+#define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC)
+
+#define DEFAULT_EXIT_USEC (5*USEC_PER_MINUTE)
+
+#define SYSTEMD_CGROUP_CONTROLLER "name=systemd"
+
+#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
+#define SIGNALS_IGNORE SIGKILL,SIGPIPE
diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c
new file mode 100644 (file)
index 0000000..b0ac02d
--- /dev/null
@@ -0,0 +1,78 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010-2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include "dev-setup.h"
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+#include "label.h"
+
+static int symlink_and_label(const char *old_path, const char *new_path) {
+        int r;
+
+        assert(old_path);
+        assert(new_path);
+
+        r = label_context_set(new_path, S_IFLNK);
+        if (r < 0)
+                return r;
+
+        if (symlink(old_path, new_path) < 0)
+                r = -errno;
+
+        label_context_clear();
+
+        return r;
+}
+
+void dev_setup(const char *prefix) {
+        const char *j, *k;
+
+        static const char symlinks[] =
+                "/proc/kcore\0"      "/dev/core\0"
+                "/proc/self/fd\0"    "/dev/fd\0"
+                "/proc/self/fd/0\0"  "/dev/stdin\0"
+                "/proc/self/fd/1\0"  "/dev/stdout\0"
+                "/proc/self/fd/2\0"  "/dev/stderr\0";
+
+        NULSTR_FOREACH_PAIR(j, k, symlinks) {
+
+                if (prefix) {
+                        char *linkname;
+
+                        if (asprintf(&linkname, "%s/%s", prefix, k) < 0) {
+                                log_oom();
+                                break;
+                        }
+
+                        symlink_and_label(j, linkname);
+                        free(linkname);
+                } else
+                        symlink_and_label(j, k);
+        }
+}
diff --git a/src/shared/dev-setup.h b/src/shared/dev-setup.h
new file mode 100644 (file)
index 0000000..320c0b3
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010-2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+void dev_setup(const char *pathprefix);
diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c
new file mode 100644 (file)
index 0000000..45131f2
--- /dev/null
@@ -0,0 +1,192 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <sys/wait.h>
+
+#include "exit-status.h"
+#include "set.h"
+#include "macro.h"
+
+const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
+
+        /* We cast to int here, so that -Wenum doesn't complain that
+         * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */
+
+        switch ((int) status) {
+
+        case EXIT_SUCCESS:
+                return "SUCCESS";
+
+        case EXIT_FAILURE:
+                return "FAILURE";
+        }
+
+
+        if (level == EXIT_STATUS_SYSTEMD || level == EXIT_STATUS_LSB) {
+                switch ((int) status) {
+
+                case EXIT_CHDIR:
+                        return "CHDIR";
+
+                case EXIT_NICE:
+                        return "NICE";
+
+                case EXIT_FDS:
+                        return "FDS";
+
+                case EXIT_EXEC:
+                        return "EXEC";
+
+                case EXIT_MEMORY:
+                        return "MEMORY";
+
+                case EXIT_LIMITS:
+                        return "LIMITS";
+
+                case EXIT_OOM_ADJUST:
+                        return "OOM_ADJUST";
+
+                case EXIT_SIGNAL_MASK:
+                        return "SIGNAL_MASK";
+
+                case EXIT_STDIN:
+                        return "STDIN";
+
+                case EXIT_STDOUT:
+                        return "STDOUT";
+
+                case EXIT_CHROOT:
+                        return "CHROOT";
+
+                case EXIT_IOPRIO:
+                        return "IOPRIO";
+
+                case EXIT_TIMERSLACK:
+                        return "TIMERSLACK";
+
+                case EXIT_SECUREBITS:
+                        return "SECUREBITS";
+
+                case EXIT_SETSCHEDULER:
+                        return "SETSCHEDULER";
+
+                case EXIT_CPUAFFINITY:
+                        return "CPUAFFINITY";
+
+                case EXIT_GROUP:
+                        return "GROUP";
+
+                case EXIT_USER:
+                        return "USER";
+
+                case EXIT_CAPABILITIES:
+                        return "CAPABILITIES";
+
+                case EXIT_CGROUP:
+                        return "CGROUP";
+
+                case EXIT_SETSID:
+                        return "SETSID";
+
+                case EXIT_CONFIRM:
+                        return "CONFIRM";
+
+                case EXIT_STDERR:
+                        return "STDERR";
+
+                case EXIT_TCPWRAP:
+                        return "TCPWRAP";
+
+                case EXIT_PAM:
+                        return "PAM";
+
+                case EXIT_NETWORK:
+                        return "NETWORK";
+
+                case EXIT_NAMESPACE:
+                        return "NAMESPACE";
+
+                case EXIT_NO_NEW_PRIVILEGES:
+                        return "NO_NEW_PRIVILEGES";
+
+                case EXIT_SECCOMP:
+                        return "SECCOMP";
+                }
+        }
+
+        if (level == EXIT_STATUS_LSB) {
+                switch ((int) status) {
+
+                case EXIT_INVALIDARGUMENT:
+                        return "INVALIDARGUMENT";
+
+                case EXIT_NOTIMPLEMENTED:
+                        return "NOTIMPLEMENTED";
+
+                case EXIT_NOPERMISSION:
+                        return "NOPERMISSION";
+
+                case EXIT_NOTINSTALLED:
+                        return "NOTINSSTALLED";
+
+                case EXIT_NOTCONFIGURED:
+                        return "NOTCONFIGURED";
+
+                case EXIT_NOTRUNNING:
+                        return "NOTRUNNING";
+                }
+        }
+
+        return NULL;
+}
+
+
+bool is_clean_exit(int code, int status, ExitStatusSet *success_status) {
+
+        if (code == CLD_EXITED)
+                return status == 0 ||
+                       (success_status &&
+                       set_contains(success_status->code, INT_TO_PTR(status)));
+
+        /* If a daemon does not implement handlers for some of the
+         * signals that's not considered an unclean shutdown */
+        if (code == CLD_KILLED)
+                return
+                        status == SIGHUP ||
+                        status == SIGINT ||
+                        status == SIGTERM ||
+                        status == SIGPIPE ||
+                        (success_status &&
+                        set_contains(success_status->signal, INT_TO_PTR(status)));
+
+        return false;
+}
+
+bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status) {
+
+        if (is_clean_exit(code, status, success_status))
+                return true;
+
+        return
+                code == CLD_EXITED &&
+                (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED);
+}
diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h
new file mode 100644 (file)
index 0000000..d3b548f
--- /dev/null
@@ -0,0 +1,88 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include "set.h"
+typedef enum ExitStatus {
+        /* EXIT_SUCCESS defined by libc */
+        /* EXIT_FAILURE defined by libc */
+        EXIT_INVALIDARGUMENT = 2,
+        EXIT_NOTIMPLEMENTED = 3,
+        EXIT_NOPERMISSION = 4,
+        EXIT_NOTINSTALLED = 5,
+        EXIT_NOTCONFIGURED = 6,
+        EXIT_NOTRUNNING = 7,
+
+        /* The LSB suggests that error codes >= 200 are "reserved". We
+         * use them here under the assumption that they hence are
+         * unused by init scripts.
+         *
+         * http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html */
+
+        EXIT_CHDIR = 200,
+        EXIT_NICE,
+        EXIT_FDS,
+        EXIT_EXEC,
+        EXIT_MEMORY,
+        EXIT_LIMITS,
+        EXIT_OOM_ADJUST,
+        EXIT_SIGNAL_MASK,
+        EXIT_STDIN,
+        EXIT_STDOUT,
+        EXIT_CHROOT,   /* 210 */
+        EXIT_IOPRIO,
+        EXIT_TIMERSLACK,
+        EXIT_SECUREBITS,
+        EXIT_SETSCHEDULER,
+        EXIT_CPUAFFINITY,
+        EXIT_GROUP,
+        EXIT_USER,
+        EXIT_CAPABILITIES,
+        EXIT_CGROUP,
+        EXIT_SETSID,   /* 220 */
+        EXIT_CONFIRM,
+        EXIT_STDERR,
+        EXIT_TCPWRAP,
+        EXIT_PAM,
+        EXIT_NETWORK,
+        EXIT_NAMESPACE,
+        EXIT_NO_NEW_PRIVILEGES,
+        EXIT_SECCOMP
+} ExitStatus;
+
+typedef enum ExitStatusLevel {
+        EXIT_STATUS_MINIMAL,
+        EXIT_STATUS_SYSTEMD,
+        EXIT_STATUS_LSB,
+        EXIT_STATUS_FULL = EXIT_STATUS_LSB
+} ExitStatusLevel;
+
+typedef struct ExitStatusSet {
+        Set *code;
+        Set *signal;
+} ExitStatusSet;
+
+const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level);
+
+bool is_clean_exit(int code, int status, ExitStatusSet *success_status);
+bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status);
diff --git a/src/shared/fdset.c b/src/shared/fdset.c
new file mode 100644 (file)
index 0000000..fd27398
--- /dev/null
@@ -0,0 +1,236 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "set.h"
+#include "util.h"
+#include "macro.h"
+#include "fdset.h"
+#include "sd-daemon.h"
+
+#define MAKE_SET(s) ((Set*) s)
+#define MAKE_FDSET(s) ((FDSet*) s)
+
+/* Make sure we can distuingish fd 0 and NULL */
+#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1)
+#define PTR_TO_FD(p) (PTR_TO_INT(p)-1)
+
+FDSet *fdset_new(void) {
+        return MAKE_FDSET(set_new(trivial_hash_func, trivial_compare_func));
+}
+
+void fdset_free(FDSet *s) {
+        void *p;
+
+        while ((p = set_steal_first(MAKE_SET(s)))) {
+                /* Valgrind's fd might have ended up in this set here,
+                 * due to fdset_new_fill(). We'll ignore all failures
+                 * here, so that the EBADFD that valgrind will return
+                 * us on close() doesn't influence us */
+
+                /* When reloading duplicates of the private bus
+                 * connection fds and suchlike are closed here, which
+                 * has no effect at all, since they are only
+                 * duplicates. So don't be surprised about these log
+                 * messages. */
+
+                log_debug("Closing left-over fd %i", PTR_TO_FD(p));
+                close_nointr(PTR_TO_FD(p));
+        }
+
+        set_free(MAKE_SET(s));
+}
+
+int fdset_put(FDSet *s, int fd) {
+        assert(s);
+        assert(fd >= 0);
+
+        return set_put(MAKE_SET(s), FD_TO_PTR(fd));
+}
+
+int fdset_put_dup(FDSet *s, int fd) {
+        int copy, r;
+
+        assert(s);
+        assert(fd >= 0);
+
+        copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+        if (copy < 0)
+                return -errno;
+
+        r = fdset_put(s, copy);
+        if (r < 0) {
+                close_nointr_nofail(copy);
+                return r;
+        }
+
+        return copy;
+}
+
+bool fdset_contains(FDSet *s, int fd) {
+        assert(s);
+        assert(fd >= 0);
+
+        return !!set_get(MAKE_SET(s), FD_TO_PTR(fd));
+}
+
+int fdset_remove(FDSet *s, int fd) {
+        assert(s);
+        assert(fd >= 0);
+
+        return set_remove(MAKE_SET(s), FD_TO_PTR(fd)) ? fd : -ENOENT;
+}
+
+int fdset_new_fill(FDSet **_s) {
+        DIR *d;
+        struct dirent *de;
+        int r = 0;
+        FDSet *s;
+
+        assert(_s);
+
+        /* Creates an fdset and fills in all currently open file
+         * descriptors. */
+
+        d = opendir("/proc/self/fd");
+        if (!d)
+                return -errno;
+
+        s = fdset_new();
+        if (!s) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        while ((de = readdir(d))) {
+                int fd = -1;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                r = safe_atoi(de->d_name, &fd);
+                if (r < 0)
+                        goto finish;
+
+                if (fd < 3)
+                        continue;
+
+                if (fd == dirfd(d))
+                        continue;
+
+                r = fdset_put(s, fd);
+                if (r < 0)
+                        goto finish;
+        }
+
+        r = 0;
+        *_s = s;
+        s = NULL;
+
+finish:
+        closedir(d);
+
+        /* We won't close the fds here! */
+        if (s)
+                set_free(MAKE_SET(s));
+
+        return r;
+}
+
+int fdset_cloexec(FDSet *fds, bool b) {
+        Iterator i;
+        void *p;
+        int r;
+
+        assert(fds);
+
+        SET_FOREACH(p, MAKE_SET(fds), i)
+                if ((r = fd_cloexec(PTR_TO_FD(p), b)) < 0)
+                        return r;
+
+        return 0;
+}
+
+int fdset_new_listen_fds(FDSet **_s, bool unset) {
+        int n, fd, r;
+        FDSet *s;
+
+        assert(_s);
+
+        /* Creates an fdset and fills in all passed file descriptors */
+
+        s = fdset_new();
+        if (!s) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        n = sd_listen_fds(unset);
+        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
+                r = fdset_put(s, fd);
+                if (r < 0)
+                        goto fail;
+        }
+
+        *_s = s;
+        return 0;
+
+
+fail:
+        if (s)
+                set_free(MAKE_SET(s));
+
+        return r;
+}
+
+int fdset_close_others(FDSet *fds) {
+        void *e;
+        Iterator i;
+        int *a;
+        unsigned j, m;
+
+        j = 0, m = fdset_size(fds);
+        a = alloca(sizeof(int) * m);
+        SET_FOREACH(e, MAKE_SET(fds), i)
+                a[j++] = PTR_TO_FD(e);
+
+        assert(j == m);
+
+        return close_all_fds(a, j);
+}
+
+unsigned fdset_size(FDSet *fds) {
+        return set_size(MAKE_SET(fds));
+}
+
+int fdset_iterate(FDSet *s, Iterator *i) {
+        void *p;
+
+        p = set_iterate(MAKE_SET(s), i);
+        if (!p)
+                return -ENOENT;
+
+        return PTR_TO_FD(p);
+}
diff --git a/src/shared/fdset.h b/src/shared/fdset.h
new file mode 100644 (file)
index 0000000..a7bd5e2
--- /dev/null
@@ -0,0 +1,49 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "set.h"
+
+typedef struct FDSet FDSet;
+
+FDSet* fdset_new(void);
+void fdset_free(FDSet *s);
+
+int fdset_put(FDSet *s, int fd);
+int fdset_put_dup(FDSet *s, int fd);
+
+bool fdset_contains(FDSet *s, int fd);
+int fdset_remove(FDSet *s, int fd);
+
+int fdset_new_fill(FDSet **_s);
+int fdset_new_listen_fds(FDSet **_s, bool unset);
+
+int fdset_cloexec(FDSet *fds, bool b);
+
+int fdset_close_others(FDSet *fds);
+
+unsigned fdset_size(FDSet *fds);
+
+int fdset_iterate(FDSet *s, Iterator *i);
+
+#define FDSET_FOREACH(fd, fds, i) \
+        for ((i) = ITERATOR_FIRST, (fd) = fdset_iterate((fds), &(i)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i)))
diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c
new file mode 100644 (file)
index 0000000..a2c728d
--- /dev/null
@@ -0,0 +1,835 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "util.h"
+#include "hashmap.h"
+#include "macro.h"
+
+#define NBUCKETS 127
+
+struct hashmap_entry {
+        const void *key;
+        void *value;
+        struct hashmap_entry *bucket_next, *bucket_previous;
+        struct hashmap_entry *iterate_next, *iterate_previous;
+};
+
+struct Hashmap {
+        hash_func_t hash_func;
+        compare_func_t compare_func;
+
+        struct hashmap_entry *iterate_list_head, *iterate_list_tail;
+        unsigned n_entries;
+
+        bool from_pool;
+};
+
+#define BY_HASH(h) ((struct hashmap_entry**) ((uint8_t*) (h) + ALIGN(sizeof(Hashmap))))
+
+struct pool {
+        struct pool *next;
+        unsigned n_tiles;
+        unsigned n_used;
+};
+
+static struct pool *first_hashmap_pool = NULL;
+static void *first_hashmap_tile = NULL;
+
+static struct pool *first_entry_pool = NULL;
+static void *first_entry_tile = NULL;
+
+static void* allocate_tile(struct pool **first_pool, void **first_tile, size_t tile_size) {
+        unsigned i;
+
+        if (*first_tile) {
+                void *r;
+
+                r = *first_tile;
+                *first_tile = * (void**) (*first_tile);
+                return r;
+        }
+
+        if (_unlikely_(!*first_pool) || _unlikely_((*first_pool)->n_used >= (*first_pool)->n_tiles)) {
+                unsigned n;
+                size_t size;
+                struct pool *p;
+
+                n = *first_pool ? (*first_pool)->n_tiles : 0;
+                n = MAX(512U, n * 2);
+                size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*tile_size);
+                n = (size - ALIGN(sizeof(struct pool))) / tile_size;
+
+                p = malloc(size);
+                if (!p)
+                        return NULL;
+
+                p->next = *first_pool;
+                p->n_tiles = n;
+                p->n_used = 0;
+
+                *first_pool = p;
+        }
+
+        i = (*first_pool)->n_used++;
+
+        return ((uint8_t*) (*first_pool)) + ALIGN(sizeof(struct pool)) + i*tile_size;
+}
+
+static void deallocate_tile(void **first_tile, void *p) {
+        * (void**) p = *first_tile;
+        *first_tile = p;
+}
+
+#ifdef VALGRIND
+
+static void drop_pool(struct pool *p) {
+        while (p) {
+                struct pool *n;
+                n = p->next;
+                free(p);
+                p = n;
+        }
+}
+
+__attribute__((destructor)) static void cleanup_pool(void) {
+        /* Be nice to valgrind */
+
+        drop_pool(first_hashmap_pool);
+        drop_pool(first_entry_pool);
+}
+
+#endif
+
+unsigned string_hash_func(const void *p) {
+        unsigned hash = 5381;
+        const signed char *c;
+
+        /* DJB's hash function */
+
+        for (c = p; *c; c++)
+                hash = (hash << 5) + hash + (unsigned) *c;
+
+        return hash;
+}
+
+int string_compare_func(const void *a, const void *b) {
+        return strcmp(a, b);
+}
+
+unsigned trivial_hash_func(const void *p) {
+        return PTR_TO_UINT(p);
+}
+
+int trivial_compare_func(const void *a, const void *b) {
+        return a < b ? -1 : (a > b ? 1 : 0);
+}
+
+unsigned uint64_hash_func(const void *p) {
+        uint64_t u;
+
+        assert_cc(sizeof(uint64_t) == 2*sizeof(unsigned));
+
+        u = *(const uint64_t*) p;
+
+        return (unsigned) ((u >> 32) ^ u);
+}
+
+int uint64_compare_func(const void *_a, const void *_b) {
+        uint64_t a, b;
+
+        a = *(const uint64_t*) _a;
+        b = *(const uint64_t*) _b;
+
+        return a < b ? -1 : (a > b ? 1 : 0);
+}
+
+Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) {
+        bool b;
+        Hashmap *h;
+        size_t size;
+
+        b = is_main_thread();
+
+        size = ALIGN(sizeof(Hashmap)) + NBUCKETS * sizeof(struct hashmap_entry*);
+
+        if (b) {
+                h = allocate_tile(&first_hashmap_pool, &first_hashmap_tile, size);
+                if (!h)
+                        return NULL;
+
+                memset(h, 0, size);
+        } else {
+                h = malloc0(size);
+
+                if (!h)
+                        return NULL;
+        }
+
+        h->hash_func = hash_func ? hash_func : trivial_hash_func;
+        h->compare_func = compare_func ? compare_func : trivial_compare_func;
+
+        h->n_entries = 0;
+        h->iterate_list_head = h->iterate_list_tail = NULL;
+
+        h->from_pool = b;
+
+        return h;
+}
+
+int hashmap_ensure_allocated(Hashmap **h, hash_func_t hash_func, compare_func_t compare_func) {
+        assert(h);
+
+        if (*h)
+                return 0;
+
+        if (!(*h = hashmap_new(hash_func, compare_func)))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static void link_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) {
+        assert(h);
+        assert(e);
+
+        /* Insert into hash table */
+        e->bucket_next = BY_HASH(h)[hash];
+        e->bucket_previous = NULL;
+        if (BY_HASH(h)[hash])
+                BY_HASH(h)[hash]->bucket_previous = e;
+        BY_HASH(h)[hash] = e;
+
+        /* Insert into iteration list */
+        e->iterate_previous = h->iterate_list_tail;
+        e->iterate_next = NULL;
+        if (h->iterate_list_tail) {
+                assert(h->iterate_list_head);
+                h->iterate_list_tail->iterate_next = e;
+        } else {
+                assert(!h->iterate_list_head);
+                h->iterate_list_head = e;
+        }
+        h->iterate_list_tail = e;
+
+        h->n_entries++;
+        assert(h->n_entries >= 1);
+}
+
+static void unlink_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) {
+        assert(h);
+        assert(e);
+
+        /* Remove from iteration list */
+        if (e->iterate_next)
+                e->iterate_next->iterate_previous = e->iterate_previous;
+        else
+                h->iterate_list_tail = e->iterate_previous;
+
+        if (e->iterate_previous)
+                e->iterate_previous->iterate_next = e->iterate_next;
+        else
+                h->iterate_list_head = e->iterate_next;
+
+        /* Remove from hash table bucket list */
+        if (e->bucket_next)
+                e->bucket_next->bucket_previous = e->bucket_previous;
+
+        if (e->bucket_previous)
+                e->bucket_previous->bucket_next = e->bucket_next;
+        else
+                BY_HASH(h)[hash] = e->bucket_next;
+
+        assert(h->n_entries >= 1);
+        h->n_entries--;
+}
+
+static void remove_entry(Hashmap *h, struct hashmap_entry *e) {
+        unsigned hash;
+
+        assert(h);
+        assert(e);
+
+        hash = h->hash_func(e->key) % NBUCKETS;
+
+        unlink_entry(h, e, hash);
+
+        if (h->from_pool)
+                deallocate_tile(&first_entry_tile, e);
+        else
+                free(e);
+}
+
+void hashmap_free(Hashmap*h) {
+
+        /* Free the hashmap, but nothing in it */
+
+        if (!h)
+                return;
+
+        hashmap_clear(h);
+
+        if (h->from_pool)
+                deallocate_tile(&first_hashmap_tile, h);
+        else
+                free(h);
+}
+
+void hashmap_free_free(Hashmap *h) {
+
+        /* Free the hashmap and all data objects in it, but not the
+         * keys */
+
+        if (!h)
+                return;
+
+        hashmap_clear_free(h);
+        hashmap_free(h);
+}
+
+void hashmap_clear(Hashmap *h) {
+        if (!h)
+                return;
+
+        while (h->iterate_list_head)
+                remove_entry(h, h->iterate_list_head);
+}
+
+void hashmap_clear_free(Hashmap *h) {
+        void *p;
+
+        if (!h)
+                return;
+
+        while ((p = hashmap_steal_first(h)))
+                free(p);
+}
+
+static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *key) {
+        struct hashmap_entry *e;
+        assert(h);
+        assert(hash < NBUCKETS);
+
+        for (e = BY_HASH(h)[hash]; e; e = e->bucket_next)
+                if (h->compare_func(e->key, key) == 0)
+                        return e;
+
+        return NULL;
+}
+
+int hashmap_put(Hashmap *h, const void *key, void *value) {
+        struct hashmap_entry *e;
+        unsigned hash;
+
+        assert(h);
+
+        hash = h->hash_func(key) % NBUCKETS;
+
+        e = hash_scan(h, hash, key);
+        if (e) {
+
+                if (e->value == value)
+                        return 0;
+
+                return -EEXIST;
+        }
+
+        if (h->from_pool)
+                e = allocate_tile(&first_entry_pool, &first_entry_tile, sizeof(struct hashmap_entry));
+        else
+                e = new(struct hashmap_entry, 1);
+
+        if (!e)
+                return -ENOMEM;
+
+        e->key = key;
+        e->value = value;
+
+        link_entry(h, e, hash);
+
+        return 1;
+}
+
+int hashmap_replace(Hashmap *h, const void *key, void *value) {
+        struct hashmap_entry *e;
+        unsigned hash;
+
+        assert(h);
+
+        hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (e) {
+                e->key = key;
+                e->value = value;
+                return 0;
+        }
+
+        return hashmap_put(h, key, value);
+}
+
+int hashmap_update(Hashmap *h, const void *key, void *value) {
+        struct hashmap_entry *e;
+        unsigned hash;
+
+        assert(h);
+
+        hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (!e)
+                return -ENOENT;
+
+        e->value = value;
+        return 0;
+}
+
+void* hashmap_get(Hashmap *h, const void *key) {
+        unsigned hash;
+        struct hashmap_entry *e;
+
+        if (!h)
+                return NULL;
+
+        hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (!e)
+                return NULL;
+
+        return e->value;
+}
+
+void* hashmap_get2(Hashmap *h, const void *key, void **key2) {
+        unsigned hash;
+        struct hashmap_entry *e;
+
+        if (!h)
+                return NULL;
+
+        hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (!e)
+                return NULL;
+
+        if (key2)
+                *key2 = (void*) e->key;
+
+        return e->value;
+}
+
+bool hashmap_contains(Hashmap *h, const void *key) {
+        unsigned hash;
+
+        if (!h)
+                return false;
+
+        hash = h->hash_func(key) % NBUCKETS;
+
+        if (!hash_scan(h, hash, key))
+                return false;
+
+        return true;
+}
+
+void* hashmap_remove(Hashmap *h, const void *key) {
+        struct hashmap_entry *e;
+        unsigned hash;
+        void *data;
+
+        if (!h)
+                return NULL;
+
+        hash = h->hash_func(key) % NBUCKETS;
+
+        if (!(e = hash_scan(h, hash, key)))
+                return NULL;
+
+        data = e->value;
+        remove_entry(h, e);
+
+        return data;
+}
+
+int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value) {
+        struct hashmap_entry *e;
+        unsigned old_hash, new_hash;
+
+        if (!h)
+                return -ENOENT;
+
+        old_hash = h->hash_func(old_key) % NBUCKETS;
+        if (!(e = hash_scan(h, old_hash, old_key)))
+                return -ENOENT;
+
+        new_hash = h->hash_func(new_key) % NBUCKETS;
+        if (hash_scan(h, new_hash, new_key))
+                return -EEXIST;
+
+        unlink_entry(h, e, old_hash);
+
+        e->key = new_key;
+        e->value = value;
+
+        link_entry(h, e, new_hash);
+
+        return 0;
+}
+
+int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value) {
+        struct hashmap_entry *e, *k;
+        unsigned old_hash, new_hash;
+
+        if (!h)
+                return -ENOENT;
+
+        old_hash = h->hash_func(old_key) % NBUCKETS;
+        if (!(e = hash_scan(h, old_hash, old_key)))
+                return -ENOENT;
+
+        new_hash = h->hash_func(new_key) % NBUCKETS;
+
+        if ((k = hash_scan(h, new_hash, new_key)))
+                if (e != k)
+                        remove_entry(h, k);
+
+        unlink_entry(h, e, old_hash);
+
+        e->key = new_key;
+        e->value = value;
+
+        link_entry(h, e, new_hash);
+
+        return 0;
+}
+
+void* hashmap_remove_value(Hashmap *h, const void *key, void *value) {
+        struct hashmap_entry *e;
+        unsigned hash;
+
+        if (!h)
+                return NULL;
+
+        hash = h->hash_func(key) % NBUCKETS;
+
+        if (!(e = hash_scan(h, hash, key)))
+                return NULL;
+
+        if (e->value != value)
+                return NULL;
+
+        remove_entry(h, e);
+
+        return value;
+}
+
+void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key) {
+        struct hashmap_entry *e;
+
+        assert(i);
+
+        if (!h)
+                goto at_end;
+
+        if (*i == ITERATOR_LAST)
+                goto at_end;
+
+        if (*i == ITERATOR_FIRST && !h->iterate_list_head)
+                goto at_end;
+
+        e = *i == ITERATOR_FIRST ? h->iterate_list_head : (struct hashmap_entry*) *i;
+
+        if (e->iterate_next)
+                *i = (Iterator) e->iterate_next;
+        else
+                *i = ITERATOR_LAST;
+
+        if (key)
+                *key = e->key;
+
+        return e->value;
+
+at_end:
+        *i = ITERATOR_LAST;
+
+        if (key)
+                *key = NULL;
+
+        return NULL;
+}
+
+void *hashmap_iterate_backwards(Hashmap *h, Iterator *i, const void **key) {
+        struct hashmap_entry *e;
+
+        assert(i);
+
+        if (!h)
+                goto at_beginning;
+
+        if (*i == ITERATOR_FIRST)
+                goto at_beginning;
+
+        if (*i == ITERATOR_LAST && !h->iterate_list_tail)
+                goto at_beginning;
+
+        e = *i == ITERATOR_LAST ? h->iterate_list_tail : (struct hashmap_entry*) *i;
+
+        if (e->iterate_previous)
+                *i = (Iterator) e->iterate_previous;
+        else
+                *i = ITERATOR_FIRST;
+
+        if (key)
+                *key = e->key;
+
+        return e->value;
+
+at_beginning:
+        *i = ITERATOR_FIRST;
+
+        if (key)
+                *key = NULL;
+
+        return NULL;
+}
+
+void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i) {
+        unsigned hash;
+        struct hashmap_entry *e;
+
+        if (!h)
+                return NULL;
+
+        hash = h->hash_func(key) % NBUCKETS;
+
+        if (!(e = hash_scan(h, hash, key)))
+                return NULL;
+
+        *i = (Iterator) e;
+
+        return e->value;
+}
+
+void* hashmap_first(Hashmap *h) {
+
+        if (!h)
+                return NULL;
+
+        if (!h->iterate_list_head)
+                return NULL;
+
+        return h->iterate_list_head->value;
+}
+
+void* hashmap_first_key(Hashmap *h) {
+
+        if (!h)
+                return NULL;
+
+        if (!h->iterate_list_head)
+                return NULL;
+
+        return (void*) h->iterate_list_head->key;
+}
+
+void* hashmap_last(Hashmap *h) {
+
+        if (!h)
+                return NULL;
+
+        if (!h->iterate_list_tail)
+                return NULL;
+
+        return h->iterate_list_tail->value;
+}
+
+void* hashmap_steal_first(Hashmap *h) {
+        void *data;
+
+        if (!h)
+                return NULL;
+
+        if (!h->iterate_list_head)
+                return NULL;
+
+        data = h->iterate_list_head->value;
+        remove_entry(h, h->iterate_list_head);
+
+        return data;
+}
+
+void* hashmap_steal_first_key(Hashmap *h) {
+        void *key;
+
+        if (!h)
+                return NULL;
+
+        if (!h->iterate_list_head)
+                return NULL;
+
+        key = (void*) h->iterate_list_head->key;
+        remove_entry(h, h->iterate_list_head);
+
+        return key;
+}
+
+unsigned hashmap_size(Hashmap *h) {
+
+        if (!h)
+                return 0;
+
+        return h->n_entries;
+}
+
+bool hashmap_isempty(Hashmap *h) {
+
+        if (!h)
+                return true;
+
+        return h->n_entries == 0;
+}
+
+int hashmap_merge(Hashmap *h, Hashmap *other) {
+        struct hashmap_entry *e;
+
+        assert(h);
+
+        if (!other)
+                return 0;
+
+        for (e = other->iterate_list_head; e; e = e->iterate_next) {
+                int r;
+
+                if ((r = hashmap_put(h, e->key, e->value)) < 0)
+                        if (r != -EEXIST)
+                                return r;
+        }
+
+        return 0;
+}
+
+void hashmap_move(Hashmap *h, Hashmap *other) {
+        struct hashmap_entry *e, *n;
+
+        assert(h);
+
+        /* The same as hashmap_merge(), but every new item from other
+         * is moved to h. This function is guaranteed to succeed. */
+
+        if (!other)
+                return;
+
+        for (e = other->iterate_list_head; e; e = n) {
+                unsigned h_hash, other_hash;
+
+                n = e->iterate_next;
+
+                h_hash = h->hash_func(e->key) % NBUCKETS;
+
+                if (hash_scan(h, h_hash, e->key))
+                        continue;
+
+                other_hash = other->hash_func(e->key) % NBUCKETS;
+
+                unlink_entry(other, e, other_hash);
+                link_entry(h, e, h_hash);
+        }
+}
+
+int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) {
+        unsigned h_hash, other_hash;
+        struct hashmap_entry *e;
+
+        if (!other)
+                return 0;
+
+        assert(h);
+
+        h_hash = h->hash_func(key) % NBUCKETS;
+        if (hash_scan(h, h_hash, key))
+                return -EEXIST;
+
+        other_hash = other->hash_func(key) % NBUCKETS;
+        if (!(e = hash_scan(other, other_hash, key)))
+                return -ENOENT;
+
+        unlink_entry(other, e, other_hash);
+        link_entry(h, e, h_hash);
+
+        return 0;
+}
+
+Hashmap *hashmap_copy(Hashmap *h) {
+        Hashmap *copy;
+
+        assert(h);
+
+        if (!(copy = hashmap_new(h->hash_func, h->compare_func)))
+                return NULL;
+
+        if (hashmap_merge(copy, h) < 0) {
+                hashmap_free(copy);
+                return NULL;
+        }
+
+        return copy;
+}
+
+char **hashmap_get_strv(Hashmap *h) {
+        char **sv;
+        Iterator it;
+        char *item;
+        int n;
+
+        sv = new(char*, h->n_entries+1);
+        if (!sv)
+                return NULL;
+
+        n = 0;
+        HASHMAP_FOREACH(item, h, it)
+                sv[n++] = item;
+        sv[n] = NULL;
+
+        return sv;
+}
+
+void *hashmap_next(Hashmap *h, const void *key) {
+        unsigned hash;
+        struct hashmap_entry *e;
+
+        assert(h);
+        assert(key);
+
+        if (!h)
+                return NULL;
+
+        hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (!e)
+                return NULL;
+
+        e = e->iterate_next;
+        if (!e)
+                return NULL;
+
+        return e->value;
+}
diff --git a/src/shared/hashmap.h b/src/shared/hashmap.h
new file mode 100644 (file)
index 0000000..6fd71cf
--- /dev/null
@@ -0,0 +1,98 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+/* Pretty straightforward hash table implementation. As a minor
+ * optimization a NULL hashmap object will be treated as empty hashmap
+ * for all read operations. That way it is not necessary to
+ * instantiate an object for each Hashmap use. */
+
+typedef struct Hashmap Hashmap;
+typedef struct _IteratorStruct _IteratorStruct;
+typedef _IteratorStruct* Iterator;
+
+#define ITERATOR_FIRST ((Iterator) 0)
+#define ITERATOR_LAST ((Iterator) -1)
+
+typedef unsigned (*hash_func_t)(const void *p);
+typedef int (*compare_func_t)(const void *a, const void *b);
+
+unsigned string_hash_func(const void *p);
+int string_compare_func(const void *a, const void *b);
+
+unsigned trivial_hash_func(const void *p);
+int trivial_compare_func(const void *a, const void *b);
+
+unsigned uint64_hash_func(const void *p);
+int uint64_compare_func(const void *a, const void *b);
+
+Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func);
+void hashmap_free(Hashmap *h);
+void hashmap_free_free(Hashmap *h);
+Hashmap *hashmap_copy(Hashmap *h);
+int hashmap_ensure_allocated(Hashmap **h, hash_func_t hash_func, compare_func_t compare_func);
+
+int hashmap_put(Hashmap *h, const void *key, void *value);
+int hashmap_update(Hashmap *h, const void *key, void *value);
+int hashmap_replace(Hashmap *h, const void *key, void *value);
+void* hashmap_get(Hashmap *h, const void *key);
+void* hashmap_get2(Hashmap *h, const void *key, void **rkey);
+bool hashmap_contains(Hashmap *h, const void *key);
+void* hashmap_remove(Hashmap *h, const void *key);
+void* hashmap_remove_value(Hashmap *h, const void *key, void *value);
+int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value);
+int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value);
+
+int hashmap_merge(Hashmap *h, Hashmap *other);
+void hashmap_move(Hashmap *h, Hashmap *other);
+int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key);
+
+unsigned hashmap_size(Hashmap *h);
+bool hashmap_isempty(Hashmap *h);
+
+void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key);
+void *hashmap_iterate_backwards(Hashmap *h, Iterator *i, const void **key);
+void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i);
+
+void hashmap_clear(Hashmap *h);
+void hashmap_clear_free(Hashmap *h);
+
+void *hashmap_steal_first(Hashmap *h);
+void *hashmap_steal_first_key(Hashmap *h);
+void* hashmap_first(Hashmap *h);
+void* hashmap_first_key(Hashmap *h);
+void* hashmap_last(Hashmap *h);
+
+void *hashmap_next(Hashmap *h, const void *key);
+
+char **hashmap_get_strv(Hashmap *h);
+
+#define HASHMAP_FOREACH(e, h, i) \
+        for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), NULL); (e); (e) = hashmap_iterate((h), &(i), NULL))
+
+#define HASHMAP_FOREACH_KEY(e, k, h, i) \
+        for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), (const void**) &(k)); (e); (e) = hashmap_iterate((h), &(i), (const void**) &(k)))
+
+#define HASHMAP_FOREACH_BACKWARDS(e, h, i) \
+        for ((i) = ITERATOR_LAST, (e) = hashmap_iterate_backwards((h), &(i), NULL); (e); (e) = hashmap_iterate_backwards((h), &(i), NULL))
diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c
new file mode 100644 (file)
index 0000000..f9adf03
--- /dev/null
@@ -0,0 +1,240 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010-2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <sys/prctl.h>
+#include <sys/time.h>
+#include <linux/rtc.h>
+
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+#include "strv.h"
+#include "hwclock.h"
+
+static int rtc_open(int flags) {
+        int fd;
+        DIR *d;
+
+        /* First, we try to make use of the /dev/rtc symlink. If that
+         * doesn't exist, we open the first RTC which has hctosys=1
+         * set. If we don't find any we just take the first RTC that
+         * exists at all. */
+
+        fd = open("/dev/rtc", flags);
+        if (fd >= 0)
+                return fd;
+
+        d = opendir("/sys/class/rtc");
+        if (!d)
+                goto fallback;
+
+        for (;;) {
+                char *p, *v;
+                struct dirent *de;
+                union dirent_storage buf;
+                int r;
+
+                r = readdir_r(d, &buf.de, &de);
+                if (r != 0)
+                        goto fallback;
+
+                if (!de)
+                        goto fallback;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                p = strjoin("/sys/class/rtc/", de->d_name, "/hctosys", NULL);
+                if (!p) {
+                        closedir(d);
+                        return -ENOMEM;
+                }
+
+                r = read_one_line_file(p, &v);
+                free(p);
+
+                if (r < 0)
+                        continue;
+
+                r = parse_boolean(v);
+                free(v);
+
+                if (r <= 0)
+                        continue;
+
+                p = strappend("/dev/", de->d_name);
+                if (!p) {
+                        closedir(d);
+                        return -ENOMEM;
+                }
+
+                fd = open(p, flags);
+                free(p);
+
+                if (fd >= 0) {
+                        closedir(d);
+                        return fd;
+                }
+        }
+
+fallback:
+        if (d)
+                closedir(d);
+
+        fd = open("/dev/rtc0", flags);
+        if (fd < 0)
+                return -errno;
+
+        return fd;
+}
+
+int hwclock_get_time(struct tm *tm) {
+        int fd;
+        int err = 0;
+
+        assert(tm);
+
+        fd = rtc_open(O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        /* This leaves the timezone fields of struct tm
+         * uninitialized! */
+        if (ioctl(fd, RTC_RD_TIME, tm) < 0)
+                err = -errno;
+
+        /* We don't know daylight saving, so we reset this in order not
+         * to confused mktime(). */
+        tm->tm_isdst = -1;
+
+        close_nointr_nofail(fd);
+
+        return err;
+}
+
+int hwclock_set_time(const struct tm *tm) {
+        int fd;
+        int err = 0;
+
+        assert(tm);
+
+        fd = rtc_open(O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        if (ioctl(fd, RTC_SET_TIME, tm) < 0)
+                err = -errno;
+
+        close_nointr_nofail(fd);
+
+        return err;
+}
+
+int hwclock_is_localtime(void) {
+        FILE *f;
+        bool local = false;
+
+        /*
+         * The third line of adjtime is "UTC" or "LOCAL" or nothing.
+         *   # /etc/adjtime
+         *   0.0 0 0
+         *   0
+         *   UTC
+         */
+        f = fopen("/etc/adjtime", "re");
+        if (f) {
+                char line[LINE_MAX];
+                bool b;
+
+                b = fgets(line, sizeof(line), f) &&
+                        fgets(line, sizeof(line), f) &&
+                        fgets(line, sizeof(line), f);
+
+                fclose(f);
+
+                if (!b)
+                        return -EIO;
+
+                truncate_nl(line);
+                local = streq(line, "LOCAL");
+
+        } else if (errno != -ENOENT)
+                return -errno;
+
+        return local;
+}
+
+int hwclock_set_timezone(int *min) {
+        const struct timeval *tv_null = NULL;
+        struct timespec ts;
+        struct tm *tm;
+        int minutesdelta;
+        struct timezone tz;
+
+        assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
+        assert_se(tm = localtime(&ts.tv_sec));
+        minutesdelta = tm->tm_gmtoff / 60;
+
+        tz.tz_minuteswest = -minutesdelta;
+        tz.tz_dsttime = 0; /* DST_NONE*/
+
+        /*
+         * If the hardware clock does not run in UTC, but in local time:
+         * The very first time we set the kernel's timezone, it will warp
+         * the clock so that it runs in UTC instead of local time.
+         */
+        if (settimeofday(tv_null, &tz) < 0)
+                return -errno;
+        if (min)
+                *min = minutesdelta;
+        return 0;
+}
+
+int hwclock_reset_timezone(void) {
+        const struct timeval *tv_null = NULL;
+        struct timezone tz;
+
+        tz.tz_minuteswest = 0;
+        tz.tz_dsttime = 0; /* DST_NONE*/
+
+        /*
+         * The very first time we set the kernel's timezone, it will warp
+         * the clock. Do a dummy call here, so the time warping is sealed
+         * and we set only the time zone with next call.
+         */
+        if (settimeofday(tv_null, &tz) < 0)
+                return -errno;
+
+        return 0;
+}
diff --git a/src/shared/hwclock.h b/src/shared/hwclock.h
new file mode 100644 (file)
index 0000000..b2bdc78
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foohwclockhfoo
+#define foohwclockhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010-2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int hwclock_is_localtime(void);
+int hwclock_set_timezone(int *min);
+int hwclock_reset_timezone(void);
+int hwclock_get_time(struct tm *tm);
+int hwclock_set_time(const struct tm *tm);
+
+#endif
diff --git a/src/shared/install.c b/src/shared/install.c
new file mode 100644 (file)
index 0000000..a9d75f3
--- /dev/null
@@ -0,0 +1,2059 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <fnmatch.h>
+
+#include "util.h"
+#include "mkdir.h"
+#include "hashmap.h"
+#include "set.h"
+#include "path-util.h"
+#include "path-lookup.h"
+#include "strv.h"
+#include "unit-name.h"
+#include "install.h"
+#include "conf-parser.h"
+#include "conf-files.h"
+
+typedef struct {
+        char *name;
+        char *path;
+
+        char **aliases;
+        char **wanted_by;
+        char **required_by;
+} InstallInfo;
+
+typedef struct {
+        Hashmap *will_install;
+        Hashmap *have_installed;
+} InstallContext;
+
+static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) {
+        assert(paths);
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        zero(*paths);
+
+        return lookup_paths_init(paths,
+                                 scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
+                                 scope == UNIT_FILE_USER,
+                                 NULL, NULL, NULL);
+}
+
+static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) {
+        char *p = NULL;
+        int r;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+        assert(ret);
+
+        switch (scope) {
+
+        case UNIT_FILE_SYSTEM:
+
+                if (root_dir && runtime)
+                        asprintf(&p, "%s/run/systemd/system", root_dir);
+                else if (runtime)
+                        p = strdup("/run/systemd/system");
+                else if (root_dir)
+                        asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH);
+                else
+                        p = strdup(SYSTEM_CONFIG_UNIT_PATH);
+
+                break;
+
+        case UNIT_FILE_GLOBAL:
+
+                if (root_dir)
+                        return -EINVAL;
+
+                if (runtime)
+                        p = strdup("/run/systemd/user");
+                else
+                        p = strdup(USER_CONFIG_UNIT_PATH);
+                break;
+
+        case UNIT_FILE_USER:
+
+                if (root_dir || runtime)
+                        return -EINVAL;
+
+                r = user_config_home(&p);
+                if (r <= 0)
+                        return r < 0 ? r : -ENOENT;
+
+                break;
+
+        default:
+                assert_not_reached("Bad scope");
+        }
+
+        if (!p)
+                return -ENOMEM;
+
+        *ret = p;
+        return 0;
+}
+
+static int add_file_change(
+                UnitFileChange **changes,
+                unsigned *n_changes,
+                UnitFileChangeType type,
+                const char *path,
+                const char *source) {
+
+        UnitFileChange *c;
+        unsigned i;
+
+        assert(path);
+        assert(!changes == !n_changes);
+
+        if (!changes)
+                return 0;
+
+        c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
+        if (!c)
+                return -ENOMEM;
+
+        *changes = c;
+        i = *n_changes;
+
+        c[i].type = type;
+        c[i].path = strdup(path);
+        if (!c[i].path)
+                return -ENOMEM;
+
+        if (source) {
+                c[i].source = strdup(source);
+                if (!c[i].source) {
+                        free(c[i].path);
+                        return -ENOMEM;
+                }
+        } else
+                c[i].source = NULL;
+
+        *n_changes = i+1;
+        return 0;
+}
+
+static int mark_symlink_for_removal(
+                Set **remove_symlinks_to,
+                const char *p) {
+
+        char *n;
+        int r;
+
+        assert(p);
+
+        r = set_ensure_allocated(remove_symlinks_to, string_hash_func, string_compare_func);
+        if (r < 0)
+                return r;
+
+        n = strdup(p);
+        if (!n)
+                return -ENOMEM;
+
+        path_kill_slashes(n);
+
+        r = set_put(*remove_symlinks_to, n);
+        if (r < 0) {
+                free(n);
+                return r == -EEXIST ? 0 : r;
+        }
+
+        return 0;
+}
+
+static int remove_marked_symlinks_fd(
+                Set *remove_symlinks_to,
+                int fd,
+                const char *path,
+                const char *config_path,
+                bool *deleted,
+                UnitFileChange **changes,
+                unsigned *n_changes,
+                char** files) {
+
+        int r = 0;
+        DIR *d;
+
+        assert(remove_symlinks_to);
+        assert(fd >= 0);
+        assert(path);
+        assert(config_path);
+        assert(deleted);
+
+        d = fdopendir(fd);
+        if (!d) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        rewinddir(d);
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                int k;
+
+                k = readdir_r(d, &buf.de, &de);
+                if (k != 0) {
+                        r = -errno;
+                        break;
+                }
+
+                if (!de)
+                        break;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                dirent_ensure_type(d, de);
+
+                if (de->d_type == DT_DIR) {
+                        int nfd, q;
+                        char *p;
+
+                        nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
+                        if (nfd < 0) {
+                                if (errno == ENOENT)
+                                        continue;
+
+                                if (r == 0)
+                                        r = -errno;
+                                continue;
+                        }
+
+                        p = path_make_absolute(de->d_name, path);
+                        if (!p) {
+                                close_nointr_nofail(nfd);
+                                r = -ENOMEM;
+                                break;
+                        }
+
+                        /* This will close nfd, regardless whether it succeeds or not */
+                        q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, files);
+                        free(p);
+
+                        if (r == 0)
+                                r = q;
+
+                } else if (de->d_type == DT_LNK) {
+                        char *p, *dest;
+                        int q;
+                        bool found;
+
+                        p = path_make_absolute(de->d_name, path);
+                        if (!p) {
+                                r = -ENOMEM;
+                                break;
+                        }
+
+                        q = readlink_and_canonicalize(p, &dest);
+                        if (q < 0) {
+                                free(p);
+
+                                if (q == -ENOENT)
+                                        continue;
+
+                                if (r == 0)
+                                        r = q;
+                                continue;
+                        }
+
+                        found =
+                                set_get(remove_symlinks_to, dest) ||
+                                set_get(remove_symlinks_to, path_get_file_name(dest));
+
+                        if (unit_name_is_instance(p))
+                                found = found && strv_contains(files, path_get_file_name(p));
+
+                        if (found) {
+
+                                if (unlink(p) < 0 && errno != ENOENT) {
+
+                                        if (r == 0)
+                                                r = -errno;
+                                } else {
+                                        rmdir_parents(p, config_path);
+                                        path_kill_slashes(p);
+
+                                        add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
+
+                                        if (!set_get(remove_symlinks_to, p)) {
+
+                                                q = mark_symlink_for_removal(&remove_symlinks_to, p);
+                                                if (q < 0) {
+                                                        if (r == 0)
+                                                                r = q;
+                                                } else
+                                                        *deleted = true;
+                                        }
+                                }
+                        }
+
+                        free(p);
+                        free(dest);
+                }
+        }
+
+        closedir(d);
+
+        return r;
+}
+
+static int remove_marked_symlinks(
+                Set *remove_symlinks_to,
+                const char *config_path,
+                UnitFileChange **changes,
+                unsigned *n_changes,
+                char** files) {
+
+        int fd, r = 0;
+        bool deleted;
+
+        assert(config_path);
+
+        if (set_size(remove_symlinks_to) <= 0)
+                return 0;
+
+        fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
+        if (fd < 0)
+                return -errno;
+
+        do {
+                int q, cfd;
+                deleted = false;
+
+                cfd = dup(fd);
+                if (cfd < 0) {
+                        r = -errno;
+                        break;
+                }
+
+                /* This takes possession of cfd and closes it */
+                q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, files);
+                if (r == 0)
+                        r = q;
+        } while (deleted);
+
+        close_nointr_nofail(fd);
+
+        return r;
+}
+
+static int find_symlinks_fd(
+                const char *name,
+                int fd,
+                const char *path,
+                const char *config_path,
+                bool *same_name_link) {
+
+        int r = 0;
+        DIR *d;
+
+        assert(name);
+        assert(fd >= 0);
+        assert(path);
+        assert(config_path);
+        assert(same_name_link);
+
+        d = fdopendir(fd);
+        if (!d) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        for (;;) {
+                int k;
+                struct dirent *de;
+                union dirent_storage buf;
+
+                k = readdir_r(d, &buf.de, &de);
+                if (k != 0) {
+                        r = -errno;
+                        break;
+                }
+
+                if (!de)
+                        break;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                dirent_ensure_type(d, de);
+
+                if (de->d_type == DT_DIR) {
+                        int nfd, q;
+                        char *p;
+
+                        nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
+                        if (nfd < 0) {
+                                if (errno == ENOENT)
+                                        continue;
+
+                                if (r == 0)
+                                        r = -errno;
+                                continue;
+                        }
+
+                        p = path_make_absolute(de->d_name, path);
+                        if (!p) {
+                                close_nointr_nofail(nfd);
+                                r = -ENOMEM;
+                                break;
+                        }
+
+                        /* This will close nfd, regardless whether it succeeds or not */
+                        q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
+                        free(p);
+
+                        if (q > 0) {
+                                r = 1;
+                                break;
+                        }
+
+                        if (r == 0)
+                                r = q;
+
+                } else if (de->d_type == DT_LNK) {
+                        char *p, *dest;
+                        bool found_path, found_dest, b = false;
+                        int q;
+
+                        /* Acquire symlink name */
+                        p = path_make_absolute(de->d_name, path);
+                        if (!p) {
+                                r = -ENOMEM;
+                                break;
+                        }
+
+                        /* Acquire symlink destination */
+                        q = readlink_and_canonicalize(p, &dest);
+                        if (q < 0) {
+                                free(p);
+
+                                if (q == -ENOENT)
+                                        continue;
+
+                                if (r == 0)
+                                        r = q;
+                                continue;
+                        }
+
+                        /* Check if the symlink itself matches what we
+                         * are looking for */
+                        if (path_is_absolute(name))
+                                found_path = path_equal(p, name);
+                        else
+                                found_path = streq(de->d_name, name);
+
+                        /* Check if what the symlink points to
+                         * matches what we are looking for */
+                        if (path_is_absolute(name))
+                                found_dest = path_equal(dest, name);
+                        else
+                                found_dest = streq(path_get_file_name(dest), name);
+
+                        free(dest);
+
+                        if (found_path && found_dest) {
+                                char *t;
+
+                                /* Filter out same name links in the main
+                                 * config path */
+                                t = path_make_absolute(name, config_path);
+                                if (!t) {
+                                        free(p);
+                                        r = -ENOMEM;
+                                        break;
+                                }
+
+                                b = path_equal(t, p);
+                                free(t);
+                        }
+
+                        free(p);
+
+                        if (b)
+                                *same_name_link = true;
+                        else if (found_path || found_dest) {
+                                r = 1;
+                                break;
+                        }
+                }
+        }
+
+        closedir(d);
+
+        return r;
+}
+
+static int find_symlinks(
+                const char *name,
+                const char *config_path,
+                bool *same_name_link) {
+
+        int fd;
+
+        assert(name);
+        assert(config_path);
+        assert(same_name_link);
+
+        fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
+        if (fd < 0) {
+                if (errno == ENOENT)
+                        return 0;
+                return -errno;
+        }
+
+        /* This takes possession of fd and closes it */
+        return find_symlinks_fd(name, fd, config_path, config_path, same_name_link);
+}
+
+static int find_symlinks_in_scope(
+                UnitFileScope scope,
+                const char *root_dir,
+                const char *name,
+                UnitFileState *state) {
+
+        int r;
+        char _cleanup_free_ *path = NULL;
+        bool same_name_link_runtime = false, same_name_link = false;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+        assert(name);
+
+        if (scope == UNIT_FILE_SYSTEM || scope == UNIT_FILE_GLOBAL) {
+
+                /* First look in runtime config path */
+                r = get_config_path(scope, true, root_dir, &path);
+                if (r < 0)
+                        return r;
+
+                r = find_symlinks(name, path, &same_name_link_runtime);
+                if (r < 0)
+                        return r;
+                else if (r > 0) {
+                        *state = UNIT_FILE_ENABLED_RUNTIME;
+                        return r;
+                }
+        }
+
+        /* Then look in the normal config path */
+        r = get_config_path(scope, false, root_dir, &path);
+        if (r < 0)
+                return r;
+
+        r = find_symlinks(name, path, &same_name_link);
+        if (r < 0)
+                return r;
+        else if (r > 0) {
+                *state = UNIT_FILE_ENABLED;
+                return r;
+        }
+
+        /* Hmm, we didn't find it, but maybe we found the same name
+         * link? */
+        if (same_name_link_runtime) {
+                *state = UNIT_FILE_LINKED_RUNTIME;
+                return 1;
+        } else if (same_name_link) {
+                *state = UNIT_FILE_LINKED;
+                return 1;
+        }
+
+        return 0;
+}
+
+int unit_file_mask(
+                UnitFileScope scope,
+                bool runtime,
+                const char *root_dir,
+                char *files[],
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        char **i;
+        char _cleanup_free_ *prefix;
+        int r;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        r = get_config_path(scope, runtime, root_dir, &prefix);
+        if (r < 0)
+                return r;
+
+        STRV_FOREACH(i, files) {
+                char _cleanup_free_ *path = NULL;
+
+                if (!unit_name_is_valid(*i, true)) {
+                        if (r == 0)
+                                r = -EINVAL;
+                        continue;
+                }
+
+                path = path_make_absolute(*i, prefix);
+                if (!path) {
+                        r = -ENOMEM;
+                        break;
+                }
+
+                if (symlink("/dev/null", path) >= 0) {
+                        add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
+
+                        continue;
+                }
+
+                if (errno == EEXIST) {
+
+                        if (null_or_empty_path(path) > 0)
+                                continue;
+
+                        if (force) {
+                                unlink(path);
+
+                                if (symlink("/dev/null", path) >= 0) {
+
+                                        add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
+                                        add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
+
+                                        continue;
+                                }
+                        }
+
+                        if (r == 0)
+                                r = -EEXIST;
+                } else {
+                        if (r == 0)
+                                r = -errno;
+                }
+        }
+
+        return r;
+}
+
+int unit_file_unmask(
+                UnitFileScope scope,
+                bool runtime,
+                const char *root_dir,
+                char *files[],
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        char **i, *config_path = NULL;
+        int r, q;
+        Set *remove_symlinks_to = NULL;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        r = get_config_path(scope, runtime, root_dir, &config_path);
+        if (r < 0)
+                goto finish;
+
+        STRV_FOREACH(i, files) {
+                char *path;
+
+                if (!unit_name_is_valid(*i, true)) {
+                        if (r == 0)
+                                r = -EINVAL;
+                        continue;
+                }
+
+                path = path_make_absolute(*i, config_path);
+                if (!path) {
+                        r = -ENOMEM;
+                        break;
+                }
+
+                q = null_or_empty_path(path);
+                if (q > 0) {
+                        if (unlink(path) >= 0) {
+                                mark_symlink_for_removal(&remove_symlinks_to, path);
+                                add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
+
+                                free(path);
+                                continue;
+                        }
+
+                        q = -errno;
+                }
+
+                if (q != -ENOENT && r == 0)
+                        r = q;
+
+                free(path);
+        }
+
+
+finish:
+        q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+        if (r == 0)
+                r = q;
+
+        set_free_free(remove_symlinks_to);
+        free(config_path);
+
+        return r;
+}
+
+int unit_file_link(
+                UnitFileScope scope,
+                bool runtime,
+                const char *root_dir,
+                char *files[],
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        LookupPaths paths;
+        char **i, *config_path = NULL;
+        int r, q;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        zero(paths);
+
+        r = lookup_paths_init_from_scope(&paths, scope);
+        if (r < 0)
+                return r;
+
+        r = get_config_path(scope, runtime, root_dir, &config_path);
+        if (r < 0)
+                goto finish;
+
+        STRV_FOREACH(i, files) {
+                char *path, *fn;
+                struct stat st;
+
+                fn = path_get_file_name(*i);
+
+                if (!path_is_absolute(*i) ||
+                    !unit_name_is_valid(fn, true)) {
+                        if (r == 0)
+                                r = -EINVAL;
+                        continue;
+                }
+
+                if (lstat(*i, &st) < 0) {
+                        if (r == 0)
+                                r = -errno;
+                        continue;
+                }
+
+                if (!S_ISREG(st.st_mode)) {
+                        r = -ENOENT;
+                        continue;
+                }
+
+                q = in_search_path(*i, paths.unit_path);
+                if (q < 0) {
+                        r = q;
+                        break;
+                }
+
+                if (q > 0)
+                        continue;
+
+                path = path_make_absolute(fn, config_path);
+                if (!path) {
+                        r = -ENOMEM;
+                        break;
+                }
+
+                if (symlink(*i, path) >= 0) {
+                        add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
+
+                        free(path);
+                        continue;
+                }
+
+                if (errno == EEXIST) {
+                        char *dest = NULL;
+
+                        q = readlink_and_make_absolute(path, &dest);
+
+                        if (q < 0 && errno != ENOENT) {
+                                free(path);
+
+                                if (r == 0)
+                                        r = q;
+
+                                continue;
+                        }
+
+                        if (q >= 0 && path_equal(dest, *i)) {
+                                free(dest);
+                                free(path);
+                                continue;
+                        }
+
+                        free(dest);
+
+                        if (force) {
+                                unlink(path);
+
+                                if (symlink(*i, path) >= 0) {
+
+                                        add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
+                                        add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
+
+                                        free(path);
+                                        continue;
+                                }
+                        }
+
+                        if (r == 0)
+                                r = -EEXIST;
+                } else {
+                        if (r == 0)
+                                r = -errno;
+                }
+
+                free(path);
+        }
+
+                finish:
+        lookup_paths_free(&paths);
+        free(config_path);
+
+        return r;
+}
+
+void unit_file_list_free(Hashmap *h) {
+        UnitFileList *i;
+
+        while ((i = hashmap_steal_first(h))) {
+                free(i->path);
+                free(i);
+        }
+
+        hashmap_free(h);
+}
+
+void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
+        unsigned i;
+
+        assert(changes || n_changes == 0);
+
+        if (!changes)
+                return;
+
+        for (i = 0; i < n_changes; i++) {
+                free(changes[i].path);
+                free(changes[i].source);
+        }
+
+        free(changes);
+}
+
+static void install_info_free(InstallInfo *i) {
+        assert(i);
+
+        free(i->name);
+        free(i->path);
+        strv_free(i->aliases);
+        strv_free(i->wanted_by);
+        strv_free(i->required_by);
+        free(i);
+}
+
+static void install_info_hashmap_free(Hashmap *m) {
+        InstallInfo *i;
+
+        if (!m)
+                return;
+
+        while ((i = hashmap_steal_first(m)))
+                install_info_free(i);
+
+        hashmap_free(m);
+}
+
+static void install_context_done(InstallContext *c) {
+        assert(c);
+
+        install_info_hashmap_free(c->will_install);
+        install_info_hashmap_free(c->have_installed);
+
+        c->will_install = c->have_installed = NULL;
+}
+
+static int install_info_add(
+                InstallContext *c,
+                const char *name,
+                const char *path) {
+        InstallInfo *i = NULL;
+        int r;
+
+        assert(c);
+        assert(name || path);
+
+        if (!name)
+                name = path_get_file_name(path);
+
+        if (!unit_name_is_valid(name, true))
+                return -EINVAL;
+
+        if (hashmap_get(c->have_installed, name) ||
+            hashmap_get(c->will_install, name))
+                return 0;
+
+        r = hashmap_ensure_allocated(&c->will_install, string_hash_func, string_compare_func);
+        if (r < 0)
+                return r;
+
+        i = new0(InstallInfo, 1);
+        if (!i)
+                return -ENOMEM;
+
+        i->name = strdup(name);
+        if (!i->name) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        if (path) {
+                i->path = strdup(path);
+                if (!i->path) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+        }
+
+        r = hashmap_put(c->will_install, i->name, i);
+        if (r < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        if (i)
+                install_info_free(i);
+
+        return r;
+}
+
+static int install_info_add_auto(
+                InstallContext *c,
+                const char *name_or_path) {
+
+        assert(c);
+        assert(name_or_path);
+
+        if (path_is_absolute(name_or_path))
+                return install_info_add(c, NULL, name_or_path);
+        else
+                return install_info_add(c, name_or_path, NULL);
+}
+
+static int config_parse_also(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char *w;
+        size_t l;
+        char *state;
+        InstallContext *c = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+                char *n;
+                int r;
+
+                n = strndup(w, l);
+                if (!n)
+                        return -ENOMEM;
+
+                r = install_info_add(c, n, NULL);
+                if (r < 0) {
+                        free(n);
+                        return r;
+                }
+
+                free(n);
+        }
+
+        return 0;
+}
+
+static int unit_file_load(
+                InstallContext *c,
+                InstallInfo *info,
+                const char *path,
+                bool allow_symlink) {
+
+        const ConfigTableItem items[] = {
+                { "Install", "Alias",      config_parse_strv, 0, &info->aliases     },
+                { "Install", "WantedBy",   config_parse_strv, 0, &info->wanted_by   },
+                { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
+                { "Install", "Also",       config_parse_also, 0, c                  },
+                { NULL, NULL, NULL, 0, NULL }
+        };
+
+        int fd;
+        FILE *f;
+        int r;
+
+        assert(c);
+        assert(info);
+        assert(path);
+
+        fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
+        if (fd < 0)
+                return -errno;
+
+        f = fdopen(fd, "re");
+        if (!f) {
+                close_nointr_nofail(fd);
+                return -ENOMEM;
+        }
+
+        r = config_parse(path, f, NULL, config_item_table_lookup, (void*) items, true, info);
+        fclose(f);
+        if (r < 0)
+                return r;
+
+        return
+                strv_length(info->aliases) +
+                strv_length(info->wanted_by) +
+                strv_length(info->required_by);
+}
+
+static int unit_file_search(
+                InstallContext *c,
+                InstallInfo *info,
+                LookupPaths *paths,
+                const char *root_dir,
+                bool allow_symlink) {
+
+        char **p;
+        int r;
+
+        assert(c);
+        assert(info);
+        assert(paths);
+
+        if (info->path)
+                return unit_file_load(c, info, info->path, allow_symlink);
+
+        assert(info->name);
+
+        STRV_FOREACH(p, paths->unit_path) {
+                char *path = NULL;
+
+                if (isempty(root_dir))
+                        asprintf(&path, "%s/%s", *p, info->name);
+                else
+                        asprintf(&path, "%s/%s/%s", root_dir, *p, info->name);
+
+                if (!path)
+                        return -ENOMEM;
+
+                r = unit_file_load(c, info, path, allow_symlink);
+
+                if (r >= 0)
+                        info->path = path;
+                else {
+                        if (r == -ENOENT && unit_name_is_instance(info->name)) {
+                                /* unit file doesn't exist, however instance enablement was request */
+                                /* we will check if it is possible to load template unit file */
+                                char *template = NULL,
+                                     *template_path = NULL,
+                                     *template_dir = NULL;
+
+                                template = unit_name_template(info->name);
+                                if (!template) {
+                                        free(path);
+                                        return -ENOMEM;
+                                }
+
+                                /* we will reuse path variable since we don't need it anymore */
+                                template_dir = path;
+                                *(strrchr(path, '/') + 1) = '\0';
+
+                                template_path = strjoin(template_dir, template, NULL);
+                                if (!template_path) {
+                                        free(path);
+                                        free(template);
+                                        return -ENOMEM;
+                                }
+
+                                /* let's try to load template unit */
+                                r = unit_file_load(c, info, template_path, allow_symlink);
+                                if (r >= 0) {
+                                        info->path = strdup(template_path);
+                                        if (!info->path) {
+                                                free(path);
+                                                free(template);
+                                                free(template_path);
+                                                return -ENOMEM;
+                                        }
+                                }
+
+                                free(template);
+                                free(template_path);
+                        }
+                        free(path);
+                }
+
+                if (r != -ENOENT && r != -ELOOP)
+                        return r;
+        }
+
+        return -ENOENT;
+}
+
+static int unit_file_can_install(
+                LookupPaths *paths,
+                const char *root_dir,
+                const char *name,
+                bool allow_symlink) {
+
+        InstallContext c;
+        InstallInfo *i;
+        int r;
+
+        assert(paths);
+        assert(name);
+
+        zero(c);
+
+        r = install_info_add_auto(&c, name);
+        if (r < 0)
+                return r;
+
+        assert_se(i = hashmap_first(c.will_install));
+
+        r = unit_file_search(&c, i, paths, root_dir, allow_symlink);
+
+        if (r >= 0)
+                r =
+                        strv_length(i->aliases) +
+                        strv_length(i->wanted_by) +
+                        strv_length(i->required_by);
+
+        install_context_done(&c);
+
+        return r;
+}
+
+static int create_symlink(
+                const char *old_path,
+                const char *new_path,
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        char *dest;
+        int r;
+
+        assert(old_path);
+        assert(new_path);
+
+        mkdir_parents_label(new_path, 0755);
+
+        if (symlink(old_path, new_path) >= 0) {
+                add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
+                return 0;
+        }
+
+        if (errno != EEXIST)
+                return -errno;
+
+        r = readlink_and_make_absolute(new_path, &dest);
+        if (r < 0)
+                return r;
+
+        if (path_equal(dest, old_path)) {
+                free(dest);
+                return 0;
+        }
+
+        free(dest);
+
+        if (!force)
+                return -EEXIST;
+
+        unlink(new_path);
+
+        if (symlink(old_path, new_path) >= 0) {
+                add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
+                add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
+                return 0;
+        }
+
+        return -errno;
+}
+
+static int install_info_symlink_alias(
+                InstallInfo *i,
+                const char *config_path,
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        char **s;
+        int r = 0, q;
+
+        assert(i);
+        assert(config_path);
+
+        STRV_FOREACH(s, i->aliases) {
+                char *alias_path;
+
+                alias_path = path_make_absolute(*s, config_path);
+
+                if (!alias_path)
+                        return -ENOMEM;
+
+                q = create_symlink(i->path, alias_path, force, changes, n_changes);
+                free(alias_path);
+
+                if (r == 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+static int install_info_symlink_wants(
+                InstallInfo *i,
+                const char *config_path,
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        char **s;
+        int r = 0, q;
+
+        assert(i);
+        assert(config_path);
+
+        STRV_FOREACH(s, i->wanted_by) {
+                char *path;
+
+                if (!unit_name_is_valid(*s, true)) {
+                        r = -EINVAL;
+                        continue;
+                }
+
+                if (asprintf(&path, "%s/%s.wants/%s", config_path, *s, i->name) < 0)
+                        return -ENOMEM;
+
+                q = create_symlink(i->path, path, force, changes, n_changes);
+                free(path);
+
+                if (r == 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+static int install_info_symlink_requires(
+                InstallInfo *i,
+                const char *config_path,
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        char **s;
+        int r = 0, q;
+
+        assert(i);
+        assert(config_path);
+
+        STRV_FOREACH(s, i->required_by) {
+                char *path;
+
+                if (!unit_name_is_valid(*s, true)) {
+                        r = -EINVAL;
+                        continue;
+                }
+
+                if (asprintf(&path, "%s/%s.requires/%s", config_path, *s, i->name) < 0)
+                        return -ENOMEM;
+
+                q = create_symlink(i->path, path, force, changes, n_changes);
+                free(path);
+
+                if (r == 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+static int install_info_symlink_link(
+                InstallInfo *i,
+                LookupPaths *paths,
+                const char *config_path,
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        int r;
+        char *path;
+
+        assert(i);
+        assert(paths);
+        assert(config_path);
+        assert(i->path);
+
+        r = in_search_path(i->path, paths->unit_path);
+        if (r != 0)
+                return r;
+
+        if (asprintf(&path, "%s/%s", config_path, i->name) < 0)
+                return -ENOMEM;
+
+        r = create_symlink(i->path, path, force, changes, n_changes);
+        free(path);
+
+        return r;
+}
+
+static int install_info_apply(
+                InstallInfo *i,
+                LookupPaths *paths,
+                const char *config_path,
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        int r, q;
+
+        assert(i);
+        assert(paths);
+        assert(config_path);
+
+        r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
+
+        q = install_info_symlink_wants(i, config_path, force, changes, n_changes);
+        if (r == 0)
+                r = q;
+
+        q = install_info_symlink_requires(i, config_path, force, changes, n_changes);
+        if (r == 0)
+                r = q;
+
+        q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes);
+        if (r == 0)
+                r = q;
+
+        return r;
+}
+
+static int install_context_apply(
+                InstallContext *c,
+                LookupPaths *paths,
+                const char *config_path,
+                const char *root_dir,
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        InstallInfo *i;
+        int r = 0, q;
+
+        assert(c);
+        assert(paths);
+        assert(config_path);
+
+        while ((i = hashmap_first(c->will_install))) {
+
+                q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
+                if (q < 0)
+                        return q;
+
+                assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
+
+                q = unit_file_search(c, i, paths, root_dir, false);
+                if (q < 0) {
+                        if (r >= 0)
+                                r = q;
+
+                        return r;
+                } else if (r >= 0)
+                        r += q;
+
+                q = install_info_apply(i, paths, config_path, force, changes, n_changes);
+                if (r >= 0 && q < 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+static int install_context_mark_for_removal(
+                InstallContext *c,
+                LookupPaths *paths,
+                Set **remove_symlinks_to,
+                const char *config_path,
+                const char *root_dir) {
+
+        InstallInfo *i;
+        int r = 0, q;
+
+        assert(c);
+        assert(paths);
+        assert(config_path);
+
+        /* Marks all items for removal */
+
+        while ((i = hashmap_first(c->will_install))) {
+
+                q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
+                if (q < 0)
+                        return q;
+
+                assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
+
+                q = unit_file_search(c, i, paths, root_dir, false);
+                if (q < 0) {
+                        if (r >= 0)
+                                r = q;
+
+                        return r;
+                } else if (r >= 0)
+                        r += q;
+
+                if (unit_name_is_instance(i->name)) {
+                        char *unit_file = NULL;
+
+                        unit_file = path_get_file_name(i->path);
+
+                        if (unit_name_is_instance(unit_file))
+                                /* unit file named as instance exists, thus all symlinks pointing to it, will be removed */
+                                q = mark_symlink_for_removal(remove_symlinks_to, i->name);
+                        else
+                                /* does not exist, thus we will mark for removal symlinks to template unit file */
+                                q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
+                } else
+                        q = mark_symlink_for_removal(remove_symlinks_to, i->name);
+
+                if (r >= 0 && q < 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+int unit_file_enable(
+                UnitFileScope scope,
+                bool runtime,
+                const char *root_dir,
+                char *files[],
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        LookupPaths paths;
+        InstallContext c;
+        char **i, *config_path = NULL;
+        int r;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        zero(paths);
+        zero(c);
+
+        r = lookup_paths_init_from_scope(&paths, scope);
+        if (r < 0)
+                return r;
+
+        r = get_config_path(scope, runtime, root_dir, &config_path);
+        if (r < 0)
+                goto finish;
+
+        STRV_FOREACH(i, files) {
+                r = install_info_add_auto(&c, *i);
+                if (r < 0)
+                        goto finish;
+        }
+
+        /* This will return the number of symlink rules that were
+        supposed to be created, not the ones actually created. This is
+        useful to determine whether the passed files had any
+        installation data at all. */
+        r = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
+
+finish:
+        install_context_done(&c);
+        lookup_paths_free(&paths);
+        free(config_path);
+
+        return r;
+}
+
+int unit_file_disable(
+                UnitFileScope scope,
+                bool runtime,
+                const char *root_dir,
+                char *files[],
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        LookupPaths paths;
+        InstallContext c;
+        char **i, *config_path = NULL;
+        Set *remove_symlinks_to = NULL;
+        int r, q;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        zero(paths);
+        zero(c);
+
+        r = lookup_paths_init_from_scope(&paths, scope);
+        if (r < 0)
+                return r;
+
+        r = get_config_path(scope, runtime, root_dir, &config_path);
+        if (r < 0)
+                goto finish;
+
+        STRV_FOREACH(i, files) {
+                r = install_info_add_auto(&c, *i);
+                if (r < 0)
+                        goto finish;
+        }
+
+        r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
+
+        q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+        if (r == 0)
+                r = q;
+
+finish:
+        install_context_done(&c);
+        lookup_paths_free(&paths);
+        set_free_free(remove_symlinks_to);
+        free(config_path);
+
+        return r;
+}
+
+int unit_file_reenable(
+                UnitFileScope scope,
+                bool runtime,
+                const char *root_dir,
+                char *files[],
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        LookupPaths paths;
+        InstallContext c;
+        char **i, *config_path = NULL;
+        Set *remove_symlinks_to = NULL;
+        int r, q;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        zero(paths);
+        zero(c);
+
+        r = lookup_paths_init_from_scope(&paths, scope);
+        if (r < 0)
+                return r;
+
+        r = get_config_path(scope, runtime, root_dir, &config_path);
+        if (r < 0)
+                goto finish;
+
+        STRV_FOREACH(i, files) {
+                r = mark_symlink_for_removal(&remove_symlinks_to, *i);
+                if (r < 0)
+                        goto finish;
+
+                r = install_info_add_auto(&c, *i);
+                if (r < 0)
+                        goto finish;
+        }
+
+        r = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+
+        /* Returns number of symlinks that where supposed to be installed. */
+        q = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
+        if (r == 0)
+                r = q;
+
+finish:
+        lookup_paths_free(&paths);
+        install_context_done(&c);
+        set_free_free(remove_symlinks_to);
+        free(config_path);
+
+        return r;
+}
+
+UnitFileState unit_file_get_state(
+                UnitFileScope scope,
+                const char *root_dir,
+                const char *name) {
+
+        LookupPaths paths;
+        UnitFileState state = _UNIT_FILE_STATE_INVALID;
+        char **i, *path = NULL;
+        int r;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+        assert(name);
+
+        zero(paths);
+
+        if (root_dir && scope != UNIT_FILE_SYSTEM)
+                return -EINVAL;
+
+        if (!unit_name_is_valid(name, true))
+                return -EINVAL;
+
+        r = lookup_paths_init_from_scope(&paths, scope);
+        if (r < 0)
+                return r;
+
+        STRV_FOREACH(i, paths.unit_path) {
+                struct stat st;
+
+                free(path);
+                path = NULL;
+
+                if (root_dir)
+                        asprintf(&path, "%s/%s/%s", root_dir, *i, name);
+                else
+                        asprintf(&path, "%s/%s", *i, name);
+
+                if (!path) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (lstat(path, &st) < 0) {
+                        r = -errno;
+                        if (errno == ENOENT)
+                                continue;
+
+                        goto finish;
+                }
+
+                if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
+                        r = -ENOENT;
+                        goto finish;
+                }
+
+                r = null_or_empty_path(path);
+                if (r < 0 && r != -ENOENT)
+                        goto finish;
+                else if (r > 0) {
+                        state = path_startswith(*i, "/run") ?
+                                UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
+                        r = 0;
+                        goto finish;
+                }
+
+                r = find_symlinks_in_scope(scope, root_dir, name, &state);
+                if (r < 0) {
+                        goto finish;
+                } else if (r > 0) {
+                        r = 0;
+                        goto finish;
+                }
+
+                r = unit_file_can_install(&paths, root_dir, path, true);
+                if (r < 0 && errno != -ENOENT)
+                        goto finish;
+                else if (r > 0) {
+                        state = UNIT_FILE_DISABLED;
+                        r = 0;
+                        goto finish;
+                } else if (r == 0) {
+                        state = UNIT_FILE_STATIC;
+                        r = 0;
+                        goto finish;
+                }
+        }
+
+finish:
+        lookup_paths_free(&paths);
+        free(path);
+
+        return r < 0 ? r : state;
+}
+
+int unit_file_query_preset(UnitFileScope scope, const char *name) {
+        char **files, **i;
+        int r;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+        assert(name);
+
+        if (scope == UNIT_FILE_SYSTEM)
+                r = conf_files_list(&files, ".preset",
+                                    "/etc/systemd/system-preset",
+                                    "/usr/local/lib/systemd/system-preset",
+                                    "/usr/lib/systemd/system-preset",
+#ifdef HAVE_SPLIT_USR
+                                    "/lib/systemd/system-preset",
+#endif
+                                    NULL);
+        else if (scope == UNIT_FILE_GLOBAL)
+                r = conf_files_list(&files, ".preset",
+                                    "/etc/systemd/user-preset",
+                                    "/usr/local/lib/systemd/user-preset",
+                                    "/usr/lib/systemd/user-preset",
+                                    NULL);
+        else
+                return 1;
+
+        if (r < 0)
+                return r;
+
+        STRV_FOREACH(i, files) {
+                FILE *f;
+
+                f = fopen(*i, "re");
+                if (!f) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        r = -errno;
+                        goto finish;
+                }
+
+                for (;;) {
+                        char line[LINE_MAX], *l;
+
+                        if (!fgets(line, sizeof(line), f))
+                                break;
+
+                        l = strstrip(line);
+                        if (!*l)
+                                continue;
+
+                        if (strchr(COMMENTS, *l))
+                                continue;
+
+                        if (first_word(l, "enable")) {
+                                l += 6;
+                                l += strspn(l, WHITESPACE);
+
+                                if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
+                                        r = 1;
+                                        fclose(f);
+                                        goto finish;
+                                }
+                        } else if (first_word(l, "disable")) {
+                                l += 7;
+                                l += strspn(l, WHITESPACE);
+
+                                if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
+                                        r = 0;
+                                        fclose(f);
+                                        goto finish;
+                                }
+                        } else
+                                log_debug("Couldn't parse line '%s'", l);
+                }
+
+                fclose(f);
+        }
+
+        /* Default is "enable" */
+        r = 1;
+
+finish:
+        strv_free(files);
+
+        return r;
+}
+
+int unit_file_preset(
+                UnitFileScope scope,
+                bool runtime,
+                const char *root_dir,
+                char *files[],
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        LookupPaths paths;
+        InstallContext plus, minus;
+        char **i, *config_path = NULL;
+        Set *remove_symlinks_to = NULL;
+        int r, q;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        zero(paths);
+        zero(plus);
+        zero(minus);
+
+        r = lookup_paths_init_from_scope(&paths, scope);
+        if (r < 0)
+                return r;
+
+        r = get_config_path(scope, runtime, root_dir, &config_path);
+        if (r < 0)
+                goto finish;
+
+        STRV_FOREACH(i, files) {
+
+                if (!unit_name_is_valid(*i, true)) {
+                        r = -EINVAL;
+                        goto finish;
+                }
+
+                r = unit_file_query_preset(scope, *i);
+                if (r < 0)
+                        goto finish;
+
+                if (r)
+                        r = install_info_add_auto(&plus, *i);
+                else
+                        r = install_info_add_auto(&minus, *i);
+
+                if (r < 0)
+                        goto finish;
+        }
+
+        r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
+
+        q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+        if (r == 0)
+                r = q;
+
+        /* Returns number of symlinks that where supposed to be installed. */
+        q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
+        if (r == 0)
+                r = q;
+
+finish:
+        lookup_paths_free(&paths);
+        install_context_done(&plus);
+        install_context_done(&minus);
+        set_free_free(remove_symlinks_to);
+        free(config_path);
+
+        return r;
+}
+
+int unit_file_get_list(
+                UnitFileScope scope,
+                const char *root_dir,
+                Hashmap *h) {
+
+        LookupPaths paths;
+        char **i, *buf = NULL;
+        DIR *d = NULL;
+        int r;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+        assert(h);
+
+        zero(paths);
+
+        if (root_dir && scope != UNIT_FILE_SYSTEM)
+                return -EINVAL;
+
+        r = lookup_paths_init_from_scope(&paths, scope);
+        if (r < 0)
+                return r;
+
+        STRV_FOREACH(i, paths.unit_path) {
+                const char *units_dir;
+
+                free(buf);
+                buf = NULL;
+
+                if (root_dir) {
+                        if (asprintf(&buf, "%s/%s", root_dir, *i) < 0) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+                        units_dir = buf;
+                } else
+                        units_dir = *i;
+
+                if (d)
+                        closedir(d);
+
+                d = opendir(units_dir);
+                if (!d) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        r = -errno;
+                        goto finish;
+                }
+
+                for (;;) {
+                        struct dirent *de;
+                        union dirent_storage buffer;
+                        UnitFileList *f;
+
+                        r = readdir_r(d, &buffer.de, &de);
+                        if (r != 0) {
+                                r = -r;
+                                goto finish;
+                        }
+
+                        if (!de)
+                                break;
+
+                        if (ignore_file(de->d_name))
+                                continue;
+
+                        if (!unit_name_is_valid(de->d_name, true))
+                                continue;
+
+                        if (hashmap_get(h, de->d_name))
+                                continue;
+
+                        r = dirent_ensure_type(d, de);
+                        if (r < 0) {
+                                if (r == -ENOENT)
+                                        continue;
+
+                                goto finish;
+                        }
+
+                        if (de->d_type != DT_LNK && de->d_type != DT_REG)
+                                continue;
+
+                        f = new0(UnitFileList, 1);
+                        if (!f) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        f->path = path_make_absolute(de->d_name, units_dir);
+                        if (!f->path) {
+                                free(f);
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        r = null_or_empty_path(f->path);
+                        if (r < 0 && r != -ENOENT) {
+                                free(f->path);
+                                free(f);
+                                goto finish;
+                        } else if (r > 0) {
+                                f->state =
+                                        path_startswith(*i, "/run") ?
+                                        UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
+                                goto found;
+                        }
+
+                        r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
+                        if (r < 0) {
+                                free(f->path);
+                                free(f);
+                                goto finish;
+                        } else if (r > 0) {
+                                f->state = UNIT_FILE_ENABLED;
+                                goto found;
+                        }
+
+                        r = unit_file_can_install(&paths, root_dir, f->path, true);
+                        if (r == -EINVAL ||  /* Invalid setting? */
+                            r == -EBADMSG || /* Invalid format? */
+                            r == -ENOENT     /* Included file not found? */)
+                                f->state = UNIT_FILE_INVALID;
+                        else if (r < 0) {
+                                free(f->path);
+                                free(f);
+                                goto finish;
+                        } else if (r > 0)
+                                f->state = UNIT_FILE_DISABLED;
+                        else
+                                f->state = UNIT_FILE_STATIC;
+
+                found:
+                        r = hashmap_put(h, path_get_file_name(f->path), f);
+                        if (r < 0) {
+                                free(f->path);
+                                free(f);
+                                goto finish;
+                        }
+                }
+        }
+
+finish:
+        lookup_paths_free(&paths);
+        free(buf);
+
+        if (d)
+                closedir(d);
+
+        return r;
+}
+
+static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
+        [UNIT_FILE_ENABLED] = "enabled",
+        [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
+        [UNIT_FILE_LINKED] = "linked",
+        [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
+        [UNIT_FILE_MASKED] = "masked",
+        [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
+        [UNIT_FILE_STATIC] = "static",
+        [UNIT_FILE_DISABLED] = "disabled",
+        [UNIT_FILE_INVALID] = "invalid",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
+
+static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
+        [UNIT_FILE_SYMLINK] = "symlink",
+        [UNIT_FILE_UNLINK] = "unlink",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
diff --git a/src/shared/install.h b/src/shared/install.h
new file mode 100644 (file)
index 0000000..5524991
--- /dev/null
@@ -0,0 +1,87 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "hashmap.h"
+
+typedef enum UnitFileScope {
+        UNIT_FILE_SYSTEM,
+        UNIT_FILE_GLOBAL,
+        UNIT_FILE_USER,
+        _UNIT_FILE_SCOPE_MAX,
+        _UNIT_FILE_SCOPE_INVALID = -1
+} UnitFileScope;
+
+typedef enum UnitFileState {
+        UNIT_FILE_ENABLED,
+        UNIT_FILE_ENABLED_RUNTIME,
+        UNIT_FILE_LINKED,
+        UNIT_FILE_LINKED_RUNTIME,
+        UNIT_FILE_MASKED,
+        UNIT_FILE_MASKED_RUNTIME,
+        UNIT_FILE_STATIC,
+        UNIT_FILE_DISABLED,
+        UNIT_FILE_INVALID,
+        _UNIT_FILE_STATE_MAX,
+        _UNIT_FILE_STATE_INVALID = -1
+} UnitFileState;
+
+typedef enum UnitFileChangeType {
+        UNIT_FILE_SYMLINK,
+        UNIT_FILE_UNLINK,
+        _UNIT_FILE_CHANGE_TYPE_MAX,
+        _UNIT_FILE_CHANGE_TYPE_INVALID = -1
+} UnitFileChangeType;
+
+typedef struct UnitFileChange {
+        UnitFileChangeType type;
+        char *path;
+        char *source;
+} UnitFileChange;
+
+typedef struct UnitFileList {
+        char *path;
+        UnitFileState state;
+} UnitFileList;
+
+int unit_file_enable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_disable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes);
+int unit_file_reenable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes);
+
+UnitFileState unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename);
+
+int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h);
+
+void unit_file_list_free(Hashmap *h);
+void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes);
+
+int unit_file_query_preset(UnitFileScope scope, const char *name);
+
+const char *unit_file_state_to_string(UnitFileState s);
+UnitFileState unit_file_state_from_string(const char *s);
+
+const char *unit_file_change_type_to_string(UnitFileChangeType s);
+UnitFileChangeType unit_file_change_type_from_string(const char *s);
diff --git a/src/shared/ioprio.h b/src/shared/ioprio.h
new file mode 100644 (file)
index 0000000..9800fc2
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef IOPRIO_H
+#define IOPRIO_H
+
+/* This is minimal version of Linux' linux/ioprio.h header file, which
+ * is licensed GPL2 */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+/*
+ * Gives us 8 prio classes with 13-bits of data for each class
+ */
+#define IOPRIO_BITS             (16)
+#define IOPRIO_CLASS_SHIFT      (13)
+#define IOPRIO_PRIO_MASK        ((1UL << IOPRIO_CLASS_SHIFT) - 1)
+
+#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
+#define IOPRIO_PRIO_DATA(mask)  ((mask) & IOPRIO_PRIO_MASK)
+#define IOPRIO_PRIO_VALUE(class, data)  (((class) << IOPRIO_CLASS_SHIFT) | data)
+
+#define ioprio_valid(mask)      (IOPRIO_PRIO_CLASS((mask)) != IOPRIO_CLASS_NONE)
+
+/*
+ * These are the io priority groups as implemented by CFQ. RT is the realtime
+ * class, it always gets premium service. BE is the best-effort scheduling
+ * class, the default for any process. IDLE is the idle scheduling class, it
+ * is only served when no one else is using the disk.
+ */
+enum {
+        IOPRIO_CLASS_NONE,
+        IOPRIO_CLASS_RT,
+        IOPRIO_CLASS_BE,
+        IOPRIO_CLASS_IDLE,
+};
+
+/*
+ * 8 best effort priority levels are supported
+ */
+#define IOPRIO_BE_NR    (8)
+
+enum {
+        IOPRIO_WHO_PROCESS = 1,
+        IOPRIO_WHO_PGRP,
+        IOPRIO_WHO_USER,
+};
+
+static inline int ioprio_set(int which, int who, int ioprio)
+{
+        return syscall(__NR_ioprio_set, which, who, ioprio);
+}
+
+static inline int ioprio_get(int which, int who)
+{
+        return syscall(__NR_ioprio_get, which, who);
+}
+
+#endif
diff --git a/src/shared/label.c b/src/shared/label.c
new file mode 100644 (file)
index 0000000..d353da5
--- /dev/null
@@ -0,0 +1,382 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "label.h"
+#include "util.h"
+#include "path-util.h"
+
+#ifdef HAVE_SELINUX
+#include "selinux-util.h"
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+
+static struct selabel_handle *label_hnd = NULL;
+
+#endif
+
+int label_init(const char *prefix) {
+        int r = 0;
+
+#ifdef HAVE_SELINUX
+        usec_t before_timestamp, after_timestamp;
+        struct mallinfo before_mallinfo, after_mallinfo;
+
+        if (!use_selinux())
+                return 0;
+
+        if (label_hnd)
+                return 0;
+
+        before_mallinfo = mallinfo();
+        before_timestamp = now(CLOCK_MONOTONIC);
+
+        if (prefix) {
+                struct selinux_opt options[] = {
+                        { .type = SELABEL_OPT_SUBSET, .value = prefix },
+                };
+
+                label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options));
+        } else
+                label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+
+        if (!label_hnd) {
+                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
+                         "Failed to initialize SELinux context: %m");
+                r = security_getenforce() == 1 ? -errno : 0;
+        } else  {
+                char timespan[FORMAT_TIMESPAN_MAX];
+                int l;
+
+                after_timestamp = now(CLOCK_MONOTONIC);
+                after_mallinfo = mallinfo();
+
+                l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0;
+
+                log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
+                          format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp),
+                          (l+1023)/1024);
+        }
+#endif
+
+        return r;
+}
+
+int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
+        int r = 0;
+
+#ifdef HAVE_SELINUX
+        struct stat st;
+        security_context_t fcon;
+
+        if (!use_selinux() || !label_hnd)
+                return 0;
+
+        r = lstat(path, &st);
+        if (r == 0) {
+                r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);
+
+                /* If there's no label to set, then exit without warning */
+                if (r < 0 && errno == ENOENT)
+                        return 0;
+
+                if (r == 0) {
+                        r = lsetfilecon(path, fcon);
+                        freecon(fcon);
+
+                        /* If the FS doesn't support labels, then exit without warning */
+                        if (r < 0 && errno == ENOTSUP)
+                                return 0;
+                }
+        }
+
+        if (r < 0) {
+                /* Ignore ENOENT in some cases */
+                if (ignore_enoent && errno == ENOENT)
+                        return 0;
+
+                if (ignore_erofs && errno == EROFS)
+                        return 0;
+
+                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
+                         "Unable to fix label of %s: %m", path);
+                r = security_getenforce() == 1 ? -errno : 0;
+        }
+#endif
+
+        return r;
+}
+
+void label_finish(void) {
+
+#ifdef HAVE_SELINUX
+        if (use_selinux() && label_hnd)
+                selabel_close(label_hnd);
+#endif
+}
+
+int label_get_create_label_from_exe(const char *exe, char **label) {
+
+        int r = 0;
+
+#ifdef HAVE_SELINUX
+        security_context_t mycon = NULL, fcon = NULL;
+        security_class_t sclass;
+
+        if (!use_selinux()) {
+                *label = NULL;
+                return 0;
+        }
+
+        r = getcon(&mycon);
+        if (r < 0)
+                goto fail;
+
+        r = getfilecon(exe, &fcon);
+        if (r < 0)
+                goto fail;
+
+        sclass = string_to_security_class("process");
+        r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
+        if (r == 0)
+                log_debug("SELinux Socket context for %s will be set to %s", exe, *label);
+
+fail:
+        if (r < 0 && security_getenforce() == 1)
+                r = -errno;
+
+        freecon(mycon);
+        freecon(fcon);
+#endif
+
+        return r;
+}
+
+int label_context_set(const char *path, mode_t mode) {
+        int r = 0;
+
+#ifdef HAVE_SELINUX
+        security_context_t filecon = NULL;
+
+        if (!use_selinux() || !label_hnd)
+                return 0;
+
+        r = selabel_lookup_raw(label_hnd, &filecon, path, mode);
+        if (r < 0 && errno != ENOENT)
+                r = -errno;
+        else if (r == 0) {
+                r = setfscreatecon(filecon);
+                if (r < 0) {
+                        log_error("Failed to set SELinux file context on %s: %m", path);
+                        r = -errno;
+                }
+
+                freecon(filecon);
+        }
+
+        if (r < 0 && security_getenforce() == 0)
+                r = 0;
+#endif
+
+        return r;
+}
+
+int label_socket_set(const char *label) {
+
+#ifdef HAVE_SELINUX
+        if (!use_selinux())
+                return 0;
+
+        if (setsockcreatecon((security_context_t) label) < 0) {
+                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
+                         "Failed to set SELinux context (%s) on socket: %m", label);
+
+                if (security_getenforce() == 1)
+                        return -errno;
+        }
+#endif
+
+        return 0;
+}
+
+void label_context_clear(void) {
+
+#ifdef HAVE_SELINUX
+        if (!use_selinux())
+                return;
+
+        setfscreatecon(NULL);
+#endif
+}
+
+void label_socket_clear(void) {
+
+#ifdef HAVE_SELINUX
+        if (!use_selinux())
+                return;
+
+        setsockcreatecon(NULL);
+#endif
+}
+
+void label_free(const char *label) {
+
+#ifdef HAVE_SELINUX
+        if (!use_selinux())
+                return;
+
+        freecon((security_context_t) label);
+#endif
+}
+
+int label_mkdir(const char *path, mode_t mode, bool apply) {
+
+        /* Creates a directory and labels it according to the SELinux policy */
+#ifdef HAVE_SELINUX
+        int r;
+        security_context_t fcon = NULL;
+
+        if (!apply || !use_selinux() || !label_hnd)
+                goto skipped;
+
+        if (path_is_absolute(path))
+                r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFDIR);
+        else {
+                char *newpath;
+
+                newpath = path_make_absolute_cwd(path);
+                if (!newpath)
+                        return -ENOMEM;
+
+                r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFDIR);
+                free(newpath);
+        }
+
+        if (r == 0)
+                r = setfscreatecon(fcon);
+
+        if (r < 0 && errno != ENOENT) {
+                log_error("Failed to set security context %s for %s: %m", fcon, path);
+
+                if (security_getenforce() == 1) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        r = mkdir(path, mode);
+        if (r < 0)
+                r = -errno;
+
+finish:
+        setfscreatecon(NULL);
+        freecon(fcon);
+
+        return r;
+
+skipped:
+#endif
+        return mkdir(path, mode) < 0 ? -errno : 0;
+}
+
+int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
+
+        /* Binds a socket and label its file system object according to the SELinux policy */
+
+#ifdef HAVE_SELINUX
+        int r;
+        security_context_t fcon = NULL;
+        const struct sockaddr_un *un;
+        char *path = NULL;
+
+        assert(fd >= 0);
+        assert(addr);
+        assert(addrlen >= sizeof(sa_family_t));
+
+        if (!use_selinux() || !label_hnd)
+                goto skipped;
+
+        /* Filter out non-local sockets */
+        if (addr->sa_family != AF_UNIX)
+                goto skipped;
+
+        /* Filter out anonymous sockets */
+        if (addrlen < sizeof(sa_family_t) + 1)
+                goto skipped;
+
+        /* Filter out abstract namespace sockets */
+        un = (const struct sockaddr_un*) addr;
+        if (un->sun_path[0] == 0)
+                goto skipped;
+
+        path = strndup(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path));
+        if (!path)
+                return -ENOMEM;
+
+        if (path_is_absolute(path))
+                r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
+        else {
+                char *newpath;
+
+                newpath = path_make_absolute_cwd(path);
+
+                if (!newpath) {
+                        free(path);
+                        return -ENOMEM;
+                }
+
+                r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK);
+                free(newpath);
+        }
+
+        if (r == 0)
+                r = setfscreatecon(fcon);
+
+        if (r < 0 && errno != ENOENT) {
+                log_error("Failed to set security context %s for %s: %m", fcon, path);
+
+                if (security_getenforce() == 1) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        r = bind(fd, addr, addrlen);
+        if (r < 0)
+                r = -errno;
+
+finish:
+        setfscreatecon(NULL);
+        freecon(fcon);
+        free(path);
+
+        return r;
+
+skipped:
+#endif
+        return bind(fd, addr, addrlen) < 0 ? -errno : 0;
+}
diff --git a/src/shared/label.h b/src/shared/label.h
new file mode 100644 (file)
index 0000000..1220b18
--- /dev/null
@@ -0,0 +1,47 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+
+int label_init(const char *prefix);
+void label_finish(void);
+
+int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
+
+int label_socket_set(const char *label);
+void label_socket_clear(void);
+
+int label_context_set(const char *path, mode_t mode);
+void label_context_clear(void);
+
+void label_free(const char *label);
+
+int label_get_create_label_from_exe(const char *exe, char **label);
+
+int label_mkdir(const char *path, mode_t mode, bool apply);
+
+void label_retest_selinux(void);
+
+int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
diff --git a/src/shared/linux/Makefile b/src/shared/linux/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/shared/linux/auto_dev-ioctl.h b/src/shared/linux/auto_dev-ioctl.h
new file mode 100644 (file)
index 0000000..850f39b
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
+ * Copyright 2008 Ian Kent <raven@themaw.net>
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ */
+
+#ifndef _LINUX_AUTO_DEV_IOCTL_H
+#define _LINUX_AUTO_DEV_IOCTL_H
+
+#include <linux/auto_fs.h>
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+#else
+#include <string.h>
+#endif /* __KERNEL__ */
+
+#define AUTOFS_DEVICE_NAME             "autofs"
+
+#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
+#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
+
+#define AUTOFS_DEVID_LEN               16
+
+#define AUTOFS_DEV_IOCTL_SIZE          sizeof(struct autofs_dev_ioctl)
+
+/*
+ * An ioctl interface for autofs mount point control.
+ */
+
+struct args_protover {
+       __u32   version;
+};
+
+struct args_protosubver {
+       __u32   sub_version;
+};
+
+struct args_openmount {
+       __u32   devid;
+};
+
+struct args_ready {
+       __u32   token;
+};
+
+struct args_fail {
+       __u32   token;
+       __s32   status;
+};
+
+struct args_setpipefd {
+       __s32   pipefd;
+};
+
+struct args_timeout {
+       __u64   timeout;
+};
+
+struct args_requester {
+       __u32   uid;
+       __u32   gid;
+};
+
+struct args_expire {
+       __u32   how;
+};
+
+struct args_askumount {
+       __u32   may_umount;
+};
+
+struct args_ismountpoint {
+       union {
+               struct args_in {
+                       __u32   type;
+               } in;
+               struct args_out {
+                       __u32   devid;
+                       __u32   magic;
+               } out;
+       };
+};
+
+/*
+ * All the ioctls use this structure.
+ * When sending a path size must account for the total length
+ * of the chunk of memory otherwise is is the size of the
+ * structure.
+ */
+
+struct autofs_dev_ioctl {
+       __u32 ver_major;
+       __u32 ver_minor;
+       __u32 size;             /* total size of data passed in
+                                * including this struct */
+       __s32 ioctlfd;          /* automount command fd */
+
+       /* Command parameters */
+
+       union {
+               struct args_protover            protover;
+               struct args_protosubver         protosubver;
+               struct args_openmount           openmount;
+               struct args_ready               ready;
+               struct args_fail                fail;
+               struct args_setpipefd           setpipefd;
+               struct args_timeout             timeout;
+               struct args_requester           requester;
+               struct args_expire              expire;
+               struct args_askumount           askumount;
+               struct args_ismountpoint        ismountpoint;
+       };
+
+       char path[0];
+};
+
+static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
+{
+       memset(in, 0, sizeof(struct autofs_dev_ioctl));
+       in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
+       in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
+       in->size = sizeof(struct autofs_dev_ioctl);
+       in->ioctlfd = -1;
+       return;
+}
+
+/*
+ * If you change this make sure you make the corresponding change
+ * to autofs-dev-ioctl.c:lookup_ioctl()
+ */
+enum {
+       /* Get various version info */
+       AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
+       AUTOFS_DEV_IOCTL_PROTOVER_CMD,
+       AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD,
+
+       /* Open mount ioctl fd */
+       AUTOFS_DEV_IOCTL_OPENMOUNT_CMD,
+
+       /* Close mount ioctl fd */
+       AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD,
+
+       /* Mount/expire status returns */
+       AUTOFS_DEV_IOCTL_READY_CMD,
+       AUTOFS_DEV_IOCTL_FAIL_CMD,
+
+       /* Activate/deactivate autofs mount */
+       AUTOFS_DEV_IOCTL_SETPIPEFD_CMD,
+       AUTOFS_DEV_IOCTL_CATATONIC_CMD,
+
+       /* Expiry timeout */
+       AUTOFS_DEV_IOCTL_TIMEOUT_CMD,
+
+       /* Get mount last requesting uid and gid */
+       AUTOFS_DEV_IOCTL_REQUESTER_CMD,
+
+       /* Check for eligible expire candidates */
+       AUTOFS_DEV_IOCTL_EXPIRE_CMD,
+
+       /* Request busy status */
+       AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD,
+
+       /* Check if path is a mountpoint */
+       AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
+};
+
+#define AUTOFS_IOCTL 0x93
+
+#define AUTOFS_DEV_IOCTL_VERSION \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_PROTOVER \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_PROTOSUBVER \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_OPENMOUNT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_READY \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_FAIL \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_SETPIPEFD \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_CATATONIC \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_TIMEOUT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_REQUESTER \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_EXPIRE \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_ASKUMOUNT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
+
+#endif /* _LINUX_AUTO_DEV_IOCTL_H */
diff --git a/src/shared/linux/fanotify.h b/src/shared/linux/fanotify.h
new file mode 100644 (file)
index 0000000..63531a6
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef _LINUX_FANOTIFY_H
+#define _LINUX_FANOTIFY_H
+
+#include <linux/types.h>
+
+/* the following events that user-space can register for */
+#define FAN_ACCESS             0x00000001      /* File was accessed */
+#define FAN_MODIFY             0x00000002      /* File was modified */
+#define FAN_CLOSE_WRITE                0x00000008      /* Unwrittable file closed */
+#define FAN_CLOSE_NOWRITE      0x00000010      /* Writtable file closed */
+#define FAN_OPEN               0x00000020      /* File was opened */
+
+#define FAN_EVENT_ON_CHILD     0x08000000      /* interested in child events */
+
+/* FIXME currently Q's have no limit.... */
+#define FAN_Q_OVERFLOW         0x00004000      /* Event queued overflowed */
+
+#define FAN_OPEN_PERM          0x00010000      /* File open in perm check */
+#define FAN_ACCESS_PERM                0x00020000      /* File accessed in perm check */
+
+/* helper events */
+#define FAN_CLOSE              (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */
+
+/* flags used for fanotify_init() */
+#define FAN_CLOEXEC            0x00000001
+#define FAN_NONBLOCK           0x00000002
+
+#define FAN_ALL_INIT_FLAGS     (FAN_CLOEXEC | FAN_NONBLOCK)
+
+/* flags used for fanotify_modify_mark() */
+#define FAN_MARK_ADD           0x00000001
+#define FAN_MARK_REMOVE                0x00000002
+#define FAN_MARK_DONT_FOLLOW   0x00000004
+#define FAN_MARK_ONLYDIR       0x00000008
+#define FAN_MARK_MOUNT         0x00000010
+#define FAN_MARK_IGNORED_MASK  0x00000020
+#define FAN_MARK_IGNORED_SURV_MODIFY   0x00000040
+#define FAN_MARK_FLUSH         0x00000080
+
+#define FAN_ALL_MARK_FLAGS     (FAN_MARK_ADD |\
+                                FAN_MARK_REMOVE |\
+                                FAN_MARK_DONT_FOLLOW |\
+                                FAN_MARK_ONLYDIR |\
+                                FAN_MARK_MOUNT |\
+                                FAN_MARK_IGNORED_MASK |\
+                                FAN_MARK_IGNORED_SURV_MODIFY)
+
+/*
+ * All of the events - we build the list by hand so that we can add flags in
+ * the future and not break backward compatibility.  Apps will get only the
+ * events that they originally wanted.  Be sure to add new events here!
+ */
+#define FAN_ALL_EVENTS (FAN_ACCESS |\
+                       FAN_MODIFY |\
+                       FAN_CLOSE |\
+                       FAN_OPEN)
+
+/*
+ * All events which require a permission response from userspace
+ */
+#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM |\
+                            FAN_ACCESS_PERM)
+
+#define FAN_ALL_OUTGOING_EVENTS        (FAN_ALL_EVENTS |\
+                                FAN_ALL_PERM_EVENTS |\
+                                FAN_Q_OVERFLOW)
+
+#define FANOTIFY_METADATA_VERSION      2
+
+struct fanotify_event_metadata {
+       __u32 event_len;
+       __u32 vers;
+       __u64 mask;
+       __s32 fd;
+       __s32 pid;
+} __attribute__ ((packed));
+
+struct fanotify_response {
+       __s32 fd;
+       __u32 response;
+} __attribute__ ((packed));
+
+/* Legit userspace responses to a _PERM event */
+#define FAN_ALLOW      0x01
+#define FAN_DENY       0x02
+
+/* Helper functions to deal with fanotify_event_metadata buffers */
+#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
+
+#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, \
+                                  (struct fanotify_event_metadata*)(((char *)(meta)) + \
+                                  (meta)->event_len))
+
+#define FAN_EVENT_OK(meta, len)        ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && \
+                               (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \
+                               (long)(meta)->event_len <= (long)(len))
+
+#endif /* _LINUX_FANOTIFY_H */
diff --git a/src/shared/linux/seccomp-bpf.h b/src/shared/linux/seccomp-bpf.h
new file mode 100644 (file)
index 0000000..1e3d136
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * seccomp example for x86 (32-bit and 64-bit) with BPF macros
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Authors:
+ *  Will Drewry <wad@chromium.org>
+ *  Kees Cook <keescook@chromium.org>
+ *
+ * The code may be used by anyone for any purpose, and can serve as a
+ * starting point for developing applications using mode 2 seccomp.
+ */
+#ifndef _SECCOMP_BPF_H_
+#define _SECCOMP_BPF_H_
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/prctl.h>
+
+#include <linux/unistd.h>
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+
+#ifndef SECCOMP_MODE_FILTER
+# define SECCOMP_MODE_FILTER   2 /* uses user-supplied filter. */
+# define SECCOMP_RET_KILL      0x00000000U /* kill the task immediately */
+# define SECCOMP_RET_TRAP      0x00030000U /* disallow and force a SIGSYS */
+# define SECCOMP_RET_ALLOW     0x7fff0000U /* allow */
+struct seccomp_data {
+    int nr;
+    __u32 arch;
+    __u64 instruction_pointer;
+    __u64 args[6];
+};
+#endif
+#ifndef SYS_SECCOMP
+# define SYS_SECCOMP 1
+#endif
+
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+#define arch_nr (offsetof(struct seccomp_data, arch))
+
+#if defined(__i386__)
+# define REG_SYSCALL   REG_EAX
+# define ARCH_NR       AUDIT_ARCH_I386
+#elif defined(__x86_64__)
+# define REG_SYSCALL   REG_RAX
+# define ARCH_NR       AUDIT_ARCH_X86_64
+#else
+# warning "Platform does not support seccomp filter yet"
+# define REG_SYSCALL   0
+# define ARCH_NR       0
+#endif
+
+#define VALIDATE_ARCHITECTURE \
+       BPF_STMT(BPF_LD+BPF_W+BPF_ABS, arch_nr), \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \
+       BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
+
+#define EXAMINE_SYSCALL \
+       BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr)
+
+#define ALLOW_SYSCALL(name) \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1), \
+       BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
+
+#define _KILL_PROCESS \
+       BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
+
+#endif /* _SECCOMP_BPF_H_ */
diff --git a/src/shared/linux/seccomp.h b/src/shared/linux/seccomp.h
new file mode 100644 (file)
index 0000000..9c03683
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _LINUX_SECCOMP_H
+#define _LINUX_SECCOMP_H
+
+
+#include <linux/types.h>
+
+
+/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
+#define SECCOMP_MODE_DISABLED  0 /* seccomp is not in use. */
+#define SECCOMP_MODE_STRICT    1 /* uses hard-coded filter. */
+#define SECCOMP_MODE_FILTER    2 /* uses user-supplied filter. */
+
+/*
+ * All BPF programs must return a 32-bit value.
+ * The bottom 16-bits are for optional return data.
+ * The upper 16-bits are ordered from least permissive values to most.
+ *
+ * The ordering ensures that a min_t() over composed return values always
+ * selects the least permissive choice.
+ */
+#define SECCOMP_RET_KILL       0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_TRAP       0x00030000U /* disallow and force a SIGSYS */
+#define SECCOMP_RET_ERRNO      0x00050000U /* returns an errno */
+#define SECCOMP_RET_TRACE      0x7ff00000U /* pass to a tracer or disallow */
+#define SECCOMP_RET_ALLOW      0x7fff0000U /* allow */
+
+/* Masks for the return value sections. */
+#define SECCOMP_RET_ACTION     0x7fff0000U
+#define SECCOMP_RET_DATA       0x0000ffffU
+
+/**
+ * struct seccomp_data - the format the BPF program executes over.
+ * @nr: the system call number
+ * @arch: indicates system call convention as an AUDIT_ARCH_* value
+ *        as defined in <linux/audit.h>.
+ * @instruction_pointer: at the time of the system call.
+ * @args: up to 6 system call arguments always stored as 64-bit values
+ *        regardless of the architecture.
+ */
+struct seccomp_data {
+       int nr;
+       __u32 arch;
+       __u64 instruction_pointer;
+       __u64 args[6];
+};
+
+#endif /* _LINUX_SECCOMP_H */
diff --git a/src/shared/list.h b/src/shared/list.h
new file mode 100644 (file)
index 0000000..47f275a
--- /dev/null
@@ -0,0 +1,125 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* The head of the linked list. Use this in the structure that shall
+ * contain the head of the linked list */
+#define LIST_HEAD(t,name)                                               \
+        t *name
+
+/* The pointers in the linked list's items. Use this in the item structure */
+#define LIST_FIELDS(t,name)                                             \
+        t *name##_next, *name##_prev
+
+/* Initialize the list's head */
+#define LIST_HEAD_INIT(t,head)                                          \
+        do {                                                            \
+                (head) = NULL; }                                        \
+        while(false)
+
+/* Initialize a list item */
+#define LIST_INIT(t,name,item)                                          \
+        do {                                                            \
+                t *_item = (item);                                      \
+                assert(_item);                                          \
+                _item->name##_prev = _item->name##_next = NULL;         \
+        } while(false)
+
+/* Prepend an item to the list */
+#define LIST_PREPEND(t,name,head,item)                                  \
+        do {                                                            \
+                t **_head = &(head), *_item = (item);                   \
+                assert(_item);                                          \
+                if ((_item->name##_next = *_head))                      \
+                        _item->name##_next->name##_prev = _item;        \
+                _item->name##_prev = NULL;                              \
+                *_head = _item;                                         \
+        } while(false)
+
+/* Remove an item from the list */
+#define LIST_REMOVE(t,name,head,item)                                   \
+        do {                                                            \
+                t **_head = &(head), *_item = (item);                   \
+                assert(_item);                                          \
+                if (_item->name##_next)                                 \
+                        _item->name##_next->name##_prev = _item->name##_prev; \
+                if (_item->name##_prev)                                 \
+                        _item->name##_prev->name##_next = _item->name##_next; \
+                else {                                                  \
+                        assert(*_head == _item);                        \
+                        *_head = _item->name##_next;                    \
+                }                                                       \
+                _item->name##_next = _item->name##_prev = NULL;         \
+        } while(false)
+
+/* Find the head of the list */
+#define LIST_FIND_HEAD(t,name,item,head)                                \
+        do {                                                            \
+                t *_item = (item);                                      \
+                assert(_item);                                          \
+                while (_item->name##_prev)                              \
+                       _item = _item->name##_prev;                      \
+                (head) = _item;                                         \
+        } while (false)
+
+/* Find the head of the list */
+#define LIST_FIND_TAIL(t,name,item,tail)                                \
+        do {                                                            \
+                t *_item = (item);                                      \
+                assert(_item);                                          \
+                while (_item->name##_next)                              \
+                        _item = _item->name##_next;                     \
+                (tail) = _item;                                         \
+        } while (false)
+
+/* Insert an item after another one (a = where, b = what) */
+#define LIST_INSERT_AFTER(t,name,head,a,b)                              \
+        do {                                                            \
+                t **_head = &(head), *_a = (a), *_b = (b);              \
+                assert(_b);                                             \
+                if (!_a) {                                              \
+                        if ((_b->name##_next = *_head))                 \
+                                _b->name##_next->name##_prev = _b;      \
+                        _b->name##_prev = NULL;                         \
+                        *_head = _b;                                    \
+                } else {                                                \
+                        if ((_b->name##_next = _a->name##_next))        \
+                                _b->name##_next->name##_prev = _b;      \
+                        _b->name##_prev = _a;                           \
+                        _a->name##_next = _b;                           \
+                }                                                       \
+        } while(false)
+
+#define LIST_JUST_US(name,item)                                         \
+        (!(item)->name##_prev && !(item)->name##_next)                  \
+
+#define LIST_FOREACH(name,i,head)                                       \
+        for ((i) = (head); (i); (i) = (i)->name##_next)
+
+#define LIST_FOREACH_SAFE(name,i,n,head)                                \
+        for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n))
+
+#define LIST_FOREACH_BEFORE(name,i,p)                                   \
+        for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev)
+
+#define LIST_FOREACH_AFTER(name,i,p)                                    \
+        for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next)
diff --git a/src/shared/log.c b/src/shared/log.c
new file mode 100644 (file)
index 0000000..8d3458e
--- /dev/null
@@ -0,0 +1,952 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stddef.h>
+#include <printf.h>
+
+#include "log.h"
+#include "util.h"
+#include "missing.h"
+#include "macro.h"
+#include "socket-util.h"
+
+#define SNDBUF_SIZE (8*1024*1024)
+
+static LogTarget log_target = LOG_TARGET_CONSOLE;
+static int log_max_level = LOG_INFO;
+static int log_facility = LOG_DAEMON;
+
+static int console_fd = STDERR_FILENO;
+static int syslog_fd = -1;
+static int kmsg_fd = -1;
+static int journal_fd = -1;
+
+static bool syslog_is_stream = false;
+
+static bool show_color = false;
+static bool show_location = false;
+
+/* Akin to glibc's __abort_msg; which is private and we hence cannot
+ * use here. */
+static char *log_abort_msg = NULL;
+
+void log_close_console(void) {
+
+        if (console_fd < 0)
+                return;
+
+        if (getpid() == 1) {
+                if (console_fd >= 3)
+                        close_nointr_nofail(console_fd);
+
+                console_fd = -1;
+        }
+}
+
+static int log_open_console(void) {
+
+        if (console_fd >= 0)
+                return 0;
+
+        if (getpid() == 1) {
+                console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+                if (console_fd < 0)
+                        return console_fd;
+        } else
+                console_fd = STDERR_FILENO;
+
+        return 0;
+}
+
+void log_close_kmsg(void) {
+
+        if (kmsg_fd < 0)
+                return;
+
+        close_nointr_nofail(kmsg_fd);
+        kmsg_fd = -1;
+}
+
+static int log_open_kmsg(void) {
+
+        if (kmsg_fd >= 0)
+                return 0;
+
+        kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+        if (kmsg_fd < 0)
+                return -errno;
+
+        return 0;
+}
+
+void log_close_syslog(void) {
+
+        if (syslog_fd < 0)
+                return;
+
+        close_nointr_nofail(syslog_fd);
+        syslog_fd = -1;
+}
+
+static int create_log_socket(int type) {
+        int fd;
+
+        /* All output to the syslog/journal fds we do asynchronously,
+         * and if the buffers are full we just drop the messages */
+
+        fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (fd < 0)
+                return -errno;
+
+        fd_inc_sndbuf(fd, SNDBUF_SIZE);
+
+        return fd;
+}
+
+static int log_open_syslog(void) {
+        union sockaddr_union sa;
+        int r;
+
+        if (syslog_fd >= 0)
+                return 0;
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path));
+
+        syslog_fd = create_log_socket(SOCK_DGRAM);
+        if (syslog_fd < 0) {
+                r = syslog_fd;
+                goto fail;
+        }
+
+        if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+                close_nointr_nofail(syslog_fd);
+
+                /* Some legacy syslog systems still use stream
+                 * sockets. They really shouldn't. But what can we
+                 * do... */
+                syslog_fd = create_log_socket(SOCK_STREAM);
+                if (syslog_fd < 0) {
+                        r = syslog_fd;
+                        goto fail;
+                }
+
+                if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+
+                syslog_is_stream = true;
+        } else
+                syslog_is_stream = false;
+
+        return 0;
+
+fail:
+        log_close_syslog();
+        return r;
+}
+
+void log_close_journal(void) {
+
+        if (journal_fd < 0)
+                return;
+
+        close_nointr_nofail(journal_fd);
+        journal_fd = -1;
+}
+
+static int log_open_journal(void) {
+        union sockaddr_union sa;
+        int r;
+
+        if (journal_fd >= 0)
+                return 0;
+
+        journal_fd = create_log_socket(SOCK_DGRAM);
+        if (journal_fd < 0) {
+                r = journal_fd;
+                goto fail;
+        }
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
+
+        if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        return 0;
+
+fail:
+        log_close_journal();
+        return r;
+}
+
+int log_open(void) {
+        int r;
+
+        /* If we don't use the console we close it here, to not get
+         * killed by SAK. If we don't use syslog we close it here so
+         * that we are not confused by somebody deleting the socket in
+         * the fs. If we don't use /dev/kmsg we still keep it open,
+         * because there is no reason to close it. */
+
+        if (log_target == LOG_TARGET_NULL) {
+                log_close_journal();
+                log_close_syslog();
+                log_close_console();
+                return 0;
+        }
+
+        if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
+            getpid() == 1 ||
+            isatty(STDERR_FILENO) <= 0) {
+
+                if (log_target == LOG_TARGET_AUTO ||
+                    log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
+                    log_target == LOG_TARGET_JOURNAL) {
+                        r = log_open_journal();
+                        if (r >= 0) {
+                                log_close_syslog();
+                                log_close_console();
+                                return r;
+                        }
+                }
+
+                if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+                    log_target == LOG_TARGET_SYSLOG) {
+                        r = log_open_syslog();
+                        if (r >= 0) {
+                                log_close_journal();
+                                log_close_console();
+                                return r;
+                        }
+                }
+
+                if (log_target == LOG_TARGET_AUTO ||
+                    log_target == LOG_TARGET_SAFE ||
+                    log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
+                    log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+                    log_target == LOG_TARGET_KMSG) {
+                        r = log_open_kmsg();
+                        if (r >= 0) {
+                                log_close_journal();
+                                log_close_syslog();
+                                log_close_console();
+                                return r;
+                        }
+                }
+        }
+
+        log_close_journal();
+        log_close_syslog();
+
+        /* Get the real /dev/console if we are PID=1, hence reopen */
+        log_close_console();
+        return log_open_console();
+}
+
+void log_set_target(LogTarget target) {
+        assert(target >= 0);
+        assert(target < _LOG_TARGET_MAX);
+
+        log_target = target;
+}
+
+void log_close(void) {
+        log_close_journal();
+        log_close_syslog();
+        log_close_kmsg();
+        log_close_console();
+}
+
+void log_forget_fds(void) {
+        console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
+}
+
+void log_set_max_level(int level) {
+        assert((level & LOG_PRIMASK) == level);
+
+        log_max_level = level;
+}
+
+void log_set_facility(int facility) {
+        log_facility = facility;
+}
+
+static int write_to_console(
+                int level,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_name,
+                const char *object,
+                const char *buffer) {
+
+        char location[64];
+        struct iovec iovec[5];
+        unsigned n = 0;
+        bool highlight;
+
+        if (console_fd < 0)
+                return 0;
+
+        highlight = LOG_PRI(level) <= LOG_ERR && show_color;
+
+        zero(iovec);
+
+        if (show_location) {
+                snprintf(location, sizeof(location), "(%s:%u) ", file, line);
+                char_array_0(location);
+                IOVEC_SET_STRING(iovec[n++], location);
+        }
+
+        if (highlight)
+                IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON);
+        IOVEC_SET_STRING(iovec[n++], buffer);
+        if (highlight)
+                IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
+        IOVEC_SET_STRING(iovec[n++], "\n");
+
+        if (writev(console_fd, iovec, n) < 0)
+                return -errno;
+
+        return 1;
+}
+
+static int write_to_syslog(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *object_name,
+        const char *object,
+        const char *buffer) {
+
+        char header_priority[16], header_time[64], header_pid[16];
+        struct iovec iovec[5];
+        struct msghdr msghdr;
+        time_t t;
+        struct tm *tm;
+
+        if (syslog_fd < 0)
+                return 0;
+
+        snprintf(header_priority, sizeof(header_priority), "<%i>", level);
+        char_array_0(header_priority);
+
+        t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
+        tm = localtime(&t);
+        if (!tm)
+                return -EINVAL;
+
+        if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
+                return -EINVAL;
+
+        snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
+        char_array_0(header_pid);
+
+        zero(iovec);
+        IOVEC_SET_STRING(iovec[0], header_priority);
+        IOVEC_SET_STRING(iovec[1], header_time);
+        IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
+        IOVEC_SET_STRING(iovec[3], header_pid);
+        IOVEC_SET_STRING(iovec[4], buffer);
+
+        /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
+        if (syslog_is_stream)
+                iovec[4].iov_len++;
+
+        zero(msghdr);
+        msghdr.msg_iov = iovec;
+        msghdr.msg_iovlen = ELEMENTSOF(iovec);
+
+        for (;;) {
+                ssize_t n;
+
+                n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
+                if (n < 0)
+                        return -errno;
+
+                if (!syslog_is_stream ||
+                    (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
+                        break;
+
+                IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
+        }
+
+        return 1;
+}
+
+static int write_to_kmsg(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *object_name,
+        const char *object,
+        const char *buffer) {
+
+        char header_priority[16], header_pid[16];
+        struct iovec iovec[5];
+
+        if (kmsg_fd < 0)
+                return 0;
+
+        snprintf(header_priority, sizeof(header_priority), "<%i>", level);
+        char_array_0(header_priority);
+
+        snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
+        char_array_0(header_pid);
+
+        zero(iovec);
+        IOVEC_SET_STRING(iovec[0], header_priority);
+        IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
+        IOVEC_SET_STRING(iovec[2], header_pid);
+        IOVEC_SET_STRING(iovec[3], buffer);
+        IOVEC_SET_STRING(iovec[4], "\n");
+
+        if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
+                return -errno;
+
+        return 1;
+}
+
+static int write_to_journal(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *object_name,
+        const char *object,
+        const char *buffer) {
+
+        char header[LINE_MAX];
+        struct iovec iovec[3];
+        struct msghdr mh;
+
+        if (journal_fd < 0)
+                return 0;
+
+        snprintf(header, sizeof(header),
+                 "PRIORITY=%i\n"
+                 "SYSLOG_FACILITY=%i\n"
+                 "CODE_FILE=%s\n"
+                 "CODE_LINE=%i\n"
+                 "CODE_FUNCTION=%s\n"
+                 "%s%.*s%s"
+                 "SYSLOG_IDENTIFIER=%s\n"
+                 "MESSAGE=",
+                 LOG_PRI(level),
+                 LOG_FAC(level),
+                 file,
+                 line,
+                 func,
+                 object ? object_name : "",
+                 object ? LINE_MAX : 0, object, /* %.0s means no output */
+                 object ? "\n" : "",
+                 program_invocation_short_name);
+
+        char_array_0(header);
+
+        zero(iovec);
+        IOVEC_SET_STRING(iovec[0], header);
+        IOVEC_SET_STRING(iovec[1], buffer);
+        IOVEC_SET_STRING(iovec[2], "\n");
+
+        zero(mh);
+        mh.msg_iov = iovec;
+        mh.msg_iovlen = ELEMENTSOF(iovec);
+
+        if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
+                return -errno;
+
+        return 1;
+}
+
+static int log_dispatch(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *object_name,
+        const char *object,
+        char *buffer) {
+
+        int r = 0;
+
+        if (log_target == LOG_TARGET_NULL)
+                return 0;
+
+        /* Patch in LOG_DAEMON facility if necessary */
+        if ((level & LOG_FACMASK) == 0)
+                level = log_facility | LOG_PRI(level);
+
+        do {
+                char *e;
+                int k = 0;
+
+                buffer += strspn(buffer, NEWLINE);
+
+                if (buffer[0] == 0)
+                        break;
+
+                if ((e = strpbrk(buffer, NEWLINE)))
+                        *(e++) = 0;
+
+                if (log_target == LOG_TARGET_AUTO ||
+                    log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
+                    log_target == LOG_TARGET_JOURNAL) {
+
+                        k = write_to_journal(level, file, line, func,
+                                             object_name, object, buffer);
+                        if (k < 0) {
+                                if (k != -EAGAIN)
+                                        log_close_journal();
+                                log_open_kmsg();
+                        } else if (k > 0)
+                                r++;
+                }
+
+                if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+                    log_target == LOG_TARGET_SYSLOG) {
+
+                        k = write_to_syslog(level, file, line, func,
+                                            object_name, object, buffer);
+                        if (k < 0) {
+                                if (k != -EAGAIN)
+                                        log_close_syslog();
+                                log_open_kmsg();
+                        } else if (k > 0)
+                                r++;
+                }
+
+                if (k <= 0 &&
+                    (log_target == LOG_TARGET_AUTO ||
+                     log_target == LOG_TARGET_SAFE ||
+                     log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+                     log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
+                     log_target == LOG_TARGET_KMSG)) {
+
+                        k = write_to_kmsg(level, file, line, func,
+                                          object_name, object, buffer);
+                        if (k < 0) {
+                                log_close_kmsg();
+                                log_open_console();
+                        } else if (k > 0)
+                                r++;
+                }
+
+                if (k <= 0) {
+                        k = write_to_console(level, file, line, func,
+                                             object_name, object, buffer);
+                        if (k < 0)
+                                return k;
+                }
+
+                buffer = e;
+        } while (buffer);
+
+        return r;
+}
+
+int log_dump_internal(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        char *buffer) {
+
+        int saved_errno, r;
+
+        /* This modifies the buffer... */
+
+        if (_likely_(LOG_PRI(level) > log_max_level))
+                return 0;
+
+        saved_errno = errno;
+        r = log_dispatch(level, file, line, func, NULL, NULL, buffer);
+        errno = saved_errno;
+
+        return r;
+}
+
+int log_metav(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *format,
+        va_list ap) {
+
+        char buffer[LINE_MAX];
+        int saved_errno, r;
+
+        if (_likely_(LOG_PRI(level) > log_max_level))
+                return 0;
+
+        saved_errno = errno;
+        vsnprintf(buffer, sizeof(buffer), format, ap);
+        char_array_0(buffer);
+
+        r = log_dispatch(level, file, line, func, NULL, NULL, buffer);
+        errno = saved_errno;
+
+        return r;
+}
+
+int log_meta(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *format, ...) {
+
+        int r;
+        va_list ap;
+
+        va_start(ap, format);
+        r = log_metav(level, file, line, func, format, ap);
+        va_end(ap);
+
+        return r;
+}
+
+int log_metav_object(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *object_name,
+        const char *object,
+        const char *format,
+        va_list ap) {
+
+        char buffer[LINE_MAX];
+        int saved_errno, r;
+
+        if (_likely_(LOG_PRI(level) > log_max_level))
+                return 0;
+
+        saved_errno = errno;
+        vsnprintf(buffer, sizeof(buffer), format, ap);
+        char_array_0(buffer);
+
+        r = log_dispatch(level, file, line, func,
+                         object_name, object, buffer);
+        errno = saved_errno;
+
+        return r;
+}
+
+int log_meta_object(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *object_name,
+        const char *object,
+        const char *format, ...) {
+
+        int r;
+        va_list ap;
+
+        va_start(ap, format);
+        r = log_metav_object(level, file, line, func,
+                             object_name, object, format, ap);
+        va_end(ap);
+
+        return r;
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+_noreturn_ static void log_assert(const char *text, const char *file, int line, const char *func, const char *format) {
+        static char buffer[LINE_MAX];
+
+        snprintf(buffer, sizeof(buffer), format, text, file, line, func);
+
+        char_array_0(buffer);
+        log_abort_msg = buffer;
+
+        log_dispatch(LOG_CRIT, file, line, func, NULL, NULL, buffer);
+        abort();
+}
+#pragma GCC diagnostic pop
+
+_noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func) {
+        log_assert(text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
+}
+
+_noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
+        log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
+}
+
+int log_oom_internal(const char *file, int line, const char *func) {
+        log_meta(LOG_ERR, file, line, func, "Out of memory.");
+        return -ENOMEM;
+}
+
+int log_struct_internal(
+                int level,
+                const char *file,
+                int line,
+                const char *func,
+                const char *format, ...) {
+
+        int saved_errno;
+        va_list ap;
+        int r;
+
+        if (_likely_(LOG_PRI(level) > log_max_level))
+                return 0;
+
+        if (log_target == LOG_TARGET_NULL)
+                return 0;
+
+        if ((level & LOG_FACMASK) == 0)
+                level = log_facility | LOG_PRI(level);
+
+        saved_errno = errno;
+
+        if ((log_target == LOG_TARGET_AUTO ||
+             log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
+             log_target == LOG_TARGET_JOURNAL) &&
+            journal_fd >= 0) {
+
+                char header[LINE_MAX];
+                struct iovec iovec[17];
+                unsigned n = 0, i;
+                struct msghdr mh;
+                const char nl = '\n';
+
+                /* If the journal is available do structured logging */
+
+                snprintf(header, sizeof(header),
+                        "PRIORITY=%i\n"
+                        "SYSLOG_FACILITY=%i\n"
+                        "CODE_FILE=%s\n"
+                        "CODE_LINE=%i\n"
+                        "CODE_FUNCTION=%s\n"
+                        "SYSLOG_IDENTIFIER=%s\n",
+                        LOG_PRI(level),
+                        LOG_FAC(level),
+                        file,
+                        line,
+                        func,
+                        program_invocation_short_name);
+                char_array_0(header);
+
+                zero(iovec);
+                IOVEC_SET_STRING(iovec[n++], header);
+
+                va_start(ap, format);
+                while (format && n + 1 < ELEMENTSOF(iovec)) {
+                        char *buf;
+                        va_list aq;
+
+                        /* We need to copy the va_list structure,
+                         * since vasprintf() leaves it afterwards at
+                         * an undefined location */
+
+                        va_copy(aq, ap);
+                        if (vasprintf(&buf, format, aq) < 0) {
+                                va_end(aq);
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+                        va_end(aq);
+
+                        /* Now, jump enough ahead, so that we point to
+                         * the next format string */
+                        VA_FORMAT_ADVANCE(format, ap);
+
+                        IOVEC_SET_STRING(iovec[n++], buf);
+
+                        iovec[n].iov_base = (char*) &nl;
+                        iovec[n].iov_len = 1;
+                        n++;
+
+                        format = va_arg(ap, char *);
+                }
+
+                zero(mh);
+                mh.msg_iov = iovec;
+                mh.msg_iovlen = n;
+
+                if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
+                        r = -errno;
+                else
+                        r = 1;
+
+        finish:
+                va_end(ap);
+                for (i = 1; i < n; i += 2)
+                        free(iovec[i].iov_base);
+
+        } else {
+                char buf[LINE_MAX];
+                bool found = false;
+
+                /* Fallback if journal logging is not available */
+
+                va_start(ap, format);
+                while (format) {
+                        va_list aq;
+
+                        va_copy(aq, ap);
+                        vsnprintf(buf, sizeof(buf), format, aq);
+                        va_end(aq);
+                        char_array_0(buf);
+
+                        if (startswith(buf, "MESSAGE=")) {
+                                found = true;
+                                break;
+                        }
+
+                        VA_FORMAT_ADVANCE(format, ap);
+
+                        format = va_arg(ap, char *);
+                }
+                va_end(ap);
+
+                if (found)
+                        r = log_dispatch(level, file, line, func,
+                                         NULL, NULL, buf + 8);
+                else
+                        r = -EINVAL;
+        }
+
+        errno = saved_errno;
+        return r;
+}
+
+int log_set_target_from_string(const char *e) {
+        LogTarget t;
+
+        t = log_target_from_string(e);
+        if (t < 0)
+                return -EINVAL;
+
+        log_set_target(t);
+        return 0;
+}
+
+int log_set_max_level_from_string(const char *e) {
+        int t;
+
+        t = log_level_from_string(e);
+        if (t < 0)
+                return t;
+
+        log_set_max_level(t);
+        return 0;
+}
+
+void log_parse_environment(void) {
+        const char *e;
+
+        e = secure_getenv("SYSTEMD_LOG_TARGET");
+        if (e && log_set_target_from_string(e) < 0)
+                log_warning("Failed to parse log target %s. Ignoring.", e);
+
+        e = secure_getenv("SYSTEMD_LOG_LEVEL");
+        if (e && log_set_max_level_from_string(e) < 0)
+                log_warning("Failed to parse log level %s. Ignoring.", e);
+
+        e = secure_getenv("SYSTEMD_LOG_COLOR");
+        if (e && log_show_color_from_string(e) < 0)
+                log_warning("Failed to parse bool %s. Ignoring.", e);
+
+        e = secure_getenv("SYSTEMD_LOG_LOCATION");
+        if (e && log_show_location_from_string(e) < 0)
+                log_warning("Failed to parse bool %s. Ignoring.", e);
+}
+
+LogTarget log_get_target(void) {
+        return log_target;
+}
+
+int log_get_max_level(void) {
+        return log_max_level;
+}
+
+void log_show_color(bool b) {
+        show_color = b;
+}
+
+void log_show_location(bool b) {
+        show_location = b;
+}
+
+int log_show_color_from_string(const char *e) {
+        int t;
+
+        t = parse_boolean(e);
+        if (t < 0)
+                return t;
+
+        log_show_color(t);
+        return 0;
+}
+
+int log_show_location_from_string(const char *e) {
+        int t;
+
+        t = parse_boolean(e);
+        if (t < 0)
+                return t;
+
+        log_show_location(t);
+        return 0;
+}
+
+bool log_on_console(void) {
+        if (log_target == LOG_TARGET_CONSOLE)
+                return true;
+
+        return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
+}
+
+static const char *const log_target_table[] = {
+        [LOG_TARGET_CONSOLE] = "console",
+        [LOG_TARGET_KMSG] = "kmsg",
+        [LOG_TARGET_JOURNAL] = "journal",
+        [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
+        [LOG_TARGET_SYSLOG] = "syslog",
+        [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
+        [LOG_TARGET_AUTO] = "auto",
+        [LOG_TARGET_SAFE] = "safe",
+        [LOG_TARGET_NULL] = "null"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
diff --git a/src/shared/log.h b/src/shared/log.h
new file mode 100644 (file)
index 0000000..9aafcb4
--- /dev/null
@@ -0,0 +1,159 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <syslog.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include "macro.h"
+#include "sd-id128.h"
+
+typedef enum LogTarget{
+        LOG_TARGET_CONSOLE,
+        LOG_TARGET_KMSG,
+        LOG_TARGET_JOURNAL,
+        LOG_TARGET_JOURNAL_OR_KMSG,
+        LOG_TARGET_SYSLOG,
+        LOG_TARGET_SYSLOG_OR_KMSG,
+        LOG_TARGET_AUTO, /* console if stderr is tty, JOURNAL_OR_KMSG otherwise */
+        LOG_TARGET_SAFE, /* console if stderr is tty, KMSG otherwise */
+        LOG_TARGET_NULL,
+        _LOG_TARGET_MAX,
+        _LOG_TARGET_INVALID = -1
+}  LogTarget;
+
+void log_set_target(LogTarget target);
+void log_set_max_level(int level);
+void log_set_facility(int facility);
+
+int log_set_target_from_string(const char *e);
+int log_set_max_level_from_string(const char *e);
+
+void log_show_color(bool b);
+void log_show_location(bool b);
+
+int log_show_color_from_string(const char *e);
+int log_show_location_from_string(const char *e);
+
+LogTarget log_get_target(void);
+int log_get_max_level(void);
+
+int log_open(void);
+void log_close(void);
+void log_forget_fds(void);
+
+void log_close_syslog(void);
+void log_close_journal(void);
+void log_close_kmsg(void);
+void log_close_console(void);
+
+void log_parse_environment(void);
+
+int log_meta(
+                int level,
+                const char*file,
+                int line,
+                const char *func,
+                const char *format, ...) _printf_attr_(5,6);
+
+int log_metav(
+                int level,
+                const char*file,
+                int line,
+                const char *func,
+                const char *format,
+                va_list ap);
+
+int log_meta_object(
+                int level,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_name,
+                const char *object,
+                const char *format, ...) _printf_attr_(7,8);
+
+int log_metav_object(
+                int level,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_name,
+                const char *object,
+                const char *format,
+                va_list ap);
+
+int log_struct_internal(
+                int level,
+                const char *file,
+                int line,
+                const char *func,
+                const char *format, ...) _sentinel_;
+
+int log_oom_internal(
+                const char *file,
+                int line,
+                const char *func);
+
+/* This modifies the buffer passed! */
+int log_dump_internal(
+                int level,
+                const char*file,
+                int line,
+                const char *func,
+                char *buffer);
+
+_noreturn_ void log_assert_failed(
+                const char *text,
+                const char *file,
+                int line,
+                const char *func);
+
+_noreturn_ void log_assert_failed_unreachable(
+                const char *text,
+                const char *file,
+                int line,
+                const char *func);
+
+#define log_full(level, ...) log_meta(level,   __FILE__, __LINE__, __func__, __VA_ARGS__)
+
+#define log_debug(...)   log_meta(LOG_DEBUG,   __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_info(...)    log_meta(LOG_INFO,    __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_notice(...)  log_meta(LOG_NOTICE,  __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_warning(...) log_meta(LOG_WARNING, __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_error(...)   log_meta(LOG_ERR,     __FILE__, __LINE__, __func__, __VA_ARGS__)
+
+#define log_struct(level, ...) log_struct_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__)
+
+#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
+
+/* This modifies the buffer passed! */
+#define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer)
+
+bool log_on_console(void);
+
+const char *log_target_to_string(LogTarget target);
+LogTarget log_target_from_string(const char *s);
+
+#define MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x)
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
new file mode 100644 (file)
index 0000000..04450a5
--- /dev/null
@@ -0,0 +1,943 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <time.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/poll.h>
+#include <string.h>
+
+#include "logs-show.h"
+#include "log.h"
+#include "util.h"
+#include "utf8.h"
+#include "hashmap.h"
+
+#define PRINT_THRESHOLD 128
+#define JSON_THRESHOLD 4096
+
+static int print_catalog(FILE *f, sd_journal *j) {
+        int r;
+        _cleanup_free_ char *t = NULL, *z = NULL;
+
+
+        r = sd_journal_get_catalog(j, &t);
+        if (r < 0)
+                return r;
+
+        z = strreplace(strstrip(t), "\n", "\n-- ");
+        if (!z)
+                return log_oom();
+
+        fputs("-- ", f);
+        fputs(z, f);
+        fputc('\n', f);
+
+        return 0;
+}
+
+static int parse_field(const void *data, size_t length, const char *field, char **target, size_t *target_size) {
+        size_t fl, nl;
+        void *buf;
+
+        assert(data);
+        assert(field);
+        assert(target);
+        assert(target_size);
+
+        fl = strlen(field);
+        if (length < fl)
+                return 0;
+
+        if (memcmp(data, field, fl))
+                return 0;
+
+        nl = length - fl;
+        buf = malloc(nl+1);
+        if (!buf)
+                return log_oom();
+
+        memcpy(buf, (const char*) data + fl, nl);
+        ((char*)buf)[nl] = 0;
+
+        free(*target);
+        *target = buf;
+        *target_size = nl;
+
+        return 1;
+}
+
+static bool shall_print(const char *p, size_t l, OutputFlags flags) {
+        assert(p);
+
+        if (flags & OUTPUT_SHOW_ALL)
+                return true;
+
+        if (l >= PRINT_THRESHOLD)
+                return false;
+
+        if (!utf8_is_printable_n(p, l))
+                return false;
+
+        return true;
+}
+
+static int output_short(
+                FILE *f,
+                sd_journal *j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags) {
+
+        int r;
+        const void *data;
+        size_t length;
+        size_t n = 0;
+        _cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL;
+        size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0;
+        int p = LOG_INFO;
+        const char *color_on = "", *color_off = "";
+
+        assert(f);
+        assert(j);
+
+        sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : PRINT_THRESHOLD);
+
+        SD_JOURNAL_FOREACH_DATA(j, data, length) {
+
+                r = parse_field(data, length, "PRIORITY=", &priority, &priority_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        continue;
+
+                r = parse_field(data, length, "_HOSTNAME=", &hostname, &hostname_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        continue;
+
+                r = parse_field(data, length, "SYSLOG_IDENTIFIER=", &identifier, &identifier_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        continue;
+
+                r = parse_field(data, length, "_COMM=", &comm, &comm_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        continue;
+
+                r = parse_field(data, length, "_PID=", &pid, &pid_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        continue;
+
+                r = parse_field(data, length, "SYSLOG_PID=", &fake_pid, &fake_pid_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        continue;
+
+                r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        continue;
+
+                r = parse_field(data, length, "_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len);
+                if (r < 0)
+                        return r;
+                else if (r > 0)
+                        continue;
+
+                r = parse_field(data, length, "MESSAGE=", &message, &message_len);
+                if (r < 0)
+                        return r;
+        }
+
+        if (!message)
+                return 0;
+
+        if (!(flags & OUTPUT_SHOW_ALL))
+                strip_tab_ansi(&message, &message_len);
+
+        if (priority_len == 1 && *priority >= '0' && *priority <= '7')
+                p = *priority - '0';
+
+        if (mode == OUTPUT_SHORT_MONOTONIC) {
+                uint64_t t;
+                sd_id128_t boot_id;
+
+                r = -ENOENT;
+
+                if (monotonic)
+                        r = safe_atou64(monotonic, &t);
+
+                if (r < 0)
+                        r = sd_journal_get_monotonic_usec(j, &t, &boot_id);
+
+                if (r < 0) {
+                        log_error("Failed to get monotonic: %s", strerror(-r));
+                        return r;
+                }
+
+                fprintf(f, "[%5llu.%06llu]",
+                        (unsigned long long) (t / USEC_PER_SEC),
+                        (unsigned long long) (t % USEC_PER_SEC));
+
+                n += 1 + 5 + 1 + 6 + 1;
+
+        } else {
+                char buf[64];
+                uint64_t x;
+                time_t t;
+                struct tm tm;
+
+                r = -ENOENT;
+
+                if (realtime)
+                        r = safe_atou64(realtime, &x);
+
+                if (r < 0)
+                        r = sd_journal_get_realtime_usec(j, &x);
+
+                if (r < 0) {
+                        log_error("Failed to get realtime: %s", strerror(-r));
+                        return r;
+                }
+
+                t = (time_t) (x / USEC_PER_SEC);
+                if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)) <= 0) {
+                        log_error("Failed to format time.");
+                        return r;
+                }
+
+                fputs(buf, f);
+                n += strlen(buf);
+        }
+
+        if (hostname && shall_print(hostname, hostname_len, flags)) {
+                fprintf(f, " %.*s", (int) hostname_len, hostname);
+                n += hostname_len + 1;
+        }
+
+        if (identifier && shall_print(identifier, identifier_len, flags)) {
+                fprintf(f, " %.*s", (int) identifier_len, identifier);
+                n += identifier_len + 1;
+        } else if (comm && shall_print(comm, comm_len, flags)) {
+                fprintf(f, " %.*s", (int) comm_len, comm);
+                n += comm_len + 1;
+        } else
+                fputc(' ', f);
+
+        if (pid && shall_print(pid, pid_len, flags)) {
+                fprintf(f, "[%.*s]", (int) pid_len, pid);
+                n += pid_len + 2;
+        } else if (fake_pid && shall_print(fake_pid, fake_pid_len, flags)) {
+                fprintf(f, "[%.*s]", (int) fake_pid_len, fake_pid);
+                n += fake_pid_len + 2;
+        }
+
+        if (flags & OUTPUT_COLOR) {
+                if (p <= LOG_ERR) {
+                        color_on = ANSI_HIGHLIGHT_RED_ON;
+                        color_off = ANSI_HIGHLIGHT_OFF;
+                } else if (p <= LOG_NOTICE) {
+                        color_on = ANSI_HIGHLIGHT_ON;
+                        color_off = ANSI_HIGHLIGHT_OFF;
+                }
+        }
+
+        if (flags & OUTPUT_SHOW_ALL)
+                fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off);
+        else if (!utf8_is_printable_n(message, message_len)) {
+                char bytes[FORMAT_BYTES_MAX];
+                fprintf(f, ": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
+        } else if ((flags & OUTPUT_FULL_WIDTH) || (message_len + n + 1 < n_columns))
+                fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off);
+        else if (n < n_columns && n_columns - n - 2 >= 3) {
+                char *e;
+
+                e = ellipsize_mem(message, message_len, n_columns - n - 2, 90);
+
+                if (!e)
+                        fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off);
+                else
+                        fprintf(f, ": %s%s%s\n", color_on, e, color_off);
+
+                free(e);
+        } else
+                fputs("\n", f);
+
+        if (flags & OUTPUT_CATALOG)
+                print_catalog(f, j);
+
+        return 0;
+}
+
+static int output_verbose(
+                FILE *f,
+                sd_journal *j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags) {
+
+        const void *data;
+        size_t length;
+        char *cursor;
+        uint64_t realtime;
+        char ts[FORMAT_TIMESTAMP_MAX];
+        int r;
+
+        assert(f);
+        assert(j);
+
+        sd_journal_set_data_threshold(j, 0);
+
+        r = sd_journal_get_realtime_usec(j, &realtime);
+        if (r < 0) {
+                log_error("Failed to get realtime timestamp: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_journal_get_cursor(j, &cursor);
+        if (r < 0) {
+                log_error("Failed to get cursor: %s", strerror(-r));
+                return r;
+        }
+
+        fprintf(f, "%s [%s]\n",
+                format_timestamp(ts, sizeof(ts), realtime),
+                cursor);
+
+        free(cursor);
+
+        SD_JOURNAL_FOREACH_DATA(j, data, length) {
+                if (!shall_print(data, length, flags)) {
+                        const char *c;
+                        char bytes[FORMAT_BYTES_MAX];
+
+                        c = memchr(data, '=', length);
+                        if (!c) {
+                                log_error("Invalid field.");
+                                return -EINVAL;
+                        }
+
+                        fprintf(f, "\t%.*s=[%s blob data]\n",
+                               (int) (c - (const char*) data),
+                               (const char*) data,
+                               format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1));
+                } else
+                        fprintf(f, "\t%.*s\n", (int) length, (const char*) data);
+        }
+
+        if (flags & OUTPUT_CATALOG)
+                print_catalog(f, j);
+
+        return 0;
+}
+
+static int output_export(
+                FILE *f,
+                sd_journal *j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags) {
+
+        sd_id128_t boot_id;
+        char sid[33];
+        int r;
+        usec_t realtime, monotonic;
+        char *cursor;
+        const void *data;
+        size_t length;
+
+        assert(j);
+
+        sd_journal_set_data_threshold(j, 0);
+
+        r = sd_journal_get_realtime_usec(j, &realtime);
+        if (r < 0) {
+                log_error("Failed to get realtime timestamp: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
+        if (r < 0) {
+                log_error("Failed to get monotonic timestamp: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_journal_get_cursor(j, &cursor);
+        if (r < 0) {
+                log_error("Failed to get cursor: %s", strerror(-r));
+                return r;
+        }
+
+        fprintf(f,
+                "__CURSOR=%s\n"
+                "__REALTIME_TIMESTAMP=%llu\n"
+                "__MONOTONIC_TIMESTAMP=%llu\n"
+                "_BOOT_ID=%s\n",
+                cursor,
+                (unsigned long long) realtime,
+                (unsigned long long) monotonic,
+                sd_id128_to_string(boot_id, sid));
+
+        free(cursor);
+
+        SD_JOURNAL_FOREACH_DATA(j, data, length) {
+
+                /* We already printed the boot id, from the data in
+                 * the header, hence let's suppress it here */
+                if (length >= 9 &&
+                    memcmp(data, "_BOOT_ID=", 9) == 0)
+                        continue;
+
+                if (!utf8_is_printable_n(data, length)) {
+                        const char *c;
+                        uint64_t le64;
+
+                        c = memchr(data, '=', length);
+                        if (!c) {
+                                log_error("Invalid field.");
+                                return -EINVAL;
+                        }
+
+                        fwrite(data, c - (const char*) data, 1, f);
+                        fputc('\n', f);
+                        le64 = htole64(length - (c - (const char*) data) - 1);
+                        fwrite(&le64, sizeof(le64), 1, f);
+                        fwrite(c + 1, length - (c - (const char*) data) - 1, 1, f);
+                } else
+                        fwrite(data, length, 1, f);
+
+                fputc('\n', f);
+        }
+
+        fputc('\n', f);
+
+        return 0;
+}
+
+void json_escape(
+                FILE *f,
+                const char* p,
+                size_t l,
+                OutputFlags flags) {
+
+        assert(f);
+        assert(p);
+
+        if (!(flags & OUTPUT_SHOW_ALL) && l >= JSON_THRESHOLD)
+
+                fputs("null", f);
+
+        else if (!utf8_is_printable_n(p, l)) {
+                bool not_first = false;
+
+                fputs("[ ", f);
+
+                while (l > 0) {
+                        if (not_first)
+                                fprintf(f, ", %u", (uint8_t) *p);
+                        else {
+                                not_first = true;
+                                fprintf(f, "%u", (uint8_t) *p);
+                        }
+
+                        p++;
+                        l--;
+                }
+
+                fputs(" ]", f);
+        } else {
+                fputc('\"', f);
+
+                while (l > 0) {
+                        if (*p == '"' || *p == '\\') {
+                                fputc('\\', f);
+                                fputc(*p, f);
+                        } else if (*p < ' ')
+                                fprintf(f, "\\u%04x", *p);
+                        else
+                                fputc(*p, f);
+
+                        p++;
+                        l--;
+                }
+
+                fputc('\"', f);
+        }
+}
+
+static int output_json(
+                FILE *f,
+                sd_journal *j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags) {
+
+        uint64_t realtime, monotonic;
+        char *cursor, *k;
+        const void *data;
+        size_t length;
+        sd_id128_t boot_id;
+        char sid[33];
+        int r;
+        Hashmap *h = NULL;
+        bool done, separator;
+
+        assert(j);
+
+        sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : JSON_THRESHOLD);
+
+        r = sd_journal_get_realtime_usec(j, &realtime);
+        if (r < 0) {
+                log_error("Failed to get realtime timestamp: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
+        if (r < 0) {
+                log_error("Failed to get monotonic timestamp: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_journal_get_cursor(j, &cursor);
+        if (r < 0) {
+                log_error("Failed to get cursor: %s", strerror(-r));
+                return r;
+        }
+
+        if (mode == OUTPUT_JSON_PRETTY)
+                fprintf(f,
+                        "{\n"
+                        "\t\"__CURSOR\" : \"%s\",\n"
+                        "\t\"__REALTIME_TIMESTAMP\" : \"%llu\",\n"
+                        "\t\"__MONOTONIC_TIMESTAMP\" : \"%llu\",\n"
+                        "\t\"_BOOT_ID\" : \"%s\"",
+                        cursor,
+                        (unsigned long long) realtime,
+                        (unsigned long long) monotonic,
+                        sd_id128_to_string(boot_id, sid));
+        else {
+                if (mode == OUTPUT_JSON_SSE)
+                        fputs("data: ", f);
+
+                fprintf(f,
+                        "{ \"__CURSOR\" : \"%s\", "
+                        "\"__REALTIME_TIMESTAMP\" : \"%llu\", "
+                        "\"__MONOTONIC_TIMESTAMP\" : \"%llu\", "
+                        "\"_BOOT_ID\" : \"%s\"",
+                        cursor,
+                        (unsigned long long) realtime,
+                        (unsigned long long) monotonic,
+                        sd_id128_to_string(boot_id, sid));
+        }
+        free(cursor);
+
+        h = hashmap_new(string_hash_func, string_compare_func);
+        if (!h)
+                return -ENOMEM;
+
+        /* First round, iterate through the entry and count how often each field appears */
+        SD_JOURNAL_FOREACH_DATA(j, data, length) {
+                const char *eq;
+                char *n;
+                unsigned u;
+
+                if (length >= 9 &&
+                    memcmp(data, "_BOOT_ID=", 9) == 0)
+                        continue;
+
+                eq = memchr(data, '=', length);
+                if (!eq)
+                        continue;
+
+                n = strndup(data, eq - (const char*) data);
+                if (!n) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                u = PTR_TO_UINT(hashmap_get(h, n));
+                if (u == 0) {
+                        r = hashmap_put(h, n, UINT_TO_PTR(1));
+                        if (r < 0) {
+                                free(n);
+                                goto finish;
+                        }
+                } else {
+                        r = hashmap_update(h, n, UINT_TO_PTR(u + 1));
+                        free(n);
+                        if (r < 0)
+                                goto finish;
+                }
+        }
+
+        separator = true;
+        do {
+                done = true;
+
+                SD_JOURNAL_FOREACH_DATA(j, data, length) {
+                        const char *eq;
+                        char *kk, *n;
+                        size_t m;
+                        unsigned u;
+
+                        /* We already printed the boot id, from the data in
+                         * the header, hence let's suppress it here */
+                        if (length >= 9 &&
+                            memcmp(data, "_BOOT_ID=", 9) == 0)
+                                continue;
+
+                        eq = memchr(data, '=', length);
+                        if (!eq)
+                                continue;
+
+                        if (separator) {
+                                if (mode == OUTPUT_JSON_PRETTY)
+                                        fputs(",\n\t", f);
+                                else
+                                        fputs(", ", f);
+                        }
+
+                        m = eq - (const char*) data;
+
+                        n = strndup(data, m);
+                        if (!n) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        u = PTR_TO_UINT(hashmap_get2(h, n, (void**) &kk));
+                        if (u == 0) {
+                                /* We already printed this, let's jump to the next */
+                                free(n);
+                                separator = false;
+
+                                continue;
+                        } else if (u == 1) {
+                                /* Field only appears once, output it directly */
+
+                                json_escape(f, data, m, flags);
+                                fputs(" : ", f);
+
+                                json_escape(f, eq + 1, length - m - 1, flags);
+
+                                hashmap_remove(h, n);
+                                free(kk);
+                                free(n);
+
+                                separator = true;
+
+                                continue;
+
+                        } else {
+                                /* Field appears multiple times, output it as array */
+                                json_escape(f, data, m, flags);
+                                fputs(" : [ ", f);
+                                json_escape(f, eq + 1, length - m - 1, flags);
+
+                                /* Iterate through the end of the list */
+
+                                while (sd_journal_enumerate_data(j, &data, &length) > 0) {
+                                        if (length < m + 1)
+                                                continue;
+
+                                        if (memcmp(data, n, m) != 0)
+                                                continue;
+
+                                        if (((const char*) data)[m] != '=')
+                                                continue;
+
+                                        fputs(", ", f);
+                                        json_escape(f, (const char*) data + m + 1, length - m - 1, flags);
+                                }
+
+                                fputs(" ]", f);
+
+                                hashmap_remove(h, n);
+                                free(kk);
+                                free(n);
+
+                                /* Iterate data fields form the beginning */
+                                done = false;
+                                separator = true;
+
+                                break;
+                        }
+                }
+
+        } while (!done);
+
+        if (mode == OUTPUT_JSON_PRETTY)
+                fputs("\n}\n", f);
+        else if (mode == OUTPUT_JSON_SSE)
+                fputs("}\n\n", f);
+        else
+                fputs(" }\n", f);
+
+        r = 0;
+
+finish:
+        while ((k = hashmap_steal_first_key(h)))
+                free(k);
+
+        hashmap_free(h);
+
+        return r;
+}
+
+static int output_cat(
+                FILE *f,
+                sd_journal *j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags) {
+
+        const void *data;
+        size_t l;
+        int r;
+
+        assert(j);
+        assert(f);
+
+        sd_journal_set_data_threshold(j, 0);
+
+        r = sd_journal_get_data(j, "MESSAGE", &data, &l);
+        if (r < 0) {
+                /* An entry without MESSAGE=? */
+                if (r == -ENOENT)
+                        return 0;
+
+                log_error("Failed to get data: %s", strerror(-r));
+                return r;
+        }
+
+        assert(l >= 8);
+
+        fwrite((const char*) data + 8, 1, l - 8, f);
+        fputc('\n', f);
+
+        return 0;
+}
+
+static int (*output_funcs[_OUTPUT_MODE_MAX])(
+                FILE *f,
+                sd_journal*j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags) = {
+
+        [OUTPUT_SHORT] = output_short,
+        [OUTPUT_SHORT_MONOTONIC] = output_short,
+        [OUTPUT_VERBOSE] = output_verbose,
+        [OUTPUT_EXPORT] = output_export,
+        [OUTPUT_JSON] = output_json,
+        [OUTPUT_JSON_PRETTY] = output_json,
+        [OUTPUT_JSON_SSE] = output_json,
+        [OUTPUT_CAT] = output_cat
+};
+
+int output_journal(
+                FILE *f,
+                sd_journal *j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags) {
+
+        int ret;
+        assert(mode >= 0);
+        assert(mode < _OUTPUT_MODE_MAX);
+
+        if (n_columns <= 0)
+                n_columns = columns();
+
+        ret = output_funcs[mode](f, j, mode, n_columns, flags);
+        fflush(stdout);
+        return ret;
+}
+
+int show_journal_by_unit(
+                FILE *f,
+                const char *unit,
+                OutputMode mode,
+                unsigned n_columns,
+                usec_t not_before,
+                unsigned how_many,
+                OutputFlags flags) {
+
+        _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL;
+        sd_journal *j = NULL;
+        int r;
+        unsigned line = 0;
+        bool need_seek = false;
+        int warn_cutoff = flags & OUTPUT_WARN_CUTOFF;
+
+        assert(mode >= 0);
+        assert(mode < _OUTPUT_MODE_MAX);
+        assert(unit);
+
+        if (!endswith(unit, ".service") &&
+            !endswith(unit, ".socket") &&
+            !endswith(unit, ".mount") &&
+            !endswith(unit, ".swap"))
+                return 0;
+
+        if (how_many <= 0)
+                return 0;
+
+        if (asprintf(&m1, "_SYSTEMD_UNIT=%s", unit) < 0 ||
+            asprintf(&m2, "COREDUMP_UNIT=%s", unit) < 0 ||
+            asprintf(&m3, "UNIT=%s", unit) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY);
+        if (r < 0)
+                goto finish;
+
+        /* Look for messages from the service itself */
+        r = sd_journal_add_match(j, m1, 0);
+        if (r < 0)
+                goto finish;
+
+        /* Look for coredumps of the service */
+        r = sd_journal_add_disjunction(j);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, m2, 0);
+        if (r < 0)
+                goto finish;
+
+        /* Look for messages from PID 1 about this service */
+        r = sd_journal_add_disjunction(j);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, "_PID=1", 0);
+        if (r < 0)
+                goto finish;
+        r = sd_journal_add_match(j, m3, 0);
+        if (r < 0)
+                goto finish;
+
+        /* Seek to end */
+        r = sd_journal_seek_tail(j);
+        if (r < 0)
+                goto finish;
+
+        r = sd_journal_previous_skip(j, how_many);
+        if (r < 0)
+                goto finish;
+
+        for (;;) {
+                for (;;) {
+                        usec_t usec;
+
+                        if (need_seek) {
+                                r = sd_journal_next(j);
+                                if (r < 0)
+                                        goto finish;
+                        }
+
+                        if (r == 0)
+                                break;
+
+                        need_seek = true;
+
+                        if (not_before > 0) {
+                                r = sd_journal_get_monotonic_usec(j, &usec, NULL);
+
+                                /* -ESTALE is returned if the
+                                   timestamp is not from this boot */
+                                if (r == -ESTALE)
+                                        continue;
+                                else if (r < 0)
+                                        goto finish;
+
+                                if (usec < not_before)
+                                        continue;
+                        }
+
+                        line ++;
+
+                        r = output_journal(f, j, mode, n_columns, flags);
+                        if (r < 0)
+                                goto finish;
+                }
+
+                if (warn_cutoff && line < how_many && not_before > 0) {
+                        sd_id128_t boot_id;
+                        usec_t cutoff;
+
+                        /* Check whether the cutoff line is too early */
+
+                        r = sd_id128_get_boot(&boot_id);
+                        if (r < 0)
+                                goto finish;
+
+                        r = sd_journal_get_cutoff_monotonic_usec(j, boot_id, &cutoff, NULL);
+                        if (r < 0)
+                                goto finish;
+
+                        if (r > 0 && not_before < cutoff)
+                                fprintf(f, "Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.\n");
+
+                        warn_cutoff = false;
+                }
+
+                if (!(flags & OUTPUT_FOLLOW))
+                        break;
+
+                r = sd_journal_wait(j, (usec_t) -1);
+                if (r < 0)
+                        goto finish;
+
+        }
+
+finish:
+        if (j)
+                sd_journal_close(j);
+
+        return r;
+}
+
+static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
+        [OUTPUT_SHORT] = "short",
+        [OUTPUT_SHORT_MONOTONIC] = "short-monotonic",
+        [OUTPUT_VERBOSE] = "verbose",
+        [OUTPUT_EXPORT] = "export",
+        [OUTPUT_JSON] = "json",
+        [OUTPUT_JSON_PRETTY] = "json-pretty",
+        [OUTPUT_JSON_SSE] = "json-sse",
+        [OUTPUT_CAT] = "cat"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(output_mode, OutputMode);
diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h
new file mode 100644 (file)
index 0000000..11cb41a
--- /dev/null
@@ -0,0 +1,75 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include <systemd/sd-journal.h>
+
+#include "util.h"
+
+typedef enum OutputMode {
+        OUTPUT_SHORT,
+        OUTPUT_SHORT_MONOTONIC,
+        OUTPUT_VERBOSE,
+        OUTPUT_EXPORT,
+        OUTPUT_JSON,
+        OUTPUT_JSON_PRETTY,
+        OUTPUT_JSON_SSE,
+        OUTPUT_CAT,
+        _OUTPUT_MODE_MAX,
+        _OUTPUT_MODE_INVALID = -1
+} OutputMode;
+
+typedef enum OutputFlags {
+        OUTPUT_SHOW_ALL       = 1 << 0,
+        OUTPUT_FOLLOW         = 1 << 1,
+        OUTPUT_WARN_CUTOFF    = 1 << 2,
+        OUTPUT_FULL_WIDTH     = 1 << 3,
+        OUTPUT_COLOR          = 1 << 4,
+        OUTPUT_CATALOG        = 1 << 5
+} OutputFlags;
+
+int output_journal(
+                FILE *f,
+                sd_journal *j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags);
+
+int show_journal_by_unit(
+                FILE *f,
+                const char *unit,
+                OutputMode mode,
+                unsigned n_columns,
+                usec_t not_before,
+                unsigned how_many,
+                OutputFlags flags);
+
+void json_escape(
+                FILE *f,
+                const char* p,
+                size_t l,
+                OutputFlags flags);
+
+const char* output_mode_to_string(OutputMode m);
+OutputMode output_mode_from_string(const char *s);
diff --git a/src/shared/macro.h b/src/shared/macro.h
new file mode 100644 (file)
index 0000000..700171b
--- /dev/null
@@ -0,0 +1,249 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <inttypes.h>
+
+#define _printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
+#define _sentinel_ __attribute__ ((sentinel))
+#define _noreturn_ __attribute__((noreturn))
+#define _unused_ __attribute__ ((unused))
+#define _destructor_ __attribute__ ((destructor))
+#define _pure_ __attribute__ ((pure))
+#define _const_ __attribute__ ((const))
+#define _deprecated_ __attribute__ ((deprecated))
+#define _packed_ __attribute__ ((packed))
+#define _malloc_ __attribute__ ((malloc))
+#define _weak_ __attribute__ ((weak))
+#define _likely_(x) (__builtin_expect(!!(x),1))
+#define _unlikely_(x) (__builtin_expect(!!(x),0))
+#define _public_ __attribute__ ((visibility("default")))
+#define _hidden_ __attribute__ ((visibility("hidden")))
+#define _weakref_(x) __attribute__((weakref(#x)))
+#define _introspect_(x) __attribute__((section("introspect." x)))
+#define _alignas_(x) __attribute__((aligned(__alignof(x))))
+
+#define XSTRINGIFY(x) #x
+#define STRINGIFY(x) XSTRINGIFY(x)
+
+/* Rounds up */
+#define ALIGN(l) ALIGN_TO((l), sizeof(void*))
+static inline size_t ALIGN_TO(size_t l, size_t ali) {
+        return ((l + ali - 1) & ~(ali - 1));
+}
+
+#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
+
+/*
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+
+#ifndef MAX
+#define MAX(a,b)                                \
+        __extension__ ({                        \
+                        typeof(a) _a = (a);     \
+                        typeof(b) _b = (b);     \
+                        _a > _b ? _a : _b;      \
+                })
+#endif
+
+#define MAX3(a,b,c)                             \
+        MAX(MAX(a,b),c)
+
+#ifndef MIN
+#define MIN(a,b)                                \
+        __extension__ ({                        \
+                        typeof(a) _a = (a);     \
+                        typeof(b) _b = (b);     \
+                        _a < _b ? _a : _b;      \
+                })
+#endif
+
+#define MIN3(a,b,c)                             \
+        MIN(MIN(a,b),c)
+
+#define CLAMP(x, low, high)                                             \
+        __extension__ ({                                                \
+                        typeof(x) _x = (x);                             \
+                        typeof(low) _low = (low);                       \
+                        typeof(high) _high = (high);                    \
+                        ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
+                })
+
+#define assert_se(expr)                                                 \
+        do {                                                            \
+                if (_unlikely_(!(expr)))                                \
+                        log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
+        } while (false)                                                 \
+
+/* We override the glibc assert() here. */
+#undef assert
+#ifdef NDEBUG
+#define assert(expr) do {} while(false)
+#else
+#define assert(expr) assert_se(expr)
+#endif
+
+#define assert_not_reached(t)                                           \
+        do {                                                            \
+                log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
+        } while (false)
+
+#if defined(static_assert)
+#define assert_cc(expr)                         \
+        do {                                    \
+                static_assert(expr, #expr);     \
+        } while (false)
+#else
+#define assert_cc(expr)                         \
+        do {                                    \
+                switch (0) {                    \
+                case 0:                         \
+                case !!(expr):                  \
+                        ;                       \
+                }                               \
+        } while (false)
+#endif
+
+#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
+#define UINT_TO_PTR(u) ((void*) ((uintptr_t) (u)))
+
+#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
+#define UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u)))
+
+#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
+#define ULONG_TO_PTR(u) ((void*) ((uintptr_t) (u)))
+
+#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
+#define INT_TO_PTR(u) ((void*) ((intptr_t) (u)))
+
+#define TO_INT32(p) ((int32_t) ((intptr_t) (p)))
+#define INT32_TO_PTR(u) ((void*) ((intptr_t) (u)))
+
+#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
+#define LONG_TO_PTR(u) ((void*) ((intptr_t) (u)))
+
+#define memzero(x,l) (memset((x), 0, (l)))
+#define zero(x) (memzero(&(x), sizeof(x)))
+
+#define char_array_0(x) x[sizeof(x)-1] = 0;
+
+#define IOVEC_SET_STRING(i, s)                  \
+        do {                                    \
+                struct iovec *_i = &(i);        \
+                char *_s = (char *)(s);         \
+                _i->iov_base = _s;              \
+                _i->iov_len = strlen(_s);       \
+        } while(false)
+
+static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
+        unsigned j;
+        size_t r = 0;
+
+        for (j = 0; j < n; j++)
+                r += i[j].iov_len;
+
+        return r;
+}
+
+static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
+        unsigned j;
+
+        for (j = 0; j < n; j++) {
+                size_t sub;
+
+                if (_unlikely_(k <= 0))
+                        break;
+
+                sub = MIN(i[j].iov_len, k);
+                i[j].iov_len -= sub;
+                i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
+                k -= sub;
+        }
+
+        return k;
+}
+
+#define _cleanup_free_ __attribute__((cleanup(freep)))
+#define _cleanup_fclose_ __attribute__((cleanup(fclosep)))
+#define _cleanup_close_ __attribute__((cleanup(closep)))
+#define _cleanup_closedir_ __attribute__((cleanup(closedirp)))
+#define _cleanup_umask_ __attribute__((cleanup(umaskp)))
+#define _cleanup_strv_free_ __attribute__((cleanup(strv_freep)))
+
+#define VA_FORMAT_ADVANCE(format, ap)                                   \
+do {                                                                    \
+        int _argtypes[128];                                             \
+        size_t _i, _k;                                                  \
+        _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
+        assert(_k < ELEMENTSOF(_argtypes));                             \
+        for (_i = 0; _i < _k; _i++) {                                   \
+                if (_argtypes[_i] & PA_FLAG_PTR)  {                     \
+                        (void) va_arg(ap, void*);                       \
+                        continue;                                       \
+                }                                                       \
+                                                                        \
+                switch (_argtypes[_i]) {                                \
+                case PA_INT:                                            \
+                case PA_INT|PA_FLAG_SHORT:                              \
+                case PA_CHAR:                                           \
+                        (void) va_arg(ap, int);                         \
+                        break;                                          \
+                case PA_INT|PA_FLAG_LONG:                               \
+                        (void) va_arg(ap, long int);                    \
+                        break;                                          \
+                case PA_INT|PA_FLAG_LONG_LONG:                          \
+                        (void) va_arg(ap, long long int);               \
+                        break;                                          \
+                case PA_WCHAR:                                          \
+                        (void) va_arg(ap, wchar_t);                     \
+                        break;                                          \
+                case PA_WSTRING:                                        \
+                case PA_STRING:                                         \
+                case PA_POINTER:                                        \
+                        (void) va_arg(ap, void*);                       \
+                        break;                                          \
+                case PA_FLOAT:                                          \
+                case PA_DOUBLE:                                         \
+                        (void) va_arg(ap, double);                      \
+                        break;                                          \
+                case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:                     \
+                        (void) va_arg(ap, long double);                 \
+                        break;                                          \
+                default:                                                \
+                        assert_not_reached("Unknown format string argument."); \
+                }                                                       \
+        }                                                               \
+} while(false)
+
+#include "log.h"
diff --git a/src/shared/missing.h b/src/shared/missing.h
new file mode 100644 (file)
index 0000000..c53579f
--- /dev/null
@@ -0,0 +1,259 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* Missing glibc definitions to access certain kernel APIs */
+
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/oom.h>
+
+#ifdef HAVE_AUDIT
+#include <libaudit.h>
+#endif
+
+#include "macro.h"
+
+#ifdef ARCH_MIPS
+#include <asm/sgidefs.h>
+#endif
+
+#ifndef RLIMIT_RTTIME
+#define RLIMIT_RTTIME 15
+#endif
+
+#ifndef F_LINUX_SPECIFIC_BASE
+#define F_LINUX_SPECIFIC_BASE 1024
+#endif
+
+#ifndef F_SETPIPE_SZ
+#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
+#endif
+
+#ifndef F_GETPIPE_SZ
+#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
+#endif
+
+#ifndef IP_FREEBIND
+#define IP_FREEBIND 15
+#endif
+
+#ifndef OOM_SCORE_ADJ_MIN
+#define OOM_SCORE_ADJ_MIN (-1000)
+#endif
+
+#ifndef OOM_SCORE_ADJ_MAX
+#define OOM_SCORE_ADJ_MAX 1000
+#endif
+
+#ifndef AUDIT_SERVICE_START
+#define AUDIT_SERVICE_START 1130 /* Service (daemon) start */
+#endif
+
+#ifndef AUDIT_SERVICE_STOP
+#define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */
+#endif
+
+#ifndef TIOCVHANGUP
+#define TIOCVHANGUP 0x5437
+#endif
+
+#ifndef IP_TRANSPARENT
+#define IP_TRANSPARENT 19
+#endif
+
+#if !HAVE_DECL_PIVOT_ROOT
+static inline int pivot_root(const char *new_root, const char *put_old) {
+        return syscall(SYS_pivot_root, new_root, put_old);
+}
+#endif
+
+#ifdef __x86_64__
+#  ifndef __NR_fanotify_init
+#    define __NR_fanotify_init 300
+#  endif
+#  ifndef __NR_fanotify_mark
+#    define __NR_fanotify_mark 301
+#  endif
+#elif defined _MIPS_SIM
+#  if _MIPS_SIM == _MIPS_SIM_ABI32
+#    ifndef __NR_fanotify_init
+#      define __NR_fanotify_init 4336
+#    endif
+#    ifndef __NR_fanotify_mark
+#      define __NR_fanotify_mark 4337
+#    endif
+#  elif _MIPS_SIM == _MIPS_SIM_NABI32
+#    ifndef __NR_fanotify_init
+#      define __NR_fanotify_init 6300
+#    endif
+#    ifndef __NR_fanotify_mark
+#      define __NR_fanotify_mark 6301
+#    endif
+#  elif _MIPS_SIM == _MIPS_SIM_ABI64
+#    ifndef __NR_fanotify_init
+#      define __NR_fanotify_init 5295
+#    endif
+#    ifndef __NR_fanotify_mark
+#      define __NR_fanotify_mark 5296
+#    endif
+#  endif
+#else
+#  ifndef __NR_fanotify_init
+#    define __NR_fanotify_init 338
+#  endif
+#  ifndef __NR_fanotify_mark
+#    define __NR_fanotify_mark 339
+#  endif
+#endif
+
+#ifndef HAVE_FANOTIFY_INIT
+static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) {
+        return syscall(__NR_fanotify_init, flags, event_f_flags);
+}
+#endif
+
+#ifndef HAVE_FANOTIFY_MARK
+static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask,
+                                int dfd, const char *pathname) {
+#if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 || defined __powerpc__ && !defined __powerpc64__
+        union {
+                uint64_t _64;
+                uint32_t _32[2];
+        } _mask;
+        _mask._64 = mask;
+
+        return syscall(__NR_fanotify_mark, fanotify_fd, flags,
+                       _mask._32[0], _mask._32[1], dfd, pathname);
+#else
+        return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dfd, pathname);
+#endif
+}
+#endif
+
+#ifndef BTRFS_IOCTL_MAGIC
+#define BTRFS_IOCTL_MAGIC 0x94
+#endif
+
+#ifndef BTRFS_PATH_NAME_MAX
+#define BTRFS_PATH_NAME_MAX 4087
+#endif
+
+struct btrfs_ioctl_vol_args {
+        int64_t fd;
+        char name[BTRFS_PATH_NAME_MAX + 1];
+};
+
+#ifndef BTRFS_IOC_DEFRAG
+#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct btrfs_ioctl_vol_args)
+#endif
+
+#ifndef BTRFS_SUPER_MAGIC
+#define BTRFS_SUPER_MAGIC 0x9123683E
+#endif
+
+#ifndef MS_MOVE
+#define MS_MOVE 8192
+#endif
+
+#ifndef MS_PRIVATE
+#define MS_PRIVATE  (1 << 18)
+#endif
+
+#if !HAVE_DECL_GETTID
+static inline pid_t gettid(void) {
+        return (pid_t) syscall(SYS_gettid);
+}
+#endif
+
+#ifndef SCM_SECURITY
+#define SCM_SECURITY 0x03
+#endif
+
+#ifndef MS_STRICTATIME
+#define MS_STRICTATIME (1<<24)
+#endif
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 38
+#endif
+
+#ifndef PR_SET_CHILD_SUBREAPER
+#define PR_SET_CHILD_SUBREAPER 36
+#endif
+
+#ifndef MAX_HANDLE_SZ
+#define MAX_HANDLE_SZ 128
+#endif
+
+#if defined __x86_64__
+#  ifndef __NR_name_to_handle_at
+#    define __NR_name_to_handle_at 303
+#  endif
+#elif defined __i386__
+#  ifndef __NR_name_to_handle_at
+#    define __NR_name_to_handle_at 341
+#  endif
+#elif defined __arm__
+#  ifndef __NR_name_to_handle_at
+#    define __NR_name_to_handle_at 370
+#  endif
+#elif defined __powerpc__
+#  ifndef __NR_name_to_handle_at
+#    define __NR_name_to_handle_at 345
+#  endif
+#else
+#  ifndef __NR_name_to_handle_at
+#    error __NR_name_to_handle_at is not defined
+#  endif
+#endif
+
+#if !HAVE_DECL_NAME_TO_HANDLE_AT
+struct file_handle {
+        unsigned int handle_bytes;
+        int handle_type;
+        unsigned char f_handle[0];
+};
+
+static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) {
+        return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags);
+}
+#endif
+
+#ifndef HAVE_SECURE_GETENV
+#  ifdef HAVE___SECURE_GETENV
+#    define secure_getenv __secure_getenv
+#  else
+#    error neither secure_getenv nor __secure_getenv are available
+#  endif
+#endif
+
+#ifndef CIFS_MAGIC_NUMBER
+#define CIFS_MAGIC_NUMBER 0xFF534D42
+#endif
+
+#ifndef TFD_TIMER_CANCEL_ON_SET
+#define TFD_TIMER_CANCEL_ON_SET (1 << 1)
+#endif
diff --git a/src/shared/mkdir.c b/src/shared/mkdir.c
new file mode 100644 (file)
index 0000000..0e51b64
--- /dev/null
@@ -0,0 +1,147 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mkdir.h"
+#include "label.h"
+#include "util.h"
+
+int mkdir_label(const char *path, mode_t mode) {
+        return label_mkdir(path, mode, true);
+}
+
+static int makedir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool apply) {
+        struct stat st;
+
+        if (label_mkdir(path, mode, apply) >= 0)
+                if (chmod_and_chown(path, mode, uid, gid) < 0)
+                        return -errno;
+
+        if (lstat(path, &st) < 0)
+                return -errno;
+
+        if ((st.st_mode & 0777) != mode ||
+            st.st_uid != uid ||
+            st.st_gid != gid ||
+            !S_ISDIR(st.st_mode)) {
+                errno = EEXIST;
+                return -errno;
+        }
+
+        return 0;
+}
+
+int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid) {
+        return makedir_safe(path, mode, uid, gid, false);
+}
+
+int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid) {
+        return makedir_safe(path, mode, uid, gid, true);
+}
+
+static int makedir_parents(const char *path, mode_t mode, bool apply) {
+        struct stat st;
+        const char *p, *e;
+
+        assert(path);
+
+        /* return immediately if directory exists */
+        e = strrchr(path, '/');
+        if (!e)
+                return -EINVAL;
+        p = strndupa(path, e - path);
+        if (stat(p, &st) >= 0) {
+                if ((st.st_mode & S_IFMT) == S_IFDIR)
+                        return 0;
+                else
+                        return -ENOTDIR;
+        }
+
+        /* create every parent directory in the path, except the last component */
+        p = path + strspn(path, "/");
+        for (;;) {
+                int r;
+                char *t;
+
+                e = p + strcspn(p, "/");
+                p = e + strspn(e, "/");
+
+                /* Is this the last component? If so, then we're
+                 * done */
+                if (*p == 0)
+                        return 0;
+
+                t = strndup(path, e - path);
+                if (!t)
+                        return -ENOMEM;
+
+                r = label_mkdir(t, mode, apply);
+                free(t);
+
+                if (r < 0 && errno != EEXIST)
+                        return -errno;
+        }
+}
+
+int mkdir_parents(const char *path, mode_t mode) {
+        return makedir_parents(path, mode, false);
+}
+
+int mkdir_parents_label(const char *path, mode_t mode) {
+        return makedir_parents(path, mode, true);
+}
+
+static int is_dir(const char* path) {
+        struct stat st;
+        if (stat(path, &st) < 0)
+                return -errno;
+        return S_ISDIR(st.st_mode);
+}
+
+static int makedir_p(const char *path, mode_t mode, bool apply) {
+        int r;
+
+        /* Like mkdir -p */
+
+        r = makedir_parents(path, mode, apply);
+        if (r < 0)
+                return r;
+
+        r = label_mkdir(path, mode, apply);
+        if (r < 0 && (errno != EEXIST || is_dir(path) <= 0))
+                return -errno;
+
+        return 0;
+}
+
+int mkdir_p(const char *path, mode_t mode) {
+        return makedir_p(path, mode, false);
+}
+
+int mkdir_p_label(const char *path, mode_t mode) {
+        return makedir_p(path, mode, true);
+}
diff --git a/src/shared/mkdir.h b/src/shared/mkdir.h
new file mode 100644 (file)
index 0000000..ce1c35e
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foomkdirhfoo
+#define foomkdirhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int mkdir_label(const char *path, mode_t mode);
+int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid);
+int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid);
+int mkdir_parents(const char *path, mode_t mode);
+int mkdir_parents_label(const char *path, mode_t mode);
+int mkdir_p(const char *path, mode_t mode);
+int mkdir_p_label(const char *path, mode_t mode);
+#endif
diff --git a/src/shared/pager.c b/src/shared/pager.c
new file mode 100644 (file)
index 0000000..488a12c
--- /dev/null
@@ -0,0 +1,143 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/prctl.h>
+
+#include "pager.h"
+#include "util.h"
+#include "macro.h"
+
+static pid_t pager_pid = 0;
+
+_noreturn_ static void pager_fallback(void) {
+        ssize_t n;
+        do {
+                n = splice(STDIN_FILENO, NULL, STDOUT_FILENO, NULL, 64*1024, 0);
+        } while (n > 0);
+        if (n < 0) {
+                log_error("Internal pager failed: %m");
+                _exit(EXIT_FAILURE);
+        }
+        _exit(EXIT_SUCCESS);
+}
+
+int pager_open(void) {
+        int fd[2];
+        const char *pager;
+        pid_t parent_pid;
+        int r;
+
+        if (pager_pid > 0)
+                return 1;
+
+        if ((pager = getenv("SYSTEMD_PAGER")) || (pager = getenv("PAGER")))
+                if (!*pager || streq(pager, "cat"))
+                        return 0;
+
+        if (!on_tty())
+                return 0;
+
+        /* Determine and cache number of columns before we spawn the
+         * pager so that we get the value from the actual tty */
+        columns();
+
+        if (pipe(fd) < 0) {
+                log_error("Failed to create pager pipe: %m");
+                return -errno;
+        }
+
+        parent_pid = getpid();
+
+        pager_pid = fork();
+        if (pager_pid < 0) {
+                r = -errno;
+                log_error("Failed to fork pager: %m");
+                close_pipe(fd);
+                return r;
+        }
+
+        /* In the child start the pager */
+        if (pager_pid == 0) {
+
+                dup2(fd[0], STDIN_FILENO);
+                close_pipe(fd);
+
+                setenv("LESS", "FRSX", 0);
+
+                /* Make sure the pager goes away when the parent dies */
+                if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
+                        _exit(EXIT_FAILURE);
+
+                /* Check whether our parent died before we were able
+                 * to set the death signal */
+                if (getppid() != parent_pid)
+                        _exit(EXIT_SUCCESS);
+
+                if (pager) {
+                        execlp(pager, pager, NULL);
+                        execl("/bin/sh", "sh", "-c", pager, NULL);
+                }
+
+                /* Debian's alternatives command for pagers is
+                 * called 'pager'. Note that we do not call
+                 * sensible-pagers here, since that is just a
+                 * shell script that implements a logic that
+                 * is similar to this one anyway, but is
+                 * Debian-specific. */
+                execlp("pager", "pager", NULL);
+
+                execlp("less", "less", NULL);
+                execlp("more", "more", NULL);
+
+                pager_fallback();
+                /* not reached */
+        }
+
+        /* Return in the parent */
+        if (dup2(fd[1], STDOUT_FILENO) < 0) {
+                log_error("Failed to duplicate pager pipe: %m");
+                return -errno;
+        }
+
+        close_pipe(fd);
+        return 1;
+}
+
+void pager_close(void) {
+
+        if (pager_pid <= 0)
+                return;
+
+        /* Inform pager that we are done */
+        fclose(stdout);
+        kill(pager_pid, SIGCONT);
+        wait_for_terminate(pager_pid, NULL);
+        pager_pid = 0;
+}
+
+bool pager_have(void) {
+        return pager_pid > 0;
+}
diff --git a/src/shared/pager.h b/src/shared/pager.h
new file mode 100644 (file)
index 0000000..5e7b5ab
--- /dev/null
@@ -0,0 +1,28 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+int pager_open(void);
+void pager_close(void);
+bool pager_have(void);
diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
new file mode 100644 (file)
index 0000000..6e5529e
--- /dev/null
@@ -0,0 +1,430 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "util.h"
+#include "mkdir.h"
+#include "strv.h"
+#include "path-util.h"
+#include "path-lookup.h"
+
+static const char* const systemd_running_as_table[_SYSTEMD_RUNNING_AS_MAX] = {
+        [SYSTEMD_SYSTEM] = "system",
+        [SYSTEMD_USER] = "user"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(systemd_running_as, SystemdRunningAs);
+
+int user_config_home(char **config_home) {
+        const char *e;
+
+        e = getenv("XDG_CONFIG_HOME");
+        if (e) {
+                if (asprintf(config_home, "%s/systemd/user", e) < 0)
+                        return -ENOMEM;
+
+                return 1;
+        } else {
+                const char *home;
+
+                home = getenv("HOME");
+                if (home) {
+                        if (asprintf(config_home, "%s/.config/systemd/user", home) < 0)
+                                return -ENOMEM;
+
+                        return 1;
+                }
+        }
+
+        return 0;
+}
+
+static char** user_dirs(
+                const char *generator,
+                const char *generator_early,
+                const char *generator_late) {
+
+        const char * const config_unit_paths[] = {
+                USER_CONFIG_UNIT_PATH,
+                "/etc/systemd/user",
+                "/run/systemd/user",
+                NULL
+        };
+
+        const char * const data_unit_paths[] = {
+                "/usr/local/lib/systemd/user",
+                "/usr/local/share/systemd/user",
+                USER_DATA_UNIT_PATH,
+                "/usr/lib/systemd/user",
+                "/usr/share/systemd/user",
+                NULL
+        };
+
+        const char *home, *e;
+        char *config_home = NULL, *data_home = NULL;
+        char **config_dirs = NULL, **data_dirs = NULL;
+        char **r = NULL, **t;
+
+        /* Implement the mechanisms defined in
+         *
+         * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
+         *
+         * We look in both the config and the data dirs because we
+         * want to encourage that distributors ship their unit files
+         * as data, and allow overriding as configuration.
+         */
+
+        if (user_config_home(&config_home) < 0)
+                goto fail;
+
+        home = getenv("HOME");
+
+        e = getenv("XDG_CONFIG_DIRS");
+        if (e) {
+                config_dirs = strv_split(e, ":");
+                if (!config_dirs)
+                        goto fail;
+        }
+
+        /* We don't treat /etc/xdg/systemd here as the spec
+         * suggests because we assume that that is a link to
+         * /etc/systemd/ anyway. */
+
+        e = getenv("XDG_DATA_HOME");
+        if (e) {
+                if (asprintf(&data_home, "%s/systemd/user", e) < 0)
+                        goto fail;
+
+        } else if (home) {
+                if (asprintf(&data_home, "%s/.local/share/systemd/user", home) < 0)
+                        goto fail;
+
+                /* There is really no need for two unit dirs in $HOME,
+                 * except to be fully compliant with the XDG spec. We
+                 * now try to link the two dirs, so that we can
+                 * minimize disk seeks a little. Further down we'll
+                 * then filter out this link, if it is actually is
+                 * one. */
+
+                mkdir_parents_label(data_home, 0777);
+                (void) symlink("../../../.config/systemd/user", data_home);
+        }
+
+        e = getenv("XDG_DATA_DIRS");
+        if (e)
+                data_dirs = strv_split(e, ":");
+        else
+                data_dirs = strv_new("/usr/local/share",
+                                     "/usr/share",
+                                     NULL);
+        if (!data_dirs)
+                goto fail;
+
+        /* Now merge everything we found. */
+        if (generator_early) {
+                t = strv_append(r, generator_early);
+                if (!t)
+                        goto fail;
+                strv_free(r);
+                r = t;
+        }
+
+        if (config_home) {
+                t = strv_append(r, config_home);
+                if (!t)
+                        goto fail;
+                strv_free(r);
+                r = t;
+        }
+
+        if (!strv_isempty(config_dirs)) {
+                t = strv_merge_concat(r, config_dirs, "/systemd/user");
+                if (!t)
+                        goto finish;
+                strv_free(r);
+                r = t;
+        }
+
+        t = strv_merge(r, (char**) config_unit_paths);
+        if (!t)
+                goto fail;
+        strv_free(r);
+        r = t;
+
+        if (generator) {
+                t = strv_append(r, generator);
+                if (!t)
+                        goto fail;
+                strv_free(r);
+                r = t;
+        }
+
+        if (data_home) {
+                t = strv_append(r, data_home);
+                if (!t)
+                        goto fail;
+                strv_free(r);
+                r = t;
+        }
+
+        if (!strv_isempty(data_dirs)) {
+                t = strv_merge_concat(r, data_dirs, "/systemd/user");
+                if (!t)
+                        goto fail;
+                strv_free(r);
+                r = t;
+        }
+
+        t = strv_merge(r, (char**) data_unit_paths);
+        if (!t)
+                goto fail;
+        strv_free(r);
+        r = t;
+
+        if (generator_late) {
+                t = strv_append(r, generator_late);
+                if (!t)
+                        goto fail;
+                strv_free(r);
+                r = t;
+        }
+
+        if (!path_strv_make_absolute_cwd(r))
+                goto fail;
+
+finish:
+        free(config_home);
+        strv_free(config_dirs);
+        free(data_home);
+        strv_free(data_dirs);
+
+        return r;
+
+fail:
+        strv_free(r);
+        r = NULL;
+        goto finish;
+}
+
+int lookup_paths_init(
+                LookupPaths *p,
+                SystemdRunningAs running_as,
+                bool personal,
+                const char *generator,
+                const char *generator_early,
+                const char *generator_late) {
+
+        const char *e;
+        char *t;
+
+        assert(p);
+
+        /* First priority is whatever has been passed to us via env
+         * vars */
+        e = getenv("SYSTEMD_UNIT_PATH");
+        if (e) {
+                p->unit_path = path_split_and_make_absolute(e);
+                if (!p->unit_path)
+                        return -ENOMEM;
+        } else
+                p->unit_path = NULL;
+
+        if (strv_isempty(p->unit_path)) {
+                /* Nothing is set, so let's figure something out. */
+                strv_free(p->unit_path);
+
+                /* For the user units we include share/ in the search
+                 * path in order to comply with the XDG basedir
+                 * spec. For the system stuff we avoid such
+                 * nonsense. OTOH we include /lib in the search path
+                 * for the system stuff but avoid it for user
+                 * stuff. */
+
+                if (running_as == SYSTEMD_USER) {
+
+                        if (personal)
+                                p->unit_path = user_dirs(generator, generator_early, generator_late);
+                        else
+                                p->unit_path = strv_new(
+                                                /* If you modify this you also want to modify
+                                                 * systemduserunitpath= in systemd.pc.in, and
+                                                 * the arrays in user_dirs() above! */
+                                                STRV_IFNOTNULL(generator_early),
+                                                USER_CONFIG_UNIT_PATH,
+                                                "/etc/systemd/user",
+                                                "/run/systemd/user",
+                                                STRV_IFNOTNULL(generator),
+                                                "/usr/local/lib/systemd/user",
+                                                "/usr/local/share/systemd/user",
+                                                USER_DATA_UNIT_PATH,
+                                                "/usr/lib/systemd/user",
+                                                "/usr/share/systemd/user",
+                                                STRV_IFNOTNULL(generator_late),
+                                                NULL);
+
+                        if (!p->unit_path)
+                                return -ENOMEM;
+
+                } else {
+                        p->unit_path = strv_new(
+                                        /* If you modify this you also want to modify
+                                         * systemdsystemunitpath= in systemd.pc.in! */
+                                        STRV_IFNOTNULL(generator_early),
+                                        SYSTEM_CONFIG_UNIT_PATH,
+                                        "/etc/systemd/system",
+                                        "/run/systemd/system",
+                                        STRV_IFNOTNULL(generator),
+                                        "/usr/local/lib/systemd/system",
+                                        SYSTEM_DATA_UNIT_PATH,
+                                        "/usr/lib/systemd/system",
+#ifdef HAVE_SPLIT_USR
+                                        "/lib/systemd/system",
+#endif
+                                        STRV_IFNOTNULL(generator_late),
+                                        NULL);
+
+                        if (!p->unit_path)
+                                return -ENOMEM;
+                }
+        }
+
+        if (!path_strv_canonicalize(p->unit_path))
+                return -ENOMEM;
+
+        strv_uniq(p->unit_path);
+        path_strv_remove_empty(p->unit_path);
+
+        if (!strv_isempty(p->unit_path)) {
+
+                t = strv_join(p->unit_path, "\n\t");
+                if (!t)
+                        return -ENOMEM;
+                log_debug("Looking for unit files in:\n\t%s", t);
+                free(t);
+        } else {
+                log_debug("Ignoring unit files.");
+                strv_free(p->unit_path);
+                p->unit_path = NULL;
+        }
+
+        if (running_as == SYSTEMD_SYSTEM) {
+#ifdef HAVE_SYSV_COMPAT
+                /* /etc/init.d/ compatibility does not matter to users */
+
+                e = getenv("SYSTEMD_SYSVINIT_PATH");
+                if (e) {
+                        p->sysvinit_path = path_split_and_make_absolute(e);
+                        if (!p->sysvinit_path)
+                                return -ENOMEM;
+                } else
+                        p->sysvinit_path = NULL;
+
+                if (strv_isempty(p->sysvinit_path)) {
+                        strv_free(p->sysvinit_path);
+
+                        p->sysvinit_path = strv_new(
+                                        SYSTEM_SYSVINIT_PATH,     /* /etc/init.d/ */
+                                        NULL);
+                        if (!p->sysvinit_path)
+                                return -ENOMEM;
+                }
+
+                e = getenv("SYSTEMD_SYSVRCND_PATH");
+                if (e) {
+                        p->sysvrcnd_path = path_split_and_make_absolute(e);
+                        if (!p->sysvrcnd_path)
+                                return -ENOMEM;
+                } else
+                        p->sysvrcnd_path = NULL;
+
+                if (strv_isempty(p->sysvrcnd_path)) {
+                        strv_free(p->sysvrcnd_path);
+
+                        p->sysvrcnd_path = strv_new(
+                                        SYSTEM_SYSVRCND_PATH,     /* /etc/rcN.d/ */
+                                        NULL);
+                        if (!p->sysvrcnd_path)
+                                return -ENOMEM;
+                }
+
+                if (!path_strv_canonicalize(p->sysvinit_path))
+                        return -ENOMEM;
+
+                if (!path_strv_canonicalize(p->sysvrcnd_path))
+                        return -ENOMEM;
+
+                strv_uniq(p->sysvinit_path);
+                strv_uniq(p->sysvrcnd_path);
+                path_strv_remove_empty(p->sysvinit_path);
+                path_strv_remove_empty(p->sysvrcnd_path);
+
+                if (!strv_isempty(p->sysvinit_path)) {
+
+                        t = strv_join(p->sysvinit_path, "\n\t");
+                        if (!t)
+                                return -ENOMEM;
+                        log_debug("Looking for SysV init scripts in:\n\t%s", t);
+                        free(t);
+                } else {
+                        log_debug("Ignoring SysV init scripts.");
+                        strv_free(p->sysvinit_path);
+                        p->sysvinit_path = NULL;
+                }
+
+                if (!strv_isempty(p->sysvrcnd_path)) {
+
+                        t = strv_join(p->sysvrcnd_path, "\n\t");
+                        if (!t)
+                                return -ENOMEM;
+
+                        log_debug("Looking for SysV rcN.d links in:\n\t%s", t);
+                        free(t);
+                } else {
+                        log_debug("Ignoring SysV rcN.d links.");
+                        strv_free(p->sysvrcnd_path);
+                        p->sysvrcnd_path = NULL;
+                }
+#else
+                log_debug("Disabled SysV init scripts and rcN.d links support");
+#endif
+        }
+
+        return 0;
+}
+
+void lookup_paths_free(LookupPaths *p) {
+        assert(p);
+
+        strv_free(p->unit_path);
+        p->unit_path = NULL;
+
+#ifdef HAVE_SYSV_COMPAT
+        strv_free(p->sysvinit_path);
+        strv_free(p->sysvrcnd_path);
+        p->sysvinit_path = p->sysvrcnd_path = NULL;
+#endif
+}
diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h
new file mode 100644 (file)
index 0000000..baef622
--- /dev/null
@@ -0,0 +1,45 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct LookupPaths {
+        char **unit_path;
+#ifdef HAVE_SYSV_COMPAT
+        char **sysvinit_path;
+        char **sysvrcnd_path;
+#endif
+} LookupPaths;
+
+typedef enum SystemdRunningAs {
+        SYSTEMD_SYSTEM,
+        SYSTEMD_USER,
+        _SYSTEMD_RUNNING_AS_MAX,
+        _SYSTEMD_RUNNING_AS_INVALID = -1
+} SystemdRunningAs;
+
+const char* systemd_running_as_to_string(SystemdRunningAs i);
+SystemdRunningAs systemd_running_as_from_string(const char *s);
+
+int user_config_home(char **config_home);
+
+int lookup_paths_init(LookupPaths *p, SystemdRunningAs running_as, bool personal, const char *generator, const char *generator_early, const char *generator_late);
+void lookup_paths_free(LookupPaths *p);
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
new file mode 100644 (file)
index 0000000..dd12d3d
--- /dev/null
@@ -0,0 +1,420 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010-2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/statvfs.h>
+
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+#include "strv.h"
+#include "path-util.h"
+#include "missing.h"
+
+bool path_is_absolute(const char *p) {
+        return p[0] == '/';
+}
+
+bool is_path(const char *p) {
+        return !!strchr(p, '/');
+}
+
+char *path_get_file_name(const char *p) {
+        char *r;
+
+        assert(p);
+
+        if ((r = strrchr(p, '/')))
+                return r + 1;
+
+        return (char*) p;
+}
+
+int path_get_parent(const char *path, char **_r) {
+        const char *e, *a = NULL, *b = NULL, *p;
+        char *r;
+        bool slash = false;
+
+        assert(path);
+        assert(_r);
+
+        if (!*path)
+                return -EINVAL;
+
+        for (e = path; *e; e++) {
+
+                if (!slash && *e == '/') {
+                        a = b;
+                        b = e;
+                        slash = true;
+                } else if (slash && *e != '/')
+                        slash = false;
+        }
+
+        if (*(e-1) == '/')
+                p = a;
+        else
+                p = b;
+
+        if (!p)
+                return -EINVAL;
+
+        if (p == path)
+                r = strdup("/");
+        else
+                r = strndup(path, p-path);
+
+        if (!r)
+                return -ENOMEM;
+
+        *_r = r;
+        return 0;
+}
+
+char **path_split_and_make_absolute(const char *p) {
+        char **l;
+        assert(p);
+
+        if (!(l = strv_split(p, ":")))
+                return NULL;
+
+        if (!path_strv_make_absolute_cwd(l)) {
+                strv_free(l);
+                return NULL;
+        }
+
+        return l;
+}
+
+char *path_make_absolute(const char *p, const char *prefix) {
+        assert(p);
+
+        /* Makes every item in the list an absolute path by prepending
+         * the prefix, if specified and necessary */
+
+        if (path_is_absolute(p) || !prefix)
+                return strdup(p);
+
+        return strjoin(prefix, "/", p, NULL);
+}
+
+char *path_make_absolute_cwd(const char *p) {
+        char *cwd, *r;
+
+        assert(p);
+
+        /* Similar to path_make_absolute(), but prefixes with the
+         * current working directory. */
+
+        if (path_is_absolute(p))
+                return strdup(p);
+
+        if (!(cwd = get_current_dir_name()))
+                return NULL;
+
+        r = path_make_absolute(p, cwd);
+        free(cwd);
+
+        return r;
+}
+
+char **path_strv_make_absolute_cwd(char **l) {
+        char **s;
+
+        /* Goes through every item in the string list and makes it
+         * absolute. This works in place and won't rollback any
+         * changes on failure. */
+
+        STRV_FOREACH(s, l) {
+                char *t;
+
+                if (!(t = path_make_absolute_cwd(*s)))
+                        return NULL;
+
+                free(*s);
+                *s = t;
+        }
+
+        return l;
+}
+
+char **path_strv_canonicalize(char **l) {
+        char **s;
+        unsigned k = 0;
+        bool enomem = false;
+
+        if (strv_isempty(l))
+                return l;
+
+        /* Goes through every item in the string list and canonicalize
+         * the path. This works in place and won't rollback any
+         * changes on failure. */
+
+        STRV_FOREACH(s, l) {
+                char *t, *u;
+
+                t = path_make_absolute_cwd(*s);
+                free(*s);
+                *s = NULL;
+
+                if (!t) {
+                        enomem = true;
+                        continue;
+                }
+
+                errno = 0;
+                u = canonicalize_file_name(t);
+                free(t);
+
+                if (!u) {
+                        if (errno == ENOMEM || !errno)
+                                enomem = true;
+
+                        continue;
+                }
+
+                l[k++] = u;
+        }
+
+        l[k] = NULL;
+
+        if (enomem)
+                return NULL;
+
+        return l;
+}
+
+char **path_strv_remove_empty(char **l) {
+        char **f, **t;
+
+        if (!l)
+                return NULL;
+
+        for (f = t = l; *f; f++) {
+
+                if (dir_is_empty(*f) > 0) {
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return l;
+}
+
+char *path_kill_slashes(char *path) {
+        char *f, *t;
+        bool slash = false;
+
+        /* Removes redundant inner and trailing slashes. Modifies the
+         * passed string in-place.
+         *
+         * ///foo///bar/ becomes /foo/bar
+         */
+
+        for (f = path, t = path; *f; f++) {
+
+                if (*f == '/') {
+                        slash = true;
+                        continue;
+                }
+
+                if (slash) {
+                        slash = false;
+                        *(t++) = '/';
+                }
+
+                *(t++) = *f;
+        }
+
+        /* Special rule, if we are talking of the root directory, a
+        trailing slash is good */
+
+        if (t == path && slash)
+                *(t++) = '/';
+
+        *t = 0;
+        return path;
+}
+
+char* path_startswith(const char *path, const char *prefix) {
+        assert(path);
+        assert(prefix);
+
+        if ((path[0] == '/') != (prefix[0] == '/'))
+                return NULL;
+
+        for (;;) {
+                size_t a, b;
+
+                path += strspn(path, "/");
+                prefix += strspn(prefix, "/");
+
+                if (*prefix == 0)
+                        return (char*) path;
+
+                if (*path == 0)
+                        return NULL;
+
+                a = strcspn(path, "/");
+                b = strcspn(prefix, "/");
+
+                if (a != b)
+                        return NULL;
+
+                if (memcmp(path, prefix, a) != 0)
+                        return NULL;
+
+                path += a;
+                prefix += b;
+        }
+}
+
+bool path_equal(const char *a, const char *b) {
+        assert(a);
+        assert(b);
+
+        if ((a[0] == '/') != (b[0] == '/'))
+                return false;
+
+        for (;;) {
+                size_t j, k;
+
+                a += strspn(a, "/");
+                b += strspn(b, "/");
+
+                if (*a == 0 && *b == 0)
+                        return true;
+
+                if (*a == 0 || *b == 0)
+                        return false;
+
+                j = strcspn(a, "/");
+                k = strcspn(b, "/");
+
+                if (j != k)
+                        return false;
+
+                if (memcmp(a, b, j) != 0)
+                        return false;
+
+                a += j;
+                b += k;
+        }
+}
+
+int path_is_mount_point(const char *t, bool allow_symlink) {
+        char *parent;
+        int r;
+        struct file_handle *h;
+        int mount_id, mount_id_parent;
+        struct stat a, b;
+
+        /* We are not actually interested in the file handles, but
+         * name_to_handle_at() also passes us the mount ID, hence use
+         * it but throw the handle away */
+
+        if (path_equal(t, "/"))
+                return 1;
+
+        h = alloca(MAX_HANDLE_SZ);
+        h->handle_bytes = MAX_HANDLE_SZ;
+
+        r = name_to_handle_at(AT_FDCWD, t, h, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0);
+        if (r < 0) {
+                if (errno == ENOSYS || errno == ENOTSUP)
+                        /* This kernel or file system does not support
+                         * name_to_handle_at(), hence fallback to the
+                         * traditional stat() logic */
+                        goto fallback;
+
+                if (errno == ENOENT)
+                        return 0;
+
+                return -errno;
+        }
+
+        r = path_get_parent(t, &parent);
+        if (r < 0)
+                return r;
+
+        h->handle_bytes = MAX_HANDLE_SZ;
+        r = name_to_handle_at(AT_FDCWD, parent, h, &mount_id_parent, 0);
+        free(parent);
+
+        if (r < 0) {
+                /* The parent can't do name_to_handle_at() but the
+                 * directory we are interested in can? If so, it must
+                 * be a mount point */
+                if (errno == ENOTSUP)
+                        return 1;
+
+                return -errno;
+        }
+
+        return mount_id != mount_id_parent;
+
+fallback:
+        if (allow_symlink)
+                r = stat(t, &a);
+        else
+                r = lstat(t, &a);
+
+        if (r < 0) {
+                if (errno == ENOENT)
+                        return 0;
+
+                return -errno;
+        }
+
+        r = path_get_parent(t, &parent);
+        if (r < 0)
+                return r;
+
+        r = lstat(parent, &b);
+        free(parent);
+
+        if (r < 0)
+                return -errno;
+
+        return a.st_dev != b.st_dev;
+}
+
+int path_is_read_only_fs(const char *path) {
+        struct statvfs st;
+
+        assert(path);
+
+        if (statvfs(path, &st) < 0)
+                return -errno;
+
+        return !!(st.f_flag & ST_RDONLY);
+}
diff --git a/src/shared/path-util.h b/src/shared/path-util.h
new file mode 100644 (file)
index 0000000..e81821a
--- /dev/null
@@ -0,0 +1,45 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foopathutilhfoo
+#define foopathutilhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010-2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "stdbool.h"
+
+bool is_path(const char *p);
+char **path_split_and_make_absolute(const char *p);
+char *path_get_file_name(const char *p);
+int path_get_parent(const char *path, char **parent);
+bool path_is_absolute(const char *p);
+char *path_make_absolute(const char *p, const char *prefix);
+char *path_make_absolute_cwd(const char *p);
+char *path_kill_slashes(char *path);
+char *path_startswith(const char *path, const char *prefix);
+bool path_equal(const char *a, const char *b);
+
+char **path_strv_make_absolute_cwd(char **l);
+char **path_strv_canonicalize(char **l);
+char **path_strv_remove_empty(char **l);
+
+int path_is_mount_point(const char *path, bool allow_symlink);
+int path_is_read_only_fs(const char *path);
+
+#endif
diff --git a/src/shared/polkit.c b/src/shared/polkit.c
new file mode 100644 (file)
index 0000000..8269445
--- /dev/null
@@ -0,0 +1,166 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+#include <errno.h>
+
+#include "util.h"
+#include "dbus-common.h"
+#include "polkit.h"
+
+int verify_polkit(
+                DBusConnection *c,
+                DBusMessage *request,
+                const char *action,
+                bool interactive,
+                bool *_challenge,
+                DBusError *error) {
+
+        DBusMessage *m = NULL, *reply = NULL;
+        const char *unix_process = "unix-process", *pid = "pid", *starttime = "start-time", *cancel_id = "";
+        const char *sender;
+        uint32_t flags = interactive ? 1 : 0;
+        pid_t pid_raw;
+        uint32_t pid_u32;
+        unsigned long long starttime_raw;
+        uint64_t starttime_u64;
+        DBusMessageIter iter_msg, iter_struct, iter_array, iter_dict, iter_variant;
+        int r;
+        dbus_bool_t authorized = FALSE, challenge = FALSE;
+        unsigned long ul;
+
+        assert(c);
+        assert(request);
+
+        sender = dbus_message_get_sender(request);
+        if (!sender)
+                return -EINVAL;
+
+        ul = dbus_bus_get_unix_user(c, sender, error);
+        if (ul == (unsigned long) -1)
+                return -EINVAL;
+
+        /* Shortcut things for root, to avoid the PK roundtrip and dependency */
+        if (ul == 0)
+                return 1;
+
+        pid_raw = bus_get_unix_process_id(c, sender, error);
+        if (pid_raw == 0)
+                return -EINVAL;
+
+        r = get_starttime_of_pid(pid_raw, &starttime_raw);
+        if (r < 0)
+                return r;
+
+        m = dbus_message_new_method_call(
+                        "org.freedesktop.PolicyKit1",
+                        "/org/freedesktop/PolicyKit1/Authority",
+                        "org.freedesktop.PolicyKit1.Authority",
+                        "CheckAuthorization");
+        if (!m)
+                return -ENOMEM;
+
+        dbus_message_iter_init_append(m, &iter_msg);
+
+        pid_u32 = (uint32_t) pid_raw;
+        starttime_u64 = (uint64_t) starttime_raw;
+
+        if (!dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_STRUCT, NULL, &iter_struct) ||
+            !dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &unix_process) ||
+            !dbus_message_iter_open_container(&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_array) ||
+            !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) ||
+            !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &pid) ||
+            !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "u", &iter_variant) ||
+            !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT32, &pid_u32) ||
+            !dbus_message_iter_close_container(&iter_dict, &iter_variant) ||
+            !dbus_message_iter_close_container(&iter_array, &iter_dict) ||
+            !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) ||
+            !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &starttime) ||
+            !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "t", &iter_variant) ||
+            !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT64, &starttime_u64) ||
+            !dbus_message_iter_close_container(&iter_dict, &iter_variant) ||
+            !dbus_message_iter_close_container(&iter_array, &iter_dict) ||
+            !dbus_message_iter_close_container(&iter_struct, &iter_array) ||
+            !dbus_message_iter_close_container(&iter_msg, &iter_struct) ||
+            !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &action) ||
+            !dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_ARRAY, "{ss}", &iter_array) ||
+            !dbus_message_iter_close_container(&iter_msg, &iter_array) ||
+            !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_UINT32, &flags) ||
+            !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &cancel_id)) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        reply = dbus_connection_send_with_reply_and_block(c, m, -1, error);
+        if (!reply) {
+
+                /* Treat no PK available as access denied */
+                if (dbus_error_has_name(error, DBUS_ERROR_SERVICE_UNKNOWN)) {
+                        r = -EACCES;
+                        dbus_error_free(error);
+                        goto finish;
+                }
+
+                r = -EIO;
+                goto finish;
+        }
+
+        if (!dbus_message_iter_init(reply, &iter_msg) ||
+            dbus_message_iter_get_arg_type(&iter_msg) != DBUS_TYPE_STRUCT) {
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter_msg, &iter_struct);
+
+        if (dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) {
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_get_basic(&iter_struct, &authorized);
+
+        if (!dbus_message_iter_next(&iter_struct) ||
+            dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) {
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_get_basic(&iter_struct, &challenge);
+
+        if (authorized)
+                r = 1;
+        else if (_challenge) {
+                *_challenge = !!challenge;
+                r = 0;
+        } else
+                r = -EPERM;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
diff --git a/src/shared/polkit.h b/src/shared/polkit.h
new file mode 100644 (file)
index 0000000..6255d1f
--- /dev/null
@@ -0,0 +1,33 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <dbus/dbus.h>
+
+int verify_polkit(
+                DBusConnection *c,
+                DBusMessage *request,
+                const char *action,
+                bool interactive,
+                bool *challenge,
+                DBusError *error);
diff --git a/src/shared/ratelimit.c b/src/shared/ratelimit.c
new file mode 100644 (file)
index 0000000..1054d52
--- /dev/null
@@ -0,0 +1,57 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+
+#include "ratelimit.h"
+#include "log.h"
+
+/* Modelled after Linux' lib/ratelimit.c by Dave Young
+ * <hidave.darkstar@gmail.com>, which is licensed GPLv2. */
+
+bool ratelimit_test(RateLimit *r) {
+        usec_t ts;
+
+        assert(r);
+
+        if (r->interval <= 0 || r->burst <= 0)
+                return true;
+
+        ts = now(CLOCK_MONOTONIC);
+
+        if (r->begin <= 0 ||
+            r->begin + r->interval < ts) {
+                r->begin = ts;
+
+                /* Reset counter */
+                r->num = 0;
+                goto good;
+        }
+
+        if (r->num <= r->burst)
+                goto good;
+
+        return false;
+
+good:
+        r->num++;
+        return true;
+}
diff --git a/src/shared/ratelimit.h b/src/shared/ratelimit.h
new file mode 100644 (file)
index 0000000..58efca7
--- /dev/null
@@ -0,0 +1,57 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+
+typedef struct RateLimit {
+        usec_t interval;
+        usec_t begin;
+        unsigned burst;
+        unsigned num;
+} RateLimit;
+
+#define RATELIMIT_DEFINE(_name, _interval, _burst)       \
+        RateLimit _name = {                              \
+                .interval = (_interval),                 \
+                .burst = (_burst),                       \
+                .num = 0,                                \
+                .begin = 0                               \
+        }
+
+#define RATELIMIT_INIT(v, _interval, _burst)             \
+        do {                                             \
+                RateLimit *_r = &(v);                    \
+                _r->interval = (_interval);              \
+                _r->burst = (_burst);                    \
+                _r->num = 0;                             \
+                _r->begin = 0;                           \
+        } while (false)
+
+#define RATELIMIT_RESET(v)                               \
+        do {                                             \
+                RateLimit *_r = &(v);                    \
+                _r->num = 0;                             \
+                _r->begin = 0;                           \
+        } while (false)
+
+bool ratelimit_test(RateLimit *r);
diff --git a/src/shared/replace-var.c b/src/shared/replace-var.c
new file mode 100644 (file)
index 0000000..e11c57a
--- /dev/null
@@ -0,0 +1,110 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "macro.h"
+#include "util.h"
+#include "replace-var.h"
+
+/*
+ * Generic infrastructure for replacing @FOO@ style variables in
+ * strings. Will call a callback for each replacement.
+ */
+
+static int get_variable(const char *b, char **r) {
+        size_t k;
+        char *t;
+
+        assert(b);
+        assert(r);
+
+        if (*b != '@')
+                return 0;
+
+        k = strspn(b + 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ_");
+        if (k <= 0 || b[k+1] != '@')
+                return 0;
+
+        t = strndup(b + 1, k);
+        if (!t)
+                return -ENOMEM;
+
+        *r = t;
+        return 1;
+}
+
+char *replace_var(const char *text, char *(*lookup)(const char *variable, void*userdata), void *userdata) {
+        char *r, *t;
+        const char *f;
+        size_t l;
+
+        assert(text);
+        assert(lookup);
+
+        l = strlen(text);
+        r = new(char, l+1);
+        if (!r)
+                return NULL;
+
+        f = text;
+        t = r;
+        while (*f) {
+                _cleanup_free_ char *v = NULL, *n = NULL;
+                char *a;
+                int k;
+                size_t skip, d, nl;
+
+                k = get_variable(f, &v);
+                if (k < 0)
+                        goto oom;
+                if (k == 0) {
+                        *(t++) = *(f++);
+                        continue;
+                }
+
+                n = lookup(v, userdata);
+                if (!n)
+                        goto oom;
+
+                skip = strlen(v) + 2;
+
+                d = t - r;
+                nl = l - skip + strlen(n);
+                a = realloc(r, nl + 1);
+                if (!a)
+                        goto oom;
+
+                l = nl;
+                r = a;
+                t = r + d;
+
+                t = stpcpy(t, n);
+                f += skip;
+        }
+
+        *t = 0;
+        return r;
+
+oom:
+        free(r);
+        return NULL;
+}
diff --git a/src/shared/replace-var.h b/src/shared/replace-var.h
new file mode 100644 (file)
index 0000000..7eaee93
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+char *replace_var(const char *text, char *(*lookup)(const char *variable, void*userdata), void *userdata);
diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c
new file mode 100644 (file)
index 0000000..ff33756
--- /dev/null
@@ -0,0 +1,42 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "selinux-util.h"
+
+#ifdef HAVE_SELINUX
+
+#include <selinux/selinux.h>
+
+static int use_selinux_cached = -1;
+
+bool use_selinux(void) {
+
+        if (use_selinux_cached < 0)
+                use_selinux_cached = is_selinux_enabled() > 0;
+
+        return use_selinux_cached;
+}
+
+void retest_selinux(void) {
+        use_selinux_cached = -1;
+}
+
+#endif
diff --git a/src/shared/selinux-util.h b/src/shared/selinux-util.h
new file mode 100644 (file)
index 0000000..4b81202
--- /dev/null
@@ -0,0 +1,27 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+bool use_selinux(void);
+void retest_selinux(void);
diff --git a/src/shared/set.c b/src/shared/set.c
new file mode 100644 (file)
index 0000000..5f83c50
--- /dev/null
@@ -0,0 +1,130 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+
+#include "set.h"
+#include "hashmap.h"
+
+#define MAKE_SET(h) ((Set*) (h))
+#define MAKE_HASHMAP(s) ((Hashmap*) (s))
+
+/* For now this is not much more than a wrapper around a hashmap */
+
+Set *set_new(hash_func_t hash_func, compare_func_t compare_func) {
+        return MAKE_SET(hashmap_new(hash_func, compare_func));
+}
+
+void set_free(Set* s) {
+        hashmap_free(MAKE_HASHMAP(s));
+}
+
+void set_free_free(Set *s) {
+        hashmap_free_free(MAKE_HASHMAP(s));
+}
+
+int set_ensure_allocated(Set **s, hash_func_t hash_func, compare_func_t compare_func) {
+        return hashmap_ensure_allocated((Hashmap**) s, hash_func, compare_func);
+}
+
+int set_put(Set *s, void *value) {
+        return hashmap_put(MAKE_HASHMAP(s), value, value);
+}
+
+int set_replace(Set *s, void *value) {
+        return hashmap_replace(MAKE_HASHMAP(s), value, value);
+}
+
+void *set_get(Set *s, void *value) {
+        return hashmap_get(MAKE_HASHMAP(s), value);
+}
+
+bool set_contains(Set *s, void *value) {
+        return hashmap_contains(MAKE_HASHMAP(s), value);
+}
+
+void *set_remove(Set *s, void *value) {
+        return hashmap_remove(MAKE_HASHMAP(s), value);
+}
+
+int set_remove_and_put(Set *s, void *old_value, void *new_value) {
+        return hashmap_remove_and_put(MAKE_HASHMAP(s), old_value, new_value, new_value);
+}
+
+unsigned set_size(Set *s) {
+        return hashmap_size(MAKE_HASHMAP(s));
+}
+
+bool set_isempty(Set *s) {
+        return hashmap_isempty(MAKE_HASHMAP(s));
+}
+
+void *set_iterate(Set *s, Iterator *i) {
+        return hashmap_iterate(MAKE_HASHMAP(s), i, NULL);
+}
+
+void *set_iterate_backwards(Set *s, Iterator *i) {
+        return hashmap_iterate_backwards(MAKE_HASHMAP(s), i, NULL);
+}
+
+void *set_iterate_skip(Set *s, void *value, Iterator *i) {
+        return hashmap_iterate_skip(MAKE_HASHMAP(s), value, i);
+}
+
+void *set_steal_first(Set *s) {
+        return hashmap_steal_first(MAKE_HASHMAP(s));
+}
+
+void* set_first(Set *s) {
+        return hashmap_first(MAKE_HASHMAP(s));
+}
+
+void* set_last(Set *s) {
+        return hashmap_last(MAKE_HASHMAP(s));
+}
+
+int set_merge(Set *s, Set *other) {
+        return hashmap_merge(MAKE_HASHMAP(s), MAKE_HASHMAP(other));
+}
+
+void set_move(Set *s, Set *other) {
+        return hashmap_move(MAKE_HASHMAP(s), MAKE_HASHMAP(other));
+}
+
+int set_move_one(Set *s, Set *other, void *value) {
+        return hashmap_move_one(MAKE_HASHMAP(s), MAKE_HASHMAP(other), value);
+}
+
+Set* set_copy(Set *s) {
+        return MAKE_SET(hashmap_copy(MAKE_HASHMAP(s)));
+}
+
+void set_clear(Set *s) {
+        hashmap_clear(MAKE_HASHMAP(s));
+}
+
+void set_clear_free(Set *s) {
+        hashmap_clear_free(MAKE_HASHMAP(s));
+}
+
+char **set_get_strv(Set *s) {
+        return hashmap_get_strv(MAKE_HASHMAP(s));
+}
diff --git a/src/shared/set.h b/src/shared/set.h
new file mode 100644 (file)
index 0000000..9162e2a
--- /dev/null
@@ -0,0 +1,71 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* Pretty straightforward set implementation. Internally based on the
+ * hashmap. That means that as a minor optimization a NULL set
+ * object will be treated as empty set for all read
+ * operations. That way it is not necessary to instantiate an object
+ * for each set use. */
+
+#include "hashmap.h"
+
+typedef struct Set Set;
+
+Set *set_new(hash_func_t hash_func, compare_func_t compare_func);
+void set_free(Set* s);
+void set_free_free(Set *s);
+Set* set_copy(Set *s);
+int set_ensure_allocated(Set **s, hash_func_t hash_func, compare_func_t compare_func);
+
+int set_put(Set *s, void *value);
+int set_replace(Set *s, void *value);
+void *set_get(Set *s, void *value);
+bool set_contains(Set *s, void *value);
+void *set_remove(Set *s, void *value);
+int set_remove_and_put(Set *s, void *old_value, void *new_value);
+
+int set_merge(Set *s, Set *other);
+void set_move(Set *s, Set *other);
+int set_move_one(Set *s, Set *other, void *value);
+
+unsigned set_size(Set *s);
+bool set_isempty(Set *s);
+
+void *set_iterate(Set *s, Iterator *i);
+void *set_iterate_backwards(Set *s, Iterator *i);
+void *set_iterate_skip(Set *s, void *value, Iterator *i);
+
+void set_clear(Set *s);
+void set_clear_free(Set *s);
+
+void *set_steal_first(Set *s);
+void* set_first(Set *s);
+void* set_last(Set *s);
+
+char **set_get_strv(Set *s);
+
+#define SET_FOREACH(e, s, i) \
+        for ((i) = ITERATOR_FIRST, (e) = set_iterate((s), &(i)); (e); (e) = set_iterate((s), &(i)))
+
+#define SET_FOREACH_BACKWARDS(e, s, i) \
+        for ((i) = ITERATOR_LAST, (e) = set_iterate_backwards((s), &(i)); (e); (e) = set_iterate_backwards((s), &(i)))
diff --git a/src/shared/socket-label.c b/src/shared/socket-label.c
new file mode 100644 (file)
index 0000000..ff212de
--- /dev/null
@@ -0,0 +1,143 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <sys/ioctl.h>
+
+#include "macro.h"
+#include "util.h"
+#include "mkdir.h"
+#include "socket-util.h"
+#include "missing.h"
+#include "label.h"
+
+int socket_address_listen(
+                const SocketAddress *a,
+                int backlog,
+                SocketAddressBindIPv6Only only,
+                const char *bind_to_device,
+                bool free_bind,
+                bool transparent,
+                mode_t directory_mode,
+                mode_t socket_mode,
+                const char *label,
+                int *ret) {
+
+        int r, fd, one;
+        assert(a);
+        assert(ret);
+
+        if ((r = socket_address_verify(a)) < 0)
+                return r;
+
+        if (socket_address_family(a) == AF_INET6 && !socket_ipv6_is_supported())
+                return -EAFNOSUPPORT;
+
+        r = label_socket_set(label);
+        if (r < 0)
+                return r;
+
+        fd = socket(socket_address_family(a), a->type | SOCK_NONBLOCK | SOCK_CLOEXEC, a->protocol);
+        r = fd < 0 ? -errno : 0;
+
+        label_socket_clear();
+
+        if (r < 0)
+                return r;
+
+        if (socket_address_family(a) == AF_INET6 && only != SOCKET_ADDRESS_DEFAULT) {
+                int flag = only == SOCKET_ADDRESS_IPV6_ONLY;
+
+                if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) < 0)
+                        goto fail;
+        }
+
+        if (socket_address_family(a) == AF_INET || socket_address_family(a) == AF_INET6) {
+                if (bind_to_device)
+                        if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, bind_to_device, strlen(bind_to_device)+1) < 0)
+                                goto fail;
+
+                if (free_bind) {
+                        one = 1;
+                        if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &one, sizeof(one)) < 0)
+                                log_warning("IP_FREEBIND failed: %m");
+                }
+
+                if (transparent) {
+                        one = 1;
+                        if (setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &one, sizeof(one)) < 0)
+                                log_warning("IP_TRANSPARENT failed: %m");
+                }
+        }
+
+        one = 1;
+        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
+                goto fail;
+
+        if (socket_address_family(a) == AF_UNIX && a->sockaddr.un.sun_path[0] != 0) {
+                mode_t old_mask;
+
+                /* Create parents */
+                mkdir_parents_label(a->sockaddr.un.sun_path, directory_mode);
+
+                /* Enforce the right access mode for the socket*/
+                old_mask = umask(~ socket_mode);
+
+                /* Include the original umask in our mask */
+                umask(~socket_mode | old_mask);
+
+                r = label_bind(fd, &a->sockaddr.sa, a->size);
+
+                if (r < 0 && errno == EADDRINUSE) {
+                        /* Unlink and try again */
+                        unlink(a->sockaddr.un.sun_path);
+                        r = bind(fd, &a->sockaddr.sa, a->size);
+                }
+
+                umask(old_mask);
+        } else
+                r = bind(fd, &a->sockaddr.sa, a->size);
+
+        if (r < 0)
+                goto fail;
+
+        if (socket_address_can_accept(a))
+                if (listen(fd, backlog) < 0)
+                        goto fail;
+
+        *ret = fd;
+        return 0;
+
+fail:
+        r = -errno;
+        close_nointr_nofail(fd);
+        return r;
+}
diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c
new file mode 100644 (file)
index 0000000..56ec99f
--- /dev/null
@@ -0,0 +1,595 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <sys/ioctl.h>
+
+#include "macro.h"
+#include "util.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "socket-util.h"
+#include "missing.h"
+
+int socket_address_parse(SocketAddress *a, const char *s) {
+        int r;
+        char *e, *n;
+        unsigned u;
+
+        assert(a);
+        assert(s);
+
+        zero(*a);
+        a->type = SOCK_STREAM;
+
+        if (*s == '[') {
+                /* IPv6 in [x:.....:z]:p notation */
+
+                if (!socket_ipv6_is_supported()) {
+                        log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
+                        return -EAFNOSUPPORT;
+                }
+
+                if (!(e = strchr(s+1, ']')))
+                        return -EINVAL;
+
+                if (!(n = strndup(s+1, e-s-1)))
+                        return -ENOMEM;
+
+                errno = 0;
+                if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) {
+                        free(n);
+                        return errno != 0 ? -errno : -EINVAL;
+                }
+
+                free(n);
+
+                e++;
+                if (*e != ':')
+                        return -EINVAL;
+
+                e++;
+                if ((r = safe_atou(e, &u)) < 0)
+                        return r;
+
+                if (u <= 0 || u > 0xFFFF)
+                        return -EINVAL;
+
+                a->sockaddr.in6.sin6_family = AF_INET6;
+                a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+                a->size = sizeof(struct sockaddr_in6);
+
+        } else if (*s == '/') {
+                /* AF_UNIX socket */
+
+                size_t l;
+
+                l = strlen(s);
+                if (l >= sizeof(a->sockaddr.un.sun_path))
+                        return -EINVAL;
+
+                a->sockaddr.un.sun_family = AF_UNIX;
+                memcpy(a->sockaddr.un.sun_path, s, l);
+                a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
+
+        } else if (*s == '@') {
+                /* Abstract AF_UNIX socket */
+                size_t l;
+
+                l = strlen(s+1);
+                if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
+                        return -EINVAL;
+
+                a->sockaddr.un.sun_family = AF_UNIX;
+                memcpy(a->sockaddr.un.sun_path+1, s+1, l);
+                a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
+
+        } else {
+
+                if ((e = strchr(s, ':'))) {
+
+                        if ((r = safe_atou(e+1, &u)) < 0)
+                                return r;
+
+                        if (u <= 0 || u > 0xFFFF)
+                                return -EINVAL;
+
+                        if (!(n = strndup(s, e-s)))
+                                return -ENOMEM;
+
+                        /* IPv4 in w.x.y.z:p notation? */
+                        if ((r = inet_pton(AF_INET, n, &a->sockaddr.in4.sin_addr)) < 0) {
+                                free(n);
+                                return -errno;
+                        }
+
+                        if (r > 0) {
+                                /* Gotcha, it's a traditional IPv4 address */
+                                free(n);
+
+                                a->sockaddr.in4.sin_family = AF_INET;
+                                a->sockaddr.in4.sin_port = htons((uint16_t) u);
+                                a->size = sizeof(struct sockaddr_in);
+                        } else {
+                                unsigned idx;
+
+                                if (strlen(n) > IF_NAMESIZE-1) {
+                                        free(n);
+                                        return -EINVAL;
+                                }
+
+                                /* Uh, our last resort, an interface name */
+                                idx = if_nametoindex(n);
+                                free(n);
+
+                                if (idx == 0)
+                                        return -EINVAL;
+
+                                if (!socket_ipv6_is_supported()) {
+                                        log_warning("Binding to interface is not available since kernel does not support IPv6.");
+                                        return -EAFNOSUPPORT;
+                                }
+
+                                a->sockaddr.in6.sin6_family = AF_INET6;
+                                a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+                                a->sockaddr.in6.sin6_scope_id = idx;
+                                a->sockaddr.in6.sin6_addr = in6addr_any;
+                                a->size = sizeof(struct sockaddr_in6);
+                        }
+                } else {
+
+                        /* Just a port */
+                        r = safe_atou(s, &u);
+                        if (r < 0)
+                                return r;
+
+                        if (u <= 0 || u > 0xFFFF)
+                                return -EINVAL;
+
+                        if (socket_ipv6_is_supported()) {
+                                a->sockaddr.in6.sin6_family = AF_INET6;
+                                a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+                                a->sockaddr.in6.sin6_addr = in6addr_any;
+                                a->size = sizeof(struct sockaddr_in6);
+                        } else {
+                                a->sockaddr.in4.sin_family = AF_INET;
+                                a->sockaddr.in4.sin_port = htons((uint16_t) u);
+                                a->sockaddr.in4.sin_addr.s_addr = INADDR_ANY;
+                                a->size = sizeof(struct sockaddr_in);
+                        }
+                }
+        }
+
+        return 0;
+}
+
+int socket_address_parse_netlink(SocketAddress *a, const char *s) {
+        int family;
+        unsigned group = 0;
+        _cleanup_free_ char *sfamily = NULL;
+        assert(a);
+        assert(s);
+
+        zero(*a);
+        a->type = SOCK_RAW;
+
+        errno = 0;
+        if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
+                return errno ? -errno : -EINVAL;
+
+        family = netlink_family_from_string(sfamily);
+        if (family < 0)
+                return -EINVAL;
+
+        a->sockaddr.nl.nl_family = AF_NETLINK;
+        a->sockaddr.nl.nl_groups = group;
+
+        a->type = SOCK_RAW;
+        a->size = sizeof(struct sockaddr_nl);
+        a->protocol = family;
+
+        return 0;
+}
+
+int socket_address_verify(const SocketAddress *a) {
+        assert(a);
+
+        switch (socket_address_family(a)) {
+
+        case AF_INET:
+                if (a->size != sizeof(struct sockaddr_in))
+                        return -EINVAL;
+
+                if (a->sockaddr.in4.sin_port == 0)
+                        return -EINVAL;
+
+                if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
+                        return -EINVAL;
+
+                return 0;
+
+        case AF_INET6:
+                if (a->size != sizeof(struct sockaddr_in6))
+                        return -EINVAL;
+
+                if (a->sockaddr.in6.sin6_port == 0)
+                        return -EINVAL;
+
+                if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
+                        return -EINVAL;
+
+                return 0;
+
+        case AF_UNIX:
+                if (a->size < offsetof(struct sockaddr_un, sun_path))
+                        return -EINVAL;
+
+                if (a->size > offsetof(struct sockaddr_un, sun_path)) {
+
+                        if (a->sockaddr.un.sun_path[0] != 0) {
+                                char *e;
+
+                                /* path */
+                                if (!(e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path))))
+                                        return -EINVAL;
+
+                                if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
+                                        return -EINVAL;
+                        }
+                }
+
+                if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
+                        return -EINVAL;
+
+                return 0;
+
+        case AF_NETLINK:
+
+                if (a->size != sizeof(struct sockaddr_nl))
+                        return -EINVAL;
+
+                if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
+                        return -EINVAL;
+
+                return 0;
+
+        default:
+                return -EAFNOSUPPORT;
+        }
+}
+
+int socket_address_print(const SocketAddress *a, char **p) {
+        int r;
+        assert(a);
+        assert(p);
+
+        if ((r = socket_address_verify(a)) < 0)
+                return r;
+
+        switch (socket_address_family(a)) {
+
+        case AF_INET: {
+                char *ret;
+
+                if (!(ret = new(char, INET_ADDRSTRLEN+1+5+1)))
+                        return -ENOMEM;
+
+                if (!inet_ntop(AF_INET, &a->sockaddr.in4.sin_addr, ret, INET_ADDRSTRLEN)) {
+                        free(ret);
+                        return -errno;
+                }
+
+                sprintf(strchr(ret, 0), ":%u", ntohs(a->sockaddr.in4.sin_port));
+                *p = ret;
+                return 0;
+        }
+
+        case AF_INET6: {
+                char *ret;
+
+                if (!(ret = new(char, 1+INET6_ADDRSTRLEN+2+5+1)))
+                        return -ENOMEM;
+
+                ret[0] = '[';
+                if (!inet_ntop(AF_INET6, &a->sockaddr.in6.sin6_addr, ret+1, INET6_ADDRSTRLEN)) {
+                        free(ret);
+                        return -errno;
+                }
+
+                sprintf(strchr(ret, 0), "]:%u", ntohs(a->sockaddr.in6.sin6_port));
+                *p = ret;
+                return 0;
+        }
+
+        case AF_UNIX: {
+                char *ret;
+
+                if (a->size <= offsetof(struct sockaddr_un, sun_path)) {
+
+                        if (!(ret = strdup("<unnamed>")))
+                                return -ENOMEM;
+
+                } else if (a->sockaddr.un.sun_path[0] == 0) {
+                        /* abstract */
+
+                        /* FIXME: We assume we can print the
+                         * socket path here and that it hasn't
+                         * more than one NUL byte. That is
+                         * actually an invalid assumption */
+
+                        if (!(ret = new(char, sizeof(a->sockaddr.un.sun_path)+1)))
+                                return -ENOMEM;
+
+                        ret[0] = '@';
+                        memcpy(ret+1, a->sockaddr.un.sun_path+1, sizeof(a->sockaddr.un.sun_path)-1);
+                        ret[sizeof(a->sockaddr.un.sun_path)] = 0;
+
+                } else {
+
+                        if (!(ret = strdup(a->sockaddr.un.sun_path)))
+                                return -ENOMEM;
+                }
+
+                *p = ret;
+                return 0;
+        }
+
+        case AF_NETLINK: {
+                char _cleanup_free_ *sfamily = NULL;
+
+                r = netlink_family_to_string_alloc(a->protocol, &sfamily);
+                if (r < 0)
+                        return r;
+                r = asprintf(p, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
+                if (r < 0)
+                        return -ENOMEM;
+
+                return 0;
+        }
+
+        default:
+                return -EINVAL;
+        }
+}
+
+bool socket_address_can_accept(const SocketAddress *a) {
+        assert(a);
+
+        return
+                a->type == SOCK_STREAM ||
+                a->type == SOCK_SEQPACKET;
+}
+
+bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
+        assert(a);
+        assert(b);
+
+        /* Invalid addresses are unequal to all */
+        if (socket_address_verify(a) < 0 ||
+            socket_address_verify(b) < 0)
+                return false;
+
+        if (a->type != b->type)
+                return false;
+
+        if (a->size != b->size)
+                return false;
+
+        if (socket_address_family(a) != socket_address_family(b))
+                return false;
+
+        switch (socket_address_family(a)) {
+
+        case AF_INET:
+                if (a->sockaddr.in4.sin_addr.s_addr != b->sockaddr.in4.sin_addr.s_addr)
+                        return false;
+
+                if (a->sockaddr.in4.sin_port != b->sockaddr.in4.sin_port)
+                        return false;
+
+                break;
+
+        case AF_INET6:
+                if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
+                        return false;
+
+                if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
+                        return false;
+
+                break;
+
+        case AF_UNIX:
+
+                if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
+                        return false;
+
+                if (a->sockaddr.un.sun_path[0]) {
+                        if (strncmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, sizeof(a->sockaddr.un.sun_path)) != 0)
+                                return false;
+                } else {
+                        if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
+                                return false;
+                }
+
+                break;
+
+        case AF_NETLINK:
+
+                if (a->protocol != b->protocol)
+                        return false;
+
+                if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
+                        return false;
+
+                break;
+
+        default:
+                /* Cannot compare, so we assume the addresses are different */
+                return false;
+        }
+
+        return true;
+}
+
+bool socket_address_is(const SocketAddress *a, const char *s, int type) {
+        struct SocketAddress b;
+
+        assert(a);
+        assert(s);
+
+        if (socket_address_parse(&b, s) < 0)
+                return false;
+
+        b.type = type;
+
+        return socket_address_equal(a, &b);
+}
+
+bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
+        struct SocketAddress b;
+
+        assert(a);
+        assert(s);
+
+        if (socket_address_parse_netlink(&b, s) < 0)
+                return false;
+
+        return socket_address_equal(a, &b);
+}
+
+bool socket_address_needs_mount(const SocketAddress *a, const char *prefix) {
+        assert(a);
+
+        if (socket_address_family(a) != AF_UNIX)
+                return false;
+
+        if (a->sockaddr.un.sun_path[0] == 0)
+                return false;
+
+        return path_startswith(a->sockaddr.un.sun_path, prefix);
+}
+
+bool socket_ipv6_is_supported(void) {
+        char *l = 0;
+        bool enabled;
+
+        if (access("/sys/module/ipv6", F_OK) != 0)
+                return 0;
+
+        /* If we can't check "disable" parameter, assume enabled */
+        if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
+                return 1;
+
+        /* If module was loaded with disable=1 no IPv6 available */
+        enabled = l[0] == '0';
+        free(l);
+
+        return enabled;
+}
+
+bool socket_address_matches_fd(const SocketAddress *a, int fd) {
+        union sockaddr_union sa;
+        socklen_t salen = sizeof(sa), solen;
+        int protocol, type;
+
+        assert(a);
+        assert(fd >= 0);
+
+        if (getsockname(fd, &sa.sa, &salen) < 0)
+                return false;
+
+        if (sa.sa.sa_family != a->sockaddr.sa.sa_family)
+                return false;
+
+        solen = sizeof(type);
+        if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &solen) < 0)
+                return false;
+
+        if (type != a->type)
+                return false;
+
+        if (a->protocol != 0)  {
+                solen = sizeof(protocol);
+                if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &solen) < 0)
+                        return false;
+
+                if (protocol != a->protocol)
+                        return false;
+        }
+
+        switch (sa.sa.sa_family) {
+
+        case AF_INET:
+                return sa.in4.sin_port == a->sockaddr.in4.sin_port &&
+                        sa.in4.sin_addr.s_addr == a->sockaddr.in4.sin_addr.s_addr;
+
+        case AF_INET6:
+                return sa.in6.sin6_port == a->sockaddr.in6.sin6_port &&
+                        memcmp(&sa.in6.sin6_addr, &a->sockaddr.in6.sin6_addr, sizeof(struct in6_addr)) == 0;
+
+        case AF_UNIX:
+                return salen == a->size &&
+                        memcmp(sa.un.sun_path, a->sockaddr.un.sun_path, salen - offsetof(struct sockaddr_un, sun_path)) == 0;
+
+        }
+
+        return false;
+}
+
+static const char* const netlink_family_table[] = {
+        [NETLINK_ROUTE] = "route",
+        [NETLINK_FIREWALL] = "firewall",
+        [NETLINK_INET_DIAG] = "inet-diag",
+        [NETLINK_NFLOG] = "nflog",
+        [NETLINK_XFRM] = "xfrm",
+        [NETLINK_SELINUX] = "selinux",
+        [NETLINK_ISCSI] = "iscsi",
+        [NETLINK_AUDIT] = "audit",
+        [NETLINK_FIB_LOOKUP] = "fib-lookup",
+        [NETLINK_CONNECTOR] = "connector",
+        [NETLINK_NETFILTER] = "netfilter",
+        [NETLINK_IP6_FW] = "ip6-fw",
+        [NETLINK_DNRTMSG] = "dnrtmsg",
+        [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
+        [NETLINK_GENERIC] = "generic",
+        [NETLINK_SCSITRANSPORT] = "scsitransport",
+        [NETLINK_ECRYPTFS] = "ecryptfs"
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
+
+static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
+        [SOCKET_ADDRESS_DEFAULT] = "default",
+        [SOCKET_ADDRESS_BOTH] = "both",
+        [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h
new file mode 100644 (file)
index 0000000..771765d
--- /dev/null
@@ -0,0 +1,101 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <net/if.h>
+#include <asm/types.h>
+#include <linux/netlink.h>
+
+#include "macro.h"
+#include "util.h"
+
+union sockaddr_union {
+        struct sockaddr sa;
+        struct sockaddr_in in4;
+        struct sockaddr_in6 in6;
+        struct sockaddr_un un;
+        struct sockaddr_nl nl;
+        struct sockaddr_storage storage;
+};
+
+typedef struct SocketAddress {
+        union sockaddr_union sockaddr;
+
+        /* We store the size here explicitly due to the weird
+         * sockaddr_un semantics for abstract sockets */
+        socklen_t size;
+
+        /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */
+        int type;
+
+        /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */
+        int protocol;
+} SocketAddress;
+
+typedef enum SocketAddressBindIPv6Only {
+        SOCKET_ADDRESS_DEFAULT,
+        SOCKET_ADDRESS_BOTH,
+        SOCKET_ADDRESS_IPV6_ONLY,
+        _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX,
+        _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1
+} SocketAddressBindIPv6Only;
+
+#define socket_address_family(a) ((a)->sockaddr.sa.sa_family)
+
+int socket_address_parse(SocketAddress *a, const char *s);
+int socket_address_parse_netlink(SocketAddress *a, const char *s);
+int socket_address_print(const SocketAddress *a, char **p);
+int socket_address_verify(const SocketAddress *a);
+
+bool socket_address_can_accept(const SocketAddress *a);
+
+int socket_address_listen(
+                const SocketAddress *a,
+                int backlog,
+                SocketAddressBindIPv6Only only,
+                const char *bind_to_device,
+                bool free_bind,
+                bool transparent,
+                mode_t directory_mode,
+                mode_t socket_mode,
+                const char *label,
+                int *ret);
+
+bool socket_address_is(const SocketAddress *a, const char *s, int type);
+bool socket_address_is_netlink(const SocketAddress *a, const char *s);
+
+bool socket_address_matches_fd(const SocketAddress *a, int fd);
+
+bool socket_address_equal(const SocketAddress *a, const SocketAddress *b);
+
+bool socket_address_needs_mount(const SocketAddress *a, const char *prefix);
+
+const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b);
+SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s);
+
+int netlink_family_to_string_alloc(int b, char **s);
+int netlink_family_from_string(const char *s);
+
+bool socket_ipv6_is_supported(void);
diff --git a/src/shared/sparse-endian.h b/src/shared/sparse-endian.h
new file mode 100644 (file)
index 0000000..eb4dbf3
--- /dev/null
@@ -0,0 +1,87 @@
+/* Copyright (c) 2012 Josh Triplett <josh@joshtriplett.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#ifndef SPARSE_ENDIAN_H
+#define SPARSE_ENDIAN_H
+
+#include <endian.h>
+#include <stdint.h>
+
+#ifdef __CHECKER__
+#define __bitwise __attribute__((bitwise))
+#define __force __attribute__((force))
+#else
+#define __bitwise
+#define __force
+#endif
+
+typedef uint16_t __bitwise le16_t;
+typedef uint16_t __bitwise be16_t;
+typedef uint32_t __bitwise le32_t;
+typedef uint32_t __bitwise be32_t;
+typedef uint64_t __bitwise le64_t;
+typedef uint64_t __bitwise be64_t;
+
+#undef htobe16
+#undef htole16
+#undef be16toh
+#undef le16toh
+#undef htobe32
+#undef htole32
+#undef be32toh
+#undef le32toh
+#undef htobe64
+#undef htole64
+#undef be64toh
+#undef le64toh
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define bswap_16_on_le(x) __bswap_16(x)
+#define bswap_32_on_le(x) __bswap_32(x)
+#define bswap_64_on_le(x) __bswap_64(x)
+#define bswap_16_on_be(x) (x)
+#define bswap_32_on_be(x) (x)
+#define bswap_64_on_be(x) (x)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define bswap_16_on_le(x) (x)
+#define bswap_32_on_le(x) (x)
+#define bswap_64_on_le(x) (x)
+#define bswap_16_on_be(x) __bswap_16(x)
+#define bswap_32_on_be(x) __bswap_32(x)
+#define bswap_64_on_be(x) __bswap_64(x)
+#endif
+
+static inline le16_t htole16(uint16_t value) { return (le16_t __force) bswap_16_on_be(value); }
+static inline le32_t htole32(uint32_t value) { return (le32_t __force) bswap_32_on_be(value); }
+static inline le64_t htole64(uint64_t value) { return (le64_t __force) bswap_64_on_be(value); }
+
+static inline be16_t htobe16(uint16_t value) { return (be16_t __force) bswap_16_on_le(value); }
+static inline be32_t htobe32(uint32_t value) { return (be32_t __force) bswap_32_on_le(value); }
+static inline be64_t htobe64(uint64_t value) { return (be64_t __force) bswap_64_on_le(value); }
+
+static inline uint16_t le16toh(le16_t value) { return bswap_16_on_be((uint16_t __force)value); }
+static inline uint32_t le32toh(le32_t value) { return bswap_32_on_be((uint32_t __force)value); }
+static inline uint64_t le64toh(le64_t value) { return bswap_64_on_be((uint64_t __force)value); }
+
+static inline uint16_t be16toh(be16_t value) { return bswap_16_on_le((uint16_t __force)value); }
+static inline uint32_t be32toh(be32_t value) { return bswap_32_on_le((uint32_t __force)value); }
+static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t __force)value); }
+
+#endif /* SPARSE_ENDIAN_H */
diff --git a/src/shared/spawn-ask-password-agent.c b/src/shared/spawn-ask-password-agent.c
new file mode 100644 (file)
index 0000000..c1a9c58
--- /dev/null
@@ -0,0 +1,67 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include "log.h"
+#include "util.h"
+#include "spawn-ask-password-agent.h"
+
+static pid_t agent_pid = 0;
+
+int ask_password_agent_open(void) {
+        int r;
+
+        if (agent_pid > 0)
+                return 0;
+
+        /* We check STDIN here, not STDOUT, since this is about input,
+         * not output */
+        if (!isatty(STDIN_FILENO))
+                return 0;
+
+        r = fork_agent(&agent_pid,
+                       NULL, 0,
+                       SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH,
+                       SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL);
+        if (r < 0)
+                log_error("Failed to fork TTY ask password agent: %s", strerror(-r));
+
+        return r;
+}
+
+void ask_password_agent_close(void) {
+
+        if (agent_pid <= 0)
+                return;
+
+        /* Inform agent that we are done */
+        kill(agent_pid, SIGTERM);
+        kill(agent_pid, SIGCONT);
+        wait_for_terminate(agent_pid, NULL);
+        agent_pid = 0;
+}
diff --git a/src/shared/spawn-ask-password-agent.h b/src/shared/spawn-ask-password-agent.h
new file mode 100644 (file)
index 0000000..31b4bea
--- /dev/null
@@ -0,0 +1,25 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int ask_password_agent_open(void);
+void ask_password_agent_close(void);
diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c
new file mode 100644 (file)
index 0000000..fcb3722
--- /dev/null
@@ -0,0 +1,86 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/poll.h>
+
+#include "log.h"
+#include "util.h"
+#include "spawn-polkit-agent.h"
+
+static pid_t agent_pid = 0;
+
+int polkit_agent_open(void) {
+        int r;
+        int pipe_fd[2];
+        char notify_fd[10 + 1];
+
+        if (agent_pid > 0)
+                return 0;
+
+        /* We check STDIN here, not STDOUT, since this is about input,
+         * not output */
+        if (!isatty(STDIN_FILENO))
+                return 0;
+
+        if (pipe2(pipe_fd, 0) < 0)
+                return -errno;
+
+        snprintf(notify_fd, sizeof(notify_fd), "%i", pipe_fd[1]);
+        char_array_0(notify_fd);
+
+        r = fork_agent(&agent_pid,
+                       &pipe_fd[1], 1,
+                       POLKIT_AGENT_BINARY_PATH,
+                       POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL);
+
+        /* Close the writing side, because that's the one for the agent */
+        close_nointr_nofail(pipe_fd[1]);
+
+        if (r < 0)
+                log_error("Failed to fork TTY ask password agent: %s", strerror(-r));
+        else
+                /* Wait until the agent closes the fd */
+                fd_wait_for_event(pipe_fd[0], POLLHUP, (usec_t) -1);
+
+        close_nointr_nofail(pipe_fd[0]);
+
+        return r;
+}
+
+void polkit_agent_close(void) {
+
+        if (agent_pid <= 0)
+                return;
+
+        /* Inform agent that we are done */
+        kill(agent_pid, SIGTERM);
+        kill(agent_pid, SIGCONT);
+        wait_for_terminate(agent_pid, NULL);
+        agent_pid = 0;
+}
diff --git a/src/shared/spawn-polkit-agent.h b/src/shared/spawn-polkit-agent.h
new file mode 100644 (file)
index 0000000..b91d20f
--- /dev/null
@@ -0,0 +1,28 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foospawnpolkitagenthfoo
+#define foospawnpolkitagenthfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int polkit_agent_open(void);
+void polkit_agent_close(void);
+
+#endif
diff --git a/src/shared/specifier.c b/src/shared/specifier.c
new file mode 100644 (file)
index 0000000..599027c
--- /dev/null
@@ -0,0 +1,111 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "macro.h"
+#include "util.h"
+#include "specifier.h"
+
+/*
+ * Generic infrastructure for replacing %x style specifiers in
+ * strings. Will call a callback for each replacement.
+ *
+ */
+
+char *specifier_printf(const char *text, const Specifier table[], void *userdata) {
+        char *r, *t;
+        const char *f;
+        bool percent = false;
+        size_t l;
+
+        assert(text);
+        assert(table);
+
+        l = strlen(text);
+        r = new(char, l+1);
+        if (!r)
+                return NULL;
+
+        t = r;
+
+        for (f = text; *f; f++, l--) {
+
+                if (percent) {
+                        if (*f == '%')
+                                *(t++) = '%';
+                        else {
+                                const Specifier *i;
+
+                                for (i = table; i->specifier; i++)
+                                        if (i->specifier == *f)
+                                                break;
+
+                                if (i->lookup) {
+                                        char *n, *w;
+                                        size_t k, j;
+
+                                        w = i->lookup(i->specifier, i->data, userdata);
+                                        if (!w) {
+                                                free(r);
+                                                return NULL;
+                                        }
+
+                                        j = t - r;
+                                        k = strlen(w);
+
+                                        n = new(char, j + k + l + 1);
+                                        if (!n) {
+                                                free(r);
+                                                free(w);
+                                                return NULL;
+                                        }
+
+                                        memcpy(n, r, j);
+                                        memcpy(n + j, w, k);
+
+                                        free(r);
+                                        free(w);
+
+                                        r = n;
+                                        t = n + j + k;
+                                } else {
+                                        *(t++) = '%';
+                                        *(t++) = *f;
+                                }
+                        }
+
+                        percent = false;
+                } else if (*f == '%')
+                        percent = true;
+                else
+                        *(t++) = *f;
+        }
+
+        *t = 0;
+        return r;
+}
+
+/* Generic handler for simple string replacements */
+
+char* specifier_string(char specifier, void *data, void *userdata) {
+        return strdup(strempty(data));
+}
diff --git a/src/shared/specifier.h b/src/shared/specifier.h
new file mode 100644 (file)
index 0000000..25a27a4
--- /dev/null
@@ -0,0 +1,34 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef char* (*SpecifierCallback)(char specifier, void *data, void *userdata);
+
+typedef struct Specifier {
+        const char specifier;
+        const SpecifierCallback lookup;
+        void *data;
+} Specifier;
+
+char *specifier_printf(const char *text, const Specifier table[], void *userdata);
+
+char* specifier_string(char specifier, void *data, void *userdata);
diff --git a/src/shared/strbuf.c b/src/shared/strbuf.c
new file mode 100644 (file)
index 0000000..915cd3a
--- /dev/null
@@ -0,0 +1,176 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+#include "strbuf.h"
+
+/*
+ * Strbuf stores given strings in a single continous allocated memory
+ * area. Identical strings are de-duplicated and return the same offset
+ * as the first string stored. If the tail of a string already exists
+ * in the buffer, the tail is returned.
+ *
+ * A trie (http://en.wikipedia.org/wiki/Trie) is used to maintain the
+ * information about the stored strings.
+ *
+ * Example of udev rules:
+ *   $ ./udevadm test .
+ *   ...
+ *   read rules file: /usr/lib/udev/rules.d/99-systemd.rules
+ *   rules contain 196608 bytes tokens (16384 * 12 bytes), 39742 bytes strings
+ *   23939 strings (207859 bytes), 20404 de-duplicated (171653 bytes), 3536 trie nodes used
+ *   ...
+ */
+
+struct strbuf *strbuf_new(void) {
+        struct strbuf *str;
+
+        str = new0(struct strbuf, 1);
+        if (!str)
+                return NULL;
+
+        str->buf = new0(char, 1);
+        if (!str->buf)
+                goto err;
+        str->len = 1;
+
+        str->root = new0(struct strbuf_node, 1);
+        if (!str->root)
+                goto err;
+        str->nodes_count = 1;
+        return str;
+err:
+        free(str->buf);
+        free(str->root);
+        free(str);
+        return NULL;
+}
+
+static void strbuf_node_cleanup(struct strbuf_node *node) {
+        size_t i;
+
+        for (i = 0; i < node->children_count; i++)
+                strbuf_node_cleanup(node->children[i].child);
+        free(node->children);
+        free(node);
+}
+
+/* clean up trie data, leave only the string buffer */
+void strbuf_complete(struct strbuf *str) {
+        if (!str)
+                return;
+        if (str->root)
+                strbuf_node_cleanup(str->root);
+        str->root = NULL;
+}
+
+/* clean up everything */
+void strbuf_cleanup(struct strbuf *str) {
+        if (!str)
+                return;
+        if (str->root)
+                strbuf_node_cleanup(str->root);
+        free(str->buf);
+        free(str);
+}
+
+static int strbuf_children_cmp(const void *v1, const void *v2) {
+        const struct strbuf_child_entry *n1 = v1;
+        const struct strbuf_child_entry *n2 = v2;
+
+        return n1->c - n2->c;
+}
+
+/* add string, return the index/offset into the buffer */
+ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
+        uint8_t c;
+        struct strbuf_node *node;
+        size_t depth;
+        char *buf_new;
+        struct strbuf_child_entry *child;
+        struct strbuf_node *node_child;
+        ssize_t off;
+
+        if (!str->root)
+                return -EINVAL;
+
+        /* search string; start from last character to find possibly matching tails */
+        if (len == 0)
+                return 0;
+        str->in_count++;
+        str->in_len += len;
+
+        node = str->root;
+        c = s[len-1];
+        for (depth = 0; depth <= len; depth++) {
+                struct strbuf_child_entry search;
+
+                /* match against current node */
+                off = node->value_off + node->value_len - len;
+                if (depth == len || (node->value_len >= len && memcmp(str->buf + off, s, len) == 0)) {
+                        str->dedup_len += len;
+                        str->dedup_count++;
+                        return off;
+                }
+
+                /* lookup child node */
+                c = s[len - 1 - depth];
+                search.c = c;
+                child = bsearch(&search, node->children, node->children_count, sizeof(struct strbuf_child_entry),
+                                strbuf_children_cmp);
+                if (!child)
+                        break;
+                node = child->child;
+        }
+
+        /* add new string */
+        buf_new = realloc(str->buf, str->len + len+1);
+        if (!buf_new)
+                return -ENOMEM;
+        str->buf = buf_new;
+        off = str->len;
+        memcpy(str->buf + off, s, len);
+        str->len += len;
+        str->buf[str->len++] = '\0';
+
+        /* new node */
+        node_child = new0(struct strbuf_node, 1);
+        if (!node_child)
+                return -ENOMEM;
+        str->nodes_count++;
+        node_child->value_off = off;
+        node_child->value_len = len;
+
+        /* extend array, add new entry, sort for bisection */
+        child = realloc(node->children, (node->children_count + 1) * sizeof(struct strbuf_child_entry));
+        if (!child)
+                return -ENOMEM;
+        node->children = child;
+        node->children[node->children_count].c = c;
+        node->children[node->children_count].child = node_child;
+        node->children_count++;
+        qsort(node->children, node->children_count, sizeof(struct strbuf_child_entry), strbuf_children_cmp);
+
+        return off;
+}
diff --git a/src/shared/strbuf.h b/src/shared/strbuf.h
new file mode 100644 (file)
index 0000000..2347fd4
--- /dev/null
@@ -0,0 +1,56 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+struct strbuf {
+        char *buf;
+        size_t len;
+        struct strbuf_node *root;
+
+        size_t nodes_count;
+        size_t in_count;
+        size_t in_len;
+        size_t dedup_len;
+        size_t dedup_count;
+};
+
+struct strbuf_node {
+        size_t value_off;
+        size_t value_len;
+
+        struct strbuf_child_entry *children;
+        uint8_t children_count;
+};
+
+struct strbuf_child_entry {
+        uint8_t c;
+        struct strbuf_node *child;
+};
+
+struct strbuf *strbuf_new(void);
+ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len);
+void strbuf_complete(struct strbuf *str);
+void strbuf_cleanup(struct strbuf *str);
diff --git a/src/shared/strv.c b/src/shared/strv.c
new file mode 100644 (file)
index 0000000..6b76d0e
--- /dev/null
@@ -0,0 +1,750 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include "util.h"
+#include "strv.h"
+
+char *strv_find(char **l, const char *name) {
+        char **i;
+
+        assert(name);
+
+        STRV_FOREACH(i, l)
+                if (streq(*i, name))
+                        return *i;
+
+        return NULL;
+}
+
+char *strv_find_prefix(char **l, const char *name) {
+        char **i;
+
+        assert(name);
+
+        STRV_FOREACH(i, l)
+                if (startswith(*i, name))
+                        return *i;
+
+        return NULL;
+}
+
+void strv_free(char **l) {
+        char **k;
+
+        if (!l)
+                return;
+
+        for (k = l; *k; k++)
+                free(*k);
+
+        free(l);
+}
+
+void strv_freep(char ***l) {
+        if (!l)
+                return;
+
+        strv_free(*l);
+        *l = NULL;
+}
+
+char **strv_copy(char **l) {
+        char **r, **k;
+
+        k = r = new(char*, strv_length(l) + 1);
+        if (!r)
+                return NULL;
+
+        if (l)
+                for (; *l; k++, l++) {
+                        *k = strdup(*l);
+                        if (!*k) {
+                                strv_free(r);
+                                return NULL;
+                        }
+                }
+
+        *k = NULL;
+        return r;
+}
+
+unsigned strv_length(char **l) {
+        unsigned n = 0;
+
+        if (!l)
+                return 0;
+
+        for (; *l; l++)
+                n++;
+
+        return n;
+}
+
+char **strv_new_ap(const char *x, va_list ap) {
+        const char *s;
+        char **a;
+        unsigned n = 0, i = 0;
+        va_list aq;
+
+        /* As a special trick we ignore all listed strings that equal
+         * (const char*) -1. This is supposed to be used with the
+         * STRV_IFNOTNULL() macro to include possibly NULL strings in
+         * the string list. */
+
+        if (x) {
+                n = x == (const char*) -1 ? 0 : 1;
+
+                va_copy(aq, ap);
+                while ((s = va_arg(aq, const char*))) {
+                        if (s == (const char*) -1)
+                                continue;
+
+                        n++;
+                }
+
+                va_end(aq);
+        }
+
+        a = new(char*, n+1);
+        if (!a)
+                return NULL;
+
+        if (x) {
+                if (x != (const char*) -1) {
+                        a[i] = strdup(x);
+                        if (!a[i])
+                                goto fail;
+                        i++;
+                }
+
+                while ((s = va_arg(ap, const char*))) {
+
+                        if (s == (const char*) -1)
+                                continue;
+
+                        a[i] = strdup(s);
+                        if (!a[i])
+                                goto fail;
+
+                        i++;
+                }
+        }
+
+        a[i] = NULL;
+
+        return a;
+
+fail:
+        strv_free(a);
+        return NULL;
+}
+
+char **strv_new(const char *x, ...) {
+        char **r;
+        va_list ap;
+
+        va_start(ap, x);
+        r = strv_new_ap(x, ap);
+        va_end(ap);
+
+        return r;
+}
+
+char **strv_merge(char **a, char **b) {
+        char **r, **k;
+
+        if (!a)
+                return strv_copy(b);
+
+        if (!b)
+                return strv_copy(a);
+
+        r = new(char*, strv_length(a) + strv_length(b) + 1);
+        if (!r)
+                return NULL;
+
+        for (k = r; *a; k++, a++) {
+                *k = strdup(*a);
+                if (!*k)
+                        goto fail;
+        }
+
+        for (; *b; k++, b++) {
+                *k = strdup(*b);
+                if (!*k)
+                        goto fail;
+        }
+
+        *k = NULL;
+        return r;
+
+fail:
+        strv_free(r);
+        return NULL;
+}
+
+char **strv_merge_concat(char **a, char **b, const char *suffix) {
+        char **r, **k;
+
+        /* Like strv_merge(), but appends suffix to all strings in b, before adding */
+
+        if (!b)
+                return strv_copy(a);
+
+        r = new(char*, strv_length(a) + strv_length(b) + 1);
+        if (!r)
+                return NULL;
+
+        k = r;
+        if (a)
+                for (; *a; k++, a++) {
+                        *k = strdup(*a);
+                        if (!*k)
+                                goto fail;
+                }
+
+        for (; *b; k++, b++) {
+                *k = strappend(*b, suffix);
+                if (!*k)
+                        goto fail;
+        }
+
+        *k = NULL;
+        return r;
+
+fail:
+        strv_free(r);
+        return NULL;
+
+}
+
+char **strv_split(const char *s, const char *separator) {
+        char *state;
+        char *w;
+        size_t l;
+        unsigned n, i;
+        char **r;
+
+        assert(s);
+
+        n = 0;
+        FOREACH_WORD_SEPARATOR(w, l, s, separator, state)
+                n++;
+
+        r = new(char*, n+1);
+        if (!r)
+                return NULL;
+
+        i = 0;
+        FOREACH_WORD_SEPARATOR(w, l, s, separator, state) {
+                r[i] = strndup(w, l);
+                if (!r[i]) {
+                        strv_free(r);
+                        return NULL;
+                }
+
+                i++;
+        }
+
+        r[i] = NULL;
+        return r;
+}
+
+char **strv_split_quoted(const char *s) {
+        char *state;
+        char *w;
+        size_t l;
+        unsigned n, i;
+        char **r;
+
+        assert(s);
+
+        n = 0;
+        FOREACH_WORD_QUOTED(w, l, s, state)
+                n++;
+
+        r = new(char*, n+1);
+        if (!r)
+                return NULL;
+
+        i = 0;
+        FOREACH_WORD_QUOTED(w, l, s, state) {
+                r[i] = cunescape_length(w, l);
+                if (!r[i]) {
+                        strv_free(r);
+                        return NULL;
+                }
+                i++;
+        }
+
+        r[i] = NULL;
+        return r;
+}
+
+char *strv_join(char **l, const char *separator) {
+        char *r, *e;
+        char **s;
+        size_t n, k;
+
+        if (!separator)
+                separator = " ";
+
+        k = strlen(separator);
+
+        n = 0;
+        STRV_FOREACH(s, l) {
+                if (n != 0)
+                        n += k;
+                n += strlen(*s);
+        }
+
+        r = new(char, n+1);
+        if (!r)
+                return NULL;
+
+        e = r;
+        STRV_FOREACH(s, l) {
+                if (e != r)
+                        e = stpcpy(e, separator);
+
+                e = stpcpy(e, *s);
+        }
+
+        *e = 0;
+
+        return r;
+}
+
+char **strv_append(char **l, const char *s) {
+        char **r, **k;
+
+        if (!l)
+                return strv_new(s, NULL);
+
+        if (!s)
+                return strv_copy(l);
+
+        r = new(char*, strv_length(l)+2);
+        if (!r)
+                return NULL;
+
+        for (k = r; *l; k++, l++) {
+                *k = strdup(*l);
+                if (!*k)
+                        goto fail;
+        }
+
+        k[0] = strdup(s);
+        if (!k[0])
+                goto fail;
+
+        k[1] = NULL;
+        return r;
+
+fail:
+        strv_free(r);
+        return NULL;
+}
+
+char **strv_uniq(char **l) {
+        char **i;
+
+        /* Drops duplicate entries. The first identical string will be
+         * kept, the others dropped */
+
+        STRV_FOREACH(i, l)
+                strv_remove(i+1, *i);
+
+        return l;
+}
+
+char **strv_remove(char **l, const char *s) {
+        char **f, **t;
+
+        if (!l)
+                return NULL;
+
+        assert(s);
+
+        /* Drops every occurrence of s in the string list, edits
+         * in-place. */
+
+        for (f = t = l; *f; f++) {
+
+                if (streq(*f, s)) {
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return l;
+}
+
+char **strv_remove_prefix(char **l, const char *s) {
+        char **f, **t;
+
+        if (!l)
+                return NULL;
+
+        assert(s);
+
+        /* Drops every occurrence of a string prefixed with s in the
+         * string list, edits in-place. */
+
+        for (f = t = l; *f; f++) {
+
+                if (startswith(*f, s)) {
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return l;
+}
+
+static int env_append(char **r, char ***k, char **a) {
+        assert(r);
+        assert(k);
+
+        if (!a)
+                return 0;
+
+        /* Add the entries of a to *k unless they already exist in *r
+         * in which case they are overridden instead. This assumes
+         * there is enough space in the r array. */
+
+        for (; *a; a++) {
+                char **j;
+                size_t n;
+
+                n = strcspn(*a, "=");
+
+                if ((*a)[n] == '=')
+                        n++;
+
+                for (j = r; j < *k; j++)
+                        if (strncmp(*j, *a, n) == 0)
+                                break;
+
+                if (j >= *k)
+                        (*k)++;
+                else
+                        free(*j);
+
+                *j = strdup(*a);
+                if (!*j)
+                        return -ENOMEM;
+        }
+
+        return 0;
+}
+
+char **strv_env_merge(unsigned n_lists, ...) {
+        size_t n = 0;
+        char **l, **k, **r;
+        va_list ap;
+        unsigned i;
+
+        /* Merges an arbitrary number of environment sets */
+
+        va_start(ap, n_lists);
+        for (i = 0; i < n_lists; i++) {
+                l = va_arg(ap, char**);
+                n += strv_length(l);
+        }
+        va_end(ap);
+
+        r = new(char*, n+1);
+        if (!r)
+                return NULL;
+
+        k = r;
+
+        va_start(ap, n_lists);
+        for (i = 0; i < n_lists; i++) {
+                l = va_arg(ap, char**);
+                if (env_append(r, &k, l) < 0)
+                        goto fail;
+        }
+        va_end(ap);
+
+        *k = NULL;
+
+        return r;
+
+fail:
+        va_end(ap);
+        strv_free(r);
+
+        return NULL;
+}
+
+static bool env_match(const char *t, const char *pattern) {
+        assert(t);
+        assert(pattern);
+
+        /* pattern a matches string a
+         *         a matches a=
+         *         a matches a=b
+         *         a= matches a=
+         *         a=b matches a=b
+         *         a= does not match a
+         *         a=b does not match a=
+         *         a=b does not match a
+         *         a=b does not match a=c */
+
+        if (streq(t, pattern))
+                return true;
+
+        if (!strchr(pattern, '=')) {
+                size_t l = strlen(pattern);
+
+                return strncmp(t, pattern, l) == 0 && t[l] == '=';
+        }
+
+        return false;
+}
+
+char **strv_env_delete(char **x, unsigned n_lists, ...) {
+        size_t n, i = 0;
+        char **k, **r;
+        va_list ap;
+
+        /* Deletes every entry from x that is mentioned in the other
+         * string lists */
+
+        n = strv_length(x);
+
+        r = new(char*, n+1);
+        if (!r)
+                return NULL;
+
+        STRV_FOREACH(k, x) {
+                unsigned v;
+
+                va_start(ap, n_lists);
+                for (v = 0; v < n_lists; v++) {
+                        char **l, **j;
+
+                        l = va_arg(ap, char**);
+                        STRV_FOREACH(j, l)
+                                if (env_match(*k, *j))
+                                        goto skip;
+                }
+                va_end(ap);
+
+                r[i] = strdup(*k);
+                if (!r[i]) {
+                        strv_free(r);
+                        return NULL;
+                }
+
+                i++;
+                continue;
+
+        skip:
+                va_end(ap);
+        }
+
+        r[i] = NULL;
+
+        assert(i <= n);
+
+        return r;
+}
+
+char **strv_env_unset(char **l, const char *p) {
+
+        char **f, **t;
+
+        if (!l)
+                return NULL;
+
+        assert(p);
+
+        /* Drops every occurrence of the env var setting p in the
+         * string list. edits in-place. */
+
+        for (f = t = l; *f; f++) {
+
+                if (env_match(*f, p)) {
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return l;
+}
+
+char **strv_env_set(char **x, const char *p) {
+
+        char **k, **r;
+        char* m[2] = { (char*) p, NULL };
+
+        /* Overrides the env var setting of p, returns a new copy */
+
+        r = new(char*, strv_length(x)+2);
+        if (!r)
+                return NULL;
+
+        k = r;
+        if (env_append(r, &k, x) < 0)
+                goto fail;
+
+        if (env_append(r, &k, m) < 0)
+                goto fail;
+
+        *k = NULL;
+
+        return r;
+
+fail:
+        strv_free(r);
+        return NULL;
+
+}
+
+char *strv_env_get_with_length(char **l, const char *name, size_t k) {
+        char **i;
+
+        assert(name);
+
+        STRV_FOREACH(i, l)
+                if (strncmp(*i, name, k) == 0 &&
+                    (*i)[k] == '=')
+                        return *i + k + 1;
+
+        return NULL;
+}
+
+char *strv_env_get(char **l, const char *name) {
+        return strv_env_get_with_length(l, name, strlen(name));
+}
+
+char **strv_env_clean(char **l) {
+        char **r, **ret;
+
+        for (r = ret = l; *l; l++) {
+                const char *equal;
+
+                equal = strchr(*l, '=');
+
+                if (equal && equal[1] == 0) {
+                        free(*l);
+                        continue;
+                }
+
+                *(r++) = *l;
+        }
+
+        *r = NULL;
+
+        return ret;
+}
+
+char **strv_parse_nulstr(const char *s, size_t l) {
+        const char *p;
+        unsigned c = 0, i = 0;
+        char **v;
+
+        assert(s || l <= 0);
+
+        if (l <= 0)
+                return strv_new(NULL, NULL);
+
+        for (p = s; p < s + l; p++)
+                if (*p == 0)
+                        c++;
+
+        if (s[l-1] != 0)
+                c++;
+
+        v = new0(char*, c+1);
+        if (!v)
+                return NULL;
+
+        p = s;
+        while (p < s + l) {
+                const char *e;
+
+                e = memchr(p, 0, s + l - p);
+
+                v[i] = strndup(p, e ? e - p : s + l - p);
+                if (!v[i]) {
+                        strv_free(v);
+                        return NULL;
+                }
+
+                i++;
+
+                if (!e)
+                        break;
+
+                p = e + 1;
+        }
+
+        assert(i == c);
+
+        return v;
+}
+
+bool strv_overlap(char **a, char **b) {
+        char **i, **j;
+
+        STRV_FOREACH(i, a) {
+                STRV_FOREACH(j, b) {
+                        if (streq(*i, *j))
+                                return true;
+                }
+        }
+
+        return false;
+}
+
+static int str_compare(const void *_a, const void *_b) {
+        const char **a = (const char**) _a, **b = (const char**) _b;
+
+        return strcmp(*a, *b);
+}
+
+char **strv_sort(char **l) {
+
+        if (strv_isempty(l))
+                return l;
+
+        qsort(l, strv_length(l), sizeof(char*), str_compare);
+        return l;
+}
diff --git a/src/shared/strv.h b/src/shared/strv.h
new file mode 100644 (file)
index 0000000..45558d8
--- /dev/null
@@ -0,0 +1,84 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdarg.h>
+#include <stdbool.h>
+
+#include "macro.h"
+
+char *strv_find(char **l, const char *name);
+char *strv_find_prefix(char **l, const char *name);
+
+void strv_free(char **l);
+void strv_freep(char ***l);
+char **strv_copy(char **l) _malloc_;
+unsigned strv_length(char **l);
+
+char **strv_merge(char **a, char **b);
+char **strv_merge_concat(char **a, char **b, const char *suffix);
+char **strv_append(char **l, const char *s);
+
+char **strv_remove(char **l, const char *s);
+char **strv_remove_prefix(char **l, const char *s);
+char **strv_uniq(char **l);
+
+#define strv_contains(l, s) (!!strv_find((l), (s)))
+
+char **strv_new(const char *x, ...) _sentinel_ _malloc_;
+char **strv_new_ap(const char *x, va_list ap) _malloc_;
+
+static inline const char* STRV_IFNOTNULL(const char *x) {
+        return x ? x : (const char *) -1;
+}
+
+static inline bool strv_isempty(char **l) {
+        return !l || !*l;
+}
+
+char **strv_split(const char *s, const char *separator) _malloc_;
+char **strv_split_quoted(const char *s) _malloc_;
+
+char *strv_join(char **l, const char *separator) _malloc_;
+
+char **strv_env_merge(unsigned n_lists, ...);
+char **strv_env_delete(char **x, unsigned n_lists, ...);
+
+char **strv_env_set(char **x, const char *p);
+char **strv_env_unset(char **l, const char *p);
+
+char *strv_env_get_with_length(char **l, const char *name, size_t k);
+char *strv_env_get(char **x, const char *n);
+
+char **strv_env_clean(char **l);
+
+char **strv_parse_nulstr(const char *s, size_t l);
+
+bool strv_overlap(char **a, char **b);
+
+#define STRV_FOREACH(s, l)                      \
+        for ((s) = (l); (s) && *(s); (s)++)
+
+#define STRV_FOREACH_BACKWARDS(s, l)            \
+        for (; (l) && ((s) >= (l)); (s)--)
+
+char **strv_sort(char **l);
diff --git a/src/shared/time-dst.c b/src/shared/time-dst.c
new file mode 100644 (file)
index 0000000..afc893c
--- /dev/null
@@ -0,0 +1,341 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Timezone file reading code from glibc 2.16.
+
+  Copyright (C) 1991-2012 Free Software Foundation, Inc.
+  Copyright 2012 Kay Sievers
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+#include <ctype.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <assert.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+
+#include "time-dst.h"
+
+/*
+ * If tzh_version is '2' or greater, the above is followed by a second instance
+ * of tzhead and a second instance of the data in which each coded transition
+ * time uses 8 rather than 4 chars, then a POSIX-TZ-environment-variable-style
+ * string for use in handling instants after the last transition time stored in
+ * the file * (with nothing between the newlines if there is no POSIX
+ * representation for such instants).
+ */
+#define TZ_MAGIC                "TZif"
+struct tzhead {
+        char tzh_magic[4];      /* TZ_MAGIC */
+        char tzh_version[1];    /* '\0' or '2' as of 2005 */
+        char tzh_reserved[15];  /* reserved--must be zero */
+        char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
+        char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
+        char tzh_leapcnt[4];    /* coded number of leap seconds */
+        char tzh_timecnt[4];    /* coded number of transition times */
+        char tzh_typecnt[4];    /* coded number of local time types */
+        char tzh_charcnt[4];    /* coded number of abbr. chars */
+};
+
+struct ttinfo {
+        long int offset;        /* Seconds east of GMT.  */
+        unsigned char isdst;    /* Used to set tm_isdst.  */
+        unsigned char idx;      /* Index into `zone_names'.  */
+        unsigned char isstd;    /* Transition times are in standard time.  */
+        unsigned char isgmt;    /* Transition times are in GMT.  */
+};
+
+struct leap {
+        time_t transition;      /* Time the transition takes effect.  */
+        long int change;        /* Seconds of correction to apply.  */
+};
+
+static inline int decode(const void *ptr) {
+        return be32toh(*(int *)ptr);
+}
+
+static inline int64_t decode64(const void *ptr) {
+        return be64toh(*(int64_t *)ptr);
+}
+
+int time_get_dst(time_t date, const char *tzfile,
+                 time_t *switch_cur, char **zone_cur, bool *dst_cur,
+                 time_t *switch_next, int *delta_next, char **zone_next, bool *dst_next) {
+        time_t *transitions = NULL;
+        size_t num_transitions = 0;
+        unsigned char *type_idxs = 0;
+        size_t num_types = 0;
+        struct ttinfo *types = NULL;
+        char *zone_names = NULL;
+        struct stat st;
+        size_t num_isstd, num_isgmt;
+        FILE *f;
+        struct tzhead tzhead;
+        size_t chars;
+        size_t i;
+        size_t total_size;
+        size_t types_idx;
+        int trans_width = 4;
+        size_t tzspec_len;
+        size_t num_leaps;
+        size_t lo, hi;
+        int err = -EINVAL;
+
+        f = fopen(tzfile, "re");
+        if (f == NULL)
+                return -errno;
+
+        if (fstat(fileno(f), &st) < 0) {
+                err = -errno;
+                fclose(f);
+                return err;
+        }
+
+read_again:
+        if (fread((void *)&tzhead, sizeof(tzhead), 1, f) != 1 ||
+            memcmp(tzhead.tzh_magic, TZ_MAGIC, sizeof(tzhead.tzh_magic)) != 0)
+                goto lose;
+
+        num_transitions = (size_t)decode(tzhead.tzh_timecnt);
+        num_types = (size_t)decode(tzhead.tzh_typecnt);
+        chars = (size_t)decode(tzhead.tzh_charcnt);
+        num_leaps = (size_t)decode(tzhead.tzh_leapcnt);
+        num_isstd = (size_t)decode(tzhead.tzh_ttisstdcnt);
+        num_isgmt = (size_t)decode(tzhead.tzh_ttisgmtcnt);
+
+        /* For platforms with 64-bit time_t we use the new format if available.  */
+        if (sizeof(time_t) == 8 && trans_width == 4 && tzhead.tzh_version[0] != '\0') {
+                size_t to_skip;
+
+                /* We use the 8-byte format.  */
+                trans_width = 8;
+
+                /* Position the stream before the second header.  */
+                to_skip = (num_transitions * (4 + 1)
+                           + num_types * 6
+                           + chars
+                           + num_leaps * 8 + num_isstd + num_isgmt);
+                if (fseek(f, to_skip, SEEK_CUR) != 0)
+                        goto lose;
+
+                goto read_again;
+        }
+
+        if (num_transitions > ((SIZE_MAX - (__alignof__(struct ttinfo) - 1)) / (sizeof(time_t) + 1)))
+                 goto lose;
+
+        total_size = num_transitions * (sizeof(time_t) + 1);
+        total_size = ((total_size + __alignof__(struct ttinfo) - 1) & ~(__alignof__(struct ttinfo) - 1));
+        types_idx = total_size;
+        if (num_leaps > (SIZE_MAX - total_size) / sizeof(struct ttinfo))
+                goto lose;
+
+        total_size += num_types * sizeof(struct ttinfo);
+        if (chars > SIZE_MAX - total_size)
+                goto lose;
+
+        total_size += chars;
+        if (__alignof__(struct leap) - 1 > SIZE_MAX - total_size)
+                 goto lose;
+
+        total_size = ((total_size + __alignof__(struct leap) - 1) & ~(__alignof__(struct leap) - 1));
+        if (num_leaps > (SIZE_MAX - total_size) / sizeof(struct leap))
+                goto lose;
+
+        total_size += num_leaps * sizeof(struct leap);
+        tzspec_len = 0;
+        if (sizeof(time_t) == 8 && trans_width == 8) {
+                off_t rem = st.st_size - ftello(f);
+
+                if (rem < 0 || (size_t) rem < (num_transitions * (8 + 1) + num_types * 6 + chars))
+                        goto lose;
+                tzspec_len = (size_t) rem - (num_transitions * (8 + 1) + num_types * 6 + chars);
+                if (num_leaps > SIZE_MAX / 12 || tzspec_len < num_leaps * 12)
+                        goto lose;
+                tzspec_len -= num_leaps * 12;
+                if (tzspec_len < num_isstd)
+                        goto lose;
+                tzspec_len -= num_isstd;
+                if (tzspec_len == 0 || tzspec_len - 1 < num_isgmt)
+                        goto lose;
+                tzspec_len -= num_isgmt + 1;
+                if (SIZE_MAX - total_size < tzspec_len)
+                        goto lose;
+        }
+
+        transitions = (time_t *)calloc(total_size + tzspec_len, 1);
+        if (transitions == NULL)
+                goto lose;
+
+        type_idxs = (unsigned char *)transitions + (num_transitions
+                                                    * sizeof(time_t));
+        types = (struct ttinfo *)((char *)transitions + types_idx);
+        zone_names = (char *)types + num_types * sizeof(struct ttinfo);
+
+        if (sizeof(time_t) == 4 || trans_width == 8) {
+                if (fread(transitions, trans_width + 1, num_transitions, f) != num_transitions)
+                        goto lose;
+        } else {
+                if (fread(transitions, 4, num_transitions, f) != num_transitions ||
+                    fread(type_idxs, 1, num_transitions, f) != num_transitions)
+                        goto lose;
+        }
+
+        /* Check for bogus indices in the data file, so we can hereafter
+           safely use type_idxs[T] as indices into `types' and never crash.  */
+        for (i = 0; i < num_transitions; ++i)
+                if (type_idxs[i] >= num_types)
+                        goto lose;
+
+        if ((BYTE_ORDER != BIG_ENDIAN && (sizeof(time_t) == 4 || trans_width == 4)) ||
+            (BYTE_ORDER == BIG_ENDIAN && sizeof(time_t) == 8 && trans_width == 4)) {
+                /* Decode the transition times, stored as 4-byte integers in
+                   network (big-endian) byte order.  We work from the end of
+                   the array so as not to clobber the next element to be
+                   processed when sizeof (time_t) > 4.  */
+                i = num_transitions;
+                while (i-- > 0)
+                        transitions[i] = decode((char *)transitions + i * 4);
+        } else if (BYTE_ORDER != BIG_ENDIAN && sizeof(time_t) == 8) {
+                /* Decode the transition times, stored as 8-byte integers in
+                   network (big-endian) byte order.  */
+                for (i = 0; i < num_transitions; ++i)
+                        transitions[i] = decode64((char *)transitions + i * 8);
+        }
+
+        for (i = 0; i < num_types; ++i) {
+                unsigned char x[4];
+                int c;
+
+                if (fread(x, 1, sizeof(x), f) != sizeof(x))
+                        goto lose;
+                c = getc(f);
+                if ((unsigned int)c > 1u)
+                        goto lose;
+                types[i].isdst = c;
+                c = getc(f);
+                if ((size_t) c > chars)
+                        /* Bogus index in data file.  */
+                        goto lose;
+                types[i].idx = c;
+                types[i].offset = (long int)decode(x);
+        }
+
+        if (fread(zone_names, 1, chars, f) != chars)
+                goto lose;
+
+        for (i = 0; i < num_isstd; ++i) {
+                int c = getc(f);
+                if (c == EOF)
+                        goto lose;
+                types[i].isstd = c != 0;
+        }
+
+        while (i < num_types)
+                types[i++].isstd = 0;
+
+        for (i = 0; i < num_isgmt; ++i) {
+                int c = getc(f);
+                if (c == EOF)
+                        goto lose;
+                types[i].isgmt = c != 0;
+        }
+
+        while (i < num_types)
+                types[i++].isgmt = 0;
+
+        if (num_transitions == 0)
+               goto lose;
+
+        if (date < transitions[0] || date >= transitions[num_transitions - 1])
+               goto lose;
+
+        /* Find the first transition after TIMER, and
+           then pick the type of the transition before it.  */
+        lo = 0;
+        hi = num_transitions - 1;
+
+        /* Assume that DST is changing twice a year and guess initial
+           search spot from it.
+           Half of a gregorian year has on average 365.2425 * 86400 / 2
+           = 15778476 seconds.  */
+        i = (transitions[num_transitions - 1] - date) / 15778476;
+        if (i < num_transitions) {
+                i = num_transitions - 1 - i;
+                if (date < transitions[i]) {
+                        if (i < 10 || date >= transitions[i - 10]) {
+                                /* Linear search.  */
+                                while (date < transitions[i - 1])
+                                        i--;
+                                goto found;
+                        }
+                        hi = i - 10;
+                } else {
+                        if (i + 10 >= num_transitions || date < transitions[i + 10]) {
+                                /* Linear search.  */
+                                while (date >= transitions[i])
+                                        i++;
+                                goto found;
+                        }
+                        lo = i + 10;
+                }
+        }
+
+        /* Binary search. */
+        while (lo + 1 < hi) {
+                i = (lo + hi) / 2;
+                if (date < transitions[i])
+                        hi = i;
+                else
+                        lo = i;
+        }
+        i = hi;
+
+found:
+        if (switch_cur)
+                *switch_cur = transitions[i-1];
+        if (zone_cur)
+                *zone_cur = strdup(&zone_names[types[type_idxs[i - 1]].idx]);
+        if (dst_cur)
+                *dst_cur = types[type_idxs[i-1]].isdst;
+
+        if (switch_next)
+                *switch_next = transitions[i];
+        if (delta_next)
+                *delta_next = (types[type_idxs[i]].offset - types[type_idxs[i-1]].offset) / 60;
+        if (zone_next)
+                *zone_next = strdup(&zone_names[types[type_idxs[i]].idx]);
+        if (dst_next)
+                *dst_next = types[type_idxs[i]].isdst;
+
+        free(transitions);
+        fclose(f);
+        return 0;
+lose:
+        free(transitions);
+        fclose(f);
+        return err;
+}
diff --git a/src/shared/time-dst.h b/src/shared/time-dst.h
new file mode 100644 (file)
index 0000000..536b6bb
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int time_get_dst(time_t date, const char *tzfile,
+                 time_t *switch_cur, char **zone_cur, bool *dst_cur,
+                 time_t *switch_next, int *delta_next, char **zone_next, bool *dst_next);
diff --git a/src/shared/time-util.c b/src/shared/time-util.c
new file mode 100644 (file)
index 0000000..13d57ba
--- /dev/null
@@ -0,0 +1,628 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <time.h>
+#include <string.h>
+
+#include "util.h"
+#include "time-util.h"
+
+usec_t now(clockid_t clock_id) {
+        struct timespec ts;
+
+        assert_se(clock_gettime(clock_id, &ts) == 0);
+
+        return timespec_load(&ts);
+}
+
+dual_timestamp* dual_timestamp_get(dual_timestamp *ts) {
+        assert(ts);
+
+        ts->realtime = now(CLOCK_REALTIME);
+        ts->monotonic = now(CLOCK_MONOTONIC);
+
+        return ts;
+}
+
+dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
+        int64_t delta;
+        assert(ts);
+
+        ts->realtime = u;
+
+        if (u == 0)
+                ts->monotonic = 0;
+        else {
+                delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
+
+                ts->monotonic = now(CLOCK_MONOTONIC);
+
+                if ((int64_t) ts->monotonic > delta)
+                        ts->monotonic -= delta;
+                else
+                        ts->monotonic = 0;
+        }
+
+        return ts;
+}
+
+usec_t timespec_load(const struct timespec *ts) {
+        assert(ts);
+
+        if (ts->tv_sec == (time_t) -1 &&
+            ts->tv_nsec == (long) -1)
+                return (usec_t) -1;
+
+        if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC)
+                return (usec_t) -1;
+
+        return
+                (usec_t) ts->tv_sec * USEC_PER_SEC +
+                (usec_t) ts->tv_nsec / NSEC_PER_USEC;
+}
+
+struct timespec *timespec_store(struct timespec *ts, usec_t u)  {
+        assert(ts);
+
+        if (u == (usec_t) -1) {
+                ts->tv_sec = (time_t) -1;
+                ts->tv_nsec = (long) -1;
+                return ts;
+        }
+
+        ts->tv_sec = (time_t) (u / USEC_PER_SEC);
+        ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
+
+        return ts;
+}
+
+usec_t timeval_load(const struct timeval *tv) {
+        assert(tv);
+
+        if (tv->tv_sec == (time_t) -1 &&
+            tv->tv_usec == (suseconds_t) -1)
+                return (usec_t) -1;
+
+        if ((usec_t) tv->tv_sec > (UINT64_MAX - tv->tv_usec) / USEC_PER_SEC)
+                return (usec_t) -1;
+
+        return
+                (usec_t) tv->tv_sec * USEC_PER_SEC +
+                (usec_t) tv->tv_usec;
+}
+
+struct timeval *timeval_store(struct timeval *tv, usec_t u) {
+        assert(tv);
+
+        if (u == (usec_t) -1) {
+                tv->tv_sec = (time_t) -1;
+                tv->tv_usec = (suseconds_t) -1;
+                return tv;
+        }
+
+        tv->tv_sec = (time_t) (u / USEC_PER_SEC);
+        tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
+
+        return tv;
+}
+
+char *format_timestamp(char *buf, size_t l, usec_t t) {
+        struct tm tm;
+        time_t sec;
+
+        assert(buf);
+        assert(l > 0);
+
+        if (t <= 0)
+                return NULL;
+
+        sec = (time_t) (t / USEC_PER_SEC);
+
+        if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) <= 0)
+                return NULL;
+
+        return buf;
+}
+
+char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
+        usec_t n, d;
+
+        n = now(CLOCK_REALTIME);
+
+        if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
+                return NULL;
+
+        d = n - t;
+
+        if (d >= USEC_PER_YEAR)
+                snprintf(buf, l, "%llu years %llu months ago",
+                         (unsigned long long) (d / USEC_PER_YEAR),
+                         (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
+        else if (d >= USEC_PER_MONTH)
+                snprintf(buf, l, "%llu months %llu days ago",
+                         (unsigned long long) (d / USEC_PER_MONTH),
+                         (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
+        else if (d >= USEC_PER_WEEK)
+                snprintf(buf, l, "%llu weeks %llu days ago",
+                         (unsigned long long) (d / USEC_PER_WEEK),
+                         (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
+        else if (d >= 2*USEC_PER_DAY)
+                snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
+        else if (d >= 25*USEC_PER_HOUR)
+                snprintf(buf, l, "1 day %lluh ago",
+                         (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
+        else if (d >= 6*USEC_PER_HOUR)
+                snprintf(buf, l, "%lluh ago",
+                         (unsigned long long) (d / USEC_PER_HOUR));
+        else if (d >= USEC_PER_HOUR)
+                snprintf(buf, l, "%lluh %llumin ago",
+                         (unsigned long long) (d / USEC_PER_HOUR),
+                         (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
+        else if (d >= 5*USEC_PER_MINUTE)
+                snprintf(buf, l, "%llumin ago",
+                         (unsigned long long) (d / USEC_PER_MINUTE));
+        else if (d >= USEC_PER_MINUTE)
+                snprintf(buf, l, "%llumin %llus ago",
+                         (unsigned long long) (d / USEC_PER_MINUTE),
+                         (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
+        else if (d >= USEC_PER_SEC)
+                snprintf(buf, l, "%llus ago",
+                         (unsigned long long) (d / USEC_PER_SEC));
+        else if (d >= USEC_PER_MSEC)
+                snprintf(buf, l, "%llums ago",
+                         (unsigned long long) (d / USEC_PER_MSEC));
+        else if (d > 0)
+                snprintf(buf, l, "%lluus ago",
+                         (unsigned long long) d);
+        else
+                snprintf(buf, l, "now");
+
+        buf[l-1] = 0;
+        return buf;
+}
+
+char *format_timespan(char *buf, size_t l, usec_t t) {
+        static const struct {
+                const char *suffix;
+                usec_t usec;
+        } table[] = {
+                { "w", USEC_PER_WEEK },
+                { "d", USEC_PER_DAY },
+                { "h", USEC_PER_HOUR },
+                { "min", USEC_PER_MINUTE },
+                { "s", USEC_PER_SEC },
+                { "ms", USEC_PER_MSEC },
+                { "us", 1 },
+        };
+
+        unsigned i;
+        char *p = buf;
+
+        assert(buf);
+        assert(l > 0);
+
+        if (t == (usec_t) -1)
+                return NULL;
+
+        if (t == 0) {
+                snprintf(p, l, "0");
+                p[l-1] = 0;
+                return p;
+        }
+
+        /* The result of this function can be parsed with parse_usec */
+
+        for (i = 0; i < ELEMENTSOF(table); i++) {
+                int k;
+                size_t n;
+
+                if (t < table[i].usec)
+                        continue;
+
+                if (l <= 1)
+                        break;
+
+                k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix);
+                n = MIN((size_t) k, l);
+
+                l -= n;
+                p += n;
+
+                t %= table[i].usec;
+        }
+
+        *p = 0;
+
+        return buf;
+}
+
+void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
+
+        assert(f);
+        assert(name);
+        assert(t);
+
+        if (!dual_timestamp_is_set(t))
+                return;
+
+        fprintf(f, "%s=%llu %llu\n",
+                name,
+                (unsigned long long) t->realtime,
+                (unsigned long long) t->monotonic);
+}
+
+void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
+        unsigned long long a, b;
+
+        assert(value);
+        assert(t);
+
+        if (sscanf(value, "%lli %llu", &a, &b) != 2)
+                log_debug("Failed to parse finish timestamp value %s", value);
+        else {
+                t->realtime = a;
+                t->monotonic = b;
+        }
+}
+
+int parse_timestamp(const char *t, usec_t *usec) {
+        static const struct {
+                const char *name;
+                const int nr;
+        } day_nr[] = {
+                { "Sunday",    0 },
+                { "Sun",       0 },
+                { "Monday",    1 },
+                { "Mon",       1 },
+                { "Tuesday",   2 },
+                { "Tue",       2 },
+                { "Wednesday", 3 },
+                { "Wed",       3 },
+                { "Thursday",  4 },
+                { "Thu",       4 },
+                { "Friday",    5 },
+                { "Fri",       5 },
+                { "Saturday",  6 },
+                { "Sat",       6 },
+        };
+
+        const char *k;
+        struct tm tm, copy;
+        time_t x;
+        usec_t plus = 0, minus = 0, ret;
+        int r, weekday = -1;
+        unsigned i;
+
+        /*
+         * Allowed syntaxes:
+         *
+         *   2012-09-22 16:34:22
+         *   2012-09-22 16:34     (seconds will be set to 0)
+         *   2012-09-22           (time will be set to 00:00:00)
+         *   16:34:22             (date will be set to today)
+         *   16:34                (date will be set to today, seconds to 0)
+         *   now
+         *   yesterday            (time is set to 00:00:00)
+         *   today                (time is set to 00:00:00)
+         *   tomorrow             (time is set to 00:00:00)
+         *   +5min
+         *   -5days
+         *
+         */
+
+        assert(t);
+        assert(usec);
+
+        x = time(NULL);
+        assert_se(localtime_r(&x, &tm));
+        tm.tm_isdst = -1;
+
+        if (streq(t, "now"))
+                goto finish;
+
+        else if (streq(t, "today")) {
+                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
+                goto finish;
+
+        } else if (streq(t, "yesterday")) {
+                tm.tm_mday --;
+                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
+                goto finish;
+
+        } else if (streq(t, "tomorrow")) {
+                tm.tm_mday ++;
+                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
+                goto finish;
+
+        } else if (t[0] == '+') {
+
+                r = parse_usec(t+1, &plus);
+                if (r < 0)
+                        return r;
+
+                goto finish;
+        } else if (t[0] == '-') {
+
+                r = parse_usec(t+1, &minus);
+                if (r < 0)
+                        return r;
+
+                goto finish;
+
+        } else if (endswith(t, " ago")) {
+                _cleanup_free_ char *z;
+
+                z = strndup(t, strlen(t) - 4);
+                if (!z)
+                        return -ENOMEM;
+
+                r = parse_usec(z, &minus);
+                if (r < 0)
+                        return r;
+
+                goto finish;
+        }
+
+        for (i = 0; i < ELEMENTSOF(day_nr); i++) {
+                size_t skip;
+
+                if (!startswith_no_case(t, day_nr[i].name))
+                        continue;
+
+                skip = strlen(day_nr[i].name);
+                if (t[skip] != ' ')
+                        continue;
+
+                weekday = day_nr[i].nr;
+                t += skip + 1;
+                break;
+        }
+
+        copy = tm;
+        k = strptime(t, "%y-%m-%d %H:%M:%S", &tm);
+        if (k && *k == 0)
+                goto finish;
+
+        tm = copy;
+        k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm);
+        if (k && *k == 0)
+                goto finish;
+
+        tm = copy;
+        k = strptime(t, "%y-%m-%d %H:%M", &tm);
+        if (k && *k == 0) {
+                tm.tm_sec = 0;
+                goto finish;
+        }
+
+        tm = copy;
+        k = strptime(t, "%Y-%m-%d %H:%M", &tm);
+        if (k && *k == 0) {
+                tm.tm_sec = 0;
+                goto finish;
+        }
+
+        tm = copy;
+        k = strptime(t, "%y-%m-%d", &tm);
+        if (k && *k == 0) {
+                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
+                goto finish;
+        }
+
+        tm = copy;
+        k = strptime(t, "%Y-%m-%d", &tm);
+        if (k && *k == 0) {
+                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
+                goto finish;
+        }
+
+        tm = copy;
+        k = strptime(t, "%H:%M:%S", &tm);
+        if (k && *k == 0)
+                goto finish;
+
+        tm = copy;
+        k = strptime(t, "%H:%M", &tm);
+        if (k && *k == 0) {
+                tm.tm_sec = 0;
+                goto finish;
+        }
+
+        return -EINVAL;
+
+finish:
+        x = mktime(&tm);
+        if (x == (time_t) -1)
+                return -EINVAL;
+
+        if (weekday >= 0 && tm.tm_wday != weekday)
+                return -EINVAL;
+
+        ret = (usec_t) x * USEC_PER_SEC;
+
+        ret += plus;
+        if (ret > minus)
+                ret -= minus;
+        else
+                ret = 0;
+
+        *usec = ret;
+
+        return 0;
+}
+
+int parse_usec(const char *t, usec_t *usec) {
+        static const struct {
+                const char *suffix;
+                usec_t usec;
+        } table[] = {
+                { "seconds", USEC_PER_SEC },
+                { "second", USEC_PER_SEC },
+                { "sec", USEC_PER_SEC },
+                { "s", USEC_PER_SEC },
+                { "minutes", USEC_PER_MINUTE },
+                { "minute", USEC_PER_MINUTE },
+                { "min", USEC_PER_MINUTE },
+                { "months", USEC_PER_MONTH },
+                { "month", USEC_PER_MONTH },
+                { "msec", USEC_PER_MSEC },
+                { "ms", USEC_PER_MSEC },
+                { "m", USEC_PER_MINUTE },
+                { "hours", USEC_PER_HOUR },
+                { "hour", USEC_PER_HOUR },
+                { "hr", USEC_PER_HOUR },
+                { "h", USEC_PER_HOUR },
+                { "days", USEC_PER_DAY },
+                { "day", USEC_PER_DAY },
+                { "d", USEC_PER_DAY },
+                { "weeks", USEC_PER_WEEK },
+                { "week", USEC_PER_WEEK },
+                { "w", USEC_PER_WEEK },
+                { "years", USEC_PER_YEAR },
+                { "year", USEC_PER_YEAR },
+                { "y", USEC_PER_YEAR },
+                { "usec", 1ULL },
+                { "us", 1ULL },
+                { "", USEC_PER_SEC }, /* default is sec */
+        };
+
+        const char *p;
+        usec_t r = 0;
+
+        assert(t);
+        assert(usec);
+
+        p = t;
+        do {
+                long long l;
+                char *e;
+                unsigned i;
+
+                errno = 0;
+                l = strtoll(p, &e, 10);
+
+                if (errno != 0)
+                        return -errno;
+
+                if (l < 0)
+                        return -ERANGE;
+
+                if (e == p)
+                        return -EINVAL;
+
+                e += strspn(e, WHITESPACE);
+
+                for (i = 0; i < ELEMENTSOF(table); i++)
+                        if (startswith(e, table[i].suffix)) {
+                                r += (usec_t) l * table[i].usec;
+                                p = e + strlen(table[i].suffix);
+                                break;
+                        }
+
+                if (i >= ELEMENTSOF(table))
+                        return -EINVAL;
+
+        } while (*p != 0);
+
+        *usec = r;
+
+        return 0;
+}
+
+int parse_nsec(const char *t, nsec_t *nsec) {
+        static const struct {
+                const char *suffix;
+                nsec_t nsec;
+        } table[] = {
+                { "seconds", NSEC_PER_SEC },
+                { "second", NSEC_PER_SEC },
+                { "sec", NSEC_PER_SEC },
+                { "s", NSEC_PER_SEC },
+                { "minutes", NSEC_PER_MINUTE },
+                { "minute", NSEC_PER_MINUTE },
+                { "min", NSEC_PER_MINUTE },
+                { "months", NSEC_PER_MONTH },
+                { "month", NSEC_PER_MONTH },
+                { "msec", NSEC_PER_MSEC },
+                { "ms", NSEC_PER_MSEC },
+                { "m", NSEC_PER_MINUTE },
+                { "hours", NSEC_PER_HOUR },
+                { "hour", NSEC_PER_HOUR },
+                { "hr", NSEC_PER_HOUR },
+                { "h", NSEC_PER_HOUR },
+                { "days", NSEC_PER_DAY },
+                { "day", NSEC_PER_DAY },
+                { "d", NSEC_PER_DAY },
+                { "weeks", NSEC_PER_WEEK },
+                { "week", NSEC_PER_WEEK },
+                { "w", NSEC_PER_WEEK },
+                { "years", NSEC_PER_YEAR },
+                { "year", NSEC_PER_YEAR },
+                { "y", NSEC_PER_YEAR },
+                { "usec", NSEC_PER_USEC },
+                { "us", NSEC_PER_USEC },
+                { "nsec", 1ULL },
+                { "ns", 1ULL },
+                { "", 1ULL }, /* default is nsec */
+        };
+
+        const char *p;
+        nsec_t r = 0;
+
+        assert(t);
+        assert(nsec);
+
+        p = t;
+        do {
+                long long l;
+                char *e;
+                unsigned i;
+
+                errno = 0;
+                l = strtoll(p, &e, 10);
+
+                if (errno != 0)
+                        return -errno;
+
+                if (l < 0)
+                        return -ERANGE;
+
+                if (e == p)
+                        return -EINVAL;
+
+                e += strspn(e, WHITESPACE);
+
+                for (i = 0; i < ELEMENTSOF(table); i++)
+                        if (startswith(e, table[i].suffix)) {
+                                r += (nsec_t) l * table[i].nsec;
+                                p = e + strlen(table[i].suffix);
+                                break;
+                        }
+
+                if (i >= ELEMENTSOF(table))
+                        return -EINVAL;
+
+        } while (*p != 0);
+
+        *nsec = r;
+
+        return 0;
+}
diff --git a/src/shared/time-util.h b/src/shared/time-util.h
new file mode 100644 (file)
index 0000000..7194875
--- /dev/null
@@ -0,0 +1,83 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+
+typedef uint64_t usec_t;
+typedef uint64_t nsec_t;
+
+#include "macro.h"
+
+typedef struct dual_timestamp {
+        usec_t realtime;
+        usec_t monotonic;
+} dual_timestamp;
+
+#define MSEC_PER_SEC  1000ULL
+#define USEC_PER_SEC  1000000ULL
+#define USEC_PER_MSEC 1000ULL
+#define NSEC_PER_SEC  1000000000ULL
+#define NSEC_PER_MSEC 1000000ULL
+#define NSEC_PER_USEC 1000ULL
+
+#define USEC_PER_MINUTE (60ULL*USEC_PER_SEC)
+#define NSEC_PER_MINUTE (60ULL*NSEC_PER_SEC)
+#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE)
+#define NSEC_PER_HOUR (60ULL*NSEC_PER_MINUTE)
+#define USEC_PER_DAY (24ULL*USEC_PER_HOUR)
+#define NSEC_PER_DAY (24ULL*NSEC_PER_HOUR)
+#define USEC_PER_WEEK (7ULL*USEC_PER_DAY)
+#define NSEC_PER_WEEK (7ULL*NSEC_PER_DAY)
+#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC)
+#define NSEC_PER_MONTH (2629800ULL*NSEC_PER_SEC)
+#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC)
+#define NSEC_PER_YEAR (31557600ULL*NSEC_PER_SEC)
+
+#define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */
+#define FORMAT_TIMESTAMP_RELATIVE_MAX 256
+#define FORMAT_TIMESPAN_MAX 64
+
+usec_t now(clockid_t clock);
+
+dual_timestamp* dual_timestamp_get(dual_timestamp *ts);
+dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u);
+
+#define dual_timestamp_is_set(ts) ((ts)->realtime > 0)
+
+usec_t timespec_load(const struct timespec *ts);
+struct timespec *timespec_store(struct timespec *ts, usec_t u);
+
+usec_t timeval_load(const struct timeval *tv);
+struct timeval *timeval_store(struct timeval *tv, usec_t u);
+
+char *format_timestamp(char *buf, size_t l, usec_t t);
+char *format_timestamp_relative(char *buf, size_t l, usec_t t);
+char *format_timespan(char *buf, size_t l, usec_t t);
+
+void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t);
+void dual_timestamp_deserialize(const char *value, dual_timestamp *t);
+
+int parse_timestamp(const char *t, usec_t *usec);
+
+int parse_usec(const char *t, usec_t *usec);
+int parse_nsec(const char *t, nsec_t *nsec);
diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c
new file mode 100644 (file)
index 0000000..88ca0b8
--- /dev/null
@@ -0,0 +1,519 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+
+#include "path-util.h"
+#include "util.h"
+#include "unit-name.h"
+
+#define VALID_CHARS                             \
+        "0123456789"                            \
+        "abcdefghijklmnopqrstuvwxyz"            \
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"            \
+        ":-_.\\"
+
+const char* const unit_type_table[_UNIT_TYPE_MAX] = {
+        [UNIT_SERVICE] = "service",
+        [UNIT_SOCKET] = "socket",
+        [UNIT_TARGET] = "target",
+        [UNIT_DEVICE] = "device",
+        [UNIT_MOUNT] = "mount",
+        [UNIT_AUTOMOUNT] = "automount",
+        [UNIT_SNAPSHOT] = "snapshot",
+        [UNIT_TIMER] = "timer",
+        [UNIT_SWAP] = "swap",
+        [UNIT_PATH] = "path",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType);
+
+const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
+        [UNIT_STUB] = "stub",
+        [UNIT_LOADED] = "loaded",
+        [UNIT_ERROR] = "error",
+        [UNIT_MERGED] = "merged",
+        [UNIT_MASKED] = "masked"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
+
+bool unit_name_is_valid(const char *n, bool template_ok) {
+        const char *e, *i, *at;
+
+        /* Valid formats:
+         *
+         *         string@instance.suffix
+         *         string.suffix
+         */
+
+        assert(n);
+
+        if (strlen(n) >= UNIT_NAME_MAX)
+                return false;
+
+        e = strrchr(n, '.');
+        if (!e || e == n)
+                return false;
+
+        if (unit_type_from_string(e + 1) < 0)
+                return false;
+
+        for (i = n, at = NULL; i < e; i++) {
+
+                if (*i == '@' && !at)
+                        at = i;
+
+                if (!strchr("@" VALID_CHARS, *i))
+                        return false;
+        }
+
+        if (at) {
+                if (at == n)
+                        return false;
+
+                if (!template_ok && at+1 == e)
+                        return false;
+        }
+
+        return true;
+}
+
+bool unit_instance_is_valid(const char *i) {
+        assert(i);
+
+        /* The max length depends on the length of the string, so we
+         * don't really check this here. */
+
+        if (i[0] == 0)
+                return false;
+
+        /* We allow additional @ in the instance string, we do not
+         * allow them in the prefix! */
+
+        for (; *i; i++)
+                if (!strchr("@" VALID_CHARS, *i))
+                        return false;
+
+        return true;
+}
+
+bool unit_prefix_is_valid(const char *p) {
+
+        /* We don't allow additional @ in the instance string */
+
+        if (p[0] == 0)
+                return false;
+
+        for (; *p; p++)
+                if (!strchr(VALID_CHARS, *p))
+                        return false;
+
+        return true;
+}
+
+int unit_name_to_instance(const char *n, char **instance) {
+        const char *p, *d;
+        char *i;
+
+        assert(n);
+        assert(instance);
+
+        /* Everything past the first @ and before the last . is the instance */
+        p = strchr(n, '@');
+        if (!p) {
+                *instance = NULL;
+                return 0;
+        }
+
+        assert_se(d = strrchr(n, '.'));
+        assert(p < d);
+
+        i = strndup(p+1, d-p-1);
+        if (!i)
+                return -ENOMEM;
+
+        *instance = i;
+        return 0;
+}
+
+char *unit_name_to_prefix_and_instance(const char *n) {
+        const char *d;
+
+        assert(n);
+
+        assert_se(d = strrchr(n, '.'));
+
+        return strndup(n, d - n);
+}
+
+char *unit_name_to_prefix(const char *n) {
+        const char *p;
+
+        p = strchr(n, '@');
+        if (p)
+                return strndup(n, p - n);
+
+        return unit_name_to_prefix_and_instance(n);
+}
+
+char *unit_name_change_suffix(const char *n, const char *suffix) {
+        char *e, *r;
+        size_t a, b;
+
+        assert(n);
+        assert(unit_name_is_valid(n, true));
+        assert(suffix);
+
+        assert_se(e = strrchr(n, '.'));
+        a = e - n;
+        b = strlen(suffix);
+
+        r = new(char, a + b + 1);
+        if (!r)
+                return NULL;
+
+        memcpy(r, n, a);
+        memcpy(r+a, suffix, b+1);
+
+        return r;
+}
+
+char *unit_name_build(const char *prefix, const char *instance, const char *suffix) {
+        assert(prefix);
+        assert(unit_prefix_is_valid(prefix));
+        assert(!instance || unit_instance_is_valid(instance));
+        assert(suffix);
+
+        if (!instance)
+                return strappend(prefix, suffix);
+
+        return strjoin(prefix, "@", instance, suffix, NULL);
+}
+
+static char *do_escape_char(char c, char *t) {
+        *(t++) = '\\';
+        *(t++) = 'x';
+        *(t++) = hexchar(c >> 4);
+        *(t++) = hexchar(c);
+        return t;
+}
+
+static char *do_escape(const char *f, char *t) {
+        assert(f);
+        assert(t);
+
+        /* do not create units with a leading '.', like for "/.dotdir" mount points */
+        if (*f == '.') {
+                t = do_escape_char(*f, t);
+                f++;
+        }
+
+        for (; *f; f++) {
+                if (*f == '/')
+                        *(t++) = '-';
+                else if (*f == '-' || *f == '\\' || !strchr(VALID_CHARS, *f))
+                        t = do_escape_char(*f, t);
+                else
+                        *(t++) = *f;
+        }
+
+        return t;
+}
+
+char *unit_name_escape(const char *f) {
+        char *r, *t;
+
+        r = new(char, strlen(f)*4+1);
+        if (!r)
+                return NULL;
+
+        t = do_escape(f, r);
+        *t = 0;
+
+        return r;
+}
+
+char *unit_name_unescape(const char *f) {
+        char *r, *t;
+
+        assert(f);
+
+        r = strdup(f);
+        if (!r)
+                return NULL;
+
+        for (t = r; *f; f++) {
+                if (*f == '-')
+                        *(t++) = '/';
+                else if (*f == '\\') {
+                        int a, b;
+
+                        if (f[1] != 'x' ||
+                            (a = unhexchar(f[2])) < 0 ||
+                            (b = unhexchar(f[3])) < 0) {
+                                /* Invalid escape code, let's take it literal then */
+                                *(t++) = '\\';
+                        } else {
+                                *(t++) = (char) ((a << 4) | b);
+                                f += 3;
+                        }
+                } else
+                        *(t++) = *f;
+        }
+
+        *t = 0;
+
+        return r;
+}
+
+char *unit_name_path_escape(const char *f) {
+        char *p, *e;
+
+        assert(f);
+
+        p = strdup(f);
+        if (!p)
+                return NULL;
+
+        path_kill_slashes(p);
+
+        if (streq(p, "/")) {
+                free(p);
+                return strdup("-");
+        }
+
+        e = unit_name_escape(p[0] == '/' ? p + 1 : p);
+        free(p);
+
+        return e;
+}
+
+char *unit_name_path_unescape(const char *f) {
+        char *e;
+
+        assert(f);
+
+        e = unit_name_unescape(f);
+        if (!e)
+                return NULL;
+
+        if (e[0] != '/') {
+                char *w;
+
+                w = strappend("/", e);
+                free(e);
+
+                return w;
+        }
+
+        return e;
+}
+
+bool unit_name_is_template(const char *n) {
+        const char *p;
+
+        assert(n);
+
+        p = strchr(n, '@');
+        if (!p)
+                return false;
+
+        return p[1] == '.';
+}
+
+bool unit_name_is_instance(const char *n) {
+        const char *p;
+
+        assert(n);
+
+        p = strchr(n, '@');
+        if (!p)
+                return false;
+
+        return p[1] != '.';
+}
+
+char *unit_name_replace_instance(const char *f, const char *i) {
+        const char *p, *e;
+        char *r, *k;
+        size_t a, b;
+
+        assert(f);
+
+        p = strchr(f, '@');
+        if (!p)
+                return strdup(f);
+
+        e = strrchr(f, '.');
+        if (!e)
+                assert_se(e = strchr(f, 0));
+
+        a = p - f;
+        b = strlen(i);
+
+        r = new(char, a + 1 + b + strlen(e) + 1);
+        if (!r)
+                return NULL;
+
+        k = mempcpy(r, f, a + 1);
+        k = mempcpy(k, i, b);
+        strcpy(k, e);
+
+        return r;
+}
+
+char *unit_name_template(const char *f) {
+        const char *p, *e;
+        char *r;
+        size_t a;
+
+        p = strchr(f, '@');
+        if (!p)
+                return strdup(f);
+
+        assert_se(e = strrchr(f, '.'));
+        a = p - f + 1;
+
+        r = new(char, a + strlen(e) + 1);
+        if (!r)
+                return NULL;
+
+        strcpy(mempcpy(r, f, a), e);
+        return r;
+
+}
+
+char *unit_name_from_path(const char *path, const char *suffix) {
+        char *p, *r;
+
+        assert(path);
+        assert(suffix);
+
+        p = unit_name_path_escape(path);
+        if (!p)
+                return NULL;
+
+        r = strappend(p, suffix);
+        free(p);
+
+        return r;
+}
+
+char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix) {
+        char *p, *r;
+
+        assert(prefix);
+        assert(path);
+        assert(suffix);
+
+        p = unit_name_path_escape(path);
+        if (!p)
+                return NULL;
+
+        r = strjoin(prefix, "@", p, suffix, NULL);
+        free(p);
+
+        return r;
+}
+
+char *unit_name_to_path(const char *name) {
+        char *w, *e;
+
+        assert(name);
+
+        w = unit_name_to_prefix(name);
+        if (!w)
+                return NULL;
+
+        e = unit_name_path_unescape(w);
+        free(w);
+
+        return e;
+}
+
+char *unit_dbus_path_from_name(const char *name) {
+        char *e, *p;
+
+        assert(name);
+
+        e = bus_path_escape(name);
+        if (!e)
+                return NULL;
+
+        p = strappend("/org/freedesktop/systemd1/unit/", e);
+        free(e);
+
+        return p;
+}
+
+char *unit_name_mangle(const char *name) {
+        char *r, *t;
+        const char *f;
+
+        assert(name);
+
+        /* Try to turn a string that might not be a unit name into a
+         * sensible unit name. */
+
+        if (is_device_path(name))
+                return unit_name_from_path(name, ".device");
+
+        if (path_is_absolute(name))
+                return unit_name_from_path(name, ".mount");
+
+        /* We'll only escape the obvious characters here, to play
+         * safe. */
+
+        r = new(char, strlen(name) * 4 + 1 + sizeof(".service")-1);
+        if (!r)
+                return NULL;
+
+        for (f = name, t = r; *f; f++) {
+                if (*f == '/')
+                        *(t++) = '-';
+                else if (!strchr("@" VALID_CHARS, *f))
+                        t = do_escape_char(*f, t);
+                else
+                        *(t++) = *f;
+        }
+
+        if (unit_name_to_type(name) < 0)
+                strcpy(t, ".service");
+        else
+                *t = 0;
+
+        return r;
+}
+
+UnitType unit_name_to_type(const char *n) {
+        const char *e;
+
+        assert(n);
+
+        e = strrchr(n, '.');
+        if (!e)
+                return _UNIT_TYPE_INVALID;
+
+        return unit_type_from_string(e + 1);
+}
diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h
new file mode 100644 (file)
index 0000000..d7528a3
--- /dev/null
@@ -0,0 +1,96 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#define UNIT_NAME_MAX 256
+
+typedef enum UnitType UnitType;
+typedef enum UnitLoadState UnitLoadState;
+
+enum UnitType {
+        UNIT_SERVICE = 0,
+        UNIT_SOCKET,
+        UNIT_TARGET,
+        UNIT_DEVICE,
+        UNIT_MOUNT,
+        UNIT_AUTOMOUNT,
+        UNIT_SNAPSHOT,
+        UNIT_TIMER,
+        UNIT_SWAP,
+        UNIT_PATH,
+        _UNIT_TYPE_MAX,
+        _UNIT_TYPE_INVALID = -1
+};
+
+enum UnitLoadState {
+        UNIT_STUB = 0,
+        UNIT_LOADED,
+        UNIT_ERROR,
+        UNIT_MERGED,
+        UNIT_MASKED,
+        _UNIT_LOAD_STATE_MAX,
+        _UNIT_LOAD_STATE_INVALID = -1
+};
+
+extern const char* const unit_type_table[];
+const char *unit_type_to_string(UnitType i);
+UnitType unit_type_from_string(const char *s);
+
+extern const char* const unit_load_state_table[];
+const char *unit_load_state_to_string(UnitLoadState i);
+UnitLoadState unit_load_state_from_string(const char *s);
+
+int unit_name_to_instance(const char *n, char **instance);
+char* unit_name_to_prefix(const char *n);
+char* unit_name_to_prefix_and_instance(const char *n);
+
+bool unit_name_is_valid(const char *n, bool template_ok);
+bool unit_prefix_is_valid(const char *p);
+bool unit_instance_is_valid(const char *i);
+
+UnitType unit_name_to_type(const char *n);
+
+char *unit_name_change_suffix(const char *n, const char *suffix);
+
+char *unit_name_build(const char *prefix, const char *instance, const char *suffix);
+
+char *unit_name_escape(const char *f);
+char *unit_name_unescape(const char *f);
+char *unit_name_path_escape(const char *f);
+char *unit_name_path_unescape(const char *f);
+
+bool unit_name_is_template(const char *n);
+bool unit_name_is_instance(const char *n);
+
+char *unit_name_replace_instance(const char *f, const char *i);
+
+char *unit_name_template(const char *f);
+
+char *unit_name_from_path(const char *path, const char *suffix);
+char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix);
+char *unit_name_to_path(const char *name);
+
+char *unit_dbus_path_from_name(const char *name);
+
+char *unit_name_mangle(const char *name);
diff --git a/src/shared/utf8.c b/src/shared/utf8.c
new file mode 100644 (file)
index 0000000..62e2803
--- /dev/null
@@ -0,0 +1,285 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* This file is based on the GLIB utf8 validation functions. The
+ * original license text follows. */
+
+/* gutf8.c - Operations on UTF-8 strings.
+ *
+ * Copyright (C) 1999 Tom Tromey
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "utf8.h"
+
+#define FILTER_CHAR '_'
+
+static inline bool is_unicode_valid(uint32_t ch) {
+
+        if (ch >= 0x110000) /* End of unicode space */
+                return false;
+        if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */
+                return false;
+        if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) /* Reserved */
+                return false;
+        if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */
+                return false;
+
+        return true;
+}
+
+static inline bool is_continuation_char(uint8_t ch) {
+        if ((ch & 0xc0) != 0x80) /* 10xxxxxx */
+                return false;
+        return true;
+}
+
+static inline void merge_continuation_char(uint32_t *u_ch, uint8_t ch) {
+        *u_ch <<= 6;
+        *u_ch |= ch & 0x3f;
+}
+
+static bool is_unicode_control(uint32_t ch) {
+
+        /*
+          0 to ' '-1 is the C0 range.
+          DEL=0x7F, and DEL+1 to 0x9F is C1 range.
+          '\t' is in C0 range, but more or less harmless and commonly used.
+        */
+
+        return (ch < ' ' && ch != '\t') ||
+                (0x7F <= ch && ch <= 0x9F);
+}
+
+char* utf8_is_printable_n(const char* str, size_t length) {
+        uint32_t val = 0;
+        uint32_t min = 0;
+        const uint8_t *p;
+
+        assert(str);
+
+        for (p = (const uint8_t*) str; length; p++, length--) {
+                if (*p < 128) {
+                        val = *p;
+                } else {
+                        if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */
+                                min = 128;
+                                val = (uint32_t) (*p & 0x1e);
+                                goto ONE_REMAINING;
+                        } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/
+                                min = (1 << 11);
+                                val = (uint32_t) (*p & 0x0f);
+                                goto TWO_REMAINING;
+                        } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */
+                                min = (1 << 16);
+                                val = (uint32_t) (*p & 0x07);
+                        } else
+                                goto error;
+
+                        p++;
+                        length--;
+                        if (!length || !is_continuation_char(*p))
+                                goto error;
+                        merge_continuation_char(&val, *p);
+
+                TWO_REMAINING:
+                        p++;
+                        length--;
+                        if (!is_continuation_char(*p))
+                                goto error;
+                        merge_continuation_char(&val, *p);
+
+                ONE_REMAINING:
+                        p++;
+                        length--;
+                        if (!is_continuation_char(*p))
+                                goto error;
+                        merge_continuation_char(&val, *p);
+
+                        if (val < min)
+                                goto error;
+                }
+
+                if (is_unicode_control(val))
+                        goto error;
+        }
+
+        return (char*) str;
+
+error:
+        return NULL;
+}
+
+static char* utf8_validate(const char *str, char *output) {
+        uint32_t val = 0;
+        uint32_t min = 0;
+        const uint8_t *p, *last;
+        int size;
+        uint8_t *o;
+
+        assert(str);
+
+        o = (uint8_t*) output;
+        for (p = (const uint8_t*) str; *p; p++) {
+                if (*p < 128) {
+                        if (o)
+                                *o = *p;
+                } else {
+                        last = p;
+
+                        if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */
+                                size = 2;
+                                min = 128;
+                                val = (uint32_t) (*p & 0x1e);
+                                goto ONE_REMAINING;
+                        } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/
+                                size = 3;
+                                min = (1 << 11);
+                                val = (uint32_t) (*p & 0x0f);
+                                goto TWO_REMAINING;
+                        } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */
+                                size = 4;
+                                min = (1 << 16);
+                                val = (uint32_t) (*p & 0x07);
+                        } else
+                                goto error;
+
+                        p++;
+                        if (!is_continuation_char(*p))
+                                goto error;
+                        merge_continuation_char(&val, *p);
+
+                TWO_REMAINING:
+                        p++;
+                        if (!is_continuation_char(*p))
+                                goto error;
+                        merge_continuation_char(&val, *p);
+
+                ONE_REMAINING:
+                        p++;
+                        if (!is_continuation_char(*p))
+                                goto error;
+                        merge_continuation_char(&val, *p);
+
+                        if (val < min)
+                                goto error;
+
+                        if (!is_unicode_valid(val))
+                                goto error;
+
+                        if (o) {
+                                memcpy(o, last, (size_t) size);
+                                o += size;
+                        }
+
+                        continue;
+
+                error:
+                        if (o) {
+                                *o = FILTER_CHAR;
+                                p = last; /* We retry at the next character */
+                        } else
+                                goto failure;
+                }
+
+                if (o)
+                        o++;
+        }
+
+        if (o) {
+                *o = '\0';
+                return output;
+        }
+
+        return (char*) str;
+
+failure:
+        return NULL;
+}
+
+char* utf8_is_valid (const char *str) {
+        return utf8_validate(str, NULL);
+}
+
+char* utf8_filter (const char *str) {
+        char *new_str;
+
+        assert(str);
+
+        new_str = malloc(strlen(str) + 1);
+        if (!new_str)
+                return NULL;
+
+        return utf8_validate(str, new_str);
+}
+
+char *ascii_is_valid(const char *str) {
+        const char *p;
+
+        assert(str);
+
+        for (p = str; *p; p++)
+                if ((unsigned char) *p >= 128)
+                        return NULL;
+
+        return (char*) str;
+}
+
+char *ascii_filter(const char *str) {
+        const char *s;
+        char *r, *d;
+        size_t l;
+
+        assert(str);
+
+        l = strlen(str);
+        r = malloc(l + 1);
+        if (!r)
+                return NULL;
+
+        for (s = str, d = r; *s; s++)
+                if ((unsigned char) *s < 128)
+                        *(d++) = *s;
+
+        *d = 0;
+
+        return r;
+}
diff --git a/src/shared/utf8.h b/src/shared/utf8.h
new file mode 100644 (file)
index 0000000..13d2f6a
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+
+char *utf8_is_valid(const char *s) _pure_;
+char *ascii_is_valid(const char *s) _pure_;
+
+char *utf8_is_printable_n(const char* str, size_t length) _pure_;
+
+char *utf8_filter(const char *s);
+char *ascii_filter(const char *s);
diff --git a/src/shared/util.c b/src/shared/util.c
new file mode 100644 (file)
index 0000000..49b5844
--- /dev/null
@@ -0,0 +1,5843 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <sched.h>
+#include <sys/resource.h>
+#include <linux/sched.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <linux/vt.h>
+#include <linux/tiocl.h>
+#include <termios.h>
+#include <stdarg.h>
+#include <sys/inotify.h>
+#include <sys/poll.h>
+#include <libgen.h>
+#include <ctype.h>
+#include <sys/prctl.h>
+#include <sys/utsname.h>
+#include <pwd.h>
+#include <netinet/ip.h>
+#include <linux/kd.h>
+#include <dlfcn.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <glob.h>
+#include <grp.h>
+#include <sys/mman.h>
+#include <sys/vfs.h>
+#include <linux/magic.h>
+#include <limits.h>
+#include <langinfo.h>
+#include <locale.h>
+
+#include "macro.h"
+#include "util.h"
+#include "ioprio.h"
+#include "missing.h"
+#include "log.h"
+#include "strv.h"
+#include "label.h"
+#include "path-util.h"
+#include "exit-status.h"
+#include "hashmap.h"
+
+int saved_argc = 0;
+char **saved_argv = NULL;
+
+static volatile unsigned cached_columns = 0;
+static volatile unsigned cached_lines = 0;
+
+bool is_efiboot(void) {
+        return access("/sys/firmware/efi", F_OK) >= 0;
+}
+
+size_t page_size(void) {
+        static __thread size_t pgsz = 0;
+        long r;
+
+        if (_likely_(pgsz > 0))
+                return pgsz;
+
+        r = sysconf(_SC_PAGESIZE);
+        assert(r > 0);
+
+        pgsz = (size_t) r;
+        return pgsz;
+}
+
+bool streq_ptr(const char *a, const char *b) {
+
+        /* Like streq(), but tries to make sense of NULL pointers */
+
+        if (a && b)
+                return streq(a, b);
+
+        if (!a && !b)
+                return true;
+
+        return false;
+}
+
+char* endswith(const char *s, const char *postfix) {
+        size_t sl, pl;
+
+        assert(s);
+        assert(postfix);
+
+        sl = strlen(s);
+        pl = strlen(postfix);
+
+        if (pl == 0)
+                return (char*) s + sl;
+
+        if (sl < pl)
+                return NULL;
+
+        if (memcmp(s + sl - pl, postfix, pl) != 0)
+                return NULL;
+
+        return (char*) s + sl - pl;
+}
+
+char* startswith(const char *s, const char *prefix) {
+        const char *a, *b;
+
+        assert(s);
+        assert(prefix);
+
+        a = s, b = prefix;
+        for (;;) {
+                if (*b == 0)
+                        return (char*) a;
+                if (*a != *b)
+                        return NULL;
+
+                a++, b++;
+        }
+}
+
+char* startswith_no_case(const char *s, const char *prefix) {
+        const char *a, *b;
+
+        assert(s);
+        assert(prefix);
+
+        a = s, b = prefix;
+        for (;;) {
+                if (*b == 0)
+                        return (char*) a;
+                if (tolower(*a) != tolower(*b))
+                        return NULL;
+
+                a++, b++;
+        }
+}
+
+bool first_word(const char *s, const char *word) {
+        size_t sl, wl;
+
+        assert(s);
+        assert(word);
+
+        sl = strlen(s);
+        wl = strlen(word);
+
+        if (sl < wl)
+                return false;
+
+        if (wl == 0)
+                return true;
+
+        if (memcmp(s, word, wl) != 0)
+                return false;
+
+        return s[wl] == 0 ||
+                strchr(WHITESPACE, s[wl]);
+}
+
+int close_nointr(int fd) {
+        assert(fd >= 0);
+
+        for (;;) {
+                int r;
+
+                r = close(fd);
+                if (r >= 0)
+                        return r;
+
+                if (errno != EINTR)
+                        return -errno;
+        }
+}
+
+void close_nointr_nofail(int fd) {
+        int saved_errno = errno;
+
+        /* like close_nointr() but cannot fail, and guarantees errno
+         * is unchanged */
+
+        assert_se(close_nointr(fd) == 0);
+
+        errno = saved_errno;
+}
+
+void close_many(const int fds[], unsigned n_fd) {
+        unsigned i;
+
+        for (i = 0; i < n_fd; i++)
+                close_nointr_nofail(fds[i]);
+}
+
+int parse_boolean(const char *v) {
+        assert(v);
+
+        if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
+                return 1;
+        else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
+                return 0;
+
+        return -EINVAL;
+}
+
+int parse_pid(const char *s, pid_t* ret_pid) {
+        unsigned long ul = 0;
+        pid_t pid;
+        int r;
+
+        assert(s);
+        assert(ret_pid);
+
+        r = safe_atolu(s, &ul);
+        if (r < 0)
+                return r;
+
+        pid = (pid_t) ul;
+
+        if ((unsigned long) pid != ul)
+                return -ERANGE;
+
+        if (pid <= 0)
+                return -ERANGE;
+
+        *ret_pid = pid;
+        return 0;
+}
+
+int parse_uid(const char *s, uid_t* ret_uid) {
+        unsigned long ul = 0;
+        uid_t uid;
+        int r;
+
+        assert(s);
+        assert(ret_uid);
+
+        r = safe_atolu(s, &ul);
+        if (r < 0)
+                return r;
+
+        uid = (uid_t) ul;
+
+        if ((unsigned long) uid != ul)
+                return -ERANGE;
+
+        *ret_uid = uid;
+        return 0;
+}
+
+int safe_atou(const char *s, unsigned *ret_u) {
+        char *x = NULL;
+        unsigned long l;
+
+        assert(s);
+        assert(ret_u);
+
+        errno = 0;
+        l = strtoul(s, &x, 0);
+
+        if (!x || x == s || *x || errno)
+                return errno ? -errno : -EINVAL;
+
+        if ((unsigned long) (unsigned) l != l)
+                return -ERANGE;
+
+        *ret_u = (unsigned) l;
+        return 0;
+}
+
+int safe_atoi(const char *s, int *ret_i) {
+        char *x = NULL;
+        long l;
+
+        assert(s);
+        assert(ret_i);
+
+        errno = 0;
+        l = strtol(s, &x, 0);
+
+        if (!x || x == s || *x || errno)
+                return errno ? -errno : -EINVAL;
+
+        if ((long) (int) l != l)
+                return -ERANGE;
+
+        *ret_i = (int) l;
+        return 0;
+}
+
+int safe_atollu(const char *s, long long unsigned *ret_llu) {
+        char *x = NULL;
+        unsigned long long l;
+
+        assert(s);
+        assert(ret_llu);
+
+        errno = 0;
+        l = strtoull(s, &x, 0);
+
+        if (!x || x == s || *x || errno)
+                return errno ? -errno : -EINVAL;
+
+        *ret_llu = l;
+        return 0;
+}
+
+int safe_atolli(const char *s, long long int *ret_lli) {
+        char *x = NULL;
+        long long l;
+
+        assert(s);
+        assert(ret_lli);
+
+        errno = 0;
+        l = strtoll(s, &x, 0);
+
+        if (!x || x == s || *x || errno)
+                return errno ? -errno : -EINVAL;
+
+        *ret_lli = l;
+        return 0;
+}
+
+/* Split a string into words. */
+char *split(const char *c, size_t *l, const char *separator, char **state) {
+        char *current;
+
+        current = *state ? *state : (char*) c;
+
+        if (!*current || *c == 0)
+                return NULL;
+
+        current += strspn(current, separator);
+        *l = strcspn(current, separator);
+        *state = current+*l;
+
+        return (char*) current;
+}
+
+/* Split a string into words, but consider strings enclosed in '' and
+ * "" as words even if they include spaces. */
+char *split_quoted(const char *c, size_t *l, char **state) {
+        char *current, *e;
+        bool escaped = false;
+
+        current = *state ? *state : (char*) c;
+
+        if (!*current || *c == 0)
+                return NULL;
+
+        current += strspn(current, WHITESPACE);
+
+        if (*current == '\'') {
+                current ++;
+
+                for (e = current; *e; e++) {
+                        if (escaped)
+                                escaped = false;
+                        else if (*e == '\\')
+                                escaped = true;
+                        else if (*e == '\'')
+                                break;
+                }
+
+                *l = e-current;
+                *state = *e == 0 ? e : e+1;
+        } else if (*current == '\"') {
+                current ++;
+
+                for (e = current; *e; e++) {
+                        if (escaped)
+                                escaped = false;
+                        else if (*e == '\\')
+                                escaped = true;
+                        else if (*e == '\"')
+                                break;
+                }
+
+                *l = e-current;
+                *state = *e == 0 ? e : e+1;
+        } else {
+                for (e = current; *e; e++) {
+                        if (escaped)
+                                escaped = false;
+                        else if (*e == '\\')
+                                escaped = true;
+                        else if (strchr(WHITESPACE, *e))
+                                break;
+                }
+                *l = e-current;
+                *state = e;
+        }
+
+        return (char*) current;
+}
+
+int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
+        int r;
+        _cleanup_fclose_ FILE *f = NULL;
+        char fn[PATH_MAX], line[LINE_MAX], *p;
+        long unsigned ppid;
+
+        assert(pid > 0);
+        assert(_ppid);
+
+        assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
+        char_array_0(fn);
+
+        f = fopen(fn, "re");
+        if (!f)
+                return -errno;
+
+        if (!fgets(line, sizeof(line), f)) {
+                r = feof(f) ? -EIO : -errno;
+                fclose(f);
+                return r;
+        }
+
+        /* Let's skip the pid and comm fields. The latter is enclosed
+         * in () but does not escape any () in its value, so let's
+         * skip over it manually */
+
+        p = strrchr(line, ')');
+        if (!p)
+                return -EIO;
+
+        p++;
+
+        if (sscanf(p, " "
+                   "%*c "  /* state */
+                   "%lu ", /* ppid */
+                   &ppid) != 1)
+                return -EIO;
+
+        if ((long unsigned) (pid_t) ppid != ppid)
+                return -ERANGE;
+
+        *_ppid = (pid_t) ppid;
+
+        return 0;
+}
+
+int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
+        _cleanup_fclose_ FILE *f = NULL;
+        char fn[PATH_MAX], line[LINE_MAX], *p;
+
+        assert(pid > 0);
+        assert(st);
+
+        assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
+        char_array_0(fn);
+
+        f = fopen(fn, "re");
+        if (!f)
+                return -errno;
+
+        if (!fgets(line, sizeof(line), f)) {
+                if (ferror(f))
+                        return -errno;
+
+                return -EIO;
+        }
+
+        /* Let's skip the pid and comm fields. The latter is enclosed
+         * in () but does not escape any () in its value, so let's
+         * skip over it manually */
+
+        p = strrchr(line, ')');
+        if (!p)
+                return -EIO;
+
+        p++;
+
+        if (sscanf(p, " "
+                   "%*c "  /* state */
+                   "%*d "  /* ppid */
+                   "%*d "  /* pgrp */
+                   "%*d "  /* session */
+                   "%*d "  /* tty_nr */
+                   "%*d "  /* tpgid */
+                   "%*u "  /* flags */
+                   "%*u "  /* minflt */
+                   "%*u "  /* cminflt */
+                   "%*u "  /* majflt */
+                   "%*u "  /* cmajflt */
+                   "%*u "  /* utime */
+                   "%*u "  /* stime */
+                   "%*d "  /* cutime */
+                   "%*d "  /* cstime */
+                   "%*d "  /* priority */
+                   "%*d "  /* nice */
+                   "%*d "  /* num_threads */
+                   "%*d "  /* itrealvalue */
+                   "%llu "  /* starttime */,
+                   st) != 1)
+                return -EIO;
+
+        return 0;
+}
+
+int write_one_line_file(const char *fn, const char *line) {
+        _cleanup_fclose_ FILE *f = NULL;
+
+        assert(fn);
+        assert(line);
+
+        f = fopen(fn, "we");
+        if (!f)
+                return -errno;
+
+        errno = 0;
+        if (fputs(line, f) < 0)
+                return errno ? -errno : -EIO;
+
+        if (!endswith(line, "\n"))
+                fputc('\n', f);
+
+        fflush(f);
+
+        if (ferror(f))
+                return errno ? -errno : -EIO;
+
+        return 0;
+}
+
+int fchmod_umask(int fd, mode_t m) {
+        mode_t u;
+        int r;
+
+        u = umask(0777);
+        r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
+        umask(u);
+
+        return r;
+}
+
+int write_one_line_file_atomic(const char *fn, const char *line) {
+        FILE *f;
+        int r;
+        char *p;
+
+        assert(fn);
+        assert(line);
+
+        r = fopen_temporary(fn, &f, &p);
+        if (r < 0)
+                return r;
+
+        fchmod_umask(fileno(f), 0644);
+
+        errno = 0;
+        if (fputs(line, f) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (!endswith(line, "\n"))
+                fputc('\n', f);
+
+        fflush(f);
+
+        if (ferror(f)) {
+                if (errno != 0)
+                        r = -errno;
+                else
+                        r = -EIO;
+        } else {
+                if (rename(p, fn) < 0)
+                        r = -errno;
+                else
+                        r = 0;
+        }
+
+finish:
+        if (r < 0)
+                unlink(p);
+
+        fclose(f);
+        free(p);
+
+        return r;
+}
+
+int read_one_line_file(const char *fn, char **line) {
+        _cleanup_fclose_ FILE *f = NULL;
+        char t[LINE_MAX], *c;
+
+        assert(fn);
+        assert(line);
+
+        f = fopen(fn, "re");
+        if (!f)
+                return -errno;
+
+        if (!fgets(t, sizeof(t), f)) {
+
+                if (ferror(f))
+                        return errno ? -errno : -EIO;
+
+                t[0] = 0;
+        }
+
+        c = strdup(t);
+        if (!c)
+                return -ENOMEM;
+        truncate_nl(c);
+
+        *line = c;
+        return 0;
+}
+
+int read_full_file(const char *fn, char **contents, size_t *size) {
+        _cleanup_fclose_ FILE *f = NULL;
+        size_t n, l;
+        _cleanup_free_ char *buf = NULL;
+        struct stat st;
+
+        f = fopen(fn, "re");
+        if (!f)
+                return -errno;
+
+        if (fstat(fileno(f), &st) < 0)
+                return -errno;
+
+        /* Safety check */
+        if (st.st_size > 4*1024*1024)
+                return -E2BIG;
+
+        n = st.st_size > 0 ? st.st_size : LINE_MAX;
+        l = 0;
+
+        for (;;) {
+                char *t;
+                size_t k;
+
+                t = realloc(buf, n+1);
+                if (!t)
+                        return -ENOMEM;
+
+                buf = t;
+                k = fread(buf + l, 1, n - l, f);
+
+                if (k <= 0) {
+                        if (ferror(f))
+                                return -errno;
+
+                        break;
+                }
+
+                l += k;
+                n *= 2;
+
+                /* Safety check */
+                if (n > 4*1024*1024)
+                        return -E2BIG;
+        }
+
+        buf[l] = 0;
+        *contents = buf;
+        buf = NULL;
+
+        if (size)
+                *size = l;
+
+        return 0;
+}
+
+int parse_env_file(
+                const char *fname,
+                const char *separator, ...) {
+
+        int r = 0;
+        char *contents = NULL, *p;
+
+        assert(fname);
+        assert(separator);
+
+        if ((r = read_full_file(fname, &contents, NULL)) < 0)
+                return r;
+
+        p = contents;
+        for (;;) {
+                const char *key = NULL;
+
+                p += strspn(p, separator);
+                p += strspn(p, WHITESPACE);
+
+                if (!*p)
+                        break;
+
+                if (!strchr(COMMENTS, *p)) {
+                        va_list ap;
+                        char **value;
+
+                        va_start(ap, separator);
+                        while ((key = va_arg(ap, char *))) {
+                                size_t n;
+                                char *v;
+
+                                value = va_arg(ap, char **);
+
+                                n = strlen(key);
+                                if (strncmp(p, key, n) != 0 ||
+                                    p[n] != '=')
+                                        continue;
+
+                                p += n + 1;
+                                n = strcspn(p, separator);
+
+                                if (n >= 2 &&
+                                    strchr(QUOTES, p[0]) &&
+                                    p[n-1] == p[0])
+                                        v = strndup(p+1, n-2);
+                                else
+                                        v = strndup(p, n);
+
+                                if (!v) {
+                                        r = -ENOMEM;
+                                        va_end(ap);
+                                        goto fail;
+                                }
+
+                                if (v[0] == '\0') {
+                                        /* return empty value strings as NULL */
+                                        free(v);
+                                        v = NULL;
+                                }
+
+                                free(*value);
+                                *value = v;
+
+                                p += n;
+
+                                r ++;
+                                break;
+                        }
+                        va_end(ap);
+                }
+
+                if (!key)
+                        p += strcspn(p, separator);
+        }
+
+fail:
+        free(contents);
+        return r;
+}
+
+int load_env_file(
+                const char *fname,
+                char ***rl) {
+
+        FILE *f;
+        char **m = NULL;
+        int r;
+
+        assert(fname);
+        assert(rl);
+
+        if (!(f = fopen(fname, "re")))
+                return -errno;
+
+        while (!feof(f)) {
+                char l[LINE_MAX], *p, *u;
+                char **t;
+
+                if (!fgets(l, sizeof(l), f)) {
+                        if (feof(f))
+                                break;
+
+                        r = -errno;
+                        goto finish;
+                }
+
+                p = strstrip(l);
+
+                if (!*p)
+                        continue;
+
+                if (strchr(COMMENTS, *p))
+                        continue;
+
+                if (!(u = normalize_env_assignment(p))) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                t = strv_append(m, u);
+                free(u);
+
+                if (!t) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                strv_free(m);
+                m = t;
+        }
+
+        r = 0;
+
+        *rl = m;
+        m = NULL;
+
+finish:
+        if (f)
+                fclose(f);
+
+        strv_free(m);
+
+        return r;
+}
+
+int write_env_file(const char *fname, char **l) {
+        char **i, *p;
+        FILE *f;
+        int r;
+
+        r = fopen_temporary(fname, &f, &p);
+        if (r < 0)
+                return r;
+
+        fchmod_umask(fileno(f), 0644);
+
+        errno = 0;
+        STRV_FOREACH(i, l) {
+                fputs(*i, f);
+                fputc('\n', f);
+        }
+
+        fflush(f);
+
+        if (ferror(f)) {
+                if (errno != 0)
+                        r = -errno;
+                else
+                        r = -EIO;
+        } else {
+                if (rename(p, fname) < 0)
+                        r = -errno;
+                else
+                        r = 0;
+        }
+
+        if (r < 0)
+                unlink(p);
+
+        fclose(f);
+        free(p);
+
+        return r;
+}
+
+char *truncate_nl(char *s) {
+        assert(s);
+
+        s[strcspn(s, NEWLINE)] = 0;
+        return s;
+}
+
+int get_process_comm(pid_t pid, char **name) {
+        int r;
+
+        assert(name);
+
+        if (pid == 0)
+                r = read_one_line_file("/proc/self/comm", name);
+        else {
+                char *p;
+                if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
+                        return -ENOMEM;
+
+                r = read_one_line_file(p, name);
+                free(p);
+        }
+
+        return r;
+}
+
+int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
+        char *r, *k;
+        int c;
+        bool space = false;
+        size_t left;
+        FILE *f;
+
+        assert(max_length > 0);
+        assert(line);
+
+        if (pid == 0)
+                f = fopen("/proc/self/cmdline", "re");
+        else {
+                char *p;
+                if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
+                        return -ENOMEM;
+
+                f = fopen(p, "re");
+                free(p);
+        }
+
+        if (!f)
+                return -errno;
+
+        r = new(char, max_length);
+        if (!r) {
+                fclose(f);
+                return -ENOMEM;
+        }
+
+        k = r;
+        left = max_length;
+        while ((c = getc(f)) != EOF) {
+
+                if (isprint(c)) {
+                        if (space) {
+                                if (left <= 4)
+                                        break;
+
+                                *(k++) = ' ';
+                                left--;
+                                space = false;
+                        }
+
+                        if (left <= 4)
+                                break;
+
+                        *(k++) = (char) c;
+                        left--;
+                }  else
+                        space = true;
+        }
+
+        if (left <= 4) {
+                size_t n = MIN(left-1, 3U);
+                memcpy(k, "...", n);
+                k[n] = 0;
+        } else
+                *k = 0;
+
+        fclose(f);
+
+        /* Kernel threads have no argv[] */
+        if (r[0] == 0) {
+                char *t;
+                int h;
+
+                free(r);
+
+                if (!comm_fallback)
+                        return -ENOENT;
+
+                h = get_process_comm(pid, &t);
+                if (h < 0)
+                        return h;
+
+                r = strjoin("[", t, "]", NULL);
+                free(t);
+
+                if (!r)
+                        return -ENOMEM;
+        }
+
+        *line = r;
+        return 0;
+}
+
+int is_kernel_thread(pid_t pid) {
+        char *p;
+        size_t count;
+        char c;
+        bool eof;
+        FILE *f;
+
+        if (pid == 0)
+                return 0;
+
+        if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
+                return -ENOMEM;
+
+        f = fopen(p, "re");
+        free(p);
+
+        if (!f)
+                return -errno;
+
+        count = fread(&c, 1, 1, f);
+        eof = feof(f);
+        fclose(f);
+
+        /* Kernel threads have an empty cmdline */
+
+        if (count <= 0)
+                return eof ? 1 : -errno;
+
+        return 0;
+}
+
+int get_process_exe(pid_t pid, char **name) {
+        int r;
+
+        assert(name);
+
+        if (pid == 0)
+                r = readlink_malloc("/proc/self/exe", name);
+        else {
+                char *p;
+                if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
+                        return -ENOMEM;
+
+                r = readlink_malloc(p, name);
+                free(p);
+        }
+
+        return r;
+}
+
+static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
+        char *p;
+        FILE *f;
+        int r;
+
+        assert(uid);
+
+        if (pid == 0)
+                return getuid();
+
+        if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
+                return -ENOMEM;
+
+        f = fopen(p, "re");
+        free(p);
+
+        if (!f)
+                return -errno;
+
+        while (!feof(f)) {
+                char line[LINE_MAX], *l;
+
+                if (!fgets(line, sizeof(line), f)) {
+                        if (feof(f))
+                                break;
+
+                        r = -errno;
+                        goto finish;
+                }
+
+                l = strstrip(line);
+
+                if (startswith(l, field)) {
+                        l += strlen(field);
+                        l += strspn(l, WHITESPACE);
+
+                        l[strcspn(l, WHITESPACE)] = 0;
+
+                        r = parse_uid(l, uid);
+                        goto finish;
+                }
+        }
+
+        r = -EIO;
+
+finish:
+        fclose(f);
+
+        return r;
+}
+
+int get_process_uid(pid_t pid, uid_t *uid) {
+        return get_process_id(pid, "Uid:", uid);
+}
+
+int get_process_gid(pid_t pid, gid_t *gid) {
+        return get_process_id(pid, "Gid:", gid);
+}
+
+char *strnappend(const char *s, const char *suffix, size_t b) {
+        size_t a;
+        char *r;
+
+        if (!s && !suffix)
+                return strdup("");
+
+        if (!s)
+                return strndup(suffix, b);
+
+        if (!suffix)
+                return strdup(s);
+
+        assert(s);
+        assert(suffix);
+
+        a = strlen(s);
+        if (b > ((size_t) -1) - a)
+                return NULL;
+
+        r = new(char, a+b+1);
+        if (!r)
+                return NULL;
+
+        memcpy(r, s, a);
+        memcpy(r+a, suffix, b);
+        r[a+b] = 0;
+
+        return r;
+}
+
+char *strappend(const char *s, const char *suffix) {
+        return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
+}
+
+int readlink_malloc(const char *p, char **r) {
+        size_t l = 100;
+
+        assert(p);
+        assert(r);
+
+        for (;;) {
+                char *c;
+                ssize_t n;
+
+                if (!(c = new(char, l)))
+                        return -ENOMEM;
+
+                if ((n = readlink(p, c, l-1)) < 0) {
+                        int ret = -errno;
+                        free(c);
+                        return ret;
+                }
+
+                if ((size_t) n < l-1) {
+                        c[n] = 0;
+                        *r = c;
+                        return 0;
+                }
+
+                free(c);
+                l *= 2;
+        }
+}
+
+int readlink_and_make_absolute(const char *p, char **r) {
+        char *target, *k;
+        int j;
+
+        assert(p);
+        assert(r);
+
+        if ((j = readlink_malloc(p, &target)) < 0)
+                return j;
+
+        k = file_in_same_dir(p, target);
+        free(target);
+
+        if (!k)
+                return -ENOMEM;
+
+        *r = k;
+        return 0;
+}
+
+int readlink_and_canonicalize(const char *p, char **r) {
+        char *t, *s;
+        int j;
+
+        assert(p);
+        assert(r);
+
+        j = readlink_and_make_absolute(p, &t);
+        if (j < 0)
+                return j;
+
+        s = canonicalize_file_name(t);
+        if (s) {
+                free(t);
+                *r = s;
+        } else
+                *r = t;
+
+        path_kill_slashes(*r);
+
+        return 0;
+}
+
+int reset_all_signal_handlers(void) {
+        int sig;
+
+        for (sig = 1; sig < _NSIG; sig++) {
+                struct sigaction sa;
+
+                if (sig == SIGKILL || sig == SIGSTOP)
+                        continue;
+
+                zero(sa);
+                sa.sa_handler = SIG_DFL;
+                sa.sa_flags = SA_RESTART;
+
+                /* On Linux the first two RT signals are reserved by
+                 * glibc, and sigaction() will return EINVAL for them. */
+                if ((sigaction(sig, &sa, NULL) < 0))
+                        if (errno != EINVAL)
+                                return -errno;
+        }
+
+        return 0;
+}
+
+char *strstrip(char *s) {
+        char *e;
+
+        /* Drops trailing whitespace. Modifies the string in
+         * place. Returns pointer to first non-space character */
+
+        s += strspn(s, WHITESPACE);
+
+        for (e = strchr(s, 0); e > s; e --)
+                if (!strchr(WHITESPACE, e[-1]))
+                        break;
+
+        *e = 0;
+
+        return s;
+}
+
+char *delete_chars(char *s, const char *bad) {
+        char *f, *t;
+
+        /* Drops all whitespace, regardless where in the string */
+
+        for (f = s, t = s; *f; f++) {
+                if (strchr(bad, *f))
+                        continue;
+
+                *(t++) = *f;
+        }
+
+        *t = 0;
+
+        return s;
+}
+
+bool in_charset(const char *s, const char* charset) {
+        const char *i;
+
+        assert(s);
+        assert(charset);
+
+        for (i = s; *i; i++)
+                if (!strchr(charset, *i))
+                        return false;
+
+        return true;
+}
+
+char *file_in_same_dir(const char *path, const char *filename) {
+        char *e, *r;
+        size_t k;
+
+        assert(path);
+        assert(filename);
+
+        /* This removes the last component of path and appends
+         * filename, unless the latter is absolute anyway or the
+         * former isn't */
+
+        if (path_is_absolute(filename))
+                return strdup(filename);
+
+        if (!(e = strrchr(path, '/')))
+                return strdup(filename);
+
+        k = strlen(filename);
+        if (!(r = new(char, e-path+1+k+1)))
+                return NULL;
+
+        memcpy(r, path, e-path+1);
+        memcpy(r+(e-path)+1, filename, k+1);
+
+        return r;
+}
+
+int rmdir_parents(const char *path, const char *stop) {
+        size_t l;
+        int r = 0;
+
+        assert(path);
+        assert(stop);
+
+        l = strlen(path);
+
+        /* Skip trailing slashes */
+        while (l > 0 && path[l-1] == '/')
+                l--;
+
+        while (l > 0) {
+                char *t;
+
+                /* Skip last component */
+                while (l > 0 && path[l-1] != '/')
+                        l--;
+
+                /* Skip trailing slashes */
+                while (l > 0 && path[l-1] == '/')
+                        l--;
+
+                if (l <= 0)
+                        break;
+
+                if (!(t = strndup(path, l)))
+                        return -ENOMEM;
+
+                if (path_startswith(stop, t)) {
+                        free(t);
+                        return 0;
+                }
+
+                r = rmdir(t);
+                free(t);
+
+                if (r < 0)
+                        if (errno != ENOENT)
+                                return -errno;
+        }
+
+        return 0;
+}
+
+
+char hexchar(int x) {
+        static const char table[16] = "0123456789abcdef";
+
+        return table[x & 15];
+}
+
+int unhexchar(char c) {
+
+        if (c >= '0' && c <= '9')
+                return c - '0';
+
+        if (c >= 'a' && c <= 'f')
+                return c - 'a' + 10;
+
+        if (c >= 'A' && c <= 'F')
+                return c - 'A' + 10;
+
+        return -1;
+}
+
+char octchar(int x) {
+        return '0' + (x & 7);
+}
+
+int unoctchar(char c) {
+
+        if (c >= '0' && c <= '7')
+                return c - '0';
+
+        return -1;
+}
+
+char decchar(int x) {
+        return '0' + (x % 10);
+}
+
+int undecchar(char c) {
+
+        if (c >= '0' && c <= '9')
+                return c - '0';
+
+        return -1;
+}
+
+char *cescape(const char *s) {
+        char *r, *t;
+        const char *f;
+
+        assert(s);
+
+        /* Does C style string escaping. */
+
+        r = new(char, strlen(s)*4 + 1);
+        if (!r)
+                return NULL;
+
+        for (f = s, t = r; *f; f++)
+
+                switch (*f) {
+
+                case '\a':
+                        *(t++) = '\\';
+                        *(t++) = 'a';
+                        break;
+                case '\b':
+                        *(t++) = '\\';
+                        *(t++) = 'b';
+                        break;
+                case '\f':
+                        *(t++) = '\\';
+                        *(t++) = 'f';
+                        break;
+                case '\n':
+                        *(t++) = '\\';
+                        *(t++) = 'n';
+                        break;
+                case '\r':
+                        *(t++) = '\\';
+                        *(t++) = 'r';
+                        break;
+                case '\t':
+                        *(t++) = '\\';
+                        *(t++) = 't';
+                        break;
+                case '\v':
+                        *(t++) = '\\';
+                        *(t++) = 'v';
+                        break;
+                case '\\':
+                        *(t++) = '\\';
+                        *(t++) = '\\';
+                        break;
+                case '"':
+                        *(t++) = '\\';
+                        *(t++) = '"';
+                        break;
+                case '\'':
+                        *(t++) = '\\';
+                        *(t++) = '\'';
+                        break;
+
+                default:
+                        /* For special chars we prefer octal over
+                         * hexadecimal encoding, simply because glib's
+                         * g_strescape() does the same */
+                        if ((*f < ' ') || (*f >= 127)) {
+                                *(t++) = '\\';
+                                *(t++) = octchar((unsigned char) *f >> 6);
+                                *(t++) = octchar((unsigned char) *f >> 3);
+                                *(t++) = octchar((unsigned char) *f);
+                        } else
+                                *(t++) = *f;
+                        break;
+                }
+
+        *t = 0;
+
+        return r;
+}
+
+char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
+        char *r, *t;
+        const char *f;
+        size_t pl;
+
+        assert(s);
+
+        /* Undoes C style string escaping, and optionally prefixes it. */
+
+        pl = prefix ? strlen(prefix) : 0;
+
+        r = new(char, pl+length+1);
+        if (!r)
+                return r;
+
+        if (prefix)
+                memcpy(r, prefix, pl);
+
+        for (f = s, t = r + pl; f < s + length; f++) {
+
+                if (*f != '\\') {
+                        *(t++) = *f;
+                        continue;
+                }
+
+                f++;
+
+                switch (*f) {
+
+                case 'a':
+                        *(t++) = '\a';
+                        break;
+                case 'b':
+                        *(t++) = '\b';
+                        break;
+                case 'f':
+                        *(t++) = '\f';
+                        break;
+                case 'n':
+                        *(t++) = '\n';
+                        break;
+                case 'r':
+                        *(t++) = '\r';
+                        break;
+                case 't':
+                        *(t++) = '\t';
+                        break;
+                case 'v':
+                        *(t++) = '\v';
+                        break;
+                case '\\':
+                        *(t++) = '\\';
+                        break;
+                case '"':
+                        *(t++) = '"';
+                        break;
+                case '\'':
+                        *(t++) = '\'';
+                        break;
+
+                case 's':
+                        /* This is an extension of the XDG syntax files */
+                        *(t++) = ' ';
+                        break;
+
+                case 'x': {
+                        /* hexadecimal encoding */
+                        int a, b;
+
+                        a = unhexchar(f[1]);
+                        b = unhexchar(f[2]);
+
+                        if (a < 0 || b < 0) {
+                                /* Invalid escape code, let's take it literal then */
+                                *(t++) = '\\';
+                                *(t++) = 'x';
+                        } else {
+                                *(t++) = (char) ((a << 4) | b);
+                                f += 2;
+                        }
+
+                        break;
+                }
+
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7': {
+                        /* octal encoding */
+                        int a, b, c;
+
+                        a = unoctchar(f[0]);
+                        b = unoctchar(f[1]);
+                        c = unoctchar(f[2]);
+
+                        if (a < 0 || b < 0 || c < 0) {
+                                /* Invalid escape code, let's take it literal then */
+                                *(t++) = '\\';
+                                *(t++) = f[0];
+                        } else {
+                                *(t++) = (char) ((a << 6) | (b << 3) | c);
+                                f += 2;
+                        }
+
+                        break;
+                }
+
+                case 0:
+                        /* premature end of string.*/
+                        *(t++) = '\\';
+                        goto finish;
+
+                default:
+                        /* Invalid escape code, let's take it literal then */
+                        *(t++) = '\\';
+                        *(t++) = *f;
+                        break;
+                }
+        }
+
+finish:
+        *t = 0;
+        return r;
+}
+
+char *cunescape_length(const char *s, size_t length) {
+        return cunescape_length_with_prefix(s, length, NULL);
+}
+
+char *cunescape(const char *s) {
+        assert(s);
+
+        return cunescape_length(s, strlen(s));
+}
+
+char *xescape(const char *s, const char *bad) {
+        char *r, *t;
+        const char *f;
+
+        /* Escapes all chars in bad, in addition to \ and all special
+         * chars, in \xFF style escaping. May be reversed with
+         * cunescape. */
+
+        r = new(char, strlen(s) * 4 + 1);
+        if (!r)
+                return NULL;
+
+        for (f = s, t = r; *f; f++) {
+
+                if ((*f < ' ') || (*f >= 127) ||
+                    (*f == '\\') || strchr(bad, *f)) {
+                        *(t++) = '\\';
+                        *(t++) = 'x';
+                        *(t++) = hexchar(*f >> 4);
+                        *(t++) = hexchar(*f);
+                } else
+                        *(t++) = *f;
+        }
+
+        *t = 0;
+
+        return r;
+}
+
+char *bus_path_escape(const char *s) {
+        char *r, *t;
+        const char *f;
+
+        assert(s);
+
+        /* Escapes all chars that D-Bus' object path cannot deal
+         * with. Can be reverse with bus_path_unescape() */
+
+        if (!(r = new(char, strlen(s)*3+1)))
+                return NULL;
+
+        for (f = s, t = r; *f; f++) {
+
+                if (!(*f >= 'A' && *f <= 'Z') &&
+                    !(*f >= 'a' && *f <= 'z') &&
+                    !(*f >= '0' && *f <= '9')) {
+                        *(t++) = '_';
+                        *(t++) = hexchar(*f >> 4);
+                        *(t++) = hexchar(*f);
+                } else
+                        *(t++) = *f;
+        }
+
+        *t = 0;
+
+        return r;
+}
+
+char *bus_path_unescape(const char *f) {
+        char *r, *t;
+
+        assert(f);
+
+        if (!(r = strdup(f)))
+                return NULL;
+
+        for (t = r; *f; f++) {
+
+                if (*f == '_') {
+                        int a, b;
+
+                        if ((a = unhexchar(f[1])) < 0 ||
+                            (b = unhexchar(f[2])) < 0) {
+                                /* Invalid escape code, let's take it literal then */
+                                *(t++) = '_';
+                        } else {
+                                *(t++) = (char) ((a << 4) | b);
+                                f += 2;
+                        }
+                } else
+                        *(t++) = *f;
+        }
+
+        *t = 0;
+
+        return r;
+}
+
+char *ascii_strlower(char *t) {
+        char *p;
+
+        assert(t);
+
+        for (p = t; *p; p++)
+                if (*p >= 'A' && *p <= 'Z')
+                        *p = *p - 'A' + 'a';
+
+        return t;
+}
+
+static bool ignore_file_allow_backup(const char *filename) {
+        assert(filename);
+
+        return
+                filename[0] == '.' ||
+                streq(filename, "lost+found") ||
+                streq(filename, "aquota.user") ||
+                streq(filename, "aquota.group") ||
+                endswith(filename, ".rpmnew") ||
+                endswith(filename, ".rpmsave") ||
+                endswith(filename, ".rpmorig") ||
+                endswith(filename, ".dpkg-old") ||
+                endswith(filename, ".dpkg-new") ||
+                endswith(filename, ".swp");
+}
+
+bool ignore_file(const char *filename) {
+        assert(filename);
+
+        if (endswith(filename, "~"))
+                return false;
+
+        return ignore_file_allow_backup(filename);
+}
+
+int fd_nonblock(int fd, bool nonblock) {
+        int flags;
+
+        assert(fd >= 0);
+
+        if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
+                return -errno;
+
+        if (nonblock)
+                flags |= O_NONBLOCK;
+        else
+                flags &= ~O_NONBLOCK;
+
+        if (fcntl(fd, F_SETFL, flags) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int fd_cloexec(int fd, bool cloexec) {
+        int flags;
+
+        assert(fd >= 0);
+
+        if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
+                return -errno;
+
+        if (cloexec)
+                flags |= FD_CLOEXEC;
+        else
+                flags &= ~FD_CLOEXEC;
+
+        if (fcntl(fd, F_SETFD, flags) < 0)
+                return -errno;
+
+        return 0;
+}
+
+static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
+        unsigned i;
+
+        assert(n_fdset == 0 || fdset);
+
+        for (i = 0; i < n_fdset; i++)
+                if (fdset[i] == fd)
+                        return true;
+
+        return false;
+}
+
+int close_all_fds(const int except[], unsigned n_except) {
+        DIR *d;
+        struct dirent *de;
+        int r = 0;
+
+        assert(n_except == 0 || except);
+
+        d = opendir("/proc/self/fd");
+        if (!d) {
+                int fd;
+                struct rlimit rl;
+
+                /* When /proc isn't available (for example in chroots)
+                 * the fallback is brute forcing through the fd
+                 * table */
+
+                assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
+                for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
+
+                        if (fd_in_set(fd, except, n_except))
+                                continue;
+
+                        if (close_nointr(fd) < 0)
+                                if (errno != EBADF && r == 0)
+                                        r = -errno;
+                }
+
+                return r;
+        }
+
+        while ((de = readdir(d))) {
+                int fd = -1;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                if (safe_atoi(de->d_name, &fd) < 0)
+                        /* Let's better ignore this, just in case */
+                        continue;
+
+                if (fd < 3)
+                        continue;
+
+                if (fd == dirfd(d))
+                        continue;
+
+                if (fd_in_set(fd, except, n_except))
+                        continue;
+
+                if (close_nointr(fd) < 0) {
+                        /* Valgrind has its own FD and doesn't want to have it closed */
+                        if (errno != EBADF && r == 0)
+                                r = -errno;
+                }
+        }
+
+        closedir(d);
+        return r;
+}
+
+bool chars_intersect(const char *a, const char *b) {
+        const char *p;
+
+        /* Returns true if any of the chars in a are in b. */
+        for (p = a; *p; p++)
+                if (strchr(b, *p))
+                        return true;
+
+        return false;
+}
+
+bool fstype_is_network(const char *fstype) {
+        static const char table[] =
+                "cifs\0"
+                "smbfs\0"
+                "ncpfs\0"
+                "nfs\0"
+                "nfs4\0"
+                "gfs\0"
+                "gfs2\0";
+
+        return nulstr_contains(table, fstype);
+}
+
+int chvt(int vt) {
+        _cleanup_close_ int fd;
+
+        fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        if (vt < 0) {
+                int tiocl[2] = {
+                        TIOCL_GETKMSGREDIRECT,
+                        0
+                };
+
+                if (ioctl(fd, TIOCLINUX, tiocl) < 0)
+                        return -errno;
+
+                vt = tiocl[0] <= 0 ? 1 : tiocl[0];
+        }
+
+        if (ioctl(fd, VT_ACTIVATE, vt) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
+        struct termios old_termios, new_termios;
+        char c;
+        char line[LINE_MAX];
+
+        assert(f);
+        assert(ret);
+
+        if (tcgetattr(fileno(f), &old_termios) >= 0) {
+                new_termios = old_termios;
+
+                new_termios.c_lflag &= ~ICANON;
+                new_termios.c_cc[VMIN] = 1;
+                new_termios.c_cc[VTIME] = 0;
+
+                if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
+                        size_t k;
+
+                        if (t != (usec_t) -1) {
+                                if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
+                                        tcsetattr(fileno(f), TCSADRAIN, &old_termios);
+                                        return -ETIMEDOUT;
+                                }
+                        }
+
+                        k = fread(&c, 1, 1, f);
+
+                        tcsetattr(fileno(f), TCSADRAIN, &old_termios);
+
+                        if (k <= 0)
+                                return -EIO;
+
+                        if (need_nl)
+                                *need_nl = c != '\n';
+
+                        *ret = c;
+                        return 0;
+                }
+        }
+
+        if (t != (usec_t) -1)
+                if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
+                        return -ETIMEDOUT;
+
+        if (!fgets(line, sizeof(line), f))
+                return -EIO;
+
+        truncate_nl(line);
+
+        if (strlen(line) != 1)
+                return -EBADMSG;
+
+        if (need_nl)
+                *need_nl = false;
+
+        *ret = line[0];
+        return 0;
+}
+
+int ask(char *ret, const char *replies, const char *text, ...) {
+
+        assert(ret);
+        assert(replies);
+        assert(text);
+
+        for (;;) {
+                va_list ap;
+                char c;
+                int r;
+                bool need_nl = true;
+
+                if (on_tty())
+                        fputs(ANSI_HIGHLIGHT_ON, stdout);
+
+                va_start(ap, text);
+                vprintf(text, ap);
+                va_end(ap);
+
+                if (on_tty())
+                        fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
+                fflush(stdout);
+
+                r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
+                if (r < 0) {
+
+                        if (r == -EBADMSG) {
+                                puts("Bad input, please try again.");
+                                continue;
+                        }
+
+                        putchar('\n');
+                        return r;
+                }
+
+                if (need_nl)
+                        putchar('\n');
+
+                if (strchr(replies, c)) {
+                        *ret = c;
+                        return 0;
+                }
+
+                puts("Read unexpected character, please try again.");
+        }
+}
+
+int reset_terminal_fd(int fd, bool switch_to_text) {
+        struct termios termios;
+        int r = 0;
+
+        /* Set terminal to some sane defaults */
+
+        assert(fd >= 0);
+
+        /* We leave locked terminal attributes untouched, so that
+         * Plymouth may set whatever it wants to set, and we don't
+         * interfere with that. */
+
+        /* Disable exclusive mode, just in case */
+        ioctl(fd, TIOCNXCL);
+
+        /* Switch to text mode */
+        if (switch_to_text)
+                ioctl(fd, KDSETMODE, KD_TEXT);
+
+        /* Enable console unicode mode */
+        ioctl(fd, KDSKBMODE, K_UNICODE);
+
+        if (tcgetattr(fd, &termios) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        /* We only reset the stuff that matters to the software. How
+         * hardware is set up we don't touch assuming that somebody
+         * else will do that for us */
+
+        termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
+        termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
+        termios.c_oflag |= ONLCR;
+        termios.c_cflag |= CREAD;
+        termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
+
+        termios.c_cc[VINTR]    =   03;  /* ^C */
+        termios.c_cc[VQUIT]    =  034;  /* ^\ */
+        termios.c_cc[VERASE]   = 0177;
+        termios.c_cc[VKILL]    =  025;  /* ^X */
+        termios.c_cc[VEOF]     =   04;  /* ^D */
+        termios.c_cc[VSTART]   =  021;  /* ^Q */
+        termios.c_cc[VSTOP]    =  023;  /* ^S */
+        termios.c_cc[VSUSP]    =  032;  /* ^Z */
+        termios.c_cc[VLNEXT]   =  026;  /* ^V */
+        termios.c_cc[VWERASE]  =  027;  /* ^W */
+        termios.c_cc[VREPRINT] =  022;  /* ^R */
+        termios.c_cc[VEOL]     =    0;
+        termios.c_cc[VEOL2]    =    0;
+
+        termios.c_cc[VTIME]  = 0;
+        termios.c_cc[VMIN]   = 1;
+
+        if (tcsetattr(fd, TCSANOW, &termios) < 0)
+                r = -errno;
+
+finish:
+        /* Just in case, flush all crap out */
+        tcflush(fd, TCIOFLUSH);
+
+        return r;
+}
+
+int reset_terminal(const char *name) {
+        int fd, r;
+
+        fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        r = reset_terminal_fd(fd, true);
+        close_nointr_nofail(fd);
+
+        return r;
+}
+
+int open_terminal(const char *name, int mode) {
+        int fd, r;
+        unsigned c = 0;
+
+        /*
+         * If a TTY is in the process of being closed opening it might
+         * cause EIO. This is horribly awful, but unlikely to be
+         * changed in the kernel. Hence we work around this problem by
+         * retrying a couple of times.
+         *
+         * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
+         */
+
+        for (;;) {
+                fd = open(name, mode);
+                if (fd >= 0)
+                        break;
+
+                if (errno != EIO)
+                        return -errno;
+
+                /* Max 1s in total */
+                if (c >= 20)
+                        return -errno;
+
+                usleep(50 * USEC_PER_MSEC);
+                c++;
+        }
+
+        if (fd < 0)
+                return -errno;
+
+        r = isatty(fd);
+        if (r < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        if (!r) {
+                close_nointr_nofail(fd);
+                return -ENOTTY;
+        }
+
+        return fd;
+}
+
+int flush_fd(int fd) {
+        struct pollfd pollfd;
+
+        zero(pollfd);
+        pollfd.fd = fd;
+        pollfd.events = POLLIN;
+
+        for (;;) {
+                char buf[LINE_MAX];
+                ssize_t l;
+                int r;
+
+                if ((r = poll(&pollfd, 1, 0)) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        return -errno;
+                }
+
+                if (r == 0)
+                        return 0;
+
+                if ((l = read(fd, buf, sizeof(buf))) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        if (errno == EAGAIN)
+                                return 0;
+
+                        return -errno;
+                }
+
+                if (l <= 0)
+                        return 0;
+        }
+}
+
+int acquire_terminal(
+                const char *name,
+                bool fail,
+                bool force,
+                bool ignore_tiocstty_eperm,
+                usec_t timeout) {
+
+        int fd = -1, notify = -1, r = 0, wd = -1;
+        usec_t ts = 0;
+        struct sigaction sa_old, sa_new;
+
+        assert(name);
+
+        /* We use inotify to be notified when the tty is closed. We
+         * create the watch before checking if we can actually acquire
+         * it, so that we don't lose any event.
+         *
+         * Note: strictly speaking this actually watches for the
+         * device being closed, it does *not* really watch whether a
+         * tty loses its controlling process. However, unless some
+         * rogue process uses TIOCNOTTY on /dev/tty *after* closing
+         * its tty otherwise this will not become a problem. As long
+         * as the administrator makes sure not configure any service
+         * on the same tty as an untrusted user this should not be a
+         * problem. (Which he probably should not do anyway.) */
+
+        if (timeout != (usec_t) -1)
+                ts = now(CLOCK_MONOTONIC);
+
+        if (!fail && !force) {
+                notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
+                if (notify < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+
+                wd = inotify_add_watch(notify, name, IN_CLOSE);
+                if (wd < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+        }
+
+        for (;;) {
+                if (notify >= 0) {
+                        r = flush_fd(notify);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                /* We pass here O_NOCTTY only so that we can check the return
+                 * value TIOCSCTTY and have a reliable way to figure out if we
+                 * successfully became the controlling process of the tty */
+                fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+                if (fd < 0)
+                        return fd;
+
+                /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
+                 * if we already own the tty. */
+                zero(sa_new);
+                sa_new.sa_handler = SIG_IGN;
+                sa_new.sa_flags = SA_RESTART;
+                assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
+
+                /* First, try to get the tty */
+                if (ioctl(fd, TIOCSCTTY, force) < 0)
+                        r = -errno;
+
+                assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
+
+                /* Sometimes it makes sense to ignore TIOCSCTTY
+                 * returning EPERM, i.e. when very likely we already
+                 * are have this controlling terminal. */
+                if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
+                        r = 0;
+
+                if (r < 0 && (force || fail || r != -EPERM)) {
+                        goto fail;
+                }
+
+                if (r >= 0)
+                        break;
+
+                assert(!fail);
+                assert(!force);
+                assert(notify >= 0);
+
+                for (;;) {
+                        uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
+                        ssize_t l;
+                        struct inotify_event *e;
+
+                        if (timeout != (usec_t) -1) {
+                                usec_t n;
+
+                                n = now(CLOCK_MONOTONIC);
+                                if (ts + timeout < n) {
+                                        r = -ETIMEDOUT;
+                                        goto fail;
+                                }
+
+                                r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
+                                if (r < 0)
+                                        goto fail;
+
+                                if (r == 0) {
+                                        r = -ETIMEDOUT;
+                                        goto fail;
+                                }
+                        }
+
+                        l = read(notify, inotify_buffer, sizeof(inotify_buffer));
+                        if (l < 0) {
+
+                                if (errno == EINTR || errno == EAGAIN)
+                                        continue;
+
+                                r = -errno;
+                                goto fail;
+                        }
+
+                        e = (struct inotify_event*) inotify_buffer;
+
+                        while (l > 0) {
+                                size_t step;
+
+                                if (e->wd != wd || !(e->mask & IN_CLOSE)) {
+                                        r = -EIO;
+                                        goto fail;
+                                }
+
+                                step = sizeof(struct inotify_event) + e->len;
+                                assert(step <= (size_t) l);
+
+                                e = (struct inotify_event*) ((uint8_t*) e + step);
+                                l -= step;
+                        }
+
+                        break;
+                }
+
+                /* We close the tty fd here since if the old session
+                 * ended our handle will be dead. It's important that
+                 * we do this after sleeping, so that we don't enter
+                 * an endless loop. */
+                close_nointr_nofail(fd);
+        }
+
+        if (notify >= 0)
+                close_nointr_nofail(notify);
+
+        r = reset_terminal_fd(fd, true);
+        if (r < 0)
+                log_warning("Failed to reset terminal: %s", strerror(-r));
+
+        return fd;
+
+fail:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        if (notify >= 0)
+                close_nointr_nofail(notify);
+
+        return r;
+}
+
+int release_terminal(void) {
+        int r = 0, fd;
+        struct sigaction sa_old, sa_new;
+
+        if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
+                return -errno;
+
+        /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
+         * by our own TIOCNOTTY */
+
+        zero(sa_new);
+        sa_new.sa_handler = SIG_IGN;
+        sa_new.sa_flags = SA_RESTART;
+        assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
+
+        if (ioctl(fd, TIOCNOTTY) < 0)
+                r = -errno;
+
+        assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
+
+        close_nointr_nofail(fd);
+        return r;
+}
+
+int sigaction_many(const struct sigaction *sa, ...) {
+        va_list ap;
+        int r = 0, sig;
+
+        va_start(ap, sa);
+        while ((sig = va_arg(ap, int)) > 0)
+                if (sigaction(sig, sa, NULL) < 0)
+                        r = -errno;
+        va_end(ap);
+
+        return r;
+}
+
+int ignore_signals(int sig, ...) {
+        struct sigaction sa;
+        va_list ap;
+        int r = 0;
+
+        zero(sa);
+        sa.sa_handler = SIG_IGN;
+        sa.sa_flags = SA_RESTART;
+
+        if (sigaction(sig, &sa, NULL) < 0)
+                r = -errno;
+
+        va_start(ap, sig);
+        while ((sig = va_arg(ap, int)) > 0)
+                if (sigaction(sig, &sa, NULL) < 0)
+                        r = -errno;
+        va_end(ap);
+
+        return r;
+}
+
+int default_signals(int sig, ...) {
+        struct sigaction sa;
+        va_list ap;
+        int r = 0;
+
+        zero(sa);
+        sa.sa_handler = SIG_DFL;
+        sa.sa_flags = SA_RESTART;
+
+        if (sigaction(sig, &sa, NULL) < 0)
+                r = -errno;
+
+        va_start(ap, sig);
+        while ((sig = va_arg(ap, int)) > 0)
+                if (sigaction(sig, &sa, NULL) < 0)
+                        r = -errno;
+        va_end(ap);
+
+        return r;
+}
+
+int close_pipe(int p[]) {
+        int a = 0, b = 0;
+
+        assert(p);
+
+        if (p[0] >= 0) {
+                a = close_nointr(p[0]);
+                p[0] = -1;
+        }
+
+        if (p[1] >= 0) {
+                b = close_nointr(p[1]);
+                p[1] = -1;
+        }
+
+        return a < 0 ? a : b;
+}
+
+ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
+        uint8_t *p;
+        ssize_t n = 0;
+
+        assert(fd >= 0);
+        assert(buf);
+
+        p = buf;
+
+        while (nbytes > 0) {
+                ssize_t k;
+
+                if ((k = read(fd, p, nbytes)) <= 0) {
+
+                        if (k < 0 && errno == EINTR)
+                                continue;
+
+                        if (k < 0 && errno == EAGAIN && do_poll) {
+                                struct pollfd pollfd;
+
+                                zero(pollfd);
+                                pollfd.fd = fd;
+                                pollfd.events = POLLIN;
+
+                                if (poll(&pollfd, 1, -1) < 0) {
+                                        if (errno == EINTR)
+                                                continue;
+
+                                        return n > 0 ? n : -errno;
+                                }
+
+                                if (pollfd.revents != POLLIN)
+                                        return n > 0 ? n : -EIO;
+
+                                continue;
+                        }
+
+                        return n > 0 ? n : (k < 0 ? -errno : 0);
+                }
+
+                p += k;
+                nbytes -= k;
+                n += k;
+        }
+
+        return n;
+}
+
+ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
+        const uint8_t *p;
+        ssize_t n = 0;
+
+        assert(fd >= 0);
+        assert(buf);
+
+        p = buf;
+
+        while (nbytes > 0) {
+                ssize_t k;
+
+                k = write(fd, p, nbytes);
+                if (k <= 0) {
+
+                        if (k < 0 && errno == EINTR)
+                                continue;
+
+                        if (k < 0 && errno == EAGAIN && do_poll) {
+                                struct pollfd pollfd;
+
+                                zero(pollfd);
+                                pollfd.fd = fd;
+                                pollfd.events = POLLOUT;
+
+                                if (poll(&pollfd, 1, -1) < 0) {
+                                        if (errno == EINTR)
+                                                continue;
+
+                                        return n > 0 ? n : -errno;
+                                }
+
+                                if (pollfd.revents != POLLOUT)
+                                        return n > 0 ? n : -EIO;
+
+                                continue;
+                        }
+
+                        return n > 0 ? n : (k < 0 ? -errno : 0);
+                }
+
+                p += k;
+                nbytes -= k;
+                n += k;
+        }
+
+        return n;
+}
+
+int parse_bytes(const char *t, off_t *bytes) {
+        static const struct {
+                const char *suffix;
+                off_t factor;
+        } table[] = {
+                { "B", 1 },
+                { "K", 1024ULL },
+                { "M", 1024ULL*1024ULL },
+                { "G", 1024ULL*1024ULL*1024ULL },
+                { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
+                { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
+                { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
+                { "", 1 },
+        };
+
+        const char *p;
+        off_t r = 0;
+
+        assert(t);
+        assert(bytes);
+
+        p = t;
+        do {
+                long long l;
+                char *e;
+                unsigned i;
+
+                errno = 0;
+                l = strtoll(p, &e, 10);
+
+                if (errno != 0)
+                        return -errno;
+
+                if (l < 0)
+                        return -ERANGE;
+
+                if (e == p)
+                        return -EINVAL;
+
+                e += strspn(e, WHITESPACE);
+
+                for (i = 0; i < ELEMENTSOF(table); i++)
+                        if (startswith(e, table[i].suffix)) {
+                                r += (off_t) l * table[i].factor;
+                                p = e + strlen(table[i].suffix);
+                                break;
+                        }
+
+                if (i >= ELEMENTSOF(table))
+                        return -EINVAL;
+
+        } while (*p != 0);
+
+        *bytes = r;
+
+        return 0;
+}
+
+int make_stdio(int fd) {
+        int r, s, t;
+
+        assert(fd >= 0);
+
+        r = dup3(fd, STDIN_FILENO, 0);
+        s = dup3(fd, STDOUT_FILENO, 0);
+        t = dup3(fd, STDERR_FILENO, 0);
+
+        if (fd >= 3)
+                close_nointr_nofail(fd);
+
+        if (r < 0 || s < 0 || t < 0)
+                return -errno;
+
+        /* We rely here that the new fd has O_CLOEXEC not set */
+
+        return 0;
+}
+
+int make_null_stdio(void) {
+        int null_fd;
+
+        null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
+        if (null_fd < 0)
+                return -errno;
+
+        return make_stdio(null_fd);
+}
+
+bool is_device_path(const char *path) {
+
+        /* Returns true on paths that refer to a device, either in
+         * sysfs or in /dev */
+
+        return
+                path_startswith(path, "/dev/") ||
+                path_startswith(path, "/sys/");
+}
+
+int dir_is_empty(const char *path) {
+        _cleanup_closedir_ DIR *d;
+        int r;
+
+        d = opendir(path);
+        if (!d)
+                return -errno;
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+
+                r = readdir_r(d, &buf.de, &de);
+                if (r > 0)
+                        return -r;
+
+                if (!de)
+                        return 1;
+
+                if (!ignore_file(de->d_name))
+                        return 0;
+        }
+}
+
+unsigned long long random_ull(void) {
+        _cleanup_close_ int fd;
+        uint64_t ull;
+        ssize_t r;
+
+        fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                goto fallback;
+
+        r = loop_read(fd, &ull, sizeof(ull), true);
+        if (r != sizeof(ull))
+                goto fallback;
+
+        return ull;
+
+fallback:
+        return random() * RAND_MAX + random();
+}
+
+void rename_process(const char name[8]) {
+        assert(name);
+
+        /* This is a like a poor man's setproctitle(). It changes the
+         * comm field, argv[0], and also the glibc's internally used
+         * name of the process. For the first one a limit of 16 chars
+         * applies, to the second one usually one of 10 (i.e. length
+         * of "/sbin/init"), to the third one one of 7 (i.e. length of
+         * "systemd"). If you pass a longer string it will be
+         * truncated */
+
+        prctl(PR_SET_NAME, name);
+
+        if (program_invocation_name)
+                strncpy(program_invocation_name, name, strlen(program_invocation_name));
+
+        if (saved_argc > 0) {
+                int i;
+
+                if (saved_argv[0])
+                        strncpy(saved_argv[0], name, strlen(saved_argv[0]));
+
+                for (i = 1; i < saved_argc; i++) {
+                        if (!saved_argv[i])
+                                break;
+
+                        memset(saved_argv[i], 0, strlen(saved_argv[i]));
+                }
+        }
+}
+
+void sigset_add_many(sigset_t *ss, ...) {
+        va_list ap;
+        int sig;
+
+        assert(ss);
+
+        va_start(ap, ss);
+        while ((sig = va_arg(ap, int)) > 0)
+                assert_se(sigaddset(ss, sig) == 0);
+        va_end(ap);
+}
+
+char* gethostname_malloc(void) {
+        struct utsname u;
+
+        assert_se(uname(&u) >= 0);
+
+        if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
+                return strdup(u.nodename);
+
+        return strdup(u.sysname);
+}
+
+bool hostname_is_set(void) {
+        struct utsname u;
+
+        assert_se(uname(&u) >= 0);
+
+        return !isempty(u.nodename) && !streq(u.nodename, "(none)");
+}
+
+static char *lookup_uid(uid_t uid) {
+        long bufsize;
+        char *name;
+        _cleanup_free_ char *buf = NULL;
+        struct passwd pwbuf, *pw = NULL;
+
+        /* Shortcut things to avoid NSS lookups */
+        if (uid == 0)
+                return strdup("root");
+
+        bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+        if (bufsize <= 0)
+                bufsize = 4096;
+
+        buf = malloc(bufsize);
+        if (!buf)
+                return NULL;
+
+        if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
+                return strdup(pw->pw_name);
+
+        if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
+                return NULL;
+
+        return name;
+}
+
+char* getlogname_malloc(void) {
+        uid_t uid;
+        struct stat st;
+
+        if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
+                uid = st.st_uid;
+        else
+                uid = getuid();
+
+        return lookup_uid(uid);
+}
+
+char *getusername_malloc(void) {
+        const char *e;
+
+        e = getenv("USER");
+        if (e)
+                return strdup(e);
+
+        return lookup_uid(getuid());
+}
+
+int getttyname_malloc(int fd, char **r) {
+        char path[PATH_MAX], *c;
+        int k;
+
+        assert(r);
+
+        k = ttyname_r(fd, path, sizeof(path));
+        if (k != 0)
+                return -k;
+
+        char_array_0(path);
+
+        c = strdup(startswith(path, "/dev/") ? path + 5 : path);
+        if (!c)
+                return -ENOMEM;
+
+        *r = c;
+        return 0;
+}
+
+int getttyname_harder(int fd, char **r) {
+        int k;
+        char *s;
+
+        k = getttyname_malloc(fd, &s);
+        if (k < 0)
+                return k;
+
+        if (streq(s, "tty")) {
+                free(s);
+                return get_ctty(0, NULL, r);
+        }
+
+        *r = s;
+        return 0;
+}
+
+int get_ctty_devnr(pid_t pid, dev_t *d) {
+        int k;
+        char line[LINE_MAX], *p, *fn;
+        unsigned long ttynr;
+        FILE *f;
+
+        if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
+                return -ENOMEM;
+
+        f = fopen(fn, "re");
+        free(fn);
+        if (!f)
+                return -errno;
+
+        if (!fgets(line, sizeof(line), f)) {
+                k = feof(f) ? -EIO : -errno;
+                fclose(f);
+                return k;
+        }
+
+        fclose(f);
+
+        p = strrchr(line, ')');
+        if (!p)
+                return -EIO;
+
+        p++;
+
+        if (sscanf(p, " "
+                   "%*c "  /* state */
+                   "%*d "  /* ppid */
+                   "%*d "  /* pgrp */
+                   "%*d "  /* session */
+                   "%lu ", /* ttynr */
+                   &ttynr) != 1)
+                return -EIO;
+
+        if (major(ttynr) == 0 && minor(ttynr) == 0)
+                return -ENOENT;
+
+        *d = (dev_t) ttynr;
+        return 0;
+}
+
+int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
+        int k;
+        char fn[PATH_MAX], *s, *b, *p;
+        dev_t devnr;
+
+        assert(r);
+
+        k = get_ctty_devnr(pid, &devnr);
+        if (k < 0)
+                return k;
+
+        snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
+        char_array_0(fn);
+
+        k = readlink_malloc(fn, &s);
+        if (k < 0) {
+
+                if (k != -ENOENT)
+                        return k;
+
+                /* This is an ugly hack */
+                if (major(devnr) == 136) {
+                        if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
+                                return -ENOMEM;
+
+                        *r = b;
+                        if (_devnr)
+                                *_devnr = devnr;
+
+                        return 0;
+                }
+
+                /* Probably something like the ptys which have no
+                 * symlink in /dev/char. Let's return something
+                 * vaguely useful. */
+
+                b = strdup(fn + 5);
+                if (!b)
+                        return -ENOMEM;
+
+                *r = b;
+                if (_devnr)
+                        *_devnr = devnr;
+
+                return 0;
+        }
+
+        if (startswith(s, "/dev/"))
+                p = s + 5;
+        else if (startswith(s, "../"))
+                p = s + 3;
+        else
+                p = s;
+
+        b = strdup(p);
+        free(s);
+
+        if (!b)
+                return -ENOMEM;
+
+        *r = b;
+        if (_devnr)
+                *_devnr = devnr;
+
+        return 0;
+}
+
+int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
+        DIR *d;
+        int ret = 0;
+
+        assert(fd >= 0);
+
+        /* This returns the first error we run into, but nevertheless
+         * tries to go on. This closes the passed fd. */
+
+        d = fdopendir(fd);
+        if (!d) {
+                close_nointr_nofail(fd);
+
+                return errno == ENOENT ? 0 : -errno;
+        }
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                bool is_dir, keep_around;
+                struct stat st;
+                int r;
+
+                r = readdir_r(d, &buf.de, &de);
+                if (r != 0 && ret == 0) {
+                        ret = -r;
+                        break;
+                }
+
+                if (!de)
+                        break;
+
+                if (streq(de->d_name, ".") || streq(de->d_name, ".."))
+                        continue;
+
+                if (de->d_type == DT_UNKNOWN ||
+                    honour_sticky ||
+                    (de->d_type == DT_DIR && root_dev)) {
+                        if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
+                                if (ret == 0 && errno != ENOENT)
+                                        ret = -errno;
+                                continue;
+                        }
+
+                        is_dir = S_ISDIR(st.st_mode);
+                        keep_around =
+                                honour_sticky &&
+                                (st.st_uid == 0 || st.st_uid == getuid()) &&
+                                (st.st_mode & S_ISVTX);
+                } else {
+                        is_dir = de->d_type == DT_DIR;
+                        keep_around = false;
+                }
+
+                if (is_dir) {
+                        int subdir_fd;
+
+                        /* if root_dev is set, remove subdirectories only, if device is same as dir */
+                        if (root_dev && st.st_dev != root_dev->st_dev)
+                                continue;
+
+                        subdir_fd = openat(fd, de->d_name,
+                                           O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+                        if (subdir_fd < 0) {
+                                if (ret == 0 && errno != ENOENT)
+                                        ret = -errno;
+                                continue;
+                        }
+
+                        r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
+                        if (r < 0 && ret == 0)
+                                ret = r;
+
+                        if (!keep_around)
+                                if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
+                                        if (ret == 0 && errno != ENOENT)
+                                                ret = -errno;
+                                }
+
+                } else if (!only_dirs && !keep_around) {
+
+                        if (unlinkat(fd, de->d_name, 0) < 0) {
+                                if (ret == 0 && errno != ENOENT)
+                                        ret = -errno;
+                        }
+                }
+        }
+
+        closedir(d);
+
+        return ret;
+}
+
+static int is_temporary_fs(struct statfs *s) {
+        assert(s);
+        return s->f_type == TMPFS_MAGIC ||
+                (long)s->f_type == (long)RAMFS_MAGIC;
+}
+
+int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
+        struct statfs s;
+
+        assert(fd >= 0);
+
+        if (fstatfs(fd, &s) < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        /* We refuse to clean disk file systems with this call. This
+         * is extra paranoia just to be sure we never ever remove
+         * non-state data */
+        if (!is_temporary_fs(&s)) {
+                log_error("Attempted to remove disk file system, and we can't allow that.");
+                close_nointr_nofail(fd);
+                return -EPERM;
+        }
+
+        return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
+}
+
+static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
+        int fd, r;
+        struct statfs s;
+
+        assert(path);
+
+        /* We refuse to clean the root file system with this
+         * call. This is extra paranoia to never cause a really
+         * seriously broken system. */
+        if (path_equal(path, "/")) {
+                log_error("Attempted to remove entire root file system, and we can't allow that.");
+                return -EPERM;
+        }
+
+        fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+        if (fd < 0) {
+
+                if (errno != ENOTDIR)
+                        return -errno;
+
+                if (!dangerous) {
+                        if (statfs(path, &s) < 0)
+                                return -errno;
+
+                        if (!is_temporary_fs(&s)) {
+                                log_error("Attempted to remove disk file system, and we can't allow that.");
+                                return -EPERM;
+                        }
+                }
+
+                if (delete_root && !only_dirs)
+                        if (unlink(path) < 0 && errno != ENOENT)
+                                return -errno;
+
+                return 0;
+        }
+
+        if (!dangerous) {
+                if (fstatfs(fd, &s) < 0) {
+                        close_nointr_nofail(fd);
+                        return -errno;
+                }
+
+                if (!is_temporary_fs(&s)) {
+                        log_error("Attempted to remove disk file system, and we can't allow that.");
+                        close_nointr_nofail(fd);
+                        return -EPERM;
+                }
+        }
+
+        r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
+        if (delete_root) {
+
+                if (honour_sticky && file_is_priv_sticky(path) > 0)
+                        return r;
+
+                if (rmdir(path) < 0 && errno != ENOENT) {
+                        if (r == 0)
+                                r = -errno;
+                }
+        }
+
+        return r;
+}
+
+int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
+        return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
+}
+
+int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
+        return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
+}
+
+int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
+        assert(path);
+
+        /* Under the assumption that we are running privileged we
+         * first change the access mode and only then hand out
+         * ownership to avoid a window where access is too open. */
+
+        if (mode != (mode_t) -1)
+                if (chmod(path, mode) < 0)
+                        return -errno;
+
+        if (uid != (uid_t) -1 || gid != (gid_t) -1)
+                if (chown(path, uid, gid) < 0)
+                        return -errno;
+
+        return 0;
+}
+
+int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
+        assert(fd >= 0);
+
+        /* Under the assumption that we are running privileged we
+         * first change the access mode and only then hand out
+         * ownership to avoid a window where access is too open. */
+
+        if (fchmod(fd, mode) < 0)
+                return -errno;
+
+        if (fchown(fd, uid, gid) < 0)
+                return -errno;
+
+        return 0;
+}
+
+cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
+        cpu_set_t *r;
+        unsigned n = 1024;
+
+        /* Allocates the cpuset in the right size */
+
+        for (;;) {
+                if (!(r = CPU_ALLOC(n)))
+                        return NULL;
+
+                if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
+                        CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
+
+                        if (ncpus)
+                                *ncpus = n;
+
+                        return r;
+                }
+
+                CPU_FREE(r);
+
+                if (errno != EINVAL)
+                        return NULL;
+
+                n *= 2;
+        }
+}
+
+int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
+        static const char status_indent[] = "         "; /* "[" STATUS "] " */
+        _cleanup_free_ char *s = NULL;
+        _cleanup_close_ int fd = -1;
+        struct iovec iovec[5];
+        int n = 0;
+
+        assert(format);
+
+        /* This is independent of logging, as status messages are
+         * optional and go exclusively to the console. */
+
+        if (vasprintf(&s, format, ap) < 0)
+                return log_oom();
+
+        fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        if (ellipse) {
+                char *e;
+                size_t emax, sl;
+                int c;
+
+                c = fd_columns(fd);
+                if (c <= 0)
+                        c = 80;
+
+                sl = status ? sizeof(status_indent)-1 : 0;
+
+                emax = c - sl - 1;
+                if (emax < 3)
+                        emax = 3;
+
+                e = ellipsize(s, emax, 75);
+                if (e) {
+                        free(s);
+                        s = e;
+                }
+        }
+
+        zero(iovec);
+
+        if (status) {
+                if (!isempty(status)) {
+                        IOVEC_SET_STRING(iovec[n++], "[");
+                        IOVEC_SET_STRING(iovec[n++], status);
+                        IOVEC_SET_STRING(iovec[n++], "] ");
+                } else
+                        IOVEC_SET_STRING(iovec[n++], status_indent);
+        }
+
+        IOVEC_SET_STRING(iovec[n++], s);
+        IOVEC_SET_STRING(iovec[n++], "\n");
+
+        if (writev(fd, iovec, n) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int status_printf(const char *status, bool ellipse, const char *format, ...) {
+        va_list ap;
+        int r;
+
+        assert(format);
+
+        va_start(ap, format);
+        r = status_vprintf(status, ellipse, format, ap);
+        va_end(ap);
+
+        return r;
+}
+
+int status_welcome(void) {
+        int r;
+        _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
+
+        r = parse_env_file("/etc/os-release", NEWLINE,
+                           "PRETTY_NAME", &pretty_name,
+                           "ANSI_COLOR", &ansi_color,
+                           NULL);
+        if (r < 0 && r != -ENOENT)
+                log_warning("Failed to read /etc/os-release: %s", strerror(-r));
+
+        return status_printf(NULL, false,
+                             "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
+                             isempty(ansi_color) ? "1" : ansi_color,
+                             isempty(pretty_name) ? "Linux" : pretty_name);
+}
+
+char *replace_env(const char *format, char **env) {
+        enum {
+                WORD,
+                CURLY,
+                VARIABLE
+        } state = WORD;
+
+        const char *e, *word = format;
+        char *r = NULL, *k;
+
+        assert(format);
+
+        for (e = format; *e; e ++) {
+
+                switch (state) {
+
+                case WORD:
+                        if (*e == '$')
+                                state = CURLY;
+                        break;
+
+                case CURLY:
+                        if (*e == '{') {
+                                if (!(k = strnappend(r, word, e-word-1)))
+                                        goto fail;
+
+                                free(r);
+                                r = k;
+
+                                word = e-1;
+                                state = VARIABLE;
+
+                        } else if (*e == '$') {
+                                if (!(k = strnappend(r, word, e-word)))
+                                        goto fail;
+
+                                free(r);
+                                r = k;
+
+                                word = e+1;
+                                state = WORD;
+                        } else
+                                state = WORD;
+                        break;
+
+                case VARIABLE:
+                        if (*e == '}') {
+                                const char *t;
+
+                                if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
+                                        t = "";
+
+                                if (!(k = strappend(r, t)))
+                                        goto fail;
+
+                                free(r);
+                                r = k;
+
+                                word = e+1;
+                                state = WORD;
+                        }
+                        break;
+                }
+        }
+
+        if (!(k = strnappend(r, word, e-word)))
+                goto fail;
+
+        free(r);
+        return k;
+
+fail:
+        free(r);
+        return NULL;
+}
+
+char **replace_env_argv(char **argv, char **env) {
+        char **r, **i;
+        unsigned k = 0, l = 0;
+
+        l = strv_length(argv);
+
+        if (!(r = new(char*, l+1)))
+                return NULL;
+
+        STRV_FOREACH(i, argv) {
+
+                /* If $FOO appears as single word, replace it by the split up variable */
+                if ((*i)[0] == '$' && (*i)[1] != '{') {
+                        char *e;
+                        char **w, **m;
+                        unsigned q;
+
+                        if ((e = strv_env_get(env, *i+1))) {
+
+                                if (!(m = strv_split_quoted(e))) {
+                                        r[k] = NULL;
+                                        strv_free(r);
+                                        return NULL;
+                                }
+                        } else
+                                m = NULL;
+
+                        q = strv_length(m);
+                        l = l + q - 1;
+
+                        if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
+                                r[k] = NULL;
+                                strv_free(r);
+                                strv_free(m);
+                                return NULL;
+                        }
+
+                        r = w;
+                        if (m) {
+                                memcpy(r + k, m, q * sizeof(char*));
+                                free(m);
+                        }
+
+                        k += q;
+                        continue;
+                }
+
+                /* If ${FOO} appears as part of a word, replace it by the variable as-is */
+                if (!(r[k++] = replace_env(*i, env))) {
+                        strv_free(r);
+                        return NULL;
+                }
+        }
+
+        r[k] = NULL;
+        return r;
+}
+
+int fd_columns(int fd) {
+        struct winsize ws;
+        zero(ws);
+
+        if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
+                return -errno;
+
+        if (ws.ws_col <= 0)
+                return -EIO;
+
+        return ws.ws_col;
+}
+
+unsigned columns(void) {
+        const char *e;
+        int c;
+
+        if (_likely_(cached_columns > 0))
+                return cached_columns;
+
+        c = 0;
+        e = getenv("COLUMNS");
+        if (e)
+                safe_atoi(e, &c);
+
+        if (c <= 0)
+                c = fd_columns(STDOUT_FILENO);
+
+        if (c <= 0)
+                c = 80;
+
+        cached_columns = c;
+        return c;
+}
+
+int fd_lines(int fd) {
+        struct winsize ws;
+        zero(ws);
+
+        if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
+                return -errno;
+
+        if (ws.ws_row <= 0)
+                return -EIO;
+
+        return ws.ws_row;
+}
+
+unsigned lines(void) {
+        const char *e;
+        unsigned l;
+
+        if (_likely_(cached_lines > 0))
+                return cached_lines;
+
+        l = 0;
+        e = getenv("LINES");
+        if (e)
+                safe_atou(e, &l);
+
+        if (l <= 0)
+                l = fd_lines(STDOUT_FILENO);
+
+        if (l <= 0)
+                l = 24;
+
+        cached_lines = l;
+        return cached_lines;
+}
+
+/* intended to be used as a SIGWINCH sighandler */
+void columns_lines_cache_reset(int signum) {
+        cached_columns = 0;
+        cached_lines = 0;
+}
+
+bool on_tty(void) {
+        static int cached_on_tty = -1;
+
+        if (_unlikely_(cached_on_tty < 0))
+                cached_on_tty = isatty(STDOUT_FILENO) > 0;
+
+        return cached_on_tty;
+}
+
+int running_in_chroot(void) {
+        struct stat a, b;
+
+        zero(a);
+        zero(b);
+
+        /* Only works as root */
+
+        if (stat("/proc/1/root", &a) < 0)
+                return -errno;
+
+        if (stat("/", &b) < 0)
+                return -errno;
+
+        return
+                a.st_dev != b.st_dev ||
+                a.st_ino != b.st_ino;
+}
+
+char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
+        size_t x;
+        char *r;
+
+        assert(s);
+        assert(percent <= 100);
+        assert(new_length >= 3);
+
+        if (old_length <= 3 || old_length <= new_length)
+                return strndup(s, old_length);
+
+        r = new0(char, new_length+1);
+        if (!r)
+                return r;
+
+        x = (new_length * percent) / 100;
+
+        if (x > new_length - 3)
+                x = new_length - 3;
+
+        memcpy(r, s, x);
+        r[x] = '.';
+        r[x+1] = '.';
+        r[x+2] = '.';
+        memcpy(r + x + 3,
+               s + old_length - (new_length - x - 3),
+               new_length - x - 3);
+
+        return r;
+}
+
+char *ellipsize(const char *s, size_t length, unsigned percent) {
+        return ellipsize_mem(s, strlen(s), length, percent);
+}
+
+int touch(const char *path) {
+        int fd;
+
+        assert(path);
+
+        /* This just opens the file for writing, ensuring it
+         * exists. It doesn't call utimensat() the way /usr/bin/touch
+         * does it. */
+
+        fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
+        if (fd < 0)
+                return -errno;
+
+        close_nointr_nofail(fd);
+        return 0;
+}
+
+char *unquote(const char *s, const char* quotes) {
+        size_t l;
+        assert(s);
+
+        /* This is rather stupid, simply removes the heading and
+         * trailing quotes if there is one. Doesn't care about
+         * escaping or anything. We should make this smarter one
+         * day...*/
+
+        l = strlen(s);
+        if (l < 2)
+                return strdup(s);
+
+        if (strchr(quotes, s[0]) && s[l-1] == s[0])
+                return strndup(s+1, l-2);
+
+        return strdup(s);
+}
+
+char *normalize_env_assignment(const char *s) {
+        _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
+        char *eq, *r;
+
+        eq = strchr(s, '=');
+        if (!eq) {
+                char *t;
+
+                r = strdup(s);
+                if (!r)
+                        return NULL;
+
+                t = strstrip(r);
+                if (t == r)
+                        return r;
+
+                memmove(r, t, strlen(t) + 1);
+                return r;
+        }
+
+        name = strndup(s, eq - s);
+        if (!name)
+                return NULL;
+
+        p = strdup(eq + 1);
+        if (!p)
+                return NULL;
+
+        value = unquote(strstrip(p), QUOTES);
+        if (!value)
+                return NULL;
+
+        if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
+                r = NULL;
+
+        return r;
+}
+
+int wait_for_terminate(pid_t pid, siginfo_t *status) {
+        siginfo_t dummy;
+
+        assert(pid >= 1);
+
+        if (!status)
+                status = &dummy;
+
+        for (;;) {
+                zero(*status);
+
+                if (waitid(P_PID, pid, status, WEXITED) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        return -errno;
+                }
+
+                return 0;
+        }
+}
+
+int wait_for_terminate_and_warn(const char *name, pid_t pid) {
+        int r;
+        siginfo_t status;
+
+        assert(name);
+        assert(pid > 1);
+
+        r = wait_for_terminate(pid, &status);
+        if (r < 0) {
+                log_warning("Failed to wait for %s: %s", name, strerror(-r));
+                return r;
+        }
+
+        if (status.si_code == CLD_EXITED) {
+                if (status.si_status != 0) {
+                        log_warning("%s failed with error code %i.", name, status.si_status);
+                        return status.si_status;
+                }
+
+                log_debug("%s succeeded.", name);
+                return 0;
+
+        } else if (status.si_code == CLD_KILLED ||
+                   status.si_code == CLD_DUMPED) {
+
+                log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
+                return -EPROTO;
+        }
+
+        log_warning("%s failed due to unknown reason.", name);
+        return -EPROTO;
+}
+
+_noreturn_ void freeze(void) {
+
+        /* Make sure nobody waits for us on a socket anymore */
+        close_all_fds(NULL, 0);
+
+        sync();
+
+        for (;;)
+                pause();
+}
+
+bool null_or_empty(struct stat *st) {
+        assert(st);
+
+        if (S_ISREG(st->st_mode) && st->st_size <= 0)
+                return true;
+
+        if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
+                return true;
+
+        return false;
+}
+
+int null_or_empty_path(const char *fn) {
+        struct stat st;
+
+        assert(fn);
+
+        if (stat(fn, &st) < 0)
+                return -errno;
+
+        return null_or_empty(&st);
+}
+
+DIR *xopendirat(int fd, const char *name, int flags) {
+        int nfd;
+        DIR *d;
+
+        nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
+        if (nfd < 0)
+                return NULL;
+
+        d = fdopendir(nfd);
+        if (!d) {
+                close_nointr_nofail(nfd);
+                return NULL;
+        }
+
+        return d;
+}
+
+int signal_from_string_try_harder(const char *s) {
+        int signo;
+        assert(s);
+
+        signo = signal_from_string(s);
+        if (signo <= 0)
+                if (startswith(s, "SIG"))
+                        return signal_from_string(s+3);
+
+        return signo;
+}
+
+static char *tag_to_udev_node(const char *tagvalue, const char *by) {
+        char *dn, *t, *u;
+        int r;
+
+        /* FIXME: to follow udev's logic 100% we need to leave valid
+         * UTF8 chars unescaped */
+
+        u = unquote(tagvalue, "\"\'");
+        if (u == NULL)
+                return NULL;
+
+        t = xescape(u, "/ ");
+        free(u);
+
+        if (t == NULL)
+                return NULL;
+
+        r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t);
+        free(t);
+
+        if (r < 0)
+                return NULL;
+
+        return dn;
+}
+
+char *fstab_node_to_udev_node(const char *p) {
+        assert(p);
+
+        if (startswith(p, "LABEL="))
+                return tag_to_udev_node(p+6, "label");
+
+        if (startswith(p, "UUID="))
+                return tag_to_udev_node(p+5, "uuid");
+
+        if (startswith(p, "PARTUUID="))
+                return tag_to_udev_node(p+9, "partuuid");
+
+        if (startswith(p, "PARTLABEL="))
+                return tag_to_udev_node(p+10, "partlabel");
+
+        return strdup(p);
+}
+
+bool tty_is_vc(const char *tty) {
+        assert(tty);
+
+        if (startswith(tty, "/dev/"))
+                tty += 5;
+
+        return vtnr_from_tty(tty) >= 0;
+}
+
+bool tty_is_console(const char *tty) {
+        assert(tty);
+
+        if (startswith(tty, "/dev/"))
+                tty += 5;
+
+        return streq(tty, "console");
+}
+
+int vtnr_from_tty(const char *tty) {
+        int i, r;
+
+        assert(tty);
+
+        if (startswith(tty, "/dev/"))
+                tty += 5;
+
+        if (!startswith(tty, "tty") )
+                return -EINVAL;
+
+        if (tty[3] < '0' || tty[3] > '9')
+                return -EINVAL;
+
+        r = safe_atoi(tty+3, &i);
+        if (r < 0)
+                return r;
+
+        if (i < 0 || i > 63)
+                return -EINVAL;
+
+        return i;
+}
+
+bool tty_is_vc_resolve(const char *tty) {
+        char *active = NULL;
+        bool b;
+
+        assert(tty);
+
+        if (startswith(tty, "/dev/"))
+                tty += 5;
+
+        /* Resolve where /dev/console is pointing to, if /sys is
+         * actually ours (i.e. not read-only-mounted which is a sign
+         * for container setups) */
+        if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
+                if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
+                        /* If multiple log outputs are configured the
+                         * last one is what /dev/console points to */
+                        tty = strrchr(active, ' ');
+                        if (tty)
+                                tty++;
+                        else
+                                tty = active;
+                }
+
+        b = tty_is_vc(tty);
+        free(active);
+
+        return b;
+}
+
+const char *default_term_for_tty(const char *tty) {
+        assert(tty);
+
+        return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
+}
+
+bool dirent_is_file(const struct dirent *de) {
+        assert(de);
+
+        if (ignore_file(de->d_name))
+                return false;
+
+        if (de->d_type != DT_REG &&
+            de->d_type != DT_LNK &&
+            de->d_type != DT_UNKNOWN)
+                return false;
+
+        return true;
+}
+
+bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
+        assert(de);
+
+        if (de->d_type != DT_REG &&
+            de->d_type != DT_LNK &&
+            de->d_type != DT_UNKNOWN)
+                return false;
+
+        if (ignore_file_allow_backup(de->d_name))
+                return false;
+
+        return endswith(de->d_name, suffix);
+}
+
+void execute_directory(const char *directory, DIR *d, char *argv[]) {
+        DIR *_d = NULL;
+        struct dirent *de;
+        Hashmap *pids = NULL;
+
+        assert(directory);
+
+        /* Executes all binaries in a directory in parallel and waits
+         * until all they all finished. */
+
+        if (!d) {
+                if (!(_d = opendir(directory))) {
+
+                        if (errno == ENOENT)
+                                return;
+
+                        log_error("Failed to enumerate directory %s: %m", directory);
+                        return;
+                }
+
+                d = _d;
+        }
+
+        if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
+                log_error("Failed to allocate set.");
+                goto finish;
+        }
+
+        while ((de = readdir(d))) {
+                char *path;
+                pid_t pid;
+                int k;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
+                        log_oom();
+                        continue;
+                }
+
+                if ((pid = fork()) < 0) {
+                        log_error("Failed to fork: %m");
+                        free(path);
+                        continue;
+                }
+
+                if (pid == 0) {
+                        char *_argv[2];
+                        /* Child */
+
+                        if (!argv) {
+                                _argv[0] = path;
+                                _argv[1] = NULL;
+                                argv = _argv;
+                        } else
+                                argv[0] = path;
+
+                        execv(path, argv);
+
+                        log_error("Failed to execute %s: %m", path);
+                        _exit(EXIT_FAILURE);
+                }
+
+                log_debug("Spawned %s as %lu", path, (unsigned long) pid);
+
+                if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
+                        log_error("Failed to add PID to set: %s", strerror(-k));
+                        free(path);
+                }
+        }
+
+        while (!hashmap_isempty(pids)) {
+                pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
+                siginfo_t si;
+                char *path;
+
+                zero(si);
+                if (waitid(P_PID, pid, &si, WEXITED) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        log_error("waitid() failed: %m");
+                        goto finish;
+                }
+
+                if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
+                        if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
+                                if (si.si_code == CLD_EXITED)
+                                        log_error("%s exited with exit status %i.", path, si.si_status);
+                                else
+                                        log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
+                        } else
+                                log_debug("%s exited successfully.", path);
+
+                        free(path);
+                }
+        }
+
+finish:
+        if (_d)
+                closedir(_d);
+
+        if (pids)
+                hashmap_free_free(pids);
+}
+
+int kill_and_sigcont(pid_t pid, int sig) {
+        int r;
+
+        r = kill(pid, sig) < 0 ? -errno : 0;
+
+        if (r >= 0)
+                kill(pid, SIGCONT);
+
+        return r;
+}
+
+bool nulstr_contains(const char*nulstr, const char *needle) {
+        const char *i;
+
+        if (!nulstr)
+                return false;
+
+        NULSTR_FOREACH(i, nulstr)
+                if (streq(i, needle))
+                        return true;
+
+        return false;
+}
+
+bool plymouth_running(void) {
+        return access("/run/plymouth/pid", F_OK) >= 0;
+}
+
+char* strshorten(char *s, size_t l) {
+        assert(s);
+
+        if (l < strlen(s))
+                s[l] = 0;
+
+        return s;
+}
+
+static bool hostname_valid_char(char c) {
+        return
+                (c >= 'a' && c <= 'z') ||
+                (c >= 'A' && c <= 'Z') ||
+                (c >= '0' && c <= '9') ||
+                c == '-' ||
+                c == '_' ||
+                c == '.';
+}
+
+bool hostname_is_valid(const char *s) {
+        const char *p;
+
+        if (isempty(s))
+                return false;
+
+        for (p = s; *p; p++)
+                if (!hostname_valid_char(*p))
+                        return false;
+
+        if (p-s > HOST_NAME_MAX)
+                return false;
+
+        return true;
+}
+
+char* hostname_cleanup(char *s) {
+        char *p, *d;
+
+        for (p = s, d = s; *p; p++)
+                if ((*p >= 'a' && *p <= 'z') ||
+                    (*p >= 'A' && *p <= 'Z') ||
+                    (*p >= '0' && *p <= '9') ||
+                    *p == '-' ||
+                    *p == '_' ||
+                    *p == '.')
+                        *(d++) = *p;
+
+        *d = 0;
+
+        strshorten(s, HOST_NAME_MAX);
+        return s;
+}
+
+int pipe_eof(int fd) {
+        struct pollfd pollfd;
+        int r;
+
+        zero(pollfd);
+        pollfd.fd = fd;
+        pollfd.events = POLLIN|POLLHUP;
+
+        r = poll(&pollfd, 1, 0);
+        if (r < 0)
+                return -errno;
+
+        if (r == 0)
+                return 0;
+
+        return pollfd.revents & POLLHUP;
+}
+
+int fd_wait_for_event(int fd, int event, usec_t t) {
+        struct pollfd pollfd;
+        int r;
+
+        zero(pollfd);
+        pollfd.fd = fd;
+        pollfd.events = event;
+
+        r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
+        if (r < 0)
+                return -errno;
+
+        if (r == 0)
+                return 0;
+
+        return pollfd.revents;
+}
+
+int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
+        FILE *f;
+        char *t;
+        const char *fn;
+        size_t k;
+        int fd;
+
+        assert(path);
+        assert(_f);
+        assert(_temp_path);
+
+        t = new(char, strlen(path) + 1 + 6 + 1);
+        if (!t)
+                return -ENOMEM;
+
+        fn = path_get_file_name(path);
+        k = fn-path;
+        memcpy(t, path, k);
+        t[k] = '.';
+        stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
+
+        fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
+        if (fd < 0) {
+                free(t);
+                return -errno;
+        }
+
+        f = fdopen(fd, "we");
+        if (!f) {
+                unlink(t);
+                free(t);
+                return -errno;
+        }
+
+        *_f = f;
+        *_temp_path = t;
+
+        return 0;
+}
+
+int terminal_vhangup_fd(int fd) {
+        assert(fd >= 0);
+
+        if (ioctl(fd, TIOCVHANGUP) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int terminal_vhangup(const char *name) {
+        int fd, r;
+
+        fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        r = terminal_vhangup_fd(fd);
+        close_nointr_nofail(fd);
+
+        return r;
+}
+
+int vt_disallocate(const char *name) {
+        int fd, r;
+        unsigned u;
+
+        /* Deallocate the VT if possible. If not possible
+         * (i.e. because it is the active one), at least clear it
+         * entirely (including the scrollback buffer) */
+
+        if (!startswith(name, "/dev/"))
+                return -EINVAL;
+
+        if (!tty_is_vc(name)) {
+                /* So this is not a VT. I guess we cannot deallocate
+                 * it then. But let's at least clear the screen */
+
+                fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+                if (fd < 0)
+                        return fd;
+
+                loop_write(fd,
+                           "\033[r"    /* clear scrolling region */
+                           "\033[H"    /* move home */
+                           "\033[2J",  /* clear screen */
+                           10, false);
+                close_nointr_nofail(fd);
+
+                return 0;
+        }
+
+        if (!startswith(name, "/dev/tty"))
+                return -EINVAL;
+
+        r = safe_atou(name+8, &u);
+        if (r < 0)
+                return r;
+
+        if (u <= 0)
+                return -EINVAL;
+
+        /* Try to deallocate */
+        fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        r = ioctl(fd, VT_DISALLOCATE, u);
+        close_nointr_nofail(fd);
+
+        if (r >= 0)
+                return 0;
+
+        if (errno != EBUSY)
+                return -errno;
+
+        /* Couldn't deallocate, so let's clear it fully with
+         * scrollback */
+        fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        loop_write(fd,
+                   "\033[r"   /* clear scrolling region */
+                   "\033[H"   /* move home */
+                   "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
+                   10, false);
+        close_nointr_nofail(fd);
+
+        return 0;
+}
+
+int copy_file(const char *from, const char *to) {
+        int r, fdf, fdt;
+
+        assert(from);
+        assert(to);
+
+        fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fdf < 0)
+                return -errno;
+
+        fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
+        if (fdt < 0) {
+                close_nointr_nofail(fdf);
+                return -errno;
+        }
+
+        for (;;) {
+                char buf[PIPE_BUF];
+                ssize_t n, k;
+
+                n = read(fdf, buf, sizeof(buf));
+                if (n < 0) {
+                        r = -errno;
+
+                        close_nointr_nofail(fdf);
+                        close_nointr(fdt);
+                        unlink(to);
+
+                        return r;
+                }
+
+                if (n == 0)
+                        break;
+
+                errno = 0;
+                k = loop_write(fdt, buf, n, false);
+                if (n != k) {
+                        r = k < 0 ? k : (errno ? -errno : -EIO);
+
+                        close_nointr_nofail(fdf);
+                        close_nointr(fdt);
+
+                        unlink(to);
+                        return r;
+                }
+        }
+
+        close_nointr_nofail(fdf);
+        r = close_nointr(fdt);
+
+        if (r < 0) {
+                unlink(to);
+                return r;
+        }
+
+        return 0;
+}
+
+int symlink_atomic(const char *from, const char *to) {
+        char *x;
+        _cleanup_free_ char *t;
+        const char *fn;
+        size_t k;
+        unsigned long long ull;
+        unsigned i;
+        int r;
+
+        assert(from);
+        assert(to);
+
+        t = new(char, strlen(to) + 1 + 16 + 1);
+        if (!t)
+                return -ENOMEM;
+
+        fn = path_get_file_name(to);
+        k = fn-to;
+        memcpy(t, to, k);
+        t[k] = '.';
+        x = stpcpy(t+k+1, fn);
+
+        ull = random_ull();
+        for (i = 0; i < 16; i++) {
+                *(x++) = hexchar(ull & 0xF);
+                ull >>= 4;
+        }
+
+        *x = 0;
+
+        if (symlink(from, t) < 0)
+                return -errno;
+
+        if (rename(t, to) < 0) {
+                r = -errno;
+                unlink(t);
+                return r;
+        }
+
+        return 0;
+}
+
+bool display_is_local(const char *display) {
+        assert(display);
+
+        return
+                display[0] == ':' &&
+                display[1] >= '0' &&
+                display[1] <= '9';
+}
+
+int socket_from_display(const char *display, char **path) {
+        size_t k;
+        char *f, *c;
+
+        assert(display);
+        assert(path);
+
+        if (!display_is_local(display))
+                return -EINVAL;
+
+        k = strspn(display+1, "0123456789");
+
+        f = new(char, sizeof("/tmp/.X11-unix/X") + k);
+        if (!f)
+                return -ENOMEM;
+
+        c = stpcpy(f, "/tmp/.X11-unix/X");
+        memcpy(c, display+1, k);
+        c[k] = 0;
+
+        *path = f;
+
+        return 0;
+}
+
+int get_user_creds(
+                const char **username,
+                uid_t *uid, gid_t *gid,
+                const char **home,
+                const char **shell) {
+
+        struct passwd *p;
+        uid_t u;
+
+        assert(username);
+        assert(*username);
+
+        /* We enforce some special rules for uid=0: in order to avoid
+         * NSS lookups for root we hardcode its data. */
+
+        if (streq(*username, "root") || streq(*username, "0")) {
+                *username = "root";
+
+                if (uid)
+                        *uid = 0;
+
+                if (gid)
+                        *gid = 0;
+
+                if (home)
+                        *home = "/root";
+
+                if (shell)
+                        *shell = "/bin/sh";
+
+                return 0;
+        }
+
+        if (parse_uid(*username, &u) >= 0) {
+                errno = 0;
+                p = getpwuid(u);
+
+                /* If there are multiple users with the same id, make
+                 * sure to leave $USER to the configured value instead
+                 * of the first occurrence in the database. However if
+                 * the uid was configured by a numeric uid, then let's
+                 * pick the real username from /etc/passwd. */
+                if (p)
+                        *username = p->pw_name;
+        } else {
+                errno = 0;
+                p = getpwnam(*username);
+        }
+
+        if (!p)
+                return errno != 0 ? -errno : -ESRCH;
+
+        if (uid)
+                *uid = p->pw_uid;
+
+        if (gid)
+                *gid = p->pw_gid;
+
+        if (home)
+                *home = p->pw_dir;
+
+        if (shell)
+                *shell = p->pw_shell;
+
+        return 0;
+}
+
+int get_group_creds(const char **groupname, gid_t *gid) {
+        struct group *g;
+        gid_t id;
+
+        assert(groupname);
+
+        /* We enforce some special rules for gid=0: in order to avoid
+         * NSS lookups for root we hardcode its data. */
+
+        if (streq(*groupname, "root") || streq(*groupname, "0")) {
+                *groupname = "root";
+
+                if (gid)
+                        *gid = 0;
+
+                return 0;
+        }
+
+        if (parse_gid(*groupname, &id) >= 0) {
+                errno = 0;
+                g = getgrgid(id);
+
+                if (g)
+                        *groupname = g->gr_name;
+        } else {
+                errno = 0;
+                g = getgrnam(*groupname);
+        }
+
+        if (!g)
+                return errno != 0 ? -errno : -ESRCH;
+
+        if (gid)
+                *gid = g->gr_gid;
+
+        return 0;
+}
+
+int in_group(const char *name) {
+        gid_t gid, *gids;
+        int ngroups_max, r, i;
+
+        r = get_group_creds(&name, &gid);
+        if (r < 0)
+                return r;
+
+        if (getgid() == gid)
+                return 1;
+
+        if (getegid() == gid)
+                return 1;
+
+        ngroups_max = sysconf(_SC_NGROUPS_MAX);
+        assert(ngroups_max > 0);
+
+        gids = alloca(sizeof(gid_t) * ngroups_max);
+
+        r = getgroups(ngroups_max, gids);
+        if (r < 0)
+                return -errno;
+
+        for (i = 0; i < r; i++)
+                if (gids[i] == gid)
+                        return 1;
+
+        return 0;
+}
+
+int glob_exists(const char *path) {
+        glob_t g;
+        int r, k;
+
+        assert(path);
+
+        zero(g);
+        errno = 0;
+        k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
+
+        if (k == GLOB_NOMATCH)
+                r = 0;
+        else if (k == GLOB_NOSPACE)
+                r = -ENOMEM;
+        else if (k == 0)
+                r = !strv_isempty(g.gl_pathv);
+        else
+                r = errno ? -errno : -EIO;
+
+        globfree(&g);
+
+        return r;
+}
+
+int dirent_ensure_type(DIR *d, struct dirent *de) {
+        struct stat st;
+
+        assert(d);
+        assert(de);
+
+        if (de->d_type != DT_UNKNOWN)
+                return 0;
+
+        if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
+                return -errno;
+
+        de->d_type =
+                S_ISREG(st.st_mode)  ? DT_REG  :
+                S_ISDIR(st.st_mode)  ? DT_DIR  :
+                S_ISLNK(st.st_mode)  ? DT_LNK  :
+                S_ISFIFO(st.st_mode) ? DT_FIFO :
+                S_ISSOCK(st.st_mode) ? DT_SOCK :
+                S_ISCHR(st.st_mode)  ? DT_CHR  :
+                S_ISBLK(st.st_mode)  ? DT_BLK  :
+                                       DT_UNKNOWN;
+
+        return 0;
+}
+
+int in_search_path(const char *path, char **search) {
+        char **i, *parent;
+        int r;
+
+        r = path_get_parent(path, &parent);
+        if (r < 0)
+                return r;
+
+        r = 0;
+
+        STRV_FOREACH(i, search) {
+                if (path_equal(parent, *i)) {
+                        r = 1;
+                        break;
+                }
+        }
+
+        free(parent);
+
+        return r;
+}
+
+int get_files_in_directory(const char *path, char ***list) {
+        DIR *d;
+        int r = 0;
+        unsigned n = 0;
+        char **l = NULL;
+
+        assert(path);
+
+        /* Returns all files in a directory in *list, and the number
+         * of files as return value. If list is NULL returns only the
+         * number */
+
+        d = opendir(path);
+        if (!d)
+                return -errno;
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                int k;
+
+                k = readdir_r(d, &buf.de, &de);
+                if (k != 0) {
+                        r = -k;
+                        goto finish;
+                }
+
+                if (!de)
+                        break;
+
+                dirent_ensure_type(d, de);
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                if (list) {
+                        if ((unsigned) r >= n) {
+                                char **t;
+
+                                n = MAX(16, 2*r);
+                                t = realloc(l, sizeof(char*) * n);
+                                if (!t) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                l = t;
+                        }
+
+                        assert((unsigned) r < n);
+
+                        l[r] = strdup(de->d_name);
+                        if (!l[r]) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        l[++r] = NULL;
+                } else
+                        r++;
+        }
+
+finish:
+        if (d)
+                closedir(d);
+
+        if (r >= 0) {
+                if (list)
+                        *list = l;
+        } else
+                strv_free(l);
+
+        return r;
+}
+
+char *strjoin(const char *x, ...) {
+        va_list ap;
+        size_t l;
+        char *r, *p;
+
+        va_start(ap, x);
+
+        if (x) {
+                l = strlen(x);
+
+                for (;;) {
+                        const char *t;
+                        size_t n;
+
+                        t = va_arg(ap, const char *);
+                        if (!t)
+                                break;
+
+                        n = strlen(t);
+                        if (n > ((size_t) -1) - l) {
+                                va_end(ap);
+                                return NULL;
+                        }
+
+                        l += n;
+                }
+        } else
+                l = 0;
+
+        va_end(ap);
+
+        r = new(char, l+1);
+        if (!r)
+                return NULL;
+
+        if (x) {
+                p = stpcpy(r, x);
+
+                va_start(ap, x);
+
+                for (;;) {
+                        const char *t;
+
+                        t = va_arg(ap, const char *);
+                        if (!t)
+                                break;
+
+                        p = stpcpy(p, t);
+                }
+
+                va_end(ap);
+        } else
+                r[0] = 0;
+
+        return r;
+}
+
+bool is_main_thread(void) {
+        static __thread int cached = 0;
+
+        if (_unlikely_(cached == 0))
+                cached = getpid() == gettid() ? 1 : -1;
+
+        return cached > 0;
+}
+
+int block_get_whole_disk(dev_t d, dev_t *ret) {
+        char *p, *s;
+        int r;
+        unsigned n, m;
+
+        assert(ret);
+
+        /* If it has a queue this is good enough for us */
+        if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
+                return -ENOMEM;
+
+        r = access(p, F_OK);
+        free(p);
+
+        if (r >= 0) {
+                *ret = d;
+                return 0;
+        }
+
+        /* If it is a partition find the originating device */
+        if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
+                return -ENOMEM;
+
+        r = access(p, F_OK);
+        free(p);
+
+        if (r < 0)
+                return -ENOENT;
+
+        /* Get parent dev_t */
+        if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
+                return -ENOMEM;
+
+        r = read_one_line_file(p, &s);
+        free(p);
+
+        if (r < 0)
+                return r;
+
+        r = sscanf(s, "%u:%u", &m, &n);
+        free(s);
+
+        if (r != 2)
+                return -EINVAL;
+
+        /* Only return this if it is really good enough for us. */
+        if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
+                return -ENOMEM;
+
+        r = access(p, F_OK);
+        free(p);
+
+        if (r >= 0) {
+                *ret = makedev(m, n);
+                return 0;
+        }
+
+        return -ENOENT;
+}
+
+int file_is_priv_sticky(const char *p) {
+        struct stat st;
+
+        assert(p);
+
+        if (lstat(p, &st) < 0)
+                return -errno;
+
+        return
+                (st.st_uid == 0 || st.st_uid == getuid()) &&
+                (st.st_mode & S_ISVTX);
+}
+
+static const char *const ioprio_class_table[] = {
+        [IOPRIO_CLASS_NONE] = "none",
+        [IOPRIO_CLASS_RT] = "realtime",
+        [IOPRIO_CLASS_BE] = "best-effort",
+        [IOPRIO_CLASS_IDLE] = "idle"
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
+
+static const char *const sigchld_code_table[] = {
+        [CLD_EXITED] = "exited",
+        [CLD_KILLED] = "killed",
+        [CLD_DUMPED] = "dumped",
+        [CLD_TRAPPED] = "trapped",
+        [CLD_STOPPED] = "stopped",
+        [CLD_CONTINUED] = "continued",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
+
+static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
+        [LOG_FAC(LOG_KERN)] = "kern",
+        [LOG_FAC(LOG_USER)] = "user",
+        [LOG_FAC(LOG_MAIL)] = "mail",
+        [LOG_FAC(LOG_DAEMON)] = "daemon",
+        [LOG_FAC(LOG_AUTH)] = "auth",
+        [LOG_FAC(LOG_SYSLOG)] = "syslog",
+        [LOG_FAC(LOG_LPR)] = "lpr",
+        [LOG_FAC(LOG_NEWS)] = "news",
+        [LOG_FAC(LOG_UUCP)] = "uucp",
+        [LOG_FAC(LOG_CRON)] = "cron",
+        [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
+        [LOG_FAC(LOG_FTP)] = "ftp",
+        [LOG_FAC(LOG_LOCAL0)] = "local0",
+        [LOG_FAC(LOG_LOCAL1)] = "local1",
+        [LOG_FAC(LOG_LOCAL2)] = "local2",
+        [LOG_FAC(LOG_LOCAL3)] = "local3",
+        [LOG_FAC(LOG_LOCAL4)] = "local4",
+        [LOG_FAC(LOG_LOCAL5)] = "local5",
+        [LOG_FAC(LOG_LOCAL6)] = "local6",
+        [LOG_FAC(LOG_LOCAL7)] = "local7"
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
+
+static const char *const log_level_table[] = {
+        [LOG_EMERG] = "emerg",
+        [LOG_ALERT] = "alert",
+        [LOG_CRIT] = "crit",
+        [LOG_ERR] = "err",
+        [LOG_WARNING] = "warning",
+        [LOG_NOTICE] = "notice",
+        [LOG_INFO] = "info",
+        [LOG_DEBUG] = "debug"
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
+
+static const char* const sched_policy_table[] = {
+        [SCHED_OTHER] = "other",
+        [SCHED_BATCH] = "batch",
+        [SCHED_IDLE] = "idle",
+        [SCHED_FIFO] = "fifo",
+        [SCHED_RR] = "rr"
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
+
+static const char* const rlimit_table[] = {
+        [RLIMIT_CPU] = "LimitCPU",
+        [RLIMIT_FSIZE] = "LimitFSIZE",
+        [RLIMIT_DATA] = "LimitDATA",
+        [RLIMIT_STACK] = "LimitSTACK",
+        [RLIMIT_CORE] = "LimitCORE",
+        [RLIMIT_RSS] = "LimitRSS",
+        [RLIMIT_NOFILE] = "LimitNOFILE",
+        [RLIMIT_AS] = "LimitAS",
+        [RLIMIT_NPROC] = "LimitNPROC",
+        [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
+        [RLIMIT_LOCKS] = "LimitLOCKS",
+        [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
+        [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
+        [RLIMIT_NICE] = "LimitNICE",
+        [RLIMIT_RTPRIO] = "LimitRTPRIO",
+        [RLIMIT_RTTIME] = "LimitRTTIME"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
+
+static const char* const ip_tos_table[] = {
+        [IPTOS_LOWDELAY] = "low-delay",
+        [IPTOS_THROUGHPUT] = "throughput",
+        [IPTOS_RELIABILITY] = "reliability",
+        [IPTOS_LOWCOST] = "low-cost",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
+
+static const char *const __signal_table[] = {
+        [SIGHUP] = "HUP",
+        [SIGINT] = "INT",
+        [SIGQUIT] = "QUIT",
+        [SIGILL] = "ILL",
+        [SIGTRAP] = "TRAP",
+        [SIGABRT] = "ABRT",
+        [SIGBUS] = "BUS",
+        [SIGFPE] = "FPE",
+        [SIGKILL] = "KILL",
+        [SIGUSR1] = "USR1",
+        [SIGSEGV] = "SEGV",
+        [SIGUSR2] = "USR2",
+        [SIGPIPE] = "PIPE",
+        [SIGALRM] = "ALRM",
+        [SIGTERM] = "TERM",
+#ifdef SIGSTKFLT
+        [SIGSTKFLT] = "STKFLT",  /* Linux on SPARC doesn't know SIGSTKFLT */
+#endif
+        [SIGCHLD] = "CHLD",
+        [SIGCONT] = "CONT",
+        [SIGSTOP] = "STOP",
+        [SIGTSTP] = "TSTP",
+        [SIGTTIN] = "TTIN",
+        [SIGTTOU] = "TTOU",
+        [SIGURG] = "URG",
+        [SIGXCPU] = "XCPU",
+        [SIGXFSZ] = "XFSZ",
+        [SIGVTALRM] = "VTALRM",
+        [SIGPROF] = "PROF",
+        [SIGWINCH] = "WINCH",
+        [SIGIO] = "IO",
+        [SIGPWR] = "PWR",
+        [SIGSYS] = "SYS"
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
+
+const char *signal_to_string(int signo) {
+        static __thread char buf[12];
+        const char *name;
+
+        name = __signal_to_string(signo);
+        if (name)
+                return name;
+
+        if (signo >= SIGRTMIN && signo <= SIGRTMAX)
+                snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
+        else
+                snprintf(buf, sizeof(buf) - 1, "%d", signo);
+        char_array_0(buf);
+        return buf;
+}
+
+int signal_from_string(const char *s) {
+        int signo;
+        int offset = 0;
+        unsigned u;
+
+        signo = __signal_from_string(s);
+        if (signo > 0)
+                return signo;
+
+        if (startswith(s, "RTMIN+")) {
+                s += 6;
+                offset = SIGRTMIN;
+        }
+        if (safe_atou(s, &u) >= 0) {
+                signo = (int) u + offset;
+                if (signo > 0 && signo < _NSIG)
+                        return signo;
+        }
+        return -1;
+}
+
+bool kexec_loaded(void) {
+       bool loaded = false;
+       char *s;
+
+       if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
+               if (s[0] == '1')
+                       loaded = true;
+               free(s);
+       }
+       return loaded;
+}
+
+int strdup_or_null(const char *a, char **b) {
+        char *c;
+
+        assert(b);
+
+        if (!a) {
+                *b = NULL;
+                return 0;
+        }
+
+        c = strdup(a);
+        if (!c)
+                return -ENOMEM;
+
+        *b = c;
+        return 0;
+}
+
+int prot_from_flags(int flags) {
+
+        switch (flags & O_ACCMODE) {
+
+        case O_RDONLY:
+                return PROT_READ;
+
+        case O_WRONLY:
+                return PROT_WRITE;
+
+        case O_RDWR:
+                return PROT_READ|PROT_WRITE;
+
+        default:
+                return -EINVAL;
+        }
+}
+
+char *format_bytes(char *buf, size_t l, off_t t) {
+        unsigned i;
+
+        static const struct {
+                const char *suffix;
+                off_t factor;
+        } table[] = {
+                { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
+                { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
+                { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
+                { "G", 1024ULL*1024ULL*1024ULL },
+                { "M", 1024ULL*1024ULL },
+                { "K", 1024ULL },
+        };
+
+        for (i = 0; i < ELEMENTSOF(table); i++) {
+
+                if (t >= table[i].factor) {
+                        snprintf(buf, l,
+                                 "%llu.%llu%s",
+                                 (unsigned long long) (t / table[i].factor),
+                                 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
+                                 table[i].suffix);
+
+                        goto finish;
+                }
+        }
+
+        snprintf(buf, l, "%lluB", (unsigned long long) t);
+
+finish:
+        buf[l-1] = 0;
+        return buf;
+
+}
+
+void* memdup(const void *p, size_t l) {
+        void *r;
+
+        assert(p);
+
+        r = malloc(l);
+        if (!r)
+                return NULL;
+
+        memcpy(r, p, l);
+        return r;
+}
+
+int fd_inc_sndbuf(int fd, size_t n) {
+        int r, value;
+        socklen_t l = sizeof(value);
+
+        r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
+        if (r >= 0 &&
+            l == sizeof(value) &&
+            (size_t) value >= n*2)
+                return 0;
+
+        value = (int) n;
+        r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
+        if (r < 0)
+                return -errno;
+
+        return 1;
+}
+
+int fd_inc_rcvbuf(int fd, size_t n) {
+        int r, value;
+        socklen_t l = sizeof(value);
+
+        r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
+        if (r >= 0 &&
+            l == sizeof(value) &&
+            (size_t) value >= n*2)
+                return 0;
+
+        value = (int) n;
+        r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
+        if (r < 0)
+                return -errno;
+
+        return 1;
+}
+
+int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
+        pid_t parent_pid, agent_pid;
+        int fd;
+        bool stdout_is_tty, stderr_is_tty;
+        unsigned n, i;
+        va_list ap;
+        char **l;
+
+        assert(pid);
+        assert(path);
+
+        parent_pid = getpid();
+
+        /* Spawns a temporary TTY agent, making sure it goes away when
+         * we go away */
+
+        agent_pid = fork();
+        if (agent_pid < 0)
+                return -errno;
+
+        if (agent_pid != 0) {
+                *pid = agent_pid;
+                return 0;
+        }
+
+        /* In the child:
+         *
+         * Make sure the agent goes away when the parent dies */
+        if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
+                _exit(EXIT_FAILURE);
+
+        /* Check whether our parent died before we were able
+         * to set the death signal */
+        if (getppid() != parent_pid)
+                _exit(EXIT_SUCCESS);
+
+        /* Don't leak fds to the agent */
+        close_all_fds(except, n_except);
+
+        stdout_is_tty = isatty(STDOUT_FILENO);
+        stderr_is_tty = isatty(STDERR_FILENO);
+
+        if (!stdout_is_tty || !stderr_is_tty) {
+                /* Detach from stdout/stderr. and reopen
+                 * /dev/tty for them. This is important to
+                 * ensure that when systemctl is started via
+                 * popen() or a similar call that expects to
+                 * read EOF we actually do generate EOF and
+                 * not delay this indefinitely by because we
+                 * keep an unused copy of stdin around. */
+                fd = open("/dev/tty", O_WRONLY);
+                if (fd < 0) {
+                        log_error("Failed to open /dev/tty: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
+                if (!stdout_is_tty)
+                        dup2(fd, STDOUT_FILENO);
+
+                if (!stderr_is_tty)
+                        dup2(fd, STDERR_FILENO);
+
+                if (fd > 2)
+                        close(fd);
+        }
+
+        /* Count arguments */
+        va_start(ap, path);
+        for (n = 0; va_arg(ap, char*); n++)
+                ;
+        va_end(ap);
+
+        /* Allocate strv */
+        l = alloca(sizeof(char *) * (n + 1));
+
+        /* Fill in arguments */
+        va_start(ap, path);
+        for (i = 0; i <= n; i++)
+                l[i] = va_arg(ap, char*);
+        va_end(ap);
+
+        execv(path, l);
+        _exit(EXIT_FAILURE);
+}
+
+int setrlimit_closest(int resource, const struct rlimit *rlim) {
+        struct rlimit highest, fixed;
+
+        assert(rlim);
+
+        if (setrlimit(resource, rlim) >= 0)
+                return 0;
+
+        if (errno != EPERM)
+                return -errno;
+
+        /* So we failed to set the desired setrlimit, then let's try
+         * to get as close as we can */
+        assert_se(getrlimit(resource, &highest) == 0);
+
+        fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
+        fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
+
+        if (setrlimit(resource, &fixed) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int getenv_for_pid(pid_t pid, const char *field, char **_value) {
+        char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
+        int r;
+        FILE *f;
+        bool done = false;
+        size_t l;
+
+        assert(field);
+        assert(_value);
+
+        if (pid == 0)
+                pid = getpid();
+
+        snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
+        char_array_0(path);
+
+        f = fopen(path, "re");
+        if (!f)
+                return -errno;
+
+        l = strlen(field);
+        r = 0;
+
+        do {
+                char line[LINE_MAX];
+                unsigned i;
+
+                for (i = 0; i < sizeof(line)-1; i++) {
+                        int c;
+
+                        c = getc(f);
+                        if (_unlikely_(c == EOF)) {
+                                done = true;
+                                break;
+                        } else if (c == 0)
+                                break;
+
+                        line[i] = c;
+                }
+                line[i] = 0;
+
+                if (memcmp(line, field, l) == 0 && line[l] == '=') {
+                        value = strdup(line + l + 1);
+                        if (!value) {
+                                r = -ENOMEM;
+                                break;
+                        }
+
+                        r = 1;
+                        break;
+                }
+
+        } while (!done);
+
+        fclose(f);
+
+        if (r >= 0)
+                *_value = value;
+
+        return r;
+}
+
+int can_sleep(const char *type) {
+        char *w, *state;
+        size_t l, k;
+        int r;
+        _cleanup_free_ char *p = NULL;
+
+        assert(type);
+
+        /* If /sys is read-only we cannot sleep */
+        if (access("/sys/power/state", W_OK) < 0)
+                return false;
+
+        r = read_one_line_file("/sys/power/state", &p);
+        if (r < 0)
+                return false;
+
+        k = strlen(type);
+        FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
+                if (l == k && memcmp(w, type, l) == 0)
+                        return true;
+
+        return false;
+}
+
+int can_sleep_disk(const char *type) {
+        char *w, *state;
+        size_t l, k;
+        int r;
+        _cleanup_free_ char *p = NULL;
+
+        assert(type);
+
+        /* If /sys is read-only we cannot sleep */
+        if (access("/sys/power/state", W_OK) < 0 ||
+            access("/sys/power/disk", W_OK) < 0)
+                return false;
+
+        r = read_one_line_file("/sys/power/disk", &p);
+        if (r < 0)
+                return false;
+
+        k = strlen(type);
+        FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
+                if (l == k && memcmp(w, type, l) == 0)
+                        return true;
+
+                if (l == k + 2 && w[0] == '[' && memcmp(w + 1, type, l - 2) == 0 && w[l-1] == ']')
+                        return true;
+        }
+
+        return false;
+}
+
+bool is_valid_documentation_url(const char *url) {
+        assert(url);
+
+        if (startswith(url, "http://") && url[7])
+                return true;
+
+        if (startswith(url, "https://") && url[8])
+                return true;
+
+        if (startswith(url, "file:") && url[5])
+                return true;
+
+        if (startswith(url, "info:") && url[5])
+                return true;
+
+        if (startswith(url, "man:") && url[4])
+                return true;
+
+        return false;
+}
+
+bool in_initrd(void) {
+        static __thread int saved = -1;
+        struct statfs s;
+
+        if (saved >= 0)
+                return saved;
+
+        /* We make two checks here:
+         *
+         * 1. the flag file /etc/initrd-release must exist
+         * 2. the root file system must be a memory file system
+         *
+         * The second check is extra paranoia, since misdetecting an
+         * initrd can have bad bad consequences due the initrd
+         * emptying when transititioning to the main systemd.
+         */
+
+        saved = access("/etc/initrd-release", F_OK) >= 0 &&
+                statfs("/", &s) >= 0 &&
+                is_temporary_fs(&s);
+
+        return saved;
+}
+
+void warn_melody(void) {
+        _cleanup_close_ int fd = -1;
+
+        fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                return;
+
+        /* Yeah, this is synchronous. Kinda sucks. But well... */
+
+        ioctl(fd, KIOCSOUND, (int)(1193180/440));
+        usleep(125*USEC_PER_MSEC);
+
+        ioctl(fd, KIOCSOUND, (int)(1193180/220));
+        usleep(125*USEC_PER_MSEC);
+
+        ioctl(fd, KIOCSOUND, (int)(1193180/220));
+        usleep(125*USEC_PER_MSEC);
+
+        ioctl(fd, KIOCSOUND, 0);
+}
+
+int make_console_stdio(void) {
+        int fd, r;
+
+        /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
+
+        fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
+        if (fd < 0) {
+                log_error("Failed to acquire terminal: %s", strerror(-fd));
+                return fd;
+        }
+
+        r = make_stdio(fd);
+        if (r < 0) {
+                log_error("Failed to duplicate terminal fd: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+int get_home_dir(char **_h) {
+        char *h;
+        const char *e;
+        uid_t u;
+        struct passwd *p;
+
+        assert(_h);
+
+        /* Take the user specified one */
+        e = getenv("HOME");
+        if (e) {
+                h = strdup(e);
+                if (!h)
+                        return -ENOMEM;
+
+                *_h = h;
+                return 0;
+        }
+
+        /* Hardcode home directory for root to avoid NSS */
+        u = getuid();
+        if (u == 0) {
+                h = strdup("/root");
+                if (!h)
+                        return -ENOMEM;
+
+                *_h = h;
+                return 0;
+        }
+
+        /* Check the database... */
+        errno = 0;
+        p = getpwuid(u);
+        if (!p)
+                return errno ? -errno : -ESRCH;
+
+        if (!path_is_absolute(p->pw_dir))
+                return -EINVAL;
+
+        h = strdup(p->pw_dir);
+        if (!h)
+                return -ENOMEM;
+
+        *_h = h;
+        return 0;
+}
+
+int get_shell(char **_sh) {
+        char *sh;
+        const char *e;
+        uid_t u;
+        struct passwd *p;
+
+        assert(_sh);
+
+        /* Take the user specified one */
+        e = getenv("SHELL");
+        if (e) {
+                sh = strdup(e);
+                if (!sh)
+                        return -ENOMEM;
+
+                *_sh = sh;
+                return 0;
+        }
+
+        /* Hardcode home directory for root to avoid NSS */
+        u = getuid();
+        if (u == 0) {
+                sh = strdup("/bin/sh");
+                if (!sh)
+                        return -ENOMEM;
+
+                *_sh = sh;
+                return 0;
+        }
+
+        /* Check the database... */
+        errno = 0;
+        p = getpwuid(u);
+        if (!p)
+                return errno ? -errno : -ESRCH;
+
+        if (!path_is_absolute(p->pw_shell))
+                return -EINVAL;
+
+        sh = strdup(p->pw_shell);
+        if (!sh)
+                return -ENOMEM;
+
+        *_sh = sh;
+        return 0;
+}
+
+void freep(void *p) {
+        free(*(void**) p);
+}
+
+void fclosep(FILE **f) {
+        if (*f)
+                fclose(*f);
+}
+
+void closep(int *fd) {
+        if (*fd >= 0)
+                close_nointr_nofail(*fd);
+}
+
+void closedirp(DIR **d) {
+        if (*d)
+                closedir(*d);
+}
+
+void umaskp(mode_t *u) {
+        umask(*u);
+}
+
+bool filename_is_safe(const char *p) {
+
+        if (isempty(p))
+                return false;
+
+        if (strchr(p, '/'))
+                return false;
+
+        if (streq(p, "."))
+                return false;
+
+        if (streq(p, ".."))
+                return false;
+
+        if (strlen(p) > FILENAME_MAX)
+                return false;
+
+        return true;
+}
+
+bool string_is_safe(const char *p) {
+        const char *t;
+
+        assert(p);
+
+        for (t = p; *t; t++) {
+                if (*t > 0 && *t < ' ')
+                        return false;
+
+                if (strchr("\\\"\'", *t))
+                        return false;
+        }
+
+        return true;
+}
+
+/* hey glibc, APIs with callbacks without a user pointer are so useless */
+void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
+                 int (*compar) (const void *, const void *, void *), void *arg) {
+        size_t l, u, idx;
+        const void *p;
+        int comparison;
+
+        l = 0;
+        u = nmemb;
+        while (l < u) {
+                idx = (l + u) / 2;
+                p = (void *)(((const char *) base) + (idx * size));
+                comparison = compar(key, p, arg);
+                if (comparison < 0)
+                        u = idx;
+                else if (comparison > 0)
+                        l = idx + 1;
+                else
+                        return (void *)p;
+        }
+        return NULL;
+}
+
+bool is_locale_utf8(void) {
+        const char *set;
+        static int cached_answer = -1;
+
+        if (cached_answer >= 0)
+                goto out;
+
+        if (!setlocale(LC_ALL, "")) {
+                cached_answer = true;
+                goto out;
+        }
+
+        set = nl_langinfo(CODESET);
+        if (!set) {
+                cached_answer = true;
+                goto out;
+        }
+
+        cached_answer = streq(set, "UTF-8");
+out:
+        return (bool)cached_answer;
+}
+
+const char *draw_special_char(DrawSpecialChar ch) {
+        static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
+                /* UTF-8 */ {
+                        [DRAW_TREE_VERT]          = "\342\224\202 ",            /* │  */
+                        [DRAW_TREE_BRANCH]        = "\342\224\234\342\224\200", /* ├─ */
+                        [DRAW_TREE_RIGHT]         = "\342\224\224\342\224\200", /* └─ */
+                        [DRAW_TRIANGULAR_BULLET]  = "\342\200\243 ",            /* ‣  */
+                },
+                /* ASCII fallback */ {
+                        [DRAW_TREE_VERT]          = "| ",
+                        [DRAW_TREE_BRANCH]        = "|-",
+                        [DRAW_TREE_RIGHT]         = "`-",
+                        [DRAW_TRIANGULAR_BULLET]  = "> ",
+                }
+        };
+
+        return draw_table[!is_locale_utf8()][ch];
+}
+
+char *strreplace(const char *text, const char *old_string, const char *new_string) {
+        const char *f;
+        char *t, *r;
+        size_t l, old_len, new_len;
+
+        assert(text);
+        assert(old_string);
+        assert(new_string);
+
+        old_len = strlen(old_string);
+        new_len = strlen(new_string);
+
+        l = strlen(text);
+        r = new(char, l+1);
+        if (!r)
+                return NULL;
+
+        f = text;
+        t = r;
+        while (*f) {
+                char *a;
+                size_t d, nl;
+
+                if (!startswith(f, old_string)) {
+                        *(t++) = *(f++);
+                        continue;
+                }
+
+                d = t - r;
+                nl = l - old_len + new_len;
+                a = realloc(r, nl + 1);
+                if (!a)
+                        goto oom;
+
+                l = nl;
+                r = a;
+                t = r + d;
+
+                t = stpcpy(t, new_string);
+                f += old_len;
+        }
+
+        *t = 0;
+        return r;
+
+oom:
+        free(r);
+        return NULL;
+}
+
+char *strip_tab_ansi(char **ibuf, size_t *_isz) {
+        const char *i, *begin = NULL;
+        enum {
+                STATE_OTHER,
+                STATE_ESCAPE,
+                STATE_BRACKET
+        } state = STATE_OTHER;
+        char *obuf = NULL;
+        size_t osz = 0, isz;
+        FILE *f;
+
+        assert(ibuf);
+        assert(*ibuf);
+
+        /* Strips ANSI color and replaces TABs by 8 spaces */
+
+        isz = _isz ? *_isz : strlen(*ibuf);
+
+        f = open_memstream(&obuf, &osz);
+        if (!f)
+                return NULL;
+
+        for (i = *ibuf; i < *ibuf + isz + 1; i++) {
+
+                switch (state) {
+
+                case STATE_OTHER:
+                        if (i >= *ibuf + isz) /* EOT */
+                                break;
+                        else if (*i == '\x1B')
+                                state = STATE_ESCAPE;
+                        else if (*i == '\t')
+                                fputs("        ", f);
+                        else
+                                fputc(*i, f);
+                        break;
+
+                case STATE_ESCAPE:
+                        if (i >= *ibuf + isz) { /* EOT */
+                                fputc('\x1B', f);
+                                break;
+                        } else if (*i == '[') {
+                                state = STATE_BRACKET;
+                                begin = i + 1;
+                        } else {
+                                fputc('\x1B', f);
+                                fputc(*i, f);
+                                state = STATE_OTHER;
+                        }
+
+                        break;
+
+                case STATE_BRACKET:
+
+                        if (i >= *ibuf + isz || /* EOT */
+                            (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
+                                fputc('\x1B', f);
+                                fputc('[', f);
+                                state = STATE_OTHER;
+                                i = begin-1;
+                        } else if (*i == 'm')
+                                state = STATE_OTHER;
+                        break;
+                }
+        }
+
+        if (ferror(f)) {
+                fclose(f);
+                free(obuf);
+                return NULL;
+        }
+
+        fclose(f);
+
+        free(*ibuf);
+        *ibuf = obuf;
+
+        if (_isz)
+                *_isz = osz;
+
+        return obuf;
+}
+
+int on_ac_power(void) {
+        bool found_offline = false, found_online = false;
+        _cleanup_closedir_ DIR *d = NULL;
+
+        d = opendir("/sys/class/power_supply");
+        if (!d)
+                return -errno;
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                _cleanup_free_ char *p = NULL;
+                _cleanup_close_ int fd = -1, device = -1;
+                char contents[6];
+                ssize_t n;
+                int k;
+
+                k = readdir_r(d, &buf.de, &de);
+                if (k != 0)
+                        return -k;
+
+                if (!de)
+                        break;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (device < 0) {
+                        if (errno == ENOENT || errno == ENOTDIR)
+                                continue;
+
+                        return -errno;
+                }
+
+                fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (fd < 0) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        return -errno;
+                }
+
+                n = read(fd, contents, sizeof(contents));
+                if (n < 0)
+                        return -errno;
+
+                if (n != 6 || memcmp(contents, "Mains\n", 6))
+                        continue;
+
+                close_nointr_nofail(fd);
+                fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (fd < 0) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        return -errno;
+                }
+
+                n = read(fd, contents, sizeof(contents));
+                if (n < 0)
+                        return -errno;
+
+                if (n != 2 || contents[1] != '\n')
+                        return -EIO;
+
+                if (contents[0] == '1') {
+                        found_online = true;
+                        break;
+                } else if (contents[0] == '0')
+                        found_offline = true;
+                else
+                        return -EIO;
+        }
+
+        return found_online || !found_offline;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
new file mode 100644 (file)
index 0000000..bb6602f
--- /dev/null
@@ -0,0 +1,565 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <time.h>
+#include <sys/time.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sched.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <sys/resource.h>
+#include <stddef.h>
+
+#include "macro.h"
+#include "time-util.h"
+
+union dirent_storage {
+        struct dirent de;
+        uint8_t storage[offsetof(struct dirent, d_name) +
+                        ((NAME_MAX + 1 + sizeof(long)) & ~(sizeof(long) - 1))];
+};
+
+/* What is interpreted as whitespace? */
+#define WHITESPACE " \t\n\r"
+#define NEWLINE "\n\r"
+#define QUOTES "\"\'"
+#define COMMENTS "#;\n"
+
+#define FORMAT_BYTES_MAX 8
+
+#define ANSI_HIGHLIGHT_ON "\x1B[1;39m"
+#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m"
+#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m"
+#define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m"
+#define ANSI_HIGHLIGHT_OFF "\x1B[0m"
+
+bool is_efiboot(void);
+
+size_t page_size(void);
+#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
+
+#define streq(a,b) (strcmp((a),(b)) == 0)
+#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
+
+bool streq_ptr(const char *a, const char *b);
+
+#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
+
+#define new0(t, n) ((t*) calloc((n), sizeof(t)))
+
+#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
+
+#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
+
+#define malloc0(n) (calloc((n), 1))
+
+static inline const char* yes_no(bool b) {
+        return b ? "yes" : "no";
+}
+
+static inline const char* strempty(const char *s) {
+        return s ? s : "";
+}
+
+static inline const char* strnull(const char *s) {
+        return s ? s : "(null)";
+}
+
+static inline const char *strna(const char *s) {
+        return s ? s : "n/a";
+}
+
+static inline bool isempty(const char *p) {
+        return !p || !p[0];
+}
+
+char *endswith(const char *s, const char *postfix);
+char *startswith(const char *s, const char *prefix);
+char *startswith_no_case(const char *s, const char *prefix);
+
+bool first_word(const char *s, const char *word);
+
+int close_nointr(int fd);
+void close_nointr_nofail(int fd);
+void close_many(const int fds[], unsigned n_fd);
+
+int parse_boolean(const char *v);
+int parse_bytes(const char *t, off_t *bytes);
+int parse_pid(const char *s, pid_t* ret_pid);
+int parse_uid(const char *s, uid_t* ret_uid);
+#define parse_gid(s, ret_uid) parse_uid(s, ret_uid)
+
+int safe_atou(const char *s, unsigned *ret_u);
+int safe_atoi(const char *s, int *ret_i);
+
+int safe_atollu(const char *s, unsigned long long *ret_u);
+int safe_atolli(const char *s, long long int *ret_i);
+
+#if __WORDSIZE == 32
+static inline int safe_atolu(const char *s, unsigned long *ret_u) {
+        assert_cc(sizeof(unsigned long) == sizeof(unsigned));
+        return safe_atou(s, (unsigned*) ret_u);
+}
+static inline int safe_atoli(const char *s, long int *ret_u) {
+        assert_cc(sizeof(long int) == sizeof(int));
+        return safe_atoi(s, (int*) ret_u);
+}
+#else
+static inline int safe_atolu(const char *s, unsigned long *ret_u) {
+        assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
+        return safe_atollu(s, (unsigned long long*) ret_u);
+}
+static inline int safe_atoli(const char *s, long int *ret_u) {
+        assert_cc(sizeof(long int) == sizeof(long long int));
+        return safe_atolli(s, (long long int*) ret_u);
+}
+#endif
+
+static inline int safe_atou32(const char *s, uint32_t *ret_u) {
+        assert_cc(sizeof(uint32_t) == sizeof(unsigned));
+        return safe_atou(s, (unsigned*) ret_u);
+}
+
+static inline int safe_atoi32(const char *s, int32_t *ret_i) {
+        assert_cc(sizeof(int32_t) == sizeof(int));
+        return safe_atoi(s, (int*) ret_i);
+}
+
+static inline int safe_atou64(const char *s, uint64_t *ret_u) {
+        assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
+        return safe_atollu(s, (unsigned long long*) ret_u);
+}
+
+static inline int safe_atoi64(const char *s, int64_t *ret_i) {
+        assert_cc(sizeof(int64_t) == sizeof(long long int));
+        return safe_atolli(s, (long long int*) ret_i);
+}
+
+char *split(const char *c, size_t *l, const char *separator, char **state);
+char *split_quoted(const char *c, size_t *l, char **state);
+
+#define FOREACH_WORD(word, length, s, state)                            \
+        for ((state) = NULL, (word) = split((s), &(length), WHITESPACE, &(state)); (word); (word) = split((s), &(length), WHITESPACE, &(state)))
+
+#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state)       \
+        for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); (word); (word) = split((s), &(length), (separator), &(state)))
+
+#define FOREACH_WORD_QUOTED(word, length, s, state)                     \
+        for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state)))
+
+pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
+int get_starttime_of_pid(pid_t pid, unsigned long long *st);
+
+int write_one_line_file(const char *fn, const char *line);
+int write_one_line_file_atomic(const char *fn, const char *line);
+int read_one_line_file(const char *fn, char **line);
+int read_full_file(const char *fn, char **contents, size_t *size);
+
+int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
+int load_env_file(const char *fname, char ***l);
+int write_env_file(const char *fname, char **l);
+
+char *strappend(const char *s, const char *suffix);
+char *strnappend(const char *s, const char *suffix, size_t length);
+
+char *replace_env(const char *format, char **env);
+char **replace_env_argv(char **argv, char **env);
+
+int readlink_malloc(const char *p, char **r);
+int readlink_and_make_absolute(const char *p, char **r);
+int readlink_and_canonicalize(const char *p, char **r);
+
+int reset_all_signal_handlers(void);
+
+char *strstrip(char *s);
+char *delete_chars(char *s, const char *bad);
+char *truncate_nl(char *s);
+
+char *file_in_same_dir(const char *path, const char *filename);
+
+int rmdir_parents(const char *path, const char *stop);
+
+int get_process_comm(pid_t pid, char **name);
+int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
+int get_process_exe(pid_t pid, char **name);
+int get_process_uid(pid_t pid, uid_t *uid);
+int get_process_gid(pid_t pid, gid_t *gid);
+
+char hexchar(int x);
+int unhexchar(char c);
+char octchar(int x);
+int unoctchar(char c);
+char decchar(int x);
+int undecchar(char c);
+
+char *cescape(const char *s);
+char *cunescape(const char *s);
+char *cunescape_length(const char *s, size_t length);
+char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix);
+
+char *xescape(const char *s, const char *bad);
+
+char *bus_path_escape(const char *s);
+char *bus_path_unescape(const char *s);
+
+char *ascii_strlower(char *path);
+
+bool dirent_is_file(const struct dirent *de);
+bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix);
+
+bool ignore_file(const char *filename);
+
+bool chars_intersect(const char *a, const char *b);
+
+int make_stdio(int fd);
+int make_null_stdio(void);
+int make_console_stdio(void);
+
+unsigned long long random_ull(void);
+
+/* For basic lookup tables with strictly enumerated entries */
+#define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope)                   \
+        scope const char *name##_to_string(type i) {                    \
+                if (i < 0 || i >= (type) ELEMENTSOF(name##_table))      \
+                        return NULL;                                    \
+                return name##_table[i];                                 \
+        }                                                               \
+        scope type name##_from_string(const char *s) {                  \
+                type i;                                                 \
+                assert(s);                                              \
+                for (i = 0; i < (type)ELEMENTSOF(name##_table); i++)    \
+                        if (name##_table[i] &&                          \
+                            streq(name##_table[i], s))                  \
+                                return i;                               \
+                return (type) -1;                                       \
+        }                                                               \
+        struct __useless_struct_to_allow_trailing_semicolon__
+
+#define DEFINE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,static)
+
+/* For string conversions where numbers are also acceptable */
+#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max)         \
+        int name##_to_string_alloc(type i, char **str) {                \
+                char *s;                                                \
+                int r;                                                  \
+                if (i < 0 || i > max)                                   \
+                        return -ERANGE;                                 \
+                if (i < (type) ELEMENTSOF(name##_table)) {              \
+                        s = strdup(name##_table[i]);                    \
+                        if (!s)                                         \
+                                return log_oom();                       \
+                } else {                                                \
+                        r = asprintf(&s, "%u", i);                      \
+                        if (r < 0)                                      \
+                                return log_oom();                       \
+                }                                                       \
+                *str = s;                                               \
+                return 0;                                               \
+        }                                                               \
+        type name##_from_string(const char *s) {                        \
+                type i;                                                 \
+                unsigned u = 0;                                         \
+                assert(s);                                              \
+                for (i = 0; i < (type)ELEMENTSOF(name##_table); i++)    \
+                        if (name##_table[i] &&                          \
+                            streq(name##_table[i], s))                  \
+                                return i;                               \
+                if (safe_atou(s, &u) >= 0 && u <= max)                  \
+                        return (type) u;                                \
+                return (type) -1;                                       \
+        }                                                               \
+        struct __useless_struct_to_allow_trailing_semicolon__
+
+int fd_nonblock(int fd, bool nonblock);
+int fd_cloexec(int fd, bool cloexec);
+
+int close_all_fds(const int except[], unsigned n_except);
+
+bool fstype_is_network(const char *fstype);
+
+int chvt(int vt);
+
+int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
+int ask(char *ret, const char *replies, const char *text, ...);
+
+int reset_terminal_fd(int fd, bool switch_to_text);
+int reset_terminal(const char *name);
+
+int open_terminal(const char *name, int mode);
+int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout);
+int release_terminal(void);
+
+int flush_fd(int fd);
+
+int ignore_signals(int sig, ...);
+int default_signals(int sig, ...);
+int sigaction_many(const struct sigaction *sa, ...);
+
+int close_pipe(int p[]);
+int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
+
+ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
+ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
+
+bool is_device_path(const char *path);
+
+int dir_is_empty(const char *path);
+
+void rename_process(const char name[8]);
+
+void sigset_add_many(sigset_t *ss, ...);
+
+bool hostname_is_set(void);
+
+char* gethostname_malloc(void);
+char* getlogname_malloc(void);
+char* getusername_malloc(void);
+
+int getttyname_malloc(int fd, char **r);
+int getttyname_harder(int fd, char **r);
+
+int get_ctty_devnr(pid_t pid, dev_t *d);
+int get_ctty(pid_t, dev_t *_devnr, char **r);
+
+int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
+int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
+
+int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
+int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
+int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
+int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
+
+int pipe_eof(int fd);
+
+cpu_set_t* cpu_set_malloc(unsigned *ncpus);
+
+int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap);
+int status_printf(const char *status, bool ellipse, const char *format, ...);
+int status_welcome(void);
+
+int fd_columns(int fd);
+unsigned columns(void);
+int fd_lines(int fd);
+unsigned lines(void);
+void columns_lines_cache_reset(int _unused_ signum);
+
+bool on_tty(void);
+
+int running_in_chroot(void);
+
+char *ellipsize(const char *s, size_t length, unsigned percent);
+char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent);
+
+int touch(const char *path);
+
+char *unquote(const char *s, const char *quotes);
+char *normalize_env_assignment(const char *s);
+
+int wait_for_terminate(pid_t pid, siginfo_t *status);
+int wait_for_terminate_and_warn(const char *name, pid_t pid);
+
+_noreturn_ void freeze(void);
+
+bool null_or_empty(struct stat *st);
+int null_or_empty_path(const char *fn);
+
+DIR *xopendirat(int dirfd, const char *name, int flags);
+
+char *fstab_node_to_udev_node(const char *p);
+
+bool tty_is_vc(const char *tty);
+bool tty_is_vc_resolve(const char *tty);
+bool tty_is_console(const char *tty);
+int vtnr_from_tty(const char *tty);
+const char *default_term_for_tty(const char *tty);
+
+void execute_directory(const char *directory, DIR *_d, char *argv[]);
+
+int kill_and_sigcont(pid_t pid, int sig);
+
+bool nulstr_contains(const char*nulstr, const char *needle);
+
+bool plymouth_running(void);
+
+bool hostname_is_valid(const char *s);
+char* hostname_cleanup(char *s);
+
+char* strshorten(char *s, size_t l);
+
+int terminal_vhangup_fd(int fd);
+int terminal_vhangup(const char *name);
+
+int vt_disallocate(const char *name);
+
+int copy_file(const char *from, const char *to);
+
+int symlink_atomic(const char *from, const char *to);
+
+int fchmod_umask(int fd, mode_t mode);
+
+bool display_is_local(const char *display);
+int socket_from_display(const char *display, char **path);
+
+int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
+int get_group_creds(const char **groupname, gid_t *gid);
+
+int in_group(const char *name);
+
+int glob_exists(const char *path);
+
+int dirent_ensure_type(DIR *d, struct dirent *de);
+
+int in_search_path(const char *path, char **search);
+int get_files_in_directory(const char *path, char ***list);
+
+char *strjoin(const char *x, ...) _sentinel_;
+
+bool is_main_thread(void);
+
+bool in_charset(const char *s, const char* charset);
+
+int block_get_whole_disk(dev_t d, dev_t *ret);
+
+int file_is_priv_sticky(const char *p);
+
+int strdup_or_null(const char *a, char **b);
+
+#define NULSTR_FOREACH(i, l)                                    \
+        for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
+
+#define NULSTR_FOREACH_PAIR(i, j, l)                             \
+        for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
+
+int ioprio_class_to_string_alloc(int i, char **s);
+int ioprio_class_from_string(const char *s);
+
+const char *sigchld_code_to_string(int i);
+int sigchld_code_from_string(const char *s);
+
+int log_facility_unshifted_to_string_alloc(int i, char **s);
+int log_facility_unshifted_from_string(const char *s);
+
+int log_level_to_string_alloc(int i, char **s);
+int log_level_from_string(const char *s);
+
+int sched_policy_to_string_alloc(int i, char **s);
+int sched_policy_from_string(const char *s);
+
+const char *rlimit_to_string(int i);
+int rlimit_from_string(const char *s);
+
+int ip_tos_to_string_alloc(int i, char **s);
+int ip_tos_from_string(const char *s);
+
+const char *signal_to_string(int i);
+int signal_from_string(const char *s);
+
+int signal_from_string_try_harder(const char *s);
+
+extern int saved_argc;
+extern char **saved_argv;
+
+bool kexec_loaded(void);
+
+int prot_from_flags(int flags);
+
+char *format_bytes(char *buf, size_t l, off_t t);
+
+int fd_wait_for_event(int fd, int event, usec_t timeout);
+
+void* memdup(const void *p, size_t l) _malloc_;
+
+int is_kernel_thread(pid_t pid);
+
+int fd_inc_sndbuf(int fd, size_t n);
+int fd_inc_rcvbuf(int fd, size_t n);
+
+int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
+
+int setrlimit_closest(int resource, const struct rlimit *rlim);
+
+int getenv_for_pid(pid_t pid, const char *field, char **_value);
+
+int can_sleep(const char *type);
+int can_sleep_disk(const char *type);
+
+bool is_valid_documentation_url(const char *url);
+
+bool in_initrd(void);
+
+void warn_melody(void);
+
+int get_shell(char **ret);
+int get_home_dir(char **ret);
+
+void freep(void *p);
+void fclosep(FILE **f);
+void closep(int *fd);
+void closedirp(DIR **d);
+void umaskp(mode_t *u);
+
+_malloc_  static inline void *malloc_multiply(size_t a, size_t b) {
+        if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
+                return NULL;
+
+        return malloc(a * b);
+}
+
+_malloc_ static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
+        if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
+                return NULL;
+
+        return memdup(p, a * b);
+}
+
+bool filename_is_safe(const char *p);
+bool string_is_safe(const char *p);
+
+void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
+                 int (*compar) (const void *, const void *, void *),
+                 void *arg);
+
+bool is_locale_utf8(void);
+
+typedef enum DrawSpecialChar {
+        DRAW_TREE_VERT,
+        DRAW_TREE_BRANCH,
+        DRAW_TREE_RIGHT,
+        DRAW_TRIANGULAR_BULLET,
+        _DRAW_SPECIAL_CHAR_MAX
+} DrawSpecialChar;
+const char *draw_special_char(DrawSpecialChar ch);
+
+char *strreplace(const char *text, const char *old_string, const char *new_string);
+
+char *strip_tab_ansi(char **p, size_t *l);
+
+int on_ac_power(void);
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
new file mode 100644 (file)
index 0000000..046fb58
--- /dev/null
@@ -0,0 +1,431 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <utmpx.h>
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/poll.h>
+
+#include "macro.h"
+#include "path-util.h"
+#include "utmp-wtmp.h"
+
+int utmp_get_runlevel(int *runlevel, int *previous) {
+        struct utmpx lookup, *found;
+        int r;
+        const char *e;
+
+        assert(runlevel);
+
+        /* If these values are set in the environment this takes
+         * precedence. Presumably, sysvinit does this to work around a
+         * race condition that would otherwise exist where we'd always
+         * go to disk and hence might read runlevel data that might be
+         * very new and does not apply to the current script being
+         * executed. */
+
+        if ((e = getenv("RUNLEVEL")) && e[0] > 0) {
+                *runlevel = e[0];
+
+                if (previous) {
+                        /* $PREVLEVEL seems to be an Upstart thing */
+
+                        if ((e = getenv("PREVLEVEL")) && e[0] > 0)
+                                *previous = e[0];
+                        else
+                                *previous = 0;
+                }
+
+                return 0;
+        }
+
+        if (utmpxname(_PATH_UTMPX) < 0)
+                return -errno;
+
+        setutxent();
+
+        zero(lookup);
+        lookup.ut_type = RUN_LVL;
+
+        if (!(found = getutxid(&lookup)))
+                r = -errno;
+        else {
+                int a, b;
+
+                a = found->ut_pid & 0xFF;
+                b = (found->ut_pid >> 8) & 0xFF;
+
+                if (a < 0 || b < 0)
+                        r = -EIO;
+                else {
+                        *runlevel = a;
+
+                        if (previous)
+                                *previous = b;
+                        r = 0;
+                }
+        }
+
+        endutxent();
+
+        return r;
+}
+
+static void init_timestamp(struct utmpx *store, usec_t t) {
+        assert(store);
+
+        zero(*store);
+
+        if (t <= 0)
+                t = now(CLOCK_REALTIME);
+
+        store->ut_tv.tv_sec = t / USEC_PER_SEC;
+        store->ut_tv.tv_usec = t % USEC_PER_SEC;
+}
+
+static void init_entry(struct utmpx *store, usec_t t) {
+        struct utsname uts;
+
+        assert(store);
+
+        init_timestamp(store, t);
+
+        zero(uts);
+
+        if (uname(&uts) >= 0)
+                strncpy(store->ut_host, uts.release, sizeof(store->ut_host));
+
+        strncpy(store->ut_line, "~", sizeof(store->ut_line));  /* or ~~ ? */
+        strncpy(store->ut_id, "~~", sizeof(store->ut_id));
+}
+
+static int write_entry_utmp(const struct utmpx *store) {
+        int r;
+
+        assert(store);
+
+        /* utmp is similar to wtmp, but there is only one entry for
+         * each entry type resp. user; i.e. basically a key/value
+         * table. */
+
+        if (utmpxname(_PATH_UTMPX) < 0)
+                return -errno;
+
+        setutxent();
+
+        if (!pututxline(store))
+                r = -errno;
+        else
+                r = 0;
+
+        endutxent();
+
+        return r;
+}
+
+static int write_entry_wtmp(const struct utmpx *store) {
+        assert(store);
+
+        /* wtmp is a simple append-only file where each entry is
+        simply appended to * the end; i.e. basically a log. */
+
+        errno = 0;
+        updwtmpx(_PATH_WTMPX, store);
+        return -errno;
+}
+
+static int write_utmp_wtmp(const struct utmpx *store_utmp, const struct utmpx *store_wtmp) {
+        int r, s;
+
+        r = write_entry_utmp(store_utmp);
+        s = write_entry_wtmp(store_wtmp);
+
+        if (r >= 0)
+                r = s;
+
+        /* If utmp/wtmp have been disabled, that's a good thing, hence
+         * ignore the errors */
+        if (r == -ENOENT)
+                r = 0;
+
+        return r;
+}
+
+static int write_entry_both(const struct utmpx *store) {
+        return write_utmp_wtmp(store, store);
+}
+
+int utmp_put_shutdown(void) {
+        struct utmpx store;
+
+        init_entry(&store, 0);
+
+        store.ut_type = RUN_LVL;
+        strncpy(store.ut_user, "shutdown", sizeof(store.ut_user));
+
+        return write_entry_both(&store);
+}
+
+int utmp_put_reboot(usec_t t) {
+        struct utmpx store;
+
+        init_entry(&store, t);
+
+        store.ut_type = BOOT_TIME;
+        strncpy(store.ut_user, "reboot", sizeof(store.ut_user));
+
+        return write_entry_both(&store);
+}
+
+static const char *sanitize_id(const char *id) {
+        size_t l;
+
+        assert(id);
+        l = strlen(id);
+
+        if (l <= sizeof(((struct utmpx*) NULL)->ut_id))
+                return id;
+
+        return id + l - sizeof(((struct utmpx*) NULL)->ut_id);
+}
+
+int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line) {
+        struct utmpx store;
+
+        assert(id);
+
+        init_timestamp(&store, 0);
+
+        store.ut_type = INIT_PROCESS;
+        store.ut_pid = pid;
+        store.ut_session = sid;
+
+        strncpy(store.ut_id, sanitize_id(id), sizeof(store.ut_id));
+
+        if (line)
+                strncpy(store.ut_line, path_get_file_name(line), sizeof(store.ut_line));
+
+        return write_entry_both(&store);
+}
+
+int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
+        struct utmpx lookup, store, store_wtmp, *found;
+
+        assert(id);
+
+        setutxent();
+
+        zero(lookup);
+        lookup.ut_type = INIT_PROCESS; /* looks for DEAD_PROCESS, LOGIN_PROCESS, USER_PROCESS, too */
+        strncpy(lookup.ut_id, sanitize_id(id), sizeof(lookup.ut_id));
+
+        if (!(found = getutxid(&lookup)))
+                return 0;
+
+        if (found->ut_pid != pid)
+                return 0;
+
+        memcpy(&store, found, sizeof(store));
+        store.ut_type = DEAD_PROCESS;
+        store.ut_exit.e_termination = code;
+        store.ut_exit.e_exit = status;
+
+        zero(store.ut_user);
+        zero(store.ut_host);
+        zero(store.ut_tv);
+
+        memcpy(&store_wtmp, &store, sizeof(store_wtmp));
+        /* wtmp wants the current time */
+        init_timestamp(&store_wtmp, 0);
+
+        return write_utmp_wtmp(&store, &store_wtmp);
+}
+
+
+int utmp_put_runlevel(int runlevel, int previous) {
+        struct utmpx store;
+        int r;
+
+        assert(runlevel > 0);
+
+        if (previous <= 0) {
+                /* Find the old runlevel automatically */
+
+                if ((r = utmp_get_runlevel(&previous, NULL)) < 0) {
+                        if (r != -ESRCH)
+                                return r;
+
+                        previous = 0;
+                }
+        }
+
+        if (previous == runlevel)
+                return 0;
+
+        init_entry(&store, 0);
+
+        store.ut_type = RUN_LVL;
+        store.ut_pid = (runlevel & 0xFF) | ((previous & 0xFF) << 8);
+        strncpy(store.ut_user, "runlevel", sizeof(store.ut_user));
+
+        return write_entry_both(&store);
+}
+
+#define TIMEOUT_MSEC 50
+
+static int write_to_terminal(const char *tty, const char *message) {
+        int fd, r;
+        const char *p;
+        size_t left;
+        usec_t end;
+
+        assert(tty);
+        assert(message);
+
+        if ((fd = open(tty, O_WRONLY|O_NDELAY|O_NOCTTY|O_CLOEXEC)) < 0)
+                return -errno;
+
+        if (!isatty(fd)) {
+                r = -errno;
+                goto finish;
+        }
+
+        p = message;
+        left = strlen(message);
+
+        end = now(CLOCK_MONOTONIC) + TIMEOUT_MSEC*USEC_PER_MSEC;
+
+        while (left > 0) {
+                ssize_t n;
+                struct pollfd pollfd;
+                usec_t t;
+                int k;
+
+                t = now(CLOCK_MONOTONIC);
+
+                if (t >= end) {
+                        r = -ETIME;
+                        goto finish;
+                }
+
+                zero(pollfd);
+                pollfd.fd = fd;
+                pollfd.events = POLLOUT;
+
+                if ((k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC)) < 0)
+                        return -errno;
+
+                if (k <= 0) {
+                        r = -ETIME;
+                        goto finish;
+                }
+
+                if ((n = write(fd, p, left)) < 0) {
+
+                        if (errno == EAGAIN)
+                                continue;
+
+                        r = -errno;
+                        goto finish;
+                }
+
+                assert((size_t) n <= left);
+
+                p += n;
+                left -= n;
+        }
+
+        r = 0;
+
+finish:
+        close_nointr_nofail(fd);
+
+        return r;
+}
+
+int utmp_wall(const char *message, bool (*match_tty)(const char *tty)) {
+        struct utmpx *u;
+        char date[FORMAT_TIMESTAMP_MAX];
+        char *text = NULL, *hn = NULL, *un = NULL, *tty = NULL;
+        int r;
+
+        if (!(hn = gethostname_malloc()) ||
+            !(un = getlogname_malloc())) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        getttyname_harder(STDIN_FILENO, &tty);
+
+        if (asprintf(&text,
+                     "\a\r\n"
+                     "Broadcast message from %s@%s%s%s (%s):\r\n\r\n"
+                     "%s\r\n\r\n",
+                     un, hn,
+                     tty ? " on " : "", strempty(tty),
+                     format_timestamp(date, sizeof(date), now(CLOCK_REALTIME)),
+                     message) < 0) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        setutxent();
+
+        r = 0;
+
+        while ((u = getutxent())) {
+                int q;
+                const char *path;
+                char *buf = NULL;
+
+                if (u->ut_type != USER_PROCESS || u->ut_user[0] == 0)
+                        continue;
+
+                if (path_startswith(u->ut_line, "/dev/"))
+                        path = u->ut_line;
+                else {
+                        if (asprintf(&buf, "/dev/%s", u->ut_line) < 0) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        path = buf;
+                }
+
+                if (!match_tty || match_tty(path))
+                        if ((q = write_to_terminal(path, text)) < 0)
+                                r = q;
+
+                free(buf);
+        }
+
+finish:
+        free(hn);
+        free(un);
+        free(tty);
+        free(text);
+
+        return r;
+}
diff --git a/src/shared/utmp-wtmp.h b/src/shared/utmp-wtmp.h
new file mode 100644 (file)
index 0000000..5924023
--- /dev/null
@@ -0,0 +1,35 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+
+int utmp_get_runlevel(int *runlevel, int *previous);
+
+int utmp_put_shutdown(void);
+int utmp_put_reboot(usec_t timestamp);
+int utmp_put_runlevel(int runlevel, int previous);
+
+int utmp_put_dead_process(const char *id, pid_t pid, int code, int status);
+int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line);
+
+int utmp_wall(const char *message, bool (*match_tty)(const char *tty));
diff --git a/src/shared/virt.c b/src/shared/virt.c
new file mode 100644 (file)
index 0000000..fc62c72
--- /dev/null
@@ -0,0 +1,259 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "virt.h"
+
+/* Returns a short identifier for the various VM implementations */
+int detect_vm(const char **id) {
+
+#if defined(__i386__) || defined(__x86_64__)
+
+        /* Both CPUID and DMI are x86 specific interfaces... */
+
+        static const char *const dmi_vendors[] = {
+                "/sys/class/dmi/id/sys_vendor",
+                "/sys/class/dmi/id/board_vendor",
+                "/sys/class/dmi/id/bios_vendor"
+        };
+
+        static const char dmi_vendor_table[] =
+                "QEMU\0"                  "qemu\0"
+                /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
+                "VMware\0"                "vmware\0"
+                "VMW\0"                   "vmware\0"
+                "Microsoft Corporation\0" "microsoft\0"
+                "innotek GmbH\0"          "oracle\0"
+                "Xen\0"                   "xen\0"
+                "Bochs\0"                 "bochs\0";
+
+        static const char cpuid_vendor_table[] =
+                "XenVMMXenVMM\0"          "xen\0"
+                "KVMKVMKVM\0"             "kvm\0"
+                /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
+                "VMwareVMware\0"          "vmware\0"
+                /* http://msdn.microsoft.com/en-us/library/ff542428.aspx */
+                "Microsoft Hv\0"          "microsoft\0";
+
+        uint32_t eax, ecx;
+        union {
+                uint32_t sig32[3];
+                char text[13];
+        } sig;
+        unsigned i;
+        const char *j, *k;
+        bool hypervisor;
+
+        /* http://lwn.net/Articles/301888/ */
+        zero(sig);
+
+#if defined (__i386__)
+#define REG_a "eax"
+#define REG_b "ebx"
+#elif defined (__amd64__)
+#define REG_a "rax"
+#define REG_b "rbx"
+#endif
+
+        /* First detect whether there is a hypervisor */
+        eax = 1;
+        __asm__ __volatile__ (
+                /* ebx/rbx is being used for PIC! */
+                "  push %%"REG_b"         \n\t"
+                "  cpuid                  \n\t"
+                "  pop %%"REG_b"          \n\t"
+
+                : "=a" (eax), "=c" (ecx)
+                : "0" (eax)
+        );
+
+        hypervisor = !!(ecx & 0x80000000U);
+
+        if (hypervisor) {
+
+                /* There is a hypervisor, see what it is */
+                eax = 0x40000000U;
+                __asm__ __volatile__ (
+                        /* ebx/rbx is being used for PIC! */
+                        "  push %%"REG_b"         \n\t"
+                        "  cpuid                  \n\t"
+                        "  mov %%ebx, %1          \n\t"
+                        "  pop %%"REG_b"          \n\t"
+
+                        : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2])
+                        : "0" (eax)
+                );
+
+                NULSTR_FOREACH_PAIR(j, k, cpuid_vendor_table)
+                        if (streq(sig.text, j)) {
+
+                                if (id)
+                                        *id = k;
+
+                                return 1;
+                        }
+        }
+
+        for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) {
+                char *s;
+                int r;
+                const char *found = NULL;
+
+                if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) {
+                        if (r != -ENOENT)
+                                return r;
+
+                        continue;
+                }
+
+                NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table)
+                        if (startswith(s, j))
+                                found = k;
+                free(s);
+
+                if (found) {
+                        if (id)
+                                *id = found;
+
+                        return 1;
+                }
+        }
+
+        if (hypervisor) {
+                if (id)
+                        *id = "other";
+
+                return 1;
+        }
+
+#endif
+        return 0;
+}
+
+int detect_container(const char **id) {
+        char *e = NULL;
+        int r;
+
+        /* Unfortunately many of these operations require root access
+         * in one way or another */
+
+        r = running_in_chroot();
+        if (r < 0)
+                return r;
+        if (r > 0) {
+
+                if (id)
+                        *id = "chroot";
+
+                return 1;
+        }
+
+        /* /proc/vz exists in container and outside of the container,
+         * /proc/bc only outside of the container. */
+        if (access("/proc/vz", F_OK) >= 0 &&
+            access("/proc/bc", F_OK) < 0) {
+
+                if (id)
+                        *id = "openvz";
+
+                return 1;
+        }
+
+        r = getenv_for_pid(1, "container", &e);
+        if (r <= 0)
+                return r;
+
+        /* We only recognize a selected few here, since we want to
+         * enforce a redacted namespace */
+        if (streq(e, "lxc")) {
+                if (id)
+                        *id = "lxc";
+        } else if (streq(e, "lxc-libvirt")) {
+                if (id)
+                        *id = "lxc-libvirt";
+        } else if (streq(e, "systemd-nspawn")) {
+                if (id)
+                        *id = "systemd-nspawn";
+        } else {
+                if (id)
+                        *id = "other";
+        }
+
+        free(e);
+
+        return r;
+}
+
+/* Returns a short identifier for the various VM/container implementations */
+Virtualization detect_virtualization(const char **id) {
+
+        static __thread Virtualization cached_virt = _VIRTUALIZATION_INVALID;
+        static __thread const char *cached_id = NULL;
+
+        const char *_id;
+        int r;
+        Virtualization v;
+
+        if (_likely_(cached_virt >= 0)) {
+
+                if (id && cached_virt > 0)
+                        *id = cached_id;
+
+                return cached_virt;
+        }
+
+        r = detect_container(&_id);
+        if (r < 0) {
+                v = r;
+                goto finish;
+        } else if (r > 0) {
+                v = VIRTUALIZATION_CONTAINER;
+                goto finish;
+        }
+
+        r = detect_vm(&_id);
+        if (r < 0) {
+                v = r;
+                goto finish;
+        } else if (r > 0) {
+                v = VIRTUALIZATION_VM;
+                goto finish;
+        }
+
+        v = VIRTUALIZATION_NONE;
+
+finish:
+        if (v > 0) {
+                cached_id = _id;
+
+                if (id)
+                        *id = _id;
+        }
+
+        if (v >= 0)
+                cached_virt = v;
+
+        return v;
+}
diff --git a/src/shared/virt.h b/src/shared/virt.h
new file mode 100644 (file)
index 0000000..aa6ad35
--- /dev/null
@@ -0,0 +1,35 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int detect_vm(const char **id);
+int detect_container(const char **id);
+
+typedef enum Virtualization {
+        VIRTUALIZATION_NONE = 0,
+        VIRTUALIZATION_VM,
+        VIRTUALIZATION_CONTAINER,
+        _VIRTUALIZATION_MAX,
+        _VIRTUALIZATION_INVALID = -1
+} Virtualization;
+
+Virtualization detect_virtualization(const char **id);
diff --git a/src/shared/watchdog.c b/src/shared/watchdog.c
new file mode 100644 (file)
index 0000000..13265e7
--- /dev/null
@@ -0,0 +1,169 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/watchdog.h>
+
+#include "watchdog.h"
+#include "log.h"
+
+static int watchdog_fd = -1;
+static usec_t watchdog_timeout = (usec_t) -1;
+
+static int update_timeout(void) {
+        int r;
+
+        if (watchdog_fd < 0)
+                return 0;
+
+        if (watchdog_timeout == (usec_t) -1)
+                return 0;
+        else if (watchdog_timeout == 0) {
+                int flags;
+
+                flags = WDIOS_DISABLECARD;
+                r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
+                if (r < 0) {
+                        log_warning("Failed to disable hardware watchdog: %m");
+                        return -errno;
+                }
+        } else {
+                int sec, flags;
+                char buf[FORMAT_TIMESPAN_MAX];
+
+                sec = (int) ((watchdog_timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
+                r = ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec);
+                if (r < 0) {
+                        log_warning("Failed to set timeout to %is: %m", sec);
+                        return -errno;
+                }
+
+                watchdog_timeout = (usec_t) sec * USEC_PER_SEC;
+                log_info("Set hardware watchdog to %s.", format_timespan(buf, sizeof(buf), watchdog_timeout));
+
+                flags = WDIOS_ENABLECARD;
+                r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
+                if (r < 0) {
+                        log_warning("Failed to enable hardware watchdog: %m");
+                        return -errno;
+                }
+
+                r = ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0);
+                if (r < 0) {
+                        log_warning("Failed to ping hardware watchdog: %m");
+                        return -errno;
+                }
+        }
+
+        return 0;
+}
+
+static int open_watchdog(void) {
+        struct watchdog_info ident;
+
+        if (watchdog_fd >= 0)
+                return 0;
+
+        watchdog_fd = open("/dev/watchdog", O_WRONLY|O_CLOEXEC);
+        if (watchdog_fd < 0)
+                return -errno;
+
+        if (ioctl(watchdog_fd, WDIOC_GETSUPPORT, &ident) >= 0)
+                log_info("Hardware watchdog '%s', version %x",
+                         ident.identity,
+                         ident.firmware_version);
+
+        return update_timeout();
+}
+
+int watchdog_set_timeout(usec_t *usec) {
+        int r;
+
+        watchdog_timeout = *usec;
+
+        /* If we didn't open the watchdog yet and didn't get any
+         * explicit timeout value set, don't do anything */
+        if (watchdog_fd < 0 && watchdog_timeout == (usec_t) -1)
+                return 0;
+
+        if (watchdog_fd < 0)
+                r = open_watchdog();
+        else
+                r = update_timeout();
+
+        *usec = watchdog_timeout;
+
+        return r;
+}
+
+int watchdog_ping(void) {
+        int r;
+
+        if (watchdog_fd < 0) {
+                r = open_watchdog();
+                if (r < 0)
+                        return r;
+        }
+
+        r = ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0);
+        if (r < 0) {
+                log_warning("Failed to ping hardware watchdog: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+void watchdog_close(bool disarm) {
+        int r;
+
+        if (watchdog_fd < 0)
+                return;
+
+        if (disarm) {
+                int flags;
+
+                /* Explicitly disarm it */
+                flags = WDIOS_DISABLECARD;
+                r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
+                if (r < 0)
+                        log_warning("Failed to disable hardware watchdog: %m");
+
+                /* To be sure, use magic close logic, too */
+                for (;;) {
+                        static const char v = 'V';
+
+                        if (write(watchdog_fd, &v, 1) > 0)
+                                break;
+
+                        if (errno != EINTR) {
+                                log_error("Failed to disarm watchdog timer: %m");
+                                break;
+                        }
+                }
+        }
+
+        close_nointr_nofail(watchdog_fd);
+        watchdog_fd = -1;
+}
diff --git a/src/shared/watchdog.h b/src/shared/watchdog.h
new file mode 100644 (file)
index 0000000..b748b15
--- /dev/null
@@ -0,0 +1,28 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+
+int watchdog_set_timeout(usec_t *usec);
+int watchdog_ping(void);
+void watchdog_close(bool disarm);
diff --git a/src/shutdownd/Makefile b/src/shutdownd/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/shutdownd/shutdownd.c b/src/shutdownd/shutdownd.c
new file mode 100644 (file)
index 0000000..c074741
--- /dev/null
@@ -0,0 +1,478 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/timerfd.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stddef.h>
+
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-shutdown.h>
+
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+#include "utmp-wtmp.h"
+#include "mkdir.h"
+
+union shutdown_buffer {
+        struct sd_shutdown_command command;
+        char space[offsetof(struct sd_shutdown_command, wall_message) + LINE_MAX];
+};
+
+static int read_packet(int fd, union shutdown_buffer *_b) {
+        struct msghdr msghdr;
+        struct iovec iovec;
+        struct ucred *ucred;
+        union {
+                struct cmsghdr cmsghdr;
+                uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
+        } control;
+        ssize_t n;
+        union shutdown_buffer b; /* We maintain our own copy here, in order not to corrupt the last message */
+
+        assert(fd >= 0);
+        assert(_b);
+
+        zero(iovec);
+        iovec.iov_base = &b;
+        iovec.iov_len = sizeof(b) - 1;
+
+        zero(control);
+        zero(msghdr);
+        msghdr.msg_iov = &iovec;
+        msghdr.msg_iovlen = 1;
+        msghdr.msg_control = &control;
+        msghdr.msg_controllen = sizeof(control);
+
+        n = recvmsg(fd, &msghdr, MSG_DONTWAIT);
+        if (n <= 0) {
+                if (n == 0) {
+                        log_error("Short read");
+                        return -EIO;
+                }
+
+                if (errno == EAGAIN || errno == EINTR)
+                        return 0;
+
+                log_error("recvmsg(): %m");
+                return -errno;
+        }
+
+        if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
+            control.cmsghdr.cmsg_level != SOL_SOCKET ||
+            control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
+            control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
+                log_warning("Received message without credentials. Ignoring.");
+                return 0;
+        }
+
+        ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
+        if (ucred->uid != 0) {
+                log_warning("Got request from unprivileged user. Ignoring.");
+                return 0;
+        }
+
+        if ((size_t) n < offsetof(struct sd_shutdown_command, wall_message)) {
+                log_warning("Message has invalid size. Ignoring.");
+                return 0;
+        }
+
+        if (b.command.mode != SD_SHUTDOWN_NONE &&
+            b.command.mode != SD_SHUTDOWN_REBOOT &&
+            b.command.mode != SD_SHUTDOWN_POWEROFF &&
+            b.command.mode != SD_SHUTDOWN_HALT &&
+            b.command.mode != SD_SHUTDOWN_KEXEC) {
+                log_warning("Message has invalid mode. Ignoring.");
+                return 0;
+        }
+
+        b.space[n] = 0;
+
+        *_b = b;
+        return 1;
+}
+
+static void warn_wall(usec_t n, struct sd_shutdown_command *c) {
+        char date[FORMAT_TIMESTAMP_MAX];
+        const char *prefix;
+        char *l = NULL;
+
+        assert(c);
+        assert(c->warn_wall);
+
+        if (n >= c->usec)
+                return;
+
+        if (c->mode == SD_SHUTDOWN_HALT)
+                prefix = "The system is going down for system halt at ";
+        else if (c->mode == SD_SHUTDOWN_POWEROFF)
+                prefix = "The system is going down for power-off at ";
+        else if (c->mode == SD_SHUTDOWN_REBOOT)
+                prefix = "The system is going down for reboot at ";
+        else if (c->mode == SD_SHUTDOWN_KEXEC)
+                prefix = "The system is going down for kexec reboot at ";
+        else if (c->mode == SD_SHUTDOWN_NONE)
+                prefix = "The system shutdown has been cancelled at ";
+        else
+                assert_not_reached("Unknown mode!");
+
+        if (asprintf(&l, "%s%s%s%s!", c->wall_message, c->wall_message[0] ? "\n" : "",
+                     prefix, format_timestamp(date, sizeof(date), c->usec)) < 0)
+                log_error("Failed to allocate wall message");
+        else {
+                utmp_wall(l, NULL);
+                free(l);
+        }
+}
+
+static usec_t when_wall(usec_t n, usec_t elapse) {
+
+        static const struct {
+                usec_t delay;
+                usec_t interval;
+        } table[] = {
+                { 10 * USEC_PER_MINUTE, USEC_PER_MINUTE      },
+                { USEC_PER_HOUR,        15 * USEC_PER_MINUTE },
+                { 3 * USEC_PER_HOUR,    30 * USEC_PER_MINUTE }
+        };
+
+        usec_t left, sub;
+        unsigned i;
+
+        /* If the time is already passed, then don't announce */
+        if (n >= elapse)
+                return 0;
+
+        left = elapse - n;
+        for (i = 0; i < ELEMENTSOF(table); i++)
+                if (n + table[i].delay >= elapse) {
+                        sub = ((left / table[i].interval) * table[i].interval);
+                        break;
+                }
+
+        if (i >= ELEMENTSOF(table))
+                sub = ((left / USEC_PER_HOUR) * USEC_PER_HOUR);
+
+        return elapse > sub ? elapse - sub : 1;
+}
+
+static usec_t when_nologin(usec_t elapse) {
+        return elapse > 5*USEC_PER_MINUTE ? elapse - 5*USEC_PER_MINUTE : 1;
+}
+
+static const char *mode_to_string(enum sd_shutdown_mode m) {
+        switch (m) {
+        case SD_SHUTDOWN_REBOOT:
+                return "reboot";
+        case SD_SHUTDOWN_POWEROFF:
+                return "poweroff";
+        case SD_SHUTDOWN_HALT:
+                return "halt";
+        case SD_SHUTDOWN_KEXEC:
+                return "kexec";
+        default:
+                return NULL;
+        }
+}
+
+static int update_schedule_file(struct sd_shutdown_command *c) {
+        int r;
+        FILE *f;
+        char *temp_path, *t;
+
+        assert(c);
+
+        r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
+        if (r < 0) {
+                log_error("Failed to create shutdown subdirectory: %s", strerror(-r));
+                return r;
+        }
+
+        t = cescape(c->wall_message);
+        if (!t)
+                return log_oom();
+
+        r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
+        if (r < 0) {
+                log_error("Failed to save information about scheduled shutdowns: %s", strerror(-r));
+                free(t);
+                return r;
+        }
+
+        fchmod(fileno(f), 0644);
+
+        fprintf(f,
+                "USEC=%llu\n"
+                "WARN_WALL=%i\n"
+                "MODE=%s\n",
+                (unsigned long long) c->usec,
+                c->warn_wall,
+                mode_to_string(c->mode));
+
+        if (c->dry_run)
+                fputs("DRY_RUN=1\n", f);
+
+        if (!isempty(t))
+                fprintf(f, "WALL_MESSAGE=%s\n", t);
+
+        free(t);
+
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
+                log_error("Failed to write information about scheduled shutdowns: %m");
+                r = -errno;
+
+                unlink(temp_path);
+                unlink("/run/systemd/shutdown/scheduled");
+        }
+
+        fclose(f);
+        free(temp_path);
+
+        return r;
+}
+
+static bool scheduled(struct sd_shutdown_command *c) {
+        return c->usec > 0 && c->mode != SD_SHUTDOWN_NONE;
+}
+
+int main(int argc, char *argv[]) {
+        enum {
+                FD_SOCKET,
+                FD_WALL_TIMER,
+                FD_NOLOGIN_TIMER,
+                FD_SHUTDOWN_TIMER,
+                _FD_MAX
+        };
+
+        int r = EXIT_FAILURE, n_fds;
+        union shutdown_buffer b;
+        struct pollfd pollfd[_FD_MAX];
+        bool exec_shutdown = false, unlink_nologin = false;
+        unsigned i;
+
+        if (getppid() != 1) {
+                log_error("This program should be invoked by init only.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1) {
+                log_error("This program does not take arguments.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        n_fds = sd_listen_fds(true);
+        if (n_fds < 0) {
+                log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
+                return EXIT_FAILURE;
+        }
+
+        if (n_fds != 1) {
+                log_error("Need exactly one file descriptor.");
+                return EXIT_FAILURE;
+        }
+
+        zero(b);
+        zero(pollfd);
+
+        pollfd[FD_SOCKET].fd = SD_LISTEN_FDS_START;
+        pollfd[FD_SOCKET].events = POLLIN;
+
+        for (i = FD_WALL_TIMER; i < _FD_MAX; i++) {
+                pollfd[i].events = POLLIN;
+                pollfd[i].fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+                if (pollfd[i].fd < 0) {
+                        log_error("timerfd_create(): %m");
+                        goto finish;
+                }
+        }
+
+        log_debug("systemd-shutdownd running as pid %lu", (unsigned long) getpid());
+
+        sd_notify(false,
+                  "READY=1\n"
+                  "STATUS=Processing requests...");
+
+        for (;;) {
+                int k;
+                usec_t n;
+
+                k = poll(pollfd, _FD_MAX, scheduled(&b.command) ? -1 : 0);
+                if (k < 0) {
+
+                        if (errno == EAGAIN || errno == EINTR)
+                                continue;
+
+                        log_error("poll(): %m");
+                        goto finish;
+                }
+
+                /* Exit on idle */
+                if (k == 0)
+                        break;
+
+                n = now(CLOCK_REALTIME);
+
+                if (pollfd[FD_SOCKET].revents) {
+
+                        k = read_packet(pollfd[FD_SOCKET].fd, &b);
+                        if (k < 0)
+                                goto finish;
+                        else if (k > 0) {
+                                struct itimerspec its;
+                                char date[FORMAT_TIMESTAMP_MAX];
+
+                                if (!scheduled(&b.command)) {
+                                        log_info("Shutdown canceled.");
+                                        if (b.command.warn_wall)
+                                                warn_wall(0, &b.command);
+                                        break;
+                                }
+
+                                zero(its);
+                                if (b.command.warn_wall) {
+                                        /* Send wall messages every so often */
+                                        timespec_store(&its.it_value, when_wall(n, b.command.usec));
+
+                                        /* Warn immediately if less than 15 minutes are left */
+                                        if (n < b.command.usec &&
+                                            n + 15*USEC_PER_MINUTE >= b.command.usec)
+                                                warn_wall(n, &b.command);
+                                }
+                                if (timerfd_settime(pollfd[FD_WALL_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
+                                        log_error("timerfd_settime(): %m");
+                                        goto finish;
+                                }
+
+                                /* Disallow logins 5 minutes prior to shutdown */
+                                zero(its);
+                                timespec_store(&its.it_value, when_nologin(b.command.usec));
+                                if (timerfd_settime(pollfd[FD_NOLOGIN_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
+                                        log_error("timerfd_settime(): %m");
+                                        goto finish;
+                                }
+
+                                /* Shutdown after the specified time is reached */
+                                zero(its);
+                                timespec_store(&its.it_value, b.command.usec);
+                                if (timerfd_settime(pollfd[FD_SHUTDOWN_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
+                                        log_error("timerfd_settime(): %m");
+                                        goto finish;
+                                }
+
+                                update_schedule_file(&b.command);
+
+                                sd_notifyf(false,
+                                           "STATUS=Shutting down at %s (%s)...",
+                                           format_timestamp(date, sizeof(date), b.command.usec),
+                                           mode_to_string(b.command.mode));
+
+                                log_info("Shutting down at %s (%s)...", date, mode_to_string(b.command.mode));
+                        }
+                }
+
+                if (pollfd[FD_WALL_TIMER].revents) {
+                        struct itimerspec its;
+
+                        warn_wall(n, &b.command);
+                        flush_fd(pollfd[FD_WALL_TIMER].fd);
+
+                        /* Restart timer */
+                        zero(its);
+                        timespec_store(&its.it_value, when_wall(n, b.command.usec));
+                        if (timerfd_settime(pollfd[FD_WALL_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
+                                log_error("timerfd_settime(): %m");
+                                goto finish;
+                        }
+                }
+
+                if (pollfd[FD_NOLOGIN_TIMER].revents) {
+                        int e;
+
+                        log_info("Creating /run/nologin, blocking further logins...");
+
+                        e = write_one_line_file_atomic("/run/nologin", "System is going down.");
+                        if (e < 0)
+                                log_error("Failed to create /run/nologin: %s", strerror(-e));
+                        else
+                                unlink_nologin = true;
+
+                        flush_fd(pollfd[FD_NOLOGIN_TIMER].fd);
+                }
+
+                if (pollfd[FD_SHUTDOWN_TIMER].revents) {
+                        exec_shutdown = true;
+                        goto finish;
+                }
+        }
+
+        r = EXIT_SUCCESS;
+
+        log_debug("systemd-shutdownd stopped as pid %lu", (unsigned long) getpid());
+
+finish:
+
+        for (i = 0; i < _FD_MAX; i++)
+                if (pollfd[i].fd >= 0)
+                        close_nointr_nofail(pollfd[i].fd);
+
+        if (unlink_nologin)
+                unlink("/run/nologin");
+
+        unlink("/run/systemd/shutdown/scheduled");
+
+        if (exec_shutdown && !b.command.dry_run) {
+                char sw[3];
+
+                sw[0] = '-';
+                sw[1] = b.command.mode;
+                sw[2] = 0;
+
+                execl(SYSTEMCTL_BINARY_PATH,
+                      "shutdown",
+                      sw,
+                      "now",
+                      (b.command.warn_wall && b.command.wall_message[0]) ? b.command.wall_message :
+                      (b.command.warn_wall ? NULL : "--no-wall"),
+                      NULL);
+
+                log_error("Failed to execute /sbin/shutdown: %m");
+        }
+
+        sd_notify(false,
+                  "STATUS=Exiting...");
+
+        return r;
+}
diff --git a/src/sleep/Makefile b/src/sleep/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
new file mode 100644 (file)
index 0000000..218de3a
--- /dev/null
@@ -0,0 +1,127 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include "log.h"
+#include "util.h"
+#include "systemd/sd-id128.h"
+#include "systemd/sd-messages.h"
+
+int main(int argc, char *argv[]) {
+        const char *verb;
+        char* arguments[4];
+        int r;
+        FILE *f;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        if (argc != 2) {
+                log_error("Invalid number of arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        if (streq(argv[1], "suspend"))
+                verb = "mem";
+        else if (streq(argv[1], "hibernate") || streq(argv[1], "hybrid-sleep"))
+                verb = "disk";
+        else {
+                log_error("Unknown action '%s'.", argv[1]);
+                r = -EINVAL;
+                goto finish;
+        }
+
+        /* Configure the hibernation mode */
+        if (streq(argv[1], "hibernate")) {
+                if (write_one_line_file("/sys/power/disk", "platform") < 0)
+                        write_one_line_file("/sys/power/disk", "shutdown");
+        } else if (streq(argv[1], "hybrid-sleep")) {
+                if (write_one_line_file("/sys/power/disk", "suspend") < 0)
+                        if (write_one_line_file("/sys/power/disk", "platform") < 0)
+                                write_one_line_file("/sys/power/disk", "shutdown");
+        }
+
+        f = fopen("/sys/power/state", "we");
+        if (!f) {
+                log_error("Failed to open /sys/power/state: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        arguments[0] = NULL;
+        arguments[1] = (char*) "pre";
+        arguments[2] = argv[1];
+        arguments[3] = NULL;
+        execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments);
+
+        if (streq(argv[1], "suspend"))
+                log_struct(LOG_INFO,
+                           MESSAGE_ID(SD_MESSAGE_SLEEP_START),
+                           "MESSAGE=Suspending system...",
+                           "SLEEP=suspend",
+                           NULL);
+        else if (streq(argv[1], "hibernate"))
+                log_struct(LOG_INFO,
+                           MESSAGE_ID(SD_MESSAGE_SLEEP_START),
+                           "MESSAGE=Hibernating system...",
+                           "SLEEP=hibernate",
+                           NULL);
+        else
+                log_struct(LOG_INFO,
+                           MESSAGE_ID(SD_MESSAGE_SLEEP_START),
+                           "MESSAGE=Hibernating and suspending system...",
+                           "SLEEP=hybrid-sleep",
+                           NULL);
+
+        fputs(verb, f);
+        fputc('\n', f);
+        fflush(f);
+
+        r = ferror(f) ? -errno : 0;
+
+        if (streq(argv[1], "suspend"))
+                log_struct(LOG_INFO,
+                           MESSAGE_ID(SD_MESSAGE_SLEEP_STOP),
+                           "MESSAGE=System resumed.",
+                           "SLEEP=suspend",
+                           NULL);
+        else
+                log_struct(LOG_INFO,
+                           MESSAGE_ID(SD_MESSAGE_SLEEP_STOP),
+                           "MESSAGE=System thawed.",
+                           "SLEEP=hibernate",
+                           NULL);
+
+        arguments[1] = (char*) "post";
+        execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments);
+
+        fclose(f);
+
+finish:
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+}
diff --git a/src/stdio-bridge/Makefile b/src/stdio-bridge/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c
new file mode 100644 (file)
index 0000000..f926fe5
--- /dev/null
@@ -0,0 +1,367 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/epoll.h>
+#include <stddef.h>
+
+#include "log.h"
+#include "util.h"
+#include "socket-util.h"
+
+#define BUFFER_SIZE (64*1024)
+#define EXTRA_SIZE 16
+
+static bool initial_nul = false;
+static bool auth_over = false;
+
+static void format_uid(char *buf, size_t l) {
+        char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
+        unsigned j;
+
+        assert(l > 0);
+
+        snprintf(text, sizeof(text)-1, "%llu", (unsigned long long) geteuid());
+        text[sizeof(text)-1] = 0;
+
+        memset(buf, 0, l);
+
+        for (j = 0; text[j] && j*2+2 < l; j++) {
+                buf[j*2]   = hexchar(text[j] >> 4);
+                buf[j*2+1] = hexchar(text[j] & 0xF);
+        }
+
+        buf[j*2] = 0;
+}
+
+static size_t patch_in_line(char *line, size_t l, size_t left) {
+        size_t r;
+
+        if (line[0] == 0 && !initial_nul) {
+                initial_nul = true;
+                line += 1;
+                l -= 1;
+                r = 1;
+        } else
+                r = 0;
+
+        if (l == 5 && strncmp(line, "BEGIN", 5) == 0) {
+                r += l;
+                auth_over = true;
+
+        } else if (l == 17 && strncmp(line, "NEGOTIATE_UNIX_FD", 17) == 0) {
+                memmove(line + 13, line + 17, left);
+                memcpy(line, "NEGOTIATE_NOP", 13);
+                r += 13;
+
+        } else if (l >= 14 && strncmp(line, "AUTH EXTERNAL ", 14) == 0) {
+                char uid[20*2 + 1];
+                size_t len;
+
+                format_uid(uid, sizeof(uid));
+                len = strlen(uid);
+                assert(len <= EXTRA_SIZE);
+
+                memmove(line + 14 + len, line + l, left);
+                memcpy(line + 14, uid, len);
+
+                r += 14 + len;
+        } else
+                r += l;
+
+        return r;
+}
+
+static size_t patch_in_buffer(char* in_buffer, size_t *in_buffer_full) {
+        size_t i, good = 0;
+
+        if (*in_buffer_full <= 0)
+                return *in_buffer_full;
+
+        /* If authentication is done, we don't touch anything anymore */
+        if (auth_over)
+                return *in_buffer_full;
+
+        if (*in_buffer_full < 2)
+                return 0;
+
+        for (i = 0; i <= *in_buffer_full - 2; i ++) {
+
+                /* Fully lines can be send on */
+                if (in_buffer[i] == '\r' && in_buffer[i+1] == '\n') {
+                        if (i > good) {
+                                size_t old_length, new_length;
+
+                                old_length = i - good;
+                                new_length = patch_in_line(in_buffer+good, old_length, *in_buffer_full - i);
+                                *in_buffer_full = *in_buffer_full + new_length - old_length;
+
+                                good += new_length + 2;
+
+                        } else
+                                good = i+2;
+                }
+
+                if (auth_over)
+                        break;
+        }
+
+        return good;
+}
+
+int main(int argc, char *argv[]) {
+        int r = EXIT_FAILURE, fd = -1, ep = -1;
+        union sockaddr_union sa;
+        char in_buffer[BUFFER_SIZE+EXTRA_SIZE], out_buffer[BUFFER_SIZE+EXTRA_SIZE];
+        size_t in_buffer_full = 0, out_buffer_full = 0;
+        struct epoll_event stdin_ev, stdout_ev, fd_ev;
+        bool stdin_readable = false, stdout_writable = false, fd_readable = false, fd_writable = false;
+        bool stdin_rhup = false, stdout_whup = false, fd_rhup = false, fd_whup = false;
+
+        if (argc > 1) {
+                log_error("This program takes no argument.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+        log_parse_environment();
+        log_open();
+
+        if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
+                log_error("Failed to create socket: %s", strerror(errno));
+                goto finish;
+        }
+
+        zero(sa);
+        sa.un.sun_family = AF_UNIX;
+        strncpy(sa.un.sun_path, "/run/dbus/system_bus_socket", sizeof(sa.un.sun_path));
+
+        if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+                log_error("Failed to connect: %m");
+                goto finish;
+        }
+
+        fd_nonblock(STDIN_FILENO, 1);
+        fd_nonblock(STDOUT_FILENO, 1);
+
+        if ((ep = epoll_create1(EPOLL_CLOEXEC)) < 0) {
+                log_error("Failed to create epoll: %m");
+                goto finish;
+        }
+
+        zero(stdin_ev);
+        stdin_ev.events = EPOLLIN|EPOLLET;
+        stdin_ev.data.fd = STDIN_FILENO;
+
+        zero(stdout_ev);
+        stdout_ev.events = EPOLLOUT|EPOLLET;
+        stdout_ev.data.fd = STDOUT_FILENO;
+
+        zero(fd_ev);
+        fd_ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
+        fd_ev.data.fd = fd;
+
+        if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 ||
+            epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 ||
+            epoll_ctl(ep, EPOLL_CTL_ADD, fd, &fd_ev) < 0) {
+                log_error("Failed to regiser fds in epoll: %m");
+                goto finish;
+        }
+
+        do {
+                struct epoll_event ev[16];
+                ssize_t k;
+                int i, nfds;
+
+                if ((nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1)) < 0) {
+
+                        if (errno == EINTR || errno == EAGAIN)
+                                continue;
+
+                        log_error("epoll_wait(): %m");
+                        goto finish;
+                }
+
+                assert(nfds >= 1);
+
+                for (i = 0; i < nfds; i++) {
+                        if (ev[i].data.fd == STDIN_FILENO) {
+
+                                if (!stdin_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN)))
+                                        stdin_readable = true;
+
+                        } else if (ev[i].data.fd == STDOUT_FILENO) {
+
+                                if (ev[i].events & EPOLLHUP) {
+                                        stdout_writable = false;
+                                        stdout_whup = true;
+                                }
+
+                                if (!stdout_whup && (ev[i].events & EPOLLOUT))
+                                        stdout_writable = true;
+
+                        } else if (ev[i].data.fd == fd) {
+
+                                if (ev[i].events & EPOLLHUP) {
+                                        fd_writable = false;
+                                        fd_whup = true;
+                                }
+
+                                if (!fd_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN)))
+                                        fd_readable = true;
+
+                                if (!fd_whup && (ev[i].events & EPOLLOUT))
+                                        fd_writable = true;
+                        }
+                }
+
+                while ((stdin_readable && in_buffer_full <= 0) ||
+                       (fd_writable && patch_in_buffer(in_buffer, &in_buffer_full) > 0) ||
+                       (fd_readable && out_buffer_full <= 0) ||
+                       (stdout_writable && out_buffer_full > 0)) {
+
+                        size_t in_buffer_good = 0;
+
+                        if (stdin_readable && in_buffer_full < BUFFER_SIZE) {
+
+                                if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) {
+
+                                        if (errno == EAGAIN)
+                                                stdin_readable = false;
+                                        else if (errno == EPIPE || errno == ECONNRESET)
+                                                k = 0;
+                                        else {
+                                                log_error("read(): %m");
+                                                goto finish;
+                                        }
+                                } else
+                                        in_buffer_full += (size_t) k;
+
+                                if (k == 0) {
+                                        stdin_rhup = true;
+                                        stdin_readable = false;
+                                        shutdown(STDIN_FILENO, SHUT_RD);
+                                        close_nointr_nofail(STDIN_FILENO);
+                                }
+                        }
+
+                        in_buffer_good = patch_in_buffer(in_buffer, &in_buffer_full);
+
+                        if (fd_writable && in_buffer_good > 0) {
+
+                                if ((k = write(fd, in_buffer, in_buffer_good)) < 0) {
+
+                                        if (errno == EAGAIN)
+                                                fd_writable = false;
+                                        else if (errno == EPIPE || errno == ECONNRESET) {
+                                                fd_whup = true;
+                                                fd_writable = false;
+                                                shutdown(fd, SHUT_WR);
+                                        } else {
+                                                log_error("write(): %m");
+                                                goto finish;
+                                        }
+
+                                } else {
+                                        assert(in_buffer_full >= (size_t) k);
+                                        memmove(in_buffer, in_buffer + k, in_buffer_full - k);
+                                        in_buffer_full -= k;
+                                }
+                        }
+
+                        if (fd_readable && out_buffer_full < BUFFER_SIZE) {
+
+                                if ((k = read(fd, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) {
+
+                                        if (errno == EAGAIN)
+                                                fd_readable = false;
+                                        else if (errno == EPIPE || errno == ECONNRESET)
+                                                k = 0;
+                                        else {
+                                                log_error("read(): %m");
+                                                goto finish;
+                                        }
+                                }  else
+                                        out_buffer_full += (size_t) k;
+
+                                if (k == 0) {
+                                        fd_rhup = true;
+                                        fd_readable = false;
+                                        shutdown(fd, SHUT_RD);
+                                }
+                        }
+
+                        if (stdout_writable && out_buffer_full > 0) {
+
+                                if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) {
+
+                                        if (errno == EAGAIN)
+                                                stdout_writable = false;
+                                        else if (errno == EPIPE || errno == ECONNRESET) {
+                                                stdout_whup = true;
+                                                stdout_writable = false;
+                                                shutdown(STDOUT_FILENO, SHUT_WR);
+                                                close_nointr(STDOUT_FILENO);
+                                        } else {
+                                                log_error("write(): %m");
+                                                goto finish;
+                                        }
+
+                                } else {
+                                        assert(out_buffer_full >= (size_t) k);
+                                        memmove(out_buffer, out_buffer + k, out_buffer_full - k);
+                                        out_buffer_full -= k;
+                                }
+                        }
+                }
+
+                if (stdin_rhup && in_buffer_full <= 0 && !fd_whup) {
+                        fd_whup = true;
+                        fd_writable = false;
+                        shutdown(fd, SHUT_WR);
+                }
+
+                if (fd_rhup && out_buffer_full <= 0 && !stdout_whup) {
+                        stdout_whup = true;
+                        stdout_writable = false;
+                        shutdown(STDOUT_FILENO, SHUT_WR);
+                        close_nointr(STDOUT_FILENO);
+                }
+
+        } while (!stdout_whup || !fd_whup);
+
+        r = EXIT_SUCCESS;
+
+finish:
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        if (ep >= 0)
+                close_nointr_nofail(ep);
+
+        return r;
+}
diff --git a/src/sysctl/Makefile b/src/sysctl/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
new file mode 100644 (file)
index 0000000..035e0ec
--- /dev/null
@@ -0,0 +1,336 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <limits.h>
+#include <getopt.h>
+
+#include "log.h"
+#include "strv.h"
+#include "util.h"
+#include "strv.h"
+#include "hashmap.h"
+#include "path-util.h"
+#include "conf-files.h"
+
+#define PROC_SYS_PREFIX "/proc/sys/"
+
+static char **arg_prefixes;
+static Hashmap *sysctl_options;
+
+static int apply_sysctl(const char *property, const char *value) {
+        char *p, *n;
+        int r = 0, k;
+
+        log_debug("Setting '%s' to '%s'", property, value);
+
+        p = new(char, sizeof(PROC_SYS_PREFIX) + strlen(property));
+        if (!p)
+                return log_oom();
+
+        n = stpcpy(p, PROC_SYS_PREFIX);
+        strcpy(n, property);
+
+        for (; *n; n++)
+                if (*n == '.')
+                        *n = '/';
+
+        if (!strv_isempty(arg_prefixes)) {
+                char **i;
+                bool good = false;
+
+                STRV_FOREACH(i, arg_prefixes)
+                        if (path_startswith(p, *i)) {
+                                good = true;
+                                break;
+                        }
+
+                if (!good) {
+                        log_debug("Skipping %s", p);
+                        free(p);
+                        return 0;
+                }
+        }
+
+        k = write_one_line_file(p, value);
+        if (k < 0) {
+
+                log_full(k == -ENOENT ? LOG_DEBUG : LOG_WARNING,
+                         "Failed to write '%s' to '%s': %s", value, p, strerror(-k));
+
+                if (k != -ENOENT && r == 0)
+                        r = k;
+        }
+
+        free(p);
+
+        return r;
+}
+
+static int apply_all(void) {
+        int r = 0;
+        char *property, *value;
+        Iterator i;
+
+        HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) {
+                int k;
+
+                k = apply_sysctl(property, value);
+                if (k < 0 && r == 0)
+                        r = k;
+        }
+        return r;
+}
+
+static int parse_file(const char *path, bool ignore_enoent) {
+        FILE *f;
+        int r = 0;
+
+        assert(path);
+
+        f = fopen(path, "re");
+        if (!f) {
+                if (ignore_enoent && errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open file '%s', ignoring: %m", path);
+                return -errno;
+        }
+
+        log_debug("parse: %s\n", path);
+        while (!feof(f)) {
+                char l[LINE_MAX], *p, *value, *new_value, *property;
+
+                if (!fgets(l, sizeof(l), f)) {
+                        if (feof(f))
+                                break;
+
+                        log_error("Failed to read file '%s', ignoring: %m", path);
+                        r = -errno;
+                        goto finish;
+                }
+
+                p = strstrip(l);
+
+                if (!*p)
+                        continue;
+
+                if (strchr(COMMENTS, *p))
+                        continue;
+
+                value = strchr(p, '=');
+                if (!value) {
+                        log_error("Line is not an assignment in file '%s': %s", path, value);
+
+                        if (r == 0)
+                                r = -EINVAL;
+                        continue;
+                }
+
+                *value = 0;
+                value++;
+
+                property = strdup(strstrip(p));
+                if (!property) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                new_value = strdup(strstrip(value));
+                if (!new_value) {
+                        free(property);
+                        r = log_oom();
+                        goto finish;
+                }
+
+                r = hashmap_put(sysctl_options, property, new_value);
+                if (r < 0) {
+                        if (r == -EEXIST) {
+                                /* ignore this "error" to avoid returning it
+                                 * for the function when this is the last key
+                                 * in the file being parsed. */
+                                r = 0;
+                                log_debug("Skipping previously assigned sysctl variable %s", property);
+                        } else
+                                log_error("Failed to add sysctl variable %s to hashmap: %s", property, strerror(-r));
+
+                        free(property);
+                        free(new_value);
+                        if (r != 0)
+                                goto finish;
+                }
+        }
+
+finish:
+        fclose(f);
+
+        return r;
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
+               "Applies kernel sysctl settings.\n\n"
+               "  -h --help             Show this help\n"
+               "     --prefix=PATH      Only apply rules that apply to paths with the specified prefix\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_PREFIX
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "prefix",    required_argument, NULL, ARG_PREFIX    },
+                { NULL,        0,                 NULL, 0             }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_PREFIX: {
+                        char *p;
+                        char **l;
+
+                        for (p = optarg; *p; p++)
+                                if (*p == '.')
+                                        *p = '/';
+
+                        l = strv_append(arg_prefixes, optarg);
+                        if (!l)
+                                return log_oom();
+
+                        strv_free(arg_prefixes);
+                        arg_prefixes = l;
+
+                        break;
+                }
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r = 0, k;
+        char *property, *value;
+        Iterator it;
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        sysctl_options = hashmap_new(string_hash_func, string_compare_func);
+        if (!sysctl_options) {
+                r = log_oom();
+                goto finish;
+        }
+
+        r = 0;
+
+        if (argc > optind) {
+                int i;
+
+                for (i = optind; i < argc; i++) {
+                        k = parse_file(argv[i], false);
+                        if (k < 0)
+                                r = k;
+                }
+        } else {
+                char **files, **f;
+
+                r = conf_files_list(&files, ".conf",
+                                    "/etc/sysctl.d",
+                                    "/run/sysctl.d",
+                                    "/usr/local/lib/sysctl.d",
+                                    "/usr/lib/sysctl.d",
+#ifdef HAVE_SPLIT_USR
+                                    "/lib/sysctl.d",
+#endif
+                                    NULL);
+                if (r < 0) {
+                        log_error("Failed to enumerate sysctl.d files: %s", strerror(-r));
+                        goto finish;
+                }
+
+                /* We parse the files in decreasing order of precedence.
+                 * parse_file() will skip keys that were already assigned. */
+
+                r = parse_file("/etc/sysctl.conf", true);
+
+                f = files + strv_length(files) - 1;
+                STRV_FOREACH_BACKWARDS(f, files) {
+                        k = parse_file(*f, true);
+                        if (k < 0)
+                                r = k;
+                }
+
+                strv_free(files);
+        }
+
+        k = apply_all();
+        if (k < 0)
+                r = k;
+
+finish:
+        HASHMAP_FOREACH_KEY(value, property, sysctl_options, it) {
+                hashmap_remove(sysctl_options, property);
+                free(property);
+                free(value);
+        }
+        hashmap_free(sysctl_options);
+
+        strv_free(arg_prefixes);
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/system-update-generator/Makefile b/src/system-update-generator/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/system-update-generator/system-update-generator.c b/src/system-update-generator/system-update-generator.c
new file mode 100644 (file)
index 0000000..6660192
--- /dev/null
@@ -0,0 +1,84 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+#include "unit-name.h"
+#include "path-util.h"
+
+/*
+ * Implements the logic described in
+ * http://freedesktop.org/wiki/Software/systemd/SystemUpdates
+ */
+
+static const char *arg_dest = "/tmp";
+
+static int generate_symlink(void) {
+        struct stat st;
+        char *p;
+
+        if (lstat("/system-update", &st) < 0) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to check for system update: %m");
+                return -EINVAL;
+        }
+
+        p = strappend(arg_dest, "/default.target");
+        if (!p)
+                return log_oom();
+
+        if (symlink(SYSTEM_DATA_UNIT_PATH "/system-update.target", p) < 0) {
+                free(p);
+                log_error("Failed to create symlink: %m");
+                return -errno;
+        }
+
+        free(p);
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        if (argc > 1 && argc != 4) {
+                log_error("This program takes three or no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1)
+                arg_dest = argv[2];
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        r = generate_symlink();
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/systemctl/Makefile b/src/systemctl/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
new file mode 100644 (file)
index 0000000..2ebfff8
--- /dev/null
@@ -0,0 +1,5430 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/reboot.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <sys/prctl.h>
+#include <dbus/dbus.h>
+
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-shutdown.h>
+
+#include "log.h"
+#include "util.h"
+#include "macro.h"
+#include "set.h"
+#include "utmp-wtmp.h"
+#include "special.h"
+#include "initreq.h"
+#include "path-util.h"
+#include "strv.h"
+#include "dbus-common.h"
+#include "cgroup-show.h"
+#include "cgroup-util.h"
+#include "list.h"
+#include "path-lookup.h"
+#include "conf-parser.h"
+#include "exit-status.h"
+#include "bus-errors.h"
+#include "build.h"
+#include "unit-name.h"
+#include "pager.h"
+#include "spawn-ask-password-agent.h"
+#include "spawn-polkit-agent.h"
+#include "install.h"
+#include "logs-show.h"
+#include "path-util.h"
+#include "socket-util.h"
+
+static const char *arg_type = NULL;
+static const char *arg_load_state = NULL;
+static char **arg_property = NULL;
+static bool arg_all = false;
+static const char *arg_job_mode = "replace";
+static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
+static bool arg_no_block = false;
+static bool arg_no_legend = false;
+static bool arg_no_pager = false;
+static bool arg_no_wtmp = false;
+static bool arg_no_wall = false;
+static bool arg_no_reload = false;
+static bool arg_dry = false;
+static bool arg_quiet = false;
+static bool arg_full = false;
+static int arg_force = 0;
+static bool arg_ask_password = true;
+static bool arg_failed = false;
+static bool arg_runtime = false;
+static char **arg_wall = NULL;
+static const char *arg_kill_who = NULL;
+static int arg_signal = SIGTERM;
+static const char *arg_root = NULL;
+static usec_t arg_when = 0;
+static enum action {
+        ACTION_INVALID,
+        ACTION_SYSTEMCTL,
+        ACTION_HALT,
+        ACTION_POWEROFF,
+        ACTION_REBOOT,
+        ACTION_KEXEC,
+        ACTION_EXIT,
+        ACTION_SUSPEND,
+        ACTION_HIBERNATE,
+        ACTION_HYBRID_SLEEP,
+        ACTION_RUNLEVEL2,
+        ACTION_RUNLEVEL3,
+        ACTION_RUNLEVEL4,
+        ACTION_RUNLEVEL5,
+        ACTION_RESCUE,
+        ACTION_EMERGENCY,
+        ACTION_DEFAULT,
+        ACTION_RELOAD,
+        ACTION_REEXEC,
+        ACTION_RUNLEVEL,
+        ACTION_CANCEL_SHUTDOWN,
+        _ACTION_MAX
+} arg_action = ACTION_SYSTEMCTL;
+static enum dot {
+        DOT_ALL,
+        DOT_ORDER,
+        DOT_REQUIRE
+} arg_dot = DOT_ALL;
+static enum transport {
+        TRANSPORT_NORMAL,
+        TRANSPORT_SSH,
+        TRANSPORT_POLKIT
+} arg_transport = TRANSPORT_NORMAL;
+static const char *arg_host = NULL;
+static unsigned arg_lines = 10;
+static OutputMode arg_output = OUTPUT_SHORT;
+
+static bool private_bus = false;
+
+static int daemon_reload(DBusConnection *bus, char **args);
+static void halt_now(enum action a);
+
+static void pager_open_if_enabled(void) {
+
+        if (arg_no_pager)
+                return;
+
+        pager_open();
+}
+
+static void ask_password_agent_open_if_enabled(void) {
+
+        /* Open the password agent as a child process if necessary */
+
+        if (!arg_ask_password)
+                return;
+
+        if (arg_scope != UNIT_FILE_SYSTEM)
+                return;
+
+        ask_password_agent_open();
+}
+
+#ifdef HAVE_LOGIND
+static void polkit_agent_open_if_enabled(void) {
+
+        /* Open the polkit agent as a child process if necessary */
+
+        if (!arg_ask_password)
+                return;
+
+        if (arg_scope != UNIT_FILE_SYSTEM)
+                return;
+
+        polkit_agent_open();
+}
+#endif
+
+static const char *ansi_highlight(bool b) {
+
+        if (!on_tty())
+                return "";
+
+        return b ? ANSI_HIGHLIGHT_ON : ANSI_HIGHLIGHT_OFF;
+}
+
+static const char *ansi_highlight_red(bool b) {
+
+        if (!on_tty())
+                return "";
+
+        return b ? ANSI_HIGHLIGHT_RED_ON : ANSI_HIGHLIGHT_OFF;
+}
+
+static const char *ansi_highlight_green(bool b) {
+
+        if (!on_tty())
+                return "";
+
+        return b ? ANSI_HIGHLIGHT_GREEN_ON : ANSI_HIGHLIGHT_OFF;
+}
+
+static int translate_bus_error_to_exit_status(int r, const DBusError *error) {
+        assert(error);
+
+        if (!dbus_error_is_set(error))
+                return r;
+
+        if (dbus_error_has_name(error, DBUS_ERROR_ACCESS_DENIED) ||
+            dbus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
+            dbus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
+            dbus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
+                return EXIT_NOPERMISSION;
+
+        if (dbus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
+                return EXIT_NOTINSTALLED;
+
+        if (dbus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
+            dbus_error_has_name(error, BUS_ERROR_NOT_SUPPORTED))
+                return EXIT_NOTIMPLEMENTED;
+
+        if (dbus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
+                return EXIT_NOTCONFIGURED;
+
+        if (r != 0)
+                return r;
+
+        return EXIT_FAILURE;
+}
+
+static void warn_wall(enum action a) {
+        static const char *table[_ACTION_MAX] = {
+                [ACTION_HALT]            = "The system is going down for system halt NOW!",
+                [ACTION_REBOOT]          = "The system is going down for reboot NOW!",
+                [ACTION_POWEROFF]        = "The system is going down for power-off NOW!",
+                [ACTION_KEXEC]           = "The system is going down for kexec reboot NOW!",
+                [ACTION_RESCUE]          = "The system is going down to rescue mode NOW!",
+                [ACTION_EMERGENCY]       = "The system is going down to emergency mode NOW!",
+                [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
+        };
+
+        if (arg_no_wall)
+                return;
+
+        if (arg_wall) {
+                char *p;
+
+                p = strv_join(arg_wall, " ");
+                if (!p) {
+                        log_error("Failed to join strings.");
+                        return;
+                }
+
+                if (*p) {
+                        utmp_wall(p, NULL);
+                        free(p);
+                        return;
+                }
+
+                free(p);
+        }
+
+        if (!table[a])
+                return;
+
+        utmp_wall(table[a], NULL);
+}
+
+static bool avoid_bus(void) {
+
+        if (running_in_chroot() > 0)
+                return true;
+
+        if (sd_booted() <= 0)
+                return true;
+
+        if (!isempty(arg_root))
+                return true;
+
+        if (arg_scope == UNIT_FILE_GLOBAL)
+                return true;
+
+        return false;
+}
+
+struct unit_info {
+        const char *id;
+        const char *description;
+        const char *load_state;
+        const char *active_state;
+        const char *sub_state;
+        const char *following;
+        const char *unit_path;
+        uint32_t job_id;
+        const char *job_type;
+        const char *job_path;
+};
+
+static int compare_unit_info(const void *a, const void *b) {
+        const char *d1, *d2;
+        const struct unit_info *u = a, *v = b;
+
+        d1 = strrchr(u->id, '.');
+        d2 = strrchr(v->id, '.');
+
+        if (d1 && d2) {
+                int r;
+
+                if ((r = strcasecmp(d1, d2)) != 0)
+                        return r;
+        }
+
+        return strcasecmp(u->id, v->id);
+}
+
+static bool output_show_unit(const struct unit_info *u) {
+        const char *dot;
+
+        if (arg_failed)
+                return streq(u->active_state, "failed");
+
+        return (!arg_type || ((dot = strrchr(u->id, '.')) &&
+                              streq(dot+1, arg_type))) &&
+                (!arg_load_state || streq(u->load_state, arg_load_state)) &&
+                (arg_all || !(streq(u->active_state, "inactive")
+                              || u->following[0]) || u->job_id > 0);
+}
+
+static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
+        unsigned id_len, max_id_len, active_len, sub_len, job_len, desc_len, n_shown = 0;
+        const struct unit_info *u;
+        int job_count = 0;
+
+        max_id_len = sizeof("UNIT")-1;
+        active_len = sizeof("ACTIVE")-1;
+        sub_len = sizeof("SUB")-1;
+        job_len = sizeof("JOB")-1;
+        desc_len = 0;
+
+        for (u = unit_infos; u < unit_infos + c; u++) {
+                if (!output_show_unit(u))
+                        continue;
+
+                max_id_len = MAX(max_id_len, strlen(u->id));
+                active_len = MAX(active_len, strlen(u->active_state));
+                sub_len = MAX(sub_len, strlen(u->sub_state));
+                if (u->job_id != 0) {
+                        job_len = MAX(job_len, strlen(u->job_type));
+                        job_count++;
+                }
+        }
+
+        if (!arg_full) {
+                unsigned basic_len;
+                id_len = MIN(max_id_len, 25);
+                basic_len = 5 + id_len + 5 + active_len + sub_len;
+                if (job_count)
+                        basic_len += job_len + 1;
+                if (basic_len < (unsigned) columns()) {
+                        unsigned extra_len, incr;
+                        extra_len = columns() - basic_len;
+                        /* Either UNIT already got 25, or is fully satisfied.
+                         * Grant up to 25 to DESC now. */
+                        incr = MIN(extra_len, 25);
+                        desc_len += incr;
+                        extra_len -= incr;
+                        /* split the remaining space between UNIT and DESC,
+                         * but do not give UNIT more than it needs. */
+                        if (extra_len > 0) {
+                                incr = MIN(extra_len / 2, max_id_len - id_len);
+                                id_len += incr;
+                                desc_len += extra_len - incr;
+                        }
+                }
+        } else
+                id_len = max_id_len;
+
+        for (u = unit_infos; u < unit_infos + c; u++) {
+                char *e;
+                const char *on_loaded, *off_loaded;
+                const char *on_active, *off_active;
+
+                if (!output_show_unit(u))
+                        continue;
+
+                if (!n_shown && !arg_no_legend) {
+                        printf("%-*s %-6s %-*s %-*s ", id_len, "UNIT", "LOAD",
+                               active_len, "ACTIVE", sub_len, "SUB");
+                        if (job_count)
+                                printf("%-*s ", job_len, "JOB");
+                        if (!arg_full && arg_no_pager)
+                                printf("%.*s\n", desc_len, "DESCRIPTION");
+                        else
+                                printf("%s\n", "DESCRIPTION");
+                }
+
+                n_shown++;
+
+                if (streq(u->load_state, "error")) {
+                        on_loaded = ansi_highlight_red(true);
+                        off_loaded = ansi_highlight_red(false);
+                } else
+                        on_loaded = off_loaded = "";
+
+                if (streq(u->active_state, "failed")) {
+                        on_active = ansi_highlight_red(true);
+                        off_active = ansi_highlight_red(false);
+                } else
+                        on_active = off_active = "";
+
+                e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
+
+                printf("%-*s %s%-6s%s %s%-*s %-*s%s %-*s",
+                       id_len, e ? e : u->id,
+                       on_loaded, u->load_state, off_loaded,
+                       on_active, active_len, u->active_state,
+                       sub_len, u->sub_state, off_active,
+                       job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
+                if (!arg_full && arg_no_pager)
+                        printf("%.*s\n", desc_len, u->description);
+                else
+                        printf("%s\n", u->description);
+
+                free(e);
+        }
+
+        if (!arg_no_legend) {
+                const char *on, *off;
+
+                if (n_shown) {
+                        printf("\nLOAD   = Reflects whether the unit definition was properly loaded.\n"
+                               "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
+                               "SUB    = The low-level unit activation state, values depend on unit type.\n");
+                        if (job_count)
+                                printf("JOB    = Pending job for the unit.\n");
+                        puts("");
+                        on = ansi_highlight(true);
+                        off = ansi_highlight(false);
+                } else {
+                        on = ansi_highlight_red(true);
+                        off = ansi_highlight_red(false);
+                }
+
+                if (arg_all)
+                        printf("%s%u loaded units listed.%s\n"
+                               "To show all installed unit files use 'systemctl list-unit-files'.\n",
+                               on, n_shown, off);
+                else
+                        printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
+                               "To show all installed unit files use 'systemctl list-unit-files'.\n",
+                               on, n_shown, off);
+        }
+}
+
+static int list_units(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        int r;
+        DBusMessageIter iter, sub, sub2;
+        unsigned c = 0, n_units = 0;
+        struct unit_info *unit_infos = NULL;
+
+        pager_open_if_enabled();
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "ListUnits",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                struct unit_info *u;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if (c >= n_units) {
+                        struct unit_info *w;
+
+                        n_units = MAX(2*c, 16);
+                        w = realloc(unit_infos, sizeof(struct unit_info) * n_units);
+
+                        if (!w) {
+                                log_error("Failed to allocate unit array.");
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        unit_infos = w;
+                }
+
+                u = unit_infos+c;
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->id, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->description, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->load_state, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->active_state, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->sub_state, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->following, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &u->unit_path, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &u->job_id, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->job_type, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &u->job_path, false) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_next(&sub);
+                c++;
+        }
+
+        if (c > 0) {
+                qsort(unit_infos, c, sizeof(struct unit_info), compare_unit_info);
+                output_units_list(unit_infos, c);
+        }
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        free(unit_infos);
+
+        return r;
+}
+
+static int compare_unit_file_list(const void *a, const void *b) {
+        const char *d1, *d2;
+        const UnitFileList *u = a, *v = b;
+
+        d1 = strrchr(u->path, '.');
+        d2 = strrchr(v->path, '.');
+
+        if (d1 && d2) {
+                int r;
+
+                r = strcasecmp(d1, d2);
+                if (r != 0)
+                        return r;
+        }
+
+        return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
+}
+
+static bool output_show_unit_file(const UnitFileList *u) {
+        const char *dot;
+
+        return !arg_type || ((dot = strrchr(u->path, '.')) && streq(dot+1, arg_type));
+}
+
+static void output_unit_file_list(const UnitFileList *units, unsigned c) {
+        unsigned max_id_len, id_cols, state_cols, n_shown = 0;
+        const UnitFileList *u;
+
+        max_id_len = sizeof("UNIT FILE")-1;
+        state_cols = sizeof("STATE")-1;
+        for (u = units; u < units + c; u++) {
+                if (!output_show_unit_file(u))
+                        continue;
+
+                max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
+                state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
+        }
+
+        if (!arg_full) {
+                unsigned basic_cols;
+                id_cols = MIN(max_id_len, 25);
+                basic_cols = 1 + id_cols + state_cols;
+                if (basic_cols < (unsigned) columns())
+                        id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
+        } else
+                id_cols = max_id_len;
+
+        if (!arg_no_legend)
+                printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE");
+
+        for (u = units; u < units + c; u++) {
+                char *e;
+                const char *on, *off;
+                const char *id;
+
+                if (!output_show_unit_file(u))
+                        continue;
+
+                n_shown++;
+
+                if (u->state == UNIT_FILE_MASKED ||
+                    u->state == UNIT_FILE_MASKED_RUNTIME ||
+                    u->state == UNIT_FILE_DISABLED ||
+                    u->state == UNIT_FILE_INVALID) {
+                        on  = ansi_highlight_red(true);
+                        off = ansi_highlight_red(false);
+                } else if (u->state == UNIT_FILE_ENABLED) {
+                        on  = ansi_highlight_green(true);
+                        off = ansi_highlight_green(false);
+                } else
+                        on = off = "";
+
+                id = path_get_file_name(u->path);
+
+                e = arg_full ? NULL : ellipsize(id, id_cols, 33);
+
+                printf("%-*s %s%-*s%s\n",
+                       id_cols, e ? e : id,
+                       on, state_cols, unit_file_state_to_string(u->state), off);
+
+                free(e);
+        }
+
+        if (!arg_no_legend)
+                printf("\n%u unit files listed.\n", n_shown);
+}
+
+static int list_unit_files(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        int r;
+        DBusMessageIter iter, sub, sub2;
+        unsigned c = 0, n_units = 0;
+        UnitFileList *units = NULL;
+
+        pager_open_if_enabled();
+
+        if (avoid_bus()) {
+                Hashmap *h;
+                UnitFileList *u;
+                Iterator i;
+
+                h = hashmap_new(string_hash_func, string_compare_func);
+                if (!h)
+                        return log_oom();
+
+                r = unit_file_get_list(arg_scope, arg_root, h);
+                if (r < 0) {
+                        unit_file_list_free(h);
+                        log_error("Failed to get unit file list: %s", strerror(-r));
+                        return r;
+                }
+
+                n_units = hashmap_size(h);
+                units = new(UnitFileList, n_units);
+                if (!units) {
+                        unit_file_list_free(h);
+                        return log_oom();
+                }
+
+                HASHMAP_FOREACH(u, h, i) {
+                        memcpy(units + c++, u, sizeof(UnitFileList));
+                        free(u);
+                }
+
+                hashmap_free(h);
+        } else {
+                r = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "ListUnitFiles",
+                                &reply,
+                                NULL,
+                                DBUS_TYPE_INVALID);
+                if (r)
+                        goto finish;
+
+                if (!dbus_message_iter_init(reply, &iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+                    dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&iter, &sub);
+
+                while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                        UnitFileList *u;
+                        const char *state;
+
+                        if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                                log_error("Failed to parse reply.");
+                                r = -EIO;
+                                goto finish;
+                        }
+
+                        if (c >= n_units) {
+                                UnitFileList *w;
+
+                                n_units = MAX(2*c, 16);
+                                w = realloc(units, sizeof(struct UnitFileList) * n_units);
+
+                                if (!w) {
+                                        log_error("Failed to allocate unit array.");
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                units = w;
+                        }
+
+                        u = units+c;
+
+                        dbus_message_iter_recurse(&sub, &sub2);
+
+                        if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->path, true) < 0 ||
+                            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &state, false) < 0) {
+                                log_error("Failed to parse reply.");
+                                r = -EIO;
+                                goto finish;
+                        }
+
+                        u->state = unit_file_state_from_string(state);
+
+                        dbus_message_iter_next(&sub);
+                        c++;
+                }
+        }
+
+        if (c > 0) {
+                qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
+                output_unit_file_list(units, c);
+        }
+
+        r = 0;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        free(units);
+
+        return r;
+}
+
+static int dot_one_property(const char *name, const char *prop, DBusMessageIter *iter) {
+        static const char * const colors[] = {
+                "Requires",              "[color=\"black\"]",
+                "RequiresOverridable",   "[color=\"black\"]",
+                "Requisite",             "[color=\"darkblue\"]",
+                "RequisiteOverridable",  "[color=\"darkblue\"]",
+                "Wants",                 "[color=\"grey66\"]",
+                "Conflicts",             "[color=\"red\"]",
+                "ConflictedBy",          "[color=\"red\"]",
+                "After",                 "[color=\"green\"]"
+        };
+
+        const char *c = NULL;
+        unsigned i;
+
+        assert(name);
+        assert(prop);
+        assert(iter);
+
+        for (i = 0; i < ELEMENTSOF(colors); i += 2)
+                if (streq(colors[i], prop)) {
+                        c = colors[i+1];
+                        break;
+                }
+
+        if (!c)
+                return 0;
+
+        if (arg_dot != DOT_ALL)
+                if ((arg_dot == DOT_ORDER) != streq(prop, "After"))
+                        return 0;
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_ARRAY:
+
+                if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) {
+                        DBusMessageIter sub;
+
+                        dbus_message_iter_recurse(iter, &sub);
+
+                        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                const char *s;
+
+                                assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
+                                dbus_message_iter_get_basic(&sub, &s);
+                                printf("\t\"%s\"->\"%s\" %s;\n", name, s, c);
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+                }
+        }
+
+        return 0;
+}
+
+static int dot_one(DBusConnection *bus, const char *name, const char *path) {
+        DBusMessage *reply = NULL;
+        const char *interface = "org.freedesktop.systemd1.Unit";
+        int r;
+        DBusMessageIter iter, sub, sub2, sub3;
+
+        assert(path);
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *prop;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &prop, true) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)  {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub2, &sub3);
+
+                if (dot_one_property(name, prop, &sub3)) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_next(&sub);
+        }
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int dot(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        int r;
+        DBusMessageIter iter, sub, sub2;
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "ListUnits",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        printf("digraph systemd {\n");
+
+        dbus_message_iter_recurse(&iter, &sub);
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *id, *description, *load_state, *active_state, *sub_state, *following, *unit_path;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &description, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &load_state, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &active_state, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &sub_state, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &following, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &unit_path, true) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if ((r = dot_one(bus, id, unit_path)) < 0)
+                        goto finish;
+
+                /* printf("\t\"%s\";\n", id); */
+                dbus_message_iter_next(&sub);
+        }
+
+        printf("}\n");
+
+        log_info("   Color legend: black     = Requires\n"
+                 "                 dark blue = Requisite\n"
+                 "                 dark grey = Wants\n"
+                 "                 red       = Conflicts\n"
+                 "                 green     = After\n");
+
+        if (on_tty())
+                log_notice("-- You probably want to process this output with graphviz' dot tool.\n"
+                           "-- Try a shell pipeline like 'systemctl dot | dot -Tsvg > systemd.svg'!\n");
+
+        r = 0;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int list_jobs(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        int r;
+        DBusMessageIter iter, sub, sub2;
+        unsigned k = 0;
+
+        pager_open_if_enabled();
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "ListJobs",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (on_tty())
+                printf("%4s %-25s %-15s %-7s\n", "JOB", "UNIT", "TYPE", "STATE");
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *name, *type, *state, *job_path, *unit_path;
+                uint32_t id;
+                char *e;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &id, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &state, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &job_path, true) < 0 ||
+                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &unit_path, false) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                e = arg_full ? NULL : ellipsize(name, 25, 33);
+                printf("%4u %-25s %-15s %-7s\n", id, e ? e : name, type, state);
+                free(e);
+
+                k++;
+
+                dbus_message_iter_next(&sub);
+        }
+
+        if (on_tty())
+                printf("\n%u jobs listed.\n", k);
+
+        r = 0;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int load_unit(DBusConnection *bus, char **args) {
+        int r = 0;
+        char **name, *n;
+
+        assert(args);
+
+        STRV_FOREACH(name, args+1) {
+                n = unit_name_mangle(*name);
+                r = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "LoadUnit",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_STRING, n ? &n : name,
+                                DBUS_TYPE_INVALID);
+                free(n);
+                if (r)
+                        goto finish;
+        }
+
+finish:
+        return r;
+}
+
+static int cancel_job(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        int r = 0;
+        char **name;
+
+        assert(args);
+
+        if (strv_length(args) <= 1)
+                return daemon_reload(bus, args);
+
+        STRV_FOREACH(name, args+1) {
+                unsigned id;
+                const char *path;
+
+                r = safe_atou(*name, &id);
+                if (r < 0) {
+                        log_error("Failed to parse job id: %s", strerror(-r));
+                        goto finish;
+                }
+                assert_cc(sizeof(uint32_t) == sizeof(id));
+
+                r = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "GetJob",
+                                &reply,
+                                NULL,
+                                DBUS_TYPE_UINT32, &id,
+                                DBUS_TYPE_INVALID);
+                if (r)
+                        goto finish;
+
+                if (!dbus_message_get_args(reply, NULL,
+                                           DBUS_TYPE_OBJECT_PATH, &path,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse reply");
+                        dbus_message_unref(reply);
+                        r = -EIO;
+                        goto finish;
+                }
+                dbus_message_unref(reply);
+
+                r = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.systemd1",
+                                path,
+                                "org.freedesktop.systemd1.Job",
+                                "Cancel",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_INVALID);
+                if (r)
+                        goto finish;
+        }
+
+finish:
+        return r;
+}
+
+static bool need_daemon_reload(DBusConnection *bus, const char *unit) {
+        DBusMessage *reply = NULL;
+        dbus_bool_t b = FALSE;
+        DBusMessageIter iter, sub;
+        const char
+                *interface = "org.freedesktop.systemd1.Unit",
+                *property = "NeedDaemonReload",
+                *path;
+        char *n;
+        int r;
+
+        /* We ignore all errors here, since this is used to show a warning only */
+
+        n = unit_name_mangle(unit);
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "GetUnit",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, n ? (const char**) &n : &unit,
+                        DBUS_TYPE_INVALID);
+        free(n);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_get_args(reply, NULL,
+                                   DBUS_TYPE_OBJECT_PATH, &path,
+                                   DBUS_TYPE_INVALID))
+                goto finish;
+
+        dbus_message_unref(reply);
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.DBus.Properties",
+                        "Get",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_STRING, &property,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+                goto finish;
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
+                goto finish;
+
+        dbus_message_iter_get_basic(&sub, &b);
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return b;
+}
+
+typedef struct WaitData {
+        Set *set;
+
+        char *name;
+        char *result;
+} WaitData;
+
+static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *message, void *data) {
+        DBusError error;
+        WaitData *d = data;
+
+        assert(connection);
+        assert(message);
+        assert(d);
+
+        dbus_error_init(&error);
+
+        log_debug("Got D-Bus request: %s.%s() on %s",
+                  dbus_message_get_interface(message),
+                  dbus_message_get_member(message),
+                  dbus_message_get_path(message));
+
+        if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
+                log_error("Warning! D-Bus connection terminated.");
+                dbus_connection_close(connection);
+
+        } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
+                uint32_t id;
+                const char *path, *result, *unit;
+                dbus_bool_t success = true;
+
+                if (dbus_message_get_args(message, &error,
+                                          DBUS_TYPE_UINT32, &id,
+                                          DBUS_TYPE_OBJECT_PATH, &path,
+                                          DBUS_TYPE_STRING, &unit,
+                                          DBUS_TYPE_STRING, &result,
+                                          DBUS_TYPE_INVALID)) {
+                        char *p;
+
+                        p = set_remove(d->set, (char*) path);
+                        free(p);
+
+                        if (!isempty(result))
+                                d->result = strdup(result);
+
+                        if (!isempty(unit))
+                                d->name = strdup(unit);
+
+                        goto finish;
+                }
+#ifndef LEGACY
+                dbus_error_free(&error);
+                if (dbus_message_get_args(message, &error,
+                                          DBUS_TYPE_UINT32, &id,
+                                          DBUS_TYPE_OBJECT_PATH, &path,
+                                          DBUS_TYPE_STRING, &result,
+                                          DBUS_TYPE_INVALID)) {
+                        char *p;
+
+                        /* Compatibility with older systemd versions <
+                         * 183 during upgrades. This should be dropped
+                         * one day. */
+                        p = set_remove(d->set, (char*) path);
+                        free(p);
+
+                        if (*result)
+                                d->result = strdup(result);
+
+                        goto finish;
+                }
+
+                dbus_error_free(&error);
+                if (dbus_message_get_args(message, &error,
+                                          DBUS_TYPE_UINT32, &id,
+                                          DBUS_TYPE_OBJECT_PATH, &path,
+                                          DBUS_TYPE_BOOLEAN, &success,
+                                          DBUS_TYPE_INVALID)) {
+                        char *p;
+
+                        /* Compatibility with older systemd versions <
+                         * 19 during upgrades. This should be dropped
+                         * one day */
+
+                        p = set_remove(d->set, (char*) path);
+                        free(p);
+
+                        if (!success)
+                                d->result = strdup("failed");
+
+                        goto finish;
+                }
+#endif
+
+                log_error("Failed to parse message: %s", bus_error_message(&error));
+        }
+
+finish:
+        dbus_error_free(&error);
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static int enable_wait_for_jobs(DBusConnection *bus) {
+        DBusError error;
+
+        assert(bus);
+
+        if (private_bus)
+                return 0;
+
+        dbus_error_init(&error);
+        dbus_bus_add_match(bus,
+                           "type='signal',"
+                           "sender='org.freedesktop.systemd1',"
+                           "interface='org.freedesktop.systemd1.Manager',"
+                           "member='JobRemoved',"
+                           "path='/org/freedesktop/systemd1'",
+                           &error);
+
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to add match: %s", bus_error_message(&error));
+                dbus_error_free(&error);
+                return -EIO;
+        }
+
+        /* This is slightly dirty, since we don't undo the match registrations. */
+        return 0;
+}
+
+static int wait_for_jobs(DBusConnection *bus, Set *s) {
+        int r = 0;
+        WaitData d;
+
+        assert(bus);
+        assert(s);
+
+        zero(d);
+        d.set = s;
+
+        if (!dbus_connection_add_filter(bus, wait_filter, &d, NULL))
+                return log_oom();
+
+        while (!set_isempty(s)) {
+
+                if (!dbus_connection_read_write_dispatch(bus, -1)) {
+                        log_error("Disconnected from bus.");
+                        return -ECONNREFUSED;
+                }
+
+                if (!d.result)
+                        goto free_name;
+
+                if (!arg_quiet) {
+                        if (streq(d.result, "timeout"))
+                                log_error("Job for %s timed out.", strna(d.name));
+                        else if (streq(d.result, "canceled"))
+                                log_error("Job for %s canceled.", strna(d.name));
+                        else if (streq(d.result, "dependency"))
+                                log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
+                        else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
+                                log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
+                }
+
+                if (streq_ptr(d.result, "timeout"))
+                        r = -ETIME;
+                else if (streq_ptr(d.result, "canceled"))
+                        r = -ECANCELED;
+                else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
+                        r = -EIO;
+
+                free(d.result);
+                d.result = NULL;
+
+        free_name:
+                free(d.name);
+                d.name = NULL;
+        }
+
+        dbus_connection_remove_filter(bus, wait_filter, &d);
+        return r;
+}
+
+static int check_one_unit(DBusConnection *bus, char *name, char **check_states, bool quiet) {
+        DBusMessage *reply = NULL;
+        DBusMessageIter iter, sub;
+        const char
+                *interface = "org.freedesktop.systemd1.Unit",
+                *property = "ActiveState";
+        const char *path = NULL;
+        const char *state;
+        int r;
+        char *n;
+
+        assert(name);
+
+        n = unit_name_mangle(name);
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "GetUnit",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, n ? &n : &name,
+                        DBUS_TYPE_INVALID);
+        free(n);
+        if (r) {
+                if ((r != -ENOMEM) && (!quiet))
+                        puts("unknown");
+                goto finish;
+        }
+
+        if (!dbus_message_get_args(reply, NULL,
+                                   DBUS_TYPE_OBJECT_PATH, &path,
+                                   DBUS_TYPE_INVALID)) {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_unref(reply);
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.DBus.Properties",
+                        "Get",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_STRING, &property,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_get_basic(&sub, &state);
+
+        if (!quiet)
+                puts(state);
+
+        if (strv_find(check_states, state))
+                r = 0;
+        else
+                r = 3; /* According to LSB: "program is not running" */
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static void check_triggering_units(
+                DBusConnection *bus,
+                const char *unit_name) {
+
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        DBusMessageIter iter, sub;
+        char *service_trigger = NULL;
+        const char *interface = "org.freedesktop.systemd1.Unit",
+                   *triggered_by_property = "TriggeredBy";
+
+        char _cleanup_free_ *unit_path = NULL, *n = NULL;
+        bool print_warning_label = true;
+        int r;
+
+        n = unit_name_mangle(unit_name);
+        if (!n) {
+                log_oom();
+                return;
+        }
+
+        unit_path = unit_dbus_path_from_name(n);
+        if (!unit_path) {
+                log_oom();
+                return;
+        }
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        unit_path,
+                        "org.freedesktop.DBus.Properties",
+                        "Get",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_STRING, &triggered_by_property,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                return;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
+                log_error("Failed to parse reply.");
+                return;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+        dbus_message_iter_recurse(&sub, &iter);
+        sub = iter;
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                char **check_states = NULL;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
+                        log_error("Failed to parse reply.");
+                        return;
+                }
+
+                dbus_message_iter_get_basic(&sub, &service_trigger);
+
+                check_states = strv_new("active", "reloading", NULL);
+                r = check_one_unit(bus, service_trigger, check_states, true);
+                strv_free(check_states);
+                if (r < 0)
+                        return;
+                if (r == 0) {
+                        if (print_warning_label) {
+                                log_warning("Warning: Stopping %s, but it can still be activated by:", unit_name);
+                                print_warning_label = false;
+                        }
+                        log_warning("  %s", service_trigger);
+                }
+
+                dbus_message_iter_next(&sub);
+        }
+}
+
+static int start_unit_one(
+                DBusConnection *bus,
+                const char *method,
+                const char *name,
+                const char *mode,
+                DBusError *error,
+                Set *s) {
+
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        const char *path;
+        int r;
+        _cleanup_free_ char *n, *p = NULL;
+
+        assert(method);
+        assert(name);
+        assert(mode);
+        assert(error);
+
+        n = unit_name_mangle(name);
+        if (!n)
+                return log_oom();
+
+        r = bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        method,
+                        &reply,
+                        error,
+                        DBUS_TYPE_STRING, &n,
+                        DBUS_TYPE_STRING, &mode,
+                        DBUS_TYPE_INVALID);
+        if (r) {
+                if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
+                        /* There's always a fallback possible for
+                         * legacy actions. */
+                        r = -EADDRNOTAVAIL;
+                else
+                        log_error("Failed to issue method call: %s", bus_error_message(error));
+
+                return r;
+        }
+
+        if (!dbus_message_get_args(reply, error,
+                                   DBUS_TYPE_OBJECT_PATH, &path,
+                                   DBUS_TYPE_INVALID)) {
+                log_error("Failed to parse reply: %s", bus_error_message(error));
+                return -EIO;
+        }
+
+        if (need_daemon_reload(bus, n))
+                log_warning("Warning: Unit file of %s changed on disk, 'systemctl %s daemon-reload' recommended.",
+                            n, arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user");
+
+        if (s) {
+                p = strdup(path);
+                if (!p)
+                        return log_oom();
+
+                r = set_put(s, p);
+                if (r < 0) {
+                        log_error("Failed to add path to set.");
+                        return r;
+                }
+
+                p = NULL;
+        }
+
+        return 0;
+}
+
+static enum action verb_to_action(const char *verb) {
+        if (streq(verb, "halt"))
+                return ACTION_HALT;
+        else if (streq(verb, "poweroff"))
+                return ACTION_POWEROFF;
+        else if (streq(verb, "reboot"))
+                return ACTION_REBOOT;
+        else if (streq(verb, "kexec"))
+                return ACTION_KEXEC;
+        else if (streq(verb, "rescue"))
+                return ACTION_RESCUE;
+        else if (streq(verb, "emergency"))
+                return ACTION_EMERGENCY;
+        else if (streq(verb, "default"))
+                return ACTION_DEFAULT;
+        else if (streq(verb, "exit"))
+                return ACTION_EXIT;
+        else if (streq(verb, "suspend"))
+                return ACTION_SUSPEND;
+        else if (streq(verb, "hibernate"))
+                return ACTION_HIBERNATE;
+        else if (streq(verb, "hybrid-sleep"))
+                return ACTION_HYBRID_SLEEP;
+        else
+                return ACTION_INVALID;
+}
+
+static int start_unit(DBusConnection *bus, char **args) {
+
+        static const char * const table[_ACTION_MAX] = {
+                [ACTION_HALT] = SPECIAL_HALT_TARGET,
+                [ACTION_POWEROFF] = SPECIAL_POWEROFF_TARGET,
+                [ACTION_REBOOT] = SPECIAL_REBOOT_TARGET,
+                [ACTION_KEXEC] = SPECIAL_KEXEC_TARGET,
+                [ACTION_RUNLEVEL2] = SPECIAL_RUNLEVEL2_TARGET,
+                [ACTION_RUNLEVEL3] = SPECIAL_RUNLEVEL3_TARGET,
+                [ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET,
+                [ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET,
+                [ACTION_RESCUE] = SPECIAL_RESCUE_TARGET,
+                [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET,
+                [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET,
+                [ACTION_EXIT] = SPECIAL_EXIT_TARGET,
+                [ACTION_SUSPEND] = SPECIAL_SUSPEND_TARGET,
+                [ACTION_HIBERNATE] = SPECIAL_HIBERNATE_TARGET,
+                [ACTION_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET
+        };
+
+        int r, ret = 0;
+        const char *method, *mode, *one_name;
+        Set *s = NULL;
+        DBusError error;
+        char **name;
+
+        dbus_error_init(&error);
+
+        assert(bus);
+
+        ask_password_agent_open_if_enabled();
+
+        if (arg_action == ACTION_SYSTEMCTL) {
+                method =
+                        streq(args[0], "stop") ||
+                        streq(args[0], "condstop")              ? "StopUnit" :
+                        streq(args[0], "reload")                ? "ReloadUnit" :
+                        streq(args[0], "restart")               ? "RestartUnit" :
+
+                        streq(args[0], "try-restart")           ||
+                        streq(args[0], "condrestart")           ? "TryRestartUnit" :
+
+                        streq(args[0], "reload-or-restart")     ? "ReloadOrRestartUnit" :
+
+                        streq(args[0], "reload-or-try-restart") ||
+                        streq(args[0], "condreload") ||
+
+                        streq(args[0], "force-reload")          ? "ReloadOrTryRestartUnit" :
+                                                                  "StartUnit";
+
+                mode =
+                        (streq(args[0], "isolate") ||
+                         streq(args[0], "rescue")  ||
+                         streq(args[0], "emergency")) ? "isolate" : arg_job_mode;
+
+                one_name = table[verb_to_action(args[0])];
+
+        } else {
+                assert(arg_action < ELEMENTSOF(table));
+                assert(table[arg_action]);
+
+                method = "StartUnit";
+
+                mode = (arg_action == ACTION_EMERGENCY ||
+                        arg_action == ACTION_RESCUE ||
+                        arg_action == ACTION_RUNLEVEL2 ||
+                        arg_action == ACTION_RUNLEVEL3 ||
+                        arg_action == ACTION_RUNLEVEL4 ||
+                        arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace";
+
+                one_name = table[arg_action];
+        }
+
+        if (!arg_no_block) {
+                ret = enable_wait_for_jobs(bus);
+                if (ret < 0) {
+                        log_error("Could not watch jobs: %s", strerror(-ret));
+                        goto finish;
+                }
+
+                s = set_new(string_hash_func, string_compare_func);
+                if (!s) {
+                        ret = log_oom();
+                        goto finish;
+                }
+        }
+
+        if (one_name) {
+                ret = start_unit_one(bus, method, one_name, mode, &error, s);
+                if (ret < 0)
+                        ret = translate_bus_error_to_exit_status(ret, &error);
+        } else {
+                STRV_FOREACH(name, args+1) {
+                        r = start_unit_one(bus, method, *name, mode, &error, s);
+                        if (r < 0) {
+                                ret = translate_bus_error_to_exit_status(r, &error);
+                                dbus_error_free(&error);
+                        }
+                }
+        }
+
+        if (!arg_no_block) {
+                r = wait_for_jobs(bus, s);
+                if (r < 0) {
+                        ret = r;
+                        goto finish;
+                }
+
+                /* When stopping units, warn if they can still be triggered by
+                 * another active unit (socket, path, timer) */
+                if (!arg_quiet && streq(method, "StopUnit")) {
+                        if (one_name)
+                                check_triggering_units(bus, one_name);
+                        else
+                                STRV_FOREACH(name, args+1)
+                                        check_triggering_units(bus, *name);
+                }
+        }
+
+finish:
+        set_free_free(s);
+        dbus_error_free(&error);
+
+        return ret;
+}
+
+/* Ask systemd-logind, which might grant access to unprivileged users
+ * through PolicyKit */
+static int reboot_with_logind(DBusConnection *bus, enum action a) {
+#ifdef HAVE_LOGIND
+        const char *method;
+        dbus_bool_t interactive = true;
+
+        polkit_agent_open_if_enabled();
+
+        switch (a) {
+
+        case ACTION_REBOOT:
+                method = "Reboot";
+                break;
+
+        case ACTION_POWEROFF:
+                method = "PowerOff";
+                break;
+
+        case ACTION_SUSPEND:
+                method = "Suspend";
+                break;
+
+        case ACTION_HIBERNATE:
+                method = "Hibernate";
+                break;
+
+        case ACTION_HYBRID_SLEEP:
+                method = "HybridSleep";
+                break;
+
+        default:
+                return -EINVAL;
+        }
+
+        return bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.login1",
+                        "/org/freedesktop/login1",
+                        "org.freedesktop.login1.Manager",
+                        method,
+                        NULL,
+                        NULL,
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+#else
+        return -ENOSYS;
+#endif
+}
+
+static int start_special(DBusConnection *bus, char **args) {
+        enum action a;
+        int r;
+
+        assert(args);
+
+        a = verb_to_action(args[0]);
+
+        if (arg_force >= 2 && geteuid() != 0) {
+                log_error("Must be root.");
+                return -EPERM;
+        }
+
+        if (arg_force >= 2 &&
+            (a == ACTION_HALT ||
+             a == ACTION_POWEROFF ||
+             a == ACTION_REBOOT))
+                halt_now(a);
+
+        if (arg_force >= 1 &&
+            (a == ACTION_HALT ||
+             a == ACTION_POWEROFF ||
+             a == ACTION_REBOOT ||
+             a == ACTION_KEXEC ||
+             a == ACTION_EXIT))
+                return daemon_reload(bus, args);
+
+        /* first try logind, to allow authentication with polkit */
+        if (geteuid() != 0 &&
+            (a == ACTION_POWEROFF ||
+             a == ACTION_REBOOT ||
+             a == ACTION_SUSPEND ||
+             a == ACTION_HIBERNATE ||
+             a == ACTION_HYBRID_SLEEP)) {
+                r = reboot_with_logind(bus, a);
+                if (r >= 0)
+                        return r;
+        }
+
+        r = start_unit(bus, args);
+        if (r >= 0)
+                warn_wall(a);
+
+        return r;
+}
+
+static int check_unit_active(DBusConnection *bus, char **args) {
+        char **name;
+        int r = 3; /* According to LSB: "program is not running" */
+
+        assert(bus);
+        assert(args);
+
+        STRV_FOREACH(name, args+1) {
+                char **check_states = strv_new("active", "reloading", NULL);
+                int state = check_one_unit(bus, *name, check_states, arg_quiet);
+                strv_free(check_states);
+                if (state < 0)
+                        return state;
+                if (state == 0)
+                        r = 0;
+        }
+
+        return r;
+}
+
+static int check_unit_failed(DBusConnection *bus, char **args) {
+        char **name;
+        int r = 1;
+
+        assert(bus);
+        assert(args);
+
+        STRV_FOREACH(name, args+1) {
+                char **check_states = strv_new("failed", NULL);
+                int state = check_one_unit(bus, *name, check_states, arg_quiet);
+                strv_free(check_states);
+                if (state < 0)
+                        return state;
+                if (state == 0)
+                        r = 0;
+        }
+
+        return r;
+}
+
+static int kill_unit(DBusConnection *bus, char **args) {
+        int r = 0;
+        char **name, *n;
+
+        assert(args);
+
+        if (!arg_kill_who)
+                arg_kill_who = "all";
+
+        STRV_FOREACH(name, args+1) {
+                n = unit_name_mangle(*name);
+                r = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "KillUnit",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_STRING, n ? &n : name,
+                                DBUS_TYPE_STRING, &arg_kill_who,
+                                DBUS_TYPE_INT32, &arg_signal,
+                                DBUS_TYPE_INVALID);
+                free(n);
+                if (r)
+                        return r;
+        }
+        return 0;
+}
+
+typedef struct ExecStatusInfo {
+        char *name;
+
+        char *path;
+        char **argv;
+
+        bool ignore;
+
+        usec_t start_timestamp;
+        usec_t exit_timestamp;
+        pid_t pid;
+        int code;
+        int status;
+
+        LIST_FIELDS(struct ExecStatusInfo, exec);
+} ExecStatusInfo;
+
+static void exec_status_info_free(ExecStatusInfo *i) {
+        assert(i);
+
+        free(i->name);
+        free(i->path);
+        strv_free(i->argv);
+        free(i);
+}
+
+static int exec_status_info_deserialize(DBusMessageIter *sub, ExecStatusInfo *i) {
+        uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
+        DBusMessageIter sub2, sub3;
+        const char*path;
+        unsigned n;
+        uint32_t pid;
+        int32_t code, status;
+        dbus_bool_t ignore;
+
+        assert(i);
+        assert(i);
+
+        if (dbus_message_iter_get_arg_type(sub) != DBUS_TYPE_STRUCT)
+                return -EIO;
+
+        dbus_message_iter_recurse(sub, &sub2);
+
+        if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0)
+                return -EIO;
+
+        if (!(i->path = strdup(path)))
+                return -ENOMEM;
+
+        if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&sub2) != DBUS_TYPE_STRING)
+                return -EIO;
+
+        n = 0;
+        dbus_message_iter_recurse(&sub2, &sub3);
+        while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) {
+                assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING);
+                dbus_message_iter_next(&sub3);
+                n++;
+        }
+
+
+        if (!(i->argv = new0(char*, n+1)))
+                return -ENOMEM;
+
+        n = 0;
+        dbus_message_iter_recurse(&sub2, &sub3);
+        while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) {
+                const char *s;
+
+                assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING);
+                dbus_message_iter_get_basic(&sub3, &s);
+                dbus_message_iter_next(&sub3);
+
+                if (!(i->argv[n++] = strdup(s)))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_next(&sub2) ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &ignore, true) < 0 ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_timestamp, true) < 0 ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_timestamp_monotonic, true) < 0 ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_timestamp, true) < 0 ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_timestamp_monotonic, true) < 0 ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) < 0 ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &code, true) < 0 ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) < 0)
+                return -EIO;
+
+        i->ignore = ignore;
+        i->start_timestamp = (usec_t) start_timestamp;
+        i->exit_timestamp = (usec_t) exit_timestamp;
+        i->pid = (pid_t) pid;
+        i->code = code;
+        i->status = status;
+
+        return 0;
+}
+
+typedef struct UnitStatusInfo {
+        const char *id;
+        const char *load_state;
+        const char *active_state;
+        const char *sub_state;
+        const char *unit_file_state;
+
+        const char *description;
+        const char *following;
+
+        char **documentation;
+
+        const char *fragment_path;
+        const char *source_path;
+        const char *default_control_group;
+
+        const char *load_error;
+        const char *result;
+
+        usec_t inactive_exit_timestamp;
+        usec_t inactive_exit_timestamp_monotonic;
+        usec_t active_enter_timestamp;
+        usec_t active_exit_timestamp;
+        usec_t inactive_enter_timestamp;
+
+        bool need_daemon_reload;
+
+        /* Service */
+        pid_t main_pid;
+        pid_t control_pid;
+        const char *status_text;
+        bool running:1;
+
+        usec_t start_timestamp;
+        usec_t exit_timestamp;
+
+        int exit_code, exit_status;
+
+        usec_t condition_timestamp;
+        bool condition_result;
+
+        /* Socket */
+        unsigned n_accepted;
+        unsigned n_connections;
+        bool accept;
+
+        /* Device */
+        const char *sysfs_path;
+
+        /* Mount, Automount */
+        const char *where;
+
+        /* Swap */
+        const char *what;
+
+        LIST_HEAD(ExecStatusInfo, exec);
+} UnitStatusInfo;
+
+static void print_status_info(UnitStatusInfo *i) {
+        ExecStatusInfo *p;
+        const char *on, *off, *ss;
+        usec_t timestamp;
+        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
+        char since2[FORMAT_TIMESTAMP_MAX], *s2;
+        const char *path;
+
+        assert(i);
+
+        /* This shows pretty information about a unit. See
+         * print_property() for a low-level property printer */
+
+        printf("%s", strna(i->id));
+
+        if (i->description && !streq_ptr(i->id, i->description))
+                printf(" - %s", i->description);
+
+        printf("\n");
+
+        if (i->following)
+                printf("\t  Follow: unit currently follows state of %s\n", i->following);
+
+        if (streq_ptr(i->load_state, "error")) {
+                on = ansi_highlight_red(true);
+                off = ansi_highlight_red(false);
+        } else
+                on = off = "";
+
+        path = i->source_path ? i->source_path : i->fragment_path;
+
+        if (i->load_error)
+                printf("\t  Loaded: %s%s%s (Reason: %s)\n", on, strna(i->load_state), off, i->load_error);
+        else if (path && i->unit_file_state)
+                printf("\t  Loaded: %s%s%s (%s; %s)\n", on, strna(i->load_state), off, path, i->unit_file_state);
+        else if (path)
+                printf("\t  Loaded: %s%s%s (%s)\n", on, strna(i->load_state), off, path);
+        else
+                printf("\t  Loaded: %s%s%s\n", on, strna(i->load_state), off);
+
+        ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
+
+        if (streq_ptr(i->active_state, "failed")) {
+                on = ansi_highlight_red(true);
+                off = ansi_highlight_red(false);
+        } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
+                on = ansi_highlight_green(true);
+                off = ansi_highlight_green(false);
+        } else
+                on = off = "";
+
+        if (ss)
+                printf("\t  Active: %s%s (%s)%s",
+                       on,
+                       strna(i->active_state),
+                       ss,
+                       off);
+        else
+                printf("\t  Active: %s%s%s",
+                       on,
+                       strna(i->active_state),
+                       off);
+
+        if (!isempty(i->result) && !streq(i->result, "success"))
+                printf(" (Result: %s)", i->result);
+
+        timestamp = (streq_ptr(i->active_state, "active")      ||
+                     streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
+                    (streq_ptr(i->active_state, "inactive")    ||
+                     streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
+                    streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
+                                                                  i->active_exit_timestamp;
+
+        s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
+        s2 = format_timestamp(since2, sizeof(since2), timestamp);
+
+        if (s1)
+                printf(" since %s; %s\n", s2, s1);
+        else if (s2)
+                printf(" since %s\n", s2);
+        else
+                printf("\n");
+
+        if (!i->condition_result && i->condition_timestamp > 0) {
+                s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
+                s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
+
+                if (s1)
+                        printf("\t          start condition failed at %s; %s\n", s2, s1);
+                else if (s2)
+                        printf("\t          start condition failed at %s\n", s2);
+        }
+
+        if (i->sysfs_path)
+                printf("\t  Device: %s\n", i->sysfs_path);
+        if (i->where)
+                printf("\t   Where: %s\n", i->where);
+        if (i->what)
+                printf("\t    What: %s\n", i->what);
+
+        if (!strv_isempty(i->documentation)) {
+                char **t;
+                bool first = true;
+
+                STRV_FOREACH(t, i->documentation) {
+                        if (first) {
+                                printf("\t    Docs: %s\n", *t);
+                                first = false;
+                        } else
+                                printf("\t          %s\n", *t);
+                }
+        }
+
+        if (i->accept)
+                printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
+
+        LIST_FOREACH(exec, p, i->exec) {
+                char *t;
+                bool good;
+
+                /* Only show exited processes here */
+                if (p->code == 0)
+                        continue;
+
+                t = strv_join(p->argv, " ");
+                printf("\t Process: %u %s=%s ", p->pid, p->name, strna(t));
+                free(t);
+
+                good = is_clean_exit_lsb(p->code, p->status, NULL);
+                if (!good) {
+                        on = ansi_highlight_red(true);
+                        off = ansi_highlight_red(false);
+                } else
+                        on = off = "";
+
+                printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
+
+                if (p->code == CLD_EXITED) {
+                        const char *c;
+
+                        printf("status=%i", p->status);
+
+                        c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
+                        if (c)
+                                printf("/%s", c);
+
+                } else
+                        printf("signal=%s", signal_to_string(p->status));
+
+                printf(")%s\n", off);
+
+                if (i->main_pid == p->pid &&
+                    i->start_timestamp == p->start_timestamp &&
+                    i->exit_timestamp == p->start_timestamp)
+                        /* Let's not show this twice */
+                        i->main_pid = 0;
+
+                if (p->pid == i->control_pid)
+                        i->control_pid = 0;
+        }
+
+        if (i->main_pid > 0 || i->control_pid > 0) {
+                printf("\t");
+
+                if (i->main_pid > 0) {
+                        printf("Main PID: %u", (unsigned) i->main_pid);
+
+                        if (i->running) {
+                                char *t = NULL;
+                                get_process_comm(i->main_pid, &t);
+                                if (t) {
+                                        printf(" (%s)", t);
+                                        free(t);
+                                }
+                        } else if (i->exit_code > 0) {
+                                printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
+
+                                if (i->exit_code == CLD_EXITED) {
+                                        const char *c;
+
+                                        printf("status=%i", i->exit_status);
+
+                                        c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
+                                        if (c)
+                                                printf("/%s", c);
+
+                                } else
+                                        printf("signal=%s", signal_to_string(i->exit_status));
+                                printf(")");
+                        }
+                }
+
+                if (i->main_pid > 0 && i->control_pid > 0)
+                        printf(";");
+
+                if (i->control_pid > 0) {
+                        char *t = NULL;
+
+                        printf(" Control: %u", (unsigned) i->control_pid);
+
+                        get_process_comm(i->control_pid, &t);
+                        if (t) {
+                                printf(" (%s)", t);
+                                free(t);
+                        }
+                }
+
+                printf("\n");
+        }
+
+        if (i->status_text)
+                printf("\t  Status: \"%s\"\n", i->status_text);
+
+        if (i->default_control_group &&
+            (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_by_spec(i->default_control_group, false) == 0)) {
+                unsigned c;
+
+                printf("\t  CGroup: %s\n", i->default_control_group);
+
+                if (arg_transport != TRANSPORT_SSH) {
+                        unsigned k = 0;
+                        pid_t extra[2];
+
+                        c = columns();
+                        if (c > 18)
+                                c -= 18;
+                        else
+                                c = 0;
+
+                        if (i->main_pid > 0)
+                                extra[k++] = i->main_pid;
+
+                        if (i->control_pid > 0)
+                                extra[k++] = i->control_pid;
+
+                        show_cgroup_and_extra_by_spec(i->default_control_group, "\t\t  ", c, false, arg_all, extra, k);
+                }
+        }
+
+        if (i->id && arg_transport != TRANSPORT_SSH) {
+                int flags =
+                        arg_all * OUTPUT_SHOW_ALL |
+                        (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+                        on_tty() * OUTPUT_COLOR |
+                        !arg_quiet * OUTPUT_WARN_CUTOFF;
+
+                printf("\n");
+                show_journal_by_unit(stdout,
+                                     i->id,
+                                     arg_output,
+                                     0,
+                                     i->inactive_exit_timestamp_monotonic,
+                                     arg_lines,
+                                     flags);
+        }
+
+        if (i->need_daemon_reload)
+                printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %s daemon-reload' recommended.\n",
+                       ansi_highlight_red(true),
+                       ansi_highlight_red(false),
+                       arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user");
+}
+
+static void show_unit_help(UnitStatusInfo *i) {
+        char **p;
+
+        assert(i);
+
+        if (!i->documentation) {
+                log_info("Documentation for %s not known.", i->id);
+                return;
+        }
+
+        STRV_FOREACH(p, i->documentation) {
+
+                if (startswith(*p, "man:")) {
+                        size_t k;
+                        char *e = NULL;
+                        char *page = NULL, *section = NULL;
+                        const char *args[4] = { "man", NULL, NULL, NULL };
+                        pid_t pid;
+
+                        k = strlen(*p);
+
+                        if ((*p)[k-1] == ')')
+                                e = strrchr(*p, '(');
+
+                        if (e) {
+                                page = strndup((*p) + 4, e - *p - 4);
+                                if (!page) {
+                                        log_oom();
+                                        return;
+                                }
+
+                                section = strndup(e + 1, *p + k - e - 2);
+                                if (!section) {
+                                        free(page);
+                                        log_oom();
+                                        return;
+                                }
+
+                                args[1] = section;
+                                args[2] = page;
+                        } else
+                                args[1] = *p + 4;
+
+                        pid = fork();
+                        if (pid < 0) {
+                                log_error("Failed to fork: %m");
+                                free(page);
+                                free(section);
+                                continue;
+                        }
+
+                        if (pid == 0) {
+                                /* Child */
+                                execvp(args[0], (char**) args);
+                                log_error("Failed to execute man: %m");
+                                _exit(EXIT_FAILURE);
+                        }
+
+                        free(page);
+                        free(section);
+
+                        wait_for_terminate(pid, NULL);
+                } else
+                        log_info("Can't show: %s", *p);
+        }
+}
+
+static int status_property(const char *name, DBusMessageIter *iter, UnitStatusInfo *i) {
+
+        assert(name);
+        assert(iter);
+        assert(i);
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRING: {
+                const char *s;
+
+                dbus_message_iter_get_basic(iter, &s);
+
+                if (!isempty(s)) {
+                        if (streq(name, "Id"))
+                                i->id = s;
+                        else if (streq(name, "LoadState"))
+                                i->load_state = s;
+                        else if (streq(name, "ActiveState"))
+                                i->active_state = s;
+                        else if (streq(name, "SubState"))
+                                i->sub_state = s;
+                        else if (streq(name, "Description"))
+                                i->description = s;
+                        else if (streq(name, "FragmentPath"))
+                                i->fragment_path = s;
+                        else if (streq(name, "SourcePath"))
+                                i->source_path = s;
+                        else if (streq(name, "DefaultControlGroup"))
+                                i->default_control_group = s;
+                        else if (streq(name, "StatusText"))
+                                i->status_text = s;
+                        else if (streq(name, "SysFSPath"))
+                                i->sysfs_path = s;
+                        else if (streq(name, "Where"))
+                                i->where = s;
+                        else if (streq(name, "What"))
+                                i->what = s;
+                        else if (streq(name, "Following"))
+                                i->following = s;
+                        else if (streq(name, "UnitFileState"))
+                                i->unit_file_state = s;
+                        else if (streq(name, "Result"))
+                                i->result = s;
+                }
+
+                break;
+        }
+
+        case DBUS_TYPE_BOOLEAN: {
+                dbus_bool_t b;
+
+                dbus_message_iter_get_basic(iter, &b);
+
+                if (streq(name, "Accept"))
+                        i->accept = b;
+                else if (streq(name, "NeedDaemonReload"))
+                        i->need_daemon_reload = b;
+                else if (streq(name, "ConditionResult"))
+                        i->condition_result = b;
+
+                break;
+        }
+
+        case DBUS_TYPE_UINT32: {
+                uint32_t u;
+
+                dbus_message_iter_get_basic(iter, &u);
+
+                if (streq(name, "MainPID")) {
+                        if (u > 0) {
+                                i->main_pid = (pid_t) u;
+                                i->running = true;
+                        }
+                } else if (streq(name, "ControlPID"))
+                        i->control_pid = (pid_t) u;
+                else if (streq(name, "ExecMainPID")) {
+                        if (u > 0)
+                                i->main_pid = (pid_t) u;
+                } else if (streq(name, "NAccepted"))
+                        i->n_accepted = u;
+                else if (streq(name, "NConnections"))
+                        i->n_connections = u;
+
+                break;
+        }
+
+        case DBUS_TYPE_INT32: {
+                int32_t j;
+
+                dbus_message_iter_get_basic(iter, &j);
+
+                if (streq(name, "ExecMainCode"))
+                        i->exit_code = (int) j;
+                else if (streq(name, "ExecMainStatus"))
+                        i->exit_status = (int) j;
+
+                break;
+        }
+
+        case DBUS_TYPE_UINT64: {
+                uint64_t u;
+
+                dbus_message_iter_get_basic(iter, &u);
+
+                if (streq(name, "ExecMainStartTimestamp"))
+                        i->start_timestamp = (usec_t) u;
+                else if (streq(name, "ExecMainExitTimestamp"))
+                        i->exit_timestamp = (usec_t) u;
+                else if (streq(name, "ActiveEnterTimestamp"))
+                        i->active_enter_timestamp = (usec_t) u;
+                else if (streq(name, "InactiveEnterTimestamp"))
+                        i->inactive_enter_timestamp = (usec_t) u;
+                else if (streq(name, "InactiveExitTimestamp"))
+                        i->inactive_exit_timestamp = (usec_t) u;
+                else if (streq(name, "InactiveExitTimestampMonotonic"))
+                        i->inactive_exit_timestamp_monotonic = (usec_t) u;
+                else if (streq(name, "ActiveExitTimestamp"))
+                        i->active_exit_timestamp = (usec_t) u;
+                else if (streq(name, "ConditionTimestamp"))
+                        i->condition_timestamp = (usec_t) u;
+
+                break;
+        }
+
+        case DBUS_TYPE_ARRAY: {
+
+                if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT &&
+                    startswith(name, "Exec")) {
+                        DBusMessageIter sub;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                ExecStatusInfo *info;
+                                int r;
+
+                                if (!(info = new0(ExecStatusInfo, 1)))
+                                        return -ENOMEM;
+
+                                if (!(info->name = strdup(name))) {
+                                        free(info);
+                                        return -ENOMEM;
+                                }
+
+                                if ((r = exec_status_info_deserialize(&sub, info)) < 0) {
+                                        free(info);
+                                        return r;
+                                }
+
+                                LIST_PREPEND(ExecStatusInfo, exec, i->exec, info);
+
+                                dbus_message_iter_next(&sub);
+                        }
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING &&
+                           streq(name, "Documentation")) {
+
+                        DBusMessageIter sub;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
+                                const char *s;
+                                char **l;
+
+                                dbus_message_iter_get_basic(&sub, &s);
+
+                                l = strv_append(i->documentation, s);
+                                if (!l)
+                                        return -ENOMEM;
+
+                                strv_free(i->documentation);
+                                i->documentation = l;
+
+                                dbus_message_iter_next(&sub);
+                        }
+                }
+
+                break;
+        }
+
+        case DBUS_TYPE_STRUCT: {
+
+                if (streq(name, "LoadError")) {
+                        DBusMessageIter sub;
+                        const char *n, *message;
+                        int r;
+
+                        dbus_message_iter_recurse(iter, &sub);
+
+                        r = bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &n, true);
+                        if (r < 0)
+                                return r;
+
+                        r = bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &message, false);
+                        if (r < 0)
+                                return r;
+
+                        if (!isempty(message))
+                                i->load_error = message;
+                }
+
+                break;
+        }
+        }
+
+        return 0;
+}
+
+static int print_property(const char *name, DBusMessageIter *iter) {
+        assert(name);
+        assert(iter);
+
+        /* This is a low-level property printer, see
+         * print_status_info() for the nicer output */
+
+        if (arg_property && !strv_find(arg_property, name))
+                return 0;
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRUCT: {
+                DBusMessageIter sub;
+                dbus_message_iter_recurse(iter, &sub);
+
+                if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && streq(name, "Job")) {
+                        uint32_t u;
+
+                        dbus_message_iter_get_basic(&sub, &u);
+
+                        if (u)
+                                printf("%s=%u\n", name, (unsigned) u);
+                        else if (arg_all)
+                                printf("%s=\n", name);
+
+                        return 0;
+                } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Unit")) {
+                        const char *s;
+
+                        dbus_message_iter_get_basic(&sub, &s);
+
+                        if (arg_all || s[0])
+                                printf("%s=%s\n", name, s);
+
+                        return 0;
+                } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "LoadError")) {
+                        const char *a = NULL, *b = NULL;
+
+                        if (bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &a, true) >= 0)
+                                bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &b, false);
+
+                        if (arg_all || !isempty(a) || !isempty(b))
+                                printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
+
+                        return 0;
+                }
+
+                break;
+        }
+
+        case DBUS_TYPE_ARRAY:
+
+                if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "EnvironmentFiles")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *path;
+                                dbus_bool_t ignore;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &ignore, false) >= 0)
+                                        printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Paths")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *type, *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0)
+                                        printf("%s=%s\n", type, path);
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Timers")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *base;
+                                uint64_t value, next_elapse;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &base, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &value, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0) {
+                                        char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
+
+                                        printf("%s={ value=%s ; next_elapse=%s }\n",
+                                               base,
+                                               format_timespan(timespan1, sizeof(timespan1), value),
+                                               format_timespan(timespan2, sizeof(timespan2), next_elapse));
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "ControlGroupAttributes")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *controller, *attr, *value;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &controller, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &attr, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &value, false) >= 0) {
+
+                                        printf("ControlGroupAttribute={ controller=%s ; attribute=%s ; value=\"%s\" }\n",
+                                               controller,
+                                               attr,
+                                               value);
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) {
+                        DBusMessageIter sub;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                ExecStatusInfo info;
+
+                                zero(info);
+                                if (exec_status_info_deserialize(&sub, &info) >= 0) {
+                                        char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
+                                        char *t;
+
+                                        t = strv_join(info.argv, " ");
+
+                                        printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
+                                               name,
+                                               strna(info.path),
+                                               strna(t),
+                                               yes_no(info.ignore),
+                                               strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
+                                               strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
+                                               (unsigned) info. pid,
+                                               sigchld_code_to_string(info.code),
+                                               info.status,
+                                               info.code == CLD_EXITED ? "" : "/",
+                                               strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
+
+                                        free(t);
+                                }
+
+                                free(info.path);
+                                strv_free(info.argv);
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+                }
+
+                break;
+        }
+
+        if (generic_print_property(name, iter, arg_all) > 0)
+                return 0;
+
+        if (arg_all)
+                printf("%s=[unprintable]\n", name);
+
+        return 0;
+}
+
+static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) {
+        DBusMessage *reply = NULL;
+        const char *interface = "";
+        int r;
+        DBusMessageIter iter, sub, sub2, sub3;
+        UnitStatusInfo info;
+        ExecStatusInfo *p;
+
+        assert(path);
+        assert(new_line);
+
+        zero(info);
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (*new_line)
+                printf("\n");
+
+        *new_line = true;
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *name;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)  {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&sub2, &sub3);
+
+                if (show_properties)
+                        r = print_property(name, &sub3);
+                else
+                        r = status_property(name, &sub3, &info);
+
+                if (r < 0) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_next(&sub);
+        }
+
+        r = 0;
+
+        if (!show_properties) {
+                if (streq(verb, "help"))
+                        show_unit_help(&info);
+                else
+                        print_status_info(&info);
+        }
+
+        strv_free(info.documentation);
+
+        if (!streq_ptr(info.active_state, "active") &&
+            !streq_ptr(info.active_state, "reloading") &&
+            streq(verb, "status"))
+                /* According to LSB: "program not running" */
+                r = 3;
+
+        while ((p = info.exec)) {
+                LIST_REMOVE(ExecStatusInfo, exec, info.exec, p);
+                exec_status_info_free(p);
+        }
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int show_one_by_pid(const char *verb, DBusConnection *bus, uint32_t pid, bool *new_line) {
+        DBusMessage *reply = NULL;
+        const char *path = NULL;
+        DBusError error;
+        int r;
+
+        dbus_error_init(&error);
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "GetUnitByPID",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_UINT32, &pid,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_get_args(reply, &error,
+                                   DBUS_TYPE_OBJECT_PATH, &path,
+                                   DBUS_TYPE_INVALID)) {
+                log_error("Failed to parse reply: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        r = show_one(verb, bus, path, false, new_line);
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int show(DBusConnection *bus, char **args) {
+        int r, ret = 0;
+        bool show_properties, new_line = false;
+        char **name;
+
+        assert(bus);
+        assert(args);
+
+        show_properties = streq(args[0], "show");
+
+        if (show_properties)
+                pager_open_if_enabled();
+
+        if (show_properties && strv_length(args) <= 1) {
+                /* If not argument is specified inspect the manager
+                 * itself */
+
+                return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line);
+        }
+
+        STRV_FOREACH(name, args+1) {
+                uint32_t id;
+
+                if (safe_atou32(*name, &id) < 0) {
+                        char *p, *n;
+                        /* Interpret as unit name */
+
+                        n = unit_name_mangle(*name);
+                        p = unit_dbus_path_from_name(n ? n : *name);
+                        free(n);
+                        if (!p)
+                                return log_oom();
+
+                        r = show_one(args[0], bus, p, show_properties, &new_line);
+                        free(p);
+
+                        if (r != 0)
+                                ret = r;
+
+                } else if (show_properties) {
+
+                        /* Interpret as job id */
+
+                        char *p;
+                        if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
+                                return log_oom();
+
+                        r = show_one(args[0], bus, p, show_properties, &new_line);
+                        free(p);
+
+                        if (r != 0)
+                                ret = r;
+
+                } else {
+
+                        /* Interpret as PID */
+
+                        r = show_one_by_pid(args[0], bus, id, &new_line);
+                        if (r != 0)
+                                ret = r;
+                }
+        }
+
+        return ret;
+}
+
+static int dump(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        DBusError error;
+        int r;
+        const char *text;
+
+        dbus_error_init(&error);
+
+        pager_open_if_enabled();
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "Dump",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_get_args(reply, &error,
+                                   DBUS_TYPE_STRING, &text,
+                                   DBUS_TYPE_INVALID)) {
+                log_error("Failed to parse reply: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        fputs(text, stdout);
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int snapshot(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        DBusError error;
+        int r;
+        dbus_bool_t cleanup = FALSE;
+        DBusMessageIter iter, sub;
+        const char
+                *name = "", *path, *id,
+                *interface = "org.freedesktop.systemd1.Unit",
+                *property = "Id";
+        char *n;
+
+        dbus_error_init(&error);
+
+        if (strv_length(args) > 1)
+                name = args[1];
+
+        n = unit_name_mangle(name);
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "CreateSnapshot",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, n ? (const char**) &n : &name,
+                        DBUS_TYPE_BOOLEAN, &cleanup,
+                        DBUS_TYPE_INVALID);
+        free(n);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_get_args(reply, &error,
+                                   DBUS_TYPE_OBJECT_PATH, &path,
+                                   DBUS_TYPE_INVALID)) {
+                log_error("Failed to parse reply: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_unref(reply);
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.DBus.Properties",
+                        "Get",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_STRING, &property,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_get_basic(&sub, &id);
+
+        if (!arg_quiet)
+                puts(id);
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int delete_snapshot(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        int r = 0;
+        DBusError error;
+        char **name;
+
+        assert(args);
+
+        dbus_error_init(&error);
+
+        STRV_FOREACH(name, args+1) {
+                const char *path = NULL;
+                char *n;
+
+                n = unit_name_mangle(*name);
+                r = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "GetUnit",
+                                &reply,
+                                NULL,
+                                DBUS_TYPE_STRING, n ? &n : name,
+                                DBUS_TYPE_INVALID);
+                free(n);
+                if (r)
+                        goto finish;
+
+                if (!dbus_message_get_args(reply, &error,
+                                           DBUS_TYPE_OBJECT_PATH, &path,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse reply: %s", bus_error_message(&error));
+                        r = -EIO;
+                        dbus_message_unref(reply);
+                        dbus_error_free(&error);
+                        goto finish;
+                }
+                dbus_message_unref(reply);
+
+                r = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.systemd1",
+                                path,
+                                "org.freedesktop.systemd1.Snapshot",
+                                "Remove",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_INVALID);
+                if (r)
+                        goto finish;
+        }
+
+finish:
+        return r;
+}
+
+static int daemon_reload(DBusConnection *bus, char **args) {
+        int r;
+        const char *method;
+        DBusError error;
+
+        if (arg_action == ACTION_RELOAD)
+                method = "Reload";
+        else if (arg_action == ACTION_REEXEC)
+                method = "Reexecute";
+        else {
+                assert(arg_action == ACTION_SYSTEMCTL);
+
+                method =
+                        streq(args[0], "clear-jobs")    ||
+                        streq(args[0], "cancel")        ? "ClearJobs" :
+                        streq(args[0], "daemon-reexec") ? "Reexecute" :
+                        streq(args[0], "reset-failed")  ? "ResetFailed" :
+                        streq(args[0], "halt")          ? "Halt" :
+                        streq(args[0], "poweroff")      ? "PowerOff" :
+                        streq(args[0], "reboot")        ? "Reboot" :
+                        streq(args[0], "kexec")         ? "KExec" :
+                        streq(args[0], "exit")          ? "Exit" :
+                                    /* "daemon-reload" */ "Reload";
+        }
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        method,
+                        NULL,
+                        &error,
+                        DBUS_TYPE_INVALID);
+
+        if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
+                /* There's always a fallback possible for
+                 * legacy actions. */
+                r = -EADDRNOTAVAIL;
+        else if (r == -ETIMEDOUT && streq(method, "Reexecute"))
+                /* On reexecution, we expect a disconnect, not
+                 * a reply */
+                r = 0;
+        else if (r)
+                log_error("Failed to issue method call: %s", bus_error_message(&error));
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int reset_failed(DBusConnection *bus, char **args) {
+        int r = 0;
+        char **name, *n;
+
+        if (strv_length(args) <= 1)
+                return daemon_reload(bus, args);
+
+        STRV_FOREACH(name, args+1) {
+                n = unit_name_mangle(*name);
+                r = bus_method_call_with_reply (
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "ResetFailedUnit",
+                                NULL,
+                                NULL,
+                                DBUS_TYPE_STRING, n ? &n : name,
+                                DBUS_TYPE_INVALID);
+                free(n);
+                if (r)
+                        goto finish;
+        }
+
+finish:
+        return r;
+}
+
+static int show_enviroment(DBusConnection *bus, char **args) {
+        DBusMessage *reply = NULL;
+        DBusMessageIter iter, sub, sub2;
+        int r;
+        const char
+                *interface = "org.freedesktop.systemd1.Manager",
+                *property = "Environment";
+
+        pager_open_if_enabled();
+
+        r = bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.DBus.Properties",
+                        "Get",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_STRING, &property,
+                        DBUS_TYPE_INVALID);
+        if (r)
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_STRING)  {
+                log_error("Failed to parse reply.");
+                r = -EIO;
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&sub, &sub2);
+
+        while (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_INVALID) {
+                const char *text;
+
+                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_get_basic(&sub2, &text);
+                printf("%s\n", text);
+
+                dbus_message_iter_next(&sub2);
+        }
+
+        r = 0;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        return r;
+}
+
+static int switch_root(DBusConnection *bus, char **args) {
+        unsigned l;
+        const char *root;
+        _cleanup_free_ char *init = NULL;
+
+        l = strv_length(args);
+        if (l < 2 || l > 3) {
+                log_error("Wrong number of arguments.");
+                return -EINVAL;
+        }
+
+        root = args[1];
+
+        if (l >= 3)
+                init = strdup(args[2]);
+        else {
+                parse_env_file("/proc/cmdline", WHITESPACE,
+                               "init", &init,
+                               NULL);
+
+                if (!init)
+                        init = strdup("");
+
+                if (!init)
+                        return log_oom();
+
+        }
+
+        log_debug("switching root - root: %s; init: %s", root, init);
+
+        return bus_method_call_with_reply (
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "SwitchRoot",
+                        NULL,
+                        NULL,
+                        DBUS_TYPE_STRING, &root,
+                        DBUS_TYPE_STRING, &init,
+                        DBUS_TYPE_INVALID);
+}
+
+static int set_environment(DBusConnection *bus, char **args) {
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
+        DBusError error;
+        const char *method;
+        DBusMessageIter iter;
+        int r;
+
+        assert(bus);
+
+        dbus_error_init(&error);
+
+        method = streq(args[0], "set-environment")
+                ? "SetEnvironment"
+                : "UnsetEnvironment";
+
+        m = dbus_message_new_method_call(
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        method);
+        if (!m)
+                return log_oom();
+
+        dbus_message_iter_init_append(m, &iter);
+
+        r = bus_append_strv_iter(&iter, args + 1);
+        if (r < 0)
+                return log_oom();
+
+        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+        if (!reply) {
+                log_error("Failed to issue method call: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        r = 0;
+
+finish:
+        dbus_error_free(&error);
+        return r;
+}
+
+static int enable_sysv_units(char **args) {
+        int r = 0;
+
+#if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
+        const char *verb = args[0];
+        unsigned f = 1, t = 1;
+        LookupPaths paths;
+
+        if (arg_scope != UNIT_FILE_SYSTEM)
+                return 0;
+
+        if (!streq(verb, "enable") &&
+            !streq(verb, "disable") &&
+            !streq(verb, "is-enabled"))
+                return 0;
+
+        /* Processes all SysV units, and reshuffles the array so that
+         * afterwards only the native units remain */
+
+        zero(paths);
+        r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
+        if (r < 0)
+                return r;
+
+        r = 0;
+        for (f = 1; args[f]; f++) {
+                const char *name;
+                char *p;
+                bool found_native = false, found_sysv;
+                unsigned c = 1;
+                const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
+                char **k, *l, *q = NULL;
+                int j;
+                pid_t pid;
+                siginfo_t status;
+
+                name = args[f];
+
+                if (!endswith(name, ".service"))
+                        continue;
+
+                if (path_is_absolute(name))
+                        continue;
+
+                STRV_FOREACH(k, paths.unit_path) {
+                        p = NULL;
+
+                        if (!isempty(arg_root))
+                                asprintf(&p, "%s/%s/%s", arg_root, *k, name);
+                        else
+                                asprintf(&p, "%s/%s", *k, name);
+
+                        if (!p) {
+                                r = log_oom();
+                                goto finish;
+                        }
+
+                        found_native = access(p, F_OK) >= 0;
+                        free(p);
+
+                        if (found_native)
+                                break;
+                }
+
+                if (found_native)
+                        continue;
+
+                p = NULL;
+                if (!isempty(arg_root))
+                        asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
+                else
+                        asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
+                if (!p) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                p[strlen(p) - sizeof(".service") + 1] = 0;
+                found_sysv = access(p, F_OK) >= 0;
+
+                if (!found_sysv) {
+                        free(p);
+                        continue;
+                }
+
+                /* Mark this entry, so that we don't try enabling it as native unit */
+                args[f] = (char*) "";
+
+                log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
+
+                if (!isempty(arg_root))
+                        argv[c++] = q = strappend("--root=", arg_root);
+
+                argv[c++] = path_get_file_name(p);
+                argv[c++] =
+                        streq(verb, "enable") ? "on" :
+                        streq(verb, "disable") ? "off" : "--level=5";
+                argv[c] = NULL;
+
+                l = strv_join((char**)argv, " ");
+                if (!l) {
+                        free(q);
+                        free(p);
+                        r = log_oom();
+                        goto finish;
+                }
+
+                log_info("Executing %s", l);
+                free(l);
+
+                pid = fork();
+                if (pid < 0) {
+                        log_error("Failed to fork: %m");
+                        free(p);
+                        free(q);
+                        r = -errno;
+                        goto finish;
+                } else if (pid == 0) {
+                        /* Child */
+
+                        execv(argv[0], (char**) argv);
+                        _exit(EXIT_FAILURE);
+                }
+
+                free(p);
+                free(q);
+
+                j = wait_for_terminate(pid, &status);
+                if (j < 0) {
+                        log_error("Failed to wait for child: %s", strerror(-r));
+                        r = j;
+                        goto finish;
+                }
+
+                if (status.si_code == CLD_EXITED) {
+                        if (streq(verb, "is-enabled")) {
+                                if (status.si_status == 0) {
+                                        if (!arg_quiet)
+                                                puts("enabled");
+                                        r = 1;
+                                } else {
+                                        if (!arg_quiet)
+                                                puts("disabled");
+                                }
+
+                        } else if (status.si_status != 0) {
+                                r = -EINVAL;
+                                goto finish;
+                        }
+                } else {
+                        r = -EPROTO;
+                        goto finish;
+                }
+        }
+
+finish:
+        lookup_paths_free(&paths);
+
+        /* Drop all SysV units */
+        for (f = 1, t = 1; args[f]; f++) {
+
+                if (isempty(args[f]))
+                        continue;
+
+                args[t++] = args[f];
+        }
+
+        args[t] = NULL;
+
+#endif
+        return r;
+}
+
+static int mangle_names(char **original_names, char ***mangled_names) {
+        char **i, **l, **name;
+
+        l = new(char*, strv_length(original_names) + 1);
+        if (!l)
+                return log_oom();
+
+        i = l;
+        STRV_FOREACH(name, original_names) {
+
+                /* When enabling units qualified path names are OK,
+                 * too, hence allow them explicitly. */
+
+                if (is_path(*name))
+                        *i = strdup(*name);
+                else
+                        *i = unit_name_mangle(*name);
+
+                if (!*i) {
+                        strv_free(l);
+                        return log_oom();
+                }
+
+                i++;
+        }
+
+        *i = NULL;
+        *mangled_names = l;
+
+        return 0;
+}
+
+static int enable_unit(DBusConnection *bus, char **args) {
+        const char *verb = args[0];
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0, i;
+        int carries_install_info = -1;
+        DBusMessage *m = NULL, *reply = NULL;
+        int r;
+        DBusError error;
+        char **mangled_names = NULL;
+
+        r = enable_sysv_units(args);
+        if (r < 0)
+                return r;
+
+        if (!args[1])
+                return 0;
+
+        dbus_error_init(&error);
+
+        if (!bus || avoid_bus()) {
+                if (streq(verb, "enable")) {
+                        r = unit_file_enable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
+                        carries_install_info = r;
+                } else if (streq(verb, "disable"))
+                        r = unit_file_disable(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes);
+                else if (streq(verb, "reenable")) {
+                        r = unit_file_reenable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
+                        carries_install_info = r;
+                } else if (streq(verb, "link"))
+                        r = unit_file_link(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
+                else if (streq(verb, "preset")) {
+                        r = unit_file_preset(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
+                        carries_install_info = r;
+                } else if (streq(verb, "mask"))
+                        r = unit_file_mask(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
+                else if (streq(verb, "unmask"))
+                        r = unit_file_unmask(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes);
+                else
+                        assert_not_reached("Unknown verb");
+
+                if (r < 0) {
+                        log_error("Operation failed: %s", strerror(-r));
+                        goto finish;
+                }
+
+                if (!arg_quiet) {
+                        for (i = 0; i < n_changes; i++) {
+                                if (changes[i].type == UNIT_FILE_SYMLINK)
+                                        log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
+                                else
+                                        log_info("rm '%s'", changes[i].path);
+                        }
+                }
+
+                r = 0;
+        } else {
+                const char *method;
+                bool send_force = true, expect_carries_install_info = false;
+                dbus_bool_t a, b;
+                DBusMessageIter iter, sub, sub2;
+
+                if (streq(verb, "enable")) {
+                        method = "EnableUnitFiles";
+                        expect_carries_install_info = true;
+                } else if (streq(verb, "disable")) {
+                        method = "DisableUnitFiles";
+                        send_force = false;
+                } else if (streq(verb, "reenable")) {
+                        method = "ReenableUnitFiles";
+                        expect_carries_install_info = true;
+                } else if (streq(verb, "link"))
+                        method = "LinkUnitFiles";
+                else if (streq(verb, "preset")) {
+                        method = "PresetUnitFiles";
+                        expect_carries_install_info = true;
+                } else if (streq(verb, "mask"))
+                        method = "MaskUnitFiles";
+                else if (streq(verb, "unmask")) {
+                        method = "UnmaskUnitFiles";
+                        send_force = false;
+                } else
+                        assert_not_reached("Unknown verb");
+
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                method);
+                if (!m) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                dbus_message_iter_init_append(m, &iter);
+
+                r = mangle_names(args+1, &mangled_names);
+                if(r < 0)
+                        goto finish;
+
+                r = bus_append_strv_iter(&iter, mangled_names);
+                if (r < 0) {
+                        log_error("Failed to append unit files.");
+                        goto finish;
+                }
+
+                a = arg_runtime;
+                if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &a)) {
+                        log_error("Failed to append runtime boolean.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (send_force) {
+                        b = arg_force;
+
+                        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b)) {
+                                log_error("Failed to append force boolean.");
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+                }
+
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+                if (!reply) {
+                        log_error("Failed to issue method call: %s", bus_error_message(&error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if (!dbus_message_iter_init(reply, &iter)) {
+                        log_error("Failed to initialize iterator.");
+                        goto finish;
+                }
+
+                if (expect_carries_install_info) {
+                        r = bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &b, true);
+                        if (r < 0) {
+                                log_error("Failed to parse reply.");
+                                goto finish;
+                        }
+
+                        carries_install_info = b;
+                }
+
+                if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+                    dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&iter, &sub);
+                while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                        const char *type, *path, *source;
+
+                        if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
+                                log_error("Failed to parse reply.");
+                                r = -EIO;
+                                goto finish;
+                        }
+
+                        dbus_message_iter_recurse(&sub, &sub2);
+
+                        if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) < 0 ||
+                            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0 ||
+                            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &source, false) < 0) {
+                                log_error("Failed to parse reply.");
+                                r = -EIO;
+                                goto finish;
+                        }
+
+                        if (!arg_quiet) {
+                                if (streq(type, "symlink"))
+                                        log_info("ln -s '%s' '%s'", source, path);
+                                else
+                                        log_info("rm '%s'", path);
+                        }
+
+                        dbus_message_iter_next(&sub);
+                }
+
+                /* Try to reload if enabeld */
+                if (!arg_no_reload)
+                        r = daemon_reload(bus, args);
+        }
+
+        if (carries_install_info == 0)
+                log_warning(
+"The unit files have no [Install] section. They are not meant to be enabled\n"
+"using systemctl.\n"
+"Possible reasons for having this kind of units are:\n"
+"1) A unit may be statically enabled by being symlinked from another unit's\n"
+"   .wants/ or .requires/ directory.\n"
+"2) A unit's purpose may be to act as a helper for some other unit which has\n"
+"   a requirement dependency on it.\n"
+"3) A unit may be started when needed via activation (socket, path, timer,\n"
+"   D-Bus, udev, scripted systemctl call, ...).\n");
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        unit_file_changes_free(changes, n_changes);
+
+        dbus_error_free(&error);
+
+        strv_free(mangled_names);
+
+        return r;
+}
+
+static int unit_is_enabled(DBusConnection *bus, char **args) {
+        DBusError error;
+        int r;
+        DBusMessage *reply = NULL;
+        bool enabled;
+        char **name;
+
+        dbus_error_init(&error);
+
+        r = enable_sysv_units(args);
+        if (r < 0)
+                return r;
+
+        enabled = r > 0;
+
+        if (!bus || avoid_bus()) {
+
+                STRV_FOREACH(name, args+1) {
+                        UnitFileState state;
+
+                        state = unit_file_get_state(arg_scope, arg_root, *name);
+                        if (state < 0) {
+                                r = state;
+                                goto finish;
+                        }
+
+                        if (state == UNIT_FILE_ENABLED ||
+                            state == UNIT_FILE_ENABLED_RUNTIME ||
+                            state == UNIT_FILE_STATIC)
+                                enabled = true;
+
+                        if (!arg_quiet)
+                                puts(unit_file_state_to_string(state));
+                }
+
+        } else {
+                STRV_FOREACH(name, args+1) {
+                        const char *s;
+
+                        r = bus_method_call_with_reply (
+                                        bus,
+                                        "org.freedesktop.systemd1",
+                                        "/org/freedesktop/systemd1",
+                                        "org.freedesktop.systemd1.Manager",
+                                        "GetUnitFileState",
+                                        &reply,
+                                        NULL,
+                                        DBUS_TYPE_STRING, name,
+                                        DBUS_TYPE_INVALID);
+                        if (r)
+                                goto finish;
+
+                        if (!dbus_message_get_args(reply, &error,
+                                                   DBUS_TYPE_STRING, &s,
+                                                   DBUS_TYPE_INVALID)) {
+                                log_error("Failed to parse reply: %s", bus_error_message(&error));
+                                r = -EIO;
+                                goto finish;
+                        }
+
+                        dbus_message_unref(reply);
+                        reply = NULL;
+
+                        if (streq(s, "enabled") ||
+                            streq(s, "enabled-runtime") ||
+                            streq(s, "static"))
+                                enabled = true;
+
+                        if (!arg_quiet)
+                                puts(s);
+                }
+        }
+
+        r = enabled ? 0 : 1;
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+        return r;
+}
+
+static int systemctl_help(void) {
+
+        pager_open_if_enabled();
+
+        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
+               "Query or send control commands to the systemd manager.\n\n"
+               "  -h --help           Show this help\n"
+               "     --version        Show package version\n"
+               "  -t --type=TYPE      List only units of a particular type\n"
+               "  -p --property=NAME  Show only properties by this name\n"
+               "  -a --all            Show all units/properties, including dead/empty ones\n"
+               "     --failed         Show only failed units\n"
+               "     --full           Don't ellipsize unit names on output\n"
+               "     --fail           When queueing a new job, fail if conflicting jobs are\n"
+               "                      pending\n"
+               "     --ignore-dependencies\n"
+               "                      When queueing a new job, ignore all its dependencies\n"
+               "     --kill-who=WHO   Who to send signal to\n"
+               "  -s --signal=SIGNAL  Which signal to send\n"
+               "  -H --host=[USER@]HOST\n"
+               "                      Show information for remote host\n"
+               "  -P --privileged     Acquire privileges before execution\n"
+               "  -q --quiet          Suppress output\n"
+               "     --no-block       Do not wait until operation finished\n"
+               "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
+               "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
+               "                      configuration\n"
+               "     --no-legend      Do not print a legend (column headers and hints)\n"
+               "     --no-pager       Do not pipe output into a pager\n"
+               "     --no-ask-password\n"
+               "                      Do not ask for system passwords\n"
+               "     --order          When generating graph for dot, show only order\n"
+               "     --require        When generating graph for dot, show only requirement\n"
+               "     --system         Connect to system manager\n"
+               "     --user           Connect to user service manager\n"
+               "     --global         Enable/disable unit files globally\n"
+               "  -f --force          When enabling unit files, override existing symlinks\n"
+               "                      When shutting down, execute action immediately\n"
+               "     --root=PATH      Enable unit files in the specified root directory\n"
+               "     --runtime        Enable unit files only temporarily until next reboot\n"
+               "  -n --lines=INTEGER  Journal entries to show\n"
+               "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
+               "                      verbose, export, json, json-pretty, json-sse, cat)\n\n"
+               "Unit Commands:\n"
+               "  list-units                      List loaded units\n"
+               "  start [NAME...]                 Start (activate) one or more units\n"
+               "  stop [NAME...]                  Stop (deactivate) one or more units\n"
+               "  reload [NAME...]                Reload one or more units\n"
+               "  restart [NAME...]               Start or restart one or more units\n"
+               "  try-restart [NAME...]           Restart one or more units if active\n"
+               "  reload-or-restart [NAME...]     Reload one or more units if possible,\n"
+               "                                  otherwise start or restart\n"
+               "  reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
+               "                                  otherwise restart if active\n"
+               "  isolate [NAME]                  Start one unit and stop all others\n"
+               "  kill [NAME...]                  Send signal to processes of a unit\n"
+               "  is-active [NAME...]             Check whether units are active\n"
+               "  is-failed [NAME...]             Check whether units are failed\n"
+               "  status [NAME...|PID...]         Show runtime status of one or more units\n"
+               "  show [NAME...|JOB...]           Show properties of one or more\n"
+               "                                  units/jobs or the manager\n"
+               "  help [NAME...|PID...]            Show manual for one or more units\n"
+               "  reset-failed [NAME...]          Reset failed state for all, one, or more\n"
+               "                                  units\n"
+               "  load [NAME...]                  Load one or more units\n\n"
+               "Unit File Commands:\n"
+               "  list-unit-files                 List installed unit files\n"
+               "  enable [NAME...]                Enable one or more unit files\n"
+               "  disable [NAME...]               Disable one or more unit files\n"
+               "  reenable [NAME...]              Reenable one or more unit files\n"
+               "  preset [NAME...]                Enable/disable one or more unit files\n"
+               "                                  based on preset configuration\n"
+               "  mask [NAME...]                  Mask one or more units\n"
+               "  unmask [NAME...]                Unmask one or more units\n"
+               "  link [PATH...]                  Link one or more units files into\n"
+               "                                  the search path\n"
+               "  is-enabled [NAME...]            Check whether unit files are enabled\n\n"
+               "Job Commands:\n"
+               "  list-jobs                       List jobs\n"
+               "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
+               "Status Commands:\n"
+               "  dump                            Dump server status\n"
+               "  dot                             Dump dependency graph for dot(1)\n\n"
+               "Snapshot Commands:\n"
+               "  snapshot [NAME]                 Create a snapshot\n"
+               "  delete [NAME...]                Remove one or more snapshots\n\n"
+               "Environment Commands:\n"
+               "  show-environment                Dump environment\n"
+               "  set-environment [NAME=VALUE...] Set one or more environment variables\n"
+               "  unset-environment [NAME...]     Unset one or more environment variables\n\n"
+               "Manager Lifecycle Commands:\n"
+               "  daemon-reload                   Reload systemd manager configuration\n"
+               "  daemon-reexec                   Reexecute systemd manager\n\n"
+               "System Commands:\n"
+               "  default                         Enter system default mode\n"
+               "  rescue                          Enter system rescue mode\n"
+               "  emergency                       Enter system emergency mode\n"
+               "  halt                            Shut down and halt the system\n"
+               "  poweroff                        Shut down and power-off the system\n"
+               "  reboot                          Shut down and reboot the system\n"
+               "  kexec                           Shut down and reboot the system with kexec\n"
+               "  exit                            Request user instance exit\n"
+               "  switch-root [ROOT] [INIT]       Change to a different root file system\n"
+               "  suspend                         Suspend the system\n"
+               "  hibernate                       Hibernate the system\n"
+               "  hybrid-sleep                    Hibernate and suspend the system\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int halt_help(void) {
+
+        printf("%s [OPTIONS...]\n\n"
+               "%s the system.\n\n"
+               "     --help      Show this help\n"
+               "     --halt      Halt the machine\n"
+               "  -p --poweroff  Switch off the machine\n"
+               "     --reboot    Reboot the machine\n"
+               "  -f --force     Force immediate halt/power-off/reboot\n"
+               "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
+               "  -d --no-wtmp   Don't write wtmp record\n"
+               "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
+               program_invocation_short_name,
+               arg_action == ACTION_REBOOT   ? "Reboot" :
+               arg_action == ACTION_POWEROFF ? "Power off" :
+                                               "Halt");
+
+        return 0;
+}
+
+static int shutdown_help(void) {
+
+        printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
+               "Shut down the system.\n\n"
+               "     --help      Show this help\n"
+               "  -H --halt      Halt the machine\n"
+               "  -P --poweroff  Power-off the machine\n"
+               "  -r --reboot    Reboot the machine\n"
+               "  -h             Equivalent to --poweroff, overridden by --halt\n"
+               "  -k             Don't halt/power-off/reboot, just send warnings\n"
+               "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
+               "  -c             Cancel a pending shutdown\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int telinit_help(void) {
+
+        printf("%s [OPTIONS...] {COMMAND}\n\n"
+               "Send control commands to the init daemon.\n\n"
+               "     --help      Show this help\n"
+               "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
+               "Commands:\n"
+               "  0              Power-off the machine\n"
+               "  6              Reboot the machine\n"
+               "  2, 3, 4, 5     Start runlevelX.target unit\n"
+               "  1, s, S        Enter rescue mode\n"
+               "  q, Q           Reload init daemon configuration\n"
+               "  u, U           Reexecute init daemon\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int runlevel_help(void) {
+
+        printf("%s [OPTIONS...]\n\n"
+               "Prints the previous and current runlevel of the init system.\n\n"
+               "     --help      Show this help\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int help_types(void) {
+        int i;
+
+        puts("Available unit types:");
+        for(i = UNIT_SERVICE; i < _UNIT_TYPE_MAX; i++)
+                if (unit_type_table[i])
+                        puts(unit_type_table[i]);
+
+        puts("\nAvailable unit load states: ");
+        for(i = UNIT_STUB; i < _UNIT_LOAD_STATE_MAX; i++)
+                if (unit_type_table[i])
+                        puts(unit_load_state_table[i]);
+
+        return 0;
+}
+
+static int systemctl_parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_FAIL = 0x100,
+                ARG_IGNORE_DEPENDENCIES,
+                ARG_VERSION,
+                ARG_USER,
+                ARG_SYSTEM,
+                ARG_GLOBAL,
+                ARG_NO_BLOCK,
+                ARG_NO_LEGEND,
+                ARG_NO_PAGER,
+                ARG_NO_WALL,
+                ARG_ORDER,
+                ARG_REQUIRE,
+                ARG_ROOT,
+                ARG_FULL,
+                ARG_NO_RELOAD,
+                ARG_KILL_WHO,
+                ARG_NO_ASK_PASSWORD,
+                ARG_FAILED,
+                ARG_RUNTIME,
+                ARG_FORCE
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "type",      required_argument, NULL, 't'           },
+                { "property",  required_argument, NULL, 'p'           },
+                { "all",       no_argument,       NULL, 'a'           },
+                { "failed",    no_argument,       NULL, ARG_FAILED    },
+                { "full",      no_argument,       NULL, ARG_FULL      },
+                { "fail",      no_argument,       NULL, ARG_FAIL      },
+                { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
+                { "user",      no_argument,       NULL, ARG_USER      },
+                { "system",    no_argument,       NULL, ARG_SYSTEM    },
+                { "global",    no_argument,       NULL, ARG_GLOBAL    },
+                { "no-block",  no_argument,       NULL, ARG_NO_BLOCK  },
+                { "no-legend", no_argument,       NULL, ARG_NO_LEGEND },
+                { "no-pager",  no_argument,       NULL, ARG_NO_PAGER  },
+                { "no-wall",   no_argument,       NULL, ARG_NO_WALL   },
+                { "quiet",     no_argument,       NULL, 'q'           },
+                { "order",     no_argument,       NULL, ARG_ORDER     },
+                { "require",   no_argument,       NULL, ARG_REQUIRE   },
+                { "root",      required_argument, NULL, ARG_ROOT      },
+                { "force",     no_argument,       NULL, ARG_FORCE     },
+                { "no-reload", no_argument,       NULL, ARG_NO_RELOAD },
+                { "kill-who",  required_argument, NULL, ARG_KILL_WHO  },
+                { "signal",    required_argument, NULL, 's'           },
+                { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
+                { "host",      required_argument, NULL, 'H'           },
+                { "privileged",no_argument,       NULL, 'P'           },
+                { "runtime",   no_argument,       NULL, ARG_RUNTIME   },
+                { "lines",     required_argument, NULL, 'n'           },
+                { "output",    required_argument, NULL, 'o'           },
+                { NULL,        0,                 NULL, 0             }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:Pn:o:", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        systemctl_help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case 't':
+                        if (streq(optarg, "help")) {
+                                help_types();
+                                return 0;
+                        }
+
+                        if (unit_type_from_string(optarg) >= 0) {
+                                arg_type = optarg;
+                                break;
+                        }
+                        if (unit_load_state_from_string(optarg) >= 0) {
+                                arg_load_state = optarg;
+                                break;
+                        }
+                        log_error("Unkown unit type or load state '%s'.",
+                                  optarg);
+                        log_info("Use -t help to see a list of allowed values.");
+                        return -EINVAL;
+                case 'p': {
+                        char **l;
+
+                        if (!(l = strv_append(arg_property, optarg)))
+                                return -ENOMEM;
+
+                        strv_free(arg_property);
+                        arg_property = l;
+
+                        /* If the user asked for a particular
+                         * property, show it to him, even if it is
+                         * empty. */
+                        arg_all = true;
+                        break;
+                }
+
+                case 'a':
+                        arg_all = true;
+                        break;
+
+                case ARG_FAIL:
+                        arg_job_mode = "fail";
+                        break;
+
+                case ARG_IGNORE_DEPENDENCIES:
+                        arg_job_mode = "ignore-dependencies";
+                        break;
+
+                case ARG_USER:
+                        arg_scope = UNIT_FILE_USER;
+                        break;
+
+                case ARG_SYSTEM:
+                        arg_scope = UNIT_FILE_SYSTEM;
+                        break;
+
+                case ARG_GLOBAL:
+                        arg_scope = UNIT_FILE_GLOBAL;
+                        break;
+
+                case ARG_NO_BLOCK:
+                        arg_no_block = true;
+                        break;
+
+                case ARG_NO_LEGEND:
+                        arg_no_legend = true;
+                        break;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case ARG_NO_WALL:
+                        arg_no_wall = true;
+                        break;
+
+                case ARG_ORDER:
+                        arg_dot = DOT_ORDER;
+                        break;
+
+                case ARG_REQUIRE:
+                        arg_dot = DOT_REQUIRE;
+                        break;
+
+                case ARG_ROOT:
+                        arg_root = optarg;
+                        break;
+
+                case ARG_FULL:
+                        arg_full = true;
+                        break;
+
+                case ARG_FAILED:
+                        arg_failed = true;
+                        break;
+
+                case 'q':
+                        arg_quiet = true;
+                        break;
+
+                case ARG_FORCE:
+                        arg_force ++;
+                        break;
+
+                case 'f':
+                        arg_force ++;
+                        break;
+
+                case ARG_NO_RELOAD:
+                        arg_no_reload = true;
+                        break;
+
+                case ARG_KILL_WHO:
+                        arg_kill_who = optarg;
+                        break;
+
+                case 's':
+                        if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
+                                log_error("Failed to parse signal string %s.", optarg);
+                                return -EINVAL;
+                        }
+                        break;
+
+                case ARG_NO_ASK_PASSWORD:
+                        arg_ask_password = false;
+                        break;
+
+                case 'P':
+                        arg_transport = TRANSPORT_POLKIT;
+                        break;
+
+                case 'H':
+                        arg_transport = TRANSPORT_SSH;
+                        arg_host = optarg;
+                        break;
+
+                case ARG_RUNTIME:
+                        arg_runtime = true;
+                        break;
+
+                case 'n':
+                        if (safe_atou(optarg, &arg_lines) < 0) {
+                                log_error("Failed to parse lines '%s'", optarg);
+                                return -EINVAL;
+                        }
+                        break;
+
+                case 'o':
+                        arg_output = output_mode_from_string(optarg);
+                        if (arg_output < 0) {
+                                log_error("Unknown output '%s'.", optarg);
+                                return -EINVAL;
+                        }
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code '%c'.", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (arg_transport != TRANSPORT_NORMAL && arg_scope != UNIT_FILE_SYSTEM) {
+                log_error("Cannot access user instance remotely.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+static int halt_parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_HELP = 0x100,
+                ARG_HALT,
+                ARG_REBOOT,
+                ARG_NO_WALL
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, ARG_HELP    },
+                { "halt",      no_argument,       NULL, ARG_HALT    },
+                { "poweroff",  no_argument,       NULL, 'p'         },
+                { "reboot",    no_argument,       NULL, ARG_REBOOT  },
+                { "force",     no_argument,       NULL, 'f'         },
+                { "wtmp-only", no_argument,       NULL, 'w'         },
+                { "no-wtmp",   no_argument,       NULL, 'd'         },
+                { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
+                { NULL,        0,                 NULL, 0           }
+        };
+
+        int c, runlevel;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        if (utmp_get_runlevel(&runlevel, NULL) >= 0)
+                if (runlevel == '0' || runlevel == '6')
+                        arg_force = 2;
+
+        while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
+                switch (c) {
+
+                case ARG_HELP:
+                        halt_help();
+                        return 0;
+
+                case ARG_HALT:
+                        arg_action = ACTION_HALT;
+                        break;
+
+                case 'p':
+                        if (arg_action != ACTION_REBOOT)
+                                arg_action = ACTION_POWEROFF;
+                        break;
+
+                case ARG_REBOOT:
+                        arg_action = ACTION_REBOOT;
+                        break;
+
+                case 'f':
+                        arg_force = 2;
+                        break;
+
+                case 'w':
+                        arg_dry = true;
+                        break;
+
+                case 'd':
+                        arg_no_wtmp = true;
+                        break;
+
+                case ARG_NO_WALL:
+                        arg_no_wall = true;
+                        break;
+
+                case 'i':
+                case 'h':
+                case 'n':
+                        /* Compatibility nops */
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code '%c'.", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind < argc) {
+                log_error("Too many arguments.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+static int parse_time_spec(const char *t, usec_t *_u) {
+        assert(t);
+        assert(_u);
+
+        if (streq(t, "now"))
+                *_u = 0;
+        else if (!strchr(t, ':')) {
+                uint64_t u;
+
+                if (safe_atou64(t, &u) < 0)
+                        return -EINVAL;
+
+                *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
+        } else {
+                char *e = NULL;
+                long hour, minute;
+                struct tm tm;
+                time_t s;
+                usec_t n;
+
+                errno = 0;
+                hour = strtol(t, &e, 10);
+                if (errno != 0 || *e != ':' || hour < 0 || hour > 23)
+                        return -EINVAL;
+
+                minute = strtol(e+1, &e, 10);
+                if (errno != 0 || *e != 0 || minute < 0 || minute > 59)
+                        return -EINVAL;
+
+                n = now(CLOCK_REALTIME);
+                s = (time_t) (n / USEC_PER_SEC);
+
+                zero(tm);
+                assert_se(localtime_r(&s, &tm));
+
+                tm.tm_hour = (int) hour;
+                tm.tm_min = (int) minute;
+                tm.tm_sec = 0;
+
+                assert_se(s = mktime(&tm));
+
+                *_u = (usec_t) s * USEC_PER_SEC;
+
+                while (*_u <= n)
+                        *_u += USEC_PER_DAY;
+        }
+
+        return 0;
+}
+
+static int shutdown_parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_HELP = 0x100,
+                ARG_NO_WALL
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, ARG_HELP    },
+                { "halt",      no_argument,       NULL, 'H'         },
+                { "poweroff",  no_argument,       NULL, 'P'         },
+                { "reboot",    no_argument,       NULL, 'r'         },
+                { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
+                { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
+                { NULL,        0,                 NULL, 0           }
+        };
+
+        int c, r;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
+                switch (c) {
+
+                case ARG_HELP:
+                        shutdown_help();
+                        return 0;
+
+                case 'H':
+                        arg_action = ACTION_HALT;
+                        break;
+
+                case 'P':
+                        arg_action = ACTION_POWEROFF;
+                        break;
+
+                case 'r':
+                        if (kexec_loaded())
+                                arg_action = ACTION_KEXEC;
+                        else
+                                arg_action = ACTION_REBOOT;
+                        break;
+
+                case 'K':
+                        arg_action = ACTION_KEXEC;
+                        break;
+
+                case 'h':
+                        if (arg_action != ACTION_HALT)
+                                arg_action = ACTION_POWEROFF;
+                        break;
+
+                case 'k':
+                        arg_dry = true;
+                        break;
+
+                case ARG_NO_WALL:
+                        arg_no_wall = true;
+                        break;
+
+                case 't':
+                case 'a':
+                        /* Compatibility nops */
+                        break;
+
+                case 'c':
+                        arg_action = ACTION_CANCEL_SHUTDOWN;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code '%c'.", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
+                r = parse_time_spec(argv[optind], &arg_when);
+                if (r < 0) {
+                        log_error("Failed to parse time specification: %s", argv[optind]);
+                        return r;
+                }
+        } else
+                arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
+
+        if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
+                /* No time argument for shutdown cancel */
+                arg_wall = argv + optind;
+        else if (argc > optind + 1)
+                /* We skip the time argument */
+                arg_wall = argv + optind + 1;
+
+        optind = argc;
+
+        return 1;
+}
+
+static int telinit_parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_HELP = 0x100,
+                ARG_NO_WALL
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, ARG_HELP    },
+                { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
+                { NULL,        0,                 NULL, 0           }
+        };
+
+        static const struct {
+                char from;
+                enum action to;
+        } table[] = {
+                { '0', ACTION_POWEROFF },
+                { '6', ACTION_REBOOT },
+                { '1', ACTION_RESCUE },
+                { '2', ACTION_RUNLEVEL2 },
+                { '3', ACTION_RUNLEVEL3 },
+                { '4', ACTION_RUNLEVEL4 },
+                { '5', ACTION_RUNLEVEL5 },
+                { 's', ACTION_RESCUE },
+                { 'S', ACTION_RESCUE },
+                { 'q', ACTION_RELOAD },
+                { 'Q', ACTION_RELOAD },
+                { 'u', ACTION_REEXEC },
+                { 'U', ACTION_REEXEC }
+        };
+
+        unsigned i;
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
+                switch (c) {
+
+                case ARG_HELP:
+                        telinit_help();
+                        return 0;
+
+                case ARG_NO_WALL:
+                        arg_no_wall = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code '%c'.", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind >= argc) {
+                telinit_help();
+                return -EINVAL;
+        }
+
+        if (optind + 1 < argc) {
+                log_error("Too many arguments.");
+                return -EINVAL;
+        }
+
+        if (strlen(argv[optind]) != 1) {
+                log_error("Expected single character argument.");
+                return -EINVAL;
+        }
+
+        for (i = 0; i < ELEMENTSOF(table); i++)
+                if (table[i].from == argv[optind][0])
+                        break;
+
+        if (i >= ELEMENTSOF(table)) {
+                log_error("Unknown command '%s'.", argv[optind]);
+                return -EINVAL;
+        }
+
+        arg_action = table[i].to;
+
+        optind ++;
+
+        return 1;
+}
+
+static int runlevel_parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_HELP = 0x100,
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, ARG_HELP    },
+                { NULL,        0,                 NULL, 0           }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
+                switch (c) {
+
+                case ARG_HELP:
+                        runlevel_help();
+                        return 0;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code '%c'.", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind < argc) {
+                log_error("Too many arguments.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+        assert(argc >= 0);
+        assert(argv);
+
+        if (program_invocation_short_name) {
+
+                if (strstr(program_invocation_short_name, "halt")) {
+                        arg_action = ACTION_HALT;
+                        return halt_parse_argv(argc, argv);
+                } else if (strstr(program_invocation_short_name, "poweroff")) {
+                        arg_action = ACTION_POWEROFF;
+                        return halt_parse_argv(argc, argv);
+                } else if (strstr(program_invocation_short_name, "reboot")) {
+                        if (kexec_loaded())
+                                arg_action = ACTION_KEXEC;
+                        else
+                                arg_action = ACTION_REBOOT;
+                        return halt_parse_argv(argc, argv);
+                } else if (strstr(program_invocation_short_name, "shutdown")) {
+                        arg_action = ACTION_POWEROFF;
+                        return shutdown_parse_argv(argc, argv);
+                } else if (strstr(program_invocation_short_name, "init")) {
+
+                        if (sd_booted() > 0) {
+                                arg_action = ACTION_INVALID;
+                                return telinit_parse_argv(argc, argv);
+                        } else {
+                                /* Hmm, so some other init system is
+                                 * running, we need to forward this
+                                 * request to it. For now we simply
+                                 * guess that it is Upstart. */
+
+                                execv("/lib/upstart/telinit", argv);
+
+                                log_error("Couldn't find an alternative telinit implementation to spawn.");
+                                return -EIO;
+                        }
+
+                } else if (strstr(program_invocation_short_name, "runlevel")) {
+                        arg_action = ACTION_RUNLEVEL;
+                        return runlevel_parse_argv(argc, argv);
+                }
+        }
+
+        arg_action = ACTION_SYSTEMCTL;
+        return systemctl_parse_argv(argc, argv);
+}
+
+static int action_to_runlevel(void) {
+
+        static const char table[_ACTION_MAX] = {
+                [ACTION_HALT] =      '0',
+                [ACTION_POWEROFF] =  '0',
+                [ACTION_REBOOT] =    '6',
+                [ACTION_RUNLEVEL2] = '2',
+                [ACTION_RUNLEVEL3] = '3',
+                [ACTION_RUNLEVEL4] = '4',
+                [ACTION_RUNLEVEL5] = '5',
+                [ACTION_RESCUE] =    '1'
+        };
+
+        assert(arg_action < _ACTION_MAX);
+
+        return table[arg_action];
+}
+
+static int talk_upstart(void) {
+        DBusMessage *m = NULL, *reply = NULL;
+        DBusError error;
+        int previous, rl, r;
+        char
+                env1_buf[] = "RUNLEVEL=X",
+                env2_buf[] = "PREVLEVEL=X";
+        char *env1 = env1_buf, *env2 = env2_buf;
+        const char *emit = "runlevel";
+        dbus_bool_t b_false = FALSE;
+        DBusMessageIter iter, sub;
+        DBusConnection *bus;
+
+        dbus_error_init(&error);
+
+        if (!(rl = action_to_runlevel()))
+                return 0;
+
+        if (utmp_get_runlevel(&previous, NULL) < 0)
+                previous = 'N';
+
+        if (!(bus = dbus_connection_open_private("unix:abstract=/com/ubuntu/upstart", &error))) {
+                if (dbus_error_has_name(&error, DBUS_ERROR_NO_SERVER)) {
+                        r = 0;
+                        goto finish;
+                }
+
+                log_error("Failed to connect to Upstart bus: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        if ((r = bus_check_peercred(bus)) < 0) {
+                log_error("Failed to verify owner of bus.");
+                goto finish;
+        }
+
+        if (!(m = dbus_message_new_method_call(
+                              "com.ubuntu.Upstart",
+                              "/com/ubuntu/Upstart",
+                              "com.ubuntu.Upstart0_6",
+                              "EmitEvent"))) {
+
+                log_error("Could not allocate message.");
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        dbus_message_iter_init_append(m, &iter);
+
+        env1_buf[sizeof(env1_buf)-2] = rl;
+        env2_buf[sizeof(env2_buf)-2] = previous;
+
+        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &emit) ||
+            !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &env1) ||
+            !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &env2) ||
+            !dbus_message_iter_close_container(&iter, &sub) ||
+            !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b_false)) {
+                log_error("Could not append arguments to message.");
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+
+                if (bus_error_is_no_service(&error)) {
+                        r = -EADDRNOTAVAIL;
+                        goto finish;
+                }
+
+                log_error("Failed to issue method call: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        r = 1;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int talk_initctl(void) {
+        struct init_request request;
+        int r, fd;
+        char rl;
+
+        if (!(rl = action_to_runlevel()))
+                return 0;
+
+        zero(request);
+        request.magic = INIT_MAGIC;
+        request.sleeptime = 0;
+        request.cmd = INIT_CMD_RUNLVL;
+        request.runlevel = rl;
+
+        if ((fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY)) < 0) {
+
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open "INIT_FIFO": %m");
+                return -errno;
+        }
+
+        errno = 0;
+        r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
+        close_nointr_nofail(fd);
+
+        if (r < 0) {
+                log_error("Failed to write to "INIT_FIFO": %m");
+                return errno ? -errno : -EIO;
+        }
+
+        return 1;
+}
+
+static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) {
+
+        static const struct {
+                const char* verb;
+                const enum {
+                        MORE,
+                        LESS,
+                        EQUAL
+                } argc_cmp;
+                const int argc;
+                int (* const dispatch)(DBusConnection *bus, char **args);
+        } verbs[] = {
+                { "list-units",            LESS,  1, list_units        },
+                { "list-unit-files",       EQUAL, 1, list_unit_files   },
+                { "list-jobs",             EQUAL, 1, list_jobs         },
+                { "clear-jobs",            EQUAL, 1, daemon_reload     },
+                { "load",                  MORE,  2, load_unit         },
+                { "cancel",                MORE,  2, cancel_job        },
+                { "start",                 MORE,  2, start_unit        },
+                { "stop",                  MORE,  2, start_unit        },
+                { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
+                { "reload",                MORE,  2, start_unit        },
+                { "restart",               MORE,  2, start_unit        },
+                { "try-restart",           MORE,  2, start_unit        },
+                { "reload-or-restart",     MORE,  2, start_unit        },
+                { "reload-or-try-restart", MORE,  2, start_unit        },
+                { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
+                { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
+                { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
+                { "isolate",               EQUAL, 2, start_unit        },
+                { "kill",                  MORE,  2, kill_unit         },
+                { "is-active",             MORE,  2, check_unit_active },
+                { "check",                 MORE,  2, check_unit_active },
+                { "is-failed",             MORE,  2, check_unit_failed },
+                { "show",                  MORE,  1, show              },
+                { "status",                MORE,  2, show              },
+                { "help",                  MORE,  2, show              },
+                { "dump",                  EQUAL, 1, dump              },
+                { "dot",                   EQUAL, 1, dot               },
+                { "snapshot",              LESS,  2, snapshot          },
+                { "delete",                MORE,  2, delete_snapshot   },
+                { "daemon-reload",         EQUAL, 1, daemon_reload     },
+                { "daemon-reexec",         EQUAL, 1, daemon_reload     },
+                { "show-environment",      EQUAL, 1, show_enviroment   },
+                { "set-environment",       MORE,  2, set_environment   },
+                { "unset-environment",     MORE,  2, set_environment   },
+                { "halt",                  EQUAL, 1, start_special     },
+                { "poweroff",              EQUAL, 1, start_special     },
+                { "reboot",                EQUAL, 1, start_special     },
+                { "kexec",                 EQUAL, 1, start_special     },
+                { "suspend",               EQUAL, 1, start_special     },
+                { "hibernate",             EQUAL, 1, start_special     },
+                { "hybrid-sleep",          EQUAL, 1, start_special     },
+                { "default",               EQUAL, 1, start_special     },
+                { "rescue",                EQUAL, 1, start_special     },
+                { "emergency",             EQUAL, 1, start_special     },
+                { "exit",                  EQUAL, 1, start_special     },
+                { "reset-failed",          MORE,  1, reset_failed      },
+                { "enable",                MORE,  2, enable_unit       },
+                { "disable",               MORE,  2, enable_unit       },
+                { "is-enabled",            MORE,  2, unit_is_enabled   },
+                { "reenable",              MORE,  2, enable_unit       },
+                { "preset",                MORE,  2, enable_unit       },
+                { "mask",                  MORE,  2, enable_unit       },
+                { "unmask",                MORE,  2, enable_unit       },
+                { "link",                  MORE,  2, enable_unit       },
+                { "switch-root",           MORE,  2, switch_root       },
+        };
+
+        int left;
+        unsigned i;
+
+        assert(argc >= 0);
+        assert(argv);
+        assert(error);
+
+        left = argc - optind;
+
+        if (left <= 0)
+                /* Special rule: no arguments means "list-units" */
+                i = 0;
+        else {
+                if (streq(argv[optind], "help") && !argv[optind+1]) {
+                        log_error("This command expects one or more "
+                                  "unit names. Did you mean --help?");
+                        return -EINVAL;
+                }
+
+                for (i = 0; i < ELEMENTSOF(verbs); i++)
+                        if (streq(argv[optind], verbs[i].verb))
+                                break;
+
+                if (i >= ELEMENTSOF(verbs)) {
+                        log_error("Unknown operation '%s'.", argv[optind]);
+                        return -EINVAL;
+                }
+        }
+
+        switch (verbs[i].argc_cmp) {
+
+        case EQUAL:
+                if (left != verbs[i].argc) {
+                        log_error("Invalid number of arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case MORE:
+                if (left < verbs[i].argc) {
+                        log_error("Too few arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case LESS:
+                if (left > verbs[i].argc) {
+                        log_error("Too many arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("Unknown comparison operator.");
+        }
+
+        /* Require a bus connection for all operations but
+         * enable/disable */
+        if (!streq(verbs[i].verb, "enable") &&
+            !streq(verbs[i].verb, "disable") &&
+            !streq(verbs[i].verb, "is-enabled") &&
+            !streq(verbs[i].verb, "list-unit-files") &&
+            !streq(verbs[i].verb, "reenable") &&
+            !streq(verbs[i].verb, "preset") &&
+            !streq(verbs[i].verb, "mask") &&
+            !streq(verbs[i].verb, "unmask") &&
+            !streq(verbs[i].verb, "link")) {
+
+                if (running_in_chroot() > 0) {
+                        log_info("Running in chroot, ignoring request.");
+                        return 0;
+                }
+
+                if (((!streq(verbs[i].verb, "reboot") &&
+                      !streq(verbs[i].verb, "halt") &&
+                      !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
+                        log_error("Failed to get D-Bus connection: %s",
+                                  dbus_error_is_set(error) ? error->message : "No connection to service manager.");
+                        return -EIO;
+                }
+
+        } else {
+
+                if (!bus && !avoid_bus()) {
+                        log_error("Failed to get D-Bus connection: %s",
+                                  dbus_error_is_set(error) ? error->message : "No connection to service manager.");
+                        return -EIO;
+                }
+        }
+
+        return verbs[i].dispatch(bus, argv + optind);
+}
+
+static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
+        int fd;
+        struct msghdr msghdr;
+        struct iovec iovec[2];
+        union sockaddr_union sockaddr;
+        struct sd_shutdown_command c;
+
+        fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+        if (fd < 0)
+                return -errno;
+
+        zero(c);
+        c.usec = t;
+        c.mode = mode;
+        c.dry_run = dry_run;
+        c.warn_wall = warn;
+
+        zero(sockaddr);
+        sockaddr.sa.sa_family = AF_UNIX;
+        strncpy(sockaddr.un.sun_path, "/run/systemd/shutdownd", sizeof(sockaddr.un.sun_path));
+
+        zero(msghdr);
+        msghdr.msg_name = &sockaddr;
+        msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + sizeof("/run/systemd/shutdownd") - 1;
+
+        zero(iovec);
+        iovec[0].iov_base = (char*) &c;
+        iovec[0].iov_len = offsetof(struct sd_shutdown_command, wall_message);
+
+        if (isempty(message))
+                msghdr.msg_iovlen = 1;
+        else {
+                iovec[1].iov_base = (char*) message;
+                iovec[1].iov_len = strlen(message);
+                msghdr.msg_iovlen = 2;
+        }
+        msghdr.msg_iov = iovec;
+
+        if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
+                close_nointr_nofail(fd);
+                return -errno;
+        }
+
+        close_nointr_nofail(fd);
+        return 0;
+}
+
+static int reload_with_fallback(DBusConnection *bus) {
+
+        if (bus) {
+                /* First, try systemd via D-Bus. */
+                if (daemon_reload(bus, NULL) >= 0)
+                        return 0;
+        }
+
+        /* Nothing else worked, so let's try signals */
+        assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
+
+        if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
+                log_error("kill() failed: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+static int start_with_fallback(DBusConnection *bus) {
+
+        if (bus) {
+                /* First, try systemd via D-Bus. */
+                if (start_unit(bus, NULL) >= 0)
+                        goto done;
+        }
+
+        /* Hmm, talking to systemd via D-Bus didn't work. Then
+         * let's try to talk to Upstart via D-Bus. */
+        if (talk_upstart() > 0)
+                goto done;
+
+        /* Nothing else worked, so let's try
+         * /dev/initctl */
+        if (talk_initctl() > 0)
+                goto done;
+
+        log_error("Failed to talk to init daemon.");
+        return -EIO;
+
+done:
+        warn_wall(arg_action);
+        return 0;
+}
+
+static _noreturn_ void halt_now(enum action a) {
+
+       /* Make sure C-A-D is handled by the kernel from this
+         * point on... */
+        reboot(RB_ENABLE_CAD);
+
+        switch (a) {
+
+        case ACTION_HALT:
+                log_info("Halting.");
+                reboot(RB_HALT_SYSTEM);
+                break;
+
+        case ACTION_POWEROFF:
+                log_info("Powering off.");
+                reboot(RB_POWER_OFF);
+                break;
+
+        case ACTION_REBOOT:
+                log_info("Rebooting.");
+                reboot(RB_AUTOBOOT);
+                break;
+
+        default:
+                assert_not_reached("Unknown halt action.");
+        }
+
+        assert_not_reached("Uh? This shouldn't happen.");
+}
+
+static int halt_main(DBusConnection *bus) {
+        int r;
+
+        if (geteuid() != 0) {
+                /* Try logind if we are a normal user and no special
+                 * mode applies. Maybe PolicyKit allows us to shutdown
+                 * the machine. */
+
+                if (arg_when <= 0 &&
+                    !arg_dry &&
+                    !arg_force &&
+                    (arg_action == ACTION_POWEROFF ||
+                     arg_action == ACTION_REBOOT)) {
+                        r = reboot_with_logind(bus, arg_action);
+                        if (r >= 0)
+                                return r;
+                }
+
+                log_error("Must be root.");
+                return -EPERM;
+        }
+
+        if (arg_when > 0) {
+                char *m;
+
+                m = strv_join(arg_wall, " ");
+                r = send_shutdownd(arg_when,
+                                   arg_action == ACTION_HALT     ? 'H' :
+                                   arg_action == ACTION_POWEROFF ? 'P' :
+                                   arg_action == ACTION_KEXEC    ? 'K' :
+                                                                   'r',
+                                   arg_dry,
+                                   !arg_no_wall,
+                                   m);
+                free(m);
+
+                if (r < 0)
+                        log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
+                else {
+                        char date[FORMAT_TIMESTAMP_MAX];
+
+                        log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
+                                 format_timestamp(date, sizeof(date), arg_when));
+                        return 0;
+                }
+        }
+
+        if (!arg_dry && !arg_force)
+                return start_with_fallback(bus);
+
+        if (!arg_no_wtmp) {
+                if (sd_booted() > 0)
+                        log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
+                else {
+                        r = utmp_put_shutdown();
+                        if (r < 0)
+                                log_warning("Failed to write utmp record: %s", strerror(-r));
+                }
+        }
+
+        if (arg_dry)
+                return 0;
+
+        halt_now(arg_action);
+        /* We should never reach this. */
+        return -ENOSYS;
+}
+
+static int runlevel_main(void) {
+        int r, runlevel, previous;
+
+        r = utmp_get_runlevel(&runlevel, &previous);
+        if (r < 0) {
+                puts("unknown");
+                return r;
+        }
+
+        printf("%c %c\n",
+               previous <= 0 ? 'N' : previous,
+               runlevel <= 0 ? 'N' : runlevel);
+
+        return 0;
+}
+
+int main(int argc, char*argv[]) {
+        int r, retval = EXIT_FAILURE;
+        DBusConnection *bus = NULL;
+        DBusError error;
+
+        dbus_error_init(&error);
+
+        setlocale(LC_ALL, "");
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                goto finish;
+        else if (r == 0) {
+                retval = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        /* /sbin/runlevel doesn't need to communicate via D-Bus, so
+         * let's shortcut this */
+        if (arg_action == ACTION_RUNLEVEL) {
+                r = runlevel_main();
+                retval = r < 0 ? EXIT_FAILURE : r;
+                goto finish;
+        }
+
+        if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
+                log_info("Running in chroot, ignoring request.");
+                retval = 0;
+                goto finish;
+        }
+
+        if (!avoid_bus()) {
+                if (arg_transport == TRANSPORT_NORMAL)
+                        bus_connect(arg_scope == UNIT_FILE_SYSTEM ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, &bus, &private_bus, &error);
+                else if (arg_transport == TRANSPORT_POLKIT) {
+                        bus_connect_system_polkit(&bus, &error);
+                        private_bus = false;
+                } else if (arg_transport == TRANSPORT_SSH) {
+                        bus_connect_system_ssh(NULL, arg_host, &bus, &error);
+                        private_bus = false;
+                } else
+                        assert_not_reached("Uh, invalid transport...");
+        }
+
+        switch (arg_action) {
+
+        case ACTION_SYSTEMCTL:
+                r = systemctl_main(bus, argc, argv, &error);
+                break;
+
+        case ACTION_HALT:
+        case ACTION_POWEROFF:
+        case ACTION_REBOOT:
+        case ACTION_KEXEC:
+                r = halt_main(bus);
+                break;
+
+        case ACTION_RUNLEVEL2:
+        case ACTION_RUNLEVEL3:
+        case ACTION_RUNLEVEL4:
+        case ACTION_RUNLEVEL5:
+        case ACTION_RESCUE:
+        case ACTION_EMERGENCY:
+        case ACTION_DEFAULT:
+                r = start_with_fallback(bus);
+                break;
+
+        case ACTION_RELOAD:
+        case ACTION_REEXEC:
+                r = reload_with_fallback(bus);
+                break;
+
+        case ACTION_CANCEL_SHUTDOWN: {
+                char *m = NULL;
+
+                if (arg_wall) {
+                        m = strv_join(arg_wall, " ");
+                        if (!m) {
+                                retval = EXIT_FAILURE;
+                                goto finish;
+                        }
+                }
+                r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
+                if (r < 0)
+                        log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
+                free(m);
+                break;
+        }
+
+        case ACTION_INVALID:
+        case ACTION_RUNLEVEL:
+        default:
+                assert_not_reached("Unknown action");
+        }
+
+        retval = r < 0 ? EXIT_FAILURE : r;
+
+finish:
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        dbus_error_free(&error);
+
+        dbus_shutdown();
+
+        strv_free(arg_property);
+
+        pager_close();
+        ask_password_agent_close();
+        polkit_agent_close();
+
+        return retval;
+}
diff --git a/src/systemd/Makefile b/src/systemd/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/systemd/sd-daemon.h b/src/systemd/sd-daemon.h
new file mode 100644 (file)
index 0000000..fb7456d
--- /dev/null
@@ -0,0 +1,282 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosddaemonhfoo
+#define foosddaemonhfoo
+
+/***
+  Copyright 2010 Lennart Poettering
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+***/
+
+#include <sys/types.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+  Reference implementation of a few systemd related interfaces for
+  writing daemons. These interfaces are trivial to implement. To
+  simplify porting we provide this reference implementation.
+  Applications are welcome to reimplement the algorithms described
+  here if they do not want to include these two source files.
+
+  The following functionality is provided:
+
+  - Support for logging with log levels on stderr
+  - File descriptor passing for socket-based activation
+  - Daemon startup and status notification
+  - Detection of systemd boots
+
+  You may compile this with -DDISABLE_SYSTEMD to disable systemd
+  support. This makes all those calls NOPs that are directly related to
+  systemd (i.e. only sd_is_xxx() will stay useful).
+
+  Since this is drop-in code we don't want any of our symbols to be
+  exported in any case. Hence we declare hidden visibility for all of
+  them.
+
+  You may find an up-to-date version of these source files online:
+
+  http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h
+  http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c
+
+  This should compile on non-Linux systems, too, but with the
+  exception of the sd_is_xxx() calls all functions will become NOPs.
+
+  See sd-daemon(3) for more information.
+*/
+
+#ifndef _sd_printf_attr_
+#if __GNUC__ >= 4
+#define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
+#else
+#define _sd_printf_attr_(a,b)
+#endif
+#endif
+
+/*
+  Log levels for usage on stderr:
+
+          fprintf(stderr, SD_NOTICE "Hello World!\n");
+
+  This is similar to printk() usage in the kernel.
+*/
+#define SD_EMERG   "<0>"  /* system is unusable */
+#define SD_ALERT   "<1>"  /* action must be taken immediately */
+#define SD_CRIT    "<2>"  /* critical conditions */
+#define SD_ERR     "<3>"  /* error conditions */
+#define SD_WARNING "<4>"  /* warning conditions */
+#define SD_NOTICE  "<5>"  /* normal but significant condition */
+#define SD_INFO    "<6>"  /* informational */
+#define SD_DEBUG   "<7>"  /* debug-level messages */
+
+/* The first passed file descriptor is fd 3 */
+#define SD_LISTEN_FDS_START 3
+
+/*
+  Returns how many file descriptors have been passed, or a negative
+  errno code on failure. Optionally, removes the $LISTEN_FDS and
+  $LISTEN_PID file descriptors from the environment (recommended, but
+  problematic in threaded environments). If r is the return value of
+  this function you'll find the file descriptors passed as fds
+  SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative
+  errno style error code on failure. This function call ensures that
+  the FD_CLOEXEC flag is set for the passed file descriptors, to make
+  sure they are not passed on to child processes. If FD_CLOEXEC shall
+  not be set, the caller needs to unset it after this call for all file
+  descriptors that are used.
+
+  See sd_listen_fds(3) for more information.
+*/
+int sd_listen_fds(int unset_environment);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is a FIFO in the file system stored under the
+  specified path, 0 otherwise. If path is NULL a path name check will
+  not be done and the call only verifies if the file descriptor
+  refers to a FIFO. Returns a negative errno style error code on
+  failure.
+
+  See sd_is_fifo(3) for more information.
+*/
+int sd_is_fifo(int fd, const char *path);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is a special character device on the file
+  system stored under the specified path, 0 otherwise.
+  If path is NULL a path name check will not be done and the call
+  only verifies if the file descriptor refers to a special character.
+  Returns a negative errno style error code on failure.
+
+  See sd_is_special(3) for more information.
+*/
+int sd_is_special(int fd, const char *path);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is a socket of the specified family (AF_INET,
+  ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
+  family is 0 a socket family check will not be done. If type is 0 a
+  socket type check will not be done and the call only verifies if
+  the file descriptor refers to a socket. If listening is > 0 it is
+  verified that the socket is in listening mode. (i.e. listen() has
+  been called) If listening is == 0 it is verified that the socket is
+  not in listening mode. If listening is < 0 no listening mode check
+  is done. Returns a negative errno style error code on failure.
+
+  See sd_is_socket(3) for more information.
+*/
+int sd_is_socket(int fd, int family, int type, int listening);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is an Internet socket, of the specified family
+  (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM,
+  SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
+  check is not done. If type is 0 a socket type check will not be
+  done. If port is 0 a socket port check will not be done. The
+  listening flag is used the same way as in sd_is_socket(). Returns a
+  negative errno style error code on failure.
+
+  See sd_is_socket_inet(3) for more information.
+*/
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is an AF_UNIX socket of the specified type
+  (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0
+  a socket type check will not be done. If path is NULL a socket path
+  check will not be done. For normal AF_UNIX sockets set length to
+  0. For abstract namespace sockets set length to the length of the
+  socket name (including the initial 0 byte), and pass the full
+  socket path in path (including the initial 0 byte). The listening
+  flag is used the same way as in sd_is_socket(). Returns a negative
+  errno style error code on failure.
+
+  See sd_is_socket_unix(3) for more information.
+*/
+int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is a POSIX Message Queue of the specified name,
+  0 otherwise. If path is NULL a message queue name check is not
+  done. Returns a negative errno style error code on failure.
+*/
+int sd_is_mq(int fd, const char *path);
+
+/*
+  Informs systemd about changed daemon state. This takes a number of
+  newline separated environment-style variable assignments in a
+  string. The following variables are known:
+
+     READY=1      Tells systemd that daemon startup is finished (only
+                  relevant for services of Type=notify). The passed
+                  argument is a boolean "1" or "0". Since there is
+                  little value in signaling non-readiness the only
+                  value daemons should send is "READY=1".
+
+     STATUS=...   Passes a single-line status string back to systemd
+                  that describes the daemon state. This is free-from
+                  and can be used for various purposes: general state
+                  feedback, fsck-like programs could pass completion
+                  percentages and failing programs could pass a human
+                  readable error message. Example: "STATUS=Completed
+                  66% of file system check..."
+
+     ERRNO=...    If a daemon fails, the errno-style error code,
+                  formatted as string. Example: "ERRNO=2" for ENOENT.
+
+     BUSERROR=... If a daemon fails, the D-Bus error-style error
+                  code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
+
+     MAINPID=...  The main pid of a daemon, in case systemd did not
+                  fork off the process itself. Example: "MAINPID=4711"
+
+     WATCHDOG=1   Tells systemd to update the watchdog timestamp.
+                  Services using this feature should do this in
+                  regular intervals. A watchdog framework can use the
+                  timestamps to detect failed services.
+
+  Daemons can choose to send additional variables. However, it is
+  recommended to prefix variable names not listed above with X_.
+
+  Returns a negative errno-style error code on failure. Returns > 0
+  if systemd could be notified, 0 if it couldn't possibly because
+  systemd is not running.
+
+  Example: When a daemon finished starting up, it could issue this
+  call to notify systemd about it:
+
+     sd_notify(0, "READY=1");
+
+  See sd_notifyf() for more complete examples.
+
+  See sd_notify(3) for more information.
+*/
+int sd_notify(int unset_environment, const char *state);
+
+/*
+  Similar to sd_notify() but takes a format string.
+
+  Example 1: A daemon could send the following after initialization:
+
+     sd_notifyf(0, "READY=1\n"
+                   "STATUS=Processing requests...\n"
+                   "MAINPID=%lu",
+                   (unsigned long) getpid());
+
+  Example 2: A daemon could send the following shortly before
+  exiting, on failure:
+
+     sd_notifyf(0, "STATUS=Failed to start up: %s\n"
+                   "ERRNO=%i",
+                   strerror(errno),
+                   errno);
+
+  See sd_notifyf(3) for more information.
+*/
+int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3);
+
+/*
+  Returns > 0 if the system was booted with systemd. Returns < 0 on
+  error. Returns 0 if the system was not booted with systemd. Note
+  that all of the functions above handle non-systemd boots just
+  fine. You should NOT protect them with a call to this function. Also
+  note that this function checks whether the system, not the user
+  session is controlled by systemd. However the functions above work
+  for both user and system services.
+
+  See sd_booted(3) for more information.
+*/
+int sd_booted(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h
new file mode 100644 (file)
index 0000000..79bb8b3
--- /dev/null
@@ -0,0 +1,109 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef fooid128hfoo
+#define fooid128hfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 128 Bit ID APIs. See sd-id128(3) for more information. */
+
+typedef union sd_id128 sd_id128_t;
+
+union sd_id128 {
+        uint8_t bytes[16];
+        uint64_t qwords[2];
+};
+
+char *sd_id128_to_string(sd_id128_t id, char s[33]);
+
+int sd_id128_from_string(const char s[33], sd_id128_t *ret);
+
+int sd_id128_randomize(sd_id128_t *ret);
+
+int sd_id128_get_machine(sd_id128_t *ret);
+
+int sd_id128_get_boot(sd_id128_t *ret);
+
+#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \
+        ((sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \
+                                   0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }})
+
+/* Note that SD_ID128_FORMAT_VAL will evaluate the passed argument 16
+ * times. It is hence not a good idea to call this macro with an
+ * expensive function as paramater or an expression with side
+ * effects */
+
+#define SD_ID128_FORMAT_STR "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+#define SD_ID128_FORMAT_VAL(x) (x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], (x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], (x).bytes[8], (x).bytes[9], (x).bytes[10], (x).bytes[11], (x).bytes[12], (x).bytes[13], (x).bytes[14], (x).bytes[15]
+
+#define SD_ID128_CONST_STR(x)                                           \
+        ((char[33]) {                                                   \
+                ((x).bytes[0] >> 4) >= 10 ? 'a' + ((x).bytes[0] >> 4) - 10 : '0' + ((x).bytes[0] >> 4), \
+                ((x).bytes[0] & 15) >= 10 ? 'a' + ((x).bytes[0] & 15) - 10 : '0' + ((x).bytes[0] & 15), \
+                ((x).bytes[1] >> 4) >= 10 ? 'a' + ((x).bytes[1] >> 4) - 10 : '0' + ((x).bytes[1] >> 4), \
+                ((x).bytes[1] & 15) >= 10 ? 'a' + ((x).bytes[1] & 15) - 10 : '0' + ((x).bytes[1] & 15), \
+                ((x).bytes[2] >> 4) >= 10 ? 'a' + ((x).bytes[2] >> 4) - 10 : '0' + ((x).bytes[2] >> 4), \
+                ((x).bytes[2] & 15) >= 10 ? 'a' + ((x).bytes[2] & 15) - 10 : '0' + ((x).bytes[2] & 15), \
+                ((x).bytes[3] >> 4) >= 10 ? 'a' + ((x).bytes[3] >> 4) - 10 : '0' + ((x).bytes[3] >> 4), \
+                ((x).bytes[3] & 15) >= 10 ? 'a' + ((x).bytes[3] & 15) - 10 : '0' + ((x).bytes[3] & 15), \
+                ((x).bytes[4] >> 4) >= 10 ? 'a' + ((x).bytes[4] >> 4) - 10 : '0' + ((x).bytes[4] >> 4), \
+                ((x).bytes[4] & 15) >= 10 ? 'a' + ((x).bytes[4] & 15) - 10 : '0' + ((x).bytes[4] & 15), \
+                ((x).bytes[5] >> 4) >= 10 ? 'a' + ((x).bytes[5] >> 4) - 10 : '0' + ((x).bytes[5] >> 4), \
+                ((x).bytes[5] & 15) >= 10 ? 'a' + ((x).bytes[5] & 15) - 10 : '0' + ((x).bytes[5] & 15), \
+                ((x).bytes[6] >> 4) >= 10 ? 'a' + ((x).bytes[6] >> 4) - 10 : '0' + ((x).bytes[6] >> 4), \
+                ((x).bytes[6] & 15) >= 10 ? 'a' + ((x).bytes[6] & 15) - 10 : '0' + ((x).bytes[6] & 15), \
+                ((x).bytes[7] >> 4) >= 10 ? 'a' + ((x).bytes[7] >> 4) - 10 : '0' + ((x).bytes[7] >> 4), \
+                ((x).bytes[7] & 15) >= 10 ? 'a' + ((x).bytes[7] & 15) - 10 : '0' + ((x).bytes[7] & 15), \
+                ((x).bytes[8] >> 4) >= 10 ? 'a' + ((x).bytes[8] >> 4) - 10 : '0' + ((x).bytes[8] >> 4), \
+                ((x).bytes[8] & 15) >= 10 ? 'a' + ((x).bytes[8] & 15) - 10 : '0' + ((x).bytes[8] & 15), \
+                ((x).bytes[9] >> 4) >= 10 ? 'a' + ((x).bytes[9] >> 4) - 10 : '0' + ((x).bytes[9] >> 4), \
+                ((x).bytes[9] & 15) >= 10 ? 'a' + ((x).bytes[9] & 15) - 10 : '0' + ((x).bytes[9] & 15), \
+                ((x).bytes[10] >> 4) >= 10 ? 'a' + ((x).bytes[10] >> 4) - 10 : '0' + ((x).bytes[10] >> 4), \
+                ((x).bytes[10] & 15) >= 10 ? 'a' + ((x).bytes[10] & 15) - 10 : '0' + ((x).bytes[10] & 15), \
+                ((x).bytes[11] >> 4) >= 10 ? 'a' + ((x).bytes[11] >> 4) - 10 : '0' + ((x).bytes[11] >> 4), \
+                ((x).bytes[11] & 15) >= 10 ? 'a' + ((x).bytes[11] & 15) - 10 : '0' + ((x).bytes[11] & 15), \
+                ((x).bytes[12] >> 4) >= 10 ? 'a' + ((x).bytes[12] >> 4) - 10 : '0' + ((x).bytes[12] >> 4), \
+                ((x).bytes[12] & 15) >= 10 ? 'a' + ((x).bytes[12] & 15) - 10 : '0' + ((x).bytes[12] & 15), \
+                ((x).bytes[13] >> 4) >= 10 ? 'a' + ((x).bytes[13] >> 4) - 10 : '0' + ((x).bytes[13] >> 4), \
+                ((x).bytes[13] & 15) >= 10 ? 'a' + ((x).bytes[13] & 15) - 10 : '0' + ((x).bytes[13] & 15), \
+                ((x).bytes[14] >> 4) >= 10 ? 'a' + ((x).bytes[14] >> 4) - 10 : '0' + ((x).bytes[14] >> 4), \
+                ((x).bytes[14] & 15) >= 10 ? 'a' + ((x).bytes[14] & 15) - 10 : '0' + ((x).bytes[14] & 15), \
+                ((x).bytes[15] >> 4) >= 10 ? 'a' + ((x).bytes[15] >> 4) - 10 : '0' + ((x).bytes[15] >> 4), \
+                ((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \
+                0 })
+
+static inline int sd_id128_equal(sd_id128_t a, sd_id128_t b) {
+        return memcmp(&a, &b, 16) == 0;
+}
+
+#define SD_ID128_NULL ((sd_id128_t) { .qwords = { 0, 0 }})
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h
new file mode 100644 (file)
index 0000000..2e8d2d8
--- /dev/null
@@ -0,0 +1,155 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foojournalhfoo
+#define foojournalhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <sys/uio.h>
+#include <syslog.h>
+
+#include <systemd/sd-id128.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Journal APIs. See sd-journal(3) for more information. */
+
+/* Write to daemon */
+int sd_journal_print(int priority, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+int sd_journal_printv(int priority, const char *format, va_list ap);
+int sd_journal_send(const char *format, ...) __attribute__((sentinel));
+int sd_journal_sendv(const struct iovec *iov, int n);
+int sd_journal_perror(const char *message);
+
+/* Used by the macros below. Don't call this directly. */
+int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
+int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap);
+int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) __attribute__((sentinel));
+int sd_journal_sendv_with_location(const char *file, const char *line, const char *func, const struct iovec *iov, int n);
+int sd_journal_perror_with_location(const char *file, const char *line, const char *func, const char *message);
+
+/* implicitly add code location to messages sent, if this is enabled */
+#ifndef SD_JOURNAL_SUPPRESS_LOCATION
+
+#define _sd_XSTRINGIFY(x) #x
+#define _sd_STRINGIFY(x) _sd_XSTRINGIFY(x)
+
+#define sd_journal_print(priority, ...) sd_journal_print_with_location(priority, "CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, __VA_ARGS__)
+#define sd_journal_printv(priority, format, ap) sd_journal_printv_with_location(priority, "CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, format, ap)
+#define sd_journal_send(...) sd_journal_send_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, __VA_ARGS__)
+#define sd_journal_sendv(iovec, n) sd_journal_sendv_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, iovec, n)
+#define sd_journal_perror(message) sd_journal_perror_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, message)
+
+#endif
+
+int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix);
+
+/* Browse journal stream */
+
+typedef struct sd_journal sd_journal;
+
+/* Open flags */
+enum {
+        SD_JOURNAL_LOCAL_ONLY = 1,
+        SD_JOURNAL_RUNTIME_ONLY = 2,
+        SD_JOURNAL_SYSTEM_ONLY = 4
+};
+
+/* Wakeup event types */
+enum {
+        SD_JOURNAL_NOP,
+        SD_JOURNAL_APPEND,
+        SD_JOURNAL_INVALIDATE
+};
+
+int sd_journal_open(sd_journal **ret, int flags);
+int sd_journal_open_directory(sd_journal **ret, const char *path, int flags);
+void sd_journal_close(sd_journal *j);
+
+int sd_journal_previous(sd_journal *j);
+int sd_journal_next(sd_journal *j);
+
+int sd_journal_previous_skip(sd_journal *j, uint64_t skip);
+int sd_journal_next_skip(sd_journal *j, uint64_t skip);
+
+int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret);
+int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id);
+
+int sd_journal_set_data_threshold(sd_journal *j, size_t sz);
+int sd_journal_get_data_threshold(sd_journal *j, size_t *sz);
+
+int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *l);
+int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *l);
+void sd_journal_restart_data(sd_journal *j);
+
+int sd_journal_add_match(sd_journal *j, const void *data, size_t size);
+int sd_journal_add_disjunction(sd_journal *j);
+void sd_journal_flush_matches(sd_journal *j);
+
+int sd_journal_seek_head(sd_journal *j);
+int sd_journal_seek_tail(sd_journal *j);
+int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec);
+int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec);
+int sd_journal_seek_cursor(sd_journal *j, const char *cursor);
+
+int sd_journal_get_cursor(sd_journal *j, char **cursor);
+int sd_journal_test_cursor(sd_journal *j, const char *cursor);
+
+int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, uint64_t *to);
+int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, const sd_id128_t boot_id, uint64_t *from, uint64_t *to);
+
+int sd_journal_get_usage(sd_journal *j, uint64_t *bytes);
+
+int sd_journal_query_unique(sd_journal *j, const char *field);
+int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l);
+void sd_journal_restart_unique(sd_journal *j);
+
+int sd_journal_get_fd(sd_journal *j);
+int sd_journal_reliable_fd(sd_journal *j);
+int sd_journal_process(sd_journal *j);
+int sd_journal_wait(sd_journal *j, uint64_t timeout_usec);
+
+int sd_journal_get_catalog(sd_journal *j, char **text);
+int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret);
+
+#define SD_JOURNAL_FOREACH(j)                                           \
+        if (sd_journal_seek_head(j) >= 0)                               \
+                while (sd_journal_next(j) > 0)
+
+#define SD_JOURNAL_FOREACH_BACKWARDS(j)                                 \
+        if (sd_journal_seek_tail(j) >= 0)                               \
+                while (sd_journal_previous(j) > 0)
+
+#define SD_JOURNAL_FOREACH_DATA(j, data, l)                             \
+        for (sd_journal_restart_data(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; )
+
+#define SD_JOURNAL_FOREACH_UNIQUE(j, data, l)                           \
+        for (sd_journal_restart_unique(j); sd_journal_enumerate_unique((j), &(data), &(l)) > 0; )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h
new file mode 100644 (file)
index 0000000..6bd1f2d
--- /dev/null
@@ -0,0 +1,160 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosdloginhfoo
+#define foosdloginhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A few points:
+ *
+ * Instead of returning an empty string array or empty uid array, we
+ * may return NULL.
+ *
+ * Free the data the library returns with libc free(). String arrays
+ * are NULL terminated and you need to free the array itself in
+ * addition to the strings contained.
+ *
+ * We return error codes as negative errno, kernel-style. 0 or
+ * positive on success.
+ *
+ * These functions access data in /proc, /sys/fs/cgroup and /run. All
+ * of these are virtual file systems, hence the accesses are
+ * relatively cheap.
+ *
+ * See sd-login(3) for more information.
+ */
+
+/* Get session from PID. Note that 'shared' processes of a user are
+ * not attached to a session, but only attached to a user. This will
+ * return an error for system processes and 'shared' processes of a
+ * user. */
+int sd_pid_get_session(pid_t pid, char **session);
+
+/* Get UID of the owner of the session of the PID (or in case the
+ * process is a 'shared' user process the UID of that user is
+ * returned). This will not return the UID of the process, but rather
+ * the UID of the owner of the cgroup the process is in. This will
+ * return an error for system processes. */
+int sd_pid_get_owner_uid(pid_t pid, uid_t *uid);
+
+/* Get systemd unit (i.e. service) name from PID. This will return an
+ * error for non-service processes. */
+int sd_pid_get_unit(pid_t, char **unit);
+
+/* Get state from uid. Possible states: offline, lingering, online, active, closing */
+int sd_uid_get_state(uid_t uid, char**state);
+
+/* Return 1 if uid has session on seat. If require_active is true will
+ * look for active sessions only. */
+int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat);
+
+/* Return sessions of user. If require_active is true will look for
+ * active sessions only. Returns number of sessions as return
+ * value. If sessions is NULL will just return number of sessions. */
+int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions);
+
+/* Return seats of user is on. If require_active is true will look for
+ * active seats only.  Returns number of seats. If seats is NULL will
+ * just return number of seats.*/
+int sd_uid_get_seats(uid_t uid, int require_active, char ***seats);
+
+/* Return 1 if the session is a active. */
+int sd_session_is_active(const char *session);
+
+/* Get state from session. Possible states: online, active, closing
+ * (This function is a more generic version of
+ * sd_session_is_active().) */
+int sd_session_get_state(const char *sessio, char **state);
+
+/* Determine user id of session */
+int sd_session_get_uid(const char *session, uid_t *uid);
+
+/* Determine seat of session */
+int sd_session_get_seat(const char *session, char **seat);
+
+/* Determine the (PAM) service name this session was registered by. */
+int sd_session_get_service(const char *session, char **service);
+
+/* Determine the type of this session, i.e. one of "tty", "x11" or "unspecified". */
+int sd_session_get_type(const char *session, char **type);
+
+/* Determine the class of this session, i.e. one of "user", "greeter" or "lock-screen". */
+int sd_session_get_class(const char *session, char **clazz);
+
+/* Determine the X11 display of this session. */
+int sd_session_get_display(const char *session, char **display);
+
+/* Return active session and user of seat */
+int sd_seat_get_active(const char *seat, char **session, uid_t *uid);
+
+/* Return sessions and users on seat. Returns number of sessions as
+ * return value. If sessions is NULL returns only the number of
+ * sessions. */
+int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uid, unsigned *n_uids);
+
+/* Return whether the seat is multi-session capable */
+int sd_seat_can_multi_session(const char *seat);
+
+/* Return whether the seat is TTY capable, i.e. suitable for showing console UIs */
+int sd_seat_can_tty(const char *seat);
+
+/* Return whether the seat is graphics capable, i.e. suitable for showing graphical UIs */
+int sd_seat_can_graphical(const char *seat);
+
+/* Get all seats, store in *seats. Returns the number of seats. If
+ * seats is NULL only returns number of seats. */
+int sd_get_seats(char ***seats);
+
+/* Get all sessions, store in *sessions. Returns the number of
+ * sessions. If sessions is NULL only returns number of sessions. */
+int sd_get_sessions(char ***sessions);
+
+/* Get all logged in users, store in *users. Returns the number of
+ * users. If users is NULL only returns the number of users. */
+int sd_get_uids(uid_t **users);
+
+/* Monitor object */
+typedef struct sd_login_monitor sd_login_monitor;
+
+/* Create a new monitor. Category must be NULL, "seat", "session",
+ * "uid" to get monitor events for the specific category (or all). */
+int sd_login_monitor_new(const char *category, sd_login_monitor** ret);
+
+/* Destroys the passed monitor. Returns NULL. */
+sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m);
+
+/* Flushes the monitor */
+int sd_login_monitor_flush(sd_login_monitor *m);
+
+/* Get FD from monitor */
+int sd_login_monitor_get_fd(sd_login_monitor *m);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h
new file mode 100644 (file)
index 0000000..bc56094
--- /dev/null
@@ -0,0 +1,74 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosdmessageshfoo
+#define foosdmessageshfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <systemd/sd-id128.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Hey! If you add a new message here, you *must* also update the
+ * message catalog with an appropriate explanation */
+
+#define SD_MESSAGE_JOURNAL_START    SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b)
+#define SD_MESSAGE_JOURNAL_STOP     SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b)
+#define SD_MESSAGE_JOURNAL_DROPPED  SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e)
+#define SD_MESSAGE_JOURNAL_MISSED   SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06)
+
+#define SD_MESSAGE_COREDUMP         SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
+
+#define SD_MESSAGE_SESSION_START    SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66)
+#define SD_MESSAGE_SESSION_STOP     SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a)
+#define SD_MESSAGE_SEAT_START       SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b)
+#define SD_MESSAGE_SEAT_STOP        SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5)
+
+#define SD_MESSAGE_TIME_CHANGE      SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27)
+#define SD_MESSAGE_TIMEZONE_CHANGE  SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90)
+
+#define SD_MESSAGE_STARTUP_FINISHED SD_ID128_MAKE(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff)
+
+#define SD_MESSAGE_SLEEP_START      SD_ID128_MAKE(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28)
+#define SD_MESSAGE_SLEEP_STOP       SD_ID128_MAKE(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14)
+
+#define SD_MESSAGE_SHUTDOWN         SD_ID128_MAKE(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40)
+
+#define SD_MESSAGE_UNIT_STARTING    SD_ID128_MAKE(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5)
+#define SD_MESSAGE_UNIT_STARTED     SD_ID128_MAKE(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf)
+#define SD_MESSAGE_UNIT_STOPPING    SD_ID128_MAKE(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f)
+#define SD_MESSAGE_UNIT_STOPPED     SD_ID128_MAKE(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86)
+#define SD_MESSAGE_UNIT_FAILED      SD_ID128_MAKE(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d)
+#define SD_MESSAGE_UNIT_RELOADING   SD_ID128_MAKE(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25)
+#define SD_MESSAGE_UNIT_RELOADED    SD_ID128_MAKE(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54)
+
+#define SD_MESSAGE_SPAWN_FAILED     SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7)
+
+#define SD_MESSAGE_FORWARD_SYSLOG_MISSED SD_ID128_MAKE(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e)
+
+#define SD_MESSAGE_OVERMOUNTING     SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/systemd/sd-readahead.h b/src/systemd/sd-readahead.h
new file mode 100644 (file)
index 0000000..2dac104
--- /dev/null
@@ -0,0 +1,73 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosdreadaheadhfoo
+#define foosdreadaheadhfoo
+
+/***
+  Copyright 2010 Lennart Poettering
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+***/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+  Reference implementation of a few boot readahead related
+  interfaces. These interfaces are trivial to implement. To simplify
+  porting we provide this reference implementation.  Applications are
+  welcome to reimplement the algorithms described here if they do not
+  want to include these two source files.
+
+  You may compile this with -DDISABLE_SYSTEMD to disable systemd
+  support. This makes all calls NOPs.
+
+  Since this is drop-in code we don't want any of our symbols to be
+  exported in any case. Hence we declare hidden visibility for all of
+  them.
+
+  You may find an up-to-date version of these source files online:
+
+  http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h
+  http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c
+
+  This should compile on non-Linux systems, too, but all functions
+  will become NOPs.
+
+  See sd-readahead(3) for more information.
+*/
+
+/*
+  Controls ongoing disk read-ahead operations during boot-up. The argument
+  must be a string, and either "cancel", "done" or "noreplay".
+
+  cancel = terminate read-ahead data collection, drop collected information
+  done = terminate read-ahead data collection, keep collected information
+  noreplay = terminate read-ahead replay
+*/
+int sd_readahead(const char *action);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/systemd/sd-shutdown.h b/src/systemd/sd-shutdown.h
new file mode 100644 (file)
index 0000000..cee4350
--- /dev/null
@@ -0,0 +1,108 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosdshutdownhfoo
+#define foosdshutdownhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* Interface for scheduling and cancelling timed shutdowns. */
+
+#include <inttypes.h>
+
+typedef enum sd_shutdown_mode {
+        SD_SHUTDOWN_NONE = 0,
+        SD_SHUTDOWN_REBOOT = 'r',
+        SD_SHUTDOWN_POWEROFF = 'P',
+        SD_SHUTDOWN_HALT = 'H',
+        SD_SHUTDOWN_KEXEC = 'K'
+} sd_shutdown_mode_t;
+
+/* Calculate the size of the message as "offsetof(struct
+ * sd_shutdown_command, wall_message) +
+ * strlen(command.wall_message)" */
+__attribute__((packed)) struct sd_shutdown_command {
+        /* Microseconds after the epoch 1970 UTC */
+        uint64_t usec;
+
+        /* H, P, r, i.e. the switches usually passed to
+         * /usr/bin/shutdown to select whether to halt, power-off or
+         * reboot the machine */
+        sd_shutdown_mode_t mode:8;
+
+        /* If non-zero, don't actually shut down, just pretend */
+        unsigned dry_run:1;
+
+        /* If non-zero, send our wall message */
+        unsigned warn_wall:1;
+
+        /* The wall message to send around. Leave empty for the
+         * default wall message */
+        char wall_message[];
+};
+
+/* The scheme is very simple:
+ *
+ * To schedule a shutdown, simply fill in and send a single
+ * AF_UNIX/SOCK_DGRAM datagram with the structure above suffixed with
+ * the wall message to the socket /run/systemd/shutdownd (leave an
+ * empty wall message for the default shutdown message). To calculate
+ * the size of the message use "offsetof(struct sd_shutdown_command,
+ * wall_message) + strlen(command.wall_message)".
+ *
+ * To cancel a shutdown, do the same, but send an fully zeroed out
+ * structure.
+ *
+ * To be notified about scheduled shutdowns, create an inotify watch
+ * on /run/shutdown/. Whenever a file called "scheduled" appears a
+ * shutdown is scheduled. If it is removed it is canceled. It is
+ * replaced the scheduled shutdown has been changed. The file contains
+ * a simple environment-like block, that contains information about
+ * the scheduled shutdown:
+ *
+ * USEC=
+ * encodes the time for the shutdown in usecs since the epoch UTC,
+ * formatted as numeric string.
+ *
+ * WARN_WALL=
+ * is 1 if a wall message shall be sent
+ *
+ * DRY_RUN=
+ * is 1 if a dry run shutdown is scheduled
+ *
+ * MODE=
+ * is the shutdown mode, one of "poweroff", "reboot", "halt", "kexec"
+ *
+ * WALL_MESSAGE=
+ * is the wall message to use, with all special characters escape in C style.
+ *
+ * Note that some fields might be missing if they do not apply.
+ *
+ * Note that the file is first written to a temporary file and then
+ * renamed, in order to provide atomic properties for readers: if the
+ * file exists under the name "scheduled" it is guaranteed to be fully
+ * written. A reader should ignore all files in that directory by any
+ * other name.
+ *
+ * Scheduled shutdowns are only accepted from privileged processes,
+ * but the directory may be watched and the file in it read by
+ * anybody.
+ */
+
+#endif
diff --git a/src/test/Makefile b/src/test/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
new file mode 100644 (file)
index 0000000..21b0024
--- /dev/null
@@ -0,0 +1,88 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "calendarspec.h"
+#include "util.h"
+
+static void test_one(const char *input, const char *output) {
+        CalendarSpec *c;
+        _cleanup_free_ char *p = NULL, *q = NULL;
+        usec_t u;
+        char buf[FORMAT_TIMESTAMP_MAX];
+        int r;
+
+        assert_se(calendar_spec_from_string(input, &c) >= 0);
+
+        assert_se(calendar_spec_to_string(c, &p) >= 0);
+        printf("\"%s\" → \"%s\"\n", input, p);
+
+        assert_se(streq(p, output));
+
+        u = now(CLOCK_REALTIME);
+        r = calendar_spec_next_usec(c, u, &u);
+        printf("Next: %s\n", r < 0 ? strerror(-r) : format_timestamp(buf, sizeof(buf), u));
+        calendar_spec_free(c);
+
+        assert_se(calendar_spec_from_string(p, &c) >= 0);
+        assert_se(calendar_spec_to_string(c, &q) >= 0);
+        calendar_spec_free(c);
+
+        assert_se(streq(q, p));
+}
+
+int main(int argc, char* argv[]) {
+        CalendarSpec *c;
+
+        test_one("Sat,Thu,Mon-Wed,Sat-Sun", "Mon-Thu,Sat,Sun *-*-* 00:00:00");
+        test_one("Mon,Sun 12-*-* 2,1:23", "Mon,Sun 2012-*-* 01,02:23:00");
+        test_one("Wed *-1", "Wed *-*-01 00:00:00");
+        test_one("Wed-Wed,Wed *-1", "Wed *-*-01 00:00:00");
+        test_one("Wed, 17:48", "Wed *-*-* 17:48:00");
+        test_one("Wed-Sat,Tue 12-10-15 1:2:3", "Tue-Sat 2012-10-15 01:02:03");
+        test_one("*-*-7 0:0:0", "*-*-07 00:00:00");
+        test_one("10-15", "*-10-15 00:00:00");
+        test_one("monday *-12-* 17:00", "Mon *-12-* 17:00:00");
+        test_one("Mon,Fri *-*-3,1,2 *:30:45", "Mon,Fri *-*-01,02,03 *:30:45");
+        test_one("12,14,13,12:20,10,30", "*-*-* 12,13,14:10,20,30:00");
+        test_one("mon,fri *-1/2-1,3 *:30:45", "Mon,Fri *-01/2-01,03 *:30:45");
+        test_one("03-05 08:05:40", "*-03-05 08:05:40");
+        test_one("08:05:40", "*-*-* 08:05:40");
+        test_one("05:40", "*-*-* 05:40:00");
+        test_one("Sat,Sun 12-05 08:05:40", "Sat,Sun *-12-05 08:05:40");
+        test_one("Sat,Sun 08:05:40", "Sat,Sun *-*-* 08:05:40");
+        test_one("2003-03-05 05:40", "2003-03-05 05:40:00");
+        test_one("2003-03-05", "2003-03-05 00:00:00");
+        test_one("03-05", "*-03-05 00:00:00");
+        test_one("hourly", "*-*-* *:00:00");
+        test_one("daily", "*-*-* 00:00:00");
+        test_one("monthly", "*-*-01 00:00:00");
+        test_one("weekly", "Mon *-*-* 00:00:00");
+        test_one("*:2/3", "*-*-* *:02/3:00");
+
+        assert_se(calendar_spec_from_string("test", &c) < 0);
+        assert_se(calendar_spec_from_string("", &c) < 0);
+        assert_se(calendar_spec_from_string("7", &c) < 0);
+        assert_se(calendar_spec_from_string("121212:1:2", &c) < 0);
+
+        return 0;
+}
diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c
new file mode 100644 (file)
index 0000000..6d64a4e
--- /dev/null
@@ -0,0 +1,105 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <string.h>
+
+#include "cgroup-util.h"
+#include "path-util.h"
+#include "util.h"
+#include "log.h"
+
+int main(int argc, char*argv[]) {
+        char *path;
+        char *c, *p;
+
+        assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0);
+        assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0);
+        assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b") == 0);
+        assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-c") == 0);
+        assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0) == 0);
+
+        assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+        assert_se(streq(path, "/test-b"));
+        free(path);
+
+        assert_se(cg_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0) == 0);
+
+        assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+        assert_se(path_equal(path, "/test-a"));
+        free(path);
+
+        assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", 0) == 0);
+
+        assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+        assert_se(path_equal(path, "/test-b/test-d"));
+        free(path);
+
+        assert_se(cg_get_path(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", NULL, &path) == 0);
+        assert_se(path_equal(path, "/sys/fs/cgroup/systemd/test-b/test-d"));
+        free(path);
+
+        assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0);
+        assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0);
+        assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0);
+        assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) == 0);
+
+        assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) == 0);
+        assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) > 0);
+
+        assert_se(cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", "/test-a", false, false) > 0);
+
+        assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) == 0);
+        assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0);
+
+        assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) > 0);
+        assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) == 0);
+
+        cg_trim(SYSTEMD_CGROUP_CONTROLLER, "/", false);
+
+        assert_se(cg_delete(SYSTEMD_CGROUP_CONTROLLER, "/test-b") < 0);
+        assert_se(cg_delete(SYSTEMD_CGROUP_CONTROLLER, "/test-a") >= 0);
+
+        assert_se(cg_split_spec("foobar:/", &c, &p) == 0);
+        assert(streq(c, "foobar"));
+        assert(streq(p, "/"));
+        free(c);
+        free(p);
+
+        assert_se(cg_split_spec("foobar:", &c, &p) < 0);
+        assert_se(cg_split_spec("foobar:asdfd", &c, &p) < 0);
+        assert_se(cg_split_spec(":///", &c, &p) < 0);
+        assert_se(cg_split_spec(":", &c, &p) < 0);
+        assert_se(cg_split_spec("", &c, &p) < 0);
+        assert_se(cg_split_spec("fo/obar:/", &c, &p) < 0);
+
+        assert_se(cg_split_spec("/", &c, &p) >= 0);
+        assert(c == NULL);
+        assert(streq(p, "/"));
+        free(p);
+
+        assert_se(cg_split_spec("foo", &c, &p) >= 0);
+        assert(streq(c, "foo"));
+        assert(p == NULL);
+        free(c);
+
+        return 0;
+}
diff --git a/src/test/test-daemon.c b/src/test/test-daemon.c
new file mode 100644 (file)
index 0000000..3215f0c
--- /dev/null
@@ -0,0 +1,37 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+
+#include <systemd/sd-daemon.h>
+
+int main(int argc, char*argv[]) {
+
+        sd_notify(0, "STATUS=Starting up");
+        sleep(5);
+        sd_notify(0,
+                  "STATUS=Running\n"
+                  "READY=1");
+        sleep(10);
+        sd_notify(0, "STATUS=Quitting");
+
+        return 0;
+}
diff --git a/src/test/test-date.c b/src/test/test-date.c
new file mode 100644 (file)
index 0000000..40ffc17
--- /dev/null
@@ -0,0 +1,61 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "util.h"
+
+static void test_one(const char *p) {
+        usec_t t, q;
+        char buf[FORMAT_TIMESTAMP_MAX], buf_relative[FORMAT_TIMESTAMP_RELATIVE_MAX];
+
+        assert_se(parse_timestamp(p, &t) >= 0);
+        log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+        /* Chop off timezone */
+        *strrchr(buf, ' ') = 0;
+
+        assert_se(parse_timestamp(buf, &q) >= 0);
+        assert_se(q == t);
+
+        log_info("%s", strna(format_timestamp_relative(buf_relative, sizeof(buf_relative), t)));
+        assert_se(parse_timestamp(buf, &q) >= 0);
+}
+
+int main(int argc, char *argv[]) {
+        test_one("17:41");
+        test_one("18:42:44");
+        test_one("12-10-02 12:13:14");
+        test_one("12-10-2 12:13:14");
+        test_one("12-10-03 12:13");
+        test_one("2012-12-30 18:42");
+        test_one("2012-10-02");
+        test_one("Tue 2012-10-02");
+        test_one("now");
+        test_one("yesterday");
+        test_one("today");
+        test_one("tomorrow");
+        test_one("+2d");
+        test_one("+2y 4d");
+        test_one("5months ago");
+
+        return 0;
+}
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
new file mode 100644 (file)
index 0000000..0f38622
--- /dev/null
@@ -0,0 +1,99 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "manager.h"
+
+int main(int argc, char *argv[]) {
+        Manager *m = NULL;
+        Unit *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL, *h = NULL;
+        Job *j;
+
+        assert_se(set_unit_path("test") >= 0);
+
+        assert_se(manager_new(SYSTEMD_SYSTEM, &m) >= 0);
+
+        printf("Load1:\n");
+        assert_se(manager_load_unit(m, "a.service", NULL, NULL, &a) >= 0);
+        assert_se(manager_load_unit(m, "b.service", NULL, NULL, &b) >= 0);
+        assert_se(manager_load_unit(m, "c.service", NULL, NULL, &c) >= 0);
+        manager_dump_units(m, stdout, "\t");
+
+        printf("Test1: (Trivial)\n");
+        assert_se(manager_add_job(m, JOB_START, c, JOB_REPLACE, false, NULL, &j) == 0);
+        manager_dump_jobs(m, stdout, "\t");
+
+        printf("Load2:\n");
+        manager_clear_jobs(m);
+        assert_se(manager_load_unit(m, "d.service", NULL, NULL, &d) >= 0);
+        assert_se(manager_load_unit(m, "e.service", NULL, NULL, &e) >= 0);
+        manager_dump_units(m, stdout, "\t");
+
+        printf("Test2: (Cyclic Order, Unfixable)\n");
+        assert_se(manager_add_job(m, JOB_START, d, JOB_REPLACE, false, NULL, &j) == -ENOEXEC);
+        manager_dump_jobs(m, stdout, "\t");
+
+        printf("Test3: (Cyclic Order, Fixable, Garbage Collector)\n");
+        assert_se(manager_add_job(m, JOB_START, e, JOB_REPLACE, false, NULL, &j) == 0);
+        manager_dump_jobs(m, stdout, "\t");
+
+        printf("Test4: (Identical transaction)\n");
+        assert_se(manager_add_job(m, JOB_START, e, JOB_FAIL, false, NULL, &j) == 0);
+        manager_dump_jobs(m, stdout, "\t");
+
+        printf("Load3:\n");
+        assert_se(manager_load_unit(m, "g.service", NULL, NULL, &g) >= 0);
+        manager_dump_units(m, stdout, "\t");
+
+        printf("Test5: (Colliding transaction, fail)\n");
+        assert_se(manager_add_job(m, JOB_START, g, JOB_FAIL, false, NULL, &j) == -EEXIST);
+
+        printf("Test6: (Colliding transaction, replace)\n");
+        assert_se(manager_add_job(m, JOB_START, g, JOB_REPLACE, false, NULL, &j) == 0);
+        manager_dump_jobs(m, stdout, "\t");
+
+        printf("Test7: (Unmergeable job type, fail)\n");
+        assert_se(manager_add_job(m, JOB_STOP, g, JOB_FAIL, false, NULL, &j) == -EEXIST);
+
+        printf("Test8: (Mergeable job type, fail)\n");
+        assert_se(manager_add_job(m, JOB_RESTART, g, JOB_FAIL, false, NULL, &j) == 0);
+        manager_dump_jobs(m, stdout, "\t");
+
+        printf("Test9: (Unmergeable job type, replace)\n");
+        assert_se(manager_add_job(m, JOB_STOP, g, JOB_REPLACE, false, NULL, &j) == 0);
+        manager_dump_jobs(m, stdout, "\t");
+
+        printf("Load4:\n");
+        assert_se(manager_load_unit(m, "h.service", NULL, NULL, &h) >= 0);
+        manager_dump_units(m, stdout, "\t");
+
+        printf("Test10: (Unmergeable job type of auxiliary job, fail)\n");
+        assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, false, NULL, &j) == 0);
+        manager_dump_jobs(m, stdout, "\t");
+
+        manager_free(m);
+
+        return 0;
+}
diff --git a/src/test/test-env-replace.c b/src/test/test-env-replace.c
new file mode 100644 (file)
index 0000000..cd596a6
--- /dev/null
@@ -0,0 +1,143 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <string.h>
+
+#include "util.h"
+#include "log.h"
+#include "strv.h"
+
+int main(int argc, char *argv[]) {
+
+        const char *env[] = {
+                "FOO=BAR BAR",
+                "BAR=waldo",
+                NULL
+        };
+
+        const char *line[] = {
+                "FOO$FOO",
+                "FOO$FOOFOO",
+                "FOO${FOO}$FOO",
+                "FOO${FOO}",
+                "${FOO}",
+                "$FOO",
+                "$FOO$FOO",
+                "${FOO}${BAR}",
+                "${FOO",
+                NULL
+        };
+
+        char **i, **r, *t, **a, **b;
+        const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
+
+        a = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
+
+        STRV_FOREACH(i, a)
+                printf("nulstr--%s\n", *i);
+
+        strv_free(a);
+
+        r = replace_env_argv((char**) line, (char**) env);
+
+        STRV_FOREACH(i, r)
+                printf("%s\n", *i);
+
+        strv_free(r);
+
+        t = normalize_env_assignment("foo=bar");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("=bar");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("foo=");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("=");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("a=\"waldo\"");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("a=\"waldo");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("a=waldo\"");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("a=\'");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment("a=\'\'");
+        printf("%s\n", t);
+        free(t);
+
+        t = normalize_env_assignment(" xyz  ");
+        printf("<%s>\n", t);
+        free(t);
+
+        t = normalize_env_assignment(" xyz = bar  ");
+        printf("<%s>\n", t);
+        free(t);
+
+        t = normalize_env_assignment(" xyz = 'bar ' ");
+        printf("<%s>\n", t);
+        free(t);
+
+        t = normalize_env_assignment(" ' xyz' = 'bar ' ");
+        printf("<%s>\n", t);
+        free(t);
+
+        a = strv_new("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF", NULL);
+        b = strv_new("FOO=KKK", "FOO=", "PIEP=", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL);
+
+        r = strv_env_merge(2, a, b);
+        strv_free(a);
+        strv_free(b);
+
+        STRV_FOREACH(i, r)
+                printf("%s\n", *i);
+
+        printf("CLEANED UP:\n");
+
+        r = strv_env_clean(r);
+
+        STRV_FOREACH(i, r)
+                printf("%s\n", *i);
+
+        strv_free(r);
+
+        return 0;
+}
diff --git a/src/test/test-hostname.c b/src/test/test-hostname.c
new file mode 100644 (file)
index 0000000..ad4f285
--- /dev/null
@@ -0,0 +1,38 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "hostname-setup.h"
+#include "util.h"
+
+int main(int argc, char* argv[]) {
+        int r;
+
+        r = hostname_setup();
+        if (r < 0)
+                fprintf(stderr, "hostname: %s\n", strerror(-r));
+
+        return 0;
+}
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
new file mode 100644 (file)
index 0000000..bfd743e
--- /dev/null
@@ -0,0 +1,52 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include <systemd/sd-id128.h>
+
+#include "util.h"
+#include "macro.h"
+
+#define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10)
+
+int main(int argc, char *argv[]) {
+        sd_id128_t id, id2;
+        char t[33];
+
+        assert_se(sd_id128_randomize(&id) == 0);
+        printf("random: %s\n", sd_id128_to_string(id, t));
+
+        assert_se(sd_id128_from_string(t, &id2) == 0);
+        assert_se(sd_id128_equal(id, id2));
+
+        assert_se(sd_id128_get_machine(&id) == 0);
+        printf("machine: %s\n", sd_id128_to_string(id, t));
+
+        assert_se(sd_id128_get_boot(&id) == 0);
+        printf("boot: %s\n", sd_id128_to_string(id, t));
+
+        printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t));
+
+        printf("waldi2: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(ID128_WALDI));
+
+        return 0;
+}
diff --git a/src/test/test-install.c b/src/test/test-install.c
new file mode 100644 (file)
index 0000000..2c1b9ef
--- /dev/null
@@ -0,0 +1,265 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "util.h"
+#include "path-util.h"
+#include "install.h"
+
+static void dump_changes(UnitFileChange *c, unsigned n) {
+        unsigned i;
+
+        assert(n == 0 || c);
+
+        for (i = 0; i < n; i++) {
+                if (c[i].type == UNIT_FILE_UNLINK)
+                        printf("rm '%s'\n", c[i].path);
+                else if (c[i].type == UNIT_FILE_SYMLINK)
+                        printf("ln -s '%s' '%s'\n", c[i].source, c[i].path);
+        }
+}
+
+int main(int argc, char* argv[]) {
+        Hashmap *h;
+        UnitFileList *p;
+        Iterator i;
+        int r;
+        const char *const files[] = { "avahi-daemon.service", NULL };
+        const char *const files2[] = { "/home/lennart/test.service", NULL };
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
+
+        h = hashmap_new(string_hash_func, string_compare_func);
+        r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
+        assert_se(r == 0);
+
+        HASHMAP_FOREACH(p, h, i) {
+                UnitFileState s;
+
+                s = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(p->path));
+
+                assert_se(p->state == s);
+
+                fprintf(stderr, "%s (%s)\n",
+                        p->path,
+                        unit_file_state_to_string(p->state));
+        }
+
+        unit_file_list_free(h);
+
+        log_error("enable");
+
+        r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        log_error("enable2");
+
+        r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_ENABLED);
+
+        log_error("disable");
+
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED);
+
+        log_error("mask");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+        assert_se(r >= 0);
+        log_error("mask2");
+        r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED);
+
+        log_error("unmask");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+        assert_se(r >= 0);
+        log_error("unmask2");
+        r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED);
+
+        log_error("mask");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED);
+
+        log_error("disable");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+        assert_se(r >= 0);
+        log_error("disable2");
+        r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED);
+
+        log_error("umask");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED);
+
+        log_error("enable files2");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_ENABLED);
+
+        log_error("disable files2");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID);
+
+        log_error("link files2");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_LINKED);
+
+        log_error("disable files2");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID);
+
+        log_error("link files2");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_LINKED);
+
+        log_error("reenable files2");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_reenable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_ENABLED);
+
+        log_error("disable files2");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID);
+        log_error("preset files");
+        changes = NULL;
+        n_changes = 0;
+
+        r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+        assert_se(r >= 0);
+
+        dump_changes(changes, n_changes);
+        unit_file_changes_free(changes, n_changes);
+
+        assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files[0])) == UNIT_FILE_ENABLED);
+
+        return 0;
+}
diff --git a/src/test/test-job-type.c b/src/test/test-job-type.c
new file mode 100644 (file)
index 0000000..1066374
--- /dev/null
@@ -0,0 +1,105 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "job.h"
+#include "unit.h"
+#include "service.h"
+
+int main(int argc, char*argv[]) {
+        JobType a, b, c, ab, bc, ab_c, bc_a, a_bc;
+        const ServiceState test_states[] = { SERVICE_DEAD, SERVICE_RUNNING };
+        unsigned i;
+        bool merged_ab;
+
+        /* fake a unit */
+        static Service s = {
+                .meta.load_state = UNIT_LOADED,
+                .type = SERVICE_SIMPLE,
+        };
+        Unit *u = UNIT(&s);
+
+        for (i = 0; i < ELEMENTSOF(test_states); i++) {
+                s.state = test_states[i];
+                printf("\nWith collapsing for service state %s\n"
+                       "=========================================\n", service_state_to_string(s.state));
+                for (a = 0; a < _JOB_TYPE_MAX_MERGING; a++) {
+                        for (b = 0; b < _JOB_TYPE_MAX_MERGING; b++) {
+
+                                ab = a;
+                                merged_ab = (job_type_merge_and_collapse(&ab, b, u) >= 0);
+
+                                if (!job_type_is_mergeable(a, b)) {
+                                        assert(!merged_ab);
+                                        printf("Not mergeable: %s + %s\n", job_type_to_string(a), job_type_to_string(b));
+                                        continue;
+                                }
+
+                                assert(merged_ab);
+                                printf("%s + %s = %s\n", job_type_to_string(a), job_type_to_string(b), job_type_to_string(ab));
+
+                                for (c = 0; c < _JOB_TYPE_MAX_MERGING; c++) {
+
+                                        /* Verify transitivity of mergeability of job types */
+                                        assert(!job_type_is_mergeable(a, b) ||
+                                               !job_type_is_mergeable(b, c) ||
+                                               job_type_is_mergeable(a, c));
+
+                                        /* Verify that merged entries can be merged with the same entries
+                                         * they can be merged with separately */
+                                        assert(!job_type_is_mergeable(a, c) || job_type_is_mergeable(ab, c));
+                                        assert(!job_type_is_mergeable(b, c) || job_type_is_mergeable(ab, c));
+
+                                        /* Verify that if a merged with b is not mergeable with c, then
+                                         * either a or b is not mergeable with c either. */
+                                        assert(job_type_is_mergeable(ab, c) || !job_type_is_mergeable(a, c) || !job_type_is_mergeable(b, c));
+
+                                        bc = b;
+                                        if (job_type_merge_and_collapse(&bc, c, u) >= 0) {
+
+                                                /* Verify associativity */
+
+                                                ab_c = ab;
+                                                assert(job_type_merge_and_collapse(&ab_c, c, u) == 0);
+
+                                                bc_a = bc;
+                                                assert(job_type_merge_and_collapse(&bc_a, a, u) == 0);
+
+                                                a_bc = a;
+                                                assert(job_type_merge_and_collapse(&a_bc, bc, u) == 0);
+
+                                                assert(ab_c == bc_a);
+                                                assert(ab_c == a_bc);
+
+                                                printf("%s + %s + %s = %s\n", job_type_to_string(a), job_type_to_string(b), job_type_to_string(c), job_type_to_string(ab_c));
+                                        }
+                                }
+                        }
+                }
+        }
+
+
+        return 0;
+}
diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c
new file mode 100644 (file)
index 0000000..caa3b4d
--- /dev/null
@@ -0,0 +1,520 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+
+#include "libudev.h"
+#include "util.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static void log_fn(struct udev *udev,
+                   int priority, const char *file, int line, const char *fn,
+                   const char *format, va_list args)
+{
+        printf("test-libudev: %s %s:%d ", fn, file, line);
+        vprintf(format, args);
+}
+
+static void print_device(struct udev_device *device)
+{
+        const char *str;
+        dev_t devnum;
+        int count;
+        struct udev_list_entry *list_entry;
+
+        printf("*** device: %p ***\n", device);
+        str = udev_device_get_action(device);
+        if (str != NULL)
+                printf("action:    '%s'\n", str);
+
+        str = udev_device_get_syspath(device);
+        printf("syspath:   '%s'\n", str);
+
+        str = udev_device_get_sysname(device);
+        printf("sysname:   '%s'\n", str);
+
+        str = udev_device_get_sysnum(device);
+        if (str != NULL)
+                printf("sysnum:    '%s'\n", str);
+
+        str = udev_device_get_devpath(device);
+        printf("devpath:   '%s'\n", str);
+
+        str = udev_device_get_subsystem(device);
+        if (str != NULL)
+                printf("subsystem: '%s'\n", str);
+
+        str = udev_device_get_devtype(device);
+        if (str != NULL)
+                printf("devtype:   '%s'\n", str);
+
+        str = udev_device_get_driver(device);
+        if (str != NULL)
+                printf("driver:    '%s'\n", str);
+
+        str = udev_device_get_devnode(device);
+        if (str != NULL)
+                printf("devname:   '%s'\n", str);
+
+        devnum = udev_device_get_devnum(device);
+        if (major(devnum) > 0)
+                printf("devnum:    %u:%u\n", major(devnum), minor(devnum));
+
+        count = 0;
+        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
+                printf("link:      '%s'\n", udev_list_entry_get_name(list_entry));
+                count++;
+        }
+        if (count > 0)
+                printf("found %i links\n", count);
+
+        count = 0;
+        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
+                printf("property:  '%s=%s'\n",
+                       udev_list_entry_get_name(list_entry),
+                       udev_list_entry_get_value(list_entry));
+                count++;
+        }
+        if (count > 0)
+                printf("found %i properties\n", count);
+
+        str = udev_device_get_property_value(device, "MAJOR");
+        if (str != NULL)
+                printf("MAJOR: '%s'\n", str);
+
+        str = udev_device_get_sysattr_value(device, "dev");
+        if (str != NULL)
+                printf("attr{dev}: '%s'\n", str);
+
+        printf("\n");
+}
+
+static int test_device(struct udev *udev, const char *syspath)
+{
+        struct udev_device *device;
+
+        printf("looking at device: %s\n", syspath);
+        device = udev_device_new_from_syspath(udev, syspath);
+        if (device == NULL) {
+                printf("no device found\n");
+                return -1;
+        }
+        print_device(device);
+        udev_device_unref(device);
+        return 0;
+}
+
+static int test_device_parents(struct udev *udev, const char *syspath)
+{
+        struct udev_device *device;
+        struct udev_device *device_parent;
+
+        printf("looking at device: %s\n", syspath);
+        device = udev_device_new_from_syspath(udev, syspath);
+        if (device == NULL)
+                return -1;
+
+        printf("looking at parents\n");
+        device_parent = device;
+        do {
+                print_device(device_parent);
+                device_parent = udev_device_get_parent(device_parent);
+        } while (device_parent != NULL);
+
+        printf("looking at parents again\n");
+        device_parent = device;
+        do {
+                print_device(device_parent);
+                device_parent = udev_device_get_parent(device_parent);
+        } while (device_parent != NULL);
+        udev_device_unref(device);
+
+        return 0;
+}
+
+static int test_device_devnum(struct udev *udev)
+{
+        dev_t devnum = makedev(1, 3);
+        struct udev_device *device;
+
+        printf("looking up device: %u:%u\n", major(devnum), minor(devnum));
+        device = udev_device_new_from_devnum(udev, 'c', devnum);
+        if (device == NULL)
+                return -1;
+        print_device(device);
+        udev_device_unref(device);
+        return 0;
+}
+
+static int test_device_subsys_name(struct udev *udev)
+{
+        struct udev_device *device;
+
+        printf("looking up device: 'block':'sda'\n");
+        device = udev_device_new_from_subsystem_sysname(udev, "block", "sda");
+        if (device == NULL)
+                return -1;
+        print_device(device);
+        udev_device_unref(device);
+
+        printf("looking up device: 'subsystem':'pci'\n");
+        device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
+        if (device == NULL)
+                return -1;
+        print_device(device);
+        udev_device_unref(device);
+
+        printf("looking up device: 'drivers':'scsi:sd'\n");
+        device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd");
+        if (device == NULL)
+                return -1;
+        print_device(device);
+        udev_device_unref(device);
+
+        printf("looking up device: 'module':'printk'\n");
+        device = udev_device_new_from_subsystem_sysname(udev, "module", "printk");
+        if (device == NULL)
+                return -1;
+        print_device(device);
+        udev_device_unref(device);
+        return 0;
+}
+
+static int test_enumerate_print_list(struct udev_enumerate *enumerate)
+{
+        struct udev_list_entry *list_entry;
+        int count = 0;
+
+        udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
+                struct udev_device *device;
+
+                device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
+                                                      udev_list_entry_get_name(list_entry));
+                if (device != NULL) {
+                        printf("device: '%s' (%s)\n",
+                               udev_device_get_syspath(device),
+                               udev_device_get_subsystem(device));
+                        udev_device_unref(device);
+                        count++;
+                }
+        }
+        printf("found %i devices\n\n", count);
+        return count;
+}
+
+static int test_monitor(struct udev *udev)
+{
+        struct udev_monitor *udev_monitor = NULL;
+        int fd_ep;
+        int fd_udev = -1;
+        struct epoll_event ep_udev, ep_stdin;
+
+        fd_ep = epoll_create1(EPOLL_CLOEXEC);
+        if (fd_ep < 0) {
+                printf("error creating epoll fd: %m\n");
+                goto out;
+        }
+
+        udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
+        if (udev_monitor == NULL) {
+                printf("no socket\n");
+                goto out;
+        }
+        fd_udev = udev_monitor_get_fd(udev_monitor);
+
+        if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 ||
+            udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 ||
+            udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) {
+                printf("filter failed\n");
+                goto out;
+        }
+
+        if (udev_monitor_enable_receiving(udev_monitor) < 0) {
+                printf("bind failed\n");
+                goto out;
+        }
+
+        memset(&ep_udev, 0, sizeof(struct epoll_event));
+        ep_udev.events = EPOLLIN;
+        ep_udev.data.fd = fd_udev;
+        if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
+                printf("fail to add fd to epoll: %m\n");
+                goto out;
+        }
+
+        memset(&ep_stdin, 0, sizeof(struct epoll_event));
+        ep_stdin.events = EPOLLIN;
+        ep_stdin.data.fd = STDIN_FILENO;
+        if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) {
+                printf("fail to add fd to epoll: %m\n");
+                goto out;
+        }
+
+        for (;;) {
+                int fdcount;
+                struct epoll_event ev[4];
+                struct udev_device *device;
+                int i;
+
+                printf("waiting for events from udev, press ENTER to exit\n");
+                fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
+                printf("epoll fd count: %i\n", fdcount);
+
+                for (i = 0; i < fdcount; i++) {
+                        if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
+                                device = udev_monitor_receive_device(udev_monitor);
+                                if (device == NULL) {
+                                        printf("no device from socket\n");
+                                        continue;
+                                }
+                                print_device(device);
+                                udev_device_unref(device);
+                        } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
+                                printf("exiting loop\n");
+                                goto out;
+                        }
+                }
+        }
+out:
+        if (fd_ep >= 0)
+                close(fd_ep);
+        udev_monitor_unref(udev_monitor);
+        return 0;
+}
+
+static int test_queue(struct udev *udev)
+{
+        struct udev_queue *udev_queue;
+        unsigned long long int seqnum;
+        struct udev_list_entry *list_entry;
+
+        udev_queue = udev_queue_new(udev);
+        if (udev_queue == NULL)
+                return -1;
+        seqnum = udev_queue_get_kernel_seqnum(udev_queue);
+        printf("seqnum kernel: %llu\n", seqnum);
+        seqnum = udev_queue_get_udev_seqnum(udev_queue);
+        printf("seqnum udev  : %llu\n", seqnum);
+
+        if (udev_queue_get_queue_is_empty(udev_queue))
+                printf("queue is empty\n");
+        printf("get queue list\n");
+        udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
+                printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
+        printf("\n");
+        printf("get queue list again\n");
+        udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
+                printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
+        printf("\n");
+
+        list_entry = udev_queue_get_queued_list_entry(udev_queue);
+        if (list_entry != NULL) {
+                printf("event [%llu] is queued\n", seqnum);
+                seqnum = strtoull(udev_list_entry_get_value(list_entry), NULL, 10);
+                if (udev_queue_get_seqnum_is_finished(udev_queue, seqnum))
+                        printf("event [%llu] is not finished\n", seqnum);
+                else
+                        printf("event [%llu] is finished\n", seqnum);
+        }
+        printf("\n");
+        udev_queue_unref(udev_queue);
+        return 0;
+}
+
+static int test_enumerate(struct udev *udev, const char *subsystem)
+{
+        struct udev_enumerate *udev_enumerate;
+
+        printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem);
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
+        udev_enumerate_scan_devices(udev_enumerate);
+        test_enumerate_print_list(udev_enumerate);
+        udev_enumerate_unref(udev_enumerate);
+
+        printf("enumerate 'net' + duplicated scan + null + zero\n");
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_add_match_subsystem(udev_enumerate, "net");
+        udev_enumerate_scan_devices(udev_enumerate);
+        udev_enumerate_scan_devices(udev_enumerate);
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
+        udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
+        udev_enumerate_scan_devices(udev_enumerate);
+        test_enumerate_print_list(udev_enumerate);
+        udev_enumerate_unref(udev_enumerate);
+
+        printf("enumerate 'block'\n");
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_add_match_subsystem(udev_enumerate,"block");
+        udev_enumerate_add_match_is_initialized(udev_enumerate);
+        udev_enumerate_scan_devices(udev_enumerate);
+        test_enumerate_print_list(udev_enumerate);
+        udev_enumerate_unref(udev_enumerate);
+
+        printf("enumerate 'not block'\n");
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block");
+        udev_enumerate_scan_devices(udev_enumerate);
+        test_enumerate_print_list(udev_enumerate);
+        udev_enumerate_unref(udev_enumerate);
+
+        printf("enumerate 'pci, mem, vc'\n");
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_add_match_subsystem(udev_enumerate, "pci");
+        udev_enumerate_add_match_subsystem(udev_enumerate, "mem");
+        udev_enumerate_add_match_subsystem(udev_enumerate, "vc");
+        udev_enumerate_scan_devices(udev_enumerate);
+        test_enumerate_print_list(udev_enumerate);
+        udev_enumerate_unref(udev_enumerate);
+
+        printf("enumerate 'subsystem'\n");
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_scan_subsystems(udev_enumerate);
+        test_enumerate_print_list(udev_enumerate);
+        udev_enumerate_unref(udev_enumerate);
+
+        printf("enumerate 'property IF_FS_*=filesystem'\n");
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_add_match_property(udev_enumerate, "ID_FS*", "filesystem");
+        udev_enumerate_scan_devices(udev_enumerate);
+        test_enumerate_print_list(udev_enumerate);
+        udev_enumerate_unref(udev_enumerate);
+        return 0;
+}
+
+static int test_hwdb(struct udev *udev, const char *modalias) {
+        struct udev_hwdb * hwdb;
+        struct udev_list_entry *entry;
+
+        hwdb = udev_hwdb_new(udev);
+
+        udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
+                printf("'%s'='%s'\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
+        printf("\n");
+
+        hwdb = udev_hwdb_unref(hwdb);
+        return 0;
+}
+
+int main(int argc, char *argv[])
+{
+        struct udev *udev = NULL;
+        static const struct option options[] = {
+                { "syspath", required_argument, NULL, 'p' },
+                { "subsystem", required_argument, NULL, 's' },
+                { "debug", no_argument, NULL, 'd' },
+                { "help", no_argument, NULL, 'h' },
+                { "version", no_argument, NULL, 'V' },
+                {}
+        };
+        const char *syspath = "/devices/virtual/mem/null";
+        const char *subsystem = NULL;
+        char path[1024];
+
+        udev = udev_new();
+        printf("context: %p\n", udev);
+        if (udev == NULL) {
+                printf("no context\n");
+                return 1;
+        }
+        udev_set_log_fn(udev, log_fn);
+        printf("set log: %p\n", log_fn);
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "+p:s:dhV", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'p':
+                        syspath = optarg;
+                        break;
+                case 's':
+                        subsystem = optarg;
+                        break;
+                case 'd':
+                        if (udev_get_log_priority(udev) < LOG_INFO)
+                                udev_set_log_priority(udev, LOG_INFO);
+                        break;
+                case 'h':
+                        printf("--debug --syspath= --subsystem= --help\n");
+                        goto out;
+                case 'V':
+                        printf("%s\n", VERSION);
+                        goto out;
+                default:
+                        goto out;
+                }
+        }
+
+        /* add sys path if needed */
+        if (!startswith(syspath, "/sys")) {
+                snprintf(path, sizeof(path), "/sys/%s", syspath);
+                syspath = path;
+        }
+
+        test_device(udev, syspath);
+        test_device_devnum(udev);
+        test_device_subsys_name(udev);
+        test_device_parents(udev, syspath);
+
+        test_enumerate(udev, subsystem);
+
+        test_queue(udev);
+
+        test_hwdb(udev, "usb:v0D50p0011*");
+
+        test_monitor(udev);
+out:
+        udev_unref(udev);
+        return 0;
+}
diff --git a/src/test/test-log.c b/src/test/test-log.c
new file mode 100644 (file)
index 0000000..8dc3d53
--- /dev/null
@@ -0,0 +1,53 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stddef.h>
+#include <unistd.h>
+
+#include "log.h"
+
+int main(int argc, char* argv[]) {
+
+        log_set_target(LOG_TARGET_CONSOLE);
+        log_open();
+
+        log_struct(LOG_INFO,
+                   "MESSAGE=Waldo PID=%lu", (unsigned long) getpid(),
+                   "SERVICE=piepapo",
+                   NULL);
+
+        log_set_target(LOG_TARGET_JOURNAL);
+        log_open();
+
+        log_struct(LOG_INFO,
+                   "MESSAGE=Foobar PID=%lu", (unsigned long) getpid(),
+                   "SERVICE=foobar",
+                   NULL);
+
+        log_struct(LOG_INFO,
+                   "MESSAGE=Foobar PID=%lu", (unsigned long) getpid(),
+                   "FORMAT_STR_TEST=1=%i A=%c 2=%hi 3=%li 4=%lli 1=%p foo=%s 2.5=%g 3.5=%g 4.5=%Lg",
+                   (int) 1, 'A', (short) 2, (long int) 3, (long long int) 4, (void*) 1, "foo", (float) 2.5f, (double) 3.5, (long double) 4.5,
+                   "SUFFIX=GOT IT",
+                   NULL);
+
+        return 0;
+}
diff --git a/src/test/test-loopback.c b/src/test/test-loopback.c
new file mode 100644 (file)
index 0000000..ab330ac
--- /dev/null
@@ -0,0 +1,37 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "loopback-setup.h"
+#include "util.h"
+
+int main(int argc, char* argv[]) {
+        int r;
+
+        if ((r = loopback_setup()) < 0)
+                fprintf(stderr, "loopback: %s\n", strerror(-r));
+
+        return 0;
+}
diff --git a/src/test/test-ns.c b/src/test/test-ns.c
new file mode 100644 (file)
index 0000000..b1c759f
--- /dev/null
@@ -0,0 +1,61 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <linux/fs.h>
+
+#include "namespace.h"
+#include "log.h"
+
+int main(int argc, char *argv[]) {
+        const char * const writable[] = {
+                "/home",
+                NULL
+        };
+
+        const char * const readonly[] = {
+                "/",
+                "/usr",
+                "/boot",
+                NULL
+        };
+
+        const char * const inaccessible[] = {
+                "/home/lennart/projects",
+                NULL
+        };
+
+        int r;
+
+        r = setup_namespace((char**) writable, (char**) readonly, (char**) inaccessible, true, 0);
+        if (r < 0) {
+                log_error("Failed to setup namespace: %s", strerror(-r));
+                return 1;
+        }
+
+        execl("/bin/sh", "/bin/sh", NULL);
+        log_error("execl(): %m");
+
+        return 1;
+}
diff --git a/src/test/test-replace-var.c b/src/test/test-replace-var.c
new file mode 100644 (file)
index 0000000..b1d42d7
--- /dev/null
@@ -0,0 +1,46 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "util.h"
+#include "macro.h"
+#include "replace-var.h"
+
+static char *lookup(const char *variable, void *userdata) {
+        return strjoin("<<<", variable, ">>>", NULL);
+}
+
+int main(int argc, char *argv[]) {
+        char *r;
+
+        assert_se(r = replace_var("@@@foobar@xyz@HALLO@foobar@test@@testtest@TEST@...@@@", lookup, NULL));
+        puts(r);
+        assert_se(streq(r, "@@@foobar@xyz<<<HALLO>>>foobar@test@@testtest<<<TEST>>>...@@@"));
+        free(r);
+
+        assert_se(r = strreplace("XYZFFFFXYZFFFFXYZ", "XYZ", "ABC"));
+        puts(r);
+        assert_se(streq(r, "ABCFFFFABCFFFFABC"));
+        free(r);
+
+        return 0;
+}
diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c
new file mode 100644 (file)
index 0000000..29235e8
--- /dev/null
@@ -0,0 +1,86 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Holger Hans Peter Freyther
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sched.h>
+
+#include "manager.h"
+
+
+int main(int argc, char *argv[]) {
+        Manager *m;
+        Unit *idle_ok, *idle_bad, *rr_ok, *rr_bad, *rr_sched;
+        Service *ser;
+        FILE *serial = NULL;
+        FDSet *fdset = NULL;
+
+        /* prepare the test */
+        assert_se(set_unit_path(TEST_DIR) >= 0);
+        assert_se(manager_new(SYSTEMD_SYSTEM, &m) >= 0);
+        assert_se(manager_startup(m, serial, fdset) >= 0);
+
+        /* load idle ok */
+        assert_se(manager_load_unit(m, "sched_idle_ok.service", NULL, NULL, &idle_ok) >= 0);
+        assert_se(idle_ok->load_state == UNIT_LOADED);
+        ser = SERVICE(idle_ok);
+        assert_se(ser->exec_context.cpu_sched_policy == SCHED_OTHER);
+        assert_se(ser->exec_context.cpu_sched_priority == 0);
+
+        /*
+         * load idle bad. This should print a warning but we have no way to look at it.
+         */
+        assert_se(manager_load_unit(m, "sched_idle_bad.service", NULL, NULL, &idle_bad) >= 0);
+        assert_se(idle_bad->load_state == UNIT_LOADED);
+        ser = SERVICE(idle_ok);
+        assert_se(ser->exec_context.cpu_sched_policy == SCHED_OTHER);
+        assert_se(ser->exec_context.cpu_sched_priority == 0);
+
+        /*
+         * load rr ok.
+         * Test that the default priority is moving from 0 to 1.
+         */
+        assert_se(manager_load_unit(m, "sched_rr_ok.service", NULL, NULL, &rr_ok) >= 0);
+        assert_se(rr_ok->load_state == UNIT_LOADED);
+        ser = SERVICE(rr_ok);
+        assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR);
+        assert_se(ser->exec_context.cpu_sched_priority == 1);
+
+        /*
+         * load rr bad.
+         * Test that the value of 0 and 100 is ignored.
+         */
+        assert_se(manager_load_unit(m, "sched_rr_bad.service", NULL, NULL, &rr_bad) >= 0);
+        assert_se(rr_bad->load_state == UNIT_LOADED);
+        ser = SERVICE(rr_bad);
+        assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR);
+        assert_se(ser->exec_context.cpu_sched_priority == 1);
+
+        /*
+         * load rr change.
+         * Test that anything between 1 and 99 can be set.
+         */
+        assert_se(manager_load_unit(m, "sched_rr_change.service", NULL, NULL, &rr_sched) >= 0);
+        assert_se(rr_sched->load_state == UNIT_LOADED);
+        ser = SERVICE(rr_sched);
+        assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR);
+        assert_se(ser->exec_context.cpu_sched_priority == 99);
+
+        return 0;
+}
diff --git a/src/test/test-sleep.c b/src/test/test-sleep.c
new file mode 100644 (file)
index 0000000..5a98ecd
--- /dev/null
@@ -0,0 +1,39 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "util.h"
+#include "log.h"
+
+int main(int argc, char* argv[]) {
+        log_info("Can Suspend: %s", yes_no(can_sleep("mem") > 0));
+        log_info("Can Hibernate: %s", yes_no(can_sleep("disk") > 0));
+        log_info("Can Hibernate+Suspend (Hybrid-Sleep): %s", yes_no(can_sleep_disk("suspend") > 0));
+        log_info("Can Hibernate+Reboot: %s", yes_no(can_sleep_disk("reboot") > 0));
+        log_info("Can Hibernate+Platform: %s", yes_no(can_sleep_disk("platform") > 0));
+        log_info("Can Hibernate+Shutdown: %s", yes_no(can_sleep_disk("shutdown") > 0));
+
+        return 0;
+}
diff --git a/src/test/test-strip-tab-ansi.c b/src/test/test-strip-tab-ansi.c
new file mode 100644 (file)
index 0000000..5016906
--- /dev/null
@@ -0,0 +1,52 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+
+#include "util.h"
+
+int main(int argc, char *argv[]) {
+        char *p;
+
+        assert_se(p = strdup("\tFoobar\tbar\twaldo\t"));
+        assert_se(strip_tab_ansi(&p, NULL));
+        fprintf(stdout, "<%s>\n", p);
+        assert_se(streq(p, "        Foobar        bar        waldo        "));
+        free(p);
+
+        assert_se(p = strdup(ANSI_HIGHLIGHT_ON "Hello" ANSI_HIGHLIGHT_OFF ANSI_HIGHLIGHT_RED_ON " world!" ANSI_HIGHLIGHT_OFF));
+        assert_se(strip_tab_ansi(&p, NULL));
+        fprintf(stdout, "<%s>\n", p);
+        assert_se(streq(p, "Hello world!"));
+        free(p);
+
+        assert_se(p = strdup("\x1B[\x1B[\t\x1B[" ANSI_HIGHLIGHT_ON "\x1B[" "Hello" ANSI_HIGHLIGHT_OFF ANSI_HIGHLIGHT_RED_ON " world!" ANSI_HIGHLIGHT_OFF));
+        assert_se(strip_tab_ansi(&p, NULL));
+        assert_se(streq(p, "\x1B[\x1B[        \x1B[\x1B[Hello world!"));
+        free(p);
+
+        assert_se(p = strdup("\x1B[waldo"));
+        assert_se(strip_tab_ansi(&p, NULL));
+        assert_se(streq(p, "\x1B[waldo"));
+        free(p);
+
+        return 0;
+}
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
new file mode 100644 (file)
index 0000000..5ee4447
--- /dev/null
@@ -0,0 +1,66 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "util.h"
+#include "specifier.h"
+
+int main(int argc, char *argv[]) {
+        const Specifier table[] = {
+                { 'a', specifier_string, (char*) "AAAA" },
+                { 'b', specifier_string, (char*) "BBBB" },
+                { 0, NULL, NULL }
+        };
+
+        char *w, *state;
+        size_t l;
+        const char test[] = "test a b c 'd' e '' '' hhh '' ''";
+
+        printf("<%s>\n", test);
+
+        FOREACH_WORD_QUOTED(w, l, test, state) {
+                char *t;
+
+                assert_se(t = strndup(w, l));
+                printf("<%s>\n", t);
+                free(t);
+        }
+
+        printf("%s\n", default_term_for_tty("/dev/tty23"));
+        printf("%s\n", default_term_for_tty("/dev/ttyS23"));
+        printf("%s\n", default_term_for_tty("/dev/tty0"));
+        printf("%s\n", default_term_for_tty("/dev/pty0"));
+        printf("%s\n", default_term_for_tty("/dev/pts/0"));
+        printf("%s\n", default_term_for_tty("/dev/console"));
+        printf("%s\n", default_term_for_tty("tty23"));
+        printf("%s\n", default_term_for_tty("ttyS23"));
+        printf("%s\n", default_term_for_tty("tty0"));
+        printf("%s\n", default_term_for_tty("pty0"));
+        printf("%s\n", default_term_for_tty("pts/0"));
+        printf("%s\n", default_term_for_tty("console"));
+
+        w = specifier_printf("xxx a=%a b=%b yyy", table, NULL);
+        printf("<%s>\n", w);
+        free(w);
+
+        return 0;
+}
diff --git a/src/test/test-udev.c b/src/test/test-udev.c
new file mode 100644 (file)
index 0000000..db9d361
--- /dev/null
@@ -0,0 +1,170 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
+  Copyright 2004-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <grp.h>
+#include <sched.h>
+#include <sys/mount.h>
+#include <sys/signalfd.h>
+
+#include "udev.h"
+
+void udev_main_log(struct udev *udev, int priority,
+                   const char *file, int line, const char *fn,
+                   const char *format, va_list args) {}
+
+static int fake_filesystems(void) {
+        static const struct fakefs {
+                const char *src;
+                const char *target;
+                const char *error;
+        } fakefss[] = {
+                { "test/sys", "/sys",                   "failed to mount test /sys" },
+                { "test/dev", "/dev",                   "failed to mount test /dev" },
+                { "test/run", "/run",                   "failed to mount test /run" },
+                { "test/run", "/etc/udev/rules.d",      "failed to mount empty /etc/udev/rules.d" },
+                { "test/run", "/usr/lib/udev/rules.d",  "failed to mount empty /usr/lib/udev/rules.d" },
+        };
+        unsigned int i;
+        int err;
+
+        err = unshare(CLONE_NEWNS);
+        if (err < 0) {
+                err = -errno;
+                fprintf(stderr, "failed to call unshare(): %m\n");
+                goto out;
+        }
+
+        if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
+                err = -errno;
+                fprintf(stderr, "failed to mount / as private: %m\n");
+                goto out;
+        }
+
+        for (i = 0; i < ELEMENTSOF(fakefss); i++) {
+                err = mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL);
+                if (err < 0) {
+                        err = -errno;
+                        fprintf(stderr, "%s %m", fakefss[i].error);
+                        return err;
+                }
+        }
+out:
+        return err;
+}
+
+
+int main(int argc, char *argv[])
+{
+        struct udev *udev;
+        struct udev_event *event = NULL;
+        struct udev_device *dev = NULL;
+        struct udev_rules *rules = NULL;
+        char syspath[UTIL_PATH_SIZE];
+        const char *devpath;
+        const char *action;
+        sigset_t mask, sigmask_orig;
+        int err;
+
+        err = fake_filesystems();
+        if (err < 0)
+                return EXIT_FAILURE;
+
+        udev = udev_new();
+        if (udev == NULL)
+                exit(EXIT_FAILURE);
+        log_debug("version %s\n", VERSION);
+        label_init("/dev");
+
+        sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);
+
+        action = argv[1];
+        if (action == NULL) {
+                log_error("action missing\n");
+                goto out;
+        }
+
+        devpath = argv[2];
+        if (devpath == NULL) {
+                log_error("devpath missing\n");
+                goto out;
+        }
+
+        rules = udev_rules_new(udev, 1);
+
+        util_strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL);
+        dev = udev_device_new_from_syspath(udev, syspath);
+        if (dev == NULL) {
+                log_debug("unknown device '%s'\n", devpath);
+                goto out;
+        }
+
+        udev_device_set_action(dev, action);
+        event = udev_event_new(dev);
+
+        sigfillset(&mask);
+        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
+        event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (event->fd_signal < 0) {
+                fprintf(stderr, "error creating signalfd\n");
+                goto out;
+        }
+
+        /* do what devtmpfs usually provides us */
+        if (udev_device_get_devnode(dev) != NULL) {
+                mode_t mode = 0600;
+
+                if (strcmp(udev_device_get_subsystem(dev), "block") == 0)
+                        mode |= S_IFBLK;
+                else
+                        mode |= S_IFCHR;
+
+                if (strcmp(action, "remove") != 0) {
+                        mkdir_parents_label(udev_device_get_devnode(dev), 0755);
+                        mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev));
+                } else {
+                        unlink(udev_device_get_devnode(dev));
+                        util_delete_path(udev, udev_device_get_devnode(dev));
+                }
+        }
+
+        err = udev_event_execute_rules(event, rules, &sigmask_orig);
+        if (err == 0)
+                udev_event_execute_run(event, NULL);
+out:
+        if (event != NULL && event->fd_signal >= 0)
+                close(event->fd_signal);
+        udev_event_unref(event);
+        udev_device_unref(dev);
+        udev_rules_unref(rules);
+        label_finish();
+        udev_unref(udev);
+        if (err != 0)
+                return EXIT_FAILURE;
+        return EXIT_SUCCESS;
+}
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
new file mode 100644 (file)
index 0000000..6636b94
--- /dev/null
@@ -0,0 +1,183 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "install.h"
+#include "util.h"
+#include "macro.h"
+#include "hashmap.h"
+#include "load-fragment.h"
+
+static void test_unit_file_get_set(void) {
+        int r;
+        Hashmap *h;
+        Iterator i;
+        UnitFileList *p;
+
+        h = hashmap_new(string_hash_func, string_compare_func);
+        assert(h);
+
+        r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
+        log_info("unit_file_get_list: %s", strerror(-r));
+        assert(r >= 0);
+
+        HASHMAP_FOREACH(p, h, i)
+                printf("%s = %s\n", p->path, unit_file_state_to_string(p->state));
+
+        unit_file_list_free(h);
+}
+
+static void check_execcommand(ExecCommand *c,
+                              const char* path,
+                              const char* argv0,
+                              const char* argv1,
+                              bool ignore) {
+        assert_se(c);
+        log_info("%s %s %s %s",
+                 c->path, c->argv[0], c->argv[1], c->argv[2]);
+        assert_se(streq(c->path, path));
+        assert_se(streq(c->argv[0], argv0));
+        assert_se(streq(c->argv[1], argv1));
+        assert_se(c->argv[2] == NULL);
+        assert_se(c->ignore == ignore);
+}
+
+static void test_config_parse_exec(void) {
+        /* int config_parse_exec( */
+        /*         const char *filename, */
+        /*         unsigned line, */
+        /*         const char *section, */
+        /*         const char *lvalue, */
+        /*         int ltype, */
+        /*         const char *rvalue, */
+        /*         void *data, */
+        /*         void *userdata) */
+        int r;
+
+        ExecCommand *c = NULL, *c1;
+
+        /* basic test */
+        r = config_parse_exec("fake", 1, "section",
+                              "LValue", 0, "/RValue r1",
+                              &c, NULL);
+        assert_se(r >= 0);
+        check_execcommand(c, "/RValue", "/RValue", "r1", false);
+
+        r = config_parse_exec("fake", 2, "section",
+                              "LValue", 0, "/RValue///slashes/// r1",
+                              &c, NULL);
+       /* test slashes */
+        assert_se(r >= 0);
+        c1 = c->command_next;
+        check_execcommand(c1, "/RValue/slashes", "/RValue///slashes///",
+                          "r1", false);
+
+        /* honour_argv0 */
+        r = config_parse_exec("fake", 3, "section",
+                              "LValue", 0, "@/RValue///slashes2/// argv0 r1",
+                              &c, NULL);
+        assert_se(r >= 0);
+        c1 = c1->command_next;
+        check_execcommand(c1, "/RValue/slashes2", "argv0", "r1", false);
+
+        /* ignore && honour_argv0 */
+        r = config_parse_exec("fake", 4, "section",
+                              "LValue", 0, "-@/RValue///slashes3/// argv0a r1",
+                              &c, NULL);
+        assert_se(r >= 0);
+        c1 = c1->command_next;
+        check_execcommand(c1,
+                          "/RValue/slashes3", "argv0a", "r1", true);
+
+        /* ignore && honour_argv0 */
+        r = config_parse_exec("fake", 4, "section",
+                              "LValue", 0, "@-/RValue///slashes4/// argv0b r1",
+                              &c, NULL);
+        assert_se(r >= 0);
+        c1 = c1->command_next;
+        check_execcommand(c1,
+                          "/RValue/slashes4", "argv0b", "r1", true);
+
+        /* ignore && ignore */
+        r = config_parse_exec("fake", 4, "section",
+                              "LValue", 0, "--/RValue argv0 r1",
+                              &c, NULL);
+        assert_se(r == 0);
+        assert_se(c1->command_next == NULL);
+
+        /* ignore && ignore */
+        r = config_parse_exec("fake", 4, "section",
+                              "LValue", 0, "-@-/RValue argv0 r1",
+                              &c, NULL);
+        assert_se(r == 0);
+        assert_se(c1->command_next == NULL);
+
+        /* semicolon */
+        r = config_parse_exec("fake", 5, "section",
+                              "LValue", 0,
+                              "-@/RValue argv0 r1 ; "
+                              "/goo/goo boo",
+                              &c, NULL);
+        assert_se(r >= 0);
+        c1 = c1->command_next;
+        check_execcommand(c1,
+                          "/RValue", "argv0", "r1", true);
+
+        c1 = c1->command_next;
+        check_execcommand(c1,
+                          "/goo/goo", "/goo/goo", "boo", false);
+
+        /* trailing semicolon */
+        r = config_parse_exec("fake", 5, "section",
+                              "LValue", 0,
+                              "-@/RValue argv0 r1 ; ",
+                              &c, NULL);
+        assert_se(r >= 0);
+        c1 = c1->command_next;
+        check_execcommand(c1,
+                          "/RValue", "argv0", "r1", true);
+
+        assert_se(c1->command_next == NULL);
+
+        /* escaped semicolon */
+        r = config_parse_exec("fake", 5, "section",
+                              "LValue", 0,
+                              "/usr/bin/find \\;",
+                              &c, NULL);
+        assert_se(r >= 0);
+        c1 = c1->command_next;
+        check_execcommand(c1,
+                          "/usr/bin/find", "/usr/bin/find", ";", false);
+
+        exec_command_free_list(c);
+}
+
+int main(int argc, char *argv[]) {
+
+        test_unit_file_get_set();
+        test_config_parse_exec();
+
+        return 0;
+}
diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
new file mode 100644 (file)
index 0000000..50187e1
--- /dev/null
@@ -0,0 +1,177 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "unit-name.h"
+#include "util.h"
+
+int main(int argc, char* argv[]) {
+        char *t, *k;
+
+        t = unit_name_replace_instance("foo@.service", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("foo@xyz.service", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("xyz", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("", "");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("foo.service", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance(".service", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("foo@bar", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("foo@", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("@", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_replace_instance("@bar", "waldo");
+        puts(t);
+        free(t);
+
+        t = unit_name_from_path("/waldo", ".mount");
+        puts(t);
+        k = unit_name_to_path(t);
+        puts(k);
+        free(k);
+        free(t);
+
+        t = unit_name_from_path("/waldo/quuix", ".mount");
+        puts(t);
+        k = unit_name_to_path(t);
+        puts(k);
+        free(k);
+        free(t);
+
+        t = unit_name_from_path("/waldo/quuix/", ".mount");
+        puts(t);
+        k = unit_name_to_path(t);
+        puts(k);
+        free(k);
+        free(t);
+
+        t = unit_name_from_path("/", ".mount");
+        puts(t);
+        k = unit_name_to_path(t);
+        puts(k);
+        free(k);
+        free(t);
+
+        t = unit_name_from_path("///", ".mount");
+        puts(t);
+        k = unit_name_to_path(t);
+        puts(k);
+        free(k);
+        free(t);
+
+        t = unit_name_from_path_instance("waldo", "/waldo", ".mount");
+        puts(t);
+        free(t);
+
+        t = unit_name_from_path_instance("waldo", "/waldo////quuix////", ".mount");
+        puts(t);
+        free(t);
+
+        t = unit_name_from_path_instance("waldo", "/", ".mount");
+        puts(t);
+        free(t);
+
+        t = unit_name_from_path_instance("wa--ldo", "/--", ".mount");
+        puts(t);
+        free(t);
+
+        assert_se(t = unit_name_mangle("/home"));
+        assert_se(k = unit_name_mangle(t));
+        puts(t);
+        assert_se(streq(t, k));
+        free(t);
+        free(k);
+
+        assert_se(t = unit_name_mangle("/dev/sda"));
+        assert_se(k = unit_name_mangle(t));
+        puts(t);
+        assert_se(streq(t, k));
+        free(t);
+        free(k);
+
+        assert_se(t = unit_name_mangle("üxknürz.service"));
+        assert_se(k = unit_name_mangle(t));
+        puts(t);
+        assert_se(streq(t, k));
+        free(t);
+        free(k);
+
+        assert_se(t = unit_name_mangle("foobar-meh...waldi.service"));
+        assert_se(k = unit_name_mangle(t));
+        puts(t);
+        assert_se(streq(t, k));
+        free(t);
+        free(k);
+
+        assert_se(t = unit_name_mangle("_____####----.....service"));
+        assert_se(k = unit_name_mangle(t));
+        puts(t);
+        assert_se(streq(t, k));
+        free(t);
+        free(k);
+
+        assert_se(t = unit_name_mangle("_____##@;;;,,,##----.....service"));
+        assert_se(k = unit_name_mangle(t));
+        puts(t);
+        assert_se(streq(t, k));
+        free(t);
+        free(k);
+
+        assert_se(t = unit_name_mangle("xxx@@@@/////\\\\\\\\\\yyy.service"));
+        assert_se(k = unit_name_mangle(t));
+        puts(t);
+        assert_se(streq(t, k));
+        free(t);
+        free(k);
+
+        return 0;
+}
diff --git a/src/test/test-watchdog.c b/src/test/test-watchdog.c
new file mode 100644 (file)
index 0000000..ccb1854
--- /dev/null
@@ -0,0 +1,51 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <string.h>
+
+#include "watchdog.h"
+#include "log.h"
+
+int main(int argc, char *argv[]) {
+        usec_t t = 10 * USEC_PER_SEC;
+        unsigned i;
+        int r;
+
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+
+        r = watchdog_set_timeout(&t);
+        if (r < 0)
+                log_warning("Failed to open watchdog: %s", strerror(-r));
+
+        for (i = 0; i < 5; i++) {
+                log_info("Pinging...");
+                r = watchdog_ping();
+                if (r < 0)
+                        log_warning("Failed to ping watchdog: %s", strerror(-r));
+
+                usleep(t/2);
+        }
+
+        watchdog_close(true);
+        return 0;
+}
diff --git a/src/timedate/.gitignore b/src/timedate/.gitignore
new file mode 100644 (file)
index 0000000..48757f0
--- /dev/null
@@ -0,0 +1 @@
+org.freedesktop.timedate1.policy
diff --git a/src/timedate/Makefile b/src/timedate/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/timedate/org.freedesktop.timedate1.conf b/src/timedate/org.freedesktop.timedate1.conf
new file mode 100644 (file)
index 0000000..36557d5
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0"?> <!--*-nxml-*-->
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<busconfig>
+
+        <policy user="root">
+                <allow own="org.freedesktop.timedate1"/>
+                <allow send_destination="org.freedesktop.timedate1"/>
+                <allow receive_sender="org.freedesktop.timedate1"/>
+        </policy>
+
+        <policy context="default">
+                <allow send_destination="org.freedesktop.timedate1"/>
+                <allow receive_sender="org.freedesktop.timedate1"/>
+        </policy>
+
+</busconfig>
diff --git a/src/timedate/org.freedesktop.timedate1.policy.in b/src/timedate/org.freedesktop.timedate1.policy.in
new file mode 100644 (file)
index 0000000..aa30b70
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<policyconfig>
+
+        <vendor>The systemd Project</vendor>
+        <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
+
+        <action id="org.freedesktop.timedate1.set-time">
+                <_description>Set system time</_description>
+                <_message>Authentication is required to set the system time.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.timedate1.set-timezone org.freedesktop.timedate1.set-ntp</annotate>
+        </action>
+
+        <action id="org.freedesktop.timedate1.set-timezone">
+                <_description>Set system timezone</_description>
+                <_message>Authentication is required to set the system timezone.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.timedate1.set-local-rtc">
+                <_description>Set RTC to local timezone or UTC</_description>
+                <_message>Authentication is required to control whether
+                the RTC stores the local or UTC time.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.timedate1.set-ntp">
+                <_description>Turn network time synchronization on or off</_description>
+                <_message>Authentication is required to control whether
+                network time synchronization shall be enabled.</_message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+</policyconfig>
diff --git a/src/timedate/org.freedesktop.timedate1.service b/src/timedate/org.freedesktop.timedate1.service
new file mode 100644 (file)
index 0000000..875f4be
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[D-BUS Service]
+Name=org.freedesktop.timedate1
+Exec=/bin/false
+User=root
+SystemdService=dbus-org.freedesktop.timedate1.service
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
new file mode 100644 (file)
index 0000000..281c052
--- /dev/null
@@ -0,0 +1,716 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <locale.h>
+#include <string.h>
+#include <sys/timex.h>
+
+#include "dbus-common.h"
+#include "util.h"
+#include "spawn-polkit-agent.h"
+#include "build.h"
+#include "hwclock.h"
+#include "strv.h"
+#include "pager.h"
+#include "time-dst.h"
+
+static bool arg_adjust_system_clock = false;
+static bool arg_no_pager = false;
+static enum transport {
+        TRANSPORT_NORMAL,
+        TRANSPORT_SSH,
+        TRANSPORT_POLKIT
+} arg_transport = TRANSPORT_NORMAL;
+static bool arg_ask_password = true;
+static const char *arg_host = NULL;
+
+static void pager_open_if_enabled(void) {
+
+        if (arg_no_pager)
+                return;
+
+        pager_open();
+}
+
+static void polkit_agent_open_if_enabled(void) {
+
+        /* Open the polkit agent as a child process if necessary */
+
+        if (!arg_ask_password)
+                return;
+
+        polkit_agent_open();
+}
+
+typedef struct StatusInfo {
+        const char *timezone;
+        bool local_rtc;
+        bool ntp;
+} StatusInfo;
+
+static bool ntp_synced(void) {
+        struct timex txc;
+
+        zero(txc);
+        if (adjtimex(&txc) < 0)
+                return false;
+
+        if (txc.status & STA_UNSYNC)
+                return false;
+
+        return true;
+}
+
+static const char *jump_str(int delta_minutes, char *s, size_t size) {
+        if (delta_minutes == 60)
+                return "one hour forward";
+        if (delta_minutes == -60)
+                return "one hour backwards";
+        if (delta_minutes < 0) {
+                snprintf(s, size, "%i minutes backwards", -delta_minutes);
+                return s;
+        }
+        if (delta_minutes > 0) {
+                snprintf(s, size, "%i minutes forward", delta_minutes);
+                return s;
+        }
+        return "";
+}
+
+static void print_status_info(StatusInfo *i) {
+        usec_t n;
+        char a[FORMAT_TIMESTAMP_MAX];
+        char b[FORMAT_TIMESTAMP_MAX];
+        char s[32];
+        struct tm tm;
+        time_t sec;
+        char *zc, *zn;
+        time_t t, tc, tn;
+        int dn;
+        bool is_dstc, is_dstn;
+        int r;
+
+        assert(i);
+
+        /* enforce the values of /etc/localtime */
+        if (getenv("TZ")) {
+                fprintf(stderr, "Warning: ignoring the TZ variable, reading the system's timezone setting only.\n\n");
+                unsetenv("TZ");
+        }
+
+        n = now(CLOCK_REALTIME);
+        sec = (time_t) (n / USEC_PER_SEC);
+
+        zero(tm);
+        assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) > 0);
+        char_array_0(a);
+        printf("      Local time: %s\n", a);
+
+        zero(tm);
+        assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm)) > 0);
+        char_array_0(a);
+        printf("  Universal time: %s\n", a);
+
+        zero(tm);
+        r = hwclock_get_time(&tm);
+        if (r >= 0) {
+                /* Calculcate the week-day */
+                mktime(&tm);
+
+                assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S", &tm) > 0);
+                char_array_0(a);
+                printf("        RTC time: %s\n", a);
+        }
+
+        zero(tm);
+        assert_se(strftime(a, sizeof(a), "%Z, %z", localtime_r(&sec, &tm)) > 0);
+        char_array_0(a);
+        printf("        Timezone: %s (%s)\n"
+               "     NTP enabled: %s\n"
+               "NTP synchronized: %s\n"
+               " RTC in local TZ: %s\n",
+               strna(i->timezone),
+               a,
+               yes_no(i->ntp),
+               yes_no(ntp_synced()),
+               yes_no(i->local_rtc));
+
+        r = time_get_dst(sec, "/etc/localtime",
+                         &tc, &zc, &is_dstc,
+                         &tn, &dn, &zn, &is_dstn);
+        if (r < 0)
+                printf("      DST active: n/a\n");
+        else {
+                printf("      DST active: %s\n", yes_no(is_dstc));
+
+                t = tc - 1;
+                zero(tm);
+                assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
+                char_array_0(a);
+
+                zero(tm);
+                assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)) > 0);
+                char_array_0(b);
+                printf(" Last DST change: DST %s at\n"
+                       "                  %s\n"
+                       "                  %s\n",
+                       is_dstc ? "began" : "ended", a, b);
+
+                t = tn - 1;
+                zero(tm);
+                assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
+                char_array_0(a);
+
+                zero(tm);
+                assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)) > 0);
+                char_array_0(b);
+                printf(" Next DST change: DST %s (the clock jumps %s) at\n"
+                       "                  %s\n"
+                       "                  %s\n",
+                       is_dstn ? "begins" : "ends", jump_str(dn, s, sizeof(s)), a, b);
+
+                free(zc);
+                free(zn);
+        }
+
+        if (i->local_rtc)
+                fputs("\n" ANSI_HIGHLIGHT_ON
+                      "Warning: The RTC is configured to maintain time in the local time zone. This\n"
+                      "         mode is not fully supported and will create various problems with time\n"
+                      "         zone changes and daylight saving adjustments. If at all possible use\n"
+                      "         RTC in UTC, by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout);
+}
+
+static int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) {
+        assert(name);
+        assert(iter);
+
+        switch (dbus_message_iter_get_arg_type(iter)) {
+
+        case DBUS_TYPE_STRING: {
+                const char *s;
+
+                dbus_message_iter_get_basic(iter, &s);
+                if (!isempty(s)) {
+                        if (streq(name, "Timezone"))
+                                i->timezone = s;
+                }
+                break;
+        }
+
+        case DBUS_TYPE_BOOLEAN: {
+                dbus_bool_t b;
+
+                dbus_message_iter_get_basic(iter, &b);
+                if (streq(name, "LocalRTC"))
+                        i->local_rtc = b;
+                else if (streq(name, "NTP"))
+                        i->ntp = b;
+        }
+        }
+
+        return 0;
+}
+
+static int show_status(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        const char *interface = "";
+        int r;
+        DBusMessageIter iter, sub, sub2, sub3;
+        StatusInfo info;
+
+        assert(args);
+
+        r = bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.timedate1",
+                        "/org/freedesktop/timedate1",
+                        "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_INVALID);
+        if (r < 0)
+                return r;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)  {
+                log_error("Failed to parse reply.");
+                return -EIO;
+        }
+
+        zero(info);
+        dbus_message_iter_recurse(&iter, &sub);
+
+        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                const char *name;
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                dbus_message_iter_recurse(&sub, &sub2);
+
+                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)  {
+                        log_error("Failed to parse reply.");
+                        return -EIO;
+                }
+
+                dbus_message_iter_recurse(&sub2, &sub3);
+
+                r = status_property(name, &sub3, &info);
+                if (r < 0) {
+                        log_error("Failed to parse reply.");
+                        return r;
+                }
+
+                dbus_message_iter_next(&sub);
+        }
+
+        print_status_info(&info);
+        return 0;
+}
+
+static int set_time(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t relative = false, interactive = true;
+        usec_t t;
+        dbus_int64_t u;
+        int r;
+
+        assert(args);
+        assert(n == 2);
+
+        polkit_agent_open_if_enabled();
+
+        r = parse_timestamp(args[1], &t);
+        if (r < 0) {
+                log_error("Failed to parse time specification: %s", args[1]);
+                return r;
+        }
+
+        u = (dbus_uint64_t) t;
+
+        return bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.timedate1",
+                        "/org/freedesktop/timedate1",
+                        "org.freedesktop.timedate1",
+                        "SetTime",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_INT64, &u,
+                        DBUS_TYPE_BOOLEAN, &relative,
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static int set_timezone(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t interactive = true;
+
+        assert(args);
+        assert(n == 2);
+
+        polkit_agent_open_if_enabled();
+
+        return bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.timedate1",
+                        "/org/freedesktop/timedate1",
+                        "org.freedesktop.timedate1",
+                        "SetTimezone",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &args[1],
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static int set_local_rtc(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t interactive = true, b, q;
+        int r;
+
+        assert(args);
+        assert(n == 2);
+
+        polkit_agent_open_if_enabled();
+
+        r = parse_boolean(args[1]);
+        if (r < 0) {
+                log_error("Failed to parse local RTC setting: %s", args[1]);
+                return r;
+        }
+
+        b = r;
+        q = arg_adjust_system_clock;
+
+        return bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.timedate1",
+                        "/org/freedesktop/timedate1",
+                        "org.freedesktop.timedate1",
+                        "SetLocalRTC",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_BOOLEAN, &b,
+                        DBUS_TYPE_BOOLEAN, &q,
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static int set_ntp(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        dbus_bool_t interactive = true, b;
+        int r;
+
+        assert(args);
+        assert(n == 2);
+
+        polkit_agent_open_if_enabled();
+
+        r = parse_boolean(args[1]);
+        if (r < 0) {
+                log_error("Failed to parse NTP setting: %s", args[1]);
+                return r;
+        }
+
+        b = r;
+
+        return bus_method_call_with_reply(
+                        bus,
+                        "org.freedesktop.timedate1",
+                        "/org/freedesktop/timedate1",
+                        "org.freedesktop.timedate1",
+                        "SetNTP",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_BOOLEAN, &b,
+                        DBUS_TYPE_BOOLEAN, &interactive,
+                        DBUS_TYPE_INVALID);
+}
+
+static int list_timezones(DBusConnection *bus, char **args, unsigned n) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_strv_free_ char **zones = NULL;
+        size_t n_zones = 0;
+        char **i;
+
+        assert(args);
+        assert(n == 1);
+
+        f = fopen("/usr/share/zoneinfo/zone.tab", "re");
+        if (!f) {
+                log_error("Failed to open timezone database: %m");
+                return -errno;
+        }
+
+        for (;;) {
+                char l[LINE_MAX], *p, **z, *w;
+                size_t k;
+
+                if (!fgets(l, sizeof(l), f)) {
+                        if (feof(f))
+                                break;
+
+                        log_error("Failed to read timezone database: %m");
+                        return -errno;
+                }
+
+                p = strstrip(l);
+
+                if (isempty(p) || *p == '#')
+                        continue;
+
+
+                /* Skip over country code */
+                p += strcspn(p, WHITESPACE);
+                p += strspn(p, WHITESPACE);
+
+                /* Skip over coordinates */
+                p += strcspn(p, WHITESPACE);
+                p += strspn(p, WHITESPACE);
+
+                /* Found timezone name */
+                k = strcspn(p, WHITESPACE);
+                if (k <= 0)
+                        continue;
+
+                w = strndup(p, k);
+                if (!w)
+                        return log_oom();
+
+                z = realloc(zones, sizeof(char*) * (n_zones + 2));
+                if (!z) {
+                        free(w);
+                        return log_oom();
+                }
+
+                zones = z;
+                zones[n_zones++] = w;
+        }
+
+        if (zones)
+                zones[n_zones] = NULL;
+
+        pager_open_if_enabled();
+
+        strv_sort(zones);
+        STRV_FOREACH(i, zones)
+                puts(*i);
+
+        return 0;
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] COMMAND ...\n\n"
+               "Query or change system time and date settings.\n\n"
+               "  -h --help              Show this help\n"
+               "     --version           Show package version\n"
+               "     --adjust-system-clock\n"
+               "                         Adjust system clock when changing local RTC mode\n"
+               "     --no-pager          Do not pipe output into a pager\n"
+               "     --no-ask-password   Do not prompt for password\n"
+               "  -H --host=[USER@]HOST  Operate on remote host\n\n"
+               "Commands:\n"
+               "  status                 Show current time settings\n"
+               "  set-time TIME          Set system time\n"
+               "  set-timezone ZONE      Set system timezone\n"
+               "  list-timezones         Show known timezones\n"
+               "  set-local-rtc BOOL     Control whether RTC is in local time\n"
+               "  set-ntp BOOL           Control whether NTP is enabled\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_NO_PAGER,
+                ARG_ADJUST_SYSTEM_CLOCK,
+                ARG_NO_ASK_PASSWORD
+        };
+
+        static const struct option options[] = {
+                { "help",                no_argument,       NULL, 'h'                     },
+                { "version",             no_argument,       NULL, ARG_VERSION             },
+                { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
+                { "host",                required_argument, NULL, 'H'                     },
+                { "privileged",          no_argument,       NULL, 'P'                     },
+                { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
+                { "adjust-system-clock", no_argument,       NULL, ARG_ADJUST_SYSTEM_CLOCK },
+                { NULL,                  0,                 NULL, 0                       }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "+hH:P", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case 'P':
+                        arg_transport = TRANSPORT_POLKIT;
+                        break;
+
+                case 'H':
+                        arg_transport = TRANSPORT_SSH;
+                        arg_host = optarg;
+                        break;
+
+                case ARG_ADJUST_SYSTEM_CLOCK:
+                        arg_adjust_system_clock = true;
+                        break;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        return 1;
+}
+
+static int timedatectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) {
+
+        static const struct {
+                const char* verb;
+                const enum {
+                        MORE,
+                        LESS,
+                        EQUAL
+                } argc_cmp;
+                const int argc;
+                int (* const dispatch)(DBusConnection *bus, char **args, unsigned n);
+        } verbs[] = {
+                { "status",                LESS,   1, show_status      },
+                { "set-time",              EQUAL,  2, set_time         },
+                { "set-timezone",          EQUAL,  2, set_timezone     },
+                { "list-timezones",        EQUAL,  1, list_timezones   },
+                { "set-local-rtc",         EQUAL,  2, set_local_rtc    },
+                { "set-ntp",               EQUAL,  2, set_ntp,         },
+        };
+
+        int left;
+        unsigned i;
+
+        assert(argc >= 0);
+        assert(argv);
+        assert(error);
+
+        left = argc - optind;
+
+        if (left <= 0)
+                /* Special rule: no arguments means "status" */
+                i = 0;
+        else {
+                if (streq(argv[optind], "help")) {
+                        help();
+                        return 0;
+                }
+
+                for (i = 0; i < ELEMENTSOF(verbs); i++)
+                        if (streq(argv[optind], verbs[i].verb))
+                                break;
+
+                if (i >= ELEMENTSOF(verbs)) {
+                        log_error("Unknown operation %s", argv[optind]);
+                        return -EINVAL;
+                }
+        }
+
+        switch (verbs[i].argc_cmp) {
+
+        case EQUAL:
+                if (left != verbs[i].argc) {
+                        log_error("Invalid number of arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case MORE:
+                if (left < verbs[i].argc) {
+                        log_error("Too few arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case LESS:
+                if (left > verbs[i].argc) {
+                        log_error("Too many arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("Unknown comparison operator.");
+        }
+
+        if (!bus) {
+                log_error("Failed to get D-Bus connection: %s", error->message);
+                return -EIO;
+        }
+
+        return verbs[i].dispatch(bus, argv + optind, left);
+}
+
+int main(int argc, char *argv[]) {
+        int r, retval = EXIT_FAILURE;
+        DBusConnection *bus = NULL;
+        DBusError error;
+
+        dbus_error_init(&error);
+
+        setlocale(LC_ALL, "");
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                goto finish;
+        else if (r == 0) {
+                retval = EXIT_SUCCESS;
+                goto finish;
+        }
+
+        if (arg_transport == TRANSPORT_NORMAL)
+                bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        else if (arg_transport == TRANSPORT_POLKIT)
+                bus_connect_system_polkit(&bus, &error);
+        else if (arg_transport == TRANSPORT_SSH)
+                bus_connect_system_ssh(NULL, arg_host, &bus, &error);
+        else
+                assert_not_reached("Uh, invalid transport...");
+
+        r = timedatectl_main(bus, argc, argv, &error);
+        retval = r < 0 ? EXIT_FAILURE : r;
+
+finish:
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        dbus_error_free(&error);
+        dbus_shutdown();
+
+        pager_close();
+
+        return retval;
+}
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
new file mode 100644 (file)
index 0000000..fdb4335
--- /dev/null
@@ -0,0 +1,1025 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dbus/dbus.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "systemd/sd-id128.h"
+#include "systemd/sd-messages.h"
+#include "util.h"
+#include "strv.h"
+#include "dbus-common.h"
+#include "polkit.h"
+#include "def.h"
+#include "hwclock.h"
+#include "conf-files.h"
+#include "path-util.h"
+
+#define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
+#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
+
+#define INTERFACE                                                       \
+        " <interface name=\"org.freedesktop.timedate1\">\n"             \
+        "  <property name=\"Timezone\" type=\"s\" access=\"read\"/>\n"  \
+        "  <property name=\"LocalRTC\" type=\"b\" access=\"read\"/>\n"  \
+        "  <property name=\"NTP\" type=\"b\" access=\"read\"/>\n"       \
+        "  <method name=\"SetTime\">\n"                                 \
+        "   <arg name=\"usec_utc\" type=\"x\" direction=\"in\"/>\n"     \
+        "   <arg name=\"relative\" type=\"b\" direction=\"in\"/>\n"     \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetTimezone\">\n"                             \
+        "   <arg name=\"timezone\" type=\"s\" direction=\"in\"/>\n"     \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetLocalRTC\">\n"                             \
+        "   <arg name=\"local_rtc\" type=\"b\" direction=\"in\"/>\n"    \
+        "   <arg name=\"fix_system\" type=\"b\" direction=\"in\"/>\n"   \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"SetNTP\">\n"                                  \
+        "   <arg name=\"use_ntp\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
+        "  </method>\n"                                                 \
+        " </interface>\n"
+
+#define INTROSPECTION                                                   \
+        DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+        "<node>\n"                                                      \
+        INTERFACE                                                       \
+        BUS_PROPERTIES_INTERFACE                                        \
+        BUS_INTROSPECTABLE_INTERFACE                                    \
+        BUS_PEER_INTERFACE                                              \
+        "</node>\n"
+
+#define INTERFACES_LIST                         \
+        BUS_GENERIC_INTERFACES_LIST             \
+        "org.freedesktop.timedate1\0"
+
+const char timedate_interface[] _introspect_("timedate1") = INTERFACE;
+
+typedef struct TZ {
+        char *zone;
+        bool local_rtc;
+        int use_ntp;
+} TZ;
+
+static TZ tz = {
+        .use_ntp = -1,
+};
+
+static usec_t remain_until;
+
+static void free_data(void) {
+        free(tz.zone);
+        tz.zone = NULL;
+
+        tz.local_rtc = false;
+}
+
+static bool valid_timezone(const char *name) {
+        const char *p;
+        char *t;
+        bool slash = false;
+        int r;
+        struct stat st;
+
+        assert(name);
+
+        if (*name == '/' || *name == 0)
+                return false;
+
+        for (p = name; *p; p++) {
+                if (!(*p >= '0' && *p <= '9') &&
+                    !(*p >= 'a' && *p <= 'z') &&
+                    !(*p >= 'A' && *p <= 'Z') &&
+                    !(*p == '-' || *p == '_' || *p == '+' || *p == '/'))
+                        return false;
+
+                if (*p == '/') {
+
+                        if (slash)
+                                return false;
+
+                        slash = true;
+                } else
+                        slash = false;
+        }
+
+        if (slash)
+                return false;
+
+        t = strappend("/usr/share/zoneinfo/", name);
+        if (!t)
+                return false;
+
+        r = stat(t, &st);
+        free(t);
+
+        if (r < 0)
+                return false;
+
+        if (!S_ISREG(st.st_mode))
+                return false;
+
+        return true;
+}
+
+static int read_data(void) {
+        int r;
+        _cleanup_free_ char *t = NULL;
+
+        free_data();
+
+        r = readlink_malloc("/etc/localtime", &t);
+        if (r < 0) {
+                if (r == -EINVAL)
+                        log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/.");
+                else
+                        log_warning("Failed to get target of /etc/localtime: %s", strerror(-r));
+        } else {
+                const char *e;
+
+                e = path_startswith(t, "/usr/share/zoneinfo/");
+                if (!e)
+                        e = path_startswith(t, "../usr/share/zoneinfo/");
+
+                if (!e)
+                        log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/.");
+                else {
+                        tz.zone = strdup(e);
+                        if (!tz.zone)
+                                return log_oom();
+
+                        goto have_timezone;
+                }
+        }
+
+#ifdef HAVE_DEBIAN
+        r = read_one_line_file("/etc/timezone", &tz.zone);
+        if (r < 0) {
+                if (r != -ENOENT)
+                        log_warning("Failed to read /etc/timezone: %s", strerror(-r));
+        }
+#endif
+
+have_timezone:
+        if (isempty(tz.zone)) {
+                free(tz.zone);
+                tz.zone = NULL;
+        }
+
+        tz.local_rtc = hwclock_is_localtime() > 0;
+
+        return 0;
+}
+
+static int write_data_timezone(void) {
+        int r = 0;
+        _cleanup_free_ char *p = NULL;
+
+        if (!tz.zone) {
+                if (unlink("/etc/localtime") < 0 && errno != ENOENT)
+                        r = -errno;
+
+                return r;
+        }
+
+        p = strappend("../usr/share/zoneinfo/", tz.zone);
+        if (!p)
+                return log_oom();
+
+        r = symlink_atomic(p, "/etc/localtime");
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int write_data_local_rtc(void) {
+        int r;
+        char *s, *w;
+
+        r = read_full_file("/etc/adjtime", &s, NULL);
+        if (r < 0) {
+                if (r != -ENOENT)
+                        return r;
+
+                if (!tz.local_rtc)
+                        return 0;
+
+                w = strdup(NULL_ADJTIME_LOCAL);
+                if (!w)
+                        return -ENOMEM;
+        } else {
+                char *p, *e;
+                size_t a, b;
+
+                p = strchr(s, '\n');
+                if (!p) {
+                        free(s);
+                        return -EIO;
+                }
+
+                p = strchr(p+1, '\n');
+                if (!p) {
+                        free(s);
+                        return -EIO;
+                }
+
+                p++;
+                e = strchr(p, '\n');
+                if (!e) {
+                        free(s);
+                        return -EIO;
+                }
+
+                a = p - s;
+                b = strlen(e);
+
+                w = new(char, a + (tz.local_rtc ? 5 : 3) + b + 1);
+                if (!w) {
+                        free(s);
+                        return -ENOMEM;
+                }
+
+                *(char*) mempcpy(stpcpy(mempcpy(w, s, a), tz.local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
+
+                if (streq(w, NULL_ADJTIME_UTC)) {
+                        free(w);
+
+                        if (unlink("/etc/adjtime") < 0) {
+                                if (errno != ENOENT)
+                                        return -errno;
+                        }
+
+                        return 0;
+                }
+        }
+
+        r = write_one_line_file_atomic("/etc/adjtime", w);
+        free(w);
+
+        return r;
+}
+
+static char** get_ntp_services(void) {
+        char **r = NULL, **files, **i;
+        int k;
+
+        k = conf_files_list(&files, ".list",
+                            "/etc/systemd/ntp-units.d",
+                            "/run/systemd/ntp-units.d",
+                            "/usr/local/lib/systemd/ntp-units.d",
+                            "/usr/lib/systemd/ntp-units.d",
+                            NULL);
+        if (k < 0)
+                return NULL;
+
+        STRV_FOREACH(i, files) {
+                FILE *f;
+
+                f = fopen(*i, "re");
+                if (!f)
+                        continue;
+
+                for (;;) {
+                        char line[PATH_MAX], *l, **q;
+
+                        if (!fgets(line, sizeof(line), f)) {
+
+                                if (ferror(f))
+                                        log_error("Failed to read NTP units file: %m");
+
+                                break;
+                        }
+
+                        l = strstrip(line);
+                        if (l[0] == 0 || l[0] == '#')
+                                continue;
+
+                        q = strv_append(r, l);
+                        if (!q) {
+                                log_oom();
+                                break;
+                        }
+
+                        strv_free(r);
+                        r = q;
+                }
+
+                fclose(f);
+        }
+
+        strv_free(files);
+
+        return strv_uniq(r);
+}
+
+static int read_ntp(DBusConnection *bus) {
+        DBusMessage *m = NULL, *reply = NULL;
+        DBusError error;
+        int r;
+        char **i, **l;
+
+        assert(bus);
+
+        dbus_error_init(&error);
+
+        l = get_ntp_services();
+        STRV_FOREACH(i, l) {
+                const char *s;
+
+                if (m)
+                        dbus_message_unref(m);
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "GetUnitFileState");
+                if (!m) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                if (!dbus_message_append_args(m,
+                                              DBUS_TYPE_STRING, i,
+                                              DBUS_TYPE_INVALID)) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                if (reply)
+                        dbus_message_unref(reply);
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+                if (!reply) {
+                        if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
+                                /* This implementation does not exist, try next one */
+                                dbus_error_free(&error);
+                                continue;
+                        }
+
+                        log_error("Failed to issue method call: %s", bus_error_message(&error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                if (!dbus_message_get_args(reply, &error,
+                                           DBUS_TYPE_STRING, &s,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse reply: %s", bus_error_message(&error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                tz.use_ntp =
+                        streq(s, "enabled") ||
+                        streq(s, "enabled-runtime");
+                r = 0;
+                goto finish;
+        }
+
+        /* NTP is not installed. */
+        tz.use_ntp = 0;
+        r = 0;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        strv_free(l);
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int start_ntp(DBusConnection *bus, DBusError *error) {
+        DBusMessage *m = NULL, *reply = NULL;
+        const char *mode = "replace";
+        char **i, **l;
+        int r;
+
+        assert(bus);
+        assert(error);
+
+        l = get_ntp_services();
+        STRV_FOREACH(i, l) {
+                if (m)
+                        dbus_message_unref(m);
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                tz.use_ntp ? "StartUnit" : "StopUnit");
+                if (!m) {
+                        log_error("Could not allocate message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (!dbus_message_append_args(m,
+                                              DBUS_TYPE_STRING, i,
+                                              DBUS_TYPE_STRING, &mode,
+                                              DBUS_TYPE_INVALID)) {
+                        log_error("Could not append arguments to message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (reply)
+                        dbus_message_unref(reply);
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+                if (!reply) {
+                        if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound") ||
+                            streq(error->name, "org.freedesktop.systemd1.LoadFailed") ||
+                            streq(error->name, "org.freedesktop.systemd1.NoSuchUnit")) {
+                                /* This implementation does not exist, try next one */
+                                dbus_error_free(error);
+                                continue;
+                        }
+
+                        log_error("Failed to issue method call: %s", bus_error_message(error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                r = 0;
+                goto finish;
+        }
+
+        /* No implementaiton available... */
+        r = -ENOENT;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        strv_free(l);
+
+        return r;
+}
+
+static int enable_ntp(DBusConnection *bus, DBusError *error) {
+        DBusMessage *m = NULL, *reply = NULL;
+        int r;
+        DBusMessageIter iter;
+        dbus_bool_t f = FALSE, t = TRUE;
+        char **i, **l;
+
+        assert(bus);
+        assert(error);
+
+        l = get_ntp_services();
+        STRV_FOREACH(i, l) {
+                char* k[2];
+
+                if (m)
+                        dbus_message_unref(m);
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
+                if (!m) {
+                        log_error("Could not allocate message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                dbus_message_iter_init_append(m, &iter);
+
+                k[0] = *i;
+                k[1] = NULL;
+
+                r = bus_append_strv_iter(&iter, k);
+                if (r < 0) {
+                        log_error("Failed to append unit files.");
+                        goto finish;
+                }
+
+                /* send runtime bool */
+                if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) {
+                        log_error("Failed to append runtime boolean.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (tz.use_ntp) {
+                        /* send force bool */
+                        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
+                                log_error("Failed to append force boolean.");
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+                }
+
+                if (reply)
+                        dbus_message_unref(reply);
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+                if (!reply) {
+                        if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound")) {
+                                /* This implementation does not exist, try next one */
+                                dbus_error_free(error);
+                                continue;
+                        }
+
+                        log_error("Failed to issue method call: %s", bus_error_message(error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_unref(m);
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "Reload");
+                if (!m) {
+                        log_error("Could not allocate message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                dbus_message_unref(reply);
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+                if (!reply) {
+                        log_error("Failed to issue method call: %s", bus_error_message(error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                r = 0;
+                goto finish;
+        }
+
+        r = -ENOENT;
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        strv_free(l);
+
+        return r;
+}
+
+static int property_append_ntp(DBusMessageIter *i, const char *property, void *data) {
+        dbus_bool_t db;
+
+        assert(i);
+        assert(property);
+
+        db = tz.use_ntp > 0;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db))
+                return -ENOMEM;
+
+        return 0;
+}
+
+static const BusProperty bus_timedate_properties[] = {
+        { "Timezone", bus_property_append_string, "s", offsetof(TZ, zone),     true },
+        { "LocalRTC", bus_property_append_bool,   "b", offsetof(TZ, local_rtc) },
+        { "NTP",      property_append_ntp,        "b", offsetof(TZ, use_ntp)   },
+        { NULL, }
+};
+
+static const BusBoundProperties bps[] = {
+        { "org.freedesktop.timedate1", bus_timedate_properties, &tz },
+        { NULL, }
+};
+
+static DBusHandlerResult timedate_message_handler(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+        DBusMessage *reply = NULL, *changed = NULL;
+        DBusError error;
+        int r;
+
+        assert(connection);
+        assert(message);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetTimezone")) {
+                const char *z;
+                dbus_bool_t interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &z,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (!valid_timezone(z))
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                if (!streq_ptr(z, tz.zone)) {
+                        char *t;
+
+                        r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-timezone", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        t = strdup(z);
+                        if (!t)
+                                goto oom;
+
+                        free(tz.zone);
+                        tz.zone = t;
+
+                        /* 1. Write new configuration file */
+                        r = write_data_timezone();
+                        if (r < 0) {
+                                log_error("Failed to set timezone: %s", strerror(-r));
+                                return bus_send_error_reply(connection, message, NULL, r);
+                        }
+
+                        /* 2. Tell the kernel our time zone */
+                        hwclock_set_timezone(NULL);
+
+                        if (tz.local_rtc) {
+                                struct timespec ts;
+                                struct tm *tm;
+
+                                /* 3. Sync RTC from system clock, with the new delta */
+                                assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
+                                assert_se(tm = localtime(&ts.tv_sec));
+                                hwclock_set_time(tm);
+                        }
+
+                        log_struct(LOG_INFO,
+                                   MESSAGE_ID(SD_MESSAGE_TIMEZONE_CHANGE),
+                                   "TIMEZONE=%s", tz.zone,
+                                   "MESSAGE=Changed timezone to '%s'.", tz.zone,
+                                   NULL);
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/timedate1",
+                                        "org.freedesktop.timedate1",
+                                        "Timezone\0");
+                        if (!changed)
+                                goto oom;
+                }
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetLocalRTC")) {
+                dbus_bool_t lrtc;
+                dbus_bool_t fix_system;
+                dbus_bool_t interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_BOOLEAN, &lrtc,
+                                    DBUS_TYPE_BOOLEAN, &fix_system,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (lrtc != tz.local_rtc) {
+                        struct timespec ts;
+
+                        r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-local-rtc", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        tz.local_rtc = lrtc;
+
+                        /* 1. Write new configuration file */
+                        r = write_data_local_rtc();
+                        if (r < 0) {
+                                log_error("Failed to set RTC to local/UTC: %s", strerror(-r));
+                                return bus_send_error_reply(connection, message, NULL, r);
+                        }
+
+                        /* 2. Tell the kernel our time zone */
+                        hwclock_set_timezone(NULL);
+
+                        /* 3. Synchronize clocks */
+                        assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
+
+                        if (fix_system) {
+                                struct tm tm;
+
+                                /* Sync system clock from RTC; first,
+                                 * initialize the timezone fields of
+                                 * struct tm. */
+                                if (tz.local_rtc)
+                                        tm = *localtime(&ts.tv_sec);
+                                else
+                                        tm = *gmtime(&ts.tv_sec);
+
+                                /* Override the main fields of
+                                 * struct tm, but not the timezone
+                                 * fields */
+                                if (hwclock_get_time(&tm) >= 0) {
+
+                                        /* And set the system clock
+                                         * with this */
+                                        if (tz.local_rtc)
+                                                ts.tv_sec = mktime(&tm);
+                                        else
+                                                ts.tv_sec = timegm(&tm);
+
+                                        clock_settime(CLOCK_REALTIME, &ts);
+                                }
+
+                        } else {
+                                struct tm *tm;
+
+                                /* Sync RTC from system clock */
+                                if (tz.local_rtc)
+                                        tm = localtime(&ts.tv_sec);
+                                else
+                                        tm = gmtime(&ts.tv_sec);
+
+                                hwclock_set_time(tm);
+                        }
+
+                        log_info("RTC configured to %s time.", tz.local_rtc ? "local" : "UTC");
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/timedate1",
+                                        "org.freedesktop.timedate1",
+                                        "LocalRTC\0");
+                        if (!changed)
+                                goto oom;
+                }
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetTime")) {
+                int64_t utc;
+                dbus_bool_t relative;
+                dbus_bool_t interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_INT64, &utc,
+                                    DBUS_TYPE_BOOLEAN, &relative,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (!relative && utc <= 0)
+                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+                if (!relative || utc != 0) {
+                        struct timespec ts;
+                        struct tm* tm;
+
+                        r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-time", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        if (relative)
+                                timespec_store(&ts, now(CLOCK_REALTIME) + utc);
+                        else
+                                timespec_store(&ts, utc);
+
+                        /* Set system clock */
+                        if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
+                                log_error("Failed to set local time: %m");
+                                return bus_send_error_reply(connection, message, NULL, -errno);
+                        }
+
+                        /* Sync down to RTC */
+                        if (tz.local_rtc)
+                                tm = localtime(&ts.tv_sec);
+                        else
+                                tm = gmtime(&ts.tv_sec);
+
+                        hwclock_set_time(tm);
+
+                        log_struct(LOG_INFO,
+                                   MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
+                                   "REALTIME=%llu", (unsigned long long) timespec_load(&ts),
+                                   "MESSAGE=Changed local time to %s", ctime(&ts.tv_sec),
+                                   NULL);
+                }
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetNTP")) {
+                dbus_bool_t ntp;
+                dbus_bool_t interactive;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_BOOLEAN, &ntp,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                if (ntp != !!tz.use_ntp) {
+
+                        r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-ntp", interactive, NULL, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        tz.use_ntp = !!ntp;
+
+                        r = enable_ntp(connection, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        r = start_ntp(connection, &error);
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+
+                        log_info("Set NTP to %s", tz.use_ntp ? "enabled" : "disabled");
+
+                        changed = bus_properties_changed_new(
+                                        "/org/freedesktop/timedate1",
+                                        "org.freedesktop.timedate1",
+                                        "NTP\0");
+                        if (!changed)
+                                goto oom;
+                }
+
+        } else
+                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
+
+        if (!(reply = dbus_message_new_method_return(message)))
+                goto oom;
+
+        if (!dbus_connection_send(connection, reply, NULL))
+                goto oom;
+
+        dbus_message_unref(reply);
+        reply = NULL;
+
+        if (changed) {
+
+                if (!dbus_connection_send(connection, changed, NULL))
+                        goto oom;
+
+                dbus_message_unref(changed);
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        if (changed)
+                dbus_message_unref(changed);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+}
+
+static int connect_bus(DBusConnection **_bus) {
+        static const DBusObjectPathVTable timedate_vtable = {
+                .message_function = timedate_message_handler
+        };
+        DBusError error;
+        DBusConnection *bus = NULL;
+        int r;
+
+        assert(_bus);
+
+        dbus_error_init(&error);
+
+        bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+        if (!bus) {
+                log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
+                r = -ECONNREFUSED;
+                goto fail2;
+        }
+
+        dbus_connection_set_exit_on_disconnect(bus, FALSE);
+
+        if (!dbus_connection_register_object_path(bus, "/org/freedesktop/timedate1", &timedate_vtable, NULL) ||
+            !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) {
+                r = log_oom();
+                goto fail;
+        }
+
+        r = dbus_bus_request_name(bus, "org.freedesktop.timedate1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to register name on bus: %s", bus_error_message(&error));
+                r = -EEXIST;
+                goto fail;
+        }
+
+        if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
+                log_error("Failed to acquire name.");
+                r = -EEXIST;
+                goto fail;
+        }
+
+        if (_bus)
+                *_bus = bus;
+
+        return 0;
+
+fail:
+        dbus_connection_close(bus);
+        dbus_connection_unref(bus);
+fail2:
+        dbus_error_free(&error);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+        DBusConnection *bus = NULL;
+        bool exiting = false;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argc == 2 && streq(argv[1], "--introspect")) {
+                fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+                      "<node>\n", stdout);
+                fputs(timedate_interface, stdout);
+                fputs("</node>\n", stdout);
+                return 0;
+        }
+
+        if (argc != 1) {
+                log_error("This program takes no arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        r = read_data();
+        if (r < 0) {
+                log_error("Failed to read timezone data: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = connect_bus(&bus);
+        if (r < 0)
+                goto finish;
+
+        r = read_ntp(bus);
+        if (r < 0) {
+                log_error("Failed to determine whether NTP is enabled: %s", strerror(-r));
+                goto finish;
+        }
+
+        remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
+        for (;;) {
+
+                if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
+                        break;
+
+                if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
+                        exiting = true;
+                        bus_async_unregister_and_exit(bus, "org.freedesktop.timedated1");
+                }
+        }
+
+        r = 0;
+
+finish:
+        free_data();
+
+        if (bus) {
+                dbus_connection_flush(bus);
+                dbus_connection_close(bus);
+                dbus_connection_unref(bus);
+        }
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/timestamp/Makefile b/src/timestamp/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/timestamp/timestamp.c b/src/timestamp/timestamp.c
new file mode 100644 (file)
index 0000000..1152f1b
--- /dev/null
@@ -0,0 +1,39 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+
+#include "util.h"
+
+int main(int argc, char *argv[]) {
+        struct dual_timestamp t;
+
+        /* This is mostly useful for stuff like init ram disk scripts
+         * which want to take a proper timestamp to do minimal bootup
+         * profiling. */
+
+        dual_timestamp_get(&t);
+        printf("%llu %llu\n",
+               (unsigned long long) t.realtime,
+               (unsigned long long) t.monotonic);
+
+        return 0;
+}
diff --git a/src/tmpfiles/Makefile b/src/tmpfiles/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
new file mode 100644 (file)
index 0000000..d8fb07e
--- /dev/null
@@ -0,0 +1,1420 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering, Kay Sievers
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <dirent.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <glob.h>
+#include <fnmatch.h>
+#include <sys/capability.h>
+
+#include "log.h"
+#include "util.h"
+#include "macro.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "strv.h"
+#include "label.h"
+#include "set.h"
+#include "conf-files.h"
+#include "capability.h"
+
+/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
+ * them in the file system. This is intended to be used to create
+ * properly owned directories beneath /tmp, /var/tmp, /run, which are
+ * volatile and hence need to be recreated on bootup. */
+
+typedef enum ItemType {
+        /* These ones take file names */
+        CREATE_FILE = 'f',
+        TRUNCATE_FILE = 'F',
+        WRITE_FILE = 'w',
+        CREATE_DIRECTORY = 'd',
+        TRUNCATE_DIRECTORY = 'D',
+        CREATE_FIFO = 'p',
+        CREATE_SYMLINK = 'L',
+        CREATE_CHAR_DEVICE = 'c',
+        CREATE_BLOCK_DEVICE = 'b',
+
+        /* These ones take globs */
+        IGNORE_PATH = 'x',
+        REMOVE_PATH = 'r',
+        RECURSIVE_REMOVE_PATH = 'R',
+        RELABEL_PATH = 'z',
+        RECURSIVE_RELABEL_PATH = 'Z'
+} ItemType;
+
+typedef struct Item {
+        ItemType type;
+
+        char *path;
+        char *argument;
+        uid_t uid;
+        gid_t gid;
+        mode_t mode;
+        usec_t age;
+
+        dev_t major_minor;
+
+        bool uid_set:1;
+        bool gid_set:1;
+        bool mode_set:1;
+        bool age_set:1;
+
+        bool keep_first_level:1;
+} Item;
+
+static Hashmap *items = NULL, *globs = NULL;
+static Set *unix_sockets = NULL;
+
+static bool arg_create = false;
+static bool arg_clean = false;
+static bool arg_remove = false;
+
+static const char *arg_prefix = NULL;
+
+static const char * const conf_file_dirs[] = {
+        "/etc/tmpfiles.d",
+        "/run/tmpfiles.d",
+        "/usr/local/lib/tmpfiles.d",
+        "/usr/lib/tmpfiles.d",
+#ifdef HAVE_SPLIT_USR
+        "/lib/tmpfiles.d",
+#endif
+        NULL
+};
+
+#define MAX_DEPTH 256
+
+static bool needs_glob(ItemType t) {
+        return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RELABEL_PATH || t == RECURSIVE_RELABEL_PATH;
+}
+
+static struct Item* find_glob(Hashmap *h, const char *match) {
+        Item *j;
+        Iterator i;
+
+        HASHMAP_FOREACH(j, h, i)
+                if (fnmatch(j->path, match, FNM_PATHNAME|FNM_PERIOD) == 0)
+                        return j;
+
+        return NULL;
+}
+
+static void load_unix_sockets(void) {
+        FILE *f = NULL;
+        char line[LINE_MAX];
+
+        if (unix_sockets)
+                return;
+
+        /* We maintain a cache of the sockets we found in
+         * /proc/net/unix to speed things up a little. */
+
+        unix_sockets = set_new(string_hash_func, string_compare_func);
+        if (!unix_sockets)
+                return;
+
+        f = fopen("/proc/net/unix", "re");
+        if (!f)
+                return;
+
+        /* Skip header */
+        if (!fgets(line, sizeof(line), f))
+                goto fail;
+
+        for (;;) {
+                char *p, *s;
+                int k;
+
+                if (!fgets(line, sizeof(line), f))
+                        break;
+
+                truncate_nl(line);
+
+                p = strchr(line, ':');
+                if (!p)
+                        continue;
+
+                if (strlen(p) < 37)
+                        continue;
+
+                p += 37;
+                p += strspn(p, WHITESPACE);
+                p += strcspn(p, WHITESPACE); /* skip one more word */
+                p += strspn(p, WHITESPACE);
+
+                if (*p != '/')
+                        continue;
+
+                s = strdup(p);
+                if (!s)
+                        goto fail;
+
+                path_kill_slashes(s);
+
+                k = set_put(unix_sockets, s);
+                if (k < 0) {
+                        free(s);
+
+                        if (k != -EEXIST)
+                                goto fail;
+                }
+        }
+
+        fclose(f);
+        return;
+
+fail:
+        set_free_free(unix_sockets);
+        unix_sockets = NULL;
+
+        if (f)
+                fclose(f);
+}
+
+static bool unix_socket_alive(const char *fn) {
+        assert(fn);
+
+        load_unix_sockets();
+
+        if (unix_sockets)
+                return !!set_get(unix_sockets, (char*) fn);
+
+        /* We don't know, so assume yes */
+        return true;
+}
+
+static int dir_cleanup(
+                const char *p,
+                DIR *d,
+                const struct stat *ds,
+                usec_t cutoff,
+                dev_t rootdev,
+                bool mountpoint,
+                int maxdepth,
+                bool keep_this_level)
+{
+        struct dirent *dent;
+        struct timespec times[2];
+        bool deleted = false;
+        char *sub_path = NULL;
+        int r = 0;
+
+        while ((dent = readdir(d))) {
+                struct stat s;
+                usec_t age;
+
+                if (streq(dent->d_name, ".") ||
+                    streq(dent->d_name, ".."))
+                        continue;
+
+                if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) {
+
+                        if (errno != ENOENT) {
+                                log_error("stat(%s/%s) failed: %m", p, dent->d_name);
+                                r = -errno;
+                        }
+
+                        continue;
+                }
+
+                /* Stay on the same filesystem */
+                if (s.st_dev != rootdev)
+                        continue;
+
+                /* Do not delete read-only files owned by root */
+                if (s.st_uid == 0 && !(s.st_mode & S_IWUSR))
+                        continue;
+
+                free(sub_path);
+                sub_path = NULL;
+
+                if (asprintf(&sub_path, "%s/%s", p, dent->d_name) < 0) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                /* Is there an item configured for this path? */
+                if (hashmap_get(items, sub_path))
+                        continue;
+
+                if (find_glob(globs, sub_path))
+                        continue;
+
+                if (S_ISDIR(s.st_mode)) {
+
+                        if (mountpoint &&
+                            streq(dent->d_name, "lost+found") &&
+                            s.st_uid == 0)
+                                continue;
+
+                        if (maxdepth <= 0)
+                                log_warning("Reached max depth on %s.", sub_path);
+                        else {
+                                DIR *sub_dir;
+                                int q;
+
+                                sub_dir = xopendirat(dirfd(d), dent->d_name, O_NOFOLLOW|O_NOATIME);
+                                if (sub_dir == NULL) {
+                                        if (errno != ENOENT) {
+                                                log_error("opendir(%s/%s) failed: %m", p, dent->d_name);
+                                                r = -errno;
+                                        }
+
+                                        continue;
+                                }
+
+                                q = dir_cleanup(sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false);
+                                closedir(sub_dir);
+
+                                if (q < 0)
+                                        r = q;
+                        }
+
+                        /* Note: if you are wondering why we don't
+                         * support the sticky bit for excluding
+                         * directories from cleaning like we do it for
+                         * other file system objects: well, the sticky
+                         * bit already has a meaning for directories,
+                         * so we don't want to overload that. */
+
+                        if (keep_this_level)
+                                continue;
+
+                        /* Ignore ctime, we change it when deleting */
+                        age = MAX(timespec_load(&s.st_mtim),
+                                  timespec_load(&s.st_atim));
+                        if (age >= cutoff)
+                                continue;
+
+                        log_debug("rmdir '%s'\n", sub_path);
+
+                        if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) {
+                                if (errno != ENOENT && errno != ENOTEMPTY) {
+                                        log_error("rmdir(%s): %m", sub_path);
+                                        r = -errno;
+                                }
+                        }
+
+                } else {
+                        /* Skip files for which the sticky bit is
+                         * set. These are semantics we define, and are
+                         * unknown elsewhere. See XDG_RUNTIME_DIR
+                         * specification for details. */
+                        if (s.st_mode & S_ISVTX)
+                                continue;
+
+                        if (mountpoint && S_ISREG(s.st_mode)) {
+                                if (streq(dent->d_name, ".journal") &&
+                                    s.st_uid == 0)
+                                        continue;
+
+                                if (streq(dent->d_name, "aquota.user") ||
+                                    streq(dent->d_name, "aquota.group"))
+                                        continue;
+                        }
+
+                        /* Ignore sockets that are listed in /proc/net/unix */
+                        if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path))
+                                continue;
+
+                        /* Ignore device nodes */
+                        if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))
+                                continue;
+
+                        /* Keep files on this level around if this is
+                         * requested */
+                        if (keep_this_level)
+                                continue;
+
+                        age = MAX3(timespec_load(&s.st_mtim),
+                                   timespec_load(&s.st_atim),
+                                   timespec_load(&s.st_ctim));
+
+                        if (age >= cutoff)
+                                continue;
+
+                        log_debug("unlink '%s'\n", sub_path);
+
+                        if (unlinkat(dirfd(d), dent->d_name, 0) < 0) {
+                                if (errno != ENOENT) {
+                                        log_error("unlink(%s): %m", sub_path);
+                                        r = -errno;
+                                }
+                        }
+
+                        deleted = true;
+                }
+        }
+
+finish:
+        if (deleted) {
+                /* Restore original directory timestamps */
+                times[0] = ds->st_atim;
+                times[1] = ds->st_mtim;
+
+                if (futimens(dirfd(d), times) < 0)
+                        log_error("utimensat(%s): %m", p);
+        }
+
+        free(sub_path);
+
+        return r;
+}
+
+static int clean_item(Item *i) {
+        DIR *d;
+        struct stat s, ps;
+        bool mountpoint;
+        int r;
+        usec_t cutoff, n;
+
+        assert(i);
+
+        if (i->type != CREATE_DIRECTORY &&
+            i->type != TRUNCATE_DIRECTORY &&
+            i->type != IGNORE_PATH)
+                return 0;
+
+        if (!i->age_set)
+                return 0;
+
+        n = now(CLOCK_REALTIME);
+        if (n < i->age)
+                return 0;
+
+        cutoff = n - i->age;
+
+        d = opendir(i->path);
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open directory %s: %m", i->path);
+                return -errno;
+        }
+
+        if (fstat(dirfd(d), &s) < 0) {
+                log_error("stat(%s) failed: %m", i->path);
+                r = -errno;
+                goto finish;
+        }
+
+        if (!S_ISDIR(s.st_mode)) {
+                log_error("%s is not a directory.", i->path);
+                r = -ENOTDIR;
+                goto finish;
+        }
+
+        if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) {
+                log_error("stat(%s/..) failed: %m", i->path);
+                r = -errno;
+                goto finish;
+        }
+
+        mountpoint = s.st_dev != ps.st_dev ||
+                     (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino);
+
+        r = dir_cleanup(i->path, d, &s, cutoff, s.st_dev, mountpoint, MAX_DEPTH, i->keep_first_level);
+
+finish:
+        if (d)
+                closedir(d);
+
+        return r;
+}
+
+static int item_set_perms(Item *i, const char *path) {
+        /* not using i->path directly because it may be a glob */
+        if (i->mode_set)
+                if (chmod(path, i->mode) < 0) {
+                        log_error("chmod(%s) failed: %m", path);
+                        return -errno;
+                }
+
+        if (i->uid_set || i->gid_set)
+                if (chown(path,
+                          i->uid_set ? i->uid : (uid_t) -1,
+                          i->gid_set ? i->gid : (gid_t) -1) < 0) {
+
+                        log_error("chown(%s) failed: %m", path);
+                        return -errno;
+                }
+
+        return label_fix(path, false, false);
+}
+
+static int write_one_file(Item *i, const char *path) {
+        int r, e, fd, flags;
+        struct stat st;
+        mode_t u;
+
+        flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
+                i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
+
+        u = umask(0);
+        label_context_set(path, S_IFREG);
+        fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
+        e = errno;
+        label_context_clear();
+        umask(u);
+        errno = e;
+
+        if (fd < 0) {
+                if (i->type == WRITE_FILE && errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to create file %s: %m", path);
+                return -errno;
+        }
+
+        if (i->argument) {
+                ssize_t n;
+                size_t l;
+                _cleanup_free_ char *unescaped;
+
+                unescaped = cunescape(i->argument);
+                if (unescaped == NULL) {
+                        close_nointr_nofail(fd);
+                        return log_oom();
+                }
+
+                l = strlen(unescaped);
+                n = write(fd, unescaped, l);
+
+                if (n < 0 || (size_t) n < l) {
+                        log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
+                        close_nointr_nofail(fd);
+                        return n < 0 ? n : -EIO;
+                }
+        }
+
+        close_nointr_nofail(fd);
+
+        if (stat(path, &st) < 0) {
+                log_error("stat(%s) failed: %m", path);
+                return -errno;
+        }
+
+        if (!S_ISREG(st.st_mode)) {
+                log_error("%s is not a file.", path);
+                return -EEXIST;
+        }
+
+        r = item_set_perms(i, path);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int recursive_relabel_children(Item *i, const char *path) {
+        DIR *d;
+        int ret = 0;
+
+        /* This returns the first error we run into, but nevertheless
+         * tries to go on */
+
+        d = opendir(path);
+        if (!d)
+                return errno == ENOENT ? 0 : -errno;
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                bool is_dir;
+                int r;
+                char *entry_path;
+
+                r = readdir_r(d, &buf.de, &de);
+                if (r != 0) {
+                        if (ret == 0)
+                                ret = -r;
+                        break;
+                }
+
+                if (!de)
+                        break;
+
+                if (streq(de->d_name, ".") || streq(de->d_name, ".."))
+                        continue;
+
+                if (asprintf(&entry_path, "%s/%s", path, de->d_name) < 0) {
+                        if (ret == 0)
+                                ret = -ENOMEM;
+                        continue;
+                }
+
+                if (de->d_type == DT_UNKNOWN) {
+                        struct stat st;
+
+                        if (lstat(entry_path, &st) < 0) {
+                                if (ret == 0 && errno != ENOENT)
+                                        ret = -errno;
+                                free(entry_path);
+                                continue;
+                        }
+
+                        is_dir = S_ISDIR(st.st_mode);
+
+                } else
+                        is_dir = de->d_type == DT_DIR;
+
+                r = item_set_perms(i, entry_path);
+                if (r < 0) {
+                        if (ret == 0 && r != -ENOENT)
+                                ret = r;
+                        free(entry_path);
+                        continue;
+                }
+
+                if (is_dir) {
+                        r = recursive_relabel_children(i, entry_path);
+                        if (r < 0 && ret == 0)
+                                ret = r;
+                }
+
+                free(entry_path);
+        }
+
+        closedir(d);
+
+        return ret;
+}
+
+static int recursive_relabel(Item *i, const char *path) {
+        int r;
+        struct stat st;
+
+        r = item_set_perms(i, path);
+        if (r < 0)
+                return r;
+
+        if (lstat(path, &st) < 0)
+                return -errno;
+
+        if (S_ISDIR(st.st_mode))
+                r = recursive_relabel_children(i, path);
+
+        return r;
+}
+
+static int glob_item(Item *i, int (*action)(Item *, const char *)) {
+        int r = 0, k;
+        glob_t g;
+        char **fn;
+
+        zero(g);
+
+        errno = 0;
+        if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) {
+
+                if (k != GLOB_NOMATCH) {
+                        if (errno != 0)
+                                errno = EIO;
+
+                        log_error("glob(%s) failed: %m", i->path);
+                        return -errno;
+                }
+        }
+
+        STRV_FOREACH(fn, g.gl_pathv)
+                if ((k = action(i, *fn)) < 0)
+                        r = k;
+
+        globfree(&g);
+        return r;
+}
+
+static int create_item(Item *i) {
+        int r, e;
+        mode_t u;
+        struct stat st;
+
+        assert(i);
+
+        switch (i->type) {
+
+        case IGNORE_PATH:
+        case REMOVE_PATH:
+        case RECURSIVE_REMOVE_PATH:
+                return 0;
+
+        case CREATE_FILE:
+        case TRUNCATE_FILE:
+                r = write_one_file(i, i->path);
+                if (r < 0)
+                        return r;
+                break;
+        case WRITE_FILE:
+                r = glob_item(i, write_one_file);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case TRUNCATE_DIRECTORY:
+        case CREATE_DIRECTORY:
+
+                u = umask(0);
+                mkdir_parents_label(i->path, 0755);
+                r = mkdir(i->path, i->mode);
+                umask(u);
+
+                if (r < 0 && errno != EEXIST) {
+                        log_error("Failed to create directory %s: %m", i->path);
+                        return -errno;
+                }
+
+                if (stat(i->path, &st) < 0) {
+                        log_error("stat(%s) failed: %m", i->path);
+                        return -errno;
+                }
+
+                if (!S_ISDIR(st.st_mode)) {
+                        log_error("%s is not a directory.", i->path);
+                        return -EEXIST;
+                }
+
+                r = item_set_perms(i, i->path);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case CREATE_FIFO:
+
+                u = umask(0);
+                r = mkfifo(i->path, i->mode);
+                umask(u);
+
+                if (r < 0 && errno != EEXIST) {
+                        log_error("Failed to create fifo %s: %m", i->path);
+                        return -errno;
+                }
+
+                if (stat(i->path, &st) < 0) {
+                        log_error("stat(%s) failed: %m", i->path);
+                        return -errno;
+                }
+
+                if (!S_ISFIFO(st.st_mode)) {
+                        log_error("%s is not a fifo.", i->path);
+                        return -EEXIST;
+                }
+
+                r = item_set_perms(i, i->path);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case CREATE_SYMLINK: {
+                char *x;
+
+                label_context_set(i->path, S_IFLNK);
+                r = symlink(i->argument, i->path);
+                e = errno;
+                label_context_clear();
+                errno = e;
+
+                if (r < 0 && errno != EEXIST) {
+                        log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
+                        return -errno;
+                }
+
+                r = readlink_malloc(i->path, &x);
+                if (r < 0) {
+                        log_error("readlink(%s) failed: %s", i->path, strerror(-r));
+                        return -errno;
+                }
+
+                if (!streq(i->argument, x)) {
+                        free(x);
+                        log_error("%s is not the right symlinks.", i->path);
+                        return -EEXIST;
+                }
+
+                free(x);
+                break;
+        }
+
+        case CREATE_BLOCK_DEVICE:
+        case CREATE_CHAR_DEVICE: {
+                mode_t file_type;
+
+                if (have_effective_cap(CAP_MKNOD) == 0) {
+                        /* In a container we lack CAP_MKNOD. We
+                        shouldnt attempt to create the device node in
+                        that case to avoid noise, and we don't support
+                        virtualized devices in containers anyway. */
+
+                        log_debug("We lack CAP_MKNOD, skipping creation of device node %s.", i->path);
+                        return 0;
+                }
+
+                file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR);
+
+                u = umask(0);
+                label_context_set(i->path, file_type);
+                r = mknod(i->path, i->mode | file_type, i->major_minor);
+                e = errno;
+                label_context_clear();
+                umask(u);
+                errno = e;
+
+                if (r < 0 && errno != EEXIST) {
+                        log_error("Failed to create device node %s: %m", i->path);
+                        return -errno;
+                }
+
+                if (stat(i->path, &st) < 0) {
+                        log_error("stat(%s) failed: %m", i->path);
+                        return -errno;
+                }
+
+                if ((st.st_mode & S_IFMT) != file_type) {
+                        log_error("%s is not a device node.", i->path);
+                        return -EEXIST;
+                }
+
+                r = item_set_perms(i, i->path);
+                if (r < 0)
+                        return r;
+
+                break;
+        }
+
+        case RELABEL_PATH:
+
+                r = glob_item(i, item_set_perms);
+                if (r < 0)
+                        return 0;
+                break;
+
+        case RECURSIVE_RELABEL_PATH:
+
+                r = glob_item(i, recursive_relabel);
+                if (r < 0)
+                        return r;
+        }
+
+        log_debug("%s created successfully.", i->path);
+
+        return 0;
+}
+
+static int remove_item_instance(Item *i, const char *instance) {
+        int r;
+
+        assert(i);
+
+        switch (i->type) {
+
+        case CREATE_FILE:
+        case TRUNCATE_FILE:
+        case CREATE_DIRECTORY:
+        case CREATE_FIFO:
+        case CREATE_SYMLINK:
+        case CREATE_BLOCK_DEVICE:
+        case CREATE_CHAR_DEVICE:
+        case IGNORE_PATH:
+        case RELABEL_PATH:
+        case RECURSIVE_RELABEL_PATH:
+        case WRITE_FILE:
+                break;
+
+        case REMOVE_PATH:
+                if (remove(instance) < 0 && errno != ENOENT) {
+                        log_error("remove(%s): %m", instance);
+                        return -errno;
+                }
+
+                break;
+
+        case TRUNCATE_DIRECTORY:
+        case RECURSIVE_REMOVE_PATH:
+                /* FIXME: we probably should use dir_cleanup() here
+                 * instead of rm_rf() so that 'x' is honoured. */
+                r = rm_rf_dangerous(instance, false, i->type == RECURSIVE_REMOVE_PATH, false);
+                if (r < 0 && r != -ENOENT) {
+                        log_error("rm_rf(%s): %s", instance, strerror(-r));
+                        return r;
+                }
+
+                break;
+        }
+
+        return 0;
+}
+
+static int remove_item(Item *i) {
+        int r = 0;
+
+        assert(i);
+
+        switch (i->type) {
+
+        case CREATE_FILE:
+        case TRUNCATE_FILE:
+        case CREATE_DIRECTORY:
+        case CREATE_FIFO:
+        case CREATE_SYMLINK:
+        case CREATE_CHAR_DEVICE:
+        case CREATE_BLOCK_DEVICE:
+        case IGNORE_PATH:
+        case RELABEL_PATH:
+        case RECURSIVE_RELABEL_PATH:
+        case WRITE_FILE:
+                break;
+
+        case REMOVE_PATH:
+        case TRUNCATE_DIRECTORY:
+        case RECURSIVE_REMOVE_PATH:
+                r = glob_item(i, remove_item_instance);
+                break;
+        }
+
+        return r;
+}
+
+static int process_item(Item *i) {
+        int r, q, p;
+
+        assert(i);
+
+        r = arg_create ? create_item(i) : 0;
+        q = arg_remove ? remove_item(i) : 0;
+        p = arg_clean ? clean_item(i) : 0;
+
+        if (r < 0)
+                return r;
+
+        if (q < 0)
+                return q;
+
+        return p;
+}
+
+static void item_free(Item *i) {
+        assert(i);
+
+        free(i->path);
+        free(i->argument);
+        free(i);
+}
+
+static bool item_equal(Item *a, Item *b) {
+        assert(a);
+        assert(b);
+
+        if (!streq_ptr(a->path, b->path))
+                return false;
+
+        if (a->type != b->type)
+                return false;
+
+        if (a->uid_set != b->uid_set ||
+            (a->uid_set && a->uid != b->uid))
+            return false;
+
+        if (a->gid_set != b->gid_set ||
+            (a->gid_set && a->gid != b->gid))
+            return false;
+
+        if (a->mode_set != b->mode_set ||
+            (a->mode_set && a->mode != b->mode))
+            return false;
+
+        if (a->age_set != b->age_set ||
+            (a->age_set && a->age != b->age))
+            return false;
+
+        if ((a->type == CREATE_FILE ||
+             a->type == TRUNCATE_FILE ||
+             a->type == WRITE_FILE ||
+             a->type == CREATE_SYMLINK) &&
+            !streq_ptr(a->argument, b->argument))
+                return false;
+
+        if ((a->type == CREATE_CHAR_DEVICE ||
+             a->type == CREATE_BLOCK_DEVICE) &&
+            a->major_minor != b->major_minor)
+                return false;
+
+        return true;
+}
+
+static int parse_line(const char *fname, unsigned line, const char *buffer) {
+        Item *i, *existing;
+        char *mode = NULL, *user = NULL, *group = NULL, *age = NULL;
+        char type;
+        Hashmap *h;
+        int r, n = -1;
+
+        assert(fname);
+        assert(line >= 1);
+        assert(buffer);
+
+        i = new0(Item, 1);
+        if (!i)
+                return log_oom();
+
+        if (sscanf(buffer,
+                   "%c "
+                   "%ms "
+                   "%ms "
+                   "%ms "
+                   "%ms "
+                   "%ms "
+                   "%n",
+                   &type,
+                   &i->path,
+                   &mode,
+                   &user,
+                   &group,
+                   &age,
+                   &n) < 2) {
+                log_error("[%s:%u] Syntax error.", fname, line);
+                r = -EIO;
+                goto finish;
+        }
+
+        if (n >= 0)  {
+                n += strspn(buffer+n, WHITESPACE);
+                if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) {
+                        i->argument = unquote(buffer+n, "\"");
+                        if (!i->argument)
+                                return log_oom();
+                }
+        }
+
+        switch(type) {
+
+        case CREATE_FILE:
+        case TRUNCATE_FILE:
+        case CREATE_DIRECTORY:
+        case TRUNCATE_DIRECTORY:
+        case CREATE_FIFO:
+        case IGNORE_PATH:
+        case REMOVE_PATH:
+        case RECURSIVE_REMOVE_PATH:
+        case RELABEL_PATH:
+        case RECURSIVE_RELABEL_PATH:
+                break;
+
+        case CREATE_SYMLINK:
+                if (!i->argument) {
+                        log_error("[%s:%u] Symlink file requires argument.", fname, line);
+                        r = -EBADMSG;
+                        goto finish;
+                }
+                break;
+
+        case WRITE_FILE:
+                if (!i->argument) {
+                        log_error("[%s:%u] Write file requires argument.", fname, line);
+                        r = -EBADMSG;
+                        goto finish;
+                }
+                break;
+
+        case CREATE_CHAR_DEVICE:
+        case CREATE_BLOCK_DEVICE: {
+                unsigned major, minor;
+
+                if (!i->argument) {
+                        log_error("[%s:%u] Device file requires argument.", fname, line);
+                        r = -EBADMSG;
+                        goto finish;
+                }
+
+                if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) {
+                        log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument);
+                        r = -EBADMSG;
+                        goto finish;
+                }
+
+                i->major_minor = makedev(major, minor);
+                break;
+        }
+
+        default:
+                log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        i->type = type;
+
+        if (!path_is_absolute(i->path)) {
+                log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        path_kill_slashes(i->path);
+
+        if (arg_prefix && !path_startswith(i->path, arg_prefix)) {
+                r = 0;
+                goto finish;
+        }
+
+        if (user && !streq(user, "-")) {
+                const char *u = user;
+
+                r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
+                if (r < 0) {
+                        log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
+                        goto finish;
+                }
+
+                i->uid_set = true;
+        }
+
+        if (group && !streq(group, "-")) {
+                const char *g = group;
+
+                r = get_group_creds(&g, &i->gid);
+                if (r < 0) {
+                        log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
+                        goto finish;
+                }
+
+                i->gid_set = true;
+        }
+
+        if (mode && !streq(mode, "-")) {
+                unsigned m;
+
+                if (sscanf(mode, "%o", &m) != 1) {
+                        log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
+                        r = -ENOENT;
+                        goto finish;
+                }
+
+                i->mode = m;
+                i->mode_set = true;
+        } else
+                i->mode =
+                        i->type == CREATE_DIRECTORY ||
+                        i->type == TRUNCATE_DIRECTORY ? 0755 : 0644;
+
+        if (age && !streq(age, "-")) {
+                const char *a = age;
+
+                if (*a == '~') {
+                        i->keep_first_level = true;
+                        a++;
+                }
+
+                if (parse_usec(a, &i->age) < 0) {
+                        log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
+                        r = -EBADMSG;
+                        goto finish;
+                }
+
+                i->age_set = true;
+        }
+
+        h = needs_glob(i->type) ? globs : items;
+
+        existing = hashmap_get(h, i->path);
+        if (existing) {
+
+                /* Two identical items are fine */
+                if (!item_equal(existing, i))
+                        log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
+
+                r = 0;
+                goto finish;
+        }
+
+        r = hashmap_put(h, i->path, i);
+        if (r < 0) {
+                log_error("Failed to insert item %s: %s", i->path, strerror(-r));
+                goto finish;
+        }
+
+        i = NULL;
+        r = 0;
+
+finish:
+        free(user);
+        free(group);
+        free(mode);
+        free(age);
+
+        if (i)
+                item_free(i);
+
+        return r;
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
+               "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
+               "  -h --help             Show this help\n"
+               "     --create           Create marked files/directories\n"
+               "     --clean            Clean up marked directories\n"
+               "     --remove           Remove marked files/directories\n"
+               "     --prefix=PATH      Only apply rules that apply to paths with the specified prefix\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_CREATE,
+                ARG_CLEAN,
+                ARG_REMOVE,
+                ARG_PREFIX
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "create",    no_argument,       NULL, ARG_CREATE    },
+                { "clean",     no_argument,       NULL, ARG_CLEAN     },
+                { "remove",    no_argument,       NULL, ARG_REMOVE    },
+                { "prefix",    required_argument, NULL, ARG_PREFIX    },
+                { NULL,        0,                 NULL, 0             }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_CREATE:
+                        arg_create = true;
+                        break;
+
+                case ARG_CLEAN:
+                        arg_clean = true;
+                        break;
+
+                case ARG_REMOVE:
+                        arg_remove = true;
+                        break;
+
+                case ARG_PREFIX:
+                        arg_prefix = optarg;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (!arg_clean && !arg_create && !arg_remove) {
+                log_error("You need to specify at least one of --clean, --create or --remove.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+static int read_config_file(const char *fn, bool ignore_enoent) {
+        FILE *f;
+        unsigned v = 0;
+        int r = 0;
+
+        assert(fn);
+
+        f = fopen(fn, "re");
+        if (!f) {
+
+                if (ignore_enoent && errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open %s: %m", fn);
+                return -errno;
+        }
+
+        log_debug("apply: %s\n", fn);
+        for (;;) {
+                char line[LINE_MAX], *l;
+                int k;
+
+                if (!(fgets(line, sizeof(line), f)))
+                        break;
+
+                v++;
+
+                l = strstrip(line);
+                if (*l == '#' || *l == 0)
+                        continue;
+
+                if ((k = parse_line(fn, v, l)) < 0)
+                        if (r == 0)
+                                r = k;
+        }
+
+        if (ferror(f)) {
+                log_error("Failed to read from file %s: %m", fn);
+                if (r == 0)
+                        r = -EIO;
+        }
+
+        fclose(f);
+
+        return r;
+}
+
+static char *resolve_fragment(const char *fragment, const char **search_paths) {
+        const char **p;
+        char *resolved_path;
+
+        if (is_path(fragment))
+                return strdup(fragment);
+
+        STRV_FOREACH(p, search_paths) {
+                resolved_path = strjoin(*p, "/", fragment, NULL);
+                if (resolved_path == NULL) {
+                        log_oom();
+                        return NULL;
+                }
+
+                if (access(resolved_path, F_OK) == 0)
+                        return resolved_path;
+
+                free(resolved_path);
+        }
+
+        errno = ENOENT;
+        return NULL;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+        Item *i;
+        Iterator iterator;
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        label_init(NULL);
+
+        items = hashmap_new(string_hash_func, string_compare_func);
+        globs = hashmap_new(string_hash_func, string_compare_func);
+
+        if (!items || !globs) {
+                log_oom();
+                r = EXIT_FAILURE;
+                goto finish;
+        }
+
+        r = EXIT_SUCCESS;
+
+        if (optind < argc) {
+                int j;
+
+                for (j = optind; j < argc; j++) {
+                        char *fragment;
+
+                        fragment = resolve_fragment(argv[j], (const char **)conf_file_dirs);
+                        if (!fragment) {
+                                log_error("Failed to find a %s file: %m", argv[j]);
+                                r = EXIT_FAILURE;
+                                goto finish;
+                        }
+                        if (read_config_file(fragment, false) < 0)
+                                r = EXIT_FAILURE;
+                        free(fragment);
+                }
+
+        } else {
+                char **files, **f;
+
+                r = conf_files_list_strv(&files, ".conf", (const char **)conf_file_dirs);
+                if (r < 0) {
+                        log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r));
+                        r = EXIT_FAILURE;
+                        goto finish;
+                }
+
+                STRV_FOREACH(f, files) {
+                        if (read_config_file(*f, true) < 0)
+                                r = EXIT_FAILURE;
+                }
+
+                strv_free(files);
+        }
+
+        HASHMAP_FOREACH(i, globs, iterator)
+                process_item(i);
+
+        HASHMAP_FOREACH(i, items, iterator)
+                process_item(i);
+
+finish:
+        while ((i = hashmap_steal_first(items)))
+                item_free(i);
+
+        while ((i = hashmap_steal_first(globs)))
+                item_free(i);
+
+        hashmap_free(items);
+        hashmap_free(globs);
+
+        set_free_free(unix_sockets);
+
+        label_finish();
+
+        return r;
+}
diff --git a/src/tty-ask-password-agent/Makefile b/src/tty-ask-password-agent/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
new file mode 100644 (file)
index 0000000..99a626c
--- /dev/null
@@ -0,0 +1,763 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stddef.h>
+#include <sys/poll.h>
+#include <sys/inotify.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/signalfd.h>
+#include <fcntl.h>
+
+#include "util.h"
+#include "mkdir.h"
+#include "path-util.h"
+#include "conf-parser.h"
+#include "utmp-wtmp.h"
+#include "socket-util.h"
+#include "ask-password-api.h"
+#include "strv.h"
+#include "build.h"
+
+static enum {
+        ACTION_LIST,
+        ACTION_QUERY,
+        ACTION_WATCH,
+        ACTION_WALL
+} arg_action = ACTION_QUERY;
+
+static bool arg_plymouth = false;
+static bool arg_console = false;
+
+static int ask_password_plymouth(
+                const char *message,
+                usec_t until,
+                const char *flag_file,
+                bool accept_cached,
+                char ***_passphrases) {
+
+        int fd = -1, notify = -1;
+        union sockaddr_union sa;
+        char *packet = NULL;
+        ssize_t k;
+        int r, n;
+        struct pollfd pollfd[2];
+        char buffer[LINE_MAX];
+        size_t p = 0;
+        enum {
+                POLL_SOCKET,
+                POLL_INOTIFY
+        };
+
+        assert(_passphrases);
+
+        if (flag_file) {
+                if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        zero(sa);
+        sa.sa.sa_family = AF_UNIX;
+        strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
+        if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
+                log_error("Failed to connect to Plymouth: %m");
+                r = -errno;
+                goto finish;
+        }
+
+        if (accept_cached) {
+                packet = strdup("c");
+                n = 1;
+        } else
+                asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n);
+
+        if (!packet) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if ((k = loop_write(fd, packet, n+1, true)) != n+1) {
+                r = k < 0 ? (int) k : -EIO;
+                goto finish;
+        }
+
+        zero(pollfd);
+        pollfd[POLL_SOCKET].fd = fd;
+        pollfd[POLL_SOCKET].events = POLLIN;
+        pollfd[POLL_INOTIFY].fd = notify;
+        pollfd[POLL_INOTIFY].events = POLLIN;
+
+        for (;;) {
+                int sleep_for = -1, j;
+
+                if (until > 0) {
+                        usec_t y;
+
+                        y = now(CLOCK_MONOTONIC);
+
+                        if (y > until) {
+                                r = -ETIME;
+                                goto finish;
+                        }
+
+                        sleep_for = (int) ((until - y) / USEC_PER_MSEC);
+                }
+
+                if (flag_file)
+                        if (access(flag_file, F_OK) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                if ((j = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        r = -errno;
+                        goto finish;
+                } else if (j == 0) {
+                        r = -ETIME;
+                        goto finish;
+                }
+
+                if (notify > 0 && pollfd[POLL_INOTIFY].revents != 0)
+                        flush_fd(notify);
+
+                if (pollfd[POLL_SOCKET].revents == 0)
+                        continue;
+
+                if ((k = read(fd, buffer + p, sizeof(buffer) - p)) <= 0) {
+                        r = k < 0 ? -errno : -EIO;
+                        goto finish;
+                }
+
+                p += k;
+
+                if (p < 1)
+                        continue;
+
+                if (buffer[0] == 5) {
+
+                        if (accept_cached) {
+                                /* Hmm, first try with cached
+                                 * passwords failed, so let's retry
+                                 * with a normal password request */
+                                free(packet);
+                                packet = NULL;
+
+                                if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                if ((k = loop_write(fd, packet, n+1, true)) != n+1) {
+                                        r = k < 0 ? (int) k : -EIO;
+                                        goto finish;
+                                }
+
+                                accept_cached = false;
+                                p = 0;
+                                continue;
+                        }
+
+                        /* No password, because UI not shown */
+                        r = -ENOENT;
+                        goto finish;
+
+                } else if (buffer[0] == 2 || buffer[0] == 9) {
+                        uint32_t size;
+                        char **l;
+
+                        /* One ore more answers */
+                        if (p < 5)
+                                continue;
+
+                        memcpy(&size, buffer+1, sizeof(size));
+                        size = le32toh(size);
+                        if (size+5 > sizeof(buffer)) {
+                                r = -EIO;
+                                goto finish;
+                        }
+
+                        if (p-5 < size)
+                                continue;
+
+                        if (!(l = strv_parse_nulstr(buffer + 5, size))) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        *_passphrases = l;
+                        break;
+
+                } else {
+                        /* Unknown packet */
+                        r = -EIO;
+                        goto finish;
+                }
+        }
+
+        r = 0;
+
+finish:
+        if (notify >= 0)
+                close_nointr_nofail(notify);
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        free(packet);
+
+        return r;
+}
+
+static int parse_password(const char *filename, char **wall) {
+        char *socket_name = NULL, *message = NULL, *packet = NULL;
+        uint64_t not_after = 0;
+        unsigned pid = 0;
+        int socket_fd = -1;
+        bool accept_cached = false;
+
+        const ConfigTableItem items[] = {
+                { "Ask", "Socket",       config_parse_string,   0, &socket_name   },
+                { "Ask", "NotAfter",     config_parse_uint64,   0, &not_after     },
+                { "Ask", "Message",      config_parse_string,   0, &message       },
+                { "Ask", "PID",          config_parse_unsigned, 0, &pid           },
+                { "Ask", "AcceptCached", config_parse_bool,     0, &accept_cached },
+                { NULL, NULL, NULL, 0, NULL }
+        };
+
+        FILE *f;
+        int r;
+
+        assert(filename);
+
+        f = fopen(filename, "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("open(%s): %m", filename);
+                return -errno;
+        }
+
+        r = config_parse(filename, f, NULL, config_item_table_lookup, (void*) items, true, NULL);
+        if (r < 0) {
+                log_error("Failed to parse password file %s: %s", filename, strerror(-r));
+                goto finish;
+        }
+
+        if (!socket_name) {
+                log_error("Invalid password file %s", filename);
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        if (not_after > 0) {
+                if (now(CLOCK_MONOTONIC) > not_after) {
+                        r = 0;
+                        goto finish;
+                }
+        }
+
+        if (pid > 0 &&
+            kill(pid, 0) < 0 &&
+            errno == ESRCH) {
+                r = 0;
+                goto finish;
+        }
+
+        if (arg_action == ACTION_LIST)
+                printf("'%s' (PID %u)\n", message, pid);
+        else if (arg_action == ACTION_WALL) {
+                char *_wall;
+
+                if (asprintf(&_wall,
+                             "%s%sPassword entry required for \'%s\' (PID %u).\r\n"
+                             "Please enter password with the systemd-tty-ask-password-agent tool!",
+                             *wall ? *wall : "",
+                             *wall ? "\r\n\r\n" : "",
+                             message,
+                             pid) < 0) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                free(*wall);
+                *wall = _wall;
+        } else {
+                union {
+                        struct sockaddr sa;
+                        struct sockaddr_un un;
+                } sa;
+                size_t packet_length = 0;
+
+                assert(arg_action == ACTION_QUERY ||
+                       arg_action == ACTION_WATCH);
+
+                if (access(socket_name, W_OK) < 0) {
+
+                        if (arg_action == ACTION_QUERY)
+                                log_info("Not querying '%s' (PID %u), lacking privileges.", message, pid);
+
+                        r = 0;
+                        goto finish;
+                }
+
+                if (arg_plymouth) {
+                        char **passwords = NULL;
+
+                        if ((r = ask_password_plymouth(message, not_after, filename, accept_cached, &passwords)) >= 0) {
+                                char **p;
+
+                                packet_length = 1;
+                                STRV_FOREACH(p, passwords)
+                                        packet_length += strlen(*p) + 1;
+
+                                if (!(packet = new(char, packet_length)))
+                                        r = -ENOMEM;
+                                else {
+                                        char *d;
+
+                                        packet[0] = '+';
+                                        d = packet+1;
+
+                                        STRV_FOREACH(p, passwords)
+                                                d = stpcpy(d, *p) + 1;
+                                }
+                        }
+
+                } else {
+                        int tty_fd = -1;
+                        char *password;
+
+                        if (arg_console)
+                                if ((tty_fd = acquire_terminal("/dev/console", false, false, false, (usec_t) -1)) < 0) {
+                                        r = tty_fd;
+                                        goto finish;
+                                }
+
+                        r = ask_password_tty(message, not_after, filename, &password);
+
+                        if (arg_console) {
+                                close_nointr_nofail(tty_fd);
+                                release_terminal();
+                        }
+
+                        if (r >= 0) {
+                                packet_length = 1+strlen(password)+1;
+                                if (!(packet = new(char, packet_length)))
+                                        r = -ENOMEM;
+                                else {
+                                        packet[0] = '+';
+                                        strcpy(packet+1, password);
+                                }
+
+                                free(password);
+                        }
+                }
+
+                if (r == -ETIME || r == -ENOENT) {
+                        /* If the query went away, that's OK */
+                        r = 0;
+                        goto finish;
+                }
+
+                if (r < 0) {
+                        log_error("Failed to query password: %s", strerror(-r));
+                        goto finish;
+                }
+
+                if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) {
+                        log_error("socket(): %m");
+                        r = -errno;
+                        goto finish;
+                }
+
+                zero(sa);
+                sa.un.sun_family = AF_UNIX;
+                strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
+
+                if (sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) {
+                        log_error("Failed to send: %m");
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+finish:
+        fclose(f);
+
+        if (socket_fd >= 0)
+                close_nointr_nofail(socket_fd);
+
+        free(packet);
+        free(socket_name);
+        free(message);
+
+        return r;
+}
+
+static int wall_tty_block(void) {
+        char *p;
+        int fd, r;
+        dev_t devnr;
+
+        r = get_ctty_devnr(0, &devnr);
+        if (r < 0)
+                return -r;
+
+        if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0)
+                return -ENOMEM;
+
+        mkdir_parents_label(p, 0700);
+        mkfifo(p, 0600);
+
+        fd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        free(p);
+
+        if (fd < 0)
+                return -errno;
+
+        return fd;
+}
+
+static bool wall_tty_match(const char *path) {
+        int fd, k;
+        char *p;
+        struct stat st;
+
+        if (path_is_absolute(path))
+                k = lstat(path, &st);
+        else {
+                if (asprintf(&p, "/dev/%s", path) < 0)
+                        return true;
+
+                k = lstat(p, &st);
+                free(p);
+        }
+
+        if (k < 0)
+                return true;
+
+        if (!S_ISCHR(st.st_mode))
+                return true;
+
+        /* We use named pipes to ensure that wall messages suggesting
+         * password entry are not printed over password prompts
+         * already shown. We use the fact here that opening a pipe in
+         * non-blocking mode for write-only will succeed only if
+         * there's some writer behind it. Using pipes has the
+         * advantage that the block will automatically go away if the
+         * process dies. */
+
+        if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0)
+                return true;
+
+        fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        free(p);
+
+        if (fd < 0)
+                return true;
+
+        /* What, we managed to open the pipe? Then this tty is filtered. */
+        close_nointr_nofail(fd);
+        return false;
+}
+
+static int show_passwords(void) {
+        DIR *d;
+        struct dirent *de;
+        int r = 0;
+
+        if (!(d = opendir("/run/systemd/ask-password"))) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("opendir(): %m");
+                return -errno;
+        }
+
+        while ((de = readdir(d))) {
+                char *p;
+                int q;
+                char *wall;
+
+                /* We only support /dev on tmpfs, hence we can rely on
+                 * d_type to be reliable */
+
+                if (de->d_type != DT_REG)
+                        continue;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                if (!startswith(de->d_name, "ask."))
+                        continue;
+
+                if (!(p = strappend("/run/systemd/ask-password/", de->d_name))) {
+                        r = log_oom();
+                        goto finish;
+                }
+
+                wall = NULL;
+                if ((q = parse_password(p, &wall)) < 0)
+                        r = q;
+
+                free(p);
+
+                if (wall) {
+                        utmp_wall(wall, wall_tty_match);
+                        free(wall);
+                }
+        }
+
+finish:
+        if (d)
+                closedir(d);
+
+        return r;
+}
+
+static int watch_passwords(void) {
+        enum {
+                FD_INOTIFY,
+                FD_SIGNAL,
+                _FD_MAX
+        };
+
+        int notify = -1, signal_fd = -1, tty_block_fd = -1;
+        struct pollfd pollfd[_FD_MAX];
+        sigset_t mask;
+        int r;
+
+        tty_block_fd = wall_tty_block();
+
+        mkdir_p_label("/run/systemd/ask-password", 0755);
+
+        if ((notify = inotify_init1(IN_CLOEXEC)) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+        if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
+                log_error("signalfd(): %m");
+                r = -errno;
+                goto finish;
+        }
+
+        zero(pollfd);
+        pollfd[FD_INOTIFY].fd = notify;
+        pollfd[FD_INOTIFY].events = POLLIN;
+        pollfd[FD_SIGNAL].fd = signal_fd;
+        pollfd[FD_SIGNAL].events = POLLIN;
+
+        for (;;) {
+                if ((r = show_passwords()) < 0)
+                        log_error("Failed to show password: %s", strerror(-r));
+
+                if (poll(pollfd, _FD_MAX, -1) < 0) {
+
+                        if (errno == EINTR)
+                                continue;
+
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (pollfd[FD_INOTIFY].revents != 0)
+                        flush_fd(notify);
+
+                if (pollfd[FD_SIGNAL].revents != 0)
+                        break;
+        }
+
+        r = 0;
+
+finish:
+        if (notify >= 0)
+                close_nointr_nofail(notify);
+
+        if (signal_fd >= 0)
+                close_nointr_nofail(signal_fd);
+
+        if (tty_block_fd >= 0)
+                close_nointr_nofail(tty_block_fd);
+
+        return r;
+}
+
+static int help(void) {
+
+        printf("%s [OPTIONS...]\n\n"
+               "Process system password requests.\n\n"
+               "  -h --help     Show this help\n"
+               "     --version  Show package version\n"
+               "     --list     Show pending password requests\n"
+               "     --query    Process pending password requests\n"
+               "     --watch    Continuously process password requests\n"
+               "     --wall     Continuously forward password requests to wall\n"
+               "     --plymouth Ask question with Plymouth instead of on TTY\n"
+               "     --console  Ask question on /dev/console instead of current TTY\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_LIST = 0x100,
+                ARG_QUERY,
+                ARG_WATCH,
+                ARG_WALL,
+                ARG_PLYMOUTH,
+                ARG_CONSOLE,
+                ARG_VERSION
+        };
+
+        static const struct option options[] = {
+                { "help",     no_argument, NULL, 'h'          },
+                { "version",  no_argument, NULL, ARG_VERSION  },
+                { "list",     no_argument, NULL, ARG_LIST     },
+                { "query",    no_argument, NULL, ARG_QUERY    },
+                { "watch",    no_argument, NULL, ARG_WATCH    },
+                { "wall",     no_argument, NULL, ARG_WALL     },
+                { "plymouth", no_argument, NULL, ARG_PLYMOUTH },
+                { "console",  no_argument, NULL, ARG_CONSOLE  },
+                { NULL,    0,           NULL, 0               }
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_LIST:
+                        arg_action = ACTION_LIST;
+                        break;
+
+                case ARG_QUERY:
+                        arg_action = ACTION_QUERY;
+                        break;
+
+                case ARG_WATCH:
+                        arg_action = ACTION_WATCH;
+                        break;
+
+                case ARG_WALL:
+                        arg_action = ACTION_WALL;
+                        break;
+
+                case ARG_PLYMOUTH:
+                        arg_plymouth = true;
+                        break;
+
+                case ARG_CONSOLE:
+                        arg_console = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+        }
+
+        if (optind != argc) {
+                help();
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if ((r = parse_argv(argc, argv)) <= 0)
+                goto finish;
+
+        if (arg_console) {
+                setsid();
+                release_terminal();
+        }
+
+        if (arg_action == ACTION_WATCH ||
+            arg_action == ACTION_WALL)
+                r = watch_passwords();
+        else
+                r = show_passwords();
+
+        if (r < 0)
+                log_error("Error: %s", strerror(-r));
+
+finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/udev/.gitignore b/src/udev/.gitignore
new file mode 100644 (file)
index 0000000..3e375a7
--- /dev/null
@@ -0,0 +1 @@
+/udev.pc
diff --git a/src/udev/.vimrc b/src/udev/.vimrc
new file mode 100644 (file)
index 0000000..366fbdc
--- /dev/null
@@ -0,0 +1,4 @@
+" 'set exrc' in ~/.vimrc will read .vimrc from the current directory
+set tabstop=8
+set shiftwidth=8
+set expandtab
diff --git a/src/udev/Makefile b/src/udev/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/udev/accelerometer/accelerometer.c b/src/udev/accelerometer/accelerometer.c
new file mode 100644 (file)
index 0000000..21f5193
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * accelerometer - exports device orientation through property
+ *
+ * When an "change" event is received on an accelerometer,
+ * open its device node, and from the value, as well as the previous
+ * value of the property, calculate the device's new orientation,
+ * and export it as ID_INPUT_ACCELEROMETER_ORIENTATION.
+ *
+ * Possible values are:
+ * undefined
+ * * normal
+ * * bottom-up
+ * * left-up
+ * * right-up
+ *
+ * The property will be persistent across sessions, and the new
+ * orientations can be deducted from the previous one (it allows
+ * for a threshold for switching between opposite ends of the
+ * orientation).
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Author:
+ *   Bastien Nocera <hadess@hadess.net>
+ *
+ * orientation_calc() from the sensorfw package
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Authors:
+ *   Üstün Ergenoglu <ext-ustun.ergenoglu@nokia.com>
+ *   Timo Rongas <ext-timo.2.rongas@nokia.com>
+ *   Lihan Guo <lihan.guo@digia.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <limits.h>
+#include <linux/limits.h>
+#include <linux/input.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+/* we must use this kernel-compatible implementation */
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define OFF(x)  ((x)%BITS_PER_LONG)
+#define BIT(x)  (1UL<<OFF(x))
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
+
+static int debug = 0;
+
+static void log_fn(struct udev *udev, int priority,
+                   const char *file, int line, const char *fn,
+                   const char *format, va_list args)
+{
+        if (debug) {
+                fprintf(stderr, "%s: ", fn);
+                vfprintf(stderr, format, args);
+        } else {
+                vsyslog(priority, format, args);
+        }
+}
+
+typedef enum {
+        ORIENTATION_UNDEFINED,
+        ORIENTATION_NORMAL,
+        ORIENTATION_BOTTOM_UP,
+        ORIENTATION_LEFT_UP,
+        ORIENTATION_RIGHT_UP
+} OrientationUp;
+
+static const char *orientations[] = {
+        "undefined",
+        "normal",
+        "bottom-up",
+        "left-up",
+        "right-up",
+        NULL
+};
+
+#define ORIENTATION_UP_UP ORIENTATION_NORMAL
+
+#define DEFAULT_THRESHOLD 250
+#define RADIANS_TO_DEGREES 180.0/M_PI
+#define SAME_AXIS_LIMIT 5
+
+#define THRESHOLD_LANDSCAPE  25
+#define THRESHOLD_PORTRAIT  20
+
+static const char *
+orientation_to_string (OrientationUp o)
+{
+        return orientations[o];
+}
+
+static OrientationUp
+string_to_orientation (const char *orientation)
+{
+        int i;
+
+        if (orientation == NULL)
+                return ORIENTATION_UNDEFINED;
+        for (i = 0; orientations[i] != NULL; i++) {
+                if (strcmp (orientation, orientations[i]) == 0)
+                        return i;
+        }
+        return ORIENTATION_UNDEFINED;
+}
+
+static OrientationUp
+orientation_calc (OrientationUp prev,
+                  int x, int y, int z)
+{
+        int rotation;
+        OrientationUp ret = prev;
+
+        /* Portrait check */
+        rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES);
+
+        if (abs(rotation) > THRESHOLD_PORTRAIT) {
+                ret = (rotation < 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;
+
+                /* Some threshold to switching between portrait modes */
+                if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) {
+                        if (abs(rotation) < SAME_AXIS_LIMIT) {
+                                ret = prev;
+                        }
+                }
+
+        } else {
+                /* Landscape check */
+                rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES);
+
+                if (abs(rotation) > THRESHOLD_LANDSCAPE) {
+                        ret = (rotation < 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;
+
+                        /* Some threshold to switching between landscape modes */
+                        if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) {
+                                if (abs(rotation) < SAME_AXIS_LIMIT) {
+                                        ret = prev;
+                                }
+                        }
+                }
+        }
+
+        return ret;
+}
+
+static OrientationUp
+get_prev_orientation(struct udev_device *dev)
+{
+        const char *value;
+
+        value = udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER_ORIENTATION");
+        if (value == NULL)
+                return ORIENTATION_UNDEFINED;
+        return string_to_orientation(value);
+}
+
+#define SET_AXIS(axis, code_) if (ev[i].code == code_) { if (got_##axis == 0) { axis = ev[i].value; got_##axis = 1; } }
+
+/* accelerometers */
+static void test_orientation(struct udev *udev,
+                             struct udev_device *dev,
+                             const char *devpath)
+{
+        OrientationUp old, new;
+        int fd, r;
+        struct input_event ev[64];
+        int got_syn = 0;
+        int got_x, got_y, got_z;
+        int x = 0, y = 0, z = 0;
+        char text[64];
+
+        old = get_prev_orientation(dev);
+
+        if ((fd = open(devpath, O_RDONLY)) < 0)
+                return;
+
+        got_x = got_y = got_z = 0;
+
+        while (1) {
+                int i;
+
+                r = read(fd, ev, sizeof(struct input_event) * 64);
+
+                if (r < (int) sizeof(struct input_event)) {
+                        close(fd);
+                        return;
+                }
+
+                for (i = 0; i < r / (int) sizeof(struct input_event); i++) {
+                        if (got_syn == 1) {
+                                if (ev[i].type == EV_ABS) {
+                                        SET_AXIS(x, ABS_X);
+                                        SET_AXIS(y, ABS_Y);
+                                        SET_AXIS(z, ABS_Z);
+                                }
+                        }
+                        if (ev[i].type == EV_SYN && ev[i].code == SYN_REPORT) {
+                                got_syn = 1;
+                        }
+                        if (got_x && got_y && got_z)
+                                goto read_dev;
+                }
+        }
+
+read_dev:
+        close(fd);
+
+        if (!got_x || !got_y || !got_z)
+                return;
+
+        new = orientation_calc(old, x, y, z);
+        snprintf(text, sizeof(text), "ID_INPUT_ACCELEROMETER_ORIENTATION=%s", orientation_to_string(new));
+        puts(text);
+}
+
+static void help(void)
+{
+        printf("Usage: accelerometer [options] <device path>\n"
+               "  --debug         debug to stderr\n"
+               "  --help          print this help text\n\n");
+}
+
+int main (int argc, char** argv)
+{
+        struct udev *udev;
+        struct udev_device *dev;
+
+        static const struct option options[] = {
+                { "debug", no_argument, NULL, 'd' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+
+        char devpath[PATH_MAX];
+        char *devnode;
+        const char *id_path;
+        struct udev_enumerate *enumerate;
+        struct udev_list_entry *list_entry;
+
+        udev = udev_new();
+        if (udev == NULL)
+                return 1;
+
+        log_open();
+        udev_set_log_fn(udev, log_fn);
+
+        /* CLI argument parsing */
+        while (1) {
+                int option;
+
+                option = getopt_long(argc, argv, "dxh", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'd':
+                        debug = 1;
+                        log_set_max_level(LOG_DEBUG);
+                        udev_set_log_priority(udev, LOG_DEBUG);
+                        break;
+                case 'h':
+                        help();
+                        exit(0);
+                default:
+                        exit(1);
+                }
+        }
+
+        if (argv[optind] == NULL) {
+                help();
+                exit(1);
+        }
+
+        /* get the device */
+        snprintf(devpath, sizeof(devpath), "/sys/%s", argv[optind]);
+        dev = udev_device_new_from_syspath(udev, devpath);
+        if (dev == NULL) {
+                fprintf(stderr, "unable to access '%s'\n", devpath);
+                return 1;
+        }
+
+        id_path = udev_device_get_property_value(dev, "ID_PATH");
+        if (id_path == NULL) {
+                fprintf (stderr, "unable to get property ID_PATH for '%s'", devpath);
+                return 0;
+        }
+
+        /* Get the children devices and find the devnode */
+        /* FIXME: use udev_enumerate_add_match_parent() instead */
+        devnode = NULL;
+        enumerate = udev_enumerate_new(udev);
+        udev_enumerate_add_match_property(enumerate, "ID_PATH", id_path);
+        udev_enumerate_add_match_subsystem(enumerate, "input");
+        udev_enumerate_scan_devices(enumerate);
+        udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
+                struct udev_device *device;
+                const char *node;
+
+                device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
+                                                      udev_list_entry_get_name(list_entry));
+                if (device == NULL)
+                        continue;
+                /* Already found it */
+                if (devnode != NULL) {
+                        udev_device_unref(device);
+                        continue;
+                }
+
+                node = udev_device_get_devnode(device);
+                if (node == NULL) {
+                        udev_device_unref(device);
+                        continue;
+                }
+                /* Use the event sub-device */
+                if (strstr(node, "/event") == NULL) {
+                        udev_device_unref(device);
+                        continue;
+                }
+
+                devnode = strdup(node);
+                udev_device_unref(device);
+        }
+
+        if (devnode == NULL) {
+                fprintf(stderr, "unable to get device node for '%s'\n", devpath);
+                return 0;
+        }
+
+        log_debug("opening accelerometer device %s\n", devnode);
+        test_orientation(udev, dev, devnode);
+        free(devnode);
+        log_close();
+        return 0;
+}
diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c
new file mode 100644 (file)
index 0000000..488fed4
--- /dev/null
@@ -0,0 +1,714 @@
+/*
+ * ata_id - reads product/serial number from ATA drives
+ *
+ * Copyright (C) 2005-2008 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2009 Lennart Poettering <lennart@poettering.net>
+ * Copyright (C) 2009-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <scsi/scsi.h>
+#include <scsi/sg.h>
+#include <scsi/scsi_ioctl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <linux/types.h>
+#include <linux/hdreg.h>
+#include <linux/fs.h>
+#include <linux/cdrom.h>
+#include <linux/bsg.h>
+#include <arpa/inet.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+#include "log.h"
+
+#define COMMAND_TIMEOUT_MSEC (30 * 1000)
+
+static int disk_scsi_inquiry_command(int      fd,
+                                     void    *buf,
+                                     size_t   buf_len)
+{
+        struct sg_io_v4 io_v4;
+        uint8_t cdb[6];
+        uint8_t sense[32];
+        int ret;
+
+        /*
+         * INQUIRY, see SPC-4 section 6.4
+         */
+        memset(cdb, 0, sizeof(cdb));
+        cdb[0] = 0x12;                         /* OPERATION CODE: INQUIRY */
+        cdb[3] = (buf_len >> 8);         /* ALLOCATION LENGTH */
+        cdb[4] = (buf_len & 0xff);
+
+        memset(sense, 0, sizeof(sense));
+
+        memset(&io_v4, 0, sizeof(struct sg_io_v4));
+        io_v4.guard = 'Q';
+        io_v4.protocol = BSG_PROTOCOL_SCSI;
+        io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
+        io_v4.request_len = sizeof (cdb);
+        io_v4.request = (uintptr_t) cdb;
+        io_v4.max_response_len = sizeof (sense);
+        io_v4.response = (uintptr_t) sense;
+        io_v4.din_xfer_len = buf_len;
+        io_v4.din_xferp = (uintptr_t) buf;
+        io_v4.timeout = COMMAND_TIMEOUT_MSEC;
+
+        ret = ioctl(fd, SG_IO, &io_v4);
+        if (ret != 0) {
+                /* could be that the driver doesn't do version 4, try version 3 */
+                if (errno == EINVAL) {
+                        struct sg_io_hdr io_hdr;
+
+                        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+                        io_hdr.interface_id = 'S';
+                        io_hdr.cmdp = (unsigned char*) cdb;
+                        io_hdr.cmd_len = sizeof (cdb);
+                        io_hdr.dxferp = buf;
+                        io_hdr.dxfer_len = buf_len;
+                        io_hdr.sbp = sense;
+                        io_hdr.mx_sb_len = sizeof (sense);
+                        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+                        io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
+
+                        ret = ioctl(fd, SG_IO, &io_hdr);
+                        if (ret != 0)
+                                goto out;
+
+                        /* even if the ioctl succeeds, we need to check the return value */
+                        if (!(io_hdr.status == 0 &&
+                              io_hdr.host_status == 0 &&
+                              io_hdr.driver_status == 0)) {
+                                errno = EIO;
+                                ret = -1;
+                                goto out;
+                        }
+                } else {
+                        goto out;
+                }
+        }
+
+        /* even if the ioctl succeeds, we need to check the return value */
+        if (!(io_v4.device_status == 0 &&
+              io_v4.transport_status == 0 &&
+              io_v4.driver_status == 0)) {
+                errno = EIO;
+                ret = -1;
+                goto out;
+        }
+
+ out:
+        return ret;
+}
+
+static int disk_identify_command(int          fd,
+                                 void         *buf,
+                                 size_t          buf_len)
+{
+        struct sg_io_v4 io_v4;
+        uint8_t cdb[12];
+        uint8_t sense[32];
+        uint8_t *desc = sense+8;
+        int ret;
+
+        /*
+         * ATA Pass-Through 12 byte command, as described in
+         *
+         *  T10 04-262r8 ATA Command Pass-Through
+         *
+         * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
+         */
+        memset(cdb, 0, sizeof(cdb));
+        cdb[0] = 0xa1;                        /* OPERATION CODE: 12 byte pass through */
+        cdb[1] = 4 << 1;                /* PROTOCOL: PIO Data-in */
+        cdb[2] = 0x2e;                        /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
+        cdb[3] = 0;                        /* FEATURES */
+        cdb[4] = 1;                        /* SECTORS */
+        cdb[5] = 0;                        /* LBA LOW */
+        cdb[6] = 0;                        /* LBA MID */
+        cdb[7] = 0;                        /* LBA HIGH */
+        cdb[8] = 0 & 0x4F;                /* SELECT */
+        cdb[9] = 0xEC;                        /* Command: ATA IDENTIFY DEVICE */;
+        memset(sense, 0, sizeof(sense));
+
+        memset(&io_v4, 0, sizeof(struct sg_io_v4));
+        io_v4.guard = 'Q';
+        io_v4.protocol = BSG_PROTOCOL_SCSI;
+        io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
+        io_v4.request_len = sizeof (cdb);
+        io_v4.request = (uintptr_t) cdb;
+        io_v4.max_response_len = sizeof (sense);
+        io_v4.response = (uintptr_t) sense;
+        io_v4.din_xfer_len = buf_len;
+        io_v4.din_xferp = (uintptr_t) buf;
+        io_v4.timeout = COMMAND_TIMEOUT_MSEC;
+
+        ret = ioctl(fd, SG_IO, &io_v4);
+        if (ret != 0) {
+                /* could be that the driver doesn't do version 4, try version 3 */
+                if (errno == EINVAL) {
+                        struct sg_io_hdr io_hdr;
+
+                        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+                        io_hdr.interface_id = 'S';
+                        io_hdr.cmdp = (unsigned char*) cdb;
+                        io_hdr.cmd_len = sizeof (cdb);
+                        io_hdr.dxferp = buf;
+                        io_hdr.dxfer_len = buf_len;
+                        io_hdr.sbp = sense;
+                        io_hdr.mx_sb_len = sizeof (sense);
+                        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+                        io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
+
+                        ret = ioctl(fd, SG_IO, &io_hdr);
+                        if (ret != 0)
+                                goto out;
+                } else {
+                        goto out;
+                }
+        }
+
+        if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
+                errno = EIO;
+                ret = -1;
+                goto out;
+        }
+
+ out:
+        return ret;
+}
+
+static int disk_identify_packet_device_command(int          fd,
+                                               void         *buf,
+                                               size_t          buf_len)
+{
+        struct sg_io_v4 io_v4;
+        uint8_t cdb[16];
+        uint8_t sense[32];
+        uint8_t *desc = sense+8;
+        int ret;
+
+        /*
+         * ATA Pass-Through 16 byte command, as described in
+         *
+         *  T10 04-262r8 ATA Command Pass-Through
+         *
+         * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
+         */
+        memset(cdb, 0, sizeof(cdb));
+        cdb[0] = 0x85;                        /* OPERATION CODE: 16 byte pass through */
+        cdb[1] = 4 << 1;                /* PROTOCOL: PIO Data-in */
+        cdb[2] = 0x2e;                        /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
+        cdb[3] = 0;                        /* FEATURES */
+        cdb[4] = 0;                        /* FEATURES */
+        cdb[5] = 0;                        /* SECTORS */
+        cdb[6] = 1;                        /* SECTORS */
+        cdb[7] = 0;                        /* LBA LOW */
+        cdb[8] = 0;                        /* LBA LOW */
+        cdb[9] = 0;                        /* LBA MID */
+        cdb[10] = 0;                        /* LBA MID */
+        cdb[11] = 0;                        /* LBA HIGH */
+        cdb[12] = 0;                        /* LBA HIGH */
+        cdb[13] = 0;                        /* DEVICE */
+        cdb[14] = 0xA1;                        /* Command: ATA IDENTIFY PACKET DEVICE */;
+        cdb[15] = 0;                        /* CONTROL */
+        memset(sense, 0, sizeof(sense));
+
+        memset(&io_v4, 0, sizeof(struct sg_io_v4));
+        io_v4.guard = 'Q';
+        io_v4.protocol = BSG_PROTOCOL_SCSI;
+        io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
+        io_v4.request_len = sizeof (cdb);
+        io_v4.request = (uintptr_t) cdb;
+        io_v4.max_response_len = sizeof (sense);
+        io_v4.response = (uintptr_t) sense;
+        io_v4.din_xfer_len = buf_len;
+        io_v4.din_xferp = (uintptr_t) buf;
+        io_v4.timeout = COMMAND_TIMEOUT_MSEC;
+
+        ret = ioctl(fd, SG_IO, &io_v4);
+        if (ret != 0) {
+                /* could be that the driver doesn't do version 4, try version 3 */
+                if (errno == EINVAL) {
+                        struct sg_io_hdr io_hdr;
+
+                        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+                        io_hdr.interface_id = 'S';
+                        io_hdr.cmdp = (unsigned char*) cdb;
+                        io_hdr.cmd_len = sizeof (cdb);
+                        io_hdr.dxferp = buf;
+                        io_hdr.dxfer_len = buf_len;
+                        io_hdr.sbp = sense;
+                        io_hdr.mx_sb_len = sizeof (sense);
+                        io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+                        io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
+
+                        ret = ioctl(fd, SG_IO, &io_hdr);
+                        if (ret != 0)
+                                goto out;
+                } else {
+                        goto out;
+                }
+        }
+
+        if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
+                errno = EIO;
+                ret = -1;
+                goto out;
+        }
+
+ out:
+        return ret;
+}
+
+/**
+ * disk_identify_get_string:
+ * @identify: A block of IDENTIFY data
+ * @offset_words: Offset of the string to get, in words.
+ * @dest: Destination buffer for the string.
+ * @dest_len: Length of destination buffer, in bytes.
+ *
+ * Copies the ATA string from @identify located at @offset_words into @dest.
+ */
+static void disk_identify_get_string(uint8_t identify[512],
+                                     unsigned int offset_words,
+                                     char *dest,
+                                     size_t dest_len)
+{
+        unsigned int c1;
+        unsigned int c2;
+
+        while (dest_len > 0) {
+                c1 = identify[offset_words * 2 + 1];
+                c2 = identify[offset_words * 2];
+                *dest = c1;
+                dest++;
+                *dest = c2;
+                dest++;
+                offset_words++;
+                dest_len -= 2;
+        }
+}
+
+static void disk_identify_fixup_string(uint8_t identify[512],
+                                       unsigned int offset_words,
+                                       size_t len)
+{
+        disk_identify_get_string(identify, offset_words,
+                                 (char *) identify + offset_words * 2, len);
+}
+
+static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offset_words)
+{
+        uint16_t *p;
+
+        p = (uint16_t *) identify;
+        p[offset_words] = le16toh (p[offset_words]);
+}
+
+/**
+ * disk_identify:
+ * @udev: The libudev context.
+ * @fd: File descriptor for the block device.
+ * @out_identify: Return location for IDENTIFY data.
+ * @out_is_packet_device: Return location for whether returned data is from a IDENTIFY PACKET DEVICE.
+ *
+ * Sends the IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command to the
+ * device represented by @fd. If successful, then the result will be
+ * copied into @out_identify and @out_is_packet_device.
+ *
+ * This routine is based on code from libatasmart, Copyright 2008
+ * Lennart Poettering, LGPL v2.1.
+ *
+ * Returns: 0 if the data was successfully obtained, otherwise
+ * non-zero with errno set.
+ */
+static int disk_identify(struct udev *udev,
+                         int               fd,
+                         uint8_t      out_identify[512],
+                         int              *out_is_packet_device)
+{
+        int ret;
+        uint8_t inquiry_buf[36];
+        int peripheral_device_type;
+        int all_nul_bytes;
+        int n;
+        int is_packet_device;
+
+        /* init results */
+        memset(out_identify, '\0', 512);
+        is_packet_device = 0;
+
+        /* If we were to use ATA PASS_THROUGH (12) on an ATAPI device
+         * we could accidentally blank media. This is because MMC's BLANK
+         * command has the same op-code (0x61).
+         *
+         * To prevent this from happening we bail out if the device
+         * isn't a Direct Access Block Device, e.g. SCSI type 0x00
+         * (CD/DVD devices are type 0x05). So we send a SCSI INQUIRY
+         * command first... libata is handling this via its SCSI
+         * emulation layer.
+         *
+         * This also ensures that we're actually dealing with a device
+         * that understands SCSI commands.
+         *
+         * (Yes, it is a bit perverse that we're tunneling the ATA
+         * command through SCSI and relying on the ATA driver
+         * emulating SCSI well-enough...)
+         *
+         * (See commit 160b069c25690bfb0c785994c7c3710289179107 for
+         * the original bug-fix and see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=556635
+         * for the original bug-report.)
+         */
+        ret = disk_scsi_inquiry_command (fd, inquiry_buf, sizeof (inquiry_buf));
+        if (ret != 0)
+                goto out;
+
+        /* SPC-4, section 6.4.2: Standard INQUIRY data */
+        peripheral_device_type = inquiry_buf[0] & 0x1f;
+        if (peripheral_device_type == 0x05)
+          {
+            is_packet_device = 1;
+            ret = disk_identify_packet_device_command(fd, out_identify, 512);
+            goto check_nul_bytes;
+          }
+        if (peripheral_device_type != 0x00) {
+                ret = -1;
+                errno = EIO;
+                goto out;
+        }
+
+        /* OK, now issue the IDENTIFY DEVICE command */
+        ret = disk_identify_command(fd, out_identify, 512);
+        if (ret != 0)
+                goto out;
+
+ check_nul_bytes:
+         /* Check if IDENTIFY data is all NUL bytes - if so, bail */
+        all_nul_bytes = 1;
+        for (n = 0; n < 512; n++) {
+                if (out_identify[n] != '\0') {
+                        all_nul_bytes = 0;
+                        break;
+                }
+        }
+
+        if (all_nul_bytes) {
+                ret = -1;
+                errno = EIO;
+                goto out;
+        }
+
+out:
+        if (out_is_packet_device != NULL)
+          *out_is_packet_device = is_packet_device;
+        return ret;
+}
+
+static void log_fn(struct udev *udev, int priority,
+                   const char *file, int line, const char *fn,
+                   const char *format, va_list args)
+{
+        vsyslog(priority, format, args);
+}
+
+int main(int argc, char *argv[])
+{
+        struct udev *udev;
+        struct hd_driveid id;
+        uint8_t identify[512];
+        uint16_t *identify_words;
+        char model[41];
+        char model_enc[256];
+        char serial[21];
+        char revision[9];
+        const char *node = NULL;
+        int export = 0;
+        int fd;
+        uint16_t word;
+        int rc = 0;
+        int is_packet_device = 0;
+        static const struct option options[] = {
+                { "export", no_argument, NULL, 'x' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+
+        udev = udev_new();
+        if (udev == NULL)
+                goto exit;
+
+        log_open();
+        udev_set_log_fn(udev, log_fn);
+
+        while (1) {
+                int option;
+
+                option = getopt_long(argc, argv, "xh", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'x':
+                        export = 1;
+                        break;
+                case 'h':
+                        printf("Usage: ata_id [--export] [--help] <device>\n"
+                               "  --export    print values as environment keys\n"
+                               "  --help      print this help text\n\n");
+                        goto exit;
+                }
+        }
+
+        node = argv[optind];
+        if (node == NULL) {
+                log_error("no node specified\n");
+                rc = 1;
+                goto exit;
+        }
+
+        fd = open(node, O_RDONLY|O_NONBLOCK);
+        if (fd < 0) {
+                log_error("unable to open '%s'\n", node);
+                rc = 1;
+                goto exit;
+        }
+
+        if (disk_identify(udev, fd, identify, &is_packet_device) == 0) {
+                /*
+                 * fix up only the fields from the IDENTIFY data that we are going to
+                 * use and copy it into the hd_driveid struct for convenience
+                 */
+                disk_identify_fixup_string(identify,  10, 20); /* serial */
+                disk_identify_fixup_string(identify,  23,  8); /* fwrev */
+                disk_identify_fixup_string(identify,  27, 40); /* model */
+                disk_identify_fixup_uint16(identify,  0);      /* configuration */
+                disk_identify_fixup_uint16(identify,  75);     /* queue depth */
+                disk_identify_fixup_uint16(identify,  75);     /* SATA capabilities */
+                disk_identify_fixup_uint16(identify,  82);     /* command set supported */
+                disk_identify_fixup_uint16(identify,  83);     /* command set supported */
+                disk_identify_fixup_uint16(identify,  84);     /* command set supported */
+                disk_identify_fixup_uint16(identify,  85);     /* command set supported */
+                disk_identify_fixup_uint16(identify,  86);     /* command set supported */
+                disk_identify_fixup_uint16(identify,  87);     /* command set supported */
+                disk_identify_fixup_uint16(identify,  89);     /* time required for SECURITY ERASE UNIT */
+                disk_identify_fixup_uint16(identify,  90);     /* time required for enhanced SECURITY ERASE UNIT */
+                disk_identify_fixup_uint16(identify,  91);     /* current APM values */
+                disk_identify_fixup_uint16(identify,  94);     /* current AAM value */
+                disk_identify_fixup_uint16(identify, 128);     /* device lock function */
+                disk_identify_fixup_uint16(identify, 217);     /* nominal media rotation rate */
+                memcpy(&id, identify, sizeof id);
+        } else {
+                /* If this fails, then try HDIO_GET_IDENTITY */
+                if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) {
+                        log_info("HDIO_GET_IDENTITY failed for '%s': %m\n", node);
+                        rc = 2;
+                        goto close;
+                }
+        }
+        identify_words = (uint16_t *) identify;
+
+        memcpy (model, id.model, 40);
+        model[40] = '\0';
+        udev_util_encode_string(model, model_enc, sizeof(model_enc));
+        util_replace_whitespace((char *) id.model, model, 40);
+        util_replace_chars(model, NULL);
+        util_replace_whitespace((char *) id.serial_no, serial, 20);
+        util_replace_chars(serial, NULL);
+        util_replace_whitespace((char *) id.fw_rev, revision, 8);
+        util_replace_chars(revision, NULL);
+
+        if (export) {
+                /* Set this to convey the disk speaks the ATA protocol */
+                printf("ID_ATA=1\n");
+
+                if ((id.config >> 8) & 0x80) {
+                        /* This is an ATAPI device */
+                        switch ((id.config >> 8) & 0x1f) {
+                        case 0:
+                                printf("ID_TYPE=cd\n");
+                                break;
+                        case 1:
+                                printf("ID_TYPE=tape\n");
+                                break;
+                        case 5:
+                                printf("ID_TYPE=cd\n");
+                                break;
+                        case 7:
+                                printf("ID_TYPE=optical\n");
+                                break;
+                        default:
+                                printf("ID_TYPE=generic\n");
+                                break;
+                        }
+                } else {
+                        printf("ID_TYPE=disk\n");
+                }
+                printf("ID_BUS=ata\n");
+                printf("ID_MODEL=%s\n", model);
+                printf("ID_MODEL_ENC=%s\n", model_enc);
+                printf("ID_REVISION=%s\n", revision);
+                if (serial[0] != '\0') {
+                        printf("ID_SERIAL=%s_%s\n", model, serial);
+                        printf("ID_SERIAL_SHORT=%s\n", serial);
+                } else {
+                        printf("ID_SERIAL=%s\n", model);
+                }
+
+                if (id.command_set_1 & (1<<5)) {
+                        printf ("ID_ATA_WRITE_CACHE=1\n");
+                        printf ("ID_ATA_WRITE_CACHE_ENABLED=%d\n", (id.cfs_enable_1 & (1<<5)) ? 1 : 0);
+                }
+                if (id.command_set_1 & (1<<10)) {
+                        printf("ID_ATA_FEATURE_SET_HPA=1\n");
+                        printf("ID_ATA_FEATURE_SET_HPA_ENABLED=%d\n", (id.cfs_enable_1 & (1<<10)) ? 1 : 0);
+
+                        /*
+                         * TODO: use the READ NATIVE MAX ADDRESS command to get the native max address
+                         * so it is easy to check whether the protected area is in use.
+                         */
+                }
+                if (id.command_set_1 & (1<<3)) {
+                        printf("ID_ATA_FEATURE_SET_PM=1\n");
+                        printf("ID_ATA_FEATURE_SET_PM_ENABLED=%d\n", (id.cfs_enable_1 & (1<<3)) ? 1 : 0);
+                }
+                if (id.command_set_1 & (1<<1)) {
+                        printf("ID_ATA_FEATURE_SET_SECURITY=1\n");
+                        printf("ID_ATA_FEATURE_SET_SECURITY_ENABLED=%d\n", (id.cfs_enable_1 & (1<<1)) ? 1 : 0);
+                        printf("ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=%d\n", id.trseuc * 2);
+                        if ((id.cfs_enable_1 & (1<<1))) /* enabled */ {
+                                if (id.dlf & (1<<8))
+                                        printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=maximum\n");
+                                else
+                                        printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=high\n");
+                        }
+                        if (id.dlf & (1<<5))
+                                printf("ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=%d\n", id.trsEuc * 2);
+                        if (id.dlf & (1<<4))
+                                printf("ID_ATA_FEATURE_SET_SECURITY_EXPIRE=1\n");
+                        if (id.dlf & (1<<3))
+                                printf("ID_ATA_FEATURE_SET_SECURITY_FROZEN=1\n");
+                        if (id.dlf & (1<<2))
+                                printf("ID_ATA_FEATURE_SET_SECURITY_LOCKED=1\n");
+                }
+                if (id.command_set_1 & (1<<0)) {
+                        printf("ID_ATA_FEATURE_SET_SMART=1\n");
+                        printf("ID_ATA_FEATURE_SET_SMART_ENABLED=%d\n", (id.cfs_enable_1 & (1<<0)) ? 1 : 0);
+                }
+                if (id.command_set_2 & (1<<9)) {
+                        printf("ID_ATA_FEATURE_SET_AAM=1\n");
+                        printf("ID_ATA_FEATURE_SET_AAM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<9)) ? 1 : 0);
+                        printf("ID_ATA_FEATURE_SET_AAM_VENDOR_RECOMMENDED_VALUE=%d\n", id.acoustic >> 8);
+                        printf("ID_ATA_FEATURE_SET_AAM_CURRENT_VALUE=%d\n", id.acoustic & 0xff);
+                }
+                if (id.command_set_2 & (1<<5)) {
+                        printf("ID_ATA_FEATURE_SET_PUIS=1\n");
+                        printf("ID_ATA_FEATURE_SET_PUIS_ENABLED=%d\n", (id.cfs_enable_2 & (1<<5)) ? 1 : 0);
+                }
+                if (id.command_set_2 & (1<<3)) {
+                        printf("ID_ATA_FEATURE_SET_APM=1\n");
+                        printf("ID_ATA_FEATURE_SET_APM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<3)) ? 1 : 0);
+                        if ((id.cfs_enable_2 & (1<<3)))
+                                printf("ID_ATA_FEATURE_SET_APM_CURRENT_VALUE=%d\n", id.CurAPMvalues & 0xff);
+                }
+                if (id.command_set_2 & (1<<0))
+                        printf("ID_ATA_DOWNLOAD_MICROCODE=1\n");
+
+                /*
+                 * Word 76 indicates the capabilities of a SATA device. A PATA device shall set
+                 * word 76 to 0000h or FFFFh. If word 76 is set to 0000h or FFFFh, then
+                 * the device does not claim compliance with the Serial ATA specification and words
+                 * 76 through 79 are not valid and shall be ignored.
+                 */
+                word = *((uint16_t *) identify + 76);
+                if (word != 0x0000 && word != 0xffff) {
+                        printf("ID_ATA_SATA=1\n");
+                        /*
+                         * If bit 2 of word 76 is set to one, then the device supports the Gen2
+                         * signaling rate of 3.0 Gb/s (see SATA 2.6).
+                         *
+                         * If bit 1 of word 76 is set to one, then the device supports the Gen1
+                         * signaling rate of 1.5 Gb/s (see SATA 2.6).
+                         */
+                        if (word & (1<<2))
+                                printf("ID_ATA_SATA_SIGNAL_RATE_GEN2=1\n");
+                        if (word & (1<<1))
+                                printf("ID_ATA_SATA_SIGNAL_RATE_GEN1=1\n");
+                }
+
+                /* Word 217 indicates the nominal media rotation rate of the device */
+                word = *((uint16_t *) identify + 217);
+                if (word != 0x0000) {
+                        if (word == 0x0001) {
+                                printf ("ID_ATA_ROTATION_RATE_RPM=0\n"); /* non-rotating e.g. SSD */
+                        } else if (word >= 0x0401 && word <= 0xfffe) {
+                                printf ("ID_ATA_ROTATION_RATE_RPM=%d\n", word);
+                        }
+                }
+
+                /*
+                 * Words 108-111 contain a mandatory World Wide Name (WWN) in the NAA IEEE Registered identifier
+                 * format. Word 108 bits (15:12) shall contain 5h, indicating that the naming authority is IEEE.
+                 * All other values are reserved.
+                 */
+                word = *((uint16_t *) identify + 108);
+                if ((word & 0xf000) == 0x5000) {
+                        uint64_t wwwn;
+
+                        wwwn   = *((uint16_t *) identify + 108);
+                        wwwn <<= 16;
+                        wwwn  |= *((uint16_t *) identify + 109);
+                        wwwn <<= 16;
+                        wwwn  |= *((uint16_t *) identify + 110);
+                        wwwn <<= 16;
+                        wwwn  |= *((uint16_t *) identify + 111);
+                        printf("ID_WWN=0x%llx\n", (unsigned long long int) wwwn);
+                        /* ATA devices have no vendor extension */
+                        printf("ID_WWN_WITH_EXTENSION=0x%llx\n", (unsigned long long int) wwwn);
+                }
+
+                /* from Linux's include/linux/ata.h */
+                if (identify_words[0] == 0x848a || identify_words[0] == 0x844a) {
+                        printf("ID_ATA_CFA=1\n");
+                } else {
+                        if ((identify_words[83] & 0xc004) == 0x4004) {
+                                printf("ID_ATA_CFA=1\n");
+                        }
+                }
+        } else {
+                if (serial[0] != '\0')
+                        printf("%s_%s\n", model, serial);
+                else
+                        printf("%s\n", model);
+        }
+close:
+        close(fd);
+exit:
+        udev_unref(udev);
+        log_close();
+        return rc;
+}
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
new file mode 100644 (file)
index 0000000..1056536
--- /dev/null
@@ -0,0 +1,1099 @@
+/*
+ * cdrom_id - optical drive and media information prober
+ *
+ * Copyright (C) 2008-2010 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <getopt.h>
+#include <time.h>
+#include <scsi/sg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+static bool debug;
+
+static void log_fn(struct udev *udev, int priority,
+                   const char *file, int line, const char *fn,
+                   const char *format, va_list args)
+{
+        if (debug) {
+                fprintf(stderr, "%s: ", fn);
+                vfprintf(stderr, format, args);
+        } else {
+                vsyslog(priority, format, args);
+        }
+}
+
+/* device info */
+static unsigned int cd_cd_rom;
+static unsigned int cd_cd_r;
+static unsigned int cd_cd_rw;
+static unsigned int cd_dvd_rom;
+static unsigned int cd_dvd_r;
+static unsigned int cd_dvd_rw;
+static unsigned int cd_dvd_ram;
+static unsigned int cd_dvd_plus_r;
+static unsigned int cd_dvd_plus_rw;
+static unsigned int cd_dvd_plus_r_dl;
+static unsigned int cd_dvd_plus_rw_dl;
+static unsigned int cd_bd;
+static unsigned int cd_bd_r;
+static unsigned int cd_bd_re;
+static unsigned int cd_hddvd;
+static unsigned int cd_hddvd_r;
+static unsigned int cd_hddvd_rw;
+static unsigned int cd_mo;
+static unsigned int cd_mrw;
+static unsigned int cd_mrw_w;
+
+/* media info */
+static unsigned int cd_media;
+static unsigned int cd_media_cd_rom;
+static unsigned int cd_media_cd_r;
+static unsigned int cd_media_cd_rw;
+static unsigned int cd_media_dvd_rom;
+static unsigned int cd_media_dvd_r;
+static unsigned int cd_media_dvd_rw;
+static unsigned int cd_media_dvd_rw_ro; /* restricted overwrite mode */
+static unsigned int cd_media_dvd_rw_seq; /* sequential mode */
+static unsigned int cd_media_dvd_ram;
+static unsigned int cd_media_dvd_plus_r;
+static unsigned int cd_media_dvd_plus_rw;
+static unsigned int cd_media_dvd_plus_r_dl;
+static unsigned int cd_media_dvd_plus_rw_dl;
+static unsigned int cd_media_bd;
+static unsigned int cd_media_bd_r;
+static unsigned int cd_media_bd_re;
+static unsigned int cd_media_hddvd;
+static unsigned int cd_media_hddvd_r;
+static unsigned int cd_media_hddvd_rw;
+static unsigned int cd_media_mo;
+static unsigned int cd_media_mrw;
+static unsigned int cd_media_mrw_w;
+
+static const char *cd_media_state = NULL;
+static unsigned int cd_media_session_next;
+static unsigned int cd_media_session_count;
+static unsigned int cd_media_track_count;
+static unsigned int cd_media_track_count_data;
+static unsigned int cd_media_track_count_audio;
+static unsigned long long int cd_media_session_last_offset;
+
+#define ERRCODE(s)        ((((s)[2] & 0x0F) << 16) | ((s)[12] << 8) | ((s)[13]))
+#define SK(errcode)        (((errcode) >> 16) & 0xF)
+#define ASC(errcode)        (((errcode) >> 8) & 0xFF)
+#define ASCQ(errcode)        ((errcode) & 0xFF)
+
+static bool is_mounted(const char *device)
+{
+        struct stat statbuf;
+        FILE *fp;
+        int maj, min;
+        bool mounted = false;
+
+        if (stat(device, &statbuf) < 0)
+                return -ENODEV;
+
+        fp = fopen("/proc/self/mountinfo", "re");
+        if (fp == NULL)
+                return -ENOSYS;
+        while (fscanf(fp, "%*s %*s %i:%i %*[^\n]", &maj, &min) == 2) {
+                if (makedev(maj, min) == statbuf.st_rdev) {
+                        mounted = true;
+                        break;
+                }
+        }
+        fclose(fp);
+        return mounted;
+}
+
+static void info_scsi_cmd_err(struct udev *udev, const char *cmd, int err)
+{
+        if (err == -1) {
+                log_debug("%s failed\n", cmd);
+                return;
+        }
+        log_debug("%s failed with SK=%Xh/ASC=%02Xh/ACQ=%02Xh\n", cmd, SK(err), ASC(err), ASCQ(err));
+}
+
+struct scsi_cmd {
+        struct cdrom_generic_command cgc;
+        union {
+                struct request_sense s;
+                unsigned char u[18];
+        } _sense;
+        struct sg_io_hdr sg_io;
+};
+
+static void scsi_cmd_init(struct udev *udev, struct scsi_cmd *cmd)
+{
+        memset(cmd, 0x00, sizeof(struct scsi_cmd));
+        cmd->cgc.quiet = 1;
+        cmd->cgc.sense = &cmd->_sense.s;
+        cmd->sg_io.interface_id = 'S';
+        cmd->sg_io.mx_sb_len = sizeof(cmd->_sense);
+        cmd->sg_io.cmdp = cmd->cgc.cmd;
+        cmd->sg_io.sbp = cmd->_sense.u;
+        cmd->sg_io.flags = SG_FLAG_LUN_INHIBIT | SG_FLAG_DIRECT_IO;
+}
+
+static void scsi_cmd_set(struct udev *udev, struct scsi_cmd *cmd, size_t i, unsigned char arg)
+{
+        cmd->sg_io.cmd_len = i + 1;
+        cmd->cgc.cmd[i] = arg;
+}
+
+#define CHECK_CONDITION 0x01
+
+static int scsi_cmd_run(struct udev *udev, struct scsi_cmd *cmd, int fd, unsigned char *buf, size_t bufsize)
+{
+        int ret = 0;
+
+        if (bufsize > 0) {
+                cmd->sg_io.dxferp = buf;
+                cmd->sg_io.dxfer_len = bufsize;
+                cmd->sg_io.dxfer_direction = SG_DXFER_FROM_DEV;
+        } else {
+                cmd->sg_io.dxfer_direction = SG_DXFER_NONE;
+        }
+        if (ioctl(fd, SG_IO, &cmd->sg_io))
+                return -1;
+
+        if ((cmd->sg_io.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
+                errno = EIO;
+                ret = -1;
+                if (cmd->sg_io.masked_status & CHECK_CONDITION) {
+                        ret = ERRCODE(cmd->_sense.u);
+                        if (ret == 0)
+                                ret = -1;
+                }
+        }
+        return ret;
+}
+
+static int media_lock(struct udev *udev, int fd, bool lock)
+{
+        int err;
+
+        /* disable the kernel's lock logic */
+        err = ioctl(fd, CDROM_CLEAR_OPTIONS, CDO_LOCK);
+        if (err < 0)
+                log_debug("CDROM_CLEAR_OPTIONS, CDO_LOCK failed\n");
+
+        err = ioctl(fd, CDROM_LOCKDOOR, lock ? 1 : 0);
+        if (err < 0)
+                log_debug("CDROM_LOCKDOOR failed\n");
+
+        return err;
+}
+
+static int media_eject(struct udev *udev, int fd)
+{
+        struct scsi_cmd sc;
+        int err;
+
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x1b);
+        scsi_cmd_set(udev, &sc, 4, 0x02);
+        scsi_cmd_set(udev, &sc, 5, 0);
+        err = scsi_cmd_run(udev, &sc, fd, NULL, 0);
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "START_STOP_UNIT", err);
+                return -1;
+        }
+        return 0;
+}
+
+static int cd_capability_compat(struct udev *udev, int fd)
+{
+        int capability;
+
+        capability = ioctl(fd, CDROM_GET_CAPABILITY, NULL);
+        if (capability < 0) {
+                log_debug("CDROM_GET_CAPABILITY failed\n");
+                return -1;
+        }
+
+        if (capability & CDC_CD_R)
+                cd_cd_r = 1;
+        if (capability & CDC_CD_RW)
+                cd_cd_rw = 1;
+        if (capability & CDC_DVD)
+                cd_dvd_rom = 1;
+        if (capability & CDC_DVD_R)
+                cd_dvd_r = 1;
+        if (capability & CDC_DVD_RAM)
+                cd_dvd_ram = 1;
+        if (capability & CDC_MRW)
+                cd_mrw = 1;
+        if (capability & CDC_MRW_W)
+                cd_mrw_w = 1;
+        return 0;
+}
+
+static int cd_media_compat(struct udev *udev, int fd)
+{
+        if (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) != CDS_DISC_OK) {
+                log_debug("CDROM_DRIVE_STATUS != CDS_DISC_OK\n");
+                return -1;
+        }
+        cd_media = 1;
+        return 0;
+}
+
+static int cd_inquiry(struct udev *udev, int fd)
+{
+        struct scsi_cmd sc;
+        unsigned char inq[128];
+        int err;
+
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x12);
+        scsi_cmd_set(udev, &sc, 4, 36);
+        scsi_cmd_set(udev, &sc, 5, 0);
+        err = scsi_cmd_run(udev, &sc, fd, inq, 36);
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "INQUIRY", err);
+                return -1;
+        }
+
+        if ((inq[0] & 0x1F) != 5) {
+                log_debug("not an MMC unit\n");
+                return -1;
+        }
+
+        log_debug("INQUIRY: [%.8s][%.16s][%.4s]\n", inq + 8, inq + 16, inq + 32);
+        return 0;
+}
+
+static void feature_profile_media(struct udev *udev, int cur_profile)
+{
+        switch (cur_profile) {
+        case 0x03:
+        case 0x04:
+        case 0x05:
+                log_debug("profile 0x%02x \n", cur_profile);
+                cd_media = 1;
+                cd_media_mo = 1;
+                break;
+        case 0x08:
+                log_debug("profile 0x%02x media_cd_rom\n", cur_profile);
+                cd_media = 1;
+                cd_media_cd_rom = 1;
+                break;
+        case 0x09:
+                log_debug("profile 0x%02x media_cd_r\n", cur_profile);
+                cd_media = 1;
+                cd_media_cd_r = 1;
+                break;
+        case 0x0a:
+                log_debug("profile 0x%02x media_cd_rw\n", cur_profile);
+                cd_media = 1;
+                cd_media_cd_rw = 1;
+                break;
+        case 0x10:
+                log_debug("profile 0x%02x media_dvd_ro\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_rom = 1;
+                break;
+        case 0x11:
+                log_debug("profile 0x%02x media_dvd_r\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_r = 1;
+                break;
+        case 0x12:
+                log_debug("profile 0x%02x media_dvd_ram\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_ram = 1;
+                break;
+        case 0x13:
+                log_debug("profile 0x%02x media_dvd_rw_ro\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_rw = 1;
+                cd_media_dvd_rw_ro = 1;
+                break;
+        case 0x14:
+                log_debug("profile 0x%02x media_dvd_rw_seq\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_rw = 1;
+                cd_media_dvd_rw_seq = 1;
+                break;
+        case 0x1B:
+                log_debug("profile 0x%02x media_dvd_plus_r\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_plus_r = 1;
+                break;
+        case 0x1A:
+                log_debug("profile 0x%02x media_dvd_plus_rw\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_plus_rw = 1;
+                break;
+        case 0x2A:
+                log_debug("profile 0x%02x media_dvd_plus_rw_dl\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_plus_rw_dl = 1;
+                break;
+        case 0x2B:
+                log_debug("profile 0x%02x media_dvd_plus_r_dl\n", cur_profile);
+                cd_media = 1;
+                cd_media_dvd_plus_r_dl = 1;
+                break;
+        case 0x40:
+                log_debug("profile 0x%02x media_bd\n", cur_profile);
+                cd_media = 1;
+                cd_media_bd = 1;
+                break;
+        case 0x41:
+        case 0x42:
+                log_debug("profile 0x%02x media_bd_r\n", cur_profile);
+                cd_media = 1;
+                cd_media_bd_r = 1;
+                break;
+        case 0x43:
+                log_debug("profile 0x%02x media_bd_re\n", cur_profile);
+                cd_media = 1;
+                cd_media_bd_re = 1;
+                break;
+        case 0x50:
+                log_debug("profile 0x%02x media_hddvd\n", cur_profile);
+                cd_media = 1;
+                cd_media_hddvd = 1;
+                break;
+        case 0x51:
+                log_debug("profile 0x%02x media_hddvd_r\n", cur_profile);
+                cd_media = 1;
+                cd_media_hddvd_r = 1;
+                break;
+        case 0x52:
+                log_debug("profile 0x%02x media_hddvd_rw\n", cur_profile);
+                cd_media = 1;
+                cd_media_hddvd_rw = 1;
+                break;
+        default:
+                log_debug("profile 0x%02x <ignored>\n", cur_profile);
+                break;
+        }
+}
+
+static int feature_profiles(struct udev *udev, const unsigned char *profiles, size_t size)
+{
+        unsigned int i;
+
+        for (i = 0; i+4 <= size; i += 4) {
+                int profile;
+
+                profile = profiles[i] << 8 | profiles[i+1];
+                switch (profile) {
+                case 0x03:
+                case 0x04:
+                case 0x05:
+                        log_debug("profile 0x%02x mo\n", profile);
+                        cd_mo = 1;
+                        break;
+                case 0x08:
+                        log_debug("profile 0x%02x cd_rom\n", profile);
+                        cd_cd_rom = 1;
+                        break;
+                case 0x09:
+                        log_debug("profile 0x%02x cd_r\n", profile);
+                        cd_cd_r = 1;
+                        break;
+                case 0x0A:
+                        log_debug("profile 0x%02x cd_rw\n", profile);
+                        cd_cd_rw = 1;
+                        break;
+                case 0x10:
+                        log_debug("profile 0x%02x dvd_rom\n", profile);
+                        cd_dvd_rom = 1;
+                        break;
+                case 0x12:
+                        log_debug("profile 0x%02x dvd_ram\n", profile);
+                        cd_dvd_ram = 1;
+                        break;
+                case 0x13:
+                case 0x14:
+                        log_debug("profile 0x%02x dvd_rw\n", profile);
+                        cd_dvd_rw = 1;
+                        break;
+                case 0x1B:
+                        log_debug("profile 0x%02x dvd_plus_r\n", profile);
+                        cd_dvd_plus_r = 1;
+                        break;
+                case 0x1A:
+                        log_debug("profile 0x%02x dvd_plus_rw\n", profile);
+                        cd_dvd_plus_rw = 1;
+                        break;
+                case 0x2A:
+                        log_debug("profile 0x%02x dvd_plus_rw_dl\n", profile);
+                        cd_dvd_plus_rw_dl = 1;
+                        break;
+                case 0x2B:
+                        log_debug("profile 0x%02x dvd_plus_r_dl\n", profile);
+                        cd_dvd_plus_r_dl = 1;
+                        break;
+                case 0x40:
+                        cd_bd = 1;
+                        log_debug("profile 0x%02x bd\n", profile);
+                        break;
+                case 0x41:
+                case 0x42:
+                        cd_bd_r = 1;
+                        log_debug("profile 0x%02x bd_r\n", profile);
+                        break;
+                case 0x43:
+                        cd_bd_re = 1;
+                        log_debug("profile 0x%02x bd_re\n", profile);
+                        break;
+                case 0x50:
+                        cd_hddvd = 1;
+                        log_debug("profile 0x%02x hddvd\n", profile);
+                        break;
+                case 0x51:
+                        cd_hddvd_r = 1;
+                        log_debug("profile 0x%02x hddvd_r\n", profile);
+                        break;
+                case 0x52:
+                        cd_hddvd_rw = 1;
+                        log_debug("profile 0x%02x hddvd_rw\n", profile);
+                        break;
+                default:
+                        log_debug("profile 0x%02x <ignored>\n", profile);
+                        break;
+                }
+        }
+        return 0;
+}
+
+/* returns 0 if media was detected */
+static int cd_profiles_old_mmc(struct udev *udev, int fd)
+{
+        struct scsi_cmd sc;
+        int err;
+
+        unsigned char header[32];
+
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x51);
+        scsi_cmd_set(udev, &sc, 8, sizeof(header));
+        scsi_cmd_set(udev, &sc, 9, 0);
+        err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header));
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "READ DISC INFORMATION", err);
+                if (cd_media == 1) {
+                        log_debug("no current profile, but disc is present; assuming CD-ROM\n");
+                        cd_media_cd_rom = 1;
+                        return 0;
+                } else {
+                        log_debug("no current profile, assuming no media\n");
+                        return -1;
+                }
+        };
+
+        cd_media = 1;
+
+        if (header[2] & 16) {
+                cd_media_cd_rw = 1;
+                log_debug("profile 0x0a media_cd_rw\n");
+        } else if ((header[2] & 3) < 2 && cd_cd_r) {
+                cd_media_cd_r = 1;
+                log_debug("profile 0x09 media_cd_r\n");
+        } else {
+                cd_media_cd_rom = 1;
+                log_debug("profile 0x08 media_cd_rom\n");
+        }
+        return 0;
+}
+
+/* returns 0 if media was detected */
+static int cd_profiles(struct udev *udev, int fd)
+{
+        struct scsi_cmd sc;
+        unsigned char features[65530];
+        unsigned int cur_profile = 0;
+        unsigned int len;
+        unsigned int i;
+        int err;
+        int ret;
+
+        ret = -1;
+
+        /* First query the current profile */
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x46);
+        scsi_cmd_set(udev, &sc, 8, 8);
+        scsi_cmd_set(udev, &sc, 9, 0);
+        err = scsi_cmd_run(udev, &sc, fd, features, 8);
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "GET CONFIGURATION", err);
+                /* handle pre-MMC2 drives which do not support GET CONFIGURATION */
+                if (SK(err) == 0x5 && ASC(err) == 0x20) {
+                        log_debug("drive is pre-MMC2 and does not support 46h get configuration command\n");
+                        log_debug("trying to work around the problem\n");
+                        ret = cd_profiles_old_mmc(udev, fd);
+                }
+                goto out;
+        }
+
+        cur_profile = features[6] << 8 | features[7];
+        if (cur_profile > 0) {
+                log_debug("current profile 0x%02x\n", cur_profile);
+                feature_profile_media (udev, cur_profile);
+                ret = 0; /* we have media */
+        } else {
+                log_debug("no current profile, assuming no media\n");
+        }
+
+        len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3];
+        log_debug("GET CONFIGURATION: size of features buffer 0x%04x\n", len);
+
+        if (len > sizeof(features)) {
+                log_debug("can not get features in a single query, truncating\n");
+                len = sizeof(features);
+        } else if (len <= 8) {
+                len = sizeof(features);
+        }
+
+        /* Now get the full feature buffer */
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x46);
+        scsi_cmd_set(udev, &sc, 7, ( len >> 8 ) & 0xff);
+        scsi_cmd_set(udev, &sc, 8, len & 0xff);
+        scsi_cmd_set(udev, &sc, 9, 0);
+        err = scsi_cmd_run(udev, &sc, fd, features, len);
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "GET CONFIGURATION", err);
+                return -1;
+        }
+
+        /* parse the length once more, in case the drive decided to have other features suddenly :) */
+        len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3];
+        log_debug("GET CONFIGURATION: size of features buffer 0x%04x\n", len);
+
+        if (len > sizeof(features)) {
+                log_debug("can not get features in a single query, truncating\n");
+                len = sizeof(features);
+        }
+
+        /* device features */
+        for (i = 8; i+4 < len; i += (4 + features[i+3])) {
+                unsigned int feature;
+
+                feature = features[i] << 8 | features[i+1];
+
+                switch (feature) {
+                case 0x00:
+                        log_debug("GET CONFIGURATION: feature 'profiles', with %i entries\n", features[i+3] / 4);
+                        feature_profiles(udev, &features[i]+4, features[i+3]);
+                        break;
+                default:
+                        log_debug("GET CONFIGURATION: feature 0x%04x <ignored>, with 0x%02x bytes\n", feature, features[i+3]);
+                        break;
+                }
+        }
+out:
+        return ret;
+}
+
+static int cd_media_info(struct udev *udev, int fd)
+{
+        struct scsi_cmd sc;
+        unsigned char header[32];
+        static const char *media_status[] = {
+                "blank",
+                "appendable",
+                "complete",
+                "other"
+        };
+        int err;
+
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x51);
+        scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff);
+        scsi_cmd_set(udev, &sc, 9, 0);
+        err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header));
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "READ DISC INFORMATION", err);
+                return -1;
+        };
+
+        cd_media = 1;
+        log_debug("disk type %02x\n", header[8]);
+        log_debug("hardware reported media status: %s\n", media_status[header[2] & 3]);
+
+        /* exclude plain CDROM, some fake cdroms return 0 for "blank" media here */
+        if (!cd_media_cd_rom)
+                cd_media_state = media_status[header[2] & 3];
+
+        /* fresh DVD-RW in restricted overwite mode reports itself as
+         * "appendable"; change it to "blank" to make it consistent with what
+         * gets reported after blanking, and what userspace expects  */
+        if (cd_media_dvd_rw_ro && (header[2] & 3) == 1)
+                cd_media_state = media_status[0];
+
+        /* DVD+RW discs (and DVD-RW in restricted mode) once formatted are
+         * always "complete", DVD-RAM are "other" or "complete" if the disc is
+         * write protected; we need to check the contents if it is blank */
+        if ((cd_media_dvd_rw_ro || cd_media_dvd_plus_rw || cd_media_dvd_plus_rw_dl || cd_media_dvd_ram) && (header[2] & 3) > 1) {
+                unsigned char buffer[32 * 2048];
+                unsigned char result, len;
+                int block, offset;
+
+                if (cd_media_dvd_ram) {
+                        /* a write protected dvd-ram may report "complete" status */
+
+                        unsigned char dvdstruct[8];
+                        unsigned char format[12];
+
+                        scsi_cmd_init(udev, &sc);
+                        scsi_cmd_set(udev, &sc, 0, 0xAD);
+                        scsi_cmd_set(udev, &sc, 7, 0xC0);
+                        scsi_cmd_set(udev, &sc, 9, sizeof(dvdstruct));
+                        scsi_cmd_set(udev, &sc, 11, 0);
+                        err = scsi_cmd_run(udev, &sc, fd, dvdstruct, sizeof(dvdstruct));
+                        if ((err != 0)) {
+                                info_scsi_cmd_err(udev, "READ DVD STRUCTURE", err);
+                                return -1;
+                        }
+                        if (dvdstruct[4] & 0x02) {
+                                cd_media_state = media_status[2];
+                                log_debug("write-protected DVD-RAM media inserted\n");
+                                goto determined;
+                        }
+
+                        /* let's make sure we don't try to read unformatted media */
+                        scsi_cmd_init(udev, &sc);
+                        scsi_cmd_set(udev, &sc, 0, 0x23);
+                        scsi_cmd_set(udev, &sc, 8, sizeof(format));
+                        scsi_cmd_set(udev, &sc, 9, 0);
+                        err = scsi_cmd_run(udev, &sc, fd, format, sizeof(format));
+                        if ((err != 0)) {
+                                info_scsi_cmd_err(udev, "READ DVD FORMAT CAPACITIES", err);
+                                return -1;
+                        }
+
+                        len = format[3];
+                        if (len & 7 || len < 16) {
+                                log_debug("invalid format capacities length\n");
+                                return -1;
+                        }
+
+                        switch(format[8] & 3) {
+                            case 1:
+                                log_debug("unformatted DVD-RAM media inserted\n");
+                                /* This means that last format was interrupted
+                                 * or failed, blank dvd-ram discs are factory
+                                 * formatted. Take no action here as it takes
+                                 * quite a while to reformat a dvd-ram and it's
+                                 * not automatically started */
+                                goto determined;
+
+                            case 2:
+                                log_debug("formatted DVD-RAM media inserted\n");
+                                break;
+
+                            case 3:
+                                cd_media = 0; //return no media
+                                log_debug("format capacities returned no media\n");
+                                return -1;
+                        }
+                }
+
+                /* Take a closer look at formatted media (unformatted DVD+RW
+                 * has "blank" status", DVD-RAM was examined earlier) and check
+                 * for ISO and UDF PVDs or a fs superblock presence and do it
+                 * in one ioctl (we need just sectors 0 and 16) */
+                scsi_cmd_init(udev, &sc);
+                scsi_cmd_set(udev, &sc, 0, 0x28);
+                scsi_cmd_set(udev, &sc, 5, 0);
+                scsi_cmd_set(udev, &sc, 8, 32);
+                scsi_cmd_set(udev, &sc, 9, 0);
+                err = scsi_cmd_run(udev, &sc, fd, buffer, sizeof(buffer));
+                if ((err != 0)) {
+                        cd_media = 0;
+                        info_scsi_cmd_err(udev, "READ FIRST 32 BLOCKS", err);
+                        return -1;
+                }
+
+                /* if any non-zero data is found in sector 16 (iso and udf) or
+                 * eventually 0 (fat32 boot sector, ext2 superblock, etc), disc
+                 * is assumed non-blank */
+                result = 0;
+
+                for (block = 32768; block >= 0 && !result; block -= 32768) {
+                        offset = block;
+                        while (offset < (block + 2048) && !result) {
+                                result = buffer [offset];
+                                offset++;
+                        }
+                }
+
+                if (!result) {
+                        cd_media_state = media_status[0];
+                        log_debug("no data in blocks 0 or 16, assuming blank\n");
+                } else {
+                        log_debug("data in blocks 0 or 16, assuming complete\n");
+                }
+        }
+
+determined:
+        /* "other" is e. g. DVD-RAM, can't append sessions there; DVDs in
+         * restricted overwrite mode can never append, only in sequential mode */
+        if ((header[2] & 3) < 2 && !cd_media_dvd_rw_ro)
+                cd_media_session_next = header[10] << 8 | header[5];
+        cd_media_session_count = header[9] << 8 | header[4];
+        cd_media_track_count = header[11] << 8 | header[6];
+
+        return 0;
+}
+
+static int cd_media_toc(struct udev *udev, int fd)
+{
+        struct scsi_cmd sc;
+        unsigned char header[12];
+        unsigned char toc[65536];
+        unsigned int len, i, num_tracks;
+        unsigned char *p;
+        int err;
+
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x43);
+        scsi_cmd_set(udev, &sc, 6, 1);
+        scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff);
+        scsi_cmd_set(udev, &sc, 9, 0);
+        err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header));
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "READ TOC", err);
+                return -1;
+        }
+
+        len = (header[0] << 8 | header[1]) + 2;
+        log_debug("READ TOC: len: %d, start track: %d, end track: %d\n", len, header[2], header[3]);
+        if (len > sizeof(toc))
+                return -1;
+        if (len < 2)
+                return -1;
+        /* 2: first track, 3: last track */
+        num_tracks = header[3] - header[2] + 1;
+
+        /* empty media has no tracks */
+        if (len < 8)
+                return 0;
+
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x43);
+        scsi_cmd_set(udev, &sc, 6, header[2]); /* First Track/Session Number */
+        scsi_cmd_set(udev, &sc, 7, (len >> 8) & 0xff);
+        scsi_cmd_set(udev, &sc, 8, len & 0xff);
+        scsi_cmd_set(udev, &sc, 9, 0);
+        err = scsi_cmd_run(udev, &sc, fd, toc, len);
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "READ TOC (tracks)", err);
+                return -1;
+        }
+
+        /* Take care to not iterate beyond the last valid track as specified in
+         * the TOC, but also avoid going beyond the TOC length, just in case
+         * the last track number is invalidly large */
+        for (p = toc+4, i = 4; i < len-8 && num_tracks > 0; i += 8, p += 8, --num_tracks) {
+                unsigned int block;
+                unsigned int is_data_track;
+
+                is_data_track = (p[1] & 0x04) != 0;
+
+                block = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7];
+                log_debug("track=%u info=0x%x(%s) start_block=%u\n",
+                     p[2], p[1] & 0x0f, is_data_track ? "data":"audio", block);
+
+                if (is_data_track)
+                        cd_media_track_count_data++;
+                else
+                        cd_media_track_count_audio++;
+        }
+
+        scsi_cmd_init(udev, &sc);
+        scsi_cmd_set(udev, &sc, 0, 0x43);
+        scsi_cmd_set(udev, &sc, 2, 1); /* Session Info */
+        scsi_cmd_set(udev, &sc, 8, sizeof(header));
+        scsi_cmd_set(udev, &sc, 9, 0);
+        err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header));
+        if ((err != 0)) {
+                info_scsi_cmd_err(udev, "READ TOC (multi session)", err);
+                return -1;
+        }
+        len = header[4+4] << 24 | header[4+5] << 16 | header[4+6] << 8 | header[4+7];
+        log_debug("last track %u starts at block %u\n", header[4+2], len);
+        cd_media_session_last_offset = (unsigned long long int)len * 2048;
+        return 0;
+}
+
+int main(int argc, char *argv[])
+{
+        struct udev *udev;
+        static const struct option options[] = {
+                { "lock-media", no_argument, NULL, 'l' },
+                { "unlock-media", no_argument, NULL, 'u' },
+                { "eject-media", no_argument, NULL, 'e' },
+                { "debug", no_argument, NULL, 'd' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+        bool eject = false;
+        bool lock = false;
+        bool unlock = false;
+        const char *node = NULL;
+        int fd = -1;
+        int cnt;
+        int rc = 0;
+
+        udev = udev_new();
+        if (udev == NULL)
+                goto exit;
+
+        log_open();
+        udev_set_log_fn(udev, log_fn);
+
+        while (1) {
+                int option;
+
+                option = getopt_long(argc, argv, "deluh", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'l':
+                        lock = true;
+                        break;
+                case 'u':
+                        unlock = true;
+                        break;
+                case 'e':
+                        eject = true;
+                        break;
+                case 'd':
+                        debug = true;
+                        log_set_max_level(LOG_DEBUG);
+                        udev_set_log_priority(udev, LOG_DEBUG);
+                        break;
+                case 'h':
+                        printf("Usage: cdrom_id [options] <device>\n"
+                               "  --lock-media    lock the media (to enable eject request events)\n"
+                               "  --unlock-media  unlock the media\n"
+                               "  --eject-media   eject the media\n"
+                               "  --debug         debug to stderr\n"
+                               "  --help          print this help text\n\n");
+                        goto exit;
+                default:
+                        rc = 1;
+                        goto exit;
+                }
+        }
+
+        node = argv[optind];
+        if (!node) {
+                log_error("no device\n");
+                fprintf(stderr, "no device\n");
+                rc = 1;
+                goto exit;
+        }
+
+        srand((unsigned int)getpid());
+        for (cnt = 20; cnt > 0; cnt--) {
+                struct timespec duration;
+
+                fd = open(node, O_RDONLY|O_NONBLOCK|(is_mounted(node) ? 0 : O_EXCL));
+                if (fd >= 0 || errno != EBUSY)
+                        break;
+                duration.tv_sec = 0;
+                duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000);
+                nanosleep(&duration, NULL);
+        }
+        if (fd < 0) {
+                log_debug("unable to open '%s'\n", node);
+                fprintf(stderr, "unable to open '%s'\n", node);
+                rc = 1;
+                goto exit;
+        }
+        log_debug("probing: '%s'\n", node);
+
+        /* same data as original cdrom_id */
+        if (cd_capability_compat(udev, fd) < 0) {
+                rc = 1;
+                goto exit;
+        }
+
+        /* check for media - don't bail if there's no media as we still need to
+         * to read profiles */
+        cd_media_compat(udev, fd);
+
+        /* check if drive talks MMC */
+        if (cd_inquiry(udev, fd) < 0)
+                goto work;
+
+        /* read drive and possibly current profile */
+        if (cd_profiles(udev, fd) != 0)
+                goto work;
+
+        /* at this point we are guaranteed to have media in the drive - find out more about it */
+
+        /* get session/track info */
+        cd_media_toc(udev, fd);
+
+        /* get writable media state */
+        cd_media_info(udev, fd);
+
+work:
+        /* lock the media, so we enable eject button events */
+        if (lock && cd_media) {
+                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)\n");
+                media_lock(udev, fd, true);
+        }
+
+        if (unlock && cd_media) {
+                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n");
+                media_lock(udev, fd, false);
+        }
+
+        if (eject) {
+                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n");
+                media_lock(udev, fd, false);
+                log_debug("START_STOP_UNIT (eject)\n");
+                media_eject(udev, fd);
+        }
+
+        printf("ID_CDROM=1\n");
+        if (cd_cd_rom)
+                printf("ID_CDROM_CD=1\n");
+        if (cd_cd_r)
+                printf("ID_CDROM_CD_R=1\n");
+        if (cd_cd_rw)
+                printf("ID_CDROM_CD_RW=1\n");
+        if (cd_dvd_rom)
+                printf("ID_CDROM_DVD=1\n");
+        if (cd_dvd_r)
+                printf("ID_CDROM_DVD_R=1\n");
+        if (cd_dvd_rw)
+                printf("ID_CDROM_DVD_RW=1\n");
+        if (cd_dvd_ram)
+                printf("ID_CDROM_DVD_RAM=1\n");
+        if (cd_dvd_plus_r)
+                printf("ID_CDROM_DVD_PLUS_R=1\n");
+        if (cd_dvd_plus_rw)
+                printf("ID_CDROM_DVD_PLUS_RW=1\n");
+        if (cd_dvd_plus_r_dl)
+                printf("ID_CDROM_DVD_PLUS_R_DL=1\n");
+        if (cd_dvd_plus_rw_dl)
+                printf("ID_CDROM_DVD_PLUS_RW_DL=1\n");
+        if (cd_bd)
+                printf("ID_CDROM_BD=1\n");
+        if (cd_bd_r)
+                printf("ID_CDROM_BD_R=1\n");
+        if (cd_bd_re)
+                printf("ID_CDROM_BD_RE=1\n");
+        if (cd_hddvd)
+                printf("ID_CDROM_HDDVD=1\n");
+        if (cd_hddvd_r)
+                printf("ID_CDROM_HDDVD_R=1\n");
+        if (cd_hddvd_rw)
+                printf("ID_CDROM_HDDVD_RW=1\n");
+        if (cd_mo)
+                printf("ID_CDROM_MO=1\n");
+        if (cd_mrw)
+                printf("ID_CDROM_MRW=1\n");
+        if (cd_mrw_w)
+                printf("ID_CDROM_MRW_W=1\n");
+
+        if (cd_media)
+                printf("ID_CDROM_MEDIA=1\n");
+        if (cd_media_mo)
+                printf("ID_CDROM_MEDIA_MO=1\n");
+        if (cd_media_mrw)
+                printf("ID_CDROM_MEDIA_MRW=1\n");
+        if (cd_media_mrw_w)
+                printf("ID_CDROM_MEDIA_MRW_W=1\n");
+        if (cd_media_cd_rom)
+                printf("ID_CDROM_MEDIA_CD=1\n");
+        if (cd_media_cd_r)
+                printf("ID_CDROM_MEDIA_CD_R=1\n");
+        if (cd_media_cd_rw)
+                printf("ID_CDROM_MEDIA_CD_RW=1\n");
+        if (cd_media_dvd_rom)
+                printf("ID_CDROM_MEDIA_DVD=1\n");
+        if (cd_media_dvd_r)
+                printf("ID_CDROM_MEDIA_DVD_R=1\n");
+        if (cd_media_dvd_ram)
+                printf("ID_CDROM_MEDIA_DVD_RAM=1\n");
+        if (cd_media_dvd_rw)
+                printf("ID_CDROM_MEDIA_DVD_RW=1\n");
+        if (cd_media_dvd_plus_r)
+                printf("ID_CDROM_MEDIA_DVD_PLUS_R=1\n");
+        if (cd_media_dvd_plus_rw)
+                printf("ID_CDROM_MEDIA_DVD_PLUS_RW=1\n");
+        if (cd_media_dvd_plus_rw_dl)
+                printf("ID_CDROM_MEDIA_DVD_PLUS_RW_DL=1\n");
+        if (cd_media_dvd_plus_r_dl)
+                printf("ID_CDROM_MEDIA_DVD_PLUS_R_DL=1\n");
+        if (cd_media_bd)
+                printf("ID_CDROM_MEDIA_BD=1\n");
+        if (cd_media_bd_r)
+                printf("ID_CDROM_MEDIA_BD_R=1\n");
+        if (cd_media_bd_re)
+                printf("ID_CDROM_MEDIA_BD_RE=1\n");
+        if (cd_media_hddvd)
+                printf("ID_CDROM_MEDIA_HDDVD=1\n");
+        if (cd_media_hddvd_r)
+                printf("ID_CDROM_MEDIA_HDDVD_R=1\n");
+        if (cd_media_hddvd_rw)
+                printf("ID_CDROM_MEDIA_HDDVD_RW=1\n");
+
+        if (cd_media_state != NULL)
+                printf("ID_CDROM_MEDIA_STATE=%s\n", cd_media_state);
+        if (cd_media_session_next > 0)
+                printf("ID_CDROM_MEDIA_SESSION_NEXT=%d\n", cd_media_session_next);
+        if (cd_media_session_count > 0)
+                printf("ID_CDROM_MEDIA_SESSION_COUNT=%d\n", cd_media_session_count);
+        if (cd_media_session_count > 1 && cd_media_session_last_offset > 0)
+                printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset);
+        if (cd_media_track_count > 0)
+                printf("ID_CDROM_MEDIA_TRACK_COUNT=%d\n", cd_media_track_count);
+        if (cd_media_track_count_audio > 0)
+                printf("ID_CDROM_MEDIA_TRACK_COUNT_AUDIO=%d\n", cd_media_track_count_audio);
+        if (cd_media_track_count_data > 0)
+                printf("ID_CDROM_MEDIA_TRACK_COUNT_DATA=%d\n", cd_media_track_count_data);
+exit:
+        if (fd >= 0)
+                close(fd);
+        udev_unref(udev);
+        log_close();
+        return rc;
+}
diff --git a/src/udev/collect/collect.c b/src/udev/collect/collect.c
new file mode 100644 (file)
index 0000000..3c46e40
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+ * Collect variables across events.
+ *
+ * usage: collect [--add|--remove] <checkpoint> <id> <idlist>
+ *
+ * Adds ID <id> to the list governed by <checkpoint>.
+ * <id> must be part of the ID list <idlist>.
+ * If all IDs given by <idlist> are listed (ie collect has been
+ * invoked for each ID in <idlist>) collect returns 0, the
+ * number of missing IDs otherwise.
+ * A negative number is returned on error.
+ *
+ * Copyright(C) 2007, 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+#include "macro.h"
+
+#define BUFSIZE                        16
+#define UDEV_ALARM_TIMEOUT        180
+
+enum collect_state {
+        STATE_NONE,
+        STATE_OLD,
+        STATE_CONFIRMED,
+};
+
+struct _mate {
+        struct udev_list_node node;
+        char *name;
+        enum collect_state state;
+};
+
+static struct udev_list_node bunch;
+static int debug;
+
+/* This can increase dynamically */
+static size_t bufsize = BUFSIZE;
+
+static inline struct _mate *node_to_mate(struct udev_list_node *node)
+{
+        return container_of(node, struct _mate, node);
+}
+
+_noreturn_ static void sig_alrm(int signo)
+{
+        exit(4);
+}
+
+static void usage(void)
+{
+        printf("usage: collect [--add|--remove] [--debug] <checkpoint> <id> <idlist>\n"
+               "\n"
+               "  Adds ID <id> to the list governed by <checkpoint>.\n"
+               "  <id> must be part of the list <idlist>.\n"
+               "  If all IDs given by <idlist> are listed (ie collect has been\n"
+               "  invoked for each ID in <idlist>) collect returns 0, the\n"
+               "  number of missing IDs otherwise.\n"
+               "  On error a negative number is returned.\n"
+               "\n");
+}
+
+/*
+ * prepare
+ *
+ * Prepares the database file
+ */
+static int prepare(char *dir, char *filename)
+{
+        struct stat statbuf;
+        char buf[512];
+        int fd;
+
+        if (stat(dir, &statbuf) < 0)
+                mkdir(dir, 0700);
+
+        snprintf(buf, sizeof(buf), "%s/%s", dir, filename);
+
+        fd = open(buf,O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
+        if (fd < 0)
+                fprintf(stderr, "Cannot open %s: %s\n", buf, strerror(errno));
+
+        if (lockf(fd,F_TLOCK,0) < 0) {
+                if (debug)
+                        fprintf(stderr, "Lock taken, wait for %d seconds\n", UDEV_ALARM_TIMEOUT);
+                if (errno == EAGAIN || errno == EACCES) {
+                        alarm(UDEV_ALARM_TIMEOUT);
+                        lockf(fd, F_LOCK, 0);
+                        if (debug)
+                                fprintf(stderr, "Acquired lock on %s\n", buf);
+                } else {
+                        if (debug)
+                                fprintf(stderr, "Could not get lock on %s: %s\n", buf, strerror(errno));
+                }
+        }
+
+        return fd;
+}
+
+/*
+ * Read checkpoint file
+ *
+ * Tricky reading this. We allocate a buffer twice as large
+ * as we're going to read. Then we read into the upper half
+ * of that buffer and start parsing.
+ * Once we do _not_ find end-of-work terminator (whitespace
+ * character) we move the upper half to the lower half,
+ * adjust the read pointer and read the next bit.
+ * Quite clever methinks :-)
+ * I should become a programmer ...
+ *
+ * Yes, one could have used fgets() for this. But then we'd
+ * have to use freopen etc which I found quite tedious.
+ */
+static int checkout(int fd)
+{
+        int len;
+        char *buf, *ptr, *word = NULL;
+        struct _mate *him;
+
+ restart:
+        len = bufsize >> 1;
+        buf = calloc(1,bufsize + 1);
+        if (!buf) {
+                fprintf(stderr, "Out of memory.\n");
+                return log_oom();
+        }
+        memset(buf, ' ', bufsize);
+        ptr = buf + len;
+        while ((read(fd, buf + len, len)) > 0) {
+                while (ptr && *ptr) {
+                        word = ptr;
+                        ptr = strpbrk(word," \n\t\r");
+                        if (!ptr && word < (buf + len)) {
+                                bufsize = bufsize << 1;
+                                if (debug)
+                                        fprintf(stderr, "ID overflow, restarting with size %zi\n", bufsize);
+                                free(buf);
+                                lseek(fd, 0, SEEK_SET);
+                                goto restart;
+                        }
+                        if (ptr) {
+                                *ptr = '\0';
+                                ptr++;
+                                if (!strlen(word))
+                                        continue;
+
+                                if (debug)
+                                        fprintf(stderr, "Found word %s\n", word);
+                                him = malloc(sizeof (struct _mate));
+                                if (!him) {
+                                        free(buf);
+                                        return log_oom();
+                                }
+                                him->name = strdup(word);
+                                if (!him->name) {
+                                        free(buf);
+                                        free(him);
+                                        return log_oom();
+                                }
+                                him->state = STATE_OLD;
+                                udev_list_node_append(&him->node, &bunch);
+                                word = NULL;
+                        }
+                }
+                memcpy(buf, buf + len, len);
+                memset(buf + len, ' ', len);
+
+                if (!ptr)
+                        ptr = word;
+                if (!ptr)
+                        break;
+                ptr -= len;
+        }
+
+        free(buf);
+        return 0;
+}
+
+/*
+ * invite
+ *
+ * Adds a new ID 'us' to the internal list,
+ * marks it as confirmed.
+ */
+static void invite(char *us)
+{
+        struct udev_list_node *him_node;
+        struct _mate *who = NULL;
+
+        if (debug)
+                fprintf(stderr, "Adding ID '%s'\n", us);
+
+        udev_list_node_foreach(him_node, &bunch) {
+                struct _mate *him = node_to_mate(him_node);
+
+                if (!strcmp(him->name, us)) {
+                        him->state = STATE_CONFIRMED;
+                        who = him;
+                }
+        }
+        if (debug && !who)
+                fprintf(stderr, "ID '%s' not in database\n", us);
+
+}
+
+/*
+ * reject
+ *
+ * Marks the ID 'us' as invalid,
+ * causing it to be removed when the
+ * list is written out.
+ */
+static void reject(char *us)
+{
+        struct udev_list_node *him_node;
+        struct _mate *who = NULL;
+
+        if (debug)
+                fprintf(stderr, "Removing ID '%s'\n", us);
+
+        udev_list_node_foreach(him_node, &bunch) {
+                struct _mate *him = node_to_mate(him_node);
+
+                if (!strcmp(him->name, us)) {
+                        him->state = STATE_NONE;
+                        who = him;
+                }
+        }
+        if (debug && !who)
+                fprintf(stderr, "ID '%s' not in database\n", us);
+}
+
+/*
+ * kickout
+ *
+ * Remove all IDs in the internal list which are not part
+ * of the list passed via the commandline.
+ */
+static void kickout(void)
+{
+        struct udev_list_node *him_node;
+        struct udev_list_node *tmp;
+
+        udev_list_node_foreach_safe(him_node, tmp, &bunch) {
+                struct _mate *him = node_to_mate(him_node);
+
+                if (him->state == STATE_OLD) {
+                        udev_list_node_remove(&him->node);
+                        free(him->name);
+                        free(him);
+                }
+        }
+}
+
+/*
+ * missing
+ *
+ * Counts all missing IDs in the internal list.
+ */
+static int missing(int fd)
+{
+        char *buf;
+        int ret = 0;
+        struct udev_list_node *him_node;
+
+        buf = malloc(bufsize);
+        if (!buf)
+                return log_oom();
+
+        udev_list_node_foreach(him_node, &bunch) {
+                struct _mate *him = node_to_mate(him_node);
+
+                if (him->state == STATE_NONE) {
+                        ret++;
+                } else {
+                        while (strlen(him->name)+1 >= bufsize) {
+                                char *tmpbuf;
+
+                                bufsize = bufsize << 1;
+                                tmpbuf = realloc(buf, bufsize);
+                                if (!tmpbuf) {
+                                        free(buf);
+                                        return log_oom();
+                                }
+                                buf = tmpbuf;
+                        }
+                        snprintf(buf, strlen(him->name)+2, "%s ", him->name);
+                        if (write(fd, buf, strlen(buf)) < 0) {
+                                free(buf);
+                                return -1;
+                        }
+                }
+        }
+
+        free(buf);
+        return ret;
+}
+
+/*
+ * everybody
+ *
+ * Prints out the status of the internal list.
+ */
+static void everybody(void)
+{
+        struct udev_list_node *him_node;
+        const char *state = "";
+
+        udev_list_node_foreach(him_node, &bunch) {
+                struct _mate *him = node_to_mate(him_node);
+
+                switch (him->state) {
+                case STATE_NONE:
+                        state = "none";
+                        break;
+                case STATE_OLD:
+                        state = "old";
+                        break;
+                case STATE_CONFIRMED:
+                        state = "confirmed";
+                        break;
+                }
+                fprintf(stderr, "ID: %s=%s\n", him->name, state);
+        }
+}
+
+int main(int argc, char **argv)
+{
+        struct udev *udev;
+        static const struct option options[] = {
+                { "add", no_argument, NULL, 'a' },
+                { "remove", no_argument, NULL, 'r' },
+                { "debug", no_argument, NULL, 'd' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+        int argi;
+        char *checkpoint, *us;
+        int fd;
+        int i;
+        int ret = EXIT_SUCCESS;
+        int prune = 0;
+        char tmpdir[UTIL_PATH_SIZE];
+
+        udev = udev_new();
+        if (udev == NULL) {
+                ret = EXIT_FAILURE;
+                goto exit;
+        }
+
+        while (1) {
+                int option;
+
+                option = getopt_long(argc, argv, "ardh", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'a':
+                        prune = 0;
+                        break;
+                case 'r':
+                        prune = 1;
+                        break;
+                case 'd':
+                        debug = 1;
+                        break;
+                case 'h':
+                        usage();
+                        goto exit;
+                default:
+                        ret = 1;
+                        goto exit;
+                }
+        }
+
+        argi = optind;
+        if (argi + 2 > argc) {
+                printf("Missing parameter(s)\n");
+                ret = 1;
+                goto exit;
+        }
+        checkpoint = argv[argi++];
+        us = argv[argi++];
+
+        if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
+                fprintf(stderr, "Cannot set SIGALRM: %s\n", strerror(errno));
+                ret = 2;
+                goto exit;
+        }
+
+        udev_list_node_init(&bunch);
+
+        if (debug)
+                fprintf(stderr, "Using checkpoint '%s'\n", checkpoint);
+
+        util_strscpyl(tmpdir, sizeof(tmpdir), "/run/udev/collect", NULL);
+        fd = prepare(tmpdir, checkpoint);
+        if (fd < 0) {
+                ret = 3;
+                goto out;
+        }
+
+        if (checkout(fd) < 0) {
+                ret = 2;
+                goto out;
+        }
+
+        for (i = argi; i < argc; i++) {
+                struct udev_list_node *him_node;
+                struct _mate *who;
+
+                who = NULL;
+                udev_list_node_foreach(him_node, &bunch) {
+                        struct _mate *him = node_to_mate(him_node);
+
+                        if (!strcmp(him->name, argv[i]))
+                                who = him;
+                }
+                if (!who) {
+                        struct _mate *him;
+
+                        if (debug)
+                                fprintf(stderr, "ID %s: not in database\n", argv[i]);
+                        him = malloc(sizeof (struct _mate));
+                        if (!him) {
+                                ret = ENOMEM;
+                                goto out;
+                        }
+
+                        him->name = malloc(strlen(argv[i]) + 1);
+                        if (!him->name) {
+                                ret = ENOMEM;
+                                goto out;
+                        }
+
+                        strcpy(him->name, argv[i]);
+                        him->state = STATE_NONE;
+                        udev_list_node_append(&him->node, &bunch);
+                } else {
+                        if (debug)
+                                fprintf(stderr, "ID %s: found in database\n", argv[i]);
+                        who->state = STATE_CONFIRMED;
+                }
+        }
+
+        if (prune)
+                reject(us);
+        else
+                invite(us);
+
+        if (debug) {
+                everybody();
+                fprintf(stderr, "Prune lists\n");
+        }
+        kickout();
+
+        lseek(fd, 0, SEEK_SET);
+        ftruncate(fd, 0);
+        ret = missing(fd);
+
+        lockf(fd, F_ULOCK, 0);
+        close(fd);
+out:
+        if (debug)
+                everybody();
+        if (ret >= 0)
+                printf("COLLECT_%s=%d\n", checkpoint, ret);
+exit:
+        udev_unref(udev);
+        return ret;
+}
diff --git a/src/udev/keymap/.gitignore b/src/udev/keymap/.gitignore
new file mode 100644 (file)
index 0000000..4567584
--- /dev/null
@@ -0,0 +1,5 @@
+keyboard-force-release.sh
+keys-from-name.gperf
+keys-from-name.h
+keys-to-name.h
+keys.txt
diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules
new file mode 100644 (file)
index 0000000..f97a022
--- /dev/null
@@ -0,0 +1,57 @@
+# Set model specific atkbd force_release quirk
+#
+# Several laptops have hotkeys which don't generate release events,
+# which can cause problems with software key repeat.
+# The atkbd driver has a quirk handler for generating synthetic
+# release events, which can be configured via sysfs since 2.6.32.
+# Simply add a file with a list of scancodes for your laptop model
+# in /usr/lib/udev/keymaps, and add a rule here.
+# If the hotkeys also need a keymap assignment you can copy the
+# scancodes from the keymap file, otherwise you can run
+# /usr/lib/udev/keymap -i /dev/input/eventX
+# on a Linux vt to find out.
+
+ACTION=="remove", GOTO="force_release_end"
+SUBSYSTEM!="serio", GOTO="force_release_end"
+KERNEL!="serio*", GOTO="force_release_end"
+DRIVER!="atkbd", GOTO="force_release_end"
+
+ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}"
+
+ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keyboard-force-release.sh $devpath samsung-other"
+ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keyboard-force-release.sh $devpath samsung-series-9"
+
+ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Studio 1557|Studio 1558", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Latitude E*|Latitude *U|Precision M*", RUN+="keyboard-force-release.sh $devpath dell-touchpad"
+ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="XPS*", RUN+="keyboard-force-release.sh $devpath dell-xps"
+
+ENV{DMI_VENDOR}=="FUJITSU SIEMENS", ATTR{[dmi/id]product_name}=="AMILO*", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="FOXCONN", ATTR{[dmi/id]product_name}=="QBOOK", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="MTC", ATTR{[dmi/id]product_version}=="A0", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="Mio Technology", ATTR{[dmi/id]product_name}=="N890", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="PEGATRON CORP.", ATTR{[dmi/id]product_name}=="Spring Peak", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite [uU]300*|Satellite Pro [uU]300*|Satellite [uU]305*|SATELLITE [uU]500*", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="Viooo Corporation", ATTR{[dmi/id]product_name}=="PT17", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+# These are all the HP laptops that setup a touchpad toggle key
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keyboard-force-release.sh $devpath hp-other"
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keyboard-force-release.sh $devpath hp-other"
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*|HP G60 Notebook PC", RUN+="keyboard-force-release.sh $devpath hp-other"
+
+ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote 6615WD", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote", ATTR{[dmi/id]product_version}=="6625WD", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="HANNspree", ATTR{[dmi/id]product_name}=="SN10E100", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="GIGABYTE", ATTR{[dmi/id]product_name}=="i1520M", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+ENV{DMI_VENDOR}=="BenQ", ATTR{[dmi/id]product_name}=="*nScreen*", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
+
+LABEL="force_release_end"
diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules
new file mode 100644 (file)
index 0000000..347b5a1
--- /dev/null
@@ -0,0 +1,176 @@
+# Set model specific hotkey keycodes.
+#
+# Key map overrides can be specified by either giving scancode/keyname pairs
+# directly as keymap arguments (if there are just one or two to change), or as
+# a file name (in /usr/lib/udev/keymaps), which has to contain scancode/keyname
+# pairs.
+
+ACTION=="remove", GOTO="keyboard_end"
+KERNEL!="event*", GOTO="keyboard_end"
+ENV{ID_INPUT_KEY}=="", GOTO="keyboard_end"
+SUBSYSTEMS=="bluetooth", GOTO="keyboard_end"
+
+SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
+SUBSYSTEMS=="usb", GOTO="keyboard_usbcheck"
+GOTO="keyboard_modulecheck"
+
+#
+# The following are external USB keyboards
+#
+
+LABEL="keyboard_usbcheck"
+
+ENV{ID_VENDOR}=="Genius", ENV{ID_MODEL_ID}=="0708", ENV{ID_USB_INTERFACE_NUM}=="01", RUN+="keymap $name genius-slimstar-320"
+ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Multimedia Keyboard", RUN+="keymap $name logitech-wave"
+ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-cordless"
+# Logitech Cordless Wave Pro looks slightly weird; some hotkeys are coming through the mouse interface
+ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c52[9b]", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-pro-cordless"
+
+ENV{ID_VENDOR}=="Lite-On_Technology_Corp*", ATTRS{name}=="Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint", RUN+="keymap $name lenovo-thinkpad-usb-keyboard-trackpoint"
+ENV{ID_VENDOR_ID}=="04b3", ENV{ID_MODEL_ID}=="301[89]", RUN+="keymap $name ibm-thinkpad-usb-keyboard-trackpoint"
+
+ENV{ID_VENDOR}=="Microsoft", ENV{ID_MODEL_ID}=="00db", RUN+="keymap $name 0xc022d zoomin 0xc022e zoomout"
+
+GOTO="keyboard_end"
+
+#
+# The following are exposed as separate input devices with low key codes, thus
+# we need to check their input device product name
+#
+
+LABEL="keyboard_modulecheck"
+
+ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}"
+ENV{DMI_VENDOR}=="", GOTO="keyboard_end"
+
+ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-lenovo"
+ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Lenovo ThinkPad SL Series extra buttons", RUN+="keymap $name 0x0E bluetooth"
+ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Ideapad extra buttons", RUN+="keymap $name 0x42 f23 0x43 f22"
+
+ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Extra Buttons", ATTR{[dmi/id]product_name}=="W3J", RUN+="keymap $name module-asus-w3j"
+ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC WMI hotkeys|Asus Laptop Support|Asus*WMI*", RUN+="keymap $name 0x6B f21"
+ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC Hotkey Driver", RUN+="keymap $name 0x37 f21"
+
+ENV{DMI_VENDOR}=="IBM*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-ibm"
+ENV{DMI_VENDOR}=="Sony*", KERNELS=="input*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony"
+ENV{DMI_VENDOR}=="Acer*", KERNELS=="input*", ATTRS{name}=="Acer WMI hotkeys", RUN+="keymap $name 0x82 f21"
+ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", KERNELS=="input*", ATTRS{name}=="MSI Laptop hotkeys", RUN+="keymap $name 0x213 f22 0x214 f23"
+
+# Older Vaios have some different keys
+ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="*PCG-C1*|*PCG-K25*|*PCG-F1*|*PCG-F2*|*PCG-F3*|*PCG-F4*|*PCG-F5*|*PCG-F6*|*PCG-FX*|*PCG-FRV*|*PCG-GR*|*PCG-TR*|*PCG-NV*|*PCG-Z*|*VGN-S360*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-old"
+
+# Some Sony VGN/VPC models have yet another one
+ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="VGN-AR71*|VGN-FW*|VGN-Z21*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-vgn"
+ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="VPC*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-vpc"
+
+
+#
+# The following rules belong to standard i8042 AT keyboard with high key codes.
+#
+
+DRIVERS=="atkbd", GOTO="keyboard_vendorcheck"
+GOTO="keyboard_end"
+
+LABEL="keyboard_vendorcheck"
+
+ENV{DMI_VENDOR}=="Dell*", RUN+="keymap $name dell"
+ENV{DMI_VENDOR}=="Dell*", ATTR{[dmi/id]product_name}=="Inspiron 910|Inspiron 1010|Inspiron 1011|Inspiron 1012|Inspiron 1110|Inspiron 1210", RUN+="keymap $name 0x84 wlan"
+ENV{DMI_VENDOR}=="Dell*", ATTR{[dmi/id]product_name}=="Latitude XT2", RUN+="keymap $name dell-latitude-xt2"
+
+ENV{DMI_VENDOR}=="Compaq*", ATTR{[dmi/id]product_name}=="*E500*|*Evo N*", RUN+="keymap $name compaq-e_evo"
+
+ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*3000*", RUN+="keymap $name lenovo-3000"
+ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X6*", ATTR{[dmi/id]product_version}=="* Tablet", RUN+="keymap $name lenovo-thinkpad_x6_tablet"
+ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X2* Tablet*", ATTR{[dmi/id]product_version}=="* Tablet", RUN+="keymap $name lenovo-thinkpad_x200_tablet"
+ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*IdeaPad*", RUN+="keymap $name lenovo-ideapad"
+ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_name}=="S10-*", RUN+="keymap $name lenovo-ideapad"
+ENV{DMI_VENDOR}=="LENOVO", ATTR{[dmi/id]product_version}=="*IdeaPad Y550*", RUN+="keymap $name 0x95 media 0xA3 play"
+ENV{DMI_VENDOR}=="LENOVO", ATTR{[dmi/id]product_version}=="*Lenovo V480*", RUN+="keymap $name 0xf1 f21"
+
+ENV{DMI_VENDOR}=="Hewlett-Packard*", RUN+="keymap $name hewlett-packard"
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][aA][bB][lL][eE][tT]*", RUN+="keymap $name hewlett-packard-tablet"
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keymap $name hewlett-packard-pavilion"
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Compaq*|*EliteBook*|*2230s*", RUN+="keymap $name hewlett-packard-compaq_elitebook"
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Presario*CQ*", RUN+="keymap $name 0xD8 f21 0xD9 f21"
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*|HP G60 Notebook PC", RUN+="keymap $name hewlett-packard-2510p_2530p"
+ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keymap $name hewlett-packard-tx2"
+ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="Presario 2100*", RUN+="keymap $name hewlett-packard-presario-2100"
+ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP G62 Notebook PC", RUN+="keymap $name 0xB2 www"
+ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP ProBook*", RUN+="keymap $name 0xF8 rfkill"
+ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP EliteBook 8440p", RUN+="keymap $name hewlett-packard_elitebook-8440p"
+# HP Pavillion dv6315ea has empty DMI_VENDOR
+ATTR{[dmi/id]board_vendor}=="Quanta", ATTR{[dmi/id]board_name}=="30B7", ATTR{[dmi/id]board_version}=="65.2B", RUN+="keymap $name 0x88 media" # "quick play
+
+# Gateway clone of Acer Aspire One AOA110/AOA150
+ENV{DMI_VENDOR}=="Gateway*", ATTR{[dmi/id]product_name}=="*AOA1*", RUN+="keymap $name acer"
+
+ENV{DMI_VENDOR}=="Acer*", RUN+="keymap $name acer"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Extensa*", ATTR{[dmi/id]product_name}=="*5210*|*5220*|*5610*|*5620*|*5720*", RUN+="keymap $name 0xEE screenlock"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*C3[01]0*", RUN+="keymap $name acer-travelmate_c300"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*6292*|TravelMate*8471*|TravelMate*4720*|TravelMate*7720*|Aspire 1810T*|AO751h|AO531h", RUN+="keymap $name 0xD9 bluetooth"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*4720*", RUN+="keymap $name 0xB2 www 0xEE screenlock"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate 6593|Aspire 1640", RUN+="keymap $name 0xB2 www 0xEE screenlock"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 6920", RUN+="keymap $name acer-aspire_6920"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5920G", RUN+="keymap $name acer-aspire_5920g"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5720*", RUN+="keymap $name acer-aspire_5720"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 8930", RUN+="keymap $name acer-aspire_8930"
+ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_serial}=="ZG8*", RUN+="keymap $name acer-aspire_5720"
+
+ENV{DMI_VENDOR}=="*BenQ*", ATTR{[dmi/id]product_name}=="*Joybook R22*", RUN+="keymap $name 0x6E wlan"
+
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro V3205*", RUN+="keymap $name fujitsu-amilo_pro_v3205"
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pa 2548*", RUN+="keymap $name fujitsu-amilo_pa_2548"
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V5*", RUN+="keymap $name fujitsu-esprimo_mobile_v5"
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V6*", RUN+="keymap $name fujitsu-esprimo_mobile_v6"
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro Edition V3505*", RUN+="keymap $name fujitsu-amilo_pro_edition_v3505"
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*Amilo Si 1520*", RUN+="keymap $name fujitsu-amilo_si_1520"
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="AMILO*M*", RUN+="keymap $name 0x97 prog2 0x9F prog1"
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="Amilo Li 1718", RUN+="keymap $name 0xD6 wlan"
+ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="AMILO Li 2732", RUN+="keymap $name fujitsu-amilo_li_2732"
+
+ENV{DMI_VENDOR}=="LG*", ATTR{[dmi/id]product_name}=="*X110*", RUN+="keymap $name lg-x110"
+
+ENV{DMI_VENDOR}=="MEDION*", ATTR{[dmi/id]product_name}=="*FID2060*", RUN+="keymap $name medion-fid2060"
+ENV{DMI_VENDOR}=="MEDIONNB", ATTR{[dmi/id]product_name}=="A555*", RUN+="keymap $name medionnb-a555"
+
+ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", RUN+="keymap $name micro-star"
+
+# some MSI models generate ACPI/input events on the LNXVIDEO input devices,
+# plus some extra synthesized ones on atkbd as an echo of actually changing the
+# brightness; so ignore those atkbd ones, to avoid loops
+ENV{DMI_VENDOR}=="MICRO-STAR*", ATTR{[dmi/id]product_name}=="*U-100*|*U100*|*N033", RUN+="keymap $name 0xF7 reserved 0xF8 reserved"
+
+ENV{DMI_VENDOR}=="INVENTEC", ATTR{[dmi/id]product_name}=="SYMPHONY 6.0/7.0", RUN+="keymap $name inventec-symphony_6.0_7.0"
+
+ENV{DMI_VENDOR}=="MAXDATA", ATTR{[dmi/id]product_name}=="Pro 7000*", RUN+="keymap $name maxdata-pro_7000"
+
+ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keymap $name samsung-other"
+ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*SX20S*", RUN+="keymap $name samsung-sx20s"
+ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="SQ1US", RUN+="keymap $name samsung-sq1us"
+ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700Z*", RUN+="keymap $name 0xBA ejectcd 0x96 keyboardbrightnessup 0x97 keyboardbrightnessdown"
+ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700T*", RUN+="keymap $name 0xAD leftmeta"
+ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keymap $name samsung-series-9"
+
+ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="SATELLITE A100", RUN+="keymap $name toshiba-satellite_a100"
+ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite A110", RUN+="keymap $name toshiba-satellite_a110"
+ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite M30X", RUN+="keymap $name toshiba-satellite_m30x"
+
+ENV{DMI_VENDOR}=="OQO Inc.*", ATTR{[dmi/id]product_name}=="OQO Model 2*", RUN+="keymap $name oqo-model2"
+
+ENV{DMI_VENDOR}=="ONKYO CORPORATION", ATTR{[dmi/id]product_name}=="ONKYOPC", RUN+="keymap $name onkyo"
+
+ENV{DMI_VENDOR}=="ASUS", RUN+="keymap $name asus"
+
+ENV{DMI_VENDOR}=="VIA", ATTR{[dmi/id]product_name}=="K8N800", ATTR{[dmi/id]product_version}=="VT8204B", RUN+="keymap $name 0x81 prog1"
+
+ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote", ATTR{[dmi/id]product_version}=="62*|63*", RUN+="keymap $name zepto-znote"
+
+ENV{DMI_VENDOR}=="Everex", ATTR{[dmi/id]product_name}=="XT5000*", RUN+="keymap $name everex-xt5000"
+
+ENV{DMI_VENDOR}=="COMPAL", ATTR{[dmi/id]product_name}=="HEL80I", RUN+="keymap $name 0x84 wlan"
+
+ENV{DMI_VENDOR}=="OLPC", ATTR{[dmi/id]product_name}=="XO", RUN+="keymap $name olpc-xo"
+
+ENV{DMI_VENDOR}=="Alienware*", ATTR{[dmi/id]product_name}=="M14xR1", RUN+="keymap $name 0x8A ejectcd"
+
+LABEL="keyboard_end"
diff --git a/src/udev/keymap/README.keymap.txt b/src/udev/keymap/README.keymap.txt
new file mode 100644 (file)
index 0000000..2cf2a4e
--- /dev/null
@@ -0,0 +1,97 @@
+= The udev keymap tool =
+
+== Introduction ==
+
+This udev extension configures computer model specific key mappings. This is
+particularly necessary for the non-standard extra keys found on many laptops,
+such as "brightness up", "next song", "www browser", or "suspend". Often these
+are accessed with the Fn key.
+
+Every key produces a "scan code", which is highly vendor/model specific for the
+nonstandard keys. This tool maintains mappings for these scan codes to standard
+"key codes", which denote the "meaning" of the key. The key codes are defined
+in /usr/include/linux/input.h.
+
+If some of your keys on your keyboard are not working at all, or produce the
+wrong effect, then a very likely cause of this is that the scan code -> key
+code mapping is incorrect on your computer.
+
+== Structure ==
+
+udev-keymap consists of the following parts:
+
+ keymaps/*:: mappings of scan codes to key code names
+
+ 95-keymap.rules:: udev rules for mapping system vendor/product names and
+ input module names to one of the keymaps above
+
+ keymap:: manipulate an evdev input device:
+  * write a key map file into a device (used by udev rules)
+  * dump current scan → key code mapping
+  * interactively display scan and key codes of pressed keys
+
+ findkeyboards:: display evdev input devices which belong to actual keyboards,
+ i. e. those suitable for the keymap program
+
+== Fixing broken keys ==
+
+In order to make a broken key work on your system and send it back to upstream
+for inclusion you need to do the following steps:
+
+ 1. Find the keyboard device.
+
+ Run /usr/lib/udev/findkeyboards. This should always give you an "AT
+ keyboard" and possibly a "module". Some laptops (notably Thinkpads, Sonys, and
+ Acers) have multimedia/function keys on a separate input device instead of the
+ primary keyboard. The keyboard device should have a name like "input/event3".
+ In the following commands, the name will be written as "input/eventX" (replace
+ X with the appropriate number).
+
+ 2. Find broken scan codes:
+
+ sudo /usr/lib/udev/keymap -i input/eventX
+
+ Press all multimedia/function keys and check if the key name that gets printed
+ out is plausible. If it is unknown or wrong, write down the scan code (looks
+ like "0x1E") and the intended functionality of this key. Look in
+ /usr/include/linux/input.h for an available KEY_XXXXX constant which most
+ closely approximates this functionality and write it down as the new key code.
+
+ For example, you might press a key labeled "web browser" which currently
+ produces "unknown". Note down this:
+
+   0x1E www # Fn+F2 web browser
+
+ Repeat that for all other keys. Write the resulting list into a file. Look at
+ /usr/lib/udev/keymaps/ for existing key map files and make sure that you use the
+ same structure.
+
+ If the key only ever works once and then your keyboard (or the entire desktop)
+ gets stuck for a long time, then it is likely that the BIOS fails to send a
+ corresponding "key release" event after the key press event. Please note down
+ this case as well, as it can be worked around in
+ /usr/lib/udev/keymaps/95-keyboard-force-release.rules .
+
+ 3. Find out your system vendor and product:
+
+ cat /sys/class/dmi/id/sys_vendor
+ cat /sys/class/dmi/id/product_name
+
+ 4. Generate a device dump with "udevadm info --export-db > /tmp/udev-db.txt".
+
+ 6. Send the system vendor/product names, the key mapping from step 2,
+ and /tmp/udev-db.txt from step 4 to the linux-hotplug@vger.kernel.org mailing
+ list, so that they can be included in the next release.
+
+For local testing, copy your map file to /usr/lib/udev/keymaps/ with an appropriate
+name, and add an appropriate udev rule to /usr/lib/udev/rules.d/95-keymap.rules:
+
+  * If you selected an "AT keyboard", add the rule to the section after
+  'LABEL="keyboard_vendorcheck"'.
+
+  * If you selected a "module", add the rule to the top section where the
+  "ThinkPad Extra Buttons" are.
+
+== Author ==
+
+keymap is written and maintained by Martin Pitt <martin.pitt@ubuntu.com>.
diff --git a/src/udev/keymap/check-keymaps.sh b/src/udev/keymap/check-keymaps.sh
new file mode 100755 (executable)
index 0000000..c457274
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# check that all key names in keymaps/* are known in <linux/input.h>
+# and that all key maps listed in the rules are valid and present in
+# Makefile.am
+SRCDIR=${1:-.}
+KEYLIST=${2:-src/udev/keymap/keys.txt}
+KEYMAPS_DIR=$SRCDIR/keymaps
+RULES=$SRCDIR/src/udev/keymap/95-keymap.rules
+
+[ -e "$KEYLIST" ] || {
+        echo "need $KEYLIST please build first" >&2
+        exit 1
+}
+
+missing=$(join -v 2 <(awk '{print tolower(substr($1,5))}' $KEYLIST | sort -u) \
+                    <(grep -hv '^#' ${KEYMAPS_DIR}/*| awk '{print $2}' | sort -u))
+[ -z "$missing" ] || {
+        echo "ERROR: unknown key names in keymaps/*:" >&2
+        echo "$missing" >&2
+        exit 1
+}
+
+# check that all maps referred to in $RULES exist
+maps=$(sed -rn '/keymap \$name/ { s/^.*\$name ([^"[:space:]]+).*$/\1/; p }' $RULES)
+for m in $maps; do
+        # ignore inline mappings
+        [ "$m" = "${m#0x}" ] || continue
+
+        [ -e ${KEYMAPS_DIR}/$m ] || {
+                echo "ERROR: unknown map name in $RULES: $m" >&2
+                exit 1
+        }
+        grep -q "keymaps/$m\>" $SRCDIR/Makefile.am || {
+                echo "ERROR: map file $m is not added to Makefile.am" >&2
+                exit 1
+        }
+done
diff --git a/src/udev/keymap/findkeyboards b/src/udev/keymap/findkeyboards
new file mode 100755 (executable)
index 0000000..9ce2742
--- /dev/null
@@ -0,0 +1,68 @@
+#!/bin/sh -e
+# Find "real" keyboard devices and print their device path.
+# Author: Martin Pitt <martin.pitt@ubuntu.com>
+#
+# Copyright (C) 2009, Canonical Ltd.
+#
+# 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.
+
+# returns OK if $1 contains $2
+strstr() {
+        [ "${1#*$2*}" != "$1" ]
+}
+
+# returns OK if $1 contains $2 at the beginning
+str_starts() {
+        [ "${1#$2*}" != "$1" ]
+}
+
+str_line_starts() {
+        while read a; do str_starts "$a" "$1" && return 0;done
+        return 1;
+}
+
+# print a list of input devices which are keyboard-like
+keyboard_devices() {
+        # standard AT keyboard
+        for dev in `udevadm trigger --dry-run --verbose --property-match=ID_INPUT_KEYBOARD=1`; do
+                walk=`udevadm info --attribute-walk --path=$dev`
+                env=`udevadm info --query=env --path=$dev`
+                # filter out non-event devices, such as the parent input devices which have no devnode
+                if ! echo "$env" | str_line_starts 'DEVNAME='; then
+                        continue
+                fi
+                if strstr "$walk" 'DRIVERS=="atkbd"'; then
+                        echo -n 'AT keyboard: '
+                elif echo "$env" | str_line_starts 'ID_USB_DRIVER=usbhid'; then
+                        echo -n 'USB keyboard: '
+                else
+                        echo -n 'Unknown type: '
+               fi
+                       udevadm info --query=name --path=$dev
+        done
+
+        # modules
+        module=$(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*Extra Buttons')
+        module="$module
+        $(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*extra buttons')"
+        module="$module
+        $(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='Sony Vaio Keys')"
+        for m in $module; do
+                for evdev in $m/event*/dev; do
+                        if [ -e "$evdev" ]; then
+                                echo -n 'module: '
+                                udevadm info --query=name --path=${evdev%%/dev}
+                        fi
+                done
+        done
+}
+
+keyboard_devices
diff --git a/src/udev/keymap/keyboard-force-release.sh.in b/src/udev/keymap/keyboard-force-release.sh.in
new file mode 100755 (executable)
index 0000000..b826748
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/sh -e
+# read list of scancodes, convert hex to decimal and
+# append to the atkbd force_release sysfs attribute
+# $1 sysfs devpath for serioX
+# $2 file with scancode list (hex or dec)
+
+case "$2" in
+        /*) scf="$2" ;;
+        *)  scf="@udevlibexecdir@/keymaps/force-release/$2" ;;
+esac
+
+read attr <"/sys/$1/force_release"
+while read scancode dummy; do
+        case "$scancode" in
+                \#*) ;;
+                *)
+                        scancode=$(($scancode))
+                        attr="$attr${attr:+,}$scancode"
+                        ;;
+        esac
+done <"$scf"
+echo "$attr" >"/sys/$1/force_release"
diff --git a/src/udev/keymap/keymap.c b/src/udev/keymap/keymap.c
new file mode 100644 (file)
index 0000000..27aaf6b
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ * keymap - dump keymap of an evdev device or set a new keymap from a file
+ *
+ * Based on keyfuzz by Lennart Poettering <mzqrovna@0pointer.net>
+ * Adapted for udev-extras by Martin Pitt <martin.pitt@ubuntu.com>
+ *
+ * Copyright (C) 2006, Lennart Poettering
+ * Copyright (C) 2009, Canonical Ltd.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/ioctl.h>
+#include <linux/limits.h>
+#include <linux/input.h>
+
+const struct key* lookup_key (const char *str, unsigned int len);
+
+#include "keys-from-name.h"
+#include "keys-to-name.h"
+#include "macro.h"
+#include "util.h"
+
+#define MAX_SCANCODES 1024
+
+static int evdev_open(const char *dev)
+{
+        int fd;
+        char fn[PATH_MAX];
+
+        if (!startswith(dev, "/dev")) {
+                snprintf(fn, sizeof(fn), "/dev/%s", dev);
+                dev = fn;
+        }
+
+        if ((fd = open(dev, O_RDWR)) < 0) {
+                fprintf(stderr, "error open('%s'): %m\n", dev);
+                return -1;
+        }
+        return fd;
+}
+
+static int evdev_get_keycode(int fd, unsigned scancode, int e)
+{
+        unsigned codes[2];
+
+        codes[0] = scancode;
+        if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) {
+                if (e && errno == EINVAL) {
+                        return -2;
+                } else {
+                        fprintf(stderr, "EVIOCGKEYCODE for scan code 0x%x: %m\n", scancode);
+                        return -1;
+                }
+        }
+        return codes[1];
+}
+
+static int evdev_set_keycode(int fd, unsigned scancode, int keycode)
+{
+        unsigned codes[2];
+
+        codes[0] = scancode;
+        codes[1] = (unsigned) keycode;
+
+        if (ioctl(fd, EVIOCSKEYCODE, codes) < 0) {
+                fprintf(stderr, "EVIOCSKEYCODE: %m\n");
+                return -1;
+        }
+        return 0;
+}
+
+static int evdev_driver_version(int fd, char *v, size_t l)
+{
+        int version;
+
+        if (ioctl(fd, EVIOCGVERSION, &version)) {
+                fprintf(stderr, "EVIOCGVERSION: %m\n");
+                return -1;
+        }
+
+        snprintf(v, l, "%i.%i.%i.", version >> 16, (version >> 8) & 0xff, version & 0xff);
+        return 0;
+}
+
+static int evdev_device_name(int fd, char *n, size_t l)
+{
+        if (ioctl(fd, EVIOCGNAME(l), n) < 0) {
+                fprintf(stderr, "EVIOCGNAME: %m\n");
+                return -1;
+        }
+        return 0;
+}
+
+/* Return a lower-case string with KEY_ prefix removed */
+static const char* format_keyname(const char* key) {
+        static char result[101];
+        const char* s;
+        int len;
+
+        for (s = key+4, len = 0; *s && len < 100; ++len, ++s)
+                result[len] = tolower(*s);
+        result[len] = '\0';
+        return result;
+}
+
+static int dump_table(int fd) {
+        char version[256], name[256];
+        unsigned scancode;
+        int r = -1;
+
+        if (evdev_driver_version(fd, version, sizeof(version)) < 0)
+                goto fail;
+
+        if (evdev_device_name(fd, name, sizeof(name)) < 0)
+                goto fail;
+
+        printf("### evdev %s, driver '%s'\n", version, name);
+
+        r = 0;
+        for (scancode = 0; scancode < MAX_SCANCODES; scancode++) {
+                int keycode;
+
+                if ((keycode = evdev_get_keycode(fd, scancode, 1)) < 0) {
+                        if (keycode == -2)
+                                continue;
+                        r = -1;
+                        break;
+                }
+
+                if (keycode < KEY_MAX && key_names[keycode])
+                        printf("0x%03x %s\n", scancode, format_keyname(key_names[keycode]));
+                else
+                        printf("0x%03x 0x%03x\n", scancode, keycode);
+        }
+fail:
+        return r;
+}
+
+static void set_key(int fd, const char* scancode_str, const char* keyname)
+{
+        unsigned scancode;
+        char *endptr;
+        char t[105] = "KEY_UNKNOWN";
+        const struct key *k;
+
+        scancode = (unsigned) strtol(scancode_str, &endptr, 0);
+        if (*endptr != '\0') {
+                fprintf(stderr, "ERROR: Invalid scancode\n");
+                exit(1);
+        }
+
+        snprintf(t, sizeof(t), "KEY_%s", keyname);
+
+        if (!(k = lookup_key(t, strlen(t)))) {
+                fprintf(stderr, "ERROR: Unknown key name '%s'\n", keyname);
+                exit(1);
+        }
+
+        if (evdev_set_keycode(fd, scancode, k->id) < 0)
+                fprintf(stderr, "setting scancode 0x%2X to key code %i failed\n",
+                        scancode, k->id);
+        else
+                printf("setting scancode 0x%2X to key code %i\n",
+                        scancode, k->id);
+}
+
+static int merge_table(int fd, FILE *f) {
+        int r = 0;
+        int line = 0;
+
+        while (!feof(f)) {
+                char s[256], *p;
+                unsigned scancode;
+                int new_keycode, old_keycode;
+
+                if (!fgets(s, sizeof(s), f))
+                        break;
+
+                line++;
+                p = s+strspn(s, "\t ");
+                if (*p == '#' || *p == '\n')
+                        continue;
+
+                if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) {
+                        char t[105] = "KEY_UNKNOWN";
+                        const struct key *k;
+
+                        if (sscanf(p, "%i %100s", &scancode, t+4) != 2) {
+                                fprintf(stderr, "WARNING: Parse failure at line %i, ignoring.\n", line);
+                                r = -1;
+                                continue;
+                        }
+
+                        if (!(k = lookup_key(t, strlen(t)))) {
+                                fprintf(stderr, "WARNING: Unknown key '%s' at line %i, ignoring.\n", t, line);
+                                r = -1;
+                                continue;
+                        }
+
+                        new_keycode = k->id;
+                }
+
+
+                if ((old_keycode = evdev_get_keycode(fd, scancode, 0)) < 0) {
+                        r = -1;
+                        continue;
+                }
+
+                if (evdev_set_keycode(fd, scancode, new_keycode) < 0) {
+                        r = -1;
+                        continue;
+                }
+
+                if (new_keycode != old_keycode)
+                        fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n",
+                                scancode, new_keycode, old_keycode);
+        }
+
+        fclose(f);
+        return r;
+}
+
+
+/* read one event; return 1 if valid */
+static int read_event(int fd, struct input_event* ev)
+{
+        int ret;
+        ret = read(fd, ev, sizeof(struct input_event));
+
+        if (ret < 0) {
+                perror("read");
+                return 0;
+        }
+        if (ret != sizeof(struct input_event)) {
+                fprintf(stderr, "did not get enough data for event struct, aborting\n");
+                return 0;
+        }
+
+        return 1;
+}
+
+static void print_key(unsigned scancode, uint16_t keycode, int has_scan, int has_key)
+{
+        const char *keyname;
+
+        /* ignore key release events */
+        if (has_key == 1)
+                return;
+
+        if (has_key == 0 && has_scan != 0) {
+                fprintf(stderr, "got scan code event 0x%02X without a key code event\n",
+                        scancode);
+                return;
+        }
+
+        if (has_scan != 0)
+                printf("scan code: 0x%02X   ", scancode);
+        else
+                printf("(no scan code received)  ");
+
+        keyname = key_names[keycode];
+        if (keyname != NULL)
+                printf("key code: %s\n", format_keyname(keyname));
+        else
+                printf("key code: %03X\n", keycode);
+}
+
+static void interactive(int fd)
+{
+        struct input_event ev;
+        unsigned last_scan = 0;
+        uint16_t last_key = 0;
+        int has_scan; /* boolean */
+        int has_key; /* 0: none, 1: release, 2: press */
+
+        /* grab input device */
+        ioctl(fd, EVIOCGRAB, 1);
+        puts("Press ESC to finish, or Control-C if this device is not your primary keyboard");
+
+        has_scan = has_key = 0;
+        while (read_event(fd, &ev)) {
+                /* Drivers usually send the scan code first, then the key code,
+                 * then a SYN. Some drivers (like thinkpad_acpi) send the key
+                 * code first, and some drivers might not send SYN events, so
+                 * keep a robust state machine which can deal with any of those
+                 */
+
+                if (ev.type == EV_MSC && ev.code == MSC_SCAN) {
+                        if (has_scan) {
+                                fputs("driver did not send SYN event in between key events; previous event:\n",
+                                      stderr);
+                                print_key(last_scan, last_key, has_scan, has_key);
+                                has_key = 0;
+                        }
+
+                        last_scan = ev.value;
+                        has_scan = 1;
+                        /*printf("--- got scan %u; has scan %i key %i\n", last_scan, has_scan, has_key); */
+                }
+                else if (ev.type == EV_KEY) {
+                        if (has_key) {
+                                fputs("driver did not send SYN event in between key events; previous event:\n",
+                                      stderr);
+                                print_key(last_scan, last_key, has_scan, has_key);
+                                has_scan = 0;
+                        }
+
+                        last_key = ev.code;
+                        has_key = 1 + ev.value;
+                        /*printf("--- got key %hu; has scan %i key %i\n", last_key, has_scan, has_key);*/
+
+                        /* Stop on ESC */
+                        if (ev.code == KEY_ESC && ev.value == 0)
+                                break;
+                }
+                else if (ev.type == EV_SYN) {
+                        /*printf("--- got SYN; has scan %i key %i\n", has_scan, has_key);*/
+                        print_key(last_scan, last_key, has_scan, has_key);
+
+                        has_scan = has_key = 0;
+                }
+
+        }
+
+        /* release input device */
+        ioctl(fd, EVIOCGRAB, 0);
+}
+
+_noreturn_ static void help(int error)
+{
+        const char* h = "Usage: keymap <event device> [<map file>]\n"
+                        "       keymap <event device> scancode keyname [...]\n"
+                        "       keymap -i <event device>\n";
+        if (error) {
+                fputs(h, stderr);
+                exit(2);
+        } else {
+                fputs(h, stdout);
+                exit(0);
+        }
+}
+
+int main(int argc, char **argv)
+{
+        static const struct option options[] = {
+                { "help", no_argument, NULL, 'h' },
+                { "interactive", no_argument, NULL, 'i' },
+                {}
+        };
+        int fd = -1;
+        int opt_interactive = 0;
+        int i;
+
+        while (1) {
+                int option;
+
+                option = getopt_long(argc, argv, "hi", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'h':
+                        help(0);
+
+                case 'i':
+                        opt_interactive = 1;
+                        break;
+                default:
+                        return 1;
+                }
+        }
+
+        if (argc < optind+1)
+                help (1);
+
+        if ((fd = evdev_open(argv[optind])) < 0)
+                return 3;
+
+        /* one argument (device): dump or interactive */
+        if (argc == optind+1) {
+                if (opt_interactive)
+                        interactive(fd);
+                else
+                        dump_table(fd);
+                return 0;
+        }
+
+        /* two arguments (device, mapfile): set map file */
+        if (argc == optind+2) {
+                const char *filearg = argv[optind+1];
+                if (strchr(filearg, '/')) {
+                        /* Keymap file argument is a path */
+                        FILE *f = fopen(filearg, "re");
+                        if (f)
+                                merge_table(fd, f);
+                        else
+                                perror(filearg);
+                } else {
+                        /* Keymap file argument is a filename */
+                        /* Open override file if present, otherwise default file */
+                        char keymap_path[PATH_MAX];
+                        FILE *f;
+
+                        snprintf(keymap_path, sizeof(keymap_path), "/etc/udev/keymaps/%s", filearg);
+                        f = fopen(keymap_path, "re");
+                        if (f) {
+                                merge_table(fd, f);
+                        } else {
+                                snprintf(keymap_path, sizeof(keymap_path), UDEVLIBEXECDIR "/keymaps/%s", filearg);
+                                f = fopen(keymap_path, "re");
+                                if (f)
+                                        merge_table(fd, f);
+                                else
+                                        perror(keymap_path);
+                        }
+                }
+                return 0;
+        }
+
+        /* more arguments (device, scancode/keyname pairs): set keys directly */
+        if ((argc - optind - 1) % 2 == 0) {
+                for (i = optind+1; i < argc; i += 2)
+                        set_key(fd, argv[i], argv[i+1]);
+                return 0;
+        }
+
+        /* invalid number of arguments */
+        help(1);
+        return 1; /* not reached */
+}
diff --git a/src/udev/mtd_probe/mtd_probe.c b/src/udev/mtd_probe/mtd_probe.c
new file mode 100644 (file)
index 0000000..70c04db
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 - Maxim Levitsky
+ *
+ * mtd_probe 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.
+ *
+ * mtd_probe 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 mtd_probe; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ */
+#include "mtd_probe.h"
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <mtd/mtd-user.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+int main(int argc, char** argv)
+{
+        int mtd_fd;
+        int error;
+        mtd_info_t mtd_info;
+
+        if (argc != 2) {
+                printf("usage: mtd_probe /dev/mtd[n]\n");
+                return 1;
+        }
+
+        mtd_fd = open(argv[1], O_RDONLY);
+        if (mtd_fd == -1) {
+                perror("open");
+                exit(-1);
+        }
+
+        error = ioctl(mtd_fd, MEMGETINFO, &mtd_info);
+        if (error == -1) {
+                perror("ioctl");
+                exit(-1);
+        }
+
+        probe_smart_media(mtd_fd, &mtd_info);
+        return -1;
+}
diff --git a/src/udev/mtd_probe/mtd_probe.h b/src/udev/mtd_probe/mtd_probe.h
new file mode 100644 (file)
index 0000000..2a37ede
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 - Maxim Levitsky
+ *
+ * mtd_probe 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.
+ *
+ * mtd_probe 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 mtd_probe; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ */
+
+#include <mtd/mtd-user.h>
+
+/* Full oob structure as written on the flash */
+struct sm_oob {
+        uint32_t reserved;
+        uint8_t data_status;
+        uint8_t block_status;
+        uint8_t lba_copy1[2];
+        uint8_t ecc2[3];
+        uint8_t lba_copy2[2];
+        uint8_t ecc1[3];
+} __attribute__((packed));
+
+
+/* one sector is always 512 bytes, but it can consist of two nand pages */
+#define SM_SECTOR_SIZE                512
+
+/* oob area is also 16 bytes, but might be from two pages */
+#define SM_OOB_SIZE                16
+
+/* This is maximum zone size, and all devices that have more that one zone
+   have this size */
+#define SM_MAX_ZONE_SIZE         1024
+
+/* support for small page nand */
+#define SM_SMALL_PAGE                 256
+#define SM_SMALL_OOB_SIZE        8
+
+
+void probe_smart_media(int mtd_fd, mtd_info_t *info);
diff --git a/src/udev/mtd_probe/probe_smartmedia.c b/src/udev/mtd_probe/probe_smartmedia.c
new file mode 100644 (file)
index 0000000..feadb50
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 - Maxim Levitsky
+ *
+ * mtd_probe 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.
+ *
+ * mtd_probe 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 mtd_probe; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mtd/mtd-user.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "mtd_probe.h"
+
+static const uint8_t cis_signature[] = {
+        0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20
+};
+
+
+void probe_smart_media(int mtd_fd, mtd_info_t* info)
+{
+        int sector_size;
+        int block_size;
+        int size_in_megs;
+        int spare_count;
+        char* cis_buffer = malloc(SM_SECTOR_SIZE);
+        int offset;
+        int cis_found = 0;
+
+        if (!cis_buffer)
+                return;
+
+        if (info->type != MTD_NANDFLASH)
+                goto exit;
+
+        sector_size = info->writesize;
+        block_size = info->erasesize;
+        size_in_megs = info->size / (1024 * 1024);
+
+        if (sector_size != SM_SECTOR_SIZE && sector_size != SM_SMALL_PAGE)
+                goto exit;
+
+        switch(size_in_megs) {
+        case 1:
+        case 2:
+                spare_count = 6;
+                break;
+        case 4:
+                spare_count = 12;
+                break;
+        default:
+                spare_count = 24;
+                break;
+        }
+
+        for (offset = 0 ; offset < block_size * spare_count ;
+                                                offset += sector_size) {
+                lseek(mtd_fd, SEEK_SET, offset);
+                if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE){
+                        cis_found = 1;
+                        break;
+                }
+        }
+
+        if (!cis_found)
+                goto exit;
+
+        if (memcmp(cis_buffer, cis_signature, sizeof(cis_signature)) != 0 &&
+                (memcmp(cis_buffer + SM_SMALL_PAGE, cis_signature,
+                        sizeof(cis_signature)) != 0))
+                goto exit;
+
+        printf("MTD_FTL=smartmedia\n");
+        free(cis_buffer);
+        exit(0);
+exit:
+        free(cis_buffer);
+        return;
+}
diff --git a/src/udev/scsi_id/.gitignore b/src/udev/scsi_id/.gitignore
new file mode 100644 (file)
index 0000000..6aebddd
--- /dev/null
@@ -0,0 +1 @@
+scsi_id_version.h
diff --git a/src/udev/scsi_id/README b/src/udev/scsi_id/README
new file mode 100644 (file)
index 0000000..9cfe739
--- /dev/null
@@ -0,0 +1,4 @@
+scsi_id - generate a SCSI unique identifier for a given SCSI device
+
+Please send questions, comments or patches to <patmans@us.ibm.com> or
+<linux-hotplug-devel@lists.sourceforge.net>.
diff --git a/src/udev/scsi_id/scsi.h b/src/udev/scsi_id/scsi.h
new file mode 100644 (file)
index 0000000..c423cac
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * scsi.h
+ *
+ * General scsi and linux scsi specific defines and structs.
+ *
+ * Copyright (C) IBM Corp. 2003
+ *
+ *        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.
+ */
+
+#include <scsi/scsi.h>
+
+struct scsi_ioctl_command {
+        unsigned int inlen;        /* excluding scsi command length */
+        unsigned int outlen;
+        unsigned char data[1];
+        /* on input, scsi command starts here then opt. data */
+};
+
+/*
+ * Default 5 second timeout
+ */
+#define DEF_TIMEOUT        5000
+
+#define SENSE_BUFF_LEN        32
+
+/*
+ * The request buffer size passed to the SCSI INQUIRY commands, use 254,
+ * as this is a nice value for some devices, especially some of the usb
+ * mass storage devices.
+ */
+#define        SCSI_INQ_BUFF_LEN        254
+
+/*
+ * SCSI INQUIRY vendor and model (really product) lengths.
+ */
+#define VENDOR_LENGTH        8
+#define        MODEL_LENGTH        16
+
+#define INQUIRY_CMD     0x12
+#define INQUIRY_CMDLEN  6
+
+/*
+ * INQUIRY VPD page 0x83 identifier descriptor related values. Reference the
+ * SCSI Primary Commands specification for details.
+ */
+
+/*
+ * id type values of id descriptors. These are assumed to fit in 4 bits.
+ */
+#define SCSI_ID_VENDOR_SPECIFIC        0
+#define SCSI_ID_T10_VENDOR        1
+#define SCSI_ID_EUI_64                2
+#define SCSI_ID_NAA                3
+#define SCSI_ID_RELPORT                4
+#define SCSI_ID_TGTGROUP        5
+#define SCSI_ID_LUNGROUP        6
+#define SCSI_ID_MD5                7
+#define SCSI_ID_NAME                8
+
+/*
+ * Supported NAA values. These fit in 4 bits, so the "don't care" value
+ * cannot conflict with real values.
+ */
+#define        SCSI_ID_NAA_DONT_CARE                0xff
+#define        SCSI_ID_NAA_IEEE_REG                5
+#define        SCSI_ID_NAA_IEEE_REG_EXTENDED        6
+
+/*
+ * Supported Code Set values.
+ */
+#define        SCSI_ID_BINARY        1
+#define        SCSI_ID_ASCII        2
+
+struct scsi_id_search_values {
+        u_char        id_type;
+        u_char        naa_type;
+        u_char        code_set;
+};
+
+/*
+ * Following are the "true" SCSI status codes. Linux has traditionally
+ * used a 1 bit right and masked version of these. So now CHECK_CONDITION
+ * and friends (in <scsi/scsi.h>) are deprecated.
+ */
+#define SCSI_CHECK_CONDITION 0x2
+#define SCSI_CONDITION_MET 0x4
+#define SCSI_BUSY 0x8
+#define SCSI_IMMEDIATE 0x10
+#define SCSI_IMMEDIATE_CONDITION_MET 0x14
+#define SCSI_RESERVATION_CONFLICT 0x18
+#define SCSI_COMMAND_TERMINATED 0x22
+#define SCSI_TASK_SET_FULL 0x28
+#define SCSI_ACA_ACTIVE 0x30
+#define SCSI_TASK_ABORTED 0x40
diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c
new file mode 100644 (file)
index 0000000..c90b6aa
--- /dev/null
@@ -0,0 +1,634 @@
+/*
+ * Copyright (C) IBM Corp. 2003
+ * Copyright (C) SUSE Linux Products GmbH, 2006
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <sys/stat.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+#include "scsi_id.h"
+
+static const struct option options[] = {
+        { "device", required_argument, NULL, 'd' },
+        { "config", required_argument, NULL, 'f' },
+        { "page", required_argument, NULL, 'p' },
+        { "blacklisted", no_argument, NULL, 'b' },
+        { "whitelisted", no_argument, NULL, 'g' },
+        { "replace-whitespace", no_argument, NULL, 'u' },
+        { "sg-version", required_argument, NULL, 's' },
+        { "verbose", no_argument, NULL, 'v' },
+        { "version", no_argument, NULL, 'V' },
+        { "export", no_argument, NULL, 'x' },
+        { "help", no_argument, NULL, 'h' },
+        {}
+};
+
+static const char short_options[] = "d:f:ghip:uvVx";
+static const char dev_short_options[] = "bgp:";
+
+static int all_good;
+static int dev_specified;
+static char config_file[MAX_PATH_LEN] = "/etc/scsi_id.config";
+static enum page_code default_page_code;
+static int sg_version = 4;
+static int use_stderr;
+static int debug;
+static int reformat_serial;
+static int export;
+static char vendor_str[64];
+static char model_str[64];
+static char vendor_enc_str[256];
+static char model_enc_str[256];
+static char revision_str[16];
+static char type_str[16];
+
+static void log_fn(struct udev *udev, int priority,
+                   const char *file, int line, const char *fn,
+                   const char *format, va_list args)
+{
+        vsyslog(priority, format, args);
+}
+
+static void set_type(const char *from, char *to, size_t len)
+{
+        int type_num;
+        char *eptr;
+        const char *type = "generic";
+
+        type_num = strtoul(from, &eptr, 0);
+        if (eptr != from) {
+                switch (type_num) {
+                case 0:
+                        type = "disk";
+                        break;
+                case 1:
+                        type = "tape";
+                        break;
+                case 4:
+                        type = "optical";
+                        break;
+                case 5:
+                        type = "cd";
+                        break;
+                case 7:
+                        type = "optical";
+                        break;
+                case 0xe:
+                        type = "disk";
+                        break;
+                case 0xf:
+                        type = "optical";
+                        break;
+                default:
+                        break;
+                }
+        }
+        util_strscpy(to, len, type);
+}
+
+/*
+ * get_value:
+ *
+ * buf points to an '=' followed by a quoted string ("foo") or a string ending
+ * with a space or ','.
+ *
+ * Return a pointer to the NUL terminated string, returns NULL if no
+ * matches.
+ */
+static char *get_value(char **buffer)
+{
+        static const char *quote_string = "\"\n";
+        static const char *comma_string = ",\n";
+        char *val;
+        const char *end;
+
+        if (**buffer == '"') {
+                /*
+                 * skip leading quote, terminate when quote seen
+                 */
+                (*buffer)++;
+                end = quote_string;
+        } else {
+                end = comma_string;
+        }
+        val = strsep(buffer, end);
+        if (val && end == quote_string)
+                /*
+                 * skip trailing quote
+                 */
+                (*buffer)++;
+
+        while (isspace(**buffer))
+                (*buffer)++;
+
+        return val;
+}
+
+static int argc_count(char *opts)
+{
+        int i = 0;
+        while (*opts != '\0')
+                if (*opts++ == ' ')
+                        i++;
+        return i;
+}
+
+/*
+ * get_file_options:
+ *
+ * If vendor == NULL, find a line in the config file with only "OPTIONS=";
+ * if vendor and model are set find the first OPTIONS line in the config
+ * file that matches. Set argc and argv to match the OPTIONS string.
+ *
+ * vendor and model can end in '\n'.
+ */
+static int get_file_options(struct udev *udev,
+                            const char *vendor, const char *model,
+                            int *argc, char ***newargv)
+{
+        char *buffer;
+        FILE *fd;
+        char *buf;
+        char *str1;
+        char *vendor_in, *model_in, *options_in; /* read in from file */
+        int lineno;
+        int c;
+        int retval = 0;
+
+        fd = fopen(config_file, "re");
+        if (fd == NULL) {
+                if (errno == ENOENT) {
+                        return 1;
+                } else {
+                        log_error("can't open %s: %s\n", config_file, strerror(errno));
+                        return -1;
+                }
+        }
+
+        /*
+         * Allocate a buffer rather than put it on the stack so we can
+         * keep it around to parse any options (any allocated newargv
+         * points into this buffer for its strings).
+         */
+        buffer = malloc(MAX_BUFFER_LEN);
+        if (!buffer) {
+                fclose(fd);
+                return log_oom();
+        }
+
+        *newargv = NULL;
+        lineno = 0;
+        while (1) {
+                vendor_in = model_in = options_in = NULL;
+
+                buf = fgets(buffer, MAX_BUFFER_LEN, fd);
+                if (buf == NULL)
+                        break;
+                lineno++;
+                if (buf[strlen(buffer) - 1] != '\n') {
+                        log_error("Config file line %d too long\n", lineno);
+                        break;
+                }
+
+                while (isspace(*buf))
+                        buf++;
+
+                /* blank or all whitespace line */
+                if (*buf == '\0')
+                        continue;
+
+                /* comment line */
+                if (*buf == '#')
+                        continue;
+
+                str1 = strsep(&buf, "=");
+                if (str1 && strcasecmp(str1, "VENDOR") == 0) {
+                        str1 = get_value(&buf);
+                        if (!str1) {
+                                retval = log_oom();
+                                break;
+                        }
+                        vendor_in = str1;
+
+                        str1 = strsep(&buf, "=");
+                        if (str1 && strcasecmp(str1, "MODEL") == 0) {
+                                str1 = get_value(&buf);
+                                if (!str1) {
+                                        retval = log_oom();
+                                        break;
+                                }
+                                model_in = str1;
+                                str1 = strsep(&buf, "=");
+                        }
+                }
+
+                if (str1 && strcasecmp(str1, "OPTIONS") == 0) {
+                        str1 = get_value(&buf);
+                        if (!str1) {
+                                retval = log_oom();
+                                break;
+                        }
+                        options_in = str1;
+                }
+
+                /*
+                 * Only allow: [vendor=foo[,model=bar]]options=stuff
+                 */
+                if (!options_in || (!vendor_in && model_in)) {
+                        log_error("Error parsing config file line %d '%s'\n", lineno, buffer);
+                        retval = -1;
+                        break;
+                }
+                if (vendor == NULL) {
+                        if (vendor_in == NULL)
+                                break;
+                } else if ((vendor_in && strncmp(vendor, vendor_in,
+                                                 strlen(vendor_in)) == 0) &&
+                           (!model_in || (strncmp(model, model_in,
+                                                  strlen(model_in)) == 0))) {
+                                /*
+                                 * Matched vendor and optionally model.
+                                 *
+                                 * Note: a short vendor_in or model_in can
+                                 * give a partial match (that is FOO
+                                 * matches FOOBAR).
+                                 */
+                                break;
+                }
+        }
+
+        if (retval == 0) {
+                if (vendor_in != NULL || model_in != NULL ||
+                    options_in != NULL) {
+                        /*
+                         * Something matched. Allocate newargv, and store
+                         * values found in options_in.
+                         */
+                        strcpy(buffer, options_in);
+                        c = argc_count(buffer) + 2;
+                        *newargv = calloc(c, sizeof(**newargv));
+                        if (!*newargv) {
+                                retval = log_oom();
+                        } else {
+                                *argc = c;
+                                c = 0;
+                                /*
+                                 * argv[0] at 0 is skipped by getopt, but
+                                 * store the buffer address there for
+                                 * later freeing
+                                 */
+                                (*newargv)[c] = buffer;
+                                for (c = 1; c < *argc; c++)
+                                        (*newargv)[c] = strsep(&buffer, " \t");
+                        }
+                } else {
+                        /* No matches  */
+                        retval = 1;
+                }
+        }
+        if (retval != 0)
+                free(buffer);
+        fclose(fd);
+        return retval;
+}
+
+static int set_options(struct udev *udev,
+                       int argc, char **argv, const char *short_opts,
+                       char *maj_min_dev)
+{
+        int option;
+
+        /*
+         * optind is a global extern used by getopt. Since we can call
+         * set_options twice (once for command line, and once for config
+         * file) we have to reset this back to 1.
+         */
+        optind = 1;
+        while (1) {
+                option = getopt_long(argc, argv, short_opts, options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'b':
+                        all_good = 0;
+                        break;
+
+                case 'd':
+                        dev_specified = 1;
+                        util_strscpy(maj_min_dev, MAX_PATH_LEN, optarg);
+                        break;
+
+                case 'e':
+                        use_stderr = 1;
+                        break;
+
+                case 'f':
+                        util_strscpy(config_file, MAX_PATH_LEN, optarg);
+                        break;
+
+                case 'g':
+                        all_good = 1;
+                        break;
+
+                case 'h':
+                        printf("Usage: scsi_id OPTIONS <device>\n"
+                               "  --device=                     device node for SG_IO commands\n"
+                               "  --config=                     location of config file\n"
+                               "  --page=0x80|0x83|pre-spc3-83  SCSI page (0x80, 0x83, pre-spc3-83)\n"
+                               "  --sg-version=3|4              use SGv3 or SGv4\n"
+                               "  --blacklisted                 threat device as blacklisted\n"
+                               "  --whitelisted                 threat device as whitelisted\n"
+                               "  --replace-whitespace          replace all whitespaces by underscores\n"
+                               "  --verbose                     verbose logging\n"
+                               "  --version                     print version\n"
+                               "  --export                      print values as environment keys\n"
+                               "  --help                        print this help text\n\n");
+                        exit(0);
+
+                case 'p':
+                        if (strcmp(optarg, "0x80") == 0) {
+                                default_page_code = PAGE_80;
+                        } else if (strcmp(optarg, "0x83") == 0) {
+                                default_page_code = PAGE_83;
+                        } else if (strcmp(optarg, "pre-spc3-83") == 0) {
+                                default_page_code = PAGE_83_PRE_SPC3;
+                        } else {
+                                log_error("Unknown page code '%s'\n", optarg);
+                                return -1;
+                        }
+                        break;
+
+                case 's':
+                        sg_version = atoi(optarg);
+                        if (sg_version < 3 || sg_version > 4) {
+                                log_error("Unknown SG version '%s'\n", optarg);
+                                return -1;
+                        }
+                        break;
+
+                case 'u':
+                        reformat_serial = 1;
+                        break;
+
+                case 'x':
+                        export = 1;
+                        break;
+
+                case 'v':
+                        debug++;
+                        break;
+
+                case 'V':
+                        printf("%s\n", VERSION);
+                        exit(0);
+                        break;
+
+                default:
+                        exit(1);
+                }
+        }
+        if (optind < argc && !dev_specified) {
+                dev_specified = 1;
+                util_strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]);
+        }
+        return 0;
+}
+
+static int per_dev_options(struct udev *udev,
+                           struct scsi_id_device *dev_scsi, int *good_bad, int *page_code)
+{
+        int retval;
+        int newargc;
+        char **newargv = NULL;
+        int option;
+
+        *good_bad = all_good;
+        *page_code = default_page_code;
+
+        retval = get_file_options(udev, vendor_str, model_str, &newargc, &newargv);
+
+        optind = 1; /* reset this global extern */
+        while (retval == 0) {
+                option = getopt_long(newargc, newargv, dev_short_options, options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'b':
+                        *good_bad = 0;
+                        break;
+
+                case 'g':
+                        *good_bad = 1;
+                        break;
+
+                case 'p':
+                        if (strcmp(optarg, "0x80") == 0) {
+                                *page_code = PAGE_80;
+                        } else if (strcmp(optarg, "0x83") == 0) {
+                                *page_code = PAGE_83;
+                        } else if (strcmp(optarg, "pre-spc3-83") == 0) {
+                                *page_code = PAGE_83_PRE_SPC3;
+                        } else {
+                                log_error("Unknown page code '%s'\n", optarg);
+                                retval = -1;
+                        }
+                        break;
+
+                default:
+                        log_error("Unknown or bad option '%c' (0x%x)\n", option, option);
+                        retval = -1;
+                        break;
+                }
+        }
+
+        if (newargv) {
+                free(newargv[0]);
+                free(newargv);
+        }
+        return retval;
+}
+
+static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, const char *path)
+{
+        int retval;
+
+        dev_scsi->use_sg = sg_version;
+
+        retval = scsi_std_inquiry(udev, dev_scsi, path);
+        if (retval)
+                return retval;
+
+        udev_util_encode_string(dev_scsi->vendor, vendor_enc_str, sizeof(vendor_enc_str));
+        udev_util_encode_string(dev_scsi->model, model_enc_str, sizeof(model_enc_str));
+
+        util_replace_whitespace(dev_scsi->vendor, vendor_str, sizeof(vendor_str));
+        util_replace_chars(vendor_str, NULL);
+        util_replace_whitespace(dev_scsi->model, model_str, sizeof(model_str));
+        util_replace_chars(model_str, NULL);
+        set_type(dev_scsi->type, type_str, sizeof(type_str));
+        util_replace_whitespace(dev_scsi->revision, revision_str, sizeof(revision_str));
+        util_replace_chars(revision_str, NULL);
+        return 0;
+}
+
+/*
+ * scsi_id: try to get an id, if one is found, printf it to stdout.
+ * returns a value passed to exit() - 0 if printed an id, else 1.
+ */
+static int scsi_id(struct udev *udev, char *maj_min_dev)
+{
+        struct scsi_id_device dev_scsi;
+        int good_dev;
+        int page_code;
+        int retval = 0;
+
+        memset(&dev_scsi, 0x00, sizeof(struct scsi_id_device));
+
+        if (set_inq_values(udev, &dev_scsi, maj_min_dev) < 0) {
+                retval = 1;
+                goto out;
+        }
+
+        /* get per device (vendor + model) options from the config file */
+        per_dev_options(udev, &dev_scsi, &good_dev, &page_code);
+        if (!good_dev) {
+                retval = 1;
+                goto out;
+        }
+
+        /* read serial number from mode pages (no values for optical drives) */
+        scsi_get_serial(udev, &dev_scsi, maj_min_dev, page_code, MAX_SERIAL_LEN);
+
+        if (export) {
+                char serial_str[MAX_SERIAL_LEN];
+
+                printf("ID_SCSI=1\n");
+                printf("ID_VENDOR=%s\n", vendor_str);
+                printf("ID_VENDOR_ENC=%s\n", vendor_enc_str);
+                printf("ID_MODEL=%s\n", model_str);
+                printf("ID_MODEL_ENC=%s\n", model_enc_str);
+                printf("ID_REVISION=%s\n", revision_str);
+                printf("ID_TYPE=%s\n", type_str);
+                if (dev_scsi.serial[0] != '\0') {
+                        util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str));
+                        util_replace_chars(serial_str, NULL);
+                        printf("ID_SERIAL=%s\n", serial_str);
+                        util_replace_whitespace(dev_scsi.serial_short, serial_str, sizeof(serial_str));
+                        util_replace_chars(serial_str, NULL);
+                        printf("ID_SERIAL_SHORT=%s\n", serial_str);
+                }
+                if (dev_scsi.wwn[0] != '\0') {
+                        printf("ID_WWN=0x%s\n", dev_scsi.wwn);
+                        if (dev_scsi.wwn_vendor_extension[0] != '\0') {
+                                printf("ID_WWN_VENDOR_EXTENSION=0x%s\n", dev_scsi.wwn_vendor_extension);
+                                printf("ID_WWN_WITH_EXTENSION=0x%s%s\n", dev_scsi.wwn, dev_scsi.wwn_vendor_extension);
+                        } else {
+                                printf("ID_WWN_WITH_EXTENSION=0x%s\n", dev_scsi.wwn);
+                        }
+                }
+                if (dev_scsi.tgpt_group[0] != '\0') {
+                        printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group);
+                }
+                if (dev_scsi.unit_serial_number[0] != '\0') {
+                        printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number);
+                }
+                goto out;
+        }
+
+        if (dev_scsi.serial[0] == '\0') {
+                retval = 1;
+                goto out;
+        }
+
+        if (reformat_serial) {
+                char serial_str[MAX_SERIAL_LEN];
+
+                util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str));
+                util_replace_chars(serial_str, NULL);
+                printf("%s\n", serial_str);
+                goto out;
+        }
+
+        printf("%s\n", dev_scsi.serial);
+out:
+        return retval;
+}
+
+int main(int argc, char **argv)
+{
+        struct udev *udev;
+        int retval = 0;
+        char maj_min_dev[MAX_PATH_LEN];
+        int newargc;
+        char **newargv;
+
+        udev = udev_new();
+        if (udev == NULL)
+                goto exit;
+
+        log_open();
+        udev_set_log_fn(udev, log_fn);
+
+        /*
+         * Get config file options.
+         */
+        newargv = NULL;
+        retval = get_file_options(udev, NULL, NULL, &newargc, &newargv);
+        if (retval < 0) {
+                retval = 1;
+                goto exit;
+        }
+        if (newargv && (retval == 0)) {
+                if (set_options(udev, newargc, newargv, short_options, maj_min_dev) < 0) {
+                        retval = 2;
+                        goto exit;
+                }
+                free(newargv);
+        }
+
+        /*
+         * Get command line options (overriding any config file settings).
+         */
+        if (set_options(udev, argc, argv, short_options, maj_min_dev) < 0)
+                exit(1);
+
+        if (!dev_specified) {
+                log_error("no device specified\n");
+                retval = 1;
+                goto exit;
+        }
+
+        retval = scsi_id(udev, maj_min_dev);
+
+exit:
+        udev_unref(udev);
+        log_close();
+        return retval;
+}
diff --git a/src/udev/scsi_id/scsi_id.h b/src/udev/scsi_id/scsi_id.h
new file mode 100644 (file)
index 0000000..828a983
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) IBM Corp. 2003
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define        MAX_PATH_LEN        512
+
+/*
+ * MAX_ATTR_LEN: maximum length of the result of reading a sysfs
+ * attribute.
+ */
+#define        MAX_ATTR_LEN        256
+
+/*
+ * MAX_SERIAL_LEN: the maximum length of the serial number, including
+ * added prefixes such as vendor and product (model) strings.
+ */
+#define        MAX_SERIAL_LEN        256
+
+/*
+ * MAX_BUFFER_LEN: maximum buffer size and line length used while reading
+ * the config file.
+ */
+#define MAX_BUFFER_LEN        256
+
+struct scsi_id_device {
+        char vendor[9];
+        char model[17];
+        char revision[5];
+        char type[33];
+        char kernel[64];
+        char serial[MAX_SERIAL_LEN];
+        char serial_short[MAX_SERIAL_LEN];
+        int use_sg;
+
+        /* Always from page 0x80 e.g. 'B3G1P8500RWT' - may not be unique */
+        char unit_serial_number[MAX_SERIAL_LEN];
+
+        /* NULs if not set - otherwise hex encoding using lower-case e.g. '50014ee0016eb572' */
+        char wwn[17];
+
+        /* NULs if not set - otherwise hex encoding using lower-case e.g. '0xe00000d80000' */
+        char wwn_vendor_extension[17];
+
+        /* NULs if not set - otherwise decimal number */
+        char tgpt_group[8];
+};
+
+extern int scsi_std_inquiry(struct udev *udev, struct scsi_id_device *dev_scsi, const char *devname);
+extern int scsi_get_serial (struct udev *udev, struct scsi_id_device *dev_scsi, const char *devname,
+                            int page_code, int len);
+
+/*
+ * Page code values.
+ */
+enum page_code {
+                PAGE_83_PRE_SPC3 = -0x83,
+                PAGE_UNSPECIFIED = 0x00,
+                PAGE_80                 = 0x80,
+                PAGE_83                 = 0x83,
+};
diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c
new file mode 100644 (file)
index 0000000..3c52dee
--- /dev/null
@@ -0,0 +1,968 @@
+/*
+ * Copyright (C) IBM Corp. 2003
+ *
+ * Author: Patrick Mansfield<patmans@us.ibm.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <time.h>
+#include <inttypes.h>
+#include <scsi/scsi.h>
+#include <scsi/sg.h>
+#include <linux/types.h>
+#include <linux/bsg.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+#include "scsi.h"
+#include "scsi_id.h"
+
+/*
+ * A priority based list of id, naa, and binary/ascii for the identifier
+ * descriptor in VPD page 0x83.
+ *
+ * Brute force search for a match starting with the first value in the
+ * following id_search_list. This is not a performance issue, since there
+ * is normally one or some small number of descriptors.
+ */
+static const struct scsi_id_search_values id_search_list[] = {
+        { SCSI_ID_TGTGROUP,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
+        { SCSI_ID_NAA,        SCSI_ID_NAA_IEEE_REG_EXTENDED,        SCSI_ID_BINARY },
+        { SCSI_ID_NAA,        SCSI_ID_NAA_IEEE_REG_EXTENDED,        SCSI_ID_ASCII },
+        { SCSI_ID_NAA,        SCSI_ID_NAA_IEEE_REG,        SCSI_ID_BINARY },
+        { SCSI_ID_NAA,        SCSI_ID_NAA_IEEE_REG,        SCSI_ID_ASCII },
+        /*
+         * Devices already exist using NAA values that are now marked
+         * reserved. These should not conflict with other values, or it is
+         * a bug in the device. As long as we find the IEEE extended one
+         * first, we really don't care what other ones are used. Using
+         * don't care here means that a device that returns multiple
+         * non-IEEE descriptors in a random order will get different
+         * names.
+         */
+        { SCSI_ID_NAA,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
+        { SCSI_ID_NAA,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_ASCII },
+        { SCSI_ID_EUI_64,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
+        { SCSI_ID_EUI_64,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_ASCII },
+        { SCSI_ID_T10_VENDOR,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
+        { SCSI_ID_T10_VENDOR,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_ASCII },
+        { SCSI_ID_VENDOR_SPECIFIC,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
+        { SCSI_ID_VENDOR_SPECIFIC,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_ASCII },
+};
+
+static const char hex_str[]="0123456789abcdef";
+
+/*
+ * Values returned in the result/status, only the ones used by the code
+ * are used here.
+ */
+
+#define DID_NO_CONNECT                        0x01        /* Unable to connect before timeout */
+#define DID_BUS_BUSY                        0x02        /* Bus remain busy until timeout */
+#define DID_TIME_OUT                        0x03        /* Timed out for some other reason */
+#define DRIVER_TIMEOUT                        0x06
+#define DRIVER_SENSE                        0x08        /* Sense_buffer has been set */
+
+/* The following "category" function returns one of the following */
+#define SG_ERR_CAT_CLEAN                0        /* No errors or other information */
+#define SG_ERR_CAT_MEDIA_CHANGED        1        /* interpreted from sense buffer */
+#define SG_ERR_CAT_RESET                2        /* interpreted from sense buffer */
+#define SG_ERR_CAT_TIMEOUT                3
+#define SG_ERR_CAT_RECOVERED                4        /* Successful command after recovered err */
+#define SG_ERR_CAT_NOTSUPPORTED                5        /* Illegal / unsupported command */
+#define SG_ERR_CAT_SENSE                98        /* Something else in the sense buffer */
+#define SG_ERR_CAT_OTHER                99        /* Some other error/warning */
+
+static int do_scsi_page80_inquiry(struct udev *udev,
+                                  struct scsi_id_device *dev_scsi, int fd,
+                                  char *serial, char *serial_short, int max_len);
+
+static int sg_err_category_new(struct udev *udev,
+                               int scsi_status, int msg_status, int
+                               host_status, int driver_status, const
+                               unsigned char *sense_buffer, int sb_len)
+{
+        scsi_status &= 0x7e;
+
+        /*
+         * XXX change to return only two values - failed or OK.
+         */
+
+        if (!scsi_status && !host_status && !driver_status)
+                return SG_ERR_CAT_CLEAN;
+
+        if ((scsi_status == SCSI_CHECK_CONDITION) ||
+            (scsi_status == SCSI_COMMAND_TERMINATED) ||
+            ((driver_status & 0xf) == DRIVER_SENSE)) {
+                if (sense_buffer && (sb_len > 2)) {
+                        int sense_key;
+                        unsigned char asc;
+
+                        if (sense_buffer[0] & 0x2) {
+                                sense_key = sense_buffer[1] & 0xf;
+                                asc = sense_buffer[2];
+                        } else {
+                                sense_key = sense_buffer[2] & 0xf;
+                                asc = (sb_len > 12) ? sense_buffer[12] : 0;
+                        }
+
+                        if (sense_key == RECOVERED_ERROR)
+                                return SG_ERR_CAT_RECOVERED;
+                        else if (sense_key == UNIT_ATTENTION) {
+                                if (0x28 == asc)
+                                        return SG_ERR_CAT_MEDIA_CHANGED;
+                                if (0x29 == asc)
+                                        return SG_ERR_CAT_RESET;
+                        } else if (sense_key == ILLEGAL_REQUEST) {
+                                return SG_ERR_CAT_NOTSUPPORTED;
+                        }
+                }
+                return SG_ERR_CAT_SENSE;
+        }
+        if (host_status) {
+                if ((host_status == DID_NO_CONNECT) ||
+                    (host_status == DID_BUS_BUSY) ||
+                    (host_status == DID_TIME_OUT))
+                        return SG_ERR_CAT_TIMEOUT;
+        }
+        if (driver_status) {
+                if (driver_status == DRIVER_TIMEOUT)
+                        return SG_ERR_CAT_TIMEOUT;
+        }
+        return SG_ERR_CAT_OTHER;
+}
+
+static int sg_err_category3(struct udev *udev, struct sg_io_hdr *hp)
+{
+        return sg_err_category_new(udev,
+                                   hp->status, hp->msg_status,
+                                   hp->host_status, hp->driver_status,
+                                   hp->sbp, hp->sb_len_wr);
+}
+
+static int sg_err_category4(struct udev *udev, struct sg_io_v4 *hp)
+{
+        return sg_err_category_new(udev, hp->device_status, 0,
+                                   hp->transport_status, hp->driver_status,
+                                   (unsigned char *)(uintptr_t)hp->response,
+                                   hp->response_len);
+}
+
+static int scsi_dump_sense(struct udev *udev,
+                           struct scsi_id_device *dev_scsi,
+                           unsigned char *sense_buffer, int sb_len)
+{
+        int s;
+        int code;
+        int sense_class;
+        int sense_key;
+        int asc, ascq;
+#ifdef DUMP_SENSE
+        char out_buffer[256];
+        int i, j;
+#endif
+
+        /*
+         * Figure out and print the sense key, asc and ascq.
+         *
+         * If you want to suppress these for a particular drive model, add
+         * a black list entry in the scsi_id config file.
+         *
+         * XXX We probably need to: lookup the sense/asc/ascq in a retry
+         * table, and if found return 1 (after dumping the sense, asc, and
+         * ascq). So, if/when we get something like a power on/reset,
+         * we'll retry the command.
+         */
+
+        if (sb_len < 1) {
+                log_debug("%s: sense buffer empty\n", dev_scsi->kernel);
+                return -1;
+        }
+
+        sense_class = (sense_buffer[0] >> 4) & 0x07;
+        code = sense_buffer[0] & 0xf;
+
+        if (sense_class == 7) {
+                /*
+                 * extended sense data.
+                 */
+                s = sense_buffer[7] + 8;
+                if (sb_len < s) {
+                        log_debug("%s: sense buffer too small %d bytes, %d bytes too short\n",
+                            dev_scsi->kernel, sb_len, s - sb_len);
+                        return -1;
+                }
+                if ((code == 0x0) || (code == 0x1)) {
+                        sense_key = sense_buffer[2] & 0xf;
+                        if (s < 14) {
+                                /*
+                                 * Possible?
+                                 */
+                                log_debug("%s: sense result too" " small %d bytes\n",
+                                    dev_scsi->kernel, s);
+                                return -1;
+                        }
+                        asc = sense_buffer[12];
+                        ascq = sense_buffer[13];
+                } else if ((code == 0x2) || (code == 0x3)) {
+                        sense_key = sense_buffer[1] & 0xf;
+                        asc = sense_buffer[2];
+                        ascq = sense_buffer[3];
+                } else {
+                        log_debug("%s: invalid sense code 0x%x\n",
+                            dev_scsi->kernel, code);
+                        return -1;
+                }
+                log_debug("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x\n",
+                    dev_scsi->kernel, sense_key, asc, ascq);
+        } else {
+                if (sb_len < 4) {
+                        log_debug("%s: sense buffer too small %d bytes, %d bytes too short\n",
+                            dev_scsi->kernel, sb_len, 4 - sb_len);
+                        return -1;
+                }
+
+                if (sense_buffer[0] < 15)
+                        log_debug("%s: old sense key: 0x%x\n", dev_scsi->kernel, sense_buffer[0] & 0x0f);
+                else
+                        log_debug("%s: sense = %2x %2x\n",
+                            dev_scsi->kernel, sense_buffer[0], sense_buffer[2]);
+                log_debug("%s: non-extended sense class %d code 0x%0x\n",
+                    dev_scsi->kernel, sense_class, code);
+
+        }
+
+#ifdef DUMP_SENSE
+        for (i = 0, j = 0; (i < s) && (j < 254); i++) {
+                out_buffer[j++] = hex_str[(sense_buffer[i] & 0xf0) >> 4];
+                out_buffer[j++] = hex_str[sense_buffer[i] & 0x0f];
+                out_buffer[j++] = ' ';
+        }
+        out_buffer[j] = '\0';
+        log_debug("%s: sense dump:\n", dev_scsi->kernel);
+        log_debug("%s: %s\n", dev_scsi->kernel, out_buffer);
+
+#endif
+        return -1;
+}
+
+static int scsi_dump(struct udev *udev,
+                     struct scsi_id_device *dev_scsi, struct sg_io_hdr *io)
+{
+        if (!io->status && !io->host_status && !io->msg_status &&
+            !io->driver_status) {
+                /*
+                 * Impossible, should not be called.
+                 */
+                log_debug("%s: called with no error\n", __FUNCTION__);
+                return -1;
+        }
+
+        log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x\n",
+            dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status);
+        if (io->status == SCSI_CHECK_CONDITION)
+                return scsi_dump_sense(udev, dev_scsi, io->sbp, io->sb_len_wr);
+        else
+                return -1;
+}
+
+static int scsi_dump_v4(struct udev *udev,
+                        struct scsi_id_device *dev_scsi, struct sg_io_v4 *io)
+{
+        if (!io->device_status && !io->transport_status &&
+            !io->driver_status) {
+                /*
+                 * Impossible, should not be called.
+                 */
+                log_debug("%s: called with no error\n", __FUNCTION__);
+                return -1;
+        }
+
+        log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x\n",
+            dev_scsi->kernel, io->driver_status, io->transport_status,
+             io->device_status);
+        if (io->device_status == SCSI_CHECK_CONDITION)
+                return scsi_dump_sense(udev, dev_scsi, (unsigned char *)(uintptr_t)io->response,
+                                       io->response_len);
+        else
+                return -1;
+}
+
+static int scsi_inquiry(struct udev *udev,
+                        struct scsi_id_device *dev_scsi, int fd,
+                        unsigned char evpd, unsigned char page,
+                        unsigned char *buf, unsigned int buflen)
+{
+        unsigned char inq_cmd[INQUIRY_CMDLEN] =
+                { INQUIRY_CMD, evpd, page, 0, buflen, 0 };
+        unsigned char sense[SENSE_BUFF_LEN];
+        void *io_buf;
+        struct sg_io_v4 io_v4;
+        struct sg_io_hdr io_hdr;
+        int retry = 3; /* rather random */
+        int retval;
+
+        if (buflen > SCSI_INQ_BUFF_LEN) {
+                log_debug("buflen %d too long\n", buflen);
+                return -1;
+        }
+
+resend:
+        if (dev_scsi->use_sg == 4) {
+                memset(&io_v4, 0, sizeof(struct sg_io_v4));
+                io_v4.guard = 'Q';
+                io_v4.protocol = BSG_PROTOCOL_SCSI;
+                io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
+                io_v4.request_len = sizeof(inq_cmd);
+                io_v4.request = (uintptr_t)inq_cmd;
+                io_v4.max_response_len = sizeof(sense);
+                io_v4.response = (uintptr_t)sense;
+                io_v4.din_xfer_len = buflen;
+                io_v4.din_xferp = (uintptr_t)buf;
+                io_buf = (void *)&io_v4;
+        } else {
+                memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+                io_hdr.interface_id = 'S';
+                io_hdr.cmd_len = sizeof(inq_cmd);
+                io_hdr.mx_sb_len = sizeof(sense);
+                io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+                io_hdr.dxfer_len = buflen;
+                io_hdr.dxferp = buf;
+                io_hdr.cmdp = inq_cmd;
+                io_hdr.sbp = sense;
+                io_hdr.timeout = DEF_TIMEOUT;
+                io_buf = (void *)&io_hdr;
+        }
+
+        retval = ioctl(fd, SG_IO, io_buf);
+        if (retval < 0) {
+                if ((errno == EINVAL || errno == ENOSYS) && dev_scsi->use_sg == 4) {
+                        dev_scsi->use_sg = 3;
+                        goto resend;
+                }
+                log_debug("%s: ioctl failed: %s\n", dev_scsi->kernel, strerror(errno));
+                goto error;
+        }
+
+        if (dev_scsi->use_sg == 4)
+                retval = sg_err_category4(udev, io_buf);
+        else
+                retval = sg_err_category3(udev, io_buf);
+
+        switch (retval) {
+                case SG_ERR_CAT_NOTSUPPORTED:
+                        buf[1] = 0;
+                        /* Fallthrough */
+                case SG_ERR_CAT_CLEAN:
+                case SG_ERR_CAT_RECOVERED:
+                        retval = 0;
+                        break;
+
+                default:
+                        if (dev_scsi->use_sg == 4)
+                                retval = scsi_dump_v4(udev, dev_scsi, io_buf);
+                        else
+                                retval = scsi_dump(udev, dev_scsi, io_buf);
+        }
+
+        if (!retval) {
+                retval = buflen;
+        } else if (retval > 0) {
+                if (--retry > 0)
+                        goto resend;
+                retval = -1;
+        }
+
+error:
+        if (retval < 0)
+                log_debug("%s: Unable to get INQUIRY vpd %d page 0x%x.\n",
+                    dev_scsi->kernel, evpd, page);
+
+        return retval;
+}
+
+/* Get list of supported EVPD pages */
+static int do_scsi_page0_inquiry(struct udev *udev,
+                                 struct scsi_id_device *dev_scsi, int fd,
+                                 unsigned char *buffer, unsigned int len)
+{
+        int retval;
+
+        memset(buffer, 0, len);
+        retval = scsi_inquiry(udev, dev_scsi, fd, 1, 0x0, buffer, len);
+        if (retval < 0)
+                return 1;
+
+        if (buffer[1] != 0) {
+                log_debug("%s: page 0 not available.\n", dev_scsi->kernel);
+                return 1;
+        }
+        if (buffer[3] > len) {
+                log_debug("%s: page 0 buffer too long %d\n", dev_scsi->kernel,         buffer[3]);
+                return 1;
+        }
+
+        /*
+         * Following check is based on code once included in the 2.5.x
+         * kernel.
+         *
+         * Some ill behaved devices return the standard inquiry here
+         * rather than the evpd data, snoop the data to verify.
+         */
+        if (buffer[3] > MODEL_LENGTH) {
+                /*
+                 * If the vendor id appears in the page assume the page is
+                 * invalid.
+                 */
+                if (!strncmp((char *)&buffer[VENDOR_LENGTH], dev_scsi->vendor, VENDOR_LENGTH)) {
+                        log_debug("%s: invalid page0 data\n", dev_scsi->kernel);
+                        return 1;
+                }
+        }
+        return 0;
+}
+
+/*
+ * The caller checks that serial is long enough to include the vendor +
+ * model.
+ */
+static int prepend_vendor_model(struct udev *udev,
+                                struct scsi_id_device *dev_scsi, char *serial)
+{
+        int ind;
+
+        strncpy(serial, dev_scsi->vendor, VENDOR_LENGTH);
+        strncat(serial, dev_scsi->model, MODEL_LENGTH);
+        ind = strlen(serial);
+
+        /*
+         * This is not a complete check, since we are using strncat/cpy
+         * above, ind will never be too large.
+         */
+        if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) {
+                log_debug("%s: expected length %d, got length %d\n",
+                     dev_scsi->kernel, (VENDOR_LENGTH + MODEL_LENGTH), ind);
+                return -1;
+        }
+        return ind;
+}
+
+/*
+ * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill
+ * serial number.
+ */
+static int check_fill_0x83_id(struct udev *udev,
+                              struct scsi_id_device *dev_scsi,
+                              unsigned char *page_83,
+                              const struct scsi_id_search_values
+                              *id_search, char *serial, char *serial_short,
+                              int max_len, char *wwn,
+                              char *wwn_vendor_extension, char *tgpt_group)
+{
+        int i, j, s, len;
+
+        /*
+         * ASSOCIATION must be with the device (value 0)
+         * or with the target port for SCSI_ID_TGTPORT
+         */
+        if ((page_83[1] & 0x30) == 0x10) {
+                if (id_search->id_type != SCSI_ID_TGTGROUP)
+                        return 1;
+        } else if ((page_83[1] & 0x30) != 0) {
+                return 1;
+        }
+
+        if ((page_83[1] & 0x0f) != id_search->id_type)
+                return 1;
+
+        /*
+         * Possibly check NAA sub-type.
+         */
+        if ((id_search->naa_type != SCSI_ID_NAA_DONT_CARE) &&
+            (id_search->naa_type != (page_83[4] & 0xf0) >> 4))
+                return 1;
+
+        /*
+         * Check for matching code set - ASCII or BINARY.
+         */
+        if ((page_83[0] & 0x0f) != id_search->code_set)
+                return 1;
+
+        /*
+         * page_83[3]: identifier length
+         */
+        len = page_83[3];
+        if ((page_83[0] & 0x0f) != SCSI_ID_ASCII)
+                /*
+                 * If not ASCII, use two bytes for each binary value.
+                 */
+                len *= 2;
+
+        /*
+         * Add one byte for the NUL termination, and one for the id_type.
+         */
+        len += 2;
+        if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC)
+                len += VENDOR_LENGTH + MODEL_LENGTH;
+
+        if (max_len < len) {
+                log_debug("%s: length %d too short - need %d\n",
+                    dev_scsi->kernel, max_len, len);
+                return 1;
+        }
+
+        if (id_search->id_type == SCSI_ID_TGTGROUP && tgpt_group != NULL) {
+                unsigned int group;
+
+                group = ((unsigned int)page_83[6] << 8) | page_83[7];
+                sprintf(tgpt_group,"%x", group);
+                return 1;
+        }
+
+        serial[0] = hex_str[id_search->id_type];
+
+        /*
+         * For SCSI_ID_VENDOR_SPECIFIC prepend the vendor and model before
+         * the id since it is not unique across all vendors and models,
+         * this differs from SCSI_ID_T10_VENDOR, where the vendor is
+         * included in the identifier.
+         */
+        if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC)
+                if (prepend_vendor_model(udev, dev_scsi, &serial[1]) < 0)
+                        return 1;
+
+        i = 4; /* offset to the start of the identifier */
+        s = j = strlen(serial);
+        if ((page_83[0] & 0x0f) == SCSI_ID_ASCII) {
+                /*
+                 * ASCII descriptor.
+                 */
+                while (i < (4 + page_83[3]))
+                        serial[j++] = page_83[i++];
+        } else {
+                /*
+                 * Binary descriptor, convert to ASCII, using two bytes of
+                 * ASCII for each byte in the page_83.
+                 */
+                while (i < (4 + page_83[3])) {
+                        serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4];
+                        serial[j++] = hex_str[page_83[i] & 0x0f];
+                        i++;
+                }
+        }
+
+        strcpy(serial_short, &serial[s]);
+
+        if (id_search->id_type == SCSI_ID_NAA && wwn != NULL) {
+                strncpy(wwn, &serial[s], 16);
+                if (wwn_vendor_extension != NULL) {
+                        strncpy(wwn_vendor_extension, &serial[s + 16], 16);
+                }
+        }
+
+        return 0;
+}
+
+/* Extract the raw binary from VPD 0x83 pre-SPC devices */
+static int check_fill_0x83_prespc3(struct udev *udev,
+                                   struct scsi_id_device *dev_scsi,
+                                   unsigned char *page_83,
+                                   const struct scsi_id_search_values
+                                   *id_search, char *serial, char *serial_short, int max_len)
+{
+        int i, j;
+
+        serial[0] = hex_str[id_search->id_type];
+        /* serial has been memset to zero before */
+        j = strlen(serial);        /* j = 1; */
+
+        for (i = 0; (i < page_83[3]) && (j < max_len-3); ++i) {
+                serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4];
+                serial[j++] = hex_str[ page_83[4+i] & 0x0f];
+        }
+        serial[max_len-1] = 0;
+        strncpy(serial_short, serial, max_len-1);
+        return 0;
+}
+
+
+/* Get device identification VPD page */
+static int do_scsi_page83_inquiry(struct udev *udev,
+                                  struct scsi_id_device *dev_scsi, int fd,
+                                  char *serial, char *serial_short, int len,
+                                  char *unit_serial_number, char *wwn,
+                                  char *wwn_vendor_extension, char *tgpt_group)
+{
+        int retval;
+        unsigned int id_ind, j;
+        unsigned char page_83[SCSI_INQ_BUFF_LEN];
+
+        /* also pick up the page 80 serial number */
+        do_scsi_page80_inquiry(udev, dev_scsi, fd, NULL, unit_serial_number, MAX_SERIAL_LEN);
+
+        memset(page_83, 0, SCSI_INQ_BUFF_LEN);
+        retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_83, page_83,
+                              SCSI_INQ_BUFF_LEN);
+        if (retval < 0)
+                return 1;
+
+        if (page_83[1] != PAGE_83) {
+                log_debug("%s: Invalid page 0x83\n", dev_scsi->kernel);
+                return 1;
+        }
+
+        /*
+         * XXX Some devices (IBM 3542) return all spaces for an identifier if
+         * the LUN is not actually configured. This leads to identifiers of
+         * the form: "1            ".
+         */
+
+        /*
+         * Model 4, 5, and (some) model 6 EMC Symmetrix devices return
+         * a page 83 reply according to SCSI-2 format instead of SPC-2/3.
+         *
+         * The SCSI-2 page 83 format returns an IEEE WWN in binary
+         * encoded hexi-decimal in the 16 bytes following the initial
+         * 4-byte page 83 reply header.
+         *
+         * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part
+         * of an Identification descriptor.  The 3rd byte of the first
+         * Identification descriptor is a reserved (BSZ) byte field.
+         *
+         * Reference the 7th byte of the page 83 reply to determine
+         * whether the reply is compliant with SCSI-2 or SPC-2/3
+         * specifications.  A zero value in the 7th byte indicates
+         * an SPC-2/3 conformant reply, (i.e., the reserved field of the
+         * first Identification descriptor).  This byte will be non-zero
+         * for a SCSI-2 conformant page 83 reply from these EMC
+         * Symmetrix models since the 7th byte of the reply corresponds
+         * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is,
+         * 0x006048.
+         */
+
+        if (page_83[6] != 0)
+                return check_fill_0x83_prespc3(udev,
+                                               dev_scsi, page_83, id_search_list,
+                                               serial, serial_short, len);
+
+        /*
+         * Search for a match in the prioritized id_search_list - since WWN ids
+         * come first we can pick up the WWN in check_fill_0x83_id().
+         */
+        for (id_ind = 0;
+             id_ind < sizeof(id_search_list)/sizeof(id_search_list[0]);
+             id_ind++) {
+                /*
+                 * Examine each descriptor returned. There is normally only
+                 * one or a small number of descriptors.
+                 */
+                for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) {
+                        retval = check_fill_0x83_id(udev,
+                                                    dev_scsi, &page_83[j],
+                                                    &id_search_list[id_ind],
+                                                    serial, serial_short, len,
+                                                    wwn, wwn_vendor_extension,
+                                                    tgpt_group);
+                        if (!retval)
+                                return retval;
+                        else if (retval < 0)
+                                return retval;
+                }
+        }
+        return 1;
+}
+
+/*
+ * Get device identification VPD page for older SCSI-2 device which is not
+ * compliant with either SPC-2 or SPC-3 format.
+ *
+ * Return the hard coded error code value 2 if the page 83 reply is not
+ * conformant to the SCSI-2 format.
+ */
+static int do_scsi_page83_prespc3_inquiry(struct udev *udev,
+                                          struct scsi_id_device *dev_scsi, int fd,
+                                          char *serial, char *serial_short, int len)
+{
+        int retval;
+        int i, j;
+        unsigned char page_83[SCSI_INQ_BUFF_LEN];
+
+        memset(page_83, 0, SCSI_INQ_BUFF_LEN);
+        retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN);
+        if (retval < 0)
+                return 1;
+
+        if (page_83[1] != PAGE_83) {
+                log_debug("%s: Invalid page 0x83\n", dev_scsi->kernel);
+                return 1;
+        }
+        /*
+         * Model 4, 5, and (some) model 6 EMC Symmetrix devices return
+         * a page 83 reply according to SCSI-2 format instead of SPC-2/3.
+         *
+         * The SCSI-2 page 83 format returns an IEEE WWN in binary
+         * encoded hexi-decimal in the 16 bytes following the initial
+         * 4-byte page 83 reply header.
+         *
+         * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part
+         * of an Identification descriptor.  The 3rd byte of the first
+         * Identification descriptor is a reserved (BSZ) byte field.
+         *
+         * Reference the 7th byte of the page 83 reply to determine
+         * whether the reply is compliant with SCSI-2 or SPC-2/3
+         * specifications.  A zero value in the 7th byte indicates
+         * an SPC-2/3 conformant reply, (i.e., the reserved field of the
+         * first Identification descriptor).  This byte will be non-zero
+         * for a SCSI-2 conformant page 83 reply from these EMC
+         * Symmetrix models since the 7th byte of the reply corresponds
+         * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is,
+         * 0x006048.
+         */
+        if (page_83[6] == 0)
+                return 2;
+
+        serial[0] = hex_str[id_search_list[0].id_type];
+        /*
+         * The first four bytes contain data, not a descriptor.
+         */
+        i = 4;
+        j = strlen(serial);
+        /*
+         * Binary descriptor, convert to ASCII,
+         * using two bytes of ASCII for each byte
+         * in the page_83.
+         */
+        while (i < (page_83[3]+4)) {
+                serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4];
+                serial[j++] = hex_str[page_83[i] & 0x0f];
+                i++;
+        }
+        return 0;
+}
+
+/* Get unit serial number VPD page */
+static int do_scsi_page80_inquiry(struct udev *udev,
+                                  struct scsi_id_device *dev_scsi, int fd,
+                                  char *serial, char *serial_short, int max_len)
+{
+        int retval;
+        int ser_ind;
+        int i;
+        int len;
+        unsigned char buf[SCSI_INQ_BUFF_LEN];
+
+        memset(buf, 0, SCSI_INQ_BUFF_LEN);
+        retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN);
+        if (retval < 0)
+                return retval;
+
+        if (buf[1] != PAGE_80) {
+                log_debug("%s: Invalid page 0x80\n", dev_scsi->kernel);
+                return 1;
+        }
+
+        len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3];
+        if (max_len < len) {
+                log_debug("%s: length %d too short - need %d\n",
+                     dev_scsi->kernel, max_len, len);
+                return 1;
+        }
+        /*
+         * Prepend 'S' to avoid unlikely collision with page 0x83 vendor
+         * specific type where we prepend '0' + vendor + model.
+         */
+        len = buf[3];
+        if (serial != NULL) {
+                serial[0] = 'S';
+                ser_ind = prepend_vendor_model(udev, dev_scsi, &serial[1]);
+                if (ser_ind < 0)
+                        return 1;
+                ser_ind++;     /* for the leading 'S' */
+                for (i = 4; i < len + 4; i++, ser_ind++)
+                        serial[ser_ind] = buf[i];
+        }
+        if (serial_short != NULL) {
+                memcpy(serial_short, &buf[4], len);
+                serial_short[len] = '\0';
+        }
+        return 0;
+}
+
+int scsi_std_inquiry(struct udev *udev,
+                     struct scsi_id_device *dev_scsi, const char *devname)
+{
+        int fd;
+        unsigned char buf[SCSI_INQ_BUFF_LEN];
+        struct stat statbuf;
+        int err = 0;
+
+        fd = open(devname, O_RDONLY | O_NONBLOCK);
+        if (fd < 0) {
+                log_debug("scsi_id: cannot open %s: %s\n",
+                     devname, strerror(errno));
+                return 1;
+        }
+
+        if (fstat(fd, &statbuf) < 0) {
+                log_debug("scsi_id: cannot stat %s: %s\n",
+                     devname, strerror(errno));
+                err = 2;
+                goto out;
+        }
+        sprintf(dev_scsi->kernel,"%d:%d", major(statbuf.st_rdev),
+                minor(statbuf.st_rdev));
+
+        memset(buf, 0, SCSI_INQ_BUFF_LEN);
+        err = scsi_inquiry(udev, dev_scsi, fd, 0, 0, buf, SCSI_INQ_BUFF_LEN);
+        if (err < 0)
+                goto out;
+
+        err = 0;
+        memcpy(dev_scsi->vendor, buf + 8, 8);
+        dev_scsi->vendor[8] = '\0';
+        memcpy(dev_scsi->model, buf + 16, 16);
+        dev_scsi->model[16] = '\0';
+        memcpy(dev_scsi->revision, buf + 32, 4);
+        dev_scsi->revision[4] = '\0';
+        sprintf(dev_scsi->type,"%x", buf[0] & 0x1f);
+
+out:
+        close(fd);
+        return err;
+}
+
+int scsi_get_serial(struct udev *udev,
+                    struct scsi_id_device *dev_scsi, const char *devname,
+                    int page_code, int len)
+{
+        unsigned char page0[SCSI_INQ_BUFF_LEN];
+        int fd = -1;
+        int cnt;
+        int ind;
+        int retval;
+
+        memset(dev_scsi->serial, 0, len);
+        srand((unsigned int)getpid());
+        for (cnt = 20; cnt > 0; cnt--) {
+                struct timespec duration;
+
+                fd = open(devname, O_RDONLY | O_NONBLOCK);
+                if (fd >= 0 || errno != EBUSY)
+                        break;
+                duration.tv_sec = 0;
+                duration.tv_nsec = (200 * 1000 * 1000) + (rand() % 100 * 1000 * 1000);
+                nanosleep(&duration, NULL);
+        }
+        if (fd < 0)
+                return 1;
+
+        if (page_code == PAGE_80) {
+                if (do_scsi_page80_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len)) {
+                        retval = 1;
+                        goto completed;
+                } else  {
+                        retval = 0;
+                        goto completed;
+                }
+        } else if (page_code == PAGE_83) {
+                if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) {
+                        retval = 1;
+                        goto completed;
+                } else  {
+                        retval = 0;
+                        goto completed;
+                }
+        } else if (page_code == PAGE_83_PRE_SPC3) {
+                retval = do_scsi_page83_prespc3_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len);
+                if (retval) {
+                        /*
+                         * Fallback to servicing a SPC-2/3 compliant page 83
+                         * inquiry if the page 83 reply format does not
+                         * conform to pre-SPC3 expectations.
+                         */
+                        if (retval == 2) {
+                                if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) {
+                                        retval = 1;
+                                        goto completed;
+                                } else  {
+                                        retval = 0;
+                                        goto completed;
+                                }
+                        }
+                        else {
+                                retval = 1;
+                                goto completed;
+                        }
+                } else  {
+                        retval = 0;
+                        goto completed;
+                }
+        } else if (page_code != 0x00) {
+                log_debug("%s: unsupported page code 0x%d\n", dev_scsi->kernel, page_code);
+                retval = 1;
+                goto completed;
+        }
+
+        /*
+         * Get page 0, the page of the pages. By default, try from best to
+         * worst of supported pages: 0x83 then 0x80.
+         */
+        if (do_scsi_page0_inquiry(udev, dev_scsi, fd, page0, SCSI_INQ_BUFF_LEN)) {
+                /*
+                 * Don't try anything else. Black list if a specific page
+                 * should be used for this vendor+model, or maybe have an
+                 * optional fall-back to page 0x80 or page 0x83.
+                 */
+                retval = 1;
+                goto completed;
+        }
+
+        for (ind = 4; ind <= page0[3] + 3; ind++)
+                if (page0[ind] == PAGE_83)
+                        if (!do_scsi_page83_inquiry(udev, dev_scsi, fd,
+                                                    dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) {
+                                /*
+                                 * Success
+                                 */
+                                retval = 0;
+                                goto completed;
+                        }
+
+        for (ind = 4; ind <= page0[3] + 3; ind++)
+                if (page0[ind] == PAGE_80)
+                        if (!do_scsi_page80_inquiry(udev, dev_scsi, fd,
+                                                    dev_scsi->serial, dev_scsi->serial_short, len)) {
+                                /*
+                                 * Success
+                                 */
+                                retval = 0;
+                                goto completed;
+                        }
+        retval = 1;
+
+completed:
+        close(fd);
+        return retval;
+}
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
new file mode 100644 (file)
index 0000000..4293103
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * probe disks for filesystems and partitions
+ *
+ * Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2011 Karel Zak <kzak@redhat.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/stat.h>
+#include <blkid/blkid.h>
+
+#include "udev.h"
+
+static void print_property(struct udev_device *dev, bool test, const char *name, const char *value)
+{
+        char s[265];
+
+        s[0] = '\0';
+
+        if (streq(name, "TYPE")) {
+                udev_builtin_add_property(dev, test, "ID_FS_TYPE", value);
+
+        } else if (streq(name, "USAGE")) {
+                udev_builtin_add_property(dev, test, "ID_FS_USAGE", value);
+
+        } else if (streq(name, "VERSION")) {
+                udev_builtin_add_property(dev, test, "ID_FS_VERSION", value);
+
+        } else if (streq(name, "UUID")) {
+                blkid_safe_string(value, s, sizeof(s));
+                udev_builtin_add_property(dev, test, "ID_FS_UUID", s);
+                blkid_encode_string(value, s, sizeof(s));
+                udev_builtin_add_property(dev, test, "ID_FS_UUID_ENC", s);
+
+        } else if (streq(name, "UUID_SUB")) {
+                blkid_safe_string(value, s, sizeof(s));
+                udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB", s);
+                blkid_encode_string(value, s, sizeof(s));
+                udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB_ENC", s);
+
+        } else if (streq(name, "LABEL")) {
+                blkid_safe_string(value, s, sizeof(s));
+                udev_builtin_add_property(dev, test, "ID_FS_LABEL", s);
+                blkid_encode_string(value, s, sizeof(s));
+                udev_builtin_add_property(dev, test, "ID_FS_LABEL_ENC", s);
+
+        } else if (streq(name, "PTTYPE")) {
+                udev_builtin_add_property(dev, test, "ID_PART_TABLE_TYPE", value);
+
+        } else if (streq(name, "PART_ENTRY_NAME")) {
+                blkid_encode_string(value, s, sizeof(s));
+                udev_builtin_add_property(dev, test, "ID_PART_ENTRY_NAME", s);
+
+        } else if (streq(name, "PART_ENTRY_TYPE")) {
+                blkid_encode_string(value, s, sizeof(s));
+                udev_builtin_add_property(dev, test, "ID_PART_ENTRY_TYPE", s);
+
+        } else if (startswith(name, "PART_ENTRY_")) {
+                util_strscpyl(s, sizeof(s), "ID_", name, NULL);
+                udev_builtin_add_property(dev, test, s, value);
+        }
+}
+
+static int probe_superblocks(blkid_probe pr)
+{
+        struct stat st;
+        int rc;
+
+        if (fstat(blkid_probe_get_fd(pr), &st))
+                return -1;
+
+        blkid_probe_enable_partitions(pr, 1);
+
+        if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 &&
+            blkid_probe_is_wholedisk(pr)) {
+                /*
+                 * check if the small disk is partitioned, if yes then
+                 * don't probe for filesystems.
+                 */
+                blkid_probe_enable_superblocks(pr, 0);
+
+                rc = blkid_do_fullprobe(pr);
+                if (rc < 0)
+                        return rc;        /* -1 = error, 1 = nothing, 0 = succes */
+
+                if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0)
+                        return 0;        /* partition table detected */
+        }
+
+        blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
+        blkid_probe_enable_superblocks(pr, 1);
+
+        return blkid_do_safeprobe(pr);
+}
+
+static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test)
+{
+        int64_t offset = 0;
+        bool noraid = false;
+        int fd = -1;
+        blkid_probe pr;
+        const char *data;
+        const char *name;
+        int nvals;
+        int i;
+        size_t len;
+        int err = 0;
+
+        static const struct option options[] = {
+                { "offset", optional_argument, NULL, 'o' },
+                { "noraid", no_argument, NULL, 'R' },
+                {}
+        };
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "oR", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'o':
+                        offset = strtoull(optarg, NULL, 0);
+                        break;
+                case 'R':
+                        noraid = true;
+                        break;
+                }
+        }
+
+        pr = blkid_new_probe();
+        if (!pr)
+                return EXIT_FAILURE;
+
+        blkid_probe_set_superblocks_flags(pr,
+                BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
+                BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
+                BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);
+
+        if (noraid)
+                blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID);
+
+        fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC);
+        if (fd < 0) {
+                fprintf(stderr, "error: %s: %m\n", udev_device_get_devnode(dev));
+                goto out;
+        }
+
+        err = blkid_probe_set_device(pr, fd, offset, 0);
+        if (err < 0)
+                goto out;
+
+        log_debug("probe %s %sraid offset=%llu\n",
+                  udev_device_get_devnode(dev),
+                  noraid ? "no" : "", (unsigned long long) offset);
+
+        err = probe_superblocks(pr);
+        if (err < 0)
+                goto out;
+
+        nvals = blkid_probe_numof_values(pr);
+        for (i = 0; i < nvals; i++) {
+                if (blkid_probe_get_value(pr, i, &name, &data, &len))
+                        continue;
+                len = strnlen((char *) data, len);
+                print_property(dev, test, name, (char *) data);
+        }
+
+        blkid_free_probe(pr);
+out:
+        if (fd > 0)
+                close(fd);
+        if (err < 0)
+                return EXIT_FAILURE;
+        return EXIT_SUCCESS;
+}
+
+const struct udev_builtin udev_builtin_blkid = {
+        .name = "blkid",
+        .cmd = builtin_blkid,
+        .help = "filesystem and partition probing",
+        .run_once = true,
+};
diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c
new file mode 100644 (file)
index 0000000..dfb0552
--- /dev/null
@@ -0,0 +1,65 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#include "udev.h"
+
+#define BTRFS_PATH_NAME_MAX 4087
+struct btrfs_ioctl_vol_args {
+        int64_t fd;
+        char name[BTRFS_PATH_NAME_MAX + 1];
+};
+#define BTRFS_IOCTL_MAGIC 0x94
+#define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, struct btrfs_ioctl_vol_args)
+
+static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test)
+{
+        struct  btrfs_ioctl_vol_args args;
+        int fd;
+        int err;
+
+        if (argc != 3 || !streq(argv[1], "ready"))
+                return EXIT_FAILURE;
+
+        fd = open("/dev/btrfs-control", O_RDWR);
+        if (fd < 0)
+                return EXIT_FAILURE;
+
+        util_strscpy(args.name, sizeof(args.name), argv[2]);
+        err = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args);
+        close(fd);
+        if (err < 0)
+                return EXIT_FAILURE;
+
+        udev_builtin_add_property(dev, test, "ID_BTRFS_READY", err == 0 ? "1" : "0");
+        return EXIT_SUCCESS;
+}
+
+const struct udev_builtin udev_builtin_btrfs = {
+        .name = "btrfs",
+        .cmd = builtin_btrfs,
+        .help = "btrfs volume management",
+};
diff --git a/src/udev/udev-builtin-firmware.c b/src/udev/udev-builtin-firmware.c
new file mode 100644 (file)
index 0000000..4a91d33
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * firmware - Kernel firmware loader
+ *
+ * Copyright (C) 2009 Piter Punk <piterpunk@slackware.com>
+ * Copyright (C) 2009-2011 Kay Sievers <kay@vrfy.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:*
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+
+#include "udev.h"
+
+static bool set_loading(struct udev *udev, char *loadpath, const char *state)
+{
+        FILE *ldfile;
+
+        ldfile = fopen(loadpath, "we");
+        if (ldfile == NULL) {
+                log_error("error: can not open '%s'\n", loadpath);
+                return false;
+        };
+        fprintf(ldfile, "%s\n", state);
+        fclose(ldfile);
+        return true;
+}
+
+static bool copy_firmware(struct udev *udev, const char *source, const char *target, size_t size)
+{
+        char *buf;
+        FILE *fsource = NULL, *ftarget = NULL;
+        bool ret = false;
+
+        buf = malloc(size);
+        if (buf == NULL) {
+                log_error("No memory available to load firmware file");
+                return false;
+        }
+
+        log_debug("writing '%s' (%zi) to '%s'\n", source, size, target);
+
+        fsource = fopen(source, "re");
+        if (fsource == NULL)
+                goto exit;
+        ftarget = fopen(target, "we");
+        if (ftarget == NULL)
+                goto exit;
+        if (fread(buf, size, 1, fsource) != 1)
+                goto exit;
+        if (fwrite(buf, size, 1, ftarget) == 1)
+                ret = true;
+exit:
+        if (ftarget != NULL)
+                fclose(ftarget);
+        if (fsource != NULL)
+                fclose(fsource);
+        free(buf);
+        return ret;
+}
+
+static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], bool test)
+{
+        struct udev *udev = udev_device_get_udev(dev);
+        static const char *searchpath[] = { FIRMWARE_PATH };
+        char fwencpath[UTIL_PATH_SIZE];
+        char misspath[UTIL_PATH_SIZE];
+        char loadpath[UTIL_PATH_SIZE];
+        char datapath[UTIL_PATH_SIZE];
+        char fwpath[UTIL_PATH_SIZE];
+        const char *firmware;
+        FILE *fwfile = NULL;
+        struct utsname kernel;
+        struct stat statbuf;
+        unsigned int i;
+        int rc = EXIT_SUCCESS;
+
+        firmware = udev_device_get_property_value(dev, "FIRMWARE");
+        if (firmware == NULL) {
+                log_error("firmware parameter missing\n\n");
+                rc = EXIT_FAILURE;
+                goto exit;
+        }
+
+        /* lookup firmware file */
+        uname(&kernel);
+        for (i = 0; i < ELEMENTSOF(searchpath); i++) {
+                util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], kernel.release, "/", firmware, NULL);
+                fwfile = fopen(fwpath, "re");
+                if (fwfile != NULL)
+                        break;
+
+                util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], firmware, NULL);
+                fwfile = fopen(fwpath, "re");
+                if (fwfile != NULL)
+                        break;
+        }
+
+        util_path_encode(firmware, fwencpath, sizeof(fwencpath));
+        util_strscpyl(misspath, sizeof(misspath), "/run/udev/firmware-missing/", fwencpath, NULL);
+        util_strscpyl(loadpath, sizeof(loadpath), udev_device_get_syspath(dev), "/loading", NULL);
+
+        if (fwfile == NULL) {
+                int err;
+
+                /* This link indicates the missing firmware file and the associated device */
+                log_debug("did not find firmware file '%s'\n", firmware);
+                do {
+                        err = mkdir_parents(misspath, 0755);
+                        if (err != 0 && err != -ENOENT)
+                                break;
+                        err = symlink(udev_device_get_devpath(dev), misspath);
+                        if (err != 0)
+                                err = -errno;
+                } while (err == -ENOENT);
+                rc = EXIT_FAILURE;
+                /*
+                 * Do not cancel the request in the initrd, the real root might have
+                 * the firmware file and the 'coldplug' run in the real root will find
+                 * this pending request and fulfill or cancel it.
+                 * */
+                if (!in_initrd())
+                        set_loading(udev, loadpath, "-1");
+                goto exit;
+        }
+
+        if (stat(fwpath, &statbuf) < 0 || statbuf.st_size == 0) {
+                if (!in_initrd())
+                        set_loading(udev, loadpath, "-1");
+                rc = EXIT_FAILURE;
+                goto exit;
+        }
+
+        if (unlink(misspath) == 0)
+                util_delete_path(udev, misspath);
+
+        if (!set_loading(udev, loadpath, "1"))
+                goto exit;
+
+        util_strscpyl(datapath, sizeof(datapath), udev_device_get_syspath(dev), "/data", NULL);
+        if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
+                log_error("error sending firmware '%s' to device\n", firmware);
+                set_loading(udev, loadpath, "-1");
+                rc = EXIT_FAILURE;
+                goto exit;
+        };
+
+        set_loading(udev, loadpath, "0");
+exit:
+        if (fwfile)
+                fclose(fwfile);
+        return rc;
+}
+
+const struct udev_builtin udev_builtin_firmware = {
+        .name = "firmware",
+        .cmd = builtin_firmware,
+        .help = "kernel firmware loader",
+        .run_once = true,
+};
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
new file mode 100644 (file)
index 0000000..0b35d79
--- /dev/null
@@ -0,0 +1,162 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "udev.h"
+
+static struct udev_hwdb *hwdb;
+
+int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, bool test) {
+        struct udev_list_entry *entry;
+        int n = 0;
+
+        if (!hwdb)
+                return -ENOENT;
+
+        udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0)) {
+                if (udev_builtin_add_property(dev, test,
+                                              udev_list_entry_get_name(entry),
+                                              udev_list_entry_get_value(entry)) < 0)
+                        return -ENOMEM;
+                n++;
+        }
+        return n;
+}
+
+static const char *modalias_usb(struct udev_device *dev, char *s, size_t size) {
+        const char *v, *p;
+        int vn, pn;
+
+        v = udev_device_get_sysattr_value(dev, "idVendor");
+        if (!v)
+                return NULL;
+        p = udev_device_get_sysattr_value(dev, "idProduct");
+        if (!p)
+                return NULL;
+        vn = strtol(v, NULL, 16);
+        if (vn <= 0)
+                return NULL;
+        pn = strtol(p, NULL, 16);
+        if (pn <= 0)
+                return NULL;
+        snprintf(s, size, "usb:v%04Xp%04X*", vn, pn);
+        return s;
+}
+
+static int udev_builtin_hwdb_search(struct udev_device *dev, const char *subsystem, bool test) {
+        struct udev_device *d;
+        char s[16];
+        int n = 0;
+
+        for (d = dev; d; d = udev_device_get_parent(d)) {
+                const char *dsubsys;
+                const char *modalias = NULL;
+
+                dsubsys = udev_device_get_subsystem(d);
+                if (!dsubsys)
+                        continue;
+
+                /* look only at devices of a specific subsystem */
+                if (subsystem && !streq(dsubsys, subsystem))
+                        continue;
+
+                /* the usb_device does not have a modalias, compose one */
+                if (streq(dsubsys, "usb"))
+                        modalias = modalias_usb(dev, s, sizeof(s));
+
+                if (!modalias)
+                        modalias = udev_device_get_property_value(d, "MODALIAS");
+
+                if (!modalias)
+                        continue;
+                n = udev_builtin_hwdb_lookup(dev, modalias, test);
+                if (n > 0)
+                        break;
+        }
+
+        return n;
+}
+
+static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool test) {
+        static const struct option options[] = {
+                { "subsystem", required_argument, NULL, 's' },
+                {}
+        };
+        const char *subsystem = NULL;
+
+        if (!hwdb)
+                return EXIT_FAILURE;
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "s", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 's':
+                        subsystem = optarg;
+                        break;
+                }
+        }
+
+        if (udev_builtin_hwdb_search(dev, subsystem, test) < 0)
+                return EXIT_FAILURE;
+        return EXIT_SUCCESS;
+}
+
+/* called at udev startup and reload */
+static int builtin_hwdb_init(struct udev *udev)
+{
+        if (hwdb)
+                return 0;
+        hwdb = udev_hwdb_new(udev);
+        if (!hwdb)
+                return -ENOMEM;
+        return 0;
+}
+
+/* called on udev shutdown and reload request */
+static void builtin_hwdb_exit(struct udev *udev)
+{
+        hwdb = udev_hwdb_unref(hwdb);
+}
+
+/* called every couple of seconds during event activity; 'true' if config has changed */
+static bool builtin_hwdb_validate(struct udev *udev)
+{
+        return udev_hwdb_validate(hwdb);
+}
+
+const struct udev_builtin udev_builtin_hwdb = {
+        .name = "hwdb",
+        .cmd = builtin_hwdb,
+        .init = builtin_hwdb_init,
+        .exit = builtin_hwdb_exit,
+        .validate = builtin_hwdb_validate,
+        .help = "hardware database",
+};
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
new file mode 100644 (file)
index 0000000..445b602
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * compose persistent device path
+ *
+ * Copyright (C) 2009 Martin Pitt <martin.pitt@ubuntu.com>
+ * Portions Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2011 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <linux/limits.h>
+#include <linux/input.h>
+
+#include "udev.h"
+
+/* we must use this kernel-compatible implementation */
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define OFF(x)  ((x)%BITS_PER_LONG)
+#define BIT(x)  (1UL<<OFF(x))
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+/*
+ * Read a capability attribute and return bitmask.
+ * @param dev udev_device
+ * @param attr sysfs attribute name (e. g. "capabilities/key")
+ * @param bitmask: Output array which has a sizeof of bitmask_size
+ */
+static void get_cap_mask(struct udev_device *dev,
+                         struct udev_device *pdev, const char* attr,
+                         unsigned long *bitmask, size_t bitmask_size,
+                         bool test)
+{
+        char text[4096];
+        unsigned i;
+        char* word;
+        unsigned long val;
+
+        snprintf(text, sizeof(text), "%s", udev_device_get_sysattr_value(pdev, attr));
+        log_debug("%s raw kernel attribute: %s\n", attr, text);
+
+        memset (bitmask, 0, bitmask_size);
+        i = 0;
+        while ((word = strrchr(text, ' ')) != NULL) {
+                val = strtoul (word+1, NULL, 16);
+                if (i < bitmask_size/sizeof(unsigned long))
+                        bitmask[i] = val;
+                else
+                        log_debug("ignoring %s block %lX which is larger than maximum size\n", attr, val);
+                *word = '\0';
+                ++i;
+        }
+        val = strtoul (text, NULL, 16);
+        if (i < bitmask_size / sizeof(unsigned long))
+                bitmask[i] = val;
+        else
+                log_debug("ignoring %s block %lX which is larger than maximum size\n", attr, val);
+
+        if (test) {
+                /* printf pattern with the right unsigned long number of hex chars */
+                snprintf(text, sizeof(text), "  bit %%4u: %%0%zilX\n", 2 * sizeof(unsigned long));
+                log_debug("%s decoded bit map:\n", attr);
+                val = bitmask_size / sizeof (unsigned long);
+                /* skip over leading zeros */
+                while (bitmask[val-1] == 0 && val > 0)
+                        --val;
+                for (i = 0; i < val; ++i)
+                        log_debug(text, i * BITS_PER_LONG, bitmask[i]);
+        }
+}
+#pragma GCC diagnostic pop
+
+/* pointer devices */
+static void test_pointers (struct udev_device *dev,
+                           const unsigned long* bitmask_ev,
+                           const unsigned long* bitmask_abs,
+                           const unsigned long* bitmask_key,
+                           const unsigned long* bitmask_rel,
+                           bool test)
+{
+        int is_mouse = 0;
+        int is_touchpad = 0;
+
+        if (!test_bit (EV_KEY, bitmask_ev)) {
+                if (test_bit (EV_ABS, bitmask_ev) &&
+                    test_bit (ABS_X, bitmask_abs) &&
+                    test_bit (ABS_Y, bitmask_abs) &&
+                    test_bit (ABS_Z, bitmask_abs))
+                        udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1");
+                return;
+        }
+
+        if (test_bit (EV_ABS, bitmask_ev) &&
+            test_bit (ABS_X, bitmask_abs) && test_bit (ABS_Y, bitmask_abs)) {
+                if (test_bit (BTN_STYLUS, bitmask_key) || test_bit (BTN_TOOL_PEN, bitmask_key))
+                        udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");
+                else if (test_bit (BTN_TOOL_FINGER, bitmask_key) && !test_bit (BTN_TOOL_PEN, bitmask_key))
+                        is_touchpad = 1;
+                else if (test_bit (BTN_TRIGGER, bitmask_key) ||
+                         test_bit (BTN_A, bitmask_key) ||
+                         test_bit (BTN_1, bitmask_key))
+                        udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
+                else if (test_bit (BTN_MOUSE, bitmask_key))
+                        /* This path is taken by VMware's USB mouse, which has
+                         * absolute axes, but no touch/pressure button. */
+                        is_mouse = 1;
+                else if (test_bit (BTN_TOUCH, bitmask_key))
+                        udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
+        }
+
+        if (test_bit (EV_REL, bitmask_ev) &&
+            test_bit (REL_X, bitmask_rel) && test_bit (REL_Y, bitmask_rel) &&
+            test_bit (BTN_MOUSE, bitmask_key))
+                is_mouse = 1;
+
+        if (is_mouse)
+                udev_builtin_add_property(dev, test, "ID_INPUT_MOUSE", "1");
+        if (is_touchpad)
+                udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHPAD", "1");
+}
+
+/* key like devices */
+static void test_key (struct udev_device *dev,
+                      const unsigned long* bitmask_ev,
+                      const unsigned long* bitmask_key,
+                      bool test)
+{
+        unsigned i;
+        unsigned long found;
+        unsigned long mask;
+
+        /* do we have any KEY_* capability? */
+        if (!test_bit (EV_KEY, bitmask_ev)) {
+                log_debug("test_key: no EV_KEY capability\n");
+                return;
+        }
+
+        /* only consider KEY_* here, not BTN_* */
+        found = 0;
+        for (i = 0; i < BTN_MISC/BITS_PER_LONG; ++i) {
+                found |= bitmask_key[i];
+                log_debug("test_key: checking bit block %lu for any keys; found=%i\n", (unsigned long)i*BITS_PER_LONG, found > 0);
+        }
+        /* If there are no keys in the lower block, check the higher block */
+        if (!found) {
+                for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; ++i) {
+                        if (test_bit (i, bitmask_key)) {
+                                log_debug("test_key: Found key %x in high block\n", i);
+                                found = 1;
+                                break;
+                        }
+                }
+        }
+
+        if (found > 0)
+                udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1");
+
+        /* the first 32 bits are ESC, numbers, and Q to D; if we have all of
+         * those, consider it a full keyboard; do not test KEY_RESERVED, though */
+        mask = 0xFFFFFFFE;
+        if ((bitmask_key[0] & mask) == mask)
+                udev_builtin_add_property(dev, test, "ID_INPUT_KEYBOARD", "1");
+}
+
+static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test)
+{
+        struct udev_device *pdev;
+        unsigned long bitmask_ev[NBITS(EV_MAX)];
+        unsigned long bitmask_abs[NBITS(ABS_MAX)];
+        unsigned long bitmask_key[NBITS(KEY_MAX)];
+        unsigned long bitmask_rel[NBITS(REL_MAX)];
+
+        /* walk up the parental chain until we find the real input device; the
+         * argument is very likely a subdevice of this, like eventN */
+        pdev = dev;
+        while (pdev != NULL && udev_device_get_sysattr_value(pdev, "capabilities/ev") == NULL)
+                pdev = udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
+
+        /* not an "input" class device */
+        if (pdev == NULL)
+                return EXIT_SUCCESS;
+
+        /* Use this as a flag that input devices were detected, so that this
+         * program doesn't need to be called more than once per device */
+        udev_builtin_add_property(dev, test, "ID_INPUT", "1");
+        get_cap_mask(dev, pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), test);
+        get_cap_mask(dev, pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), test);
+        get_cap_mask(dev, pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), test);
+        get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test);
+        test_pointers(dev, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, test);
+        test_key(dev, bitmask_ev, bitmask_key, test);
+        return EXIT_SUCCESS;
+}
+
+const struct udev_builtin udev_builtin_input_id = {
+        .name = "input_id",
+        .cmd = builtin_input_id,
+        .help = "input device properties",
+};
diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c
new file mode 100644 (file)
index 0000000..17aca29
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * load kernel modules
+ *
+ * Copyright (C) 2011-2012 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2011 ProFUSION embedded systems
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <libkmod.h>
+
+#include "udev.h"
+
+static struct kmod_ctx *ctx;
+
+static int load_module(struct udev *udev, const char *alias)
+{
+        struct kmod_list *list = NULL;
+        struct kmod_list *l;
+        int err;
+
+        err = kmod_module_new_from_lookup(ctx, alias, &list);
+        if (err < 0)
+                return err;
+
+        if (list == NULL)
+                log_debug("no module matches '%s'\n", alias);
+
+        kmod_list_foreach(l, list) {
+                struct kmod_module *mod = kmod_module_get_module(l);
+
+                err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
+                if (err == KMOD_PROBE_APPLY_BLACKLIST)
+                        log_debug("module '%s' is blacklisted\n", kmod_module_get_name(mod));
+                else if (err == 0)
+                        log_debug("inserted '%s'\n", kmod_module_get_name(mod));
+                else
+                        log_debug("failed to insert '%s'\n", kmod_module_get_name(mod));
+
+                kmod_module_unref(mod);
+        }
+
+        kmod_module_unref_list(list);
+        return err;
+}
+
+static void udev_kmod_log(void *data, int priority, const char *file, int line,
+                          const char *fn, const char *format, va_list args)
+{
+        udev_main_log(data, priority, file, line, fn, format, args);
+}
+
+static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test)
+{
+        struct udev *udev = udev_device_get_udev(dev);
+        int i;
+
+        if (!ctx)
+                return 0;
+
+        if (argc < 3 || strcmp(argv[1], "load")) {
+                log_error("expect: %s load <module>\n", argv[0]);
+                return EXIT_FAILURE;
+        }
+
+        for (i = 2; argv[i]; i++) {
+                log_debug("execute '%s' '%s'\n", argv[1], argv[i]);
+                load_module(udev, argv[i]);
+        }
+
+        return EXIT_SUCCESS;
+}
+
+/* called at udev startup and reload */
+static int builtin_kmod_init(struct udev *udev)
+{
+        if (ctx)
+                return 0;
+
+        ctx = kmod_new(NULL, NULL);
+        if (!ctx)
+                return -ENOMEM;
+
+        log_debug("load module index\n");
+        kmod_set_log_fn(ctx, udev_kmod_log, udev);
+        kmod_load_resources(ctx);
+        return 0;
+}
+
+/* called on udev shutdown and reload request */
+static void builtin_kmod_exit(struct udev *udev)
+{
+        log_debug("unload module index\n");
+        ctx = kmod_unref(ctx);
+}
+
+/* called every couple of seconds during event activity; 'true' if config has changed */
+static bool builtin_kmod_validate(struct udev *udev)
+{
+        log_debug("validate module index\n");
+        if (!ctx)
+                return false;
+        return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK);
+}
+
+const struct udev_builtin udev_builtin_kmod = {
+        .name = "kmod",
+        .cmd = builtin_kmod,
+        .init = builtin_kmod_init,
+        .exit = builtin_kmod_exit,
+        .validate = builtin_kmod_validate,
+        .help = "kernel module loader",
+        .run_once = false,
+};
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
new file mode 100644 (file)
index 0000000..d5db762
--- /dev/null
@@ -0,0 +1,452 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Predictable network interface device names based on:
+ *  - firmware/bios-provided index numbers for on-board devices
+ *  - firmware-provided pci-express hotplug slot index number
+ *  - physical/geographical location of the hardware
+ *  - the interface's MAC address
+ *
+ * Two character prefixes based on the type of interface:
+ *   en -- ethernet
+ *   wl -- wlan
+ *   ww -- wwan
+ *
+ * Type of names:
+ *   o<index>                              -- on-board device index number
+ *   s<slot>[f<function>][d<dev_id>]       -- hotplug slot index number
+ *   x<MAC>                                -- MAC address
+ *   p<bus>s<slot>[f<function>][d<dev_id>] -- PCI geographical location
+ *   p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
+ *                                         -- USB port number chain
+ *
+ * All multi-function PCI devices will carry the [f<function>] number in the
+ * device name, including the function 0 device.
+ *
+ * For USB devices the full chain of port numbers of hubs is composed. If the
+ * name gets longer than the maximum number of 15 characters, the name is not
+ * exported.
+ * The usual USB configuration == 1 and interface == 0 values are suppressed.
+ *
+ * PCI ethernet card with firmware index "1":
+ *   ID_NET_NAME_ONBOARD=eno1
+ *   ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
+ *
+ * PCI ethernet card in hotplug slot with firmware index number:
+ *   /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
+ *   ID_NET_NAME_MAC=enx000000000466
+ *   ID_NET_NAME_PATH=enp5s0
+ *   ID_NET_NAME_SLOT=ens1
+ *
+ * PCI ethernet multi-function card with 2 ports:
+ *   /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
+ *   ID_NET_NAME_MAC=enx78e7d1ea46da
+ *   ID_NET_NAME_PATH=enp2s0f0
+ *   /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1
+ *   ID_NET_NAME_MAC=enx78e7d1ea46dc
+ *   ID_NET_NAME_PATH=enp2s0f1
+ *
+ * PCI wlan card:
+ *   /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0
+ *   ID_NET_NAME_MAC=wlx0024d7e31130
+ *   ID_NET_NAME_PATH=wlp3s0
+ *
+ * USB built-in 3G modem:
+ *   /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6
+ *   ID_NET_NAME_MAC=wwx028037ec0200
+ *   ID_NET_NAME_PATH=wwp0s29u1u4i6
+ *
+ * USB Android phone:
+ *   /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
+ *   ID_NET_NAME_MAC=enxd626b3450fb5
+ *   ID_NET_NAME_PATH=enp0s29u1u2
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <net/if.h>
+#include <linux/pci_regs.h>
+
+#include "udev.h"
+
+enum netname_type{
+        NET_UNDEF,
+        NET_PCI,
+        NET_USB,
+};
+
+struct netnames {
+        enum netname_type type;
+
+        uint8_t mac[6];
+        bool mac_valid;
+
+        struct udev_device *pcidev;
+        char pci_slot[IFNAMSIZ];
+        char pci_path[IFNAMSIZ];
+        char pci_onboard[IFNAMSIZ];
+        const char *pci_onboard_label;
+
+        struct udev_device *usbdev;
+        char usb_ports[IFNAMSIZ];
+};
+
+/* retrieve on-board index number and label from firmware */
+static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
+        const char *index;
+        int idx;
+
+        /* ACPI _DSM  -- device specific method for naming a PCI or PCI Express device */
+        index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
+        /* SMBIOS type 41 -- Onboard Devices Extended Information */
+        if (!index)
+                index = udev_device_get_sysattr_value(names->pcidev, "index");
+        if (!index)
+                return -ENOENT;
+        idx = strtoul(index, NULL, 0);
+        if (idx <= 0)
+                return -EINVAL;
+        snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx);
+
+        names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
+        return 0;
+}
+
+/* read the 256 bytes PCI configuration space to check the multi-function bit */
+static bool is_pci_multifunction(struct udev_device *dev) {
+        char filename[256];
+        FILE *f;
+        char config[64];
+        bool multi = false;
+
+        snprintf(filename, sizeof(filename), "%s/config", udev_device_get_syspath(dev));
+        f = fopen(filename, "re");
+        if (!f)
+                goto out;
+        if (fread(&config, sizeof(config), 1, f) != 1)
+                goto out;
+
+        /* bit 0-6 header type, bit 7 multi/single function device */
+        if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
+                multi = true;
+out:
+        fclose(f);
+        return multi;
+}
+
+static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
+        struct udev *udev = udev_device_get_udev(names->pcidev);
+        unsigned int bus;
+        unsigned int slot;
+        unsigned int func;
+        unsigned int dev_id = 0;
+        size_t l;
+        char *s;
+        const char *attr;
+        struct udev_device *pci = NULL;
+        char slots[256];
+        DIR *dir;
+        struct dirent *dent;
+        char str[256];
+        int hotplug_slot = 0;
+        int err = 0;
+
+        if (sscanf(udev_device_get_sysname(names->pcidev), "0000:%x:%x.%d", &bus, &slot, &func) != 3)
+                return -ENOENT;
+
+        /* kernel provided multi-device index */
+        attr = udev_device_get_sysattr_value(dev, "dev_id");
+        if (attr)
+                dev_id = strtol(attr, NULL, 16);
+
+        /* compose a name based on the raw kernel's PCI bus, slot numbers */
+        s = names->pci_path;
+        l = util_strpcpyf(&s, sizeof(names->pci_path), "p%ds%d", bus, slot);
+        if (func > 0 || is_pci_multifunction(names->pcidev))
+                l = util_strpcpyf(&s, l, "f%d", func);
+        if (dev_id > 0)
+                l = util_strpcpyf(&s, l, "d%d", dev_id);
+        if (l == 0)
+                names->pci_path[0] = '\0';
+
+        /* ACPI _SUN  -- slot user number */
+        pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
+        if (!pci) {
+                err = -ENOENT;
+                goto out;
+        }
+        snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci));
+        dir = opendir(slots);
+        if (!dir) {
+                err = -errno;
+                goto out;
+        }
+
+        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                int i;
+                char *rest;
+                char *address;
+
+                if (dent->d_name[0] == '.')
+                        continue;
+                i = strtol(dent->d_name, &rest, 10);
+                if (rest[0] != '\0')
+                        continue;
+                if (i < 1)
+                        continue;
+                snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
+                if (read_one_line_file(str, &address) >= 0) {
+                        /* match slot address with device by stripping the function */
+                        if (strncmp(address, udev_device_get_sysname(names->pcidev), strlen(address)) == 0)
+                                hotplug_slot = i;
+                        free(address);
+                }
+
+                if (hotplug_slot > 0)
+                        break;
+        }
+        closedir(dir);
+
+        if (hotplug_slot > 0) {
+                s = names->pci_slot;
+                l = util_strpcpyf(&s, sizeof(names->pci_slot), "s%d", hotplug_slot);
+                if (func > 0 || is_pci_multifunction(names->pcidev))
+                        l = util_strpcpyf(&s, l, "f%d", func);
+                if (dev_id > 0)
+                        l = util_strpcpyf(&s, l, "d%d", dev_id);
+                if (l == 0)
+                        names->pci_path[0] = '\0';
+        }
+out:
+        udev_device_unref(pci);
+        return err;
+}
+
+static int names_pci(struct udev_device *dev, struct netnames *names) {
+        struct udev_device *parent;
+
+        parent = udev_device_get_parent(dev);
+        if (!parent)
+                return -ENOENT;
+        /* check if our direct parent is a PCI device with no other bus in-between */
+        if (streq("pci", udev_device_get_subsystem(parent))) {
+                names->type = NET_PCI;
+                names->pcidev = parent;
+        } else {
+                names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
+                if (!names->pcidev)
+                        return -ENOENT;
+        }
+        dev_pci_onboard(dev, names);
+        dev_pci_slot(dev, names);
+        return 0;
+}
+
+static int names_usb(struct udev_device *dev, struct netnames *names) {
+        char name[256];
+        char *ports;
+        char *config;
+        char *interf;
+        size_t l;
+        char *s;
+
+        names->usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
+        if (!names->usbdev)
+                return -ENOENT;
+
+        /* get USB port number chain, configuration, interface */
+        util_strscpy(name, sizeof(name), udev_device_get_sysname(names->usbdev));
+        s = strchr(name, '-');
+        if (!s)
+                return -EINVAL;
+        ports = s+1;
+
+        s = strchr(ports, ':');
+        if (!s)
+                return -EINVAL;
+        s[0] = '\0';
+        config = s+1;
+
+        s = strchr(config, '.');
+        if (!s)
+                return -EINVAL;
+        s[0] = '\0';
+        interf = s+1;
+
+        /* prefix every port number in the chain with "u"*/
+        s = ports;
+        while ((s = strchr(s, '.')))
+                s[0] = 'u';
+        s = names->usb_ports;
+        l = util_strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL);
+
+        /* append USB config number, suppress the common config == 1 */
+        if (!streq(config, "1"))
+                l = util_strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL);
+
+        /* append USB interface number, suppress the interface == 0 */
+        if (!streq(interf, "0"))
+                l = util_strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL);
+        if (l == 0)
+                return -ENAMETOOLONG;
+
+        names->type = NET_USB;
+        return 0;
+}
+
+static int names_mac(struct udev_device *dev, struct netnames *names) {
+        const char *s;
+        unsigned int i;
+        unsigned int a1, a2, a3, a4, a5, a6;
+
+        /* check for NET_ADDR_PERM, skip random MAC addresses */
+        s = udev_device_get_sysattr_value(dev, "addr_assign_type");
+        if (!s)
+                return EXIT_FAILURE;
+        i = strtoul(s, NULL, 0);
+        if (i != 0)
+                return 0;
+
+        s = udev_device_get_sysattr_value(dev, "address");
+        if (!s)
+                return -ENOENT;
+        if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6)
+                return -EINVAL;
+
+        /* skip empty MAC addresses */
+        if (a1 + a2 + a3 + a4 + a5 + a6 == 0)
+                return -EINVAL;
+
+        names->mac[0] = a1;
+        names->mac[1] = a2;
+        names->mac[2] = a3;
+        names->mac[3] = a4;
+        names->mac[4] = a5;
+        names->mac[5] = a6;
+        names->mac_valid = true;
+        return 0;
+}
+
+/* IEEE Organizationally Unique Identifier vendor string */
+static int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) {
+        char str[32];
+
+        if (!names->mac_valid)
+                return -ENOENT;
+        /* skip commonly misused 00:00:00 (Xerox) prefix */
+        if (memcmp(names->mac, "\0\0\0", 3) == 0)
+                return -EINVAL;
+        snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X",
+                 names->mac[0], names->mac[1], names->mac[2],
+                 names->mac[3], names->mac[4], names->mac[5]);
+        udev_builtin_hwdb_lookup(dev, str, test);
+        return 0;
+}
+
+static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) {
+        const char *s;
+        unsigned int i;
+        const char *devtype;
+        const char *prefix = "en";
+        struct netnames names;
+        int err;
+
+        /* handle only ARPHRD_ETHER devices */
+        s = udev_device_get_sysattr_value(dev, "type");
+        if (!s)
+                return EXIT_FAILURE;
+        i = strtoul(s, NULL, 0);
+        if (i != 1)
+                return 0;
+
+        devtype = udev_device_get_devtype(dev);
+        if (devtype) {
+                if (streq("wlan", devtype))
+                        prefix = "wl";
+                else if (streq("wwan", devtype))
+                        prefix = "ww";
+        }
+
+        zero(names);
+        err = names_mac(dev, &names);
+        if (err >= 0 && names.mac_valid) {
+                char str[IFNAMSIZ];
+
+                snprintf(str, sizeof(str), "%sx%02x%02x%02x%02x%02x%02x", prefix,
+                         names.mac[0], names.mac[1], names.mac[2],
+                         names.mac[3], names.mac[4], names.mac[5]);
+                udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
+
+                ieee_oui(dev, &names, test);
+        }
+
+        /* get PCI based path names, we compose only PCI based paths */
+        err = names_pci(dev, &names);
+        if (err < 0)
+                goto out;
+
+        /* plain PCI device */
+        if (names.type == NET_PCI) {
+                char str[IFNAMSIZ];
+
+                if (names.pci_onboard[0])
+                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard) < (int)sizeof(str))
+                                udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str);
+
+                if (names.pci_onboard_label)
+                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard_label) < (int)sizeof(str))
+                                udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str);
+
+                if (names.pci_path[0])
+                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_path) < (int)sizeof(str))
+                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
+
+                if (names.pci_slot[0])
+                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_slot) < (int)sizeof(str))
+                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+                goto out;
+        }
+
+        /* USB device */
+        err = names_usb(dev, &names);
+        if (err >= 0 && names.type == NET_USB) {
+                char str[IFNAMSIZ];
+
+                if (names.pci_path[0])
+                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.usb_ports) < (int)sizeof(str))
+                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
+
+                if (names.pci_slot[0])
+                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str))
+                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+        }
+out:
+        return EXIT_SUCCESS;
+}
+
+const struct udev_builtin udev_builtin_net_id = {
+        .name = "net_id",
+        .cmd = builtin_net_id,
+        .help = "network device properties",
+};
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
new file mode 100644 (file)
index 0000000..c2c9161
--- /dev/null
@@ -0,0 +1,590 @@
+/*
+ * compose persistent device path
+ *
+ * Copyright (C) 2009-2011 Kay Sievers <kay@vrfy.org>
+ *
+ * Logic based on Hannes Reinecke's shell script.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <getopt.h>
+
+#include "udev.h"
+
+static int path_prepend(char **path, const char *fmt, ...)
+{
+        va_list va;
+        char *pre;
+        int err = 0;
+
+        va_start(va, fmt);
+        err = vasprintf(&pre, fmt, va);
+        va_end(va);
+        if (err < 0)
+                goto out;
+
+        if (*path != NULL) {
+                char *new;
+
+                err = asprintf(&new, "%s-%s", pre, *path);
+                free(pre);
+                if (err < 0)
+                        goto out;
+                free(*path);
+                *path = new;
+        } else {
+                *path = pre;
+        }
+out:
+        return err;
+}
+
+/*
+** Linux only supports 32 bit luns.
+** See drivers/scsi/scsi_scan.c::scsilun_to_int() for more details.
+*/
+static int format_lun_number(struct udev_device *dev, char **path)
+{
+        unsigned long lun = strtoul(udev_device_get_sysnum(dev), NULL, 10);
+
+        /* address method 0, peripheral device addressing with bus id of zero */
+        if (lun < 256)
+                return path_prepend(path, "lun-%d", lun);
+        /* handle all other lun addressing methods by using a variant of the original lun format */
+        return path_prepend(path, "lun-0x%04x%04x00000000", (lun & 0xffff), (lun >> 16) & 0xffff);
+}
+
+static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys)
+{
+        struct udev_device *parent = dev;
+
+        while (parent != NULL) {
+                const char *subsystem;
+
+                subsystem = udev_device_get_subsystem(parent);
+                if (subsystem == NULL || strcmp(subsystem, subsys) != 0)
+                        break;
+                dev = parent;
+                parent = udev_device_get_parent(parent);
+        }
+        return dev;
+}
+
+static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path)
+{
+        struct udev *udev  = udev_device_get_udev(parent);
+        struct udev_device *targetdev;
+        struct udev_device *fcdev = NULL;
+        const char *port;
+        char *lun = NULL;
+
+        targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
+        if (targetdev == NULL)
+                return NULL;
+
+        fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev));
+        if (fcdev == NULL)
+                return NULL;
+        port = udev_device_get_sysattr_value(fcdev, "port_name");
+        if (port == NULL) {
+                parent = NULL;
+                goto out;
+        }
+
+        format_lun_number(parent, &lun);
+        path_prepend(path, "fc-%s-%s", port, lun);
+        if (lun)
+                free(lun);
+out:
+        udev_device_unref(fcdev);
+        return parent;
+}
+
+static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path)
+{
+        struct udev *udev  = udev_device_get_udev(parent);
+        struct udev_device *targetdev;
+        struct udev_device *target_parent;
+        struct udev_device *sasdev;
+        const char *sas_address;
+        char *lun = NULL;
+
+        targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
+        if (targetdev == NULL)
+                return NULL;
+
+        target_parent = udev_device_get_parent(targetdev);
+        if (target_parent == NULL)
+                return NULL;
+
+        sasdev = udev_device_new_from_subsystem_sysname(udev, "sas_device",
+                                udev_device_get_sysname(target_parent));
+        if (sasdev == NULL)
+                return NULL;
+
+        sas_address = udev_device_get_sysattr_value(sasdev, "sas_address");
+        if (sas_address == NULL) {
+                parent = NULL;
+                goto out;
+        }
+
+        format_lun_number(parent, &lun);
+        path_prepend(path, "sas-%s-%s", sas_address, lun);
+        if (lun)
+                free(lun);
+out:
+        udev_device_unref(sasdev);
+        return parent;
+}
+
+static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path)
+{
+        struct udev *udev  = udev_device_get_udev(parent);
+        struct udev_device *transportdev;
+        struct udev_device *sessiondev = NULL;
+        const char *target;
+        char *connname;
+        struct udev_device *conndev = NULL;
+        const char *addr;
+        const char *port;
+        char *lun = NULL;
+
+        /* find iscsi session */
+        transportdev = parent;
+        for (;;) {
+                transportdev = udev_device_get_parent(transportdev);
+                if (transportdev == NULL)
+                        return NULL;
+                if (startswith(udev_device_get_sysname(transportdev), "session"))
+                        break;
+        }
+
+        /* find iscsi session device */
+        sessiondev = udev_device_new_from_subsystem_sysname(udev, "iscsi_session", udev_device_get_sysname(transportdev));
+        if (sessiondev == NULL)
+                return NULL;
+        target = udev_device_get_sysattr_value(sessiondev, "targetname");
+        if (target == NULL) {
+                parent = NULL;
+                goto out;
+        }
+
+        if (asprintf(&connname, "connection%s:0", udev_device_get_sysnum(transportdev)) < 0) {
+                parent = NULL;
+                goto out;
+        }
+        conndev = udev_device_new_from_subsystem_sysname(udev, "iscsi_connection", connname);
+        free(connname);
+        if (conndev == NULL) {
+                parent = NULL;
+                goto out;
+        }
+        addr = udev_device_get_sysattr_value(conndev, "persistent_address");
+        port = udev_device_get_sysattr_value(conndev, "persistent_port");
+        if (addr == NULL || port == NULL) {
+                parent = NULL;
+                goto out;
+        }
+
+        format_lun_number(parent, &lun);
+        path_prepend(path, "ip-%s:%s-iscsi-%s-%s", addr, port, target, lun);
+        if (lun)
+                free(lun);
+out:
+        udev_device_unref(sessiondev);
+        udev_device_unref(conndev);
+        return parent;
+}
+
+static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path)
+{
+        struct udev_device *hostdev;
+        int host, bus, target, lun;
+        const char *name;
+        char *base;
+        char *pos;
+        DIR *dir;
+        struct dirent *dent;
+        int basenum;
+
+        hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
+        if (hostdev == NULL)
+                return NULL;
+
+        name = udev_device_get_sysname(parent);
+        if (sscanf(name, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4)
+                return NULL;
+
+        /*
+         * Rebase host offset to get the local relative number
+         *
+         * Note: This is by definition racy, unreliable and too simple.
+         * Please do not copy this model anywhere. It's just a left-over
+         * from the time we had no idea how things should look like in
+         * the end.
+         *
+         * Making assumptions about a global in-kernel counter and use
+         * that to calculate a local offset is a very broken concept. It
+         * can only work as long as things are in strict order.
+         *
+         * The kernel needs to export the instance/port number of a
+         * controller directly, without the need for rebase magic like
+         * this. Manual driver unbind/bind, parallel hotplug/unplug will
+         * get into the way of this "I hope it works" logic.
+         */
+        basenum = -1;
+        base = strdup(udev_device_get_syspath(hostdev));
+        if (base == NULL)
+                return NULL;
+        pos = strrchr(base, '/');
+        if (pos == NULL) {
+                parent = NULL;
+                goto out;
+        }
+        pos[0] = '\0';
+        dir = opendir(base);
+        if (dir == NULL) {
+                parent = NULL;
+                goto out;
+        }
+        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                char *rest;
+                int i;
+
+                if (dent->d_name[0] == '.')
+                        continue;
+                if (dent->d_type != DT_DIR && dent->d_type != DT_LNK)
+                        continue;
+                if (!startswith(dent->d_name, "host"))
+                        continue;
+                i = strtoul(&dent->d_name[4], &rest, 10);
+                if (rest[0] != '\0')
+                        continue;
+                /*
+                 * find the smallest number; the host really needs to export its
+                 * own instance number per parent device; relying on the global host
+                 * enumeration and plainly rebasing the numbers sounds unreliable
+                 */
+                if (basenum == -1 || i < basenum)
+                        basenum = i;
+        }
+        closedir(dir);
+        if (basenum == -1) {
+                parent = NULL;
+                goto out;
+        }
+        host -= basenum;
+
+        path_prepend(path, "scsi-%u:%u:%u:%u", host, bus, target, lun);
+out:
+        free(base);
+        return hostdev;
+}
+
+static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char **path) {
+        struct udev_device *hostdev;
+        struct udev_device *vmbusdev;
+        const char *guid_str;
+        char *lun = NULL;
+        char guid[38];
+        size_t i, k;
+
+        hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
+        if (!hostdev)
+                return NULL;
+
+        vmbusdev = udev_device_get_parent(hostdev);
+        if (!vmbusdev)
+                return NULL;
+
+        guid_str = udev_device_get_sysattr_value(vmbusdev, "device_id");
+        if (!guid_str)
+                return NULL;
+
+        if (strlen(guid_str) < 37 || guid_str[0] != '{' || guid_str[36] != '}')
+                return NULL;
+
+        for (i = 1, k = 0; i < 36; i++) {
+                if (guid_str[i] == '-')
+                        continue;
+                guid[k++] = guid_str[i];
+        }
+        guid[k] = '\0';
+
+        format_lun_number(parent, &lun);
+        path_prepend(path, "vmbus-%s-%s", guid, lun);
+        free(lun);
+        return parent;
+}
+
+static struct udev_device *handle_scsi(struct udev_device *parent, char **path)
+{
+        const char *devtype;
+        const char *name;
+        const char *id;
+
+        devtype = udev_device_get_devtype(parent);
+        if (devtype == NULL || strcmp(devtype, "scsi_device") != 0)
+                return parent;
+
+        /* firewire */
+        id = udev_device_get_sysattr_value(parent, "ieee1394_id");
+        if (id != NULL) {
+                parent = skip_subsystem(parent, "scsi");
+                path_prepend(path, "ieee1394-0x%s", id);
+                goto out;
+        }
+
+        /* lousy scsi sysfs does not have a "subsystem" for the transport */
+        name = udev_device_get_syspath(parent);
+
+        if (strstr(name, "/rport-") != NULL) {
+                parent = handle_scsi_fibre_channel(parent, path);
+                goto out;
+        }
+
+        if (strstr(name, "/end_device-") != NULL) {
+                parent = handle_scsi_sas(parent, path);
+                goto out;
+        }
+
+        if (strstr(name, "/session") != NULL) {
+                parent = handle_scsi_iscsi(parent, path);
+                goto out;
+        }
+
+        /*
+         * We do not support the ATA transport class, it creates duplicated link
+         * names as the fake SCSI host adapters are all separated, they are all
+         * re-based as host == 0. ATA should just stop faking two duplicated
+         * hierarchies for a single topology and leave the SCSI stuff alone;
+         * until that happens, there are no by-path/ links for ATA devices behind
+         * an ATA transport class.
+         */
+        if (strstr(name, "/ata") != NULL) {
+                parent = NULL;
+                goto out;
+        }
+
+        if (strstr(name, "/vmbus_") != NULL) {
+                parent = handle_scsi_hyperv(parent, path);
+                goto out;
+        }
+
+        parent = handle_scsi_default(parent, path);
+out:
+        return parent;
+}
+
+static struct udev_device *handle_cciss(struct udev_device *parent, char **path)
+{
+        const char *str;
+        unsigned int controller, disk;
+
+        str = udev_device_get_sysname(parent);
+        if (sscanf(str, "c%ud%u%*s", &controller, &disk) != 2)
+                return NULL;
+
+        path_prepend(path, "cciss-disk%u", disk);
+        parent = skip_subsystem(parent, "cciss");
+        return parent;
+}
+
+static void handle_scsi_tape(struct udev_device *dev, char **path)
+{
+        const char *name;
+
+        /* must be the last device in the syspath */
+        if (*path != NULL)
+                return;
+
+        name = udev_device_get_sysname(dev);
+        if (startswith(name, "nst") && strchr("lma", name[3]) != NULL)
+                path_prepend(path, "nst%c", name[3]);
+        else if (startswith(name, "st") && strchr("lma", name[2]) != NULL)
+                path_prepend(path, "st%c", name[2]);
+}
+
+static struct udev_device *handle_usb(struct udev_device *parent, char **path)
+{
+        const char *devtype;
+        const char *str;
+        const char *port;
+
+        devtype = udev_device_get_devtype(parent);
+        if (devtype == NULL)
+                return parent;
+        if (strcmp(devtype, "usb_interface") != 0 && strcmp(devtype, "usb_device") != 0)
+                return parent;
+
+        str = udev_device_get_sysname(parent);
+        port = strchr(str, '-');
+        if (port == NULL)
+                return parent;
+        port++;
+
+        parent = skip_subsystem(parent, "usb");
+        path_prepend(path, "usb-0:%s", port);
+        return parent;
+}
+
+static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path)
+{
+        struct udev_device *scsi_dev;
+
+        scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
+        if (scsi_dev != NULL) {
+                const char *wwpn;
+                const char *lun;
+                const char *hba_id;
+
+                hba_id = udev_device_get_sysattr_value(scsi_dev, "hba_id");
+                wwpn = udev_device_get_sysattr_value(scsi_dev, "wwpn");
+                lun = udev_device_get_sysattr_value(scsi_dev, "fcp_lun");
+                if (hba_id != NULL && lun != NULL && wwpn != NULL) {
+                        path_prepend(path, "ccw-%s-zfcp-%s:%s", hba_id, wwpn, lun);
+                        goto out;
+                }
+        }
+
+        path_prepend(path, "ccw-%s", udev_device_get_sysname(parent));
+out:
+        parent = skip_subsystem(parent, "ccw");
+        return parent;
+}
+
+static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test)
+{
+        struct udev_device *parent;
+        char *path = NULL;
+        bool some_transport = false;
+
+        /* S390 ccw bus */
+        parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
+        if (parent != NULL) {
+                handle_ccw(parent, dev, &path);
+                goto out;
+        }
+
+        /* walk up the chain of devices and compose path */
+        parent = dev;
+        while (parent != NULL) {
+                const char *subsys;
+
+                subsys = udev_device_get_subsystem(parent);
+                if (subsys == NULL) {
+                        ;
+                } else if (strcmp(subsys, "scsi_tape") == 0) {
+                        handle_scsi_tape(parent, &path);
+                } else if (strcmp(subsys, "scsi") == 0) {
+                        parent = handle_scsi(parent, &path);
+                        some_transport = true;
+                } else if (strcmp(subsys, "cciss") == 0) {
+                        parent = handle_cciss(parent, &path);
+                        some_transport = true;
+                } else if (strcmp(subsys, "usb") == 0) {
+                        parent = handle_usb(parent, &path);
+                        some_transport = true;
+                } else if (strcmp(subsys, "serio") == 0) {
+                        path_prepend(&path, "serio-%s", udev_device_get_sysnum(parent));
+                        parent = skip_subsystem(parent, "serio");
+                } else if (strcmp(subsys, "pci") == 0) {
+                        path_prepend(&path, "pci-%s", udev_device_get_sysname(parent));
+                        parent = skip_subsystem(parent, "pci");
+                } else if (strcmp(subsys, "platform") == 0) {
+                        path_prepend(&path, "platform-%s", udev_device_get_sysname(parent));
+                        parent = skip_subsystem(parent, "platform");
+                        some_transport = true;
+                } else if (strcmp(subsys, "acpi") == 0) {
+                        path_prepend(&path, "acpi-%s", udev_device_get_sysname(parent));
+                        parent = skip_subsystem(parent, "acpi");
+                } else if (strcmp(subsys, "xen") == 0) {
+                        path_prepend(&path, "xen-%s", udev_device_get_sysname(parent));
+                        parent = skip_subsystem(parent, "xen");
+                } else if (strcmp(subsys, "virtio") == 0) {
+                        path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent));
+                        parent = skip_subsystem(parent, "virtio");
+                } else if (strcmp(subsys, "scm") == 0) {
+                        path_prepend(&path, "scm-%s", udev_device_get_sysname(parent));
+                        parent = skip_subsystem(parent, "scm");
+                }
+
+                parent = udev_device_get_parent(parent);
+        }
+
+        /*
+         * Do not return a single-parent-device-only for block
+         * devices, they might have entire buses behind it which
+         * do not get unique IDs only by using the parent device.
+         */
+        if (!some_transport && streq(udev_device_get_subsystem(dev), "block")) {
+                free(path);
+                path = NULL;
+        }
+
+out:
+        if (path != NULL) {
+                char tag[UTIL_NAME_SIZE];
+                size_t i;
+                const char *p;
+
+                /* compose valid udev tag name */
+                for (p = path, i = 0; *p; p++) {
+                        if ((*p >= '0' && *p <= '9') ||
+                            (*p >= 'A' && *p <= 'Z') ||
+                            (*p >= 'a' && *p <= 'z') ||
+                            *p == '-') {
+                                tag[i++] = *p;
+                                continue;
+                        }
+
+                        /* skip all leading '_' */
+                        if (i == 0)
+                                continue;
+
+                        /* avoid second '_' */
+                        if (tag[i-1] == '_')
+                                continue;
+
+                        tag[i++] = '_';
+                }
+                /* strip trailing '_' */
+                while (i > 0 && tag[i-1] == '_')
+                        i--;
+                tag[i] = '\0';
+
+                udev_builtin_add_property(dev, test, "ID_PATH", path);
+                udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag);
+                free(path);
+                return EXIT_SUCCESS;
+        }
+        return EXIT_FAILURE;
+}
+
+const struct udev_builtin udev_builtin_path_id = {
+        .name = "path_id",
+        .cmd = builtin_path_id,
+        .help = "compose persistent device path",
+        .run_once = true,
+};
diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c
new file mode 100644 (file)
index 0000000..662bac9
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * manage device node user ACL
+ *
+ * Copyright 2010-2012 Kay Sievers <kay@vrfy.org>
+ * Copyright 2010 Lennart Poettering
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <getopt.h>
+
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-login.h>
+#include "logind-acl.h"
+#include "udev.h"
+#include "util.h"
+
+static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool test)
+{
+        int r;
+        const char *path = NULL, *seat;
+        bool changed_acl = false;
+        uid_t uid;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        /* don't muck around with ACLs when the system is not running systemd */
+        if (!sd_booted())
+                return 0;
+
+        path = udev_device_get_devnode(dev);
+        seat = udev_device_get_property_value(dev, "ID_SEAT");
+        if (!seat)
+                seat = "seat0";
+
+        r = sd_seat_get_active(seat, NULL, &uid);
+        if (r == -ENOENT) {
+                /* No active session on this seat */
+                r = 0;
+                goto finish;
+        } else if (r < 0) {
+                log_error("Failed to determine active user on seat %s.", seat);
+                goto finish;
+        }
+
+        r = devnode_acl(path, true, false, 0, true, uid);
+        if (r < 0) {
+                log_error("Failed to apply ACL on %s: %s", path, strerror(-r));
+                goto finish;
+        }
+
+        changed_acl = true;
+        r = 0;
+
+finish:
+        if (path && !changed_acl) {
+                int k;
+
+                /* Better be safe than sorry and reset ACL */
+                k = devnode_acl(path, true, false, 0, false, 0);
+                if (k < 0) {
+                        log_error("Failed to apply ACL on %s: %s", path, strerror(-k));
+                        if (r >= 0)
+                                r = k;
+                }
+        }
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+const struct udev_builtin udev_builtin_uaccess = {
+        .name = "uaccess",
+        .cmd = builtin_uaccess,
+        .help = "manage device node user ACL",
+};
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
new file mode 100644 (file)
index 0000000..13d1226
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * USB device properties and persistent device path
+ *
+ * Copyright (c) 2005 SUSE Linux Products GmbH, Germany
+ *   Author: Hannes Reinecke <hare@suse.de>
+ *
+ * Copyright (C) 2005-2011 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "udev.h"
+
+static void set_usb_iftype(char *to, int if_class_num, size_t len)
+{
+        const char *type = "generic";
+
+        switch (if_class_num) {
+        case 1:
+                type = "audio";
+                break;
+        case 2: /* CDC-Control */
+                break;
+        case 3:
+                type = "hid";
+                break;
+        case 5: /* Physical */
+                break;
+        case 6:
+                type = "media";
+                break;
+        case 7:
+                type = "printer";
+                break;
+        case 8:
+                type = "storage";
+                break;
+        case 9:
+                type = "hub";
+                break;
+        case 0x0a: /* CDC-Data */
+                break;
+        case 0x0b: /* Chip/Smart Card */
+                break;
+        case 0x0d: /* Content Security */
+                break;
+        case 0x0e:
+                type = "video";
+                break;
+        case 0xdc: /* Diagnostic Device */
+                break;
+        case 0xe0: /* Wireless Controller */
+                break;
+        case 0xfe: /* Application-specific */
+                break;
+        case 0xff: /* Vendor-specific */
+                break;
+        default:
+                break;
+        }
+        strncpy(to, type, len);
+        to[len-1] = '\0';
+}
+
+static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len)
+{
+        int type_num = 0;
+        char *eptr;
+        const char *type = "generic";
+
+        type_num = strtoul(from, &eptr, 0);
+        if (eptr != from) {
+                switch (type_num) {
+                case 2:
+                        type = "atapi";
+                        break;
+                case 3:
+                        type = "tape";
+                        break;
+                case 4: /* UFI */
+                case 5: /* SFF-8070i */
+                        type = "floppy";
+                        break;
+                case 1: /* RBC devices */
+                        type = "rbc";
+                        break;
+                case 6: /* Transparent SPC-2 devices */
+                        type = "scsi";
+                        break;
+                default:
+                        break;
+                }
+        }
+        util_strscpy(to, len, type);
+        return type_num;
+}
+
+static void set_scsi_type(char *to, const char *from, size_t len)
+{
+        int type_num;
+        char *eptr;
+        const char *type = "generic";
+
+        type_num = strtoul(from, &eptr, 0);
+        if (eptr != from) {
+                switch (type_num) {
+                case 0:
+                case 0xe:
+                        type = "disk";
+                        break;
+                case 1:
+                        type = "tape";
+                        break;
+                case 4:
+                case 7:
+                case 0xf:
+                        type = "optical";
+                        break;
+                case 5:
+                        type = "cd";
+                        break;
+                default:
+                        break;
+                }
+        }
+        util_strscpy(to, len, type);
+}
+
+#define USB_DT_DEVICE                        0x01
+#define USB_DT_INTERFACE                0x04
+
+static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len)
+{
+        char *filename = NULL;
+        int fd;
+        ssize_t size;
+        unsigned char buf[18 + 65535];
+        unsigned int pos, strpos;
+        struct usb_interface_descriptor {
+                u_int8_t        bLength;
+                u_int8_t        bDescriptorType;
+                u_int8_t        bInterfaceNumber;
+                u_int8_t        bAlternateSetting;
+                u_int8_t        bNumEndpoints;
+                u_int8_t        bInterfaceClass;
+                u_int8_t        bInterfaceSubClass;
+                u_int8_t        bInterfaceProtocol;
+                u_int8_t        iInterface;
+        } __attribute__((packed));
+        int err = 0;
+
+        if (asprintf(&filename, "%s/descriptors", udev_device_get_syspath(dev)) < 0) {
+                err = -1;
+                goto out;
+        }
+        fd = open(filename, O_RDONLY|O_CLOEXEC);
+        if (fd < 0) {
+                fprintf(stderr, "error opening USB device 'descriptors' file\n");
+                err = -1;
+                goto out;
+        }
+        size = read(fd, buf, sizeof(buf));
+        close(fd);
+        if (size < 18 || size == sizeof(buf)) {
+                err = -1;
+                goto out;
+        }
+
+        pos = 0;
+        strpos = 0;
+        ifs_str[0] = '\0';
+        while (pos < sizeof(buf) && strpos+7 < len-2) {
+                struct usb_interface_descriptor *desc;
+                char if_str[8];
+
+                desc = (struct usb_interface_descriptor *) &buf[pos];
+                if (desc->bLength < 3)
+                        break;
+                pos += desc->bLength;
+
+                if (desc->bDescriptorType != USB_DT_INTERFACE)
+                        continue;
+
+                if (snprintf(if_str, 8, ":%02x%02x%02x",
+                             desc->bInterfaceClass,
+                             desc->bInterfaceSubClass,
+                             desc->bInterfaceProtocol) != 7)
+                        continue;
+
+                if (strstr(ifs_str, if_str) != NULL)
+                        continue;
+
+                memcpy(&ifs_str[strpos], if_str, 8),
+                strpos += 7;
+        }
+        if (strpos > 0) {
+                ifs_str[strpos++] = ':';
+                ifs_str[strpos++] = '\0';
+        }
+out:
+        free(filename);
+        return err;
+}
+
+/*
+ * A unique USB identification is generated like this:
+ *
+ * 1.) Get the USB device type from InterfaceClass and InterfaceSubClass
+ * 2.) If the device type is 'Mass-Storage/SPC-2' or 'Mass-Storage/RBC'
+ *     use the SCSI vendor and model as USB-Vendor and USB-model.
+ * 3.) Otherwise use the USB manufacturer and product as
+ *     USB-Vendor and USB-model. Any non-printable characters
+ *     in those strings will be skipped; a slash '/' will be converted
+ *     into a full stop '.'.
+ * 4.) If that fails, too, we will use idVendor and idProduct
+ *     as USB-Vendor and USB-model.
+ * 5.) The USB identification is the USB-vendor and USB-model
+ *     string concatenated with an underscore '_'.
+ * 6.) If the device supplies a serial number, this number
+ *     is concatenated with the identification with an underscore '_'.
+ */
+static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test)
+{
+        char vendor_str[64];
+        char vendor_str_enc[256];
+        const char *vendor_id;
+        char model_str[64];
+        char model_str_enc[256];
+        const char *product_id;
+        char serial_str[UTIL_NAME_SIZE];
+        char packed_if_str[UTIL_NAME_SIZE];
+        char revision_str[64];
+        char type_str[64];
+        char instance_str[64];
+        const char *ifnum = NULL;
+        const char *driver = NULL;
+        char serial[256];
+
+        struct udev_device *dev_interface = NULL;
+        struct udev_device *dev_usb = NULL;
+        const char *if_class, *if_subclass;
+        int if_class_num;
+        int protocol = 0;
+        size_t l;
+        char *s;
+
+        vendor_str[0] = '\0';
+        model_str[0] = '\0';
+        serial_str[0] = '\0';
+        packed_if_str[0] = '\0';
+        revision_str[0] = '\0';
+        type_str[0] = '\0';
+        instance_str[0] = '\0';
+
+        /* shortcut, if we are called directly for a "usb_device" type */
+        if (udev_device_get_devtype(dev) != NULL && strcmp(udev_device_get_devtype(dev), "usb_device") == 0) {
+                dev_if_packed_info(dev, packed_if_str, sizeof(packed_if_str));
+                dev_usb = dev;
+                goto fallback;
+        }
+
+        /* usb interface directory */
+        dev_interface = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
+        if (dev_interface == NULL) {
+                log_debug("unable to access usb_interface device of '%s'\n",
+                     udev_device_get_syspath(dev));
+                return EXIT_FAILURE;
+        }
+
+        ifnum = udev_device_get_sysattr_value(dev_interface, "bInterfaceNumber");
+        driver = udev_device_get_sysattr_value(dev_interface, "driver");
+
+        if_class = udev_device_get_sysattr_value(dev_interface, "bInterfaceClass");
+        if (!if_class) {
+                log_debug("%s: cannot get bInterfaceClass attribute\n",
+                     udev_device_get_sysname(dev));
+                return EXIT_FAILURE;
+        }
+
+        if_class_num = strtoul(if_class, NULL, 16);
+        if (if_class_num == 8) {
+                /* mass storage */
+                if_subclass = udev_device_get_sysattr_value(dev_interface, "bInterfaceSubClass");
+                if (if_subclass != NULL)
+                        protocol = set_usb_mass_storage_ifsubtype(type_str, if_subclass, sizeof(type_str)-1);
+        } else {
+                set_usb_iftype(type_str, if_class_num, sizeof(type_str)-1);
+        }
+
+        log_debug("%s: if_class %d protocol %d\n",
+             udev_device_get_syspath(dev_interface), if_class_num, protocol);
+
+        /* usb device directory */
+        dev_usb = udev_device_get_parent_with_subsystem_devtype(dev_interface, "usb", "usb_device");
+        if (!dev_usb) {
+                log_debug("unable to find parent 'usb' device of '%s'\n",
+                     udev_device_get_syspath(dev));
+                return EXIT_FAILURE;
+        }
+
+        /* all interfaces of the device in a single string */
+        dev_if_packed_info(dev_usb, packed_if_str, sizeof(packed_if_str));
+
+        /* mass storage : SCSI or ATAPI */
+        if ((protocol == 6 || protocol == 2)) {
+                struct udev_device *dev_scsi;
+                const char *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev;
+                int host, bus, target, lun;
+
+                /* get scsi device */
+                dev_scsi = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
+                if (dev_scsi == NULL) {
+                        log_debug("unable to find parent 'scsi' device of '%s'\n",
+                             udev_device_get_syspath(dev));
+                        goto fallback;
+                }
+                if (sscanf(udev_device_get_sysname(dev_scsi), "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) {
+                        log_debug("invalid scsi device '%s'\n", udev_device_get_sysname(dev_scsi));
+                        goto fallback;
+                }
+
+                /* Generic SPC-2 device */
+                scsi_vendor = udev_device_get_sysattr_value(dev_scsi, "vendor");
+                if (!scsi_vendor) {
+                        log_debug("%s: cannot get SCSI vendor attribute\n",
+                             udev_device_get_sysname(dev_scsi));
+                        goto fallback;
+                }
+                udev_util_encode_string(scsi_vendor, vendor_str_enc, sizeof(vendor_str_enc));
+                util_replace_whitespace(scsi_vendor, vendor_str, sizeof(vendor_str)-1);
+                util_replace_chars(vendor_str, NULL);
+
+                scsi_model = udev_device_get_sysattr_value(dev_scsi, "model");
+                if (!scsi_model) {
+                        log_debug("%s: cannot get SCSI model attribute\n",
+                             udev_device_get_sysname(dev_scsi));
+                        goto fallback;
+                }
+                udev_util_encode_string(scsi_model, model_str_enc, sizeof(model_str_enc));
+                util_replace_whitespace(scsi_model, model_str, sizeof(model_str)-1);
+                util_replace_chars(model_str, NULL);
+
+                scsi_type = udev_device_get_sysattr_value(dev_scsi, "type");
+                if (!scsi_type) {
+                        log_debug("%s: cannot get SCSI type attribute\n",
+                             udev_device_get_sysname(dev_scsi));
+                        goto fallback;
+                }
+                set_scsi_type(type_str, scsi_type, sizeof(type_str)-1);
+
+                scsi_rev = udev_device_get_sysattr_value(dev_scsi, "rev");
+                if (!scsi_rev) {
+                        log_debug("%s: cannot get SCSI revision attribute\n",
+                             udev_device_get_sysname(dev_scsi));
+                        goto fallback;
+                }
+                util_replace_whitespace(scsi_rev, revision_str, sizeof(revision_str)-1);
+                util_replace_chars(revision_str, NULL);
+
+                /*
+                 * some broken devices have the same identifiers
+                 * for all luns, export the target:lun number
+                 */
+                sprintf(instance_str, "%d:%d", target, lun);
+        }
+
+fallback:
+        vendor_id = udev_device_get_sysattr_value(dev_usb, "idVendor");
+        product_id = udev_device_get_sysattr_value(dev_usb, "idProduct");
+
+        /* fallback to USB vendor & device */
+        if (vendor_str[0] == '\0') {
+                const char *usb_vendor = NULL;
+
+                usb_vendor = udev_device_get_sysattr_value(dev_usb, "manufacturer");
+                if (!usb_vendor)
+                        usb_vendor = vendor_id;
+                if (!usb_vendor) {
+                        log_debug("No USB vendor information available\n");
+                        return EXIT_FAILURE;
+                }
+                udev_util_encode_string(usb_vendor, vendor_str_enc, sizeof(vendor_str_enc));
+                util_replace_whitespace(usb_vendor, vendor_str, sizeof(vendor_str)-1);
+                util_replace_chars(vendor_str, NULL);
+        }
+
+        if (model_str[0] == '\0') {
+                const char *usb_model = NULL;
+
+                usb_model = udev_device_get_sysattr_value(dev_usb, "product");
+                if (!usb_model)
+                        usb_model = product_id;
+                if (!usb_model)
+                        return EXIT_FAILURE;
+                udev_util_encode_string(usb_model, model_str_enc, sizeof(model_str_enc));
+                util_replace_whitespace(usb_model, model_str, sizeof(model_str)-1);
+                util_replace_chars(model_str, NULL);
+        }
+
+        if (revision_str[0] == '\0') {
+                const char *usb_rev;
+
+                usb_rev = udev_device_get_sysattr_value(dev_usb, "bcdDevice");
+                if (usb_rev) {
+                        util_replace_whitespace(usb_rev, revision_str, sizeof(revision_str)-1);
+                        util_replace_chars(revision_str, NULL);
+                }
+        }
+
+        if (serial_str[0] == '\0') {
+                const char *usb_serial;
+
+                usb_serial = udev_device_get_sysattr_value(dev_usb, "serial");
+                if (usb_serial) {
+                        util_replace_whitespace(usb_serial, serial_str, sizeof(serial_str)-1);
+                        util_replace_chars(serial_str, NULL);
+                }
+        }
+
+        s = serial;
+        l = util_strpcpyl(&s, sizeof(serial), vendor_str, "_", model_str, NULL);
+        if (serial_str[0] != '\0')
+                l = util_strpcpyl(&s, l, "_", serial_str, NULL);
+
+        if (instance_str[0] != '\0')
+                util_strpcpyl(&s, l, "-", instance_str, NULL);
+
+        udev_builtin_add_property(dev, test, "ID_VENDOR", vendor_str);
+        udev_builtin_add_property(dev, test, "ID_VENDOR_ENC", vendor_str_enc);
+        udev_builtin_add_property(dev, test, "ID_VENDOR_ID", vendor_id);
+        udev_builtin_add_property(dev, test, "ID_MODEL", model_str);
+        udev_builtin_add_property(dev, test, "ID_MODEL_ENC", model_str_enc);
+        udev_builtin_add_property(dev, test, "ID_MODEL_ID", product_id);
+        udev_builtin_add_property(dev, test, "ID_REVISION", revision_str);
+        udev_builtin_add_property(dev, test, "ID_SERIAL", serial);
+        if (serial_str[0] != '\0')
+                udev_builtin_add_property(dev, test, "ID_SERIAL_SHORT", serial_str);
+        if (type_str[0] != '\0')
+                udev_builtin_add_property(dev, test, "ID_TYPE", type_str);
+        if (instance_str[0] != '\0')
+                udev_builtin_add_property(dev, test, "ID_INSTANCE", instance_str);
+        udev_builtin_add_property(dev, test, "ID_BUS", "usb");
+        if (packed_if_str[0] != '\0')
+                udev_builtin_add_property(dev, test, "ID_USB_INTERFACES", packed_if_str);
+        if (ifnum != NULL)
+                udev_builtin_add_property(dev, test, "ID_USB_INTERFACE_NUM", ifnum);
+        if (driver != NULL)
+                udev_builtin_add_property(dev, test, "ID_USB_DRIVER", driver);
+        return EXIT_SUCCESS;
+}
+
+const struct udev_builtin udev_builtin_usb_id = {
+        .name = "usb_id",
+        .cmd = builtin_usb_id,
+        .help = "usb device properties",
+        .run_once = true,
+};
diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
new file mode 100644 (file)
index 0000000..32e6e1e
--- /dev/null
@@ -0,0 +1,148 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2007-2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
+#include "udev.h"
+
+static bool initialized;
+
+static const struct udev_builtin *builtins[] = {
+#ifdef HAVE_BLKID
+        [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
+#endif
+        [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs,
+        [UDEV_BUILTIN_FIRMWARE] = &udev_builtin_firmware,
+        [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb,
+        [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id,
+#ifdef HAVE_KMOD
+        [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
+#endif
+        [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id,
+        [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
+        [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id,
+#ifdef HAVE_ACL
+        [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess,
+#endif
+};
+
+void udev_builtin_init(struct udev *udev)
+{
+        unsigned int i;
+
+        if (initialized)
+                return;
+
+        for (i = 0; i < ELEMENTSOF(builtins); i++)
+                if (builtins[i]->init)
+                        builtins[i]->init(udev);
+
+        initialized = true;
+}
+
+void udev_builtin_exit(struct udev *udev)
+{
+        unsigned int i;
+
+        if (!initialized)
+                return;
+
+        for (i = 0; i < ELEMENTSOF(builtins); i++)
+                if (builtins[i]->exit)
+                        builtins[i]->exit(udev);
+
+        initialized = false;
+}
+
+bool udev_builtin_validate(struct udev *udev)
+{
+        unsigned int i;
+
+        for (i = 0; i < ELEMENTSOF(builtins); i++)
+                if (builtins[i]->validate && builtins[i]->validate(udev))
+                        return true;
+        return false;
+}
+
+void udev_builtin_list(struct udev *udev)
+{
+        unsigned int i;
+
+        for (i = 0; i < ELEMENTSOF(builtins); i++)
+                fprintf(stderr, "  %-12s %s\n", builtins[i]->name, builtins[i]->help);
+}
+
+const char *udev_builtin_name(enum udev_builtin_cmd cmd)
+{
+        return builtins[cmd]->name;
+}
+
+bool udev_builtin_run_once(enum udev_builtin_cmd cmd)
+{
+        return builtins[cmd]->run_once;
+}
+
+enum udev_builtin_cmd udev_builtin_lookup(const char *command)
+{
+        char name[UTIL_PATH_SIZE];
+        enum udev_builtin_cmd i;
+        char *pos;
+
+        util_strscpy(name, sizeof(name), command);
+        pos = strchr(name, ' ');
+        if (pos)
+                pos[0] = '\0';
+        for (i = 0; i < ELEMENTSOF(builtins); i++)
+                if (strcmp(builtins[i]->name, name) == 0)
+                        return i;
+        return UDEV_BUILTIN_MAX;
+}
+
+int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test)
+{
+        char arg[UTIL_PATH_SIZE];
+        int argc;
+        char *argv[128];
+
+        /* we need '0' here to reset the internal state */
+        optind = 0;
+        util_strscpy(arg, sizeof(arg), command);
+        udev_build_argv(udev_device_get_udev(dev), arg, &argc, argv);
+        return builtins[cmd]->cmd(dev, argc, argv, test);
+}
+
+int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val)
+{
+        struct udev_list_entry *entry;
+
+        entry = udev_device_add_property(dev, key, val);
+        /* store in db, skip private keys */
+        if (key[0] != '.')
+                udev_list_entry_set_num(entry, true);
+
+        if (test)
+                printf("%s=%s\n", key, val);
+        return 0;
+}
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
new file mode 100644 (file)
index 0000000..a235912
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * libudev - interface to udev device information
+ *
+ * Copyright (C) 2008 Kay Sievers <kay@vrfy.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "udev.h"
+
+/* wire protocol magic must match */
+#define UDEV_CTRL_MAGIC                                0xdead1dea
+
+enum udev_ctrl_msg_type {
+        UDEV_CTRL_UNKNOWN,
+        UDEV_CTRL_SET_LOG_LEVEL,
+        UDEV_CTRL_STOP_EXEC_QUEUE,
+        UDEV_CTRL_START_EXEC_QUEUE,
+        UDEV_CTRL_RELOAD,
+        UDEV_CTRL_SET_ENV,
+        UDEV_CTRL_SET_CHILDREN_MAX,
+        UDEV_CTRL_PING,
+        UDEV_CTRL_EXIT,
+};
+
+struct udev_ctrl_msg_wire {
+        char version[16];
+        unsigned int magic;
+        enum udev_ctrl_msg_type type;
+        union {
+                int intval;
+                char buf[256];
+        };
+};
+
+struct udev_ctrl_msg {
+        int refcount;
+        struct udev_ctrl_connection *conn;
+        struct udev_ctrl_msg_wire ctrl_msg_wire;
+};
+
+struct udev_ctrl {
+        int refcount;
+        struct udev *udev;
+        int sock;
+        struct sockaddr_un saddr;
+        socklen_t addrlen;
+        bool bound;
+        bool cleanup_socket;
+        bool connected;
+};
+
+struct udev_ctrl_connection {
+        int refcount;
+        struct udev_ctrl *uctrl;
+        int sock;
+};
+
+struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd)
+{
+        struct udev_ctrl *uctrl;
+
+        uctrl = calloc(1, sizeof(struct udev_ctrl));
+        if (uctrl == NULL)
+                return NULL;
+        uctrl->refcount = 1;
+        uctrl->udev = udev;
+
+        if (fd < 0) {
+                uctrl->sock = socket(AF_LOCAL, SOCK_SEQPACKET|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
+                if (uctrl->sock < 0) {
+                        log_error("error getting socket: %m\n");
+                        udev_ctrl_unref(uctrl);
+                        return NULL;
+                }
+        } else {
+                uctrl->bound = true;
+                uctrl->sock = fd;
+        }
+
+        uctrl->saddr.sun_family = AF_LOCAL;
+        util_strscpy(uctrl->saddr.sun_path, sizeof(uctrl->saddr.sun_path), "/run/udev/control");
+        uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.sun_path);
+        return uctrl;
+}
+
+struct udev_ctrl *udev_ctrl_new(struct udev *udev)
+{
+        return udev_ctrl_new_from_fd(udev, -1);
+}
+
+int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl)
+{
+        int err;
+
+        if (!uctrl->bound) {
+                err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen);
+                if (err < 0 && errno == EADDRINUSE) {
+                        unlink(uctrl->saddr.sun_path);
+                        err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen);
+                }
+
+                if (err < 0) {
+                        err = -errno;
+                        log_error("bind failed: %m\n");
+                        return err;
+                }
+
+                err = listen(uctrl->sock, 0);
+                if (err < 0) {
+                        err = -errno;
+                        log_error("listen failed: %m\n");
+                        return err;
+                }
+
+                uctrl->bound = true;
+                uctrl->cleanup_socket = true;
+        }
+        return 0;
+}
+
+struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl)
+{
+        return uctrl->udev;
+}
+
+struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl)
+{
+        if (uctrl == NULL)
+                return NULL;
+        uctrl->refcount++;
+        return uctrl;
+}
+
+struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl)
+{
+        if (uctrl == NULL)
+                return NULL;
+        uctrl->refcount--;
+        if (uctrl->refcount > 0)
+                return uctrl;
+        if (uctrl->sock >= 0)
+                close(uctrl->sock);
+        free(uctrl);
+        return NULL;
+}
+
+int udev_ctrl_cleanup(struct udev_ctrl *uctrl)
+{
+        if (uctrl == NULL)
+                return 0;
+        if (uctrl->cleanup_socket)
+                unlink(uctrl->saddr.sun_path);
+        return 0;
+}
+
+int udev_ctrl_get_fd(struct udev_ctrl *uctrl)
+{
+        if (uctrl == NULL)
+                return -EINVAL;
+        return uctrl->sock;
+}
+
+struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl)
+{
+        struct udev_ctrl_connection *conn;
+        struct ucred ucred;
+        socklen_t slen;
+        const int on = 1;
+
+        conn = calloc(1, sizeof(struct udev_ctrl_connection));
+        if (conn == NULL)
+                return NULL;
+        conn->refcount = 1;
+        conn->uctrl = uctrl;
+
+        conn->sock = accept4(uctrl->sock, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK);
+        if (conn->sock < 0) {
+                if (errno != EINTR)
+                        log_error("unable to receive ctrl connection: %m\n");
+                goto err;
+        }
+
+        /* check peer credential of connection */
+        slen = sizeof(ucred);
+        if (getsockopt(conn->sock, SOL_SOCKET, SO_PEERCRED, &ucred, &slen) < 0) {
+                log_error("unable to receive credentials of ctrl connection: %m\n");
+                goto err;
+        }
+        if (ucred.uid > 0) {
+                log_error("sender uid=%i, message ignored\n", ucred.uid);
+                goto err;
+        }
+
+        /* enable receiving of the sender credentials in the messages */
+        setsockopt(conn->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
+        udev_ctrl_ref(uctrl);
+        return conn;
+err:
+        if (conn->sock >= 0)
+                close(conn->sock);
+        free(conn);
+        return NULL;
+}
+
+struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn)
+{
+        if (conn == NULL)
+                return NULL;
+        conn->refcount++;
+        return conn;
+}
+
+struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn)
+{
+        if (conn == NULL)
+                return NULL;
+        conn->refcount--;
+        if (conn->refcount > 0)
+                return conn;
+        if (conn->sock >= 0)
+                close(conn->sock);
+        udev_ctrl_unref(conn->uctrl);
+        free(conn);
+        return NULL;
+}
+
+static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int intval, const char *buf, int timeout)
+{
+        struct udev_ctrl_msg_wire ctrl_msg_wire;
+        int err = 0;
+
+        memset(&ctrl_msg_wire, 0x00, sizeof(struct udev_ctrl_msg_wire));
+        strcpy(ctrl_msg_wire.version, "udev-" VERSION);
+        ctrl_msg_wire.magic = UDEV_CTRL_MAGIC;
+        ctrl_msg_wire.type = type;
+
+        if (buf != NULL)
+                util_strscpy(ctrl_msg_wire.buf, sizeof(ctrl_msg_wire.buf), buf);
+        else
+                ctrl_msg_wire.intval = intval;
+
+        if (!uctrl->connected) {
+                if (connect(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen) < 0) {
+                        err = -errno;
+                        goto out;
+                }
+                uctrl->connected = true;
+        }
+        if (send(uctrl->sock, &ctrl_msg_wire, sizeof(ctrl_msg_wire), 0) < 0) {
+                err = -errno;
+                goto out;
+        }
+
+        /* wait for peer message handling or disconnect */
+        for (;;) {
+                struct pollfd pfd[1];
+                int r;
+
+                pfd[0].fd = uctrl->sock;
+                pfd[0].events = POLLIN;
+                r = poll(pfd, 1, timeout * 1000);
+                if (r  < 0) {
+                        if (errno == EINTR)
+                                continue;
+                        err = -errno;
+                        break;
+                }
+
+                if (r > 0 && pfd[0].revents & POLLERR) {
+                        err = -EIO;
+                        break;
+                }
+
+                if (r == 0)
+                        err = -ETIMEDOUT;
+                break;
+        }
+out:
+        return err;
+}
+
+int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout)
+{
+        return ctrl_send(uctrl, UDEV_CTRL_SET_LOG_LEVEL, priority, NULL, timeout);
+}
+
+int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout)
+{
+        return ctrl_send(uctrl, UDEV_CTRL_STOP_EXEC_QUEUE, 0, NULL, timeout);
+}
+
+int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl, int timeout)
+{
+        return ctrl_send(uctrl, UDEV_CTRL_START_EXEC_QUEUE, 0, NULL, timeout);
+}
+
+int udev_ctrl_send_reload(struct udev_ctrl *uctrl, int timeout)
+{
+        return ctrl_send(uctrl, UDEV_CTRL_RELOAD, 0, NULL, timeout);
+}
+
+int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key, int timeout)
+{
+        return ctrl_send(uctrl, UDEV_CTRL_SET_ENV, 0, key, timeout);
+}
+
+int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count, int timeout)
+{
+        return ctrl_send(uctrl, UDEV_CTRL_SET_CHILDREN_MAX, count, NULL, timeout);
+}
+
+int udev_ctrl_send_ping(struct udev_ctrl *uctrl, int timeout)
+{
+        return ctrl_send(uctrl, UDEV_CTRL_PING, 0, NULL, timeout);
+}
+
+int udev_ctrl_send_exit(struct udev_ctrl *uctrl, int timeout)
+{
+        return ctrl_send(uctrl, UDEV_CTRL_EXIT, 0, NULL, timeout);
+}
+
+struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn)
+{
+        struct udev_ctrl_msg *uctrl_msg;
+        ssize_t size;
+        struct msghdr smsg;
+        struct cmsghdr *cmsg;
+        struct iovec iov;
+        struct ucred *cred;
+        char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+
+        uctrl_msg = calloc(1, sizeof(struct udev_ctrl_msg));
+        if (uctrl_msg == NULL)
+                return NULL;
+        uctrl_msg->refcount = 1;
+        uctrl_msg->conn = conn;
+        udev_ctrl_connection_ref(conn);
+
+        /* wait for the incoming message */
+        for(;;) {
+                struct pollfd pfd[1];
+                int r;
+
+                pfd[0].fd = conn->sock;
+                pfd[0].events = POLLIN;
+
+                r = poll(pfd, 1, 10000);
+                if (r  < 0) {
+                        if (errno == EINTR)
+                                continue;
+                        goto err;
+                } else if (r == 0) {
+                        log_error("timeout waiting for ctrl message\n");
+                        goto err;
+                } else {
+                        if (!(pfd[0].revents & POLLIN)) {
+                                log_error("ctrl connection error: %m\n");
+                                goto err;
+                        }
+                }
+
+                break;
+        }
+
+        iov.iov_base = &uctrl_msg->ctrl_msg_wire;
+        iov.iov_len = sizeof(struct udev_ctrl_msg_wire);
+        memset(&smsg, 0x00, sizeof(struct msghdr));
+        smsg.msg_iov = &iov;
+        smsg.msg_iovlen = 1;
+        smsg.msg_control = cred_msg;
+        smsg.msg_controllen = sizeof(cred_msg);
+        size = recvmsg(conn->sock, &smsg, 0);
+        if (size <  0) {
+                log_error("unable to receive ctrl message: %m\n");
+                goto err;
+        }
+        cmsg = CMSG_FIRSTHDR(&smsg);
+        cred = (struct ucred *) CMSG_DATA(cmsg);
+
+        if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
+                log_error("no sender credentials received, message ignored\n");
+                goto err;
+        }
+
+        if (cred->uid != 0) {
+                log_error("sender uid=%i, message ignored\n", cred->uid);
+                goto err;
+        }
+
+        if (uctrl_msg->ctrl_msg_wire.magic != UDEV_CTRL_MAGIC) {
+                log_error("message magic 0x%08x doesn't match, ignore it\n", uctrl_msg->ctrl_msg_wire.magic);
+                goto err;
+        }
+
+        return uctrl_msg;
+err:
+        udev_ctrl_msg_unref(uctrl_msg);
+        return NULL;
+}
+
+struct udev_ctrl_msg *udev_ctrl_msg_ref(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg == NULL)
+                return NULL;
+        ctrl_msg->refcount++;
+        return ctrl_msg;
+}
+
+struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg == NULL)
+                return NULL;
+        ctrl_msg->refcount--;
+        if (ctrl_msg->refcount > 0)
+                return ctrl_msg;
+        udev_ctrl_connection_unref(ctrl_msg->conn);
+        free(ctrl_msg);
+        return NULL;
+}
+
+int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_LOG_LEVEL)
+                return ctrl_msg->ctrl_msg_wire.intval;
+        return -1;
+}
+
+int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_STOP_EXEC_QUEUE)
+                return 1;
+        return -1;
+}
+
+int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_START_EXEC_QUEUE)
+                return 1;
+        return -1;
+}
+
+int udev_ctrl_get_reload(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_RELOAD)
+                return 1;
+        return -1;
+}
+
+const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_ENV)
+                return ctrl_msg->ctrl_msg_wire.buf;
+        return NULL;
+}
+
+int udev_ctrl_get_set_children_max(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_CHILDREN_MAX)
+                return ctrl_msg->ctrl_msg_wire.intval;
+        return -1;
+}
+
+int udev_ctrl_get_ping(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_PING)
+                return 1;
+        return -1;
+}
+
+int udev_ctrl_get_exit(struct udev_ctrl_msg *ctrl_msg)
+{
+        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_EXIT)
+                return 1;
+        return -1;
+}
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
new file mode 100644 (file)
index 0000000..5eedf4f
--- /dev/null
@@ -0,0 +1,911 @@
+/*
+ * Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+#include <sys/poll.h>
+#include <sys/epoll.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/signalfd.h>
+#include <linux/sockios.h>
+
+#include "udev.h"
+
+struct udev_event *udev_event_new(struct udev_device *dev)
+{
+        struct udev *udev = udev_device_get_udev(dev);
+        struct udev_event *event;
+
+        event = calloc(1, sizeof(struct udev_event));
+        if (event == NULL)
+                return NULL;
+        event->dev = dev;
+        event->udev = udev;
+        udev_list_init(udev, &event->run_list, false);
+        event->fd_signal = -1;
+        event->birth_usec = now(CLOCK_MONOTONIC);
+        event->timeout_usec = 30 * 1000 * 1000;
+        return event;
+}
+
+void udev_event_unref(struct udev_event *event)
+{
+        if (event == NULL)
+                return;
+        udev_list_cleanup(&event->run_list);
+        free(event->program_result);
+        free(event->name);
+        free(event);
+}
+
+size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size)
+{
+        struct udev_device *dev = event->dev;
+        enum subst_type {
+                SUBST_UNKNOWN,
+                SUBST_DEVNODE,
+                SUBST_ATTR,
+                SUBST_ENV,
+                SUBST_KERNEL,
+                SUBST_KERNEL_NUMBER,
+                SUBST_DRIVER,
+                SUBST_DEVPATH,
+                SUBST_ID,
+                SUBST_MAJOR,
+                SUBST_MINOR,
+                SUBST_RESULT,
+                SUBST_PARENT,
+                SUBST_NAME,
+                SUBST_LINKS,
+                SUBST_ROOT,
+                SUBST_SYS,
+        };
+        static const struct subst_map {
+                const char *name;
+                const char fmt;
+                enum subst_type type;
+        } map[] = {
+                { .name = "devnode",  .fmt = 'N', .type = SUBST_DEVNODE },
+                { .name = "tempnode", .fmt = 'N', .type = SUBST_DEVNODE },
+                { .name = "attr",     .fmt = 's', .type = SUBST_ATTR },
+                { .name = "sysfs",    .fmt = 's', .type = SUBST_ATTR },
+                { .name = "env",      .fmt = 'E', .type = SUBST_ENV },
+                { .name = "kernel",   .fmt = 'k', .type = SUBST_KERNEL },
+                { .name = "number",   .fmt = 'n', .type = SUBST_KERNEL_NUMBER },
+                { .name = "driver",   .fmt = 'd', .type = SUBST_DRIVER },
+                { .name = "devpath",  .fmt = 'p', .type = SUBST_DEVPATH },
+                { .name = "id",       .fmt = 'b', .type = SUBST_ID },
+                { .name = "major",    .fmt = 'M', .type = SUBST_MAJOR },
+                { .name = "minor",    .fmt = 'm', .type = SUBST_MINOR },
+                { .name = "result",   .fmt = 'c', .type = SUBST_RESULT },
+                { .name = "parent",   .fmt = 'P', .type = SUBST_PARENT },
+                { .name = "name",     .fmt = 'D', .type = SUBST_NAME },
+                { .name = "links",    .fmt = 'L', .type = SUBST_LINKS },
+                { .name = "root",     .fmt = 'r', .type = SUBST_ROOT },
+                { .name = "sys",      .fmt = 'S', .type = SUBST_SYS },
+        };
+        const char *from;
+        char *s;
+        size_t l;
+
+        from = src;
+        s = dest;
+        l = size;
+
+        for (;;) {
+                enum subst_type type = SUBST_UNKNOWN;
+                char attrbuf[UTIL_PATH_SIZE];
+                char *attr = NULL;
+
+                while (from[0] != '\0') {
+                        if (from[0] == '$') {
+                                /* substitute named variable */
+                                unsigned int i;
+
+                                if (from[1] == '$') {
+                                        from++;
+                                        goto copy;
+                                }
+
+                                for (i = 0; i < ELEMENTSOF(map); i++) {
+                                        if (startswith(&from[1], map[i].name)) {
+                                                type = map[i].type;
+                                                from += strlen(map[i].name)+1;
+                                                goto subst;
+                                        }
+                                }
+                        } else if (from[0] == '%') {
+                                /* substitute format char */
+                                unsigned int i;
+
+                                if (from[1] == '%') {
+                                        from++;
+                                        goto copy;
+                                }
+
+                                for (i = 0; i < ELEMENTSOF(map); i++) {
+                                        if (from[1] == map[i].fmt) {
+                                                type = map[i].type;
+                                                from += 2;
+                                                goto subst;
+                                        }
+                                }
+                        }
+copy:
+                        /* copy char */
+                        if (l == 0)
+                                goto out;
+                        s[0] = from[0];
+                        from++;
+                        s++;
+                        l--;
+                }
+
+                goto out;
+subst:
+                /* extract possible $format{attr} */
+                if (from[0] == '{') {
+                        unsigned int i;
+
+                        from++;
+                        for (i = 0; from[i] != '}'; i++) {
+                                if (from[i] == '\0') {
+                                        log_error("missing closing brace for format '%s'\n", src);
+                                        goto out;
+                                }
+                        }
+                        if (i >= sizeof(attrbuf))
+                                goto out;
+                        memcpy(attrbuf, from, i);
+                        attrbuf[i] = '\0';
+                        from += i+1;
+                        attr = attrbuf;
+                } else {
+                        attr = NULL;
+                }
+
+                switch (type) {
+                case SUBST_DEVPATH:
+                        l = util_strpcpy(&s, l, udev_device_get_devpath(dev));
+                        break;
+                case SUBST_KERNEL:
+                        l = util_strpcpy(&s, l, udev_device_get_sysname(dev));
+                        break;
+                case SUBST_KERNEL_NUMBER:
+                        if (udev_device_get_sysnum(dev) == NULL)
+                                break;
+                        l = util_strpcpy(&s, l, udev_device_get_sysnum(dev));
+                        break;
+                case SUBST_ID:
+                        if (event->dev_parent == NULL)
+                                break;
+                        l = util_strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
+                        break;
+                case SUBST_DRIVER: {
+                        const char *driver;
+
+                        if (event->dev_parent == NULL)
+                                break;
+
+                        driver = udev_device_get_driver(event->dev_parent);
+                        if (driver == NULL)
+                                break;
+                        l = util_strpcpy(&s, l, driver);
+                        break;
+                }
+                case SUBST_MAJOR: {
+                        char num[UTIL_PATH_SIZE];
+
+                        sprintf(num, "%d", major(udev_device_get_devnum(dev)));
+                        l = util_strpcpy(&s, l, num);
+                        break;
+                }
+                case SUBST_MINOR: {
+                        char num[UTIL_PATH_SIZE];
+
+                        sprintf(num, "%d", minor(udev_device_get_devnum(dev)));
+                        l = util_strpcpy(&s, l, num);
+                        break;
+                }
+                case SUBST_RESULT: {
+                        char *rest;
+                        int i;
+
+                        if (event->program_result == NULL)
+                                break;
+                        /* get part part of the result string */
+                        i = 0;
+                        if (attr != NULL)
+                                i = strtoul(attr, &rest, 10);
+                        if (i > 0) {
+                                char result[UTIL_PATH_SIZE];
+                                char tmp[UTIL_PATH_SIZE];
+                                char *cpos;
+
+                                util_strscpy(result, sizeof(result), event->program_result);
+                                cpos = result;
+                                while (--i) {
+                                        while (cpos[0] != '\0' && !isspace(cpos[0]))
+                                                cpos++;
+                                        while (isspace(cpos[0]))
+                                                cpos++;
+                                }
+                                if (i > 0) {
+                                        log_error("requested part of result string not found\n");
+                                        break;
+                                }
+                                util_strscpy(tmp, sizeof(tmp), cpos);
+                                /* %{2+}c copies the whole string from the second part on */
+                                if (rest[0] != '+') {
+                                        cpos = strchr(tmp, ' ');
+                                        if (cpos)
+                                                cpos[0] = '\0';
+                                }
+                                l = util_strpcpy(&s, l, tmp);
+                        } else {
+                                l = util_strpcpy(&s, l, event->program_result);
+                        }
+                        break;
+                }
+                case SUBST_ATTR: {
+                        const char *value = NULL;
+                        char vbuf[UTIL_NAME_SIZE];
+                        size_t len;
+                        int count;
+
+                        if (attr == NULL) {
+                                log_error("missing file parameter for attr\n");
+                                break;
+                        }
+
+                        /* try to read the value specified by "[dmi/id]product_name" */
+                        if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
+                                value = vbuf;
+
+                        /* try to read the attribute the device */
+                        if (value == NULL)
+                                value = udev_device_get_sysattr_value(event->dev, attr);
+
+                        /* try to read the attribute of the parent device, other matches have selected */
+                        if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
+                                value = udev_device_get_sysattr_value(event->dev_parent, attr);
+
+                        if (value == NULL)
+                                break;
+
+                        /* strip trailing whitespace, and replace unwanted characters */
+                        if (value != vbuf)
+                                util_strscpy(vbuf, sizeof(vbuf), value);
+                        len = strlen(vbuf);
+                        while (len > 0 && isspace(vbuf[--len]))
+                                vbuf[len] = '\0';
+                        count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
+                        if (count > 0)
+                                log_debug("%i character(s) replaced\n" , count);
+                        l = util_strpcpy(&s, l, vbuf);
+                        break;
+                }
+                case SUBST_PARENT: {
+                        struct udev_device *dev_parent;
+                        const char *devnode;
+
+                        dev_parent = udev_device_get_parent(event->dev);
+                        if (dev_parent == NULL)
+                                break;
+                        devnode = udev_device_get_devnode(dev_parent);
+                        if (devnode != NULL)
+                                l = util_strpcpy(&s, l, devnode + strlen("/dev/"));
+                        break;
+                }
+                case SUBST_DEVNODE:
+                        if (udev_device_get_devnode(dev) != NULL)
+                                l = util_strpcpy(&s, l, udev_device_get_devnode(dev));
+                        break;
+                case SUBST_NAME:
+                        if (event->name != NULL)
+                                l = util_strpcpy(&s, l, event->name);
+                        else if (udev_device_get_devnode(dev) != NULL)
+                                l = util_strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
+                        else
+                                l = util_strpcpy(&s, l, udev_device_get_sysname(dev));
+                        break;
+                case SUBST_LINKS: {
+                        struct udev_list_entry *list_entry;
+
+                        list_entry = udev_device_get_devlinks_list_entry(dev);
+                        if (list_entry == NULL)
+                                break;
+                        l = util_strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+                        udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
+                                l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
+                        break;
+                }
+                case SUBST_ROOT:
+                        l = util_strpcpy(&s, l, "/dev");
+                        break;
+                case SUBST_SYS:
+                        l = util_strpcpy(&s, l, "/sys");
+                        break;
+                case SUBST_ENV:
+                        if (attr == NULL) {
+                                break;
+                        } else {
+                                const char *value;
+
+                                value = udev_device_get_property_value(event->dev, attr);
+                                if (value == NULL)
+                                        break;
+                                l = util_strpcpy(&s, l, value);
+                                break;
+                        }
+                default:
+                        log_error("unknown substitution type=%i\n", type);
+                        break;
+                }
+        }
+
+out:
+        s[0] = '\0';
+        return l;
+}
+
+static int spawn_exec(struct udev_event *event,
+                      const char *cmd, char *const argv[], char **envp, const sigset_t *sigmask,
+                      int fd_stdout, int fd_stderr)
+{
+        int err;
+        int fd;
+
+        /* discard child output or connect to pipe */
+        fd = open("/dev/null", O_RDWR);
+        if (fd >= 0) {
+                dup2(fd, STDIN_FILENO);
+                if (fd_stdout < 0)
+                        dup2(fd, STDOUT_FILENO);
+                if (fd_stderr < 0)
+                        dup2(fd, STDERR_FILENO);
+                close(fd);
+        } else {
+                log_error("open /dev/null failed: %m\n");
+        }
+
+        /* connect pipes to std{out,err} */
+        if (fd_stdout >= 0) {
+                dup2(fd_stdout, STDOUT_FILENO);
+                        close(fd_stdout);
+        }
+        if (fd_stderr >= 0) {
+                dup2(fd_stderr, STDERR_FILENO);
+                close(fd_stderr);
+        }
+
+        /* terminate child in case parent goes away */
+        prctl(PR_SET_PDEATHSIG, SIGTERM);
+
+        /* restore original udev sigmask before exec */
+        if (sigmask)
+                sigprocmask(SIG_SETMASK, sigmask, NULL);
+
+        execve(argv[0], argv, envp);
+
+        /* exec failed */
+        err = -errno;
+        log_error("failed to execute '%s' '%s': %m\n", argv[0], cmd);
+        return err;
+}
+
+static void spawn_read(struct udev_event *event,
+                      const char *cmd,
+                      int fd_stdout, int fd_stderr,
+                      char *result, size_t ressize)
+{
+        size_t respos = 0;
+        int fd_ep = -1;
+        struct epoll_event ep_outpipe, ep_errpipe;
+
+        /* read from child if requested */
+        if (fd_stdout < 0 && fd_stderr < 0)
+                return;
+
+        fd_ep = epoll_create1(EPOLL_CLOEXEC);
+        if (fd_ep < 0) {
+                log_error("error creating epoll fd: %m\n");
+                goto out;
+        }
+
+        if (fd_stdout >= 0) {
+                memset(&ep_outpipe, 0, sizeof(struct epoll_event));
+                ep_outpipe.events = EPOLLIN;
+                ep_outpipe.data.ptr = &fd_stdout;
+                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stdout, &ep_outpipe) < 0) {
+                        log_error("fail to add fd to epoll: %m\n");
+                        goto out;
+                }
+        }
+
+        if (fd_stderr >= 0) {
+                memset(&ep_errpipe, 0, sizeof(struct epoll_event));
+                ep_errpipe.events = EPOLLIN;
+                ep_errpipe.data.ptr = &fd_stderr;
+                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stderr, &ep_errpipe) < 0) {
+                        log_error("fail to add fd to epoll: %m\n");
+                        goto out;
+                }
+        }
+
+        /* read child output */
+        while (fd_stdout >= 0 || fd_stderr >= 0) {
+                int timeout;
+                int fdcount;
+                struct epoll_event ev[4];
+                int i;
+
+                if (event->timeout_usec > 0) {
+                        usec_t age_usec;
+
+                        age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
+                        if (age_usec >= event->timeout_usec) {
+                                log_error("timeout '%s'\n", cmd);
+                                goto out;
+                        }
+                        timeout = ((event->timeout_usec - age_usec) / 1000) + 1000;
+                } else {
+                        timeout = -1;
+                }
+
+                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
+                if (fdcount < 0) {
+                        if (errno == EINTR)
+                                continue;
+                        log_error("failed to poll: %m\n");
+                        goto out;
+                }
+                if (fdcount == 0) {
+                        log_error("timeout '%s'\n", cmd);
+                        goto out;
+                }
+
+                for (i = 0; i < fdcount; i++) {
+                        int *fd = (int *)ev[i].data.ptr;
+
+                        if (ev[i].events & EPOLLIN) {
+                                ssize_t count;
+                                char buf[4096];
+
+                                count = read(*fd, buf, sizeof(buf)-1);
+                                if (count <= 0)
+                                        continue;
+                                buf[count] = '\0';
+
+                                /* store stdout result */
+                                if (result != NULL && *fd == fd_stdout) {
+                                        if (respos + count < ressize) {
+                                                memcpy(&result[respos], buf, count);
+                                                respos += count;
+                                        } else {
+                                                log_error("'%s' ressize %zd too short\n", cmd, ressize);
+                                        }
+                                }
+
+                                /* log debug output only if we watch stderr */
+                                if (fd_stderr >= 0) {
+                                        char *pos;
+                                        char *line;
+
+                                        pos = buf;
+                                        while ((line = strsep(&pos, "\n"))) {
+                                                if (pos != NULL || line[0] != '\0')
+                                                        log_debug("'%s'(%s) '%s'\n", cmd, *fd == fd_stdout ? "out" : "err" , line);
+                                        }
+                                }
+                        } else if (ev[i].events & EPOLLHUP) {
+                                if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, *fd, NULL) < 0) {
+                                        log_error("failed to remove fd from epoll: %m\n");
+                                        goto out;
+                                }
+                                *fd = -1;
+                        }
+                }
+        }
+
+        /* return the child's stdout string */
+        if (result != NULL)
+                result[respos] = '\0';
+out:
+        if (fd_ep >= 0)
+                close(fd_ep);
+}
+
+static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
+{
+        struct pollfd pfd[1];
+        int err = 0;
+
+        pfd[0].events = POLLIN;
+        pfd[0].fd = event->fd_signal;
+
+        while (pid > 0) {
+                int timeout;
+                int fdcount;
+
+                if (event->timeout_usec > 0) {
+                        usec_t age_usec;
+
+                        age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
+                        if (age_usec >= event->timeout_usec)
+                                timeout = 1000;
+                        else
+                                timeout = ((event->timeout_usec - age_usec) / 1000) + 1000;
+                } else {
+                        timeout = -1;
+                }
+
+                fdcount = poll(pfd, 1, timeout);
+                if (fdcount < 0) {
+                        if (errno == EINTR)
+                                continue;
+                        err = -errno;
+                        log_error("failed to poll: %m\n");
+                        goto out;
+                }
+                if (fdcount == 0) {
+                        log_error("timeout: killing '%s' [%u]\n", cmd, pid);
+                        kill(pid, SIGKILL);
+                }
+
+                if (pfd[0].revents & POLLIN) {
+                        struct signalfd_siginfo fdsi;
+                        int status;
+                        ssize_t size;
+
+                        size = read(event->fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
+                        if (size != sizeof(struct signalfd_siginfo))
+                                continue;
+
+                        switch (fdsi.ssi_signo) {
+                        case SIGTERM:
+                                event->sigterm = true;
+                                break;
+                        case SIGCHLD:
+                                if (waitpid(pid, &status, WNOHANG) < 0)
+                                        break;
+                                if (WIFEXITED(status)) {
+                                        log_debug("'%s' [%u] exit with return code %i\n", cmd, pid, WEXITSTATUS(status));
+                                        if (WEXITSTATUS(status) != 0)
+                                                err = -1;
+                                } else if (WIFSIGNALED(status)) {
+                                        log_error("'%s' [%u] terminated by signal %i (%s)\n", cmd, pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
+                                        err = -1;
+                                } else if (WIFSTOPPED(status)) {
+                                        log_error("'%s' [%u] stopped\n", cmd, pid);
+                                        err = -1;
+                                } else if (WIFCONTINUED(status)) {
+                                        log_error("'%s' [%u] continued\n", cmd, pid);
+                                        err = -1;
+                                } else {
+                                        log_error("'%s' [%u] exit with status 0x%04x\n", cmd, pid, status);
+                                        err = -1;
+                                }
+                                pid = 0;
+                                break;
+                        }
+                }
+        }
+out:
+        return err;
+}
+
+int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[])
+{
+        int i = 0;
+        char *pos;
+
+        if (strchr(cmd, ' ') == NULL) {
+                argv[i++] = cmd;
+                goto out;
+        }
+
+        pos = cmd;
+        while (pos != NULL && pos[0] != '\0') {
+                if (pos[0] == '\'') {
+                        /* do not separate quotes */
+                        pos++;
+                        argv[i] = strsep(&pos, "\'");
+                        if (pos != NULL)
+                                while (pos[0] == ' ')
+                                        pos++;
+                } else {
+                        argv[i] = strsep(&pos, " ");
+                        if (pos != NULL)
+                                while (pos[0] == ' ')
+                                        pos++;
+                }
+                i++;
+        }
+out:
+        argv[i] = NULL;
+        if (argc)
+                *argc = i;
+        return 0;
+}
+
+int udev_event_spawn(struct udev_event *event,
+                     const char *cmd, char **envp, const sigset_t *sigmask,
+                     char *result, size_t ressize)
+{
+        struct udev *udev = event->udev;
+        int outpipe[2] = {-1, -1};
+        int errpipe[2] = {-1, -1};
+        pid_t pid;
+        char arg[UTIL_PATH_SIZE];
+        char *argv[128];
+        char program[UTIL_PATH_SIZE];
+        int err = 0;
+
+        util_strscpy(arg, sizeof(arg), cmd);
+        udev_build_argv(event->udev, arg, NULL, argv);
+
+        /* pipes from child to parent */
+        if (result != NULL || udev_get_log_priority(udev) >= LOG_INFO) {
+                if (pipe2(outpipe, O_NONBLOCK) != 0) {
+                        err = -errno;
+                        log_error("pipe failed: %m\n");
+                        goto out;
+                }
+        }
+        if (udev_get_log_priority(udev) >= LOG_INFO) {
+                if (pipe2(errpipe, O_NONBLOCK) != 0) {
+                        err = -errno;
+                        log_error("pipe failed: %m\n");
+                        goto out;
+                }
+        }
+
+        /* allow programs in /usr/lib/udev/ to be called without the path */
+        if (argv[0][0] != '/') {
+                util_strscpyl(program, sizeof(program), UDEVLIBEXECDIR "/", argv[0], NULL);
+                argv[0] = program;
+        }
+
+        pid = fork();
+        switch(pid) {
+        case 0:
+                /* child closes parent's ends of pipes */
+                if (outpipe[READ_END] >= 0) {
+                        close(outpipe[READ_END]);
+                        outpipe[READ_END] = -1;
+                }
+                if (errpipe[READ_END] >= 0) {
+                        close(errpipe[READ_END]);
+                        errpipe[READ_END] = -1;
+                }
+
+                log_debug("starting '%s'\n", cmd);
+
+                spawn_exec(event, cmd, argv, envp, sigmask,
+                           outpipe[WRITE_END], errpipe[WRITE_END]);
+
+                _exit(2 );
+        case -1:
+                log_error("fork of '%s' failed: %m\n", cmd);
+                err = -1;
+                goto out;
+        default:
+                /* parent closed child's ends of pipes */
+                if (outpipe[WRITE_END] >= 0) {
+                        close(outpipe[WRITE_END]);
+                        outpipe[WRITE_END] = -1;
+                }
+                if (errpipe[WRITE_END] >= 0) {
+                        close(errpipe[WRITE_END]);
+                        errpipe[WRITE_END] = -1;
+                }
+
+                spawn_read(event, cmd,
+                         outpipe[READ_END], errpipe[READ_END],
+                         result, ressize);
+
+                err = spawn_wait(event, cmd, pid);
+        }
+
+out:
+        if (outpipe[READ_END] >= 0)
+                close(outpipe[READ_END]);
+        if (outpipe[WRITE_END] >= 0)
+                close(outpipe[WRITE_END]);
+        if (errpipe[READ_END] >= 0)
+                close(errpipe[READ_END]);
+        if (errpipe[WRITE_END] >= 0)
+                close(errpipe[WRITE_END]);
+        return err;
+}
+
+static int rename_netif(struct udev_event *event)
+{
+        struct udev_device *dev = event->dev;
+        int sk;
+        struct ifreq ifr;
+        int err;
+
+        log_debug("changing net interface name from '%s' to '%s'\n",
+                  udev_device_get_sysname(dev), event->name);
+
+        sk = socket(PF_INET, SOCK_DGRAM, 0);
+        if (sk < 0) {
+                err = -errno;
+                log_error("error opening socket: %m\n");
+                return err;
+        }
+
+        memset(&ifr, 0x00, sizeof(struct ifreq));
+        util_strscpy(ifr.ifr_name, IFNAMSIZ, udev_device_get_sysname(dev));
+        util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name);
+        err = ioctl(sk, SIOCSIFNAME, &ifr);
+        if (err >= 0) {
+                print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname);
+        } else {
+                err = -errno;
+                log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname);
+        }
+        close(sk);
+        return err;
+}
+
+int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask)
+{
+        struct udev_device *dev = event->dev;
+        int err = 0;
+
+        if (udev_device_get_subsystem(dev) == NULL)
+                return -1;
+
+        if (strcmp(udev_device_get_action(dev), "remove") == 0) {
+                udev_device_read_db(dev, NULL);
+                udev_device_delete_db(dev);
+                udev_device_tag_index(dev, NULL, false);
+
+                if (major(udev_device_get_devnum(dev)) != 0)
+                        udev_watch_end(event->udev, dev);
+
+                udev_rules_apply_to_event(rules, event, sigmask);
+
+                if (major(udev_device_get_devnum(dev)) != 0)
+                        udev_node_remove(dev);
+        } else {
+                event->dev_db = udev_device_new(event->udev);
+                if (event->dev_db != NULL) {
+                        udev_device_set_syspath(event->dev_db, udev_device_get_syspath(dev));
+                        udev_device_set_subsystem(event->dev_db, udev_device_get_subsystem(dev));
+                        udev_device_read_db(event->dev_db, NULL);
+                        udev_device_set_info_loaded(event->dev_db);
+
+                        /* disable watch during event processing */
+                        if (major(udev_device_get_devnum(dev)) != 0)
+                                udev_watch_end(event->udev, event->dev_db);
+                }
+
+                udev_rules_apply_to_event(rules, event, sigmask);
+
+                /* rename a new network interface, if needed */
+                if (udev_device_get_ifindex(dev) > 0 && strcmp(udev_device_get_action(dev), "add") == 0 &&
+                    event->name != NULL && strcmp(event->name, udev_device_get_sysname(dev)) != 0) {
+                        char syspath[UTIL_PATH_SIZE];
+                        char *pos;
+
+                        err = rename_netif(event);
+                        if (err == 0) {
+                                log_debug("renamed netif to '%s'\n", event->name);
+
+                                /* remember old name */
+                                udev_device_add_property(dev, "INTERFACE_OLD", udev_device_get_sysname(dev));
+
+                                /* now change the devpath, because the kernel device name has changed */
+                                util_strscpy(syspath, sizeof(syspath), udev_device_get_syspath(dev));
+                                pos = strrchr(syspath, '/');
+                                if (pos != NULL) {
+                                        pos++;
+                                        util_strscpy(pos, sizeof(syspath) - (pos - syspath), event->name);
+                                        udev_device_set_syspath(event->dev, syspath);
+                                        udev_device_add_property(dev, "INTERFACE", udev_device_get_sysname(dev));
+                                        log_debug("changed devpath to '%s'\n", udev_device_get_devpath(dev));
+                                }
+                        }
+                }
+
+                if (major(udev_device_get_devnum(dev)) > 0) {
+                        /* remove/update possible left-over symlinks from old database entry */
+                        if (event->dev_db != NULL)
+                                udev_node_update_old_links(dev, event->dev_db);
+
+                        if (!event->owner_set)
+                                event->uid = udev_device_get_devnode_uid(dev);
+
+                        if (!event->group_set)
+                                event->gid = udev_device_get_devnode_gid(dev);
+
+                        if (!event->mode_set) {
+                                if (udev_device_get_devnode_mode(dev) > 0) {
+                                        /* kernel supplied value */
+                                        event->mode = udev_device_get_devnode_mode(dev);
+                                } else if (event->gid > 0) {
+                                        /* default 0660 if a group is assigned */
+                                        event->mode = 0660;
+                                } else {
+                                        /* default 0600 */
+                                        event->mode = 0600;
+                                }
+                        }
+
+                        udev_node_add(dev, event->mode, event->uid, event->gid);
+                }
+
+                /* preserve old, or get new initialization timestamp */
+                if (event->dev_db != NULL && udev_device_get_usec_initialized(event->dev_db) > 0)
+                        udev_device_set_usec_initialized(event->dev, udev_device_get_usec_initialized(event->dev_db));
+                else if (udev_device_get_usec_initialized(event->dev) == 0)
+                        udev_device_set_usec_initialized(event->dev, now(CLOCK_MONOTONIC));
+
+                /* (re)write database file */
+                udev_device_update_db(dev);
+                udev_device_tag_index(dev, event->dev_db, true);
+                udev_device_set_is_initialized(dev);
+
+                udev_device_unref(event->dev_db);
+                event->dev_db = NULL;
+        }
+        return err;
+}
+
+void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
+{
+        struct udev_list_entry *list_entry;
+
+        udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
+                const char *cmd = udev_list_entry_get_name(list_entry);
+                enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry);
+
+                if (builtin_cmd < UDEV_BUILTIN_MAX) {
+                        char command[UTIL_PATH_SIZE];
+
+                        udev_event_apply_format(event, cmd, command, sizeof(command));
+                        udev_builtin_run(event->dev, builtin_cmd, command, false);
+                } else {
+                        char program[UTIL_PATH_SIZE];
+                        char **envp;
+
+                        if (event->exec_delay > 0) {
+                                log_debug("delay execution of '%s'\n", program);
+                                sleep(event->exec_delay);
+                        }
+
+                        udev_event_apply_format(event, cmd, program, sizeof(program));
+                        envp = udev_device_get_properties_envp(event->dev);
+                        udev_event_spawn(event, program, envp, sigmask, NULL, 0);
+                }
+        }
+}
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
new file mode 100644 (file)
index 0000000..1e378ad
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <grp.h>
+#include <dirent.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "udev.h"
+
+#define TMP_FILE_EXT                ".udev-tmp"
+
+static int node_symlink(struct udev *udev, const char *node, const char *slink)
+{
+        struct stat stats;
+        char target[UTIL_PATH_SIZE];
+        char *s;
+        size_t l;
+        char slink_tmp[UTIL_PATH_SIZE + sizeof(TMP_FILE_EXT)];
+        int i = 0;
+        int tail = 0;
+        int err = 0;
+
+        /* use relative link */
+        target[0] = '\0';
+        while (node[i] && (node[i] == slink[i])) {
+                if (node[i] == '/')
+                        tail = i+1;
+                i++;
+        }
+        s = target;
+        l = sizeof(target);
+        while (slink[i] != '\0') {
+                if (slink[i] == '/')
+                        l = util_strpcpy(&s, l, "../");
+                i++;
+        }
+        l = util_strscpy(s, l, &node[tail]);
+        if (l == 0) {
+                err = -EINVAL;
+                goto exit;
+        }
+
+        /* preserve link with correct target, do not replace node of other device */
+        if (lstat(slink, &stats) == 0) {
+                if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) {
+                        log_error("conflicting device node '%s' found, link to '%s' will not be created\n", slink, node);
+                        goto exit;
+                } else if (S_ISLNK(stats.st_mode)) {
+                        char buf[UTIL_PATH_SIZE];
+                        int len;
+
+                        len = readlink(slink, buf, sizeof(buf));
+                        if (len > 0 && len < (int)sizeof(buf)) {
+                                buf[len] = '\0';
+                                if (strcmp(target, buf) == 0) {
+                                        log_debug("preserve already existing symlink '%s' to '%s'\n", slink, target);
+                                        label_fix(slink, true, false);
+                                        utimensat(AT_FDCWD, slink, NULL, AT_SYMLINK_NOFOLLOW);
+                                        goto exit;
+                                }
+                        }
+                }
+        } else {
+                log_debug("creating symlink '%s' to '%s'\n", slink, target);
+                do {
+                        err = mkdir_parents_label(slink, 0755);
+                        if (err != 0 && err != -ENOENT)
+                                break;
+                        label_context_set(slink, S_IFLNK);
+                        err = symlink(target, slink);
+                        if (err != 0)
+                                err = -errno;
+                        label_context_clear();
+                } while (err == -ENOENT);
+                if (err == 0)
+                        goto exit;
+        }
+
+        log_debug("atomically replace '%s'\n", slink);
+        util_strscpyl(slink_tmp, sizeof(slink_tmp), slink, TMP_FILE_EXT, NULL);
+        unlink(slink_tmp);
+        do {
+                err = mkdir_parents_label(slink_tmp, 0755);
+                if (err != 0 && err != -ENOENT)
+                        break;
+                label_context_set(slink_tmp, S_IFLNK);
+                err = symlink(target, slink_tmp);
+                if (err != 0)
+                        err = -errno;
+                label_context_clear();
+        } while (err == -ENOENT);
+        if (err != 0) {
+                log_error("symlink '%s' '%s' failed: %m\n", target, slink_tmp);
+                goto exit;
+        }
+        err = rename(slink_tmp, slink);
+        if (err != 0) {
+                log_error("rename '%s' '%s' failed: %m\n", slink_tmp, slink);
+                unlink(slink_tmp);
+        }
+exit:
+        return err;
+}
+
+/* find device node of device with highest priority */
+static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize)
+{
+        struct udev *udev = udev_device_get_udev(dev);
+        DIR *dir;
+        int priority = 0;
+        const char *target = NULL;
+
+        if (add) {
+                priority = udev_device_get_devlink_priority(dev);
+                util_strscpy(buf, bufsize, udev_device_get_devnode(dev));
+                target = buf;
+        }
+
+        dir = opendir(stackdir);
+        if (dir == NULL)
+                return target;
+        for (;;) {
+                struct udev_device *dev_db;
+                struct dirent *dent;
+
+                dent = readdir(dir);
+                if (dent == NULL || dent->d_name[0] == '\0')
+                        break;
+                if (dent->d_name[0] == '.')
+                        continue;
+
+                log_debug("found '%s' claiming '%s'\n", dent->d_name, stackdir);
+
+                /* did we find ourself? */
+                if (strcmp(dent->d_name, udev_device_get_id_filename(dev)) == 0)
+                        continue;
+
+                dev_db = udev_device_new_from_device_id(udev, dent->d_name);
+                if (dev_db != NULL) {
+                        const char *devnode;
+
+                        devnode = udev_device_get_devnode(dev_db);
+                        if (devnode != NULL) {
+                                if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) {
+                                        log_debug("'%s' claims priority %i for '%s'\n",
+                                                  udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir);
+                                        priority = udev_device_get_devlink_priority(dev_db);
+                                        util_strscpy(buf, bufsize, devnode);
+                                        target = buf;
+                                }
+                        }
+                        udev_device_unref(dev_db);
+                }
+        }
+        closedir(dir);
+        return target;
+}
+
+/* manage "stack of names" with possibly specified device priorities */
+static void link_update(struct udev_device *dev, const char *slink, bool add)
+{
+        struct udev *udev = udev_device_get_udev(dev);
+        char name_enc[UTIL_PATH_SIZE];
+        char filename[UTIL_PATH_SIZE * 2];
+        char dirname[UTIL_PATH_SIZE];
+        const char *target;
+        char buf[UTIL_PATH_SIZE];
+
+        util_path_encode(slink + strlen("/dev"), name_enc, sizeof(name_enc));
+        util_strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL);
+        util_strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);
+
+        if (!add && unlink(filename) == 0)
+                rmdir(dirname);
+
+        target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf));
+        if (target == NULL) {
+                log_debug("no reference left, remove '%s'\n", slink);
+                if (unlink(slink) == 0)
+                        util_delete_path(udev, slink);
+        } else {
+                log_debug("creating link '%s' to '%s'\n", slink, target);
+                node_symlink(udev, target, slink);
+        }
+
+        if (add) {
+                int err;
+
+                do {
+                        int fd;
+
+                        err = mkdir_parents(filename, 0755);
+                        if (err != 0 && err != -ENOENT)
+                                break;
+                        fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
+                        if (fd >= 0)
+                                close(fd);
+                        else
+                                err = -errno;
+                } while (err == -ENOENT);
+        }
+}
+
+void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old)
+{
+        struct udev_list_entry *list_entry;
+
+        /* update possible left-over symlinks */
+        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev_old)) {
+                const char *name = udev_list_entry_get_name(list_entry);
+                struct udev_list_entry *list_entry_current;
+                int found;
+
+                /* check if old link name still belongs to this device */
+                found = 0;
+                udev_list_entry_foreach(list_entry_current, udev_device_get_devlinks_list_entry(dev)) {
+                        const char *name_current = udev_list_entry_get_name(list_entry_current);
+
+                        if (strcmp(name, name_current) == 0) {
+                                found = 1;
+                                break;
+                        }
+                }
+                if (found)
+                        continue;
+
+                log_debug("update old name, '%s' no longer belonging to '%s'\n",
+                     name, udev_device_get_devpath(dev));
+                link_update(dev, name, false);
+        }
+}
+
+static int node_fixup(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid)
+{
+        const char *devnode = udev_device_get_devnode(dev);
+        dev_t devnum = udev_device_get_devnum(dev);
+        struct stat stats;
+        int err = 0;
+
+        if (strcmp(udev_device_get_subsystem(dev), "block") == 0)
+                mode |= S_IFBLK;
+        else
+                mode |= S_IFCHR;
+
+        if (lstat(devnode, &stats) != 0) {
+                err = -errno;
+                log_debug("can not stat() node '%s' (%m)\n", devnode);
+                goto out;
+        }
+
+        if (((stats.st_mode & S_IFMT) != (mode & S_IFMT)) || (stats.st_rdev != devnum)) {
+                err = -EEXIST;
+                log_debug("found node '%s' with non-matching devnum %s, skip handling\n",
+                          udev_device_get_devnode(dev), udev_device_get_id_filename(dev));
+                goto out;
+        }
+
+        /*
+         * Set permissions and selinux file context only on add events. We always
+         * set it on bootup (coldplug) with "trigger --action=add" for all devices
+         * and for any newly added devices (hotplug). We don't want to change it
+         * later, in case something else has applied custom settings in the meantime.
+         */
+        if (strcmp(udev_device_get_action(dev), "add") == 0) {
+                if ((stats.st_mode & 0777) != (mode & 0777) || stats.st_uid != uid || stats.st_gid != gid) {
+                        log_debug("set permissions %s, %#o, uid=%u, gid=%u\n", devnode, mode, uid, gid);
+                        chmod(devnode, mode);
+                        chown(devnode, uid, gid);
+                } else {
+                        log_debug("preserve permissions %s, %#o, uid=%u, gid=%u\n", devnode, mode, uid, gid);
+                }
+
+                label_fix(devnode, true, false);
+        }
+
+        /* always update timestamp when we re-use the node, like on media change events */
+        utimensat(AT_FDCWD, devnode, NULL, 0);
+out:
+        return err;
+}
+
+void udev_node_add(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid)
+{
+        struct udev *udev = udev_device_get_udev(dev);
+        char filename[UTIL_PATH_SIZE];
+        struct udev_list_entry *list_entry;
+
+        log_debug("handling device node '%s', devnum=%s, mode=%#o, uid=%d, gid=%d\n",
+                  udev_device_get_devnode(dev), udev_device_get_id_filename(dev), mode, uid, gid);
+
+        if (node_fixup(dev, mode, uid, gid) < 0)
+                return;
+
+        /* always add /dev/{block,char}/$major:$minor */
+        snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
+                 strcmp(udev_device_get_subsystem(dev), "block") == 0 ? "block" : "char",
+                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
+        node_symlink(udev, udev_device_get_devnode(dev), filename);
+
+        /* create/update symlinks, add symlinks to name index */
+        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
+                        link_update(dev, udev_list_entry_get_name(list_entry), true);
+}
+
+void udev_node_remove(struct udev_device *dev)
+{
+        struct udev_list_entry *list_entry;
+        char filename[UTIL_PATH_SIZE];
+
+        /* remove/update symlinks, remove symlinks from name index */
+        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
+                link_update(dev, udev_list_entry_get_name(list_entry), false);
+
+        /* remove /dev/{block,char}/$major:$minor */
+        snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
+                 strcmp(udev_device_get_subsystem(dev), "block") == 0 ? "block" : "char",
+                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
+        unlink(filename);
+}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
new file mode 100644 (file)
index 0000000..9743243
--- /dev/null
@@ -0,0 +1,2577 @@
+/*
+ * Copyright (C) 2003-2012 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stddef.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fnmatch.h>
+#include <time.h>
+
+#include "udev.h"
+#include "path-util.h"
+#include "conf-files.h"
+#include "strbuf.h"
+
+#define PREALLOC_TOKEN          2048
+
+struct uid_gid {
+        unsigned int name_off;
+        union {
+                uid_t uid;
+                gid_t gid;
+        };
+};
+
+struct udev_rules {
+        struct udev *udev;
+        char **dirs;
+        usec_t *dirs_ts_usec;
+        int resolve_names;
+
+        /* every key in the rules file becomes a token */
+        struct token *tokens;
+        unsigned int token_cur;
+        unsigned int token_max;
+
+        /* all key strings are copied and de-duplicated in a single continous string buffer */
+        struct strbuf *strbuf;
+
+        /* during rule parsing, uid/gid lookup results are cached */
+        struct uid_gid *uids;
+        unsigned int uids_cur;
+        unsigned int uids_max;
+        struct uid_gid *gids;
+        unsigned int gids_cur;
+        unsigned int gids_max;
+};
+
+static char *rules_str(struct udev_rules *rules, unsigned int off) {
+        return rules->strbuf->buf + off;
+}
+
+static unsigned int rules_add_string(struct udev_rules *rules, const char *s) {
+        return strbuf_add_string(rules->strbuf, s, strlen(s));
+}
+
+/* KEY=="", KEY!="", KEY+="", KEY="", KEY:="" */
+enum operation_type {
+        OP_UNSET,
+
+        OP_MATCH,
+        OP_NOMATCH,
+        OP_MATCH_MAX,
+
+        OP_ADD,
+        OP_ASSIGN,
+        OP_ASSIGN_FINAL,
+};
+
+enum string_glob_type {
+        GL_UNSET,
+        GL_PLAIN,                       /* no special chars */
+        GL_GLOB,                        /* shell globs ?,*,[] */
+        GL_SPLIT,                       /* multi-value A|B */
+        GL_SPLIT_GLOB,                  /* multi-value with glob A*|B* */
+        GL_SOMETHING,                   /* commonly used "?*" */
+};
+
+enum string_subst_type {
+        SB_UNSET,
+        SB_NONE,
+        SB_FORMAT,
+        SB_SUBSYS,
+};
+
+/* tokens of a rule are sorted/handled in this order */
+enum token_type {
+        TK_UNSET,
+        TK_RULE,
+
+        TK_M_ACTION,                    /* val */
+        TK_M_DEVPATH,                   /* val */
+        TK_M_KERNEL,                    /* val */
+        TK_M_DEVLINK,                   /* val */
+        TK_M_NAME,                      /* val */
+        TK_M_ENV,                       /* val, attr */
+        TK_M_TAG,                       /* val */
+        TK_M_SUBSYSTEM,                 /* val */
+        TK_M_DRIVER,                    /* val */
+        TK_M_WAITFOR,                   /* val */
+        TK_M_ATTR,                      /* val, attr */
+
+        TK_M_PARENTS_MIN,
+        TK_M_KERNELS,                   /* val */
+        TK_M_SUBSYSTEMS,                /* val */
+        TK_M_DRIVERS,                   /* val */
+        TK_M_ATTRS,                     /* val, attr */
+        TK_M_TAGS,                      /* val */
+        TK_M_PARENTS_MAX,
+
+        TK_M_TEST,                      /* val, mode_t */
+        TK_M_EVENT_TIMEOUT,             /* int */
+        TK_M_PROGRAM,                   /* val */
+        TK_M_IMPORT_FILE,               /* val */
+        TK_M_IMPORT_PROG,               /* val */
+        TK_M_IMPORT_BUILTIN,            /* val */
+        TK_M_IMPORT_DB,                 /* val */
+        TK_M_IMPORT_CMDLINE,            /* val */
+        TK_M_IMPORT_PARENT,             /* val */
+        TK_M_RESULT,                    /* val */
+        TK_M_MAX,
+
+        TK_A_STRING_ESCAPE_NONE,
+        TK_A_STRING_ESCAPE_REPLACE,
+        TK_A_DB_PERSIST,
+        TK_A_INOTIFY_WATCH,             /* int */
+        TK_A_DEVLINK_PRIO,              /* int */
+        TK_A_OWNER,                     /* val */
+        TK_A_GROUP,                     /* val */
+        TK_A_MODE,                      /* val */
+        TK_A_OWNER_ID,                  /* uid_t */
+        TK_A_GROUP_ID,                  /* gid_t */
+        TK_A_MODE_ID,                   /* mode_t */
+        TK_A_STATIC_NODE,               /* val */
+        TK_A_ENV,                       /* val, attr */
+        TK_A_TAG,                       /* val */
+        TK_A_NAME,                      /* val */
+        TK_A_DEVLINK,                   /* val */
+        TK_A_ATTR,                      /* val, attr */
+        TK_A_RUN_BUILTIN,               /* val, bool */
+        TK_A_RUN_PROGRAM,               /* val, bool */
+        TK_A_GOTO,                      /* size_t */
+
+        TK_END,
+};
+
+/* we try to pack stuff in a way that we take only 12 bytes per token */
+struct token {
+        union {
+                unsigned char type;                /* same in rule and key */
+                struct {
+                        enum token_type type:8;
+                        bool can_set_name:1;
+                        bool has_static_node:1;
+                        unsigned int unused:6;
+                        unsigned short token_count;
+                        unsigned int label_off;
+                        unsigned short filename_off;
+                        unsigned short filename_line;
+                } rule;
+                struct {
+                        enum token_type type:8;
+                        enum operation_type op:8;
+                        enum string_glob_type glob:8;
+                        enum string_subst_type subst:4;
+                        enum string_subst_type attrsubst:4;
+                        unsigned int value_off;
+                        union {
+                                unsigned int attr_off;
+                                unsigned int rule_goto;
+                                mode_t  mode;
+                                uid_t uid;
+                                gid_t gid;
+                                int devlink_prio;
+                                int event_timeout;
+                                int watch;
+                                enum udev_builtin_cmd builtin_cmd;
+                        };
+                } key;
+        };
+};
+
+#define MAX_TK                64
+struct rule_tmp {
+        struct udev_rules *rules;
+        struct token rule;
+        struct token token[MAX_TK];
+        unsigned int token_cur;
+};
+
+#ifdef DEBUG
+static const char *operation_str(enum operation_type type)
+{
+        static const char *operation_strs[] = {
+                [OP_UNSET] =            "UNSET",
+                [OP_MATCH] =            "match",
+                [OP_NOMATCH] =          "nomatch",
+                [OP_MATCH_MAX] =        "MATCH_MAX",
+
+                [OP_ADD] =              "add",
+                [OP_ASSIGN] =           "assign",
+                [OP_ASSIGN_FINAL] =     "assign-final",
+}        ;
+
+        return operation_strs[type];
+}
+
+static const char *string_glob_str(enum string_glob_type type)
+{
+        static const char *string_glob_strs[] = {
+                [GL_UNSET] =            "UNSET",
+                [GL_PLAIN] =            "plain",
+                [GL_GLOB] =             "glob",
+                [GL_SPLIT] =            "split",
+                [GL_SPLIT_GLOB] =       "split-glob",
+                [GL_SOMETHING] =        "split-glob",
+        };
+
+        return string_glob_strs[type];
+}
+
+static const char *token_str(enum token_type type)
+{
+        static const char *token_strs[] = {
+                [TK_UNSET] =                    "UNSET",
+                [TK_RULE] =                     "RULE",
+
+                [TK_M_ACTION] =                 "M ACTION",
+                [TK_M_DEVPATH] =                "M DEVPATH",
+                [TK_M_KERNEL] =                 "M KERNEL",
+                [TK_M_DEVLINK] =                "M DEVLINK",
+                [TK_M_NAME] =                   "M NAME",
+                [TK_M_ENV] =                    "M ENV",
+                [TK_M_TAG] =                    "M TAG",
+                [TK_M_SUBSYSTEM] =              "M SUBSYSTEM",
+                [TK_M_DRIVER] =                 "M DRIVER",
+                [TK_M_WAITFOR] =                "M WAITFOR",
+                [TK_M_ATTR] =                   "M ATTR",
+
+                [TK_M_PARENTS_MIN] =            "M PARENTS_MIN",
+                [TK_M_KERNELS] =                "M KERNELS",
+                [TK_M_SUBSYSTEMS] =             "M SUBSYSTEMS",
+                [TK_M_DRIVERS] =                "M DRIVERS",
+                [TK_M_ATTRS] =                  "M ATTRS",
+                [TK_M_TAGS] =                   "M TAGS",
+                [TK_M_PARENTS_MAX] =            "M PARENTS_MAX",
+
+                [TK_M_TEST] =                   "M TEST",
+                [TK_M_EVENT_TIMEOUT] =          "M EVENT_TIMEOUT",
+                [TK_M_PROGRAM] =                "M PROGRAM",
+                [TK_M_IMPORT_FILE] =            "M IMPORT_FILE",
+                [TK_M_IMPORT_PROG] =            "M IMPORT_PROG",
+                [TK_M_IMPORT_BUILTIN] =         "M IMPORT_BUILTIN",
+                [TK_M_IMPORT_DB] =              "M IMPORT_DB",
+                [TK_M_IMPORT_CMDLINE] =         "M IMPORT_CMDLINE",
+                [TK_M_IMPORT_PARENT] =          "M IMPORT_PARENT",
+                [TK_M_RESULT] =                 "M RESULT",
+                [TK_M_MAX] =                    "M MAX",
+
+                [TK_A_STRING_ESCAPE_NONE] =     "A STRING_ESCAPE_NONE",
+                [TK_A_STRING_ESCAPE_REPLACE] =  "A STRING_ESCAPE_REPLACE",
+                [TK_A_DB_PERSIST] =             "A DB_PERSIST",
+                [TK_A_INOTIFY_WATCH] =          "A INOTIFY_WATCH",
+                [TK_A_DEVLINK_PRIO] =           "A DEVLINK_PRIO",
+                [TK_A_OWNER] =                  "A OWNER",
+                [TK_A_GROUP] =                  "A GROUP",
+                [TK_A_MODE] =                   "A MODE",
+                [TK_A_OWNER_ID] =               "A OWNER_ID",
+                [TK_A_GROUP_ID] =               "A GROUP_ID",
+                [TK_A_STATIC_NODE] =            "A STATIC_NODE",
+                [TK_A_MODE_ID] =                "A MODE_ID",
+                [TK_A_ENV] =                    "A ENV",
+                [TK_A_TAG] =                    "A ENV",
+                [TK_A_NAME] =                   "A NAME",
+                [TK_A_DEVLINK] =                "A DEVLINK",
+                [TK_A_ATTR] =                   "A ATTR",
+                [TK_A_RUN_BUILTIN] =            "A RUN_BUILTIN",
+                [TK_A_RUN_PROGRAM] =            "A RUN_PROGRAM",
+                [TK_A_GOTO] =                   "A GOTO",
+
+                [TK_END] =                      "END",
+        };
+
+        return token_strs[type];
+}
+
+static void dump_token(struct udev_rules *rules, struct token *token)
+{
+        enum token_type type = token->type;
+        enum operation_type op = token->key.op;
+        enum string_glob_type glob = token->key.glob;
+        const char *value = str(rules, token->key.value_off);
+        const char *attr = &rules->buf[token->key.attr_off];
+
+        switch (type) {
+        case TK_RULE:
+                {
+                        const char *tks_ptr = (char *)rules->tokens;
+                        const char *tk_ptr = (char *)token;
+                        unsigned int idx = (tk_ptr - tks_ptr) / sizeof(struct token);
+
+                        log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'\n",
+                                  &rules->buf[token->rule.filename_off], token->rule.filename_line,
+                                  idx, token->rule.token_count,
+                                  &rules->buf[token->rule.label_off]);
+                        break;
+                }
+        case TK_M_ACTION:
+        case TK_M_DEVPATH:
+        case TK_M_KERNEL:
+        case TK_M_SUBSYSTEM:
+        case TK_M_DRIVER:
+        case TK_M_WAITFOR:
+        case TK_M_DEVLINK:
+        case TK_M_NAME:
+        case TK_M_KERNELS:
+        case TK_M_SUBSYSTEMS:
+        case TK_M_DRIVERS:
+        case TK_M_TAGS:
+        case TK_M_PROGRAM:
+        case TK_M_IMPORT_FILE:
+        case TK_M_IMPORT_PROG:
+        case TK_M_IMPORT_DB:
+        case TK_M_IMPORT_CMDLINE:
+        case TK_M_IMPORT_PARENT:
+        case TK_M_RESULT:
+        case TK_A_NAME:
+        case TK_A_DEVLINK:
+        case TK_A_OWNER:
+        case TK_A_GROUP:
+        case TK_A_MODE:
+        case TK_A_RUN_BUILTIN:
+        case TK_A_RUN_PROGRAM:
+                log_debug("%s %s '%s'(%s)\n",
+                          token_str(type), operation_str(op), value, string_glob_str(glob));
+                break;
+        case TK_M_IMPORT_BUILTIN:
+                log_debug("%s %i '%s'\n", token_str(type), token->key.builtin_cmd, value);
+                break;
+        case TK_M_ATTR:
+        case TK_M_ATTRS:
+        case TK_M_ENV:
+        case TK_A_ATTR:
+        case TK_A_ENV:
+                log_debug("%s %s '%s' '%s'(%s)\n",
+                          token_str(type), operation_str(op), attr, value, string_glob_str(glob));
+                break;
+        case TK_M_TAG:
+        case TK_A_TAG:
+                log_debug("%s %s '%s'\n", token_str(type), operation_str(op), value);
+                break;
+        case TK_A_STRING_ESCAPE_NONE:
+        case TK_A_STRING_ESCAPE_REPLACE:
+        case TK_A_DB_PERSIST:
+                log_debug("%s\n", token_str(type));
+                break;
+        case TK_M_TEST:
+                log_debug("%s %s '%s'(%s) %#o\n",
+                          token_str(type), operation_str(op), value, string_glob_str(glob), token->key.mode);
+                break;
+        case TK_A_INOTIFY_WATCH:
+                log_debug("%s %u\n", token_str(type), token->key.watch);
+                break;
+        case TK_A_DEVLINK_PRIO:
+                log_debug("%s %u\n", token_str(type), token->key.devlink_prio);
+                break;
+        case TK_A_OWNER_ID:
+                log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.uid);
+                break;
+        case TK_A_GROUP_ID:
+                log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.gid);
+                break;
+        case TK_A_MODE_ID:
+                log_debug("%s %s %#o\n", token_str(type), operation_str(op), token->key.mode);
+                break;
+        case TK_A_STATIC_NODE:
+                log_debug("%s '%s'\n", token_str(type), value);
+                break;
+        case TK_M_EVENT_TIMEOUT:
+                log_debug("%s %u\n", token_str(type), token->key.event_timeout);
+                break;
+        case TK_A_GOTO:
+                log_debug("%s '%s' %u\n", token_str(type), value, token->key.rule_goto);
+                break;
+        case TK_END:
+                log_debug("* %s\n", token_str(type));
+                break;
+        case TK_M_PARENTS_MIN:
+        case TK_M_PARENTS_MAX:
+        case TK_M_MAX:
+        case TK_UNSET:
+                log_debug("unknown type %u\n", type);
+                break;
+        }
+}
+
+static void dump_rules(struct udev_rules *rules)
+{
+        unsigned int i;
+
+        log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings\n",
+                  rules->token_cur,
+                  rules->token_cur * sizeof(struct token),
+                  rules->buf_count,
+                  rules->buf_cur);
+        for(i = 0; i < rules->token_cur; i++)
+                dump_token(rules, &rules->tokens[i]);
+}
+#else
+static inline const char *operation_str(enum operation_type type) { return NULL; }
+static inline const char *token_str(enum token_type type) { return NULL; }
+static inline void dump_token(struct udev_rules *rules, struct token *token) {}
+static inline void dump_rules(struct udev_rules *rules) {}
+#endif /* DEBUG */
+
+static int add_token(struct udev_rules *rules, struct token *token)
+{
+        /* grow buffer if needed */
+        if (rules->token_cur+1 >= rules->token_max) {
+                struct token *tokens;
+                unsigned int add;
+
+                /* double the buffer size */
+                add = rules->token_max;
+                if (add < 8)
+                        add = 8;
+
+                tokens = realloc(rules->tokens, (rules->token_max + add ) * sizeof(struct token));
+                if (tokens == NULL)
+                        return -1;
+                rules->tokens = tokens;
+                rules->token_max += add;
+        }
+        memcpy(&rules->tokens[rules->token_cur], token, sizeof(struct token));
+        rules->token_cur++;
+        return 0;
+}
+
+static uid_t add_uid(struct udev_rules *rules, const char *owner)
+{
+        unsigned int i;
+        uid_t uid;
+        unsigned int off;
+
+        /* lookup, if we know it already */
+        for (i = 0; i < rules->uids_cur; i++) {
+                off = rules->uids[i].name_off;
+                if (streq(rules_str(rules, off), owner)) {
+                        uid = rules->uids[i].uid;
+                        return uid;
+                }
+        }
+        uid = util_lookup_user(rules->udev, owner);
+
+        /* grow buffer if needed */
+        if (rules->uids_cur+1 >= rules->uids_max) {
+                struct uid_gid *uids;
+                unsigned int add;
+
+                /* double the buffer size */
+                add = rules->uids_max;
+                if (add < 1)
+                        add = 8;
+
+                uids = realloc(rules->uids, (rules->uids_max + add ) * sizeof(struct uid_gid));
+                if (uids == NULL)
+                        return uid;
+                rules->uids = uids;
+                rules->uids_max += add;
+        }
+        rules->uids[rules->uids_cur].uid = uid;
+        off = rules_add_string(rules, owner);
+        if (off <= 0)
+                return uid;
+        rules->uids[rules->uids_cur].name_off = off;
+        rules->uids_cur++;
+        return uid;
+}
+
+static gid_t add_gid(struct udev_rules *rules, const char *group)
+{
+        unsigned int i;
+        gid_t gid;
+        unsigned int off;
+
+        /* lookup, if we know it already */
+        for (i = 0; i < rules->gids_cur; i++) {
+                off = rules->gids[i].name_off;
+                if (streq(rules_str(rules, off), group)) {
+                        gid = rules->gids[i].gid;
+                        return gid;
+                }
+        }
+        gid = util_lookup_group(rules->udev, group);
+
+        /* grow buffer if needed */
+        if (rules->gids_cur+1 >= rules->gids_max) {
+                struct uid_gid *gids;
+                unsigned int add;
+
+                /* double the buffer size */
+                add = rules->gids_max;
+                if (add < 1)
+                        add = 8;
+
+                gids = realloc(rules->gids, (rules->gids_max + add ) * sizeof(struct uid_gid));
+                if (gids == NULL)
+                        return gid;
+                rules->gids = gids;
+                rules->gids_max += add;
+        }
+        rules->gids[rules->gids_cur].gid = gid;
+        off = rules_add_string(rules, group);
+        if (off <= 0)
+                return gid;
+        rules->gids[rules->gids_cur].name_off = off;
+        rules->gids_cur++;
+        return gid;
+}
+
+static int import_property_from_string(struct udev_device *dev, char *line)
+{
+        char *key;
+        char *val;
+        size_t len;
+
+        /* find key */
+        key = line;
+        while (isspace(key[0]))
+                key++;
+
+        /* comment or empty line */
+        if (key[0] == '#' || key[0] == '\0')
+                return -1;
+
+        /* split key/value */
+        val = strchr(key, '=');
+        if (val == NULL)
+                return -1;
+        val[0] = '\0';
+        val++;
+
+        /* find value */
+        while (isspace(val[0]))
+                val++;
+
+        /* terminate key */
+        len = strlen(key);
+        if (len == 0)
+                return -1;
+        while (isspace(key[len-1]))
+                len--;
+        key[len] = '\0';
+
+        /* terminate value */
+        len = strlen(val);
+        if (len == 0)
+                return -1;
+        while (isspace(val[len-1]))
+                len--;
+        val[len] = '\0';
+
+        if (len == 0)
+                return -1;
+
+        /* unquote */
+        if (val[0] == '"' || val[0] == '\'') {
+                if (val[len-1] != val[0]) {
+                        log_debug("inconsistent quoting: '%s', skip\n", line);
+                        return -1;
+                }
+                val[len-1] = '\0';
+                val++;
+        }
+
+        /* handle device, renamed by external tool, returning new path */
+        if (streq(key, "DEVPATH")) {
+                char syspath[UTIL_PATH_SIZE];
+
+                log_debug("updating devpath from '%s' to '%s'\n",
+                          udev_device_get_devpath(dev), val);
+                util_strscpyl(syspath, sizeof(syspath), "/sys", val, NULL);
+                udev_device_set_syspath(dev, syspath);
+        } else {
+                struct udev_list_entry *entry;
+
+                entry = udev_device_add_property(dev, key, val);
+                /* store in db, skip private keys */
+                if (key[0] != '.')
+                        udev_list_entry_set_num(entry, true);
+        }
+        return 0;
+}
+
+static int import_file_into_properties(struct udev_device *dev, const char *filename)
+{
+        FILE *f;
+        char line[UTIL_LINE_SIZE];
+
+        f = fopen(filename, "re");
+        if (f == NULL)
+                return -1;
+        while (fgets(line, sizeof(line), f) != NULL)
+                import_property_from_string(dev, line);
+        fclose(f);
+        return 0;
+}
+
+static int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask)
+{
+        struct udev_device *dev = event->dev;
+        char **envp;
+        char result[UTIL_LINE_SIZE];
+        char *line;
+        int err;
+
+        envp = udev_device_get_properties_envp(dev);
+        err = udev_event_spawn(event, program, envp, sigmask, result, sizeof(result));
+        if (err < 0)
+                return err;
+
+        line = result;
+        while (line != NULL) {
+                char *pos;
+
+                pos = strchr(line, '\n');
+                if (pos != NULL) {
+                        pos[0] = '\0';
+                        pos = &pos[1];
+                }
+                import_property_from_string(dev, line);
+                line = pos;
+        }
+        return 0;
+}
+
+static int import_parent_into_properties(struct udev_device *dev, const char *filter)
+{
+        struct udev_device *dev_parent;
+        struct udev_list_entry *list_entry;
+
+        dev_parent = udev_device_get_parent(dev);
+        if (dev_parent == NULL)
+                return -1;
+
+        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev_parent)) {
+                const char *key = udev_list_entry_get_name(list_entry);
+                const char *val = udev_list_entry_get_value(list_entry);
+
+                if (fnmatch(filter, key, 0) == 0) {
+                        struct udev_list_entry *entry;
+
+                        entry = udev_device_add_property(dev, key, val);
+                        /* store in db, skip private keys */
+                        if (key[0] != '.')
+                                udev_list_entry_set_num(entry, true);
+                }
+        }
+        return 0;
+}
+
+#define WAIT_LOOP_PER_SECOND                50
+static int wait_for_file(struct udev_device *dev, const char *file, int timeout)
+{
+        char filepath[UTIL_PATH_SIZE];
+        char devicepath[UTIL_PATH_SIZE];
+        struct stat stats;
+        int loop = timeout * WAIT_LOOP_PER_SECOND;
+
+        /* a relative path is a device attribute */
+        devicepath[0] = '\0';
+        if (file[0] != '/') {
+                util_strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL);
+                util_strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL);
+                file = filepath;
+        }
+
+        while (--loop) {
+                const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND };
+
+                /* lookup file */
+                if (stat(file, &stats) == 0) {
+                        log_debug("file '%s' appeared after %i loops\n", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
+                        return 0;
+                }
+                /* make sure, the device did not disappear in the meantime */
+                if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) {
+                        log_debug("device disappeared while waiting for '%s'\n", file);
+                        return -2;
+                }
+                log_debug("wait for '%s' for %i mseconds\n", file, 1000 / WAIT_LOOP_PER_SECOND);
+                nanosleep(&duration, NULL);
+        }
+        log_debug("waiting for '%s' failed\n", file);
+        return -1;
+}
+
+static int attr_subst_subdir(char *attr, size_t len)
+{
+        bool found = false;
+
+        if (strstr(attr, "/*/")) {
+                char *pos;
+                char dirname[UTIL_PATH_SIZE];
+                const char *tail;
+                DIR *dir;
+
+                util_strscpy(dirname, sizeof(dirname), attr);
+                pos = strstr(dirname, "/*/");
+                if (pos == NULL)
+                        return -1;
+                pos[0] = '\0';
+                tail = &pos[2];
+                dir = opendir(dirname);
+                if (dir != NULL) {
+                        struct dirent *dent;
+
+                        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                                struct stat stats;
+
+                                if (dent->d_name[0] == '.')
+                                        continue;
+                                util_strscpyl(attr, len, dirname, "/", dent->d_name, tail, NULL);
+                                if (stat(attr, &stats) == 0) {
+                                        found = true;
+                                        break;
+                                }
+                        }
+                        closedir(dir);
+                }
+        }
+
+        return found;
+}
+
+static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value)
+{
+        char *linepos;
+        char *temp;
+
+        linepos = *line;
+        if (linepos == NULL || linepos[0] == '\0')
+                return -1;
+
+        /* skip whitespace */
+        while (isspace(linepos[0]) || linepos[0] == ',')
+                linepos++;
+
+        /* get the key */
+        if (linepos[0] == '\0')
+                return -1;
+        *key = linepos;
+
+        for (;;) {
+                linepos++;
+                if (linepos[0] == '\0')
+                        return -1;
+                if (isspace(linepos[0]))
+                        break;
+                if (linepos[0] == '=')
+                        break;
+                if ((linepos[0] == '+') || (linepos[0] == '!') || (linepos[0] == ':'))
+                        if (linepos[1] == '=')
+                                break;
+        }
+
+        /* remember end of key */
+        temp = linepos;
+
+        /* skip whitespace after key */
+        while (isspace(linepos[0]))
+                linepos++;
+        if (linepos[0] == '\0')
+                return -1;
+
+        /* get operation type */
+        if (linepos[0] == '=' && linepos[1] == '=') {
+                *op = OP_MATCH;
+                linepos += 2;
+        } else if (linepos[0] == '!' && linepos[1] == '=') {
+                *op = OP_NOMATCH;
+                linepos += 2;
+        } else if (linepos[0] == '+' && linepos[1] == '=') {
+                *op = OP_ADD;
+                linepos += 2;
+        } else if (linepos[0] == '=') {
+                *op = OP_ASSIGN;
+                linepos++;
+        } else if (linepos[0] == ':' && linepos[1] == '=') {
+                *op = OP_ASSIGN_FINAL;
+                linepos += 2;
+        } else
+                return -1;
+
+        /* terminate key */
+        temp[0] = '\0';
+
+        /* skip whitespace after operator */
+        while (isspace(linepos[0]))
+                linepos++;
+        if (linepos[0] == '\0')
+                return -1;
+
+        /* get the value */
+        if (linepos[0] == '"')
+                linepos++;
+        else
+                return -1;
+        *value = linepos;
+
+        /* terminate */
+        temp = strchr(linepos, '"');
+        if (!temp)
+                return -1;
+        temp[0] = '\0';
+        temp++;
+
+        /* move line to next key */
+        *line = temp;
+        return 0;
+}
+
+/* extract possible KEY{attr} */
+static const char *get_key_attribute(struct udev *udev, char *str)
+{
+        char *pos;
+        char *attr;
+
+        attr = strchr(str, '{');
+        if (attr != NULL) {
+                attr++;
+                pos = strchr(attr, '}');
+                if (pos == NULL) {
+                        log_error("missing closing brace for format\n");
+                        return NULL;
+                }
+                pos[0] = '\0';
+                return attr;
+        }
+        return NULL;
+}
+
+static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
+                        enum operation_type op,
+                        const char *value, const void *data)
+{
+        struct token *token = &rule_tmp->token[rule_tmp->token_cur];
+        const char *attr = NULL;
+
+        memset(token, 0x00, sizeof(struct token));
+
+        switch (type) {
+        case TK_M_ACTION:
+        case TK_M_DEVPATH:
+        case TK_M_KERNEL:
+        case TK_M_SUBSYSTEM:
+        case TK_M_DRIVER:
+        case TK_M_WAITFOR:
+        case TK_M_DEVLINK:
+        case TK_M_NAME:
+        case TK_M_KERNELS:
+        case TK_M_SUBSYSTEMS:
+        case TK_M_DRIVERS:
+        case TK_M_TAGS:
+        case TK_M_PROGRAM:
+        case TK_M_IMPORT_FILE:
+        case TK_M_IMPORT_PROG:
+        case TK_M_IMPORT_DB:
+        case TK_M_IMPORT_CMDLINE:
+        case TK_M_IMPORT_PARENT:
+        case TK_M_RESULT:
+        case TK_A_OWNER:
+        case TK_A_GROUP:
+        case TK_A_MODE:
+        case TK_A_DEVLINK:
+        case TK_A_NAME:
+        case TK_A_GOTO:
+        case TK_M_TAG:
+        case TK_A_TAG:
+                token->key.value_off = rules_add_string(rule_tmp->rules, value);
+                break;
+        case TK_M_IMPORT_BUILTIN:
+                token->key.value_off = rules_add_string(rule_tmp->rules, value);
+                token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
+                break;
+        case TK_M_ENV:
+        case TK_M_ATTR:
+        case TK_M_ATTRS:
+        case TK_A_ATTR:
+        case TK_A_ENV:
+                attr = data;
+                token->key.value_off = rules_add_string(rule_tmp->rules, value);
+                token->key.attr_off = rules_add_string(rule_tmp->rules, attr);
+                break;
+        case TK_M_TEST:
+                token->key.value_off = rules_add_string(rule_tmp->rules, value);
+                if (data != NULL)
+                        token->key.mode = *(mode_t *)data;
+                break;
+        case TK_A_STRING_ESCAPE_NONE:
+        case TK_A_STRING_ESCAPE_REPLACE:
+        case TK_A_DB_PERSIST:
+                break;
+        case TK_A_RUN_BUILTIN:
+        case TK_A_RUN_PROGRAM:
+                token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
+                token->key.value_off = rules_add_string(rule_tmp->rules, value);
+                break;
+        case TK_A_INOTIFY_WATCH:
+        case TK_A_DEVLINK_PRIO:
+                token->key.devlink_prio = *(int *)data;
+                break;
+        case TK_A_OWNER_ID:
+                token->key.uid = *(uid_t *)data;
+                break;
+        case TK_A_GROUP_ID:
+                token->key.gid = *(gid_t *)data;
+                break;
+        case TK_A_MODE_ID:
+                token->key.mode = *(mode_t *)data;
+                break;
+        case TK_A_STATIC_NODE:
+                token->key.value_off = rules_add_string(rule_tmp->rules, value);
+                break;
+        case TK_M_EVENT_TIMEOUT:
+                token->key.event_timeout = *(int *)data;
+                break;
+        case TK_RULE:
+        case TK_M_PARENTS_MIN:
+        case TK_M_PARENTS_MAX:
+        case TK_M_MAX:
+        case TK_END:
+        case TK_UNSET:
+                log_error("wrong type %u\n", type);
+                return -1;
+        }
+
+        if (value != NULL && type < TK_M_MAX) {
+                /* check if we need to split or call fnmatch() while matching rules */
+                enum string_glob_type glob;
+                int has_split;
+                int has_glob;
+
+                has_split = (strchr(value, '|') != NULL);
+                has_glob = (strchr(value, '*') != NULL || strchr(value, '?') != NULL || strchr(value, '[') != NULL);
+                if (has_split && has_glob) {
+                        glob = GL_SPLIT_GLOB;
+                } else if (has_split) {
+                        glob = GL_SPLIT;
+                } else if (has_glob) {
+                        if (streq(value, "?*"))
+                                glob = GL_SOMETHING;
+                        else
+                                glob = GL_GLOB;
+                } else {
+                        glob = GL_PLAIN;
+                }
+                token->key.glob = glob;
+        }
+
+        if (value != NULL && type > TK_M_MAX) {
+                /* check if assigned value has substitution chars */
+                if (value[0] == '[')
+                        token->key.subst = SB_SUBSYS;
+                else if (strchr(value, '%') != NULL || strchr(value, '$') != NULL)
+                        token->key.subst = SB_FORMAT;
+                else
+                        token->key.subst = SB_NONE;
+        }
+
+        if (attr != NULL) {
+                /* check if property/attribut name has substitution chars */
+                if (attr[0] == '[')
+                        token->key.attrsubst = SB_SUBSYS;
+                else if (strchr(attr, '%') != NULL || strchr(attr, '$') != NULL)
+                        token->key.attrsubst = SB_FORMAT;
+                else
+                        token->key.attrsubst = SB_NONE;
+        }
+
+        token->key.type = type;
+        token->key.op = op;
+        rule_tmp->token_cur++;
+        if (rule_tmp->token_cur >= ELEMENTSOF(rule_tmp->token)) {
+                log_error("temporary rule array too small\n");
+                return -1;
+        }
+        return 0;
+}
+
+static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp)
+{
+        unsigned int i;
+        unsigned int start = 0;
+        unsigned int end = rule_tmp->token_cur;
+
+        for (i = 0; i < rule_tmp->token_cur; i++) {
+                enum token_type next_val = TK_UNSET;
+                unsigned int next_idx = 0;
+                unsigned int j;
+
+                /* find smallest value */
+                for (j = start; j < end; j++) {
+                        if (rule_tmp->token[j].type == TK_UNSET)
+                                continue;
+                        if (next_val == TK_UNSET || rule_tmp->token[j].type < next_val) {
+                                next_val = rule_tmp->token[j].type;
+                                next_idx = j;
+                        }
+                }
+
+                /* add token and mark done */
+                if (add_token(rules, &rule_tmp->token[next_idx]) != 0)
+                        return -1;
+                rule_tmp->token[next_idx].type = TK_UNSET;
+
+                /* shrink range */
+                if (next_idx == start)
+                        start++;
+                if (next_idx+1 == end)
+                        end--;
+        }
+        return 0;
+}
+
+static int add_rule(struct udev_rules *rules, char *line,
+                    const char *filename, unsigned int filename_off, unsigned int lineno)
+{
+        char *linepos;
+        const char *attr;
+        struct rule_tmp rule_tmp;
+
+        memset(&rule_tmp, 0x00, sizeof(struct rule_tmp));
+        rule_tmp.rules = rules;
+        rule_tmp.rule.type = TK_RULE;
+        /* the offset in the rule is limited to unsigned short */
+        if (filename_off < USHRT_MAX)
+                rule_tmp.rule.rule.filename_off = filename_off;
+        rule_tmp.rule.rule.filename_line = lineno;
+
+        linepos = line;
+        for (;;) {
+                char *key;
+                char *value;
+                enum operation_type op;
+
+                if (get_key(rules->udev, &linepos, &key, &op, &value) != 0)
+                        break;
+
+                if (streq(key, "ACTION")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid ACTION operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_ACTION, op, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "DEVPATH")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid DEVPATH operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_DEVPATH, op, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "KERNEL")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid KERNEL operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_KERNEL, op, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "SUBSYSTEM")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid SUBSYSTEM operation\n");
+                                goto invalid;
+                        }
+                        /* bus, class, subsystem events should all be the same */
+                        if (streq(value, "subsystem") ||
+                            streq(value, "bus") ||
+                            streq(value, "class")) {
+                                if (streq(value, "bus") || streq(value, "class"))
+                                        log_error("'%s' must be specified as 'subsystem' \n"
+                                            "please fix it in %s:%u", value, filename, lineno);
+                                rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL);
+                        } else
+                                rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "DRIVER")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid DRIVER operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL);
+                        continue;
+                }
+
+                if (startswith(key, "ATTR{")) {
+                        attr = get_key_attribute(rules->udev, key + sizeof("ATTR")-1);
+                        if (attr == NULL) {
+                                log_error("error parsing ATTR attribute\n");
+                                goto invalid;
+                        }
+                        if (op < OP_MATCH_MAX) {
+                                rule_add_key(&rule_tmp, TK_M_ATTR, op, value, attr);
+                        } else {
+                                rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr);
+                        }
+                        continue;
+                }
+
+                if (streq(key, "KERNELS")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid KERNELS operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "SUBSYSTEMS")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid SUBSYSTEMS operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "DRIVERS")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid DRIVERS operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_DRIVERS, op, value, NULL);
+                        continue;
+                }
+
+                if (startswith(key, "ATTRS{")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid ATTRS operation\n");
+                                goto invalid;
+                        }
+                        attr = get_key_attribute(rules->udev, key + sizeof("ATTRS")-1);
+                        if (attr == NULL) {
+                                log_error("error parsing ATTRS attribute\n");
+                                goto invalid;
+                        }
+                        if (startswith(attr, "device/"))
+                                log_error("the 'device' link may not be available in a future kernel, "
+                                    "please fix it in %s:%u", filename, lineno);
+                        else if (strstr(attr, "../") != NULL)
+                                log_error("do not reference parent sysfs directories directly, "
+                                    "it may break with a future kernel, please fix it in %s:%u", filename, lineno);
+                        rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr);
+                        continue;
+                }
+
+                if (streq(key, "TAGS")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid TAGS operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL);
+                        continue;
+                }
+
+                if (startswith(key, "ENV{")) {
+                        attr = get_key_attribute(rules->udev, key + sizeof("ENV")-1);
+                        if (attr == NULL) {
+                                log_error("error parsing ENV attribute\n");
+                                goto invalid;
+                        }
+                        if (op < OP_MATCH_MAX) {
+                                if (rule_add_key(&rule_tmp, TK_M_ENV, op, value, attr) != 0)
+                                        goto invalid;
+                        } else {
+                                static const char *blacklist[] = {
+                                        "ACTION",
+                                        "SUBSYSTEM",
+                                        "DEVTYPE",
+                                        "MAJOR",
+                                        "MINOR",
+                                        "DRIVER",
+                                        "IFINDEX",
+                                        "DEVNAME",
+                                        "DEVLINKS",
+                                        "DEVPATH",
+                                        "TAGS",
+                                };
+                                unsigned int i;
+
+                                for (i = 0; i < ELEMENTSOF(blacklist); i++) {
+                                        if (!streq(attr, blacklist[i]))
+                                                continue;
+                                        log_error("invalid ENV attribute, '%s' can not be set %s:%u\n", attr, filename, lineno);
+                                        goto invalid;
+                                }
+                                if (rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr) != 0)
+                                        goto invalid;
+                        }
+                        continue;
+                }
+
+                if (streq(key, "TAG")) {
+                        if (op < OP_MATCH_MAX)
+                                rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL);
+                        else
+                                rule_add_key(&rule_tmp, TK_A_TAG, op, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "PROGRAM")) {
+                        rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "RESULT")) {
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid RESULT operation\n");
+                                goto invalid;
+                        }
+                        rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL);
+                        continue;
+                }
+
+                if (startswith(key, "IMPORT")) {
+                        attr = get_key_attribute(rules->udev, key + sizeof("IMPORT")-1);
+                        if (attr == NULL) {
+                                log_error("IMPORT{} type missing, ignoring IMPORT %s:%u\n", filename, lineno);
+                                continue;
+                        }
+                        if (streq(attr, "program")) {
+                                /* find known built-in command */
+                                if (value[0] != '/') {
+                                        enum udev_builtin_cmd cmd;
+
+                                        cmd = udev_builtin_lookup(value);
+                                        if (cmd < UDEV_BUILTIN_MAX) {
+                                                log_debug("IMPORT found builtin '%s', replacing %s:%u\n",
+                                                          value, filename, lineno);
+                                                rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
+                                                continue;
+                                        }
+                                }
+                                rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL);
+                        } else if (streq(attr, "builtin")) {
+                                enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
+
+                                if (cmd < UDEV_BUILTIN_MAX)
+                                        rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
+                                else
+                                        log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
+                        } else if (streq(attr, "file")) {
+                                rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL);
+                        } else if (streq(attr, "db")) {
+                                rule_add_key(&rule_tmp, TK_M_IMPORT_DB, op, value, NULL);
+                        } else if (streq(attr, "cmdline")) {
+                                rule_add_key(&rule_tmp, TK_M_IMPORT_CMDLINE, op, value, NULL);
+                        } else if (streq(attr, "parent")) {
+                                rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL);
+                        } else
+                                log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u\n", filename, lineno);
+                        continue;
+                }
+
+                if (startswith(key, "TEST")) {
+                        mode_t mode = 0;
+
+                        if (op > OP_MATCH_MAX) {
+                                log_error("invalid TEST operation\n");
+                                goto invalid;
+                        }
+                        attr = get_key_attribute(rules->udev, key + sizeof("TEST")-1);
+                        if (attr != NULL) {
+                                mode = strtol(attr, NULL, 8);
+                                rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode);
+                        } else {
+                                rule_add_key(&rule_tmp, TK_M_TEST, op, value, NULL);
+                        }
+                        continue;
+                }
+
+                if (startswith(key, "RUN")) {
+                        attr = get_key_attribute(rules->udev, key + sizeof("RUN")-1);
+                        if (attr == NULL)
+                                attr = "program";
+
+                        if (streq(attr, "builtin")) {
+                                enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
+
+                                if (cmd < UDEV_BUILTIN_MAX)
+                                        rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd);
+                                else
+                                        log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
+                        } else if (streq(attr, "program")) {
+                                enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX;
+
+                                rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd);
+                        } else {
+                                log_error("RUN{} unknown type, ignoring RUN %s:%u\n", filename, lineno);
+                        }
+
+                        continue;
+                }
+
+                if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) {
+                        rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL);
+                        continue;
+                }
+
+                if (streq(key, "LABEL")) {
+                        rule_tmp.rule.rule.label_off = rules_add_string(rules, value);
+                        continue;
+                }
+
+                if (streq(key, "GOTO")) {
+                        rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL);
+                        continue;
+                }
+
+                if (startswith(key, "NAME")) {
+                        if (op < OP_MATCH_MAX) {
+                                rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL);
+                        } else {
+                                if (streq(value, "%k")) {
+                                        log_error("NAME=\"%%k\" is ignored, because it breaks kernel supplied names, "
+                                            "please remove it from %s:%u\n", filename, lineno);
+                                        continue;
+                                }
+                                if (value[0] == '\0') {
+                                        log_debug("NAME=\"\" is ignored, because udev will not delete any device nodes, "
+                                                  "please remove it from %s:%u\n", filename, lineno);
+                                        continue;
+                                }
+                                rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL);
+                        }
+                        rule_tmp.rule.rule.can_set_name = true;
+                        continue;
+                }
+
+                if (streq(key, "SYMLINK")) {
+                        if (op < OP_MATCH_MAX)
+                                rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL);
+                        else
+                                rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL);
+                        rule_tmp.rule.rule.can_set_name = true;
+                        continue;
+                }
+
+                if (streq(key, "OWNER")) {
+                        uid_t uid;
+                        char *endptr;
+
+                        uid = strtoul(value, &endptr, 10);
+                        if (endptr[0] == '\0') {
+                                rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
+                        } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
+                                uid = add_uid(rules, value);
+                                rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
+                        } else if (rules->resolve_names >= 0) {
+                                rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL);
+                        }
+                        rule_tmp.rule.rule.can_set_name = true;
+                        continue;
+                }
+
+                if (streq(key, "GROUP")) {
+                        gid_t gid;
+                        char *endptr;
+
+                        gid = strtoul(value, &endptr, 10);
+                        if (endptr[0] == '\0') {
+                                rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
+                        } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
+                                gid = add_gid(rules, value);
+                                rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
+                        } else if (rules->resolve_names >= 0) {
+                                rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL);
+                        }
+                        rule_tmp.rule.rule.can_set_name = true;
+                        continue;
+                }
+
+                if (streq(key, "MODE")) {
+                        mode_t mode;
+                        char *endptr;
+
+                        mode = strtol(value, &endptr, 8);
+                        if (endptr[0] == '\0')
+                                rule_add_key(&rule_tmp, TK_A_MODE_ID, op, NULL, &mode);
+                        else
+                                rule_add_key(&rule_tmp, TK_A_MODE, op, value, NULL);
+                        rule_tmp.rule.rule.can_set_name = true;
+                        continue;
+                }
+
+                if (streq(key, "OPTIONS")) {
+                        const char *pos;
+
+                        pos = strstr(value, "link_priority=");
+                        if (pos != NULL) {
+                                int prio = atoi(&pos[strlen("link_priority=")]);
+
+                                rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
+                        }
+
+                        pos = strstr(value, "event_timeout=");
+                        if (pos != NULL) {
+                                int tout = atoi(&pos[strlen("event_timeout=")]);
+
+                                rule_add_key(&rule_tmp, TK_M_EVENT_TIMEOUT, op, NULL, &tout);
+                        }
+
+                        pos = strstr(value, "string_escape=");
+                        if (pos != NULL) {
+                                pos = &pos[strlen("string_escape=")];
+                                if (startswith(pos, "none"))
+                                        rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL);
+                                else if (startswith(pos, "replace"))
+                                        rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_REPLACE, op, NULL, NULL);
+                        }
+
+                        pos = strstr(value, "db_persist");
+                        if (pos != NULL)
+                                rule_add_key(&rule_tmp, TK_A_DB_PERSIST, op, NULL, NULL);
+
+                        pos = strstr(value, "nowatch");
+                        if (pos != NULL) {
+                                const int off = 0;
+
+                                rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &off);
+                        } else {
+                                pos = strstr(value, "watch");
+                                if (pos != NULL) {
+                                        const int on = 1;
+
+                                        rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &on);
+                                }
+                        }
+
+                        pos = strstr(value, "static_node=");
+                        if (pos != NULL) {
+                                rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, &pos[strlen("static_node=")], NULL);
+                                rule_tmp.rule.rule.has_static_node = true;
+                        }
+
+                        continue;
+                }
+
+                log_error("unknown key '%s' in %s:%u\n", key, filename, lineno);
+                goto invalid;
+        }
+
+        /* add rule token */
+        rule_tmp.rule.rule.token_count = 1 + rule_tmp.token_cur;
+        if (add_token(rules, &rule_tmp.rule) != 0)
+                goto invalid;
+
+        /* add tokens to list, sorted by type */
+        if (sort_token(rules, &rule_tmp) != 0)
+                goto invalid;
+
+        return 0;
+invalid:
+        log_error("invalid rule '%s:%u'\n", filename, lineno);
+        return -1;
+}
+
+static int parse_file(struct udev_rules *rules, const char *filename)
+{
+        FILE *f;
+        unsigned int first_token;
+        unsigned int filename_off;
+        char line[UTIL_LINE_SIZE];
+        int line_nr = 0;
+        unsigned int i;
+
+        if (null_or_empty_path(filename)) {
+                log_debug("skip empty file: %s\n", filename);
+                return 0;
+        }
+        log_debug("read rules file: %s\n", filename);
+
+        f = fopen(filename, "re");
+        if (f == NULL)
+                return -1;
+
+        first_token = rules->token_cur;
+        filename_off = rules_add_string(rules, filename);
+
+        while (fgets(line, sizeof(line), f) != NULL) {
+                char *key;
+                size_t len;
+
+                /* skip whitespace */
+                line_nr++;
+                key = line;
+                while (isspace(key[0]))
+                        key++;
+
+                /* comment */
+                if (key[0] == '#')
+                        continue;
+
+                len = strlen(line);
+                if (len < 3)
+                        continue;
+
+                /* continue reading if backslash+newline is found */
+                while (line[len-2] == '\\') {
+                        if (fgets(&line[len-2], (sizeof(line)-len)+2, f) == NULL)
+                                break;
+                        if (strlen(&line[len-2]) < 2)
+                                break;
+                        line_nr++;
+                        len = strlen(line);
+                }
+
+                if (len+1 >= sizeof(line)) {
+                        log_error("line too long '%s':%u, ignored\n", filename, line_nr);
+                        continue;
+                }
+                add_rule(rules, key, filename, filename_off, line_nr);
+        }
+        fclose(f);
+
+        /* link GOTOs to LABEL rules in this file to be able to fast-forward */
+        for (i = first_token+1; i < rules->token_cur; i++) {
+                if (rules->tokens[i].type == TK_A_GOTO) {
+                        char *label = rules_str(rules, rules->tokens[i].key.value_off);
+                        unsigned int j;
+
+                        for (j = i+1; j < rules->token_cur; j++) {
+                                if (rules->tokens[j].type != TK_RULE)
+                                        continue;
+                                if (rules->tokens[j].rule.label_off == 0)
+                                        continue;
+                                if (!streq(label, rules_str(rules, rules->tokens[j].rule.label_off)))
+                                        continue;
+                                rules->tokens[i].key.rule_goto = j;
+                                break;
+                        }
+                        if (rules->tokens[i].key.rule_goto == 0)
+                                log_error("GOTO '%s' has no matching label in: '%s'\n", label, filename);
+                }
+        }
+        return 0;
+}
+
+struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
+{
+        struct udev_rules *rules;
+        struct udev_list file_list;
+        struct token end_token;
+        char **files, **f;
+        int r;
+
+        rules = calloc(1, sizeof(struct udev_rules));
+        if (rules == NULL)
+                return NULL;
+        rules->udev = udev;
+        rules->resolve_names = resolve_names;
+        udev_list_init(udev, &file_list, true);
+
+        /* init token array and string buffer */
+        rules->tokens = malloc(PREALLOC_TOKEN * sizeof(struct token));
+        if (rules->tokens == NULL)
+                return udev_rules_unref(rules);
+        rules->token_max = PREALLOC_TOKEN;
+
+        rules->strbuf = strbuf_new();
+        if (!rules->strbuf)
+                return udev_rules_unref(rules);
+
+        rules->dirs = strv_new("/etc/udev/rules.d",
+                               "/run/udev/rules.d",
+                               UDEVLIBEXECDIR "/rules.d",
+                               NULL);
+        if (!rules->dirs) {
+                log_error("failed to build config directory array");
+                return udev_rules_unref(rules);
+        }
+        if (!path_strv_canonicalize(rules->dirs)) {
+                log_error("failed to canonicalize config directories\n");
+                return udev_rules_unref(rules);
+        }
+        strv_uniq(rules->dirs);
+
+        rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(long long));
+        if(!rules->dirs_ts_usec)
+                return udev_rules_unref(rules);
+        udev_rules_check_timestamp(rules);
+
+        r = conf_files_list_strv(&files, ".rules", (const char **)rules->dirs);
+        if (r < 0) {
+                log_error("failed to enumerate rules files: %s\n", strerror(-r));
+                return udev_rules_unref(rules);
+        }
+
+        /*
+         * The offset value in the rules strct is limited; add all
+         * rules file names to the beginning of the string buffer.
+         */
+        STRV_FOREACH(f, files)
+                rules_add_string(rules, *f);
+
+        STRV_FOREACH(f, files)
+                parse_file(rules, *f);
+
+        strv_free(files);
+
+        memset(&end_token, 0x00, sizeof(struct token));
+        end_token.type = TK_END;
+        add_token(rules, &end_token);
+        log_debug("rules contain %zu bytes tokens (%u * %zu bytes), %zu bytes strings\n",
+                  rules->token_max * sizeof(struct token), rules->token_max, sizeof(struct token), rules->strbuf->len);
+
+        /* cleanup temporary strbuf data */
+        log_debug("%zu strings (%zu bytes), %zu de-duplicated (%zu bytes), %zu trie nodes used\n",
+                  rules->strbuf->in_count, rules->strbuf->in_len,
+                  rules->strbuf->dedup_count, rules->strbuf->dedup_len, rules->strbuf->nodes_count);
+        strbuf_complete(rules->strbuf);
+
+        /* cleanup uid/gid cache */
+        free(rules->uids);
+        rules->uids = NULL;
+        rules->uids_cur = 0;
+        rules->uids_max = 0;
+        free(rules->gids);
+        rules->gids = NULL;
+        rules->gids_cur = 0;
+        rules->gids_max = 0;
+
+        dump_rules(rules);
+        return rules;
+}
+
+struct udev_rules *udev_rules_unref(struct udev_rules *rules)
+{
+        if (rules == NULL)
+                return NULL;
+        free(rules->tokens);
+        strbuf_cleanup(rules->strbuf);
+        free(rules->uids);
+        free(rules->gids);
+        strv_free(rules->dirs);
+        free(rules->dirs_ts_usec);
+        free(rules);
+        return NULL;
+}
+
+bool udev_rules_check_timestamp(struct udev_rules *rules)
+{
+        unsigned int i;
+        bool changed = false;
+
+        if (rules == NULL)
+                goto out;
+
+        for (i = 0; rules->dirs[i]; i++) {
+                struct stat stats;
+
+                if (stat(rules->dirs[i], &stats) < 0)
+                        continue;
+
+                if (rules->dirs_ts_usec[i] == timespec_load(&stats.st_mtim))
+                        continue;
+
+                /* first check */
+                if (rules->dirs_ts_usec[i] != 0) {
+                        log_debug("reload - timestamp of '%s' changed\n", rules->dirs[i]);
+                        changed = true;
+                }
+
+                /* update timestamp */
+                rules->dirs_ts_usec[i] = timespec_load(&stats.st_mtim);
+        }
+out:
+        return changed;
+}
+
+static int match_key(struct udev_rules *rules, struct token *token, const char *val)
+{
+        char *key_value = rules_str(rules, token->key.value_off);
+        char *pos;
+        bool match = false;
+
+        if (val == NULL)
+                val = "";
+
+        switch (token->key.glob) {
+        case GL_PLAIN:
+                match = (streq(key_value, val));
+                break;
+        case GL_GLOB:
+                match = (fnmatch(key_value, val, 0) == 0);
+                break;
+        case GL_SPLIT:
+                {
+                        const char *s;
+                        size_t len;
+
+                        s = rules_str(rules, token->key.value_off);
+                        len = strlen(val);
+                        for (;;) {
+                                const char *next;
+
+                                next = strchr(s, '|');
+                                if (next != NULL) {
+                                        size_t matchlen = (size_t)(next - s);
+
+                                        match = (matchlen == len && strncmp(s, val, matchlen) == 0);
+                                        if (match)
+                                                break;
+                                } else {
+                                        match = (streq(s, val));
+                                        break;
+                                }
+                                s = &next[1];
+                        }
+                        break;
+                }
+        case GL_SPLIT_GLOB:
+                {
+                        char value[UTIL_PATH_SIZE];
+
+                        util_strscpy(value, sizeof(value), rules_str(rules, token->key.value_off));
+                        key_value = value;
+                        while (key_value != NULL) {
+                                pos = strchr(key_value, '|');
+                                if (pos != NULL) {
+                                        pos[0] = '\0';
+                                        pos = &pos[1];
+                                }
+                                match = (fnmatch(key_value, val, 0) == 0);
+                                if (match)
+                                        break;
+                                key_value = pos;
+                        }
+                        break;
+                }
+        case GL_SOMETHING:
+                match = (val[0] != '\0');
+                break;
+        case GL_UNSET:
+                return -1;
+        }
+
+        if (match && (token->key.op == OP_MATCH))
+                return 0;
+        if (!match && (token->key.op == OP_NOMATCH))
+                return 0;
+        return -1;
+}
+
+static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct udev_event *event, struct token *cur)
+{
+        const char *name;
+        char nbuf[UTIL_NAME_SIZE];
+        const char *value;
+        char vbuf[UTIL_NAME_SIZE];
+        size_t len;
+
+        name = rules_str(rules, cur->key.attr_off);
+        switch (cur->key.attrsubst) {
+        case SB_FORMAT:
+                udev_event_apply_format(event, name, nbuf, sizeof(nbuf));
+                name = nbuf;
+                /* fall through */
+        case SB_NONE:
+                value = udev_device_get_sysattr_value(dev, name);
+                if (value == NULL)
+                        return -1;
+                break;
+        case SB_SUBSYS:
+                if (util_resolve_subsys_kernel(event->udev, name, vbuf, sizeof(vbuf), 1) != 0)
+                        return -1;
+                value = vbuf;
+                break;
+        default:
+                return -1;
+        }
+
+        /* remove trailing whitespace, if not asked to match for it */
+        len = strlen(value);
+        if (len > 0 && isspace(value[len-1])) {
+                const char *key_value;
+                size_t klen;
+
+                key_value = rules_str(rules, cur->key.value_off);
+                klen = strlen(key_value);
+                if (klen > 0 && !isspace(key_value[klen-1])) {
+                        if (value != vbuf) {
+                                util_strscpy(vbuf, sizeof(vbuf), value);
+                                value = vbuf;
+                        }
+                        while (len > 0 && isspace(vbuf[--len]))
+                                vbuf[len] = '\0';
+                }
+        }
+
+        return match_key(rules, cur, value);
+}
+
+enum escape_type {
+        ESCAPE_UNSET,
+        ESCAPE_NONE,
+        ESCAPE_REPLACE,
+};
+
+int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask)
+{
+        struct token *cur;
+        struct token *rule;
+        enum escape_type esc = ESCAPE_UNSET;
+        bool can_set_name;
+
+        if (rules->tokens == NULL)
+                return -1;
+
+        can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) &&
+                        (major(udev_device_get_devnum(event->dev)) > 0 ||
+                         udev_device_get_ifindex(event->dev) > 0));
+
+        /* loop through token list, match, run actions or forward to next rule */
+        cur = &rules->tokens[0];
+        rule = cur;
+        for (;;) {
+                dump_token(rules, cur);
+                switch (cur->type) {
+                case TK_RULE:
+                        /* current rule */
+                        rule = cur;
+                        /* possibly skip rules which want to set NAME, SYMLINK, OWNER, GROUP, MODE */
+                        if (!can_set_name && rule->rule.can_set_name)
+                                goto nomatch;
+                        esc = ESCAPE_UNSET;
+                        break;
+                case TK_M_ACTION:
+                        if (match_key(rules, cur, udev_device_get_action(event->dev)) != 0)
+                                goto nomatch;
+                        break;
+                case TK_M_DEVPATH:
+                        if (match_key(rules, cur, udev_device_get_devpath(event->dev)) != 0)
+                                goto nomatch;
+                        break;
+                case TK_M_KERNEL:
+                        if (match_key(rules, cur, udev_device_get_sysname(event->dev)) != 0)
+                                goto nomatch;
+                        break;
+                case TK_M_DEVLINK: {
+                        struct udev_list_entry *list_entry;
+                        bool match = false;
+
+                        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(event->dev)) {
+                                const char *devlink;
+
+                                devlink =  udev_list_entry_get_name(list_entry) + strlen("/dev/");
+                                if (match_key(rules, cur, devlink) == 0) {
+                                        match = true;
+                                        break;
+                                }
+                        }
+                        if (!match)
+                                goto nomatch;
+                        break;
+                }
+                case TK_M_NAME:
+                        if (match_key(rules, cur, event->name) != 0)
+                                goto nomatch;
+                        break;
+                case TK_M_ENV: {
+                        const char *key_name = rules_str(rules, cur->key.attr_off);
+                        const char *value;
+
+                        value = udev_device_get_property_value(event->dev, key_name);
+                        if (value == NULL)
+                                value = "";
+                        if (match_key(rules, cur, value))
+                                goto nomatch;
+                        break;
+                }
+                case TK_M_TAG: {
+                        struct udev_list_entry *list_entry;
+                        bool match = false;
+
+                        udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(event->dev)) {
+                                if (streq(rules_str(rules, cur->key.value_off), udev_list_entry_get_name(list_entry))) {
+                                        match = true;
+                                        break;
+                                }
+                        }
+                        if (!match && (cur->key.op != OP_NOMATCH))
+                                goto nomatch;
+                        break;
+                }
+                case TK_M_SUBSYSTEM:
+                        if (match_key(rules, cur, udev_device_get_subsystem(event->dev)) != 0)
+                                goto nomatch;
+                        break;
+                case TK_M_DRIVER:
+                        if (match_key(rules, cur, udev_device_get_driver(event->dev)) != 0)
+                                goto nomatch;
+                        break;
+                case TK_M_WAITFOR: {
+                        char filename[UTIL_PATH_SIZE];
+                        int found;
+
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename));
+                        found = (wait_for_file(event->dev, filename, 10) == 0);
+                        if (!found && (cur->key.op != OP_NOMATCH))
+                                goto nomatch;
+                        break;
+                }
+                case TK_M_ATTR:
+                        if (match_attr(rules, event->dev, event, cur) != 0)
+                                goto nomatch;
+                        break;
+                case TK_M_KERNELS:
+                case TK_M_SUBSYSTEMS:
+                case TK_M_DRIVERS:
+                case TK_M_ATTRS:
+                case TK_M_TAGS: {
+                        struct token *next;
+
+                        /* get whole sequence of parent matches */
+                        next = cur;
+                        while (next->type > TK_M_PARENTS_MIN && next->type < TK_M_PARENTS_MAX)
+                                next++;
+
+                        /* loop over parents */
+                        event->dev_parent = event->dev;
+                        for (;;) {
+                                struct token *key;
+
+                                /* loop over sequence of parent match keys */
+                                for (key = cur; key < next; key++ ) {
+                                        dump_token(rules, key);
+                                        switch(key->type) {
+                                        case TK_M_KERNELS:
+                                                if (match_key(rules, key, udev_device_get_sysname(event->dev_parent)) != 0)
+                                                        goto try_parent;
+                                                break;
+                                        case TK_M_SUBSYSTEMS:
+                                                if (match_key(rules, key, udev_device_get_subsystem(event->dev_parent)) != 0)
+                                                        goto try_parent;
+                                                break;
+                                        case TK_M_DRIVERS:
+                                                if (match_key(rules, key, udev_device_get_driver(event->dev_parent)) != 0)
+                                                        goto try_parent;
+                                                break;
+                                        case TK_M_ATTRS:
+                                                if (match_attr(rules, event->dev_parent, event, key) != 0)
+                                                        goto try_parent;
+                                                break;
+                                        case TK_M_TAGS: {
+                                                bool match = udev_device_has_tag(event->dev_parent, rules_str(rules, cur->key.value_off));
+
+                                                if (match && key->key.op == OP_NOMATCH)
+                                                        goto try_parent;
+                                                if (!match && key->key.op == OP_MATCH)
+                                                        goto try_parent;
+                                                break;
+                                        }
+                                        default:
+                                                goto nomatch;
+                                        }
+                                }
+                                break;
+
+                        try_parent:
+                                event->dev_parent = udev_device_get_parent(event->dev_parent);
+                                if (event->dev_parent == NULL)
+                                        goto nomatch;
+                        }
+                        /* move behind our sequence of parent match keys */
+                        cur = next;
+                        continue;
+                }
+                case TK_M_TEST: {
+                        char filename[UTIL_PATH_SIZE];
+                        struct stat statbuf;
+                        int match;
+
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename));
+                        if (util_resolve_subsys_kernel(event->udev, filename, filename, sizeof(filename), 0) != 0) {
+                                if (filename[0] != '/') {
+                                        char tmp[UTIL_PATH_SIZE];
+
+                                        util_strscpy(tmp, sizeof(tmp), filename);
+                                        util_strscpyl(filename, sizeof(filename),
+                                                      udev_device_get_syspath(event->dev), "/", tmp, NULL);
+                                }
+                        }
+                        attr_subst_subdir(filename, sizeof(filename));
+
+                        match = (stat(filename, &statbuf) == 0);
+                        if (match && cur->key.mode > 0)
+                                match = ((statbuf.st_mode & cur->key.mode) > 0);
+                        if (match && cur->key.op == OP_NOMATCH)
+                                goto nomatch;
+                        if (!match && cur->key.op == OP_MATCH)
+                                goto nomatch;
+                        break;
+                }
+                case TK_M_EVENT_TIMEOUT:
+                        log_debug("OPTIONS event_timeout=%u\n", cur->key.event_timeout);
+                        event->timeout_usec = cur->key.event_timeout * 1000 * 1000;
+                        break;
+                case TK_M_PROGRAM: {
+                        char program[UTIL_PATH_SIZE];
+                        char **envp;
+                        char result[UTIL_PATH_SIZE];
+
+                        free(event->program_result);
+                        event->program_result = NULL;
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program));
+                        envp = udev_device_get_properties_envp(event->dev);
+                        log_debug("PROGRAM '%s' %s:%u\n",
+                                  program,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+
+                        if (udev_event_spawn(event, program, envp, sigmask, result, sizeof(result)) < 0) {
+                                if (cur->key.op != OP_NOMATCH)
+                                        goto nomatch;
+                        } else {
+                                int count;
+
+                                util_remove_trailing_chars(result, '\n');
+                                if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) {
+                                        count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT);
+                                        if (count > 0)
+                                                log_debug("%i character(s) replaced\n" , count);
+                                }
+                                event->program_result = strdup(result);
+                                if (cur->key.op == OP_NOMATCH)
+                                        goto nomatch;
+                        }
+                        break;
+                }
+                case TK_M_IMPORT_FILE: {
+                        char import[UTIL_PATH_SIZE];
+
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
+                        if (import_file_into_properties(event->dev, import) != 0)
+                                if (cur->key.op != OP_NOMATCH)
+                                        goto nomatch;
+                        break;
+                }
+                case TK_M_IMPORT_PROG: {
+                        char import[UTIL_PATH_SIZE];
+
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
+                        log_debug("IMPORT '%s' %s:%u\n",
+                                  import,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+
+                        if (import_program_into_properties(event, import, sigmask) != 0)
+                                if (cur->key.op != OP_NOMATCH)
+                                        goto nomatch;
+                        break;
+                }
+                case TK_M_IMPORT_BUILTIN: {
+                        char command[UTIL_PATH_SIZE];
+
+                        if (udev_builtin_run_once(cur->key.builtin_cmd)) {
+                                /* check if we ran already */
+                                if (event->builtin_run & (1 << cur->key.builtin_cmd)) {
+                                        log_debug("IMPORT builtin skip '%s' %s:%u\n",
+                                                  udev_builtin_name(cur->key.builtin_cmd),
+                                                  rules_str(rules, rule->rule.filename_off),
+                                                  rule->rule.filename_line);
+                                        /* return the result from earlier run */
+                                        if (event->builtin_ret & (1 << cur->key.builtin_cmd))
+                                        if (cur->key.op != OP_NOMATCH)
+                                                        goto nomatch;
+                                        break;
+                                }
+                                /* mark as ran */
+                                event->builtin_run |= (1 << cur->key.builtin_cmd);
+                        }
+
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command));
+                        log_debug("IMPORT builtin '%s' %s:%u\n",
+                                  udev_builtin_name(cur->key.builtin_cmd),
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+
+                        if (udev_builtin_run(event->dev, cur->key.builtin_cmd, command, false) != 0) {
+                                /* remember failure */
+                                log_debug("IMPORT builtin '%s' returned non-zero\n",
+                                          udev_builtin_name(cur->key.builtin_cmd));
+                                event->builtin_ret |= (1 << cur->key.builtin_cmd);
+                                if (cur->key.op != OP_NOMATCH)
+                                        goto nomatch;
+                        }
+                        break;
+                }
+                case TK_M_IMPORT_DB: {
+                        const char *key = rules_str(rules, cur->key.value_off);
+                        const char *value;
+
+                        value = udev_device_get_property_value(event->dev_db, key);
+                        if (value != NULL) {
+                                struct udev_list_entry *entry;
+
+                                entry = udev_device_add_property(event->dev, key, value);
+                                udev_list_entry_set_num(entry, true);
+                        } else {
+                                if (cur->key.op != OP_NOMATCH)
+                                        goto nomatch;
+                        }
+                        break;
+                }
+                case TK_M_IMPORT_CMDLINE: {
+                        FILE *f;
+                        bool imported = false;
+
+                        f = fopen("/proc/cmdline", "re");
+                        if (f != NULL) {
+                                char cmdline[4096];
+
+                                if (fgets(cmdline, sizeof(cmdline), f) != NULL) {
+                                        const char *key = rules_str(rules, cur->key.value_off);
+                                        char *pos;
+
+                                        pos = strstr(cmdline, key);
+                                        if (pos != NULL) {
+                                                struct udev_list_entry *entry;
+
+                                                pos += strlen(key);
+                                                if (pos[0] == '\0' || isspace(pos[0])) {
+                                                        /* we import simple flags as 'FLAG=1' */
+                                                        entry = udev_device_add_property(event->dev, key, "1");
+                                                        udev_list_entry_set_num(entry, true);
+                                                        imported = true;
+                                                } else if (pos[0] == '=') {
+                                                        const char *value;
+
+                                                        pos++;
+                                                        value = pos;
+                                                        while (pos[0] != '\0' && !isspace(pos[0]))
+                                                                pos++;
+                                                        pos[0] = '\0';
+                                                        entry = udev_device_add_property(event->dev, key, value);
+                                                        udev_list_entry_set_num(entry, true);
+                                                        imported = true;
+                                                }
+                                        }
+                                }
+                                fclose(f);
+                        }
+                        if (!imported && cur->key.op != OP_NOMATCH)
+                                goto nomatch;
+                        break;
+                }
+                case TK_M_IMPORT_PARENT: {
+                        char import[UTIL_PATH_SIZE];
+
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
+                        if (import_parent_into_properties(event->dev, import) != 0)
+                                if (cur->key.op != OP_NOMATCH)
+                                        goto nomatch;
+                        break;
+                }
+                case TK_M_RESULT:
+                        if (match_key(rules, cur, event->program_result) != 0)
+                                goto nomatch;
+                        break;
+                case TK_A_STRING_ESCAPE_NONE:
+                        esc = ESCAPE_NONE;
+                        break;
+                case TK_A_STRING_ESCAPE_REPLACE:
+                        esc = ESCAPE_REPLACE;
+                        break;
+                case TK_A_DB_PERSIST:
+                        udev_device_set_db_persist(event->dev);
+                        break;
+                case TK_A_INOTIFY_WATCH:
+                        if (event->inotify_watch_final)
+                                break;
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->inotify_watch_final = true;
+                        event->inotify_watch = cur->key.watch;
+                        break;
+                case TK_A_DEVLINK_PRIO:
+                        udev_device_set_devlink_priority(event->dev, cur->key.devlink_prio);
+                        break;
+                case TK_A_OWNER: {
+                        char owner[UTIL_NAME_SIZE];
+
+                        if (event->owner_final)
+                                break;
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->owner_final = true;
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner));
+                        event->owner_set = true;
+                        event->uid = util_lookup_user(event->udev, owner);
+                        log_debug("OWNER %u %s:%u\n",
+                                  event->uid,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        break;
+                }
+                case TK_A_GROUP: {
+                        char group[UTIL_NAME_SIZE];
+
+                        if (event->group_final)
+                                break;
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->group_final = true;
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group));
+                        event->group_set = true;
+                        event->gid = util_lookup_group(event->udev, group);
+                        log_debug("GROUP %u %s:%u\n",
+                                  event->gid,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        break;
+                }
+                case TK_A_MODE: {
+                        char mode_str[UTIL_NAME_SIZE];
+                        mode_t mode;
+                        char *endptr;
+
+                        if (event->mode_final)
+                                break;
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str));
+                        mode = strtol(mode_str, &endptr, 8);
+                        if (endptr[0] != '\0') {
+                                log_error("ignoring invalid mode '%s'\n", mode_str);
+                                break;
+                        }
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->mode_final = true;
+                        event->mode_set = true;
+                        event->mode = mode;
+                        log_debug("MODE %#o %s:%u\n",
+                                  event->mode,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        break;
+                }
+                case TK_A_OWNER_ID:
+                        if (event->owner_final)
+                                break;
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->owner_final = true;
+                        event->owner_set = true;
+                        event->uid = cur->key.uid;
+                        log_debug("OWNER %u %s:%u\n",
+                                  event->uid,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        break;
+                case TK_A_GROUP_ID:
+                        if (event->group_final)
+                                break;
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->group_final = true;
+                        event->group_set = true;
+                        event->gid = cur->key.gid;
+                        log_debug("GROUP %u %s:%u\n",
+                                  event->gid,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        break;
+                case TK_A_MODE_ID:
+                        if (event->mode_final)
+                                break;
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->mode_final = true;
+                        event->mode_set = true;
+                        event->mode = cur->key.mode;
+                        log_debug("MODE %#o %s:%u\n",
+                                  event->mode,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        break;
+                case TK_A_ENV: {
+                        const char *name = rules_str(rules, cur->key.attr_off);
+                        char *value = rules_str(rules, cur->key.value_off);
+                        char value_new[UTIL_NAME_SIZE];
+                        const char *value_old = NULL;
+                        struct udev_list_entry *entry;
+
+                        if (value[0] == '\0') {
+                                if (cur->key.op == OP_ADD)
+                                        break;
+                                udev_device_add_property(event->dev, name, NULL);
+                                break;
+                        }
+
+                        if (cur->key.op == OP_ADD)
+                                value_old = udev_device_get_property_value(event->dev, name);
+                        if (value_old) {
+                                char temp[UTIL_NAME_SIZE];
+
+                                /* append value separated by space */
+                                udev_event_apply_format(event, value, temp, sizeof(temp));
+                                util_strscpyl(value_new, sizeof(value_new), value_old, " ", temp, NULL);
+                        } else
+                                udev_event_apply_format(event, value, value_new, sizeof(value_new));
+
+                        entry = udev_device_add_property(event->dev, name, value_new);
+                        /* store in db, skip private keys */
+                        if (name[0] != '.')
+                                udev_list_entry_set_num(entry, true);
+                        break;
+                }
+                case TK_A_TAG: {
+                        char tag[UTIL_PATH_SIZE];
+                        const char *p;
+
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag));
+                        if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
+                                udev_device_cleanup_tags_list(event->dev);
+                        for (p = tag; *p != '\0'; p++) {
+                                if ((*p >= 'a' && *p <= 'z') ||
+                                    (*p >= 'A' && *p <= 'Z') ||
+                                    (*p >= '0' && *p <= '9') ||
+                                    *p == '-' || *p == '_')
+                                        continue;
+                                log_error("ignoring invalid tag name '%s'\n", tag);
+                                break;
+                        }
+                        udev_device_add_tag(event->dev, tag);
+                        break;
+                }
+                case TK_A_NAME: {
+                        const char *name  = rules_str(rules, cur->key.value_off);
+
+                        char name_str[UTIL_PATH_SIZE];
+                        int count;
+
+                        if (event->name_final)
+                                break;
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->name_final = true;
+                        udev_event_apply_format(event, name, name_str, sizeof(name_str));
+                        if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) {
+                                count = util_replace_chars(name_str, "/");
+                                if (count > 0)
+                                        log_debug("%i character(s) replaced\n", count);
+                        }
+                        if (major(udev_device_get_devnum(event->dev)) &&
+                            (!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) {
+                                log_error("NAME=\"%s\" ignored, kernel device nodes "
+                                    "can not be renamed; please fix it in %s:%u\n", name,
+                                    rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
+                                break;
+                        }
+                        free(event->name);
+                        event->name = strdup(name_str);
+                        log_debug("NAME '%s' %s:%u\n",
+                                  event->name,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        break;
+                }
+                case TK_A_DEVLINK: {
+                        char temp[UTIL_PATH_SIZE];
+                        char filename[UTIL_PATH_SIZE];
+                        char *pos, *next;
+                        int count = 0;
+
+                        if (event->devlink_final)
+                                break;
+                        if (major(udev_device_get_devnum(event->dev)) == 0)
+                                break;
+                        if (cur->key.op == OP_ASSIGN_FINAL)
+                                event->devlink_final = true;
+                        if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
+                                udev_device_cleanup_devlinks_list(event->dev);
+
+                        /* allow  multiple symlinks separated by spaces */
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp));
+                        if (esc == ESCAPE_UNSET)
+                                count = util_replace_chars(temp, "/ ");
+                        else if (esc == ESCAPE_REPLACE)
+                                count = util_replace_chars(temp, "/");
+                        if (count > 0)
+                                log_debug("%i character(s) replaced\n" , count);
+                        pos = temp;
+                        while (isspace(pos[0]))
+                                pos++;
+                        next = strchr(pos, ' ');
+                        while (next != NULL) {
+                                next[0] = '\0';
+                                log_debug("LINK '%s' %s:%u\n", pos,
+                                          rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
+                                util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL);
+                                udev_device_add_devlink(event->dev, filename);
+                                while (isspace(next[1]))
+                                        next++;
+                                pos = &next[1];
+                                next = strchr(pos, ' ');
+                        }
+                        if (pos[0] != '\0') {
+                                log_debug("LINK '%s' %s:%u\n", pos,
+                                          rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
+                                util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL);
+                                udev_device_add_devlink(event->dev, filename);
+                        }
+                        break;
+                }
+                case TK_A_ATTR: {
+                        const char *key_name = rules_str(rules, cur->key.attr_off);
+                        char attr[UTIL_PATH_SIZE];
+                        char value[UTIL_NAME_SIZE];
+                        FILE *f;
+
+                        if (util_resolve_subsys_kernel(event->udev, key_name, attr, sizeof(attr), 0) != 0)
+                                util_strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL);
+                        attr_subst_subdir(attr, sizeof(attr));
+
+                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value));
+                        log_debug("ATTR '%s' writing '%s' %s:%u\n", attr, value,
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        f = fopen(attr, "we");
+                        if (f != NULL) {
+                                if (fprintf(f, "%s", value) <= 0)
+                                        log_error("error writing ATTR{%s}: %m\n", attr);
+                                fclose(f);
+                        } else {
+                                log_error("error opening ATTR{%s} for writing: %m\n", attr);
+                        }
+                        break;
+                }
+                case TK_A_RUN_BUILTIN:
+                case TK_A_RUN_PROGRAM: {
+                        struct udev_list_entry *entry;
+
+                        if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
+                                udev_list_cleanup(&event->run_list);
+                        log_debug("RUN '%s' %s:%u\n",
+                                  rules_str(rules, cur->key.value_off),
+                                  rules_str(rules, rule->rule.filename_off),
+                                  rule->rule.filename_line);
+                        entry = udev_list_entry_add(&event->run_list, rules_str(rules, cur->key.value_off), NULL);
+                        udev_list_entry_set_num(entry, cur->key.builtin_cmd);
+                        break;
+                }
+                case TK_A_GOTO:
+                        if (cur->key.rule_goto == 0)
+                                break;
+                        cur = &rules->tokens[cur->key.rule_goto];
+                        continue;
+                case TK_END:
+                        return 0;
+
+                case TK_M_PARENTS_MIN:
+                case TK_M_PARENTS_MAX:
+                case TK_M_MAX:
+                case TK_UNSET:
+                        log_error("wrong type %u\n", cur->type);
+                        goto nomatch;
+                }
+
+                cur++;
+                continue;
+        nomatch:
+                /* fast-forward to next rule */
+                cur = rule + rule->rule.token_count;
+        }
+}
+
+void udev_rules_apply_static_dev_perms(struct udev_rules *rules)
+{
+        struct token *cur;
+        struct token *rule;
+        uid_t uid = 0;
+        gid_t gid = 0;
+        mode_t mode = 0;
+
+        if (rules->tokens == NULL)
+                return;
+
+        cur = &rules->tokens[0];
+        rule = cur;
+        for (;;) {
+                switch (cur->type) {
+                case TK_RULE:
+                        /* current rule */
+                        rule = cur;
+
+                        /* skip rules without a static_node tag */
+                        if (!rule->rule.has_static_node)
+                                goto next;
+
+                        uid = 0;
+                        gid = 0;
+                        mode = 0;
+                        break;
+                case TK_A_OWNER_ID:
+                        uid = cur->key.uid;
+                        break;
+                case TK_A_GROUP_ID:
+                        gid = cur->key.gid;
+                        break;
+                case TK_A_MODE_ID:
+                        mode = cur->key.mode;
+                        break;
+                case TK_A_STATIC_NODE: {
+                        char filename[UTIL_PATH_SIZE];
+                        struct stat stats;
+
+                        /* we assure, that the permissions tokens are sorted before the static token */
+                        if (mode == 0 && uid == 0 && gid == 0)
+                                goto next;
+                        util_strscpyl(filename, sizeof(filename), "/dev/", rules_str(rules, cur->key.value_off), NULL);
+                        if (stat(filename, &stats) != 0)
+                                goto next;
+                        if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode))
+                                goto next;
+                        if (mode == 0) {
+                                if (gid > 0)
+                                        mode = 0660;
+                                else
+                                        mode = 0600;
+                        }
+                        if (mode != (stats.st_mode & 01777)) {
+                                chmod(filename, mode);
+                                log_debug("chmod '%s' %#o\n", filename, mode);
+                        }
+
+                        if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) {
+                                chown(filename, uid, gid);
+                                log_debug("chown '%s' %u %u\n", filename, uid, gid);
+                        }
+
+                        utimensat(AT_FDCWD, filename, NULL, 0);
+                        break;
+                }
+                case TK_END:
+                        return;
+                }
+
+                cur++;
+                continue;
+next:
+                /* fast-forward to next rule */
+                cur = rule + rule->rule.token_count;
+                continue;
+        }
+}
diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c
new file mode 100644 (file)
index 0000000..311f5bd
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2009 Canonical Ltd.
+ * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/inotify.h>
+
+#include "udev.h"
+
+static int inotify_fd = -1;
+
+/* inotify descriptor, will be shared with rules directory;
+ * set to cloexec since we need our children to be able to add
+ * watches for us
+ */
+int udev_watch_init(struct udev *udev)
+{
+        inotify_fd = inotify_init1(IN_CLOEXEC);
+        if (inotify_fd < 0)
+                log_error("inotify_init failed: %m\n");
+        return inotify_fd;
+}
+
+/* move any old watches directory out of the way, and then restore
+ * the watches
+ */
+void udev_watch_restore(struct udev *udev)
+{
+        if (inotify_fd < 0)
+                return;
+
+        if (rename("/run/udev/watch", "/run/udev/watch.old") == 0) {
+                DIR *dir;
+                struct dirent *ent;
+
+                dir = opendir("/run/udev/watch.old");
+                if (dir == NULL) {
+                        log_error("unable to open old watches dir /run/udev/watch.old; old watches will not be restored: %m");
+                        return;
+                }
+
+                for (ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
+                        char device[UTIL_PATH_SIZE];
+                        ssize_t len;
+                        struct udev_device *dev;
+
+                        if (ent->d_name[0] == '.')
+                                continue;
+
+                        len = readlinkat(dirfd(dir), ent->d_name, device, sizeof(device));
+                        if (len <= 0 || len == (ssize_t)sizeof(device))
+                                goto unlink;
+                        device[len] = '\0';
+
+                        dev = udev_device_new_from_device_id(udev, device);
+                        if (dev == NULL)
+                                goto unlink;
+
+                        log_debug("restoring old watch on '%s'\n", udev_device_get_devnode(dev));
+                        udev_watch_begin(udev, dev);
+                        udev_device_unref(dev);
+unlink:
+                        unlinkat(dirfd(dir), ent->d_name, 0);
+                }
+
+                closedir(dir);
+                rmdir("/run/udev/watch.old");
+
+        } else if (errno != ENOENT) {
+                log_error("unable to move watches dir /run/udev/watch; old watches will not be restored: %m");
+        }
+}
+
+void udev_watch_begin(struct udev *udev, struct udev_device *dev)
+{
+        char filename[UTIL_PATH_SIZE];
+        int wd;
+        int r;
+
+        if (inotify_fd < 0)
+                return;
+
+        log_debug("adding watch on '%s'\n", udev_device_get_devnode(dev));
+        wd = inotify_add_watch(inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
+        if (wd < 0) {
+                log_error("inotify_add_watch(%d, %s, %o) failed: %m\n",
+                    inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
+                return;
+        }
+
+        snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
+        mkdir_parents(filename, 0755);
+        unlink(filename);
+        r = symlink(udev_device_get_id_filename(dev), filename);
+        if (r < 0)
+                log_error("Failed to create symlink: %m");
+
+        udev_device_set_watch_handle(dev, wd);
+}
+
+void udev_watch_end(struct udev *udev, struct udev_device *dev)
+{
+        int wd;
+        char filename[UTIL_PATH_SIZE];
+
+        if (inotify_fd < 0)
+                return;
+
+        wd = udev_device_get_watch_handle(dev);
+        if (wd < 0)
+                return;
+
+        log_debug("removing watch on '%s'\n", udev_device_get_devnode(dev));
+        inotify_rm_watch(inotify_fd, wd);
+
+        snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
+        unlink(filename);
+
+        udev_device_set_watch_handle(dev, -1);
+}
+
+struct udev_device *udev_watch_lookup(struct udev *udev, int wd)
+{
+        char filename[UTIL_PATH_SIZE];
+        char device[UTIL_NAME_SIZE];
+        ssize_t len;
+
+        if (inotify_fd < 0 || wd < 0)
+                return NULL;
+
+        snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
+        len = readlink(filename, device, sizeof(device));
+        if (len <= 0 || (size_t)len == sizeof(device))
+                return NULL;
+        device[len] = '\0';
+
+        return udev_device_new_from_device_id(udev, device);
+}
diff --git a/src/udev/udev.conf b/src/udev/udev.conf
new file mode 100644 (file)
index 0000000..f39253e
--- /dev/null
@@ -0,0 +1,3 @@
+# see udev(7) for details
+
+#udev_log="info"
diff --git a/src/udev/udev.h b/src/udev/udev.h
new file mode 100644 (file)
index 0000000..72a7623
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _UDEV_H_
+#define _UDEV_H_
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <signal.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+#include "util.h"
+#include "label.h"
+#include "strv.h"
+
+struct udev_event {
+        struct udev *udev;
+        struct udev_device *dev;
+        struct udev_device *dev_parent;
+        struct udev_device *dev_db;
+        char *name;
+        char *program_result;
+        mode_t mode;
+        uid_t uid;
+        gid_t gid;
+        struct udev_list run_list;
+        int exec_delay;
+        usec_t birth_usec;
+        usec_t timeout_usec;
+        int fd_signal;
+        unsigned int builtin_run;
+        unsigned int builtin_ret;
+        bool sigterm;
+        bool inotify_watch;
+        bool inotify_watch_final;
+        bool group_set;
+        bool group_final;
+        bool owner_set;
+        bool owner_final;
+        bool mode_set;
+        bool mode_final;
+        bool name_final;
+        bool devlink_final;
+        bool run_final;
+};
+
+struct udev_watch {
+        struct udev_list_node node;
+        int handle;
+        char *name;
+};
+
+/* udev-rules.c */
+struct udev_rules;
+struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names);
+struct udev_rules *udev_rules_unref(struct udev_rules *rules);
+bool udev_rules_check_timestamp(struct udev_rules *rules);
+int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask);
+void udev_rules_apply_static_dev_perms(struct udev_rules *rules);
+
+/* udev-event.c */
+struct udev_event *udev_event_new(struct udev_device *dev);
+void udev_event_unref(struct udev_event *event);
+size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size);
+int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string,
+                                   char *result, size_t maxsize, int read_value);
+int udev_event_spawn(struct udev_event *event,
+                     const char *cmd, char **envp, const sigset_t *sigmask,
+                     char *result, size_t ressize);
+int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset);
+void udev_event_execute_run(struct udev_event *event, const sigset_t *sigset);
+int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
+
+/* udev-watch.c */
+int udev_watch_init(struct udev *udev);
+void udev_watch_restore(struct udev *udev);
+void udev_watch_begin(struct udev *udev, struct udev_device *dev);
+void udev_watch_end(struct udev *udev, struct udev_device *dev);
+struct udev_device *udev_watch_lookup(struct udev *udev, int wd);
+
+/* udev-node.c */
+void udev_node_add(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid);
+void udev_node_remove(struct udev_device *dev);
+void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old);
+
+/* udev-ctrl.c */
+struct udev_ctrl;
+struct udev_ctrl *udev_ctrl_new(struct udev *udev);
+struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd);
+int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl);
+struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl);
+struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl);
+int udev_ctrl_cleanup(struct udev_ctrl *uctrl);
+struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl);
+int udev_ctrl_get_fd(struct udev_ctrl *uctrl);
+int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout);
+int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout);
+int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl, int timeout);
+int udev_ctrl_send_reload(struct udev_ctrl *uctrl, int timeout);
+int udev_ctrl_send_ping(struct udev_ctrl *uctrl, int timeout);
+int udev_ctrl_send_exit(struct udev_ctrl *uctrl, int timeout);
+int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key, int timeout);
+int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count, int timeout);
+struct udev_ctrl_connection;
+struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl);
+struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn);
+struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn);
+struct udev_ctrl_msg;
+struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn);
+struct udev_ctrl_msg *udev_ctrl_msg_ref(struct udev_ctrl_msg *ctrl_msg);
+struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg);
+int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg);
+int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg);
+int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg);
+int udev_ctrl_get_reload(struct udev_ctrl_msg *ctrl_msg);
+int udev_ctrl_get_ping(struct udev_ctrl_msg *ctrl_msg);
+int udev_ctrl_get_exit(struct udev_ctrl_msg *ctrl_msg);
+const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg);
+int udev_ctrl_get_set_children_max(struct udev_ctrl_msg *ctrl_msg);
+
+/* built-in commands */
+enum udev_builtin_cmd {
+#ifdef HAVE_BLKID
+        UDEV_BUILTIN_BLKID,
+#endif
+        UDEV_BUILTIN_BTRFS,
+        UDEV_BUILTIN_FIRMWARE,
+        UDEV_BUILTIN_HWDB,
+        UDEV_BUILTIN_INPUT_ID,
+#ifdef HAVE_KMOD
+        UDEV_BUILTIN_KMOD,
+#endif
+        UDEV_BUILTIN_NET_ID,
+        UDEV_BUILTIN_PATH_ID,
+        UDEV_BUILTIN_USB_ID,
+#ifdef HAVE_ACL
+        UDEV_BUILTIN_UACCESS,
+#endif
+        UDEV_BUILTIN_MAX
+};
+struct udev_builtin {
+        const char *name;
+        int (*cmd)(struct udev_device *dev, int argc, char *argv[], bool test);
+        const char *help;
+        int (*init)(struct udev *udev);
+        void (*exit)(struct udev *udev);
+        bool (*validate)(struct udev *udev);
+        bool run_once;
+};
+#ifdef HAVE_BLKID
+extern const struct udev_builtin udev_builtin_blkid;
+#endif
+extern const struct udev_builtin udev_builtin_btrfs;
+extern const struct udev_builtin udev_builtin_firmware;
+extern const struct udev_builtin udev_builtin_hwdb;
+extern const struct udev_builtin udev_builtin_input_id;
+#ifdef HAVE_KMOD
+extern const struct udev_builtin udev_builtin_kmod;
+#endif
+extern const struct udev_builtin udev_builtin_net_id;
+extern const struct udev_builtin udev_builtin_path_id;
+extern const struct udev_builtin udev_builtin_usb_id;
+extern const struct udev_builtin udev_builtin_uaccess;
+void udev_builtin_init(struct udev *udev);
+void udev_builtin_exit(struct udev *udev);
+enum udev_builtin_cmd udev_builtin_lookup(const char *command);
+const char *udev_builtin_name(enum udev_builtin_cmd cmd);
+bool udev_builtin_run_once(enum udev_builtin_cmd cmd);
+int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test);
+void udev_builtin_list(struct udev *udev);
+bool udev_builtin_validate(struct udev *udev);
+int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val);
+int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, bool test);
+
+/* udev logging */
+void udev_main_log(struct udev *udev, int priority,
+                   const char *file, int line, const char *fn,
+                   const char *format, va_list args);
+
+/* udevadm commands */
+struct udevadm_cmd {
+        const char *name;
+        int (*cmd)(struct udev *udev, int argc, char *argv[]);
+        const char *help;
+        int debug;
+};
+extern const struct udevadm_cmd udevadm_info;
+extern const struct udevadm_cmd udevadm_trigger;
+extern const struct udevadm_cmd udevadm_settle;
+extern const struct udevadm_cmd udevadm_control;
+extern const struct udevadm_cmd udevadm_monitor;
+extern const struct udevadm_cmd udevadm_hwdb;
+extern const struct udevadm_cmd udevadm_test;
+extern const struct udevadm_cmd udevadm_test_builtin;
+#endif
diff --git a/src/udev/udev.pc.in b/src/udev/udev.pc.in
new file mode 100644 (file)
index 0000000..a0c2e82
--- /dev/null
@@ -0,0 +1,5 @@
+Name: udev
+Description: udev
+Version: @VERSION@
+
+udevdir=@udevlibexecdir@
diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c
new file mode 100644 (file)
index 0000000..c5a1892
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2005-2011 Kay Sievers <kay@vrfy.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.
+ */
+
+#include <time.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+
+#include "udev.h"
+
+static void print_help(void)
+{
+        printf("Usage: udevadm control COMMAND\n"
+                "  --exit                   instruct the daemon to cleanup and exit\n"
+                "  --log-priority=<level>   set the udev log level for the daemon\n"
+                "  --stop-exec-queue        do not execute events, queue only\n"
+                "  --start-exec-queue       execute events, flush queue\n"
+                "  --reload                 reload rules and databases\n"
+                "  --property=<KEY>=<value> set a global property for all events\n"
+                "  --children-max=<N>       maximum number of children\n"
+                "  --timeout=<seconds>      maximum time to block for a reply\n"
+                "  --help                   print this help text\n\n");
+}
+
+static int adm_control(struct udev *udev, int argc, char *argv[])
+{
+        struct udev_ctrl *uctrl = NULL;
+        int timeout = 60;
+        int rc = 1;
+
+        static const struct option options[] = {
+                { "exit", no_argument, NULL, 'e' },
+                { "log-priority", required_argument, NULL, 'l' },
+                { "stop-exec-queue", no_argument, NULL, 's' },
+                { "start-exec-queue", no_argument, NULL, 'S' },
+                { "reload", no_argument, NULL, 'R' },
+                { "reload-rules", no_argument, NULL, 'R' },
+                { "property", required_argument, NULL, 'p' },
+                { "env", required_argument, NULL, 'p' },
+                { "children-max", required_argument, NULL, 'm' },
+                { "timeout", required_argument, NULL, 't' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+
+        if (getuid() != 0) {
+                fprintf(stderr, "root privileges required\n");
+                return 1;
+        }
+
+        uctrl = udev_ctrl_new(udev);
+        if (uctrl == NULL)
+                return 2;
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "el:sSRp:m:h", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'e':
+                        if (udev_ctrl_send_exit(uctrl, timeout) < 0)
+                                rc = 2;
+                        else
+                                rc = 0;
+                        break;
+                case 'l': {
+                        int i;
+
+                        i = util_log_priority(optarg);
+                        if (i < 0) {
+                                fprintf(stderr, "invalid number '%s'\n", optarg);
+                                goto out;
+                        }
+                        if (udev_ctrl_send_set_log_level(uctrl, util_log_priority(optarg), timeout) < 0)
+                                rc = 2;
+                        else
+                                rc = 0;
+                        break;
+                }
+                case 's':
+                        if (udev_ctrl_send_stop_exec_queue(uctrl, timeout) < 0)
+                                rc = 2;
+                        else
+                                rc = 0;
+                        break;
+                case 'S':
+                        if (udev_ctrl_send_start_exec_queue(uctrl, timeout) < 0)
+                                rc = 2;
+                        else
+                                rc = 0;
+                        break;
+                case 'R':
+                        if (udev_ctrl_send_reload(uctrl, timeout) < 0)
+                                rc = 2;
+                        else
+                                rc = 0;
+                        break;
+                case 'p':
+                        if (strchr(optarg, '=') == NULL) {
+                                fprintf(stderr, "expect <KEY>=<value> instead of '%s'\n", optarg);
+                                goto out;
+                        }
+                        if (udev_ctrl_send_set_env(uctrl, optarg, timeout) < 0)
+                                rc = 2;
+                        else
+                                rc = 0;
+                        break;
+                case 'm': {
+                        char *endp;
+                        int i;
+
+                        i = strtoul(optarg, &endp, 0);
+                        if (endp[0] != '\0' || i < 1) {
+                                fprintf(stderr, "invalid number '%s'\n", optarg);
+                                goto out;
+                        }
+                        if (udev_ctrl_send_set_children_max(uctrl, i, timeout) < 0)
+                                rc = 2;
+                        else
+                                rc = 0;
+                        break;
+                }
+                case 't': {
+                        int seconds;
+
+                        seconds = atoi(optarg);
+                        if (seconds >= 0)
+                                timeout = seconds;
+                        else
+                                fprintf(stderr, "invalid timeout value\n");
+                        break;
+                }
+                case 'h':
+                        print_help();
+                        rc = 0;
+                        break;
+                }
+        }
+
+        if (argv[optind] != NULL)
+                fprintf(stderr, "unknown option\n");
+        else if (optind == 1)
+                fprintf(stderr, "missing option\n");
+out:
+        udev_ctrl_unref(uctrl);
+        return rc;
+}
+
+const struct udevadm_cmd udevadm_control = {
+        .name = "control",
+        .cmd = adm_control,
+        .help = "control the udev daemon",
+};
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
new file mode 100644 (file)
index 0000000..00c0d3d
--- /dev/null
@@ -0,0 +1,602 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Kay Sievers <kay@vrfy.org>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+
+#include "util.h"
+#include "strbuf.h"
+#include "conf-files.h"
+
+#include "udev.h"
+#include "libudev-hwdb-def.h"
+
+/*
+ * Generic udev properties, key/value database based on modalias strings.
+ * Uses a Patricia/radix trie to index all matches for efficient lookup.
+ */
+
+static const char * const conf_file_dirs[] = {
+        "/etc/udev/hwdb.d",
+        UDEVLIBEXECDIR "/hwdb.d",
+        NULL
+};
+
+/* in-memory trie objects */
+struct trie {
+        struct trie_node *root;
+        struct strbuf *strings;
+
+        size_t nodes_count;
+        size_t children_count;
+        size_t values_count;
+};
+
+struct trie_node {
+        /* prefix, common part for all children of this node */
+        size_t prefix_off;
+
+        /* sorted array of pointers to children nodes */
+        struct trie_child_entry *children;
+        uint8_t children_count;
+
+        /* sorted array of key/value pairs */
+        struct trie_value_entry *values;
+        size_t values_count;
+};
+
+/* children array item with char (0-255) index */
+struct trie_child_entry {
+        uint8_t c;
+        struct trie_node *child;
+};
+
+/* value array item with key/value pairs */
+struct trie_value_entry {
+        size_t key_off;
+        size_t value_off;
+};
+
+static int trie_children_cmp(const void *v1, const void *v2) {
+        const struct trie_child_entry *n1 = v1;
+        const struct trie_child_entry *n2 = v2;
+
+        return n1->c - n2->c;
+}
+
+static int node_add_child(struct trie *trie, struct trie_node *node, struct trie_node *node_child, uint8_t c) {
+        struct trie_child_entry *child;
+        int err = 0;
+
+        /* extend array, add new entry, sort for bisection */
+        child = realloc(node->children, (node->children_count + 1) * sizeof(struct trie_child_entry));
+        if (!child) {
+                err = -ENOMEM;
+                goto out;
+        }
+        node->children = child;
+        trie->children_count++;
+        node->children[node->children_count].c = c;
+        node->children[node->children_count].child = node_child;
+        node->children_count++;
+        qsort(node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
+        trie->nodes_count++;
+out:
+        return err;
+}
+
+static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) {
+        struct trie_child_entry *child;
+        struct trie_child_entry search;
+
+        search.c = c;
+        child = bsearch(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
+        if (child)
+                return child->child;
+        return NULL;
+}
+
+static void trie_node_cleanup(struct trie_node *node) {
+        size_t i;
+
+        for (i = 0; i < node->children_count; i++)
+                trie_node_cleanup(node->children[i].child);
+        free(node->children);
+        free(node->values);
+        free(node);
+}
+
+static int trie_values_cmp(const void *v1, const void *v2, void *arg) {
+        const struct trie_value_entry *val1 = v1;
+        const struct trie_value_entry *val2 = v2;
+        struct trie *trie = arg;
+
+        return strcmp(trie->strings->buf + val1->key_off,
+                      trie->strings->buf + val2->key_off);
+}
+
+static int trie_node_add_value(struct trie *trie, struct trie_node *node,
+                          const char *key, const char *value) {
+        ssize_t k, v;
+        struct trie_value_entry *val;
+
+        k = strbuf_add_string(trie->strings, key, strlen(key));
+        if (k < 0)
+                return k;
+        v = strbuf_add_string(trie->strings, value, strlen(value));
+        if (v < 0)
+                return v;
+
+        if (node->values_count) {
+                struct trie_value_entry search = {
+                        .key_off = k,
+                        .value_off = v,
+                };
+
+                val = xbsearch_r(&search, node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie);
+                if (val) {
+                        /* replace existing earlier key with new value */
+                        val->value_off = v;
+                        return 0;
+                }
+        }
+
+        /* extend array, add new entry, sort for bisection */
+        val = realloc(node->values, (node->values_count + 1) * sizeof(struct trie_value_entry));
+        if (!val)
+                return -ENOMEM;
+        trie->values_count++;
+        node->values = val;
+        node->values[node->values_count].key_off = k;
+        node->values[node->values_count].value_off = v;
+        node->values_count++;
+        qsort_r(node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie);
+        return 0;
+}
+
+static int trie_insert(struct trie *trie, struct trie_node *node, const char *search,
+                       const char *key, const char *value) {
+        size_t i = 0;
+        int err = 0;
+
+        for (;;) {
+                size_t p;
+                uint8_t c;
+                struct trie_node *child;
+
+                for (p = 0; (c = trie->strings->buf[node->prefix_off + p]); p++) {
+                        char *s;
+                        ssize_t off;
+
+                        if (c == search[i + p])
+                                continue;
+
+                        /* split node */
+                        child = calloc(sizeof(struct trie_node), 1);
+                        if (!child) {
+                                err = -ENOMEM;
+                                goto out;
+                        }
+
+                        /* move values from parent to child */
+                        child->prefix_off = node->prefix_off + p+1;
+                        child->children = node->children;
+                        child->children_count = node->children_count;
+                        child->values = node->values;
+                        child->values_count = node->values_count;
+
+                        /* update parent; use strdup() because the source gets realloc()d */
+                        s = strndup(trie->strings->buf + node->prefix_off, p);
+                        if (!s) {
+                                err = -ENOMEM;
+                                goto out;
+                        }
+                        off = strbuf_add_string(trie->strings, s, p);
+                        free(s);
+                        if (off < 0) {
+                                err = off;
+                                goto out;
+                        }
+                        node->prefix_off = off;
+                        node->children = NULL;
+                        node->children_count = 0;
+                        node->values = NULL;
+                        node->values_count = 0;
+                        err = node_add_child(trie, node, child, c);
+                        if (err)
+                                goto out;
+                        break;
+                }
+                i += p;
+
+                c = search[i];
+                if (c == '\0')
+                        return trie_node_add_value(trie, node, key, value);
+
+                child = node_lookup(node, c);
+                if (!child) {
+                        ssize_t off;
+
+                        /* new child */
+                        child = calloc(sizeof(struct trie_node), 1);
+                        if (!child) {
+                                err = -ENOMEM;
+                                goto out;
+                        }
+                        off = strbuf_add_string(trie->strings, search + i+1, strlen(search + i+1));
+                        if (off < 0) {
+                                err = off;
+                                goto out;
+                        }
+                        child->prefix_off = off;
+                        err = node_add_child(trie, node, child, c);
+                        if (err)
+                                goto out;
+                        return trie_node_add_value(trie, child, key, value);
+                }
+
+                node = child;
+                i++;
+        }
+out:
+        return err;
+}
+
+struct trie_f {
+        FILE *f;
+        struct trie *trie;
+        uint64_t strings_off;
+
+        uint64_t nodes_count;
+        uint64_t children_count;
+        uint64_t values_count;
+};
+
+/* calculate the storage space for the nodes, children arrays, value arrays */
+static void trie_store_nodes_size(struct trie_f *trie, struct trie_node *node) {
+        uint64_t i;
+
+        for (i = 0; i < node->children_count; i++)
+                trie_store_nodes_size(trie, node->children[i].child);
+
+        trie->strings_off += sizeof(struct trie_node_f);
+        for (i = 0; i < node->children_count; i++)
+                trie->strings_off += sizeof(struct trie_child_entry_f);
+        for (i = 0; i < node->values_count; i++)
+                trie->strings_off += sizeof(struct trie_value_entry_f);
+}
+
+static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) {
+        uint64_t i;
+        struct trie_node_f n = {
+                .prefix_off = htole64(trie->strings_off + node->prefix_off),
+                .children_count = node->children_count,
+                .values_count = htole64(node->values_count),
+        };
+        struct trie_child_entry_f *children = NULL;
+        int64_t node_off;
+
+        if (node->children_count) {
+                children = new0(struct trie_child_entry_f, node->children_count);
+                if (!children)
+                        return -ENOMEM;
+        }
+
+        /* post-order recursion */
+        for (i = 0; i < node->children_count; i++) {
+                int64_t child_off;
+
+                child_off = trie_store_nodes(trie, node->children[i].child);
+                if (child_off < 0)
+                        return child_off;
+                children[i].c = node->children[i].c;
+                children[i].child_off = htole64(child_off);
+        }
+
+        /* write node */
+        node_off = ftello(trie->f);
+        fwrite(&n, sizeof(struct trie_node_f), 1, trie->f);
+        trie->nodes_count++;
+
+        /* append children array */
+        if (node->children_count) {
+                fwrite(children, sizeof(struct trie_child_entry_f), node->children_count, trie->f);
+                trie->children_count += node->children_count;
+                free(children);
+        }
+
+        /* append values array */
+        for (i = 0; i < node->values_count; i++) {
+                struct trie_value_entry_f v = {
+                        .key_off = htole64(trie->strings_off + node->values[i].key_off),
+                        .value_off = htole64(trie->strings_off + node->values[i].value_off),
+                };
+
+                fwrite(&v, sizeof(struct trie_value_entry_f), 1, trie->f);
+                trie->values_count++;
+        }
+
+        return node_off;
+}
+
+static int trie_store(struct trie *trie, const char *filename) {
+        struct trie_f t = {
+                .trie = trie,
+        };
+        char *filename_tmp;
+        int64_t pos;
+        int64_t root_off;
+        int64_t size;
+        struct trie_header_f h = {
+                .signature = HWDB_SIG,
+                .tool_version = htole64(atoi(VERSION)),
+                .header_size = htole64(sizeof(struct trie_header_f)),
+                .node_size = htole64(sizeof(struct trie_node_f)),
+                .child_entry_size = htole64(sizeof(struct trie_child_entry_f)),
+                .value_entry_size = htole64(sizeof(struct trie_value_entry_f)),
+        };
+        int err;
+
+        /* calculate size of header, nodes, children entries, value entries */
+        t.strings_off = sizeof(struct trie_header_f);
+        trie_store_nodes_size(&t, trie->root);
+
+        err = fopen_temporary(filename , &t.f, &filename_tmp);
+        if (err < 0)
+                return err;
+        fchmod(fileno(t.f), 0444);
+
+        /* write nodes */
+        fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET);
+        root_off = trie_store_nodes(&t, trie->root);
+        h.nodes_root_off = htole64(root_off);
+        pos = ftello(t.f);
+        h.nodes_len = htole64(pos - sizeof(struct trie_header_f));
+
+        /* write string buffer */
+        fwrite(trie->strings->buf, trie->strings->len, 1, t.f);
+        h.strings_len = htole64(trie->strings->len);
+
+        /* write header */
+        size = ftello(t.f);
+        h.file_size = htole64(size);
+        fseeko(t.f, 0, SEEK_SET);
+        fwrite(&h, sizeof(struct trie_header_f), 1, t.f);
+        err = ferror(t.f);
+        if (err)
+                err = -errno;
+        fclose(t.f);
+        if (err < 0 || rename(filename_tmp, filename) < 0) {
+                unlink(filename_tmp);
+                goto out;
+        }
+
+        log_debug("=== trie on-disk ===\n");
+        log_debug("size:             %8llu bytes\n", (unsigned long long)size);
+        log_debug("header:           %8zu bytes\n", sizeof(struct trie_header_f));
+        log_debug("nodes:            %8llu bytes (%8llu)\n",
+                  (unsigned long long)t.nodes_count * sizeof(struct trie_node_f), (unsigned long long)t.nodes_count);
+        log_debug("child pointers:   %8llu bytes (%8llu)\n",
+                  (unsigned long long)t.children_count * sizeof(struct trie_child_entry_f), (unsigned long long)t.children_count);
+        log_debug("value pointers:   %8llu bytes (%8llu)\n",
+                  (unsigned long long)t.values_count * sizeof(struct trie_value_entry_f), (unsigned long long)t.values_count);
+        log_debug("string store:     %8llu bytes\n", (unsigned long long)trie->strings->len);
+        log_debug("strings start:    %8llu\n", (unsigned long long) t.strings_off);
+out:
+        free(filename_tmp);
+        return err;
+}
+
+static int import_file(struct trie *trie, const char *filename) {
+        FILE *f;
+        char line[LINE_MAX];
+        char match[LINE_MAX];
+        char cond[LINE_MAX];
+
+        f = fopen(filename, "re");
+        if (f == NULL)
+                return -errno;
+
+        match[0] = '\0';
+        cond[0] = '\0';
+        while (fgets(line, sizeof(line), f)) {
+                size_t len;
+
+                if (line[0] == '#')
+                        continue;
+
+                /* new line, new record */
+                if (line[0] == '\n') {
+                        match[0] = '\0';
+                        cond[0] = '\0';
+                        continue;
+                }
+
+                /* remove newline */
+                len = strlen(line);
+                if (len < 2)
+                        continue;
+                line[len-1] = '\0';
+
+                /* start of new record */
+                if (match[0] == '\0') {
+                        strcpy(match, line);
+                        cond[0] = '\0';
+                        continue;
+                }
+
+                if (line[0] == '+') {
+                        strcpy(cond, line);
+                        continue;
+                }
+
+                /* TODO: support +; skip the entire record until we support it */
+                if (cond[0] != '\0')
+                        continue;
+
+                /* value lines */
+                if (line[0] == ' ') {
+                        char *value;
+
+                        value = strchr(line, '=');
+                        if (!value)
+                                continue;
+                        value[0] = '\0';
+                        value++;
+                        trie_insert(trie, trie->root, match, line, value);
+                }
+        }
+        fclose(f);
+        return 0;
+}
+
+static void help(void) {
+        printf("Usage: udevadm hwdb OPTIONS\n"
+               "  --update            update the hardware database\n"
+               "  --test <modalias>   query database and print result\n"
+               "  --help\n\n");
+}
+
+static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
+        static const struct option options[] = {
+                { "update", no_argument, NULL, 'u' },
+                { "test", required_argument, NULL, 't' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+        const char *test = NULL;
+        bool update = false;
+        struct trie *trie = NULL;
+        int err;
+        int rc = EXIT_SUCCESS;
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "ut:h", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'u':
+                        update = true;
+                        break;
+                case 't':
+                        test = optarg;
+                        break;
+                case 'h':
+                        help();
+                        return EXIT_SUCCESS;
+                }
+        }
+
+        if (!update && !test) {
+                help();
+                return EXIT_SUCCESS;
+        }
+
+        if (update) {
+                char **files, **f;
+
+                trie = calloc(sizeof(struct trie), 1);
+                if (!trie) {
+                        rc = EXIT_FAILURE;
+                        goto out;
+                }
+
+                /* string store */
+                trie->strings = strbuf_new();
+                if (!trie->strings) {
+                        rc = EXIT_FAILURE;
+                        goto out;
+                }
+
+                /* index */
+                trie->root = calloc(sizeof(struct trie_node), 1);
+                if (!trie->root) {
+                        rc = EXIT_FAILURE;
+                        goto out;
+                }
+                trie->nodes_count++;
+
+                err = conf_files_list_strv(&files, ".hwdb", (const char **)conf_file_dirs);
+                if (err < 0) {
+                        log_error("failed to enumerate hwdb files: %s\n", strerror(-err));
+                        rc = EXIT_FAILURE;
+                        goto out;
+                }
+                STRV_FOREACH(f, files) {
+                        log_debug("reading file '%s'", *f);
+                        import_file(trie, *f);
+                }
+                strv_free(files);
+
+                strbuf_complete(trie->strings);
+
+                log_debug("=== trie in-memory ===\n");
+                log_debug("nodes:            %8zu bytes (%8zu)\n",
+                          trie->nodes_count * sizeof(struct trie_node), trie->nodes_count);
+                log_debug("children arrays:  %8zu bytes (%8zu)\n",
+                          trie->children_count * sizeof(struct trie_child_entry), trie->children_count);
+                log_debug("values arrays:    %8zu bytes (%8zu)\n",
+                          trie->values_count * sizeof(struct trie_value_entry), trie->values_count);
+                log_debug("strings:          %8zu bytes\n",
+                          trie->strings->len);
+                log_debug("strings incoming: %8zu bytes (%8zu)\n",
+                          trie->strings->in_len, trie->strings->in_count);
+                log_debug("strings dedup'ed: %8zu bytes (%8zu)\n",
+                          trie->strings->dedup_len, trie->strings->dedup_count);
+
+                mkdir_parents(HWDB_BIN, 0755);
+                err = trie_store(trie, HWDB_BIN);
+                if (err < 0) {
+                        log_error("Failure writing hardware database '%s': %s",
+                                  HWDB_BIN, strerror(-err));
+                        rc = EXIT_FAILURE;
+                }
+        }
+
+        if (test) {
+                struct udev_hwdb *hwdb = udev_hwdb_new(udev);
+
+                if (hwdb) {
+                        struct udev_list_entry *entry;
+
+                        udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, test, 0))
+                                printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
+                        hwdb = udev_hwdb_unref(hwdb);
+                }
+        }
+out:
+        if (trie) {
+                if (trie->root)
+                        trie_node_cleanup(trie->root);
+                strbuf_cleanup(trie->strings);
+                free(trie);
+        }
+        return rc;
+}
+
+const struct udevadm_cmd udevadm_hwdb = {
+        .name = "hwdb",
+        .cmd = adm_hwdb,
+        .help = "maintain the hardware database index",
+};
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
new file mode 100644 (file)
index 0000000..95f077c
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) 2004-2009 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "udev.h"
+
+static bool skip_attribute(const char *name)
+{
+        static const char const *skip[] = {
+                "uevent",
+                "dev",
+                "modalias",
+                "resource",
+                "driver",
+                "subsystem",
+                "module",
+        };
+        unsigned int i;
+
+        for (i = 0; i < ELEMENTSOF(skip); i++)
+                if (strcmp(name, skip[i]) == 0)
+                        return true;
+        return false;
+}
+
+static void print_all_attributes(struct udev_device *device, const char *key)
+{
+        struct udev_list_entry *sysattr;
+
+        udev_list_entry_foreach(sysattr, udev_device_get_sysattr_list_entry(device)) {
+                const char *name;
+                const char *value;
+                size_t len;
+
+                name = udev_list_entry_get_name(sysattr);
+                if (skip_attribute(name))
+                        continue;
+
+                value = udev_device_get_sysattr_value(device, name);
+                if (value == NULL)
+                        continue;
+
+                /* skip any values that look like a path */
+                if (value[0] == '/')
+                        continue;
+
+                /* skip nonprintable attributes */
+                len = strlen(value);
+                while (len > 0 && isprint(value[len-1]))
+                        len--;
+                if (len > 0)
+                        continue;
+
+                printf("    %s{%s}==\"%s\"\n", key, name, value);
+        }
+        printf("\n");
+}
+
+static int print_device_chain(struct udev_device *device)
+{
+        struct udev_device *device_parent;
+        const char *str;
+
+        printf("\n"
+               "Udevadm info starts with the device specified by the devpath and then\n"
+               "walks up the chain of parent devices. It prints for every device\n"
+               "found, all possible attributes in the udev rules key format.\n"
+               "A rule to match, can be composed by the attributes of the device\n"
+               "and the attributes from one single parent device.\n"
+               "\n");
+
+        printf("  looking at device '%s':\n", udev_device_get_devpath(device));
+        printf("    KERNEL==\"%s\"\n", udev_device_get_sysname(device));
+        str = udev_device_get_subsystem(device);
+        if (str == NULL)
+                str = "";
+        printf("    SUBSYSTEM==\"%s\"\n", str);
+        str = udev_device_get_driver(device);
+        if (str == NULL)
+                str = "";
+        printf("    DRIVER==\"%s\"\n", str);
+        print_all_attributes(device, "ATTR");
+
+        device_parent = device;
+        do {
+                device_parent = udev_device_get_parent(device_parent);
+                if (device_parent == NULL)
+                        break;
+                printf("  looking at parent device '%s':\n", udev_device_get_devpath(device_parent));
+                printf("    KERNELS==\"%s\"\n", udev_device_get_sysname(device_parent));
+                str = udev_device_get_subsystem(device_parent);
+                if (str == NULL)
+                        str = "";
+                printf("    SUBSYSTEMS==\"%s\"\n", str);
+                str = udev_device_get_driver(device_parent);
+                if (str == NULL)
+                        str = "";
+                printf("    DRIVERS==\"%s\"\n", str);
+                print_all_attributes(device_parent, "ATTRS");
+        } while (device_parent != NULL);
+
+        return 0;
+}
+
+static void print_record(struct udev_device *device)
+{
+        const char *str;
+        int i;
+        struct udev_list_entry *list_entry;
+
+        printf("P: %s\n", udev_device_get_devpath(device));
+
+        str = udev_device_get_devnode(device);
+        if (str != NULL)
+                printf("N: %s\n", str + strlen("/dev/"));
+
+        i = udev_device_get_devlink_priority(device);
+        if (i != 0)
+                printf("L: %i\n", i);
+
+        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
+                printf("S: %s\n", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+
+        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
+                printf("E: %s=%s\n",
+                       udev_list_entry_get_name(list_entry),
+                       udev_list_entry_get_value(list_entry));
+        printf("\n");
+}
+
+static int stat_device(const char *name, bool export, const char *prefix)
+{
+        struct stat statbuf;
+
+        if (stat(name, &statbuf) != 0)
+                return -1;
+
+        if (export) {
+                if (prefix == NULL)
+                        prefix = "INFO_";
+                printf("%sMAJOR=%d\n"
+                       "%sMINOR=%d\n",
+                       prefix, major(statbuf.st_dev),
+                       prefix, minor(statbuf.st_dev));
+        } else
+                printf("%d:%d\n", major(statbuf.st_dev), minor(statbuf.st_dev));
+        return 0;
+}
+
+static int export_devices(struct udev *udev)
+{
+        struct udev_enumerate *udev_enumerate;
+        struct udev_list_entry *list_entry;
+
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_scan_devices(udev_enumerate);
+        udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
+                struct udev_device *device;
+
+                device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
+                if (device != NULL) {
+                        print_record(device);
+                        udev_device_unref(device);
+                }
+        }
+        udev_enumerate_unref(udev_enumerate);
+        return 0;
+}
+
+static void cleanup_dir(DIR *dir, mode_t mask, int depth)
+{
+        struct dirent *dent;
+
+        if (depth <= 0)
+                return;
+
+        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                struct stat stats;
+
+                if (dent->d_name[0] == '.')
+                        continue;
+                if (fstatat(dirfd(dir), dent->d_name, &stats, AT_SYMLINK_NOFOLLOW) != 0)
+                        continue;
+                if ((stats.st_mode & mask) != 0)
+                        continue;
+                if (S_ISDIR(stats.st_mode)) {
+                        DIR *dir2;
+
+                        dir2 = fdopendir(openat(dirfd(dir), dent->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC));
+                        if (dir2 != NULL) {
+                                cleanup_dir(dir2, mask, depth-1);
+                                closedir(dir2);
+                        }
+                        unlinkat(dirfd(dir), dent->d_name, AT_REMOVEDIR);
+                } else {
+                        unlinkat(dirfd(dir), dent->d_name, 0);
+                }
+        }
+}
+
+static void cleanup_db(struct udev *udev)
+{
+        DIR *dir;
+
+        unlink("/run/udev/queue.bin");
+
+        dir = opendir("/run/udev/data");
+        if (dir != NULL) {
+                cleanup_dir(dir, S_ISVTX, 1);
+                closedir(dir);
+        }
+
+        dir = opendir("/run/udev/links");
+        if (dir != NULL) {
+                cleanup_dir(dir, 0, 2);
+                closedir(dir);
+        }
+
+        dir = opendir("/run/udev/tags");
+        if (dir != NULL) {
+                cleanup_dir(dir, 0, 2);
+                closedir(dir);
+        }
+
+        dir = opendir("/run/udev/watch");
+        if (dir != NULL) {
+                cleanup_dir(dir, 0, 1);
+                closedir(dir);
+        }
+
+        dir = opendir("/run/udev/firmware-missing");
+        if (dir != NULL) {
+                cleanup_dir(dir, 0, 1);
+                closedir(dir);
+        }
+}
+
+static struct udev_device *find_device(struct udev *udev, const char *id, const char *prefix)
+{
+        char name[UTIL_PATH_SIZE];
+
+        if (prefix && !startswith(id, prefix)) {
+                util_strscpyl(name, sizeof(name), prefix, id, NULL);
+                id = name;
+        }
+
+        if (startswith(id, "/dev/")) {
+                struct stat statbuf;
+                char type;
+
+                if (stat(id, &statbuf) < 0)
+                        return NULL;
+
+                if (S_ISBLK(statbuf.st_mode))
+                        type = 'b';
+                else if (S_ISCHR(statbuf.st_mode))
+                        type = 'c';
+                else
+                        return NULL;
+
+                return udev_device_new_from_devnum(udev, type, statbuf.st_rdev);
+        } else if (startswith(id, "/sys/"))
+                return udev_device_new_from_syspath(udev, id);
+        else
+                return NULL;
+}
+
+static int uinfo(struct udev *udev, int argc, char *argv[])
+{
+        struct udev_device *device = NULL;
+        bool root = 0;
+        bool export = 0;
+        const char *export_prefix = NULL;
+        char name[UTIL_PATH_SIZE];
+        struct udev_list_entry *list_entry;
+        int rc = 0;
+
+        static const struct option options[] = {
+                { "name", required_argument, NULL, 'n' },
+                { "path", required_argument, NULL, 'p' },
+                { "query", required_argument, NULL, 'q' },
+                { "attribute-walk", no_argument, NULL, 'a' },
+                { "cleanup-db", no_argument, NULL, 'c' },
+                { "export-db", no_argument, NULL, 'e' },
+                { "root", no_argument, NULL, 'r' },
+                { "device-id-of-file", required_argument, NULL, 'd' },
+                { "export", no_argument, NULL, 'x' },
+                { "export-prefix", required_argument, NULL, 'P' },
+                { "version", no_argument, NULL, 'V' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+
+        static const char *usage =
+                "Usage: udevadm info OPTIONS\n"
+                "  --query=<type>             query device information:\n"
+                "      name                     name of device node\n"
+                "      symlink                  pointing to node\n"
+                "      path                     sys device path\n"
+                "      property                 the device properties\n"
+                "      all                      all values\n"
+                "  --path=<syspath>           sys device path used for query or attribute walk\n"
+                "  --name=<name>              node or symlink name used for query or attribute walk\n"
+                "  --root                     prepend dev directory to path names\n"
+                "  --attribute-walk           print all key matches while walking along the chain\n"
+                "                             of parent devices\n"
+                "  --device-id-of-file=<file> print major:minor of device containing this file\n"
+                "  --export                   export key/value pairs\n"
+                "  --export-prefix            export the key name with a prefix\n"
+                "  --export-db                export the content of the udev database\n"
+                "  --cleanup-db               cleanup the udev database\n"
+                "  --help\n";
+
+        enum action_type {
+                ACTION_QUERY,
+                ACTION_ATTRIBUTE_WALK,
+                ACTION_DEVICE_ID_FILE,
+        } action = ACTION_QUERY;
+
+        enum query_type {
+                QUERY_NAME,
+                QUERY_PATH,
+                QUERY_SYMLINK,
+                QUERY_PROPERTY,
+                QUERY_ALL,
+        } query = QUERY_ALL;
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'n': {
+                        if (device != NULL) {
+                                fprintf(stderr, "device already specified\n");
+                                rc = 2;
+                                goto exit;
+                        }
+
+                        device = find_device(udev, optarg, "/dev/");
+                        if (device == NULL) {
+                                fprintf(stderr, "device node not found\n");
+                                rc = 2;
+                                goto exit;
+                        }
+                        break;
+                }
+                case 'p':
+                        if (device != NULL) {
+                                fprintf(stderr, "device already specified\n");
+                                rc = 2;
+                                goto exit;
+                        }
+
+                        device = find_device(udev, optarg, "/sys");
+                        if (device == NULL) {
+                                fprintf(stderr, "syspath not found\n");
+                                rc = 2;
+                                goto exit;
+                        }
+                        break;
+                case 'q':
+                        action = ACTION_QUERY;
+                        if (strcmp(optarg, "property") == 0 || strcmp(optarg, "env") == 0) {
+                                query = QUERY_PROPERTY;
+                        } else if (strcmp(optarg, "name") == 0) {
+                                query = QUERY_NAME;
+                        } else if (strcmp(optarg, "symlink") == 0) {
+                                query = QUERY_SYMLINK;
+                        } else if (strcmp(optarg, "path") == 0) {
+                                query = QUERY_PATH;
+                        } else if (strcmp(optarg, "all") == 0) {
+                                query = QUERY_ALL;
+                        } else {
+                                fprintf(stderr, "unknown query type\n");
+                                rc = 3;
+                                goto exit;
+                        }
+                        break;
+                case 'r':
+                        root = true;
+                        break;
+                case 'd':
+                        action = ACTION_DEVICE_ID_FILE;
+                        util_strscpy(name, sizeof(name), optarg);
+                        break;
+                case 'a':
+                        action = ACTION_ATTRIBUTE_WALK;
+                        break;
+                case 'e':
+                        export_devices(udev);
+                        goto exit;
+                case 'c':
+                        cleanup_db(udev);
+                        goto exit;
+                case 'x':
+                        export = true;
+                        break;
+                case 'P':
+                        export_prefix = optarg;
+                        break;
+                case 'V':
+                        printf("%s\n", VERSION);
+                        goto exit;
+                case 'h':
+                        printf("%s\n", usage);
+                        goto exit;
+                default:
+                        rc = 1;
+                        goto exit;
+                }
+        }
+
+        switch (action) {
+        case ACTION_QUERY:
+                if (!device) {
+                        if (!argv[optind]) {
+                                fprintf(stderr, "%s\n", usage);
+                                rc = 2;
+                                goto exit;
+                        }
+                        device = find_device(udev, argv[optind], NULL);
+                        if (!device) {
+                                fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n");
+                                rc = 4;
+                                goto exit;
+                        }
+                }
+
+                switch(query) {
+                case QUERY_NAME: {
+                        const char *node = udev_device_get_devnode(device);
+
+                        if (node == NULL) {
+                                fprintf(stderr, "no device node found\n");
+                                rc = 5;
+                                goto exit;
+                        }
+
+                        if (root)
+                                printf("%s\n", udev_device_get_devnode(device));
+                        else
+                                printf("%s\n", udev_device_get_devnode(device) + strlen("/dev/"));
+                        break;
+                }
+                case QUERY_SYMLINK:
+                        list_entry = udev_device_get_devlinks_list_entry(device);
+                        while (list_entry != NULL) {
+                                if (root)
+                                        printf("%s", udev_list_entry_get_name(list_entry));
+                                else
+                                        printf("%s", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+                                list_entry = udev_list_entry_get_next(list_entry);
+                                if (list_entry != NULL)
+                                        printf(" ");
+                        }
+                        printf("\n");
+                        break;
+                case QUERY_PATH:
+                        printf("%s\n", udev_device_get_devpath(device));
+                        goto exit;
+                case QUERY_PROPERTY:
+                        list_entry = udev_device_get_properties_list_entry(device);
+                        while (list_entry != NULL) {
+                                if (export) {
+                                        const char *prefix = export_prefix;
+
+                                        if (prefix == NULL)
+                                                prefix = "";
+                                        printf("%s%s='%s'\n", prefix,
+                                               udev_list_entry_get_name(list_entry),
+                                               udev_list_entry_get_value(list_entry));
+                                } else {
+                                        printf("%s=%s\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
+                                }
+                                list_entry = udev_list_entry_get_next(list_entry);
+                        }
+                        break;
+                case QUERY_ALL:
+                        print_record(device);
+                        break;
+                default:
+                        fprintf(stderr, "unknown query type\n");
+                        break;
+                }
+                break;
+        case ACTION_ATTRIBUTE_WALK:
+                if (!device && argv[optind]) {
+                        device = find_device(udev, argv[optind], NULL);
+                        if (!device) {
+                                fprintf(stderr, "Unknown device, absolute path in /dev/ or /sys expected.\n");
+                                rc = 4;
+                                goto exit;
+                        }
+                }
+                if (!device) {
+                        fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n");
+                        rc = 4;
+                        goto exit;
+                }
+                print_device_chain(device);
+                break;
+        case ACTION_DEVICE_ID_FILE:
+                if (stat_device(name, export, export_prefix) != 0)
+                        rc = 1;
+                break;
+        }
+
+exit:
+        udev_device_unref(device);
+        return rc;
+}
+
+const struct udevadm_cmd udevadm_info = {
+        .name = "info",
+        .cmd = uinfo,
+        .help = "query sysfs or the udev database",
+};
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
new file mode 100644 (file)
index 0000000..ffa70d8
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2010 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#include <getopt.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/epoll.h>
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+#include "udev.h"
+
+static bool udev_exit;
+
+static void sig_handler(int signum)
+{
+        if (signum == SIGINT || signum == SIGTERM)
+                udev_exit = true;
+}
+
+static void print_device(struct udev_device *device, const char *source, int prop)
+{
+        struct timespec ts;
+
+        clock_gettime(CLOCK_MONOTONIC, &ts);
+        printf("%-6s[%llu.%06u] %-8s %s (%s)\n",
+               source,
+               (unsigned long long) ts.tv_sec, (unsigned int) ts.tv_nsec/1000,
+               udev_device_get_action(device),
+               udev_device_get_devpath(device),
+               udev_device_get_subsystem(device));
+        if (prop) {
+                struct udev_list_entry *list_entry;
+
+                udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
+                        printf("%s=%s\n",
+                               udev_list_entry_get_name(list_entry),
+                               udev_list_entry_get_value(list_entry));
+                printf("\n");
+        }
+}
+
+static int adm_monitor(struct udev *udev, int argc, char *argv[])
+{
+        struct sigaction act;
+        sigset_t mask;
+        int option;
+        bool prop = false;
+        bool print_kernel = false;
+        bool print_udev = false;
+        struct udev_list subsystem_match_list;
+        struct udev_list tag_match_list;
+        struct udev_monitor *udev_monitor = NULL;
+        struct udev_monitor *kernel_monitor = NULL;
+        int fd_ep = -1;
+        int fd_kernel = -1, fd_udev = -1;
+        struct epoll_event ep_kernel, ep_udev;
+        int rc = 0;
+
+        static const struct option options[] = {
+                { "property", no_argument, NULL, 'p' },
+                { "environment", no_argument, NULL, 'e' },
+                { "kernel", no_argument, NULL, 'k' },
+                { "udev", no_argument, NULL, 'u' },
+                { "subsystem-match", required_argument, NULL, 's' },
+                { "tag-match", required_argument, NULL, 't' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+
+        udev_list_init(udev, &subsystem_match_list, true);
+        udev_list_init(udev, &tag_match_list, true);
+
+        for (;;) {
+                option = getopt_long(argc, argv, "pekus:t:h", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'p':
+                case 'e':
+                        prop = true;
+                        break;
+                case 'k':
+                        print_kernel = true;
+                        break;
+                case 'u':
+                        print_udev = true;
+                        break;
+                case 's':
+                        {
+                                char subsys[UTIL_NAME_SIZE];
+                                char *devtype;
+
+                                util_strscpy(subsys, sizeof(subsys), optarg);
+                                devtype = strchr(subsys, '/');
+                                if (devtype != NULL) {
+                                        devtype[0] = '\0';
+                                        devtype++;
+                                }
+                                udev_list_entry_add(&subsystem_match_list, subsys, devtype);
+                                break;
+                        }
+                case 't':
+                        udev_list_entry_add(&tag_match_list, optarg, NULL);
+                        break;
+                case 'h':
+                        printf("Usage: udevadm monitor [--property] [--kernel] [--udev] [--help]\n"
+                               "  --property                              print the event properties\n"
+                               "  --kernel                                print kernel uevents\n"
+                               "  --udev                                  print udev events\n"
+                               "  --subsystem-match=<subsystem[/devtype]> filter events by subsystem\n"
+                               "  --tag-match=<tag>                       filter events by tag\n"
+                               "  --help\n\n");
+                        goto out;
+                default:
+                        rc = 1;
+                        goto out;
+                }
+        }
+
+        if (!print_kernel && !print_udev) {
+                print_kernel = true;
+                print_udev = true;
+        }
+
+        /* set signal handlers */
+        memset(&act, 0x00, sizeof(struct sigaction));
+        act.sa_handler = sig_handler;
+        sigemptyset(&act.sa_mask);
+        act.sa_flags = SA_RESTART;
+        sigaction(SIGINT, &act, NULL);
+        sigaction(SIGTERM, &act, NULL);
+        sigemptyset(&mask);
+        sigaddset(&mask, SIGINT);
+        sigaddset(&mask, SIGTERM);
+        sigprocmask(SIG_UNBLOCK, &mask, NULL);
+
+        fd_ep = epoll_create1(EPOLL_CLOEXEC);
+        if (fd_ep < 0) {
+                log_error("error creating epoll fd: %m\n");
+                goto out;
+        }
+
+        printf("monitor will print the received events for:\n");
+        if (print_udev) {
+                struct udev_list_entry *entry;
+
+                udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
+                if (udev_monitor == NULL) {
+                        fprintf(stderr, "error: unable to create netlink socket\n");
+                        rc = 1;
+                        goto out;
+                }
+                udev_monitor_set_receive_buffer_size(udev_monitor, 128*1024*1024);
+                fd_udev = udev_monitor_get_fd(udev_monitor);
+
+                udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) {
+                        const char *subsys = udev_list_entry_get_name(entry);
+                        const char *devtype = udev_list_entry_get_value(entry);
+
+                        if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsys, devtype) < 0)
+                                fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys);
+                }
+
+                udev_list_entry_foreach(entry, udev_list_get_entry(&tag_match_list)) {
+                        const char *tag = udev_list_entry_get_name(entry);
+
+                        if (udev_monitor_filter_add_match_tag(udev_monitor, tag) < 0)
+                                fprintf(stderr, "error: unable to apply tag filter '%s'\n", tag);
+                }
+
+                if (udev_monitor_enable_receiving(udev_monitor) < 0) {
+                        fprintf(stderr, "error: unable to subscribe to udev events\n");
+                        rc = 2;
+                        goto out;
+                }
+
+                memset(&ep_udev, 0, sizeof(struct epoll_event));
+                ep_udev.events = EPOLLIN;
+                ep_udev.data.fd = fd_udev;
+                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
+                        log_error("fail to add fd to epoll: %m\n");
+                        goto out;
+                }
+
+                printf("UDEV - the event which udev sends out after rule processing\n");
+        }
+
+        if (print_kernel) {
+                struct udev_list_entry *entry;
+
+                kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel");
+                if (kernel_monitor == NULL) {
+                        fprintf(stderr, "error: unable to create netlink socket\n");
+                        rc = 3;
+                        goto out;
+                }
+                udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024);
+                fd_kernel = udev_monitor_get_fd(kernel_monitor);
+
+                udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) {
+                        const char *subsys = udev_list_entry_get_name(entry);
+
+                        if (udev_monitor_filter_add_match_subsystem_devtype(kernel_monitor, subsys, NULL) < 0)
+                                fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys);
+                }
+
+                if (udev_monitor_enable_receiving(kernel_monitor) < 0) {
+                        fprintf(stderr, "error: unable to subscribe to kernel events\n");
+                        rc = 4;
+                        goto out;
+                }
+
+                memset(&ep_kernel, 0, sizeof(struct epoll_event));
+                ep_kernel.events = EPOLLIN;
+                ep_kernel.data.fd = fd_kernel;
+                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_kernel, &ep_kernel) < 0) {
+                        log_error("fail to add fd to epoll: %m\n");
+                        goto out;
+                }
+
+                printf("KERNEL - the kernel uevent\n");
+        }
+        printf("\n");
+
+        while (!udev_exit) {
+                int fdcount;
+                struct epoll_event ev[4];
+                int i;
+
+                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
+                if (fdcount < 0) {
+                        if (errno != EINTR)
+                                fprintf(stderr, "error receiving uevent message: %m\n");
+                        continue;
+                }
+
+                for (i = 0; i < fdcount; i++) {
+                        if (ev[i].data.fd == fd_kernel && ev[i].events & EPOLLIN) {
+                                struct udev_device *device;
+
+                                device = udev_monitor_receive_device(kernel_monitor);
+                                if (device == NULL)
+                                        continue;
+                                print_device(device, "KERNEL", prop);
+                                udev_device_unref(device);
+                        } else if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
+                                struct udev_device *device;
+
+                                device = udev_monitor_receive_device(udev_monitor);
+                                if (device == NULL)
+                                        continue;
+                                print_device(device, "UDEV", prop);
+                                udev_device_unref(device);
+                        }
+                }
+        }
+out:
+        if (fd_ep >= 0)
+                close(fd_ep);
+        udev_monitor_unref(udev_monitor);
+        udev_monitor_unref(kernel_monitor);
+        udev_list_cleanup(&subsystem_match_list);
+        udev_list_cleanup(&tag_match_list);
+        return rc;
+}
+
+const struct udevadm_cmd udevadm_monitor = {
+        .name = "monitor",
+        .cmd = adm_monitor,
+        .help = "listen to kernel and udev events",
+};
diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c
new file mode 100644 (file)
index 0000000..c4fc4ee
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2006-2009 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2009 Canonical Ltd.
+ * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/inotify.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "udev.h"
+
+static int adm_settle(struct udev *udev, int argc, char *argv[])
+{
+        static const struct option options[] = {
+                { "seq-start", required_argument, NULL, 's' },
+                { "seq-end", required_argument, NULL, 'e' },
+                { "timeout", required_argument, NULL, 't' },
+                { "exit-if-exists", required_argument, NULL, 'E' },
+                { "quiet", no_argument, NULL, 'q' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+        usec_t start_usec = now(CLOCK_MONOTONIC);
+        usec_t start = 0;
+        usec_t end = 0;
+        int quiet = 0;
+        const char *exists = NULL;
+        unsigned int timeout = 120;
+        struct pollfd pfd[1] = { {.fd = -1}, };
+        struct udev_queue *udev_queue = NULL;
+        int rc = EXIT_FAILURE;
+
+        for (;;) {
+                int option;
+                int seconds;
+
+                option = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 's':
+                        start = strtoull(optarg, NULL, 0);
+                        break;
+                case 'e':
+                        end = strtoull(optarg, NULL, 0);
+                        break;
+                case 't':
+                        seconds = atoi(optarg);
+                        if (seconds >= 0)
+                                timeout = seconds;
+                        else
+                                fprintf(stderr, "invalid timeout value\n");
+                        break;
+                case 'q':
+                        quiet = 1;
+                        break;
+                case 'E':
+                        exists = optarg;
+                        break;
+                case 'h':
+                        printf("Usage: udevadm settle OPTIONS\n"
+                               "  --timeout=<seconds>     maximum time to wait for events\n"
+                               "  --seq-start=<seqnum>    first seqnum to wait for\n"
+                               "  --seq-end=<seqnum>      last seqnum to wait for\n"
+                               "  --exit-if-exists=<file> stop waiting if file exists\n"
+                               "  --quiet                 do not print list after timeout\n"
+                               "  --help\n\n");
+                        exit(EXIT_SUCCESS);
+                default:
+                        exit(EXIT_FAILURE);
+                }
+        }
+
+        udev_queue = udev_queue_new(udev);
+        if (udev_queue == NULL)
+                exit(2);
+
+        if (start > 0) {
+                unsigned long long kernel_seq;
+
+                kernel_seq = udev_queue_get_kernel_seqnum(udev_queue);
+
+                /* unless specified, the last event is the current kernel seqnum */
+                if (end == 0)
+                        end = udev_queue_get_kernel_seqnum(udev_queue);
+
+                if (start > end) {
+                        log_error("seq-start larger than seq-end, ignoring\n");
+                        start = 0;
+                        end = 0;
+                }
+
+                if (start > kernel_seq || end > kernel_seq) {
+                        log_error("seq-start or seq-end larger than current kernel value, ignoring\n");
+                        start = 0;
+                        end = 0;
+                }
+                log_debug("start=%llu end=%llu current=%llu\n", (unsigned long long)start, (unsigned long long)end, kernel_seq);
+        } else {
+                if (end > 0) {
+                        log_error("seq-end needs seq-start parameter, ignoring\n");
+                        end = 0;
+                }
+        }
+
+        /* guarantee that the udev daemon isn't pre-processing */
+        if (getuid() == 0) {
+                struct udev_ctrl *uctrl;
+
+                uctrl = udev_ctrl_new(udev);
+                if (uctrl != NULL) {
+                        if (udev_ctrl_send_ping(uctrl, timeout) < 0) {
+                                log_debug("no connection to daemon\n");
+                                udev_ctrl_unref(uctrl);
+                                rc = EXIT_SUCCESS;
+                                goto out;
+                        }
+                        udev_ctrl_unref(uctrl);
+                }
+        }
+
+        pfd[0].events = POLLIN;
+        pfd[0].fd = inotify_init1(IN_CLOEXEC);
+        if (pfd[0].fd < 0) {
+                log_error("inotify_init failed: %m\n");
+        } else {
+                if (inotify_add_watch(pfd[0].fd, "/run/udev" , IN_MOVED_TO) < 0) {
+                        log_error("watching /run/udev failed\n");
+                        close(pfd[0].fd);
+                        pfd[0].fd = -1;
+                }
+        }
+
+        for (;;) {
+                struct stat statbuf;
+
+                if (exists != NULL && stat(exists, &statbuf) == 0) {
+                        rc = EXIT_SUCCESS;
+                        break;
+                }
+
+                if (start > 0) {
+                        /* if asked for, wait for a specific sequence of events */
+                        if (udev_queue_get_seqnum_sequence_is_finished(udev_queue, start, end) == 1) {
+                                rc = EXIT_SUCCESS;
+                                break;
+                        }
+                } else {
+                        /* exit if queue is empty */
+                        if (udev_queue_get_queue_is_empty(udev_queue)) {
+                                rc = EXIT_SUCCESS;
+                                break;
+                        }
+                }
+
+                if (pfd[0].fd >= 0) {
+                        int delay;
+
+                        if (exists != NULL || start > 0)
+                                delay = 100;
+                        else
+                                delay = 1000;
+                        /* wake up after delay, or immediately after the queue is rebuilt */
+                        if (poll(pfd, 1, delay) > 0 && pfd[0].revents & POLLIN) {
+                                char buf[sizeof(struct inotify_event) + PATH_MAX];
+
+                                read(pfd[0].fd, buf, sizeof(buf));
+                        }
+                } else {
+                        sleep(1);
+                }
+
+                if (timeout > 0) {
+                        usec_t age_usec;
+
+                        age_usec = now(CLOCK_MONOTONIC) - start_usec;
+                        if (age_usec / (1000 * 1000) >= timeout) {
+                                struct udev_list_entry *list_entry;
+
+                                if (!quiet && udev_queue_get_queued_list_entry(udev_queue) != NULL) {
+                                        log_debug("timeout waiting for udev queue\n");
+                                        printf("\nudevadm settle - timeout of %i seconds reached, the event queue contains:\n", timeout);
+                                        udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
+                                                printf("  %s (%s)\n",
+                                                udev_list_entry_get_name(list_entry),
+                                                udev_list_entry_get_value(list_entry));
+                                }
+
+                                break;
+                        }
+                }
+        }
+out:
+        if (pfd[0].fd >= 0)
+                close(pfd[0].fd);
+        udev_queue_unref(udev_queue);
+        return rc;
+}
+
+const struct udevadm_cmd udevadm_settle = {
+        .name = "settle",
+        .cmd = adm_settle,
+        .help = "wait for the event queue to finish",
+};
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
new file mode 100644 (file)
index 0000000..9853d83
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2011 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/inotify.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "udev.h"
+
+static void help(struct udev *udev)
+{
+        fprintf(stderr, "\n");
+        fprintf(stderr, "Usage: udevadm builtin [--help] <command> <syspath>\n");
+        udev_builtin_list(udev);
+        fprintf(stderr, "\n");
+}
+
+static int adm_builtin(struct udev *udev, int argc, char *argv[])
+{
+        static const struct option options[] = {
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+        char *command = NULL;
+        char *syspath = NULL;
+        char filename[UTIL_PATH_SIZE];
+        struct udev_device *dev = NULL;
+        enum udev_builtin_cmd cmd;
+        int rc = EXIT_SUCCESS;
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "h", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'h':
+                        help(udev);
+                        goto out;
+                }
+        }
+
+        command = argv[optind++];
+        if (command == NULL) {
+                fprintf(stderr, "command missing\n");
+                help(udev);
+                rc = 2;
+                goto out;
+        }
+
+        syspath = argv[optind++];
+        if (syspath == NULL) {
+                fprintf(stderr, "syspath missing\n\n");
+                rc = 3;
+                goto out;
+        }
+
+        udev_builtin_init(udev);
+
+        cmd = udev_builtin_lookup(command);
+        if (cmd >= UDEV_BUILTIN_MAX) {
+                fprintf(stderr, "unknown command '%s'\n", command);
+                help(udev);
+                rc = 5;
+                goto out;
+        }
+
+        /* add /sys if needed */
+        if (!startswith(syspath, "/sys"))
+                util_strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
+        else
+                util_strscpy(filename, sizeof(filename), syspath);
+        util_remove_trailing_chars(filename, '/');
+
+        dev = udev_device_new_from_syspath(udev, filename);
+        if (dev == NULL) {
+                fprintf(stderr, "unable to open device '%s'\n\n", filename);
+                rc = 4;
+                goto out;
+        }
+
+        rc = udev_builtin_run(dev, cmd, command, true);
+        if (rc < 0) {
+                fprintf(stderr, "error executing '%s', exit code %i\n\n", command, rc);
+                rc = 6;
+        }
+out:
+        udev_device_unref(dev);
+        udev_builtin_exit(udev);
+        return rc;
+}
+
+const struct udevadm_cmd udevadm_test_builtin = {
+        .name = "test-builtin",
+        .cmd = adm_builtin,
+        .help = "test a built-in command",
+        .debug = true,
+};
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
new file mode 100644 (file)
index 0000000..2d8aa79
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2004-2008 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <sys/signalfd.h>
+
+#include "udev.h"
+
+static int adm_test(struct udev *udev, int argc, char *argv[])
+{
+        int resolve_names = 1;
+        char filename[UTIL_PATH_SIZE];
+        const char *action = "add";
+        const char *syspath = NULL;
+        struct udev_event *event = NULL;
+        struct udev_device *dev = NULL;
+        struct udev_rules *rules = NULL;
+        struct udev_list_entry *entry;
+        sigset_t mask, sigmask_orig;
+        int err;
+        int rc = 0;
+
+        static const struct option options[] = {
+                { "action", required_argument, NULL, 'a' },
+                { "resolve-names", required_argument, NULL, 'N' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+
+        log_debug("version %s\n", VERSION);
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "a:s:N:fh", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'a':
+                        action = optarg;
+                        break;
+                case 'N':
+                        if (strcmp (optarg, "early") == 0) {
+                                resolve_names = 1;
+                        } else if (strcmp (optarg, "late") == 0) {
+                                resolve_names = 0;
+                        } else if (strcmp (optarg, "never") == 0) {
+                                resolve_names = -1;
+                        } else {
+                                fprintf(stderr, "resolve-names must be early, late or never\n");
+                                log_error("resolve-names must be early, late or never\n");
+                                exit(EXIT_FAILURE);
+                        }
+                        break;
+                case 'h':
+                        printf("Usage: udevadm test OPTIONS <syspath>\n"
+                               "  --action=<string>     set action string\n"
+                               "  --help\n\n");
+                        exit(EXIT_SUCCESS);
+                default:
+                        exit(EXIT_FAILURE);
+                }
+        }
+        syspath = argv[optind];
+
+        if (syspath == NULL) {
+                fprintf(stderr, "syspath parameter missing\n");
+                rc = 2;
+                goto out;
+        }
+
+        printf("This program is for debugging only, it does not run any program\n"
+               "specified by a RUN key. It may show incorrect results, because\n"
+               "some values may be different, or not available at a simulation run.\n"
+               "\n");
+
+        sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);
+
+        udev_builtin_init(udev);
+
+        rules = udev_rules_new(udev, resolve_names);
+        if (rules == NULL) {
+                fprintf(stderr, "error reading rules\n");
+                rc = 3;
+                goto out;
+        }
+
+        /* add /sys if needed */
+        if (!startswith(syspath, "/sys"))
+                util_strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
+        else
+                util_strscpy(filename, sizeof(filename), syspath);
+        util_remove_trailing_chars(filename, '/');
+
+        dev = udev_device_new_from_syspath(udev, filename);
+        if (dev == NULL) {
+                fprintf(stderr, "unable to open device '%s'\n", filename);
+                rc = 4;
+                goto out;
+        }
+
+        /* skip reading of db, but read kernel parameters */
+        udev_device_set_info_loaded(dev);
+        udev_device_read_uevent_file(dev);
+
+        udev_device_set_action(dev, action);
+        event = udev_event_new(dev);
+
+        sigfillset(&mask);
+        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
+        event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (event->fd_signal < 0) {
+                fprintf(stderr, "error creating signalfd\n");
+                rc = 5;
+                goto out;
+        }
+
+        err = udev_event_execute_rules(event, rules, &sigmask_orig);
+
+        udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
+                printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
+
+        if (err == 0) {
+                udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) {
+                        char program[UTIL_PATH_SIZE];
+
+                        udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program));
+                        printf("run: '%s'\n", program);
+                }
+        }
+out:
+        if (event != NULL && event->fd_signal >= 0)
+                close(event->fd_signal);
+        udev_event_unref(event);
+        udev_device_unref(dev);
+        udev_rules_unref(rules);
+        udev_builtin_exit(udev);
+        return rc;
+}
+
+const struct udevadm_cmd udevadm_test = {
+        .name = "test",
+        .cmd = adm_test,
+        .help = "test an event run",
+        .debug = true,
+};
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
new file mode 100644 (file)
index 0000000..d52ae46
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stddef.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 <fnmatch.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "udev.h"
+
+static int verbose;
+static int dry_run;
+
+static void exec_list(struct udev_enumerate *udev_enumerate, const char *action)
+{
+        struct udev_list_entry *entry;
+
+        udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(udev_enumerate)) {
+                char filename[UTIL_PATH_SIZE];
+                int fd;
+
+                if (verbose)
+                        printf("%s\n", udev_list_entry_get_name(entry));
+                if (dry_run)
+                        continue;
+                util_strscpyl(filename, sizeof(filename), udev_list_entry_get_name(entry), "/uevent", NULL);
+                fd = open(filename, O_WRONLY);
+                if (fd < 0)
+                        continue;
+                if (write(fd, action, strlen(action)) < 0)
+                        log_debug("error writing '%s' to '%s': %m\n", action, filename);
+                close(fd);
+        }
+}
+
+static const char *keyval(const char *str, const char **val, char *buf, size_t size)
+{
+        char *pos;
+
+        util_strscpy(buf, size,str);
+        pos = strchr(buf, '=');
+        if (pos != NULL) {
+                pos[0] = 0;
+                pos++;
+        }
+        *val = pos;
+        return buf;
+}
+
+static int adm_trigger(struct udev *udev, int argc, char *argv[])
+{
+        static const struct option options[] = {
+                { "verbose", no_argument, NULL, 'v' },
+                { "dry-run", no_argument, NULL, 'n' },
+                { "type", required_argument, NULL, 't' },
+                { "action", required_argument, NULL, 'c' },
+                { "subsystem-match", required_argument, NULL, 's' },
+                { "subsystem-nomatch", required_argument, NULL, 'S' },
+                { "attr-match", required_argument, NULL, 'a' },
+                { "attr-nomatch", required_argument, NULL, 'A' },
+                { "property-match", required_argument, NULL, 'p' },
+                { "tag-match", required_argument, NULL, 'g' },
+                { "sysname-match", required_argument, NULL, 'y' },
+                { "parent-match", required_argument, NULL, 'b' },
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+        enum {
+                TYPE_DEVICES,
+                TYPE_SUBSYSTEMS,
+        } device_type = TYPE_DEVICES;
+        const char *action = "change";
+        struct udev_enumerate *udev_enumerate;
+        int rc = 0;
+
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL) {
+                rc = 1;
+                goto exit;
+        }
+
+        for (;;) {
+                int option;
+                const char *key;
+                const char *val;
+                char buf[UTIL_PATH_SIZE];
+
+                option = getopt_long(argc, argv, "vng:o:t:hc:p:s:S:a:A:y:b:", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'v':
+                        verbose = 1;
+                        break;
+                case 'n':
+                        dry_run = 1;
+                        break;
+                case 't':
+                        if (strcmp(optarg, "devices") == 0) {
+                                device_type = TYPE_DEVICES;
+                        } else if (strcmp(optarg, "subsystems") == 0) {
+                                device_type = TYPE_SUBSYSTEMS;
+                        } else {
+                                log_error("unknown type --type=%s\n", optarg);
+                                rc = 2;
+                                goto exit;
+                        }
+                        break;
+                case 'c':
+                        action = optarg;
+                        break;
+                case 's':
+                        udev_enumerate_add_match_subsystem(udev_enumerate, optarg);
+                        break;
+                case 'S':
+                        udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg);
+                        break;
+                case 'a':
+                        key = keyval(optarg, &val, buf, sizeof(buf));
+                        udev_enumerate_add_match_sysattr(udev_enumerate, key, val);
+                        break;
+                case 'A':
+                        key = keyval(optarg, &val, buf, sizeof(buf));
+                        udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val);
+                        break;
+                case 'p':
+                        key = keyval(optarg, &val, buf, sizeof(buf));
+                        udev_enumerate_add_match_property(udev_enumerate, key, val);
+                        break;
+                case 'g':
+                        udev_enumerate_add_match_tag(udev_enumerate, optarg);
+                        break;
+                case 'y':
+                        udev_enumerate_add_match_sysname(udev_enumerate, optarg);
+                        break;
+                case 'b': {
+                        char path[UTIL_PATH_SIZE];
+                        struct udev_device *dev;
+
+                        /* add sys dir if needed */
+                        if (!startswith(optarg, "/sys"))
+                                util_strscpyl(path, sizeof(path), "/sys", optarg, NULL);
+                        else
+                                util_strscpy(path, sizeof(path), optarg);
+                        util_remove_trailing_chars(path, '/');
+                        dev = udev_device_new_from_syspath(udev, path);
+                        if (dev == NULL) {
+                                log_error("unable to open the device '%s'\n", optarg);
+                                rc = 2;
+                                goto exit;
+                        }
+                        udev_enumerate_add_match_parent(udev_enumerate, dev);
+                        /* drop reference immediately, enumerate pins the device as long as needed */
+                        udev_device_unref(dev);
+                        break;
+                }
+                case 'h':
+                        printf("Usage: udevadm trigger OPTIONS\n"
+                               "  --verbose                       print the list of devices while running\n"
+                               "  --dry-run                       do not actually trigger the events\n"
+                               "  --type=                         type of events to trigger\n"
+                               "      devices                       sys devices (default)\n"
+                               "      subsystems                    sys subsystems and drivers\n"
+                               "  --action=<action>               event action value, default is \"change\"\n"
+                               "  --subsystem-match=<subsystem>   trigger devices from a matching subsystem\n"
+                               "  --subsystem-nomatch=<subsystem> exclude devices from a matching subsystem\n"
+                               "  --attr-match=<file[=<value>]>   trigger devices with a matching attribute\n"
+                               "  --attr-nomatch=<file[=<value>]> exclude devices with a matching attribute\n"
+                               "  --property-match=<key>=<value>  trigger devices with a matching property\n"
+                               "  --tag-match=<key>=<value>       trigger devices with a matching property\n"
+                               "  --sysname-match=<name>          trigger devices with a matching name\n"
+                               "  --parent-match=<name>           trigger devices with that parent device\n"
+                               "  --help\n\n");
+                        goto exit;
+                default:
+                        rc = 1;
+                        goto exit;
+                }
+        }
+
+        switch (device_type) {
+        case TYPE_SUBSYSTEMS:
+                udev_enumerate_scan_subsystems(udev_enumerate);
+                exec_list(udev_enumerate, action);
+                goto exit;
+        case TYPE_DEVICES:
+                udev_enumerate_scan_devices(udev_enumerate);
+                exec_list(udev_enumerate, action);
+                goto exit;
+        default:
+                goto exit;
+        }
+exit:
+        udev_enumerate_unref(udev_enumerate);
+        return rc;
+}
+
+const struct udevadm_cmd udevadm_trigger = {
+        .name = "trigger",
+        .cmd = adm_trigger,
+        .help = "request events from the kernel",
+};
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
new file mode 100644 (file)
index 0000000..53419ff
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2007-2012 Kay Sievers <kay@vrfy.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
+#include "udev.h"
+
+void udev_main_log(struct udev *udev, int priority,
+                   const char *file, int line, const char *fn,
+                   const char *format, va_list args)
+{
+        log_metav(priority, file, line, fn, format, args);
+}
+
+static int adm_version(struct udev *udev, int argc, char *argv[])
+{
+        printf("%s\n", VERSION);
+        return 0;
+}
+
+static const struct udevadm_cmd udevadm_version = {
+        .name = "version",
+        .cmd = adm_version,
+};
+
+static int adm_help(struct udev *udev, int argc, char *argv[]);
+
+static const struct udevadm_cmd udevadm_help = {
+        .name = "help",
+        .cmd = adm_help,
+};
+
+static const struct udevadm_cmd *udevadm_cmds[] = {
+        &udevadm_info,
+        &udevadm_trigger,
+        &udevadm_settle,
+        &udevadm_control,
+        &udevadm_monitor,
+        &udevadm_hwdb,
+        &udevadm_test,
+        &udevadm_test_builtin,
+        &udevadm_version,
+        &udevadm_help,
+};
+
+static int adm_help(struct udev *udev, int argc, char *argv[])
+{
+        unsigned int i;
+
+        fprintf(stderr, "Usage: udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n");
+        for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
+                if (udevadm_cmds[i]->help != NULL)
+                        printf("  %-12s %s\n", udevadm_cmds[i]->name, udevadm_cmds[i]->help);
+        fprintf(stderr, "\n");
+        return 0;
+}
+
+static int run_command(struct udev *udev, const struct udevadm_cmd *cmd, int argc, char *argv[])
+{
+        if (cmd->debug)
+                log_set_max_level(LOG_DEBUG);
+        log_debug("calling: %s\n", cmd->name);
+        return cmd->cmd(udev, argc, argv);
+}
+
+int main(int argc, char *argv[])
+{
+        struct udev *udev;
+        static const struct option options[] = {
+                { "debug", no_argument, NULL, 'd' },
+                { "help", no_argument, NULL, 'h' },
+                { "version", no_argument, NULL, 'V' },
+                {}
+        };
+        const char *command;
+        unsigned int i;
+        int rc = 1;
+
+        udev = udev_new();
+        if (udev == NULL)
+                goto out;
+
+        log_parse_environment();
+        log_open();
+        udev_set_log_fn(udev, udev_main_log);
+        label_init("/dev");
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "+dhV", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'd':
+                        log_set_max_level(LOG_DEBUG);
+                        udev_set_log_priority(udev, LOG_DEBUG);
+                        break;
+                case 'h':
+                        rc = adm_help(udev, argc, argv);
+                        goto out;
+                case 'V':
+                        rc = adm_version(udev, argc, argv);
+                        goto out;
+                default:
+                        goto out;
+                }
+        }
+        command = argv[optind];
+
+        if (command != NULL)
+                for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) {
+                        if (strcmp(udevadm_cmds[i]->name, command) == 0) {
+                                argc -= optind;
+                                argv += optind;
+                                /* we need '0' here to reset the internal state */
+                                optind = 0;
+                                rc = run_command(udev, udevadm_cmds[i], argc, argv);
+                                goto out;
+                        }
+                }
+
+        fprintf(stderr, "missing or unknown command\n\n");
+        adm_help(udev, argc, argv);
+        rc = 2;
+out:
+        label_finish();
+        udev_unref(udev);
+        log_close();
+        return rc;
+}
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
new file mode 100644 (file)
index 0000000..ffc48a0
--- /dev/null
@@ -0,0 +1,1578 @@
+/*
+ * Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
+ * Copyright (C) 2009 Canonical Ltd.
+ * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stddef.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <time.h>
+#include <getopt.h>
+#include <dirent.h>
+#include <sys/time.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/signalfd.h>
+#include <sys/epoll.h>
+#include <sys/poll.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/inotify.h>
+#include <sys/utsname.h>
+
+#include "udev.h"
+#include "sd-daemon.h"
+#include "cgroup-util.h"
+#include "dev-setup.h"
+
+static bool debug;
+
+void udev_main_log(struct udev *udev, int priority,
+                   const char *file, int line, const char *fn,
+                   const char *format, va_list args)
+{
+        log_metav(priority, file, line, fn, format, args);
+}
+
+static struct udev_rules *rules;
+static struct udev_queue_export *udev_queue_export;
+static struct udev_ctrl *udev_ctrl;
+static struct udev_monitor *monitor;
+static int worker_watch[2] = { -1, -1 };
+static int fd_signal = -1;
+static int fd_ep = -1;
+static int fd_inotify = -1;
+static bool stop_exec_queue;
+static bool reload;
+static int children;
+static int children_max;
+static int exec_delay;
+static sigset_t sigmask_orig;
+static UDEV_LIST(event_list);
+static UDEV_LIST(worker_list);
+char *udev_cgroup;
+static bool udev_exit;
+
+enum event_state {
+        EVENT_UNDEF,
+        EVENT_QUEUED,
+        EVENT_RUNNING,
+};
+
+struct event {
+        struct udev_list_node node;
+        struct udev *udev;
+        struct udev_device *dev;
+        enum event_state state;
+        int exitcode;
+        unsigned long long int delaying_seqnum;
+        unsigned long long int seqnum;
+        const char *devpath;
+        size_t devpath_len;
+        const char *devpath_old;
+        dev_t devnum;
+        int ifindex;
+        bool is_block;
+        bool nodelay;
+};
+
+static inline struct event *node_to_event(struct udev_list_node *node)
+{
+        return container_of(node, struct event, node);
+}
+
+static void event_queue_cleanup(struct udev *udev, enum event_state type);
+
+enum worker_state {
+        WORKER_UNDEF,
+        WORKER_RUNNING,
+        WORKER_IDLE,
+        WORKER_KILLED,
+};
+
+struct worker {
+        struct udev_list_node node;
+        struct udev *udev;
+        int refcount;
+        pid_t pid;
+        struct udev_monitor *monitor;
+        enum worker_state state;
+        struct event *event;
+        usec_t event_start_usec;
+};
+
+/* passed from worker to main process */
+struct worker_message {
+        pid_t pid;
+        int exitcode;
+};
+
+static inline struct worker *node_to_worker(struct udev_list_node *node)
+{
+        return container_of(node, struct worker, node);
+}
+
+static void event_queue_delete(struct event *event, bool export)
+{
+        udev_list_node_remove(&event->node);
+
+        if (export) {
+                udev_queue_export_device_finished(udev_queue_export, event->dev);
+                log_debug("seq %llu done with %i\n", udev_device_get_seqnum(event->dev), event->exitcode);
+        }
+        udev_device_unref(event->dev);
+        free(event);
+}
+
+static struct worker *worker_ref(struct worker *worker)
+{
+        worker->refcount++;
+        return worker;
+}
+
+static void worker_cleanup(struct worker *worker)
+{
+        udev_list_node_remove(&worker->node);
+        udev_monitor_unref(worker->monitor);
+        children--;
+        free(worker);
+}
+
+static void worker_unref(struct worker *worker)
+{
+        worker->refcount--;
+        if (worker->refcount > 0)
+                return;
+        log_debug("worker [%u] cleaned up\n", worker->pid);
+        worker_cleanup(worker);
+}
+
+static void worker_list_cleanup(struct udev *udev)
+{
+        struct udev_list_node *loop, *tmp;
+
+        udev_list_node_foreach_safe(loop, tmp, &worker_list) {
+                struct worker *worker = node_to_worker(loop);
+
+                worker_cleanup(worker);
+        }
+}
+
+static void worker_new(struct event *event)
+{
+        struct udev *udev = event->udev;
+        struct worker *worker;
+        struct udev_monitor *worker_monitor;
+        pid_t pid;
+
+        /* listen for new events */
+        worker_monitor = udev_monitor_new_from_netlink(udev, NULL);
+        if (worker_monitor == NULL)
+                return;
+        /* allow the main daemon netlink address to send devices to the worker */
+        udev_monitor_allow_unicast_sender(worker_monitor, monitor);
+        udev_monitor_enable_receiving(worker_monitor);
+
+        worker = calloc(1, sizeof(struct worker));
+        if (worker == NULL) {
+                udev_monitor_unref(worker_monitor);
+                return;
+        }
+        /* worker + event reference */
+        worker->refcount = 2;
+        worker->udev = udev;
+
+        pid = fork();
+        switch (pid) {
+        case 0: {
+                struct udev_device *dev = NULL;
+                int fd_monitor;
+                struct epoll_event ep_signal, ep_monitor;
+                sigset_t mask;
+                int rc = EXIT_SUCCESS;
+
+                /* take initial device from queue */
+                dev = event->dev;
+                event->dev = NULL;
+
+                free(worker);
+                worker_list_cleanup(udev);
+                event_queue_cleanup(udev, EVENT_UNDEF);
+                udev_queue_export_unref(udev_queue_export);
+                udev_monitor_unref(monitor);
+                udev_ctrl_unref(udev_ctrl);
+                close(fd_signal);
+                close(fd_ep);
+                close(worker_watch[READ_END]);
+
+                sigfillset(&mask);
+                fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+                if (fd_signal < 0) {
+                        log_error("error creating signalfd %m\n");
+                        rc = 2;
+                        goto out;
+                }
+
+                fd_ep = epoll_create1(EPOLL_CLOEXEC);
+                if (fd_ep < 0) {
+                        log_error("error creating epoll fd: %m\n");
+                        rc = 3;
+                        goto out;
+                }
+
+                memset(&ep_signal, 0, sizeof(struct epoll_event));
+                ep_signal.events = EPOLLIN;
+                ep_signal.data.fd = fd_signal;
+
+                fd_monitor = udev_monitor_get_fd(worker_monitor);
+                memset(&ep_monitor, 0, sizeof(struct epoll_event));
+                ep_monitor.events = EPOLLIN;
+                ep_monitor.data.fd = fd_monitor;
+
+                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
+                    epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_monitor, &ep_monitor) < 0) {
+                        log_error("fail to add fds to epoll: %m\n");
+                        rc = 4;
+                        goto out;
+                }
+
+                /* request TERM signal if parent exits */
+                prctl(PR_SET_PDEATHSIG, SIGTERM);
+
+                /* reset OOM score, we only protect the main daemon */
+                write_one_line_file("/proc/self/oom_score_adj", "0");
+
+                for (;;) {
+                        struct udev_event *udev_event;
+                        struct worker_message msg;
+                        int err;
+
+                        log_debug("seq %llu running\n", udev_device_get_seqnum(dev));
+                        udev_event = udev_event_new(dev);
+                        if (udev_event == NULL) {
+                                rc = 5;
+                                goto out;
+                        }
+
+                        /* needed for SIGCHLD/SIGTERM in spawn() */
+                        udev_event->fd_signal = fd_signal;
+
+                        if (exec_delay > 0)
+                                udev_event->exec_delay = exec_delay;
+
+                        /* apply rules, create node, symlinks */
+                        err = udev_event_execute_rules(udev_event, rules, &sigmask_orig);
+
+                        if (err == 0)
+                                udev_event_execute_run(udev_event, &sigmask_orig);
+
+                        /* apply/restore inotify watch */
+                        if (err == 0 && udev_event->inotify_watch) {
+                                udev_watch_begin(udev, dev);
+                                udev_device_update_db(dev);
+                        }
+
+                        /* send processed event back to libudev listeners */
+                        udev_monitor_send_device(worker_monitor, NULL, dev);
+
+                        /* send udevd the result of the event execution */
+                        memset(&msg, 0, sizeof(struct worker_message));
+                        if (err != 0)
+                                msg.exitcode = err;
+                        msg.pid = getpid();
+                        send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0);
+
+                        log_debug("seq %llu processed with %i\n", udev_device_get_seqnum(dev), err);
+
+                        udev_device_unref(dev);
+                        dev = NULL;
+
+                        if (udev_event->sigterm) {
+                                udev_event_unref(udev_event);
+                                goto out;
+                        }
+
+                        udev_event_unref(udev_event);
+
+                        /* wait for more device messages from main udevd, or term signal */
+                        while (dev == NULL) {
+                                struct epoll_event ev[4];
+                                int fdcount;
+                                int i;
+
+                                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
+                                if (fdcount < 0) {
+                                        if (errno == EINTR)
+                                                continue;
+                                        log_error("failed to poll: %m\n");
+                                        goto out;
+                                }
+
+                                for (i = 0; i < fdcount; i++) {
+                                        if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLIN) {
+                                                dev = udev_monitor_receive_device(worker_monitor);
+                                                break;
+                                        } else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN) {
+                                                struct signalfd_siginfo fdsi;
+                                                ssize_t size;
+
+                                                size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
+                                                if (size != sizeof(struct signalfd_siginfo))
+                                                        continue;
+                                                switch (fdsi.ssi_signo) {
+                                                case SIGTERM:
+                                                        goto out;
+                                                }
+                                        }
+                                }
+                        }
+                }
+out:
+                udev_device_unref(dev);
+                if (fd_signal >= 0)
+                        close(fd_signal);
+                if (fd_ep >= 0)
+                        close(fd_ep);
+                close(fd_inotify);
+                close(worker_watch[WRITE_END]);
+                udev_rules_unref(rules);
+                udev_builtin_exit(udev);
+                udev_monitor_unref(worker_monitor);
+                udev_unref(udev);
+                log_close();
+                exit(rc);
+        }
+        case -1:
+                udev_monitor_unref(worker_monitor);
+                event->state = EVENT_QUEUED;
+                free(worker);
+                log_error("fork of child failed: %m\n");
+                break;
+        default:
+                /* close monitor, but keep address around */
+                udev_monitor_disconnect(worker_monitor);
+                worker->monitor = worker_monitor;
+                worker->pid = pid;
+                worker->state = WORKER_RUNNING;
+                worker->event_start_usec = now(CLOCK_MONOTONIC);
+                worker->event = event;
+                event->state = EVENT_RUNNING;
+                udev_list_node_append(&worker->node, &worker_list);
+                children++;
+                log_debug("seq %llu forked new worker [%u]\n", udev_device_get_seqnum(event->dev), pid);
+                break;
+        }
+}
+
+static void event_run(struct event *event)
+{
+        struct udev_list_node *loop;
+
+        udev_list_node_foreach(loop, &worker_list) {
+                struct worker *worker = node_to_worker(loop);
+                ssize_t count;
+
+                if (worker->state != WORKER_IDLE)
+                        continue;
+
+                count = udev_monitor_send_device(monitor, worker->monitor, event->dev);
+                if (count < 0) {
+                        log_error("worker [%u] did not accept message %zi (%m), kill it\n", worker->pid, count);
+                        kill(worker->pid, SIGKILL);
+                        worker->state = WORKER_KILLED;
+                        continue;
+                }
+                worker_ref(worker);
+                worker->event = event;
+                worker->state = WORKER_RUNNING;
+                worker->event_start_usec = now(CLOCK_MONOTONIC);
+                event->state = EVENT_RUNNING;
+                return;
+        }
+
+        if (children >= children_max) {
+                if (children_max > 1)
+                        log_debug("maximum number (%i) of children reached\n", children);
+                return;
+        }
+
+        /* start new worker and pass initial device */
+        worker_new(event);
+}
+
+static int event_queue_insert(struct udev_device *dev)
+{
+        struct event *event;
+
+        event = calloc(1, sizeof(struct event));
+        if (event == NULL)
+                return -1;
+
+        event->udev = udev_device_get_udev(dev);
+        event->dev = dev;
+        event->seqnum = udev_device_get_seqnum(dev);
+        event->devpath = udev_device_get_devpath(dev);
+        event->devpath_len = strlen(event->devpath);
+        event->devpath_old = udev_device_get_devpath_old(dev);
+        event->devnum = udev_device_get_devnum(dev);
+        event->is_block = streq("block", udev_device_get_subsystem(dev));
+        event->ifindex = udev_device_get_ifindex(dev);
+        if (streq(udev_device_get_subsystem(dev), "firmware"))
+                event->nodelay = true;
+
+        udev_queue_export_device_queued(udev_queue_export, dev);
+        log_debug("seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(dev),
+             udev_device_get_action(dev), udev_device_get_subsystem(dev));
+
+        event->state = EVENT_QUEUED;
+        udev_list_node_append(&event->node, &event_list);
+        return 0;
+}
+
+static void worker_kill(struct udev *udev)
+{
+        struct udev_list_node *loop;
+
+        udev_list_node_foreach(loop, &worker_list) {
+                struct worker *worker = node_to_worker(loop);
+
+                if (worker->state == WORKER_KILLED)
+                        continue;
+
+                worker->state = WORKER_KILLED;
+                kill(worker->pid, SIGTERM);
+        }
+}
+
+/* lookup event for identical, parent, child device */
+static bool is_devpath_busy(struct event *event)
+{
+        struct udev_list_node *loop;
+        size_t common;
+
+        /* check if queue contains events we depend on */
+        udev_list_node_foreach(loop, &event_list) {
+                struct event *loop_event = node_to_event(loop);
+
+                /* we already found a later event, earlier can not block us, no need to check again */
+                if (loop_event->seqnum < event->delaying_seqnum)
+                        continue;
+
+                /* event we checked earlier still exists, no need to check again */
+                if (loop_event->seqnum == event->delaying_seqnum)
+                        return true;
+
+                /* found ourself, no later event can block us */
+                if (loop_event->seqnum >= event->seqnum)
+                        break;
+
+                /* check major/minor */
+                if (major(event->devnum) != 0 && event->devnum == loop_event->devnum && event->is_block == loop_event->is_block)
+                        return true;
+
+                /* check network device ifindex */
+                if (event->ifindex != 0 && event->ifindex == loop_event->ifindex)
+                        return true;
+
+                /* check our old name */
+                if (event->devpath_old != NULL && strcmp(loop_event->devpath, event->devpath_old) == 0) {
+                        event->delaying_seqnum = loop_event->seqnum;
+                        return true;
+                }
+
+                /* compare devpath */
+                common = MIN(loop_event->devpath_len, event->devpath_len);
+
+                /* one devpath is contained in the other? */
+                if (memcmp(loop_event->devpath, event->devpath, common) != 0)
+                        continue;
+
+                /* identical device event found */
+                if (loop_event->devpath_len == event->devpath_len) {
+                        /* devices names might have changed/swapped in the meantime */
+                        if (major(event->devnum) != 0 && (event->devnum != loop_event->devnum || event->is_block != loop_event->is_block))
+                                continue;
+                        if (event->ifindex != 0 && event->ifindex != loop_event->ifindex)
+                                continue;
+                        event->delaying_seqnum = loop_event->seqnum;
+                        return true;
+                }
+
+                /* allow to bypass the dependency tracking */
+                if (event->nodelay)
+                        continue;
+
+                /* parent device event found */
+                if (event->devpath[common] == '/') {
+                        event->delaying_seqnum = loop_event->seqnum;
+                        return true;
+                }
+
+                /* child device event found */
+                if (loop_event->devpath[common] == '/') {
+                        event->delaying_seqnum = loop_event->seqnum;
+                        return true;
+                }
+
+                /* no matching device */
+                continue;
+        }
+
+        return false;
+}
+
+static void event_queue_start(struct udev *udev)
+{
+        struct udev_list_node *loop;
+
+        udev_list_node_foreach(loop, &event_list) {
+                struct event *event = node_to_event(loop);
+
+                if (event->state != EVENT_QUEUED)
+                        continue;
+
+                /* do not start event if parent or child event is still running */
+                if (is_devpath_busy(event))
+                        continue;
+
+                event_run(event);
+        }
+}
+
+static void event_queue_cleanup(struct udev *udev, enum event_state match_type)
+{
+        struct udev_list_node *loop, *tmp;
+
+        udev_list_node_foreach_safe(loop, tmp, &event_list) {
+                struct event *event = node_to_event(loop);
+
+                if (match_type != EVENT_UNDEF && match_type != event->state)
+                        continue;
+
+                event_queue_delete(event, false);
+        }
+}
+
+static void worker_returned(int fd_worker)
+{
+        for (;;) {
+                struct worker_message msg;
+                ssize_t size;
+                struct udev_list_node *loop;
+
+                size = recv(fd_worker, &msg, sizeof(struct worker_message), MSG_DONTWAIT);
+                if (size != sizeof(struct worker_message))
+                        break;
+
+                /* lookup worker who sent the signal */
+                udev_list_node_foreach(loop, &worker_list) {
+                        struct worker *worker = node_to_worker(loop);
+
+                        if (worker->pid != msg.pid)
+                                continue;
+
+                        /* worker returned */
+                        if (worker->event) {
+                                worker->event->exitcode = msg.exitcode;
+                                event_queue_delete(worker->event, true);
+                                worker->event = NULL;
+                        }
+                        if (worker->state != WORKER_KILLED)
+                                worker->state = WORKER_IDLE;
+                        worker_unref(worker);
+                        break;
+                }
+        }
+}
+
+/* receive the udevd message from userspace */
+static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl)
+{
+        struct udev *udev = udev_ctrl_get_udev(uctrl);
+        struct udev_ctrl_connection *ctrl_conn;
+        struct udev_ctrl_msg *ctrl_msg = NULL;
+        const char *str;
+        int i;
+
+        ctrl_conn = udev_ctrl_get_connection(uctrl);
+        if (ctrl_conn == NULL)
+                goto out;
+
+        ctrl_msg = udev_ctrl_receive_msg(ctrl_conn);
+        if (ctrl_msg == NULL)
+                goto out;
+
+        i = udev_ctrl_get_set_log_level(ctrl_msg);
+        if (i >= 0) {
+                log_debug("udevd message (SET_LOG_PRIORITY) received, log_priority=%i\n", i);
+                log_set_max_level(i);
+                udev_set_log_priority(udev, i);
+                worker_kill(udev);
+        }
+
+        if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) {
+                log_debug("udevd message (STOP_EXEC_QUEUE) received\n");
+                stop_exec_queue = true;
+        }
+
+        if (udev_ctrl_get_start_exec_queue(ctrl_msg) > 0) {
+                log_debug("udevd message (START_EXEC_QUEUE) received\n");
+                stop_exec_queue = false;
+        }
+
+        if (udev_ctrl_get_reload(ctrl_msg) > 0) {
+                log_debug("udevd message (RELOAD) received\n");
+                reload = true;
+        }
+
+        str = udev_ctrl_get_set_env(ctrl_msg);
+        if (str != NULL) {
+                char *key;
+
+                key = strdup(str);
+                if (key != NULL) {
+                        char *val;
+
+                        val = strchr(key, '=');
+                        if (val != NULL) {
+                                val[0] = '\0';
+                                val = &val[1];
+                                if (val[0] == '\0') {
+                                        log_debug("udevd message (ENV) received, unset '%s'\n", key);
+                                        udev_add_property(udev, key, NULL);
+                                } else {
+                                        log_debug("udevd message (ENV) received, set '%s=%s'\n", key, val);
+                                        udev_add_property(udev, key, val);
+                                }
+                        } else {
+                                log_error("wrong key format '%s'\n", key);
+                        }
+                        free(key);
+                }
+                worker_kill(udev);
+        }
+
+        i = udev_ctrl_get_set_children_max(ctrl_msg);
+        if (i >= 0) {
+                log_debug("udevd message (SET_MAX_CHILDREN) received, children_max=%i\n", i);
+                children_max = i;
+        }
+
+        if (udev_ctrl_get_ping(ctrl_msg) > 0)
+                log_debug("udevd message (SYNC) received\n");
+
+        if (udev_ctrl_get_exit(ctrl_msg) > 0) {
+                log_debug("udevd message (EXIT) received\n");
+                udev_exit = true;
+                /* keep reference to block the client until we exit */
+                udev_ctrl_connection_ref(ctrl_conn);
+        }
+out:
+        udev_ctrl_msg_unref(ctrl_msg);
+        return udev_ctrl_connection_unref(ctrl_conn);
+}
+
+/* read inotify messages */
+static int handle_inotify(struct udev *udev)
+{
+        int nbytes, pos;
+        char *buf;
+        struct inotify_event *ev;
+
+        if ((ioctl(fd_inotify, FIONREAD, &nbytes) < 0) || (nbytes <= 0))
+                return 0;
+
+        buf = malloc(nbytes);
+        if (buf == NULL) {
+                log_error("error getting buffer for inotify\n");
+                return -1;
+        }
+
+        nbytes = read(fd_inotify, buf, nbytes);
+
+        for (pos = 0; pos < nbytes; pos += sizeof(struct inotify_event) + ev->len) {
+                struct udev_device *dev;
+
+                ev = (struct inotify_event *)(buf + pos);
+                dev = udev_watch_lookup(udev, ev->wd);
+                if (dev != NULL) {
+                        log_debug("inotify event: %x for %s\n", ev->mask, udev_device_get_devnode(dev));
+                        if (ev->mask & IN_CLOSE_WRITE) {
+                                char filename[UTIL_PATH_SIZE];
+                                int fd;
+
+                                log_debug("device %s closed, synthesising 'change'\n", udev_device_get_devnode(dev));
+                                util_strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
+                                fd = open(filename, O_WRONLY);
+                                if (fd >= 0) {
+                                        if (write(fd, "change", 6) < 0)
+                                                log_debug("error writing uevent: %m\n");
+                                        close(fd);
+                                }
+                        }
+                        if (ev->mask & IN_IGNORED)
+                                udev_watch_end(udev, dev);
+
+                        udev_device_unref(dev);
+                }
+
+        }
+
+        free(buf);
+        return 0;
+}
+
+static void handle_signal(struct udev *udev, int signo)
+{
+        switch (signo) {
+        case SIGINT:
+        case SIGTERM:
+                udev_exit = true;
+                break;
+        case SIGCHLD:
+                for (;;) {
+                        pid_t pid;
+                        int status;
+                        struct udev_list_node *loop, *tmp;
+
+                        pid = waitpid(-1, &status, WNOHANG);
+                        if (pid <= 0)
+                                break;
+
+                        udev_list_node_foreach_safe(loop, tmp, &worker_list) {
+                                struct worker *worker = node_to_worker(loop);
+
+                                if (worker->pid != pid)
+                                        continue;
+                                log_debug("worker [%u] exit\n", pid);
+
+                                if (WIFEXITED(status)) {
+                                        if (WEXITSTATUS(status) != 0)
+                                                log_error("worker [%u] exit with return code %i\n", pid, WEXITSTATUS(status));
+                                } else if (WIFSIGNALED(status)) {
+                                        log_error("worker [%u] terminated by signal %i (%s)\n",
+                                            pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
+                                } else if (WIFSTOPPED(status)) {
+                                        log_error("worker [%u] stopped\n", pid);
+                                } else if (WIFCONTINUED(status)) {
+                                        log_error("worker [%u] continued\n", pid);
+                                } else {
+                                        log_error("worker [%u] exit with status 0x%04x\n", pid, status);
+                                }
+
+                                if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+                                        if (worker->event) {
+                                                log_error("worker [%u] failed while handling '%s'\n",
+                                                          pid, worker->event->devpath);
+                                                worker->event->exitcode = -32;
+                                                event_queue_delete(worker->event, true);
+                                                /* drop reference taken for state 'running' */
+                                                worker_unref(worker);
+                                        }
+                                }
+                                worker_unref(worker);
+                                break;
+                        }
+                }
+                break;
+        case SIGHUP:
+                reload = true;
+                break;
+        }
+}
+
+static void static_dev_create_from_modules(struct udev *udev)
+{
+        struct utsname kernel;
+        char modules[UTIL_PATH_SIZE];
+        char buf[4096];
+        FILE *f;
+
+        uname(&kernel);
+        util_strscpyl(modules, sizeof(modules), ROOTPREFIX "/lib/modules/", kernel.release, "/modules.devname", NULL);
+        f = fopen(modules, "re");
+        if (f == NULL)
+                return;
+
+        while (fgets(buf, sizeof(buf), f) != NULL) {
+                char *s;
+                const char *modname;
+                const char *devname;
+                const char *devno;
+                int maj, min;
+                char type;
+                mode_t mode;
+                char filename[UTIL_PATH_SIZE];
+
+                if (buf[0] == '#')
+                        continue;
+
+                modname = buf;
+                s = strchr(modname, ' ');
+                if (s == NULL)
+                        continue;
+                s[0] = '\0';
+
+                devname = &s[1];
+                s = strchr(devname, ' ');
+                if (s == NULL)
+                        continue;
+                s[0] = '\0';
+
+                devno = &s[1];
+                s = strchr(devno, ' ');
+                if (s == NULL)
+                        s = strchr(devno, '\n');
+                if (s != NULL)
+                        s[0] = '\0';
+                if (sscanf(devno, "%c%u:%u", &type, &maj, &min) != 3)
+                        continue;
+
+                mode  = 0600;
+                if (type == 'c')
+                        mode |= S_IFCHR;
+                else if (type == 'b')
+                        mode |= S_IFBLK;
+                else
+                        continue;
+
+                util_strscpyl(filename, sizeof(filename), "/dev/", devname, NULL);
+                mkdir_parents_label(filename, 0755);
+                label_context_set(filename, mode);
+                log_debug("mknod '%s' %c%u:%u\n", filename, type, maj, min);
+                if (mknod(filename, mode, makedev(maj, min)) < 0 && errno == EEXIST)
+                        utimensat(AT_FDCWD, filename, NULL, 0);
+                label_context_clear();
+        }
+
+        fclose(f);
+}
+
+static int mem_size_mb(void)
+{
+        FILE *f;
+        char buf[4096];
+        long int memsize = -1;
+
+        f = fopen("/proc/meminfo", "re");
+        if (f == NULL)
+                return -1;
+
+        while (fgets(buf, sizeof(buf), f) != NULL) {
+                long int value;
+
+                if (sscanf(buf, "MemTotal: %ld kB", &value) == 1) {
+                        memsize = value / 1024;
+                        break;
+                }
+        }
+
+        fclose(f);
+        return memsize;
+}
+
+static int convert_db(struct udev *udev)
+{
+        char filename[UTIL_PATH_SIZE];
+        struct udev_enumerate *udev_enumerate;
+        struct udev_list_entry *list_entry;
+
+        /* current database */
+        if (access("/run/udev/data", F_OK) >= 0)
+                return 0;
+
+        /* make sure we do not get here again */
+        mkdir_p("/run/udev/data", 0755);
+
+        /* old database */
+        util_strscpyl(filename, sizeof(filename), "/dev/.udev/db", NULL);
+        if (access(filename, F_OK) < 0)
+                return 0;
+
+        print_kmsg("converting old udev database\n");
+
+        udev_enumerate = udev_enumerate_new(udev);
+        if (udev_enumerate == NULL)
+                return -1;
+        udev_enumerate_scan_devices(udev_enumerate);
+        udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
+                struct udev_device *device;
+
+                device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
+                if (device == NULL)
+                        continue;
+
+                /* try to find the old database for devices without a current one */
+                if (udev_device_read_db(device, NULL) < 0) {
+                        bool have_db;
+                        const char *id;
+                        struct stat stats;
+                        char devpath[UTIL_PATH_SIZE];
+                        char from[UTIL_PATH_SIZE];
+
+                        have_db = false;
+
+                        /* find database in old location */
+                        id = udev_device_get_id_filename(device);
+                        util_strscpyl(from, sizeof(from), "/dev/.udev/db/", id, NULL);
+                        if (lstat(from, &stats) == 0) {
+                                if (!have_db) {
+                                        udev_device_read_db(device, from);
+                                        have_db = true;
+                                }
+                                unlink(from);
+                        }
+
+                        /* find old database with $subsys:$sysname name */
+                        util_strscpyl(from, sizeof(from), "/dev/.udev/db/",
+                                      udev_device_get_subsystem(device), ":", udev_device_get_sysname(device), NULL);
+                        if (lstat(from, &stats) == 0) {
+                                if (!have_db) {
+                                        udev_device_read_db(device, from);
+                                        have_db = true;
+                                }
+                                unlink(from);
+                        }
+
+                        /* find old database with the encoded devpath name */
+                        util_path_encode(udev_device_get_devpath(device), devpath, sizeof(devpath));
+                        util_strscpyl(from, sizeof(from), "/dev/.udev/db/", devpath, NULL);
+                        if (lstat(from, &stats) == 0) {
+                                if (!have_db) {
+                                        udev_device_read_db(device, from);
+                                        have_db = true;
+                                }
+                                unlink(from);
+                        }
+
+                        /* write out new database */
+                        if (have_db)
+                                udev_device_update_db(device);
+                }
+                udev_device_unref(device);
+        }
+        udev_enumerate_unref(udev_enumerate);
+        return 0;
+}
+
+static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink)
+{
+        int ctrl = -1, netlink = -1;
+        int fd, n;
+
+        n = sd_listen_fds(true);
+        if (n <= 0)
+                return -1;
+
+        for (fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) {
+                if (sd_is_socket(fd, AF_LOCAL, SOCK_SEQPACKET, -1)) {
+                        if (ctrl >= 0)
+                                return -1;
+                        ctrl = fd;
+                        continue;
+                }
+
+                if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1)) {
+                        if (netlink >= 0)
+                                return -1;
+                        netlink = fd;
+                        continue;
+                }
+
+                return -1;
+        }
+
+        if (ctrl < 0 || netlink < 0)
+                return -1;
+
+        log_debug("ctrl=%i netlink=%i\n", ctrl, netlink);
+        *rctrl = ctrl;
+        *rnetlink = netlink;
+        return 0;
+}
+
+/*
+ * read the kernel commandline, in case we need to get into debug mode
+ *   udev.log-priority=<level>              syslog priority
+ *   udev.children-max=<number of workers>  events are fully serialized if set to 1
+ *   udev.exec-delay=<number of seconds>    delay execution of every executed program
+ */
+static void kernel_cmdline_options(struct udev *udev)
+{
+        char *line, *w, *state;
+        size_t l;
+
+        if (read_one_line_file("/proc/cmdline", &line) < 0)
+                return;
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                char *s, *opt;
+
+                s = strndup(w, l);
+                if (!s)
+                        break;
+
+                /* accept the same options for the initrd, prefixed with "rd." */
+                if (in_initrd() && startswith(s, "rd."))
+                        opt = s + 3;
+                else
+                        opt = s;
+
+                if (startswith(opt, "udev.log-priority=")) {
+                        int prio;
+
+                        prio = util_log_priority(opt + 18);
+                        log_set_max_level(prio);
+                        udev_set_log_priority(udev, prio);
+                } else if (startswith(opt, "udev.children-max=")) {
+                        children_max = strtoul(opt + 18, NULL, 0);
+                } else if (startswith(opt, "udev.exec-delay=")) {
+                        exec_delay = strtoul(opt + 16, NULL, 0);
+                }
+
+                free(s);
+        }
+
+        free(line);
+}
+
+int main(int argc, char *argv[])
+{
+        struct udev *udev;
+        sigset_t mask;
+        int daemonize = false;
+        int resolve_names = 1;
+        static const struct option options[] = {
+                { "daemon", no_argument, NULL, 'd' },
+                { "debug", no_argument, NULL, 'D' },
+                { "children-max", required_argument, NULL, 'c' },
+                { "exec-delay", required_argument, NULL, 'e' },
+                { "resolve-names", required_argument, NULL, 'N' },
+                { "help", no_argument, NULL, 'h' },
+                { "version", no_argument, NULL, 'V' },
+                {}
+        };
+        int fd_ctrl = -1;
+        int fd_netlink = -1;
+        int fd_worker = -1;
+        struct epoll_event ep_ctrl, ep_inotify, ep_signal, ep_netlink, ep_worker;
+        struct udev_ctrl_connection *ctrl_conn = NULL;
+        int rc = 1;
+
+        udev = udev_new();
+        if (udev == NULL)
+                goto exit;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+        udev_set_log_fn(udev, udev_main_log);
+        log_debug("version %s\n", VERSION);
+        label_init("/dev");
+
+        for (;;) {
+                int option;
+
+                option = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'd':
+                        daemonize = true;
+                        break;
+                case 'c':
+                        children_max = strtoul(optarg, NULL, 0);
+                        break;
+                case 'e':
+                        exec_delay = strtoul(optarg, NULL, 0);
+                        break;
+                case 'D':
+                        debug = true;
+                        log_set_max_level(LOG_DEBUG);
+                        udev_set_log_priority(udev, LOG_DEBUG);
+                        break;
+                case 'N':
+                        if (strcmp (optarg, "early") == 0) {
+                                resolve_names = 1;
+                        } else if (strcmp (optarg, "late") == 0) {
+                                resolve_names = 0;
+                        } else if (strcmp (optarg, "never") == 0) {
+                                resolve_names = -1;
+                        } else {
+                                fprintf(stderr, "resolve-names must be early, late or never\n");
+                                log_error("resolve-names must be early, late or never\n");
+                                goto exit;
+                        }
+                        break;
+                case 'h':
+                        printf("Usage: udevd OPTIONS\n"
+                               "  --daemon\n"
+                               "  --debug\n"
+                               "  --children-max=<maximum number of workers>\n"
+                               "  --exec-delay=<seconds to wait before executing RUN=>\n"
+                               "  --resolve-names=early|late|never\n"
+                               "  --version\n"
+                               "  --help\n"
+                               "\n");
+                        goto exit;
+                case 'V':
+                        printf("%s\n", VERSION);
+                        goto exit;
+                default:
+                        goto exit;
+                }
+        }
+
+        kernel_cmdline_options(udev);
+
+        if (getuid() != 0) {
+                fprintf(stderr, "root privileges required\n");
+                log_error("root privileges required\n");
+                goto exit;
+        }
+
+        /* set umask before creating any file/directory */
+        chdir("/");
+        umask(022);
+
+        mkdir("/run/udev", 0755);
+
+        dev_setup(NULL);
+        static_dev_create_from_modules(udev);
+
+        /* before opening new files, make sure std{in,out,err} fds are in a sane state */
+        if (daemonize) {
+                int fd;
+
+                fd = open("/dev/null", O_RDWR);
+                if (fd >= 0) {
+                        if (write(STDOUT_FILENO, 0, 0) < 0)
+                                dup2(fd, STDOUT_FILENO);
+                        if (write(STDERR_FILENO, 0, 0) < 0)
+                                dup2(fd, STDERR_FILENO);
+                        if (fd > STDERR_FILENO)
+                                close(fd);
+                } else {
+                        fprintf(stderr, "cannot open /dev/null\n");
+                        log_error("cannot open /dev/null\n");
+                }
+        }
+
+        if (systemd_fds(udev, &fd_ctrl, &fd_netlink) >= 0) {
+                /* get control and netlink socket from systemd */
+                udev_ctrl = udev_ctrl_new_from_fd(udev, fd_ctrl);
+                if (udev_ctrl == NULL) {
+                        log_error("error taking over udev control socket");
+                        rc = 1;
+                        goto exit;
+                }
+
+                monitor = udev_monitor_new_from_netlink_fd(udev, "kernel", fd_netlink);
+                if (monitor == NULL) {
+                        log_error("error taking over netlink socket\n");
+                        rc = 3;
+                        goto exit;
+                }
+
+                /* get our own cgroup, we regularly kill everything udev has left behind */
+                if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &udev_cgroup) < 0)
+                        udev_cgroup = NULL;
+        } else {
+                /* open control and netlink socket */
+                udev_ctrl = udev_ctrl_new(udev);
+                if (udev_ctrl == NULL) {
+                        fprintf(stderr, "error initializing udev control socket");
+                        log_error("error initializing udev control socket");
+                        rc = 1;
+                        goto exit;
+                }
+                fd_ctrl = udev_ctrl_get_fd(udev_ctrl);
+
+                monitor = udev_monitor_new_from_netlink(udev, "kernel");
+                if (monitor == NULL) {
+                        fprintf(stderr, "error initializing netlink socket\n");
+                        log_error("error initializing netlink socket\n");
+                        rc = 3;
+                        goto exit;
+                }
+                fd_netlink = udev_monitor_get_fd(monitor);
+        }
+
+        if (udev_monitor_enable_receiving(monitor) < 0) {
+                fprintf(stderr, "error binding netlink socket\n");
+                log_error("error binding netlink socket\n");
+                rc = 3;
+                goto exit;
+        }
+
+        if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
+                fprintf(stderr, "error binding udev control socket\n");
+                log_error("error binding udev control socket\n");
+                rc = 1;
+                goto exit;
+        }
+
+        udev_monitor_set_receive_buffer_size(monitor, 128*1024*1024);
+
+        /* create queue file before signalling 'ready', to make sure we block 'settle' */
+        udev_queue_export = udev_queue_export_new(udev);
+        if (udev_queue_export == NULL) {
+                log_error("error creating queue file\n");
+                goto exit;
+        }
+
+        if (daemonize) {
+                pid_t pid;
+
+                pid = fork();
+                switch (pid) {
+                case 0:
+                        break;
+                case -1:
+                        log_error("fork of daemon failed: %m\n");
+                        rc = 4;
+                        goto exit;
+                default:
+                        rc = EXIT_SUCCESS;
+                        goto exit_daemonize;
+                }
+
+                setsid();
+
+                write_one_line_file("/proc/self/oom_score_adj", "-1000");
+        } else {
+                sd_notify(1, "READY=1");
+        }
+
+        print_kmsg("starting version " VERSION "\n");
+
+        if (!debug) {
+                int fd;
+
+                fd = open("/dev/null", O_RDWR);
+                if (fd >= 0) {
+                        dup2(fd, STDIN_FILENO);
+                        dup2(fd, STDOUT_FILENO);
+                        dup2(fd, STDERR_FILENO);
+                        close(fd);
+                }
+        }
+
+        fd_inotify = udev_watch_init(udev);
+        if (fd_inotify < 0) {
+                fprintf(stderr, "error initializing inotify\n");
+                log_error("error initializing inotify\n");
+                rc = 4;
+                goto exit;
+        }
+        udev_watch_restore(udev);
+
+        /* block and listen to all signals on signalfd */
+        sigfillset(&mask);
+        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
+        fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (fd_signal < 0) {
+                fprintf(stderr, "error creating signalfd\n");
+                log_error("error creating signalfd\n");
+                rc = 5;
+                goto exit;
+        }
+
+        /* unnamed socket from workers to the main daemon */
+        if (socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, worker_watch) < 0) {
+                fprintf(stderr, "error creating socketpair\n");
+                log_error("error creating socketpair\n");
+                rc = 6;
+                goto exit;
+        }
+        fd_worker = worker_watch[READ_END];
+
+        udev_builtin_init(udev);
+
+        rules = udev_rules_new(udev, resolve_names);
+        if (rules == NULL) {
+                log_error("error reading rules\n");
+                goto exit;
+        }
+
+        memset(&ep_ctrl, 0, sizeof(struct epoll_event));
+        ep_ctrl.events = EPOLLIN;
+        ep_ctrl.data.fd = fd_ctrl;
+
+        memset(&ep_inotify, 0, sizeof(struct epoll_event));
+        ep_inotify.events = EPOLLIN;
+        ep_inotify.data.fd = fd_inotify;
+
+        memset(&ep_signal, 0, sizeof(struct epoll_event));
+        ep_signal.events = EPOLLIN;
+        ep_signal.data.fd = fd_signal;
+
+        memset(&ep_netlink, 0, sizeof(struct epoll_event));
+        ep_netlink.events = EPOLLIN;
+        ep_netlink.data.fd = fd_netlink;
+
+        memset(&ep_worker, 0, sizeof(struct epoll_event));
+        ep_worker.events = EPOLLIN;
+        ep_worker.data.fd = fd_worker;
+
+        fd_ep = epoll_create1(EPOLL_CLOEXEC);
+        if (fd_ep < 0) {
+                log_error("error creating epoll fd: %m\n");
+                goto exit;
+        }
+        if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 ||
+            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_inotify, &ep_inotify) < 0 ||
+            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
+            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_netlink, &ep_netlink) < 0 ||
+            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_worker, &ep_worker) < 0) {
+                log_error("fail to add fds to epoll: %m\n");
+                goto exit;
+        }
+
+        /* if needed, convert old database from earlier udev version */
+        convert_db(udev);
+
+        if (children_max <= 0) {
+                int memsize = mem_size_mb();
+
+                /* set value depending on the amount of RAM */
+                if (memsize > 0)
+                        children_max = 16 + (memsize / 8);
+                else
+                        children_max = 16;
+        }
+        log_debug("set children_max to %u\n", children_max);
+
+        udev_rules_apply_static_dev_perms(rules);
+
+        udev_list_node_init(&event_list);
+        udev_list_node_init(&worker_list);
+
+        for (;;) {
+                static usec_t last_usec;
+                struct epoll_event ev[8];
+                int fdcount;
+                int timeout;
+                bool is_worker, is_signal, is_inotify, is_netlink, is_ctrl;
+                int i;
+
+                if (udev_exit) {
+                        /* close sources of new events and discard buffered events */
+                        if (fd_ctrl >= 0) {
+                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_ctrl, NULL);
+                                fd_ctrl = -1;
+                        }
+                        if (monitor != NULL) {
+                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_netlink, NULL);
+                                udev_monitor_unref(monitor);
+                                monitor = NULL;
+                        }
+                        if (fd_inotify >= 0) {
+                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_inotify, NULL);
+                                close(fd_inotify);
+                                fd_inotify = -1;
+                        }
+
+                        /* discard queued events and kill workers */
+                        event_queue_cleanup(udev, EVENT_QUEUED);
+                        worker_kill(udev);
+
+                        /* exit after all has cleaned up */
+                        if (udev_list_node_is_empty(&event_list) && udev_list_node_is_empty(&worker_list))
+                                break;
+
+                        /* timeout at exit for workers to finish */
+                        timeout = 30 * 1000;
+                } else if (udev_list_node_is_empty(&event_list) && !children) {
+                        /* we are idle */
+                        timeout = -1;
+
+                        /* cleanup possible left-over processes in our cgroup */
+                        if (udev_cgroup)
+                                cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL);
+                } else {
+                        /* kill idle or hanging workers */
+                        timeout = 3 * 1000;
+                }
+                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
+                if (fdcount < 0)
+                        continue;
+
+                if (fdcount == 0) {
+                        struct udev_list_node *loop;
+
+                        /* timeout */
+                        if (udev_exit) {
+                                log_error("timeout, giving up waiting for workers to finish\n");
+                                break;
+                        }
+
+                        /* kill idle workers */
+                        if (udev_list_node_is_empty(&event_list)) {
+                                log_debug("cleanup idle workers\n");
+                                worker_kill(udev);
+                        }
+
+                        /* check for hanging events */
+                        udev_list_node_foreach(loop, &worker_list) {
+                                struct worker *worker = node_to_worker(loop);
+
+                                if (worker->state != WORKER_RUNNING)
+                                        continue;
+
+                                if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) {
+                                        log_error("worker [%u] %s timeout; kill it\n", worker->pid,
+                                            worker->event ? worker->event->devpath : "<idle>");
+                                        kill(worker->pid, SIGKILL);
+                                        worker->state = WORKER_KILLED;
+                                        /* drop reference taken for state 'running' */
+                                        worker_unref(worker);
+                                        if (worker->event) {
+                                                log_error("seq %llu '%s' killed\n",
+                                                          udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
+                                                worker->event->exitcode = -64;
+                                                event_queue_delete(worker->event, true);
+                                                worker->event = NULL;
+                                        }
+                                }
+                        }
+
+                }
+
+                is_worker = is_signal = is_inotify = is_netlink = is_ctrl = false;
+                for (i = 0; i < fdcount; i++) {
+                        if (ev[i].data.fd == fd_worker && ev[i].events & EPOLLIN)
+                                is_worker = true;
+                        else if (ev[i].data.fd == fd_netlink && ev[i].events & EPOLLIN)
+                                is_netlink = true;
+                        else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN)
+                                is_signal = true;
+                        else if (ev[i].data.fd == fd_inotify && ev[i].events & EPOLLIN)
+                                is_inotify = true;
+                        else if (ev[i].data.fd == fd_ctrl && ev[i].events & EPOLLIN)
+                                is_ctrl = true;
+                }
+
+                /* check for changed config, every 3 seconds at most */
+                if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * 1000 * 1000) {
+                        if (udev_rules_check_timestamp(rules))
+                                reload = true;
+                        if (udev_builtin_validate(udev))
+                                reload = true;
+
+                        last_usec = now(CLOCK_MONOTONIC);
+                }
+
+                /* reload requested, HUP signal received, rules changed, builtin changed */
+                if (reload) {
+                        worker_kill(udev);
+                        rules = udev_rules_unref(rules);
+                        udev_builtin_exit(udev);
+                        reload = false;
+                }
+
+                /* event has finished */
+                if (is_worker)
+                        worker_returned(fd_worker);
+
+                if (is_netlink) {
+                        struct udev_device *dev;
+
+                        dev = udev_monitor_receive_device(monitor);
+                        if (dev != NULL) {
+                                udev_device_set_usec_initialized(dev, now(CLOCK_MONOTONIC));
+                                if (event_queue_insert(dev) < 0)
+                                        udev_device_unref(dev);
+                        }
+                }
+
+                /* start new events */
+                if (!udev_list_node_is_empty(&event_list) && !udev_exit && !stop_exec_queue) {
+                        udev_builtin_init(udev);
+                        if (rules == NULL)
+                                rules = udev_rules_new(udev, resolve_names);
+                        if (rules != NULL)
+                                event_queue_start(udev);
+                }
+
+                if (is_signal) {
+                        struct signalfd_siginfo fdsi;
+                        ssize_t size;
+
+                        size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
+                        if (size == sizeof(struct signalfd_siginfo))
+                                handle_signal(udev, fdsi.ssi_signo);
+                }
+
+                /* we are shutting down, the events below are not handled anymore */
+                if (udev_exit)
+                        continue;
+
+                /* device node watch */
+                if (is_inotify)
+                        handle_inotify(udev);
+
+                /*
+                 * This needs to be after the inotify handling, to make sure,
+                 * that the ping is send back after the possibly generated
+                 * "change" events by the inotify device node watch.
+                 *
+                 * A single time we may receive a client connection which we need to
+                 * keep open to block the client. It will be closed right before we
+                 * exit.
+                 */
+                if (is_ctrl)
+                        ctrl_conn = handle_ctrl_msg(udev_ctrl);
+        }
+
+        rc = EXIT_SUCCESS;
+exit:
+        udev_queue_export_cleanup(udev_queue_export);
+        udev_ctrl_cleanup(udev_ctrl);
+exit_daemonize:
+        if (fd_ep >= 0)
+                close(fd_ep);
+        worker_list_cleanup(udev);
+        event_queue_cleanup(udev, EVENT_UNDEF);
+        udev_rules_unref(rules);
+        udev_builtin_exit(udev);
+        if (fd_signal >= 0)
+                close(fd_signal);
+        if (worker_watch[READ_END] >= 0)
+                close(worker_watch[READ_END]);
+        if (worker_watch[WRITE_END] >= 0)
+                close(worker_watch[WRITE_END]);
+        udev_monitor_unref(monitor);
+        udev_queue_export_unref(udev_queue_export);
+        udev_ctrl_connection_unref(ctrl_conn);
+        udev_ctrl_unref(udev_ctrl);
+        label_finish();
+        udev_unref(udev);
+        log_close();
+        return rc;
+}
diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c
new file mode 100644 (file)
index 0000000..8dcb645
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2009 Kay Sievers <kay@vrfy.org>
+ * Copyright (c) 2009 Filippo Argiolas <filippo.argiolas@gmail.com>
+ *
+ * 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:
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <linux/videodev2.h>
+
+int main (int argc, char *argv[])
+{
+        static const struct option options[] = {
+                { "help", no_argument, NULL, 'h' },
+                {}
+        };
+        int fd;
+        char *device;
+        struct v4l2_capability v2cap;
+
+        while (1) {
+                int option;
+
+                option = getopt_long(argc, argv, "h", options, NULL);
+                if (option == -1)
+                        break;
+
+                switch (option) {
+                case 'h':
+                        printf("Usage: v4l_id [--help] <device file>\n\n");
+                        return 0;
+                default:
+                        return 1;
+                }
+        }
+        device = argv[optind];
+
+        if (device == NULL)
+                return 2;
+        fd = open (device, O_RDONLY);
+        if (fd < 0)
+                return 3;
+
+        if (ioctl (fd, VIDIOC_QUERYCAP, &v2cap) == 0) {
+                printf("ID_V4L_VERSION=2\n");
+                printf("ID_V4L_PRODUCT=%s\n", v2cap.card);
+                printf("ID_V4L_CAPABILITIES=:");
+                if ((v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0)
+                        printf("capture:");
+                if ((v2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) > 0)
+                        printf("video_output:");
+                if ((v2cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) > 0)
+                        printf("video_overlay:");
+                if ((v2cap.capabilities & V4L2_CAP_AUDIO) > 0)
+                        printf("audio:");
+                if ((v2cap.capabilities & V4L2_CAP_TUNER) > 0)
+                        printf("tuner:");
+                if ((v2cap.capabilities & V4L2_CAP_RADIO) > 0)
+                        printf("radio:");
+                printf("\n");
+        }
+
+        close (fd);
+        return 0;
+}
diff --git a/src/update-utmp/Makefile b/src/update-utmp/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
new file mode 100644 (file)
index 0000000..a311280
--- /dev/null
@@ -0,0 +1,386 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <dbus/dbus.h>
+
+#ifdef HAVE_AUDIT
+#include <libaudit.h>
+#endif
+
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+#include "special.h"
+#include "utmp-wtmp.h"
+#include "dbus-common.h"
+
+typedef struct Context {
+        DBusConnection *bus;
+#ifdef HAVE_AUDIT
+        int audit_fd;
+#endif
+} Context;
+
+static usec_t get_startup_time(Context *c) {
+        const char
+                *interface = "org.freedesktop.systemd1.Manager",
+                *property = "UserspaceTimestamp";
+
+        usec_t t = 0;
+        DBusMessage *reply = NULL;
+        DBusMessageIter iter, sub;
+
+        assert(c);
+
+        if (bus_method_call_with_reply (
+                        c->bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.DBus.Properties",
+                        "Get",
+                        &reply,
+                        NULL,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_STRING, &property,
+                        DBUS_TYPE_INVALID))
+                goto finish;
+
+        if (!dbus_message_iter_init(reply, &iter) ||
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)  {
+                log_error("Failed to parse reply.");
+                goto finish;
+        }
+
+        dbus_message_iter_recurse(&iter, &sub);
+
+        if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT64)  {
+                log_error("Failed to parse reply.");
+                goto finish;
+        }
+
+        dbus_message_iter_get_basic(&sub, &t);
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+        return t;
+}
+
+static int get_current_runlevel(Context *c) {
+        static const struct {
+                const int runlevel;
+                const char *special;
+        } table[] = {
+                /* The first target of this list that is active or has
+                 * a job scheduled wins. We prefer runlevels 5 and 3
+                 * here over the others, since these are the main
+                 * runlevels used on Fedora. It might make sense to
+                 * change the order on some distributions. */
+                { '5', SPECIAL_RUNLEVEL5_TARGET },
+                { '3', SPECIAL_RUNLEVEL3_TARGET },
+                { '4', SPECIAL_RUNLEVEL4_TARGET },
+                { '2', SPECIAL_RUNLEVEL2_TARGET },
+                { 'S', SPECIAL_RESCUE_TARGET },
+        };
+        const char
+                *interface = "org.freedesktop.systemd1.Unit",
+                *property = "ActiveState";
+
+        DBusMessage *reply = NULL;
+        int r = 0;
+        unsigned i;
+        DBusError error;
+
+        assert(c);
+
+        dbus_error_init(&error);
+
+        for (i = 0; i < ELEMENTSOF(table); i++) {
+                const char *path = NULL, *state;
+                DBusMessageIter iter, sub;
+
+                r = bus_method_call_with_reply (
+                                c->bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "GetUnit",
+                                &reply,
+                                NULL,
+                                DBUS_TYPE_STRING, &table[i].special,
+                                DBUS_TYPE_INVALID);
+                if (r == -ENOMEM)
+                        goto finish;
+                if (r)
+                        continue;
+
+                if (!dbus_message_get_args(reply, &error,
+                                           DBUS_TYPE_OBJECT_PATH, &path,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse reply: %s", bus_error_message(&error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_unref(reply);
+                r = bus_method_call_with_reply (
+                                c->bus,
+                                "org.freedesktop.systemd1",
+                                path,
+                                "org.freedesktop.DBus.Properties",
+                                "Get",
+                                &reply,
+                                NULL,
+                                DBUS_TYPE_STRING, &interface,
+                                DBUS_TYPE_STRING, &property,
+                                DBUS_TYPE_INVALID);
+                if (r)
+                        goto finish;
+
+                if (!dbus_message_iter_init(reply, &iter) ||
+                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)  {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_recurse(&iter, &sub);
+
+                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)  {
+                        log_error("Failed to parse reply.");
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_iter_get_basic(&sub, &state);
+
+                if (streq(state, "active") || streq(state, "reloading"))
+                        r = table[i].runlevel;
+
+                dbus_message_unref(reply);
+                reply = NULL;
+
+                if (r)
+                        break;
+        }
+
+finish:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return r;
+}
+
+static int on_reboot(Context *c) {
+        int r = 0, q;
+        usec_t t;
+
+        assert(c);
+
+        /* We finished start-up, so let's write the utmp
+         * record and send the audit msg */
+
+#ifdef HAVE_AUDIT
+        if (c->audit_fd >= 0)
+                if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_BOOT, "init", NULL, NULL, NULL, 1) < 0 &&
+                    errno != EPERM) {
+                        log_error("Failed to send audit message: %m");
+                        r = -errno;
+                }
+#endif
+
+        /* If this call fails it will return 0, which
+         * utmp_put_reboot() will then fix to the current time */
+        t = get_startup_time(c);
+
+        if ((q = utmp_put_reboot(t)) < 0) {
+                log_error("Failed to write utmp record: %s", strerror(-q));
+                r = q;
+        }
+
+        return r;
+}
+
+static int on_shutdown(Context *c) {
+        int r = 0, q;
+
+        assert(c);
+
+        /* We started shut-down, so let's write the utmp
+         * record and send the audit msg */
+
+#ifdef HAVE_AUDIT
+        if (c->audit_fd >= 0)
+                if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_SHUTDOWN, "init", NULL, NULL, NULL, 1) < 0 &&
+                    errno != EPERM) {
+                        log_error("Failed to send audit message: %m");
+                        r = -errno;
+                }
+#endif
+
+        if ((q = utmp_put_shutdown()) < 0) {
+                log_error("Failed to write utmp record: %s", strerror(-q));
+                r = q;
+        }
+
+        return r;
+}
+
+static int on_runlevel(Context *c) {
+        int r = 0, q, previous, runlevel;
+
+        assert(c);
+
+        /* We finished changing runlevel, so let's write the
+         * utmp record and send the audit msg */
+
+        /* First, get last runlevel */
+        if ((q = utmp_get_runlevel(&previous, NULL)) < 0) {
+
+                if (q != -ESRCH && q != -ENOENT) {
+                        log_error("Failed to get current runlevel: %s", strerror(-q));
+                        return q;
+                }
+
+                /* Hmm, we didn't find any runlevel, that means we
+                 * have been rebooted */
+                r = on_reboot(c);
+                previous = 0;
+        }
+
+        /* Secondly, get new runlevel */
+        if ((runlevel = get_current_runlevel(c)) < 0)
+                return runlevel;
+
+        if (previous == runlevel)
+                return 0;
+
+#ifdef HAVE_AUDIT
+        if (c->audit_fd >= 0) {
+                char *s = NULL;
+
+                if (asprintf(&s, "old-level=%c new-level=%c",
+                             previous > 0 ? previous : 'N',
+                             runlevel > 0 ? runlevel : 'N') < 0)
+                        return -ENOMEM;
+
+                if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_RUNLEVEL, s, NULL, NULL, NULL, 1) < 0 &&
+                    errno != EPERM) {
+                        log_error("Failed to send audit message: %m");
+                        r = -errno;
+                }
+
+                free(s);
+        }
+#endif
+
+        if ((q = utmp_put_runlevel(runlevel, previous)) < 0) {
+                if (q != -ESRCH && q != -ENOENT) {
+                        log_error("Failed to write utmp record: %s", strerror(-q));
+                        r = q;
+                }
+        }
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+        DBusError error;
+        Context c;
+
+        dbus_error_init(&error);
+
+        zero(c);
+#ifdef HAVE_AUDIT
+        c.audit_fd = -1;
+#endif
+
+        if (getppid() != 1) {
+                log_error("This program should be invoked by init only.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc != 2) {
+                log_error("This program requires one argument.");
+                return EXIT_FAILURE;
+        }
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+#ifdef HAVE_AUDIT
+        if ((c.audit_fd = audit_open()) < 0 &&
+            /* If the kernel lacks netlink or audit support,
+             * don't worry about it. */
+            errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
+                log_error("Failed to connect to audit log: %m");
+#endif
+
+        if (bus_connect(DBUS_BUS_SYSTEM, &c.bus, NULL, &error) < 0) {
+                log_error("Failed to get D-Bus connection: %s", bus_error_message(&error));
+                r = -EIO;
+                goto finish;
+        }
+
+        log_debug("systemd-update-utmp running as pid %lu", (unsigned long) getpid());
+
+        if (streq(argv[1], "reboot"))
+                r = on_reboot(&c);
+        else if (streq(argv[1], "shutdown"))
+                r = on_shutdown(&c);
+        else if (streq(argv[1], "runlevel"))
+                r = on_runlevel(&c);
+        else {
+                log_error("Unknown command %s", argv[1]);
+                r = -EINVAL;
+        }
+
+        log_debug("systemd-update-utmp stopped as pid %lu", (unsigned long) getpid());
+
+finish:
+#ifdef HAVE_AUDIT
+        if (c.audit_fd >= 0)
+                audit_close(c.audit_fd);
+#endif
+
+        if (c.bus) {
+                dbus_connection_flush(c.bus);
+                dbus_connection_close(c.bus);
+                dbus_connection_unref(c.bus);
+        }
+
+        dbus_error_free(&error);
+        dbus_shutdown();
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/vconsole/Makefile b/src/vconsole/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
new file mode 100644 (file)
index 0000000..b9d8681
--- /dev/null
@@ -0,0 +1,257 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Kay Sievers
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <linux/tiocl.h>
+#include <linux/kd.h>
+
+#include "util.h"
+#include "log.h"
+#include "macro.h"
+#include "virt.h"
+
+static bool is_vconsole(int fd) {
+        unsigned char data[1];
+
+        data[0] = TIOCL_GETFGCONSOLE;
+        return ioctl(fd, TIOCLINUX, data) >= 0;
+}
+
+static int disable_utf8(int fd) {
+        int r = 0, k;
+
+        if (ioctl(fd, KDSKBMODE, K_XLATE) < 0)
+                r = -errno;
+
+        if (loop_write(fd, "\033%@", 3, false) < 0)
+                r = -errno;
+
+        k = write_one_line_file("/sys/module/vt/parameters/default_utf8", "0");
+        if (k < 0)
+                r = k;
+
+        if (r < 0)
+                log_warning("Failed to disable UTF-8: %s", strerror(-r));
+
+        return r;
+}
+
+static int enable_utf8(int fd) {
+        int r = 0, k;
+
+        if (ioctl(fd, KDSKBMODE, K_UNICODE) < 0)
+                r = -errno;
+
+        if (loop_write(fd, "\033%G", 3, false) < 0)
+                r = -errno;
+
+        k = write_one_line_file("/sys/module/vt/parameters/default_utf8", "1");
+        if (k < 0)
+                r = k;
+
+        if (r < 0)
+                log_warning("Failed to enable UTF-8: %s", strerror(-r));
+
+        return r;
+}
+
+static int load_keymap(const char *vc, const char *map, const char *map_toggle, bool utf8, pid_t *_pid) {
+        const char *args[8];
+        int i = 0;
+        pid_t pid;
+
+        if (isempty(map)) {
+                /* An empty map means kernel map */
+                *_pid = 0;
+                return 0;
+        }
+
+        args[i++] = KBD_LOADKEYS;
+        args[i++] = "-q";
+        args[i++] = "-C";
+        args[i++] = vc;
+        if (utf8)
+                args[i++] = "-u";
+        args[i++] = map;
+        if (map_toggle)
+                args[i++] = map_toggle;
+        args[i++] = NULL;
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("Failed to fork: %m");
+                return -errno;
+        } else if (pid == 0) {
+                execv(args[0], (char **) args);
+                _exit(EXIT_FAILURE);
+        }
+
+        *_pid = pid;
+        return 0;
+}
+
+static int load_font(const char *vc, const char *font, const char *map, const char *unimap, pid_t *_pid) {
+        const char *args[9];
+        int i = 0;
+        pid_t pid;
+
+        if (isempty(font)) {
+                /* An empty font means kernel font */
+                *_pid = 0;
+                return 0;
+        }
+
+        args[i++] = KBD_SETFONT;
+        args[i++] = "-C";
+        args[i++] = vc;
+        args[i++] = font;
+        if (map) {
+                args[i++] = "-m";
+                args[i++] = map;
+        }
+        if (unimap) {
+                args[i++] = "-u";
+                args[i++] = unimap;
+        }
+        args[i++] = NULL;
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("Failed to fork: %m");
+                return -errno;
+        } else if (pid == 0) {
+                execv(args[0], (char **) args);
+                _exit(EXIT_FAILURE);
+        }
+
+        *_pid = pid;
+        return 0;
+}
+
+int main(int argc, char **argv) {
+        const char *vc;
+        char *vc_keymap = NULL;
+        char *vc_keymap_toggle = NULL;
+        char *vc_font = NULL;
+        char *vc_font_map = NULL;
+        char *vc_font_unimap = NULL;
+        int fd = -1;
+        bool utf8;
+        int r = EXIT_FAILURE;
+        pid_t font_pid = 0, keymap_pid = 0;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argv[1])
+                vc = argv[1];
+        else
+                vc = "/dev/tty0";
+
+        fd = open_terminal(vc, O_RDWR|O_CLOEXEC);
+        if (fd < 0) {
+                log_error("Failed to open %s: %m", vc);
+                goto finish;
+        }
+
+        if (!is_vconsole(fd)) {
+                log_error("Device %s is not a virtual console.", vc);
+                goto finish;
+        }
+
+        utf8 = is_locale_utf8();
+
+        r = 0;
+
+        if (detect_container(NULL) <= 0) {
+                r = parse_env_file("/proc/cmdline", WHITESPACE,
+                                   "vconsole.keymap", &vc_keymap,
+                                   "vconsole.keymap.toggle", &vc_keymap_toggle,
+                                   "vconsole.font", &vc_font,
+                                   "vconsole.font.map", &vc_font_map,
+                                   "vconsole.font.unimap", &vc_font_unimap,
+                                   NULL);
+
+                if (r < 0 && r != -ENOENT)
+                        log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
+        }
+
+        /* Hmm, nothing set on the kernel cmd line? Then let's
+         * try /etc/vconsole.conf */
+        if (r <= 0) {
+                r = parse_env_file("/etc/vconsole.conf", NEWLINE,
+                                   "KEYMAP", &vc_keymap,
+                                   "KEYMAP_TOGGLE", &vc_keymap_toggle,
+                                   "FONT", &vc_font,
+                                   "FONT_MAP", &vc_font_map,
+                                   "FONT_UNIMAP", &vc_font_unimap,
+                                   NULL);
+
+                if (r < 0 && r != -ENOENT)
+                        log_warning("Failed to read /etc/vconsole.conf: %s", strerror(-r));
+        }
+
+        if (r <= 0) {
+        }
+
+        r = EXIT_FAILURE;
+
+        if (utf8)
+                enable_utf8(fd);
+        else
+                disable_utf8(fd);
+
+
+        if (load_keymap(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid) >= 0 &&
+            load_font(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0)
+                r = EXIT_SUCCESS;
+
+finish:
+        if (keymap_pid > 0)
+                wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid);
+
+        if (font_pid > 0)
+                wait_for_terminate_and_warn(KBD_SETFONT, font_pid);
+
+        free(vc_keymap);
+        free(vc_font);
+        free(vc_font_map);
+        free(vc_font_unimap);
+
+        if (fd >= 0)
+                close_nointr_nofail(fd);
+
+        return r;
+}
diff --git a/sysctl.d/.gitignore b/sysctl.d/.gitignore
new file mode 100644 (file)
index 0000000..7563539
--- /dev/null
@@ -0,0 +1 @@
+/coredump.conf
diff --git a/sysctl.d/Makefile b/sysctl.d/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/sysctl.d/coredump.conf.in b/sysctl.d/coredump.conf.in
new file mode 100644 (file)
index 0000000..5c791b7
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See sysctl.d(5) for details
+
+kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %p %u %g %s %t %e
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644 (file)
index 0000000..93c1f95
--- /dev/null
@@ -0,0 +1,3 @@
+.testdir
+test.log
+/sys
diff --git a/test/Makefile b/test/Makefile
new file mode 100644 (file)
index 0000000..987a325
--- /dev/null
@@ -0,0 +1,20 @@
+# Just a little hook script to easy building when in this directory
+.PHONY: all check clean
+
+all:
+       $(MAKE) -C ..
+
+clean:
+       @for i in TEST-[0-9]*; do \
+               [ -d $$i ] || continue ; \
+               [ -f $$i/Makefile ] || continue ; \
+               make -C $$i clean ; \
+       done
+
+check:
+       $(MAKE) -C .. all
+       @for i in TEST-[0-9]*; do \
+               [ -d $$i ] || continue ; \
+               [ -f $$i/Makefile ] || continue ; \
+               make -C $$i all ; \
+       done
diff --git a/test/README.testsuite b/test/README.testsuite
new file mode 100644 (file)
index 0000000..0f96b98
--- /dev/null
@@ -0,0 +1,35 @@
+The extended testsuite only works with uid=0. It contains of several
+subdirectories named "test/TEST-??-*", which are run one by one.
+
+To run the extended testsuite do the following:
+
+$ make all
+$ cd test
+$ sudo make clean check
+...
+make[1]: Entering directory `/mnt/data/harald/git/systemd/test/TEST-01-BASIC'
+Making all in .
+Making all in po
+Making all in docs/libudev
+Making all in docs/gudev
+TEST: Basic systemd setup [OK]
+make[1]: Leaving directory `/mnt/data/harald/git/systemd/test/TEST-01-BASIC'
+...
+
+If one of the tests fails, then $subdir/test.log contains the log file of
+the test.
+
+To debug a special testcase of the testsuite do:
+
+$ make all
+$ cd test/TEST-01-BASIC
+$ sudo make clean setup run
+
+If you want to log in the testsuite virtual machine, you can specify
+additional kernel command line parameter with $DEBUGFAIL.
+
+$ sudo sh -c 'DEBUGFAIL="systemd.unit=multi-user.target" make clean setup run'
+
+you can even skip the "clean" and "setup" if you want to run the machine again.
+
+$ sudo sh -c 'DEBUGFAIL="systemd.unit=multi-user.target" make run'
diff --git a/test/TEST-01-BASIC/Makefile b/test/TEST-01-BASIC/Makefile
new file mode 100644 (file)
index 0000000..5e89a29
--- /dev/null
@@ -0,0 +1,10 @@
+all:
+       @make -s --no-print-directory -C ../.. all
+       @basedir=../.. TEST_BASE_DIR=../ ./test.sh --all
+setup:
+       @make --no-print-directory -C ../.. all
+       @basedir=../.. TEST_BASE_DIR=../ ./test.sh --setup
+clean:
+       @basedir=../.. TEST_BASE_DIR=../ ./test.sh --clean
+run:
+       @basedir=../.. TEST_BASE_DIR=../ ./test.sh --run
diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh
new file mode 100755 (executable)
index 0000000..eb6a80a
--- /dev/null
@@ -0,0 +1,252 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="Basic systemd setup"
+
+KVERSION=${KVERSION-$(uname -r)}
+KERNEL_VER=$(uname -r)
+
+# Uncomment this to debug failures
+#DEBUGFAIL="systemd.unit=multi-user.target"
+DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort"
+
+run_qemu() {
+    # TODO: qemu wrapper script: http://www.spinics.net/lists/kvm/msg72389.html
+    qemu-kvm \
+        -hda $TESTDIR/rootdisk.img \
+        -m 512M -nographic \
+        -net none -kernel /boot/vmlinuz-$KERNEL_VER \
+        -append "root=/dev/sda1 systemd.log_level=debug raid=noautodetect loglevel=2 init=/usr/lib/systemd/systemd ro console=ttyS0,115200n81 selinux=0 $DEBUGFAIL" || return 1
+
+    ret=1
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+    [[ -e $TESTDIR/root/testok ]] && ret=0
+    cp -a $TESTDIR/root/failed $TESTDIR
+    cp -a $TESTDIR/root/var/log/journal $TESTDIR
+    umount $TESTDIR/root
+    cat $TESTDIR/failed
+    ls -l $TESTDIR/journal/*/*.journal
+    test -s $TESTDIR/failed && ret=$(($ret+1))
+    return $ret
+}
+
+
+run_nspawn() {
+    systemd-nspawn -b -D $TESTDIR/nspawn-root --capability=CAP_AUDIT_CONTROL,CAP_AUDIT_WRITE /usr/lib/systemd/systemd
+    ret=1
+    [[ -e $TESTDIR/nspawn-root/testok ]] && ret=0
+    cp -a $TESTDIR/nspawn-root/failed $TESTDIR
+    cp -a $TESTDIR/nspawn-root/var/log/journal $TESTDIR
+    cat $TESTDIR/failed
+    ls -l $TESTDIR/journal/*/*.journal
+    test -s $TESTDIR/failed && ret=$(($ret+1))
+    return $ret
+}
+
+
+test_run() {
+    if check_qemu ; then
+        run_qemu || return 1
+    else
+        dwarn "can't run qemu-kvm, skipping"
+    fi
+    if check_nspawn; then
+        run_nspawn || return 1
+    else
+        dwarn "can't run systemd-nspawn, skipping"
+    fi
+    return 0
+}
+
+test_setup() {
+    rm -f $TESTDIR/rootdisk.img
+    # Create the blank file to use as a root filesystem
+    dd if=/dev/null of=$TESTDIR/rootdisk.img bs=1M seek=200
+    LOOPDEV=$(losetup --show -P -f $TESTDIR/rootdisk.img)
+    [ -b $LOOPDEV ] || return 1
+    echo "LOOPDEV=$LOOPDEV" >> $STATEFILE
+    sfdisk -C 6400 -H 2 -S 32 -L $LOOPDEV <<EOF
+,3200
+,
+EOF
+
+    mkfs.ext3 -L systemd ${LOOPDEV}p1
+    echo -n test >$TESTDIR/keyfile
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+    mkdir -p $TESTDIR/root/run
+
+    # Create what will eventually be our root filesystem onto an overlay
+    (
+        LOG_LEVEL=5
+        initdir=$TESTDIR/root
+
+        # create the basic filesystem layout
+        setup_basic_dirs
+
+        # install compiled files
+        (cd ../..; make DESTDIR=$initdir install)
+
+        # remove unneeded documentation
+        rm -fr $initdir/usr/share/{man,doc,gtk-doc}
+
+        # install possible missing libraries
+        for i in $initdir/{sbin,bin}/* $initdir/lib/systemd/*; do
+            inst_libs $i
+        done
+
+        # make a journal directory
+        mkdir -p $initdir/var/log/journal
+
+        # install some basic config files
+        inst /etc/sysconfig/init
+        inst /etc/passwd
+        inst /etc/shadow
+        inst /etc/group
+        inst /etc/shells
+        inst /etc/nsswitch.conf
+        inst /etc/pam.conf
+        inst /etc/securetty
+        inst /etc/os-release
+        inst /etc/localtime
+        # we want an empty environment
+        > $initdir/etc/environment
+        > $initdir/etc/machine-id
+
+        # set the hostname
+        echo  systemd-testsuite > $initdir/etc/hostname
+
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+        cat >$initdir/etc/fstab <<EOF
+LABEL=systemd           /       ext3    rw 0 1
+EOF
+
+        # setup the testsuite target
+        cat >$initdir/etc/systemd/system/testsuite.target <<EOF
+[Unit]
+Description=Testsuite target
+Requires=multi-user.target
+After=multi-user.target
+Conflicts=rescue.target
+AllowIsolate=yes
+EOF
+
+        # setup the testsuite service
+        cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/bin/bash -c 'set -x; systemctl --failed --no-legend --no-pager > /failed ; echo OK > /testok; while : ;do echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;'
+ExecStopPost=/usr/bin/systemctl poweroff
+Type=oneshot
+EOF
+        mkdir -p $initdir/etc/systemd/system/testsuite.target.wants
+        ln -fs ../testsuite.service $initdir/etc/systemd/system/testsuite.target.wants/testsuite.service
+
+        # make the testsuite the default target
+        ln -fs testsuite.target $initdir/etc/systemd/system/default.target
+        mkdir -p $initdir/etc/rc.d
+        cat >$initdir/etc/rc.d/rc.local <<EOF
+#!/bin/bash
+exit 0
+EOF
+        chmod 0755 $initdir/etc/rc.d/rc.local
+        # install basic tools needed
+        dracut_install sh bash setsid loadkeys setfont \
+            login sushell sulogin gzip sleep echo mount umount cryptsetup
+        dracut_install dmsetup modprobe
+
+        # install libnss_files for login
+        inst_libdir_file "libnss_files*"
+
+        # install dbus and pam
+        find \
+            /etc/dbus-1 \
+            /etc/pam.d \
+            /etc/security \
+            /lib64/security \
+            /lib/security -xtype f \
+            | while read file; do
+            inst $file
+        done
+
+        # install dbus socket and service file
+        inst /usr/lib/systemd/system/dbus.socket
+        inst /usr/lib/systemd/system/dbus.service
+
+        # install basic keyboard maps and fonts
+        for i in \
+            /usr/lib/kbd/consolefonts/latarcyrheb-sun16* \
+            /usr/lib/kbd/keymaps/include/* \
+            /usr/lib/kbd/keymaps/i386/include/* \
+            /usr/lib/kbd/keymaps/i386/qwerty/us.*; do
+                [[ -f $i ]] || continue
+                inst $i
+        done
+
+        # some basic terminfo files
+        for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do
+            [ -f ${_terminfodir}/l/linux ] && break
+        done
+        dracut_install -o ${_terminfodir}/l/linux
+
+        # softlink mtab
+        ln -fs /proc/self/mounts $initdir/etc/mtab
+
+        # install any Exec's from the service files
+        egrep -ho '^Exec[^ ]*=[^ ]+' $initdir/lib/systemd/system/*.service \
+            | while read i; do
+            i=${i##Exec*=}; i=${i##-}
+            inst $i
+        done
+
+        # install plymouth, if found... else remove plymouth service files
+        # if [ -x /usr/libexec/plymouth/plymouth-populate-initrd ]; then
+        #     PLYMOUTH_POPULATE_SOURCE_FUNCTIONS="$TEST_BASE_DIR/test-functions" \
+        #         /usr/libexec/plymouth/plymouth-populate-initrd -t $initdir
+        #         dracut_install plymouth plymouthd
+        # else
+        rm -f $initdir/{usr/lib,etc}/systemd/system/plymouth* $initdir/{usr/lib,etc}/systemd/system/*/plymouth*
+        # fi
+
+        # some helper tools for debugging
+        [[ $DEBUGTOOLS ]] && dracut_install $DEBUGTOOLS
+
+        # install ld.so.conf* and run ldconfig
+        cp -a /etc/ld.so.conf* $initdir/etc
+        ldconfig -r "$initdir"
+        ddebug "Strip binaeries"
+        find "$initdir" -perm +111 -type f | xargs strip --strip-unneeded | ddebug
+
+        # copy depmod files
+        inst /lib/modules/$KERNEL_VER/modules.order
+        inst /lib/modules/$KERNEL_VER/modules.builtin
+        # generate module dependencies
+        if [[ -d $initdir/lib/modules/$KERNEL_VER ]] && \
+            ! depmod -a -b "$initdir" $KERNEL_VER; then
+                dfatal "\"depmod -a $KERNEL_VER\" failed."
+                exit 1
+        fi
+    )
+    rm -fr $TESTDIR/nspawn-root
+    ddebug "cp -ar $TESTDIR/root $TESTDIR/nspawn-root"
+    cp -ar $TESTDIR/root $TESTDIR/nspawn-root
+    # we don't mount in the nspawn root
+    rm -fr $TESTDIR/nspawn-root/etc/fstab
+
+    ddebug "umount $TESTDIR/root"
+    umount $TESTDIR/root
+}
+
+test_cleanup() {
+    umount $TESTDIR/root 2>/dev/null
+    [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+    return 0
+}
+
+. $TEST_BASE_DIR/test-functions
+do_test "$@"
diff --git a/test/TEST-02-CRYPTSETUP/Makefile b/test/TEST-02-CRYPTSETUP/Makefile
new file mode 120000 (symlink)
index 0000000..e9f93b1
--- /dev/null
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
new file mode 100755 (executable)
index 0000000..790dc30
--- /dev/null
@@ -0,0 +1,264 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="cryptsetup systemd setup"
+
+KVERSION=${KVERSION-$(uname -r)}
+KERNEL_VER=$(uname -r)
+
+# Uncomment this to debug failures
+#DEBUGFAIL="systemd.unit=multi-user.target"
+DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort"
+
+run_qemu() {
+    # TODO: qemu wrapper script: http://www.spinics.net/lists/kvm/msg72389.html
+    qemu-kvm \
+        -hda $TESTDIR/rootdisk.img \
+        -m 512M -nographic \
+        -net none -kernel /boot/vmlinuz-$KERNEL_VER \
+        -append "root=/dev/sda1 systemd.log_level=debug raid=noautodetect loglevel=2 init=/usr/lib/systemd/systemd ro console=ttyS0,115200n81 selinux=0 $DEBUGFAIL" || return 1
+
+    ret=1
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+    [[ -e $TESTDIR/root/testok ]] && ret=0
+    cp -a $TESTDIR/root/failed $TESTDIR
+    cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile
+    mount /dev/mapper/varcrypt $TESTDIR/root/var
+    cp -a $TESTDIR/root/var/log/journal $TESTDIR
+    umount $TESTDIR/root/var
+    umount $TESTDIR/root
+    cryptsetup luksClose /dev/mapper/varcrypt
+    cat $TESTDIR/failed
+    ls -l $TESTDIR/journal/*/*.journal
+    test -s $TESTDIR/failed && ret=$(($ret+1))
+    return $ret
+}
+
+
+test_run() {
+    if check_qemu ; then
+        run_qemu || return 1
+    else
+        dwarn "can't run qemu-kvm, skipping"
+    fi
+    return 0
+}
+
+test_setup() {
+    rm -f $TESTDIR/rootdisk.img
+    # Create the blank file to use as a root filesystem
+    dd if=/dev/null of=$TESTDIR/rootdisk.img bs=1M seek=200
+    LOOPDEV=$(losetup --show -P -f $TESTDIR/rootdisk.img)
+    [ -b $LOOPDEV ] || return 1
+    echo "LOOPDEV=$LOOPDEV" >> $STATEFILE
+    sfdisk -C 6400 -H 2 -S 32 -L $LOOPDEV <<EOF
+,3200
+,
+EOF
+
+    mkfs.ext3 -L systemd ${LOOPDEV}p1
+    echo -n test >$TESTDIR/keyfile
+    cryptsetup -q luksFormat ${LOOPDEV}p2 $TESTDIR/keyfile
+    cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile
+    mkfs.ext3 -L var /dev/mapper/varcrypt
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+    mkdir -p $TESTDIR/root/run
+    mkdir -p $TESTDIR/root/var
+    mount /dev/mapper/varcrypt $TESTDIR/root/var
+
+    # Create what will eventually be our root filesystem onto an overlay
+    (
+        LOG_LEVEL=5
+        initdir=$TESTDIR/root
+
+        # create the basic filesystem layout
+        setup_basic_dirs
+
+        # install compiled files
+        (cd ../..; make DESTDIR=$initdir install)
+
+        # remove unneeded documentation
+        rm -fr $initdir/usr/share/{man,doc,gtk-doc}
+
+        # install possible missing libraries
+        for i in $initdir/{sbin,bin}/* $initdir/lib/systemd/*; do
+            inst_libs $i
+        done
+
+        # make a journal directory
+        mkdir -p $initdir/var/log/journal
+
+        # install some basic config files
+        inst /etc/sysconfig/init
+        inst /etc/passwd
+        inst /etc/shadow
+        inst /etc/group
+        inst /etc/shells
+        inst /etc/nsswitch.conf
+        inst /etc/pam.conf
+        inst /etc/securetty
+        inst /etc/os-release
+        inst /etc/localtime
+        # we want an empty environment
+        > $initdir/etc/environment
+        > $initdir/etc/machine-id
+
+        # set the hostname
+        echo  systemd-testsuite > $initdir/etc/hostname
+
+        eval $(udevadm info --export --query=env --name=/dev/mapper/varcrypt)
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+        cat >$initdir/etc/crypttab <<EOF
+$DM_NAME UUID=$ID_FS_UUID /etc/varkey
+EOF
+        echo -n test > $initdir/etc/varkey
+        cat $initdir/etc/crypttab | ddebug
+
+        cat >$initdir/etc/fstab <<EOF
+LABEL=systemd           /       ext3    rw 0 1
+/dev/mapper/varcrypt    /var    ext3    defaults 0 1
+EOF
+
+        # setup the testsuite target
+        cat >$initdir/etc/systemd/system/testsuite.target <<EOF
+[Unit]
+Description=Testsuite target
+Requires=multi-user.target
+After=multi-user.target
+Conflicts=rescue.target
+AllowIsolate=yes
+EOF
+
+        # setup the testsuite service
+        cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/bin/bash -c 'set -x; systemctl --failed --no-legend --no-pager > /failed ; echo OK > /testok; while : ;do systemd-cat echo "testsuite service waiting for /var/log/journal" ; echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;'
+ExecStopPost=/usr/bin/systemctl poweroff
+Type=oneshot
+EOF
+        mkdir -p $initdir/etc/systemd/system/testsuite.target.wants
+        ln -fs ../testsuite.service $initdir/etc/systemd/system/testsuite.target.wants/testsuite.service
+
+        # make the testsuite the default target
+        ln -fs testsuite.target $initdir/etc/systemd/system/default.target
+        mkdir -p $initdir/etc/rc.d
+        cat >$initdir/etc/rc.d/rc.local <<EOF
+#!/bin/bash
+exit 0
+EOF
+        chmod 0755 $initdir/etc/rc.d/rc.local
+        # install basic tools needed
+        dracut_install sh bash setsid loadkeys setfont \
+            login sushell sulogin gzip sleep echo mount umount cryptsetup
+        dracut_install dmsetup modprobe
+
+        instmods dm_crypt =crypto
+
+        type -P dmeventd >/dev/null && dracut_install dmeventd
+
+        inst_libdir_file "libdevmapper-event.so*"
+
+        inst_rules 10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
+
+        # install libnss_files for login
+        inst_libdir_file "libnss_files*"
+
+        # install dbus and pam
+        find \
+            /etc/dbus-1 \
+            /etc/pam.d \
+            /etc/security \
+            /lib64/security \
+            /lib/security -xtype f \
+            | while read file; do
+            inst $file
+        done
+
+        # install dbus socket and service file
+        inst /usr/lib/systemd/system/dbus.socket
+        inst /usr/lib/systemd/system/dbus.service
+
+        # install basic keyboard maps and fonts
+        for i in \
+            /usr/lib/kbd/consolefonts/latarcyrheb-sun16* \
+            /usr/lib/kbd/keymaps/include/* \
+            /usr/lib/kbd/keymaps/i386/include/* \
+            /usr/lib/kbd/keymaps/i386/qwerty/us.*; do
+                [[ -f $i ]] || continue
+                inst $i
+        done
+
+        # some basic terminfo files
+        for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do
+            [ -f ${_terminfodir}/l/linux ] && break
+        done
+        dracut_install -o ${_terminfodir}/l/linux
+
+        # softlink mtab
+        ln -fs /proc/self/mounts $initdir/etc/mtab
+
+        # install any Exec's from the service files
+        egrep -ho '^Exec[^ ]*=[^ ]+' $initdir/lib/systemd/system/*.service \
+            | while read i; do
+            i=${i##Exec*=}; i=${i##-}
+            inst $i
+        done
+
+        # install plymouth, if found... else remove plymouth service files
+        # if [ -x /usr/libexec/plymouth/plymouth-populate-initrd ]; then
+        #     PLYMOUTH_POPULATE_SOURCE_FUNCTIONS="$TEST_BASE_DIR/test-functions" \
+        #         /usr/libexec/plymouth/plymouth-populate-initrd -t $initdir
+        #         dracut_install plymouth plymouthd
+        # else
+        rm -f $initdir/{usr/lib,etc}/systemd/system/plymouth* $initdir/{usr/lib,etc}/systemd/system/*/plymouth*
+        # fi
+
+        # some helper tools for debugging
+        [[ $DEBUGTOOLS ]] && dracut_install $DEBUGTOOLS
+
+        # install ld.so.conf* and run ldconfig
+        cp -a /etc/ld.so.conf* $initdir/etc
+        ldconfig -r "$initdir"
+        ddebug "Strip binaeries"
+        find "$initdir" -perm +111 -type f | xargs strip --strip-unneeded | ddebug
+
+        # copy depmod files
+        inst /lib/modules/$KERNEL_VER/modules.order
+        inst /lib/modules/$KERNEL_VER/modules.builtin
+        # generate module dependencies
+        if [[ -d $initdir/lib/modules/$KERNEL_VER ]] && \
+            ! depmod -a -b "$initdir" $KERNEL_VER; then
+                dfatal "\"depmod -a $KERNEL_VER\" failed."
+                exit 1
+        fi
+    )
+    rm -fr $TESTDIR/nspawn-root
+    ddebug "cp -ar $TESTDIR/root $TESTDIR/nspawn-root"
+    cp -ar $TESTDIR/root $TESTDIR/nspawn-root
+    # we don't mount in the nspawn root
+    rm -fr $TESTDIR/nspawn-root/etc/fstab
+
+    ddebug "umount $TESTDIR/root/var"
+    umount $TESTDIR/root/var
+    cryptsetup luksClose /dev/mapper/varcrypt
+    ddebug "umount $TESTDIR/root"
+    umount $TESTDIR/root
+}
+
+test_cleanup() {
+    umount $TESTDIR/root/var 2>/dev/null
+    [[ -b /dev/mapper/varcrypt ]] && cryptsetup luksClose /dev/mapper/varcrypt
+    umount $TESTDIR/root 2>/dev/null
+    [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+    return 0
+}
+
+. $TEST_BASE_DIR/test-functions
+do_test "$@"
diff --git a/test/a.service b/test/a.service
new file mode 100644 (file)
index 0000000..4168d2d
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=A
+Requires=b.service
+Before=b.service
+
+[Service]
+ExecStart=/bin/true
diff --git a/test/b.service b/test/b.service
new file mode 100644 (file)
index 0000000..e03bae3
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=B
+Wants=f.service
+
+[Service]
+ExecStart=/bin/true
diff --git a/test/c.service b/test/c.service
new file mode 100644 (file)
index 0000000..e2f60a8
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=C
+Requires=a.service
+
+[Service]
+ExecStart=/bin/true
diff --git a/test/d.service b/test/d.service
new file mode 100644 (file)
index 0000000..921fd2e
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=D:Cyclic
+After=b.service
+Before=a.service
+Requires=a.service
+
+[Service]
+ExecStart=/bin/true
diff --git a/test/e.service b/test/e.service
new file mode 100644 (file)
index 0000000..5ba98c7
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=E:Cyclic
+After=b.service
+Before=a.service
+Wants=a.service
+
+[Service]
+ExecStart=/bin/true
diff --git a/test/f.service b/test/f.service
new file mode 100644 (file)
index 0000000..7dde681
--- /dev/null
@@ -0,0 +1,5 @@
+[Unit]
+Description=F
+
+[Service]
+ExecStart=/bin/true
diff --git a/test/g.service b/test/g.service
new file mode 100644 (file)
index 0000000..cbfa82a
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=G
+Conflicts=e.service
+
+[Service]
+ExecStart=/bin/true
diff --git a/test/h.service b/test/h.service
new file mode 100644 (file)
index 0000000..74a7751
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=H
+Wants=g.service
+
+[Service]
+ExecStart=/bin/true
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
new file mode 100755 (executable)
index 0000000..b18f878
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+# Simple udev rules syntax checker
+#
+# (C) 2010 Canonical Ltd.
+# Author: Martin Pitt <martin.pitt@ubuntu.com>
+#
+# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import re
+import sys
+
+if len(sys.argv) < 2:
+    print >> sys.stderr, 'Usage: %s <rules file> [...]' % sys.argv[0]
+    sys.exit(2)
+
+no_args_tests = re.compile('(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|RESULT|TEST)\s*(?:=|!)=\s*"([^"]*)"$')
+args_tests = re.compile('(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*"([^"]*)"$')
+no_args_assign = re.compile('(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|PROGRAM|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*"([^"]*)"$')
+args_assign = re.compile('(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*"([^"]*)"$')
+
+result = 0
+buffer = ''
+for path in sys.argv[1:]:
+    lineno = 0
+    for line in open(path):
+        lineno += 1
+
+        # handle line continuation
+        if line.endswith('\\\n'):
+            buffer += line[:-2]
+            continue
+        else:
+            line = buffer + line
+            buffer = ''
+
+        # filter out comments and empty lines
+        line = line.strip()
+        if not line or line.startswith('#'):
+            continue
+
+        for clause in line.split(','):
+            clause = clause.strip()
+            if not (no_args_tests.match(clause) or args_tests.match(clause) or
+                    no_args_assign.match(clause) or args_assign.match(clause)):
+
+                print('Invalid line %s:%i: %s' % (path, lineno, line))
+                print('  clause:', clause)
+                print()
+                result = 1
+                break
+
+sys.exit(result)
diff --git a/test/rules-test.sh b/test/rules-test.sh
new file mode 100755 (executable)
index 0000000..1e224ff
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+# Call the udev rule syntax checker on all rules that we ship
+#
+# (C) 2010 Canonical Ltd.
+# Author: Martin Pitt <martin.pitt@ubuntu.com>
+
+[ -n "$srcdir" ] || srcdir=`dirname $0`/..
+
+# skip if we don't have python
+type python >/dev/null 2>&1 || {
+        echo "$0: No python installed, skipping udev rule syntax check"
+        exit 0
+}
+
+$srcdir/test/rule-syntax-check.py `find $srcdir/rules -name '*.rules'`
diff --git a/test/sched_idle_bad.service b/test/sched_idle_bad.service
new file mode 100644 (file)
index 0000000..589a87c
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=Bad sched priority for Idle
+
+[Service]
+ExecStart=/bin/true
+CPUSchedulingPriority=1
diff --git a/test/sched_idle_ok.service b/test/sched_idle_ok.service
new file mode 100644 (file)
index 0000000..262ef3e
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=Sched idle with prio 0
+
+[Service]
+ExecStart=/bin/true
+CPUSchedulingPriority=0
diff --git a/test/sched_rr_bad.service b/test/sched_rr_bad.service
new file mode 100644 (file)
index 0000000..0be534a
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=Bad sched priority for RR
+
+[Service]
+ExecStart=/bin/true
+CPUSchedulingPolicy=rr
+CPUSchedulingPriority=0
+CPUSchedulingPriority=100
diff --git a/test/sched_rr_change.service b/test/sched_rr_change.service
new file mode 100644 (file)
index 0000000..b3e3a00
--- /dev/null
@@ -0,0 +1,9 @@
+[Unit]
+Description=Change prio
+
+[Service]
+ExecStart=/bin/true
+CPUSchedulingPolicy=rr
+CPUSchedulingPriority=1
+CPUSchedulingPriority=2
+CPUSchedulingPriority=99
diff --git a/test/sched_rr_ok.service b/test/sched_rr_ok.service
new file mode 100644 (file)
index 0000000..b88adc5
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=Default prio for RR
+
+[Service]
+ExecStart=/bin/true
+CPUSchedulingPolicy=rr
diff --git a/test/sys.tar.xz b/test/sys.tar.xz
new file mode 100644 (file)
index 0000000..49ee802
Binary files /dev/null and b/test/sys.tar.xz differ
diff --git a/test/test-functions b/test/test-functions
new file mode 100644 (file)
index 0000000..0587cd4
--- /dev/null
@@ -0,0 +1,864 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+export PATH
+
+KERNEL_VER=${KERNEL_VER-$(uname -r)}
+KERNEL_MODS="/lib/modules/$KERNEL_VER/"
+
+setup_basic_dirs() {
+    for d in usr/bin usr/sbin bin etc lib "$libdir" sbin tmp usr var var/log dev proc sys sysroot root run run/lock run/initramfs; do
+        if [ -L "/$d" ]; then
+            inst_symlink "/$d"
+        else
+            inst_dir "/$d"
+        fi
+    done
+
+    ln -sfn /run "$initdir/var/run"
+    ln -sfn /run/lock "$initdir/var/lock"
+}
+
+inst_libs() {
+    local _bin=$1
+    local _so_regex='([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)'
+    local _file _line
+
+    LC_ALL=C ldd "$_bin" 2>/dev/null | while read _line; do
+        [[ $_line = 'not a dynamic executable' ]] && break
+
+        if [[ $_line =~ $_so_regex ]]; then
+            _file=${BASH_REMATCH[1]}
+            [[ -e ${initdir}/$_file ]] && continue
+            inst_library "$_file"
+            continue
+        fi
+
+        if [[ $_line =~ not\ found ]]; then
+            dfatal "Missing a shared library required by $_bin."
+            dfatal "Run \"ldd $_bin\" to find out what it is."
+            dfatal "$_line"
+            dfatal "dracut cannot create an initrd."
+            exit 1
+        fi
+    done
+}
+
+import_testdir() {
+    STATEFILE=".testdir"
+    [[ -e $STATEFILE ]] && . $STATEFILE
+    if [[ -z "$TESTDIR" ]] || [[ ! -d "$TESTDIR" ]]; then
+        TESTDIR=$(mktemp --tmpdir=/var/tmp -d -t systemd-test.XXXXXX)
+        echo "TESTDIR=\"$TESTDIR\"" > $STATEFILE
+        export TESTDIR
+    fi
+}
+
+## @brief Converts numeric logging level to the first letter of level name.
+#
+# @param lvl Numeric logging level in range from 1 to 6.
+# @retval 1 if @a lvl is out of range.
+# @retval 0 if @a lvl is correct.
+# @result Echoes first letter of level name.
+_lvl2char() {
+    case "$1" in
+        1) echo F;;
+        2) echo E;;
+        3) echo W;;
+        4) echo I;;
+        5) echo D;;
+        6) echo T;;
+        *) return 1;;
+    esac
+}
+
+## @brief Internal helper function for _do_dlog()
+#
+# @param lvl Numeric logging level.
+# @param msg Message.
+# @retval 0 It's always returned, even if logging failed.
+#
+# @note This function is not supposed to be called manually. Please use
+# dtrace(), ddebug(), or others instead which wrap this one.
+#
+# This function calls _do_dlog() either with parameter msg, or if
+# none is given, it will read standard input and will use every line as
+# a message.
+#
+# This enables:
+# dwarn "This is a warning"
+# echo "This is a warning" | dwarn
+LOG_LEVEL=4
+
+dlog() {
+    [ -z "$LOG_LEVEL" ] && return 0
+    [ $1 -le $LOG_LEVEL ] || return 0
+    local lvl="$1"; shift
+    local lvlc=$(_lvl2char "$lvl") || return 0
+
+    if [ $# -ge 1 ]; then
+        echo "$lvlc: $*"
+    else
+        while read line; do
+            echo "$lvlc: " "$line"
+        done
+    fi
+}
+
+## @brief Logs message at TRACE level (6)
+#
+# @param msg Message.
+# @retval 0 It's always returned, even if logging failed.
+dtrace() {
+    set +x
+    dlog 6 "$@"
+    [ -n "$debug" ] && set -x || :
+}
+
+## @brief Logs message at DEBUG level (5)
+#
+# @param msg Message.
+# @retval 0 It's always returned, even if logging failed.
+ddebug() {
+#    set +x
+    dlog 5 "$@"
+#    [ -n "$debug" ] && set -x || :
+}
+
+## @brief Logs message at INFO level (4)
+#
+# @param msg Message.
+# @retval 0 It's always returned, even if logging failed.
+dinfo() {
+    set +x
+    dlog 4 "$@"
+    [ -n "$debug" ] && set -x || :
+}
+
+## @brief Logs message at WARN level (3)
+#
+# @param msg Message.
+# @retval 0 It's always returned, even if logging failed.
+dwarn() {
+    set +x
+    dlog 3 "$@"
+    [ -n "$debug" ] && set -x || :
+}
+
+## @brief Logs message at ERROR level (2)
+#
+# @param msg Message.
+# @retval 0 It's always returned, even if logging failed.
+derror() {
+#    set +x
+    dlog 2 "$@"
+#    [ -n "$debug" ] && set -x || :
+}
+
+## @brief Logs message at FATAL level (1)
+#
+# @param msg Message.
+# @retval 0 It's always returned, even if logging failed.
+dfatal() {
+    set +x
+    dlog 1 "$@"
+    [ -n "$debug" ] && set -x || :
+}
+
+
+# Generic substring function.  If $2 is in $1, return 0.
+strstr() { [ "${1#*$2*}" != "$1" ]; }
+
+# normalize_path <path>
+# Prints the normalized path, where it removes any duplicated
+# and trailing slashes.
+# Example:
+# $ normalize_path ///test/test//
+# /test/test
+normalize_path() {
+    shopt -q -s extglob
+    set -- "${1//+(\/)//}"
+    shopt -q -u extglob
+    echo "${1%/}"
+}
+
+# convert_abs_rel <from> <to>
+# Prints the relative path, when creating a symlink to <to> from <from>.
+# Example:
+# $ convert_abs_rel /usr/bin/test /bin/test-2
+# ../../bin/test-2
+# $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test
+convert_abs_rel() {
+    local __current __absolute __abssize __cursize __newpath
+    local -i __i __level
+
+    set -- "$(normalize_path "$1")" "$(normalize_path "$2")"
+
+    # corner case #1 - self looping link
+    [[ "$1" == "$2" ]] && { echo "${1##*/}"; return; }
+
+    # corner case #2 - own dir link
+    [[ "${1%/*}" == "$2" ]] && { echo "."; return; }
+
+    IFS="/" __current=($1)
+    IFS="/" __absolute=($2)
+
+    __abssize=${#__absolute[@]}
+    __cursize=${#__current[@]}
+
+    while [[ ${__absolute[__level]} == ${__current[__level]} ]]
+    do
+        (( __level++ ))
+        if (( __level > __abssize || __level > __cursize ))
+        then
+            break
+        fi
+    done
+
+    for ((__i = __level; __i < __cursize-1; __i++))
+    do
+        if ((__i > __level))
+        then
+            __newpath=$__newpath"/"
+        fi
+        __newpath=$__newpath".."
+    done
+
+    for ((__i = __level; __i < __abssize; __i++))
+    do
+        if [[ -n $__newpath ]]
+        then
+            __newpath=$__newpath"/"
+        fi
+        __newpath=$__newpath${__absolute[__i]}
+    done
+
+    echo "$__newpath"
+}
+
+
+# Install a directory, keeping symlinks as on the original system.
+# Example: if /lib points to /lib64 on the host, "inst_dir /lib/file"
+# will create ${initdir}/lib64, ${initdir}/lib64/file,
+# and a symlink ${initdir}/lib -> lib64.
+inst_dir() {
+    [[ -e ${initdir}/"$1" ]] && return 0  # already there
+
+    local _dir="$1" _part="${1%/*}" _file
+    while [[ "$_part" != "${_part%/*}" ]] && ! [[ -e "${initdir}/${_part}" ]]; do
+        _dir="$_part $_dir"
+        _part=${_part%/*}
+    done
+
+    # iterate over parent directories
+    for _file in $_dir; do
+        [[ -e "${initdir}/$_file" ]] && continue
+        if [[ -L $_file ]]; then
+            inst_symlink "$_file"
+        else
+            # create directory
+            mkdir -m 0755 -p "${initdir}/$_file" || return 1
+            [[ -e "$_file" ]] && chmod --reference="$_file" "${initdir}/$_file"
+            chmod u+w "${initdir}/$_file"
+        fi
+    done
+}
+
+# $1 = file to copy to ramdisk
+# $2 (optional) Name for the file on the ramdisk
+# Location of the image dir is assumed to be $initdir
+# We never overwrite the target if it exists.
+inst_simple() {
+    [[ -f "$1" ]] || return 1
+    strstr "$1" "/" || return 1
+
+    local _src=$1 target="${2:-$1}"
+    if ! [[ -d ${initdir}/$target ]]; then
+        [[ -e ${initdir}/$target ]] && return 0
+        [[ -L ${initdir}/$target ]] && return 0
+        [[ -d "${initdir}/${target%/*}" ]] || inst_dir "${target%/*}"
+    fi
+    # install checksum files also
+    if [[ -e "${_src%/*}/.${_src##*/}.hmac" ]]; then
+        inst "${_src%/*}/.${_src##*/}.hmac" "${target%/*}/.${target##*/}.hmac"
+    fi
+    ddebug "Installing $_src"
+    cp --sparse=always -pfL "$_src" "${initdir}/$target"
+}
+
+# find symlinks linked to given library file
+# $1 = library file
+# Function searches for symlinks by stripping version numbers appended to
+# library filename, checks if it points to the same target and finally
+# prints the list of symlinks to stdout.
+#
+# Example:
+# rev_lib_symlinks libfoo.so.8.1
+# output: libfoo.so.8 libfoo.so
+# (Only if libfoo.so.8 and libfoo.so exists on host system.)
+rev_lib_symlinks() {
+    [[ ! $1 ]] && return 0
+
+    local fn="$1" orig="$(readlink -f "$1")" links=''
+
+    [[ ${fn} =~ .*\.so\..* ]] || return 1
+
+    until [[ ${fn##*.} == so ]]; do
+        fn="${fn%.*}"
+        [[ -L ${fn} && $(readlink -f "${fn}") == ${orig} ]] && links+=" ${fn}"
+    done
+
+    echo "${links}"
+}
+
+# Same as above, but specialized to handle dynamic libraries.
+# It handles making symlinks according to how the original library
+# is referenced.
+inst_library() {
+    local _src="$1" _dest=${2:-$1} _lib _reallib _symlink
+    strstr "$1" "/" || return 1
+    [[ -e $initdir/$_dest ]] && return 0
+    if [[ -L $_src ]]; then
+        # install checksum files also
+        if [[ -e "${_src%/*}/.${_src##*/}.hmac" ]]; then
+            inst "${_src%/*}/.${_src##*/}.hmac" "${_dest%/*}/.${_dest##*/}.hmac"
+        fi
+        _reallib=$(readlink -f "$_src")
+        inst_simple "$_reallib" "$_reallib"
+        inst_dir "${_dest%/*}"
+        [[ -d "${_dest%/*}" ]] && _dest=$(readlink -f "${_dest%/*}")/${_dest##*/}
+        ln -sfn $(convert_abs_rel "${_dest}" "${_reallib}") "${initdir}/${_dest}"
+    else
+        inst_simple "$_src" "$_dest"
+    fi
+
+    # Create additional symlinks.  See rev_symlinks description.
+    for _symlink in $(rev_lib_symlinks $_src) $(rev_lib_symlinks $_reallib); do
+        [[ ! -e $initdir/$_symlink ]] && {
+            ddebug "Creating extra symlink: $_symlink"
+            inst_symlink $_symlink
+        }
+    done
+}
+
+# find a binary.  If we were not passed the full path directly,
+# search in the usual places to find the binary.
+find_binary() {
+    if [[ -z ${1##/*} ]]; then
+        if [[ -x $1 ]] || { strstr "$1" ".so" && ldd $1 &>/dev/null; };  then
+            echo $1
+            return 0
+        fi
+    fi
+
+    type -P $1
+}
+
+# Same as above, but specialized to install binary executables.
+# Install binary executable, and all shared library dependencies, if any.
+inst_binary() {
+    local _bin _target
+    _bin=$(find_binary "$1") || return 1
+    _target=${2:-$_bin}
+    [[ -e $initdir/$_target ]] && return 0
+    [[ -L $_bin ]] && inst_symlink $_bin $_target && return 0
+    local _file _line
+    local _so_regex='([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)'
+    # I love bash!
+    LC_ALL=C ldd "$_bin" 2>/dev/null | while read _line; do
+        [[ $_line = 'not a dynamic executable' ]] && break
+
+        if [[ $_line =~ $_so_regex ]]; then
+            _file=${BASH_REMATCH[1]}
+            [[ -e ${initdir}/$_file ]] && continue
+            inst_library "$_file"
+            continue
+        fi
+
+        if [[ $_line =~ not\ found ]]; then
+            dfatal "Missing a shared library required by $_bin."
+            dfatal "Run \"ldd $_bin\" to find out what it is."
+            dfatal "$_line"
+            dfatal "dracut cannot create an initrd."
+            exit 1
+        fi
+    done
+    inst_simple "$_bin" "$_target"
+}
+
+# same as above, except for shell scripts.
+# If your shell script does not start with shebang, it is not a shell script.
+inst_script() {
+    local _bin
+    _bin=$(find_binary "$1") || return 1
+    shift
+    local _line _shebang_regex
+    read -r -n 80 _line <"$_bin"
+    # If debug is set, clean unprintable chars to prevent messing up the term
+    [[ $debug ]] && _line=$(echo -n "$_line" | tr -c -d '[:print:][:space:]')
+    _shebang_regex='(#! *)(/[^ ]+).*'
+    [[ $_line =~ $_shebang_regex ]] || return 1
+    inst "${BASH_REMATCH[2]}" && inst_simple "$_bin" "$@"
+}
+
+# same as above, but specialized for symlinks
+inst_symlink() {
+    local _src=$1 _target=${2:-$1} _realsrc
+    strstr "$1" "/" || return 1
+    [[ -L $1 ]] || return 1
+    [[ -L $initdir/$_target ]] && return 0
+    _realsrc=$(readlink -f "$_src")
+    if ! [[ -e $initdir/$_realsrc ]]; then
+        if [[ -d $_realsrc ]]; then
+            inst_dir "$_realsrc"
+        else
+            inst "$_realsrc"
+        fi
+    fi
+    [[ ! -e $initdir/${_target%/*} ]] && inst_dir "${_target%/*}"
+    [[ -d ${_target%/*} ]] && _target=$(readlink -f ${_target%/*})/${_target##*/}
+    ln -sfn $(convert_abs_rel "${_target}" "${_realsrc}") "$initdir/$_target"
+}
+
+# attempt to install any programs specified in a udev rule
+inst_rule_programs() {
+    local _prog _bin
+
+    if grep -qE 'PROGRAM==?"[^ "]+' "$1"; then
+        for _prog in $(grep -E 'PROGRAM==?"[^ "]+' "$1" | sed -r 's/.*PROGRAM==?"([^ "]+).*/\1/'); do
+            if [ -x /lib/udev/$_prog ]; then
+                _bin=/lib/udev/$_prog
+            else
+                _bin=$(find_binary "$_prog") || {
+                    dinfo "Skipping program $_prog using in udev rule $(basename $1) as it cannot be found"
+                    continue;
+                }
+            fi
+
+            #dinfo "Installing $_bin due to it's use in the udev rule $(basename $1)"
+            dracut_install "$_bin"
+        done
+    fi
+}
+
+# udev rules always get installed in the same place, so
+# create a function to install them to make life simpler.
+inst_rules() {
+    local _target=/etc/udev/rules.d _rule _found
+
+    inst_dir "/lib/udev/rules.d"
+    inst_dir "$_target"
+    for _rule in "$@"; do
+        if [ "${rule#/}" = "$rule" ]; then
+            for r in /lib/udev/rules.d /etc/udev/rules.d; do
+                if [[ -f $r/$_rule ]]; then
+                    _found="$r/$_rule"
+                    inst_simple "$_found"
+                    inst_rule_programs "$_found"
+                fi
+            done
+        fi
+        for r in '' ./ $dracutbasedir/rules.d/; do
+            if [[ -f ${r}$_rule ]]; then
+                _found="${r}$_rule"
+                inst_simple "$_found" "$_target/${_found##*/}"
+                inst_rule_programs "$_found"
+            fi
+        done
+        [[ $_found ]] || dinfo "Skipping udev rule: $_rule"
+    done
+}
+
+# general purpose installation function
+# Same args as above.
+inst() {
+    local _x
+
+    case $# in
+        1) ;;
+        2) [[ ! $initdir && -d $2 ]] && export initdir=$2
+            [[ $initdir = $2 ]] && set $1;;
+        3) [[ -z $initdir ]] && export initdir=$2
+            set $1 $3;;
+        *) dfatal "inst only takes 1 or 2 or 3 arguments"
+            exit 1;;
+    esac
+    for _x in inst_symlink inst_script inst_binary inst_simple; do
+        $_x "$@" && return 0
+    done
+    return 1
+}
+
+# install any of listed files
+#
+# If first argument is '-d' and second some destination path, first accessible
+# source is installed into this path, otherwise it will installed in the same
+# path as source.  If none of listed files was installed, function return 1.
+# On first successful installation it returns with 0 status.
+#
+# Example:
+#
+# inst_any -d /bin/foo /bin/bar /bin/baz
+#
+# Lets assume that /bin/baz exists, so it will be installed as /bin/foo in
+# initramfs.
+inst_any() {
+    local to f
+
+    [[ $1 = '-d' ]] && to="$2" && shift 2
+
+    for f in "$@"; do
+        if [[ -e $f ]]; then
+            [[ $to ]] && inst "$f" "$to" && return 0
+            inst "$f" && return 0
+        fi
+    done
+
+    return 1
+}
+
+# dracut_install [-o ] <file> [<file> ... ]
+# Install <file> to the initramfs image
+# -o optionally install the <file> and don't fail, if it is not there
+dracut_install() {
+    local _optional=no
+    if [[ $1 = '-o' ]]; then
+        _optional=yes
+        shift
+    fi
+    while (($# > 0)); do
+        if ! inst "$1" ; then
+            if [[ $_optional = yes ]]; then
+                dinfo "Skipping program $1 as it cannot be found and is" \
+                    "flagged to be optional"
+            else
+                dfatal "Failed to install $1"
+                exit 1
+            fi
+        fi
+        shift
+    done
+}
+
+# Install a single kernel module along with any firmware it may require.
+# $1 = full path to kernel module to install
+install_kmod_with_fw() {
+    # no need to go further if the module is already installed
+
+    [[ -e "${initdir}/lib/modules/$KERNEL_VER/${1##*/lib/modules/$KERNEL_VER/}" ]] \
+        && return 0
+
+    [[ -e "$initdir/.kernelmodseen/${1##*/}" ]] && return 0
+
+    if [[ $omit_drivers ]]; then
+        local _kmod=${1##*/}
+        _kmod=${_kmod%.ko}
+        _kmod=${_kmod/-/_}
+        if [[ "$_kmod" =~ $omit_drivers ]]; then
+            dinfo "Omitting driver $_kmod"
+            return 1
+        fi
+        if [[ "${1##*/lib/modules/$KERNEL_VER/}" =~ $omit_drivers ]]; then
+            dinfo "Omitting driver $_kmod"
+            return 1
+        fi
+    fi
+
+    [ -d "$initdir/.kernelmodseen" ] && \
+        > "$initdir/.kernelmodseen/${1##*/}"
+
+    inst_simple "$1" "/lib/modules/$KERNEL_VER/${1##*/lib/modules/$KERNEL_VER/}" \
+        || return $?
+
+    local _modname=${1##*/} _fwdir _found _fw
+    _modname=${_modname%.ko*}
+    for _fw in $(modinfo -k $KERNEL_VER -F firmware $1 2>/dev/null); do
+        _found=''
+        for _fwdir in $fw_dir; do
+            if [[ -d $_fwdir && -f $_fwdir/$_fw ]]; then
+                inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw"
+                _found=yes
+            fi
+        done
+        if [[ $_found != yes ]]; then
+            if ! grep -qe "\<${_modname//-/_}\>" /proc/modules; then
+                dinfo "Possible missing firmware \"${_fw}\" for kernel module" \
+                    "\"${_modname}.ko\""
+            else
+                dwarn "Possible missing firmware \"${_fw}\" for kernel module" \
+                    "\"${_modname}.ko\""
+            fi
+        fi
+    done
+    return 0
+}
+
+# Do something with all the dependencies of a kernel module.
+# Note that kernel modules depend on themselves using the technique we use
+# $1 = function to call for each dependency we find
+#      It will be passed the full path to the found kernel module
+# $2 = module to get dependencies for
+# rest of args = arguments to modprobe
+# _fderr specifies FD passed from surrounding scope
+for_each_kmod_dep() {
+    local _func=$1 _kmod=$2 _cmd _modpath _options _found=0
+    shift 2
+    modprobe "$@" --ignore-install --show-depends $_kmod 2>&${_fderr} | (
+        while read _cmd _modpath _options; do
+            [[ $_cmd = insmod ]] || continue
+            $_func ${_modpath} || exit $?
+            _found=1
+        done
+        [[ $_found -eq 0 ]] && exit 1
+        exit 0
+    )
+}
+
+# filter kernel modules to install certain modules that meet specific
+# requirements.
+# $1 = search only in subdirectory of /kernel/$1
+# $2 = function to call with module name to filter.
+#      This function will be passed the full path to the module to test.
+# The behavior of this function can vary depending on whether $hostonly is set.
+# If it is, we will only look at modules that are already in memory.
+# If it is not, we will look at all kernel modules
+# This function returns the full filenames of modules that match $1
+filter_kernel_modules_by_path () (
+    local _modname _filtercmd
+    if ! [[ $hostonly ]]; then
+        _filtercmd='find "$KERNEL_MODS/kernel/$1" "$KERNEL_MODS/extra"'
+        _filtercmd+=' "$KERNEL_MODS/weak-updates" -name "*.ko" -o -name "*.ko.gz"'
+        _filtercmd+=' -o -name "*.ko.xz"'
+        _filtercmd+=' 2>/dev/null'
+    else
+        _filtercmd='cut -d " " -f 1 </proc/modules|xargs modinfo -F filename '
+        _filtercmd+='-k $KERNEL_VER 2>/dev/null'
+    fi
+    for _modname in $(eval $_filtercmd); do
+        case $_modname in
+            *.ko) "$2" "$_modname" && echo "$_modname";;
+            *.ko.gz) gzip -dc "$_modname" > $initdir/$$.ko
+                $2 $initdir/$$.ko && echo "$_modname"
+                rm -f $initdir/$$.ko
+                ;;
+            *.ko.xz) xz -dc "$_modname" > $initdir/$$.ko
+                $2 $initdir/$$.ko && echo "$_modname"
+                rm -f $initdir/$$.ko
+                ;;
+        esac
+    done
+)
+find_kernel_modules_by_path () (
+    if ! [[ $hostonly ]]; then
+        find "$KERNEL_MODS/kernel/$1" "$KERNEL_MODS/extra" "$KERNEL_MODS/weak-updates" \
+          -name "*.ko" -o -name "*.ko.gz" -o -name "*.ko.xz" 2>/dev/null
+    else
+        cut -d " " -f 1 </proc/modules \
+        | xargs modinfo -F filename -k $KERNEL_VER 2>/dev/null
+    fi
+)
+
+filter_kernel_modules () {
+    filter_kernel_modules_by_path  drivers  "$1"
+}
+
+find_kernel_modules () {
+    find_kernel_modules_by_path  drivers
+}
+
+# instmods [-c] <kernel module> [<kernel module> ... ]
+# instmods [-c] <kernel subsystem>
+# install kernel modules along with all their dependencies.
+# <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
+instmods() {
+    [[ $no_kernel = yes ]] && return
+    # called [sub]functions inherit _fderr
+    local _fderr=9
+    local _check=no
+    if [[ $1 = '-c' ]]; then
+        _check=yes
+        shift
+    fi
+
+    function inst1mod() {
+        local _ret=0 _mod="$1"
+        case $_mod in
+            =*)
+                if [ -f $KERNEL_MODS/modules.${_mod#=} ]; then
+                    ( [[ "$_mpargs" ]] && echo $_mpargs
+                      cat "${KERNEL_MODS}/modules.${_mod#=}" ) \
+                    | instmods
+                else
+                    ( [[ "$_mpargs" ]] && echo $_mpargs
+                      find "$KERNEL_MODS" -path "*/${_mod#=}/*" -printf '%f\n' ) \
+                    | instmods
+                fi
+                ;;
+            --*) _mpargs+=" $_mod" ;;
+            i2o_scsi) return ;; # Do not load this diagnostic-only module
+            *)
+                _mod=${_mod##*/}
+                # if we are already installed, skip this module and go on
+                # to the next one.
+                [[ -f "$initdir/.kernelmodseen/${_mod%.ko}.ko" ]] && return
+
+                if [[ $omit_drivers ]] && [[ "$1" =~ $omit_drivers ]]; then
+                    dinfo "Omitting driver ${_mod##$KERNEL_MODS}"
+                    return
+                fi
+                # If we are building a host-specific initramfs and this
+                # module is not already loaded, move on to the next one.
+                [[ $hostonly ]] && ! grep -qe "\<${_mod//-/_}\>" /proc/modules \
+                    && ! echo $add_drivers | grep -qe "\<${_mod}\>" \
+                    && return
+
+                # We use '-d' option in modprobe only if modules prefix path
+                # differs from default '/'.  This allows us to use Dracut with
+                # old version of modprobe which doesn't have '-d' option.
+                local _moddirname=${KERNEL_MODS%%/lib/modules/*}
+                [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/"
+
+                # ok, load the module, all its dependencies, and any firmware
+                # it may require
+                for_each_kmod_dep install_kmod_with_fw $_mod \
+                    --set-version $KERNEL_VER ${_moddirname} $_mpargs
+                ((_ret+=$?))
+                ;;
+        esac
+        return $_ret
+    }
+
+    function instmods_1() {
+        local _mod _mpargs
+        if (($# == 0)); then  # filenames from stdin
+            while read _mod; do
+                inst1mod "${_mod%.ko*}" || {
+                    if [ "$_check" = "yes" ]; then
+                        dfatal "Failed to install $_mod"
+                        return 1
+                    fi
+                }
+            done
+        fi
+        while (($# > 0)); do  # filenames as arguments
+            inst1mod ${1%.ko*} || {
+                if [ "$_check" = "yes" ]; then
+                    dfatal "Failed to install $1"
+                    return 1
+                fi
+            }
+            shift
+        done
+        return 0
+    }
+
+    local _ret _filter_not_found='FATAL: Module .* not found.'
+    set -o pipefail
+    # Capture all stderr from modprobe to _fderr. We could use {var}>...
+    # redirections, but that would make dracut require bash4 at least.
+    eval "( instmods_1 \"\$@\" ) ${_fderr}>&1" \
+    | while read line; do [[ "$line" =~ $_filter_not_found ]] && echo $line || echo $line >&2 ;done | derror
+    _ret=$?
+    set +o pipefail
+    return $_ret
+}
+
+# inst_libdir_file [-n <pattern>] <file> [<file>...]
+# Install a <file> located on a lib directory to the initramfs image
+# -n <pattern> install non-matching files
+inst_libdir_file() {
+    if [[ "$1" == "-n" ]]; then
+        local _pattern=$1
+        shift 2
+        for _dir in $libdirs; do
+            for _i in "$@"; do
+                for _f in "$_dir"/$_i; do
+                    [[ "$_i" =~ $_pattern ]] || continue
+                    [[ -e "$_i" ]] && dracut_install "$_i"
+                done
+            done
+        done
+    else
+        for _dir in $libdirs; do
+            for _i in "$@"; do
+                for _f in "$_dir"/$_i; do
+                    [[ -e "$_f" ]] && dracut_install "$_f"
+                done
+            done
+        done
+    fi
+}
+
+check_qemu() {
+    command -v qemu-kvm &>/dev/null && [[ -c /dev/kvm ]]
+}
+
+check_nspawn() {
+    [[ -d /sys/fs/cgroup/systemd ]]
+}
+
+
+do_test() {
+    if [[ $UID != "0" ]]; then
+        echo "TEST: $TEST_DESCRIPTION [SKIPPED]: not root" >&2
+        exit 0
+    fi
+
+# Detect lib paths
+    [[ $libdir ]] || for libdir in /lib64 /lib; do
+        [[ -d $libdir ]] && libdirs+=" $libdir" && break
+    done
+
+    [[ $usrlibdir ]] || for usrlibdir in /usr/lib64 /usr/lib; do
+        [[ -d $usrlibdir ]] && libdirs+=" $usrlibdir" && break
+    done
+
+    import_testdir
+
+    while (($# > 0)); do
+        case $1 in
+            --run)
+                echo "TEST RUN: $TEST_DESCRIPTION"
+                test_run
+                ret=$?
+                if [ $ret -eq 0 ]; then
+                    echo "TEST RUN: $TEST_DESCRIPTION [OK]"
+                else
+                    echo "TEST RUN: $TEST_DESCRIPTION [FAILED]"
+                fi
+                exit $ret;;
+            --setup)
+                echo "TEST SETUP: $TEST_DESCRIPTION"
+                test_setup
+                exit $?;;
+            --clean)
+                echo "TEST CLEANUP: $TEST_DESCRIPTION"
+                test_cleanup
+                rm -fr "$TESTDIR"
+                rm -f .testdir
+                exit $?;;
+            --all)
+                echo -n "TEST: $TEST_DESCRIPTION ";
+                (
+                    test_setup && test_run
+                    ret=$?
+                    test_cleanup
+                    rm -fr "$TESTDIR"
+                    rm -f .testdir
+                    exit $ret
+                ) </dev/null >test.log 2>&1
+                ret=$?
+                if [ $ret -eq 0 ]; then
+                    rm test.log
+                    echo "[OK]"
+                else
+                    echo "[FAILED]"
+                    echo "see $(pwd)/test.log"
+                fi
+                exit $ret;;
+            *) break ;;
+        esac
+        shift
+    done
+}
diff --git a/test/udev-test.pl b/test/udev-test.pl
new file mode 100755 (executable)
index 0000000..a9f5db0
--- /dev/null
@@ -0,0 +1,1530 @@
+#!/usr/bin/perl
+
+# udev test
+#
+# Provides automated testing of the udev binary.
+# The whole test is self contained in this file, except the matching sysfs tree.
+# Simply extend the @tests array, to add a new test variant.
+#
+# Every test is driven by its own temporary config file.
+# This program prepares the environment, creates the config and calls udev.
+#
+# udev parses the rules, looks at the provided sysfs and
+# first creates and then removes the device node.
+# After creation and removal the result is checked against the
+# expected value and the result is printed.
+#
+# Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
+# Copyright (C) 2004 Leann Ogasawara <ogasawara@osdl.org>
+
+use warnings;
+use strict;
+
+my $udev_bin            = "./test-udev";
+my $valgrind            = 0;
+my $udev_bin_valgrind   = "valgrind --tool=memcheck --leak-check=yes --quiet $udev_bin";
+my $udev_dev            = "test/dev";
+my $udev_run            = "test/run";
+my $udev_rules_dir      = "$udev_run/udev/rules.d";
+my $udev_rules          = "$udev_rules_dir/udev-test.rules";
+
+my @tests = (
+        {
+                desc            => "no rules",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "sda" ,
+                exp_rem_error   => "yes",
+                rules           => <<EOF
+#
+EOF
+        },
+        {
+                desc            => "label test of scsi disc",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "boot_disk" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n"
+KERNEL=="ttyACM0", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "label test of scsi disc",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "boot_disk" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n"
+KERNEL=="ttyACM0", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "label test of scsi disc",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "boot_disk" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n"
+KERNEL=="ttyACM0", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "label test of scsi partition",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "boot_disk1" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="boot_disk%n"
+EOF
+        },
+        {
+                desc            => "label test of pattern match",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "boot_disk1" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="?ATA", SYMLINK+="boot_disk%n-1"
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA?", SYMLINK+="boot_disk%n-2"
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="A??", SYMLINK+="boot_disk%n"
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATAS", SYMLINK+="boot_disk%n-3"
+EOF
+        },
+        {
+                desc            => "label test of multiple sysfs files",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "boot_disk1" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS X ", SYMLINK+="boot_diskX%n"
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", SYMLINK+="boot_disk%n"
+EOF
+        },
+        {
+                desc            => "label test of max sysfs files (skip invalid rule)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "boot_disk1" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", ATTRS{scsi_level}=="6", ATTRS{rev}=="4.06", ATTRS{type}=="0", ATTRS{queue_depth}=="32", SYMLINK+="boot_diskXX%n"
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", ATTRS{scsi_level}=="6", ATTRS{rev}=="4.06", ATTRS{type}=="0", SYMLINK+="boot_disk%n"
+EOF
+        },
+        {
+                desc            => "catch device by *",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem/0" ,
+                rules           => <<EOF
+KERNEL=="ttyACM*", SYMLINK+="modem/%n"
+EOF
+        },
+        {
+                desc            => "catch device by * - take 2",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem/0" ,
+                rules           => <<EOF
+KERNEL=="*ACM1", SYMLINK+="bad"
+KERNEL=="*ACM0", SYMLINK+="modem/%n"
+EOF
+        },
+        {
+                desc            => "catch device by ?",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem/0" ,
+                rules           => <<EOF
+KERNEL=="ttyACM??*", SYMLINK+="modem/%n-1"
+KERNEL=="ttyACM??", SYMLINK+="modem/%n-2"
+KERNEL=="ttyACM?", SYMLINK+="modem/%n"
+EOF
+        },
+        {
+                desc            => "catch device by character class",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem/0" ,
+                rules           => <<EOF
+KERNEL=="ttyACM[A-Z]*", SYMLINK+="modem/%n-1"
+KERNEL=="ttyACM?[0-9]", SYMLINK+="modem/%n-2"
+KERNEL=="ttyACM[0-9]*", SYMLINK+="modem/%n"
+EOF
+        },
+        {
+                desc            => "replace kernel name",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem" ,
+                rules           => <<EOF
+KERNEL=="ttyACM0", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "Handle comment lines in config file (and replace kernel name)",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem" ,
+                rules           => <<EOF
+# this is a comment
+KERNEL=="ttyACM0", SYMLINK+="modem"
+
+EOF
+        },
+        {
+                desc            => "Handle comment lines in config file with whitespace (and replace kernel name)",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem" ,
+                rules           => <<EOF
+ # this is a comment with whitespace before the comment
+KERNEL=="ttyACM0", SYMLINK+="modem"
+
+EOF
+        },
+        {
+                desc            => "Handle whitespace only lines (and replace kernel name)",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "whitespace" ,
+                rules           => <<EOF
+
+
+
+ # this is a comment with whitespace before the comment
+KERNEL=="ttyACM0", SYMLINK+="whitespace"
+
+
+
+EOF
+        },
+        {
+                desc            => "Handle empty lines in config file (and replace kernel name)",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem" ,
+                rules           => <<EOF
+
+KERNEL=="ttyACM0", SYMLINK+="modem"
+
+EOF
+        },
+        {
+                desc            => "Handle backslashed multi lines in config file (and replace kernel name)",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem" ,
+                rules           => <<EOF
+KERNEL=="ttyACM0", \\
+SYMLINK+="modem"
+
+EOF
+        },
+        {
+                desc            => "preserve backslashes, if they are not for a newline",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "aaa",
+                rules           => <<EOF
+KERNEL=="ttyACM0", PROGRAM=="/bin/echo -e \\101", RESULT=="A", SYMLINK+="aaa"
+EOF
+        },
+        {
+                desc            => "Handle stupid backslashed multi lines in config file (and replace kernel name)",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem" ,
+                rules           => <<EOF
+
+#
+\\
+
+\\
+
+#\\
+
+KERNEL=="ttyACM0", \\
+        SYMLINK+="modem"
+
+EOF
+        },
+        {
+                desc            => "subdirectory handling",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "sub/direct/ory/modem" ,
+                rules           => <<EOF
+KERNEL=="ttyACM0", SYMLINK+="sub/direct/ory/modem"
+EOF
+        },
+        {
+                desc            => "parent device name match of scsi partition",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "first_disk5" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="first_disk%n"
+EOF
+        },
+        {
+                desc            => "test substitution chars",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="Major:%M:minor:%m:kernelnumber:%n:id:%b"
+EOF
+        },
+        {
+                desc            => "import of shell-value returned from program",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node12345678",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", IMPORT{program}="/bin/echo -e \' TEST_KEY=12345678\\n  TEST_key2=98765\'", SYMLINK+="node\$env{TEST_KEY}"
+KERNEL=="ttyACM0", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "sustitution of sysfs value (%s{file})",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "disk-ATA-sda" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", SYMLINK+="disk-%s{vendor}-%k"
+KERNEL=="ttyACM0", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "program result substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "special-device-5" ,
+                not_exp_name    => "not" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="-special-*", SYMLINK+="not"
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-*", SYMLINK+="%c-%n"
+EOF
+        },
+        {
+                desc            => "program result substitution (newline removal)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "newline_removed" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo test", RESULT=="test", SYMLINK+="newline_removed"
+EOF
+        },
+        {
+                desc            => "program result substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "test-0:0:0:0" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n test-%b", RESULT=="test-0:0*", SYMLINK+="%c"
+EOF
+        },
+        {
+                desc            => "program with lots of arguments",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "foo9" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="%c{7}"
+EOF
+        },
+        {
+                desc            => "program with subshell",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "bar9" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'echo foo3 foo4 foo5 foo6 foo7 foo8 foo9 | sed  s/foo9/bar9/'", KERNEL=="sda5", SYMLINK+="%c{7}"
+EOF
+        },
+        {
+                desc            => "program arguments combined with apostrophes",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "foo7" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n 'foo3 foo4'   'foo5   foo6   foo7 foo8'", KERNEL=="sda5", SYMLINK+="%c{5}"
+EOF
+        },
+        {
+                desc            => "characters before the %c{N} substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "my-foo9" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="my-%c{7}"
+EOF
+        },
+        {
+                desc            => "substitute the second to last argument",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "my-foo8" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo3 foo4 foo5 foo6 foo7 foo8 foo9", KERNEL=="sda5", SYMLINK+="my-%c{6}"
+EOF
+        },
+        {
+                desc            => "test substitution by variable name",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="Major:\$major-minor:\$minor-kernelnumber:\$number-id:\$id"
+EOF
+        },
+        {
+                desc            => "test substitution by variable name 2",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="Major:\$major-minor:%m-kernelnumber:\$number-id:\$id"
+EOF
+        },
+        {
+                desc            => "test substitution by variable name 3",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "850:0:0:05" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="%M%m%b%n"
+EOF
+        },
+        {
+                desc            => "test substitution by variable name 4",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "855" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="\$major\$minor\$number"
+EOF
+        },
+        {
+                desc            => "test substitution by variable name 5",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "8550:0:0:0" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", DEVPATH=="*/sda/*", SYMLINK+="\$major%m%n\$id"
+EOF
+        },
+        {
+                desc            => "non matching SUBSYSTEMS for device with no parent",
+                devpath         => "/devices/virtual/tty/console",
+                exp_name        => "TTY",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n foo", RESULT=="foo", SYMLINK+="foo"
+KERNEL=="console", SYMLINK+="TTY"
+EOF
+        },
+        {
+                desc            => "non matching SUBSYSTEMS",
+                devpath         => "/devices/virtual/tty/console",
+                exp_name        => "TTY" ,
+                rules                => <<EOF
+SUBSYSTEMS=="foo", ATTRS{dev}=="5:1", SYMLINK+="foo"
+KERNEL=="console", SYMLINK+="TTY"
+EOF
+        },
+        {
+                desc            => "ATTRS match",
+                devpath         => "/devices/virtual/tty/console",
+                exp_name        => "foo" ,
+                rules           => <<EOF
+KERNEL=="console", SYMLINK+="TTY"
+ATTRS{dev}=="5:1", SYMLINK+="foo"
+EOF
+        },
+        {
+                desc            => "ATTR (empty file)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "empty" ,
+                rules           => <<EOF
+KERNEL=="sda", ATTR{test_empty_file}=="?*", SYMLINK+="something"
+KERNEL=="sda", ATTR{test_empty_file}!="", SYMLINK+="not-empty"
+KERNEL=="sda", ATTR{test_empty_file}=="", SYMLINK+="empty"
+KERNEL=="sda", ATTR{test_empty_file}!="?*", SYMLINK+="not-something"
+EOF
+        },
+        {
+                desc            => "ATTR (non-existent file)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "non-existent" ,
+                rules           => <<EOF
+KERNEL=="sda", ATTR{nofile}=="?*", SYMLINK+="something"
+KERNEL=="sda", ATTR{nofile}!="", SYMLINK+="not-empty"
+KERNEL=="sda", ATTR{nofile}=="", SYMLINK+="empty"
+KERNEL=="sda", ATTR{nofile}!="?*", SYMLINK+="not-something"
+KERNEL=="sda", TEST!="nofile", SYMLINK+="non-existent"
+KERNEL=="sda", SYMLINK+="wrong"
+EOF
+        },
+        {
+                desc            => "program and bus type match",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "scsi-0:0:0:0" ,
+                rules           => <<EOF
+SUBSYSTEMS=="usb", PROGRAM=="/bin/echo -n usb-%b", SYMLINK+="%c"
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n scsi-%b", SYMLINK+="%c"
+SUBSYSTEMS=="foo", PROGRAM=="/bin/echo -n foo-%b", SYMLINK+="%c"
+EOF
+        },
+        {
+                desc            => "sysfs parent hierarchy",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem" ,
+                rules           => <<EOF
+ATTRS{idProduct}=="007b", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "name test with ! in the name",
+                devpath         => "/devices/virtual/block/fake!blockdev0",
+                exp_name        => "is/a/fake/blockdev0" ,
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", SYMLINK+="is/not/a/%k"
+SUBSYSTEM=="block", SYMLINK+="is/a/%k"
+KERNEL=="ttyACM0", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "name test with ! in the name, but no matching rule",
+                devpath         => "/devices/virtual/block/fake!blockdev0",
+                exp_name        => "fake/blockdev0" ,
+                exp_rem_error   => "yes",
+                rules           => <<EOF
+KERNEL=="ttyACM0", SYMLINK+="modem"
+EOF
+        },
+        {
+                desc            => "KERNELS rule",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "scsi-0:0:0:0",
+                rules           => <<EOF
+SUBSYSTEMS=="usb", KERNELS=="0:0:0:0", SYMLINK+="not-scsi"
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:1", SYMLINK+="no-match"
+SUBSYSTEMS=="scsi", KERNELS==":0", SYMLINK+="short-id"
+SUBSYSTEMS=="scsi", KERNELS=="/0:0:0:0", SYMLINK+="no-match"
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="scsi-0:0:0:0"
+EOF
+        },
+        {
+                desc            => "KERNELS wildcard all",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "scsi-0:0:0:0",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="*:1", SYMLINK+="no-match"
+SUBSYSTEMS=="scsi", KERNELS=="*:0:1", SYMLINK+="no-match"
+SUBSYSTEMS=="scsi", KERNELS=="*:0:0:1", SYMLINK+="no-match"
+SUBSYSTEMS=="scsi", KERNEL=="0:0:0:0", SYMLINK+="before"
+SUBSYSTEMS=="scsi", KERNELS=="*", SYMLINK+="scsi-0:0:0:0"
+EOF
+        },
+        {
+                desc            => "KERNELS wildcard partial",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "scsi-0:0:0:0",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="before"
+SUBSYSTEMS=="scsi", KERNELS=="*:0", SYMLINK+="scsi-0:0:0:0"
+EOF
+        },
+        {
+                desc            => "KERNELS wildcard partial 2",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "scsi-0:0:0:0",
+                rules                => <<EOF
+SUBSYSTEMS=="scsi", KERNELS=="0:0:0:0", SYMLINK+="before"
+SUBSYSTEMS=="scsi", KERNELS=="*:0:0:0", SYMLINK+="scsi-0:0:0:0"
+EOF
+        },
+        {
+                desc            => "substitute attr with link target value (first match)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "driver-is-sd",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", SYMLINK+="driver-is-\$attr{driver}"
+EOF
+        },
+        {
+                desc            => "substitute attr with link target value (currently selected device)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "driver-is-ahci",
+                rules           => <<EOF
+SUBSYSTEMS=="pci", SYMLINK+="driver-is-\$attr{driver}"
+EOF
+        },
+        {
+                desc            => "ignore ATTRS attribute whitespace",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "ignored",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE  SPACE", SYMLINK+="ignored"
+EOF
+        },
+        {
+                desc            => "do not ignore ATTRS attribute whitespace",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "matched-with-space",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE  SPACE ", SYMLINK+="wrong-to-ignore"
+SUBSYSTEMS=="scsi", ATTRS{whitespace_test}=="WHITE  SPACE   ", SYMLINK+="matched-with-space"
+EOF
+        },
+        {
+                desc            => "permissions USER=bad GROUP=name",
+                devpath         => "/devices/virtual/tty/tty33",
+                exp_name        => "tty33",
+                exp_perms       => "0:0:0600",
+                rules           => <<EOF
+KERNEL=="tty33", OWNER="bad", GROUP="name"
+EOF
+        },
+        {
+                desc            => "permissions OWNER=5000",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                exp_perms       => "5000::0600",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="5000"
+EOF
+        },
+        {
+                desc            => "permissions GROUP=100",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                exp_perms       => ":100:0660",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", GROUP="100"
+EOF
+        },
+        {
+                desc            => "textual user id",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                exp_perms       => "nobody::0600",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="nobody"
+EOF
+        },
+        {
+                desc            => "textual group id",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                exp_perms       => ":daemon:0660",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", GROUP="daemon"
+EOF
+        },
+        {
+                desc            => "textual user/group id",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                exp_perms       => "root:mail:0660",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="root", GROUP="mail"
+EOF
+        },
+        {
+                desc            => "permissions MODE=0777",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                exp_perms       => "::0777",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", MODE="0777"
+EOF
+        },
+        {
+                desc            => "permissions OWNER=5000 GROUP=100 MODE=0777",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                exp_perms       => "5000:100:0777",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", OWNER="5000", GROUP="100", MODE="0777"
+EOF
+        },
+        {
+                desc            => "permissions OWNER to 5000",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "ttyACM0",
+                exp_perms       => "5000::",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", OWNER="5000"
+EOF
+        },
+        {
+                desc            => "permissions GROUP to 100",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "ttyACM0",
+                exp_perms       => ":100:0660",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", GROUP="100"
+EOF
+        },
+        {
+                desc            => "permissions MODE to 0060",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "ttyACM0",
+                exp_perms       => "::0060",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", MODE="0060"
+EOF
+        },
+        {
+                desc            => "permissions OWNER, GROUP, MODE",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "ttyACM0",
+                exp_perms       => "5000:100:0777",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", OWNER="5000", GROUP="100", MODE="0777"
+EOF
+        },
+        {
+                desc            => "permissions only rule",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "ttyACM0",
+                exp_perms       => "5000:100:0777",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", OWNER="5000", GROUP="100", MODE="0777"
+KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n"
+EOF
+        },
+        {
+                desc            => "multiple permissions only rule",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "ttyACM0",
+                exp_perms       => "3000:4000:0777",
+                rules           => <<EOF
+SUBSYSTEM=="tty", OWNER="3000"
+SUBSYSTEM=="tty", GROUP="4000"
+SUBSYSTEM=="tty", MODE="0777"
+KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n"
+EOF
+        },
+        {
+                desc            => "permissions only rule with override at SYMLINK+ rule",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "ttyACM0",
+                exp_perms       => "3000:8000:0777",
+                rules           => <<EOF
+SUBSYSTEM=="tty", OWNER="3000"
+SUBSYSTEM=="tty", GROUP="4000"
+SUBSYSTEM=="tty", MODE="0777"
+KERNEL=="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444"
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", GROUP="8000"
+EOF
+        },
+        {
+                desc            => "major/minor number test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                exp_majorminor  => "8:0",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node"
+EOF
+        },
+        {
+                desc            => "big major number test",
+                devpath         => "/devices/virtual/misc/misc-fake1",
+                exp_name        => "node",
+                exp_majorminor  => "4095:1",
+                rules                => <<EOF
+KERNEL=="misc-fake1", SYMLINK+="node"
+EOF
+        },
+        {
+                desc            => "big major and big minor number test",
+                devpath         => "/devices/virtual/misc/misc-fake89999",
+                exp_name        => "node",
+                exp_majorminor  => "4095:89999",
+                rules           => <<EOF
+KERNEL=="misc-fake89999", SYMLINK+="node"
+EOF
+        },
+        {
+                desc            => "multiple symlinks with format char",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "symlink2-ttyACM0",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK="symlink1-%n symlink2-%k symlink3-%b"
+EOF
+        },
+        {
+                desc            => "multiple symlinks with a lot of s p a c e s",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "one",
+                not_exp_name        => " ",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK="  one     two        "
+EOF
+        },
+        {
+                desc            => "symlink creation (same directory)",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "modem0",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK="modem%n"
+EOF
+        },
+        {
+                desc            => "multiple symlinks",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "second-0" ,
+                rules           => <<EOF
+KERNEL=="ttyACM0", SYMLINK="first-%n second-%n third-%n"
+EOF
+        },
+        {
+                desc            => "symlink name '.'",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => ".",
+                exp_add_error        => "yes",
+                exp_rem_error        => "yes",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="."
+EOF
+        },
+        {
+                desc            => "symlink node to itself",
+                devpath         => "/devices/virtual/tty/tty0",
+                exp_name        => "link",
+                exp_add_error        => "yes",
+                exp_rem_error        => "yes",
+                option                => "clean",
+                rules           => <<EOF
+KERNEL=="tty0", SYMLINK+="tty0"
+EOF
+        },
+        {
+                desc            => "symlink %n substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "symlink0",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="symlink%n"
+EOF
+        },
+        {
+                desc            => "symlink %k substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "symlink-ttyACM0",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="symlink-%k"
+EOF
+        },
+        {
+                desc            => "symlink %M:%m substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "major-166:0",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="ttyACM%n", SYMLINK+="major-%M:%m"
+EOF
+        },
+        {
+                desc            => "symlink %b substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "symlink-0:0:0:0",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="symlink-%b"
+EOF
+        },
+        {
+                desc            => "symlink %c substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "test",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo test", SYMLINK+="%c"
+EOF
+        },
+        {
+                desc            => "symlink %c{N} substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "test",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo symlink test this", SYMLINK+="%c{2}"
+EOF
+        },
+        {
+                desc            => "symlink %c{N+} substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "this",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", PROGRAM=="/bin/echo symlink test this", SYMLINK+="%c{2+}"
+EOF
+        },
+        {
+                desc            => "symlink only rule with %c{N+}",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "test",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", PROGRAM=="/bin/echo link test this" SYMLINK+="%c{2+}"
+EOF
+        },
+        {
+                desc            => "symlink %s{filename} substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "166:0",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="%s{dev}"
+EOF
+        },
+        {
+                desc            => "program result substitution (numbered part of)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "link1",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n node link1 link2", RESULT=="node *", SYMLINK+="%c{2} %c{3}"
+EOF
+        },
+        {
+                desc            => "program result substitution (numbered part of+)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
+                exp_name        => "link4",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n node link1 link2 link3 link4", RESULT=="node *", SYMLINK+="%c{2+}"
+EOF
+        },
+        {
+                desc            => "SUBSYSTEM match test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match", SUBSYSTEM=="vc"
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", SUBSYSTEM=="block"
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match2", SUBSYSTEM=="vc"
+EOF
+        },
+        {
+                desc            => "DRIVERS match test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="should_not_match", DRIVERS=="sd-wrong"
+SUBSYSTEMS=="scsi", KERNEL=="sda", SYMLINK+="node", DRIVERS=="sd"
+EOF
+        },
+        {
+                desc            => "devnode substitution test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda", PROGRAM=="/usr/bin/test -b %N" SYMLINK+="node"
+EOF
+        },
+        {
+                desc            => "parent node name substitution test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "sda-part-1",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="%P-part-1"
+EOF
+        },
+        {
+                desc            => "udev_root substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "start-/dev-end",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="start-%r-end"
+EOF
+        },
+        {
+                desc            => "last_rule option",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "last",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="last", OPTIONS="last_rule"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="very-last"
+EOF
+        },
+        {
+                desc            => "negation KERNEL!=",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "match",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL!="sda1", SYMLINK+="matches-but-is-negated"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
+SUBSYSTEMS=="scsi", KERNEL!="xsda1", SYMLINK+="match"
+EOF
+        },
+        {
+                desc            => "negation SUBSYSTEM!=",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "not-anything",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", SUBSYSTEM=="block", KERNEL!="sda1", SYMLINK+="matches-but-is-negated"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
+SUBSYSTEMS=="scsi", SUBSYSTEM!="anything", SYMLINK+="not-anything"
+EOF
+        },
+        {
+                desc            => "negation PROGRAM!= exit code",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "nonzero-program",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
+KERNEL=="sda1", PROGRAM!="/bin/false", SYMLINK+="nonzero-program"
+EOF
+        },
+        {
+                desc            => "ENV{} test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "true",
+                rules           => <<EOF
+ENV{ENV_KEY_TEST}="test"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="go", SYMLINK+="wrong"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="test", SYMLINK+="true"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="bad", SYMLINK+="bad"
+EOF
+        },
+        {
+                desc            => "ENV{} test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "true",
+                rules           => <<EOF
+ENV{ENV_KEY_TEST}="test"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="go", SYMLINK+="wrong"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="*/block/sda/sdax1", SYMLINK+="no"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="test", ENV{ACTION}=="add", ENV{DEVPATH}=="*/block/sda/sda1", SYMLINK+="true"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="bad", SYMLINK+="bad"
+EOF
+        },
+        {
+                desc            => "ENV{} test (assign)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "true",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="true"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="yes", SYMLINK+="no"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="true", SYMLINK+="true"
+EOF
+        },
+        {
+                desc            => "ENV{} test (assign 2 times)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "true",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="true"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}="absolutely-\$env{ASSIGN}"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="before"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="yes", SYMLINK+="no"
+SUBSYSTEMS=="scsi", KERNEL=="sda1", ENV{ASSIGN}=="absolutely-true", SYMLINK+="true"
+EOF
+        },
+        {
+                desc            => "ENV{} test (assign2)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "part",
+                rules           => <<EOF
+SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{PARTITION}="true", ENV{MAINDEVICE}="false"
+SUBSYSTEM=="block", KERNEL=="*[!0-9]", ENV{PARTITION}="false", ENV{MAINDEVICE}="true"
+ENV{MAINDEVICE}=="true", SYMLINK+="disk"
+SUBSYSTEM=="block", SYMLINK+="before"
+ENV{PARTITION}=="true", SYMLINK+="part"
+EOF
+        },
+        {
+                desc            => "untrusted string sanitize",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "sane",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e name; (/usr/bin/badprogram)", RESULT=="name_ _/usr/bin/badprogram_", SYMLINK+="sane"
+EOF
+        },
+        {
+                desc            => "untrusted string sanitize (don't replace utf8)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "uber",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e \\xc3\\xbcber" RESULT=="\xc3\xbcber", SYMLINK+="uber"
+EOF
+        },
+        {
+                desc            => "untrusted string sanitize (replace invalid utf8)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "replaced",
+                rules           => <<EOF
+SUBSYSTEMS=="scsi", KERNEL=="sda1", PROGRAM=="/bin/echo -e \\xef\\xe8garbage", RESULT=="__garbage", SYMLINK+="replaced"
+EOF
+        },
+        {
+                desc            => "read sysfs value from parent device",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "serial-354172020305000",
+                rules           => <<EOF
+KERNEL=="ttyACM*", ATTRS{serial}=="?*", SYMLINK+="serial-%s{serial}"
+EOF
+        },
+        {
+                desc            => "match against empty key string",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "ok",
+                rules           => <<EOF
+KERNEL=="sda", ATTRS{nothing}!="", SYMLINK+="not-1-ok"
+KERNEL=="sda", ATTRS{nothing}=="", SYMLINK+="not-2-ok"
+KERNEL=="sda", ATTRS{vendor}!="", SYMLINK+="ok"
+KERNEL=="sda", ATTRS{vendor}=="", SYMLINK+="not-3-ok"
+EOF
+        },
+        {
+                desc            => "check ACTION value",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "ok",
+                rules           => <<EOF
+ACTION=="unknown", KERNEL=="sda", SYMLINK+="unknown-not-ok"
+ACTION=="add", KERNEL=="sda", SYMLINK+="ok"
+EOF
+        },
+        {
+                desc            => "final assignment",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "ok",
+                exp_perms       => "root:tty:0640",
+                rules           => <<EOF
+KERNEL=="sda", GROUP:="tty"
+KERNEL=="sda", GROUP="not-ok", MODE="0640", SYMLINK+="ok"
+EOF
+        },
+        {
+                desc            => "final assignment 2",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "ok",
+                exp_perms       => "root:tty:0640",
+                rules           => <<EOF
+KERNEL=="sda", GROUP:="tty"
+SUBSYSTEM=="block", MODE:="640"
+KERNEL=="sda", GROUP="not-ok", MODE="0666", SYMLINK+="ok"
+EOF
+        },
+        {
+                desc            => "env substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "node-add-me",
+                rules           => <<EOF
+KERNEL=="sda", MODE="0666", SYMLINK+="node-\$env{ACTION}-me"
+EOF
+        },
+        {
+                desc            => "reset list to current value",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "three",
+                not_exp_name    => "two",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="one"
+KERNEL=="ttyACM[0-9]*", SYMLINK+="two"
+KERNEL=="ttyACM[0-9]*", SYMLINK="three"
+EOF
+        },
+        {
+                desc            => "test empty SYMLINK+ (empty override)",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "right",
+                not_exp_name    => "wrong",
+                rules           => <<EOF
+KERNEL=="ttyACM[0-9]*", SYMLINK+="wrong"
+KERNEL=="ttyACM[0-9]*", SYMLINK=""
+KERNEL=="ttyACM[0-9]*", SYMLINK+="right"
+EOF
+        },
+        {
+                desc            => "test multi matches",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "right",
+                rules           => <<EOF
+KERNEL=="ttyACM*", SYMLINK+="before"
+KERNEL=="ttyACM*|nothing", SYMLINK+="right"
+EOF
+        },
+        {
+                desc            => "test multi matches 2",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "right",
+                rules           => <<EOF
+KERNEL=="dontknow*|*nothing", SYMLINK+="nomatch"
+KERNEL=="ttyACM*", SYMLINK+="before"
+KERNEL=="dontknow*|ttyACM*|nothing*", SYMLINK+="right"
+EOF
+        },
+        {
+                desc            => "test multi matches 3",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "right",
+                rules           => <<EOF
+KERNEL=="dontknow|nothing", SYMLINK+="nomatch"
+KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1"
+KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2"
+KERNEL=="dontknow|ttyACM0|nothing", SYMLINK+="right"
+EOF
+        },
+        {
+                desc            => "test multi matches 4",
+                devpath         => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+                exp_name        => "right",
+                rules           => <<EOF
+KERNEL=="dontknow|nothing", SYMLINK+="nomatch"
+KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1"
+KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2"
+KERNEL=="all|dontknow|ttyACM0", SYMLINK+="right"
+KERNEL=="ttyACM0a|nothing", SYMLINK+="wrong3"
+EOF
+        },
+        {
+                desc            => "IMPORT parent test sequence 1/2 (keep)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "parent",
+                option          => "keep",
+                rules           => <<EOF
+KERNEL=="sda", IMPORT{program}="/bin/echo -e \'PARENT_KEY=parent_right\\nWRONG_PARENT_KEY=parent_wrong'"
+KERNEL=="sda", SYMLINK+="parent"
+EOF
+        },
+        {
+                desc            => "IMPORT parent test sequence 2/2 (keep)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "parentenv-parent_right",
+                option          => "clean",
+                rules           => <<EOF
+KERNEL=="sda1", IMPORT{parent}="PARENT*", SYMLINK+="parentenv-\$env{PARENT_KEY}\$env{WRONG_PARENT_KEY}"
+EOF
+        },
+        {
+                desc            => "GOTO test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "right",
+                rules           => <<EOF
+KERNEL=="sda1", GOTO="TEST"
+KERNEL=="sda1", SYMLINK+="wrong"
+KERNEL=="sda1", GOTO="BAD"
+KERNEL=="sda1", SYMLINK+="", LABEL="NO"
+KERNEL=="sda1", SYMLINK+="right", LABEL="TEST", GOTO="end"
+KERNEL=="sda1", SYMLINK+="wrong2", LABEL="BAD"
+LABEL="end"
+EOF
+        },
+        {
+                desc            => "GOTO label does not exist",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "right",
+                rules           => <<EOF
+KERNEL=="sda1", GOTO="does-not-exist"
+KERNEL=="sda1", SYMLINK+="right",
+LABEL="exists"
+EOF
+        },
+        {
+                desc            => "SYMLINK+ compare test",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "right",
+                not_exp_name    => "wrong",
+                rules           => <<EOF
+KERNEL=="sda1", SYMLINK+="link"
+KERNEL=="sda1", SYMLINK=="link*", SYMLINK+="right"
+KERNEL=="sda1", SYMLINK=="nolink*", SYMLINK+="wrong"
+EOF
+        },
+        {
+                desc            => "invalid key operation",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "yes",
+                rules           => <<EOF
+KERNEL="sda1", SYMLINK+="no"
+KERNEL=="sda1", SYMLINK+="yes"
+EOF
+        },
+        {
+                desc            => "operator chars in attribute",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "yes",
+                rules           => <<EOF
+KERNEL=="sda", ATTR{test:colon+plus}=="?*", SYMLINK+="yes"
+EOF
+        },
+        {
+                desc            => "overlong comment line",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1",
+                exp_name        => "yes",
+                rules           => <<EOF
+# 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+   # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+KERNEL=="sda1", SYMLINK+=="no"
+KERNEL=="sda1", SYMLINK+="yes"
+EOF
+        },
+        {
+                desc            => "magic subsys/kernel lookup",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "00:16:41:e2:8d:ff",
+                rules           => <<EOF
+KERNEL=="sda", SYMLINK+="\$attr{[net/eth0]address}"
+EOF
+        },
+        {
+                desc            => "TEST absolute path",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "there",
+                rules           => <<EOF
+TEST=="/etc/hosts", SYMLINK+="there"
+TEST!="/etc/hosts", SYMLINK+="notthere"
+EOF
+        },
+        {
+                desc            => "TEST subsys/kernel lookup",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "yes",
+                rules           => <<EOF
+KERNEL=="sda", TEST=="[net/eth0]", SYMLINK+="yes"
+EOF
+        },
+        {
+                desc            => "TEST relative path",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "relative",
+                rules           => <<EOF
+KERNEL=="sda", TEST=="size", SYMLINK+="relative"
+EOF
+        },
+        {
+                desc            => "TEST wildcard substitution (find queue/nr_requests)",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "found-subdir",
+                rules           => <<EOF
+KERNEL=="sda", TEST=="*/nr_requests", SYMLINK+="found-subdir"
+EOF
+        },
+        {
+                desc            => "TEST MODE=0000",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "sda",
+                exp_perms       => "0:0:0000",
+                exp_rem_error   => "yes",
+                rules           => <<EOF
+KERNEL=="sda", MODE="0000"
+EOF
+        },
+        {
+                desc            => "TEST PROGRAM feeds OWNER, GROUP, MODE",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "sda",
+                exp_perms       => "5000:100:0400",
+                exp_rem_error   => "yes",
+                rules           => <<EOF
+KERNEL=="sda", MODE="666"
+KERNEL=="sda", PROGRAM=="/bin/echo 5000 100 0400", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}"
+EOF
+        },
+        {
+                desc            => "TEST PROGRAM feeds MODE with overflow",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "sda",
+                exp_perms       => "0:0:0440",
+                exp_rem_error   => "yes",
+                rules           => <<EOF
+KERNEL=="sda", MODE="440"
+KERNEL=="sda", PROGRAM=="/bin/echo 0 0 0400letsdoabuffferoverflow0123456789012345789012345678901234567890", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}"
+EOF
+        },
+        {
+                desc            => "magic [subsys/sysname] attribute substitution",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "sda-8741C4G-end",
+                exp_perms       => "0:0:0600",
+                rules           => <<EOF
+KERNEL=="sda", PROGRAM="/bin/true create-envp"
+KERNEL=="sda", ENV{TESTENV}="change-envp"
+KERNEL=="sda", SYMLINK+="%k-%s{[dmi/id]product_name}-end"
+EOF
+        },
+        {
+                desc            => "builtin path_id",
+                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
+                exp_name        => "disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0",
+                rules           => <<EOF
+KERNEL=="sda", IMPORT{builtin}="path_id"
+KERNEL=="sda", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/\$env{ID_PATH}"
+EOF
+        },
+);
+
+sub udev {
+        my ($action, $devpath, $rules) = @_;
+
+        # create temporary rules
+        system("mkdir", "-p", "$udev_rules_dir");
+        open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules";
+        print CONF $$rules;
+        close CONF;
+
+        if ($valgrind > 0) {
+                system("$udev_bin_valgrind $action $devpath");
+        } else {
+                system("$udev_bin", "$action", "$devpath");
+        }
+}
+
+my $error = 0;
+
+sub permissions_test {
+        my($rules, $uid, $gid, $mode) = @_;
+
+        my $wrong = 0;
+        my $userid;
+        my $groupid;
+
+        $rules->{exp_perms} =~ m/^(.*):(.*):(.*)$/;
+        if ($1 ne "") {
+                if (defined(getpwnam($1))) {
+                        $userid = int(getpwnam($1));
+                } else {
+                        $userid = $1;
+                }
+                if ($uid != $userid) { $wrong = 1; }
+        }
+        if ($2 ne "") {
+                if (defined(getgrnam($2))) {
+                        $groupid = int(getgrnam($2));
+                } else {
+                        $groupid = $2;
+                }
+                if ($gid != $groupid) { $wrong = 1; }
+        }
+        if ($3 ne "") {
+                if (($mode & 07777) != oct($3)) { $wrong = 1; };
+        }
+        if ($wrong == 0) {
+                print "permissions: ok\n";
+        } else {
+                printf "  expected permissions are: %s:%s:%#o\n", $1, $2, oct($3);
+                printf "  created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777;
+                print "permissions: error\n";
+                $error++;
+                sleep(1);
+        }
+}
+
+sub major_minor_test {
+        my($rules, $rdev) = @_;
+
+        my $major = ($rdev >> 8) & 0xfff;
+        my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00);
+        my $wrong = 0;
+
+        $rules->{exp_majorminor} =~ m/^(.*):(.*)$/;
+        if ($1 ne "") {
+                if ($major != $1) { $wrong = 1; };
+        }
+        if ($2 ne "") {
+                if ($minor != $2) { $wrong = 1; };
+        }
+        if ($wrong == 0) {
+                print "major:minor: ok\n";
+        } else {
+                printf "  expected major:minor is: %i:%i\n", $1, $2;
+                printf "  created major:minor is : %i:%i\n", $major, $minor;
+                print "major:minor: error\n";
+                $error++;
+                sleep(1);
+        }
+}
+
+sub udev_setup {
+        system("rm", "-rf", "$udev_dev");
+        mkdir($udev_dev) || die "unable to create udev_dev: $udev_dev\n";
+        # setting group and mode of udev_dev ensures the tests work
+        # even if the parent directory has setgid bit enabled.
+        chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n";
+        chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n";
+
+        system("rm", "-rf", "$udev_run");
+}
+
+sub run_test {
+        my ($rules, $number) = @_;
+
+        print "TEST $number: $rules->{desc}\n";
+        print "device \'$rules->{devpath}\' expecting node/link \'$rules->{exp_name}\'\n";
+
+        udev("add", $rules->{devpath}, \$rules->{rules});
+        if (defined($rules->{not_exp_name})) {
+                if ((-e "$udev_dev/$rules->{not_exp_name}") ||
+                    (-l "$udev_dev/$rules->{not_exp_name}")) {
+                        print "nonexistent: error \'$rules->{not_exp_name}\' not expected to be there\n";
+                        $error++;
+                        sleep(1);
+                }
+        }
+
+        if ((-e "$udev_dev/$rules->{exp_name}") ||
+            (-l "$udev_dev/$rules->{exp_name}")) {
+
+                my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
+                    $atime, $mtime, $ctime, $blksize, $blocks) = stat("$udev_dev/$rules->{exp_name}");
+
+                if (defined($rules->{exp_perms})) {
+                        permissions_test($rules, $uid, $gid, $mode);
+                }
+                if (defined($rules->{exp_majorminor})) {
+                        major_minor_test($rules, $rdev);
+                }
+                print "add:         ok\n";
+        } else {
+                print "add:         error";
+                if ($rules->{exp_add_error}) {
+                        print " as expected\n";
+                } else {
+                        print "\n";
+                        system("tree", "$udev_dev");
+                        print "\n";
+                        $error++;
+                        sleep(1);
+                }
+        }
+
+        if (defined($rules->{option}) && $rules->{option} eq "keep") {
+                print "\n\n";
+                return;
+        }
+
+        udev("remove", $rules->{devpath}, \$rules->{rules});
+        if ((-e "$udev_dev/$rules->{exp_name}") ||
+            (-l "$udev_dev/$rules->{exp_name}")) {
+                print "remove:      error";
+                if ($rules->{exp_rem_error}) {
+                        print " as expected\n";
+                } else {
+                        print "\n";
+                        system("tree", "$udev_dev");
+                        print "\n";
+                        $error++;
+                        sleep(1);
+                }
+        } else {
+                print "remove:      ok\n";
+        }
+
+        print "\n";
+
+        if (defined($rules->{option}) && $rules->{option} eq "clean") {
+                udev_setup();
+        }
+
+}
+
+# only run if we have root permissions
+# due to mknod restrictions
+if (!($<==0)) {
+        print "Must have root permissions to run properly.\n";
+        exit;
+}
+
+udev_setup();
+
+my $test_num = 1;
+my @list;
+
+foreach my $arg (@ARGV) {
+        if ($arg =~ m/--valgrind/) {
+                $valgrind = 1;
+                printf("using valgrind\n");
+        } else {
+                push(@list, $arg);
+        }
+}
+
+if ($list[0]) {
+        foreach my $arg (@list) {
+                if (defined($tests[$arg-1]->{desc})) {
+                        print "udev-test will run test number $arg:\n\n";
+                        run_test($tests[$arg-1], $arg);
+                } else {
+                        print "test does not exist.\n";
+                }
+        }
+} else {
+        # test all
+        print "\nudev-test will run ".($#tests + 1)." tests:\n\n";
+
+        foreach my $rules (@tests) {
+                run_test($rules, $test_num);
+                $test_num++;
+        }
+}
+
+print "$error errors occured\n\n";
+
+# cleanup
+system("rm", "-rf", "$udev_dev");
+system("rm", "-rf", "$udev_run");
+
+if ($error > 0) {
+    exit(1);
+}
+exit(0);
diff --git a/tmpfiles.d/Makefile b/tmpfiles.d/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/tmpfiles.d/legacy.conf b/tmpfiles.d/legacy.conf
new file mode 100644 (file)
index 0000000..92bd71b
--- /dev/null
@@ -0,0 +1,22 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+# These files are considered legacy and are unnecessary on legacy-free
+# systems. /run/lock/subsys is used for serializing SysV service
+# execution, and hence without use on SysV-less systems.
+#
+# /run/lock/lockdev is used to serialize access to tty devices via
+# LCK..xxx style lock files, For more information see:
+# http://lists.freedesktop.org/archives/systemd-devel/2011-March/001823.html
+# On modern systems a BSD file lock is a better choice if
+# serialization is needed on those devices.
+
+d /run/lock 0755 root root -
+d /run/lock/subsys 0755 root root -
+d /run/lock/lockdev 0775 root lock -
diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf
new file mode 100644 (file)
index 0000000..965c6fc
--- /dev/null
@@ -0,0 +1,28 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+d /run/user 0755 root root ~10d
+F /run/utmp 0664 root utmp -
+
+f /var/log/wtmp 0664 root utmp -
+f /var/log/btmp 0600 root utmp -
+
+d /var/cache/man - - - 30d
+
+r /forcefsck
+r /forcequotacheck
+r /fastboot
+
+d /run/systemd/ask-password 0755 root root -
+d /run/systemd/seats 0755 root root -
+d /run/systemd/sessions 0755 root root -
+d /run/systemd/users 0755 root root -
+d /run/systemd/shutdown 0755 root root -
+
+F /run/nologin 0755 - - - "System is booting up."
diff --git a/tmpfiles.d/tmp.conf b/tmpfiles.d/tmp.conf
new file mode 100644 (file)
index 0000000..1284fc4
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+# Clear tmp directories separately, to make them easier to override
+d /tmp 1777 root root 10d
+d /var/tmp 1777 root root 30d
diff --git a/tmpfiles.d/x11.conf b/tmpfiles.d/x11.conf
new file mode 100644 (file)
index 0000000..ece6a5c
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+# Make sure these are created by default so that nobody else can
+d /tmp/.X11-unix 1777 root root 10d
+d /tmp/.ICE-unix 1777 root root 10d
+d /tmp/.XIM-unix 1777 root root 10d
+d /tmp/.font-unix 1777 root root 10d
+d /tmp/.Test-unix 1777 root root 10d
+
+# Unlink the X11 lock files
+r /tmp/.X[0-9]*-lock
diff --git a/units/.gitignore b/units/.gitignore
new file mode 100644 (file)
index 0000000..5e86d30
--- /dev/null
@@ -0,0 +1,51 @@
+/halt-local.service
+/rc-local.service
+/systemd-hybrid-sleep.service
+/systemd-journal-gatewayd.service
+/systemd-journal-flush.service
+/systemd-hibernate.service
+/systemd-suspend.service
+/console-getty.service
+/systemd-journald.service
+/user@.service
+/systemd-logind.service
+/systemd-localed.service
+/systemd-timedated.service
+/systemd-hostnamed.service
+/console-shell.service
+/systemd-sysctl.service
+/systemd-ask-password-console.service
+/rescue.service
+/systemd-ask-password-wall.service
+/systemd-quotacheck.service
+/quotaon.service
+/systemd-fsck@.service
+/systemd-fsck-root.service
+/systemd-tmpfiles-clean.service
+/systemd-tmpfiles-setup.service
+/systemd-halt.service
+/systemd-poweroff.service
+/systemd-reboot.service
+/systemd-kexec.service
+/systemd-user-sessions.service
+/systemd-readahead-done.service
+/systemd-tmpfiles.service
+/systemd-readahead-collect.service
+/systemd-readahead-replay.service
+/serial-getty@.service
+/systemd-modules-load.service
+/systemd-remount-fs.service
+/systemd-vconsole-setup.service
+/systemd-shutdownd.service
+/systemd-random-seed-load.service
+/systemd-random-seed-save.service
+/systemd-initctl.service
+/getty@.service
+/systemd-update-utmp-runlevel.service
+/systemd-update-utmp-shutdown.service
+/systemd-binfmt.service
+/emergency.service
+/systemd-udev-settle.service
+/systemd-udev-trigger.service
+/systemd-udevd.service
+/debug-shell.service
diff --git a/units/Makefile b/units/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/units/basic.target b/units/basic.target
new file mode 100644 (file)
index 0000000..f9d03fa
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Basic System
+Documentation=man:systemd.special(7)
+Requires=sysinit.target sockets.target
+After=sysinit.target sockets.target
+RefuseManualStart=yes
diff --git a/units/bluetooth.target b/units/bluetooth.target
new file mode 100644 (file)
index 0000000..dd4ae14
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Bluetooth
+Documentation=man:systemd.special(7)
+StopWhenUnneeded=yes
diff --git a/units/console-getty.service.m4.in b/units/console-getty.service.m4.in
new file mode 100644 (file)
index 0000000..0426050
--- /dev/null
@@ -0,0 +1,34 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Console Getty
+Documentation=man:agetty(8)
+After=systemd-user-sessions.service plymouth-quit-wait.service
+m4_ifdef(`HAVE_SYSV_COMPAT',
+After=rc-local.service
+)m4_dnl
+Before=getty.target
+
+[Service]
+ExecStart=-/sbin/agetty --noclear -s console 115200,38400,9600
+Type=idle
+Restart=always
+RestartSec=0
+UtmpIdentifier=cons
+TTYPath=/dev/console
+TTYReset=yes
+TTYVHangup=yes
+KillMode=process
+IgnoreSIGPIPE=no
+
+# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
+# terminates cleanly.
+KillSignal=SIGHUP
+
+[Install]
+WantedBy=getty.target
diff --git a/units/console-shell.service.m4.in b/units/console-shell.service.m4.in
new file mode 100644 (file)
index 0000000..dac2ac2
--- /dev/null
@@ -0,0 +1,34 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Console Shell
+Documentation=man:sulogin(8)
+After=systemd-user-sessions.service plymouth-quit-wait.service
+m4_ifdef(`HAVE_SYSV_COMPAT',
+After=rc-local.service
+)m4_dnl
+Before=getty.target
+
+[Service]
+Environment=HOME=/root
+WorkingDirectory=/root
+ExecStart=-/sbin/sulogin
+ExecStopPost=-@SYSTEMCTL@ poweroff
+Type=idle
+StandardInput=tty-force
+StandardOutput=inherit
+StandardError=inherit
+KillMode=process
+IgnoreSIGPIPE=no
+
+# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
+# terminates cleanly.
+KillSignal=SIGHUP
+
+[Install]
+WantedBy=getty.target
diff --git a/units/cryptsetup.target b/units/cryptsetup.target
new file mode 100644 (file)
index 0000000..25d3e33
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Encrypted Volumes
+Documentation=man:systemd.special(7)
diff --git a/units/debug-shell.service.in b/units/debug-shell.service.in
new file mode 100644 (file)
index 0000000..2aa98d3
--- /dev/null
@@ -0,0 +1,33 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Early root shell on tty9 FOR DEBUGGING ONLY
+Documentation=man:sushell(8)
+DefaultDependencies=no
+IgnoreOnIsolate=yes
+
+[Service]
+Environment=TERM=linux
+ExecStart=@sushell@
+Restart=always
+RestartSec=0
+StandardInput=tty
+TTYPath=/dev/tty9
+TTYReset=yes
+TTYVHangup=yes
+KillMode=process
+IgnoreSIGPIPE=no
+# bash ignores SIGTERM
+KillSignal=SIGHUP
+
+# Unset locale for the console getty since the console has problems
+# displaying some internationalized messages.
+Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=
+
+[Install]
+WantedBy=sysinit.target
diff --git a/units/dev-hugepages.mount b/units/dev-hugepages.mount
new file mode 100644 (file)
index 0000000..9381167
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Huge Pages File System
+Documentation=https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
+DefaultDependencies=no
+Before=sysinit.target
+ConditionPathExists=/sys/kernel/mm/hugepages
+
+[Mount]
+What=hugetlbfs
+Where=/dev/hugepages
+Type=hugetlbfs
diff --git a/units/dev-mqueue.mount b/units/dev-mqueue.mount
new file mode 100644 (file)
index 0000000..5786bb1
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=POSIX Message Queue File System
+Documentation=man:mq_overview(7)
+DefaultDependencies=no
+Before=sysinit.target
+ConditionPathExists=/proc/sys/fs/mqueue
+
+[Mount]
+What=mqueue
+Where=/dev/mqueue
+Type=mqueue
diff --git a/units/emergency.service.in b/units/emergency.service.in
new file mode 100644 (file)
index 0000000..442f0e0
--- /dev/null
@@ -0,0 +1,31 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Emergency Shell
+Documentation=man:sulogin(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Environment=HOME=/root
+WorkingDirectory=/root
+ExecStartPre=-/bin/plymouth quit
+ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" to try again\\nto boot into default mode.'
+ExecStart=-/sbin/sulogin
+ExecStopPost=@SYSTEMCTL@ --fail --no-block default
+Type=idle
+StandardInput=tty-force
+StandardOutput=inherit
+StandardError=inherit
+KillMode=process
+IgnoreSIGPIPE=no
+
+# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
+# terminates cleanly.
+KillSignal=SIGHUP
diff --git a/units/emergency.target b/units/emergency.target
new file mode 100644 (file)
index 0000000..0760d66
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Emergency Mode
+Documentation=man:systemd.special(7)
+Requires=emergency.service
+After=emergency.service
+AllowIsolate=yes
diff --git a/units/final.target b/units/final.target
new file mode 100644 (file)
index 0000000..4281910
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Final Step
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+RefuseManualStart=yes
+After=shutdown.target umount.target
diff --git a/units/getty.target b/units/getty.target
new file mode 100644 (file)
index 0000000..c33d446
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Login Prompts
+Documentation=man:systemd.special(7) man:systemd-getty-generator(8)
+Documentation=http://0pointer.de/blog/projects/serial-console.html
diff --git a/units/getty@.service.m4 b/units/getty@.service.m4
new file mode 100644 (file)
index 0000000..083eb97
--- /dev/null
@@ -0,0 +1,51 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Getty on %I
+Documentation=man:agetty(8) man:systemd-getty-generator(8)
+Documentation=http://0pointer.de/blog/projects/serial-console.html
+After=systemd-user-sessions.service plymouth-quit-wait.service
+m4_ifdef(`HAVE_SYSV_COMPAT',
+After=rc-local.service
+)m4_dnl
+
+# If additional gettys are spawned during boot then we should make
+# sure that this is synchronized before getty.target, even though
+# getty.target didn't actually pull it in.
+Before=getty.target
+IgnoreOnIsolate=yes
+
+# On systems without virtual consoles, don't start any getty. (Note
+# that serial gettys are covered by serial-getty@.service, not this
+# unit
+ConditionPathExists=/dev/tty0
+
+[Service]
+# the VT is cleared by TTYVTDisallocate
+ExecStart=-/sbin/agetty --noclear %I 38400 linux
+Type=idle
+Restart=always
+RestartSec=0
+UtmpIdentifier=%I
+TTYPath=/dev/%I
+TTYReset=yes
+TTYVHangup=yes
+TTYVTDisallocate=yes
+KillMode=process
+IgnoreSIGPIPE=no
+
+# Unset locale for the console getty since the console has problems
+# displaying some internationalized messages.
+Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=
+
+# Some login implementations ignore SIGTERM, so we send SIGHUP
+# instead, to ensure that login terminates cleanly.
+KillSignal=SIGHUP
+
+[Install]
+Alias=getty.target.wants/getty@tty1.service
diff --git a/units/graphical.target b/units/graphical.target
new file mode 100644 (file)
index 0000000..65f2521
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Graphical Interface
+Documentation=man:systemd.special(7)
+Requires=multi-user.target
+After=multi-user.target
+Conflicts=rescue.target
+Wants=display-manager.service
+AllowIsolate=yes
+
+[Install]
+Alias=default.target
diff --git a/units/halt-local.service.in b/units/halt-local.service.in
new file mode 100644 (file)
index 0000000..c8be896
--- /dev/null
@@ -0,0 +1,20 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=@RC_LOCAL_SCRIPT_PATH_STOP@ Compatibility
+ConditionFileIsExecutable=@RC_LOCAL_SCRIPT_PATH_STOP@
+DefaultDependencies=no
+After=shutdown.target
+Before=final.target
+
+[Service]
+Type=oneshot
+ExecStart=@RC_LOCAL_SCRIPT_PATH_STOP@
+TimeoutSec=0
+StandardOutput=tty
+RemainAfterExit=yes
diff --git a/units/halt.target b/units/halt.target
new file mode 100644 (file)
index 0000000..a21d984
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Halt
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+Requires=systemd-halt.service
+After=systemd-halt.service
+AllowIsolate=yes
+
+[Install]
+Alias=ctrl-alt-del.target
diff --git a/units/hibernate.target b/units/hibernate.target
new file mode 100644 (file)
index 0000000..143eb59
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Hibernate
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+BindsTo=systemd-hibernate.service
+After=systemd-hibernate.service
diff --git a/units/hybrid-sleep.target b/units/hybrid-sleep.target
new file mode 100644 (file)
index 0000000..d2d3409
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Hybrid Suspend+Hibernate
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+BindsTo=systemd-hybrid-sleep.service
+After=systemd-hybrid-sleep.service
diff --git a/units/kexec.target b/units/kexec.target
new file mode 100644 (file)
index 0000000..90795d0
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Reboot via kexec
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+Requires=systemd-kexec.service
+After=systemd-kexec.service
+AllowIsolate=yes
+
+[Install]
+Alias=ctrl-alt-del.target
diff --git a/units/local-fs-pre.target b/units/local-fs-pre.target
new file mode 100644 (file)
index 0000000..f8760ec
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Local File Systems (Pre)
+Documentation=man:systemd.special(7)
diff --git a/units/local-fs.target b/units/local-fs.target
new file mode 100644 (file)
index 0000000..dd92b17
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Local File Systems
+Documentation=man:systemd.special(7)
+OnFailure=emergency.target
+OnFailureIsolate=yes
diff --git a/units/mail-transfer-agent.target b/units/mail-transfer-agent.target
new file mode 100644 (file)
index 0000000..d2f24d1
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# This exists mostly for compatibility with SysV/LSB units, and
+# implementations lacking socket/bus activation.
+
+[Unit]
+Description=Mail Transfer Agent
+Documentation=man:systemd.special(7)
diff --git a/units/multi-user.target b/units/multi-user.target
new file mode 100644 (file)
index 0000000..6e3f0b4
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Multi-User
+Documentation=man:systemd.special(7)
+Requires=basic.target
+Conflicts=rescue.service rescue.target
+After=basic.target rescue.service rescue.target
+AllowIsolate=yes
+
+[Install]
+Alias=default.target
diff --git a/units/network.target b/units/network.target
new file mode 100644 (file)
index 0000000..5406f4e
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Network
+Documentation=man:systemd.special(7)
diff --git a/units/nss-lookup.target b/units/nss-lookup.target
new file mode 100644 (file)
index 0000000..eea905a
--- /dev/null
@@ -0,0 +1,14 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# This exists mostly for compatibility with SysV/LSB units, and
+# implementations lacking socket/bus activation.
+
+[Unit]
+Description=Host and Network Name Lookups
+Documentation=man:systemd.special(7)
+After=network.target
diff --git a/units/nss-user-lookup.target b/units/nss-user-lookup.target
new file mode 100644 (file)
index 0000000..3e0fced
--- /dev/null
@@ -0,0 +1,14 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# This exists mostly for implementations lacking socket/bus
+# activation.
+
+[Unit]
+Description=User and Group Name Lookups
+Documentation=man:systemd.special(7)
+After=network.target
diff --git a/units/poweroff.target b/units/poweroff.target
new file mode 100644 (file)
index 0000000..7187103
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Power-Off
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+Requires=systemd-poweroff.service
+After=systemd-poweroff.service
+AllowIsolate=yes
+
+[Install]
+Alias=ctrl-alt-del.target
diff --git a/units/printer.target b/units/printer.target
new file mode 100644 (file)
index 0000000..a6b86ca
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Printer
+Documentation=man:systemd.special(7)
+StopWhenUnneeded=yes
diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount
new file mode 100644 (file)
index 0000000..7fd5afe
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Arbitrary Executable File Formats File System Automount Point
+Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
+DefaultDependencies=no
+Before=sysinit.target
+ConditionPathExists=/proc/sys/fs/binfmt_misc/
+ConditionPathIsReadWrite=/proc/sys/
+
+[Automount]
+Where=/proc/sys/fs/binfmt_misc
diff --git a/units/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount
new file mode 100644 (file)
index 0000000..c64c849
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Arbitrary Executable File Formats File System
+Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
+DefaultDependencies=no
+
+[Mount]
+What=binfmt_misc
+Where=/proc/sys/fs/binfmt_misc
+Type=binfmt_misc
diff --git a/units/quotaon.service.in b/units/quotaon.service.in
new file mode 100644 (file)
index 0000000..49a50a7
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Enable File System Quotas
+Documentation=man:quotaon(8)
+DefaultDependencies=no
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-quotacheck.service
+Before=local-fs.target shutdown.target
+ConditionPathExists=@QUOTAON@
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@QUOTAON@ -aug
diff --git a/units/rc-local.service.in b/units/rc-local.service.in
new file mode 100644 (file)
index 0000000..97d44a7
--- /dev/null
@@ -0,0 +1,20 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# This unit gets pulled automatically into multi-user.target by
+# systemd-rc-local-generator if @RC_LOCAL_SCRIPT_PATH_START@ is executable.
+[Unit]
+Description=@RC_LOCAL_SCRIPT_PATH_START@ Compatibility
+ConditionFileIsExecutable=@RC_LOCAL_SCRIPT_PATH_START@
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=@RC_LOCAL_SCRIPT_PATH_START@ start
+TimeoutSec=0
+RemainAfterExit=yes
+SysVStartPriority=99
diff --git a/units/reboot.target b/units/reboot.target
new file mode 100644 (file)
index 0000000..dec8f56
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Reboot
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+Requires=systemd-reboot.service
+After=systemd-reboot.service
+AllowIsolate=yes
+
+[Install]
+Alias=ctrl-alt-del.target
diff --git a/units/remote-fs-pre.target b/units/remote-fs-pre.target
new file mode 100644 (file)
index 0000000..2169533
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Remote File Systems (Pre)
+Documentation=man:systemd.special(7)
+After=network.target nss-lookup.target
diff --git a/units/remote-fs.target b/units/remote-fs.target
new file mode 100644 (file)
index 0000000..9e68878
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Remote File Systems
+Documentation=man:systemd.special(7)
+
+[Install]
+WantedBy=multi-user.target
diff --git a/units/rescue.service.m4.in b/units/rescue.service.m4.in
new file mode 100644 (file)
index 0000000..269797a
--- /dev/null
@@ -0,0 +1,31 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Rescue Shell
+Documentation=man:sulogin(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=sysinit.target plymouth-start.service
+Before=shutdown.target
+
+[Service]
+Environment=HOME=/root
+WorkingDirectory=/root
+ExecStartPre=-/bin/plymouth quit
+ExecStartPre=-/bin/echo -e 'Welcome to rescue mode! Type "systemctl default" or ^D to enter default mode.\\nType "journalctl -xb" to view system logs. Type "systemctl reboot" to reboot.'
+ExecStart=-/sbin/sulogin
+ExecStopPost=-@SYSTEMCTL@ --fail --no-block default
+Type=idle
+StandardInput=tty-force
+StandardOutput=inherit
+StandardError=inherit
+KillMode=process
+
+# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
+# terminates cleanly.
+KillSignal=SIGHUP
diff --git a/units/rescue.target b/units/rescue.target
new file mode 100644 (file)
index 0000000..3f59b14
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Rescue Mode
+Documentation=man:systemd.special(7)
+Requires=sysinit.target rescue.service
+After=sysinit.target rescue.service
+AllowIsolate=yes
+
+[Install]
+Alias=kbrequest.target
diff --git a/units/rpcbind.target b/units/rpcbind.target
new file mode 100644 (file)
index 0000000..eb06a6d
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# This exists mostly for compatibility with SysV/LSB units, and
+# implementations lacking socket/bus activation.
+
+[Unit]
+Description=RPC Port Mapper
+Documentation=man:systemd.special(7)
diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4
new file mode 100644 (file)
index 0000000..60d7737
--- /dev/null
@@ -0,0 +1,38 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Serial Getty on %I
+Documentation=man:agetty(8) man:systemd-getty-generator(8)
+Documentation=http://0pointer.de/blog/projects/serial-console.html
+BindsTo=dev-%i.device
+After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
+m4_ifdef(`HAVE_SYSV_COMPAT',
+After=rc-local.service
+)m4_dnl
+
+# If additional gettys are spawned during boot then we should make
+# sure that this is synchronized before getty.target, even though
+# getty.target didn't actually pull it in.
+Before=getty.target
+IgnoreOnIsolate=yes
+
+[Service]
+ExecStart=-/sbin/agetty -s %I 115200,38400,9600 vt102
+Type=idle
+Restart=always
+RestartSec=0
+UtmpIdentifier=%I
+TTYPath=/dev/%I
+TTYReset=yes
+TTYVHangup=yes
+KillMode=process
+IgnoreSIGPIPE=no
+
+# Some login implementations ignore SIGTERM, so we send SIGHUP
+# instead, to ensure that login terminates cleanly.
+KillSignal=SIGHUP
diff --git a/units/shutdown.target b/units/shutdown.target
new file mode 100644 (file)
index 0000000..73e302b
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Shutdown
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+RefuseManualStart=yes
diff --git a/units/sigpwr.target b/units/sigpwr.target
new file mode 100644 (file)
index 0000000..a52e7cf
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Power Failure
+Documentation=man:systemd.special(7)
diff --git a/units/sleep.target b/units/sleep.target
new file mode 100644 (file)
index 0000000..10c7c8d
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Sleep
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+RefuseManualStart=yes
+StopWhenUnneeded=yes
diff --git a/units/smartcard.target b/units/smartcard.target
new file mode 100644 (file)
index 0000000..5fefe84
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Smart Card
+Documentation=man:systemd.special(7)
+StopWhenUnneeded=yes
diff --git a/units/sockets.target b/units/sockets.target
new file mode 100644 (file)
index 0000000..26ab065
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Sockets
+Documentation=man:systemd.special(7)
diff --git a/units/sound.target b/units/sound.target
new file mode 100644 (file)
index 0000000..6699ade
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Sound Card
+Documentation=man:systemd.special(7)
+StopWhenUnneeded=yes
diff --git a/units/suspend.target b/units/suspend.target
new file mode 100644 (file)
index 0000000..f50cb22
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Suspend
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+BindsTo=systemd-suspend.service
+After=systemd-suspend.service
diff --git a/units/swap.target b/units/swap.target
new file mode 100644 (file)
index 0000000..23a7d0d
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Swap
+Documentation=man:systemd.special(7)
diff --git a/units/sys-fs-fuse-connections.mount b/units/sys-fs-fuse-connections.mount
new file mode 100644 (file)
index 0000000..9269ea4
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=FUSE Control File System
+Documentation=https://www.kernel.org/doc/Documentation/filesystems/fuse.txt
+DefaultDependencies=no
+ConditionPathExists=/sys/fs/fuse/connections
+After=systemd-modules-load.service
+Before=sysinit.target
+
+[Mount]
+What=fusectl
+Where=/sys/fs/fuse/connections
+Type=fusectl
diff --git a/units/sys-kernel-config.mount b/units/sys-kernel-config.mount
new file mode 100644 (file)
index 0000000..e7cd490
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Configuration File System
+Documentation=https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt
+DefaultDependencies=no
+ConditionPathExists=/sys/kernel/config
+After=systemd-modules-load.service
+Before=sysinit.target
+
+[Mount]
+What=configfs
+Where=/sys/kernel/config
+Type=configfs
diff --git a/units/sys-kernel-debug.mount b/units/sys-kernel-debug.mount
new file mode 100644 (file)
index 0000000..8b1e33e
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Debug File System
+Documentation=https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt
+DefaultDependencies=no
+ConditionPathExists=/sys/kernel/debug
+Before=sysinit.target
+
+[Mount]
+What=debugfs
+Where=/sys/kernel/debug
+Type=debugfs
diff --git a/units/sysinit.target b/units/sysinit.target
new file mode 100644 (file)
index 0000000..8f4fb8f
--- /dev/null
@@ -0,0 +1,14 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=System Initialization
+Documentation=man:systemd.special(7)
+Conflicts=emergency.service emergency.target
+Wants=local-fs.target swap.target
+After=local-fs.target swap.target emergency.service emergency.target
+RefuseManualStart=yes
diff --git a/units/syslog.socket b/units/syslog.socket
new file mode 100644 (file)
index 0000000..c784357
--- /dev/null
@@ -0,0 +1,43 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Syslog Socket
+Documentation=man:systemd.special(7)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog
+DefaultDependencies=no
+Before=sockets.target syslog.target shutdown.target
+
+# Don't allow logging until the very end
+Conflicts=shutdown.target
+
+# Pull in syslog.target to tell people that /dev/log is now accessible
+Wants=syslog.target
+
+[Socket]
+ListenDatagram=/run/systemd/journal/syslog
+SocketMode=0666
+PassCredentials=yes
+PassSecurity=yes
+ReceiveBuffer=8M
+
+# The default syslog implementation should make syslog.service a
+# symlink to itself, so that this socket activates the right actual
+# syslog service.
+#
+# Examples:
+#
+# /etc/systemd/system/syslog.service -> /lib/systemd/system/rsyslog.service
+# /etc/systemd/system/syslog.service -> /lib/systemd/system/syslog-ng.service
+#
+# Best way to achieve that is by adding this to your unit file
+# (i.e. to rsyslog.service or syslog-ng.service):
+#
+# [Install]
+# Alias=syslog.service
+#
+# See http://www.freedesktop.org/wiki/Software/systemd/syslog for details.
diff --git a/units/syslog.target b/units/syslog.target
new file mode 100644 (file)
index 0000000..423fef3
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# This exists mostly for compatibility with SysV/LSB units, and
+# implementations lacking socket/bus activation.
+
+[Unit]
+Description=Syslog
+Documentation=man:systemd.special(7)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog
+
+# Avoid that we conflict with shutdown.target, so that we can stay
+# until the very end and do not cancel shutdown.target if we should
+# happen to be activated very late.
+DefaultDependencies=no
diff --git a/units/system-update.target b/units/system-update.target
new file mode 100644 (file)
index 0000000..d0f847f
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=System Update
+Documentation=http://freedesktop.org/wiki/Software/systemd/SystemUpdates
+Documentation=man:systemd.special(7) man:systemd-system-update-generator(8)
+Requires=sysinit.target
+Conflicts=shutdown.target systemd-readahead-collect.service systemd-readahead-replay.service
+After=sysinit.target
+Before=shutdown.target
+AllowIsolate=yes
diff --git a/units/systemd-ask-password-console.path b/units/systemd-ask-password-console.path
new file mode 100644 (file)
index 0000000..80f6cc4
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Dispatch Password Requests to Console Directory Watch
+Documentation=man:systemd-ask-password-console.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=plymouth-start.service
+Before=basic.target shutdown.target
+ConditionPathExists=!/run/plymouth/pid
+
+[Path]
+DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes
diff --git a/units/systemd-ask-password-console.service.in b/units/systemd-ask-password-console.service.in
new file mode 100644 (file)
index 0000000..4bcb30b
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Dispatch Password Requests to Console
+Documentation=man:systemd-ask-password-console.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=plymouth-start.service
+Before=shutdown.target
+ConditionPathExists=!/run/plymouth/pid
+
+[Service]
+ExecStart=@rootbindir@/systemd-tty-ask-password-agent --watch --console
diff --git a/units/systemd-ask-password-wall.path b/units/systemd-ask-password-wall.path
new file mode 100644 (file)
index 0000000..62dee80
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Forward Password Requests to Wall Directory Watch
+Documentation=man:systemd-ask-password-console.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=basic.target shutdown.target
+
+[Path]
+DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes
diff --git a/units/systemd-ask-password-wall.service.in b/units/systemd-ask-password-wall.service.in
new file mode 100644 (file)
index 0000000..0eaa274
--- /dev/null
@@ -0,0 +1,15 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Forward Password Requests to Wall
+Documentation=man:systemd-ask-password-console.service(8)
+After=systemd-user-sessions.service
+
+[Service]
+ExecStartPre=-@SYSTEMCTL@ stop systemd-ask-password-console.path systemd-ask-password-console.service systemd-ask-password-plymouth.path systemd-ask-password-plymouth.service
+ExecStart=@rootbindir@/systemd-tty-ask-password-agent --wall
diff --git a/units/systemd-binfmt.service.in b/units/systemd-binfmt.service.in
new file mode 100644 (file)
index 0000000..02dfe77
--- /dev/null
@@ -0,0 +1,26 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Set Up Additional Binary Formats
+Documentation=man:systemd-binfmt.service(8) man:binfmt.d(5)
+Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service proc-sys-fs-binfmt_misc.automount
+Before=sysinit.target shutdown.target
+ConditionPathIsReadWrite=/proc/sys/
+ConditionDirectoryNotEmpty=|/lib/binfmt.d
+ConditionDirectoryNotEmpty=|/usr/lib/binfmt.d
+ConditionDirectoryNotEmpty=|/usr/local/lib/binfmt.d
+ConditionDirectoryNotEmpty=|/etc/binfmt.d
+ConditionDirectoryNotEmpty=|/run/binfmt.d
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-binfmt
diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in
new file mode 100644 (file)
index 0000000..ef5123f
--- /dev/null
@@ -0,0 +1,25 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=File System Check on Root Device
+Documentation=man:systemd-fsck@.service(8)
+DefaultDependencies=no
+After=systemd-readahead-collect.service systemd-readahead-replay.service
+Before=local-fs.target shutdown.target
+
+# Dracut informs us with this flag file if the root fsck was already run
+ConditionPathExists=!/run/initramfs/root-fsck
+ConditionPathIsReadWrite=!/
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=@rootlibexecdir@/systemd-fsck
+StandardOutput=journal+console
+FsckPassNo=1
+TimeoutSec=0
diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in
new file mode 100644 (file)
index 0000000..b3c71eb
--- /dev/null
@@ -0,0 +1,21 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=File System Check on %f
+Documentation=man:systemd-fsck@.service(8)
+DefaultDependencies=no
+BindsTo=%i.device
+After=systemd-readahead-collect.service systemd-readahead-replay.service %i.device
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=@rootlibexecdir@/systemd-fsck %f
+StandardOutput=journal+console
+TimeoutSec=0
diff --git a/units/systemd-halt.service.in b/units/systemd-halt.service.in
new file mode 100644 (file)
index 0000000..d55d622
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Halt
+Documentation=man:systemd-halt.service(8)
+DefaultDependencies=no
+Requires=shutdown.target umount.target final.target
+After=shutdown.target umount.target final.target
+
+[Service]
+Type=oneshot
+ExecStart=@SYSTEMCTL@ --force halt
diff --git a/units/systemd-hibernate.service.in b/units/systemd-hibernate.service.in
new file mode 100644 (file)
index 0000000..29d9b69
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Hibernate
+Documentation=man:systemd-suspend.service(8)
+DefaultDependencies=no
+Requires=sleep.target
+After=sleep.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-sleep hibernate
diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
new file mode 100644 (file)
index 0000000..874f6c2
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Hostname Service
+Documentation=man:systemd-hostnamed.service(8) man:hostname(5) man:machine-info(5)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-hostnamed
+BusName=org.freedesktop.hostname1
+CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE
diff --git a/units/systemd-hybrid-sleep.service.in b/units/systemd-hybrid-sleep.service.in
new file mode 100644 (file)
index 0000000..914b686
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Hybrid Suspend+Hibernate
+Documentation=man:systemd-suspend.service(8)
+DefaultDependencies=no
+Requires=sleep.target
+After=sleep.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-sleep hybrid-sleep
diff --git a/units/systemd-initctl.service.in b/units/systemd-initctl.service.in
new file mode 100644 (file)
index 0000000..27e663c
--- /dev/null
@@ -0,0 +1,15 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=/dev/initctl Compatibility Daemon
+Documentation=man:systemd-initctl.service(8)
+DefaultDependencies=no
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-initctl
+NotifyAccess=all
diff --git a/units/systemd-initctl.socket b/units/systemd-initctl.socket
new file mode 100644 (file)
index 0000000..b98d5ca
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=/dev/initctl Compatibility Named Pipe
+Documentation=man:systemd-initctl.service(8)
+DefaultDependencies=no
+Before=sockets.target
+
+[Socket]
+ListenFIFO=/dev/initctl
+SocketMode=0600
diff --git a/units/systemd-journal-flush.service.in b/units/systemd-journal-flush.service.in
new file mode 100644 (file)
index 0000000..503e8a6
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Trigger Flushing of Journal to Persistent Storage
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+DefaultDependencies=no
+Requires=systemd-journald.service
+After=systemd-journald.service local-fs.target remote-fs.target
+Before=systemd-user-sessions.service
+
+[Service]
+ExecStart=@rootbindir@/systemctl kill --kill-who=main --signal=SIGUSR1 systemd-journald.service
+Type=oneshot
diff --git a/units/systemd-journal-gatewayd.service.in b/units/systemd-journal-gatewayd.service.in
new file mode 100644 (file)
index 0000000..c3b5c72
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Journal Gateway Service
+Requires=systemd-journal-gatewayd.socket
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-journal-gatewayd
+
+[Install]
+Also=systemd-journal-gatewayd.socket
diff --git a/units/systemd-journal-gatewayd.socket b/units/systemd-journal-gatewayd.socket
new file mode 100644 (file)
index 0000000..fd11058
--- /dev/null
@@ -0,0 +1,15 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Journal Gateway Service Socket
+
+[Socket]
+ListenStream=19531
+
+[Install]
+WantedBy=sockets.target
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
new file mode 100644 (file)
index 0000000..ab2e50c
--- /dev/null
@@ -0,0 +1,26 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Journal Service
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+DefaultDependencies=no
+Requires=systemd-journald.socket
+After=systemd-journald.socket syslog.socket
+Before=sysinit.target
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-journald
+Restart=always
+RestartSec=0
+NotifyAccess=all
+StandardOutput=null
+CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID
+
+# Increase the default a bit in order to allow many simultaneous
+# services being run since we keep one fd open per service.
+LimitNOFILE=16384
diff --git a/units/systemd-journald.socket b/units/systemd-journald.socket
new file mode 100644 (file)
index 0000000..dbe8882
--- /dev/null
@@ -0,0 +1,26 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Journal Socket
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+DefaultDependencies=no
+Before=sockets.target syslog.target
+
+# Mount and swap units need this. If this socket unit is removed by an
+# isolate request the mount and and swap units would be removed too,
+# hence let's exclude this from isolate requests.
+IgnoreOnIsolate=yes
+
+[Socket]
+ListenStream=/run/systemd/journal/stdout
+ListenDatagram=/run/systemd/journal/socket
+ListenDatagram=/dev/log
+SocketMode=0666
+PassCredentials=yes
+PassSecurity=yes
+ReceiveBuffer=8M
diff --git a/units/systemd-kexec.service.in b/units/systemd-kexec.service.in
new file mode 100644 (file)
index 0000000..61303f9
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Reboot via kexec
+Documentation=man:systemd-halt.service(8)
+DefaultDependencies=no
+Requires=shutdown.target umount.target final.target
+After=shutdown.target umount.target final.target
+
+[Service]
+Type=oneshot
+ExecStart=@SYSTEMCTL@ --force kexec
diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
new file mode 100644 (file)
index 0000000..6818a4c
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Locale Service
+Documentation=man:systemd-localed.service(8) man:locale.conf(5) man:vconsole.conf(5)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-localed
+BusName=org.freedesktop.locale1
+CapabilityBoundingSet=
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
new file mode 100644 (file)
index 0000000..cf3c430
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Login Service
+Documentation=man:systemd-logind.service(8) man:logind.conf(5)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+After=nss-user-lookup.target
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-logind
+Restart=always
+RestartSec=0
+BusName=org.freedesktop.login1
+CapabilityBoundingSet=CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG
+
+# Increase the default a bit in order to allow many simultaneous
+# logins since we keep one fd open per session.
+LimitNOFILE=16384
diff --git a/units/systemd-modules-load.service.in b/units/systemd-modules-load.service.in
new file mode 100644 (file)
index 0000000..32deb52
--- /dev/null
@@ -0,0 +1,27 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Load Kernel Modules
+Documentation=man:systemd-modules-load.service(8) man:modules-load.d(5)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service
+Before=sysinit.target shutdown.target
+ConditionCapability=CAP_SYS_MODULE
+ConditionDirectoryNotEmpty=|/lib/modules-load.d
+ConditionDirectoryNotEmpty=|/usr/lib/modules-load.d
+ConditionDirectoryNotEmpty=|/usr/local/lib/modules-load.d
+ConditionDirectoryNotEmpty=|/etc/modules-load.d
+ConditionDirectoryNotEmpty=|/run/modules-load.d
+ConditionKernelCommandLine=|modules-load
+ConditionKernelCommandLine=|rd.modules-load
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-modules-load
diff --git a/units/systemd-poweroff.service.in b/units/systemd-poweroff.service.in
new file mode 100644 (file)
index 0000000..3630719
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Power-Off
+Documentation=man:systemd-halt.service(8)
+DefaultDependencies=no
+Requires=shutdown.target umount.target final.target
+After=shutdown.target umount.target final.target
+
+[Service]
+Type=oneshot
+ExecStart=@SYSTEMCTL@ --force poweroff
diff --git a/units/systemd-quotacheck.service.in b/units/systemd-quotacheck.service.in
new file mode 100644 (file)
index 0000000..f726ea1
--- /dev/null
@@ -0,0 +1,20 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=File System Quota Check
+Documentation=man:systemd-quotacheck.service(8)
+DefaultDependencies=no
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
+Before=local-fs.target shutdown.target
+ConditionPathExists=@QUOTACHECK@
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-quotacheck
+TimeoutSec=0
diff --git a/units/systemd-random-seed-load.service.in b/units/systemd-random-seed-load.service.in
new file mode 100644 (file)
index 0000000..e9156ef
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Load Random Seed
+Documentation=man:systemd-random-seed-load.service(8) man:random(4)
+DefaultDependencies=no
+RequiresMountsFor=@RANDOM_SEED@
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
+Before=sysinit.target final.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-random-seed load
diff --git a/units/systemd-random-seed-save.service.in b/units/systemd-random-seed-save.service.in
new file mode 100644 (file)
index 0000000..3444d4c
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Save Random Seed
+Documentation=man:systemd-random-seed-load.service(8) man:random(4)
+DefaultDependencies=no
+RequiresMountsFor=@RANDOM_SEED@
+After=systemd-remount-fs.service systemd-random-seed-load.service
+Before=final.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-random-seed save
diff --git a/units/systemd-readahead-collect.service.in b/units/systemd-readahead-collect.service.in
new file mode 100644 (file)
index 0000000..d4b8e67
--- /dev/null
@@ -0,0 +1,28 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Collect Read-Ahead Data
+Documentation=man:systemd-readahead-replay.service(8)
+DefaultDependencies=no
+Wants=systemd-readahead-done.timer
+Conflicts=shutdown.target
+Before=sysinit.target shutdown.target
+ConditionPathExists=!/run/systemd/readahead/cancel
+ConditionPathExists=!/run/systemd/readahead/done
+ConditionVirtualization=no
+
+[Service]
+Type=notify
+ExecStart=@rootlibexecdir@/systemd-readahead collect
+RemainAfterExit=yes
+StandardOutput=null
+OOMScoreAdjust=1000
+
+[Install]
+WantedBy=default.target
+Also=systemd-readahead-drop.service
diff --git a/units/systemd-readahead-done.service.in b/units/systemd-readahead-done.service.in
new file mode 100644 (file)
index 0000000..c3b2ac5
--- /dev/null
@@ -0,0 +1,21 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Stop Read-Ahead Data Collection
+Documentation=man:systemd-readahead-replay.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=default.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+ExecStart=@SYSTEMD_NOTIFY@ --readahead=done
+
+[Install]
+Also=systemd-readahead-collect.service
diff --git a/units/systemd-readahead-done.timer b/units/systemd-readahead-done.timer
new file mode 100644 (file)
index 0000000..2828d19
--- /dev/null
@@ -0,0 +1,20 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Stop Read-Ahead Data Collection 10s After Completed Startup
+Documentation=man:systemd-readahead-replay.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=default.target
+Before=shutdown.target
+
+[Timer]
+OnActiveSec=10s
+
+[Install]
+Also=systemd-readahead-collect.service
diff --git a/units/systemd-readahead-drop.service b/units/systemd-readahead-drop.service
new file mode 100644 (file)
index 0000000..d9d12bc
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Drop Read-Ahead Data
+Documentation=man:systemd-readahead-replay.service(8)
+ConditionPathExists=/.readahead
+
+[Service]
+Type=oneshot
+ExecStart=/bin/rm -f /.readahead
+
+[Install]
+WantedBy=system-update.target
+Also=systemd-readahead-collect.service
diff --git a/units/systemd-readahead-replay.service.in b/units/systemd-readahead-replay.service.in
new file mode 100644 (file)
index 0000000..c64a533
--- /dev/null
@@ -0,0 +1,26 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Replay Read-Ahead Data
+Documentation=man:systemd-readahead-replay.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=sysinit.target shutdown.target
+ConditionPathExists=!/run/systemd/readahead/noreplay
+ConditionPathExists=/.readahead
+ConditionVirtualization=no
+
+[Service]
+Type=notify
+ExecStart=@rootlibexecdir@/systemd-readahead replay
+RemainAfterExit=yes
+StandardOutput=null
+OOMScoreAdjust=1000
+
+[Install]
+WantedBy=default.target
diff --git a/units/systemd-reboot.service.in b/units/systemd-reboot.service.in
new file mode 100644 (file)
index 0000000..d99bd3e
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Reboot
+Documentation=man:systemd-halt.service(8)
+DefaultDependencies=no
+Requires=shutdown.target umount.target final.target
+After=shutdown.target umount.target final.target
+
+[Service]
+Type=oneshot
+ExecStart=@SYSTEMCTL@ --force reboot
diff --git a/units/systemd-remount-fs.service.in b/units/systemd-remount-fs.service.in
new file mode 100644 (file)
index 0000000..cddb0a1
--- /dev/null
@@ -0,0 +1,21 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Remount Root and Kernel File Systems
+Documentation=man:systemd-remount-fs.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-fsck-root.service
+Before=local-fs-pre.target local-fs.target shutdown.target
+Wants=local-fs-pre.target
+ConditionPathExists=/etc/fstab
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-remount-fs
diff --git a/units/systemd-shutdownd.service.in b/units/systemd-shutdownd.service.in
new file mode 100644 (file)
index 0000000..d951742
--- /dev/null
@@ -0,0 +1,15 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Delayed Shutdown Service
+Documentation=man:systemd-shutdownd.service(8)
+DefaultDependencies=no
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-shutdownd
+NotifyAccess=all
diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket
new file mode 100644 (file)
index 0000000..9421ce8
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Delayed Shutdown Socket
+Documentation=man:systemd-shutdownd.service(8)
+DefaultDependencies=no
+Before=sockets.target
+
+[Socket]
+ListenDatagram=/run/systemd/shutdownd
+SocketMode=0600
+PassCredentials=yes
+PassSecurity=yes
diff --git a/units/systemd-suspend.service.in b/units/systemd-suspend.service.in
new file mode 100644 (file)
index 0000000..3a702d2
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Suspend
+Documentation=man:systemd-suspend.service(8)
+DefaultDependencies=no
+Requires=sleep.target
+After=sleep.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-sleep suspend
diff --git a/units/systemd-sysctl.service.in b/units/systemd-sysctl.service.in
new file mode 100644 (file)
index 0000000..45e1ceb
--- /dev/null
@@ -0,0 +1,26 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Apply Kernel Variables
+Documentation=man:systemd-sysctl.service(8) man:sysctl.d(5)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service
+Before=sysinit.target shutdown.target
+ConditionPathIsReadWrite=/proc/sys/
+ConditionPathExists=|/etc/sysctl.conf
+ConditionDirectoryNotEmpty=|/lib/sysctl.d
+ConditionDirectoryNotEmpty=|/usr/lib/sysctl.d
+ConditionDirectoryNotEmpty=|/usr/local/lib/sysctl.d
+ConditionDirectoryNotEmpty=|/etc/sysctl.d
+ConditionDirectoryNotEmpty=|/run/sysctl.d
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-sysctl
diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
new file mode 100644 (file)
index 0000000..dd3eb1b
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Time & Date Service
+Documentation=man:systemd-timedated.service(8) man:localtime(5)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-timedated
+BusName=org.freedesktop.timedate1
+CapabilityBoundingSet=CAP_SYS_TIME
diff --git a/units/systemd-tmpfiles-clean.service.in b/units/systemd-tmpfiles-clean.service.in
new file mode 100644 (file)
index 0000000..a288232
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Cleanup of Temporary Directories
+Documentation=man:tmpfiles.d(5)
+DefaultDependencies=no
+Wants=local-fs.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+Before=sysinit.target shutdown.target
+ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d
+ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d
+ConditionDirectoryNotEmpty=|/etc/tmpfiles.d
+ConditionDirectoryNotEmpty=|/run/tmpfiles.d
+
+[Service]
+Type=oneshot
+ExecStart=@rootbindir@/systemd-tmpfiles --clean
+IOSchedulingClass=idle
diff --git a/units/systemd-tmpfiles-clean.timer b/units/systemd-tmpfiles-clean.timer
new file mode 100644 (file)
index 0000000..fac4ee3
--- /dev/null
@@ -0,0 +1,14 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Daily Cleanup of Temporary Directories
+Documentation=man:tmpfiles.d(5)
+
+[Timer]
+OnBootSec=15min
+OnUnitActiveSec=1d
diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in
new file mode 100644 (file)
index 0000000..dbd6bfb
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Recreate Volatile Files and Directories
+Documentation=man:tmpfiles.d(5)
+DefaultDependencies=no
+Wants=local-fs.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+Before=sysinit.target shutdown.target
+ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d
+ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d
+ConditionDirectoryNotEmpty=|/etc/tmpfiles.d
+ConditionDirectoryNotEmpty=|/run/tmpfiles.d
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootbindir@/systemd-tmpfiles --create --remove
diff --git a/units/systemd-udev-settle.service.in b/units/systemd-udev-settle.service.in
new file mode 100644 (file)
index 0000000..b631949
--- /dev/null
@@ -0,0 +1,30 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# This service is usually not enabled by default. If enabled, it
+# acts as a barrier for basic.target -- so all later services will
+# wait for udev completely finishing its coldplug run.
+#
+# If needed, to work around broken or non-hotplug-aware services,
+# it might be enabled unconditionally, or pulled-in on-demand by
+# the services that assume a fully populated /dev at startup. It
+# should not be used or pulled-in ever on systems without such
+# legacy services running.
+
+[Unit]
+Description=udev Wait for Complete Device Initialization
+Documentation=man:udev(7) man:systemd-udevd.service(8)
+DefaultDependencies=no
+Wants=systemd-udevd.service
+After=systemd-udev-trigger.service
+ConditionCapability=CAP_MKNOD
+
+[Service]
+Type=oneshot
+TimeoutSec=180
+RemainAfterExit=yes
+ExecStart=@bindir@/udevadm settle
diff --git a/units/systemd-udev-trigger.service.in b/units/systemd-udev-trigger.service.in
new file mode 100644 (file)
index 0000000..391f996
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=udev Coldplug all Devices
+Documentation=man:udev(7) man:systemd-udevd.service(8)
+Wants=systemd-udevd.service
+After=systemd-udevd-kernel.socket systemd-udevd-control.socket
+DefaultDependencies=no
+ConditionCapability=CAP_MKNOD
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@bindir@/udevadm trigger --type=subsystems --action=add ; @bindir@/udevadm trigger --type=devices --action=add
diff --git a/units/systemd-udevd-control.socket b/units/systemd-udevd-control.socket
new file mode 100644 (file)
index 0000000..9065ea2
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=udev Control Socket
+Documentation=man:systemd-udevd.service(8) man:udev(7)
+DefaultDependencies=no
+ConditionCapability=CAP_MKNOD
+
+[Socket]
+Service=systemd-udevd.service
+ListenSequentialPacket=/run/udev/control
+SocketMode=0600
+PassCredentials=yes
diff --git a/units/systemd-udevd-kernel.socket b/units/systemd-udevd-kernel.socket
new file mode 100644 (file)
index 0000000..54a005b
--- /dev/null
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=udev Kernel Socket
+Documentation=man:systemd-udevd.service(8) man:udev(7)
+DefaultDependencies=no
+ConditionCapability=CAP_MKNOD
+
+[Socket]
+Service=systemd-udevd.service
+ReceiveBuffer=134217728
+ListenNetlink=kobject-uevent 1
+PassCredentials=yes
diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
new file mode 100644 (file)
index 0000000..2fe7822
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=udev Kernel Device Manager
+Documentation=man:systemd-udevd.service(8) man:udev(7)
+Wants=systemd-udevd-control.socket systemd-udevd-kernel.socket
+After=systemd-udevd-control.socket systemd-udevd-kernel.socket
+Before=basic.target
+DefaultDependencies=no
+ConditionCapability=CAP_MKNOD
+
+[Service]
+Type=notify
+OOMScoreAdjust=-1000
+Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket
+Restart=always
+RestartSec=0
+ExecStart=@rootlibexecdir@/systemd-udevd
diff --git a/units/systemd-update-utmp-runlevel.service.in b/units/systemd-update-utmp-runlevel.service.in
new file mode 100644 (file)
index 0000000..27fae2c
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Update UTMP about System Runlevel Changes
+Documentation=man:systemd-update-utmp-runlevel.service(8) man:utmp(5)
+DefaultDependencies=no
+RequiresMountsFor=/var/log/wtmp
+After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service
+After=runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target
+Before=final.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-update-utmp runlevel
diff --git a/units/systemd-update-utmp-shutdown.service.in b/units/systemd-update-utmp-shutdown.service.in
new file mode 100644 (file)
index 0000000..aa93562
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Update UTMP about System Shutdown
+Documentation=man:systemd-update-utmp-runlevel.service(8) man:utmp(5)
+DefaultDependencies=no
+RequiresMountsFor=/var/log/wtmp
+After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service
+After=systemd-update-utmp-runlevel.service
+Before=final.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-update-utmp shutdown
diff --git a/units/systemd-user-sessions.service.in b/units/systemd-user-sessions.service.in
new file mode 100644 (file)
index 0000000..0869e73
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Permit User Sessions
+Documentation=man:systemd-user-sessions.service(8)
+After=remote-fs.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-user-sessions start
+ExecStop=@rootlibexecdir@/systemd-user-sessions stop
diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
new file mode 100644 (file)
index 0000000..18faa63
--- /dev/null
@@ -0,0 +1,20 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Setup Virtual Console
+Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service
+Before=sysinit.target shutdown.target
+ConditionPathExists=/dev/tty0
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-vconsole-setup
diff --git a/units/time-sync.target b/units/time-sync.target
new file mode 100644 (file)
index 0000000..ec00ecb
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# This exists mostly for compatibility with SysV/LSB units, and
+# implementations lacking socket/bus activation.
+
+[Unit]
+Description=System Time Synchronized
+Documentation=man:systemd.special(7)
diff --git a/units/tmp.mount b/units/tmp.mount
new file mode 100644 (file)
index 0000000..94c41c2
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Temporary Directory
+Documentation=man:hier(7)
+DefaultDependencies=no
+Conflicts=umount.target
+Before=local-fs.target umount.target
+
+[Mount]
+What=tmpfs
+Where=/tmp
+Type=tmpfs
+Options=mode=1777,strictatime
diff --git a/units/umount.target b/units/umount.target
new file mode 100644 (file)
index 0000000..39668d8
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Unmount All Filesystems
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+RefuseManualStart=yes
diff --git a/units/user/.gitignore b/units/user/.gitignore
new file mode 100644 (file)
index 0000000..41a74f5
--- /dev/null
@@ -0,0 +1 @@
+/systemd-exit.service
diff --git a/units/user/Makefile b/units/user/Makefile
new file mode 120000 (symlink)
index 0000000..50be211
--- /dev/null
@@ -0,0 +1 @@
+../../src/Makefile
\ No newline at end of file
diff --git a/units/user/default.target b/units/user/default.target
new file mode 100644 (file)
index 0000000..56cf4dc
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Default
+Documentation=man:systemd.special(7)
diff --git a/units/user/exit.target b/units/user/exit.target
new file mode 100644 (file)
index 0000000..b0ad24c
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Exit the Session
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+Requires=systemd-exit.service
+After=systemd-exit.service
+AllowIsolate=yes
+
+[Install]
+Alias=ctrl-alt-del.target
diff --git a/units/user/systemd-exit.service.in b/units/user/systemd-exit.service.in
new file mode 100644 (file)
index 0000000..987fab8
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Exit the Session
+Documentation=man:systemd.special(7)
+DefaultDependencies=no
+Requires=shutdown.target
+After=shutdown.target
+
+[Service]
+Type=oneshot
+ExecStart=@KILL@ -s 58 $MANAGERPID
diff --git a/units/user@.service.in b/units/user@.service.in
new file mode 100644 (file)
index 0000000..2c15495
--- /dev/null
@@ -0,0 +1,19 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=User Manager for %I
+After=systemd-user-sessions.service
+
+[Service]
+User=%I
+PAMName=systemd-shared
+ControlGroup=%R/user/%I/shared cpu:/
+ControlGroupModify=yes
+Type=notify
+ExecStart=-@rootlibexecdir@/systemd --user
+Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket